@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.
@@ -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==