@archont561/qgis-sdk 0.5.0 → 0.6.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/README.md +10 -14
- package/dist/bridge.d.ts +2 -2
- package/dist/bridge.js +5 -9
- package/dist/index.d.ts +4 -4
- package/dist/index.js +9 -13
- package/dist/react.d.ts +3 -3
- package/dist/react.js +6 -6
- package/dist/shared/chunk-72sjmz60.js +902 -0
- package/dist/shared/{chunk-wtv4vt4q.d.ts → chunk-8c12nwme.d.ts} +51 -71
- package/dist/shared/{chunk-3zscfm3y.d.ts → chunk-b11znjn6.d.ts} +93 -93
- package/dist/shared/{chunk-a33y575v.d.ts → chunk-nwz8n14x.d.ts} +1 -1
- package/dist/shared/chunk-xg5ntw1c.js +414 -0
- package/dist/svelte.d.ts +3 -3
- package/dist/svelte.js +6 -6
- package/dist/testing.d.ts +2 -2
- package/dist/vue.d.ts +3 -3
- package/dist/vue.js +6 -6
- package/package.json +3 -3
- package/dist/shared/chunk-8gawbn19.js +0 -433
- package/dist/shared/chunk-t1vpt5yq.js +0 -895
|
@@ -0,0 +1,902 @@
|
|
|
1
|
+
import {
|
|
2
|
+
STREAM_EVENT_KINDS,
|
|
3
|
+
isPlainRecord,
|
|
4
|
+
QgisSdkBridgeAbortedError2
|
|
5
|
+
} from "./chunk-xg5ntw1c.js";
|
|
6
|
+
import {
|
|
7
|
+
QgisSdkError2
|
|
8
|
+
} from "./chunk-2hwva3a3.js";
|
|
9
|
+
|
|
10
|
+
// src/declarations.ts
|
|
11
|
+
var MAX_SAFE_INTEGER2 = 9007199254740991;
|
|
12
|
+
var MIN_SAFE_INTEGER2 = -9007199254740991;
|
|
13
|
+
var PLUGIN_DESCRIPTION_SCHEMA_VERSION2 = 1;
|
|
14
|
+
function isSafeJsonInteger2(value) {
|
|
15
|
+
return typeof value === "number" && Number.isSafeInteger(value);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
class QgisSdkDeclarationError2 extends QgisSdkError2 {
|
|
19
|
+
constructor(message) {
|
|
20
|
+
super(message, "invalid_declaration");
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
class QgisSdkValidationIssue2 {
|
|
25
|
+
path;
|
|
26
|
+
code;
|
|
27
|
+
constructor(path, code) {
|
|
28
|
+
this.path = Object.freeze([...path]);
|
|
29
|
+
this.code = code;
|
|
30
|
+
}
|
|
31
|
+
toJSON() {
|
|
32
|
+
return {
|
|
33
|
+
path: [...this.path],
|
|
34
|
+
code: this.code
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
class QgisSdkContractValidationError2 extends QgisSdkError2 {
|
|
40
|
+
direction;
|
|
41
|
+
issues;
|
|
42
|
+
constructor(direction, issues) {
|
|
43
|
+
const prefix = direction === "request" ? "Request" : "Result";
|
|
44
|
+
super(`${prefix} contract validation failed`, "contract_validation_failed");
|
|
45
|
+
this.direction = direction;
|
|
46
|
+
this.issues = Object.freeze([...issues]);
|
|
47
|
+
}
|
|
48
|
+
toJSON() {
|
|
49
|
+
return {
|
|
50
|
+
code: this.code,
|
|
51
|
+
direction: this.direction,
|
|
52
|
+
issues: this.issues.map((issue) => issue.toJSON())
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
}
|
|
56
|
+
var DECLARATION_ID_PATTERN = /^[a-zA-Z][a-zA-Z0-9_.-]*$/;
|
|
57
|
+
var PYTHON_IDENTIFIER_PATTERN = /^[a-zA-Z_][a-zA-Z0-9_]*$/;
|
|
58
|
+
function validateDeclarationId(value, label) {
|
|
59
|
+
if (typeof value !== "string" || !DECLARATION_ID_PATTERN.test(value)) {
|
|
60
|
+
throw new QgisSdkDeclarationError2(`Invalid ${label} id: expected [a-zA-Z][a-zA-Z0-9_.-]*`);
|
|
61
|
+
}
|
|
62
|
+
return value;
|
|
63
|
+
}
|
|
64
|
+
function validateNonBlankTitle(value, id) {
|
|
65
|
+
if (typeof value !== "string" || value.trim().length === 0) {
|
|
66
|
+
throw new QgisSdkDeclarationError2(`${id}: title must be a nonempty string`);
|
|
67
|
+
}
|
|
68
|
+
return value;
|
|
69
|
+
}
|
|
70
|
+
function parseOperationHead(raw, label) {
|
|
71
|
+
if (!isPlainRecord(raw)) {
|
|
72
|
+
throw new QgisSdkDeclarationError2(`${label[0]?.toUpperCase()}${label.slice(1)} description must be an object`);
|
|
73
|
+
}
|
|
74
|
+
const id = validateDeclarationId(raw.id, label);
|
|
75
|
+
const title = validateNonBlankTitle(raw.title, id);
|
|
76
|
+
if (typeof raw.handler !== "string" || !PYTHON_IDENTIFIER_PATTERN.test(raw.handler)) {
|
|
77
|
+
throw new QgisSdkDeclarationError2(`${id}: handler must be a valid Python identifier`);
|
|
78
|
+
}
|
|
79
|
+
if (!isPlainRecord(raw.request)) {
|
|
80
|
+
throw new QgisSdkDeclarationError2(`${id}: request schema must be an object`);
|
|
81
|
+
}
|
|
82
|
+
return {
|
|
83
|
+
raw,
|
|
84
|
+
id,
|
|
85
|
+
title,
|
|
86
|
+
handler: raw.handler,
|
|
87
|
+
request: Object.freeze({ ...raw.request })
|
|
88
|
+
};
|
|
89
|
+
}
|
|
90
|
+
function parseActionDescription(raw) {
|
|
91
|
+
const head = parseOperationHead(raw, "action");
|
|
92
|
+
if (!isPlainRecord(head.raw.result)) {
|
|
93
|
+
throw new QgisSdkDeclarationError2(`${head.id}: result schema must be an object`);
|
|
94
|
+
}
|
|
95
|
+
return Object.freeze({
|
|
96
|
+
id: head.id,
|
|
97
|
+
title: head.title,
|
|
98
|
+
handler: head.handler,
|
|
99
|
+
request: head.request,
|
|
100
|
+
result: Object.freeze({ ...head.raw.result })
|
|
101
|
+
});
|
|
102
|
+
}
|
|
103
|
+
function parseStreamDescription(raw) {
|
|
104
|
+
const head = parseOperationHead(raw, "stream");
|
|
105
|
+
const declared = head.raw.events;
|
|
106
|
+
if (!isPlainRecord(declared) || Object.keys(declared).length === 0) {
|
|
107
|
+
throw new QgisSdkDeclarationError2(`${head.id}: events must map at least one event kind to a schema`);
|
|
108
|
+
}
|
|
109
|
+
const events = {};
|
|
110
|
+
for (const [kind, schema] of Object.entries(declared)) {
|
|
111
|
+
if (!STREAM_EVENT_KINDS.includes(kind)) {
|
|
112
|
+
throw new QgisSdkDeclarationError2(`${head.id}: ${kind} is not a stream event kind`);
|
|
113
|
+
}
|
|
114
|
+
if (!isPlainRecord(schema)) {
|
|
115
|
+
throw new QgisSdkDeclarationError2(`${head.id}: events.${kind} schema must be an object`);
|
|
116
|
+
}
|
|
117
|
+
events[kind] = Object.freeze({ ...schema });
|
|
118
|
+
}
|
|
119
|
+
return Object.freeze({
|
|
120
|
+
id: head.id,
|
|
121
|
+
title: head.title,
|
|
122
|
+
handler: head.handler,
|
|
123
|
+
request: head.request,
|
|
124
|
+
events: Object.freeze(events)
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
function parsePluginDescription2(input) {
|
|
128
|
+
let parsed = input;
|
|
129
|
+
if (typeof input === "string") {
|
|
130
|
+
try {
|
|
131
|
+
parsed = JSON.parse(input);
|
|
132
|
+
} catch {
|
|
133
|
+
throw new QgisSdkDeclarationError2("Plugin description is not valid JSON");
|
|
134
|
+
}
|
|
135
|
+
}
|
|
136
|
+
if (!isPlainRecord(parsed)) {
|
|
137
|
+
throw new QgisSdkDeclarationError2("Plugin description must be an object");
|
|
138
|
+
}
|
|
139
|
+
if (parsed.schema_version !== PLUGIN_DESCRIPTION_SCHEMA_VERSION2) {
|
|
140
|
+
throw new QgisSdkDeclarationError2(`Unsupported plugin description schema_version: ${String(parsed.schema_version)}`);
|
|
141
|
+
}
|
|
142
|
+
const id = validateDeclarationId(parsed.id, "plugin");
|
|
143
|
+
const title = validateNonBlankTitle(parsed.title, id);
|
|
144
|
+
if (!Array.isArray(parsed.actions)) {
|
|
145
|
+
throw new QgisSdkDeclarationError2(`${id}: actions must be an array`);
|
|
146
|
+
}
|
|
147
|
+
const declaredStreams = parsed.streams ?? [];
|
|
148
|
+
if (!Array.isArray(declaredStreams)) {
|
|
149
|
+
throw new QgisSdkDeclarationError2(`${id}: streams must be an array`);
|
|
150
|
+
}
|
|
151
|
+
const seenIds = new Set;
|
|
152
|
+
const claim = (operationId, label) => {
|
|
153
|
+
if (seenIds.has(operationId)) {
|
|
154
|
+
throw new QgisSdkDeclarationError2(`${id}: duplicate ${label} id ${operationId}`);
|
|
155
|
+
}
|
|
156
|
+
seenIds.add(operationId);
|
|
157
|
+
};
|
|
158
|
+
const actions = [];
|
|
159
|
+
for (const item of parsed.actions) {
|
|
160
|
+
const action = parseActionDescription(item);
|
|
161
|
+
claim(action.id, "action");
|
|
162
|
+
actions.push(action);
|
|
163
|
+
}
|
|
164
|
+
const streams = [];
|
|
165
|
+
for (const item of declaredStreams) {
|
|
166
|
+
const stream = parseStreamDescription(item);
|
|
167
|
+
claim(stream.id, "stream");
|
|
168
|
+
streams.push(stream);
|
|
169
|
+
}
|
|
170
|
+
const byId = (left, right) => left.id < right.id ? -1 : 1;
|
|
171
|
+
actions.sort(byId);
|
|
172
|
+
streams.sort(byId);
|
|
173
|
+
return Object.freeze({
|
|
174
|
+
schema_version: PLUGIN_DESCRIPTION_SCHEMA_VERSION2,
|
|
175
|
+
id,
|
|
176
|
+
title,
|
|
177
|
+
actions: Object.freeze(actions),
|
|
178
|
+
streams: Object.freeze(streams)
|
|
179
|
+
});
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// src/validate.ts
|
|
183
|
+
class QgisSdkContractError2 extends QgisSdkError2 {
|
|
184
|
+
operation;
|
|
185
|
+
direction;
|
|
186
|
+
issues;
|
|
187
|
+
constructor(operation, direction, issues) {
|
|
188
|
+
const detail = issues[0] === undefined ? "" : `: ${describe(issues[0])}`;
|
|
189
|
+
super(`${operation}: the ${direction} does not match the declared contract${detail}`, "contract_validation_failed");
|
|
190
|
+
this.operation = operation;
|
|
191
|
+
this.direction = direction;
|
|
192
|
+
this.issues = Object.freeze([...issues]);
|
|
193
|
+
}
|
|
194
|
+
toJSON() {
|
|
195
|
+
return {
|
|
196
|
+
code: this.code,
|
|
197
|
+
operation: this.operation,
|
|
198
|
+
direction: this.direction,
|
|
199
|
+
issues: this.issues.map((issue) => issue.toJSON())
|
|
200
|
+
};
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
function describe(issue) {
|
|
204
|
+
const where = issue.path.length === 0 ? "value" : issue.path.join(".");
|
|
205
|
+
return `${where} ${issue.code}`;
|
|
206
|
+
}
|
|
207
|
+
var PRIMITIVES = new Set([
|
|
208
|
+
"string",
|
|
209
|
+
"boolean",
|
|
210
|
+
"integer",
|
|
211
|
+
"number",
|
|
212
|
+
"null",
|
|
213
|
+
"array",
|
|
214
|
+
"object"
|
|
215
|
+
]);
|
|
216
|
+
var KNOWN_KEYWORDS = new Set([
|
|
217
|
+
"type",
|
|
218
|
+
"properties",
|
|
219
|
+
"required",
|
|
220
|
+
"additionalProperties",
|
|
221
|
+
"items",
|
|
222
|
+
"anyOf",
|
|
223
|
+
"enum",
|
|
224
|
+
"minimum",
|
|
225
|
+
"maximum",
|
|
226
|
+
"pattern",
|
|
227
|
+
"title",
|
|
228
|
+
"description",
|
|
229
|
+
"x-qgis-sdk"
|
|
230
|
+
]);
|
|
231
|
+
function validateAgainstSchema2(value, schema, options = {}) {
|
|
232
|
+
const issues = [];
|
|
233
|
+
check(value, schema, options.path ?? [], options.allowUnknown === true, issues);
|
|
234
|
+
return issues;
|
|
235
|
+
}
|
|
236
|
+
function check(value, schema, path, allowUnknown, issues) {
|
|
237
|
+
if (!isPlainRecord(schema)) {
|
|
238
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: a schema must be an object`);
|
|
239
|
+
}
|
|
240
|
+
const unknown = Object.keys(schema).filter((key) => !KNOWN_KEYWORDS.has(key));
|
|
241
|
+
if (unknown.length > 0) {
|
|
242
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: unsupported schema keyword(s) ${unknown.sort().join(", ")}`);
|
|
243
|
+
}
|
|
244
|
+
if ("anyOf" in schema) {
|
|
245
|
+
const branches = schema.anyOf;
|
|
246
|
+
if (!Array.isArray(branches) || branches.length === 0) {
|
|
247
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: anyOf must be a nonempty list`);
|
|
248
|
+
}
|
|
249
|
+
for (const branch of branches) {
|
|
250
|
+
const attempt = [];
|
|
251
|
+
check(value, branch, path, allowUnknown, attempt);
|
|
252
|
+
if (attempt.length === 0) {
|
|
253
|
+
return;
|
|
254
|
+
}
|
|
255
|
+
}
|
|
256
|
+
issues.push(new QgisSdkValidationIssue2([...path], "any_of"));
|
|
257
|
+
return;
|
|
258
|
+
}
|
|
259
|
+
if ("enum" in schema) {
|
|
260
|
+
const choices = schema.enum;
|
|
261
|
+
if (!Array.isArray(choices)) {
|
|
262
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: enum must be a list`);
|
|
263
|
+
}
|
|
264
|
+
if (!choices.some((choice) => sameJson(choice, value))) {
|
|
265
|
+
issues.push(new QgisSdkValidationIssue2([...path], "enum"));
|
|
266
|
+
}
|
|
267
|
+
return;
|
|
268
|
+
}
|
|
269
|
+
const declared = schema.type;
|
|
270
|
+
if (declared === undefined) {
|
|
271
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: a schema needs a type, anyOf or enum`);
|
|
272
|
+
}
|
|
273
|
+
if (typeof declared !== "string" || !PRIMITIVES.has(declared)) {
|
|
274
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: unsupported type ${JSON.stringify(declared)}`);
|
|
275
|
+
}
|
|
276
|
+
switch (declared) {
|
|
277
|
+
case "string":
|
|
278
|
+
checkString(value, schema, path, issues);
|
|
279
|
+
return;
|
|
280
|
+
case "boolean":
|
|
281
|
+
if (typeof value !== "boolean") {
|
|
282
|
+
issues.push(new QgisSdkValidationIssue2([...path], "type"));
|
|
283
|
+
}
|
|
284
|
+
return;
|
|
285
|
+
case "integer":
|
|
286
|
+
if (typeof value !== "number" || !Number.isInteger(value)) {
|
|
287
|
+
issues.push(new QgisSdkValidationIssue2([...path], "type"));
|
|
288
|
+
return;
|
|
289
|
+
}
|
|
290
|
+
checkBounds(value, schema, path, issues);
|
|
291
|
+
return;
|
|
292
|
+
case "number":
|
|
293
|
+
if (typeof value !== "number") {
|
|
294
|
+
issues.push(new QgisSdkValidationIssue2([...path], "type"));
|
|
295
|
+
return;
|
|
296
|
+
}
|
|
297
|
+
if (!Number.isFinite(value)) {
|
|
298
|
+
issues.push(new QgisSdkValidationIssue2([...path], "not_finite"));
|
|
299
|
+
return;
|
|
300
|
+
}
|
|
301
|
+
checkBounds(value, schema, path, issues);
|
|
302
|
+
return;
|
|
303
|
+
case "null":
|
|
304
|
+
if (value !== null) {
|
|
305
|
+
issues.push(new QgisSdkValidationIssue2([...path], "type"));
|
|
306
|
+
}
|
|
307
|
+
return;
|
|
308
|
+
case "array":
|
|
309
|
+
checkArray(value, schema, path, allowUnknown, issues);
|
|
310
|
+
return;
|
|
311
|
+
default:
|
|
312
|
+
checkObject(value, schema, path, allowUnknown, issues);
|
|
313
|
+
}
|
|
314
|
+
}
|
|
315
|
+
function checkString(value, schema, path, issues) {
|
|
316
|
+
if (typeof value !== "string") {
|
|
317
|
+
issues.push(new QgisSdkValidationIssue2([...path], "type"));
|
|
318
|
+
return;
|
|
319
|
+
}
|
|
320
|
+
const pattern = schema.pattern;
|
|
321
|
+
if (pattern === undefined || pattern === null) {
|
|
322
|
+
return;
|
|
323
|
+
}
|
|
324
|
+
if (typeof pattern !== "string") {
|
|
325
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: pattern must be a string`);
|
|
326
|
+
}
|
|
327
|
+
let expression;
|
|
328
|
+
try {
|
|
329
|
+
expression = new RegExp(`^(?:${pattern})$`, "u");
|
|
330
|
+
} catch (error) {
|
|
331
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: pattern ${JSON.stringify(pattern)} is unusable: ${String(error)}`);
|
|
332
|
+
}
|
|
333
|
+
if (!expression.test(value)) {
|
|
334
|
+
issues.push(new QgisSdkValidationIssue2([...path], "pattern"));
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function checkBounds(value, schema, path, issues) {
|
|
338
|
+
const minimum = schema.minimum;
|
|
339
|
+
if (typeof minimum === "number" && value < minimum) {
|
|
340
|
+
issues.push(new QgisSdkValidationIssue2([...path], "minimum"));
|
|
341
|
+
}
|
|
342
|
+
const maximum = schema.maximum;
|
|
343
|
+
if (typeof maximum === "number" && value > maximum) {
|
|
344
|
+
issues.push(new QgisSdkValidationIssue2([...path], "maximum"));
|
|
345
|
+
}
|
|
346
|
+
}
|
|
347
|
+
function checkArray(value, schema, path, allowUnknown, issues) {
|
|
348
|
+
if (!Array.isArray(value)) {
|
|
349
|
+
issues.push(new QgisSdkValidationIssue2([...path], "type"));
|
|
350
|
+
return;
|
|
351
|
+
}
|
|
352
|
+
const items = schema.items;
|
|
353
|
+
if (items === undefined || items === null) {
|
|
354
|
+
return;
|
|
355
|
+
}
|
|
356
|
+
value.forEach((item, index) => {
|
|
357
|
+
check(item, items, [...path, index], allowUnknown, issues);
|
|
358
|
+
});
|
|
359
|
+
}
|
|
360
|
+
function checkObject(value, schema, path, allowUnknown, issues) {
|
|
361
|
+
if (!isPlainRecord(value)) {
|
|
362
|
+
issues.push(new QgisSdkValidationIssue2([...path], "type"));
|
|
363
|
+
return;
|
|
364
|
+
}
|
|
365
|
+
const properties = schema.properties ?? {};
|
|
366
|
+
if (!isPlainRecord(properties)) {
|
|
367
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: properties must be an object`);
|
|
368
|
+
}
|
|
369
|
+
const required = schema.required ?? [];
|
|
370
|
+
if (!Array.isArray(required)) {
|
|
371
|
+
throw new QgisSdkDeclarationError2(`${where(path)}: required must be a list`);
|
|
372
|
+
}
|
|
373
|
+
for (const key of required) {
|
|
374
|
+
if (typeof key === "string" && !(key in value)) {
|
|
375
|
+
issues.push(new QgisSdkValidationIssue2([...path, key], "required"));
|
|
376
|
+
}
|
|
377
|
+
}
|
|
378
|
+
const strict = schema.additionalProperties === false && !allowUnknown;
|
|
379
|
+
for (const [key, item] of Object.entries(value)) {
|
|
380
|
+
if (Object.hasOwn(properties, key)) {
|
|
381
|
+
check(item, properties[key], [...path, key], allowUnknown, issues);
|
|
382
|
+
} else if (strict) {
|
|
383
|
+
issues.push(new QgisSdkValidationIssue2([...path, key], "unknown_property"));
|
|
384
|
+
}
|
|
385
|
+
}
|
|
386
|
+
}
|
|
387
|
+
function sameJson(a, b) {
|
|
388
|
+
if (a === b) {
|
|
389
|
+
return true;
|
|
390
|
+
}
|
|
391
|
+
if (typeof a !== typeof b || a === null || b === null) {
|
|
392
|
+
return false;
|
|
393
|
+
}
|
|
394
|
+
if (Array.isArray(a)) {
|
|
395
|
+
return Array.isArray(b) && a.length === b.length && a.every((item, index) => sameJson(item, b[index]));
|
|
396
|
+
}
|
|
397
|
+
if (isPlainRecord(a) && isPlainRecord(b)) {
|
|
398
|
+
const keys = Object.keys(a);
|
|
399
|
+
return keys.length === Object.keys(b).length && keys.every((key) => Object.hasOwn(b, key) && sameJson(a[key], b[key]));
|
|
400
|
+
}
|
|
401
|
+
return false;
|
|
402
|
+
}
|
|
403
|
+
function where(path) {
|
|
404
|
+
return path.length === 0 ? "value" : path.join(".");
|
|
405
|
+
}
|
|
406
|
+
|
|
407
|
+
// src/stores/base.ts
|
|
408
|
+
class QgisSdkStoreError2 extends QgisSdkError2 {
|
|
409
|
+
constructor(message) {
|
|
410
|
+
super(message, "store_binding");
|
|
411
|
+
}
|
|
412
|
+
}
|
|
413
|
+
|
|
414
|
+
class BaseStore {
|
|
415
|
+
snapshot;
|
|
416
|
+
listeners = new Set;
|
|
417
|
+
constructor(initial) {
|
|
418
|
+
this.snapshot = initial;
|
|
419
|
+
}
|
|
420
|
+
getSnapshot = () => this.snapshot;
|
|
421
|
+
subscribe = (listener) => {
|
|
422
|
+
this.listeners.add(listener);
|
|
423
|
+
listener(this.snapshot);
|
|
424
|
+
return () => {
|
|
425
|
+
this.listeners.delete(listener);
|
|
426
|
+
};
|
|
427
|
+
};
|
|
428
|
+
publish(next) {
|
|
429
|
+
if (Object.is(next, this.snapshot)) {
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
this.snapshot = next;
|
|
433
|
+
for (const listener of [...this.listeners]) {
|
|
434
|
+
listener(next);
|
|
435
|
+
}
|
|
436
|
+
}
|
|
437
|
+
}
|
|
438
|
+
function asError(error) {
|
|
439
|
+
return error instanceof Error ? error : new Error(String(error));
|
|
440
|
+
}
|
|
441
|
+
|
|
442
|
+
// src/stores/operation.ts
|
|
443
|
+
var IDLE = Object.freeze({ status: "idle" });
|
|
444
|
+
var PENDING = Object.freeze({ status: "pending" });
|
|
445
|
+
|
|
446
|
+
class OperationStore2 extends BaseStore {
|
|
447
|
+
operation;
|
|
448
|
+
generation = 0;
|
|
449
|
+
controller = null;
|
|
450
|
+
constructor(operation) {
|
|
451
|
+
super(IDLE);
|
|
452
|
+
this.operation = operation;
|
|
453
|
+
}
|
|
454
|
+
abort = () => {
|
|
455
|
+
this.generation += 1;
|
|
456
|
+
this.controller?.abort();
|
|
457
|
+
this.controller = null;
|
|
458
|
+
};
|
|
459
|
+
reset = () => {
|
|
460
|
+
this.abort();
|
|
461
|
+
this.publish(IDLE);
|
|
462
|
+
};
|
|
463
|
+
run = async (input) => {
|
|
464
|
+
this.abort();
|
|
465
|
+
const mine = this.generation;
|
|
466
|
+
const controller = new AbortController;
|
|
467
|
+
this.controller = controller;
|
|
468
|
+
this.publish(PENDING);
|
|
469
|
+
try {
|
|
470
|
+
const value = await this.operation(input, { signal: controller.signal });
|
|
471
|
+
if (this.generation !== mine) {
|
|
472
|
+
return;
|
|
473
|
+
}
|
|
474
|
+
this.publish({ status: "ok", value });
|
|
475
|
+
return value;
|
|
476
|
+
} catch (error) {
|
|
477
|
+
if (this.generation !== mine || error instanceof QgisSdkBridgeAbortedError2) {
|
|
478
|
+
return;
|
|
479
|
+
}
|
|
480
|
+
this.publish({ status: "error", error: asError(error) });
|
|
481
|
+
return;
|
|
482
|
+
} finally {
|
|
483
|
+
if (this.controller === controller) {
|
|
484
|
+
this.controller = null;
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
};
|
|
488
|
+
}
|
|
489
|
+
|
|
490
|
+
// src/stores/form.ts
|
|
491
|
+
var FIELD_KINDS = new Set([
|
|
492
|
+
"text",
|
|
493
|
+
"integer",
|
|
494
|
+
"number",
|
|
495
|
+
"boolean",
|
|
496
|
+
"choice",
|
|
497
|
+
"layer",
|
|
498
|
+
"crs",
|
|
499
|
+
"metres",
|
|
500
|
+
"file",
|
|
501
|
+
"directory",
|
|
502
|
+
"field",
|
|
503
|
+
"range",
|
|
504
|
+
"colour"
|
|
505
|
+
]);
|
|
506
|
+
var PRIMITIVE_KINDS = {
|
|
507
|
+
string: "text",
|
|
508
|
+
integer: "integer",
|
|
509
|
+
number: "number",
|
|
510
|
+
boolean: "boolean"
|
|
511
|
+
};
|
|
512
|
+
var NUMERIC_KINDS = new Set([
|
|
513
|
+
"integer",
|
|
514
|
+
"number",
|
|
515
|
+
"metres",
|
|
516
|
+
"range"
|
|
517
|
+
]);
|
|
518
|
+
var DETAIL_KEYS = ["minimum", "maximum", "step", "of", "filters", "alpha"];
|
|
519
|
+
function labelFor2(name) {
|
|
520
|
+
const spaced = name.replace(/_/g, " ").trim();
|
|
521
|
+
return spaced.charAt(0).toUpperCase() + spaced.slice(1).toLowerCase();
|
|
522
|
+
}
|
|
523
|
+
function concrete(schema) {
|
|
524
|
+
const branches = schema.anyOf;
|
|
525
|
+
if (!Array.isArray(branches)) {
|
|
526
|
+
return [schema, false];
|
|
527
|
+
}
|
|
528
|
+
const nonNull = branches.filter((branch) => isPlainRecord(branch) && branch.type !== "null");
|
|
529
|
+
if (nonNull.length === 1 && nonNull.length !== branches.length) {
|
|
530
|
+
return [nonNull[0], true];
|
|
531
|
+
}
|
|
532
|
+
throw new QgisSdkStoreError2("a union field must be one type or that type plus null to be rendered");
|
|
533
|
+
}
|
|
534
|
+
function kindFor(owner, name, schema) {
|
|
535
|
+
const intent = schema["x-qgis-sdk"];
|
|
536
|
+
const marked = isPlainRecord(intent) ? intent.kind : undefined;
|
|
537
|
+
if (typeof marked === "string") {
|
|
538
|
+
if (!FIELD_KINDS.has(marked)) {
|
|
539
|
+
throw new QgisSdkStoreError2(`${owner}: field ${name} has unknown kind ${JSON.stringify(marked)}`);
|
|
540
|
+
}
|
|
541
|
+
return marked;
|
|
542
|
+
}
|
|
543
|
+
if ("enum" in schema) {
|
|
544
|
+
return "choice";
|
|
545
|
+
}
|
|
546
|
+
const kind = PRIMITIVE_KINDS[String(schema.type)];
|
|
547
|
+
if (kind === undefined) {
|
|
548
|
+
throw new QgisSdkStoreError2(`${owner}: field ${name} has no input for its schema; declare a primitive, an enum or a kind`);
|
|
549
|
+
}
|
|
550
|
+
return kind;
|
|
551
|
+
}
|
|
552
|
+
function schemaFields2(schema, owner = "form") {
|
|
553
|
+
const properties = schema.properties;
|
|
554
|
+
if (!isPlainRecord(properties)) {
|
|
555
|
+
return Object.freeze([]);
|
|
556
|
+
}
|
|
557
|
+
const required = new Set(Array.isArray(schema.required) ? schema.required : []);
|
|
558
|
+
return Object.freeze(Object.entries(properties).map(([name, property]) => {
|
|
559
|
+
if (!isPlainRecord(property)) {
|
|
560
|
+
throw new QgisSdkStoreError2(`${owner}: field ${name} is not a schema`);
|
|
561
|
+
}
|
|
562
|
+
const [shape, nullable] = concrete(property);
|
|
563
|
+
const kind = kindFor(owner, name, shape);
|
|
564
|
+
const intent = isPlainRecord(shape["x-qgis-sdk"]) ? shape["x-qgis-sdk"] : {};
|
|
565
|
+
const merged = { ...shape, ...intent };
|
|
566
|
+
const details = kind === "integer" ? {} : Object.fromEntries(DETAIL_KEYS.filter((key) => (key in merged)).map((key) => [
|
|
567
|
+
key,
|
|
568
|
+
merged[key]
|
|
569
|
+
]));
|
|
570
|
+
return Object.freeze({
|
|
571
|
+
name,
|
|
572
|
+
label: labelFor2(name),
|
|
573
|
+
kind,
|
|
574
|
+
required: required.has(name) && !nullable,
|
|
575
|
+
nullable,
|
|
576
|
+
choices: Object.freeze(kind === "choice" && Array.isArray(shape.enum) ? [...shape.enum] : []),
|
|
577
|
+
details: Object.freeze(details),
|
|
578
|
+
schema: property
|
|
579
|
+
});
|
|
580
|
+
}));
|
|
581
|
+
}
|
|
582
|
+
function operationOf(qgis, id) {
|
|
583
|
+
let node = qgis;
|
|
584
|
+
for (const segment of id.split(".")) {
|
|
585
|
+
node = isPlainRecord(node) || typeof node === "function" ? node[segment] : undefined;
|
|
586
|
+
}
|
|
587
|
+
if (typeof node !== "function") {
|
|
588
|
+
throw new QgisSdkStoreError2(`${id} is not an operation of this QgisSdk`);
|
|
589
|
+
}
|
|
590
|
+
return node;
|
|
591
|
+
}
|
|
592
|
+
function coerce(field, value) {
|
|
593
|
+
if (value === "" && field.kind !== "text") {
|
|
594
|
+
return;
|
|
595
|
+
}
|
|
596
|
+
if (NUMERIC_KINDS.has(field.kind) && typeof value === "string") {
|
|
597
|
+
const trimmed = value.trim();
|
|
598
|
+
if (trimmed !== "" && /^[-+]?(\d+\.?\d*|\.\d+)([eE][-+]?\d+)?$/.test(trimmed)) {
|
|
599
|
+
const number = Number(trimmed);
|
|
600
|
+
if (field.kind !== "integer" || Number.isInteger(number)) {
|
|
601
|
+
return number;
|
|
602
|
+
}
|
|
603
|
+
}
|
|
604
|
+
}
|
|
605
|
+
return value;
|
|
606
|
+
}
|
|
607
|
+
|
|
608
|
+
class FormStore2 extends BaseStore {
|
|
609
|
+
id;
|
|
610
|
+
title;
|
|
611
|
+
fields;
|
|
612
|
+
byName;
|
|
613
|
+
request;
|
|
614
|
+
initial;
|
|
615
|
+
operation;
|
|
616
|
+
unsubscribe;
|
|
617
|
+
constructor(qgis, id, options = {}) {
|
|
618
|
+
const action = qgis.schema.actions.find((candidate) => candidate.id === id);
|
|
619
|
+
if (action === undefined) {
|
|
620
|
+
throw new QgisSdkStoreError2(`${id} is not a declared action of this schema`);
|
|
621
|
+
}
|
|
622
|
+
const fields = schemaFields2(action.request, `form ${id}`);
|
|
623
|
+
const initial = FormStore2.defaults(options.initial ?? {});
|
|
624
|
+
super(FormStore2.evaluate(initial, action.request, false, false, IDLE));
|
|
625
|
+
this.id = id;
|
|
626
|
+
this.title = action.title;
|
|
627
|
+
this.fields = fields;
|
|
628
|
+
this.byName = new Map(fields.map((field) => [field.name, field]));
|
|
629
|
+
this.request = action.request;
|
|
630
|
+
this.initial = initial;
|
|
631
|
+
this.operation = new OperationStore2(operationOf(qgis, id));
|
|
632
|
+
let first = true;
|
|
633
|
+
this.unsubscribe = this.operation.subscribe((submission) => {
|
|
634
|
+
if (first) {
|
|
635
|
+
first = false;
|
|
636
|
+
return;
|
|
637
|
+
}
|
|
638
|
+
const current = this.getSnapshot();
|
|
639
|
+
this.publish({ ...current, submission });
|
|
640
|
+
});
|
|
641
|
+
}
|
|
642
|
+
static describe(qgis, id) {
|
|
643
|
+
return qgis.schema.actions.find((candidate) => candidate.id === id);
|
|
644
|
+
}
|
|
645
|
+
static defaults(initial) {
|
|
646
|
+
return Object.freeze(Object.fromEntries(Object.entries(initial).filter(([, value]) => value !== undefined)));
|
|
647
|
+
}
|
|
648
|
+
static evaluate(values, request, dirty, submitted, submission) {
|
|
649
|
+
const issues = validateAgainstSchema2(values, request);
|
|
650
|
+
const errors = {};
|
|
651
|
+
for (const issue of issues) {
|
|
652
|
+
const [head] = issue.path;
|
|
653
|
+
const name = typeof head === "string" ? head : "";
|
|
654
|
+
if (!(name in errors)) {
|
|
655
|
+
errors[name] = issue.code;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
return Object.freeze({
|
|
659
|
+
values,
|
|
660
|
+
issues: Object.freeze(issues),
|
|
661
|
+
errors: Object.freeze(errors),
|
|
662
|
+
valid: issues.length === 0,
|
|
663
|
+
dirty,
|
|
664
|
+
submitted,
|
|
665
|
+
submission
|
|
666
|
+
});
|
|
667
|
+
}
|
|
668
|
+
set = (name, value) => {
|
|
669
|
+
this.setValues({ [name]: value });
|
|
670
|
+
};
|
|
671
|
+
setValues = (changes) => {
|
|
672
|
+
const current = this.getSnapshot();
|
|
673
|
+
const values = { ...current.values };
|
|
674
|
+
for (const [name, raw] of Object.entries(changes)) {
|
|
675
|
+
const field = this.byName.get(name);
|
|
676
|
+
if (field === undefined) {
|
|
677
|
+
throw new QgisSdkStoreError2(`${this.id} has no field ${name}`);
|
|
678
|
+
}
|
|
679
|
+
const value = coerce(field, raw);
|
|
680
|
+
if (value === undefined) {
|
|
681
|
+
delete values[name];
|
|
682
|
+
} else {
|
|
683
|
+
values[name] = value;
|
|
684
|
+
}
|
|
685
|
+
}
|
|
686
|
+
this.publish(FormStore2.evaluate(Object.freeze(values), this.request, true, current.submitted, current.submission));
|
|
687
|
+
};
|
|
688
|
+
field(name) {
|
|
689
|
+
const field = this.byName.get(name);
|
|
690
|
+
if (field === undefined) {
|
|
691
|
+
throw new QgisSdkStoreError2(`${this.id} has no field ${name}`);
|
|
692
|
+
}
|
|
693
|
+
return field;
|
|
694
|
+
}
|
|
695
|
+
reset = () => {
|
|
696
|
+
this.operation.reset();
|
|
697
|
+
this.publish(FormStore2.evaluate(this.initial, this.request, false, false, IDLE));
|
|
698
|
+
};
|
|
699
|
+
abort = () => {
|
|
700
|
+
this.operation.abort();
|
|
701
|
+
};
|
|
702
|
+
submit = async () => {
|
|
703
|
+
const current = this.getSnapshot();
|
|
704
|
+
if (!current.valid) {
|
|
705
|
+
this.publish({ ...current, submitted: true });
|
|
706
|
+
return;
|
|
707
|
+
}
|
|
708
|
+
if (!current.submitted) {
|
|
709
|
+
this.publish({ ...current, submitted: true });
|
|
710
|
+
}
|
|
711
|
+
return this.operation.run(current.values);
|
|
712
|
+
};
|
|
713
|
+
dispose() {
|
|
714
|
+
this.operation.abort();
|
|
715
|
+
this.unsubscribe();
|
|
716
|
+
}
|
|
717
|
+
}
|
|
718
|
+
function formStore2(qgis, id, options) {
|
|
719
|
+
return new FormStore2(qgis, id, options);
|
|
720
|
+
}
|
|
721
|
+
|
|
722
|
+
// src/stores/host-query.ts
|
|
723
|
+
var IDLE_QUERY = Object.freeze({ status: "idle" });
|
|
724
|
+
|
|
725
|
+
class HostQueryStore2 extends BaseStore {
|
|
726
|
+
qgis;
|
|
727
|
+
operation;
|
|
728
|
+
loader;
|
|
729
|
+
generation = 0;
|
|
730
|
+
controller = null;
|
|
731
|
+
constructor(qgis, operation, loader) {
|
|
732
|
+
super(IDLE_QUERY);
|
|
733
|
+
this.qgis = qgis;
|
|
734
|
+
this.operation = operation;
|
|
735
|
+
this.loader = loader;
|
|
736
|
+
}
|
|
737
|
+
abort = () => {
|
|
738
|
+
this.generation += 1;
|
|
739
|
+
this.controller?.abort();
|
|
740
|
+
this.controller = null;
|
|
741
|
+
};
|
|
742
|
+
reset = () => {
|
|
743
|
+
this.abort();
|
|
744
|
+
this.publish(IDLE_QUERY);
|
|
745
|
+
};
|
|
746
|
+
refresh = async () => {
|
|
747
|
+
this.abort();
|
|
748
|
+
const mine = this.generation;
|
|
749
|
+
const controller = new AbortController;
|
|
750
|
+
this.controller = controller;
|
|
751
|
+
this.publish({ status: "loading" });
|
|
752
|
+
try {
|
|
753
|
+
await this.qgis.ready;
|
|
754
|
+
if (this.generation !== mine) {
|
|
755
|
+
return;
|
|
756
|
+
}
|
|
757
|
+
if (!this.qgis.host.granted.includes(this.operation)) {
|
|
758
|
+
this.publish({
|
|
759
|
+
status: "refused",
|
|
760
|
+
operation: this.operation,
|
|
761
|
+
message: `this view was not granted ${this.operation}`
|
|
762
|
+
});
|
|
763
|
+
return;
|
|
764
|
+
}
|
|
765
|
+
const value = await this.loader(this.qgis.host, {
|
|
766
|
+
signal: controller.signal
|
|
767
|
+
});
|
|
768
|
+
if (this.generation !== mine) {
|
|
769
|
+
return;
|
|
770
|
+
}
|
|
771
|
+
this.publish({ status: "ok", value });
|
|
772
|
+
return value;
|
|
773
|
+
} catch (error) {
|
|
774
|
+
if (this.generation !== mine || error instanceof QgisSdkBridgeAbortedError2) {
|
|
775
|
+
return;
|
|
776
|
+
}
|
|
777
|
+
this.publish({ status: "error", error: asError(error) });
|
|
778
|
+
return;
|
|
779
|
+
} finally {
|
|
780
|
+
if (this.controller === controller) {
|
|
781
|
+
this.controller = null;
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
};
|
|
785
|
+
}
|
|
786
|
+
function layersQuery2(qgis, options = {}) {
|
|
787
|
+
return new HostQueryStore2(qgis, "layers.list", async (host, { signal }) => {
|
|
788
|
+
const items = [];
|
|
789
|
+
let cursor;
|
|
790
|
+
do {
|
|
791
|
+
const page = await host.layers.list({
|
|
792
|
+
...cursor === undefined ? {} : { cursor },
|
|
793
|
+
...options.pageSize === undefined ? {} : { limit: options.pageSize }
|
|
794
|
+
}, { signal });
|
|
795
|
+
items.push(...page.items);
|
|
796
|
+
cursor = page.next_cursor;
|
|
797
|
+
} while (cursor !== undefined);
|
|
798
|
+
return Object.freeze(items);
|
|
799
|
+
});
|
|
800
|
+
}
|
|
801
|
+
function layerFieldsQuery2(qgis, layerId) {
|
|
802
|
+
return new HostQueryStore2(qgis, "layers.get", async (host, { signal }) => {
|
|
803
|
+
const layer = await host.layers.get({ layer_id: layerId }, { signal });
|
|
804
|
+
return Object.freeze([...layer.field_names]);
|
|
805
|
+
});
|
|
806
|
+
}
|
|
807
|
+
|
|
808
|
+
// src/stores/stream.ts
|
|
809
|
+
var IDLE_STREAM = Object.freeze({
|
|
810
|
+
status: "idle",
|
|
811
|
+
lastEvent: null,
|
|
812
|
+
terminal: null,
|
|
813
|
+
error: null
|
|
814
|
+
});
|
|
815
|
+
function stableKey2(value) {
|
|
816
|
+
return JSON.stringify(value, (_key, item) => isPlainRecord(item) ? Object.fromEntries(Object.entries(item).sort(([a], [b]) => a < b ? -1 : a > b ? 1 : 0)) : item);
|
|
817
|
+
}
|
|
818
|
+
|
|
819
|
+
class StreamStore2 extends BaseStore {
|
|
820
|
+
open;
|
|
821
|
+
handlers;
|
|
822
|
+
key = null;
|
|
823
|
+
cancel = null;
|
|
824
|
+
constructor(open, handlers = {}) {
|
|
825
|
+
super(IDLE_STREAM);
|
|
826
|
+
this.open = open;
|
|
827
|
+
this.handlers = handlers;
|
|
828
|
+
}
|
|
829
|
+
setHandlers(handlers) {
|
|
830
|
+
this.handlers = handlers;
|
|
831
|
+
}
|
|
832
|
+
setInput = (input) => {
|
|
833
|
+
const key = input === null ? null : stableKey2(input);
|
|
834
|
+
if (key === this.key) {
|
|
835
|
+
return;
|
|
836
|
+
}
|
|
837
|
+
this.cancel?.();
|
|
838
|
+
this.cancel = null;
|
|
839
|
+
this.key = key;
|
|
840
|
+
if (input === null || key === null) {
|
|
841
|
+
this.publish(IDLE_STREAM);
|
|
842
|
+
return;
|
|
843
|
+
}
|
|
844
|
+
this.cancel = this.start(input);
|
|
845
|
+
};
|
|
846
|
+
close = () => {
|
|
847
|
+
this.setInput(null);
|
|
848
|
+
};
|
|
849
|
+
start(input) {
|
|
850
|
+
let cancelled = false;
|
|
851
|
+
let handle = null;
|
|
852
|
+
const update = (change) => {
|
|
853
|
+
if (!cancelled) {
|
|
854
|
+
this.publish(change(this.getSnapshot()));
|
|
855
|
+
}
|
|
856
|
+
};
|
|
857
|
+
this.publish({
|
|
858
|
+
status: "opening",
|
|
859
|
+
lastEvent: null,
|
|
860
|
+
terminal: null,
|
|
861
|
+
error: null
|
|
862
|
+
});
|
|
863
|
+
this.open(input, {
|
|
864
|
+
onEvent: (event) => {
|
|
865
|
+
if (cancelled) {
|
|
866
|
+
return;
|
|
867
|
+
}
|
|
868
|
+
this.handlers.onEvent?.(event);
|
|
869
|
+
update((previous) => ({ ...previous, lastEvent: event }));
|
|
870
|
+
},
|
|
871
|
+
onTerminal: (terminal) => {
|
|
872
|
+
if (cancelled) {
|
|
873
|
+
return;
|
|
874
|
+
}
|
|
875
|
+
this.handlers.onTerminal?.(terminal);
|
|
876
|
+
update((previous) => ({ ...previous, status: "ended", terminal }));
|
|
877
|
+
}
|
|
878
|
+
}).then((opened) => {
|
|
879
|
+
if (cancelled) {
|
|
880
|
+
opened.close();
|
|
881
|
+
return;
|
|
882
|
+
}
|
|
883
|
+
handle = opened;
|
|
884
|
+
update((previous) => previous.status === "ended" ? previous : { ...previous, status: "open" });
|
|
885
|
+
}, (error) => {
|
|
886
|
+
update(() => ({
|
|
887
|
+
status: "failed",
|
|
888
|
+
lastEvent: null,
|
|
889
|
+
terminal: null,
|
|
890
|
+
error: asError(error)
|
|
891
|
+
}));
|
|
892
|
+
});
|
|
893
|
+
return () => {
|
|
894
|
+
cancelled = true;
|
|
895
|
+
handle?.close();
|
|
896
|
+
};
|
|
897
|
+
}
|
|
898
|
+
}
|
|
899
|
+
export { MAX_SAFE_INTEGER2, MIN_SAFE_INTEGER2, PLUGIN_DESCRIPTION_SCHEMA_VERSION2, isSafeJsonInteger2, QgisSdkDeclarationError2, QgisSdkValidationIssue2, QgisSdkContractValidationError2, parsePluginDescription2, QgisSdkContractError2, validateAgainstSchema2, QgisSdkStoreError2, OperationStore2, labelFor2, schemaFields2, FormStore2, formStore2, HostQueryStore2, layersQuery2, layerFieldsQuery2, stableKey2, StreamStore2 };
|
|
900
|
+
|
|
901
|
+
//# debugId=DD645B0085B7656764756E2164756E21
|
|
902
|
+
//# sourceMappingURL=data:application/json;base64,ewogICJ2ZXJzaW9uIjogMywKICAic291cmNlcyI6IFsic3JjL2RlY2xhcmF0aW9ucy50cyIsICJzcmMvdmFsaWRhdGUudHMiLCAic3JjL3N0b3Jlcy9iYXNlLnRzIiwgInNyYy9zdG9yZXMvb3BlcmF0aW9uLnRzIiwgInNyYy9zdG9yZXMvZm9ybS50cyIsICJzcmMvc3RvcmVzL2hvc3QtcXVlcnkudHMiLCAic3JjL3N0b3Jlcy9zdHJlYW0udHMiXSwKICAic291cmNlc0NvbnRlbnQiOiBbCiAgICAiLyoqXG4gKiBUaGUgdmVyc2lvbiAxIHBsdWdpbi1kZXNjcmlwdGlvbiBjb250cmFjdCBhbmQgaXRzIHdpcmUgbGltaXRzLlxuICpcbiAqIE1pcnJvcnMgdGhlIFFHSVMtZnJlZSBgcWdpc19zZGsubW9kZWxzYCBhbmQgYHFnaXNfc2RrLmRlY2xhcmF0aW9uc2BcbiAqIChgc2NoZW1hX3ZlcnNpb24gPSAxYCkgY29udHJhY3RzIHdpdGhvdXQgaW1wb3J0aW5nIGJyb3dzZXIgb3IgUXQgZ2xvYmFscy5cbiAqIGBwYXJzZVBsdWdpbkRlc2NyaXB0aW9uYCBpcyB0aGUgYnJvd3Nlci1zaWRlIHJlYWRlciBvZiB3aGF0XG4gKiBgZGVzY3JpYmUoYXBwKS50b19qc29uKClgIGVtaXRzOyBgcWdpcy1zZGsgYnJpZGdlIGdlbmVyYXRlYCBpcyB0aGVcbiAqIGJ1aWxkLXRpbWUgb25lLlxuICovXG5cbmltcG9ydCB7IFFnaXNTZGtFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgaXNQbGFpblJlY29yZCwgU1RSRUFNX0VWRU5UX0tJTkRTIH0gZnJvbSBcIi4vaW50ZXJuYWxcIjtcblxuZXhwb3J0IGNvbnN0IE1BWF9TQUZFX0lOVEVHRVI6IG51bWJlciA9IDlfMDA3XzE5OV8yNTRfNzQwXzk5MTtcbmV4cG9ydCBjb25zdCBNSU5fU0FGRV9JTlRFR0VSOiBudW1iZXIgPSAtOV8wMDdfMTk5XzI1NF83NDBfOTkxO1xuZXhwb3J0IGNvbnN0IFBMVUdJTl9ERVNDUklQVElPTl9TQ0hFTUFfVkVSU0lPTjogMSA9IDE7XG5cbmV4cG9ydCB0eXBlIFZhbGlkYXRpb25EaXJlY3Rpb24gPSBcInJlcXVlc3RcIiB8IFwicmVzdWx0XCI7XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VyaWFsaXplZFZhbGlkYXRpb25Jc3N1ZSB7XG5cdHJlYWRvbmx5IHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW107XG5cdHJlYWRvbmx5IGNvZGU6IHN0cmluZztcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJpYWxpemVkQ29udHJhY3RWYWxpZGF0aW9uRXJyb3Ige1xuXHRyZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGRpcmVjdGlvbjogVmFsaWRhdGlvbkRpcmVjdGlvbjtcblx0cmVhZG9ubHkgaXNzdWVzOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQWN0aW9uRGVzY3JpcHRpb24ge1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBoYW5kbGVyOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcblx0cmVhZG9ubHkgcmVzdWx0OiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG59XG5cbi8qKiBUaGUgZXZlbnQga2luZHMgYSBzdHJlYW0gbWF5IGRlY2xhcmU7IHRoZSBmcmFtZSBjYXJyaWVzIHRoZSBzYW1lIHRocmVlLiAqL1xuZXhwb3J0IHR5cGUgU3RyZWFtRXZlbnRLaW5kID0gXCJkYXRhXCIgfCBcInByb2dyZXNzXCIgfCBcInN0YXRlXCI7XG5cbi8qKlxuICogQSBkZWNsYXJlZCBzdHJlYW0gKGRlY2lzaW9uLTI4KTogYSByZXF1ZXN0IGluLCBvbmUgcGF5bG9hZCBzY2hlbWEgcGVyXG4gKiBkZWNsYXJlZCBldmVudCBraW5kIG91dC4gVGhlcmUgaXMgbm8gYHJlc3VsdGA6IHRoZSByZXBseSB0byBhIHN1YnNjcmlwdGlvbiBpc1xuICogdGhlIHByb3RvY29sJ3MgYWNrbm93bGVkZ2VtZW50LCBub3Qgc29tZXRoaW5nIGFuIGF1dGhvciBkZWNsYXJlcy5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1EZXNjcmlwdGlvbiB7XG5cdHJlYWRvbmx5IGlkOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHRpdGxlOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGhhbmRsZXI6IHN0cmluZztcblx0cmVhZG9ubHkgcmVxdWVzdDogUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuXHRyZWFkb25seSBldmVudHM6IFJlYWRvbmx5PFxuXHRcdFBhcnRpYWw8UmVjb3JkPFN0cmVhbUV2ZW50S2luZCwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+Pj5cblx0Pjtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBQbHVnaW5EZXNjcmlwdGlvbiB7XG5cdHJlYWRvbmx5IHNjaGVtYV92ZXJzaW9uOiAxO1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBhY3Rpb25zOiByZWFkb25seSBBY3Rpb25EZXNjcmlwdGlvbltdO1xuXHQvKiogRGVjbGFyZWQgc3RyZWFtczsgYSBkZXNjcmlwdGlvbiBmcm9tIGEgaG9zdCB0aGF0IHByZWRhdGVzIHRoZW0gaXMgZW1wdHkuICovXG5cdHJlYWRvbmx5IHN0cmVhbXM6IHJlYWRvbmx5IFN0cmVhbURlc2NyaXB0aW9uW107XG59XG5cbi8qKlxuICogUmV0dXJuIHdoZXRoZXIgYHZhbHVlYCBpcyBhIGZpbml0ZSBpbnRlZ2VyIHdpdGhpbiB0aGUgSmF2YVNjcmlwdC1zYWZlIHdpcmUgcmFuZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NhZmVKc29uSW50ZWdlcih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIG51bWJlciB7XG5cdHJldHVybiB0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzU2FmZUludGVnZXIodmFsdWUpO1xufVxuXG4vKipcbiAqIEEgZGVjbGFyYXRpb24gY2Fubm90IGJlIHJlcHJlc2VudGVkIG9yIHBhcnNlZCBpbiB0aGUgdmVyc2lvbmVkIGNvbnRyYWN0LlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgY29uc3RydWN0b3IobWVzc2FnZTogc3RyaW5nKSB7XG5cdFx0c3VwZXIobWVzc2FnZSwgXCJpbnZhbGlkX2RlY2xhcmF0aW9uXCIpO1xuXHR9XG59XG5cbi8qKlxuICogU2FmZSwgc3RydWN0dXJlZCBsb2NhdGlvbiBhbmQgY2F0ZWdvcnkgZm9yIGEgcmVqZWN0ZWQgY29udHJhY3QgdmFsdWUuXG4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlIHtcblx0cHVibGljIHJlYWRvbmx5IHBhdGg6IHJlYWRvbmx5IChzdHJpbmcgfCBudW1iZXIpW107XG5cdHB1YmxpYyByZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKHBhdGg6IHJlYWRvbmx5IChzdHJpbmcgfCBudW1iZXIpW10sIGNvZGU6IHN0cmluZykge1xuXHRcdHRoaXMucGF0aCA9IE9iamVjdC5mcmVlemUoWy4uLnBhdGhdKTtcblx0XHR0aGlzLmNvZGUgPSBjb2RlO1xuXHR9XG5cblx0cHVibGljIHRvSlNPTigpOiBTZXJpYWxpemVkVmFsaWRhdGlvbklzc3VlIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0cGF0aDogWy4uLnRoaXMucGF0aF0sXG5cdFx0XHRjb2RlOiB0aGlzLmNvZGUsXG5cdFx0fTtcblx0fVxufVxuXG4vKipcbiAqIEEgcmVxdWVzdCBvciByZXN1bHQgZGlkIG5vdCBzYXRpc2Z5IGl0cyBkZWNsYXJlZCB3aXJlIGNvbnRyYWN0LlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka0NvbnRyYWN0VmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgUWdpc1Nka0Vycm9yIHtcblx0cHVibGljIHJlYWRvbmx5IGRpcmVjdGlvbjogVmFsaWRhdGlvbkRpcmVjdGlvbjtcblx0cHVibGljIHJlYWRvbmx5IGlzc3VlczogcmVhZG9ubHkgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRkaXJlY3Rpb246IFZhbGlkYXRpb25EaXJlY3Rpb24sXG5cdFx0aXNzdWVzOiByZWFkb25seSBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10sXG5cdCkge1xuXHRcdGNvbnN0IHByZWZpeCA9IGRpcmVjdGlvbiA9PT0gXCJyZXF1ZXN0XCIgPyBcIlJlcXVlc3RcIiA6IFwiUmVzdWx0XCI7XG5cdFx0c3VwZXIoYCR7cHJlZml4fSBjb250cmFjdCB2YWxpZGF0aW9uIGZhaWxlZGAsIFwiY29udHJhY3RfdmFsaWRhdGlvbl9mYWlsZWRcIik7XG5cdFx0dGhpcy5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG5cdFx0dGhpcy5pc3N1ZXMgPSBPYmplY3QuZnJlZXplKFsuLi5pc3N1ZXNdKTtcblx0fVxuXG5cdHB1YmxpYyB0b0pTT04oKTogU2VyaWFsaXplZENvbnRyYWN0VmFsaWRhdGlvbkVycm9yIHtcblx0XHRyZXR1cm4ge1xuXHRcdFx0Y29kZTogdGhpcy5jb2RlLFxuXHRcdFx0ZGlyZWN0aW9uOiB0aGlzLmRpcmVjdGlvbixcblx0XHRcdGlzc3VlczogdGhpcy5pc3N1ZXMubWFwKChpc3N1ZSkgPT4gaXNzdWUudG9KU09OKCkpLFxuXHRcdH07XG5cdH1cbn1cblxuY29uc3QgREVDTEFSQVRJT05fSURfUEFUVEVSTiA9IC9eW2EtekEtWl1bYS16QS1aMC05Xy4tXSokLztcbmNvbnN0IFBZVEhPTl9JREVOVElGSUVSX1BBVFRFUk4gPSAvXlthLXpBLVpfXVthLXpBLVowLTlfXSokLztcblxuZnVuY3Rpb24gdmFsaWRhdGVEZWNsYXJhdGlvbklkKHZhbHVlOiB1bmtub3duLCBsYWJlbDogc3RyaW5nKTogc3RyaW5nIHtcblx0aWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIiB8fCAhREVDTEFSQVRJT05fSURfUEFUVEVSTi50ZXN0KHZhbHVlKSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGBJbnZhbGlkICR7bGFiZWx9IGlkOiBleHBlY3RlZCBbYS16QS1aXVthLXpBLVowLTlfLi1dKmAsXG5cdFx0KTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHZhbGlkYXRlTm9uQmxhbmtUaXRsZSh2YWx1ZTogdW5rbm93biwgaWQ6IHN0cmluZyk6IHN0cmluZyB7XG5cdGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgfHwgdmFsdWUudHJpbSgpLmxlbmd0aCA9PT0gMCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihgJHtpZH06IHRpdGxlIG11c3QgYmUgYSBub25lbXB0eSBzdHJpbmdgKTtcblx0fVxuXHRyZXR1cm4gdmFsdWU7XG59XG5cbmZ1bmN0aW9uIHBhcnNlT3BlcmF0aW9uSGVhZChcblx0cmF3OiB1bmtub3duLFxuXHRsYWJlbDogc3RyaW5nLFxuKToge1xuXHRyZWFkb25seSByYXc6IFJlY29yZDxzdHJpbmcsIHVua25vd24+O1xuXHRyZWFkb25seSBpZDogc3RyaW5nO1xuXHRyZWFkb25seSB0aXRsZTogc3RyaW5nO1xuXHRyZWFkb25seSBoYW5kbGVyOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHJlcXVlc3Q6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcbn0ge1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQocmF3KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2xhYmVsWzBdPy50b1VwcGVyQ2FzZSgpfSR7bGFiZWwuc2xpY2UoMSl9IGRlc2NyaXB0aW9uIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IGlkID0gdmFsaWRhdGVEZWNsYXJhdGlvbklkKHJhdy5pZCwgbGFiZWwpO1xuXHRjb25zdCB0aXRsZSA9IHZhbGlkYXRlTm9uQmxhbmtUaXRsZShyYXcudGl0bGUsIGlkKTtcblx0aWYgKFxuXHRcdHR5cGVvZiByYXcuaGFuZGxlciAhPT0gXCJzdHJpbmdcIiB8fFxuXHRcdCFQWVRIT05fSURFTlRJRklFUl9QQVRURVJOLnRlc3QocmF3LmhhbmRsZXIpXG5cdCkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2lkfTogaGFuZGxlciBtdXN0IGJlIGEgdmFsaWQgUHl0aG9uIGlkZW50aWZpZXJgLFxuXHRcdCk7XG5cdH1cblx0aWYgKCFpc1BsYWluUmVjb3JkKHJhdy5yZXF1ZXN0KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2lkfTogcmVxdWVzdCBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3RgLFxuXHRcdCk7XG5cdH1cblx0cmV0dXJuIHtcblx0XHRyYXcsXG5cdFx0aWQsXG5cdFx0dGl0bGUsXG5cdFx0aGFuZGxlcjogcmF3LmhhbmRsZXIsXG5cdFx0cmVxdWVzdDogT2JqZWN0LmZyZWV6ZSh7IC4uLnJhdy5yZXF1ZXN0IH0pLFxuXHR9O1xufVxuXG5mdW5jdGlvbiBwYXJzZUFjdGlvbkRlc2NyaXB0aW9uKHJhdzogdW5rbm93bik6IEFjdGlvbkRlc2NyaXB0aW9uIHtcblx0Y29uc3QgaGVhZCA9IHBhcnNlT3BlcmF0aW9uSGVhZChyYXcsIFwiYWN0aW9uXCIpO1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQoaGVhZC5yYXcucmVzdWx0KSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke2hlYWQuaWR9OiByZXN1bHQgc2NoZW1hIG11c3QgYmUgYW4gb2JqZWN0YCxcblx0XHQpO1xuXHR9XG5cdHJldHVybiBPYmplY3QuZnJlZXplKHtcblx0XHRpZDogaGVhZC5pZCxcblx0XHR0aXRsZTogaGVhZC50aXRsZSxcblx0XHRoYW5kbGVyOiBoZWFkLmhhbmRsZXIsXG5cdFx0cmVxdWVzdDogaGVhZC5yZXF1ZXN0LFxuXHRcdHJlc3VsdDogT2JqZWN0LmZyZWV6ZSh7IC4uLmhlYWQucmF3LnJlc3VsdCB9KSxcblx0fSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3RyZWFtRGVzY3JpcHRpb24ocmF3OiB1bmtub3duKTogU3RyZWFtRGVzY3JpcHRpb24ge1xuXHRjb25zdCBoZWFkID0gcGFyc2VPcGVyYXRpb25IZWFkKHJhdywgXCJzdHJlYW1cIik7XG5cdGNvbnN0IGRlY2xhcmVkID0gaGVhZC5yYXcuZXZlbnRzO1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQoZGVjbGFyZWQpIHx8IE9iamVjdC5rZXlzKGRlY2xhcmVkKS5sZW5ndGggPT09IDApIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHtoZWFkLmlkfTogZXZlbnRzIG11c3QgbWFwIGF0IGxlYXN0IG9uZSBldmVudCBraW5kIHRvIGEgc2NoZW1hYCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IGV2ZW50czogUGFydGlhbDxcblx0XHRSZWNvcmQ8U3RyZWFtRXZlbnRLaW5kLCBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4+XG5cdD4gPSB7fTtcblx0Zm9yIChjb25zdCBba2luZCwgc2NoZW1hXSBvZiBPYmplY3QuZW50cmllcyhkZWNsYXJlZCkpIHtcblx0XHRpZiAoIVNUUkVBTV9FVkVOVF9LSU5EUy5pbmNsdWRlcyhraW5kIGFzIFN0cmVhbUV2ZW50S2luZCkpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aGVhZC5pZH06ICR7a2luZH0gaXMgbm90IGEgc3RyZWFtIGV2ZW50IGtpbmRgLFxuXHRcdFx0KTtcblx0XHR9XG5cdFx0aWYgKCFpc1BsYWluUmVjb3JkKHNjaGVtYSkpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aGVhZC5pZH06IGV2ZW50cy4ke2tpbmR9IHNjaGVtYSBtdXN0IGJlIGFuIG9iamVjdGAsXG5cdFx0XHQpO1xuXHRcdH1cblx0XHRldmVudHNba2luZCBhcyBTdHJlYW1FdmVudEtpbmRdID0gT2JqZWN0LmZyZWV6ZSh7IC4uLnNjaGVtYSB9KTtcblx0fVxuXHRyZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG5cdFx0aWQ6IGhlYWQuaWQsXG5cdFx0dGl0bGU6IGhlYWQudGl0bGUsXG5cdFx0aGFuZGxlcjogaGVhZC5oYW5kbGVyLFxuXHRcdHJlcXVlc3Q6IGhlYWQucmVxdWVzdCxcblx0XHRldmVudHM6IE9iamVjdC5mcmVlemUoZXZlbnRzKSxcblx0fSk7XG59XG5cbi8qKlxuICogUGFyc2UgYW5kIHZhbGlkYXRlIGEgdmVyc2lvbiAxIGBQbHVnaW5EZXNjcmlwdGlvbmAgZW1pdHRlZCBieSBgZGVzY3JpYmUoYXBwKWAuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVBsdWdpbkRlc2NyaXB0aW9uKFxuXHRpbnB1dDogc3RyaW5nIHwgUmVhZG9ubHk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+LFxuKTogUGx1Z2luRGVzY3JpcHRpb24ge1xuXHRsZXQgcGFyc2VkOiB1bmtub3duID0gaW5wdXQ7XG5cdGlmICh0eXBlb2YgaW5wdXQgPT09IFwic3RyaW5nXCIpIHtcblx0XHR0cnkge1xuXHRcdFx0cGFyc2VkID0gSlNPTi5wYXJzZShpbnB1dCk7XG5cdFx0fSBjYXRjaCB7XG5cdFx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXCJQbHVnaW4gZGVzY3JpcHRpb24gaXMgbm90IHZhbGlkIEpTT05cIik7XG5cdFx0fVxuXHR9XG5cdGlmICghaXNQbGFpblJlY29yZChwYXJzZWQpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFwiUGx1Z2luIGRlc2NyaXB0aW9uIG11c3QgYmUgYW4gb2JqZWN0XCIpO1xuXHR9XG5cdGlmIChwYXJzZWQuc2NoZW1hX3ZlcnNpb24gIT09IFBMVUdJTl9ERVNDUklQVElPTl9TQ0hFTUFfVkVSU0lPTikge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGBVbnN1cHBvcnRlZCBwbHVnaW4gZGVzY3JpcHRpb24gc2NoZW1hX3ZlcnNpb246ICR7U3RyaW5nKHBhcnNlZC5zY2hlbWFfdmVyc2lvbil9YCxcblx0XHQpO1xuXHR9XG5cdGNvbnN0IGlkID0gdmFsaWRhdGVEZWNsYXJhdGlvbklkKHBhcnNlZC5pZCwgXCJwbHVnaW5cIik7XG5cdGNvbnN0IHRpdGxlID0gdmFsaWRhdGVOb25CbGFua1RpdGxlKHBhcnNlZC50aXRsZSwgaWQpO1xuXHRpZiAoIUFycmF5LmlzQXJyYXkocGFyc2VkLmFjdGlvbnMpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKGAke2lkfTogYWN0aW9ucyBtdXN0IGJlIGFuIGFycmF5YCk7XG5cdH1cblx0Y29uc3QgZGVjbGFyZWRTdHJlYW1zID0gcGFyc2VkLnN0cmVhbXMgPz8gW107XG5cdGlmICghQXJyYXkuaXNBcnJheShkZWNsYXJlZFN0cmVhbXMpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKGAke2lkfTogc3RyZWFtcyBtdXN0IGJlIGFuIGFycmF5YCk7XG5cdH1cblx0Ly8gQWN0aW9ucyBhbmQgc3RyZWFtcyBzaGFyZSBvbmUgaWQgbmFtZXNwYWNlIChkZWNpc2lvbi0yOCkuXG5cdGNvbnN0IHNlZW5JZHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblx0Y29uc3QgY2xhaW0gPSAob3BlcmF0aW9uSWQ6IHN0cmluZywgbGFiZWw6IHN0cmluZyk6IHZvaWQgPT4ge1xuXHRcdGlmIChzZWVuSWRzLmhhcyhvcGVyYXRpb25JZCkpIHtcblx0XHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdFx0YCR7aWR9OiBkdXBsaWNhdGUgJHtsYWJlbH0gaWQgJHtvcGVyYXRpb25JZH1gLFxuXHRcdFx0KTtcblx0XHR9XG5cdFx0c2Vlbklkcy5hZGQob3BlcmF0aW9uSWQpO1xuXHR9O1xuXHRjb25zdCBhY3Rpb25zOiBBY3Rpb25EZXNjcmlwdGlvbltdID0gW107XG5cdGZvciAoY29uc3QgaXRlbSBvZiBwYXJzZWQuYWN0aW9ucykge1xuXHRcdGNvbnN0IGFjdGlvbiA9IHBhcnNlQWN0aW9uRGVzY3JpcHRpb24oaXRlbSk7XG5cdFx0Y2xhaW0oYWN0aW9uLmlkLCBcImFjdGlvblwiKTtcblx0XHRhY3Rpb25zLnB1c2goYWN0aW9uKTtcblx0fVxuXHRjb25zdCBzdHJlYW1zOiBTdHJlYW1EZXNjcmlwdGlvbltdID0gW107XG5cdGZvciAoY29uc3QgaXRlbSBvZiBkZWNsYXJlZFN0cmVhbXMpIHtcblx0XHRjb25zdCBzdHJlYW0gPSBwYXJzZVN0cmVhbURlc2NyaXB0aW9uKGl0ZW0pO1xuXHRcdGNsYWltKHN0cmVhbS5pZCwgXCJzdHJlYW1cIik7XG5cdFx0c3RyZWFtcy5wdXNoKHN0cmVhbSk7XG5cdH1cblx0Y29uc3QgYnlJZCA9IChcblx0XHRsZWZ0OiB7IHJlYWRvbmx5IGlkOiBzdHJpbmcgfSxcblx0XHRyaWdodDogeyByZWFkb25seSBpZDogc3RyaW5nIH0sXG5cdCk6IG51bWJlciA9PiAobGVmdC5pZCA8IHJpZ2h0LmlkID8gLTEgOiAxKTtcblx0YWN0aW9ucy5zb3J0KGJ5SWQpO1xuXHRzdHJlYW1zLnNvcnQoYnlJZCk7XG5cdHJldHVybiBPYmplY3QuZnJlZXplKHtcblx0XHRzY2hlbWFfdmVyc2lvbjogUExVR0lOX0RFU0NSSVBUSU9OX1NDSEVNQV9WRVJTSU9OLFxuXHRcdGlkLFxuXHRcdHRpdGxlLFxuXHRcdGFjdGlvbnM6IE9iamVjdC5mcmVlemUoYWN0aW9ucyksXG5cdFx0c3RyZWFtczogT2JqZWN0LmZyZWV6ZShzdHJlYW1zKSxcblx0fSk7XG59XG4iLAogICAgIi8qKlxuICogVmFsaWRhdGUgYSB2YWx1ZSBhZ2FpbnN0IHRoZSBzY2hlbWEgc3Vic2V0IGBkZXNjcmliZShhcHApYCBlbWl0cy5cbiAqXG4gKiBUaGlzIGlzIHRoZSBUeXBlU2NyaXB0IHNpZGUgb2YgYHFnaXNfc2RrLmJyaWRnZS5zY2hlbWFgOiB0aGUgc2FtZSBjbG9zZWRcbiAqIGRpYWxlY3QgKG9iamVjdHMgd2l0aCBgcHJvcGVydGllc2AvYHJlcXVpcmVkYC9gYWRkaXRpb25hbFByb3BlcnRpZXNgLCBhcnJheXNcbiAqIHdpdGggYGl0ZW1zYCwgdGhlIGZpdmUgSlNPTiBwcmltaXRpdmVzLCBgYW55T2ZgIGFuZCBgZW51bWAsIHRoZSBpbnRlZ2VyXG4gKiBib3VuZHMgYW5kIGBwYXR0ZXJuYCkgY2hlY2tlZCB0aGUgc2FtZSB3YXksIHNvIGBRZ2lzU2RrYCByZWZ1c2VzIG9uIHRoZSBwYWdlXG4gKiBleGFjdGx5IHdoYXQgdGhlIGhvc3Qgd291bGQgcmVmdXNlIGEgbWVzc2FnZSBsYXRlci4gQW55dGhpbmcgb3V0c2lkZSB0aGVcbiAqIGRpYWxlY3QgaXMgYSBkZWNsYXJhdGlvbiBmYXVsdCBhbmQgdGhyb3dzOyBhIHZhbHVlIHRoYXQgZG9lcyBub3QgZml0IGlzIGFuXG4gKiBpc3N1ZSB0aGUgY2FsbGVyIHJlcG9ydHMuXG4gKlxuICogVGhlIHR3byBhc3ltbWV0cmllcyBvZiBkZWNpc2lvbi0yMiBob2xkIGhlcmUgdG9vOiBhIHJlcXVlc3QgaXMgY2hlY2tlZFxuICogc3RyaWN0bHkgKGFuIHVua25vd24gcHJvcGVydHkgaXMgYW4gaXNzdWUgd2hlbiB0aGUgc2NoZW1hIGNsb3NlcyB0aGVcbiAqIG9iamVjdCksIGEgcmVzdWx0IG9yIGFuIGV2ZW50IGxlbmllbnRseSAoYGFsbG93VW5rbm93bmApLCBzbyBhIGhvc3QgbWF5IGFkZFxuICogYSBmaWVsZCB3aXRob3V0IGJyZWFraW5nIGFuIG9sZGVyIHBhZ2Ugd2hpbGUgYSBtaXNzaW5nIG9yIG1pc3R5cGVkIGZpZWxkIGlzXG4gKiBzdGlsbCBjYXVnaHQuXG4gKi9cblxuaW1wb3J0IHtcblx0UWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IsXG5cdFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUsXG5cdHR5cGUgU2VyaWFsaXplZFZhbGlkYXRpb25Jc3N1ZSxcbn0gZnJvbSBcIi4vZGVjbGFyYXRpb25zXCI7XG5pbXBvcnQgeyBRZ2lzU2RrRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IGlzUGxhaW5SZWNvcmQgfSBmcm9tIFwiLi9pbnRlcm5hbFwiO1xuXG4vKiogT25lIHNjaGVtYSBvZiB0aGUgZGVjbGFyZWQgZGlhbGVjdCwgYXMgdGhlIGRlc2NyaXB0aW9uIGNhcnJpZXMgaXQuICovXG5leHBvcnQgdHlwZSBEZWNsYXJlZFNjaGVtYSA9IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+PjtcblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayB2YWxpZGF0ZUFnYWluc3RTY2hlbWF9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBWYWxpZGF0ZU9wdGlvbnMge1xuXHQvKiogSWdub3JlIHByb3BlcnRpZXMgdGhlIHNjaGVtYSBkb2VzIG5vdCBuYW1lIChyZXN1bHRzIGFuZCBldmVudHMpLiAqL1xuXHRyZWFkb25seSBhbGxvd1Vua25vd24/OiBib29sZWFuO1xuXHQvKiogV2hlcmUgdGhlIHZhbHVlIHNpdHMsIHByZWZpeGVkIHRvIGV2ZXJ5IGlzc3VlJ3MgcGF0aC4gKi9cblx0cmVhZG9ubHkgcGF0aD86IHJlYWRvbmx5IChzdHJpbmcgfCBudW1iZXIpW107XG59XG5cbi8qKiBXaGljaCBzaWRlIG9mIGEgY2FsbCBhIGNvbnRyYWN0IGlzc3VlIGJlbG9uZ3MgdG8uICovXG5leHBvcnQgdHlwZSBDb250cmFjdERpcmVjdGlvbiA9IFwicmVxdWVzdFwiIHwgXCJyZXN1bHRcIiB8IFwiZXZlbnRcIjtcblxuLyoqIFRoZSBKU09OIGZvcm0gb2Yge0BsaW5rIFFnaXNTZGtDb250cmFjdEVycm9yfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU2VyaWFsaXplZENvbnRyYWN0RXJyb3Ige1xuXHRyZWFkb25seSBjb2RlOiBzdHJpbmc7XG5cdHJlYWRvbmx5IG9wZXJhdGlvbjogc3RyaW5nO1xuXHRyZWFkb25seSBkaXJlY3Rpb246IENvbnRyYWN0RGlyZWN0aW9uO1xuXHRyZWFkb25seSBpc3N1ZXM6IFNlcmlhbGl6ZWRWYWxpZGF0aW9uSXNzdWVbXTtcbn1cblxuLyoqXG4gKiBBbiBhcmd1bWVudCwgYSByZXBseSBvciBhbiBldmVudCBkb2VzIG5vdCBtYXRjaCB0aGUgZGVjbGFyZWQgY29udHJhY3QuXG4gKlxuICogVGhlIGNvZGUgaXMgdGhlIG9uZSBib3RoIGxhbmd1YWdlcyB1c2UgZm9yIHRoaXMgY2F0ZWdvcnksIHNvIGEgcGFnZSB0aGF0XG4gKiBhbHJlYWR5IG1hdGNoZXMgYGNvbnRyYWN0X3ZhbGlkYXRpb25fZmFpbGVkYCBuZWVkcyBubyBzZWNvbmQgYnJhbmNoLlxuICovXG5leHBvcnQgY2xhc3MgUWdpc1Nka0NvbnRyYWN0RXJyb3IgZXh0ZW5kcyBRZ2lzU2RrRXJyb3Ige1xuXHRwdWJsaWMgcmVhZG9ubHkgb3BlcmF0aW9uOiBzdHJpbmc7XG5cdHB1YmxpYyByZWFkb25seSBkaXJlY3Rpb246IENvbnRyYWN0RGlyZWN0aW9uO1xuXHRwdWJsaWMgcmVhZG9ubHkgaXNzdWVzOiByZWFkb25seSBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW107XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKFxuXHRcdG9wZXJhdGlvbjogc3RyaW5nLFxuXHRcdGRpcmVjdGlvbjogQ29udHJhY3REaXJlY3Rpb24sXG5cdFx0aXNzdWVzOiByZWFkb25seSBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10sXG5cdCkge1xuXHRcdGNvbnN0IGRldGFpbCA9IGlzc3Vlc1swXSA9PT0gdW5kZWZpbmVkID8gXCJcIiA6IGA6ICR7ZGVzY3JpYmUoaXNzdWVzWzBdKX1gO1xuXHRcdHN1cGVyKFxuXHRcdFx0YCR7b3BlcmF0aW9ufTogdGhlICR7ZGlyZWN0aW9ufSBkb2VzIG5vdCBtYXRjaCB0aGUgZGVjbGFyZWQgY29udHJhY3Qke2RldGFpbH1gLFxuXHRcdFx0XCJjb250cmFjdF92YWxpZGF0aW9uX2ZhaWxlZFwiLFxuXHRcdCk7XG5cdFx0dGhpcy5vcGVyYXRpb24gPSBvcGVyYXRpb247XG5cdFx0dGhpcy5kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG5cdFx0dGhpcy5pc3N1ZXMgPSBPYmplY3QuZnJlZXplKFsuLi5pc3N1ZXNdKTtcblx0fVxuXG5cdHB1YmxpYyB0b0pTT04oKTogU2VyaWFsaXplZENvbnRyYWN0RXJyb3Ige1xuXHRcdHJldHVybiB7XG5cdFx0XHRjb2RlOiB0aGlzLmNvZGUsXG5cdFx0XHRvcGVyYXRpb246IHRoaXMub3BlcmF0aW9uLFxuXHRcdFx0ZGlyZWN0aW9uOiB0aGlzLmRpcmVjdGlvbixcblx0XHRcdGlzc3VlczogdGhpcy5pc3N1ZXMubWFwKChpc3N1ZSkgPT4gaXNzdWUudG9KU09OKCkpLFxuXHRcdH07XG5cdH1cbn1cblxuZnVuY3Rpb24gZGVzY3JpYmUoaXNzdWU6IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUpOiBzdHJpbmcge1xuXHRjb25zdCB3aGVyZSA9IGlzc3VlLnBhdGgubGVuZ3RoID09PSAwID8gXCJ2YWx1ZVwiIDogaXNzdWUucGF0aC5qb2luKFwiLlwiKTtcblx0cmV0dXJuIGAke3doZXJlfSAke2lzc3VlLmNvZGV9YDtcbn1cblxuY29uc3QgUFJJTUlUSVZFUzogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQoW1xuXHRcInN0cmluZ1wiLFxuXHRcImJvb2xlYW5cIixcblx0XCJpbnRlZ2VyXCIsXG5cdFwibnVtYmVyXCIsXG5cdFwibnVsbFwiLFxuXHRcImFycmF5XCIsXG5cdFwib2JqZWN0XCIsXG5dKTtcblxuY29uc3QgS05PV05fS0VZV09SRFM6IFJlYWRvbmx5U2V0PHN0cmluZz4gPSBuZXcgU2V0KFtcblx0XCJ0eXBlXCIsXG5cdFwicHJvcGVydGllc1wiLFxuXHRcInJlcXVpcmVkXCIsXG5cdFwiYWRkaXRpb25hbFByb3BlcnRpZXNcIixcblx0XCJpdGVtc1wiLFxuXHRcImFueU9mXCIsXG5cdFwiZW51bVwiLFxuXHRcIm1pbmltdW1cIixcblx0XCJtYXhpbXVtXCIsXG5cdFwicGF0dGVyblwiLFxuXHRcInRpdGxlXCIsXG5cdFwiZGVzY3JpcHRpb25cIixcblx0Ly8gVGhlIGlucHV0IGtpbmQgYSBkZXNjcmliZXIgYW5ub3RhdGVkIChgeyBraW5kOiBcImxheWVyXCIgfWApOyBmb3JtcyBhbmRcblx0Ly8gcGFnZXMgcmVhZCBpdCwgdmFsaWRhdGlvbiByZWFkcyBwYXN0IGl0LlxuXHRcIngtcWdpcy1zZGtcIixcbl0pO1xuXG50eXBlIFBhdGggPSByZWFkb25seSAoc3RyaW5nIHwgbnVtYmVyKVtdO1xuXG4vKipcbiAqIFJldHVybiBldmVyeSBpc3N1ZSBgdmFsdWVgIGhhcyBhZ2FpbnN0IGBzY2hlbWFgOyBhbiBlbXB0eSBhcnJheSBpcyBhIG1hdGNoLlxuICpcbiAqIFRocm93cyB7QGxpbmsgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3J9IHdoZW4gYHNjaGVtYWAgbGVhdmVzIHRoZSBkZWNsYXJlZFxuICogZGlhbGVjdCwgYmVjYXVzZSB0aGF0IGlzIGEgZmF1bHQgaW4gdGhlIGRlY2xhcmF0aW9uLCBuZXZlciBpbiB0aGUgdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZUFnYWluc3RTY2hlbWEoXG5cdHZhbHVlOiB1bmtub3duLFxuXHRzY2hlbWE6IERlY2xhcmVkU2NoZW1hLFxuXHRvcHRpb25zOiBWYWxpZGF0ZU9wdGlvbnMgPSB7fSxcbik6IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWVbXSB7XG5cdGNvbnN0IGlzc3VlczogUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdID0gW107XG5cdGNoZWNrKFxuXHRcdHZhbHVlLFxuXHRcdHNjaGVtYSxcblx0XHRvcHRpb25zLnBhdGggPz8gW10sXG5cdFx0b3B0aW9ucy5hbGxvd1Vua25vd24gPT09IHRydWUsXG5cdFx0aXNzdWVzLFxuXHQpO1xuXHRyZXR1cm4gaXNzdWVzO1xufVxuXG5mdW5jdGlvbiBjaGVjayhcblx0dmFsdWU6IHVua25vd24sXG5cdHNjaGVtYTogdW5rbm93bixcblx0cGF0aDogUGF0aCxcblx0YWxsb3dVbmtub3duOiBib29sZWFuLFxuXHRpc3N1ZXM6IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWVbXSxcbik6IHZvaWQge1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQoc2NoZW1hKSkge1xuXHRcdHRocm93IG5ldyBRZ2lzU2RrRGVjbGFyYXRpb25FcnJvcihcblx0XHRcdGAke3doZXJlKHBhdGgpfTogYSBzY2hlbWEgbXVzdCBiZSBhbiBvYmplY3RgLFxuXHRcdCk7XG5cdH1cblx0Y29uc3QgdW5rbm93biA9IE9iamVjdC5rZXlzKHNjaGVtYSkuZmlsdGVyKChrZXkpID0+ICFLTk9XTl9LRVlXT1JEUy5oYXMoa2V5KSk7XG5cdGlmICh1bmtub3duLmxlbmd0aCA+IDApIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHt3aGVyZShwYXRoKX06IHVuc3VwcG9ydGVkIHNjaGVtYSBrZXl3b3JkKHMpICR7dW5rbm93bi5zb3J0KCkuam9pbihcIiwgXCIpfWAsXG5cdFx0KTtcblx0fVxuXHRpZiAoXCJhbnlPZlwiIGluIHNjaGVtYSkge1xuXHRcdGNvbnN0IGJyYW5jaGVzID0gc2NoZW1hLmFueU9mO1xuXHRcdGlmICghQXJyYXkuaXNBcnJheShicmFuY2hlcykgfHwgYnJhbmNoZXMubGVuZ3RoID09PSAwKSB7XG5cdFx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRcdGAke3doZXJlKHBhdGgpfTogYW55T2YgbXVzdCBiZSBhIG5vbmVtcHR5IGxpc3RgLFxuXHRcdFx0KTtcblx0XHR9XG5cdFx0Zm9yIChjb25zdCBicmFuY2ggb2YgYnJhbmNoZXMpIHtcblx0XHRcdGNvbnN0IGF0dGVtcHQ6IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWVbXSA9IFtdO1xuXHRcdFx0Y2hlY2sodmFsdWUsIGJyYW5jaCwgcGF0aCwgYWxsb3dVbmtub3duLCBhdHRlbXB0KTtcblx0XHRcdGlmIChhdHRlbXB0Lmxlbmd0aCA9PT0gMCkge1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0fVxuXHRcdGlzc3Vlcy5wdXNoKG5ldyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlKFsuLi5wYXRoXSwgXCJhbnlfb2ZcIikpO1xuXHRcdHJldHVybjtcblx0fVxuXHRpZiAoXCJlbnVtXCIgaW4gc2NoZW1hKSB7XG5cdFx0Y29uc3QgY2hvaWNlcyA9IHNjaGVtYS5lbnVtO1xuXHRcdGlmICghQXJyYXkuaXNBcnJheShjaG9pY2VzKSkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKGAke3doZXJlKHBhdGgpfTogZW51bSBtdXN0IGJlIGEgbGlzdGApO1xuXHRcdH1cblx0XHRpZiAoIWNob2ljZXMuc29tZSgoY2hvaWNlKSA9PiBzYW1lSnNvbihjaG9pY2UsIHZhbHVlKSkpIHtcblx0XHRcdGlzc3Vlcy5wdXNoKG5ldyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlKFsuLi5wYXRoXSwgXCJlbnVtXCIpKTtcblx0XHR9XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGNvbnN0IGRlY2xhcmVkID0gc2NoZW1hLnR5cGU7XG5cdGlmIChkZWNsYXJlZCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YCR7d2hlcmUocGF0aCl9OiBhIHNjaGVtYSBuZWVkcyBhIHR5cGUsIGFueU9mIG9yIGVudW1gLFxuXHRcdCk7XG5cdH1cblx0aWYgKHR5cGVvZiBkZWNsYXJlZCAhPT0gXCJzdHJpbmdcIiB8fCAhUFJJTUlUSVZFUy5oYXMoZGVjbGFyZWQpKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YCR7d2hlcmUocGF0aCl9OiB1bnN1cHBvcnRlZCB0eXBlICR7SlNPTi5zdHJpbmdpZnkoZGVjbGFyZWQpfWAsXG5cdFx0KTtcblx0fVxuXHRzd2l0Y2ggKGRlY2xhcmVkKSB7XG5cdFx0Y2FzZSBcInN0cmluZ1wiOlxuXHRcdFx0Y2hlY2tTdHJpbmcodmFsdWUsIHNjaGVtYSwgcGF0aCwgaXNzdWVzKTtcblx0XHRcdHJldHVybjtcblx0XHRjYXNlIFwiYm9vbGVhblwiOlxuXHRcdFx0aWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJib29sZWFuXCIpIHtcblx0XHRcdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGhdLCBcInR5cGVcIikpO1xuXHRcdFx0fVxuXHRcdFx0cmV0dXJuO1xuXHRcdGNhc2UgXCJpbnRlZ2VyXCI6XG5cdFx0XHRpZiAodHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiIHx8ICFOdW1iZXIuaXNJbnRlZ2VyKHZhbHVlKSkge1xuXHRcdFx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwidHlwZVwiKSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGNoZWNrQm91bmRzKHZhbHVlLCBzY2hlbWEsIHBhdGgsIGlzc3Vlcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0Y2FzZSBcIm51bWJlclwiOlxuXHRcdFx0aWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJudW1iZXJcIikge1xuXHRcdFx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwidHlwZVwiKSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGlmICghTnVtYmVyLmlzRmluaXRlKHZhbHVlKSkge1xuXHRcdFx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwibm90X2Zpbml0ZVwiKSk7XG5cdFx0XHRcdHJldHVybjtcblx0XHRcdH1cblx0XHRcdGNoZWNrQm91bmRzKHZhbHVlLCBzY2hlbWEsIHBhdGgsIGlzc3Vlcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0Y2FzZSBcIm51bGxcIjpcblx0XHRcdGlmICh2YWx1ZSAhPT0gbnVsbCkge1xuXHRcdFx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwidHlwZVwiKSk7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm47XG5cdFx0Y2FzZSBcImFycmF5XCI6XG5cdFx0XHRjaGVja0FycmF5KHZhbHVlLCBzY2hlbWEsIHBhdGgsIGFsbG93VW5rbm93biwgaXNzdWVzKTtcblx0XHRcdHJldHVybjtcblx0XHRkZWZhdWx0OlxuXHRcdFx0Y2hlY2tPYmplY3QodmFsdWUsIHNjaGVtYSwgcGF0aCwgYWxsb3dVbmtub3duLCBpc3N1ZXMpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNoZWNrU3RyaW5nKFxuXHR2YWx1ZTogdW5rbm93bixcblx0c2NoZW1hOiBEZWNsYXJlZFNjaGVtYSxcblx0cGF0aDogUGF0aCxcblx0aXNzdWVzOiBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10sXG4pOiB2b2lkIHtcblx0aWYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIikge1xuXHRcdGlzc3Vlcy5wdXNoKG5ldyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlKFsuLi5wYXRoXSwgXCJ0eXBlXCIpKTtcblx0XHRyZXR1cm47XG5cdH1cblx0Y29uc3QgcGF0dGVybiA9IHNjaGVtYS5wYXR0ZXJuO1xuXHRpZiAocGF0dGVybiA9PT0gdW5kZWZpbmVkIHx8IHBhdHRlcm4gPT09IG51bGwpIHtcblx0XHRyZXR1cm47XG5cdH1cblx0aWYgKHR5cGVvZiBwYXR0ZXJuICE9PSBcInN0cmluZ1wiKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtEZWNsYXJhdGlvbkVycm9yKFxuXHRcdFx0YCR7d2hlcmUocGF0aCl9OiBwYXR0ZXJuIG11c3QgYmUgYSBzdHJpbmdgLFxuXHRcdCk7XG5cdH1cblx0bGV0IGV4cHJlc3Npb246IFJlZ0V4cDtcblx0dHJ5IHtcblx0XHQvLyBQeXRob24ncyByZS5mdWxsbWF0Y2g6IHRoZSB3aG9sZSBzdHJpbmcsIHdpdGggdGhlIHVuaWNvZGUgZmxhZyB0aGVcblx0XHQvLyBkZWNsYXJhdGlvbiBzaWRlIGFscmVhZHkgYXNzdW1lcy5cblx0XHRleHByZXNzaW9uID0gbmV3IFJlZ0V4cChgXig/OiR7cGF0dGVybn0pJGAsIFwidVwiKTtcblx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHt3aGVyZShwYXRoKX06IHBhdHRlcm4gJHtKU09OLnN0cmluZ2lmeShwYXR0ZXJuKX0gaXMgdW51c2FibGU6ICR7U3RyaW5nKGVycm9yKX1gLFxuXHRcdCk7XG5cdH1cblx0aWYgKCFleHByZXNzaW9uLnRlc3QodmFsdWUpKSB7XG5cdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGhdLCBcInBhdHRlcm5cIikpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNoZWNrQm91bmRzKFxuXHR2YWx1ZTogbnVtYmVyLFxuXHRzY2hlbWE6IERlY2xhcmVkU2NoZW1hLFxuXHRwYXRoOiBQYXRoLFxuXHRpc3N1ZXM6IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWVbXSxcbik6IHZvaWQge1xuXHRjb25zdCBtaW5pbXVtID0gc2NoZW1hLm1pbmltdW07XG5cdGlmICh0eXBlb2YgbWluaW11bSA9PT0gXCJudW1iZXJcIiAmJiB2YWx1ZSA8IG1pbmltdW0pIHtcblx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwibWluaW11bVwiKSk7XG5cdH1cblx0Y29uc3QgbWF4aW11bSA9IHNjaGVtYS5tYXhpbXVtO1xuXHRpZiAodHlwZW9mIG1heGltdW0gPT09IFwibnVtYmVyXCIgJiYgdmFsdWUgPiBtYXhpbXVtKSB7XG5cdFx0aXNzdWVzLnB1c2gobmV3IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUoWy4uLnBhdGhdLCBcIm1heGltdW1cIikpO1xuXHR9XG59XG5cbmZ1bmN0aW9uIGNoZWNrQXJyYXkoXG5cdHZhbHVlOiB1bmtub3duLFxuXHRzY2hlbWE6IERlY2xhcmVkU2NoZW1hLFxuXHRwYXRoOiBQYXRoLFxuXHRhbGxvd1Vua25vd246IGJvb2xlYW4sXG5cdGlzc3VlczogUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZVtdLFxuKTogdm9pZCB7XG5cdGlmICghQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcblx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aF0sIFwidHlwZVwiKSk7XG5cdFx0cmV0dXJuO1xuXHR9XG5cdGNvbnN0IGl0ZW1zID0gc2NoZW1hLml0ZW1zO1xuXHRpZiAoaXRlbXMgPT09IHVuZGVmaW5lZCB8fCBpdGVtcyA9PT0gbnVsbCkge1xuXHRcdHJldHVybjtcblx0fVxuXHR2YWx1ZS5mb3JFYWNoKChpdGVtLCBpbmRleCkgPT4ge1xuXHRcdGNoZWNrKGl0ZW0sIGl0ZW1zLCBbLi4ucGF0aCwgaW5kZXhdLCBhbGxvd1Vua25vd24sIGlzc3Vlcyk7XG5cdH0pO1xufVxuXG5mdW5jdGlvbiBjaGVja09iamVjdChcblx0dmFsdWU6IHVua25vd24sXG5cdHNjaGVtYTogRGVjbGFyZWRTY2hlbWEsXG5cdHBhdGg6IFBhdGgsXG5cdGFsbG93VW5rbm93bjogYm9vbGVhbixcblx0aXNzdWVzOiBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlW10sXG4pOiB2b2lkIHtcblx0aWYgKCFpc1BsYWluUmVjb3JkKHZhbHVlKSkge1xuXHRcdGlzc3Vlcy5wdXNoKG5ldyBRZ2lzU2RrVmFsaWRhdGlvbklzc3VlKFsuLi5wYXRoXSwgXCJ0eXBlXCIpKTtcblx0XHRyZXR1cm47XG5cdH1cblx0Y29uc3QgcHJvcGVydGllcyA9IHNjaGVtYS5wcm9wZXJ0aWVzID8/IHt9O1xuXHRpZiAoIWlzUGxhaW5SZWNvcmQocHJvcGVydGllcykpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHt3aGVyZShwYXRoKX06IHByb3BlcnRpZXMgbXVzdCBiZSBhbiBvYmplY3RgLFxuXHRcdCk7XG5cdH1cblx0Y29uc3QgcmVxdWlyZWQgPSBzY2hlbWEucmVxdWlyZWQgPz8gW107XG5cdGlmICghQXJyYXkuaXNBcnJheShyZXF1aXJlZCkpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka0RlY2xhcmF0aW9uRXJyb3IoXG5cdFx0XHRgJHt3aGVyZShwYXRoKX06IHJlcXVpcmVkIG11c3QgYmUgYSBsaXN0YCxcblx0XHQpO1xuXHR9XG5cdGZvciAoY29uc3Qga2V5IG9mIHJlcXVpcmVkKSB7XG5cdFx0aWYgKHR5cGVvZiBrZXkgPT09IFwic3RyaW5nXCIgJiYgIShrZXkgaW4gdmFsdWUpKSB7XG5cdFx0XHRpc3N1ZXMucHVzaChuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aCwga2V5XSwgXCJyZXF1aXJlZFwiKSk7XG5cdFx0fVxuXHR9XG5cdGNvbnN0IHN0cmljdCA9IHNjaGVtYS5hZGRpdGlvbmFsUHJvcGVydGllcyA9PT0gZmFsc2UgJiYgIWFsbG93VW5rbm93bjtcblx0Zm9yIChjb25zdCBba2V5LCBpdGVtXSBvZiBPYmplY3QuZW50cmllcyh2YWx1ZSkpIHtcblx0XHRpZiAoT2JqZWN0Lmhhc093bihwcm9wZXJ0aWVzLCBrZXkpKSB7XG5cdFx0XHRjaGVjayhpdGVtLCBwcm9wZXJ0aWVzW2tleV0sIFsuLi5wYXRoLCBrZXldLCBhbGxvd1Vua25vd24sIGlzc3Vlcyk7XG5cdFx0fSBlbHNlIGlmIChzdHJpY3QpIHtcblx0XHRcdGlzc3Vlcy5wdXNoKFxuXHRcdFx0XHRuZXcgUWdpc1Nka1ZhbGlkYXRpb25Jc3N1ZShbLi4ucGF0aCwga2V5XSwgXCJ1bmtub3duX3Byb3BlcnR5XCIpLFxuXHRcdFx0KTtcblx0XHR9XG5cdH1cbn1cblxuLyoqIEpTT04gZXF1YWxpdHk6IGB0cnVlYCBpcyBub3QgYDFgLCBhbmQgYDFgIGlzIGAxLjBgLiAqL1xuZnVuY3Rpb24gc2FtZUpzb24oYTogdW5rbm93biwgYjogdW5rbm93bik6IGJvb2xlYW4ge1xuXHRpZiAoYSA9PT0gYikge1xuXHRcdHJldHVybiB0cnVlO1xuXHR9XG5cdGlmICh0eXBlb2YgYSAhPT0gdHlwZW9mIGIgfHwgYSA9PT0gbnVsbCB8fCBiID09PSBudWxsKSB7XG5cdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG5cdGlmIChBcnJheS5pc0FycmF5KGEpKSB7XG5cdFx0cmV0dXJuIChcblx0XHRcdEFycmF5LmlzQXJyYXkoYikgJiZcblx0XHRcdGEubGVuZ3RoID09PSBiLmxlbmd0aCAmJlxuXHRcdFx0YS5ldmVyeSgoaXRlbSwgaW5kZXgpID0+IHNhbWVKc29uKGl0ZW0sIGJbaW5kZXhdKSlcblx0XHQpO1xuXHR9XG5cdGlmIChpc1BsYWluUmVjb3JkKGEpICYmIGlzUGxhaW5SZWNvcmQoYikpIHtcblx0XHRjb25zdCBrZXlzID0gT2JqZWN0LmtleXMoYSk7XG5cdFx0cmV0dXJuIChcblx0XHRcdGtleXMubGVuZ3RoID09PSBPYmplY3Qua2V5cyhiKS5sZW5ndGggJiZcblx0XHRcdGtleXMuZXZlcnkoKGtleSkgPT4gT2JqZWN0Lmhhc093bihiLCBrZXkpICYmIHNhbWVKc29uKGFba2V5XSwgYltrZXldKSlcblx0XHQpO1xuXHR9XG5cdHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gd2hlcmUocGF0aDogUGF0aCk6IHN0cmluZyB7XG5cdHJldHVybiBwYXRoLmxlbmd0aCA9PT0gMCA/IFwidmFsdWVcIiA6IHBhdGguam9pbihcIi5cIik7XG59XG4iLAogICAgIi8qKiBUaGUgc3RvcmUgY29udHJhY3QgYW5kIHRoZSBiYXNlIGV2ZXJ5IHN0b3JlIGV4dGVuZHMgKHNlZSBgLi4vc3RvcmVzLnRzYCkuICovXG5cbmltcG9ydCB7IFFnaXNTZGtFcnJvciB9IGZyb20gXCIuLi9lcnJvcnNcIjtcblxuLyoqIEEgc3RvcmUgd2FzIGJ1aWx0IG9yIGRyaXZlbiBvdXRzaWRlIHRoZSBzaGFwZSBpdCBuZWVkcy4gKi9cbmV4cG9ydCBjbGFzcyBRZ2lzU2RrU3RvcmVFcnJvciBleHRlbmRzIFFnaXNTZGtFcnJvciB7XG5cdHB1YmxpYyBjb25zdHJ1Y3RvcihtZXNzYWdlOiBzdHJpbmcpIHtcblx0XHRzdXBlcihtZXNzYWdlLCBcInN0b3JlX2JpbmRpbmdcIik7XG5cdH1cbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBUaGUgY29udHJhY3Rcbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKiogV2hhdCBhIGxpc3RlbmVyIHJlY2VpdmVzOiB0aGUgd2hvbGUgc25hcHNob3QsIG5ldmVyIGEgZGlmZi4gKi9cbmV4cG9ydCB0eXBlIFN0b3JlTGlzdGVuZXI8VD4gPSAoc25hcHNob3Q6IFQpID0+IHZvaWQ7XG5cbi8qKlxuICogVGhlIGNvbnRyYWN0IGV2ZXJ5IHN0b3JlIGhvbm91cnMsIGFuZCB0aGUgb25lIGB1c2VTeW5jRXh0ZXJuYWxTdG9yZWAsXG4gKiBWdWUncyBgc2hhbGxvd1JlZmAgd2lyaW5nIGFuZCBTdmVsdGUncyBgJHN0b3JlYCBhbGwgcmVhZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdG9yZTxUPiB7XG5cdC8qKiBUaGUgY3VycmVudCB2YWx1ZTsgdGhlIHNhbWUgb2JqZWN0IHVudGlsIHRoZSBuZXh0IGNoYW5nZS4gQm91bmQuICovXG5cdHJlYWRvbmx5IGdldFNuYXBzaG90OiAoKSA9PiBUO1xuXHQvKipcblx0ICogQ2FsbCBgbGlzdGVuZXJgIG5vdyBhbmQgYWZ0ZXIgZXZlcnkgY2hhbmdlOyB0aGUgcmV0dXJuZWQgZnVuY3Rpb25cblx0ICogc3RvcHMgdGhlIGNhbGxzLiBCb3VuZC4gU3ZlbHRlIHBhc3NlcyBhIHNlY29uZCBgaW52YWxpZGF0ZWAgYXJndW1lbnQsXG5cdCAqIHdoaWNoIGlzIGlnbm9yZWQuXG5cdCAqL1xuXHRyZWFkb25seSBzdWJzY3JpYmU6IChsaXN0ZW5lcjogU3RvcmVMaXN0ZW5lcjxUPikgPT4gKCkgPT4gdm9pZDtcbn1cblxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VTdG9yZTxUPiBpbXBsZW1lbnRzIFN0b3JlPFQ+IHtcblx0cHJpdmF0ZSBzbmFwc2hvdDogVDtcblx0cHJpdmF0ZSByZWFkb25seSBsaXN0ZW5lcnMgPSBuZXcgU2V0PFN0b3JlTGlzdGVuZXI8VD4+KCk7XG5cblx0cHJvdGVjdGVkIGNvbnN0cnVjdG9yKGluaXRpYWw6IFQpIHtcblx0XHR0aGlzLnNuYXBzaG90ID0gaW5pdGlhbDtcblx0fVxuXG5cdC8vIEJvdW5kLCBzbyBgdXNlU3luY0V4dGVybmFsU3RvcmUoc3RvcmUuc3Vic2NyaWJlLCBzdG9yZS5nZXRTbmFwc2hvdClgXG5cdC8vIG5lZWRzIG5vIHdyYXBwZXIuXG5cdHB1YmxpYyByZWFkb25seSBnZXRTbmFwc2hvdCA9ICgpOiBUID0+IHRoaXMuc25hcHNob3Q7XG5cblx0cHVibGljIHJlYWRvbmx5IHN1YnNjcmliZSA9IChsaXN0ZW5lcjogU3RvcmVMaXN0ZW5lcjxUPik6ICgoKSA9PiB2b2lkKSA9PiB7XG5cdFx0dGhpcy5saXN0ZW5lcnMuYWRkKGxpc3RlbmVyKTtcblx0XHRsaXN0ZW5lcih0aGlzLnNuYXBzaG90KTtcblx0XHRyZXR1cm4gKCkgPT4ge1xuXHRcdFx0dGhpcy5saXN0ZW5lcnMuZGVsZXRlKGxpc3RlbmVyKTtcblx0XHR9O1xuXHR9O1xuXG5cdHByb3RlY3RlZCBwdWJsaXNoKG5leHQ6IFQpOiB2b2lkIHtcblx0XHRpZiAoT2JqZWN0LmlzKG5leHQsIHRoaXMuc25hcHNob3QpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuc25hcHNob3QgPSBuZXh0O1xuXHRcdGZvciAoY29uc3QgbGlzdGVuZXIgb2YgWy4uLnRoaXMubGlzdGVuZXJzXSkge1xuXHRcdFx0bGlzdGVuZXIobmV4dCk7XG5cdFx0fVxuXHR9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBhc0Vycm9yKGVycm9yOiB1bmtub3duKTogRXJyb3Ige1xuXHRyZXR1cm4gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpO1xufVxuIiwKICAgICIvKioge0BsaW5rIE9wZXJhdGlvblN0b3JlfTogb25lIGdlbmVyYXRlZCBvcGVyYXRpb24sIGxhdGVzdCBydW4gd2lucy4gKi9cblxuaW1wb3J0IHsgUWdpc1Nka0JyaWRnZUFib3J0ZWRFcnJvciB9IGZyb20gXCIuLi9icmlkZ2VcIjtcbmltcG9ydCB7IGFzRXJyb3IsIEJhc2VTdG9yZSB9IGZyb20gXCIuL2Jhc2VcIjtcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBPcGVyYXRpb25TdG9yZVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBXaGVyZSBvbmUgaW52b2NhdGlvbiBzdGFuZHMuICovXG5leHBvcnQgdHlwZSBPcGVyYXRpb25TdGF0ZTxSPiA9XG5cdHwgeyByZWFkb25seSBzdGF0dXM6IFwiaWRsZVwiIH1cblx0fCB7IHJlYWRvbmx5IHN0YXR1czogXCJwZW5kaW5nXCIgfVxuXHR8IHsgcmVhZG9ubHkgc3RhdHVzOiBcIm9rXCI7IHJlYWRvbmx5IHZhbHVlOiBSIH1cblx0fCB7IHJlYWRvbmx5IHN0YXR1czogXCJlcnJvclwiOyByZWFkb25seSBlcnJvcjogRXJyb3IgfTtcblxuLyoqIEFuIG9wZXJhdGlvbiBtZW1iZXIgb2YgYSBnZW5lcmF0ZWQgbWFwOiBpbnB1dCwgb3B0aW9uYWwgc2lnbmFsLCBwcm9taXNlLiAqL1xuZXhwb3J0IHR5cGUgT3BlcmF0aW9uPEksIFI+ID0gKFxuXHRpbnB1dDogSSxcblx0b3B0aW9ucz86IHsgcmVhZG9ubHkgc2lnbmFsPzogQWJvcnRTaWduYWwgfSxcbikgPT4gUHJvbWlzZTxSPjtcblxuZXhwb3J0IGNvbnN0IElETEU6IE9wZXJhdGlvblN0YXRlPG5ldmVyPiA9IE9iamVjdC5mcmVlemUoeyBzdGF0dXM6IFwiaWRsZVwiIH0pO1xuY29uc3QgUEVORElORzogT3BlcmF0aW9uU3RhdGU8bmV2ZXI+ID0gT2JqZWN0LmZyZWV6ZSh7IHN0YXR1czogXCJwZW5kaW5nXCIgfSk7XG5cbi8qKlxuICogUnVuIG9uZSBnZW5lcmF0ZWQgb3BlcmF0aW9uLlxuICpcbiAqIGBydW5gIHJlc29sdmVzIHdpdGggdGhlIHZhbHVlLCBvciB3aXRoIGB1bmRlZmluZWRgIHdoZW4gdGhlIGNhbGwgZmFpbGVkLFxuICogd2FzIGFib3J0ZWQgb3Igd2FzIHN1cGVyc2VkZWQgYnkgYSBsYXRlciBydW4gLSB0aGUgc3RhdGUgY2FycmllcyB0aGUgZXJyb3IsXG4gKiBzbyB0aGUgcHJvbWlzZSBuZXZlciByZWplY3RzIGludG8gYW4gZXZlbnQgaGFuZGxlci4gT25seSB0aGUgbGF0ZXN0IHJ1biBjYW5cbiAqIGNoYW5nZSB0aGUgc3RhdGUuIGBhYm9ydGAgZW5kcyB0aGUgaW4tZmxpZ2h0IGNhbGwgbG9jYWxseSAodGhlIGhvc3QgbWF5XG4gKiBzdGlsbCBydW4gaXQpOyBgcmVzZXRgIGFib3J0cyBhbmQgcmV0dXJucyB0byBgaWRsZWAuIFRoZSBtZXRob2RzIGFyZSBib3VuZCxcbiAqIHNvIHRoZXkgY2FuIGJlIHBhc3NlZCBhcm91bmQgd2l0aG91dCB0aGUgc3RvcmUuXG4gKi9cbmV4cG9ydCBjbGFzcyBPcGVyYXRpb25TdG9yZTxJLCBSPiBleHRlbmRzIEJhc2VTdG9yZTxPcGVyYXRpb25TdGF0ZTxSPj4ge1xuXHRwcml2YXRlIGdlbmVyYXRpb24gPSAwO1xuXHRwcml2YXRlIGNvbnRyb2xsZXI6IEFib3J0Q29udHJvbGxlciB8IG51bGwgPSBudWxsO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IG9wZXJhdGlvbjogT3BlcmF0aW9uPEksIFI+KSB7XG5cdFx0c3VwZXIoSURMRSk7XG5cdH1cblxuXHRwdWJsaWMgcmVhZG9ubHkgYWJvcnQgPSAoKTogdm9pZCA9PiB7XG5cdFx0dGhpcy5nZW5lcmF0aW9uICs9IDE7XG5cdFx0dGhpcy5jb250cm9sbGVyPy5hYm9ydCgpO1xuXHRcdHRoaXMuY29udHJvbGxlciA9IG51bGw7XG5cdH07XG5cblx0cHVibGljIHJlYWRvbmx5IHJlc2V0ID0gKCk6IHZvaWQgPT4ge1xuXHRcdHRoaXMuYWJvcnQoKTtcblx0XHR0aGlzLnB1Ymxpc2goSURMRSk7XG5cdH07XG5cblx0cHVibGljIHJlYWRvbmx5IHJ1biA9IGFzeW5jIChpbnB1dDogSSk6IFByb21pc2U8UiB8IHVuZGVmaW5lZD4gPT4ge1xuXHRcdHRoaXMuYWJvcnQoKTtcblx0XHRjb25zdCBtaW5lID0gdGhpcy5nZW5lcmF0aW9uO1xuXHRcdGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgQWJvcnRDb250cm9sbGVyKCk7XG5cdFx0dGhpcy5jb250cm9sbGVyID0gY29udHJvbGxlcjtcblx0XHR0aGlzLnB1Ymxpc2goUEVORElORyk7XG5cdFx0dHJ5IHtcblx0XHRcdGNvbnN0IHZhbHVlID0gYXdhaXQgdGhpcy5vcGVyYXRpb24oaW5wdXQsIHsgc2lnbmFsOiBjb250cm9sbGVyLnNpZ25hbCB9KTtcblx0XHRcdGlmICh0aGlzLmdlbmVyYXRpb24gIT09IG1pbmUpIHtcblx0XHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdHRoaXMucHVibGlzaCh7IHN0YXR1czogXCJva1wiLCB2YWx1ZSB9KTtcblx0XHRcdHJldHVybiB2YWx1ZTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0aWYgKFxuXHRcdFx0XHR0aGlzLmdlbmVyYXRpb24gIT09IG1pbmUgfHxcblx0XHRcdFx0ZXJyb3IgaW5zdGFuY2VvZiBRZ2lzU2RrQnJpZGdlQWJvcnRlZEVycm9yXG5cdFx0XHQpIHtcblx0XHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHRcdH1cblx0XHRcdHRoaXMucHVibGlzaCh7IHN0YXR1czogXCJlcnJvclwiLCBlcnJvcjogYXNFcnJvcihlcnJvcikgfSk7XG5cdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdH0gZmluYWxseSB7XG5cdFx0XHRpZiAodGhpcy5jb250cm9sbGVyID09PSBjb250cm9sbGVyKSB7XG5cdFx0XHRcdHRoaXMuY29udHJvbGxlciA9IG51bGw7XG5cdFx0XHR9XG5cdFx0fVxuXHR9O1xufVxuIiwKICAgICIvKioge0BsaW5rIEZvcm1TdG9yZX06IG9uZSBkZWNsYXJlZCBhY3Rpb24ncyByZXF1ZXN0IGJvdW5kIHRvIGl0cyBzY2hlbWEuICovXG5cbmltcG9ydCB0eXBlIHtcblx0QWN0aW9uRGVzY3JpcHRpb24sXG5cdFFnaXNTZGtWYWxpZGF0aW9uSXNzdWUsXG59IGZyb20gXCIuLi9kZWNsYXJhdGlvbnNcIjtcbmltcG9ydCB7IGlzUGxhaW5SZWNvcmQgfSBmcm9tIFwiLi4vaW50ZXJuYWxcIjtcbmltcG9ydCB0eXBlIHsgUWdpc1Nka0NvcmUgfSBmcm9tIFwiLi4vcWdpcy1zZGtcIjtcbmltcG9ydCB0eXBlIHsgT3BlcmF0aW9uU2hhcGUgfSBmcm9tIFwiLi4vc2NoZW1hXCI7XG5pbXBvcnQgeyB0eXBlIERlY2xhcmVkU2NoZW1hLCB2YWxpZGF0ZUFnYWluc3RTY2hlbWEgfSBmcm9tIFwiLi4vdmFsaWRhdGVcIjtcbmltcG9ydCB7IEJhc2VTdG9yZSwgUWdpc1Nka1N0b3JlRXJyb3IgfSBmcm9tIFwiLi9iYXNlXCI7XG5pbXBvcnQge1xuXHRJRExFLFxuXHR0eXBlIE9wZXJhdGlvbixcblx0dHlwZSBPcGVyYXRpb25TdGF0ZSxcblx0T3BlcmF0aW9uU3RvcmUsXG59IGZyb20gXCIuL29wZXJhdGlvblwiO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEZvcm1TdG9yZVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKlxuICogVGhlIGlucHV0IGZhbWlsaWVzIGEgZGVjbGFyZWQgcmVxdWVzdCBjYW4gYXNrIGZvcjogdGhlIHNhbWUgbmFtZXMgdGhlXG4gKiBQeXRob24gYHFnaXNfc2RrLnVpYCBjYXRhbG9ndWUgZHJhd3MsIHNvIGEgZm9ybSBvbiBlaXRoZXIgc2lkZSBvZiB0aGVcbiAqIGJyaWRnZSByZW5kZXJzIG9uZSBkZWNsYXJhdGlvbiB0aGUgc2FtZSB3YXkuXG4gKi9cbmV4cG9ydCB0eXBlIEZvcm1GaWVsZEtpbmQgPVxuXHR8IFwidGV4dFwiXG5cdHwgXCJpbnRlZ2VyXCJcblx0fCBcIm51bWJlclwiXG5cdHwgXCJib29sZWFuXCJcblx0fCBcImNob2ljZVwiXG5cdHwgXCJsYXllclwiXG5cdHwgXCJjcnNcIlxuXHR8IFwibWV0cmVzXCJcblx0fCBcImZpbGVcIlxuXHR8IFwiZGlyZWN0b3J5XCJcblx0fCBcImZpZWxkXCJcblx0fCBcInJhbmdlXCJcblx0fCBcImNvbG91clwiO1xuXG5jb25zdCBGSUVMRF9LSU5EUzogUmVhZG9ubHlTZXQ8c3RyaW5nPiA9IG5ldyBTZXQ8Rm9ybUZpZWxkS2luZD4oW1xuXHRcInRleHRcIixcblx0XCJpbnRlZ2VyXCIsXG5cdFwibnVtYmVyXCIsXG5cdFwiYm9vbGVhblwiLFxuXHRcImNob2ljZVwiLFxuXHRcImxheWVyXCIsXG5cdFwiY3JzXCIsXG5cdFwibWV0cmVzXCIsXG5cdFwiZmlsZVwiLFxuXHRcImRpcmVjdG9yeVwiLFxuXHRcImZpZWxkXCIsXG5cdFwicmFuZ2VcIixcblx0XCJjb2xvdXJcIixcbl0pO1xuY29uc3QgUFJJTUlUSVZFX0tJTkRTOiBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCBGb3JtRmllbGRLaW5kPj4gPSB7XG5cdHN0cmluZzogXCJ0ZXh0XCIsXG5cdGludGVnZXI6IFwiaW50ZWdlclwiLFxuXHRudW1iZXI6IFwibnVtYmVyXCIsXG5cdGJvb2xlYW46IFwiYm9vbGVhblwiLFxufTtcbmNvbnN0IE5VTUVSSUNfS0lORFM6IFJlYWRvbmx5U2V0PEZvcm1GaWVsZEtpbmQ+ID0gbmV3IFNldDxGb3JtRmllbGRLaW5kPihbXG5cdFwiaW50ZWdlclwiLFxuXHRcIm51bWJlclwiLFxuXHRcIm1ldHJlc1wiLFxuXHRcInJhbmdlXCIsXG5dKTtcbmNvbnN0IERFVEFJTF9LRVlTID0gW1wibWluaW11bVwiLCBcIm1heGltdW1cIiwgXCJzdGVwXCIsIFwib2ZcIiwgXCJmaWx0ZXJzXCIsIFwiYWxwaGFcIl07XG5cbi8qKiBPbmUgaW5wdXQgb2YgYSBkZWNsYXJlZCBhY3Rpb24sIGFzIGEgcGFnZSBzaG91bGQgcmVuZGVyIGl0LiAqL1xuZXhwb3J0IGludGVyZmFjZSBGb3JtRmllbGQge1xuXHRyZWFkb25seSBuYW1lOiBzdHJpbmc7XG5cdC8qKiBgYnVmZmVyX2Rpc3RhbmNlYCAtPiBgQnVmZmVyIGRpc3RhbmNlYC4gKi9cblx0cmVhZG9ubHkgbGFiZWw6IHN0cmluZztcblx0cmVhZG9ubHkga2luZDogRm9ybUZpZWxkS2luZDtcblx0cmVhZG9ubHkgcmVxdWlyZWQ6IGJvb2xlYW47XG5cdHJlYWRvbmx5IG51bGxhYmxlOiBib29sZWFuO1xuXHQvKiogVGhlIGBlbnVtYCBvZiBhIGBjaG9pY2VgIGZpZWxkOyBlbXB0eSBvdGhlcndpc2UuICovXG5cdHJlYWRvbmx5IGNob2ljZXM6IHJlYWRvbmx5IHVua25vd25bXTtcblx0LyoqIEJvdW5kcywgYSBwYXJlbnQgaW5wdXQsIHBpY2tlciBmaWx0ZXJzOiB3aGF0IHRoZSBraW5kIG5lZWRzIGJleW9uZCBhIG5hbWUuICovXG5cdHJlYWRvbmx5IGRldGFpbHM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHVua25vd24+Pjtcblx0LyoqIFRoZSBwcm9wZXJ0eSBzY2hlbWEgdGhlIHZhbHVlIGlzIHZhbGlkYXRlZCBhZ2FpbnN0LiAqL1xuXHRyZWFkb25seSBzY2hlbWE6IERlY2xhcmVkU2NoZW1hO1xufVxuXG4vKiogUmVuZGVyIGEgZmllbGQgbmFtZSBhcyBhIGxhYmVsLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGxhYmVsRm9yKG5hbWU6IHN0cmluZyk6IHN0cmluZyB7XG5cdGNvbnN0IHNwYWNlZCA9IG5hbWUucmVwbGFjZSgvXy9nLCBcIiBcIikudHJpbSgpO1xuXHRyZXR1cm4gc3BhY2VkLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsgc3BhY2VkLnNsaWNlKDEpLnRvTG93ZXJDYXNlKCk7XG59XG5cbmZ1bmN0aW9uIGNvbmNyZXRlKHNjaGVtYTogRGVjbGFyZWRTY2hlbWEpOiBbRGVjbGFyZWRTY2hlbWEsIGJvb2xlYW5dIHtcblx0Y29uc3QgYnJhbmNoZXMgPSBzY2hlbWEuYW55T2Y7XG5cdGlmICghQXJyYXkuaXNBcnJheShicmFuY2hlcykpIHtcblx0XHRyZXR1cm4gW3NjaGVtYSwgZmFsc2VdO1xuXHR9XG5cdGNvbnN0IG5vbk51bGwgPSBicmFuY2hlcy5maWx0ZXIoXG5cdFx0KGJyYW5jaCk6IGJyYW5jaCBpcyBEZWNsYXJlZFNjaGVtYSA9PlxuXHRcdFx0aXNQbGFpblJlY29yZChicmFuY2gpICYmIGJyYW5jaC50eXBlICE9PSBcIm51bGxcIixcblx0KTtcblx0aWYgKG5vbk51bGwubGVuZ3RoID09PSAxICYmIG5vbk51bGwubGVuZ3RoICE9PSBicmFuY2hlcy5sZW5ndGgpIHtcblx0XHRyZXR1cm4gW25vbk51bGxbMF0gYXMgRGVjbGFyZWRTY2hlbWEsIHRydWVdO1xuXHR9XG5cdHRocm93IG5ldyBRZ2lzU2RrU3RvcmVFcnJvcihcblx0XHRcImEgdW5pb24gZmllbGQgbXVzdCBiZSBvbmUgdHlwZSBvciB0aGF0IHR5cGUgcGx1cyBudWxsIHRvIGJlIHJlbmRlcmVkXCIsXG5cdCk7XG59XG5cbmZ1bmN0aW9uIGtpbmRGb3IoXG5cdG93bmVyOiBzdHJpbmcsXG5cdG5hbWU6IHN0cmluZyxcblx0c2NoZW1hOiBEZWNsYXJlZFNjaGVtYSxcbik6IEZvcm1GaWVsZEtpbmQge1xuXHRjb25zdCBpbnRlbnQgPSBzY2hlbWFbXCJ4LXFnaXMtc2RrXCJdO1xuXHRjb25zdCBtYXJrZWQgPSBpc1BsYWluUmVjb3JkKGludGVudCkgPyBpbnRlbnQua2luZCA6IHVuZGVmaW5lZDtcblx0aWYgKHR5cGVvZiBtYXJrZWQgPT09IFwic3RyaW5nXCIpIHtcblx0XHRpZiAoIUZJRUxEX0tJTkRTLmhhcyhtYXJrZWQpKSB7XG5cdFx0XHR0aHJvdyBuZXcgUWdpc1Nka1N0b3JlRXJyb3IoXG5cdFx0XHRcdGAke293bmVyfTogZmllbGQgJHtuYW1lfSBoYXMgdW5rbm93biBraW5kICR7SlNPTi5zdHJpbmdpZnkobWFya2VkKX1gLFxuXHRcdFx0KTtcblx0XHR9XG5cdFx0cmV0dXJuIG1hcmtlZCBhcyBGb3JtRmllbGRLaW5kO1xuXHR9XG5cdGlmIChcImVudW1cIiBpbiBzY2hlbWEpIHtcblx0XHRyZXR1cm4gXCJjaG9pY2VcIjtcblx0fVxuXHRjb25zdCBraW5kID0gUFJJTUlUSVZFX0tJTkRTW1N0cmluZyhzY2hlbWEudHlwZSldO1xuXHRpZiAoa2luZCA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0dGhyb3cgbmV3IFFnaXNTZGtTdG9yZUVycm9yKFxuXHRcdFx0YCR7b3duZXJ9OiBmaWVsZCAke25hbWV9IGhhcyBubyBpbnB1dCBmb3IgaXRzIHNjaGVtYTsgZGVjbGFyZSBhIHByaW1pdGl2ZSwgYW4gZW51bSBvciBhIGtpbmRgLFxuXHRcdCk7XG5cdH1cblx0cmV0dXJuIGtpbmQ7XG59XG5cbi8qKlxuICogVGhlIGZpZWxkcyBvZiBhIGRlY2xhcmVkIHJlcXVlc3Qgc2NoZW1hLCBpbiBkZWNsYXJhdGlvbiBvcmRlcjogdGhlXG4gKiBUeXBlU2NyaXB0IHR3aW4gb2YgYHFnaXNfc2RrLnVpLnNjaGVtYV9maWVsZHNgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2NoZW1hRmllbGRzKFxuXHRzY2hlbWE6IERlY2xhcmVkU2NoZW1hLFxuXHRvd25lciA9IFwiZm9ybVwiLFxuKTogcmVhZG9ubHkgRm9ybUZpZWxkW10ge1xuXHRjb25zdCBwcm9wZXJ0aWVzID0gc2NoZW1hLnByb3BlcnRpZXM7XG5cdGlmICghaXNQbGFpblJlY29yZChwcm9wZXJ0aWVzKSkge1xuXHRcdHJldHVybiBPYmplY3QuZnJlZXplKFtdKTtcblx0fVxuXHRjb25zdCByZXF1aXJlZCA9IG5ldyBTZXQoXG5cdFx0QXJyYXkuaXNBcnJheShzY2hlbWEucmVxdWlyZWQpID8gKHNjaGVtYS5yZXF1aXJlZCBhcyBzdHJpbmdbXSkgOiBbXSxcblx0KTtcblx0cmV0dXJuIE9iamVjdC5mcmVlemUoXG5cdFx0T2JqZWN0LmVudHJpZXMocHJvcGVydGllcykubWFwKChbbmFtZSwgcHJvcGVydHldKSA9PiB7XG5cdFx0XHRpZiAoIWlzUGxhaW5SZWNvcmQocHJvcGVydHkpKSB7XG5cdFx0XHRcdHRocm93IG5ldyBRZ2lzU2RrU3RvcmVFcnJvcihgJHtvd25lcn06IGZpZWxkICR7bmFtZX0gaXMgbm90IGEgc2NoZW1hYCk7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBbc2hhcGUsIG51bGxhYmxlXSA9IGNvbmNyZXRlKHByb3BlcnR5KTtcblx0XHRcdGNvbnN0IGtpbmQgPSBraW5kRm9yKG93bmVyLCBuYW1lLCBzaGFwZSk7XG5cdFx0XHRjb25zdCBpbnRlbnQgPSBpc1BsYWluUmVjb3JkKHNoYXBlW1wieC1xZ2lzLXNka1wiXSlcblx0XHRcdFx0PyBzaGFwZVtcIngtcWdpcy1zZGtcIl1cblx0XHRcdFx0OiB7fTtcblx0XHRcdGNvbnN0IG1lcmdlZDogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7IC4uLnNoYXBlLCAuLi5pbnRlbnQgfTtcblx0XHRcdGNvbnN0IGRldGFpbHMgPVxuXHRcdFx0XHRraW5kID09PSBcImludGVnZXJcIlxuXHRcdFx0XHRcdD8ge31cblx0XHRcdFx0XHQ6IE9iamVjdC5mcm9tRW50cmllcyhcblx0XHRcdFx0XHRcdFx0REVUQUlMX0tFWVMuZmlsdGVyKChrZXkpID0+IGtleSBpbiBtZXJnZWQpLm1hcCgoa2V5KSA9PiBbXG5cdFx0XHRcdFx0XHRcdFx0a2V5LFxuXHRcdFx0XHRcdFx0XHRcdG1lcmdlZFtrZXldLFxuXHRcdFx0XHRcdFx0XHRdKSxcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRyZXR1cm4gT2JqZWN0LmZyZWV6ZSh7XG5cdFx0XHRcdG5hbWUsXG5cdFx0XHRcdGxhYmVsOiBsYWJlbEZvcihuYW1lKSxcblx0XHRcdFx0a2luZCxcblx0XHRcdFx0cmVxdWlyZWQ6IHJlcXVpcmVkLmhhcyhuYW1lKSAmJiAhbnVsbGFibGUsXG5cdFx0XHRcdG51bGxhYmxlLFxuXHRcdFx0XHRjaG9pY2VzOiBPYmplY3QuZnJlZXplKFxuXHRcdFx0XHRcdGtpbmQgPT09IFwiY2hvaWNlXCIgJiYgQXJyYXkuaXNBcnJheShzaGFwZS5lbnVtKSA/IFsuLi5zaGFwZS5lbnVtXSA6IFtdLFxuXHRcdFx0XHQpLFxuXHRcdFx0XHRkZXRhaWxzOiBPYmplY3QuZnJlZXplKGRldGFpbHMpLFxuXHRcdFx0XHRzY2hlbWE6IHByb3BlcnR5LFxuXHRcdFx0fSk7XG5cdFx0fSksXG5cdCk7XG59XG5cbi8qKiBUaGUgdmFsdWVzIGEgZm9ybSBob2xkczogb25lIGVudHJ5IHBlciBmaWVsZCB0aGUgdXNlciBvciB0aGUgc2NoZW1hIHNldC4gKi9cbmV4cG9ydCB0eXBlIEZvcm1WYWx1ZXMgPSBSZWFkb25seTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj47XG5cbi8qKiBXaGVyZSBvbmUgZm9ybSBzdGFuZHMuICovXG5leHBvcnQgaW50ZXJmYWNlIEZvcm1TdGF0ZTxSPiB7XG5cdHJlYWRvbmx5IHZhbHVlczogRm9ybVZhbHVlcztcblx0LyoqIEV2ZXJ5IGlzc3VlIHRoZSBjdXJyZW50IHZhbHVlcyBoYXZlIGFnYWluc3QgdGhlIHJlcXVlc3Qgc2NoZW1hLiAqL1xuXHRyZWFkb25seSBpc3N1ZXM6IHJlYWRvbmx5IFFnaXNTZGtWYWxpZGF0aW9uSXNzdWVbXTtcblx0LyoqIFRoZSBmaXJzdCBpc3N1ZSBjb2RlIHBlciBmaWVsZCBuYW1lLCBmb3IgYSBsYWJlbCB0byBzaG93LiAqL1xuXHRyZWFkb25seSBlcnJvcnM6IFJlYWRvbmx5PFJlY29yZDxzdHJpbmcsIHN0cmluZz4+O1xuXHRyZWFkb25seSB2YWxpZDogYm9vbGVhbjtcblx0LyoqIEEgdmFsdWUgY2hhbmdlZCBzaW5jZSBjb25zdHJ1Y3Rpb24gb3IgdGhlIGxhc3QgYHJlc2V0YC4gKi9cblx0cmVhZG9ubHkgZGlydHk6IGJvb2xlYW47XG5cdC8qKiBgc3VibWl0YCB3YXMgYXR0ZW1wdGVkIHNpbmNlIGNvbnN0cnVjdGlvbiBvciB0aGUgbGFzdCBgcmVzZXRgLiAqL1xuXHRyZWFkb25seSBzdWJtaXR0ZWQ6IGJvb2xlYW47XG5cdC8qKiBUaGUgbGF0ZXN0IHN1Ym1pc3Npb24sIGFzIGFuIG9wZXJhdGlvbiBzdG9yZSByZXBvcnRzIGl0LiAqL1xuXHRyZWFkb25seSBzdWJtaXNzaW9uOiBPcGVyYXRpb25TdGF0ZTxSPjtcbn1cblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayBGb3JtU3RvcmV9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBGb3JtT3B0aW9ucyB7XG5cdC8qKiBWYWx1ZXMgdG8gc3RhcnQgZnJvbTsgdGhlIGRlY2xhcmVkIGRpYWxlY3QgaGFzIG5vIGRlZmF1bHRzIG9mIGl0cyBvd24uICovXG5cdHJlYWRvbmx5IGluaXRpYWw/OiBGb3JtVmFsdWVzO1xufVxuXG50eXBlIFJlcXVlc3RPZjxPLCBLIGV4dGVuZHMga2V5b2YgTz4gPSBPW0tdIGV4dGVuZHMgT3BlcmF0aW9uU2hhcGVcblx0PyBPW0tdW1wicmVxdWVzdFwiXVxuXHQ6IG5ldmVyO1xudHlwZSBSZXN1bHRPZjxPLCBLIGV4dGVuZHMga2V5b2YgTz4gPSBPW0tdIGV4dGVuZHMgT3BlcmF0aW9uU2hhcGVcblx0PyBPW0tdW1wicmVzdWx0XCJdXG5cdDogbmV2ZXI7XG5cbi8qKlxuICogV2FsayBgcWdpc2AgYnkgdGhlIGRvdHRlZCBpZCB0byB0aGUgbWV0aG9kIGEgZGVjbGFyZWQgYWN0aW9uIGJlY2FtZS5cbiAqL1xuZnVuY3Rpb24gb3BlcmF0aW9uT2Y8SSwgUj4oXG5cdHFnaXM6IFFnaXNTZGtDb3JlPHVua25vd24sIHVua25vd24+LFxuXHRpZDogc3RyaW5nLFxuKTogT3BlcmF0aW9uPEksIFI+IHtcblx0bGV0IG5vZGU6IHVua25vd24gPSBxZ2lzO1xuXHRmb3IgKGNvbnN0IHNlZ21lbnQgb2YgaWQuc3BsaXQoXCIuXCIpKSB7XG5cdFx0bm9kZSA9XG5cdFx0XHRpc1BsYWluUmVjb3JkKG5vZGUpIHx8IHR5cGVvZiBub2RlID09PSBcImZ1bmN0aW9uXCJcblx0XHRcdFx0PyAobm9kZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPilbc2VnbWVudF1cblx0XHRcdFx0OiB1bmRlZmluZWQ7XG5cdH1cblx0aWYgKHR5cGVvZiBub2RlICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHR0aHJvdyBuZXcgUWdpc1Nka1N0b3JlRXJyb3IoYCR7aWR9IGlzIG5vdCBhbiBvcGVyYXRpb24gb2YgdGhpcyBRZ2lzU2RrYCk7XG5cdH1cblx0cmV0dXJuIG5vZGUgYXMgT3BlcmF0aW9uPEksIFI+O1xufVxuXG5mdW5jdGlvbiBjb2VyY2UoZmllbGQ6IEZvcm1GaWVsZCwgdmFsdWU6IHVua25vd24pOiB1bmtub3duIHtcblx0aWYgKHZhbHVlID09PSBcIlwiICYmIGZpZWxkLmtpbmQgIT09IFwidGV4dFwiKSB7XG5cdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0fVxuXHRpZiAoTlVNRVJJQ19LSU5EUy5oYXMoZmllbGQua2luZCkgJiYgdHlwZW9mIHZhbHVlID09PSBcInN0cmluZ1wiKSB7XG5cdFx0Y29uc3QgdHJpbW1lZCA9IHZhbHVlLnRyaW0oKTtcblx0XHRpZiAoXG5cdFx0XHR0cmltbWVkICE9PSBcIlwiICYmXG5cdFx0XHQvXlstK10/KFxcZCtcXC4/XFxkKnxcXC5cXGQrKShbZUVdWy0rXT9cXGQrKT8kLy50ZXN0KHRyaW1tZWQpXG5cdFx0KSB7XG5cdFx0XHRjb25zdCBudW1iZXIgPSBOdW1iZXIodHJpbW1lZCk7XG5cdFx0XHRpZiAoZmllbGQua2luZCAhPT0gXCJpbnRlZ2VyXCIgfHwgTnVtYmVyLmlzSW50ZWdlcihudW1iZXIpKSB7XG5cdFx0XHRcdHJldHVybiBudW1iZXI7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cdHJldHVybiB2YWx1ZTtcbn1cblxuLyoqXG4gKiBCaW5kIHRoZSByZXF1ZXN0IG9mIG9uZSBkZWNsYXJlZCBhY3Rpb24gdG8gaXRzIHNjaGVtYS5cbiAqXG4gKiBUaGUgZmllbGRzIGNvbWUgZnJvbSB0aGUgZGVjbGFyYXRpb24sIHNvIGEgcGFnZSByZW5kZXJzIGBmb3JtLmZpZWxkc2BcbiAqIGluc3RlYWQgb2YgZ3Vlc3Npbmc7IGBzZXRgIGNvZXJjZXMgd2hhdCBhbiBgPGlucHV0PmAgeWllbGRzIChgXCIzXCJgIGZvciBhXG4gKiBudW1lcmljIGZpZWxkLCBgXCJcImAgZm9yIGFuIHVuc2V0IG9uZSkgYW5kIHJlLXZhbGlkYXRlczsgYHN1Ym1pdGAgcmVmdXNlc1xuICogaW52YWxpZCB2YWx1ZXMgd2l0aG91dCBhIGNhbGwgYW5kIG90aGVyd2lzZSBydW5zIHRoZSBvcGVyYXRpb24gdGhyb3VnaCBhblxuICoge0BsaW5rIE9wZXJhdGlvblN0b3JlfSwgd2hvc2Ugc3RhdGUgaXMgYHN1Ym1pc3Npb25gLlxuICovXG5leHBvcnQgY2xhc3MgRm9ybVN0b3JlPFJlcSBleHRlbmRzIG9iamVjdCwgUj4gZXh0ZW5kcyBCYXNlU3RvcmU8Rm9ybVN0YXRlPFI+PiB7XG5cdHB1YmxpYyByZWFkb25seSBpZDogc3RyaW5nO1xuXHRwdWJsaWMgcmVhZG9ubHkgdGl0bGU6IHN0cmluZztcblx0cHVibGljIHJlYWRvbmx5IGZpZWxkczogcmVhZG9ubHkgRm9ybUZpZWxkW107XG5cdHByaXZhdGUgcmVhZG9ubHkgYnlOYW1lOiBSZWFkb25seU1hcDxzdHJpbmcsIEZvcm1GaWVsZD47XG5cdHByaXZhdGUgcmVhZG9ubHkgcmVxdWVzdDogRGVjbGFyZWRTY2hlbWE7XG5cdHByaXZhdGUgcmVhZG9ubHkgaW5pdGlhbDogRm9ybVZhbHVlcztcblx0cHJpdmF0ZSByZWFkb25seSBvcGVyYXRpb246IE9wZXJhdGlvblN0b3JlPFJlcSwgUj47XG5cdHByaXZhdGUgcmVhZG9ubHkgdW5zdWJzY3JpYmU6ICgpID0+IHZvaWQ7XG5cblx0cHVibGljIGNvbnN0cnVjdG9yKFxuXHRcdHFnaXM6IFFnaXNTZGtDb3JlPHVua25vd24sIHVua25vd24+LFxuXHRcdGlkOiBzdHJpbmcsXG5cdFx0b3B0aW9uczogRm9ybU9wdGlvbnMgPSB7fSxcblx0KSB7XG5cdFx0Y29uc3QgYWN0aW9uID0gcWdpcy5zY2hlbWEuYWN0aW9ucy5maW5kKChjYW5kaWRhdGUpID0+IGNhbmRpZGF0ZS5pZCA9PT0gaWQpO1xuXHRcdGlmIChhY3Rpb24gPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtTdG9yZUVycm9yKFxuXHRcdFx0XHRgJHtpZH0gaXMgbm90IGEgZGVjbGFyZWQgYWN0aW9uIG9mIHRoaXMgc2NoZW1hYCxcblx0XHRcdCk7XG5cdFx0fVxuXHRcdGNvbnN0IGZpZWxkcyA9IHNjaGVtYUZpZWxkcyhhY3Rpb24ucmVxdWVzdCwgYGZvcm0gJHtpZH1gKTtcblx0XHRjb25zdCBpbml0aWFsID0gRm9ybVN0b3JlLmRlZmF1bHRzKG9wdGlvbnMuaW5pdGlhbCA/PyB7fSk7XG5cdFx0c3VwZXIoRm9ybVN0b3JlLmV2YWx1YXRlKGluaXRpYWwsIGFjdGlvbi5yZXF1ZXN0LCBmYWxzZSwgZmFsc2UsIElETEUpKTtcblx0XHR0aGlzLmlkID0gaWQ7XG5cdFx0dGhpcy50aXRsZSA9IGFjdGlvbi50aXRsZTtcblx0XHR0aGlzLmZpZWxkcyA9IGZpZWxkcztcblx0XHR0aGlzLmJ5TmFtZSA9IG5ldyBNYXAoZmllbGRzLm1hcCgoZmllbGQpID0+IFtmaWVsZC5uYW1lLCBmaWVsZF0pKTtcblx0XHR0aGlzLnJlcXVlc3QgPSBhY3Rpb24ucmVxdWVzdDtcblx0XHR0aGlzLmluaXRpYWwgPSBpbml0aWFsO1xuXHRcdHRoaXMub3BlcmF0aW9uID0gbmV3IE9wZXJhdGlvblN0b3JlKG9wZXJhdGlvbk9mPFJlcSwgUj4ocWdpcywgaWQpKTtcblx0XHRsZXQgZmlyc3QgPSB0cnVlO1xuXHRcdHRoaXMudW5zdWJzY3JpYmUgPSB0aGlzLm9wZXJhdGlvbi5zdWJzY3JpYmUoKHN1Ym1pc3Npb24pID0+IHtcblx0XHRcdGlmIChmaXJzdCkge1xuXHRcdFx0XHRmaXJzdCA9IGZhbHNlO1xuXHRcdFx0XHRyZXR1cm47XG5cdFx0XHR9XG5cdFx0XHRjb25zdCBjdXJyZW50ID0gdGhpcy5nZXRTbmFwc2hvdCgpO1xuXHRcdFx0dGhpcy5wdWJsaXNoKHsgLi4uY3VycmVudCwgc3VibWlzc2lvbiB9KTtcblx0XHR9KTtcblx0fVxuXG5cdC8qKiBUaGUgZGVjbGFyYXRpb24gdGhlIGZvcm0gd2FzIGJ1aWx0IGZyb20sIGZvciBhIHBhZ2UgdGhhdCByZW5kZXJzIG1vcmUuICovXG5cdHB1YmxpYyBzdGF0aWMgZGVzY3JpYmUoXG5cdFx0cWdpczogUWdpc1Nka0NvcmU8dW5rbm93biwgdW5rbm93bj4sXG5cdFx0aWQ6IHN0cmluZyxcblx0KTogQWN0aW9uRGVzY3JpcHRpb24gfCB1bmRlZmluZWQge1xuXHRcdHJldHVybiBxZ2lzLnNjaGVtYS5hY3Rpb25zLmZpbmQoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlLmlkID09PSBpZCk7XG5cdH1cblxuXHRwcml2YXRlIHN0YXRpYyBkZWZhdWx0cyhpbml0aWFsOiBGb3JtVmFsdWVzKTogRm9ybVZhbHVlcyB7XG5cdFx0Ly8gVGhlIGRlY2xhcmVkIGRpYWxlY3QgY2FycmllcyBubyBgZGVmYXVsdGAga2V5d29yZDogd2hhdCBhIGZvcm0gc3RhcnRzXG5cdFx0Ly8gZnJvbSBpcyB0aGUgcGFnZSdzIGNob2ljZSwgYW5kIGFuIHVuc2V0IHJlcXVpcmVkIGZpZWxkIGlzIGFuIGlzc3VlXG5cdFx0Ly8gdGhlIHBhZ2Ugc2hvd3Mgb25jZSBgc3VibWl0dGVkYCBpcyB0cnVlLlxuXHRcdHJldHVybiBPYmplY3QuZnJlZXplKFxuXHRcdFx0T2JqZWN0LmZyb21FbnRyaWVzKFxuXHRcdFx0XHRPYmplY3QuZW50cmllcyhpbml0aWFsKS5maWx0ZXIoKFssIHZhbHVlXSkgPT4gdmFsdWUgIT09IHVuZGVmaW5lZCksXG5cdFx0XHQpLFxuXHRcdCk7XG5cdH1cblxuXHRwcml2YXRlIHN0YXRpYyBldmFsdWF0ZTxSPihcblx0XHR2YWx1ZXM6IEZvcm1WYWx1ZXMsXG5cdFx0cmVxdWVzdDogRGVjbGFyZWRTY2hlbWEsXG5cdFx0ZGlydHk6IGJvb2xlYW4sXG5cdFx0c3VibWl0dGVkOiBib29sZWFuLFxuXHRcdHN1Ym1pc3Npb246IE9wZXJhdGlvblN0YXRlPFI+LFxuXHQpOiBGb3JtU3RhdGU8Uj4ge1xuXHRcdGNvbnN0IGlzc3VlcyA9IHZhbGlkYXRlQWdhaW5zdFNjaGVtYSh2YWx1ZXMsIHJlcXVlc3QpO1xuXHRcdGNvbnN0IGVycm9yczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiA9IHt9O1xuXHRcdGZvciAoY29uc3QgaXNzdWUgb2YgaXNzdWVzKSB7XG5cdFx0XHRjb25zdCBbaGVhZF0gPSBpc3N1ZS5wYXRoO1xuXHRcdFx0Y29uc3QgbmFtZSA9IHR5cGVvZiBoZWFkID09PSBcInN0cmluZ1wiID8gaGVhZCA6IFwiXCI7XG5cdFx0XHRpZiAoIShuYW1lIGluIGVycm9ycykpIHtcblx0XHRcdFx0ZXJyb3JzW25hbWVdID0gaXNzdWUuY29kZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0cmV0dXJuIE9iamVjdC5mcmVlemUoe1xuXHRcdFx0dmFsdWVzLFxuXHRcdFx0aXNzdWVzOiBPYmplY3QuZnJlZXplKGlzc3VlcyksXG5cdFx0XHRlcnJvcnM6IE9iamVjdC5mcmVlemUoZXJyb3JzKSxcblx0XHRcdHZhbGlkOiBpc3N1ZXMubGVuZ3RoID09PSAwLFxuXHRcdFx0ZGlydHksXG5cdFx0XHRzdWJtaXR0ZWQsXG5cdFx0XHRzdWJtaXNzaW9uLFxuXHRcdH0pO1xuXHR9XG5cblx0LyoqIFNldCBvbmUgZmllbGQ7IGB1bmRlZmluZWRgIHVuc2V0cyBpdC4gKi9cblx0cHVibGljIHJlYWRvbmx5IHNldCA9IChuYW1lOiBzdHJpbmcsIHZhbHVlOiB1bmtub3duKTogdm9pZCA9PiB7XG5cdFx0dGhpcy5zZXRWYWx1ZXMoeyBbbmFtZV06IHZhbHVlIH0pO1xuXHR9O1xuXG5cdC8qKiBTZXQgc2V2ZXJhbCBmaWVsZHMgYXQgb25jZS4gKi9cblx0cHVibGljIHJlYWRvbmx5IHNldFZhbHVlcyA9IChjaGFuZ2VzOiBGb3JtVmFsdWVzKTogdm9pZCA9PiB7XG5cdFx0Y29uc3QgY3VycmVudCA9IHRoaXMuZ2V0U25hcHNob3QoKTtcblx0XHRjb25zdCB2YWx1ZXM6IFJlY29yZDxzdHJpbmcsIHVua25vd24+ID0geyAuLi5jdXJyZW50LnZhbHVlcyB9O1xuXHRcdGZvciAoY29uc3QgW25hbWUsIHJhd10gb2YgT2JqZWN0LmVudHJpZXMoY2hhbmdlcykpIHtcblx0XHRcdGNvbnN0IGZpZWxkID0gdGhpcy5ieU5hbWUuZ2V0KG5hbWUpO1xuXHRcdFx0aWYgKGZpZWxkID09PSB1bmRlZmluZWQpIHtcblx0XHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtTdG9yZUVycm9yKGAke3RoaXMuaWR9IGhhcyBubyBmaWVsZCAke25hbWV9YCk7XG5cdFx0XHR9XG5cdFx0XHRjb25zdCB2YWx1ZSA9IGNvZXJjZShmaWVsZCwgcmF3KTtcblx0XHRcdGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG5cdFx0XHRcdGRlbGV0ZSB2YWx1ZXNbbmFtZV07XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR2YWx1ZXNbbmFtZV0gPSB2YWx1ZTtcblx0XHRcdH1cblx0XHR9XG5cdFx0dGhpcy5wdWJsaXNoKFxuXHRcdFx0Rm9ybVN0b3JlLmV2YWx1YXRlKFxuXHRcdFx0XHRPYmplY3QuZnJlZXplKHZhbHVlcyksXG5cdFx0XHRcdHRoaXMucmVxdWVzdCxcblx0XHRcdFx0dHJ1ZSxcblx0XHRcdFx0Y3VycmVudC5zdWJtaXR0ZWQsXG5cdFx0XHRcdGN1cnJlbnQuc3VibWlzc2lvbixcblx0XHRcdCksXG5cdFx0KTtcblx0fTtcblxuXHQvKiogVGhlIGRlY2xhcmVkIGZpZWxkLCBmb3IgYSByZW5kZXJlciB3b3JraW5nIGZyb20gYSBuYW1lLiAqL1xuXHRwdWJsaWMgZmllbGQobmFtZTogc3RyaW5nKTogRm9ybUZpZWxkIHtcblx0XHRjb25zdCBmaWVsZCA9IHRoaXMuYnlOYW1lLmdldChuYW1lKTtcblx0XHRpZiAoZmllbGQgPT09IHVuZGVmaW5lZCkge1xuXHRcdFx0dGhyb3cgbmV3IFFnaXNTZGtTdG9yZUVycm9yKGAke3RoaXMuaWR9IGhhcyBubyBmaWVsZCAke25hbWV9YCk7XG5cdFx0fVxuXHRcdHJldHVybiBmaWVsZDtcblx0fVxuXG5cdC8qKiBCYWNrIHRvIHRoZSBpbml0aWFsIHZhbHVlcyBhbmQgYW4gaWRsZSBzdWJtaXNzaW9uOyBhYm9ydHMgYSBjYWxsIGluIGZsaWdodC4gKi9cblx0cHVibGljIHJlYWRvbmx5IHJlc2V0ID0gKCk6IHZvaWQgPT4ge1xuXHRcdHRoaXMub3BlcmF0aW9uLnJlc2V0KCk7XG5cdFx0dGhpcy5wdWJsaXNoKFxuXHRcdFx0Rm9ybVN0b3JlLmV2YWx1YXRlKHRoaXMuaW5pdGlhbCwgdGhpcy5yZXF1ZXN0LCBmYWxzZSwgZmFsc2UsIElETEUpLFxuXHRcdCk7XG5cdH07XG5cblx0LyoqIEFib3J0IGEgc3VibWlzc2lvbiBpbiBmbGlnaHQ7IHRoZSB2YWx1ZXMgc3RheS4gKi9cblx0cHVibGljIHJlYWRvbmx5IGFib3J0ID0gKCk6IHZvaWQgPT4ge1xuXHRcdHRoaXMub3BlcmF0aW9uLmFib3J0KCk7XG5cdH07XG5cblx0LyoqXG5cdCAqIFZhbGlkYXRlLCB0aGVuIHJ1biB0aGUgYWN0aW9uIHdpdGggdGhlIGN1cnJlbnQgdmFsdWVzLiBSZXNvbHZlcyB3aXRoIHRoZVxuXHQgKiByZXN1bHQsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlIHZhbHVlcyBhcmUgaW52YWxpZCAobm8gY2FsbCBpcyBtYWRlKSBvclxuXHQgKiB0aGUgY2FsbCBmYWlsZWQsIHdhcyBhYm9ydGVkIG9yIHN1cGVyc2VkZWQgLSBgc3VibWlzc2lvbmAgc2F5cyB3aGljaC5cblx0ICovXG5cdHB1YmxpYyByZWFkb25seSBzdWJtaXQgPSBhc3luYyAoKTogUHJvbWlzZTxSIHwgdW5kZWZpbmVkPiA9PiB7XG5cdFx0Y29uc3QgY3VycmVudCA9IHRoaXMuZ2V0U25hcHNob3QoKTtcblx0XHRpZiAoIWN1cnJlbnQudmFsaWQpIHtcblx0XHRcdHRoaXMucHVibGlzaCh7IC4uLmN1cnJlbnQsIHN1Ym1pdHRlZDogdHJ1ZSB9KTtcblx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0fVxuXHRcdGlmICghY3VycmVudC5zdWJtaXR0ZWQpIHtcblx0XHRcdHRoaXMucHVibGlzaCh7IC4uLmN1cnJlbnQsIHN1Ym1pdHRlZDogdHJ1ZSB9KTtcblx0XHR9XG5cdFx0cmV0dXJuIHRoaXMub3BlcmF0aW9uLnJ1bihjdXJyZW50LnZhbHVlcyBhcyBSZXEpO1xuXHR9O1xuXG5cdC8qKiBTdG9wIGZvbGxvd2luZyB0aGUgc3VibWlzc2lvbjsgZm9yIGFuIGFkYXB0ZXIgdGVhcmluZyB0aGUgZm9ybSBkb3duLiAqL1xuXHRwdWJsaWMgZGlzcG9zZSgpOiB2b2lkIHtcblx0XHR0aGlzLm9wZXJhdGlvbi5hYm9ydCgpO1xuXHRcdHRoaXMudW5zdWJzY3JpYmUoKTtcblx0fVxufVxuXG4vKipcbiAqIFRoZSBmb3JtIGZvciBgcWdpcy48aWQ+YCwgdHlwZWQgZnJvbSB0aGUgc2NoZW1hOiB0aGUgcmVxdWVzdCBuYW1lcyB0aGVcbiAqIGZpZWxkcywgdGhlIHJlc3VsdCB0eXBlcyB0aGUgc3VibWlzc2lvbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGZvcm1TdG9yZTxPLCBLIGV4dGVuZHMga2V5b2YgTyAmIHN0cmluZz4oXG5cdHFnaXM6IFFnaXNTZGtDb3JlPE8sIHVua25vd24+LFxuXHRpZDogSyxcblx0b3B0aW9ucz86IEZvcm1PcHRpb25zLFxuKTogRm9ybVN0b3JlPFJlcXVlc3RPZjxPLCBLPiAmIG9iamVjdCwgUmVzdWx0T2Y8TywgSz4+IHtcblx0cmV0dXJuIG5ldyBGb3JtU3RvcmUocWdpcyBhcyBRZ2lzU2RrQ29yZTx1bmtub3duLCB1bmtub3duPiwgaWQsIG9wdGlvbnMpO1xufVxuIiwKICAgICIvKioge0BsaW5rIEhvc3RRdWVyeVN0b3JlfTogcmVhZHMgb2YgdGhlIGN1cmF0ZWQgaG9zdCBzdXJmYWNlLCByZWZ1c2VkIGJlZm9yZSBhbnkgY2FsbC4gKi9cblxuaW1wb3J0IHsgUWdpc1Nka0JyaWRnZUFib3J0ZWRFcnJvciB9IGZyb20gXCIuLi9icmlkZ2VcIjtcbmltcG9ydCB0eXBlIHtcblx0SG9zdE9wZXJhdGlvbklkLFxuXHRMYXllclBhZ2UsXG5cdFZlY3RvckxheWVySW5mbyxcbn0gZnJvbSBcIi4uL2dlbmVyYXRlZC9ob3N0XCI7XG5pbXBvcnQgdHlwZSB7IFFnaXNTZGtDb3JlLCBRZ2lzU2RrSG9zdCB9IGZyb20gXCIuLi9xZ2lzLXNka1wiO1xuaW1wb3J0IHsgYXNFcnJvciwgQmFzZVN0b3JlIH0gZnJvbSBcIi4vYmFzZVwiO1xuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIEhvc3RRdWVyeVN0b3JlXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqIFdoZXJlIG9uZSBob3N0IHF1ZXJ5IHN0YW5kcy4gKi9cbmV4cG9ydCB0eXBlIEhvc3RRdWVyeVN0YXRlPFQ+ID1cblx0fCB7IHJlYWRvbmx5IHN0YXR1czogXCJpZGxlXCIgfVxuXHR8IHsgcmVhZG9ubHkgc3RhdHVzOiBcImxvYWRpbmdcIiB9XG5cdHwgeyByZWFkb25seSBzdGF0dXM6IFwib2tcIjsgcmVhZG9ubHkgdmFsdWU6IFQgfVxuXHR8IHsgcmVhZG9ubHkgc3RhdHVzOiBcImVycm9yXCI7IHJlYWRvbmx5IGVycm9yOiBFcnJvciB9XG5cdHwge1xuXHRcdFx0LyoqIFRoZSBoYW5kc2hha2UgZGlkIG5vdCBncmFudCBgb3BlcmF0aW9uYDsgbm8gY2FsbCB3YXMgbWFkZS4gKi9cblx0XHRcdHJlYWRvbmx5IHN0YXR1czogXCJyZWZ1c2VkXCI7XG5cdFx0XHRyZWFkb25seSBvcGVyYXRpb246IEhvc3RPcGVyYXRpb25JZDtcblx0XHRcdHJlYWRvbmx5IG1lc3NhZ2U6IHN0cmluZztcblx0ICB9O1xuXG5jb25zdCBJRExFX1FVRVJZOiBIb3N0UXVlcnlTdGF0ZTxuZXZlcj4gPSBPYmplY3QuZnJlZXplKHsgc3RhdHVzOiBcImlkbGVcIiB9KTtcblxuLyoqIFdoYXQgYSBob3N0IHF1ZXJ5IHJ1bnMgb25jZSB0aGUgZ3JhbnQgaXMgY29uZmlybWVkLiAqL1xuZXhwb3J0IHR5cGUgSG9zdFF1ZXJ5TG9hZGVyPFQ+ID0gKFxuXHRob3N0OiBRZ2lzU2RrSG9zdCxcblx0b3B0aW9uczogeyByZWFkb25seSBzaWduYWw6IEFib3J0U2lnbmFsIH0sXG4pID0+IFByb21pc2U8VD47XG5cbi8qKlxuICogUmVhZCB0aGUgY3VyYXRlZCBob3N0IHN1cmZhY2UsIGdyYW50IGZpcnN0LlxuICpcbiAqIGByZWZyZXNoYCB3YWl0cyBmb3IgdGhlIGhhbmRzaGFrZSwgdGhlbiAtIHdoZW4gYHFnaXMuaG9zdC5ncmFudGVkYCBsYWNrc1xuICogdGhlIG9wZXJhdGlvbiB0aGUgcXVlcnkgbmVlZHMgLSBzZXR0bGVzIG9uIGByZWZ1c2VkYCB3aXRob3V0IGEgY2FsbCwgc28gYVxuICogcGFnZSBjYW4gc2hvdyBcImFzayB0aGUgcGx1Z2luIGF1dGhvciBmb3IgYGxheWVycy5yZWFkYFwiIGluc3RlYWQgb2YgYVxuICogYG5vdF9hdXRob3JpemVkYCBmYXVsdC4gT3RoZXJ3aXNlIHRoZSBsb2FkZXIgcnVucyB3aXRoIGxhdGVzdC13aW5zXG4gKiBzZW1hbnRpY3MgbGlrZSBhbiBvcGVyYXRpb24gc3RvcmUuXG4gKi9cbmV4cG9ydCBjbGFzcyBIb3N0UXVlcnlTdG9yZTxUPiBleHRlbmRzIEJhc2VTdG9yZTxIb3N0UXVlcnlTdGF0ZTxUPj4ge1xuXHRwcml2YXRlIGdlbmVyYXRpb24gPSAwO1xuXHRwcml2YXRlIGNvbnRyb2xsZXI6IEFib3J0Q29udHJvbGxlciB8IG51bGwgPSBudWxsO1xuXG5cdHB1YmxpYyBjb25zdHJ1Y3Rvcihcblx0XHRwcml2YXRlIHJlYWRvbmx5IHFnaXM6IFFnaXNTZGtDb3JlPHVua25vd24sIHVua25vd24+LFxuXHRcdHB1YmxpYyByZWFkb25seSBvcGVyYXRpb246IEhvc3RPcGVyYXRpb25JZCxcblx0XHRwcml2YXRlIHJlYWRvbmx5IGxvYWRlcjogSG9zdFF1ZXJ5TG9hZGVyPFQ+LFxuXHQpIHtcblx0XHRzdXBlcihJRExFX1FVRVJZKTtcblx0fVxuXG5cdHB1YmxpYyByZWFkb25seSBhYm9ydCA9ICgpOiB2b2lkID0+IHtcblx0XHR0aGlzLmdlbmVyYXRpb24gKz0gMTtcblx0XHR0aGlzLmNvbnRyb2xsZXI/LmFib3J0KCk7XG5cdFx0dGhpcy5jb250cm9sbGVyID0gbnVsbDtcblx0fTtcblxuXHRwdWJsaWMgcmVhZG9ubHkgcmVzZXQgPSAoKTogdm9pZCA9PiB7XG5cdFx0dGhpcy5hYm9ydCgpO1xuXHRcdHRoaXMucHVibGlzaChJRExFX1FVRVJZKTtcblx0fTtcblxuXHRwdWJsaWMgcmVhZG9ubHkgcmVmcmVzaCA9IGFzeW5jICgpOiBQcm9taXNlPFQgfCB1bmRlZmluZWQ+ID0+IHtcblx0XHR0aGlzLmFib3J0KCk7XG5cdFx0Y29uc3QgbWluZSA9IHRoaXMuZ2VuZXJhdGlvbjtcblx0XHRjb25zdCBjb250cm9sbGVyID0gbmV3IEFib3J0Q29udHJvbGxlcigpO1xuXHRcdHRoaXMuY29udHJvbGxlciA9IGNvbnRyb2xsZXI7XG5cdFx0dGhpcy5wdWJsaXNoKHsgc3RhdHVzOiBcImxvYWRpbmdcIiB9KTtcblx0XHR0cnkge1xuXHRcdFx0YXdhaXQgdGhpcy5xZ2lzLnJlYWR5O1xuXHRcdFx0aWYgKHRoaXMuZ2VuZXJhdGlvbiAhPT0gbWluZSkge1xuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0aWYgKCF0aGlzLnFnaXMuaG9zdC5ncmFudGVkLmluY2x1ZGVzKHRoaXMub3BlcmF0aW9uKSkge1xuXHRcdFx0XHR0aGlzLnB1Ymxpc2goe1xuXHRcdFx0XHRcdHN0YXR1czogXCJyZWZ1c2VkXCIsXG5cdFx0XHRcdFx0b3BlcmF0aW9uOiB0aGlzLm9wZXJhdGlvbixcblx0XHRcdFx0XHRtZXNzYWdlOiBgdGhpcyB2aWV3IHdhcyBub3QgZ3JhbnRlZCAke3RoaXMub3BlcmF0aW9ufWAsXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRyZXR1cm4gdW5kZWZpbmVkO1xuXHRcdFx0fVxuXHRcdFx0Y29uc3QgdmFsdWUgPSBhd2FpdCB0aGlzLmxvYWRlcih0aGlzLnFnaXMuaG9zdCwge1xuXHRcdFx0XHRzaWduYWw6IGNvbnRyb2xsZXIuc2lnbmFsLFxuXHRcdFx0fSk7XG5cdFx0XHRpZiAodGhpcy5nZW5lcmF0aW9uICE9PSBtaW5lKSB7XG5cdFx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnB1Ymxpc2goeyBzdGF0dXM6IFwib2tcIiwgdmFsdWUgfSk7XG5cdFx0XHRyZXR1cm4gdmFsdWU7XG5cdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdGlmIChcblx0XHRcdFx0dGhpcy5nZW5lcmF0aW9uICE9PSBtaW5lIHx8XG5cdFx0XHRcdGVycm9yIGluc3RhbmNlb2YgUWdpc1Nka0JyaWRnZUFib3J0ZWRFcnJvclxuXHRcdFx0KSB7XG5cdFx0XHRcdHJldHVybiB1bmRlZmluZWQ7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLnB1Ymxpc2goeyBzdGF0dXM6IFwiZXJyb3JcIiwgZXJyb3I6IGFzRXJyb3IoZXJyb3IpIH0pO1xuXHRcdFx0cmV0dXJuIHVuZGVmaW5lZDtcblx0XHR9IGZpbmFsbHkge1xuXHRcdFx0aWYgKHRoaXMuY29udHJvbGxlciA9PT0gY29udHJvbGxlcikge1xuXHRcdFx0XHR0aGlzLmNvbnRyb2xsZXIgPSBudWxsO1xuXHRcdFx0fVxuXHRcdH1cblx0fTtcbn1cblxuLyoqIE9wdGlvbnMgZm9yIHtAbGluayBsYXllcnNRdWVyeX0uICovXG5leHBvcnQgaW50ZXJmYWNlIExheWVyc1F1ZXJ5T3B0aW9ucyB7XG5cdC8qKiBJdGVtcyBwZXIgcGFnZSB3aGlsZSBmb2xsb3dpbmcgYG5leHRfY3Vyc29yYDsgdGhlIGhvc3QncyBkZWZhdWx0IG90aGVyd2lzZS4gKi9cblx0cmVhZG9ubHkgcGFnZVNpemU/OiBudW1iZXI7XG59XG5cbi8qKlxuICogRXZlcnkgdmVjdG9yIGxheWVyIG9mIHRoZSBwcm9qZWN0LCBmb2xsb3dpbmcgYGxheWVycy5saXN0YCBwYWdlcyB0byB0aGVcbiAqIGVuZDogd2hhdCBhIGxheWVyIHBpY2tlciBiaW5kcyB0by4gTmVlZHMgdGhlIGBsYXllcnMucmVhZGAgZ3JhbnQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXllcnNRdWVyeShcblx0cWdpczogUWdpc1Nka0NvcmU8dW5rbm93biwgdW5rbm93bj4sXG5cdG9wdGlvbnM6IExheWVyc1F1ZXJ5T3B0aW9ucyA9IHt9LFxuKTogSG9zdFF1ZXJ5U3RvcmU8cmVhZG9ubHkgVmVjdG9yTGF5ZXJJbmZvW10+IHtcblx0cmV0dXJuIG5ldyBIb3N0UXVlcnlTdG9yZShxZ2lzLCBcImxheWVycy5saXN0XCIsIGFzeW5jIChob3N0LCB7IHNpZ25hbCB9KSA9PiB7XG5cdFx0Y29uc3QgaXRlbXM6IFZlY3RvckxheWVySW5mb1tdID0gW107XG5cdFx0bGV0IGN1cnNvcjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuXHRcdGRvIHtcblx0XHRcdGNvbnN0IHBhZ2U6IExheWVyUGFnZSA9IGF3YWl0IGhvc3QubGF5ZXJzLmxpc3QoXG5cdFx0XHRcdHtcblx0XHRcdFx0XHQuLi4oY3Vyc29yID09PSB1bmRlZmluZWQgPyB7fSA6IHsgY3Vyc29yIH0pLFxuXHRcdFx0XHRcdC4uLihvcHRpb25zLnBhZ2VTaXplID09PSB1bmRlZmluZWRcblx0XHRcdFx0XHRcdD8ge31cblx0XHRcdFx0XHRcdDogeyBsaW1pdDogb3B0aW9ucy5wYWdlU2l6ZSB9KSxcblx0XHRcdFx0fSxcblx0XHRcdFx0eyBzaWduYWwgfSxcblx0XHRcdCk7XG5cdFx0XHRpdGVtcy5wdXNoKC4uLnBhZ2UuaXRlbXMpO1xuXHRcdFx0Y3Vyc29yID0gcGFnZS5uZXh0X2N1cnNvcjtcblx0XHR9IHdoaWxlIChjdXJzb3IgIT09IHVuZGVmaW5lZCk7XG5cdFx0cmV0dXJuIE9iamVjdC5mcmVlemUoaXRlbXMpO1xuXHR9KTtcbn1cblxuLyoqXG4gKiBUaGUgZmllbGQgbmFtZXMgb2Ygb25lIHZlY3RvciBsYXllciwgZm9yIGEgYGZpZWxkYCBpbnB1dCB3aG9zZSBgb2ZgIG5hbWVzXG4gKiBhIGxheWVyIGlucHV0OiBgbGF5ZXJzLmdldGAgdW5kZXIgdGhlIGBsYXllcnMucmVhZGAgZ3JhbnQuIEEgbGF5ZXIncyBDUlMgaXNcbiAqIG9uIHRoZSBzYW1lIHJlcGx5OyBhIHByb2plY3QgQ1JTIHF1ZXJ5IGlzIG5vdCBvbiB0aGUgd2lyZSB5ZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBsYXllckZpZWxkc1F1ZXJ5KFxuXHRxZ2lzOiBRZ2lzU2RrQ29yZTx1bmtub3duLCB1bmtub3duPixcblx0bGF5ZXJJZDogc3RyaW5nLFxuKTogSG9zdFF1ZXJ5U3RvcmU8cmVhZG9ubHkgc3RyaW5nW10+IHtcblx0cmV0dXJuIG5ldyBIb3N0UXVlcnlTdG9yZShxZ2lzLCBcImxheWVycy5nZXRcIiwgYXN5bmMgKGhvc3QsIHsgc2lnbmFsIH0pID0+IHtcblx0XHRjb25zdCBsYXllciA9IGF3YWl0IGhvc3QubGF5ZXJzLmdldCh7IGxheWVyX2lkOiBsYXllcklkIH0sIHsgc2lnbmFsIH0pO1xuXHRcdHJldHVybiBPYmplY3QuZnJlZXplKFsuLi5sYXllci5maWVsZF9uYW1lc10pO1xuXHR9KTtcbn1cbiIsCiAgICAiLyoqIHtAbGluayBTdHJlYW1TdG9yZX06IG9uZSBnZW5lcmF0ZWQgc3RyZWFtIGhlbGQgb3BlbiB3aGlsZSBpdHMgaW5wdXQgaXMgbm9uLW51bGwuICovXG5cbmltcG9ydCB7IGlzUGxhaW5SZWNvcmQgfSBmcm9tIFwiLi4vaW50ZXJuYWxcIjtcbmltcG9ydCB7IGFzRXJyb3IsIEJhc2VTdG9yZSB9IGZyb20gXCIuL2Jhc2VcIjtcblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBTdHJlYW1TdG9yZVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBIb3cgYSBzdHJlYW0gZW5kZWQsIGFzIHRoZSBnZW5lcmF0ZWQgbW9kdWxlIHJlcG9ydHMgaXQuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0cmVhbVRlcm1pbmFsTGlrZSB7XG5cdHJlYWRvbmx5IGtpbmQ6IHN0cmluZztcblx0cmVhZG9ubHkgbWVzc2FnZT86IHN0cmluZztcblx0cmVhZG9ubHkgZHJvcHBlZD86IG51bWJlcjtcbn1cblxuLyoqIFRoZSBoYW5kbGUgYSBnZW5lcmF0ZWQgc3RyZWFtIG1lbWJlciByZXNvbHZlcyB3aXRoLiAqL1xuZXhwb3J0IGludGVyZmFjZSBTdHJlYW1IYW5kbGVMaWtlIHtcblx0cmVhZG9ubHkgaWQ6IHN0cmluZztcblx0cmVhZG9ubHkgY2xvc2VkOiBib29sZWFuO1xuXHRjbG9zZSgpOiB2b2lkO1xufVxuXG4vKiogSGFuZGxlcnMgZm9yIGEgc3RyZWFtLCBhcyBhIGdlbmVyYXRlZCBtb2R1bGUgdHlwZXMgdGhlbS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtSGFuZGxlcnNMaWtlPEU+IHtcblx0cmVhZG9ubHkgb25FdmVudD86IChldmVudDogRSkgPT4gdm9pZDtcblx0cmVhZG9ubHkgb25UZXJtaW5hbD86ICh0ZXJtaW5hbDogU3RyZWFtVGVybWluYWxMaWtlKSA9PiB2b2lkO1xufVxuXG4vKiogQSBzdHJlYW0gbWVtYmVyIG9mIGEgZ2VuZXJhdGVkIG1hcC4gKi9cbmV4cG9ydCB0eXBlIFN0cmVhbTxJLCBFPiA9IChcblx0aW5wdXQ6IEksXG5cdGhhbmRsZXJzOiBTdHJlYW1IYW5kbGVyc0xpa2U8RT4sXG5cdG9wdGlvbnM/OiB7IHJlYWRvbmx5IHNpZ25hbD86IEFib3J0U2lnbmFsIH0sXG4pID0+IFByb21pc2U8U3RyZWFtSGFuZGxlTGlrZT47XG5cbi8qKiBXaGVyZSBvbmUgc3Vic2NyaXB0aW9uIHN0YW5kcy4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgU3RyZWFtU3RhdGU8RT4ge1xuXHQvKiogYGlkbGVgIHdpdGggYSBudWxsIGlucHV0LCBgZmFpbGVkYCB3aGVuIHRoZSBob3N0IHJlZnVzZWQgdG8gb3BlbiBpdC4gKi9cblx0cmVhZG9ubHkgc3RhdHVzOiBcImlkbGVcIiB8IFwib3BlbmluZ1wiIHwgXCJvcGVuXCIgfCBcImVuZGVkXCIgfCBcImZhaWxlZFwiO1xuXHRyZWFkb25seSBsYXN0RXZlbnQ6IEUgfCBudWxsO1xuXHRyZWFkb25seSB0ZXJtaW5hbDogU3RyZWFtVGVybWluYWxMaWtlIHwgbnVsbDtcblx0cmVhZG9ubHkgZXJyb3I6IEVycm9yIHwgbnVsbDtcbn1cblxuY29uc3QgSURMRV9TVFJFQU06IFN0cmVhbVN0YXRlPG5ldmVyPiA9IE9iamVjdC5mcmVlemUoe1xuXHRzdGF0dXM6IFwiaWRsZVwiLFxuXHRsYXN0RXZlbnQ6IG51bGwsXG5cdHRlcm1pbmFsOiBudWxsLFxuXHRlcnJvcjogbnVsbCxcbn0pO1xuXG4vKipcbiAqIFJldHVybiBhIGtleSB0aGF0IGlzIGVxdWFsIGZvciB0d28gaW5wdXRzIHdpdGggdGhlIHNhbWUgY29udGVudCwgd2hhdGV2ZXJcbiAqIHRoZSBvcmRlciB0aGVpciBmaWVsZHMgd2VyZSB3cml0dGVuIGluLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc3RhYmxlS2V5KHZhbHVlOiB1bmtub3duKTogc3RyaW5nIHtcblx0cmV0dXJuIEpTT04uc3RyaW5naWZ5KHZhbHVlLCAoX2tleSwgaXRlbTogdW5rbm93bikgPT5cblx0XHRpc1BsYWluUmVjb3JkKGl0ZW0pXG5cdFx0XHQ/IE9iamVjdC5mcm9tRW50cmllcyhcblx0XHRcdFx0XHRPYmplY3QuZW50cmllcyhpdGVtKS5zb3J0KChbYV0sIFtiXSkgPT4gKGEgPCBiID8gLTEgOiBhID4gYiA/IDEgOiAwKSksXG5cdFx0XHRcdClcblx0XHRcdDogaXRlbSxcblx0KTtcbn1cblxuLyoqXG4gKiBIb2xkIG9uZSBnZW5lcmF0ZWQgc3RyZWFtIG9wZW4gd2hpbGUgaXRzIGlucHV0IGlzIG5vbi1udWxsLlxuICpcbiAqIGBzZXRJbnB1dGAgZm9sbG93cyB0aGUgKmNvbnRlbnQqIG9mIHRoZSBpbnB1dDogYSBuZXcgb2JqZWN0IHdpdGggdGhlIHNhbWVcbiAqIGZpZWxkcyBjaGFuZ2VzIG5vdGhpbmcsIGEgZGlmZmVyZW50IG9uZSBjbG9zZXMgdGhlIG9sZCBzdHJlYW0gYW5kIG9wZW5zIGFcbiAqIG5ldyBvbmUsIGBudWxsYCBjbG9zZXMgaXQuIEhhbmRsZXJzIGFyZSByZWFkIGZyZXNoIG9uIGV2ZXJ5IGZyYW1lLCBzb1xuICogYHNldEhhbmRsZXJzYCB3aXRoIGEgbmV3IGNsb3N1cmUgcmVvcGVucyBub3RoaW5nLiBgY2xvc2VgIGlzIHNhZmUgYmVmb3JlIHRoZVxuICogaG9zdCBoYXMgYWNrbm93bGVkZ2VkIHRoZSBzdHJlYW06IHRoZSBoYW5kbGUgaXMgY2xvc2VkIHRoZSBtb21lbnQgaXRcbiAqIGFycml2ZXMuXG4gKi9cbmV4cG9ydCBjbGFzcyBTdHJlYW1TdG9yZTxJLCBFPiBleHRlbmRzIEJhc2VTdG9yZTxTdHJlYW1TdGF0ZTxFPj4ge1xuXHRwcml2YXRlIGtleTogc3RyaW5nIHwgbnVsbCA9IG51bGw7XG5cdHByaXZhdGUgY2FuY2VsOiAoKCkgPT4gdm9pZCkgfCBudWxsID0gbnVsbDtcblxuXHRwdWJsaWMgY29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSByZWFkb25seSBvcGVuOiBTdHJlYW08SSwgRT4sXG5cdFx0cHJpdmF0ZSBoYW5kbGVyczogU3RyZWFtSGFuZGxlcnNMaWtlPEU+ID0ge30sXG5cdCkge1xuXHRcdHN1cGVyKElETEVfU1RSRUFNKTtcblx0fVxuXG5cdC8qKiBSZXBsYWNlIHRoZSBoYW5kbGVycyB0aGUgbmV4dCBmcmFtZXMgcmVhY2g7IG5vdGhpbmcgcmVvcGVucy4gKi9cblx0cHVibGljIHNldEhhbmRsZXJzKGhhbmRsZXJzOiBTdHJlYW1IYW5kbGVyc0xpa2U8RT4pOiB2b2lkIHtcblx0XHR0aGlzLmhhbmRsZXJzID0gaGFuZGxlcnM7XG5cdH1cblxuXHRwdWJsaWMgcmVhZG9ubHkgc2V0SW5wdXQgPSAoaW5wdXQ6IEkgfCBudWxsKTogdm9pZCA9PiB7XG5cdFx0Y29uc3Qga2V5ID0gaW5wdXQgPT09IG51bGwgPyBudWxsIDogc3RhYmxlS2V5KGlucHV0KTtcblx0XHRpZiAoa2V5ID09PSB0aGlzLmtleSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblx0XHR0aGlzLmNhbmNlbD8uKCk7XG5cdFx0dGhpcy5jYW5jZWwgPSBudWxsO1xuXHRcdHRoaXMua2V5ID0ga2V5O1xuXHRcdGlmIChpbnB1dCA9PT0gbnVsbCB8fCBrZXkgPT09IG51bGwpIHtcblx0XHRcdHRoaXMucHVibGlzaChJRExFX1NUUkVBTSk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXHRcdHRoaXMuY2FuY2VsID0gdGhpcy5zdGFydChpbnB1dCk7XG5cdH07XG5cblx0cHVibGljIHJlYWRvbmx5IGNsb3NlID0gKCk6IHZvaWQgPT4ge1xuXHRcdHRoaXMuc2V0SW5wdXQobnVsbCk7XG5cdH07XG5cblx0cHJpdmF0ZSBzdGFydChpbnB1dDogSSk6ICgpID0+IHZvaWQge1xuXHRcdGxldCBjYW5jZWxsZWQgPSBmYWxzZTtcblx0XHRsZXQgaGFuZGxlOiBTdHJlYW1IYW5kbGVMaWtlIHwgbnVsbCA9IG51bGw7XG5cdFx0Y29uc3QgdXBkYXRlID0gKGNoYW5nZTogKHByZXZpb3VzOiBTdHJlYW1TdGF0ZTxFPikgPT4gU3RyZWFtU3RhdGU8RT4pID0+IHtcblx0XHRcdGlmICghY2FuY2VsbGVkKSB7XG5cdFx0XHRcdHRoaXMucHVibGlzaChjaGFuZ2UodGhpcy5nZXRTbmFwc2hvdCgpKSk7XG5cdFx0XHR9XG5cdFx0fTtcblx0XHR0aGlzLnB1Ymxpc2goe1xuXHRcdFx0c3RhdHVzOiBcIm9wZW5pbmdcIixcblx0XHRcdGxhc3RFdmVudDogbnVsbCxcblx0XHRcdHRlcm1pbmFsOiBudWxsLFxuXHRcdFx0ZXJyb3I6IG51bGwsXG5cdFx0fSk7XG5cdFx0dGhpcy5vcGVuKGlucHV0LCB7XG5cdFx0XHRvbkV2ZW50OiAoZXZlbnQpID0+IHtcblx0XHRcdFx0aWYgKGNhbmNlbGxlZCkge1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLmhhbmRsZXJzLm9uRXZlbnQ/LihldmVudCk7XG5cdFx0XHRcdHVwZGF0ZSgocHJldmlvdXMpID0+ICh7IC4uLnByZXZpb3VzLCBsYXN0RXZlbnQ6IGV2ZW50IH0pKTtcblx0XHRcdH0sXG5cdFx0XHRvblRlcm1pbmFsOiAodGVybWluYWwpID0+IHtcblx0XHRcdFx0aWYgKGNhbmNlbGxlZCkge1xuXHRcdFx0XHRcdHJldHVybjtcblx0XHRcdFx0fVxuXHRcdFx0XHR0aGlzLmhhbmRsZXJzLm9uVGVybWluYWw/Lih0ZXJtaW5hbCk7XG5cdFx0XHRcdHVwZGF0ZSgocHJldmlvdXMpID0+ICh7IC4uLnByZXZpb3VzLCBzdGF0dXM6IFwiZW5kZWRcIiwgdGVybWluYWwgfSkpO1xuXHRcdFx0fSxcblx0XHR9KS50aGVuKFxuXHRcdFx0KG9wZW5lZCkgPT4ge1xuXHRcdFx0XHRpZiAoY2FuY2VsbGVkKSB7XG5cdFx0XHRcdFx0b3BlbmVkLmNsb3NlKCk7XG5cdFx0XHRcdFx0cmV0dXJuO1xuXHRcdFx0XHR9XG5cdFx0XHRcdGhhbmRsZSA9IG9wZW5lZDtcblx0XHRcdFx0dXBkYXRlKChwcmV2aW91cykgPT5cblx0XHRcdFx0XHRwcmV2aW91cy5zdGF0dXMgPT09IFwiZW5kZWRcIlxuXHRcdFx0XHRcdFx0PyBwcmV2aW91c1xuXHRcdFx0XHRcdFx0OiB7IC4uLnByZXZpb3VzLCBzdGF0dXM6IFwib3BlblwiIH0sXG5cdFx0XHRcdCk7XG5cdFx0XHR9LFxuXHRcdFx0KGVycm9yOiB1bmtub3duKSA9PiB7XG5cdFx0XHRcdHVwZGF0ZSgoKSA9PiAoe1xuXHRcdFx0XHRcdHN0YXR1czogXCJmYWlsZWRcIixcblx0XHRcdFx0XHRsYXN0RXZlbnQ6IG51bGwsXG5cdFx0XHRcdFx0dGVybWluYWw6IG51bGwsXG5cdFx0XHRcdFx0ZXJyb3I6IGFzRXJyb3IoZXJyb3IpLFxuXHRcdFx0XHR9KSk7XG5cdFx0XHR9LFxuXHRcdCk7XG5cdFx0cmV0dXJuICgpID0+IHtcblx0XHRcdGNhbmNlbGxlZCA9IHRydWU7XG5cdFx0XHRoYW5kbGU/LmNsb3NlKCk7XG5cdFx0fTtcblx0fVxufVxuIgogIF0sCiAgIm1hcHBpbmdzIjogIjs7Ozs7Ozs7OztBQWFPLElBQU0sb0JBQTJCO0FBQ2pDLElBQU0sb0JBQTJCO0FBQ2pDLElBQU0scUNBQXVDO0FBcUQ3QyxTQUFTLGtCQUFpQixDQUFDLE9BQWlDO0FBQUEsRUFDbEUsT0FBTyxPQUFPLFVBQVUsWUFBWSxPQUFPLGNBQWMsS0FBSztBQUFBO0FBQUE7QUFNeEQsTUFBTSxpQ0FBZ0MsY0FBYTtBQUFBLEVBQ2xELFdBQVcsQ0FBQyxTQUFpQjtBQUFBLElBQ25DLE1BQU0sU0FBUyxxQkFBcUI7QUFBQTtBQUV0QztBQUFBO0FBS08sTUFBTSx3QkFBdUI7QUFBQSxFQUNuQjtBQUFBLEVBQ0E7QUFBQSxFQUVULFdBQVcsQ0FBQyxNQUFvQyxNQUFjO0FBQUEsSUFDcEUsS0FBSyxPQUFPLE9BQU8sT0FBTyxDQUFDLEdBQUcsSUFBSSxDQUFDO0FBQUEsSUFDbkMsS0FBSyxPQUFPO0FBQUE7QUFBQSxFQUdOLE1BQU0sR0FBOEI7QUFBQSxJQUMxQyxPQUFPO0FBQUEsTUFDTixNQUFNLENBQUMsR0FBRyxLQUFLLElBQUk7QUFBQSxNQUNuQixNQUFNLEtBQUs7QUFBQSxJQUNaO0FB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QUNBLEtBQUssU0FBUyxVQUFVLEtBQUs7QUFBQSxRQUM3QixPQUFPLENBQUMsY0FBYyxLQUFLLFVBQVUsV0FBVyxNQUFNLEVBQUU7QUFBQTtBQUFBLE1BRXpELFlBQVksQ0FBQyxhQUFhO0FBQUEsUUFDekIsSUFBSSxXQUFXO0FBQUEsVUFDZDtBQUFBLFFBQ0Q7QUFBQSxRQUNBLEtBQUssU0FBUyxhQUFhLFFBQVE7QUFBQSxRQUNuQyxPQUFPLENBQUMsY0FBYyxLQUFLLFVBQVUsUUFBUSxTQUFTLFNBQVMsRUFBRTtBQUFBO0FBQUEsSUFFbkUsQ0FBQyxFQUFFLEtBQ0YsQ0FBQyxXQUFXO0FBQUEsTUFDWCxJQUFJLFdBQVc7QUFBQSxRQUNkLE9BQU8sTUFBTTtBQUFBLFFBQ2I7QUFBQSxNQUNEO0FBQUEsTUFDQSxTQUFTO0FBQUEsTUFDVCxPQUFPLENBQUMsYUFDUCxTQUFTLFdBQVcsVUFDakIsV0FDQSxLQUFLLFVBQVUsUUFBUSxPQUFPLENBQ2xDO0FBQUEsT0FFRCxDQUFDLFVBQW1CO0FBQUEsTUFDbkIsT0FBTyxPQUFPO0FBQUEsUUFDYixRQUFRO0FBQUEsUUFDUixXQUFXO0FBQUEsUUFDWCxVQUFVO0FBQUEsUUFDVixPQUFPLFFBQVEsS0FBSztBQUFBLE1BQ3JCLEVBQUU7QUFBQSxLQUVKO0FBQUEsSUFDQSxPQUFPLE1BQU07QUFBQSxNQUNaLFlBQVk7QUFBQSxNQUNaLFFBQVEsTUFBTTtBQUFBO0FBQUE7QUFHakI7IiwKICAiZGVidWdJZCI6ICJERDY0NUIwMDg1Qjc2NTY3NjQ3NTZFMjE2NDc1NkUyMSIsCiAgIm5hbWVzIjogW10KfQ==
|