footprintjs 9.11.0 → 9.12.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (31) hide show
  1. package/CLAUDE.md +2 -1
  2. package/README.md +18 -0
  3. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +33 -0
  4. package/dist/esm/lib/engine/narrative/CombinedNarrativeRecorder.js +25 -1
  5. package/dist/esm/lib/engine/narrative/types.d.ts +3 -0
  6. package/dist/esm/lib/engine/narrative/types.js +1 -1
  7. package/dist/esm/lib/memory/TransactionBuffer.d.ts +63 -3
  8. package/dist/esm/lib/memory/TransactionBuffer.js +177 -9
  9. package/dist/esm/lib/recorder/CombinedRecorder.d.ts +3 -0
  10. package/dist/esm/lib/recorder/CombinedRecorder.js +1 -1
  11. package/dist/esm/lib/runner/ExecutionRuntime.d.ts +17 -0
  12. package/dist/esm/lib/runner/ExecutionRuntime.js +1 -1
  13. package/dist/esm/lib/runner/FlowChartExecutor.d.ts +27 -0
  14. package/dist/esm/lib/runner/FlowChartExecutor.js +57 -48
  15. package/dist/esm/lib/scope/types.d.ts +3 -0
  16. package/dist/esm/lib/scope/types.js +1 -1
  17. package/dist/lib/engine/narrative/CombinedNarrativeRecorder.js +25 -1
  18. package/dist/lib/engine/narrative/types.js +1 -1
  19. package/dist/lib/memory/TransactionBuffer.js +177 -9
  20. package/dist/lib/recorder/CombinedRecorder.js +1 -1
  21. package/dist/lib/runner/ExecutionRuntime.js +1 -1
  22. package/dist/lib/runner/FlowChartExecutor.js +57 -48
  23. package/dist/lib/scope/types.js +1 -1
  24. package/dist/types/lib/engine/narrative/CombinedNarrativeRecorder.d.ts +33 -0
  25. package/dist/types/lib/engine/narrative/types.d.ts +3 -0
  26. package/dist/types/lib/memory/TransactionBuffer.d.ts +63 -3
  27. package/dist/types/lib/recorder/CombinedRecorder.d.ts +3 -0
  28. package/dist/types/lib/runner/ExecutionRuntime.d.ts +17 -0
  29. package/dist/types/lib/runner/FlowChartExecutor.d.ts +27 -0
  30. package/dist/types/lib/scope/types.d.ts +3 -0
  31. package/package.json +1 -1
@@ -139,16 +139,21 @@ export declare class TransactionBuffer {
139
139
  private toChangeOnlyPayload;
140
140
  /**
141
141
  * Delta-encoded payload (`commitValues: 'delta'`, #13c-B) — same net-change
142
- * filter as {@link toChangeOnlyPayload}, two encoding differences:
142
+ * filter as {@link toChangeOnlyPayload}, three encoding differences:
143
143
  *
144
144
  * 1. **One trace entry per surviving path** (the §2.5 dedup rule — `append`
145
145
  * is NOT idempotent on replay, so duplicate entries would multiply
146
146
  * tails). The verb is resolved from the path's op mix + base→final
147
147
  * relationship; entries are ordered by each path's LAST touch,
148
148
  * preserving last-writer-wins for nested/overlapping paths.
149
- * 2. **Verb resolution per path**:
149
+ * 2. **Verb resolution per path** — for a path with NO surviving relative
150
+ * (see 3):
150
151
  * - last op `'delete'` AND final value gone → `delete` (the path stays
151
- * enumerated in `overwrite` with `undefined` for key-set consumers);
152
+ * enumerated in `overwrite` with `undefined` for key-set consumers).
153
+ * Requires the parent to be a real container in the base — replay uses
154
+ * `nativeDelete`, which is inert on a primitive/absent parent, whereas
155
+ * the `'full'` flattening (`_set` of `undefined`) COERCES that parent
156
+ * into an object; when they would disagree we keep the flattening;
152
157
  * - ONLY `'merge'` ops → `merge` with the accumulated `updatePatch`
153
158
  * delta (replaying the accumulated delta once ≡ the full mode's
154
159
  * k sequential replays — `deepSmartMerge` is reference-idempotent
@@ -163,11 +168,66 @@ export declare class TransactionBuffer {
163
168
  * with the `'full'` mode's committed state is the contract). If base
164
169
  * and that value are arrays and base is a STRICT PREFIX → `append`
165
170
  * storing only the tail; else `set` storing the full value.
171
+ * 3. **OVERLAP FAMILIES take the full-value fallback.** `overwrite` /
172
+ * `updates` are nested path TREES, so two surviving paths where one is
173
+ * an ancestor of the other (`a` and `a.p`) share storage. The `'full'`
174
+ * payload survives that because every entry stores the FULL value at its
175
+ * path, drawn from one coherent tree — nested entries agree with their
176
+ * ancestor by construction. Delta's per-path encodings do NOT: an
177
+ * `append` ancestor stores only a TAIL (whose indices are shifted
178
+ * relative to the whole array) and a `delete` ancestor stores
179
+ * `undefined`, so whichever entry is written second silently destroys or
180
+ * corrupts the other — the recorded write is LOST at replay. Therefore
181
+ * every path that has a surviving ancestor/descendant is committed as a
182
+ * plain `set` of the value it holds in the family's replayed value
183
+ * ({@link replayFamilyVerbs}), and the family's shallowest path (whose
184
+ * set covers the whole subtree) is emitted LAST. One coherent tree in,
185
+ * one coherent tree out: entries can no longer clobber each other and
186
+ * the replayed value is exact regardless of order.
166
187
  *
167
188
  * Losslessness never depends on detection succeeding — every fallback is
168
189
  * today's full-value `set`.
169
190
  */
170
191
  private toDeltaPayload;
192
+ /**
193
+ * Bucket the staged ops of every OVERLAPPING family by family root, in op
194
+ * order — the input {@link replayFamilyVerbs} folds. Ops on paths the
195
+ * net-change filter dropped are skipped (they are absent from `rootOf`),
196
+ * exactly as the `'full'` payload drops them from its trace. One pass over
197
+ * `opTrace`, and only when at least one family actually overlaps — commits
198
+ * that write no nested path pay nothing.
199
+ */
200
+ private opsByFamily;
201
+ /**
202
+ * Replay ONE overlapping family's staged ops onto the family root's base
203
+ * value — the multi-path generalisation of {@link replayPathVerbs}, and
204
+ * byte-for-byte what `applySmartMerge` produces for the corresponding
205
+ * `'full'`-mode entries: each `set`/`delete` position writes that path's
206
+ * `overwritePatch` value, each `merge` position deep-merges that path's
207
+ * accumulated `updatePatch` delta into the value replayed so far.
208
+ *
209
+ * (Both patches are single coherent trees, so a full-mode bundle's stored
210
+ * value at any recorded path always reads back as its `overwritePatch` /
211
+ * `updatePatch` value — which is why sourcing from them here reproduces the
212
+ * full-mode replay exactly, including its intermediate-coercion quirks.)
213
+ *
214
+ * The value is held in a `{ v }` box so the root itself (relative path `[]`)
215
+ * can be REPLACED by `_set` the same way `applySmartMerge` replaces it
216
+ * inside the state tree — including `nativeSet`'s coercion of primitive
217
+ * intermediates.
218
+ */
219
+ private replayFamilyVerbs;
220
+ /**
221
+ * May a staged `delete` at this path commit as the `'delete'` verb?
222
+ *
223
+ * Only when removing the key and the `'full'` mode's flattening (`_set` of
224
+ * `undefined`) land in the same place. They diverge when the parent is not
225
+ * a container: `nativeDelete` walks away untouched, while `nativeSet`
226
+ * COERCES the primitive parent into an object to hold the key. Committing
227
+ * `delete` there would silently drop a state change the stage really made,
228
+ * so those (pathological) deletes keep the historical flattening.
229
+ */
230
+ private deleteReplaysAsFlattening;
171
231
  /**
172
232
  * Replay ONE path's op-verb sequence against its base value, exactly the
173
233
  * way `applySmartMerge` replays the corresponding full-mode bundle: every
@@ -203,16 +203,21 @@ export class TransactionBuffer {
203
203
  }
204
204
  /**
205
205
  * Delta-encoded payload (`commitValues: 'delta'`, #13c-B) — same net-change
206
- * filter as {@link toChangeOnlyPayload}, two encoding differences:
206
+ * filter as {@link toChangeOnlyPayload}, three encoding differences:
207
207
  *
208
208
  * 1. **One trace entry per surviving path** (the §2.5 dedup rule — `append`
209
209
  * is NOT idempotent on replay, so duplicate entries would multiply
210
210
  * tails). The verb is resolved from the path's op mix + base→final
211
211
  * relationship; entries are ordered by each path's LAST touch,
212
212
  * preserving last-writer-wins for nested/overlapping paths.
213
- * 2. **Verb resolution per path**:
213
+ * 2. **Verb resolution per path** — for a path with NO surviving relative
214
+ * (see 3):
214
215
  * - last op `'delete'` AND final value gone → `delete` (the path stays
215
- * enumerated in `overwrite` with `undefined` for key-set consumers);
216
+ * enumerated in `overwrite` with `undefined` for key-set consumers).
217
+ * Requires the parent to be a real container in the base — replay uses
218
+ * `nativeDelete`, which is inert on a primitive/absent parent, whereas
219
+ * the `'full'` flattening (`_set` of `undefined`) COERCES that parent
220
+ * into an object; when they would disagree we keep the flattening;
216
221
  * - ONLY `'merge'` ops → `merge` with the accumulated `updatePatch`
217
222
  * delta (replaying the accumulated delta once ≡ the full mode's
218
223
  * k sequential replays — `deepSmartMerge` is reference-idempotent
@@ -227,6 +232,22 @@ export class TransactionBuffer {
227
232
  * with the `'full'` mode's committed state is the contract). If base
228
233
  * and that value are arrays and base is a STRICT PREFIX → `append`
229
234
  * storing only the tail; else `set` storing the full value.
235
+ * 3. **OVERLAP FAMILIES take the full-value fallback.** `overwrite` /
236
+ * `updates` are nested path TREES, so two surviving paths where one is
237
+ * an ancestor of the other (`a` and `a.p`) share storage. The `'full'`
238
+ * payload survives that because every entry stores the FULL value at its
239
+ * path, drawn from one coherent tree — nested entries agree with their
240
+ * ancestor by construction. Delta's per-path encodings do NOT: an
241
+ * `append` ancestor stores only a TAIL (whose indices are shifted
242
+ * relative to the whole array) and a `delete` ancestor stores
243
+ * `undefined`, so whichever entry is written second silently destroys or
244
+ * corrupts the other — the recorded write is LOST at replay. Therefore
245
+ * every path that has a surviving ancestor/descendant is committed as a
246
+ * plain `set` of the value it holds in the family's replayed value
247
+ * ({@link replayFamilyVerbs}), and the family's shallowest path (whose
248
+ * set covers the whole subtree) is emitted LAST. One coherent tree in,
249
+ * one coherent tree out: entries can no longer clobber each other and
250
+ * the replayed value is exact regardless of order.
230
251
  *
231
252
  * Losslessness never depends on detection succeeding — every fallback is
232
253
  * today's full-value `set`.
@@ -235,7 +256,6 @@ export class TransactionBuffer {
235
256
  const overwrite = {};
236
257
  const updates = {};
237
258
  const trace = [];
238
- const survivingPaths = new Set();
239
259
  // Path → its op-verb sequence, ordered by LAST touch (delete +
240
260
  // re-insert moves a re-touched path to the end of the Map's insertion
241
261
  // order — preserving last-writer-wins for nested/overlapping paths).
@@ -255,16 +275,63 @@ export class TransactionBuffer {
255
275
  byPath.set(op.path, { verbs: [op.verb], ...(op.readKeys !== undefined && { readKeys: op.readKeys }) });
256
276
  }
257
277
  }
278
+ // Net-change filter — identical to 'full'. Survivors keep last-touch order.
279
+ const survivors = [];
258
280
  for (const [path, { verbs, readKeys }] of byPath) {
259
- const prov = readKeys !== undefined ? { readKeys } : undefined;
260
281
  const segments = path.split(DELIM);
261
282
  const before = _get(this.baseSnapshot, segments);
262
283
  const after = _get(this.workingCopy, segments);
263
284
  if (deepEqual(before, after))
264
285
  continue; // no-op or write-then-revert → no net change (same filter as 'full')
265
- survivingPaths.add(path);
286
+ survivors.push({ path, segments, verbs, readKeys, before, after });
287
+ }
288
+ const survivingPaths = new Set(survivors.map((s) => s.path));
289
+ // Group survivors into OVERLAP FAMILIES (rule 3): each path's family is
290
+ // keyed by its SHALLOWEST surviving ancestor — walking prefixes shallow
291
+ // first means the first hit is that root, and a depth-1 path (the common
292
+ // case) never enters the loop at all. Any two paths sharing a root are
293
+ // exactly the paths whose patch storage overlaps.
294
+ const rootOf = new Map();
295
+ const byRoot = new Map();
296
+ for (const s of survivors) {
297
+ let root = s.path;
298
+ for (let i = 1; i < s.segments.length; i++) {
299
+ const ancestor = s.segments.slice(0, i).join(DELIM);
300
+ if (survivingPaths.has(ancestor)) {
301
+ root = ancestor;
302
+ break;
303
+ }
304
+ }
305
+ rootOf.set(s.path, root);
306
+ const family = byRoot.get(root);
307
+ if (family)
308
+ family.push(s);
309
+ else
310
+ byRoot.set(root, [s]);
311
+ }
312
+ // Replay each overlapping family ONCE (lazily — most commits have none).
313
+ const familyOps = this.opsByFamily(rootOf, byRoot);
314
+ const familyValues = new Map();
315
+ const familyValue = (root) => {
316
+ if (!familyValues.has(root)) {
317
+ familyValues.set(root, this.replayFamilyVerbs(root.split(DELIM), familyOps.get(root) ?? []));
318
+ }
319
+ return familyValues.get(root);
320
+ };
321
+ const emit = (s) => {
322
+ const { path, segments, verbs, before } = s;
323
+ const prov = s.readKeys !== undefined ? { readKeys: s.readKeys } : undefined;
324
+ const root = rootOf.get(path);
325
+ const family = byRoot.get(root);
326
+ if (family.length > 1) {
327
+ // Rule 3 — full-value fallback from ONE coherent family value.
328
+ const relative = ['v', ...segments.slice(root.split(DELIM).length)];
329
+ trace.push({ path, verb: 'set', ...prov });
330
+ _set(overwrite, segments, structuredClone(_get({ v: familyValue(root) }, relative)));
331
+ return;
332
+ }
266
333
  const lastVerb = verbs[verbs.length - 1];
267
- if (lastVerb === 'delete' && after === undefined) {
334
+ if (lastVerb === 'delete' && s.after === undefined && this.deleteReplaysAsFlattening(segments)) {
268
335
  // Real deletion — replay removes the key. Keep the path enumerated
269
336
  // in `overwrite` (undefined) so Object.keys consumers see it.
270
337
  trace.push({ path, verb: 'delete', ...prov });
@@ -288,10 +355,97 @@ export class TransactionBuffer {
288
355
  _set(overwrite, segments, structuredClone(committed));
289
356
  }
290
357
  }
358
+ };
359
+ for (const s of survivors) {
360
+ const root = rootOf.get(s.path);
361
+ const family = byRoot.get(root);
362
+ if (family.length === 1) {
363
+ emit(s);
364
+ continue;
365
+ }
366
+ // Overlapping family: members in last-touch order, the ROOT emitted
367
+ // LAST — its whole-subtree set is what makes the replayed subtree
368
+ // exactly the family value (a descendant applied afterwards could only
369
+ // re-state a value already inside it, but would also leave behind the
370
+ // `key: undefined` shells 'full' mode never has).
371
+ if (s.path !== root)
372
+ emit(s);
373
+ if (family[family.length - 1] === s)
374
+ emit(family.find((m) => m.path === root));
291
375
  }
292
376
  const redactedPaths = new Set([...this.redactedPaths].filter((path) => survivingPaths.has(path)));
293
377
  return { overwrite, updates, redactedPaths, trace };
294
378
  }
379
+ /**
380
+ * Bucket the staged ops of every OVERLAPPING family by family root, in op
381
+ * order — the input {@link replayFamilyVerbs} folds. Ops on paths the
382
+ * net-change filter dropped are skipped (they are absent from `rootOf`),
383
+ * exactly as the `'full'` payload drops them from its trace. One pass over
384
+ * `opTrace`, and only when at least one family actually overlaps — commits
385
+ * that write no nested path pay nothing.
386
+ */
387
+ opsByFamily(rootOf, byRoot) {
388
+ const buckets = new Map();
389
+ for (const [root, family] of byRoot)
390
+ if (family.length > 1)
391
+ buckets.set(root, []);
392
+ if (buckets.size === 0)
393
+ return buckets;
394
+ for (const op of this.opTrace) {
395
+ const bucket = buckets.get(rootOf.get(op.path));
396
+ if (bucket)
397
+ bucket.push(op);
398
+ }
399
+ return buckets;
400
+ }
401
+ /**
402
+ * Replay ONE overlapping family's staged ops onto the family root's base
403
+ * value — the multi-path generalisation of {@link replayPathVerbs}, and
404
+ * byte-for-byte what `applySmartMerge` produces for the corresponding
405
+ * `'full'`-mode entries: each `set`/`delete` position writes that path's
406
+ * `overwritePatch` value, each `merge` position deep-merges that path's
407
+ * accumulated `updatePatch` delta into the value replayed so far.
408
+ *
409
+ * (Both patches are single coherent trees, so a full-mode bundle's stored
410
+ * value at any recorded path always reads back as its `overwritePatch` /
411
+ * `updatePatch` value — which is why sourcing from them here reproduces the
412
+ * full-mode replay exactly, including its intermediate-coercion quirks.)
413
+ *
414
+ * The value is held in a `{ v }` box so the root itself (relative path `[]`)
415
+ * can be REPLACED by `_set` the same way `applySmartMerge` replaces it
416
+ * inside the state tree — including `nativeSet`'s coercion of primitive
417
+ * intermediates.
418
+ */
419
+ replayFamilyVerbs(rootSegments, ops) {
420
+ const box = { v: structuredClone(_get(this.baseSnapshot, rootSegments)) };
421
+ for (const op of ops) {
422
+ const segments = op.path.split(DELIM);
423
+ const at = ['v', ...segments.slice(rootSegments.length)];
424
+ if (op.verb === 'merge') {
425
+ _set(box, at, deepSmartMerge(_get(box, at) ?? {}, structuredClone(_get(this.updatePatch, segments))));
426
+ }
427
+ else {
428
+ _set(box, at, structuredClone(_get(this.overwritePatch, segments)));
429
+ }
430
+ }
431
+ return box.v;
432
+ }
433
+ /**
434
+ * May a staged `delete` at this path commit as the `'delete'` verb?
435
+ *
436
+ * Only when removing the key and the `'full'` mode's flattening (`_set` of
437
+ * `undefined`) land in the same place. They diverge when the parent is not
438
+ * a container: `nativeDelete` walks away untouched, while `nativeSet`
439
+ * COERCES the primitive parent into an object to hold the key. Committing
440
+ * `delete` there would silently drop a state change the stage really made,
441
+ * so those (pathological) deletes keep the historical flattening.
442
+ */
443
+ deleteReplaysAsFlattening(segments) {
444
+ if (segments.length === 1)
445
+ return true; // parent is the state root — always a container
446
+ const parent = _get(this.baseSnapshot, segments.slice(0, -1));
447
+ return parent !== null && typeof parent === 'object';
448
+ }
295
449
  /**
296
450
  * Replay ONE path's op-verb sequence against its base value, exactly the
297
451
  * way `applySmartMerge` replays the corresponding full-mode bundle: every
@@ -323,6 +477,13 @@ export class TransactionBuffer {
323
477
  *
324
478
  * `before === undefined` (first write) fails `Array.isArray` → `set`, which
325
479
  * keeps the first write as the causal anchor for "who initialized this key".
480
+ *
481
+ * BOTH arrays must also be plain and dense ({@link isIndexOnly}): replay
482
+ * reconstructs an append as `[...current, ...tail]`, and that spread carries
483
+ * ONLY indexed elements — a named property parked on an array (a nested write
484
+ * like `set(['history','note'], …)`, which `nativeSet` happily hangs off the
485
+ * array object) or a hole would be silently dropped, where `'full'` mode
486
+ * stores the value whole and keeps it.
326
487
  */
327
488
  function isStrictArrayPrefix(before, after) {
328
489
  if (!Array.isArray(before) || !Array.isArray(after))
@@ -333,6 +494,13 @@ function isStrictArrayPrefix(before, after) {
333
494
  if (!deepEqual(before[i], after[i]))
334
495
  return false;
335
496
  }
336
- return true;
497
+ return isIndexOnly(before) && isIndexOnly(after);
498
+ }
499
+ /** True when an array's own enumerable keys are exactly its indices — no
500
+ * extra named properties and no holes, i.e. the array survives a spread
501
+ * intact. One `Object.keys` pass, same order as the prefix compare above
502
+ * and paid only after it succeeds. */
503
+ function isIndexOnly(arr) {
504
+ return Object.keys(arr).length === arr.length;
337
505
  }
338
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25CdWZmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS9UcmFuc2FjdGlvbkJ1ZmZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLFNBQVMsSUFBSSxJQUFJLEVBQUUsU0FBUyxJQUFJLElBQUksRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVwRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBUTdFLE1BQU0sT0FBTyxpQkFBaUI7SUFDWCxZQUFZLENBQU07SUFDM0IsV0FBVyxDQUFNO0lBRWpCLGNBQWMsR0FBZ0IsRUFBRSxDQUFDO0lBQ2pDLFdBQVcsR0FBZ0IsRUFBRSxDQUFDO0lBQzlCLE9BQU8sR0FBMEQsRUFBRSxDQUFDO0lBQ3BFLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQzFDLDBFQUEwRTtJQUN6RCxZQUFZLENBQW1CO0lBRWhEOzs7K0VBRzJFO0lBQzFELGdCQUFnQixDQUFrQjtJQUVuRCxZQUFZLElBQVMsRUFBRSxlQUFpQyxNQUFNLEVBQUUsZ0JBQWlDO1FBQy9GLElBQUksQ0FBQyxZQUFZLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzFDLElBQUksQ0FBQyxXQUFXLEdBQUcsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxZQUFZLEdBQUcsWUFBWSxDQUFDO1FBQ2pDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxnQkFBZ0IsQ0FBQztJQUMzQyxDQUFDO0lBRUQ7OzBEQUVzRDtJQUM5QyxhQUFhLENBQUMsRUFBdUQ7UUFDM0UsSUFBSSxJQUFJLENBQUMsZ0JBQWdCO1lBQUUsRUFBRSxDQUFDLFFBQVEsR0FBRyxJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUNq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QUNyRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUNwRCxJQUFJLEtBQUssR0FBWSxNQUFNLENBQUM7UUFDNUIsS0FBSyxNQUFNLElBQUksSUFBSSxLQUFLLEVBQUUsQ0FBQztZQUN6QixLQUFLLEdBQUcsSUFBSSxLQUFLLE9BQU8sQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLEtBQUssSUFBSSxFQUFFLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUNoRixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0NBQ0Y7QUFFRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxNQUFlLEVBQUUsS0FBYztJQUMxRCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDbEUsSUFBSSxLQUFLLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxNQUFNO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDaEQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztRQUN2QyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztJQUNwRCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBUcmFuc2FjdGlvbkJ1ZmZlciDigJQgUGVyLXN0YWdlIFNUQUdJTkcgYnVmZmVyIGZvciBzdGF0ZSBtdXRhdGlvbnNcbiAqXG4gKiBXaGF0IGl0IElTOiBhIHN0YWdpbmcgYnVmZmVyIHdpdGggcmVhZC15b3VyLXdyaXRlcyBhbmQgbmV0LWNoYW5nZSBjb21taXRzLlxuICogLSBDaGFuZ2VzIGFyZSBzdGFnZWQgaGVyZSBkdXJpbmcgc3RhZ2UgZXhlY3V0aW9uIGFuZCBmbHVzaGVkIHRvXG4gKiAgIFNoYXJlZE1lbW9yeSBpbiBPTkUgYmF0Y2ggcGVyIHN0YWdlIChgY29tbWl0KClgKSDigJQgb3RoZXIgc3RhZ2VzIGFuZFxuICogICBwYXJhbGxlbCBzaWJsaW5ncyBuZXZlciBvYnNlcnZlIGEgc3RhZ2UncyBoYWxmLWZpbmlzaGVkIHdyaXRlcy5cbiAqIC0gUmVhZC1hZnRlci13cml0ZSBjb25zaXN0ZW5jeSB3aXRoaW4gYSBzdGFnZSDigJQgYSBzdGFnZSBzZWVzIGl0cyBvd25cbiAqICAgc3RhZ2VkIHdyaXRlcyBpbW1lZGlhdGVseS5cbiAqIC0gYGNvbW1pdCgpYCByZWNvcmRzIHRoZSBzdGFnZSdzIE5FVCBjaGFuZ2UgKHNlZSB7QGxpbmsgY29tbWl0fSksIHBsdXMgYW5cbiAqICAgb3BlcmF0aW9uIHRyYWNlIGZvciBkZXRlcm1pbmlzdGljIHJlcGxheS5cbiAqXG4gKiBXaGF0IGl0IGlzIE5PVDogYSByb2xsYmFjayBtZWNoYW5pc20uIERlc3BpdGUgdGhlIG5hbWUsIHRoZXJlIGlzIG5vXG4gKiBhYm9ydC9yb2xsYmFjayBwYXRoIOKAlCB3aGVuIGEgc3RhZ2UgVEhST1dTLCB0aGUgZW5naW5lIHN0aWxsIGNvbW1pdHNcbiAqIGV2ZXJ5dGhpbmcgc3RhZ2VkIHNvIGZhciBiZWZvcmUgcmUtdGhyb3dpbmcgKGNvbW1pdC1vbi1lcnJvciBpblxuICogYEZsb3djaGFydFRyYXZlcnNlcmApLiBUaGF0IGlzIGRlbGliZXJhdGU6IHRoZSBhdWRpdCB0cmFpbCBtdXN0IHJlY29yZFxuICogd2hhdCB0aGUgZmFpbGluZyBzdGFnZSBjaGFuZ2VkLiBEbyBub3QgcmVseSBvbiBcInN0YWdlIGZhaWxlZCDihpIgaXRzXG4gKiB3cml0ZXMgdmFuaXNoZWRcIi5cbiAqL1xuXG5pbXBvcnQgeyBuYXRpdmVHZXQgYXMgX2dldCwgbmF0aXZlU2V0IGFzIF9zZXQgfSBmcm9tICcuL3BhdGhPcHMuanMnO1xuaW1wb3J0IHR5cGUgeyBDb21taXRWYWx1ZXNNb2RlLCBNZW1vcnlQYXRjaCwgVHJhY2VFbnRyeSB9IGZyb20gJy4vdHlwZXMuanMnO1xuaW1wb3J0IHsgZGVlcEVxdWFsLCBkZWVwU21hcnRNZXJnZSwgREVMSU0sIG5vcm1hbGlzZVBhdGggfSBmcm9tICcuL3V0aWxzLmpzJztcblxuLyoqIE9wLWxldmVsIHZlcmJzIHN0YWdlZCBpbnRvIGBvcFRyYWNlYC4gYCdkZWxldGUnYCBpcyBzdGFnZWQgZGlzdGluY3RseSBzb1xuICogIGRlbHRhLW1vZGUgY29tbWl0cyAoIzEzYy1CKSBjYW4gZW1pdCBhIHJlYWwgYGRlbGV0ZWAgdHJhY2UgZW50cnk7IHVuZGVyXG4gKiAgdGhlIGRlZmF1bHQgYCdmdWxsJ2AgbW9kZSBpdCBjb21taXRzIGFzIGAnc2V0J2AgKG9mIGB1bmRlZmluZWRgKSDigJRcbiAqICBieXRlLWlkZW50aWNhbCB0byB0aGUgaGlzdG9yaWNhbCBmbGF0dGVuaW5nLiAqL1xudHlwZSBPcFZlcmIgPSAnc2V0JyB8ICdtZXJnZScgfCAnZGVsZXRlJztcblxuZXhwb3J0IGNsYXNzIFRyYW5zYWN0aW9uQnVmZmVyIHtcbiAgcHJpdmF0ZSByZWFkb25seSBiYXNlU25hcHNob3Q6IGFueTtcbiAgcHJpdmF0ZSB3b3JraW5nQ29weTogYW55O1xuXG4gIHByaXZhdGUgb3ZlcndyaXRlUGF0Y2g6IE1lbW9yeVBhdGNoID0ge307XG4gIHByaXZhdGUgdXBkYXRlUGF0Y2g6IE1lbW9yeVBhdGNoID0ge307XG4gIHByaXZhdGUgb3BUcmFjZTogeyBwYXRoOiBzdHJpbmc7IHZlcmI6IE9wVmVyYjsgcmVhZEtleXM/OiBzdHJpbmdbXSB9W10gPSBbXTtcbiAgcHJpdmF0ZSByZWRhY3RlZFBhdGhzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIC8qKiBDb21taXQtdmFsdWUgZW5jb2RpbmcgcG9saWN5ICgjMTNjLUIpLiBgJ2Z1bGwnYCA9IGhpc3RvcmljYWwgYnl0ZXMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgY29tbWl0VmFsdWVzOiBDb21taXRWYWx1ZXNNb2RlO1xuXG4gIC8qKiBQZXItd3JpdGUgcmVhZC1wcm92ZW5hbmNlIHNvdXJjZSAoI1AxKS4gV2hlbiBzZXQgKHRoZVxuICAgKiAgYHdyaXRlUHJvdmVuYW5jZTogJ3JlYWRzLXByZWZpeCdgIGRpYWwpLCBldmVyeSBzdGFnZWQgb3Agc25hcHNob3RzIHRoZVxuICAgKiAga2V5cyB0cmFja2VkLXJlYWQgc28gZmFyIOKAlCB0aGUgdGVtcG9yYWwtcHJlZml4IGF0dHJpYnV0aW9uIGNvbnN1bWVkIGJ5XG4gICAqICBjYXVzYWwgc2xpY2luZy4gVW5kZWZpbmVkIChkZWZhdWx0KSA9IHplcm8gY29zdCwgYnl0ZS1pZGVudGljYWwgb3BzLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHJlYWRLZXlzUHJvdmlkZXI/OiAoKSA9PiBzdHJpbmdbXTtcblxuICBjb25zdHJ1Y3RvcihiYXNlOiBhbnksIGNvbW1pdFZhbHVlczogQ29tbWl0VmFsdWVzTW9kZSA9ICdmdWxsJywgcmVhZEtleXNQcm92aWRlcj86ICgpID0+IHN0cmluZ1tdKSB7XG4gICAgdGhpcy5iYXNlU25hcHNob3QgPSBzdHJ1Y3R1cmVkQ2xvbmUoYmFzZSk7XG4gICAgdGhpcy53b3JraW5nQ29weSA9IHN0cnVjdHVyZWRDbG9uZShiYXNlKTtcbiAgICB0aGlzLmNvbW1pdFZhbHVlcyA9IGNvbW1pdFZhbHVlcztcbiAgICB0aGlzLnJlYWRLZXlzUHJvdmlkZXIgPSByZWFkS2V5c1Byb3ZpZGVyO1xuICB9XG5cbiAgLyoqIFN0YW1wIHRoZSBjdXJyZW50IHJlYWQgcHJlZml4IG9udG8gYSBzdGFnZWQgb3Ag4oCUIG9ubHkgd2hlbiB0aGVcbiAgICogIHByb3ZlbmFuY2UgZGlhbCBpcyBvbiAocHJvdmlkZXIgcHJlc2VudCksIHNvIHRoZSBkZWZhdWx0IHBhdGggYWxsb2NhdGVzXG4gICAqICBub3RoaW5nIGFuZCBjb21taXQgYnVuZGxlcyBzdGF5IGJ5dGUtaWRlbnRpY2FsLiAqL1xuICBwcml2YXRlIHN0YW1wUmVhZEtleXMob3A6IHsgcGF0aDogc3RyaW5nOyB2ZXJiOiBPcFZlcmI7IHJlYWRLZXlzPzogc3RyaW5nW10gfSk6IHR5cGVvZiBvcCB7XG4gICAgaWYgKHRoaXMucmVhZEtleXNQcm92aWRlcikgb3AucmVhZEtleXMgPSB0aGlzLnJlYWRLZXlzUHJvdmlkZXIoKTtcbiAgICByZXR1cm4gb3A7XG4gIH1cblxuICAvKiogSGFyZCBvdmVyd3JpdGUgYXQgdGhlIHNwZWNpZmllZCBwYXRoLiAqL1xuICBzZXQocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgdmFsdWU6IGFueSwgc2hvdWxkUmVkYWN0ID0gZmFsc2UpOiB2b2lkIHtcbiAgICBfc2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIHZhbHVlKTtcbiAgICBfc2V0KHRoaXMub3ZlcndyaXRlUGF0Y2gsIHBhdGgsIHN0cnVjdHVyZWRDbG9uZSh2YWx1ZSkpO1xuICAgIGlmIChzaG91bGRSZWRhY3QpIHtcbiAgICAgIHRoaXMucmVkYWN0ZWRQYXRocy5hZGQobm9ybWFsaXNlUGF0aChwYXRoKSk7XG4gICAgfVxuICAgIHRoaXMub3BUcmFjZS5wdXNoKHRoaXMuc3RhbXBSZWFkS2V5cyh7IHBhdGg6IG5vcm1hbGlzZVBhdGgocGF0aCksIHZlcmI6ICdzZXQnIH0pKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFeHBsaWNpdCBrZXkgZGVsZXRpb24gYXQgdGhlIHNwZWNpZmllZCBwYXRoICgjMTNjLUI7IGFic29yYnMgYmFja2xvZyBCOCkuXG4gICAqXG4gICAqIFN0YWdlcyBFWEFDVExZIHRoZSBzYW1lIGJ1ZmZlciBtdXRhdGlvbnMgYXMgYHNldChwYXRoLCB1bmRlZmluZWQpYCDigJRcbiAgICogYHdvcmtpbmdDb3B5YC9gb3ZlcndyaXRlUGF0Y2hgIGdldCBhbiBvd24gYHVuZGVmaW5lZGAgYXQgdGhlIHBhdGggKHRoZVxuICAgKiBoaXN0b3JpY2FsIGZsYXR0ZW5pbmcsIHByZXNlcnZpbmcgcmVhZCBiZWhhdmlvciBhbmQgdGhlIGRlZHVwIGRpZmYgYmFzZVxuICAgKiBhY3Jvc3MgbW9kZXMpIOKAlCBidXQgcmVjb3JkcyB0aGUgb3AgdmVyYiBhcyBgJ2RlbGV0ZSdgLiBBdCBjb21taXQ6XG4gICAqIGAnZnVsbCdgIG1vZGUgbWFwcyBpdCBiYWNrIHRvIGEgYCdzZXQnYCB0cmFjZSBlbnRyeSAoYnl0ZS1pZGVudGljYWwgdG9cbiAgICogdG9kYXkpOyBgJ2RlbHRhJ2AgbW9kZSBlbWl0cyBhIHJlYWwgYCdkZWxldGUnYCBlbnRyeSB3aG9zZSByZXBsYXlcbiAgICogUkVNT1ZFUyB0aGUga2V5IGluc3RlYWQgb2YgbGVhdmluZyBga2V5OiB1bmRlZmluZWRgIGJlaGluZC5cbiAgICovXG4gIGRlbGV0ZShwYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdLCBzaG91bGRSZWRhY3QgPSBmYWxzZSk6IHZvaWQge1xuICAgIF9zZXQodGhpcy53b3JraW5nQ29weSwgcGF0aCwgdW5kZWZpbmVkKTtcbiAgICBfc2V0KHRoaXMub3ZlcndyaXRlUGF0Y2gsIHBhdGgsIHVuZGVmaW5lZCk7XG4gICAgaWYgKHNob3VsZFJlZGFjdCkge1xuICAgICAgdGhpcy5yZWRhY3RlZFBhdGhzLmFkZChub3JtYWxpc2VQYXRoKHBhdGgpKTtcbiAgICB9XG4gICAgdGhpcy5vcFRyYWNlLnB1c2godGhpcy5zdGFtcFJlYWRLZXlzKHsgcGF0aDogbm9ybWFsaXNlUGF0aChwYXRoKSwgdmVyYjogJ2RlbGV0ZScgfSkpO1xuICB9XG5cbiAgLyoqIERlZXAgdW5pb24gbWVyZ2UgYXQgdGhlIHNwZWNpZmllZCBwYXRoLiAqL1xuICBtZXJnZShwYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdLCB2YWx1ZTogYW55LCBzaG91bGRSZWRhY3QgPSBmYWxzZSk6IHZvaWQge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gX2dldCh0aGlzLndvcmtpbmdDb3B5LCBwYXRoKSA/PyB7fTtcbiAgICBjb25zdCBtZXJnZWQgPSBkZWVwU21hcnRNZXJnZShleGlzdGluZywgdmFsdWUpO1xuICAgIF9zZXQodGhpcy53b3JraW5nQ29weSwgcGF0aCwgbWVyZ2VkKTtcbiAgICBfc2V0KHRoaXMudXBkYXRlUGF0Y2gsIHBhdGgsIGRlZXBTbWFydE1lcmdlKF9nZXQodGhpcy51cGRhdGVQYXRjaCwgcGF0aCkgPz8ge30sIHZhbHVlKSk7XG4gICAgaWYgKHNob3VsZFJlZGFjdCkge1xuICAgICAgdGhpcy5yZWRhY3RlZFBhdGhzLmFkZChub3JtYWxpc2VQYXRoKHBhdGgpKTtcbiAgICB9XG4gICAgdGhpcy5vcFRyYWNlLnB1c2godGhpcy5zdGFtcFJlYWRLZXlzKHsgcGF0aDogbm9ybWFsaXNlUGF0aChwYXRoKSwgdmVyYjogJ21lcmdlJyB9KSk7XG4gIH1cblxuICAvKiogUmVhZCBjdXJyZW50IHZhbHVlIGF0IHBhdGggKGluY2x1ZGVzIHVuY29tbWl0dGVkIGNoYW5nZXMpLiAqL1xuICBnZXQocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgZGVmYXVsdFZhbHVlPzogYW55KSB7XG4gICAgcmV0dXJuIF9nZXQodGhpcy53b3JraW5nQ29weSwgcGF0aCwgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbHVzaCBhbGwgc3RhZ2VkIG11dGF0aW9ucyBhbmQgcmV0dXJuIHRoZSBjb21taXQgYnVuZGxlIOKAlCByZWNvcmRpbmcgdGhlXG4gICAqIHN0YWdlJ3MgTkVUIENIQU5HRSwgbm90IGl0cyByYXcgd3JpdGUgbG9nLlxuICAgKlxuICAgKiDilIDilIAgV0hZICh0aGUgZGVmZWN0IHRoaXMgZml4ZXMpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgKiBQcmV2aW91c2x5IGV2ZXJ5IGBzZXRgL2BtZXJnZWAgd2FzIHJlY29yZGVkIHZlcmJhdGltLCBzbyB0aGUgY29tbWl0IGJ1bmRsZVxuICAgKiB3YXMgYSBsb2cgb2YgKm9wZXJhdGlvbnMqIHJhdGhlciB0aGFuICpjaGFuZ2VzKi4gVHdvIG9wZXJhdGlvbnMgcHJvZHVjZSBub1xuICAgKiBuZXQgY2hhbmdlIHlldCB3ZXJlIHN0aWxsIGNvbW1pdHRlZCBhcyBcIm11dGF0aW9uc1wiOlxuICAgKlxuICAgKiAgIDEuIE5vLW9wIHdyaXRlICAg4oCUIHdyaXRpbmcgYSBrZXkgdGhlIHZhbHVlIGl0IGFscmVhZHkgaG9sZHMgKGUuZy4gYW5cbiAgICogICAgICAgICAgICAgICAgICAgICAgYWdlbnQgY29udGV4dCBzbG90IHJlLWVtaXR0aW5nIGlkZW50aWNhbCBjb250ZW50IGV2ZXJ5XG4gICAqICAgICAgICAgICAgICAgICAgICAgIHR1cm4pLiBiYXNlIEs9MSwgc3RhZ2Ugd3JpdGVzIEs9MS5cbiAgICogICAyLiBXcml0ZS1yZXZlcnQgIOKAlCBjaGFuZ2luZyB0aGVuIHJlc3RvcmluZyBhIGtleSB3aXRoaW4gb25lIHN0YWdlLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICBiYXNlIEs9MSwgc3RhZ2Ugd3JpdGVzIEs9MiB0aGVuIEs9MS5cbiAgICpcbiAgICogUmVjb3JkaW5nIHRoZXNlIGFzIG11dGF0aW9ucyAoYSkgYmxvYXRlZCBjYXVzYWwgc2xpY2luZyAvIGJhY2t0cmFja2luZyB3aXRoXG4gICAqIHNwdXJpb3VzIGRlcGVuZGVuY2llcyBvbiBpbnRlcm1lZGlhdGUgdmFsdWVzIHRoYXQgbmV2ZXIgcmVhY2ggZmluYWwgc3RhdGUsXG4gICAqIGFuZCAoYikgbWFkZSBkb3duc3RyZWFtIFwid2hhdCBjaGFuZ2VkIGhlcmU/XCIgY29uc3VtZXJzIGxpZ2h0IHVwIHN0YWdlcyB0aGF0XG4gICAqIGNoYW5nZWQgbm90aGluZyDigJQgbW9zdCB2aXNpYmx5IHRoZSBsZW5zIGhpZ2hsaWdodCBmbGFnZ2luZyBldmVyeSBzbG90LlxuICAgKlxuICAgKiDilIDilIAgSE9XIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgKiBBdCBjb21taXQgd2UgaG9sZCBCT1RIIGBiYXNlU25hcHNob3RgIChzdGF0ZSB3aGVuIHRoZSBzdGFnZSBiZWdhbikgYW5kXG4gICAqIGB3b3JraW5nQ29weWAgKHN0YXRlIGFmdGVyIGFsbCBpdHMgd3JpdGVzKS4gRm9yIGVhY2ggcGF0aCB0aGUgc3RhZ2UgdG91Y2hlZFxuICAgKiB3ZSBrZWVwIGl0IGluIHRoZSBidW5kbGUgT05MWSBpZiBpdHMgZmluYWwgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBiYXNlXG4gICAqIHZhbHVlICh7QGxpbmsgZGVlcEVxdWFsfSkuIE5vLW9wIEFORCB3cml0ZS1yZXZlcnQgcGF0aHMgZHJvcCBvdXQsIGJlY2F1c2VcbiAgICogYm90aCBjb21wYXJlIGVxdWFsIHRvIGJhc2UuIFRoaXMgaXMgYSBzaW5nbGUgbmV0LWRlbHRhIGRpZmYgYXQgY29tbWl0IHRpbWVcbiAgICog4oCUIG9uZSBkZWVwIGNvbXBhcmUgcGVyIHRvdWNoZWQgcGF0aCwgTyhjaGFuZ2VkIHN0YXRlKSwgcGFpZCBvbmNlIHBlciBzdGFnZVxuICAgKiAoTk9UIHBlciB3cml0ZSkuIEEgbmFpdmUgcGVyLXdyaXRlIGRlZXAtZXF1YWwgc2tpcCB3b3VsZCBiZSBtb3JlIGV4cGVuc2l2ZVxuICAgKiBhbmQgd291bGQgc3RpbGwgbWlzcyB3cml0ZS1yZXZlcnQgKHRoZSBpbnRlcm1lZGlhdGUgd3JpdGUgZGlmZmVycyBmcm9tIHRoZVxuICAgKiB2YWx1ZSBwcmVzZW50IGF0IHRoZSBtb21lbnQgb2Ygd3JpdGluZykuXG4gICAqXG4gICAqIOKUgOKUgCBUV08gSE9ORVNUIFRJRVJTIChieSBkZXNpZ24g4oCUIGRvIG5vdCBcInVuaWZ5XCIgdGhlbSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAqICAg4oCiIGNvbW1pdCAoaGVyZSkgICA9IENIQU5HRS1sZXZlbCDigJQgdHJ1dGhmdWwgbmV0IGRlbHRhLiBGZWVkcyB0aGUgY29tbWl0XG4gICAqICAgICAgICAgICAgICAgICAgICAgICBsb2csIGNhdXNhbCBjaGFpbiwgbmFycmF0aXZlLCBhbmQgdGhlIGxlbnMgaGlnaGxpZ2h0LlxuICAgKiAgIOKAoiBgb25Xcml0ZWAgZXZlbnQgPSBPUC1sZXZlbCDigJQgZmlyZXMgb24gRVZFUlkgd3JpdGUgYXR0ZW1wdCByZWdhcmRsZXNzIG9mXG4gICAqICAgICAgICAgICAgICAgICAgICAgICBuZXQgY2hhbmdlLiBGZWVkcyBtZXRyaWNzIC8gYmVoYXZpb3VyYWwgb2JzZXJ2YWJpbGl0eVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgKGEgZGVidWdnZXIgd2FudHMgdG8gc2VlIFwid3JvdGUgMiwgdGhlbiByZXZlcnRlZFwiKS5cbiAgICogYG9uV3JpdGVgIGlzIHVuY2hhbmdlZCBieSB0aGlzIG1ldGhvZDsgb25seSB0aGUgQ09NTUlUIGJlY29tZXMgY2hhbmdlLW9ubHkuXG4gICAqXG4gICAqIOKUgOKUgCBFTVBUWSBDT01NSVRTIEFSRSBJTlRFTlRJT05BTCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogQSBzdGFnZSB0aGF0IG5ldHMgbm8gY2hhbmdlIGNvbW1pdHMgYW4gRU1QVFkgcGF0Y2gg4oCUIE5PVCBub3RoaW5nLlxuICAgKiB7QGxpbmsgU3RhZ2VDb250ZXh0LmNvbW1pdH0gc3RpbGwgcmVjb3JkcyB0aGUgYnVuZGxlIHVuY29uZGl0aW9uYWxseSwgc29cbiAgICogZXZlcnkgZXhlY3V0ZWQgc3RhZ2UgcmVtYWlucyBhIHRpbWUtdHJhdmVsIGN1cnNvciBzdG9wIChpdHMgYHJ1bnRpbWVTdGFnZUlkYFxuICAgKiBtYXJrZXIgaXMgcHJlc2VydmVkKTsgb25seSBpdHMgUEFUQ0ggaXMgZW1wdHkuIFRoaXMgaXMgd2hhdCBrZWVwcyB0aGVcbiAgICogY29tbWl0LWluZGV4ZWQgc2xpZGVyIHN0YWJsZSB3aGlsZSBtYWtpbmcgdGhlIGhpZ2hsaWdodCB0cnV0aGZ1bC5cbiAgICpcbiAgICog4pSA4pSAIEtOT1dOIExJTUlUQVRJT05TIC8gRlVUVVJFIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgKiAgIOKAoiBFeHBsaWNpdCBrZXkgREVMRVRJT04gdW5kZXIgdGhlIGRlZmF1bHQgJ2Z1bGwnIG1vZGUgaXMgc3RpbGxcbiAgICogICAgIGZsYXR0ZW5lZCB0byBzZXQtb2YtYHVuZGVmaW5lZGAgKGEgcmVtb3ZlZCBrZXkgY2Fubm90IGJlIGV4cHJlc3NlZFxuICAgKiAgICAgaW4gTWVtb3J5UGF0Y2ggYWxvbmUpLiBDTE9TRUQgdW5kZXIgYGNvbW1pdFZhbHVlczogJ2RlbHRhJ2AgKCMxM2MtQik6XG4gICAqICAgICB7QGxpbmsgZGVsZXRlfSBzdGFnZXMgYSBkaXN0aW5jdCBvcCBhbmQgdGhlIGJ1bmRsZSBjYXJyaWVzIGEgcmVhbFxuICAgKiAgICAgYGRlbGV0ZWAgdHJhY2UgdmVyYiB3aG9zZSByZXBsYXkgcmVtb3ZlcyB0aGUga2V5LlxuICAgKiAgIOKAoiBBcnJheS1tZXJnZSBkZWR1cCBpbiB7QGxpbmsgZGVlcFNtYXJ0TWVyZ2V9IHN0aWxsIHVzZXMgcmVmZXJlbmNlIGVxdWFsaXR5XG4gICAqICAgICAoYG5ldyBTZXRgKSwgc28gZGVlcC1lcXVhbCAqb2JqZWN0cyogaW4gYSBtZXJnZWQgYXJyYXkgYXJlIG5vdCBkZWR1cGVkLlxuICAgKiAgICAgT3J0aG9nb25hbCB0byB0aGlzIGNoYW5nZTsgdHJhY2tlZCBzZXBhcmF0ZWx5LlxuICAgKlxuICAgKiBSZXNldHMgdGhlIGJ1ZmZlciB0byBlbXB0eSBzdGF0ZSBhZnRlciBjb21taXQuXG4gICAqL1xuICBjb21taXQoKToge1xuICAgIG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2g7XG4gICAgdXBkYXRlczogTWVtb3J5UGF0Y2g7XG4gICAgcmVkYWN0ZWRQYXRoczogU2V0PHN0cmluZz47XG4gICAgdHJhY2U6IFRyYWNlRW50cnlbXTtcbiAgfSB7XG4gICAgY29uc3QgcGF5bG9hZCA9IHRoaXMuY29tbWl0VmFsdWVzID09PSAnZGVsdGEnID8gdGhpcy50b0RlbHRhUGF5bG9hZCgpIDogdGhpcy50b0NoYW5nZU9ubHlQYXlsb2FkKCk7XG5cbiAgICB0aGlzLm92ZXJ3cml0ZVBhdGNoID0ge307XG4gICAgdGhpcy51cGRhdGVQYXRjaCA9IHt9O1xuICAgIHRoaXMub3BUcmFjZS5sZW5ndGggPSAwO1xuICAgIHRoaXMucmVkYWN0ZWRQYXRocy5jbGVhcigpO1xuICAgIHRoaXMud29ya2luZ0NvcHkgPSB7fTtcblxuICAgIHJldHVybiBwYXlsb2FkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYnVpbGQgb3ZlcndyaXRlIC8gdXBkYXRlcyAvIHRyYWNlIGtlZXBpbmcgT05MWSBwYXRocyB3aG9zZSBmaW5hbCB2YWx1ZVxuICAgKiBkaWZmZXJzIGZyb20gdGhlIGJhc2UgdmFsdWUg4oCUIGkuZS4gdGhlIHN0YWdlJ3MgbmV0IGNoYW5nZS4gU2VlXG4gICAqIHtAbGluayBUcmFuc2FjdGlvbkJ1ZmZlci5jb21taXR9IGZvciB0aGUgcmF0aW9uYWxlLlxuICAgKlxuICAgKiBQYXRocyBhcmUgY29tcGFyZWQgYXQgdGhlIGV4YWN0IGdyYW51bGFyaXR5IHRoZXkgd2VyZSB3cml0dGVuIChlYWNoIHRyYWNlXG4gICAqIGVudHJ5J3MgcGF0aCksIGFnYWluc3QgYHdvcmtpbmdDb3B5YCAoZmluYWwpIHZzIGBiYXNlU25hcHNob3RgIChzdGFydCkuXG4gICAqIFN1cnZpdmluZyBgc2V0YCBwYXRocyBjb3B5IHRoZWlyIGZpbmFsIHZhbHVlIGZyb20gYG92ZXJ3cml0ZVBhdGNoYDtcbiAgICogc3Vydml2aW5nIGBtZXJnZWAgcGF0aHMgY29weSB0aGVpciBhY2N1bXVsYXRlZCBkZWx0YSBmcm9tIGB1cGRhdGVQYXRjaGAg4oCUXG4gICAqIHByZXNlcnZpbmcgdGhlIHNldC12cy1tZXJnZSB2ZXJiIHNvIHJlcGxheSAoe0BsaW5rIGFwcGx5U21hcnRNZXJnZX0pIGlzXG4gICAqIGJ5dGUtZm9yLWJ5dGUgaWRlbnRpY2FsIHRvIHJlY29yZGluZyBvbmx5IHRoZSByZWFsIGNoYW5nZXMuXG4gICAqXG4gICAqIFRoaXMgaXMgdGhlIERFRkFVTFQgKGBjb21taXRWYWx1ZXM6ICdmdWxsJ2ApIHBheWxvYWQg4oCUIGJ5dGUtaWRlbnRpY2FsIHRvXG4gICAqIHRoZSBoaXN0b3JpY2FsIGJlaGF2aW9yLCBpbmNsdWRpbmcgZmxhdHRlbmluZyBzdGFnZWQgYGRlbGV0ZWAgb3BzIGludG9cbiAgICogYHNldGAtb2YtYHVuZGVmaW5lZGAgdHJhY2UgZW50cmllcy4gVGhlIGRlbHRhIGVuY29kaW5nIGxpdmVzIGluXG4gICAqIHtAbGluayB0b0RlbHRhUGF5bG9hZH0uXG4gICAqL1xuICBwcml2YXRlIHRvQ2hhbmdlT25seVBheWxvYWQoKToge1xuICAgIG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2g7XG4gICAgdXBkYXRlczogTWVtb3J5UGF0Y2g7XG4gICAgcmVkYWN0ZWRQYXRoczogU2V0PHN0cmluZz47XG4gICAgdHJhY2U6IFRyYWNlRW50cnlbXTtcbiAgfSB7XG4gICAgY29uc3Qgb3ZlcndyaXRlOiBNZW1vcnlQYXRjaCA9IHt9O1xuICAgIGNvbnN0IHVwZGF0ZXM6IE1lbW9yeVBhdGNoID0ge307XG4gICAgY29uc3QgdHJhY2U6IFRyYWNlRW50cnlbXSA9IFtdO1xuICAgIGNvbnN0IHN1cnZpdmluZ1BhdGhzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IG9wIG9mIHRoaXMub3BUcmFjZSkge1xuICAgICAgY29uc3Qgc2VnbWVudHMgPSBvcC5wYXRoLnNwbGl0KERFTElNKTtcbiAgICAgIGNvbnN0IGJlZm9yZSA9IF9nZXQodGhpcy5iYXNlU25hcHNob3QsIHNlZ21lbnRzKTtcbiAgICAgIGNvbnN0IGFmdGVyID0gX2dldCh0aGlzLndvcmtpbmdDb3B5LCBzZWdtZW50cyk7XG4gICAgICBpZiAoZGVlcEVxdWFsKGJlZm9yZSwgYWZ0ZXIpKSBjb250aW51ZTsgLy8gbm8tb3Agb3Igd3JpdGUtdGhlbi1yZXZlcnQg4oaSIG5vIG5ldCBjaGFuZ2VcblxuICAgICAgLy8gSGlzdG9yaWNhbCBmbGF0dGVuaW5nOiBhbiBleHBsaWNpdCBkZWxldGUgY29tbWl0cyBhcyBzZXQtb2YtdW5kZWZpbmVkLlxuICAgICAgLy8gUGVyLXdyaXRlIHByb3ZlbmFuY2UgKCNQMSkgcmlkZXMgZWFjaCBzdXJ2aXZpbmcgZW50cnkgdW50b3VjaGVkLlxuICAgICAgdHJhY2UucHVzaChcbiAgICAgICAgb3AudmVyYiA9PT0gJ2RlbGV0ZSdcbiAgICAgICAgICA/IHsgcGF0aDogb3AucGF0aCwgdmVyYjogJ3NldCcgYXMgY29uc3QsIC4uLihvcC5yZWFkS2V5cyAhPT0gdW5kZWZpbmVkICYmIHsgcmVhZEtleXM6IG9wLnJlYWRLZXlzIH0pIH1cbiAgICAgICAgICA6IG9wLFxuICAgICAgKTtcbiAgICAgIHN1cnZpdmluZ1BhdGhzLmFkZChvcC5wYXRoKTtcbiAgICAgIGlmIChvcC52ZXJiID09PSAnbWVyZ2UnKSB7XG4gICAgICAgIF9zZXQodXBkYXRlcywgc2VnbWVudHMsIHN0cnVjdHVyZWRDbG9uZShfZ2V0KHRoaXMudXBkYXRlUGF0Y2gsIHNlZ21lbnRzKSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX3NldChvdmVyd3JpdGUsIHNlZ21lbnRzLCBzdHJ1Y3R1cmVkQ2xvbmUoX2dldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBzZWdtZW50cykpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZWRhY3RlZFBhdGhzID0gbmV3IFNldChbLi4udGhpcy5yZWRhY3RlZFBhdGhzXS5maWx0ZXIoKHBhdGgpID0+IHN1cnZpdmluZ1BhdGhzLmhhcyhwYXRoKSkpO1xuICAgIHJldHVybiB7IG92ZXJ3cml0ZSwgdXBkYXRlcywgcmVkYWN0ZWRQYXRocywgdHJhY2UgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWx0YS1lbmNvZGVkIHBheWxvYWQgKGBjb21taXRWYWx1ZXM6ICdkZWx0YSdgLCAjMTNjLUIpIOKAlCBzYW1lIG5ldC1jaGFuZ2VcbiAgICogZmlsdGVyIGFzIHtAbGluayB0b0NoYW5nZU9ubHlQYXlsb2FkfSwgdHdvIGVuY29kaW5nIGRpZmZlcmVuY2VzOlxuICAgKlxuICAgKiAxLiAqKk9uZSB0cmFjZSBlbnRyeSBwZXIgc3Vydml2aW5nIHBhdGgqKiAodGhlIMKnMi41IGRlZHVwIHJ1bGUg4oCUIGBhcHBlbmRgXG4gICAqICAgIGlzIE5PVCBpZGVtcG90ZW50IG9uIHJlcGxheSwgc28gZHVwbGljYXRlIGVudHJpZXMgd291bGQgbXVsdGlwbHlcbiAgICogICAgdGFpbHMpLiBUaGUgdmVyYiBpcyByZXNvbHZlZCBmcm9tIHRoZSBwYXRoJ3Mgb3AgbWl4ICsgYmFzZeKGkmZpbmFsXG4gICAqICAgIHJlbGF0aW9uc2hpcDsgZW50cmllcyBhcmUgb3JkZXJlZCBieSBlYWNoIHBhdGgncyBMQVNUIHRvdWNoLFxuICAgKiAgICBwcmVzZXJ2aW5nIGxhc3Qtd3JpdGVyLXdpbnMgZm9yIG5lc3RlZC9vdmVybGFwcGluZyBwYXRocy5cbiAgICogMi4gKipWZXJiIHJlc29sdXRpb24gcGVyIHBhdGgqKjpcbiAgICogICAgLSBsYXN0IG9wIGAnZGVsZXRlJ2AgQU5EIGZpbmFsIHZhbHVlIGdvbmUg4oaSIGBkZWxldGVgICh0aGUgcGF0aCBzdGF5c1xuICAgKiAgICAgIGVudW1lcmF0ZWQgaW4gYG92ZXJ3cml0ZWAgd2l0aCBgdW5kZWZpbmVkYCBmb3Iga2V5LXNldCBjb25zdW1lcnMpO1xuICAgKiAgICAtIE9OTFkgYCdtZXJnZSdgIG9wcyDihpIgYG1lcmdlYCB3aXRoIHRoZSBhY2N1bXVsYXRlZCBgdXBkYXRlUGF0Y2hgXG4gICAqICAgICAgZGVsdGEgKHJlcGxheWluZyB0aGUgYWNjdW11bGF0ZWQgZGVsdGEgb25jZSDiiaEgdGhlIGZ1bGwgbW9kZSdzXG4gICAqICAgICAgayBzZXF1ZW50aWFsIHJlcGxheXMg4oCUIGBkZWVwU21hcnRNZXJnZWAgaXMgcmVmZXJlbmNlLWlkZW1wb3RlbnRcbiAgICogICAgICB3aXRoaW4gb25lIHJlcGxheSBwYXNzKTtcbiAgICogICAgLSBvdGhlcndpc2UgKGBzZXRgL21peGVkKTogdGhlIGNvbW1pdHRlZCB2YWx1ZSBpcyBjb21wdXRlZCBieVxuICAgKiAgICAgIHJlcGxheWluZyB0aGUgcGF0aCdzIG9wIHNlcXVlbmNlIEVYQUNUTFkgdGhlIHdheSBgYXBwbHlTbWFydE1lcmdlYFxuICAgKiAgICAgIHJlcGxheXMgdGhlIGZ1bGwtbW9kZSBidW5kbGUgKHtAbGluayByZXBsYXlQYXRoVmVyYnN9KSDigJQgZm9yXG4gICAqICAgICAgcHVyZS1zZXQgcGF0aHMgdGhhdCBpcyBzaW1wbHkgdGhlIGxhc3Qgc2V0IHZhbHVlOyBmb3IgbWl4ZWRcbiAgICogICAgICBzZXQrbWVyZ2UgaW50ZXJsZWF2aW5ncyBpdCByZXByb2R1Y2VzIHRoZSBmdWxsIG1vZGUncyBxdWlyayBvZlxuICAgKiAgICAgIGFwcGx5aW5nIHRoZSBBQ0NVTVVMQVRFRCBtZXJnZSBkZWx0YSBhdCBldmVyeSBtZXJnZSBwb3NpdGlvblxuICAgKiAgICAgICh3aGljaCBjYW4gZGlmZmVyIGZyb20gdGhlIGJ1ZmZlcidzIHJlYWQteW91ci13cml0ZXMgdmlldzsgcGFyaXR5XG4gICAqICAgICAgd2l0aCB0aGUgYCdmdWxsJ2AgbW9kZSdzIGNvbW1pdHRlZCBzdGF0ZSBpcyB0aGUgY29udHJhY3QpLiBJZiBiYXNlXG4gICAqICAgICAgYW5kIHRoYXQgdmFsdWUgYXJlIGFycmF5cyBhbmQgYmFzZSBpcyBhIFNUUklDVCBQUkVGSVgg4oaSIGBhcHBlbmRgXG4gICAqICAgICAgc3RvcmluZyBvbmx5IHRoZSB0YWlsOyBlbHNlIGBzZXRgIHN0b3JpbmcgdGhlIGZ1bGwgdmFsdWUuXG4gICAqXG4gICAqIExvc3NsZXNzbmVzcyBuZXZlciBkZXBlbmRzIG9uIGRldGVjdGlvbiBzdWNjZWVkaW5nIOKAlCBldmVyeSBmYWxsYmFjayBpc1xuICAgKiB0b2RheSdzIGZ1bGwtdmFsdWUgYHNldGAuXG4gICAqL1xuICBwcml2YXRlIHRvRGVsdGFQYXlsb2FkKCk6IHtcbiAgICBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoO1xuICAgIHVwZGF0ZXM6IE1lbW9yeVBhdGNoO1xuICAgIHJlZGFjdGVkUGF0aHM6IFNldDxzdHJpbmc+O1xuICAgIHRyYWNlOiBUcmFjZUVudHJ5W107XG4gIH0ge1xuICAgIGNvbnN0IG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2ggPSB7fTtcbiAgICBjb25zdCB1cGRhdGVzOiBNZW1vcnlQYXRjaCA9IHt9O1xuICAgIGNvbnN0IHRyYWNlOiBUcmFjZUVudHJ5W10gPSBbXTtcbiAgICBjb25zdCBzdXJ2aXZpbmdQYXRocyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgLy8gUGF0aCDihpIgaXRzIG9wLXZlcmIgc2VxdWVuY2UsIG9yZGVyZWQgYnkgTEFTVCB0b3VjaCAoZGVsZXRlICtcbiAgICAvLyByZS1pbnNlcnQgbW92ZXMgYSByZS10b3VjaGVkIHBhdGggdG8gdGhlIGVuZCBvZiB0aGUgTWFwJ3MgaW5zZXJ0aW9uXG4gICAgLy8gb3JkZXIg4oCUIHByZXNlcnZpbmcgbGFzdC13cml0ZXItd2lucyBmb3IgbmVzdGVkL292ZXJsYXBwaW5nIHBhdGhzKS5cbiAgICAvLyBQZXItd3JpdGUgcHJvdmVuYW5jZSAoI1AxKTogdGhlIExBU1Qgb3AncyByZWFkS2V5cyBpcyBrZXB0IOKAlCByZWFkXG4gICAgLy8gcHJlZml4ZXMgb25seSBncm93IHdpdGhpbiBhIHN0YWdlLCBzbyBsYXN0ID09IHVuaW9uIGFjcm9zcyB0aGUgcGF0aC5cbiAgICBjb25zdCBieVBhdGggPSBuZXcgTWFwPHN0cmluZywgeyB2ZXJiczogT3BWZXJiW107IHJlYWRLZXlzPzogc3RyaW5nW10gfT4oKTtcbiAgICBmb3IgKGNvbnN0IG9wIG9mIHRoaXMub3BUcmFjZSkge1xuICAgICAgY29uc3QgcHJldiA9IGJ5UGF0aC5nZXQob3AucGF0aCk7XG4gICAgICBpZiAocHJldikge1xuICAgICAgICBwcmV2LnZlcmJzLnB1c2gob3AudmVyYik7XG4gICAgICAgIGlmIChvcC5yZWFkS2V5cyAhPT0gdW5kZWZpbmVkKSBwcmV2LnJlYWRLZXlzID0gb3AucmVhZEtleXM7XG4gICAgICAgIGJ5UGF0aC5kZWxldGUob3AucGF0aCk7XG4gICAgICAgIGJ5UGF0aC5zZXQob3AucGF0aCwgcHJldik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBieVBhdGguc2V0KG9wLnBhdGgsIHsgdmVyYnM6IFtvcC52ZXJiXSwgLi4uKG9wLnJlYWRLZXlzICE9PSB1bmRlZmluZWQgJiYgeyByZWFkS2V5czogb3AucmVhZEtleXMgfSkgfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBbcGF0aCwgeyB2ZXJicywgcmVhZEtleXMgfV0gb2YgYnlQYXRoKSB7XG4gICAgICBjb25zdCBwcm92ID0gcmVhZEtleXMgIT09IHVuZGVmaW5lZCA/IHsgcmVhZEtleXMgfSA6IHVuZGVmaW5lZDtcbiAgICAgIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdChERUxJTSk7XG4gICAgICBjb25zdCBiZWZvcmUgPSBfZ2V0KHRoaXMuYmFzZVNuYXBzaG90LCBzZWdtZW50cyk7XG4gICAgICBjb25zdCBhZnRlciA9IF9nZXQodGhpcy53b3JraW5nQ29weSwgc2VnbWVudHMpO1xuICAgICAgaWYgKGRlZXBFcXVhbChiZWZvcmUsIGFmdGVyKSkgY29udGludWU7IC8vIG5vLW9wIG9yIHdyaXRlLXRoZW4tcmV2ZXJ0IOKGkiBubyBuZXQgY2hhbmdlIChzYW1lIGZpbHRlciBhcyAnZnVsbCcpXG5cbiAgICAgIHN1cnZpdmluZ1BhdGhzLmFkZChwYXRoKTtcbiAgICAgIGNvbnN0IGxhc3RWZXJiID0gdmVyYnNbdmVyYnMubGVuZ3RoIC0gMV07XG4gICAgICBpZiAobGFzdFZlcmIgPT09ICdkZWxldGUnICYmIGFmdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gUmVhbCBkZWxldGlvbiDigJQgcmVwbGF5IHJlbW92ZXMgdGhlIGtleS4gS2VlcCB0aGUgcGF0aCBlbnVtZXJhdGVkXG4gICAgICAgIC8vIGluIGBvdmVyd3JpdGVgICh1bmRlZmluZWQpIHNvIE9iamVjdC5rZXlzIGNvbnN1bWVycyBzZWUgaXQuXG4gICAgICAgIHRyYWNlLnB1c2goeyBwYXRoLCB2ZXJiOiAnZGVsZXRlJywgLi4ucHJvdiB9KTtcbiAgICAgICAgX3NldChvdmVyd3JpdGUsIHNlZ21lbnRzLCB1bmRlZmluZWQpO1xuICAgICAgfSBlbHNlIGlmICh2ZXJicy5ldmVyeSgodikgPT4gdiA9PT0gJ21lcmdlJykpIHtcbiAgICAgICAgdHJhY2UucHVzaCh7IHBhdGgsIHZlcmI6ICdtZXJnZScsIC4uLnByb3YgfSk7XG4gICAgICAgIF9zZXQodXBkYXRlcywgc2VnbWVudHMsIHN0cnVjdHVyZWRDbG9uZShfZ2V0KHRoaXMudXBkYXRlUGF0Y2gsIHNlZ21lbnRzKSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ29tbWl0dGVkLWVxdWl2YWxlbnQgdmFsdWU6IHJlcGxheSB0aGlzIHBhdGgncyBvcCBzZXF1ZW5jZSB0aGUgd2F5XG4gICAgICAgIC8vIGFwcGx5U21hcnRNZXJnZSByZXBsYXlzIHRoZSBGVUxMLW1vZGUgYnVuZGxlLCBzbyBib3RoIG1vZGVzIGNvbW1pdFxuICAgICAgICAvLyBieXRlLWlkZW50aWNhbCBzdGF0ZSAoc2VlIHRoZSBtZXRob2QgSlNEb2MpLlxuICAgICAgICBjb25zdCBjb21taXR0ZWQgPSB0aGlzLnJlcGxheVBhdGhWZXJicyhiZWZvcmUsIHNlZ21lbnRzLCB2ZXJicyk7XG4gICAgICAgIGlmIChpc1N0cmljdEFycmF5UHJlZml4KGJlZm9yZSwgY29tbWl0dGVkKSkge1xuICAgICAgICAgIHRyYWNlLnB1c2goeyBwYXRoLCB2ZXJiOiAnYXBwZW5kJywgLi4ucHJvdiB9KTtcbiAgICAgICAgICBfc2V0KG92ZXJ3cml0ZSwgc2VnbWVudHMsIHN0cnVjdHVyZWRDbG9uZSgoY29tbWl0dGVkIGFzIHVua25vd25bXSkuc2xpY2UoKGJlZm9yZSBhcyB1bmtub3duW10pLmxlbmd0aCkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0cmFjZS5wdXNoKHsgcGF0aCwgdmVyYjogJ3NldCcsIC4uLnByb3YgfSk7XG4gICAgICAgICAgX3NldChvdmVyd3JpdGUsIHNlZ21lbnRzLCBzdHJ1Y3R1cmVkQ2xvbmUoY29tbWl0dGVkKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZWRhY3RlZFBhdGhzID0gbmV3IFNldChbLi4udGhpcy5yZWRhY3RlZFBhdGhzXS5maWx0ZXIoKHBhdGgpID0+IHN1cnZpdmluZ1BhdGhzLmhhcyhwYXRoKSkpO1xuICAgIHJldHVybiB7IG92ZXJ3cml0ZSwgdXBkYXRlcywgcmVkYWN0ZWRQYXRocywgdHJhY2UgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYXkgT05FIHBhdGgncyBvcC12ZXJiIHNlcXVlbmNlIGFnYWluc3QgaXRzIGJhc2UgdmFsdWUsIGV4YWN0bHkgdGhlXG4gICAqIHdheSBgYXBwbHlTbWFydE1lcmdlYCByZXBsYXlzIHRoZSBjb3JyZXNwb25kaW5nIGZ1bGwtbW9kZSBidW5kbGU6IGV2ZXJ5XG4gICAqIGBzZXRgL2BkZWxldGVgIHBvc2l0aW9uIGFwcGxpZXMgdGhlIExBU1Qgc3RhZ2VkIG92ZXJ3cml0ZSB2YWx1ZSAodGhlXG4gICAqIGJhZyBob2xkcyBvbmUgdmFsdWUgcGVyIHBhdGgg4oCUIGxhc3Qgd3JpdGVyIHdpbnMpLCBldmVyeSBgbWVyZ2VgXG4gICAqIHBvc2l0aW9uIGFwcGxpZXMgdGhlIEFDQ1VNVUxBVEVEIGB1cGRhdGVQYXRjaGAgZGVsdGEuIFRoaXMgcmVwcm9kdWNlc1xuICAgKiB0aGUgZnVsbCBtb2RlJ3MgY29tbWl0dGVkIHZhbHVlIGZvciBhbnkgaW50ZXJsZWF2aW5nIOKAlCBpbmNsdWRpbmcgdGhlXG4gICAqIG1peGVkIHNldCttZXJnZSBxdWlyayB3aGVyZSB0aGUgYWNjdW11bGF0ZWQgZGVsdGEgcmUtYXBwbGllcyBwcmUtc2V0XG4gICAqIG1lcmdlIGtleXMgKGZ1bGwtbW9kZSByZXBsYXkgc2VtYW50aWNzLCBrZXB0IGZvciBieXRlLXBhcml0eSBhY3Jvc3NcbiAgICogbW9kZXM7IHByb3BlcnR5LXRlc3RlZCBpbiBkZWx0YS1yZXBsYXktZXF1aXZhbGVuY2UpLlxuICAgKi9cbiAgcHJpdmF0ZSByZXBsYXlQYXRoVmVyYnMoYmVmb3JlOiB1bmtub3duLCBzZWdtZW50czogc3RyaW5nW10sIHZlcmJzOiBPcFZlcmJbXSk6IHVua25vd24ge1xuICAgIGNvbnN0IHNldFZhbHVlID0gX2dldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBzZWdtZW50cyk7XG4gICAgY29uc3QgbWVyZ2VEZWx0YSA9IF9nZXQodGhpcy51cGRhdGVQYXRjaCwgc2VnbWVudHMpO1xuICAgIGxldCB2YWx1ZTogdW5rbm93biA9IGJlZm9yZTtcbiAgICBmb3IgKGNvbnN0IHZlcmIgb2YgdmVyYnMpIHtcbiAgICAgIHZhbHVlID0gdmVyYiA9PT0gJ21lcmdlJyA/IGRlZXBTbWFydE1lcmdlKHZhbHVlID8/IHt9LCBtZXJnZURlbHRhKSA6IHNldFZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBBcHBlbmQtZGV0ZWN0aW9uIHByZWRpY2F0ZSAoIzEzYy1CIMKnMi4yKTogYm90aCB2YWx1ZXMgYXJlIGFycmF5cywgdGhlXG4gKiBmaW5hbCBpcyBzdHJpY3RseSBsb25nZXIsIGFuZCB0aGUgYmFzZSBpcyBhIHN0cnVjdHVyYWwgcHJlZml4IG9mIHRoZVxuICogZmluYWwuIEVsZW1lbnQgY29tcGFyZXMgc2hvcnQtY2lyY3VpdCBvbiByZWZlcmVuY2UgaWRlbnRpdHkgKGBkZWVwRXF1YWxgJ3NcbiAqIGA9PT1gIGZhc3QgcGF0aCkgYmVmb3JlIHdhbGtpbmcgc3RydWN0dXJlLCBhbmQgYmFpbCBhdCB0aGUgZmlyc3QgbWlzbWF0Y2hcbiAqIOKAlCB3b3JzdCBjYXNlIG9uZSBzdHJ1Y3R1cmFsIGNvbXBhcmUgb2YgdGhlIGJhc2UgYXJyYXksIHN0cmljdGx5IGNoZWFwZXJcbiAqIHRoYW4gdGhlIGZ1bGwtdmFsdWUgYHN0cnVjdHVyZWRDbG9uZWAgdGhlIGZhbGxiYWNrIHBheXMuXG4gKlxuICogYGJlZm9yZSA9PT0gdW5kZWZpbmVkYCAoZmlyc3Qgd3JpdGUpIGZhaWxzIGBBcnJheS5pc0FycmF5YCDihpIgYHNldGAsIHdoaWNoXG4gKiBrZWVwcyB0aGUgZmlyc3Qgd3JpdGUgYXMgdGhlIGNhdXNhbCBhbmNob3IgZm9yIFwid2hvIGluaXRpYWxpemVkIHRoaXMga2V5XCIuXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaWN0QXJyYXlQcmVmaXgoYmVmb3JlOiB1bmtub3duLCBhZnRlcjogdW5rbm93bik6IGJlZm9yZSBpcyB1bmtub3duW10ge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoYmVmb3JlKSB8fCAhQXJyYXkuaXNBcnJheShhZnRlcikpIHJldHVybiBmYWxzZTtcbiAgaWYgKGFmdGVyLmxlbmd0aCA8PSBiZWZvcmUubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYmVmb3JlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFkZWVwRXF1YWwoYmVmb3JlW2ldLCBhZnRlcltpXSkpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==
506
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25CdWZmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS9UcmFuc2FjdGlvbkJ1ZmZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLFNBQVMsSUFBSSxJQUFJLEVBQUUsU0FBUyxJQUFJLElBQUksRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVwRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBc0I3RSxNQUFNLE9BQU8saUJBQWlCO0lBQ1gsWUFBWSxDQUFNO0lBQzNCLFdBQVcsQ0FBTTtJQUVqQixjQUFjLEdBQWdCLEVBQUUsQ0FBQztJQUNqQyxXQUFXLEdBQWdCLEVBQUUsQ0FBQztJQUM5QixPQUFPLEdBQTBELEVBQUUsQ0FBQztJQUNwRSxhQUFhLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztJQUMxQywwRUFBMEU7SUFDekQsWUFBWSxDQUFtQjtJQUVoRDs7OytFQUcyRTtJQUMxRCxnQkFBZ0IsQ0FBa0I7SUFFbkQsWUFBWSxJQUFTLEVBQUUsZUFBaUMsTUFBTSxFQUFFLGdCQUFpQztRQUMvRixJQUFJLENBQUMsWUFBWSxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsV0FBVyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN6QyxJQUFJLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztRQUNqQyxJQUFJLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7SUFDM0MsQ0FBQztJQUVEOzswREFFc0Q7SUFDOUMsYUFBYSxDQUFDLEVBQXVEO1FBQzNFLElBQUksSUFBSSxDQUFDLGdCQUFnQjtZQUFFLEVBQUUsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFD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QUMsQ0FBQyxDQUFDLFFBQVEsQ0FBQztRQUNoRixDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0NBQ0Y7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSCxTQUFTLG1CQUFtQixDQUFDLE1BQWUsRUFBRSxLQUFjO0lBQzFELElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUM7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNsRSxJQUFJLEtBQUssQ0FBQyxNQUFNLElBQUksTUFBTSxDQUFDLE1BQU07UUFBRSxPQUFPLEtBQUssQ0FBQztJQUNoRCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3BELENBQUM7SUFDRCxPQUFPLFdBQVcsQ0FBQyxNQUFNLENBQUMsSUFBSSxXQUFXLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDbkQsQ0FBQztBQUVEOzs7dUNBR3VDO0FBQ3ZDLFNBQVMsV0FBVyxDQUFDLEdBQWM7SUFDakMsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE1BQU0sS0FBSyxHQUFHLENBQUMsTUFBTSxDQUFDO0FBQ2hELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRyYW5zYWN0aW9uQnVmZmVyIOKAlCBQZXItc3RhZ2UgU1RBR0lORyBidWZmZXIgZm9yIHN0YXRlIG11dGF0aW9uc1xuICpcbiAqIFdoYXQgaXQgSVM6IGEgc3RhZ2luZyBidWZmZXIgd2l0aCByZWFkLXlvdXItd3JpdGVzIGFuZCBuZXQtY2hhbmdlIGNvbW1pdHMuXG4gKiAtIENoYW5nZXMgYXJlIHN0YWdlZCBoZXJlIGR1cmluZyBzdGFnZSBleGVjdXRpb24gYW5kIGZsdXNoZWQgdG9cbiAqICAgU2hhcmVkTWVtb3J5IGluIE9ORSBiYXRjaCBwZXIgc3RhZ2UgKGBjb21taXQoKWApIOKAlCBvdGhlciBzdGFnZXMgYW5kXG4gKiAgIHBhcmFsbGVsIHNpYmxpbmdzIG5ldmVyIG9ic2VydmUgYSBzdGFnZSdzIGhhbGYtZmluaXNoZWQgd3JpdGVzLlxuICogLSBSZWFkLWFmdGVyLXdyaXRlIGNvbnNpc3RlbmN5IHdpdGhpbiBhIHN0YWdlIOKAlCBhIHN0YWdlIHNlZXMgaXRzIG93blxuICogICBzdGFnZWQgd3JpdGVzIGltbWVkaWF0ZWx5LlxuICogLSBgY29tbWl0KClgIHJlY29yZHMgdGhlIHN0YWdlJ3MgTkVUIGNoYW5nZSAoc2VlIHtAbGluayBjb21taXR9KSwgcGx1cyBhblxuICogICBvcGVyYXRpb24gdHJhY2UgZm9yIGRldGVybWluaXN0aWMgcmVwbGF5LlxuICpcbiAqIFdoYXQgaXQgaXMgTk9UOiBhIHJvbGxiYWNrIG1lY2hhbmlzbS4gRGVzcGl0ZSB0aGUgbmFtZSwgdGhlcmUgaXMgbm9cbiAqIGFib3J0L3JvbGxiYWNrIHBhdGgg4oCUIHdoZW4gYSBzdGFnZSBUSFJPV1MsIHRoZSBlbmdpbmUgc3RpbGwgY29tbWl0c1xuICogZXZlcnl0aGluZyBzdGFnZWQgc28gZmFyIGJlZm9yZSByZS10aHJvd2luZyAoY29tbWl0LW9uLWVycm9yIGluXG4gKiBgRmxvd2NoYXJ0VHJhdmVyc2VyYCkuIFRoYXQgaXMgZGVsaWJlcmF0ZTogdGhlIGF1ZGl0IHRyYWlsIG11c3QgcmVjb3JkXG4gKiB3aGF0IHRoZSBmYWlsaW5nIHN0YWdlIGNoYW5nZWQuIERvIG5vdCByZWx5IG9uIFwic3RhZ2UgZmFpbGVkIOKGkiBpdHNcbiAqIHdyaXRlcyB2YW5pc2hlZFwiLlxuICovXG5cbmltcG9ydCB7IG5hdGl2ZUdldCBhcyBfZ2V0LCBuYXRpdmVTZXQgYXMgX3NldCB9IGZyb20gJy4vcGF0aE9wcy5qcyc7XG5pbXBvcnQgdHlwZSB7IENvbW1pdFZhbHVlc01vZGUsIE1lbW9yeVBhdGNoLCBUcmFjZUVudHJ5IH0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgeyBkZWVwRXF1YWwsIGRlZXBTbWFydE1lcmdlLCBERUxJTSwgbm9ybWFsaXNlUGF0aCB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG4vKiogT3AtbGV2ZWwgdmVyYnMgc3RhZ2VkIGludG8gYG9wVHJhY2VgLiBgJ2RlbGV0ZSdgIGlzIHN0YWdlZCBkaXN0aW5jdGx5IHNvXG4gKiAgZGVsdGEtbW9kZSBjb21taXRzICgjMTNjLUIpIGNhbiBlbWl0IGEgcmVhbCBgZGVsZXRlYCB0cmFjZSBlbnRyeTsgdW5kZXJcbiAqICB0aGUgZGVmYXVsdCBgJ2Z1bGwnYCBtb2RlIGl0IGNvbW1pdHMgYXMgYCdzZXQnYCAob2YgYHVuZGVmaW5lZGApIOKAlFxuICogIGJ5dGUtaWRlbnRpY2FsIHRvIHRoZSBoaXN0b3JpY2FsIGZsYXR0ZW5pbmcuICovXG50eXBlIE9wVmVyYiA9ICdzZXQnIHwgJ21lcmdlJyB8ICdkZWxldGUnO1xuXG4vKiogQSBwYXRoIHRoYXQgcGFzc2VkIHRoZSBuZXQtY2hhbmdlIGZpbHRlciwgd2l0aCBldmVyeXRoaW5nIHRoZSBkZWx0YVxuICogIGVuY29kZXIgbmVlZHMgdG8gZGVjaWRlIGl0cyB2ZXJiIOKAlCByZXNvbHZlZCBvbmNlLCB0aGVuIHJldXNlZCBieSB0aGVcbiAqICBvdmVybGFwLWZhbWlseSBncm91cGluZyAoYHRvRGVsdGFQYXlsb2FkYCBydWxlIDMpLiAqL1xudHlwZSBTdXJ2aXZvciA9IHtcbiAgcGF0aDogc3RyaW5nO1xuICBzZWdtZW50czogc3RyaW5nW107XG4gIHZlcmJzOiBPcFZlcmJbXTtcbiAgcmVhZEtleXM/OiBzdHJpbmdbXTtcbiAgLyoqIFZhbHVlIGF0IHRoaXMgcGF0aCB3aGVuIHRoZSBzdGFnZSBiZWdhbiAodGhlIGFwcGVuZC9kaWZmIGJhc2UpLiAqL1xuICBiZWZvcmU6IHVua25vd247XG4gIC8qKiBWYWx1ZSBhdCB0aGlzIHBhdGggYWZ0ZXIgZXZlcnkgc3RhZ2VkIG9wIChyZWFkLXlvdXItd3JpdGVzIHZpZXcpLiAqL1xuICBhZnRlcjogdW5rbm93bjtcbn07XG5cbmV4cG9ydCBjbGFzcyBUcmFuc2FjdGlvbkJ1ZmZlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYmFzZVNuYXBzaG90OiBhbnk7XG4gIHByaXZhdGUgd29ya2luZ0NvcHk6IGFueTtcblxuICBwcml2YXRlIG92ZXJ3cml0ZVBhdGNoOiBNZW1vcnlQYXRjaCA9IHt9O1xuICBwcml2YXRlIHVwZGF0ZVBhdGNoOiBNZW1vcnlQYXRjaCA9IHt9O1xuICBwcml2YXRlIG9wVHJhY2U6IHsgcGF0aDogc3RyaW5nOyB2ZXJiOiBPcFZlcmI7IHJlYWRLZXlzPzogc3RyaW5nW10gfVtdID0gW107XG4gIHByaXZhdGUgcmVkYWN0ZWRQYXRocyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAvKiogQ29tbWl0LXZhbHVlIGVuY29kaW5nIHBvbGljeSAoIzEzYy1CKS4gYCdmdWxsJ2AgPSBoaXN0b3JpY2FsIGJ5dGVzLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbW1pdFZhbHVlczogQ29tbWl0VmFsdWVzTW9kZTtcblxuICAvKiogUGVyLXdyaXRlIHJlYWQtcHJvdmVuYW5jZSBzb3VyY2UgKCNQMSkuIFdoZW4gc2V0ICh0aGVcbiAgICogIGB3cml0ZVByb3ZlbmFuY2U6ICdyZWFkcy1wcmVmaXgnYCBkaWFsKSwgZXZlcnkgc3RhZ2VkIG9wIHNuYXBzaG90cyB0aGVcbiAgICogIGtleXMgdHJhY2tlZC1yZWFkIHNvIGZhciDigJQgdGhlIHRlbXBvcmFsLXByZWZpeCBhdHRyaWJ1dGlvbiBjb25zdW1lZCBieVxuICAgKiAgY2F1c2FsIHNsaWNpbmcuIFVuZGVmaW5lZCAoZGVmYXVsdCkgPSB6ZXJvIGNvc3QsIGJ5dGUtaWRlbnRpY2FsIG9wcy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZWFkS2V5c1Byb3ZpZGVyPzogKCkgPT4gc3RyaW5nW107XG5cbiAgY29uc3RydWN0b3IoYmFzZTogYW55LCBjb21taXRWYWx1ZXM6IENvbW1pdFZhbHVlc01vZGUgPSAnZnVsbCcsIHJlYWRLZXlzUHJvdmlkZXI/OiAoKSA9PiBzdHJpbmdbXSkge1xuICAgIHRoaXMuYmFzZVNuYXBzaG90ID0gc3RydWN0dXJlZENsb25lKGJhc2UpO1xuICAgIHRoaXMud29ya2luZ0NvcHkgPSBzdHJ1Y3R1cmVkQ2xvbmUoYmFzZSk7XG4gICAgdGhpcy5jb21taXRWYWx1ZXMgPSBjb21taXRWYWx1ZXM7XG4gICAgdGhpcy5yZWFkS2V5c1Byb3ZpZGVyID0gcmVhZEtleXNQcm92aWRlcjtcbiAgfVxuXG4gIC8qKiBTdGFtcCB0aGUgY3VycmVudCByZWFkIHByZWZpeCBvbnRvIGEgc3RhZ2VkIG9wIOKAlCBvbmx5IHdoZW4gdGhlXG4gICAqICBwcm92ZW5hbmNlIGRpYWwgaXMgb24gKHByb3ZpZGVyIHByZXNlbnQpLCBzbyB0aGUgZGVmYXVsdCBwYXRoIGFsbG9jYXRlc1xuICAgKiAgbm90aGluZyBhbmQgY29tbWl0IGJ1bmRsZXMgc3RheSBieXRlLWlkZW50aWNhbC4gKi9cbiAgcHJpdmF0ZSBzdGFtcFJlYWRLZXlzKG9wOiB7IHBhdGg6IHN0cmluZzsgdmVyYjogT3BWZXJiOyByZWFkS2V5cz86IHN0cmluZ1tdIH0pOiB0eXBlb2Ygb3Age1xuICAgIGlmICh0aGlzLnJlYWRLZXlzUHJvdmlkZXIpIG9wLnJlYWRLZXlzID0gdGhpcy5yZWFkS2V5c1Byb3ZpZGVyKCk7XG4gICAgcmV0dXJuIG9wO1xuICB9XG5cbiAgLyoqIEhhcmQgb3ZlcndyaXRlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aC4gKi9cbiAgc2V0KHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10sIHZhbHVlOiBhbnksIHNob3VsZFJlZGFjdCA9IGZhbHNlKTogdm9pZCB7XG4gICAgX3NldCh0aGlzLndvcmtpbmdDb3B5LCBwYXRoLCB2YWx1ZSk7XG4gICAgX3NldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBwYXRoLCBzdHJ1Y3R1cmVkQ2xvbmUodmFsdWUpKTtcbiAgICBpZiAoc2hvdWxkUmVkYWN0KSB7XG4gICAgICB0aGlzLnJlZGFjdGVkUGF0aHMuYWRkKG5vcm1hbGlzZVBhdGgocGF0aCkpO1xuICAgIH1cbiAgICB0aGlzLm9wVHJhY2UucHVzaCh0aGlzLnN0YW1wUmVhZEtleXMoeyBwYXRoOiBub3JtYWxpc2VQYXRoKHBhdGgpLCB2ZXJiOiAnc2V0JyB9KSk7XG4gIH1cblxuICAvKipcbiAgICogRXhwbGljaXQga2V5IGRlbGV0aW9uIGF0IHRoZSBzcGVjaWZpZWQgcGF0aCAoIzEzYy1COyBhYnNvcmJzIGJhY2tsb2cgQjgpLlxuICAgKlxuICAgKiBTdGFnZXMgRVhBQ1RMWSB0aGUgc2FtZSBidWZmZXIgbXV0YXRpb25zIGFzIGBzZXQocGF0aCwgdW5kZWZpbmVkKWAg4oCUXG4gICAqIGB3b3JraW5nQ29weWAvYG92ZXJ3cml0ZVBhdGNoYCBnZXQgYW4gb3duIGB1bmRlZmluZWRgIGF0IHRoZSBwYXRoICh0aGVcbiAgICogaGlzdG9yaWNhbCBmbGF0dGVuaW5nLCBwcmVzZXJ2aW5nIHJlYWQgYmVoYXZpb3IgYW5kIHRoZSBkZWR1cCBkaWZmIGJhc2VcbiAgICogYWNyb3NzIG1vZGVzKSDigJQgYnV0IHJlY29yZHMgdGhlIG9wIHZlcmIgYXMgYCdkZWxldGUnYC4gQXQgY29tbWl0OlxuICAgKiBgJ2Z1bGwnYCBtb2RlIG1hcHMgaXQgYmFjayB0byBhIGAnc2V0J2AgdHJhY2UgZW50cnkgKGJ5dGUtaWRlbnRpY2FsIHRvXG4gICAqIHRvZGF5KTsgYCdkZWx0YSdgIG1vZGUgZW1pdHMgYSByZWFsIGAnZGVsZXRlJ2AgZW50cnkgd2hvc2UgcmVwbGF5XG4gICAqIFJFTU9WRVMgdGhlIGtleSBpbnN0ZWFkIG9mIGxlYXZpbmcgYGtleTogdW5kZWZpbmVkYCBiZWhpbmQuXG4gICAqL1xuICBkZWxldGUocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgc2hvdWxkUmVkYWN0ID0gZmFsc2UpOiB2b2lkIHtcbiAgICBfc2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIHVuZGVmaW5lZCk7XG4gICAgX3NldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBwYXRoLCB1bmRlZmluZWQpO1xuICAgIGlmIChzaG91bGRSZWRhY3QpIHtcbiAgICAgIHRoaXMucmVkYWN0ZWRQYXRocy5hZGQobm9ybWFsaXNlUGF0aChwYXRoKSk7XG4gICAgfVxuICAgIHRoaXMub3BUcmFjZS5wdXNoKHRoaXMuc3RhbXBSZWFkS2V5cyh7IHBhdGg6IG5vcm1hbGlzZVBhdGgocGF0aCksIHZlcmI6ICdkZWxldGUnIH0pKTtcbiAgfVxuXG4gIC8qKiBEZWVwIHVuaW9uIG1lcmdlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aC4gKi9cbiAgbWVyZ2UocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgdmFsdWU6IGFueSwgc2hvdWxkUmVkYWN0ID0gZmFsc2UpOiB2b2lkIHtcbiAgICBjb25zdCBleGlzdGluZyA9IF9nZXQodGhpcy53b3JraW5nQ29weSwgcGF0aCkgPz8ge307XG4gICAgY29uc3QgbWVyZ2VkID0gZGVlcFNtYXJ0TWVyZ2UoZXhpc3RpbmcsIHZhbHVlKTtcbiAgICBfc2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIG1lcmdlZCk7XG4gICAgX3NldCh0aGlzLnVwZGF0ZVBhdGNoLCBwYXRoLCBkZWVwU21hcnRNZXJnZShfZ2V0KHRoaXMudXBkYXRlUGF0Y2gsIHBhdGgpID8/IHt9LCB2YWx1ZSkpO1xuICAgIGlmIChzaG91bGRSZWRhY3QpIHtcbiAgICAgIHRoaXMucmVkYWN0ZWRQYXRocy5hZGQobm9ybWFsaXNlUGF0aChwYXRoKSk7XG4gICAgfVxuICAgIHRoaXMub3BUcmFjZS5wdXNoKHRoaXMuc3RhbXBSZWFkS2V5cyh7IHBhdGg6IG5vcm1hbGlzZVBhdGgocGF0aCksIHZlcmI6ICdtZXJnZScgfSkpO1xuICB9XG5cbiAgLyoqIFJlYWQgY3VycmVudCB2YWx1ZSBhdCBwYXRoIChpbmNsdWRlcyB1bmNvbW1pdHRlZCBjaGFuZ2VzKS4gKi9cbiAgZ2V0KHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10sIGRlZmF1bHRWYWx1ZT86IGFueSkge1xuICAgIHJldHVybiBfZ2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogRmx1c2ggYWxsIHN0YWdlZCBtdXRhdGlvbnMgYW5kIHJldHVybiB0aGUgY29tbWl0IGJ1bmRsZSDigJQgcmVjb3JkaW5nIHRoZVxuICAgKiBzdGFnZSdzIE5FVCBDSEFOR0UsIG5vdCBpdHMgcmF3IHdyaXRlIGxvZy5cbiAgICpcbiAgICog4pSA4pSAIFdIWSAodGhlIGRlZmVjdCB0aGlzIGZpeGVzKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogUHJldmlvdXNseSBldmVyeSBgc2V0YC9gbWVyZ2VgIHdhcyByZWNvcmRlZCB2ZXJiYXRpbSwgc28gdGhlIGNvbW1pdCBidW5kbGVcbiAgICogd2FzIGEgbG9nIG9mICpvcGVyYXRpb25zKiByYXRoZXIgdGhhbiAqY2hhbmdlcyouIFR3byBvcGVyYXRpb25zIHByb2R1Y2Ugbm9cbiAgICogbmV0IGNoYW5nZSB5ZXQgd2VyZSBzdGlsbCBjb21taXR0ZWQgYXMgXCJtdXRhdGlvbnNcIjpcbiAgICpcbiAgICogICAxLiBOby1vcCB3cml0ZSAgIOKAlCB3cml0aW5nIGEga2V5IHRoZSB2YWx1ZSBpdCBhbHJlYWR5IGhvbGRzIChlLmcuIGFuXG4gICAqICAgICAgICAgICAgICAgICAgICAgIGFnZW50IGNvbnRleHQgc2xvdCByZS1lbWl0dGluZyBpZGVudGljYWwgY29udGVudCBldmVyeVxuICAgKiAgICAgICAgICAgICAgICAgICAgICB0dXJuKS4gYmFzZSBLPTEsIHN0YWdlIHdyaXRlcyBLPTEuXG4gICAqICAgMi4gV3JpdGUtcmV2ZXJ0ICDigJQgY2hhbmdpbmcgdGhlbiByZXN0b3JpbmcgYSBrZXkgd2l0aGluIG9uZSBzdGFnZS5cbiAgICogICAgICAgICAgICAgICAgICAgICAgYmFzZSBLPTEsIHN0YWdlIHdyaXRlcyBLPTIgdGhlbiBLPTEuXG4gICAqXG4gICAqIFJlY29yZGluZyB0aGVzZSBhcyBtdXRhdGlvbnMgKGEpIGJsb2F0ZWQgY2F1c2FsIHNsaWNpbmcgLyBiYWNrdHJhY2tpbmcgd2l0aFxuICAgKiBzcHVyaW91cyBkZXBlbmRlbmNpZXMgb24gaW50ZXJtZWRpYXRlIHZhbHVlcyB0aGF0IG5ldmVyIHJlYWNoIGZpbmFsIHN0YXRlLFxuICAgKiBhbmQgKGIpIG1hZGUgZG93bnN0cmVhbSBcIndoYXQgY2hhbmdlZCBoZXJlP1wiIGNvbnN1bWVycyBsaWdodCB1cCBzdGFnZXMgdGhhdFxuICAgKiBjaGFuZ2VkIG5vdGhpbmcg4oCUIG1vc3QgdmlzaWJseSB0aGUgbGVucyBoaWdobGlnaHQgZmxhZ2dpbmcgZXZlcnkgc2xvdC5cbiAgICpcbiAgICog4pSA4pSAIEhPVyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogQXQgY29tbWl0IHdlIGhvbGQgQk9USCBgYmFzZVNuYXBzaG90YCAoc3RhdGUgd2hlbiB0aGUgc3RhZ2UgYmVnYW4pIGFuZFxuICAgKiBgd29ya2luZ0NvcHlgIChzdGF0ZSBhZnRlciBhbGwgaXRzIHdyaXRlcykuIEZvciBlYWNoIHBhdGggdGhlIHN0YWdlIHRvdWNoZWRcbiAgICogd2Uga2VlcCBpdCBpbiB0aGUgYnVuZGxlIE9OTFkgaWYgaXRzIGZpbmFsIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgYmFzZVxuICAgKiB2YWx1ZSAoe0BsaW5rIGRlZXBFcXVhbH0pLiBOby1vcCBBTkQgd3JpdGUtcmV2ZXJ0IHBhdGhzIGRyb3Agb3V0LCBiZWNhdXNlXG4gICAqIGJvdGggY29tcGFyZSBlcXVhbCB0byBiYXNlLiBUaGlzIGlzIGEgc2luZ2xlIG5ldC1kZWx0YSBkaWZmIGF0IGNvbW1pdCB0aW1lXG4gICAqIOKAlCBvbmUgZGVlcCBjb21wYXJlIHBlciB0b3VjaGVkIHBhdGgsIE8oY2hhbmdlZCBzdGF0ZSksIHBhaWQgb25jZSBwZXIgc3RhZ2VcbiAgICogKE5PVCBwZXIgd3JpdGUpLiBBIG5haXZlIHBlci13cml0ZSBkZWVwLWVxdWFsIHNraXAgd291bGQgYmUgbW9yZSBleHBlbnNpdmVcbiAgICogYW5kIHdvdWxkIHN0aWxsIG1pc3Mgd3JpdGUtcmV2ZXJ0ICh0aGUgaW50ZXJtZWRpYXRlIHdyaXRlIGRpZmZlcnMgZnJvbSB0aGVcbiAgICogdmFsdWUgcHJlc2VudCBhdCB0aGUgbW9tZW50IG9mIHdyaXRpbmcpLlxuICAgKlxuICAgKiDilIDilIAgVFdPIEhPTkVTVCBUSUVSUyAoYnkgZGVzaWduIOKAlCBkbyBub3QgXCJ1bmlmeVwiIHRoZW0pIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgKiAgIOKAoiBjb21taXQgKGhlcmUpICAgPSBDSEFOR0UtbGV2ZWwg4oCUIHRydXRoZnVsIG5ldCBkZWx0YS4gRmVlZHMgdGhlIGNvbW1pdFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgbG9nLCBjYXVzYWwgY2hhaW4sIG5hcnJhdGl2ZSwgYW5kIHRoZSBsZW5zIGhpZ2hsaWdodC5cbiAgICogICDigKIgYG9uV3JpdGVgIGV2ZW50ID0gT1AtbGV2ZWwg4oCUIGZpcmVzIG9uIEVWRVJZIHdyaXRlIGF0dGVtcHQgcmVnYXJkbGVzcyBvZlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgbmV0IGNoYW5nZS4gRmVlZHMgbWV0cmljcyAvIGJlaGF2aW91cmFsIG9ic2VydmFiaWxpdHlcbiAgICogICAgICAgICAgICAgICAgICAgICAgIChhIGRlYnVnZ2VyIHdhbnRzIHRvIHNlZSBcIndyb3RlIDIsIHRoZW4gcmV2ZXJ0ZWRcIikuXG4gICAqIGBvbldyaXRlYCBpcyB1bmNoYW5nZWQgYnkgdGhpcyBtZXRob2Q7IG9ubHkgdGhlIENPTU1JVCBiZWNvbWVzIGNoYW5nZS1vbmx5LlxuICAgKlxuICAgKiDilIDilIAgRU1QVFkgQ09NTUlUUyBBUkUgSU5URU5USU9OQUwg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAqIEEgc3RhZ2UgdGhhdCBuZXRzIG5vIGNoYW5nZSBjb21taXRzIGFuIEVNUFRZIHBhdGNoIOKAlCBOT1Qgbm90aGluZy5cbiAgICoge0BsaW5rIFN0YWdlQ29udGV4dC5jb21taXR9IHN0aWxsIHJlY29yZHMgdGhlIGJ1bmRsZSB1bmNvbmRpdGlvbmFsbHksIHNvXG4gICAqIGV2ZXJ5IGV4ZWN1dGVkIHN0YWdlIHJlbWFpbnMgYSB0aW1lLXRyYXZlbCBjdXJzb3Igc3RvcCAoaXRzIGBydW50aW1lU3RhZ2VJZGBcbiAgICogbWFya2VyIGlzIHByZXNlcnZlZCk7IG9ubHkgaXRzIFBBVENIIGlzIGVtcHR5LiBUaGlzIGlzIHdoYXQga2VlcHMgdGhlXG4gICAqIGNvbW1pdC1pbmRleGVkIHNsaWRlciBzdGFibGUgd2hpbGUgbWFraW5nIHRoZSBoaWdobGlnaHQgdHJ1dGhmdWwuXG4gICAqXG4gICAqIOKUgOKUgCBLTk9XTiBMSU1JVEFUSU9OUyAvIEZVVFVSRSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogICDigKIgRXhwbGljaXQga2V5IERFTEVUSU9OIHVuZGVyIHRoZSBkZWZhdWx0ICdmdWxsJyBtb2RlIGlzIHN0aWxsXG4gICAqICAgICBmbGF0dGVuZWQgdG8gc2V0LW9mLWB1bmRlZmluZWRgIChhIHJlbW92ZWQga2V5IGNhbm5vdCBiZSBleHByZXNzZWRcbiAgICogICAgIGluIE1lbW9yeVBhdGNoIGFsb25lKS4gQ0xPU0VEIHVuZGVyIGBjb21taXRWYWx1ZXM6ICdkZWx0YSdgICgjMTNjLUIpOlxuICAgKiAgICAge0BsaW5rIGRlbGV0ZX0gc3RhZ2VzIGEgZGlzdGluY3Qgb3AgYW5kIHRoZSBidW5kbGUgY2FycmllcyBhIHJlYWxcbiAgICogICAgIGBkZWxldGVgIHRyYWNlIHZlcmIgd2hvc2UgcmVwbGF5IHJlbW92ZXMgdGhlIGtleS5cbiAgICogICDigKIgQXJyYXktbWVyZ2UgZGVkdXAgaW4ge0BsaW5rIGRlZXBTbWFydE1lcmdlfSBzdGlsbCB1c2VzIHJlZmVyZW5jZSBlcXVhbGl0eVxuICAgKiAgICAgKGBuZXcgU2V0YCksIHNvIGRlZXAtZXF1YWwgKm9iamVjdHMqIGluIGEgbWVyZ2VkIGFycmF5IGFyZSBub3QgZGVkdXBlZC5cbiAgICogICAgIE9ydGhvZ29uYWwgdG8gdGhpcyBjaGFuZ2U7IHRyYWNrZWQgc2VwYXJhdGVseS5cbiAgICpcbiAgICogUmVzZXRzIHRoZSBidWZmZXIgdG8gZW1wdHkgc3RhdGUgYWZ0ZXIgY29tbWl0LlxuICAgKi9cbiAgY29tbWl0KCk6IHtcbiAgICBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoO1xuICAgIHVwZGF0ZXM6IE1lbW9yeVBhdGNoO1xuICAgIHJlZGFjdGVkUGF0aHM6IFNldDxzdHJpbmc+O1xuICAgIHRyYWNlOiBUcmFjZUVudHJ5W107XG4gIH0ge1xuICAgIGNvbnN0IHBheWxvYWQgPSB0aGlzLmNvbW1pdFZhbHVlcyA9PT0gJ2RlbHRhJyA/IHRoaXMudG9EZWx0YVBheWxvYWQoKSA6IHRoaXMudG9DaGFuZ2VPbmx5UGF5bG9hZCgpO1xuXG4gICAgdGhpcy5vdmVyd3JpdGVQYXRjaCA9IHt9O1xuICAgIHRoaXMudXBkYXRlUGF0Y2ggPSB7fTtcbiAgICB0aGlzLm9wVHJhY2UubGVuZ3RoID0gMDtcbiAgICB0aGlzLnJlZGFjdGVkUGF0aHMuY2xlYXIoKTtcbiAgICB0aGlzLndvcmtpbmdDb3B5ID0ge307XG5cbiAgICByZXR1cm4gcGF5bG9hZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWJ1aWxkIG92ZXJ3cml0ZSAvIHVwZGF0ZXMgLyB0cmFjZSBrZWVwaW5nIE9OTFkgcGF0aHMgd2hvc2UgZmluYWwgdmFsdWVcbiAgICogZGlmZmVycyBmcm9tIHRoZSBiYXNlIHZhbHVlIOKAlCBpLmUuIHRoZSBzdGFnZSdzIG5ldCBjaGFuZ2UuIFNlZVxuICAgKiB7QGxpbmsgVHJhbnNhY3Rpb25CdWZmZXIuY29tbWl0fSBmb3IgdGhlIHJhdGlvbmFsZS5cbiAgICpcbiAgICogUGF0aHMgYXJlIGNvbXBhcmVkIGF0IHRoZSBleGFjdCBncmFudWxhcml0eSB0aGV5IHdlcmUgd3JpdHRlbiAoZWFjaCB0cmFjZVxuICAgKiBlbnRyeSdzIHBhdGgpLCBhZ2FpbnN0IGB3b3JraW5nQ29weWAgKGZpbmFsKSB2cyBgYmFzZVNuYXBzaG90YCAoc3RhcnQpLlxuICAgKiBTdXJ2aXZpbmcgYHNldGAgcGF0aHMgY29weSB0aGVpciBmaW5hbCB2YWx1ZSBmcm9tIGBvdmVyd3JpdGVQYXRjaGA7XG4gICAqIHN1cnZpdmluZyBgbWVyZ2VgIHBhdGhzIGNvcHkgdGhlaXIgYWNjdW11bGF0ZWQgZGVsdGEgZnJvbSBgdXBkYXRlUGF0Y2hgIOKAlFxuICAgKiBwcmVzZXJ2aW5nIHRoZSBzZXQtdnMtbWVyZ2UgdmVyYiBzbyByZXBsYXkgKHtAbGluayBhcHBseVNtYXJ0TWVyZ2V9KSBpc1xuICAgKiBieXRlLWZvci1ieXRlIGlkZW50aWNhbCB0byByZWNvcmRpbmcgb25seSB0aGUgcmVhbCBjaGFuZ2VzLlxuICAgKlxuICAgKiBUaGlzIGlzIHRoZSBERUZBVUxUIChgY29tbWl0VmFsdWVzOiAnZnVsbCdgKSBwYXlsb2FkIOKAlCBieXRlLWlkZW50aWNhbCB0b1xuICAgKiB0aGUgaGlzdG9yaWNhbCBiZWhhdmlvciwgaW5jbHVkaW5nIGZsYXR0ZW5pbmcgc3RhZ2VkIGBkZWxldGVgIG9wcyBpbnRvXG4gICAqIGBzZXRgLW9mLWB1bmRlZmluZWRgIHRyYWNlIGVudHJpZXMuIFRoZSBkZWx0YSBlbmNvZGluZyBsaXZlcyBpblxuICAgKiB7QGxpbmsgdG9EZWx0YVBheWxvYWR9LlxuICAgKi9cbiAgcHJpdmF0ZSB0b0NoYW5nZU9ubHlQYXlsb2FkKCk6IHtcbiAgICBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoO1xuICAgIHVwZGF0ZXM6IE1lbW9yeVBhdGNoO1xuICAgIHJlZGFjdGVkUGF0aHM6IFNldDxzdHJpbmc+O1xuICAgIHRyYWNlOiBUcmFjZUVudHJ5W107XG4gIH0ge1xuICAgIGNvbnN0IG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2ggPSB7fTtcbiAgICBjb25zdCB1cGRhdGVzOiBNZW1vcnlQYXRjaCA9IHt9O1xuICAgIGNvbnN0IHRyYWNlOiBUcmFjZUVudHJ5W10gPSBbXTtcbiAgICBjb25zdCBzdXJ2aXZpbmdQYXRocyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChjb25zdCBvcCBvZiB0aGlzLm9wVHJhY2UpIHtcbiAgICAgIGNvbnN0IHNlZ21lbnRzID0gb3AucGF0aC5zcGxpdChERUxJTSk7XG4gICAgICBjb25zdCBiZWZvcmUgPSBfZ2V0KHRoaXMuYmFzZVNuYXBzaG90LCBzZWdtZW50cyk7XG4gICAgICBjb25zdCBhZnRlciA9IF9nZXQodGhpcy53b3JraW5nQ29weSwgc2VnbWVudHMpO1xuICAgICAgaWYgKGRlZXBFcXVhbChiZWZvcmUsIGFmdGVyKSkgY29udGludWU7IC8vIG5vLW9wIG9yIHdyaXRlLXRoZW4tcmV2ZXJ0IOKGkiBubyBuZXQgY2hhbmdlXG5cbiAgICAgIC8vIEhpc3RvcmljYWwgZmxhdHRlbmluZzogYW4gZXhwbGljaXQgZGVsZXRlIGNvbW1pdHMgYXMgc2V0LW9mLXVuZGVmaW5lZC5cbiAgICAgIC8vIFBlci13cml0ZSBwcm92ZW5hbmNlICgjUDEpIHJpZGVzIGVhY2ggc3Vydml2aW5nIGVudHJ5IHVudG91Y2hlZC5cbiAgICAgIHRyYWNlLnB1c2goXG4gICAgICAgIG9wLnZlcmIgPT09ICdkZWxldGUnXG4gICAgICAgICAgPyB7IHBhdGg6IG9wLnBhdGgsIHZlcmI6ICdzZXQnIGFzIGNvbnN0LCAuLi4ob3AucmVhZEtleXMgIT09IHVuZGVmaW5lZCAmJiB7IHJlYWRLZXlzOiBvcC5yZWFkS2V5cyB9KSB9XG4gICAgICAgICAgOiBvcCxcbiAgICAgICk7XG4gICAgICBzdXJ2aXZpbmdQYXRocy5hZGQob3AucGF0aCk7XG4gICAgICBpZiAob3AudmVyYiA9PT0gJ21lcmdlJykge1xuICAgICAgICBfc2V0KHVwZGF0ZXMsIHNlZ21lbnRzLCBzdHJ1Y3R1cmVkQ2xvbmUoX2dldCh0aGlzLnVwZGF0ZVBhdGNoLCBzZWdtZW50cykpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9zZXQob3ZlcndyaXRlLCBzZWdtZW50cywgc3RydWN0dXJlZENsb25lKF9nZXQodGhpcy5vdmVyd3JpdGVQYXRjaCwgc2VnbWVudHMpKSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgY29uc3QgcmVkYWN0ZWRQYXRocyA9IG5ldyBTZXQoWy4uLnRoaXMucmVkYWN0ZWRQYXRoc10uZmlsdGVyKChwYXRoKSA9PiBzdXJ2aXZpbmdQYXRocy5oYXMocGF0aCkpKTtcbiAgICByZXR1cm4geyBvdmVyd3JpdGUsIHVwZGF0ZXMsIHJlZGFjdGVkUGF0aHMsIHRyYWNlIH07XG4gIH1cblxuICAvKipcbiAgICogRGVsdGEtZW5jb2RlZCBwYXlsb2FkIChgY29tbWl0VmFsdWVzOiAnZGVsdGEnYCwgIzEzYy1CKSDigJQgc2FtZSBuZXQtY2hhbmdlXG4gICAqIGZpbHRlciBhcyB7QGxpbmsgdG9DaGFuZ2VPbmx5UGF5bG9hZH0sIHRocmVlIGVuY29kaW5nIGRpZmZlcmVuY2VzOlxuICAgKlxuICAgKiAxLiAqKk9uZSB0cmFjZSBlbnRyeSBwZXIgc3Vydml2aW5nIHBhdGgqKiAodGhlIMKnMi41IGRlZHVwIHJ1bGUg4oCUIGBhcHBlbmRgXG4gICAqICAgIGlzIE5PVCBpZGVtcG90ZW50IG9uIHJlcGxheSwgc28gZHVwbGljYXRlIGVudHJpZXMgd291bGQgbXVsdGlwbHlcbiAgICogICAgdGFpbHMpLiBUaGUgdmVyYiBpcyByZXNvbHZlZCBmcm9tIHRoZSBwYXRoJ3Mgb3AgbWl4ICsgYmFzZeKGkmZpbmFsXG4gICAqICAgIHJlbGF0aW9uc2hpcDsgZW50cmllcyBhcmUgb3JkZXJlZCBieSBlYWNoIHBhdGgncyBMQVNUIHRvdWNoLFxuICAgKiAgICBwcmVzZXJ2aW5nIGxhc3Qtd3JpdGVyLXdpbnMgZm9yIG5lc3RlZC9vdmVybGFwcGluZyBwYXRocy5cbiAgICogMi4gKipWZXJiIHJlc29sdXRpb24gcGVyIHBhdGgqKiDigJQgZm9yIGEgcGF0aCB3aXRoIE5PIHN1cnZpdmluZyByZWxhdGl2ZVxuICAgKiAgICAoc2VlIDMpOlxuICAgKiAgICAtIGxhc3Qgb3AgYCdkZWxldGUnYCBBTkQgZmluYWwgdmFsdWUgZ29uZSDihpIgYGRlbGV0ZWAgKHRoZSBwYXRoIHN0YXlzXG4gICAqICAgICAgZW51bWVyYXRlZCBpbiBgb3ZlcndyaXRlYCB3aXRoIGB1bmRlZmluZWRgIGZvciBrZXktc2V0IGNvbnN1bWVycykuXG4gICAqICAgICAgUmVxdWlyZXMgdGhlIHBhcmVudCB0byBiZSBhIHJlYWwgY29udGFpbmVyIGluIHRoZSBiYXNlIOKAlCByZXBsYXkgdXNlc1xuICAgKiAgICAgIGBuYXRpdmVEZWxldGVgLCB3aGljaCBpcyBpbmVydCBvbiBhIHByaW1pdGl2ZS9hYnNlbnQgcGFyZW50LCB3aGVyZWFzXG4gICAqICAgICAgdGhlIGAnZnVsbCdgIGZsYXR0ZW5pbmcgKGBfc2V0YCBvZiBgdW5kZWZpbmVkYCkgQ09FUkNFUyB0aGF0IHBhcmVudFxuICAgKiAgICAgIGludG8gYW4gb2JqZWN0OyB3aGVuIHRoZXkgd291bGQgZGlzYWdyZWUgd2Uga2VlcCB0aGUgZmxhdHRlbmluZztcbiAgICogICAgLSBPTkxZIGAnbWVyZ2UnYCBvcHMg4oaSIGBtZXJnZWAgd2l0aCB0aGUgYWNjdW11bGF0ZWQgYHVwZGF0ZVBhdGNoYFxuICAgKiAgICAgIGRlbHRhIChyZXBsYXlpbmcgdGhlIGFjY3VtdWxhdGVkIGRlbHRhIG9uY2Ug4omhIHRoZSBmdWxsIG1vZGUnc1xuICAgKiAgICAgIGsgc2VxdWVudGlhbCByZXBsYXlzIOKAlCBgZGVlcFNtYXJ0TWVyZ2VgIGlzIHJlZmVyZW5jZS1pZGVtcG90ZW50XG4gICAqICAgICAgd2l0aGluIG9uZSByZXBsYXkgcGFzcyk7XG4gICAqICAgIC0gb3RoZXJ3aXNlIChgc2V0YC9taXhlZCk6IHRoZSBjb21taXR0ZWQgdmFsdWUgaXMgY29tcHV0ZWQgYnlcbiAgICogICAgICByZXBsYXlpbmcgdGhlIHBhdGgncyBvcCBzZXF1ZW5jZSBFWEFDVExZIHRoZSB3YXkgYGFwcGx5U21hcnRNZXJnZWBcbiAgICogICAgICByZXBsYXlzIHRoZSBmdWxsLW1vZGUgYnVuZGxlICh7QGxpbmsgcmVwbGF5UGF0aFZlcmJzfSkg4oCUIGZvclxuICAgKiAgICAgIHB1cmUtc2V0IHBhdGhzIHRoYXQgaXMgc2ltcGx5IHRoZSBsYXN0IHNldCB2YWx1ZTsgZm9yIG1peGVkXG4gICAqICAgICAgc2V0K21lcmdlIGludGVybGVhdmluZ3MgaXQgcmVwcm9kdWNlcyB0aGUgZnVsbCBtb2RlJ3MgcXVpcmsgb2ZcbiAgICogICAgICBhcHBseWluZyB0aGUgQUNDVU1VTEFURUQgbWVyZ2UgZGVsdGEgYXQgZXZlcnkgbWVyZ2UgcG9zaXRpb25cbiAgICogICAgICAod2hpY2ggY2FuIGRpZmZlciBmcm9tIHRoZSBidWZmZXIncyByZWFkLXlvdXItd3JpdGVzIHZpZXc7IHBhcml0eVxuICAgKiAgICAgIHdpdGggdGhlIGAnZnVsbCdgIG1vZGUncyBjb21taXR0ZWQgc3RhdGUgaXMgdGhlIGNvbnRyYWN0KS4gSWYgYmFzZVxuICAgKiAgICAgIGFuZCB0aGF0IHZhbHVlIGFyZSBhcnJheXMgYW5kIGJhc2UgaXMgYSBTVFJJQ1QgUFJFRklYIOKGkiBgYXBwZW5kYFxuICAgKiAgICAgIHN0b3Jpbmcgb25seSB0aGUgdGFpbDsgZWxzZSBgc2V0YCBzdG9yaW5nIHRoZSBmdWxsIHZhbHVlLlxuICAgKiAzLiAqKk9WRVJMQVAgRkFNSUxJRVMgdGFrZSB0aGUgZnVsbC12YWx1ZSBmYWxsYmFjay4qKiBgb3ZlcndyaXRlYCAvXG4gICAqICAgIGB1cGRhdGVzYCBhcmUgbmVzdGVkIHBhdGggVFJFRVMsIHNvIHR3byBzdXJ2aXZpbmcgcGF0aHMgd2hlcmUgb25lIGlzXG4gICAqICAgIGFuIGFuY2VzdG9yIG9mIHRoZSBvdGhlciAoYGFgIGFuZCBgYS5wYCkgc2hhcmUgc3RvcmFnZS4gVGhlIGAnZnVsbCdgXG4gICAqICAgIHBheWxvYWQgc3Vydml2ZXMgdGhhdCBiZWNhdXNlIGV2ZXJ5IGVudHJ5IHN0b3JlcyB0aGUgRlVMTCB2YWx1ZSBhdCBpdHNcbiAgICogICAgcGF0aCwgZHJhd24gZnJvbSBvbmUgY29oZXJlbnQgdHJlZSDigJQgbmVzdGVkIGVudHJpZXMgYWdyZWUgd2l0aCB0aGVpclxuICAgKiAgICBhbmNlc3RvciBieSBjb25zdHJ1Y3Rpb24uIERlbHRhJ3MgcGVyLXBhdGggZW5jb2RpbmdzIGRvIE5PVDogYW5cbiAgICogICAgYGFwcGVuZGAgYW5jZXN0b3Igc3RvcmVzIG9ubHkgYSBUQUlMICh3aG9zZSBpbmRpY2VzIGFyZSBzaGlmdGVkXG4gICAqICAgIHJlbGF0aXZlIHRvIHRoZSB3aG9sZSBhcnJheSkgYW5kIGEgYGRlbGV0ZWAgYW5jZXN0b3Igc3RvcmVzXG4gICAqICAgIGB1bmRlZmluZWRgLCBzbyB3aGljaGV2ZXIgZW50cnkgaXMgd3JpdHRlbiBzZWNvbmQgc2lsZW50bHkgZGVzdHJveXMgb3JcbiAgICogICAgY29ycnVwdHMgdGhlIG90aGVyIOKAlCB0aGUgcmVjb3JkZWQgd3JpdGUgaXMgTE9TVCBhdCByZXBsYXkuIFRoZXJlZm9yZVxuICAgKiAgICBldmVyeSBwYXRoIHRoYXQgaGFzIGEgc3Vydml2aW5nIGFuY2VzdG9yL2Rlc2NlbmRhbnQgaXMgY29tbWl0dGVkIGFzIGFcbiAgICogICAgcGxhaW4gYHNldGAgb2YgdGhlIHZhbHVlIGl0IGhvbGRzIGluIHRoZSBmYW1pbHkncyByZXBsYXllZCB2YWx1ZVxuICAgKiAgICAoe0BsaW5rIHJlcGxheUZhbWlseVZlcmJzfSksIGFuZCB0aGUgZmFtaWx5J3Mgc2hhbGxvd2VzdCBwYXRoICh3aG9zZVxuICAgKiAgICBzZXQgY292ZXJzIHRoZSB3aG9sZSBzdWJ0cmVlKSBpcyBlbWl0dGVkIExBU1QuIE9uZSBjb2hlcmVudCB0cmVlIGluLFxuICAgKiAgICBvbmUgY29oZXJlbnQgdHJlZSBvdXQ6IGVudHJpZXMgY2FuIG5vIGxvbmdlciBjbG9iYmVyIGVhY2ggb3RoZXIgYW5kXG4gICAqICAgIHRoZSByZXBsYXllZCB2YWx1ZSBpcyBleGFjdCByZWdhcmRsZXNzIG9mIG9yZGVyLlxuICAgKlxuICAgKiBMb3NzbGVzc25lc3MgbmV2ZXIgZGVwZW5kcyBvbiBkZXRlY3Rpb24gc3VjY2VlZGluZyDigJQgZXZlcnkgZmFsbGJhY2sgaXNcbiAgICogdG9kYXkncyBmdWxsLXZhbHVlIGBzZXRgLlxuICAgKi9cbiAgcHJpdmF0ZSB0b0RlbHRhUGF5bG9hZCgpOiB7XG4gICAgb3ZlcndyaXRlOiBNZW1vcnlQYXRjaDtcbiAgICB1cGRhdGVzOiBNZW1vcnlQYXRjaDtcbiAgICByZWRhY3RlZFBhdGhzOiBTZXQ8c3RyaW5nPjtcbiAgICB0cmFjZTogVHJhY2VFbnRyeVtdO1xuICB9IHtcbiAgICBjb25zdCBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoID0ge307XG4gICAgY29uc3QgdXBkYXRlczogTWVtb3J5UGF0Y2ggPSB7fTtcbiAgICBjb25zdCB0cmFjZTogVHJhY2VFbnRyeVtdID0gW107XG5cbiAgICAvLyBQYXRoIOKGkiBpdHMgb3AtdmVyYiBzZXF1ZW5jZSwgb3JkZXJlZCBieSBMQVNUIHRvdWNoIChkZWxldGUgK1xuICAgIC8vIHJlLWluc2VydCBtb3ZlcyBhIHJlLXRvdWNoZWQgcGF0aCB0byB0aGUgZW5kIG9mIHRoZSBNYXAncyBpbnNlcnRpb25cbiAgICAvLyBvcmRlciDigJQgcHJlc2VydmluZyBsYXN0LXdyaXRlci13aW5zIGZvciBuZXN0ZWQvb3ZlcmxhcHBpbmcgcGF0aHMpLlxuICAgIC8vIFBlci13cml0ZSBwcm92ZW5hbmNlICgjUDEpOiB0aGUgTEFTVCBvcCdzIHJlYWRLZXlzIGlzIGtlcHQg4oCUIHJlYWRcbiAgICAvLyBwcmVmaXhlcyBvbmx5IGdyb3cgd2l0aGluIGEgc3RhZ2UsIHNvIGxhc3QgPT0gdW5pb24gYWNyb3NzIHRoZSBwYXRoLlxuICAgIGNvbnN0IGJ5UGF0aCA9IG5ldyBNYXA8c3RyaW5nLCB7IHZlcmJzOiBPcFZlcmJbXTsgcmVhZEtleXM/OiBzdHJpbmdbXSB9PigpO1xuICAgIGZvciAoY29uc3Qgb3Agb2YgdGhpcy5vcFRyYWNlKSB7XG4gICAgICBjb25zdCBwcmV2ID0gYnlQYXRoLmdldChvcC5wYXRoKTtcbiAgICAgIGlmIChwcmV2KSB7XG4gICAgICAgIHByZXYudmVyYnMucHVzaChvcC52ZXJiKTtcbiAgICAgICAgaWYgKG9wLnJlYWRLZXlzICE9PSB1bmRlZmluZWQpIHByZXYucmVhZEtleXMgPSBvcC5yZWFkS2V5cztcbiAgICAgICAgYnlQYXRoLmRlbGV0ZShvcC5wYXRoKTtcbiAgICAgICAgYnlQYXRoLnNldChvcC5wYXRoLCBwcmV2KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJ5UGF0aC5zZXQob3AucGF0aCwgeyB2ZXJiczogW29wLnZlcmJdLCAuLi4ob3AucmVhZEtleXMgIT09IHVuZGVmaW5lZCAmJiB7IHJlYWRLZXlzOiBvcC5yZWFkS2V5cyB9KSB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBOZXQtY2hhbmdlIGZpbHRlciDigJQgaWRlbnRpY2FsIHRvICdmdWxsJy4gU3Vydml2b3JzIGtlZXAgbGFzdC10b3VjaCBvcmRlci5cbiAgICBjb25zdCBzdXJ2aXZvcnM6IFN1cnZpdm9yW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IFtwYXRoLCB7IHZlcmJzLCByZWFkS2V5cyB9XSBvZiBieVBhdGgpIHtcbiAgICAgIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdChERUxJTSk7XG4gICAgICBjb25zdCBiZWZvcmUgPSBfZ2V0KHRoaXMuYmFzZVNuYXBzaG90LCBzZWdtZW50cyk7XG4gICAgICBjb25zdCBhZnRlciA9IF9nZXQodGhpcy53b3JraW5nQ29weSwgc2VnbWVudHMpO1xuICAgICAgaWYgKGRlZXBFcXVhbChiZWZvcmUsIGFmdGVyKSkgY29udGludWU7IC8vIG5vLW9wIG9yIHdyaXRlLXRoZW4tcmV2ZXJ0IOKGkiBubyBuZXQgY2hhbmdlIChzYW1lIGZpbHRlciBhcyAnZnVsbCcpXG4gICAgICBzdXJ2aXZvcnMucHVzaCh7IHBhdGgsIHNlZ21lbnRzLCB2ZXJicywgcmVhZEtleXMsIGJlZm9yZSwgYWZ0ZXIgfSk7XG4gICAgfVxuICAgIGNvbnN0IHN1cnZpdmluZ1BhdGhzID0gbmV3IFNldChzdXJ2aXZvcnMubWFwKChzKSA9PiBzLnBhdGgpKTtcblxuICAgIC8vIEdyb3VwIHN1cnZpdm9ycyBpbnRvIE9WRVJMQVAgRkFNSUxJRVMgKHJ1bGUgMyk6IGVhY2ggcGF0aCdzIGZhbWlseSBpc1xuICAgIC8vIGtleWVkIGJ5IGl0cyBTSEFMTE9XRVNUIHN1cnZpdmluZyBhbmNlc3RvciDigJQgd2Fsa2luZyBwcmVmaXhlcyBzaGFsbG93XG4gICAgLy8gZmlyc3QgbWVhbnMgdGhlIGZpcnN0IGhpdCBpcyB0aGF0IHJvb3QsIGFuZCBhIGRlcHRoLTEgcGF0aCAodGhlIGNvbW1vblxuICAgIC8vIGNhc2UpIG5ldmVyIGVudGVycyB0aGUgbG9vcCBhdCBhbGwuIEFueSB0d28gcGF0aHMgc2hhcmluZyBhIHJvb3QgYXJlXG4gICAgLy8gZXhhY3RseSB0aGUgcGF0aHMgd2hvc2UgcGF0Y2ggc3RvcmFnZSBvdmVybGFwcy5cbiAgICBjb25zdCByb290T2YgPSBuZXcgTWFwPHN0cmluZywgc3RyaW5nPigpO1xuICAgIGNvbnN0IGJ5Um9vdCA9IG5ldyBNYXA8c3RyaW5nLCBTdXJ2aXZvcltdPigpO1xuICAgIGZvciAoY29uc3QgcyBvZiBzdXJ2aXZvcnMpIHtcbiAgICAgIGxldCByb290ID0gcy5wYXRoO1xuICAgICAgZm9yIChsZXQgaSA9IDE7IGkgPCBzLnNlZ21lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGNvbnN0IGFuY2VzdG9yID0gcy5zZWdtZW50cy5zbGljZSgwLCBpKS5qb2luKERFTElNKTtcbiAgICAgICAgaWYgKHN1cnZpdmluZ1BhdGhzLmhhcyhhbmNlc3RvcikpIHtcbiAgICAgICAgICByb290ID0gYW5jZXN0b3I7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJvb3RPZi5zZXQocy5wYXRoLCByb290KTtcbiAgICAgIGNvbnN0IGZhbWlseSA9IGJ5Um9vdC5nZXQocm9vdCk7XG4gICAgICBpZiAoZmFtaWx5KSBmYW1pbHkucHVzaChzKTtcbiAgICAgIGVsc2UgYnlSb290LnNldChyb290LCBbc10pO1xuICAgIH1cblxuICAgIC8vIFJlcGxheSBlYWNoIG92ZXJsYXBwaW5nIGZhbWlseSBPTkNFIChsYXppbHkg4oCUIG1vc3QgY29tbWl0cyBoYXZlIG5vbmUpLlxuICAgIGNvbnN0IGZhbWlseU9wcyA9IHRoaXMub3BzQnlGYW1pbHkocm9vdE9mLCBieVJvb3QpO1xuICAgIGNvbnN0IGZhbWlseVZhbHVlcyA9IG5ldyBNYXA8c3RyaW5nLCB1bmtub3duPigpO1xuICAgIGNvbnN0IGZhbWlseVZhbHVlID0gKHJvb3Q6IHN0cmluZyk6IHVua25vd24gPT4ge1xuICAgICAgaWYgKCFmYW1pbHlWYWx1ZXMuaGFzKHJvb3QpKSB7XG4gICAgICAgIGZhbWlseVZhbHVlcy5zZXQocm9vdCwgdGhpcy5yZXBsYXlGYW1pbHlWZXJicyhyb290LnNwbGl0KERFTElNKSwgZmFtaWx5T3BzLmdldChyb290KSA/PyBbXSkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbWlseVZhbHVlcy5nZXQocm9vdCk7XG4gICAgfTtcblxuICAgIGNvbnN0IGVtaXQgPSAoczogU3Vydml2b3IpOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IHsgcGF0aCwgc2VnbWVudHMsIHZlcmJzLCBiZWZvcmUgfSA9IHM7XG4gICAgICBjb25zdCBwcm92ID0gcy5yZWFkS2V5cyAhPT0gdW5kZWZpbmVkID8geyByZWFkS2V5czogcy5yZWFkS2V5cyB9IDogdW5kZWZpbmVkO1xuICAgICAgY29uc3Qgcm9vdCA9IHJvb3RPZi5nZXQocGF0aCkgYXMgc3RyaW5nO1xuICAgICAgY29uc3QgZmFtaWx5ID0gYnlSb290LmdldChyb290KSBhcyBTdXJ2aXZvcltdO1xuXG4gICAgICBpZiAoZmFtaWx5Lmxlbmd0aCA+IDEpIHtcbiAgICAgICAgLy8gUnVsZSAzIOKAlCBmdWxsLXZhbHVlIGZhbGxiYWNrIGZyb20gT05FIGNvaGVyZW50IGZhbWlseSB2YWx1ZS5cbiAgICAgICAgY29uc3QgcmVsYXRpdmUgPSBbJ3YnLCAuLi5zZWdtZW50cy5zbGljZShyb290LnNwbGl0KERFTElNKS5sZW5ndGgpXTtcbiAgICAgICAgdHJhY2UucHVzaCh7IHBhdGgsIHZlcmI6ICdzZXQnLCAuLi5wcm92IH0pO1xuICAgICAgICBfc2V0KG92ZXJ3cml0ZSwgc2VnbWVudHMsIHN0cnVjdHVyZWRDbG9uZShfZ2V0KHsgdjogZmFtaWx5VmFsdWUocm9vdCkgfSwgcmVsYXRpdmUpKSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY29uc3QgbGFzdFZlcmIgPSB2ZXJic1t2ZXJicy5sZW5ndGggLSAxXTtcbiAgICAgIGlmIChsYXN0VmVyYiA9PT0gJ2RlbGV0ZScgJiYgcy5hZnRlciA9PT0gdW5kZWZpbmVkICYmIHRoaXMuZGVsZXRlUmVwbGF5c0FzRmxhdHRlbmluZyhzZWdtZW50cykpIHtcbiAgICAgICAgLy8gUmVhbCBkZWxldGlvbiDigJQgcmVwbGF5IHJlbW92ZXMgdGhlIGtleS4gS2VlcCB0aGUgcGF0aCBlbnVtZXJhdGVkXG4gICAgICAgIC8vIGluIGBvdmVyd3JpdGVgICh1bmRlZmluZWQpIHNvIE9iamVjdC5rZXlzIGNvbnN1bWVycyBzZWUgaXQuXG4gICAgICAgIHRyYWNlLnB1c2goeyBwYXRoLCB2ZXJiOiAnZGVsZXRlJywgLi4ucHJvdiB9KTtcbiAgICAgICAgX3NldChvdmVyd3JpdGUsIHNlZ21lbnRzLCB1bmRlZmluZWQpO1xuICAgICAgfSBlbHNlIGlmICh2ZXJicy5ldmVyeSgodikgPT4gdiA9PT0gJ21lcmdlJykpIHtcbiAgICAgICAgdHJhY2UucHVzaCh7IHBhdGgsIHZlcmI6ICdtZXJnZScsIC4uLnByb3YgfSk7XG4gICAgICAgIF9zZXQodXBkYXRlcywgc2VnbWVudHMsIHN0cnVjdHVyZWRDbG9uZShfZ2V0KHRoaXMudXBkYXRlUGF0Y2gsIHNlZ21lbnRzKSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ29tbWl0dGVkLWVxdWl2YWxlbnQgdmFsdWU6IHJlcGxheSB0aGlzIHBhdGgncyBvcCBzZXF1ZW5jZSB0aGUgd2F5XG4gICAgICAgIC8vIGFwcGx5U21hcnRNZXJnZSByZXBsYXlzIHRoZSBGVUxMLW1vZGUgYnVuZGxlLCBzbyBib3RoIG1vZGVzIGNvbW1pdFxuICAgICAgICAvLyBieXRlLWlkZW50aWNhbCBzdGF0ZSAoc2VlIHRoZSBtZXRob2QgSlNEb2MpLlxuICAgICAgICBjb25zdCBjb21taXR0ZWQgPSB0aGlzLnJlcGxheVBhdGhWZXJicyhiZWZvcmUsIHNlZ21lbnRzLCB2ZXJicyk7XG4gICAgICAgIGlmIChpc1N0cmljdEFycmF5UHJlZml4KGJlZm9yZSwgY29tbWl0dGVkKSkge1xuICAgICAgICAgIHRyYWNlLnB1c2goeyBwYXRoLCB2ZXJiOiAnYXBwZW5kJywgLi4ucHJvdiB9KTtcbiAgICAgICAgICBfc2V0KG92ZXJ3cml0ZSwgc2VnbWVudHMsIHN0cnVjdHVyZWRDbG9uZSgoY29tbWl0dGVkIGFzIHVua25vd25bXSkuc2xpY2UoKGJlZm9yZSBhcyB1bmtub3duW10pLmxlbmd0aCkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0cmFjZS5wdXNoKHsgcGF0aCwgdmVyYjogJ3NldCcsIC4uLnByb3YgfSk7XG4gICAgICAgICAgX3NldChvdmVyd3JpdGUsIHNlZ21lbnRzLCBzdHJ1Y3R1cmVkQ2xvbmUoY29tbWl0dGVkKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9O1xuXG4gICAgZm9yIChjb25zdCBzIG9mIHN1cnZpdm9ycykge1xuICAgICAgY29uc3Qgcm9vdCA9IHJvb3RPZi5nZXQocy5wYXRoKSBhcyBzdHJpbmc7XG4gICAgICBjb25zdCBmYW1pbHkgPSBieVJvb3QuZ2V0KHJvb3QpIGFzIFN1cnZpdm9yW107XG4gICAgICBpZiAoZmFtaWx5Lmxlbmd0aCA9PT0gMSkge1xuICAgICAgICBlbWl0KHMpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIC8vIE92ZXJsYXBwaW5nIGZhbWlseTogbWVtYmVycyBpbiBsYXN0LXRvdWNoIG9yZGVyLCB0aGUgUk9PVCBlbWl0dGVkXG4gICAgICAvLyBMQVNUIOKAlCBpdHMgd2hvbGUtc3VidHJlZSBzZXQgaXMgd2hhdCBtYWtlcyB0aGUgcmVwbGF5ZWQgc3VidHJlZVxuICAgICAgLy8gZXhhY3RseSB0aGUgZmFtaWx5IHZhbHVlIChhIGRlc2NlbmRhbnQgYXBwbGllZCBhZnRlcndhcmRzIGNvdWxkIG9ubHlcbiAgICAgIC8vIHJlLXN0YXRlIGEgdmFsdWUgYWxyZWFkeSBpbnNpZGUgaXQsIGJ1dCB3b3VsZCBhbHNvIGxlYXZlIGJlaGluZCB0aGVcbiAgICAgIC8vIGBrZXk6IHVuZGVmaW5lZGAgc2hlbGxzICdmdWxsJyBtb2RlIG5ldmVyIGhhcykuXG4gICAgICBpZiAocy5wYXRoICE9PSByb290KSBlbWl0KHMpO1xuICAgICAgaWYgKGZhbWlseVtmYW1pbHkubGVuZ3RoIC0gMV0gPT09IHMpIGVtaXQoZmFtaWx5LmZpbmQoKG0pID0+IG0ucGF0aCA9PT0gcm9vdCkgYXMgU3Vydml2b3IpO1xuICAgIH1cblxuICAgIGNvbnN0IHJlZGFjdGVkUGF0aHMgPSBuZXcgU2V0KFsuLi50aGlzLnJlZGFjdGVkUGF0aHNdLmZpbHRlcigocGF0aCkgPT4gc3Vydml2aW5nUGF0aHMuaGFzKHBhdGgpKSk7XG4gICAgcmV0dXJuIHsgb3ZlcndyaXRlLCB1cGRhdGVzLCByZWRhY3RlZFBhdGhzLCB0cmFjZSB9O1xuICB9XG5cbiAgLyoqXG4gICAqIEJ1Y2tldCB0aGUgc3RhZ2VkIG9wcyBvZiBldmVyeSBPVkVSTEFQUElORyBmYW1pbHkgYnkgZmFtaWx5IHJvb3QsIGluIG9wXG4gICAqIG9yZGVyIOKAlCB0aGUgaW5wdXQge0BsaW5rIHJlcGxheUZhbWlseVZlcmJzfSBmb2xkcy4gT3BzIG9uIHBhdGhzIHRoZVxuICAgKiBuZXQtY2hhbmdlIGZpbHRlciBkcm9wcGVkIGFyZSBza2lwcGVkICh0aGV5IGFyZSBhYnNlbnQgZnJvbSBgcm9vdE9mYCksXG4gICAqIGV4YWN0bHkgYXMgdGhlIGAnZnVsbCdgIHBheWxvYWQgZHJvcHMgdGhlbSBmcm9tIGl0cyB0cmFjZS4gT25lIHBhc3Mgb3ZlclxuICAgKiBgb3BUcmFjZWAsIGFuZCBvbmx5IHdoZW4gYXQgbGVhc3Qgb25lIGZhbWlseSBhY3R1YWxseSBvdmVybGFwcyDigJQgY29tbWl0c1xuICAgKiB0aGF0IHdyaXRlIG5vIG5lc3RlZCBwYXRoIHBheSBub3RoaW5nLlxuICAgKi9cbiAgcHJpdmF0ZSBvcHNCeUZhbWlseShcbiAgICByb290T2Y6IE1hcDxzdHJpbmcsIHN0cmluZz4sXG4gICAgYnlSb290OiBNYXA8c3RyaW5nLCBTdXJ2aXZvcltdPixcbiAgKTogTWFwPHN0cmluZywgeyBwYXRoOiBzdHJpbmc7IHZlcmI6IE9wVmVyYiB9W10+IHtcbiAgICBjb25zdCBidWNrZXRzID0gbmV3IE1hcDxzdHJpbmcsIHsgcGF0aDogc3RyaW5nOyB2ZXJiOiBPcFZlcmIgfVtdPigpO1xuICAgIGZvciAoY29uc3QgW3Jvb3QsIGZhbWlseV0gb2YgYnlSb290KSBpZiAoZmFtaWx5Lmxlbmd0aCA+IDEpIGJ1Y2tldHMuc2V0KHJvb3QsIFtdKTtcbiAgICBpZiAoYnVja2V0cy5zaXplID09PSAwKSByZXR1cm4gYnVja2V0cztcbiAgICBmb3IgKGNvbnN0IG9wIG9mIHRoaXMub3BUcmFjZSkge1xuICAgICAgY29uc3QgYnVja2V0ID0gYnVja2V0cy5nZXQocm9vdE9mLmdldChvcC5wYXRoKSBhcyBzdHJpbmcpO1xuICAgICAgaWYgKGJ1Y2tldCkgYnVja2V0LnB1c2gob3ApO1xuICAgIH1cbiAgICByZXR1cm4gYnVja2V0cztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYXkgT05FIG92ZXJsYXBwaW5nIGZhbWlseSdzIHN0YWdlZCBvcHMgb250byB0aGUgZmFtaWx5IHJvb3QncyBiYXNlXG4gICAqIHZhbHVlIOKAlCB0aGUgbXVsdGktcGF0aCBnZW5lcmFsaXNhdGlvbiBvZiB7QGxpbmsgcmVwbGF5UGF0aFZlcmJzfSwgYW5kXG4gICAqIGJ5dGUtZm9yLWJ5dGUgd2hhdCBgYXBwbHlTbWFydE1lcmdlYCBwcm9kdWNlcyBmb3IgdGhlIGNvcnJlc3BvbmRpbmdcbiAgICogYCdmdWxsJ2AtbW9kZSBlbnRyaWVzOiBlYWNoIGBzZXRgL2BkZWxldGVgIHBvc2l0aW9uIHdyaXRlcyB0aGF0IHBhdGgnc1xuICAgKiBgb3ZlcndyaXRlUGF0Y2hgIHZhbHVlLCBlYWNoIGBtZXJnZWAgcG9zaXRpb24gZGVlcC1tZXJnZXMgdGhhdCBwYXRoJ3NcbiAgICogYWNjdW11bGF0ZWQgYHVwZGF0ZVBhdGNoYCBkZWx0YSBpbnRvIHRoZSB2YWx1ZSByZXBsYXllZCBzbyBmYXIuXG4gICAqXG4gICAqIChCb3RoIHBhdGNoZXMgYXJlIHNpbmdsZSBjb2hlcmVudCB0cmVlcywgc28gYSBmdWxsLW1vZGUgYnVuZGxlJ3Mgc3RvcmVkXG4gICAqIHZhbHVlIGF0IGFueSByZWNvcmRlZCBwYXRoIGFsd2F5cyByZWFkcyBiYWNrIGFzIGl0cyBgb3ZlcndyaXRlUGF0Y2hgIC9cbiAgICogYHVwZGF0ZVBhdGNoYCB2YWx1ZSDigJQgd2hpY2ggaXMgd2h5IHNvdXJjaW5nIGZyb20gdGhlbSBoZXJlIHJlcHJvZHVjZXMgdGhlXG4gICAqIGZ1bGwtbW9kZSByZXBsYXkgZXhhY3RseSwgaW5jbHVkaW5nIGl0cyBpbnRlcm1lZGlhdGUtY29lcmNpb24gcXVpcmtzLilcbiAgICpcbiAgICogVGhlIHZhbHVlIGlzIGhlbGQgaW4gYSBgeyB2IH1gIGJveCBzbyB0aGUgcm9vdCBpdHNlbGYgKHJlbGF0aXZlIHBhdGggYFtdYClcbiAgICogY2FuIGJlIFJFUExBQ0VEIGJ5IGBfc2V0YCB0aGUgc2FtZSB3YXkgYGFwcGx5U21hcnRNZXJnZWAgcmVwbGFjZXMgaXRcbiAgICogaW5zaWRlIHRoZSBzdGF0ZSB0cmVlIOKAlCBpbmNsdWRpbmcgYG5hdGl2ZVNldGAncyBjb2VyY2lvbiBvZiBwcmltaXRpdmVcbiAgICogaW50ZXJtZWRpYXRlcy5cbiAgICovXG4gIHByaXZhdGUgcmVwbGF5RmFtaWx5VmVyYnMocm9vdFNlZ21lbnRzOiBzdHJpbmdbXSwgb3BzOiB7IHBhdGg6IHN0cmluZzsgdmVyYjogT3BWZXJiIH1bXSk6IHVua25vd24ge1xuICAgIGNvbnN0IGJveDogeyB2OiB1bmtub3duIH0gPSB7IHY6IHN0cnVjdHVyZWRDbG9uZShfZ2V0KHRoaXMuYmFzZVNuYXBzaG90LCByb290U2VnbWVudHMpKSB9O1xuICAgIGZvciAoY29uc3Qgb3Agb2Ygb3BzKSB7XG4gICAgICBjb25zdCBzZWdtZW50cyA9IG9wLnBhdGguc3BsaXQoREVMSU0pO1xuICAgICAgY29uc3QgYXQgPSBbJ3YnLCAuLi5zZWdtZW50cy5zbGljZShyb290U2VnbWVudHMubGVuZ3RoKV07XG4gICAgICBpZiAob3AudmVyYiA9PT0gJ21lcmdlJykge1xuICAgICAgICBfc2V0KGJveCwgYXQsIGRlZXBTbWFydE1lcmdlKF9nZXQoYm94LCBhdCkgPz8ge30sIHN0cnVjdHVyZWRDbG9uZShfZ2V0KHRoaXMudXBkYXRlUGF0Y2gsIHNlZ21lbnRzKSkpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIF9zZXQoYm94LCBhdCwgc3RydWN0dXJlZENsb25lKF9nZXQodGhpcy5vdmVyd3JpdGVQYXRjaCwgc2VnbWVudHMpKSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBib3gudjtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYXkgYSBzdGFnZWQgYGRlbGV0ZWAgYXQgdGhpcyBwYXRoIGNvbW1pdCBhcyB0aGUgYCdkZWxldGUnYCB2ZXJiP1xuICAgKlxuICAgKiBPbmx5IHdoZW4gcmVtb3ZpbmcgdGhlIGtleSBhbmQgdGhlIGAnZnVsbCdgIG1vZGUncyBmbGF0dGVuaW5nIChgX3NldGAgb2ZcbiAgICogYHVuZGVmaW5lZGApIGxhbmQgaW4gdGhlIHNhbWUgcGxhY2UuIFRoZXkgZGl2ZXJnZSB3aGVuIHRoZSBwYXJlbnQgaXMgbm90XG4gICAqIGEgY29udGFpbmVyOiBgbmF0aXZlRGVsZXRlYCB3YWxrcyBhd2F5IHVudG91Y2hlZCwgd2hpbGUgYG5hdGl2ZVNldGBcbiAgICogQ09FUkNFUyB0aGUgcHJpbWl0aXZlIHBhcmVudCBpbnRvIGFuIG9iamVjdCB0byBob2xkIHRoZSBrZXkuIENvbW1pdHRpbmdcbiAgICogYGRlbGV0ZWAgdGhlcmUgd291bGQgc2lsZW50bHkgZHJvcCBhIHN0YXRlIGNoYW5nZSB0aGUgc3RhZ2UgcmVhbGx5IG1hZGUsXG4gICAqIHNvIHRob3NlIChwYXRob2xvZ2ljYWwpIGRlbGV0ZXMga2VlcCB0aGUgaGlzdG9yaWNhbCBmbGF0dGVuaW5nLlxuICAgKi9cbiAgcHJpdmF0ZSBkZWxldGVSZXBsYXlzQXNGbGF0dGVuaW5nKHNlZ21lbnRzOiBzdHJpbmdbXSk6IGJvb2xlYW4ge1xuICAgIGlmIChzZWdtZW50cy5sZW5ndGggPT09IDEpIHJldHVybiB0cnVlOyAvLyBwYXJlbnQgaXMgdGhlIHN0YXRlIHJvb3Qg4oCUIGFsd2F5cyBhIGNvbnRhaW5lclxuICAgIGNvbnN0IHBhcmVudCA9IF9nZXQodGhpcy5iYXNlU25hcHNob3QsIHNlZ21lbnRzLnNsaWNlKDAsIC0xKSk7XG4gICAgcmV0dXJuIHBhcmVudCAhPT0gbnVsbCAmJiB0eXBlb2YgcGFyZW50ID09PSAnb2JqZWN0JztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYXkgT05FIHBhdGgncyBvcC12ZXJiIHNlcXVlbmNlIGFnYWluc3QgaXRzIGJhc2UgdmFsdWUsIGV4YWN0bHkgdGhlXG4gICAqIHdheSBgYXBwbHlTbWFydE1lcmdlYCByZXBsYXlzIHRoZSBjb3JyZXNwb25kaW5nIGZ1bGwtbW9kZSBidW5kbGU6IGV2ZXJ5XG4gICAqIGBzZXRgL2BkZWxldGVgIHBvc2l0aW9uIGFwcGxpZXMgdGhlIExBU1Qgc3RhZ2VkIG92ZXJ3cml0ZSB2YWx1ZSAodGhlXG4gICAqIGJhZyBob2xkcyBvbmUgdmFsdWUgcGVyIHBhdGgg4oCUIGxhc3Qgd3JpdGVyIHdpbnMpLCBldmVyeSBgbWVyZ2VgXG4gICAqIHBvc2l0aW9uIGFwcGxpZXMgdGhlIEFDQ1VNVUxBVEVEIGB1cGRhdGVQYXRjaGAgZGVsdGEuIFRoaXMgcmVwcm9kdWNlc1xuICAgKiB0aGUgZnVsbCBtb2RlJ3MgY29tbWl0dGVkIHZhbHVlIGZvciBhbnkgaW50ZXJsZWF2aW5nIOKAlCBpbmNsdWRpbmcgdGhlXG4gICAqIG1peGVkIHNldCttZXJnZSBxdWlyayB3aGVyZSB0aGUgYWNjdW11bGF0ZWQgZGVsdGEgcmUtYXBwbGllcyBwcmUtc2V0XG4gICAqIG1lcmdlIGtleXMgKGZ1bGwtbW9kZSByZXBsYXkgc2VtYW50aWNzLCBrZXB0IGZvciBieXRlLXBhcml0eSBhY3Jvc3NcbiAgICogbW9kZXM7IHByb3BlcnR5LXRlc3RlZCBpbiBkZWx0YS1yZXBsYXktZXF1aXZhbGVuY2UpLlxuICAgKi9cbiAgcHJpdmF0ZSByZXBsYXlQYXRoVmVyYnMoYmVmb3JlOiB1bmtub3duLCBzZWdtZW50czogc3RyaW5nW10sIHZlcmJzOiBPcFZlcmJbXSk6IHVua25vd24ge1xuICAgIGNvbnN0IHNldFZhbHVlID0gX2dldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBzZWdtZW50cyk7XG4gICAgY29uc3QgbWVyZ2VEZWx0YSA9IF9nZXQodGhpcy51cGRhdGVQYXRjaCwgc2VnbWVudHMpO1xuICAgIGxldCB2YWx1ZTogdW5rbm93biA9IGJlZm9yZTtcbiAgICBmb3IgKGNvbnN0IHZlcmIgb2YgdmVyYnMpIHtcbiAgICAgIHZhbHVlID0gdmVyYiA9PT0gJ21lcmdlJyA/IGRlZXBTbWFydE1lcmdlKHZhbHVlID8/IHt9LCBtZXJnZURlbHRhKSA6IHNldFZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBBcHBlbmQtZGV0ZWN0aW9uIHByZWRpY2F0ZSAoIzEzYy1CIMKnMi4yKTogYm90aCB2YWx1ZXMgYXJlIGFycmF5cywgdGhlXG4gKiBmaW5hbCBpcyBzdHJpY3RseSBsb25nZXIsIGFuZCB0aGUgYmFzZSBpcyBhIHN0cnVjdHVyYWwgcHJlZml4IG9mIHRoZVxuICogZmluYWwuIEVsZW1lbnQgY29tcGFyZXMgc2hvcnQtY2lyY3VpdCBvbiByZWZlcmVuY2UgaWRlbnRpdHkgKGBkZWVwRXF1YWxgJ3NcbiAqIGA9PT1gIGZhc3QgcGF0aCkgYmVmb3JlIHdhbGtpbmcgc3RydWN0dXJlLCBhbmQgYmFpbCBhdCB0aGUgZmlyc3QgbWlzbWF0Y2hcbiAqIOKAlCB3b3JzdCBjYXNlIG9uZSBzdHJ1Y3R1cmFsIGNvbXBhcmUgb2YgdGhlIGJhc2UgYXJyYXksIHN0cmljdGx5IGNoZWFwZXJcbiAqIHRoYW4gdGhlIGZ1bGwtdmFsdWUgYHN0cnVjdHVyZWRDbG9uZWAgdGhlIGZhbGxiYWNrIHBheXMuXG4gKlxuICogYGJlZm9yZSA9PT0gdW5kZWZpbmVkYCAoZmlyc3Qgd3JpdGUpIGZhaWxzIGBBcnJheS5pc0FycmF5YCDihpIgYHNldGAsIHdoaWNoXG4gKiBrZWVwcyB0aGUgZmlyc3Qgd3JpdGUgYXMgdGhlIGNhdXNhbCBhbmNob3IgZm9yIFwid2hvIGluaXRpYWxpemVkIHRoaXMga2V5XCIuXG4gKlxuICogQk9USCBhcnJheXMgbXVzdCBhbHNvIGJlIHBsYWluIGFuZCBkZW5zZSAoe0BsaW5rIGlzSW5kZXhPbmx5fSk6IHJlcGxheVxuICogcmVjb25zdHJ1Y3RzIGFuIGFwcGVuZCBhcyBgWy4uLmN1cnJlbnQsIC4uLnRhaWxdYCwgYW5kIHRoYXQgc3ByZWFkIGNhcnJpZXNcbiAqIE9OTFkgaW5kZXhlZCBlbGVtZW50cyDigJQgYSBuYW1lZCBwcm9wZXJ0eSBwYXJrZWQgb24gYW4gYXJyYXkgKGEgbmVzdGVkIHdyaXRlXG4gKiBsaWtlIGBzZXQoWydoaXN0b3J5Jywnbm90ZSddLCDigKYpYCwgd2hpY2ggYG5hdGl2ZVNldGAgaGFwcGlseSBoYW5ncyBvZmYgdGhlXG4gKiBhcnJheSBvYmplY3QpIG9yIGEgaG9sZSB3b3VsZCBiZSBzaWxlbnRseSBkcm9wcGVkLCB3aGVyZSBgJ2Z1bGwnYCBtb2RlXG4gKiBzdG9yZXMgdGhlIHZhbHVlIHdob2xlIGFuZCBrZWVwcyBpdC5cbiAqL1xuZnVuY3Rpb24gaXNTdHJpY3RBcnJheVByZWZpeChiZWZvcmU6IHVua25vd24sIGFmdGVyOiB1bmtub3duKTogYmVmb3JlIGlzIHVua25vd25bXSB7XG4gIGlmICghQXJyYXkuaXNBcnJheShiZWZvcmUpIHx8ICFBcnJheS5pc0FycmF5KGFmdGVyKSkgcmV0dXJuIGZhbHNlO1xuICBpZiAoYWZ0ZXIubGVuZ3RoIDw9IGJlZm9yZS5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBiZWZvcmUubGVuZ3RoOyBpKyspIHtcbiAgICBpZiAoIWRlZXBFcXVhbChiZWZvcmVbaV0sIGFmdGVyW2ldKSkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiBpc0luZGV4T25seShiZWZvcmUpICYmIGlzSW5kZXhPbmx5KGFmdGVyKTtcbn1cblxuLyoqIFRydWUgd2hlbiBhbiBhcnJheSdzIG93biBlbnVtZXJhYmxlIGtleXMgYXJlIGV4YWN0bHkgaXRzIGluZGljZXMg4oCUIG5vXG4gKiAgZXh0cmEgbmFtZWQgcHJvcGVydGllcyBhbmQgbm8gaG9sZXMsIGkuZS4gdGhlIGFycmF5IHN1cnZpdmVzIGEgc3ByZWFkXG4gKiAgaW50YWN0LiBPbmUgYE9iamVjdC5rZXlzYCBwYXNzLCBzYW1lIG9yZGVyIGFzIHRoZSBwcmVmaXggY29tcGFyZSBhYm92ZVxuICogIGFuZCBwYWlkIG9ubHkgYWZ0ZXIgaXQgc3VjY2VlZHMuICovXG5mdW5jdGlvbiBpc0luZGV4T25seShhcnI6IHVua25vd25bXSk6IGJvb2xlYW4ge1xuICByZXR1cm4gT2JqZWN0LmtleXMoYXJyKS5sZW5ndGggPT09IGFyci5sZW5ndGg7XG59XG4iXX0=
@@ -111,6 +111,9 @@ export type CombinedRecorder = Partial<Omit<ScopeRecorder, SharedLifecycleOverla
111
111
  description?: string;
112
112
  preferredOperation?: 'translate' | 'accumulate' | 'aggregate';
113
113
  data: unknown;
114
+ /** Machine-readable facts about the bundle itself — see
115
+ * {@link import('../runner/ExecutionRuntime.js').RecorderSnapshot.meta}. */
116
+ meta?: Readonly<Record<string, unknown>>;
114
117
  };
115
118
  onError?(event: ErrorEvent | FlowErrorEvent): void;
116
119
  onPause?(event: PauseEvent | FlowPauseEvent): void;