basesite-shared-grid-lib 0.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +24 -0
- package/basesite-shared-grid-lib-0.0.1.tgz +0 -0
- package/esm2020/basesite-shared-grid-lib.mjs +5 -0
- package/esm2020/lib/grid-library.component.mjs +301 -0
- package/esm2020/lib/grid-library.module.mjs +42 -0
- package/esm2020/lib/grid-library.service.mjs +42 -0
- package/esm2020/lib/helpers/index.mjs +3 -0
- package/esm2020/lib/helpers/oDataProvider.mjs +769 -0
- package/esm2020/lib/helpers/types.mjs +2 -0
- package/esm2020/lib/helpers/utils.mjs +7 -0
- package/esm2020/lib/renderer/button-renderer/button-renderer.component.mjs +49 -0
- package/esm2020/lib/renderer/tooltip-renderer/custom-tooltip-renderer.mjs +36 -0
- package/esm2020/public-api.mjs +7 -0
- package/fesm2015/basesite-shared-grid-lib.mjs +1245 -0
- package/fesm2015/basesite-shared-grid-lib.mjs.map +1 -0
- package/fesm2020/basesite-shared-grid-lib.mjs +1241 -0
- package/fesm2020/basesite-shared-grid-lib.mjs.map +1 -0
- package/index.d.ts +5 -0
- package/lib/grid-library.component.d.ts +43 -0
- package/lib/grid-library.module.d.ts +13 -0
- package/lib/grid-library.service.d.ts +12 -0
- package/lib/helpers/index.d.ts +2 -0
- package/lib/helpers/oDataProvider.d.ts +338 -0
- package/lib/helpers/types.d.ts +20 -0
- package/lib/helpers/utils.d.ts +2 -0
- package/lib/renderer/button-renderer/button-renderer.component.d.ts +12 -0
- package/lib/renderer/tooltip-renderer/custom-tooltip-renderer.d.ts +16 -0
- package/package.json +39 -0
- package/public-api.d.ts +3 -0
- package/src/lib/styles/styles.scss +84 -0
|
@@ -0,0 +1,769 @@
|
|
|
1
|
+
import { replaceAll } from './utils';
|
|
2
|
+
export class OdataProvider {
|
|
3
|
+
constructor(options) {
|
|
4
|
+
/**
|
|
5
|
+
* Name of field contain count of record results in grouping odata query
|
|
6
|
+
* @default childCount
|
|
7
|
+
*/
|
|
8
|
+
this.groupCountFieldName = 'childCount';
|
|
9
|
+
/**
|
|
10
|
+
* Use in odata build query
|
|
11
|
+
* @default false
|
|
12
|
+
*/
|
|
13
|
+
this.isCaseSensitiveStringFilter = false;
|
|
14
|
+
/**Creator a cancelable Promise */
|
|
15
|
+
this.createCancelablePromise = () => {
|
|
16
|
+
let cancel;
|
|
17
|
+
const pr = new Promise((_, reject) => {
|
|
18
|
+
cancel = reject;
|
|
19
|
+
}).catch(() => { });
|
|
20
|
+
return {
|
|
21
|
+
promise: pr,
|
|
22
|
+
cancel,
|
|
23
|
+
};
|
|
24
|
+
};
|
|
25
|
+
/**Odata query operations */
|
|
26
|
+
this.odataOperator = {
|
|
27
|
+
// Logical
|
|
28
|
+
equals: (col, value1) => `${col} eq ${value1}`,
|
|
29
|
+
notEqual: (col, value1) => `${col} ne ${value1}`,
|
|
30
|
+
lessThan: (col, value1) => `${col} lt ${value1}`,
|
|
31
|
+
lessThanOrEqual: (col, value1) => `${col} le ${value1}`,
|
|
32
|
+
greaterThan: (col, value1) => `${col} gt ${value1}`,
|
|
33
|
+
greaterThanOrEqual: (col, value1) => `${col} ge ${value1}`,
|
|
34
|
+
inRange: (col, value1, value2) => `(${col} ge ${value1} and ${col} le ${value2})`,
|
|
35
|
+
// String
|
|
36
|
+
equalsStr: (col, value1, isCaseSensitiveStringFilter) => `${this.ifTolowerCol(col, isCaseSensitiveStringFilter)} eq ${this.ifTolower(value1, isCaseSensitiveStringFilter)}`,
|
|
37
|
+
notEqualStr: (col, value1, isCaseSensitiveStringFilter) => `${this.ifTolowerCol(col, isCaseSensitiveStringFilter)} ne ${this.ifTolower(value1, isCaseSensitiveStringFilter)}`,
|
|
38
|
+
contains: (col, value1, isCaseSensitiveStringFilter) => `contains(${this.ifTolowerCol(col, isCaseSensitiveStringFilter)},${this.ifTolower(value1, isCaseSensitiveStringFilter)})`,
|
|
39
|
+
notContains: (col, value1, isCaseSensitiveStringFilter) => `contains(${this.ifTolowerCol(col, isCaseSensitiveStringFilter)},${this.ifTolower(value1, isCaseSensitiveStringFilter)}) eq false`,
|
|
40
|
+
startsWith: (col, value1, isCaseSensitiveStringFilter) => `startswith(${this.ifTolowerCol(col, isCaseSensitiveStringFilter)},${this.ifTolower(value1, isCaseSensitiveStringFilter)}) eq true`,
|
|
41
|
+
endsWith: (col, value1, isCaseSensitiveStringFilter) => `endswith(${this.ifTolowerCol(col, isCaseSensitiveStringFilter)},${this.ifTolower(value1, isCaseSensitiveStringFilter)}) eq true`,
|
|
42
|
+
inStr: (col, values, isCaseSensitiveStringFilter) => `${this.ifTolowerCol(col, isCaseSensitiveStringFilter)} in (${values
|
|
43
|
+
.map((x) => `'${this.ifTolower(this.encode(x), isCaseSensitiveStringFilter)}'`)
|
|
44
|
+
.join()})`,
|
|
45
|
+
in: (col, values) => `${col} in (${values.map((x) => `${this.encode(x)}`).join()})`,
|
|
46
|
+
notIn: (col, values) => `not (${col} in (${values.map((x) => `${x}`).join()}))`,
|
|
47
|
+
// Date
|
|
48
|
+
trunc: (col) => `date(${col})`,
|
|
49
|
+
};
|
|
50
|
+
/**
|
|
51
|
+
* Apply tolower for column in odata syntax
|
|
52
|
+
* @param col column name
|
|
53
|
+
* @param isCaseSensitiveStringFilter need apply tolower
|
|
54
|
+
*/
|
|
55
|
+
this.ifTolowerCol = (col, isCaseSensitiveStringFilter) => isCaseSensitiveStringFilter ? col : `tolower(${col})`;
|
|
56
|
+
/**
|
|
57
|
+
*
|
|
58
|
+
* @param value string value
|
|
59
|
+
* @param isCaseSensitiveStringFilter need apply tolower
|
|
60
|
+
*/
|
|
61
|
+
this.ifTolower = (value, isCaseSensitiveStringFilter) => isCaseSensitiveStringFilter ? value : value ? value.toLowerCase() : value;
|
|
62
|
+
/**
|
|
63
|
+
* Odata aggregation operations
|
|
64
|
+
*/
|
|
65
|
+
this.odataAggregation = {
|
|
66
|
+
// Logical
|
|
67
|
+
sum: (col, asField) => `${col} with sum as ${col || asField}`,
|
|
68
|
+
min: (col, asField) => `${col} with min as ${col || asField}`,
|
|
69
|
+
max: (col, asField) => `${col} with max as ${col || asField}`,
|
|
70
|
+
avg: (col, asField) => `${col} with average as ${col || asField}`,
|
|
71
|
+
count: (col, asField) => `$count as ${col || asField}`,
|
|
72
|
+
};
|
|
73
|
+
/**
|
|
74
|
+
* Odata query builder
|
|
75
|
+
* @param options parameter for odata query
|
|
76
|
+
*/
|
|
77
|
+
this.toQuery = (options) => {
|
|
78
|
+
let path = [];
|
|
79
|
+
if (options.count) {
|
|
80
|
+
path.push('$count=true');
|
|
81
|
+
}
|
|
82
|
+
if (options.skip) {
|
|
83
|
+
path.push(`$skip=${options.skip}`);
|
|
84
|
+
}
|
|
85
|
+
if (options.top) {
|
|
86
|
+
path.push(`$top=${options.top}`);
|
|
87
|
+
}
|
|
88
|
+
if (options.sort && options.sort.length > 0) {
|
|
89
|
+
path.push('$orderby=' + options.sort.join(','));
|
|
90
|
+
}
|
|
91
|
+
if (options.filter && options.filter.length > 0) {
|
|
92
|
+
path.push('$filter=' + options.filter.join(' and '));
|
|
93
|
+
}
|
|
94
|
+
if (options.apply && options.apply.length > 0) {
|
|
95
|
+
path.push('$apply=' + options.apply.join('/'));
|
|
96
|
+
}
|
|
97
|
+
if (options.expand && options.expand.length > 0) {
|
|
98
|
+
path.push('$expand=' + options.expand.join(','));
|
|
99
|
+
}
|
|
100
|
+
if (options.select && options.select.length > 0) {
|
|
101
|
+
path.push('$select=' + options.select.join(','));
|
|
102
|
+
}
|
|
103
|
+
let query = '';
|
|
104
|
+
if (path.length > 0) {
|
|
105
|
+
query = '?' + path.join('&');
|
|
106
|
+
}
|
|
107
|
+
return query;
|
|
108
|
+
};
|
|
109
|
+
/**
|
|
110
|
+
* Add quotes for string value
|
|
111
|
+
* @param value string value
|
|
112
|
+
*/
|
|
113
|
+
this.encode = (value) => this.isStrVal(value) ? replaceAll(value, "'", "''") : value;
|
|
114
|
+
/**
|
|
115
|
+
* Conctat to date a time for create datetime format for odata query
|
|
116
|
+
* @param value date string
|
|
117
|
+
*/
|
|
118
|
+
this.toDateTime = (value) => {
|
|
119
|
+
const dt = new Date(value);
|
|
120
|
+
if (isNaN(dt.getTime()))
|
|
121
|
+
return null;
|
|
122
|
+
const dt1 = new Date(Date.UTC(dt.getFullYear(), dt.getMonth(), dt.getDate()));
|
|
123
|
+
return dt1.toISOString();
|
|
124
|
+
};
|
|
125
|
+
/**
|
|
126
|
+
*
|
|
127
|
+
* @param colName columnName
|
|
128
|
+
* @returns is CaseSensitive for column
|
|
129
|
+
*/
|
|
130
|
+
this.getIsNeedCaseSensitive = (colName) => {
|
|
131
|
+
if (!this.isCaseSensitiveStringFilter &&
|
|
132
|
+
this.caseSensitiveColumns &&
|
|
133
|
+
this.caseSensitiveColumns.length > 0) {
|
|
134
|
+
return this.caseSensitiveColumns.indexOf(colName) >= 0;
|
|
135
|
+
}
|
|
136
|
+
return this.isCaseSensitiveStringFilter;
|
|
137
|
+
};
|
|
138
|
+
/**
|
|
139
|
+
* Convert ag-grid column filter to odata query
|
|
140
|
+
* @param colName columnName
|
|
141
|
+
* @param col ag-grid column
|
|
142
|
+
*/
|
|
143
|
+
this.getFilterOdata = (colName, col) => {
|
|
144
|
+
const me = this;
|
|
145
|
+
const isCaseSensitiveStringFilter = me.getIsNeedCaseSensitive(colName);
|
|
146
|
+
const customFilter = me.customFilters && me.customFilters[colName];
|
|
147
|
+
colName = replaceAll(colName, '.', '/');
|
|
148
|
+
colName = me.getWrapColumnName(colName);
|
|
149
|
+
if (customFilter) {
|
|
150
|
+
return customFilter(colName, col, isCaseSensitiveStringFilter, me);
|
|
151
|
+
}
|
|
152
|
+
else {
|
|
153
|
+
switch (col.filterType) {
|
|
154
|
+
case 'number':
|
|
155
|
+
return me.odataOperator[col.type](colName, col.filter, col.filterTo);
|
|
156
|
+
case 'text': {
|
|
157
|
+
let operatorName = col.type;
|
|
158
|
+
const filter = me.encode(col.filter);
|
|
159
|
+
// let filterTo = me.encode(col.filterTo);
|
|
160
|
+
if ((operatorName === 'equals' || operatorName === 'notEqual') &&
|
|
161
|
+
!isCaseSensitiveStringFilter) {
|
|
162
|
+
operatorName += 'Str';
|
|
163
|
+
}
|
|
164
|
+
return me.odataOperator[operatorName](colName, `'${filter}'`, isCaseSensitiveStringFilter);
|
|
165
|
+
}
|
|
166
|
+
case 'date':
|
|
167
|
+
if (col.dateFrom != null &&
|
|
168
|
+
me.toDateTime(col.dateFrom) != null &&
|
|
169
|
+
(col.dateTo == null ||
|
|
170
|
+
(col.dateTo != null && me.toDateTime(col.dateTo) != null))) {
|
|
171
|
+
return me.odataOperator[col.type](colName, `${me.toDateTime(col.dateFrom)}`, `${me.toDateTime(col.dateTo)}`);
|
|
172
|
+
}
|
|
173
|
+
break;
|
|
174
|
+
case 'set':
|
|
175
|
+
return col.values.length > 0
|
|
176
|
+
? me.odataOperator.inStr(colName, col.values, isCaseSensitiveStringFilter)
|
|
177
|
+
: '';
|
|
178
|
+
default:
|
|
179
|
+
break;
|
|
180
|
+
}
|
|
181
|
+
}
|
|
182
|
+
return '';
|
|
183
|
+
};
|
|
184
|
+
/**
|
|
185
|
+
* Caclulate pivot data for ag-grid from odata
|
|
186
|
+
* @param pivotCols pivot columns
|
|
187
|
+
* @param rowGroupCols row group columns
|
|
188
|
+
* @param valueCols value columns
|
|
189
|
+
* @param data odata result
|
|
190
|
+
* @param countField count field name
|
|
191
|
+
*/
|
|
192
|
+
this.getPivot = (pivotCols, rowGroupCols, valueCols, data, countField) => {
|
|
193
|
+
// assume 1 pivot col and 1 value col for this example
|
|
194
|
+
const me = this;
|
|
195
|
+
const pivotData = [];
|
|
196
|
+
const aggColsList = [];
|
|
197
|
+
const colKeyExistsMap = {};
|
|
198
|
+
const secondaryColDefs = [];
|
|
199
|
+
const secondaryColDefsMap = {};
|
|
200
|
+
data.forEach(function (item) {
|
|
201
|
+
var pivotValues = [];
|
|
202
|
+
pivotCols.forEach(function (pivotCol) {
|
|
203
|
+
var pivotField = pivotCol.id;
|
|
204
|
+
var pivotValue = me.getValue(pivotField, item);
|
|
205
|
+
if (pivotValue !== null &&
|
|
206
|
+
pivotValue !== undefined &&
|
|
207
|
+
pivotValue.toString) {
|
|
208
|
+
pivotValues.push(pivotValue.toString());
|
|
209
|
+
}
|
|
210
|
+
else {
|
|
211
|
+
pivotValues.push('-');
|
|
212
|
+
}
|
|
213
|
+
});
|
|
214
|
+
// var pivotValue = item[pivotField].toString();
|
|
215
|
+
var pivotItem = {};
|
|
216
|
+
valueCols.forEach(function (valueCol) {
|
|
217
|
+
var valField = valueCol.id;
|
|
218
|
+
var colKey = createColKey(pivotValues, valField);
|
|
219
|
+
var value = me.getValue(valField, item);
|
|
220
|
+
pivotItem[colKey] = value;
|
|
221
|
+
if (!colKeyExistsMap[colKey]) {
|
|
222
|
+
addNewAggCol(colKey, valueCol);
|
|
223
|
+
addNewSecondaryColDef(colKey, pivotValues, valueCol);
|
|
224
|
+
colKeyExistsMap[colKey] = true;
|
|
225
|
+
}
|
|
226
|
+
});
|
|
227
|
+
if (countField) {
|
|
228
|
+
pivotItem[countField] = me.getValue(countField, item);
|
|
229
|
+
}
|
|
230
|
+
rowGroupCols.forEach(function (rowGroupCol) {
|
|
231
|
+
var rowGroupField = rowGroupCol.id.split('.')[0];
|
|
232
|
+
pivotItem[rowGroupField] = item[rowGroupField];
|
|
233
|
+
});
|
|
234
|
+
pivotData.push(pivotItem);
|
|
235
|
+
});
|
|
236
|
+
function addNewAggCol(colKey, valueCol) {
|
|
237
|
+
var newCol = {
|
|
238
|
+
id: colKey,
|
|
239
|
+
field: colKey,
|
|
240
|
+
aggFunc: valueCol.aggFunc,
|
|
241
|
+
};
|
|
242
|
+
aggColsList.push(newCol);
|
|
243
|
+
}
|
|
244
|
+
function addNewSecondaryColDef(colKey, pivotValues, valueCol) {
|
|
245
|
+
var parentGroup = null;
|
|
246
|
+
var keyParts = [];
|
|
247
|
+
pivotValues.forEach(function (pivotValue) {
|
|
248
|
+
keyParts.push(pivotValue);
|
|
249
|
+
var colKey = createColKey(keyParts);
|
|
250
|
+
var groupColDef = secondaryColDefsMap[colKey];
|
|
251
|
+
if (!groupColDef) {
|
|
252
|
+
groupColDef = {
|
|
253
|
+
groupId: colKey,
|
|
254
|
+
headerName: pivotValue,
|
|
255
|
+
children: [],
|
|
256
|
+
};
|
|
257
|
+
secondaryColDefsMap[colKey] = groupColDef;
|
|
258
|
+
if (parentGroup) {
|
|
259
|
+
parentGroup.children.push(groupColDef);
|
|
260
|
+
}
|
|
261
|
+
else {
|
|
262
|
+
secondaryColDefs.push(groupColDef);
|
|
263
|
+
}
|
|
264
|
+
}
|
|
265
|
+
parentGroup = groupColDef;
|
|
266
|
+
});
|
|
267
|
+
parentGroup.children.push({
|
|
268
|
+
colId: colKey,
|
|
269
|
+
headerName: valueCol.aggFunc + '(' + valueCol.displayName + ')',
|
|
270
|
+
field: colKey,
|
|
271
|
+
suppressMenu: true,
|
|
272
|
+
sortable: false,
|
|
273
|
+
});
|
|
274
|
+
}
|
|
275
|
+
function createColKey(pivotValues, valueField) {
|
|
276
|
+
var result = pivotValues.join('|');
|
|
277
|
+
if (valueField !== undefined) {
|
|
278
|
+
result += '|' + valueField;
|
|
279
|
+
}
|
|
280
|
+
result = replaceAll(result, '.', '*');
|
|
281
|
+
return result;
|
|
282
|
+
}
|
|
283
|
+
return {
|
|
284
|
+
data: pivotData,
|
|
285
|
+
aggCols: aggColsList,
|
|
286
|
+
secondaryColDefs: secondaryColDefs,
|
|
287
|
+
};
|
|
288
|
+
};
|
|
289
|
+
/**
|
|
290
|
+
*
|
|
291
|
+
* @param rowData array odata result
|
|
292
|
+
* @param rowGroupCols row group columns
|
|
293
|
+
* @param groupKeys what groups the user is viewing
|
|
294
|
+
* @param countField count field name
|
|
295
|
+
*/
|
|
296
|
+
this.buildGroupsFromData = (rowData, rowGroupCols, groupKeys, countField) => {
|
|
297
|
+
const me = this;
|
|
298
|
+
let rowGroupCol = rowGroupCols[groupKeys.length];
|
|
299
|
+
let field = rowGroupCol.id;
|
|
300
|
+
let mappedRowData = me.groupBy(rowData, field);
|
|
301
|
+
let groups = [];
|
|
302
|
+
me.iterateObject(mappedRowData, function (key, rowData) {
|
|
303
|
+
var groupItem = me.aggregateList(rowData, countField);
|
|
304
|
+
groupItem[field] = key;
|
|
305
|
+
groups.push(groupItem);
|
|
306
|
+
});
|
|
307
|
+
return groups;
|
|
308
|
+
};
|
|
309
|
+
/**
|
|
310
|
+
* Internal function for execute callback function for each property of object
|
|
311
|
+
* @param object object contained odata grouped result
|
|
312
|
+
* @param callback function do somthing
|
|
313
|
+
*/
|
|
314
|
+
this.iterateObject = (object, callback) => {
|
|
315
|
+
if (!object) {
|
|
316
|
+
return;
|
|
317
|
+
}
|
|
318
|
+
const keys = Object.keys(object);
|
|
319
|
+
for (let i = 0; i < keys.length; i++) {
|
|
320
|
+
const key = keys[i];
|
|
321
|
+
const value = object[key];
|
|
322
|
+
callback(key, value);
|
|
323
|
+
}
|
|
324
|
+
};
|
|
325
|
+
/**
|
|
326
|
+
* Prepeare grouped data
|
|
327
|
+
* @param rowData array odata result
|
|
328
|
+
* @param field grouping field
|
|
329
|
+
*/
|
|
330
|
+
this.groupBy = (rowData, field) => {
|
|
331
|
+
var result = {};
|
|
332
|
+
const me = this;
|
|
333
|
+
rowData.forEach(function (item) {
|
|
334
|
+
var key = me.getValue(field, item);
|
|
335
|
+
var listForThisKey = result[key];
|
|
336
|
+
if (!listForThisKey) {
|
|
337
|
+
listForThisKey = [];
|
|
338
|
+
result[key] = listForThisKey;
|
|
339
|
+
}
|
|
340
|
+
listForThisKey.push(item);
|
|
341
|
+
});
|
|
342
|
+
return result;
|
|
343
|
+
};
|
|
344
|
+
/**
|
|
345
|
+
* Calculate total count records in group
|
|
346
|
+
* @param rowData array odata result data
|
|
347
|
+
* @param countField field contained count of all records
|
|
348
|
+
*/
|
|
349
|
+
this.aggregateList = (rowData, countField) => {
|
|
350
|
+
var result = {};
|
|
351
|
+
rowData.forEach((row) => {
|
|
352
|
+
if (countField && row[countField] != null) {
|
|
353
|
+
const totalCount = (result[countField] || 0) + (row[countField] || 0);
|
|
354
|
+
delete row[countField];
|
|
355
|
+
result[countField] = totalCount;
|
|
356
|
+
}
|
|
357
|
+
result = Object.assign(result, row);
|
|
358
|
+
});
|
|
359
|
+
return result;
|
|
360
|
+
};
|
|
361
|
+
/**
|
|
362
|
+
* Calculate distinct values for input field from Odata api
|
|
363
|
+
* @param field The field of the row to get the cells data from
|
|
364
|
+
* @param callback The function for return distinct values for input field
|
|
365
|
+
* @param beforeRequest The function for customize request
|
|
366
|
+
* @example
|
|
367
|
+
* <pre><code>
|
|
368
|
+
* const setFilterValuesFuncParams = params => {
|
|
369
|
+
* const me = this
|
|
370
|
+
* const col = params.colDef.field
|
|
371
|
+
* const storeName = me.getStoreName(col)
|
|
372
|
+
* const callback = data => {
|
|
373
|
+
* if (data) {
|
|
374
|
+
* me.setState({ [storeName]: data })
|
|
375
|
+
* params.success(data)
|
|
376
|
+
* }
|
|
377
|
+
* }
|
|
378
|
+
* odataProviderInstance.getFilterValuesParams(params.colDef.field, callback)
|
|
379
|
+
* }
|
|
380
|
+
*
|
|
381
|
+
* ///....
|
|
382
|
+
* <AgGridColumn
|
|
383
|
+
field="product"
|
|
384
|
+
headerName={'PRODUCT'}
|
|
385
|
+
filter="agSetColumnFilter"
|
|
386
|
+
// rowGroup
|
|
387
|
+
// enablePivot
|
|
388
|
+
enableRowGroup
|
|
389
|
+
filterParams={{
|
|
390
|
+
values: setFilterValuesFuncParams,
|
|
391
|
+
newRowsAction: 'keep'
|
|
392
|
+
}}
|
|
393
|
+
// filterParams={{caseSensitive: true}}
|
|
394
|
+
/>
|
|
395
|
+
* </code></pre>
|
|
396
|
+
*/
|
|
397
|
+
this.getFilterValuesParams = (field, callback, beforeRequest) => {
|
|
398
|
+
const me = this;
|
|
399
|
+
const options = {
|
|
400
|
+
apply: [`groupby((${me.getWrapColumnName(field)}))`],
|
|
401
|
+
};
|
|
402
|
+
if (beforeRequest) {
|
|
403
|
+
beforeRequest(options);
|
|
404
|
+
}
|
|
405
|
+
me.callApi(me.toQuery(options)).then((x) => {
|
|
406
|
+
if (x) {
|
|
407
|
+
let values = me.getOdataResult(x);
|
|
408
|
+
callback(values.map((y) => y[field]));
|
|
409
|
+
}
|
|
410
|
+
});
|
|
411
|
+
};
|
|
412
|
+
/**
|
|
413
|
+
* Detect is string value
|
|
414
|
+
* @param value
|
|
415
|
+
*/
|
|
416
|
+
this.isStrVal = (value) => typeof value === 'string';
|
|
417
|
+
/**
|
|
418
|
+
* Extartc values from odata response
|
|
419
|
+
* @param response
|
|
420
|
+
*/
|
|
421
|
+
this.getOdataResult = (response) => Array.isArray(response) ? response : response.value;
|
|
422
|
+
/**
|
|
423
|
+
* Endocing column name to odata notation
|
|
424
|
+
* @param colName column name
|
|
425
|
+
*/
|
|
426
|
+
this.getWrapColumnName = (colName) => colName ? replaceAll(colName, '.', '/') : '';
|
|
427
|
+
/**
|
|
428
|
+
* Set result
|
|
429
|
+
* @param params ag-grid details for the request
|
|
430
|
+
* @param isServerMode detect type of params
|
|
431
|
+
* @param rowsThisBlock data of the request
|
|
432
|
+
* @param rowCount count of total result
|
|
433
|
+
*/
|
|
434
|
+
this.setResult = (params, isServerMode, rowsThisBlock, rowCount) => {
|
|
435
|
+
if (isServerMode) {
|
|
436
|
+
;
|
|
437
|
+
params.success({
|
|
438
|
+
rowData: rowsThisBlock,
|
|
439
|
+
rowCount: rowCount,
|
|
440
|
+
});
|
|
441
|
+
}
|
|
442
|
+
else {
|
|
443
|
+
;
|
|
444
|
+
params.successCallback(rowsThisBlock, rowCount);
|
|
445
|
+
}
|
|
446
|
+
};
|
|
447
|
+
/**
|
|
448
|
+
* Generate odata options for build query from ag-grid request
|
|
449
|
+
* @param params ag-grid details for the request
|
|
450
|
+
*/
|
|
451
|
+
this.getOdataOptions = (params) => {
|
|
452
|
+
const me = this;
|
|
453
|
+
const options = {};
|
|
454
|
+
const isServerMode = 'request' in params;
|
|
455
|
+
const request = isServerMode
|
|
456
|
+
? params.request
|
|
457
|
+
: params;
|
|
458
|
+
const childCount = me.groupCountFieldName;
|
|
459
|
+
if (this.beforeRequest) {
|
|
460
|
+
this.beforeRequest(options, this, request);
|
|
461
|
+
}
|
|
462
|
+
if (request.sortModel.length > 0) {
|
|
463
|
+
const sort = options.sort || [];
|
|
464
|
+
for (let i = 0; i < request.sortModel.length; i++) {
|
|
465
|
+
const col = request.sortModel[i];
|
|
466
|
+
let colName = me.getWrapColumnName(col.colId);
|
|
467
|
+
if (col.sort !== 'asc') {
|
|
468
|
+
colName += ' desc';
|
|
469
|
+
}
|
|
470
|
+
sort.push(colName);
|
|
471
|
+
}
|
|
472
|
+
options.sort = sort;
|
|
473
|
+
}
|
|
474
|
+
const filter = options.filter || [];
|
|
475
|
+
for (const colName in request.filterModel) {
|
|
476
|
+
if (request.filterModel.hasOwnProperty(colName)) {
|
|
477
|
+
const col = request.filterModel[colName];
|
|
478
|
+
let colFilter = '';
|
|
479
|
+
if (!col.operator) {
|
|
480
|
+
colFilter = me.getFilterOdata(colName, col);
|
|
481
|
+
if (colFilter) {
|
|
482
|
+
filter.push(colFilter);
|
|
483
|
+
}
|
|
484
|
+
}
|
|
485
|
+
else {
|
|
486
|
+
const condition1 = me.getFilterOdata(colName, col.condition1);
|
|
487
|
+
const condition2 = me.getFilterOdata(colName, col.condition2);
|
|
488
|
+
if (condition1 && condition2) {
|
|
489
|
+
colFilter = `(${condition1} ${col.operator.toLowerCase()} ${condition2})`;
|
|
490
|
+
filter.push(colFilter);
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
}
|
|
494
|
+
}
|
|
495
|
+
let pivotActive = false;
|
|
496
|
+
const apply = options.apply || [];
|
|
497
|
+
if (isServerMode) {
|
|
498
|
+
const requestSrv = request;
|
|
499
|
+
pivotActive =
|
|
500
|
+
requestSrv.pivotMode &&
|
|
501
|
+
requestSrv.pivotCols.length > 0 &&
|
|
502
|
+
requestSrv.valueCols.length > 0;
|
|
503
|
+
if (requestSrv.rowGroupCols.length > 0) {
|
|
504
|
+
const filterGroupBy = [];
|
|
505
|
+
if (requestSrv.groupKeys.length < requestSrv.rowGroupCols.length) {
|
|
506
|
+
// If request only groups
|
|
507
|
+
for (let idx = 0; idx < requestSrv.groupKeys.length; idx++) {
|
|
508
|
+
const colValue = requestSrv.groupKeys[idx];
|
|
509
|
+
const condition = `${me.getWrapColumnName(requestSrv.rowGroupCols[idx].field)} eq ${(me.isStrVal(colValue) ? "'" : '') +
|
|
510
|
+
me.encode(colValue) +
|
|
511
|
+
(me.isStrVal(colValue) ? "'" : '')}`;
|
|
512
|
+
filterGroupBy.push(condition);
|
|
513
|
+
}
|
|
514
|
+
if (filterGroupBy.length > 0 || filter.length > 0) {
|
|
515
|
+
// Filters must by first
|
|
516
|
+
apply.push(`filter(${filterGroupBy.concat(filter).join(' and ')})`);
|
|
517
|
+
}
|
|
518
|
+
const aggregate = [];
|
|
519
|
+
if (childCount) {
|
|
520
|
+
aggregate.push(me.odataAggregation.count(childCount));
|
|
521
|
+
}
|
|
522
|
+
if (requestSrv.valueCols.length > 0) {
|
|
523
|
+
for (let idx = 0; idx < requestSrv.valueCols.length; idx++) {
|
|
524
|
+
const colValue = requestSrv.valueCols[idx];
|
|
525
|
+
colValue.aggFunc &&
|
|
526
|
+
aggregate.push(me.odataAggregation[colValue.aggFunc](me.getWrapColumnName(colValue.field)));
|
|
527
|
+
}
|
|
528
|
+
}
|
|
529
|
+
let groups = [
|
|
530
|
+
me.getWrapColumnName(requestSrv.rowGroupCols[requestSrv.groupKeys.length].field),
|
|
531
|
+
];
|
|
532
|
+
const sort = options.sort || [];
|
|
533
|
+
const sortColOnly = sort.map((x) => x.split(' ')[0]);
|
|
534
|
+
if (pivotActive) {
|
|
535
|
+
groups = groups.concat(requestSrv.pivotCols.map((x) => me.getWrapColumnName(x.field)));
|
|
536
|
+
groups.forEach((x) => {
|
|
537
|
+
if (sortColOnly.indexOf(x) < 0) {
|
|
538
|
+
sort.push(x);
|
|
539
|
+
}
|
|
540
|
+
});
|
|
541
|
+
}
|
|
542
|
+
options.sort = sort;
|
|
543
|
+
apply.push(`groupby((${groups.join(',')})${aggregate.length > 0 ? `,aggregate(${aggregate.join(',')})` : ''})`);
|
|
544
|
+
options.apply = apply;
|
|
545
|
+
if (options.sort && options.sort.length > 0) {
|
|
546
|
+
options.sort = options.sort.filter((x) => groups.indexOf(x.split(' ')[0]) >= 0);
|
|
547
|
+
}
|
|
548
|
+
// delete options.sort;
|
|
549
|
+
}
|
|
550
|
+
else {
|
|
551
|
+
// If request rowData by group filter
|
|
552
|
+
for (let idx = 0; idx < requestSrv.groupKeys.length; idx++) {
|
|
553
|
+
const colValue = requestSrv.groupKeys[idx];
|
|
554
|
+
const condition = `${me.getWrapColumnName(requestSrv.rowGroupCols[idx].field)} eq ${(me.isStrVal(colValue) ? "'" : '') +
|
|
555
|
+
me.encode(colValue) +
|
|
556
|
+
(me.isStrVal(colValue) ? "'" : '')}`;
|
|
557
|
+
filter.push(condition);
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
}
|
|
561
|
+
}
|
|
562
|
+
if (filter.length > 0) {
|
|
563
|
+
options.filter = filter;
|
|
564
|
+
}
|
|
565
|
+
if (apply.length > 0) {
|
|
566
|
+
options.apply = apply;
|
|
567
|
+
delete options.filter;
|
|
568
|
+
delete options.expand;
|
|
569
|
+
delete options.select;
|
|
570
|
+
// options.sort = null;
|
|
571
|
+
}
|
|
572
|
+
options.skip = request.startRow;
|
|
573
|
+
options.top = (request.endRow || 0) - (request.startRow || 0);
|
|
574
|
+
if (!options.apply && options.skip === 0) {
|
|
575
|
+
options.count = true;
|
|
576
|
+
}
|
|
577
|
+
return options;
|
|
578
|
+
};
|
|
579
|
+
/**
|
|
580
|
+
* Generate odata query from ag-grid request
|
|
581
|
+
* @param params ag-grid details for the request
|
|
582
|
+
*/
|
|
583
|
+
this.getOdataQuery = (params) => this.toQuery(this.getOdataOptions(params));
|
|
584
|
+
Object.assign(this, options);
|
|
585
|
+
if (this.callApi == null) {
|
|
586
|
+
throw new Error('callApi must be specified');
|
|
587
|
+
}
|
|
588
|
+
if (typeof this.callApi !== 'function') {
|
|
589
|
+
throw new Error('callApi must be a function');
|
|
590
|
+
}
|
|
591
|
+
if (this.beforeRequest != null &&
|
|
592
|
+
typeof this.beforeRequest !== 'function') {
|
|
593
|
+
throw new Error('beforeRequest must be a function');
|
|
594
|
+
}
|
|
595
|
+
if (this.afterLoadData != null &&
|
|
596
|
+
typeof this.afterLoadData !== 'function') {
|
|
597
|
+
throw new Error('afterLoadData must be a function');
|
|
598
|
+
}
|
|
599
|
+
if (this.setError != null && typeof this.setError !== 'function') {
|
|
600
|
+
throw new Error('setError must be a function');
|
|
601
|
+
}
|
|
602
|
+
this.cancelPromice = this.createCancelablePromise();
|
|
603
|
+
}
|
|
604
|
+
/**
|
|
605
|
+
* Extract value from record by path to field
|
|
606
|
+
* @param field path to column value
|
|
607
|
+
* @param obj record
|
|
608
|
+
*/
|
|
609
|
+
getValue(field, obj) {
|
|
610
|
+
const paths = field.split('.');
|
|
611
|
+
if (paths.length === 1) {
|
|
612
|
+
return obj[field];
|
|
613
|
+
}
|
|
614
|
+
else {
|
|
615
|
+
return paths.reduce((object, path) => {
|
|
616
|
+
return (object || {})[path]; // Oliver Steele's pattern
|
|
617
|
+
}, obj);
|
|
618
|
+
}
|
|
619
|
+
}
|
|
620
|
+
/**
|
|
621
|
+
* grid calls this to get rows for IServerSideDatasource
|
|
622
|
+
* @param params ag-grid details for the request
|
|
623
|
+
*/
|
|
624
|
+
/**
|
|
625
|
+
* grid calls this to get rows implement
|
|
626
|
+
* @param params ag-grid details for the request
|
|
627
|
+
*/
|
|
628
|
+
getRows(params) {
|
|
629
|
+
const me = this;
|
|
630
|
+
const childCount = me.groupCountFieldName;
|
|
631
|
+
const isServerMode = 'request' in params;
|
|
632
|
+
const request = isServerMode
|
|
633
|
+
? params.request
|
|
634
|
+
: params;
|
|
635
|
+
const requestSrv = request;
|
|
636
|
+
const pivotActive = !isServerMode
|
|
637
|
+
? false
|
|
638
|
+
: requestSrv.pivotMode &&
|
|
639
|
+
requestSrv.pivotCols.length > 0 &&
|
|
640
|
+
requestSrv.valueCols.length > 0;
|
|
641
|
+
if (!pivotActive) {
|
|
642
|
+
let fn = params.columnApi.setPivotResultColumns;
|
|
643
|
+
if (fn != null) {
|
|
644
|
+
// if ((params as any).columnApi.isPivotMode()) {
|
|
645
|
+
;
|
|
646
|
+
params.columnApi.setPivotResultColumns([]);
|
|
647
|
+
// }
|
|
648
|
+
}
|
|
649
|
+
else {
|
|
650
|
+
;
|
|
651
|
+
params.columnApi.setSecondaryColumns([]);
|
|
652
|
+
}
|
|
653
|
+
}
|
|
654
|
+
const options = me.getOdataOptions(params);
|
|
655
|
+
const query = me.toQuery(options);
|
|
656
|
+
if (options.skip === 0 &&
|
|
657
|
+
(!isServerMode ||
|
|
658
|
+
(isServerMode &&
|
|
659
|
+
params.parentNode.level === -1))) {
|
|
660
|
+
me.cancelPromice.cancel();
|
|
661
|
+
me.cancelPromice = me.createCancelablePromise();
|
|
662
|
+
}
|
|
663
|
+
Promise.race([me.cancelPromice.promise, me.callApi(query)]).then(async (x) => {
|
|
664
|
+
if (!x) {
|
|
665
|
+
params.failCallback();
|
|
666
|
+
}
|
|
667
|
+
else {
|
|
668
|
+
const values = me.getOdataResult(x);
|
|
669
|
+
if (!pivotActive) {
|
|
670
|
+
if (!options.apply) {
|
|
671
|
+
me.setResult(params, isServerMode, values, x['@odata.count']);
|
|
672
|
+
if (this.afterLoadData) {
|
|
673
|
+
this.afterLoadData(options, values, x['@odata.count']);
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
else {
|
|
677
|
+
let count = values.length;
|
|
678
|
+
if (count === options.top && options.skip === 0) {
|
|
679
|
+
// If received grouped count of value large than requested then request total count of values
|
|
680
|
+
me.callApi(query + '/aggregate($count as count)').then((y) => {
|
|
681
|
+
count = me.getOdataResult(y)[0].count;
|
|
682
|
+
me.setResult(params, isServerMode, values, count);
|
|
683
|
+
});
|
|
684
|
+
}
|
|
685
|
+
else {
|
|
686
|
+
if (options.skip != null && options.skip > 0) {
|
|
687
|
+
count = null;
|
|
688
|
+
}
|
|
689
|
+
me.setResult(params, isServerMode, values, count);
|
|
690
|
+
if (this.afterLoadData) {
|
|
691
|
+
this.afterLoadData(options, values, count);
|
|
692
|
+
}
|
|
693
|
+
}
|
|
694
|
+
}
|
|
695
|
+
}
|
|
696
|
+
else {
|
|
697
|
+
let rowData = me.getOdataResult(x);
|
|
698
|
+
// Check count
|
|
699
|
+
if (rowData.length === options.top &&
|
|
700
|
+
options.skip === 0 &&
|
|
701
|
+
requestSrv.groupKeys.length === 0) {
|
|
702
|
+
let eof = false;
|
|
703
|
+
while (!eof) {
|
|
704
|
+
options.skip += options.top || 0;
|
|
705
|
+
const subQuery = me.toQuery(options);
|
|
706
|
+
const newRowData = await me.callApi(subQuery);
|
|
707
|
+
if (!newRowData) {
|
|
708
|
+
params.failCallback();
|
|
709
|
+
return;
|
|
710
|
+
}
|
|
711
|
+
eof = newRowData.length !== options.top;
|
|
712
|
+
rowData = rowData.concat(newRowData);
|
|
713
|
+
}
|
|
714
|
+
}
|
|
715
|
+
const pivotResult = me.getPivot(requestSrv.pivotCols, requestSrv.rowGroupCols, requestSrv.valueCols, rowData, childCount);
|
|
716
|
+
rowData = pivotResult.data;
|
|
717
|
+
const secondaryColDefs = pivotResult.secondaryColDefs;
|
|
718
|
+
rowData = me.buildGroupsFromData(rowData, requestSrv.rowGroupCols, requestSrv.groupKeys, childCount);
|
|
719
|
+
const totalCount = requestSrv.groupKeys.length === 0
|
|
720
|
+
? rowData.length
|
|
721
|
+
: rowData.length === options.top
|
|
722
|
+
? null
|
|
723
|
+
: rowData.length;
|
|
724
|
+
// if (totalCount > (options.top || 0)) {
|
|
725
|
+
// const serverSideBlock = (params as any).parentNode.rowModel
|
|
726
|
+
// .rowNodeBlockLoader.blocks[0];
|
|
727
|
+
// serverSideBlock.rowNodeCacheParams.blockSize = totalCount;
|
|
728
|
+
// serverSideBlock.endRow = serverSideBlock.startRow + totalCount;
|
|
729
|
+
// serverSideBlock.createRowNodes();
|
|
730
|
+
// }
|
|
731
|
+
me.setResult(params, isServerMode, rowData, totalCount);
|
|
732
|
+
if (this.afterLoadData) {
|
|
733
|
+
this.afterLoadData(options, rowData, totalCount);
|
|
734
|
+
}
|
|
735
|
+
if (requestSrv.groupKeys.length === 0) {
|
|
736
|
+
if (this.beforeSetSecondaryColumns) {
|
|
737
|
+
this.beforeSetSecondaryColumns(secondaryColDefs);
|
|
738
|
+
}
|
|
739
|
+
let fn = params.columnApi.setPivotResultColumns;
|
|
740
|
+
if (fn) {
|
|
741
|
+
;
|
|
742
|
+
params.columnApi.setPivotResultColumns(secondaryColDefs);
|
|
743
|
+
}
|
|
744
|
+
else {
|
|
745
|
+
;
|
|
746
|
+
params.columnApi.setSecondaryColumns(secondaryColDefs);
|
|
747
|
+
}
|
|
748
|
+
}
|
|
749
|
+
}
|
|
750
|
+
}
|
|
751
|
+
}, (err) => {
|
|
752
|
+
me.setResult(params, isServerMode, [], 0);
|
|
753
|
+
if (this.setError) {
|
|
754
|
+
this.setError(err, params);
|
|
755
|
+
}
|
|
756
|
+
});
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
export class OdataProviderClient extends OdataProvider {
|
|
760
|
+
getRows(params) {
|
|
761
|
+
super.getRows(params);
|
|
762
|
+
}
|
|
763
|
+
}
|
|
764
|
+
export class OdataServerSideProvider extends OdataProvider {
|
|
765
|
+
getRows(params) {
|
|
766
|
+
super.getRows(params);
|
|
767
|
+
}
|
|
768
|
+
}
|
|
769
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib0RhdGFQcm92aWRlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2Jhc2VzaXRlLXNoYXJlZC1ncmlkLWxpYi9zcmMvbGliL2hlbHBlcnMvb0RhdGFQcm92aWRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFnQkUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLFNBQVMsQ0FBQTtBQXNHcEMsTUFBTSxPQUFPLGFBQWE7SUFnR3hCLFlBQVksT0FBNkI7UUEzRnpDOzs7V0FHRztRQUNILHdCQUFtQixHQUFXLFlBQVksQ0FBQTtRQUMxQzs7O1dBR0c7UUFDSCxnQ0FBMkIsR0FBWSxLQUFLLENBQUE7UUE0RzVDLGtDQUFrQztRQUNsQyw0QkFBdUIsR0FBRyxHQUFzQixFQUFFO1lBQ2hELElBQUksTUFBVSxDQUFBO1lBQ2QsTUFBTSxFQUFFLEdBQUcsSUFBSSxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsTUFBTSxFQUFFLEVBQUU7Z0JBQ25DLE1BQU0sR0FBRyxNQUFNLENBQUE7WUFDakIsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQyxDQUFBO1lBQ2xCLE9BQU87Z0JBQ0wsT0FBTyxFQUFFLEVBQUU7Z0JBQ1gsTUFBTTthQUNQLENBQUE7UUFDSCxDQUFDLENBQUE7UUFDRCw0QkFBNEI7UUFDNUIsa0JBQWEsR0FBTztZQUNsQixVQUFVO1lBQ1YsTUFBTSxFQUFFLENBQUMsR0FBVyxFQUFFLE1BQWMsRUFBVSxFQUFFLENBQUMsR0FBRyxHQUFHLE9BQU8sTUFBTSxFQUFFO1lBQ3RFLFFBQVEsRUFBRSxDQUFDLEdBQVcsRUFBRSxNQUFjLEVBQVUsRUFBRSxDQUFDLEdBQUcsR0FBRyxPQUFPLE1BQU0sRUFBRTtZQUN4RSxRQUFRLEVBQUUsQ0FBQyxHQUFXLEVBQUUsTUFBYyxFQUFVLEVBQUUsQ0FBQyxHQUFHLEdBQUcsT0FBTyxNQUFNLEVBQUU7WUFDeEUsZUFBZSxF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eUJBQ2pEO3dCQUNELElBQUksRUFBRSxHQUFJLE1BQWMsQ0FBQyxTQUFTLENBQUMscUJBQXFCLENBQUE7d0JBQ3hELElBQUksRUFBRSxFQUFFOzRCQUNOLENBQUM7NEJBQUMsTUFBYyxDQUFDLFNBQVMsQ0FBQyxxQkFBcUIsQ0FDOUMsZ0JBQWdCLENBQ2pCLENBQUE7eUJBQ0Y7NkJBQU07NEJBQ0wsQ0FBQzs0QkFBQyxNQUFjLENBQUMsU0FBUyxDQUFDLG1CQUFtQixDQUFDLGdCQUFnQixDQUFDLENBQUE7eUJBQ2pFO3FCQUNGO2lCQUNGO2FBQ0Y7UUFDSCxDQUFDLEVBQ0QsQ0FBQyxHQUFHLEVBQUUsRUFBRTtZQUNOLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLFlBQVksRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUE7WUFDekMsSUFBSSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNqQixJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQTthQUMzQjtRQUNILENBQUMsQ0FDRixDQUFBO0lBQ0gsQ0FBQztDQTZMRjtBQUVELE1BQU0sT0FBTyxtQkFBb0IsU0FBUSxhQUFhO0lBQ3BDLE9BQU8sQ0FBQyxNQUFnQztRQUN0RCxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3ZCLENBQUM7Q0FDRjtBQUNELE1BQU0sT0FBTyx1QkFBd0IsU0FBUSxhQUFhO0lBQ3hDLE9BQU8sQ0FBQyxNQUFnQztRQUN0RCxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFBO0lBQ3ZCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgICBJR2V0Um93c1BhcmFtcyxcclxuICAgIENvbERlZixcclxuICAgIENvbEdyb3VwRGVmLFxyXG4gICAgQ29sdW1uVk8sXHJcbiAgICBJU2VydmVyU2lkZUdldFJvd3NSZXF1ZXN0LFxyXG4gICAgSVNlcnZlclNpZGVHZXRSb3dzUGFyYW1zLFxyXG4gIH0gZnJvbSAnYWctZ3JpZC1jb21tdW5pdHknXHJcbiAgXHJcbiAgaW1wb3J0IHtcclxuICAgIE9kYXRhUXVlcnlFeHRlbmRGdWxsLFxyXG4gICAgT2RhdGFRdWVyeUV4dGVuZE9wdGlvbnMsXHJcbiAgICBPZGF0YVF1ZXJ5T3B0aW9ucyxcclxuICAgIFBpdm90UmVzdWx0RGF0LFxyXG4gIH0gZnJvbSAnLi90eXBlcydcclxuICBcclxuICBpbXBvcnQgeyByZXBsYWNlQWxsIH0gZnJvbSAnLi91dGlscydcclxuICBleHBvcnQgZGVjbGFyZSBjbGFzcyBPZGF0YVByb3ZpZGVyT3B0aW9ucyB7XHJcbiAgICAvKipcclxuICAgICAqIEZ1bmN0aW9uIGZvciBjYWxsIG9kYXRhIGFwaVxyXG4gICAgICovXHJcbiAgICBjYWxsQXBpOiAocXVlcnk6IHN0cmluZykgPT4gUHJvbWlzZTxhbnk+XHJcbiAgICAvKipcclxuICAgICAqIE5hbWUgb2YgZmllbGQgY29udGFpbiBjb3VudCBvZiByZWNvcmQgcmVzdWx0cyBpbiBncm91cGluZyBvZGF0YSBxdWVyeVxyXG4gICAgICogQGRlZmF1bHQgY2hpbGRDb3VudFxyXG4gICAgICovXHJcbiAgICBncm91cENvdW50RmllbGROYW1lPzogc3RyaW5nXHJcbiAgICAvKipcclxuICAgICAqIFVzZSBpbiBvZGF0YSBidWlsZCBxdWVyeVxyXG4gICAgICogQGRlZmF1bHQgZmFsc2VcclxuICAgICAqL1xyXG4gICAgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyPzogYm9vbGVhblxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayBmb3IgZXh0ZW5kIG9kYXRhIHF1ZXJ5IG9wdGlvbnMgZm9yIGltcGxlbWVudCB1c2VyIGxvZ2ljXHJcbiAgICAgKi9cclxuICAgIGJlZm9yZVJlcXVlc3Q/OiAoXHJcbiAgICAgIG9wdGlvbnM6IE9kYXRhUXVlcnlPcHRpb25zLFxyXG4gICAgICBwcm92aWRlcjogT2RhdGFQcm92aWRlcixcclxuICAgICAgcmVxdWVzdDogSUdldFJvd3NQYXJhbXMgfCBJU2VydmVyU2lkZUdldFJvd3NSZXF1ZXN0XHJcbiAgICApID0+IHZvaWRcclxuICAgIC8qKlxyXG4gICAgKiBDYWxsYmFjayBmb3IgcGl2b3Qgb3IgZ3JvdXAgZm9yIGFwbGx5IGNvbHVtbiBhZy1ncmlkIHNldHRpbmdzXHJcbiAgICAqIEBleGFtcGxlXHJcbiAgICAqIDxwcmU+PGNvZGU+XHJcbiAgICAqIGJlZm9yZVNldFNlY29uZGFyeUNvbHVtbnMgPSBzZWNvbmRhcnlDb2x1bW5zID0+IHtcclxuICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlY29uZGFyeUNvbHVtbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgIGNvbnN0IGNvbCA9IHNlY29uZGFyeUNvbHVtbnNbaV1cclxuICAgICAgIGlmIChjb2wuY2hpbGRyZW4pIHtcclxuICAgICAgICAgYmVmb3JlU2V0U2Vjb25kYXJ5Q29sdW1ucyhjb2wuY2hpbGRyZW4pXHJcbiAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAvL0FwbGx5IG5ldyBzZXR0aW5nIGZvciBncm91cCBkeW5jYW1pYyBjcmVhdGVkIGNvbHVtblxyXG4gICAgICAgICAvLyBjb2wuY2VsbENsYXNzUnVsZXMgPSBcclxuICAgICAgICAgLy8gY29sLnZhbHVlRm9ybWF0dGVyID0gXHJcbiAgICAgICB9XHJcbiAgICAgfVxyXG4gICB9XHJcbiAgICAqIDwvcHJlPjwvY29kZT5cclxuICAgICovXHJcbiAgICBiZWZvcmVTZXRTZWNvbmRhcnlDb2x1bW5zPzogKFxyXG4gICAgICBzZWNvbmRhcnlDb2xEZWZzOiAoQ29sRGVmIHwgQ29sR3JvdXBEZWYpW11cclxuICAgICkgPT4gdm9pZFxyXG4gICAgLyoqXHJcbiAgICAqIENhbGxiYWNrIGludm9rZWQgYWZ0ZXIgbG9hZCBkYXRhXHJcbiAgICAqIEBwYXJhbSBvcHRpb25zIG9kYXRhIHByb3ZpZGVyIG9wdGlvbnNcclxuICAgICogQHBhcmFtIHJvd0RhdGEgZGF0YSBmb3IgYWctZ3JpZFxyXG4gICAgKiBAcGFyYW0gdG90YWxDb3VudCB0b3RhbCBjb3VudCByZWNvcmRzXHJcbiAgICAqIFxyXG4gICAgKiBAZXhhbXBsZVxyXG4gICAgKiA8cHJlPjxjb2RlPlxyXG4gICAgICAgICBhZnRlckxvYWREYXRhID0gKG9wdGlvbnMsIHJvd0RhdGEsIHRvdGFsQ291bnQpID0+IHtcclxuICAgICAgICAgICAgIGlmIChvcHRpb25zLnNraXAgPT09IDAgJiYgcm93RGF0YS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICBncmlkQXBpLmNvbHVtbkNvbnRyb2xsZXIuYXV0b1NpemVBbGxDb2x1bW5zKClcclxuICAgICAgICAgICAgIH1cclxuICAgICAgICAgfVxyXG4gICAgKiA8L2NvZGU+PC9wcmU+XHJcbiAgICAqL1xyXG4gICAgYWZ0ZXJMb2FkRGF0YT86IChcclxuICAgICAgb3B0aW9uczogT2RhdGFRdWVyeUV4dGVuZE9wdGlvbnMsXHJcbiAgICAgIHJvd0RhdGE6IGFueVtdLFxyXG4gICAgICB0b3RhbENvdW50OiBudW1iZXJcclxuICAgICkgPT4gdm9pZFxyXG4gICAgLyoqXHJcbiAgICAgKiBDYWxsYmFjayBmb3IgY2F0Y2ggZXJyb3JcclxuICAgICAqL1xyXG4gICAgc2V0RXJyb3I/OiAoXHJcbiAgICAgIGVycm9yOiBhbnksXHJcbiAgICAgIHBhcmFtczogSUdldFJvd3NQYXJhbXMgfCBJU2VydmVyU2lkZUdldFJvd3NQYXJhbXNcclxuICAgICkgPT4gdm9pZFxyXG4gICAgLyoqXHJcbiAgICAgKiBMaXN0IG9mIGNvbHVtbnMgYnkgaWQvZmllbGQgYXJlIGNhc2Ugc2Vuc2l0aXZlIGZvciBidWlsZCBvZGF0YSBxdWVyeVxyXG4gICAgICovXHJcbiAgICBjYXNlU2Vuc2l0aXZlQ29sdW1ucz86IHN0cmluZ1tdXHJcbiAgICAvKipcclxuICAgICAqIFVzZSBmb3Igc3BlY2lmaWVkIGNvbHVtbiBjdXN0b20gZmlsdGVyIGltcGxlbWVudGF0aW9uXHJcbiAgICAgKiA8cHJlPjxjb2RlPlxyXG4gICAgICAgICBjdXN0b21GaWx0ZXJzOiB7XHJcbiAgICAgICAgICAgICBcImN1c3RvbWVyXCI6IChjb2xOYW1lLGNvbCxpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXIscHJvdmlkZXIpID0+e1xyXG4gICAgICAgICAgICAgICByZXR1cm4gcHJvdmlkZXIub2RhdGFPcGVyYXRvci5pbihcclxuICAgICAgICAgICAgICAgIGNvbE5hbWUsXHJcbiAgICAgICAgICAgICAgICBjb2wudmFsdWVzXHJcbiAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgfVxyXG4gICAgICAgICB9XHJcbiAgICAgKi9cclxuICAgIGN1c3RvbUZpbHRlcnM/OiB7XHJcbiAgICAgIFtpbmRleDogc3RyaW5nXTogKFxyXG4gICAgICAgIGNvbE5hbWU6IHN0cmluZyxcclxuICAgICAgICBjb2w6IGFueSxcclxuICAgICAgICBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXI6IGJvb2xlYW4sXHJcbiAgICAgICAgcHJvdmlkZXI6IE9kYXRhUHJvdmlkZXJcclxuICAgICAgKSA9PiBzdHJpbmdcclxuICAgIH1cclxuICB9XHJcbiAgXHJcbiAgZGVjbGFyZSBpbnRlcmZhY2UgQ2FuY2VsYWJsZVByb21pc2Uge1xyXG4gICAgcHJvbWlzZTogUHJvbWlzZTxhbnk+XHJcbiAgICBjYW5jZWw6ICgpID0+IHZvaWRcclxuICB9XHJcbiAgZXhwb3J0IGNsYXNzIE9kYXRhUHJvdmlkZXIgaW1wbGVtZW50cyBPZGF0YVByb3ZpZGVyT3B0aW9ucyB7XHJcbiAgICAvKipcclxuICAgICAqIEZ1bmN0aW9uIGZvciBjYWxsIG9kYXRhIGFwaVxyXG4gICAgICovXHJcbiAgICBjYWxsQXBpITogKHF1ZXJ5OiBzdHJpbmcpID0+IFByb21pc2U8YW55PlxyXG4gICAgLyoqXHJcbiAgICAgKiBOYW1lIG9mIGZpZWxkIGNvbnRhaW4gY291bnQgb2YgcmVjb3JkIHJlc3VsdHMgaW4gZ3JvdXBpbmcgb2RhdGEgcXVlcnlcclxuICAgICAqIEBkZWZhdWx0IGNoaWxkQ291bnRcclxuICAgICAqL1xyXG4gICAgZ3JvdXBDb3VudEZpZWxkTmFtZTogc3RyaW5nID0gJ2NoaWxkQ291bnQnXHJcbiAgICAvKipcclxuICAgICAqIFVzZSBpbiBvZGF0YSBidWlsZCBxdWVyeVxyXG4gICAgICogQGRlZmF1bHQgZmFsc2VcclxuICAgICAqL1xyXG4gICAgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyOiBib29sZWFuID0gZmFsc2VcclxuICAgIC8qKlxyXG4gICAgICogQ2FsbGJhY2sgZm9yIGV4dGVuZCBvZGF0YSBxdWVyeSBvcHRpb25zIGZvciBpbXBsZW1lbnQgdXNlciBsb2dpY1xyXG4gICAgICovXHJcbiAgICBiZWZvcmVSZXF1ZXN0OiAoKFxyXG4gICAgICAgIG9wdGlvbnM6IE9kYXRhUXVlcnlPcHRpb25zLFxyXG4gICAgICAgIHByb3ZpZGVyOiBPZGF0YVByb3ZpZGVyLFxyXG4gICAgICAgIHJlcXVlc3Q6IElHZXRSb3dzUGFyYW1zIHwgSVNlcnZlclNpZGVHZXRSb3dzUmVxdWVzdFxyXG4gICAgKSA9PiB2b2lkKSB8IHVuZGVmaW5lZFxyXG4gICAgLyoqXHJcbiAgICAgICogQ2FsbGJhY2sgZm9yIHBpdm90IG9yIGdyb3VwIGZvciBhcGxseSBjb2x1bW4gYWctZ3JpZCBzZXR0aW5nc1xyXG4gICAgICAqIEBleGFtcGxlXHJcbiAgICAgICogPHByZT48Y29kZT5cclxuICAgICAgKiBiZWZvcmVTZXRTZWNvbmRhcnlDb2x1bW5zID0gc2Vjb25kYXJ5Q29sdW1ucyA9PiB7XHJcbiAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHNlY29uZGFyeUNvbHVtbnMubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgY29uc3QgY29sID0gc2Vjb25kYXJ5Q29sdW1uc1tpXVxyXG4gICAgICAgICBpZiAoY29sLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgICAgYmVmb3JlU2V0U2Vjb25kYXJ5Q29sdW1ucyhjb2wuY2hpbGRyZW4pXHJcbiAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgLy9BcGxseSBuZXcgc2V0dGluZyBmb3IgZ3JvdXAgZHluY2FtaWMgY3JlYXRlZCBjb2x1bW5cclxuICAgICAgICAgICAvLyBjb2wuY2VsbENsYXNzUnVsZXMgPSBcclxuICAgICAgICAgICAvLyBjb2wudmFsdWVGb3JtYXR0ZXIgPSBcclxuICAgICAgICAgfVxyXG4gICAgICAgfVxyXG4gICAgIH1cclxuICAgICAgKiA8L3ByZT48L2NvZGU+XHJcbiAgICAgICovXHJcbiAgICBiZWZvcmVTZXRTZWNvbmRhcnlDb2x1bW5zOiAoKFxyXG4gICAgICAgIHNlY29uZGFyeUNvbERlZnM6IChDb2xEZWYgfCBDb2xHcm91cERlZilbXVxyXG4gICAgKSA9PiB2b2lkKSB8IHVuZGVmaW5lZFxyXG4gICAgLyoqXHJcbiAgICAgICogQ2FsbGJhY2sgaW52b2tlZCBhZnRlciBsb2FkIGRhdGFcclxuICAgICAgKiBAcGFyYW0gb3B0aW9ucyBvZGF0YSBwcm92aWRlciBvcHRpb25zXHJcbiAgICAgICogQHBhcmFtIHJvd0RhdGEgZGF0YSBmb3IgYWctZ3JpZFxyXG4gICAgICAqIEBwYXJhbSB0b3RhbENvdW50IHRvdGFsIGNvdW50IHJlY29yZHNcclxuICAgICAgKiBcclxuICAgICAgKiBAZXhhbXBsZVxyXG4gICAgICAqIDxwcmU+PGNvZGU+XHJcbiAgICAgICAgICAgYWZ0ZXJMb2FkRGF0YSA9IChvcHRpb25zLCByb3dEYXRhLCB0b3RhbENvdW50KSA9PiB7XHJcbiAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNraXAgPT09IDAgJiYgcm93RGF0YS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgIGdyaWRBcGkuY29sdW1uQ29udHJvbGxlci5hdXRvU2l6ZUFsbENvbHVtbnMoKVxyXG4gICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgfVxyXG4gICAgICAqIDwvY29kZT48L3ByZT5cclxuICAgICAgKi9cclxuICAgIGFmdGVyTG9hZERhdGE6ICgoXHJcbiAgICAgICAgb3B0aW9uczogT2RhdGFRdWVyeUV4dGVuZE9wdGlvbnMsXHJcbiAgICAgICAgcm93RGF0YTogYW55W10sXHJcbiAgICAgICAgdG90YWxDb3VudDogbnVtYmVyXHJcbiAgICApID0+IHZvaWQpIHwgdW5kZWZpbmVkXHJcbiAgICAvKipcclxuICAgICAqIENhbGxiYWNrIGZvciBjYXRjaCBlcnJvclxyXG4gICAgICovXHJcbiAgICBzZXRFcnJvcjogKChcclxuICAgICAgICBlcnJvcjogYW55LFxyXG4gICAgICAgIHBhcmFtczogSUdldFJvd3NQYXJhbXMgfCBJU2VydmVyU2lkZUdldFJvd3NQYXJhbXNcclxuICAgICkgPT4gdm9pZCkgfCB1bmRlZmluZWRcclxuICAgIC8qKlxyXG4gICAgICogTGlzdCBvZiBjb2x1bW5zIGJ5IGlkL2ZpZWxkIGFyZSBjYXNlIHNlbnNpdGl2ZSBmb3IgYnVpbGQgb2RhdGEgcXVlcnlcclxuICAgICAqL1xyXG4gICAgY2FzZVNlbnNpdGl2ZUNvbHVtbnM/OiBzdHJpbmdbXVxyXG4gICAgLyoqXHJcbiAgICAgKiBVc2UgZm9yIHNwZWNpZmllZCBjb2x1bW4gY3VzdG9tIGZpbHRlciBpbXBsZW1lbnRhdGlvblxyXG4gICAgICogPHByZT48Y29kZT5cclxuICAgICAgICAgY3VzdG9tRmlsdGVyczoge1xyXG4gICAgICAgICAgICAgXCJjdXN0b21lclwiOiAoY29sTmFtZSxjb2wsaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyLHByb3ZpZGVyKSA9PntcclxuICAgICAgICAgICAgICAgcmV0dXJuIHByb3ZpZGVyLm9kYXRhT3BlcmF0b3IuaW4oXHJcbiAgICAgICAgICAgICAgICBjb2xOYW1lLFxyXG4gICAgICAgICAgICAgICAgY29sLnZhbHVlc1xyXG4gICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgIH1cclxuICAgICAgICAgfVxyXG4gICAgICovXHJcbiAgICBjdXN0b21GaWx0ZXJzPzoge1xyXG4gICAgICBbaW5kZXg6IHN0cmluZ106IChcclxuICAgICAgICBjb2xOYW1lOiBzdHJpbmcsXHJcbiAgICAgICAgY29sOiBhbnksXHJcbiAgICAgICAgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyOiBib29sZWFuLFxyXG4gICAgICAgIHByb3ZpZGVyOiBPZGF0YVByb3ZpZGVyXHJcbiAgICAgICkgPT4gc3RyaW5nXHJcbiAgICB9XHJcbiAgICBjYW5jZWxQcm9taWNlOiBDYW5jZWxhYmxlUHJvbWlzZVxyXG4gICAgY29uc3RydWN0b3Iob3B0aW9uczogT2RhdGFQcm92aWRlck9wdGlvbnMpIHtcclxuICAgICAgT2JqZWN0LmFzc2lnbih0aGlzLCBvcHRpb25zKTtcclxuICAgICAgaWYgKHRoaXMuY2FsbEFwaSA9PSBudWxsKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdjYWxsQXBpIG11c3QgYmUgc3BlY2lmaWVkJylcclxuICAgICAgfVxyXG4gICAgICBpZiAodHlwZW9mIHRoaXMuY2FsbEFwaSAhPT0gJ2Z1bmN0aW9uJykge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcignY2FsbEFwaSBtdXN0IGJlIGEgZnVuY3Rpb24nKVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChcclxuICAgICAgICB0aGlzLmJlZm9yZVJlcXVlc3QgIT0gbnVsbCAmJlxyXG4gICAgICAgIHR5cGVvZiB0aGlzLmJlZm9yZVJlcXVlc3QgIT09ICdmdW5jdGlvbidcclxuICAgICAgKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdiZWZvcmVSZXF1ZXN0IG11c3QgYmUgYSBmdW5jdGlvbicpXHJcbiAgICAgIH1cclxuICAgICAgaWYgKFxyXG4gICAgICAgIHRoaXMuYWZ0ZXJMb2FkRGF0YSAhPSBudWxsICYmXHJcbiAgICAgICAgdHlwZW9mIHRoaXMuYWZ0ZXJMb2FkRGF0YSAhPT0gJ2Z1bmN0aW9uJ1xyXG4gICAgICApIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoJ2FmdGVyTG9hZERhdGEgbXVzdCBiZSBhIGZ1bmN0aW9uJylcclxuICAgICAgfVxyXG4gICAgICBpZiAodGhpcy5zZXRFcnJvciAhPSBudWxsICYmIHR5cGVvZiB0aGlzLnNldEVycm9yICE9PSAnZnVuY3Rpb24nKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzZXRFcnJvciBtdXN0IGJlIGEgZnVuY3Rpb24nKVxyXG4gICAgICB9XHJcbiAgICAgIHRoaXMuY2FuY2VsUHJvbWljZSA9IHRoaXMuY3JlYXRlQ2FuY2VsYWJsZVByb21pc2UoKVxyXG4gICAgfVxyXG4gIFxyXG4gICAgLyoqQ3JlYXRvciBhIGNhbmNlbGFibGUgUHJvbWlzZSAqL1xyXG4gICAgY3JlYXRlQ2FuY2VsYWJsZVByb21pc2UgPSAoKTogQ2FuY2VsYWJsZVByb21pc2UgPT4ge1xyXG4gICAgICBsZXQgY2FuY2VsOmFueVxyXG4gICAgICBjb25zdCBwciA9IG5ldyBQcm9taXNlKChfLCByZWplY3QpID0+IHtcclxuICAgICAgICBjYW5jZWwgPSByZWplY3RcclxuICAgICAgfSkuY2F0Y2goKCkgPT4ge30pXHJcbiAgICAgIHJldHVybiB7XHJcbiAgICAgICAgcHJvbWlzZTogcHIsXHJcbiAgICAgICAgY2FuY2VsLFxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvKipPZGF0YSBxdWVyeSBvcGVyYXRpb25zICovXHJcbiAgICBvZGF0YU9wZXJhdG9yOmFueSA9IHtcclxuICAgICAgLy8gTG9naWNhbFxyXG4gICAgICBlcXVhbHM6IChjb2w6IHN0cmluZywgdmFsdWUxOiBzdHJpbmcpOiBzdHJpbmcgPT4gYCR7Y29sfSBlcSAke3ZhbHVlMX1gLFxyXG4gICAgICBub3RFcXVhbDogKGNvbDogc3RyaW5nLCB2YWx1ZTE6IHN0cmluZyk6IHN0cmluZyA9PiBgJHtjb2x9IG5lICR7dmFsdWUxfWAsXHJcbiAgICAgIGxlc3NUaGFuOiAoY29sOiBzdHJpbmcsIHZhbHVlMTogc3RyaW5nKTogc3RyaW5nID0+IGAke2NvbH0gbHQgJHt2YWx1ZTF9YCxcclxuICAgICAgbGVzc1RoYW5PckVxdWFsOiAoY29sOiBzdHJpbmcsIHZhbHVlMTogc3RyaW5nKTogc3RyaW5nID0+XHJcbiAgICAgICAgYCR7Y29sfSBsZSAke3ZhbHVlMX1gLFxyXG4gICAgICBncmVhdGVyVGhhbjogKGNvbDogc3RyaW5nLCB2YWx1ZTE6IHN0cmluZyk6IHN0cmluZyA9PiBgJHtjb2x9IGd0ICR7dmFsdWUxfWAsXHJcbiAgICAgIGdyZWF0ZXJUaGFuT3JFcXVhbDogKGNvbDogc3RyaW5nLCB2YWx1ZTE6IHN0cmluZyk6IHN0cmluZyA9PlxyXG4gICAgICAgIGAke2NvbH0gZ2UgJHt2YWx1ZTF9YCxcclxuICAgICAgaW5SYW5nZTogKGNvbDogc3RyaW5nLCB2YWx1ZTE6IHN0cmluZywgdmFsdWUyOiBhbnkpOiBzdHJpbmcgPT5cclxuICAgICAgICBgKCR7Y29sfSBnZSAke3ZhbHVlMX0gYW5kICR7Y29sfSBsZSAke3ZhbHVlMn0pYCxcclxuICAgICAgLy8gU3RyaW5nXHJcbiAgICAgIGVxdWFsc1N0cjogKFxyXG4gICAgICAgIGNvbDogc3RyaW5nLFxyXG4gICAgICAgIHZhbHVlMTogc3RyaW5nLFxyXG4gICAgICAgIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlcjogYm9vbGVhblxyXG4gICAgICApOiBzdHJpbmcgPT5cclxuICAgICAgICBgJHt0aGlzLmlmVG9sb3dlckNvbChcclxuICAgICAgICAgIGNvbCxcclxuICAgICAgICAgIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlclxyXG4gICAgICAgICl9IGVxICR7dGhpcy5pZlRvbG93ZXIodmFsdWUxLCBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXIpfWAsXHJcbiAgICAgIG5vdEVxdWFsU3RyOiAoXHJcbiAgICAgICAgY29sOiBzdHJpbmcsXHJcbiAgICAgICAgdmFsdWUxOiBzdHJpbmcsXHJcbiAgICAgICAgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyOiBib29sZWFuXHJcbiAgICAgICk6IHN0cmluZyA9PlxyXG4gICAgICAgIGAke3RoaXMuaWZUb2xvd2VyQ29sKFxyXG4gICAgICAgICAgY29sLFxyXG4gICAgICAgICAgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyXHJcbiAgICAgICAgKX0gbmUgJHt0aGlzLmlmVG9sb3dlcih2YWx1ZTEsIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlcil9YCxcclxuICAgICAgY29udGFpbnM6IChcclxuICAgICAgICBjb2w6IHN0cmluZyxcclxuICAgICAgICB2YWx1ZTE6IHN0cmluZyxcclxuICAgICAgICBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXI6IGJvb2xlYW5cclxuICAgICAgKTogc3RyaW5nID0+XHJcbiAgICAgICAgYGNvbnRhaW5zKCR7dGhpcy5pZlRvbG93ZXJDb2woXHJcbiAgICAgICAgICBjb2wsXHJcbiAgICAgICAgICBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXJcclxuICAgICAgICApfSwke3RoaXMuaWZUb2xvd2VyKHZhbHVlMSwgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyKX0pYCxcclxuICAgICAgbm90Q29udGFpbnM6IChcclxuICAgICAgICBjb2w6IHN0cmluZyxcclxuICAgICAgICB2YWx1ZTE6IHN0cmluZyxcclxuICAgICAgICBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXI6IGJvb2xlYW5cclxuICAgICAgKTogc3RyaW5nID0+XHJcbiAgICAgICAgYGNvbnRhaW5zKCR7dGhpcy5pZlRvbG93ZXJDb2woXHJcbiAgICAgICAgICBjb2wsXHJcbiAgICAgICAgICBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXJcclxuICAgICAgICApfSwke3RoaXMuaWZUb2xvd2VyKHZhbHVlMSwgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyKX0pIGVxIGZhbHNlYCxcclxuICAgICAgc3RhcnRzV2l0aDogKFxyXG4gICAgICAgIGNvbDogc3RyaW5nLFxyXG4gICAgICAgIHZhbHVlMTogc3RyaW5nLFxyXG4gICAgICAgIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlcjogYm9vbGVhblxyXG4gICAgICApOiBzdHJpbmcgPT5cclxuICAgICAgICBgc3RhcnRzd2l0aCgke3RoaXMuaWZUb2xvd2VyQ29sKFxyXG4gICAgICAgICAgY29sLFxyXG4gICAgICAgICAgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyXHJcbiAgICAgICAgKX0sJHt0aGlzLmlmVG9sb3dlcih2YWx1ZTEsIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlcil9KSAgZXEgdHJ1ZWAsXHJcbiAgICAgIGVuZHNXaXRoOiAoXHJcbiAgICAgICAgY29sOiBzdHJpbmcsXHJcbiAgICAgICAgdmFsdWUxOiBzdHJpbmcsXHJcbiAgICAgICAgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyOiBib29sZWFuXHJcbiAgICAgICk6IHN0cmluZyA9PlxyXG4gICAgICAgIGBlbmRzd2l0aCgke3RoaXMuaWZUb2xvd2VyQ29sKFxyXG4gICAgICAgICAgY29sLFxyXG4gICAgICAgICAgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyXHJcbiAgICAgICAgKX0sJHt0aGlzLmlmVG9sb3dlcih2YWx1ZTEsIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlcil9KSAgZXEgdHJ1ZWAsXHJcbiAgICAgIGluU3RyOiAoXHJcbiAgICAgICAgY29sOiBzdHJpbmcsXHJcbiAgICAgICAgdmFsdWVzOiBzdHJpbmdbXSxcclxuICAgICAgICBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXI6IGJvb2xlYW5cclxuICAgICAgKTogc3RyaW5nID0+XHJcbiAgICAgICAgYCR7dGhpcy5pZlRvbG93ZXJDb2woY29sLCBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXIpfSBpbiAoJHt2YWx1ZXNcclxuICAgICAgICAgIC5tYXAoXHJcbiAgICAgICAgICAgICh4KSA9PlxyXG4gICAgICAgICAgICAgIGAnJHt0aGlzLmlmVG9sb3dlcih0aGlzLmVuY29kZSh4KSwgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyKX0nYFxyXG4gICAgICAgICAgKVxyXG4gICAgICAgICAgLmpvaW4oKX0pYCxcclxuICAgICAgaW46IChjb2w6IHN0cmluZywgdmFsdWVzOiBzdHJpbmdbXSkgPT5cclxuICAgICAgICBgJHtjb2x9IGluICgke3ZhbHVlcy5tYXAoKHgpID0+IGAke3RoaXMuZW5jb2RlKHgpfWApLmpvaW4oKX0pYCxcclxuICAgICAgbm90SW46IChjb2w6IHN0cmluZywgdmFsdWVzOiBzdHJpbmdbXSkgPT5cclxuICAgICAgICBgbm90ICgke2NvbH0gaW4gKCR7dmFsdWVzLm1hcCgoeCkgPT4gYCR7eH1gKS5qb2luKCl9KSlgLFxyXG4gICAgICAvLyBEYXRlXHJcbiAgICAgIHRydW5jOiAoY29sOiBzdHJpbmcpOiBzdHJpbmcgPT4gYGRhdGUoJHtjb2x9KWAsXHJcbiAgICB9XHJcbiAgXHJcbiAgICAvKipcclxuICAgICAqIEFwcGx5IHRvbG93ZXIgZm9yIGNvbHVtbiBpbiBvZGF0YSBzeW50YXhcclxuICAgICAqIEBwYXJhbSBjb2wgY29sdW1uIG5hbWVcclxuICAgICAqIEBwYXJhbSBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXIgbmVlZCBhcHBseSB0b2xvd2VyXHJcbiAgICAgKi9cclxuICAgIGlmVG9sb3dlckNvbCA9IChjb2w6IHN0cmluZywgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyOiBib29sZWFuKTogc3RyaW5nID0+XHJcbiAgICAgIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlciA/IGNvbCA6IGB0b2xvd2VyKCR7Y29sfSlgXHJcbiAgXHJcbiAgICAvKipcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gdmFsdWUgc3RyaW5nIHZhbHVlXHJcbiAgICAgKiBAcGFyYW0gaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyICBuZWVkIGFwcGx5IHRvbG93ZXJcclxuICAgICAqL1xyXG4gICAgaWZUb2xvd2VyID0gKHZhbHVlOiBzdHJpbmcsIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlcjogYm9vbGVhbik6IHN0cmluZyA9PlxyXG4gICAgICBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXIgPyB2YWx1ZSA6IHZhbHVlID8gdmFsdWUudG9Mb3dlckNhc2UoKSA6IHZhbHVlXHJcbiAgICAvKipcclxuICAgICAqIE9kYXRhIGFnZ3JlZ2F0aW9uIG9wZXJhdGlvbnNcclxuICAgICAqL1xyXG4gICAgb2RhdGFBZ2dyZWdhdGlvbjphbnkgPSB7XHJcbiAgICAgIC8vIExvZ2ljYWxcclxuICAgICAgc3VtOiAoY29sOiBzdHJpbmcsIGFzRmllbGQ/OiBhbnkpOiBzdHJpbmcgPT5cclxuICAgICAgICBgJHtjb2x9IHdpdGggc3VtIGFzICR7Y29sIHx8IGFzRmllbGR9YCxcclxuICAgICAgbWluOiAoY29sOiBzdHJpbmcsIGFzRmllbGQ/OiBhbnkpOiBzdHJpbmcgPT5cclxuICAgICAgICBgJHtjb2x9IHdpdGggbWluIGFzICR7Y29sIHx8IGFzRmllbGR9YCxcclxuICAgICAgbWF4OiAoY29sOiBzdHJpbmcsIGFzRmllbGQ/OiBhbnkpOiBzdHJpbmcgPT5cclxuICAgICAgICBgJHtjb2x9IHdpdGggbWF4IGFzICR7Y29sIHx8IGFzRmllbGR9YCxcclxuICAgICAgYXZnOiAoY29sOiBzdHJpbmcsIGFzRmllbGQ/OiBhbnkpOiBzdHJpbmcgPT5cclxuICAgICAgICBgJHtjb2x9IHdpdGggYXZlcmFnZSBhcyAke2NvbCB8fCBhc0ZpZWxkfWAsXHJcbiAgICAgIGNvdW50OiAoY29sOiBzdHJpbmcsIGFzRmllbGQ/OiBhbnkpOiBzdHJpbmcgPT5cclxuICAgICAgICBgJGNvdW50IGFzICR7Y29sIHx8IGFzRmllbGR9YCxcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogT2RhdGEgcXVlcnkgYnVpbGRlclxyXG4gICAgICogQHBhcmFtIG9wdGlvbnMgcGFyYW1ldGVyIGZvciBvZGF0YSBxdWVyeVxyXG4gICAgICovXHJcbiAgICB0b1F1ZXJ5ID0gKG9wdGlvbnM6IE9kYXRhUXVlcnlFeHRlbmRGdWxsKTogc3RyaW5nID0+IHtcclxuICAgICAgbGV0IHBhdGg6IHN0cmluZ1tdID0gW11cclxuICAgICAgaWYgKG9wdGlvbnMuY291bnQpIHtcclxuICAgICAgICBwYXRoLnB1c2goJyRjb3VudD10cnVlJylcclxuICAgICAgfVxyXG4gICAgICBpZiAob3B0aW9ucy5za2lwKSB7XHJcbiAgICAgICAgcGF0aC5wdXNoKGAkc2tpcD0ke29wdGlvbnMuc2tpcH1gKVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChvcHRpb25zLnRvcCkge1xyXG4gICAgICAgIHBhdGgucHVzaChgJHRvcD0ke29wdGlvbnMudG9wfWApXHJcbiAgICAgIH1cclxuICAgICAgaWYgKG9wdGlvbnMuc29ydCAmJiBvcHRpb25zLnNvcnQubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIHBhdGgucHVzaCgnJG9yZGVyYnk9JyArIG9wdGlvbnMuc29ydC5qb2luKCcsJykpXHJcbiAgICAgIH1cclxuICAgICAgaWYgKG9wdGlvbnMuZmlsdGVyICYmIG9wdGlvbnMuZmlsdGVyLmxlbmd0aCA+IDApIHtcclxuICAgICAgICBwYXRoLnB1c2goJyRmaWx0ZXI9JyArIG9wdGlvbnMuZmlsdGVyLmpvaW4oJyBhbmQgJykpXHJcbiAgICAgIH1cclxuICAgICAgaWYgKG9wdGlvbnMuYXBwbHkgJiYgb3B0aW9ucy5hcHBseS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcGF0aC5wdXNoKCckYXBwbHk9JyArIG9wdGlvbnMuYXBwbHkuam9pbignLycpKVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChvcHRpb25zLmV4cGFuZCAmJiBvcHRpb25zLmV4cGFuZC5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgcGF0aC5wdXNoKCckZXhwYW5kPScgKyBvcHRpb25zLmV4cGFuZC5qb2luKCcsJykpXHJcbiAgICAgIH1cclxuICAgICAgaWYgKG9wdGlvbnMuc2VsZWN0ICYmIG9wdGlvbnMuc2VsZWN0Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICBwYXRoLnB1c2goJyRzZWxlY3Q9JyArIG9wdGlvbnMuc2VsZWN0LmpvaW4oJywnKSlcclxuICAgICAgfVxyXG4gICAgICBsZXQgcXVlcnk6IHN0cmluZyA9ICcnXHJcbiAgICAgIGlmIChwYXRoLmxlbmd0aCA+IDApIHtcclxuICAgICAgICBxdWVyeSA9ICc/JyArIHBhdGguam9pbignJicpXHJcbiAgICAgIH1cclxuICAgICAgcmV0dXJuIHF1ZXJ5XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIEFkZCBxdW90ZXMgZm9yIHN0cmluZyB2YWx1ZVxyXG4gICAgICogQHBhcmFtIHZhbHVlIHN0cmluZyB2YWx1ZVxyXG4gICAgICovXHJcbiAgICBlbmNvZGUgPSAodmFsdWU6IHN0cmluZyk6IHN0cmluZyA9PlxyXG4gICAgICB0aGlzLmlzU3RyVmFsKHZhbHVlKSA/IHJlcGxhY2VBbGwodmFsdWUsIFwiJ1wiLCBcIicnXCIpIDogdmFsdWVcclxuICAgIC8qKlxyXG4gICAgICogQ29uY3RhdCB0byBkYXRlIGEgdGltZSBmb3IgY3JlYXRlIGRhdGV0aW1lIGZvcm1hdCBmb3Igb2RhdGEgcXVlcnlcclxuICAgICAqIEBwYXJhbSB2YWx1ZSBkYXRlIHN0cmluZ1xyXG4gICAgICovXHJcbiAgICB0b0RhdGVUaW1lID0gKHZhbHVlOiBzdHJpbmcpOiBzdHJpbmcgfCBudWxsID0+IHtcclxuICAgICAgY29uc3QgZHQgPSBuZXcgRGF0ZSh2YWx1ZSlcclxuICAgICAgaWYgKGlzTmFOKGR0LmdldFRpbWUoKSkpIHJldHVybiBudWxsXHJcbiAgICAgIGNvbnN0IGR0MSA9IG5ldyBEYXRlKFxyXG4gICAgICAgIERhdGUuVVRDKGR0LmdldEZ1bGxZZWFyKCksIGR0LmdldE1vbnRoKCksIGR0LmdldERhdGUoKSlcclxuICAgICAgKVxyXG4gICAgICByZXR1cm4gZHQxLnRvSVNPU3RyaW5nKClcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBjb2xOYW1lIGNvbHVtbk5hbWVcclxuICAgICAqIEByZXR1cm5zIGlzIENhc2VTZW5zaXRpdmUgZm9yIGNvbHVtblxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldElzTmVlZENhc2VTZW5zaXRpdmUgPSAoY29sTmFtZTogc3RyaW5nKSA9PiB7XHJcbiAgICAgIGlmIChcclxuICAgICAgICAhdGhpcy5pc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXIgJiZcclxuICAgICAgICB0aGlzLmNhc2VTZW5zaXRpdmVDb2x1bW5zICYmXHJcbiAgICAgICAgdGhpcy5jYXNlU2Vuc2l0aXZlQ29sdW1ucy5sZW5ndGggPiAwXHJcbiAgICAgICkge1xyXG4gICAgICAgIHJldHVybiB0aGlzLmNhc2VTZW5zaXRpdmVDb2x1bW5zLmluZGV4T2YoY29sTmFtZSkgPj0gMFxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB0aGlzLmlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlclxyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBDb252ZXJ0IGFnLWdyaWQgY29sdW1uIGZpbHRlciB0byBvZGF0YSBxdWVyeVxyXG4gICAgICogQHBhcmFtIGNvbE5hbWUgY29sdW1uTmFtZVxyXG4gICAgICogQHBhcmFtIGNvbCBhZy1ncmlkIGNvbHVtblxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldEZpbHRlck9kYXRhID0gKGNvbE5hbWU6IHN0cmluZywgY29sOiBhbnkpOiBzdHJpbmcgPT4ge1xyXG4gICAgICBjb25zdCBtZSA9IHRoaXNcclxuICAgICAgY29uc3QgaXNDYXNlU2Vuc2l0aXZlU3RyaW5nRmlsdGVyID0gbWUuZ2V0SXNOZWVkQ2FzZVNlbnNpdGl2ZShjb2xOYW1lKVxyXG4gICAgICBjb25zdCBjdXN0b21GaWx0ZXIgPSBtZS5jdXN0b21GaWx0ZXJzICYmIG1lLmN1c3RvbUZpbHRlcnNbY29sTmFtZV1cclxuICAgICAgY29sTmFtZSA9IHJlcGxhY2VBbGwoY29sTmFtZSwgJy4nLCAnLycpXHJcbiAgICAgIGNvbE5hbWUgPSBtZS5nZXRXcmFwQ29sdW1uTmFtZShjb2xOYW1lKVxyXG4gICAgICBpZiAoY3VzdG9tRmlsdGVyKSB7XHJcbiAgICAgICAgcmV0dXJuIGN1c3RvbUZpbHRlcihjb2xOYW1lLCBjb2wsIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlciwgbWUpXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgc3dpdGNoIChjb2wuZmlsdGVyVHlwZSkge1xyXG4gICAgICAgICAgY2FzZSAnbnVtYmVyJzpcclxuICAgICAgICAgICAgcmV0dXJuIG1lLm9kYXRhT3BlcmF0b3JbY29sLnR5cGVdKGNvbE5hbWUsIGNvbC5maWx0ZXIsIGNvbC5maWx0ZXJUbylcclxuICAgICAgICAgIGNhc2UgJ3RleHQnOiB7XHJcbiAgICAgICAgICAgIGxldCBvcGVyYXRvck5hbWUgPSBjb2wudHlwZVxyXG4gICAgICAgICAgICBjb25zdCBmaWx0ZXIgPSBtZS5lbmNvZGUoY29sLmZpbHRlcilcclxuICAgICAgICAgICAgLy8gbGV0IGZpbHRlclRvID0gbWUuZW5jb2RlKGNvbC5maWx0ZXJUbyk7XHJcbiAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICAob3BlcmF0b3JOYW1lID09PSAnZXF1YWxzJyB8fCBvcGVyYXRvck5hbWUgPT09ICdub3RFcXVhbCcpICYmXHJcbiAgICAgICAgICAgICAgIWlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlclxyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICBvcGVyYXRvck5hbWUgKz0gJ1N0cidcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICByZXR1cm4gbWUub2RhdGFPcGVyYXRvcltvcGVyYXRvck5hbWVdKFxyXG4gICAgICAgICAgICAgIGNvbE5hbWUsXHJcbiAgICAgICAgICAgICAgYCcke2ZpbHRlcn0nYCxcclxuICAgICAgICAgICAgICBpc0Nhc2VTZW5zaXRpdmVTdHJpbmdGaWx0ZXJcclxuICAgICAgICAgICAgKVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgY2FzZSAnZGF0ZSc6XHJcbiAgICAgICAgICAgIGlmIChcclxuICAgICAgICAgICAgICBjb2wuZGF0ZUZyb20gIT0gbnVsbCAmJlxyXG4gICAgICAgICAgICAgIG1lLnRvRGF0ZVRpbWUoY29sLmRhdGVGcm9tKSAhPSBudWxsICYmXHJcbiAgICAgICAgICAgICAgKGNvbC5kYXRlVG8gPT0gbnVsbCB8fFxyXG4gICAgICAgICAgICAgICAgKGNvbC5kYXRlVG8gIT0gbnVsbCAmJiBtZS50b0RhdGVUaW1lKGNvbC5kYXRlVG8pICE9IG51bGwpKVxyXG4gICAgICAgICAgICApIHtcclxuICAgICAgICAgICAgICByZXR1cm4gbWUub2RhdGFPcGVyYXRvcltjb2wudHlwZV0oXHJcbiAgICAgICAgICAgICAgICBjb2xOYW1lLFxyXG4gICAgICAgICAgICAgICAgYCR7bWUudG9EYXRlVGltZShjb2wuZGF0ZUZyb20pfWAsXHJcbiAgICAgICAgICAgICAgICBgJHttZS50b0RhdGVUaW1lKGNvbC5kYXRlVG8pfWBcclxuICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgYnJlYWtcclxuICAgICAgICAgIGNhc2UgJ3NldCc6XHJcbiAgICAgICAgICAgIHJldHVybiBjb2wudmFsdWVzLmxlbmd0aCA+IDBcclxuICAgICAgICAgICAgICA/IG1lLm9kYXRhT3BlcmF0b3IuaW5TdHIoXHJcbiAgICAgICAgICAgICAgICAgIGNvbE5hbWUsXHJcbiAgICAgICAgICAgICAgICAgIGNvbC52YWx1ZXMsXHJcbiAgICAgICAgICAgICAgICAgIGlzQ2FzZVNlbnNpdGl2ZVN0cmluZ0ZpbHRlclxyXG4gICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgIDogJydcclxuICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgIGJyZWFrXHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiAnJ1xyXG4gICAgfVxyXG4gIFxyXG4gICAgLyoqXHJcbiAgICAgKiBFeHRyYWN0IHZhbHVlIGZyb20gcmVjb3JkIGJ5IHBhdGggdG8gZmllbGRcclxuICAgICAqIEBwYXJhbSBmaWVsZCBwYXRoIHRvIGNvbHVtbiB2YWx1ZVxyXG4gICAgICogQHBhcmFtIG9iaiAgcmVjb3JkXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0VmFsdWUoZmllbGQ6IHN0cmluZywgb2JqOiBhbnkpOiBhbnkge1xyXG4gICAgICBjb25zdCBwYXRocyA9IGZpZWxkLnNwbGl0KCcuJylcclxuICAgICAgaWYgKHBhdGhzLmxlbmd0aCA9PT0gMSkge1xyXG4gICAgICAgIHJldHVybiBvYmpbZmllbGRdXHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgcmV0dXJuIHBhdGhzLnJlZHVjZSgob2JqZWN0LCBwYXRoKSA9PiB7XHJcbiAgICAgICAgICByZXR1cm4gKG9iamVjdCB8fCB7fSlbcGF0aF0gLy8gT2xpdmVyIFN0ZWVsZSdzIHBhdHRlcm5cclxuICAgICAgICB9LCBvYmopXHJcbiAgICAgIH1cclxuICAgIH1cclxuICBcclxuICAgIC8qKlxyXG4gICAgICogQ2FjbHVsYXRlIHBpdm90IGRhdGEgZm9yIGFnLWdyaWQgZnJvbSBvZGF0YVxyXG4gICAgICogQHBhcmFtIHBpdm90Q29scyBwaXZvdCBjb2x1bW5zXHJcbiAgICAgKiBAcGFyYW0gcm93R3JvdXBDb2xzIHJvdyBncm91cCBjb2x1bW5zXHJcbiAgICAgKiBAcGFyYW0gdmFsdWVDb2xzIHZhbHVlIGNvbHVtbnNcclxuICAgICAqIEBwYXJhbSBkYXRhIG9kYXRhIHJlc3VsdFxyXG4gICAgICogQHBhcmFtIGNvdW50RmllbGQgY291bnQgZmllbGQgbmFtZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGdldFBpdm90ID0gKFxyXG4gICAgICBwaXZvdENvbHM6IENvbHVtblZPW10sXHJcbiAgICAgIHJvd0dyb3VwQ29sczogQ29sdW1uVk9bXSxcclxuICAgICAgdmFsdWVDb2xzOiBDb2x1bW5WT1tdLFxyXG4gICAgICBkYXRhOiBhbnlbXSxcclxuICAgICAgY291bnRGaWVsZDogc3RyaW5nXHJcbiAgICApOiBQaXZvdFJlc3VsdERhdCA9PiB7XHJcbiAgICAgIC8vIGFzc3VtZSAxIHBpdm90IGNvbCBhbmQgMSB2YWx1ZSBjb2wgZm9yIHRoaXMgZXhhbXBsZVxyXG4gICAgICBjb25zdCBtZSA9IHRoaXNcclxuICAgICAgY29uc3QgcGl2b3REYXRhOiBhbnlbXSA9IFtdXHJcbiAgICAgIGNvbnN0IGFnZ0NvbHNMaXN0OiBhbnlbXSA9IFtdXHJcbiAgXHJcbiAgICAgIGNvbnN0IGNvbEtleUV4aXN0c01hcDogYW55ID0ge31cclxuICBcclxuICAgICAgY29uc3Qgc2Vjb25kYXJ5Q29sRGVmczogYW55W10gPSBbXVxyXG4gICAgICBjb25zdCBzZWNvbmRhcnlDb2xEZWZzTWFwOmFueSA9IHt9XHJcbiAgXHJcbiAgICAgIGRhdGEuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgIHZhciBwaXZvdFZhbHVlczogc3RyaW5nW10gPSBbXVxyXG4gICAgICAgIHBpdm90Q29scy5mb3JFYWNoKGZ1bmN0aW9uIChwaXZvdENvbCkge1xyXG4gICAgICAgICAgdmFyIHBpdm90RmllbGQgPSBwaXZvdENvbC5pZFxyXG4gICAgICAgICAgdmFyIHBpdm90VmFsdWUgPSBtZS5nZXRWYWx1ZShwaXZvdEZpZWxkLCBpdGVtKVxyXG4gICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICBwaXZvdFZhbHVlICE9PSBudWxsICYmXHJcbiAgICAgICAgICAgIHBpdm90VmFsdWUgIT09IHVuZGVmaW5lZCAmJlxyXG4gICAgICAgICAgICBwaXZvdFZhbHVlLnRvU3RyaW5nXHJcbiAgICAgICAgICApIHtcclxuICAgICAgICAgICAgcGl2b3RWYWx1ZXMucHVzaChwaXZvdFZhbHVlLnRvU3RyaW5nKCkpXHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBwaXZvdFZhbHVlcy5wdXNoKCctJylcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gIFxyXG4gICAgICAgIC8vIHZhciBwaXZvdFZhbHVlID0gaXRlbVtwaXZvdEZpZWxkXS50b1N0cmluZygpO1xyXG4gICAgICAgIHZhciBwaXZvdEl0ZW06YW55ID0ge31cclxuICBcclxuICAgICAgICB2YWx1ZUNvbHMuZm9yRWFjaChmdW5jdGlvbiAodmFsdWVDb2wpIHtcclxuICAgICAgICAgIHZhciB2YWxGaWVsZCA9IHZhbHVlQ29sLmlkXHJcbiAgICAgICAgICB2YXIgY29sS2V5ID0gY3JlYXRlQ29sS2V5KHBpdm90VmFsdWVzLCB2YWxGaWVsZClcclxuICBcclxuICAgICAgICAgIHZhciB2YWx1ZSA9IG1lLmdldFZhbHVlKHZhbEZpZWxkLCBpdGVtKVxyXG4gICAgICAgICAgcGl2b3RJdGVtW2NvbEtleV0gPSB2YWx1ZVxyXG4gIFxyXG4gICAgICAgICAgaWYgKCFjb2xLZXlFeGlzdHNNYXBbY29sS2V5XSkge1xyXG4gICAgICAgICAgICBhZGROZXdBZ2dDb2woY29sS2V5LCB2YWx1ZUNvbClcclxuICAgICAgICAgICAgYWRkTmV3U2Vjb25kYXJ5Q29sRGVmKGNvbEtleSwgcGl2b3RWYWx1ZXMsIHZhbHVlQ29sKVxyXG4gICAgICAgICAgICBjb2xLZXlFeGlzdHNNYXBbY29sS2V5XSA9IHRydWVcclxuICAgICAgICAgIH1cclxuICAgICAgICB9KVxyXG4gICAgICAgIGlmIChjb3VudEZpZWxkKSB7XHJcbiAgICAgICAgICBwaXZvdEl0ZW1bY291bnRGaWVsZF0gPSBtZS5nZXRWYWx1ZShjb3VudEZpZWxkLCBpdGVtKVxyXG4gICAgICAgIH1cclxuICBcclxuICAgICAgICByb3dHcm91cENvbHMuZm9yRWFjaChmdW5jdGlvbiAocm93R3JvdXBDb2wpIHtcclxuICAgICAgICAgIHZhciByb3dHcm91cEZpZWxkID0gcm93R3JvdXBDb2wuaWQuc3BsaXQoJy4nKVswXVxyXG4gICAgICAgICAgcGl2b3RJdGVtW3Jvd0dyb3VwRmllbGRdID0gaXRlbVtyb3dHcm91cEZpZWxkXVxyXG4gICAgICAgIH0pXHJcbiAgXHJcbiAgICAgICAgcGl2b3REYXRhLnB1c2gocGl2b3RJdGVtKVxyXG4gICAgICB9KVxyXG4gIFxyXG4gICAgICBmdW5jdGlvbiBhZGROZXdBZ2dDb2woY29sS2V5OiBzdHJpbmcsIHZhbHVlQ29sOiBDb2x1bW5WTyk6IHZvaWQge1xyXG4gICAgICAgIHZhciBuZXdDb2wgPSB7XHJcbiAgICAgICAgICBpZDogY29sS2V5LFxyXG4gICAgICAgICAgZmllbGQ6IGNvbEtleSxcclxuICAgICAgICAgIGFnZ0Z1bmM6IHZhbHVlQ29sLmFnZ0Z1bmMsXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGFnZ0NvbHNMaXN0LnB1c2gobmV3Q29sKVxyXG4gICAgICB9XHJcbiAgXHJcbiAgICAgIGZ1bmN0aW9uIGFkZE5ld1NlY29uZGFyeUNvbERlZihjb2xLZXk6YW55LCBwaXZvdFZhbHVlczphbnksIHZhbHVlQ29sOmFueSkge1xyXG4gICAgICAgIHZhciBwYXJlbnRHcm91cDogYW55ID0gbnVsbFxyXG4gIFxyXG4gICAgICAgIHZhciBrZXlQYXJ0czogYW55ID0gW11cclxuICBcclxuICAgICAgICBwaXZvdFZhbHVlcy5mb3JFYWNoKGZ1bmN0aW9uIChwaXZvdFZhbHVlOiBhbnkpIHtcclxuICAgICAgICAgIGtleVBhcnRzLnB1c2gocGl2b3RWYWx1ZSlcclxuICAgICAgICAgIHZhciBjb2xLZXkgPSBjcmVhdGVDb2xLZXkoa2V5UGFydHMpXHJcbiAgICAgICAgICB2YXIgZ3JvdXBDb2xEZWY6IGFueSA9IHNlY29uZGFyeUNvbERlZnNNYXBbY29sS2V5XVxyXG4gICAgICAgICAgaWYgKCFncm91cENvbERlZikge1xyXG4gICAgICAgICAgICBncm91cENvbERlZiA9IHtcclxuICAgICAgICAgICAgICBncm91cElkOiBjb2xLZXksXHJcbiAgICAgICAgICAgICAgaGVhZGVyTmFtZTogcGl2b3RWYWx1ZSxcclxuICAgICAgICAgICAgICBjaGlsZHJlbjogW10sXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgc2Vjb25kYXJ5Q29sRGVmc01hcFtjb2xLZXldID0gZ3JvdXBDb2xEZWZcclxuICAgICAgICAgICAgaWYgKHBhcmVudEdyb3VwKSB7XHJcbiAgICAgICAgICAgICAgcGFyZW50R3JvdXAuY2hpbGRyZW4ucHVzaChncm91cENvbERlZilcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICBzZWNvbmRhcnlDb2xEZWZzLnB1c2goZ3JvdXBDb2xEZWYpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHBhcmVudEdyb3VwID0gZ3JvdXBDb2xEZWZcclxuICAgICAgICB9KVxyXG4gIFxyXG4gICAgICAgIHBhcmVudEdyb3VwLmNoaWxkcmVuLnB1c2goe1xyXG4gICAgICAgICAgY29sSWQ6IGNvbEtleSxcclxuICAgICAgICAgIGhlYWRlck5hbWU6IHZhbHVlQ29sLmFnZ0Z1bmMgKyAnKCcgKyB2YWx1ZUNvbC5kaXNwbGF5TmFtZSArICcpJyxcclxuICAgICAgICAgIGZpZWxkOiBjb2xLZXksXHJcbiAgICAgICAgICBzdXBwcmVzc01lbnU6IHRydWUsXHJcbiAgICAgICAgICBzb3J0YWJsZTogZmFsc2UsXHJcbiAgICAgICAgfSlcclxuICAgICAgfVxyXG4gIFxyXG4gICAgICBmdW5jdGlvbiBjcmVhdGVDb2xLZXkocGl2b3RWYWx1ZXM6IHN0cmluZ1tdLCB2YWx1ZUZpZWxkPzogc3RyaW5nKTogc3RyaW5nIHtcclxuICAgICAgICB2YXIgcmVzdWx0ID0gcGl2b3RWYWx1ZXMuam9pbignfCcpXHJcbiAgICAgICAgaWYgKHZhbHVlRmllbGQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgcmVzdWx0ICs9ICd8JyArIHZhbHVlRmllbGRcclxuICAgICAgICB9XHJcbiAgICAgICAgcmVzdWx0ID0gcmVwbGFjZUFsbChyZXN1bHQsICcuJywgJyonKVxyXG4gICAgICAgIHJldHVybiByZXN1bHRcclxuICAgICAgfVxyXG4gIFxyXG4gICAgICByZXR1cm4ge1xyXG4gICAgICAgIGRhdGE6IHBpdm90RGF0YSxcclxuICAgICAgICBhZ2dDb2xzOiBhZ2dDb2xzTGlzdCxcclxuICAgICAgICBzZWNvbmRhcnlDb2xEZWZzOiBzZWNvbmRhcnlDb2xEZWZzLFxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgXHJcbiAgICAvKipcclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gcm93RGF0YSBhcnJheSBvZGF0YSByZXN1bHRcclxuICAgICAqIEBwYXJhbSByb3dHcm91cENvbHMgcm93IGdyb3VwIGNvbHVtbnNcclxuICAgICAqIEBwYXJhbSBncm91cEtleXMgd2hhdCBncm91cHMgdGhlIHVzZXIgaXMgdmlld2luZ1xyXG4gICAgICogQHBhcmFtIGNvdW50RmllbGQgY291bnQgZmllbGQgbmFtZVxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIGJ1aWxkR3JvdXBzRnJvbURhdGEgPSAoXHJcbiAgICAgIHJvd0RhdGE6IGFueVtdLFxyXG4gICAgICByb3dHcm91cENvbHM6IENvbHVtblZPW10sXHJcbiAgICAgIGdyb3VwS2V5czogc3RyaW5nW10sXHJcbiAgICAgIGNvdW50RmllbGQ6IHN0cmluZ1xyXG4gICAgKTogYW55W10gPT4ge1xyXG4gICAgICBjb25zdCBtZSA9IHRoaXNcclxuICAgICAgbGV0IHJvd0dyb3VwQ29sID0gcm93R3JvdXBDb2xzW2dyb3VwS2V5cy5sZW5ndGhdXHJcbiAgICAgIGxldCBmaWVsZCA9IHJvd0dyb3VwQ29sLmlkXHJcbiAgICAgIGxldCBtYXBwZWRSb3dEYXRhID0gbWUuZ3JvdXBCeShyb3dEYXRhLCBmaWVsZClcclxuICAgICAgbGV0IGdyb3VwczogYW55ID0gW11cclxuICBcclxuICAgICAgbWUuaXRlcmF0ZU9iamVjdChtYXBwZWRSb3dEYXRhLCBmdW5jdGlvbiAoa2V5LCByb3dEYXRhKSB7XHJcbiAgICAgICAgdmFyIGdyb3VwSXRlbSA9IG1lLmFnZ3JlZ2F0ZUxpc3Qocm93RGF0YSwgY291bnRGaWVsZClcclxuICAgICAgICBncm91cEl0ZW1bZmllbGRdID0ga2V5XHJcbiAgICAgICAgZ3JvdXBzLnB1c2goZ3JvdXBJdGVtKVxyXG4gICAgICB9KVxyXG4gICAgICByZXR1cm4gZ3JvdXBzXHJcbiAgICB9XHJcbiAgXHJcbiAgICAvKipcclxuICAgICAqIEludGVybmFsIGZ1bmN0aW9uIGZvciBleGVjdXRlIGNhbGxiYWNrIGZ1bmN0aW9uIGZvciBlYWNoIHByb3BlcnR5IG9mIG9iamVjdFxyXG4gICAgICogQHBhcmFtIG9iamVjdCBvYmplY3QgY29udGFpbmVkIG9kYXRhIGdyb3VwZWQgcmVzdWx0XHJcbiAgICAgKiBAcGFyYW0gY2FsbGJhY2sgZnVuY3Rpb24gZG8gc29tdGhpbmdcclxuICAgICAqL1xyXG4gICAgcHJpdmF0ZSBpdGVyYXRlT2JqZWN0ID0gKFxyXG4gICAgICBvYmplY3Q6IGFueSxcclxuICAgICAgY2FsbGJhY2s6IChrZXk6IHN0cmluZywgcm93RGF0YTogYW55W10pID0+IHZvaWRcclxuICAgICk6IHZvaWQgPT4ge1xyXG4gICAgICBpZiAoIW9iamVjdCkge1xyXG4gICAgICAgIHJldHVyblxyXG4gICAgICB9XHJcbiAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhvYmplY3QpXHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGNvbnN0IGtleSA9IGtleXNbaV1cclxuICAgICAgICBjb25zdCB2YWx1ZSA9IG9iamVjdFtrZXldXHJcbiAgICAgICAgY2FsbGJhY2soa2V5LCB2YWx1ZSlcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIFxyXG4gICAgLyoqXHJcbiAgICAgKiBQcmVwZWFyZSBncm91cGVkIGRhdGFcclxuICAgICAqIEBwYXJhbSByb3dEYXRhIGFycmF5IG9kYXRhIHJlc3VsdFxyXG4gICAgICogQHBhcmFtIGZpZWxkIGdyb3VwaW5nIGZpZWxkXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ3JvdXBCeSA9IChyb3dEYXRhOiBhbnlbXSwgZmllbGQ6IHN0cmluZyk6IGFueSA9PiB7XHJcbiAgICAgIHZhciByZXN1bHQ6YW55ID0ge31cclxuICAgICAgY29uc3QgbWUgPSB0aGlzXHJcbiAgICAgIHJvd0RhdGEuZm9yRWFjaChmdW5jdGlvbiAoaXRlbSkge1xyXG4gICAgICAgIHZhciBrZXkgPSBtZS5nZXRWYWx1ZShmaWVsZCwgaXRlbSlcclxuICAgICAgICB2YXIgbGlzdEZvclRoaXNLZXkgPSByZXN1bHRba2V5XVxyXG4gICAgICAgIGlmICghbGlzdEZvclRoaXNLZXkpIHtcclxuICAgICAgICAgIGxpc3RGb3JUaGlzS2V5ID0gW11cclxuICAgICAgICAgIHJlc3VsdFtrZXldID0gbGlzdEZvclRoaXNLZXlcclxuICAgICAgICB9XHJcbiAgICAgICAgbGlzdEZvclRoaXNLZXkucHVzaChpdGVtKVxyXG4gICAgICB9KVxyXG4gICAgICByZXR1cm4gcmVzdWx0XHJcbiAgICB9XHJcbiAgXHJcbiAgICAvKipcclxuICAgICAqIENhbGN1bGF0ZSB0b3RhbCBjb3VudCByZWNvcmRzIGluIGdyb3VwXHJcbiAgICAgKiBAcGFyYW0gcm93RGF0YSBhcnJheSBvZGF0YSByZXN1bHQgZGF0YVxyXG4gICAgICogQHBhcmFtIGNvdW50RmllbGQgZmllbGQgY29udGFpbmVkIGNvdW50IG9mIGFsbCByZWNvcmRzXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgYWdncmVnYXRlTGlzdCA9IChyb3dEYXRhOiBhbnlbXSwgY291bnRGaWVsZDogc3RyaW5nKTogYW55ID0+IHtcclxuICAgICAgdmFyIHJlc3VsdDphbnkgPSB7fVxyXG4gICAgICByb3dEYXRhLmZvckVhY2goKHJvdykgPT4ge1xyXG4gICAgICAgIGlmIChjb3VudEZpZWxkICYmIHJvd1tjb3VudEZpZWxkXSAhPSBudWxsKSB7XHJcbiAgICAgICAgICBjb25zdCB0b3RhbENvdW50ID0gKHJlc3VsdFtjb3VudEZpZWxkXSB8fCAwKSArIChyb3dbY291bnRGaWVsZF0gfHwgMClcclxuICAgICAgICAgIGRlbGV0ZSByb3dbY291bnRGaWVsZF1cclxuICAgICAgICAgIHJlc3VsdFtjb3VudEZpZWxkXSA9IHRvdGFsQ291bnRcclxuICAgICAgICB9XHJcbiAgICAgICAgcmVzdWx0ID0gT2JqZWN0LmFzc2lnbihyZXN1bHQsIHJvdylcclxuICAgICAgfSlcclxuICAgICAgcmV0dXJuIHJlc3VsdFxyXG4gICAgfVxyXG4gIFxyXG4gICAgLyoqXHJcbiAgICAgICAqIENhbGN1bGF0ZSBkaXN0aW5jdCB2YWx1ZXMgZm9yIGlucHV0IGZpZWxkIGZyb20gT2RhdGEgYXBpXHJcbiAgICAgICAqIEBwYXJhbSBmaWVsZCBUaGUgZmllbGQgb2YgdGhlIHJvdyB0byBnZXQgdGhlIGNlbGxzIGRhdGEgZnJvbSBcclxuICAgICAgICogQHBhcmFtIGNhbGxiYWNrIFRoZSBmdW5jdGlvbiBmb3IgcmV0dXJuIGRpc3RpbmN0IHZhbHVlcyBmb3IgaW5wdXQgZmllbGRcclxuICAgICAgICogQHBhcmFtIGJlZm9yZVJlcXVlc3QgVGhlIGZ1bmN0aW9uIGZvciBjdXN0b21pemUgcmVxdWVzdFxyXG4gICAgICAgKiBAZXhhbXBsZSBcclxuICAgICAgICogPHByZT48Y29kZT5cclxuICAgICAgICogIGNvbnN0IHNldEZpbHRlclZhbHVlc0Z1bmNQYXJhbXMgPSBwYXJhbXMgPT4ge1xyXG4gICAgICAgKiAgICBjb25zdCBtZSA9IHRoaXNcclxuICAgICAgICogICAgY29uc3QgY29sID0gcGFyYW1zLmNvbERlZi5maWVsZFxyXG4gICAgICAgKiAgICBjb25zdCBzdG9yZU5hbWUgPSBtZS5nZXRTdG9yZU5hbWUoY29sKVxyXG4gICAgICAgKiAgICBjb25zdCBjYWxsYmFjayA9IGRhdGEgPT4ge1xyXG4gICAgICAgKiAgICAgIGlmIChkYXRhKSB7XHJcbiAgICAgICAqICAgICAgICBtZS5zZXRTdGF0ZSh7IFtzdG9yZU5hbWVdOiBkYXRhIH0pXHJcbiAgICAgICAqICAgICAgICBwYXJhbXMuc3VjY2VzcyhkYXRhKVxyXG4gICAgICAgKiAgICAgIH1cclxuICAgICAgICogICAgfVxyXG4gICAgICAgKiAgICBvZGF0YVByb3ZpZGVySW5zdGFuY2UuZ2V0RmlsdGVyVmFsdWVzUGFyYW1zKHBhcmFtcy5jb2xEZWYuZmllbGQsIGNhbGxiYWNrKVxyXG4gICAgICAgKiAgfVxyXG4gICAgICAgKiBcclxuICAgICAgICogLy8vLi4uLlxyXG4gICAgICAgKiAgICAgIDxBZ0dyaWRDb2x1bW5cclxuICAgICAgICAgICAgICAgICAgICBmaWVsZD1cInByb2R1Y3RcIlxyXG4gICAgICAgICAgICAgICAgICAgIGhlYWRlck5hbWU9eydQUk9EVUNUJ31cclxuICAgICAgICAgICAgICAgICAgICBmaWx0ZXI9XCJhZ1NldENvbHVtbkZpbHRlclwiXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gcm93R3JvdXBcclxuICAgICAgICAgICAgICAgICAgICAvLyBlbmFibGVQaXZvdFxyXG4gICAgICAgICAgICAgICAgICAgIGVuYWJsZVJvd0dyb3VwXHJcbiAgICAgICAgICAgICAgICAgICAgZmlsdGVyUGFyYW1zPXt7XHJcbiAgICAgICAgICAgICAgICAgICAgICB2YWx1ZXM6IHNldEZpbHRlclZhbHVlc0Z1bmNQYXJhbXMsXHJcbiAgICAgICAgICAgICAgICAgICAgICBuZXdSb3dzQWN0aW9uOiAna2VlcCdcclxuICAgICAgICAgICAgICAgICAgICB9fVxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGZpbHRlclBhcmFtcz17e2Nhc2VTZW5zaXRpdmU6IHRydWV9fVxyXG4gICAgICAgICAgICAgICAgICAvPlxyXG4gICAgICAgKiA8L2NvZGU+PC9wcmU+XHJcbiAgICAgICAqL1xyXG4gICAgZ2V0RmlsdGVyVmFsdWVzUGFyYW1zID0gKFxyXG4gICAgICBmaWVsZDogc3RyaW5nLFxyXG4gICAgICBjYWxsYmFjazogKGRhdGE6IGFueVtdKSA9PiB2b2lkLFxyXG4gICAgICBiZWZvcmVSZXF1ZXN0OiAob3B0aW9uczogT2RhdGFRdWVyeUV4dGVuZEZ1bGwpID0+IHZvaWQgfCB1bmRlZmluZWRcclxuICAgICk6IHZvaWQgPT4ge1xyXG4gICAgICBjb25zdCBtZSA9IHRoaXNcclxuICAgICAgY29uc3Qgb3B0aW9uczogT2RhdGFRdWVyeUV4dGVuZEZ1bGwgPSB7XHJcbiAgICAgICAgYXBwbHk6IFtgZ3JvdXBieSgoJHttZS5nZXRXcmFwQ29sdW1uTmFtZShmaWVsZCl9KSlgXSxcclxuICAgICAgfVxyXG4gICAgICBpZiAoYmVmb3JlUmVxdWVzdCkge1xyXG4gICAgICAgIGJlZm9yZVJlcXVlc3Qob3B0aW9ucylcclxuICAgICAgfVxyXG4gICAgICBtZS5jYWxsQXBpKG1lLnRvUXVlcnkob3B0aW9ucykpLnRoZW4oKHgpID0+IHtcclxuICAgICAgICBpZiAoeCkge1xyXG4gICAgICAgICAgbGV0IHZhbHVlcyA9IG1lLmdldE9kYXRhUmVzdWx0KHgpXHJcbiAgICAgICAgICBjYWxsYmFjayh2YWx1ZXMubWFwKCh5OmFueSkgPT4geVtmaWVsZF0pKVxyXG4gICAgICAgIH1cclxuICAgICAgfSlcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogRGV0ZWN0IGlzIHN0cmluZyB2YWx1ZVxyXG4gICAgICogQHBhcmFtIHZhbHVlXHJcbiAgICAgKi9cclxuICAgIGlzU3RyVmFsID0gKHZhbHVlOiBhbnkpOiBib29sZWFuID0+IHR5cGVvZiB2YWx1ZSA9PT0gJ3N0cmluZydcclxuICAgIC8qKlxyXG4gICAgICogRXh0YXJ0YyB2YWx1ZXMgZnJvbSBvZGF0YSByZXNwb25zZVxyXG4gICAgICogQHBhcmFtIHJlc3BvbnNlXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0T2RhdGFSZXN1bHQgPSAocmVzcG9uc2U6IGFueSk6IGFueSA9PlxyXG4gICAgICBBcnJheS5pc0FycmF5KHJlc3BvbnNlKSA/IHJlc3BvbnNlIDogcmVzcG9uc2UudmFsdWVcclxuICAgIC8qKlxyXG4gICAgICogRW5kb2NpbmcgY29sdW1uIG5hbWUgdG8gb2RhdGEgbm90YXRpb25cclxuICAgICAqIEBwYXJhbSBjb2xOYW1lIGNvbHVtbiBuYW1lXHJcbiAgICAgKi9cclxuICAgIHByaXZhdGUgZ2V0V3JhcENvbHVtbk5hbWUgPSAoY29sTmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkKTogc3RyaW5nID0+XHJcbiAgICAgIGNvbE5hbWUgPyByZXBsYWNlQWxsKGNvbE5hbWUsICcuJywgJy8nKSA6ICcnXHJcbiAgICAvKipcclxuICAgICAqIGdyaWQgY2FsbHMgdGhpcyB0byBnZXQgcm93cyBmb3IgSVNlcnZlclNpZGVEYXRhc291cmNlXHJcbiAgICAgKiBAcGFyYW0gcGFyYW1zIGFnLWdyaWQgZGV0YWlscyBmb3IgdGhlIHJlcXVlc3RcclxuICAgICAqL1xyXG4gICAgLyoqXHJcbiAgICAgKiBncmlkIGNhbGxzIHRoaXMgdG8gZ2V0IHJvd3MgaW1wbGVtZW50XHJcbiAgICAgKiBAcGFyYW0gcGFyYW1zIGFnLWdyaWQgZGV0YWlscyBmb3IgdGhlIHJlcXVlc3RcclxuICAgICAqL1xyXG4gICAgcHVibGljIGdldFJvd3MocGFyYW1zOiBJR2V0Um93c1BhcmFtcyB8IElTZXJ2ZXJTaWRlR2V0Um93c1BhcmFtcyk6IHZvaWQge1xyXG4gICAgICBjb25zdCBtZSA9IHRoaXNcclxuICAgICAgY29uc3QgY2hpbGRDb3VudCA9IG1lLmdyb3VwQ291bnRGaWVsZE5hbWVcclxuICAgICAgY29uc3QgaXNTZXJ2ZXJNb2RlID0gJ3JlcXVlc3QnIGluIHBhcmFtc1xyXG4gICAgICBjb25zdCByZXF1ZXN0ID0gaXNTZXJ2ZXJNb2RlXHJcbiAgICAgICAgPyAocGFyYW1zIGFzIElTZXJ2ZXJTaWRlR2V0Um93c1BhcmFtcykucmVxdWVzdFxyXG4gICAgICAgIDogKHBhcmFtcyBhcyBJR2V0Um93c1BhcmFtcylcclxuICAgICAgY29uc3QgcmVxdWVzdFNydiA9IHJlcXVlc3QgYXMgSVNlcnZlclNpZGVHZXRSb3dzUmVxdWVzdFxyXG4gIFxyXG4gICAgICBjb25zdCBwaXZvdEFjdGl2ZSA9ICFpc1NlcnZlck1vZGVcclxuICAgICAgICA/IGZhbHNlXHJcbiAgICAgICAgOiByZXF1ZXN0U3J2LnBpdm90TW9kZSAmJlxyXG4gICAgICAgICAgcmVxdWVzdFNydi5waXZvdENvbHMubGVuZ3RoID4gMCAmJlxyXG4gICAgICAgICAgcmVxdWVzdFNydi52YWx1ZUNvbHMubGVuZ3RoID4gMFxyXG4gIFxyXG4gICAgICBpZiAoIXBpdm90QWN0aXZlKSB7XHJcbiAgICAgICAgbGV0IGZuID0gKHBhcmFtcyBhcyBhbnkpLmNvbHVtbkFwaS5zZXRQaXZvdFJlc3VsdENvbHVtbnNcclxuICAgICAgICBpZiAoZm4gIT0gbnVsbCkge1xyXG4gICAgICAgICAgLy8gaWYgKChwYXJhbXMgYXMgYW55KS5jb2x1bW5BcGkuaXNQaXZvdE1vZGUoKSkge1xyXG4gICAgICAgICAgOyhwYXJhbXMgYXMgYW55KS5jb2x1bW5BcGkuc2V0UGl2b3RSZXN1bHRDb2x1bW5zKFtdKVxyXG4gICAgICAgICAgLy8gfVxyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICA7KHBhcmFtcyBhcyBhbnkpLmNvbHVtbkFwaS5zZXRTZWNvbmRhcnlDb2x1bW5zKFtdKVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBjb25zdCBvcHRpb25zID0gbWUuZ2V0T2RhdGFPcHRpb25zKHBhcmFtcylcclxuICAgICAgY29uc3QgcXVlcnkgPSBtZS50b1F1ZXJ5KG9wdGlvbnMpXHJcbiAgICAgIGlmIChcclxuICAgICAgICBvcHRpb25zLnNraXAgPT09IDAgJiZcclxuICAgICAgICAoIWlzU2VydmVyTW9kZSB8fFxyXG4gICAgICAgICAgKGlzU2VydmVyTW9kZSAmJlxyXG4gICAgICAgICAgICAocGFyYW1zIGFzIElTZXJ2ZXJTaWRlR2V0Um93c1BhcmFtcykucGFyZW50Tm9kZS5sZXZlbCA9PT0gLTEpKVxyXG4gICAgICApIHtcclxuICAgICAgICBtZS5jYW5jZWxQcm9taWNlLmNhbmNlbCgpXHJcbiAgICAgICAgbWUuY2FuY2VsUHJvbWljZSA9IG1lLmNyZWF0ZUNhbmNlbGFibGVQcm9taXNlKClcclxuICAgICAgfVxyXG4gICAgICBQcm9taXNlLnJhY2UoW21lLmNhbmNlbFByb21pY2UucHJvbWlzZSwgbWUuY2FsbEFwaShxdWVyeSldKS50aGVuKFxyXG4gICAgICAgIGFzeW5jICh4KSA9PiB7XHJcbiAgICAgICAgICBpZiAoIXgpIHtcclxuICAgICAgICAgICAgcGFyYW1zLmZhaWxDYWxsYmFjaygpXHJcbiAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBjb25zdCB2YWx1ZXMgPSBtZS5nZXRPZGF0YVJlc3VsdCh4KVxyXG4gICAgICAgICAgICBpZiAoIXBpdm90QWN0aXZlKSB7XHJcbiAgICAgICAgICAgICAgaWYgKCFvcHRpb25zLmFwcGx5KSB7XHJcbiAgICAgICAgICAgICAgICBtZS5zZXRSZXN1bHQocGFyYW1zLCBpc1NlcnZlck1vZGUsIHZhbHVlcywgeFsnQG9kYXRhLmNvdW50J10pXHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5hZnRlckxvYWREYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuYWZ0ZXJMb2FkRGF0YShvcHRpb25zLCB2YWx1ZXMsIHhbJ0BvZGF0YS5jb3VudCddKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBsZXQgY291bnQgPSB2YWx1ZXMubGVuZ3RoXHJcbiAgICAgICAgICAgICAgICBpZiAoY291bnQgPT09IG9wdGlvbnMudG9wICYmIG9wdGlvbnMuc2tpcCA9PT0gMCkge1xyXG4gICAgICAgICAgICAgICAgICAvLyBJZiByZWNlaXZlZCBncm91cGVkIGNvdW50IG9mIHZhbHVlIGxhcmdlIHRoYW4gcmVxdWVzdGVkIHRoZW4gcmVxdWVzdCB0b3RhbCBjb3VudCBvZiB2YWx1ZXNcclxuICAgICAgICAgICAgICAgICAgbWUuY2FsbEFwaShxdWVyeSArICcvYWdncmVnYXRlKCRjb3VudCBhcyBjb3VudCknKS50aGVuKCh5KSA9PiB7XHJcbiAgICAgICAgICAgICAgICAgICAgY291bnQgPSBtZS5nZXRPZGF0YVJlc3VsdCh5KVswXS5jb3VudFxyXG4gICAgICAgICAgICAgICAgICAgIG1lLnNldFJlc3VsdChwYXJhbXMsIGlzU2VydmVyTW9kZSwgdmFsdWVzLCBjb3VudClcclxuICAgICAgICAgICAgICAgICAgfSlcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgIGlmIChvcHRpb25zLnNraXAgIT0gbnVsbCAmJiBvcHRpb25zLnNraXAgPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY291bnQgPSBudWxsXHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgbWUuc2V0UmVzdWx0KHBhcmFtcywgaXNTZXJ2ZXJNb2RlLCB2YWx1ZXMsIGNvdW50KVxyXG4gICAgICAgICAgICAgICAgICBpZiAodGhpcy5hZnRlckxvYWREYXRhKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5hZnRlckxvYWREYXRhKG9wdGlvbnMsIHZhbHVlcywgY291bnQpXHJcbiAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgbGV0IHJvd0RhdGEgPSBtZS5nZXRPZGF0YVJlc3VsdCh4KVxyXG4gICAgICAgICAgICAgIC8vIENoZWNrIGNvdW50XHJcbiAgICAgICAgICAgICAgaWYgKFxyXG4gICAgICAgICAgICAgICAgcm93RGF0YS5sZW5ndGggPT09IG9wdGlvbnMudG9wICYmXHJcbiAgICAgICAgICAgICAgICBvcHRpb25zLnNraXAgPT09IDAgJiZcclxuICAgICAgICAgICAgICAgIHJlcXVlc3RTcnYuZ3JvdXBLZXlzLmxlbmd0aCA9PT0gMFxyXG4gICAgICAgICAgICAgICkge1xyXG4gICAgICAgICAgICAgICAgbGV0IGVvZiA9IGZhbHNlXHJcbiAgICAgICAgICAgICAgICB3aGlsZSAoIWVvZikge1xyXG4gICAgICAgICAgICAgICAgICBvcHRpb25zLnNraXAgKz0gb3B0aW9ucy50b3AgfHwgMFxyXG4gICAgICAgICAgICAgICAgICBjb25zdCBzdWJRdWVyeSA9IG1lLnRvUXVlcnkob3B0aW9ucylcclxuICAgICAgICAgICAgICAgICAgY29uc3QgbmV3Um93RGF0YSA9IGF3YWl0IG1lLmNhbGxBcGkoc3ViUXVlcnkpXHJcbiAgICAgICAgICAgICAgICAgIGlmICghbmV3Um93RGF0YSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcmFtcy5mYWlsQ2FsbGJhY2soKVxyXG4gICAgICAgICAgICAgICAgICAgIHJldHVyblxyXG4gICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgIGVvZiA9IG5ld1Jvd0RhdGEubGVuZ3RoICE9PSBvcHRpb25zLnRvcFxyXG4gICAgICAgICAgICAgICAgICByb3dEYXRhID0gcm93RGF0YS5jb25jYXQobmV3Um93RGF0YSlcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgY29uc3QgcGl2b3RSZXN1bHQgPSBtZS5nZXRQaXZvdChcclxuICAgICAgICAgICAgICAgIHJlcXVlc3RTcnYucGl2b3RDb2xzLFxyXG4gICAgICAgICAgICAgICAgcmVxdWVzdFNydi5yb3dHcm91cENvbHMsXHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0U3J2LnZhbHVlQ29scyxcclxuICAgICAgICAgICAgICAgIHJvd0RhdGEsXHJcbiAgICAgICAgICAgICAgICBjaGlsZENvdW50XHJcbiAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgIHJvd0RhdGEgPSBwaXZvdFJlc3VsdC5kYXRhXHJcbiAgICAgICAgICAgICAgY29uc3Qgc2Vjb25kYXJ5Q29sRGVmcyA9IHBpdm90UmVzdWx0LnNlY29uZGFyeUNvbERlZnNcclxuICAgICAgICAgICAgICByb3dEYXRhID0gbWUuYnVpbGRHcm91cHNGcm9tRGF0YShcclxuICAgICAgICAgICAgICAgIHJvd0RhdGEsXHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0U3J2LnJvd0dyb3VwQ29scyxcclxuICAgICAgICAgICAgICAgIHJlcXVlc3RTcnYuZ3JvdXBLZXlzLFxyXG4gICAgICAgICAgICAgICAgY2hpbGRDb3VudFxyXG4gICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICBjb25zdCB0b3RhbENvdW50ID1cclxuICAgICAgICAgICAgICAgIHJlcXVlc3RTcnYuZ3JvdXBLZXlzLmxlbmd0aCA9PT0gMFxyXG4gICAgICAgICAgICAgICAgICA/IHJvd0RhdGEubGVuZ3RoXHJcbiAgICAgICAgICAgICAgICAgIDogcm93RGF0YS5sZW5ndGggPT09IG9wdGlvbnMudG9wXHJcbiAgICAgICAgICAgICAgICAgID8gbnVsbFxyXG4gICAgICAgICAgICAgICAgICA6IHJvd0RhdGEubGVuZ3RoXHJcbiAgICAgICAgICAgICAgLy8gaWYgKHRvdGFsQ291bnQgPiAob3B0aW9ucy50b3AgfHwgMCkpIHtcclxuICAgICAgICAgICAgICAvLyAgIGNvbnN0IHNlcnZlclNpZGVCbG9jayA9IChwYXJhbXMgYXMgYW55KS5wYXJlbnROb2RlLnJvd01vZGVsXHJcbiAgICAgICAgICAgICAgLy8gICAgIC5yb3dOb2RlQmxvY2tMb2FkZXIuYmxvY2tzWzBdO1xyXG4gICAgICAgICAgICAgIC8vICAgc2VydmVyU2lkZUJsb2NrLnJvd05vZGVDYWNoZVBhcmFtcy5ibG9ja1NpemUgPSB0b3RhbENvdW50O1xyXG4gICAgICAgICAgICAgIC8vICAgc2VydmVyU2lkZUJsb2NrLmVuZFJvdyA9IHNlcnZlclNpZGVCbG9jay5zdGFydFJvdyArIHRvdGFsQ291bnQ7XHJcbiAgICAgICAgICAgICAgLy8gICBzZXJ2ZXJTaWRlQmxvY2suY3JlYXRlUm93Tm9kZXMoKTtcclxuICAgICAgICAgICAgICAvLyB9XHJcbiAgICAgICAgICAgICAgbWUuc2V0UmVzdWx0KHBhcmFtcywgaXNTZXJ2ZXJNb2RlLCByb3dEYXRhLCB0b3RhbENvdW50KVxyXG4gICAgICAgICAgICAgIGlmICh0aGlzLmFmdGVyTG9hZERhdGEpIHtcclxuICAgICAgICAgICAgICAgIHRoaXMuYWZ0ZXJMb2FkRGF0YShvcHRpb25zLCByb3dEYXRhLCB0b3RhbENvdW50KVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICBpZiAocmVxdWVzdFNydi5ncm91cEtleXMubGVuZ3RoID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICBpZiAodGhpcy5iZWZvcmVTZXRTZWNvbmRhcnlDb2x1bW5zKSB7XHJcbiAgICAgICAgICAgICAgICAgIHRoaXMuYmVmb3JlU2V0U2Vjb25kYXJ5Q29sdW1ucyhzZWNvbmRhcnlDb2xEZWZzKVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgbGV0IGZuID0gKHBhcmFtcyBhcyBhbnkpLmNvbHVtbkFwaS5zZXRQaXZvdFJlc3VsdENvbHVtbnNcclxuICAgICAgICAgICAgICAgIGlmIChmbikge1xyXG4gICAgICAgICAgICAgICAgICA7KHBhcmFtcyBhcyBhbnkpLmNvbHVtbkFwaS5zZXRQaXZvdFJlc3VsdENvbHVtbnMoXHJcbiAgICAgICAgICAgICAgICAgICAgc2Vjb25kYXJ5Q29sRGVmc1xyXG4gICAgICAgICAgICAgICAgICApXHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICA7KHBhcmFtcyBhcyBhbnkpLmNvbHVtbkFwaS5zZXRTZWNvbmRhcnlDb2x1bW5zKHNlY29uZGFyeUNvbERlZnMpXHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfSxcclxuICAgICAgICAoZXJyKSA9PiB7XHJcbiAgICAgICAgICBtZS5zZXRSZXN1bHQocGFyYW1zLCBpc1NlcnZlck1vZGUsIFtdLCAwKVxyXG4gICAgICAgICAgaWYgKHRoaXMuc2V0RXJyb3IpIHtcclxuICAgICAgICAgICAgdGhpcy5zZXRFcnJvcihlcnIsIHBhcmFtcylcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIClcclxuICAgIH1cclxuICAgIC8qKlxyXG4gICAgICogU2V0IHJlc3VsdFxyXG4gICAgICogQHBhcmFtIHBhcmFtcyBhZy1ncmlkIGRldGFpbHMgZm9yIHRoZSByZXF1ZXN0XHJcbiAgICAgKiBAcGFyYW0gaXNTZXJ2ZXJNb2RlIGRldGVjdCB0eXBlIG9mIHBhcmFtc1xyXG4gICAgICogQHBhcmFtIHJvd3NUaGlzQmxvY2sgZGF0YSBvZiB0aGUgcmVxdWVzdFxyXG4gICAgICogQHBhcmFtIHJvd0NvdW50IGNvdW50IG9mIHRvdGFsIHJlc3VsdFxyXG4gICAgICovXHJcbiAgICBwcml2YXRlIHNldFJlc3VsdCA9IChcclxuICAgICAgcGFyYW1zOiBJR2V0Um93c1BhcmFtcyB8IElTZXJ2ZXJTaWRlR2V0Um93c1BhcmFtcyxcclxuICAgICAgaXNTZXJ2ZXJNb2RlOiBib29sZWFuLFxyXG4gICAgICByb3dzVGhpc0Jsb2NrOiBhbnlbXSxcclxuICAgICAgcm93Q291bnQ/OiBudW1iZXJcclxuICAgICk6IHZvaWQgPT4ge1xyXG4gICAgICBpZiAoaXNTZXJ2ZXJNb2RlKSB7XHJcbiAgICAgICAgOyhwYXJhbXMgYXMgSVNlcnZlclNpZGVHZXRSb3dzUGFyYW1zKS5zdWNjZXNzKHtcclxuICAgICAgICAgIHJvd0RhdGE6IHJvd3NUaGlzQmxvY2ssXHJcbiAgICAgICAgICByb3dDb3VudDogcm93Q291bnQsXHJcbiAgICAgICAgfSlcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICA7KHBhcmFtcyBhcyBJR2V0Um93c1BhcmFtcykuc3VjY2Vzc0NhbGxiYWNrKHJvd3NUaGlzQmxvY2ssIHJvd0NvdW50KVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgICAvKipcclxuICAgICAqIEdlbmVyYXRlIG9kYXRhIG9wdGlvbnMgZm9yIGJ1aWxkIHF1ZXJ5IGZyb20gYWctZ3JpZCByZXF1ZXN0XHJcbiAgICAgKiBAcGFyYW0gcGFyYW1zIGFnLWdyaWQgZGV0YWlscyBmb3IgdGhlIHJlcXVlc3RcclxuICAgICAqL1xyXG4gICAgZ2V0T2RhdGFPcHRpb25zID0gKFxyXG4gICAgICBwYXJhbXM6IElHZXRSb3dzUGFyYW1zIHwgSVNlcnZlclNpZGVHZXRSb3dzUGFyYW1zXHJcbiAgICApOiBPZGF0YVF1ZXJ5RXh0ZW5kRnVsbCA9PiB7XHJcbiAgICAgIGNvbnN0IG1lID0gdGhpc1xyXG4gICAgICBjb25zdCBvcHRpb25zOiBPZGF0YVF1ZXJ5RXh0ZW5kRnVsbCA9IHt9XHJcbiAgICAgIGNvbnN0IGlzU2VydmVyTW9kZSA9ICdyZXF1ZXN0JyBpbiBwYXJhbXNcclxuICAgICAgY29uc3QgcmVxdWVzdCA9IGlzU2VydmVyTW9kZVxyXG4gICAgICAgID8gKHBhcmFtcyBhcyBJU2VydmVyU2lkZUdldFJvd3NQYXJhbXMpLnJlcXVlc3RcclxuICAgICAgICA6IChwYXJhbXMgYXMgSUdldFJvd3NQYXJhbXMpXHJcbiAgICAgIGNvbnN0IGNoaWxkQ291bnQgPSBtZS5ncm91cENvdW50RmllbGROYW1lXHJcbiAgICAgIGlmICh0aGlzLmJlZm9yZVJlcXVlc3QpIHtcclxuICAgICAgICB0aGlzLmJlZm9yZVJlcXVlc3Qob3B0aW9ucywgdGhpcywgcmVxdWVzdClcclxuICAgICAgfVxyXG4gICAgICBpZiAocmVxdWVzdC5zb3J0TW9kZWwubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIGNvbnN0IHNvcnQgPSBvcHRpb25zLnNvcnQgfHwgW11cclxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlcXVlc3Quc29ydE1vZGVsLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICBjb25zdCBjb2wgPSByZXF1ZXN0LnNvcnRNb2RlbFtpXVxyXG4gICAgICAgICAgbGV0IGNvbE5hbWUgPSBtZS5nZXRXcmFwQ29sdW1uTmFtZShjb2wuY29sSWQpXHJcbiAgICAgICAgICBpZiAoY29sLnNvcnQgIT09ICdhc2MnKSB7XHJcbiAgICAgICAgICAgIGNvbE5hbWUgKz0gJyBkZXNjJ1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgc29ydC5wdXNoKGNvbE5hbWUpXHJcbiAgICAgICAgfVxyXG4gICAgICAgIG9wdGlvbnMuc29ydCA9IHNvcnRcclxuICAgICAgfVxyXG4gIFxyXG4gICAgICBjb25zdCBmaWx0ZXIgPSBvcHRpb25zLmZpbHRlciB8fCBbXVxyXG4gICAgICBmb3IgKGNvbnN0IGNvbE5hbWUgaW4gcmVxdWVzdC5maWx0ZXJNb2RlbCkge1xyXG4gICAgICAgIGlmIChyZXF1ZXN0LmZpbHRlck1vZGVsLmhhc093blByb3BlcnR5KGNvbE5hbWUpKSB7XHJcbiAgICAgICAgICBjb25zdCBjb2wgPSByZXF1ZXN0LmZpbHRlck1vZGVsW2NvbE5hbWVdXHJcbiAgICAgICAgICBsZXQgY29sRmlsdGVyID0gJydcclxuICAgICAgICAgIGlmICghY29sLm9wZXJhdG9yKSB7XHJcbiAgICAgICAgICAgIGNvbEZpbHRlciA9IG1lLmdldEZpbHRlck9kYXRhKGNvbE5hbWUsIGNvbClcclxuICAgICAgICAgICAgaWYgKGNvbEZpbHRlcikge1xyXG4gICAgICAgICAgICAgIGZpbHRlci5wdXNoKGNvbEZpbHRlcilcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgY29uZGl0aW9uMSA9IG1lLmdldEZpbHRlck9kYXRhKGNvbE5hbWUsIGNvbC5jb25kaXRpb24xKVxyXG4gICAgICAgICAgICBjb25zdCBjb25kaXRpb24yID0gbWUuZ2V0RmlsdGVyT2RhdGEoY29sTmFtZSwgY29sLmNvbmRpdGlvbjIpXHJcbiAgICAgICAgICAgIGlmIChjb25kaXRpb24xICYmIGNvbmRpdGlvbjIpIHtcclxuICAgICAgICAgICAgICBjb2xGaWx0ZXIgPSBgKCR7Y29uZGl0aW9uMX0gJHtjb2wub3BlcmF0b3IudG9Mb3dlckNhc2UoKX0gJHtjb25kaXRpb24yfSlgXHJcbiAgICAgICAgICAgICAgZmlsdGVyLnB1c2goY29sRmlsdGVyKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgXHJcbiAgICAgIGxldCBwaXZvdEFjdGl2ZSA9IGZhbHNlXHJcbiAgXHJcbiAgICAgIGNvbnN0IGFwcGx5ID0gb3B0aW9ucy5hcHBseSB8fCBbXVxyXG4gICAgICBpZiAoaXNTZXJ2ZXJNb2RlKSB7XHJcbiAgICAgICAgY29uc3QgcmVxdWVzdFNydiA9IHJlcXVlc3QgYXMgSVNlcnZlclNpZGVHZXRSb3dzUmVxdWVzdFxyXG4gICAgICAgIHBpdm90QWN0aXZlID1cclxuICAgICAgICAgIHJlcXVlc3RTcnYucGl2b3RNb2RlICYmXHJcbiAgICAgICAgICByZXF1ZXN0U3J2LnBpdm90Q29scy5sZW5ndGggPiAwICYmXHJcbiAgICAgICAgICByZXF1ZXN0U3J2LnZhbHVlQ29scy5sZW5ndGggPiAwXHJcbiAgICAgICAgaWYgKHJlcXVlc3RTcnYucm93R3JvdXBDb2xzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgIGNvbnN0IGZpbHRlckdyb3VwQnk6IHN0cmluZ1tdID0gW11cclxuICAgICAgICAgIGlmIChyZXF1ZXN0U3J2Lmdyb3VwS2V5cy5sZW5ndGggPCByZXF1ZXN0U3J2LnJvd0dyb3VwQ29scy5sZW5ndGgpIHtcclxuICAgICAgICAgICAgLy8gSWYgcmVxdWVzdCBvbmx5IGdyb3Vwc1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCByZXF1ZXN0U3J2Lmdyb3VwS2V5cy5sZW5ndGg7IGlkeCsrKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgY29sVmFsdWUgPSByZXF1ZXN0U3J2Lmdyb3VwS2V5c1tpZHhdXHJcbiAgICAgICAgICAgICAgY29uc3QgY29uZGl0aW9uID0gYCR7bWUuZ2V0V3JhcENvbHVtbk5hbWUoXHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0U3J2LnJvd0dyb3VwQ29sc1tpZHhdLmZpZWxkXHJcbiAgICAgICAgICAgICAgKX0gZXEgJHtcclxuICAgICAgICAgICAgICAgIChtZS5pc1N0clZhbChjb2xWYWx1ZSkgPyBcIidcIiA6ICcnKSArXHJcbiAgICAgICAgICAgICAgICBtZS5lbmNvZGUoY29sVmFsdWUpICtcclxuICAgICAgICAgICAgICAgIChtZS5pc1N0clZhbChjb2xWYWx1ZSkgPyBcIidcIiA6ICcnKVxyXG4gICAgICAgICAgICAgIH1gXHJcbiAgICAgICAgICAgICAgZmlsdGVyR3JvdXBCeS5wdXNoKGNvbmRpdGlvbilcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoZmlsdGVyR3JvdXBCeS5sZW5ndGggPiAwIHx8IGZpbHRlci5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgLy8gRmlsdGVycyBtdXN0IGJ5IGZpcnN0XHJcbiAgICAgICAgICAgICAgYXBwbHkucHVzaChgZmlsdGVyKCR7ZmlsdGVyR3JvdXBCeS5jb25jYXQoZmlsdGVyKS5qb2luKCcgYW5kICcpfSlgKVxyXG4gICAgICAgICAgICB9XHJcbiAgXHJcbiAgICAgICAgICAgIGNvbnN0IGFnZ3JlZ2F0ZTogc3RyaW5nW10gPSBbXVxyXG4gICAgICAgICAgICBpZiAoY2hpbGRDb3VudCkge1xyXG4gICAgICAgICAgICAgIGFnZ3JlZ2F0ZS5wdXNoKG1lLm9kYXRhQWdncmVnYXRpb24uY291bnQoY2hpbGRDb3VudCkpXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKHJlcXVlc3RTcnYudmFsdWVDb2xzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCByZXF1ZXN0U3J2LnZhbHVlQ29scy5sZW5ndGg7IGlkeCsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xWYWx1ZSA9IHJlcXVlc3RTcnYudmFsdWVDb2xzW2lkeF1cclxuICAgICAgICAgICAgICAgIGNvbFZhbHVlLmFnZ0Z1bmMgJiZcclxuICAgICAgICAgICAgICAgICAgYWdncmVnYXRlLnB1c2goXHJcbiAgICAgICAgICAgICAgICAgICAgbWUub2RhdGFBZ2dyZWdhdGlvbltjb2xWYWx1ZS5hZ2dGdW5jXShcclxuICAgICAgICAgICAgICAgICAgICAgIG1lLmdldFdyYXBDb2x1bW5OYW1lKGNvbFZhbHVlLmZpZWxkKVxyXG4gICAgICAgICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICAgICAgKVxyXG4gICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBsZXQgZ3JvdXBzID0gW1xyXG4gICAgICAgICAgICAgIG1lLmdldFdyYXBDb2x1bW5OYW1lKFxyXG4gICAgICAgICAgICAgICAgcmVxdWVzdFNydi5yb3dHcm91cENvbHNbcmVxdWVzdFNydi5ncm91cEtleXMubGVuZ3RoXS5maWVsZFxyXG4gICAgICAgICAgICAgICksXHJcbiAgICAgICAgICAgIF1cclxuICAgICAgICAgICAgY29uc3Qgc29ydCA9IG9wdGlvbnMuc29ydCB8fCBbXVxyXG4gICAgICAgICAgICBjb25zdCBzb3J0Q29sT25seSA9IHNvcnQubWFwKCh4KSA9PiB4LnNwbGl0KCcgJylbMF0pXHJcbiAgICAgICAgICAgIGlmIChwaXZvdEFjdGl2ZSkge1xyXG4gICAgICAgICAgICAgIGdyb3VwcyA9IGdyb3Vwcy5jb25jYXQoXHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0U3J2LnBpdm90Q29scy5tYXAoKHgpID0+IG1lLmdldFdyYXBDb2x1bW5OYW1lKHguZmllbGQpKVxyXG4gICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgICBncm91cHMuZm9yRWFjaCgoeCkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYgKHNvcnRDb2xPbmx5LmluZGV4T2YoeCkgPCAwKSB7XHJcbiAgICAgICAgICAgICAgICAgIHNvcnQucHVzaCh4KVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgb3B0aW9ucy5zb3J0ID0gc29ydFxyXG4gICAgICAgICAgICBhcHBseS5wdXNoKFxyXG4gICAgICAgICAgICAgIGBncm91cGJ5KCgke2dyb3Vwcy5qb2luKCcsJyl9KSR7XHJcbiAgICAgICAgICAgICAgICBhZ2dyZWdhdGUubGVuZ3RoID4gMCA/IGAsYWdncmVnYXRlKCR7YWdncmVnYXRlLmpvaW4oJywnKX0pYCA6ICcnXHJcbiAgICAgICAgICAgICAgfSlgXHJcbiAgICAgICAgICAgIClcclxuICBcclxuICAgICAgICAgICAgb3B0aW9ucy5hcHBseSA9IGFwcGx5XHJcbiAgICAgICAgICAgIGlmIChvcHRpb25zLnNvcnQgJiYgb3B0aW9ucy5zb3J0Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICBvcHRpb25zLnNvcnQgPSBvcHRpb25zLnNvcnQuZmlsdGVyKFxyXG4gICAgICAgICAgICAgICAgKHgpID0+IGdyb3Vwcy5pbmRleE9mKHguc3BsaXQoJyAnKVswXSkgPj0gMFxyXG4gICAgICAgICAgICAgIClcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBkZWxldGUgb3B0aW9ucy5zb3J0O1xyXG4gICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgLy8gSWYgcmVxdWVzdCByb3dEYXRhIGJ5IGdyb3VwIGZpbHRlclxyXG4gICAgICAgICAgICBmb3IgKGxldCBpZHggPSAwOyBpZHggPCByZXF1ZXN0U3J2Lmdyb3VwS2V5cy5sZW5ndGg7IGlkeCsrKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgY29sVmFsdWUgPSByZXF1ZXN0U3J2Lmdyb3VwS2V5c1tpZHhdXHJcbiAgICAgICAgICAgICAgY29uc3QgY29uZGl0aW9uID0gYCR7bWUuZ2V0V3JhcENvbHVtbk5hbWUoXHJcbiAgICAgICAgICAgICAgICByZXF1ZXN0U3J2LnJvd0dyb3VwQ29sc1tpZHhdLmZpZWxkXHJcbiAgICAgICAgICAgICAgKX0gZXEgJHtcclxuICAgICAgICAgICAgICAgIChtZS5pc1N0clZhbChjb2xWYWx1ZSkgPyBcIidcIiA6ICcnKSArXHJcbiAgICAgICAgICAgICAgICBtZS5lbmNvZGUoY29sVmFsdWUpICtcclxuICAgICAgICAgICAgICAgIChtZS5pc1N0clZhbChjb2xWYWx1ZSkgPyBcIidcIiA6ICcnKVxyXG4gICAgICAgICAgICAgIH1gXHJcbiAgICAgICAgICAgICAgZmlsdGVyLnB1c2goY29uZGl0aW9uKVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICAgIGlmIChmaWx0ZXIubGVuZ3RoID4gMCkge1xyXG4gICAgICAgIG9wdGlvbnMuZmlsdGVyID0gZmlsdGVyXHJcbiAgICAgIH1cclxuICAgICAgaWYgKGFwcGx5Lmxlbmd0aCA+IDApIHtcclxuICAgICAgICBvcHRpb25zLmFwcGx5ID0gYXBwbHlcclxuICAgICAgICBkZWxldGUgb3B0aW9ucy5maWx0ZXJcclxuICAgICAgICBkZWxldGUgb3B0aW9ucy5leHBhbmRcclxuICAgICAgICBkZWxldGUgb3B0aW9ucy5zZWxlY3RcclxuICAgICAgICAvLyBvcHRpb25zLnNvcnQgPSBudWxsO1xyXG4gICAgICB9XHJcbiAgICAgIG9wdGlvbnMuc2tpcCA9IHJlcXVlc3Quc3RhcnRSb3dcclxuICAgICAgb3B0aW9ucy50b3AgPSAocmVxdWVzdC5lbmRSb3cgfHwgMCkgLSAocmVxdWVzdC5zdGFydFJvdyB8fCAwKVxyXG4gIFxyXG4gICAgICBpZiAoIW9wdGlvbnMuYXBwbHkgJiYgb3B0aW9ucy5za2lwID09PSAwKSB7XHJcbiAgICAgICAgb3B0aW9ucy5jb3VudCA9IHRydWVcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gb3B0aW9uc1xyXG4gICAgfVxyXG4gICAgLyoqXHJcbiAgICAgKiBHZW5lcmF0ZSBvZGF0YSBxdWVyeSBmcm9tIGFnLWdyaWQgcmVxdWVzdFxyXG4gICAgICogQHBhcmFtIHBhcmFtcyBhZy1ncmlkIGRldGFpbHMgZm9yIHRoZSByZXF1ZXN0XHJcbiAgICAgKi9cclxuICAgIGdldE9kYXRhUXVlcnkgPSAocGFyYW1zOiBJR2V0Um93c1BhcmFtcyB8IElTZXJ2ZXJTaWRlR2V0Um93c1BhcmFtcyk6IHN0cmluZyA9PlxyXG4gICAgICB0aGlzLnRvUXVlcnkodGhpcy5nZXRPZGF0YU9wdGlvbnMocGFyYW1zKSlcclxuICB9XHJcbiAgXHJcbiAgZXhwb3J0IGNsYXNzIE9kYXRhUHJvdmlkZXJDbGllbnQgZXh0ZW5kcyBPZGF0YVByb3ZpZGVyIHtcclxuICAgIHB1YmxpYyBvdmVycmlkZSBnZXRSb3dzKHBhcmFtczogSVNlcnZlclNpZGVHZXRSb3dzUGFyYW1zKSB7XHJcbiAgICAgIHN1cGVyLmdldFJvd3MocGFyYW1zKVxyXG4gICAgfVxyXG4gIH1cclxuICBleHBvcnQgY2xhc3MgT2RhdGFTZXJ2ZXJTaWRlUHJvdmlkZXIgZXh0ZW5kcyBPZGF0YVByb3ZpZGVyIHtcclxuICAgIHB1YmxpYyBvdmVycmlkZSBnZXRSb3dzKHBhcmFtczogSVNlcnZlclNpZGVHZXRSb3dzUGFyYW1zKTogdm9pZCB7XHJcbiAgICAgIHN1cGVyLmdldFJvd3MocGFyYW1zKVxyXG4gICAgfVxyXG4gIH0iXX0=
|