footprintjs 8.2.0 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,12 +1,15 @@
1
1
  /**
2
2
  * FlowchartTraverser — Pre-order DFS traversal of StageNode graph.
3
3
  *
4
- * Unified traversal algorithm for all node shapes:
5
- * const pre = await prep();
6
- * const [x, y] = await Promise.all([fx(pre), fy(pre)]);
7
- * return await next(x, y);
4
+ * Unified traversal algorithm for all node shapes. `executeNode` is a
5
+ * TRAMPOLINE driver: it runs `executeNodeStep` (one node, all 7 phases) in
6
+ * a flat loop, following tail continuations (linear `next`, loop edges,
7
+ * dynamic next, flat decider dispatch) iteratively — so chain length and
8
+ * loop iterations never grow the call stack. Only true tree nesting (fork
9
+ * children, with-continuation decider/selector branches, subflow mounts)
10
+ * recurses.
8
11
  *
9
- * For each node, executeNode follows 7 phases:
12
+ * For each node, executeNodeStep follows 7 phases:
10
13
  * 0. CLASSIFY — subflow detection, early delegation
11
14
  * 1. VALIDATE — node invariants, role markers
12
15
  * 2. EXECUTE — run stage fn, commit, break check
@@ -33,6 +36,15 @@ import { FlowRecorderDispatcher } from '../narrative/FlowRecorderDispatcher.js';
33
36
  import { NarrativeFlowRecorder } from '../narrative/NarrativeFlowRecorder.js';
34
37
  import { NullControlFlowNarrativeGenerator } from '../narrative/NullControlFlowNarrativeGenerator.js';
35
38
  import { buildRuntimeStageId } from '../runtimeStageId.js';
39
+ /**
40
+ * Trampoline brand — marks a continuation hop returned by `executeNodeStep`
41
+ * to the driver loop in `executeNode`. Module-private symbol so a stage's own
42
+ * return value (which can be any object) can never be mistaken for a hop.
43
+ */
44
+ const CONTINUE_HOP = Symbol('footprintjs.executeNode.continue');
45
+ function isContinuationHop(value) {
46
+ return typeof value === 'object' && value !== null && value[CONTINUE_HOP] === true;
47
+ }
36
48
  export class FlowchartTraverser {
37
49
  root;
38
50
  stageMap;
@@ -69,11 +81,41 @@ export class FlowchartTraverser {
69
81
  */
70
82
  resolvedLazySubflows = new Set();
71
83
  /**
72
- * Recursion depth counter for executeNode.
73
- * Each recursive executeNode call increments this; decrements on exit (try/finally).
74
- * Prevents call-stack overflow on infinite loops or excessively deep stage chains.
84
+ * Per-traverser overlay of dynamic StageNode returns, keyed by `node.id`.
85
+ * Phase 4 writes patches HERE instead of mutating the shared built-chart
86
+ * node objects (same isolation convention as `resolvedLazySubflows`).
87
+ * All engine reads of the patched fields go through the `eff*` accessors
88
+ * below. The map dies with the traverser — one run, one overlay — so a
89
+ * fresh executor over the same built chart always sees the original graph.
90
+ *
91
+ * Keyed by the node OBJECT (WeakMap), not `node.id`: a dynamic child that
92
+ * reuses a built node's id must NOT make the built node inherit the patch
93
+ * (id-keyed lookup caused phantom double-execution). `patchCount` is the
94
+ * fast-path check — WeakMap has no `size`.
95
+ */
96
+ dynamicPatches = new WeakMap();
97
+ patchCount = 0;
98
+ /**
99
+ * TREE-nesting depth counter for executeNode (the trampoline driver).
100
+ * Each driver invocation increments this; decrements on exit (try/finally).
101
+ *
102
+ * Linear `next` chains, loop edges, and dynamic continuations are followed
103
+ * ITERATIVELY inside one driver invocation, so they never grow this
104
+ * counter. Only true tree recursion does: fork children, decider/selector
105
+ * branch dispatch (when the decider has its own continuation), and
106
+ * unbounded dynamic recursion. Prevents call-stack overflow on runaway
107
+ * recursive composition.
75
108
  */
76
109
  _executeDepth = 0;
110
+ /**
111
+ * Memoized parent-chain depth per StageContext. The context tree deepens
112
+ * by one per executed stage along a chain, so the naive parent-walk in
113
+ * `computeContextDepth` is O(chain length) per stage — O(n²) per run once
114
+ * the trampoline allows chains of tens of thousands of stages. Contexts
115
+ * are visited parent-before-child, so the memo makes each lookup O(1)
116
+ * amortized. WeakMap — dies with the traverser.
117
+ */
118
+ contextDepthCache = new WeakMap();
77
119
  /**
78
120
  * Shared mutable execution counter — monotonic, incremented per stage execution.
79
121
  * Shared with child traversers (subflows) so indices are globally unique within a run.
@@ -84,18 +126,26 @@ export class FlowchartTraverser {
84
126
  */
85
127
  _maxDepth;
86
128
  /**
87
- * Default maximum recursive executeNode depth before an error is thrown.
88
- * 500 comfortably covers any realistic pipeline depth (including deeply nested
89
- * subflows) while preventing call-stack overflow (~10 000 frames in V8).
129
+ * Per-instance loop-iteration limit forwarded to the ContinuationResolver
130
+ * and propagated to subflow traversers. Undefined resolver default (1000).
131
+ */
132
+ _maxIterations;
133
+ /**
134
+ * Default maximum nested executeNode depth before an error is thrown.
90
135
  *
91
- * **Note on counting:** the counter increments once per `executeNode` call, not once per
92
- * logical user stage. Subflow root entry and subflow continuation after return each cost
93
- * one tick. For pipelines with many nested subflows, budget roughly 2 × (avg stages per
94
- * subflow) of headroom when computing a custom `maxDepth` via `RunOptions.maxDepth`.
136
+ * **What counts as depth (trampoline model):** `executeNode` is an iterative
137
+ * driver linear `next` hops, loop edges (`loopTo`/dynamic next), and
138
+ * dynamic-subflow re-entry are followed in a flat loop and consume NO depth.
139
+ * Depth grows only with true tree nesting: one tick per fork child, one per
140
+ * decider/selector branch dispatch that must return to its invoker (decider
141
+ * with its own `next`), one per subflow mount frame in the parent (the
142
+ * subflow body itself runs on a FRESH traverser with its own budget).
95
143
  *
96
- * **Note on loops:** for `loopTo()` pipelines, this depth guard and `ContinuationResolver`'s
97
- * iteration limit are independent the lower one fires first. The default depth guard (500)
98
- * fires before the default iteration limit (1000) for loop-heavy pipelines.
144
+ * 500 therefore covers any realistic chart it bounds recursive
145
+ * COMPOSITION, not chain length or loop count. Loops are bounded by
146
+ * `ContinuationResolver`'s independent iteration limit (default 1000,
147
+ * configurable via `RunOptions.maxIterations`), which is now the binding
148
+ * constraint for loop-heavy pipelines.
99
149
  *
100
150
  * @remarks Not safe for concurrent `.execute()` calls on the same instance — concurrent
101
151
  * executions race on `_executeDepth`. Use a separate `FlowchartTraverser` per concurrent
@@ -107,6 +157,10 @@ export class FlowchartTraverser {
107
157
  if (maxDepth < 1)
108
158
  throw new Error('FlowchartTraverser: maxDepth must be >= 1');
109
159
  this._maxDepth = maxDepth;
160
+ if (opts.maxIterations !== undefined && opts.maxIterations < 1) {
161
+ throw new Error('FlowchartTraverser: maxIterations must be >= 1');
162
+ }
163
+ this._maxIterations = opts.maxIterations;
110
164
  this._executionCounter = opts.executionCounter ?? { value: 0 };
111
165
  this.root = opts.root;
112
166
  // Shallow-copy stageMap and subflows so that lazy-resolution mutations
@@ -152,11 +206,14 @@ export class FlowchartTraverser {
152
206
  const deps = this.createDeps(opts);
153
207
  // Build O(1) node ID map from the root graph (avoids repeated DFS on every loopTo())
154
208
  const nodeIdMap = this.buildNodeIdMap(opts.root);
155
- // Initialize handler modules
156
- this.nodeResolver = new NodeResolver(deps, nodeIdMap);
209
+ // Initialize handler modules.
210
+ // NodeResolver's DFS fallback resolves loop targets against the LIVE
211
+ // runtime shape, so it reads children through the dynamic-patch overlay
212
+ // (a loop can target a node added by a dynamic StageNode return).
213
+ this.nodeResolver = new NodeResolver(deps, nodeIdMap, (n) => this.effChildren(n));
157
214
  this.childrenExecutor = new ChildrenExecutor(deps, this.executeNode.bind(this));
158
215
  this.stageRunner = new StageRunner(deps);
159
- this.continuationResolver = new ContinuationResolver(deps, this.nodeResolver, (nodeId, count) => this.structureManager.updateIterationCount(nodeId, count));
216
+ this.continuationResolver = new ContinuationResolver(deps, this.nodeResolver, (nodeId, count) => this.structureManager.updateIterationCount(nodeId, count), this._maxIterations);
160
217
  this.deciderHandler = new DeciderHandler(deps);
161
218
  this.selectorHandler = new SelectorHandler(deps, this.childrenExecutor);
162
219
  this.subflowExecutor = new SubflowExecutor(deps, this.createSubflowTraverserFactory(opts));
@@ -189,6 +246,7 @@ export class FlowchartTraverser {
189
246
  logger: parentOpts.logger,
190
247
  signal: parentOpts.signal,
191
248
  maxDepth: this._maxDepth,
249
+ ...(this._maxIterations !== undefined && { maxIterations: this._maxIterations }),
192
250
  parentSubflowId: subflowOpts.subflowId,
193
251
  executionCounter: this._executionCounter, // Share counter — subflow continues global numbering
194
252
  runId: this.runId, // Subflow inherits parent's runId — same logical run
@@ -326,26 +384,30 @@ export class FlowchartTraverser {
326
384
  /**
327
385
  * Build an O(1) ID→node map from the root graph.
328
386
  * Used by NodeResolver to avoid repeated DFS on every loopTo() call.
329
- * Depth-guarded at MAX_EXECUTE_DEPTH to prevent infinite recursion on cyclic graphs.
387
+ * Iterative worklist (no recursion) so arbitrarily long chains index fully;
388
+ * the `map.has` guard handles cyclic refs. First-visited node wins per ID —
389
+ * worklist order matches the old recursive pre-order (children, then next).
330
390
  * Dynamic subflows and lazy-resolved nodes are added to stageMap at runtime but not to this map —
331
391
  * those use the DFS fallback in NodeResolver.
332
392
  */
333
393
  buildNodeIdMap(root) {
334
394
  const map = new Map();
335
- const visit = (node, depth) => {
336
- if (depth > FlowchartTraverser.MAX_EXECUTE_DEPTH)
337
- return;
395
+ const stack = [root];
396
+ while (stack.length > 0) {
397
+ const node = stack.pop();
338
398
  if (map.has(node.id))
339
- return; // already visited (avoids infinite loops on cyclic refs)
399
+ continue; // already visited (avoids infinite loops on cyclic refs)
340
400
  map.set(node.id, node);
401
+ // Push in reverse visit order (LIFO stack): next first, then children
402
+ // reversed — so children are visited before next, first child first,
403
+ // matching the recursive pre-order exactly.
404
+ if (node.next)
405
+ stack.push(node.next);
341
406
  if (node.children) {
342
- for (const child of node.children)
343
- visit(child, depth + 1);
407
+ for (let i = node.children.length - 1; i >= 0; i--)
408
+ stack.push(node.children[i]);
344
409
  }
345
- if (node.next)
346
- visit(node.next, depth + 1);
347
- };
348
- visit(root, 0);
410
+ }
349
411
  return map;
350
412
  }
351
413
  getStageFn(node) {
@@ -358,323 +420,490 @@ export class FlowchartTraverser {
358
420
  // Fallback: look up by name (supports hand-crafted stageMaps in tests and advanced use)
359
421
  return this.stageMap.get(node.name);
360
422
  }
423
+ // ─────────────── Dynamic-patch overlay accessors ───────────────
424
+ //
425
+ // Every engine read of a field that Phase 4 can patch (children,
426
+ // nextNodeSelector, subflow meta) goes through these. Fast path: charts
427
+ // with no dynamic returns never allocate and pay one `size === 0` check.
428
+ getPatch(node) {
429
+ if (this.patchCount === 0)
430
+ return undefined;
431
+ return this.dynamicPatches.get(node);
432
+ }
433
+ getOrCreatePatch(node) {
434
+ let patch = this.dynamicPatches.get(node);
435
+ if (!patch) {
436
+ patch = {};
437
+ this.dynamicPatches.set(node, patch);
438
+ this.patchCount++;
439
+ }
440
+ return patch;
441
+ }
442
+ /** Effective children: dynamic patch first, then the built node's children. */
443
+ effChildren(node) {
444
+ return this.getPatch(node)?.children ?? node.children;
445
+ }
446
+ /** Effective output-based selector: dynamic patch first, then the built node's. */
447
+ effSelector(node) {
448
+ return this.getPatch(node)?.nextNodeSelector ?? node.nextNodeSelector;
449
+ }
450
+ /** Effective subflow-root marker (true when a dynamic subflow was patched on). */
451
+ effIsSubflowRoot(node) {
452
+ const meta = this.getPatch(node)?.subflowMeta;
453
+ return meta ? true : node.isSubflowRoot;
454
+ }
455
+ /** Effective subflow id (patched verbatim by a dynamic subflow return). */
456
+ effSubflowId(node) {
457
+ const meta = this.getPatch(node)?.subflowMeta;
458
+ return meta ? meta.subflowId : node.subflowId;
459
+ }
460
+ /**
461
+ * Materialize the effective view of a node — field-identical to what the
462
+ * pre-overlay code produced by mutating the shared node. Used where a node
463
+ * is handed to a helper executor (NodeResolver / SubflowExecutor /
464
+ * ChildrenExecutor) so helpers never read stale built fields. Returns the
465
+ * node itself (no allocation) when it carries no patch.
466
+ */
467
+ effNode(node) {
468
+ const patch = this.getPatch(node);
469
+ if (!patch)
470
+ return node;
471
+ const merged = { ...node };
472
+ if (patch.subflowMeta) {
473
+ merged.isSubflowRoot = true;
474
+ merged.subflowId = patch.subflowMeta.subflowId;
475
+ merged.subflowName = patch.subflowMeta.subflowName;
476
+ merged.subflowMountOptions = patch.subflowMeta.subflowMountOptions;
477
+ }
478
+ if (patch.children)
479
+ merged.children = patch.children;
480
+ if (patch.nextNodeSelector)
481
+ merged.nextNodeSelector = patch.nextNodeSelector;
482
+ return merged;
483
+ }
361
484
  async executeStage(node, stageFunc, context, breakFn) {
362
485
  // runtimeStageId is assigned in executeNode() before traversalContext creation,
363
486
  // ensuring scope events and flow events use the same value.
364
487
  return this.stageRunner.run(node, stageFunc, context, breakFn);
365
488
  }
366
489
  /**
367
- * Pre-order DFS traversal the core algorithm.
368
- * Each call processes one node through all 7 phases.
490
+ * Trampoline driver — pre-order DFS traversal entry point.
491
+ *
492
+ * Runs `executeNodeStep` (one node, all 7 phases) in a flat loop: every
493
+ * TAIL continuation (linear `next`, loop edge, dynamic next / dynamic
494
+ * re-entry, no-continuation decider dispatch) comes back as a
495
+ * `ContinuationHop` and is followed ITERATIVELY — neither the call stack
496
+ * nor the retained promise chain grows with chain length or loop count.
497
+ *
498
+ * Recursion remains ONLY for true tree nesting (each gets a nested driver
499
+ * call): fork children (`ChildrenExecutor`), selector branches (parallel
500
+ * fan-out), decider branch dispatch when the decider has its own `next`
501
+ * (the branch must complete BEFORE the decider's continuation runs), and
502
+ * subflow mounts (fresh traverser; the mount frame stays in the parent).
503
+ * `_executeDepth` therefore counts chart COMPOSITION depth only, guarded
504
+ * by `_maxDepth` (default `MAX_EXECUTE_DEPTH` = 500).
505
+ *
506
+ * PauseSignal: a flat decider dispatch records an `InvokerStamp`; if the
507
+ * continued chain later pauses, the driver stamps the signal during
508
+ * unwind — same invoker context the recursive dispatch's catch used to
509
+ * stamp, innermost (most recent dispatch) first.
369
510
  */
370
511
  async executeNode(node, context, breakFlag, branchPath) {
371
- // ─── Recursion depth guard ───
372
- // Each `await executeNode(...)` keeps the calling frame on the stack.
373
- // Without a cap, an infinite loop or an excessively deep stage chain will
374
- // eventually overflow the V8 call stack (~10 000 frames) with a cryptic
375
- // "Maximum call stack size exceeded" error. We fail early with a clear
376
- // message so users can diagnose the cause (infinite loop, missing break, etc.).
377
- // The increment is inside `try` so `finally` always decrements — no fragile
378
- // gap between check and try entry.
512
+ // Invoker stamps from flat decider dispatches in THIS driver — kept
513
+ // local so nested drivers (fork children, with-next decider branches)
514
+ // get their own windows, matching the old frame-on-stack stamping scope.
515
+ let pendingInvokers;
516
+ // ─── Tree-depth guard ───
517
+ // The increment is inside `try` so `finally` always decrements no
518
+ // fragile gap between check and try entry.
379
519
  try {
380
520
  if (++this._executeDepth > this._maxDepth) {
381
521
  throw new Error(`FlowchartTraverser: maximum traversal depth exceeded (${this._maxDepth}). ` +
382
- 'Check for infinite loops or missing break conditions in your flowchart. ' +
522
+ 'Depth counts NESTED dispatch (fork children, decider/selector branches, recursive composition) ' +
523
+ 'linear chains and loop iterations run flat and do not consume it. ' +
383
524
  `Last stage: '${node.name}'. ` +
384
- 'For loopTo() pipelines, consider adding a break condition or using RunOptions.maxDepth to raise the limit.');
525
+ 'Check for unbounded recursive chart composition, or raise the limit via RunOptions.maxDepth.');
385
526
  }
386
- // Attach builder metadata to context for snapshot enrichment
387
- if (node.description)
388
- context.description = node.description;
389
- if (node.isSubflowRoot && node.subflowId)
390
- context.subflowId = node.subflowId;
391
- // Assign runtimeStageId BEFORE traversalContext creation — ensures scope events
392
- // (buffered by runtimeStageId) and flow events (flushed by traversalContext.runtimeStageId)
393
- // use the same value. Must happen before executeStage AND before traversalContext.
394
- const idx = this._executionCounter.value++;
395
- context.runtimeStageId = buildRuntimeStageId(node.id, idx);
396
- // Build traversal context for recorder events — created once per stage, shared by all events
397
- const traversalContext = {
398
- runId: this.runId,
399
- stageId: node.id ?? context.stageId,
400
- runtimeStageId: context.runtimeStageId,
401
- stageName: node.name,
402
- parentStageId: context.parent?.stageId,
403
- subflowId: context.subflowId ?? this.parentSubflowId,
404
- subflowPath: branchPath || undefined,
405
- depth: this.computeContextDepth(context),
406
- };
407
- // ─── Phase 0a: LAZY RESOLVE — deferred subflow resolution ───
408
- // Guard uses the per-traverser resolvedLazySubflows set (not the shared node) so
409
- // concurrent traversers do not race on node.subflowResolver or clear it for each other.
410
- if (node.isSubflowRoot && node.subflowResolver && !this.resolvedLazySubflows.has(node.subflowId)) {
411
- const resolved = node.subflowResolver();
412
- const prefixedRoot = this.prefixNodeTree(resolved.root, node.subflowId);
413
- // Register the resolved subflow (same path as eager registration)
414
- this.subflows[node.subflowId] = { root: prefixedRoot };
415
- // Merge stageMap entries
416
- for (const [key, fn] of resolved.stageMap) {
417
- const prefixedKey = `${node.subflowId}/${key}`;
418
- if (!this.stageMap.has(prefixedKey)) {
419
- this.stageMap.set(prefixedKey, fn);
420
- }
421
- }
422
- // Merge nested subflows
423
- if (resolved.subflows) {
424
- for (const [key, def] of Object.entries(resolved.subflows)) {
425
- const prefixedKey = `${node.subflowId}/${key}`;
426
- if (!this.subflows[prefixedKey]) {
427
- this.subflows[prefixedKey] = def;
428
- }
429
- }
527
+ let current = { [CONTINUE_HOP]: true, node, context, branchPath };
528
+ for (;;) {
529
+ const result = await this.executeNodeStep(current.node, current.context, breakFlag, current.branchPath);
530
+ if (!isContinuationHop(result)) {
531
+ return result;
430
532
  }
431
- // Update runtime structure with the now-resolved spec
432
- this.structureManager.updateDynamicSubflow(node.id, node.subflowId, node.subflowName, resolved.buildTimeStructure);
433
- // Mark as resolved for THIS traverser — per-traverser set prevents re-entry
434
- // without mutating the shared StageNode graph (which would race concurrent traversers).
435
- this.resolvedLazySubflows.add(node.subflowId);
533
+ if (result.invokerStamp)
534
+ (pendingInvokers ??= []).push(result.invokerStamp);
535
+ current = result;
436
536
  }
437
- // ─── Phase 0: CLASSIFY — subflow detection ───
438
- if (node.isSubflowRoot && node.subflowId) {
439
- const resolvedNode = this.nodeResolver.resolveSubflowReference(node);
440
- const subflowOutput = await this.subflowExecutor.executeSubflow(resolvedNode, context, breakFlag, branchPath, this.subflowResults, traversalContext);
441
- const isReferenceBasedSubflow = resolvedNode !== node;
442
- const hasChildren = Boolean(node.children && node.children.length > 0);
443
- const shouldExecuteContinuation = isReferenceBasedSubflow || hasChildren;
444
- // ─── Break-flag check AFTER subflow returns ───
445
- // If the subflow was mounted with `propagateBreak: true` and broke
446
- // internally, `SubflowExecutor` has already flipped our breakFlag.
447
- // Stop the outer traversal here — do not run the next linear stage.
448
- if (breakFlag.shouldBreak) {
449
- return subflowOutput;
537
+ }
538
+ catch (error) {
539
+ // Replay invoker stamps most-recent-first. `setInvoker` is
540
+ // first-write-wins, so the innermost dispatch's stamp lands exactly
541
+ // the old bubble-up order through nested catch frames.
542
+ if (pendingInvokers !== undefined && isPauseSignal(error)) {
543
+ for (let i = pendingInvokers.length - 1; i >= 0; i--) {
544
+ error.setInvoker(pendingInvokers[i].invokerStageId, pendingInvokers[i].continuationStageId);
450
545
  }
451
- if (node.next && shouldExecuteContinuation) {
452
- const nextCtx = context.createNext(branchPath, node.next.name, node.next.id);
453
- return await this.executeNode(node.next, nextCtx, breakFlag, branchPath);
546
+ }
547
+ throw error;
548
+ }
549
+ finally {
550
+ this._executeDepth--;
551
+ }
552
+ }
553
+ /** Build a flat continuation hop for the driver loop. */
554
+ hop(node, context, branchPath, invokerStamp) {
555
+ return { [CONTINUE_HOP]: true, node, context, branchPath, ...(invokerStamp && { invokerStamp }) };
556
+ }
557
+ /**
558
+ * Execute ONE node through all 7 phases — the old recursive `executeNode`
559
+ * body; only the tail calls became `ContinuationHop` returns. Returns the
560
+ * node's result, or a hop for the driver loop to follow.
561
+ */
562
+ async executeNodeStep(node, context, breakFlag, branchPath) {
563
+ // Attach builder metadata to context for snapshot enrichment.
564
+ // Subflow meta reads go through the dynamic-patch overlay — a node
565
+ // patched by a dynamic-subflow return re-enters executeNode and must
566
+ // classify as a subflow without the shared node ever being mutated.
567
+ if (node.description)
568
+ context.description = node.description;
569
+ const effSubflowId = this.effSubflowId(node);
570
+ if (this.effIsSubflowRoot(node) && effSubflowId)
571
+ context.subflowId = effSubflowId;
572
+ // Assign runtimeStageId BEFORE traversalContext creation — ensures scope events
573
+ // (buffered by runtimeStageId) and flow events (flushed by traversalContext.runtimeStageId)
574
+ // use the same value. Must happen before executeStage AND before traversalContext.
575
+ const idx = this._executionCounter.value++;
576
+ context.runtimeStageId = buildRuntimeStageId(node.id, idx);
577
+ // Build traversal context for recorder events — created once per stage, shared by all events
578
+ const traversalContext = {
579
+ runId: this.runId,
580
+ stageId: node.id ?? context.stageId,
581
+ runtimeStageId: context.runtimeStageId,
582
+ stageName: node.name,
583
+ parentStageId: context.parent?.stageId,
584
+ subflowId: context.subflowId ?? this.parentSubflowId,
585
+ subflowPath: branchPath || undefined,
586
+ depth: this.computeContextDepth(context),
587
+ };
588
+ // ─── Phase 0a: LAZY RESOLVE — deferred subflow resolution ───
589
+ // Guard uses the per-traverser resolvedLazySubflows set (not the shared node) so
590
+ // concurrent traversers do not race on node.subflowResolver or clear it for each other.
591
+ if (node.isSubflowRoot && node.subflowResolver && !this.resolvedLazySubflows.has(node.subflowId)) {
592
+ const resolved = node.subflowResolver();
593
+ const prefixedRoot = this.prefixNodeTree(resolved.root, node.subflowId);
594
+ // Register the resolved subflow (same path as eager registration)
595
+ this.subflows[node.subflowId] = { root: prefixedRoot };
596
+ // Merge stageMap entries
597
+ for (const [key, fn] of resolved.stageMap) {
598
+ const prefixedKey = `${node.subflowId}/${key}`;
599
+ if (!this.stageMap.has(prefixedKey)) {
600
+ this.stageMap.set(prefixedKey, fn);
454
601
  }
455
- return subflowOutput;
456
602
  }
457
- const stageFunc = this.getStageFn(node);
458
- const hasStageFunction = Boolean(stageFunc);
459
- const isScopeBasedDecider = Boolean(node.deciderFn);
460
- const isScopeBasedSelector = Boolean(node.selectorFn);
461
- const isDeciderNode = isScopeBasedDecider;
462
- const hasChildren = Boolean(node.children?.length);
463
- const hasNext = Boolean(node.next);
464
- const originalNext = node.next;
465
- // ─── Phase 1: VALIDATE — node invariants ───
466
- if (!hasStageFunction && !isDeciderNode && !isScopeBasedSelector && !hasChildren) {
467
- const errorMessage = `Node '${node.name}' must define: embedded fn OR a stageMap entry OR have children/decider`;
468
- this.logger.error(`Error in pipeline (${branchPath}) stage [${node.name}]:`, { error: errorMessage });
469
- throw new Error(errorMessage);
603
+ // Merge nested subflows
604
+ if (resolved.subflows) {
605
+ for (const [key, def] of Object.entries(resolved.subflows)) {
606
+ const prefixedKey = `${node.subflowId}/${key}`;
607
+ if (!this.subflows[prefixedKey]) {
608
+ this.subflows[prefixedKey] = def;
609
+ }
610
+ }
470
611
  }
471
- if (isDeciderNode && !hasChildren) {
472
- const errorMessage = 'Decider node needs to have children to execute';
473
- this.logger.error(`Error in pipeline (${branchPath}) stage [${node.name}]:`, { error: errorMessage });
474
- throw new Error(errorMessage);
612
+ // Update runtime structure with the now-resolved spec
613
+ this.structureManager.updateDynamicSubflow(node.id, node.subflowId, node.subflowName, resolved.buildTimeStructure);
614
+ // Mark as resolved for THIS traverser per-traverser set prevents re-entry
615
+ // without mutating the shared StageNode graph (which would race concurrent traversers).
616
+ this.resolvedLazySubflows.add(node.subflowId);
617
+ }
618
+ // ─── Phase 0: CLASSIFY — subflow detection ───
619
+ if (this.effIsSubflowRoot(node) && effSubflowId) {
620
+ // Hand helpers the EFFECTIVE node view (built fields + dynamic patch)
621
+ // so SubflowExecutor/NodeResolver never read stale built fields.
622
+ const mountNode = this.effNode(node);
623
+ const resolvedNode = this.nodeResolver.resolveSubflowReference(mountNode);
624
+ const subflowOutput = await this.subflowExecutor.executeSubflow(resolvedNode, context, breakFlag, branchPath, this.subflowResults, traversalContext);
625
+ const isReferenceBasedSubflow = resolvedNode !== mountNode;
626
+ const hasChildren = Boolean(mountNode.children && mountNode.children.length > 0);
627
+ const shouldExecuteContinuation = isReferenceBasedSubflow || hasChildren;
628
+ // ─── Break-flag check AFTER subflow returns ───
629
+ // If the subflow was mounted with `propagateBreak: true` and broke
630
+ // internally, `SubflowExecutor` has already flipped our breakFlag.
631
+ // Stop the outer traversal here — do not run the next linear stage.
632
+ if (breakFlag.shouldBreak) {
633
+ return subflowOutput;
475
634
  }
476
- if (isScopeBasedSelector && !hasChildren) {
477
- const errorMessage = 'Selector node needs to have children to execute';
478
- this.logger.error(`Error in pipeline (${branchPath}) stage [${node.name}]:`, { error: errorMessage });
479
- throw new Error(errorMessage);
635
+ if (node.next && shouldExecuteContinuation) {
636
+ const nextCtx = context.createNext(branchPath, node.next.name, node.next.id);
637
+ return this.hop(node.next, nextCtx, branchPath);
480
638
  }
481
- // Role markers for debug panels
482
- if (!hasStageFunction) {
483
- if (isDeciderNode)
484
- context.setAsDecider();
485
- else if (hasChildren)
486
- context.setAsFork();
639
+ return subflowOutput;
640
+ }
641
+ const stageFunc = this.getStageFn(node);
642
+ const hasStageFunction = Boolean(stageFunc);
643
+ const isScopeBasedDecider = Boolean(node.deciderFn);
644
+ const isScopeBasedSelector = Boolean(node.selectorFn);
645
+ const isDeciderNode = isScopeBasedDecider;
646
+ const hasChildren = Boolean(this.effChildren(node)?.length);
647
+ // `next` is never overlaid — a dynamic next applies only to the visit
648
+ // that produced it (handled via the `dynamicNext` local below), so the
649
+ // built chart's next is always the correct continuation here.
650
+ const hasNext = Boolean(node.next);
651
+ const originalNext = node.next;
652
+ // ─── Phase 1: VALIDATE — node invariants ───
653
+ if (!hasStageFunction && !isDeciderNode && !isScopeBasedSelector && !hasChildren) {
654
+ const errorMessage = `Node '${node.name}' must define: embedded fn OR a stageMap entry OR have children/decider`;
655
+ this.logger.error(`Error in pipeline (${branchPath}) stage [${node.name}]:`, { error: errorMessage });
656
+ throw new Error(errorMessage);
657
+ }
658
+ if (isDeciderNode && !hasChildren) {
659
+ const errorMessage = 'Decider node needs to have children to execute';
660
+ this.logger.error(`Error in pipeline (${branchPath}) stage [${node.name}]:`, { error: errorMessage });
661
+ throw new Error(errorMessage);
662
+ }
663
+ if (isScopeBasedSelector && !hasChildren) {
664
+ const errorMessage = 'Selector node needs to have children to execute';
665
+ this.logger.error(`Error in pipeline (${branchPath}) stage [${node.name}]:`, { error: errorMessage });
666
+ throw new Error(errorMessage);
667
+ }
668
+ // Role markers for debug panels
669
+ if (!hasStageFunction) {
670
+ if (isDeciderNode)
671
+ context.setAsDecider();
672
+ else if (hasChildren)
673
+ context.setAsFork();
674
+ }
675
+ // Break handler wired to the scope. Captures the optional reason
676
+ // passed via `scope.$break(reason)` and parks it on the breakFlag so
677
+ // downstream code (FlowRecorder.onBreak, subflow propagation) can
678
+ // surface it. A second $break call in the same stage keeps the FIRST
679
+ // reason — first-break-wins — matching the "execution stopped" story.
680
+ const breakFn = (reason) => {
681
+ breakFlag.shouldBreak = true;
682
+ if (reason !== undefined && breakFlag.reason === undefined) {
683
+ breakFlag.reason = reason;
487
684
  }
488
- // Break handler wired to the scope. Captures the optional reason
489
- // passed via `scope.$break(reason)` and parks it on the breakFlag so
490
- // downstream code (FlowRecorder.onBreak, subflow propagation) can
491
- // surface it. A second $break call in the same stage keeps the FIRST
492
- // reason — first-break-wins — matching the "execution stopped" story.
493
- const breakFn = (reason) => {
494
- breakFlag.shouldBreak = true;
495
- if (reason !== undefined && breakFlag.reason === undefined) {
496
- breakFlag.reason = reason;
497
- }
498
- };
499
- // ─── Phase 2a: SELECTOR — scope-based multi-choice ───
500
- if (isScopeBasedSelector) {
501
- const selectorResult = await this.selectorHandler.handleScopeBased(node, stageFunc, context, breakFlag, branchPath, this.executeStage.bind(this), this.executeNode.bind(this), traversalContext);
502
- if (hasNext) {
503
- const nextCtx = context.createNext(branchPath, node.next.name, node.next.id);
504
- return await this.executeNode(node.next, nextCtx, breakFlag, branchPath);
505
- }
506
- return selectorResult;
685
+ };
686
+ // ─── Phase 2a: SELECTOR scope-based multi-choice ───
687
+ if (isScopeBasedSelector) {
688
+ const selectorResult = await this.selectorHandler.handleScopeBased(node, stageFunc, context, breakFlag, branchPath, this.executeStage.bind(this), this.executeNode.bind(this), traversalContext);
689
+ if (hasNext) {
690
+ const nextCtx = context.createNext(branchPath, node.next.name, node.next.id);
691
+ return this.hop(node.next, nextCtx, branchPath);
507
692
  }
508
- // ─── Phase 2b: DECIDER — scope-based single-choice conditional branch ───
509
- if (isDeciderNode) {
510
- const deciderResult = await this.deciderHandler.handleScopeBased(node, stageFunc, context, breakFlag, branchPath, this.executeStage.bind(this), this.executeNode.bind(this), traversalContext);
511
- // After branch execution, follow decider's own next (e.g., loopTo target)
512
- if (hasNext && !breakFlag.shouldBreak) {
513
- const nextNode = originalNext;
514
- // Use the isLoopRef flag set by loopTo() do not rely on stageMap absence,
515
- // since id-keyed stageMaps would otherwise cause loop targets to be executed directly.
516
- const isLoopRef = nextNode.isLoopRef === true ||
517
- (!this.getStageFn(nextNode) &&
518
- !nextNode.children?.length &&
519
- !nextNode.deciderFn &&
520
- !nextNode.selectorFn &&
521
- !nextNode.isSubflowRoot);
522
- if (isLoopRef) {
523
- return this.continuationResolver.resolve(nextNode, node, context, breakFlag, branchPath, this.executeNode.bind(this));
524
- }
525
- this.narrativeGenerator.onNext(node.name, nextNode.name, nextNode.description, traversalContext);
526
- const nextCtx = context.createNext(branchPath, nextNode.name, nextNode.id);
527
- return await this.executeNode(nextNode, nextCtx, breakFlag, branchPath);
528
- }
529
- return deciderResult;
693
+ return selectorResult;
694
+ }
695
+ // ─── Phase 2b: DECIDER scope-based single-choice conditional branch ───
696
+ if (isDeciderNode) {
697
+ const dispatch = await this.deciderHandler.prepareDispatch(node, stageFunc, context, breakFlag, branchPath, this.executeStage.bind(this), traversalContext);
698
+ // No decider-level continuation → the branch dispatch is a tail
699
+ // call. Hand it to the driver as a flat hop so loop-heavy decider
700
+ // charts (e.g. agent ReAct loops with branch-sourced `loopTo`) stay
701
+ // flat-stacked. The invoker stamp preserves PauseSignal semantics —
702
+ // the decider is the invoker of whatever pauses in the chain.
703
+ if (!hasNext && dispatch.kind === 'dispatch') {
704
+ return this.hop(dispatch.chosen, dispatch.branchContext, branchPath, {
705
+ invokerStageId: node.id,
706
+ continuationStageId: node.next?.id,
707
+ });
530
708
  }
531
- // ─── Abort check cooperative cancellation ───
532
- if (this.signal?.aborted) {
533
- const reason = this.signal.reason instanceof Error ? this.signal.reason : new Error(this.signal.reason ?? 'Aborted');
534
- throw reason;
709
+ // Decider WITH its own next: the branch chain must complete BEFORE
710
+ // the decider's continuation runs — true tree nesting, kept
711
+ // recursive (a nested driver). Mirrors handleScopeBased exactly,
712
+ // including the PauseSignal invoker stamp on bubble-up.
713
+ let deciderResult;
714
+ if (dispatch.kind === 'break') {
715
+ deciderResult = dispatch.branchId;
535
716
  }
536
- // ─── Phase 3: EXECUTE — run stage function ───
537
- let stageOutput;
538
- let dynamicNext;
539
- if (stageFunc) {
717
+ else {
540
718
  try {
541
- stageOutput = await this.executeStage(node, stageFunc, context, breakFn);
719
+ deciderResult = await this.executeNode(dispatch.chosen, dispatch.branchContext, breakFlag, branchPath);
542
720
  }
543
721
  catch (error) {
544
- // PauseSignal is expected control flow, not an error — fire narrative, commit, re-throw.
545
722
  if (isPauseSignal(error)) {
546
- context.commit();
547
- this.narrativeGenerator.onPause(node.name, node.id, error.pauseData, error.subflowPath, traversalContext);
548
- throw error;
723
+ error.setInvoker(node.id, node.next?.id);
549
724
  }
725
+ throw error;
726
+ }
727
+ }
728
+ // After branch execution, follow decider's own next (e.g., loopTo target)
729
+ if (hasNext && !breakFlag.shouldBreak) {
730
+ const nextNode = originalNext;
731
+ // Use the isLoopRef flag set by loopTo() — do not rely on stageMap absence,
732
+ // since id-keyed stageMaps would otherwise cause loop targets to be executed directly.
733
+ const isLoopRef = nextNode.isLoopRef === true ||
734
+ (!this.getStageFn(nextNode) &&
735
+ !this.effChildren(nextNode)?.length &&
736
+ !nextNode.deciderFn &&
737
+ !nextNode.selectorFn &&
738
+ !this.effIsSubflowRoot(nextNode));
739
+ if (isLoopRef) {
740
+ const target = this.continuationResolver.resolveTarget(nextNode, node, context, branchPath);
741
+ return this.hop(target.node, target.context, branchPath);
742
+ }
743
+ this.narrativeGenerator.onNext(node.name, nextNode.name, nextNode.description, traversalContext);
744
+ const nextCtx = context.createNext(branchPath, nextNode.name, nextNode.id);
745
+ return this.hop(nextNode, nextCtx, branchPath);
746
+ }
747
+ return deciderResult;
748
+ }
749
+ // ─── Abort check — cooperative cancellation ───
750
+ if (this.signal?.aborted) {
751
+ const reason = this.signal.reason instanceof Error ? this.signal.reason : new Error(this.signal.reason ?? 'Aborted');
752
+ throw reason;
753
+ }
754
+ // ─── Phase 3: EXECUTE — run stage function ───
755
+ let stageOutput;
756
+ let dynamicNext;
757
+ if (stageFunc) {
758
+ try {
759
+ stageOutput = await this.executeStage(node, stageFunc, context, breakFn);
760
+ }
761
+ catch (error) {
762
+ // PauseSignal is expected control flow, not an error — fire narrative, commit, re-throw.
763
+ if (isPauseSignal(error)) {
550
764
  context.commit();
551
- this.narrativeGenerator.onError(node.name, error.toString(), error, traversalContext);
552
- this.logger.error(`Error in pipeline (${branchPath}) stage [${node.name}]:`, { error });
553
- context.addError('stageExecutionError', error.toString());
765
+ this.narrativeGenerator.onPause(node.name, node.id, error.pauseData, error.subflowPath, traversalContext);
554
766
  throw error;
555
767
  }
556
768
  context.commit();
557
- this.narrativeGenerator.onStageExecuted(node.name, node.description, traversalContext, 'linear');
558
- if (breakFlag.shouldBreak) {
559
- // Forward the optional reason captured on breakFlag — set by the
560
- // stage's $break(reason) call OR by a subflow's propagateBreak.
561
- this.narrativeGenerator.onBreak(node.name, traversalContext, breakFlag.reason);
562
- return stageOutput;
769
+ this.narrativeGenerator.onError(node.name, error.toString(), error, traversalContext);
770
+ this.logger.error(`Error in pipeline (${branchPath}) stage [${node.name}]:`, { error });
771
+ context.addError('stageExecutionError', error.toString());
772
+ throw error;
773
+ }
774
+ context.commit();
775
+ this.narrativeGenerator.onStageExecuted(node.name, node.description, traversalContext, 'linear');
776
+ if (breakFlag.shouldBreak) {
777
+ // Forward the optional reason captured on breakFlag — set by the
778
+ // stage's $break(reason) call OR by a subflow's propagateBreak.
779
+ this.narrativeGenerator.onBreak(node.name, traversalContext, breakFlag.reason);
780
+ return stageOutput;
781
+ }
782
+ // ─── Phase 4: DYNAMIC — StageNode return detection ───
783
+ if (stageOutput && typeof stageOutput === 'object' && isStageNodeReturn(stageOutput)) {
784
+ const dynamicNode = stageOutput;
785
+ context.addLog('isDynamic', true);
786
+ context.addLog('dynamicPattern', 'StageNodeReturn');
787
+ // Dynamic subflow auto-registration. The subflow meta lands in the
788
+ // traverser-local overlay (NOT on the shared node); the immediate
789
+ // executeNode re-entry sees it through the eff* accessors and
790
+ // classifies the node as a subflow mount in Phase 0.
791
+ if (dynamicNode.isSubflowRoot && dynamicNode.subflowDef && dynamicNode.subflowId) {
792
+ context.addLog('dynamicPattern', 'dynamicSubflow');
793
+ context.addLog('dynamicSubflowId', dynamicNode.subflowId);
794
+ this.autoRegisterSubflowDef(dynamicNode.subflowId, dynamicNode.subflowDef, node.id);
795
+ this.getOrCreatePatch(node).subflowMeta = {
796
+ isSubflowRoot: true,
797
+ subflowId: dynamicNode.subflowId,
798
+ subflowName: dynamicNode.subflowName,
799
+ subflowMountOptions: dynamicNode.subflowMountOptions,
800
+ };
801
+ this.structureManager.updateDynamicSubflow(node.id, dynamicNode.subflowId, dynamicNode.subflowName, dynamicNode.subflowDef?.buildTimeStructure);
802
+ // Re-enter THIS node (same context): the overlay patch makes the
803
+ // next step classify it as a subflow mount in Phase 0.
804
+ return this.hop(node, context, branchPath);
563
805
  }
564
- // ─── Phase 4: DYNAMIC — StageNode return detection ───
565
- if (stageOutput && typeof stageOutput === 'object' && isStageNodeReturn(stageOutput)) {
566
- const dynamicNode = stageOutput;
567
- context.addLog('isDynamic', true);
568
- context.addLog('dynamicPattern', 'StageNodeReturn');
569
- // Dynamic subflow auto-registration
570
- if (dynamicNode.isSubflowRoot && dynamicNode.subflowDef && dynamicNode.subflowId) {
571
- context.addLog('dynamicPattern', 'dynamicSubflow');
572
- context.addLog('dynamicSubflowId', dynamicNode.subflowId);
573
- this.autoRegisterSubflowDef(dynamicNode.subflowId, dynamicNode.subflowDef, node.id);
574
- node.isSubflowRoot = true;
575
- node.subflowId = dynamicNode.subflowId;
576
- node.subflowName = dynamicNode.subflowName;
577
- node.subflowMountOptions = dynamicNode.subflowMountOptions;
578
- this.structureManager.updateDynamicSubflow(node.id, dynamicNode.subflowId, dynamicNode.subflowName, dynamicNode.subflowDef?.buildTimeStructure);
579
- return await this.executeNode(node, context, breakFlag, branchPath);
580
- }
581
- // Check children for subflowDef
582
- if (dynamicNode.children) {
583
- for (const child of dynamicNode.children) {
584
- if (child.isSubflowRoot && child.subflowDef && child.subflowId) {
585
- this.autoRegisterSubflowDef(child.subflowId, child.subflowDef, child.id);
586
- this.structureManager.updateDynamicSubflow(child.id, child.subflowId, child.subflowName, child.subflowDef?.buildTimeStructure);
587
- }
806
+ // Check children for subflowDef
807
+ if (dynamicNode.children) {
808
+ for (const child of dynamicNode.children) {
809
+ if (child.isSubflowRoot && child.subflowDef && child.subflowId) {
810
+ this.autoRegisterSubflowDef(child.subflowId, child.subflowDef, child.id);
811
+ this.structureManager.updateDynamicSubflow(child.id, child.subflowId, child.subflowName, child.subflowDef?.buildTimeStructure);
588
812
  }
589
813
  }
590
- // Dynamic children (fork pattern)
591
- if (dynamicNode.children && dynamicNode.children.length > 0) {
592
- node.children = dynamicNode.children;
593
- context.addLog('dynamicChildCount', dynamicNode.children.length);
594
- context.addLog('dynamicChildIds', dynamicNode.children.map((c) => c.id));
595
- this.structureManager.updateDynamicChildren(node.id, dynamicNode.children, Boolean(dynamicNode.nextNodeSelector), Boolean(dynamicNode.deciderFn));
596
- if (typeof dynamicNode.nextNodeSelector === 'function') {
597
- node.nextNodeSelector = dynamicNode.nextNodeSelector;
598
- context.addLog('hasSelector', true);
599
- }
600
- }
601
- // Dynamic next (linear continuation)
602
- if (dynamicNode.next) {
603
- dynamicNext = dynamicNode.next;
604
- this.structureManager.updateDynamicNext(node.id, dynamicNode.next);
605
- node.next = dynamicNode.next;
606
- context.addLog('hasDynamicNext', true);
607
- }
608
- stageOutput = undefined;
609
- }
610
- // Restore original next to avoid stale reference on loop revisit
611
- if (dynamicNext) {
612
- node.next = originalNext;
613
- }
614
- }
615
- // ─── Phase 5: CHILDREN — fork dispatch ───
616
- const hasChildrenAfterStage = Boolean(node.children?.length);
617
- if (hasChildrenAfterStage) {
618
- context.addLog('totalChildren', node.children?.length);
619
- context.addLog('orderOfExecution', 'ChildrenAfterStage');
620
- let nodeChildrenResults;
621
- if (node.nextNodeSelector) {
622
- nodeChildrenResults = await this.childrenExecutor.executeSelectedChildren(node.nextNodeSelector, node.children, stageOutput, context, branchPath, traversalContext, node.failFast);
623
- }
624
- else {
625
- const childCount = node.children?.length ?? 0;
626
- const childNames = node.children?.map((c) => c.name).join(', ');
627
- context.addFlowDebugMessage('children', `Executing all ${childCount} children in parallel: ${childNames}`, {
628
- count: childCount,
629
- targetStage: node.children?.map((c) => c.name),
630
- });
631
- nodeChildrenResults = await this.childrenExecutor.executeNodeChildren(node, context, undefined, branchPath, traversalContext);
632
814
  }
633
- // Fork-only: return bundle
634
- if (!hasNext && !dynamicNext) {
635
- return nodeChildrenResults;
815
+ // Dynamic children (fork pattern) — patched into the overlay;
816
+ // Phase 5 below reads them back through effChildren/effSelector.
817
+ if (dynamicNode.children && dynamicNode.children.length > 0) {
818
+ this.getOrCreatePatch(node).children = dynamicNode.children;
819
+ context.addLog('dynamicChildCount', dynamicNode.children.length);
820
+ context.addLog('dynamicChildIds', dynamicNode.children.map((c) => c.id));
821
+ this.structureManager.updateDynamicChildren(node.id, dynamicNode.children, Boolean(dynamicNode.nextNodeSelector), Boolean(dynamicNode.deciderFn));
822
+ if (typeof dynamicNode.nextNodeSelector === 'function') {
823
+ this.getOrCreatePatch(node).nextNodeSelector = dynamicNode.nextNodeSelector;
824
+ context.addLog('hasSelector', true);
825
+ }
636
826
  }
637
- // Capture dynamic children as synthetic subflow result for UI
638
- const isDynamic = context.debug?.logContext?.isDynamic;
639
- if (isDynamic && node.children && node.children.length > 0) {
640
- this.captureDynamicChildrenResult(node, context);
827
+ // Dynamic next (linear continuation) stays a LOCAL: it applies
828
+ // only to this visit (Phase 6 routes it through the
829
+ // ContinuationResolver), so the shared node's next is never touched
830
+ // and a loop revisit naturally sees the built continuation.
831
+ if (dynamicNode.next) {
832
+ dynamicNext = dynamicNode.next;
833
+ this.structureManager.updateDynamicNext(node.id, dynamicNode.next);
834
+ context.addLog('hasDynamicNext', true);
641
835
  }
836
+ stageOutput = undefined;
642
837
  }
643
- // ─── Phase 6: CONTINUE — dynamic next / linear next ───
644
- if (dynamicNext) {
645
- return this.continuationResolver.resolve(dynamicNext, node, context, breakFlag, branchPath, this.executeNode.bind(this));
838
+ }
839
+ // ─── Phase 5: CHILDREN — fork dispatch ───
840
+ // Re-read through the overlay: Phase 4 may have just patched dynamic
841
+ // children/selector for THIS visit (or an earlier visit in this run).
842
+ const childrenAfterStage = this.effChildren(node);
843
+ const hasChildrenAfterStage = Boolean(childrenAfterStage?.length);
844
+ if (hasChildrenAfterStage) {
845
+ context.addLog('totalChildren', childrenAfterStage?.length);
846
+ context.addLog('orderOfExecution', 'ChildrenAfterStage');
847
+ let nodeChildrenResults;
848
+ const effSelectorFn = this.effSelector(node);
849
+ if (effSelectorFn) {
850
+ nodeChildrenResults = await this.childrenExecutor.executeSelectedChildren(effSelectorFn, childrenAfterStage, stageOutput, context, branchPath, traversalContext, node.failFast);
646
851
  }
647
- if (hasNext) {
648
- const nextNode = originalNext;
649
- // Detect loop reference nodes created by loopTo() marked with isLoopRef flag.
650
- // Route through ContinuationResolver for proper ID resolution, iteration
651
- // tracking, and narrative generation.
652
- const isLoopReference = nextNode.isLoopRef;
653
- if (isLoopReference) {
654
- return this.continuationResolver.resolve(nextNode, node, context, breakFlag, branchPath, this.executeNode.bind(this), traversalContext);
655
- }
656
- this.narrativeGenerator.onNext(node.name, nextNode.name, nextNode.description, traversalContext);
657
- context.addFlowDebugMessage('next', `Moving to ${nextNode.name} stage`, {
658
- targetStage: nextNode.name,
852
+ else {
853
+ const childCount = childrenAfterStage?.length ?? 0;
854
+ const childNames = childrenAfterStage?.map((c) => c.name).join(', ');
855
+ context.addFlowDebugMessage('children', `Executing all ${childCount} children in parallel: ${childNames}`, {
856
+ count: childCount,
857
+ targetStage: childrenAfterStage?.map((c) => c.name),
659
858
  });
660
- const nextCtx = context.createNext(branchPath, nextNode.name, nextNode.id);
661
- return await this.executeNode(nextNode, nextCtx, breakFlag, branchPath);
859
+ // effNode: ChildrenExecutor reads node.children/node.failFast itself.
860
+ nodeChildrenResults = await this.childrenExecutor.executeNodeChildren(this.effNode(node), context, undefined, branchPath, traversalContext);
861
+ }
862
+ // Fork-only: return bundle
863
+ if (!hasNext && !dynamicNext) {
864
+ return nodeChildrenResults;
865
+ }
866
+ // Capture dynamic children as synthetic subflow result for UI
867
+ const isDynamic = context.debug?.logContext?.isDynamic;
868
+ if (isDynamic && childrenAfterStage && childrenAfterStage.length > 0) {
869
+ this.captureDynamicChildrenResult(node, childrenAfterStage, context);
662
870
  }
663
- // ─── Phase 7: LEAF — no continuation ───
664
- return stageOutput;
665
871
  }
666
- finally {
667
- this._executeDepth--;
872
+ // ─── Phase 6: CONTINUE — dynamic next / linear next ───
873
+ if (dynamicNext) {
874
+ const target = this.continuationResolver.resolveTarget(dynamicNext, node, context, branchPath);
875
+ return this.hop(target.node, target.context, branchPath);
876
+ }
877
+ if (hasNext) {
878
+ const nextNode = originalNext;
879
+ // Detect loop reference nodes created by loopTo() — marked with isLoopRef flag.
880
+ // Route through ContinuationResolver for proper ID resolution, iteration
881
+ // tracking, and narrative generation. The resolved target comes back
882
+ // as a hop — loop edges consume no stack, so the iteration limit
883
+ // (not call-stack depth) is what bounds a loop.
884
+ const isLoopReference = nextNode.isLoopRef;
885
+ if (isLoopReference) {
886
+ const target = this.continuationResolver.resolveTarget(nextNode, node, context, branchPath, traversalContext);
887
+ return this.hop(target.node, target.context, branchPath);
888
+ }
889
+ this.narrativeGenerator.onNext(node.name, nextNode.name, nextNode.description, traversalContext);
890
+ context.addFlowDebugMessage('next', `Moving to ${nextNode.name} stage`, {
891
+ targetStage: nextNode.name,
892
+ });
893
+ const nextCtx = context.createNext(branchPath, nextNode.name, nextNode.id);
894
+ return this.hop(nextNode, nextCtx, branchPath);
668
895
  }
896
+ // ─── Phase 7: LEAF — no continuation ───
897
+ return stageOutput;
669
898
  }
670
899
  // ─────────────────────── Private Helpers ───────────────────────
671
- captureDynamicChildrenResult(node, context) {
900
+ captureDynamicChildrenResult(node, children, context) {
672
901
  const parentStageId = context.getStageId();
673
902
  const childStructure = {
674
903
  id: `${node.id}-children`,
675
904
  name: 'Dynamic Children',
676
905
  type: 'fork',
677
- children: node.children.map((c) => ({
906
+ children: children.map((c) => ({
678
907
  id: c.id,
679
908
  name: c.name,
680
909
  type: 'stage',
@@ -705,13 +934,35 @@ export class FlowchartTraverser {
705
934
  pipelineStructure: childStructure,
706
935
  });
707
936
  }
937
+ /**
938
+ * Parent-chain length of a StageContext — same value the pre-trampoline
939
+ * walk produced, memoized. The context tree deepens by one per executed
940
+ * stage along a chain, so the naive walk is O(chain length) per stage —
941
+ * O(n²) per run once chains reach trampoline scale. Contexts are visited
942
+ * parent-before-child, so the cached parent makes this O(1) amortized.
943
+ */
708
944
  computeContextDepth(context) {
709
- let depth = 0;
710
- let current = context.parent;
945
+ const cached = this.contextDepthCache.get(context);
946
+ if (cached !== undefined)
947
+ return cached;
948
+ // Walk up to the nearest cached ancestor (or the root), then fill the
949
+ // cache back down — iterative, so a cold deep chain can't overflow.
950
+ const uncached = [];
951
+ let depth = -1; // depth of the node ABOVE the first uncached entry
952
+ let current = context;
711
953
  while (current) {
712
- depth++;
954
+ const hit = this.contextDepthCache.get(current);
955
+ if (hit !== undefined) {
956
+ depth = hit;
957
+ break;
958
+ }
959
+ uncached.push(current);
713
960
  current = current.parent;
714
961
  }
962
+ for (let i = uncached.length - 1; i >= 0; i--) {
963
+ depth++;
964
+ this.contextDepthCache.set(uncached[i], depth);
965
+ }
715
966
  return depth;
716
967
  }
717
968
  prefixNodeTree(node, prefix) {
@@ -766,4 +1017,4 @@ export class FlowchartTraverser {
766
1017
  }
767
1018
  }
768
1019
  }
769
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmxvd2NoYXJ0VHJhdmVyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9lbmdpbmUvdHJhdmVyc2FsL0Zsb3djaGFydFRyYXZlcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW1CRztBQUdILE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUMzRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRWpFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBRXRHLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBcUUzRCxNQUFNLE9BQU8sa0JBQWtCO0lBQ1osSUFBSSxDQUEwQjtJQUN2QyxRQUFR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SSxFQUFFLElBQUksSUFBSSxTQUFTLENBQUM7WUFDdkYsSUFBSSxDQUFDLGtCQUFrQixDQUFDLG1CQUFtQixDQUN6QyxTQUFTLEVBQ1QsV0FBVyxFQUNYLFVBQVUsQ0FBQyxJQUFJLEVBQUUsV0FBVyxFQUM1QixVQUFVLENBQUMsa0JBQWtCLENBQzlCLENBQUM7UUFDSixDQUFDO0lBQ0gsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRmxvd2NoYXJ0VHJhdmVyc2VyIOKAlCBQcmUtb3JkZXIgREZTIHRyYXZlcnNhbCBvZiBTdGFnZU5vZGUgZ3JhcGguXG4gKlxuICogVW5pZmllZCB0cmF2ZXJzYWwgYWxnb3JpdGhtIGZvciBhbGwgbm9kZSBzaGFwZXM6XG4gKiAgIGNvbnN0IHByZSA9IGF3YWl0IHByZXAoKTtcbiAqICAgY29uc3QgW3gsIHldID0gYXdhaXQgUHJvbWlzZS5hbGwoW2Z4KHByZSksIGZ5KHByZSldKTtcbiAqICAgcmV0dXJuIGF3YWl0IG5leHQoeCwgeSk7XG4gKlxuICogRm9yIGVhY2ggbm9kZSwgZXhlY3V0ZU5vZGUgZm9sbG93cyA3IHBoYXNlczpcbiAqICAgMC4gQ0xBU1NJRlkgIOKAlCBzdWJmbG93IGRldGVjdGlvbiwgZWFybHkgZGVsZWdhdGlvblxuICogICAxLiBWQUxJREFURSAg4oCUIG5vZGUgaW52YXJpYW50cywgcm9sZSBtYXJrZXJzXG4gKiAgIDIuIEVYRUNVVEUgICDigJQgcnVuIHN0YWdlIGZuLCBjb21taXQsIGJyZWFrIGNoZWNrXG4gKiAgIDMuIERZTkFNSUMgICDigJQgU3RhZ2VOb2RlIHJldHVybiBkZXRlY3Rpb24sIHN1YmZsb3cgYXV0by1yZWdpc3RyYXRpb24sIHN0cnVjdHVyZSB1cGRhdGVzXG4gKiAgIDQuIENISUxEUkVOICDigJQgZm9yay9zZWxlY3Rvci9kZWNpZGVyIGRpc3BhdGNoXG4gKiAgIDUuIENPTlRJTlVFICDigJQgZHluYW1pYyBuZXh0IC8gbGluZWFyIG5leHQgcmVzb2x1dGlvblxuICogICA2LiBMRUFGICAgICAg4oCUIG5vIGNvbnRpbnVhdGlvbiwgcmV0dXJuIG91dHB1dFxuICpcbiAqIEJyZWFrIHNlbWFudGljczogSWYgYSBzdGFnZSBjYWxscyBicmVha0ZuKCksIGNvbW1pdCBhbmQgU1RPUC5cbiAqIFBhdGNoIG1vZGVsOiBTdGFnZSB3cml0ZXMgaW50byBsb2NhbCBwYXRjaDsgY29tbWl0UGF0Y2goKSBhZnRlciByZXR1cm4gb3IgdGhyb3cuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBTdGFnZUNvbnRleHQgfSBmcm9tICcuLi8uLi9tZW1vcnkvU3RhZ2VDb250ZXh0LmpzJztcbmltcG9ydCB7IGlzUGF1c2VTaWduYWwgfSBmcm9tICcuLi8uLi9wYXVzZS90eXBlcy5qcyc7XG5pbXBvcnQgdHlwZSB7IFNjb3BlUHJvdGVjdGlvbk1vZGUgfSBmcm9tICcuLi8uLi9zY29wZS9wcm90ZWN0aW9uL3R5cGVzLmpzJztcbmltcG9ydCB7IGV4dHJhY3RFcnJvckluZm8gfSBmcm9tICcuLi9lcnJvcnMvZXJyb3JJbmZvLmpzJztcbmltcG9ydCB7IGlzU3RhZ2VOb2RlUmV0dXJuIH0gZnJvbSAnLi4vZ3JhcGgvU3RhZ2VOb2RlLmpzJztcbmltcG9ydCB7IENoaWxkcmVuRXhlY3V0b3IgfSBmcm9tICcuLi9oYW5kbGVycy9DaGlsZHJlbkV4ZWN1dG9yLmpzJztcbmltcG9ydCB7IENvbnRpbnVhdGlvblJlc29sdmVyIH0gZnJvbSAnLi4vaGFuZGxlcnMvQ29udGludWF0aW9uUmVzb2x2ZXIuanMnO1xuaW1wb3J0IHsgRGVjaWRlckhhbmRsZXIgfSBmcm9tICcuLi9oYW5kbGVycy9EZWNpZGVySGFuZGxlci5qcyc7XG5pbXBvcnQgeyBOb2RlUmVzb2x2ZXIgfSBmcm9tICcuLi9oYW5kbGVycy9Ob2RlUmVzb2x2ZXIuanMnO1xuaW1wb3J0IHsgUnVudGltZVN0cnVjdHVyZU1hbmFnZXIgfSBmcm9tICcuLi9oYW5kbGVycy9SdW50aW1lU3RydWN0dXJlTWFuYWdlci5qcyc7XG5pbXBvcnQgeyBTZWxlY3RvckhhbmRsZXIgfSBmcm9tICcuLi9oYW5kbGVycy9TZWxlY3RvckhhbmRsZXIuanMnO1xuaW1wb3J0IHsgU3RhZ2VSdW5uZXIgfSBmcm9tICcuLi9oYW5kbGVycy9TdGFnZVJ1bm5lci5qcyc7XG5pbXBvcnQgeyBTdWJmbG93RXhlY3V0b3IgfSBmcm9tICcuLi9oYW5kbGVycy9TdWJmbG93RXhlY3V0b3IuanMnO1xuaW1wb3J0IHR5cGUgeyBCcmVha0ZsYWcgfSBmcm9tICcuLi9oYW5kbGVycy90eXBlcy5qcyc7XG5pbXBvcnQgeyBGbG93UmVjb3JkZXJEaXNwYXRjaGVyIH0gZnJvbSAnLi4vbmFycmF0aXZlL0Zsb3dSZWNvcmRlckRpc3BhdGNoZXIuanMnO1xuaW1wb3J0IHsgTmFycmF0aXZlRmxvd1JlY29yZGVyIH0gZnJvbSAnLi4vbmFycmF0aXZlL05hcnJhdGl2ZUZsb3dSZWNvcmRlci5qcyc7XG5pbXBvcnQgeyBOdWxsQ29udHJvbEZsb3dOYXJyYXRpdmVHZW5lcmF0b3IgfSBmcm9tICcuLi9uYXJyYXRpdmUvTnVsbENvbnRyb2xGbG93TmFycmF0aXZlR2VuZXJhdG9yLmpzJztcbmltcG9ydCB0eXBlIHsgRmxvd1JlY29yZGVyLCBJQ29udHJvbEZsb3dOYXJyYXRpdmUsIFRyYXZlcnNhbENvbnRleHQgfSBmcm9tICcuLi9uYXJyYXRpdmUvdHlwZXMuanMnO1xuaW1wb3J0IHsgYnVpbGRSdW50aW1lU3RhZ2VJZCB9IGZyb20gJy4uL3J1bnRpbWVTdGFnZUlkLmpzJztcbmltcG9ydCB0eXBlIHtcbiAgSGFuZGxlckRlcHMsXG4gIElFeGVjdXRpb25SdW50aW1lLFxuICBJTG9nZ2VyLFxuICBOb2RlUmVzdWx0VHlwZSxcbiAgU2NvcGVGYWN0b3J5LFxuICBTZXJpYWxpemVkUGlwZWxpbmVTdHJ1Y3R1cmUsXG4gIFN0YWdlRnVuY3Rpb24sXG4gIFN0YWdlTm9kZSxcbiAgU3RyZWFtSGFuZGxlcnMsXG4gIFN1YmZsb3dSZXN1bHQsXG4gIFN1YmZsb3dUcmF2ZXJzZXJGYWN0b3J5LFxuICBUcmF2ZXJzYWxSZXN1bHQsXG59IGZyb20gJy4uL3R5cGVzLmpzJztcblxuZXhwb3J0IGludGVyZmFjZSBUcmF2ZXJzZXJPcHRpb25zPFRPdXQgPSBhbnksIFRTY29wZSA9IGFueT4ge1xuICByb290OiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPjtcbiAgc3RhZ2VNYXA6IE1hcDxzdHJpbmcsIFN0YWdlRnVuY3Rpb248VE91dCwgVFNjb3BlPj47XG4gIHNjb3BlRmFjdG9yeTogU2NvcGVGYWN0b3J5PFRTY29wZT47XG4gIGV4ZWN1dGlvblJ1bnRpbWU6IElFeGVjdXRpb25SdW50aW1lO1xuICByZWFkT25seUNvbnRleHQ/OiB1bmtub3duO1xuICAvKiogRXhlY3V0aW9uIGVudmlyb25tZW50IOKAlCBwcm9wYWdhdGVzIHRvIHN1YmZsb3dzIGF1dG9tYXRpY2FsbHkuICovXG4gIGV4ZWN1dGlvbkVudj86IGltcG9ydCgnLi4vLi4vZW5naW5lL3R5cGVzJykuRXhlY3V0aW9uRW52O1xuICB0aHJvdHRsaW5nRXJyb3JDaGVja2VyPzogKGVycm9yOiB1bmtub3duKSA9PiBib29sZWFuO1xuICBzdHJlYW1IYW5kbGVycz86IFN0cmVhbUhhbmRsZXJzO1xuICBzY29wZVByb3RlY3Rpb25Nb2RlPzogU2NvcGVQcm90ZWN0aW9uTW9kZTtcbiAgc3ViZmxvd3M/OiBSZWNvcmQ8c3RyaW5nLCB7IHJvb3Q6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+IH0+O1xuICBuYXJyYXRpdmVFbmFibGVkPzogYm9vbGVhbjtcbiAgYnVpbGRUaW1lU3RydWN0dXJlPzogU2VyaWFsaXplZFBpcGVsaW5lU3RydWN0dXJlO1xuICBsb2dnZXI6IElMb2dnZXI7XG4gIHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICAvKiogUHJlLWNvbmZpZ3VyZWQgRmxvd1JlY29yZGVycyB0byBhdHRhY2ggd2hlbiBuYXJyYXRpdmUgaXMgZW5hYmxlZC4gKi9cbiAgZmxvd1JlY29yZGVycz86IEZsb3dSZWNvcmRlcltdO1xuICAvKipcbiAgICogUHJlLWNvbmZpZ3VyZWQgbmFycmF0aXZlIGdlbmVyYXRvci4gSWYgcHJvdmlkZWQsIHRha2VzIHByZWNlZGVuY2Ugb3ZlclxuICAgKiBmbG93UmVjb3JkZXJzIGFuZCBuYXJyYXRpdmVFbmFibGVkLiBVc2VkIGJ5IHRoZSBzdWJmbG93IHRyYXZlcnNlciBmYWN0b3J5XG4gICAqIHRvIHNoYXJlIHRoZSBwYXJlbnQncyBuYXJyYXRpdmUgZ2VuZXJhdG9yIHdpdGggc3ViZmxvdyB0cmF2ZXJzZXJzLlxuICAgKi9cbiAgbmFycmF0aXZlR2VuZXJhdG9yPzogSUNvbnRyb2xGbG93TmFycmF0aXZlO1xuICAvKipcbiAgICogTWF4aW11bSByZWN1cnNpdmUgZXhlY3V0ZU5vZGUgZGVwdGguIERlZmF1bHRzIHRvIEZsb3djaGFydFRyYXZlcnNlci5NQVhfRVhFQ1VURV9ERVBUSCAoNTAwKS5cbiAgICogT3ZlcnJpZGUgaW4gdGVzdHMgb3IgdW51c3VhbGx5IGRlZXAgcGlwZWxpbmVzLlxuICAgKi9cbiAgbWF4RGVwdGg/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBXaGVuIHRoaXMgdHJhdmVyc2VyIHJ1bnMgaW5zaWRlIGEgc3ViZmxvdywgc2V0IHRoaXMgdG8gdGhlIHN1YmZsb3cncyBJRC5cbiAgICogUHJvcGFnYXRlZCB0byBUcmF2ZXJzYWxDb250ZXh0IHNvIG5hcnJhdGl2ZSBlbnRyaWVzIGNhcnJ5IHRoZSBjb3JyZWN0IHN1YmZsb3dJZC5cbiAgICovXG4gIHBhcmVudFN1YmZsb3dJZD86IHN0cmluZztcbiAgLyoqIFNoYXJlZCBleGVjdXRpb24gY291bnRlciBmcm9tIHBhcmVudCB0cmF2ZXJzZXIuIFN1YmZsb3dzIGNvbnRpbnVlIHRoZSBwYXJlbnQncyBudW1iZXJpbmcuICovXG4gIGV4ZWN1dGlvbkNvdW50ZXI/OiB7IHZhbHVlOiBudW1iZXIgfTtcbiAgLyoqXG4gICAqIFBlci1zdWJmbG93IHNjb3BlIGNhcHR1cmVzIGZyb20gYSBjaGVja3BvaW50LCBvbiB0aGUgcmVzdW1lIHBhdGguXG4gICAqIEZvcndhcmRlZCB0byBgSGFuZGxlckRlcHMuc3ViZmxvd1N0YXRlc0ZvclJlc3VtZWAgc28gU3ViZmxvd0V4ZWN1dG9yXG4gICAqIGNhbiByZS1zZWVkIG5lc3RlZCBydW50aW1lcyBmcm9tIHByZS1wYXVzZSBzdGF0ZSBpbnN0ZWFkIG9mIHJ1bm5pbmdcbiAgICogdGhlIGlucHV0TWFwcGVyLiBVbmRlZmluZWQgb24gbm9ybWFsIGBydW4oKWAgcGF0aHMuXG4gICAqL1xuICBzdWJmbG93U3RhdGVzRm9yUmVzdW1lPzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICAvKipcbiAgICogUGVyLWBleGVjdXRvci5ydW4oKWAgaWRlbnRpZmllci4gVGhyZWFkZWQgaW50byBldmVyeSBUcmF2ZXJzYWxDb250ZXh0XG4gICAqIHRoaXMgdHJhdmVyc2VyIHByb2R1Y2VzIHNvIHJlY29yZGVycyBjYW4gc2NvcGUgc3RhdGUgdG8gYSBzaW5nbGUgcnVuLlxuICAgKiBTdWJmbG93IHRyYXZlcnNlcnMgaW5oZXJpdCB0aGUgcGFyZW50J3MgcnVuSWQgKHRoZSBzdWJmbG93IGlzIHBhcnQgb2ZcbiAgICogdGhlIHNhbWUgcnVuIGZyb20gdGhlIGNvbnN1bWVyJ3MgUE9WKS4gUmVxdWlyZWQgZmllbGQg4oCUIGV2ZXJ5IGV2ZW50XG4gICAqIG5lZWRzIGl0LiBTZWUgYHJ1bm5lci9ydW5JZC50c2AuXG4gICAqL1xuICBydW5JZDogc3RyaW5nO1xufVxuXG5leHBvcnQgY2xhc3MgRmxvd2NoYXJ0VHJhdmVyc2VyPFRPdXQgPSBhbnksIFRTY29wZSA9IGFueT4ge1xuICBwcml2YXRlIHJlYWRvbmx5IHJvb3Q6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+O1xuICBwcml2YXRlIHN0YWdlTWFwOiBNYXA8c3RyaW5nLCBTdGFnZUZ1bmN0aW9uPFRPdXQsIFRTY29wZT4+O1xuICBwcml2YXRlIHJlYWRvbmx5IGV4ZWN1dGlvblJ1bnRpbWU6IElFeGVjdXRpb25SdW50aW1lO1xuICBwcml2YXRlIHN1YmZsb3dzOiBSZWNvcmQ8c3RyaW5nLCB7IHJvb3Q6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+IH0+O1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZ2dlcjogSUxvZ2dlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBzaWduYWw/OiBBYm9ydFNpZ25hbDtcbiAgcHJpdmF0ZSByZWFkb25seSBwYXJlbnRTdWJmbG93SWQ/OiBzdHJpbmc7XG4gIC8qKiBGcm96ZW4gdmFsdWUgcGFzc2VkIHZpYSBgcnVuKHtpbnB1dH0pYC4gU3VyZmFjZWQgb24gYG9uUnVuU3RhcnRgIGF0IHRoZVxuICAgKiAgdG9wLWxldmVsIHRyYXZlcnNhbCBzbyBjb25zdW1lcnMgKGUuZy4gYEluT3V0UmVjb3JkZXJgKSBjYW4gYnJhY2tldFxuICAgKiAgdGhlIHJ1biB3aXRoIHRoZSBzYW1lIHBheWxvYWQgc2hhcGUgdGhhdCBzdWJmbG93cyBhbHJlYWR5IGhhdmUuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcmVhZE9ubHlDb250ZXh0PzogdW5rbm93bjtcbiAgLyoqIFBlci1gZXhlY3V0b3IucnVuKClgIGlkZW50aWZpZXIuIFN0YW1wZWQgb250byBldmVyeSBUcmF2ZXJzYWxDb250ZXh0LlxuICAgKiAgSW5oZXJpdGVkIGJ5IHN1YmZsb3cgdHJhdmVyc2VycyBzbyBhbGwgZXZlbnRzIG9mIG9uZSBydW4gc2hhcmUgb25lIHJ1bklkLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHJ1bklkOiBzdHJpbmc7XG5cbiAgLy8gSGFuZGxlciBtb2R1bGVzXG4gIHByaXZhdGUgcmVhZG9ubHkgbm9kZVJlc29sdmVyOiBOb2RlUmVzb2x2ZXI8VE91dCwgVFNjb3BlPjtcbiAgcHJpdmF0ZSByZWFkb25seSBjaGlsZHJlbkV4ZWN1dG9yOiBDaGlsZHJlbkV4ZWN1dG9yPFRPdXQsIFRTY29wZT47XG4gIHByaXZhdGUgcmVhZG9ubHkgc3ViZmxvd0V4ZWN1dG9yOiBTdWJmbG93RXhlY3V0b3I8VE91dCwgVFNjb3BlPjtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGFnZVJ1bm5lcjogU3RhZ2VSdW5uZXI8VE91dCwgVFNjb3BlPjtcbiAgcHJpdmF0ZSByZWFkb25seSBjb250aW51YXRpb25SZXNvbHZlcjogQ29udGludWF0aW9uUmVzb2x2ZXI8VE91dCwgVFNjb3BlPjtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWNpZGVySGFuZGxlcjogRGVjaWRlckhhbmRsZXI8VE91dCwgVFNjb3BlPjtcbiAgcHJpdmF0ZSByZWFkb25seSBzZWxlY3RvckhhbmRsZXI6IFNlbGVjdG9ySGFuZGxlcjxUT3V0LCBUU2NvcGU+O1xuICBwcml2YXRlIHJlYWRvbmx5IHN0cnVjdHVyZU1hbmFnZXI6IFJ1bnRpbWVTdHJ1Y3R1cmVNYW5hZ2VyO1xuICBwcml2YXRlIHJlYWRvbmx5IG5hcnJhdGl2ZUdlbmVyYXRvcjogSUNvbnRyb2xGbG93TmFycmF0aXZlO1xuICBwcml2YXRlIHJlYWRvbmx5IGZsb3dSZWNvcmRlckRpc3BhdGNoZXI6IEZsb3dSZWNvcmRlckRpc3BhdGNoZXIgfCB1bmRlZmluZWQ7XG5cbiAgLy8gRXhlY3V0aW9uIHN0YXRlXG4gIHByaXZhdGUgc3ViZmxvd1Jlc3VsdHM6IE1hcDxzdHJpbmcsIFN1YmZsb3dSZXN1bHQ+ID0gbmV3IE1hcCgpO1xuXG4gIC8qKlxuICAgKiBQZXItdHJhdmVyc2VyIHNldCBvZiBsYXp5IHN1YmZsb3cgSURzIHRoYXQgaGF2ZSBiZWVuIHJlc29sdmVkIGJ5IFRISVMgcnVuLlxuICAgKiBVc2VkIGluc3RlYWQgb2Ygd3JpdGluZyBgbm9kZS5zdWJmbG93UmVzb2x2ZXIgPSB1bmRlZmluZWRgIGJhY2sgdG8gdGhlIHNoYXJlZFxuICAgKiBTdGFnZU5vZGUgZ3JhcGgg4oCUIGF2b2lkcyBhIHJhY2Ugd2hlcmUgYSBjb25jdXJyZW50IHRyYXZlcnNlciBjbGVhcnMgdGhlIHNoYXJlZFxuICAgKiByZXNvbHZlciBiZWZvcmUgYW5vdGhlciB0cmF2ZXJzZXIgaGFzIGZpbmlzaGVkIHVzaW5nIGl0LlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZXNvbHZlZExhenlTdWJmbG93cyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gIC8qKlxuICAgKiBSZWN1cnNpb24gZGVwdGggY291bnRlciBmb3IgZXhlY3V0ZU5vZGUuXG4gICAqIEVhY2ggcmVjdXJzaXZlIGV4ZWN1dGVOb2RlIGNhbGwgaW5jcmVtZW50cyB0aGlzOyBkZWNyZW1lbnRzIG9uIGV4aXQgKHRyeS9maW5hbGx5KS5cbiAgICogUHJldmVudHMgY2FsbC1zdGFjayBvdmVyZmxvdyBvbiBpbmZpbml0ZSBsb29wcyBvciBleGNlc3NpdmVseSBkZWVwIHN0YWdlIGNoYWlucy5cbiAgICovXG4gIHByaXZhdGUgX2V4ZWN1dGVEZXB0aCA9IDA7XG5cbiAgLyoqXG4gICAqIFNoYXJlZCBtdXRhYmxlIGV4ZWN1dGlvbiBjb3VudGVyIOKAlCBtb25vdG9uaWMsIGluY3JlbWVudGVkIHBlciBzdGFnZSBleGVjdXRpb24uXG4gICAqIFNoYXJlZCB3aXRoIGNoaWxkIHRyYXZlcnNlcnMgKHN1YmZsb3dzKSBzbyBpbmRpY2VzIGFyZSBnbG9iYWxseSB1bmlxdWUgd2l0aGluIGEgcnVuLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfZXhlY3V0aW9uQ291bnRlcjogeyB2YWx1ZTogbnVtYmVyIH07XG5cbiAgLyoqXG4gICAqIFBlci1pbnN0YW5jZSBtYXhpbXVtIGRlcHRoIChzZXQgZnJvbSBUcmF2ZXJzZXJPcHRpb25zLm1heERlcHRoIG9yIHRoZSBjbGFzcyBkZWZhdWx0KS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgX21heERlcHRoOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIERlZmF1bHQgbWF4aW11bSByZWN1cnNpdmUgZXhlY3V0ZU5vZGUgZGVwdGggYmVmb3JlIGFuIGVycm9yIGlzIHRocm93bi5cbiAgICogNTAwIGNvbWZvcnRhYmx5IGNvdmVycyBhbnkgcmVhbGlzdGljIHBpcGVsaW5lIGRlcHRoIChpbmNsdWRpbmcgZGVlcGx5IG5lc3RlZFxuICAgKiBzdWJmbG93cykgd2hpbGUgcHJldmVudGluZyBjYWxsLXN0YWNrIG92ZXJmbG93ICh+MTAgMDAwIGZyYW1lcyBpbiBWOCkuXG4gICAqXG4gICAqICoqTm90ZSBvbiBjb3VudGluZzoqKiB0aGUgY291bnRlciBpbmNyZW1lbnRzIG9uY2UgcGVyIGBleGVjdXRlTm9kZWAgY2FsbCwgbm90IG9uY2UgcGVyXG4gICAqIGxvZ2ljYWwgdXNlciBzdGFnZS4gU3ViZmxvdyByb290IGVudHJ5IGFuZCBzdWJmbG93IGNvbnRpbnVhdGlvbiBhZnRlciByZXR1cm4gZWFjaCBjb3N0XG4gICAqIG9uZSB0aWNrLiBGb3IgcGlwZWxpbmVzIHdpdGggbWFueSBuZXN0ZWQgc3ViZmxvd3MsIGJ1ZGdldCByb3VnaGx5IDIgw5cgKGF2ZyBzdGFnZXMgcGVyXG4gICAqIHN1YmZsb3cpIG9mIGhlYWRyb29tIHdoZW4gY29tcHV0aW5nIGEgY3VzdG9tIGBtYXhEZXB0aGAgdmlhIGBSdW5PcHRpb25zLm1heERlcHRoYC5cbiAgICpcbiAgICogKipOb3RlIG9uIGxvb3BzOioqIGZvciBgbG9vcFRvKClgIHBpcGVsaW5lcywgdGhpcyBkZXB0aCBndWFyZCBhbmQgYENvbnRpbnVhdGlvblJlc29sdmVyYCdzXG4gICAqIGl0ZXJhdGlvbiBsaW1pdCBhcmUgaW5kZXBlbmRlbnQg4oCUIHRoZSBsb3dlciBvbmUgZmlyZXMgZmlyc3QuIFRoZSBkZWZhdWx0IGRlcHRoIGd1YXJkICg1MDApXG4gICAqIGZpcmVzIGJlZm9yZSB0aGUgZGVmYXVsdCBpdGVyYXRpb24gbGltaXQgKDEwMDApIGZvciBsb29wLWhlYXZ5IHBpcGVsaW5lcy5cbiAgICpcbiAgICogQHJlbWFya3MgTm90IHNhZmUgZm9yIGNvbmN1cnJlbnQgYC5leGVjdXRlKClgIGNhbGxzIG9uIHRoZSBzYW1lIGluc3RhbmNlIOKAlCBjb25jdXJyZW50XG4gICAqIGV4ZWN1dGlvbnMgcmFjZSBvbiBgX2V4ZWN1dGVEZXB0aGAuIFVzZSBhIHNlcGFyYXRlIGBGbG93Y2hhcnRUcmF2ZXJzZXJgIHBlciBjb25jdXJyZW50XG4gICAqIGV4ZWN1dGlvbi4gYEZsb3dDaGFydEV4ZWN1dG9yLnJ1bigpYCBhbHdheXMgY3JlYXRlcyBhIGZyZXNoIHRyYXZlcnNlciBwZXIgY2FsbC5cbiAgICovXG4gIHN0YXRpYyByZWFkb25seSBNQVhfRVhFQ1VURV9ERVBUSCA9IDUwMDtcblxuICBjb25zdHJ1Y3RvcihvcHRzOiBUcmF2ZXJzZXJPcHRpb25zPFRPdXQsIFRTY29wZT4pIHtcbiAgICBjb25zdCBtYXhEZXB0aCA9IG9wdHMubWF4RGVwdGggPz8gRmxvd2NoYXJ0VHJhdmVyc2VyLk1BWF9FWEVDVVRFX0RFUFRIO1xuICAgIGlmIChtYXhEZXB0aCA8IDEpIHRocm93IG5ldyBFcnJvcignRmxvd2NoYXJ0VHJhdmVyc2VyOiBtYXhEZXB0aCBtdXN0IGJlID49IDEnKTtcbiAgICB0aGlzLl9tYXhEZXB0aCA9IG1heERlcHRoO1xuICAgIHRoaXMuX2V4ZWN1dGlvbkNvdW50ZXIgPSBvcHRzLmV4ZWN1dGlvbkNvdW50ZXIgPz8geyB2YWx1ZTogMCB9O1xuICAgIHRoaXMucm9vdCA9IG9wdHMucm9vdDtcbiAgICAvLyBTaGFsbG93LWNvcHkgc3RhZ2VNYXAgYW5kIHN1YmZsb3dzIHNvIHRoYXQgbGF6eS1yZXNvbHV0aW9uIG11dGF0aW9uc1xuICAgIC8vIChwcmVmaXhlZCBlbnRyaWVzIGFkZGVkIGR1cmluZyBleGVjdXRpb24pIHN0YXkgc2NvcGVkIHRvIFRISVMgdHJhdmVyc2VyXG4gICAgLy8gYW5kIGRvIG5vdCBlc2NhcGUgdG8gdGhlIHNoYXJlZCBGbG93Q2hhcnQgb2JqZWN0LiBXaXRob3V0IHRoZSBjb3B5LFxuICAgIC8vIGNvbmN1cnJlbnQgRmxvd0NoYXJ0RXhlY3V0b3IgcnVucyBzaGFyaW5nIHRoZSBzYW1lIEZsb3dDaGFydCB3b3VsZCByYWNlXG4gICAgLy8gb24gdGhlc2UgdHdvIG11dGFibGUgZGljdGlvbmFyaWVzLlxuICAgIHRoaXMuc3RhZ2VNYXAgPSBuZXcgTWFwKG9wdHMuc3RhZ2VNYXApO1xuICAgIHRoaXMuZXhlY3V0aW9uUnVudGltZSA9IG9wdHMuZXhlY3V0aW9uUnVudGltZTtcbiAgICB0aGlzLnN1YmZsb3dzID0gb3B0cy5zdWJmbG93cyA/IHsgLi4ub3B0cy5zdWJmbG93cyB9IDoge307XG4gICAgdGhpcy5sb2dnZXIgPSBvcHRzLmxvZ2dlcjtcbiAgICB0aGlzLnNpZ25hbCA9IG9wdHMuc2lnbmFsO1xuICAgIHRoaXMucGFyZW50U3ViZmxvd0lkID0gb3B0cy5wYXJlbnRTdWJmbG93SWQ7XG4gICAgdGhpcy5yZWFkT25seUNvbnRleHQgPSBvcHRzLnJlYWRPbmx5Q29udGV4dDtcbiAgICB0aGlzLnJ1bklkID0gb3B0cy5ydW5JZDtcblxuICAgIC8vIFN0cnVjdHVyZSBtYW5hZ2VyIChkZWVwLWNsb25lcyBidWlsZC10aW1lIHN0cnVjdHVyZSlcbiAgICB0aGlzLnN0cnVjdHVyZU1hbmFnZXIgPSBuZXcgUnVudGltZVN0cnVjdHVyZU1hbmFnZXIoKTtcbiAgICB0aGlzLnN0cnVjdHVyZU1hbmFnZXIuaW5pdChvcHRzLmJ1aWxkVGltZVN0cnVjdHVyZSk7XG5cbiAgICAvLyBOYXJyYXRpdmUgZ2VuZXJhdG9yXG4gICAgLy8gUHJpb3JpdHk6IGV4cGxpY2l0IG5hcnJhdGl2ZUdlbmVyYXRvciA+IGZsb3dSZWNvcmRlcnMgPiBkZWZhdWx0IE5hcnJhdGl2ZUZsb3dSZWNvcmRlciA+IG51bGwuXG4gICAgLy8gU3ViZmxvdyB0cmF2ZXJzZXJzIHJlY2VpdmUgdGhlIHBhcmVudCdzIG5hcnJhdGl2ZUdlbmVyYXRvciBzbyBhbGwgZXZlbnRzIGZsb3cgdG8gb25lIHBsYWNlLlxuICAgIGlmIChvcHRzLm5hcnJhdGl2ZUdlbmVyYXRvcikge1xuICAgICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3IgPSBvcHRzLm5hcnJhdGl2ZUdlbmVyYXRvcjtcbiAgICB9IGVsc2UgaWYgKG9wdHMubmFycmF0aXZlRW5hYmxlZCkge1xuICAgICAgY29uc3QgZGlzcGF0Y2hlciA9IG5ldyBGbG93UmVjb3JkZXJEaXNwYXRjaGVyKCk7XG4gICAgICB0aGlzLmZsb3dSZWNvcmRlckRpc3BhdGNoZXIgPSBkaXNwYXRjaGVyO1xuXG4gICAgICAvLyBJZiBjdXN0b20gRmxvd1JlY29yZGVycyBhcmUgcHJvdmlkZWQsIHVzZSB0aGVtOyBvdGhlcndpc2UgYXR0YWNoIGRlZmF1bHQgTmFycmF0aXZlRmxvd1JlY29yZGVyXG4gICAgICBpZiAob3B0cy5mbG93UmVjb3JkZXJzICYmIG9wdHMuZmxvd1JlY29yZGVycy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGZvciAoY29uc3QgcmVjb3JkZXIgb2Ygb3B0cy5mbG93UmVjb3JkZXJzKSB7XG4gICAgICAgICAgZGlzcGF0Y2hlci5hdHRhY2gocmVjb3JkZXIpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBkaXNwYXRjaGVyLmF0dGFjaChuZXcgTmFycmF0aXZlRmxvd1JlY29yZGVyKCkpO1xuICAgICAgfVxuXG4gICAgICB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvciA9IGRpc3BhdGNoZXI7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yID0gbmV3IE51bGxDb250cm9sRmxvd05hcnJhdGl2ZUdlbmVyYXRvcigpO1xuICAgIH1cblxuICAgIC8vIEJ1aWxkIHNoYXJlZCBkZXBzIGJhZ1xuICAgIGNvbnN0IGRlcHMgPSB0aGlzLmNyZWF0ZURlcHMob3B0cyk7XG5cbiAgICAvLyBCdWlsZCBPKDEpIG5vZGUgSUQgbWFwIGZyb20gdGhlIHJvb3QgZ3JhcGggKGF2b2lkcyByZXBlYXRlZCBERlMgb24gZXZlcnkgbG9vcFRvKCkpXG4gICAgY29uc3Qgbm9kZUlkTWFwID0gdGhpcy5idWlsZE5vZGVJZE1hcChvcHRzLnJvb3QpO1xuXG4gICAgLy8gSW5pdGlhbGl6ZSBoYW5kbGVyIG1vZHVsZXNcbiAgICB0aGlzLm5vZGVSZXNvbHZlciA9IG5ldyBOb2RlUmVzb2x2ZXIoZGVwcywgbm9kZUlkTWFwKTtcbiAgICB0aGlzLmNoaWxkcmVuRXhlY3V0b3IgPSBuZXcgQ2hpbGRyZW5FeGVjdXRvcihkZXBzLCB0aGlzLmV4ZWN1dGVOb2RlLmJpbmQodGhpcykpO1xuICAgIHRoaXMuc3RhZ2VSdW5uZXIgPSBuZXcgU3RhZ2VSdW5uZXIoZGVwcyk7XG4gICAgdGhpcy5jb250aW51YXRpb25SZXNvbHZlciA9IG5ldyBDb250aW51YXRpb25SZXNvbHZlcihkZXBzLCB0aGlzLm5vZGVSZXNvbHZlciwgKG5vZGVJZCwgY291bnQpID0+XG4gICAgICB0aGlzLnN0cnVjdHVyZU1hbmFnZXIudXBkYXRlSXRlcmF0aW9uQ291bnQobm9kZUlkLCBjb3VudCksXG4gICAgKTtcbiAgICB0aGlzLmRlY2lkZXJIYW5kbGVyID0gbmV3IERlY2lkZXJIYW5kbGVyKGRlcHMpO1xuICAgIHRoaXMuc2VsZWN0b3JIYW5kbGVyID0gbmV3IFNlbGVjdG9ySGFuZGxlcihkZXBzLCB0aGlzLmNoaWxkcmVuRXhlY3V0b3IpO1xuICAgIHRoaXMuc3ViZmxvd0V4ZWN1dG9yID0gbmV3IFN1YmZsb3dFeGVjdXRvcihkZXBzLCB0aGlzLmNyZWF0ZVN1YmZsb3dUcmF2ZXJzZXJGYWN0b3J5KG9wdHMpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGUgYSBmYWN0b3J5IHRoYXQgcHJvZHVjZXMgRmxvd2NoYXJ0VHJhdmVyc2VyIGluc3RhbmNlcyBmb3Igc3ViZmxvdyBleGVjdXRpb24uXG4gICAqIENhcHR1cmVzIHBhcmVudCBjb25maWcgaW4gY2xvc3VyZSDigJQgU3ViZmxvd0V4ZWN1dG9yIHByb3ZpZGVzIHN1YmZsb3ctc3BlY2lmaWMgb3ZlcnJpZGVzLlxuICAgKiBFYWNoIHN1YmZsb3cgZ2V0cyBhIGZ1bGwgdHJhdmVyc2VyIHdpdGggYWxsIDcgcGhhc2VzIChkZWNpZGVycywgc2VsZWN0b3JzLCBsb29wcywgZXRjLikuXG4gICAqL1xuICBwcml2YXRlIGNyZWF0ZVN1YmZsb3dUcmF2ZXJzZXJGYWN0b3J5KFxuICAgIHBhcmVudE9wdHM6IFRyYXZlcnNlck9wdGlvbnM8VE91dCwgVFNjb3BlPixcbiAgKTogU3ViZmxvd1RyYXZlcnNlckZhY3Rvcnk8VE91dCwgVFNjb3BlPiB7XG4gICAgLy8gQ2FwdHVyZSByZWZlcmVuY2VzIHRvIG11dGFibGUgc3RhdGUg4oCUIGZhY3RvcnkgcmVhZHMgdGhlIENVUlJFTlQgc3RhdGUgd2hlbiBjYWxsZWQsXG4gICAgLy8gbm90IHRoZSBzdGF0ZSBhdCBmYWN0b3J5IGNyZWF0aW9uIHRpbWUuIFRoaXMgaXMgY29ycmVjdCBiZWNhdXNlIGxhenkgc3ViZmxvdyByZXNvbHV0aW9uXG4gICAgLy8gbWF5IGFkZCBlbnRyaWVzIHRvIHN0YWdlTWFwL3N1YmZsb3dzIGJlZm9yZSBhIG5lc3RlZCBzdWJmbG93IGlzIGVuY291bnRlcmVkLlxuICAgIGNvbnN0IHBhcmVudFN0YWdlTWFwID0gdGhpcy5zdGFnZU1hcDtcbiAgICBjb25zdCBwYXJlbnRTdWJmbG93cyA9IHRoaXMuc3ViZmxvd3M7XG4gICAgY29uc3QgbmFycmF0aXZlR2VuZXJhdG9yID0gdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3I7XG5cbiAgICByZXR1cm4gKHN1YmZsb3dPcHRzKSA9PiB7XG4gICAgICBjb25zdCB0cmF2ZXJzZXIgPSBuZXcgRmxvd2NoYXJ0VHJhdmVyc2VyPFRPdXQsIFRTY29wZT4oe1xuICAgICAgICByb290OiBzdWJmbG93T3B0cy5yb290LFxuICAgICAgICBzdGFnZU1hcDogcGFyZW50U3RhZ2VNYXAsIC8vIENvbnN0cnVjdG9yIHNoYWxsb3ctY29waWVzIHRoaXNcbiAgICAgICAgc2NvcGVGYWN0b3J5OiBwYXJlbnRPcHRzLnNjb3BlRmFjdG9yeSxcbiAgICAgICAgZXhlY3V0aW9uUnVudGltZTogc3ViZmxvd09wdHMuZXhlY3V0aW9uUnVudGltZSxcbiAgICAgICAgcmVhZE9ubHlDb250ZXh0OiBzdWJmbG93T3B0cy5yZWFkT25seUNvbnRleHQsXG4gICAgICAgIGV4ZWN1dGlvbkVudjogcGFyZW50T3B0cy5leGVjdXRpb25FbnYsXG4gICAgICAgIHRocm90dGxpbmdFcnJvckNoZWNrZXI6IHBhcmVudE9wdHMudGhyb3R0bGluZ0Vycm9yQ2hlY2tlcixcbiAgICAgICAgc3RyZWFtSGFuZGxlcnM6IHBhcmVudE9wdHMuc3RyZWFtSGFuZGxlcnMsXG4gICAgICAgIHNjb3BlUHJvdGVjdGlvbk1vZGU6IHBhcmVudE9wdHMuc2NvcGVQcm90ZWN0aW9uTW9kZSxcbiAgICAgICAgc3ViZmxvd3M6IHBhcmVudFN1YmZsb3dzLCAvLyBDb25zdHJ1Y3RvciBzaGFsbG93LWNvcGllcyB0aGlzXG4gICAgICAgIG5hcnJhdGl2ZUdlbmVyYXRvciwgLy8gU2hhcmUgcGFyZW50J3Mg4oCUIGFsbCBldmVudHMgZmxvdyB0byBvbmUgcGxhY2VcbiAgICAgICAgbG9nZ2VyOiBwYXJlbnRPcHRzLmxvZ2dlcixcbiAgICAgICAgc2lnbmFsOiBwYXJlbnRPcHRzLnNpZ25hbCxcbiAgICAgICAgbWF4RGVwdGg6IHRoaXMuX21heERlcHRoLFxuICAgICAgICBwYXJlbnRTdWJmbG93SWQ6IHN1YmZsb3dPcHRzLnN1YmZsb3dJZCxcbiAgICAgICAgZXhlY3V0aW9uQ291bnRlcjogdGhpcy5fZXhlY3V0aW9uQ291bnRlciwgLy8gU2hhcmUgY291bnRlciDigJQgc3ViZmxvdyBjb250aW51ZXMgZ2xvYmFsIG51bWJlcmluZ1xuICAgICAgICBydW5JZDogdGhpcy5ydW5JZCwgLy8gU3ViZmxvdyBpbmhlcml0cyBwYXJlbnQncyBydW5JZCDigJQgc2FtZSBsb2dpY2FsIHJ1blxuICAgICAgICAvLyBGb3J3YXJkIHRoZSByZXN1bWUtb25seSBzdWJmbG93IHNjb3BlIGNhcHR1cmVzIHNvIG5lc3RlZFxuICAgICAgICAvLyBTdWJmbG93RXhlY3V0b3JzIGNhbiByZS1zZWVkIGRlZXBlci1uZXN0ZWQgcnVudGltZXMgKGUuZy5cbiAgICAgICAgLy8gU2VxdWVuY2UoQWdlbnQoLi4uKSkgd2hlcmUgdGhlIGlubmVyIEFnZW50IHN1YmZsb3cgcGF1c2VkKS5cbiAgICAgICAgLi4uKHBhcmVudE9wdHMuc3ViZmxvd1N0YXRlc0ZvclJlc3VtZSAmJiB7XG4gICAgICAgICAgc3ViZmxvd1N0YXRlc0ZvclJlc3VtZTogcGFyZW50T3B0cy5zdWJmbG93U3RhdGVzRm9yUmVzdW1lLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBleGVjdXRlOiAoKSA9PiB0cmF2ZXJzZXIuZXhlY3V0ZSgpLFxuICAgICAgICBnZXRTdWJmbG93UmVzdWx0czogKCkgPT4gdHJhdmVyc2VyLmdldFN1YmZsb3dSZXN1bHRzKCksXG4gICAgICAgIGdldEJyZWFrU3RhdGU6ICgpID0+IHRyYXZlcnNlci5nZXRCcmVha1N0YXRlKCksXG4gICAgICB9O1xuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZURlcHMob3B0czogVHJhdmVyc2VyT3B0aW9uczxUT3V0LCBUU2NvcGU+KTogSGFuZGxlckRlcHM8VE91dCwgVFNjb3BlPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YWdlTWFwOiB0aGlzLnN0YWdlTWFwLFxuICAgICAgcm9vdDogdGhpcy5yb290LFxuICAgICAgZXhlY3V0aW9uUnVudGltZTogdGhpcy5leGVjdXRpb25SdW50aW1lLFxuICAgICAgc2NvcGVGYWN0b3J5OiBvcHRzLnNjb3BlRmFjdG9yeSxcbiAgICAgIHN1YmZsb3dzOiB0aGlzLnN1YmZsb3dzLFxuICAgICAgdGhyb3R0bGluZ0Vycm9yQ2hlY2tlcjogb3B0cy50aHJvdHRsaW5nRXJyb3JDaGVja2VyLFxuICAgICAgc3RyZWFtSGFuZGxlcnM6IG9wdHMuc3RyZWFtSGFuZGxlcnMsXG4gICAgICBzY29wZVByb3RlY3Rpb25Nb2RlOiBvcHRzLnNjb3BlUHJvdGVjdGlvbk1vZGUgPz8gJ2Vycm9yJyxcbiAgICAgIHJlYWRPbmx5Q29udGV4dDogb3B0cy5yZWFkT25seUNvbnRleHQsXG4gICAgICBleGVjdXRpb25FbnY6IG9wdHMuZXhlY3V0aW9uRW52LFxuICAgICAgbmFycmF0aXZlR2VuZXJhdG9yOiB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvcixcbiAgICAgIGxvZ2dlcjogdGhpcy5sb2dnZXIsXG4gICAgICBzaWduYWw6IG9wdHMuc2lnbmFsLFxuICAgICAgLi4uKG9wdHMuc3ViZmxvd1N0YXRlc0ZvclJlc3VtZSAmJiB7XG4gICAgICAgIHN1YmZsb3dTdGF0ZXNGb3JSZXN1bWU6IG9wdHMuc3ViZmxvd1N0YXRlc0ZvclJlc3VtZSxcbiAgICAgIH0pLFxuICAgIH07XG4gIH1cblxuICAvLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAgUHVibGljIEFQSSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogSG9sZHMgdGhlIHRvcC1sZXZlbCBicmVhayBmbGFnIGZvciB0aGUgZHVyYXRpb24gb2YgYGV4ZWN1dGUoKWAuIEtlcHQgYXNcbiAgICogYSBmaWVsZCAobm90IGEgbG9jYWwpIHNvIGBnZXRCcmVha1N0YXRlKClgIGNhbiBzdXJmYWNlIHRoZSBmaW5hbCBzdGF0ZVxuICAgKiBmb3IgY2FsbGVycyBsaWtlIGBTdWJmbG93RXhlY3V0b3JgIHRoYXQgaW1wbGVtZW50IGBwcm9wYWdhdGVCcmVha2AuXG4gICAqL1xuICBwcml2YXRlIF90b3BCcmVha0ZsYWc6IHsgc2hvdWxkQnJlYWs6IGJvb2xlYW47IHJlYXNvbj86IHN0cmluZyB9ID0geyBzaG91bGRCcmVhazogZmFsc2UgfTtcblxuICBhc3luYyBleGVjdXRlKGJyYW5jaFBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPFRyYXZlcnNhbFJlc3VsdD4ge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmV4ZWN1dGlvblJ1bnRpbWUucm9vdFN0YWdlQ29udGV4dDtcbiAgICB0aGlzLl90b3BCcmVha0ZsYWcgPSB7IHNob3VsZEJyZWFrOiBmYWxzZSB9O1xuXG4gICAgLy8gRmlyZSBvblJ1blN0YXJ0IE9OTFkgYXQgdGhlIHRvcC1sZXZlbCB0cmF2ZXJzYWwg4oCUIHN1YmZsb3cgdHJhdmVyc2Vyc1xuICAgIC8vIGFscmVhZHkgcHJvZHVjZSBvblN1YmZsb3dFbnRyeS9vblN1YmZsb3dFeGl0IHBhaXJzLCBzbyBlbWl0dGluZyBydW5cbiAgICAvLyBldmVudHMgZm9yIHRoZW0gd291bGQgZG91YmxlLWJyYWNrZXQgdGhlIGJvdW5kYXJ5IHN0cmVhbS4gVGhlXG4gICAgLy8gdG9wLWxldmVsIHRyYXZlcnNlciBpcyB0aGUgb25lIHdpdGhvdXQgYSBwYXJlbnRTdWJmbG93SWQuXG4gICAgY29uc3QgaXNUb3BMZXZlbCA9IHRoaXMucGFyZW50U3ViZmxvd0lkID09PSB1bmRlZmluZWQ7XG4gICAgLy8gU3ludGhldGljIFRyYXZlcnNhbENvbnRleHQgZm9yIHJ1bi5lbnRyeSAvIHJ1bi5leGl0LiBGaWVsZHMgdXNlXG4gICAgLy8gcm9vdC1zdGFnZSBkZWZhdWx0cyAoc3RhZ2VJZD0nX19yb290X18nLCBydW50aW1lU3RhZ2VJZD0nX19yb290X18jMCcsXG4gICAgLy8gZGVwdGggMCkgc28gdGhlIHJ1bklkIGlzIHJlbGlhYmx5IGF2YWlsYWJsZSBvbiBydW4gZXZlbnRzIHdpdGhvdXRcbiAgICAvLyBmb3JjaW5nIHJlY29yZGVycyB0byBoYW5kbGUgYHRyYXZlcnNhbENvbnRleHQgPT09IHVuZGVmaW5lZGAuXG4gICAgY29uc3Qgcm9vdENvbnRleHQ6IFRyYXZlcnNhbENvbnRleHQgPSB7XG4gICAgICBydW5JZDogdGhpcy5ydW5JZCxcbiAgICAgIHN0YWdlSWQ6ICdfX3Jvb3RfXycsXG4gICAgICBydW50aW1lU3RhZ2VJZDogJ19fcm9vdF9fIzAnLFxuICAgICAgc3RhZ2VOYW1lOiAnX19yb290X18nLFxuICAgICAgZGVwdGg6IDAsXG4gICAgfTtcbiAgICBpZiAoaXNUb3BMZXZlbCkge1xuICAgICAgLy8gYHJlYWRPbmx5Q29udGV4dGAgaXMgdGhlIGVuZ2luZSdzIHZpZXcgb2YgYHJ1bih7aW5wdXR9KWAg4oCUIHBhc3NlZFxuICAgICAgLy8gdGhyb3VnaCBmcm9tIGBGbG93Q2hhcnRFeGVjdXRvci5ydW4oKWAgYXMgdGhlIHZhbGlkYXRlZCBpbnB1dC5cbiAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yLm9uUnVuU3RhcnQodGhpcy5yZWFkT25seUNvbnRleHQsIHJvb3RDb250ZXh0KTtcbiAgICB9XG5cbiAgICAvLyBUb3AtbGV2ZWwgcnVucyBjbG9zZSB0aGVpciBib3VuZGFyeSBTWU1NRVRSSUNBTExZOiBldmVyeSBvblJ1blN0YXJ0XG4gICAgLy8gaXMgZm9sbG93ZWQgYnkgZXhhY3RseSBvbmUgb25SdW5FbmQgKGNsZWFuKSBvciBvblJ1bkZhaWxlZCAoZXJyb3IpLlxuICAgIC8vIFdpdGhvdXQgdGhlIGNhdGNoLCBhIHRocm93biBydW4gZmlyZWQgb25SdW5TdGFydCB0aGVuIG5vdGhpbmcg4oCUIGFcbiAgICAvLyBtb25pdG9yIGNvdWxkbid0IHRlbGwgXCJzdGlsbCBydW5uaW5nXCIgZnJvbSBcImNyYXNoZWQuXCIgUGF1c2UgaXMgTk9UXG4gICAgLy8gYW4gZXJyb3IgKGl0J3MgZXhwZWN0ZWQgc3VzcGVuc2lvbiksIHNvIGl0IHNraXBzIG9uUnVuRmFpbGVkIGFuZFxuICAgIC8vIHJlLXRocm93cyB1bnRvdWNoZWQuIFRoZSBzdGFnZS1sZXZlbCBjYXRjaCBhbHJlYWR5IHJlY29yZGVkIHRoZVxuICAgIC8vIGZhaWxpbmcgc3RhZ2UgKG9uRXJyb3IgKyBjb21taXQpOyB0aGlzIGFkZHMgdGhlIHJ1bi1sZXZlbCB0ZXJtaW5hbFxuICAgIC8vIHNpZ25hbC4gVGhlIGVycm9yIHN0aWxsIHByb3BhZ2F0ZXMg4oCUIHRoaXMgaXMgb2JzZXJ2YXRpb24sIG5vdFxuICAgIC8vIHJlY292ZXJ5LiBTdWJmbG93IHRyYXZlcnNlcnMgZG9uJ3QgZmlyZSBydW4gZXZlbnRzOyB0aGVpciBlcnJvcnNcbiAgICAvLyBidWJibGUgdXAgYW5kIHN1cmZhY2UgaGVyZSBhdCB0aGUgdG9wIGxldmVsLlxuICAgIGlmICghaXNUb3BMZXZlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZU5vZGUodGhpcy5yb290LCBjb250ZXh0LCB0aGlzLl90b3BCcmVha0ZsYWcsIGJyYW5jaFBhdGggPz8gJycpO1xuICAgIH1cbiAgICBsZXQgcmVzdWx0OiBUcmF2ZXJzYWxSZXN1bHQ7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZU5vZGUodGhpcy5yb290LCBjb250ZXh0LCB0aGlzLl90b3BCcmVha0ZsYWcsIGJyYW5jaFBhdGggPz8gJycpO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBpZiAoIWlzUGF1c2VTaWduYWwoZXJyb3IpKSB7XG4gICAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yLm9uUnVuRmFpbGVkKGV4dHJhY3RFcnJvckluZm8oZXJyb3IpLCByb290Q29udGV4dCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3Iub25SdW5FbmQocmVzdWx0LCByb290Q29udGV4dCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBCcmVhayBzdGF0ZSBjYXB0dXJlZCBhdCB0aGUgdG9wLWxldmVsIG9mIHRoZSBtb3N0IHJlY2VudCBgZXhlY3V0ZSgpYC5cbiAgICogYHNob3VsZEJyZWFrYCBpcyB0cnVlIHdoZW4gYSBzdGFnZSBjYWxsZWQgYHNjb3BlLiRicmVhayhyZWFzb24pYDsgdGhlXG4gICAqIG9wdGlvbmFsIGByZWFzb25gIGNhcnJpZXMgdGhlIHN0cmluZyBwYXNzZWQgdG8gYCRicmVha2AuXG4gICAqXG4gICAqIFVzZWQgYnkgYFN1YmZsb3dFeGVjdXRvcmAgdG8gcHJvcGFnYXRlIGFuIGlubmVyIHN1YmZsb3cncyBicmVhayB1cCB0b1xuICAgKiB0aGUgcGFyZW50IHRyYXZlcnNlciB3aGVuIHRoZSBtb3VudCBzZXRzIGBwcm9wYWdhdGVCcmVhazogdHJ1ZWAuXG4gICAqL1xuICBnZXRCcmVha1N0YXRlKCk6IHsgc2hvdWxkQnJlYWs6IGJvb2xlYW47IHJlYXNvbj86IHN0cmluZyB9IHtcbiAgICByZXR1cm4geyAuLi50aGlzLl90b3BCcmVha0ZsYWcgfTtcbiAgfVxuXG4gIGdldFJ1bnRpbWVTdHJ1Y3R1cmUoKTogU2VyaWFsaXplZFBpcGVsaW5lU3RydWN0dXJlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5zdHJ1Y3R1cmVNYW5hZ2VyLmdldFN0cnVjdHVyZSgpO1xuICB9XG5cbiAgZ2V0U25hcHNob3Qob3B0aW9ucz86IHsgcmVkYWN0PzogYm9vbGVhbiB9KSB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0aW9uUnVudGltZS5nZXRTbmFwc2hvdChvcHRpb25zKTtcbiAgfVxuXG4gIGdldFJ1bnRpbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0aW9uUnVudGltZTtcbiAgfVxuXG4gIHNldFJvb3RPYmplY3QocGF0aDogc3RyaW5nW10sIGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikge1xuICAgIHRoaXMuZXhlY3V0aW9uUnVudGltZS5zZXRSb290T2JqZWN0KHBhdGgsIGtleSwgdmFsdWUpO1xuICB9XG5cbiAgZ2V0QnJhbmNoSWRzKCkge1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGlvblJ1bnRpbWUuZ2V0UGlwZWxpbmVzKCk7XG4gIH1cblxuICBnZXRSdW50aW1lUm9vdCgpOiBTdGFnZU5vZGUge1xuICAgIHJldHVybiB0aGlzLnJvb3Q7XG4gIH1cblxuICBnZXRTdWJmbG93UmVzdWx0cygpOiBNYXA8c3RyaW5nLCBTdWJmbG93UmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuc3ViZmxvd1Jlc3VsdHM7XG4gIH1cblxuICBnZXROYXJyYXRpdmUoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvci5nZXRTZW50ZW5jZXMoKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBGbG93UmVjb3JkZXJEaXNwYXRjaGVyLCBvciB1bmRlZmluZWQgaWYgbmFycmF0aXZlIGlzIGRpc2FibGVkLiAqL1xuICBnZXRGbG93UmVjb3JkZXJEaXNwYXRjaGVyKCk6IEZsb3dSZWNvcmRlckRpc3BhdGNoZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmZsb3dSZWNvcmRlckRpc3BhdGNoZXI7XG4gIH1cblxuICAvLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAgQ29yZSBUcmF2ZXJzYWwg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFuIE8oMSkgSUTihpJub2RlIG1hcCBmcm9tIHRoZSByb290IGdyYXBoLlxuICAgKiBVc2VkIGJ5IE5vZGVSZXNvbHZlciB0byBhdm9pZCByZXBlYXRlZCBERlMgb24gZXZlcnkgbG9vcFRvKCkgY2FsbC5cbiAgICogRGVwdGgtZ3VhcmRlZCBhdCBNQVhfRVhFQ1VURV9ERVBUSCB0byBwcmV2ZW50IGluZmluaXRlIHJlY3Vyc2lvbiBvbiBjeWNsaWMgZ3JhcGhzLlxuICAgKiBEeW5hbWljIHN1YmZsb3dzIGFuZCBsYXp5LXJlc29sdmVkIG5vZGVzIGFyZSBhZGRlZCB0byBzdGFnZU1hcCBhdCBydW50aW1lIGJ1dCBub3QgdG8gdGhpcyBtYXAg4oCUXG4gICAqIHRob3NlIHVzZSB0aGUgREZTIGZhbGxiYWNrIGluIE5vZGVSZXNvbHZlci5cbiAgICovXG4gIHByaXZhdGUgYnVpbGROb2RlSWRNYXAocm9vdDogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4pOiBNYXA8c3RyaW5nLCBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPj4ge1xuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nLCBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPj4oKTtcbiAgICBjb25zdCB2aXNpdCA9IChub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiwgZGVwdGg6IG51bWJlcik6IHZvaWQgPT4ge1xuICAgICAgaWYgKGRlcHRoID4gRmxvd2NoYXJ0VHJhdmVyc2VyLk1BWF9FWEVDVVRFX0RFUFRIKSByZXR1cm47XG4gICAgICBpZiAobWFwLmhhcyhub2RlLmlkKSkgcmV0dXJuOyAvLyBhbHJlYWR5IHZpc2l0ZWQgKGF2b2lkcyBpbmZpbml0ZSBsb29wcyBvbiBjeWNsaWMgcmVmcylcbiAgICAgIG1hcC5zZXQobm9kZS5pZCwgbm9kZSk7XG4gICAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgICBmb3IgKGNvbnN0IGNoaWxkIG9mIG5vZGUuY2hpbGRyZW4pIHZpc2l0KGNoaWxkLCBkZXB0aCArIDEpO1xuICAgICAgfVxuICAgICAgaWYgKG5vZGUubmV4dCkgdmlzaXQobm9kZS5uZXh0LCBkZXB0aCArIDEpO1xuICAgIH07XG4gICAgdmlzaXQocm9vdCwgMCk7XG4gICAgcmV0dXJuIG1hcDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3RhZ2VGbihub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPik6IFN0YWdlRnVuY3Rpb248VE91dCwgVFNjb3BlPiB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiBub2RlLmZuID09PSAnZnVuY3Rpb24nKSByZXR1cm4gbm9kZS5mbiBhcyBTdGFnZUZ1bmN0aW9uPFRPdXQsIFRTY29wZT47XG4gICAgLy8gUHJpbWFyeTogbG9vayB1cCBieSBpZCAoc3RhYmxlIGlkZW50aWZpZXIsIGtleWVkIGJ5IEZsb3dDaGFydEJ1aWxkZXIpXG4gICAgY29uc3QgYnlJZCA9IHRoaXMuc3RhZ2VNYXAuZ2V0KG5vZGUuaWQpO1xuICAgIGlmIChieUlkICE9PSB1bmRlZmluZWQpIHJldHVybiBieUlkO1xuICAgIC8vIEZhbGxiYWNrOiBsb29rIHVwIGJ5IG5hbWUgKHN1cHBvcnRzIGhhbmQtY3JhZnRlZCBzdGFnZU1hcHMgaW4gdGVzdHMgYW5kIGFkdmFuY2VkIHVzZSlcbiAgICByZXR1cm4gdGhpcy5zdGFnZU1hcC5nZXQobm9kZS5uYW1lKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgZXhlY3V0ZVN0YWdlKFxuICAgIG5vZGU6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+LFxuICAgIHN0YWdlRnVuYzogU3RhZ2VGdW5jdGlvbjxUT3V0LCBUU2NvcGU+LFxuICAgIGNvbnRleHQ6IFN0YWdlQ29udGV4dCxcbiAgICBicmVha0ZuOiAoKSA9PiB2b2lkLFxuICApIHtcbiAgICAvLyBydW50aW1lU3RhZ2VJZCBpcyBhc3NpZ25lZCBpbiBleGVjdXRlTm9kZSgpIGJlZm9yZSB0cmF2ZXJzYWxDb250ZXh0IGNyZWF0aW9uLFxuICAgIC8vIGVuc3VyaW5nIHNjb3BlIGV2ZW50cyBhbmQgZmxvdyBldmVudHMgdXNlIHRoZSBzYW1lIHZhbHVlLlxuICAgIHJldHVybiB0aGlzLnN0YWdlUnVubmVyLnJ1bihub2RlLCBzdGFnZUZ1bmMsIGNvbnRleHQsIGJyZWFrRm4pO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZS1vcmRlciBERlMgdHJhdmVyc2FsIOKAlCB0aGUgY29yZSBhbGdvcml0aG0uXG4gICAqIEVhY2ggY2FsbCBwcm9jZXNzZXMgb25lIG5vZGUgdGhyb3VnaCBhbGwgNyBwaGFzZXMuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVOb2RlKFxuICAgIG5vZGU6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+LFxuICAgIGNvbnRleHQ6IFN0YWdlQ29udGV4dCxcbiAgICBicmVha0ZsYWc6IEJyZWFrRmxhZyxcbiAgICBicmFuY2hQYXRoPzogc3RyaW5nLFxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIC8vIOKUgOKUgOKUgCBSZWN1cnNpb24gZGVwdGggZ3VhcmQg4pSA4pSA4pSAXG4gICAgLy8gRWFjaCBgYXdhaXQgZXhlY3V0ZU5vZGUoLi4uKWAga2VlcHMgdGhlIGNhbGxpbmcgZnJhbWUgb24gdGhlIHN0YWNrLlxuICAgIC8vIFdpdGhvdXQgYSBjYXAsIGFuIGluZmluaXRlIGxvb3Agb3IgYW4gZXhjZXNzaXZlbHkgZGVlcCBzdGFnZSBjaGFpbiB3aWxsXG4gICAgLy8gZXZlbnR1YWxseSBvdmVyZmxvdyB0aGUgVjggY2FsbCBzdGFjayAofjEwIDAwMCBmcmFtZXMpIHdpdGggYSBjcnlwdGljXG4gICAgLy8gXCJNYXhpbXVtIGNhbGwgc3RhY2sgc2l6ZSBleGNlZWRlZFwiIGVycm9yLiAgV2UgZmFpbCBlYXJseSB3aXRoIGEgY2xlYXJcbiAgICAvLyBtZXNzYWdlIHNvIHVzZXJzIGNhbiBkaWFnbm9zZSB0aGUgY2F1c2UgKGluZmluaXRlIGxvb3AsIG1pc3NpbmcgYnJlYWssIGV0Yy4pLlxuICAgIC8vIFRoZSBpbmNyZW1lbnQgaXMgaW5zaWRlIGB0cnlgIHNvIGBmaW5hbGx5YCBhbHdheXMgZGVjcmVtZW50cyDigJQgbm8gZnJhZ2lsZVxuICAgIC8vIGdhcCBiZXR3ZWVuIGNoZWNrIGFuZCB0cnkgZW50cnkuXG4gICAgdHJ5IHtcbiAgICAgIGlmICgrK3RoaXMuX2V4ZWN1dGVEZXB0aCA+IHRoaXMuX21heERlcHRoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgRmxvd2NoYXJ0VHJhdmVyc2VyOiBtYXhpbXVtIHRyYXZlcnNhbCBkZXB0aCBleGNlZWRlZCAoJHt0aGlzLl9tYXhEZXB0aH0pLiBgICtcbiAgICAgICAgICAgICdDaGVjayBmb3IgaW5maW5pdGUgbG9vcHMgb3IgbWlzc2luZyBicmVhayBjb25kaXRpb25zIGluIHlvdXIgZmxvd2NoYXJ0LiAnICtcbiAgICAgICAgICAgIGBMYXN0IHN0YWdlOiAnJHtub2RlLm5hbWV9Jy4gYCArXG4gICAgICAgICAgICAnRm9yIGxvb3BUbygpIHBpcGVsaW5lcywgY29uc2lkZXIgYWRkaW5nIGEgYnJlYWsgY29uZGl0aW9uIG9yIHVzaW5nIFJ1bk9wdGlvbnMubWF4RGVwdGggdG8gcmFpc2UgdGhlIGxpbWl0LicsXG4gICAgICAgICk7XG4gICAgICB9XG5cbiAgICAgIC8vIEF0dGFjaCBidWlsZGVyIG1ldGFkYXRhIHRvIGNvbnRleHQgZm9yIHNuYXBzaG90IGVucmljaG1lbnRcbiAgICAgIGlmIChub2RlLmRlc2NyaXB0aW9uKSBjb250ZXh0LmRlc2NyaXB0aW9uID0gbm9kZS5kZXNjcmlwdGlvbjtcbiAgICAgIGlmIChub2RlLmlzU3ViZmxvd1Jvb3QgJiYgbm9kZS5zdWJmbG93SWQpIGNvbnRleHQuc3ViZmxvd0lkID0gbm9kZS5zdWJmbG93SWQ7XG5cbiAgICAgIC8vIEFzc2lnbiBydW50aW1lU3RhZ2VJZCBCRUZPUkUgdHJhdmVyc2FsQ29udGV4dCBjcmVhdGlvbiDigJQgZW5zdXJlcyBzY29wZSBldmVudHNcbiAgICAgIC8vIChidWZmZXJlZCBieSBydW50aW1lU3RhZ2VJZCkgYW5kIGZsb3cgZXZlbnRzIChmbHVzaGVkIGJ5IHRyYXZlcnNhbENvbnRleHQucnVudGltZVN0YWdlSWQpXG4gICAgICAvLyB1c2UgdGhlIHNhbWUgdmFsdWUuIE11c3QgaGFwcGVuIGJlZm9yZSBleGVjdXRlU3RhZ2UgQU5EIGJlZm9yZSB0cmF2ZXJzYWxDb250ZXh0LlxuICAgICAgY29uc3QgaWR4ID0gdGhpcy5fZXhlY3V0aW9uQ291bnRlci52YWx1ZSsrO1xuICAgICAgY29udGV4dC5ydW50aW1lU3RhZ2VJZCA9IGJ1aWxkUnVudGltZVN0YWdlSWQobm9kZS5pZCwgaWR4KTtcblxuICAgICAgLy8gQnVpbGQgdHJhdmVyc2FsIGNvbnRleHQgZm9yIHJlY29yZGVyIGV2ZW50cyDigJQgY3JlYXRlZCBvbmNlIHBlciBzdGFnZSwgc2hhcmVkIGJ5IGFsbCBldmVudHNcbiAgICAgIGNvbnN0IHRyYXZlcnNhbENvbnRleHQ6IFRyYXZlcnNhbENvbnRleHQgPSB7XG4gICAgICAgIHJ1bklkOiB0aGlzLnJ1bklkLFxuICAgICAgICBzdGFnZUlkOiBub2RlLmlkID8/IGNvbnRleHQuc3RhZ2VJZCxcbiAgICAgICAgcnVudGltZVN0YWdlSWQ6IGNvbnRleHQucnVudGltZVN0YWdlSWQsXG4gICAgICAgIHN0YWdlTmFtZTogbm9kZS5uYW1lLFxuICAgICAgICBwYXJlbnRTdGFnZUlkOiBjb250ZXh0LnBhcmVudD8uc3RhZ2VJZCxcbiAgICAgICAgc3ViZmxvd0lkOiBjb250ZXh0LnN1YmZsb3dJZCA/PyB0aGlzLnBhcmVudFN1YmZsb3dJZCxcbiAgICAgICAgc3ViZmxvd1BhdGg6IGJyYW5jaFBhdGggfHwgdW5kZWZpbmVkLFxuICAgICAgICBkZXB0aDogdGhpcy5jb21wdXRlQ29udGV4dERlcHRoKGNvbnRleHQpLFxuICAgICAgfTtcblxuICAgICAgLy8g4pSA4pSA4pSAIFBoYXNlIDBhOiBMQVpZIFJFU09MVkUg4oCUIGRlZmVycmVkIHN1YmZsb3cgcmVzb2x1dGlvbiDilIDilIDilIBcbiAgICAgIC8vIEd1YXJkIHVzZXMgdGhlIHBlci10cmF2ZXJzZXIgcmVzb2x2ZWRMYXp5U3ViZmxvd3Mgc2V0IChub3QgdGhlIHNoYXJlZCBub2RlKSBzb1xuICAgICAgLy8gY29uY3VycmVudCB0cmF2ZXJzZXJzIGRvIG5vdCByYWNlIG9uIG5vZGUuc3ViZmxvd1Jlc29sdmVyIG9yIGNsZWFyIGl0IGZvciBlYWNoIG90aGVyLlxuICAgICAgaWYgKG5vZGUuaXNTdWJmbG93Um9vdCAmJiBub2RlLnN1YmZsb3dSZXNvbHZlciAmJiAhdGhpcy5yZXNvbHZlZExhenlTdWJmbG93cy5oYXMobm9kZS5zdWJmbG93SWQhKSkge1xuICAgICAgICBjb25zdCByZXNvbHZlZCA9IG5vZGUuc3ViZmxvd1Jlc29sdmVyKCk7XG4gICAgICAgIGNvbnN0IHByZWZpeGVkUm9vdCA9IHRoaXMucHJlZml4Tm9kZVRyZWUocmVzb2x2ZWQucm9vdCBhcyBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiwgbm9kZS5zdWJmbG93SWQhKTtcblxuICAgICAgICAvLyBSZWdpc3RlciB0aGUgcmVzb2x2ZWQgc3ViZmxvdyAoc2FtZSBwYXRoIGFzIGVhZ2VyIHJlZ2lzdHJhdGlvbilcbiAgICAgICAgdGhpcy5zdWJmbG93c1tub2RlLnN1YmZsb3dJZCFdID0geyByb290OiBwcmVmaXhlZFJvb3QgfTtcblxuICAgICAgICAvLyBNZXJnZSBzdGFnZU1hcCBlbnRyaWVzXG4gICAgICAgIGZvciAoY29uc3QgW2tleSwgZm5dIG9mIHJlc29sdmVkLnN0YWdlTWFwKSB7XG4gICAgICAgICAgY29uc3QgcHJlZml4ZWRLZXkgPSBgJHtub2RlLnN1YmZsb3dJZH0vJHtrZXl9YDtcbiAgICAgICAgICBpZiAoIXRoaXMuc3RhZ2VNYXAuaGFzKHByZWZpeGVkS2V5KSkge1xuICAgICAgICAgICAgdGhpcy5zdGFnZU1hcC5zZXQocHJlZml4ZWRLZXksIGZuIGFzIFN0YWdlRnVuY3Rpb248VE91dCwgVFNjb3BlPik7XG4gICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gTWVyZ2UgbmVzdGVkIHN1YmZsb3dzXG4gICAgICAgIGlmIChyZXNvbHZlZC5zdWJmbG93cykge1xuICAgICAgICAgIGZvciAoY29uc3QgW2tleSwgZGVmXSBvZiBPYmplY3QuZW50cmllcyhyZXNvbHZlZC5zdWJmbG93cykpIHtcbiAgICAgICAgICAgIGNvbnN0IHByZWZpeGVkS2V5ID0gYCR7bm9kZS5zdWJmbG93SWR9LyR7a2V5fWA7XG4gICAgICAgICAgICBpZiAoIXRoaXMuc3ViZmxvd3NbcHJlZml4ZWRLZXldKSB7XG4gICAgICAgICAgICAgIHRoaXMuc3ViZmxvd3NbcHJlZml4ZWRLZXldID0gZGVmIGFzIHsgcm9vdDogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4gfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBVcGRhdGUgcnVudGltZSBzdHJ1Y3R1cmUgd2l0aCB0aGUgbm93LXJlc29sdmVkIHNwZWNcbiAgICAgICAgdGhpcy5zdHJ1Y3R1cmVNYW5hZ2VyLnVwZGF0ZUR5bmFtaWNTdWJmbG93KFxuICAgICAgICAgIG5vZGUuaWQsXG4gICAgICAgICAgbm9kZS5zdWJmbG93SWQhLFxuICAgICAgICAgIG5vZGUuc3ViZmxvd05hbWUsXG4gICAgICAgICAgcmVzb2x2ZWQuYnVpbGRUaW1lU3RydWN0dXJlLFxuICAgICAgICApO1xuXG4gICAgICAgIC8vIE1hcmsgYXMgcmVzb2x2ZWQgZm9yIFRISVMgdHJhdmVyc2VyIOKAlCBwZXItdHJhdmVyc2VyIHNldCBwcmV2ZW50cyByZS1lbnRyeVxuICAgICAgICAvLyB3aXRob3V0IG11dGF0aW5nIHRoZSBzaGFyZWQgU3RhZ2VOb2RlIGdyYXBoICh3aGljaCB3b3VsZCByYWNlIGNvbmN1cnJlbnQgdHJhdmVyc2VycykuXG4gICAgICAgIHRoaXMucmVzb2x2ZWRMYXp5U3ViZmxvd3MuYWRkKG5vZGUuc3ViZmxvd0lkISk7XG4gICAgICB9XG5cbiAgICAgIC8vIOKUgOKUgOKUgCBQaGFzZSAwOiBDTEFTU0lGWSDigJQgc3ViZmxvdyBkZXRlY3Rpb24g4pSA4pSA4pSAXG4gICAgICBpZiAobm9kZS5pc1N1YmZsb3dSb290ICYmIG5vZGUuc3ViZmxvd0lkKSB7XG4gICAgICAgIGNvbnN0IHJlc29sdmVkTm9kZSA9IHRoaXMubm9kZVJlc29sdmVyLnJlc29sdmVTdWJmbG93UmVmZXJlbmNlKG5vZGUpO1xuXG4gICAgICAgIGNvbnN0IHN1YmZsb3dPdXRwdXQgPSBhd2FpdCB0aGlzLnN1YmZsb3dFeGVjdXRvci5leGVjdXRlU3ViZmxvdyhcbiAgICAgICAgICByZXNvbHZlZE5vZGUsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBicmVha0ZsYWcsXG4gICAgICAgICAgYnJhbmNoUGF0aCxcbiAgICAgICAgICB0aGlzLnN1YmZsb3dSZXN1bHRzLFxuICAgICAgICAgIHRyYXZlcnNhbENvbnRleHQsXG4gICAgICAgICk7XG5cbiAgICAgICAgY29uc3QgaXNSZWZlcmVuY2VCYXNlZFN1YmZsb3cgPSByZXNvbHZlZE5vZGUgIT09IG5vZGU7XG4gICAgICAgIGNvbnN0IGhhc0NoaWxkcmVuID0gQm9vbGVhbihub2RlLmNoaWxkcmVuICYmIG5vZGUuY2hpbGRyZW4ubGVuZ3RoID4gMCk7XG4gICAgICAgIGNvbnN0IHNob3VsZEV4ZWN1dGVDb250aW51YXRpb24gPSBpc1JlZmVyZW5jZUJhc2VkU3ViZmxvdyB8fCBoYXNDaGlsZHJlbjtcblxuICAgICAgICAvLyDilIDilIDilIAgQnJlYWstZmxhZyBjaGVjayBBRlRFUiBzdWJmbG93IHJldHVybnMg4pSA4pSA4pSAXG4gICAgICAgIC8vIElmIHRoZSBzdWJmbG93IHdhcyBtb3VudGVkIHdpdGggYHByb3BhZ2F0ZUJyZWFrOiB0cnVlYCBhbmQgYnJva2VcbiAgICAgICAgLy8gaW50ZXJuYWxseSwgYFN1YmZsb3dFeGVjdXRvcmAgaGFzIGFscmVhZHkgZmxpcHBlZCBvdXIgYnJlYWtGbGFnLlxuICAgICAgICAvLyBTdG9wIHRoZSBvdXRlciB0cmF2ZXJzYWwgaGVyZSDigJQgZG8gbm90IHJ1biB0aGUgbmV4dCBsaW5lYXIgc3RhZ2UuXG4gICAgICAgIGlmIChicmVha0ZsYWcuc2hvdWxkQnJlYWspIHtcbiAgICAgICAgICByZXR1cm4gc3ViZmxvd091dHB1dDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChub2RlLm5leHQgJiYgc2hvdWxkRXhlY3V0ZUNvbnRpbnVhdGlvbikge1xuICAgICAgICAgIGNvbnN0IG5leHRDdHggPSBjb250ZXh0LmNyZWF0ZU5leHQoYnJhbmNoUGF0aCBhcyBzdHJpbmcsIG5vZGUubmV4dC5uYW1lLCBub2RlLm5leHQuaWQpO1xuICAgICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmV4ZWN1dGVOb2RlKG5vZGUubmV4dCwgbmV4dEN0eCwgYnJlYWtGbGFnLCBicmFuY2hQYXRoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBzdWJmbG93T3V0cHV0O1xuICAgICAgfVxuXG4gICAgICBjb25zdCBzdGFnZUZ1bmMgPSB0aGlzLmdldFN0YWdlRm4obm9kZSk7XG4gICAgICBjb25zdCBoYXNTdGFnZUZ1bmN0aW9uID0gQm9vbGVhbihzdGFnZUZ1bmMpO1xuICAgICAgY29uc3QgaXNTY29wZUJhc2VkRGVjaWRlciA9IEJvb2xlYW4obm9kZS5kZWNpZGVyRm4pO1xuICAgICAgY29uc3QgaXNTY29wZUJhc2VkU2VsZWN0b3IgPSBCb29sZWFuKG5vZGUuc2VsZWN0b3JGbik7XG4gICAgICBjb25zdCBpc0RlY2lkZXJOb2RlID0gaXNTY29wZUJhc2VkRGVjaWRlcjtcbiAgICAgIGNvbnN0IGhhc0NoaWxkcmVuID0gQm9vbGVhbihub2RlLmNoaWxkcmVuPy5sZW5ndGgpO1xuICAgICAgY29uc3QgaGFzTmV4dCA9IEJvb2xlYW4obm9kZS5uZXh0KTtcbiAgICAgIGNvbnN0IG9yaWdpbmFsTmV4dCA9IG5vZGUubmV4dDtcblxuICAgICAgLy8g4pSA4pSA4pSAIFBoYXNlIDE6IFZBTElEQVRFIOKAlCBub2RlIGludmFyaWFudHMg4pSA4pSA4pSAXG4gICAgICBpZiAoIWhhc1N0YWdlRnVuY3Rpb24gJiYgIWlzRGVjaWRlck5vZGUgJiYgIWlzU2NvcGVCYXNlZFNlbGVjdG9yICYmICFoYXNDaGlsZHJlbikge1xuICAgICAgICBjb25zdCBlcnJvck1lc3NhZ2UgPSBgTm9kZSAnJHtub2RlLm5hbWV9JyBtdXN0IGRlZmluZTogZW1iZWRkZWQgZm4gT1IgYSBzdGFnZU1hcCBlbnRyeSBPUiBoYXZlIGNoaWxkcmVuL2RlY2lkZXJgO1xuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihgRXJyb3IgaW4gcGlwZWxpbmUgKCR7YnJhbmNoUGF0aH0pIHN0YWdlIFske25vZGUubmFtZX1dOmAsIHsgZXJyb3I6IGVycm9yTWVzc2FnZSB9KTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgICB9XG4gICAgICBpZiAoaXNEZWNpZGVyTm9kZSAmJiAhaGFzQ2hpbGRyZW4pIHtcbiAgICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gJ0RlY2lkZXIgbm9kZSBuZWVkcyB0byBoYXZlIGNoaWxkcmVuIHRvIGV4ZWN1dGUnO1xuICAgICAgICB0aGlzLmxvZ2dlci5lcnJvcihgRXJyb3IgaW4gcGlwZWxpbmUgKCR7YnJhbmNoUGF0aH0pIHN0YWdlIFske25vZGUubmFtZX1dOmAsIHsgZXJyb3I6IGVycm9yTWVzc2FnZSB9KTtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgICB9XG4gICAgICBpZiAoaXNTY29wZUJhc2VkU2VsZWN0b3IgJiYgIWhhc0NoaWxkcmVuKSB7XG4gICAgICAgIGNvbnN0IGVycm9yTWVzc2FnZSA9ICdTZWxlY3RvciBub2RlIG5lZWRzIHRvIGhhdmUgY2hpbGRyZW4gdG8gZXhlY3V0ZSc7XG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGBFcnJvciBpbiBwaXBlbGluZSAoJHticmFuY2hQYXRofSkgc3RhZ2UgWyR7bm9kZS5uYW1lfV06YCwgeyBlcnJvcjogZXJyb3JNZXNzYWdlIH0pO1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgICAgIH1cblxuICAgICAgLy8gUm9sZSBtYXJrZXJzIGZvciBkZWJ1ZyBwYW5lbHNcbiAgICAgIGlmICghaGFzU3RhZ2VGdW5jdGlvbikge1xuICAgICAgICBpZiAoaXNEZWNpZGVyTm9kZSkgY29udGV4dC5zZXRBc0RlY2lkZXIoKTtcbiAgICAgICAgZWxzZSBpZiAoaGFzQ2hpbGRyZW4pIGNvbnRleHQuc2V0QXNGb3JrKCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEJyZWFrIGhhbmRsZXIgd2lyZWQgdG8gdGhlIHNjb3BlLiBDYXB0dXJlcyB0aGUgb3B0aW9uYWwgcmVhc29uXG4gICAgICAvLyBwYXNzZWQgdmlhIGBzY29wZS4kYnJlYWsocmVhc29uKWAgYW5kIHBhcmtzIGl0IG9uIHRoZSBicmVha0ZsYWcgc29cbiAgICAgIC8vIGRvd25zdHJlYW0gY29kZSAoRmxvd1JlY29yZGVyLm9uQnJlYWssIHN1YmZsb3cgcHJvcGFnYXRpb24pIGNhblxuICAgICAgLy8gc3VyZmFjZSBpdC4gQSBzZWNvbmQgJGJyZWFrIGNhbGwgaW4gdGhlIHNhbWUgc3RhZ2Uga2VlcHMgdGhlIEZJUlNUXG4gICAgICAvLyByZWFzb24g4oCUIGZpcnN0LWJyZWFrLXdpbnMg4oCUIG1hdGNoaW5nIHRoZSBcImV4ZWN1dGlvbiBzdG9wcGVkXCIgc3RvcnkuXG4gICAgICBjb25zdCBicmVha0ZuID0gKHJlYXNvbj86IHN0cmluZykgPT4ge1xuICAgICAgICBicmVha0ZsYWcuc2hvdWxkQnJlYWsgPSB0cnVlO1xuICAgICAgICBpZiAocmVhc29uICE9PSB1bmRlZmluZWQgJiYgYnJlYWtGbGFnLnJlYXNvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgYnJlYWtGbGFnLnJlYXNvbiA9IHJlYXNvbjtcbiAgICAgICAgfVxuICAgICAgfTtcblxuICAgICAgLy8g4pSA4pSA4pSAIFBoYXNlIDJhOiBTRUxFQ1RPUiDigJQgc2NvcGUtYmFzZWQgbXVsdGktY2hvaWNlIOKUgOKUgOKUgFxuICAgICAgaWYgKGlzU2NvcGVCYXNlZFNlbGVjdG9yKSB7XG4gICAgICAgIGNvbnN0IHNlbGVjdG9yUmVzdWx0ID0gYXdhaXQgdGhpcy5zZWxlY3RvckhhbmRsZXIuaGFuZGxlU2NvcGVCYXNlZChcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIHN0YWdlRnVuYyEsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBicmVha0ZsYWcsXG4gICAgICAgICAgYnJhbmNoUGF0aCxcbiAgICAgICAgICB0aGlzLmV4ZWN1dGVTdGFnZS5iaW5kKHRoaXMpLFxuICAgICAgICAgIHRoaXMuZXhlY3V0ZU5vZGUuYmluZCh0aGlzKSxcbiAgICAgICAgICB0cmF2ZXJzYWxDb250ZXh0LFxuICAgICAgICApO1xuXG4gICAgICAgIGlmIChoYXNOZXh0KSB7XG4gICAgICAgICAgY29uc3QgbmV4dEN0eCA9IGNvbnRleHQuY3JlYXRlTmV4dChicmFuY2hQYXRoIGFzIHN0cmluZywgbm9kZS5uZXh0IS5uYW1lLCBub2RlLm5leHQhLmlkKTtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5leGVjdXRlTm9kZShub2RlLm5leHQhLCBuZXh0Q3R4LCBicmVha0ZsYWcsIGJyYW5jaFBhdGgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzZWxlY3RvclJlc3VsdDtcbiAgICAgIH1cblxuICAgICAgLy8g4pSA4pSA4pSAIFBoYXNlIDJiOiBERUNJREVSIOKAlCBzY29wZS1iYXNlZCBzaW5nbGUtY2hvaWNlIGNvbmRpdGlvbmFsIGJyYW5jaCDilIDilIDilIBcbiAgICAgIGlmIChpc0RlY2lkZXJOb2RlKSB7XG4gICAgICAgIGNvbnN0IGRlY2lkZXJSZXN1bHQgPSBhd2FpdCB0aGlzLmRlY2lkZXJIYW5kbGVyLmhhbmRsZVNjb3BlQmFzZWQoXG4gICAgICAgICAgbm9kZSxcbiAgICAgICAgICBzdGFnZUZ1bmMhLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgYnJlYWtGbGFnLFxuICAgICAgICAgIGJyYW5jaFBhdGgsXG4gICAgICAgICAgdGhpcy5leGVjdXRlU3RhZ2UuYmluZCh0aGlzKSxcbiAgICAgICAgICB0aGlzLmV4ZWN1dGVOb2RlLmJpbmQodGhpcyksXG4gICAgICAgICAgdHJhdmVyc2FsQ29udGV4dCxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBBZnRlciBicmFuY2ggZXhlY3V0aW9uLCBmb2xsb3cgZGVjaWRlcidzIG93biBuZXh0IChlLmcuLCBsb29wVG8gdGFyZ2V0KVxuICAgICAgICBpZiAoaGFzTmV4dCAmJiAhYnJlYWtGbGFnLnNob3VsZEJyZWFrKSB7XG4gICAgICAgICAgY29uc3QgbmV4dE5vZGUgPSBvcmlnaW5hbE5leHQhO1xuICAgICAgICAgIC8vIFVzZSB0aGUgaXNMb29wUmVmIGZsYWcgc2V0IGJ5IGxvb3BUbygpIOKAlCBkbyBub3QgcmVseSBvbiBzdGFnZU1hcCBhYnNlbmNlLFxuICAgICAgICAgIC8vIHNpbmNlIGlkLWtleWVkIHN0YWdlTWFwcyB3b3VsZCBvdGhlcndpc2UgY2F1c2UgbG9vcCB0YXJnZXRzIHRvIGJlIGV4ZWN1dGVkIGRpcmVjdGx5LlxuICAgICAgICAgIGNvbnN0IGlzTG9vcFJlZiA9XG4gICAgICAgICAgICBuZXh0Tm9kZS5pc0xvb3BSZWYgPT09IHRydWUgfHxcbiAgICAgICAgICAgICghdGhpcy5nZXRTdGFnZUZuKG5leHROb2RlKSAmJlxuICAgICAgICAgICAgICAhbmV4dE5vZGUuY2hpbGRyZW4/Lmxlbmd0aCAmJlxuICAgICAgICAgICAgICAhbmV4dE5vZGUuZGVjaWRlckZuICYmXG4gICAgICAgICAgICAgICFuZXh0Tm9kZS5zZWxlY3RvckZuICYmXG4gICAgICAgICAgICAgICFuZXh0Tm9kZS5pc1N1YmZsb3dSb290KTtcblxuICAgICAgICAgIGlmIChpc0xvb3BSZWYpIHtcbiAgICAgICAgICAgIHJldHVybiB0aGlzLmNvbnRpbnVhdGlvblJlc29sdmVyLnJlc29sdmUoXG4gICAgICAgICAgICAgIG5leHROb2RlLFxuICAgICAgICAgICAgICBub2RlLFxuICAgICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgICAgICBicmVha0ZsYWcsXG4gICAgICAgICAgICAgIGJyYW5jaFBhdGgsXG4gICAgICAgICAgICAgIHRoaXMuZXhlY3V0ZU5vZGUuYmluZCh0aGlzKSxcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3Iub25OZXh0KG5vZGUubmFtZSwgbmV4dE5vZGUubmFtZSwgbmV4dE5vZGUuZGVzY3JpcHRpb24sIHRyYXZlcnNhbENvbnRleHQpO1xuICAgICAgICAgIGNvbnN0IG5leHRDdHggPSBjb250ZXh0LmNyZWF0ZU5leHQoYnJhbmNoUGF0aCBhcyBzdHJpbmcsIG5leHROb2RlLm5hbWUsIG5leHROb2RlLmlkKTtcbiAgICAgICAgICByZXR1cm4gYXdhaXQgdGhpcy5leGVjdXRlTm9kZShuZXh0Tm9kZSwgbmV4dEN0eCwgYnJlYWtGbGFnLCBicmFuY2hQYXRoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBkZWNpZGVyUmVzdWx0O1xuICAgICAgfVxuXG4gICAgICAvLyDilIDilIDilIAgQWJvcnQgY2hlY2sg4oCUIGNvb3BlcmF0aXZlIGNhbmNlbGxhdGlvbiDilIDilIDilIBcbiAgICAgIGlmICh0aGlzLnNpZ25hbD8uYWJvcnRlZCkge1xuICAgICAgICBjb25zdCByZWFzb24gPVxuICAgICAgICAgIHRoaXMuc2lnbmFsLnJlYXNvbiBpbnN0YW5jZW9mIEVycm9yID8gdGhpcy5zaWduYWwucmVhc29uIDogbmV3IEVycm9yKHRoaXMuc2lnbmFsLnJlYXNvbiA/PyAnQWJvcnRlZCcpO1xuICAgICAgICB0aHJvdyByZWFzb247XG4gICAgICB9XG5cbiAgICAgIC8vIOKUgOKUgOKUgCBQaGFzZSAzOiBFWEVDVVRFIOKAlCBydW4gc3RhZ2UgZnVuY3Rpb24g4pSA4pSA4pSAXG4gICAgICBsZXQgc3RhZ2VPdXRwdXQ6IFRPdXQgfCB1bmRlZmluZWQ7XG4gICAgICBsZXQgZHluYW1pY05leHQ6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+IHwgdW5kZWZpbmVkO1xuXG4gICAgICBpZiAoc3RhZ2VGdW5jKSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgc3RhZ2VPdXRwdXQgPSBhd2FpdCB0aGlzLmV4ZWN1dGVTdGFnZShub2RlLCBzdGFnZUZ1bmMsIGNvbnRleHQsIGJyZWFrRm4pO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogYW55KSB7XG4gICAgICAgICAgLy8gUGF1c2VTaWduYWwgaXMgZXhwZWN0ZWQgY29udHJvbCBmbG93LCBub3QgYW4gZXJyb3Ig4oCUIGZpcmUgbmFycmF0aXZlLCBjb21taXQsIHJlLXRocm93LlxuICAgICAgICAgIGlmIChpc1BhdXNlU2lnbmFsKGVycm9yKSkge1xuICAgICAgICAgICAgY29udGV4dC5jb21taXQoKTtcbiAgICAgICAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yLm9uUGF1c2Uobm9kZS5uYW1lLCBub2RlLmlkLCBlcnJvci5wYXVzZURhdGEsIGVycm9yLnN1YmZsb3dQYXRoLCB0cmF2ZXJzYWxDb250ZXh0KTtcbiAgICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb250ZXh0LmNvbW1pdCgpO1xuICAgICAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yLm9uRXJyb3Iobm9kZS5uYW1lLCBlcnJvci50b1N0cmluZygpLCBlcnJvciwgdHJhdmVyc2FsQ29udGV4dCk7XG4gICAgICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoYEVycm9yIGluIHBpcGVsaW5lICgke2JyYW5jaFBhdGh9KSBzdGFnZSBbJHtub2RlLm5hbWV9XTpgLCB7IGVycm9yIH0pO1xuICAgICAgICAgIGNvbnRleHQuYWRkRXJyb3IoJ3N0YWdlRXhlY3V0aW9uRXJyb3InLCBlcnJvci50b1N0cmluZygpKTtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBjb250ZXh0LmNvbW1pdCgpO1xuICAgICAgICB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvci5vblN0YWdlRXhlY3V0ZWQobm9kZS5uYW1lLCBub2RlLmRlc2NyaXB0aW9uLCB0cmF2ZXJzYWxDb250ZXh0LCAnbGluZWFyJyk7XG5cbiAgICAgICAgaWYgKGJyZWFrRmxhZy5zaG91bGRCcmVhaykge1xuICAgICAgICAgIC8vIEZvcndhcmQgdGhlIG9wdGlvbmFsIHJlYXNvbiBjYXB0dXJlZCBvbiBicmVha0ZsYWcg4oCUIHNldCBieSB0aGVcbiAgICAgICAgICAvLyBzdGFnZSdzICRicmVhayhyZWFzb24pIGNhbGwgT1IgYnkgYSBzdWJmbG93J3MgcHJvcGFnYXRlQnJlYWsuXG4gICAgICAgICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3Iub25CcmVhayhub2RlLm5hbWUsIHRyYXZlcnNhbENvbnRleHQsIGJyZWFrRmxhZy5yZWFzb24pO1xuICAgICAgICAgIHJldHVybiBzdGFnZU91dHB1dDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIOKUgOKUgOKUgCBQaGFzZSA0OiBEWU5BTUlDIOKAlCBTdGFnZU5vZGUgcmV0dXJuIGRldGVjdGlvbiDilIDilIDilIBcbiAgICAgICAgaWYgKHN0YWdlT3V0cHV0ICYmIHR5cGVvZiBzdGFnZU91dHB1dCA9PT0gJ29iamVjdCcgJiYgaXNTdGFnZU5vZGVSZXR1cm4oc3RhZ2VPdXRwdXQpKSB7XG4gICAgICAgICAgY29uc3QgZHluYW1pY05vZGUgPSBzdGFnZU91dHB1dCBhcyBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPjtcbiAgICAgICAgICBjb250ZXh0LmFkZExvZygnaXNEeW5hbWljJywgdHJ1ZSk7XG4gICAgICAgICAgY29udGV4dC5hZGRMb2coJ2R5bmFtaWNQYXR0ZXJuJywgJ1N0YWdlTm9kZVJldHVybicpO1xuXG4gICAgICAgICAgLy8gRHluYW1pYyBzdWJmbG93IGF1dG8tcmVnaXN0cmF0aW9uXG4gICAgICAgICAgaWYgKGR5bmFtaWNOb2RlLmlzU3ViZmxvd1Jvb3QgJiYgZHluYW1pY05vZGUuc3ViZmxvd0RlZiAmJiBkeW5hbWljTm9kZS5zdWJmbG93SWQpIHtcbiAgICAgICAgICAgIGNvbnRleHQuYWRkTG9nKCdkeW5hbWljUGF0dGVybicsICdkeW5hbWljU3ViZmxvdycpO1xuICAgICAgICAgICAgY29udGV4dC5hZGRMb2coJ2R5bmFtaWNTdWJmbG93SWQnLCBkeW5hbWljTm9kZS5zdWJmbG93SWQpO1xuXG4gICAgICAgICAgICB0aGlzLmF1dG9SZWdpc3RlclN1YmZsb3dEZWYoZHluYW1pY05vZGUuc3ViZmxvd0lkLCBkeW5hbWljTm9kZS5zdWJmbG93RGVmLCBub2RlLmlkKTtcblxuICAgICAgICAgICAgbm9kZS5pc1N1YmZsb3dSb290ID0gdHJ1ZTtcbiAgICAgICAgICAgIG5vZGUuc3ViZmxvd0lkID0gZHluYW1pY05vZGUuc3ViZmxvd0lkO1xuICAgICAgICAgICAgbm9kZS5zdWJmbG93TmFtZSA9IGR5bmFtaWNOb2RlLnN1YmZsb3dOYW1lO1xuICAgICAgICAgICAgbm9kZS5zdWJmbG93TW91bnRPcHRpb25zID0gZHluYW1pY05vZGUuc3ViZmxvd01vdW50T3B0aW9ucztcblxuICAgICAgICAgICAgdGhpcy5zdHJ1Y3R1cmVNYW5hZ2VyLnVwZGF0ZUR5bmFtaWNTdWJmbG93KFxuICAgICAgICAgICAgICBub2RlLmlkLFxuICAgICAgICAgICAgICBkeW5hbWljTm9kZS5zdWJmbG93SWQhLFxuICAgICAgICAgICAgICBkeW5hbWljTm9kZS5zdWJmbG93TmFtZSxcbiAgICAgICAgICAgICAgZHluYW1pY05vZGUuc3ViZmxvd0RlZj8uYnVpbGRUaW1lU3RydWN0dXJlLFxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuZXhlY3V0ZU5vZGUobm9kZSwgY29udGV4dCwgYnJlYWtGbGFnLCBicmFuY2hQYXRoKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBDaGVjayBjaGlsZHJlbiBmb3Igc3ViZmxvd0RlZlxuICAgICAgICAgIGlmIChkeW5hbWljTm9kZS5jaGlsZHJlbikge1xuICAgICAgICAgICAgZm9yIChjb25zdCBjaGlsZCBvZiBkeW5hbWljTm9kZS5jaGlsZHJlbikge1xuICAgICAgICAgICAgICBpZiAoY2hpbGQuaXNTdWJmbG93Um9vdCAmJiBjaGlsZC5zdWJmbG93RGVmICYmIGNoaWxkLnN1YmZsb3dJZCkge1xuICAgICAgICAgICAgICAgIHRoaXMuYXV0b1JlZ2lzdGVyU3ViZmxvd0RlZihjaGlsZC5zdWJmbG93SWQsIGNoaWxkLnN1YmZsb3dEZWYsIGNoaWxkLmlkKTtcbiAgICAgICAgICAgICAgICB0aGlzLnN0cnVjdHVyZU1hbmFnZXIudXBkYXRlRHluYW1pY1N1YmZsb3coXG4gICAgICAgICAgICAgICAgICBjaGlsZC5pZCxcbiAgICAgICAgICAgICAgICAgIGNoaWxkLnN1YmZsb3dJZCEsXG4gICAgICAgICAgICAgICAgICBjaGlsZC5zdWJmbG93TmFtZSxcbiAgICAgICAgICAgICAgICAgIGNoaWxkLnN1YmZsb3dEZWY/LmJ1aWxkVGltZVN0cnVjdHVyZSxcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gRHluYW1pYyBjaGlsZHJlbiAoZm9yayBwYXR0ZXJuKVxuICAgICAgICAgIGlmIChkeW5hbWljTm9kZS5jaGlsZHJlbiAmJiBkeW5hbWljTm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBub2RlLmNoaWxkcmVuID0gZHluYW1pY05vZGUuY2hpbGRyZW47XG4gICAgICAgICAgICBjb250ZXh0LmFkZExvZygnZHluYW1pY0NoaWxkQ291bnQnLCBkeW5hbWljTm9kZS5jaGlsZHJlbi5sZW5ndGgpO1xuICAgICAgICAgICAgY29udGV4dC5hZGRMb2coXG4gICAgICAgICAgICAgICdkeW5hbWljQ2hpbGRJZHMnLFxuICAgICAgICAgICAgICBkeW5hbWljTm9kZS5jaGlsZHJlbi5tYXAoKGMpID0+IGMuaWQpLFxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgdGhpcy5zdHJ1Y3R1cmVNYW5hZ2VyLnVwZGF0ZUR5bmFtaWNDaGlsZHJlbihcbiAgICAgICAgICAgICAgbm9kZS5pZCxcbiAgICAgICAgICAgICAgZHluYW1pY05vZGUuY2hpbGRyZW4sXG4gICAgICAgICAgICAgIEJvb2xlYW4oZHluYW1pY05vZGUubmV4dE5vZGVTZWxlY3RvciksXG4gICAgICAgICAgICAgIEJvb2xlYW4oZHluYW1pY05vZGUuZGVjaWRlckZuKSxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGlmICh0eXBlb2YgZHluYW1pY05vZGUubmV4dE5vZGVTZWxlY3RvciA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgICAgICBub2RlLm5leHROb2RlU2VsZWN0b3IgPSBkeW5hbWljTm9kZS5uZXh0Tm9kZVNlbGVjdG9yO1xuICAgICAgICAgICAgICBjb250ZXh0LmFkZExvZygnaGFzU2VsZWN0b3InLCB0cnVlKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG5cbiAgICAgICAgICAvLyBEeW5hbWljIG5leHQgKGxpbmVhciBjb250aW51YXRpb24pXG4gICAgICAgICAgaWYgKGR5bmFtaWNOb2RlLm5leHQpIHtcbiAgICAgICAgICAgIGR5bmFtaWNOZXh0ID0gZHluYW1pY05vZGUubmV4dDtcbiAgICAgICAgICAgIHRoaXMuc3RydWN0dXJlTWFuYWdlci51cGRhdGVEeW5hbWljTmV4dChub2RlLmlkLCBkeW5hbWljTm9kZS5uZXh0KTtcbiAgICAgICAgICAgIG5vZGUubmV4dCA9IGR5bmFtaWNOb2RlLm5leHQ7XG4gICAgICAgICAgICBjb250ZXh0LmFkZExvZygnaGFzRHluYW1pY05leHQnLCB0cnVlKTtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBzdGFnZU91dHB1dCA9IHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFJlc3RvcmUgb3JpZ2luYWwgbmV4dCB0byBhdm9pZCBzdGFsZSByZWZlcmVuY2Ugb24gbG9vcCByZXZpc2l0XG4gICAgICAgIGlmIChkeW5hbWljTmV4dCkge1xuICAgICAgICAgIG5vZGUubmV4dCA9IG9yaWdpbmFsTmV4dDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyDilIDilIDilIAgUGhhc2UgNTogQ0hJTERSRU4g4oCUIGZvcmsgZGlzcGF0Y2gg4pSA4pSA4pSAXG4gICAgICBjb25zdCBoYXNDaGlsZHJlbkFmdGVyU3RhZ2UgPSBCb29sZWFuKG5vZGUuY2hpbGRyZW4/Lmxlbmd0aCk7XG5cbiAgICAgIGlmIChoYXNDaGlsZHJlbkFmdGVyU3RhZ2UpIHtcbiAgICAgICAgY29udGV4dC5hZGRMb2coJ3RvdGFsQ2hpbGRyZW4nLCBub2RlLmNoaWxkcmVuPy5sZW5ndGgpO1xuICAgICAgICBjb250ZXh0LmFkZExvZygnb3JkZXJPZkV4ZWN1dGlvbicsICdDaGlsZHJlbkFmdGVyU3RhZ2UnKTtcblxuICAgICAgICBsZXQgbm9kZUNoaWxkcmVuUmVzdWx0czogUmVjb3JkPHN0cmluZywgTm9kZVJlc3VsdFR5cGU+O1xuXG4gICAgICAgIGlmIChub2RlLm5leHROb2RlU2VsZWN0b3IpIHtcbiAgICAgICAgICBub2RlQ2hpbGRyZW5SZXN1bHRzID0gYXdhaXQgdGhpcy5jaGlsZHJlbkV4ZWN1dG9yLmV4ZWN1dGVTZWxlY3RlZENoaWxkcmVuKFxuICAgICAgICAgICAgbm9kZS5uZXh0Tm9kZVNlbGVjdG9yLFxuICAgICAgICAgICAgbm9kZS5jaGlsZHJlbiEsXG4gICAgICAgICAgICBzdGFnZU91dHB1dCxcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBicmFuY2hQYXRoIGFzIHN0cmluZyxcbiAgICAgICAgICAgIHRyYXZlcnNhbENvbnRleHQsXG4gICAgICAgICAgICBub2RlLmZhaWxGYXN0LFxuICAgICAgICAgICk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgY2hpbGRDb3VudCA9IG5vZGUuY2hpbGRyZW4/Lmxlbmd0aCA/PyAwO1xuICAgICAgICAgIGNvbnN0IGNoaWxkTmFtZXMgPSBub2RlLmNoaWxkcmVuPy5tYXAoKGMpID0+IGMubmFtZSkuam9pbignLCAnKTtcbiAgICAgICAgICBjb250ZXh0LmFkZEZsb3dEZWJ1Z01lc3NhZ2UoJ2NoaWxkcmVuJywgYEV4ZWN1dGluZyBhbGwgJHtjaGlsZENvdW50fSBjaGlsZHJlbiBpbiBwYXJhbGxlbDogJHtjaGlsZE5hbWVzfWAsIHtcbiAgICAgICAgICAgIGNvdW50OiBjaGlsZENvdW50LFxuICAgICAgICAgICAgdGFyZ2V0U3RhZ2U6IG5vZGUuY2hpbGRyZW4/Lm1hcCgoYykgPT4gYy5uYW1lKSxcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIG5vZGVDaGlsZHJlblJlc3VsdHMgPSBhd2FpdCB0aGlzLmNoaWxkcmVuRXhlY3V0b3IuZXhlY3V0ZU5vZGVDaGlsZHJlbihcbiAgICAgICAgICAgIG5vZGUsXG4gICAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgICAgYnJhbmNoUGF0aCxcbiAgICAgICAgICAgIHRyYXZlcnNhbENvbnRleHQsXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZvcmstb25seTogcmV0dXJuIGJ1bmRsZVxuICAgICAgICBpZiAoIWhhc05leHQgJiYgIWR5bmFtaWNOZXh0KSB7XG4gICAgICAgICAgcmV0dXJuIG5vZGVDaGlsZHJlblJlc3VsdHMhO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ2FwdHVyZSBkeW5hbWljIGNoaWxkcmVuIGFzIHN5bnRoZXRpYyBzdWJmbG93IHJlc3VsdCBmb3IgVUlcbiAgICAgICAgY29uc3QgaXNEeW5hbWljID0gY29udGV4dC5kZWJ1Zz8ubG9nQ29udGV4dD8uaXNEeW5hbWljO1xuICAgICAgICBpZiAoaXNEeW5hbWljICYmIG5vZGUuY2hpbGRyZW4gJiYgbm9kZS5jaGlsZHJlbi5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgdGhpcy5jYXB0dXJlRHluYW1pY0NoaWxkcmVuUmVzdWx0KG5vZGUsIGNvbnRleHQpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIOKUgOKUgOKUgCBQaGFzZSA2OiBDT05USU5VRSDigJQgZHluYW1pYyBuZXh0IC8gbGluZWFyIG5leHQg4pSA4pSA4pSAXG4gICAgICBpZiAoZHluYW1pY05leHQpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udGludWF0aW9uUmVzb2x2ZXIucmVzb2x2ZShcbiAgICAgICAgICBkeW5hbWljTmV4dCxcbiAgICAgICAgICBub2RlLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgYnJlYWtGbGFnLFxuICAgICAgICAgIGJyYW5jaFBhdGgsXG4gICAgICAgICAgdGhpcy5leGVjdXRlTm9kZS5iaW5kKHRoaXMpLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBpZiAoaGFzTmV4dCkge1xuICAgICAgICBjb25zdCBuZXh0Tm9kZSA9IG9yaWdpbmFsTmV4dCE7XG5cbiAgICAgICAgLy8gRGV0ZWN0IGxvb3AgcmVmZXJlbmNlIG5vZGVzIGNyZWF0ZWQgYnkgbG9vcFRvKCkg4oCUIG1hcmtlZCB3aXRoIGlzTG9vcFJlZiBmbGFnLlxuICAgICAgICAvLyBSb3V0ZSB0aHJvdWdoIENvbnRpbnVhdGlvblJlc29sdmVyIGZvciBwcm9wZXIgSUQgcmVzb2x1dGlvbiwgaXRlcmF0aW9uXG4gICAgICAgIC8vIHRyYWNraW5nLCBhbmQgbmFycmF0aXZlIGdlbmVyYXRpb24uXG4gICAgICAgIGNvbnN0IGlzTG9vcFJlZmVyZW5jZSA9IG5leHROb2RlLmlzTG9vcFJlZjtcblxuICAgICAgICBpZiAoaXNMb29wUmVmZXJlbmNlKSB7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuY29udGludWF0aW9uUmVzb2x2ZXIucmVzb2x2ZShcbiAgICAgICAgICAgIG5leHROb2RlLFxuICAgICAgICAgICAgbm9kZSxcbiAgICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgICBicmVha0ZsYWcsXG4gICAgICAgICAgICBicmFuY2hQYXRoLFxuICAgICAgICAgICAgdGhpcy5leGVjdXRlTm9kZS5iaW5kKHRoaXMpLFxuICAgICAgICAgICAgdHJhdmVyc2FsQ29udGV4dCxcbiAgICAgICAgICApO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3Iub25OZXh0KG5vZGUubmFtZSwgbmV4dE5vZGUubmFtZSwgbmV4dE5vZGUuZGVzY3JpcHRpb24sIHRyYXZlcnNhbENvbnRleHQpO1xuICAgICAgICBjb250ZXh0LmFkZEZsb3dEZWJ1Z01lc3NhZ2UoJ25leHQnLCBgTW92aW5nIHRvICR7bmV4dE5vZGUubmFtZX0gc3RhZ2VgLCB7XG4gICAgICAgICAgdGFyZ2V0U3RhZ2U6IG5leHROb2RlLm5hbWUsXG4gICAgICAgIH0pO1xuICAgICAgICBjb25zdCBuZXh0Q3R4ID0gY29udGV4dC5jcmVhdGVOZXh0KGJyYW5jaFBhdGggYXMgc3RyaW5nLCBuZXh0Tm9kZS5uYW1lLCBuZXh0Tm9kZS5pZCk7XG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLmV4ZWN1dGVOb2RlKG5leHROb2RlLCBuZXh0Q3R4LCBicmVha0ZsYWcsIGJyYW5jaFBhdGgpO1xuICAgICAgfVxuXG4gICAgICAvLyDilIDilIDilIAgUGhhc2UgNzogTEVBRiDigJQgbm8gY29udGludWF0aW9uIOKUgOKUgOKUgFxuICAgICAgcmV0dXJuIHN0YWdlT3V0cHV0O1xuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLl9leGVjdXRlRGVwdGgtLTtcbiAgICB9XG4gIH1cblxuICAvLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAgUHJpdmF0ZSBIZWxwZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuXG4gIHByaXZhdGUgY2FwdHVyZUR5bmFtaWNDaGlsZHJlblJlc3VsdChub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiwgY29udGV4dDogU3RhZ2VDb250ZXh0KTogdm9pZCB7XG4gICAgY29uc3QgcGFyZW50U3RhZ2VJZCA9IGNvbnRleHQuZ2V0U3RhZ2VJZCgpO1xuXG4gICAgY29uc3QgY2hpbGRTdHJ1Y3R1cmU6IGFueSA9IHtcbiAgICAgIGlkOiBgJHtub2RlLmlkfS1jaGlsZHJlbmAsXG4gICAgICBuYW1lOiAnRHluYW1pYyBDaGlsZHJlbicsXG4gICAgICB0eXBlOiAnZm9yaycsXG4gICAgICBjaGlsZHJlbjogbm9kZS5jaGlsZHJlbiEubWFwKChjKSA9PiAoe1xuICAgICAgICBpZDogYy5pZCxcbiAgICAgICAgbmFtZTogYy5uYW1lLFxuICAgICAgICB0eXBlOiAnc3RhZ2UnLFxuICAgICAgfSkpLFxuICAgIH07XG5cbiAgICBjb25zdCBjaGlsZFN0YWdlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICBpZiAoY29udGV4dC5jaGlsZHJlbikge1xuICAgICAgZm9yIChjb25zdCBjaGlsZEN0eCBvZiBjb250ZXh0LmNoaWxkcmVuKSB7XG4gICAgICAgIGNvbnN0IHNuYXBzaG90ID0gY2hpbGRDdHguZ2V0U25hcHNob3QoKTtcbiAgICAgICAgY2hpbGRTdGFnZXNbc25hcHNob3QubmFtZSB8fCBzbmFwc2hvdC5pZF0gPSB7XG4gICAgICAgICAgbmFtZTogc25hcHNob3QubmFtZSxcbiAgICAgICAgICBvdXRwdXQ6IHNuYXBzaG90LmxvZ3MsXG4gICAgICAgICAgZXJyb3JzOiBzbmFwc2hvdC5lcnJvcnMsXG4gICAgICAgICAgbWV0cmljczogc25hcHNob3QubWV0cmljcyxcbiAgICAgICAgICBzdGF0dXM6IHNuYXBzaG90LmVycm9ycyAmJiBPYmplY3Qua2V5cyhzbmFwc2hvdC5lcnJvcnMpLmxlbmd0aCA+IDAgPyAnZXJyb3InIDogJ3N1Y2Nlc3MnLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc3ViZmxvd1Jlc3VsdHMuc2V0KG5vZGUuaWQsIHtcbiAgICAgIHN1YmZsb3dJZDogbm9kZS5pZCxcbiAgICAgIHN1YmZsb3dOYW1lOiBub2RlLm5hbWUsXG4gICAgICB0cmVlQ29udGV4dDoge1xuICAgICAgICBnbG9iYWxDb250ZXh0OiB7fSxcbiAgICAgICAgc3RhZ2VDb250ZXh0czogY2hpbGRTdGFnZXMgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICAgaGlzdG9yeTogW10sXG4gICAgICB9LFxuICAgICAgcGFyZW50U3RhZ2VJZCxcbiAgICAgIHBpcGVsaW5lU3RydWN0dXJlOiBjaGlsZFN0cnVjdHVyZSxcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgY29tcHV0ZUNvbnRleHREZXB0aChjb250ZXh0OiBTdGFnZUNvbnRleHQpOiBudW1iZXIge1xuICAgIGxldCBkZXB0aCA9IDA7XG4gICAgbGV0IGN1cnJlbnQgPSBjb250ZXh0LnBhcmVudDtcbiAgICB3aGlsZSAoY3VycmVudCkge1xuICAgICAgZGVwdGgrKztcbiAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnBhcmVudDtcbiAgICB9XG4gICAgcmV0dXJuIGRlcHRoO1xuICB9XG5cbiAgcHJpdmF0ZSBwcmVmaXhOb2RlVHJlZShub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiwgcHJlZml4OiBzdHJpbmcpOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiB7XG4gICAgaWYgKCFub2RlKSByZXR1cm4gbm9kZTtcbiAgICBjb25zdCBjbG9uZTogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4gPSB7IC4uLm5vZGUgfTtcbiAgICBjbG9uZS5uYW1lID0gYCR7cHJlZml4fS8ke25vZGUubmFtZX1gO1xuICAgIGNsb25lLmlkID0gYCR7cHJlZml4fS8ke2Nsb25lLmlkfWA7XG4gICAgaWYgKGNsb25lLnN1YmZsb3dJZCkgY2xvbmUuc3ViZmxvd0lkID0gYCR7cHJlZml4fS8ke2Nsb25lLnN1YmZsb3dJZH1gO1xuICAgIGlmIChjbG9uZS5uZXh0KSBjbG9uZS5uZXh0ID0gdGhpcy5wcmVmaXhOb2RlVHJlZShjbG9uZS5uZXh0LCBwcmVmaXgpO1xuICAgIGlmIChjbG9uZS5jaGlsZHJlbikge1xuICAgICAgY2xvbmUuY2hpbGRyZW4gPSBjbG9uZS5jaGlsZHJlbi5tYXAoKGMpID0+IHRoaXMucHJlZml4Tm9kZVRyZWUoYywgcHJlZml4KSk7XG4gICAgfVxuICAgIHJldHVybiBjbG9uZTtcbiAgfVxuXG4gIHByaXZhdGUgYXV0b1JlZ2lzdGVyU3ViZmxvd0RlZihcbiAgICBzdWJmbG93SWQ6IHN0cmluZyxcbiAgICBzdWJmbG93RGVmOiBOb25OdWxsYWJsZTxTdGFnZU5vZGVbJ3N1YmZsb3dEZWYnXT4sXG4gICAgbW91bnROb2RlSWQ/OiBzdHJpbmcsXG4gICk6IHZvaWQge1xuICAgIC8vIHRoaXMuc3ViZmxvd3MgaXMgYWx3YXlzIGluaXRpYWxpemVkIGluIHRoZSBjb25zdHJ1Y3RvcjsgdGhlIG51bGwgZ3VhcmQgYmVsb3cgaXMgdW5yZWFjaGFibGUuXG4gICAgY29uc3Qgc3ViZmxvd3NEaWN0ID0gdGhpcy5zdWJmbG93cztcblxuICAgIC8vIEZpcnN0LXdyaXRlLXdpbnNcbiAgICBjb25zdCBpc05ld1JlZ2lzdHJhdGlvbiA9ICFzdWJmbG93c0RpY3Rbc3ViZmxvd0lkXTtcbiAgICBpZiAoaXNOZXdSZWdpc3RyYXRpb24gJiYgc3ViZmxvd0RlZi5yb290KSB7XG4gICAgICBzdWJmbG93c0RpY3Rbc3ViZmxvd0lkXSA9IHtcbiAgICAgICAgcm9vdDogc3ViZmxvd0RlZi5yb290IGFzIFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+LFxuICAgICAgICAuLi4oc3ViZmxvd0RlZi5idWlsZFRpbWVTdHJ1Y3R1cmUgPyB7IGJ1aWxkVGltZVN0cnVjdHVyZTogc3ViZmxvd0RlZi5idWlsZFRpbWVTdHJ1Y3R1cmUgfSA6IHt9KSxcbiAgICAgIH0gYXMgYW55O1xuICAgIH1cblxuICAgIC8vIE1lcmdlIHN0YWdlTWFwIGVudHJpZXMgKHBhcmVudCBlbnRyaWVzIHByZXNlcnZlZClcbiAgICBpZiAoc3ViZmxvd0RlZi5zdGFnZU1hcCkge1xuICAgICAgZm9yIChjb25zdCBba2V5LCBmbl0gb2YgQXJyYXkuZnJvbShzdWJmbG93RGVmLnN0YWdlTWFwLmVudHJpZXMoKSkpIHtcbiAgICAgICAgaWYgKCF0aGlzLnN0YWdlTWFwLmhhcyhrZXkpKSB7XG4gICAgICAgICAgdGhpcy5zdGFnZU1hcC5zZXQoa2V5LCBmbiBhcyBTdGFnZUZ1bmN0aW9uPFRPdXQsIFRTY29wZT4pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gTWVyZ2UgbmVzdGVkIHN1YmZsb3dzXG4gICAgaWYgKHN1YmZsb3dEZWYuc3ViZmxvd3MpIHtcbiAgICAgIGZvciAoY29uc3QgW2tleSwgZGVmXSBvZiBPYmplY3QuZW50cmllcyhzdWJmbG93RGVmLnN1YmZsb3dzKSkge1xuICAgICAgICBpZiAoIXN1YmZsb3dzRGljdFtrZXldKSB7XG4gICAgICAgICAgc3ViZmxvd3NEaWN0W2tleV0gPSBkZWYgYXMgeyByb290OiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiB9O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG1vdW50Tm9kZUlkKSB7XG4gICAgICB0aGlzLnN0cnVjdHVyZU1hbmFnZXIudXBkYXRlRHluYW1pY1N1YmZsb3coXG4gICAgICAgIG1vdW50Tm9kZUlkLFxuICAgICAgICBzdWJmbG93SWQsXG4gICAgICAgIHN1YmZsb3dEZWYucm9vdD8uc3ViZmxvd05hbWUgfHwgc3ViZmxvd0RlZi5yb290Py5uYW1lLFxuICAgICAgICBzdWJmbG93RGVmLmJ1aWxkVGltZVN0cnVjdHVyZSxcbiAgICAgICk7XG4gICAgfVxuXG4gICAgLy8gTm90aWZ5IEZsb3dSZWNvcmRlcnMgb25seSBvbiBmaXJzdCByZWdpc3RyYXRpb24gKG1hdGNoZXMgZmlyc3Qtd3JpdGUtd2lucylcbiAgICBpZiAoaXNOZXdSZWdpc3RyYXRpb24pIHtcbiAgICAgIGNvbnN0IHN1YmZsb3dOYW1lID0gc3ViZmxvd0RlZi5yb290Py5zdWJmbG93TmFtZSB8fCBzdWJmbG93RGVmLnJvb3Q/Lm5hbWUgfHwgc3ViZmxvd0lkO1xuICAgICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3Iub25TdWJmbG93UmVnaXN0ZXJlZChcbiAgICAgICAgc3ViZmxvd0lkLFxuICAgICAgICBzdWJmbG93TmFtZSxcbiAgICAgICAgc3ViZmxvd0RlZi5yb290Py5kZXNjcmlwdGlvbixcbiAgICAgICAgc3ViZmxvd0RlZi5idWlsZFRpbWVTdHJ1Y3R1cmUsXG4gICAgICApO1xuICAgIH1cbiAgfVxufVxuIl19
1020
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRmxvd2NoYXJ0VHJhdmVyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9lbmdpbmUvdHJhdmVyc2FsL0Zsb3djaGFydFRyYXZlcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXNCRztBQUdILE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUMxRCxPQUFPLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUMxRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQUNuRSxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxxQ0FBcUMsQ0FBQztBQUMzRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDL0QsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQzNELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ2pGLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNqRSxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDekQsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLGdDQUFnQyxDQUFDO0FBRWpFLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxNQUFNLHdDQUF3QyxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHVDQUF1QyxDQUFDO0FBQzlFLE9BQU8sRUFBRSxpQ0FBaUMsRUFBRSxNQUFNLG1EQUFtRCxDQUFDO0FBRXRHLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBOEczRDs7OztHQUlHO0FBQ0gsTUFBTSxZQUFZLEdBQWtCLE1BQU0sQ0FBQyxr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LE1BQU0sV0FBVyxHQUFHLFVBQVUsQ0FBQyxJQUFJLEVBQUUsV0FBVyxJQUFJLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxJQUFJLFNBQVMsQ0FBQztZQUN2RixJQUFJLENBQUMsa0JBQWtCLENBQUMsbUJBQW1CLENBQ3pDLFNBQVMsRUFDVCxXQUFXLEVBQ1gsVUFBVSxDQUFDLElBQUksRUFBRSxXQUFXLEVBQzVCLFVBQVUsQ0FBQyxrQkFBa0IsQ0FDOUIsQ0FBQztRQUNKLENBQUM7SUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBGbG93Y2hhcnRUcmF2ZXJzZXIg4oCUIFByZS1vcmRlciBERlMgdHJhdmVyc2FsIG9mIFN0YWdlTm9kZSBncmFwaC5cbiAqXG4gKiBVbmlmaWVkIHRyYXZlcnNhbCBhbGdvcml0aG0gZm9yIGFsbCBub2RlIHNoYXBlcy4gYGV4ZWN1dGVOb2RlYCBpcyBhXG4gKiBUUkFNUE9MSU5FIGRyaXZlcjogaXQgcnVucyBgZXhlY3V0ZU5vZGVTdGVwYCAob25lIG5vZGUsIGFsbCA3IHBoYXNlcykgaW5cbiAqIGEgZmxhdCBsb29wLCBmb2xsb3dpbmcgdGFpbCBjb250aW51YXRpb25zIChsaW5lYXIgYG5leHRgLCBsb29wIGVkZ2VzLFxuICogZHluYW1pYyBuZXh0LCBmbGF0IGRlY2lkZXIgZGlzcGF0Y2gpIGl0ZXJhdGl2ZWx5IOKAlCBzbyBjaGFpbiBsZW5ndGggYW5kXG4gKiBsb29wIGl0ZXJhdGlvbnMgbmV2ZXIgZ3JvdyB0aGUgY2FsbCBzdGFjay4gT25seSB0cnVlIHRyZWUgbmVzdGluZyAoZm9ya1xuICogY2hpbGRyZW4sIHdpdGgtY29udGludWF0aW9uIGRlY2lkZXIvc2VsZWN0b3IgYnJhbmNoZXMsIHN1YmZsb3cgbW91bnRzKVxuICogcmVjdXJzZXMuXG4gKlxuICogRm9yIGVhY2ggbm9kZSwgZXhlY3V0ZU5vZGVTdGVwIGZvbGxvd3MgNyBwaGFzZXM6XG4gKiAgIDAuIENMQVNTSUZZICDigJQgc3ViZmxvdyBkZXRlY3Rpb24sIGVhcmx5IGRlbGVnYXRpb25cbiAqICAgMS4gVkFMSURBVEUgIOKAlCBub2RlIGludmFyaWFudHMsIHJvbGUgbWFya2Vyc1xuICogICAyLiBFWEVDVVRFICAg4oCUIHJ1biBzdGFnZSBmbiwgY29tbWl0LCBicmVhayBjaGVja1xuICogICAzLiBEWU5BTUlDICAg4oCUIFN0YWdlTm9kZSByZXR1cm4gZGV0ZWN0aW9uLCBzdWJmbG93IGF1dG8tcmVnaXN0cmF0aW9uLCBzdHJ1Y3R1cmUgdXBkYXRlc1xuICogICA0LiBDSElMRFJFTiAg4oCUIGZvcmsvc2VsZWN0b3IvZGVjaWRlciBkaXNwYXRjaFxuICogICA1LiBDT05USU5VRSAg4oCUIGR5bmFtaWMgbmV4dCAvIGxpbmVhciBuZXh0IHJlc29sdXRpb25cbiAqICAgNi4gTEVBRiAgICAgIOKAlCBubyBjb250aW51YXRpb24sIHJldHVybiBvdXRwdXRcbiAqXG4gKiBCcmVhayBzZW1hbnRpY3M6IElmIGEgc3RhZ2UgY2FsbHMgYnJlYWtGbigpLCBjb21taXQgYW5kIFNUT1AuXG4gKiBQYXRjaCBtb2RlbDogU3RhZ2Ugd3JpdGVzIGludG8gbG9jYWwgcGF0Y2g7IGNvbW1pdFBhdGNoKCkgYWZ0ZXIgcmV0dXJuIG9yIHRocm93LlxuICovXG5cbmltcG9ydCB0eXBlIHsgU3RhZ2VDb250ZXh0IH0gZnJvbSAnLi4vLi4vbWVtb3J5L1N0YWdlQ29udGV4dC5qcyc7XG5pbXBvcnQgeyBpc1BhdXNlU2lnbmFsIH0gZnJvbSAnLi4vLi4vcGF1c2UvdHlwZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBTY29wZVByb3RlY3Rpb25Nb2RlIH0gZnJvbSAnLi4vLi4vc2NvcGUvcHJvdGVjdGlvbi90eXBlcy5qcyc7XG5pbXBvcnQgeyBleHRyYWN0RXJyb3JJbmZvIH0gZnJvbSAnLi4vZXJyb3JzL2Vycm9ySW5mby5qcyc7XG5pbXBvcnQgeyBpc1N0YWdlTm9kZVJldHVybiB9IGZyb20gJy4uL2dyYXBoL1N0YWdlTm9kZS5qcyc7XG5pbXBvcnQgeyBDaGlsZHJlbkV4ZWN1dG9yIH0gZnJvbSAnLi4vaGFuZGxlcnMvQ2hpbGRyZW5FeGVjdXRvci5qcyc7XG5pbXBvcnQgeyBDb250aW51YXRpb25SZXNvbHZlciB9IGZyb20gJy4uL2hhbmRsZXJzL0NvbnRpbnVhdGlvblJlc29sdmVyLmpzJztcbmltcG9ydCB7IERlY2lkZXJIYW5kbGVyIH0gZnJvbSAnLi4vaGFuZGxlcnMvRGVjaWRlckhhbmRsZXIuanMnO1xuaW1wb3J0IHsgTm9kZVJlc29sdmVyIH0gZnJvbSAnLi4vaGFuZGxlcnMvTm9kZVJlc29sdmVyLmpzJztcbmltcG9ydCB7IFJ1bnRpbWVTdHJ1Y3R1cmVNYW5hZ2VyIH0gZnJvbSAnLi4vaGFuZGxlcnMvUnVudGltZVN0cnVjdHVyZU1hbmFnZXIuanMnO1xuaW1wb3J0IHsgU2VsZWN0b3JIYW5kbGVyIH0gZnJvbSAnLi4vaGFuZGxlcnMvU2VsZWN0b3JIYW5kbGVyLmpzJztcbmltcG9ydCB7IFN0YWdlUnVubmVyIH0gZnJvbSAnLi4vaGFuZGxlcnMvU3RhZ2VSdW5uZXIuanMnO1xuaW1wb3J0IHsgU3ViZmxvd0V4ZWN1dG9yIH0gZnJvbSAnLi4vaGFuZGxlcnMvU3ViZmxvd0V4ZWN1dG9yLmpzJztcbmltcG9ydCB0eXBlIHsgQnJlYWtGbGFnIH0gZnJvbSAnLi4vaGFuZGxlcnMvdHlwZXMuanMnO1xuaW1wb3J0IHsgRmxvd1JlY29yZGVyRGlzcGF0Y2hlciB9IGZyb20gJy4uL25hcnJhdGl2ZS9GbG93UmVjb3JkZXJEaXNwYXRjaGVyLmpzJztcbmltcG9ydCB7IE5hcnJhdGl2ZUZsb3dSZWNvcmRlciB9IGZyb20gJy4uL25hcnJhdGl2ZS9OYXJyYXRpdmVGbG93UmVjb3JkZXIuanMnO1xuaW1wb3J0IHsgTnVsbENvbnRyb2xGbG93TmFycmF0aXZlR2VuZXJhdG9yIH0gZnJvbSAnLi4vbmFycmF0aXZlL051bGxDb250cm9sRmxvd05hcnJhdGl2ZUdlbmVyYXRvci5qcyc7XG5pbXBvcnQgdHlwZSB7IEZsb3dSZWNvcmRlciwgSUNvbnRyb2xGbG93TmFycmF0aXZlLCBUcmF2ZXJzYWxDb250ZXh0IH0gZnJvbSAnLi4vbmFycmF0aXZlL3R5cGVzLmpzJztcbmltcG9ydCB7IGJ1aWxkUnVudGltZVN0YWdlSWQgfSBmcm9tICcuLi9ydW50aW1lU3RhZ2VJZC5qcyc7XG5pbXBvcnQgdHlwZSB7XG4gIEhhbmRsZXJEZXBzLFxuICBJRXhlY3V0aW9uUnVudGltZSxcbiAgSUxvZ2dlcixcbiAgTm9kZVJlc3VsdFR5cGUsXG4gIFNjb3BlRmFjdG9yeSxcbiAgU2VsZWN0b3IsXG4gIFNlcmlhbGl6ZWRQaXBlbGluZVN0cnVjdHVyZSxcbiAgU3RhZ2VGdW5jdGlvbixcbiAgU3RhZ2VOb2RlLFxuICBTdHJlYW1IYW5kbGVycyxcbiAgU3ViZmxvd01vdW50T3B0aW9ucyxcbiAgU3ViZmxvd1Jlc3VsdCxcbiAgU3ViZmxvd1RyYXZlcnNlckZhY3RvcnksXG4gIFRyYXZlcnNhbFJlc3VsdCxcbn0gZnJvbSAnLi4vdHlwZXMuanMnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFRyYXZlcnNlck9wdGlvbnM8VE91dCA9IGFueSwgVFNjb3BlID0gYW55PiB7XG4gIHJvb3Q6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+O1xuICBzdGFnZU1hcDogTWFwPHN0cmluZywgU3RhZ2VGdW5jdGlvbjxUT3V0LCBUU2NvcGU+PjtcbiAgc2NvcGVGYWN0b3J5OiBTY29wZUZhY3Rvcnk8VFNjb3BlPjtcbiAgZXhlY3V0aW9uUnVudGltZTogSUV4ZWN1dGlvblJ1bnRpbWU7XG4gIHJlYWRPbmx5Q29udGV4dD86IHVua25vd247XG4gIC8qKiBFeGVjdXRpb24gZW52aXJvbm1lbnQg4oCUIHByb3BhZ2F0ZXMgdG8gc3ViZmxvd3MgYXV0b21hdGljYWxseS4gKi9cbiAgZXhlY3V0aW9uRW52PzogaW1wb3J0KCcuLi8uLi9lbmdpbmUvdHlwZXMnKS5FeGVjdXRpb25FbnY7XG4gIHRocm90dGxpbmdFcnJvckNoZWNrZXI/OiAoZXJyb3I6IHVua25vd24pID0+IGJvb2xlYW47XG4gIHN0cmVhbUhhbmRsZXJzPzogU3RyZWFtSGFuZGxlcnM7XG4gIHNjb3BlUHJvdGVjdGlvbk1vZGU/OiBTY29wZVByb3RlY3Rpb25Nb2RlO1xuICBzdWJmbG93cz86IFJlY29yZDxzdHJpbmcsIHsgcm9vdDogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4gfT47XG4gIG5hcnJhdGl2ZUVuYWJsZWQ/OiBib29sZWFuO1xuICBidWlsZFRpbWVTdHJ1Y3R1cmU/OiBTZXJpYWxpemVkUGlwZWxpbmVTdHJ1Y3R1cmU7XG4gIGxvZ2dlcjogSUxvZ2dlcjtcbiAgc2lnbmFsPzogQWJvcnRTaWduYWw7XG4gIC8qKiBQcmUtY29uZmlndXJlZCBGbG93UmVjb3JkZXJzIHRvIGF0dGFjaCB3aGVuIG5hcnJhdGl2ZSBpcyBlbmFibGVkLiAqL1xuICBmbG93UmVjb3JkZXJzPzogRmxvd1JlY29yZGVyW107XG4gIC8qKlxuICAgKiBQcmUtY29uZmlndXJlZCBuYXJyYXRpdmUgZ2VuZXJhdG9yLiBJZiBwcm92aWRlZCwgdGFrZXMgcHJlY2VkZW5jZSBvdmVyXG4gICAqIGZsb3dSZWNvcmRlcnMgYW5kIG5hcnJhdGl2ZUVuYWJsZWQuIFVzZWQgYnkgdGhlIHN1YmZsb3cgdHJhdmVyc2VyIGZhY3RvcnlcbiAgICogdG8gc2hhcmUgdGhlIHBhcmVudCdzIG5hcnJhdGl2ZSBnZW5lcmF0b3Igd2l0aCBzdWJmbG93IHRyYXZlcnNlcnMuXG4gICAqL1xuICBuYXJyYXRpdmVHZW5lcmF0b3I/OiBJQ29udHJvbEZsb3dOYXJyYXRpdmU7XG4gIC8qKlxuICAgKiBNYXhpbXVtIG5lc3RlZCBleGVjdXRlTm9kZSBkZXB0aCAodHJlZSBuZXN0aW5nIOKAlCBicmFuY2gvZm9yayBkaXNwYXRjaCBhbmRcbiAgICogZHluYW1pYyByZWN1cnNpb24sIE5PVCBsaW5lYXIgY2hhaW5zIG9yIGxvb3AgaXRlcmF0aW9ucywgd2hpY2ggcnVuIGZsYXQpLlxuICAgKiBEZWZhdWx0cyB0byBGbG93Y2hhcnRUcmF2ZXJzZXIuTUFYX0VYRUNVVEVfREVQVEggKDUwMCkuXG4gICAqL1xuICBtYXhEZXB0aD86IG51bWJlcjtcbiAgLyoqXG4gICAqIE1heGltdW0gbG9vcCBpdGVyYXRpb25zIHBlciBub2RlICh0aGUgQ29udGludWF0aW9uUmVzb2x2ZXIgZ3VhcmQpLlxuICAgKiBEZWZhdWx0cyB0byBERUZBVUxUX01BWF9JVEVSQVRJT05TICgxMDAwKS4gUHJvcGFnYXRlZCB0byBzdWJmbG93XG4gICAqIHRyYXZlcnNlcnMuIE11c3QgYmUgPj0gMS5cbiAgICovXG4gIG1heEl0ZXJhdGlvbnM/OiBudW1iZXI7XG4gIC8qKlxuICAgKiBXaGVuIHRoaXMgdHJhdmVyc2VyIHJ1bnMgaW5zaWRlIGEgc3ViZmxvdywgc2V0IHRoaXMgdG8gdGhlIHN1YmZsb3cncyBJRC5cbiAgICogUHJvcGFnYXRlZCB0byBUcmF2ZXJzYWxDb250ZXh0IHNvIG5hcnJhdGl2ZSBlbnRyaWVzIGNhcnJ5IHRoZSBjb3JyZWN0IHN1YmZsb3dJZC5cbiAgICovXG4gIHBhcmVudFN1YmZsb3dJZD86IHN0cmluZztcbiAgLyoqIFNoYXJlZCBleGVjdXRpb24gY291bnRlciBmcm9tIHBhcmVudCB0cmF2ZXJzZXIuIFN1YmZsb3dzIGNvbnRpbnVlIHRoZSBwYXJlbnQncyBudW1iZXJpbmcuICovXG4gIGV4ZWN1dGlvbkNvdW50ZXI/OiB7IHZhbHVlOiBudW1iZXIgfTtcbiAgLyoqXG4gICAqIFBlci1zdWJmbG93IHNjb3BlIGNhcHR1cmVzIGZyb20gYSBjaGVja3BvaW50LCBvbiB0aGUgcmVzdW1lIHBhdGguXG4gICAqIEZvcndhcmRlZCB0byBgSGFuZGxlckRlcHMuc3ViZmxvd1N0YXRlc0ZvclJlc3VtZWAgc28gU3ViZmxvd0V4ZWN1dG9yXG4gICAqIGNhbiByZS1zZWVkIG5lc3RlZCBydW50aW1lcyBmcm9tIHByZS1wYXVzZSBzdGF0ZSBpbnN0ZWFkIG9mIHJ1bm5pbmdcbiAgICogdGhlIGlucHV0TWFwcGVyLiBVbmRlZmluZWQgb24gbm9ybWFsIGBydW4oKWAgcGF0aHMuXG4gICAqL1xuICBzdWJmbG93U3RhdGVzRm9yUmVzdW1lPzogUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgdW5rbm93bj4+O1xuICAvKipcbiAgICogUGVyLWBleGVjdXRvci5ydW4oKWAgaWRlbnRpZmllci4gVGhyZWFkZWQgaW50byBldmVyeSBUcmF2ZXJzYWxDb250ZXh0XG4gICAqIHRoaXMgdHJhdmVyc2VyIHByb2R1Y2VzIHNvIHJlY29yZGVycyBjYW4gc2NvcGUgc3RhdGUgdG8gYSBzaW5nbGUgcnVuLlxuICAgKiBTdWJmbG93IHRyYXZlcnNlcnMgaW5oZXJpdCB0aGUgcGFyZW50J3MgcnVuSWQgKHRoZSBzdWJmbG93IGlzIHBhcnQgb2ZcbiAgICogdGhlIHNhbWUgcnVuIGZyb20gdGhlIGNvbnN1bWVyJ3MgUE9WKS4gUmVxdWlyZWQgZmllbGQg4oCUIGV2ZXJ5IGV2ZW50XG4gICAqIG5lZWRzIGl0LiBTZWUgYHJ1bm5lci9ydW5JZC50c2AuXG4gICAqL1xuICBydW5JZDogc3RyaW5nO1xufVxuXG4vKipcbiAqIFRyYXZlcnNlci1sb2NhbCBvdmVybGF5IGVudHJ5IGZvciBhIG5vZGUgd2hvc2Ugc3RhZ2UgZnVuY3Rpb24gcmV0dXJuZWQgYVxuICogU3RhZ2VOb2RlIChkeW5hbWljIGNvbnRpbnVhdGlvbikuIEhvbGRzIHRoZSBkeW5hbWljIHZhbHVlcyB0aGF0IGVhcmxpZXJcbiAqIHZlcnNpb25zIHdyb3RlIERJUkVDVExZIG9udG8gdGhlIHNoYXJlZCBidWlsdC1jaGFydCBub2RlIOKAlCB3aGljaCBsZWFrZWQgdGhlXG4gKiBkeW5hbWljIHNoYXBlIGludG8gZXZlcnkgbGF0ZXIgcnVuIG9mIHRoZSBzYW1lIGJ1aWx0IGNoYXJ0IGFuZCByYWNlZFxuICogY29uY3VycmVudCBleGVjdXRvcnMuIFRoZSBvdmVybGF5IGtlZXBzIHRoZSBidWlsdCBncmFwaCBpbW11dGFibGU6IHBhdGNoZXNcbiAqIGxpdmUgaW4gYSBwZXItdHJhdmVyc2VyIE1hcCBrZXllZCBieSBgbm9kZS5pZGAgYW5kIGRpZSB3aXRoIHRoZSBydW4uXG4gKlxuICogYG5leHRgIGlzIGludGVudGlvbmFsbHkgQUJTRU5UOiBhIGR5bmFtaWMgYG5leHRgIG9ubHkgZXZlciBhcHBsaWVzIHRvIHRoZVxuICogdmlzaXQgdGhhdCBwcm9kdWNlZCBpdCAodGhlIG9sZCBjb2RlIHdyb3RlIGBub2RlLm5leHRgIGFuZCByZXN0b3JlZCBpdFxuICogYmVmb3JlIGFueXRoaW5nIGNvdWxkIG9ic2VydmUgdGhlIHdyaXRlKSwgc28gaXQgc3RheXMgYSBsb2NhbCB2YXJpYWJsZSBpblxuICogYGV4ZWN1dGVOb2RlYCBhbmQgaXMgcm91dGVkIHRocm91Z2ggYENvbnRpbnVhdGlvblJlc29sdmVyYCBkaXJlY3RseS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEeW5hbWljTm9kZVBhdGNoPFRPdXQgPSBhbnksIFRTY29wZSA9IGFueT4ge1xuICAvKipcbiAgICogU3ViZmxvdyBtb3VudCBtZXRhZGF0YSBmcm9tIGEgZHluYW1pYy1zdWJmbG93IHJldHVybi4gR3JvdXBlZCBzbyB0aGVcbiAgICogbWVyZ2VkIHZpZXcgcmVwcm9kdWNlcyB0aGUgb2xkIGZpZWxkLXdpc2Ugb3ZlcndyaXRlIGV4YWN0bHkg4oCUIGluY2x1ZGluZ1xuICAgKiBgc3ViZmxvd05hbWVgL2BzdWJmbG93TW91bnRPcHRpb25zYCBiZWNvbWluZyB1bmRlZmluZWQgd2hlbiB0aGUgZHluYW1pY1xuICAgKiByZXR1cm4gb21pdHRlZCB0aGVtLlxuICAgKi9cbiAgc3ViZmxvd01ldGE/OiB7XG4gICAgaXNTdWJmbG93Um9vdDogdHJ1ZTtcbiAgICBzdWJmbG93SWQ6IHN0cmluZztcbiAgICBzdWJmbG93TmFtZTogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIHN1YmZsb3dNb3VudE9wdGlvbnM6IFN1YmZsb3dNb3VudE9wdGlvbnMgfCB1bmRlZmluZWQ7XG4gIH07XG4gIC8qKiBEeW5hbWljIGZvcmsgY2hpbGRyZW4gKHJlcGxhY2VzIHRoZSBidWlsdCBub2RlJ3MgY2hpbGRyZW4gZm9yIHRoaXMgcnVuKS4gKi9cbiAgY2hpbGRyZW4/OiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPltdO1xuICAvKiogRHluYW1pYyBvdXRwdXQtYmFzZWQgc2VsZWN0b3IgYWNjb21wYW55aW5nIGR5bmFtaWMgY2hpbGRyZW4uICovXG4gIG5leHROb2RlU2VsZWN0b3I/OiBTZWxlY3Rvcjtcbn1cblxuLyoqXG4gKiBUcmFtcG9saW5lIGJyYW5kIOKAlCBtYXJrcyBhIGNvbnRpbnVhdGlvbiBob3AgcmV0dXJuZWQgYnkgYGV4ZWN1dGVOb2RlU3RlcGBcbiAqIHRvIHRoZSBkcml2ZXIgbG9vcCBpbiBgZXhlY3V0ZU5vZGVgLiBNb2R1bGUtcHJpdmF0ZSBzeW1ib2wgc28gYSBzdGFnZSdzIG93blxuICogcmV0dXJuIHZhbHVlICh3aGljaCBjYW4gYmUgYW55IG9iamVjdCkgY2FuIG5ldmVyIGJlIG1pc3Rha2VuIGZvciBhIGhvcC5cbiAqL1xuY29uc3QgQ09OVElOVUVfSE9QOiB1bmlxdWUgc3ltYm9sID0gU3ltYm9sKCdmb290cHJpbnRqcy5leGVjdXRlTm9kZS5jb250aW51ZScpO1xuXG4vKipcbiAqIEEgZmxhdCBjb250aW51YXRpb24g4oCUIFwiZXhlY3V0ZSB0aGlzIG5vZGUgbmV4dCwgaW4gdGhpcyBjb250ZXh0XCIg4oCUIHJldHVybmVkXG4gKiBieSBgZXhlY3V0ZU5vZGVTdGVwYCBmb3IgZXZlcnkgVEFJTCBjb250aW51YXRpb24gKGxpbmVhciBgbmV4dGAsIGxvb3BcbiAqIGVkZ2VzLCBkeW5hbWljIG5leHQsIGR5bmFtaWMtc3ViZmxvdyByZS1lbnRyeSwgbm8tY29udGludWF0aW9uIGRlY2lkZXJcbiAqIGRpc3BhdGNoKS4gVGhlIGRyaXZlciBsb29wIGluIGBleGVjdXRlTm9kZWAgY29uc3VtZXMgaG9wcyBpdGVyYXRpdmVseTpcbiAqIGBjdXJyZW50ID0gaG9wOyBjb250aW51ZTtgIOKAlCBzbyBuZWl0aGVyIHRoZSBjYWxsIHN0YWNrIG5vciB0aGUgcmV0YWluZWRcbiAqIHByb21pc2UgY2hhaW4gZ3Jvd3Mgd2l0aCBjaGFpbiBsZW5ndGggb3IgbG9vcCBpdGVyYXRpb25zLlxuICovXG5pbnRlcmZhY2UgQ29udGludWF0aW9uSG9wPFRPdXQgPSBhbnksIFRTY29wZSA9IGFueT4ge1xuICByZWFkb25seSBbQ09OVElOVUVfSE9QXTogdHJ1ZTtcbiAgcmVhZG9ubHkgbm9kZTogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT47XG4gIHJlYWRvbmx5IGNvbnRleHQ6IFN0YWdlQ29udGV4dDtcbiAgcmVhZG9ubHkgYnJhbmNoUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogUHJlc2VudCB3aGVuIHRoZSBob3AgaXMgYSBkZWNpZGVyJ3MgYnJhbmNoIGRpc3BhdGNoIChkZWNpZGVyIHdpdGhvdXQgaXRzXG4gICAqIG93biBgbmV4dGApLiBUaGUgZHJpdmVyIHJlY29yZHMgaXQgc28gYSBQYXVzZVNpZ25hbCB0aHJvd24gYW55d2hlcmUgaW5cbiAgICogdGhlIGNvbnRpbnVlZCBjaGFpbiBzdGlsbCBnZXRzIHRoZSBkZWNpZGVyIHN0YW1wZWQgYXMgaXRzIGludm9rZXIg4oCUXG4gICAqIGV4YWN0bHkgd2hhdCB0aGUgcmVjdXJzaXZlIGRpc3BhdGNoJ3MgY2F0Y2ggdXNlZCB0byBkby5cbiAgICovXG4gIHJlYWRvbmx5IGludm9rZXJTdGFtcD86IEludm9rZXJTdGFtcDtcbn1cblxuLyoqIFBhdXNlLWludm9rZXIgY29udGV4dCByZWNvcmRlZCBieSB0aGUgZHJpdmVyIGZvciBmbGF0IGRlY2lkZXIgZGlzcGF0Y2hlcy4gKi9cbmludGVyZmFjZSBJbnZva2VyU3RhbXAge1xuICByZWFkb25seSBpbnZva2VyU3RhZ2VJZDogc3RyaW5nO1xuICByZWFkb25seSBjb250aW51YXRpb25TdGFnZUlkPzogc3RyaW5nO1xufVxuXG5mdW5jdGlvbiBpc0NvbnRpbnVhdGlvbkhvcDxUT3V0LCBUU2NvcGU+KHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgQ29udGludWF0aW9uSG9wPFRPdXQsIFRTY29wZT4ge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0JyAmJiB2YWx1ZSAhPT0gbnVsbCAmJiAodmFsdWUgYXMgUmVjb3JkPHN5bWJvbCwgdW5rbm93bj4pW0NPTlRJTlVFX0hPUF0gPT09IHRydWU7XG59XG5cbmV4cG9ydCBjbGFzcyBGbG93Y2hhcnRUcmF2ZXJzZXI8VE91dCA9IGFueSwgVFNjb3BlID0gYW55PiB7XG4gIHByaXZhdGUgcmVhZG9ubHkgcm9vdDogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT47XG4gIHByaXZhdGUgc3RhZ2VNYXA6IE1hcDxzdHJpbmcsIFN0YWdlRnVuY3Rpb248VE91dCwgVFNjb3BlPj47XG4gIHByaXZhdGUgcmVhZG9ubHkgZXhlY3V0aW9uUnVudGltZTogSUV4ZWN1dGlvblJ1bnRpbWU7XG4gIHByaXZhdGUgc3ViZmxvd3M6IFJlY29yZDxzdHJpbmcsIHsgcm9vdDogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4gfT47XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nZ2VyOiBJTG9nZ2VyO1xuICBwcml2YXRlIHJlYWRvbmx5IHNpZ25hbD86IEFib3J0U2lnbmFsO1xuICBwcml2YXRlIHJlYWRvbmx5IHBhcmVudFN1YmZsb3dJZD86IHN0cmluZztcbiAgLyoqIEZyb3plbiB2YWx1ZSBwYXNzZWQgdmlhIGBydW4oe2lucHV0fSlgLiBTdXJmYWNlZCBvbiBgb25SdW5TdGFydGAgYXQgdGhlXG4gICAqICB0b3AtbGV2ZWwgdHJhdmVyc2FsIHNvIGNvbnN1bWVycyAoZS5nLiBgSW5PdXRSZWNvcmRlcmApIGNhbiBicmFja2V0XG4gICAqICB0aGUgcnVuIHdpdGggdGhlIHNhbWUgcGF5bG9hZCBzaGFwZSB0aGF0IHN1YmZsb3dzIGFscmVhZHkgaGF2ZS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZWFkT25seUNvbnRleHQ/OiB1bmtub3duO1xuICAvKiogUGVyLWBleGVjdXRvci5ydW4oKWAgaWRlbnRpZmllci4gU3RhbXBlZCBvbnRvIGV2ZXJ5IFRyYXZlcnNhbENvbnRleHQuXG4gICAqICBJbmhlcml0ZWQgYnkgc3ViZmxvdyB0cmF2ZXJzZXJzIHNvIGFsbCBldmVudHMgb2Ygb25lIHJ1biBzaGFyZSBvbmUgcnVuSWQuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcnVuSWQ6IHN0cmluZztcblxuICAvLyBIYW5kbGVyIG1vZHVsZXNcbiAgcHJpdmF0ZSByZWFkb25seSBub2RlUmVzb2x2ZXI6IE5vZGVSZXNvbHZlcjxUT3V0LCBUU2NvcGU+O1xuICBwcml2YXRlIHJlYWRvbmx5IGNoaWxkcmVuRXhlY3V0b3I6IENoaWxkcmVuRXhlY3V0b3I8VE91dCwgVFNjb3BlPjtcbiAgcHJpdmF0ZSByZWFkb25seSBzdWJmbG93RXhlY3V0b3I6IFN1YmZsb3dFeGVjdXRvcjxUT3V0LCBUU2NvcGU+O1xuICBwcml2YXRlIHJlYWRvbmx5IHN0YWdlUnVubmVyOiBTdGFnZVJ1bm5lcjxUT3V0LCBUU2NvcGU+O1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbnRpbnVhdGlvblJlc29sdmVyOiBDb250aW51YXRpb25SZXNvbHZlcjxUT3V0LCBUU2NvcGU+O1xuICBwcml2YXRlIHJlYWRvbmx5IGRlY2lkZXJIYW5kbGVyOiBEZWNpZGVySGFuZGxlcjxUT3V0LCBUU2NvcGU+O1xuICBwcml2YXRlIHJlYWRvbmx5IHNlbGVjdG9ySGFuZGxlcjogU2VsZWN0b3JIYW5kbGVyPFRPdXQsIFRTY29wZT47XG4gIHByaXZhdGUgcmVhZG9ubHkgc3RydWN0dXJlTWFuYWdlcjogUnVudGltZVN0cnVjdHVyZU1hbmFnZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbmFycmF0aXZlR2VuZXJhdG9yOiBJQ29udHJvbEZsb3dOYXJyYXRpdmU7XG4gIHByaXZhdGUgcmVhZG9ubHkgZmxvd1JlY29yZGVyRGlzcGF0Y2hlcjogRmxvd1JlY29yZGVyRGlzcGF0Y2hlciB8IHVuZGVmaW5lZDtcblxuICAvLyBFeGVjdXRpb24gc3RhdGVcbiAgcHJpdmF0ZSBzdWJmbG93UmVzdWx0czogTWFwPHN0cmluZywgU3ViZmxvd1Jlc3VsdD4gPSBuZXcgTWFwKCk7XG5cbiAgLyoqXG4gICAqIFBlci10cmF2ZXJzZXIgc2V0IG9mIGxhenkgc3ViZmxvdyBJRHMgdGhhdCBoYXZlIGJlZW4gcmVzb2x2ZWQgYnkgVEhJUyBydW4uXG4gICAqIFVzZWQgaW5zdGVhZCBvZiB3cml0aW5nIGBub2RlLnN1YmZsb3dSZXNvbHZlciA9IHVuZGVmaW5lZGAgYmFjayB0byB0aGUgc2hhcmVkXG4gICAqIFN0YWdlTm9kZSBncmFwaCDigJQgYXZvaWRzIGEgcmFjZSB3aGVyZSBhIGNvbmN1cnJlbnQgdHJhdmVyc2VyIGNsZWFycyB0aGUgc2hhcmVkXG4gICAqIHJlc29sdmVyIGJlZm9yZSBhbm90aGVyIHRyYXZlcnNlciBoYXMgZmluaXNoZWQgdXNpbmcgaXQuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHJlc29sdmVkTGF6eVN1YmZsb3dzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgLyoqXG4gICAqIFBlci10cmF2ZXJzZXIgb3ZlcmxheSBvZiBkeW5hbWljIFN0YWdlTm9kZSByZXR1cm5zLCBrZXllZCBieSBgbm9kZS5pZGAuXG4gICAqIFBoYXNlIDQgd3JpdGVzIHBhdGNoZXMgSEVSRSBpbnN0ZWFkIG9mIG11dGF0aW5nIHRoZSBzaGFyZWQgYnVpbHQtY2hhcnRcbiAgICogbm9kZSBvYmplY3RzIChzYW1lIGlzb2xhdGlvbiBjb252ZW50aW9uIGFzIGByZXNvbHZlZExhenlTdWJmbG93c2ApLlxuICAgKiBBbGwgZW5naW5lIHJlYWRzIG9mIHRoZSBwYXRjaGVkIGZpZWxkcyBnbyB0aHJvdWdoIHRoZSBgZWZmKmAgYWNjZXNzb3JzXG4gICAqIGJlbG93LiBUaGUgbWFwIGRpZXMgd2l0aCB0aGUgdHJhdmVyc2VyIOKAlCBvbmUgcnVuLCBvbmUgb3ZlcmxheSDigJQgc28gYVxuICAgKiBmcmVzaCBleGVjdXRvciBvdmVyIHRoZSBzYW1lIGJ1aWx0IGNoYXJ0IGFsd2F5cyBzZWVzIHRoZSBvcmlnaW5hbCBncmFwaC5cbiAgICpcbiAgICogS2V5ZWQgYnkgdGhlIG5vZGUgT0JKRUNUIChXZWFrTWFwKSwgbm90IGBub2RlLmlkYDogYSBkeW5hbWljIGNoaWxkIHRoYXRcbiAgICogcmV1c2VzIGEgYnVpbHQgbm9kZSdzIGlkIG11c3QgTk9UIG1ha2UgdGhlIGJ1aWx0IG5vZGUgaW5oZXJpdCB0aGUgcGF0Y2hcbiAgICogKGlkLWtleWVkIGxvb2t1cCBjYXVzZWQgcGhhbnRvbSBkb3VibGUtZXhlY3V0aW9uKS4gYHBhdGNoQ291bnRgIGlzIHRoZVxuICAgKiBmYXN0LXBhdGggY2hlY2sg4oCUIFdlYWtNYXAgaGFzIG5vIGBzaXplYC5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZHluYW1pY1BhdGNoZXMgPSBuZXcgV2Vha01hcDxTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiwgRHluYW1pY05vZGVQYXRjaDxUT3V0LCBUU2NvcGU+PigpO1xuICBwcml2YXRlIHBhdGNoQ291bnQgPSAwO1xuXG4gIC8qKlxuICAgKiBUUkVFLW5lc3RpbmcgZGVwdGggY291bnRlciBmb3IgZXhlY3V0ZU5vZGUgKHRoZSB0cmFtcG9saW5lIGRyaXZlcikuXG4gICAqIEVhY2ggZHJpdmVyIGludm9jYXRpb24gaW5jcmVtZW50cyB0aGlzOyBkZWNyZW1lbnRzIG9uIGV4aXQgKHRyeS9maW5hbGx5KS5cbiAgICpcbiAgICogTGluZWFyIGBuZXh0YCBjaGFpbnMsIGxvb3AgZWRnZXMsIGFuZCBkeW5hbWljIGNvbnRpbnVhdGlvbnMgYXJlIGZvbGxvd2VkXG4gICAqIElURVJBVElWRUxZIGluc2lkZSBvbmUgZHJpdmVyIGludm9jYXRpb24sIHNvIHRoZXkgbmV2ZXIgZ3JvdyB0aGlzXG4gICAqIGNvdW50ZXIuIE9ubHkgdHJ1ZSB0cmVlIHJlY3Vyc2lvbiBkb2VzOiBmb3JrIGNoaWxkcmVuLCBkZWNpZGVyL3NlbGVjdG9yXG4gICAqIGJyYW5jaCBkaXNwYXRjaCAod2hlbiB0aGUgZGVjaWRlciBoYXMgaXRzIG93biBjb250aW51YXRpb24pLCBhbmRcbiAgICogdW5ib3VuZGVkIGR5bmFtaWMgcmVjdXJzaW9uLiBQcmV2ZW50cyBjYWxsLXN0YWNrIG92ZXJmbG93IG9uIHJ1bmF3YXlcbiAgICogcmVjdXJzaXZlIGNvbXBvc2l0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBfZXhlY3V0ZURlcHRoID0gMDtcblxuICAvKipcbiAgICogTWVtb2l6ZWQgcGFyZW50LWNoYWluIGRlcHRoIHBlciBTdGFnZUNvbnRleHQuIFRoZSBjb250ZXh0IHRyZWUgZGVlcGVuc1xuICAgKiBieSBvbmUgcGVyIGV4ZWN1dGVkIHN0YWdlIGFsb25nIGEgY2hhaW4sIHNvIHRoZSBuYWl2ZSBwYXJlbnQtd2FsayBpblxuICAgKiBgY29tcHV0ZUNvbnRleHREZXB0aGAgaXMgTyhjaGFpbiBsZW5ndGgpIHBlciBzdGFnZSDigJQgTyhuwrIpIHBlciBydW4gb25jZVxuICAgKiB0aGUgdHJhbXBvbGluZSBhbGxvd3MgY2hhaW5zIG9mIHRlbnMgb2YgdGhvdXNhbmRzIG9mIHN0YWdlcy4gQ29udGV4dHNcbiAgICogYXJlIHZpc2l0ZWQgcGFyZW50LWJlZm9yZS1jaGlsZCwgc28gdGhlIG1lbW8gbWFrZXMgZWFjaCBsb29rdXAgTygxKVxuICAgKiBhbW9ydGl6ZWQuIFdlYWtNYXAg4oCUIGRpZXMgd2l0aCB0aGUgdHJhdmVyc2VyLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb250ZXh0RGVwdGhDYWNoZSA9IG5ldyBXZWFrTWFwPFN0YWdlQ29udGV4dCwgbnVtYmVyPigpO1xuXG4gIC8qKlxuICAgKiBTaGFyZWQgbXV0YWJsZSBleGVjdXRpb24gY291bnRlciDigJQgbW9ub3RvbmljLCBpbmNyZW1lbnRlZCBwZXIgc3RhZ2UgZXhlY3V0aW9uLlxuICAgKiBTaGFyZWQgd2l0aCBjaGlsZCB0cmF2ZXJzZXJzIChzdWJmbG93cykgc28gaW5kaWNlcyBhcmUgZ2xvYmFsbHkgdW5pcXVlIHdpdGhpbiBhIHJ1bi5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgX2V4ZWN1dGlvbkNvdW50ZXI6IHsgdmFsdWU6IG51bWJlciB9O1xuXG4gIC8qKlxuICAgKiBQZXItaW5zdGFuY2UgbWF4aW11bSBkZXB0aCAoc2V0IGZyb20gVHJhdmVyc2VyT3B0aW9ucy5tYXhEZXB0aCBvciB0aGUgY2xhc3MgZGVmYXVsdCkuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9tYXhEZXB0aDogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBQZXItaW5zdGFuY2UgbG9vcC1pdGVyYXRpb24gbGltaXQgZm9yd2FyZGVkIHRvIHRoZSBDb250aW51YXRpb25SZXNvbHZlclxuICAgKiBhbmQgcHJvcGFnYXRlZCB0byBzdWJmbG93IHRyYXZlcnNlcnMuIFVuZGVmaW5lZCDihpIgcmVzb2x2ZXIgZGVmYXVsdCAoMTAwMCkuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IF9tYXhJdGVyYXRpb25zPzogbnVtYmVyO1xuXG4gIC8qKlxuICAgKiBEZWZhdWx0IG1heGltdW0gbmVzdGVkIGV4ZWN1dGVOb2RlIGRlcHRoIGJlZm9yZSBhbiBlcnJvciBpcyB0aHJvd24uXG4gICAqXG4gICAqICoqV2hhdCBjb3VudHMgYXMgZGVwdGggKHRyYW1wb2xpbmUgbW9kZWwpOioqIGBleGVjdXRlTm9kZWAgaXMgYW4gaXRlcmF0aXZlXG4gICAqIGRyaXZlciDigJQgbGluZWFyIGBuZXh0YCBob3BzLCBsb29wIGVkZ2VzIChgbG9vcFRvYC9keW5hbWljIG5leHQpLCBhbmRcbiAgICogZHluYW1pYy1zdWJmbG93IHJlLWVudHJ5IGFyZSBmb2xsb3dlZCBpbiBhIGZsYXQgbG9vcCBhbmQgY29uc3VtZSBOTyBkZXB0aC5cbiAgICogRGVwdGggZ3Jvd3Mgb25seSB3aXRoIHRydWUgdHJlZSBuZXN0aW5nOiBvbmUgdGljayBwZXIgZm9yayBjaGlsZCwgb25lIHBlclxuICAgKiBkZWNpZGVyL3NlbGVjdG9yIGJyYW5jaCBkaXNwYXRjaCB0aGF0IG11c3QgcmV0dXJuIHRvIGl0cyBpbnZva2VyIChkZWNpZGVyXG4gICAqIHdpdGggaXRzIG93biBgbmV4dGApLCBvbmUgcGVyIHN1YmZsb3cgbW91bnQgZnJhbWUgaW4gdGhlIHBhcmVudCAodGhlXG4gICAqIHN1YmZsb3cgYm9keSBpdHNlbGYgcnVucyBvbiBhIEZSRVNIIHRyYXZlcnNlciB3aXRoIGl0cyBvd24gYnVkZ2V0KS5cbiAgICpcbiAgICogNTAwIHRoZXJlZm9yZSBjb3ZlcnMgYW55IHJlYWxpc3RpYyBjaGFydCDigJQgaXQgYm91bmRzIHJlY3Vyc2l2ZVxuICAgKiBDT01QT1NJVElPTiwgbm90IGNoYWluIGxlbmd0aCBvciBsb29wIGNvdW50LiBMb29wcyBhcmUgYm91bmRlZCBieVxuICAgKiBgQ29udGludWF0aW9uUmVzb2x2ZXJgJ3MgaW5kZXBlbmRlbnQgaXRlcmF0aW9uIGxpbWl0IChkZWZhdWx0IDEwMDAsXG4gICAqIGNvbmZpZ3VyYWJsZSB2aWEgYFJ1bk9wdGlvbnMubWF4SXRlcmF0aW9uc2ApLCB3aGljaCBpcyBub3cgdGhlIGJpbmRpbmdcbiAgICogY29uc3RyYWludCBmb3IgbG9vcC1oZWF2eSBwaXBlbGluZXMuXG4gICAqXG4gICAqIEByZW1hcmtzIE5vdCBzYWZlIGZvciBjb25jdXJyZW50IGAuZXhlY3V0ZSgpYCBjYWxscyBvbiB0aGUgc2FtZSBpbnN0YW5jZSDigJQgY29uY3VycmVudFxuICAgKiBleGVjdXRpb25zIHJhY2Ugb24gYF9leGVjdXRlRGVwdGhgLiBVc2UgYSBzZXBhcmF0ZSBgRmxvd2NoYXJ0VHJhdmVyc2VyYCBwZXIgY29uY3VycmVudFxuICAgKiBleGVjdXRpb24uIGBGbG93Q2hhcnRFeGVjdXRvci5ydW4oKWAgYWx3YXlzIGNyZWF0ZXMgYSBmcmVzaCB0cmF2ZXJzZXIgcGVyIGNhbGwuXG4gICAqL1xuICBzdGF0aWMgcmVhZG9ubHkgTUFYX0VYRUNVVEVfREVQVEggPSA1MDA7XG5cbiAgY29uc3RydWN0b3Iob3B0czogVHJhdmVyc2VyT3B0aW9uczxUT3V0LCBUU2NvcGU+KSB7XG4gICAgY29uc3QgbWF4RGVwdGggPSBvcHRzLm1heERlcHRoID8/IEZsb3djaGFydFRyYXZlcnNlci5NQVhfRVhFQ1VURV9ERVBUSDtcbiAgICBpZiAobWF4RGVwdGggPCAxKSB0aHJvdyBuZXcgRXJyb3IoJ0Zsb3djaGFydFRyYXZlcnNlcjogbWF4RGVwdGggbXVzdCBiZSA+PSAxJyk7XG4gICAgdGhpcy5fbWF4RGVwdGggPSBtYXhEZXB0aDtcbiAgICBpZiAob3B0cy5tYXhJdGVyYXRpb25zICE9PSB1bmRlZmluZWQgJiYgb3B0cy5tYXhJdGVyYXRpb25zIDwgMSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdGbG93Y2hhcnRUcmF2ZXJzZXI6IG1heEl0ZXJhdGlvbnMgbXVzdCBiZSA+PSAxJyk7XG4gICAgfVxuICAgIHRoaXMuX21heEl0ZXJhdGlvbnMgPSBvcHRzLm1heEl0ZXJhdGlvbnM7XG4gICAgdGhpcy5fZXhlY3V0aW9uQ291bnRlciA9IG9wdHMuZXhlY3V0aW9uQ291bnRlciA/PyB7IHZhbHVlOiAwIH07XG4gICAgdGhpcy5yb290ID0gb3B0cy5yb290O1xuICAgIC8vIFNoYWxsb3ctY29weSBzdGFnZU1hcCBhbmQgc3ViZmxvd3Mgc28gdGhhdCBsYXp5LXJlc29sdXRpb24gbXV0YXRpb25zXG4gICAgLy8gKHByZWZpeGVkIGVudHJpZXMgYWRkZWQgZHVyaW5nIGV4ZWN1dGlvbikgc3RheSBzY29wZWQgdG8gVEhJUyB0cmF2ZXJzZXJcbiAgICAvLyBhbmQgZG8gbm90IGVzY2FwZSB0byB0aGUgc2hhcmVkIEZsb3dDaGFydCBvYmplY3QuIFdpdGhvdXQgdGhlIGNvcHksXG4gICAgLy8gY29uY3VycmVudCBGbG93Q2hhcnRFeGVjdXRvciBydW5zIHNoYXJpbmcgdGhlIHNhbWUgRmxvd0NoYXJ0IHdvdWxkIHJhY2VcbiAgICAvLyBvbiB0aGVzZSB0d28gbXV0YWJsZSBkaWN0aW9uYXJpZXMuXG4gICAgdGhpcy5zdGFnZU1hcCA9IG5ldyBNYXAob3B0cy5zdGFnZU1hcCk7XG4gICAgdGhpcy5leGVjdXRpb25SdW50aW1lID0gb3B0cy5leGVjdXRpb25SdW50aW1lO1xuICAgIHRoaXMuc3ViZmxvd3MgPSBvcHRzLnN1YmZsb3dzID8geyAuLi5vcHRzLnN1YmZsb3dzIH0gOiB7fTtcbiAgICB0aGlzLmxvZ2dlciA9IG9wdHMubG9nZ2VyO1xuICAgIHRoaXMuc2lnbmFsID0gb3B0cy5zaWduYWw7XG4gICAgdGhpcy5wYXJlbnRTdWJmbG93SWQgPSBvcHRzLnBhcmVudFN1YmZsb3dJZDtcbiAgICB0aGlzLnJlYWRPbmx5Q29udGV4dCA9IG9wdHMucmVhZE9ubHlDb250ZXh0O1xuICAgIHRoaXMucnVuSWQgPSBvcHRzLnJ1bklkO1xuXG4gICAgLy8gU3RydWN0dXJlIG1hbmFnZXIgKGRlZXAtY2xvbmVzIGJ1aWxkLXRpbWUgc3RydWN0dXJlKVxuICAgIHRoaXMuc3RydWN0dXJlTWFuYWdlciA9IG5ldyBSdW50aW1lU3RydWN0dXJlTWFuYWdlcigpO1xuICAgIHRoaXMuc3RydWN0dXJlTWFuYWdlci5pbml0KG9wdHMuYnVpbGRUaW1lU3RydWN0dXJlKTtcblxuICAgIC8vIE5hcnJhdGl2ZSBnZW5lcmF0b3JcbiAgICAvLyBQcmlvcml0eTogZXhwbGljaXQgbmFycmF0aXZlR2VuZXJhdG9yID4gZmxvd1JlY29yZGVycyA+IGRlZmF1bHQgTmFycmF0aXZlRmxvd1JlY29yZGVyID4gbnVsbC5cbiAgICAvLyBTdWJmbG93IHRyYXZlcnNlcnMgcmVjZWl2ZSB0aGUgcGFyZW50J3MgbmFycmF0aXZlR2VuZXJhdG9yIHNvIGFsbCBldmVudHMgZmxvdyB0byBvbmUgcGxhY2UuXG4gICAgaWYgKG9wdHMubmFycmF0aXZlR2VuZXJhdG9yKSB7XG4gICAgICB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvciA9IG9wdHMubmFycmF0aXZlR2VuZXJhdG9yO1xuICAgIH0gZWxzZSBpZiAob3B0cy5uYXJyYXRpdmVFbmFibGVkKSB7XG4gICAgICBjb25zdCBkaXNwYXRjaGVyID0gbmV3IEZsb3dSZWNvcmRlckRpc3BhdGNoZXIoKTtcbiAgICAgIHRoaXMuZmxvd1JlY29yZGVyRGlzcGF0Y2hlciA9IGRpc3BhdGNoZXI7XG5cbiAgICAgIC8vIElmIGN1c3RvbSBGbG93UmVjb3JkZXJzIGFyZSBwcm92aWRlZCwgdXNlIHRoZW07IG90aGVyd2lzZSBhdHRhY2ggZGVmYXVsdCBOYXJyYXRpdmVGbG93UmVjb3JkZXJcbiAgICAgIGlmIChvcHRzLmZsb3dSZWNvcmRlcnMgJiYgb3B0cy5mbG93UmVjb3JkZXJzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgZm9yIChjb25zdCByZWNvcmRlciBvZiBvcHRzLmZsb3dSZWNvcmRlcnMpIHtcbiAgICAgICAgICBkaXNwYXRjaGVyLmF0dGFjaChyZWNvcmRlcik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRpc3BhdGNoZXIuYXR0YWNoKG5ldyBOYXJyYXRpdmVGbG93UmVjb3JkZXIoKSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yID0gZGlzcGF0Y2hlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3IgPSBuZXcgTnVsbENvbnRyb2xGbG93TmFycmF0aXZlR2VuZXJhdG9yKCk7XG4gICAgfVxuXG4gICAgLy8gQnVpbGQgc2hhcmVkIGRlcHMgYmFnXG4gICAgY29uc3QgZGVwcyA9IHRoaXMuY3JlYXRlRGVwcyhvcHRzKTtcblxuICAgIC8vIEJ1aWxkIE8oMSkgbm9kZSBJRCBtYXAgZnJvbSB0aGUgcm9vdCBncmFwaCAoYXZvaWRzIHJlcGVhdGVkIERGUyBvbiBldmVyeSBsb29wVG8oKSlcbiAgICBjb25zdCBub2RlSWRNYXAgPSB0aGlzLmJ1aWxkTm9kZUlkTWFwKG9wdHMucm9vdCk7XG5cbiAgICAvLyBJbml0aWFsaXplIGhhbmRsZXIgbW9kdWxlcy5cbiAgICAvLyBOb2RlUmVzb2x2ZXIncyBERlMgZmFsbGJhY2sgcmVzb2x2ZXMgbG9vcCB0YXJnZXRzIGFnYWluc3QgdGhlIExJVkVcbiAgICAvLyBydW50aW1lIHNoYXBlLCBzbyBpdCByZWFkcyBjaGlsZHJlbiB0aHJvdWdoIHRoZSBkeW5hbWljLXBhdGNoIG92ZXJsYXlcbiAgICAvLyAoYSBsb29wIGNhbiB0YXJnZXQgYSBub2RlIGFkZGVkIGJ5IGEgZHluYW1pYyBTdGFnZU5vZGUgcmV0dXJuKS5cbiAgICB0aGlzLm5vZGVSZXNvbHZlciA9IG5ldyBOb2RlUmVzb2x2ZXIoZGVwcywgbm9kZUlkTWFwLCAobikgPT4gdGhpcy5lZmZDaGlsZHJlbihuKSk7XG4gICAgdGhpcy5jaGlsZHJlbkV4ZWN1dG9yID0gbmV3IENoaWxkcmVuRXhlY3V0b3IoZGVwcywgdGhpcy5leGVjdXRlTm9kZS5iaW5kKHRoaXMpKTtcbiAgICB0aGlzLnN0YWdlUnVubmVyID0gbmV3IFN0YWdlUnVubmVyKGRlcHMpO1xuICAgIHRoaXMuY29udGludWF0aW9uUmVzb2x2ZXIgPSBuZXcgQ29udGludWF0aW9uUmVzb2x2ZXIoXG4gICAgICBkZXBzLFxuICAgICAgdGhpcy5ub2RlUmVzb2x2ZXIsXG4gICAgICAobm9kZUlkLCBjb3VudCkgPT4gdGhpcy5zdHJ1Y3R1cmVNYW5hZ2VyLnVwZGF0ZUl0ZXJhdGlvbkNvdW50KG5vZGVJZCwgY291bnQpLFxuICAgICAgdGhpcy5fbWF4SXRlcmF0aW9ucyxcbiAgICApO1xuICAgIHRoaXMuZGVjaWRlckhhbmRsZXIgPSBuZXcgRGVjaWRlckhhbmRsZXIoZGVwcyk7XG4gICAgdGhpcy5zZWxlY3RvckhhbmRsZXIgPSBuZXcgU2VsZWN0b3JIYW5kbGVyKGRlcHMsIHRoaXMuY2hpbGRyZW5FeGVjdXRvcik7XG4gICAgdGhpcy5zdWJmbG93RXhlY3V0b3IgPSBuZXcgU3ViZmxvd0V4ZWN1dG9yKGRlcHMsIHRoaXMuY3JlYXRlU3ViZmxvd1RyYXZlcnNlckZhY3Rvcnkob3B0cykpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZSBhIGZhY3RvcnkgdGhhdCBwcm9kdWNlcyBGbG93Y2hhcnRUcmF2ZXJzZXIgaW5zdGFuY2VzIGZvciBzdWJmbG93IGV4ZWN1dGlvbi5cbiAgICogQ2FwdHVyZXMgcGFyZW50IGNvbmZpZyBpbiBjbG9zdXJlIOKAlCBTdWJmbG93RXhlY3V0b3IgcHJvdmlkZXMgc3ViZmxvdy1zcGVjaWZpYyBvdmVycmlkZXMuXG4gICAqIEVhY2ggc3ViZmxvdyBnZXRzIGEgZnVsbCB0cmF2ZXJzZXIgd2l0aCBhbGwgNyBwaGFzZXMgKGRlY2lkZXJzLCBzZWxlY3RvcnMsIGxvb3BzLCBldGMuKS5cbiAgICovXG4gIHByaXZhdGUgY3JlYXRlU3ViZmxvd1RyYXZlcnNlckZhY3RvcnkoXG4gICAgcGFyZW50T3B0czogVHJhdmVyc2VyT3B0aW9uczxUT3V0LCBUU2NvcGU+LFxuICApOiBTdWJmbG93VHJhdmVyc2VyRmFjdG9yeTxUT3V0LCBUU2NvcGU+IHtcbiAgICAvLyBDYXB0dXJlIHJlZmVyZW5jZXMgdG8gbXV0YWJsZSBzdGF0ZSDigJQgZmFjdG9yeSByZWFkcyB0aGUgQ1VSUkVOVCBzdGF0ZSB3aGVuIGNhbGxlZCxcbiAgICAvLyBub3QgdGhlIHN0YXRlIGF0IGZhY3RvcnkgY3JlYXRpb24gdGltZS4gVGhpcyBpcyBjb3JyZWN0IGJlY2F1c2UgbGF6eSBzdWJmbG93IHJlc29sdXRpb25cbiAgICAvLyBtYXkgYWRkIGVudHJpZXMgdG8gc3RhZ2VNYXAvc3ViZmxvd3MgYmVmb3JlIGEgbmVzdGVkIHN1YmZsb3cgaXMgZW5jb3VudGVyZWQuXG4gICAgY29uc3QgcGFyZW50U3RhZ2VNYXAgPSB0aGlzLnN0YWdlTWFwO1xuICAgIGNvbnN0IHBhcmVudFN1YmZsb3dzID0gdGhpcy5zdWJmbG93cztcbiAgICBjb25zdCBuYXJyYXRpdmVHZW5lcmF0b3IgPSB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvcjtcblxuICAgIHJldHVybiAoc3ViZmxvd09wdHMpID0+IHtcbiAgICAgIGNvbnN0IHRyYXZlcnNlciA9IG5ldyBGbG93Y2hhcnRUcmF2ZXJzZXI8VE91dCwgVFNjb3BlPih7XG4gICAgICAgIHJvb3Q6IHN1YmZsb3dPcHRzLnJvb3QsXG4gICAgICAgIHN0YWdlTWFwOiBwYXJlbnRTdGFnZU1hcCwgLy8gQ29uc3RydWN0b3Igc2hhbGxvdy1jb3BpZXMgdGhpc1xuICAgICAgICBzY29wZUZhY3Rvcnk6IHBhcmVudE9wdHMuc2NvcGVGYWN0b3J5LFxuICAgICAgICBleGVjdXRpb25SdW50aW1lOiBzdWJmbG93T3B0cy5leGVjdXRpb25SdW50aW1lLFxuICAgICAgICByZWFkT25seUNvbnRleHQ6IHN1YmZsb3dPcHRzLnJlYWRPbmx5Q29udGV4dCxcbiAgICAgICAgZXhlY3V0aW9uRW52OiBwYXJlbnRPcHRzLmV4ZWN1dGlvbkVudixcbiAgICAgICAgdGhyb3R0bGluZ0Vycm9yQ2hlY2tlcjogcGFyZW50T3B0cy50aHJvdHRsaW5nRXJyb3JDaGVja2VyLFxuICAgICAgICBzdHJlYW1IYW5kbGVyczogcGFyZW50T3B0cy5zdHJlYW1IYW5kbGVycyxcbiAgICAgICAgc2NvcGVQcm90ZWN0aW9uTW9kZTogcGFyZW50T3B0cy5zY29wZVByb3RlY3Rpb25Nb2RlLFxuICAgICAgICBzdWJmbG93czogcGFyZW50U3ViZmxvd3MsIC8vIENvbnN0cnVjdG9yIHNoYWxsb3ctY29waWVzIHRoaXNcbiAgICAgICAgbmFycmF0aXZlR2VuZXJhdG9yLCAvLyBTaGFyZSBwYXJlbnQncyDigJQgYWxsIGV2ZW50cyBmbG93IHRvIG9uZSBwbGFjZVxuICAgICAgICBsb2dnZXI6IHBhcmVudE9wdHMubG9nZ2VyLFxuICAgICAgICBzaWduYWw6IHBhcmVudE9wdHMuc2lnbmFsLFxuICAgICAgICBtYXhEZXB0aDogdGhpcy5fbWF4RGVwdGgsXG4gICAgICAgIC4uLih0aGlzLl9tYXhJdGVyYXRpb25zICE9PSB1bmRlZmluZWQgJiYgeyBtYXhJdGVyYXRpb25zOiB0aGlzLl9tYXhJdGVyYXRpb25zIH0pLFxuICAgICAgICBwYXJlbnRTdWJmbG93SWQ6IHN1YmZsb3dPcHRzLnN1YmZsb3dJZCxcbiAgICAgICAgZXhlY3V0aW9uQ291bnRlcjogdGhpcy5fZXhlY3V0aW9uQ291bnRlciwgLy8gU2hhcmUgY291bnRlciDigJQgc3ViZmxvdyBjb250aW51ZXMgZ2xvYmFsIG51bWJlcmluZ1xuICAgICAgICBydW5JZDogdGhpcy5ydW5JZCwgLy8gU3ViZmxvdyBpbmhlcml0cyBwYXJlbnQncyBydW5JZCDigJQgc2FtZSBsb2dpY2FsIHJ1blxuICAgICAgICAvLyBGb3J3YXJkIHRoZSByZXN1bWUtb25seSBzdWJmbG93IHNjb3BlIGNhcHR1cmVzIHNvIG5lc3RlZFxuICAgICAgICAvLyBTdWJmbG93RXhlY3V0b3JzIGNhbiByZS1zZWVkIGRlZXBlci1uZXN0ZWQgcnVudGltZXMgKGUuZy5cbiAgICAgICAgLy8gU2VxdWVuY2UoQWdlbnQoLi4uKSkgd2hlcmUgdGhlIGlubmVyIEFnZW50IHN1YmZsb3cgcGF1c2VkKS5cbiAgICAgICAgLi4uKHBhcmVudE9wdHMuc3ViZmxvd1N0YXRlc0ZvclJlc3VtZSAmJiB7XG4gICAgICAgICAgc3ViZmxvd1N0YXRlc0ZvclJlc3VtZTogcGFyZW50T3B0cy5zdWJmbG93U3RhdGVzRm9yUmVzdW1lLFxuICAgICAgICB9KSxcbiAgICAgIH0pO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBleGVjdXRlOiAoKSA9PiB0cmF2ZXJzZXIuZXhlY3V0ZSgpLFxuICAgICAgICBnZXRTdWJmbG93UmVzdWx0czogKCkgPT4gdHJhdmVyc2VyLmdldFN1YmZsb3dSZXN1bHRzKCksXG4gICAgICAgIGdldEJyZWFrU3RhdGU6ICgpID0+IHRyYXZlcnNlci5nZXRCcmVha1N0YXRlKCksXG4gICAgICB9O1xuICAgIH07XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZURlcHMob3B0czogVHJhdmVyc2VyT3B0aW9uczxUT3V0LCBUU2NvcGU+KTogSGFuZGxlckRlcHM8VE91dCwgVFNjb3BlPiB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHN0YWdlTWFwOiB0aGlzLnN0YWdlTWFwLFxuICAgICAgcm9vdDogdGhpcy5yb290LFxuICAgICAgZXhlY3V0aW9uUnVudGltZTogdGhpcy5leGVjdXRpb25SdW50aW1lLFxuICAgICAgc2NvcGVGYWN0b3J5OiBvcHRzLnNjb3BlRmFjdG9yeSxcbiAgICAgIHN1YmZsb3dzOiB0aGlzLnN1YmZsb3dzLFxuICAgICAgdGhyb3R0bGluZ0Vycm9yQ2hlY2tlcjogb3B0cy50aHJvdHRsaW5nRXJyb3JDaGVja2VyLFxuICAgICAgc3RyZWFtSGFuZGxlcnM6IG9wdHMuc3RyZWFtSGFuZGxlcnMsXG4gICAgICBzY29wZVByb3RlY3Rpb25Nb2RlOiBvcHRzLnNjb3BlUHJvdGVjdGlvbk1vZGUgPz8gJ2Vycm9yJyxcbiAgICAgIHJlYWRPbmx5Q29udGV4dDogb3B0cy5yZWFkT25seUNvbnRleHQsXG4gICAgICBleGVjdXRpb25FbnY6IG9wdHMuZXhlY3V0aW9uRW52LFxuICAgICAgbmFycmF0aXZlR2VuZXJhdG9yOiB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvcixcbiAgICAgIGxvZ2dlcjogdGhpcy5sb2dnZXIsXG4gICAgICBzaWduYWw6IG9wdHMuc2lnbmFsLFxuICAgICAgLi4uKG9wdHMuc3ViZmxvd1N0YXRlc0ZvclJlc3VtZSAmJiB7XG4gICAgICAgIHN1YmZsb3dTdGF0ZXNGb3JSZXN1bWU6IG9wdHMuc3ViZmxvd1N0YXRlc0ZvclJlc3VtZSxcbiAgICAgIH0pLFxuICAgIH07XG4gIH1cblxuICAvLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAgUHVibGljIEFQSSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcblxuICAvKipcbiAgICogSG9sZHMgdGhlIHRvcC1sZXZlbCBicmVhayBmbGFnIGZvciB0aGUgZHVyYXRpb24gb2YgYGV4ZWN1dGUoKWAuIEtlcHQgYXNcbiAgICogYSBmaWVsZCAobm90IGEgbG9jYWwpIHNvIGBnZXRCcmVha1N0YXRlKClgIGNhbiBzdXJmYWNlIHRoZSBmaW5hbCBzdGF0ZVxuICAgKiBmb3IgY2FsbGVycyBsaWtlIGBTdWJmbG93RXhlY3V0b3JgIHRoYXQgaW1wbGVtZW50IGBwcm9wYWdhdGVCcmVha2AuXG4gICAqL1xuICBwcml2YXRlIF90b3BCcmVha0ZsYWc6IHsgc2hvdWxkQnJlYWs6IGJvb2xlYW47IHJlYXNvbj86IHN0cmluZyB9ID0geyBzaG91bGRCcmVhazogZmFsc2UgfTtcblxuICBhc3luYyBleGVjdXRlKGJyYW5jaFBhdGg/OiBzdHJpbmcpOiBQcm9taXNlPFRyYXZlcnNhbFJlc3VsdD4ge1xuICAgIGNvbnN0IGNvbnRleHQgPSB0aGlzLmV4ZWN1dGlvblJ1bnRpbWUucm9vdFN0YWdlQ29udGV4dDtcbiAgICB0aGlzLl90b3BCcmVha0ZsYWcgPSB7IHNob3VsZEJyZWFrOiBmYWxzZSB9O1xuXG4gICAgLy8gRmlyZSBvblJ1blN0YXJ0IE9OTFkgYXQgdGhlIHRvcC1sZXZlbCB0cmF2ZXJzYWwg4oCUIHN1YmZsb3cgdHJhdmVyc2Vyc1xuICAgIC8vIGFscmVhZHkgcHJvZHVjZSBvblN1YmZsb3dFbnRyeS9vblN1YmZsb3dFeGl0IHBhaXJzLCBzbyBlbWl0dGluZyBydW5cbiAgICAvLyBldmVudHMgZm9yIHRoZW0gd291bGQgZG91YmxlLWJyYWNrZXQgdGhlIGJvdW5kYXJ5IHN0cmVhbS4gVGhlXG4gICAgLy8gdG9wLWxldmVsIHRyYXZlcnNlciBpcyB0aGUgb25lIHdpdGhvdXQgYSBwYXJlbnRTdWJmbG93SWQuXG4gICAgY29uc3QgaXNUb3BMZXZlbCA9IHRoaXMucGFyZW50U3ViZmxvd0lkID09PSB1bmRlZmluZWQ7XG4gICAgLy8gU3ludGhldGljIFRyYXZlcnNhbENvbnRleHQgZm9yIHJ1bi5lbnRyeSAvIHJ1bi5leGl0LiBGaWVsZHMgdXNlXG4gICAgLy8gcm9vdC1zdGFnZSBkZWZhdWx0cyAoc3RhZ2VJZD0nX19yb290X18nLCBydW50aW1lU3RhZ2VJZD0nX19yb290X18jMCcsXG4gICAgLy8gZGVwdGggMCkgc28gdGhlIHJ1bklkIGlzIHJlbGlhYmx5IGF2YWlsYWJsZSBvbiBydW4gZXZlbnRzIHdpdGhvdXRcbiAgICAvLyBmb3JjaW5nIHJlY29yZGVycyB0byBoYW5kbGUgYHRyYXZlcnNhbENvbnRleHQgPT09IHVuZGVmaW5lZGAuXG4gICAgY29uc3Qgcm9vdENvbnRleHQ6IFRyYXZlcnNhbENvbnRleHQgPSB7XG4gICAgICBydW5JZDogdGhpcy5ydW5JZCxcbiAgICAgIHN0YWdlSWQ6ICdfX3Jvb3RfXycsXG4gICAgICBydW50aW1lU3RhZ2VJZDogJ19fcm9vdF9fIzAnLFxuICAgICAgc3RhZ2VOYW1lOiAnX19yb290X18nLFxuICAgICAgZGVwdGg6IDAsXG4gICAgfTtcbiAgICBpZiAoaXNUb3BMZXZlbCkge1xuICAgICAgLy8gYHJlYWRPbmx5Q29udGV4dGAgaXMgdGhlIGVuZ2luZSdzIHZpZXcgb2YgYHJ1bih7aW5wdXR9KWAg4oCUIHBhc3NlZFxuICAgICAgLy8gdGhyb3VnaCBmcm9tIGBGbG93Q2hhcnRFeGVjdXRvci5ydW4oKWAgYXMgdGhlIHZhbGlkYXRlZCBpbnB1dC5cbiAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yLm9uUnVuU3RhcnQodGhpcy5yZWFkT25seUNvbnRleHQsIHJvb3RDb250ZXh0KTtcbiAgICB9XG5cbiAgICAvLyBUb3AtbGV2ZWwgcnVucyBjbG9zZSB0aGVpciBib3VuZGFyeSBTWU1NRVRSSUNBTExZOiBldmVyeSBvblJ1blN0YXJ0XG4gICAgLy8gaXMgZm9sbG93ZWQgYnkgZXhhY3RseSBvbmUgb25SdW5FbmQgKGNsZWFuKSBvciBvblJ1bkZhaWxlZCAoZXJyb3IpLlxuICAgIC8vIFdpdGhvdXQgdGhlIGNhdGNoLCBhIHRocm93biBydW4gZmlyZWQgb25SdW5TdGFydCB0aGVuIG5vdGhpbmcg4oCUIGFcbiAgICAvLyBtb25pdG9yIGNvdWxkbid0IHRlbGwgXCJzdGlsbCBydW5uaW5nXCIgZnJvbSBcImNyYXNoZWQuXCIgUGF1c2UgaXMgTk9UXG4gICAgLy8gYW4gZXJyb3IgKGl0J3MgZXhwZWN0ZWQgc3VzcGVuc2lvbiksIHNvIGl0IHNraXBzIG9uUnVuRmFpbGVkIGFuZFxuICAgIC8vIHJlLXRocm93cyB1bnRvdWNoZWQuIFRoZSBzdGFnZS1sZXZlbCBjYXRjaCBhbHJlYWR5IHJlY29yZGVkIHRoZVxuICAgIC8vIGZhaWxpbmcgc3RhZ2UgKG9uRXJyb3IgKyBjb21taXQpOyB0aGlzIGFkZHMgdGhlIHJ1bi1sZXZlbCB0ZXJtaW5hbFxuICAgIC8vIHNpZ25hbC4gVGhlIGVycm9yIHN0aWxsIHByb3BhZ2F0ZXMg4oCUIHRoaXMgaXMgb2JzZXJ2YXRpb24sIG5vdFxuICAgIC8vIHJlY292ZXJ5LiBTdWJmbG93IHRyYXZlcnNlcnMgZG9uJ3QgZmlyZSBydW4gZXZlbnRzOyB0aGVpciBlcnJvcnNcbiAgICAvLyBidWJibGUgdXAgYW5kIHN1cmZhY2UgaGVyZSBhdCB0aGUgdG9wIGxldmVsLlxuICAgIGlmICghaXNUb3BMZXZlbCkge1xuICAgICAgcmV0dXJuIHRoaXMuZXhlY3V0ZU5vZGUodGhpcy5yb290LCBjb250ZXh0LCB0aGlzLl90b3BCcmVha0ZsYWcsIGJyYW5jaFBhdGggPz8gJycpO1xuICAgIH1cbiAgICBsZXQgcmVzdWx0OiBUcmF2ZXJzYWxSZXN1bHQ7XG4gICAgdHJ5IHtcbiAgICAgIHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZU5vZGUodGhpcy5yb290LCBjb250ZXh0LCB0aGlzLl90b3BCcmVha0ZsYWcsIGJyYW5jaFBhdGggPz8gJycpO1xuICAgIH0gY2F0Y2ggKGVycm9yOiB1bmtub3duKSB7XG4gICAgICBpZiAoIWlzUGF1c2VTaWduYWwoZXJyb3IpKSB7XG4gICAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yLm9uUnVuRmFpbGVkKGV4dHJhY3RFcnJvckluZm8oZXJyb3IpLCByb290Q29udGV4dCk7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3Iub25SdW5FbmQocmVzdWx0LCByb290Q29udGV4dCk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBCcmVhayBzdGF0ZSBjYXB0dXJlZCBhdCB0aGUgdG9wLWxldmVsIG9mIHRoZSBtb3N0IHJlY2VudCBgZXhlY3V0ZSgpYC5cbiAgICogYHNob3VsZEJyZWFrYCBpcyB0cnVlIHdoZW4gYSBzdGFnZSBjYWxsZWQgYHNjb3BlLiRicmVhayhyZWFzb24pYDsgdGhlXG4gICAqIG9wdGlvbmFsIGByZWFzb25gIGNhcnJpZXMgdGhlIHN0cmluZyBwYXNzZWQgdG8gYCRicmVha2AuXG4gICAqXG4gICAqIFVzZWQgYnkgYFN1YmZsb3dFeGVjdXRvcmAgdG8gcHJvcGFnYXRlIGFuIGlubmVyIHN1YmZsb3cncyBicmVhayB1cCB0b1xuICAgKiB0aGUgcGFyZW50IHRyYXZlcnNlciB3aGVuIHRoZSBtb3VudCBzZXRzIGBwcm9wYWdhdGVCcmVhazogdHJ1ZWAuXG4gICAqL1xuICBnZXRCcmVha1N0YXRlKCk6IHsgc2hvdWxkQnJlYWs6IGJvb2xlYW47IHJlYXNvbj86IHN0cmluZyB9IHtcbiAgICByZXR1cm4geyAuLi50aGlzLl90b3BCcmVha0ZsYWcgfTtcbiAgfVxuXG4gIGdldFJ1bnRpbWVTdHJ1Y3R1cmUoKTogU2VyaWFsaXplZFBpcGVsaW5lU3RydWN0dXJlIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5zdHJ1Y3R1cmVNYW5hZ2VyLmdldFN0cnVjdHVyZSgpO1xuICB9XG5cbiAgZ2V0U25hcHNob3Qob3B0aW9ucz86IHsgcmVkYWN0PzogYm9vbGVhbiB9KSB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0aW9uUnVudGltZS5nZXRTbmFwc2hvdChvcHRpb25zKTtcbiAgfVxuXG4gIGdldFJ1bnRpbWUoKSB7XG4gICAgcmV0dXJuIHRoaXMuZXhlY3V0aW9uUnVudGltZTtcbiAgfVxuXG4gIHNldFJvb3RPYmplY3QocGF0aDogc3RyaW5nW10sIGtleTogc3RyaW5nLCB2YWx1ZTogdW5rbm93bikge1xuICAgIHRoaXMuZXhlY3V0aW9uUnVudGltZS5zZXRSb290T2JqZWN0KHBhdGgsIGtleSwgdmFsdWUpO1xuICB9XG5cbiAgZ2V0QnJhbmNoSWRzKCkge1xuICAgIHJldHVybiB0aGlzLmV4ZWN1dGlvblJ1bnRpbWUuZ2V0UGlwZWxpbmVzKCk7XG4gIH1cblxuICBnZXRSdW50aW1lUm9vdCgpOiBTdGFnZU5vZGUge1xuICAgIHJldHVybiB0aGlzLnJvb3Q7XG4gIH1cblxuICBnZXRTdWJmbG93UmVzdWx0cygpOiBNYXA8c3RyaW5nLCBTdWJmbG93UmVzdWx0PiB7XG4gICAgcmV0dXJuIHRoaXMuc3ViZmxvd1Jlc3VsdHM7XG4gIH1cblxuICBnZXROYXJyYXRpdmUoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvci5nZXRTZW50ZW5jZXMoKTtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSBGbG93UmVjb3JkZXJEaXNwYXRjaGVyLCBvciB1bmRlZmluZWQgaWYgbmFycmF0aXZlIGlzIGRpc2FibGVkLiAqL1xuICBnZXRGbG93UmVjb3JkZXJEaXNwYXRjaGVyKCk6IEZsb3dSZWNvcmRlckRpc3BhdGNoZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmZsb3dSZWNvcmRlckRpc3BhdGNoZXI7XG4gIH1cblxuICAvLyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIAgQ29yZSBUcmF2ZXJzYWwg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgLyoqXG4gICAqIEJ1aWxkIGFuIE8oMSkgSUTihpJub2RlIG1hcCBmcm9tIHRoZSByb290IGdyYXBoLlxuICAgKiBVc2VkIGJ5IE5vZGVSZXNvbHZlciB0byBhdm9pZCByZXBlYXRlZCBERlMgb24gZXZlcnkgbG9vcFRvKCkgY2FsbC5cbiAgICogSXRlcmF0aXZlIHdvcmtsaXN0IChubyByZWN1cnNpb24pIHNvIGFyYml0cmFyaWx5IGxvbmcgY2hhaW5zIGluZGV4IGZ1bGx5O1xuICAgKiB0aGUgYG1hcC5oYXNgIGd1YXJkIGhhbmRsZXMgY3ljbGljIHJlZnMuIEZpcnN0LXZpc2l0ZWQgbm9kZSB3aW5zIHBlciBJRCDigJRcbiAgICogd29ya2xpc3Qgb3JkZXIgbWF0Y2hlcyB0aGUgb2xkIHJlY3Vyc2l2ZSBwcmUtb3JkZXIgKGNoaWxkcmVuLCB0aGVuIG5leHQpLlxuICAgKiBEeW5hbWljIHN1YmZsb3dzIGFuZCBsYXp5LXJlc29sdmVkIG5vZGVzIGFyZSBhZGRlZCB0byBzdGFnZU1hcCBhdCBydW50aW1lIGJ1dCBub3QgdG8gdGhpcyBtYXAg4oCUXG4gICAqIHRob3NlIHVzZSB0aGUgREZTIGZhbGxiYWNrIGluIE5vZGVSZXNvbHZlci5cbiAgICovXG4gIHByaXZhdGUgYnVpbGROb2RlSWRNYXAocm9vdDogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4pOiBNYXA8c3RyaW5nLCBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPj4ge1xuICAgIGNvbnN0IG1hcCA9IG5ldyBNYXA8c3RyaW5nLCBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPj4oKTtcbiAgICBjb25zdCBzdGFjazogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT5bXSA9IFtyb290XTtcbiAgICB3aGlsZSAoc3RhY2subGVuZ3RoID4gMCkge1xuICAgICAgY29uc3Qgbm9kZSA9IHN0YWNrLnBvcCgpITtcbiAgICAgIGlmIChtYXAuaGFzKG5vZGUuaWQpKSBjb250aW51ZTsgLy8gYWxyZWFkeSB2aXNpdGVkIChhdm9pZHMgaW5maW5pdGUgbG9vcHMgb24gY3ljbGljIHJlZnMpXG4gICAgICBtYXAuc2V0KG5vZGUuaWQsIG5vZGUpO1xuICAgICAgLy8gUHVzaCBpbiByZXZlcnNlIHZpc2l0IG9yZGVyIChMSUZPIHN0YWNrKTogbmV4dCBmaXJzdCwgdGhlbiBjaGlsZHJlblxuICAgICAgLy8gcmV2ZXJzZWQg4oCUIHNvIGNoaWxkcmVuIGFyZSB2aXNpdGVkIGJlZm9yZSBuZXh0LCBmaXJzdCBjaGlsZCBmaXJzdCxcbiAgICAgIC8vIG1hdGNoaW5nIHRoZSByZWN1cnNpdmUgcHJlLW9yZGVyIGV4YWN0bHkuXG4gICAgICBpZiAobm9kZS5uZXh0KSBzdGFjay5wdXNoKG5vZGUubmV4dCk7XG4gICAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgICBmb3IgKGxldCBpID0gbm9kZS5jaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IGktLSkgc3RhY2sucHVzaChub2RlLmNoaWxkcmVuW2ldKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hcDtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3RhZ2VGbihub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPik6IFN0YWdlRnVuY3Rpb248VE91dCwgVFNjb3BlPiB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHR5cGVvZiBub2RlLmZuID09PSAnZnVuY3Rpb24nKSByZXR1cm4gbm9kZS5mbiBhcyBTdGFnZUZ1bmN0aW9uPFRPdXQsIFRTY29wZT47XG4gICAgLy8gUHJpbWFyeTogbG9vayB1cCBieSBpZCAoc3RhYmxlIGlkZW50aWZpZXIsIGtleWVkIGJ5IEZsb3dDaGFydEJ1aWxkZXIpXG4gICAgY29uc3QgYnlJZCA9IHRoaXMuc3RhZ2VNYXAuZ2V0KG5vZGUuaWQpO1xuICAgIGlmIChieUlkICE9PSB1bmRlZmluZWQpIHJldHVybiBieUlkO1xuICAgIC8vIEZhbGxiYWNrOiBsb29rIHVwIGJ5IG5hbWUgKHN1cHBvcnRzIGhhbmQtY3JhZnRlZCBzdGFnZU1hcHMgaW4gdGVzdHMgYW5kIGFkdmFuY2VkIHVzZSlcbiAgICByZXR1cm4gdGhpcy5zdGFnZU1hcC5nZXQobm9kZS5uYW1lKTtcbiAgfVxuXG4gIC8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgCBEeW5hbWljLXBhdGNoIG92ZXJsYXkgYWNjZXNzb3JzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvL1xuICAvLyBFdmVyeSBlbmdpbmUgcmVhZCBvZiBhIGZpZWxkIHRoYXQgUGhhc2UgNCBjYW4gcGF0Y2ggKGNoaWxkcmVuLFxuICAvLyBuZXh0Tm9kZVNlbGVjdG9yLCBzdWJmbG93IG1ldGEpIGdvZXMgdGhyb3VnaCB0aGVzZS4gRmFzdCBwYXRoOiBjaGFydHNcbiAgLy8gd2l0aCBubyBkeW5hbWljIHJldHVybnMgbmV2ZXIgYWxsb2NhdGUgYW5kIHBheSBvbmUgYHNpemUgPT09IDBgIGNoZWNrLlxuXG4gIHByaXZhdGUgZ2V0UGF0Y2gobm9kZTogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4pOiBEeW5hbWljTm9kZVBhdGNoPFRPdXQsIFRTY29wZT4gfCB1bmRlZmluZWQge1xuICAgIGlmICh0aGlzLnBhdGNoQ291bnQgPT09IDApIHJldHVybiB1bmRlZmluZWQ7XG4gICAgcmV0dXJuIHRoaXMuZHluYW1pY1BhdGNoZXMuZ2V0KG5vZGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRPckNyZWF0ZVBhdGNoKG5vZGU6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+KTogRHluYW1pY05vZGVQYXRjaDxUT3V0LCBUU2NvcGU+IHtcbiAgICBsZXQgcGF0Y2ggPSB0aGlzLmR5bmFtaWNQYXRjaGVzLmdldChub2RlKTtcbiAgICBpZiAoIXBhdGNoKSB7XG4gICAgICBwYXRjaCA9IHt9O1xuICAgICAgdGhpcy5keW5hbWljUGF0Y2hlcy5zZXQobm9kZSwgcGF0Y2gpO1xuICAgICAgdGhpcy5wYXRjaENvdW50Kys7XG4gICAgfVxuICAgIHJldHVybiBwYXRjaDtcbiAgfVxuXG4gIC8qKiBFZmZlY3RpdmUgY2hpbGRyZW46IGR5bmFtaWMgcGF0Y2ggZmlyc3QsIHRoZW4gdGhlIGJ1aWx0IG5vZGUncyBjaGlsZHJlbi4gKi9cbiAgcHJpdmF0ZSBlZmZDaGlsZHJlbihub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPik6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+W10gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmdldFBhdGNoKG5vZGUpPy5jaGlsZHJlbiA/PyBub2RlLmNoaWxkcmVuO1xuICB9XG5cbiAgLyoqIEVmZmVjdGl2ZSBvdXRwdXQtYmFzZWQgc2VsZWN0b3I6IGR5bmFtaWMgcGF0Y2ggZmlyc3QsIHRoZW4gdGhlIGJ1aWx0IG5vZGUncy4gKi9cbiAgcHJpdmF0ZSBlZmZTZWxlY3Rvcihub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPik6IFNlbGVjdG9yIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5nZXRQYXRjaChub2RlKT8ubmV4dE5vZGVTZWxlY3RvciA/PyBub2RlLm5leHROb2RlU2VsZWN0b3I7XG4gIH1cblxuICAvKiogRWZmZWN0aXZlIHN1YmZsb3ctcm9vdCBtYXJrZXIgKHRydWUgd2hlbiBhIGR5bmFtaWMgc3ViZmxvdyB3YXMgcGF0Y2hlZCBvbikuICovXG4gIHByaXZhdGUgZWZmSXNTdWJmbG93Um9vdChub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPik6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldFBhdGNoKG5vZGUpPy5zdWJmbG93TWV0YTtcbiAgICByZXR1cm4gbWV0YSA/IHRydWUgOiBub2RlLmlzU3ViZmxvd1Jvb3Q7XG4gIH1cblxuICAvKiogRWZmZWN0aXZlIHN1YmZsb3cgaWQgKHBhdGNoZWQgdmVyYmF0aW0gYnkgYSBkeW5hbWljIHN1YmZsb3cgcmV0dXJuKS4gKi9cbiAgcHJpdmF0ZSBlZmZTdWJmbG93SWQobm9kZTogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldFBhdGNoKG5vZGUpPy5zdWJmbG93TWV0YTtcbiAgICByZXR1cm4gbWV0YSA/IG1ldGEuc3ViZmxvd0lkIDogbm9kZS5zdWJmbG93SWQ7XG4gIH1cblxuICAvKipcbiAgICogTWF0ZXJpYWxpemUgdGhlIGVmZmVjdGl2ZSB2aWV3IG9mIGEgbm9kZSDigJQgZmllbGQtaWRlbnRpY2FsIHRvIHdoYXQgdGhlXG4gICAqIHByZS1vdmVybGF5IGNvZGUgcHJvZHVjZWQgYnkgbXV0YXRpbmcgdGhlIHNoYXJlZCBub2RlLiBVc2VkIHdoZXJlIGEgbm9kZVxuICAgKiBpcyBoYW5kZWQgdG8gYSBoZWxwZXIgZXhlY3V0b3IgKE5vZGVSZXNvbHZlciAvIFN1YmZsb3dFeGVjdXRvciAvXG4gICAqIENoaWxkcmVuRXhlY3V0b3IpIHNvIGhlbHBlcnMgbmV2ZXIgcmVhZCBzdGFsZSBidWlsdCBmaWVsZHMuIFJldHVybnMgdGhlXG4gICAqIG5vZGUgaXRzZWxmIChubyBhbGxvY2F0aW9uKSB3aGVuIGl0IGNhcnJpZXMgbm8gcGF0Y2guXG4gICAqL1xuICBwcml2YXRlIGVmZk5vZGUobm9kZTogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4pOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiB7XG4gICAgY29uc3QgcGF0Y2ggPSB0aGlzLmdldFBhdGNoKG5vZGUpO1xuICAgIGlmICghcGF0Y2gpIHJldHVybiBub2RlO1xuICAgIGNvbnN0IG1lcmdlZDogU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4gPSB7IC4uLm5vZGUgfTtcbiAgICBpZiAocGF0Y2guc3ViZmxvd01ldGEpIHtcbiAgICAgIG1lcmdlZC5pc1N1YmZsb3dSb290ID0gdHJ1ZTtcbiAgICAgIG1lcmdlZC5zdWJmbG93SWQgPSBwYXRjaC5zdWJmbG93TWV0YS5zdWJmbG93SWQ7XG4gICAgICBtZXJnZWQuc3ViZmxvd05hbWUgPSBwYXRjaC5zdWJmbG93TWV0YS5zdWJmbG93TmFtZTtcbiAgICAgIG1lcmdlZC5zdWJmbG93TW91bnRPcHRpb25zID0gcGF0Y2guc3ViZmxvd01ldGEuc3ViZmxvd01vdW50T3B0aW9ucztcbiAgICB9XG4gICAgaWYgKHBhdGNoLmNoaWxkcmVuKSBtZXJnZWQuY2hpbGRyZW4gPSBwYXRjaC5jaGlsZHJlbjtcbiAgICBpZiAocGF0Y2gubmV4dE5vZGVTZWxlY3RvcikgbWVyZ2VkLm5leHROb2RlU2VsZWN0b3IgPSBwYXRjaC5uZXh0Tm9kZVNlbGVjdG9yO1xuICAgIHJldHVybiBtZXJnZWQ7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVTdGFnZShcbiAgICBub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPixcbiAgICBzdGFnZUZ1bmM6IFN0YWdlRnVuY3Rpb248VE91dCwgVFNjb3BlPixcbiAgICBjb250ZXh0OiBTdGFnZUNvbnRleHQsXG4gICAgYnJlYWtGbjogKCkgPT4gdm9pZCxcbiAgKSB7XG4gICAgLy8gcnVudGltZVN0YWdlSWQgaXMgYXNzaWduZWQgaW4gZXhlY3V0ZU5vZGUoKSBiZWZvcmUgdHJhdmVyc2FsQ29udGV4dCBjcmVhdGlvbixcbiAgICAvLyBlbnN1cmluZyBzY29wZSBldmVudHMgYW5kIGZsb3cgZXZlbnRzIHVzZSB0aGUgc2FtZSB2YWx1ZS5cbiAgICByZXR1cm4gdGhpcy5zdGFnZVJ1bm5lci5ydW4obm9kZSwgc3RhZ2VGdW5jLCBjb250ZXh0LCBicmVha0ZuKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFtcG9saW5lIGRyaXZlciDigJQgcHJlLW9yZGVyIERGUyB0cmF2ZXJzYWwgZW50cnkgcG9pbnQuXG4gICAqXG4gICAqIFJ1bnMgYGV4ZWN1dGVOb2RlU3RlcGAgKG9uZSBub2RlLCBhbGwgNyBwaGFzZXMpIGluIGEgZmxhdCBsb29wOiBldmVyeVxuICAgKiBUQUlMIGNvbnRpbnVhdGlvbiAobGluZWFyIGBuZXh0YCwgbG9vcCBlZGdlLCBkeW5hbWljIG5leHQgLyBkeW5hbWljXG4gICAqIHJlLWVudHJ5LCBuby1jb250aW51YXRpb24gZGVjaWRlciBkaXNwYXRjaCkgY29tZXMgYmFjayBhcyBhXG4gICAqIGBDb250aW51YXRpb25Ib3BgIGFuZCBpcyBmb2xsb3dlZCBJVEVSQVRJVkVMWSDigJQgbmVpdGhlciB0aGUgY2FsbCBzdGFja1xuICAgKiBub3IgdGhlIHJldGFpbmVkIHByb21pc2UgY2hhaW4gZ3Jvd3Mgd2l0aCBjaGFpbiBsZW5ndGggb3IgbG9vcCBjb3VudC5cbiAgICpcbiAgICogUmVjdXJzaW9uIHJlbWFpbnMgT05MWSBmb3IgdHJ1ZSB0cmVlIG5lc3RpbmcgKGVhY2ggZ2V0cyBhIG5lc3RlZCBkcml2ZXJcbiAgICogY2FsbCk6IGZvcmsgY2hpbGRyZW4gKGBDaGlsZHJlbkV4ZWN1dG9yYCksIHNlbGVjdG9yIGJyYW5jaGVzIChwYXJhbGxlbFxuICAgKiBmYW4tb3V0KSwgZGVjaWRlciBicmFuY2ggZGlzcGF0Y2ggd2hlbiB0aGUgZGVjaWRlciBoYXMgaXRzIG93biBgbmV4dGBcbiAgICogKHRoZSBicmFuY2ggbXVzdCBjb21wbGV0ZSBCRUZPUkUgdGhlIGRlY2lkZXIncyBjb250aW51YXRpb24gcnVucyksIGFuZFxuICAgKiBzdWJmbG93IG1vdW50cyAoZnJlc2ggdHJhdmVyc2VyOyB0aGUgbW91bnQgZnJhbWUgc3RheXMgaW4gdGhlIHBhcmVudCkuXG4gICAqIGBfZXhlY3V0ZURlcHRoYCB0aGVyZWZvcmUgY291bnRzIGNoYXJ0IENPTVBPU0lUSU9OIGRlcHRoIG9ubHksIGd1YXJkZWRcbiAgICogYnkgYF9tYXhEZXB0aGAgKGRlZmF1bHQgYE1BWF9FWEVDVVRFX0RFUFRIYCA9IDUwMCkuXG4gICAqXG4gICAqIFBhdXNlU2lnbmFsOiBhIGZsYXQgZGVjaWRlciBkaXNwYXRjaCByZWNvcmRzIGFuIGBJbnZva2VyU3RhbXBgOyBpZiB0aGVcbiAgICogY29udGludWVkIGNoYWluIGxhdGVyIHBhdXNlcywgdGhlIGRyaXZlciBzdGFtcHMgdGhlIHNpZ25hbCBkdXJpbmdcbiAgICogdW53aW5kIOKAlCBzYW1lIGludm9rZXIgY29udGV4dCB0aGUgcmVjdXJzaXZlIGRpc3BhdGNoJ3MgY2F0Y2ggdXNlZCB0b1xuICAgKiBzdGFtcCwgaW5uZXJtb3N0IChtb3N0IHJlY2VudCBkaXNwYXRjaCkgZmlyc3QuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGV4ZWN1dGVOb2RlKFxuICAgIG5vZGU6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+LFxuICAgIGNvbnRleHQ6IFN0YWdlQ29udGV4dCxcbiAgICBicmVha0ZsYWc6IEJyZWFrRmxhZyxcbiAgICBicmFuY2hQYXRoPzogc3RyaW5nLFxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIC8vIEludm9rZXIgc3RhbXBzIGZyb20gZmxhdCBkZWNpZGVyIGRpc3BhdGNoZXMgaW4gVEhJUyBkcml2ZXIg4oCUIGtlcHRcbiAgICAvLyBsb2NhbCBzbyBuZXN0ZWQgZHJpdmVycyAoZm9yayBjaGlsZHJlbiwgd2l0aC1uZXh0IGRlY2lkZXIgYnJhbmNoZXMpXG4gICAgLy8gZ2V0IHRoZWlyIG93biB3aW5kb3dzLCBtYXRjaGluZyB0aGUgb2xkIGZyYW1lLW9uLXN0YWNrIHN0YW1waW5nIHNjb3BlLlxuICAgIGxldCBwZW5kaW5nSW52b2tlcnM6IEludm9rZXJTdGFtcFtdIHwgdW5kZWZpbmVkO1xuICAgIC8vIOKUgOKUgOKUgCBUcmVlLWRlcHRoIGd1YXJkIOKUgOKUgOKUgFxuICAgIC8vIFRoZSBpbmNyZW1lbnQgaXMgaW5zaWRlIGB0cnlgIHNvIGBmaW5hbGx5YCBhbHdheXMgZGVjcmVtZW50cyDigJQgbm9cbiAgICAvLyBmcmFnaWxlIGdhcCBiZXR3ZWVuIGNoZWNrIGFuZCB0cnkgZW50cnkuXG4gICAgdHJ5IHtcbiAgICAgIGlmICgrK3RoaXMuX2V4ZWN1dGVEZXB0aCA+IHRoaXMuX21heERlcHRoKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICBgRmxvd2NoYXJ0VHJhdmVyc2VyOiBtYXhpbXVtIHRyYXZlcnNhbCBkZXB0aCBleGNlZWRlZCAoJHt0aGlzLl9tYXhEZXB0aH0pLiBgICtcbiAgICAgICAgICAgICdEZXB0aCBjb3VudHMgTkVTVEVEIGRpc3BhdGNoIChmb3JrIGNoaWxkcmVuLCBkZWNpZGVyL3NlbGVjdG9yIGJyYW5jaGVzLCByZWN1cnNpdmUgY29tcG9zaXRpb24pIOKAlCAnICtcbiAgICAgICAgICAgICdsaW5lYXIgY2hhaW5zIGFuZCBsb29wIGl0ZXJhdGlvbnMgcnVuIGZsYXQgYW5kIGRvIG5vdCBjb25zdW1lIGl0LiAnICtcbiAgICAgICAgICAgIGBMYXN0IHN0YWdlOiAnJHtub2RlLm5hbWV9Jy4gYCArXG4gICAgICAgICAgICAnQ2hlY2sgZm9yIHVuYm91bmRlZCByZWN1cnNpdmUgY2hhcnQgY29tcG9zaXRpb24sIG9yIHJhaXNlIHRoZSBsaW1pdCB2aWEgUnVuT3B0aW9ucy5tYXhEZXB0aC4nLFxuICAgICAgICApO1xuICAgICAgfVxuXG4gICAgICBsZXQgY3VycmVudDogQ29udGludWF0aW9uSG9wPFRPdXQsIFRTY29wZT4gPSB7IFtDT05USU5VRV9IT1BdOiB0cnVlLCBub2RlLCBjb250ZXh0LCBicmFuY2hQYXRoIH07XG4gICAgICBmb3IgKDs7KSB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZU5vZGVTdGVwKGN1cnJlbnQubm9kZSwgY3VycmVudC5jb250ZXh0LCBicmVha0ZsYWcsIGN1cnJlbnQuYnJhbmNoUGF0aCk7XG4gICAgICAgIGlmICghaXNDb250aW51YXRpb25Ib3A8VE91dCwgVFNjb3BlPihyZXN1bHQpKSB7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfVxuICAgICAgICBpZiAocmVzdWx0Lmludm9rZXJTdGFtcCkgKHBlbmRpbmdJbnZva2VycyA/Pz0gW10pLnB1c2gocmVzdWx0Lmludm9rZXJTdGFtcCk7XG4gICAgICAgIGN1cnJlbnQgPSByZXN1bHQ7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZXJyb3I6IHVua25vd24pIHtcbiAgICAgIC8vIFJlcGxheSBpbnZva2VyIHN0YW1wcyBtb3N0LXJlY2VudC1maXJzdC4gYHNldEludm9rZXJgIGlzXG4gICAgICAvLyBmaXJzdC13cml0ZS13aW5zLCBzbyB0aGUgaW5uZXJtb3N0IGRpc3BhdGNoJ3Mgc3RhbXAgbGFuZHMg4oCUIGV4YWN0bHlcbiAgICAgIC8vIHRoZSBvbGQgYnViYmxlLXVwIG9yZGVyIHRocm91Z2ggbmVzdGVkIGNhdGNoIGZyYW1lcy5cbiAgICAgIGlmIChwZW5kaW5nSW52b2tlcnMgIT09IHVuZGVmaW5lZCAmJiBpc1BhdXNlU2lnbmFsKGVycm9yKSkge1xuICAgICAgICBmb3IgKGxldCBpID0gcGVuZGluZ0ludm9rZXJzLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgZXJyb3Iuc2V0SW52b2tlcihwZW5kaW5nSW52b2tlcnNbaV0uaW52b2tlclN0YWdlSWQsIHBlbmRpbmdJbnZva2Vyc1tpXS5jb250aW51YXRpb25TdGFnZUlkKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuX2V4ZWN1dGVEZXB0aC0tO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBCdWlsZCBhIGZsYXQgY29udGludWF0aW9uIGhvcCBmb3IgdGhlIGRyaXZlciBsb29wLiAqL1xuICBwcml2YXRlIGhvcChcbiAgICBub2RlOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPixcbiAgICBjb250ZXh0OiBTdGFnZUNvbnRleHQsXG4gICAgYnJhbmNoUGF0aDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICAgIGludm9rZXJTdGFtcD86IEludm9rZXJTdGFtcCxcbiAgKTogQ29udGludWF0aW9uSG9wPFRPdXQsIFRTY29wZT4ge1xuICAgIHJldHVybiB7IFtDT05USU5VRV9IT1BdOiB0cnVlLCBub2RlLCBjb250ZXh0LCBicmFuY2hQYXRoLCAuLi4oaW52b2tlclN0YW1wICYmIHsgaW52b2tlclN0YW1wIH0pIH07XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZSBPTkUgbm9kZSB0aHJvdWdoIGFsbCA3IHBoYXNlcyDigJQgdGhlIG9sZCByZWN1cnNpdmUgYGV4ZWN1dGVOb2RlYFxuICAgKiBib2R5OyBvbmx5IHRoZSB0YWlsIGNhbGxzIGJlY2FtZSBgQ29udGludWF0aW9uSG9wYCByZXR1cm5zLiBSZXR1cm5zIHRoZVxuICAgKiBub2RlJ3MgcmVzdWx0LCBvciBhIGhvcCBmb3IgdGhlIGRyaXZlciBsb29wIHRvIGZvbGxvdy5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgZXhlY3V0ZU5vZGVTdGVwKFxuICAgIG5vZGU6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+LFxuICAgIGNvbnRleHQ6IFN0YWdlQ29udGV4dCxcbiAgICBicmVha0ZsYWc6IEJyZWFrRmxhZyxcbiAgICBicmFuY2hQYXRoPzogc3RyaW5nLFxuICApOiBQcm9taXNlPGFueT4ge1xuICAgIC8vIEF0dGFjaCBidWlsZGVyIG1ldGFkYXRhIHRvIGNvbnRleHQgZm9yIHNuYXBzaG90IGVucmljaG1lbnQuXG4gICAgLy8gU3ViZmxvdyBtZXRhIHJlYWRzIGdvIHRocm91Z2ggdGhlIGR5bmFtaWMtcGF0Y2ggb3ZlcmxheSDigJQgYSBub2RlXG4gICAgLy8gcGF0Y2hlZCBieSBhIGR5bmFtaWMtc3ViZmxvdyByZXR1cm4gcmUtZW50ZXJzIGV4ZWN1dGVOb2RlIGFuZCBtdXN0XG4gICAgLy8gY2xhc3NpZnkgYXMgYSBzdWJmbG93IHdpdGhvdXQgdGhlIHNoYXJlZCBub2RlIGV2ZXIgYmVpbmcgbXV0YXRlZC5cbiAgICBpZiAobm9kZS5kZXNjcmlwdGlvbikgY29udGV4dC5kZXNjcmlwdGlvbiA9IG5vZGUuZGVzY3JpcHRpb247XG4gICAgY29uc3QgZWZmU3ViZmxvd0lkID0gdGhpcy5lZmZTdWJmbG93SWQobm9kZSk7XG4gICAgaWYgKHRoaXMuZWZmSXNTdWJmbG93Um9vdChub2RlKSAmJiBlZmZTdWJmbG93SWQpIGNvbnRleHQuc3ViZmxvd0lkID0gZWZmU3ViZmxvd0lkO1xuXG4gICAgLy8gQXNzaWduIHJ1bnRpbWVTdGFnZUlkIEJFRk9SRSB0cmF2ZXJzYWxDb250ZXh0IGNyZWF0aW9uIOKAlCBlbnN1cmVzIHNjb3BlIGV2ZW50c1xuICAgIC8vIChidWZmZXJlZCBieSBydW50aW1lU3RhZ2VJZCkgYW5kIGZsb3cgZXZlbnRzIChmbHVzaGVkIGJ5IHRyYXZlcnNhbENvbnRleHQucnVudGltZVN0YWdlSWQpXG4gICAgLy8gdXNlIHRoZSBzYW1lIHZhbHVlLiBNdXN0IGhhcHBlbiBiZWZvcmUgZXhlY3V0ZVN0YWdlIEFORCBiZWZvcmUgdHJhdmVyc2FsQ29udGV4dC5cbiAgICBjb25zdCBpZHggPSB0aGlzLl9leGVjdXRpb25Db3VudGVyLnZhbHVlKys7XG4gICAgY29udGV4dC5ydW50aW1lU3RhZ2VJZCA9IGJ1aWxkUnVudGltZVN0YWdlSWQobm9kZS5pZCwgaWR4KTtcblxuICAgIC8vIEJ1aWxkIHRyYXZlcnNhbCBjb250ZXh0IGZvciByZWNvcmRlciBldmVudHMg4oCUIGNyZWF0ZWQgb25jZSBwZXIgc3RhZ2UsIHNoYXJlZCBieSBhbGwgZXZlbnRzXG4gICAgY29uc3QgdHJhdmVyc2FsQ29udGV4dDogVHJhdmVyc2FsQ29udGV4dCA9IHtcbiAgICAgIHJ1bklkOiB0aGlzLnJ1bklkLFxuICAgICAgc3RhZ2VJZDogbm9kZS5pZCA/PyBjb250ZXh0LnN0YWdlSWQsXG4gICAgICBydW50aW1lU3RhZ2VJZDogY29udGV4dC5ydW50aW1lU3RhZ2VJZCxcbiAgICAgIHN0YWdlTmFtZTogbm9kZS5uYW1lLFxuICAgICAgcGFyZW50U3RhZ2VJZDogY29udGV4dC5wYXJlbnQ/LnN0YWdlSWQsXG4gICAgICBzdWJmbG93SWQ6IGNvbnRleHQuc3ViZmxvd0lkID8/IHRoaXMucGFyZW50U3ViZmxvd0lkLFxuICAgICAgc3ViZmxvd1BhdGg6IGJyYW5jaFBhdGggfHwgdW5kZWZpbmVkLFxuICAgICAgZGVwdGg6IHRoaXMuY29tcHV0ZUNvbnRleHREZXB0aChjb250ZXh0KSxcbiAgICB9O1xuXG4gICAgLy8g4pSA4pSA4pSAIFBoYXNlIDBhOiBMQVpZIFJFU09MVkUg4oCUIGRlZmVycmVkIHN1YmZsb3cgcmVzb2x1dGlvbiDilIDilIDilIBcbiAgICAvLyBHdWFyZCB1c2VzIHRoZSBwZXItdHJhdmVyc2VyIHJlc29sdmVkTGF6eVN1YmZsb3dzIHNldCAobm90IHRoZSBzaGFyZWQgbm9kZSkgc29cbiAgICAvLyBjb25jdXJyZW50IHRyYXZlcnNlcnMgZG8gbm90IHJhY2Ugb24gbm9kZS5zdWJmbG93UmVzb2x2ZXIgb3IgY2xlYXIgaXQgZm9yIGVhY2ggb3RoZXIuXG4gICAgaWYgKG5vZGUuaXNTdWJmbG93Um9vdCAmJiBub2RlLnN1YmZsb3dSZXNvbHZlciAmJiAhdGhpcy5yZXNvbHZlZExhenlTdWJmbG93cy5oYXMobm9kZS5zdWJmbG93SWQhKSkge1xuICAgICAgY29uc3QgcmVzb2x2ZWQgPSBub2RlLnN1YmZsb3dSZXNvbHZlcigpO1xuICAgICAgY29uc3QgcHJlZml4ZWRSb290ID0gdGhpcy5wcmVmaXhOb2RlVHJlZShyZXNvbHZlZC5yb290IGFzIFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+LCBub2RlLnN1YmZsb3dJZCEpO1xuXG4gICAgICAvLyBSZWdpc3RlciB0aGUgcmVzb2x2ZWQgc3ViZmxvdyAoc2FtZSBwYXRoIGFzIGVhZ2VyIHJlZ2lzdHJhdGlvbilcbiAgICAgIHRoaXMuc3ViZmxvd3Nbbm9kZS5zdWJmbG93SWQhXSA9IHsgcm9vdDogcHJlZml4ZWRSb290IH07XG5cbiAgICAgIC8vIE1lcmdlIHN0YWdlTWFwIGVudHJpZXNcbiAgICAgIGZvciAoY29uc3QgW2tleSwgZm5dIG9mIHJlc29sdmVkLnN0YWdlTWFwKSB7XG4gICAgICAgIGNvbnN0IHByZWZpeGVkS2V5ID0gYCR7bm9kZS5zdWJmbG93SWR9LyR7a2V5fWA7XG4gICAgICAgIGlmICghdGhpcy5zdGFnZU1hcC5oYXMocHJlZml4ZWRLZXkpKSB7XG4gICAgICAgICAgdGhpcy5zdGFnZU1hcC5zZXQocHJlZml4ZWRLZXksIGZuIGFzIFN0YWdlRnVuY3Rpb248VE91dCwgVFNjb3BlPik7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gTWVyZ2UgbmVzdGVkIHN1YmZsb3dzXG4gICAgICBpZiAocmVzb2x2ZWQuc3ViZmxvd3MpIHtcbiAgICAgICAgZm9yIChjb25zdCBba2V5LCBkZWZdIG9mIE9iamVjdC5lbnRyaWVzKHJlc29sdmVkLnN1YmZsb3dzKSkge1xuICAgICAgICAgIGNvbnN0IHByZWZpeGVkS2V5ID0gYCR7bm9kZS5zdWJmbG93SWR9LyR7a2V5fWA7XG4gICAgICAgICAgaWYgKCF0aGlzLnN1YmZsb3dzW3ByZWZpeGVkS2V5XSkge1xuICAgICAgICAgICAgdGhpcy5zdWJmbG93c1twcmVmaXhlZEtleV0gPSBkZWYgYXMgeyByb290OiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiB9O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBVcGRhdGUgcnVudGltZSBzdHJ1Y3R1cmUgd2l0aCB0aGUgbm93LXJlc29sdmVkIHNwZWNcbiAgICAgIHRoaXMuc3RydWN0dXJlTWFuYWdlci51cGRhdGVEeW5hbWljU3ViZmxvdyhcbiAgICAgICAgbm9kZS5pZCxcbiAgICAgICAgbm9kZS5zdWJmbG93SWQhLFxuICAgICAgICBub2RlLnN1YmZsb3dOYW1lLFxuICAgICAgICByZXNvbHZlZC5idWlsZFRpbWVTdHJ1Y3R1cmUsXG4gICAgICApO1xuXG4gICAgICAvLyBNYXJrIGFzIHJlc29sdmVkIGZvciBUSElTIHRyYXZlcnNlciDigJQgcGVyLXRyYXZlcnNlciBzZXQgcHJldmVudHMgcmUtZW50cnlcbiAgICAgIC8vIHdpdGhvdXQgbXV0YXRpbmcgdGhlIHNoYXJlZCBTdGFnZU5vZGUgZ3JhcGggKHdoaWNoIHdvdWxkIHJhY2UgY29uY3VycmVudCB0cmF2ZXJzZXJzKS5cbiAgICAgIHRoaXMucmVzb2x2ZWRMYXp5U3ViZmxvd3MuYWRkKG5vZGUuc3ViZmxvd0lkISk7XG4gICAgfVxuXG4gICAgLy8g4pSA4pSA4pSAIFBoYXNlIDA6IENMQVNTSUZZIOKAlCBzdWJmbG93IGRldGVjdGlvbiDilIDilIDilIBcbiAgICBpZiAodGhpcy5lZmZJc1N1YmZsb3dSb290KG5vZGUpICYmIGVmZlN1YmZsb3dJZCkge1xuICAgICAgLy8gSGFuZCBoZWxwZXJzIHRoZSBFRkZFQ1RJVkUgbm9kZSB2aWV3IChidWlsdCBmaWVsZHMgKyBkeW5hbWljIHBhdGNoKVxuICAgICAgLy8gc28gU3ViZmxvd0V4ZWN1dG9yL05vZGVSZXNvbHZlciBuZXZlciByZWFkIHN0YWxlIGJ1aWx0IGZpZWxkcy5cbiAgICAgIGNvbnN0IG1vdW50Tm9kZSA9IHRoaXMuZWZmTm9kZShub2RlKTtcbiAgICAgIGNvbnN0IHJlc29sdmVkTm9kZSA9IHRoaXMubm9kZVJlc29sdmVyLnJlc29sdmVTdWJmbG93UmVmZXJlbmNlKG1vdW50Tm9kZSk7XG5cbiAgICAgIGNvbnN0IHN1YmZsb3dPdXRwdXQgPSBhd2FpdCB0aGlzLnN1YmZsb3dFeGVjdXRvci5leGVjdXRlU3ViZmxvdyhcbiAgICAgICAgcmVzb2x2ZWROb2RlLFxuICAgICAgICBjb250ZXh0LFxuICAgICAgICBicmVha0ZsYWcsXG4gICAgICAgIGJyYW5jaFBhdGgsXG4gICAgICAgIHRoaXMuc3ViZmxvd1Jlc3VsdHMsXG4gICAgICAgIHRyYXZlcnNhbENvbnRleHQsXG4gICAgICApO1xuXG4gICAgICBjb25zdCBpc1JlZmVyZW5jZUJhc2VkU3ViZmxvdyA9IHJlc29sdmVkTm9kZSAhPT0gbW91bnROb2RlO1xuICAgICAgY29uc3QgaGFzQ2hpbGRyZW4gPSBCb29sZWFuKG1vdW50Tm9kZS5jaGlsZHJlbiAmJiBtb3VudE5vZGUuY2hpbGRyZW4ubGVuZ3RoID4gMCk7XG4gICAgICBjb25zdCBzaG91bGRFeGVjdXRlQ29udGludWF0aW9uID0gaXNSZWZlcmVuY2VCYXNlZFN1YmZsb3cgfHwgaGFzQ2hpbGRyZW47XG5cbiAgICAgIC8vIOKUgOKUgOKUgCBCcmVhay1mbGFnIGNoZWNrIEFGVEVSIHN1YmZsb3cgcmV0dXJucyDilIDilIDilIBcbiAgICAgIC8vIElmIHRoZSBzdWJmbG93IHdhcyBtb3VudGVkIHdpdGggYHByb3BhZ2F0ZUJyZWFrOiB0cnVlYCBhbmQgYnJva2VcbiAgICAgIC8vIGludGVybmFsbHksIGBTdWJmbG93RXhlY3V0b3JgIGhhcyBhbHJlYWR5IGZsaXBwZWQgb3VyIGJyZWFrRmxhZy5cbiAgICAgIC8vIFN0b3AgdGhlIG91dGVyIHRyYXZlcnNhbCBoZXJlIOKAlCBkbyBub3QgcnVuIHRoZSBuZXh0IGxpbmVhciBzdGFnZS5cbiAgICAgIGlmIChicmVha0ZsYWcuc2hvdWxkQnJlYWspIHtcbiAgICAgICAgcmV0dXJuIHN1YmZsb3dPdXRwdXQ7XG4gICAgICB9XG5cbiAgICAgIGlmIChub2RlLm5leHQgJiYgc2hvdWxkRXhlY3V0ZUNvbnRpbnVhdGlvbikge1xuICAgICAgICBjb25zdCBuZXh0Q3R4ID0gY29udGV4dC5jcmVhdGVOZXh0KGJyYW5jaFBhdGggYXMgc3RyaW5nLCBub2RlLm5leHQubmFtZSwgbm9kZS5uZXh0LmlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaG9wKG5vZGUubmV4dCwgbmV4dEN0eCwgYnJhbmNoUGF0aCk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBzdWJmbG93T3V0cHV0O1xuICAgIH1cblxuICAgIGNvbnN0IHN0YWdlRnVuYyA9IHRoaXMuZ2V0U3RhZ2VGbihub2RlKTtcbiAgICBjb25zdCBoYXNTdGFnZUZ1bmN0aW9uID0gQm9vbGVhbihzdGFnZUZ1bmMpO1xuICAgIGNvbnN0IGlzU2NvcGVCYXNlZERlY2lkZXIgPSBCb29sZWFuKG5vZGUuZGVjaWRlckZuKTtcbiAgICBjb25zdCBpc1Njb3BlQmFzZWRTZWxlY3RvciA9IEJvb2xlYW4obm9kZS5zZWxlY3RvckZuKTtcbiAgICBjb25zdCBpc0RlY2lkZXJOb2RlID0gaXNTY29wZUJhc2VkRGVjaWRlcjtcbiAgICBjb25zdCBoYXNDaGlsZHJlbiA9IEJvb2xlYW4odGhpcy5lZmZDaGlsZHJlbihub2RlKT8ubGVuZ3RoKTtcbiAgICAvLyBgbmV4dGAgaXMgbmV2ZXIgb3ZlcmxhaWQg4oCUIGEgZHluYW1pYyBuZXh0IGFwcGxpZXMgb25seSB0byB0aGUgdmlzaXRcbiAgICAvLyB0aGF0IHByb2R1Y2VkIGl0IChoYW5kbGVkIHZpYSB0aGUgYGR5bmFtaWNOZXh0YCBsb2NhbCBiZWxvdyksIHNvIHRoZVxuICAgIC8vIGJ1aWx0IGNoYXJ0J3MgbmV4dCBpcyBhbHdheXMgdGhlIGNvcnJlY3QgY29udGludWF0aW9uIGhlcmUuXG4gICAgY29uc3QgaGFzTmV4dCA9IEJvb2xlYW4obm9kZS5uZXh0KTtcbiAgICBjb25zdCBvcmlnaW5hbE5leHQgPSBub2RlLm5leHQ7XG5cbiAgICAvLyDilIDilIDilIAgUGhhc2UgMTogVkFMSURBVEUg4oCUIG5vZGUgaW52YXJpYW50cyDilIDilIDilIBcbiAgICBpZiAoIWhhc1N0YWdlRnVuY3Rpb24gJiYgIWlzRGVjaWRlck5vZGUgJiYgIWlzU2NvcGVCYXNlZFNlbGVjdG9yICYmICFoYXNDaGlsZHJlbikge1xuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gYE5vZGUgJyR7bm9kZS5uYW1lfScgbXVzdCBkZWZpbmU6IGVtYmVkZGVkIGZuIE9SIGEgc3RhZ2VNYXAgZW50cnkgT1IgaGF2ZSBjaGlsZHJlbi9kZWNpZGVyYDtcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGBFcnJvciBpbiBwaXBlbGluZSAoJHticmFuY2hQYXRofSkgc3RhZ2UgWyR7bm9kZS5uYW1lfV06YCwgeyBlcnJvcjogZXJyb3JNZXNzYWdlIH0pO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgfVxuICAgIGlmIChpc0RlY2lkZXJOb2RlICYmICFoYXNDaGlsZHJlbikge1xuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gJ0RlY2lkZXIgbm9kZSBuZWVkcyB0byBoYXZlIGNoaWxkcmVuIHRvIGV4ZWN1dGUnO1xuICAgICAgdGhpcy5sb2dnZXIuZXJyb3IoYEVycm9yIGluIHBpcGVsaW5lICgke2JyYW5jaFBhdGh9KSBzdGFnZSBbJHtub2RlLm5hbWV9XTpgLCB7IGVycm9yOiBlcnJvck1lc3NhZ2UgfSk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgICB9XG4gICAgaWYgKGlzU2NvcGVCYXNlZFNlbGVjdG9yICYmICFoYXNDaGlsZHJlbikge1xuICAgICAgY29uc3QgZXJyb3JNZXNzYWdlID0gJ1NlbGVjdG9yIG5vZGUgbmVlZHMgdG8gaGF2ZSBjaGlsZHJlbiB0byBleGVjdXRlJztcbiAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGBFcnJvciBpbiBwaXBlbGluZSAoJHticmFuY2hQYXRofSkgc3RhZ2UgWyR7bm9kZS5uYW1lfV06YCwgeyBlcnJvcjogZXJyb3JNZXNzYWdlIH0pO1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGVycm9yTWVzc2FnZSk7XG4gICAgfVxuXG4gICAgLy8gUm9sZSBtYXJrZXJzIGZvciBkZWJ1ZyBwYW5lbHNcbiAgICBpZiAoIWhhc1N0YWdlRnVuY3Rpb24pIHtcbiAgICAgIGlmIChpc0RlY2lkZXJOb2RlKSBjb250ZXh0LnNldEFzRGVjaWRlcigpO1xuICAgICAgZWxzZSBpZiAoaGFzQ2hpbGRyZW4pIGNvbnRleHQuc2V0QXNGb3JrKCk7XG4gICAgfVxuXG4gICAgLy8gQnJlYWsgaGFuZGxlciB3aXJlZCB0byB0aGUgc2NvcGUuIENhcHR1cmVzIHRoZSBvcHRpb25hbCByZWFzb25cbiAgICAvLyBwYXNzZWQgdmlhIGBzY29wZS4kYnJlYWsocmVhc29uKWAgYW5kIHBhcmtzIGl0IG9uIHRoZSBicmVha0ZsYWcgc29cbiAgICAvLyBkb3duc3RyZWFtIGNvZGUgKEZsb3dSZWNvcmRlci5vbkJyZWFrLCBzdWJmbG93IHByb3BhZ2F0aW9uKSBjYW5cbiAgICAvLyBzdXJmYWNlIGl0LiBBIHNlY29uZCAkYnJlYWsgY2FsbCBpbiB0aGUgc2FtZSBzdGFnZSBrZWVwcyB0aGUgRklSU1RcbiAgICAvLyByZWFzb24g4oCUIGZpcnN0LWJyZWFrLXdpbnMg4oCUIG1hdGNoaW5nIHRoZSBcImV4ZWN1dGlvbiBzdG9wcGVkXCIgc3RvcnkuXG4gICAgY29uc3QgYnJlYWtGbiA9IChyZWFzb24/OiBzdHJpbmcpID0+IHtcbiAgICAgIGJyZWFrRmxhZy5zaG91bGRCcmVhayA9IHRydWU7XG4gICAgICBpZiAocmVhc29uICE9PSB1bmRlZmluZWQgJiYgYnJlYWtGbGFnLnJlYXNvbiA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIGJyZWFrRmxhZy5yZWFzb24gPSByZWFzb247XG4gICAgICB9XG4gICAgfTtcblxuICAgIC8vIOKUgOKUgOKUgCBQaGFzZSAyYTogU0VMRUNUT1Ig4oCUIHNjb3BlLWJhc2VkIG11bHRpLWNob2ljZSDilIDilIDilIBcbiAgICBpZiAoaXNTY29wZUJhc2VkU2VsZWN0b3IpIHtcbiAgICAgIGNvbnN0IHNlbGVjdG9yUmVzdWx0ID0gYXdhaXQgdGhpcy5zZWxlY3RvckhhbmRsZXIuaGFuZGxlU2NvcGVCYXNlZChcbiAgICAgICAgbm9kZSxcbiAgICAgICAgc3RhZ2VGdW5jISxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAgYnJlYWtGbGFnLFxuICAgICAgICBicmFuY2hQYXRoLFxuICAgICAgICB0aGlzLmV4ZWN1dGVTdGFnZS5iaW5kKHRoaXMpLFxuICAgICAgICB0aGlzLmV4ZWN1dGVOb2RlLmJpbmQodGhpcyksXG4gICAgICAgIHRyYXZlcnNhbENvbnRleHQsXG4gICAgICApO1xuXG4gICAgICBpZiAoaGFzTmV4dCkge1xuICAgICAgICBjb25zdCBuZXh0Q3R4ID0gY29udGV4dC5jcmVhdGVOZXh0KGJyYW5jaFBhdGggYXMgc3RyaW5nLCBub2RlLm5leHQhLm5hbWUsIG5vZGUubmV4dCEuaWQpO1xuICAgICAgICByZXR1cm4gdGhpcy5ob3Aobm9kZS5uZXh0ISwgbmV4dEN0eCwgYnJhbmNoUGF0aCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gc2VsZWN0b3JSZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8g4pSA4pSA4pSAIFBoYXNlIDJiOiBERUNJREVSIOKAlCBzY29wZS1iYXNlZCBzaW5nbGUtY2hvaWNlIGNvbmRpdGlvbmFsIGJyYW5jaCDilIDilIDilIBcbiAgICBpZiAoaXNEZWNpZGVyTm9kZSkge1xuICAgICAgY29uc3QgZGlzcGF0Y2ggPSBhd2FpdCB0aGlzLmRlY2lkZXJIYW5kbGVyLnByZXBhcmVEaXNwYXRjaChcbiAgICAgICAgbm9kZSxcbiAgICAgICAgc3RhZ2VGdW5jISxcbiAgICAgICAgY29udGV4dCxcbiAgICAgICAgYnJlYWtGbGFnLFxuICAgICAgICBicmFuY2hQYXRoLFxuICAgICAgICB0aGlzLmV4ZWN1dGVTdGFnZS5iaW5kKHRoaXMpLFxuICAgICAgICB0cmF2ZXJzYWxDb250ZXh0LFxuICAgICAgKTtcblxuICAgICAgLy8gTm8gZGVjaWRlci1sZXZlbCBjb250aW51YXRpb24g4oaSIHRoZSBicmFuY2ggZGlzcGF0Y2ggaXMgYSB0YWlsXG4gICAgICAvLyBjYWxsLiBIYW5kIGl0IHRvIHRoZSBkcml2ZXIgYXMgYSBmbGF0IGhvcCBzbyBsb29wLWhlYXZ5IGRlY2lkZXJcbiAgICAgIC8vIGNoYXJ0cyAoZS5nLiBhZ2VudCBSZUFjdCBsb29wcyB3aXRoIGJyYW5jaC1zb3VyY2VkIGBsb29wVG9gKSBzdGF5XG4gICAgICAvLyBmbGF0LXN0YWNrZWQuIFRoZSBpbnZva2VyIHN0YW1wIHByZXNlcnZlcyBQYXVzZVNpZ25hbCBzZW1hbnRpY3Mg4oCUXG4gICAgICAvLyB0aGUgZGVjaWRlciBpcyB0aGUgaW52b2tlciBvZiB3aGF0ZXZlciBwYXVzZXMgaW4gdGhlIGNoYWluLlxuICAgICAgaWYgKCFoYXNOZXh0ICYmIGRpc3BhdGNoLmtpbmQgPT09ICdkaXNwYXRjaCcpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuaG9wKGRpc3BhdGNoLmNob3NlbiwgZGlzcGF0Y2guYnJhbmNoQ29udGV4dCwgYnJhbmNoUGF0aCwge1xuICAgICAgICAgIGludm9rZXJTdGFnZUlkOiBub2RlLmlkISxcbiAgICAgICAgICBjb250aW51YXRpb25TdGFnZUlkOiBub2RlLm5leHQ/LmlkLFxuICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gRGVjaWRlciBXSVRIIGl0cyBvd24gbmV4dDogdGhlIGJyYW5jaCBjaGFpbiBtdXN0IGNvbXBsZXRlIEJFRk9SRVxuICAgICAgLy8gdGhlIGRlY2lkZXIncyBjb250aW51YXRpb24gcnVucyDigJQgdHJ1ZSB0cmVlIG5lc3RpbmcsIGtlcHRcbiAgICAgIC8vIHJlY3Vyc2l2ZSAoYSBuZXN0ZWQgZHJpdmVyKS4gTWlycm9ycyBoYW5kbGVTY29wZUJhc2VkIGV4YWN0bHksXG4gICAgICAvLyBpbmNsdWRpbmcgdGhlIFBhdXNlU2lnbmFsIGludm9rZXIgc3RhbXAgb24gYnViYmxlLXVwLlxuICAgICAgbGV0IGRlY2lkZXJSZXN1bHQ6IGFueTtcbiAgICAgIGlmIChkaXNwYXRjaC5raW5kID09PSAnYnJlYWsnKSB7XG4gICAgICAgIGRlY2lkZXJSZXN1bHQgPSBkaXNwYXRjaC5icmFuY2hJZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgZGVjaWRlclJlc3VsdCA9IGF3YWl0IHRoaXMuZXhlY3V0ZU5vZGUoZGlzcGF0Y2guY2hvc2VuLCBkaXNwYXRjaC5icmFuY2hDb250ZXh0LCBicmVha0ZsYWcsIGJyYW5jaFBhdGgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcjogdW5rbm93bikge1xuICAgICAgICAgIGlmIChpc1BhdXNlU2lnbmFsKGVycm9yKSkge1xuICAgICAgICAgICAgZXJyb3Iuc2V0SW52b2tlcihub2RlLmlkISwgbm9kZS5uZXh0Py5pZCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIEFmdGVyIGJyYW5jaCBleGVjdXRpb24sIGZvbGxvdyBkZWNpZGVyJ3Mgb3duIG5leHQgKGUuZy4sIGxvb3BUbyB0YXJnZXQpXG4gICAgICBpZiAoaGFzTmV4dCAmJiAhYnJlYWtGbGFnLnNob3VsZEJyZWFrKSB7XG4gICAgICAgIGNvbnN0IG5leHROb2RlID0gb3JpZ2luYWxOZXh0ITtcbiAgICAgICAgLy8gVXNlIHRoZSBpc0xvb3BSZWYgZmxhZyBzZXQgYnkgbG9vcFRvKCkg4oCUIGRvIG5vdCByZWx5IG9uIHN0YWdlTWFwIGFic2VuY2UsXG4gICAgICAgIC8vIHNpbmNlIGlkLWtleWVkIHN0YWdlTWFwcyB3b3VsZCBvdGhlcndpc2UgY2F1c2UgbG9vcCB0YXJnZXRzIHRvIGJlIGV4ZWN1dGVkIGRpcmVjdGx5LlxuICAgICAgICBjb25zdCBpc0xvb3BSZWYgPVxuICAgICAgICAgIG5leHROb2RlLmlzTG9vcFJlZiA9PT0gdHJ1ZSB8fFxuICAgICAgICAgICghdGhpcy5nZXRTdGFnZUZuKG5leHROb2RlKSAmJlxuICAgICAgICAgICAgIXRoaXMuZWZmQ2hpbGRyZW4obmV4dE5vZGUpPy5sZW5ndGggJiZcbiAgICAgICAgICAgICFuZXh0Tm9kZS5kZWNpZGVyRm4gJiZcbiAgICAgICAgICAgICFuZXh0Tm9kZS5zZWxlY3RvckZuICYmXG4gICAgICAgICAgICAhdGhpcy5lZmZJc1N1YmZsb3dSb290KG5leHROb2RlKSk7XG5cbiAgICAgICAgaWYgKGlzTG9vcFJlZikge1xuICAgICAgICAgIGNvbnN0IHRhcmdldCA9IHRoaXMuY29udGludWF0aW9uUmVzb2x2ZXIucmVzb2x2ZVRhcmdldChuZXh0Tm9kZSwgbm9kZSwgY29udGV4dCwgYnJhbmNoUGF0aCk7XG4gICAgICAgICAgcmV0dXJuIHRoaXMuaG9wKHRhcmdldC5ub2RlLCB0YXJnZXQuY29udGV4dCwgYnJhbmNoUGF0aCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvci5vbk5leHQobm9kZS5uYW1lLCBuZXh0Tm9kZS5uYW1lLCBuZXh0Tm9kZS5kZXNjcmlwdGlvbiwgdHJhdmVyc2FsQ29udGV4dCk7XG4gICAgICAgIGNvbnN0IG5leHRDdHggPSBjb250ZXh0LmNyZWF0ZU5leHQoYnJhbmNoUGF0aCBhcyBzdHJpbmcsIG5leHROb2RlLm5hbWUsIG5leHROb2RlLmlkKTtcbiAgICAgICAgcmV0dXJuIHRoaXMuaG9wKG5leHROb2RlLCBuZXh0Q3R4LCBicmFuY2hQYXRoKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGRlY2lkZXJSZXN1bHQ7XG4gICAgfVxuXG4gICAgLy8g4pSA4pSA4pSAIEFib3J0IGNoZWNrIOKAlCBjb29wZXJhdGl2ZSBjYW5jZWxsYXRpb24g4pSA4pSA4pSAXG4gICAgaWYgKHRoaXMuc2lnbmFsPy5hYm9ydGVkKSB7XG4gICAgICBjb25zdCByZWFzb24gPVxuICAgICAgICB0aGlzLnNpZ25hbC5yZWFzb24gaW5zdGFuY2VvZiBFcnJvciA/IHRoaXMuc2lnbmFsLnJlYXNvbiA6IG5ldyBFcnJvcih0aGlzLnNpZ25hbC5yZWFzb24gPz8gJ0Fib3J0ZWQnKTtcbiAgICAgIHRocm93IHJlYXNvbjtcbiAgICB9XG5cbiAgICAvLyDilIDilIDilIAgUGhhc2UgMzogRVhFQ1VURSDigJQgcnVuIHN0YWdlIGZ1bmN0aW9uIOKUgOKUgOKUgFxuICAgIGxldCBzdGFnZU91dHB1dDogVE91dCB8IHVuZGVmaW5lZDtcbiAgICBsZXQgZHluYW1pY05leHQ6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+IHwgdW5kZWZpbmVkO1xuXG4gICAgaWYgKHN0YWdlRnVuYykge1xuICAgICAgdHJ5IHtcbiAgICAgICAgc3RhZ2VPdXRwdXQgPSBhd2FpdCB0aGlzLmV4ZWN1dGVTdGFnZShub2RlLCBzdGFnZUZ1bmMsIGNvbnRleHQsIGJyZWFrRm4pO1xuICAgICAgfSBjYXRjaCAoZXJyb3I6IGFueSkge1xuICAgICAgICAvLyBQYXVzZVNpZ25hbCBpcyBleHBlY3RlZCBjb250cm9sIGZsb3csIG5vdCBhbiBlcnJvciDigJQgZmlyZSBuYXJyYXRpdmUsIGNvbW1pdCwgcmUtdGhyb3cuXG4gICAgICAgIGlmIChpc1BhdXNlU2lnbmFsKGVycm9yKSkge1xuICAgICAgICAgIGNvbnRleHQuY29tbWl0KCk7XG4gICAgICAgICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3Iub25QYXVzZShub2RlLm5hbWUsIG5vZGUuaWQsIGVycm9yLnBhdXNlRGF0YSwgZXJyb3Iuc3ViZmxvd1BhdGgsIHRyYXZlcnNhbENvbnRleHQpO1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGNvbnRleHQuY29tbWl0KCk7XG4gICAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yLm9uRXJyb3Iobm9kZS5uYW1lLCBlcnJvci50b1N0cmluZygpLCBlcnJvciwgdHJhdmVyc2FsQ29udGV4dCk7XG4gICAgICAgIHRoaXMubG9nZ2VyLmVycm9yKGBFcnJvciBpbiBwaXBlbGluZSAoJHticmFuY2hQYXRofSkgc3RhZ2UgWyR7bm9kZS5uYW1lfV06YCwgeyBlcnJvciB9KTtcbiAgICAgICAgY29udGV4dC5hZGRFcnJvcignc3RhZ2VFeGVjdXRpb25FcnJvcicsIGVycm9yLnRvU3RyaW5nKCkpO1xuICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgIH1cbiAgICAgIGNvbnRleHQuY29tbWl0KCk7XG4gICAgICB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvci5vblN0YWdlRXhlY3V0ZWQobm9kZS5uYW1lLCBub2RlLmRlc2NyaXB0aW9uLCB0cmF2ZXJzYWxDb250ZXh0LCAnbGluZWFyJyk7XG5cbiAgICAgIGlmIChicmVha0ZsYWcuc2hvdWxkQnJlYWspIHtcbiAgICAgICAgLy8gRm9yd2FyZCB0aGUgb3B0aW9uYWwgcmVhc29uIGNhcHR1cmVkIG9uIGJyZWFrRmxhZyDigJQgc2V0IGJ5IHRoZVxuICAgICAgICAvLyBzdGFnZSdzICRicmVhayhyZWFzb24pIGNhbGwgT1IgYnkgYSBzdWJmbG93J3MgcHJvcGFnYXRlQnJlYWsuXG4gICAgICAgIHRoaXMubmFycmF0aXZlR2VuZXJhdG9yLm9uQnJlYWsobm9kZS5uYW1lLCB0cmF2ZXJzYWxDb250ZXh0LCBicmVha0ZsYWcucmVhc29uKTtcbiAgICAgICAgcmV0dXJuIHN0YWdlT3V0cHV0O1xuICAgICAgfVxuXG4gICAgICAvLyDilIDilIDilIAgUGhhc2UgNDogRFlOQU1JQyDigJQgU3RhZ2VOb2RlIHJldHVybiBkZXRlY3Rpb24g4pSA4pSA4pSAXG4gICAgICBpZiAoc3RhZ2VPdXRwdXQgJiYgdHlwZW9mIHN0YWdlT3V0cHV0ID09PSAnb2JqZWN0JyAmJiBpc1N0YWdlTm9kZVJldHVybihzdGFnZU91dHB1dCkpIHtcbiAgICAgICAgY29uc3QgZHluYW1pY05vZGUgPSBzdGFnZU91dHB1dCBhcyBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPjtcbiAgICAgICAgY29udGV4dC5hZGRMb2coJ2lzRHluYW1pYycsIHRydWUpO1xuICAgICAgICBjb250ZXh0LmFkZExvZygnZHluYW1pY1BhdHRlcm4nLCAnU3RhZ2VOb2RlUmV0dXJuJyk7XG5cbiAgICAgICAgLy8gRHluYW1pYyBzdWJmbG93IGF1dG8tcmVnaXN0cmF0aW9uLiBUaGUgc3ViZmxvdyBtZXRhIGxhbmRzIGluIHRoZVxuICAgICAgICAvLyB0cmF2ZXJzZXItbG9jYWwgb3ZlcmxheSAoTk9UIG9uIHRoZSBzaGFyZWQgbm9kZSk7IHRoZSBpbW1lZGlhdGVcbiAgICAgICAgLy8gZXhlY3V0ZU5vZGUgcmUtZW50cnkgc2VlcyBpdCB0aHJvdWdoIHRoZSBlZmYqIGFjY2Vzc29ycyBhbmRcbiAgICAgICAgLy8gY2xhc3NpZmllcyB0aGUgbm9kZSBhcyBhIHN1YmZsb3cgbW91bnQgaW4gUGhhc2UgMC5cbiAgICAgICAgaWYgKGR5bmFtaWNOb2RlLmlzU3ViZmxvd1Jvb3QgJiYgZHluYW1pY05vZGUuc3ViZmxvd0RlZiAmJiBkeW5hbWljTm9kZS5zdWJmbG93SWQpIHtcbiAgICAgICAgICBjb250ZXh0LmFkZExvZygnZHluYW1pY1BhdHRlcm4nLCAnZHluYW1pY1N1YmZsb3cnKTtcbiAgICAgICAgICBjb250ZXh0LmFkZExvZygnZHluYW1pY1N1YmZsb3dJZCcsIGR5bmFtaWNOb2RlLnN1YmZsb3dJZCk7XG5cbiAgICAgICAgICB0aGlzLmF1dG9SZWdpc3RlclN1YmZsb3dEZWYoZHluYW1pY05vZGUuc3ViZmxvd0lkLCBkeW5hbWljTm9kZS5zdWJmbG93RGVmLCBub2RlLmlkKTtcblxuICAgICAgICAgIHRoaXMuZ2V0T3JDcmVhdGVQYXRjaChub2RlKS5zdWJmbG93TWV0YSA9IHtcbiAgICAgICAgICAgIGlzU3ViZmxvd1Jvb3Q6IHRydWUsXG4gICAgICAgICAgICBzdWJmbG93SWQ6IGR5bmFtaWNOb2RlLnN1YmZsb3dJZCxcbiAgICAgICAgICAgIHN1YmZsb3dOYW1lOiBkeW5hbWljTm9kZS5zdWJmbG93TmFtZSxcbiAgICAgICAgICAgIHN1YmZsb3dNb3VudE9wdGlvbnM6IGR5bmFtaWNOb2RlLnN1YmZsb3dNb3VudE9wdGlvbnMsXG4gICAgICAgICAgfTtcblxuICAgICAgICAgIHRoaXMuc3RydWN0dXJlTWFuYWdlci51cGRhdGVEeW5hbWljU3ViZmxvdyhcbiAgICAgICAgICAgIG5vZGUuaWQsXG4gICAgICAgICAgICBkeW5hbWljTm9kZS5zdWJmbG93SWQhLFxuICAgICAgICAgICAgZHluYW1pY05vZGUuc3ViZmxvd05hbWUsXG4gICAgICAgICAgICBkeW5hbWljTm9kZS5zdWJmbG93RGVmPy5idWlsZFRpbWVTdHJ1Y3R1cmUsXG4gICAgICAgICAgKTtcblxuICAgICAgICAgIC8vIFJlLWVudGVyIFRISVMgbm9kZSAoc2FtZSBjb250ZXh0KTogdGhlIG92ZXJsYXkgcGF0Y2ggbWFrZXMgdGhlXG4gICAgICAgICAgLy8gbmV4dCBzdGVwIGNsYXNzaWZ5IGl0IGFzIGEgc3ViZmxvdyBtb3VudCBpbiBQaGFzZSAwLlxuICAgICAgICAgIHJldHVybiB0aGlzLmhvcChub2RlLCBjb250ZXh0LCBicmFuY2hQYXRoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGNoaWxkcmVuIGZvciBzdWJmbG93RGVmXG4gICAgICAgIGlmIChkeW5hbWljTm9kZS5jaGlsZHJlbikge1xuICAgICAgICAgIGZvciAoY29uc3QgY2hpbGQgb2YgZHluYW1pY05vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgICAgIGlmIChjaGlsZC5pc1N1YmZsb3dSb290ICYmIGNoaWxkLnN1YmZsb3dEZWYgJiYgY2hpbGQuc3ViZmxvd0lkKSB7XG4gICAgICAgICAgICAgIHRoaXMuYXV0b1JlZ2lzdGVyU3ViZmxvd0RlZihjaGlsZC5zdWJmbG93SWQsIGNoaWxkLnN1YmZsb3dEZWYsIGNoaWxkLmlkKTtcbiAgICAgICAgICAgICAgdGhpcy5zdHJ1Y3R1cmVNYW5hZ2VyLnVwZGF0ZUR5bmFtaWNTdWJmbG93KFxuICAgICAgICAgICAgICAgIGNoaWxkLmlkLFxuICAgICAgICAgICAgICAgIGNoaWxkLnN1YmZsb3dJZCEsXG4gICAgICAgICAgICAgICAgY2hpbGQuc3ViZmxvd05hbWUsXG4gICAgICAgICAgICAgICAgY2hpbGQuc3ViZmxvd0RlZj8uYnVpbGRUaW1lU3RydWN0dXJlLFxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIER5bmFtaWMgY2hpbGRyZW4gKGZvcmsgcGF0dGVybikg4oCUIHBhdGNoZWQgaW50byB0aGUgb3ZlcmxheTtcbiAgICAgICAgLy8gUGhhc2UgNSBiZWxvdyByZWFkcyB0aGVtIGJhY2sgdGhyb3VnaCBlZmZDaGlsZHJlbi9lZmZTZWxlY3Rvci5cbiAgICAgICAgaWYgKGR5bmFtaWNOb2RlLmNoaWxkcmVuICYmIGR5bmFtaWNOb2RlLmNoaWxkcmVuLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICB0aGlzLmdldE9yQ3JlYXRlUGF0Y2gobm9kZSkuY2hpbGRyZW4gPSBkeW5hbWljTm9kZS5jaGlsZHJlbjtcbiAgICAgICAgICBjb250ZXh0LmFkZExvZygnZHluYW1pY0NoaWxkQ291bnQnLCBkeW5hbWljTm9kZS5jaGlsZHJlbi5sZW5ndGgpO1xuICAgICAgICAgIGNvbnRleHQuYWRkTG9nKFxuICAgICAgICAgICAgJ2R5bmFtaWNDaGlsZElkcycsXG4gICAgICAgICAgICBkeW5hbWljTm9kZS5jaGlsZHJlbi5tYXAoKGMpID0+IGMuaWQpLFxuICAgICAgICAgICk7XG5cbiAgICAgICAgICB0aGlzLnN0cnVjdHVyZU1hbmFnZXIudXBkYXRlRHluYW1pY0NoaWxkcmVuKFxuICAgICAgICAgICAgbm9kZS5pZCxcbiAgICAgICAgICAgIGR5bmFtaWNOb2RlLmNoaWxkcmVuLFxuICAgICAgICAgICAgQm9vbGVhbihkeW5hbWljTm9kZS5uZXh0Tm9kZVNlbGVjdG9yKSxcbiAgICAgICAgICAgIEJvb2xlYW4oZHluYW1pY05vZGUuZGVjaWRlckZuKSxcbiAgICAgICAgICApO1xuXG4gICAgICAgICAgaWYgKHR5cGVvZiBkeW5hbWljTm9kZS5uZXh0Tm9kZVNlbGVjdG9yID09PSAnZnVuY3Rpb24nKSB7XG4gICAgICAgICAgICB0aGlzLmdldE9yQ3JlYXRlUGF0Y2gobm9kZSkubmV4dE5vZGVTZWxlY3RvciA9IGR5bmFtaWNOb2RlLm5leHROb2RlU2VsZWN0b3I7XG4gICAgICAgICAgICBjb250ZXh0LmFkZExvZygnaGFzU2VsZWN0b3InLCB0cnVlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICAvLyBEeW5hbWljIG5leHQgKGxpbmVhciBjb250aW51YXRpb24pIOKAlCBzdGF5cyBhIExPQ0FMOiBpdCBhcHBsaWVzXG4gICAgICAgIC8vIG9ubHkgdG8gdGhpcyB2aXNpdCAoUGhhc2UgNiByb3V0ZXMgaXQgdGhyb3VnaCB0aGVcbiAgICAgICAgLy8gQ29udGludWF0aW9uUmVzb2x2ZXIpLCBzbyB0aGUgc2hhcmVkIG5vZGUncyBuZXh0IGlzIG5ldmVyIHRvdWNoZWRcbiAgICAgICAgLy8gYW5kIGEgbG9vcCByZXZpc2l0IG5hdHVyYWxseSBzZWVzIHRoZSBidWlsdCBjb250aW51YXRpb24uXG4gICAgICAgIGlmIChkeW5hbWljTm9kZS5uZXh0KSB7XG4gICAgICAgICAgZHluYW1pY05leHQgPSBkeW5hbWljTm9kZS5uZXh0O1xuICAgICAgICAgIHRoaXMuc3RydWN0dXJlTWFuYWdlci51cGRhdGVEeW5hbWljTmV4dChub2RlLmlkLCBkeW5hbWljTm9kZS5uZXh0KTtcbiAgICAgICAgICBjb250ZXh0LmFkZExvZygnaGFzRHluYW1pY05leHQnLCB0cnVlKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHN0YWdlT3V0cHV0ID0gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIOKUgOKUgOKUgCBQaGFzZSA1OiBDSElMRFJFTiDigJQgZm9yayBkaXNwYXRjaCDilIDilIDilIBcbiAgICAvLyBSZS1yZWFkIHRocm91Z2ggdGhlIG92ZXJsYXk6IFBoYXNlIDQgbWF5IGhhdmUganVzdCBwYXRjaGVkIGR5bmFtaWNcbiAgICAvLyBjaGlsZHJlbi9zZWxlY3RvciBmb3IgVEhJUyB2aXNpdCAob3IgYW4gZWFybGllciB2aXNpdCBpbiB0aGlzIHJ1bikuXG4gICAgY29uc3QgY2hpbGRyZW5BZnRlclN0YWdlID0gdGhpcy5lZmZDaGlsZHJlbihub2RlKTtcbiAgICBjb25zdCBoYXNDaGlsZHJlbkFmdGVyU3RhZ2UgPSBCb29sZWFuKGNoaWxkcmVuQWZ0ZXJTdGFnZT8ubGVuZ3RoKTtcblxuICAgIGlmIChoYXNDaGlsZHJlbkFmdGVyU3RhZ2UpIHtcbiAgICAgIGNvbnRleHQuYWRkTG9nKCd0b3RhbENoaWxkcmVuJywgY2hpbGRyZW5BZnRlclN0YWdlPy5sZW5ndGgpO1xuICAgICAgY29udGV4dC5hZGRMb2coJ29yZGVyT2ZFeGVjdXRpb24nLCAnQ2hpbGRyZW5BZnRlclN0YWdlJyk7XG5cbiAgICAgIGxldCBub2RlQ2hpbGRyZW5SZXN1bHRzOiBSZWNvcmQ8c3RyaW5nLCBOb2RlUmVzdWx0VHlwZT47XG5cbiAgICAgIGNvbnN0IGVmZlNlbGVjdG9yRm4gPSB0aGlzLmVmZlNlbGVjdG9yKG5vZGUpO1xuICAgICAgaWYgKGVmZlNlbGVjdG9yRm4pIHtcbiAgICAgICAgbm9kZUNoaWxkcmVuUmVzdWx0cyA9IGF3YWl0IHRoaXMuY2hpbGRyZW5FeGVjdXRvci5leGVjdXRlU2VsZWN0ZWRDaGlsZHJlbihcbiAgICAgICAgICBlZmZTZWxlY3RvckZuLFxuICAgICAgICAgIGNoaWxkcmVuQWZ0ZXJTdGFnZSEsXG4gICAgICAgICAgc3RhZ2VPdXRwdXQsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBicmFuY2hQYXRoIGFzIHN0cmluZyxcbiAgICAgICAgICB0cmF2ZXJzYWxDb250ZXh0LFxuICAgICAgICAgIG5vZGUuZmFpbEZhc3QsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb25zdCBjaGlsZENvdW50ID0gY2hpbGRyZW5BZnRlclN0YWdlPy5sZW5ndGggPz8gMDtcbiAgICAgICAgY29uc3QgY2hpbGROYW1lcyA9IGNoaWxkcmVuQWZ0ZXJTdGFnZT8ubWFwKChjKSA9PiBjLm5hbWUpLmpvaW4oJywgJyk7XG4gICAgICAgIGNvbnRleHQuYWRkRmxvd0RlYnVnTWVzc2FnZSgnY2hpbGRyZW4nLCBgRXhlY3V0aW5nIGFsbCAke2NoaWxkQ291bnR9IGNoaWxkcmVuIGluIHBhcmFsbGVsOiAke2NoaWxkTmFtZXN9YCwge1xuICAgICAgICAgIGNvdW50OiBjaGlsZENvdW50LFxuICAgICAgICAgIHRhcmdldFN0YWdlOiBjaGlsZHJlbkFmdGVyU3RhZ2U/Lm1hcCgoYykgPT4gYy5uYW1lKSxcbiAgICAgICAgfSk7XG5cbiAgICAgICAgLy8gZWZmTm9kZTogQ2hpbGRyZW5FeGVjdXRvciByZWFkcyBub2RlLmNoaWxkcmVuL25vZGUuZmFpbEZhc3QgaXRzZWxmLlxuICAgICAgICBub2RlQ2hpbGRyZW5SZXN1bHRzID0gYXdhaXQgdGhpcy5jaGlsZHJlbkV4ZWN1dG9yLmV4ZWN1dGVOb2RlQ2hpbGRyZW4oXG4gICAgICAgICAgdGhpcy5lZmZOb2RlKG5vZGUpLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgdW5kZWZpbmVkLFxuICAgICAgICAgIGJyYW5jaFBhdGgsXG4gICAgICAgICAgdHJhdmVyc2FsQ29udGV4dCxcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgLy8gRm9yay1vbmx5OiByZXR1cm4gYnVuZGxlXG4gICAgICBpZiAoIWhhc05leHQgJiYgIWR5bmFtaWNOZXh0KSB7XG4gICAgICAgIHJldHVybiBub2RlQ2hpbGRyZW5SZXN1bHRzITtcbiAgICAgIH1cblxuICAgICAgLy8gQ2FwdHVyZSBkeW5hbWljIGNoaWxkcmVuIGFzIHN5bnRoZXRpYyBzdWJmbG93IHJlc3VsdCBmb3IgVUlcbiAgICAgIGNvbnN0IGlzRHluYW1pYyA9IGNvbnRleHQuZGVidWc/LmxvZ0NvbnRleHQ/LmlzRHluYW1pYztcbiAgICAgIGlmIChpc0R5bmFtaWMgJiYgY2hpbGRyZW5BZnRlclN0YWdlICYmIGNoaWxkcmVuQWZ0ZXJTdGFnZS5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRoaXMuY2FwdHVyZUR5bmFtaWNDaGlsZHJlblJlc3VsdChub2RlLCBjaGlsZHJlbkFmdGVyU3RhZ2UsIGNvbnRleHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIOKUgOKUgOKUgCBQaGFzZSA2OiBDT05USU5VRSDigJQgZHluYW1pYyBuZXh0IC8gbGluZWFyIG5leHQg4pSA4pSA4pSAXG4gICAgaWYgKGR5bmFtaWNOZXh0KSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmNvbnRpbnVhdGlvblJlc29sdmVyLnJlc29sdmVUYXJnZXQoZHluYW1pY05leHQsIG5vZGUsIGNvbnRleHQsIGJyYW5jaFBhdGgpO1xuICAgICAgcmV0dXJuIHRoaXMuaG9wKHRhcmdldC5ub2RlLCB0YXJnZXQuY29udGV4dCwgYnJhbmNoUGF0aCk7XG4gICAgfVxuXG4gICAgaWYgKGhhc05leHQpIHtcbiAgICAgIGNvbnN0IG5leHROb2RlID0gb3JpZ2luYWxOZXh0ITtcblxuICAgICAgLy8gRGV0ZWN0IGxvb3AgcmVmZXJlbmNlIG5vZGVzIGNyZWF0ZWQgYnkgbG9vcFRvKCkg4oCUIG1hcmtlZCB3aXRoIGlzTG9vcFJlZiBmbGFnLlxuICAgICAgLy8gUm91dGUgdGhyb3VnaCBDb250aW51YXRpb25SZXNvbHZlciBmb3IgcHJvcGVyIElEIHJlc29sdXRpb24sIGl0ZXJhdGlvblxuICAgICAgLy8gdHJhY2tpbmcsIGFuZCBuYXJyYXRpdmUgZ2VuZXJhdGlvbi4gVGhlIHJlc29sdmVkIHRhcmdldCBjb21lcyBiYWNrXG4gICAgICAvLyBhcyBhIGhvcCDigJQgbG9vcCBlZGdlcyBjb25zdW1lIG5vIHN0YWNrLCBzbyB0aGUgaXRlcmF0aW9uIGxpbWl0XG4gICAgICAvLyAobm90IGNhbGwtc3RhY2sgZGVwdGgpIGlzIHdoYXQgYm91bmRzIGEgbG9vcC5cbiAgICAgIGNvbnN0IGlzTG9vcFJlZmVyZW5jZSA9IG5leHROb2RlLmlzTG9vcFJlZjtcblxuICAgICAgaWYgKGlzTG9vcFJlZmVyZW5jZSkge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmNvbnRpbnVhdGlvblJlc29sdmVyLnJlc29sdmVUYXJnZXQobmV4dE5vZGUsIG5vZGUsIGNvbnRleHQsIGJyYW5jaFBhdGgsIHRyYXZlcnNhbENvbnRleHQpO1xuICAgICAgICByZXR1cm4gdGhpcy5ob3AodGFyZ2V0Lm5vZGUsIHRhcmdldC5jb250ZXh0LCBicmFuY2hQYXRoKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5uYXJyYXRpdmVHZW5lcmF0b3Iub25OZXh0KG5vZGUubmFtZSwgbmV4dE5vZGUubmFtZSwgbmV4dE5vZGUuZGVzY3JpcHRpb24sIHRyYXZlcnNhbENvbnRleHQpO1xuICAgICAgY29udGV4dC5hZGRGbG93RGVidWdNZXNzYWdlKCduZXh0JywgYE1vdmluZyB0byAke25leHROb2RlLm5hbWV9IHN0YWdlYCwge1xuICAgICAgICB0YXJnZXRTdGFnZTogbmV4dE5vZGUubmFtZSxcbiAgICAgIH0pO1xuICAgICAgY29uc3QgbmV4dEN0eCA9IGNvbnRleHQuY3JlYXRlTmV4dChicmFuY2hQYXRoIGFzIHN0cmluZywgbmV4dE5vZGUubmFtZSwgbmV4dE5vZGUuaWQpO1xuICAgICAgcmV0dXJuIHRoaXMuaG9wKG5leHROb2RlLCBuZXh0Q3R4LCBicmFuY2hQYXRoKTtcbiAgICB9XG5cbiAgICAvLyDilIDilIDilIAgUGhhc2UgNzogTEVBRiDigJQgbm8gY29udGludWF0aW9uIOKUgOKUgOKUgFxuICAgIHJldHVybiBzdGFnZU91dHB1dDtcbiAgfVxuXG4gIC8vIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgCBQcml2YXRlIEhlbHBlcnMg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG5cbiAgcHJpdmF0ZSBjYXB0dXJlRHluYW1pY0NoaWxkcmVuUmVzdWx0KFxuICAgIG5vZGU6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+LFxuICAgIGNoaWxkcmVuOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPltdLFxuICAgIGNvbnRleHQ6IFN0YWdlQ29udGV4dCxcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgcGFyZW50U3RhZ2VJZCA9IGNvbnRleHQuZ2V0U3RhZ2VJZCgpO1xuXG4gICAgY29uc3QgY2hpbGRTdHJ1Y3R1cmU6IGFueSA9IHtcbiAgICAgIGlkOiBgJHtub2RlLmlkfS1jaGlsZHJlbmAsXG4gICAgICBuYW1lOiAnRHluYW1pYyBDaGlsZHJlbicsXG4gICAgICB0eXBlOiAnZm9yaycsXG4gICAgICBjaGlsZHJlbjogY2hpbGRyZW4ubWFwKChjKSA9PiAoe1xuICAgICAgICBpZDogYy5pZCxcbiAgICAgICAgbmFtZTogYy5uYW1lLFxuICAgICAgICB0eXBlOiAnc3RhZ2UnLFxuICAgICAgfSkpLFxuICAgIH07XG5cbiAgICBjb25zdCBjaGlsZFN0YWdlczogUmVjb3JkPHN0cmluZywgdW5rbm93bj4gPSB7fTtcbiAgICBpZiAoY29udGV4dC5jaGlsZHJlbikge1xuICAgICAgZm9yIChjb25zdCBjaGlsZEN0eCBvZiBjb250ZXh0LmNoaWxkcmVuKSB7XG4gICAgICAgIGNvbnN0IHNuYXBzaG90ID0gY2hpbGRDdHguZ2V0U25hcHNob3QoKTtcbiAgICAgICAgY2hpbGRTdGFnZXNbc25hcHNob3QubmFtZSB8fCBzbmFwc2hvdC5pZF0gPSB7XG4gICAgICAgICAgbmFtZTogc25hcHNob3QubmFtZSxcbiAgICAgICAgICBvdXRwdXQ6IHNuYXBzaG90LmxvZ3MsXG4gICAgICAgICAgZXJyb3JzOiBzbmFwc2hvdC5lcnJvcnMsXG4gICAgICAgICAgbWV0cmljczogc25hcHNob3QubWV0cmljcyxcbiAgICAgICAgICBzdGF0dXM6IHNuYXBzaG90LmVycm9ycyAmJiBPYmplY3Qua2V5cyhzbmFwc2hvdC5lcnJvcnMpLmxlbmd0aCA+IDAgPyAnZXJyb3InIDogJ3N1Y2Nlc3MnLFxuICAgICAgICB9O1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc3ViZmxvd1Jlc3VsdHMuc2V0KG5vZGUuaWQsIHtcbiAgICAgIHN1YmZsb3dJZDogbm9kZS5pZCxcbiAgICAgIHN1YmZsb3dOYW1lOiBub2RlLm5hbWUsXG4gICAgICB0cmVlQ29udGV4dDoge1xuICAgICAgICBnbG9iYWxDb250ZXh0OiB7fSxcbiAgICAgICAgc3RhZ2VDb250ZXh0czogY2hpbGRTdGFnZXMgYXMgdW5rbm93biBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPixcbiAgICAgICAgaGlzdG9yeTogW10sXG4gICAgICB9LFxuICAgICAgcGFyZW50U3RhZ2VJZCxcbiAgICAgIHBpcGVsaW5lU3RydWN0dXJlOiBjaGlsZFN0cnVjdHVyZSxcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJlbnQtY2hhaW4gbGVuZ3RoIG9mIGEgU3RhZ2VDb250ZXh0IOKAlCBzYW1lIHZhbHVlIHRoZSBwcmUtdHJhbXBvbGluZVxuICAgKiB3YWxrIHByb2R1Y2VkLCBtZW1vaXplZC4gVGhlIGNvbnRleHQgdHJlZSBkZWVwZW5zIGJ5IG9uZSBwZXIgZXhlY3V0ZWRcbiAgICogc3RhZ2UgYWxvbmcgYSBjaGFpbiwgc28gdGhlIG5haXZlIHdhbGsgaXMgTyhjaGFpbiBsZW5ndGgpIHBlciBzdGFnZSDigJRcbiAgICogTyhuwrIpIHBlciBydW4gb25jZSBjaGFpbnMgcmVhY2ggdHJhbXBvbGluZSBzY2FsZS4gQ29udGV4dHMgYXJlIHZpc2l0ZWRcbiAgICogcGFyZW50LWJlZm9yZS1jaGlsZCwgc28gdGhlIGNhY2hlZCBwYXJlbnQgbWFrZXMgdGhpcyBPKDEpIGFtb3J0aXplZC5cbiAgICovXG4gIHByaXZhdGUgY29tcHV0ZUNvbnRleHREZXB0aChjb250ZXh0OiBTdGFnZUNvbnRleHQpOiBudW1iZXIge1xuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMuY29udGV4dERlcHRoQ2FjaGUuZ2V0KGNvbnRleHQpO1xuICAgIGlmIChjYWNoZWQgIT09IHVuZGVmaW5lZCkgcmV0dXJuIGNhY2hlZDtcblxuICAgIC8vIFdhbGsgdXAgdG8gdGhlIG5lYXJlc3QgY2FjaGVkIGFuY2VzdG9yIChvciB0aGUgcm9vdCksIHRoZW4gZmlsbCB0aGVcbiAgICAvLyBjYWNoZSBiYWNrIGRvd24g4oCUIGl0ZXJhdGl2ZSwgc28gYSBjb2xkIGRlZXAgY2hhaW4gY2FuJ3Qgb3ZlcmZsb3cuXG4gICAgY29uc3QgdW5jYWNoZWQ6IFN0YWdlQ29udGV4dFtdID0gW107XG4gICAgbGV0IGRlcHRoID0gLTE7IC8vIGRlcHRoIG9mIHRoZSBub2RlIEFCT1ZFIHRoZSBmaXJzdCB1bmNhY2hlZCBlbnRyeVxuICAgIGxldCBjdXJyZW50OiBTdGFnZUNvbnRleHQgfCB1bmRlZmluZWQgPSBjb250ZXh0O1xuICAgIHdoaWxlIChjdXJyZW50KSB7XG4gICAgICBjb25zdCBoaXQgPSB0aGlzLmNvbnRleHREZXB0aENhY2hlLmdldChjdXJyZW50KTtcbiAgICAgIGlmIChoaXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBkZXB0aCA9IGhpdDtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICB1bmNhY2hlZC5wdXNoKGN1cnJlbnQpO1xuICAgICAgY3VycmVudCA9IGN1cnJlbnQucGFyZW50O1xuICAgIH1cbiAgICBmb3IgKGxldCBpID0gdW5jYWNoZWQubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGRlcHRoKys7XG4gICAgICB0aGlzLmNvbnRleHREZXB0aENhY2hlLnNldCh1bmNhY2hlZFtpXSwgZGVwdGgpO1xuICAgIH1cbiAgICByZXR1cm4gZGVwdGg7XG4gIH1cblxuICBwcml2YXRlIHByZWZpeE5vZGVUcmVlKG5vZGU6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+LCBwcmVmaXg6IHN0cmluZyk6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+IHtcbiAgICBpZiAoIW5vZGUpIHJldHVybiBub2RlO1xuICAgIGNvbnN0IGNsb25lOiBTdGFnZU5vZGU8VE91dCwgVFNjb3BlPiA9IHsgLi4ubm9kZSB9O1xuICAgIGNsb25lLm5hbWUgPSBgJHtwcmVmaXh9LyR7bm9kZS5uYW1lfWA7XG4gICAgY2xvbmUuaWQgPSBgJHtwcmVmaXh9LyR7Y2xvbmUuaWR9YDtcbiAgICBpZiAoY2xvbmUuc3ViZmxvd0lkKSBjbG9uZS5zdWJmbG93SWQgPSBgJHtwcmVmaXh9LyR7Y2xvbmUuc3ViZmxvd0lkfWA7XG4gICAgaWYgKGNsb25lLm5leHQpIGNsb25lLm5leHQgPSB0aGlzLnByZWZpeE5vZGVUcmVlKGNsb25lLm5leHQsIHByZWZpeCk7XG4gICAgaWYgKGNsb25lLmNoaWxkcmVuKSB7XG4gICAgICBjbG9uZS5jaGlsZHJlbiA9IGNsb25lLmNoaWxkcmVuLm1hcCgoYykgPT4gdGhpcy5wcmVmaXhOb2RlVHJlZShjLCBwcmVmaXgpKTtcbiAgICB9XG4gICAgcmV0dXJuIGNsb25lO1xuICB9XG5cbiAgcHJpdmF0ZSBhdXRvUmVnaXN0ZXJTdWJmbG93RGVmKFxuICAgIHN1YmZsb3dJZDogc3RyaW5nLFxuICAgIHN1YmZsb3dEZWY6IE5vbk51bGxhYmxlPFN0YWdlTm9kZVsnc3ViZmxvd0RlZiddPixcbiAgICBtb3VudE5vZGVJZD86IHN0cmluZyxcbiAgKTogdm9pZCB7XG4gICAgLy8gdGhpcy5zdWJmbG93cyBpcyBhbHdheXMgaW5pdGlhbGl6ZWQgaW4gdGhlIGNvbnN0cnVjdG9yOyB0aGUgbnVsbCBndWFyZCBiZWxvdyBpcyB1bnJlYWNoYWJsZS5cbiAgICBjb25zdCBzdWJmbG93c0RpY3QgPSB0aGlzLnN1YmZsb3dzO1xuXG4gICAgLy8gRmlyc3Qtd3JpdGUtd2luc1xuICAgIGNvbnN0IGlzTmV3UmVnaXN0cmF0aW9uID0gIXN1YmZsb3dzRGljdFtzdWJmbG93SWRdO1xuICAgIGlmIChpc05ld1JlZ2lzdHJhdGlvbiAmJiBzdWJmbG93RGVmLnJvb3QpIHtcbiAgICAgIHN1YmZsb3dzRGljdFtzdWJmbG93SWRdID0ge1xuICAgICAgICByb290OiBzdWJmbG93RGVmLnJvb3QgYXMgU3RhZ2VOb2RlPFRPdXQsIFRTY29wZT4sXG4gICAgICAgIC4uLihzdWJmbG93RGVmLmJ1aWxkVGltZVN0cnVjdHVyZSA/IHsgYnVpbGRUaW1lU3RydWN0dXJlOiBzdWJmbG93RGVmLmJ1aWxkVGltZVN0cnVjdHVyZSB9IDoge30pLFxuICAgICAgfSBhcyBhbnk7XG4gICAgfVxuXG4gICAgLy8gTWVyZ2Ugc3RhZ2VNYXAgZW50cmllcyAocGFyZW50IGVudHJpZXMgcHJlc2VydmVkKVxuICAgIGlmIChzdWJmbG93RGVmLnN0YWdlTWFwKSB7XG4gICAgICBmb3IgKGNvbnN0IFtrZXksIGZuXSBvZiBBcnJheS5mcm9tKHN1YmZsb3dEZWYuc3RhZ2VNYXAuZW50cmllcygpKSkge1xuICAgICAgICBpZiAoIXRoaXMuc3RhZ2VNYXAuaGFzKGtleSkpIHtcbiAgICAgICAgICB0aGlzLnN0YWdlTWFwLnNldChrZXksIGZuIGFzIFN0YWdlRnVuY3Rpb248VE91dCwgVFNjb3BlPik7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBNZXJnZSBuZXN0ZWQgc3ViZmxvd3NcbiAgICBpZiAoc3ViZmxvd0RlZi5zdWJmbG93cykge1xuICAgICAgZm9yIChjb25zdCBba2V5LCBkZWZdIG9mIE9iamVjdC5lbnRyaWVzKHN1YmZsb3dEZWYuc3ViZmxvd3MpKSB7XG4gICAgICAgIGlmICghc3ViZmxvd3NEaWN0W2tleV0pIHtcbiAgICAgICAgICBzdWJmbG93c0RpY3Rba2V5XSA9IGRlZiBhcyB7IHJvb3Q6IFN0YWdlTm9kZTxUT3V0LCBUU2NvcGU+IH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAobW91bnROb2RlSWQpIHtcbiAgICAgIHRoaXMuc3RydWN0dXJlTWFuYWdlci51cGRhdGVEeW5hbWljU3ViZmxvdyhcbiAgICAgICAgbW91bnROb2RlSWQsXG4gICAgICAgIHN1YmZsb3dJZCxcbiAgICAgICAgc3ViZmxvd0RlZi5yb290Py5zdWJmbG93TmFtZSB8fCBzdWJmbG93RGVmLnJvb3Q/Lm5hbWUsXG4gICAgICAgIHN1YmZsb3dEZWYuYnVpbGRUaW1lU3RydWN0dXJlLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICAvLyBOb3RpZnkgRmxvd1JlY29yZGVycyBvbmx5IG9uIGZpcnN0IHJlZ2lzdHJhdGlvbiAobWF0Y2hlcyBmaXJzdC13cml0ZS13aW5zKVxuICAgIGlmIChpc05ld1JlZ2lzdHJhdGlvbikge1xuICAgICAgY29uc3Qgc3ViZmxvd05hbWUgPSBzdWJmbG93RGVmLnJvb3Q/LnN1YmZsb3dOYW1lIHx8IHN1YmZsb3dEZWYucm9vdD8ubmFtZSB8fCBzdWJmbG93SWQ7XG4gICAgICB0aGlzLm5hcnJhdGl2ZUdlbmVyYXRvci5vblN1YmZsb3dSZWdpc3RlcmVkKFxuICAgICAgICBzdWJmbG93SWQsXG4gICAgICAgIHN1YmZsb3dOYW1lLFxuICAgICAgICBzdWJmbG93RGVmLnJvb3Q/LmRlc2NyaXB0aW9uLFxuICAgICAgICBzdWJmbG93RGVmLmJ1aWxkVGltZVN0cnVjdHVyZSxcbiAgICAgICk7XG4gICAgfVxuICB9XG59XG4iXX0=