ultipa 6.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +65 -0
- package/dist/client.d.ts +194 -0
- package/dist/client.js +390 -0
- package/dist/config.d.ts +65 -0
- package/dist/config.js +135 -0
- package/dist/connection.d.ts +30 -0
- package/dist/connection.js +190 -0
- package/dist/errors.d.ts +99 -0
- package/dist/errors.js +237 -0
- package/dist/index.d.ts +14 -0
- package/dist/index.js +88 -0
- package/dist/printers.d.ts +33 -0
- package/dist/printers.js +312 -0
- package/dist/proto/gqldb.proto +632 -0
- package/dist/response.d.ts +256 -0
- package/dist/response.js +723 -0
- package/dist/services/admin-service.d.ts +40 -0
- package/dist/services/admin-service.js +115 -0
- package/dist/services/bulk-import-service.d.ts +35 -0
- package/dist/services/bulk-import-service.js +108 -0
- package/dist/services/converters.d.ts +57 -0
- package/dist/services/converters.js +254 -0
- package/dist/services/data-service.d.ts +44 -0
- package/dist/services/data-service.js +206 -0
- package/dist/services/graph-service.d.ts +32 -0
- package/dist/services/graph-service.js +127 -0
- package/dist/services/health-service.d.ts +50 -0
- package/dist/services/health-service.js +78 -0
- package/dist/services/index.d.ts +13 -0
- package/dist/services/index.js +30 -0
- package/dist/services/query-service.d.ts +39 -0
- package/dist/services/query-service.js +112 -0
- package/dist/services/service-context.d.ts +39 -0
- package/dist/services/service-context.js +73 -0
- package/dist/services/session-service.d.ts +24 -0
- package/dist/services/session-service.js +66 -0
- package/dist/services/transaction-service.d.ts +33 -0
- package/dist/services/transaction-service.js +100 -0
- package/dist/services.d.ts +28 -0
- package/dist/services.js +122 -0
- package/dist/session.d.ts +45 -0
- package/dist/session.js +75 -0
- package/dist/transaction.d.ts +42 -0
- package/dist/transaction.js +89 -0
- package/dist/types/bulk_import.d.ts +53 -0
- package/dist/types/bulk_import.js +6 -0
- package/dist/types/data_types.d.ts +116 -0
- package/dist/types/data_types.js +122 -0
- package/dist/types/enums.d.ts +59 -0
- package/dist/types/enums.js +67 -0
- package/dist/types/graph_models.d.ts +54 -0
- package/dist/types/graph_models.js +6 -0
- package/dist/types/index.d.ts +11 -0
- package/dist/types/index.js +36 -0
- package/dist/types/metadata.d.ts +60 -0
- package/dist/types/metadata.js +6 -0
- package/dist/types/schema.d.ts +31 -0
- package/dist/types/schema.js +6 -0
- package/dist/types/typed_value.d.ts +25 -0
- package/dist/types/typed_value.js +1176 -0
- package/dist/types/wrappers.d.ts +23 -0
- package/dist/types/wrappers.js +39 -0
- package/dist/types.d.ts +7 -0
- package/dist/types.js +24 -0
- package/package.json +50 -0
package/dist/response.js
ADDED
|
@@ -0,0 +1,723 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Response handling for GQLDB Node.js driver.
|
|
4
|
+
*/
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
exports.Response = exports.AliasResult = exports.Row = void 0;
|
|
7
|
+
const types_1 = require("./types");
|
|
8
|
+
/** Represents a single row in the query result */
|
|
9
|
+
class Row {
|
|
10
|
+
values;
|
|
11
|
+
types;
|
|
12
|
+
constructor(values, types = []) {
|
|
13
|
+
this.values = values;
|
|
14
|
+
this.types = types;
|
|
15
|
+
}
|
|
16
|
+
/** Get the value at the given column index */
|
|
17
|
+
get(index) {
|
|
18
|
+
if (index < 0 || index >= this.values.length) {
|
|
19
|
+
throw new Error(`Column index out of range: ${index}`);
|
|
20
|
+
}
|
|
21
|
+
const value = this.values[index];
|
|
22
|
+
// If value is a TypedValue object, convert it
|
|
23
|
+
if (value && typeof value === 'object' && 'type' in value && 'data' in value && 'isNull' in value) {
|
|
24
|
+
return (0, types_1.typedValueToJS)(value);
|
|
25
|
+
}
|
|
26
|
+
return value;
|
|
27
|
+
}
|
|
28
|
+
/** Get the PropertyType at the given column index */
|
|
29
|
+
getType(index) {
|
|
30
|
+
if (index < 0 || index >= this.types.length) {
|
|
31
|
+
return types_1.PropertyType.UNSET;
|
|
32
|
+
}
|
|
33
|
+
return this.types[index];
|
|
34
|
+
}
|
|
35
|
+
/** Get the value at the given column index as a string */
|
|
36
|
+
getString(index) {
|
|
37
|
+
const val = this.get(index);
|
|
38
|
+
if (val === null || val === undefined)
|
|
39
|
+
return '';
|
|
40
|
+
if (typeof val === 'string')
|
|
41
|
+
return val;
|
|
42
|
+
return String(val);
|
|
43
|
+
}
|
|
44
|
+
/** Get the value at the given column index as a number */
|
|
45
|
+
getNumber(index) {
|
|
46
|
+
const val = this.get(index);
|
|
47
|
+
if (val === null || val === undefined)
|
|
48
|
+
return 0;
|
|
49
|
+
if (typeof val === 'number')
|
|
50
|
+
return val;
|
|
51
|
+
const num = Number(val);
|
|
52
|
+
if (isNaN(num))
|
|
53
|
+
throw new Error(`Cannot convert ${typeof val} to number`);
|
|
54
|
+
return num;
|
|
55
|
+
}
|
|
56
|
+
/** Get the value at the given column index as a boolean */
|
|
57
|
+
getBoolean(index) {
|
|
58
|
+
const val = this.get(index);
|
|
59
|
+
if (val === null || val === undefined)
|
|
60
|
+
return false;
|
|
61
|
+
if (typeof val === 'boolean')
|
|
62
|
+
return val;
|
|
63
|
+
throw new Error(`Cannot convert ${typeof val} to boolean`);
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
exports.Row = Row;
|
|
67
|
+
/**
|
|
68
|
+
* Represents a single column's data from the response.
|
|
69
|
+
* Allows chaining operations like resp.alias("n").asNodes() or resp.get(0).asNodes().
|
|
70
|
+
*/
|
|
71
|
+
class AliasResult {
|
|
72
|
+
aliasName;
|
|
73
|
+
columnIdx;
|
|
74
|
+
response;
|
|
75
|
+
constructor(aliasName, columnIdx, response) {
|
|
76
|
+
this.aliasName = aliasName;
|
|
77
|
+
this.columnIdx = columnIdx;
|
|
78
|
+
this.response = response;
|
|
79
|
+
}
|
|
80
|
+
/** Get the alias name */
|
|
81
|
+
get alias() {
|
|
82
|
+
return this.aliasName;
|
|
83
|
+
}
|
|
84
|
+
/** Get the column index */
|
|
85
|
+
get columnIndex() {
|
|
86
|
+
return this.columnIdx;
|
|
87
|
+
}
|
|
88
|
+
/**
|
|
89
|
+
* Extract nodes from the aliased column with schema info.
|
|
90
|
+
* Throws TypeError if the column contains non-NODE types.
|
|
91
|
+
*/
|
|
92
|
+
collectNode(val, nodes, schemas) {
|
|
93
|
+
if (val && typeof val.id === 'string' && 'labels' in val) {
|
|
94
|
+
const node = {
|
|
95
|
+
id: val.id,
|
|
96
|
+
labels: val.labels || [],
|
|
97
|
+
properties: val.properties || {},
|
|
98
|
+
};
|
|
99
|
+
nodes.push(node);
|
|
100
|
+
for (const label of node.labels) {
|
|
101
|
+
if (!schemas.has(label)) {
|
|
102
|
+
schemas.set(label, this.buildSchemaFromNode(label, node));
|
|
103
|
+
}
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
collectEdge(val, edges, schemas) {
|
|
108
|
+
if (val && typeof val.id === 'string' && 'label' in val) {
|
|
109
|
+
const edge = {
|
|
110
|
+
id: val.id,
|
|
111
|
+
label: val.label || '',
|
|
112
|
+
fromNodeId: val.fromNodeId || '',
|
|
113
|
+
toNodeId: val.toNodeId || '',
|
|
114
|
+
properties: val.properties || {},
|
|
115
|
+
};
|
|
116
|
+
edges.push(edge);
|
|
117
|
+
if (edge.label && !schemas.has(edge.label)) {
|
|
118
|
+
schemas.set(edge.label, this.buildSchemaFromEdge(edge.label, edge));
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
/**
|
|
123
|
+
* Extract nodes from the aliased column with schema info.
|
|
124
|
+
* Supports both direct NODE columns and LIST of NODE columns
|
|
125
|
+
* (e.g., group variables from quantified patterns).
|
|
126
|
+
*/
|
|
127
|
+
asNodes() {
|
|
128
|
+
const nodes = [];
|
|
129
|
+
const schemas = new Map();
|
|
130
|
+
for (const row of this.response.rows) {
|
|
131
|
+
if (this.columnIdx >= row.values.length) {
|
|
132
|
+
continue;
|
|
133
|
+
}
|
|
134
|
+
let itemType = row.getType(this.columnIdx);
|
|
135
|
+
const rawValue = row.values[this.columnIdx];
|
|
136
|
+
if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
|
|
137
|
+
itemType = rawValue.type;
|
|
138
|
+
}
|
|
139
|
+
if (!rawValue || (typeof rawValue === 'object' && 'isNull' in rawValue && rawValue.isNull)) {
|
|
140
|
+
continue;
|
|
141
|
+
}
|
|
142
|
+
if (itemType === types_1.PropertyType.NODE) {
|
|
143
|
+
this.collectNode(row.get(this.columnIdx), nodes, schemas);
|
|
144
|
+
}
|
|
145
|
+
else if (itemType === types_1.PropertyType.LIST) {
|
|
146
|
+
// LIST of NODE (group variable from quantified pattern)
|
|
147
|
+
const list = row.get(this.columnIdx);
|
|
148
|
+
if (Array.isArray(list)) {
|
|
149
|
+
for (const item of list) {
|
|
150
|
+
this.collectNode(item, nodes, schemas);
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
else {
|
|
155
|
+
throw new TypeError(`Type mismatch: column '${this.aliasName}' (index ${this.columnIdx}) contains ${types_1.PropertyType[itemType]}, expected NODE or LIST of NODE`);
|
|
156
|
+
}
|
|
157
|
+
}
|
|
158
|
+
return { nodes, schemas };
|
|
159
|
+
}
|
|
160
|
+
/**
|
|
161
|
+
* Extract edges from the aliased column with schema info.
|
|
162
|
+
* Supports both direct EDGE columns and LIST of EDGE columns
|
|
163
|
+
* (e.g., group variables from quantified patterns).
|
|
164
|
+
*/
|
|
165
|
+
asEdges() {
|
|
166
|
+
const edges = [];
|
|
167
|
+
const schemas = new Map();
|
|
168
|
+
for (const row of this.response.rows) {
|
|
169
|
+
if (this.columnIdx >= row.values.length) {
|
|
170
|
+
continue;
|
|
171
|
+
}
|
|
172
|
+
let itemType = row.getType(this.columnIdx);
|
|
173
|
+
const rawValue = row.values[this.columnIdx];
|
|
174
|
+
if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
|
|
175
|
+
itemType = rawValue.type;
|
|
176
|
+
}
|
|
177
|
+
if (!rawValue || (typeof rawValue === 'object' && 'isNull' in rawValue && rawValue.isNull)) {
|
|
178
|
+
continue;
|
|
179
|
+
}
|
|
180
|
+
if (itemType === types_1.PropertyType.EDGE) {
|
|
181
|
+
this.collectEdge(row.get(this.columnIdx), edges, schemas);
|
|
182
|
+
}
|
|
183
|
+
else if (itemType === types_1.PropertyType.LIST) {
|
|
184
|
+
// LIST of EDGE (group variable from quantified pattern)
|
|
185
|
+
const list = row.get(this.columnIdx);
|
|
186
|
+
if (Array.isArray(list)) {
|
|
187
|
+
for (const item of list) {
|
|
188
|
+
this.collectEdge(item, edges, schemas);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
throw new TypeError(`Type mismatch: column '${this.aliasName}' (index ${this.columnIdx}) contains ${types_1.PropertyType[itemType]}, expected EDGE or LIST of EDGE`);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return { edges, schemas };
|
|
197
|
+
}
|
|
198
|
+
/**
|
|
199
|
+
* Extract paths from the aliased column.
|
|
200
|
+
* Throws TypeError if the column contains non-PATH types.
|
|
201
|
+
*/
|
|
202
|
+
asPaths() {
|
|
203
|
+
const paths = [];
|
|
204
|
+
for (const row of this.response.rows) {
|
|
205
|
+
if (this.columnIdx >= row.values.length) {
|
|
206
|
+
continue;
|
|
207
|
+
}
|
|
208
|
+
// Check type from types array or from TypedValue object
|
|
209
|
+
let itemType = row.getType(this.columnIdx);
|
|
210
|
+
const rawValue = row.values[this.columnIdx];
|
|
211
|
+
if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
|
|
212
|
+
itemType = rawValue.type;
|
|
213
|
+
}
|
|
214
|
+
// Skip null values
|
|
215
|
+
if (!rawValue || (typeof rawValue === 'object' && 'isNull' in rawValue && rawValue.isNull)) {
|
|
216
|
+
continue;
|
|
217
|
+
}
|
|
218
|
+
// Type checking: must be PATH type
|
|
219
|
+
if (itemType !== types_1.PropertyType.PATH) {
|
|
220
|
+
throw new TypeError(`Type mismatch: column '${this.aliasName}' (index ${this.columnIdx}) contains ${types_1.PropertyType[itemType]}, expected PATH`);
|
|
221
|
+
}
|
|
222
|
+
// Convert TypedValue to GqldbPath
|
|
223
|
+
const val = row.get(this.columnIdx);
|
|
224
|
+
if (val && Array.isArray(val.nodes)) {
|
|
225
|
+
// Convert GqldbNode/GqldbEdge to Node/Edge
|
|
226
|
+
const nodes = (val.nodes || []).map((n) => ({
|
|
227
|
+
id: n.id || '',
|
|
228
|
+
labels: n.labels || [],
|
|
229
|
+
properties: n.properties || {},
|
|
230
|
+
}));
|
|
231
|
+
const edges = (val.edges || []).map((e) => ({
|
|
232
|
+
id: e.id || '',
|
|
233
|
+
label: e.label || '',
|
|
234
|
+
fromNodeId: e.fromNodeId || '',
|
|
235
|
+
toNodeId: e.toNodeId || '',
|
|
236
|
+
properties: e.properties || {},
|
|
237
|
+
}));
|
|
238
|
+
paths.push({ nodes, edges });
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
return paths;
|
|
242
|
+
}
|
|
243
|
+
/** Convert the aliased column to a single-column table */
|
|
244
|
+
asTable() {
|
|
245
|
+
// Check if first non-null value is a GqldbTable — if so, unwrap it
|
|
246
|
+
for (const row of this.response.rows) {
|
|
247
|
+
if (this.columnIdx < row.values.length) {
|
|
248
|
+
const itemType = row.getType(this.columnIdx);
|
|
249
|
+
if (itemType === types_1.PropertyType.TABLE) {
|
|
250
|
+
const val = row.get(this.columnIdx);
|
|
251
|
+
if (val && 'columns' in val && 'rows' in val) {
|
|
252
|
+
return this.unwrapGqldbTable(val);
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
break; // only check first row
|
|
257
|
+
}
|
|
258
|
+
// Fallback: generic single-column table
|
|
259
|
+
const headers = [{
|
|
260
|
+
name: this.aliasName,
|
|
261
|
+
type: types_1.PropertyType.UNSET,
|
|
262
|
+
}];
|
|
263
|
+
if (this.response.rows.length > 0) {
|
|
264
|
+
for (const row of this.response.rows) {
|
|
265
|
+
if (this.columnIdx < row.values.length) {
|
|
266
|
+
const type = row.getType(this.columnIdx);
|
|
267
|
+
if (type !== types_1.PropertyType.UNSET) {
|
|
268
|
+
headers[0].type = type;
|
|
269
|
+
break;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
const tableRows = this.response.rows.map(row => {
|
|
275
|
+
if (this.columnIdx < row.values.length) {
|
|
276
|
+
return [row.get(this.columnIdx)];
|
|
277
|
+
}
|
|
278
|
+
return [null];
|
|
279
|
+
});
|
|
280
|
+
return { name: '', headers, rows: tableRows };
|
|
281
|
+
}
|
|
282
|
+
unwrapGqldbTable(gt) {
|
|
283
|
+
const headers = gt.columns.map((col, i) => {
|
|
284
|
+
let colType = types_1.PropertyType.UNSET;
|
|
285
|
+
if (gt.rows.length > 0 && i < gt.rows[0].length) {
|
|
286
|
+
const v = gt.rows[0][i];
|
|
287
|
+
if (typeof v === 'number')
|
|
288
|
+
colType = Number.isInteger(v) ? types_1.PropertyType.INT64 : types_1.PropertyType.DOUBLE;
|
|
289
|
+
else if (typeof v === 'string')
|
|
290
|
+
colType = types_1.PropertyType.STRING;
|
|
291
|
+
else if (typeof v === 'boolean')
|
|
292
|
+
colType = types_1.PropertyType.BOOL;
|
|
293
|
+
}
|
|
294
|
+
return { name: col, type: colType };
|
|
295
|
+
});
|
|
296
|
+
return { name: this.aliasName, headers, rows: gt.rows };
|
|
297
|
+
}
|
|
298
|
+
/** Extract scalar or list attribute values from the aliased column */
|
|
299
|
+
asAttr() {
|
|
300
|
+
const values = [];
|
|
301
|
+
let attrType = types_1.PropertyType.UNSET;
|
|
302
|
+
for (const row of this.response.rows) {
|
|
303
|
+
if (this.columnIdx < row.values.length) {
|
|
304
|
+
// Try to get type from row.types first, then from TypedValue object
|
|
305
|
+
if (attrType === types_1.PropertyType.UNSET) {
|
|
306
|
+
attrType = row.getType(this.columnIdx);
|
|
307
|
+
if (attrType === types_1.PropertyType.UNSET) {
|
|
308
|
+
const rawValue = row.values[this.columnIdx];
|
|
309
|
+
if (rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
|
|
310
|
+
attrType = rawValue.type;
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
}
|
|
314
|
+
const value = row.get(this.columnIdx); // Use get() to convert TypedValue
|
|
315
|
+
values.push(value);
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
return { name: this.aliasName, type: attrType, values };
|
|
319
|
+
}
|
|
320
|
+
/** Extract raw JavaScript values from the aliased column */
|
|
321
|
+
asValues() {
|
|
322
|
+
const values = [];
|
|
323
|
+
for (const row of this.response.rows) {
|
|
324
|
+
if (this.columnIdx < row.values.length) {
|
|
325
|
+
values.push(row.get(this.columnIdx));
|
|
326
|
+
}
|
|
327
|
+
}
|
|
328
|
+
return values;
|
|
329
|
+
}
|
|
330
|
+
// Helper methods
|
|
331
|
+
buildSchemaFromNode(label, node) {
|
|
332
|
+
const properties = Object.entries(node.properties).map(([name, value]) => ({
|
|
333
|
+
name,
|
|
334
|
+
type: this.inferPropertyType(value),
|
|
335
|
+
}));
|
|
336
|
+
return { name: label, properties };
|
|
337
|
+
}
|
|
338
|
+
buildSchemaFromEdge(label, edge) {
|
|
339
|
+
const properties = Object.entries(edge.properties).map(([name, value]) => ({
|
|
340
|
+
name,
|
|
341
|
+
type: this.inferPropertyType(value),
|
|
342
|
+
}));
|
|
343
|
+
return { name: label, properties };
|
|
344
|
+
}
|
|
345
|
+
inferPropertyType(value) {
|
|
346
|
+
if (value === null || value === undefined)
|
|
347
|
+
return types_1.PropertyType.NULL;
|
|
348
|
+
if (typeof value === 'boolean')
|
|
349
|
+
return types_1.PropertyType.BOOL;
|
|
350
|
+
if (typeof value === 'number') {
|
|
351
|
+
return Number.isInteger(value) ? types_1.PropertyType.INT64 : types_1.PropertyType.DOUBLE;
|
|
352
|
+
}
|
|
353
|
+
if (typeof value === 'string')
|
|
354
|
+
return types_1.PropertyType.STRING;
|
|
355
|
+
if (Buffer.isBuffer(value))
|
|
356
|
+
return types_1.PropertyType.BLOB;
|
|
357
|
+
if (Array.isArray(value))
|
|
358
|
+
return types_1.PropertyType.LIST;
|
|
359
|
+
if (typeof value === 'object')
|
|
360
|
+
return types_1.PropertyType.MAP;
|
|
361
|
+
return types_1.PropertyType.UNSET;
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
exports.AliasResult = AliasResult;
|
|
365
|
+
/** Represents the result of a GQL query */
|
|
366
|
+
class Response {
|
|
367
|
+
columns;
|
|
368
|
+
rows;
|
|
369
|
+
rowCount;
|
|
370
|
+
hasMore;
|
|
371
|
+
warnings;
|
|
372
|
+
rowsAffected;
|
|
373
|
+
constructor(columns, rows, rowCount, hasMore, warnings, rowsAffected = 0) {
|
|
374
|
+
this.columns = columns;
|
|
375
|
+
this.rows = rows;
|
|
376
|
+
this.rowCount = rowCount;
|
|
377
|
+
this.hasMore = hasMore;
|
|
378
|
+
this.warnings = warnings;
|
|
379
|
+
this.rowsAffected = rowsAffected;
|
|
380
|
+
}
|
|
381
|
+
/** Check if the response has no rows */
|
|
382
|
+
isEmpty() {
|
|
383
|
+
return this.rows.length === 0;
|
|
384
|
+
}
|
|
385
|
+
/** Get the first row */
|
|
386
|
+
first() {
|
|
387
|
+
return this.rows[0];
|
|
388
|
+
}
|
|
389
|
+
/** Get the last row */
|
|
390
|
+
last() {
|
|
391
|
+
return this.rows[this.rows.length - 1];
|
|
392
|
+
}
|
|
393
|
+
/** Get the value for a column by name */
|
|
394
|
+
getByName(row, columnName) {
|
|
395
|
+
const index = this.columns.indexOf(columnName);
|
|
396
|
+
if (index === -1) {
|
|
397
|
+
throw new Error(`Column not found: ${columnName}`);
|
|
398
|
+
}
|
|
399
|
+
return row.get(index);
|
|
400
|
+
}
|
|
401
|
+
/** Iterate over all rows with a callback */
|
|
402
|
+
forEach(fn) {
|
|
403
|
+
this.rows.forEach(fn);
|
|
404
|
+
}
|
|
405
|
+
/** Transform each row using a callback */
|
|
406
|
+
map(fn) {
|
|
407
|
+
return this.rows.map(fn);
|
|
408
|
+
}
|
|
409
|
+
/** Convert the response to an array of objects */
|
|
410
|
+
toObjects() {
|
|
411
|
+
return this.rows.map(row => {
|
|
412
|
+
const obj = {};
|
|
413
|
+
this.columns.forEach((col, i) => {
|
|
414
|
+
// Add boundary check to handle mismatched columns/values
|
|
415
|
+
obj[col] = i < row.values.length ? row.get(i) : null;
|
|
416
|
+
});
|
|
417
|
+
return obj;
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
/** Convert the response to JSON */
|
|
421
|
+
toJSON() {
|
|
422
|
+
return JSON.stringify(this.toObjects());
|
|
423
|
+
}
|
|
424
|
+
/** Get the single value from a single-row, single-column response */
|
|
425
|
+
singleValue() {
|
|
426
|
+
if (this.rows.length === 0)
|
|
427
|
+
return null;
|
|
428
|
+
if (this.rows.length > 1) {
|
|
429
|
+
throw new Error(`Expected single row, got ${this.rows.length}`);
|
|
430
|
+
}
|
|
431
|
+
if (this.rows[0].values.length === 0)
|
|
432
|
+
return null;
|
|
433
|
+
if (this.rows[0].values.length > 1) {
|
|
434
|
+
throw new Error(`Expected single column, got ${this.rows[0].values.length}`);
|
|
435
|
+
}
|
|
436
|
+
return this.rows[0].get(0);
|
|
437
|
+
}
|
|
438
|
+
/** Get the single number value */
|
|
439
|
+
singleNumber() {
|
|
440
|
+
const val = this.singleValue();
|
|
441
|
+
if (val === null || val === undefined)
|
|
442
|
+
return 0;
|
|
443
|
+
if (typeof val === 'number')
|
|
444
|
+
return val;
|
|
445
|
+
const num = Number(val);
|
|
446
|
+
if (isNaN(num))
|
|
447
|
+
throw new Error(`Cannot convert ${typeof val} to number`);
|
|
448
|
+
return num;
|
|
449
|
+
}
|
|
450
|
+
/** Get the single string value */
|
|
451
|
+
singleString() {
|
|
452
|
+
const val = this.singleValue();
|
|
453
|
+
if (val === null || val === undefined)
|
|
454
|
+
return '';
|
|
455
|
+
if (typeof val === 'string')
|
|
456
|
+
return val;
|
|
457
|
+
return String(val);
|
|
458
|
+
}
|
|
459
|
+
/** Iterator support */
|
|
460
|
+
[Symbol.iterator]() {
|
|
461
|
+
return this.rows[Symbol.iterator]();
|
|
462
|
+
}
|
|
463
|
+
/** Get the number of rows */
|
|
464
|
+
get length() {
|
|
465
|
+
return this.rows.length;
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Get an AliasResult for the specified column name.
|
|
469
|
+
* Use this to extract data from a specific column by name.
|
|
470
|
+
* Example: resp.alias("n").asNodes()
|
|
471
|
+
*/
|
|
472
|
+
alias(columnName) {
|
|
473
|
+
const colIdx = this.columns.indexOf(columnName);
|
|
474
|
+
if (colIdx === -1) {
|
|
475
|
+
throw new Error(`Column alias not found: ${columnName}`);
|
|
476
|
+
}
|
|
477
|
+
return new AliasResult(columnName, colIdx, this);
|
|
478
|
+
}
|
|
479
|
+
/**
|
|
480
|
+
* Get an AliasResult for the column at the specified index.
|
|
481
|
+
* Use this to extract data from a specific column by index.
|
|
482
|
+
* Example: resp.get(0).asNodes()
|
|
483
|
+
*/
|
|
484
|
+
get(index) {
|
|
485
|
+
if (index < 0 || index >= this.columns.length) {
|
|
486
|
+
throw new Error(`Column index out of range: ${index} (total: ${this.columns.length})`);
|
|
487
|
+
}
|
|
488
|
+
return new AliasResult(this.columns[index], index, this);
|
|
489
|
+
}
|
|
490
|
+
/**
|
|
491
|
+
* @deprecated Use alias() or get() instead. This method will be removed in a future version.
|
|
492
|
+
* Extract nodes from response with schema info.
|
|
493
|
+
* Supports both NODE and LIST of NODE columns.
|
|
494
|
+
*/
|
|
495
|
+
asNodes() {
|
|
496
|
+
const nodes = [];
|
|
497
|
+
const schemas = new Map();
|
|
498
|
+
const collectNode = (val) => {
|
|
499
|
+
if (val && typeof val.id === 'string' && 'labels' in val) {
|
|
500
|
+
const node = {
|
|
501
|
+
id: val.id,
|
|
502
|
+
labels: val.labels || [],
|
|
503
|
+
properties: val.properties || {},
|
|
504
|
+
};
|
|
505
|
+
nodes.push(node);
|
|
506
|
+
for (const label of node.labels) {
|
|
507
|
+
if (!schemas.has(label)) {
|
|
508
|
+
schemas.set(label, this.buildSchemaFromNode(label, node));
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
}
|
|
512
|
+
};
|
|
513
|
+
for (const row of this.rows) {
|
|
514
|
+
for (let i = 0; i < row.values.length; i++) {
|
|
515
|
+
let itemType = row.getType(i);
|
|
516
|
+
const rawValue = row.values[i];
|
|
517
|
+
if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
|
|
518
|
+
itemType = rawValue.type;
|
|
519
|
+
}
|
|
520
|
+
if (itemType === types_1.PropertyType.NODE) {
|
|
521
|
+
collectNode(row.get(i));
|
|
522
|
+
}
|
|
523
|
+
else if (itemType === types_1.PropertyType.LIST) {
|
|
524
|
+
const list = row.get(i);
|
|
525
|
+
if (Array.isArray(list)) {
|
|
526
|
+
for (const item of list) {
|
|
527
|
+
collectNode(item);
|
|
528
|
+
}
|
|
529
|
+
}
|
|
530
|
+
}
|
|
531
|
+
}
|
|
532
|
+
}
|
|
533
|
+
return { nodes, schemas };
|
|
534
|
+
}
|
|
535
|
+
/**
|
|
536
|
+
* @deprecated Use alias() or get() instead. This method will be removed in a future version.
|
|
537
|
+
* Extract edges from response with schema info.
|
|
538
|
+
* Supports both EDGE and LIST of EDGE columns.
|
|
539
|
+
*/
|
|
540
|
+
asEdges() {
|
|
541
|
+
const edges = [];
|
|
542
|
+
const schemas = new Map();
|
|
543
|
+
const collectEdge = (val) => {
|
|
544
|
+
if (val && typeof val.id === 'string' && 'label' in val) {
|
|
545
|
+
const edge = {
|
|
546
|
+
id: val.id,
|
|
547
|
+
label: val.label || '',
|
|
548
|
+
fromNodeId: val.fromNodeId || '',
|
|
549
|
+
toNodeId: val.toNodeId || '',
|
|
550
|
+
properties: val.properties || {},
|
|
551
|
+
};
|
|
552
|
+
edges.push(edge);
|
|
553
|
+
if (edge.label && !schemas.has(edge.label)) {
|
|
554
|
+
schemas.set(edge.label, this.buildSchemaFromEdge(edge.label, edge));
|
|
555
|
+
}
|
|
556
|
+
}
|
|
557
|
+
};
|
|
558
|
+
for (const row of this.rows) {
|
|
559
|
+
for (let i = 0; i < row.values.length; i++) {
|
|
560
|
+
let itemType = row.getType(i);
|
|
561
|
+
const rawValue = row.values[i];
|
|
562
|
+
if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
|
|
563
|
+
itemType = rawValue.type;
|
|
564
|
+
}
|
|
565
|
+
if (itemType === types_1.PropertyType.EDGE) {
|
|
566
|
+
collectEdge(row.get(i));
|
|
567
|
+
}
|
|
568
|
+
else if (itemType === types_1.PropertyType.LIST) {
|
|
569
|
+
const list = row.get(i);
|
|
570
|
+
if (Array.isArray(list)) {
|
|
571
|
+
for (const item of list) {
|
|
572
|
+
collectEdge(item);
|
|
573
|
+
}
|
|
574
|
+
}
|
|
575
|
+
}
|
|
576
|
+
}
|
|
577
|
+
}
|
|
578
|
+
return { edges, schemas };
|
|
579
|
+
}
|
|
580
|
+
/**
|
|
581
|
+
* @deprecated Use alias() or get() instead. This method will be removed in a future version.
|
|
582
|
+
* Extract paths from response.
|
|
583
|
+
* Paths are identified by PropertyType.PATH type in the TypedValue.
|
|
584
|
+
*/
|
|
585
|
+
asPaths() {
|
|
586
|
+
const paths = [];
|
|
587
|
+
for (const row of this.rows) {
|
|
588
|
+
for (let i = 0; i < row.values.length; i++) {
|
|
589
|
+
// Check type from types array or from TypedValue object
|
|
590
|
+
let itemType = row.getType(i);
|
|
591
|
+
const rawValue = row.values[i];
|
|
592
|
+
if (itemType === types_1.PropertyType.UNSET && rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
|
|
593
|
+
itemType = rawValue.type;
|
|
594
|
+
}
|
|
595
|
+
if (itemType === types_1.PropertyType.PATH) {
|
|
596
|
+
// Convert TypedValue to GqldbPath
|
|
597
|
+
const val = row.get(i);
|
|
598
|
+
if (val && Array.isArray(val.nodes)) {
|
|
599
|
+
// Convert GqldbNode/GqldbEdge to Node/Edge
|
|
600
|
+
const nodes = (val.nodes || []).map((n) => ({
|
|
601
|
+
id: n.id || '',
|
|
602
|
+
labels: n.labels || [],
|
|
603
|
+
properties: n.properties || {},
|
|
604
|
+
}));
|
|
605
|
+
const edges = (val.edges || []).map((e) => ({
|
|
606
|
+
id: e.id || '',
|
|
607
|
+
label: e.label || '',
|
|
608
|
+
fromNodeId: e.fromNodeId || '',
|
|
609
|
+
toNodeId: e.toNodeId || '',
|
|
610
|
+
properties: e.properties || {},
|
|
611
|
+
}));
|
|
612
|
+
paths.push({ nodes, edges });
|
|
613
|
+
}
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
}
|
|
617
|
+
return paths;
|
|
618
|
+
}
|
|
619
|
+
/**
|
|
620
|
+
* @deprecated Use alias() or get() instead. This method will be removed in a future version.
|
|
621
|
+
* Return response as generic table.
|
|
622
|
+
* If response is a single TABLE column, unwraps the GqldbTable into proper headers/rows.
|
|
623
|
+
*/
|
|
624
|
+
asTable() {
|
|
625
|
+
// If single column of TABLE type, unwrap GqldbTable
|
|
626
|
+
if (this.columns.length === 1 && this.rows.length > 0) {
|
|
627
|
+
const itemType = this.rows[0].getType(0);
|
|
628
|
+
if (itemType === types_1.PropertyType.TABLE) {
|
|
629
|
+
const val = this.rows[0].get(0);
|
|
630
|
+
if (val && 'columns' in val && 'rows' in val) {
|
|
631
|
+
const gt = val;
|
|
632
|
+
const headers = gt.columns.map((col, i) => {
|
|
633
|
+
let colType = types_1.PropertyType.UNSET;
|
|
634
|
+
if (gt.rows.length > 0 && i < gt.rows[0].length) {
|
|
635
|
+
const v = gt.rows[0][i];
|
|
636
|
+
if (typeof v === 'number')
|
|
637
|
+
colType = Number.isInteger(v) ? types_1.PropertyType.INT64 : types_1.PropertyType.DOUBLE;
|
|
638
|
+
else if (typeof v === 'string')
|
|
639
|
+
colType = types_1.PropertyType.STRING;
|
|
640
|
+
else if (typeof v === 'boolean')
|
|
641
|
+
colType = types_1.PropertyType.BOOL;
|
|
642
|
+
}
|
|
643
|
+
return { name: col, type: colType };
|
|
644
|
+
});
|
|
645
|
+
return { name: this.columns[0], headers, rows: gt.rows };
|
|
646
|
+
}
|
|
647
|
+
}
|
|
648
|
+
}
|
|
649
|
+
// Fallback: generic multi-column table
|
|
650
|
+
const headers = this.columns.map(col => ({
|
|
651
|
+
name: col,
|
|
652
|
+
type: types_1.PropertyType.UNSET,
|
|
653
|
+
}));
|
|
654
|
+
const tableRows = this.rows.map(row => {
|
|
655
|
+
return this.columns.map((_, i) => (i < row.values.length ? row.get(i) : null));
|
|
656
|
+
});
|
|
657
|
+
return { name: '', headers, rows: tableRows };
|
|
658
|
+
}
|
|
659
|
+
/**
|
|
660
|
+
* @deprecated Use alias() or get() instead. This method will be removed in a future version.
|
|
661
|
+
* Extract scalar or list attribute values
|
|
662
|
+
*/
|
|
663
|
+
asAttr(columnName) {
|
|
664
|
+
const colIndex = this.columns.indexOf(columnName);
|
|
665
|
+
if (colIndex === -1) {
|
|
666
|
+
throw new Error(`Column not found: ${columnName}`);
|
|
667
|
+
}
|
|
668
|
+
const values = [];
|
|
669
|
+
let attrType = types_1.PropertyType.UNSET;
|
|
670
|
+
for (const row of this.rows) {
|
|
671
|
+
if (colIndex < row.values.length) {
|
|
672
|
+
// Try to get type from row.types first, then from TypedValue object
|
|
673
|
+
if (attrType === types_1.PropertyType.UNSET) {
|
|
674
|
+
attrType = row.getType(colIndex);
|
|
675
|
+
if (attrType === types_1.PropertyType.UNSET) {
|
|
676
|
+
const rawValue = row.values[colIndex];
|
|
677
|
+
if (rawValue && typeof rawValue === 'object' && 'type' in rawValue) {
|
|
678
|
+
attrType = rawValue.type;
|
|
679
|
+
}
|
|
680
|
+
}
|
|
681
|
+
}
|
|
682
|
+
const value = row.get(colIndex); // Use get() to convert TypedValue
|
|
683
|
+
values.push(value);
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
return { name: columnName, type: attrType, values };
|
|
687
|
+
}
|
|
688
|
+
// Helper methods
|
|
689
|
+
buildSchemaFromNode(label, node) {
|
|
690
|
+
const properties = Object.entries(node.properties).map(([name, value]) => ({
|
|
691
|
+
name,
|
|
692
|
+
type: this.inferPropertyType(value),
|
|
693
|
+
}));
|
|
694
|
+
return { name: label, properties };
|
|
695
|
+
}
|
|
696
|
+
buildSchemaFromEdge(label, edge) {
|
|
697
|
+
const properties = Object.entries(edge.properties).map(([name, value]) => ({
|
|
698
|
+
name,
|
|
699
|
+
type: this.inferPropertyType(value),
|
|
700
|
+
}));
|
|
701
|
+
return { name: label, properties };
|
|
702
|
+
}
|
|
703
|
+
inferPropertyType(value) {
|
|
704
|
+
if (value === null || value === undefined)
|
|
705
|
+
return types_1.PropertyType.NULL;
|
|
706
|
+
if (typeof value === 'boolean')
|
|
707
|
+
return types_1.PropertyType.BOOL;
|
|
708
|
+
if (typeof value === 'number') {
|
|
709
|
+
return Number.isInteger(value) ? types_1.PropertyType.INT64 : types_1.PropertyType.DOUBLE;
|
|
710
|
+
}
|
|
711
|
+
if (typeof value === 'string')
|
|
712
|
+
return types_1.PropertyType.STRING;
|
|
713
|
+
if (Buffer.isBuffer(value))
|
|
714
|
+
return types_1.PropertyType.BLOB;
|
|
715
|
+
if (Array.isArray(value))
|
|
716
|
+
return types_1.PropertyType.LIST;
|
|
717
|
+
if (typeof value === 'object')
|
|
718
|
+
return types_1.PropertyType.MAP;
|
|
719
|
+
return types_1.PropertyType.UNSET;
|
|
720
|
+
}
|
|
721
|
+
}
|
|
722
|
+
exports.Response = Response;
|
|
723
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVzcG9uc2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvcmVzcG9uc2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBOztHQUVHOzs7QUFFSCxtQ0FBOEk7QUFFOUksa0RBQWtEO0FBQ2xELE1BQWEsR0FBRztJQUVJO0lBQ0E7SUFGbEIsWUFDa0IsTUFBYSxFQUNiLFFBQXdCLEVBQUU7UUFEMUIsV0FBTSxHQUFOLE1BQU0sQ0FBTztRQUNiLFVBQUssR0FBTCxLQUFLLENBQXFCO0lBQ3pDLENBQUM7SUFFSiw4Q0FBOEM7SUFDOUMsR0FBRyxDQUFDLEtBQWE7UUFDZixJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksS0FBSyxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDN0MsTUFBTSxJQUFJLEtBQUssQ0FBQyw4QkFBOEIsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN6RCxDQUFDO1FBQ0QsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqQyw4Q0FBOEM7UUFDOUMsSUFBSSxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLE1BQU0sSUFBSSxLQUFLLElBQUksTUFBTSxJQUFJLEtBQUssSUFBSSxRQUFRLElBQUksS0FBSyxFQUFFLENBQUM7WUFDbEcsT0FBTyxJQUFBLHNCQUFjLEVBQUMsS0FBbUIsQ0FBQyxDQUFDO1FBQzdDLENBQUM7UUFDRCxPQUFPLEtBQUssQ0FBQztJQUNmLENBQUM7SUFFRCxxREFBcUQ7SUFDckQsT0FBTyxDQUFDLEtBQWE7UUFDbkIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQzVDLE9BQU8sb0JBQVksQ0FBQyxLQUFLLENBQUM7UUFDNUIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQztJ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LElBQUksRUFBRSxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN4RixJQUFJO1lBQ0osSUFBSSxFQUFFLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxLQUFLLENBQUM7U0FDcEMsQ0FBQyxDQUFDLENBQUM7UUFDSixPQUFPLEVBQUUsSUFBSSxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsQ0FBQztJQUNyQyxDQUFDO0lBRU8saUJBQWlCLENBQUMsS0FBVTtRQUNsQyxJQUFJLEtBQUssS0FBSyxJQUFJLElBQUksS0FBSyxLQUFLLFNBQVM7WUFBRSxPQUFPLG9CQUFZLENBQUMsSUFBSSxDQUFDO1FBQ3BFLElBQUksT0FBTyxLQUFLLEtBQUssU0FBUztZQUFFLE9BQU8sb0JBQVksQ0FBQyxJQUFJLENBQUM7UUFDekQsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztZQUM5QixPQUFPLE1BQU0sQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLG9CQUFZLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxvQkFBWSxDQUFDLE1BQU0sQ0FBQztRQUM1RSxDQUFDO1FBQ0QsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRO1lBQUUsT0FBTyxvQkFBWSxDQUFDLE1BQU0sQ0FBQztRQUMxRCxJQUFJLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxvQkFBWSxDQUFDLElBQUksQ0FBQztRQUNyRCxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1lBQUUsT0FBTyxvQkFBWSxDQUFDLElBQUksQ0FBQztRQUNuRCxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7WUFBRSxPQUFPLG9CQUFZLENBQUMsR0FBRyxDQUFDO1FBQ3ZELE9BQU8sb0JBQVksQ0FBQyxLQUFLLENBQUM7SUFDNUIsQ0FBQztDQUNGO0FBcFhELDRCQW9YQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxyXG4gKiBSZXNwb25zZSBoYW5kbGluZyBmb3IgR1FMREIgTm9kZS5qcyBkcml2ZXIuXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgVHlwZWRWYWx1ZSwgdHlwZWRWYWx1ZVRvSlMsIFByb3BlcnR5VHlwZSwgU2NoZW1hLCBQcm9wZXJ0eURlZiwgVGFibGUsIEhlYWRlciwgQXR0ciwgR3FsZGJOb2RlLCBHcWxkYkVkZ2UsIEdxbGRiUGF0aCB9IGZyb20gJy4vdHlwZXMnO1xyXG5cclxuLyoqIFJlcHJlc2VudHMgYSBzaW5nbGUgcm93IGluIHRoZSBxdWVyeSByZXN1bHQgKi9cclxuZXhwb3J0IGNsYXNzIFJvdyB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgdmFsdWVzOiBhbnlbXSxcclxuICAgIHB1YmxpYyByZWFkb25seSB0eXBlczogUHJvcGVydHlUeXBlW10gPSBbXVxyXG4gICkge31cclxuXHJcbiAgLyoqIEdldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIGNvbHVtbiBpbmRleCAqL1xyXG4gIGdldChpbmRleDogbnVtYmVyKTogYW55IHtcclxuICAgIGlmIChpbmRleCA8IDAgfHwgaW5kZXggPj0gdGhpcy52YWx1ZXMubGVuZ3RoKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29sdW1uIGluZGV4IG91dCBvZiByYW5nZTogJHtpbmRleH1gKTtcclxuICAgIH1cclxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy52YWx1ZXNbaW5kZXhdO1xyXG4gICAgLy8gSWYgdmFsdWUgaXMgYSBUeXBlZFZhbHVlIG9iamVjdCwgY29udmVydCBpdFxyXG4gICAgaWYgKHZhbHVlICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ29iamVjdCcgJiYgJ3R5cGUnIGluIHZhbHVlICYmICdkYXRhJyBpbiB2YWx1ZSAmJiAnaXNOdWxsJyBpbiB2YWx1ZSkge1xyXG4gICAgICByZXR1cm4gdHlwZWRWYWx1ZVRvSlModmFsdWUgYXMgVHlwZWRWYWx1ZSk7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdmFsdWU7XHJcbiAgfVxyXG5cclxuICAvKiogR2V0IHRoZSBQcm9wZXJ0eVR5cGUgYXQgdGhlIGdpdmVuIGNvbHVtbiBpbmRleCAqL1xyXG4gIGdldFR5cGUoaW5kZXg6IG51bWJlcik6IFByb3BlcnR5VHlwZSB7XHJcbiAgICBpZiAoaW5kZXggPCAwIHx8IGluZGV4ID49IHRoaXMudHlwZXMubGVuZ3RoKSB7XHJcbiAgICAgIHJldHVybiBQcm9wZXJ0eVR5cGUuVU5TRVQ7XHJcbiAgICB9XHJcbiAgICByZXR1cm4gdGhpcy50eXBlc1tpbmRleF07XHJcbiAgfVxyXG5cclxuICAvKiogR2V0IHRoZSB2YWx1ZSBhdCB0aGUgZ2l2ZW4gY29sdW1uIGluZGV4IGFzIGEgc3RyaW5nICovXHJcbiAgZ2V0U3RyaW5nKGluZGV4OiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgdmFsID0gdGhpcy5nZXQoaW5kZXgpO1xyXG4gICAgaWYgKHZhbCA9PT0gbnVsbCB8fCB2YWwgPT09IHVuZGVmaW5lZCkgcmV0dXJuICcnO1xyXG4gICAgaWYgKHR5cGVvZiB2YWwgPT09ICdzdHJpbmcnKSByZXR1cm4gdmFsO1xyXG4gICAgcmV0dXJuIFN0cmluZyh2YWwpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEdldCB0aGUgdmFsdWUgYXQgdGhlIGdpdmVuIGNvbHVtbiBpbmRleCBhcyBhIG51bWJlciAqL1xyXG4gIGdldE51bWJlcihpbmRleDogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgIGNvbnN0IHZhbCA9IHRoaXMuZ2V0KGluZGV4KTtcclxuICAgIGlmICh2YWwgPT09IG51bGwgfHwgdmFsID09PSB1bmRlZmluZWQpIHJldHVybiAwO1xyXG4gICAgaWYgKHR5cGVvZiB2YWwgPT09ICdudW1iZXInKSByZXR1cm4gdmFsO1xyXG4gICAgY29uc3QgbnVtID0gTnVtYmVyKHZhbCk7XHJcbiAgICBpZiAoaXNOYU4obnVtKSkgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29udmVydCAke3R5cGVvZiB2YWx9IHRvIG51bWJlcmApO1xyXG4gICAgcmV0dXJuIG51bTtcclxuICB9XHJcblxyXG4gIC8qKiBHZXQgdGhlIHZhbHVlIGF0IHRoZSBnaXZlbiBjb2x1bW4gaW5kZXggYXMgYSBib29sZWFuICovXHJcbiAgZ2V0Qm9vbGVhbihpbmRleDogbnVtYmVyKTogYm9vbGVhbiB7XHJcbiAgICBjb25zdCB2YWwgPSB0aGlzLmdldChpbmRleCk7XHJcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gZmFsc2U7XHJcbiAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ2Jvb2xlYW4nKSByZXR1cm4gdmFsO1xyXG4gICAgdGhyb3cgbmV3IEVycm9yKGBDYW5ub3QgY29udmVydCAke3R5cGVvZiB2YWx9IHRvIGJvb2xlYW5gKTtcclxuICB9XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBSZXByZXNlbnRzIGEgc2luZ2xlIGNvbHVtbidzIGRhdGEgZnJvbSB0aGUgcmVzcG9uc2UuXHJcbiAqIEFsbG93cyBjaGFpbmluZyBvcGVyYXRpb25zIGxpa2UgcmVzcC5hbGlhcyhcIm5cIikuYXNOb2RlcygpIG9yIHJlc3AuZ2V0KDApLmFzTm9kZXMoKS5cclxuICovXHJcbmV4cG9ydCBjbGFzcyBBbGlhc1Jlc3VsdCB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwcml2YXRlIHJlYWRvbmx5IGFsaWFzTmFtZTogc3RyaW5nLFxyXG4gICAgcHJpdmF0ZSByZWFkb25seSBjb2x1bW5JZHg6IG51bWJlcixcclxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVzcG9uc2U6IFJlc3BvbnNlXHJcbiAgKSB7fVxyXG5cclxuICAvKiogR2V0IHRoZSBhbGlhcyBuYW1lICovXHJcbiAgZ2V0IGFsaWFzKCk6IHN0cmluZyB7XHJcbiAgICByZXR1cm4gdGhpcy5hbGlhc05hbWU7XHJcbiAgfVxyXG5cclxuICAvKiogR2V0IHRoZSBjb2x1bW4gaW5kZXggKi9cclxuICBnZXQgY29sdW1uSW5kZXgoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLmNvbHVtbklkeDtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4dHJhY3Qgbm9kZXMgZnJvbSB0aGUgYWxpYXNlZCBjb2x1bW4gd2l0aCBzY2hlbWEgaW5mby5cclxuICAgKiBUaHJvd3MgVHlwZUVycm9yIGlmIHRoZSBjb2x1bW4gY29udGFpbnMgbm9uLU5PREUgdHlwZXMuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBjb2xsZWN0Tm9kZSh2YWw6IGFueSwgbm9kZXM6IE5vZGVbXSwgc2NoZW1hczogTWFwPHN0cmluZywgU2NoZW1hPik6IHZvaWQge1xyXG4gICAgaWYgKHZhbCAmJiB0eXBlb2YgdmFsLmlkID09PSAnc3RyaW5nJyAmJiAnbGFiZWxzJyBpbiB2YWwpIHtcclxuICAgICAgY29uc3Qgbm9kZTogTm9kZSA9IHtcclxuICAgICAgICBpZDogdmFsLmlkLFxyXG4gICAgICAgIGxhYmVsczogdmFsLmxhYmVscyB8fCBbXSxcclxuICAgICAgICBwcm9wZXJ0aWVzOiB2YWwucHJvcGVydGllcyB8fCB7fSxcclxuICAgICAgfTtcclxuICAgICAgbm9kZXMucHVzaChub2RlKTtcclxuICAgICAgZm9yIChjb25zdCBsYWJlbCBvZiBub2RlLmxhYmVscykge1xyXG4gICAgICAgIGlmICghc2NoZW1hcy5oYXMobGFiZWwpKSB7XHJcbiAgICAgICAgICBzY2hlbWFzLnNldChsYWJlbCwgdGhpcy5idWlsZFNjaGVtYUZyb21Ob2RlKGxhYmVsLCBub2RlKSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGNvbGxlY3RFZGdlKHZhbDogYW55LCBlZGdlczogRWRnZVtdLCBzY2hlbWFzOiBNYXA8c3RyaW5nLCBTY2hlbWE+KTogdm9pZCB7XHJcbiAgICBpZiAodmFsICYmIHR5cGVvZiB2YWwuaWQgPT09ICdzdHJpbmcnICYmICdsYWJlbCcgaW4gdmFsKSB7XHJcbiAgICAgIGNvbnN0IGVkZ2U6IEVkZ2UgPSB7XHJcbiAgICAgICAgaWQ6IHZhbC5pZCxcclxuICAgICAgICBsYWJlbDogdmFsLmxhYmVsIHx8ICcnLFxyXG4gICAgICAgIGZyb21Ob2RlSWQ6IHZhbC5mcm9tTm9kZUlkIHx8ICcnLFxyXG4gICAgICAgIHRvTm9kZUlkOiB2YWwudG9Ob2RlSWQgfHwgJycsXHJcbiAgICAgICAgcHJvcGVydGllczogdmFsLnByb3BlcnRpZXMgfHwge30sXHJcbiAgICAgIH07XHJcbiAgICAgIGVkZ2VzLnB1c2goZWRnZSk7XHJcbiAgICAgIGlmIChlZGdlLmxhYmVsICYmICFzY2hlbWFzLmhhcyhlZGdlLmxhYmVsKSkge1xyXG4gICAgICAgIHNjaGVtYXMuc2V0KGVkZ2UubGFiZWwsIHRoaXMuYnVpbGRTY2hlbWFGcm9tRWRnZShlZGdlLmxhYmVsLCBlZGdlKSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEV4dHJhY3Qgbm9kZXMgZnJvbSB0aGUgYWxpYXNlZCBjb2x1bW4gd2l0aCBzY2hlbWEgaW5mby5cclxuICAgKiBTdXBwb3J0cyBib3RoIGRpcmVjdCBOT0RFIGNvbHVtbnMgYW5kIExJU1Qgb2YgTk9ERSBjb2x1bW5zXHJcbiAgICogKGUuZy4sIGdyb3VwIHZhcmlhYmxlcyBmcm9tIHF1YW50aWZpZWQgcGF0dGVybnMpLlxyXG4gICAqL1xyXG4gIGFzTm9kZXMoKTogTm9kZVJlc3VsdCB7XHJcbiAgICBjb25zdCBub2RlczogTm9kZVtdID0gW107XHJcbiAgICBjb25zdCBzY2hlbWFzID0gbmV3IE1hcDxzdHJpbmcsIFNjaGVtYT4oKTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiB0aGlzLnJlc3BvbnNlLnJvd3MpIHtcclxuICAgICAgaWYgKHRoaXMuY29sdW1uSWR4ID49IHJvdy52YWx1ZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGxldCBpdGVtVHlwZSA9IHJvdy5nZXRUeXBlKHRoaXMuY29sdW1uSWR4KTtcclxuICAgICAgY29uc3QgcmF3VmFsdWUgPSByb3cudmFsdWVzW3RoaXMuY29sdW1uSWR4XTtcclxuICAgICAgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuVU5TRVQgJiYgcmF3VmFsdWUgJiYgdHlwZW9mIHJhd1ZhbHVlID09PSAnb2JqZWN0JyAmJiAndHlwZScgaW4gcmF3VmFsdWUpIHtcclxuICAgICAgICBpdGVtVHlwZSA9IHJhd1ZhbHVlLnR5cGU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmICghcmF3VmFsdWUgfHwgKHR5cGVvZiByYXdWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ2lzTnVsbCcgaW4gcmF3VmFsdWUgJiYgcmF3VmFsdWUuaXNOdWxsKSkge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaXRlbVR5cGUgPT09IFByb3BlcnR5VHlwZS5OT0RFKSB7XHJcbiAgICAgICAgdGhpcy5jb2xsZWN0Tm9kZShyb3cuZ2V0KHRoaXMuY29sdW1uSWR4KSwgbm9kZXMsIHNjaGVtYXMpO1xyXG4gICAgICB9IGVsc2UgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuTElTVCkge1xyXG4gICAgICAgIC8vIExJU1Qgb2YgTk9ERSAoZ3JvdXAgdmFyaWFibGUgZnJvbSBxdWFudGlmaWVkIHBhdHRlcm4pXHJcbiAgICAgICAgY29uc3QgbGlzdCA9IHJvdy5nZXQodGhpcy5jb2x1bW5JZHgpO1xyXG4gICAgICAgIGlmIChBcnJheS5pc0FycmF5KGxpc3QpKSB7XHJcbiAgICAgICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgbGlzdCkge1xyXG4gICAgICAgICAgICB0aGlzLmNvbGxlY3ROb2RlKGl0ZW0sIG5vZGVzLCBzY2hlbWFzKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcclxuICAgICAgICAgIGBUeXBlIG1pc21hdGNoOiBjb2x1bW4gJyR7dGhpcy5hbGlhc05hbWV9JyAoaW5kZXggJHt0aGlzLmNvbHVtbklkeH0pIGNvbnRhaW5zICR7UHJvcGVydHlUeXBlW2l0ZW1UeXBlXX0sIGV4cGVjdGVkIE5PREUgb3IgTElTVCBvZiBOT0RFYFxyXG4gICAgICAgICk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4geyBub2Rlcywgc2NoZW1hcyB9O1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogRXh0cmFjdCBlZGdlcyBmcm9tIHRoZSBhbGlhc2VkIGNvbHVtbiB3aXRoIHNjaGVtYSBpbmZvLlxyXG4gICAqIFN1cHBvcnRzIGJvdGggZGlyZWN0IEVER0UgY29sdW1ucyBhbmQgTElTVCBvZiBFREdFIGNvbHVtbnNcclxuICAgKiAoZS5nLiwgZ3JvdXAgdmFyaWFibGVzIGZyb20gcXVhbnRpZmllZCBwYXR0ZXJucykuXHJcbiAgICovXHJcbiAgYXNFZGdlcygpOiBFZGdlUmVzdWx0IHtcclxuICAgIGNvbnN0IGVkZ2VzOiBFZGdlW10gPSBbXTtcclxuICAgIGNvbnN0IHNjaGVtYXMgPSBuZXcgTWFwPHN0cmluZywgU2NoZW1hPigpO1xyXG5cclxuICAgIGZvciAoY29uc3Qgcm93IG9mIHRoaXMucmVzcG9uc2Uucm93cykge1xyXG4gICAgICBpZiAodGhpcy5jb2x1bW5JZHggPj0gcm93LnZhbHVlcy5sZW5ndGgpIHtcclxuICAgICAgICBjb250aW51ZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgbGV0IGl0ZW1UeXBlID0gcm93LmdldFR5cGUodGhpcy5jb2x1bW5JZHgpO1xyXG4gICAgICBjb25zdCByYXdWYWx1ZSA9IHJvdy52YWx1ZXNbdGhpcy5jb2x1bW5JZHhdO1xyXG4gICAgICBpZiAoaXRlbVR5cGUgPT09IFByb3BlcnR5VHlwZS5VTlNFVCAmJiByYXdWYWx1ZSAmJiB0eXBlb2YgcmF3VmFsdWUgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiByYXdWYWx1ZSkge1xyXG4gICAgICAgIGl0ZW1UeXBlID0gcmF3VmFsdWUudHlwZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgaWYgKCFyYXdWYWx1ZSB8fCAodHlwZW9mIHJhd1ZhbHVlID09PSAnb2JqZWN0JyAmJiAnaXNOdWxsJyBpbiByYXdWYWx1ZSAmJiByYXdWYWx1ZS5pc051bGwpKSB7XHJcbiAgICAgICAgY29udGludWU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLkVER0UpIHtcclxuICAgICAgICB0aGlzLmNvbGxlY3RFZGdlKHJvdy5nZXQodGhpcy5jb2x1bW5JZHgpLCBlZGdlcywgc2NoZW1hcyk7XHJcbiAgICAgIH0gZWxzZSBpZiAoaXRlbVR5cGUgPT09IFByb3BlcnR5VHlwZS5MSVNUKSB7XHJcbiAgICAgICAgLy8gTElTVCBvZiBFREdFIChncm91cCB2YXJpYWJsZSBmcm9tIHF1YW50aWZpZWQgcGF0dGVybilcclxuICAgICAgICBjb25zdCBsaXN0ID0gcm93LmdldCh0aGlzLmNvbHVtbklkeCk7XHJcbiAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobGlzdCkpIHtcclxuICAgICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBsaXN0KSB7XHJcbiAgICAgICAgICAgIHRoaXMuY29sbGVjdEVkZ2UoaXRlbSwgZWRnZXMsIHNjaGVtYXMpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKFxyXG4gICAgICAgICAgYFR5cGUgbWlzbWF0Y2g6IGNvbHVtbiAnJHt0aGlzLmFsaWFzTmFtZX0nIChpbmRleCAke3RoaXMuY29sdW1uSWR4fSkgY29udGFpbnMgJHtQcm9wZXJ0eVR5cGVbaXRlbVR5cGVdfSwgZXhwZWN0ZWQgRURHRSBvciBMSVNUIG9mIEVER0VgXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7IGVkZ2VzLCBzY2hlbWFzIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBFeHRyYWN0IHBhdGhzIGZyb20gdGhlIGFsaWFzZWQgY29sdW1uLlxyXG4gICAqIFRocm93cyBUeXBlRXJyb3IgaWYgdGhlIGNvbHVtbiBjb250YWlucyBub24tUEFUSCB0eXBlcy5cclxuICAgKi9cclxuICBhc1BhdGhzKCk6IFBhdGhbXSB7XHJcbiAgICBjb25zdCBwYXRoczogUGF0aFtdID0gW107XHJcblxyXG4gICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yZXNwb25zZS5yb3dzKSB7XHJcbiAgICAgIGlmICh0aGlzLmNvbHVtbklkeCA+PSByb3cudmFsdWVzLmxlbmd0aCkge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBDaGVjayB0eXBlIGZyb20gdHlwZXMgYXJyYXkgb3IgZnJvbSBUeXBlZFZhbHVlIG9iamVjdFxyXG4gICAgICBsZXQgaXRlbVR5cGUgPSByb3cuZ2V0VHlwZSh0aGlzLmNvbHVtbklkeCk7XHJcbiAgICAgIGNvbnN0IHJhd1ZhbHVlID0gcm93LnZhbHVlc1t0aGlzLmNvbHVtbklkeF07XHJcbiAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLlVOU0VUICYmIHJhd1ZhbHVlICYmIHR5cGVvZiByYXdWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ3R5cGUnIGluIHJhd1ZhbHVlKSB7XHJcbiAgICAgICAgaXRlbVR5cGUgPSByYXdWYWx1ZS50eXBlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBTa2lwIG51bGwgdmFsdWVzXHJcbiAgICAgIGlmICghcmF3VmFsdWUgfHwgKHR5cGVvZiByYXdWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ2lzTnVsbCcgaW4gcmF3VmFsdWUgJiYgcmF3VmFsdWUuaXNOdWxsKSkge1xyXG4gICAgICAgIGNvbnRpbnVlO1xyXG4gICAgICB9XHJcblxyXG4gICAgICAvLyBUeXBlIGNoZWNraW5nOiBtdXN0IGJlIFBBVEggdHlwZVxyXG4gICAgICBpZiAoaXRlbVR5cGUgIT09IFByb3BlcnR5VHlwZS5QQVRIKSB7XHJcbiAgICAgICAgdGhyb3cgbmV3IFR5cGVFcnJvcihcclxuICAgICAgICAgIGBUeXBlIG1pc21hdGNoOiBjb2x1bW4gJyR7dGhpcy5hbGlhc05hbWV9JyAoaW5kZXggJHt0aGlzLmNvbHVtbklkeH0pIGNvbnRhaW5zICR7UHJvcGVydHlUeXBlW2l0ZW1UeXBlXX0sIGV4cGVjdGVkIFBBVEhgXHJcbiAgICAgICAgKTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gQ29udmVydCBUeXBlZFZhbHVlIHRvIEdxbGRiUGF0aFxyXG4gICAgICBjb25zdCB2YWwgPSByb3cuZ2V0KHRoaXMuY29sdW1uSWR4KSBhcyBHcWxkYlBhdGg7XHJcbiAgICAgIGlmICh2YWwgJiYgQXJyYXkuaXNBcnJheSh2YWwubm9kZXMpKSB7XHJcbiAgICAgICAgLy8gQ29udmVydCBHcWxkYk5vZGUvR3FsZGJFZGdlIHRvIE5vZGUvRWRnZVxyXG4gICAgICAgIGNvbnN0IG5vZGVzOiBOb2RlW10gPSAodmFsLm5vZGVzIHx8IFtdKS5tYXAoKG46IEdxbGRiTm9kZSkgPT4gKHtcclxuICAgICAgICAgIGlkOiBuLmlkIHx8ICcnLFxyXG4gICAgICAgICAgbGFiZWxzOiBuLmxhYmVscyB8fCBbXSxcclxuICAgICAgICAgIHByb3BlcnRpZXM6IG4ucHJvcGVydGllcyB8fCB7fSxcclxuICAgICAgICB9KSk7XHJcbiAgICAgICAgY29uc3QgZWRnZXM6IEVkZ2VbXSA9ICh2YWwuZWRnZXMgfHwgW10pLm1hcCgoZTogR3FsZGJFZGdlKSA9PiAoe1xyXG4gICAgICAgICAgaWQ6IGUuaWQgfHwgJycsXHJcbiAgICAgICAgICBsYWJlbDogZS5sYWJlbCB8fCAnJyxcclxuICAgICAgICAgIGZyb21Ob2RlSWQ6IGUuZnJvbU5vZGVJZCB8fCAnJyxcclxuICAgICAgICAgIHRvTm9kZUlkOiBlLnRvTm9kZUlkIHx8ICcnLFxyXG4gICAgICAgICAgcHJvcGVydGllczogZS5wcm9wZXJ0aWVzIHx8IHt9LFxyXG4gICAgICAgIH0pKTtcclxuICAgICAgICBwYXRocy5wdXNoKHsgbm9kZXMsIGVkZ2VzIH0pO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBhdGhzO1xyXG4gIH1cclxuXHJcbiAgLyoqIENvbnZlcnQgdGhlIGFsaWFzZWQgY29sdW1uIHRvIGEgc2luZ2xlLWNvbHVtbiB0YWJsZSAqL1xyXG4gIGFzVGFibGUoKTogVGFibGUge1xyXG4gICAgLy8gQ2hlY2sgaWYgZmlyc3Qgbm9uLW51bGwgdmFsdWUgaXMgYSBHcWxkYlRhYmxlIOKAlCBpZiBzbywgdW53cmFwIGl0XHJcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiB0aGlzLnJlc3BvbnNlLnJvd3MpIHtcclxuICAgICAgaWYgKHRoaXMuY29sdW1uSWR4IDwgcm93LnZhbHVlcy5sZW5ndGgpIHtcclxuICAgICAgICBjb25zdCBpdGVtVHlwZSA9IHJvdy5nZXRUeXBlKHRoaXMuY29sdW1uSWR4KTtcclxuICAgICAgICBpZiAoaXRlbVR5cGUgPT09IFByb3BlcnR5VHlwZS5UQUJMRSkge1xyXG4gICAgICAgICAgY29uc3QgdmFsID0gcm93LmdldCh0aGlzLmNvbHVtbklkeCkgYXMgYW55O1xyXG4gICAgICAgICAgaWYgKHZhbCAmJiAnY29sdW1ucycgaW4gdmFsICYmICdyb3dzJyBpbiB2YWwpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMudW53cmFwR3FsZGJUYWJsZSh2YWwpO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgICBicmVhazsgLy8gb25seSBjaGVjayBmaXJzdCByb3dcclxuICAgIH1cclxuXHJcbiAgICAvLyBGYWxsYmFjazogZ2VuZXJpYyBzaW5nbGUtY29sdW1uIHRhYmxlXHJcbiAgICBjb25zdCBoZWFkZXJzOiBIZWFkZXJbXSA9IFt7XHJcbiAgICAgIG5hbWU6IHRoaXMuYWxpYXNOYW1lLFxyXG4gICAgICB0eXBlOiBQcm9wZXJ0eVR5cGUuVU5TRVQsXHJcbiAgICB9XTtcclxuXHJcbiAgICBpZiAodGhpcy5yZXNwb25zZS5yb3dzLmxlbmd0aCA+IDApIHtcclxuICAgICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yZXNwb25zZS5yb3dzKSB7XHJcbiAgICAgICAgaWYgKHRoaXMuY29sdW1uSWR4IDwgcm93LnZhbHVlcy5sZW5ndGgpIHtcclxuICAgICAgICAgIGNvbnN0IHR5cGUgPSByb3cuZ2V0VHlwZSh0aGlzLmNvbHVtbklkeCk7XHJcbiAgICAgICAgICBpZiAodHlwZSAhPT0gUHJvcGVydHlUeXBlLlVOU0VUKSB7XHJcbiAgICAgICAgICAgIGhlYWRlcnNbMF0udHlwZSA9IHR5cGU7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHRhYmxlUm93czogYW55W11bXSA9IHRoaXMucmVzcG9uc2Uucm93cy5tYXAocm93ID0+IHtcclxuICAgICAgaWYgKHRoaXMuY29sdW1uSWR4IDwgcm93LnZhbHVlcy5sZW5ndGgpIHtcclxuICAgICAgICByZXR1cm4gW3Jvdy5nZXQodGhpcy5jb2x1bW5JZHgpXTtcclxuICAgICAgfVxyXG4gICAgICByZXR1cm4gW251bGxdO1xyXG4gICAgfSk7XHJcblxyXG4gICAgcmV0dXJuIHsgbmFtZTogJycsIGhlYWRlcnMsIHJvd3M6IHRhYmxlUm93cyB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1bndyYXBHcWxkYlRhYmxlKGd0OiB7IGNvbHVtbnM6IHN0cmluZ1tdOyByb3dzOiBhbnlbXVtdIH0pOiBUYWJsZSB7XHJcbiAgICBjb25zdCBoZWFkZXJzOiBIZWFkZXJbXSA9IGd0LmNvbHVtbnMubWFwKChjb2wsIGkpID0+IHtcclxuICAgICAgbGV0IGNvbFR5cGUgPSBQcm9wZXJ0eVR5cGUuVU5TRVQ7XHJcbiAgICAgIGlmIChndC5yb3dzLmxlbmd0aCA+IDAgJiYgaSA8IGd0LnJvd3NbMF0ubGVuZ3RoKSB7XHJcbiAgICAgICAgY29uc3QgdiA9IGd0LnJvd3NbMF1baV07XHJcbiAgICAgICAgaWYgKHR5cGVvZiB2ID09PSAnbnVtYmVyJykgY29sVHlwZSA9IE51bWJlci5pc0ludGVnZXIodikgPyBQcm9wZXJ0eVR5cGUuSU5UNjQgOiBQcm9wZXJ0eVR5cGUuRE9VQkxFO1xyXG4gICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2ID09PSAnc3RyaW5nJykgY29sVHlwZSA9IFByb3BlcnR5VHlwZS5TVFJJTkc7XHJcbiAgICAgICAgZWxzZSBpZiAodHlwZW9mIHYgPT09ICdib29sZWFuJykgY29sVHlwZSA9IFByb3BlcnR5VHlwZS5CT09MO1xyXG4gICAgICB9XHJcbiAgICAgIHJldHVybiB7IG5hbWU6IGNvbCwgdHlwZTogY29sVHlwZSB9O1xyXG4gICAgfSk7XHJcbiAgICByZXR1cm4geyBuYW1lOiB0aGlzLmFsaWFzTmFtZSwgaGVhZGVycywgcm93czogZ3Qucm93cyB9O1xyXG4gIH1cclxuXHJcbiAgLyoqIEV4dHJhY3Qgc2NhbGFyIG9yIGxpc3QgYXR0cmlidXRlIHZhbHVlcyBmcm9tIHRoZSBhbGlhc2VkIGNvbHVtbiAqL1xyXG4gIGFzQXR0cigpOiBBdHRyIHtcclxuICAgIGNvbnN0IHZhbHVlczogYW55W10gPSBbXTtcclxuICAgIGxldCBhdHRyVHlwZSA9IFByb3BlcnR5VHlwZS5VTlNFVDtcclxuXHJcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiB0aGlzLnJlc3BvbnNlLnJvd3MpIHtcclxuICAgICAgaWYgKHRoaXMuY29sdW1uSWR4IDwgcm93LnZhbHVlcy5sZW5ndGgpIHtcclxuICAgICAgICAvLyBUcnkgdG8gZ2V0IHR5cGUgZnJvbSByb3cudHlwZXMgZmlyc3QsIHRoZW4gZnJvbSBUeXBlZFZhbHVlIG9iamVjdFxyXG4gICAgICAgIGlmIChhdHRyVHlwZSA9PT0gUHJvcGVydHlUeXBlLlVOU0VUKSB7XHJcbiAgICAgICAgICBhdHRyVHlwZSA9IHJvdy5nZXRUeXBlKHRoaXMuY29sdW1uSWR4KTtcclxuICAgICAgICAgIGlmIChhdHRyVHlwZSA9PT0gUHJvcGVydHlUeXBlLlVOU0VUKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IHJhd1ZhbHVlID0gcm93LnZhbHVlc1t0aGlzLmNvbHVtbklkeF07XHJcbiAgICAgICAgICAgIGlmIChyYXdWYWx1ZSAmJiB0eXBlb2YgcmF3VmFsdWUgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiByYXdWYWx1ZSkge1xyXG4gICAgICAgICAgICAgIGF0dHJUeXBlID0gcmF3VmFsdWUudHlwZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBjb25zdCB2YWx1ZSA9IHJvdy5nZXQodGhpcy5jb2x1bW5JZHgpOyAgLy8gVXNlIGdldCgpIHRvIGNvbnZlcnQgVHlwZWRWYWx1ZVxyXG4gICAgICAgIHZhbHVlcy5wdXNoKHZhbHVlKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7IG5hbWU6IHRoaXMuYWxpYXNOYW1lLCB0eXBlOiBhdHRyVHlwZSwgdmFsdWVzIH07XHJcbiAgfVxyXG5cclxuICAvKiogRXh0cmFjdCByYXcgSmF2YVNjcmlwdCB2YWx1ZXMgZnJvbSB0aGUgYWxpYXNlZCBjb2x1bW4gKi9cclxuICBhc1ZhbHVlcygpOiBhbnlbXSB7XHJcbiAgICBjb25zdCB2YWx1ZXM6IGFueVtdID0gW107XHJcblxyXG4gICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yZXNwb25zZS5yb3dzKSB7XHJcbiAgICAgIGlmICh0aGlzLmNvbHVtbklkeCA8IHJvdy52YWx1ZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgdmFsdWVzLnB1c2gocm93LmdldCh0aGlzLmNvbHVtbklkeCkpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHZhbHVlcztcclxuICB9XHJcblxyXG4gIC8vIEhlbHBlciBtZXRob2RzXHJcblxyXG4gIHByaXZhdGUgYnVpbGRTY2hlbWFGcm9tTm9kZShsYWJlbDogc3RyaW5nLCBub2RlOiBOb2RlKTogU2NoZW1hIHtcclxuICAgIGNvbnN0IHByb3BlcnRpZXM6IFByb3BlcnR5RGVmW10gPSBPYmplY3QuZW50cmllcyhub2RlLnByb3BlcnRpZXMpLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4gKHtcclxuICAgICAgbmFtZSxcclxuICAgICAgdHlwZTogdGhpcy5pbmZlclByb3BlcnR5VHlwZSh2YWx1ZSksXHJcbiAgICB9KSk7XHJcbiAgICByZXR1cm4geyBuYW1lOiBsYWJlbCwgcHJvcGVydGllcyB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBidWlsZFNjaGVtYUZyb21FZGdlKGxhYmVsOiBzdHJpbmcsIGVkZ2U6IEVkZ2UpOiBTY2hlbWEge1xyXG4gICAgY29uc3QgcHJvcGVydGllczogUHJvcGVydHlEZWZbXSA9IE9iamVjdC5lbnRyaWVzKGVkZ2UucHJvcGVydGllcykubWFwKChbbmFtZSwgdmFsdWVdKSA9PiAoe1xyXG4gICAgICBuYW1lLFxyXG4gICAgICB0eXBlOiB0aGlzLmluZmVyUHJvcGVydHlUeXBlKHZhbHVlKSxcclxuICAgIH0pKTtcclxuICAgIHJldHVybiB7IG5hbWU6IGxhYmVsLCBwcm9wZXJ0aWVzIH07XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluZmVyUHJvcGVydHlUeXBlKHZhbHVlOiBhbnkpOiBQcm9wZXJ0eVR5cGUge1xyXG4gICAgaWYgKHZhbHVlID09PSBudWxsIHx8IHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybiBQcm9wZXJ0eVR5cGUuTlVMTDtcclxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdib29sZWFuJykgcmV0dXJuIFByb3BlcnR5VHlwZS5CT09MO1xyXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHtcclxuICAgICAgcmV0dXJuIE51bWJlci5pc0ludGVnZXIodmFsdWUpID8gUHJvcGVydHlUeXBlLklOVDY0IDogUHJvcGVydHlUeXBlLkRPVUJMRTtcclxuICAgIH1cclxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdzdHJpbmcnKSByZXR1cm4gUHJvcGVydHlUeXBlLlNUUklORztcclxuICAgIGlmIChCdWZmZXIuaXNCdWZmZXIodmFsdWUpKSByZXR1cm4gUHJvcGVydHlUeXBlLkJMT0I7XHJcbiAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiBQcm9wZXJ0eVR5cGUuTElTVDtcclxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnKSByZXR1cm4gUHJvcGVydHlUeXBlLk1BUDtcclxuICAgIHJldHVybiBQcm9wZXJ0eVR5cGUuVU5TRVQ7XHJcbiAgfVxyXG59XHJcblxyXG4vKiogUmVwcmVzZW50cyB0aGUgcmVzdWx0IG9mIGEgR1FMIHF1ZXJ5ICovXHJcbmV4cG9ydCBjbGFzcyBSZXNwb25zZSB7XHJcbiAgY29uc3RydWN0b3IoXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgY29sdW1uczogc3RyaW5nW10sXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgcm93czogUm93W10sXHJcbiAgICBwdWJsaWMgcmVhZG9ubHkgcm93Q291bnQ6IG51bWJlcixcclxuICAgIHB1YmxpYyByZWFkb25seSBoYXNNb3JlOiBib29sZWFuLFxyXG4gICAgcHVibGljIHJlYWRvbmx5IHdhcm5pbmdzOiBzdHJpbmdbXSxcclxuICAgIHB1YmxpYyByZWFkb25seSByb3dzQWZmZWN0ZWQ6IG51bWJlciA9IDBcclxuICApIHt9XHJcblxyXG4gIC8qKiBDaGVjayBpZiB0aGUgcmVzcG9uc2UgaGFzIG5vIHJvd3MgKi9cclxuICBpc0VtcHR5KCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMucm93cy5sZW5ndGggPT09IDA7XHJcbiAgfVxyXG5cclxuICAvKiogR2V0IHRoZSBmaXJzdCByb3cgKi9cclxuICBmaXJzdCgpOiBSb3cgfCB1bmRlZmluZWQge1xyXG4gICAgcmV0dXJuIHRoaXMucm93c1swXTtcclxuICB9XHJcblxyXG4gIC8qKiBHZXQgdGhlIGxhc3Qgcm93ICovXHJcbiAgbGFzdCgpOiBSb3cgfCB1bmRlZmluZWQge1xyXG4gICAgcmV0dXJuIHRoaXMucm93c1t0aGlzLnJvd3MubGVuZ3RoIC0gMV07XHJcbiAgfVxyXG5cclxuICAvKiogR2V0IHRoZSB2YWx1ZSBmb3IgYSBjb2x1bW4gYnkgbmFtZSAqL1xyXG4gIGdldEJ5TmFtZShyb3c6IFJvdywgY29sdW1uTmFtZTogc3RyaW5nKTogYW55IHtcclxuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5jb2x1bW5zLmluZGV4T2YoY29sdW1uTmFtZSk7XHJcbiAgICBpZiAoaW5kZXggPT09IC0xKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29sdW1uIG5vdCBmb3VuZDogJHtjb2x1bW5OYW1lfWApO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHJvdy5nZXQoaW5kZXgpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEl0ZXJhdGUgb3ZlciBhbGwgcm93cyB3aXRoIGEgY2FsbGJhY2sgKi9cclxuICBmb3JFYWNoKGZuOiAocm93OiBSb3csIGluZGV4OiBudW1iZXIpID0+IHZvaWQpOiB2b2lkIHtcclxuICAgIHRoaXMucm93cy5mb3JFYWNoKGZuKTtcclxuICB9XHJcblxyXG4gIC8qKiBUcmFuc2Zvcm0gZWFjaCByb3cgdXNpbmcgYSBjYWxsYmFjayAqL1xyXG4gIG1hcDxUPihmbjogKHJvdzogUm93KSA9PiBUKTogVFtdIHtcclxuICAgIHJldHVybiB0aGlzLnJvd3MubWFwKGZuKTtcclxuICB9XHJcblxyXG4gIC8qKiBDb252ZXJ0IHRoZSByZXNwb25zZSB0byBhbiBhcnJheSBvZiBvYmplY3RzICovXHJcbiAgdG9PYmplY3RzKCk6IFJlY29yZDxzdHJpbmcsIGFueT5bXSB7XHJcbiAgICByZXR1cm4gdGhpcy5yb3dzLm1hcChyb3cgPT4ge1xyXG4gICAgICBjb25zdCBvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcclxuICAgICAgdGhpcy5jb2x1bW5zLmZvckVhY2goKGNvbCwgaSkgPT4ge1xyXG4gICAgICAgIC8vIEFkZCBib3VuZGFyeSBjaGVjayB0byBoYW5kbGUgbWlzbWF0Y2hlZCBjb2x1bW5zL3ZhbHVlc1xyXG4gICAgICAgIG9ialtjb2xdID0gaSA8IHJvdy52YWx1ZXMubGVuZ3RoID8gcm93LmdldChpKSA6IG51bGw7XHJcbiAgICAgIH0pO1xyXG4gICAgICByZXR1cm4gb2JqO1xyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICAvKiogQ29udmVydCB0aGUgcmVzcG9uc2UgdG8gSlNPTiAqL1xyXG4gIHRvSlNPTigpOiBzdHJpbmcge1xyXG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHRoaXMudG9PYmplY3RzKCkpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEdldCB0aGUgc2luZ2xlIHZhbHVlIGZyb20gYSBzaW5nbGUtcm93LCBzaW5nbGUtY29sdW1uIHJlc3BvbnNlICovXHJcbiAgc2luZ2xlVmFsdWUoKTogYW55IHtcclxuICAgIGlmICh0aGlzLnJvd3MubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcclxuICAgIGlmICh0aGlzLnJvd3MubGVuZ3RoID4gMSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIHNpbmdsZSByb3csIGdvdCAke3RoaXMucm93cy5sZW5ndGh9YCk7XHJcbiAgICB9XHJcbiAgICBpZiAodGhpcy5yb3dzWzBdLnZhbHVlcy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xyXG4gICAgaWYgKHRoaXMucm93c1swXS52YWx1ZXMubGVuZ3RoID4gMSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYEV4cGVjdGVkIHNpbmdsZSBjb2x1bW4sIGdvdCAke3RoaXMucm93c1swXS52YWx1ZXMubGVuZ3RofWApO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHRoaXMucm93c1swXS5nZXQoMCk7XHJcbiAgfVxyXG5cclxuICAvKiogR2V0IHRoZSBzaW5nbGUgbnVtYmVyIHZhbHVlICovXHJcbiAgc2luZ2xlTnVtYmVyKCk6IG51bWJlciB7XHJcbiAgICBjb25zdCB2YWwgPSB0aGlzLnNpbmdsZVZhbHVlKCk7XHJcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gMDtcclxuICAgIGlmICh0eXBlb2YgdmFsID09PSAnbnVtYmVyJykgcmV0dXJuIHZhbDtcclxuICAgIGNvbnN0IG51bSA9IE51bWJlcih2YWwpO1xyXG4gICAgaWYgKGlzTmFOKG51bSkpIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGNvbnZlcnQgJHt0eXBlb2YgdmFsfSB0byBudW1iZXJgKTtcclxuICAgIHJldHVybiBudW07XHJcbiAgfVxyXG5cclxuICAvKiogR2V0IHRoZSBzaW5nbGUgc3RyaW5nIHZhbHVlICovXHJcbiAgc2luZ2xlU3RyaW5nKCk6IHN0cmluZyB7XHJcbiAgICBjb25zdCB2YWwgPSB0aGlzLnNpbmdsZVZhbHVlKCk7XHJcbiAgICBpZiAodmFsID09PSBudWxsIHx8IHZhbCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gJyc7XHJcbiAgICBpZiAodHlwZW9mIHZhbCA9PT0gJ3N0cmluZycpIHJldHVybiB2YWw7XHJcbiAgICByZXR1cm4gU3RyaW5nKHZhbCk7XHJcbiAgfVxyXG5cclxuICAvKiogSXRlcmF0b3Igc3VwcG9ydCAqL1xyXG4gIFtTeW1ib2wuaXRlcmF0b3JdKCk6IEl0ZXJhdG9yPFJvdz4ge1xyXG4gICAgcmV0dXJuIHRoaXMucm93c1tTeW1ib2wuaXRlcmF0b3JdKCk7XHJcbiAgfVxyXG5cclxuICAvKiogR2V0IHRoZSBudW1iZXIgb2Ygcm93cyAqL1xyXG4gIGdldCBsZW5ndGgoKTogbnVtYmVyIHtcclxuICAgIHJldHVybiB0aGlzLnJvd3MubGVuZ3RoO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogR2V0IGFuIEFsaWFzUmVzdWx0IGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbiBuYW1lLlxyXG4gICAqIFVzZSB0aGlzIHRvIGV4dHJhY3QgZGF0YSBmcm9tIGEgc3BlY2lmaWMgY29sdW1uIGJ5IG5hbWUuXHJcbiAgICogRXhhbXBsZTogcmVzcC5hbGlhcyhcIm5cIikuYXNOb2RlcygpXHJcbiAgICovXHJcbiAgYWxpYXMoY29sdW1uTmFtZTogc3RyaW5nKTogQWxpYXNSZXN1bHQge1xyXG4gICAgY29uc3QgY29sSWR4ID0gdGhpcy5jb2x1bW5zLmluZGV4T2YoY29sdW1uTmFtZSk7XHJcbiAgICBpZiAoY29sSWR4ID09PSAtMSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiBhbGlhcyBub3QgZm91bmQ6ICR7Y29sdW1uTmFtZX1gKTtcclxuICAgIH1cclxuICAgIHJldHVybiBuZXcgQWxpYXNSZXN1bHQoY29sdW1uTmFtZSwgY29sSWR4LCB0aGlzKTtcclxuICB9XHJcblxyXG4gIC8qKlxyXG4gICAqIEdldCBhbiBBbGlhc1Jlc3VsdCBmb3IgdGhlIGNvbHVtbiBhdCB0aGUgc3BlY2lmaWVkIGluZGV4LlxyXG4gICAqIFVzZSB0aGlzIHRvIGV4dHJhY3QgZGF0YSBmcm9tIGEgc3BlY2lmaWMgY29sdW1uIGJ5IGluZGV4LlxyXG4gICAqIEV4YW1wbGU6IHJlc3AuZ2V0KDApLmFzTm9kZXMoKVxyXG4gICAqL1xyXG4gIGdldChpbmRleDogbnVtYmVyKTogQWxpYXNSZXN1bHQge1xyXG4gICAgaWYgKGluZGV4IDwgMCB8fCBpbmRleCA+PSB0aGlzLmNvbHVtbnMubGVuZ3RoKSB7XHJcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29sdW1uIGluZGV4IG91dCBvZiByYW5nZTogJHtpbmRleH0gKHRvdGFsOiAke3RoaXMuY29sdW1ucy5sZW5ndGh9KWApO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIG5ldyBBbGlhc1Jlc3VsdCh0aGlzLmNvbHVtbnNbaW5kZXhdLCBpbmRleCwgdGhpcyk7XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVwcmVjYXRlZCBVc2UgYWxpYXMoKSBvciBnZXQoKSBpbnN0ZWFkLiBUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi5cclxuICAgKiBFeHRyYWN0IG5vZGVzIGZyb20gcmVzcG9uc2Ugd2l0aCBzY2hlbWEgaW5mby5cclxuICAgKiBTdXBwb3J0cyBib3RoIE5PREUgYW5kIExJU1Qgb2YgTk9ERSBjb2x1bW5zLlxyXG4gICAqL1xyXG4gIGFzTm9kZXMoKTogTm9kZVJlc3VsdCB7XHJcbiAgICBjb25zdCBub2RlczogTm9kZVtdID0gW107XHJcbiAgICBjb25zdCBzY2hlbWFzID0gbmV3IE1hcDxzdHJpbmcsIFNjaGVtYT4oKTtcclxuXHJcbiAgICBjb25zdCBjb2xsZWN0Tm9kZSA9ICh2YWw6IGFueSkgPT4ge1xyXG4gICAgICBpZiAodmFsICYmIHR5cGVvZiB2YWwuaWQgPT09ICdzdHJpbmcnICYmICdsYWJlbHMnIGluIHZhbCkge1xyXG4gICAgICAgIGNvbnN0IG5vZGU6IE5vZGUgPSB7XHJcbiAgICAgICAgICBpZDogdmFsLmlkLFxyXG4gICAgICAgICAgbGFiZWxzOiB2YWwubGFiZWxzIHx8IFtdLFxyXG4gICAgICAgICAgcHJvcGVydGllczogdmFsLnByb3BlcnRpZXMgfHwge30sXHJcbiAgICAgICAgfTtcclxuICAgICAgICBub2Rlcy5wdXNoKG5vZGUpO1xyXG4gICAgICAgIGZvciAoY29uc3QgbGFiZWwgb2Ygbm9kZS5sYWJlbHMpIHtcclxuICAgICAgICAgIGlmICghc2NoZW1hcy5oYXMobGFiZWwpKSB7XHJcbiAgICAgICAgICAgIHNjaGVtYXMuc2V0KGxhYmVsLCB0aGlzLmJ1aWxkU2NoZW1hRnJvbU5vZGUobGFiZWwsIG5vZGUpKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yb3dzKSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93LnZhbHVlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGxldCBpdGVtVHlwZSA9IHJvdy5nZXRUeXBlKGkpO1xyXG4gICAgICAgIGNvbnN0IHJhd1ZhbHVlID0gcm93LnZhbHVlc1tpXTtcclxuICAgICAgICBpZiAoaXRlbVR5cGUgPT09IFByb3BlcnR5VHlwZS5VTlNFVCAmJiByYXdWYWx1ZSAmJiB0eXBlb2YgcmF3VmFsdWUgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiByYXdWYWx1ZSkge1xyXG4gICAgICAgICAgaXRlbVR5cGUgPSByYXdWYWx1ZS50eXBlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuTk9ERSkge1xyXG4gICAgICAgICAgY29sbGVjdE5vZGUocm93LmdldChpKSk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLkxJU1QpIHtcclxuICAgICAgICAgIGNvbnN0IGxpc3QgPSByb3cuZ2V0KGkpO1xyXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobGlzdCkpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGxpc3QpIHtcclxuICAgICAgICAgICAgICBjb2xsZWN0Tm9kZShpdGVtKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7IG5vZGVzLCBzY2hlbWFzIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVwcmVjYXRlZCBVc2UgYWxpYXMoKSBvciBnZXQoKSBpbnN0ZWFkLiBUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi5cclxuICAgKiBFeHRyYWN0IGVkZ2VzIGZyb20gcmVzcG9uc2Ugd2l0aCBzY2hlbWEgaW5mby5cclxuICAgKiBTdXBwb3J0cyBib3RoIEVER0UgYW5kIExJU1Qgb2YgRURHRSBjb2x1bW5zLlxyXG4gICAqL1xyXG4gIGFzRWRnZXMoKTogRWRnZVJlc3VsdCB7XHJcbiAgICBjb25zdCBlZGdlczogRWRnZVtdID0gW107XHJcbiAgICBjb25zdCBzY2hlbWFzID0gbmV3IE1hcDxzdHJpbmcsIFNjaGVtYT4oKTtcclxuXHJcbiAgICBjb25zdCBjb2xsZWN0RWRnZSA9ICh2YWw6IGFueSkgPT4ge1xyXG4gICAgICBpZiAodmFsICYmIHR5cGVvZiB2YWwuaWQgPT09ICdzdHJpbmcnICYmICdsYWJlbCcgaW4gdmFsKSB7XHJcbiAgICAgICAgY29uc3QgZWRnZTogRWRnZSA9IHtcclxuICAgICAgICAgIGlkOiB2YWwuaWQsXHJcbiAgICAgICAgICBsYWJlbDogdmFsLmxhYmVsIHx8ICcnLFxyXG4gICAgICAgICAgZnJvbU5vZGVJZDogdmFsLmZyb21Ob2RlSWQgfHwgJycsXHJcbiAgICAgICAgICB0b05vZGVJZDogdmFsLnRvTm9kZUlkIHx8ICcnLFxyXG4gICAgICAgICAgcHJvcGVydGllczogdmFsLnByb3BlcnRpZXMgfHwge30sXHJcbiAgICAgICAgfTtcclxuICAgICAgICBlZGdlcy5wdXNoKGVkZ2UpO1xyXG4gICAgICAgIGlmIChlZGdlLmxhYmVsICYmICFzY2hlbWFzLmhhcyhlZGdlLmxhYmVsKSkge1xyXG4gICAgICAgICAgc2NoZW1hcy5zZXQoZWRnZS5sYWJlbCwgdGhpcy5idWlsZFNjaGVtYUZyb21FZGdlKGVkZ2UubGFiZWwsIGVkZ2UpKTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yb3dzKSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93LnZhbHVlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIGxldCBpdGVtVHlwZSA9IHJvdy5nZXRUeXBlKGkpO1xyXG4gICAgICAgIGNvbnN0IHJhd1ZhbHVlID0gcm93LnZhbHVlc1tpXTtcclxuICAgICAgICBpZiAoaXRlbVR5cGUgPT09IFByb3BlcnR5VHlwZS5VTlNFVCAmJiByYXdWYWx1ZSAmJiB0eXBlb2YgcmF3VmFsdWUgPT09ICdvYmplY3QnICYmICd0eXBlJyBpbiByYXdWYWx1ZSkge1xyXG4gICAgICAgICAgaXRlbVR5cGUgPSByYXdWYWx1ZS50eXBlO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgaWYgKGl0ZW1UeXBlID09PSBQcm9wZXJ0eVR5cGUuRURHRSkge1xyXG4gICAgICAgICAgY29sbGVjdEVkZ2Uocm93LmdldChpKSk7XHJcbiAgICAgICAgfSBlbHNlIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLkxJU1QpIHtcclxuICAgICAgICAgIGNvbnN0IGxpc3QgPSByb3cuZ2V0KGkpO1xyXG4gICAgICAgICAgaWYgKEFycmF5LmlzQXJyYXkobGlzdCkpIHtcclxuICAgICAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIGxpc3QpIHtcclxuICAgICAgICAgICAgICBjb2xsZWN0RWRnZShpdGVtKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB7IGVkZ2VzLCBzY2hlbWFzIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVwcmVjYXRlZCBVc2UgYWxpYXMoKSBvciBnZXQoKSBpbnN0ZWFkLiBUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi5cclxuICAgKiBFeHRyYWN0IHBhdGhzIGZyb20gcmVzcG9uc2UuXHJcbiAgICogUGF0aHMgYXJlIGlkZW50aWZpZWQgYnkgUHJvcGVydHlUeXBlLlBBVEggdHlwZSBpbiB0aGUgVHlwZWRWYWx1ZS5cclxuICAgKi9cclxuICBhc1BhdGhzKCk6IFBhdGhbXSB7XHJcbiAgICBjb25zdCBwYXRoczogUGF0aFtdID0gW107XHJcblxyXG4gICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yb3dzKSB7XHJcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcm93LnZhbHVlcy5sZW5ndGg7IGkrKykge1xyXG4gICAgICAgIC8vIENoZWNrIHR5cGUgZnJvbSB0eXBlcyBhcnJheSBvciBmcm9tIFR5cGVkVmFsdWUgb2JqZWN0XHJcbiAgICAgICAgbGV0IGl0ZW1UeXBlID0gcm93LmdldFR5cGUoaSk7XHJcbiAgICAgICAgY29uc3QgcmF3VmFsdWUgPSByb3cudmFsdWVzW2ldO1xyXG4gICAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLlVOU0VUICYmIHJhd1ZhbHVlICYmIHR5cGVvZiByYXdWYWx1ZSA9PT0gJ29iamVjdCcgJiYgJ3R5cGUnIGluIHJhd1ZhbHVlKSB7XHJcbiAgICAgICAgICBpdGVtVHlwZSA9IHJhd1ZhbHVlLnR5cGU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoaXRlbVR5cGUgPT09IFByb3BlcnR5VHlwZS5QQVRIKSB7XHJcbiAgICAgICAgICAvLyBDb252ZXJ0IFR5cGVkVmFsdWUgdG8gR3FsZGJQYXRoXHJcbiAgICAgICAgICBjb25zdCB2YWwgPSByb3cuZ2V0KGkpIGFzIEdxbGRiUGF0aDtcclxuICAgICAgICAgIGlmICh2YWwgJiYgQXJyYXkuaXNBcnJheSh2YWwubm9kZXMpKSB7XHJcbiAgICAgICAgICAgIC8vIENvbnZlcnQgR3FsZGJOb2RlL0dxbGRiRWRnZSB0byBOb2RlL0VkZ2VcclxuICAgICAgICAgICAgY29uc3Qgbm9kZXM6IE5vZGVbXSA9ICh2YWwubm9kZXMgfHwgW10pLm1hcCgobjogR3FsZGJOb2RlKSA9PiAoe1xyXG4gICAgICAgICAgICAgIGlkOiBuLmlkIHx8ICcnLFxyXG4gICAgICAgICAgICAgIGxhYmVsczogbi5sYWJlbHMgfHwgW10sXHJcbiAgICAgICAgICAgICAgcHJvcGVydGllczogbi5wcm9wZXJ0aWVzIHx8IHt9LFxyXG4gICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIGNvbnN0IGVkZ2VzOiBFZGdlW10gPSAodmFsLmVkZ2VzIHx8IFtdKS5tYXAoKGU6IEdxbGRiRWRnZSkgPT4gKHtcclxuICAgICAgICAgICAgICBpZDogZS5pZCB8fCAnJyxcclxuICAgICAgICAgICAgICBsYWJlbDogZS5sYWJlbCB8fCAnJyxcclxuICAgICAgICAgICAgICBmcm9tTm9kZUlkOiBlLmZyb21Ob2RlSWQgfHwgJycsXHJcbiAgICAgICAgICAgICAgdG9Ob2RlSWQ6IGUudG9Ob2RlSWQgfHwgJycsXHJcbiAgICAgICAgICAgICAgcHJvcGVydGllczogZS5wcm9wZXJ0aWVzIHx8IHt9LFxyXG4gICAgICAgICAgICB9KSk7XHJcbiAgICAgICAgICAgIHBhdGhzLnB1c2goeyBub2RlcywgZWRnZXMgfSk7XHJcbiAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBhdGhzO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogQGRlcHJlY2F0ZWQgVXNlIGFsaWFzKCkgb3IgZ2V0KCkgaW5zdGVhZC4gVGhpcyBtZXRob2Qgd2lsbCBiZSByZW1vdmVkIGluIGEgZnV0dXJlIHZlcnNpb24uXHJcbiAgICogUmV0dXJuIHJlc3BvbnNlIGFzIGdlbmVyaWMgdGFibGUuXHJcbiAgICogSWYgcmVzcG9uc2UgaXMgYSBzaW5nbGUgVEFCTEUgY29sdW1uLCB1bndyYXBzIHRoZSBHcWxkYlRhYmxlIGludG8gcHJvcGVyIGhlYWRlcnMvcm93cy5cclxuICAgKi9cclxuICBhc1RhYmxlKCk6IFRhYmxlIHtcclxuICAgIC8vIElmIHNpbmdsZSBjb2x1bW4gb2YgVEFCTEUgdHlwZSwgdW53cmFwIEdxbGRiVGFibGVcclxuICAgIGlmICh0aGlzLmNvbHVtbnMubGVuZ3RoID09PSAxICYmIHRoaXMucm93cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgIGNvbnN0IGl0ZW1UeXBlID0gdGhpcy5yb3dzWzBdLmdldFR5cGUoMCk7XHJcbiAgICAgIGlmIChpdGVtVHlwZSA9PT0gUHJvcGVydHlUeXBlLlRBQkxFKSB7XHJcbiAgICAgICAgY29uc3QgdmFsID0gdGhpcy5yb3dzWzBdLmdldCgwKSBhcyBhbnk7XHJcbiAgICAgICAgaWYgKHZhbCAmJiAnY29sdW1ucycgaW4gdmFsICYmICdyb3dzJyBpbiB2YWwpIHtcclxuICAgICAgICAgIGNvbnN0IGd0ID0gdmFsIGFzIHsgY29sdW1uczogc3RyaW5nW107IHJvd3M6IGFueVtdW10gfTtcclxuICAgICAgICAgIGNvbnN0IGhlYWRlcnM6IEhlYWRlcltdID0gZ3QuY29sdW1ucy5tYXAoKGNvbDogc3RyaW5nLCBpOiBudW1iZXIpID0+IHtcclxuICAgICAgICAgICAgbGV0IGNvbFR5cGUgPSBQcm9wZXJ0eVR5cGUuVU5TRVQ7XHJcbiAgICAgICAgICAgIGlmIChndC5yb3dzLmxlbmd0aCA+IDAgJiYgaSA8IGd0LnJvd3NbMF0ubGVuZ3RoKSB7XHJcbiAgICAgICAgICAgICAgY29uc3QgdiA9IGd0LnJvd3NbMF1baV07XHJcbiAgICAgICAgICAgICAgaWYgKHR5cGVvZiB2ID09PSAnbnVtYmVyJykgY29sVHlwZSA9IE51bWJlci5pc0ludGVnZXIodikgPyBQcm9wZXJ0eVR5cGUuSU5UNjQgOiBQcm9wZXJ0eVR5cGUuRE9VQkxFO1xyXG4gICAgICAgICAgICAgIGVsc2UgaWYgKHR5cGVvZiB2ID09PSAnc3RyaW5nJykgY29sVHlwZSA9IFByb3BlcnR5VHlwZS5TVFJJTkc7XHJcbiAgICAgICAgICAgICAgZWxzZSBpZiAodHlwZW9mIHYgPT09ICdib29sZWFuJykgY29sVHlwZSA9IFByb3BlcnR5VHlwZS5CT09MO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiB7IG5hbWU6IGNvbCwgdHlwZTogY29sVHlwZSB9O1xyXG4gICAgICAgICAgfSk7XHJcbiAgICAgICAgICByZXR1cm4geyBuYW1lOiB0aGlzLmNvbHVtbnNbMF0sIGhlYWRlcnMsIHJvd3M6IGd0LnJvd3MgfTtcclxuICAgICAgICB9XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvLyBGYWxsYmFjazogZ2VuZXJpYyBtdWx0aS1jb2x1bW4gdGFibGVcclxuICAgIGNvbnN0IGhlYWRlcnM6IEhlYWRlcltdID0gdGhpcy5jb2x1bW5zLm1hcChjb2wgPT4gKHtcclxuICAgICAgbmFtZTogY29sLFxyXG4gICAgICB0eXBlOiBQcm9wZXJ0eVR5cGUuVU5TRVQsXHJcbiAgICB9KSk7XHJcblxyXG4gICAgY29uc3QgdGFibGVSb3dzOiBhbnlbXVtdID0gdGhpcy5yb3dzLm1hcChyb3cgPT4ge1xyXG4gICAgICByZXR1cm4gdGhpcy5jb2x1bW5zLm1hcCgoXywgaSkgPT4gKGkgPCByb3cudmFsdWVzLmxlbmd0aCA/IHJvdy5nZXQoaSkgOiBudWxsKSk7XHJcbiAgICB9KTtcclxuXHJcbiAgICByZXR1cm4geyBuYW1lOiAnJywgaGVhZGVycywgcm93czogdGFibGVSb3dzIH07XHJcbiAgfVxyXG5cclxuICAvKipcclxuICAgKiBAZGVwcmVjYXRlZCBVc2UgYWxpYXMoKSBvciBnZXQoKSBpbnN0ZWFkLiBUaGlzIG1ldGhvZCB3aWxsIGJlIHJlbW92ZWQgaW4gYSBmdXR1cmUgdmVyc2lvbi5cclxuICAgKiBFeHRyYWN0IHNjYWxhciBvciBsaXN0IGF0dHJpYnV0ZSB2YWx1ZXNcclxuICAgKi9cclxuICBhc0F0dHIoY29sdW1uTmFtZTogc3RyaW5nKTogQXR0ciB7XHJcbiAgICBjb25zdCBjb2xJbmRleCA9IHRoaXMuY29sdW1ucy5pbmRleE9mKGNvbHVtbk5hbWUpO1xyXG4gICAgaWYgKGNvbEluZGV4ID09PSAtMSkge1xyXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbHVtbiBub3QgZm91bmQ6ICR7Y29sdW1uTmFtZX1gKTtcclxuICAgIH1cclxuXHJcbiAgICBjb25zdCB2YWx1ZXM6IGFueVtdID0gW107XHJcbiAgICBsZXQgYXR0clR5cGUgPSBQcm9wZXJ0eVR5cGUuVU5TRVQ7XHJcblxyXG4gICAgZm9yIChjb25zdCByb3cgb2YgdGhpcy5yb3dzKSB7XHJcbiAgICAgIGlmIChjb2xJbmRleCA8IHJvdy52YWx1ZXMubGVuZ3RoKSB7XHJcbiAgICAgICAgLy8gVHJ5IHRvIGdldCB0eXBlIGZyb20gcm93LnR5cGVzIGZpcnN0LCB0aGVuIGZyb20gVHlwZWRWYWx1ZSBvYmplY3RcclxuICAgICAgICBpZiAoYXR0clR5cGUgPT09IFByb3BlcnR5VHlwZS5VTlNFVCkge1xyXG4gICAgICAgICAgYXR0clR5cGUgPSByb3cuZ2V0VHlwZShjb2xJbmRleCk7XHJcbiAgICAgICAgICBpZiAoYXR0clR5cGUgPT09IFByb3BlcnR5VHlwZS5VTlNFVCkge1xyXG4gICAgICAgICAgICBjb25zdCByYXdWYWx1ZSA9IHJvdy52YWx1ZXNbY29sSW5kZXhdO1xyXG4gICAgICAgICAgICBpZiAocmF3VmFsdWUgJiYgdHlwZW9mIHJhd1ZhbHVlID09PSAnb2JqZWN0JyAmJiAndHlwZScgaW4gcmF3VmFsdWUpIHtcclxuICAgICAgICAgICAgICBhdHRyVHlwZSA9IHJhd1ZhbHVlLnR5cGU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgdmFsdWUgPSByb3cuZ2V0KGNvbEluZGV4KTsgIC8vIFVzZSBnZXQoKSB0byBjb252ZXJ0IFR5cGVkVmFsdWVcclxuICAgICAgICB2YWx1ZXMucHVzaCh2YWx1ZSk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4geyBuYW1lOiBjb2x1bW5OYW1lLCB0eXBlOiBhdHRyVHlwZSwgdmFsdWVzIH07XHJcbiAgfVxyXG5cclxuICAvLyBIZWxwZXIgbWV0aG9kc1xyXG5cclxuICBwcml2YXRlIGJ1aWxkU2NoZW1hRnJvbU5vZGUobGFiZWw6IHN0cmluZywgbm9kZTogTm9kZSk6IFNjaGVtYSB7XHJcbiAgICBjb25zdCBwcm9wZXJ0aWVzOiBQcm9wZXJ0eURlZltdID0gT2JqZWN0LmVudHJpZXMobm9kZS5wcm9wZXJ0aWVzKS5tYXAoKFtuYW1lLCB2YWx1ZV0pID0+ICh7XHJcbiAgICAgIG5hbWUsXHJcbiAgICAgIHR5cGU6IHRoaXMuaW5mZXJQcm9wZXJ0eVR5cGUodmFsdWUpLFxyXG4gICAgfSkpO1xyXG4gICAgcmV0dXJuIHsgbmFtZTogbGFiZWwsIHByb3BlcnRpZXMgfTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgYnVpbGRTY2hlbWFGcm9tRWRnZShsYWJlbDogc3RyaW5nLCBlZGdlOiBFZGdlKTogU2NoZW1hIHtcclxuICAgIGNvbnN0IHByb3BlcnRpZXM6IFByb3BlcnR5RGVmW10gPSBPYmplY3QuZW50cmllcyhlZGdlLnByb3BlcnRpZXMpLm1hcCgoW25hbWUsIHZhbHVlXSkgPT4gKHtcclxuICAgICAgbmFtZSxcclxuICAgICAgdHlwZTogdGhpcy5pbmZlclByb3BlcnR5VHlwZSh2YWx1ZSksXHJcbiAgICB9KSk7XHJcbiAgICByZXR1cm4geyBuYW1lOiBsYWJlbCwgcHJvcGVydGllcyB9O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbmZlclByb3BlcnR5VHlwZSh2YWx1ZTogYW55KTogUHJvcGVydHlUeXBlIHtcclxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gUHJvcGVydHlUeXBlLk5VTEw7XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnYm9vbGVhbicpIHJldHVybiBQcm9wZXJ0eVR5cGUuQk9PTDtcclxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XHJcbiAgICAgIHJldHVybiBOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSA/IFByb3BlcnR5VHlwZS5JTlQ2NCA6IFByb3BlcnR5VHlwZS5ET1VCTEU7XHJcbiAgICB9XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykgcmV0dXJuIFByb3BlcnR5VHlwZS5TVFJJTkc7XHJcbiAgICBpZiAoQnVmZmVyLmlzQnVmZmVyKHZhbHVlKSkgcmV0dXJuIFByb3BlcnR5VHlwZS5CTE9CO1xyXG4gICAgaWYgKEFycmF5LmlzQXJyYXkodmFsdWUpKSByZXR1cm4gUHJvcGVydHlUeXBlLkxJU1Q7XHJcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JykgcmV0dXJuIFByb3BlcnR5VHlwZS5NQVA7XHJcbiAgICByZXR1cm4gUHJvcGVydHlUeXBlLlVOU0VUO1xyXG4gIH1cclxufVxyXG5cclxuLyoqIFJlc3VsdCBvZiBhbiBpbnNlcnQgbm9kZXMgb3BlcmF0aW9uICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgSW5zZXJ0Tm9kZXNSZXN1bHQge1xyXG4gIHN1Y2Nlc3M6IGJvb2xlYW47XHJcbiAgbm9kZUlkczogc3RyaW5nW107XHJcbiAgbm9kZUNvdW50OiBudW1iZXI7XHJcbiAgbWVzc2FnZTogc3RyaW5nO1xyXG59XHJcblxyXG4vKiogUmVzdWx0IG9mIGFuIGluc2VydCBlZGdlcyBvcGVyYXRpb24gKi9cclxuZXhwb3J0IGludGVyZmFjZSBJbnNlcnRFZGdlc1Jlc3VsdCB7XHJcbiAgc3VjY2VzczogYm9vbGVhbjtcclxuICBlZGdlSWRzOiBzdHJpbmdbXTtcclxuICBlZGdlQ291bnQ6IG51bWJlcjtcclxuICBtZXNzYWdlOiBzdHJpbmc7XHJcbiAgc2tpcHBlZENvdW50OiBudW1iZXI7XHJcbn1cclxuXHJcbi8qKiBSZXN1bHQgb2YgYSBkZWxldGUgb3BlcmF0aW9uICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRGVsZXRlUmVzdWx0IHtcclxuICBzdWNjZXNzOiBib29sZWFuO1xyXG4gIGRlbGV0ZWRDb3VudDogbnVtYmVyO1xyXG4gIG1lc3NhZ2U6IHN0cmluZztcclxufVxyXG5cclxuLyoqIENvbmZpZ3VyYXRpb24gZm9yIHRoZSB1bmlmaWVkIEV4cG9ydCBvcGVyYXRpb24gKi9cclxuZXhwb3J0IGludGVyZmFjZSBFeHBvcnRDb25maWcge1xyXG4gIGdyYXBoTmFtZTogc3RyaW5nO1xyXG4gIGJhdGNoU2l6ZT86IG51bWJlcjtcclxuICBleHBvcnROb2Rlcz86IGJvb2xlYW47XHJcbiAgZXhwb3J0RWRnZXM/OiBib29sZWFuO1xyXG4gIG5vZGVMYWJlbHM/OiBzdHJpbmdbXTtcclxuICBlZGdlTGFiZWxzPzogc3RyaW5nW107XHJcbiAgaW5jbHVkZU1ldGFkYXRhPzogYm9vbGVhbjtcclxufVxyXG5cclxuLyoqIFN0YXRpc3RpY3MgZm9yIGFuIGV4cG9ydCBvcGVyYXRpb24gKi9cclxuZXhwb3J0IGludGVyZmFjZSBFeHBvcnRTdGF0cyB7XHJcbiAgbm9kZXNFeHBvcnRlZDogbnVtYmVyO1xyXG4gIGVkZ2VzRXhwb3J0ZWQ6IG51bWJlcjtcclxuICBieXRlc1dyaXR0ZW46IG51bWJlcjtcclxuICBkdXJhdGlvbk1zOiBudW1iZXI7XHJcbn1cclxuXHJcbi8qKiBBIGNodW5rIG9mIGV4cG9ydGVkIGRhdGEgaW4gSlNPTiBMaW5lcyBmb3JtYXQgKi9cclxuZXhwb3J0IGludGVyZmFjZSBFeHBvcnRDaHVuayB7XHJcbiAgZGF0YTogQnVmZmVyO1xyXG4gIGlzRmluYWw6IGJvb2xlYW47XHJcbiAgc3RhdHM/OiBFeHBvcnRTdGF0cztcclxufVxyXG5cclxuLyoqXHJcbiAqIEEgYmF0Y2ggb2YgZXhwb3J0ZWQgbm9kZXNcclxuICogQGRlcHJlY2F0ZWQgVXNlIGV4cG9ydCgpIHdpdGggRXhwb3J0Q29uZmlnIGluc3RlYWRcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRXhwb3J0Tm9kZXNSZXN1bHQge1xyXG4gIG5vZGVzOiBFeHBvcnRlZE5vZGVbXTtcclxuICBoYXNNb3JlOiBib29sZWFuO1xyXG59XHJcblxyXG4vKipcclxuICogQSBiYXRjaCBvZiBleHBvcnRlZCBlZGdlc1xyXG4gKiBAZGVwcmVjYXRlZCBVc2UgZXhwb3J0KCkgd2l0aCBFeHBvcnRDb25maWcgaW5zdGVhZFxyXG4gKi9cclxuZXhwb3J0IGludGVyZmFjZSBFeHBvcnRFZGdlc1Jlc3VsdCB7XHJcbiAgZWRnZXM6IEV4cG9ydGVkRWRnZVtdO1xyXG4gIGhhc01vcmU6IGJvb2xlYW47XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBBIG5vZGUgZXhwb3J0ZWQgZnJvbSB0aGUgZGF0YWJhc2VcclxuICogQGRlcHJlY2F0ZWQgVXNlIGV4cG9ydCgpIHdpdGggRXhwb3J0Q29uZmlnIGluc3RlYWRcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRXhwb3J0ZWROb2RlIHtcclxuICBpZDogc3RyaW5nO1xyXG4gIGxhYmVsczogc3RyaW5nW107XHJcbiAgcHJvcGVydGllczogUmVjb3JkPHN0cmluZywgYW55PjtcclxufVxyXG5cclxuLyoqXHJcbiAqIEFuIGVkZ2UgZXhwb3J0ZWQgZnJvbSB0aGUgZGF0YWJhc2VcclxuICogQGRlcHJlY2F0ZWQgVXNlIGV4cG9ydCgpIHdpdGggRXhwb3J0Q29uZmlnIGluc3RlYWRcclxuICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRXhwb3J0ZWRFZGdlIHtcclxuICBpZDogc3RyaW5nO1xyXG4gIGxhYmVsOiBzdHJpbmc7XHJcbiAgZnJvbU5vZGVJZDogc3RyaW5nO1xyXG4gIHRvTm9kZUlkOiBzdHJpbmc7XHJcbiAgcHJvcGVydGllczogUmVjb3JkPHN0cmluZywgYW55PjtcclxufVxyXG5cclxuLyoqIFJlcHJlc2VudHMgYSBub2RlIGluIHRoZSBncmFwaCBkYXRhYmFzZSAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIE5vZGUge1xyXG4gIGlkOiBzdHJpbmc7XHJcbiAgbGFiZWxzOiBzdHJpbmdbXTtcclxuICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xyXG59XHJcblxyXG4vKiogUmVwcmVzZW50cyBhbiBlZGdlIGluIHRoZSBncmFwaCBkYXRhYmFzZSAqL1xyXG5leHBvcnQgaW50ZXJmYWNlIEVkZ2Uge1xyXG4gIGlkOiBzdHJpbmc7XHJcbiAgbGFiZWw6IHN0cmluZztcclxuICBmcm9tTm9kZUlkOiBzdHJpbmc7XHJcbiAgdG9Ob2RlSWQ6IHN0cmluZztcclxuICBwcm9wZXJ0aWVzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+O1xyXG59XHJcblxyXG4vKiogUmVwcmVzZW50cyBhIHBhdGggaW4gdGhlIGdyYXBoIGRhdGFiYXNlICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgUGF0aCB7XHJcbiAgbm9kZXM6IE5vZGVbXTtcclxuICBlZGdlczogRWRnZVtdO1xyXG59XHJcblxyXG4vKiogUmVzdWx0IHdyYXBwZXIgZm9yIG5vZGVzIHdpdGggc2NoZW1hIGluZm9ybWF0aW9uICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgTm9kZVJlc3VsdCB7XHJcbiAgbm9kZXM6IE5vZGVbXTtcclxuICBzY2hlbWFzOiBNYXA8c3RyaW5nLCBTY2hlbWE+O1xyXG59XHJcblxyXG4vKiogUmVzdWx0IHdyYXBwZXIgZm9yIGVkZ2VzIHdpdGggc2NoZW1hIGluZm9ybWF0aW9uICovXHJcbmV4cG9ydCBpbnRlcmZhY2UgRWRnZVJlc3VsdCB7XHJcbiAgZWRnZXM6IEVkZ2VbXTtcclxuICBzY2hlbWFzOiBNYXA8c3RyaW5nLCBTY2hlbWE+O1xyXG59XHJcbiJdfQ==
|