footprintjs 9.23.0 → 9.23.2

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.
@@ -38,9 +38,9 @@
38
38
  *
39
39
  * Now an indexed read of a wrappable element returns an ELEMENT PROXY that
40
40
  * accumulates the path inside the element and, on write, rebuilds the array
41
- * immutably ({@link setInPath}) and hands the whole new array to `commit` —
42
- * the same funnel `push` already used. One write path for the whole array,
43
- * whatever depth it is addressed at.
41
+ * immutably (`structuralWrite.setInPath`, behind `writeTraps.elementSink`)
42
+ * and hands the whole new array to `commit` — the same funnel `push` already
43
+ * used. One write path for the whole array, whatever depth it is addressed at.
44
44
  *
45
45
  * ── What is still NOT seen (by design) ───────────────────────────────────
46
46
  * Elements reached WITHOUT an index — `find()`, `filter()`, `for…of`,
@@ -50,10 +50,30 @@
50
50
  * not lost in silence either: `StageContext` compares what a stage READ with
51
51
  * what the value holds at commit and, in dev mode, warns with the exact path.
52
52
  * See src/lib/reactive/README.md.
53
+ *
54
+ * ── Shape (9.23.1) ───────────────────────────────────────────────────────
55
+ * `createArrayProxy` and `createElementProxy` are ORCHESTRATORS: they wire
56
+ * traps and hold the caches. Every trap body is a named leaf below — one
57
+ * concern each — and the element proxy's set/delete/get traps are the SAME
58
+ * leaves the nested and terminal object proxies use (`writeTraps.ts`,
59
+ * `liveView.ts`), over an {@link elementSink}. A fix lands in a leaf once.
60
+ */
61
+ import { type WriteSink } from './writeTraps.js';
62
+ /**
63
+ * WHY: an array anywhere below a sink's root is ONE write path — it reads
64
+ * through the sink and commits the WHOLE new array back through it, so
65
+ * `push` three levels down and `arr[i].x = v` at the top share a funnel.
53
66
  */
67
+ export declare function arrayProxyAt(sink: WriteSink, path: readonly string[]): unknown[];
54
68
  /**
55
69
  * Creates a Proxy over an array that intercepts mutating operations.
56
70
  *
71
+ * The actual current array is the Proxy target: Node.js console.log inspects
72
+ * the target directly (bypasses Proxy traps), so the real array shows correct
73
+ * values. The target reference is fixed at creation time — after mutations,
74
+ * the proxy returns a new proxy (via cache invalidation) with the fresh array
75
+ * as target.
76
+ *
57
77
  * @param getCurrent - Returns the current array snapshot from state
58
78
  * @param commit - Called with the new array after a mutation (triggers setValue)
59
79
  * @returns Proxied array with copy-on-write semantics
@@ -38,9 +38,9 @@
38
38
  *
39
39
  * Now an indexed read of a wrappable element returns an ELEMENT PROXY that
40
40
  * accumulates the path inside the element and, on write, rebuilds the array
41
- * immutably ({@link setInPath}) and hands the whole new array to `commit` —
42
- * the same funnel `push` already used. One write path for the whole array,
43
- * whatever depth it is addressed at.
41
+ * immutably (`structuralWrite.setInPath`, behind `writeTraps.elementSink`)
42
+ * and hands the whole new array to `commit` — the same funnel `push` already
43
+ * used. One write path for the whole array, whatever depth it is addressed at.
44
44
  *
45
45
  * ── What is still NOT seen (by design) ───────────────────────────────────
46
46
  * Elements reached WITHOUT an index — `find()`, `filter()`, `for…of`,
@@ -50,12 +50,18 @@
50
50
  * not lost in silence either: `StageContext` compares what a stage READ with
51
51
  * what the value holds at commit and, in dev mode, warns with the exact path.
52
52
  * See src/lib/reactive/README.md.
53
+ *
54
+ * ── Shape (9.23.1) ───────────────────────────────────────────────────────
55
+ * `createArrayProxy` and `createElementProxy` are ORCHESTRATORS: they wire
56
+ * traps and hold the caches. Every trap body is a named leaf below — one
57
+ * concern each — and the element proxy's set/delete/get traps are the SAME
58
+ * leaves the nested and terminal object proxies use (`writeTraps.ts`,
59
+ * `liveView.ts`), over an {@link elementSink}. A fix lands in a leaf once.
53
60
  */
54
- import { nativeGet } from '../memory/pathOps.js';
55
61
  import { shouldWrapWithProxy } from './allowlist.js';
56
- import { toJSONView } from './jsonProjection.js';
57
- import { liveInspectionTraps, liveObject } from './liveView.js';
58
- import { deleteInPath, setInPath, unwrapProxy } from './structuralWrite.js';
62
+ import { liveGetTrap, liveInspectionTraps, liveObject, MemberCache } from './liveView.js';
63
+ import { unwrapProxy } from './structuralWrite.js';
64
+ import { elementSink, sinkDeleteTrap, sinkSetTrap } from './writeTraps.js';
59
65
  /** Methods that mutate the array in-place. We intercept and copy-on-write. */
60
66
  const MUTATING_METHODS = new Set([
61
67
  'push',
@@ -68,6 +74,43 @@ const MUTATING_METHODS = new Set([
68
74
  'fill',
69
75
  'copyWithin',
70
76
  ]);
77
+ // -- Leaves: reads ------------------------------------------------------------
78
+ /** WHY `Number(prop)`: the historical reading of an index name — `'01'` and
79
+ * `''` address slots 1 and 0, as they always have. In range only. */
80
+ function indexIn(current, prop) {
81
+ if (typeof prop !== 'string')
82
+ return undefined;
83
+ const index = Number(prop);
84
+ return Number.isInteger(index) && index >= 0 && index < current.length ? index : undefined;
85
+ }
86
+ /** A non-negative integer index named by `prop` (any range — a write past the end grows the array). */
87
+ function indexNamed(prop) {
88
+ if (typeof prop !== 'string')
89
+ return undefined;
90
+ const index = Number(prop);
91
+ return Number.isInteger(index) && index >= 0 ? index : undefined;
92
+ }
93
+ /** WHY: a non-mutating read answers from the CURRENT array, never the
94
+ * creation-time target — a method is bound to it, anything else read off it. */
95
+ function boundMember(current, prop) {
96
+ const val = current[prop];
97
+ return typeof val === 'function' ? val.bind(current) : val;
98
+ }
99
+ /** WHY the cache: reading `lines[i].qty` in a loop must not allocate a proxy
100
+ * per read, and `lines[0] === lines[0]` must hold within a stage. Validated by
101
+ * raw identity — a commit replaces the array, the ref check misses, and a
102
+ * fresh proxy is built over the new element. A primitive is handed back raw. */
103
+ function cachedElement(cache, element, index, read, write) {
104
+ if (!shouldWrapWithProxy(element))
105
+ return element;
106
+ const cached = cache.get(index);
107
+ if (cached && cached.ref === element)
108
+ return cached.proxy;
109
+ const wrapped = wrapElementMember(element, elementSink(read, write, index), [], new Set());
110
+ cache.set(index, { ref: element, proxy: wrapped });
111
+ return wrapped;
112
+ }
113
+ // -- Leaves: writes -----------------------------------------------------------
71
114
  /** Slots from the current end up to (not including) `upTo` become `null` —
72
115
  * the JSON spelling of a hole, which is what the whole-array round-trip used
73
116
  * to produce for them. No-op when `upTo` is within the array. */
@@ -75,84 +118,52 @@ function fillHoles(arr, upTo) {
75
118
  for (let i = arr.length; i < upTo; i++)
76
119
  arr[i] = null;
77
120
  }
78
- /** Reads that must never be answered with a state value (see createTypedScope's GUARD_PROPS). */
79
- function guardValue(prop) {
80
- if (prop === 'then' || prop === 'asymmetricMatch')
81
- return { hit: true, value: undefined };
82
- if (prop === 'constructor')
83
- return { hit: true, value: Object };
84
- return { hit: false };
121
+ /** WHY: a mutating method runs on a COPY, with its arguments unwrapped (they
122
+ * are the assigned values; a number or a comparator passes through), and the
123
+ * copy is committed whole. The array in state is never touched. */
124
+ function mutatingMethod(read, write, name) {
125
+ return (...args) => {
126
+ const clone = [...read()];
127
+ const result = clone[name](...args.map(unwrapProxy));
128
+ write(clone);
129
+ return result;
130
+ };
85
131
  }
86
- /**
87
- * The three primitives every write inside an element goes through. All of them
88
- * rebuild the owning array immutably and hand the WHOLE new array to `commit`
89
- * — the array proxy's own copy-on-write contract, applied one or more levels
90
- * down. `path` is measured from the element: `[]` IS the element slot.
91
- */
92
- function replaceInElement(getCurrent, commit, index, path, value) {
93
- const next = [...getCurrent()];
94
- if (index >= next.length)
95
- return; // the element is gone — nothing to write into
96
- next[index] = path.length === 0 ? value : setInPath(next[index], path, value);
97
- commit(next);
132
+ /** `arr[i] = v`: copy, `null` the slots a write past the end skips, place the unwrapped value, commit. */
133
+ function setIndex(read, write, index, value) {
134
+ const clone = [...read()];
135
+ fillHoles(clone, index);
136
+ clone[index] = unwrapProxy(value);
137
+ write(clone);
98
138
  }
99
- function removeInElement(getCurrent, commit, index, path) {
100
- const next = [...getCurrent()];
101
- if (index >= next.length)
102
- return;
103
- next[index] = deleteInPath(next[index], path);
104
- commit(next);
139
+ /** `arr.length = n`: copy, `null` the slots growth adds, truncate or extend, commit. */
140
+ function setLength(read, write, length) {
141
+ const clone = [...read()];
142
+ fillHoles(clone, length);
143
+ clone.length = length;
144
+ write(clone);
105
145
  }
106
- /** The value at `path` inside element `index`, as it stands NOW (read-your-writes). */
107
- function readInElement(getCurrent, index, path) {
108
- const element = getCurrent()[index];
109
- return path.length === 0 ? element : nativeGet(element, path);
146
+ /** WHY: without this trap `delete items[2]` reaches the RAW array captured
147
+ * as the proxy target — committed state, no commit record. JS `delete` on an
148
+ * index leaves the slot empty and the length unchanged, and so does this:
149
+ * the emptied slot commits as `null`, JSON's only spelling for a hole. */
150
+ function deleteSlot(read, write, prop) {
151
+ const clone = [...read()];
152
+ const index = typeof prop === 'string' ? Number(prop) : NaN;
153
+ if (Number.isInteger(index) && index >= 0 && index < clone.length)
154
+ clone[index] = null;
155
+ else
156
+ delete clone[prop];
157
+ write(clone);
110
158
  }
159
+ // -- Leaves: the chain below an element --------------------------------------
111
160
  /**
112
- * Proxy over one OBJECT element (or an object nested inside one), carrying the
113
- * path from the element down to it. Reads recurse; writes go back out through
114
- * the owning array's commit callback.
115
- *
116
- * READS ARE LIVE. Every write rebuilds the array immutably, so the object the
117
- * proxy was created over is the PRE-write element for ever after; a held
118
- * handle that read from it saw its own writes vanish (`line.n += 1` twice
119
- * gave 2, `line.total = line.qty * 10` used the old `qty`, `'x' in line` was
120
- * false right after `line.x = 1`). Every trap therefore resolves the element
121
- * through {@link readInElement} first, and falls back to the captured object
122
- * only when the path no longer exists (the slot was emptied or the array
123
- * shrank) — the same read-your-writes the array proxy itself has always had,
124
- * and the same law the nested and terminal object proxies follow (liveView.ts).
161
+ * WHY: an array anywhere below a sink's root is ONE write path — it reads
162
+ * through the sink and commits the WHOLE new array back through it, so
163
+ * `push` three levels down and `arr[i].x = v` at the top share a funnel.
125
164
  */
126
- function createElementProxy(raw, getCurrent, commit, index, segments, visited) {
127
- const live = () => liveObject(raw, readInElement(getCurrent, index, segments));
128
- return new Proxy(raw, {
129
- get(_target, prop) {
130
- const current = live();
131
- if (typeof prop === 'symbol')
132
- return current[prop];
133
- const guard = guardValue(prop);
134
- if (guard.hit)
135
- return guard.value;
136
- // Law: serializing a proxied value equals serializing the raw value.
137
- if (prop === 'toJSON')
138
- return () => toJSONView(current);
139
- const value = current[prop];
140
- return wrapElementMember(value, getCurrent, commit, index, [...segments, prop], visited);
141
- },
142
- set(_target, prop, value) {
143
- if (typeof prop !== 'string')
144
- return true;
145
- replaceInElement(getCurrent, commit, index, [...segments, prop], unwrapProxy(value));
146
- return true;
147
- },
148
- deleteProperty(_target, prop) {
149
- if (typeof prop !== 'string')
150
- return true;
151
- removeInElement(getCurrent, commit, index, [...segments, prop]);
152
- return true;
153
- },
154
- ...liveInspectionTraps(live),
155
- });
165
+ export function arrayProxyAt(sink, path) {
166
+ return createArrayProxy(() => sink.readAt(path) ?? [], (next) => sink.put(path, next));
156
167
  }
157
168
  /**
158
169
  * Wrap a value read out of an element: arrays become array proxies whose
@@ -161,140 +172,90 @@ function createElementProxy(raw, getCurrent, commit, index, segments, visited) {
161
172
  * on the access chain (a cycle) is returned raw — the same back-edge the
162
173
  * nested-object terminal proxy takes.
163
174
  */
164
- function wrapElementMember(value, getCurrent, commit, index, path, visited) {
175
+ function wrapElementMember(value, sink, path, visited) {
165
176
  if (!shouldWrapWithProxy(value))
166
177
  return value;
167
178
  if (visited.has(value))
168
179
  return value;
169
180
  const branch = new Set(visited);
170
181
  branch.add(value);
171
- if (Array.isArray(value)) {
172
- return createArrayProxy(() => readInElement(getCurrent, index, path) ?? [], (inner) => replaceInElement(getCurrent, commit, index, path, inner));
173
- }
174
- return createElementProxy(value, getCurrent, commit, index, path, branch);
182
+ if (Array.isArray(value))
183
+ return arrayProxyAt(sink, path);
184
+ return createElementProxy(value, sink, path, branch);
185
+ }
186
+ // -- Orchestrators ------------------------------------------------------------
187
+ /**
188
+ * Proxy over one OBJECT element (or an object nested inside one), carrying the
189
+ * path from the element down to it. Reads recurse; writes go back out through
190
+ * the owning array's commit callback (the {@link elementSink}).
191
+ *
192
+ * READS ARE LIVE. Every write rebuilds the array immutably, so the object the
193
+ * proxy was created over is the PRE-write element for ever after; a held
194
+ * handle that read from it saw its own writes vanish (`line.n += 1` twice
195
+ * gave 2, `line.total = line.qty * 10` used the old `qty`, `'x' in line` was
196
+ * false right after `line.x = 1`). Every trap therefore resolves the element
197
+ * through the sink first, and falls back to the captured object only when
198
+ * the path no longer exists (the slot was emptied or the array shrank) — the
199
+ * same read-your-writes the array proxy itself has always had, and the same
200
+ * law the nested and terminal object proxies follow (liveView.ts).
201
+ */
202
+ function createElementProxy(raw, sink, segments, visited) {
203
+ const members = new MemberCache();
204
+ const live = () => liveObject(raw, sink.readAt(segments));
205
+ return new Proxy(raw, {
206
+ get: liveGetTrap(live, segments, (value, path) => wrapElementMember(value, sink, path, visited), members),
207
+ set: sinkSetTrap(sink, segments),
208
+ deleteProperty: sinkDeleteTrap(sink, segments),
209
+ ...liveInspectionTraps(live),
210
+ });
175
211
  }
176
212
  /**
177
213
  * Creates a Proxy over an array that intercepts mutating operations.
178
214
  *
215
+ * The actual current array is the Proxy target: Node.js console.log inspects
216
+ * the target directly (bypasses Proxy traps), so the real array shows correct
217
+ * values. The target reference is fixed at creation time — after mutations,
218
+ * the proxy returns a new proxy (via cache invalidation) with the fresh array
219
+ * as target.
220
+ *
179
221
  * @param getCurrent - Returns the current array snapshot from state
180
222
  * @param commit - Called with the new array after a mutation (triggers setValue)
181
223
  * @returns Proxied array with copy-on-write semantics
182
224
  */
183
225
  export function createArrayProxy(getCurrent, commit) {
184
- // Use the actual current array as the Proxy target. Node.js console.log
185
- // inspects the target directly (bypasses Proxy traps). By using the real
186
- // array, console.log shows correct values. The target reference is fixed
187
- // at creation time — after mutations, the proxy returns a new proxy
188
- // (via cache invalidation) with the fresh array as target.
189
226
  const target = getCurrent();
190
- const readCurrent = getCurrent;
191
- const writeCommit = commit;
192
- // Element proxies are cached per index and validated by raw identity — the
193
- // same bargain the top-level child cache makes. Without it, reading
194
- // `lines[i].qty` in a loop would allocate one proxy per read; with it,
195
- // repeated access to an UNCHANGED element is free and `lines[0] === lines[0]`
196
- // holds within a stage. A commit replaces the array, so the ref check misses
197
- // and a fresh proxy is built over the new element.
198
- const elementCache = new Map();
227
+ const read = getCurrent;
228
+ const write = commit;
229
+ const elements = new Map();
199
230
  return new Proxy(target, {
200
- get(_target, prop, receiver) {
201
- // Intercept mutating methods
202
- if (typeof prop === 'string' && MUTATING_METHODS.has(prop)) {
203
- return (...args) => {
204
- const clone = [...getCurrent()];
205
- // The arguments are the assigned values — unwrap each one (a
206
- // number, a comparator or a primitive passes through untouched).
207
- const result = clone[prop](...args.map(unwrapProxy));
208
- commit(clone);
209
- return result;
210
- };
211
- }
212
- // Non-mutating access: delegate to the current array snapshot
213
- const current = getCurrent();
214
- // 'length' and index access
231
+ get(_target, prop) {
232
+ if (typeof prop === 'string' && MUTATING_METHODS.has(prop))
233
+ return mutatingMethod(read, write, prop);
234
+ const current = read();
215
235
  if (prop === 'length')
216
236
  return current.length;
217
- // Numeric index access — the element joins the write chain (see header).
218
- if (typeof prop === 'string') {
219
- const index = Number(prop);
220
- if (Number.isInteger(index) && index >= 0 && index < current.length) {
221
- const element = current[index];
222
- if (!shouldWrapWithProxy(element))
223
- return element;
224
- const cached = elementCache.get(index);
225
- if (cached && cached.ref === element)
226
- return cached.proxy;
227
- const wrapped = wrapElementMember(element, readCurrent, writeCommit, index, [], new Set());
228
- elementCache.set(index, { ref: element, proxy: wrapped });
229
- return wrapped;
230
- }
231
- }
232
- // Node.js util.inspect custom formatting
233
- if (prop === Symbol.for('nodejs.util.inspect.custom')) {
237
+ const index = indexIn(current, prop);
238
+ if (index !== undefined)
239
+ return cachedElement(elements, current[index], index, read, write);
240
+ if (prop === Symbol.for('nodejs.util.inspect.custom'))
234
241
  return () => current;
235
- }
236
- // Symbol.iterator and other built-in symbols
237
- if (typeof prop === 'symbol') {
238
- const val = current[prop];
239
- if (typeof val === 'function')
240
- return val.bind(current);
241
- return val;
242
- }
243
- // All other methods (map, filter, forEach, find, etc.) -- bind to current
244
- const val = current[prop];
245
- if (typeof val === 'function')
246
- return val.bind(current);
247
- return val;
242
+ return boundMember(current, prop);
248
243
  },
249
244
  set(_target, prop, value) {
250
- // Index assignment: scope.items[2] = 'updated'
251
- if (typeof prop === 'string') {
252
- const index = Number(prop);
253
- if (Number.isInteger(index) && index >= 0) {
254
- const clone = [...getCurrent()];
255
- fillHoles(clone, index); // a write past the end: the skipped slots are `null`, not holes
256
- clone[index] = unwrapProxy(value);
257
- commit(clone);
258
- return true;
259
- }
260
- }
261
- // Setting 'length' (e.g., arr.length = 0 to clear)
262
- if (prop === 'length' && typeof value === 'number') {
263
- const clone = [...getCurrent()];
264
- fillHoles(clone, value); // growth: the new slots are `null`, not holes
265
- clone.length = value;
266
- commit(clone);
267
- return true;
268
- }
269
- return true; // ignore other set operations
245
+ const index = indexNamed(prop);
246
+ if (index !== undefined)
247
+ setIndex(read, write, index, value);
248
+ else if (prop === 'length' && typeof value === 'number')
249
+ setLength(read, write, value);
250
+ return true; // any other set is ignored (an expando on an array is out of contract — README)
270
251
  },
271
- // `delete items[2]` — without this trap the default reaches the RAW array
272
- // captured as the proxy target, mutating committed state with no commit
273
- // record. Copy-on-write like every other mutation; JS `delete` on an index
274
- // leaves the slot empty and the length unchanged, and so does this — the
275
- // emptied slot commits as `null`, JSON's only spelling for an array hole.
276
252
  deleteProperty(_target, prop) {
277
- const clone = [...getCurrent()];
278
- const index = typeof prop === 'string' ? Number(prop) : NaN;
279
- if (Number.isInteger(index) && index >= 0 && index < clone.length)
280
- clone[index] = null;
281
- else
282
- delete clone[prop];
283
- commit(clone);
253
+ deleteSlot(read, write, prop);
284
254
  return true;
285
255
  },
286
- has(_target, prop) {
287
- const current = getCurrent();
288
- return Reflect.has(current, prop);
289
- },
290
- ownKeys() {
291
- const current = getCurrent();
292
- return Reflect.ownKeys(current);
293
- },
294
- getOwnPropertyDescriptor(_target, prop) {
295
- const current = getCurrent();
296
- return Object.getOwnPropertyDescriptor(current, prop);
297
- },
256
+ has: (_target, prop) => Reflect.has(read(), prop),
257
+ ownKeys: () => Reflect.ownKeys(read()),
258
+ getOwnPropertyDescriptor: (_target, prop) => Object.getOwnPropertyDescriptor(read(), prop),
298
259
  });
299
260
  }
300
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXlUcmFwcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcmVhY3RpdmUvYXJyYXlUcmFwcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9ERztBQUVILE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUNqRCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDakQsT0FBTyxFQUFFLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUNoRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUU1RSw4RUFBOEU7QUFDOUUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMvQixNQUFNO0lBQ04sS0FBSztJQUNMLE9BQU87SUFDUCxTQUFTO0lBQ1QsUUFBUTtJQUNSLE1BQU07SUFDTixTQUFTO0lBQ1QsTUFBTTtJQUNOLFlBQVk7Q0FDYixDQUFDLENBQUM7QUFFSDs7a0VBRWtFO0FBQ2xFLFNBQVMsU0FBUyxDQUFDLEdBQWMsRUFBRSxJQUFZO0lBQzdDLEtBQUssSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLE1BQU0sRUFBRSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRTtRQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUM7QUFDeEQsQ0FBQztBQUVELGlHQUFpRztBQUNqRyxTQUFTLFVBQVUsQ0FBQyxJQUFZO0lBQzlCLElBQUksSUFBSSxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssaUJBQWlCO1FBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsS0FBSyxF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QUksQ0FBQztRQUNkLENBQUM7UUFFRCxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUk7WUFDZixNQUFNLE9BQU8sR0FBRyxVQUFVLEVBQUUsQ0FBQztZQUM3QixPQUFPLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3BDLENBQUM7UUFFRCxPQUFPO1lBQ0wsTUFBTSxPQUFPLEdBQUcsVUFBVSxFQUFFLENBQUM7WUFDN0IsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFFRCx3QkFBd0IsQ0FBQyxPQUFPLEVBQUUsSUFBSTtZQUNwQyxNQUFNLE9BQU8sR0FBRyxVQUFVLEVBQUUsQ0FBQztZQUM3QixPQUFPLE1BQU0sQ0FBQyx3QkFBd0IsQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDeEQsQ0FBQztLQUNGLENBQUMsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHJlYWN0aXZlL2FycmF5VHJhcHMgLS0gQXJyYXkgbXV0YXRpb24gaW50ZXJjZXB0aW9uIHZpYSBQcm94eS5cbiAqXG4gKiBXaGVuIHNjb3BlLml0ZW1zIGlzIGFuIGFycmF5LCB3ZSByZXR1cm4gYSBQcm94eSB0aGF0IGludGVyY2VwdHMgbXV0YXRpbmdcbiAqIG1ldGhvZHMgKHB1c2gsIHBvcCwgc3BsaWNlLCBldGMuKSBBTkQgaW5kZXhlZCBhY2Nlc3MuIEVhY2ggbXV0YXRpb246XG4gKiAxLiBDbG9uZXMgdGhlIGN1cnJlbnQgYXJyYXlcbiAqIDIuIEFwcGxpZXMgdGhlIG11dGF0aW9uIHRvIHRoZSBjbG9uZVxuICogMy4gQ29tbWl0cyB0aGUgbmV3IGFycmF5IHZpYSB0aGUgY29tbWl0IGNhbGxiYWNrXG4gKlxuICogTm9uLW11dGF0aW5nIG1ldGhvZHMgKG1hcCwgZmlsdGVyLCBmb3JFYWNoLCBldGMuKSBwYXNzIHRocm91Z2ggdG8gdGhlXG4gKiBjdXJyZW50IGFycmF5IHNuYXBzaG90IHdpdGhvdXQgaW50ZXJjZXB0aW9uLlxuICpcbiAqIFRoZSBvcmlnaW5hbCBhcnJheSBpbiBzdGF0ZSBpcyBORVZFUiBtdXRhdGVkIGRpcmVjdGx5IC0tIGFsbCB3cml0ZXMgZ29cbiAqIHRocm91Z2ggdGhlIGNvbW1pdCBjYWxsYmFjayB3aGljaCBjYWxscyBzZXRWYWx1ZS91cGRhdGVWYWx1ZS5cbiAqXG4gKiDilIDilIAgT25seSB0aGUgQVNTSUdORUQgdmFsdWUgaXMgdW53cmFwcGVkICg5LjIzLjApIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICogTGFuZG1pbmUgMSBzYXlzIHRoZSBzZXQgdHJhcCBKU09OLXJvdW5kLXRyaXBzIHRoZSB2YWx1ZSB0aGUgY2FsbGVyIGhhbmRlZFxuICogaW4uIEZvciBhbiBhcnJheSB0aGF0IGlzIHRoZSBpbmRleC1hc3NpZ25lZCBlbGVtZW50LCBhIG11dGF0aW5nIG1ldGhvZCdzXG4gKiBhcmd1bWVudHMgKGBwdXNoKHgpYCwgYHNwbGljZShpLCBuLCAuLi5pdGVtcylgLCBgZmlsbCh4KWApLCBvciB0aGUgbGVhZiBhblxuICogZWxlbWVudCBwcm94eSB3cml0ZXMg4oCUIGFuZCBpdCBpcyB1bndyYXBwZWQgSEVSRSwgYXQgdGhlIHRyYXAgdGhhdCByZWNlaXZlc1xuICogaXQuIFRoZSByZWJ1aWx0IGFycmF5IGlzIGhhbmRlZCB0byBgY29tbWl0YCBhcyBpdCBpczogZXZlcnkgc2libGluZyB0aGVcbiAqIGNhbGxlciBkaWQgbm90IHRvdWNoIHBhc3NlcyB0aHJvdWdoIGJ5IHJlZmVyZW5jZSwgYERhdGVgcyBhbmQgYE1hcGBzXG4gKiBpbnRhY3QuIFVudGlsIDkuMjMuMCB0aGUgY29tbWl0IGNhbGxiYWNrcyByb3VuZC10cmlwcGVkIHRoZSBXSE9MRSByZWJ1aWx0XG4gKiBhcnJheSwgd2hpY2ggc3RyaW5naWZpZWQgdW50b3VjaGVkIHNpYmxpbmdzIGFuZCB3YXMgTyhOKSBwZXIgZWxlbWVudCB3cml0ZS5cbiAqIFRoZSBvbmUgdGhpbmcgdGhlIHJvdW5kLXRyaXAgdXNlZCB0byBkbyBmb3IgdGhlIGFycmF5J3Mgb3duIHNoYXBlIOKAlCBhblxuICogZW1wdGllZCBvciBza2lwcGVkIHNsb3QgYmVjYW1lIGBudWxsYCwgSlNPTidzIG9ubHkgc3BlbGxpbmcgZm9yIGEgaG9sZSDigJRcbiAqIGlzIG5vdyBkb25lIGV4cGxpY2l0bHkgYnkgdGhlIHRyYXBzIHRoYXQgY2FuIGNyZWF0ZSBvbmUgKGBkZWxldGUgYXJyW2ldYCxcbiAqIGBhcnJbaV0gPSB2YCBwYXN0IHRoZSBlbmQsIGBhcnIubGVuZ3RoID0gbmAgZ3Jvd3RoKS5cbiAqXG4gKiDilIDilIAgSW5kZXhlZCBhY2Nlc3MgaXMgcGFydCBvZiB0aGUgY2hhaW4gKDkuMjIuMCkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gKiBgYXJyW2ldYCB1c2VkIHRvIGhhbmQgYmFjayB0aGUgUkFXIGVsZW1lbnQsIHdoaWNoIGJyb2tlIHRoZSBwcm94eSBjaGFpbiBhdFxuICogZXhhY3RseSB0aGUgcG9pbnQgdXNlcnMgd3JpdGUgdGhyb3VnaCBpdDogYG9yZGVyLmxpbmVzWzBdLnF0eSA9IDRgIHdhcyBhblxuICogaW4tcGxhY2UgbXV0YXRpb24gb2YgYSBib3Jyb3dlZCByZWFkIOKAlCBubyB0cmFwLCBubyB0cmFjZSByb3csIG5vIGNvbW1pdC5cbiAqIEJlZm9yZSB0aGUgc3RhZ2UncyBmaXJzdCBzdGFnZWQgd3JpdGUgdGhhdCBib3Jyb3dlZCB2YWx1ZSBJUyBjb21taXR0ZWRcbiAqIHNoYXJlZCBtZW1vcnksIHNvIHRoZSBtdXRhdGlvbiBtb3ZlZCBzdGF0ZSB3aGlsZSB0aGUgbG9nIHN0YXllZCBlbXB0eTsgYWZ0ZXJcbiAqIGl0LCB0aGUgbXV0YXRpb24gbGFuZGVkIGluIHRoZSBwcml2YXRlIGJ1ZmZlciBjbG9uZSBhbmQgd2FzIGRyb3BwZWQuIFNhbWVcbiAqIGV4cHJlc3Npb24sIHR3byBzaWxlbnQgb3V0Y29tZXMuXG4gKlxuICogTm93IGFuIGluZGV4ZWQgcmVhZCBvZiBhIHdyYXBwYWJsZSBlbGVtZW50IHJldHVybnMgYW4gRUxFTUVOVCBQUk9YWSB0aGF0XG4gKiBhY2N1bXVsYXRlcyB0aGUgcGF0aCBpbnNpZGUgdGhlIGVsZW1lbnQgYW5kLCBvbiB3cml0ZSwgcmVidWlsZHMgdGhlIGFycmF5XG4gKiBpbW11dGFibHkgKHtAbGluayBzZXRJblBhdGh9KSBhbmQgaGFuZHMgdGhlIHdob2xlIG5ldyBhcnJheSB0byBgY29tbWl0YCDigJRcbiAqIHRoZSBzYW1lIGZ1bm5lbCBgcHVzaGAgYWxyZWFkeSB1c2VkLiBPbmUgd3JpdGUgcGF0aCBmb3IgdGhlIHdob2xlIGFycmF5LFxuICogd2hhdGV2ZXIgZGVwdGggaXQgaXMgYWRkcmVzc2VkIGF0LlxuICpcbiAqIOKUgOKUgCBXaGF0IGlzIHN0aWxsIE5PVCBzZWVuIChieSBkZXNpZ24pIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICogRWxlbWVudHMgcmVhY2hlZCBXSVRIT1VUIGFuIGluZGV4IOKAlCBgZmluZCgpYCwgYGZpbHRlcigpYCwgYGZvcuKApm9mYCxcbiAqIGBmb3JFYWNoYCwgZGVzdHJ1Y3R1cmluZyDigJQgYXJlIGhhbmRlZCBiYWNrIHJhdywgYmVjYXVzZSB3cmFwcGluZyB0aGVtIHdvdWxkXG4gKiBtZWFuIHJldHVybmluZyBwcm94aWVzIG91dCBvZiBldmVyeSByZWFkIG1ldGhvZCAoYG1hcGAgd291bGQgYnVpbGQgYW4gYXJyYXlcbiAqIG9mIHByb3hpZXMpIGZvciBhIGNvc3QgdGhlIGxpYnJhcnkgc2hvdWxkIG5vdCBwYXkuIE11dGF0aW5nIG9uZSBvZiB0aG9zZSBpc1xuICogbm90IGxvc3QgaW4gc2lsZW5jZSBlaXRoZXI6IGBTdGFnZUNvbnRleHRgIGNvbXBhcmVzIHdoYXQgYSBzdGFnZSBSRUFEIHdpdGhcbiAqIHdoYXQgdGhlIHZhbHVlIGhvbGRzIGF0IGNvbW1pdCBhbmQsIGluIGRldiBtb2RlLCB3YXJucyB3aXRoIHRoZSBleGFjdCBwYXRoLlxuICogU2VlIHNyYy9saWIvcmVhY3RpdmUvUkVBRE1FLm1kLlxuICovXG5cbmltcG9ydCB7IG5hdGl2ZUdldCB9IGZyb20gJy4uL21lbW9yeS9wYXRoT3BzLmpzJztcbmltcG9ydCB7IHNob3VsZFdyYXBXaXRoUHJveHkgfSBmcm9tICcuL2FsbG93bGlzdC5qcyc7XG5pbXBvcnQgeyB0b0pTT05WaWV3IH0gZnJvbSAnLi9qc29uUHJvamVjdGlvbi5qcyc7XG5pbXBvcnQgeyBsaXZlSW5zcGVjdGlvblRyYXBzLCBsaXZlT2JqZWN0IH0gZnJvbSAnLi9saXZlVmlldy5qcyc7XG5pbXBvcnQgeyBkZWxldGVJblBhdGgsIHNldEluUGF0aCwgdW53cmFwUHJveHkgfSBmcm9tICcuL3N0cnVjdHVyYWxXcml0ZS5qcyc7XG5cbi8qKiBNZXRob2RzIHRoYXQgbXV0YXRlIHRoZSBhcnJheSBpbi1wbGFjZS4gV2UgaW50ZXJjZXB0IGFuZCBjb3B5LW9uLXdyaXRlLiAqL1xuY29uc3QgTVVUQVRJTkdfTUVUSE9EUyA9IG5ldyBTZXQoW1xuICAncHVzaCcsXG4gICdwb3AnLFxuICAnc2hpZnQnLFxuICAndW5zaGlmdCcsXG4gICdzcGxpY2UnLFxuICAnc29ydCcsXG4gICdyZXZlcnNlJyxcbiAgJ2ZpbGwnLFxuICAnY29weVdpdGhpbicsXG5dKTtcblxuLyoqIFNsb3RzIGZyb20gdGhlIGN1cnJlbnQgZW5kIHVwIHRvIChub3QgaW5jbHVkaW5nKSBgdXBUb2AgYmVjb21lIGBudWxsYCDigJRcbiAqICB0aGUgSlNPTiBzcGVsbGluZyBvZiBhIGhvbGUsIHdoaWNoIGlzIHdoYXQgdGhlIHdob2xlLWFycmF5IHJvdW5kLXRyaXAgdXNlZFxuICogIHRvIHByb2R1Y2UgZm9yIHRoZW0uIE5vLW9wIHdoZW4gYHVwVG9gIGlzIHdpdGhpbiB0aGUgYXJyYXkuICovXG5mdW5jdGlvbiBmaWxsSG9sZXMoYXJyOiB1bmtub3duW10sIHVwVG86IG51bWJlcik6IHZvaWQge1xuICBmb3IgKGxldCBpID0gYXJyLmxlbmd0aDsgaSA8IHVwVG87IGkrKykgYXJyW2ldID0gbnVsbDtcbn1cblxuLyoqIFJlYWRzIHRoYXQgbXVzdCBuZXZlciBiZSBhbnN3ZXJlZCB3aXRoIGEgc3RhdGUgdmFsdWUgKHNlZSBjcmVhdGVUeXBlZFNjb3BlJ3MgR1VBUkRfUFJPUFMpLiAqL1xuZnVuY3Rpb24gZ3VhcmRWYWx1ZShwcm9wOiBzdHJpbmcpOiB7IGhpdDogYm9vbGVhbjsgdmFsdWU/OiB1bmtub3duIH0ge1xuICBpZiAocHJvcCA9PT0gJ3RoZW4nIHx8IHByb3AgPT09ICdhc3ltbWV0cmljTWF0Y2gnKSByZXR1cm4geyBoaXQ6IHRydWUsIHZhbHVlOiB1bmRlZmluZWQgfTtcbiAgaWYgKHByb3AgPT09ICdjb25zdHJ1Y3RvcicpIHJldHVybiB7IGhpdDogdHJ1ZSwgdmFsdWU6IE9iamVjdCB9O1xuICByZXR1cm4geyBoaXQ6IGZhbHNlIH07XG59XG5cbi8qKlxuICogVGhlIHRocmVlIHByaW1pdGl2ZXMgZXZlcnkgd3JpdGUgaW5zaWRlIGFuIGVsZW1lbnQgZ29lcyB0aHJvdWdoLiBBbGwgb2YgdGhlbVxuICogcmVidWlsZCB0aGUgb3duaW5nIGFycmF5IGltbXV0YWJseSBhbmQgaGFuZCB0aGUgV0hPTEUgbmV3IGFycmF5IHRvIGBjb21taXRgXG4gKiDigJQgdGhlIGFycmF5IHByb3h5J3Mgb3duIGNvcHktb24td3JpdGUgY29udHJhY3QsIGFwcGxpZWQgb25lIG9yIG1vcmUgbGV2ZWxzXG4gKiBkb3duLiBgcGF0aGAgaXMgbWVhc3VyZWQgZnJvbSB0aGUgZWxlbWVudDogYFtdYCBJUyB0aGUgZWxlbWVudCBzbG90LlxuICovXG5mdW5jdGlvbiByZXBsYWNlSW5FbGVtZW50KFxuICBnZXRDdXJyZW50OiAoKSA9PiB1bmtub3duW10sXG4gIGNvbW1pdDogKG5leHQ6IGFueVtdKSA9PiB2b2lkLFxuICBpbmRleDogbnVtYmVyLFxuICBwYXRoOiByZWFkb25seSBzdHJpbmdbXSxcbiAgdmFsdWU6IHVua25vd24sXG4pOiB2b2lkIHtcbiAgY29uc3QgbmV4dCA9IFsuLi5nZXRDdXJyZW50KCldO1xuICBpZiAoaW5kZXggPj0gbmV4dC5sZW5ndGgpIHJldHVybjsgLy8gdGhlIGVsZW1lbnQgaXMgZ29uZSDigJQgbm90aGluZyB0byB3cml0ZSBpbnRvXG4gIG5leHRbaW5kZXhdID0gcGF0aC5sZW5ndGggPT09IDAgPyB2YWx1ZSA6IHNldEluUGF0aChuZXh0W2luZGV4XSwgcGF0aCwgdmFsdWUpO1xuICBjb21taXQobmV4dCk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZUluRWxlbWVudChcbiAgZ2V0Q3VycmVudDogKCkgPT4gdW5rbm93bltdLFxuICBjb21taXQ6IChuZXh0OiBhbnlbXSkgPT4gdm9pZCxcbiAgaW5kZXg6IG51bWJlcixcbiAgcGF0aDogcmVhZG9ubHkgc3RyaW5nW10sXG4pOiB2b2lkIHtcbiAgY29uc3QgbmV4dCA9IFsuLi5nZXRDdXJyZW50KCldO1xuICBpZiAoaW5kZXggPj0gbmV4dC5sZW5ndGgpIHJldHVybjtcbiAgbmV4dFtpbmRleF0gPSBkZWxldGVJblBhdGgobmV4dFtpbmRleF0sIHBhdGgpO1xuICBjb21taXQobmV4dCk7XG59XG5cbi8qKiBUaGUgdmFsdWUgYXQgYHBhdGhgIGluc2lkZSBlbGVtZW50IGBpbmRleGAsIGFzIGl0IHN0YW5kcyBOT1cgKHJlYWQteW91ci13cml0ZXMpLiAqL1xuZnVuY3Rpb24gcmVhZEluRWxlbWVudChnZXRDdXJyZW50OiAoKSA9PiB1bmtub3duW10sIGluZGV4OiBudW1iZXIsIHBhdGg6IHJlYWRvbmx5IHN0cmluZ1tdKTogdW5rbm93biB7XG4gIGNvbnN0IGVsZW1lbnQgPSBnZXRDdXJyZW50KClbaW5kZXhdO1xuICByZXR1cm4gcGF0aC5sZW5ndGggPT09IDAgPyBlbGVtZW50IDogbmF0aXZlR2V0KGVsZW1lbnQsIHBhdGggYXMgc3RyaW5nW10pO1xufVxuXG4vKipcbiAqIFByb3h5IG92ZXIgb25lIE9CSkVDVCBlbGVtZW50IChvciBhbiBvYmplY3QgbmVzdGVkIGluc2lkZSBvbmUpLCBjYXJyeWluZyB0aGVcbiAqIHBhdGggZnJvbSB0aGUgZWxlbWVudCBkb3duIHRvIGl0LiBSZWFkcyByZWN1cnNlOyB3cml0ZXMgZ28gYmFjayBvdXQgdGhyb3VnaFxuICogdGhlIG93bmluZyBhcnJheSdzIGNvbW1pdCBjYWxsYmFjay5cbiAqXG4gKiBSRUFEUyBBUkUgTElWRS4gRXZlcnkgd3JpdGUgcmVidWlsZHMgdGhlIGFycmF5IGltbXV0YWJseSwgc28gdGhlIG9iamVjdCB0aGVcbiAqIHByb3h5IHdhcyBjcmVhdGVkIG92ZXIgaXMgdGhlIFBSRS13cml0ZSBlbGVtZW50IGZvciBldmVyIGFmdGVyOyBhIGhlbGRcbiAqIGhhbmRsZSB0aGF0IHJlYWQgZnJvbSBpdCBzYXcgaXRzIG93biB3cml0ZXMgdmFuaXNoIChgbGluZS5uICs9IDFgIHR3aWNlXG4gKiBnYXZlIDIsIGBsaW5lLnRvdGFsID0gbGluZS5xdHkgKiAxMGAgdXNlZCB0aGUgb2xkIGBxdHlgLCBgJ3gnIGluIGxpbmVgIHdhc1xuICogZmFsc2UgcmlnaHQgYWZ0ZXIgYGxpbmUueCA9IDFgKS4gRXZlcnkgdHJhcCB0aGVyZWZvcmUgcmVzb2x2ZXMgdGhlIGVsZW1lbnRcbiAqIHRocm91Z2gge0BsaW5rIHJlYWRJbkVsZW1lbnR9IGZpcnN0LCBhbmQgZmFsbHMgYmFjayB0byB0aGUgY2FwdHVyZWQgb2JqZWN0XG4gKiBvbmx5IHdoZW4gdGhlIHBhdGggbm8gbG9uZ2VyIGV4aXN0cyAodGhlIHNsb3Qgd2FzIGVtcHRpZWQgb3IgdGhlIGFycmF5XG4gKiBzaHJhbmspIOKAlCB0aGUgc2FtZSByZWFkLXlvdXItd3JpdGVzIHRoZSBhcnJheSBwcm94eSBpdHNlbGYgaGFzIGFsd2F5cyBoYWQsXG4gKiBhbmQgdGhlIHNhbWUgbGF3IHRoZSBuZXN0ZWQgYW5kIHRlcm1pbmFsIG9iamVjdCBwcm94aWVzIGZvbGxvdyAobGl2ZVZpZXcudHMpLlxuICovXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50UHJveHkoXG4gIHJhdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIGdldEN1cnJlbnQ6ICgpID0+IHVua25vd25bXSxcbiAgY29tbWl0OiAobmV4dDogYW55W10pID0+IHZvaWQsXG4gIGluZGV4OiBudW1iZXIsXG4gIHNlZ21lbnRzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgdmlzaXRlZDogU2V0PG9iamVjdD4sXG4pOiB1bmtub3duIHtcbiAgY29uc3QgbGl2ZSA9ICgpID0+IGxpdmVPYmplY3QocmF3LCByZWFkSW5FbGVtZW50KGdldEN1cnJlbnQsIGluZGV4LCBzZWdtZW50cykpO1xuXG4gIHJldHVybiBuZXcgUHJveHkocmF3LCB7XG4gICAgZ2V0KF90YXJnZXQsIHByb3ApIHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBsaXZlKCk7XG4gICAgICBpZiAodHlwZW9mIHByb3AgPT09ICdzeW1ib2wnKSByZXR1cm4gKGN1cnJlbnQgYXMgYW55KVtwcm9wXTtcbiAgICAgIGNvbnN0IGd1YXJkID0gZ3VhcmRWYWx1ZShwcm9wKTtcbiAgICAgIGlmIChndWFyZC5oaXQpIHJldHVybiBndWFyZC52YWx1ZTtcbiAgICAgIC8vIExhdzogc2VyaWFsaXppbmcgYSBwcm94aWVkIHZhbHVlIGVxdWFscyBzZXJpYWxpemluZyB0aGUgcmF3IHZhbHVlLlxuICAgICAgaWYgKHByb3AgPT09ICd0b0pTT04nKSByZXR1cm4gKCkgPT4gdG9KU09OVmlldyhjdXJyZW50KTtcblxuICAgICAgY29uc3QgdmFsdWUgPSAoY3VycmVudCBhcyBhbnkpW3Byb3BdO1xuICAgICAgcmV0dXJuIHdyYXBFbGVtZW50TWVtYmVyKHZhbHVlLCBnZXRDdXJyZW50LCBjb21taXQsIGluZGV4LCBbLi4uc2VnbWVudHMsIHByb3BdLCB2aXNpdGVkKTtcbiAgICB9LFxuXG4gICAgc2V0KF90YXJnZXQsIHByb3AsIHZhbHVlKSB7XG4gICAgICBpZiAodHlwZW9mIHByb3AgIT09ICdzdHJpbmcnKSByZXR1cm4gdHJ1ZTtcbiAgICAgIHJlcGxhY2VJbkVsZW1lbnQoZ2V0Q3VycmVudCwgY29tbWl0LCBpbmRleCwgWy4uLnNlZ21lbnRzLCBwcm9wXSwgdW53cmFwUHJveHkodmFsdWUpKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICBkZWxldGVQcm9wZXJ0eShfdGFyZ2V0LCBwcm9wKSB7XG4gICAgICBpZiAodHlwZW9mIHByb3AgIT09ICdzdHJpbmcnKSByZXR1cm4gdHJ1ZTtcbiAgICAgIHJlbW92ZUluRWxlbWVudChnZXRDdXJyZW50LCBjb21taXQsIGluZGV4LCBbLi4uc2VnbWVudHMsIHByb3BdKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0sXG5cbiAgICAuLi5saXZlSW5zcGVjdGlvblRyYXBzKGxpdmUpLFxuICB9KTtcbn1cblxuLyoqXG4gKiBXcmFwIGEgdmFsdWUgcmVhZCBvdXQgb2YgYW4gZWxlbWVudDogYXJyYXlzIGJlY29tZSBhcnJheSBwcm94aWVzIHdob3NlXG4gKiBjb21taXRzIHJvdXRlIGJhY2sgdGhyb3VnaCB0aGUgb3duaW5nIGFycmF5LCBwbGFpbiBvYmplY3RzIGJlY29tZSBlbGVtZW50XG4gKiBwcm94aWVzIG9uZSBsZXZlbCBkZWVwZXIsIGV2ZXJ5dGhpbmcgZWxzZSBpcyByZXR1cm5lZCBhcy1pcy4gQSB2YWx1ZSBhbHJlYWR5XG4gKiBvbiB0aGUgYWNjZXNzIGNoYWluIChhIGN5Y2xlKSBpcyByZXR1cm5lZCByYXcg4oCUIHRoZSBzYW1lIGJhY2stZWRnZSB0aGVcbiAqIG5lc3RlZC1vYmplY3QgdGVybWluYWwgcHJveHkgdGFrZXMuXG4gKi9cbmZ1bmN0aW9uIHdyYXBFbGVtZW50TWVtYmVyKFxuICB2YWx1ZTogdW5rbm93bixcbiAgZ2V0Q3VycmVudDogKCkgPT4gdW5rbm93bltdLFxuICBjb21taXQ6IChuZXh0OiBhbnlbXSkgPT4gdm9pZCxcbiAgaW5kZXg6IG51bWJlcixcbiAgcGF0aDogcmVhZG9ubHkgc3RyaW5nW10sXG4gIHZpc2l0ZWQ6IFNldDxvYmplY3Q+LFxuKTogdW5rbm93biB7XG4gIGlmICghc2hvdWxkV3JhcFdpdGhQcm94eSh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcbiAgaWYgKHZpc2l0ZWQuaGFzKHZhbHVlIGFzIG9iamVjdCkpIHJldHVybiB2YWx1ZTtcbiAgY29uc3QgYnJhbmNoID0gbmV3IFNldCh2aXNpdGVkKTtcbiAgYnJhbmNoLmFkZCh2YWx1ZSBhcyBvYmplY3QpO1xuXG4gIGlmIChBcnJheS5pc0FycmF5KHZhbHVlKSkge1xuICAgIHJldHVybiBjcmVhdGVBcnJheVByb3h5KFxuICAgICAgKCkgPT4gKHJlYWRJbkVsZW1lbnQoZ2V0Q3VycmVudCwgaW5kZXgsIHBhdGgpIGFzIHVua25vd25bXSkgPz8gW10sXG4gICAgICAoaW5uZXIpID0+IHJlcGxhY2VJbkVsZW1lbnQoZ2V0Q3VycmVudCwgY29tbWl0LCBpbmRleCwgcGF0aCwgaW5uZXIpLFxuICAgICk7XG4gIH1cbiAgcmV0dXJuIGNyZWF0ZUVsZW1lbnRQcm94eSh2YWx1ZSBhcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPiwgZ2V0Q3VycmVudCwgY29tbWl0LCBpbmRleCwgcGF0aCwgYnJhbmNoKTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgUHJveHkgb3ZlciBhbiBhcnJheSB0aGF0IGludGVyY2VwdHMgbXV0YXRpbmcgb3BlcmF0aW9ucy5cbiAqXG4gKiBAcGFyYW0gZ2V0Q3VycmVudCAtIFJldHVybnMgdGhlIGN1cnJlbnQgYXJyYXkgc25hcHNob3QgZnJvbSBzdGF0ZVxuICogQHBhcmFtIGNvbW1pdCAtIENhbGxlZCB3aXRoIHRoZSBuZXcgYXJyYXkgYWZ0ZXIgYSBtdXRhdGlvbiAodHJpZ2dlcnMgc2V0VmFsdWUpXG4gKiBAcmV0dXJucyBQcm94aWVkIGFycmF5IHdpdGggY29weS1vbi13cml0ZSBzZW1hbnRpY3NcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZUFycmF5UHJveHk8VD4oZ2V0Q3VycmVudDogKCkgPT4gVFtdLCBjb21taXQ6IChuZXdBcnJheTogVFtdKSA9PiB2b2lkKTogVFtdIHtcbiAgLy8gVXNlIHRoZSBhY3R1YWwgY3VycmVudCBhcnJheSBhcyB0aGUgUHJveHkgdGFyZ2V0LiBOb2RlLmpzIGNvbnNvbGUubG9nXG4gIC8vIGluc3BlY3RzIHRoZSB0YXJnZXQgZGlyZWN0bHkgKGJ5cGFzc2VzIFByb3h5IHRyYXBzKS4gQnkgdXNpbmcgdGhlIHJlYWxcbiAgLy8gYXJyYXksIGNvbnNvbGUubG9nIHNob3dzIGNvcnJlY3QgdmFsdWVzLiBUaGUgdGFyZ2V0IHJlZmVyZW5jZSBpcyBmaXhlZFxuICAvLyBhdCBjcmVhdGlvbiB0aW1lIOKAlCBhZnRlciBtdXRhdGlvbnMsIHRoZSBwcm94eSByZXR1cm5zIGEgbmV3IHByb3h5XG4gIC8vICh2aWEgY2FjaGUgaW52YWxpZGF0aW9uKSB3aXRoIHRoZSBmcmVzaCBhcnJheSBhcyB0YXJnZXQuXG4gIGNvbnN0IHRhcmdldCA9IGdldEN1cnJlbnQoKSBhcyBUW107XG4gIGNvbnN0IHJlYWRDdXJyZW50ID0gZ2V0Q3VycmVudCBhcyB1bmtub3duIGFzICgpID0+IHVua25vd25bXTtcbiAgY29uc3Qgd3JpdGVDb21taXQgPSBjb21taXQgYXMgdW5rbm93biBhcyAobmV4dDogYW55W10pID0+IHZvaWQ7XG4gIC8vIEVsZW1lbnQgcHJveGllcyBhcmUgY2FjaGVkIHBlciBpbmRleCBhbmQgdmFsaWRhdGVkIGJ5IHJhdyBpZGVudGl0eSDigJQgdGhlXG4gIC8vIHNhbWUgYmFyZ2FpbiB0aGUgdG9wLWxldmVsIGNoaWxkIGNhY2hlIG1ha2VzLiBXaXRob3V0IGl0LCByZWFkaW5nXG4gIC8vIGBsaW5lc1tpXS5xdHlgIGluIGEgbG9vcCB3b3VsZCBhbGxvY2F0ZSBvbmUgcHJveHkgcGVyIHJlYWQ7IHdpdGggaXQsXG4gIC8vIHJlcGVhdGVkIGFjY2VzcyB0byBhbiBVTkNIQU5HRUQgZWxlbWVudCBpcyBmcmVlIGFuZCBgbGluZXNbMF0gPT09IGxpbmVzWzBdYFxuICAvLyBob2xkcyB3aXRoaW4gYSBzdGFnZS4gQSBjb21taXQgcmVwbGFjZXMgdGhlIGFycmF5LCBzbyB0aGUgcmVmIGNoZWNrIG1pc3Nlc1xuICAvLyBhbmQgYSBmcmVzaCBwcm94eSBpcyBidWlsdCBvdmVyIHRoZSBuZXcgZWxlbWVudC5cbiAgY29uc3QgZWxlbWVudENhY2hlID0gbmV3IE1hcDxudW1iZXIsIHsgcmVmOiB1bmtub3duOyBwcm94eTogdW5rbm93biB9PigpO1xuXG4gIHJldHVybiBuZXcgUHJveHkodGFyZ2V0LCB7XG4gICAgZ2V0KF90YXJnZXQsIHByb3AsIHJlY2VpdmVyKSB7XG4gICAgICAvLyBJbnRlcmNlcHQgbXV0YXRpbmcgbWV0aG9kc1xuICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnc3RyaW5nJyAmJiBNVVRBVElOR19NRVRIT0RTLmhhcyhwcm9wKSkge1xuICAgICAgICByZXR1cm4gKC4uLmFyZ3M6IHVua25vd25bXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNsb25lID0gWy4uLmdldEN1cnJlbnQoKV07XG4gICAgICAgICAgLy8gVGhlIGFyZ3VtZW50cyBhcmUgdGhlIGFzc2lnbmVkIHZhbHVlcyDigJQgdW53cmFwIGVhY2ggb25lIChhXG4gICAgICAgICAgLy8gbnVtYmVyLCBhIGNvbXBhcmF0b3Igb3IgYSBwcmltaXRpdmUgcGFzc2VzIHRocm91Z2ggdW50b3VjaGVkKS5cbiAgICAgICAgICBjb25zdCByZXN1bHQgPSAoY2xvbmUgYXMgYW55KVtwcm9wXSguLi5hcmdzLm1hcCh1bndyYXBQcm94eSkpO1xuICAgICAgICAgIGNvbW1pdChjbG9uZSk7XG4gICAgICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICAgICAgfTtcbiAgICAgIH1cblxuICAgICAgLy8gTm9uLW11dGF0aW5nIGFjY2VzczogZGVsZWdhdGUgdG8gdGhlIGN1cnJlbnQgYXJyYXkgc25hcHNob3RcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBnZXRDdXJyZW50KCk7XG5cbiAgICAgIC8vICdsZW5ndGgnIGFuZCBpbmRleCBhY2Nlc3NcbiAgICAgIGlmIChwcm9wID09PSAnbGVuZ3RoJykgcmV0dXJuIGN1cnJlbnQubGVuZ3RoO1xuXG4gICAgICAvLyBOdW1lcmljIGluZGV4IGFjY2VzcyDigJQgdGhlIGVsZW1lbnQgam9pbnMgdGhlIHdyaXRlIGNoYWluIChzZWUgaGVhZGVyKS5cbiAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBOdW1iZXIocHJvcCk7XG4gICAgICAgIGlmIChOdW1iZXIuaXNJbnRlZ2VyKGluZGV4KSAmJiBpbmRleCA+PSAwICYmIGluZGV4IDwgY3VycmVudC5sZW5ndGgpIHtcbiAgICAgICAgICBjb25zdCBlbGVtZW50ID0gY3VycmVudFtpbmRleF07XG4gICAgICAgICAgaWYgKCFzaG91bGRXcmFwV2l0aFByb3h5KGVsZW1lbnQpKSByZXR1cm4gZWxlbWVudDtcbiAgICAgICAgICBjb25zdCBjYWNoZWQgPSBlbGVtZW50Q2FjaGUuZ2V0KGluZGV4KTtcbiAgICAgICAgICBpZiAoY2FjaGVkICYmIGNhY2hlZC5yZWYgPT09IGVsZW1lbnQpIHJldHVybiBjYWNoZWQucHJveHk7XG4gICAgICAgICAgY29uc3Qgd3JhcHBlZCA9IHdyYXBFbGVtZW50TWVtYmVyKGVsZW1lbnQsIHJlYWRDdXJyZW50LCB3cml0ZUNvbW1pdCwgaW5kZXgsIFtdLCBuZXcgU2V0PG9iamVjdD4oKSk7XG4gICAgICAgICAgZWxlbWVudENhY2hlLnNldChpbmRleCwgeyByZWY6IGVsZW1lbnQsIHByb3h5OiB3cmFwcGVkIH0pO1xuICAgICAgICAgIHJldHVybiB3cmFwcGVkO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE5vZGUuanMgdXRpbC5pbnNwZWN0IGN1c3RvbSBmb3JtYXR0aW5nXG4gICAgICBpZiAocHJvcCA9PT0gU3ltYm9sLmZvcignbm9kZWpzLnV0aWwuaW5zcGVjdC5jdXN0b20nKSkge1xuICAgICAgICByZXR1cm4gKCkgPT4gY3VycmVudDtcbiAgICAgIH1cblxuICAgICAgLy8gU3ltYm9sLml0ZXJhdG9yIGFuZCBvdGhlciBidWlsdC1pbiBzeW1ib2xzXG4gICAgICBpZiAodHlwZW9mIHByb3AgPT09ICdzeW1ib2wnKSB7XG4gICAgICAgIGNvbnN0IHZhbCA9IChjdXJyZW50IGFzIGFueSlbcHJvcF07XG4gICAgICAgIGlmICh0eXBlb2YgdmFsID09PSAnZnVuY3Rpb24nKSByZXR1cm4gdmFsLmJpbmQoY3VycmVudCk7XG4gICAgICAgIHJldHVybiB2YWw7XG4gICAgICB9XG5cbiAgICAgIC8vIEFsbCBvdGhlciBtZXRob2RzIChtYXAsIGZpbHRlciwgZm9yRWFjaCwgZmluZCwgZXRjLikgLS0gYmluZCB0byBjdXJyZW50XG4gICAgICBjb25zdCB2YWwgPSAoY3VycmVudCBhcyBhbnkpW3Byb3BdO1xuICAgICAgaWYgKHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbicpIHJldHVybiB2YWwuYmluZChjdXJyZW50KTtcbiAgICAgIHJldHVybiB2YWw7XG4gICAgfSxcblxuICAgIHNldChfdGFyZ2V0LCBwcm9wLCB2YWx1ZSkge1xuICAgICAgLy8gSW5kZXggYXNzaWdubWVudDogc2NvcGUuaXRlbXNbMl0gPSAndXBkYXRlZCdcbiAgICAgIGlmICh0eXBlb2YgcHJvcCA9PT0gJ3N0cmluZycpIHtcbiAgICAgICAgY29uc3QgaW5kZXggPSBOdW1iZXIocHJvcCk7XG4gICAgICAgIGlmIChOdW1iZXIuaXNJbnRlZ2VyKGluZGV4KSAmJiBpbmRleCA+PSAwKSB7XG4gICAgICAgICAgY29uc3QgY2xvbmUgPSBbLi4uZ2V0Q3VycmVudCgpXTtcbiAgICAgICAgICBmaWxsSG9sZXMoY2xvbmUsIGluZGV4KTsgLy8gYSB3cml0ZSBwYXN0IHRoZSBlbmQ6IHRoZSBza2lwcGVkIHNsb3RzIGFyZSBgbnVsbGAsIG5vdCBob2xlc1xuICAgICAgICAgIGNsb25lW2luZGV4XSA9IHVud3JhcFByb3h5KHZhbHVlKSBhcyBUO1xuICAgICAgICAgIGNvbW1pdChjbG9uZSk7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gU2V0dGluZyAnbGVuZ3RoJyAoZS5nLiwgYXJyLmxlbmd0aCA9IDAgdG8gY2xlYXIpXG4gICAgICBpZiAocHJvcCA9PT0gJ2xlbmd0aCcgJiYgdHlwZW9mIHZhbHVlID09PSAnbnVtYmVyJykge1xuICAgICAgICBjb25zdCBjbG9uZSA9IFsuLi5nZXRDdXJyZW50KCldO1xuICAgICAgICBmaWxsSG9sZXMoY2xvbmUsIHZhbHVlKTsgLy8gZ3Jvd3RoOiB0aGUgbmV3IHNsb3RzIGFyZSBgbnVsbGAsIG5vdCBob2xlc1xuICAgICAgICBjbG9uZS5sZW5ndGggPSB2YWx1ZTtcbiAgICAgICAgY29tbWl0KGNsb25lKTtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB0cnVlOyAvLyBpZ25vcmUgb3RoZXIgc2V0IG9wZXJhdGlvbnNcbiAgICB9LFxuXG4gICAgLy8gYGRlbGV0ZSBpdGVtc1syXWAg4oCUIHdpdGhvdXQgdGhpcyB0cmFwIHRoZSBkZWZhdWx0IHJlYWNoZXMgdGhlIFJBVyBhcnJheVxuICAgIC8vIGNhcHR1cmVkIGFzIHRoZSBwcm94eSB0YXJnZXQsIG11dGF0aW5nIGNvbW1pdHRlZCBzdGF0ZSB3aXRoIG5vIGNvbW1pdFxuICAgIC8vIHJlY29yZC4gQ29weS1vbi13cml0ZSBsaWtlIGV2ZXJ5IG90aGVyIG11dGF0aW9uOyBKUyBgZGVsZXRlYCBvbiBhbiBpbmRleFxuICAgIC8vIGxlYXZlcyB0aGUgc2xvdCBlbXB0eSBhbmQgdGhlIGxlbmd0aCB1bmNoYW5nZWQsIGFuZCBzbyBkb2VzIHRoaXMg4oCUIHRoZVxuICAgIC8vIGVtcHRpZWQgc2xvdCBjb21taXRzIGFzIGBudWxsYCwgSlNPTidzIG9ubHkgc3BlbGxpbmcgZm9yIGFuIGFycmF5IGhvbGUuXG4gICAgZGVsZXRlUHJvcGVydHkoX3RhcmdldCwgcHJvcCkge1xuICAgICAgY29uc3QgY2xvbmUgPSBbLi4uZ2V0Q3VycmVudCgpXTtcbiAgICAgIGNvbnN0IGluZGV4ID0gdHlwZW9mIHByb3AgPT09ICdzdHJpbmcnID8gTnVtYmVyKHByb3ApIDogTmFOO1xuICAgICAgaWYgKE51bWJlci5pc0ludGVnZXIoaW5kZXgpICYmIGluZGV4ID49IDAgJiYgaW5kZXggPCBjbG9uZS5sZW5ndGgpIChjbG9uZSBhcyB1bmtub3duW10pW2luZGV4XSA9IG51bGw7XG4gICAgICBlbHNlIGRlbGV0ZSAoY2xvbmUgYXMgYW55KVtwcm9wXTtcbiAgICAgIGNvbW1pdChjbG9uZSk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9LFxuXG4gICAgaGFzKF90YXJnZXQsIHByb3ApIHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBnZXRDdXJyZW50KCk7XG4gICAgICByZXR1cm4gUmVmbGVjdC5oYXMoY3VycmVudCwgcHJvcCk7XG4gICAgfSxcblxuICAgIG93bktleXMoKSB7XG4gICAgICBjb25zdCBjdXJyZW50ID0gZ2V0Q3VycmVudCgpO1xuICAgICAgcmV0dXJuIFJlZmxlY3Qub3duS2V5cyhjdXJyZW50KTtcbiAgICB9LFxuXG4gICAgZ2V0T3duUHJvcGVydHlEZXNjcmlwdG9yKF90YXJnZXQsIHByb3ApIHtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSBnZXRDdXJyZW50KCk7XG4gICAgICByZXR1cm4gT2JqZWN0LmdldE93blByb3BlcnR5RGVzY3JpcHRvcihjdXJyZW50LCBwcm9wKTtcbiAgICB9LFxuICB9KTtcbn1cbiJdfQ==
261
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXJyYXlUcmFwcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3NyYy9saWIvcmVhY3RpdmUvYXJyYXlUcmFwcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EyREc7QUFFSCxPQUFPLEVBQUUsbUJBQW1CLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNyRCxPQUFPLEVBQUUsV0FBVyxFQUFFLG1CQUFtQixFQUFFLFVBQVUsRUFBRSxXQUFXLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDMUYsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBQ25ELE9BQU8sRUFBa0IsV0FBVyxFQUFFLGNBQWMsRUFBRSxXQUFXLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUUzRiw4RUFBOEU7QUFDOUUsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUMvQixNQUFNO0lBQ04sS0FBSztJQUNMLE9BQU87SUFDUCxTQUFTO0lBQ1QsUUFBUTtJQUNSLE1BQU07SUFDTixTQUFTO0lBQ1QsTUFBTTtJQUNOLFlBQVk7Q0FDYixDQUFDLENBQUM7QUFLSCxnRkFBZ0Y7QUFFaEY7c0VBQ3NFO0FBQ3RFLFNBQVMsT0FBTyxDQUFDLE9BQWtCLEVBQUUsSUFBcUI7SUFDeEQsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRO1FBQUUsT0FBTyxTQUFTLENBQUM7SUFDL0MsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQzNCLE9BQU8sTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLEtBQUssR0FBRyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUM3RixDQUFDO0FBRUQsdUdBQXVH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LEdBQUcsVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQy9CLElBQUksS0FBSyxLQUFLLFNBQVM7Z0JBQUUsUUFBUSxDQUFDLElBQUksRUFBRSxLQUFLLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO2lCQUN4RCxJQUFJLElBQUksS0FBSyxRQUFRLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUTtnQkFBRSxTQUFTLENBQUMsSUFBSSxFQUFFLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBQztZQUN2RixPQUFPLElBQUksQ0FBQyxDQUFDLGdGQUFnRjtRQUMvRixDQUFDO1FBQ0QsY0FBYyxDQUFDLE9BQU8sRUFBRSxJQUFJO1lBQzFCLFVBQVUsQ0FBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQzlCLE9BQU8sSUFBSSxDQUFDO1FBQ2QsQ0FBQztRQUNELEdBQUcsRUFBRSxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLEVBQUUsSUFBSSxDQUFDO1FBQ2pELE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3RDLHdCQUF3QixFQUFFLENBQUMsT0FBTyxFQUFFLElBQUksRUFBRSxFQUFFLENBQUMsTUFBTSxDQUFDLHdCQUF3QixDQUFDLElBQUksRUFBRSxFQUFFLElBQUksQ0FBQztLQUMzRixDQUFDLENBQUM7QUFDTCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiByZWFjdGl2ZS9hcnJheVRyYXBzIC0tIEFycmF5IG11dGF0aW9uIGludGVyY2VwdGlvbiB2aWEgUHJveHkuXG4gKlxuICogV2hlbiBzY29wZS5pdGVtcyBpcyBhbiBhcnJheSwgd2UgcmV0dXJuIGEgUHJveHkgdGhhdCBpbnRlcmNlcHRzIG11dGF0aW5nXG4gKiBtZXRob2RzIChwdXNoLCBwb3AsIHNwbGljZSwgZXRjLikgQU5EIGluZGV4ZWQgYWNjZXNzLiBFYWNoIG11dGF0aW9uOlxuICogMS4gQ2xvbmVzIHRoZSBjdXJyZW50IGFycmF5XG4gKiAyLiBBcHBsaWVzIHRoZSBtdXRhdGlvbiB0byB0aGUgY2xvbmVcbiAqIDMuIENvbW1pdHMgdGhlIG5ldyBhcnJheSB2aWEgdGhlIGNvbW1pdCBjYWxsYmFja1xuICpcbiAqIE5vbi1tdXRhdGluZyBtZXRob2RzIChtYXAsIGZpbHRlciwgZm9yRWFjaCwgZXRjLikgcGFzcyB0aHJvdWdoIHRvIHRoZVxuICogY3VycmVudCBhcnJheSBzbmFwc2hvdCB3aXRob3V0IGludGVyY2VwdGlvbi5cbiAqXG4gKiBUaGUgb3JpZ2luYWwgYXJyYXkgaW4gc3RhdGUgaXMgTkVWRVIgbXV0YXRlZCBkaXJlY3RseSAtLSBhbGwgd3JpdGVzIGdvXG4gKiB0aHJvdWdoIHRoZSBjb21taXQgY2FsbGJhY2sgd2hpY2ggY2FsbHMgc2V0VmFsdWUvdXBkYXRlVmFsdWUuXG4gKlxuICog4pSA4pSAIE9ubHkgdGhlIEFTU0lHTkVEIHZhbHVlIGlzIHVud3JhcHBlZCAoOS4yMy4wKSDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAqIExhbmRtaW5lIDEgc2F5cyB0aGUgc2V0IHRyYXAgSlNPTi1yb3VuZC10cmlwcyB0aGUgdmFsdWUgdGhlIGNhbGxlciBoYW5kZWRcbiAqIGluLiBGb3IgYW4gYXJyYXkgdGhhdCBpcyB0aGUgaW5kZXgtYXNzaWduZWQgZWxlbWVudCwgYSBtdXRhdGluZyBtZXRob2Qnc1xuICogYXJndW1lbnRzIChgcHVzaCh4KWAsIGBzcGxpY2UoaSwgbiwgLi4uaXRlbXMpYCwgYGZpbGwoeClgKSwgb3IgdGhlIGxlYWYgYW5cbiAqIGVsZW1lbnQgcHJveHkgd3JpdGVzIOKAlCBhbmQgaXQgaXMgdW53cmFwcGVkIEhFUkUsIGF0IHRoZSB0cmFwIHRoYXQgcmVjZWl2ZXNcbiAqIGl0LiBUaGUgcmVidWlsdCBhcnJheSBpcyBoYW5kZWQgdG8gYGNvbW1pdGAgYXMgaXQgaXM6IGV2ZXJ5IHNpYmxpbmcgdGhlXG4gKiBjYWxsZXIgZGlkIG5vdCB0b3VjaCBwYXNzZXMgdGhyb3VnaCBieSByZWZlcmVuY2UsIGBEYXRlYHMgYW5kIGBNYXBgc1xuICogaW50YWN0LiBVbnRpbCA5LjIzLjAgdGhlIGNvbW1pdCBjYWxsYmFja3Mgcm91bmQtdHJpcHBlZCB0aGUgV0hPTEUgcmVidWlsdFxuICogYXJyYXksIHdoaWNoIHN0cmluZ2lmaWVkIHVudG91Y2hlZCBzaWJsaW5ncyBhbmQgd2FzIE8oTikgcGVyIGVsZW1lbnQgd3JpdGUuXG4gKiBUaGUgb25lIHRoaW5nIHRoZSByb3VuZC10cmlwIHVzZWQgdG8gZG8gZm9yIHRoZSBhcnJheSdzIG93biBzaGFwZSDigJQgYW5cbiAqIGVtcHRpZWQgb3Igc2tpcHBlZCBzbG90IGJlY2FtZSBgbnVsbGAsIEpTT04ncyBvbmx5IHNwZWxsaW5nIGZvciBhIGhvbGUg4oCUXG4gKiBpcyBub3cgZG9uZSBleHBsaWNpdGx5IGJ5IHRoZSB0cmFwcyB0aGF0IGNhbiBjcmVhdGUgb25lIChgZGVsZXRlIGFycltpXWAsXG4gKiBgYXJyW2ldID0gdmAgcGFzdCB0aGUgZW5kLCBgYXJyLmxlbmd0aCA9IG5gIGdyb3d0aCkuXG4gKlxuICog4pSA4pSAIEluZGV4ZWQgYWNjZXNzIGlzIHBhcnQgb2YgdGhlIGNoYWluICg5LjIyLjApIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICogYGFycltpXWAgdXNlZCB0byBoYW5kIGJhY2sgdGhlIFJBVyBlbGVtZW50LCB3aGljaCBicm9rZSB0aGUgcHJveHkgY2hhaW4gYXRcbiAqIGV4YWN0bHkgdGhlIHBvaW50IHVzZXJzIHdyaXRlIHRocm91Z2ggaXQ6IGBvcmRlci5saW5lc1swXS5xdHkgPSA0YCB3YXMgYW5cbiAqIGluLXBsYWNlIG11dGF0aW9uIG9mIGEgYm9ycm93ZWQgcmVhZCDigJQgbm8gdHJhcCwgbm8gdHJhY2Ugcm93LCBubyBjb21taXQuXG4gKiBCZWZvcmUgdGhlIHN0YWdlJ3MgZmlyc3Qgc3RhZ2VkIHdyaXRlIHRoYXQgYm9ycm93ZWQgdmFsdWUgSVMgY29tbWl0dGVkXG4gKiBzaGFyZWQgbWVtb3J5LCBzbyB0aGUgbXV0YXRpb24gbW92ZWQgc3RhdGUgd2hpbGUgdGhlIGxvZyBzdGF5ZWQgZW1wdHk7IGFmdGVyXG4gKiBpdCwgdGhlIG11dGF0aW9uIGxhbmRlZCBpbiB0aGUgcHJpdmF0ZSBidWZmZXIgY2xvbmUgYW5kIHdhcyBkcm9wcGVkLiBTYW1lXG4gKiBleHByZXNzaW9uLCB0d28gc2lsZW50IG91dGNvbWVzLlxuICpcbiAqIE5vdyBhbiBpbmRleGVkIHJlYWQgb2YgYSB3cmFwcGFibGUgZWxlbWVudCByZXR1cm5zIGFuIEVMRU1FTlQgUFJPWFkgdGhhdFxuICogYWNjdW11bGF0ZXMgdGhlIHBhdGggaW5zaWRlIHRoZSBlbGVtZW50IGFuZCwgb24gd3JpdGUsIHJlYnVpbGRzIHRoZSBhcnJheVxuICogaW1tdXRhYmx5IChgc3RydWN0dXJhbFdyaXRlLnNldEluUGF0aGAsIGJlaGluZCBgd3JpdGVUcmFwcy5lbGVtZW50U2lua2ApXG4gKiBhbmQgaGFuZHMgdGhlIHdob2xlIG5ldyBhcnJheSB0byBgY29tbWl0YCDigJQgdGhlIHNhbWUgZnVubmVsIGBwdXNoYCBhbHJlYWR5XG4gKiB1c2VkLiBPbmUgd3JpdGUgcGF0aCBmb3IgdGhlIHdob2xlIGFycmF5LCB3aGF0ZXZlciBkZXB0aCBpdCBpcyBhZGRyZXNzZWQgYXQuXG4gKlxuICog4pSA4pSAIFdoYXQgaXMgc3RpbGwgTk9UIHNlZW4gKGJ5IGRlc2lnbikg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gKiBFbGVtZW50cyByZWFjaGVkIFdJVEhPVVQgYW4gaW5kZXgg4oCUIGBmaW5kKClgLCBgZmlsdGVyKClgLCBgZm9y4oCmb2ZgLFxuICogYGZvckVhY2hgLCBkZXN0cnVjdHVyaW5nIOKAlCBhcmUgaGFuZGVkIGJhY2sgcmF3LCBiZWNhdXNlIHdyYXBwaW5nIHRoZW0gd291bGRcbiAqIG1lYW4gcmV0dXJuaW5nIHByb3hpZXMgb3V0IG9mIGV2ZXJ5IHJlYWQgbWV0aG9kIChgbWFwYCB3b3VsZCBidWlsZCBhbiBhcnJheVxuICogb2YgcHJveGllcykgZm9yIGEgY29zdCB0aGUgbGlicmFyeSBzaG91bGQgbm90IHBheS4gTXV0YXRpbmcgb25lIG9mIHRob3NlIGlzXG4gKiBub3QgbG9zdCBpbiBzaWxlbmNlIGVpdGhlcjogYFN0YWdlQ29udGV4dGAgY29tcGFyZXMgd2hhdCBhIHN0YWdlIFJFQUQgd2l0aFxuICogd2hhdCB0aGUgdmFsdWUgaG9sZHMgYXQgY29tbWl0IGFuZCwgaW4gZGV2IG1vZGUsIHdhcm5zIHdpdGggdGhlIGV4YWN0IHBhdGguXG4gKiBTZWUgc3JjL2xpYi9yZWFjdGl2ZS9SRUFETUUubWQuXG4gKlxuICog4pSA4pSAIFNoYXBlICg5LjIzLjEpIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICogYGNyZWF0ZUFycmF5UHJveHlgIGFuZCBgY3JlYXRlRWxlbWVudFByb3h5YCBhcmUgT1JDSEVTVFJBVE9SUzogdGhleSB3aXJlXG4gKiB0cmFwcyBhbmQgaG9sZCB0aGUgY2FjaGVzLiBFdmVyeSB0cmFwIGJvZHkgaXMgYSBuYW1lZCBsZWFmIGJlbG93IOKAlCBvbmVcbiAqIGNvbmNlcm4gZWFjaCDigJQgYW5kIHRoZSBlbGVtZW50IHByb3h5J3Mgc2V0L2RlbGV0ZS9nZXQgdHJhcHMgYXJlIHRoZSBTQU1FXG4gKiBsZWF2ZXMgdGhlIG5lc3RlZCBhbmQgdGVybWluYWwgb2JqZWN0IHByb3hpZXMgdXNlIChgd3JpdGVUcmFwcy50c2AsXG4gKiBgbGl2ZVZpZXcudHNgKSwgb3ZlciBhbiB7QGxpbmsgZWxlbWVudFNpbmt9LiBBIGZpeCBsYW5kcyBpbiBhIGxlYWYgb25jZS5cbiAqL1xuXG5pbXBvcnQgeyBzaG91bGRXcmFwV2l0aFByb3h5IH0gZnJvbSAnLi9hbGxvd2xpc3QuanMnO1xuaW1wb3J0IHsgbGl2ZUdldFRyYXAsIGxpdmVJbnNwZWN0aW9uVHJhcHMsIGxpdmVPYmplY3QsIE1lbWJlckNhY2hlIH0gZnJvbSAnLi9saXZlVmlldy5qcyc7XG5pbXBvcnQgeyB1bndyYXBQcm94eSB9IGZyb20gJy4vc3RydWN0dXJhbFdyaXRlLmpzJztcbmltcG9ydCB7IHR5cGUgV3JpdGVTaW5rLCBlbGVtZW50U2luaywgc2lua0RlbGV0ZVRyYXAsIHNpbmtTZXRUcmFwIH0gZnJvbSAnLi93cml0ZVRyYXBzLmpzJztcblxuLyoqIE1ldGhvZHMgdGhhdCBtdXRhdGUgdGhlIGFycmF5IGluLXBsYWNlLiBXZSBpbnRlcmNlcHQgYW5kIGNvcHktb24td3JpdGUuICovXG5jb25zdCBNVVRBVElOR19NRVRIT0RTID0gbmV3IFNldChbXG4gICdwdXNoJyxcbiAgJ3BvcCcsXG4gICdzaGlmdCcsXG4gICd1bnNoaWZ0JyxcbiAgJ3NwbGljZScsXG4gICdzb3J0JyxcbiAgJ3JldmVyc2UnLFxuICAnZmlsbCcsXG4gICdjb3B5V2l0aGluJyxcbl0pO1xuXG50eXBlIFJlYWQgPSAoKSA9PiB1bmtub3duW107XG50eXBlIFdyaXRlID0gKG5leHQ6IHVua25vd25bXSkgPT4gdm9pZDtcblxuLy8gLS0gTGVhdmVzOiByZWFkcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuLyoqIFdIWSBgTnVtYmVyKHByb3ApYDogdGhlIGhpc3RvcmljYWwgcmVhZGluZyBvZiBhbiBpbmRleCBuYW1lIOKAlCBgJzAxJ2AgYW5kXG4gKiAgYCcnYCBhZGRyZXNzIHNsb3RzIDEgYW5kIDAsIGFzIHRoZXkgYWx3YXlzIGhhdmUuIEluIHJhbmdlIG9ubHkuICovXG5mdW5jdGlvbiBpbmRleEluKGN1cnJlbnQ6IHVua25vd25bXSwgcHJvcDogc3RyaW5nIHwgc3ltYm9sKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHR5cGVvZiBwcm9wICE9PSAnc3RyaW5nJykgcmV0dXJuIHVuZGVmaW5lZDtcbiAgY29uc3QgaW5kZXggPSBOdW1iZXIocHJvcCk7XG4gIHJldHVybiBOdW1iZXIuaXNJbnRlZ2VyKGluZGV4KSAmJiBpbmRleCA+PSAwICYmIGluZGV4IDwgY3VycmVudC5sZW5ndGggPyBpbmRleCA6IHVuZGVmaW5lZDtcbn1cblxuLyoqIEEgbm9uLW5lZ2F0aXZlIGludGVnZXIgaW5kZXggbmFtZWQgYnkgYHByb3BgIChhbnkgcmFuZ2Ug4oCUIGEgd3JpdGUgcGFzdCB0aGUgZW5kIGdyb3dzIHRoZSBhcnJheSkuICovXG5mdW5jdGlvbiBpbmRleE5hbWVkKHByb3A6IHN0cmluZyB8IHN5bWJvbCk6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIGlmICh0eXBlb2YgcHJvcCAhPT0gJ3N0cmluZycpIHJldHVybiB1bmRlZmluZWQ7XG4gIGNvbnN0IGluZGV4ID0gTnVtYmVyKHByb3ApO1xuICByZXR1cm4gTnVtYmVyLmlzSW50ZWdlcihpbmRleCkgJiYgaW5kZXggPj0gMCA/IGluZGV4IDogdW5kZWZpbmVkO1xufVxuXG4vKiogV0hZOiBhIG5vbi1tdXRhdGluZyByZWFkIGFuc3dlcnMgZnJvbSB0aGUgQ1VSUkVOVCBhcnJheSwgbmV2ZXIgdGhlXG4gKiAgY3JlYXRpb24tdGltZSB0YXJnZXQg4oCUIGEgbWV0aG9kIGlzIGJvdW5kIHRvIGl0LCBhbnl0aGluZyBlbHNlIHJlYWQgb2ZmIGl0LiAqL1xuZnVuY3Rpb24gYm91bmRNZW1iZXIoY3VycmVudDogdW5rbm93bltdLCBwcm9wOiBzdHJpbmcgfCBzeW1ib2wpOiB1bmtub3duIHtcbiAgY29uc3QgdmFsID0gKGN1cnJlbnQgYXMgYW55KVtwcm9wXTtcbiAgcmV0dXJuIHR5cGVvZiB2YWwgPT09ICdmdW5jdGlvbicgPyB2YWwuYmluZChjdXJyZW50KSA6IHZhbDtcbn1cblxudHlwZSBFbGVtZW50Q2FjaGUgPSBNYXA8bnVtYmVyLCB7IHJlZjogdW5rbm93bjsgcHJveHk6IHVua25vd24gfT47XG5cbi8qKiBXSFkgdGhlIGNhY2hlOiByZWFkaW5nIGBsaW5lc1tpXS5xdHlgIGluIGEgbG9vcCBtdXN0IG5vdCBhbGxvY2F0ZSBhIHByb3h5XG4gKiAgcGVyIHJlYWQsIGFuZCBgbGluZXNbMF0gPT09IGxpbmVzWzBdYCBtdXN0IGhvbGQgd2l0aGluIGEgc3RhZ2UuIFZhbGlkYXRlZCBieVxuICogIHJhdyBpZGVudGl0eSDigJQgYSBjb21taXQgcmVwbGFjZXMgdGhlIGFycmF5LCB0aGUgcmVmIGNoZWNrIG1pc3NlcywgYW5kIGFcbiAqICBmcmVzaCBwcm94eSBpcyBidWlsdCBvdmVyIHRoZSBuZXcgZWxlbWVudC4gQSBwcmltaXRpdmUgaXMgaGFuZGVkIGJhY2sgcmF3LiAqL1xuZnVuY3Rpb24gY2FjaGVkRWxlbWVudChjYWNoZTogRWxlbWVudENhY2hlLCBlbGVtZW50OiB1bmtub3duLCBpbmRleDogbnVtYmVyLCByZWFkOiBSZWFkLCB3cml0ZTogV3JpdGUpOiB1bmtub3duIHtcbiAgaWYgKCFzaG91bGRXcmFwV2l0aFByb3h5KGVsZW1lbnQpKSByZXR1cm4gZWxlbWVudDtcbiAgY29uc3QgY2FjaGVkID0gY2FjaGUuZ2V0KGluZGV4KTtcbiAgaWYgKGNhY2hlZCAmJiBjYWNoZWQucmVmID09PSBlbGVtZW50KSByZXR1cm4gY2FjaGVkLnByb3h5O1xuICBjb25zdCB3cmFwcGVkID0gd3JhcEVsZW1lbnRNZW1iZXIoZWxlbWVudCwgZWxlbWVudFNpbmsocmVhZCwgd3JpdGUsIGluZGV4KSwgW10sIG5ldyBTZXQ8b2JqZWN0PigpKTtcbiAgY2FjaGUuc2V0KGluZGV4LCB7IHJlZjogZWxlbWVudCwgcHJveHk6IHdyYXBwZWQgfSk7XG4gIHJldHVybiB3cmFwcGVkO1xufVxuXG4vLyAtLSBMZWF2ZXM6IHdyaXRlcyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4vKiogU2xvdHMgZnJvbSB0aGUgY3VycmVudCBlbmQgdXAgdG8gKG5vdCBpbmNsdWRpbmcpIGB1cFRvYCBiZWNvbWUgYG51bGxgIOKAlFxuICogIHRoZSBKU09OIHNwZWxsaW5nIG9mIGEgaG9sZSwgd2hpY2ggaXMgd2hhdCB0aGUgd2hvbGUtYXJyYXkgcm91bmQtdHJpcCB1c2VkXG4gKiAgdG8gcHJvZHVjZSBmb3IgdGhlbS4gTm8tb3Agd2hlbiBgdXBUb2AgaXMgd2l0aGluIHRoZSBhcnJheS4gKi9cbmZ1bmN0aW9uIGZpbGxIb2xlcyhhcnI6IHVua25vd25bXSwgdXBUbzogbnVtYmVyKTogdm9pZCB7XG4gIGZvciAobGV0IGkgPSBhcnIubGVuZ3RoOyBpIDwgdXBUbzsgaSsrKSBhcnJbaV0gPSBudWxsO1xufVxuXG4vKiogV0hZOiBhIG11dGF0aW5nIG1ldGhvZCBydW5zIG9uIGEgQ09QWSwgd2l0aCBpdHMgYXJndW1lbnRzIHVud3JhcHBlZCAodGhleVxuICogIGFyZSB0aGUgYXNzaWduZWQgdmFsdWVzOyBhIG51bWJlciBvciBhIGNvbXBhcmF0b3IgcGFzc2VzIHRocm91Z2gpLCBhbmQgdGhlXG4gKiAgY29weSBpcyBjb21taXR0ZWQgd2hvbGUuIFRoZSBhcnJheSBpbiBzdGF0ZSBpcyBuZXZlciB0b3VjaGVkLiAqL1xuZnVuY3Rpb24gbXV0YXRpbmdNZXRob2QocmVhZDogUmVhZCwgd3JpdGU6IFdyaXRlLCBuYW1lOiBzdHJpbmcpOiAoLi4uYXJnczogdW5rbm93bltdKSA9PiB1bmtub3duIHtcbiAgcmV0dXJuICguLi5hcmdzKSA9PiB7XG4gICAgY29uc3QgY2xvbmUgPSBbLi4ucmVhZCgpXTtcbiAgICBjb25zdCByZXN1bHQgPSAoY2xvbmUgYXMgYW55KVtuYW1lXSguLi5hcmdzLm1hcCh1bndyYXBQcm94eSkpO1xuICAgIHdyaXRlKGNsb25lKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9O1xufVxuXG4vKiogYGFycltpXSA9IHZgOiBjb3B5LCBgbnVsbGAgdGhlIHNsb3RzIGEgd3JpdGUgcGFzdCB0aGUgZW5kIHNraXBzLCBwbGFjZSB0aGUgdW53cmFwcGVkIHZhbHVlLCBjb21taXQuICovXG5mdW5jdGlvbiBzZXRJbmRleChyZWFkOiBSZWFkLCB3cml0ZTogV3JpdGUsIGluZGV4OiBudW1iZXIsIHZhbHVlOiB1bmtub3duKTogdm9pZCB7XG4gIGNvbnN0IGNsb25lID0gWy4uLnJlYWQoKV07XG4gIGZpbGxIb2xlcyhjbG9uZSwgaW5kZXgpO1xuICBjbG9uZVtpbmRleF0gPSB1bndyYXBQcm94eSh2YWx1ZSk7XG4gIHdyaXRlKGNsb25lKTtcbn1cblxuLyoqIGBhcnIubGVuZ3RoID0gbmA6IGNvcHksIGBudWxsYCB0aGUgc2xvdHMgZ3Jvd3RoIGFkZHMsIHRydW5jYXRlIG9yIGV4dGVuZCwgY29tbWl0LiAqL1xuZnVuY3Rpb24gc2V0TGVuZ3RoKHJlYWQ6IFJlYWQsIHdyaXRlOiBXcml0ZSwgbGVuZ3RoOiBudW1iZXIpOiB2b2lkIHtcbiAgY29uc3QgY2xvbmUgPSBbLi4ucmVhZCgpXTtcbiAgZmlsbEhvbGVzKGNsb25lLCBsZW5ndGgpO1xuICBjbG9uZS5sZW5ndGggPSBsZW5ndGg7XG4gIHdyaXRlKGNsb25lKTtcbn1cblxuLyoqIFdIWTogd2l0aG91dCB0aGlzIHRyYXAgYGRlbGV0ZSBpdGVtc1syXWAgcmVhY2hlcyB0aGUgUkFXIGFycmF5IGNhcHR1cmVkXG4gKiAgYXMgdGhlIHByb3h5IHRhcmdldCDigJQgY29tbWl0dGVkIHN0YXRlLCBubyBjb21taXQgcmVjb3JkLiBKUyBgZGVsZXRlYCBvbiBhblxuICogIGluZGV4IGxlYXZlcyB0aGUgc2xvdCBlbXB0eSBhbmQgdGhlIGxlbmd0aCB1bmNoYW5nZWQsIGFuZCBzbyBkb2VzIHRoaXM6XG4gKiAgdGhlIGVtcHRpZWQgc2xvdCBjb21taXRzIGFzIGBudWxsYCwgSlNPTidzIG9ubHkgc3BlbGxpbmcgZm9yIGEgaG9sZS4gKi9cbmZ1bmN0aW9uIGRlbGV0ZVNsb3QocmVhZDogUmVhZCwgd3JpdGU6IFdyaXRlLCBwcm9wOiBzdHJpbmcgfCBzeW1ib2wpOiB2b2lkIHtcbiAgY29uc3QgY2xvbmUgPSBbLi4ucmVhZCgpXTtcbiAgY29uc3QgaW5kZXggPSB0eXBlb2YgcHJvcCA9PT0gJ3N0cmluZycgPyBOdW1iZXIocHJvcCkgOiBOYU47XG4gIGlmIChOdW1iZXIuaXNJbnRlZ2VyKGluZGV4KSAmJiBpbmRleCA+PSAwICYmIGluZGV4IDwgY2xvbmUubGVuZ3RoKSBjbG9uZVtpbmRleF0gPSBudWxsO1xuICBlbHNlIGRlbGV0ZSAoY2xvbmUgYXMgYW55KVtwcm9wXTtcbiAgd3JpdGUoY2xvbmUpO1xufVxuXG4vLyAtLSBMZWF2ZXM6IHRoZSBjaGFpbiBiZWxvdyBhbiBlbGVtZW50IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKlxuICogV0hZOiBhbiBhcnJheSBhbnl3aGVyZSBiZWxvdyBhIHNpbmsncyByb290IGlzIE9ORSB3cml0ZSBwYXRoIOKAlCBpdCByZWFkc1xuICogdGhyb3VnaCB0aGUgc2luayBhbmQgY29tbWl0cyB0aGUgV0hPTEUgbmV3IGFycmF5IGJhY2sgdGhyb3VnaCBpdCwgc29cbiAqIGBwdXNoYCB0aHJlZSBsZXZlbHMgZG93biBhbmQgYGFycltpXS54ID0gdmAgYXQgdGhlIHRvcCBzaGFyZSBhIGZ1bm5lbC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFycmF5UHJveHlBdChzaW5rOiBXcml0ZVNpbmssIHBhdGg6IHJlYWRvbmx5IHN0cmluZ1tdKTogdW5rbm93bltdIHtcbiAgcmV0dXJuIGNyZWF0ZUFycmF5UHJveHkoXG4gICAgKCkgPT4gKHNpbmsucmVhZEF0KHBhdGgpIGFzIHVua25vd25bXSkgPz8gW10sXG4gICAgKG5leHQpID0+IHNpbmsucHV0KHBhdGgsIG5leHQpLFxuICApO1xufVxuXG4vKipcbiAqIFdyYXAgYSB2YWx1ZSByZWFkIG91dCBvZiBhbiBlbGVtZW50OiBhcnJheXMgYmVjb21lIGFycmF5IHByb3hpZXMgd2hvc2VcbiAqIGNvbW1pdHMgcm91dGUgYmFjayB0aHJvdWdoIHRoZSBvd25pbmcgYXJyYXksIHBsYWluIG9iamVjdHMgYmVjb21lIGVsZW1lbnRcbiAqIHByb3hpZXMgb25lIGxldmVsIGRlZXBlciwgZXZlcnl0aGluZyBlbHNlIGlzIHJldHVybmVkIGFzLWlzLiBBIHZhbHVlIGFscmVhZHlcbiAqIG9uIHRoZSBhY2Nlc3MgY2hhaW4gKGEgY3ljbGUpIGlzIHJldHVybmVkIHJhdyDigJQgdGhlIHNhbWUgYmFjay1lZGdlIHRoZVxuICogbmVzdGVkLW9iamVjdCB0ZXJtaW5hbCBwcm94eSB0YWtlcy5cbiAqL1xuZnVuY3Rpb24gd3JhcEVsZW1lbnRNZW1iZXIodmFsdWU6IHVua25vd24sIHNpbms6IFdyaXRlU2luaywgcGF0aDogc3RyaW5nW10sIHZpc2l0ZWQ6IFNldDxvYmplY3Q+KTogdW5rbm93biB7XG4gIGlmICghc2hvdWxkV3JhcFdpdGhQcm94eSh2YWx1ZSkpIHJldHVybiB2YWx1ZTtcbiAgaWYgKHZpc2l0ZWQuaGFzKHZhbHVlIGFzIG9iamVjdCkpIHJldHVybiB2YWx1ZTtcbiAgY29uc3QgYnJhbmNoID0gbmV3IFNldCh2aXNpdGVkKTtcbiAgYnJhbmNoLmFkZCh2YWx1ZSBhcyBvYmplY3QpO1xuICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiBhcnJheVByb3h5QXQoc2luaywgcGF0aCk7XG4gIHJldHVybiBjcmVhdGVFbGVtZW50UHJveHkodmFsdWUgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4sIHNpbmssIHBhdGgsIGJyYW5jaCk7XG59XG5cbi8vIC0tIE9yY2hlc3RyYXRvcnMgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKlxuICogUHJveHkgb3ZlciBvbmUgT0JKRUNUIGVsZW1lbnQgKG9yIGFuIG9iamVjdCBuZXN0ZWQgaW5zaWRlIG9uZSksIGNhcnJ5aW5nIHRoZVxuICogcGF0aCBmcm9tIHRoZSBlbGVtZW50IGRvd24gdG8gaXQuIFJlYWRzIHJlY3Vyc2U7IHdyaXRlcyBnbyBiYWNrIG91dCB0aHJvdWdoXG4gKiB0aGUgb3duaW5nIGFycmF5J3MgY29tbWl0IGNhbGxiYWNrICh0aGUge0BsaW5rIGVsZW1lbnRTaW5rfSkuXG4gKlxuICogUkVBRFMgQVJFIExJVkUuIEV2ZXJ5IHdyaXRlIHJlYnVpbGRzIHRoZSBhcnJheSBpbW11dGFibHksIHNvIHRoZSBvYmplY3QgdGhlXG4gKiBwcm94eSB3YXMgY3JlYXRlZCBvdmVyIGlzIHRoZSBQUkUtd3JpdGUgZWxlbWVudCBmb3IgZXZlciBhZnRlcjsgYSBoZWxkXG4gKiBoYW5kbGUgdGhhdCByZWFkIGZyb20gaXQgc2F3IGl0cyBvd24gd3JpdGVzIHZhbmlzaCAoYGxpbmUubiArPSAxYCB0d2ljZVxuICogZ2F2ZSAyLCBgbGluZS50b3RhbCA9IGxpbmUucXR5ICogMTBgIHVzZWQgdGhlIG9sZCBgcXR5YCwgYCd4JyBpbiBsaW5lYCB3YXNcbiAqIGZhbHNlIHJpZ2h0IGFmdGVyIGBsaW5lLnggPSAxYCkuIEV2ZXJ5IHRyYXAgdGhlcmVmb3JlIHJlc29sdmVzIHRoZSBlbGVtZW50XG4gKiB0aHJvdWdoIHRoZSBzaW5rIGZpcnN0LCBhbmQgZmFsbHMgYmFjayB0byB0aGUgY2FwdHVyZWQgb2JqZWN0IG9ubHkgd2hlblxuICogdGhlIHBhdGggbm8gbG9uZ2VyIGV4aXN0cyAodGhlIHNsb3Qgd2FzIGVtcHRpZWQgb3IgdGhlIGFycmF5IHNocmFuaykg4oCUIHRoZVxuICogc2FtZSByZWFkLXlvdXItd3JpdGVzIHRoZSBhcnJheSBwcm94eSBpdHNlbGYgaGFzIGFsd2F5cyBoYWQsIGFuZCB0aGUgc2FtZVxuICogbGF3IHRoZSBuZXN0ZWQgYW5kIHRlcm1pbmFsIG9iamVjdCBwcm94aWVzIGZvbGxvdyAobGl2ZVZpZXcudHMpLlxuICovXG5mdW5jdGlvbiBjcmVhdGVFbGVtZW50UHJveHkoXG4gIHJhdzogUmVjb3JkPHN0cmluZywgdW5rbm93bj4sXG4gIHNpbms6IFdyaXRlU2luayxcbiAgc2VnbWVudHM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICB2aXNpdGVkOiBTZXQ8b2JqZWN0Pixcbik6IHVua25vd24ge1xuICBjb25zdCBtZW1iZXJzID0gbmV3IE1lbWJlckNhY2hlKCk7XG4gIGNvbnN0IGxpdmUgPSAoKSA9PiBsaXZlT2JqZWN0KHJhdywgc2luay5yZWFkQXQoc2VnbWVudHMpKTtcbiAgcmV0dXJuIG5ldyBQcm94eShyYXcsIHtcbiAgICBnZXQ6IGxpdmVHZXRUcmFwKGxpdmUsIHNlZ21lbnRzLCAodmFsdWUsIHBhdGgpID0+IHdyYXBFbGVtZW50TWVtYmVyKHZhbHVlLCBzaW5rLCBwYXRoLCB2aXNpdGVkKSwgbWVtYmVycyksXG4gICAgc2V0OiBzaW5rU2V0VHJhcChzaW5rLCBzZWdtZW50cyksXG4gICAgZGVsZXRlUHJvcGVydHk6IHNpbmtEZWxldGVUcmFwKHNpbmssIHNlZ21lbnRzKSxcbiAgICAuLi5saXZlSW5zcGVjdGlvblRyYXBzKGxpdmUpLFxuICB9KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgUHJveHkgb3ZlciBhbiBhcnJheSB0aGF0IGludGVyY2VwdHMgbXV0YXRpbmcgb3BlcmF0aW9ucy5cbiAqXG4gKiBUaGUgYWN0dWFsIGN1cnJlbnQgYXJyYXkgaXMgdGhlIFByb3h5IHRhcmdldDogTm9kZS5qcyBjb25zb2xlLmxvZyBpbnNwZWN0c1xuICogdGhlIHRhcmdldCBkaXJlY3RseSAoYnlwYXNzZXMgUHJveHkgdHJhcHMpLCBzbyB0aGUgcmVhbCBhcnJheSBzaG93cyBjb3JyZWN0XG4gKiB2YWx1ZXMuIFRoZSB0YXJnZXQgcmVmZXJlbmNlIGlzIGZpeGVkIGF0IGNyZWF0aW9uIHRpbWUg4oCUIGFmdGVyIG11dGF0aW9ucyxcbiAqIHRoZSBwcm94eSByZXR1cm5zIGEgbmV3IHByb3h5ICh2aWEgY2FjaGUgaW52YWxpZGF0aW9uKSB3aXRoIHRoZSBmcmVzaCBhcnJheVxuICogYXMgdGFyZ2V0LlxuICpcbiAqIEBwYXJhbSBnZXRDdXJyZW50IC0gUmV0dXJucyB0aGUgY3VycmVudCBhcnJheSBzbmFwc2hvdCBmcm9tIHN0YXRlXG4gKiBAcGFyYW0gY29tbWl0IC0gQ2FsbGVkIHdpdGggdGhlIG5ldyBhcnJheSBhZnRlciBhIG11dGF0aW9uICh0cmlnZ2VycyBzZXRWYWx1ZSlcbiAqIEByZXR1cm5zIFByb3hpZWQgYXJyYXkgd2l0aCBjb3B5LW9uLXdyaXRlIHNlbWFudGljc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQXJyYXlQcm94eTxUPihnZXRDdXJyZW50OiAoKSA9PiBUW10sIGNvbW1pdDogKG5ld0FycmF5OiBUW10pID0+IHZvaWQpOiBUW10ge1xuICBjb25zdCB0YXJnZXQgPSBnZXRDdXJyZW50KCkgYXMgVFtdO1xuICBjb25zdCByZWFkID0gZ2V0Q3VycmVudCBhcyB1bmtub3duIGFzIFJlYWQ7XG4gIGNvbnN0IHdyaXRlID0gY29tbWl0IGFzIHVua25vd24gYXMgV3JpdGU7XG4gIGNvbnN0IGVsZW1lbnRzOiBFbGVtZW50Q2FjaGUgPSBuZXcgTWFwKCk7XG5cbiAgcmV0dXJuIG5ldyBQcm94eSh0YXJnZXQsIHtcbiAgICBnZXQoX3RhcmdldCwgcHJvcCkge1xuICAgICAgaWYgKHR5cGVvZiBwcm9wID09PSAnc3RyaW5nJyAmJiBNVVRBVElOR19NRVRIT0RTLmhhcyhwcm9wKSkgcmV0dXJuIG11dGF0aW5nTWV0aG9kKHJlYWQsIHdyaXRlLCBwcm9wKTtcbiAgICAgIGNvbnN0IGN1cnJlbnQgPSByZWFkKCk7XG4gICAgICBpZiAocHJvcCA9PT0gJ2xlbmd0aCcpIHJldHVybiBjdXJyZW50Lmxlbmd0aDtcbiAgICAgIGNvbnN0IGluZGV4ID0gaW5kZXhJbihjdXJyZW50LCBwcm9wKTtcbiAgICAgIGlmIChpbmRleCAhPT0gdW5kZWZpbmVkKSByZXR1cm4gY2FjaGVkRWxlbWVudChlbGVtZW50cywgY3VycmVudFtpbmRleF0sIGluZGV4LCByZWFkLCB3cml0ZSk7XG4gICAgICBpZiAocHJvcCA9PT0gU3ltYm9sLmZvcignbm9kZWpzLnV0aWwuaW5zcGVjdC5jdXN0b20nKSkgcmV0dXJuICgpID0+IGN1cnJlbnQ7XG4gICAgICByZXR1cm4gYm91bmRNZW1iZXIoY3VycmVudCwgcHJvcCk7XG4gICAgfSxcbiAgICBzZXQoX3RhcmdldCwgcHJvcCwgdmFsdWUpIHtcbiAgICAgIGNvbnN0IGluZGV4ID0gaW5kZXhOYW1lZChwcm9wKTtcbiAgICAgIGlmIChpbmRleCAhPT0gdW5kZWZpbmVkKSBzZXRJbmRleChyZWFkLCB3cml0ZSwgaW5kZXgsIHZhbHVlKTtcbiAgICAgIGVsc2UgaWYgKHByb3AgPT09ICdsZW5ndGgnICYmIHR5cGVvZiB2YWx1ZSA9PT0gJ251bWJlcicpIHNldExlbmd0aChyZWFkLCB3cml0ZSwgdmFsdWUpO1xuICAgICAgcmV0dXJuIHRydWU7IC8vIGFueSBvdGhlciBzZXQgaXMgaWdub3JlZCAoYW4gZXhwYW5kbyBvbiBhbiBhcnJheSBpcyBvdXQgb2YgY29udHJhY3Qg4oCUIFJFQURNRSlcbiAgICB9LFxuICAgIGRlbGV0ZVByb3BlcnR5KF90YXJnZXQsIHByb3ApIHtcbiAgICAgIGRlbGV0ZVNsb3QocmVhZCwgd3JpdGUsIHByb3ApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSxcbiAgICBoYXM6IChfdGFyZ2V0LCBwcm9wKSA9PiBSZWZsZWN0LmhhcyhyZWFkKCksIHByb3ApLFxuICAgIG93bktleXM6ICgpID0+IFJlZmxlY3Qub3duS2V5cyhyZWFkKCkpLFxuICAgIGdldE93blByb3BlcnR5RGVzY3JpcHRvcjogKF90YXJnZXQsIHByb3ApID0+IE9iamVjdC5nZXRPd25Qcm9wZXJ0eURlc2NyaXB0b3IocmVhZCgpLCBwcm9wKSxcbiAgfSk7XG59XG4iXX0=