@lumeer/pivot 0.0.13 → 0.2.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.
Files changed (49) hide show
  1. package/fesm2022/lumeer-pivot.mjs +56 -43
  2. package/fesm2022/lumeer-pivot.mjs.map +1 -1
  3. package/index.d.ts +332 -5
  4. package/lumeer-pivot-0.2.0.tgz +0 -0
  5. package/package.json +4 -6
  6. package/esm2022/lib/directives/lmr-templates.directive.mjs +0 -27
  7. package/esm2022/lib/lmr-pivot-table.component.mjs +0 -147
  8. package/esm2022/lib/lmr-pivot-table.module.mjs +0 -63
  9. package/esm2022/lib/lmr-simple-pivot-table.component.mjs +0 -101
  10. package/esm2022/lib/pipes/cell-has-value.pipe.mjs +0 -35
  11. package/esm2022/lib/pipes/contrast-color.pipe.mjs +0 -41
  12. package/esm2022/lib/pipes/filter-visible-cells.pipe.mjs +0 -35
  13. package/esm2022/lib/pipes/is-cell-expandable.pipe.mjs +0 -35
  14. package/esm2022/lib/pipes/is-cell-expanded.pipe.mjs +0 -37
  15. package/esm2022/lib/pipes/is-cell-rows-expandable.pipe.mjs +0 -35
  16. package/esm2022/lib/pipes/pivot-data-empty.pipe.mjs +0 -38
  17. package/esm2022/lib/util/lmr-pivot-config.mjs +0 -17
  18. package/esm2022/lib/util/lmr-pivot-constants.mjs +0 -12
  19. package/esm2022/lib/util/lmr-pivot-data.mjs +0 -2
  20. package/esm2022/lib/util/lmr-pivot-state.mjs +0 -156
  21. package/esm2022/lib/util/lmr-pivot-table.mjs +0 -2
  22. package/esm2022/lib/util/lmr-simple-pivot-config.mjs +0 -2
  23. package/esm2022/lib/util/pivot-data-converter.mjs +0 -507
  24. package/esm2022/lib/util/pivot-table-converter.mjs +0 -1017
  25. package/esm2022/lib/util/pivot-util.mjs +0 -75
  26. package/esm2022/lumeer-pivot.mjs +0 -5
  27. package/esm2022/public-api.mjs +0 -13
  28. package/lib/directives/lmr-templates.directive.d.ts +0 -14
  29. package/lib/lmr-pivot-table.component.d.ts +0 -49
  30. package/lib/lmr-pivot-table.module.d.ts +0 -18
  31. package/lib/lmr-simple-pivot-table.component.d.ts +0 -38
  32. package/lib/pipes/cell-has-value.pipe.d.ts +0 -8
  33. package/lib/pipes/contrast-color.pipe.d.ts +0 -11
  34. package/lib/pipes/filter-visible-cells.pipe.d.ts +0 -9
  35. package/lib/pipes/is-cell-expandable.pipe.d.ts +0 -8
  36. package/lib/pipes/is-cell-expanded.pipe.d.ts +0 -9
  37. package/lib/pipes/is-cell-rows-expandable.pipe.d.ts +0 -8
  38. package/lib/pipes/pivot-data-empty.pipe.d.ts +0 -8
  39. package/lib/util/lmr-pivot-config.d.ts +0 -84
  40. package/lib/util/lmr-pivot-constants.d.ts +0 -11
  41. package/lib/util/lmr-pivot-data.d.ts +0 -50
  42. package/lib/util/lmr-pivot-state.d.ts +0 -14
  43. package/lib/util/lmr-pivot-table.d.ts +0 -25
  44. package/lib/util/lmr-simple-pivot-config.d.ts +0 -9
  45. package/lib/util/pivot-data-converter.d.ts +0 -46
  46. package/lib/util/pivot-table-converter.d.ts +0 -74
  47. package/lib/util/pivot-util.d.ts +0 -12
  48. package/lumeer-pivot-0.0.13.tgz +0 -0
  49. package/public-api.d.ts +0 -9
@@ -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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O0lBQzVDLElBQUksaUJBQWlCLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztRQUM3QixPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxJQUFJLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUMzQyxJQUFJLE9BQU8sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUNsQixPQUFPLEtBQUssR0FBRyxPQUFPLENBQUM7UUFDekIsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLENBQUMsQ0FBQztRQUNYLENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAqIEx1bWVlcjogTW9kZXJuIERhdGEgRGVmaW5pdGlvbiBhbmQgUHJvY2Vzc2luZyBQbGF0Zm9ybVxuICpcbiAqIENvcHlyaWdodCAoQykgc2luY2UgMjAxNyBMdW1lZXIuaW8sIHMuci5vLiBhbmQvb3IgaXRzIGFmZmlsaWF0ZXMuXG4gKlxuICogVGhpcyBwcm9ncmFtIGlzIGZyZWUgc29mdHdhcmU6IHlvdSBjYW4gcmVkaXN0cmlidXRlIGl0IGFuZC9vciBtb2RpZnlcbiAqIGl0IHVuZGVyIHRoZSB0ZXJtcyBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2UgYXMgcHVibGlzaGVkIGJ5XG4gKiB0aGUgRnJlZSBTb2Z0d2FyZSBGb3VuZGF0aW9uLCBlaXRoZXIgdmVyc2lvbiAzIG9mIHRoZSBMaWNlbnNlLCBvclxuICogKGF0IHlvdXIgb3B0aW9uKSBhbnkgbGF0ZXIgdmVyc2lvbi5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZGlzdHJpYnV0ZWQgaW4gdGhlIGhvcGUgdGhhdCBpdCB3aWxsIGJlIHVzZWZ1bCxcbiAqIGJ1dCBXSVRIT1VUIEFOWSBXQVJSQU5UWTsgd2l0aG91dCBldmVuIHRoZSBpbXBsaWVkIHdhcnJhbnR5IG9mXG4gKiBNRVJDSEFOVEFCSUxJVFkgb3IgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UuICBTZWUgdGhlXG4gKiBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBmb3IgbW9yZSBkZXRhaWxzLlxuICpcbiAqIFlvdSBzaG91bGQgaGF2ZSByZWNlaXZlZCBhIGNvcHkgb2YgdGhlIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlXG4gKiBhbG9uZyB3aXRoIHRoaXMgcHJvZ3JhbS4gIElmIG5vdCwgc2VlIDxodHRwOi8vd3d3LmdudS5vcmcvbGljZW5zZXMvPi5cbiAqL1xuaW1wb3J0IHthZ2dyZWdhdGVEYXRhVmFsdWVzLCBDb25zdHJhaW50LCBDb25zdHJhaW50RGF0YSwgRGF0YUFnZ3JlZ2F0aW9uVHlwZSwgRGF0YVJlc291cmNlLCBpc1ZhbHVlQWdncmVnYXRpb24sIE51bWJlckNvbnN0cmFpbnQsIFBlcmNlbnRhZ2VDb25zdHJhaW50LCBVbmtub3duQ29uc3RyYWludCx9IGZyb20gJ0BsdW1lZXIvZGF0YS1maWx0ZXJzJztcbmltcG9ydCB7Y3JlYXRlUmFuZ2UsIGRlZXBPYmplY3RDb3B5LCBpc0FycmF5LCBpc05vdE51bGxPclVuZGVmaW5lZCwgaXNOdWxsT3JVbmRlZmluZWQsIGlzTnVtZXJpYywgc2hhZGVDb2xvciwgdG9OdW1iZXIsIHVuaXF1ZVZhbHVlcyx9IGZyb20gJ0BsdW1lZXIvdXRpbHMnO1xuXG5pbXBvcnQge0xtclBpdm90RGF0YSwgTG1yUGl2b3REYXRhSGVhZGVyLCBMbXJQaXZvdERhdGFIZWFkZXJFeHByZXNzaW9uLCBMbXJQaXZvdERhdGFIZWFkZXJPcGVyYW5kLCBMbXJQaXZvdERpbWVuc2lvbkNvbmZpZywgTG1yUGl2b3RTdGVtRGF0YX0gZnJvbSAnLi9sbXItcGl2b3QtZGF0YSc7XG5pbXBvcnQge0xtclBpdm90VGFibGUsIExtclBpdm90VGFibGVDZWxsfSBmcm9tICcuL2xtci1waXZvdC10YWJsZSc7XG5pbXBvcnQge0xtclBpdm90RXhwcmVzc2lvbiwgTG1yUGl2b3RIZWFkZXJPcGVyYW5kLCBMbXJQaXZvdE9wZXJhbmQsIExtclBpdm90UG9zaXRpb24sIExtclBpdm90U29ydCwgTG1yUGl2b3RUcmFuc2Zvcm0sIExtclBpdm90VmFsdWVUeXBlfSBmcm9tICcuL2xtci1waXZvdC1jb25maWcnO1xuaW1wb3J0IHtDT0xPUl9HUkFZMTAwLCBDT0xPUl9HUkFZMjAwLCBDT0xPUl9HUkFZMzAwLCBDT0xPUl9HUkFZNDAwLCBDT0xPUl9HUkFZNTAwfSBmcm9tICcuL2xtci1waXZvdC1jb25zdGFudHMnO1xuXG5pbnRlcmZhY2UgSGVhZGVyR3JvdXBJbmZvIHtcbiAgYmFja2dyb3VuZDogc3RyaW5nO1xuICBpbmRleGVzOiBudW1iZXJbXTtcbiAgZXhwcmVzc2lvbj86IExtclBpdm90RGF0YUhlYWRlckV4cHJlc3Npb247XG4gIGxldmVsOiBudW1iZXI7XG59XG5cbmludGVyZmFjZSBWYWx1ZVR5cGVJbmZvIHtcbiAgc3VtPzogbnVtYmVyO1xuICBzdW1zUm93cz86IG51bWJlcltdO1xuICBzdW1zQ29sdW1ucz86IG51bWJlcltdO1xuICBkZWZhdWx0Q29uc3RyYWludD86IENvbnN0cmFpbnQ7XG59XG5cbmV4cG9ydCBjbGFzcyBQaXZvdFRhYmxlQ29udmVydGVyIHtcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBlbXB0eUNsYXNzID0gJ3Bpdm90LWVtcHR5LWNlbGwnO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IGRhdGFDbGFzcyA9ICdwaXZvdC1kYXRhLWNlbGwnO1xuICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IGdyb3VwRGF0YUNsYXNzID0gJ3Bpdm90LWRhdGEtZ3JvdXAtY2VsbCc7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgcm93SGVhZGVyQ2xhc3MgPSAncGl2b3Qtcm93LWhlYWRlci1jZWxsJztcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSByb3dHcm91cEhlYWRlckNsYXNzID0gJ3Bpdm90LXJvdy1ncm91cC1oZWFkZXItY2VsbCc7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgcm93QXR0cmlidXRlSGVhZGVyQ2xhc3MgPSAncGl2b3Qtcm93LWF0dHJpYnV0ZS1oZWFkZXItY2VsbCc7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgY29sdW1uSGVhZGVyQ2xhc3MgPSAncGl2b3QtY29sdW1uLWhlYWRlci1jZWxsJztcbiAgcHVibGljIHN0YXRpYyByZWFkb25seSBjb2x1bW5Hcm91cEhlYWRlckNsYXNzID0gJ3Bpdm90LWNvbHVtbi1ncm91cC1oZWFkZXItY2VsbCc7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBncm91cENvbG9ycyA9IFtDT0xPUl9HUkFZMTAwLCBDT0xPUl9HUkFZMjAwLCBDT0xPUl9HUkFZMzAwLCBDT0xPUl9HUkFZNDAwLCBDT0xPUl9HUkFZNTAwXTtcblxuICBwcml2YXRlIHJlYWRvbmx5IHBlcmNlbnRhZ2VDb25zdHJhaW50ID0gbmV3IFBlcmNlbnRhZ2VDb25zdHJhaW50KHtkZWNpbWFsczogMn0pO1xuXG4gIHByaXZhdGUgZGF0YTogTG1yUGl2b3RTdGVtRGF0YTtcbiAgcHJpdmF0ZSB0cmFuc2Zvcm06IExtclBpdm90VHJhbnNmb3JtO1xuICBwcml2YXRlIHZhbHVlczogYW55W11bXTtcbiAgcHJpdmF0ZSBkYXRhUmVzb3VyY2VzOiBEYXRhUmVzb3VyY2VbXVtdW107XG4gIHByaXZhdGUgY29uc3RyYWludERhdGE6IENvbnN0cmFpbnREYXRhO1xuICBwcml2YXRlIHJvd0xldmVsczogbnVtYmVyO1xuICBwcml2YXRlIHJvd3NUcmFuc2Zvcm1hdGlvbkFycmF5OiBudW1iZXJbXTtcbiAgcHJpdmF0ZSBjb2x1bW5MZXZlbHM6IG51bWJlcjtcbiAgcHJpdmF0ZSBjb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheTogbnVtYmVyW107XG4gIHByaXZhdGUgdmFsdWVUeXBlSW5mbzogVmFsdWVUeXBlSW5mb1tdO1xuICBwcml2YXRlIG5vblN0aWNreVJvd0luZGV4OiBudW1iZXI7XG4gIHByaXZhdGUgbm9uU3RpY2t5Q29sdW1uSW5kZXg6IG51bWJlcjtcblxuICBwdWJsaWMgY3JlYXRlVGFibGVzKHBpdm90RGF0YTogTG1yUGl2b3REYXRhLCB0cmFuc2Zvcm06IExtclBpdm90VHJhbnNmb3JtKTogTG1yUGl2b3RUYWJsZVtdIHtcbiAgICBpZiAoIXBpdm90RGF0YSkge1xuICAgICAgcmV0dXJuIFt7Y2VsbHM6IFtdfV07XG4gICAgfVxuXG4gICAgdGhpcy50cmFuc2Zvcm0gPSB0cmFuc2Zvcm07XG4gICAgdGhpcy5jb25zdHJhaW50RGF0YSA9IHBpdm90RGF0YS5jb25zdHJhaW50RGF0YTtcblxuICAgIHJldHVybiAocGl2b3REYXRhLmRhdGEgfHwgW10pLm1hcChkID0+IHtcbiAgICAgIGlmICh0aGlzLmRhdGFBcmVFbXB0eShkKSkge1xuICAgICAgICByZXR1cm4ge2NlbGxzOiBbXX07XG4gICAgICB9XG4gICAgICB0aGlzLnVwZGF0ZURhdGEoZCk7XG4gICAgICByZXR1cm4gdGhpcy50cmFuc2Zvcm1EYXRhKCk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGRhdGFBcmVFbXB0eShkYXRhOiBMbXJQaXZvdFN0ZW1EYXRhKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChkYXRhLnJvd0hlYWRlcnMgfHwgW10pLmxlbmd0aCA9PT0gMCAmJiAoZGF0YS5jb2x1bW5IZWFkZXJzIHx8IFtdKS5sZW5ndGggPT09IDA7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZURhdGEoZGF0YTogTG1yUGl2b3RTdGVtRGF0YSkge1xuICAgIGNvbnN0IG51bWJlck9mU3VtcyA9IE1hdGgubWF4KDEsIChkYXRhLnZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGgpO1xuICAgIHRoaXMudmFsdWVUeXBlSW5mbyA9IGdldFZhbHVlc1R5cGVJbmZvKGRhdGEudmFsdWVzLCBkYXRhLnZhbHVlVHlwZXMsIG51bWJlck9mU3Vtcyk7XG4gICAgdGhpcy5kYXRhID0gcHJlcGFyZVBpdm90RGF0YShkYXRhLCB0aGlzLmNvbnN0cmFpbnREYXRhLCB0aGlzLnZhbHVlVHlwZUluZm8pO1xuICAgIHRoaXMudmFsdWVzID0gZGF0YS52YWx1ZXMgfHwgW107XG4gICAgdGhpcy5kYXRhUmVzb3VyY2VzID0gZGF0YS5kYXRhUmVzb3VyY2VzIHx8IFtdO1xuICAgIHRoaXMucm93TGV2ZWxzID0gKGRhdGEucm93c0NvbmZpZyB8fCBbXSkubGVuZ3RoO1xuICAgIHRoaXMuY29sdW1uTGV2ZWxzID0gKGRhdGEuY29sdW1uc0NvbmZpZyB8fCBbXSkubGVuZ3RoICsgKGRhdGEuaGFzQWRkaXRpb25hbENvbHVtbkxldmVsID8gMSA6IDApO1xuICAgIGNvbnN0IHJvd0FsbFN0aWNreSA9IHRoaXMuZGF0YS5yb3dzQ29uZmlnPy5sZW5ndGggJiYgdGhpcy5kYXRhLnJvd3NDb25maWcuZXZlcnkoY29uZmlnID0+ICEhY29uZmlnPy5zdGlja3kpXG4gICAgdGhpcy5ub25TdGlja3lSb3dJbmRleCA9IE1hdGgubWF4KHJvd0FsbFN0aWNreSA/IHRoaXMucm93TGV2ZWxzIDogKHRoaXMuZGF0YS5yb3dzQ29uZmlnPy5maW5kSW5kZXgoY29uZmlnID0+ICFjb25maWc/LnN0aWNreSkgfHwgMCksIDApO1xuICAgIGNvbnN0IGNvbHVtbkFsbFN0aWNreSA9IHRoaXMuZGF0YS5jb2x1bW5zQ29uZmlnPy5sZW5ndGggJiYgdGhpcy5kYXRhLmNvbHVtbnNDb25maWcuZXZlcnkoY29uZmlnID0+ICEhY29uZmlnPy5zdGlja3kpXG4gICAgdGhpcy5ub25TdGlja3lDb2x1bW5JbmRleCA9IE1hdGgubWF4KGNvbHVtbkFsbFN0aWNreSA/IHRoaXMuY29sdW1uTGV2ZWxzIDogKHRoaXMuZGF0YS5jb2x1bW5zQ29uZmlnPy5maW5kSW5kZXgoY29uZmlnID0+ICFjb25maWc/LnN0aWNreSkgfHwgMCksIDApO1xuICAgIGNvbnN0IGhhc1ZhbHVlID0gKGRhdGEudmFsdWVUaXRsZXMgfHwgW10pLmxlbmd0aCA+IDA7XG4gICAgaWYgKCh0aGlzLmRhdGEucm93SGVhZGVycyB8fCBbXSkubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheSA9IGNyZWF0ZVRyYW5zZm9ybWF0aW9uTWFwKFxuICAgICAgICB0aGlzLmRhdGEucm93SGVhZGVycyxcbiAgICAgICAgdGhpcy5yb3dTaG93U3VtcyxcbiAgICAgICAgdGhpcy5jb2x1bW5MZXZlbHMsXG4gICAgICAgIDFcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXkgPSBoYXNWYWx1ZSA/IFt0aGlzLmNvbHVtbkxldmVsc10gOiBbXTtcbiAgICB9XG5cbiAgICBpZiAoKHRoaXMuZGF0YS5jb2x1bW5IZWFkZXJzIHx8IFtdKS5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5ID0gY3JlYXRlVHJhbnNmb3JtYXRpb25NYXAoXG4gICAgICAgIHRoaXMuZGF0YS5jb2x1bW5IZWFkZXJzLFxuICAgICAgICB0aGlzLmNvbHVtblNob3dTdW1zLFxuICAgICAgICB0aGlzLnJvd0xldmVscyxcbiAgICAgICAgbnVtYmVyT2ZTdW1zXG4gICAgICApO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5ID0gaGFzVmFsdWUgPyBbdGhpcy5yb3dMZXZlbHNdIDogW107XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXQgcm93U2hvd1N1bXMoKTogYm9vbGVhbltdIHtcbiAgICByZXR1cm4gKHRoaXMuZGF0YS5yb3dzQ29uZmlnIHx8IFtdKS5tYXAoY29uZmlnID0+IGNvbmZpZy5zaG93U3Vtcyk7XG4gIH1cblxuICBwcml2YXRlIGdldCBjb2x1bW5TaG93U3VtcygpOiBib29sZWFuW10ge1xuICAgIHJldHVybiAodGhpcy5kYXRhLmNvbHVtbnNDb25maWcgfHwgW10pLm1hcChjb25maWcgPT4gY29uZmlnLnNob3dTdW1zKTtcbiAgfVxuXG4gIHByaXZhdGUgdHJhbnNmb3JtRGF0YSgpOiBMbXJQaXZvdFRhYmxlIHtcbiAgICBjb25zdCBjZWxscyA9IHRoaXMuaW5pdENlbGxzKCk7XG4gICAgY29uc3Qgcm93R3JvdXBzID0gdGhpcy5maWxsQ2VsbHNCeVJvd3MoY2VsbHMpO1xuICAgIGNvbnN0IGNvbHVtbkdyb3VwcyA9IHRoaXMuZmlsbENlbGxzQnlDb2x1bW5zKGNlbGxzKTtcbiAgICB0aGlzLmZpbGxDZWxsc0J5R3JvdXBJbnRlcnNlY3Rpb24oY2VsbHMsIHJvd0dyb3VwcywgY29sdW1uR3JvdXBzKTtcbiAgICByZXR1cm4ge2NlbGxzfTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbENlbGxzQnlSb3dzKGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10pOiBIZWFkZXJHcm91cEluZm9bXSB7XG4gICAgY29uc3Qgcm93R3JvdXBzID0gW107XG4gICAgdGhpcy5pdGVyYXRlQW5kRmlsbENlbGxzQnlSb3dzKGNlbGxzLCByb3dHcm91cHMsIHRoaXMuZGF0YS5yb3dIZWFkZXJzLCB0aGlzLmNvbHVtbkxldmVscywgdGhpcy5yb3dTaG93U3VtcywgMCk7XG4gICAgcmV0dXJuIHJvd0dyb3VwcztcbiAgfVxuXG4gIHByaXZhdGUgaXRlcmF0ZUFuZEZpbGxDZWxsc0J5Um93cyhcbiAgICBjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLFxuICAgIHJvd0dyb3Vwc0luZm86IEhlYWRlckdyb3VwSW5mb1tdLFxuICAgIGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICAgIHN0YXJ0SW5kZXg6IG51bWJlcixcbiAgICBzaG93U3VtczogYm9vbGVhbltdLFxuICAgIGxldmVsOiBudW1iZXIsXG4gICAgcGFyZW50SGVhZGVyPzogTG1yUGl2b3REYXRhSGVhZGVyXG4gICkge1xuICAgIGxldCBjdXJyZW50SW5kZXggPSBzdGFydEluZGV4O1xuICAgIGZvciAoY29uc3QgaGVhZGVyIG9mIGhlYWRlcnMpIHtcblxuICAgICAgY29uc3QgYmVmb3JlRXhwcmVzc2lvbnMgPSAoaGVhZGVyLmV4cHJlc3Npb25zIHx8IFtdKS5maWx0ZXIoZXhwID0+IGV4cC5wb3NpdGlvbiA9PT0gTG1yUGl2b3RQb3NpdGlvbi5CZWZvcmVIZWFkZXIpXG4gICAgICB0aGlzLmZpbGxDZWxsc0ZvckV4cHJlc3Npb25zKGNlbGxzLCByb3dHcm91cHNJbmZvLCBsZXZlbCwgY3VycmVudEluZGV4LCBiZWZvcmVFeHByZXNzaW9ucylcbiAgICAgIGN1cnJlbnRJbmRleCArPSBiZWZvcmVFeHByZXNzaW9ucy5sZW5ndGhcblxuICAgICAgY29uc3Qgcm93U3BhbiA9IGdldERpcmVjdEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMpO1xuICAgICAgY2VsbHNbY3VycmVudEluZGV4XVtsZXZlbF0gPSB7XG4gICAgICAgIHZhbHVlOiB0aGlzLmZvcm1hdFJvd0hlYWRlcihoZWFkZXIudGl0bGUsIGxldmVsKSxcbiAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIucm93SGVhZGVyQ2xhc3MsXG4gICAgICAgIGlzSGVhZGVyOiB0cnVlLFxuICAgICAgICBzdGlja3lTdGFydDogdGhpcy5pc1Jvd0xldmVsU3RpY2t5KGxldmVsKSxcbiAgICAgICAgcm93U3BhbixcbiAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgYmFja2dyb3VuZDogdGhpcy5nZXRIZWFkZXJCYWNrZ3JvdW5kKGhlYWRlciwgbGV2ZWwpLFxuICAgICAgICBjb25zdHJhaW50OiBoZWFkZXIuY29uc3RyYWludCxcbiAgICAgICAgbGFiZWw6IGhlYWRlci5hdHRyaWJ1dGVOYW1lLFxuICAgICAgICBjaGlsZEluZGV4ZXM6IGNyZWF0ZVJhbmdlKGN1cnJlbnRJbmRleCwgY3VycmVudEluZGV4ICsgKGhlYWRlci5jaGlsZHJlbj8ubGVuZ3RoIHx8IDEpKSxcbiAgICAgICAgZXhwYW5kYWJsZTogdHJ1ZSxcbiAgICAgIH07XG5cbiAgICAgIGlmIChoZWFkZXIuY2hpbGRyZW4pIHtcbiAgICAgICAgdGhpcy5pdGVyYXRlQW5kRmlsbENlbGxzQnlSb3dzKFxuICAgICAgICAgIGNlbGxzLFxuICAgICAgICAgIHJvd0dyb3Vwc0luZm8sXG4gICAgICAgICAgaGVhZGVyLmNoaWxkcmVuLFxuICAgICAgICAgIGN1cnJlbnRJbmRleCxcbiAgICAgICAgICBzaG93U3VtcyxcbiAgICAgICAgICBsZXZlbCArIDEsXG4gICAgICAgICAgaGVhZGVyXG4gICAgICAgICk7XG4gICAgICB9IGVsc2UgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGhlYWRlci50YXJnZXRJbmRleCkpIHtcbiAgICAgICAgdGhpcy5maWxsQ2VsbHNGb3JSb3coY2VsbHMsIGhlYWRlci50YXJnZXRJbmRleCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGFmdGVyRXhwcmVzc2lvbnMgPSAoaGVhZGVyLmV4cHJlc3Npb25zIHx8IFtdKS5maWx0ZXIoZXhwID0+IGV4cC5wb3NpdGlvbiA9PT0gTG1yUGl2b3RQb3NpdGlvbi5TdGlja1RvRW5kKVxuICAgICAgY3VycmVudEluZGV4ICs9IGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMpIC0gYmVmb3JlRXhwcmVzc2lvbnMubGVuZ3RoO1xuICAgICAgdGhpcy5maWxsQ2VsbHNGb3JFeHByZXNzaW9ucyhjZWxscywgcm93R3JvdXBzSW5mbywgbGV2ZWwsIGN1cnJlbnRJbmRleCAtIGFmdGVyRXhwcmVzc2lvbnMubGVuZ3RoLCBhZnRlckV4cHJlc3Npb25zKVxuICAgIH1cblxuICAgIGlmIChzaG93U3Vtc1tsZXZlbF0pIHtcbiAgICAgIGNvbnN0IHsgdGl0bGUsIHN1bW1hcnkgfSA9IHRoaXMuZm9ybWF0U3VtbWFyeUhlYWRlcihwYXJlbnRIZWFkZXIsIGxldmVsKVxuICAgICAgY29uc3QgYmFja2dyb3VuZCA9IHRoaXMuZ2V0U3VtbWFyeUJhY2tncm91bmQobGV2ZWwpO1xuICAgICAgY29uc3QgY29sdW1uSW5kZXggPSBNYXRoLm1heChsZXZlbCAtIDEsIDApO1xuICAgICAgdGhpcy5zcGxpdFJvd0dyb3VwSGVhZGVyKGNlbGxzLCBjb2x1bW5JbmRleCwgY3VycmVudEluZGV4LCBiYWNrZ3JvdW5kLCBzdW1tYXJ5LCBbXSwgZmFsc2UsIHRpdGxlLCBwYXJlbnRIZWFkZXI/LmNvbnN0cmFpbnQsIHBhcmVudEhlYWRlcj8uYXR0cmlidXRlTmFtZSlcblxuICAgICAgY29uc3Qgcm93SW5kZXhlcyA9IGdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXJzKGhlYWRlcnMpO1xuICAgICAgY29uc3QgdHJhbnNmb3JtZWRSb3dJbmRleGVzID0gdGhpcy50cmFuc2Zvcm1Sb3dJbmRleGVzKHJvd0luZGV4ZXMpO1xuICAgICAgcm93R3JvdXBzSW5mb1tjdXJyZW50SW5kZXhdID0ge2JhY2tncm91bmQsIGluZGV4ZXM6IHRyYW5zZm9ybWVkUm93SW5kZXhlcywgbGV2ZWx9O1xuXG4gICAgICB0aGlzLmZpbGxDZWxsc0Zvckdyb3VwZWRSb3coY2VsbHMsIHJvd0luZGV4ZXMsIGN1cnJlbnRJbmRleCwgYmFja2dyb3VuZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ2VsbHNGb3JFeHByZXNzaW9ucyhjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLCByb3dHcm91cHNJbmZvOiBIZWFkZXJHcm91cEluZm9bXSwgbGV2ZWw6IG51bWJlciwgY3VycmVudEluZGV4OiBudW1iZXIsIGV4cHJlc3Npb25zOiBMbXJQaXZvdERhdGFIZWFkZXJFeHByZXNzaW9uW10pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGV4cHJlc3Npb25zLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBleHByZXNzaW9uSW5kZXggPSBjdXJyZW50SW5kZXggKyBpXG4gICAgICBjb25zdCBiYWNrZ3JvdW5kID0gdGhpcy5nZXRTdW1tYXJ5QmFja2dyb3VuZChsZXZlbCk7XG4gICAgICBjb25zdCB7aW5kZXhlc30gPSB0aGlzLmZpbGxDZWxsc0ZvckV4cHJlc3Npb25Sb3coY2VsbHMsIGV4cHJlc3Npb25zW2ldLCBleHByZXNzaW9uSW5kZXgsIGJhY2tncm91bmQpXG4gICAgICB0aGlzLnNwbGl0Um93R3JvdXBIZWFkZXIoY2VsbHMsIGxldmVsLCBleHByZXNzaW9uSW5kZXgsIGJhY2tncm91bmQsIGV4cHJlc3Npb25zW2ldLnRpdGxlLCBpbmRleGVzLCBleHByZXNzaW9uc1tpXS5leHBhbmRhYmxlKVxuICAgICAgcm93R3JvdXBzSW5mb1tleHByZXNzaW9uSW5kZXhdID0ge2JhY2tncm91bmQsIGluZGV4ZXM6IFtdLCBleHByZXNzaW9uOiBleHByZXNzaW9uc1tpXSwgbGV2ZWx9O1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgc3BsaXRSb3dHcm91cEhlYWRlcihjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLCBjb2x1bW5JbmRleDogbnVtYmVyLCBjdXJyZW50SW5kZXg6IG51bWJlciwgYmFja2dyb3VuZDogc3RyaW5nLCBzdW1tYXJ5OiBzdHJpbmcsIHJvd0luZGV4ZXM6IG51bWJlcltdLCBleHBhbmRhYmxlOiBib29sZWFuLCB0aXRsZT86IHN0cmluZywgY29uc3RyYWludD86IENvbnN0cmFpbnQsIGxhYmVsPzogc3RyaW5nKSB7XG4gICAgbGV0IGNvbFNwYW4gPSB0aGlzLnJvd0xldmVscyAtIGNvbHVtbkluZGV4O1xuICAgIGNvbnN0IHN0aWNreVN0YXJ0ID0gdGhpcy5pc1Jvd0xldmVsU3RpY2t5KGNvbHVtbkluZGV4KTtcblxuICAgIC8vIHNwbGl0IHJvdyBncm91cCBoZWFkZXIgY2VsbCBiZWNhdXNlIG9mIGNvcnJlY3Qgc3RpY2t5IHNjcm9sbFxuICAgIGlmIChzdGlja3lTdGFydCAmJiB0aGlzLm5vblN0aWNreVJvd0luZGV4ID4gMCAmJiB0aGlzLm5vblN0aWNreVJvd0luZGV4IDwgdGhpcy5yb3dMZXZlbHMgJiYgY29sU3BhbiA+IDEpIHtcbiAgICAgIGNvbnN0IG5ld0NvbHNwYW4gPSB0aGlzLm5vblN0aWNreVJvd0luZGV4IC0gY29sdW1uSW5kZXg7XG5cbiAgICAgIGNlbGxzW2N1cnJlbnRJbmRleF1bdGhpcy5ub25TdGlja3lSb3dJbmRleF0gPSB7XG4gICAgICAgIHZhbHVlOiB1bmRlZmluZWQsXG4gICAgICAgIGNvbnN0cmFpbnQ6IHVuZGVmaW5lZCxcbiAgICAgICAgbGFiZWw6IHVuZGVmaW5lZCxcbiAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIucm93R3JvdXBIZWFkZXJDbGFzcyxcbiAgICAgICAgaXNTdW1tYXJ5OiB0cnVlLFxuICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICBjb2xTcGFuOiBjb2xTcGFuIC0gbmV3Q29sc3BhbixcbiAgICAgICAgYmFja2dyb3VuZCxcbiAgICAgICAgc3VtbWFyeTogdW5kZWZpbmVkLFxuICAgICAgICBleHBhbmRhYmxlLFxuICAgICAgfTtcblxuICAgICAgY29sU3BhbiA9IG5ld0NvbHNwYW47XG4gICAgfVxuXG4gICAgY2VsbHNbY3VycmVudEluZGV4XVtjb2x1bW5JbmRleF0gPSB7XG4gICAgICB2YWx1ZTogdGl0bGUsXG4gICAgICBjb25zdHJhaW50LFxuICAgICAgbGFiZWwsXG4gICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5yb3dHcm91cEhlYWRlckNsYXNzLFxuICAgICAgaXNTdW1tYXJ5OiB0cnVlLFxuICAgICAgc3RpY2t5U3RhcnQsXG4gICAgICByb3dTcGFuOiAxLFxuICAgICAgY29sU3BhbixcbiAgICAgIGJhY2tncm91bmQsXG4gICAgICBzdW1tYXJ5LFxuICAgICAgcm93SW5kZXhlcyxcbiAgICAgIGV4cGFuZGFibGUsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0U3VtbWFyeUhlYWRlcihoZWFkZXI6IExtclBpdm90RGF0YUhlYWRlciwgbGV2ZWw6IG51bWJlcik6IHt0aXRsZT86IHN0cmluZzsgc3VtbWFyeTogc3RyaW5nfSB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtLmZvcm1hdFN1bW1hcnlIZWFkZXI/LihoZWFkZXIsIGxldmVsKSB8fCB7XG4gICAgICB0aXRsZTogaGVhZGVyPy50aXRsZSxcbiAgICAgIHN1bW1hcnk6ICcnLFxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0Um93SGVhZGVyKHRpdGxlOiBzdHJpbmcsIGxldmVsOiBudW1iZXIpOiBzdHJpbmcge1xuICAgIHJldHVybiB0aGlzLnRyYW5zZm9ybT8uZm9ybWF0Um93SGVhZGVyPy4odGl0bGUsIGxldmVsKSB8fCB0aXRsZVxuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRDb2x1bW5IZWFkZXIodGl0bGU6IHN0cmluZywgbGV2ZWw6IG51bWJlcik6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMudHJhbnNmb3JtPy5mb3JtYXRDb2x1bW5IZWFkZXI/Lih0aXRsZSwgbGV2ZWwpIHx8IHRpdGxlXG4gIH1cblxuICBwcml2YXRlIGdldEhlYWRlckJhY2tncm91bmQoaGVhZGVyOiB7IGNvbG9yOiBzdHJpbmcgfSwgbGV2ZWw6IG51bWJlcik6IHN0cmluZyB7XG4gICAgaWYgKGhlYWRlcj8uY29sb3IpIHtcbiAgICAgIHJldHVybiBzaGFkZUNvbG9yKGhlYWRlci5jb2xvciwgdGhpcy5nZXRMZXZlbE9wYWNpdHkobGV2ZWwpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRMZXZlbE9wYWNpdHkobGV2ZWw6IG51bWJlcik6IG51bWJlciB7XG4gICAgcmV0dXJuIE1hdGgubWluKDgwLCA1MCArIGxldmVsICogNSkgLyAxMDA7XG4gIH1cblxuICBwcml2YXRlIGlzUm93TGV2ZWxTdGlja3kobGV2ZWw6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmRhdGE/LnJvd3NDb25maWc/LltsZXZlbF0/LnN0aWNreTtcbiAgfVxuXG4gIHByaXZhdGUgaXNDb2x1bW5MZXZlbFN0aWNreShsZXZlbDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgbWF4TGV2ZWwgPSBNYXRoLm1pbihsZXZlbCwgKHRoaXMuZGF0YT8uY29sdW1uc0NvbmZpZz8ubGVuZ3RoID8/IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSKSAtIDEpO1xuICAgIHJldHVybiB0aGlzLmRhdGE/LmNvbHVtbnNDb25maWc/LlttYXhMZXZlbF0/LnN0aWNreTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3VtbWFyeUJhY2tncm91bmQobGV2ZWw6IG51bWJlcik6IHN0cmluZyB7XG4gICAgY29uc3QgaW5kZXggPSBNYXRoLm1pbihsZXZlbCwgdGhpcy5ncm91cENvbG9ycy5sZW5ndGggLSAxKTtcbiAgICByZXR1cm4gdGhpcy5ncm91cENvbG9yc1tpbmRleF07XG4gIH1cblxuICBwcml2YXRlIGZpbGxDZWxsc0ZvclJvdyhjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLCByb3c6IG51bWJlcikge1xuICAgIGNvbnN0IHJvd0luZGV4SW5DZWxscyA9IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXlbcm93XTtcbiAgICBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQocm93SW5kZXhJbkNlbGxzKSkge1xuICAgICAgZm9yIChsZXQgY29sdW1uID0gMDsgY29sdW1uIDwgdGhpcy5jb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheS5sZW5ndGg7IGNvbHVtbisrKSB7XG4gICAgICAgIGNvbnN0IGNvbHVtbkluZGV4SW5DZWxscyA9IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXlbY29sdW1uXTtcbiAgICAgICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGNvbHVtbkluZGV4SW5DZWxscykpIHtcbiAgICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZGF0YS52YWx1ZXNbcm93XVtjb2x1bW5dO1xuICAgICAgICAgIGNvbnN0IGRhdGFSZXNvdXJjZXMgPSB0aGlzLmRhdGFSZXNvdXJjZXM/Lltyb3ddPy5bY29sdW1uXSB8fCBbXTtcbiAgICAgICAgICBjb25zdCBmb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuYWdncmVnYXRlT3JGb3JtYXRTaW5nbGVWYWx1ZSh2YWx1ZSwgY29sdW1uKTtcbiAgICAgICAgICBjb25zdCBzdHJpbmdWYWx1ZSA9IGlzTm90TnVsbE9yVW5kZWZpbmVkKGZvcm1hdHRlZFZhbHVlKSA/IFN0cmluZyhmb3JtYXR0ZWRWYWx1ZSkgOiAnJztcbiAgICAgICAgICBjZWxsc1tyb3dJbmRleEluQ2VsbHNdW2NvbHVtbkluZGV4SW5DZWxsc10gPSB7XG4gICAgICAgICAgICB2YWx1ZTogc3RyaW5nVmFsdWUsXG4gICAgICAgICAgICBkYXRhUmVzb3VyY2VzLFxuICAgICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5kYXRhQ2xhc3MsXG4gICAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGdldFZhbHVlSW5kZXhGb3JDb2x1bW5zKGNvbHVtbnM6IG51bWJlcltdKTogbnVtYmVyIHtcbiAgICByZXR1cm4gY29sdW1uc1swXSAlIHRoaXMuZGF0YS52YWx1ZVRpdGxlcy5sZW5ndGg7XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdFZhbHVlQnlWYWx1ZVR5cGUodmFsdWU6IGFueSwgdmFsdWVJbmRleDogbnVtYmVyKTogYW55IHtcbiAgICBjb25zdCB2YWx1ZVR5cGUgPSAodGhpcy5kYXRhLnZhbHVlVHlwZXMgfHwgW10pW3ZhbHVlSW5kZXhdO1xuICAgIGlmICghdmFsdWVUeXBlIHx8IHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuRGVmYXVsdCkge1xuICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeUNvbnN0cmFpbnQodmFsdWUsIHZhbHVlSW5kZXgpO1xuICAgIH1cblxuICAgIGlmIChcbiAgICAgIFtMbXJQaXZvdFZhbHVlVHlwZS5BbGxQZXJjZW50YWdlLCBMbXJQaXZvdFZhbHVlVHlwZS5Db2x1bW5QZXJjZW50YWdlLCBMbXJQaXZvdFZhbHVlVHlwZS5Sb3dQZXJjZW50YWdlXS5pbmNsdWRlcyh2YWx1ZVR5cGUpXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5UGVyY2VudGFnZSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeUNvbnN0cmFpbnQodmFsdWUsIHZhbHVlSW5kZXgpO1xuICB9XG5cbiAgcHJpdmF0ZSBmb3JtYXRHcm91cGVkVmFsdWVCeVZhbHVlVHlwZSh2YWx1ZTogYW55LCByb3dzOiBudW1iZXJbXSwgY29sdW1uczogbnVtYmVyW10pOiBhbnkge1xuICAgIGNvbnN0IHZhbHVlSW5kZXggPSBjb2x1bW5zWzBdICUgdGhpcy5kYXRhLnZhbHVlVGl0bGVzLmxlbmd0aDtcbiAgICBjb25zdCB2YWx1ZVR5cGUgPSB0aGlzLmRhdGEudmFsdWVUeXBlcyAmJiB0aGlzLmRhdGEudmFsdWVUeXBlc1t2YWx1ZUluZGV4XTtcbiAgICBjb25zdCB2YWx1ZVR5cGVJbmZvID0gdGhpcy52YWx1ZVR5cGVJbmZvW3ZhbHVlSW5kZXhdO1xuICAgIGlmICghdmFsdWVUeXBlSW5mbyB8fCAhdmFsdWVUeXBlIHx8IHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuRGVmYXVsdCkge1xuICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeUNvbnN0cmFpbnQodmFsdWUsIHZhbHVlSW5kZXgpO1xuICAgIH1cblxuICAgIGlmICh2YWx1ZVR5cGUgPT09IExtclBpdm90VmFsdWVUeXBlLkFsbFBlcmNlbnRhZ2UpIHtcbiAgICAgIHJldHVybiB0aGlzLmZvcm1hdFZhbHVlQnlQZXJjZW50YWdlKGRpdmlkZVZhbHVlcyh2YWx1ZSwgdmFsdWVUeXBlSW5mby5zdW0pKTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuQ29sdW1uUGVyY2VudGFnZSkge1xuICAgICAgY29uc3QgY29sdW1uc0RpdmlkZXJzID0gY29sdW1ucy5yZWR1Y2UoKGRpdmlkZXJzLCBjb2x1bW4pID0+IHtcbiAgICAgICAgZGl2aWRlcnMucHVzaCh2YWx1ZVR5cGVJbmZvLnN1bXNDb2x1bW5zW2NvbHVtbl0pO1xuICAgICAgICByZXR1cm4gZGl2aWRlcnM7XG4gICAgICB9LCBbXSk7XG4gICAgICBjb25zdCBjb2x1bW5zRGl2aWRlciA9IGFnZ3JlZ2F0ZURhdGFWYWx1ZXMoRGF0YUFnZ3JlZ2F0aW9uVHlwZS5TdW0sIGNvbHVtbnNEaXZpZGVycyk7XG4gICAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5UGVyY2VudGFnZShkaXZpZGVWYWx1ZXModmFsdWUsIGNvbHVtbnNEaXZpZGVyKSk7XG4gICAgfSBlbHNlIGlmICh2YWx1ZVR5cGUgPT09IExtclBpdm90VmFsdWVUeXBlLlJvd1BlcmNlbnRhZ2UpIHtcbiAgICAgIGNvbnN0IHJvd3NEaXZpZGVycyA9IHJvd3MucmVkdWNlKChkaXZpZGVycywgcm93KSA9PiB7XG4gICAgICAgIGRpdmlkZXJzLnB1c2godmFsdWVUeXBlSW5mby5zdW1zUm93c1tyb3ddKTtcbiAgICAgICAgcmV0dXJuIGRpdmlkZXJzO1xuICAgICAgfSwgW10pO1xuICAgICAgY29uc3Qgcm93c0RpdmlkZXIgPSBhZ2dyZWdhdGVEYXRhVmFsdWVzKERhdGFBZ2dyZWdhdGlvblR5cGUuU3VtLCByb3dzRGl2aWRlcnMpO1xuICAgICAgcmV0dXJuIHRoaXMuZm9ybWF0VmFsdWVCeVBlcmNlbnRhZ2UoZGl2aWRlVmFsdWVzKHZhbHVlLCByb3dzRGl2aWRlcikpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmZvcm1hdFZhbHVlQnlDb25zdHJhaW50KHZhbHVlLCB2YWx1ZUluZGV4KTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0VmFsdWVCeVBlcmNlbnRhZ2UodmFsdWU6IGFueSk6IHN0cmluZyB7XG4gICAgcmV0dXJuIHRoaXMucGVyY2VudGFnZUNvbnN0cmFpbnQuY3JlYXRlRGF0YVZhbHVlKHZhbHVlKS5mb3JtYXQoKTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0VmFsdWVCeUNvbnN0cmFpbnQodmFsdWU6IGFueSwgdmFsdWVJbmRleDogbnVtYmVyKTogYW55IHtcbiAgICBjb25zdCBjb25zdHJhaW50ID0gdGhpcy5kYXRhLnZhbHVlc0NvbnN0cmFpbnRzPy5bdmFsdWVJbmRleF0gfHwgdGhpcy52YWx1ZVR5cGVJbmZvW3ZhbHVlSW5kZXhdPy5kZWZhdWx0Q29uc3RyYWludDtcbiAgICBpZiAoY29uc3RyYWludCkge1xuICAgICAgcmV0dXJuIGNvbnN0cmFpbnQuY3JlYXRlRGF0YVZhbHVlKHZhbHVlLCB0aGlzLmNvbnN0cmFpbnREYXRhKS5wcmV2aWV3KCk7XG4gICAgfVxuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbENlbGxzRm9yR3JvdXBlZFJvdyhcbiAgICBjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLFxuICAgIHJvd3M6IG51bWJlcltdLFxuICAgIHJvd0luZGV4SW5DZWxsczogbnVtYmVyLFxuICAgIGJhY2tncm91bmQ6IHN0cmluZ1xuICApIHtcbiAgICBmb3IgKGxldCBjb2x1bW4gPSAwOyBjb2x1bW4gPCB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5Lmxlbmd0aDsgY29sdW1uKyspIHtcbiAgICAgIGNvbnN0IGNvbHVtbkluZGV4SW5DZWxscyA9IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXlbY29sdW1uXTtcbiAgICAgIGlmIChpc05vdE51bGxPclVuZGVmaW5lZChjb2x1bW5JbmRleEluQ2VsbHMpKSB7XG4gICAgICAgIGNvbnN0IHt2YWx1ZXMsIGRhdGFSZXNvdXJjZXN9ID0gdGhpcy5nZXRHcm91cGVkVmFsdWVzRm9yUm93c0FuZENvbHMocm93cywgW2NvbHVtbl0pO1xuICAgICAgICBjb25zdCBmb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuYWdncmVnYXRlQW5kRm9ybWF0RGF0YVZhbHVlcyh2YWx1ZXMsIHJvd3MsIFtjb2x1bW5dKTtcbiAgICAgICAgY2VsbHNbcm93SW5kZXhJbkNlbGxzXVtjb2x1bW5JbmRleEluQ2VsbHNdID0ge1xuICAgICAgICAgIHZhbHVlOiBTdHJpbmcoZm9ybWF0dGVkVmFsdWUpLFxuICAgICAgICAgIGRhdGFSZXNvdXJjZXMsXG4gICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmdyb3VwRGF0YUNsYXNzLFxuICAgICAgICAgIGJhY2tncm91bmQsXG4gICAgICAgICAgaXNWYWx1ZTogdHJ1ZSxcbiAgICAgICAgfTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGZpbGxDZWxsc0ZvckV4cHJlc3Npb25Sb3coXG4gICAgY2VsbHM6IExtclBpdm90VGFibGVDZWxsW11bXSxcbiAgICBleHByZXNzaW9uOiBMbXJQaXZvdERhdGFIZWFkZXJFeHByZXNzaW9uLFxuICAgIHJvd0luZGV4SW5DZWxsczogbnVtYmVyLFxuICAgIGJhY2tncm91bmQ6IHN0cmluZ1xuICApOntpbmRleGVzOiBudW1iZXJbXX0ge1xuICAgIGxldCByb3dJbmRleGVzOiBudW1iZXJbXSA9IFtdO1xuICAgIGZvciAobGV0IGNvbHVtbiA9IDA7IGNvbHVtbiA8IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXkubGVuZ3RoOyBjb2x1bW4rKykge1xuICAgICAgY29uc3QgY29sdW1uSW5kZXhJbkNlbGxzID0gdGhpcy5jb2x1bW5zVHJhbnNmb3JtYXRpb25BcnJheVtjb2x1bW5dO1xuICAgICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGNvbHVtbkluZGV4SW5DZWxscykpIHtcbiAgICAgICAgY29uc3Qge3ZhbHVlLCBkYXRhUmVzb3VyY2VzLCBpbmRleGVzfSA9IHRoaXMuZXZhbHVhdGVFeHByZXNzaW9uKGV4cHJlc3Npb24sIFtjb2x1bW5dKTtcbiAgICAgICAgcm93SW5kZXhlcyA9IGluZGV4ZXNcbiAgICAgICAgY29uc3QgdmFsdWVJbmRleCA9IGNvbHVtbiAlIHRoaXMuZGF0YS52YWx1ZVRpdGxlcy5sZW5ndGg7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gdGhpcy5mb3JtYXRWYWx1ZUJ5Q29uc3RyYWludCh2YWx1ZSwgdmFsdWVJbmRleCk7XG4gICAgICAgIGNlbGxzW3Jvd0luZGV4SW5DZWxsc11bY29sdW1uSW5kZXhJbkNlbGxzXSA9IHtcbiAgICAgICAgICB2YWx1ZTogU3RyaW5nKGZvcm1hdHRlZFZhbHVlKSxcbiAgICAgICAgICBkYXRhUmVzb3VyY2VzLFxuICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5ncm91cERhdGFDbGFzcyxcbiAgICAgICAgICBiYWNrZ3JvdW5kLFxuICAgICAgICAgIGlzVmFsdWU6IHRydWUsXG4gICAgICAgIH07XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiB7aW5kZXhlczogdW5pcXVlVmFsdWVzKFtyb3dJbmRleEluQ2VsbHMsIC4uLnJvd0luZGV4ZXNdKX1cbiAgfVxuXG4gIHByaXZhdGUgZXZhbHVhdGVFeHByZXNzaW9uKGV4cHJlc3Npb246IExtclBpdm90RGF0YUhlYWRlckV4cHJlc3Npb24sIGNvbHVtbnM6IG51bWJlcltdKToge3ZhbHVlOiBudW1iZXI7IGRhdGFSZXNvdXJjZXM6IERhdGFSZXNvdXJjZVtdOyBpbmRleGVzOiBudW1iZXJbXSAgfSB7XG4gICAgcmV0dXJuIChleHByZXNzaW9uLm9wZXJhbmRzIHx8IFtdKS5yZWR1Y2UoKHJlc3VsdCwgb3BlcmFuZCwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IHt2YWx1ZSwgZGF0YVJlc291cmNlcywgaW5kZXhlcyB9ID0gdGhpcy5ldmFsdWF0ZU9wZXJhbmQob3BlcmFuZCwgY29sdW1ucylcbiAgICAgIHJlc3VsdC5kYXRhUmVzb3VyY2VzLnB1c2goLi4uZGF0YVJlc291cmNlcylcbiAgICAgIHJlc3VsdC5pbmRleGVzLnB1c2goLi4uaW5kZXhlcylcbiAgICAgIHN3aXRjaCAoZXhwcmVzc2lvbi5vcGVyYXRpb24pIHtcbiAgICAgICAgY2FzZSAnYWRkJzpcbiAgICAgICAgICByZXN1bHQudmFsdWUgKz0gdmFsdWVcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnc3VidHJhY3QnOlxuICAgICAgICAgIHJlc3VsdC52YWx1ZSA9IChpbmRleCA9PT0gMCA/IHZhbHVlIDogcmVzdWx0LnZhbHVlIC0gdmFsdWUpXG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgJ211bHRpcGx5JzpcbiAgICAgICAgICByZXN1bHQudmFsdWUgPSBpbmRleCA9PT0gMCA/IHZhbHVlIDogcmVzdWx0LnZhbHVlICogdmFsdWVcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSAnZGl2aWRlJzpcbiAgICAgICAgICByZXN1bHQudmFsdWUgPSBpbmRleCA9PT0gMCA/IHZhbHVlIDogdmFsdWUgPyByZXN1bHQudmFsdWUgLyB2YWx1ZSA6IHJlc3VsdC52YWx1ZVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcmVzdWx0XG4gICAgfSAsIHt2YWx1ZTogMCwgZGF0YVJlc291cmNlczogW10sIGluZGV4ZXM6IFtdfSlcbiAgfVxuXG4gIHByaXZhdGUgZXZhbHVhdGVPcGVyYW5kKG9wZXJhbmQ6IExtclBpdm90RGF0YUhlYWRlck9wZXJhbmQsIGNvbHVtbnM6IG51bWJlcltdKToge3ZhbHVlOiBudW1iZXI7IGRhdGFSZXNvdXJjZXM6IERhdGFSZXNvdXJjZVtdOyBpbmRleGVzOiBudW1iZXJbXSB9IHtcbiAgICBzd2l0Y2ggKG9wZXJhbmQudHlwZSkge1xuICAgICAgY2FzZSAnZXhwcmVzc2lvbic6IHJldHVybiB0aGlzLmV2YWx1YXRlRXhwcmVzc2lvbihvcGVyYW5kLCBjb2x1bW5zKVxuICAgICAgY2FzZSAndmFsdWUnOiByZXR1cm4ge3ZhbHVlOiBvcGVyYW5kLnZhbHVlLCBkYXRhUmVzb3VyY2VzOiBbXSwgaW5kZXhlczogW119XG4gICAgICBjYXNlICdoZWFkZXInOiB7XG4gICAgICAgIGNvbnN0IHJvd3MgPSBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVycyhvcGVyYW5kLmhlYWRlcnMpO1xuICAgICAgICBjb25zdCB7dmFsdWVzLCBkYXRhUmVzb3VyY2VzfSA9IHRoaXMuZ2V0R3JvdXBlZFZhbHVlc0ZvclJvd3NBbmRDb2xzKHJvd3MsIGNvbHVtbnMpO1xuICAgICAgICBjb25zdCB7dmFsdWV9ID0gdGhpcy5hZ2dyZWdhdGVEYXRhVmFsdWVzKHZhbHVlcywgY29sdW1ucyk7XG4gICAgICAgIHJldHVybiB7dmFsdWUsIGRhdGFSZXNvdXJjZXMsIGluZGV4ZXM6IHRoaXMudHJhbnNmb3JtUm93SW5kZXhlcyhyb3dzKX1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRyYW5zZm9ybVJvd0luZGV4ZXMocm93czogbnVtYmVyW10pOiBudW1iZXJbXSB7XG4gICAgcmV0dXJuIHJvd3NcbiAgICAgIC5tYXAodiA9PiB0aGlzLnJvd3NUcmFuc2Zvcm1hdGlvbkFycmF5W3ZdKVxuICAgICAgLmZpbHRlcih2ID0+IGlzTm90TnVsbE9yVW5kZWZpbmVkKHYpKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0R3JvdXBlZFZhbHVlc0ZvclJvd3NBbmRDb2xzKFxuICAgIHJvd3M6IG51bWJlcltdLFxuICAgIGNvbHVtbnM6IG51bWJlcltdXG4gICk6IHsgdmFsdWVzOiBhbnlbXTsgZGF0YVJlc291cmNlczogRGF0YVJlc291cmNlW10gfSB7XG4gICAgY29uc3QgdmFsdWVzID0gW107XG4gICAgY29uc3QgZGF0YVJlc291cmNlcyA9IFtdO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJvd3MpIHtcbiAgICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnMpIHtcbiAgICAgICAgY29uc3Qgcm93Q29sdW1uVmFsdWUgPSB0aGlzLnZhbHVlc1tyb3ddW2NvbHVtbl07XG4gICAgICAgIGlmIChpc0FycmF5KHJvd0NvbHVtblZhbHVlKSkge1xuICAgICAgICAgIHZhbHVlcy5wdXNoKC4uLnJvd0NvbHVtblZhbHVlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZXMucHVzaChyb3dDb2x1bW5WYWx1ZSk7XG4gICAgICAgIH1cbiAgICAgICAgZGF0YVJlc291cmNlcy5wdXNoKC4uLih0aGlzLmRhdGFSZXNvdXJjZXM/Lltyb3ddPy5bY29sdW1uXSB8fCBbXSkpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4ge3ZhbHVlcywgZGF0YVJlc291cmNlc307XG4gIH1cblxuICBwcml2YXRlIGZpbGxDZWxsc0J5Q29sdW1ucyhjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdKTogSGVhZGVyR3JvdXBJbmZvW10ge1xuICAgIGNvbnN0IGNvbHVtbkdyb3VwcyA9IFtdO1xuICAgIHRoaXMuaXRlcmF0ZUFuZEZpbGxDZWxsc0J5Q29sdW1ucyhcbiAgICAgIGNlbGxzLFxuICAgICAgY29sdW1uR3JvdXBzLFxuICAgICAgdGhpcy5kYXRhLmNvbHVtbkhlYWRlcnMsXG4gICAgICB0aGlzLnJvd0xldmVscyxcbiAgICAgIHRoaXMuY29sdW1uU2hvd1N1bXMsXG4gICAgICAwXG4gICAgKTtcbiAgICByZXR1cm4gY29sdW1uR3JvdXBzO1xuICB9XG5cbiAgcHJpdmF0ZSBpdGVyYXRlQW5kRmlsbENlbGxzQnlDb2x1bW5zKFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgY29sdW1uR3JvdXBzSW5mbzogSGVhZGVyR3JvdXBJbmZvW10sXG4gICAgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gICAgc3RhcnRJbmRleDogbnVtYmVyLFxuICAgIHNob3dTdW1zOiBib29sZWFuW10sXG4gICAgbGV2ZWw6IG51bWJlcixcbiAgICBwYXJlbnRIZWFkZXI/OiBMbXJQaXZvdERhdGFIZWFkZXJcbiAgKSB7XG4gICAgbGV0IGN1cnJlbnRJbmRleCA9IHN0YXJ0SW5kZXg7XG4gICAgY29uc3QgbnVtYmVyT2ZTdW1zID0gTWF0aC5tYXgoMSwgdGhpcy5kYXRhLnZhbHVlVGl0bGVzLmxlbmd0aCk7XG4gICAgZm9yIChjb25zdCBoZWFkZXIgb2YgaGVhZGVycykge1xuICAgICAgY29uc3QgY29sU3BhbiA9IGdldERpcmVjdEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMsIG51bWJlck9mU3Vtcyk7XG4gICAgICBjZWxsc1tsZXZlbF1bY3VycmVudEluZGV4XSA9IHtcbiAgICAgICAgdmFsdWU6IHRoaXMuZm9ybWF0Q29sdW1uSGVhZGVyKGhlYWRlci50aXRsZSwgbGV2ZWwpLFxuICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5jb2x1bW5IZWFkZXJDbGFzcyxcbiAgICAgICAgaXNIZWFkZXI6IHRydWUsXG4gICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgIGNvbFNwYW4sXG4gICAgICAgIHN0aWNreVRvcDogdGhpcy5pc0NvbHVtbkxldmVsU3RpY2t5KGxldmVsKSxcbiAgICAgICAgYmFja2dyb3VuZDogdGhpcy5nZXRIZWFkZXJCYWNrZ3JvdW5kKGhlYWRlciwgbGV2ZWwpLFxuICAgICAgICBjb25zdHJhaW50OiBoZWFkZXIuY29uc3RyYWludCxcbiAgICAgICAgbGFiZWw6IGhlYWRlci5hdHRyaWJ1dGVOYW1lLFxuICAgICAgfTtcblxuICAgICAgaWYgKGhlYWRlci5jaGlsZHJlbikge1xuICAgICAgICB0aGlzLml0ZXJhdGVBbmRGaWxsQ2VsbHNCeUNvbHVtbnMoXG4gICAgICAgICAgY2VsbHMsXG4gICAgICAgICAgY29sdW1uR3JvdXBzSW5mbyxcbiAgICAgICAgICBoZWFkZXIuY2hpbGRyZW4sXG4gICAgICAgICAgY3VycmVudEluZGV4LFxuICAgICAgICAgIHNob3dTdW1zLFxuICAgICAgICAgIGxldmVsICsgMSxcbiAgICAgICAgICBoZWFkZXJcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQoaGVhZGVyLnRhcmdldEluZGV4KSkge1xuICAgICAgICB0aGlzLmZpbGxDZWxsc0ZvckNvbHVtbihjZWxscywgaGVhZGVyLnRhcmdldEluZGV4KTtcbiAgICAgIH1cblxuICAgICAgY3VycmVudEluZGV4ICs9IGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMsIG51bWJlck9mU3Vtcyk7XG4gICAgfVxuXG4gICAgaWYgKHNob3dTdW1zW2xldmVsXSkge1xuICAgICAgY29uc3QgYmFja2dyb3VuZCA9IHRoaXMuZ2V0U3VtbWFyeUJhY2tncm91bmQobGV2ZWwpO1xuICAgICAgY29uc3QgeyB0aXRsZSwgc3VtbWFyeSB9ID0gdGhpcy5mb3JtYXRTdW1tYXJ5SGVhZGVyKHBhcmVudEhlYWRlciwgbGV2ZWwpXG4gICAgICBjb25zdCBudW1iZXJPZlZhbHVlcyA9IHRoaXMuZGF0YS52YWx1ZVRpdGxlcy5sZW5ndGg7XG4gICAgICBjb25zdCByb3dJbmRleCA9IE1hdGgubWF4KGxldmVsIC0gMSwgMCk7XG4gICAgICBjb25zdCBzaG91bGRBZGRWYWx1ZUhlYWRlcnMgPSBudW1iZXJPZlZhbHVlcyA+IDE7XG5cbiAgICAgIGNlbGxzW3Jvd0luZGV4XVtjdXJyZW50SW5kZXhdID0ge1xuICAgICAgICB2YWx1ZTogdGl0bGUsXG4gICAgICAgIGNvbnN0cmFpbnQ6IHBhcmVudEhlYWRlcj8uY29uc3RyYWludCxcbiAgICAgICAgbGFiZWw6IHBhcmVudEhlYWRlcj8uYXR0cmlidXRlTmFtZSxcbiAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIuY29sdW1uR3JvdXBIZWFkZXJDbGFzcyxcbiAgICAgICAgaXNTdW1tYXJ5OiB0cnVlLFxuICAgICAgICBzdGlja3lUb3A6IHRoaXMuaXNDb2x1bW5MZXZlbFN0aWNreShsZXZlbCksXG4gICAgICAgIHJvd1NwYW46IHRoaXMuY29sdW1uTGV2ZWxzIC0gcm93SW5kZXggLSAoc2hvdWxkQWRkVmFsdWVIZWFkZXJzID8gMSA6IDApLFxuICAgICAgICBjb2xTcGFuOiBudW1iZXJPZlN1bXMsXG4gICAgICAgIGJhY2tncm91bmQsXG4gICAgICAgIHN1bW1hcnksXG4gICAgICB9O1xuXG4gICAgICBpZiAobnVtYmVyT2ZWYWx1ZXMgPiAwKSB7XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtYmVyT2ZWYWx1ZXM7IGkrKykge1xuICAgICAgICAgIGNvbnN0IGNvbHVtbkluZGV4SW5DZWxscyA9IGN1cnJlbnRJbmRleCArIGk7XG4gICAgICAgICAgaWYgKHNob3VsZEFkZFZhbHVlSGVhZGVycykge1xuICAgICAgICAgICAgY29uc3QgdmFsdWVUaXRsZSA9IHRoaXMuZGF0YS52YWx1ZVRpdGxlc1tpXTtcbiAgICAgICAgICAgIGNlbGxzW3RoaXMuY29sdW1uTGV2ZWxzIC0gMV1bY29sdW1uSW5kZXhJbkNlbGxzXSA9IHtcbiAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlVGl0bGUsXG4gICAgICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmNvbHVtbkdyb3VwSGVhZGVyQ2xhc3MsXG4gICAgICAgICAgICAgIGlzU3VtbWFyeTogdHJ1ZSxcbiAgICAgICAgICAgICAgc3RpY2t5VG9wOiB0aGlzLmlzQ29sdW1uTGV2ZWxTdGlja3kobGV2ZWwpLFxuICAgICAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgICAgICBiYWNrZ3JvdW5kLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBjb25zdCBjb2x1bW5zSW5kZXhlcyA9IGdldFRhcmdldEluZGV4ZXNGb3JIZWFkZXJzKGhlYWRlcnMpO1xuICAgICAgICAgIGNvbnN0IHZhbHVlQ29sdW1uc0luZGV4ZXMgPSBjb2x1bW5zSW5kZXhlcy5maWx0ZXIoaW5kZXggPT4gaW5kZXggJSBudW1iZXJPZlZhbHVlcyA9PT0gaSk7XG4gICAgICAgICAgY29uc3QgdHJhbnNmb3JtZWRDb2x1bW5JbmRleGVzID0gdmFsdWVDb2x1bW5zSW5kZXhlc1xuICAgICAgICAgICAgLm1hcCh2ID0+IHRoaXMuY29sdW1uc1RyYW5zZm9ybWF0aW9uQXJyYXlbdl0pXG4gICAgICAgICAgICAuZmlsdGVyKHYgPT4gaXNOb3ROdWxsT3JVbmRlZmluZWQodikpO1xuICAgICAgICAgIGNvbHVtbkdyb3Vwc0luZm9bY29sdW1uSW5kZXhJbkNlbGxzXSA9IHtiYWNrZ3JvdW5kLCBpbmRleGVzOiB0cmFuc2Zvcm1lZENvbHVtbkluZGV4ZXMsIGxldmVsfTtcblxuICAgICAgICAgIHRoaXMuZmlsbENlbGxzRm9yR3JvdXBlZENvbHVtbihjZWxscywgdmFsdWVDb2x1bW5zSW5kZXhlcywgY29sdW1uSW5kZXhJbkNlbGxzLCBiYWNrZ3JvdW5kKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29sdW1uR3JvdXBzSW5mb1tjdXJyZW50SW5kZXhdID0ge2JhY2tncm91bmQsIGluZGV4ZXM6IFtdLCBsZXZlbH07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ2VsbHNGb3JHcm91cGVkQ29sdW1uKFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgY29sdW1uczogbnVtYmVyW10sXG4gICAgY29sdW1uSW5kZXhJbkNlbGxzOiBudW1iZXIsXG4gICAgYmFja2dyb3VuZDogc3RyaW5nXG4gICkge1xuICAgIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXkubGVuZ3RoOyByb3crKykge1xuICAgICAgY29uc3Qgcm93SW5kZXhJbkNlbGxzID0gdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheVtyb3ddO1xuICAgICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKHJvd0luZGV4SW5DZWxscykpIHtcbiAgICAgICAgY29uc3Qge3ZhbHVlcywgZGF0YVJlc291cmNlc30gPSB0aGlzLmdldEdyb3VwZWRWYWx1ZXNGb3JSb3dzQW5kQ29scyhbcm93XSwgY29sdW1ucyk7XG4gICAgICAgIGNvbnN0IGZvcm1hdHRlZFZhbHVlID0gdGhpcy5hZ2dyZWdhdGVBbmRGb3JtYXREYXRhVmFsdWVzKHZhbHVlcywgW3Jvd10sIGNvbHVtbnMpO1xuICAgICAgICBjZWxsc1tyb3dJbmRleEluQ2VsbHNdW2NvbHVtbkluZGV4SW5DZWxsc10gPSB7XG4gICAgICAgICAgdmFsdWU6IFN0cmluZyhmb3JtYXR0ZWRWYWx1ZSksXG4gICAgICAgICAgZGF0YVJlc291cmNlcyxcbiAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIuZ3JvdXBEYXRhQ2xhc3MsXG4gICAgICAgICAgYmFja2dyb3VuZCxcbiAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWdncmVnYXRlQW5kRm9ybWF0RGF0YVZhbHVlcyh2YWx1ZXM6IGFueVtdLCByb3dzOiBudW1iZXJbXSwgY29sdW1uczogbnVtYmVyW10pOiBhbnkge1xuICAgIGNvbnN0IHt2YWx1ZSwgYWdncmVnYXRpb259ID0gdGhpcy5hZ2dyZWdhdGVEYXRhVmFsdWVzKHZhbHVlcywgY29sdW1ucyk7XG4gICAgcmV0dXJuIGFnZ3JlZ2F0aW9uID09PSBEYXRhQWdncmVnYXRpb25UeXBlLkpvaW4gPyB2YWx1ZSA6IHRoaXMuZm9ybWF0R3JvdXBlZFZhbHVlQnlWYWx1ZVR5cGUodmFsdWUsIHJvd3MsIGNvbHVtbnMpXG4gIH1cblxuICBwcml2YXRlIGFnZ3JlZ2F0ZURhdGFWYWx1ZXModmFsdWVzOiBhbnlbXSwgY29sdW1uczogbnVtYmVyW10pOiB7dmFsdWU6IGFueTsgYWdncmVnYXRpb246IERhdGFBZ2dyZWdhdGlvblR5cGV9IHtcbiAgICBjb25zdCBhZ2dyZWdhdGlvbiA9IHRoaXMuYWdncmVnYXRpb25CeUNvbHVtbnMoY29sdW1ucyk7XG4gICAgaWYgKGFnZ3JlZ2F0aW9uID09PSBEYXRhQWdncmVnYXRpb25UeXBlLkpvaW4pIHtcbiAgICAgIGNvbnN0IHZhbHVlSW5kZXggPSB0aGlzLmdldFZhbHVlSW5kZXhGb3JDb2x1bW5zKGNvbHVtbnMpO1xuICAgICAgY29uc3QgY29uc3RyYWludCA9IHRoaXMuZGF0YS52YWx1ZXNDb25zdHJhaW50cz8uW3ZhbHVlSW5kZXhdIHx8IHRoaXMudmFsdWVUeXBlSW5mb1t2YWx1ZUluZGV4XT8uZGVmYXVsdENvbnN0cmFpbnQ7XG4gICAgICByZXR1cm4ge3ZhbHVlOiBhZ2dyZWdhdGVEYXRhVmFsdWVzKGFnZ3JlZ2F0aW9uLCB2YWx1ZXMsIGNvbnN0cmFpbnQsIGZhbHNlLCB0aGlzLmNvbnN0cmFpbnREYXRhKSwgYWdncmVnYXRpb259O1xuICAgIH1cbiAgICByZXR1cm4ge3ZhbHVlOiBhZ2dyZWdhdGVEYXRhVmFsdWVzKGFnZ3JlZ2F0aW9uLCB2YWx1ZXMpLCBhZ2dyZWdhdGlvbn07XG4gIH1cblxuICBwcml2YXRlIGFnZ3JlZ2F0aW9uQnlDb2x1bW5zKGNvbHVtbnM6IG51bWJlcltdKTogRGF0YUFnZ3JlZ2F0aW9uVHlwZSB7XG4gICAgY29uc3QgdmFsdWVJbmRleCA9IGNvbHVtbnNbMF0gJSB0aGlzLmRhdGEudmFsdWVUaXRsZXMubGVuZ3RoO1xuICAgIGNvbnN0IGFnZ3JlZ2F0aW9uID0gdGhpcy5kYXRhLnZhbHVlQWdncmVnYXRpb25zPy5bdmFsdWVJbmRleF07XG4gICAgcmV0dXJuIGlzVmFsdWVBZ2dyZWdhdGlvbihhZ2dyZWdhdGlvbikgPyBhZ2dyZWdhdGlvbiA6IERhdGFBZ2dyZWdhdGlvblR5cGUuU3VtO1xuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ2VsbHNGb3JDb2x1bW4oY2VsbHM6IExtclBpdm90VGFibGVDZWxsW11bXSwgY29sdW1uOiBudW1iZXIpIHtcbiAgICBjb25zdCBjb2x1bW5JbmRleEluQ2VsbHMgPSB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5W2NvbHVtbl07XG4gICAgaWYgKGlzTm90TnVsbE9yVW5kZWZpbmVkKGNvbHVtbkluZGV4SW5DZWxscykpIHtcbiAgICAgIGZvciAobGV0IHJvdyA9IDA7IHJvdyA8IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXkubGVuZ3RoOyByb3crKykge1xuICAgICAgICBjb25zdCByb3dJbmRleEluQ2VsbHMgPSB0aGlzLnJvd3NUcmFuc2Zvcm1hdGlvbkFycmF5W3Jvd107XG4gICAgICAgIGlmIChpc05vdE51bGxPclVuZGVmaW5lZChyb3dJbmRleEluQ2VsbHMpKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLmRhdGEudmFsdWVzW3Jvd11bY29sdW1uXTtcbiAgICAgICAgICBjb25zdCBkYXRhUmVzb3VyY2VzID0gdGhpcy5kYXRhUmVzb3VyY2VzPy5bcm93XT8uW2NvbHVtbl0gfHwgW107XG4gICAgICAgICAgY29uc3QgZm9ybWF0dGVkVmFsdWUgPSB0aGlzLmFnZ3JlZ2F0ZU9yRm9ybWF0U2luZ2xlVmFsdWUodmFsdWUsIGNvbHVtbik7XG4gICAgICAgICAgY29uc3Qgc3RyaW5nVmFsdWUgPSBpc05vdE51bGxPclVuZGVmaW5lZChmb3JtYXR0ZWRWYWx1ZSkgPyBTdHJpbmcoZm9ybWF0dGVkVmFsdWUpIDogJyc7XG4gICAgICAgICAgY2VsbHNbcm93SW5kZXhJbkNlbGxzXVtjb2x1bW5JbmRleEluQ2VsbHNdID0ge1xuICAgICAgICAgICAgdmFsdWU6IHN0cmluZ1ZhbHVlLFxuICAgICAgICAgICAgZGF0YVJlc291cmNlcyxcbiAgICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIuZGF0YUNsYXNzLFxuICAgICAgICAgICAgaXNWYWx1ZTogdHJ1ZSxcbiAgICAgICAgICB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBhZ2dyZWdhdGVPckZvcm1hdFNpbmdsZVZhbHVlKHZhbHVlOiBhbnksIGNvbHVtbjogbnVtYmVyKTogYW55IHtcbiAgICBjb25zdCBhZ2dyZWdhdGlvbiA9IHRoaXMuYWdncmVnYXRpb25CeUNvbHVtbnMoW2NvbHVtbl0pO1xuICAgIGNvbnN0IHZhbHVlSW5kZXggPSB0aGlzLmdldFZhbHVlSW5kZXhGb3JDb2x1bW5zKFtjb2x1bW5dKTtcbiAgICBpZiAoYWdncmVnYXRpb24gPT09IERhdGFBZ2dyZWdhdGlvblR5cGUuSm9pbikge1xuICAgICAgY29uc3QgY29uc3RyYWludCA9IHRoaXMuZGF0YS52YWx1ZXNDb25zdHJhaW50cz8uW3ZhbHVlSW5kZXhdIHx8IHRoaXMudmFsdWVUeXBlSW5mb1t2YWx1ZUluZGV4XT8uZGVmYXVsdENvbnN0cmFpbnQ7XG4gICAgICByZXR1cm4gYWdncmVnYXRlRGF0YVZhbHVlcyhhZ2dyZWdhdGlvbiwgW3ZhbHVlXSwgY29uc3RyYWludCwgZmFsc2UsIHRoaXMuY29uc3RyYWludERhdGEpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5mb3JtYXRWYWx1ZUJ5VmFsdWVUeXBlKHZhbHVlLCB2YWx1ZUluZGV4KTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbENlbGxzQnlHcm91cEludGVyc2VjdGlvbihcbiAgICBjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLFxuICAgIHJvd0dyb3Vwc0luZm86IEhlYWRlckdyb3VwSW5mb1tdLFxuICAgIGNvbHVtbkdyb3Vwc0luZm86IEhlYWRlckdyb3VwSW5mb1tdXG4gICkge1xuICAgIGNvbnN0IHJvd3NDb3VudCA9IGNlbGxzLmxlbmd0aDtcbiAgICBjb25zdCBjb2x1bW5zQ291bnQgPSBjZWxsc1swXT8ubGVuZ3RoIHx8IDA7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJvd0dyb3Vwc0luZm8ubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IHJvd0dyb3VwSW5mbyA9IHJvd0dyb3Vwc0luZm9baV07XG4gICAgICBpZiAoIXJvd0dyb3VwSW5mbykge1xuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBmb3IgKGxldCBqID0gMDsgaiA8IGNvbHVtbkdyb3Vwc0luZm8ubGVuZ3RoOyBqKyspIHtcbiAgICAgICAgaWYgKCFjb2x1bW5Hcm91cHNJbmZvW2pdKSB7XG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGNvbHVtbnMgPSBjb2x1bW5Hcm91cHNJbmZvW2pdLmluZGV4ZXNcbiAgICAgICAgY29uc3Qge3Jvd3NJbmRleGVzLCBjb2x1bW5zSW5kZXhlc30gPSB0aGlzLmdldFZhbHVlc0luZGV4ZXNGcm9tQ2VsbHNJbmRleGVzKFxuICAgICAgICAgIHJvd0dyb3VwSW5mby5pbmRleGVzLFxuICAgICAgICAgIGNvbHVtbnNcbiAgICAgICAgKTtcbiAgICAgICAgbGV0IGZvcm1hdHRlZFZhbHVlOiBzdHJpbmc7XG4gICAgICAgIGxldCBkYXRhUmVzb3VyY2VzOiBEYXRhUmVzb3VyY2VbXTtcbiAgICAgICAgaWYgKHJvd0dyb3VwSW5mby5leHByZXNzaW9uKSB7XG4gICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5ldmFsdWF0ZUV4cHJlc3Npb24ocm93R3JvdXBJbmZvLmV4cHJlc3Npb24sIGNvbHVtbnNJbmRleGVzKTtcbiAgICAgICAgICBjb25zdCB2YWx1ZUluZGV4ID0gY29sdW1uc0luZGV4ZXNbMF0gJSB0aGlzLmRhdGEudmFsdWVUaXRsZXMubGVuZ3RoO1xuICAgICAgICAgIGZvcm1hdHRlZFZhbHVlID0gdGhpcy5mb3JtYXRWYWx1ZUJ5Q29uc3RyYWludChyZXN1bHQudmFsdWUsIHZhbHVlSW5kZXgpO1xuICAgICAgICAgIGRhdGFSZXNvdXJjZXMgPSByZXN1bHQuZGF0YVJlc291cmNlc1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGl0J3MgZW5vdWdoIHRvIGZpbGwgZ3JvdXAgdmFsdWVzIG9ubHkgZnJvbSByb3cgc2lkZVxuICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuZ2V0R3JvdXBlZFZhbHVlc0ZvclJvd3NBbmRDb2xzKHJvd3NJbmRleGVzLCBjb2x1bW5zSW5kZXhlcyk7XG4gICAgICAgICAgZm9ybWF0dGVkVmFsdWUgPSB0aGlzLmFnZ3JlZ2F0ZUFuZEZvcm1hdERhdGFWYWx1ZXMocmVzdWx0LnZhbHVlcywgcm93c0luZGV4ZXMsIGNvbHVtbnNJbmRleGVzKTtcbiAgICAgICAgICBkYXRhUmVzb3VyY2VzID0gcmVzdWx0LmRhdGFSZXNvdXJjZXNcbiAgICAgICAgfVxuICAgICAgICBjZWxsc1tpXVtqXSA9IHtcbiAgICAgICAgICB2YWx1ZTogU3RyaW5nKGZvcm1hdHRlZFZhbHVlKSxcbiAgICAgICAgICBkYXRhUmVzb3VyY2VzLFxuICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5ncm91cERhdGFDbGFzcyxcbiAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICB9O1xuXG4gICAgICB9XG5cbiAgICAgIHRoaXMuZmlsbFJvd1dpdGhDb2xvcihjZWxscywgaSwgcm93R3JvdXBJbmZvLCBjb2x1bW5zQ291bnQpO1xuICAgIH1cblxuICAgIGZvciAobGV0IGogPSAwOyBqIDwgY29sdW1uR3JvdXBzSW5mby5sZW5ndGg7IGorKykge1xuICAgICAgaWYgKGNvbHVtbkdyb3Vwc0luZm9bal0pIHtcbiAgICAgICAgdGhpcy5maWxsQ29sdW1uV2l0aENvbG9yKGNlbGxzLCBqLCBjb2x1bW5Hcm91cHNJbmZvW2pdLCByb3dHcm91cHNJbmZvLCByb3dzQ291bnQpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZ2V0VmFsdWVzSW5kZXhlc0Zyb21DZWxsc0luZGV4ZXMoXG4gICAgcm93czogbnVtYmVyW10sXG4gICAgY29sdW1uczogbnVtYmVyW11cbiAgKTogeyByb3dzSW5kZXhlczogbnVtYmVyW107IGNvbHVtbnNJbmRleGVzOiBudW1iZXJbXSB9IHtcbiAgICBjb25zdCByb3dzSW5kZXhlcyA9IHJvd3NcbiAgICAgIC5tYXAocm93ID0+IHRoaXMucm93c1RyYW5zZm9ybWF0aW9uQXJyYXkuZmluZEluZGV4KHRSb3cgPT4gdFJvdyA9PT0gcm93KSlcbiAgICAgIC5maWx0ZXIoaW5kZXggPT4gaW5kZXggPj0gMCk7XG4gICAgY29uc3QgY29sdW1uc0luZGV4ZXMgPSBjb2x1bW5zXG4gICAgICAubWFwKGNvbHVtbiA9PiB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5LmZpbmRJbmRleCh0Q29sdW1uID0+IHRDb2x1bW4gPT09IGNvbHVtbikpXG4gICAgICAuZmlsdGVyKGluZGV4ID0+IGluZGV4ID49IDApO1xuICAgIHJldHVybiB7cm93c0luZGV4ZXMsIGNvbHVtbnNJbmRleGVzfTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsbFJvd1dpdGhDb2xvcihcbiAgICBjZWxsczogTG1yUGl2b3RUYWJsZUNlbGxbXVtdLFxuICAgIHJvdzogbnVtYmVyLFxuICAgIHJvd0dyb3VwSW5mbzogSGVhZGVyR3JvdXBJbmZvLFxuICAgIGNvbHVtbnNDb3VudDogbnVtYmVyXG4gICkge1xuICAgIGZvciAobGV0IGkgPSB0aGlzLnJvd0xldmVsczsgaSA8IGNvbHVtbnNDb3VudDsgaSsrKSB7XG4gICAgICBjZWxsc1tyb3ddW2ldICYmIChjZWxsc1tyb3ddW2ldLmJhY2tncm91bmQgPSByb3dHcm91cEluZm8uYmFja2dyb3VuZCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmaWxsQ29sdW1uV2l0aENvbG9yKFxuICAgIGNlbGxzOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10sXG4gICAgY29sdW1uOiBudW1iZXIsXG4gICAgY29sdW1uR3JvdXBJbmZvOiBIZWFkZXJHcm91cEluZm8sXG4gICAgcm93R3JvdXBzSW5mbzogSGVhZGVyR3JvdXBJbmZvW10sXG4gICAgcm93Q291bnQ6IG51bWJlclxuICApIHtcbiAgICBmb3IgKGxldCBpID0gdGhpcy5jb2x1bW5MZXZlbHM7IGkgPCByb3dDb3VudDsgaSsrKSB7XG4gICAgICBjb25zdCByb3dHcm91cEluZm8gPSByb3dHcm91cHNJbmZvW2ldO1xuICAgICAgaWYgKCFyb3dHcm91cEluZm8gfHwgcm93R3JvdXBJbmZvLmxldmVsID4gY29sdW1uR3JvdXBJbmZvLmxldmVsKSB7XG4gICAgICAgIGNlbGxzW2ldW2NvbHVtbl0gJiYgKGNlbGxzW2ldW2NvbHVtbl0uYmFja2dyb3VuZCA9IGNvbHVtbkdyb3VwSW5mby5iYWNrZ3JvdW5kKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGluaXRDZWxscygpOiBMbXJQaXZvdFRhYmxlQ2VsbFtdW10ge1xuICAgIGNvbnN0IHJvd3MgPSB0aGlzLmdldFJvd3NDb3VudCgpICsgdGhpcy5jb2x1bW5MZXZlbHM7XG4gICAgY29uc3QgY29sdW1ucyA9IHRoaXMuZ2V0Q29sdW1uc0NvdW50KCkgKyB0aGlzLnJvd0xldmVscztcblxuICAgIGNvbnN0IG1hdHJpeDogTG1yUGl2b3RUYWJsZUNlbGxbXVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzOyBpKyspIHtcbiAgICAgIG1hdHJpeFtpXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjb2x1bW5zOyBqKyspIHtcbiAgICAgICAgaWYgKGkgPj0gdGhpcy5jb2x1bW5MZXZlbHMgJiYgaiA+PSB0aGlzLnJvd0xldmVscykge1xuICAgICAgICAgIGNvbnN0IGlzRGF0YUNsYXNzID0gdGhpcy5yb3dzVHJhbnNmb3JtYXRpb25BcnJheS5pbmNsdWRlcyhpKSAmJiB0aGlzLmNvbHVtbnNUcmFuc2Zvcm1hdGlvbkFycmF5LmluY2x1ZGVzKGopO1xuICAgICAgICAgIG1hdHJpeFtpXVtqXSA9IHtcbiAgICAgICAgICAgIHZhbHVlOiAnJyxcbiAgICAgICAgICAgIGRhdGFSZXNvdXJjZXM6IFtdLFxuICAgICAgICAgICAgY3NzQ2xhc3M6IGlzRGF0YUNsYXNzID8gUGl2b3RUYWJsZUNvbnZlcnRlci5kYXRhQ2xhc3MgOiBQaXZvdFRhYmxlQ29udmVydGVyLmdyb3VwRGF0YUNsYXNzLFxuICAgICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICBpc1ZhbHVlOiB0cnVlLFxuICAgICAgICAgIH07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgbWF0cml4W2ldW2pdID0gdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMucm93TGV2ZWxzID4gMCAmJiB0aGlzLmNvbHVtbkxldmVscyA+IDApIHtcbiAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgdGhpcy5yb3dMZXZlbHM7IGorKykge1xuICAgICAgICBjb25zdCByb3dIZWFkZXJBdHRyaWJ1dGUgPSB0aGlzLmRhdGEucm93SGVhZGVyQXR0cmlidXRlc1tqXTtcbiAgICAgICAgaWYgKHJvd0hlYWRlckF0dHJpYnV0ZSkge1xuICAgICAgICAgIGNvbnN0IHRpdGxlUm93U3BhbiA9IHRoaXMubm9uU3RpY2t5Q29sdW1uSW5kZXggfHwgdGhpcy5jb2x1bW5MZXZlbHNcbiAgICAgICAgICBtYXRyaXhbMF1bal0gPSB7XG4gICAgICAgICAgICB2YWx1ZTogcm93SGVhZGVyQXR0cmlidXRlLnRpdGxlLFxuICAgICAgICAgICAgY3NzQ2xhc3M6IFBpdm90VGFibGVDb252ZXJ0ZXIucm93QXR0cmlidXRlSGVhZGVyQ2xhc3MsXG4gICAgICAgICAgICBpc0F0dHJpYnV0ZUhlYWRlcjogdHJ1ZSxcbiAgICAgICAgICAgIHJvd1NwYW46IHRpdGxlUm93U3BhbixcbiAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICBzdGlja3lUb3A6IHRoaXMuaXNDb2x1bW5MZXZlbFN0aWNreSgwKSxcbiAgICAgICAgICAgIHN0aWNreVN0YXJ0OiB0aGlzLmlzUm93TGV2ZWxTdGlja3koaiksXG4gICAgICAgICAgICBiYWNrZ3JvdW5kOiByb3dIZWFkZXJBdHRyaWJ1dGUuY29sb3IsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIGlmICh0aGlzLmNvbHVtbkxldmVscyAtIHRpdGxlUm93U3BhbiA+IDApIHtcbiAgICAgICAgICAgIG1hdHJpeFt0aGlzLm5vblN0aWNreUNvbHVtbkluZGV4XVtqXSA9IHtcbiAgICAgICAgICAgICAgdmFsdWU6ICcnLFxuICAgICAgICAgICAgICBjc3NDbGFzczogUGl2b3RUYWJsZUNvbnZlcnRlci5yb3dBdHRyaWJ1dGVIZWFkZXJDbGFzcyxcbiAgICAgICAgICAgICAgaXNBdHRyaWJ1dGVIZWFkZXI6IHRydWUsXG4gICAgICAgICAgICAgIHJvd1NwYW46IHRoaXMuY29sdW1uTGV2ZWxzIC0gdGl0bGVSb3dTcGFuLFxuICAgICAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgICAgICBiYWNrZ3JvdW5kOiByb3dIZWFkZXJBdHRyaWJ1dGUuY29sb3IsXG4gICAgICAgICAgICAgIHN0aWNreVN0YXJ0OiB0aGlzLmlzUm93TGV2ZWxTdGlja3koaiksXG4gICAgICAgICAgICB9O1xuICAgICAgICAgIH1cblxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5jb2x1bW5MZXZlbHM7IGkrKykge1xuICAgICAgICAgICAgbWF0cml4W2ldW2pdID0ge1xuICAgICAgICAgICAgICB2YWx1ZTogJycsXG4gICAgICAgICAgICAgIGNzc0NsYXNzOiBQaXZvdFRhYmxlQ29udmVydGVyLmVtcHR5Q2xhc3MsXG4gICAgICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICAgIHN0aWNreVN0YXJ0OiB0aGlzLmlzUm93TGV2ZWxTdGlja3koaiksXG4gICAgICAgICAgICAgIHN0aWNreVRvcDogdGhpcy5pc0NvbHVtbkxldmVsU3RpY2t5KGkpLFxuICAgICAgICAgICAgICBpc0hlYWRlcjogZmFsc2UsXG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG1hdHJpeDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Um93c0NvdW50KCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuZGF0YS5yb3dIZWFkZXJzLmxlbmd0aCA9PT0gMCAmJiAodGhpcy5kYXRhLnZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gICAgcmV0dXJuIGdldEhlYWRlcnNDaGlsZENvdW50KHRoaXMuZGF0YS5yb3dIZWFkZXJzLCB0aGlzLnJvd1Nob3dTdW1zKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0Q29sdW1uc0NvdW50KCk6IG51bWJlciB7XG4gICAgaWYgKHRoaXMuZGF0YS5jb2x1bW5IZWFkZXJzLmxlbmd0aCA9PT0gMCAmJiAodGhpcy5kYXRhLnZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGggPiAwKSB7XG4gICAgICByZXR1cm4gMTtcbiAgICB9XG4gICAgY29uc3QgbnVtYmVyT2ZTdW1zID0gTWF0aC5tYXgoMSwgKHRoaXMuZGF0YS52YWx1ZVRpdGxlcyB8fCBbXSkubGVuZ3RoKTtcbiAgICByZXR1cm4gZ2V0SGVhZGVyc0NoaWxkQ291bnQodGhpcy5kYXRhLmNvbHVtbkhlYWRlcnMsIHRoaXMuY29sdW1uU2hvd1N1bXMsIG51bWJlck9mU3Vtcyk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcHJlcGFyZVBpdm90RGF0YShcbiAgZGF0YTogTG1yUGl2b3RTdGVtRGF0YSxcbiAgY29uc3RyYWludERhdGE6IENvbnN0cmFpbnREYXRhLFxuICB2YWx1ZVR5cGVJbmZvOiBWYWx1ZVR5cGVJbmZvW11cbik6IExtclBpdm90U3RlbURhdGEge1xuICBjb25zdCBudW1iZXJPZlN1bXMgPSBNYXRoLm1heCgxLCAoZGF0YS52YWx1ZVRpdGxlcyB8fCBbXSkubGVuZ3RoKTtcbiAgY29uc3QgdmFsdWVzID0gY29tcHV0ZVZhbHVlc0J5VmFsdWVUeXBlKGRhdGEudmFsdWVzLCBkYXRhLnZhbHVlVHlwZXMsIG51bWJlck9mU3VtcywgdmFsdWVUeXBlSW5mbyk7XG4gIGNvbnN0IHNvcnRlZCA9IHNvcnRQaXZvdERhdGEoey4uLmRhdGEsIHZhbHVlc30sIGNvbnN0cmFpbnREYXRhKTtcbiAgcmV0dXJuIGZpbGxFeHByZXNzaW9uc1RvRGF0YShzb3J0ZWQpXG59XG5cbmZ1bmN0aW9uIGZpbGxFeHByZXNzaW9uc1RvRGF0YShkYXRhOiBMbXJQaXZvdFN0ZW1EYXRhKTogTG1yUGl2b3RTdGVtRGF0YSB7XG4gIHJldHVybiB7XG4gICAgLi4uZGF0YSxcbiAgICByb3dIZWFkZXJzOiBmaWxsRXhwcmVzc2lvbnNUb0hlYWRlcnMoZGF0YS5yb3dIZWFkZXJzLCBkYXRhLnJvd3NDb25maWcsIDApLFxuICAgIGNvbHVtbkhlYWRlcnM6IGZpbGxFeHByZXNzaW9uc1RvSGVhZGVycyhkYXRhLmNvbHVtbkhlYWRlcnMsIGRhdGEuY29sdW1uc0NvbmZpZywgMCksXG4gIH1cbn1cblxuZnVuY3Rpb24gZmlsbEV4cHJlc3Npb25zVG9IZWFkZXJzKGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLCBjb25maWdzOiBMbXJQaXZvdERpbWVuc2lvbkNvbmZpZ1tdLCBpbmRleDogbnVtYmVyKTogTG1yUGl2b3REYXRhSGVhZGVyW10ge1xuICBjb25zdCBleHByZXNzaW9ucyA9IGNvbmZpZ3M/LltpbmRleF0/LmV4cHJlc3Npb25zIHx8IFtdXG4gIGNvbnN0IGhlYWRlcnNDb3B5ID0gWy4uLihoZWFkZXJzIHx8IFtdKV1cbiAgZm9yIChjb25zdCBleHByZXNzaW9uIG9mIGV4cHJlc3Npb25zKSB7XG4gICAgY29uc3QgZGF0YUhlYWRlckV4cHJlc3Npb24gPSBleHRlbmRQaXZvdEV4cHJlc3Npb24oZXhwcmVzc2lvbiwgaGVhZGVycylcbiAgICBpZiAoZGF0YUhlYWRlckV4cHJlc3Npb24uZmlyc3RIZWFkZXJJbmRleCA+PSAwKSB7XG4gICAgICBjb25zdCBmaXJzdEhlYWRlckluZGV4ID0gZGF0YUhlYWRlckV4cHJlc3Npb24uZmlyc3RIZWFkZXJJbmRleFxuICAgICAgY29uc3QgbmV3SGVhZGVyOiBMbXJQaXZvdERhdGFIZWFkZXIgPSB7Li4uaGVhZGVyc0NvcHlbZmlyc3RIZWFkZXJJbmRleF0sIGV4cHJlc3Npb25zOiBbLi4uKGhlYWRlcnNDb3B5W2ZpcnN0SGVhZGVySW5kZXhdLmV4cHJlc3Npb25zIHx8IFtdKSwgZGF0YUhlYWRlckV4cHJlc3Npb25dfVxuICAgICAgaGVhZGVyc0NvcHkuc3BsaWNlKGZpcnN0SGVhZGVySW5kZXgsIDEsIG5ld0hlYWRlcilcbiAgICB9XG4gIH1cblxuICBpZiAoY29uZmlncz8uW2luZGV4ICsgMV0pIHtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhlYWRlcnNDb3B5Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBoZWFkZXJzQ29weS5zcGxpY2UoaSwgMSwgey4uLmhlYWRlcnNDb3B5W2ldLCBjaGlsZHJlbjogZmlsbEV4cHJlc3Npb25zVG9IZWFkZXJzKGhlYWRlcnNDb3B5W2ldLmNoaWxkcmVuLCBjb25maWdzLCBpbmRleCArIDEpfSlcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaGVhZGVyc0NvcHlcbn1cblxuZnVuY3Rpb24gZXh0ZW5kUGl2b3RFeHByZXNzaW9uKGV4cHJlc3Npb246IExtclBpdm90RXhwcmVzc2lvbiwgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10pOiBMbXJQaXZvdERhdGFIZWFkZXJFeHByZXNzaW9uIHtcbiAgY29uc3QgZGF0YUhlYWRlck9wZXJhbmRzOiBMbXJQaXZvdERhdGFIZWFkZXJPcGVyYW5kW10gPSBbXTtcbiAgbGV0IGZpcnN0SGVhZGVySW5kZXg6IG51bWJlciA9IE51bWJlci5NQVhfU0FGRV9JTlRFR0VSXG5cbiAgZnVuY3Rpb24gdHJhdmVyc2Uob3BlcmFuZHM6IExtclBpdm90T3BlcmFuZFtdKTogdm9pZCB7XG4gICAgZm9yIChjb25zdCBvcGVyYW5kIG9mIG9wZXJhbmRzKSB7XG4gICAgICBpZiAob3BlcmFuZC50eXBlID09PSAnaGVhZGVyJykge1xuICAgICAgICBjb25zdCBpbmRleGVzID0gZ2V0T3BlcmFuZEluZGV4ZXNJbkhlYWRlcnMob3BlcmFuZCwgaGVhZGVycylcbiAgICAgICAgZmlyc3RIZWFkZXJJbmRleCA9IE1hdGgubWluKGZpcnN0SGVhZGVySW5kZXgsIC4uLmluZGV4ZXMpXG4gICAgICAgIGNvbnN0IG9wZXJhbmRIZWFkZXJzID0gaW5kZXhlcy5tYXAoaW5kZXggPT4gaGVhZGVyc1tpbmRleF0pXG4gICAgICAgIGRhdGFIZWFkZXJPcGVyYW5kcy5wdXNoKHsuLi5vcGVyYW5kLCBoZWFkZXJzOiBvcGVyYW5kSGVhZGVyc30pO1xuICAgICAgfSBlbHNlIGlmIChvcGVyYW5kLnR5cGUgPT09ICdleHByZXNzaW9uJykge1xuICAgICAgICB0cmF2ZXJzZShvcGVyYW5kLm9wZXJhbmRzKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRhdGFIZWFkZXJPcGVyYW5kcy5wdXNoKG9wZXJhbmQpXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdHJhdmVyc2UoZXhwcmVzc2lvbi5vcGVyYW5kcyk7XG5cbiAgaWYgKGV4cHJlc3Npb24ucG9zaXRpb24gPT09IExtclBpdm90UG9zaXRpb24uU3RpY2tUb0VuZCkge1xuICAgIGZpcnN0SGVhZGVySW5kZXggPSBoZWFkZXJzLmxlbmd0aCAtIDFcbiAgfVxuXG4gIGlmIChmaXJzdEhlYWRlckluZGV4ID09PSBOdW1iZXIuTUFYX1NBRkVfSU5URUdFUikge1xuICAgIGZpcnN0SGVhZGVySW5kZXggPSAtMVxuICB9XG5cbiAgcmV0dXJuIHsuLi5leHByZXNzaW9uLCBmaXJzdEhlYWRlckluZGV4LCBvcGVyYW5kczogZGF0YUhlYWRlck9wZXJhbmRzfTtcbn1cblxuZnVuY3Rpb24gZ2V0T3BlcmFuZEluZGV4ZXNJbkhlYWRlcnMob3BlcmFuZDogTG1yUGl2b3RIZWFkZXJPcGVyYW5kLCBoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSk6IG51bWJlcltdIHtcbiAgcmV0dXJuIChoZWFkZXJzIHx8IFtdKS5yZWR1Y2U8bnVtYmVyW10+KChpbmRleGVzLCBoZWFkZXIsIGluZGV4KSA9PiB7XG4gICAgaWYgKG9wZXJhbmRDb250YWluc0hlYWRlcihvcGVyYW5kLCBoZWFkZXIpKSB7XG4gICAgICBpbmRleGVzLnB1c2goaW5kZXgpXG4gICAgfVxuICAgIHJldHVybiBpbmRleGVzXG4gIH0sIFtdKVxufVxuXG5mdW5jdGlvbiBvcGVyYW5kQ29udGFpbnNIZWFkZXIob3BlcmFuZDogTG1yUGl2b3RIZWFkZXJPcGVyYW5kLCBoZWFkZXI6IExtclBpdm90RGF0YUhlYWRlcik6IGJvb2xlYW4ge1xuICByZXR1cm4gaGVhZGVyLnRpdGxlLm1hdGNoKG5ldyBSZWdFeHAob3BlcmFuZC52YWx1ZSkpPy5sZW5ndGggPiAwXG59XG5cbmZ1bmN0aW9uIGNvbXB1dGVWYWx1ZXNCeVZhbHVlVHlwZShcbiAgdmFsdWVzOiBhbnlbXVtdLFxuICB2YWx1ZVR5cGVzOiBMbXJQaXZvdFZhbHVlVHlwZVtdLFxuICBudW1WYWx1ZXM6IG51bWJlcixcbiAgdmFsdWVUeXBlSW5mbzogVmFsdWVUeXBlSW5mb1tdXG4pOiBhbnlbXVtdIHtcbiAgY29uc3Qgcm93c0luZGV4ZXMgPSBbLi4uQXJyYXkodmFsdWVzLmxlbmd0aCkua2V5cygpXTtcbiAgY29uc3QgbW9kaWZpZWRWYWx1ZXMgPSBkZWVwT2JqZWN0Q29weSh2YWx1ZXMpO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgbnVtVmFsdWVzOyBpKyspIHtcbiAgICBjb25zdCB2YWx1ZVR5cGUgPSB2YWx1ZVR5cGVzICYmIHZhbHVlVHlwZXNbaV07XG4gICAgaWYgKCF2YWx1ZVR5cGUgfHwgdmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5EZWZhdWx0KSB7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBjb25zdCBjb2x1bW5zQ291bnQgPSAodmFsdWVzWzBdICYmIHZhbHVlc1swXS5sZW5ndGgpIHx8IDA7XG4gICAgY29uc3QgY29sdW1uSW5kZXhlcyA9IFsuLi5BcnJheShjb2x1bW5zQ291bnQpLmtleXMoKV0uZmlsdGVyKGtleSA9PiBrZXkgJSBudW1WYWx1ZXMgPT09IGkpO1xuICAgIGNvbnN0IGluZm8gPSB2YWx1ZVR5cGVJbmZvW2ldO1xuXG4gICAgZm9yIChjb25zdCByb3cgb2Ygcm93c0luZGV4ZXMpIHtcbiAgICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbkluZGV4ZXMpIHtcbiAgICAgICAgaWYgKHZhbHVlVHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuQWxsUGVyY2VudGFnZSkge1xuICAgICAgICAgIG1vZGlmaWVkVmFsdWVzW3Jvd11bY29sdW1uXSA9IGRpdmlkZVZhbHVlcyh2YWx1ZXNbcm93XVtjb2x1bW5dLCBpbmZvLnN1bSk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5Sb3dQZXJjZW50YWdlKSB7XG4gICAgICAgICAgbW9kaWZpZWRWYWx1ZXNbcm93XVtjb2x1bW5dID0gZGl2aWRlVmFsdWVzKHZhbHVlc1tyb3ddW2NvbHVtbl0sIGluZm8uc3Vtc1Jvd3Nbcm93XSk7XG4gICAgICAgIH0gZWxzZSBpZiAodmFsdWVUeXBlID09PSBMbXJQaXZvdFZhbHVlVHlwZS5Db2x1bW5QZXJjZW50YWdlKSB7XG4gICAgICAgICAgbW9kaWZpZWRWYWx1ZXNbcm93XVtjb2x1bW5dID0gZGl2aWRlVmFsdWVzKHZhbHVlc1tyb3ddW2NvbHVtbl0sIGluZm8uc3Vtc0NvbHVtbnNbY29sdW1uXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gbW9kaWZpZWRWYWx1ZXM7XG59XG5cbmZ1bmN0aW9uIGdldFZhbHVlc1R5cGVJbmZvKHZhbHVlczogYW55W11bXSwgdmFsdWVUeXBlczogTG1yUGl2b3RWYWx1ZVR5cGVbXSwgbnVtVmFsdWVzOiBudW1iZXIpOiBWYWx1ZVR5cGVJbmZvW10ge1xuICBjb25zdCB2YWx1ZVR5cGVJbmZvID0gW107XG4gIGNvbnN0IHJvd3NJbmRleGVzID0gWy4uLkFycmF5KHZhbHVlcy5sZW5ndGgpLmtleXMoKV07XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBudW1WYWx1ZXM7IGkrKykge1xuICAgIGNvbnN0IHZhbHVlVHlwZSA9IHZhbHVlVHlwZXMgJiYgdmFsdWVUeXBlc1tpXTtcbiAgICBjb25zdCBjb2x1bW5zQ291bnQgPSAodmFsdWVzWzBdICYmIHZhbHVlc1swXS5sZW5ndGgpIHx8IDA7XG4gICAgY29uc3QgY29sdW1uSW5kZXhlcyA9IFsuLi5BcnJheShjb2x1bW5zQ291bnQpLmtleXMoKV0uZmlsdGVyKGtleSA9PiBrZXkgJSBudW1WYWx1ZXMgPT09IGkpO1xuXG4gICAgdmFsdWVUeXBlSW5mb1tpXSA9IGdldFZhbHVlVHlwZUluZm8odmFsdWVzLCB2YWx1ZVR5cGUsIHJvd3NJbmRleGVzLCBjb2x1bW5JbmRleGVzKTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZVR5cGVJbmZvO1xufVxuXG5mdW5jdGlvbiBnZXRWYWx1ZVR5cGVJbmZvKHZhbHVlczogYW55W11bXSwgdHlwZTogTG1yUGl2b3RWYWx1ZVR5cGUsIHJvd3M6IG51bWJlcltdLCBjb2x1bW5zOiBudW1iZXJbXSk6IFZhbHVlVHlwZUluZm8ge1xuICBjb25zdCBjb250YWluc0RlY2ltYWwgPSBjb250YWluc0RlY2ltYWxWYWx1ZSh2YWx1ZXMsIHJvd3MsIGNvbHVtbnMpO1xuICBjb25zdCB2YWx1ZVR5cGVJbmZvOiBWYWx1ZVR5cGVJbmZvID0ge1xuICAgIGRlZmF1bHRDb25zdHJhaW50OiBjb250YWluc0RlY2ltYWwgPyBuZXcgTnVtYmVyQ29uc3RyYWludCh7ZGVjaW1hbHM6IDJ9KSA6IG51bGwsXG4gIH07XG5cbiAgaWYgKHR5cGUgPT09IExtclBpdm90VmFsdWVUeXBlLkFsbFBlcmNlbnRhZ2UpIHtcbiAgICByZXR1cm4gey4uLnZhbHVlVHlwZUluZm8sIHN1bTogZ2V0TnVtZXJpY1ZhbHVlc1N1bW1hcnkodmFsdWVzLCByb3dzLCBjb2x1bW5zKX07XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuUm93UGVyY2VudGFnZSkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi52YWx1ZVR5cGVJbmZvLFxuICAgICAgc3Vtc1Jvd3M6IHJvd3MucmVkdWNlKChhcnIsIHJvdykgPT4ge1xuICAgICAgICBhcnJbcm93XSA9IGdldE51bWVyaWNWYWx1ZXNTdW1tYXJ5KHZhbHVlcywgW3Jvd10sIGNvbHVtbnMpO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgICAgfSwgW10pLFxuICAgIH07XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gTG1yUGl2b3RWYWx1ZVR5cGUuQ29sdW1uUGVyY2VudGFnZSkge1xuICAgIHJldHVybiB7XG4gICAgICAuLi52YWx1ZVR5cGVJbmZvLFxuICAgICAgc3Vtc0NvbHVtbnM6IGNvbHVtbnMucmVkdWNlKChhcnIsIGNvbHVtbikgPT4ge1xuICAgICAgICBhcnJbY29sdW1uXSA9IGdldE51bWVyaWNWYWx1ZXNTdW1tYXJ5KHZhbHVlcywgcm93cywgW2NvbHVtbl0pO1xuICAgICAgICByZXR1cm4gYXJyO1xuICAgICAgfSwgW10pLFxuICAgIH07XG4gIH1cblxuICByZXR1cm4gey4uLnZhbHVlVHlwZUluZm99O1xufVxuXG5mdW5jdGlvbiBjb250YWluc0RlY2ltYWxWYWx1ZSh2YWx1ZXM6IGFueVtdW10sIHJvd3M6IG51bWJlcltdLCBjb2x1bW5zOiBudW1iZXJbXSk6IGJvb2xlYW4ge1xuICBmb3IgKGNvbnN0IHJvdyBvZiByb3dzKSB7XG4gICAgZm9yIChjb25zdCBjb2x1bW4gb2YgY29sdW1ucykge1xuICAgICAgaWYgKGlzVmFsdWVEZWNpbWFsKHZhbHVlc1tyb3ddW2NvbHVtbl0pKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGlzVmFsdWVEZWNpbWFsKHZhbHVlOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGlmIChpc051bWVyaWModmFsdWUpKSB7XG4gICAgcmV0dXJuIHRvTnVtYmVyKHZhbHVlKSAlIDEgIT09IDA7XG4gIH1cbiAgcmV0dXJuIGZhbHNlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVUcmFuc2Zvcm1hdGlvbk1hcChcbiAgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gIHNob3dTdW1zOiBib29sZWFuW10sXG4gIGFkZGl0aW9uYWxOdW06IG51bWJlcixcbiAgbnVtYmVyT2ZTdW1zOiBudW1iZXJcbik6IG51bWJlcltdIHtcbiAgY29uc3QgYXJyYXkgPSBbXTtcbiAgaXRlcmF0ZVRocm91Z2hUcmFuc2Zvcm1hdGlvbk1hcChoZWFkZXJzLCBhZGRpdGlvbmFsTnVtLCBhcnJheSwgMCwgc2hvd1N1bXMsIG51bWJlck9mU3Vtcyk7XG4gIHJldHVybiBhcnJheTtcbn1cblxuZnVuY3Rpb24gaXRlcmF0ZVRocm91Z2hUcmFuc2Zvcm1hdGlvbk1hcChcbiAgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gIGFkZGl0aW9uYWxOdW06IG51bWJlcixcbiAgYXJyYXk6IG51bWJlcltdLFxuICBsZXZlbDogbnVtYmVyLFxuICBzaG93U3VtczogYm9vbGVhbltdLFxuICBudW1iZXJPZlN1bXM6IG51bWJlclxuKSB7XG4gIGxldCBhZGRpdGlvbmFsID0gYWRkaXRpb25hbE51bTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBoZWFkZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgY29uc3QgaGVhZGVyID0gaGVhZGVyc1tpXTtcbiAgICBjb25zdCBiZWZvcmVFeHByZXNzaW9uc0xlbmd0aCA9IChoZWFkZXIuZXhwcmVzc2lvbnMgfHwgW10pLmZpbHRlcihleHAgPT4gZXhwLnBvc2l0aW9uID09PSBMbXJQaXZvdFBvc2l0aW9uLkJlZm9yZUhlYWRlcikubGVuZ3RoXG4gICAgY29uc3QgYWZ0ZXJFeHByZXNzaW9uc0xlbmd0aCA9IChoZWFkZXIuZXhwcmVzc2lvbnMgfHwgW10pLmZpbHRlcihleHAgPT4gZXhwLnBvc2l0aW9uID09PSBMbXJQaXZvdFBvc2l0aW9uLlN0aWNrVG9FbmQpLmxlbmd0aFxuICAgIGlmIChoZWFkZXIuY2hpbGRyZW4pIHtcbiAgICAgIGFkZGl0aW9uYWwgKz0gYmVmb3JlRXhwcmVzc2lvbnNMZW5ndGhcbiAgICAgIGl0ZXJhdGVUaHJvdWdoVHJhbnNmb3JtYXRpb25NYXAoaGVhZGVyLmNoaWxkcmVuLCBhZGRpdGlvbmFsLCBhcnJheSwgbGV2ZWwgKyAxLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKTtcbiAgICAgIGFkZGl0aW9uYWwgKz0gKGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCwgc2hvd1N1bXMsIG51bWJlck9mU3VtcykgLSBiZWZvcmVFeHByZXNzaW9uc0xlbmd0aCk7XG4gICAgfSBlbHNlIGlmIChpc05vdE51bGxPclVuZGVmaW5lZChoZWFkZXIudGFyZ2V0SW5kZXgpKSB7XG4gICAgICBhcnJheVtoZWFkZXIudGFyZ2V0SW5kZXhdID0gaSArIGFkZGl0aW9uYWwgKyBiZWZvcmVFeHByZXNzaW9uc0xlbmd0aDtcbiAgICAgIGFkZGl0aW9uYWwgKz0gYmVmb3JlRXhwcmVzc2lvbnNMZW5ndGggKyBhZnRlckV4cHJlc3Npb25zTGVuZ3RoO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVycyhoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSk6IG51bWJlcltdIHtcbiAgY29uc3QgYWxsUm93cyA9IChoZWFkZXJzIHx8IFtdKS5yZWR1Y2UoKHJvd3MsIGhlYWRlcikgPT4ge1xuICAgIHJvd3MucHVzaCguLi5nZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVyKGhlYWRlcikpO1xuICAgIHJldHVybiByb3dzO1xuICB9LCBbXSk7XG4gIHJldHVybiB1bmlxdWVWYWx1ZXM8bnVtYmVyPihhbGxSb3dzKTtcbn1cblxuZnVuY3Rpb24gZ2V0VGFyZ2V0SW5kZXhlc0ZvckhlYWRlcihwaXZvdERhdGFIZWFkZXI6IExtclBpdm90RGF0YUhlYWRlcik6IG51bWJlcltdIHtcbiAgaWYgKHBpdm90RGF0YUhlYWRlci5jaGlsZHJlbikge1xuICAgIHJldHVybiBwaXZvdERhdGFIZWFkZXIuY2hpbGRyZW4ucmVkdWNlKChyb3dzLCBoZWFkZXIpID0+IHtcbiAgICAgIHJvd3MucHVzaCguLi5nZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVyKGhlYWRlcikpO1xuICAgICAgcmV0dXJuIHJvd3M7XG4gICAgfSwgW10pO1xuICB9XG4gIHJldHVybiBbcGl2b3REYXRhSGVhZGVyLnRhcmdldEluZGV4XTtcbn1cblxuZnVuY3Rpb24gZ2V0SGVhZGVyc0NoaWxkQ291bnQoaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sIHNob3dTdW1zOiBib29sZWFuW10sIG51bWJlck9mU3VtcyA9IDEpOiBudW1iZXIge1xuICByZXR1cm4gKGhlYWRlcnMgfHwgW10pLnJlZHVjZShcbiAgICAoc3VtLCBoZWFkZXIpID0+IHN1bSArIGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCAwLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKSxcbiAgICBzaG93U3Vtc1swXSA/IG51bWJlck9mU3VtcyA6IDBcbiAgKTtcbn1cblxuZnVuY3Rpb24gZ2V0SGVhZGVyQ2hpbGRDb3VudChcbiAgcGl2b3REYXRhSGVhZGVyOiBMbXJQaXZvdERhdGFIZWFkZXIsXG4gIGxldmVsOiBudW1iZXIsXG4gIHNob3dTdW1zOiBib29sZWFuW10sXG4gIG51bWJlck9mU3VtcyA9IDEsXG4pOiBudW1iZXIge1xuICBjb25zdCBudW1FeHByZXNzaW9ucyA9IChwaXZvdERhdGFIZWFkZXIuZXhwcmVzc2lvbnMgfHwgW10pLmxlbmd0aFxuICBpZiAocGl2b3REYXRhSGVhZGVyLmNoaWxkcmVuKSB7XG4gICAgcmV0dXJuIHBpdm90RGF0YUhlYWRlci5jaGlsZHJlbi5yZWR1Y2UoXG4gICAgICAoc3VtLCBoZWFkZXIpID0+IHN1bSArIGdldEhlYWRlckNoaWxkQ291bnQoaGVhZGVyLCBsZXZlbCArIDEsIHNob3dTdW1zLCBudW1iZXJPZlN1bXMpLFxuICAgICAgKHNob3dTdW1zW2xldmVsICsgMV0gPyBudW1iZXJPZlN1bXMgOiAwKSArIG51bUV4cHJlc3Npb25zXG4gICAgKTtcbiAgfVxuICByZXR1cm4gMSArIG51bUV4cHJlc3Npb25zO1xufVxuXG5mdW5jdGlvbiBnZXREaXJlY3RIZWFkZXJDaGlsZENvdW50KFxuICBwaXZvdERhdGFIZWFkZXI6IExtclBpdm90RGF0YUhlYWRlcixcbiAgbGV2ZWw6IG51bWJlcixcbiAgc2hvd1N1bXM6IGJvb2xlYW5bXSxcbiAgbnVtYmVyT2ZTdW1zID0gMVxuKTogbnVtYmVyIHtcbiAgaWYgKHBpdm90RGF0YUhlYWRlci5jaGlsZHJlbikge1xuICAgIHJldHVybiBwaXZvdERhdGFIZWFkZXIuY2hpbGRyZW4ucmVkdWNlKFxuICAgICAgKHN1bSwgaGVhZGVyKSA9PiBzdW0gKyBnZXRIZWFkZXJDaGlsZENvdW50KGhlYWRlciwgbGV2ZWwgKyAxLCBzaG93U3VtcywgbnVtYmVyT2ZTdW1zKSxcbiAgICAgIDBcbiAgICApO1xuICB9XG4gIHJldHVybiAxO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gc29ydFBpdm90RGF0YShkYXRhOiBMbXJQaXZvdFN0ZW1EYXRhLCBjb25zdHJhaW50RGF0YTogQ29uc3RyYWludERhdGEpOiBMbXJQaXZvdFN0ZW1EYXRhIHtcbiAgY29uc3Qgcm93U29ydHMgPSAoZGF0YS5yb3dzQ29uZmlnIHx8IFtdKS5tYXAoY29uZmlnID0+IGNvbmZpZy5zb3J0KVxuICBjb25zdCBjb2x1bW5Tb3J0cyA9IChkYXRhLmNvbHVtbnNDb25maWcgfHwgW10pLm1hcChjb25maWcgPT4gY29uZmlnLnNvcnQpXG4gIHJldHVybiB7XG4gICAgLi4uZGF0YSxcbiAgICByb3dIZWFkZXJzOiBzb3J0UGl2b3RSb3dEYXRhSGVhZGVycyhkYXRhLnJvd0hlYWRlcnMsIHJvd1NvcnRzLCBkYXRhLCBjb25zdHJhaW50RGF0YSksXG4gICAgY29sdW1uSGVhZGVyczogc29ydFBpdm90Q29sdW1uRGF0YUhlYWRlcnMoZGF0YS5jb2x1bW5IZWFkZXJzLCBjb2x1bW5Tb3J0cywgZGF0YSwgY29uc3RyYWludERhdGEpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBzb3J0UGl2b3RSb3dEYXRhSGVhZGVycyhcbiAgcm93SGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gIHJvd1NvcnRzOiBMbXJQaXZvdFNvcnRbXSxcbiAgcGl2b3REYXRhOiBMbXJQaXZvdFN0ZW1EYXRhLFxuICBjb25zdHJhaW50RGF0YTogQ29uc3RyYWludERhdGFcbik6IExtclBpdm90RGF0YUhlYWRlcltdIHtcbiAgcmV0dXJuIHNvcnRQaXZvdERhdGFIZWFkZXJzUmVjdXJzaXZlKFxuICAgIHJvd0hlYWRlcnMsXG4gICAgMCxcbiAgICByb3dTb3J0cyxcbiAgICBwaXZvdERhdGEuY29sdW1uSGVhZGVycyxcbiAgICBwaXZvdERhdGEudmFsdWVzLFxuICAgIHBpdm90RGF0YS52YWx1ZVRpdGxlcyB8fCBbXSxcbiAgICB0cnVlLFxuICAgIGNvbnN0cmFpbnREYXRhXG4gICk7XG59XG5cbmZ1bmN0aW9uIHNvcnRQaXZvdENvbHVtbkRhdGFIZWFkZXJzKFxuICBjb2x1bW5IZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgY29sdW1uU29ydHM6IExtclBpdm90U29ydFtdLFxuICBwaXZvdERhdGE6IExtclBpdm90U3RlbURhdGEsXG4gIGNvbnN0cmFpbnREYXRhOiBDb25zdHJhaW50RGF0YVxuKTogTG1yUGl2b3REYXRhSGVhZGVyW10ge1xuICByZXR1cm4gc29ydFBpdm90RGF0YUhlYWRlcnNSZWN1cnNpdmUoXG4gICAgY29sdW1uSGVhZGVycyxcbiAgICAwLFxuICAgIGNvbHVtblNvcnRzLFxuICAgIHBpdm90RGF0YS5yb3dIZWFkZXJzLFxuICAgIHBpdm90RGF0YS52YWx1ZXMsXG4gICAgcGl2b3REYXRhLnZhbHVlVGl0bGVzIHx8IFtdLFxuICAgIGZhbHNlLFxuICAgIGNvbnN0cmFpbnREYXRhXG4gICk7XG59XG5cbmZ1bmN0aW9uIHNvcnRQaXZvdERhdGFIZWFkZXJzUmVjdXJzaXZlKFxuICBoZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgaW5kZXg6IG51bWJlcixcbiAgc29ydHM6IExtclBpdm90U29ydFtdLFxuICBvdGhlclNpZGVIZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgdmFsdWVzOiBhbnlbXVtdLFxuICB2YWx1ZVRpdGxlczogc3RyaW5nW10sXG4gIGlzUm93czogYm9vbGVhbixcbiAgY29uc3RyYWludERhdGE6IENvbnN0cmFpbnREYXRhXG4pOiBMbXJQaXZvdERhdGFIZWFkZXJbXSB7XG4gIC8vIHdlIGRvbid0IHdhbnQgdG8gc29ydCB2YWx1ZXMgaGVhZGVyc1xuICBpZiAoIWlzUm93cyAmJiBpc1ZhbHVlc0hlYWRlcnMoaGVhZGVycywgdmFsdWVUaXRsZXMpKSB7XG4gICAgcmV0dXJuIGhlYWRlcnM7XG4gIH1cbiAgY29uc3Qgc29ydCA9IHNvcnRzICYmIHNvcnRzW2luZGV4XTtcbiAgY29uc3QgY29uc3RyYWludCA9IGdldENvbnN0cmFpbnRGb3JTb3J0KHNvcnQsIGhlYWRlcnMpO1xuICBjb25zdCB2YWx1ZXNNYXAgPSBjcmVhdGVIZWFkZXJzVmFsdWVzTWFwKGhlYWRlcnMsIHNvcnQsIG90aGVyU2lkZUhlYWRlcnMsIHZhbHVlcywgdmFsdWVUaXRsZXMsIGlzUm93cyk7XG4gIHJldHVybiBoZWFkZXJzXG4gICAgLm1hcChoZWFkZXIgPT4gKHtcbiAgICAgIC4uLmhlYWRlcixcbiAgICAgIGNoaWxkcmVuOlxuICAgICAgICBoZWFkZXIuY2hpbGRyZW4gJiZcbiAgICAgICAgc29ydFBpdm90RGF0YUhlYWRlcnNSZWN1cnNpdmUoXG4gICAgICAgICAgaGVhZGVyLmNoaWxkcmVuLFxuICAgICAgICAgIGluZGV4ICsgMSxcbiAgICAgICAgICBzb3J0cyxcbiAgICAgICAgICBvdGhlclNpZGVIZWFkZXJzLFxuICAgICAgICAgIHZhbHVlcyxcbiAgICAgICAgICB2YWx1ZVRpdGxlcyxcbiAgICAgICAgICBpc1Jvd3MsXG4gICAgICAgICAgY29uc3RyYWludERhdGFcbiAgICAgICAgKSxcbiAgICB9KSlcbiAgICAuc29ydCgocjEsIHIyKSA9PiB7XG4gICAgICBjb25zdCByMVZhbHVlID0gY29uc3RyYWludC5jcmVhdGVEYXRhVmFsdWUodmFsdWVzTWFwW3IxLnRpdGxlXSwgY29uc3RyYWludERhdGEpO1xuICAgICAgY29uc3QgcjJWYWx1ZSA9IGNvbnN0cmFpbnQuY3JlYXRlRGF0YVZhbHVlKHZhbHVlc01hcFtyMi50aXRsZV0sIGNvbnN0cmFpbnREYXRhKTtcbiAgICAgIGNvbnN0IG11bHRpcGxpZXIgPSAhc29ydCB8fCBzb3J0LmFzYyA/IDEgOiAtMTtcbiAgICAgIHJldHVybiByMVZhbHVlLmNvbXBhcmVUbyhyMlZhbHVlKSAqIG11bHRpcGxpZXI7XG4gICAgfSk7XG59XG5cbmZ1bmN0aW9uIGdldENvbnN0cmFpbnRGb3JTb3J0KHNvcnQ6IExtclBpdm90U29ydCwgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10pOiBDb25zdHJhaW50IHtcbiAgaWYgKChzb3J0Py5saXN0Py52YWx1ZXMgfHwgW10pLmxlbmd0aCA+IDApIHtcbiAgICAvLyBzb3J0IGlzIGRvbmUgYnkgdmFsdWVzIGluIGNvbHVtbnNcbiAgICByZXR1cm4gbmV3IE51bWJlckNvbnN0cmFpbnQoe30pO1xuICB9XG4gIHJldHVybiAoKGhlYWRlcnMgfHwgW10pWzBdICYmIChoZWFkZXJzIHx8IFtdKVswXS5jb25zdHJhaW50KSB8fCBuZXcgVW5rbm93bkNvbnN0cmFpbnQoKTtcbn1cblxuZnVuY3Rpb24gaXNWYWx1ZXNIZWFkZXJzKGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLCB2YWx1ZVRpdGxlczogc3RyaW5nW10pOiBib29sZWFuIHtcbiAgcmV0dXJuIChcbiAgICB2YWx1ZVRpdGxlcy5sZW5ndGggPiAxICYmXG4gICAgKGhlYWRlcnMgfHwgW10pLmV2ZXJ5KFxuICAgICAgKGhlYWRlciwgaW5kZXgpID0+IGlzTm90TnVsbE9yVW5kZWZpbmVkKGhlYWRlci50YXJnZXRJbmRleCkgJiYgaGVhZGVyLnRpdGxlID09PSB2YWx1ZVRpdGxlc1tpbmRleF1cbiAgICApXG4gICk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUhlYWRlcnNWYWx1ZXNNYXAoXG4gIGhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICBzb3J0OiBMbXJQaXZvdFNvcnQsXG4gIG90aGVyU2lkZUhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICB2YWx1ZXM6IGFueVtdW10sXG4gIHZhbHVlVGl0bGVzOiBzdHJpbmdbXSxcbiAgaXNSb3dzOiBib29sZWFuXG4pOiBSZWNvcmQ8c3RyaW5nLCBhbnk+IHtcbiAgY29uc3Qgc29ydFRhcmdldEluZGV4ZXMgPSBzb3J0VmFsdWVUYXJnZXRJbmRleGVzKHNvcnQsIG90aGVyU2lkZUhlYWRlcnMsIHZhbHVlVGl0bGVzKTtcbiAgaWYgKCFzb3J0VGFyZ2V0SW5kZXhlcykge1xuICAgIHJldHVybiAoaGVhZGVycyB8fCBbXSkucmVkdWNlKCh2YWx1ZXNNYXAsIGhlYWRlcikgPT4ge1xuICAgICAgdmFsdWVzTWFwW2hlYWRlci50aXRsZV0gPSBoZWFkZXIudGl0bGU7XG4gICAgICByZXR1cm4gdmFsdWVzTWFwO1xuICAgIH0sIHt9KTtcbiAgfVxuXG4gIHJldHVybiAoaGVhZGVycyB8fCBbXSkucmVkdWNlKCh2YWx1ZXNNYXAsIGhlYWRlcikgPT4ge1xuICAgIGNvbnN0IHJvd3MgPSBpc1Jvd3MgPyBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVyKGhlYWRlcikgOiBzb3J0VGFyZ2V0SW5kZXhlcztcbiAgICBjb25zdCBjb2x1bW5zID0gaXNSb3dzID8gc29ydFRhcmdldEluZGV4ZXMgOiBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVyKGhlYWRlcik7XG4gICAgdmFsdWVzTWFwW2hlYWRlci50aXRsZV0gPSBnZXROdW1lcmljVmFsdWVzU3VtbWFyeSh2YWx1ZXMsIHJvd3MsIGNvbHVtbnMpO1xuICAgIHJldHVybiB2YWx1ZXNNYXA7XG4gIH0sIHt9KTtcbn1cblxuZnVuY3Rpb24gZ2V0TnVtZXJpY1ZhbHVlc1N1bW1hcnkodmFsdWVzOiBhbnlbXVtdLCByb3dzOiBudW1iZXJbXSwgY29sdW1uczogbnVtYmVyW10pOiBudW1iZXIge1xuICBsZXQgc3VtID0gMDtcbiAgZm9yIChjb25zdCByb3cgb2Ygcm93cykge1xuICAgIGZvciAoY29uc3QgY29sdW1uIG9mIGNvbHVtbnMpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdmFsdWVzW3Jvd11bY29sdW1uXTtcbiAgICAgIGlmIChpc05vdE51bGxPclVuZGVmaW5lZCh2YWx1ZSkgJiYgaXNOdW1lcmljKHZhbHVlKSkge1xuICAgICAgICBzdW0gKz0gdG9OdW1iZXIodmFsdWUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuICByZXR1cm4gc3VtO1xufVxuXG5mdW5jdGlvbiBzb3J0VmFsdWVUYXJnZXRJbmRleGVzKFxuICBzb3J0OiBMbXJQaXZvdFNvcnQsXG4gIG90aGVyU2lkZUhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICB2YWx1ZVRpdGxlczogc3RyaW5nW11cbik6IG51bWJlcltdIHwgbnVsbCB7XG4gIGlmIChzb3J0ICYmIHNvcnQubGlzdCkge1xuICAgIGxldCB2YWx1ZUluZGV4ID0gdmFsdWVUaXRsZXMuZmluZEluZGV4KHRpdGxlID0+IHRpdGxlID09PSBzb3J0Lmxpc3QudmFsdWVUaXRsZSk7XG4gICAgaWYgKHZhbHVlSW5kZXggPT09IC0xKSB7XG4gICAgICBpZiAodmFsdWVUaXRsZXMubGVuZ3RoID09PSAxKSB7XG4gICAgICAgIHZhbHVlSW5kZXggPSAwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGV0IHBpdm90SGVhZGVyOiBMbXJQaXZvdERhdGFIZWFkZXIgPSBudWxsO1xuICAgIGxldCBjdXJyZW50T3RoZXJTaWRlSGVhZGVycyA9IG90aGVyU2lkZUhlYWRlcnM7XG4gICAgZm9yIChjb25zdCB2YWx1ZSBvZiBzb3J0Lmxpc3QudmFsdWVzIHx8IFtdKSB7XG4gICAgICBpZiAodmFsdWUuaXNTdW1tYXJ5KSB7XG4gICAgICAgIGNvbnN0IGluZGV4ZXMgPSBnZXRUYXJnZXRJbmRleGVzRm9ySGVhZGVycyhjdXJyZW50T3RoZXJTaWRlSGVhZGVycyB8fCBbXSkgfHwgW107XG4gICAgICAgIHJldHVybiBmaWx0ZXJJbmRleGVzQnlNb2QoaW5kZXhlcywgdmFsdWVUaXRsZXMubGVuZ3RoLCB2YWx1ZUluZGV4KTtcbiAgICAgIH1cblxuICAgICAgcGl2b3RIZWFkZXIgPSAoY3VycmVudE90aGVyU2lkZUhlYWRlcnMgfHwgW10pLmZpbmQoaGVhZGVyID0+IGhlYWRlci50aXRsZSA9PT0gdmFsdWUudGl0bGUpO1xuICAgICAgaWYgKCFwaXZvdEhlYWRlcikge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgY3VycmVudE90aGVyU2lkZUhlYWRlcnMgPSBwaXZvdEhlYWRlci5jaGlsZHJlbiB8fCBbXTtcbiAgICB9XG5cbiAgICBpZiAocGl2b3RIZWFkZXIpIHtcbiAgICAgIGNvbnN0IHRhcmdldEluZGV4ZXMgPSBpc05vdE51bGxPclVuZGVmaW5lZChwaXZvdEhlYWRlci50YXJnZXRJbmRleClcbiAgICAgICAgPyBbcGl2b3RIZWFkZXIudGFyZ2V0SW5kZXhdXG4gICAgICAgIDogZ2V0VGFyZ2V0SW5kZXhlc0ZvckhlYWRlcnMoY3VycmVudE90aGVyU2lkZUhlYWRlcnMpO1xuICAgICAgcmV0dXJuIGZpbHRlckluZGV4ZXNCeU1vZCh0YXJnZXRJbmRleGVzLCB2YWx1ZVRpdGxlcy5sZW5ndGgsIHZhbHVlSW5kZXgpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBmaWx0ZXJJbmRleGVzQnlNb2QoaW5kZXhlczogbnVtYmVyW10sIG1vZDogbnVtYmVyLCB2YWx1ZTogbnVtYmVyKTogbnVtYmVyW10ge1xuICByZXR1cm4gKGluZGV4ZXMgfHwgW10pLmZpbHRlcihpbmRleCA9PiBpbmRleCAlIG1vZCA9PT0gdmFsdWUpO1xufVxuXG5mdW5jdGlvbiBkaXZpZGVWYWx1ZXModmFsdWU6IGFueSwgZGl2aWRlcjogYW55KTogbnVtYmVyIHtcbiAgaWYgKGlzTnVsbE9yVW5kZWZpbmVkKHZhbHVlKSkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgaWYgKGlzTnVtZXJpYyh2YWx1ZSkgJiYgaXNOdW1lcmljKGRpdmlkZXIpKSB7XG4gICAgaWYgKGRpdmlkZXIgIT09IDApIHtcbiAgICAgIHJldHVybiB2YWx1ZSAvIGRpdmlkZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAwO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBudWxsO1xufVxuIl19