@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,507 +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 { ConstraintType, DataAggregationType, DataAggregator, UnknownConstraint, aggregateDataResources, dataAggregationConstraint, AttributesResourceType, attributesResourcesAttributesMap, } from '@lumeer/data-filters';
20
- import { deepObjectsEquals, flattenMatrix, flattenValues, isArray, isNotNullOrUndefined, uniqueValues } from '@lumeer/utils';
21
- import { pivotStemConfigIsEmpty } from './pivot-util';
22
- var PivotConfigType;
23
- (function (PivotConfigType) {
24
- PivotConfigType[PivotConfigType["Values"] = 0] = "Values";
25
- PivotConfigType[PivotConfigType["Rows"] = 1] = "Rows";
26
- PivotConfigType[PivotConfigType["Columns"] = 2] = "Columns";
27
- PivotConfigType[PivotConfigType["RowsAndColumns"] = 3] = "RowsAndColumns";
28
- })(PivotConfigType || (PivotConfigType = {}));
29
- export class PivotDataConverter {
30
- collections;
31
- linkTypes;
32
- collectionsAttributesMap;
33
- linkTypesAttributesMap;
34
- data;
35
- config;
36
- transform;
37
- constraintData;
38
- dataAggregator;
39
- constructor() {
40
- this.dataAggregator = new DataAggregator((value, constraint, data, aggregatorAttribute) => this.formatPivotValue(value, constraint, data, aggregatorAttribute));
41
- }
42
- formatPivotValue(value, constraint, constraintData, aggregatorAttribute) {
43
- const pivotConstraint = aggregatorAttribute.data && aggregatorAttribute.data;
44
- const overrideConstraint = pivotConstraint && this.transform?.checkValidConstraintOverride?.(constraint, pivotConstraint);
45
- const finalConstraint = overrideConstraint || constraint || new UnknownConstraint();
46
- const serializedValue = (constraint || new UnknownConstraint()).createDataValue(value, constraintData).serialize();
47
- return this.formatDataValue(finalConstraint.createDataValue(serializedValue, constraintData), finalConstraint);
48
- }
49
- formatDataValue(dataValue, constraint) {
50
- switch (constraint.type) {
51
- case ConstraintType.DateTime:
52
- return dataValue.format();
53
- default:
54
- return dataValue.serialize();
55
- }
56
- }
57
- updateData(config, transform, collections, linkTypes, data, constraintData) {
58
- this.config = config;
59
- this.transform = transform;
60
- this.collections = collections;
61
- this.linkTypes = linkTypes;
62
- this.collectionsAttributesMap = attributesResourcesAttributesMap(collections);
63
- this.linkTypesAttributesMap = attributesResourcesAttributesMap(linkTypes);
64
- this.data = data;
65
- this.constraintData = constraintData;
66
- }
67
- createData(config, transform, collections, linkTypes, data, query, constraintData) {
68
- this.updateData(config, transform, collections, linkTypes, data, constraintData);
69
- const { stemsConfigs, stems } = this.filterEmptyConfigs(config, query);
70
- const mergeData = this.createPivotMergeData(config.mergeTables, stemsConfigs, stems);
71
- const ableToMerge = mergeData.length <= 1;
72
- const pivotData = this.mergePivotData(mergeData);
73
- return { data: pivotData, constraintData, ableToMerge, mergeTables: config.mergeTables };
74
- }
75
- filterEmptyConfigs(config, query) {
76
- return (config.stemsConfigs || []).reduce(({ stemsConfigs, stems }, stemConfig, index) => {
77
- if (!pivotStemConfigIsEmpty(stemConfig)) {
78
- const stem = (query.stems || [])[index];
79
- stemsConfigs.push(stemConfig);
80
- stems.push(stem);
81
- }
82
- return { stemsConfigs, stems };
83
- }, { stemsConfigs: [], stems: [] });
84
- }
85
- createPivotMergeData(mergeTables, stemsConfigs, stems) {
86
- return stemsConfigs.reduce((mergeData, stemConfig, index) => {
87
- const configType = getPivotStemConfigType(stemConfig);
88
- const mergeDataIndex = mergeData.findIndex(data => data.type === configType && canMergeConfigsByType(data.type, data.configs[0], stemConfig));
89
- if (mergeTables && mergeDataIndex >= 0) {
90
- mergeData[mergeDataIndex].configs.push(stemConfig);
91
- mergeData[mergeDataIndex].stems.push(stems[index]);
92
- mergeData[mergeDataIndex].stemsIndexes.push(index);
93
- }
94
- else {
95
- mergeData.push({ configs: [stemConfig], stems: [stems[index]], stemsIndexes: [index], type: configType });
96
- }
97
- return mergeData;
98
- }, []);
99
- }
100
- mergePivotData(mergeData) {
101
- return mergeData.reduce((stemData, data) => {
102
- if (data.type === PivotConfigType.Values) {
103
- stemData.push(this.convertValueAttributes(data.configs, data.stems, data.stemsIndexes));
104
- }
105
- else {
106
- stemData.push(this.transformStems(data.configs, data.stems, data.stemsIndexes));
107
- }
108
- return stemData;
109
- }, []);
110
- }
111
- transformStems(configs, queryStems, stemsIndexes) {
112
- const pivotColors = { rows: [], columns: [], values: [] };
113
- const mergedValueAttributes = [];
114
- let mergedAggregatedData = null;
115
- let additionalData;
116
- for (let i = 0; i < configs.length; i++) {
117
- const config = configs[i];
118
- const queryStem = queryStems[i];
119
- const stemIndex = stemsIndexes[i];
120
- const stemData = this.data?.dataByStems?.[stemIndex];
121
- this.dataAggregator.updateData(this.collections, stemData?.documents || [], this.linkTypes, stemData?.linkInstances || [], queryStem, this.constraintData);
122
- const rowAttributes = (config.rowAttributes || []).map(attribute => this.convertPivotRowColumnAttribute(attribute));
123
- const columnAttributes = (config.columnAttributes || []).map(attribute => this.convertPivotRowColumnAttribute(attribute));
124
- const valueAttributes = (config.valueAttributes || []).map(attribute => this.convertPivotAttribute(attribute));
125
- pivotColors.rows.push(...this.getAttributesColors(config.rowAttributes));
126
- pivotColors.columns.push(...this.getAttributesColors(config.columnAttributes));
127
- pivotColors.values.push(...this.getAttributesColors(config.valueAttributes));
128
- const aggregatedData = this.dataAggregator.aggregate(rowAttributes, columnAttributes, valueAttributes);
129
- mergedAggregatedData = this.mergeAggregatedData(mergedAggregatedData, aggregatedData);
130
- const filteredValueAttributes = (config.valueAttributes || []).filter(valueAttr => !mergedValueAttributes.some(merAttr => deepObjectsEquals(valueAttr, merAttr)));
131
- mergedValueAttributes.push(...filteredValueAttributes);
132
- if (!additionalData) {
133
- const rowSticky = this.mapStickyValues((config.rowAttributes || []).map(attr => attr.sticky));
134
- const columnSticky = this.mapStickyValues((config.columnAttributes || []).map(attr => attr.sticky));
135
- additionalData = {
136
- rowsConfig: (config.rowAttributes || []).map((attr, index) => ({ showSums: attr.showSums, sort: attr.sort, expressions: attr.expressions, sticky: rowSticky[index] })),
137
- columnsConfig: (config.columnAttributes || []).map((attr, index) => ({ showSums: attr.showSums, sort: attr.sort, expressions: attr.expressions, sticky: columnSticky[index] })),
138
- rowShowHeaderAttributes: (config.rowAttributes || []).map(attr => attr.showHeader),
139
- rowAttributes: (config.rowAttributes || []).map(attr => this.pivotAttributeAttribute(attr)),
140
- columnShowHeaderAttributes: (config.columnAttributes || []).map(attr => false),
141
- columnAttributes: (config.columnAttributes || []).map(attr => this.pivotAttributeAttribute(attr)),
142
- };
143
- }
144
- }
145
- return this.convertAggregatedData(mergedAggregatedData, mergedValueAttributes, pivotColors, additionalData);
146
- }
147
- mapStickyValues(values) {
148
- // we support only sticky rows/columns in a row
149
- return values.reduce((stickyValues, sticky, index) => {
150
- stickyValues.push(sticky && (index === 0 || stickyValues[index - 1]));
151
- return stickyValues;
152
- }, []);
153
- }
154
- pivotAttributeConstraint(pivotAttribute) {
155
- const attribute = this.findAttributeByPivotAttribute(pivotAttribute);
156
- const constraint = attribute && attribute.constraint;
157
- const overrideConstraint = pivotAttribute.constraint &&
158
- this.transform?.checkValidConstraintOverride?.(constraint, pivotAttribute.constraint);
159
- return overrideConstraint || constraint;
160
- }
161
- pivotAttributeAttribute(pivotAttribute) {
162
- const attribute = this.findAttributeByPivotAttribute(pivotAttribute);
163
- if (attribute) {
164
- const constraint = attribute?.constraint;
165
- const overrideConstraint = pivotAttribute.constraint &&
166
- this.transform?.checkValidConstraintOverride?.(constraint, pivotAttribute.constraint);
167
- return { ...attribute, constraint: overrideConstraint || constraint || new UnknownConstraint() };
168
- }
169
- return undefined;
170
- }
171
- mergeAggregatedData(a1, a2) {
172
- if (!a1 || !a2) {
173
- return a1 || a2;
174
- }
175
- this.mergeMaps(a1.map, a2.map);
176
- this.mergeMaps(a1.columnsMap, a2.columnsMap);
177
- return {
178
- map: a1.map,
179
- columnsMap: a1.columnsMap,
180
- rowLevels: Math.max(a1.rowLevels, a2.rowLevels),
181
- columnLevels: Math.max(a1.columnLevels, a2.columnLevels),
182
- };
183
- }
184
- mergeMaps(m1, m2) {
185
- Object.keys(m2).forEach(key => {
186
- if (m1[key]) {
187
- if (isArray(m1[key]) && isArray(m2[key])) {
188
- m1[key].push(...m2[key]);
189
- }
190
- else if (!isArray(m1[key]) && !isArray(m2[key])) {
191
- this.mergeMaps(m1[key], m2[key]);
192
- }
193
- }
194
- else {
195
- m1[key] = m2[key];
196
- }
197
- });
198
- }
199
- getAttributesColors(attributes) {
200
- return (attributes || []).map(attribute => {
201
- const resource = this.dataAggregator.getNextCollectionResource(attribute.resourceIndex);
202
- return resource && resource.color;
203
- });
204
- }
205
- convertPivotRowColumnAttribute(pivotAttribute) {
206
- return { ...this.convertPivotAttribute(pivotAttribute), data: pivotAttribute.constraint };
207
- }
208
- convertPivotAttribute(pivotAttribute) {
209
- return { resourceIndex: pivotAttribute.resourceIndex, attributeId: pivotAttribute.attributeId };
210
- }
211
- convertValueAttributes(configs, stems, stemsIndexes) {
212
- const data = configs.reduce((allData, config, index) => {
213
- const stem = stems[index];
214
- const stemIndex = stemsIndexes[index];
215
- const stemData = this.data?.dataByStems?.[stemIndex];
216
- this.dataAggregator.updateData(this.collections, stemData?.documents || [], this.linkTypes, stemData?.linkInstances || [], stem, this.constraintData);
217
- const valueAttributes = config.valueAttributes || [];
218
- allData.valueTypes.push(...valueAttributes.map(attr => attr.valueType));
219
- const valueColors = this.getAttributesColors(valueAttributes);
220
- const { titles, constraints } = this.createValueTitles(valueAttributes);
221
- allData.titles.push(...titles);
222
- allData.constraints.push(...constraints);
223
- const { headers } = this.convertMapToPivotDataHeader({}, 0, [], valueColors, [], titles, allData.headers.length);
224
- allData.headers.push(...headers);
225
- allData.aggregations = [...(valueAttributes || []).map(valueAttribute => valueAttribute.aggregation)];
226
- const { values, dataResources } = (valueAttributes || []).reduce((aggregator, valueAttribute, index) => {
227
- const dataResources = this.findDataResourcesByPivotAttribute(valueAttribute);
228
- const attribute = this.findAttributeByPivotAttribute(valueAttribute);
229
- const value = aggregateDataResources(valueAttribute.aggregation, dataResources, attribute, true);
230
- aggregator.values.push(value);
231
- aggregator.dataResources.push(dataResources);
232
- return aggregator;
233
- }, { values: [], dataResources: [] });
234
- allData.values.push(...values);
235
- allData.dataResources.push(...dataResources);
236
- return allData;
237
- }, { titles: [], constraints: [], headers: [], values: [], dataResources: [], valueTypes: [], aggregations: [] });
238
- return {
239
- columnHeaders: data.headers,
240
- columnHeaderAttributes: [],
241
- rowHeaders: [],
242
- rowHeaderAttributes: [],
243
- valueTitles: data.titles,
244
- values: [data.values],
245
- dataResources: [data.dataResources],
246
- valuesConstraints: data.constraints,
247
- valueTypes: data.valueTypes,
248
- valueAggregations: data.aggregations,
249
- rowsConfig: [],
250
- columnsConfig: [],
251
- hasAdditionalColumnLevel: true,
252
- };
253
- }
254
- findDataResourcesByPivotAttribute(pivotAttribute) {
255
- if (pivotAttribute.resourceType === AttributesResourceType.Collection) {
256
- return (this.data?.uniqueDocuments || []).filter(document => document.collectionId === pivotAttribute.resourceId);
257
- }
258
- else if (pivotAttribute.resourceType === AttributesResourceType.LinkType) {
259
- return (this.data?.uniqueLinkInstances || []).filter(link => link.linkTypeId === pivotAttribute.resourceId);
260
- }
261
- return [];
262
- }
263
- convertAggregatedData(aggregatedData, valueAttributes, pivotColors, additionalData) {
264
- const rowData = this.convertMapToPivotDataHeader(aggregatedData.map, aggregatedData.rowLevels, pivotColors.rows, pivotColors.values, additionalData.rowAttributes);
265
- const rowHeaderAttributes = (additionalData.rowAttributes || [])
266
- .map((attribute, index) => additionalData.rowShowHeaderAttributes?.[index] ? ({ title: attribute.name, color: pivotColors.rows?.[index] }) : undefined);
267
- const { titles: valueTitles, constraints: valuesConstraints } = this.createValueTitles(valueAttributes);
268
- const columnData = this.convertMapToPivotDataHeader(aggregatedData.rowLevels > 0 ? aggregatedData.columnsMap : aggregatedData.map, aggregatedData.columnLevels, pivotColors.columns, pivotColors.values, additionalData.columnAttributes, valueTitles);
269
- const columnHeaderAttributes = (additionalData.columnAttributes || [])
270
- .map((attribute, index) => additionalData.columnShowHeaderAttributes?.[index] ? ({ title: attribute.name, color: pivotColors.columns?.[index] }) : undefined);
271
- const values = this.initMatrix(rowData.maxIndex + 1, columnData.maxIndex + 1);
272
- const dataResources = this.initMatrix(rowData.maxIndex + 1, columnData.maxIndex + 1);
273
- if ((valueAttributes || []).length > 0) {
274
- this.fillValues(values, dataResources, rowData.headers, columnData.headers, valueAttributes, aggregatedData);
275
- }
276
- const valueAggregations = (valueAttributes || []).map(valueAttribute => valueAttribute.aggregation);
277
- const hasAdditionalColumnLevel = (aggregatedData.columnLevels === 0 && valueTitles.length > 0) ||
278
- (aggregatedData.columnLevels > 0 && valueTitles.length > 1);
279
- return {
280
- rowHeaders: rowData.headers,
281
- rowHeaderAttributes,
282
- columnHeaders: columnData.headers,
283
- columnHeaderAttributes,
284
- valueTitles,
285
- values,
286
- dataResources,
287
- valuesConstraints,
288
- valueAggregations,
289
- ...additionalData,
290
- valueTypes: valueAttributes.map(attr => attr.valueType),
291
- hasAdditionalColumnLevel,
292
- };
293
- }
294
- convertMapToPivotDataHeader(map, levels, colors, valueColors, attributes, valueTitles, additionalNum = 0) {
295
- const headers = [];
296
- const data = { maxIndex: 0 };
297
- if (levels === 0) {
298
- if ((valueTitles || []).length > 0) {
299
- headers.push(...valueTitles.map((title, index) => ({
300
- title,
301
- targetIndex: index + additionalNum,
302
- color: valueColors[index],
303
- isValueHeader: true,
304
- })));
305
- data.maxIndex = valueTitles.length - 1 + additionalNum;
306
- }
307
- }
308
- else {
309
- let currentIndex = additionalNum;
310
- Object.keys(map).forEach((title, index) => {
311
- const attribute = attributes && attributes[0];
312
- if (levels === 1 && (valueTitles || []).length <= 1) {
313
- headers.push({
314
- title,
315
- targetIndex: currentIndex,
316
- color: colors[0],
317
- constraint: attribute?.constraint || new UnknownConstraint(),
318
- isValueHeader: false,
319
- attributeName: attribute?.name,
320
- });
321
- data.maxIndex = Math.max(data.maxIndex, currentIndex);
322
- }
323
- else {
324
- headers.push({
325
- title,
326
- color: colors[0],
327
- constraint: attribute?.constraint || new UnknownConstraint(),
328
- isValueHeader: false,
329
- attributeName: attribute?.name,
330
- });
331
- }
332
- this.iterateThroughPivotDataHeader(map[title], headers[index], currentIndex, 1, levels, colors, valueColors, valueTitles || [], attributes, data);
333
- currentIndex += this.numChildren(map[title], levels - 1, (valueTitles && valueTitles.length) || 1);
334
- });
335
- }
336
- return { headers, maxIndex: data.maxIndex };
337
- }
338
- iterateThroughPivotDataHeader(currentMap, header, headerIndex, level, maxLevels, colors, valueColors, valueTitles, attributes, additionalData) {
339
- if (level === maxLevels) {
340
- if ((valueTitles || []).length > 1) {
341
- header.children = valueTitles.map((title, index) => ({
342
- title,
343
- targetIndex: headerIndex + index,
344
- color: valueColors[index],
345
- isValueHeader: true,
346
- }));
347
- additionalData.maxIndex = Math.max(additionalData.maxIndex, headerIndex + valueTitles.length - 1);
348
- }
349
- return;
350
- }
351
- header.children = [];
352
- let currentIndex = headerIndex;
353
- Object.keys(currentMap).forEach((title, index) => {
354
- const attribute = attributes && attributes[level];
355
- if (level + 1 === maxLevels && (valueTitles || []).length <= 1) {
356
- header.children.push({
357
- title,
358
- targetIndex: currentIndex,
359
- color: colors[level],
360
- constraint: attribute?.constraint || new UnknownConstraint(),
361
- isValueHeader: false,
362
- attributeName: attribute?.name,
363
- });
364
- additionalData.maxIndex = Math.max(additionalData.maxIndex, currentIndex);
365
- }
366
- else {
367
- header.children.push({
368
- title,
369
- color: colors[level],
370
- constraint: attribute?.constraint || new UnknownConstraint(),
371
- isValueHeader: false,
372
- attributeName: attribute?.name,
373
- });
374
- }
375
- this.iterateThroughPivotDataHeader(currentMap[title], header.children?.[index], currentIndex, level + 1, maxLevels, colors, valueColors, valueTitles, attributes, additionalData);
376
- currentIndex += this.numChildren(currentMap[title], maxLevels - (level + 1), (valueTitles && valueTitles.length) || 1);
377
- });
378
- }
379
- numChildren(map, maxLevels, numTitles) {
380
- if (maxLevels === 0) {
381
- return numTitles;
382
- }
383
- const keys = Object.keys(map || {});
384
- if (maxLevels === 1) {
385
- return keys.length * numTitles;
386
- }
387
- const count = keys.reduce((sum, key) => sum + this.numChildrenRecursive(map[key], 1, maxLevels), 0);
388
- return count * numTitles;
389
- }
390
- numChildrenRecursive(map, level, maxLevels) {
391
- if (level >= maxLevels) {
392
- return 0;
393
- }
394
- const keys = Object.keys(map || {});
395
- if (level + 1 === maxLevels) {
396
- return keys.length;
397
- }
398
- return keys.reduce((sum, key) => sum + this.numChildrenRecursive(map[key], level + 1, maxLevels), 0);
399
- }
400
- createValueTitles(valueAttributes) {
401
- return (valueAttributes || []).reduce(({ titles, constraints }, pivotAttribute) => {
402
- const attribute = this.findAttributeByPivotAttribute(pivotAttribute);
403
- constraints.push(dataAggregationConstraint(pivotAttribute.aggregation) || this.pivotAttributeConstraint(pivotAttribute));
404
- const title = this.createValueTitle(pivotAttribute.aggregation, attribute?.name || '');
405
- titles.push(title);
406
- return { titles, constraints };
407
- }, { titles: [], constraints: [] });
408
- }
409
- createValueTitle(aggregation, attributeName) {
410
- const valueAggregationTitle = this.transform?.formatAggregation?.(aggregation) || aggregation.toString();
411
- return `${valueAggregationTitle} ${attributeName || ''}`.trim();
412
- }
413
- initMatrix(rows, columns) {
414
- const matrix = [];
415
- for (let i = 0; i < rows; i++) {
416
- matrix[i] = [];
417
- for (let j = 0; j < columns; j++) {
418
- matrix[i][j] = undefined;
419
- }
420
- }
421
- return matrix;
422
- }
423
- fillValues(values, dataResources, rowHeaders, columnHeaders, valueAttributes, aggregatedData) {
424
- if (rowHeaders.length > 0) {
425
- this.iterateThroughRowHeaders(values, dataResources, rowHeaders, columnHeaders, valueAttributes, aggregatedData.map);
426
- }
427
- else {
428
- this.iterateThroughColumnHeaders(values, dataResources, columnHeaders, 0, valueAttributes, aggregatedData.map);
429
- }
430
- }
431
- iterateThroughRowHeaders(values, dataResources, rowHeaders, columnHeaders, valueAttributes, currentMap) {
432
- for (const rowHeader of rowHeaders) {
433
- const rowHeaderMap = currentMap[rowHeader.title] || {};
434
- if (rowHeader.children) {
435
- this.iterateThroughRowHeaders(values, dataResources, rowHeader.children, columnHeaders, valueAttributes, rowHeaderMap);
436
- }
437
- else if (isNotNullOrUndefined(rowHeader.targetIndex) && columnHeaders.length > 0) {
438
- this.iterateThroughColumnHeaders(values, dataResources, columnHeaders, rowHeader.targetIndex, valueAttributes, rowHeaderMap);
439
- }
440
- }
441
- }
442
- iterateThroughColumnHeaders(values, dataResources, columnHeaders, rowIndex, valueAttributes, currentMap) {
443
- for (const columnHeader of columnHeaders) {
444
- if (columnHeader.children) {
445
- this.iterateThroughColumnHeaders(values, dataResources, columnHeader.children, rowIndex, valueAttributes, currentMap[columnHeader.title] || {});
446
- }
447
- else if (isNotNullOrUndefined(columnHeader.targetIndex)) {
448
- const aggregatedDataValues = isArray(currentMap) ? currentMap : currentMap[columnHeader.title];
449
- if (valueAttributes.length) {
450
- const valueIndex = columnHeader.targetIndex % valueAttributes.length;
451
- const { value, dataResources: aggregatedDataResources } = this.aggregateValue(valueAttributes[valueIndex], aggregatedDataValues);
452
- values[rowIndex][columnHeader.targetIndex] = value;
453
- dataResources[rowIndex][columnHeader.targetIndex] = aggregatedDataResources || [];
454
- }
455
- }
456
- }
457
- }
458
- aggregateValue(valueAttribute, aggregatedDataValues) {
459
- const resourceAggregatedDataValues = (aggregatedDataValues || []).filter(agg => agg.resourceId === valueAttribute.resourceId && agg.type === valueAttribute.resourceType);
460
- if (resourceAggregatedDataValues.length) {
461
- const dataResources = flattenMatrix(resourceAggregatedDataValues.map(val => val.objects));
462
- const attribute = this.pivotAttributeAttribute(valueAttribute);
463
- if (valueAttribute.aggregation === DataAggregationType.Join) {
464
- // values will be joined in pivot-table-converter
465
- const values = (dataResources || []).map((resource) => resource.data?.[attribute?.id || '']);
466
- return { value: uniqueValues(flattenValues(values)), dataResources };
467
- }
468
- const value = attribute && aggregateDataResources(valueAttribute.aggregation, dataResources, attribute, true);
469
- return { value, dataResources };
470
- }
471
- return {};
472
- }
473
- findAttributeByPivotAttribute(valueAttribute) {
474
- if (valueAttribute.resourceType === AttributesResourceType.Collection) {
475
- return this.collectionsAttributesMap?.[valueAttribute.resourceId]?.[valueAttribute.attributeId];
476
- }
477
- else if (valueAttribute.resourceType === AttributesResourceType.LinkType) {
478
- return this.linkTypesAttributesMap?.[valueAttribute.resourceId]?.[valueAttribute.attributeId];
479
- }
480
- return undefined;
481
- }
482
- }
483
- function getPivotStemConfigType(stemConfig) {
484
- const rowLength = (stemConfig.rowAttributes || []).length;
485
- const columnLength = (stemConfig.columnAttributes || []).length;
486
- if (rowLength > 0 && columnLength > 0) {
487
- return PivotConfigType.RowsAndColumns;
488
- }
489
- else if (rowLength > 0) {
490
- return PivotConfigType.Rows;
491
- }
492
- else if (columnLength > 0) {
493
- return PivotConfigType.Columns;
494
- }
495
- return PivotConfigType.Values;
496
- }
497
- function canMergeConfigsByType(type, c1, c2) {
498
- if (type === PivotConfigType.Rows) {
499
- return (c1.rowAttributes || []).length === (c2.rowAttributes || []).length;
500
- }
501
- else if (type === PivotConfigType.Columns) {
502
- return (c1.columnAttributes || []).length === (c2.columnAttributes || []).length;
503
- }
504
- return ((c1.rowAttributes || []).length === (c2.rowAttributes || []).length &&
505
- (c1.columnAttributes || []).length === (c2.columnAttributes || []).length);
506
- }
507
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGl2b3QtZGF0YS1jb252ZXJ0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9sbXItcGl2b3QtdGFibGUvc3JjL2xpYi91dGlsL3Bpdm90LWRhdGEtY29udmVydGVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNILE9BQU8sRUFPTCxjQUFjLEVBQ2QsbUJBQW1CLEVBQ25CLGNBQWMsRUFJZCxpQkFBaUIsRUFDakIsc0JBQXNCLEVBQ3RCLHlCQUF5QixFQUF3RCxzQkFBc0IsRUFBRSxnQ0FBZ0MsR0FDMUksTUFBTSxzQkFBc0IsQ0FBQztBQUM5QixPQUFPLEVBQUMsaUJBQWlCLEVBQUUsYUFBYSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsWUFBWSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRzNILE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQVNwRCxJQUFLLGVBS0o7QUFMRCxXQUFLLGVBQWU7SUFDbEIseURBQU0sQ0FBQTtJQUNOLHFEQUFJLENBQUE7SUFDSiwyREFBTyxDQUFBO0lBQ1AseUVBQWMsQ0FBQTtBQUNoQixDQUFDLEVBTEksZUFBZSxLQUFmLGVBQWUsUUFLbkI7QUFpQkQsTUFBTSxPQUFPLGtCQUFrQjtJQUNyQixXQUFXLENBQWU7SUFDMUIsU0FBUyxDQUFhO0lBQ3RCLHdCQUF3QixDQUE0QztJQUNwRSxzQkFBc0IsQ0FBNEM7SUFDbEUsSUFBSSxDQUF3QjtJQUM1QixNQUFNLENBQWlCO0lBQ3ZCLFNBQVMsQ0FBb0I7SUFDN0IsY0FBYyxDQUFpQjtJQUUvQixjQUFjLENBQWlCO0lBRXZDO1FBQ0UsSUFBSSxDQUFDLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxDQUFDLEtBQUssRUFBRSxVQUFVLEVBQUUsSUFBSSxFQUFFLG1CQUFtQixFQUFFLEVBQUUsQ0FDeEYsSUFBSSxDQUFDLGdCQUFn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LElBQUksU0FBUyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3pCLE9BQU8sZUFBZSxDQUFDLElBQUksQ0FBQztJQUM5QixDQUFDO1NBQU0sSUFBSSxZQUFZLEdBQUcsQ0FBQyxFQUFFLENBQUM7UUFDNUIsT0FBTyxlQUFlLENBQUMsT0FBTyxDQUFDO0lBQ2pDLENBQUM7SUFDRCxPQUFPLGVBQWUsQ0FBQyxNQUFNLENBQUM7QUFDaEMsQ0FBQztBQUVELFNBQVMscUJBQXFCLENBQUMsSUFBcUIsRUFBRSxFQUFzQixFQUFFLEVBQXNCO0lBQ2xHLElBQUksSUFBSSxLQUFLLGVBQWUsQ0FBQyxJQUFJLEVBQUUsQ0FBQztRQUNsQyxPQUFPLENBQUMsRUFBRSxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUMsYUFBYSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUM3RSxDQUFDO1NBQU0sSUFBSSxJQUFJLEtBQUssZUFBZSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBQzVDLE9BQU8sQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDLGdCQUFnQixJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQztJQUNuRixDQUFDO0lBQ0QsT0FBTyxDQUNMLENBQUMsRUFBRSxDQUFDLGFBQWEsSUFBSSxFQUFFLENBQUMsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUMsYUFBYSxJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU07UUFDbkUsQ0FBQyxFQUFFLENBQUMsZ0JBQWdCLElBQUksRUFBRSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRSxDQUFDLGdCQUFnQixJQUFJLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FDMUUsQ0FBQztBQUNKLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICogTHVtZWVyOiBNb2Rlcm4gRGF0YSBEZWZpbml0aW9uIGFuZCBQcm9jZXNzaW5nIFBsYXRmb3JtXG4gKlxuICogQ29weXJpZ2h0IChDKSBzaW5jZSAyMDE3IEx1bWVlci5pbywgcy5yLm8uIGFuZC9vciBpdHMgYWZmaWxpYXRlcy5cbiAqXG4gKiBUaGlzIHByb2dyYW0gaXMgZnJlZSBzb2Z0d2FyZTogeW91IGNhbiByZWRpc3RyaWJ1dGUgaXQgYW5kL29yIG1vZGlmeVxuICogaXQgdW5kZXIgdGhlIHRlcm1zIG9mIHRoZSBHTlUgR2VuZXJhbCBQdWJsaWMgTGljZW5zZSBhcyBwdWJsaXNoZWQgYnlcbiAqIHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24sIGVpdGhlciB2ZXJzaW9uIDMgb2YgdGhlIExpY2Vuc2UsIG9yXG4gKiAoYXQgeW91ciBvcHRpb24pIGFueSBsYXRlciB2ZXJzaW9uLlxuICpcbiAqIFRoaXMgcHJvZ3JhbSBpcyBkaXN0cmlidXRlZCBpbiB0aGUgaG9wZSB0aGF0IGl0IHdpbGwgYmUgdXNlZnVsLFxuICogYnV0IFdJVEhPVVQgQU5ZIFdBUlJBTlRZOyB3aXRob3V0IGV2ZW4gdGhlIGltcGxpZWQgd2FycmFudHkgb2ZcbiAqIE1FUkNIQU5UQUJJTElUWSBvciBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRS4gIFNlZSB0aGVcbiAqIEdOVSBHZW5lcmFsIFB1YmxpYyBMaWNlbnNlIGZvciBtb3JlIGRldGFpbHMuXG4gKlxuICogWW91IHNob3VsZCBoYXZlIHJlY2VpdmVkIGEgY29weSBvZiB0aGUgR05VIEdlbmVyYWwgUHVibGljIExpY2Vuc2VcbiAqIGFsb25nIHdpdGggdGhpcyBwcm9ncmFtLiAgSWYgbm90LCBzZWUgPGh0dHA6Ly93d3cuZ251Lm9yZy9saWNlbnNlcy8+LlxuICovXG5pbXBvcnQge1xuICBBdHRyaWJ1dGUsXG4gIEFnZ3JlZ2F0ZWREYXRhTWFwLFxuICBBZ2dyZWdhdGVkRGF0YVZhbHVlcyxcbiAgQWdncmVnYXRlZE1hcERhdGEsXG4gIENvbnN0cmFpbnQsXG4gIENvbnN0cmFpbnREYXRhLFxuICBDb25zdHJhaW50VHlwZSxcbiAgRGF0YUFnZ3JlZ2F0aW9uVHlwZSxcbiAgRGF0YUFnZ3JlZ2F0b3IsXG4gIERhdGFBZ2dyZWdhdG9yQXR0cmlidXRlLFxuICBEYXRhVmFsdWUsXG4gIERvY3VtZW50c0FuZExpbmtzRGF0YSxcbiAgVW5rbm93bkNvbnN0cmFpbnQsXG4gIGFnZ3JlZ2F0ZURhdGFSZXNvdXJjZXMsXG4gIGRhdGFBZ2dyZWdhdGlvbkNvbnN0cmFpbnQsIFF1ZXJ5U3RlbSwgQ29sbGVjdGlvbiwgTGlua1R5cGUsIERhdGFSZXNvdXJjZSwgUXVlcnksIEF0dHJpYnV0ZXNSZXNvdXJjZVR5cGUsIGF0dHJpYnV0ZXNSZXNvdXJjZXNBdHRyaWJ1dGVzTWFwLFxufSBmcm9tICdAbHVtZWVyL2RhdGEtZmlsdGVycyc7XG5pbXBvcnQge2RlZXBPYmplY3RzRXF1YWxzLCBmbGF0dGVuTWF0cml4LCBmbGF0dGVuVmFsdWVzLCBpc0FycmF5LCBpc05vdE51bGxPclVuZGVmaW5lZCwgdW5pcXVlVmFsdWVzfSBmcm9tICdAbHVtZWVyL3V0aWxzJztcbmltcG9ydCB7TG1yUGl2b3RBdHRyaWJ1dGUsIExtclBpdm90Q29uZmlnLCBMbXJQaXZvdFJvd0NvbHVtbkF0dHJpYnV0ZSwgTG1yUGl2b3RTdGVtQ29uZmlnLCBMbXJQaXZvdFRyYW5zZm9ybSwgTG1yUGl2b3RWYWx1ZUF0dHJpYnV0ZX0gZnJvbSAnLi9sbXItcGl2b3QtY29uZmlnJztcbmltcG9ydCB7TG1yUGl2b3REYXRhLCBMbXJQaXZvdERhdGFIZWFkZXIsIExtclBpdm90RGltZW5zaW9uQ29uZmlnLCBMbXJQaXZvdEhlYWRlckF0dHJpYnV0ZSwgTG1yUGl2b3RTdGVtRGF0YX0gZnJvbSAnLi9sbXItcGl2b3QtZGF0YSc7XG5pbXBvcnQge3Bpdm90U3RlbUNvbmZpZ0lzRW1wdHl9IGZyb20gJy4vcGl2b3QtdXRpbCc7XG5cbmludGVyZmFjZSBQaXZvdE1lcmdlRGF0YSB7XG4gIGNvbmZpZ3M6IExtclBpdm90U3RlbUNvbmZpZ1tdO1xuICBzdGVtczogUXVlcnlTdGVtW107XG4gIHN0ZW1zSW5kZXhlczogbnVtYmVyW107XG4gIHR5cGU6IFBpdm90Q29uZmlnVHlwZTtcbn1cblxuZW51bSBQaXZvdENvbmZpZ1R5cGUge1xuICBWYWx1ZXMsXG4gIFJvd3MsXG4gIENvbHVtbnMsXG4gIFJvd3NBbmRDb2x1bW5zLFxufVxuXG5pbnRlcmZhY2UgUGl2b3RDb2xvcnMge1xuICByb3dzOiBzdHJpbmdbXTtcbiAgY29sdW1uczogc3RyaW5nW107XG4gIHZhbHVlczogc3RyaW5nW107XG59XG5cbmludGVyZmFjZSBQaXZvdENvbmZpZ0RhdGEge1xuICByb3dzQ29uZmlnOiBMbXJQaXZvdERpbWVuc2lvbkNvbmZpZ1tdO1xuICByb3dTaG93SGVhZGVyQXR0cmlidXRlczogYm9vbGVhbltdO1xuICBjb2x1bW5zQ29uZmlnOiBMbXJQaXZvdERpbWVuc2lvbkNvbmZpZ1tdO1xuICBjb2x1bW5TaG93SGVhZGVyQXR0cmlidXRlczogYm9vbGVhbltdO1xuICByb3dBdHRyaWJ1dGVzOiBBdHRyaWJ1dGVbXTtcbiAgY29sdW1uQXR0cmlidXRlczogQXR0cmlidXRlW107XG59XG5cbmV4cG9ydCBjbGFzcyBQaXZvdERhdGFDb252ZXJ0ZXIge1xuICBwcml2YXRlIGNvbGxlY3Rpb25zOiBDb2xsZWN0aW9uW107XG4gIHByaXZhdGUgbGlua1R5cGVzOiBMaW5rVHlwZVtdO1xuICBwcml2YXRlIGNvbGxlY3Rpb25zQXR0cmlidXRlc01hcDogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgQXR0cmlidXRlPj47XG4gIHByaXZhdGUgbGlua1R5cGVzQXR0cmlidXRlc01hcDogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgQXR0cmlidXRlPj47XG4gIHByaXZhdGUgZGF0YTogRG9jdW1lbnRzQW5kTGlua3NEYXRhO1xuICBwcml2YXRlIGNvbmZpZzogTG1yUGl2b3RDb25maWc7XG4gIHByaXZhdGUgdHJhbnNmb3JtOiBMbXJQaXZvdFRyYW5zZm9ybTtcbiAgcHJpdmF0ZSBjb25zdHJhaW50RGF0YTogQ29uc3RyYWludERhdGE7XG5cbiAgcHJpdmF0ZSBkYXRhQWdncmVnYXRvcjogRGF0YUFnZ3JlZ2F0b3I7XG5cbiAgY29uc3RydWN0b3IoKSB7XG4gICAgdGhpcy5kYXRhQWdncmVnYXRvciA9IG5ldyBEYXRhQWdncmVnYXRvcigodmFsdWUsIGNvbnN0cmFpbnQsIGRhdGEsIGFnZ3JlZ2F0b3JBdHRyaWJ1dGUpID0+XG4gICAgICB0aGlzLmZvcm1hdFBpdm90VmFsdWUodmFsdWUsIGNvbnN0cmFpbnQsIGRhdGEsIGFnZ3JlZ2F0b3JBdHRyaWJ1dGUpXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgZm9ybWF0UGl2b3RWYWx1ZShcbiAgICB2YWx1ZTogYW55LFxuICAgIGNvbnN0cmFpbnQ6IENvbnN0cmFpbnQsXG4gICAgY29uc3RyYWludERhdGE6IENvbnN0cmFpbnREYXRhLFxuICAgIGFnZ3JlZ2F0b3JBdHRyaWJ1dGU6IERhdGFBZ2dyZWdhdG9yQXR0cmlidXRlXG4gICk6IGFueSB7XG4gICAgY29uc3QgcGl2b3RDb25zdHJhaW50ID0gYWdncmVnYXRvckF0dHJpYnV0ZS5kYXRhICYmIChhZ2dyZWdhdG9yQXR0cmlidXRlLmRhdGEgYXMgQ29uc3RyYWludCk7XG4gICAgY29uc3Qgb3ZlcnJpZGVDb25zdHJhaW50ID1cbiAgICAgIHBpdm90Q29uc3RyYWludCAmJiB0aGlzLnRyYW5zZm9ybT8uY2hlY2tWYWxpZENvbnN0cmFpbnRPdmVycmlkZT8uKGNvbnN0cmFpbnQsIHBpdm90Q29uc3RyYWludCk7XG4gICAgY29uc3QgZmluYWxDb25zdHJhaW50ID0gb3ZlcnJpZGVDb25zdHJhaW50IHx8IGNvbnN0cmFpbnQgfHwgbmV3IFVua25vd25Db25zdHJhaW50KCk7XG4gICAgY29uc3Qgc2VyaWFsaXplZFZhbHVlID0gKGNvbnN0cmFpbnQgfHwgbmV3IFVua25vd25Db25zdHJhaW50KCkpLmNyZWF0ZURhdGFWYWx1ZSh2YWx1ZSwgY29uc3RyYWludERhdGEpLnNlcmlhbGl6ZSgpXG4gICAgcmV0dXJuIHRoaXMuZm9ybWF0RGF0YVZhbHVlKGZpbmFsQ29uc3RyYWludC5jcmVhdGVEYXRhVmFsdWUoc2VyaWFsaXplZFZhbHVlLCBjb25zdHJhaW50RGF0YSksIGZpbmFsQ29uc3RyYWludCk7XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdERhdGFWYWx1ZShkYXRhVmFsdWU6IERhdGFWYWx1ZSwgY29uc3RyYWludDogQ29uc3RyYWludCk6IGFueSB7XG4gICAgc3dpdGNoIChjb25zdHJhaW50LnR5cGUpIHtcbiAgICAgIGNhc2UgQ29uc3RyYWludFR5cGUuRGF0ZVRpbWU6XG4gICAgICAgIHJldHVybiBkYXRhVmFsdWUuZm9ybWF0KCk7XG4gICAgICBkZWZhdWx0OlxuICAgICAgICByZXR1cm4gZGF0YVZhbHVlLnNlcmlhbGl6ZSgpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdXBkYXRlRGF0YShcbiAgICBjb25maWc6IExtclBpdm90Q29uZmlnLFxuICAgIHRyYW5zZm9ybTogTG1yUGl2b3RUcmFuc2Zvcm0sXG4gICAgY29sbGVjdGlvbnM6IENvbGxlY3Rpb25bXSxcbiAgICBsaW5rVHlwZXM6IExpbmtUeXBlW10sXG4gICAgZGF0YTogRG9jdW1lbnRzQW5kTGlua3NEYXRhLFxuICAgIGNvbnN0cmFpbnREYXRhOiBDb25zdHJhaW50RGF0YVxuICApIHtcbiAgICB0aGlzLmNvbmZpZyA9IGNvbmZpZztcbiAgICB0aGlzLnRyYW5zZm9ybSA9IHRyYW5zZm9ybTtcbiAgICB0aGlzLmNvbGxlY3Rpb25zID0gY29sbGVjdGlvbnM7XG4gICAgdGhpcy5saW5rVHlwZXMgPSBsaW5rVHlwZXM7XG4gICAgdGhpcy5jb2xsZWN0aW9uc0F0dHJpYnV0ZXNNYXAgPSBhdHRyaWJ1dGVzUmVzb3VyY2VzQXR0cmlidXRlc01hcChjb2xsZWN0aW9ucyk7XG4gICAgdGhpcy5saW5rVHlwZXNBdHRyaWJ1dGVzTWFwID0gYXR0cmlidXRlc1Jlc291cmNlc0F0dHJpYnV0ZXNNYXAobGlua1R5cGVzKTtcbiAgICB0aGlzLmRhdGEgPSBkYXRhO1xuICAgIHRoaXMuY29uc3RyYWludERhdGEgPSBjb25zdHJhaW50RGF0YTtcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVEYXRhKFxuICAgIGNvbmZpZzogTG1yUGl2b3RDb25maWcsXG4gICAgdHJhbnNmb3JtOiBMbXJQaXZvdFRyYW5zZm9ybSxcbiAgICBjb2xsZWN0aW9uczogQ29sbGVjdGlvbltdLFxuICAgIGxpbmtUeXBlczogTGlua1R5cGVbXSxcbiAgICBkYXRhOiBEb2N1bWVudHNBbmRMaW5rc0RhdGEsXG4gICAgcXVlcnk6IFF1ZXJ5LFxuICAgIGNvbnN0cmFpbnREYXRhPzogQ29uc3RyYWludERhdGFcbiAgKTogTG1yUGl2b3REYXRhIHtcbiAgICB0aGlzLnVwZGF0ZURhdGEoY29uZmlnLCB0cmFuc2Zvcm0sIGNvbGxlY3Rpb25zLCBsaW5rVHlwZXMsIGRhdGEsIGNvbnN0cmFpbnREYXRhKTtcblxuICAgIGNvbnN0IHtzdGVtc0NvbmZpZ3MsIHN0ZW1zfSA9IHRoaXMuZmlsdGVyRW1wdHlDb25maWdzKGNvbmZpZywgcXVlcnkpO1xuXG4gICAgY29uc3QgbWVyZ2VEYXRhID0gdGhpcy5jcmVhdGVQaXZvdE1lcmdlRGF0YShjb25maWcubWVyZ2VUYWJsZXMsIHN0ZW1zQ29uZmlncywgc3RlbXMpO1xuICAgIGNvbnN0IGFibGVUb01lcmdlID0gbWVyZ2VEYXRhLmxlbmd0aCA8PSAxO1xuICAgIGNvbnN0IHBpdm90RGF0YSA9IHRoaXMubWVyZ2VQaXZvdERhdGEobWVyZ2VEYXRhKTtcbiAgICByZXR1cm4ge2RhdGE6IHBpdm90RGF0YSwgY29uc3RyYWludERhdGEsIGFibGVUb01lcmdlLCBtZXJnZVRhYmxlczogY29uZmlnLm1lcmdlVGFibGVzfTtcbiAgfVxuXG4gIHByaXZhdGUgZmlsdGVyRW1wdHlDb25maWdzKGNvbmZpZzogTG1yUGl2b3RDb25maWcsIHF1ZXJ5OiBRdWVyeSk6IHtzdGVtc0NvbmZpZ3M6IExtclBpdm90U3RlbUNvbmZpZ1tdOyBzdGVtczogUXVlcnlTdGVtW119IHtcbiAgICByZXR1cm4gKGNvbmZpZy5zdGVtc0NvbmZpZ3MgfHwgW10pLnJlZHVjZShcbiAgICAgICh7c3RlbXNDb25maWdzLCBzdGVtc30sIHN0ZW1Db25maWcsIGluZGV4KSA9PiB7XG4gICAgICAgIGlmICghcGl2b3RTdGVtQ29uZmlnSXNFbXB0eShzdGVtQ29uZmlnKSkge1xuICAgICAgICAgIGNvbnN0IHN0ZW0gPSAocXVlcnkuc3RlbXMgfHwgW10pW2luZGV4XTtcbiAgICAgICAgICBzdGVtc0NvbmZpZ3MucHVzaChzdGVtQ29uZmlnKTtcbiAgICAgICAgICBzdGVtcy5wdXNoKHN0ZW0pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIHtzdGVtc0NvbmZpZ3MsIHN0ZW1zfTtcbiAgICAgIH0sXG4gICAgICB7c3RlbXNDb25maWdzOiBbXSwgc3RlbXM6IFtdfVxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZVBpdm90TWVyZ2VEYXRhKFxuICAgIG1lcmdlVGFibGVzOiBib29sZWFuLFxuICAgIHN0ZW1zQ29uZmlnczogTG1yUGl2b3RTdGVtQ29uZmlnW10sXG4gICAgc3RlbXM6IFF1ZXJ5U3RlbVtdXG4gICk6IFBpdm90TWVyZ2VEYXRhW10ge1xuICAgIHJldHVybiBzdGVtc0NvbmZpZ3MucmVkdWNlKChtZXJnZURhdGE6IFBpdm90TWVyZ2VEYXRhW10sIHN0ZW1Db25maWcsIGluZGV4KSA9PiB7XG4gICAgICBjb25zdCBjb25maWdUeXBlID0gZ2V0UGl2b3RTdGVtQ29uZmlnVHlwZShzdGVtQ29uZmlnKTtcbiAgICAgIGNvbnN0IG1lcmdlRGF0YUluZGV4ID0gbWVyZ2VEYXRhLmZpbmRJbmRleChcbiAgICAgICAgZGF0YSA9PiBkYXRhLnR5cGUgPT09IGNvbmZpZ1R5cGUgJiYgY2FuTWVyZ2VDb25maWdzQnlUeXBlKGRhdGEudHlwZSwgZGF0YS5jb25maWdzWzBdLCBzdGVtQ29uZmlnKVxuICAgICAgKTtcbiAgICAgIGlmIChtZXJnZVRhYmxlcyAmJiBtZXJnZURhdGFJbmRleCA+PSAwKSB7XG4gICAgICAgIG1lcmdlRGF0YVttZXJnZURhdGFJbmRleF0uY29uZmlncy5wdXNoKHN0ZW1Db25maWcpO1xuICAgICAgICBtZXJnZURhdGFbbWVyZ2VEYXRhSW5kZXhdLnN0ZW1zLnB1c2goc3RlbXNbaW5kZXhdKTtcbiAgICAgICAgbWVyZ2VEYXRhW21lcmdlRGF0YUluZGV4XS5zdGVtc0luZGV4ZXMucHVzaChpbmRleCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtZXJnZURhdGEucHVzaCh7Y29uZmlnczogW3N0ZW1Db25maWddLCBzdGVtczogW3N0ZW1zW2luZGV4XV0sIHN0ZW1zSW5kZXhlczogW2luZGV4XSwgdHlwZTogY29uZmlnVHlwZX0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gbWVyZ2VEYXRhO1xuICAgIH0sIFtdKTtcbiAgfVxuXG4gIHByaXZhdGUgbWVyZ2VQaXZvdERhdGEobWVyZ2VEYXRhOiBQaXZvdE1lcmdlRGF0YVtdKTogTG1yUGl2b3RTdGVtRGF0YVtdIHtcbiAgICByZXR1cm4gbWVyZ2VEYXRhLnJlZHVjZSgoc3RlbURhdGEsIGRhdGEpID0+IHtcbiAgICAgIGlmIChkYXRhLnR5cGUgPT09IFBpdm90Q29uZmlnVHlwZS5WYWx1ZXMpIHtcbiAgICAgICAgc3RlbURhdGEucHVzaCh0aGlzLmNvbnZlcnRWYWx1ZUF0dHJpYnV0ZXMoZGF0YS5jb25maWdzLCBkYXRhLnN0ZW1zLCBkYXRhLnN0ZW1zSW5kZXhlcykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RlbURhdGEucHVzaCh0aGlzLnRyYW5zZm9ybVN0ZW1zKGRhdGEuY29uZmlncywgZGF0YS5zdGVtcywgZGF0YS5zdGVtc0luZGV4ZXMpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBzdGVtRGF0YTtcbiAgICB9LCBbXSk7XG4gIH1cblxuICBwcml2YXRlIHRyYW5zZm9ybVN0ZW1zKGNvbmZpZ3M6IExtclBpdm90U3RlbUNvbmZpZ1tdLCBxdWVyeVN0ZW1zOiBRdWVyeVN0ZW1bXSwgc3RlbXNJbmRleGVzOiBudW1iZXJbXSk6IExtclBpdm90U3RlbURhdGEge1xuICAgIGNvbnN0IHBpdm90Q29sb3JzOiBQaXZvdENvbG9ycyA9IHtyb3dzOiBbXSwgY29sdW1uczogW10sIHZhbHVlczogW119O1xuICAgIGNvbnN0IG1lcmdlZFZhbHVlQXR0cmlidXRlczogTG1yUGl2b3RWYWx1ZUF0dHJpYnV0ZVtdID0gW107XG4gICAgbGV0IG1lcmdlZEFnZ3JlZ2F0ZWREYXRhOiBBZ2dyZWdhdGVkTWFwRGF0YSA9IG51bGw7XG4gICAgbGV0IGFkZGl0aW9uYWxEYXRhOiBQaXZvdENvbmZpZ0RhdGE7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbmZpZ3MubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGNvbmZpZyA9IGNvbmZpZ3NbaV07XG4gICAgICBjb25zdCBxdWVyeVN0ZW0gPSBxdWVyeVN0ZW1zW2ldO1xuICAgICAgY29uc3Qgc3RlbUluZGV4ID0gc3RlbXNJbmRleGVzW2ldO1xuICAgICAgY29uc3Qgc3RlbURhdGEgPSB0aGlzLmRhdGE/LmRhdGFCeVN0ZW1zPy5bc3RlbUluZGV4XTtcblxuICAgICAgdGhpcy5kYXRhQWdncmVnYXRvci51cGRhdGVEYXRhKFxuICAgICAgICB0aGlzLmNvbGxlY3Rpb25zLFxuICAgICAgICBzdGVtRGF0YT8uZG9jdW1lbnRzIHx8IFtdLFxuICAgICAgICB0aGlzLmxpbmtUeXBlcyxcbiAgICAgICAgc3RlbURhdGE/LmxpbmtJbnN0YW5jZXMgfHwgW10sXG4gICAgICAgIHF1ZXJ5U3RlbSxcbiAgICAgICAgdGhpcy5jb25zdHJhaW50RGF0YVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHJvd0F0dHJpYnV0ZXMgPSAoY29uZmlnLnJvd0F0dHJpYnV0ZXMgfHwgW10pLm1hcChhdHRyaWJ1dGUgPT5cbiAgICAgICAgdGhpcy5jb252ZXJ0UGl2b3RSb3dDb2x1bW5BdHRyaWJ1dGUoYXR0cmlidXRlKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IGNvbHVtbkF0dHJpYnV0ZXMgPSAoY29uZmlnLmNvbHVtbkF0dHJpYnV0ZXMgfHwgW10pLm1hcChhdHRyaWJ1dGUgPT5cbiAgICAgICAgdGhpcy5jb252ZXJ0UGl2b3RSb3dDb2x1bW5BdHRyaWJ1dGUoYXR0cmlidXRlKVxuICAgICAgKTtcbiAgICAgIGNvbnN0IHZhbHVlQXR0cmlidXRlcyA9IChjb25maWcudmFsdWVBdHRyaWJ1dGVzIHx8IFtdKS5tYXAoYXR0cmlidXRlID0+IHRoaXMuY29udmVydFBpdm90QXR0cmlidXRlKGF0dHJpYnV0ZSkpO1xuXG4gICAgICBwaXZvdENvbG9ycy5yb3dzLnB1c2goLi4udGhpcy5nZXRBdHRyaWJ1dGVzQ29sb3JzKGNvbmZpZy5yb3dBdHRyaWJ1dGVzKSk7XG4gICAgICBwaXZvdENvbG9ycy5jb2x1bW5zLnB1c2goLi4udGhpcy5nZXRBdHRyaWJ1dGVzQ29sb3JzKGNvbmZpZy5jb2x1bW5BdHRyaWJ1dGVzKSk7XG4gICAgICBwaXZvdENvbG9ycy52YWx1ZXMucHVzaCguLi50aGlzLmdldEF0dHJpYnV0ZXNDb2xvcnMoY29uZmlnLnZhbHVlQXR0cmlidXRlcykpO1xuXG4gICAgICBjb25zdCBhZ2dyZWdhdGVkRGF0YSA9IHRoaXMuZGF0YUFnZ3JlZ2F0b3IuYWdncmVnYXRlKHJvd0F0dHJpYnV0ZXMsIGNvbHVtbkF0dHJpYnV0ZXMsIHZhbHVlQXR0cmlidXRlcyk7XG4gICAgICBtZXJnZWRBZ2dyZWdhdGVkRGF0YSA9IHRoaXMubWVyZ2VBZ2dyZWdhdGVkRGF0YShtZXJnZWRBZ2dyZWdhdGVkRGF0YSwgYWdncmVnYXRlZERhdGEpO1xuXG4gICAgICBjb25zdCBmaWx0ZXJlZFZhbHVlQXR0cmlidXRlcyA9IChjb25maWcudmFsdWVBdHRyaWJ1dGVzIHx8IFtdKS5maWx0ZXIoXG4gICAgICAgIHZhbHVlQXR0ciA9PiAhbWVyZ2VkVmFsdWVBdHRyaWJ1dGVzLnNvbWUobWVyQXR0ciA9PiBkZWVwT2JqZWN0c0VxdWFscyh2YWx1ZUF0dHIsIG1lckF0dHIpKVxuICAgICAgKTtcbiAgICAgIG1lcmdlZFZhbHVlQXR0cmlidXRlcy5wdXNoKC4uLmZpbHRlcmVkVmFsdWVBdHRyaWJ1dGVzKTtcblxuICAgICAgaWYgKCFhZGRpdGlvbmFsRGF0YSkge1xuICAgICAgICBjb25zdCByb3dTdGlja3kgPSB0aGlzLm1hcFN0aWNreVZhbHVlcygoY29uZmlnLnJvd0F0dHJpYnV0ZXMgfHwgW10pLm1hcChhdHRyID0+IGF0dHIuc3RpY2t5KSk7XG4gICAgICAgIGNvbnN0IGNvbHVtblN0aWNreSA9IHRoaXMubWFwU3RpY2t5VmFsdWVzKChjb25maWcuY29sdW1uQXR0cmlidXRlcyB8fCBbXSkubWFwKGF0dHIgPT4gYXR0ci5zdGlja3kpKTtcbiAgICAgICAgYWRkaXRpb25hbERhdGEgPSB7XG4gICAgICAgICAgcm93c0NvbmZpZzogKGNvbmZpZy5yb3dBdHRyaWJ1dGVzIHx8IFtdKS5tYXAoKGF0dHIsIGluZGV4KSA9PiAoe3Nob3dTdW1zOiBhdHRyLnNob3dTdW1zLCBzb3J0OiBhdHRyLnNvcnQsIGV4cHJlc3Npb25zOiBhdHRyLmV4cHJlc3Npb25zLCBzdGlja3k6IHJvd1N0aWNreVtpbmRleF19KSksXG4gICAgICAgICAgY29sdW1uc0NvbmZpZzogKGNvbmZpZy5jb2x1bW5BdHRyaWJ1dGVzIHx8IFtdKS5tYXAoKGF0dHIsIGluZGV4KSA9PiAoe3Nob3dTdW1zOiBhdHRyLnNob3dTdW1zLCBzb3J0OiBhdHRyLnNvcnQsIGV4cHJlc3Npb25zOiBhdHRyLmV4cHJlc3Npb25zLCBzdGlja3k6IGNvbHVtblN0aWNreVtpbmRleF19KSksXG4gICAgICAgICAgcm93U2hvd0hlYWRlckF0dHJpYnV0ZXM6IChjb25maWcucm93QXR0cmlidXRlcyB8fCBbXSkubWFwKGF0dHIgPT4gYXR0ci5zaG93SGVhZGVyKSxcbiAgICAgICAgICByb3dBdHRyaWJ1dGVzOiAoY29uZmlnLnJvd0F0dHJpYnV0ZXMgfHwgW10pLm1hcChhdHRyID0+IHRoaXMucGl2b3RBdHRyaWJ1dGVBdHRyaWJ1dGUoYXR0cikpLFxuICAgICAgICAgIGNvbHVtblNob3dIZWFkZXJBdHRyaWJ1dGVzOiAoY29uZmlnLmNvbHVtbkF0dHJpYnV0ZXMgfHwgW10pLm1hcChhdHRyID0+IGZhbHNlKSxcbiAgICAgICAgICBjb2x1bW5BdHRyaWJ1dGVzOiAoY29uZmlnLmNvbHVtbkF0dHJpYnV0ZXMgfHwgW10pLm1hcChhdHRyID0+IHRoaXMucGl2b3RBdHRyaWJ1dGVBdHRyaWJ1dGUoYXR0cikpLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNvbnZlcnRBZ2dyZWdhdGVkRGF0YShtZXJnZWRBZ2dyZWdhdGVkRGF0YSwgbWVyZ2VkVmFsdWVBdHRyaWJ1dGVzLCBwaXZvdENvbG9ycywgYWRkaXRpb25hbERhdGEpO1xuICB9XG5cbiAgcHJpdmF0ZSBtYXBTdGlja3lWYWx1ZXModmFsdWVzOiBib29sZWFuW10pOiBib29sZWFuW10ge1xuICAgIC8vIHdlIHN1cHBvcnQgb25seSBzdGlja3kgcm93cy9jb2x1bW5zIGluIGEgcm93XG4gICAgcmV0dXJuIHZhbHVlcy5yZWR1Y2UoKHN0aWNreVZhbHVlcywgc3RpY2t5LCBpbmRleCkgPT4ge1xuICAgICAgc3RpY2t5VmFsdWVzLnB1c2goc3RpY2t5ICYmIChpbmRleCA9PT0gMCB8fCBzdGlja3lWYWx1ZXNbaW5kZXggLSAxXSkpO1xuICAgICAgcmV0dXJuIHN0aWNreVZhbHVlcztcbiAgICB9LCBbXSk7XG4gIH1cblxuICBwcml2YXRlIHBpdm90QXR0cmlidXRlQ29uc3RyYWludChwaXZvdEF0dHJpYnV0ZTogTG1yUGl2b3RBdHRyaWJ1dGUpOiBDb25zdHJhaW50IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBhdHRyaWJ1dGUgPSB0aGlzLmZpbmRBdHRyaWJ1dGVCeVBpdm90QXR0cmlidXRlKHBpdm90QXR0cmlidXRlKTtcbiAgICBjb25zdCBjb25zdHJhaW50ID0gYXR0cmlidXRlICYmIGF0dHJpYnV0ZS5jb25zdHJhaW50O1xuICAgIGNvbnN0IG92ZXJyaWRlQ29uc3RyYWludCA9XG4gICAgICBwaXZvdEF0dHJpYnV0ZS5jb25zdHJhaW50ICYmXG4gICAgICB0aGlzLnRyYW5zZm9ybT8uY2hlY2tWYWxpZENvbnN0cmFpbnRPdmVycmlkZT8uKGNvbnN0cmFpbnQsIHBpdm90QXR0cmlidXRlLmNvbnN0cmFpbnQpO1xuICAgIHJldHVybiBvdmVycmlkZUNvbnN0cmFpbnQgfHwgY29uc3RyYWludDtcbiAgfVxuXG4gIHByaXZhdGUgcGl2b3RBdHRyaWJ1dGVBdHRyaWJ1dGUocGl2b3RBdHRyaWJ1dGU6IExtclBpdm90QXR0cmlidXRlKTogQXR0cmlidXRlIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBhdHRyaWJ1dGUgPSB0aGlzLmZpbmRBdHRyaWJ1dGVCeVBpdm90QXR0cmlidXRlKHBpdm90QXR0cmlidXRlKTtcbiAgICBpZiAoYXR0cmlidXRlKSB7XG4gICAgICBjb25zdCBjb25zdHJhaW50ID0gYXR0cmlidXRlPy5jb25zdHJhaW50O1xuICAgICAgY29uc3Qgb3ZlcnJpZGVDb25zdHJhaW50ID1cbiAgICAgICAgcGl2b3RBdHRyaWJ1dGUuY29uc3RyYWludCAmJlxuICAgICAgICB0aGlzLnRyYW5zZm9ybT8uY2hlY2tWYWxpZENvbnN0cmFpbnRPdmVycmlkZT8uKGNvbnN0cmFpbnQsIHBpdm90QXR0cmlidXRlLmNvbnN0cmFpbnQpO1xuICAgICAgcmV0dXJuIHsuLi5hdHRyaWJ1dGUsIGNvbnN0cmFpbnQ6IG92ZXJyaWRlQ29uc3RyYWludCB8fCBjb25zdHJhaW50IHx8IG5ldyBVbmtub3duQ29uc3RyYWludCgpfTtcbiAgICB9XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHByaXZhdGUgbWVyZ2VBZ2dyZWdhdGVkRGF0YShhMTogQWdncmVnYXRlZE1hcERhdGEsIGEyOiBBZ2dyZWdhdGVkTWFwRGF0YSk6IEFnZ3JlZ2F0ZWRNYXBEYXRhIHtcbiAgICBpZiAoIWExIHx8ICFhMikge1xuICAgICAgcmV0dXJuIGExIHx8IGEyO1xuICAgIH1cblxuICAgIHRoaXMubWVyZ2VNYXBzKGExLm1hcCwgYTIubWFwKTtcbiAgICB0aGlzLm1lcmdlTWFwcyhhMS5jb2x1bW5zTWFwLCBhMi5jb2x1bW5zTWFwKTtcbiAgICByZXR1cm4ge1xuICAgICAgbWFwOiBhMS5tYXAsXG4gICAgICBjb2x1bW5zTWFwOiBhMS5jb2x1bW5zTWFwLFxuICAgICAgcm93TGV2ZWxzOiBNYXRoLm1heChhMS5yb3dMZXZlbHMsIGEyLnJvd0xldmVscyksXG4gICAgICBjb2x1bW5MZXZlbHM6IE1hdGgubWF4KGExLmNvbHVtbkxldmVscywgYTIuY29sdW1uTGV2ZWxzKSxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBtZXJnZU1hcHMobTE6IFJlY29yZDxzdHJpbmcsIGFueT4sIG0yOiBSZWNvcmQ8c3RyaW5nLCBhbnk+KSB7XG4gICAgT2JqZWN0LmtleXMobTIpLmZvckVhY2goa2V5ID0+IHtcbiAgICAgIGlmIChtMVtrZXldKSB7XG4gICAgICAgIGlmIChpc0FycmF5KG0xW2tleV0pICYmIGlzQXJyYXkobTJba2V5XSkpIHtcbiAgICAgICAgICBtMVtrZXldLnB1c2goLi4ubTJba2V5XSk7XG4gICAgICAgIH0gZWxzZSBpZiAoIWlzQXJyYXkobTFba2V5XSkgJiYgIWlzQXJyYXkobTJba2V5XSkpIHtcbiAgICAgICAgICB0aGlzLm1lcmdlTWFwcyhtMVtrZXldLCBtMltrZXldKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbTFba2V5XSA9IG0yW2tleV07XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGdldEF0dHJpYnV0ZXNDb2xvcnMoYXR0cmlidXRlczogTG1yUGl2b3RBdHRyaWJ1dGVbXSk6IHN0cmluZ1tdIHtcbiAgICByZXR1cm4gKGF0dHJpYnV0ZXMgfHwgW10pLm1hcChhdHRyaWJ1dGUgPT4ge1xuICAgICAgY29uc3QgcmVzb3VyY2UgPSB0aGlzLmRhdGFBZ2dyZWdhdG9yLmdldE5leHRDb2xsZWN0aW9uUmVzb3VyY2UoYXR0cmlidXRlLnJlc291cmNlSW5kZXgpO1xuICAgICAgcmV0dXJuIHJlc291cmNlICYmICg8Q29sbGVjdGlvbj5yZXNvdXJjZSkuY29sb3I7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGNvbnZlcnRQaXZvdFJvd0NvbHVtbkF0dHJpYnV0ZShwaXZvdEF0dHJpYnV0ZTogTG1yUGl2b3RSb3dDb2x1bW5BdHRyaWJ1dGUpOiBEYXRhQWdncmVnYXRvckF0dHJpYnV0ZSB7XG4gICAgcmV0dXJuIHsuLi50aGlzLmNvbnZlcnRQaXZvdEF0dHJpYnV0ZShwaXZvdEF0dHJpYnV0ZSksIGRhdGE6IHBpdm90QXR0cmlidXRlLmNvbnN0cmFpbnR9O1xuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0UGl2b3RBdHRyaWJ1dGUocGl2b3RBdHRyaWJ1dGU6IExtclBpdm90QXR0cmlidXRlKTogRGF0YUFnZ3JlZ2F0b3JBdHRyaWJ1dGUge1xuICAgIHJldHVybiB7cmVzb3VyY2VJbmRleDogcGl2b3RBdHRyaWJ1dGUucmVzb3VyY2VJbmRleCwgYXR0cmlidXRlSWQ6IHBpdm90QXR0cmlidXRlLmF0dHJpYnV0ZUlkfTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydFZhbHVlQXR0cmlidXRlcyhcbiAgICBjb25maWdzOiBMbXJQaXZvdFN0ZW1Db25maWdbXSxcbiAgICBzdGVtczogUXVlcnlTdGVtW10sXG4gICAgc3RlbXNJbmRleGVzOiBudW1iZXJbXVxuICApOiBMbXJQaXZvdFN0ZW1EYXRhIHtcbiAgICBjb25zdCBkYXRhID0gY29uZmlncy5yZWR1Y2UoXG4gICAgICAoYWxsRGF0YSwgY29uZmlnLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBzdGVtID0gc3RlbXNbaW5kZXhdO1xuICAgICAgICBjb25zdCBzdGVtSW5kZXggPSBzdGVtc0luZGV4ZXNbaW5kZXhdO1xuXG4gICAgICAgIGNvbnN0IHN0ZW1EYXRhID0gdGhpcy5kYXRhPy5kYXRhQnlTdGVtcz8uW3N0ZW1JbmRleF07XG4gICAgICAgIHRoaXMuZGF0YUFnZ3JlZ2F0b3IudXBkYXRlRGF0YShcbiAgICAgICAgICB0aGlzLmNvbGxlY3Rpb25zLFxuICAgICAgICAgIHN0ZW1EYXRhPy5kb2N1bWVudHMgfHwgW10sXG4gICAgICAgICAgdGhpcy5saW5rVHlwZXMsXG4gICAgICAgICAgc3RlbURhdGE/LmxpbmtJbnN0YW5jZXMgfHwgW10sXG4gICAgICAgICAgc3RlbSxcbiAgICAgICAgICB0aGlzLmNvbnN0cmFpbnREYXRhXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgdmFsdWVBdHRyaWJ1dGVzID0gY29uZmlnLnZhbHVlQXR0cmlidXRlcyB8fCBbXTtcbiAgICAgICAgYWxsRGF0YS52YWx1ZVR5cGVzLnB1c2goLi4udmFsdWVBdHRyaWJ1dGVzLm1hcChhdHRyID0+IGF0dHIudmFsdWVUeXBlKSk7XG4gICAgICAgIGNvbnN0IHZhbHVlQ29sb3JzID0gdGhpcy5nZXRBdHRyaWJ1dGVzQ29sb3JzKHZhbHVlQXR0cmlidXRlcyk7XG5cbiAgICAgICAgY29uc3Qge3RpdGxlcywgY29uc3RyYWludHN9ID0gdGhpcy5jcmVhdGVWYWx1ZVRpdGxlcyh2YWx1ZUF0dHJpYnV0ZXMpO1xuICAgICAgICBhbGxEYXRhLnRpdGxlcy5wdXNoKC4uLnRpdGxlcyk7XG4gICAgICAgIGFsbERhdGEuY29uc3RyYWludHMucHVzaCguLi5jb25zdHJhaW50cyk7XG5cbiAgICAgICAgY29uc3Qge2hlYWRlcnN9ID0gdGhpcy5jb252ZXJ0TWFwVG9QaXZvdERhdGFIZWFkZXIoe30sIDAsIFtdLCB2YWx1ZUNvbG9ycywgW10sIHRpdGxlcywgYWxsRGF0YS5oZWFkZXJzLmxlbmd0aCk7XG4gICAgICAgIGFsbERhdGEuaGVhZGVycy5wdXNoKC4uLmhlYWRlcnMpO1xuXG4gICAgICAgIGFsbERhdGEuYWdncmVnYXRpb25zID0gWy4uLih2YWx1ZUF0dHJpYnV0ZXMgfHwgW10pLm1hcCh2YWx1ZUF0dHJpYnV0ZSA9PiB2YWx1ZUF0dHJpYnV0ZS5hZ2dyZWdhdGlvbildO1xuXG4gICAgICAgIGNvbnN0IHt2YWx1ZXMsIGRhdGFSZXNvdXJjZXN9ID0gKHZhbHVlQXR0cmlidXRlcyB8fCBbXSkucmVkdWNlPHt2YWx1ZXM6IGFueVtdOyBkYXRhUmVzb3VyY2VzOiBEYXRhUmVzb3VyY2VbXVtdfT4oXG4gICAgICAgICAgKGFnZ3JlZ2F0b3IsIHZhbHVlQXR0cmlidXRlLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZGF0YVJlc291cmNlcyA9IHRoaXMuZmluZERhdGFSZXNvdXJjZXNCeVBpdm90QXR0cmlidXRlKHZhbHVlQXR0cmlidXRlKTtcbiAgICAgICAgICAgIGNvbnN0IGF0dHJpYnV0ZSA9IHRoaXMuZmluZEF0dHJpYnV0ZUJ5UGl2b3RBdHRyaWJ1dGUodmFsdWVBdHRyaWJ1dGUpO1xuICAgICAgICAgICAgY29uc3QgdmFsdWUgPSBhZ2dyZWdhdGVEYXRhUmVzb3VyY2VzKHZhbHVlQXR0cmlidXRlLmFnZ3JlZ2F0aW9uLCBkYXRhUmVzb3VyY2VzLCBhdHRyaWJ1dGUsIHRydWUpO1xuICAgICAgICAgICAgYWdncmVnYXRvci52YWx1ZXMucHVzaCh2YWx1ZSk7XG4gICAgICAgICAgICBhZ2dyZWdhdG9yLmRhdGFSZXNvdXJjZXMucHVzaChkYXRhUmVzb3VyY2VzKTtcbiAgICAgICAgICAgIHJldHVybiBhZ2dyZWdhdG9yO1xuICAgICAgICAgIH0sXG4gICAgICAgICAge3ZhbHVlczogW10sIGRhdGFSZXNvdXJjZXM6IFtdfVxuICAgICAgICApO1xuXG4gICAgICAgIGFsbERhdGEudmFsdWVzLnB1c2goLi4udmFsdWVzKTtcbiAgICAgICAgYWxsRGF0YS5kYXRhUmVzb3VyY2VzLnB1c2goLi4uZGF0YVJlc291cmNlcyk7XG4gICAgICAgIHJldHVybiBhbGxEYXRhO1xuICAgICAgfSxcbiAgICAgIHt0aXRsZXM6IFtdLCBjb25zdHJhaW50czogW10sIGhlYWRlcnM6IFtdLCB2YWx1ZXM6IFtdLCBkYXRhUmVzb3VyY2VzOiBbXSwgdmFsdWVUeXBlczogW10sIGFnZ3JlZ2F0aW9uczogW119XG4gICAgKTtcblxuICAgIHJldHVybiB7XG4gICAgICBjb2x1bW5IZWFkZXJzOiBkYXRhLmhlYWRlcnMsXG4gICAgICBjb2x1bW5IZWFkZXJBdHRyaWJ1dGVzOiBbXSxcbiAgICAgIHJvd0hlYWRlcnM6IFtdLFxuICAgICAgcm93SGVhZGVyQXR0cmlidXRlczogW10sXG4gICAgICB2YWx1ZVRpdGxlczogZGF0YS50aXRsZXMsXG4gICAgICB2YWx1ZXM6IFtkYXRhLnZhbHVlc10sXG4gICAgICBkYXRhUmVzb3VyY2VzOiBbZGF0YS5kYXRhUmVzb3VyY2VzXSxcbiAgICAgIHZhbHVlc0NvbnN0cmFpbnRzOiBkYXRhLmNvbnN0cmFpbnRzLFxuICAgICAgdmFsdWVUeXBlczogZGF0YS52YWx1ZVR5cGVzLFxuICAgICAgdmFsdWVBZ2dyZWdhdGlvbnM6IGRhdGEuYWdncmVnYXRpb25zLFxuXG4gICAgICByb3dzQ29uZmlnOiBbXSxcbiAgICAgIGNvbHVtbnNDb25maWc6IFtdLFxuXG4gICAgICBoYXNBZGRpdGlvbmFsQ29sdW1uTGV2ZWw6IHRydWUsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgZmluZERhdGFSZXNvdXJjZXNCeVBpdm90QXR0cmlidXRlKHBpdm90QXR0cmlidXRlOiBMbXJQaXZvdEF0dHJpYnV0ZSk6IERhdGFSZXNvdXJjZVtdIHtcbiAgICBpZiAocGl2b3RBdHRyaWJ1dGUucmVzb3VyY2VUeXBlID09PSBBdHRyaWJ1dGVzUmVzb3VyY2VUeXBlLkNvbGxlY3Rpb24pIHtcbiAgICAgIHJldHVybiAodGhpcy5kYXRhPy51bmlxdWVEb2N1bWVudHMgfHwgW10pLmZpbHRlcihkb2N1bWVudCA9PiBkb2N1bWVudC5jb2xsZWN0aW9uSWQgPT09IHBpdm90QXR0cmlidXRlLnJlc291cmNlSWQpO1xuICAgIH0gZWxzZSBpZiAocGl2b3RBdHRyaWJ1dGUucmVzb3VyY2VUeXBlID09PSBBdHRyaWJ1dGVzUmVzb3VyY2VUeXBlLkxpbmtUeXBlKSB7XG4gICAgICByZXR1cm4gKHRoaXMuZGF0YT8udW5pcXVlTGlua0luc3RhbmNlcyB8fCBbXSkuZmlsdGVyKGxpbmsgPT4gbGluay5saW5rVHlwZUlkID09PSBwaXZvdEF0dHJpYnV0ZS5yZXNvdXJjZUlkKTtcbiAgICB9XG4gICAgcmV0dXJuIFtdO1xuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0QWdncmVnYXRlZERhdGEoXG4gICAgYWdncmVnYXRlZERhdGE6IEFnZ3JlZ2F0ZWRNYXBEYXRhLFxuICAgIHZhbHVlQXR0cmlidXRlczogTG1yUGl2b3RWYWx1ZUF0dHJpYnV0ZVtdLFxuICAgIHBpdm90Q29sb3JzOiBQaXZvdENvbG9ycyxcbiAgICBhZGRpdGlvbmFsRGF0YTogUGl2b3RDb25maWdEYXRhXG4gICk6IExtclBpdm90U3RlbURhdGEge1xuICAgIGNvbnN0IHJvd0RhdGEgPSB0aGlzLmNvbnZlcnRNYXBUb1Bpdm90RGF0YUhlYWRlcihcbiAgICAgIGFnZ3JlZ2F0ZWREYXRhLm1hcCxcbiAgICAgIGFnZ3JlZ2F0ZWREYXRhLnJvd0xldmVscyxcbiAgICAgIHBpdm90Q29sb3JzLnJvd3MsXG4gICAgICBwaXZvdENvbG9ycy52YWx1ZXMsXG4gICAgICBhZGRpdGlvbmFsRGF0YS5yb3dBdHRyaWJ1dGVzXG4gICAgKTtcbiAgICBjb25zdCByb3dIZWFkZXJBdHRyaWJ1dGVzOiBMbXJQaXZvdEhlYWRlckF0dHJpYnV0ZVtdID0gKGFkZGl0aW9uYWxEYXRhLnJvd0F0dHJpYnV0ZXMgfHwgW10pXG4gICAgICAubWFwKChhdHRyaWJ1dGUsIGluZGV4KSA9PiBhZGRpdGlvbmFsRGF0YS5yb3dTaG93SGVhZGVyQXR0cmlidXRlcz8uW2luZGV4XSA/ICh7dGl0bGU6IGF0dHJpYnV0ZS5uYW1lLCBjb2xvcjogcGl2b3RDb2xvcnMucm93cz8uW2luZGV4XX0pIDogdW5kZWZpbmVkKVxuXG4gICAgY29uc3Qge3RpdGxlczogdmFsdWVUaXRsZXMsIGNvbnN0cmFpbnRzOiB2YWx1ZXNDb25zdHJhaW50c30gPSB0aGlzLmNyZWF0ZVZhbHVlVGl0bGVzKHZhbHVlQXR0cmlidXRlcyk7XG4gICAgY29uc3QgY29sdW1uRGF0YSA9IHRoaXMuY29udmVydE1hcFRvUGl2b3REYXRhSGVhZGVyKFxuICAgICAgYWdncmVnYXRlZERhdGEucm93TGV2ZWxzID4gMCA/IGFnZ3JlZ2F0ZWREYXRhLmNvbHVtbnNNYXAgOiBhZ2dyZWdhdGVkRGF0YS5tYXAsXG4gICAgICBhZ2dyZWdhdGVkRGF0YS5jb2x1bW5MZXZlbHMsXG4gICAgICBwaXZvdENvbG9ycy5jb2x1bW5zLFxuICAgICAgcGl2b3RDb2xvcnMudmFsdWVzLFxuICAgICAgYWRkaXRpb25hbERhdGEuY29sdW1uQXR0cmlidXRlcyxcbiAgICAgIHZhbHVlVGl0bGVzXG4gICAgKTtcbiAgICBjb25zdCBjb2x1bW5IZWFkZXJBdHRyaWJ1dGVzOiBMbXJQaXZvdEhlYWRlckF0dHJpYnV0ZVtdID0gKGFkZGl0aW9uYWxEYXRhLmNvbHVtbkF0dHJpYnV0ZXMgfHwgW10pXG4gICAgICAubWFwKChhdHRyaWJ1dGUsIGluZGV4KSA9PiAgYWRkaXRpb25hbERhdGEuY29sdW1uU2hvd0hlYWRlckF0dHJpYnV0ZXM/LltpbmRleF0gPyAoe3RpdGxlOiBhdHRyaWJ1dGUubmFtZSwgY29sb3I6IHBpdm90Q29sb3JzLmNvbHVtbnM/LltpbmRleF19KSA6IHVuZGVmaW5lZClcblxuICAgIGNvbnN0IHZhbHVlcyA9IHRoaXMuaW5pdE1hdHJpeDxudW1iZXI+KHJvd0RhdGEubWF4SW5kZXggKyAxLCBjb2x1bW5EYXRhLm1heEluZGV4ICsgMSk7XG4gICAgY29uc3QgZGF0YVJlc291cmNlcyA9IHRoaXMuaW5pdE1hdHJpeDxEYXRhUmVzb3VyY2VbXT4ocm93RGF0YS5tYXhJbmRleCArIDEsIGNvbHVtbkRhdGEubWF4SW5kZXggKyAxKTtcbiAgICBpZiAoKHZhbHVlQXR0cmlidXRlcyB8fCBbXSkubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5maWxsVmFsdWVzKHZhbHVlcywgZGF0YVJlc291cmNlcywgcm93RGF0YS5oZWFkZXJzLCBjb2x1bW5EYXRhLmhlYWRlcnMsIHZhbHVlQXR0cmlidXRlcywgYWdncmVnYXRlZERhdGEpO1xuICAgIH1cblxuICAgIGNvbnN0IHZhbHVlQWdncmVnYXRpb25zID0gKHZhbHVlQXR0cmlidXRlcyB8fCBbXSkubWFwKHZhbHVlQXR0cmlidXRlID0+IHZhbHVlQXR0cmlidXRlLmFnZ3JlZ2F0aW9uKTtcblxuICAgIGNvbnN0IGhhc0FkZGl0aW9uYWxDb2x1bW5MZXZlbCA9XG4gICAgICAoYWdncmVnYXRlZERhdGEuY29sdW1uTGV2ZWxzID09PSAwICYmIHZhbHVlVGl0bGVzLmxlbmd0aCA+IDApIHx8XG4gICAgICAoYWdncmVnYXRlZERhdGEuY29sdW1uTGV2ZWxzID4gMCAmJiB2YWx1ZVRpdGxlcy5sZW5ndGggPiAxKTtcbiAgICByZXR1cm4ge1xuICAgICAgcm93SGVhZGVyczogcm93RGF0YS5oZWFkZXJzLFxuICAgICAgcm93SGVhZGVyQXR0cmlidXRlcyxcbiAgICAgIGNvbHVtbkhlYWRlcnM6IGNvbHVtbkRhdGEuaGVhZGVycyxcbiAgICAgIGNvbHVtbkhlYWRlckF0dHJpYnV0ZXMsXG4gICAgICB2YWx1ZVRpdGxlcyxcbiAgICAgIHZhbHVlcyxcbiAgICAgIGRhdGFSZXNvdXJjZXMsXG4gICAgICB2YWx1ZXNDb25zdHJhaW50cyxcbiAgICAgIHZhbHVlQWdncmVnYXRpb25zLFxuXG4gICAgICAuLi5hZGRpdGlvbmFsRGF0YSxcblxuICAgICAgdmFsdWVUeXBlczogdmFsdWVBdHRyaWJ1dGVzLm1hcChhdHRyID0+IGF0dHIudmFsdWVUeXBlISksXG4gICAgICBoYXNBZGRpdGlvbmFsQ29sdW1uTGV2ZWwsXG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydE1hcFRvUGl2b3REYXRhSGVhZGVyKFxuICAgIG1hcDogUmVjb3JkPHN0cmluZywgYW55PixcbiAgICBsZXZlbHM6IG51bWJlcixcbiAgICBjb2xvcnM6IHN0cmluZ1tdLFxuICAgIHZhbHVlQ29sb3JzOiBzdHJpbmdbXSxcbiAgICBhdHRyaWJ1dGVzOiBBdHRyaWJ1dGVbXSxcbiAgICB2YWx1ZVRpdGxlcz86IHN0cmluZ1tdLFxuICAgIGFkZGl0aW9uYWxOdW06IG51bWJlciA9IDBcbiAgKToge2hlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdOyBtYXhJbmRleDogbnVtYmVyfSB7XG4gICAgY29uc3QgaGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10gPSBbXTtcbiAgICBjb25zdCBkYXRhID0ge21heEluZGV4OiAwfTtcbiAgICBpZiAobGV2ZWxzID09PSAwKSB7XG4gICAgICBpZiAoKHZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGggPiAwKSB7XG4gICAgICAgIGhlYWRlcnMucHVzaChcbiAgICAgICAgICAuLi52YWx1ZVRpdGxlcyEubWFwKCh0aXRsZSwgaW5kZXgpID0+ICh7XG4gICAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICAgIHRhcmdldEluZGV4OiBpbmRleCArIGFkZGl0aW9uYWxOdW0sXG4gICAgICAgICAgICBjb2xvcjogdmFsdWVDb2xvcnNbaW5kZXhdLFxuICAgICAgICAgICAgaXNWYWx1ZUhlYWRlcjogdHJ1ZSxcbiAgICAgICAgICB9KSlcbiAgICAgICAgKTtcbiAgICAgICAgZGF0YS5tYXhJbmRleCA9IHZhbHVlVGl0bGVzIS5sZW5ndGggLSAxICsgYWRkaXRpb25hbE51bTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IGN1cnJlbnRJbmRleCA9IGFkZGl0aW9uYWxOdW07XG4gICAgICBPYmplY3Qua2V5cyhtYXApLmZvckVhY2goKHRpdGxlLCBpbmRleCkgPT4ge1xuICAgICAgICBjb25zdCBhdHRyaWJ1dGUgPSBhdHRyaWJ1dGVzICYmIGF0dHJpYnV0ZXNbMF07XG4gICAgICAgIGlmIChsZXZlbHMgPT09IDEgJiYgKHZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGggPD0gMSkge1xuICAgICAgICAgIGhlYWRlcnMucHVzaCh7XG4gICAgICAgICAgICB0aXRsZSxcbiAgICAgICAgICAgIHRhcmdldEluZGV4OiBjdXJyZW50SW5kZXgsXG4gICAgICAgICAgICBjb2xvcjogY29sb3JzWzBdLFxuICAgICAgICAgICAgY29uc3RyYWludDogYXR0cmlidXRlPy5jb25zdHJhaW50IHx8IG5ldyBVbmtub3duQ29uc3RyYWludCgpLFxuICAgICAgICAgICAgaXNWYWx1ZUhlYWRlcjogZmFsc2UsXG4gICAgICAgICAgICBhdHRyaWJ1dGVOYW1lOiBhdHRyaWJ1dGU/Lm5hbWUsXG4gICAgICAgICAgfSk7XG4gICAgICAgICAgZGF0YS5tYXhJbmRleCA9IE1hdGgubWF4KGRhdGEubWF4SW5kZXgsIGN1cnJlbnRJbmRleCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgaGVhZGVycy5wdXNoKHtcbiAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgY29sb3I6IGNvbG9yc1swXSxcbiAgICAgICAgICAgIGNvbnN0cmFpbnQ6IGF0dHJpYnV0ZT8uY29uc3RyYWludCB8fCBuZXcgVW5rbm93bkNvbnN0cmFpbnQoKSxcbiAgICAgICAgICAgIGlzVmFsdWVIZWFkZXI6IGZhbHNlLFxuICAgICAgICAgICAgYXR0cmlidXRlTmFtZTogYXR0cmlidXRlPy5uYW1lLFxuICAgICAgICAgIH0pO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5pdGVyYXRlVGhyb3VnaFBpdm90RGF0YUhlYWRlcihcbiAgICAgICAgICBtYXBbdGl0bGVdLFxuICAgICAgICAgIGhlYWRlcnNbaW5kZXhdLFxuICAgICAgICAgIGN1cnJlbnRJbmRleCxcbiAgICAgICAgICAxLFxuICAgICAgICAgIGxldmVscyxcbiAgICAgICAgICBjb2xvcnMsXG4gICAgICAgICAgdmFsdWVDb2xvcnMsXG4gICAgICAgICAgdmFsdWVUaXRsZXMgfHwgW10sXG4gICAgICAgICAgYXR0cmlidXRlcyxcbiAgICAgICAgICBkYXRhXG4gICAgICAgICk7XG4gICAgICAgIGN1cnJlbnRJbmRleCArPSB0aGlzLm51bUNoaWxkcmVuKG1hcFt0aXRsZV0sIGxldmVscyAtIDEsICh2YWx1ZVRpdGxlcyAmJiB2YWx1ZVRpdGxlcy5sZW5ndGgpIHx8IDEpO1xuICAgICAgfSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHtoZWFkZXJzLCBtYXhJbmRleDogZGF0YS5tYXhJbmRleH07XG4gIH1cblxuICBwcml2YXRlIGl0ZXJhdGVUaHJvdWdoUGl2b3REYXRhSGVhZGVyKFxuICAgIGN1cnJlbnRNYXA6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgaGVhZGVyOiBMbXJQaXZvdERhdGFIZWFkZXIsXG4gICAgaGVhZGVySW5kZXg6IG51bWJlcixcbiAgICBsZXZlbDogbnVtYmVyLFxuICAgIG1heExldmVsczogbnVtYmVyLFxuICAgIGNvbG9yczogc3RyaW5nW10sXG4gICAgdmFsdWVDb2xvcnM6IHN0cmluZ1tdLFxuICAgIHZhbHVlVGl0bGVzOiBzdHJpbmdbXSxcbiAgICBhdHRyaWJ1dGVzOiBBdHRyaWJ1dGVbXSxcbiAgICBhZGRpdGlvbmFsRGF0YToge21heEluZGV4OiBudW1iZXJ9XG4gICkge1xuICAgIGlmIChsZXZlbCA9PT0gbWF4TGV2ZWxzKSB7XG4gICAgICBpZiAoKHZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGggPiAxKSB7XG4gICAgICAgIGhlYWRlci5jaGlsZHJlbiA9IHZhbHVlVGl0bGVzLm1hcCgodGl0bGUsIGluZGV4KSA9PiAoe1xuICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgIHRhcmdldEluZGV4OiBoZWFkZXJJbmRleCArIGluZGV4LFxuICAgICAgICAgIGNvbG9yOiB2YWx1ZUNvbG9yc1tpbmRleF0sXG4gICAgICAgICAgaXNWYWx1ZUhlYWRlcjogdHJ1ZSxcbiAgICAgICAgfSkpO1xuICAgICAgICBhZGRpdGlvbmFsRGF0YS5tYXhJbmRleCA9IE1hdGgubWF4KGFkZGl0aW9uYWxEYXRhLm1heEluZGV4LCBoZWFkZXJJbmRleCArIHZhbHVlVGl0bGVzLmxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGhlYWRlci5jaGlsZHJlbiA9IFtdO1xuICAgIGxldCBjdXJyZW50SW5kZXggPSBoZWFkZXJJbmRleDtcbiAgICBPYmplY3Qua2V5cyhjdXJyZW50TWFwKS5mb3JFYWNoKCh0aXRsZSwgaW5kZXgpID0+IHtcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZSA9IGF0dHJpYnV0ZXMgJiYgYXR0cmlidXRlc1tsZXZlbF07XG4gICAgICBpZiAobGV2ZWwgKyAxID09PSBtYXhMZXZlbHMgJiYgKHZhbHVlVGl0bGVzIHx8IFtdKS5sZW5ndGggPD0gMSkge1xuICAgICAgICBoZWFkZXIuY2hpbGRyZW4hLnB1c2goe1xuICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgIHRhcmdldEluZGV4OiBjdXJyZW50SW5kZXgsXG4gICAgICAgICAgY29sb3I6IGNvbG9yc1tsZXZlbF0sXG4gICAgICAgICAgY29uc3RyYWludDogYXR0cmlidXRlPy5jb25zdHJhaW50IHx8IG5ldyBVbmtub3duQ29uc3RyYWludCgpLFxuICAgICAgICAgIGlzVmFsdWVIZWFkZXI6IGZhbHNlLFxuICAgICAgICAgIGF0dHJpYnV0ZU5hbWU6IGF0dHJpYnV0ZT8ubmFtZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGFkZGl0aW9uYWxEYXRhLm1heEluZGV4ID0gTWF0aC5tYXgoYWRkaXRpb25hbERhdGEubWF4SW5kZXgsIGN1cnJlbnRJbmRleCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoZWFkZXIuY2hpbGRyZW4hLnB1c2goe1xuICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgIGNvbG9yOiBjb2xvcnNbbGV2ZWxdLFxuICAgICAgICAgIGNvbnN0cmFpbnQ6IGF0dHJpYnV0ZT8uY29uc3RyYWludCB8fCBuZXcgVW5rbm93bkNvbnN0cmFpbnQoKSxcbiAgICAgICAgICBpc1ZhbHVlSGVhZGVyOiBmYWxzZSxcbiAgICAgICAgICBhdHRyaWJ1dGVOYW1lOiBhdHRyaWJ1dGU/Lm5hbWUsXG4gICAgICAgIH0pO1xuICAgICAgfVxuXG4gICAgICB0aGlzLml0ZXJhdGVUaHJvdWdoUGl2b3REYXRhSGVhZGVyKFxuICAgICAgICBjdXJyZW50TWFwW3RpdGxlXSxcbiAgICAgICAgaGVhZGVyLmNoaWxkcmVuPy5baW5kZXhdLFxuICAgICAgICBjdXJyZW50SW5kZXgsXG4gICAgICAgIGxldmVsICsgMSxcbiAgICAgICAgbWF4TGV2ZWxzLFxuICAgICAgICBjb2xvcnMsXG4gICAgICAgIHZhbHVlQ29sb3JzLFxuICAgICAgICB2YWx1ZVRpdGxlcyxcbiAgICAgICAgYXR0cmlidXRlcyxcbiAgICAgICAgYWRkaXRpb25hbERhdGFcbiAgICAgICk7XG5cbiAgICAgIGN1cnJlbnRJbmRleCArPSB0aGlzLm51bUNoaWxkcmVuKFxuICAgICAgICBjdXJyZW50TWFwW3RpdGxlXSxcbiAgICAgICAgbWF4TGV2ZWxzIC0gKGxldmVsICsgMSksXG4gICAgICAgICh2YWx1ZVRpdGxlcyAmJiB2YWx1ZVRpdGxlcy5sZW5ndGgpIHx8IDFcbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIG51bUNoaWxkcmVuKG1hcDogUmVjb3JkPHN0cmluZywgYW55PiwgbWF4TGV2ZWxzOiBudW1iZXIsIG51bVRpdGxlczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAobWF4TGV2ZWxzID09PSAwKSB7XG4gICAgICByZXR1cm4gbnVtVGl0bGVzO1xuICAgIH1cblxuICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhtYXAgfHwge30pO1xuICAgIGlmIChtYXhMZXZlbHMgPT09IDEpIHtcbiAgICAgIHJldHVybiBrZXlzLmxlbmd0aCAqIG51bVRpdGxlcztcbiAgICB9XG5cbiAgICBjb25zdCBjb3VudCA9IGtleXMucmVkdWNlKChzdW0sIGtleSkgPT4gc3VtICsgdGhpcy5udW1DaGlsZHJlblJlY3Vyc2l2ZShtYXBba2V5XSwgMSwgbWF4TGV2ZWxzKSwgMCk7XG4gICAgcmV0dXJuIGNvdW50ICogbnVtVGl0bGVzO1xuICB9XG5cbiAgcHJpdmF0ZSBudW1DaGlsZHJlblJlY3Vyc2l2ZShtYXA6IFJlY29yZDxzdHJpbmcsIGFueT4sIGxldmVsOiBudW1iZXIsIG1heExldmVsczogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBpZiAobGV2ZWwgPj0gbWF4TGV2ZWxzKSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG5cbiAgICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMobWFwIHx8IHt9KTtcbiAgICBpZiAobGV2ZWwgKyAxID09PSBtYXhMZXZlbHMpIHtcbiAgICAgIHJldHVybiBrZXlzLmxlbmd0aDtcbiAgICB9XG5cbiAgICByZXR1cm4ga2V5cy5yZWR1Y2UoKHN1bSwga2V5KSA9PiBzdW0gKyB0aGlzLm51bUNoaWxkcmVuUmVjdXJzaXZlKG1hcFtrZXldLCBsZXZlbCArIDEsIG1heExldmVscyksIDApO1xuICB9XG5cbiAgcHJpdmF0ZSBjcmVhdGVWYWx1ZVRpdGxlcyh2YWx1ZUF0dHJpYnV0ZXM6IExtclBpdm90VmFsdWVBdHRyaWJ1dGVbXSk6IHt0aXRsZXM6IHN0cmluZ1tdOyBjb25zdHJhaW50czogQ29uc3RyYWludFtdfSB7XG4gICAgcmV0dXJuICh2YWx1ZUF0dHJpYnV0ZXMgfHwgW10pLnJlZHVjZTx7dGl0bGVzOiBzdHJpbmdbXTsgY29uc3RyYWludHM6IENvbnN0cmFpbnRbXX0+KFxuICAgICAgKHt0aXRsZXMsIGNvbnN0cmFpbnRzfSwgcGl2b3RBdHRyaWJ1dGUpID0+IHtcbiAgICAgICAgY29uc3QgYXR0cmlidXRlID0gdGhpcy5maW5kQXR0cmlidXRlQnlQaXZvdEF0dHJpYnV0ZShwaXZvdEF0dHJpYnV0ZSk7XG4gICAgICAgIGNvbnN0cmFpbnRzLnB1c2goXG4gICAgICAgICAgZGF0YUFnZ3JlZ2F0aW9uQ29uc3RyYWludChwaXZvdEF0dHJpYnV0ZS5hZ2dyZWdhdGlvbikgfHwgdGhpcy5waXZvdEF0dHJpYnV0ZUNvbnN0cmFpbnQocGl2b3RBdHRyaWJ1dGUpXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgdGl0bGUgPSB0aGlzLmNyZWF0ZVZhbHVlVGl0bGUocGl2b3RBdHRyaWJ1dGUuYWdncmVnYXRpb24sIGF0dHJpYnV0ZT8ubmFtZSB8fCAnJyk7XG4gICAgICAgIHRpdGxlcy5wdXNoKHRpdGxlKTtcblxuICAgICAgICByZXR1cm4ge3RpdGxlcywgY29uc3RyYWludHN9O1xuICAgICAgfSxcbiAgICAgIHt0aXRsZXM6IFtdLCBjb25zdHJhaW50czogW119XG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBjcmVhdGVWYWx1ZVRpdGxlKGFnZ3JlZ2F0aW9uOiBEYXRhQWdncmVnYXRpb25UeXBlLCBhdHRyaWJ1dGVOYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IHZhbHVlQWdncmVnYXRpb25UaXRsZSA9IHRoaXMudHJhbnNmb3JtPy5mb3JtYXRBZ2dyZWdhdGlvbj8uKGFnZ3JlZ2F0aW9uKSB8fCBhZ2dyZWdhdGlvbi50b1N0cmluZygpO1xuICAgIHJldHVybiBgJHt2YWx1ZUFnZ3JlZ2F0aW9uVGl0bGV9ICR7YXR0cmlidXRlTmFtZSB8fCAnJ31gLnRyaW0oKTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdE1hdHJpeDxUPihyb3dzOiBudW1iZXIsIGNvbHVtbnM6IG51bWJlcik6IFRbXVtdIHtcbiAgICBjb25zdCBtYXRyaXg6IFRbXVtdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCByb3dzOyBpKyspIHtcbiAgICAgIG1hdHJpeFtpXSA9IFtdO1xuICAgICAgZm9yIChsZXQgaiA9IDA7IGogPCBjb2x1bW5zOyBqKyspIHtcbiAgICAgICAgbWF0cml4W2ldW2pdID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBtYXRyaXg7XG4gIH1cblxuICBwcml2YXRlIGZpbGxWYWx1ZXMoXG4gICAgdmFsdWVzOiBudW1iZXJbXVtdLFxuICAgIGRhdGFSZXNvdXJjZXM6IERhdGFSZXNvdXJjZVtdW11bXSxcbiAgICByb3dIZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgICBjb2x1bW5IZWFkZXJzOiBMbXJQaXZvdERhdGFIZWFkZXJbXSxcbiAgICB2YWx1ZUF0dHJpYnV0ZXM6IExtclBpdm90VmFsdWVBdHRyaWJ1dGVbXSxcbiAgICBhZ2dyZWdhdGVkRGF0YTogQWdncmVnYXRlZE1hcERhdGFcbiAgKSB7XG4gICAgaWYgKHJvd0hlYWRlcnMubGVuZ3RoID4gMCkge1xuICAgICAgdGhpcy5pdGVyYXRlVGhyb3VnaFJvd0hlYWRlcnMoXG4gICAgICAgIHZhbHVlcyxcbiAgICAgICAgZGF0YVJlc291cmNlcyxcbiAgICAgICAgcm93SGVhZGVycyxcbiAgICAgICAgY29sdW1uSGVhZGVycyxcbiAgICAgICAgdmFsdWVBdHRyaWJ1dGVzLFxuICAgICAgICBhZ2dyZWdhdGVkRGF0YS5tYXBcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuaXRlcmF0ZVRocm91Z2hDb2x1bW5IZWFkZXJzKHZhbHVlcywgZGF0YVJlc291cmNlcywgY29sdW1uSGVhZGVycywgMCwgdmFsdWVBdHRyaWJ1dGVzLCBhZ2dyZWdhdGVkRGF0YS5tYXApO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgaXRlcmF0ZVRocm91Z2hSb3dIZWFkZXJzKFxuICAgIHZhbHVlczogbnVtYmVyW11bXSxcbiAgICBkYXRhUmVzb3VyY2VzOiBEYXRhUmVzb3VyY2VbXVtdW10sXG4gICAgcm93SGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gICAgY29sdW1uSGVhZGVyczogTG1yUGl2b3REYXRhSGVhZGVyW10sXG4gICAgdmFsdWVBdHRyaWJ1dGVzOiBMbXJQaXZvdFZhbHVlQXR0cmlidXRlW10sXG4gICAgY3VycmVudE1hcDogQWdncmVnYXRlZERhdGFNYXBcbiAgKSB7XG4gICAgZm9yIChjb25zdCByb3dIZWFkZXIgb2Ygcm93SGVhZGVycykge1xuICAgICAgY29uc3Qgcm93SGVhZGVyTWFwID0gY3VycmVudE1hcFtyb3dIZWFkZXIudGl0bGVdIHx8IHt9O1xuXG4gICAgICBpZiAocm93SGVhZGVyLmNoaWxkcmVuKSB7XG4gICAgICAgIHRoaXMuaXRlcmF0ZVRocm91Z2hSb3dIZWFkZXJzKFxuICAgICAgICAgIHZhbHVlcyxcbiAgICAgICAgICBkYXRhUmVzb3VyY2VzLFxuICAgICAgICAgIHJvd0hlYWRlci5jaGlsZHJlbixcbiAgICAgICAgICBjb2x1bW5IZWFkZXJzLFxuICAgICAgICAgIHZhbHVlQXR0cmlidXRlcyxcbiAgICAgICAgICByb3dIZWFkZXJNYXBcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQocm93SGVhZGVyLnRhcmdldEluZGV4KSAmJiBjb2x1bW5IZWFkZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhpcy5pdGVyYXRlVGhyb3VnaENvbHVtbkhlYWRlcnMoXG4gICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgIGRhdGFSZXNvdXJjZXMsXG4gICAgICAgICAgY29sdW1uSGVhZGVycyxcbiAgICAgICAgICByb3dIZWFkZXIudGFyZ2V0SW5kZXghLFxuICAgICAgICAgIHZhbHVlQXR0cmlidXRlcyxcbiAgICAgICAgICByb3dIZWFkZXJNYXBcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwcml2YXRlIGl0ZXJhdGVUaHJvdWdoQ29sdW1uSGVhZGVycyhcbiAgICB2YWx1ZXM6IG51bWJlcltdW10sXG4gICAgZGF0YVJlc291cmNlczogRGF0YVJlc291cmNlW11bXVtdLFxuICAgIGNvbHVtbkhlYWRlcnM6IExtclBpdm90RGF0YUhlYWRlcltdLFxuICAgIHJvd0luZGV4OiBudW1iZXIsXG4gICAgdmFsdWVBdHRyaWJ1dGVzOiBMbXJQaXZvdFZhbHVlQXR0cmlidXRlW10sXG4gICAgY3VycmVudE1hcDogQWdncmVnYXRlZERhdGFNYXAgfCBBZ2dyZWdhdGVkRGF0YVZhbHVlc1tdXG4gICkge1xuICAgIGZvciAoY29uc3QgY29sdW1uSGVhZGVyIG9mIGNvbHVtbkhlYWRlcnMpIHtcbiAgICAgIGlmIChjb2x1bW5IZWFkZXIuY2hpbGRyZW4pIHtcbiAgICAgICAgdGhpcy5pdGVyYXRlVGhyb3VnaENvbHVtbkhlYWRlcnMoXG4gICAgICAgICAgdmFsdWVzLFxuICAgICAgICAgIGRhdGFSZXNvdXJjZXMsXG4gICAgICAgICAgY29sdW1uSGVhZGVyLmNoaWxkcmVuLFxuICAgICAgICAgIHJvd0luZGV4LFxuICAgICAgICAgIHZhbHVlQXR0cmlidXRlcyxcbiAgICAgICAgICBjdXJyZW50TWFwW2NvbHVtbkhlYWRlci50aXRsZV0gfHwge31cbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNOb3ROdWxsT3JVbmRlZmluZWQoY29sdW1uSGVhZGVyLnRhcmdldEluZGV4KSkge1xuICAgICAgICBjb25zdCBhZ2dyZWdhdGVkRGF0YVZhbHVlcyA9IGlzQXJyYXkoY3VycmVudE1hcCkgPyBjdXJyZW50TWFwIDogY3VycmVudE1hcFtjb2x1bW5IZWFkZXIudGl0bGVdO1xuXG4gICAgICAgIGlmICh2YWx1ZUF0dHJpYnV0ZXMubGVuZ3RoKSB7XG4gICAgICAgICAgY29uc3QgdmFsdWVJbmRleCA9IGNvbHVtbkhlYWRlci50YXJnZXRJbmRleCEgJSB2YWx1ZUF0dHJpYnV0ZXMubGVuZ3RoO1xuICAgICAgICAgIGNvbnN0IHt2YWx1ZSwgZGF0YVJlc291cmNlczogYWdncmVnYXRlZERhdGFSZXNvdXJjZXN9ID0gdGhpcy5hZ2dyZWdhdGVWYWx1ZShcbiAgICAgICAgICAgIHZhbHVlQXR0cmlidXRlc1t2YWx1ZUluZGV4XSxcbiAgICAgICAgICAgIGFnZ3JlZ2F0ZWREYXRhVmFsdWVzXG4gICAgICAgICAgKTtcbiAgICAgICAgICB2YWx1ZXNbcm93SW5kZXhdW2NvbHVtbkhlYWRlci50YXJnZXRJbmRleCFdID0gdmFsdWU7XG4gICAgICAgICAgZGF0YVJlc291cmNlc1tyb3dJbmRleF1bY29sdW1uSGVhZGVyLnRhcmdldEluZGV4IV0gPSBhZ2dyZWdhdGVkRGF0YVJlc291cmNlcyB8fCBbXTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgYWdncmVnYXRlVmFsdWUoXG4gICAgdmFsdWVBdHRyaWJ1dGU6IExtclBpdm90VmFsdWVBdHRyaWJ1dGUsXG4gICAgYWdncmVnYXRlZERhdGFWYWx1ZXM6IEFnZ3JlZ2F0ZWREYXRhVmFsdWVzW11cbiAgKToge3ZhbHVlPzogYW55OyBkYXRhUmVzb3VyY2VzPzogRGF0YVJlc291cmNlW119IHtcbiAgICBjb25zdCByZXNvdXJjZUFnZ3JlZ2F0ZWREYXRhVmFsdWVzID0gKGFnZ3JlZ2F0ZWREYXRhVmFsdWVzIHx8IFtdKS5maWx0ZXIoXG4gICAgICBhZ2cgPT4gYWdnLnJlc291cmNlSWQgPT09IHZhbHVlQXR0cmlidXRlLnJlc291cmNlSWQgJiYgYWdnLnR5cGUgPT09IHZhbHVlQXR0cmlidXRlLnJlc291cmNlVHlwZVxuICAgICk7XG4gICAgaWYgKHJlc291cmNlQWdncmVnYXRlZERhdGFWYWx1ZXMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBkYXRhUmVzb3VyY2VzID0gZmxhdHRlbk1hdHJpeChyZXNvdXJjZUFnZ3JlZ2F0ZWREYXRhVmFsdWVzLm1hcCh2YWwgPT4gdmFsLm9iamVjdHMpKTtcbiAgICAgIGNvbnN0IGF0dHJpYnV0ZSA9IHRoaXMucGl2b3RBdHRyaWJ1dGVBdHRyaWJ1dGUodmFsdWVBdHRyaWJ1dGUpO1xuICAgICAgaWYgKHZhbHVlQXR0cmlidXRlLmFnZ3JlZ2F0aW9uID09PSBEYXRhQWdncmVnYXRpb25UeXBlLkpvaW4pIHtcbiAgICAgICAgLy8gdmFsdWVzIHdpbGwgYmUgam9pbmVkIGluIHBpdm90LXRhYmxlLWNvbnZlcnRlclxuICAgICAgICBjb25zdCB2YWx1ZXMgPSAoZGF0YVJlc291cmNlcyB8fCBbXSkubWFwKChyZXNvdXJjZTogRGF0YVJlc291cmNlKSA9PiByZXNvdXJjZS5kYXRhPy5bYXR0cmlidXRlPy5pZCB8fCAnJ10pO1xuICAgICAgICByZXR1cm4ge3ZhbHVlOiB1bmlxdWVWYWx1ZXMoZmxhdHRlblZhbHVlcyh2YWx1ZXMpKSwgZGF0YVJlc291cmNlc307XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gYXR0cmlidXRlICYmIGFnZ3JlZ2F0ZURhdGFSZXNvdXJjZXModmFsdWVBdHRyaWJ1dGUuYWdncmVnYXRpb24sIGRhdGFSZXNvdXJjZXMsIGF0dHJpYnV0ZSwgdHJ1ZSk7XG4gICAgICByZXR1cm4ge3ZhbHVlLCBkYXRhUmVzb3VyY2VzfTtcbiAgICB9XG5cbiAgICByZXR1cm4ge307XG4gIH1cblxuICBwcml2YXRlIGZpbmRBdHRyaWJ1dGVCeVBpdm90QXR0cmlidXRlKHZhbHVlQXR0cmlidXRlOiBMbXJQaXZvdEF0dHJpYnV0ZSk6IEF0dHJpYnV0ZSB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHZhbHVlQXR0cmlidXRlLnJlc291cmNlVHlwZSA9PT0gQXR0cmlidXRlc1Jlc291cmNlVHlwZS5Db2xsZWN0aW9uKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb2xsZWN0aW9uc0F0dHJpYnV0ZXNNYXA/Llt2YWx1ZUF0dHJpYnV0ZS5yZXNvdXJjZUlkXT8uW3ZhbHVlQXR0cmlidXRlLmF0dHJpYnV0ZUlkXTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlQXR0cmlidXRlLnJlc291cmNlVHlwZSA9PT0gQXR0cmlidXRlc1Jlc291cmNlVHlwZS5MaW5rVHlwZSkge1xuICAgICAgcmV0dXJuIHRoaXMubGlua1R5cGVzQXR0cmlidXRlc01hcD8uW3ZhbHVlQXR0cmlidXRlLnJlc291cmNlSWRdPy5bdmFsdWVBdHRyaWJ1dGUuYXR0cmlidXRlSWRdO1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkXG4gIH1cbn1cblxuZnVuY3Rpb24gZ2V0UGl2b3RTdGVtQ29uZmlnVHlwZShzdGVtQ29uZmlnOiBMbXJQaXZvdFN0ZW1Db25maWcpOiBQaXZvdENvbmZpZ1R5cGUge1xuICBjb25zdCByb3dMZW5ndGggPSAoc3RlbUNvbmZpZy5yb3dBdHRyaWJ1dGVzIHx8IFtdKS5sZW5ndGg7XG4gIGNvbnN0IGNvbHVtbkxlbmd0aCA9IChzdGVtQ29uZmlnLmNvbHVtbkF0dHJpYnV0ZXMgfHwgW10pLmxlbmd0aDtcblxuICBpZiAocm93TGVuZ3RoID4gMCAmJiBjb2x1bW5MZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIFBpdm90Q29uZmlnVHlwZS5Sb3dzQW5kQ29sdW1ucztcbiAgfSBlbHNlIGlmIChyb3dMZW5ndGggPiAwKSB7XG4gICAgcmV0dXJuIFBpdm90Q29uZmlnVHlwZS5Sb3dzO1xuICB9IGVsc2UgaWYgKGNvbHVtbkxlbmd0aCA+IDApIHtcbiAgICByZXR1cm4gUGl2b3RDb25maWdUeXBlLkNvbHVtbnM7XG4gIH1cbiAgcmV0dXJuIFBpdm90Q29uZmlnVHlwZS5WYWx1ZXM7XG59XG5cbmZ1bmN0aW9uIGNhbk1lcmdlQ29uZmlnc0J5VHlwZSh0eXBlOiBQaXZvdENvbmZpZ1R5cGUsIGMxOiBMbXJQaXZvdFN0ZW1Db25maWcsIGMyOiBMbXJQaXZvdFN0ZW1Db25maWcpOiBib29sZWFuIHtcbiAgaWYgKHR5cGUgPT09IFBpdm90Q29uZmlnVHlwZS5Sb3dzKSB7XG4gICAgcmV0dXJuIChjMS5yb3dBdHRyaWJ1dGVzIHx8IFtdKS5sZW5ndGggPT09IChjMi5yb3dBdHRyaWJ1dGVzIHx8IFtdKS5sZW5ndGg7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gUGl2b3RDb25maWdUeXBlLkNvbHVtbnMpIHtcbiAgICByZXR1cm4gKGMxLmNvbHVtbkF0dHJpYnV0ZXMgfHwgW10pLmxlbmd0aCA9PT0gKGMyLmNvbHVtbkF0dHJpYnV0ZXMgfHwgW10pLmxlbmd0aDtcbiAgfVxuICByZXR1cm4gKFxuICAgIChjMS5yb3dBdHRyaWJ1dGVzIHx8IFtdKS5sZW5ndGggPT09IChjMi5yb3dBdHRyaWJ1dGVzIHx8IFtdKS5sZW5ndGggJiZcbiAgICAoYzEuY29sdW1uQXR0cmlidXRlcyB8fCBbXSkubGVuZ3RoID09PSAoYzIuY29sdW1uQXR0cmlidXRlcyB8fCBbXSkubGVuZ3RoXG4gICk7XG59XG4iXX0=