@dbx-tools/shared-core 0.3.44 → 0.4.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.
- package/lib/index.d.ts +36 -0
- package/lib/index.js +30 -0
- package/lib/src/async.d.ts +152 -0
- package/lib/src/async.js +163 -0
- package/lib/src/brand.d.ts +94 -0
- package/lib/src/brand.js +123 -0
- package/lib/src/error.d.ts +76 -0
- package/lib/src/error.js +168 -0
- package/lib/src/function.d.ts +38 -0
- package/lib/src/function.js +44 -0
- package/lib/src/hash.d.ts +102 -0
- package/lib/src/hash.js +274 -0
- package/lib/src/http.d.ts +79 -0
- package/lib/src/http.js +189 -0
- package/lib/src/json.d.ts +48 -0
- package/lib/src/json.js +49 -0
- package/lib/src/log.d.ts +86 -0
- package/lib/src/log.js +352 -0
- package/lib/src/net.d.ts +246 -0
- package/lib/src/net.js +465 -0
- package/lib/src/object.d.ts +382 -0
- package/lib/src/object.js +749 -0
- package/lib/src/predicate.d.ts +81 -0
- package/lib/src/predicate.js +43 -0
- package/lib/src/string.d.ts +221 -0
- package/lib/src/string.js +509 -0
- package/lib/src/token.d.ts +30 -0
- package/lib/src/token.js +126 -0
- package/lib/tsconfig.tsbuildinfo +1 -0
- package/package.json +9 -5
|
@@ -0,0 +1,749 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Dependency-free object + iterable utilities.
|
|
3
|
+
*
|
|
4
|
+
* Value guards / coercions / shape types: {@link isRecord} narrows parsed JSON
|
|
5
|
+
* to a record, {@link toBoolean} coerces loose truthy/falsy values, {@link
|
|
6
|
+
* deepEqual} compares structurally, and {@link NameLike}/{@link NonFunctionKeys}
|
|
7
|
+
* describe object shapes.
|
|
8
|
+
*
|
|
9
|
+
* Iterable helpers: {@link generator} flattens mixed arguments; {@link sequence}
|
|
10
|
+
* wraps source(s) in a lazy, `Array`-compatible {@link Sequence}. Every
|
|
11
|
+
* transform/terminal is a standalone function operating on plain {@link
|
|
12
|
+
* Container}s (see {@link map}, {@link filter}, {@link group}, ...); the {@link
|
|
13
|
+
* Sequence} methods are thin forwarders over them so the same logic backs both
|
|
14
|
+
* the free-function and the fluent/chained styles.
|
|
15
|
+
*
|
|
16
|
+
* @module
|
|
17
|
+
*/
|
|
18
|
+
/** Narrow a readonly array to a non-empty {@link OneOrMany} tuple. */
|
|
19
|
+
export function isOneOrMany(value) {
|
|
20
|
+
return value.length > 0;
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Type guard for a {@link Collection}: an {@link Array}, {@link Set}, or
|
|
24
|
+
* {@link Map}. Narrows `value` so its element/value type is treated as `T`.
|
|
25
|
+
*
|
|
26
|
+
* @typeParam T - Element (or Map value) type asserted for the collection.
|
|
27
|
+
* @param value - Value to test.
|
|
28
|
+
* @returns `true` (narrowing `value` to {@link Collection}<`T`>) for a
|
|
29
|
+
* built-in array/set/map.
|
|
30
|
+
*/
|
|
31
|
+
export function isCollection(value) {
|
|
32
|
+
return Array.isArray(value) || value instanceof Set || value instanceof Map;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* `true` when a {@link Collection} has no elements. Uses `length` for arrays
|
|
36
|
+
* and `size` for {@link Set}/{@link Map}.
|
|
37
|
+
*
|
|
38
|
+
* @param collection - The array, set, or map to test.
|
|
39
|
+
*/
|
|
40
|
+
export function isEmpty(collection, options) {
|
|
41
|
+
function visit(value, seen) {
|
|
42
|
+
if (value == null) {
|
|
43
|
+
return true;
|
|
44
|
+
}
|
|
45
|
+
else if (typeof value === "object") {
|
|
46
|
+
if (seen?.has(value))
|
|
47
|
+
return true;
|
|
48
|
+
seen?.add(value);
|
|
49
|
+
if (Array.isArray(value)) {
|
|
50
|
+
return value.length === 0 || (seen ? value.every((item) => visit(item, seen)) : false);
|
|
51
|
+
}
|
|
52
|
+
if (value instanceof Set) {
|
|
53
|
+
return value.size === 0 || (seen ? [...value].every((item) => visit(item, seen)) : false);
|
|
54
|
+
}
|
|
55
|
+
if (value instanceof Map) {
|
|
56
|
+
return (value.size === 0 ||
|
|
57
|
+
(seen ? [...value.values()].every((item) => visit(item, seen)) : false));
|
|
58
|
+
}
|
|
59
|
+
const keys = Object.keys(value);
|
|
60
|
+
if (keys.length === 0) {
|
|
61
|
+
return true;
|
|
62
|
+
}
|
|
63
|
+
else if (seen) {
|
|
64
|
+
return keys.every((key) => visit(value[key], seen));
|
|
65
|
+
}
|
|
66
|
+
else {
|
|
67
|
+
return false;
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
else {
|
|
71
|
+
return false;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
return visit(collection, options?.recursive ? new Set() : undefined);
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Normalizes a source to an iterable of its `T` values, so Maps are treated
|
|
78
|
+
* uniformly with arrays/sets: a {@link Map} yields its *values* (matching
|
|
79
|
+
* {@link Collection}'s value-typed `T`), any other iterable yields itself. This
|
|
80
|
+
* is what {@link sequence} consumes, so a `Map` contributes values everywhere
|
|
81
|
+
* rather than `[key, value]` entries.
|
|
82
|
+
*/
|
|
83
|
+
export function values(source) {
|
|
84
|
+
return source instanceof Map ? source.values() : source;
|
|
85
|
+
}
|
|
86
|
+
/**
|
|
87
|
+
* Type guard for a {@link Container} - an iterable to be treated as a collection
|
|
88
|
+
* rather than a scalar.
|
|
89
|
+
*
|
|
90
|
+
* Deliberately excludes values that are technically iterable but should be
|
|
91
|
+
* treated as scalars here - strings, `String`/`RegExp` objects, and functions -
|
|
92
|
+
* so a lone string is never spread character-by-character.
|
|
93
|
+
*
|
|
94
|
+
* @typeParam T - Element type asserted for the iterable.
|
|
95
|
+
* @param value - Value to test.
|
|
96
|
+
* @returns `true` (narrowing `value` to {@link Container}<`T`>) for a non-string
|
|
97
|
+
* iterable.
|
|
98
|
+
*/
|
|
99
|
+
export function isContainer(value) {
|
|
100
|
+
return (value != null &&
|
|
101
|
+
typeof value !== "string" &&
|
|
102
|
+
!(value instanceof String) &&
|
|
103
|
+
!(value instanceof RegExp) &&
|
|
104
|
+
typeof value !== "function" &&
|
|
105
|
+
typeof value[Symbol.iterator] === "function");
|
|
106
|
+
}
|
|
107
|
+
function sequenceSources(...sources) {
|
|
108
|
+
const sourceIterables = [];
|
|
109
|
+
for (const source of sources) {
|
|
110
|
+
if (source == null || (isCollection(source) && isEmpty(source)))
|
|
111
|
+
continue;
|
|
112
|
+
sourceIterables.push(values(source));
|
|
113
|
+
}
|
|
114
|
+
return sourceIterables;
|
|
115
|
+
}
|
|
116
|
+
/**
|
|
117
|
+
* Flattens nested arrays for {@link flat}. Non-array values are wrapped as a
|
|
118
|
+
* single-element iterable; depth decrements per array level.
|
|
119
|
+
*/
|
|
120
|
+
function flattenValue(value, depth) {
|
|
121
|
+
if (depth > 0 && Array.isArray(value)) {
|
|
122
|
+
const nextDepth = Number.isFinite(depth) ? depth - 1 : depth;
|
|
123
|
+
return {
|
|
124
|
+
*[Symbol.iterator]() {
|
|
125
|
+
for (const item of value)
|
|
126
|
+
yield* flattenValue(item, nextDepth);
|
|
127
|
+
},
|
|
128
|
+
};
|
|
129
|
+
}
|
|
130
|
+
return [value];
|
|
131
|
+
}
|
|
132
|
+
/** Wrap a per-element transform (each element -> an iterable) as a lazy {@link Sequence}. */
|
|
133
|
+
function derive(source, fn) {
|
|
134
|
+
return sequence({
|
|
135
|
+
*[Symbol.iterator]() {
|
|
136
|
+
let index = 0;
|
|
137
|
+
for (const value of source)
|
|
138
|
+
yield* fn(value, index++);
|
|
139
|
+
},
|
|
140
|
+
});
|
|
141
|
+
}
|
|
142
|
+
/** Like {@link derive}, but yields one value per source element (no wrapper iterable). */
|
|
143
|
+
function deriveOne(source, fn) {
|
|
144
|
+
return sequence({
|
|
145
|
+
*[Symbol.iterator]() {
|
|
146
|
+
let index = 0;
|
|
147
|
+
for (const value of source)
|
|
148
|
+
yield fn(value, index++);
|
|
149
|
+
},
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
/**
|
|
153
|
+
* Same semantics as `Array.prototype.map`, over a single {@link Container}.
|
|
154
|
+
*
|
|
155
|
+
* @param source - The container to map (nullish yields an empty sequence).
|
|
156
|
+
* @param callback - Called per element with its index; its result is emitted.
|
|
157
|
+
*/
|
|
158
|
+
export function map(source, callback) {
|
|
159
|
+
return deriveOne(sequence(source), callback);
|
|
160
|
+
}
|
|
161
|
+
export function filter(source, predicate) {
|
|
162
|
+
return derive(sequence(source), function* (value, index) {
|
|
163
|
+
if (predicate(value, index))
|
|
164
|
+
yield value;
|
|
165
|
+
});
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Concatenates the sources and yields only elements that are not `null` or
|
|
169
|
+
* `undefined`, narrowing the element type to {@link NonNullable}<`T`>.
|
|
170
|
+
*
|
|
171
|
+
* @param sources - Containers to concatenate (nullish sources are skipped).
|
|
172
|
+
*/
|
|
173
|
+
export function nonNull(...sources) {
|
|
174
|
+
return filter(sequence(...sources), (value) => value != null);
|
|
175
|
+
}
|
|
176
|
+
/**
|
|
177
|
+
* Same semantics as `Array.prototype.flatMap`, over a single {@link Container}.
|
|
178
|
+
*
|
|
179
|
+
* @param source - The container to map (nullish yields an empty sequence).
|
|
180
|
+
* @param callback - Returns a value or array of values, flattened one level.
|
|
181
|
+
*/
|
|
182
|
+
export function flatMap(source, callback) {
|
|
183
|
+
return derive(sequence(source), function* (value, index) {
|
|
184
|
+
const result = callback(value, index);
|
|
185
|
+
if (Array.isArray(result))
|
|
186
|
+
yield* result;
|
|
187
|
+
else
|
|
188
|
+
yield result;
|
|
189
|
+
});
|
|
190
|
+
}
|
|
191
|
+
/**
|
|
192
|
+
* Same semantics as `Array.prototype.flat` (arrays only). `depth` leads so the
|
|
193
|
+
* sources can stay variadic; use `depth < 1` for a no-op passthrough.
|
|
194
|
+
*
|
|
195
|
+
* @param depth - How many array levels to flatten.
|
|
196
|
+
* @param sources - Containers to concatenate, then flatten (nullish skipped).
|
|
197
|
+
*/
|
|
198
|
+
export function flat(depth, ...sources) {
|
|
199
|
+
const src = sequence(...sources);
|
|
200
|
+
if (depth < 1)
|
|
201
|
+
return src;
|
|
202
|
+
return derive(src, (value) => flattenValue(value, depth));
|
|
203
|
+
}
|
|
204
|
+
/**
|
|
205
|
+
* Concatenates the sources, then lazily yields values in encounter order,
|
|
206
|
+
* skipping a value only when an equal one was already yielded (`Set` /
|
|
207
|
+
* SameValueZero). Uniqueness is checked per element as it is consumed.
|
|
208
|
+
*
|
|
209
|
+
* @param sources - Containers to concatenate (nullish sources are skipped).
|
|
210
|
+
*/
|
|
211
|
+
export function distinct(...sources) {
|
|
212
|
+
const src = sequence(...sources);
|
|
213
|
+
return sequence({
|
|
214
|
+
*[Symbol.iterator]() {
|
|
215
|
+
const seen = new Set();
|
|
216
|
+
for (const value of src) {
|
|
217
|
+
if (seen.has(value))
|
|
218
|
+
continue;
|
|
219
|
+
seen.add(value);
|
|
220
|
+
yield value;
|
|
221
|
+
}
|
|
222
|
+
},
|
|
223
|
+
});
|
|
224
|
+
}
|
|
225
|
+
/**
|
|
226
|
+
* Yields `source`, then each appended `item` in order (arrays spread one level),
|
|
227
|
+
* mirroring `Array.prototype.concat`. `items` are scalar values/arrays, not
|
|
228
|
+
* containers, so `source` stays a single leading argument.
|
|
229
|
+
*
|
|
230
|
+
* @param source - The leading container (nullish yields just the items).
|
|
231
|
+
* @param items - Values (or arrays of values) appended after the source.
|
|
232
|
+
*/
|
|
233
|
+
export function concat(source, ...items) {
|
|
234
|
+
const src = sequence(source);
|
|
235
|
+
if (items.length === 0)
|
|
236
|
+
return src;
|
|
237
|
+
return sequence({
|
|
238
|
+
*[Symbol.iterator]() {
|
|
239
|
+
yield* src;
|
|
240
|
+
for (const item of items) {
|
|
241
|
+
if (Array.isArray(item))
|
|
242
|
+
yield* item;
|
|
243
|
+
else
|
|
244
|
+
yield item;
|
|
245
|
+
}
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
}
|
|
249
|
+
/**
|
|
250
|
+
* Yields at most `count` elements from the front of the concatenated sources.
|
|
251
|
+
* `count` leads so the sources can stay variadic.
|
|
252
|
+
*
|
|
253
|
+
* @param count - Maximum number of elements to yield (`<= 0` yields none).
|
|
254
|
+
* @param sources - Containers to concatenate (nullish sources are skipped).
|
|
255
|
+
*/
|
|
256
|
+
export function take(count, ...sources) {
|
|
257
|
+
if (count <= 0)
|
|
258
|
+
return emptySequence;
|
|
259
|
+
const src = sequence(...sources);
|
|
260
|
+
return sequence({
|
|
261
|
+
*[Symbol.iterator]() {
|
|
262
|
+
let taken = 0;
|
|
263
|
+
for (const value of src) {
|
|
264
|
+
yield value;
|
|
265
|
+
if (++taken >= count)
|
|
266
|
+
return;
|
|
267
|
+
}
|
|
268
|
+
},
|
|
269
|
+
});
|
|
270
|
+
}
|
|
271
|
+
/**
|
|
272
|
+
* Splits the concatenated sources into one array per named predicate. Consumes
|
|
273
|
+
* the input once, routing each element to the FIRST predicate it satisfies (so
|
|
274
|
+
* groups are disjoint); elements matching no predicate are dropped. Type-guard
|
|
275
|
+
* predicates narrow their group's element type (see {@link GroupValue}).
|
|
276
|
+
* `predicates` leads so the sources can stay variadic.
|
|
277
|
+
*
|
|
278
|
+
* @typeParam G - The map of group name -> predicate.
|
|
279
|
+
* @param predicates - Named predicates; evaluated in declaration order.
|
|
280
|
+
* @param sources - Containers to concatenate (nullish sources are skipped).
|
|
281
|
+
* @returns An object with the same keys, each an array of its group's elements.
|
|
282
|
+
*
|
|
283
|
+
* @example
|
|
284
|
+
* const { strings, fns } = group({ strings: isString, fns: isFunction }, xs);
|
|
285
|
+
*/
|
|
286
|
+
export function group(predicates, ...sources) {
|
|
287
|
+
const keys = Object.keys(predicates);
|
|
288
|
+
const buckets = new Map(keys.map((key) => [key, []]));
|
|
289
|
+
let index = 0;
|
|
290
|
+
for (const value of sequence(...sources)) {
|
|
291
|
+
const i = index++;
|
|
292
|
+
for (const key of keys) {
|
|
293
|
+
if (predicates[key](value, i)) {
|
|
294
|
+
buckets.get(key).push(value);
|
|
295
|
+
break;
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
}
|
|
299
|
+
const result = {};
|
|
300
|
+
for (const key of keys) {
|
|
301
|
+
result[key] = buckets.get(key);
|
|
302
|
+
}
|
|
303
|
+
return result;
|
|
304
|
+
}
|
|
305
|
+
export function find(source, predicate) {
|
|
306
|
+
let index = 0;
|
|
307
|
+
for (const value of sequence(source)) {
|
|
308
|
+
if (predicate(value, index++))
|
|
309
|
+
return value;
|
|
310
|
+
}
|
|
311
|
+
return undefined;
|
|
312
|
+
}
|
|
313
|
+
export function findLast(source, predicate) {
|
|
314
|
+
let index = 0;
|
|
315
|
+
let match;
|
|
316
|
+
for (const value of sequence(source)) {
|
|
317
|
+
if (predicate(value, index++))
|
|
318
|
+
match = value;
|
|
319
|
+
}
|
|
320
|
+
return match;
|
|
321
|
+
}
|
|
322
|
+
/**
|
|
323
|
+
* Same semantics as `Array.prototype.findIndex`, over a single {@link Container}.
|
|
324
|
+
* Consumes elements until a match.
|
|
325
|
+
*/
|
|
326
|
+
export function findIndex(source, predicate) {
|
|
327
|
+
let index = 0;
|
|
328
|
+
for (const value of sequence(source)) {
|
|
329
|
+
if (predicate(value, index))
|
|
330
|
+
return index;
|
|
331
|
+
index++;
|
|
332
|
+
}
|
|
333
|
+
return -1;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Same semantics as `Array.prototype.findLastIndex`, over a single
|
|
337
|
+
* {@link Container}. Consumes the full source.
|
|
338
|
+
*/
|
|
339
|
+
export function findLastIndex(source, predicate) {
|
|
340
|
+
let index = 0;
|
|
341
|
+
let match = -1;
|
|
342
|
+
for (const value of sequence(source)) {
|
|
343
|
+
if (predicate(value, index))
|
|
344
|
+
match = index;
|
|
345
|
+
index++;
|
|
346
|
+
}
|
|
347
|
+
return match;
|
|
348
|
+
}
|
|
349
|
+
/**
|
|
350
|
+
* Same semantics as `Array.prototype.some`, over a single {@link Container}.
|
|
351
|
+
* Short-circuits on the first match.
|
|
352
|
+
*/
|
|
353
|
+
export function some(source, predicate) {
|
|
354
|
+
let index = 0;
|
|
355
|
+
for (const value of sequence(source))
|
|
356
|
+
if (predicate(value, index++))
|
|
357
|
+
return true;
|
|
358
|
+
return false;
|
|
359
|
+
}
|
|
360
|
+
export function every(source, predicate) {
|
|
361
|
+
let index = 0;
|
|
362
|
+
for (const value of sequence(source))
|
|
363
|
+
if (!predicate(value, index++))
|
|
364
|
+
return false;
|
|
365
|
+
return true;
|
|
366
|
+
}
|
|
367
|
+
/**
|
|
368
|
+
* Same semantics as `Array.prototype.forEach`, over a single {@link Container}.
|
|
369
|
+
* Consumes the source.
|
|
370
|
+
*/
|
|
371
|
+
export function forEach(source, callback) {
|
|
372
|
+
let index = 0;
|
|
373
|
+
for (const value of sequence(source))
|
|
374
|
+
callback(value, index++);
|
|
375
|
+
}
|
|
376
|
+
/**
|
|
377
|
+
* Same semantics as `Array.prototype.at` over the concatenated sources.
|
|
378
|
+
* Non-negative indices scan lazily; negative indices materialize first. `index`
|
|
379
|
+
* leads so the sources can stay variadic.
|
|
380
|
+
*
|
|
381
|
+
* @param index - Zero-based position; negative counts from the end.
|
|
382
|
+
* @param sources - Containers to concatenate (nullish sources are skipped).
|
|
383
|
+
*/
|
|
384
|
+
export function at(index, ...sources) {
|
|
385
|
+
const src = sequence(...sources);
|
|
386
|
+
if (index < 0)
|
|
387
|
+
return toArray(src).at(index);
|
|
388
|
+
let i = 0;
|
|
389
|
+
for (const value of src) {
|
|
390
|
+
if (i++ === index)
|
|
391
|
+
return value;
|
|
392
|
+
}
|
|
393
|
+
return undefined;
|
|
394
|
+
}
|
|
395
|
+
export function toOneOrMany(input) {
|
|
396
|
+
return Array.isArray(input) ? input : [input];
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* Materializes the concatenated sources into a new array. Consumes single-pass
|
|
400
|
+
* sources.
|
|
401
|
+
*
|
|
402
|
+
* @param sources - Containers to concatenate (nullish sources are skipped).
|
|
403
|
+
*/
|
|
404
|
+
export function toArray(...sources) {
|
|
405
|
+
return [...sequence(...sources)];
|
|
406
|
+
}
|
|
407
|
+
/**
|
|
408
|
+
* Lazy iterable sequence with `Array`-compatible transforms and terminal
|
|
409
|
+
* methods. Single-pass by default; call {@link SequenceImpl.cache} to retain
|
|
410
|
+
* pulled values for re-iteration. Built for generators and other sources where
|
|
411
|
+
* a second pass is not guaranteed.
|
|
412
|
+
*
|
|
413
|
+
* The methods forward to the standalone functions of the same name - see each
|
|
414
|
+
* method's `@see` - so the free-function and chained styles share one impl.
|
|
415
|
+
*/
|
|
416
|
+
class SequenceImpl {
|
|
417
|
+
source;
|
|
418
|
+
buffer;
|
|
419
|
+
iterator;
|
|
420
|
+
exhausted;
|
|
421
|
+
constructor(source, buffer, state = {}) {
|
|
422
|
+
this.source = source;
|
|
423
|
+
this.buffer = buffer;
|
|
424
|
+
this.exhausted = state.exhausted ?? false;
|
|
425
|
+
}
|
|
426
|
+
get caching() {
|
|
427
|
+
return this.buffer !== undefined;
|
|
428
|
+
}
|
|
429
|
+
/** Advance the underlying source once, creating the iterator on first use. */
|
|
430
|
+
pull() {
|
|
431
|
+
this.iterator ??= this.source[Symbol.iterator]();
|
|
432
|
+
return this.iterator.next();
|
|
433
|
+
}
|
|
434
|
+
*[Symbol.iterator]() {
|
|
435
|
+
if (!this.caching) {
|
|
436
|
+
if (this.exhausted)
|
|
437
|
+
return;
|
|
438
|
+
for (let next = this.pull(); !next.done; next = this.pull()) {
|
|
439
|
+
yield next.value;
|
|
440
|
+
}
|
|
441
|
+
this.exhausted = true;
|
|
442
|
+
}
|
|
443
|
+
else {
|
|
444
|
+
// Cached: iterate like a list. Always replay the buffer from the start,
|
|
445
|
+
// extending it from the source on demand until exhausted. A broken loop
|
|
446
|
+
// leaves the buffer intact, so the next iteration starts over from the
|
|
447
|
+
// beginning.
|
|
448
|
+
const buffer = this.buffer;
|
|
449
|
+
let index = 0;
|
|
450
|
+
for (;;) {
|
|
451
|
+
if (index < buffer.length) {
|
|
452
|
+
yield buffer[index++];
|
|
453
|
+
continue;
|
|
454
|
+
}
|
|
455
|
+
if (this.exhausted)
|
|
456
|
+
return;
|
|
457
|
+
const next = this.pull();
|
|
458
|
+
if (next.done) {
|
|
459
|
+
this.exhausted = true;
|
|
460
|
+
return;
|
|
461
|
+
}
|
|
462
|
+
buffer.push(next.value);
|
|
463
|
+
yield next.value;
|
|
464
|
+
index++;
|
|
465
|
+
}
|
|
466
|
+
}
|
|
467
|
+
}
|
|
468
|
+
/** @see {@link map} */
|
|
469
|
+
map(callback) {
|
|
470
|
+
return map(this, callback);
|
|
471
|
+
}
|
|
472
|
+
filter(predicate) {
|
|
473
|
+
return filter(this, predicate);
|
|
474
|
+
}
|
|
475
|
+
/** @see {@link nonNull} */
|
|
476
|
+
nonNull() {
|
|
477
|
+
return nonNull(this);
|
|
478
|
+
}
|
|
479
|
+
/** @see {@link flatMap} */
|
|
480
|
+
flatMap(callback) {
|
|
481
|
+
return flatMap(this, callback);
|
|
482
|
+
}
|
|
483
|
+
/** @see {@link flat} */
|
|
484
|
+
flat(depth = 1) {
|
|
485
|
+
return flat(depth, this);
|
|
486
|
+
}
|
|
487
|
+
/** @see {@link distinct} */
|
|
488
|
+
distinct() {
|
|
489
|
+
return distinct(this);
|
|
490
|
+
}
|
|
491
|
+
/** @see {@link concat} */
|
|
492
|
+
concat(...items) {
|
|
493
|
+
return concat(this, ...items);
|
|
494
|
+
}
|
|
495
|
+
/**
|
|
496
|
+
* Lazily yields this sequence followed by each iterable `source` in order.
|
|
497
|
+
* Like {@link concat}, but for iterable sources (generators, other sequences,
|
|
498
|
+
* `Set`, `Map`, etc.) rather than scalar values or arrays. A {@link Map}
|
|
499
|
+
* source contributes its values.
|
|
500
|
+
*
|
|
501
|
+
* @see {@link sequence}
|
|
502
|
+
*/
|
|
503
|
+
join(...sources) {
|
|
504
|
+
const sourceIterables = sequenceSources(this, ...sources);
|
|
505
|
+
return sequenceSources.length === 0 ? this : sequence(...sourceIterables);
|
|
506
|
+
}
|
|
507
|
+
/** @see {@link take} */
|
|
508
|
+
take(count) {
|
|
509
|
+
return take(count, this);
|
|
510
|
+
}
|
|
511
|
+
/** @see {@link group} */
|
|
512
|
+
group(predicates) {
|
|
513
|
+
return group(predicates, this);
|
|
514
|
+
}
|
|
515
|
+
/**
|
|
516
|
+
* Returns a cached, re-iterable view of this sequence. An already-caching
|
|
517
|
+
* sequence returns itself; otherwise this one-pass sequence is wrapped in a
|
|
518
|
+
* new instance that retains pulled values. Iterate the returned instance, not
|
|
519
|
+
* the original, to avoid competing for the same single-pass source.
|
|
520
|
+
*/
|
|
521
|
+
cache() {
|
|
522
|
+
return this.caching ? this : new SequenceImpl(this, []);
|
|
523
|
+
}
|
|
524
|
+
find(predicate) {
|
|
525
|
+
return find(this, predicate);
|
|
526
|
+
}
|
|
527
|
+
findLast(predicate) {
|
|
528
|
+
return findLast(this, predicate);
|
|
529
|
+
}
|
|
530
|
+
/** @see {@link findIndex} */
|
|
531
|
+
findIndex(predicate) {
|
|
532
|
+
return findIndex(this, predicate);
|
|
533
|
+
}
|
|
534
|
+
/** @see {@link findLastIndex} */
|
|
535
|
+
findLastIndex(predicate) {
|
|
536
|
+
return findLastIndex(this, predicate);
|
|
537
|
+
}
|
|
538
|
+
/** @see {@link some} */
|
|
539
|
+
some(predicate) {
|
|
540
|
+
return some(this, predicate);
|
|
541
|
+
}
|
|
542
|
+
every(predicate) {
|
|
543
|
+
return every(this, predicate);
|
|
544
|
+
}
|
|
545
|
+
/** @see {@link forEach} */
|
|
546
|
+
forEach(callback) {
|
|
547
|
+
forEach(this, callback);
|
|
548
|
+
}
|
|
549
|
+
/** @see {@link at} */
|
|
550
|
+
at(index) {
|
|
551
|
+
return at(index, this);
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Materialize the sequence into a new array. Consumes a single-pass source; a
|
|
555
|
+
* cached, exhausted sequence copies its buffer directly.
|
|
556
|
+
*
|
|
557
|
+
* @see {@link toArray}
|
|
558
|
+
*/
|
|
559
|
+
toArray() {
|
|
560
|
+
if (this.caching && this.exhausted)
|
|
561
|
+
return [...this.buffer];
|
|
562
|
+
return toArray(this);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
/** Shared empty sequence singleton, reusable for any element type. */
|
|
566
|
+
const emptySequence = new SequenceImpl([], undefined, {
|
|
567
|
+
exhausted: true,
|
|
568
|
+
});
|
|
569
|
+
/**
|
|
570
|
+
* Wrap one or more iterable `sources` in a single lazy {@link Sequence},
|
|
571
|
+
* iterated in order. `null`/`undefined` sources are skipped; when nothing
|
|
572
|
+
* remains (every source omitted, `null`, `undefined`, or an empty array /
|
|
573
|
+
* `Set` / `Map`), {@link emptySequence} is returned. The result is single-pass
|
|
574
|
+
* - call `.cache()` to make it re-iterable.
|
|
575
|
+
*
|
|
576
|
+
* A {@link Map} source contributes its values (see {@link values}), consistent
|
|
577
|
+
* with {@link Collection}'s value-typed `T`.
|
|
578
|
+
*
|
|
579
|
+
* @typeParam T - Element type of the sequence.
|
|
580
|
+
* @param sources - Iterables to concatenate, in order (`Map` sources use values).
|
|
581
|
+
*/
|
|
582
|
+
export function sequence(...sources) {
|
|
583
|
+
// Skip nullish sources and known-empty collections; normalize the rest to
|
|
584
|
+
// their values so a Map contributes values rather than [key, value] entries.
|
|
585
|
+
const sourceIterables = sequenceSources(...sources);
|
|
586
|
+
if (sourceIterables.length === 0)
|
|
587
|
+
return emptySequence;
|
|
588
|
+
// Reuse an existing sequence as-is rather than re-wrapping it.
|
|
589
|
+
if (sourceIterables.length === 1) {
|
|
590
|
+
const only = sourceIterables[0];
|
|
591
|
+
return only instanceof SequenceImpl ? only : new SequenceImpl(only, undefined);
|
|
592
|
+
}
|
|
593
|
+
return new SequenceImpl({
|
|
594
|
+
*[Symbol.iterator]() {
|
|
595
|
+
for (const source of sourceIterables)
|
|
596
|
+
yield* source;
|
|
597
|
+
},
|
|
598
|
+
}, undefined);
|
|
599
|
+
}
|
|
600
|
+
/**
|
|
601
|
+
* Flattens a mix of single items and iterables into one lazy {@link Generator}.
|
|
602
|
+
*
|
|
603
|
+
* Arguments are emitted in order: `null`/`undefined` are skipped, non-string
|
|
604
|
+
* iterables (per {@link isContainer}) are yielded element-by-element, and
|
|
605
|
+
* anything else (including strings) is yielded as a single item.
|
|
606
|
+
*
|
|
607
|
+
* @typeParam T - Element type produced by the generator.
|
|
608
|
+
* @param items - Items and/or iterables to flatten, in order.
|
|
609
|
+
* @returns A generator over the flattened elements.
|
|
610
|
+
*/
|
|
611
|
+
export function* generator(...items) {
|
|
612
|
+
for (const item of items) {
|
|
613
|
+
if (item === null || item === undefined) {
|
|
614
|
+
continue;
|
|
615
|
+
}
|
|
616
|
+
else if (isContainer(item)) {
|
|
617
|
+
yield* item;
|
|
618
|
+
}
|
|
619
|
+
else {
|
|
620
|
+
yield item;
|
|
621
|
+
}
|
|
622
|
+
}
|
|
623
|
+
}
|
|
624
|
+
/**
|
|
625
|
+
* Narrow `value` to a plain (non-array) object. Use as a type guard
|
|
626
|
+
* before indexing into / mutating parsed JSON so the access is
|
|
627
|
+
* type-safe.
|
|
628
|
+
*
|
|
629
|
+
* @example
|
|
630
|
+
* if (isRecord(parsed)) parsed.foo = 1;
|
|
631
|
+
*/
|
|
632
|
+
export function isRecord(value) {
|
|
633
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
634
|
+
}
|
|
635
|
+
/**
|
|
636
|
+
* Coerce a loose boolean-ish value to a real `boolean`, or `undefined`
|
|
637
|
+
* when it can't be interpreted. Recognizes `true`/`t`/`on`/`1`/`yes`/`y`
|
|
638
|
+
* and their negatives (case- and whitespace-insensitive for strings), as
|
|
639
|
+
* well as the numbers `1` and `0`.
|
|
640
|
+
*/
|
|
641
|
+
export function toBoolean(value) {
|
|
642
|
+
if (typeof value === "boolean") {
|
|
643
|
+
return value;
|
|
644
|
+
}
|
|
645
|
+
else if (typeof value === "string") {
|
|
646
|
+
value = value.trim().toLowerCase();
|
|
647
|
+
if (value === "true" ||
|
|
648
|
+
value == "t" ||
|
|
649
|
+
value === "on" ||
|
|
650
|
+
value === "1" ||
|
|
651
|
+
value === "yes" ||
|
|
652
|
+
value === "y") {
|
|
653
|
+
return true;
|
|
654
|
+
}
|
|
655
|
+
else if (value === "false" ||
|
|
656
|
+
value == "f" ||
|
|
657
|
+
value === "off" ||
|
|
658
|
+
value === "0" ||
|
|
659
|
+
value === "no" ||
|
|
660
|
+
value === "n") {
|
|
661
|
+
return false;
|
|
662
|
+
}
|
|
663
|
+
}
|
|
664
|
+
else if (typeof value === "number") {
|
|
665
|
+
if (value === 1)
|
|
666
|
+
return true;
|
|
667
|
+
else if (value === 0)
|
|
668
|
+
return false;
|
|
669
|
+
}
|
|
670
|
+
return undefined;
|
|
671
|
+
}
|
|
672
|
+
export function deepEqual(a, b, comparator) {
|
|
673
|
+
if (comparator) {
|
|
674
|
+
const decided = comparator(a, b);
|
|
675
|
+
if (decided !== undefined)
|
|
676
|
+
return decided;
|
|
677
|
+
}
|
|
678
|
+
if (a === b)
|
|
679
|
+
return true;
|
|
680
|
+
if (typeof a !== "object" || a === null || typeof b !== "object" || b === null) {
|
|
681
|
+
// NaN is the only value not equal to itself under `===`.
|
|
682
|
+
return a !== a && b !== b;
|
|
683
|
+
}
|
|
684
|
+
if (a.constructor !== b.constructor)
|
|
685
|
+
return false;
|
|
686
|
+
if (Array.isArray(a)) {
|
|
687
|
+
const bArr = b;
|
|
688
|
+
if (a.length !== bArr.length)
|
|
689
|
+
return false;
|
|
690
|
+
for (let i = 0; i < a.length; i++) {
|
|
691
|
+
if (!deepEqual(a[i], bArr[i], comparator))
|
|
692
|
+
return false;
|
|
693
|
+
}
|
|
694
|
+
return true;
|
|
695
|
+
}
|
|
696
|
+
if (a instanceof Map) {
|
|
697
|
+
const bMap = b;
|
|
698
|
+
if (a.size !== bMap.size)
|
|
699
|
+
return false;
|
|
700
|
+
for (const [key, value] of a) {
|
|
701
|
+
if (!bMap.has(key))
|
|
702
|
+
return false;
|
|
703
|
+
if (!deepEqual(value, bMap.get(key), comparator))
|
|
704
|
+
return false;
|
|
705
|
+
}
|
|
706
|
+
return true;
|
|
707
|
+
}
|
|
708
|
+
if (a instanceof Set) {
|
|
709
|
+
const bSet = b;
|
|
710
|
+
if (a.size !== bSet.size)
|
|
711
|
+
return false;
|
|
712
|
+
for (const value of a) {
|
|
713
|
+
if (!bSet.has(value))
|
|
714
|
+
return false;
|
|
715
|
+
}
|
|
716
|
+
return true;
|
|
717
|
+
}
|
|
718
|
+
if (a instanceof Date) {
|
|
719
|
+
return a.getTime() === b.getTime();
|
|
720
|
+
}
|
|
721
|
+
if (a instanceof RegExp) {
|
|
722
|
+
const bRe = b;
|
|
723
|
+
return a.source === bRe.source && a.flags === bRe.flags;
|
|
724
|
+
}
|
|
725
|
+
if (ArrayBuffer.isView(a) && !(a instanceof DataView)) {
|
|
726
|
+
const aArr = a;
|
|
727
|
+
const bArr = b;
|
|
728
|
+
if (aArr.length !== bArr.length)
|
|
729
|
+
return false;
|
|
730
|
+
for (let i = 0; i < aArr.length; i++) {
|
|
731
|
+
if (aArr[i] !== bArr[i])
|
|
732
|
+
return false;
|
|
733
|
+
}
|
|
734
|
+
return true;
|
|
735
|
+
}
|
|
736
|
+
const aKeys = Object.keys(a);
|
|
737
|
+
const bKeys = Object.keys(b);
|
|
738
|
+
if (aKeys.length !== bKeys.length)
|
|
739
|
+
return false;
|
|
740
|
+
for (const key of aKeys) {
|
|
741
|
+
if (!Object.prototype.hasOwnProperty.call(b, key))
|
|
742
|
+
return false;
|
|
743
|
+
if (!deepEqual(a[key], b[key], comparator)) {
|
|
744
|
+
return false;
|
|
745
|
+
}
|
|
746
|
+
}
|
|
747
|
+
return true;
|
|
748
|
+
}
|
|
749
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoib2JqZWN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL29iamVjdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7Ozs7Ozs7Ozs7OztHQWdCRztBQTBCSCxzRUFBc0U7QUFDdEUsTUFBTSxVQUFVLFdBQVcsQ0FBYyxLQUFtQjtJQUMxRCxPQUFPLEtBQUssQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDO0FBQzFCLENBQUM7QUFjRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sVUFBVSxZQUFZLENBQWMsS0FBYztJQUN0RCxPQUFPLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxZQUFZLEdBQUcsSUFBSSxLQUFLLFlBQVksR0FBRyxDQUFDO0FBQzlFLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxPQUFPLENBQ3JCLFVBQXlELEVBQ3pELE9BQWlDO0lBRWpDLFNBQVMsS0FBSyxDQUFDLEtBQWMsRUFBRSxJQUFtQjtRQUNoRCxJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUNsQixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7YUFBTSxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQ3JDLElBQUksSUFBSSxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUM7Z0JBQUUsT0FBTyxJQUFJLENBQUM7WUFDbEMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUNqQixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDekIsT0FBTyxLQUFLLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN6RixDQUFDO1lBQ0QsSUFBSSxLQUFLLFlBQVksR0FBRyxFQUFFLENBQUM7Z0JBQ3pCLE9BQU8sS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLEtBQUssQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDNUYsQ0FBQztZQUNELElBQUksS0FBSyxZQUFZLEdBQUcsRUFBRSxDQUFDO2dCQUN6QixPQUFPLENBQ0wsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDO29CQUNoQixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FDeEUsQ0FBQztZQUNKLENBQUM7WUFDRCxNQUFNLElBQUksR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ2hDLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDdEIsT0FBTyxJQUFJLENBQUM7WUFDZCxDQUFDO2lCQUFNLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ2hCLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFFLEtBQWlDLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNuRixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sT0FBTyxLQUFLLENBQUM7WUFDZixDQUFDO1FBQ0gsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUMsVUFBVSxFQUFFLE9BQU8sRUFBRSxTQUFTLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDO0FBQ3ZFLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxNQUFNLFVBQVUsTUFBTSxDQUFJLE1BQTZDO0lBQ3JFLE9BQU8sTUFBTSxZQUFZLEdBQUcsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBRSxNQUFzQixDQUFDO0FBQzNFLENBQUM7QUFFRDs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxNQUFNLFVBQVUsV0FBVyxDQUFjLEtBQWM7SUFDckQsT0FBTyxDQUNMLEtBQUssSUFBSSxJQUFJO1FBQ2IsT0FBTyxLQUFLLEtBQUssUUFBUTtRQUN6QixDQUFDLENBQUMsS0FBSyxZQUFZLE1BQU0sQ0FBQztRQUMxQixDQUFDLENBQUMsS0FBSyxZQUFZLE1BQU0sQ0FBQztRQUMxQixPQUFPLEtBQUssS0FBSyxVQUFVO1FBQzNCLE9BQVEsS0FBeUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLEtBQUssVUFBVSxDQUNsRixDQUFDO0FBQ0osQ0FBQztBQUVELFNBQVMsZUFBZSxDQUFJLEdBQUcsT0FBNEI7SUFDekQsTUFBTSxlQUFlLEdBQWtCLEVBQUUsQ0FBQztJQUMxQyxLQUFLLE1BQU0sTUFBTSxJQUFJLE9BQU8sRUFBRSxDQUFDO1FBQzdCLElBQUksTUFBTSxJQUFJLElBQUksSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsSUFBSSxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7WUFBRSxTQUFTO1FBQzFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUNELE9BQU8sZUFBZSxDQUFDO0FBQ3pCLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxTQUFTLFlBQVksQ0FBQyxLQUFjLEVBQUUsS0FBYTtJQUNqRCxJQUFJLEtBQUssR0FBRyxDQUFDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDO1FBQ3RDLE1BQU0sU0FBUyxHQUFHLE1BQU0sQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztRQUM3RCxPQUFPO1lBQ0wsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7Z0JBQ2hCLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSztvQkFBRSxLQUFLLENBQUMsQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ2pFLENBQUM7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUNELE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztBQUNqQixDQUFDO0FBRUQsNkZBQTZGO0FBQzdGLFNBQVMsTUFBTSxDQUNiLE1BQW1CLEVBQ25CLEVBQTRDO0lBRTVDLE9BQU8sUUFBUSxDQUFDO1FBQ2QsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFDaEIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNO2dCQUFFLEtBQUssQ0FBQyxDQUFDLEVBQUUsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUMsQ0FBQztRQUN4RCxDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVELDBGQUEwRjtBQUMxRixTQUFTLFNBQVMsQ0FBTyxNQUFtQixFQUFFLEVBQWtDO0lBQzlFLE9BQU8sUUFBUSxDQUFDO1FBQ2QsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFDaEIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxNQUFNO2dCQUFFLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELENBQUM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsR0FBRyxDQUNqQixNQUFpQixFQUNqQixRQUF3QztJQUV4QyxPQUFPLFNBQVMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsUUFBUSxDQUFDLENBQUM7QUFDL0MsQ0FBQztBQWlCRCxNQUFNLFVBQVUsTUFBTSxDQUNwQixNQUFpQixFQUNqQixTQUErQztJQUUvQyxPQUFPLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsUUFBUSxDQUFDLEVBQUUsS0FBSyxFQUFFLEtBQUs7UUFDckQsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQztZQUFFLE1BQU0sS0FBSyxDQUFDO0lBQzNDLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLE9BQU8sQ0FBSSxHQUFHLE9BQTZCO0lBQ3pELE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxFQUFFLENBQUMsS0FBSyxFQUEyQixFQUFFLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQyxDQUFDO0FBQ3pGLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxPQUFPLENBQ3JCLE1BQWlCLEVBQ2pCLFFBQTJEO0lBRTNELE9BQU8sTUFBTSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxRQUFRLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSztRQUNyRCxNQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3RDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUM7WUFBRSxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUM7O1lBQ3BDLE1BQU0sTUFBVyxDQUFDO0lBQ3pCLENBQUMsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxJQUFJLENBQUksS0FBYSxFQUFFLEdBQUcsT0FBNkI7SUFDckUsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLEdBQUcsT0FBTyxDQUFDLENBQUM7SUFDakMsSUFBSSxLQUFLLEdBQUcsQ0FBQztRQUFFLE9BQU8sR0FBRyxDQUFDO0lBQzFCLE9BQU8sTUFBTSxDQUFDLEdBQUcsRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsQ0FBZ0IsQ0FBQztBQUMzRSxDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsTUFBTSxVQUFVLFFBQVEsQ0FBSSxHQUFHLE9BQTZCO0lBQzFELE1BQU0sR0FBRyxHQUFHLFFBQVEsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDO0lBQ2pDLE9BQU8sUUFBUSxDQUFDO1FBQ2QsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUM7WUFDaEIsTUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQUssQ0FBQztZQUMxQixLQUFLLE1BQU0sS0FBSyxJQUFJLEdBQUcsRUFBRSxDQUFDO2dCQUN4QixJQUFJLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO29CQUFFLFNBQVM7Z0JBQzlCLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ2hCLE1BQU0sS0FBSyxDQUFDO1lBQ2QsQ0FBQztRQUNILENBQUM7S0FDRixDQUFDLENBQUM7QUFDTCxDQUFDO0FBRUQ7Ozs7Ozs7R0FPRztBQUNILE1BQU0sVUFBVSxNQUFNLENBQ3BCLE1BQWlCLEVBQ2pCLEdBQUcsS0FBd0M7SUFFM0MsTUFBTSxHQUFHLEdBQUcsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0lBQzdCLElBQUksS0FBSyxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxHQUFHLENBQUM7SUFDbkMsT0FBTyxRQUFRLENBQUM7UUFDZCxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztZQUNoQixLQUFLLENBQUMsQ0FBQyxHQUFHLENBQUM7WUFDWCxLQUFLLE1BQU0sSUFBSSxJQUFJLEtBQUssRUFBRSxDQUFDO2dCQUN6QixJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDO29CQUFFLEtBQUssQ0FBQyxDQUFDLElBQUksQ0FBQzs7b0JBQ2hDLE1BQU0sSUFBUyxDQUFDO1lBQ3ZCLENBQUM7UUFDSCxDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILE1BQU0sVUFBVSxJQUFJLENBQUksS0FBYSxFQUFFLEdBQUcsT0FBNkI7SUFDckUsSUFBSSxLQUFLLElBQUksQ0FBQztRQUFFLE9BQU8sYUFBNEIsQ0FBQztJQUNwRCxNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztJQUNqQyxPQUFPLFFBQVEsQ0FBQztRQUNkLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO1lBQ2hCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztZQUNkLEtBQUssTUFBTSxLQUFLLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ3hCLE1BQU0sS0FBSyxDQUFDO2dCQUNaLElBQUksRUFBRSxLQUFLLElBQUksS0FBSztvQkFBRSxPQUFPO1lBQy9CLENBQUM7UUFDSCxDQUFDO0tBQ0YsQ0FBQyxDQUFDO0FBQ0wsQ0FBQztBQUVEOzs7Ozs7Ozs7Ozs7OztHQWNHO0FBQ0gsTUFBTSxVQUFVLEtBQUssQ0FDbkIsVUFBYSxFQUNiLEdBQUcsT0FBNkI7SUFFaEMsTUFBTSxJQUFJLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQWdCLENBQUM7SUFDcEQsTUFBTSxPQUFPLEdBQUcsSUFBSSxHQUFHLENBQWUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BFLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQztJQUNkLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxDQUFDLEdBQUcsT0FBTyxDQUFDLEVBQUUsQ0FBQztRQUN6QyxNQUFNLENBQUMsR0FBRyxLQUFLLEVBQUUsQ0FBQztRQUNsQixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ3ZCLElBQUksVUFBVSxDQUFDLEdBQUcsQ0FBRSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDO2dCQUMvQixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDOUIsTUFBTTtZQUNSLENBQUM7UUFDSCxDQUFDO0lBQ0gsQ0FBQztJQUNELE1BQU0sTUFBTSxHQUFHLEVBQStDLENBQUM7SUFDL0QsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztRQUN2QixNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQW9DLENBQUM7SUFDcEUsQ0FBQztJQUNELE9BQU8sTUFBTSxDQUFDO0FBQ2hCLENBQUM7QUFjRCxNQUFNLFVBQVUsSUFBSSxDQUNsQixNQUFpQixFQUNqQixTQUErQztJQUUvQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDZCxLQUFLLE1BQU0sS0FBSyxJQUFJLFFBQVEsQ0FBQyxNQUFNLENBQUMsRUFBRSxDQUFDO1FBQ3JDLElBQUksU0FBUyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO0lBQzlDLENBQUM7SUFDRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBY0QsTUFBTSxVQUFVLFFBQVEsQ0FDdEIsTUFBaUIsRUFDakIsU0FBK0M7SUFFL0MsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsSUFBSSxLQUFvQixDQUFDO0lBQ3pCLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDckMsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQUUsS0FBSyxHQUFHLEtBQUssQ0FBQztJQUMvQyxDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FDdkIsTUFBaUIsRUFDakIsU0FBK0M7SUFFL0MsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUNyQyxJQUFJLFNBQVMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDO1lBQUUsT0FBTyxLQUFLLENBQUM7UUFDMUMsS0FBSyxFQUFFLENBQUM7SUFDVixDQUFDO0lBQ0QsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUNaLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsYUFBYSxDQUMzQixNQUFpQixFQUNqQixTQUErQztJQUUvQyxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7SUFDZCxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQztJQUNmLEtBQUssTUFBTSxLQUFLLElBQUksUUFBUSxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7UUFDckMsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQztZQUFFLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDM0MsS0FBSyxFQUFFLENBQUM7SUFDVixDQUFDO0lBQ0QsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBTSxVQUFVLElBQUksQ0FDbEIsTUFBaUIsRUFDakIsU0FBK0M7SUFFL0MsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQUUsSUFBSSxTQUFTLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxDQUFDO1lBQUUsT0FBTyxJQUFJLENBQUM7SUFDakYsT0FBTyxLQUFLLENBQUM7QUFDZixDQUFDO0FBY0QsTUFBTSxVQUFVLEtBQUssQ0FDbkIsTUFBaUIsRUFDakIsU0FBK0M7SUFFL0MsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztJQUNuRixPQUFPLElBQUksQ0FBQztBQUNkLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsT0FBTyxDQUFJLE1BQWlCLEVBQUUsUUFBMkM7SUFDdkYsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2QsS0FBSyxNQUFNLEtBQUssSUFBSSxRQUFRLENBQUMsTUFBTSxDQUFDO1FBQUUsUUFBUSxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO0FBQ2pFLENBQUM7QUFFRDs7Ozs7OztHQU9HO0FBQ0gsTUFBTSxVQUFVLEVBQUUsQ0FBSSxLQUFhLEVBQUUsR0FBRyxPQUE2QjtJQUNuRSxNQUFNLEdBQUcsR0FBRyxRQUFRLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQztJQUNqQyxJQUFJLEtBQUssR0FBRyxDQUFDO1FBQUUsT0FBTyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzdDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNWLEtBQUssTUFBTSxLQUFLLElBQUksR0FBRyxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLEVBQUUsS0FBSyxLQUFLO1lBQUUsT0FBTyxLQUFLLENBQUM7SUFDbEMsQ0FBQztJQUNELE9BQU8sU0FBUyxDQUFDO0FBQ25CLENBQUM7QUFFRCxNQUFNLFVBQVUsV0FBVyxDQUFJLEtBQXVCO0lBQ3BELE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDO0FBQ2hELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxPQUFPLENBQUksR0FBRyxPQUE2QjtJQUN6RCxPQUFPLENBQUMsR0FBRyxRQUFRLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDO0FBQ25DLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sWUFBWTtJQUtHO0lBQ0E7SUFMWCxRQUFRLENBQWU7SUFDdkIsU0FBUyxDQUFVO0lBRTNCLFlBQ21CLE1BQW1CLEVBQ25CLE1BQXVCLEVBQ3hDLFFBQTBDLEVBQUU7UUFGM0IsV0FBTSxHQUFOLE1BQU0sQ0FBYTtRQUNuQixXQUFNLEdBQU4sTUFBTSxDQUFpQjtRQUd4QyxJQUFJLENBQUMsU0FBUyxHQUFHLEtBQUssQ0FBQyxTQUFTLElBQUksS0FBSyxDQUFDO0lBQzVDLENBQUM7SUFFRCxJQUFZLE9BQU87UUFDakIsT0FBTyxJQUFJLENBQUMsTUFBTSxLQUFLLFNBQVMsQ0FBQztJQUNuQyxDQUFDO0lBRUQsOEVBQThFO0lBQ3RFLElBQUk7UUFDVixJQUFJLENBQUMsUUFBUSxLQUFLLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDakQsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzlCLENBQUM7SUFFRCxDQUFDLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQztRQUNoQixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2xCLElBQUksSUFBSSxDQUFDLFNBQVM7Z0JBQUUsT0FBTztZQUMzQixLQUFLLElBQUksSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUM1RCxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDbkIsQ0FBQztZQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ3hCLENBQUM7YUFBTSxDQUFDO1lBQ04sd0VBQXdFO1lBQ3hFLHdFQUF3RTtZQUN4RSx1RUFBdUU7WUFDdkUsYUFBYTtZQUNiLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFPLENBQUM7WUFDNUIsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ2QsU0FBUyxDQUFDO2dCQUNSLElBQUksS0FBSyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEVBQUUsQ0FBQztvQkFDMUIsTUFBTSxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUUsQ0FBQztvQkFDdkIsU0FBUztnQkFDWCxDQUFDO2dCQUNELElBQUksSUFBSSxDQUFDLFNBQVM7b0JBQUUsT0FBTztnQkFDM0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO2dCQUN6QixJQUFJLElBQUksQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDZCxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztvQkFDdEIsT0FBTztnQkFDVCxDQUFDO2dCQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2dCQUN4QixNQUFNLElBQUksQ0FBQyxLQUFLLENBQUM7Z0JBQ2pCLEtBQUssRUFBRSxDQUFDO1lBQ1YsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsdUJBQXVCO0lBQ3ZCLEdBQUcsQ0FBSSxRQUF3QztRQUM3QyxPQUFPLEdBQUcsQ0FBQyxJQUFJLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDN0IsQ0FBQztJQUtELE1BQU0sQ0FBQyxTQUErQztRQUNwRCxPQUFPLE1BQU0sQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVELDJCQUEyQjtJQUMzQixPQUFPO1FBQ0wsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUVELDJCQUEyQjtJQUMzQixPQUFPLENBQUksUUFBMkQ7UUFDcEUsT0FBTyxPQUFPLENBQUMsSUFBSSxFQUFFLFFBQVEsQ0FBQyxDQUFDO0lBQ2pDLENBQUM7SUFFRCx3QkFBd0I7SUFDeEIsSUFBSSxDQUFDLEtBQUssR0FBRyxDQUFDO1FBQ1osT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzNCLENBQUM7SUFFRCw0QkFBNEI7SUFDNUIsUUFBUTtRQUNOLE9BQU8sUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO0lBQ3hCLENBQUM7SUFFRCwwQkFBMEI7SUFDMUIsTUFBTSxDQUFDLEdBQUcsS0FBd0M7UUFDaEQsT0FBTyxNQUFNLENBQUMsSUFBSSxFQUFFLEdBQUcsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxJQUFJLENBQUMsR0FBRyxPQUFxQztRQUMzQyxNQUFNLGVBQWUsR0FBRyxlQUFlLENBQUMsSUFBSSxFQUFFLEdBQUcsT0FBTyxDQUFDLENBQUM7UUFDMUQsT0FBTyxlQUFlLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsR0FBRyxlQUFlLENBQUMsQ0FBQztJQUM1RSxDQUFDO0lBRUQsd0JBQXdCO0lBQ3hCLElBQUksQ0FBQyxLQUFhO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztJQUMzQixDQUFDO0lBRUQseUJBQXlCO0lBQ3pCLEtBQUssQ0FBK0IsVUFBYTtRQUMvQyxPQUFPLEtBQUssQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDakMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSztRQUNILE9BQU8sSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLFlBQVksQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUQsQ0FBQztJQUtELElBQUksQ0FBQyxTQUErQztRQUNsRCxPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUtELFFBQVEsQ0FBQyxTQUErQztRQUN0RCxPQUFPLFFBQVEsQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDbkMsQ0FBQztJQUVELDZCQUE2QjtJQUM3QixTQUFTLENBQUMsU0FBK0M7UUFDdkQsT0FBTyxTQUFTLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFFRCxpQ0FBaUM7SUFDakMsYUFBYSxDQUFDLFNBQStDO1FBQzNELE9BQU8sYUFBYSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztJQUN4QyxDQUFDO0lBRUQsd0JBQXdCO0lBQ3hCLElBQUksQ0FBQyxTQUErQztRQUNsRCxPQUFPLElBQUksQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUtELEtBQUssQ0FBQyxTQUErQztRQUNuRCxPQUFPLEtBQUssQ0FBQyxJQUFJLEVBQUUsU0FBUyxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVELDJCQUEyQjtJQUMzQixPQUFPLENBQUMsUUFBMkM7UUFDakQsT0FBTyxDQUFDLElBQUksRUFBRSxRQUFRLENBQUMsQ0FBQztJQUMxQixDQUFDO0lBRUQsc0JBQXNCO0lBQ3RCLEVBQUUsQ0FBQyxLQUFhO1FBQ2QsT0FBTyxFQUFFLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE9BQU87UUFDTCxJQUFJLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTyxDQUFDLENBQUM7UUFDN0QsT0FBTyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkIsQ0FBQztDQUNGO0FBRUQsc0VBQXNFO0FBQ3RFLE1BQU0sYUFBYSxHQUFvQixJQUFJLFlBQVksQ0FBQyxFQUFFLEVBQUUsU0FBUyxFQUFFO0lBQ3JFLFNBQVMsRUFBRSxJQUFJO0NBQ2hCLENBQUMsQ0FBQztBQUVIOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE1BQU0sVUFBVSxRQUFRLENBQUksR0FBRyxPQUFxQztJQUNsRSwwRUFBMEU7SUFDMUUsNkVBQTZFO0lBQzdFLE1BQU0sZUFBZSxHQUFHLGVBQWUsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxDQUFDO0lBQ3BELElBQUksZUFBZSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTyxhQUE0QixDQUFDO0lBQ3RFLCtEQUErRDtJQUMvRCxJQUFJLGVBQWUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7UUFDakMsTUFBTSxJQUFJLEdBQUcsZUFBZSxDQUFDLENBQUMsQ0FBRSxDQUFDO1FBQ2pDLE9BQU8sSUFBSSxZQUFZLFlBQVksQ0FBQyxDQUFDLENBQUUsSUFBb0IsQ0FBQyxDQUFDLENBQUMsSUFBSSxZQUFZLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ2xHLENBQUM7SUFDRCxPQUFPLElBQUksWUFBWSxDQUNyQjtRQUNFLENBQUMsQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDO1lBQ2hCLEtBQUssTUFBTSxNQUFNLElBQUksZUFBZTtnQkFBRSxLQUFLLENBQUMsQ0FBQyxNQUFNLENBQUM7UUFDdEQsQ0FBQztLQUNGLEVBQ0QsU0FBUyxDQUNWLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7R0FVRztBQUNILE1BQU0sU0FBUyxDQUFDLENBQUMsU0FBUyxDQUN4QixHQUFHLEtBQXNEO0lBRXpELEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDekIsSUFBSSxJQUFJLEtBQUssSUFBSSxJQUFJLElBQUksS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUN4QyxTQUFTO1FBQ1gsQ0FBQzthQUFNLElBQUksV0FBVyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDN0IsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDO1FBQ2QsQ0FBQzthQUFNLENBQUM7WUFDTixNQUFNLElBQUksQ0FBQztRQUNiLENBQUM7SUFDSCxDQUFDO0FBQ0gsQ0FBQztBQWVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsUUFBUSxDQUFDLEtBQWM7SUFDckMsT0FBTyxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksS0FBSyxLQUFLLElBQUksSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7QUFDOUUsQ0FBQztBQUVEOzs7OztHQUtHO0FBQ0gsTUFBTSxVQUFVLFNBQVMsQ0FBQyxLQUFjO0lBQ3RDLElBQUksT0FBTyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDL0IsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO1NBQU0sSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUNyQyxLQUFLLEdBQUcsS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBQ25DLElBQ0UsS0FBSyxLQUFLLE1BQU07WUFDaEIsS0FBSyxJQUFJLEdBQUc7WUFDWixLQUFLLEtBQUssSUFBSTtZQUNkLEtBQUssS0FBSyxHQUFHO1lBQ2IsS0FBSyxLQUFLLEtBQUs7WUFDZixLQUFLLEtBQUssR0FBRyxFQUNiLENBQUM7WUFDRCxPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7YUFBTSxJQUNMLEtBQUssS0FBSyxPQUFPO1lBQ2pCLEtBQUssSUFBSSxHQUFHO1lBQ1osS0FBSyxLQUFLLEtBQUs7WUFDZixLQUFLLEtBQUssR0FBRztZQUNiLEtBQUssS0FBSyxJQUFJO1lBQ2QsS0FBSyxLQUFLLEdBQUcsRUFDYixDQUFDO1lBQ0QsT0FBTyxLQUFLLENBQUM7UUFDZixDQUFDO0lBQ0gsQ0FBQztTQUFNLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxFQUFFLENBQUM7UUFDckMsSUFBSSxLQUFLLEtBQUssQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO2FBQ3hCLElBQUksS0FBSyxLQUFLLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztJQUNyQyxDQUFDO0lBQ0QsT0FBTyxTQUFTLENBQUM7QUFDbkIsQ0FBQztBQXlCRCxNQUFNLFVBQVUsU0FBUyxDQUFDLENBQVUsRUFBRSxDQUFVLEVBQUUsVUFBZ0M7SUFDaEYsSUFBSSxVQUFVLEVBQUUsQ0FBQztRQUNmLE1BQU0sT0FBTyxHQUFHLFVBQVUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDakMsSUFBSSxPQUFPLEtBQUssU0FBUztZQUFFLE9BQU8sT0FBTyxDQUFDO0lBQzVDLENBQUM7SUFFRCxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFekIsSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsS0FBSyxRQUFRLElBQUksQ0FBQyxLQUFLLElBQUksRUFBRSxDQUFDO1FBQy9FLHlEQUF5RDtRQUN6RCxPQUFPLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQsSUFBSSxDQUFDLENBQUMsV0FBVyxLQUFLLENBQUMsQ0FBQyxXQUFXO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFFbEQsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDckIsTUFBTSxJQUFJLEdBQUcsQ0FBYyxDQUFDO1FBQzVCLElBQUksQ0FBQyxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQzNDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDbEMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLFVBQVUsQ0FBQztnQkFBRSxPQUFPLEtBQUssQ0FBQztRQUMxRCxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsSUFBSSxDQUFDLFlBQVksR0FBRyxFQUFFLENBQUM7UUFDckIsTUFBTSxJQUFJLEdBQUcsQ0FBMEIsQ0FBQztRQUN4QyxJQUFJLENBQUMsQ0FBQyxJQUFJLEtBQUssSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUN2QyxLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsVUFBVSxDQUFDO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ2pFLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxJQUFJLENBQUMsWUFBWSxHQUFHLEVBQUUsQ0FBQztRQUNyQixNQUFNLElBQUksR0FBRyxDQUFpQixDQUFDO1FBQy9CLElBQUksQ0FBQyxDQUFDLElBQUksS0FBSyxJQUFJLENBQUMsSUFBSTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3ZDLEtBQUssTUFBTSxLQUFLLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDO2dCQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3JDLENBQUM7UUFDRCxPQUFPLElBQUksQ0FBQztJQUNkLENBQUM7SUFFRCxJQUFJLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQztRQUN0QixPQUFPLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBTSxDQUFVLENBQUMsT0FBTyxFQUFFLENBQUM7SUFDL0MsQ0FBQztJQUVELElBQUksQ0FBQyxZQUFZLE1BQU0sRUFBRSxDQUFDO1FBQ3hCLE1BQU0sR0FBRyxHQUFHLENBQVcsQ0FBQztRQUN4QixPQUFPLENBQUMsQ0FBQyxNQUFNLEtBQUssR0FBRyxDQUFDLE1BQU0sSUFBSSxDQUFDLENBQUMsS0FBSyxLQUFLLEdBQUcsQ0FBQyxLQUFLLENBQUM7SUFDMUQsQ0FBQztJQUVELElBQUksV0FBVyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxZQUFZLFFBQVEsQ0FBQyxFQUFFLENBQUM7UUFDdEQsTUFBTSxJQUFJLEdBQUcsQ0FBaUMsQ0FBQztRQUMvQyxNQUFNLElBQUksR0FBRyxDQUFpQyxDQUFDO1FBQy9DLElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxJQUFJLENBQUMsTUFBTTtZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQzlDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDckMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFBRSxPQUFPLEtBQUssQ0FBQztRQUN4QyxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0lBRUQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUE0QixDQUFDLENBQUM7SUFDeEQsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUE0QixDQUFDLENBQUM7SUFDeEQsSUFBSSxLQUFLLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxNQUFNO1FBQUUsT0FBTyxLQUFLLENBQUM7SUFDaEQsS0FBSyxNQUFNLEdBQUcsSUFBSSxLQUFLLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUM7WUFBRSxPQUFPLEtBQUssQ0FBQztRQUNoRSxJQUNFLENBQUMsU0FBUyxDQUNQLENBQTZCLENBQUMsR0FBRyxDQUFDLEVBQ2xDLENBQTZCLENBQUMsR0FBRyxDQUFDLEVBQ25DLFVBQVUsQ0FDWCxFQUNELENBQUM7WUFDRCxPQUFPLEtBQUssQ0FBQztRQUNmLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEZXBlbmRlbmN5LWZyZWUgb2JqZWN0ICsgaXRlcmFibGUgdXRpbGl0aWVzLlxuICpcbiAqIFZhbHVlIGd1YXJkcyAvIGNvZXJjaW9ucyAvIHNoYXBlIHR5cGVzOiB7QGxpbmsgaXNSZWNvcmR9IG5hcnJvd3MgcGFyc2VkIEpTT05cbiAqIHRvIGEgcmVjb3JkLCB7QGxpbmsgdG9Cb29sZWFufSBjb2VyY2VzIGxvb3NlIHRydXRoeS9mYWxzeSB2YWx1ZXMsIHtAbGlua1xuICogZGVlcEVxdWFsfSBjb21wYXJlcyBzdHJ1Y3R1cmFsbHksIGFuZCB7QGxpbmsgTmFtZUxpa2V9L3tAbGluayBOb25GdW5jdGlvbktleXN9XG4gKiBkZXNjcmliZSBvYmplY3Qgc2hhcGVzLlxuICpcbiAqIEl0ZXJhYmxlIGhlbHBlcnM6IHtAbGluayBnZW5lcmF0b3J9IGZsYXR0ZW5zIG1peGVkIGFyZ3VtZW50czsge0BsaW5rIHNlcXVlbmNlfVxuICogd3JhcHMgc291cmNlKHMpIGluIGEgbGF6eSwgYEFycmF5YC1jb21wYXRpYmxlIHtAbGluayBTZXF1ZW5jZX0uIEV2ZXJ5XG4gKiB0cmFuc2Zvcm0vdGVybWluYWwgaXMgYSBzdGFuZGFsb25lIGZ1bmN0aW9uIG9wZXJhdGluZyBvbiBwbGFpbiB7QGxpbmtcbiAqIENvbnRhaW5lcn1zIChzZWUge0BsaW5rIG1hcH0sIHtAbGluayBmaWx0ZXJ9LCB7QGxpbmsgZ3JvdXB9LCAuLi4pOyB0aGUge0BsaW5rXG4gKiBTZXF1ZW5jZX0gbWV0aG9kcyBhcmUgdGhpbiBmb3J3YXJkZXJzIG92ZXIgdGhlbSBzbyB0aGUgc2FtZSBsb2dpYyBiYWNrcyBib3RoXG4gKiB0aGUgZnJlZS1mdW5jdGlvbiBhbmQgdGhlIGZsdWVudC9jaGFpbmVkIHN0eWxlcy5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuLyoqIExhenkgc2VxdWVuY2Ugb3ZlciBpdGVyYWJsZSBzb3VyY2UocykuIFNlZSB7QGxpbmsgc2VxdWVuY2V9LiAqL1xuZXhwb3J0IHR5cGUgU2VxdWVuY2U8VD4gPSBTZXF1ZW5jZUltcGw8VD47XG5cbnR5cGUgU2VxdWVuY2VTb3VyY2U8VD4gPSBJdGVyYWJsZTxUPiB8IFJlYWRvbmx5TWFwPHVua25vd24sIFQ+IHwgT25lT3JNYW55PFQ+IHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBBIG5vbi1zY2FsYXIge0BsaW5rIEl0ZXJhYmxlfSAtIG9uZSB0byB0cmVhdCBhcyBhIGNvbGxlY3Rpb24gb2YgZWxlbWVudHNcbiAqIHJhdGhlciB0aGFuIGEgc2NhbGFyLiB7QGxpbmsgaXNDb250YWluZXJ9IG5hcnJvd3MgdG8gdGhpcywgZXhjbHVkaW5nIHN0cmluZ3MsXG4gKiBgU3RyaW5nYC9gUmVnRXhwYCBvYmplY3RzLCBhbmQgZnVuY3Rpb25zLiB7QGxpbmsgQ29sbGVjdGlvbn0gaXMgdGhlIGVhZ2VybHktXG4gKiBzaXplZCBzdWJzZXQuIFRoZSBlbGVtZW50IGRlZmF1bHRzIHRvIGB1bmtub3duYCBzbyBhbnkgYENvbGxlY3Rpb25gIGlzXG4gKiBhc3NpZ25hYmxlIHRvIGEgYmFyZSBgQ29udGFpbmVyYC5cbiAqL1xuZXhwb3J0IHR5cGUgQ29udGFpbmVyPFQgPSB1bmtub3duPiA9IEl0ZXJhYmxlPFQ+O1xuXG4vKipcbiAqIEEgYnVpbHQtaW4sIGVhZ2VybHktc2l6ZWQge0BsaW5rIENvbnRhaW5lcn06IGFuIHtAbGluayBBcnJheX0sIHtAbGluayBTZXR9LCBvclxuICoge0BsaW5rIE1hcH0gKHdob3NlICp2YWx1ZXMqIGFyZSBgVGAgLSBhIE1hcCBpdGVyYXRlcyBgW2tleSwgdmFsdWVdYCBlbnRyaWVzLFxuICogc28gaXRzIGVsZW1lbnQgdHlwZSBkaWZmZXJzLCBidXQgaXRzIHZhbHVlIHR5cGUgaXMgYFRgKS4gQWxsIHNoYXJlIGEgY2hlYXBcbiAqIGVtcHRpbmVzcyBjaGVjayAoe0BsaW5rIGlzRW1wdHl9KS5cbiAqL1xuZXhwb3J0IHR5cGUgQ29sbGVjdGlvbjxUPiA9IFJlYWRvbmx5QXJyYXk8VD4gfCBSZWFkb25seVNldDxUPiB8IFJlYWRvbmx5TWFwPHVua25vd24sIFQ+O1xuXG5leHBvcnQgdHlwZSBPbmVPck1hbnk8VD4gPSBbVCwgLi4uVFtdXTtcblxuLyoqIE5hcnJvdyBhIHJlYWRvbmx5IGFycmF5IHRvIGEgbm9uLWVtcHR5IHtAbGluayBPbmVPck1hbnl9IHR1cGxlLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzT25lT3JNYW55PFQgPSB1bmtub3duPih2YWx1ZTogcmVhZG9ubHkgVFtdKTogdmFsdWUgaXMgT25lT3JNYW55PFQ+IHtcbiAgcmV0dXJuIHZhbHVlLmxlbmd0aCA+IDA7XG59XG5cbi8qKiBBIHNvdXJjZSBhY2NlcHRlZCBieSBhIHZhcmlhZGljIG9wOiBhIHtAbGluayBDb250YWluZXJ9IG9mIGBUYCwgb3Igbm90aGluZy4gKi9cbnR5cGUgU291cmNlPFQ+ID0gQ29udGFpbmVyPFQ+IHwgbnVsbCB8IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBFbGVtZW50IHR5cGUgb2YgYSB7QGxpbmsgZ3JvdXB9IGJ1Y2tldCBhcnJheTogd2hlbiB0aGUgcHJlZGljYXRlIGBQYCBpcyBhIHR5cGVcbiAqIGd1YXJkIChgdmFsdWUgaXMgU2ApLCB0aGUgYnVja2V0IGlzIG5hcnJvd2VkIHRvIGBTICYgVGA7IG90aGVyd2lzZSBpdCBzdGF5cyBgVGAuXG4gKi9cbnR5cGUgR3JvdXBWYWx1ZTxULCBQPiA9IFAgZXh0ZW5kcyAodmFsdWU6IGFueSwgLi4ucmVzdDogYW55W10pID0+IHZhbHVlIGlzIGluZmVyIFMgPyBTICYgVCA6IFQ7XG5cbi8qKiBBIG1hcCBvZiBncm91cCBuYW1lIC0+IHByZWRpY2F0ZSwgYXMgYWNjZXB0ZWQgYnkge0BsaW5rIGdyb3VwfS4gKi9cbnR5cGUgR3JvdXBQcmVkaWNhdGVzPFQ+ID0gUmVjb3JkPHN0cmluZywgKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuPjtcblxuLyoqXG4gKiBUeXBlIGd1YXJkIGZvciBhIHtAbGluayBDb2xsZWN0aW9ufTogYW4ge0BsaW5rIEFycmF5fSwge0BsaW5rIFNldH0sIG9yXG4gKiB7QGxpbmsgTWFwfS4gTmFycm93cyBgdmFsdWVgIHNvIGl0cyBlbGVtZW50L3ZhbHVlIHR5cGUgaXMgdHJlYXRlZCBhcyBgVGAuXG4gKlxuICogQHR5cGVQYXJhbSBUIC0gRWxlbWVudCAob3IgTWFwIHZhbHVlKSB0eXBlIGFzc2VydGVkIGZvciB0aGUgY29sbGVjdGlvbi5cbiAqIEBwYXJhbSB2YWx1ZSAtIFZhbHVlIHRvIHRlc3QuXG4gKiBAcmV0dXJucyBgdHJ1ZWAgKG5hcnJvd2luZyBgdmFsdWVgIHRvIHtAbGluayBDb2xsZWN0aW9ufTxgVGA+KSBmb3IgYVxuICogICBidWlsdC1pbiBhcnJheS9zZXQvbWFwLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNDb2xsZWN0aW9uPFQgPSB1bmtub3duPih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIENvbGxlY3Rpb248VD4ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheSh2YWx1ZSkgfHwgdmFsdWUgaW5zdGFuY2VvZiBTZXQgfHwgdmFsdWUgaW5zdGFuY2VvZiBNYXA7XG59XG5cbi8qKlxuICogYHRydWVgIHdoZW4gYSB7QGxpbmsgQ29sbGVjdGlvbn0gaGFzIG5vIGVsZW1lbnRzLiBVc2VzIGBsZW5ndGhgIGZvciBhcnJheXNcbiAqIGFuZCBgc2l6ZWAgZm9yIHtAbGluayBTZXR9L3tAbGluayBNYXB9LlxuICpcbiAqIEBwYXJhbSBjb2xsZWN0aW9uIC0gVGhlIGFycmF5LCBzZXQsIG9yIG1hcCB0byB0ZXN0LlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNFbXB0eShcbiAgY29sbGVjdGlvbjogQ29sbGVjdGlvbjx1bmtub3duPiB8IFJlY29yZDxzdHJpbmcsIHVua25vd24+LFxuICBvcHRpb25zPzogeyByZWN1cnNpdmU/OiBib29sZWFuIH0sXG4pOiBib29sZWFuIHtcbiAgZnVuY3Rpb24gdmlzaXQodmFsdWU6IHVua25vd24sIHNlZW4/OiBTZXQ8dW5rbm93bj4pOiBib29sZWFuIHtcbiAgICBpZiAodmFsdWUgPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09IFwib2JqZWN0XCIpIHtcbiAgICAgIGlmIChzZWVuPy5oYXModmFsdWUpKSByZXR1cm4gdHJ1ZTtcbiAgICAgIHNlZW4/LmFkZCh2YWx1ZSk7XG4gICAgICBpZiAoQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlLmxlbmd0aCA9PT0gMCB8fCAoc2VlbiA/IHZhbHVlLmV2ZXJ5KChpdGVtKSA9PiB2aXNpdChpdGVtLCBzZWVuKSkgOiBmYWxzZSk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICAgICAgcmV0dXJuIHZhbHVlLnNpemUgPT09IDAgfHwgKHNlZW4gPyBbLi4udmFsdWVdLmV2ZXJ5KChpdGVtKSA9PiB2aXNpdChpdGVtLCBzZWVuKSkgOiBmYWxzZSk7XG4gICAgICB9XG4gICAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBNYXApIHtcbiAgICAgICAgcmV0dXJuIChcbiAgICAgICAgICB2YWx1ZS5zaXplID09PSAwIHx8XG4gICAgICAgICAgKHNlZW4gPyBbLi4udmFsdWUudmFsdWVzKCldLmV2ZXJ5KChpdGVtKSA9PiB2aXNpdChpdGVtLCBzZWVuKSkgOiBmYWxzZSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyh2YWx1ZSk7XG4gICAgICBpZiAoa2V5cy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9IGVsc2UgaWYgKHNlZW4pIHtcbiAgICAgICAgcmV0dXJuIGtleXMuZXZlcnkoKGtleSkgPT4gdmlzaXQoKHZhbHVlIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtrZXldLCBzZWVuKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHZpc2l0KGNvbGxlY3Rpb24sIG9wdGlvbnM/LnJlY3Vyc2l2ZSA/IG5ldyBTZXQoKSA6IHVuZGVmaW5lZCk7XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhIHNvdXJjZSB0byBhbiBpdGVyYWJsZSBvZiBpdHMgYFRgIHZhbHVlcywgc28gTWFwcyBhcmUgdHJlYXRlZFxuICogdW5pZm9ybWx5IHdpdGggYXJyYXlzL3NldHM6IGEge0BsaW5rIE1hcH0geWllbGRzIGl0cyAqdmFsdWVzKiAobWF0Y2hpbmdcbiAqIHtAbGluayBDb2xsZWN0aW9ufSdzIHZhbHVlLXR5cGVkIGBUYCksIGFueSBvdGhlciBpdGVyYWJsZSB5aWVsZHMgaXRzZWxmLiBUaGlzXG4gKiBpcyB3aGF0IHtAbGluayBzZXF1ZW5jZX0gY29uc3VtZXMsIHNvIGEgYE1hcGAgY29udHJpYnV0ZXMgdmFsdWVzIGV2ZXJ5d2hlcmVcbiAqIHJhdGhlciB0aGFuIGBba2V5LCB2YWx1ZV1gIGVudHJpZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWx1ZXM8VD4oc291cmNlOiBJdGVyYWJsZTxUPiB8IFJlYWRvbmx5TWFwPHVua25vd24sIFQ+KTogSXRlcmFibGU8VD4ge1xuICByZXR1cm4gc291cmNlIGluc3RhbmNlb2YgTWFwID8gc291cmNlLnZhbHVlcygpIDogKHNvdXJjZSBhcyBJdGVyYWJsZTxUPik7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCBmb3IgYSB7QGxpbmsgQ29udGFpbmVyfSAtIGFuIGl0ZXJhYmxlIHRvIGJlIHRyZWF0ZWQgYXMgYSBjb2xsZWN0aW9uXG4gKiByYXRoZXIgdGhhbiBhIHNjYWxhci5cbiAqXG4gKiBEZWxpYmVyYXRlbHkgZXhjbHVkZXMgdmFsdWVzIHRoYXQgYXJlIHRlY2huaWNhbGx5IGl0ZXJhYmxlIGJ1dCBzaG91bGQgYmVcbiAqIHRyZWF0ZWQgYXMgc2NhbGFycyBoZXJlIC0gc3RyaW5ncywgYFN0cmluZ2AvYFJlZ0V4cGAgb2JqZWN0cywgYW5kIGZ1bmN0aW9ucyAtXG4gKiBzbyBhIGxvbmUgc3RyaW5nIGlzIG5ldmVyIHNwcmVhZCBjaGFyYWN0ZXItYnktY2hhcmFjdGVyLlxuICpcbiAqIEB0eXBlUGFyYW0gVCAtIEVsZW1lbnQgdHlwZSBhc3NlcnRlZCBmb3IgdGhlIGl0ZXJhYmxlLlxuICogQHBhcmFtIHZhbHVlIC0gVmFsdWUgdG8gdGVzdC5cbiAqIEByZXR1cm5zIGB0cnVlYCAobmFycm93aW5nIGB2YWx1ZWAgdG8ge0BsaW5rIENvbnRhaW5lcn08YFRgPikgZm9yIGEgbm9uLXN0cmluZ1xuICogICBpdGVyYWJsZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzQ29udGFpbmVyPFQgPSB1bmtub3duPih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIENvbnRhaW5lcjxUPiB7XG4gIHJldHVybiAoXG4gICAgdmFsdWUgIT0gbnVsbCAmJlxuICAgIHR5cGVvZiB2YWx1ZSAhPT0gXCJzdHJpbmdcIiAmJlxuICAgICEodmFsdWUgaW5zdGFuY2VvZiBTdHJpbmcpICYmXG4gICAgISh2YWx1ZSBpbnN0YW5jZW9mIFJlZ0V4cCkgJiZcbiAgICB0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIiAmJlxuICAgIHR5cGVvZiAodmFsdWUgYXMgeyBbU3ltYm9sLml0ZXJhdG9yXT86IHVua25vd24gfSlbU3ltYm9sLml0ZXJhdG9yXSA9PT0gXCJmdW5jdGlvblwiXG4gICk7XG59XG5cbmZ1bmN0aW9uIHNlcXVlbmNlU291cmNlczxUPiguLi5zb3VyY2VzOiBTZXF1ZW5jZVNvdXJjZTxUPltdKTogSXRlcmFibGU8VD5bXSB7XG4gIGNvbnN0IHNvdXJjZUl0ZXJhYmxlczogSXRlcmFibGU8VD5bXSA9IFtdO1xuICBmb3IgKGNvbnN0IHNvdXJjZSBvZiBzb3VyY2VzKSB7XG4gICAgaWYgKHNvdXJjZSA9PSBudWxsIHx8IChpc0NvbGxlY3Rpb24oc291cmNlKSAmJiBpc0VtcHR5KHNvdXJjZSkpKSBjb250aW51ZTtcbiAgICBzb3VyY2VJdGVyYWJsZXMucHVzaCh2YWx1ZXMoc291cmNlKSk7XG4gIH1cbiAgcmV0dXJuIHNvdXJjZUl0ZXJhYmxlcztcbn1cblxuLyoqXG4gKiBGbGF0dGVucyBuZXN0ZWQgYXJyYXlzIGZvciB7QGxpbmsgZmxhdH0uIE5vbi1hcnJheSB2YWx1ZXMgYXJlIHdyYXBwZWQgYXMgYVxuICogc2luZ2xlLWVsZW1lbnQgaXRlcmFibGU7IGRlcHRoIGRlY3JlbWVudHMgcGVyIGFycmF5IGxldmVsLlxuICovXG5mdW5jdGlvbiBmbGF0dGVuVmFsdWUodmFsdWU6IHVua25vd24sIGRlcHRoOiBudW1iZXIpOiBJdGVyYWJsZTx1bmtub3duPiB7XG4gIGlmIChkZXB0aCA+IDAgJiYgQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHtcbiAgICBjb25zdCBuZXh0RGVwdGggPSBOdW1iZXIuaXNGaW5pdGUoZGVwdGgpID8gZGVwdGggLSAxIDogZGVwdGg7XG4gICAgcmV0dXJuIHtcbiAgICAgICpbU3ltYm9sLml0ZXJhdG9yXSgpIHtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHZhbHVlKSB5aWVsZCogZmxhdHRlblZhbHVlKGl0ZW0sIG5leHREZXB0aCk7XG4gICAgICB9LFxuICAgIH07XG4gIH1cbiAgcmV0dXJuIFt2YWx1ZV07XG59XG5cbi8qKiBXcmFwIGEgcGVyLWVsZW1lbnQgdHJhbnNmb3JtIChlYWNoIGVsZW1lbnQgLT4gYW4gaXRlcmFibGUpIGFzIGEgbGF6eSB7QGxpbmsgU2VxdWVuY2V9LiAqL1xuZnVuY3Rpb24gZGVyaXZlPFQsIFU+KFxuICBzb3VyY2U6IEl0ZXJhYmxlPFQ+LFxuICBmbjogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBJdGVyYWJsZTxVPixcbik6IFNlcXVlbmNlPFU+IHtcbiAgcmV0dXJuIHNlcXVlbmNlKHtcbiAgICAqW1N5bWJvbC5pdGVyYXRvcl0oKSB7XG4gICAgICBsZXQgaW5kZXggPSAwO1xuICAgICAgZm9yIChjb25zdCB2YWx1ZSBvZiBzb3VyY2UpIHlpZWxkKiBmbih2YWx1ZSwgaW5kZXgrKyk7XG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKiBMaWtlIHtAbGluayBkZXJpdmV9LCBidXQgeWllbGRzIG9uZSB2YWx1ZSBwZXIgc291cmNlIGVsZW1lbnQgKG5vIHdyYXBwZXIgaXRlcmFibGUpLiAqL1xuZnVuY3Rpb24gZGVyaXZlT25lPFQsIFU+KHNvdXJjZTogSXRlcmFibGU8VD4sIGZuOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IFUpOiBTZXF1ZW5jZTxVPiB7XG4gIHJldHVybiBzZXF1ZW5jZSh7XG4gICAgKltTeW1ib2wuaXRlcmF0b3JdKCkge1xuICAgICAgbGV0IGluZGV4ID0gMDtcbiAgICAgIGZvciAoY29uc3QgdmFsdWUgb2Ygc291cmNlKSB5aWVsZCBmbih2YWx1ZSwgaW5kZXgrKyk7XG4gICAgfSxcbiAgfSk7XG59XG5cbi8qKlxuICogU2FtZSBzZW1hbnRpY3MgYXMgYEFycmF5LnByb3RvdHlwZS5tYXBgLCBvdmVyIGEgc2luZ2xlIHtAbGluayBDb250YWluZXJ9LlxuICpcbiAqIEBwYXJhbSBzb3VyY2UgLSBUaGUgY29udGFpbmVyIHRvIG1hcCAobnVsbGlzaCB5aWVsZHMgYW4gZW1wdHkgc2VxdWVuY2UpLlxuICogQHBhcmFtIGNhbGxiYWNrIC0gQ2FsbGVkIHBlciBlbGVtZW50IHdpdGggaXRzIGluZGV4OyBpdHMgcmVzdWx0IGlzIGVtaXR0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXA8VCwgVT4oXG4gIHNvdXJjZTogU291cmNlPFQ+LFxuICBjYWxsYmFjazogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBVLFxuKTogU2VxdWVuY2U8VT4ge1xuICByZXR1cm4gZGVyaXZlT25lKHNlcXVlbmNlKHNvdXJjZSksIGNhbGxiYWNrKTtcbn1cblxuLyoqXG4gKiBTYW1lIHNlbWFudGljcyBhcyBgQXJyYXkucHJvdG90eXBlLmZpbHRlcmAsIG92ZXIgYSBzaW5nbGUge0BsaW5rIENvbnRhaW5lcn0uXG4gKiBBIHR5cGUtZ3VhcmQgcHJlZGljYXRlIG5hcnJvd3MgdGhlIHJlc3VsdGluZyBlbGVtZW50IHR5cGUuXG4gKlxuICogQHBhcmFtIHNvdXJjZSAtIFRoZSBjb250YWluZXIgdG8gZmlsdGVyIChudWxsaXNoIHlpZWxkcyBhbiBlbXB0eSBzZXF1ZW5jZSkuXG4gKiBAcGFyYW0gcHJlZGljYXRlIC0gS2VlcHMgZWxlbWVudHMgZm9yIHdoaWNoIGl0IHJldHVybnMgYHRydWVgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyPFQsIFMgZXh0ZW5kcyBUPihcbiAgc291cmNlOiBTb3VyY2U8VD4sXG4gIHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiB2YWx1ZSBpcyBTLFxuKTogU2VxdWVuY2U8Uz47XG5leHBvcnQgZnVuY3Rpb24gZmlsdGVyPFQ+KFxuICBzb3VyY2U6IFNvdXJjZTxUPixcbiAgcHJlZGljYXRlOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4sXG4pOiBTZXF1ZW5jZTxUPjtcbmV4cG9ydCBmdW5jdGlvbiBmaWx0ZXI8VD4oXG4gIHNvdXJjZTogU291cmNlPFQ+LFxuICBwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gYm9vbGVhbixcbik6IFNlcXVlbmNlPFQ+IHtcbiAgcmV0dXJuIGRlcml2ZShzZXF1ZW5jZShzb3VyY2UpLCBmdW5jdGlvbiogKHZhbHVlLCBpbmRleCkge1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4KSkgeWllbGQgdmFsdWU7XG4gIH0pO1xufVxuXG4vKipcbiAqIENvbmNhdGVuYXRlcyB0aGUgc291cmNlcyBhbmQgeWllbGRzIG9ubHkgZWxlbWVudHMgdGhhdCBhcmUgbm90IGBudWxsYCBvclxuICogYHVuZGVmaW5lZGAsIG5hcnJvd2luZyB0aGUgZWxlbWVudCB0eXBlIHRvIHtAbGluayBOb25OdWxsYWJsZX08YFRgPi5cbiAqXG4gKiBAcGFyYW0gc291cmNlcyAtIENvbnRhaW5lcnMgdG8gY29uY2F0ZW5hdGUgKG51bGxpc2ggc291cmNlcyBhcmUgc2tpcHBlZCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBub25OdWxsPFQ+KC4uLnNvdXJjZXM6IHJlYWRvbmx5IFNvdXJjZTxUPltdKTogU2VxdWVuY2U8Tm9uTnVsbGFibGU8VD4+IHtcbiAgcmV0dXJuIGZpbHRlcihzZXF1ZW5jZSguLi5zb3VyY2VzKSwgKHZhbHVlKTogdmFsdWUgaXMgTm9uTnVsbGFibGU8VD4gPT4gdmFsdWUgIT0gbnVsbCk7XG59XG5cbi8qKlxuICogU2FtZSBzZW1hbnRpY3MgYXMgYEFycmF5LnByb3RvdHlwZS5mbGF0TWFwYCwgb3ZlciBhIHNpbmdsZSB7QGxpbmsgQ29udGFpbmVyfS5cbiAqXG4gKiBAcGFyYW0gc291cmNlIC0gVGhlIGNvbnRhaW5lciB0byBtYXAgKG51bGxpc2ggeWllbGRzIGFuIGVtcHR5IHNlcXVlbmNlKS5cbiAqIEBwYXJhbSBjYWxsYmFjayAtIFJldHVybnMgYSB2YWx1ZSBvciBhcnJheSBvZiB2YWx1ZXMsIGZsYXR0ZW5lZCBvbmUgbGV2ZWwuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGF0TWFwPFQsIFU+KFxuICBzb3VyY2U6IFNvdXJjZTxUPixcbiAgY2FsbGJhY2s6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gVSB8IFJlYWRvbmx5QXJyYXk8VT4sXG4pOiBTZXF1ZW5jZTxVPiB7XG4gIHJldHVybiBkZXJpdmUoc2VxdWVuY2Uoc291cmNlKSwgZnVuY3Rpb24qICh2YWx1ZSwgaW5kZXgpIHtcbiAgICBjb25zdCByZXN1bHQgPSBjYWxsYmFjayh2YWx1ZSwgaW5kZXgpO1xuICAgIGlmIChBcnJheS5pc0FycmF5KHJlc3VsdCkpIHlpZWxkKiByZXN1bHQ7XG4gICAgZWxzZSB5aWVsZCByZXN1bHQgYXMgVTtcbiAgfSk7XG59XG5cbi8qKlxuICogU2FtZSBzZW1hbnRpY3MgYXMgYEFycmF5LnByb3RvdHlwZS5mbGF0YCAoYXJyYXlzIG9ubHkpLiBgZGVwdGhgIGxlYWRzIHNvIHRoZVxuICogc291cmNlcyBjYW4gc3RheSB2YXJpYWRpYzsgdXNlIGBkZXB0aCA8IDFgIGZvciBhIG5vLW9wIHBhc3N0aHJvdWdoLlxuICpcbiAqIEBwYXJhbSBkZXB0aCAtIEhvdyBtYW55IGFycmF5IGxldmVscyB0byBmbGF0dGVuLlxuICogQHBhcmFtIHNvdXJjZXMgLSBDb250YWluZXJzIHRvIGNvbmNhdGVuYXRlLCB0aGVuIGZsYXR0ZW4gKG51bGxpc2ggc2tpcHBlZCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmbGF0PFQ+KGRlcHRoOiBudW1iZXIsIC4uLnNvdXJjZXM6IHJlYWRvbmx5IFNvdXJjZTxUPltdKTogU2VxdWVuY2U8VD4ge1xuICBjb25zdCBzcmMgPSBzZXF1ZW5jZSguLi5zb3VyY2VzKTtcbiAgaWYgKGRlcHRoIDwgMSkgcmV0dXJuIHNyYztcbiAgcmV0dXJuIGRlcml2ZShzcmMsICh2YWx1ZSkgPT4gZmxhdHRlblZhbHVlKHZhbHVlLCBkZXB0aCkpIGFzIFNlcXVlbmNlPFQ+O1xufVxuXG4vKipcbiAqIENvbmNhdGVuYXRlcyB0aGUgc291cmNlcywgdGhlbiBsYXppbHkgeWllbGRzIHZhbHVlcyBpbiBlbmNvdW50ZXIgb3JkZXIsXG4gKiBza2lwcGluZyBhIHZhbHVlIG9ubHkgd2hlbiBhbiBlcXVhbCBvbmUgd2FzIGFscmVhZHkgeWllbGRlZCAoYFNldGAgL1xuICogU2FtZVZhbHVlWmVybykuIFVuaXF1ZW5lc3MgaXMgY2hlY2tlZCBwZXIgZWxlbWVudCBhcyBpdCBpcyBjb25zdW1lZC5cbiAqXG4gKiBAcGFyYW0gc291cmNlcyAtIENvbnRhaW5lcnMgdG8gY29uY2F0ZW5hdGUgKG51bGxpc2ggc291cmNlcyBhcmUgc2tpcHBlZCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBkaXN0aW5jdDxUPiguLi5zb3VyY2VzOiByZWFkb25seSBTb3VyY2U8VD5bXSk6IFNlcXVlbmNlPFQ+IHtcbiAgY29uc3Qgc3JjID0gc2VxdWVuY2UoLi4uc291cmNlcyk7XG4gIHJldHVybiBzZXF1ZW5jZSh7XG4gICAgKltTeW1ib2wuaXRlcmF0b3JdKCkge1xuICAgICAgY29uc3Qgc2VlbiA9IG5ldyBTZXQ8VD4oKTtcbiAgICAgIGZvciAoY29uc3QgdmFsdWUgb2Ygc3JjKSB7XG4gICAgICAgIGlmIChzZWVuLmhhcyh2YWx1ZSkpIGNvbnRpbnVlO1xuICAgICAgICBzZWVuLmFkZCh2YWx1ZSk7XG4gICAgICAgIHlpZWxkIHZhbHVlO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIFlpZWxkcyBgc291cmNlYCwgdGhlbiBlYWNoIGFwcGVuZGVkIGBpdGVtYCBpbiBvcmRlciAoYXJyYXlzIHNwcmVhZCBvbmUgbGV2ZWwpLFxuICogbWlycm9yaW5nIGBBcnJheS5wcm90b3R5cGUuY29uY2F0YC4gYGl0ZW1zYCBhcmUgc2NhbGFyIHZhbHVlcy9hcnJheXMsIG5vdFxuICogY29udGFpbmVycywgc28gYHNvdXJjZWAgc3RheXMgYSBzaW5nbGUgbGVhZGluZyBhcmd1bWVudC5cbiAqXG4gKiBAcGFyYW0gc291cmNlIC0gVGhlIGxlYWRpbmcgY29udGFpbmVyIChudWxsaXNoIHlpZWxkcyBqdXN0IHRoZSBpdGVtcykuXG4gKiBAcGFyYW0gaXRlbXMgLSBWYWx1ZXMgKG9yIGFycmF5cyBvZiB2YWx1ZXMpIGFwcGVuZGVkIGFmdGVyIHRoZSBzb3VyY2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb25jYXQ8VD4oXG4gIHNvdXJjZTogU291cmNlPFQ+LFxuICAuLi5pdGVtczogcmVhZG9ubHkgKFQgfCBSZWFkb25seUFycmF5PFQ+KVtdXG4pOiBTZXF1ZW5jZTxUPiB7XG4gIGNvbnN0IHNyYyA9IHNlcXVlbmNlKHNvdXJjZSk7XG4gIGlmIChpdGVtcy5sZW5ndGggPT09IDApIHJldHVybiBzcmM7XG4gIHJldHVybiBzZXF1ZW5jZSh7XG4gICAgKltTeW1ib2wuaXRlcmF0b3JdKCkge1xuICAgICAgeWllbGQqIHNyYztcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShpdGVtKSkgeWllbGQqIGl0ZW07XG4gICAgICAgIGVsc2UgeWllbGQgaXRlbSBhcyBUO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIFlpZWxkcyBhdCBtb3N0IGBjb3VudGAgZWxlbWVudHMgZnJvbSB0aGUgZnJvbnQgb2YgdGhlIGNvbmNhdGVuYXRlZCBzb3VyY2VzLlxuICogYGNvdW50YCBsZWFkcyBzbyB0aGUgc291cmNlcyBjYW4gc3RheSB2YXJpYWRpYy5cbiAqXG4gKiBAcGFyYW0gY291bnQgLSBNYXhpbXVtIG51bWJlciBvZiBlbGVtZW50cyB0byB5aWVsZCAoYDw9IDBgIHlpZWxkcyBub25lKS5cbiAqIEBwYXJhbSBzb3VyY2VzIC0gQ29udGFpbmVycyB0byBjb25jYXRlbmF0ZSAobnVsbGlzaCBzb3VyY2VzIGFyZSBza2lwcGVkKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRha2U8VD4oY291bnQ6IG51bWJlciwgLi4uc291cmNlczogcmVhZG9ubHkgU291cmNlPFQ+W10pOiBTZXF1ZW5jZTxUPiB7XG4gIGlmIChjb3VudCA8PSAwKSByZXR1cm4gZW1wdHlTZXF1ZW5jZSBhcyBTZXF1ZW5jZTxUPjtcbiAgY29uc3Qgc3JjID0gc2VxdWVuY2UoLi4uc291cmNlcyk7XG4gIHJldHVybiBzZXF1ZW5jZSh7XG4gICAgKltTeW1ib2wuaXRlcmF0b3JdKCkge1xuICAgICAgbGV0IHRha2VuID0gMDtcbiAgICAgIGZvciAoY29uc3QgdmFsdWUgb2Ygc3JjKSB7XG4gICAgICAgIHlpZWxkIHZhbHVlO1xuICAgICAgICBpZiAoKyt0YWtlbiA+PSBjb3VudCkgcmV0dXJuO1xuICAgICAgfVxuICAgIH0sXG4gIH0pO1xufVxuXG4vKipcbiAqIFNwbGl0cyB0aGUgY29uY2F0ZW5hdGVkIHNvdXJjZXMgaW50byBvbmUgYXJyYXkgcGVyIG5hbWVkIHByZWRpY2F0ZS4gQ29uc3VtZXNcbiAqIHRoZSBpbnB1dCBvbmNlLCByb3V0aW5nIGVhY2ggZWxlbWVudCB0byB0aGUgRklSU1QgcHJlZGljYXRlIGl0IHNhdGlzZmllcyAoc29cbiAqIGdyb3VwcyBhcmUgZGlzam9pbnQpOyBlbGVtZW50cyBtYXRjaGluZyBubyBwcmVkaWNhdGUgYXJlIGRyb3BwZWQuIFR5cGUtZ3VhcmRcbiAqIHByZWRpY2F0ZXMgbmFycm93IHRoZWlyIGdyb3VwJ3MgZWxlbWVudCB0eXBlIChzZWUge0BsaW5rIEdyb3VwVmFsdWV9KS5cbiAqIGBwcmVkaWNhdGVzYCBsZWFkcyBzbyB0aGUgc291cmNlcyBjYW4gc3RheSB2YXJpYWRpYy5cbiAqXG4gKiBAdHlwZVBhcmFtIEcgLSBUaGUgbWFwIG9mIGdyb3VwIG5hbWUgLT4gcHJlZGljYXRlLlxuICogQHBhcmFtIHByZWRpY2F0ZXMgLSBOYW1lZCBwcmVkaWNhdGVzOyBldmFsdWF0ZWQgaW4gZGVjbGFyYXRpb24gb3JkZXIuXG4gKiBAcGFyYW0gc291cmNlcyAtIENvbnRhaW5lcnMgdG8gY29uY2F0ZW5hdGUgKG51bGxpc2ggc291cmNlcyBhcmUgc2tpcHBlZCkuXG4gKiBAcmV0dXJucyBBbiBvYmplY3Qgd2l0aCB0aGUgc2FtZSBrZXlzLCBlYWNoIGFuIGFycmF5IG9mIGl0cyBncm91cCdzIGVsZW1lbnRzLlxuICpcbiAqIEBleGFtcGxlXG4gKiAgIGNvbnN0IHsgc3RyaW5ncywgZm5zIH0gPSBncm91cCh7IHN0cmluZ3M6IGlzU3RyaW5nLCBmbnM6IGlzRnVuY3Rpb24gfSwgeHMpO1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ3JvdXA8VCwgRyBleHRlbmRzIEdyb3VwUHJlZGljYXRlczxUPj4oXG4gIHByZWRpY2F0ZXM6IEcsXG4gIC4uLnNvdXJjZXM6IHJlYWRvbmx5IFNvdXJjZTxUPltdXG4pOiB7IFtLIGluIGtleW9mIEddOiBHcm91cFZhbHVlPFQsIEdbS10+W10gfSB7XG4gIGNvbnN0IGtleXMgPSBPYmplY3Qua2V5cyhwcmVkaWNhdGVzKSBhcyAoa2V5b2YgRylbXTtcbiAgY29uc3QgYnVja2V0cyA9IG5ldyBNYXA8a2V5b2YgRywgVFtdPihrZXlzLm1hcCgoa2V5KSA9PiBba2V5LCBbXV0pKTtcbiAgbGV0IGluZGV4ID0gMDtcbiAgZm9yIChjb25zdCB2YWx1ZSBvZiBzZXF1ZW5jZSguLi5zb3VyY2VzKSkge1xuICAgIGNvbnN0IGkgPSBpbmRleCsrO1xuICAgIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICAgIGlmIChwcmVkaWNhdGVzW2tleV0hKHZhbHVlLCBpKSkge1xuICAgICAgICBidWNrZXRzLmdldChrZXkpIS5wdXNoKHZhbHVlKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGNvbnN0IHJlc3VsdCA9IHt9IGFzIHsgW0sgaW4ga2V5b2YgR106IEdyb3VwVmFsdWU8VCwgR1tLXT5bXSB9O1xuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgcmVzdWx0W2tleV0gPSBidWNrZXRzLmdldChrZXkpISBhcyBHcm91cFZhbHVlPFQsIEdbdHlwZW9mIGtleV0+W107XG4gIH1cbiAgcmV0dXJuIHJlc3VsdDtcbn1cblxuLyoqXG4gKiBTYW1lIHNlbWFudGljcyBhcyBgQXJyYXkucHJvdG90eXBlLmZpbmRgLCBvdmVyIGEgc2luZ2xlIHtAbGluayBDb250YWluZXJ9LlxuICogQ29uc3VtZXMgZWxlbWVudHMgdW50aWwgYSBtYXRjaC4gQSB0eXBlIGd1YXJkIG5hcnJvd3MgdGhlIHJldHVybiB0eXBlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZDxULCBTIGV4dGVuZHMgVD4oXG4gIHNvdXJjZTogU291cmNlPFQ+LFxuICBwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gdmFsdWUgaXMgUyxcbik6IFMgfCB1bmRlZmluZWQ7XG5leHBvcnQgZnVuY3Rpb24gZmluZDxUPihcbiAgc291cmNlOiBTb3VyY2U8VD4sXG4gIHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuLFxuKTogVCB8IHVuZGVmaW5lZDtcbmV4cG9ydCBmdW5jdGlvbiBmaW5kPFQ+KFxuICBzb3VyY2U6IFNvdXJjZTxUPixcbiAgcHJlZGljYXRlOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4sXG4pOiBUIHwgdW5kZWZpbmVkIHtcbiAgbGV0IGluZGV4ID0gMDtcbiAgZm9yIChjb25zdCB2YWx1ZSBvZiBzZXF1ZW5jZShzb3VyY2UpKSB7XG4gICAgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgrKykpIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIFNhbWUgc2VtYW50aWNzIGFzIGBBcnJheS5wcm90b3R5cGUuZmluZExhc3RgLCBvdmVyIGEgc2luZ2xlIHtAbGluayBDb250YWluZXJ9LlxuICogQ29uc3VtZXMgdGhlIGZ1bGwgc291cmNlLiBBIHR5cGUgZ3VhcmQgbmFycm93cyB0aGUgcmV0dXJuIHR5cGUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTGFzdDxULCBTIGV4dGVuZHMgVD4oXG4gIHNvdXJjZTogU291cmNlPFQ+LFxuICBwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gdmFsdWUgaXMgUyxcbik6IFMgfCB1bmRlZmluZWQ7XG5leHBvcnQgZnVuY3Rpb24gZmluZExhc3Q8VD4oXG4gIHNvdXJjZTogU291cmNlPFQ+LFxuICBwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gYm9vbGVhbixcbik6IFQgfCB1bmRlZmluZWQ7XG5leHBvcnQgZnVuY3Rpb24gZmluZExhc3Q8VD4oXG4gIHNvdXJjZTogU291cmNlPFQ+LFxuICBwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gYm9vbGVhbixcbik6IFQgfCB1bmRlZmluZWQge1xuICBsZXQgaW5kZXggPSAwO1xuICBsZXQgbWF0Y2g6IFQgfCB1bmRlZmluZWQ7XG4gIGZvciAoY29uc3QgdmFsdWUgb2Ygc2VxdWVuY2Uoc291cmNlKSkge1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4KyspKSBtYXRjaCA9IHZhbHVlO1xuICB9XG4gIHJldHVybiBtYXRjaDtcbn1cblxuLyoqXG4gKiBTYW1lIHNlbWFudGljcyBhcyBgQXJyYXkucHJvdG90eXBlLmZpbmRJbmRleGAsIG92ZXIgYSBzaW5nbGUge0BsaW5rIENvbnRhaW5lcn0uXG4gKiBDb25zdW1lcyBlbGVtZW50cyB1bnRpbCBhIG1hdGNoLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZEluZGV4PFQ+KFxuICBzb3VyY2U6IFNvdXJjZTxUPixcbiAgcHJlZGljYXRlOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4sXG4pOiBudW1iZXIge1xuICBsZXQgaW5kZXggPSAwO1xuICBmb3IgKGNvbnN0IHZhbHVlIG9mIHNlcXVlbmNlKHNvdXJjZSkpIHtcbiAgICBpZiAocHJlZGljYXRlKHZhbHVlLCBpbmRleCkpIHJldHVybiBpbmRleDtcbiAgICBpbmRleCsrO1xuICB9XG4gIHJldHVybiAtMTtcbn1cblxuLyoqXG4gKiBTYW1lIHNlbWFudGljcyBhcyBgQXJyYXkucHJvdG90eXBlLmZpbmRMYXN0SW5kZXhgLCBvdmVyIGEgc2luZ2xlXG4gKiB7QGxpbmsgQ29udGFpbmVyfS4gQ29uc3VtZXMgdGhlIGZ1bGwgc291cmNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZmluZExhc3RJbmRleDxUPihcbiAgc291cmNlOiBTb3VyY2U8VD4sXG4gIHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuLFxuKTogbnVtYmVyIHtcbiAgbGV0IGluZGV4ID0gMDtcbiAgbGV0IG1hdGNoID0gLTE7XG4gIGZvciAoY29uc3QgdmFsdWUgb2Ygc2VxdWVuY2Uoc291cmNlKSkge1xuICAgIGlmIChwcmVkaWNhdGUodmFsdWUsIGluZGV4KSkgbWF0Y2ggPSBpbmRleDtcbiAgICBpbmRleCsrO1xuICB9XG4gIHJldHVybiBtYXRjaDtcbn1cblxuLyoqXG4gKiBTYW1lIHNlbWFudGljcyBhcyBgQXJyYXkucHJvdG90eXBlLnNvbWVgLCBvdmVyIGEgc2luZ2xlIHtAbGluayBDb250YWluZXJ9LlxuICogU2hvcnQtY2lyY3VpdHMgb24gdGhlIGZpcnN0IG1hdGNoLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc29tZTxUPihcbiAgc291cmNlOiBTb3VyY2U8VD4sXG4gIHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuLFxuKTogYm9vbGVhbiB7XG4gIGxldCBpbmRleCA9IDA7XG4gIGZvciAoY29uc3QgdmFsdWUgb2Ygc2VxdWVuY2Uoc291cmNlKSkgaWYgKHByZWRpY2F0ZSh2YWx1ZSwgaW5kZXgrKykpIHJldHVybiB0cnVlO1xuICByZXR1cm4gZmFsc2U7XG59XG5cbi8qKlxuICogU2FtZSBzZW1hbnRpY3MgYXMgYEFycmF5LnByb3RvdHlwZS5ldmVyeWAsIG92ZXIgYSBzaW5nbGUge0BsaW5rIENvbnRhaW5lcn0uXG4gKiBTaG9ydC1jaXJjdWl0cyBvbiB0aGUgZmlyc3QgZmFpbHVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGV2ZXJ5PFQsIFMgZXh0ZW5kcyBUPihcbiAgc291cmNlOiBTb3VyY2U8VD4sXG4gIHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiB2YWx1ZSBpcyBTLFxuKTogYm9vbGVhbjtcbmV4cG9ydCBmdW5jdGlvbiBldmVyeTxUPihcbiAgc291cmNlOiBTb3VyY2U8VD4sXG4gIHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuLFxuKTogYm9vbGVhbjtcbmV4cG9ydCBmdW5jdGlvbiBldmVyeTxUPihcbiAgc291cmNlOiBTb3VyY2U8VD4sXG4gIHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuLFxuKTogYm9vbGVhbiB7XG4gIGxldCBpbmRleCA9IDA7XG4gIGZvciAoY29uc3QgdmFsdWUgb2Ygc2VxdWVuY2Uoc291cmNlKSkgaWYgKCFwcmVkaWNhdGUodmFsdWUsIGluZGV4KyspKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiB0cnVlO1xufVxuXG4vKipcbiAqIFNhbWUgc2VtYW50aWNzIGFzIGBBcnJheS5wcm90b3R5cGUuZm9yRWFjaGAsIG92ZXIgYSBzaW5nbGUge0BsaW5rIENvbnRhaW5lcn0uXG4gKiBDb25zdW1lcyB0aGUgc291cmNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZm9yRWFjaDxUPihzb3VyY2U6IFNvdXJjZTxUPiwgY2FsbGJhY2s6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gdm9pZCk6IHZvaWQge1xuICBsZXQgaW5kZXggPSAwO1xuICBmb3IgKGNvbnN0IHZhbHVlIG9mIHNlcXVlbmNlKHNvdXJjZSkpIGNhbGxiYWNrKHZhbHVlLCBpbmRleCsrKTtcbn1cblxuLyoqXG4gKiBTYW1lIHNlbWFudGljcyBhcyBgQXJyYXkucHJvdG90eXBlLmF0YCBvdmVyIHRoZSBjb25jYXRlbmF0ZWQgc291cmNlcy5cbiAqIE5vbi1uZWdhdGl2ZSBpbmRpY2VzIHNjYW4gbGF6aWx5OyBuZWdhdGl2ZSBpbmRpY2VzIG1hdGVyaWFsaXplIGZpcnN0LiBgaW5kZXhgXG4gKiBsZWFkcyBzbyB0aGUgc291cmNlcyBjYW4gc3RheSB2YXJpYWRpYy5cbiAqXG4gKiBAcGFyYW0gaW5kZXggLSBaZXJvLWJhc2VkIHBvc2l0aW9uOyBuZWdhdGl2ZSBjb3VudHMgZnJvbSB0aGUgZW5kLlxuICogQHBhcmFtIHNvdXJjZXMgLSBDb250YWluZXJzIHRvIGNvbmNhdGVuYXRlIChudWxsaXNoIHNvdXJjZXMgYXJlIHNraXBwZWQpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXQ8VD4oaW5kZXg6IG51bWJlciwgLi4uc291cmNlczogcmVhZG9ubHkgU291cmNlPFQ+W10pOiBUIHwgdW5kZWZpbmVkIHtcbiAgY29uc3Qgc3JjID0gc2VxdWVuY2UoLi4uc291cmNlcyk7XG4gIGlmIChpbmRleCA8IDApIHJldHVybiB0b0FycmF5KHNyYykuYXQoaW5kZXgpO1xuICBsZXQgaSA9IDA7XG4gIGZvciAoY29uc3QgdmFsdWUgb2Ygc3JjKSB7XG4gICAgaWYgKGkrKyA9PT0gaW5kZXgpIHJldHVybiB2YWx1ZTtcbiAgfVxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdG9PbmVPck1hbnk8VD4oaW5wdXQ6IFQgfCBPbmVPck1hbnk8VD4pOiBPbmVPck1hbnk8VD4ge1xuICByZXR1cm4gQXJyYXkuaXNBcnJheShpbnB1dCkgPyBpbnB1dCA6IFtpbnB1dF07XG59XG5cbi8qKlxuICogTWF0ZXJpYWxpemVzIHRoZSBjb25jYXRlbmF0ZWQgc291cmNlcyBpbnRvIGEgbmV3IGFycmF5LiBDb25zdW1lcyBzaW5nbGUtcGFzc1xuICogc291cmNlcy5cbiAqXG4gKiBAcGFyYW0gc291cmNlcyAtIENvbnRhaW5lcnMgdG8gY29uY2F0ZW5hdGUgKG51bGxpc2ggc291cmNlcyBhcmUgc2tpcHBlZCkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0b0FycmF5PFQ+KC4uLnNvdXJjZXM6IHJlYWRvbmx5IFNvdXJjZTxUPltdKTogcmVhZG9ubHkgVFtdIHtcbiAgcmV0dXJuIFsuLi5zZXF1ZW5jZSguLi5zb3VyY2VzKV07XG59XG5cbi8qKlxuICogTGF6eSBpdGVyYWJsZSBzZXF1ZW5jZSB3aXRoIGBBcnJheWAtY29tcGF0aWJsZSB0cmFuc2Zvcm1zIGFuZCB0ZXJtaW5hbFxuICogbWV0aG9kcy4gU2luZ2xlLXBhc3MgYnkgZGVmYXVsdDsgY2FsbCB7QGxpbmsgU2VxdWVuY2VJbXBsLmNhY2hlfSB0byByZXRhaW5cbiAqIHB1bGxlZCB2YWx1ZXMgZm9yIHJlLWl0ZXJhdGlvbi4gQnVpbHQgZm9yIGdlbmVyYXRvcnMgYW5kIG90aGVyIHNvdXJjZXMgd2hlcmVcbiAqIGEgc2Vjb25kIHBhc3MgaXMgbm90IGd1YXJhbnRlZWQuXG4gKlxuICogVGhlIG1ldGhvZHMgZm9yd2FyZCB0byB0aGUgc3RhbmRhbG9uZSBmdW5jdGlvbnMgb2YgdGhlIHNhbWUgbmFtZSAtIHNlZSBlYWNoXG4gKiBtZXRob2QncyBgQHNlZWAgLSBzbyB0aGUgZnJlZS1mdW5jdGlvbiBhbmQgY2hhaW5lZCBzdHlsZXMgc2hhcmUgb25lIGltcGwuXG4gKi9cbmNsYXNzIFNlcXVlbmNlSW1wbDxUPiB7XG4gIHByaXZhdGUgaXRlcmF0b3I/OiBJdGVyYXRvcjxUPjtcbiAgcHJpdmF0ZSBleGhhdXN0ZWQ6IGJvb2xlYW47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBzb3VyY2U6IEl0ZXJhYmxlPFQ+LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYnVmZmVyOiBUW10gfCB1bmRlZmluZWQsXG4gICAgc3RhdGU6IHsgcmVhZG9ubHkgZXhoYXVzdGVkPzogYm9vbGVhbiB9ID0ge30sXG4gICkge1xuICAgIHRoaXMuZXhoYXVzdGVkID0gc3RhdGUuZXhoYXVzdGVkID8/IGZhbHNlO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgY2FjaGluZygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5idWZmZXIgIT09IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKiBBZHZhbmNlIHRoZSB1bmRlcmx5aW5nIHNvdXJjZSBvbmNlLCBjcmVhdGluZyB0aGUgaXRlcmF0b3Igb24gZmlyc3QgdXNlLiAqL1xuICBwcml2YXRlIHB1bGwoKTogSXRlcmF0b3JSZXN1bHQ8VD4ge1xuICAgIHRoaXMuaXRlcmF0b3IgPz89IHRoaXMuc291cmNlW1N5bWJvbC5pdGVyYXRvcl0oKTtcbiAgICByZXR1cm4gdGhpcy5pdGVyYXRvci5uZXh0KCk7XG4gIH1cblxuICAqW1N5bWJvbC5pdGVyYXRvcl0oKTogSXRlcmF0b3I8VD4ge1xuICAgIGlmICghdGhpcy5jYWNoaW5nKSB7XG4gICAgICBpZiAodGhpcy5leGhhdXN0ZWQpIHJldHVybjtcbiAgICAgIGZvciAobGV0IG5leHQgPSB0aGlzLnB1bGwoKTsgIW5leHQuZG9uZTsgbmV4dCA9IHRoaXMucHVsbCgpKSB7XG4gICAgICAgIHlpZWxkIG5leHQudmFsdWU7XG4gICAgICB9XG4gICAgICB0aGlzLmV4aGF1c3RlZCA9IHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIENhY2hlZDogaXRlcmF0ZSBsaWtlIGEgbGlzdC4gQWx3YXlzIHJlcGxheSB0aGUgYnVmZmVyIGZyb20gdGhlIHN0YXJ0LFxuICAgICAgLy8gZXh0ZW5kaW5nIGl0IGZyb20gdGhlIHNvdXJjZSBvbiBkZW1hbmQgdW50aWwgZXhoYXVzdGVkLiBBIGJyb2tlbiBsb29wXG4gICAgICAvLyBsZWF2ZXMgdGhlIGJ1ZmZlciBpbnRhY3QsIHNvIHRoZSBuZXh0IGl0ZXJhdGlvbiBzdGFydHMgb3ZlciBmcm9tIHRoZVxuICAgICAgLy8gYmVnaW5uaW5nLlxuICAgICAgY29uc3QgYnVmZmVyID0gdGhpcy5idWZmZXIhO1xuICAgICAgbGV0IGluZGV4ID0gMDtcbiAgICAgIGZvciAoOzspIHtcbiAgICAgICAgaWYgKGluZGV4IDwgYnVmZmVyLmxlbmd0aCkge1xuICAgICAgICAgIHlpZWxkIGJ1ZmZlcltpbmRleCsrXSE7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHRoaXMuZXhoYXVzdGVkKSByZXR1cm47XG4gICAgICAgIGNvbnN0IG5leHQgPSB0aGlzLnB1bGwoKTtcbiAgICAgICAgaWYgKG5leHQuZG9uZSkge1xuICAgICAgICAgIHRoaXMuZXhoYXVzdGVkID0gdHJ1ZTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgYnVmZmVyLnB1c2gobmV4dC52YWx1ZSk7XG4gICAgICAgIHlpZWxkIG5leHQudmFsdWU7XG4gICAgICAgIGluZGV4Kys7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIEBzZWUge0BsaW5rIG1hcH0gKi9cbiAgbWFwPFU+KGNhbGxiYWNrOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IFUpOiBTZXF1ZW5jZTxVPiB7XG4gICAgcmV0dXJuIG1hcCh0aGlzLCBjYWxsYmFjayk7XG4gIH1cblxuICAvKiogQHNlZSB7QGxpbmsgZmlsdGVyfSAqL1xuICBmaWx0ZXI8UyBleHRlbmRzIFQ+KHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiB2YWx1ZSBpcyBTKTogU2VxdWVuY2U8Uz47XG4gIGZpbHRlcihwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gYm9vbGVhbik6IFNlcXVlbmNlPFQ+O1xuICBmaWx0ZXIocHJlZGljYXRlOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4pOiBTZXF1ZW5jZTxUPiB7XG4gICAgcmV0dXJuIGZpbHRlcih0aGlzLCBwcmVkaWNhdGUpO1xuICB9XG5cbiAgLyoqIEBzZWUge0BsaW5rIG5vbk51bGx9ICovXG4gIG5vbk51bGwoKTogU2VxdWVuY2U8Tm9uTnVsbGFibGU8VD4+IHtcbiAgICByZXR1cm4gbm9uTnVsbCh0aGlzKTtcbiAgfVxuXG4gIC8qKiBAc2VlIHtAbGluayBmbGF0TWFwfSAqL1xuICBmbGF0TWFwPFU+KGNhbGxiYWNrOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IFUgfCBSZWFkb25seUFycmF5PFU+KTogU2VxdWVuY2U8VT4ge1xuICAgIHJldHVybiBmbGF0TWFwKHRoaXMsIGNhbGxiYWNrKTtcbiAgfVxuXG4gIC8qKiBAc2VlIHtAbGluayBmbGF0fSAqL1xuICBmbGF0KGRlcHRoID0gMSk6IFNlcXVlbmNlPFQ+IHtcbiAgICByZXR1cm4gZmxhdChkZXB0aCwgdGhpcyk7XG4gIH1cblxuICAvKiogQHNlZSB7QGxpbmsgZGlzdGluY3R9ICovXG4gIGRpc3RpbmN0KCk6IFNlcXVlbmNlPFQ+IHtcbiAgICByZXR1cm4gZGlzdGluY3QodGhpcyk7XG4gIH1cblxuICAvKiogQHNlZSB7QGxpbmsgY29uY2F0fSAqL1xuICBjb25jYXQoLi4uaXRlbXM6IHJlYWRvbmx5IChUIHwgUmVhZG9ubHlBcnJheTxUPilbXSk6IFNlcXVlbmNlPFQ+IHtcbiAgICByZXR1cm4gY29uY2F0KHRoaXMsIC4uLml0ZW1zKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBMYXppbHkgeWllbGRzIHRoaXMgc2VxdWVuY2UgZm9sbG93ZWQgYnkgZWFjaCBpdGVyYWJsZSBgc291cmNlYCBpbiBvcmRlci5cbiAgICogTGlrZSB7QGxpbmsgY29uY2F0fSwgYnV0IGZvciBpdGVyYWJsZSBzb3VyY2VzIChnZW5lcmF0b3JzLCBvdGhlciBzZXF1ZW5jZXMsXG4gICAqIGBTZXRgLCBgTWFwYCwgZXRjLikgcmF0aGVyIHRoYW4gc2NhbGFyIHZhbHVlcyBvciBhcnJheXMuIEEge0BsaW5rIE1hcH1cbiAgICogc291cmNlIGNvbnRyaWJ1dGVzIGl0cyB2YWx1ZXMuXG4gICAqXG4gICAqIEBzZWUge0BsaW5rIHNlcXVlbmNlfVxuICAgKi9cbiAgam9pbiguLi5zb3VyY2VzOiByZWFkb25seSBTZXF1ZW5jZVNvdXJjZTxUPltdKTogU2VxdWVuY2U8VD4ge1xuICAgIGNvbnN0IHNvdXJjZUl0ZXJhYmxlcyA9IHNlcXVlbmNlU291cmNlcyh0aGlzLCAuLi5zb3VyY2VzKTtcbiAgICByZXR1cm4gc2VxdWVuY2VTb3VyY2VzLmxlbmd0aCA9PT0gMCA/IHRoaXMgOiBzZXF1ZW5jZSguLi5zb3VyY2VJdGVyYWJsZXMpO1xuICB9XG5cbiAgLyoqIEBzZWUge0BsaW5rIHRha2V9ICovXG4gIHRha2UoY291bnQ6IG51bWJlcik6IFNlcXVlbmNlPFQ+IHtcbiAgICByZXR1cm4gdGFrZShjb3VudCwgdGhpcyk7XG4gIH1cblxuICAvKiogQHNlZSB7QGxpbmsgZ3JvdXB9ICovXG4gIGdyb3VwPEcgZXh0ZW5kcyBHcm91cFByZWRpY2F0ZXM8VD4+KHByZWRpY2F0ZXM6IEcpOiB7IFtLIGluIGtleW9mIEddOiBHcm91cFZhbHVlPFQsIEdbS10+W10gfSB7XG4gICAgcmV0dXJuIGdyb3VwKHByZWRpY2F0ZXMsIHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgYSBjYWNoZWQsIHJlLWl0ZXJhYmxlIHZpZXcgb2YgdGhpcyBzZXF1ZW5jZS4gQW4gYWxyZWFkeS1jYWNoaW5nXG4gICAqIHNlcXVlbmNlIHJldHVybnMgaXRzZWxmOyBvdGhlcndpc2UgdGhpcyBvbmUtcGFzcyBzZXF1ZW5jZSBpcyB3cmFwcGVkIGluIGFcbiAgICogbmV3IGluc3RhbmNlIHRoYXQgcmV0YWlucyBwdWxsZWQgdmFsdWVzLiBJdGVyYXRlIHRoZSByZXR1cm5lZCBpbnN0YW5jZSwgbm90XG4gICAqIHRoZSBvcmlnaW5hbCwgdG8gYXZvaWQgY29tcGV0aW5nIGZvciB0aGUgc2FtZSBzaW5nbGUtcGFzcyBzb3VyY2UuXG4gICAqL1xuICBjYWNoZSgpOiBTZXF1ZW5jZTxUPiB7XG4gICAgcmV0dXJuIHRoaXMuY2FjaGluZyA/IHRoaXMgOiBuZXcgU2VxdWVuY2VJbXBsKHRoaXMsIFtdKTtcbiAgfVxuXG4gIC8qKiBAc2VlIHtAbGluayBmaW5kfSAqL1xuICBmaW5kPFMgZXh0ZW5kcyBUPihwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gdmFsdWUgaXMgUyk6IFMgfCB1bmRlZmluZWQ7XG4gIGZpbmQocHJlZGljYXRlOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4pOiBUIHwgdW5kZWZpbmVkO1xuICBmaW5kKHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuKTogVCB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIGZpbmQodGhpcywgcHJlZGljYXRlKTtcbiAgfVxuXG4gIC8qKiBAc2VlIHtAbGluayBmaW5kTGFzdH0gKi9cbiAgZmluZExhc3Q8UyBleHRlbmRzIFQ+KHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiB2YWx1ZSBpcyBTKTogUyB8IHVuZGVmaW5lZDtcbiAgZmluZExhc3QocHJlZGljYXRlOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IGJvb2xlYW4pOiBUIHwgdW5kZWZpbmVkO1xuICBmaW5kTGFzdChwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gYm9vbGVhbik6IFQgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiBmaW5kTGFzdCh0aGlzLCBwcmVkaWNhdGUpO1xuICB9XG5cbiAgLyoqIEBzZWUge0BsaW5rIGZpbmRJbmRleH0gKi9cbiAgZmluZEluZGV4KHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuKTogbnVtYmVyIHtcbiAgICByZXR1cm4gZmluZEluZGV4KHRoaXMsIHByZWRpY2F0ZSk7XG4gIH1cblxuICAvKiogQHNlZSB7QGxpbmsgZmluZExhc3RJbmRleH0gKi9cbiAgZmluZExhc3RJbmRleChwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gYm9vbGVhbik6IG51bWJlciB7XG4gICAgcmV0dXJuIGZpbmRMYXN0SW5kZXgodGhpcywgcHJlZGljYXRlKTtcbiAgfVxuXG4gIC8qKiBAc2VlIHtAbGluayBzb21lfSAqL1xuICBzb21lKHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHNvbWUodGhpcywgcHJlZGljYXRlKTtcbiAgfVxuXG4gIC8qKiBAc2VlIHtAbGluayBldmVyeX0gKHRoZSBgUyBleHRlbmRzIFRgIG92ZXJsb2FkIG5hcnJvd3MgYXQgY29tcGlsZSB0aW1lIG9ubHkpLiAqL1xuICBldmVyeTxTIGV4dGVuZHMgVD4ocHJlZGljYXRlOiAodmFsdWU6IFQsIGluZGV4OiBudW1iZXIpID0+IHZhbHVlIGlzIFMpOiB0aGlzIGlzIFNlcXVlbmNlPFM+O1xuICBldmVyeShwcmVkaWNhdGU6ICh2YWx1ZTogVCwgaW5kZXg6IG51bWJlcikgPT4gYm9vbGVhbik6IGJvb2xlYW47XG4gIGV2ZXJ5KHByZWRpY2F0ZTogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiBib29sZWFuKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIGV2ZXJ5KHRoaXMsIHByZWRpY2F0ZSk7XG4gIH1cblxuICAvKiogQHNlZSB7QGxpbmsgZm9yRWFjaH0gKi9cbiAgZm9yRWFjaChjYWxsYmFjazogKHZhbHVlOiBULCBpbmRleDogbnVtYmVyKSA9PiB2b2lkKTogdm9pZCB7XG4gICAgZm9yRWFjaCh0aGlzLCBjYWxsYmFjayk7XG4gIH1cblxuICAvKiogQHNlZSB7QGxpbmsgYXR9ICovXG4gIGF0KGluZGV4OiBudW1iZXIpOiBUIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gYXQoaW5kZXgsIHRoaXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIE1hdGVyaWFsaXplIHRoZSBzZXF1ZW5jZSBpbnRvIGEgbmV3IGFycmF5LiBDb25zdW1lcyBhIHNpbmdsZS1wYXNzIHNvdXJjZTsgYVxuICAgKiBjYWNoZWQsIGV4aGF1c3RlZCBzZXF1ZW5jZSBjb3BpZXMgaXRzIGJ1ZmZlciBkaXJlY3RseS5cbiAgICpcbiAgICogQHNlZSB7QGxpbmsgdG9BcnJheX1cbiAgICovXG4gIHRvQXJyYXkoKTogcmVhZG9ubHkgVFtdIHtcbiAgICBpZiAodGhpcy5jYWNoaW5nICYmIHRoaXMuZXhoYXVzdGVkKSByZXR1cm4gWy4uLnRoaXMuYnVmZmVyIV07XG4gICAgcmV0dXJuIHRvQXJyYXkodGhpcyk7XG4gIH1cbn1cblxuLyoqIFNoYXJlZCBlbXB0eSBzZXF1ZW5jZSBzaW5nbGV0b24sIHJldXNhYmxlIGZvciBhbnkgZWxlbWVudCB0eXBlLiAqL1xuY29uc3QgZW1wdHlTZXF1ZW5jZTogU2VxdWVuY2U8bmV2ZXI+ID0gbmV3IFNlcXVlbmNlSW1wbChbXSwgdW5kZWZpbmVkLCB7XG4gIGV4aGF1c3RlZDogdHJ1ZSxcbn0pO1xuXG4vKipcbiAqIFdyYXAgb25lIG9yIG1vcmUgaXRlcmFibGUgYHNvdXJjZXNgIGluIGEgc2luZ2xlIGxhenkge0BsaW5rIFNlcXVlbmNlfSxcbiAqIGl0ZXJhdGVkIGluIG9yZGVyLiBgbnVsbGAvYHVuZGVmaW5lZGAgc291cmNlcyBhcmUgc2tpcHBlZDsgd2hlbiBub3RoaW5nXG4gKiByZW1haW5zIChldmVyeSBzb3VyY2Ugb21pdHRlZCwgYG51bGxgLCBgdW5kZWZpbmVkYCwgb3IgYW4gZW1wdHkgYXJyYXkgL1xuICogYFNldGAgLyBgTWFwYCksIHtAbGluayBlbXB0eVNlcXVlbmNlfSBpcyByZXR1cm5lZC4gVGhlIHJlc3VsdCBpcyBzaW5nbGUtcGFzc1xuICogLSBjYWxsIGAuY2FjaGUoKWAgdG8gbWFrZSBpdCByZS1pdGVyYWJsZS5cbiAqXG4gKiBBIHtAbGluayBNYXB9IHNvdXJjZSBjb250cmlidXRlcyBpdHMgdmFsdWVzIChzZWUge0BsaW5rIHZhbHVlc30pLCBjb25zaXN0ZW50XG4gKiB3aXRoIHtAbGluayBDb2xsZWN0aW9ufSdzIHZhbHVlLXR5cGVkIGBUYC5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBFbGVtZW50IHR5cGUgb2YgdGhlIHNlcXVlbmNlLlxuICogQHBhcmFtIHNvdXJjZXMgLSBJdGVyYWJsZXMgdG8gY29uY2F0ZW5hdGUsIGluIG9yZGVyIChgTWFwYCBzb3VyY2VzIHVzZSB2YWx1ZXMpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2VxdWVuY2U8VD4oLi4uc291cmNlczogcmVhZG9ubHkgU2VxdWVuY2VTb3VyY2U8VD5bXSk6IFNlcXVlbmNlPFQ+IHtcbiAgLy8gU2tpcCBudWxsaXNoIHNvdXJjZXMgYW5kIGtub3duLWVtcHR5IGNvbGxlY3Rpb25zOyBub3JtYWxpemUgdGhlIHJlc3QgdG9cbiAgLy8gdGhlaXIgdmFsdWVzIHNvIGEgTWFwIGNvbnRyaWJ1dGVzIHZhbHVlcyByYXRoZXIgdGhhbiBba2V5LCB2YWx1ZV0gZW50cmllcy5cbiAgY29uc3Qgc291cmNlSXRlcmFibGVzID0gc2VxdWVuY2VTb3VyY2VzKC4uLnNvdXJjZXMpO1xuICBpZiAoc291cmNlSXRlcmFibGVzLmxlbmd0aCA9PT0gMCkgcmV0dXJuIGVtcHR5U2VxdWVuY2UgYXMgU2VxdWVuY2U8VD47XG4gIC8vIFJldXNlIGFuIGV4aXN0aW5nIHNlcXVlbmNlIGFzLWlzIHJhdGhlciB0aGFuIHJlLXdyYXBwaW5nIGl0LlxuICBpZiAoc291cmNlSXRlcmFibGVzLmxlbmd0aCA9PT0gMSkge1xuICAgIGNvbnN0IG9ubHkgPSBzb3VyY2VJdGVyYWJsZXNbMF0hO1xuICAgIHJldHVybiBvbmx5IGluc3RhbmNlb2YgU2VxdWVuY2VJbXBsID8gKG9ubHkgYXMgU2VxdWVuY2U8VD4pIDogbmV3IFNlcXVlbmNlSW1wbChvbmx5LCB1bmRlZmluZWQpO1xuICB9XG4gIHJldHVybiBuZXcgU2VxdWVuY2VJbXBsKFxuICAgIHtcbiAgICAgICpbU3ltYm9sLml0ZXJhdG9yXSgpIHtcbiAgICAgICAgZm9yIChjb25zdCBzb3VyY2Ugb2Ygc291cmNlSXRlcmFibGVzKSB5aWVsZCogc291cmNlO1xuICAgICAgfSxcbiAgICB9LFxuICAgIHVuZGVmaW5lZCxcbiAgKTtcbn1cblxuLyoqXG4gKiBGbGF0dGVucyBhIG1peCBvZiBzaW5nbGUgaXRlbXMgYW5kIGl0ZXJhYmxlcyBpbnRvIG9uZSBsYXp5IHtAbGluayBHZW5lcmF0b3J9LlxuICpcbiAqIEFyZ3VtZW50cyBhcmUgZW1pdHRlZCBpbiBvcmRlcjogYG51bGxgL2B1bmRlZmluZWRgIGFyZSBza2lwcGVkLCBub24tc3RyaW5nXG4gKiBpdGVyYWJsZXMgKHBlciB7QGxpbmsgaXNDb250YWluZXJ9KSBhcmUgeWllbGRlZCBlbGVtZW50LWJ5LWVsZW1lbnQsIGFuZFxuICogYW55dGhpbmcgZWxzZSAoaW5jbHVkaW5nIHN0cmluZ3MpIGlzIHlpZWxkZWQgYXMgYSBzaW5nbGUgaXRlbS5cbiAqXG4gKiBAdHlwZVBhcmFtIFQgLSBFbGVtZW50IHR5cGUgcHJvZHVjZWQgYnkgdGhlIGdlbmVyYXRvci5cbiAqIEBwYXJhbSBpdGVtcyAtIEl0ZW1zIGFuZC9vciBpdGVyYWJsZXMgdG8gZmxhdHRlbiwgaW4gb3JkZXIuXG4gKiBAcmV0dXJucyBBIGdlbmVyYXRvciBvdmVyIHRoZSBmbGF0dGVuZWQgZWxlbWVudHMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiogZ2VuZXJhdG9yPFQ+KFxuICAuLi5pdGVtczogcmVhZG9ubHkgKFQgfCBJdGVyYWJsZTxUPiB8IG51bGwgfCB1bmRlZmluZWQpW11cbik6IEdlbmVyYXRvcjxUPiB7XG4gIGZvciAoY29uc3QgaXRlbSBvZiBpdGVtcykge1xuICAgIGlmIChpdGVtID09PSBudWxsIHx8IGl0ZW0gPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIGlmIChpc0NvbnRhaW5lcihpdGVtKSkge1xuICAgICAgeWllbGQqIGl0ZW07XG4gICAgfSBlbHNlIHtcbiAgICAgIHlpZWxkIGl0ZW07XG4gICAgfVxuICB9XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gT2JqZWN0IHZhbHVlIGd1YXJkcywgY29lcmNpb25zLCBhbmQgc3RydWN0dXJhbCBlcXVhbGl0eVxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbi8qKiBNaW5pbWFsIHNoYXBlIGZvciBvYmplY3RzIHRoYXQgZXhwb3NlIGFuIG9wdGlvbmFsIGBuYW1lYCAoZS5nLiBBcHBLaXQgcGx1Z2lucykuICovXG5leHBvcnQgaW50ZXJmYWNlIE5hbWVMaWtlIHtcbiAgbmFtZT86IHN0cmluZztcbn1cblxuZXhwb3J0IHR5cGUgTm9uRnVuY3Rpb25LZXlzPFQ+ID0ge1xuICBbSyBpbiBrZXlvZiBUXTogVFtLXSBleHRlbmRzICguLi5hcmdzOiBhbnlbXSkgPT4gYW55ID8gbmV2ZXIgOiBLO1xufVtrZXlvZiBUXTtcblxuLyoqXG4gKiBOYXJyb3cgYHZhbHVlYCB0byBhIHBsYWluIChub24tYXJyYXkpIG9iamVjdC4gVXNlIGFzIGEgdHlwZSBndWFyZFxuICogYmVmb3JlIGluZGV4aW5nIGludG8gLyBtdXRhdGluZyBwYXJzZWQgSlNPTiBzbyB0aGUgYWNjZXNzIGlzXG4gKiB0eXBlLXNhZmUuXG4gKlxuICogQGV4YW1wbGVcbiAqIGlmIChpc1JlY29yZChwYXJzZWQpKSBwYXJzZWQuZm9vID0gMTtcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzUmVjb3JkKHZhbHVlOiB1bmtub3duKTogdmFsdWUgaXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4ge1xuICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm9iamVjdFwiICYmIHZhbHVlICE9PSBudWxsICYmICFBcnJheS5pc0FycmF5KHZhbHVlKTtcbn1cblxuLyoqXG4gKiBDb2VyY2UgYSBsb29zZSBib29sZWFuLWlzaCB2YWx1ZSB0byBhIHJlYWwgYGJvb2xlYW5gLCBvciBgdW5kZWZpbmVkYFxuICogd2hlbiBpdCBjYW4ndCBiZSBpbnRlcnByZXRlZC4gUmVjb2duaXplcyBgdHJ1ZWAvYHRgL2BvbmAvYDFgL2B5ZXNgL2B5YFxuICogYW5kIHRoZWlyIG5lZ2F0aXZlcyAoY2FzZS0gYW5kIHdoaXRlc3BhY2UtaW5zZW5zaXRpdmUgZm9yIHN0cmluZ3MpLCBhc1xuICogd2VsbCBhcyB0aGUgbnVtYmVycyBgMWAgYW5kIGAwYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHRvQm9vbGVhbih2YWx1ZTogdW5rbm93bik6IGJvb2xlYW4gfCB1bmRlZmluZWQge1xuICBpZiAodHlwZW9mIHZhbHVlID09PSBcImJvb2xlYW5cIikge1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfSBlbHNlIGlmICh0eXBlb2YgdmFsdWUgPT09IFwic3RyaW5nXCIpIHtcbiAgICB2YWx1ZSA9IHZhbHVlLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICAgIGlmIChcbiAgICAgIHZhbHVlID09PSBcInRydWVcIiB8fFxuICAgICAgdmFsdWUgPT0gXCJ0XCIgfHxcbiAgICAgIHZhbHVlID09PSBcIm9uXCIgfHxcbiAgICAgIHZhbHVlID09PSBcIjFcIiB8fFxuICAgICAgdmFsdWUgPT09IFwieWVzXCIgfHxcbiAgICAgIHZhbHVlID09PSBcInlcIlxuICAgICkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIGlmIChcbiAgICAgIHZhbHVlID09PSBcImZhbHNlXCIgfHxcbiAgICAgIHZhbHVlID09IFwiZlwiIHx8XG4gICAgICB2YWx1ZSA9PT0gXCJvZmZcIiB8fFxuICAgICAgdmFsdWUgPT09IFwiMFwiIHx8XG4gICAgICB2YWx1ZSA9PT0gXCJub1wiIHx8XG4gICAgICB2YWx1ZSA9PT0gXCJuXCJcbiAgICApIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH0gZWxzZSBpZiAodHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiKSB7XG4gICAgaWYgKHZhbHVlID09PSAxKSByZXR1cm4gdHJ1ZTtcbiAgICBlbHNlIGlmICh2YWx1ZSA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuICB9XG4gIHJldHVybiB1bmRlZmluZWQ7XG59XG5cbi8qKlxuICogU3RydWN0dXJhbCBkZWVwLWVxdWFsaXR5IHdpdGggYW4gb3B0aW9uYWwgY3VzdG9tIGNvbXBhcmF0b3IuXG4gKlxuICoge0BsaW5rIGRlZXBFcXVhbH0gbWlycm9ycyB0aGUgc2VtYW50aWNzIG9mIHRoZSBgZmFzdC1kZWVwLWVxdWFsYFxuICogcGFja2FnZSAoaGFuZGxlZDogbmVzdGVkIHBsYWluIG9iamVjdHMvYXJyYXlzLCBgTWFwYCwgYFNldGAsIGBEYXRlYCxcbiAqIGBSZWdFeHBgLCB0eXBlZCBhcnJheXMsIGBOYU5gLCBhbmQgYCswYC9gLTBgIHRyZWF0ZWQgYXMgZXF1YWwpIGJ1dCBpc1xuICogZGVwZW5kZW5jeS1mcmVlIHNvIGBAZGJ4LXRvb2xzL3NoYXJlZC1jb3JlYCBrZWVwcyBubyBydW50aW1lIGRlcHMuXG4gKlxuICogVGhlIG9wdGlvbmFsIGBjb21wYXJhdG9yYCBzaG9ydC1jaXJjdWl0cyB0aGUgc3RydWN0dXJhbCB3YWxrIGF0IGFueVxuICogbm9kZTogcmV0dXJuIGB0cnVlYC9gZmFsc2VgIHRvIGZvcmNlIHRoZSByZXN1bHQgZm9yIHRoYXQgcGFpciwgb3JcbiAqIGB1bmRlZmluZWRgIHRvIGRlZmVyIHRvIHRoZSBidWlsdC1pbiBjb21wYXJpc29uLiBJdCBpcyBpbnZva2VkIGZvciB0aGVcbiAqIHJvb3QgcGFpciBhbmQgcmVjdXJzaXZlbHkgZm9yIGVhY2ggbmVzdGVkIHBhaXIsIHNvIGEgY2FsbGVyIGNhbiwgZS5nLixcbiAqIGNvbXBhcmUgdHdvIGRvbWFpbiBvYmplY3RzIGJ5IGlkIHdoaWxlIGxldHRpbmcgZXZlcnl0aGluZyBlbHNlIGZhbGxcbiAqIGJhY2sgdG8gc3RydWN0dXJhbCBlcXVhbGl0eS5cbiAqXG4gKiBAZXhhbXBsZVxuICogZGVlcEVxdWFsKHsgYTogMSB9LCB7IGE6IDEgfSk7ICAgICAgICAgICAgICAgICAvLyB0cnVlXG4gKiBkZWVwRXF1YWwoWzEsIDJdLCBbMSwgMl0pOyAgICAgICAgICAgICAgICAgICAgICAvLyB0cnVlXG4gKiBkZWVwRXF1YWwoYSwgYiwgKHgsIHkpID0+XG4gKiAgIGlzRW50aXR5KHgpICYmIGlzRW50aXR5KHkpID8geC5pZCA9PT0geS5pZCA6IHVuZGVmaW5lZCk7XG4gKi9cbmV4cG9ydCB0eXBlIERlZXBFcXVhbENvbXBhcmF0b3IgPSAoYTogdW5rbm93biwgYjogdW5rbm93bikgPT4gYm9vbGVhbiB8IHVuZGVmaW5lZDtcblxuZXhwb3J0IGZ1bmN0aW9uIGRlZXBFcXVhbChhOiB1bmtub3duLCBiOiB1bmtub3duLCBjb21wYXJhdG9yPzogRGVlcEVxdWFsQ29tcGFyYXRvcik6IGJvb2xlYW4ge1xuICBpZiAoY29tcGFyYXRvcikge1xuICAgIGNvbnN0IGRlY2lkZWQgPSBjb21wYXJhdG9yKGEsIGIpO1xuICAgIGlmIChkZWNpZGVkICE9PSB1bmRlZmluZWQpIHJldHVybiBkZWNpZGVkO1xuICB9XG5cbiAgaWYgKGEgPT09IGIpIHJldHVybiB0cnVlO1xuXG4gIGlmICh0eXBlb2YgYSAhPT0gXCJvYmplY3RcIiB8fCBhID09PSBudWxsIHx8IHR5cGVvZiBiICE9PSBcIm9iamVjdFwiIHx8IGIgPT09IG51bGwpIHtcbiAgICAvLyBOYU4gaXMgdGhlIG9ubHkgdmFsdWUgbm90IGVxdWFsIHRvIGl0c2VsZiB1bmRlciBgPT09YC5cbiAgICByZXR1cm4gYSAhPT0gYSAmJiBiICE9PSBiO1xuICB9XG5cbiAgaWYgKGEuY29uc3RydWN0b3IgIT09IGIuY29uc3RydWN0b3IpIHJldHVybiBmYWxzZTtcblxuICBpZiAoQXJyYXkuaXNBcnJheShhKSkge1xuICAgIGNvbnN0IGJBcnIgPSBiIGFzIHVua25vd25bXTtcbiAgICBpZiAoYS5sZW5ndGggIT09IGJBcnIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBhLmxlbmd0aDsgaSsrKSB7XG4gICAgICBpZiAoIWRlZXBFcXVhbChhW2ldLCBiQXJyW2ldLCBjb21wYXJhdG9yKSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChhIGluc3RhbmNlb2YgTWFwKSB7XG4gICAgY29uc3QgYk1hcCA9IGIgYXMgTWFwPHVua25vd24sIHVua25vd24+O1xuICAgIGlmIChhLnNpemUgIT09IGJNYXAuc2l6ZSkgcmV0dXJuIGZhbHNlO1xuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIGEpIHtcbiAgICAgIGlmICghYk1hcC5oYXMoa2V5KSkgcmV0dXJuIGZhbHNlO1xuICAgICAgaWYgKCFkZWVwRXF1YWwodmFsdWUsIGJNYXAuZ2V0KGtleSksIGNvbXBhcmF0b3IpKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgaWYgKGEgaW5zdGFuY2VvZiBTZXQpIHtcbiAgICBjb25zdCBiU2V0ID0gYiBhcyBTZXQ8dW5rbm93bj47XG4gICAgaWYgKGEuc2l6ZSAhPT0gYlNldC5zaXplKSByZXR1cm4gZmFsc2U7XG4gICAgZm9yIChjb25zdCB2YWx1ZSBvZiBhKSB7XG4gICAgICBpZiAoIWJTZXQuaGFzKHZhbHVlKSkgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIGlmIChhIGluc3RhbmNlb2YgRGF0ZSkge1xuICAgIHJldHVybiBhLmdldFRpbWUoKSA9PT0gKGIgYXMgRGF0ZSkuZ2V0VGltZSgpO1xuICB9XG5cbiAgaWYgKGEgaW5zdGFuY2VvZiBSZWdFeHApIHtcbiAgICBjb25zdCBiUmUgPSBiIGFzIFJlZ0V4cDtcbiAgICByZXR1cm4gYS5zb3VyY2UgPT09IGJSZS5zb3VyY2UgJiYgYS5mbGFncyA9PT0gYlJlLmZsYWdzO1xuICB9XG5cbiAgaWYgKEFycmF5QnVmZmVyLmlzVmlldyhhKSAmJiAhKGEgaW5zdGFuY2VvZiBEYXRhVmlldykpIHtcbiAgICBjb25zdCBhQXJyID0gYSBhcyB1bmtub3duIGFzIEFycmF5TGlrZTxudW1iZXI+O1xuICAgIGNvbnN0IGJBcnIgPSBiIGFzIHVua25vd24gYXMgQXJyYXlMaWtlPG51bWJlcj47XG4gICAgaWYgKGFBcnIubGVuZ3RoICE9PSBiQXJyLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgYUFyci5sZW5ndGg7IGkrKykge1xuICAgICAgaWYgKGFBcnJbaV0gIT09IGJBcnJbaV0pIHJldHVybiBmYWxzZTtcbiAgICB9XG4gICAgcmV0dXJuIHRydWU7XG4gIH1cblxuICBjb25zdCBhS2V5cyA9IE9iamVjdC5rZXlzKGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pO1xuICBjb25zdCBiS2V5cyA9IE9iamVjdC5rZXlzKGIgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pO1xuICBpZiAoYUtleXMubGVuZ3RoICE9PSBiS2V5cy5sZW5ndGgpIHJldHVybiBmYWxzZTtcbiAgZm9yIChjb25zdCBrZXkgb2YgYUtleXMpIHtcbiAgICBpZiAoIU9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChiLCBrZXkpKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKFxuICAgICAgIWRlZXBFcXVhbChcbiAgICAgICAgKGEgYXMgUmVjb3JkPHN0cmluZywgdW5rbm93bj4pW2tleV0sXG4gICAgICAgIChiIGFzIFJlY29yZDxzdHJpbmcsIHVua25vd24+KVtrZXldLFxuICAgICAgICBjb21wYXJhdG9yLFxuICAgICAgKVxuICAgICkge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdHJ1ZTtcbn1cbiJdfQ==
|