footprintjs 9.6.0 → 9.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. package/CLAUDE.md +5 -2
  2. package/dist/advanced.js +1 -1
  3. package/dist/esm/advanced.js +1 -1
  4. package/dist/esm/index.js +1 -1
  5. package/dist/esm/lib/engine/handlers/SubflowExecutor.js +13 -1
  6. package/dist/esm/lib/engine/narrative/types.js +1 -1
  7. package/dist/esm/lib/engine/traversal/FlowchartTraverser.js +17 -1
  8. package/dist/esm/lib/engine/types.js +1 -1
  9. package/dist/esm/lib/memory/SharedMemory.js +1 -1
  10. package/dist/esm/lib/memory/StageContext.js +75 -4
  11. package/dist/esm/lib/memory/TransactionBuffer.js +166 -9
  12. package/dist/esm/lib/memory/backtrack.js +145 -35
  13. package/dist/esm/lib/memory/commitLogUtils.js +71 -1
  14. package/dist/esm/lib/memory/index.js +1 -1
  15. package/dist/esm/lib/memory/pathOps.js +28 -1
  16. package/dist/esm/lib/memory/types.js +1 -1
  17. package/dist/esm/lib/memory/utils.js +29 -3
  18. package/dist/esm/lib/recorder/ControlDepRecorder.js +228 -0
  19. package/dist/esm/lib/runner/ExecutionRuntime.js +19 -1
  20. package/dist/esm/lib/runner/FlowChartExecutor.js +22 -1
  21. package/dist/esm/lib/scope/ScopeFacade.js +44 -2
  22. package/dist/esm/trace.js +7 -3
  23. package/dist/index.js +1 -1
  24. package/dist/lib/engine/handlers/SubflowExecutor.js +13 -1
  25. package/dist/lib/engine/narrative/types.js +1 -1
  26. package/dist/lib/engine/traversal/FlowchartTraverser.js +17 -1
  27. package/dist/lib/engine/types.js +1 -1
  28. package/dist/lib/memory/SharedMemory.js +1 -1
  29. package/dist/lib/memory/StageContext.js +75 -4
  30. package/dist/lib/memory/TransactionBuffer.js +166 -9
  31. package/dist/lib/memory/backtrack.js +145 -35
  32. package/dist/lib/memory/commitLogUtils.js +73 -2
  33. package/dist/lib/memory/index.js +1 -1
  34. package/dist/lib/memory/pathOps.js +30 -2
  35. package/dist/lib/memory/types.js +1 -1
  36. package/dist/lib/memory/utils.js +28 -2
  37. package/dist/lib/recorder/ControlDepRecorder.js +233 -0
  38. package/dist/lib/runner/ExecutionRuntime.js +19 -1
  39. package/dist/lib/runner/FlowChartExecutor.js +22 -1
  40. package/dist/lib/scope/ScopeFacade.js +44 -2
  41. package/dist/trace.js +10 -3
  42. package/dist/types/advanced.d.ts +1 -1
  43. package/dist/types/index.d.ts +17 -0
  44. package/dist/types/lib/engine/narrative/types.d.ts +10 -0
  45. package/dist/types/lib/engine/traversal/FlowchartTraverser.d.ts +13 -0
  46. package/dist/types/lib/engine/types.d.ts +6 -0
  47. package/dist/types/lib/memory/SharedMemory.d.ts +2 -5
  48. package/dist/types/lib/memory/StageContext.d.ts +45 -1
  49. package/dist/types/lib/memory/TransactionBuffer.d.ts +70 -10
  50. package/dist/types/lib/memory/backtrack.d.ts +108 -2
  51. package/dist/types/lib/memory/commitLogUtils.d.ts +28 -0
  52. package/dist/types/lib/memory/index.d.ts +1 -1
  53. package/dist/types/lib/memory/pathOps.d.ts +10 -0
  54. package/dist/types/lib/memory/types.d.ts +78 -3
  55. package/dist/types/lib/memory/utils.d.ts +21 -6
  56. package/dist/types/lib/recorder/ControlDepRecorder.d.ts +133 -0
  57. package/dist/types/lib/runner/ExecutionRuntime.d.ts +23 -1
  58. package/dist/types/lib/runner/FlowChartExecutor.d.ts +41 -3
  59. package/dist/types/lib/scope/ScopeFacade.d.ts +30 -1
  60. package/dist/types/trace.d.ts +5 -2
  61. package/package.json +1 -1
@@ -26,9 +26,12 @@ export class TransactionBuffer {
26
26
  updatePatch = {};
27
27
  opTrace = [];
28
28
  redactedPaths = new Set();
29
- constructor(base) {
29
+ /** Commit-value encoding policy (#13c-B). `'full'` = historical bytes. */
30
+ commitValues;
31
+ constructor(base, commitValues = 'full') {
30
32
  this.baseSnapshot = structuredClone(base);
31
33
  this.workingCopy = structuredClone(base);
34
+ this.commitValues = commitValues;
32
35
  }
33
36
  /** Hard overwrite at the specified path. */
34
37
  set(path, value, shouldRedact = false) {
@@ -39,6 +42,25 @@ export class TransactionBuffer {
39
42
  }
40
43
  this.opTrace.push({ path: normalisePath(path), verb: 'set' });
41
44
  }
45
+ /**
46
+ * Explicit key deletion at the specified path (#13c-B; absorbs backlog B8).
47
+ *
48
+ * Stages EXACTLY the same buffer mutations as `set(path, undefined)` —
49
+ * `workingCopy`/`overwritePatch` get an own `undefined` at the path (the
50
+ * historical flattening, preserving read behavior and the dedup diff base
51
+ * across modes) — but records the op verb as `'delete'`. At commit:
52
+ * `'full'` mode maps it back to a `'set'` trace entry (byte-identical to
53
+ * today); `'delta'` mode emits a real `'delete'` entry whose replay
54
+ * REMOVES the key instead of leaving `key: undefined` behind.
55
+ */
56
+ delete(path, shouldRedact = false) {
57
+ _set(this.workingCopy, path, undefined);
58
+ _set(this.overwritePatch, path, undefined);
59
+ if (shouldRedact) {
60
+ this.redactedPaths.add(normalisePath(path));
61
+ }
62
+ this.opTrace.push({ path: normalisePath(path), verb: 'delete' });
63
+ }
42
64
  /** Deep union merge at the specified path. */
43
65
  merge(path, value, shouldRedact = false) {
44
66
  const existing = _get(this.workingCopy, path) ?? {};
@@ -101,10 +123,11 @@ export class TransactionBuffer {
101
123
  * commit-indexed slider stable while making the highlight truthful.
102
124
  *
103
125
  * ── KNOWN LIMITATIONS / FUTURE ──────────────────────────────────────────
104
- * • Explicit key DELETION is still unrepresentable in MemoryPatch (a removed
105
- * key cannot be expressed). Setting a key to `undefined` is treated as a
106
- * change (value differs from base), not a deletion. Tracked for a future
107
- * `delete` verb.
126
+ * • Explicit key DELETION under the default 'full' mode is still
127
+ * flattened to set-of-`undefined` (a removed key cannot be expressed
128
+ * in MemoryPatch alone). CLOSED under `commitValues: 'delta'` (#13c-B):
129
+ * {@link delete} stages a distinct op and the bundle carries a real
130
+ * `delete` trace verb whose replay removes the key.
108
131
  * • Array-merge dedup in {@link deepSmartMerge} still uses reference equality
109
132
  * (`new Set`), so deep-equal *objects* in a merged array are not deduped.
110
133
  * Orthogonal to this change; tracked separately.
@@ -112,7 +135,7 @@ export class TransactionBuffer {
112
135
  * Resets the buffer to empty state after commit.
113
136
  */
114
137
  commit() {
115
- const payload = this.toChangeOnlyPayload();
138
+ const payload = this.commitValues === 'delta' ? this.toDeltaPayload() : this.toChangeOnlyPayload();
116
139
  this.overwritePatch = {};
117
140
  this.updatePatch = {};
118
141
  this.opTrace.length = 0;
@@ -131,6 +154,11 @@ export class TransactionBuffer {
131
154
  * surviving `merge` paths copy their accumulated delta from `updatePatch` —
132
155
  * preserving the set-vs-merge verb so replay ({@link applySmartMerge}) is
133
156
  * byte-for-byte identical to recording only the real changes.
157
+ *
158
+ * This is the DEFAULT (`commitValues: 'full'`) payload — byte-identical to
159
+ * the historical behavior, including flattening staged `delete` ops into
160
+ * `set`-of-`undefined` trace entries. The delta encoding lives in
161
+ * {@link toDeltaPayload}.
134
162
  */
135
163
  toChangeOnlyPayload() {
136
164
  const overwrite = {};
@@ -143,17 +171,146 @@ export class TransactionBuffer {
143
171
  const after = _get(this.workingCopy, segments);
144
172
  if (deepEqual(before, after))
145
173
  continue; // no-op or write-then-revert → no net change
146
- trace.push(op);
174
+ // Historical flattening: an explicit delete commits as set-of-undefined.
175
+ trace.push(op.verb === 'delete' ? { path: op.path, verb: 'set' } : op);
147
176
  survivingPaths.add(op.path);
148
- if (op.verb === 'set') {
177
+ if (op.verb === 'merge') {
178
+ _set(updates, segments, structuredClone(_get(this.updatePatch, segments)));
179
+ }
180
+ else {
149
181
  _set(overwrite, segments, structuredClone(_get(this.overwritePatch, segments)));
150
182
  }
183
+ }
184
+ const redactedPaths = new Set([...this.redactedPaths].filter((path) => survivingPaths.has(path)));
185
+ return { overwrite, updates, redactedPaths, trace };
186
+ }
187
+ /**
188
+ * Delta-encoded payload (`commitValues: 'delta'`, #13c-B) — same net-change
189
+ * filter as {@link toChangeOnlyPayload}, two encoding differences:
190
+ *
191
+ * 1. **One trace entry per surviving path** (the §2.5 dedup rule — `append`
192
+ * is NOT idempotent on replay, so duplicate entries would multiply
193
+ * tails). The verb is resolved from the path's op mix + base→final
194
+ * relationship; entries are ordered by each path's LAST touch,
195
+ * preserving last-writer-wins for nested/overlapping paths.
196
+ * 2. **Verb resolution per path**:
197
+ * - last op `'delete'` AND final value gone → `delete` (the path stays
198
+ * enumerated in `overwrite` with `undefined` for key-set consumers);
199
+ * - ONLY `'merge'` ops → `merge` with the accumulated `updatePatch`
200
+ * delta (replaying the accumulated delta once ≡ the full mode's
201
+ * k sequential replays — `deepSmartMerge` is reference-idempotent
202
+ * within one replay pass);
203
+ * - otherwise (`set`/mixed): the committed value is computed by
204
+ * replaying the path's op sequence EXACTLY the way `applySmartMerge`
205
+ * replays the full-mode bundle ({@link replayPathVerbs}) — for
206
+ * pure-set paths that is simply the last set value; for mixed
207
+ * set+merge interleavings it reproduces the full mode's quirk of
208
+ * applying the ACCUMULATED merge delta at every merge position
209
+ * (which can differ from the buffer's read-your-writes view; parity
210
+ * with the `'full'` mode's committed state is the contract). If base
211
+ * and that value are arrays and base is a STRICT PREFIX → `append`
212
+ * storing only the tail; else `set` storing the full value.
213
+ *
214
+ * Losslessness never depends on detection succeeding — every fallback is
215
+ * today's full-value `set`.
216
+ */
217
+ toDeltaPayload() {
218
+ const overwrite = {};
219
+ const updates = {};
220
+ const trace = [];
221
+ const survivingPaths = new Set();
222
+ // Path → its op-verb sequence, ordered by LAST touch (delete +
223
+ // re-insert moves a re-touched path to the end of the Map's insertion
224
+ // order — preserving last-writer-wins for nested/overlapping paths).
225
+ const byPath = new Map();
226
+ for (const op of this.opTrace) {
227
+ const prev = byPath.get(op.path);
228
+ if (prev) {
229
+ prev.push(op.verb);
230
+ byPath.delete(op.path);
231
+ byPath.set(op.path, prev);
232
+ }
151
233
  else {
234
+ byPath.set(op.path, [op.verb]);
235
+ }
236
+ }
237
+ for (const [path, verbs] of byPath) {
238
+ const segments = path.split(DELIM);
239
+ const before = _get(this.baseSnapshot, segments);
240
+ const after = _get(this.workingCopy, segments);
241
+ if (deepEqual(before, after))
242
+ continue; // no-op or write-then-revert → no net change (same filter as 'full')
243
+ survivingPaths.add(path);
244
+ const lastVerb = verbs[verbs.length - 1];
245
+ if (lastVerb === 'delete' && after === undefined) {
246
+ // Real deletion — replay removes the key. Keep the path enumerated
247
+ // in `overwrite` (undefined) so Object.keys consumers see it.
248
+ trace.push({ path, verb: 'delete' });
249
+ _set(overwrite, segments, undefined);
250
+ }
251
+ else if (verbs.every((v) => v === 'merge')) {
252
+ trace.push({ path, verb: 'merge' });
152
253
  _set(updates, segments, structuredClone(_get(this.updatePatch, segments)));
153
254
  }
255
+ else {
256
+ // Committed-equivalent value: replay this path's op sequence the way
257
+ // applySmartMerge replays the FULL-mode bundle, so both modes commit
258
+ // byte-identical state (see the method JSDoc).
259
+ const committed = this.replayPathVerbs(before, segments, verbs);
260
+ if (isStrictArrayPrefix(before, committed)) {
261
+ trace.push({ path, verb: 'append' });
262
+ _set(overwrite, segments, structuredClone(committed.slice(before.length)));
263
+ }
264
+ else {
265
+ trace.push({ path, verb: 'set' });
266
+ _set(overwrite, segments, structuredClone(committed));
267
+ }
268
+ }
154
269
  }
155
270
  const redactedPaths = new Set([...this.redactedPaths].filter((path) => survivingPaths.has(path)));
156
271
  return { overwrite, updates, redactedPaths, trace };
157
272
  }
273
+ /**
274
+ * Replay ONE path's op-verb sequence against its base value, exactly the
275
+ * way `applySmartMerge` replays the corresponding full-mode bundle: every
276
+ * `set`/`delete` position applies the LAST staged overwrite value (the
277
+ * bag holds one value per path — last writer wins), every `merge`
278
+ * position applies the ACCUMULATED `updatePatch` delta. This reproduces
279
+ * the full mode's committed value for any interleaving — including the
280
+ * mixed set+merge quirk where the accumulated delta re-applies pre-set
281
+ * merge keys (full-mode replay semantics, kept for byte-parity across
282
+ * modes; property-tested in delta-replay-equivalence).
283
+ */
284
+ replayPathVerbs(before, segments, verbs) {
285
+ const setValue = _get(this.overwritePatch, segments);
286
+ const mergeDelta = _get(this.updatePatch, segments);
287
+ let value = before;
288
+ for (const verb of verbs) {
289
+ value = verb === 'merge' ? deepSmartMerge(value ?? {}, mergeDelta) : setValue;
290
+ }
291
+ return value;
292
+ }
293
+ }
294
+ /**
295
+ * Append-detection predicate (#13c-B §2.2): both values are arrays, the
296
+ * final is strictly longer, and the base is a structural prefix of the
297
+ * final. Element compares short-circuit on reference identity (`deepEqual`'s
298
+ * `===` fast path) before walking structure, and bail at the first mismatch
299
+ * — worst case one structural compare of the base array, strictly cheaper
300
+ * than the full-value `structuredClone` the fallback pays.
301
+ *
302
+ * `before === undefined` (first write) fails `Array.isArray` → `set`, which
303
+ * keeps the first write as the causal anchor for "who initialized this key".
304
+ */
305
+ function isStrictArrayPrefix(before, after) {
306
+ if (!Array.isArray(before) || !Array.isArray(after))
307
+ return false;
308
+ if (after.length <= before.length)
309
+ return false;
310
+ for (let i = 0; i < before.length; i++) {
311
+ if (!deepEqual(before[i], after[i]))
312
+ return false;
313
+ }
314
+ return true;
158
315
  }
159
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25CdWZmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS9UcmFuc2FjdGlvbkJ1ZmZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLFNBQVMsSUFBSSxJQUFJLEVBQUUsU0FBUyxJQUFJLElBQUksRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVwRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBRTdFLE1BQU0sT0FBTyxpQkFBaUI7SUFDWCxZQUFZLENBQU07SUFDM0IsV0FBVyxDQUFNO0lBRWpCLGNBQWMsR0FBZ0IsRUFBRSxDQUFDO0lBQ2pDLFdBQVcsR0FBZ0IsRUFBRSxDQUFDO0lBQzlCLE9BQU8sR0FBOEMsRUFBRSxDQUFDO0lBQ3hELGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBRTFDLFlBQVksSUFBUztRQUNuQixJQUFJLENBQUMsWUFBWSxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsV0FBVyxHQUFHLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUMzQyxDQUFDO0lBRUQsNENBQTRDO0lBQzVDLEdBQUcsQ0FBQyxJQUF5QixFQUFFLEtBQVUsRUFBRSxZQUFZLEdBQUcsS0FBSztRQUM3RCxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDcEMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxFQUFFLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQ3hELElBQUksWUFBWSxFQUFFLENBQUM7WUFDakIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLElBQUksQ0FBQyxDQUFD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LENBQUMsSUFBSSxLQUFLLEtBQUssRUFBRSxDQUFDO2dCQUN0QixJQUFJLENBQUMsU0FBUyxFQUFFLFFBQVEsRUFBRSxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2xGLENBQUM7aUJBQU0sQ0FBQztnQkFDTixJQUFJLENBQUMsT0FBTyxFQUFFLFFBQVEsRUFBRSxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzdFLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xHLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLGFBQWEsRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUN0RCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFRyYW5zYWN0aW9uQnVmZmVyIOKAlCBQZXItc3RhZ2UgU1RBR0lORyBidWZmZXIgZm9yIHN0YXRlIG11dGF0aW9uc1xuICpcbiAqIFdoYXQgaXQgSVM6IGEgc3RhZ2luZyBidWZmZXIgd2l0aCByZWFkLXlvdXItd3JpdGVzIGFuZCBuZXQtY2hhbmdlIGNvbW1pdHMuXG4gKiAtIENoYW5nZXMgYXJlIHN0YWdlZCBoZXJlIGR1cmluZyBzdGFnZSBleGVjdXRpb24gYW5kIGZsdXNoZWQgdG9cbiAqICAgU2hhcmVkTWVtb3J5IGluIE9ORSBiYXRjaCBwZXIgc3RhZ2UgKGBjb21taXQoKWApIOKAlCBvdGhlciBzdGFnZXMgYW5kXG4gKiAgIHBhcmFsbGVsIHNpYmxpbmdzIG5ldmVyIG9ic2VydmUgYSBzdGFnZSdzIGhhbGYtZmluaXNoZWQgd3JpdGVzLlxuICogLSBSZWFkLWFmdGVyLXdyaXRlIGNvbnNpc3RlbmN5IHdpdGhpbiBhIHN0YWdlIOKAlCBhIHN0YWdlIHNlZXMgaXRzIG93blxuICogICBzdGFnZWQgd3JpdGVzIGltbWVkaWF0ZWx5LlxuICogLSBgY29tbWl0KClgIHJlY29yZHMgdGhlIHN0YWdlJ3MgTkVUIGNoYW5nZSAoc2VlIHtAbGluayBjb21taXR9KSwgcGx1cyBhblxuICogICBvcGVyYXRpb24gdHJhY2UgZm9yIGRldGVybWluaXN0aWMgcmVwbGF5LlxuICpcbiAqIFdoYXQgaXQgaXMgTk9UOiBhIHJvbGxiYWNrIG1lY2hhbmlzbS4gRGVzcGl0ZSB0aGUgbmFtZSwgdGhlcmUgaXMgbm9cbiAqIGFib3J0L3JvbGxiYWNrIHBhdGgg4oCUIHdoZW4gYSBzdGFnZSBUSFJPV1MsIHRoZSBlbmdpbmUgc3RpbGwgY29tbWl0c1xuICogZXZlcnl0aGluZyBzdGFnZWQgc28gZmFyIGJlZm9yZSByZS10aHJvd2luZyAoY29tbWl0LW9uLWVycm9yIGluXG4gKiBgRmxvd2NoYXJ0VHJhdmVyc2VyYCkuIFRoYXQgaXMgZGVsaWJlcmF0ZTogdGhlIGF1ZGl0IHRyYWlsIG11c3QgcmVjb3JkXG4gKiB3aGF0IHRoZSBmYWlsaW5nIHN0YWdlIGNoYW5nZWQuIERvIG5vdCByZWx5IG9uIFwic3RhZ2UgZmFpbGVkIOKGkiBpdHNcbiAqIHdyaXRlcyB2YW5pc2hlZFwiLlxuICovXG5cbmltcG9ydCB7IG5hdGl2ZUdldCBhcyBfZ2V0LCBuYXRpdmVTZXQgYXMgX3NldCB9IGZyb20gJy4vcGF0aE9wcy5qcyc7XG5pbXBvcnQgdHlwZSB7IE1lbW9yeVBhdGNoIH0gZnJvbSAnLi90eXBlcy5qcyc7XG5pbXBvcnQgeyBkZWVwRXF1YWwsIGRlZXBTbWFydE1lcmdlLCBERUxJTSwgbm9ybWFsaXNlUGF0aCB9IGZyb20gJy4vdXRpbHMuanMnO1xuXG5leHBvcnQgY2xhc3MgVHJhbnNhY3Rpb25CdWZmZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IGJhc2VTbmFwc2hvdDogYW55O1xuICBwcml2YXRlIHdvcmtpbmdDb3B5OiBhbnk7XG5cbiAgcHJpdmF0ZSBvdmVyd3JpdGVQYXRjaDogTWVtb3J5UGF0Y2ggPSB7fTtcbiAgcHJpdmF0ZSB1cGRhdGVQYXRjaDogTWVtb3J5UGF0Y2ggPSB7fTtcbiAgcHJpdmF0ZSBvcFRyYWNlOiB7IHBhdGg6IHN0cmluZzsgdmVyYjogJ3NldCcgfCAnbWVyZ2UnIH1bXSA9IFtdO1xuICBwcml2YXRlIHJlZGFjdGVkUGF0aHMgPSBuZXcgU2V0PHN0cmluZz4oKTtcblxuICBjb25zdHJ1Y3RvcihiYXNlOiBhbnkpIHtcbiAgICB0aGlzLmJhc2VTbmFwc2hvdCA9IHN0cnVjdHVyZWRDbG9uZShiYXNlKTtcbiAgICB0aGlzLndvcmtpbmdDb3B5ID0gc3RydWN0dXJlZENsb25lKGJhc2UpO1xuICB9XG5cbiAgLyoqIEhhcmQgb3ZlcndyaXRlIGF0IHRoZSBzcGVjaWZpZWQgcGF0aC4gKi9cbiAgc2V0KHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10sIHZhbHVlOiBhbnksIHNob3VsZFJlZGFjdCA9IGZhbHNlKTogdm9pZCB7XG4gICAgX3NldCh0aGlzLndvcmtpbmdDb3B5LCBwYXRoLCB2YWx1ZSk7XG4gICAgX3NldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBwYXRoLCBzdHJ1Y3R1cmVkQ2xvbmUodmFsdWUpKTtcbiAgICBpZiAoc2hvdWxkUmVkYWN0KSB7XG4gICAgICB0aGlzLnJlZGFjdGVkUGF0aHMuYWRkKG5vcm1hbGlzZVBhdGgocGF0aCkpO1xuICAgIH1cbiAgICB0aGlzLm9wVHJhY2UucHVzaCh7IHBhdGg6IG5vcm1hbGlzZVBhdGgocGF0aCksIHZlcmI6ICdzZXQnIH0pO1xuICB9XG5cbiAgLyoqIERlZXAgdW5pb24gbWVyZ2UgYXQgdGhlIHNwZWNpZmllZCBwYXRoLiAqL1xuICBtZXJnZShwYXRoOiAoc3RyaW5nIHwgbnVtYmVyKVtdLCB2YWx1ZTogYW55LCBzaG91bGRSZWRhY3QgPSBmYWxzZSk6IHZvaWQge1xuICAgIGNvbnN0IGV4aXN0aW5nID0gX2dldCh0aGlzLndvcmtpbmdDb3B5LCBwYXRoKSA/PyB7fTtcbiAgICBjb25zdCBtZXJnZWQgPSBkZWVwU21hcnRNZXJnZShleGlzdGluZywgdmFsdWUpO1xuICAgIF9zZXQodGhpcy53b3JraW5nQ29weSwgcGF0aCwgbWVyZ2VkKTtcbiAgICBfc2V0KHRoaXMudXBkYXRlUGF0Y2gsIHBhdGgsIGRlZXBTbWFydE1lcmdlKF9nZXQodGhpcy51cGRhdGVQYXRjaCwgcGF0aCkgPz8ge30sIHZhbHVlKSk7XG4gICAgaWYgKHNob3VsZFJlZGFjdCkge1xuICAgICAgdGhpcy5yZWRhY3RlZFBhdGhzLmFkZChub3JtYWxpc2VQYXRoKHBhdGgpKTtcbiAgICB9XG4gICAgdGhpcy5vcFRyYWNlLnB1c2goeyBwYXRoOiBub3JtYWxpc2VQYXRoKHBhdGgpLCB2ZXJiOiAnbWVyZ2UnIH0pO1xuICB9XG5cbiAgLyoqIFJlYWQgY3VycmVudCB2YWx1ZSBhdCBwYXRoIChpbmNsdWRlcyB1bmNvbW1pdHRlZCBjaGFuZ2VzKS4gKi9cbiAgZ2V0KHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10sIGRlZmF1bHRWYWx1ZT86IGFueSkge1xuICAgIHJldHVybiBfZ2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIGRlZmF1bHRWYWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogRmx1c2ggYWxsIHN0YWdlZCBtdXRhdGlvbnMgYW5kIHJldHVybiB0aGUgY29tbWl0IGJ1bmRsZSDigJQgcmVjb3JkaW5nIHRoZVxuICAgKiBzdGFnZSdzIE5FVCBDSEFOR0UsIG5vdCBpdHMgcmF3IHdyaXRlIGxvZy5cbiAgICpcbiAgICog4pSA4pSAIFdIWSAodGhlIGRlZmVjdCB0aGlzIGZpeGVzKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogUHJldmlvdXNseSBldmVyeSBgc2V0YC9gbWVyZ2VgIHdhcyByZWNvcmRlZCB2ZXJiYXRpbSwgc28gdGhlIGNvbW1pdCBidW5kbGVcbiAgICogd2FzIGEgbG9nIG9mICpvcGVyYXRpb25zKiByYXRoZXIgdGhhbiAqY2hhbmdlcyouIFR3byBvcGVyYXRpb25zIHByb2R1Y2Ugbm9cbiAgICogbmV0IGNoYW5nZSB5ZXQgd2VyZSBzdGlsbCBjb21taXR0ZWQgYXMgXCJtdXRhdGlvbnNcIjpcbiAgICpcbiAgICogICAxLiBOby1vcCB3cml0ZSAgIOKAlCB3cml0aW5nIGEga2V5IHRoZSB2YWx1ZSBpdCBhbHJlYWR5IGhvbGRzIChlLmcuIGFuXG4gICAqICAgICAgICAgICAgICAgICAgICAgIGFnZW50IGNvbnRleHQgc2xvdCByZS1lbWl0dGluZyBpZGVudGljYWwgY29udGVudCBldmVyeVxuICAgKiAgICAgICAgICAgICAgICAgICAgICB0dXJuKS4gYmFzZSBLPTEsIHN0YWdlIHdyaXRlcyBLPTEuXG4gICAqICAgMi4gV3JpdGUtcmV2ZXJ0ICDigJQgY2hhbmdpbmcgdGhlbiByZXN0b3JpbmcgYSBrZXkgd2l0aGluIG9uZSBzdGFnZS5cbiAgICogICAgICAgICAgICAgICAgICAgICAgYmFzZSBLPTEsIHN0YWdlIHdyaXRlcyBLPTIgdGhlbiBLPTEuXG4gICAqXG4gICAqIFJlY29yZGluZyB0aGVzZSBhcyBtdXRhdGlvbnMgKGEpIGJsb2F0ZWQgY2F1c2FsIHNsaWNpbmcgLyBiYWNrdHJhY2tpbmcgd2l0aFxuICAgKiBzcHVyaW91cyBkZXBlbmRlbmNpZXMgb24gaW50ZXJtZWRpYXRlIHZhbHVlcyB0aGF0IG5ldmVyIHJlYWNoIGZpbmFsIHN0YXRlLFxuICAgKiBhbmQgKGIpIG1hZGUgZG93bnN0cmVhbSBcIndoYXQgY2hhbmdlZCBoZXJlP1wiIGNvbnN1bWVycyBsaWdodCB1cCBzdGFnZXMgdGhhdFxuICAgKiBjaGFuZ2VkIG5vdGhpbmcg4oCUIG1vc3QgdmlzaWJseSB0aGUgbGVucyBoaWdobGlnaHQgZmxhZ2dpbmcgZXZlcnkgc2xvdC5cbiAgICpcbiAgICog4pSA4pSAIEhPVyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogQXQgY29tbWl0IHdlIGhvbGQgQk9USCBgYmFzZVNuYXBzaG90YCAoc3RhdGUgd2hlbiB0aGUgc3RhZ2UgYmVnYW4pIGFuZFxuICAgKiBgd29ya2luZ0NvcHlgIChzdGF0ZSBhZnRlciBhbGwgaXRzIHdyaXRlcykuIEZvciBlYWNoIHBhdGggdGhlIHN0YWdlIHRvdWNoZWRcbiAgICogd2Uga2VlcCBpdCBpbiB0aGUgYnVuZGxlIE9OTFkgaWYgaXRzIGZpbmFsIHZhbHVlIGRpZmZlcnMgZnJvbSB0aGUgYmFzZVxuICAgKiB2YWx1ZSAoe0BsaW5rIGRlZXBFcXVhbH0pLiBOby1vcCBBTkQgd3JpdGUtcmV2ZXJ0IHBhdGhzIGRyb3Agb3V0LCBiZWNhdXNlXG4gICAqIGJvdGggY29tcGFyZSBlcXVhbCB0byBiYXNlLiBUaGlzIGlzIGEgc2luZ2xlIG5ldC1kZWx0YSBkaWZmIGF0IGNvbW1pdCB0aW1lXG4gICAqIOKAlCBvbmUgZGVlcCBjb21wYXJlIHBlciB0b3VjaGVkIHBhdGgsIE8oY2hhbmdlZCBzdGF0ZSksIHBhaWQgb25jZSBwZXIgc3RhZ2VcbiAgICogKE5PVCBwZXIgd3JpdGUpLiBBIG5haXZlIHBlci13cml0ZSBkZWVwLWVxdWFsIHNraXAgd291bGQgYmUgbW9yZSBleHBlbnNpdmVcbiAgICogYW5kIHdvdWxkIHN0aWxsIG1pc3Mgd3JpdGUtcmV2ZXJ0ICh0aGUgaW50ZXJtZWRpYXRlIHdyaXRlIGRpZmZlcnMgZnJvbSB0aGVcbiAgICogdmFsdWUgcHJlc2VudCBhdCB0aGUgbW9tZW50IG9mIHdyaXRpbmcpLlxuICAgKlxuICAgKiDilIDilIAgVFdPIEhPTkVTVCBUSUVSUyAoYnkgZGVzaWduIOKAlCBkbyBub3QgXCJ1bmlmeVwiIHRoZW0pIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgKiAgIOKAoiBjb21taXQgKGhlcmUpICAgPSBDSEFOR0UtbGV2ZWwg4oCUIHRydXRoZnVsIG5ldCBkZWx0YS4gRmVlZHMgdGhlIGNvbW1pdFxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgbG9nLCBjYXVzYWwgY2hhaW4sIG5hcnJhdGl2ZSwgYW5kIHRoZSBsZW5zIGhpZ2hsaWdodC5cbiAgICogICDigKIgYG9uV3JpdGVgIGV2ZW50ID0gT1AtbGV2ZWwg4oCUIGZpcmVzIG9uIEVWRVJZIHdyaXRlIGF0dGVtcHQgcmVnYXJkbGVzcyBvZlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgbmV0IGNoYW5nZS4gRmVlZHMgbWV0cmljcyAvIGJlaGF2aW91cmFsIG9ic2VydmFiaWxpdHlcbiAgICogICAgICAgICAgICAgICAgICAgICAgIChhIGRlYnVnZ2VyIHdhbnRzIHRvIHNlZSBcIndyb3RlIDIsIHRoZW4gcmV2ZXJ0ZWRcIikuXG4gICAqIGBvbldyaXRlYCBpcyB1bmNoYW5nZWQgYnkgdGhpcyBtZXRob2Q7IG9ubHkgdGhlIENPTU1JVCBiZWNvbWVzIGNoYW5nZS1vbmx5LlxuICAgKlxuICAgKiDilIDilIAgRU1QVFkgQ09NTUlUUyBBUkUgSU5URU5USU9OQUwg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAqIEEgc3RhZ2UgdGhhdCBuZXRzIG5vIGNoYW5nZSBjb21taXRzIGFuIEVNUFRZIHBhdGNoIOKAlCBOT1Qgbm90aGluZy5cbiAgICoge0BsaW5rIFN0YWdlQ29udGV4dC5jb21taXR9IHN0aWxsIHJlY29yZHMgdGhlIGJ1bmRsZSB1bmNvbmRpdGlvbmFsbHksIHNvXG4gICAqIGV2ZXJ5IGV4ZWN1dGVkIHN0YWdlIHJlbWFpbnMgYSB0aW1lLXRyYXZlbCBjdXJzb3Igc3RvcCAoaXRzIGBydW50aW1lU3RhZ2VJZGBcbiAgICogbWFya2VyIGlzIHByZXNlcnZlZCk7IG9ubHkgaXRzIFBBVENIIGlzIGVtcHR5LiBUaGlzIGlzIHdoYXQga2VlcHMgdGhlXG4gICAqIGNvbW1pdC1pbmRleGVkIHNsaWRlciBzdGFibGUgd2hpbGUgbWFraW5nIHRoZSBoaWdobGlnaHQgdHJ1dGhmdWwuXG4gICAqXG4gICAqIOKUgOKUgCBLTk9XTiBMSU1JVEFUSU9OUyAvIEZVVFVSRSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogICDigKIgRXhwbGljaXQga2V5IERFTEVUSU9OIGlzIHN0aWxsIHVucmVwcmVzZW50YWJsZSBpbiBNZW1vcnlQYXRjaCAoYSByZW1vdmVkXG4gICAqICAgICBrZXkgY2Fubm90IGJlIGV4cHJlc3NlZCkuIFNldHRpbmcgYSBrZXkgdG8gYHVuZGVmaW5lZGAgaXMgdHJlYXRlZCBhcyBhXG4gICAqICAgICBjaGFuZ2UgKHZhbHVlIGRpZmZlcnMgZnJvbSBiYXNlKSwgbm90IGEgZGVsZXRpb24uIFRyYWNrZWQgZm9yIGEgZnV0dXJlXG4gICAqICAgICBgZGVsZXRlYCB2ZXJiLlxuICAgKiAgIOKAoiBBcnJheS1tZXJnZSBkZWR1cCBpbiB7QGxpbmsgZGVlcFNtYXJ0TWVyZ2V9IHN0aWxsIHVzZXMgcmVmZXJlbmNlIGVxdWFsaXR5XG4gICAqICAgICAoYG5ldyBTZXRgKSwgc28gZGVlcC1lcXVhbCAqb2JqZWN0cyogaW4gYSBtZXJnZWQgYXJyYXkgYXJlIG5vdCBkZWR1cGVkLlxuICAgKiAgICAgT3J0aG9nb25hbCB0byB0aGlzIGNoYW5nZTsgdHJhY2tlZCBzZXBhcmF0ZWx5LlxuICAgKlxuICAgKiBSZXNldHMgdGhlIGJ1ZmZlciB0byBlbXB0eSBzdGF0ZSBhZnRlciBjb21taXQuXG4gICAqL1xuICBjb21taXQoKToge1xuICAgIG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2g7XG4gICAgdXBkYXRlczogTWVtb3J5UGF0Y2g7XG4gICAgcmVkYWN0ZWRQYXRoczogU2V0PHN0cmluZz47XG4gICAgdHJhY2U6IHsgcGF0aDogc3RyaW5nOyB2ZXJiOiAnc2V0JyB8ICdtZXJnZScgfVtdO1xuICB9IHtcbiAgICBjb25zdCBwYXlsb2FkID0gdGhpcy50b0NoYW5nZU9ubHlQYXlsb2FkKCk7XG5cbiAgICB0aGlzLm92ZXJ3cml0ZVBhdGNoID0ge307XG4gICAgdGhpcy51cGRhdGVQYXRjaCA9IHt9O1xuICAgIHRoaXMub3BUcmFjZS5sZW5ndGggPSAwO1xuICAgIHRoaXMucmVkYWN0ZWRQYXRocy5jbGVhcigpO1xuICAgIHRoaXMud29ya2luZ0NvcHkgPSB7fTtcblxuICAgIHJldHVybiBwYXlsb2FkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYnVpbGQgb3ZlcndyaXRlIC8gdXBkYXRlcyAvIHRyYWNlIGtlZXBpbmcgT05MWSBwYXRocyB3aG9zZSBmaW5hbCB2YWx1ZVxuICAgKiBkaWZmZXJzIGZyb20gdGhlIGJhc2UgdmFsdWUg4oCUIGkuZS4gdGhlIHN0YWdlJ3MgbmV0IGNoYW5nZS4gU2VlXG4gICAqIHtAbGluayBUcmFuc2FjdGlvbkJ1ZmZlci5jb21taXR9IGZvciB0aGUgcmF0aW9uYWxlLlxuICAgKlxuICAgKiBQYXRocyBhcmUgY29tcGFyZWQgYXQgdGhlIGV4YWN0IGdyYW51bGFyaXR5IHRoZXkgd2VyZSB3cml0dGVuIChlYWNoIHRyYWNlXG4gICAqIGVudHJ5J3MgcGF0aCksIGFnYWluc3QgYHdvcmtpbmdDb3B5YCAoZmluYWwpIHZzIGBiYXNlU25hcHNob3RgIChzdGFydCkuXG4gICAqIFN1cnZpdmluZyBgc2V0YCBwYXRocyBjb3B5IHRoZWlyIGZpbmFsIHZhbHVlIGZyb20gYG92ZXJ3cml0ZVBhdGNoYDtcbiAgICogc3Vydml2aW5nIGBtZXJnZWAgcGF0aHMgY29weSB0aGVpciBhY2N1bXVsYXRlZCBkZWx0YSBmcm9tIGB1cGRhdGVQYXRjaGAg4oCUXG4gICAqIHByZXNlcnZpbmcgdGhlIHNldC12cy1tZXJnZSB2ZXJiIHNvIHJlcGxheSAoe0BsaW5rIGFwcGx5U21hcnRNZXJnZX0pIGlzXG4gICAqIGJ5dGUtZm9yLWJ5dGUgaWRlbnRpY2FsIHRvIHJlY29yZGluZyBvbmx5IHRoZSByZWFsIGNoYW5nZXMuXG4gICAqL1xuICBwcml2YXRlIHRvQ2hhbmdlT25seVBheWxvYWQoKToge1xuICAgIG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2g7XG4gICAgdXBkYXRlczogTWVtb3J5UGF0Y2g7XG4gICAgcmVkYWN0ZWRQYXRoczogU2V0PHN0cmluZz47XG4gICAgdHJhY2U6IHsgcGF0aDogc3RyaW5nOyB2ZXJiOiAnc2V0JyB8ICdtZXJnZScgfVtdO1xuICB9IHtcbiAgICBjb25zdCBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoID0ge307XG4gICAgY29uc3QgdXBkYXRlczogTWVtb3J5UGF0Y2ggPSB7fTtcbiAgICBjb25zdCB0cmFjZTogeyBwYXRoOiBzdHJpbmc7IHZlcmI6ICdzZXQnIHwgJ21lcmdlJyB9W10gPSBbXTtcbiAgICBjb25zdCBzdXJ2aXZpbmdQYXRocyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgZm9yIChjb25zdCBvcCBvZiB0aGlzLm9wVHJhY2UpIHtcbiAgICAgIGNvbnN0IHNlZ21lbnRzID0gb3AucGF0aC5zcGxpdChERUxJTSk7XG4gICAgICBjb25zdCBiZWZvcmUgPSBfZ2V0KHRoaXMuYmFzZVNuYXBzaG90LCBzZWdtZW50cyk7XG4gICAgICBjb25zdCBhZnRlciA9IF9nZXQodGhpcy53b3JraW5nQ29weSwgc2VnbWVudHMpO1xuICAgICAgaWYgKGRlZXBFcXVhbChiZWZvcmUsIGFmdGVyKSkgY29udGludWU7IC8vIG5vLW9wIG9yIHdyaXRlLXRoZW4tcmV2ZXJ0IOKGkiBubyBuZXQgY2hhbmdlXG5cbiAgICAgIHRyYWNlLnB1c2gob3ApO1xuICAgICAgc3Vydml2aW5nUGF0aHMuYWRkKG9wLnBhdGgpO1xuICAgICAgaWYgKG9wLnZlcmIgPT09ICdzZXQnKSB7XG4gICAgICAgIF9zZXQob3ZlcndyaXRlLCBzZWdtZW50cywgc3RydWN0dXJlZENsb25lKF9nZXQodGhpcy5vdmVyd3JpdGVQYXRjaCwgc2VnbWVudHMpKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBfc2V0KHVwZGF0ZXMsIHNlZ21lbnRzLCBzdHJ1Y3R1cmVkQ2xvbmUoX2dldCh0aGlzLnVwZGF0ZVBhdGNoLCBzZWdtZW50cykpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZWRhY3RlZFBhdGhzID0gbmV3IFNldChbLi4udGhpcy5yZWRhY3RlZFBhdGhzXS5maWx0ZXIoKHBhdGgpID0+IHN1cnZpdmluZ1BhdGhzLmhhcyhwYXRoKSkpO1xuICAgIHJldHVybiB7IG92ZXJ3cml0ZSwgdXBkYXRlcywgcmVkYWN0ZWRQYXRocywgdHJhY2UgfTtcbiAgfVxufVxuIl19
316
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiVHJhbnNhY3Rpb25CdWZmZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvbGliL21lbW9yeS9UcmFuc2FjdGlvbkJ1ZmZlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBRUgsT0FBTyxFQUFFLFNBQVMsSUFBSSxJQUFJLEVBQUUsU0FBUyxJQUFJLElBQUksRUFBRSxNQUFNLGNBQWMsQ0FBQztBQUVwRSxPQUFPLEVBQUUsU0FBUyxFQUFFLGNBQWMsRUFBRSxLQUFLLEVBQUUsYUFBYSxFQUFFLE1BQU0sWUFBWSxDQUFDO0FBUTdFLE1BQU0sT0FBTyxpQkFBaUI7SUFDWCxZQUFZLENBQU07SUFDM0IsV0FBVyxDQUFNO0lBRWpCLGNBQWMsR0FBZ0IsRUFBRSxDQUFDO0lBQ2pDLFdBQVcsR0FBZ0IsRUFBRSxDQUFDO0lBQzlCLE9BQU8sR0FBcUMsRUFBRSxDQUFDO0lBQy9DLGFBQWEsR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQzFDLDBFQUEwRTtJQUN6RCxZQUFZLENBQW1CO0lBRWhELFlBQVksSUFBUyxFQUFFLGVBQWlDLE1BQU07UUFDNUQsSUFBSSxDQUFDLFlBQVksR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDMUMsSUFBSSxDQUFDLFdBQVcsR0FBRyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekMsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7SUFDbkMsQ0FBQztJQUVELDRDQUE0QztJQUM1QyxHQUFHLENBQUMsSUFBeUIsRUFBRSxLQUFVLEVBQUUsWUFBWSxHQUFHLEtBQUs7UUFDN0QsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLElBQUksRUFBRSxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUN4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ZSBTVEFHSU5HIGJ1ZmZlciBmb3Igc3RhdGUgbXV0YXRpb25zXG4gKlxuICogV2hhdCBpdCBJUzogYSBzdGFnaW5nIGJ1ZmZlciB3aXRoIHJlYWQteW91ci13cml0ZXMgYW5kIG5ldC1jaGFuZ2UgY29tbWl0cy5cbiAqIC0gQ2hhbmdlcyBhcmUgc3RhZ2VkIGhlcmUgZHVyaW5nIHN0YWdlIGV4ZWN1dGlvbiBhbmQgZmx1c2hlZCB0b1xuICogICBTaGFyZWRNZW1vcnkgaW4gT05FIGJhdGNoIHBlciBzdGFnZSAoYGNvbW1pdCgpYCkg4oCUIG90aGVyIHN0YWdlcyBhbmRcbiAqICAgcGFyYWxsZWwgc2libGluZ3MgbmV2ZXIgb2JzZXJ2ZSBhIHN0YWdlJ3MgaGFsZi1maW5pc2hlZCB3cml0ZXMuXG4gKiAtIFJlYWQtYWZ0ZXItd3JpdGUgY29uc2lzdGVuY3kgd2l0aGluIGEgc3RhZ2Ug4oCUIGEgc3RhZ2Ugc2VlcyBpdHMgb3duXG4gKiAgIHN0YWdlZCB3cml0ZXMgaW1tZWRpYXRlbHkuXG4gKiAtIGBjb21taXQoKWAgcmVjb3JkcyB0aGUgc3RhZ2UncyBORVQgY2hhbmdlIChzZWUge0BsaW5rIGNvbW1pdH0pLCBwbHVzIGFuXG4gKiAgIG9wZXJhdGlvbiB0cmFjZSBmb3IgZGV0ZXJtaW5pc3RpYyByZXBsYXkuXG4gKlxuICogV2hhdCBpdCBpcyBOT1Q6IGEgcm9sbGJhY2sgbWVjaGFuaXNtLiBEZXNwaXRlIHRoZSBuYW1lLCB0aGVyZSBpcyBub1xuICogYWJvcnQvcm9sbGJhY2sgcGF0aCDigJQgd2hlbiBhIHN0YWdlIFRIUk9XUywgdGhlIGVuZ2luZSBzdGlsbCBjb21taXRzXG4gKiBldmVyeXRoaW5nIHN0YWdlZCBzbyBmYXIgYmVmb3JlIHJlLXRocm93aW5nIChjb21taXQtb24tZXJyb3IgaW5cbiAqIGBGbG93Y2hhcnRUcmF2ZXJzZXJgKS4gVGhhdCBpcyBkZWxpYmVyYXRlOiB0aGUgYXVkaXQgdHJhaWwgbXVzdCByZWNvcmRcbiAqIHdoYXQgdGhlIGZhaWxpbmcgc3RhZ2UgY2hhbmdlZC4gRG8gbm90IHJlbHkgb24gXCJzdGFnZSBmYWlsZWQg4oaSIGl0c1xuICogd3JpdGVzIHZhbmlzaGVkXCIuXG4gKi9cblxuaW1wb3J0IHsgbmF0aXZlR2V0IGFzIF9nZXQsIG5hdGl2ZVNldCBhcyBfc2V0IH0gZnJvbSAnLi9wYXRoT3BzLmpzJztcbmltcG9ydCB0eXBlIHsgQ29tbWl0VmFsdWVzTW9kZSwgTWVtb3J5UGF0Y2gsIFRyYWNlRW50cnkgfSBmcm9tICcuL3R5cGVzLmpzJztcbmltcG9ydCB7IGRlZXBFcXVhbCwgZGVlcFNtYXJ0TWVyZ2UsIERFTElNLCBub3JtYWxpc2VQYXRoIH0gZnJvbSAnLi91dGlscy5qcyc7XG5cbi8qKiBPcC1sZXZlbCB2ZXJicyBzdGFnZWQgaW50byBgb3BUcmFjZWAuIGAnZGVsZXRlJ2AgaXMgc3RhZ2VkIGRpc3RpbmN0bHkgc29cbiAqICBkZWx0YS1tb2RlIGNvbW1pdHMgKCMxM2MtQikgY2FuIGVtaXQgYSByZWFsIGBkZWxldGVgIHRyYWNlIGVudHJ5OyB1bmRlclxuICogIHRoZSBkZWZhdWx0IGAnZnVsbCdgIG1vZGUgaXQgY29tbWl0cyBhcyBgJ3NldCdgIChvZiBgdW5kZWZpbmVkYCkg4oCUXG4gKiAgYnl0ZS1pZGVudGljYWwgdG8gdGhlIGhpc3RvcmljYWwgZmxhdHRlbmluZy4gKi9cbnR5cGUgT3BWZXJiID0gJ3NldCcgfCAnbWVyZ2UnIHwgJ2RlbGV0ZSc7XG5cbmV4cG9ydCBjbGFzcyBUcmFuc2FjdGlvbkJ1ZmZlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYmFzZVNuYXBzaG90OiBhbnk7XG4gIHByaXZhdGUgd29ya2luZ0NvcHk6IGFueTtcblxuICBwcml2YXRlIG92ZXJ3cml0ZVBhdGNoOiBNZW1vcnlQYXRjaCA9IHt9O1xuICBwcml2YXRlIHVwZGF0ZVBhdGNoOiBNZW1vcnlQYXRjaCA9IHt9O1xuICBwcml2YXRlIG9wVHJhY2U6IHsgcGF0aDogc3RyaW5nOyB2ZXJiOiBPcFZlcmIgfVtdID0gW107XG4gIHByaXZhdGUgcmVkYWN0ZWRQYXRocyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAvKiogQ29tbWl0LXZhbHVlIGVuY29kaW5nIHBvbGljeSAoIzEzYy1CKS4gYCdmdWxsJ2AgPSBoaXN0b3JpY2FsIGJ5dGVzLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbW1pdFZhbHVlczogQ29tbWl0VmFsdWVzTW9kZTtcblxuICBjb25zdHJ1Y3RvcihiYXNlOiBhbnksIGNvbW1pdFZhbHVlczogQ29tbWl0VmFsdWVzTW9kZSA9ICdmdWxsJykge1xuICAgIHRoaXMuYmFzZVNuYXBzaG90ID0gc3RydWN0dXJlZENsb25lKGJhc2UpO1xuICAgIHRoaXMud29ya2luZ0NvcHkgPSBzdHJ1Y3R1cmVkQ2xvbmUoYmFzZSk7XG4gICAgdGhpcy5jb21taXRWYWx1ZXMgPSBjb21taXRWYWx1ZXM7XG4gIH1cblxuICAvKiogSGFyZCBvdmVyd3JpdGUgYXQgdGhlIHNwZWNpZmllZCBwYXRoLiAqL1xuICBzZXQocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgdmFsdWU6IGFueSwgc2hvdWxkUmVkYWN0ID0gZmFsc2UpOiB2b2lkIHtcbiAgICBfc2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIHZhbHVlKTtcbiAgICBfc2V0KHRoaXMub3ZlcndyaXRlUGF0Y2gsIHBhdGgsIHN0cnVjdHVyZWRDbG9uZSh2YWx1ZSkpO1xuICAgIGlmIChzaG91bGRSZWRhY3QpIHtcbiAgICAgIHRoaXMucmVkYWN0ZWRQYXRocy5hZGQobm9ybWFsaXNlUGF0aChwYXRoKSk7XG4gICAgfVxuICAgIHRoaXMub3BUcmFjZS5wdXNoKHsgcGF0aDogbm9ybWFsaXNlUGF0aChwYXRoKSwgdmVyYjogJ3NldCcgfSk7XG4gIH1cblxuICAvKipcbiAgICogRXhwbGljaXQga2V5IGRlbGV0aW9uIGF0IHRoZSBzcGVjaWZpZWQgcGF0aCAoIzEzYy1COyBhYnNvcmJzIGJhY2tsb2cgQjgpLlxuICAgKlxuICAgKiBTdGFnZXMgRVhBQ1RMWSB0aGUgc2FtZSBidWZmZXIgbXV0YXRpb25zIGFzIGBzZXQocGF0aCwgdW5kZWZpbmVkKWAg4oCUXG4gICAqIGB3b3JraW5nQ29weWAvYG92ZXJ3cml0ZVBhdGNoYCBnZXQgYW4gb3duIGB1bmRlZmluZWRgIGF0IHRoZSBwYXRoICh0aGVcbiAgICogaGlzdG9yaWNhbCBmbGF0dGVuaW5nLCBwcmVzZXJ2aW5nIHJlYWQgYmVoYXZpb3IgYW5kIHRoZSBkZWR1cCBkaWZmIGJhc2VcbiAgICogYWNyb3NzIG1vZGVzKSDigJQgYnV0IHJlY29yZHMgdGhlIG9wIHZlcmIgYXMgYCdkZWxldGUnYC4gQXQgY29tbWl0OlxuICAgKiBgJ2Z1bGwnYCBtb2RlIG1hcHMgaXQgYmFjayB0byBhIGAnc2V0J2AgdHJhY2UgZW50cnkgKGJ5dGUtaWRlbnRpY2FsIHRvXG4gICAqIHRvZGF5KTsgYCdkZWx0YSdgIG1vZGUgZW1pdHMgYSByZWFsIGAnZGVsZXRlJ2AgZW50cnkgd2hvc2UgcmVwbGF5XG4gICAqIFJFTU9WRVMgdGhlIGtleSBpbnN0ZWFkIG9mIGxlYXZpbmcgYGtleTogdW5kZWZpbmVkYCBiZWhpbmQuXG4gICAqL1xuICBkZWxldGUocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgc2hvdWxkUmVkYWN0ID0gZmFsc2UpOiB2b2lkIHtcbiAgICBfc2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgsIHVuZGVmaW5lZCk7XG4gICAgX3NldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBwYXRoLCB1bmRlZmluZWQpO1xuICAgIGlmIChzaG91bGRSZWRhY3QpIHtcbiAgICAgIHRoaXMucmVkYWN0ZWRQYXRocy5hZGQobm9ybWFsaXNlUGF0aChwYXRoKSk7XG4gICAgfVxuICAgIHRoaXMub3BUcmFjZS5wdXNoKHsgcGF0aDogbm9ybWFsaXNlUGF0aChwYXRoKSwgdmVyYjogJ2RlbGV0ZScgfSk7XG4gIH1cblxuICAvKiogRGVlcCB1bmlvbiBtZXJnZSBhdCB0aGUgc3BlY2lmaWVkIHBhdGguICovXG4gIG1lcmdlKHBhdGg6IChzdHJpbmcgfCBudW1iZXIpW10sIHZhbHVlOiBhbnksIHNob3VsZFJlZGFjdCA9IGZhbHNlKTogdm9pZCB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSBfZ2V0KHRoaXMud29ya2luZ0NvcHksIHBhdGgpID8/IHt9O1xuICAgIGNvbnN0IG1lcmdlZCA9IGRlZXBTbWFydE1lcmdlKGV4aXN0aW5nLCB2YWx1ZSk7XG4gICAgX3NldCh0aGlzLndvcmtpbmdDb3B5LCBwYXRoLCBtZXJnZWQpO1xuICAgIF9zZXQodGhpcy51cGRhdGVQYXRjaCwgcGF0aCwgZGVlcFNtYXJ0TWVyZ2UoX2dldCh0aGlzLnVwZGF0ZVBhdGNoLCBwYXRoKSA/PyB7fSwgdmFsdWUpKTtcbiAgICBpZiAoc2hvdWxkUmVkYWN0KSB7XG4gICAgICB0aGlzLnJlZGFjdGVkUGF0aHMuYWRkKG5vcm1hbGlzZVBhdGgocGF0aCkpO1xuICAgIH1cbiAgICB0aGlzLm9wVHJhY2UucHVzaCh7IHBhdGg6IG5vcm1hbGlzZVBhdGgocGF0aCksIHZlcmI6ICdtZXJnZScgfSk7XG4gIH1cblxuICAvKiogUmVhZCBjdXJyZW50IHZhbHVlIGF0IHBhdGggKGluY2x1ZGVzIHVuY29tbWl0dGVkIGNoYW5nZXMpLiAqL1xuICBnZXQocGF0aDogKHN0cmluZyB8IG51bWJlcilbXSwgZGVmYXVsdFZhbHVlPzogYW55KSB7XG4gICAgcmV0dXJuIF9nZXQodGhpcy53b3JraW5nQ29weSwgcGF0aCwgZGVmYXVsdFZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGbHVzaCBhbGwgc3RhZ2VkIG11dGF0aW9ucyBhbmQgcmV0dXJuIHRoZSBjb21taXQgYnVuZGxlIOKAlCByZWNvcmRpbmcgdGhlXG4gICAqIHN0YWdlJ3MgTkVUIENIQU5HRSwgbm90IGl0cyByYXcgd3JpdGUgbG9nLlxuICAgKlxuICAgKiDilIDilIAgV0hZICh0aGUgZGVmZWN0IHRoaXMgZml4ZXMpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgKiBQcmV2aW91c2x5IGV2ZXJ5IGBzZXRgL2BtZXJnZWAgd2FzIHJlY29yZGVkIHZlcmJhdGltLCBzbyB0aGUgY29tbWl0IGJ1bmRsZVxuICAgKiB3YXMgYSBsb2cgb2YgKm9wZXJhdGlvbnMqIHJhdGhlciB0aGFuICpjaGFuZ2VzKi4gVHdvIG9wZXJhdGlvbnMgcHJvZHVjZSBub1xuICAgKiBuZXQgY2hhbmdlIHlldCB3ZXJlIHN0aWxsIGNvbW1pdHRlZCBhcyBcIm11dGF0aW9uc1wiOlxuICAgKlxuICAgKiAgIDEuIE5vLW9wIHdyaXRlICAg4oCUIHdyaXRpbmcgYSBrZXkgdGhlIHZhbHVlIGl0IGFscmVhZHkgaG9sZHMgKGUuZy4gYW5cbiAgICogICAgICAgICAgICAgICAgICAgICAgYWdlbnQgY29udGV4dCBzbG90IHJlLWVtaXR0aW5nIGlkZW50aWNhbCBjb250ZW50IGV2ZXJ5XG4gICAqICAgICAgICAgICAgICAgICAgICAgIHR1cm4pLiBiYXNlIEs9MSwgc3RhZ2Ugd3JpdGVzIEs9MS5cbiAgICogICAyLiBXcml0ZS1yZXZlcnQgIOKAlCBjaGFuZ2luZyB0aGVuIHJlc3RvcmluZyBhIGtleSB3aXRoaW4gb25lIHN0YWdlLlxuICAgKiAgICAgICAgICAgICAgICAgICAgICBiYXNlIEs9MSwgc3RhZ2Ugd3JpdGVzIEs9MiB0aGVuIEs9MS5cbiAgICpcbiAgICogUmVjb3JkaW5nIHRoZXNlIGFzIG11dGF0aW9ucyAoYSkgYmxvYXRlZCBjYXVzYWwgc2xpY2luZyAvIGJhY2t0cmFja2luZyB3aXRoXG4gICAqIHNwdXJpb3VzIGRlcGVuZGVuY2llcyBvbiBpbnRlcm1lZGlhdGUgdmFsdWVzIHRoYXQgbmV2ZXIgcmVhY2ggZmluYWwgc3RhdGUsXG4gICAqIGFuZCAoYikgbWFkZSBkb3duc3RyZWFtIFwid2hhdCBjaGFuZ2VkIGhlcmU/XCIgY29uc3VtZXJzIGxpZ2h0IHVwIHN0YWdlcyB0aGF0XG4gICAqIGNoYW5nZWQgbm90aGluZyDigJQgbW9zdCB2aXNpYmx5IHRoZSBsZW5zIGhpZ2hsaWdodCBmbGFnZ2luZyBldmVyeSBzbG90LlxuICAgKlxuICAgKiDilIDilIAgSE9XIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgKiBBdCBjb21taXQgd2UgaG9sZCBCT1RIIGBiYXNlU25hcHNob3RgIChzdGF0ZSB3aGVuIHRoZSBzdGFnZSBiZWdhbikgYW5kXG4gICAqIGB3b3JraW5nQ29weWAgKHN0YXRlIGFmdGVyIGFsbCBpdHMgd3JpdGVzKS4gRm9yIGVhY2ggcGF0aCB0aGUgc3RhZ2UgdG91Y2hlZFxuICAgKiB3ZSBrZWVwIGl0IGluIHRoZSBidW5kbGUgT05MWSBpZiBpdHMgZmluYWwgdmFsdWUgZGlmZmVycyBmcm9tIHRoZSBiYXNlXG4gICAqIHZhbHVlICh7QGxpbmsgZGVlcEVxdWFsfSkuIE5vLW9wIEFORCB3cml0ZS1yZXZlcnQgcGF0aHMgZHJvcCBvdXQsIGJlY2F1c2VcbiAgICogYm90aCBjb21wYXJlIGVxdWFsIHRvIGJhc2UuIFRoaXMgaXMgYSBzaW5nbGUgbmV0LWRlbHRhIGRpZmYgYXQgY29tbWl0IHRpbWVcbiAgICog4oCUIG9uZSBkZWVwIGNvbXBhcmUgcGVyIHRvdWNoZWQgcGF0aCwgTyhjaGFuZ2VkIHN0YXRlKSwgcGFpZCBvbmNlIHBlciBzdGFnZVxuICAgKiAoTk9UIHBlciB3cml0ZSkuIEEgbmFpdmUgcGVyLXdyaXRlIGRlZXAtZXF1YWwgc2tpcCB3b3VsZCBiZSBtb3JlIGV4cGVuc2l2ZVxuICAgKiBhbmQgd291bGQgc3RpbGwgbWlzcyB3cml0ZS1yZXZlcnQgKHRoZSBpbnRlcm1lZGlhdGUgd3JpdGUgZGlmZmVycyBmcm9tIHRoZVxuICAgKiB2YWx1ZSBwcmVzZW50IGF0IHRoZSBtb21lbnQgb2Ygd3JpdGluZykuXG4gICAqXG4gICAqIOKUgOKUgCBUV08gSE9ORVNUIFRJRVJTIChieSBkZXNpZ24g4oCUIGRvIG5vdCBcInVuaWZ5XCIgdGhlbSkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gICAqICAg4oCiIGNvbW1pdCAoaGVyZSkgICA9IENIQU5HRS1sZXZlbCDigJQgdHJ1dGhmdWwgbmV0IGRlbHRhLiBGZWVkcyB0aGUgY29tbWl0XG4gICAqICAgICAgICAgICAgICAgICAgICAgICBsb2csIGNhdXNhbCBjaGFpbiwgbmFycmF0aXZlLCBhbmQgdGhlIGxlbnMgaGlnaGxpZ2h0LlxuICAgKiAgIOKAoiBgb25Xcml0ZWAgZXZlbnQgPSBPUC1sZXZlbCDigJQgZmlyZXMgb24gRVZFUlkgd3JpdGUgYXR0ZW1wdCByZWdhcmRsZXNzIG9mXG4gICAqICAgICAgICAgICAgICAgICAgICAgICBuZXQgY2hhbmdlLiBGZWVkcyBtZXRyaWNzIC8gYmVoYXZpb3VyYWwgb2JzZXJ2YWJpbGl0eVxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgKGEgZGVidWdnZXIgd2FudHMgdG8gc2VlIFwid3JvdGUgMiwgdGhlbiByZXZlcnRlZFwiKS5cbiAgICogYG9uV3JpdGVgIGlzIHVuY2hhbmdlZCBieSB0aGlzIG1ldGhvZDsgb25seSB0aGUgQ09NTUlUIGJlY29tZXMgY2hhbmdlLW9ubHkuXG4gICAqXG4gICAqIOKUgOKUgCBFTVBUWSBDT01NSVRTIEFSRSBJTlRFTlRJT05BTCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgICogQSBzdGFnZSB0aGF0IG5ldHMgbm8gY2hhbmdlIGNvbW1pdHMgYW4gRU1QVFkgcGF0Y2gg4oCUIE5PVCBub3RoaW5nLlxuICAgKiB7QGxpbmsgU3RhZ2VDb250ZXh0LmNvbW1pdH0gc3RpbGwgcmVjb3JkcyB0aGUgYnVuZGxlIHVuY29uZGl0aW9uYWxseSwgc29cbiAgICogZXZlcnkgZXhlY3V0ZWQgc3RhZ2UgcmVtYWlucyBhIHRpbWUtdHJhdmVsIGN1cnNvciBzdG9wIChpdHMgYHJ1bnRpbWVTdGFnZUlkYFxuICAgKiBtYXJrZXIgaXMgcHJlc2VydmVkKTsgb25seSBpdHMgUEFUQ0ggaXMgZW1wdHkuIFRoaXMgaXMgd2hhdCBrZWVwcyB0aGVcbiAgICogY29tbWl0LWluZGV4ZWQgc2xpZGVyIHN0YWJsZSB3aGlsZSBtYWtpbmcgdGhlIGhpZ2hsaWdodCB0cnV0aGZ1bC5cbiAgICpcbiAgICog4pSA4pSAIEtOT1dOIExJTUlUQVRJT05TIC8gRlVUVVJFIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAgKiAgIOKAoiBFeHBsaWNpdCBrZXkgREVMRVRJT04gdW5kZXIgdGhlIGRlZmF1bHQgJ2Z1bGwnIG1vZGUgaXMgc3RpbGxcbiAgICogICAgIGZsYXR0ZW5lZCB0byBzZXQtb2YtYHVuZGVmaW5lZGAgKGEgcmVtb3ZlZCBrZXkgY2Fubm90IGJlIGV4cHJlc3NlZFxuICAgKiAgICAgaW4gTWVtb3J5UGF0Y2ggYWxvbmUpLiBDTE9TRUQgdW5kZXIgYGNvbW1pdFZhbHVlczogJ2RlbHRhJ2AgKCMxM2MtQik6XG4gICAqICAgICB7QGxpbmsgZGVsZXRlfSBzdGFnZXMgYSBkaXN0aW5jdCBvcCBhbmQgdGhlIGJ1bmRsZSBjYXJyaWVzIGEgcmVhbFxuICAgKiAgICAgYGRlbGV0ZWAgdHJhY2UgdmVyYiB3aG9zZSByZXBsYXkgcmVtb3ZlcyB0aGUga2V5LlxuICAgKiAgIOKAoiBBcnJheS1tZXJnZSBkZWR1cCBpbiB7QGxpbmsgZGVlcFNtYXJ0TWVyZ2V9IHN0aWxsIHVzZXMgcmVmZXJlbmNlIGVxdWFsaXR5XG4gICAqICAgICAoYG5ldyBTZXRgKSwgc28gZGVlcC1lcXVhbCAqb2JqZWN0cyogaW4gYSBtZXJnZWQgYXJyYXkgYXJlIG5vdCBkZWR1cGVkLlxuICAgKiAgICAgT3J0aG9nb25hbCB0byB0aGlzIGNoYW5nZTsgdHJhY2tlZCBzZXBhcmF0ZWx5LlxuICAgKlxuICAgKiBSZXNldHMgdGhlIGJ1ZmZlciB0byBlbXB0eSBzdGF0ZSBhZnRlciBjb21taXQuXG4gICAqL1xuICBjb21taXQoKToge1xuICAgIG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2g7XG4gICAgdXBkYXRlczogTWVtb3J5UGF0Y2g7XG4gICAgcmVkYWN0ZWRQYXRoczogU2V0PHN0cmluZz47XG4gICAgdHJhY2U6IFRyYWNlRW50cnlbXTtcbiAgfSB7XG4gICAgY29uc3QgcGF5bG9hZCA9IHRoaXMuY29tbWl0VmFsdWVzID09PSAnZGVsdGEnID8gdGhpcy50b0RlbHRhUGF5bG9hZCgpIDogdGhpcy50b0NoYW5nZU9ubHlQYXlsb2FkKCk7XG5cbiAgICB0aGlzLm92ZXJ3cml0ZVBhdGNoID0ge307XG4gICAgdGhpcy51cGRhdGVQYXRjaCA9IHt9O1xuICAgIHRoaXMub3BUcmFjZS5sZW5ndGggPSAwO1xuICAgIHRoaXMucmVkYWN0ZWRQYXRocy5jbGVhcigpO1xuICAgIHRoaXMud29ya2luZ0NvcHkgPSB7fTtcblxuICAgIHJldHVybiBwYXlsb2FkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlYnVpbGQgb3ZlcndyaXRlIC8gdXBkYXRlcyAvIHRyYWNlIGtlZXBpbmcgT05MWSBwYXRocyB3aG9zZSBmaW5hbCB2YWx1ZVxuICAgKiBkaWZmZXJzIGZyb20gdGhlIGJhc2UgdmFsdWUg4oCUIGkuZS4gdGhlIHN0YWdlJ3MgbmV0IGNoYW5nZS4gU2VlXG4gICAqIHtAbGluayBUcmFuc2FjdGlvbkJ1ZmZlci5jb21taXR9IGZvciB0aGUgcmF0aW9uYWxlLlxuICAgKlxuICAgKiBQYXRocyBhcmUgY29tcGFyZWQgYXQgdGhlIGV4YWN0IGdyYW51bGFyaXR5IHRoZXkgd2VyZSB3cml0dGVuIChlYWNoIHRyYWNlXG4gICAqIGVudHJ5J3MgcGF0aCksIGFnYWluc3QgYHdvcmtpbmdDb3B5YCAoZmluYWwpIHZzIGBiYXNlU25hcHNob3RgIChzdGFydCkuXG4gICAqIFN1cnZpdmluZyBgc2V0YCBwYXRocyBjb3B5IHRoZWlyIGZpbmFsIHZhbHVlIGZyb20gYG92ZXJ3cml0ZVBhdGNoYDtcbiAgICogc3Vydml2aW5nIGBtZXJnZWAgcGF0aHMgY29weSB0aGVpciBhY2N1bXVsYXRlZCBkZWx0YSBmcm9tIGB1cGRhdGVQYXRjaGAg4oCUXG4gICAqIHByZXNlcnZpbmcgdGhlIHNldC12cy1tZXJnZSB2ZXJiIHNvIHJlcGxheSAoe0BsaW5rIGFwcGx5U21hcnRNZXJnZX0pIGlzXG4gICAqIGJ5dGUtZm9yLWJ5dGUgaWRlbnRpY2FsIHRvIHJlY29yZGluZyBvbmx5IHRoZSByZWFsIGNoYW5nZXMuXG4gICAqXG4gICAqIFRoaXMgaXMgdGhlIERFRkFVTFQgKGBjb21taXRWYWx1ZXM6ICdmdWxsJ2ApIHBheWxvYWQg4oCUIGJ5dGUtaWRlbnRpY2FsIHRvXG4gICAqIHRoZSBoaXN0b3JpY2FsIGJlaGF2aW9yLCBpbmNsdWRpbmcgZmxhdHRlbmluZyBzdGFnZWQgYGRlbGV0ZWAgb3BzIGludG9cbiAgICogYHNldGAtb2YtYHVuZGVmaW5lZGAgdHJhY2UgZW50cmllcy4gVGhlIGRlbHRhIGVuY29kaW5nIGxpdmVzIGluXG4gICAqIHtAbGluayB0b0RlbHRhUGF5bG9hZH0uXG4gICAqL1xuICBwcml2YXRlIHRvQ2hhbmdlT25seVBheWxvYWQoKToge1xuICAgIG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2g7XG4gICAgdXBkYXRlczogTWVtb3J5UGF0Y2g7XG4gICAgcmVkYWN0ZWRQYXRoczogU2V0PHN0cmluZz47XG4gICAgdHJhY2U6IFRyYWNlRW50cnlbXTtcbiAgfSB7XG4gICAgY29uc3Qgb3ZlcndyaXRlOiBNZW1vcnlQYXRjaCA9IHt9O1xuICAgIGNvbnN0IHVwZGF0ZXM6IE1lbW9yeVBhdGNoID0ge307XG4gICAgY29uc3QgdHJhY2U6IFRyYWNlRW50cnlbXSA9IFtdO1xuICAgIGNvbnN0IHN1cnZpdmluZ1BhdGhzID0gbmV3IFNldDxzdHJpbmc+KCk7XG5cbiAgICBmb3IgKGNvbnN0IG9wIG9mIHRoaXMub3BUcmFjZSkge1xuICAgICAgY29uc3Qgc2VnbWVudHMgPSBvcC5wYXRoLnNwbGl0KERFTElNKTtcbiAgICAgIGNvbnN0IGJlZm9yZSA9IF9nZXQodGhpcy5iYXNlU25hcHNob3QsIHNlZ21lbnRzKTtcbiAgICAgIGNvbnN0IGFmdGVyID0gX2dldCh0aGlzLndvcmtpbmdDb3B5LCBzZWdtZW50cyk7XG4gICAgICBpZiAoZGVlcEVxdWFsKGJlZm9yZSwgYWZ0ZXIpKSBjb250aW51ZTsgLy8gbm8tb3Agb3Igd3JpdGUtdGhlbi1yZXZlcnQg4oaSIG5vIG5ldCBjaGFuZ2VcblxuICAgICAgLy8gSGlzdG9yaWNhbCBmbGF0dGVuaW5nOiBhbiBleHBsaWNpdCBkZWxldGUgY29tbWl0cyBhcyBzZXQtb2YtdW5kZWZpbmVkLlxuICAgICAgdHJhY2UucHVzaChvcC52ZXJiID09PSAnZGVsZXRlJyA/IHsgcGF0aDogb3AucGF0aCwgdmVyYjogJ3NldCcgfSA6IG9wKTtcbiAgICAgIHN1cnZpdmluZ1BhdGhzLmFkZChvcC5wYXRoKTtcbiAgICAgIGlmIChvcC52ZXJiID09PSAnbWVyZ2UnKSB7XG4gICAgICAgIF9zZXQodXBkYXRlcywgc2VnbWVudHMsIHN0cnVjdHVyZWRDbG9uZShfZ2V0KHRoaXMudXBkYXRlUGF0Y2gsIHNlZ21lbnRzKSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgX3NldChvdmVyd3JpdGUsIHNlZ21lbnRzLCBzdHJ1Y3R1cmVkQ2xvbmUoX2dldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBzZWdtZW50cykpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZWRhY3RlZFBhdGhzID0gbmV3IFNldChbLi4udGhpcy5yZWRhY3RlZFBhdGhzXS5maWx0ZXIoKHBhdGgpID0+IHN1cnZpdmluZ1BhdGhzLmhhcyhwYXRoKSkpO1xuICAgIHJldHVybiB7IG92ZXJ3cml0ZSwgdXBkYXRlcywgcmVkYWN0ZWRQYXRocywgdHJhY2UgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBEZWx0YS1lbmNvZGVkIHBheWxvYWQgKGBjb21taXRWYWx1ZXM6ICdkZWx0YSdgLCAjMTNjLUIpIOKAlCBzYW1lIG5ldC1jaGFuZ2VcbiAgICogZmlsdGVyIGFzIHtAbGluayB0b0NoYW5nZU9ubHlQYXlsb2FkfSwgdHdvIGVuY29kaW5nIGRpZmZlcmVuY2VzOlxuICAgKlxuICAgKiAxLiAqKk9uZSB0cmFjZSBlbnRyeSBwZXIgc3Vydml2aW5nIHBhdGgqKiAodGhlIMKnMi41IGRlZHVwIHJ1bGUg4oCUIGBhcHBlbmRgXG4gICAqICAgIGlzIE5PVCBpZGVtcG90ZW50IG9uIHJlcGxheSwgc28gZHVwbGljYXRlIGVudHJpZXMgd291bGQgbXVsdGlwbHlcbiAgICogICAgdGFpbHMpLiBUaGUgdmVyYiBpcyByZXNvbHZlZCBmcm9tIHRoZSBwYXRoJ3Mgb3AgbWl4ICsgYmFzZeKGkmZpbmFsXG4gICAqICAgIHJlbGF0aW9uc2hpcDsgZW50cmllcyBhcmUgb3JkZXJlZCBieSBlYWNoIHBhdGgncyBMQVNUIHRvdWNoLFxuICAgKiAgICBwcmVzZXJ2aW5nIGxhc3Qtd3JpdGVyLXdpbnMgZm9yIG5lc3RlZC9vdmVybGFwcGluZyBwYXRocy5cbiAgICogMi4gKipWZXJiIHJlc29sdXRpb24gcGVyIHBhdGgqKjpcbiAgICogICAgLSBsYXN0IG9wIGAnZGVsZXRlJ2AgQU5EIGZpbmFsIHZhbHVlIGdvbmUg4oaSIGBkZWxldGVgICh0aGUgcGF0aCBzdGF5c1xuICAgKiAgICAgIGVudW1lcmF0ZWQgaW4gYG92ZXJ3cml0ZWAgd2l0aCBgdW5kZWZpbmVkYCBmb3Iga2V5LXNldCBjb25zdW1lcnMpO1xuICAgKiAgICAtIE9OTFkgYCdtZXJnZSdgIG9wcyDihpIgYG1lcmdlYCB3aXRoIHRoZSBhY2N1bXVsYXRlZCBgdXBkYXRlUGF0Y2hgXG4gICAqICAgICAgZGVsdGEgKHJlcGxheWluZyB0aGUgYWNjdW11bGF0ZWQgZGVsdGEgb25jZSDiiaEgdGhlIGZ1bGwgbW9kZSdzXG4gICAqICAgICAgayBzZXF1ZW50aWFsIHJlcGxheXMg4oCUIGBkZWVwU21hcnRNZXJnZWAgaXMgcmVmZXJlbmNlLWlkZW1wb3RlbnRcbiAgICogICAgICB3aXRoaW4gb25lIHJlcGxheSBwYXNzKTtcbiAgICogICAgLSBvdGhlcndpc2UgKGBzZXRgL21peGVkKTogdGhlIGNvbW1pdHRlZCB2YWx1ZSBpcyBjb21wdXRlZCBieVxuICAgKiAgICAgIHJlcGxheWluZyB0aGUgcGF0aCdzIG9wIHNlcXVlbmNlIEVYQUNUTFkgdGhlIHdheSBgYXBwbHlTbWFydE1lcmdlYFxuICAgKiAgICAgIHJlcGxheXMgdGhlIGZ1bGwtbW9kZSBidW5kbGUgKHtAbGluayByZXBsYXlQYXRoVmVyYnN9KSDigJQgZm9yXG4gICAqICAgICAgcHVyZS1zZXQgcGF0aHMgdGhhdCBpcyBzaW1wbHkgdGhlIGxhc3Qgc2V0IHZhbHVlOyBmb3IgbWl4ZWRcbiAgICogICAgICBzZXQrbWVyZ2UgaW50ZXJsZWF2aW5ncyBpdCByZXByb2R1Y2VzIHRoZSBmdWxsIG1vZGUncyBxdWlyayBvZlxuICAgKiAgICAgIGFwcGx5aW5nIHRoZSBBQ0NVTVVMQVRFRCBtZXJnZSBkZWx0YSBhdCBldmVyeSBtZXJnZSBwb3NpdGlvblxuICAgKiAgICAgICh3aGljaCBjYW4gZGlmZmVyIGZyb20gdGhlIGJ1ZmZlcidzIHJlYWQteW91ci13cml0ZXMgdmlldzsgcGFyaXR5XG4gICAqICAgICAgd2l0aCB0aGUgYCdmdWxsJ2AgbW9kZSdzIGNvbW1pdHRlZCBzdGF0ZSBpcyB0aGUgY29udHJhY3QpLiBJZiBiYXNlXG4gICAqICAgICAgYW5kIHRoYXQgdmFsdWUgYXJlIGFycmF5cyBhbmQgYmFzZSBpcyBhIFNUUklDVCBQUkVGSVgg4oaSIGBhcHBlbmRgXG4gICAqICAgICAgc3RvcmluZyBvbmx5IHRoZSB0YWlsOyBlbHNlIGBzZXRgIHN0b3JpbmcgdGhlIGZ1bGwgdmFsdWUuXG4gICAqXG4gICAqIExvc3NsZXNzbmVzcyBuZXZlciBkZXBlbmRzIG9uIGRldGVjdGlvbiBzdWNjZWVkaW5nIOKAlCBldmVyeSBmYWxsYmFjayBpc1xuICAgKiB0b2RheSdzIGZ1bGwtdmFsdWUgYHNldGAuXG4gICAqL1xuICBwcml2YXRlIHRvRGVsdGFQYXlsb2FkKCk6IHtcbiAgICBvdmVyd3JpdGU6IE1lbW9yeVBhdGNoO1xuICAgIHVwZGF0ZXM6IE1lbW9yeVBhdGNoO1xuICAgIHJlZGFjdGVkUGF0aHM6IFNldDxzdHJpbmc+O1xuICAgIHRyYWNlOiBUcmFjZUVudHJ5W107XG4gIH0ge1xuICAgIGNvbnN0IG92ZXJ3cml0ZTogTWVtb3J5UGF0Y2ggPSB7fTtcbiAgICBjb25zdCB1cGRhdGVzOiBNZW1vcnlQYXRjaCA9IHt9O1xuICAgIGNvbnN0IHRyYWNlOiBUcmFjZUVudHJ5W10gPSBbXTtcbiAgICBjb25zdCBzdXJ2aXZpbmdQYXRocyA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuXG4gICAgLy8gUGF0aCDihpIgaXRzIG9wLXZlcmIgc2VxdWVuY2UsIG9yZGVyZWQgYnkgTEFTVCB0b3VjaCAoZGVsZXRlICtcbiAgICAvLyByZS1pbnNlcnQgbW92ZXMgYSByZS10b3VjaGVkIHBhdGggdG8gdGhlIGVuZCBvZiB0aGUgTWFwJ3MgaW5zZXJ0aW9uXG4gICAgLy8gb3JkZXIg4oCUIHByZXNlcnZpbmcgbGFzdC13cml0ZXItd2lucyBmb3IgbmVzdGVkL292ZXJsYXBwaW5nIHBhdGhzKS5cbiAgICBjb25zdCBieVBhdGggPSBuZXcgTWFwPHN0cmluZywgT3BWZXJiW10+KCk7XG4gICAgZm9yIChjb25zdCBvcCBvZiB0aGlzLm9wVHJhY2UpIHtcbiAgICAgIGNvbnN0IHByZXYgPSBieVBhdGguZ2V0KG9wLnBhdGgpO1xuICAgICAgaWYgKHByZXYpIHtcbiAgICAgICAgcHJldi5wdXNoKG9wLnZlcmIpO1xuICAgICAgICBieVBhdGguZGVsZXRlKG9wLnBhdGgpO1xuICAgICAgICBieVBhdGguc2V0KG9wLnBhdGgsIHByZXYpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnlQYXRoLnNldChvcC5wYXRoLCBbb3AudmVyYl0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3QgW3BhdGgsIHZlcmJzXSBvZiBieVBhdGgpIHtcbiAgICAgIGNvbnN0IHNlZ21lbnRzID0gcGF0aC5zcGxpdChERUxJTSk7XG4gICAgICBjb25zdCBiZWZvcmUgPSBfZ2V0KHRoaXMuYmFzZVNuYXBzaG90LCBzZWdtZW50cyk7XG4gICAgICBjb25zdCBhZnRlciA9IF9nZXQodGhpcy53b3JraW5nQ29weSwgc2VnbWVudHMpO1xuICAgICAgaWYgKGRlZXBFcXVhbChiZWZvcmUsIGFmdGVyKSkgY29udGludWU7IC8vIG5vLW9wIG9yIHdyaXRlLXRoZW4tcmV2ZXJ0IOKGkiBubyBuZXQgY2hhbmdlIChzYW1lIGZpbHRlciBhcyAnZnVsbCcpXG5cbiAgICAgIHN1cnZpdmluZ1BhdGhzLmFkZChwYXRoKTtcbiAgICAgIGNvbnN0IGxhc3RWZXJiID0gdmVyYnNbdmVyYnMubGVuZ3RoIC0gMV07XG4gICAgICBpZiAobGFzdFZlcmIgPT09ICdkZWxldGUnICYmIGFmdGVyID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgLy8gUmVhbCBkZWxldGlvbiDigJQgcmVwbGF5IHJlbW92ZXMgdGhlIGtleS4gS2VlcCB0aGUgcGF0aCBlbnVtZXJhdGVkXG4gICAgICAgIC8vIGluIGBvdmVyd3JpdGVgICh1bmRlZmluZWQpIHNvIE9iamVjdC5rZXlzIGNvbnN1bWVycyBzZWUgaXQuXG4gICAgICAgIHRyYWNlLnB1c2goeyBwYXRoLCB2ZXJiOiAnZGVsZXRlJyB9KTtcbiAgICAgICAgX3NldChvdmVyd3JpdGUsIHNlZ21lbnRzLCB1bmRlZmluZWQpO1xuICAgICAgfSBlbHNlIGlmICh2ZXJicy5ldmVyeSgodikgPT4gdiA9PT0gJ21lcmdlJykpIHtcbiAgICAgICAgdHJhY2UucHVzaCh7IHBhdGgsIHZlcmI6ICdtZXJnZScgfSk7XG4gICAgICAgIF9zZXQodXBkYXRlcywgc2VnbWVudHMsIHN0cnVjdHVyZWRDbG9uZShfZ2V0KHRoaXMudXBkYXRlUGF0Y2gsIHNlZ21lbnRzKSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQ29tbWl0dGVkLWVxdWl2YWxlbnQgdmFsdWU6IHJlcGxheSB0aGlzIHBhdGgncyBvcCBzZXF1ZW5jZSB0aGUgd2F5XG4gICAgICAgIC8vIGFwcGx5U21hcnRNZXJnZSByZXBsYXlzIHRoZSBGVUxMLW1vZGUgYnVuZGxlLCBzbyBib3RoIG1vZGVzIGNvbW1pdFxuICAgICAgICAvLyBieXRlLWlkZW50aWNhbCBzdGF0ZSAoc2VlIHRoZSBtZXRob2QgSlNEb2MpLlxuICAgICAgICBjb25zdCBjb21taXR0ZWQgPSB0aGlzLnJlcGxheVBhdGhWZXJicyhiZWZvcmUsIHNlZ21lbnRzLCB2ZXJicyk7XG4gICAgICAgIGlmIChpc1N0cmljdEFycmF5UHJlZml4KGJlZm9yZSwgY29tbWl0dGVkKSkge1xuICAgICAgICAgIHRyYWNlLnB1c2goeyBwYXRoLCB2ZXJiOiAnYXBwZW5kJyB9KTtcbiAgICAgICAgICBfc2V0KG92ZXJ3cml0ZSwgc2VnbWVudHMsIHN0cnVjdHVyZWRDbG9uZSgoY29tbWl0dGVkIGFzIHVua25vd25bXSkuc2xpY2UoKGJlZm9yZSBhcyB1bmtub3duW10pLmxlbmd0aCkpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0cmFjZS5wdXNoKHsgcGF0aCwgdmVyYjogJ3NldCcgfSk7XG4gICAgICAgICAgX3NldChvdmVyd3JpdGUsIHNlZ21lbnRzLCBzdHJ1Y3R1cmVkQ2xvbmUoY29tbWl0dGVkKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCByZWRhY3RlZFBhdGhzID0gbmV3IFNldChbLi4udGhpcy5yZWRhY3RlZFBhdGhzXS5maWx0ZXIoKHBhdGgpID0+IHN1cnZpdmluZ1BhdGhzLmhhcyhwYXRoKSkpO1xuICAgIHJldHVybiB7IG92ZXJ3cml0ZSwgdXBkYXRlcywgcmVkYWN0ZWRQYXRocywgdHJhY2UgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYXkgT05FIHBhdGgncyBvcC12ZXJiIHNlcXVlbmNlIGFnYWluc3QgaXRzIGJhc2UgdmFsdWUsIGV4YWN0bHkgdGhlXG4gICAqIHdheSBgYXBwbHlTbWFydE1lcmdlYCByZXBsYXlzIHRoZSBjb3JyZXNwb25kaW5nIGZ1bGwtbW9kZSBidW5kbGU6IGV2ZXJ5XG4gICAqIGBzZXRgL2BkZWxldGVgIHBvc2l0aW9uIGFwcGxpZXMgdGhlIExBU1Qgc3RhZ2VkIG92ZXJ3cml0ZSB2YWx1ZSAodGhlXG4gICAqIGJhZyBob2xkcyBvbmUgdmFsdWUgcGVyIHBhdGgg4oCUIGxhc3Qgd3JpdGVyIHdpbnMpLCBldmVyeSBgbWVyZ2VgXG4gICAqIHBvc2l0aW9uIGFwcGxpZXMgdGhlIEFDQ1VNVUxBVEVEIGB1cGRhdGVQYXRjaGAgZGVsdGEuIFRoaXMgcmVwcm9kdWNlc1xuICAgKiB0aGUgZnVsbCBtb2RlJ3MgY29tbWl0dGVkIHZhbHVlIGZvciBhbnkgaW50ZXJsZWF2aW5nIOKAlCBpbmNsdWRpbmcgdGhlXG4gICAqIG1peGVkIHNldCttZXJnZSBxdWlyayB3aGVyZSB0aGUgYWNjdW11bGF0ZWQgZGVsdGEgcmUtYXBwbGllcyBwcmUtc2V0XG4gICAqIG1lcmdlIGtleXMgKGZ1bGwtbW9kZSByZXBsYXkgc2VtYW50aWNzLCBrZXB0IGZvciBieXRlLXBhcml0eSBhY3Jvc3NcbiAgICogbW9kZXM7IHByb3BlcnR5LXRlc3RlZCBpbiBkZWx0YS1yZXBsYXktZXF1aXZhbGVuY2UpLlxuICAgKi9cbiAgcHJpdmF0ZSByZXBsYXlQYXRoVmVyYnMoYmVmb3JlOiB1bmtub3duLCBzZWdtZW50czogc3RyaW5nW10sIHZlcmJzOiBPcFZlcmJbXSk6IHVua25vd24ge1xuICAgIGNvbnN0IHNldFZhbHVlID0gX2dldCh0aGlzLm92ZXJ3cml0ZVBhdGNoLCBzZWdtZW50cyk7XG4gICAgY29uc3QgbWVyZ2VEZWx0YSA9IF9nZXQodGhpcy51cGRhdGVQYXRjaCwgc2VnbWVudHMpO1xuICAgIGxldCB2YWx1ZTogdW5rbm93biA9IGJlZm9yZTtcbiAgICBmb3IgKGNvbnN0IHZlcmIgb2YgdmVyYnMpIHtcbiAgICAgIHZhbHVlID0gdmVyYiA9PT0gJ21lcmdlJyA/IGRlZXBTbWFydE1lcmdlKHZhbHVlID8/IHt9LCBtZXJnZURlbHRhKSA6IHNldFZhbHVlO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cbn1cblxuLyoqXG4gKiBBcHBlbmQtZGV0ZWN0aW9uIHByZWRpY2F0ZSAoIzEzYy1CIMKnMi4yKTogYm90aCB2YWx1ZXMgYXJlIGFycmF5cywgdGhlXG4gKiBmaW5hbCBpcyBzdHJpY3RseSBsb25nZXIsIGFuZCB0aGUgYmFzZSBpcyBhIHN0cnVjdHVyYWwgcHJlZml4IG9mIHRoZVxuICogZmluYWwuIEVsZW1lbnQgY29tcGFyZXMgc2hvcnQtY2lyY3VpdCBvbiByZWZlcmVuY2UgaWRlbnRpdHkgKGBkZWVwRXF1YWxgJ3NcbiAqIGA9PT1gIGZhc3QgcGF0aCkgYmVmb3JlIHdhbGtpbmcgc3RydWN0dXJlLCBhbmQgYmFpbCBhdCB0aGUgZmlyc3QgbWlzbWF0Y2hcbiAqIOKAlCB3b3JzdCBjYXNlIG9uZSBzdHJ1Y3R1cmFsIGNvbXBhcmUgb2YgdGhlIGJhc2UgYXJyYXksIHN0cmljdGx5IGNoZWFwZXJcbiAqIHRoYW4gdGhlIGZ1bGwtdmFsdWUgYHN0cnVjdHVyZWRDbG9uZWAgdGhlIGZhbGxiYWNrIHBheXMuXG4gKlxuICogYGJlZm9yZSA9PT0gdW5kZWZpbmVkYCAoZmlyc3Qgd3JpdGUpIGZhaWxzIGBBcnJheS5pc0FycmF5YCDihpIgYHNldGAsIHdoaWNoXG4gKiBrZWVwcyB0aGUgZmlyc3Qgd3JpdGUgYXMgdGhlIGNhdXNhbCBhbmNob3IgZm9yIFwid2hvIGluaXRpYWxpemVkIHRoaXMga2V5XCIuXG4gKi9cbmZ1bmN0aW9uIGlzU3RyaWN0QXJyYXlQcmVmaXgoYmVmb3JlOiB1bmtub3duLCBhZnRlcjogdW5rbm93bik6IGJlZm9yZSBpcyB1bmtub3duW10ge1xuICBpZiAoIUFycmF5LmlzQXJyYXkoYmVmb3JlKSB8fCAhQXJyYXkuaXNBcnJheShhZnRlcikpIHJldHVybiBmYWxzZTtcbiAgaWYgKGFmdGVyLmxlbmd0aCA8PSBiZWZvcmUubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYmVmb3JlLmxlbmd0aDsgaSsrKSB7XG4gICAgaWYgKCFkZWVwRXF1YWwoYmVmb3JlW2ldLCBhZnRlcltpXSkpIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==