cdk-nextjs 0.7.5 → 0.7.7
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/.jsii +38 -38
- package/.jsii.tabl.json +1 -1
- package/README.md +12 -3
- package/assets/lambdas/post-deploy/post-deploy.lambda/index.js +31 -13
- package/docs/adapter-runtime.md +1 -1
- package/docs/caching-guide.md +11 -1
- package/docs/harness-coverage.md +11 -9
- package/lib/adapter/adapter.mjs +220 -149
- package/lib/adapter/aws-cache-store.d.ts +242 -7
- package/lib/adapter/aws-cache-store.js +520 -54
- package/lib/adapter/aws-cache-store.test.js +710 -3
- package/lib/adapter/build-outputs.js +23 -1
- package/lib/adapter/build-outputs.test.js +18 -1
- package/lib/adapter/cache-handler.d.ts +4 -3
- package/lib/adapter/cache-handler.js +1 -1
- package/lib/adapter/cache-handler.mjs +552 -91
- package/lib/adapter/cache-handler.test.js +31 -1
- package/lib/adapter/cache-utils.d.ts +68 -2
- package/lib/adapter/cache-utils.js +108 -2
- package/lib/adapter/cache-utils.test.js +45 -1
- package/lib/adapter/init-cache.d.ts +1 -1
- package/lib/adapter/init-cache.js +60 -37
- package/lib/adapter/init-cache.test.js +55 -2
- package/lib/adapter/local-file-cache-handler.d.ts +2 -2
- package/lib/adapter/local-file-cache-handler.js +4 -5
- package/lib/adapter/s3-cache-handler.d.ts +23 -7
- package/lib/adapter/s3-cache-handler.js +63 -27
- package/lib/adapter/s3-cache-handler.test.js +168 -1
- package/lib/adapter/use-cache-common.d.ts +53 -1
- package/lib/adapter/use-cache-common.js +121 -14
- package/lib/adapter/use-cache-common.test.js +138 -1
- package/lib/adapter/use-cache-default-handler.js +36 -6
- package/lib/adapter/use-cache-default-handler.mjs +557 -51
- package/lib/adapter/use-cache-handlers.test.js +247 -7
- package/lib/adapter/use-cache-remote-handler.js +10 -9
- package/lib/adapter/use-cache-remote-handler.mjs +597 -101
- package/lib/lambdas/post-deploy/prune-revalidation-table.d.ts +2 -1
- package/lib/lambdas/post-deploy/prune-revalidation-table.js +35 -13
- package/lib/lambdas/post-deploy/prune-revalidation-table.test.js +19 -1
- package/lib/nextjs-api.js +1 -1
- package/lib/nextjs-build/nextjs-build.d.ts +0 -7
- package/lib/nextjs-build/nextjs-build.js +4 -11
- package/lib/nextjs-build/nextjs-build.test.js +4 -3
- package/lib/nextjs-cache.js +1 -1
- package/lib/nextjs-compute/nextjs-containers.js +1 -1
- package/lib/nextjs-compute/nextjs-functions.js +1 -1
- package/lib/nextjs-distribution.js +1 -1
- package/lib/nextjs-post-deploy.js +1 -1
- package/lib/nextjs-static-assets.js +1 -1
- package/lib/root-constructs/nextjs-base-construct.js +1 -1
- package/lib/root-constructs/nextjs-global-containers.js +1 -1
- package/lib/root-constructs/nextjs-global-functions.js +1 -1
- package/lib/root-constructs/nextjs-regional-containers.js +1 -1
- package/lib/root-constructs/nextjs-regional-functions.js +1 -1
- package/lib/runtime/core.js +18 -4
- package/lib/runtime/core.test.js +17 -1
- package/lib/runtime/image.d.ts +19 -0
- package/lib/runtime/image.js +28 -2
- package/lib/runtime/image.test.js +43 -1
- package/lib/runtime/lambda.mjs +30 -6
- package/lib/runtime/server.mjs +30 -6
- package/lib/runtime/tag-manifest.d.ts +15 -0
- package/lib/runtime/tag-manifest.js +24 -0
- package/lib/runtime/tag-manifest.test.d.ts +1 -0
- package/lib/runtime/tag-manifest.test.js +21 -0
- package/lib/utils/deployment-build-id.d.ts +11 -0
- package/lib/utils/deployment-build-id.js +15 -0
- package/package.json +3 -3
- package/scripts/e2e-harness/README.md +1 -1
|
@@ -1,14 +1,17 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.CacheBucket = exports.TrackedTagMarkers = exports.DEFAULT_MAX_TRACKED_TAGS = exports.MAX_REVALIDATION_LOG_GAP_MS = exports.DEFAULT_TAG_RESYNC_MS = exports.REVALIDATION_LOG_LOOKBACK_MS = exports.RevalidationLog = exports.REVALIDATION_LOG_MAX_PAGES = exports.REVALIDATION_LOG_TTL_MS = exports.TagMarkerTable = exports.DEFAULT_TAG_REFRESH_MS = exports.BATCH_GET_MAX_KEYS = exports.USE_CACHE_KEY_PREFIX = void 0;
|
|
3
|
+
exports.CacheBucket = exports.TrackedTagMarkers = exports.DEFAULT_MAX_TRACKED_TAGS = exports.MAX_REVALIDATION_LOG_GAP_MS = exports.DEFAULT_TAG_RESYNC_MS = exports.REVALIDATION_LOG_LOOKBACK_MS = exports.RevalidationLog = exports.REVALIDATION_LOG_MAX_PAGES = exports.REVALIDATION_LOG_TTL_MS = exports.TagMarkerTable = exports.MAX_TAG_BYTES = exports.MAX_SORT_KEY_BYTES = exports.TAG_REFRESH_GRACE_MS = exports.DEFAULT_TAG_REFRESH_MS = exports.BATCH_GET_MAX_KEYS = exports.USE_CACHE_KEY_PREFIX = void 0;
|
|
4
4
|
exports.resolveAwsCacheConfig = resolveAwsCacheConfig;
|
|
5
5
|
exports.buildS3Key = buildS3Key;
|
|
6
|
+
exports.s3ObjectKey = s3ObjectKey;
|
|
6
7
|
exports.useCacheS3Key = useCacheS3Key;
|
|
7
8
|
exports.markerState = markerState;
|
|
8
9
|
exports.markerClock = markerClock;
|
|
9
10
|
exports.markerFor = markerFor;
|
|
10
11
|
exports.applyMarker = applyMarker;
|
|
11
12
|
exports.markerUpdate = markerUpdate;
|
|
13
|
+
exports.hashedTag = hashedTag;
|
|
14
|
+
exports.sortKeyTag = sortKeyTag;
|
|
12
15
|
exports.mergeMarkers = mergeMarkers;
|
|
13
16
|
/*
|
|
14
17
|
The S3 / DynamoDB plumbing shared by every cdk-nextjs cache handler: the
|
|
@@ -21,9 +24,11 @@ exports.mergeMarkers = mergeMarkers;
|
|
|
21
24
|
kinds of handler, and they must read each other's markers the same way.
|
|
22
25
|
*/
|
|
23
26
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
27
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
24
28
|
const node_path_1 = require("node:path");
|
|
25
29
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
26
30
|
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
31
|
+
const cache_utils_1 = require("./cache-utils");
|
|
27
32
|
/** The configuration from the environment. */
|
|
28
33
|
function resolveAwsCacheConfig() {
|
|
29
34
|
return {
|
|
@@ -41,14 +46,11 @@ function resolveAwsCacheConfig() {
|
|
|
41
46
|
* which is what keeps it disjoint from {@link useCacheS3Key}.
|
|
42
47
|
*/
|
|
43
48
|
function buildS3Key(buildId, cacheKey) {
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
cleanCacheKey = cacheKey.slice(1);
|
|
50
|
-
}
|
|
51
|
-
return (0, node_path_1.join)(buildId, `${cleanCacheKey}.json`);
|
|
49
|
+
return (0, node_path_1.join)(buildId, (0, cache_utils_1.cacheKeyFileName)(cacheKey));
|
|
50
|
+
}
|
|
51
|
+
/** `{buildId}/` + {@link cacheObjectName}: the S3 object an entry is stored in. */
|
|
52
|
+
function s3ObjectKey(buildId, cacheKey) {
|
|
53
|
+
return (0, node_path_1.join)(buildId, (0, cache_utils_1.cacheObjectName)(cacheKey));
|
|
52
54
|
}
|
|
53
55
|
/**
|
|
54
56
|
* The folder under the build prefix that `'use cache'` entries are stored in.
|
|
@@ -61,8 +63,9 @@ exports.USE_CACHE_KEY_PREFIX = "_use-cache";
|
|
|
61
63
|
* Hashed because a `'use cache'` key is the serialized arguments of the call and
|
|
62
64
|
* has no length limit, where an S3 key stops at 1024 bytes. The `.entry` suffix
|
|
63
65
|
* rather than `.json` is what makes a collision with the incremental cache
|
|
64
|
-
* impossible rather than unlikely: every
|
|
65
|
-
* `.json`, including one for a route that happens to be named
|
|
66
|
+
* impossible rather than unlikely: every object {@link s3ObjectKey} names ends
|
|
67
|
+
* in `.json` or `.long`, including one for a route that happens to be named
|
|
68
|
+
* `/_use-cache/…`.
|
|
66
69
|
* Still under the build prefix, so post-deploy pruning drops them with the build.
|
|
67
70
|
*/
|
|
68
71
|
function useCacheS3Key(buildId, keyHash) {
|
|
@@ -162,9 +165,40 @@ exports.BATCH_GET_MAX_KEYS = 100;
|
|
|
162
165
|
* revalidation log, the reads scale with instances instead of requests or tags.
|
|
163
166
|
*/
|
|
164
167
|
exports.DEFAULT_TAG_REFRESH_MS = 1000;
|
|
168
|
+
/**
|
|
169
|
+
* How far past `refreshIntervalMs` the last refresh may have settled before a
|
|
170
|
+
* `'use cache'` request waits for the next one (see
|
|
171
|
+
* {@link TrackedTagMarkers.behind}). An instance serving steady traffic stays
|
|
172
|
+
* inside it; one that sat idle, or frozen between Lambda invocations, does not.
|
|
173
|
+
*/
|
|
174
|
+
exports.TAG_REFRESH_GRACE_MS = 1000;
|
|
175
|
+
/** DynamoDB's limit on a sort key, in UTF-8 bytes. */
|
|
176
|
+
exports.MAX_SORT_KEY_BYTES = 1024;
|
|
177
|
+
/**
|
|
178
|
+
* `#<sha256(tag)>`, standing in for a tag in a sort key it would push past
|
|
179
|
+
* {@link MAX_SORT_KEY_BYTES}. Next.js caps the tags an app names, but not an
|
|
180
|
+
* implicit `_N_T_/…` tag, which is as long as its path, and a rejected write
|
|
181
|
+
* left `revalidatePath` on a long path recorded nowhere.
|
|
182
|
+
*/
|
|
183
|
+
function hashedTag(tag) {
|
|
184
|
+
return `#${(0, cache_utils_1.sha256Hex)(tag)}`;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* The longest tag a sort key spells out; past it, {@link sortKeyTag} hashes
|
|
188
|
+
* it. One cap for every row the tag is in, so a row's writer and reader agree
|
|
189
|
+
* without each working out what else shares its key. It leaves room for the
|
|
190
|
+
* most any row puts beside the tag: a mapping row's `#<buildId>/#<sha256>`,
|
|
191
|
+
* with the build ID capped at `MAX_BUILD_ID_BYTES`.
|
|
192
|
+
*/
|
|
193
|
+
exports.MAX_TAG_BYTES = 768;
|
|
194
|
+
/** `tag` as a sort key spells it: itself, or {@link hashedTag} past {@link MAX_TAG_BYTES}. */
|
|
195
|
+
function sortKeyTag(tag) {
|
|
196
|
+
return Buffer.byteLength(tag) <= exports.MAX_TAG_BYTES ? tag : hashedTag(tag);
|
|
197
|
+
}
|
|
165
198
|
/**
|
|
166
199
|
* The bare-tag marker rows of the revalidation table (`pk = buildId`,
|
|
167
|
-
* `sk = tag
|
|
200
|
+
* `sk = tag`, or {@link hashedTag} past {@link MAX_TAG_BYTES}), which record when a tag
|
|
201
|
+
* was last revalidated and how.
|
|
168
202
|
*
|
|
169
203
|
* The table also holds the incremental cache's `tag#s3Key` mapping rows, which
|
|
170
204
|
* are its own business and stay in `S3CacheHandler`: only the markers mean the
|
|
@@ -192,7 +226,7 @@ class TagMarkerTable {
|
|
|
192
226
|
TableName: this.tableName,
|
|
193
227
|
Key: {
|
|
194
228
|
pk: { S: this.buildId },
|
|
195
|
-
sk: { S: tag },
|
|
229
|
+
sk: { S: sortKeyTag(tag) },
|
|
196
230
|
},
|
|
197
231
|
...markerUpdate(now, durations),
|
|
198
232
|
ReturnValues: "ALL_NEW",
|
|
@@ -211,9 +245,11 @@ class TagMarkerTable {
|
|
|
211
245
|
const unique = Array.from(new Set(tags));
|
|
212
246
|
const markers = new Map();
|
|
213
247
|
for (let i = 0; i < unique.length; i += exports.BATCH_GET_MAX_KEYS) {
|
|
214
|
-
|
|
248
|
+
// A hashed sort key names no tag, so each row is matched back by key.
|
|
249
|
+
const tagBySk = new Map(unique
|
|
215
250
|
.slice(i, i + exports.BATCH_GET_MAX_KEYS)
|
|
216
|
-
.map((tag) => (
|
|
251
|
+
.map((tag) => [sortKeyTag(tag), tag]));
|
|
252
|
+
let keys = Array.from(tagBySk.keys(), (sk) => ({ pk: { S: buildId }, sk: { S: sk } }));
|
|
217
253
|
// `UnprocessedKeys` is DynamoDB declining part of the batch under load;
|
|
218
254
|
// a marker left unread is a revalidation missed, so it is asked again.
|
|
219
255
|
for (let attempt = 0; keys?.length && attempt < 3; attempt++) {
|
|
@@ -226,7 +262,7 @@ class TagMarkerTable {
|
|
|
226
262
|
},
|
|
227
263
|
}));
|
|
228
264
|
for (const item of response.Responses?.[tableName] ?? []) {
|
|
229
|
-
const tag = item.sk?.S;
|
|
265
|
+
const tag = tagBySk.get(item.sk?.S ?? "");
|
|
230
266
|
if (tag !== undefined) {
|
|
231
267
|
markers.set(tag, markerOf(item));
|
|
232
268
|
}
|
|
@@ -257,7 +293,8 @@ const LOG_SK_DIGITS = 15;
|
|
|
257
293
|
/**
|
|
258
294
|
* The revalidation log: one row per tag revalidation (`pk = <buildId>#log`,
|
|
259
295
|
* `sk = <Date.now(), zero-padded>#<tag>`), which expires after
|
|
260
|
-
* {@link REVALIDATION_LOG_TTL_MS}.
|
|
296
|
+
* {@link REVALIDATION_LOG_TTL_MS}. A tag past {@link MAX_TAG_BYTES} is
|
|
297
|
+
* {@link hashedTag} there, and spelled out in the row's `longTag` instead.
|
|
261
298
|
*
|
|
262
299
|
* The marker rows stay the source of truth. The log exists so an instance
|
|
263
300
|
* can ask "what was revalidated since I last looked?" in one `Query`, instead
|
|
@@ -288,11 +325,13 @@ class RevalidationLog {
|
|
|
288
325
|
* to {@link LOG_PUT_ATTEMPTS} times.
|
|
289
326
|
*/
|
|
290
327
|
async put(tag, at, marker) {
|
|
328
|
+
const skTag = sortKeyTag(tag);
|
|
291
329
|
for (let attempt = 1;; attempt++) {
|
|
292
330
|
const item = {
|
|
293
331
|
pk: { S: this.pk },
|
|
294
|
-
sk: { S: `${logSkPrefix(at)}#${
|
|
332
|
+
sk: { S: `${logSkPrefix(at)}#${skTag}` },
|
|
295
333
|
ttl: { N: String(Math.ceil((at + exports.REVALIDATION_LOG_TTL_MS) / 1000)) },
|
|
334
|
+
...(skTag !== tag && { longTag: { S: tag } }),
|
|
296
335
|
};
|
|
297
336
|
for (const field of MARKER_FIELDS) {
|
|
298
337
|
const value = marker[field];
|
|
@@ -337,7 +376,7 @@ class RevalidationLog {
|
|
|
337
376
|
":pk": { S: this.pk },
|
|
338
377
|
":since": { S: logSkPrefix(Math.max(0, since)) },
|
|
339
378
|
},
|
|
340
|
-
ProjectionExpression: "sk, revalidatedAt, staleAt, expiredAt",
|
|
379
|
+
ProjectionExpression: "sk, longTag, revalidatedAt, staleAt, expiredAt",
|
|
341
380
|
ExclusiveStartKey: startKey,
|
|
342
381
|
}));
|
|
343
382
|
for (const item of response.Items ?? []) {
|
|
@@ -350,7 +389,7 @@ class RevalidationLog {
|
|
|
350
389
|
rows.push({
|
|
351
390
|
sk,
|
|
352
391
|
at: Number(sk.slice(0, LOG_SK_DIGITS)),
|
|
353
|
-
tag: sk.slice(LOG_SK_DIGITS + 1),
|
|
392
|
+
tag: item.longTag?.S ?? sk.slice(LOG_SK_DIGITS + 1),
|
|
354
393
|
marker: markerOf(item),
|
|
355
394
|
});
|
|
356
395
|
}
|
|
@@ -433,15 +472,19 @@ exports.DEFAULT_MAX_TRACKED_TAGS = 10_000;
|
|
|
433
472
|
* The cost is bounded per instance, not per request:
|
|
434
473
|
* - {@link ensure} reads a tag's marker the first time it is needed and not
|
|
435
474
|
* again until it is evicted, so a tag costs one read per instance, not one
|
|
436
|
-
* per request.
|
|
475
|
+
* per request. An entry created since {@link completeSince} needs no read
|
|
476
|
+
* at all.
|
|
437
477
|
* - {@link refresh}, at most once per `refreshIntervalMs`, sends one `Query`
|
|
438
478
|
* for the log rows written since the last one, and applies those of tags
|
|
439
479
|
* this instance tracks. Concurrent callers share it. Alongside, it re-reads
|
|
440
480
|
* the markers of up to {@link BATCH_GET_MAX_KEYS} tags not read for
|
|
441
481
|
* {@link DEFAULT_TAG_RESYNC_MS}, in one `BatchGetItem`.
|
|
442
482
|
* A revalidation on another instance is therefore seen within
|
|
443
|
-
* `refreshIntervalMs` (plus the query itself)
|
|
444
|
-
*
|
|
483
|
+
* `refreshIntervalMs` (plus the query itself) - by `'use cache'`, from the
|
|
484
|
+
* first request after the query returns, since its `refreshTags` does not wait
|
|
485
|
+
* for it (see `tagMethods`) unless the instance is {@link behind}, which the
|
|
486
|
+
* runtime settles before a page render starts ({@link catchUp}). The instance
|
|
487
|
+
* that ran it applies it itself, at once, with {@link set}.
|
|
445
488
|
*/
|
|
446
489
|
class TrackedTagMarkers {
|
|
447
490
|
markers;
|
|
@@ -467,10 +510,64 @@ class TrackedTagMarkers {
|
|
|
467
510
|
* result rather than dropped.
|
|
468
511
|
*/
|
|
469
512
|
pendingRows = new Map();
|
|
513
|
+
/**
|
|
514
|
+
* Log rows for tags not tracked and not being read, merged by tag, oldest
|
|
515
|
+
* first: what the log has said about them since {@link completeSince}. Taken
|
|
516
|
+
* into a tag's marker when it is read or written.
|
|
517
|
+
*/
|
|
518
|
+
logOnly = new Map();
|
|
519
|
+
/** See {@link completeSince}. */
|
|
520
|
+
floor;
|
|
521
|
+
/**
|
|
522
|
+
* The future `expiredAt`s of markers dropped since, as `[from, to]`, in
|
|
523
|
+
* order: once `from` is past, {@link completeSince} moves to `to`, and not
|
|
524
|
+
* before, since only then does it expire anything. `from` and `to` are the
|
|
525
|
+
* same until spans are merged for space ({@link laterFloor}).
|
|
526
|
+
*/
|
|
527
|
+
laterFloors = [];
|
|
528
|
+
/** The in-memory entry stores judged by {@link completeSince}. */
|
|
529
|
+
entryStores = [];
|
|
530
|
+
/** How many times {@link forget} ran: a read started before one is made again. */
|
|
531
|
+
forgotten = 0;
|
|
470
532
|
/** Tracked tags whose read failed, for the next refresh to read again. */
|
|
471
533
|
unread = new Set();
|
|
534
|
+
/**
|
|
535
|
+
* Set inside a page render {@link catchUp} let go, for that render alone.
|
|
536
|
+
* See {@link behindInRender}.
|
|
537
|
+
*/
|
|
538
|
+
caughtUpRender = new node_async_hooks_1.AsyncLocalStorage();
|
|
539
|
+
/** When `sync` last scanned the entry stores ({@link oldestEntry}). */
|
|
540
|
+
lastEntryScan = -Infinity;
|
|
541
|
+
/**
|
|
542
|
+
* No `logOnly` row is known by it or earlier, so a {@link pruneLogged}
|
|
543
|
+
* against it or earlier drops nothing: a marker is only ever known by later,
|
|
544
|
+
* as its `expiredAt` passes.
|
|
545
|
+
*/
|
|
546
|
+
prunedAgainst = -Infinity;
|
|
547
|
+
/** When the last refresh started, or was skipped. */
|
|
472
548
|
lastRefresh = -Infinity;
|
|
549
|
+
/**
|
|
550
|
+
* The refresh in flight. One left open across a freeze comes back after the
|
|
551
|
+
* thaw with what it read before, so {@link refresh} waits for it and then
|
|
552
|
+
* for a fresh one, rather than the runtime waiting for it before the freeze:
|
|
553
|
+
* that would bill every Lambda invocation for the query's tail.
|
|
554
|
+
*/
|
|
473
555
|
refreshing;
|
|
556
|
+
/**
|
|
557
|
+
* When {@link refreshing} last showed the process running: a timer ticks
|
|
558
|
+
* while it is in flight, and a tick that comes late, or none at all, means
|
|
559
|
+
* the process was paused - frozen - since it started.
|
|
560
|
+
*/
|
|
561
|
+
lastTick = -Infinity;
|
|
562
|
+
/** Whether a tick came late since {@link refreshing} started. */
|
|
563
|
+
pausedWhileRefreshing = false;
|
|
564
|
+
ticker;
|
|
565
|
+
canFreeze;
|
|
566
|
+
/**
|
|
567
|
+
* When the last refresh settled, either way, unless it spanned a pause: what
|
|
568
|
+
* it knows is from then. See {@link behind}.
|
|
569
|
+
*/
|
|
570
|
+
settledAt;
|
|
474
571
|
/**
|
|
475
572
|
* Where the next log query starts (`clock()`): the last successful one's
|
|
476
573
|
* start, less {@link REVALIDATION_LOG_LOOKBACK_MS}.
|
|
@@ -494,22 +591,70 @@ class TrackedTagMarkers {
|
|
|
494
591
|
this.clock = options.clock ?? (() => Date.now());
|
|
495
592
|
this.random = options.random ?? Math.random;
|
|
496
593
|
this.debug = options.debug ?? (() => { });
|
|
594
|
+
this.canFreeze = options.canFreeze ?? false;
|
|
497
595
|
// Nothing is tracked yet, so nothing before this can be missed: every tag
|
|
498
596
|
// is read from its marker the first time it is needed.
|
|
499
597
|
const at = this.clock();
|
|
500
598
|
this.cursor = at - exports.REVALIDATION_LOG_LOOKBACK_MS;
|
|
501
599
|
this.lastLogRead = at;
|
|
600
|
+
this.settledAt = at;
|
|
601
|
+
this.floor = markerClock();
|
|
502
602
|
}
|
|
503
603
|
/** `tag`'s marker as this instance knows it, if it tracks `tag`. */
|
|
504
604
|
get(tag) {
|
|
505
605
|
return this.tags.get(tag);
|
|
506
606
|
}
|
|
607
|
+
/**
|
|
608
|
+
* Since when (`markerClock()`) this instance knows of every revalidation of
|
|
609
|
+
* every tag, tracked or not: tracked ones from their markers and the log,
|
|
610
|
+
* the others from the log alone (`logOnly`). So an entry created at or after
|
|
611
|
+
* it can be judged by {@link state} and {@link expiration} without
|
|
612
|
+
* {@link ensure} reading anything - which matters inside a `'use cache'`
|
|
613
|
+
* lookup, where Next.js waits for the answer and a read pushes the entry out
|
|
614
|
+
* of the static stage of a staged render.
|
|
615
|
+
*
|
|
616
|
+
* Starts at construction: the log is followed from before it. Moves to now
|
|
617
|
+
* when the tracked markers are forgotten, and past the revalidations of
|
|
618
|
+
* whatever else it lets go of - a marker evicted for space, a log row
|
|
619
|
+
* pruned - which are no longer known: to its `expiredAt` only once that is
|
|
620
|
+
* past, since a profile's `expire` can be a year out, and moving there at
|
|
621
|
+
* once would turn the read-free path off for the instance's life.
|
|
622
|
+
*
|
|
623
|
+
* A row is pruned only once it is no later than every entry held, so that
|
|
624
|
+
* costs those entries nothing. An entry stored afterwards with an older
|
|
625
|
+
* `timestamp` - Next.js stamps the start of its generation, which can
|
|
626
|
+
* outlast a lookback - is older than this too, and is read first.
|
|
627
|
+
*
|
|
628
|
+
* It does not cover a revalidation older than the log's first lookback
|
|
629
|
+
* whose `expiredAt` is still to come, which would expire an entry created
|
|
630
|
+
* after it. So the `'use cache'` handler reads an entry's tags in the
|
|
631
|
+
* background as it stores it.
|
|
632
|
+
*/
|
|
633
|
+
get completeSince() {
|
|
634
|
+
const at = markerClock();
|
|
635
|
+
while (this.laterFloors.length > 0 && this.laterFloors[0][0] <= at) {
|
|
636
|
+
this.floor = Math.max(this.floor, this.laterFloors.shift()[1]);
|
|
637
|
+
}
|
|
638
|
+
return this.floor;
|
|
639
|
+
}
|
|
640
|
+
/**
|
|
641
|
+
* Register an in-memory store whose entries are judged by
|
|
642
|
+
* {@link completeSince}, by the `timestamp` of the oldest entry it holds:
|
|
643
|
+
* `logOnly` keeps the rows that could still apply to one of them, and no
|
|
644
|
+
* others. With none registered it keeps nothing. Asked with `scan` false,
|
|
645
|
+
* `oldestTimestamp` may answer early, but never late, without a scan.
|
|
646
|
+
*/
|
|
647
|
+
judgeEntriesOf(oldestTimestamp, holdsAny = () => oldestTimestamp(false) < Infinity) {
|
|
648
|
+
this.entryStores.push({ oldestTimestamp, holdsAny });
|
|
649
|
+
}
|
|
507
650
|
/**
|
|
508
651
|
* Track `tag` with `marker`: what this instance just wrote, which it knows
|
|
509
652
|
* without reading it back.
|
|
510
653
|
*/
|
|
511
654
|
set(tag, marker) {
|
|
512
|
-
this.
|
|
655
|
+
const logged = this.logOnly.get(tag);
|
|
656
|
+
this.logOnly.delete(tag);
|
|
657
|
+
this.remember(tag, mergeMarkers(marker, logged));
|
|
513
658
|
this.known(tag, this.clock());
|
|
514
659
|
}
|
|
515
660
|
/**
|
|
@@ -561,31 +706,117 @@ class TrackedTagMarkers {
|
|
|
561
706
|
const waits = [];
|
|
562
707
|
const unread = [];
|
|
563
708
|
for (const tag of new Set(tags)) {
|
|
709
|
+
// Tracked first: a tracked tag in `reading` is only being re-read in
|
|
710
|
+
// the background (`sync`), which nothing needs to wait for.
|
|
564
711
|
const inFlight = this.reading.get(tag);
|
|
565
|
-
if (
|
|
566
|
-
waits.push(inFlight);
|
|
567
|
-
}
|
|
568
|
-
else if (this.tags.has(tag)) {
|
|
712
|
+
if (this.tags.has(tag)) {
|
|
569
713
|
this.touch(tag);
|
|
570
714
|
}
|
|
715
|
+
else if (inFlight) {
|
|
716
|
+
waits.push(inFlight);
|
|
717
|
+
}
|
|
571
718
|
else {
|
|
572
719
|
unread.push(tag);
|
|
573
720
|
}
|
|
574
721
|
}
|
|
575
722
|
if (unread.length > 0) {
|
|
576
|
-
|
|
577
|
-
const read = this.readInto(unread).then(() => {
|
|
578
|
-
for (const tag of unread) {
|
|
579
|
-
this.reading.delete(tag);
|
|
580
|
-
}
|
|
581
|
-
});
|
|
582
|
-
for (const tag of unread) {
|
|
583
|
-
this.reading.set(tag, read);
|
|
584
|
-
}
|
|
585
|
-
waits.push(read);
|
|
723
|
+
waits.push(this.startRead(unread));
|
|
586
724
|
}
|
|
587
725
|
await Promise.all(waits);
|
|
588
726
|
}
|
|
727
|
+
/**
|
|
728
|
+
* {@link readInto} `tags`, as the read of each that whoever needs one of
|
|
729
|
+
* them next waits on ({@link reading}). Never rejects: a failed read leaves
|
|
730
|
+
* the tags tracked.
|
|
731
|
+
*/
|
|
732
|
+
startRead(tags) {
|
|
733
|
+
const read = this.readInto(tags).then(() => {
|
|
734
|
+
for (const tag of tags) {
|
|
735
|
+
this.reading.delete(tag);
|
|
736
|
+
}
|
|
737
|
+
});
|
|
738
|
+
for (const tag of tags) {
|
|
739
|
+
this.reading.set(tag, read);
|
|
740
|
+
}
|
|
741
|
+
return read;
|
|
742
|
+
}
|
|
743
|
+
/**
|
|
744
|
+
* Whether the last refresh settled more than `refreshIntervalMs` plus
|
|
745
|
+
* {@link TAG_REFRESH_GRACE_MS} ago - one that spanned a freeze counts from
|
|
746
|
+
* when it started: after the instance sat idle or frozen - or always, with
|
|
747
|
+
* a `refreshIntervalMs` of `0`. Answering from what it knows then could
|
|
748
|
+
* serve an entry revalidated elsewhere since, however long ago that was, so
|
|
749
|
+
* `refreshTags` waits for the refresh, and the runtime waits for it before
|
|
750
|
+
* a page render starts ({@link catchUp}).
|
|
751
|
+
*
|
|
752
|
+
* From when it settled, not when it started, so a slow query the runtime
|
|
753
|
+
* waited for before the render does not leave the instance behind inside
|
|
754
|
+
* it. A failed one counts too, so one request does not wait for two: the
|
|
755
|
+
* same "assume the entry is valid" a failed read answers with, until the
|
|
756
|
+
* next refresh, at most the interval and the grace later.
|
|
757
|
+
*/
|
|
758
|
+
get behind() {
|
|
759
|
+
return (this.log !== undefined &&
|
|
760
|
+
// `0` asks before every check, so every check waits for the answer.
|
|
761
|
+
(this.refreshIntervalMs === 0 || this.overdue(this.settledAt)));
|
|
762
|
+
}
|
|
763
|
+
/**
|
|
764
|
+
* {@link behind}, as `refreshTags` asks it: never inside a page's render
|
|
765
|
+
* {@link catchUp} caught up, since the runtime settled it for that request
|
|
766
|
+
* before the render started, and a wait inside a `'use cache'` lookup is
|
|
767
|
+
* what it settled it to avoid - a render crossing the line partway through
|
|
768
|
+
* would otherwise wait after all. So a revalidation elsewhere can go unseen
|
|
769
|
+
* for a render's duration on top of the usual window.
|
|
770
|
+
*
|
|
771
|
+
* A route handler, which no catch-up precedes, waits at the plain line.
|
|
772
|
+
*/
|
|
773
|
+
get behindInRender() {
|
|
774
|
+
return this.refreshIntervalMs !== 0 && this.caughtUpRender.getStore()
|
|
775
|
+
? false
|
|
776
|
+
: this.behind;
|
|
777
|
+
}
|
|
778
|
+
/**
|
|
779
|
+
* Whether a registered store ({@link judgeEntriesOf}) holds any entry: one
|
|
780
|
+
* a refresh could expire. With none there is nothing to wait for even when
|
|
781
|
+
* the instance is {@link behind}, since whatever is stored from here on is
|
|
782
|
+
* newer than what the log would say - which covers the first `'use cache'`
|
|
783
|
+
* call of a process, which creates the handler inside the render.
|
|
784
|
+
*/
|
|
785
|
+
get holdsEntries() {
|
|
786
|
+
return this.entryStores.some((store) => store.holdsAny());
|
|
787
|
+
}
|
|
788
|
+
/**
|
|
789
|
+
* {@link refresh}, waited for when the instance is {@link behind}. The
|
|
790
|
+
* runtime calls it before handing a page request to Next.js, outside the
|
|
791
|
+
* staged render whose static stage a wait inside a `'use cache'` lookup
|
|
792
|
+
* would cut short. Only for the `'use cache'` handler's entries
|
|
793
|
+
* ({@link judgeEntriesOf}): the other caches wait for the refresh where they
|
|
794
|
+
* read anyway. Not with a `refreshIntervalMs` of `0` either, where
|
|
795
|
+
* `refreshTags` asks again regardless. Then `render`, marked as caught up
|
|
796
|
+
* for ({@link behindInRender}). Rejects only as `render` does.
|
|
797
|
+
*/
|
|
798
|
+
async catchUp(render) {
|
|
799
|
+
const log = (error) => console.error("Error refreshing cache tags:", error);
|
|
800
|
+
if (this.refreshIntervalMs > 0 && this.behind) {
|
|
801
|
+
if (!this.holdsEntries) {
|
|
802
|
+
// Not caught up, so no grace: an entry stored meanwhile, by another
|
|
803
|
+
// request, makes the render's lookups wait at the plain line.
|
|
804
|
+
return render();
|
|
805
|
+
}
|
|
806
|
+
await this.refresh().catch(log);
|
|
807
|
+
}
|
|
808
|
+
else if (this.refreshIntervalMs > 0) {
|
|
809
|
+
// Started, not waited for, as `refreshTags` would: a page that reads
|
|
810
|
+
// no cache keeps the instance current too, rather than falling behind
|
|
811
|
+
// and making a later request wait.
|
|
812
|
+
void this.refresh().catch(log);
|
|
813
|
+
}
|
|
814
|
+
return this.caughtUpRender.run(true, render);
|
|
815
|
+
}
|
|
816
|
+
/** Whether `at` is more than the interval and the grace ago. */
|
|
817
|
+
overdue(at) {
|
|
818
|
+
return this.clock() - at > this.refreshIntervalMs + exports.TAG_REFRESH_GRACE_MS;
|
|
819
|
+
}
|
|
589
820
|
/**
|
|
590
821
|
* Catch up on revalidations other instances ran, at most once per
|
|
591
822
|
* `refreshIntervalMs`. See {@link TrackedTagMarkers} for the cost.
|
|
@@ -596,6 +827,12 @@ class TrackedTagMarkers {
|
|
|
596
827
|
return;
|
|
597
828
|
}
|
|
598
829
|
if (this.refreshing) {
|
|
830
|
+
// One started before a freeze read the log as it was then, and says
|
|
831
|
+
// nothing of what ran meanwhile: an instance behind waits for a fresh
|
|
832
|
+
// one, after it. One that is merely slow is as fresh as any.
|
|
833
|
+
if (this.behind && this.pausedSinceRefreshStarted()) {
|
|
834
|
+
return this.refreshing.then(() => this.refresh());
|
|
835
|
+
}
|
|
599
836
|
return this.refreshing;
|
|
600
837
|
}
|
|
601
838
|
const at = this.clock();
|
|
@@ -604,15 +841,55 @@ class TrackedTagMarkers {
|
|
|
604
841
|
}
|
|
605
842
|
this.lastRefresh = at;
|
|
606
843
|
// Whatever gets tracked before the next refresh is read from its marker,
|
|
607
|
-
// so there is nothing to catch up on yet
|
|
608
|
-
|
|
844
|
+
// so there is nothing to catch up on yet - unless an entry is judged by
|
|
845
|
+
// `completeSince`, which relies on the log for every tag. Even with none
|
|
846
|
+
// held: a row let go of then moves `completeSince` past it, for an entry
|
|
847
|
+
// whose generation started before that revalidation and that is stored
|
|
848
|
+
// after it.
|
|
849
|
+
if (this.tags.size === 0 && this.entryStores.length === 0) {
|
|
609
850
|
return;
|
|
610
851
|
}
|
|
852
|
+
this.startTicking();
|
|
611
853
|
this.refreshing = this.sync(at, log).finally(() => {
|
|
854
|
+
// One that spanned a pause knows the log as of its start at best. So
|
|
855
|
+
// does one that only looked paused, its event loop held up: it counts
|
|
856
|
+
// as no older than its start, as if it had not settled since.
|
|
857
|
+
this.settledAt = Math.max(this.settledAt, this.pausedSinceRefreshStarted() ? this.lastRefresh : this.clock());
|
|
858
|
+
this.stopTicking();
|
|
612
859
|
this.refreshing = undefined;
|
|
613
860
|
});
|
|
614
861
|
return this.refreshing;
|
|
615
862
|
}
|
|
863
|
+
startTicking() {
|
|
864
|
+
if (!this.canFreeze) {
|
|
865
|
+
return;
|
|
866
|
+
}
|
|
867
|
+
this.lastTick = this.clock();
|
|
868
|
+
this.pausedWhileRefreshing = false;
|
|
869
|
+
this.ticker = setInterval(() => {
|
|
870
|
+
const at = this.clock();
|
|
871
|
+
if (at - this.lastTick > REFRESH_PAUSE_MS) {
|
|
872
|
+
this.pausedWhileRefreshing = true;
|
|
873
|
+
}
|
|
874
|
+
this.lastTick = at;
|
|
875
|
+
}, REFRESH_TICK_MS);
|
|
876
|
+
// Never what keeps a process alive.
|
|
877
|
+
this.ticker.unref?.();
|
|
878
|
+
}
|
|
879
|
+
stopTicking() {
|
|
880
|
+
clearInterval(this.ticker);
|
|
881
|
+
this.ticker = undefined;
|
|
882
|
+
}
|
|
883
|
+
/**
|
|
884
|
+
* Whether the process was paused since {@link refreshing} started: a tick
|
|
885
|
+
* came late, or the next one is overdue (after a thaw, a request can run
|
|
886
|
+
* before the timer does).
|
|
887
|
+
*/
|
|
888
|
+
pausedSinceRefreshStarted() {
|
|
889
|
+
return (this.canFreeze &&
|
|
890
|
+
(this.pausedWhileRefreshing ||
|
|
891
|
+
this.clock() - this.lastTick > REFRESH_PAUSE_MS));
|
|
892
|
+
}
|
|
616
893
|
/**
|
|
617
894
|
* Record a revalidation of `tags`: here at once, and in the revalidation
|
|
618
895
|
* table for every other instance - the marker row plus a log row per tag.
|
|
@@ -650,7 +927,7 @@ class TrackedTagMarkers {
|
|
|
650
927
|
const at = markerClock();
|
|
651
928
|
let state = "fresh";
|
|
652
929
|
for (const tag of tags) {
|
|
653
|
-
const marker = this.
|
|
930
|
+
const marker = this.knownMarker(tag);
|
|
654
931
|
if (!marker) {
|
|
655
932
|
continue;
|
|
656
933
|
}
|
|
@@ -674,7 +951,7 @@ class TrackedTagMarkers {
|
|
|
674
951
|
const at = markerClock();
|
|
675
952
|
let latest = 0;
|
|
676
953
|
for (const tag of tags) {
|
|
677
|
-
const marker = this.
|
|
954
|
+
const marker = this.knownMarker(tag);
|
|
678
955
|
if (!marker) {
|
|
679
956
|
continue;
|
|
680
957
|
}
|
|
@@ -756,13 +1033,17 @@ class TrackedTagMarkers {
|
|
|
756
1033
|
this.forget(at, "the revalidation log may not cover the gap since it was last read");
|
|
757
1034
|
return;
|
|
758
1035
|
}
|
|
759
|
-
|
|
760
|
-
|
|
761
|
-
|
|
762
|
-
|
|
763
|
-
|
|
764
|
-
this.
|
|
765
|
-
|
|
1036
|
+
// The rolling re-read runs alongside, not waited for: catching up needs
|
|
1037
|
+
// only the log, and a throttled `BatchGetItem` should not hold the
|
|
1038
|
+
// request `catchUp` makes wait. A forget meanwhile reads it again.
|
|
1039
|
+
const due = this.due(at);
|
|
1040
|
+
if (due.length > 0) {
|
|
1041
|
+
void this.startRead(due);
|
|
1042
|
+
}
|
|
1043
|
+
const result = await log.query(this.cursor).catch((error) => {
|
|
1044
|
+
console.error("Error reading tag revalidation log:", error);
|
|
1045
|
+
return undefined;
|
|
1046
|
+
});
|
|
766
1047
|
if (!result) {
|
|
767
1048
|
return;
|
|
768
1049
|
}
|
|
@@ -770,6 +1051,15 @@ class TrackedTagMarkers {
|
|
|
770
1051
|
this.forget(at, "the revalidation log has more rows than one query reads");
|
|
771
1052
|
return;
|
|
772
1053
|
}
|
|
1054
|
+
// A scan of every entry held, which also drops the expired ones, once in
|
|
1055
|
+
// a while: so expired entries never read again don't pile up ahead of
|
|
1056
|
+
// live ones. In between, the stores answer early without one, which only
|
|
1057
|
+
// keeps rows in `logOnly` a little longer.
|
|
1058
|
+
const scan = at - this.lastEntryScan > ENTRY_SCAN_INTERVAL_MS;
|
|
1059
|
+
if (scan) {
|
|
1060
|
+
this.lastEntryScan = at;
|
|
1061
|
+
}
|
|
1062
|
+
const oldest = this.oldestEntry(scan);
|
|
773
1063
|
let applied = 0;
|
|
774
1064
|
for (const row of result.rows) {
|
|
775
1065
|
if (this.applied.has(row.sk)) {
|
|
@@ -795,11 +1085,19 @@ class TrackedTagMarkers {
|
|
|
795
1085
|
// rolling re-read. Left unmarked, the next refresh applies it to
|
|
796
1086
|
// whatever that read found; it costs no read, only the row being
|
|
797
1087
|
// looked at again while it is inside the lookback.
|
|
1088
|
+
//
|
|
1089
|
+
// Kept meanwhile in `logOnly`, which is all `completeSince` needs.
|
|
1090
|
+
this.rememberLogged(row.tag, mergeMarkers(this.logOnly.get(row.tag), row.marker), oldest);
|
|
798
1091
|
continue;
|
|
799
1092
|
}
|
|
800
1093
|
this.applied.set(row.sk, row.at);
|
|
801
1094
|
applied++;
|
|
802
1095
|
}
|
|
1096
|
+
if (oldest > this.prunedAgainst) {
|
|
1097
|
+
this.pruneLogged(oldest);
|
|
1098
|
+
}
|
|
1099
|
+
// The rows just kept are known by later than `oldest` too.
|
|
1100
|
+
this.prunedAgainst = oldest;
|
|
803
1101
|
this.lastLogRead = at;
|
|
804
1102
|
this.advance(at - exports.REVALIDATION_LOG_LOOKBACK_MS);
|
|
805
1103
|
this.debug(`read ${result.rows.length} revalidation log rows (${applied} applied)`);
|
|
@@ -814,7 +1112,9 @@ class TrackedTagMarkers {
|
|
|
814
1112
|
for (const tag of this.unread) {
|
|
815
1113
|
if (due.length >= exports.BATCH_GET_MAX_KEYS)
|
|
816
1114
|
return due;
|
|
817
|
-
|
|
1115
|
+
if (!this.reading.has(tag)) {
|
|
1116
|
+
due.push(tag);
|
|
1117
|
+
}
|
|
818
1118
|
}
|
|
819
1119
|
// Known in time order, and each due at most `jitter` earlier than the
|
|
820
1120
|
// tags after it: past a tag due more than that from now, none is due.
|
|
@@ -823,7 +1123,7 @@ class TrackedTagMarkers {
|
|
|
823
1123
|
if (due.length >= exports.BATCH_GET_MAX_KEYS || dueAt - jitter > at) {
|
|
824
1124
|
break;
|
|
825
1125
|
}
|
|
826
|
-
if (dueAt <= at && !this.unread.has(tag)) {
|
|
1126
|
+
if (dueAt <= at && !this.unread.has(tag) && !this.reading.has(tag)) {
|
|
827
1127
|
due.push(tag);
|
|
828
1128
|
}
|
|
829
1129
|
}
|
|
@@ -836,10 +1136,21 @@ class TrackedTagMarkers {
|
|
|
836
1136
|
*/
|
|
837
1137
|
forget(at, why) {
|
|
838
1138
|
this.debug(`forgetting ${this.tags.size} tracked tags: ${why}`);
|
|
1139
|
+
this.forgotten++;
|
|
1140
|
+
// What the markers expire later is still to apply once it is past.
|
|
1141
|
+
for (const marker of this.tags.values()) {
|
|
1142
|
+
this.raiseFloor(marker);
|
|
1143
|
+
}
|
|
1144
|
+
for (const marker of this.logOnly.values()) {
|
|
1145
|
+
this.raiseFloor(marker);
|
|
1146
|
+
}
|
|
839
1147
|
this.tags.clear();
|
|
840
1148
|
this.dueAt.clear();
|
|
841
1149
|
this.unread.clear();
|
|
842
1150
|
this.applied.clear();
|
|
1151
|
+
this.logOnly.clear();
|
|
1152
|
+
// Never back: a marker dropped earlier may have expired entries later.
|
|
1153
|
+
this.floor = Math.max(this.floor, markerClock());
|
|
843
1154
|
this.cursor = at - exports.REVALIDATION_LOG_LOOKBACK_MS;
|
|
844
1155
|
this.lastLogRead = at;
|
|
845
1156
|
}
|
|
@@ -865,13 +1176,23 @@ class TrackedTagMarkers {
|
|
|
865
1176
|
* always answered with, rather than a read on every request while DynamoDB
|
|
866
1177
|
* is unavailable.
|
|
867
1178
|
*/
|
|
868
|
-
async readInto(tags) {
|
|
1179
|
+
async readInto(tags, again = false) {
|
|
869
1180
|
if (tags.length === 0) {
|
|
870
1181
|
return true;
|
|
871
1182
|
}
|
|
872
1183
|
const at = this.clock();
|
|
1184
|
+
const forgotten = this.forgotten;
|
|
873
1185
|
try {
|
|
874
1186
|
const read = await this.markers.read(tags);
|
|
1187
|
+
if (this.forgotten !== forgotten && !again) {
|
|
1188
|
+
// Read before a forget - across a freeze, as like as not - so as
|
|
1189
|
+
// stale as what it forgot. Read again rather than leave the tags
|
|
1190
|
+
// untracked: whoever waits on this read (`reading`) judges entries
|
|
1191
|
+
// by it next, and an untracked tag counts for nothing. Once: a run
|
|
1192
|
+
// of forgets (a truncated log, query after query) would otherwise
|
|
1193
|
+
// keep them waiting, and the second read began after the first.
|
|
1194
|
+
return await this.readInto(tags, true);
|
|
1195
|
+
}
|
|
875
1196
|
for (const tag of tags) {
|
|
876
1197
|
this.unread.delete(tag);
|
|
877
1198
|
this.remember(tag, mergeMarkers(mergeMarkers(this.tags.get(tag), read.get(tag)), this.takePendingRows(tag)));
|
|
@@ -882,6 +1203,9 @@ class TrackedTagMarkers {
|
|
|
882
1203
|
}
|
|
883
1204
|
catch (error) {
|
|
884
1205
|
console.error("Error reading tag markers:", error);
|
|
1206
|
+
if (this.forgotten !== forgotten && !again) {
|
|
1207
|
+
return this.readInto(tags, true);
|
|
1208
|
+
}
|
|
885
1209
|
this.trackUnread(tags);
|
|
886
1210
|
for (const tag of tags) {
|
|
887
1211
|
this.unread.add(tag);
|
|
@@ -895,8 +1219,127 @@ class TrackedTagMarkers {
|
|
|
895
1219
|
}
|
|
896
1220
|
takePendingRows(tag) {
|
|
897
1221
|
const pending = this.pendingRows.get(tag);
|
|
1222
|
+
const logged = this.logOnly.get(tag);
|
|
898
1223
|
this.pendingRows.delete(tag);
|
|
899
|
-
|
|
1224
|
+
this.logOnly.delete(tag);
|
|
1225
|
+
return logged ? mergeMarkers(logged, pending) : pending;
|
|
1226
|
+
}
|
|
1227
|
+
/**
|
|
1228
|
+
* What this instance knows of `tag`: tracked, or from the log alone -
|
|
1229
|
+
* including rows that arrived while its first read is in flight.
|
|
1230
|
+
*/
|
|
1231
|
+
knownMarker(tag) {
|
|
1232
|
+
const tracked = this.tags.get(tag);
|
|
1233
|
+
if (tracked) {
|
|
1234
|
+
return tracked;
|
|
1235
|
+
}
|
|
1236
|
+
const logged = this.logOnly.get(tag);
|
|
1237
|
+
const pending = this.pendingRows.get(tag);
|
|
1238
|
+
return logged || pending ? mergeMarkers(logged, pending) : undefined;
|
|
1239
|
+
}
|
|
1240
|
+
/**
|
|
1241
|
+
* Keep `tag`'s log rows in `logOnly`, unless they cannot apply to an entry
|
|
1242
|
+
* held, `oldest` or newer (see {@link pruneLogged}), as bounded as the
|
|
1243
|
+
* tracked tags. Either way a row let go of takes what it knew with it, so
|
|
1244
|
+
* `completeSince` moves past it.
|
|
1245
|
+
*/
|
|
1246
|
+
rememberLogged(tag, marker, oldest) {
|
|
1247
|
+
this.logOnly.delete(tag);
|
|
1248
|
+
if (knownBy(marker, markerClock()) <= oldest) {
|
|
1249
|
+
this.raiseFloor(marker);
|
|
1250
|
+
return;
|
|
1251
|
+
}
|
|
1252
|
+
this.logOnly.set(tag, marker);
|
|
1253
|
+
for (const [first, dropped] of this.logOnly) {
|
|
1254
|
+
if (this.logOnly.size <= this.maxTrackedTags) {
|
|
1255
|
+
break;
|
|
1256
|
+
}
|
|
1257
|
+
this.logOnly.delete(first);
|
|
1258
|
+
this.raiseFloor(dropped);
|
|
1259
|
+
}
|
|
1260
|
+
}
|
|
1261
|
+
/**
|
|
1262
|
+
* Drop the `logOnly` rows that cannot apply to an entry held, `oldest` or
|
|
1263
|
+
* newer: every revalidation they name so far is no later than it. That
|
|
1264
|
+
* moves `completeSince` no further than `oldest`, which costs the entries
|
|
1265
|
+
* held nothing, and a profile's `expiredAt` still to come waits in
|
|
1266
|
+
* `laterFloors`. Without this, a deployment revalidating many distinct tags
|
|
1267
|
+
* filled `logOnly` with tags no entry here carries, and the evictions past
|
|
1268
|
+
* its bound kept moving `completeSince` up to the present.
|
|
1269
|
+
*/
|
|
1270
|
+
pruneLogged(oldest) {
|
|
1271
|
+
const at = markerClock();
|
|
1272
|
+
for (const [tag, marker] of this.logOnly) {
|
|
1273
|
+
if (knownBy(marker, at) <= oldest) {
|
|
1274
|
+
this.logOnly.delete(tag);
|
|
1275
|
+
this.raiseFloor(marker);
|
|
1276
|
+
}
|
|
1277
|
+
}
|
|
1278
|
+
}
|
|
1279
|
+
/**
|
|
1280
|
+
* The oldest entry timestamp of any registered store, `Infinity` with none:
|
|
1281
|
+
* early, never late, unless `scan`.
|
|
1282
|
+
*/
|
|
1283
|
+
oldestEntry(scan) {
|
|
1284
|
+
let oldest = Infinity;
|
|
1285
|
+
for (const { oldestTimestamp } of this.entryStores) {
|
|
1286
|
+
oldest = Math.min(oldest, oldestTimestamp(scan));
|
|
1287
|
+
}
|
|
1288
|
+
return oldest;
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* Move `completeSince` past `marker`'s revalidations: what is no longer
|
|
1292
|
+
* known about a tag once its marker is dropped. A future `expiredAt` waits
|
|
1293
|
+
* in `laterFloors` until it is past.
|
|
1294
|
+
*/
|
|
1295
|
+
raiseFloor(marker) {
|
|
1296
|
+
const at = markerClock();
|
|
1297
|
+
this.floor = Math.max(this.floor, knownBy(marker, at));
|
|
1298
|
+
const { expiredAt } = marker;
|
|
1299
|
+
if (expiredAt !== undefined && expiredAt > Math.max(at, this.floor)) {
|
|
1300
|
+
this.laterFloor(expiredAt);
|
|
1301
|
+
}
|
|
1302
|
+
}
|
|
1303
|
+
/**
|
|
1304
|
+
* Add `time` to `laterFloors`, in order. Past the tracked-tag bound the two
|
|
1305
|
+
* spans closest together are merged: from the first's start,
|
|
1306
|
+
* `completeSince` is the second's end, early - which only costs reads, and
|
|
1307
|
+
* for as short a time as any merge allows. Never later than its time, which
|
|
1308
|
+
* would let an entry expire unseen.
|
|
1309
|
+
*/
|
|
1310
|
+
laterFloor(time) {
|
|
1311
|
+
const floors = this.laterFloors;
|
|
1312
|
+
let low = 0;
|
|
1313
|
+
let high = floors.length;
|
|
1314
|
+
while (low < high) {
|
|
1315
|
+
const mid = Math.floor((low + high) / 2);
|
|
1316
|
+
if (floors[mid][0] < time) {
|
|
1317
|
+
low = mid + 1;
|
|
1318
|
+
}
|
|
1319
|
+
else {
|
|
1320
|
+
high = mid;
|
|
1321
|
+
}
|
|
1322
|
+
}
|
|
1323
|
+
// Inside a merged span already: by its start, `completeSince` is past it.
|
|
1324
|
+
// Or already there: a log row for an untracked tag is applied again by
|
|
1325
|
+
// every query its lookback returns it to.
|
|
1326
|
+
if ((low > 0 && floors[low - 1][1] >= time) || floors[low]?.[0] === time) {
|
|
1327
|
+
return;
|
|
1328
|
+
}
|
|
1329
|
+
floors.splice(low, 0, [time, time]);
|
|
1330
|
+
// A scan, but only once past the bound. Merging the new time into a
|
|
1331
|
+
// neighbour instead could join an hour-out span with a year-out one, and
|
|
1332
|
+
// hold `completeSince` a year early.
|
|
1333
|
+
if (floors.length > this.maxTrackedTags) {
|
|
1334
|
+
let merge = 0;
|
|
1335
|
+
for (let i = 1; i < floors.length - 1; i++) {
|
|
1336
|
+
if (floors[i + 1][1] - floors[i][0] <
|
|
1337
|
+
floors[merge + 1][1] - floors[merge][0]) {
|
|
1338
|
+
merge = i;
|
|
1339
|
+
}
|
|
1340
|
+
}
|
|
1341
|
+
floors.splice(merge, 2, [floors[merge][0], floors[merge + 1][1]]);
|
|
1342
|
+
}
|
|
900
1343
|
}
|
|
901
1344
|
/** Record that `tag`'s marker was known from the table at `at`. */
|
|
902
1345
|
known(tag, at) {
|
|
@@ -910,6 +1353,7 @@ class TrackedTagMarkers {
|
|
|
910
1353
|
if (this.tags.size <= this.maxTrackedTags) {
|
|
911
1354
|
break;
|
|
912
1355
|
}
|
|
1356
|
+
this.raiseFloor(this.tags.get(oldest));
|
|
913
1357
|
this.tags.delete(oldest);
|
|
914
1358
|
this.dueAt.delete(oldest);
|
|
915
1359
|
this.unread.delete(oldest);
|
|
@@ -923,12 +1367,34 @@ class TrackedTagMarkers {
|
|
|
923
1367
|
}
|
|
924
1368
|
}
|
|
925
1369
|
exports.TrackedTagMarkers = TrackedTagMarkers;
|
|
1370
|
+
/**
|
|
1371
|
+
* The latest revalidation `marker` has made known by `at`, `-Infinity` with
|
|
1372
|
+
* none: a future `expiredAt` is still to come.
|
|
1373
|
+
*/
|
|
1374
|
+
function knownBy(marker, at) {
|
|
1375
|
+
const { revalidatedAt, staleAt, expiredAt } = marker;
|
|
1376
|
+
return Math.max(revalidatedAt ?? -Infinity, staleAt ?? -Infinity, expiredAt !== undefined && expiredAt <= at ? expiredAt : -Infinity);
|
|
1377
|
+
}
|
|
926
1378
|
/**
|
|
927
1379
|
* The longest a log row's put may take and still be seen by every reader: half
|
|
928
1380
|
* the lookback, leaving the rest for writers' clocks and eventually consistent
|
|
929
1381
|
* queries.
|
|
930
1382
|
*/
|
|
931
1383
|
const MAX_LOG_PUT_MS = exports.REVALIDATION_LOG_LOOKBACK_MS / 2;
|
|
1384
|
+
/**
|
|
1385
|
+
* How often a refresh scans the entry stores for their oldest entry, dropping
|
|
1386
|
+
* the expired ones no request reads again.
|
|
1387
|
+
*/
|
|
1388
|
+
const ENTRY_SCAN_INTERVAL_MS = 60_000;
|
|
1389
|
+
/** How often a refresh in flight checks the process is running. */
|
|
1390
|
+
const REFRESH_TICK_MS = 250;
|
|
1391
|
+
/**
|
|
1392
|
+
* How late a tick may come before the process counts as paused (frozen)
|
|
1393
|
+
* since the refresh in flight started. A busy event loop can delay one too:
|
|
1394
|
+
* the refresh then counts as no fresher than its start, as before the pause
|
|
1395
|
+
* check, so a request waits for the next one once that is past the grace.
|
|
1396
|
+
*/
|
|
1397
|
+
const REFRESH_PAUSE_MS = 1000;
|
|
932
1398
|
/**
|
|
933
1399
|
* A marker as read from the table or the log, keeping whatever this instance
|
|
934
1400
|
* already knows that the read does not show yet: reads are eventually
|
|
@@ -1001,4 +1467,4 @@ class CacheBucket {
|
|
|
1001
1467
|
}
|
|
1002
1468
|
}
|
|
1003
1469
|
exports.CacheBucket = CacheBucket;
|
|
1004
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLWNhY2hlLXN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvYXdzLWNhY2hlLXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQThDQSxzREFPQztBQVNELGdDQVFDO0FBa0JELHNDQUVDO0FBcUNELGtDQWdCQztBQVdELGtDQUVDO0FBV0QsOEJBV0M7QUFRRCxrQ0FXQztBQUdELG9DQWVDO0FBdzVCRCxvQ0FvQkM7QUFub0NEOzs7Ozs7Ozs7RUFTRTtBQUNGLHNEQUFzRDtBQUN0RCx5Q0FBaUM7QUFDakMsOERBU2tDO0FBQ2xDLGtEQUs0QjtBQWtCNUIsOENBQThDO0FBQzlDLFNBQWdCLHFCQUFxQjtJQUNuQyxPQUFPO1FBQ0wsVUFBVSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLElBQUksRUFBRTtRQUMxRCxTQUFTLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQ0FBa0MsSUFBSSxFQUFFO1FBQy9ELE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxXQUFXO1FBQzdDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLEVBQUU7S0FDL0MsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixVQUFVLENBQUMsT0FBZSxFQUFFLFFBQWdCO0lBQzFELElBQUksYUFBYSxHQUFHLFFBQVEsQ0FBQztJQUM3QixJQUFJLFFBQVEsS0FBSyxHQUFHLElBQUksUUFBUSxLQUFLLEVBQUUsRUFBRSxDQUFDO1FBQ3hDLGFBQWEsR0FBRyxPQUFPLENBQUM7SUFDMUIsQ0FBQztTQUFNLElBQUksUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO1FBQ3BDLGFBQWEsR0FBRyxRQUFRLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQ3BDLENBQUM7SUFDRCxPQUFPLElBQUEsZ0JBQUksRUFBQyxP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RUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUM1RCxDQUFDO1lBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDbkIsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUNELE9BQU8sTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxLQUFLLFlBQVkscUJBQVMsRUFBRSxDQUFDO2dCQUMvQixPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1lBQ0QsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVELDhDQUE4QztJQUM5QyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQVcsRUFBRSxJQUFZO1FBQ3JDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3BCLElBQUksNEJBQWdCLENBQUM7WUFDbkIsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQ3ZCLEdBQUcsRUFBRSxHQUFHO1lBQ1IsSUFBSSxFQUFFLElBQUk7WUFDVixXQUFXLEVBQUUsaUNBQWlDO1NBQy9DLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBdkNELGtDQXVDQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gIFRoZSBTMyAvIER5bmFtb0RCIHBsdW1iaW5nIHNoYXJlZCBieSBldmVyeSBjZGstbmV4dGpzIGNhY2hlIGhhbmRsZXI6IHRoZVxuICBpbmNyZW1lbnRhbCBgY2FjaGVIYW5kbGVyYCAoYFMzQ2FjaGVIYW5kbGVyYCkgYW5kIHRoZSBgY2FjaGVIYW5kbGVyc2AgZm9yXG4gIGAndXNlIGNhY2hlJ2AgLyBgJ3VzZSBjYWNoZTogcmVtb3RlJ2AuXG5cbiAgV2hhdCBsaXZlcyBoZXJlIGlzIHdoYXQgaGFzIHRvIGFncmVlIGJldHdlZW4gdGhlbSAtIHdoZXJlIHRoZSBjb25maWd1cmF0aW9uXG4gIGNvbWVzIGZyb20sIGhvdyBhIGNhY2hlIGtleSBiZWNvbWVzIGFuIFMzIGtleSwgYW5kIHdoYXQgYSB0YWcncyBtYXJrZXIgcm93IGluXG4gIHRoZSByZXZhbGlkYXRpb24gdGFibGUgbG9va3MgbGlrZSBhbmQgbWVhbnMuIEEgYHJldmFsaWRhdGVUYWdgIHJlYWNoZXMgYm90aFxuICBraW5kcyBvZiBoYW5kbGVyLCBhbmQgdGhleSBtdXN0IHJlYWQgZWFjaCBvdGhlcidzIG1hcmtlcnMgdGhlIHNhbWUgd2F5LlxuKi9cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7XG4gIEF0dHJpYnV0ZVZhbHVlLFxuICBCYXRjaEdldEl0ZW1Db21tYW5kLFxuICBCYXRjaEdldEl0ZW1Db21tYW5kT3V0cHV0LFxuICBEeW5hbW9EQkNsaWVudCxcbiAgUHV0SXRlbUNvbW1hbmQsXG4gIFF1ZXJ5Q29tbWFuZCxcbiAgUXVlcnlDb21tYW5kT3V0cHV0LFxuICBVcGRhdGVJdGVtQ29tbWFuZCxcbn0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1keW5hbW9kYlwiO1xuaW1wb3J0IHtcbiAgR2V0T2JqZWN0Q29tbWFuZCxcbiAgTm9TdWNoS2V5LFxuICBQdXRPYmplY3RDb21tYW5kLFxuICBTM0NsaWVudCxcbn0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1zM1wiO1xuXG4vKipcbiAqIFdoZXJlIHRoZSBjYWNoZSBsaXZlcywgYXMgdGhlIGNvbnN0cnVjdHMgcGFzcyBpdCB0byB0aGUgY29tcHV0ZSB0aHJvdWdoIHRoZVxuICogZW52aXJvbm1lbnQgKGBOZXh0anNGdW5jdGlvbnNgLCBgTmV4dGpzQ29udGFpbmVyc2ApLiBFbXB0eSBzdHJpbmdzIGZvciB3aGF0IGlzXG4gKiBub3QgY29uZmlndXJlZCwgd2hpY2ggZWFjaCBoYW5kbGVyIHJlYWRzIGFzIFwidGhhdCBsYXllciBpcyBkaXNhYmxlZFwiLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF3c0NhY2hlQ29uZmlnIHtcbiAgLyoqIGBDREtfTkVYVEpTX0NBQ0hFX0JVQ0tFVF9OQU1FYC4gKi9cbiAgYnVja2V0TmFtZTogc3RyaW5nO1xuICAvKiogYENES19ORVhUSlNfUkVWQUxJREFUSU9OX1RBQkxFX05BTUVgLiAqL1xuICB0YWJsZU5hbWU6IHN0cmluZztcbiAgLyoqIGBBV1NfUkVHSU9OYCwgYHVzLWVhc3QtMWAgd2hlbiB1bnNldC4gKi9cbiAgcmVnaW9uOiBzdHJpbmc7XG4gIC8qKiBgQ0RLX05FWFRKU19CVUlMRF9JRGA6IGV2ZXJ5IFMzIGtleSBhbmQgZXZlcnkgbWFya2VyIHJvdyBpcyBzY29wZWQgdG8gaXQuICovXG4gIGJ1aWxkSWQ6IHN0cmluZztcbn1cblxuLyoqIFRoZSBjb25maWd1cmF0aW9uIGZyb20gdGhlIGVudmlyb25tZW50LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVBd3NDYWNoZUNvbmZpZygpOiBBd3NDYWNoZUNvbmZpZyB7XG4gIHJldHVybiB7XG4gICAgYnVja2V0TmFtZTogcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19DQUNIRV9CVUNLRVRfTkFNRSB8fCBcIlwiLFxuICAgIHRhYmxlTmFtZTogcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19SRVZBTElEQVRJT05fVEFCTEVfTkFNRSB8fCBcIlwiLFxuICAgIHJlZ2lvbjogcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiB8fCBcInVzLWVhc3QtMVwiLFxuICAgIGJ1aWxkSWQ6IHByb2Nlc3MuZW52LkNES19ORVhUSlNfQlVJTERfSUQgfHwgXCJcIixcbiAgfTtcbn1cblxuLyoqXG4gKiBge2J1aWxkSWR9L3tjYWNoZUtleX0uanNvbmAsIHRoZSBpbmNyZW1lbnRhbCBjYWNoZSdzIGtleSBjb252ZW50aW9uLlxuICpcbiAqIFRoZSByb290IHBhdGggYmVjb21lcyBgaW5kZXhgLCBhbmQgYSBsZWFkaW5nIHNsYXNoIGlzIGRyb3BwZWQgc28gdGhlcmUgaXMgbm9cbiAqIGVtcHR5IGZvbGRlciB1bmRlciB0aGUgYnVpbGQgcHJlZml4LiBFdmVyeXRoaW5nIHRoaXMgcmV0dXJucyBlbmRzIGluIGAuanNvbmAsXG4gKiB3aGljaCBpcyB3aGF0IGtlZXBzIGl0IGRpc2pvaW50IGZyb20ge0BsaW5rIHVzZUNhY2hlUzNLZXl9LlxuICovXG5leHBvcnQgZnVuY3Rpb24gYnVpbGRTM0tleShidWlsZElkOiBzdHJpbmcsIGNhY2hlS2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICBsZXQgY2xlYW5DYWNoZUtleSA9IGNhY2hlS2V5O1xuICBpZiAoY2FjaGVLZXkgPT09IFwiL1wiIHx8IGNhY2hlS2V5ID09PSBcIlwiKSB7XG4gICAgY2xlYW5DYWNoZUtleSA9IFwiaW5kZXhcIjtcbiAgfSBlbHNlIGlmIChjYWNoZUtleS5zdGFydHNXaXRoKFwiL1wiKSkge1xuICAgIGNsZWFuQ2FjaGVLZXkgPSBjYWNoZUtleS5zbGljZSgxKTtcbiAgfVxuICByZXR1cm4gam9pbihidWlsZElkLCBgJHtjbGVhbkNhY2hlS2V5fS5qc29uYCk7XG59XG5cbi8qKlxuICogVGhlIGZvbGRlciB1bmRlciB0aGUgYnVpbGQgcHJlZml4IHRoYXQgYCd1c2UgY2FjaGUnYCBlbnRyaWVzIGFyZSBzdG9yZWQgaW4uXG4gKiBAc2VlIHVzZUNhY2hlUzNLZXlcbiAqL1xuZXhwb3J0IGNvbnN0IFVTRV9DQUNIRV9LRVlfUFJFRklYID0gXCJfdXNlLWNhY2hlXCI7XG5cbi8qKlxuICogYHtidWlsZElkfS9fdXNlLWNhY2hlL3toYXNofS5lbnRyeWAsIHdoZXJlIGEgYGNhY2hlSGFuZGxlcnNgIGVudHJ5IGlzIHN0b3JlZC5cbiAqXG4gKiBIYXNoZWQgYmVjYXVzZSBhIGAndXNlIGNhY2hlJ2Aga2V5IGlzIHRoZSBzZXJpYWxpemVkIGFyZ3VtZW50cyBvZiB0aGUgY2FsbCBhbmRcbiAqIGhhcyBubyBsZW5ndGggbGltaXQsIHdoZXJlIGFuIFMzIGtleSBzdG9wcyBhdCAxMDI0IGJ5dGVzLiBUaGUgYC5lbnRyeWAgc3VmZml4XG4gKiByYXRoZXIgdGhhbiBgLmpzb25gIGlzIHdoYXQgbWFrZXMgYSBjb2xsaXNpb24gd2l0aCB0aGUgaW5jcmVtZW50YWwgY2FjaGVcbiAqIGltcG9zc2libGUgcmF0aGVyIHRoYW4gdW5saWtlbHk6IGV2ZXJ5IGtleSB7QGxpbmsgYnVpbGRTM0tleX0gd3JpdGVzIGVuZHMgaW5cbiAqIGAuanNvbmAsIGluY2x1ZGluZyBvbmUgZm9yIGEgcm91dGUgdGhhdCBoYXBwZW5zIHRvIGJlIG5hbWVkIGAvX3VzZS1jYWNoZS/igKZgLlxuICogU3RpbGwgdW5kZXIgdGhlIGJ1aWxkIHByZWZpeCwgc28gcG9zdC1kZXBsb3kgcHJ1bmluZyBkcm9wcyB0aGVtIHdpdGggdGhlIGJ1aWxkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdXNlQ2FjaGVTM0tleShidWlsZElkOiBzdHJpbmcsIGtleUhhc2g6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGJ1aWxkSWQsIFVTRV9DQUNIRV9LRVlfUFJFRklYLCBgJHtrZXlIYXNofS5lbnRyeWApO1xufVxuXG4vKipcbiAqIFRoZSBgZHVyYXRpb25zYCBOZXh0LmpzIDE2IHBhc3NlcyBhIHRhZyByZXZhbGlkYXRpb24gZm9yIGEgcHJvZmlsZTpcbiAqIGByZXZhbGlkYXRlVGFnKFwicG9zdHNcIiwgXCJtYXhcIilgIGFycml2ZXMgYXMgYHsgZXhwaXJlOiA8dGhlIHByb2ZpbGUncyBleHBpcmU+IH1gLlxuICogQWJzZW50IGZvciBgdXBkYXRlVGFnYCBhbmQgYSBiYXJlIGByZXZhbGlkYXRlVGFnYCwgd2hpY2ggZXhwaXJlIGltbWVkaWF0ZWx5LlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFJldmFsaWRhdGVEdXJhdGlvbnMge1xuICBleHBpcmU/OiBudW1iZXI7XG59XG5cbi8qKlxuICogQSB0YWcncyBtYXJrZXIgcm93LCBhcyB0aW1lc3RhbXBzIGluIG1pbGxpc2Vjb25kcy4gV3JpdHRlbiBieVxuICoge0BsaW5rIG1hcmtlclVwZGF0ZX07IGVhY2ggZmllbGQgaXMgYWJzZW50IHVudGlsIGEgcmV2YWxpZGF0aW9uIG9mIHRoYXQgc2hhcGVcbiAqIGhhcyBoYXBwZW5lZC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBUYWdNYXJrZXIge1xuICAvKiogRXhwaXJlZCBvdXRyaWdodDogYHVwZGF0ZVRhZ2AsIG9yIGByZXZhbGlkYXRlVGFnYCB3aXRoIG5vIHByb2ZpbGUuICovXG4gIHJldmFsaWRhdGVkQXQ/OiBudW1iZXI7XG4gIC8qKiBTdGFsZSBmcm9tIGhlcmU6IGByZXZhbGlkYXRlVGFnKHRhZywgcHJvZmlsZSlgLiAqL1xuICBzdGFsZUF0PzogbnVtYmVyO1xuICAvKiogV2hlbiB0aGUgcHJvZmlsZSdzIGBleHBpcmVgIHJ1bnMgb3V0LCB3aGljaCBtYXkgYmUgaW4gdGhlIGZ1dHVyZS4gKi9cbiAgZXhwaXJlZEF0PzogbnVtYmVyO1xufVxuXG4vKipcbiAqIFdoYXQgdGhlIHRhZyBtYXJrZXJzIHNheSBhYm91dCBhbiBlbnRyeTogdW50b3VjaGVkLCBzZXJ2ZWQgc3RhbGUgd2hpbGUgYVxuICogYmFja2dyb3VuZCByZW5kZXIgcmVwbGFjZXMgaXQsIG9yIGV4cGlyZWQgYW5kIHJlLXJlbmRlcmVkIGJlZm9yZSBhbnN3ZXJpbmcuXG4gKi9cbmV4cG9ydCB0eXBlIFJldmFsaWRhdGlvblN0YXRlID0gXCJmcmVzaFwiIHwgXCJzdGFsZVwiIHwgXCJleHBpcmVkXCI7XG5cbi8qKlxuICogV2hhdCBgbWFya2VyYCBtZWFucyBmb3IgYW4gZW50cnkgY3JlYXRlZCBhdCBgY3JlYXRlZEF0YCwgYXQgYG5vd2AuXG4gKlxuICogYGV4cGlyZWRBdGAgaW4gdGhlIGZ1dHVyZSBpcyBhIHByb2ZpbGUncyBgZXhwaXJlYCB0aGF0IGhhcyBub3QgY29tZSB5ZXQsXG4gKiBjb21wYXJlZCB0aGUgd2F5IE5leHQuanMncyBgYXJlVGFnc0V4cGlyZWRgIGRvZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJTdGF0ZShcbiAgbWFya2VyOiBUYWdNYXJrZXIsXG4gIGNyZWF0ZWRBdDogbnVtYmVyLFxuICBub3c6IG51bWJlcixcbik6IFJldmFsaWRhdGlvblN0YXRlIHtcbiAgY29uc3QgeyByZXZhbGlkYXRlZEF0LCBleHBpcmVkQXQsIHN0YWxlQXQgfSA9IG1hcmtlcjtcbiAgaWYgKFxuICAgIChyZXZhbGlkYXRlZEF0ICE9PSB1bmRlZmluZWQgJiYgcmV2YWxpZGF0ZWRBdCA+IGNyZWF0ZWRBdCkgfHxcbiAgICAoZXhwaXJlZEF0ICE9PSB1bmRlZmluZWQgJiYgZXhwaXJlZEF0IDw9IG5vdyAmJiBleHBpcmVkQXQgPiBjcmVhdGVkQXQpXG4gICkge1xuICAgIHJldHVybiBcImV4cGlyZWRcIjtcbiAgfVxuICBpZiAoc3RhbGVBdCAhPT0gdW5kZWZpbmVkICYmIHN0YWxlQXQgPiBjcmVhdGVkQXQpIHtcbiAgICByZXR1cm4gXCJzdGFsZVwiO1xuICB9XG4gIHJldHVybiBcImZyZXNoXCI7XG59XG5cbi8qKlxuICogVGhlIGNsb2NrIGV2ZXJ5IHRhZyBtYXJrZXIgaXMgc3RhbXBlZCB3aXRoLCBhbmQgZXZlcnkgZW50cnkgdGltZXN0YW1wIGl0IGlzXG4gKiBjb21wYXJlZCBhZ2FpbnN0OiB0aGUgb25lIE5leHQuanMgc3RhbXBzIGBDYWNoZUVudHJ5LnRpbWVzdGFtcGAgd2l0aFxuICogKGBwZXJmb3JtYW5jZS50aW1lT3JpZ2luICsgcGVyZm9ybWFuY2Uubm93KClgLCBpbiBgdXNlLWNhY2hlLXdyYXBwZXIuanNgIGFuZFxuICogdGhlIGRlZmF1bHQgaGFuZGxlciksIHJhdGhlciB0aGFuIGBEYXRlLm5vdygpYC4gQm90aCBoYW5kbGVycyB3cml0ZSB0aGUgc2FtZVxuICogbWFya2VyIHJvd3MsIHNvIGJvdGggaGF2ZSB0byB1c2UgaXQ6IHR3byBjbG9ja3Mgb24gb25lIHJvdyBsZXQgdGhlIGxhc3Qgd3JpdGVyXG4gKiBkZWNpZGUgd2hpY2ggY2xvY2sgdGhlIG90aGVycyBjb21wYXJlIGFnYWluc3QsIGFuZCB0aGV5IGRyaWZ0IGFwYXJ0IGZvciBhc1xuICogbG9uZyBhcyBhIExhbWJkYSBzYW5kYm94IG9yIEZhcmdhdGUgdGFzayBsaXZlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcmtlckNsb2NrKCk6IG51bWJlciB7XG4gIHJldHVybiBwZXJmb3JtYW5jZS50aW1lT3JpZ2luICsgcGVyZm9ybWFuY2Uubm93KCk7XG59XG5cbi8qKlxuICogVGhlIG1hcmtlciBmaWVsZHMgYSB0YWcgcmV2YWxpZGF0ZWQgYXQgYG5vd2Agc2V0cy5cbiAqXG4gKiBXaXRob3V0IGBkdXJhdGlvbnNgIC0gYHVwZGF0ZVRhZ2AsIG9yIGByZXZhbGlkYXRlVGFnYCB3aXRoIG5vIHByb2ZpbGUgLSB0aGVcbiAqIHRhZydzIGVudHJpZXMgZXhwaXJlIGltbWVkaWF0ZWx5IChgcmV2YWxpZGF0ZWRBdGApLiBXaXRoIHRoZW0gdGhlIGVudHJpZXMgZ29cbiAqIHN0YWxlIG5vdyBhbmQgZXhwaXJlIGFmdGVyIHRoZSBwcm9maWxlJ3MgYGV4cGlyZWAsIHRoZSBzYW1lIHBhaXIgb2ZcbiAqIHRpbWVzdGFtcHMgTmV4dC5qcydzIGBGaWxlU3lzdGVtQ2FjaGUucmV2YWxpZGF0ZVRhZ2AgcmVjb3Jkcy4gQSBwcm9maWxlIHdpdGhcbiAqIG5vIGBleHBpcmVgIHNldHMgb25seSBgc3RhbGVBdGAsIGFuZCB3aGF0ZXZlciBgZXhwaXJlZEF0YCB0aGUgdGFnIGhhZCBzdGF5cy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcmtlckZvcihcbiAgbm93OiBudW1iZXIsXG4gIGR1cmF0aW9uczogUmV2YWxpZGF0ZUR1cmF0aW9ucyB8IHVuZGVmaW5lZCxcbik6IFRhZ01hcmtlciB7XG4gIGlmICghZHVyYXRpb25zKSB7XG4gICAgcmV0dXJuIHsgcmV2YWxpZGF0ZWRBdDogbm93IH07XG4gIH1cbiAgaWYgKGR1cmF0aW9ucy5leHBpcmUgPT09IHVuZGVmaW5lZCkge1xuICAgIHJldHVybiB7IHN0YWxlQXQ6IG5vdyB9O1xuICB9XG4gIHJldHVybiB7IHN0YWxlQXQ6IG5vdywgZXhwaXJlZEF0OiBub3cgKyBkdXJhdGlvbnMuZXhwaXJlICogMTAwMCB9O1xufVxuXG5jb25zdCBNQVJLRVJfRklFTERTID0gW1wicmV2YWxpZGF0ZWRBdFwiLCBcInN0YWxlQXRcIiwgXCJleHBpcmVkQXRcIl0gYXMgY29uc3Q7XG5cbi8qKlxuICogYGV4aXN0aW5nYCB3aXRoIHRoZSBmaWVsZHMgYHVwZGF0ZWAgc2V0cywgYXMgYSB7QGxpbmsgbWFya2VyVXBkYXRlfSBsZWF2ZXNcbiAqIHRoZSByb3c6IGEgZmllbGQgYHVwZGF0ZWAgZG9lcyBub3Qgc2V0IGtlZXBzIGl0cyB2YWx1ZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFwcGx5TWFya2VyKFxuICBleGlzdGluZzogVGFnTWFya2VyIHwgdW5kZWZpbmVkLFxuICB1cGRhdGU6IFRhZ01hcmtlcixcbik6IFRhZ01hcmtlciB7XG4gIGNvbnN0IG1hcmtlciA9IHsgLi4uZXhpc3RpbmcgfTtcbiAgZm9yIChjb25zdCBmaWVsZCBvZiBNQVJLRVJfRklFTERTKSB7XG4gICAgaWYgKHVwZGF0ZVtmaWVsZF0gIT09IHVuZGVmaW5lZCkge1xuICAgICAgbWFya2VyW2ZpZWxkXSA9IHVwZGF0ZVtmaWVsZF07XG4gICAgfVxuICB9XG4gIHJldHVybiBtYXJrZXI7XG59XG5cbi8qKiBUaGUgbWFya2VyLXJvdyB1cGRhdGUgdGhhdCBzZXRzIHtAbGluayBtYXJrZXJGb3J9J3MgZmllbGRzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcmtlclVwZGF0ZShcbiAgbm93OiBudW1iZXIsXG4gIGR1cmF0aW9uczogUmV2YWxpZGF0ZUR1cmF0aW9ucyB8IHVuZGVmaW5lZCxcbik6IFBpY2s8XG4gIENvbnN0cnVjdG9yUGFyYW1ldGVyczx0eXBlb2YgVXBkYXRlSXRlbUNvbW1hbmQ+WzBdLFxuICBcIlVwZGF0ZUV4cHJlc3Npb25cIiB8IFwiRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlc1wiXG4+IHtcbiAgY29uc3QgbWFya2VyID0gbWFya2VyRm9yKG5vdywgZHVyYXRpb25zKTtcbiAgY29uc3QgZmllbGRzID0gTUFSS0VSX0ZJRUxEUy5maWx0ZXIoKGZpZWxkKSA9PiBtYXJrZXJbZmllbGRdICE9PSB1bmRlZmluZWQpO1xuICByZXR1cm4ge1xuICAgIFVwZGF0ZUV4cHJlc3Npb246IGBTRVQgJHtmaWVsZHMubWFwKChmaWVsZCkgPT4gYCR7ZmllbGR9ID0gOiR7ZmllbGR9YCkuam9pbihcIiwgXCIpfWAsXG4gICAgRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczogT2JqZWN0LmZyb21FbnRyaWVzKFxuICAgICAgZmllbGRzLm1hcCgoZmllbGQpID0+IFtgOiR7ZmllbGR9YCwgeyBOOiBTdHJpbmcobWFya2VyW2ZpZWxkXSkgfV0pLFxuICAgICksXG4gIH07XG59XG5cbi8qKiBBIER5bmFtb0RCIG51bWJlciBhdHRyaWJ1dGUgYXMgYSBudW1iZXIsIG9yIGB1bmRlZmluZWRgIHdoZW4gYWJzZW50LiAqL1xuZnVuY3Rpb24gbnVtYmVyQXR0cmlidXRlKFxuICB2YWx1ZTogQXR0cmlidXRlVmFsdWUgfCB1bmRlZmluZWQsXG4pOiBudW1iZXIgfCB1bmRlZmluZWQge1xuICByZXR1cm4gdmFsdWU/Lk4gPT09IHVuZGVmaW5lZCA/IHVuZGVmaW5lZCA6IE51bWJlcih2YWx1ZS5OKTtcbn1cblxuLyoqIFRoZSBtYXJrZXIgZmllbGRzIG9mIGEgbWFya2VyIG9yIGxvZyByb3cuICovXG5mdW5jdGlvbiBtYXJrZXJPZihpdGVtOiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4pOiBUYWdNYXJrZXIge1xuICByZXR1cm4ge1xuICAgIHJldmFsaWRhdGVkQXQ6IG51bWJlckF0dHJpYnV0ZShpdGVtLnJldmFsaWRhdGVkQXQpLFxuICAgIHN0YWxlQXQ6IG51bWJlckF0dHJpYnV0ZShpdGVtLnN0YWxlQXQpLFxuICAgIGV4cGlyZWRBdDogbnVtYmVyQXR0cmlidXRlKGl0ZW0uZXhwaXJlZEF0KSxcbiAgfTtcbn1cblxuLyoqIER5bmFtb0RCJ3MgY2FwIG9uIGtleXMgaW4gb25lIGBCYXRjaEdldEl0ZW1gLiAqL1xuZXhwb3J0IGNvbnN0IEJBVENIX0dFVF9NQVhfS0VZUyA9IDEwMDtcblxuLyoqXG4gKiBIb3cgb2Z0ZW4sIGF0IG1vc3QsIGFuIGluc3RhbmNlIGNhdGNoZXMgdXAgb24gcmV2YWxpZGF0aW9ucyBvdGhlciBpbnN0YW5jZXNcbiAqIHJhbiwgdW5sZXNzIGBDREtfTkVYVEpTX1RBR19SRUZSRVNIX01TYCBzYXlzIG90aGVyd2lzZTogdGhlIHN0YWxlbmVzcyB3aW5kb3dcbiAqIGZvciBhIGByZXZhbGlkYXRlVGFnYCBydW4gZWxzZXdoZXJlLiBFdmVyeSBjYWNoZSBoaXQgY2hlY2tzIGl0cyB0YWdzJ1xuICogbWFya2VycywgYW5kIGV2ZXJ5IG1hcmtlciBvZiBhIGRlcGxveW1lbnQgc2hhcmVzIG9uZSBwYXJ0aXRpb24ga2V5LCBzb1xuICogcmVhZGluZyB0aGVtIHBlciByZXF1ZXN0IGNhcHBlZCBhIHJvdXRlJ3MgY2FjaGUgaGl0cyBhdCB0aGUgcGFydGl0aW9uJ3MgcmVhZFxuICogdGhyb3VnaHB1dCAofjEsOTAwIHJlcS9zIG9uIE5leHRqc1JlZ2lvbmFsRnVuY3Rpb25zKS4gT25jZSBhIHNlY29uZCwgZnJvbSB0aGVcbiAqIHJldmFsaWRhdGlvbiBsb2csIHRoZSByZWFkcyBzY2FsZSB3aXRoIGluc3RhbmNlcyBpbnN0ZWFkIG9mIHJlcXVlc3RzIG9yIHRhZ3MuXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX1RBR19SRUZSRVNIX01TID0gMTAwMDtcblxuLyoqXG4gKiBUaGUgYmFyZS10YWcgbWFya2VyIHJvd3Mgb2YgdGhlIHJldmFsaWRhdGlvbiB0YWJsZSAoYHBrID0gYnVpbGRJZGAsXG4gKiBgc2sgPSB0YWdgKSwgd2hpY2ggcmVjb3JkIHdoZW4gYSB0YWcgd2FzIGxhc3QgcmV2YWxpZGF0ZWQgYW5kIGhvdy5cbiAqXG4gKiBUaGUgdGFibGUgYWxzbyBob2xkcyB0aGUgaW5jcmVtZW50YWwgY2FjaGUncyBgdGFnI3MzS2V5YCBtYXBwaW5nIHJvd3MsIHdoaWNoXG4gKiBhcmUgaXRzIG93biBidXNpbmVzcyBhbmQgc3RheSBpbiBgUzNDYWNoZUhhbmRsZXJgOiBvbmx5IHRoZSBtYXJrZXJzIG1lYW4gdGhlXG4gKiBzYW1lIHRoaW5nIHRvIGV2ZXJ5IGhhbmRsZXIuIFdoYXQgYW4gaW5zdGFuY2Uga2VlcHMgb2YgdGhlbSBiZXR3ZWVuIHJlYWRzIGlzXG4gKiB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnN9LlxuICovXG5leHBvcnQgY2xhc3MgVGFnTWFya2VyVGFibGUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudDogRHluYW1vREJDbGllbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJ1aWxkSWQ6IHN0cmluZyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgYHRhZ2AncyByZXZhbGlkYXRpb24gYXQgYG5vd2AuIFNlZSB7QGxpbmsgbWFya2VyVXBkYXRlfS5cbiAgICpcbiAgICogUmV0dXJucyB0aGUgcm93IGFzIHRoaXMgd3JpdGUgbGVmdCBpdCwgc28gdGhlIGluc3RhbmNlIHRoYXQgd3JvdGUgaXQgY2FuXG4gICAqIHRyYWNrIGl0IHJhdGhlciB0aGFuIHJlYWQgaXQgYmFjazogcmVhZHMgYXJlIGV2ZW50dWFsbHkgY29uc2lzdGVudCwgYW5kIGFcbiAgICogcmVhZC1iYWNrIHJhY2luZyByZXBsaWNhdGlvbiBjb3VsZCByZXR1cm4gdGhlIG1hcmtlciBmcm9tIGJlZm9yZSB0aGUgd3JpdGUuXG4gICAqL1xuICBhc3luYyB3cml0ZShcbiAgICB0YWc6IHN0cmluZyxcbiAgICBub3c6IG51bWJlcixcbiAgICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8VGFnTWFya2VyIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNsaWVudC5zZW5kKFxuICAgICAgbmV3IFVwZGF0ZUl0ZW1Db21tYW5kKHtcbiAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgS2V5OiB7XG4gICAgICAgICAgcGs6IHsgUzogdGhpcy5idWlsZElkIH0sXG4gICAgICAgICAgc2s6IHsgUzogdGFnIH0sXG4gICAgICAgIH0sXG4gICAgICAgIC4uLm1hcmtlclVwZGF0ZShub3csIGR1cmF0aW9ucyksXG4gICAgICAgIFJldHVyblZhbHVlczogXCJBTExfTkVXXCIsXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiByZXNwb25zZT8uQXR0cmlidXRlcyA/IG1hcmtlck9mKHJlc3BvbnNlLkF0dHJpYnV0ZXMpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBtYXJrZXIgcm93cyBmb3IgYHRhZ3NgIHRoYXQgZXhpc3QsIGJ5IHRhZywgaW4gb25lIGBCYXRjaEdldEl0ZW1gIHBlclxuICAgKiB7QGxpbmsgQkFUQ0hfR0VUX01BWF9LRVlTfSB0YWdzIHJhdGhlciB0aGFuIGEgYEdldEl0ZW1gIGVhY2g6IGEgcGFnZVxuICAgKiBjYXJyaWVzIGl0cyB3aG9sZSBpbXBsaWNpdCBgX05fVF8v4oCmYCBjaGFpbiBwbHVzIHRoZSBhcHAncyBvd24gdGFncywgYVxuICAgKiBwYWdlIHdpdGggYSBmZXcgZmV0Y2hlcyBjaGVja3MgZWFjaCBvZiB0aGVtIHRvbywgYW5kIGV2ZXJ5IG9uZSBpcyBvbiB0aGVcbiAgICogcmVxdWVzdCBwYXRoLiBBIHRhZyB3aXRoIG5vIHJvdyBpcyBhYnNlbnQgZnJvbSB0aGUgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgcmVhZCh0YWdzOiBzdHJpbmdbXSk6IFByb21pc2U8TWFwPHN0cmluZywgVGFnTWFya2VyPj4ge1xuICAgIGNvbnN0IHsgdGFibGVOYW1lLCBidWlsZElkIH0gPSB0aGlzO1xuICAgIGNvbnN0IHVuaXF1ZSA9IEFycmF5LmZyb20obmV3IFNldCh0YWdzKSk7XG4gICAgY29uc3QgbWFya2VycyA9IG5ldyBNYXA8c3RyaW5nLCBUYWdNYXJrZXI+KCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVuaXF1ZS5sZW5ndGg7IGkgKz0gQkFUQ0hfR0VUX01BWF9LRVlTKSB7XG4gICAgICBsZXQga2V5czogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlVmFsdWU+W10gfCB1bmRlZmluZWQgPSB1bmlxdWVcbiAgICAgICAgLnNsaWNlKGksIGkgKyBCQVRDSF9HRVRfTUFYX0tFWVMpXG4gICAgICAgIC5tYXAoKHRhZykgPT4gKHsgcGs6IHsgUzogYnVpbGRJZCB9LCBzazogeyBTOiB0YWcgfSB9KSk7XG4gICAgICAvLyBgVW5wcm9jZXNzZWRLZXlzYCBpcyBEeW5hbW9EQiBkZWNsaW5pbmcgcGFydCBvZiB0aGUgYmF0Y2ggdW5kZXIgbG9hZDtcbiAgICAgIC8vIGEgbWFya2VyIGxlZnQgdW5yZWFkIGlzIGEgcmV2YWxpZGF0aW9uIG1pc3NlZCwgc28gaXQgaXMgYXNrZWQgYWdhaW4uXG4gICAgICBmb3IgKGxldCBhdHRlbXB0ID0gMDsga2V5cz8ubGVuZ3RoICYmIGF0dGVtcHQgPCAzOyBhdHRlbXB0KyspIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2U6IEJhdGNoR2V0SXRlbUNvbW1hbmRPdXRwdXQgPSBhd2FpdCB0aGlzLmNsaWVudC5zZW5kKFxuICAgICAgICAgIG5ldyBCYXRjaEdldEl0ZW1Db21tYW5kKHtcbiAgICAgICAgICAgIFJlcXVlc3RJdGVtczoge1xuICAgICAgICAgICAgICBbdGFibGVOYW1lXToge1xuICAgICAgICAgICAgICAgIEtleXM6IGtleXMsXG4gICAgICAgICAgICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246IFwic2ssIHJldmFsaWRhdGVkQXQsIHN0YWxlQXQsIGV4cGlyZWRBdFwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHJlc3BvbnNlLlJlc3BvbnNlcz8uW3RhYmxlTmFtZV0gPz8gW10pIHtcbiAgICAgICAgICBjb25zdCB0YWcgPSBpdGVtLnNrPy5TO1xuICAgICAgICAgIGlmICh0YWcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbWFya2Vycy5zZXQodGFnLCBtYXJrZXJPZihpdGVtKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGtleXMgPSByZXNwb25zZS5VbnByb2Nlc3NlZEtleXM/Llt0YWJsZU5hbWVdPy5LZXlzO1xuICAgICAgfVxuICAgICAgaWYgKGtleXM/Lmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYER5bmFtb0RCIGxlZnQgJHtrZXlzLmxlbmd0aH0gdGFnIG1hcmtlcnMgdW5yZWFkIGFmdGVyIHJldHJ5aW5nYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hcmtlcnM7XG4gIH1cbn1cblxuLyoqXG4gKiBIb3cgbG9uZyBhIHJldmFsaWRhdGlvbiBsb2cgcm93IGlzIGtlcHQgKGB0dGxgLCBlcG9jaCBzZWNvbmRzKS4gRHluYW1vREIgbmV2ZXJcbiAqIGRlbGV0ZXMgYW4gaXRlbSBiZWZvcmUgaXRzIFRUTCwgb25seSBzb21lIHRpbWUgYWZ0ZXIsIHNvIGEgcmVhZGVyIHRoYXQgbGFzdFxuICogcXVlcmllZCBsZXNzIHRoYW4gdGhpcyBsb25nIGFnbyAobGVzcyBhIG1hcmdpbiBmb3Igd3JpdGVycycgY2xvY2tzKSBpcyBzdXJlXG4gKiB0byBmaW5kIGV2ZXJ5IHJvdyBpdCBoYXMgbm90IHNlZW4geWV0LlxuICovXG5leHBvcnQgY29uc3QgUkVWQUxJREFUSU9OX0xPR19UVExfTVMgPSAxNSAqIDYwICogMTAwMDtcblxuLyoqIFRoZSBtb3N0IGBRdWVyeWAgcGFnZXMgb25lIHtAbGluayBSZXZhbGlkYXRpb25Mb2cucXVlcnl9IHJlYWRzLiAqL1xuZXhwb3J0IGNvbnN0IFJFVkFMSURBVElPTl9MT0dfTUFYX1BBR0VTID0gNTtcblxuLyoqIEhvdyBtYW55IHNvcnQga2V5cyB7QGxpbmsgUmV2YWxpZGF0aW9uTG9nLnB1dH0gdHJpZXMgYmVmb3JlIGdpdmluZyB1cC4gKi9cbmNvbnN0IExPR19QVVRfQVRURU1QVFMgPSA1O1xuXG4vKiogRGlnaXRzIGEgbG9nIHJvdydzIHRpbWVzdGFtcCBpcyB6ZXJvLXBhZGRlZCB0bywgc28gc29ydCBrZXlzIHNvcnQgYnkgdGltZS4gKi9cbmNvbnN0IExPR19TS19ESUdJVFMgPSAxNTtcblxuLyoqIEEgcmV2YWxpZGF0aW9uIHJlYWQgYmFjayBmcm9tIHRoZSBsb2cuICovXG5leHBvcnQgaW50ZXJmYWNlIFJldmFsaWRhdGlvbkxvZ1JvdyB7XG4gIC8qKiBUaGUgcm93J3Mgc29ydCBrZXk6IHVuaXF1ZSBwZXIgcmV2YWxpZGF0aW9uIG9mIGEgdGFnLiAqL1xuICBzazogc3RyaW5nO1xuICAvKiogV2hlbiBpdCB3YXMgd3JpdHRlbiwgb24gdGhlIHdyaXRlcidzIGBEYXRlLm5vdygpYC4gKi9cbiAgYXQ6IG51bWJlcjtcbiAgdGFnOiBzdHJpbmc7XG4gIC8qKiBUaGUgbWFya2VyIGZpZWxkcyB0aGUgcmV2YWxpZGF0aW9uIHNldCwgYXMge0BsaW5rIG1hcmtlckZvcn0gcmV0dXJucyB0aGVtLiAqL1xuICBtYXJrZXI6IFRhZ01hcmtlcjtcbn1cblxuLyoqXG4gKiBUaGUgcmV2YWxpZGF0aW9uIGxvZzogb25lIHJvdyBwZXIgdGFnIHJldmFsaWRhdGlvbiAoYHBrID0gPGJ1aWxkSWQ+I2xvZ2AsXG4gKiBgc2sgPSA8RGF0ZS5ub3coKSwgemVyby1wYWRkZWQ+Izx0YWc+YCksIHdoaWNoIGV4cGlyZXMgYWZ0ZXJcbiAqIHtAbGluayBSRVZBTElEQVRJT05fTE9HX1RUTF9NU30uXG4gKlxuICogVGhlIG1hcmtlciByb3dzIHN0YXkgdGhlIHNvdXJjZSBvZiB0cnV0aC4gVGhlIGxvZyBleGlzdHMgc28gYW4gaW5zdGFuY2VcbiAqIGNhbiBhc2sgXCJ3aGF0IHdhcyByZXZhbGlkYXRlZCBzaW5jZSBJIGxhc3QgbG9va2VkP1wiIGluIG9uZSBgUXVlcnlgLCBpbnN0ZWFkXG4gKiBvZiByZS1yZWFkaW5nIGV2ZXJ5IHRhZyBpdCB0cmFja3MgdG8gZmluZCBvdXQgdGhhdCBhbG1vc3Qgbm9uZSBjaGFuZ2VkLiBFdmVyeVxuICogbWFya2VyIHJvdyBvZiBhIGRlcGxveW1lbnQgc2hhcmVzIG9uZSBwYXJ0aXRpb24sIGFuZCB0aG9zZSByZS1yZWFkcyBmcm9tIGFcbiAqIGhhbmRmdWwgb2YgYnVzeSBpbnN0YW5jZXMgd2VyZSBlbm91Z2ggdG8gdGhyb3R0bGUgaXQuXG4gKlxuICogVGhlIHNvcnQga2V5J3MgdGltZXN0YW1wIGlzIHRoZSB3cml0ZXIncyB3YWxsIGNsb2NrIChgRGF0ZS5ub3coKWApLCBub3QgdGhlXG4gKiBwZXJmb3JtYW5jZSBjbG9jayAoe0BsaW5rIG1hcmtlckNsb2NrfSkgdGhlIG1hcmtlciB2YWx1ZXMgYXJlIHN0YW1wZWQgd2l0aCBieSBib3RoXG4gKiBoYW5kbGVyczogaXQgb25seSBvcmRlcnMgcm93cyBmb3IgcmVhZGVycycgY3Vyc29ycywgd2hpY2ggYXJlIG9uIHRoZWlyIG93blxuICogd2FsbCBjbG9ja3MsIGFuZCBpcyBuZXZlciBjb21wYXJlZCB3aXRoIGFuIGVudHJ5J3MgdGltZXN0YW1wLlxuICovXG5leHBvcnQgY2xhc3MgUmV2YWxpZGF0aW9uTG9nIHtcbiAgcHJpdmF0ZSByZWFkb25seSBwazogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBEeW5hbW9EQkNsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGJ1aWxkSWQ6IHN0cmluZyxcbiAgKSB7XG4gICAgdGhpcy5wayA9IGAke2J1aWxkSWR9I2xvZ2A7XG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkIHRoYXQgYHRhZ2Agd2FzIHJldmFsaWRhdGVkIGF0IGBhdGAgKGBEYXRlLm5vdygpYCksIHNldHRpbmcgYG1hcmtlcmAuXG4gICAqXG4gICAqIFR3byByZXZhbGlkYXRpb25zIG9mIGB0YWdgIGluIHRoZSBzYW1lIG1pbGxpc2Vjb25kIHdvdWxkIHNoYXJlIGEgc29ydCBrZXksXG4gICAqIGFuZCB0aGUgc2Vjb25kIHdvdWxkIG92ZXJ3cml0ZSB0aGUgZmlyc3QuIFNvIHRoZSByb3cgaXMgb25seSB3cml0dGVuIHdoZXJlXG4gICAqIGl0cyBrZXkgaXMgZnJlZSwgYW5kIG9uIGEgY29sbGlzaW9uIGl0IG1vdmVzIHRvIHRoZSBuZXh0IG1pbGxpc2Vjb25kLCB1cFxuICAgKiB0byB7QGxpbmsgTE9HX1BVVF9BVFRFTVBUU30gdGltZXMuXG4gICAqL1xuICBhc3luYyBwdXQodGFnOiBzdHJpbmcsIGF0OiBudW1iZXIsIG1hcmtlcjogVGFnTWFya2VyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IDsgYXR0ZW1wdCsrKSB7XG4gICAgICBjb25zdCBpdGVtOiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4gPSB7XG4gICAgICAgIHBrOiB7IFM6IHRoaXMucGsgfSxcbiAgICAgICAgc2s6IHsgUzogYCR7bG9nU2tQcmVmaXgoYXQpfSMke3RhZ31gIH0sXG4gICAgICAgIHR0bDogeyBOOiBTdHJpbmcoTWF0aC5jZWlsKChhdCArIFJFVkFMSURBVElPTl9MT0dfVFRMX01TKSAvIDEwMDApKSB9LFxuICAgICAgfTtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgTUFSS0VSX0ZJRUxEUykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG1hcmtlcltmaWVsZF07XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaXRlbVtmaWVsZF0gPSB7IE46IFN0cmluZyh2YWx1ZSkgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgICBuZXcgUHV0SXRlbUNvbW1hbmQoe1xuICAgICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICAgIEl0ZW06IGl0ZW0sXG4gICAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiBcImF0dHJpYnV0ZV9ub3RfZXhpc3RzKHNrKVwiLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKGVycm9yIGFzIEVycm9yIHwgdW5kZWZpbmVkKT8ubmFtZSAhPT1cbiAgICAgICAgICAgIFwiQ29uZGl0aW9uYWxDaGVja0ZhaWxlZEV4Y2VwdGlvblwiIHx8XG4gICAgICAgICAgYXR0ZW1wdCA+PSBMT0dfUFVUX0FUVEVNUFRTXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGF0ID0gTWF0aC5mbG9vcihhdCkgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcm93cyB3cml0dGVuIGF0IG9yIGFmdGVyIGBzaW5jZWAgKGBEYXRlLm5vdygpYCksIG9sZGVzdCBmaXJzdC5cbiAgICogYHRydW5jYXRlZGAgd2hlbiB0aGVyZSB3ZXJlIG1vcmUgdGhhbiB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19NQVhfUEFHRVN9XG4gICAqIHBhZ2VzIG9mIHRoZW0sIGFuZCBgcm93c2AgaXMgb25seSB0aGUgc3RhcnQuXG4gICAqXG4gICAqIEV2ZW50dWFsbHkgY29uc2lzdGVudDogYSByb3cgd3JpdHRlbiBhIG1vbWVudCBhZ28gbWF5IG5vdCBzaG93IHlldCwgd2hpY2hcbiAgICogaXMgd2hhdCB0aGUgcmVhZGVyJ3MgbG9va2JhY2sgaXMgZm9yLlxuICAgKi9cbiAgYXN5bmMgcXVlcnkoXG4gICAgc2luY2U6IG51bWJlcixcbiAgKTogUHJvbWlzZTx7IHJvd3M6IFJldmFsaWRhdGlvbkxvZ1Jvd1tdOyB0cnVuY2F0ZWQ6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IHJvd3M6IFJldmFsaWRhdGlvbkxvZ1Jvd1tdID0gW107XG4gICAgbGV0IHN0YXJ0S2V5OiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4gfCB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgcGFnZSA9IDA7IHBhZ2UgPCBSRVZBTElEQVRJT05fTE9HX01BWF9QQUdFUzsgcGFnZSsrKSB7XG4gICAgICBjb25zdCByZXNwb25zZTogUXVlcnlDb21tYW5kT3V0cHV0ID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgbmV3IFF1ZXJ5Q29tbWFuZCh7XG4gICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICBLZXlDb25kaXRpb25FeHByZXNzaW9uOiBcInBrID0gOnBrIEFORCBzayA+PSA6c2luY2VcIixcbiAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiB7XG4gICAgICAgICAgICBcIjpwa1wiOiB7IFM6IHRoaXMucGsgfSxcbiAgICAgICAgICAgIFwiOnNpbmNlXCI6IHsgUzogbG9nU2tQcmVmaXgoTWF0aC5tYXgoMCwgc2luY2UpKSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246IFwic2ssIHJldmFsaWRhdGVkQXQsIHN0YWxlQXQsIGV4cGlyZWRBdFwiLFxuICAgICAgICAgIEV4Y2x1c2l2ZVN0YXJ0S2V5OiBzdGFydEtleSxcbiAgICAgICAgfSksXG4gICAgICApO1xuICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHJlc3BvbnNlLkl0ZW1zID8/IFtdKSB7XG4gICAgICAgIGNvbnN0IHNrID0gaXRlbS5zaz8uUztcbiAgICAgICAgLy8gYDxkaWdpdHM+Izx0YWc+YDogdGhlIHRhZyBpcyBldmVyeXRoaW5nIGFmdGVyIHRoZSBmaXhlZC13aWR0aFxuICAgICAgICAvLyB0aW1lc3RhbXAsIGAjYHMgaW5jbHVkZWQuXG4gICAgICAgIGlmIChzayA9PT0gdW5kZWZpbmVkIHx8IHNrW0xPR19TS19ESUdJVFNdICE9PSBcIiNcIikge1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgICB9XG4gICAgICAgIHJvd3MucHVzaCh7XG4gICAgICAgICAgc2ssXG4gICAgICAgICAgYXQ6IE51bWJlcihzay5zbGljZSgwLCBMT0dfU0tfRElHSVRTKSksXG4gICAgICAgICAgdGFnOiBzay5zbGljZShMT0dfU0tfRElHSVRTICsgMSksXG4gICAgICAgICAgbWFya2VyOiBtYXJrZXJPZihpdGVtKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBzdGFydEtleSA9IHJlc3BvbnNlLkxhc3RFdmFsdWF0ZWRLZXk7XG4gICAgICBpZiAoIXN0YXJ0S2V5KSB7XG4gICAgICAgIHJldHVybiB7IHJvd3MsIHRydW5jYXRlZDogZmFsc2UgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgcm93cywgdHJ1bmNhdGVkOiB0cnVlIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gbG9nU2tQcmVmaXgoYXQ6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBTdHJpbmcoTWF0aC5mbG9vcihhdCkpLnBhZFN0YXJ0KExPR19TS19ESUdJVFMsIFwiMFwiKTtcbn1cblxuLyoqXG4gKiBIb3cgZmFyIGJlaGluZCB0aGUgbGFzdCBxdWVyeSdzIHN0YXJ0IHRoZSBuZXh0IG9uZSBzdGFydHMgcmVhZGluZyB0aGUgbG9nOlxuICogdGhlIHJvb20gZm9yIHRoZSBgUXVlcnlgIGJlaW5nIGV2ZW50dWFsbHkgY29uc2lzdGVudCBhbmQgZm9yIHdyaXRlcnMnIGNsb2Nrc1xuICogcnVubmluZyBiZWhpbmQgdGhlIHJlYWRlcidzLiBSb3dzIGluc2lkZSBpdCBhcmUgcmVhZCBhZ2FpbiwgYW5kIGRyb3BwZWQgYXNcbiAqIGFscmVhZHkgYXBwbGllZC5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVMgPSA1MDAwO1xuXG4vKipcbiAqIFRoZSBsb25nZXN0IHtAbGluayBUcmFja2VkVGFnTWFya2Vyc30gdHJ1c3RzIHRoZSBsb2cgYWxvbmUgZm9yIGEgdGFnIGJlZm9yZVxuICogcmVhZGluZyBpdHMgbWFya2VyIHJvdyBhZ2Fpbi4gVGhlIGxvZyBpcyB0aGUgZmFzdCBwYXRoLCBidXQgdGhlIG1hcmtlciByb3dzXG4gKiBhcmUgdGhlIHNvdXJjZSBvZiB0cnV0aDogYSBsb2cgcm93IHdob3NlIHdyaXRlIGZhaWxlZCB3b3VsZCBvdGhlcndpc2UgYmVcbiAqIG1pc3NlZCBmb3IgYXMgbG9uZyBhcyB0aGUgdGFnIHN0YXlzIHRyYWNrZWQuXG4gKlxuICogUm9sbGluZywgbm90IGFsbCBhdCBvbmNlOiBlYWNoIHJlZnJlc2ggcmUtcmVhZHMgYXQgbW9zdFxuICoge0BsaW5rIEJBVENIX0dFVF9NQVhfS0VZU30gb2YgdGhlIHRhZ3MgZHVlLCBvbGRlc3QgZmlyc3QuIFJlLXJlYWRpbmcgdGhlbSBhbGxcbiAqIHRvZ2V0aGVyIGNvc3QgfjUwMCBSQ1UgYXQgMTAwMCB0YWdzIC0gYSBmbGVldCBzdGFydGVkIGJ5IG9uZSBsb2FkIHRlc3QgZGlkIGl0XG4gKiBpbiB0aGUgc2FtZSBtaW51dGUsIDEyLDgwMCBSQ1UsIGFuZCB0aHJvdHRsZWQgLSBhbmQgd291bGQgYmUgfjUsMDAwIFJDVSBhdFxuICoge0BsaW5rIERFRkFVTFRfTUFYX1RSQUNLRURfVEFHU30sIHBhc3Qgd2hhdCB0aGUgb25lIHBhcnRpdGlvbiBzZXJ2ZXMgaW4gYVxuICogc2Vjb25kLiBTcHJlYWQgb3V0LCAxMCwwMDAgdHJhY2tlZCB0YWdzIGNvc3QgfjggUkNVIGEgc2Vjb25kIHBlciBpbnN0YW5jZS5cbiAqXG4gKiBFYWNoIHRhZyBpcyBkdWUgYXQgYSByYW5kb20gNzUtMTAwJSBvZiB0aGlzIGFmdGVyIGl0IHdhcyBsYXN0IHJlYWQsIHNvIHRhZ3NcbiAqIGZpcnN0IHJlYWQgdG9nZXRoZXIgLSBhbiBpbnN0YW5jZSB3YXJtaW5nIHVwIC0gZG8gbm90IGFsbCBjb21lIGR1ZSB0b2dldGhlclxuICogYWdhaW4gZXZlcnkgaW50ZXJ2YWw6IHRoZSBsb2FkIHRlc3QgdGhhdCBtZWFzdXJlZCB0aGUgcm9sbGluZyByZS1yZWFkIHNhd1xuICogaXRzIHdhcm0tdXAncyByZWFkcyByZXR1cm4gYXMgYSAzMC0zNiBSQ1UvcyBidW1wIHRlbiBtaW51dGVzIGxhdGVyLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9UQUdfUkVTWU5DX01TID0gMTAgKiA2MCAqIDEwMDA7XG5cbi8qKiBUaGUgZnJhY3Rpb24gb2Yge0BsaW5rIERFRkFVTFRfVEFHX1JFU1lOQ19NU30gYSB0YWcgbWF5IGNvbWUgZHVlIGVhcmx5IGJ5LiAqL1xuY29uc3QgVEFHX1JFU1lOQ19KSVRURVIgPSAwLjI1O1xuXG4vKipcbiAqIEhvdyBsb25nIHNpbmNlIHRoZSBsYXN0IHN1Y2Nlc3NmdWwgbG9nIHF1ZXJ5IHRoZSBsb2cgY2FuIHN0aWxsIGJlIHRydXN0ZWQgdG9cbiAqIGhvbGQgZXZlcnkgcm93IG5vdCByZWFkIHlldDogaXRzIFRUTCBsZXNzIGEgbWFyZ2luIGZvciB3cml0ZXJzJyBjbG9ja3MuIFBhc3RcbiAqIGl0IC0gYSBMYW1iZGEgZnJvemVuIGJldHdlZW4gaW52b2NhdGlvbnMsIGEgcnVuIG9mIGZhaWxlZCBxdWVyaWVzIC0gdGhlXG4gKiB0cmFja2VkIG1hcmtlcnMgYXJlIGZvcmdvdHRlbiwgdG8gYmUgcmVhZCBhZ2FpbiBhcyB0aGV5IGFyZSBuZWVkZWQsIGFuZCB0aGVcbiAqIGxvZyBpcyBmb2xsb3dlZCBmcm9tIHRoZXJlLlxuICovXG5leHBvcnQgY29uc3QgTUFYX1JFVkFMSURBVElPTl9MT0dfR0FQX01TID1cbiAgUkVWQUxJREFUSU9OX0xPR19UVExfTVMgLSA1ICogNjAgKiAxMDAwO1xuXG4vKipcbiAqIFRoZSBtb3N0IHRhZ3Mgb25lIGluc3RhbmNlIHRyYWNrcy4gUGFzdCBpdCB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZCBpc1xuICogZm9yZ290dGVuLCB3aGljaCBjb3N0cyBhIHJlYWQgdGhlIG5leHQgdGltZSBpdCBpcyBuZWVkZWQ6IGFuIHVudHJhY2tlZCB0YWdcbiAqIGlzIHJlYWQgYmVmb3JlIGl0IGlzIHRydXN0ZWQuXG4gKlxuICogQSB0cmFja2VkIHRhZyBjb3N0cyBtZW1vcnkgKH4yIE1CIGF0IHRoaXMgYm91bmQpIGFuZCBpdHMgc2hhcmUgb2YgdGhlIHJvbGxpbmdcbiAqIHJlLXJlYWQsIG5vdCBhIHJlYWQgZXZlcnkgcmVmcmVzaCwgc28gdGhlIGJvdW5kIGlzIHNldCBieSBob3cgbWFueSB0YWdzIGFuXG4gKiBpbnN0YW5jZSByZWFsbHkgdXNlcy4gRXZlcnkgcGF0aCBpcyBhIHRhZyBvZiBpdHMgb3duIChgX05fVF8vPHBhdGg+YCksIGFuZCBhdFxuICogMTAwMCBhbiBhcHAgb2YgMTAwMCB0YWdnZWQgcGFnZXMga2VwdCBldmljdGluZyB3aGF0IGl0IHdhcyBhYm91dCB0byBuZWVkOlxuICogaGFsZiBpdHMgcmVxdWVzdHMgcmUtcmVhZCBhIG1hcmtlci5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTUFYX1RSQUNLRURfVEFHUyA9IDEwXzAwMDtcblxuLyoqXG4gKiBUaGUgcmV2YWxpZGF0aW9uIHRhYmxlJ3MgbWFya2VyIHJvd3MgYW5kIGl0cyBsb2csIHdoaWNoIGFyZSBvbmx5IGV2ZXIgdXNlZFxuICogdG9nZXRoZXIsIG9yIG5laXRoZXIgZm9yIHRhZ3MgbG9jYWwgdG8gdGhpcyBwcm9jZXNzLlxuICovXG5leHBvcnQgdHlwZSBUYWdUYWJsZSA9XG4gIHwgeyBtYXJrZXJzOiBUYWdNYXJrZXJUYWJsZTsgbG9nOiBSZXZhbGlkYXRpb25Mb2cgfVxuICB8IHsgbWFya2Vycz86IHVuZGVmaW5lZDsgbG9nPzogdW5kZWZpbmVkIH07XG5cbi8qKiBIb3cge0BsaW5rIFRyYWNrZWRUYWdNYXJrZXJzfSBpcyBidWlsdC4gKi9cbmV4cG9ydCB0eXBlIFRyYWNrZWRUYWdNYXJrZXJzT3B0aW9ucyA9IFRhZ1RhYmxlICYge1xuICAvKipcbiAgICogSG93IG9mdGVuLCBhdCBtb3N0LCB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnMucmVmcmVzaH0gcmVhZHMgYW55dGhpbmcuXG4gICAqIEBkZWZhdWx0IERFRkFVTFRfVEFHX1JFRlJFU0hfTVNcbiAgICovXG4gIHJlZnJlc2hJbnRlcnZhbE1zPzogbnVtYmVyO1xuICBtYXhUcmFja2VkVGFncz86IG51bWJlcjtcbiAgLyoqIEBzZWUgREVGQVVMVF9UQUdfUkVTWU5DX01TICovXG4gIHJlc3luY0ludGVydmFsTXM/OiBudW1iZXI7XG4gIC8qKiBUaGUgd2FsbCBjbG9jayB0aGUgbG9nJ3MgY3Vyc29yIGFuZCB0aGUgaW50ZXJ2YWxzIGFyZSBrZXB0IG9uLiAqL1xuICBjbG9jaz86ICgpID0+IG51bWJlcjtcbiAgLyoqIGBNYXRoLnJhbmRvbWAsIGZvciB3aGVuIGVhY2ggdGFnJ3MgcmUtcmVhZCBjb21lcyBkdWUuICovXG4gIHJhbmRvbT86ICgpID0+IG51bWJlcjtcbiAgZGVidWc/OiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkO1xufTtcblxuLyoqXG4gKiBPbmUgaW5zdGFuY2UncyBjb3B5IG9mIHRoZSBtYXJrZXIgcm93cyBvZiB0aGUgdGFncyBpdCBoYXMgbmVlZGVkLCBrZXB0XG4gKiBjdXJyZW50IHRocm91Z2ggdGhlIHtAbGluayBSZXZhbGlkYXRpb25Mb2d9OiB0aGUgcHJvY2VzcydzIG9uZSB0YWcgbWFuaWZlc3RcbiAqIChgc2hhcmVkVGFnTWFuaWZlc3RgKSwgZm9yIHRoZSBgJ3VzZSBjYWNoZSdgIGhhbmRsZXJzIGFuZCB0aGUgaW5jcmVtZW50YWxcbiAqIGNhY2hlIGFsaWtlLlxuICpcbiAqIE5leHQuanMncyBidWlsdC1pbiBgJ3VzZSBjYWNoZSdgIGhhbmRsZXIga2VlcHMgdGFncyBpbiBhIG1vZHVsZS1sZXZlbCBtYXBcbiAqIChgdGFncy1tYW5pZmVzdC5leHRlcm5hbC5qc2ApIHRoYXQgb25seSBpdHMgb3duIGB1cGRhdGVUYWdzYCB3cml0ZXMsIGFuZCBpdHNcbiAqIGByZWZyZXNoVGFnc2AgaXMgYSBuby1vcCwgc28gYSBgcmV2YWxpZGF0ZVRhZ2Agb24gb25lIGluc3RhbmNlIG5ldmVyIHJlYWNoZXNcbiAqIHRoZSBvdGhlcnM6IHRoZXkga2VlcCBzZXJ2aW5nIHRoZSByZXZhbGlkYXRlZCBlbnRyeSwgaW5jbHVkaW5nIGluc2lkZSBwYWdlc1xuICogdGhhdCBhcmUgYmVpbmcgcmUtcmVuZGVyZWQgKmJlY2F1c2UqIG9mIHRoYXQgcmV2YWxpZGF0aW9uLiBUaGVcbiAqIGBjYWNoZUhhbmRsZXJzYCBpbnRlcmZhY2UncyBhbnN3ZXIgaXMgYHJlZnJlc2hUYWdzYCwgXCJjYWxsZWQgYmVmb3JlIHN0YXJ0aW5nXG4gKiBhIG5ldyByZXF1ZXN0IOKApiB0byByZWZyZXNoIHRoZSBsb2NhbCB0YWdzIG1hbmlmZXN0XCIsIGFuZCB0aGlzIGlzIHRoYXRcbiAqIG1hbmlmZXN0LCBiYWNrZWQgYnkgdGhlIHNhbWUgbWFya2VyIHJvd3MgdGhlIGluY3JlbWVudGFsIGNhY2hlJ3NcbiAqIGByZXZhbGlkYXRlVGFnYCB3cml0ZXMgKGBwayA9IGJ1aWxkSWRgLCBgc2sgPSB0YWdgKS5cbiAqXG4gKiBUaGUgY29zdCBpcyBib3VuZGVkIHBlciBpbnN0YW5jZSwgbm90IHBlciByZXF1ZXN0OlxuICogLSB7QGxpbmsgZW5zdXJlfSByZWFkcyBhIHRhZydzIG1hcmtlciB0aGUgZmlyc3QgdGltZSBpdCBpcyBuZWVkZWQgYW5kIG5vdFxuICogICBhZ2FpbiB1bnRpbCBpdCBpcyBldmljdGVkLCBzbyBhIHRhZyBjb3N0cyBvbmUgcmVhZCBwZXIgaW5zdGFuY2UsIG5vdCBvbmVcbiAqICAgcGVyIHJlcXVlc3QuXG4gKiAtIHtAbGluayByZWZyZXNofSwgYXQgbW9zdCBvbmNlIHBlciBgcmVmcmVzaEludGVydmFsTXNgLCBzZW5kcyBvbmUgYFF1ZXJ5YFxuICogICBmb3IgdGhlIGxvZyByb3dzIHdyaXR0ZW4gc2luY2UgdGhlIGxhc3Qgb25lLCBhbmQgYXBwbGllcyB0aG9zZSBvZiB0YWdzXG4gKiAgIHRoaXMgaW5zdGFuY2UgdHJhY2tzLiBDb25jdXJyZW50IGNhbGxlcnMgc2hhcmUgaXQuIEFsb25nc2lkZSwgaXQgcmUtcmVhZHNcbiAqICAgdGhlIG1hcmtlcnMgb2YgdXAgdG8ge0BsaW5rIEJBVENIX0dFVF9NQVhfS0VZU30gdGFncyBub3QgcmVhZCBmb3JcbiAqICAge0BsaW5rIERFRkFVTFRfVEFHX1JFU1lOQ19NU30sIGluIG9uZSBgQmF0Y2hHZXRJdGVtYC5cbiAqIEEgcmV2YWxpZGF0aW9uIG9uIGFub3RoZXIgaW5zdGFuY2UgaXMgdGhlcmVmb3JlIHNlZW4gd2l0aGluXG4gKiBgcmVmcmVzaEludGVydmFsTXNgIChwbHVzIHRoZSBxdWVyeSBpdHNlbGYpLiBUaGUgaW5zdGFuY2UgdGhhdCByYW4gaXQgYXBwbGllc1xuICogaXQgaXRzZWxmLCBhdCBvbmNlLCB3aXRoIHtAbGluayBzZXR9LlxuICovXG5leHBvcnQgY2xhc3MgVHJhY2tlZFRhZ01hcmtlcnMge1xuICBwcml2YXRlIHJlYWRvbmx5IG1hcmtlcnM6IFRhZ01hcmtlclRhYmxlIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZzogUmV2YWxpZGF0aW9uTG9nIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZnJlc2hJbnRlcnZhbE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VHJhY2tlZFRhZ3M6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSByZXN5bmNJbnRlcnZhbE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xvY2s6ICgpID0+IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSByYW5kb206ICgpID0+IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWJ1ZzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZDtcbiAgLyoqIEJ5IHRhZywgbGVhc3QgcmVjZW50bHkgdXNlZCBmaXJzdC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0YWdzID0gbmV3IE1hcDxzdHJpbmcsIFRhZ01hcmtlcj4oKTtcbiAgLyoqXG4gICAqIFdoZW4gZWFjaCB0cmFja2VkIHRhZydzIG1hcmtlciBpcyBkdWUgdG8gYmUgcmVhZCBhZ2FpbjogYSByYW5kb20gNzUtMTAwJVxuICAgKiBvZiBgcmVzeW5jSW50ZXJ2YWxNc2AgYWZ0ZXIgaXQgd2FzIGxhc3Qga25vd24gZnJvbSB0aGUgdGFibGUgLSByZWFkLFxuICAgKiB3cml0dGVuIGhlcmUsIG9yIG5ldy4gSW4gdGhlIG9yZGVyIHRoZXkgYmVjYW1lIGtub3duLCBsZWFzdCByZWNlbnQgZmlyc3QuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGR1ZUF0ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSByZWFkaW5nID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8dm9pZD4+KCk7XG4gIC8qKlxuICAgKiBMb2cgcm93cyBmb3IgdGFncyB3aG9zZSBmaXJzdCByZWFkIGlzIGluIGZsaWdodCwgbWVyZ2VkIGJ5IHRhZzogdGhlIHJlYWRcbiAgICogbWF5IGhhdmUgYmVlbiBhbnN3ZXJlZCBiZWZvcmUgdGhlIHJldmFsaWRhdGlvbiwgc28gdGhleSBhcmUgYXBwbGllZCB0byBpdHNcbiAgICogcmVzdWx0IHJhdGhlciB0aGFuIGRyb3BwZWQuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHBlbmRpbmdSb3dzID0gbmV3IE1hcDxzdHJpbmcsIFRhZ01hcmtlcj4oKTtcbiAgLyoqIFRyYWNrZWQgdGFncyB3aG9zZSByZWFkIGZhaWxlZCwgZm9yIHRoZSBuZXh0IHJlZnJlc2ggdG8gcmVhZCBhZ2Fpbi4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB1bnJlYWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgcHJpdmF0ZSBsYXN0UmVmcmVzaCA9IC1JbmZpbml0eTtcbiAgcHJpdmF0ZSByZWZyZXNoaW5nOiBQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogV2hlcmUgdGhlIG5leHQgbG9nIHF1ZXJ5IHN0YXJ0cyAoYGNsb2NrKClgKTogdGhlIGxhc3Qgc3VjY2Vzc2Z1bCBvbmUnc1xuICAgKiBzdGFydCwgbGVzcyB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NU30uXG4gICAqL1xuICBwcml2YXRlIGN1cnNvcjogbnVtYmVyO1xuICAvKiogV2hlbiB0aGUgbGFzdCBzdWNjZXNzZnVsIGxvZyBxdWVyeSBzdGFydGVkLCBvciB0aGUgbG9nIHdhcyBmaXJzdCByZWFkLiAqL1xuICBwcml2YXRlIGxhc3RMb2dSZWFkOiBudW1iZXI7XG4gIC8qKiBMb2cgcm93cyBhdCBvciBhZnRlciB0aGUgY3Vyc29yIGFscmVhZHkgYXBwbGllZCwgYnkgc29ydCBrZXkuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwbGllZCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiB7QGxpbmsgdXBkYXRlfXMgb2YgdGhlIGN1cnJlbnQgdHVybiwgYnkgdGhlaXIgYXJndW1lbnRzLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHVwZGF0aW5nID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8Ym9vbGVhbj4+KCk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogVHJhY2tlZFRhZ01hcmtlcnNPcHRpb25zKSB7XG4gICAgdGhpcy5tYXJrZXJzID0gb3B0aW9ucy5tYXJrZXJzO1xuICAgIHRoaXMubG9nID0gb3B0aW9ucy5sb2c7XG4gICAgdGhpcy5yZWZyZXNoSW50ZXJ2YWxNcyA9XG4gICAgICBvcHRpb25zLnJlZnJlc2hJbnRlcnZhbE1zID8/IERFRkFVTFRfVEFHX1JFRlJFU0hfTVM7XG4gICAgdGhpcy5tYXhUcmFja2VkVGFncyA9IG9wdGlvbnMubWF4VHJhY2tlZFRhZ3MgPz8gREVGQVVMVF9NQVhfVFJBQ0tFRF9UQUdTO1xuICAgIHRoaXMucmVzeW5jSW50ZXJ2YWxNcyA9IG9wdGlvbnMucmVzeW5jSW50ZXJ2YWxNcyA/PyBERUZBVUxUX1RBR19SRVNZTkNfTVM7XG4gICAgLy8gTG9va2VkIHVwIG9uIGVhY2ggY2FsbCByYXRoZXIgdGhhbiBib3VuZCBoZXJlLCBzbyBhIHRlc3QncyBgRGF0ZS5ub3dgXG4gICAgLy8gc3B5IGFwcGxpZXMuXG4gICAgdGhpcy5jbG9jayA9IG9wdGlvbnMuY2xvY2sgPz8gKCgpID0+IERhdGUubm93KCkpO1xuICAgIHRoaXMucmFuZG9tID0gb3B0aW9ucy5yYW5kb20gPz8gTWF0aC5yYW5kb207XG4gICAgdGhpcy5kZWJ1ZyA9IG9wdGlvbnMuZGVidWcgPz8gKCgpID0+IHt9KTtcbiAgICAvLyBOb3RoaW5nIGlzIHRyYWNrZWQgeWV0LCBzbyBub3RoaW5nIGJlZm9yZSB0aGlzIGNhbiBiZSBtaXNzZWQ6IGV2ZXJ5IHRhZ1xuICAgIC8vIGlzIHJlYWQgZnJvbSBpdHMgbWFya2VyIHRoZSBmaXJzdCB0aW1lIGl0IGlzIG5lZWRlZC5cbiAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICB0aGlzLmN1cnNvciA9IGF0IC0gUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUztcbiAgICB0aGlzLmxhc3RMb2dSZWFkID0gYXQ7XG4gIH1cblxuICAvKiogYHRhZ2AncyBtYXJrZXIgYXMgdGhpcyBpbnN0YW5jZSBrbm93cyBpdCwgaWYgaXQgdHJhY2tzIGB0YWdgLiAqL1xuICBnZXQodGFnOiBzdHJpbmcpOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRhZ3MuZ2V0KHRhZyk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2sgYHRhZ2Agd2l0aCBgbWFya2VyYDogd2hhdCB0aGlzIGluc3RhbmNlIGp1c3Qgd3JvdGUsIHdoaWNoIGl0IGtub3dzXG4gICAqIHdpdGhvdXQgcmVhZGluZyBpdCBiYWNrLlxuICAgKi9cbiAgc2V0KHRhZzogc3RyaW5nLCBtYXJrZXI6IFRhZ01hcmtlcik6IHZvaWQge1xuICAgIHRoaXMucmVtZW1iZXIodGFnLCBtYXJrZXIpO1xuICAgIHRoaXMua25vd24odGFnLCB0aGlzLmNsb2NrKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE5vdGUgYSB1c2Ugb2YgYHRhZ3NgOiB0aG9zZSBvZiBhbiBlbnRyeSB0aGlzIGluc3RhbmNlIGp1c3Qgc3RvcmVkLlxuICAgKlxuICAgKiBXaXRoIHRoZSB0YWJsZSwgYSB0YWcgbm90IHRyYWNrZWQgeWV0IGlzIGxlZnQgdW50cmFja2VkLCB0byBiZSByZWFkIGJ5XG4gICAqIHtAbGluayBlbnN1cmV9IHRoZSBmaXJzdCB0aW1lIGFuIGVudHJ5IG5lZWRzIGl0LiBOb3RoaW5nIHJldmFsaWRhdGVkIGJlZm9yZVxuICAgKiB0aGUgbmV3IGVudHJ5IHdhcyBjcmVhdGVkIGFwcGxpZXMgdG8gKml0KiwgYnV0IHRyYWNraW5nIGlzIHBlciB0YWcsIG5vdCBwZXJcbiAgICogZW50cnk6IHRyYWNraW5nIHRoZSB0YWcgd2l0aCBhbiBlbXB0eSBtYXJrZXIgd291bGQgYWxzbyB2b3VjaCBmb3IgZXZlcnlcbiAgICogb2xkZXIgZW50cnkgdGhhdCBjYXJyaWVzIGl0IC0gb25lIGFub3RoZXIgaW5zdGFuY2Ugc3RvcmVkIGluIFMzLCBvciBvbmVcbiAgICogdGhpcyBpbnN0YW5jZSBrZXB0IGluIG1lbW9yeSBhY3Jvc3MgYSB7QGxpbmsgZm9yZ2V0fSAtIGFuZCBhIHJldmFsaWRhdGlvblxuICAgKiBmcm9tIGJlZm9yZSB0aGUgbG9nJ3MgY3Vyc29yIHdvdWxkIGdvIHVuc2VlbiB1bnRpbCB0aGUgcm9sbGluZyByZS1yZWFkLlxuICAgKlxuICAgKiBXaXRob3V0IHRoZSB0YWJsZSBldmVyeSByZXZhbGlkYXRpb24gaXMgdGhpcyBwcm9jZXNzJ3Mgb3duLCBhcHBsaWVkIHdpdGhcbiAgICoge0BsaW5rIHNldH0sIHNvIGEgdGFnIGlzIHRyYWNrZWQgYXQgb25jZS5cbiAgICovXG4gIHRyYWNrKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm1hcmtlcnMpIHtcbiAgICAgIHRoaXMudHJhY2tVbnJlYWQodGFncyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIHRoaXMudG91Y2godGFnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJhY2sgYHRhZ3NgIGFzIHRoZXkgYXJlIGtub3duIG5vdywgd2l0aG91dCByZWFkaW5nIHRoZW0sIHdpdGggYW4gZW1wdHlcbiAgICogbWFya2VyIGZvciBhbnkgbm90IHRyYWNrZWQgeWV0LlxuICAgKi9cbiAgcHJpdmF0ZSB0cmFja1VucmVhZCh0YWdzOiByZWFkb25seSBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIGlmICghdGhpcy50YWdzLmhhcyh0YWcpKSB7XG4gICAgICAgIHRoaXMua25vd24odGFnLCBhdCk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlbWVtYmVyKHRhZywgdGhpcy50YWdzLmdldCh0YWcpID8/IHt9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVhZCB0aGUgbWFya2VycyBvZiB3aGljaGV2ZXIgb2YgYHRhZ3NgIHRoaXMgaW5zdGFuY2UgZG9lcyBub3QgdHJhY2sgeWV0LlxuICAgKiBOZWVkZWQgYmVmb3JlIGp1ZGdpbmcgYW4gZW50cnkgdGhpcyBpbnN0YW5jZSBkaWQgbm90IGNyZWF0ZSwgc2luY2UgaXRzXG4gICAqIHRhZ3MgbWF5IGhhdmUgYmVlbiByZXZhbGlkYXRlZCBhdCBhbnkgdGltZSBiZWZvcmUuXG4gICAqL1xuICBhc3luYyBlbnN1cmUodGFnczogcmVhZG9ubHkgc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMubWFya2Vycykge1xuICAgICAgdGhpcy50cmFja1VucmVhZCh0YWdzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgd2FpdHM6IFByb21pc2U8dm9pZD5bXSA9IFtdO1xuICAgIGNvbnN0IHVucmVhZDogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBuZXcgU2V0KHRhZ3MpKSB7XG4gICAgICBjb25zdCBpbkZsaWdodCA9IHRoaXMucmVhZGluZy5nZXQodGFnKTtcbiAgICAgIGlmIChpbkZsaWdodCkge1xuICAgICAgICB3YWl0cy5wdXNoKGluRmxpZ2h0KTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy50YWdzLmhhcyh0YWcpKSB7XG4gICAgICAgIHRoaXMudG91Y2godGFnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVucmVhZC5wdXNoKHRhZyk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh1bnJlYWQubGVuZ3RoID4gMCkge1xuICAgICAgLy8gYHJlYWRJbnRvYCBuZXZlciByZWplY3RzOiBhIGZhaWxlZCByZWFkIGxlYXZlcyB0aGUgdGFncyB0cmFja2VkLlxuICAgICAgY29uc3QgcmVhZCA9IHRoaXMucmVhZEludG8odW5yZWFkKS50aGVuKCgpID0+IHtcbiAgICAgICAgZm9yIChjb25zdCB0YWcgb2YgdW5yZWFkKSB7XG4gICAgICAgICAgdGhpcy5yZWFkaW5nLmRlbGV0ZSh0YWcpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIGZvciAoY29uc3QgdGFnIG9mIHVucmVhZCkge1xuICAgICAgICB0aGlzLnJlYWRpbmcuc2V0KHRhZywgcmVhZCk7XG4gICAgICB9XG4gICAgICB3YWl0cy5wdXNoKHJlYWQpO1xuICAgIH1cbiAgICBhd2FpdCBQcm9taXNlLmFsbCh3YWl0cyk7XG4gIH1cblxuICAvKipcbiAgICogQ2F0Y2ggdXAgb24gcmV2YWxpZGF0aW9ucyBvdGhlciBpbnN0YW5jZXMgcmFuLCBhdCBtb3N0IG9uY2UgcGVyXG4gICAqIGByZWZyZXNoSW50ZXJ2YWxNc2AuIFNlZSB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnN9IGZvciB0aGUgY29zdC5cbiAgICovXG4gIGFzeW5jIHJlZnJlc2goKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2c7XG4gICAgaWYgKCFsb2cpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMucmVmcmVzaGluZykge1xuICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaGluZztcbiAgICB9XG4gICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgaWYgKGF0IC0gdGhpcy5sYXN0UmVmcmVzaCA8IHRoaXMucmVmcmVzaEludGVydmFsTXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5sYXN0UmVmcmVzaCA9IGF0O1xuICAgIC8vIFdoYXRldmVyIGdldHMgdHJhY2tlZCBiZWZvcmUgdGhlIG5leHQgcmVmcmVzaCBpcyByZWFkIGZyb20gaXRzIG1hcmtlcixcbiAgICAvLyBzbyB0aGVyZSBpcyBub3RoaW5nIHRvIGNhdGNoIHVwIG9uIHlldC5cbiAgICBpZiAodGhpcy50YWdzLnNpemUgPT09IDApIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5yZWZyZXNoaW5nID0gdGhpcy5zeW5jKGF0LCBsb2cpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgdGhpcy5yZWZyZXNoaW5nID0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLnJlZnJlc2hpbmc7XG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkIGEgcmV2YWxpZGF0aW9uIG9mIGB0YWdzYDogaGVyZSBhdCBvbmNlLCBhbmQgaW4gdGhlIHJldmFsaWRhdGlvblxuICAgKiB0YWJsZSBmb3IgZXZlcnkgb3RoZXIgaW5zdGFuY2UgLSB0aGUgbWFya2VyIHJvdyBwbHVzIGEgbG9nIHJvdyBwZXIgdGFnLlxuICAgKlxuICAgKiBOZXh0LmpzIGNhbGxzIGByZXZhbGlkYXRlVGFnYCBvbiB0aGUgaW5jcmVtZW50YWwgY2FjaGUgYW5kIGB1cGRhdGVUYWdzYCBvblxuICAgKiBldmVyeSBkaXN0aW5jdCBgY2FjaGVIYW5kbGVyc2AgZW50cnksIGFsbCBpbiBvbmUgc3luY2hyb25vdXMgbG9vcFxuICAgKiAoYHJldmFsaWRhdGlvbi11dGlsc2ApLCBhbmQgYWxsIG9mIHRoZW0gc2hhcmUgdGhpcyBtYW5pZmVzdC4gU28gYW5cbiAgICogaWRlbnRpY2FsIGNhbGwgaW4gdGhlIHNhbWUgdHVybiBqb2lucyB0aGUgZmlyc3QgaW5zdGVhZCBvZiB3cml0aW5nIHRoZVxuICAgKiByb3dzIGFnYWluLiBPbmUgaW4gYSBsYXRlciB0dXJuIGlzIGEgcmV2YWxpZGF0aW9uIG9mIGl0cyBvd24sIGV2ZW4gd2hpbGVcbiAgICogdGhlIGZpcnN0IG9uZSdzIHdyaXRlcyBhcmUgaW4gZmxpZ2h0LCBhbmQgZ2V0cyBpdHMgb3duLCBsYXRlciwgbWFya2VyLlxuICAgKiBOZXZlciByZWplY3RzOiByZXNvbHZlcyBgZmFsc2VgIHdoZW4gYSByb3cgZmFpbGVkIHRvIHdyaXRlICh0aGUgZXJyb3IgaXNcbiAgICogbG9nZ2VkKSwgc28gb3RoZXIgaW5zdGFuY2VzIG1heSBub3Qgc2VlIGl0LlxuICAgKi9cbiAgYXN5bmMgdXBkYXRlKFxuICAgIHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdLFxuICAgIGR1cmF0aW9uczogUmV2YWxpZGF0ZUR1cmF0aW9ucyB8IHVuZGVmaW5lZCxcbiAgKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgY29uc3Qga2V5ID0gSlNPTi5zdHJpbmdpZnkoW3RhZ3MsIGR1cmF0aW9ucyA/PyBudWxsXSk7XG4gICAgY29uc3QgaW5GbGlnaHQgPSB0aGlzLnVwZGF0aW5nLmdldChrZXkpO1xuICAgIGlmIChpbkZsaWdodCkge1xuICAgICAgcmV0dXJuIGluRmxpZ2h0O1xuICAgIH1cbiAgICBjb25zdCB1cGRhdGUgPSB0aGlzLndyaXRlKHRhZ3MsIGR1cmF0aW9ucyk7XG4gICAgdGhpcy51cGRhdGluZy5zZXQoa2V5LCB1cGRhdGUpO1xuICAgIC8vIEZvcmdvdHRlbiBhcyBzb29uIGFzIHRoZSBjdXJyZW50IHR1cm4ncyBjYWxscyBoYXZlIGJlZW4gbWFkZS5cbiAgICB2b2lkIFByb21pc2UucmVzb2x2ZSgpLnRoZW4oKCkgPT4gdGhpcy51cGRhdGluZy5kZWxldGUoa2V5KSk7XG4gICAgcmV0dXJuIHVwZGF0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGF0IHRoZSB0cmFja2VkIG1hcmtlcnMgc2F5IGFib3V0IGFuIGVudHJ5IGNhcnJ5aW5nIGB0YWdzYCwgY3JlYXRlZCBhdFxuICAgKiBgY3JlYXRlZEF0YDogdGhlIG1vc3Qgc2V2ZXJlIGFuc3dlciBvZiBhbnkgb2YgdGhlbS5cbiAgICovXG4gIHN0YXRlKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdLCBjcmVhdGVkQXQ6IG51bWJlcik6IFJldmFsaWRhdGlvblN0YXRlIHtcbiAgICAvLyBgbWFya2VyQ2xvY2soKWAsIG5vdCBgRGF0ZS5ub3coKWAsIGhlcmUgYW5kIHdoZXJldmVyIGEgbWFya2VyIGlzIHN0YW1wZWQ6XG4gICAgLy8gYGNyZWF0ZWRBdGAgaXMgb24gTmV4dC5qcydzIGNsb2NrLCBhbmQgYSBtYXJrZXIgb24gdGhlIHdhbGwgY2xvY2sgd291bGQgYmVcbiAgICAvLyBjb21wYXJlZCBhY3Jvc3MgdGhlIHR3bywgc28gYW4gZW50cnkgcmVnZW5lcmF0ZWQganVzdCBhZnRlciBhXG4gICAgLy8gcmV2YWxpZGF0aW9uIGNvdWxkIHN0aWxsIHJlYWQgYXMgb2xkZXIgdGhhbiBpdCB3aGVyZXZlciB0aGV5IGRyaWZ0LlxuICAgIGNvbnN0IGF0ID0gbWFya2VyQ2xvY2soKTtcbiAgICBsZXQgc3RhdGU6IFJldmFsaWRhdGlvblN0YXRlID0gXCJmcmVzaFwiO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIGNvbnN0IG1hcmtlciA9IHRoaXMuZ2V0KHRhZyk7XG4gICAgICBpZiAoIW1hcmtlcikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhZ1N0YXRlID0gbWFya2VyU3RhdGUobWFya2VyLCBjcmVhdGVkQXQsIGF0KTtcbiAgICAgIGlmICh0YWdTdGF0ZSA9PT0gXCJleHBpcmVkXCIpIHtcbiAgICAgICAgcmV0dXJuIFwiZXhwaXJlZFwiO1xuICAgICAgfVxuICAgICAgaWYgKHRhZ1N0YXRlID09PSBcInN0YWxlXCIpIHtcbiAgICAgICAgc3RhdGUgPSBcInN0YWxlXCI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBgZ2V0RXhwaXJhdGlvbmAncyBhbnN3ZXI6IHRoZSBsYXRlc3QgdGltZSBhbnkgb2YgYHRhZ3NgIGV4cGlyZWQsIGAwYCBpZlxuICAgKiBub25lIGhhcy4gT25seSBleHBpcmF0aW9ucyBhbHJlYWR5IHBhc3QgY291bnQgLSBhIHByb2ZpbGUncyBmdXR1cmVcbiAgICogYGV4cGlyZWAgaXMgbm90IGFuIGV4cGlyYXRpb24geWV0IC0gYW5kIGEgc3RhbGUgbWFyayBkb2VzIG5vdCwgbWF0Y2hpbmdcbiAgICogTmV4dC5qcydzIGRlZmF1bHQgaGFuZGxlciwgd2hpY2ggcmVhZHMgb25seSBgZXhwaXJlZGAgZm9yIGltcGxpY2l0IHRhZ3MuXG4gICAqL1xuICBleHBpcmF0aW9uKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdKTogbnVtYmVyIHtcbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgbGV0IGxhdGVzdCA9IDA7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy5nZXQodGFnKTtcbiAgICAgIGlmICghbWFya2VyKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKG1hcmtlci5yZXZhbGlkYXRlZEF0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGF0ZXN0ID0gTWF0aC5tYXgobGF0ZXN0LCBtYXJrZXIucmV2YWxpZGF0ZWRBdCk7XG4gICAgICB9XG4gICAgICBpZiAobWFya2VyLmV4cGlyZWRBdCAhPT0gdW5kZWZpbmVkICYmIG1hcmtlci5leHBpcmVkQXQgPD0gYXQpIHtcbiAgICAgICAgbGF0ZXN0ID0gTWF0aC5tYXgobGF0ZXN0LCBtYXJrZXIuZXhwaXJlZEF0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxhdGVzdDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgd3JpdGUoXG4gICAgdGFnczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgZHVyYXRpb25zOiBSZXZhbGlkYXRlRHVyYXRpb25zIHwgdW5kZWZpbmVkLFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgY29uc3QgbWFya2VyID0gbWFya2VyRm9yKGF0LCBkdXJhdGlvbnMpO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIHRoaXMuc2V0KHRhZywgYXBwbHlNYXJrZXIodGhpcy5nZXQodGFnKSwgbWFya2VyKSk7XG4gICAgfVxuICAgIGNvbnN0IHsgbWFya2VycywgbG9nIH0gPSB0aGlzO1xuICAgIGlmICghbWFya2VycyB8fCAhbG9nKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3Qgd3JpdGVzOiBbc3RyaW5nLCBQcm9taXNlPHVua25vd24+XVtdID0gW107XG4gICAgZm9yIChjb25zdCB0YWcgb2YgbmV3IFNldCh0YWdzKSkge1xuICAgICAgd3JpdGVzLnB1c2goW1xuICAgICAgICBcIkVycm9yIHdyaXRpbmcgdGFnIHJldmFsaWRhdGlvbiBtYXJrZXI6XCIsXG4gICAgICAgIC8vIFRoZSByb3cgYXMgaXQgaXMgbm93LCB3aGljaCBjYXJyaWVzIGFueSBlYXJsaWVyIGByZXZhbGlkYXRlZEF0YFxuICAgICAgICAvLyBhbm90aGVyIGluc3RhbmNlIHdyb3RlOiB0cmFja2luZyBvbmx5IHdoYXQgdGhpcyBjYWxsIHNldCB3b3VsZFxuICAgICAgICAvLyBoaWRlIHRoYXQgb25lIHVudGlsIHRoZSByb2xsaW5nIHJlLXJlYWQsIGFuZCBhbiBlbnRyeSBvbGRlciB0aGFuIGl0XG4gICAgICAgIC8vIHdvdWxkIHJlYWQgYXMgbWVyZWx5IHN0YWxlLlxuICAgICAgICBtYXJrZXJzLndyaXRlKHRhZywgYXQsIGR1cmF0aW9ucykudGhlbigocm93KSA9PiB7XG4gICAgICAgICAgaWYgKHJvdykge1xuICAgICAgICAgICAgdGhpcy5zZXQodGFnLCBtZXJnZU1hcmtlcnModGhpcy5nZXQodGFnKSwgcm93KSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgIF0pO1xuICAgICAgd3JpdGVzLnB1c2goW1xuICAgICAgICBcIkVycm9yIHdyaXRpbmcgdGFnIHJldmFsaWRhdGlvbiBsb2cgcm93OlwiLFxuICAgICAgICB0aGlzLnB1dExvZ1Jvdyhsb2csIHRhZywgbWFya2VyKSxcbiAgICAgIF0pO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKHdyaXRlcy5tYXAoKFssIHdyaXRlXSkgPT4gd3JpdGUpKTtcbiAgICByZXN1bHRzLmZvckVhY2goKHJlc3VsdCwgaSkgPT4ge1xuICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICBjb25zb2xlLmVycm9yKHdyaXRlc1tpXVswXSwgcmVzdWx0LnJlYXNvbik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdHMuZXZlcnkoKHJlc3VsdCkgPT4gcmVzdWx0LnN0YXR1cyA9PT0gXCJmdWxmaWxsZWRcIik7XG4gIH1cblxuICAvKipcbiAgICogUHV0IGB0YWdgJ3MgbG9nIHJvdywgc3RhbXBlZCBvbiB0aGUgd2FsbCBjbG9jayAodGhlIG1hcmtlciB2YWx1ZXMgYXJlIG9uXG4gICAqIE5leHQuanMnczogc2VlIHtAbGluayBSZXZhbGlkYXRpb25Mb2d9KS5cbiAgICpcbiAgICogUmVhZGVycyBvbmx5IGxvb2sge0BsaW5rIFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVN9IGJlaGluZCB0aGVpciBsYXN0XG4gICAqIHF1ZXJ5LCBzbyBhIHJvdyB0aGF0IHNob3dzIHVwIG11Y2ggbGF0ZXIgdGhhbiBpdHMgdGltZXN0YW1wIC0gYSBzbG93XG4gICAqIGNvbm5lY3Rpb24sIHJldHJpZXMgdW5kZXIgdGhyb3R0bGluZyAtIGlzIGJlaGluZCBldmVyeSBjdXJzb3IgYW5kIG5ldmVyXG4gICAqIHJlYWQuIEEgc2xvdyBwdXQgaXMgdGhlcmVmb3JlIG1hZGUgYWdhaW4gdW5kZXIgYSBmcmVzaCB0aW1lc3RhbXAsIHdoaWNoXG4gICAqIHJlYWRlcnMgd2lsbCBzZWU7IG9uZSBzbG93IHR3aWNlIGlzIHJlcG9ydGVkIGFzIGEgZmFpbHVyZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcHV0TG9nUm93KFxuICAgIGxvZzogUmV2YWxpZGF0aW9uTG9nLFxuICAgIHRhZzogc3RyaW5nLFxuICAgIG1hcmtlcjogVGFnTWFya2VyLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgYXR0ZW1wdCA8IDI7IGF0dGVtcHQrKykge1xuICAgICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgICBhd2FpdCBsb2cucHV0KHRhZywgYXQsIG1hcmtlcik7XG4gICAgICBpZiAodGhpcy5jbG9jaygpIC0gYXQgPD0gTUFYX0xPR19QVVRfTVMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgVGhlIHJldmFsaWRhdGlvbiBsb2cgcm93IGZvciAke3RhZ30gdG9vayBsb25nZXIgdGhhbiByZWFkZXJzIGxvb2sgYmFja2AsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPbmUgcmVmcmVzaCBzdGFydGVkIGF0IGBhdGA6IHRoZSBsb2cgcm93cyBzaW5jZSB0aGUgY3Vyc29yLCBhbmQgdGhlIG5leHRcbiAgICogc2xpY2Ugb2YgdGhlIHJvbGxpbmcgcmUtcmVhZC5cbiAgICpcbiAgICogQSBmYWlsZWQgcXVlcnkgY2hhbmdlcyBub3RoaW5nIGJ1dCB0aGUgbG9nOiB0aGUgdGFncyBzdGF5IHRyYWNrZWQgYXMgdGhleVxuICAgKiB3ZXJlLCBhbmQgdGhlIG5leHQgcmVmcmVzaCBhc2tzIGFnYWluIGZyb20gdGhlIHNhbWUgY3Vyc29yLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzeW5jKGF0OiBudW1iZXIsIGxvZzogUmV2YWxpZGF0aW9uTG9nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKGF0IC0gdGhpcy5sYXN0TG9nUmVhZCA+IE1BWF9SRVZBTElEQVRJT05fTE9HX0dBUF9NUykge1xuICAgICAgdGhpcy5mb3JnZXQoXG4gICAgICAgIGF0LFxuICAgICAgICBcInRoZSByZXZhbGlkYXRpb24gbG9nIG1heSBub3QgY292ZXIgdGhlIGdhcCBzaW5jZSBpdCB3YXMgbGFzdCByZWFkXCIsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBbcmVzdWx0XSA9IGF3YWl0IFByb21pc2UuYWxsKFtcbiAgICAgIGxvZy5xdWVyeSh0aGlzLmN1cnNvcikuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciByZWFkaW5nIHRhZyByZXZhbGlkYXRpb24gbG9nOlwiLCBlcnJvcik7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9KSxcbiAgICAgIHRoaXMucmVhZEludG8odGhpcy5kdWUoYXQpKSxcbiAgICBdKTtcbiAgICBpZiAoIXJlc3VsdCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAocmVzdWx0LnRydW5jYXRlZCkge1xuICAgICAgdGhpcy5mb3JnZXQoXG4gICAgICAgIGF0LFxuICAgICAgICBcInRoZSByZXZhbGlkYXRpb24gbG9nIGhhcyBtb3JlIHJvd3MgdGhhbiBvbmUgcXVlcnkgcmVhZHNcIixcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGxldCBhcHBsaWVkID0gMDtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByZXN1bHQucm93cykge1xuICAgICAgaWYgKHRoaXMuYXBwbGllZC5oYXMocm93LnNrKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1hcmtlciA9IHRoaXMudGFncy5nZXQocm93LnRhZyk7XG4gICAgICBpZiAobWFya2VyKSB7XG4gICAgICAgIC8vIGBzZXRgIG9uIGEga2V5IGFscmVhZHkgdGhlcmUga2VlcHMgaXRzIHBsYWNlIGluIHRoZSBMUlUgb3JkZXI6IGJlaW5nXG4gICAgICAgIC8vIHJldmFsaWRhdGVkIGVsc2V3aGVyZSBpcyBub3QgYSB1c2UuXG4gICAgICAgIHRoaXMudGFncy5zZXQocm93LnRhZywgbWVyZ2VNYXJrZXJzKG1hcmtlciwgcm93Lm1hcmtlcikpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnJlYWRpbmcuaGFzKHJvdy50YWcpKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ1Jvd3Muc2V0KFxuICAgICAgICAgIHJvdy50YWcsXG4gICAgICAgICAgbWVyZ2VNYXJrZXJzKHRoaXMucGVuZGluZ1Jvd3MuZ2V0KHJvdy50YWcpLCByb3cubWFya2VyKSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEEgdGFnIHRoaXMgaW5zdGFuY2UgZG9lcyBub3QgdHJhY2sgaXMgcmVhZCBmcm9tIGl0cyBtYXJrZXIgd2hlbiBpdFxuICAgICAgICAvLyBpcyBuZXh0IG5lZWRlZCAtIGJ1dCBub3QgeWV0IG1hcmtlZCBhcHBsaWVkLCBiZWNhdXNlIHRoYXQgcmVhZCBtYXlcbiAgICAgICAgLy8gbWlzcyB0aGlzIHZlcnkgcmV2YWxpZGF0aW9uOiB0aGUgd3JpdGVyIHB1dHMgdGhlIGxvZyByb3cgYW5kIHRoZVxuICAgICAgICAvLyBtYXJrZXIgYXQgdGhlIHNhbWUgdGltZSwgYW5kIHRoZSByZWFkIGlzIGFuIGV2ZW50dWFsbHkgY29uc2lzdGVudFxuICAgICAgICAvLyBgQmF0Y2hHZXRJdGVtYCB0aGF0IGNhbiBsYW5kIG1pbGxpc2Vjb25kcyBhZnRlciB0aGUgcm93IHNob3dlZCBoZXJlLlxuICAgICAgICAvLyBNYXJrZWQgYXBwbGllZCwgdGhlIHJvdyB3YXMgc2tpcHBlZCBieSBldmVyeSBxdWVyeSB0aGUgbG9va2JhY2tcbiAgICAgICAgLy8gcmV0dXJuZWQgaXQgdG8sIGFuZCB0aGUgcHJlLXJldmFsaWRhdGlvbiBtYXJrZXIgc3Rvb2QgdW50aWwgdGhlXG4gICAgICAgIC8vIHJvbGxpbmcgcmUtcmVhZC4gTGVmdCB1bm1hcmtlZCwgdGhlIG5leHQgcmVmcmVzaCBhcHBsaWVzIGl0IHRvXG4gICAgICAgIC8vIHdoYXRldmVyIHRoYXQgcmVhZCBmb3VuZDsgaXQgY29zdHMgbm8gcmVhZCwgb25seSB0aGUgcm93IGJlaW5nXG4gICAgICAgIC8vIGxvb2tlZCBhdCBhZ2FpbiB3aGlsZSBpdCBpcyBpbnNpZGUgdGhlIGxvb2tiYWNrLlxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXBwbGllZC5zZXQocm93LnNrLCByb3cuYXQpO1xuICAgICAgYXBwbGllZCsrO1xuICAgIH1cbiAgICB0aGlzLmxhc3RMb2dSZWFkID0gYXQ7XG4gICAgdGhpcy5hZHZhbmNlKGF0IC0gUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUyk7XG4gICAgdGhpcy5kZWJ1ZyhcbiAgICAgIGByZWFkICR7cmVzdWx0LnJvd3MubGVuZ3RofSByZXZhbGlkYXRpb24gbG9nIHJvd3MgKCR7YXBwbGllZH0gYXBwbGllZClgLFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogVGhlIHRhZ3MgdG8gcmVhZCBvbiB0aGlzIHJlZnJlc2gsIGF0IG1vc3Qgb25lIGBCYXRjaEdldEl0ZW1gJ3Mgd29ydGg6XG4gICAqIHRob3NlIHdob3NlIHJlYWQgZmFpbGVkLCB0aGVuIHRob3NlIHdob3NlIHJlLXJlYWQgaGFzIGNvbWUgZHVlLCBpbiB0aGVcbiAgICogb3JkZXIgdGhleSB3ZXJlIGxhc3QgcmVhZC5cbiAgICovXG4gIHByaXZhdGUgZHVlKGF0OiBudW1iZXIpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgZHVlOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRoaXMudW5yZWFkKSB7XG4gICAgICBpZiAoZHVlLmxlbmd0aCA+PSBCQVRDSF9HRVRfTUFYX0tFWVMpIHJldHVybiBkdWU7XG4gICAgICBkdWUucHVzaCh0YWcpO1xuICAgIH1cbiAgICAvLyBLbm93biBpbiB0aW1lIG9yZGVyLCBhbmQgZWFjaCBkdWUgYXQgbW9zdCBgaml0dGVyYCBlYXJsaWVyIHRoYW4gdGhlXG4gICAgLy8gdGFncyBhZnRlciBpdDogcGFzdCBhIHRhZyBkdWUgbW9yZSB0aGFuIHRoYXQgZnJvbSBub3csIG5vbmUgaXMgZHVlLlxuICAgIGNvbnN0IGppdHRlciA9IHRoaXMucmVzeW5jSW50ZXJ2YWxNcyAqIFRBR19SRVNZTkNfSklUVEVSO1xuICAgIGZvciAoY29uc3QgW3RhZywgZHVlQXRdIG9mIHRoaXMuZHVlQXQpIHtcbiAgICAgIGlmIChkdWUubGVuZ3RoID49IEJBVENIX0dFVF9NQVhfS0VZUyB8fCBkdWVBdCAtIGppdHRlciA+IGF0KSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgaWYgKGR1ZUF0IDw9IGF0ICYmICF0aGlzLnVucmVhZC5oYXModGFnKSkge1xuICAgICAgICBkdWUucHVzaCh0YWcpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcmdldCBldmVyeSB0cmFja2VkIG1hcmtlciwgYW5kIGZvbGxvdyB0aGUgbG9nIGZyb20gYGF0YDogd2hhdCBpcyBuZWVkZWRcbiAgICogbmV4dCBpcyByZWFkIGZyb20gaXRzIG1hcmtlciBhcyBpdCBpcyBuZWVkZWQsIHNwcmVhZCBvdmVyIHRoZSByZXF1ZXN0c1xuICAgKiB0aGF0IG5lZWQgaXQsIHJhdGhlciB0aGFuIGV2ZXJ5IHRyYWNrZWQgdGFnIHJlLXJlYWQgYXQgb25jZS5cbiAgICovXG4gIHByaXZhdGUgZm9yZ2V0KGF0OiBudW1iZXIsIHdoeTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5kZWJ1ZyhgZm9yZ2V0dGluZyAke3RoaXMudGFncy5zaXplfSB0cmFja2VkIHRhZ3M6ICR7d2h5fWApO1xuICAgIHRoaXMudGFncy5jbGVhcigpO1xuICAgIHRoaXMuZHVlQXQuY2xlYXIoKTtcbiAgICB0aGlzLnVucmVhZC5jbGVhcigpO1xuICAgIHRoaXMuYXBwbGllZC5jbGVhcigpO1xuICAgIHRoaXMuY3Vyc29yID0gYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TO1xuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBjdXJzb3IgZm9yd2FyZCB0byBgY3Vyc29yYCwgZm9yZ2V0dGluZyBhcHBsaWVkIHJvd3MgYmVmb3JlIGl0OlxuICAgKiBubyBxdWVyeSByZXR1cm5zIHRoZW0gYWdhaW4uXG4gICAqL1xuICBwcml2YXRlIGFkdmFuY2UoY3Vyc29yOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoY3Vyc29yIDw9IHRoaXMuY3Vyc29yKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY3Vyc29yID0gY3Vyc29yO1xuICAgIGZvciAoY29uc3QgW3NrLCBhdF0gb2YgdGhpcy5hcHBsaWVkKSB7XG4gICAgICBpZiAoYXQgPCBjdXJzb3IpIHtcbiAgICAgICAgdGhpcy5hcHBsaWVkLmRlbGV0ZShzayk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgYHRhZ3NgIGZyb20gdGhlIHRhYmxlLCBhbmQgcmVwb3J0IHdoZXRoZXIgdGhhdCB3b3JrZWQuIEEgcmVhZCB0aGF0XG4gICAqIGZhaWxzIGxlYXZlcyB0aGVtIHRyYWNrZWQgYXMgdGhleSB3ZXJlLCBhbmQgdGhlIG5leHQgcmVmcmVzaCByZWFkcyB0aGVtXG4gICAqIGFnYWluOiB0aGUgc2FtZSBcImFzc3VtZSB0aGUgZW50cnkgaXMgdmFsaWRcIiB0aGUgaW5jcmVtZW50YWwgY2FjaGUgaGFzXG4gICAqIGFsd2F5cyBhbnN3ZXJlZCB3aXRoLCByYXRoZXIgdGhhbiBhIHJlYWQgb24gZXZlcnkgcmVxdWVzdCB3aGlsZSBEeW5hbW9EQlxuICAgKiBpcyB1bmF2YWlsYWJsZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVhZEludG8odGFnczogc3RyaW5nW10pOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAodGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVhZCA9IGF3YWl0IHRoaXMubWFya2VycyEucmVhZCh0YWdzKTtcbiAgICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgICAgdGhpcy51bnJlYWQuZGVsZXRlKHRhZyk7XG4gICAgICAgIHRoaXMucmVtZW1iZXIoXG4gICAgICAgICAgdGFnLFxuICAgICAgICAgIG1lcmdlTWFya2VycyhcbiAgICAgICAgICAgIG1lcmdlTWFya2Vycyh0aGlzLnRhZ3MuZ2V0KHRhZyksIHJlYWQuZ2V0KHRhZykpLFxuICAgICAgICAgICAgdGhpcy50YWtlUGVuZGluZ1Jvd3ModGFnKSxcbiAgICAgICAgICApLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmtub3duKHRhZywgYXQpO1xuICAgICAgfVxuICAgICAgdGhpcy5kZWJ1ZyhgcmVhZCAke3RhZ3MubGVuZ3RofSB0YWcgbWFya2VycyAoJHtyZWFkLnNpemV9IHNldClgKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgcmVhZGluZyB0YWcgbWFya2VyczpcIiwgZXJyb3IpO1xuICAgICAgdGhpcy50cmFja1VucmVhZCh0YWdzKTtcbiAgICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgICAgdGhpcy51bnJlYWQuYWRkKHRhZyk7XG4gICAgICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLnRha2VQZW5kaW5nUm93cyh0YWcpO1xuICAgICAgICBpZiAocGVuZGluZykge1xuICAgICAgICAgIHRoaXMucmVtZW1iZXIodGFnLCBtZXJnZU1hcmtlcnModGhpcy50YWdzLmdldCh0YWcpLCBwZW5kaW5nKSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRha2VQZW5kaW5nUm93cyh0YWc6IHN0cmluZyk6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcGVuZGluZyA9IHRoaXMucGVuZGluZ1Jvd3MuZ2V0KHRhZyk7XG4gICAgdGhpcy5wZW5kaW5nUm93cy5kZWxldGUodGFnKTtcbiAgICByZXR1cm4gcGVuZGluZztcbiAgfVxuXG4gIC8qKiBSZWNvcmQgdGhhdCBgdGFnYCdzIG1hcmtlciB3YXMga25vd24gZnJvbSB0aGUgdGFibGUgYXQgYGF0YC4gKi9cbiAgcHJpdmF0ZSBrbm93bih0YWc6IHN0cmluZywgYXQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZHVlQXQuZGVsZXRlKHRhZyk7XG4gICAgdGhpcy5kdWVBdC5zZXQoXG4gICAgICB0YWcsXG4gICAgICBhdCArIHRoaXMucmVzeW5jSW50ZXJ2YWxNcyAqICgxIC0gVEFHX1JFU1lOQ19KSVRURVIgKiB0aGlzLnJhbmRvbSgpKSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1lbWJlcih0YWc6IHN0cmluZywgbWFya2VyOiBUYWdNYXJrZXIpOiB2b2lkIHtcbiAgICB0aGlzLnRhZ3MuZGVsZXRlKHRhZyk7XG4gICAgdGhpcy50YWdzLnNldCh0YWcsIG1hcmtlcik7XG4gICAgZm9yIChjb25zdCBvbGRlc3Qgb2YgdGhpcy50YWdzLmtleXMoKSkge1xuICAgICAgaWYgKHRoaXMudGFncy5zaXplIDw9IHRoaXMubWF4VHJhY2tlZFRhZ3MpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICB0aGlzLnRhZ3MuZGVsZXRlKG9sZGVzdCk7XG4gICAgICB0aGlzLmR1ZUF0LmRlbGV0ZShvbGRlc3QpO1xuICAgICAgdGhpcy51bnJlYWQuZGVsZXRlKG9sZGVzdCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0b3VjaCh0YWc6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG1hcmtlciA9IHRoaXMudGFncy5nZXQodGFnKTtcbiAgICBpZiAobWFya2VyKSB7XG4gICAgICB0aGlzLnJlbWVtYmVyKHRhZywgbWFya2VyKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUaGUgbG9uZ2VzdCBhIGxvZyByb3cncyBwdXQgbWF5IHRha2UgYW5kIHN0aWxsIGJlIHNlZW4gYnkgZXZlcnkgcmVhZGVyOiBoYWxmXG4gKiB0aGUgbG9va2JhY2ssIGxlYXZpbmcgdGhlIHJlc3QgZm9yIHdyaXRlcnMnIGNsb2NrcyBhbmQgZXZlbnR1YWxseSBjb25zaXN0ZW50XG4gKiBxdWVyaWVzLlxuICovXG5jb25zdCBNQVhfTE9HX1BVVF9NUyA9IFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVMgLyAyO1xuXG4vKipcbiAqIEEgbWFya2VyIGFzIHJlYWQgZnJvbSB0aGUgdGFibGUgb3IgdGhlIGxvZywga2VlcGluZyB3aGF0ZXZlciB0aGlzIGluc3RhbmNlXG4gKiBhbHJlYWR5IGtub3dzIHRoYXQgdGhlIHJlYWQgZG9lcyBub3Qgc2hvdyB5ZXQ6IHJlYWRzIGFyZSBldmVudHVhbGx5XG4gKiBjb25zaXN0ZW50LCBhbmQgYSByZWFkIHN0cmFpZ2h0IGFmdGVyIHRoaXMgaW5zdGFuY2UncyBvd24gcmV2YWxpZGF0aW9uIGNvdWxkXG4gKiBvdGhlcndpc2UgdGFrZSBpdCBiYWNrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VNYXJrZXJzKFxuICBsb2NhbDogVGFnTWFya2VyIHwgdW5kZWZpbmVkLFxuICByZW1vdGU6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCxcbik6IFRhZ01hcmtlciB7XG4gIGlmICghbG9jYWwpIHtcbiAgICByZXR1cm4gcmVtb3RlID8/IHt9O1xuICB9XG4gIGlmICghcmVtb3RlKSB7XG4gICAgcmV0dXJuIGxvY2FsO1xuICB9XG4gIC8vIGBleHBpcmVkQXRgIGlzIHdyaXR0ZW4gd2l0aCBgc3RhbGVBdGAsIHNvIGl0IGJlbG9uZ3MgdG8gd2hpY2hldmVyIGlzXG4gIC8vIG5ld2VyIC0gdW5sZXNzIHRoYXQgcmV2YWxpZGF0aW9uJ3MgcHJvZmlsZSBoYWQgbm8gYGV4cGlyZWAgYW5kIGxlZnQgaXQuXG4gIGNvbnN0IFtvbGRlciwgbmV3ZXJdID1cbiAgICAobG9jYWwuc3RhbGVBdCA/PyAtMSkgPiAocmVtb3RlLnN0YWxlQXQgPz8gLTEpXG4gICAgICA/IFtyZW1vdGUsIGxvY2FsXVxuICAgICAgOiBbbG9jYWwsIHJlbW90ZV07XG4gIHJldHVybiB7XG4gICAgLi4uYXBwbHlNYXJrZXIob2xkZXIsIG5ld2VyKSxcbiAgICByZXZhbGlkYXRlZEF0OiBtYXhEZWZpbmVkKGxvY2FsLnJldmFsaWRhdGVkQXQsIHJlbW90ZS5yZXZhbGlkYXRlZEF0KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWF4RGVmaW5lZChhOiBudW1iZXIgfCB1bmRlZmluZWQsIGI6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICBpZiAoYSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gYjtcbiAgaWYgKGIgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGE7XG4gIHJldHVybiBNYXRoLm1heChhLCBiKTtcbn1cblxuLyoqXG4gKiBUaGUgY2FjaGUgYnVja2V0LCBhcyB0aGUgaGFuZGxlcnMgdXNlIGl0OiB3aG9sZSBvYmplY3RzIHJlYWQgYW5kIHdyaXR0ZW4gYXNcbiAqIFVURi04IHRleHQgdW5kZXIgdGhlIGtleXMgYWJvdmUuXG4gKi9cbmV4cG9ydCBjbGFzcyBDYWNoZUJ1Y2tldCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBTM0NsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJ1Y2tldE5hbWU6IHN0cmluZyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBUaGUgYm9keSBvZiB0aGUgb2JqZWN0IGF0IGBrZXlgLCBvciBgdW5kZWZpbmVkYCB3aGVuIHRoZXJlIGlzIG5vbmUgKGBOb1N1Y2hLZXlgLCBvciBhblxuICAgKiBlbXB0eSByZXNwb25zZSBib2R5KS4gQW55IG90aGVyIGVycm9yIGlzIHRocm93bjogdGhlIGhhbmRsZXJzIGRpc2FncmVlIG9uXG4gICAqIHdoZXRoZXIgb25lIGlzIHdvcnRoIGxvZ2dpbmcuXG4gICAqL1xuICBhc3luYyBnZXQoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICAgIG5ldyBHZXRPYmplY3RDb21tYW5kKHsgQnVja2V0OiB0aGlzLmJ1Y2tldE5hbWUsIEtleToga2V5IH0pLFxuICAgICAgKTtcbiAgICAgIGlmICghcmVzcG9uc2UuQm9keSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF3YWl0IHJlc3BvbnNlLkJvZHkudHJhbnNmb3JtVG9TdHJpbmcoXCJ1dGYtOFwiKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm9TdWNoS2V5KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKiogV3JpdGUgYGJvZHlgIGFzIGEgSlNPTiBvYmplY3QgYXQgYGtleWAuICovXG4gIGFzeW5jIHB1dEpzb24oa2V5OiBzdHJpbmcsIGJvZHk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICBuZXcgUHV0T2JqZWN0Q29tbWFuZCh7XG4gICAgICAgIEJ1Y2tldDogdGhpcy5idWNrZXROYW1lLFxuICAgICAgICBLZXk6IGtleSxcbiAgICAgICAgQm9keTogYm9keSxcbiAgICAgICAgQ29udGVudFR5cGU6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOFwiLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxufVxuIl19
|
|
1470
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLWNhY2hlLXN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvYXdzLWNhY2hlLXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWdEQSxzREFPQztBQVNELGdDQUVDO0FBR0Qsa0NBRUM7QUFtQkQsc0NBRUM7QUFxQ0Qsa0NBZ0JDO0FBV0Qsa0NBRUM7QUFXRCw4QkFXQztBQVFELGtDQVdDO0FBR0Qsb0NBZUM7QUFpREQsOEJBRUM7QUFZRCxnQ0FFQztBQW8yQ0Qsb0NBb0JDO0FBbHBERDs7Ozs7Ozs7O0VBU0U7QUFDRixzREFBc0Q7QUFDdEQsdURBQXFEO0FBQ3JELHlDQUFpQztBQUNqQyw4REFTa0M7QUFDbEMsa0RBSzRCO0FBQzVCLCtDQUE2RTtBQWtCN0UsOENBQThDO0FBQzlDLFNBQWdCLHFCQUFxQjtJQUNuQyxPQUFPO1FBQ0wsVUFBVSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsNEJBQTRCLElBQUksRUFBRTtRQUMxRCxTQUFTLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxrQ0FBa0MsSUFBSSxFQUFFO1FBQy9ELE1BQU0sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxXQUFXO1FBQzdDLE9BQU8sRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLG1CQUFtQixJQUFJLEVBQUU7S0FDL0MsQ0FBQztBQUNKLENBQUM7QUFFRDs7Ozs7O0dBTUc7QUFDSCxTQUFnQixVQUFVLENBQUMsT0FBZSxFQUFFLFFBQWdCO0lBQzFELE9BQU8sSUFBQSxnQkFBSSxFQUFDLE9BQU8sRUFBRSxJQUFBLDhCQUFnQixFQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDbkQsQ0FBQztBQUVELG1GQUFtRjtBQUNuRixTQUFnQixXQUFXLENBQUMsT0FBZSxFQUFFLFFBQWdCO0lBQzNELE9BQU8sSUFBQSxnQkFBSSxFQUFDLE9BQU8sRUFBRSxJQUFBLDZCQUFlLEVBQUMsUUFBUSxDQUFDLENBQUMs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QkFBZ0IsQ0FBQztZQUNuQixNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVU7WUFDdkIsR0FBRyxFQUFFLEdBQUc7WUFDUixJQUFJLEVBQUUsSUFBSTtZQUNWLFdBQVcsRUFBRSxpQ0FBaUM7U0FDL0MsQ0FBQyxDQUNILENBQUM7SUFDSixDQUFDO0NBQ0Y7QUF2Q0Qsa0NBdUNDIiwic291cmNlc0NvbnRlbnQiOlsiLypcbiAgVGhlIFMzIC8gRHluYW1vREIgcGx1bWJpbmcgc2hhcmVkIGJ5IGV2ZXJ5IGNkay1uZXh0anMgY2FjaGUgaGFuZGxlcjogdGhlXG4gIGluY3JlbWVudGFsIGBjYWNoZUhhbmRsZXJgIChgUzNDYWNoZUhhbmRsZXJgKSBhbmQgdGhlIGBjYWNoZUhhbmRsZXJzYCBmb3JcbiAgYCd1c2UgY2FjaGUnYCAvIGAndXNlIGNhY2hlOiByZW1vdGUnYC5cblxuICBXaGF0IGxpdmVzIGhlcmUgaXMgd2hhdCBoYXMgdG8gYWdyZWUgYmV0d2VlbiB0aGVtIC0gd2hlcmUgdGhlIGNvbmZpZ3VyYXRpb25cbiAgY29tZXMgZnJvbSwgaG93IGEgY2FjaGUga2V5IGJlY29tZXMgYW4gUzMga2V5LCBhbmQgd2hhdCBhIHRhZydzIG1hcmtlciByb3cgaW5cbiAgdGhlIHJldmFsaWRhdGlvbiB0YWJsZSBsb29rcyBsaWtlIGFuZCBtZWFucy4gQSBgcmV2YWxpZGF0ZVRhZ2AgcmVhY2hlcyBib3RoXG4gIGtpbmRzIG9mIGhhbmRsZXIsIGFuZCB0aGV5IG11c3QgcmVhZCBlYWNoIG90aGVyJ3MgbWFya2VycyB0aGUgc2FtZSB3YXkuXG4qL1xuLyogZXNsaW50LWRpc2FibGUgaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzICovXG5pbXBvcnQgeyBBc3luY0xvY2FsU3RvcmFnZSB9IGZyb20gXCJub2RlOmFzeW5jX2hvb2tzXCI7XG5pbXBvcnQgeyBqb2luIH0gZnJvbSBcIm5vZGU6cGF0aFwiO1xuaW1wb3J0IHtcbiAgQXR0cmlidXRlVmFsdWUsXG4gIEJhdGNoR2V0SXRlbUNvbW1hbmQsXG4gIEJhdGNoR2V0SXRlbUNvbW1hbmRPdXRwdXQsXG4gIER5bmFtb0RCQ2xpZW50LFxuICBQdXRJdGVtQ29tbWFuZCxcbiAgUXVlcnlDb21tYW5kLFxuICBRdWVyeUNvbW1hbmRPdXRwdXQsXG4gIFVwZGF0ZUl0ZW1Db21tYW5kLFxufSBmcm9tIFwiQGF3cy1zZGsvY2xpZW50LWR5bmFtb2RiXCI7XG5pbXBvcnQge1xuICBHZXRPYmplY3RDb21tYW5kLFxuICBOb1N1Y2hLZXksXG4gIFB1dE9iamVjdENvbW1hbmQsXG4gIFMzQ2xpZW50LFxufSBmcm9tIFwiQGF3cy1zZGsvY2xpZW50LXMzXCI7XG5pbXBvcnQgeyBjYWNoZUtleUZpbGVOYW1lLCBjYWNoZU9iamVjdE5hbWUsIHNoYTI1NkhleCB9IGZyb20gXCIuL2NhY2hlLXV0aWxzXCI7XG5cbi8qKlxuICogV2hlcmUgdGhlIGNhY2hlIGxpdmVzLCBhcyB0aGUgY29uc3RydWN0cyBwYXNzIGl0IHRvIHRoZSBjb21wdXRlIHRocm91Z2ggdGhlXG4gKiBlbnZpcm9ubWVudCAoYE5leHRqc0Z1bmN0aW9uc2AsIGBOZXh0anNDb250YWluZXJzYCkuIEVtcHR5IHN0cmluZ3MgZm9yIHdoYXQgaXNcbiAqIG5vdCBjb25maWd1cmVkLCB3aGljaCBlYWNoIGhhbmRsZXIgcmVhZHMgYXMgXCJ0aGF0IGxheWVyIGlzIGRpc2FibGVkXCIuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgQXdzQ2FjaGVDb25maWcge1xuICAvKiogYENES19ORVhUSlNfQ0FDSEVfQlVDS0VUX05BTUVgLiAqL1xuICBidWNrZXROYW1lOiBzdHJpbmc7XG4gIC8qKiBgQ0RLX05FWFRKU19SRVZBTElEQVRJT05fVEFCTEVfTkFNRWAuICovXG4gIHRhYmxlTmFtZTogc3RyaW5nO1xuICAvKiogYEFXU19SRUdJT05gLCBgdXMtZWFzdC0xYCB3aGVuIHVuc2V0LiAqL1xuICByZWdpb246IHN0cmluZztcbiAgLyoqIGBDREtfTkVYVEpTX0JVSUxEX0lEYDogZXZlcnkgUzMga2V5IGFuZCBldmVyeSBtYXJrZXIgcm93IGlzIHNjb3BlZCB0byBpdC4gKi9cbiAgYnVpbGRJZDogc3RyaW5nO1xufVxuXG4vKiogVGhlIGNvbmZpZ3VyYXRpb24gZnJvbSB0aGUgZW52aXJvbm1lbnQuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzb2x2ZUF3c0NhY2hlQ29uZmlnKCk6IEF3c0NhY2hlQ29uZmlnIHtcbiAgcmV0dXJuIHtcbiAgICBidWNrZXROYW1lOiBwcm9jZXNzLmVudi5DREtfTkVYVEpTX0NBQ0hFX0JVQ0tFVF9OQU1FIHx8IFwiXCIsXG4gICAgdGFibGVOYW1lOiBwcm9jZXNzLmVudi5DREtfTkVYVEpTX1JFVkFMSURBVElPTl9UQUJMRV9OQU1FIHx8IFwiXCIsXG4gICAgcmVnaW9uOiBwcm9jZXNzLmVudi5BV1NfUkVHSU9OIHx8IFwidXMtZWFzdC0xXCIsXG4gICAgYnVpbGRJZDogcHJvY2Vzcy5lbnYuQ0RLX05FWFRKU19CVUlMRF9JRCB8fCBcIlwiLFxuICB9O1xufVxuXG4vKipcbiAqIGB7YnVpbGRJZH0ve2NhY2hlS2V5fS5qc29uYCwgdGhlIGluY3JlbWVudGFsIGNhY2hlJ3Mga2V5IGNvbnZlbnRpb24uXG4gKlxuICogVGhlIHJvb3QgcGF0aCBiZWNvbWVzIGBpbmRleGAsIGFuZCBhIGxlYWRpbmcgc2xhc2ggaXMgZHJvcHBlZCBzbyB0aGVyZSBpcyBub1xuICogZW1wdHkgZm9sZGVyIHVuZGVyIHRoZSBidWlsZCBwcmVmaXguIEV2ZXJ5dGhpbmcgdGhpcyByZXR1cm5zIGVuZHMgaW4gYC5qc29uYCxcbiAqIHdoaWNoIGlzIHdoYXQga2VlcHMgaXQgZGlzam9pbnQgZnJvbSB7QGxpbmsgdXNlQ2FjaGVTM0tleX0uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBidWlsZFMzS2V5KGJ1aWxkSWQ6IHN0cmluZywgY2FjaGVLZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGJ1aWxkSWQsIGNhY2hlS2V5RmlsZU5hbWUoY2FjaGVLZXkpKTtcbn1cblxuLyoqIGB7YnVpbGRJZH0vYCArIHtAbGluayBjYWNoZU9iamVjdE5hbWV9OiB0aGUgUzMgb2JqZWN0IGFuIGVudHJ5IGlzIHN0b3JlZCBpbi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzM09iamVjdEtleShidWlsZElkOiBzdHJpbmcsIGNhY2hlS2V5OiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihidWlsZElkLCBjYWNoZU9iamVjdE5hbWUoY2FjaGVLZXkpKTtcbn1cblxuLyoqXG4gKiBUaGUgZm9sZGVyIHVuZGVyIHRoZSBidWlsZCBwcmVmaXggdGhhdCBgJ3VzZSBjYWNoZSdgIGVudHJpZXMgYXJlIHN0b3JlZCBpbi5cbiAqIEBzZWUgdXNlQ2FjaGVTM0tleVxuICovXG5leHBvcnQgY29uc3QgVVNFX0NBQ0hFX0tFWV9QUkVGSVggPSBcIl91c2UtY2FjaGVcIjtcblxuLyoqXG4gKiBge2J1aWxkSWR9L191c2UtY2FjaGUve2hhc2h9LmVudHJ5YCwgd2hlcmUgYSBgY2FjaGVIYW5kbGVyc2AgZW50cnkgaXMgc3RvcmVkLlxuICpcbiAqIEhhc2hlZCBiZWNhdXNlIGEgYCd1c2UgY2FjaGUnYCBrZXkgaXMgdGhlIHNlcmlhbGl6ZWQgYXJndW1lbnRzIG9mIHRoZSBjYWxsIGFuZFxuICogaGFzIG5vIGxlbmd0aCBsaW1pdCwgd2hlcmUgYW4gUzMga2V5IHN0b3BzIGF0IDEwMjQgYnl0ZXMuIFRoZSBgLmVudHJ5YCBzdWZmaXhcbiAqIHJhdGhlciB0aGFuIGAuanNvbmAgaXMgd2hhdCBtYWtlcyBhIGNvbGxpc2lvbiB3aXRoIHRoZSBpbmNyZW1lbnRhbCBjYWNoZVxuICogaW1wb3NzaWJsZSByYXRoZXIgdGhhbiB1bmxpa2VseTogZXZlcnkgb2JqZWN0IHtAbGluayBzM09iamVjdEtleX0gbmFtZXMgZW5kc1xuICogaW4gYC5qc29uYCBvciBgLmxvbmdgLCBpbmNsdWRpbmcgb25lIGZvciBhIHJvdXRlIHRoYXQgaGFwcGVucyB0byBiZSBuYW1lZFxuICogYC9fdXNlLWNhY2hlL+KApmAuXG4gKiBTdGlsbCB1bmRlciB0aGUgYnVpbGQgcHJlZml4LCBzbyBwb3N0LWRlcGxveSBwcnVuaW5nIGRyb3BzIHRoZW0gd2l0aCB0aGUgYnVpbGQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VDYWNoZVMzS2V5KGJ1aWxkSWQ6IHN0cmluZywga2V5SGFzaDogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oYnVpbGRJZCwgVVNFX0NBQ0hFX0tFWV9QUkVGSVgsIGAke2tleUhhc2h9LmVudHJ5YCk7XG59XG5cbi8qKlxuICogVGhlIGBkdXJhdGlvbnNgIE5leHQuanMgMTYgcGFzc2VzIGEgdGFnIHJldmFsaWRhdGlvbiBmb3IgYSBwcm9maWxlOlxuICogYHJldmFsaWRhdGVUYWcoXCJwb3N0c1wiLCBcIm1heFwiKWAgYXJyaXZlcyBhcyBgeyBleHBpcmU6IDx0aGUgcHJvZmlsZSdzIGV4cGlyZT4gfWAuXG4gKiBBYnNlbnQgZm9yIGB1cGRhdGVUYWdgIGFuZCBhIGJhcmUgYHJldmFsaWRhdGVUYWdgLCB3aGljaCBleHBpcmUgaW1tZWRpYXRlbHkuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgUmV2YWxpZGF0ZUR1cmF0aW9ucyB7XG4gIGV4cGlyZT86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBBIHRhZydzIG1hcmtlciByb3csIGFzIHRpbWVzdGFtcHMgaW4gbWlsbGlzZWNvbmRzLiBXcml0dGVuIGJ5XG4gKiB7QGxpbmsgbWFya2VyVXBkYXRlfTsgZWFjaCBmaWVsZCBpcyBhYnNlbnQgdW50aWwgYSByZXZhbGlkYXRpb24gb2YgdGhhdCBzaGFwZVxuICogaGFzIGhhcHBlbmVkLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIFRhZ01hcmtlciB7XG4gIC8qKiBFeHBpcmVkIG91dHJpZ2h0OiBgdXBkYXRlVGFnYCwgb3IgYHJldmFsaWRhdGVUYWdgIHdpdGggbm8gcHJvZmlsZS4gKi9cbiAgcmV2YWxpZGF0ZWRBdD86IG51bWJlcjtcbiAgLyoqIFN0YWxlIGZyb20gaGVyZTogYHJldmFsaWRhdGVUYWcodGFnLCBwcm9maWxlKWAuICovXG4gIHN0YWxlQXQ/OiBudW1iZXI7XG4gIC8qKiBXaGVuIHRoZSBwcm9maWxlJ3MgYGV4cGlyZWAgcnVucyBvdXQsIHdoaWNoIG1heSBiZSBpbiB0aGUgZnV0dXJlLiAqL1xuICBleHBpcmVkQXQ/OiBudW1iZXI7XG59XG5cbi8qKlxuICogV2hhdCB0aGUgdGFnIG1hcmtlcnMgc2F5IGFib3V0IGFuIGVudHJ5OiB1bnRvdWNoZWQsIHNlcnZlZCBzdGFsZSB3aGlsZSBhXG4gKiBiYWNrZ3JvdW5kIHJlbmRlciByZXBsYWNlcyBpdCwgb3IgZXhwaXJlZCBhbmQgcmUtcmVuZGVyZWQgYmVmb3JlIGFuc3dlcmluZy5cbiAqL1xuZXhwb3J0IHR5cGUgUmV2YWxpZGF0aW9uU3RhdGUgPSBcImZyZXNoXCIgfCBcInN0YWxlXCIgfCBcImV4cGlyZWRcIjtcblxuLyoqXG4gKiBXaGF0IGBtYXJrZXJgIG1lYW5zIGZvciBhbiBlbnRyeSBjcmVhdGVkIGF0IGBjcmVhdGVkQXRgLCBhdCBgbm93YC5cbiAqXG4gKiBgZXhwaXJlZEF0YCBpbiB0aGUgZnV0dXJlIGlzIGEgcHJvZmlsZSdzIGBleHBpcmVgIHRoYXQgaGFzIG5vdCBjb21lIHlldCxcbiAqIGNvbXBhcmVkIHRoZSB3YXkgTmV4dC5qcydzIGBhcmVUYWdzRXhwaXJlZGAgZG9lcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcmtlclN0YXRlKFxuICBtYXJrZXI6IFRhZ01hcmtlcixcbiAgY3JlYXRlZEF0OiBudW1iZXIsXG4gIG5vdzogbnVtYmVyLFxuKTogUmV2YWxpZGF0aW9uU3RhdGUge1xuICBjb25zdCB7IHJldmFsaWRhdGVkQXQsIGV4cGlyZWRBdCwgc3RhbGVBdCB9ID0gbWFya2VyO1xuICBpZiAoXG4gICAgKHJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCAmJiByZXZhbGlkYXRlZEF0ID4gY3JlYXRlZEF0KSB8fFxuICAgIChleHBpcmVkQXQgIT09IHVuZGVmaW5lZCAmJiBleHBpcmVkQXQgPD0gbm93ICYmIGV4cGlyZWRBdCA+IGNyZWF0ZWRBdClcbiAgKSB7XG4gICAgcmV0dXJuIFwiZXhwaXJlZFwiO1xuICB9XG4gIGlmIChzdGFsZUF0ICE9PSB1bmRlZmluZWQgJiYgc3RhbGVBdCA+IGNyZWF0ZWRBdCkge1xuICAgIHJldHVybiBcInN0YWxlXCI7XG4gIH1cbiAgcmV0dXJuIFwiZnJlc2hcIjtcbn1cblxuLyoqXG4gKiBUaGUgY2xvY2sgZXZlcnkgdGFnIG1hcmtlciBpcyBzdGFtcGVkIHdpdGgsIGFuZCBldmVyeSBlbnRyeSB0aW1lc3RhbXAgaXQgaXNcbiAqIGNvbXBhcmVkIGFnYWluc3Q6IHRoZSBvbmUgTmV4dC5qcyBzdGFtcHMgYENhY2hlRW50cnkudGltZXN0YW1wYCB3aXRoXG4gKiAoYHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gKyBwZXJmb3JtYW5jZS5ub3coKWAsIGluIGB1c2UtY2FjaGUtd3JhcHBlci5qc2AgYW5kXG4gKiB0aGUgZGVmYXVsdCBoYW5kbGVyKSwgcmF0aGVyIHRoYW4gYERhdGUubm93KClgLiBCb3RoIGhhbmRsZXJzIHdyaXRlIHRoZSBzYW1lXG4gKiBtYXJrZXIgcm93cywgc28gYm90aCBoYXZlIHRvIHVzZSBpdDogdHdvIGNsb2NrcyBvbiBvbmUgcm93IGxldCB0aGUgbGFzdCB3cml0ZXJcbiAqIGRlY2lkZSB3aGljaCBjbG9jayB0aGUgb3RoZXJzIGNvbXBhcmUgYWdhaW5zdCwgYW5kIHRoZXkgZHJpZnQgYXBhcnQgZm9yIGFzXG4gKiBsb25nIGFzIGEgTGFtYmRhIHNhbmRib3ggb3IgRmFyZ2F0ZSB0YXNrIGxpdmVzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2VyQ2xvY2soKTogbnVtYmVyIHtcbiAgcmV0dXJuIHBlcmZvcm1hbmNlLnRpbWVPcmlnaW4gKyBwZXJmb3JtYW5jZS5ub3coKTtcbn1cblxuLyoqXG4gKiBUaGUgbWFya2VyIGZpZWxkcyBhIHRhZyByZXZhbGlkYXRlZCBhdCBgbm93YCBzZXRzLlxuICpcbiAqIFdpdGhvdXQgYGR1cmF0aW9uc2AgLSBgdXBkYXRlVGFnYCwgb3IgYHJldmFsaWRhdGVUYWdgIHdpdGggbm8gcHJvZmlsZSAtIHRoZVxuICogdGFnJ3MgZW50cmllcyBleHBpcmUgaW1tZWRpYXRlbHkgKGByZXZhbGlkYXRlZEF0YCkuIFdpdGggdGhlbSB0aGUgZW50cmllcyBnb1xuICogc3RhbGUgbm93IGFuZCBleHBpcmUgYWZ0ZXIgdGhlIHByb2ZpbGUncyBgZXhwaXJlYCwgdGhlIHNhbWUgcGFpciBvZlxuICogdGltZXN0YW1wcyBOZXh0LmpzJ3MgYEZpbGVTeXN0ZW1DYWNoZS5yZXZhbGlkYXRlVGFnYCByZWNvcmRzLiBBIHByb2ZpbGUgd2l0aFxuICogbm8gYGV4cGlyZWAgc2V0cyBvbmx5IGBzdGFsZUF0YCwgYW5kIHdoYXRldmVyIGBleHBpcmVkQXRgIHRoZSB0YWcgaGFkIHN0YXlzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2VyRm9yKFxuICBub3c6IG51bWJlcixcbiAgZHVyYXRpb25zOiBSZXZhbGlkYXRlRHVyYXRpb25zIHwgdW5kZWZpbmVkLFxuKTogVGFnTWFya2VyIHtcbiAgaWYgKCFkdXJhdGlvbnMpIHtcbiAgICByZXR1cm4geyByZXZhbGlkYXRlZEF0OiBub3cgfTtcbiAgfVxuICBpZiAoZHVyYXRpb25zLmV4cGlyZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgcmV0dXJuIHsgc3RhbGVBdDogbm93IH07XG4gIH1cbiAgcmV0dXJuIHsgc3RhbGVBdDogbm93LCBleHBpcmVkQXQ6IG5vdyArIGR1cmF0aW9ucy5leHBpcmUgKiAxMDAwIH07XG59XG5cbmNvbnN0IE1BUktFUl9GSUVMRFMgPSBbXCJyZXZhbGlkYXRlZEF0XCIsIFwic3RhbGVBdFwiLCBcImV4cGlyZWRBdFwiXSBhcyBjb25zdDtcblxuLyoqXG4gKiBgZXhpc3RpbmdgIHdpdGggdGhlIGZpZWxkcyBgdXBkYXRlYCBzZXRzLCBhcyBhIHtAbGluayBtYXJrZXJVcGRhdGV9IGxlYXZlc1xuICogdGhlIHJvdzogYSBmaWVsZCBgdXBkYXRlYCBkb2VzIG5vdCBzZXQga2VlcHMgaXRzIHZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gYXBwbHlNYXJrZXIoXG4gIGV4aXN0aW5nOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQsXG4gIHVwZGF0ZTogVGFnTWFya2VyLFxuKTogVGFnTWFya2VyIHtcbiAgY29uc3QgbWFya2VyID0geyAuLi5leGlzdGluZyB9O1xuICBmb3IgKGNvbnN0IGZpZWxkIG9mIE1BUktFUl9GSUVMRFMpIHtcbiAgICBpZiAodXBkYXRlW2ZpZWxkXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBtYXJrZXJbZmllbGRdID0gdXBkYXRlW2ZpZWxkXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIG1hcmtlcjtcbn1cblxuLyoqIFRoZSBtYXJrZXItcm93IHVwZGF0ZSB0aGF0IHNldHMge0BsaW5rIG1hcmtlckZvcn0ncyBmaWVsZHMuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2VyVXBkYXRlKFxuICBub3c6IG51bWJlcixcbiAgZHVyYXRpb25zOiBSZXZhbGlkYXRlRHVyYXRpb25zIHwgdW5kZWZpbmVkLFxuKTogUGljazxcbiAgQ29uc3RydWN0b3JQYXJhbWV0ZXJzPHR5cGVvZiBVcGRhdGVJdGVtQ29tbWFuZD5bMF0sXG4gIFwiVXBkYXRlRXhwcmVzc2lvblwiIHwgXCJFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzXCJcbj4ge1xuICBjb25zdCBtYXJrZXIgPSBtYXJrZXJGb3Iobm93LCBkdXJhdGlvbnMpO1xuICBjb25zdCBmaWVsZHMgPSBNQVJLRVJfRklFTERTLmZpbHRlcigoZmllbGQpID0+IG1hcmtlcltmaWVsZF0gIT09IHVuZGVmaW5lZCk7XG4gIHJldHVybiB7XG4gICAgVXBkYXRlRXhwcmVzc2lvbjogYFNFVCAke2ZpZWxkcy5tYXAoKGZpZWxkKSA9PiBgJHtmaWVsZH0gPSA6JHtmaWVsZH1gKS5qb2luKFwiLCBcIil9YCxcbiAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiBPYmplY3QuZnJvbUVudHJpZXMoXG4gICAgICBmaWVsZHMubWFwKChmaWVsZCkgPT4gW2A6JHtmaWVsZH1gLCB7IE46IFN0cmluZyhtYXJrZXJbZmllbGRdKSB9XSksXG4gICAgKSxcbiAgfTtcbn1cblxuLyoqIEEgRHluYW1vREIgbnVtYmVyIGF0dHJpYnV0ZSBhcyBhIG51bWJlciwgb3IgYHVuZGVmaW5lZGAgd2hlbiBhYnNlbnQuICovXG5mdW5jdGlvbiBudW1iZXJBdHRyaWJ1dGUoXG4gIHZhbHVlOiBBdHRyaWJ1dGVWYWx1ZSB8IHVuZGVmaW5lZCxcbik6IG51bWJlciB8IHVuZGVmaW5lZCB7XG4gIHJldHVybiB2YWx1ZT8uTiA9PT0gdW5kZWZpbmVkID8gdW5kZWZpbmVkIDogTnVtYmVyKHZhbHVlLk4pO1xufVxuXG4vKiogVGhlIG1hcmtlciBmaWVsZHMgb2YgYSBtYXJrZXIgb3IgbG9nIHJvdy4gKi9cbmZ1bmN0aW9uIG1hcmtlck9mKGl0ZW06IFJlY29yZDxzdHJpbmcsIEF0dHJpYnV0ZVZhbHVlPik6IFRhZ01hcmtlciB7XG4gIHJldHVybiB7XG4gICAgcmV2YWxpZGF0ZWRBdDogbnVtYmVyQXR0cmlidXRlKGl0ZW0ucmV2YWxpZGF0ZWRBdCksXG4gICAgc3RhbGVBdDogbnVtYmVyQXR0cmlidXRlKGl0ZW0uc3RhbGVBdCksXG4gICAgZXhwaXJlZEF0OiBudW1iZXJBdHRyaWJ1dGUoaXRlbS5leHBpcmVkQXQpLFxuICB9O1xufVxuXG4vKiogRHluYW1vREIncyBjYXAgb24ga2V5cyBpbiBvbmUgYEJhdGNoR2V0SXRlbWAuICovXG5leHBvcnQgY29uc3QgQkFUQ0hfR0VUX01BWF9LRVlTID0gMTAwO1xuXG4vKipcbiAqIEhvdyBvZnRlbiwgYXQgbW9zdCwgYW4gaW5zdGFuY2UgY2F0Y2hlcyB1cCBvbiByZXZhbGlkYXRpb25zIG90aGVyIGluc3RhbmNlc1xuICogcmFuLCB1bmxlc3MgYENES19ORVhUSlNfVEFHX1JFRlJFU0hfTVNgIHNheXMgb3RoZXJ3aXNlOiB0aGUgc3RhbGVuZXNzIHdpbmRvd1xuICogZm9yIGEgYHJldmFsaWRhdGVUYWdgIHJ1biBlbHNld2hlcmUuIEV2ZXJ5IGNhY2hlIGhpdCBjaGVja3MgaXRzIHRhZ3MnXG4gKiBtYXJrZXJzLCBhbmQgZXZlcnkgbWFya2VyIG9mIGEgZGVwbG95bWVudCBzaGFyZXMgb25lIHBhcnRpdGlvbiBrZXksIHNvXG4gKiByZWFkaW5nIHRoZW0gcGVyIHJlcXVlc3QgY2FwcGVkIGEgcm91dGUncyBjYWNoZSBoaXRzIGF0IHRoZSBwYXJ0aXRpb24ncyByZWFkXG4gKiB0aHJvdWdocHV0ICh+MSw5MDAgcmVxL3Mgb24gTmV4dGpzUmVnaW9uYWxGdW5jdGlvbnMpLiBPbmNlIGEgc2Vjb25kLCBmcm9tIHRoZVxuICogcmV2YWxpZGF0aW9uIGxvZywgdGhlIHJlYWRzIHNjYWxlIHdpdGggaW5zdGFuY2VzIGluc3RlYWQgb2YgcmVxdWVzdHMgb3IgdGFncy5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfVEFHX1JFRlJFU0hfTVMgPSAxMDAwO1xuXG4vKipcbiAqIEhvdyBmYXIgcGFzdCBgcmVmcmVzaEludGVydmFsTXNgIHRoZSBsYXN0IHJlZnJlc2ggbWF5IGhhdmUgc2V0dGxlZCBiZWZvcmUgYVxuICogYCd1c2UgY2FjaGUnYCByZXF1ZXN0IHdhaXRzIGZvciB0aGUgbmV4dCBvbmUgKHNlZVxuICoge0BsaW5rIFRyYWNrZWRUYWdNYXJrZXJzLmJlaGluZH0pLiBBbiBpbnN0YW5jZSBzZXJ2aW5nIHN0ZWFkeSB0cmFmZmljIHN0YXlzXG4gKiBpbnNpZGUgaXQ7IG9uZSB0aGF0IHNhdCBpZGxlLCBvciBmcm96ZW4gYmV0d2VlbiBMYW1iZGEgaW52b2NhdGlvbnMsIGRvZXMgbm90LlxuICovXG5leHBvcnQgY29uc3QgVEFHX1JFRlJFU0hfR1JBQ0VfTVMgPSAxMDAwO1xuXG4vKiogRHluYW1vREIncyBsaW1pdCBvbiBhIHNvcnQga2V5LCBpbiBVVEYtOCBieXRlcy4gKi9cbmV4cG9ydCBjb25zdCBNQVhfU09SVF9LRVlfQllURVMgPSAxMDI0O1xuXG4vKipcbiAqIGAjPHNoYTI1Nih0YWcpPmAsIHN0YW5kaW5nIGluIGZvciBhIHRhZyBpbiBhIHNvcnQga2V5IGl0IHdvdWxkIHB1c2ggcGFzdFxuICoge0BsaW5rIE1BWF9TT1JUX0tFWV9CWVRFU30uIE5leHQuanMgY2FwcyB0aGUgdGFncyBhbiBhcHAgbmFtZXMsIGJ1dCBub3QgYW5cbiAqIGltcGxpY2l0IGBfTl9UXy/igKZgIHRhZywgd2hpY2ggaXMgYXMgbG9uZyBhcyBpdHMgcGF0aCwgYW5kIGEgcmVqZWN0ZWQgd3JpdGVcbiAqIGxlZnQgYHJldmFsaWRhdGVQYXRoYCBvbiBhIGxvbmcgcGF0aCByZWNvcmRlZCBub3doZXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzaGVkVGFnKHRhZzogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGAjJHtzaGEyNTZIZXgodGFnKX1gO1xufVxuXG4vKipcbiAqIFRoZSBsb25nZXN0IHRhZyBhIHNvcnQga2V5IHNwZWxscyBvdXQ7IHBhc3QgaXQsIHtAbGluayBzb3J0S2V5VGFnfSBoYXNoZXNcbiAqIGl0LiBPbmUgY2FwIGZvciBldmVyeSByb3cgdGhlIHRhZyBpcyBpbiwgc28gYSByb3cncyB3cml0ZXIgYW5kIHJlYWRlciBhZ3JlZVxuICogd2l0aG91dCBlYWNoIHdvcmtpbmcgb3V0IHdoYXQgZWxzZSBzaGFyZXMgaXRzIGtleS4gSXQgbGVhdmVzIHJvb20gZm9yIHRoZVxuICogbW9zdCBhbnkgcm93IHB1dHMgYmVzaWRlIHRoZSB0YWc6IGEgbWFwcGluZyByb3cncyBgIzxidWlsZElkPi8jPHNoYTI1Nj5gLFxuICogd2l0aCB0aGUgYnVpbGQgSUQgY2FwcGVkIGF0IGBNQVhfQlVJTERfSURfQllURVNgLlxuICovXG5leHBvcnQgY29uc3QgTUFYX1RBR19CWVRFUyA9IDc2ODtcblxuLyoqIGB0YWdgIGFzIGEgc29ydCBrZXkgc3BlbGxzIGl0OiBpdHNlbGYsIG9yIHtAbGluayBoYXNoZWRUYWd9IHBhc3Qge0BsaW5rIE1BWF9UQUdfQllURVN9LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNvcnRLZXlUYWcodGFnOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gQnVmZmVyLmJ5dGVMZW5ndGgodGFnKSA8PSBNQVhfVEFHX0JZVEVTID8gdGFnIDogaGFzaGVkVGFnKHRhZyk7XG59XG5cbi8qKlxuICogVGhlIGJhcmUtdGFnIG1hcmtlciByb3dzIG9mIHRoZSByZXZhbGlkYXRpb24gdGFibGUgKGBwayA9IGJ1aWxkSWRgLFxuICogYHNrID0gdGFnYCwgb3Ige0BsaW5rIGhhc2hlZFRhZ30gcGFzdCB7QGxpbmsgTUFYX1RBR19CWVRFU30pLCB3aGljaCByZWNvcmQgd2hlbiBhIHRhZ1xuICogd2FzIGxhc3QgcmV2YWxpZGF0ZWQgYW5kIGhvdy5cbiAqXG4gKiBUaGUgdGFibGUgYWxzbyBob2xkcyB0aGUgaW5jcmVtZW50YWwgY2FjaGUncyBgdGFnI3MzS2V5YCBtYXBwaW5nIHJvd3MsIHdoaWNoXG4gKiBhcmUgaXRzIG93biBidXNpbmVzcyBhbmQgc3RheSBpbiBgUzNDYWNoZUhhbmRsZXJgOiBvbmx5IHRoZSBtYXJrZXJzIG1lYW4gdGhlXG4gKiBzYW1lIHRoaW5nIHRvIGV2ZXJ5IGhhbmRsZXIuIFdoYXQgYW4gaW5zdGFuY2Uga2VlcHMgb2YgdGhlbSBiZXR3ZWVuIHJlYWRzIGlzXG4gKiB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnN9LlxuICovXG5leHBvcnQgY2xhc3MgVGFnTWFya2VyVGFibGUge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudDogRHluYW1vREJDbGllbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSB0YWJsZU5hbWU6IHN0cmluZyxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJ1aWxkSWQ6IHN0cmluZyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgYHRhZ2AncyByZXZhbGlkYXRpb24gYXQgYG5vd2AuIFNlZSB7QGxpbmsgbWFya2VyVXBkYXRlfS5cbiAgICpcbiAgICogUmV0dXJucyB0aGUgcm93IGFzIHRoaXMgd3JpdGUgbGVmdCBpdCwgc28gdGhlIGluc3RhbmNlIHRoYXQgd3JvdGUgaXQgY2FuXG4gICAqIHRyYWNrIGl0IHJhdGhlciB0aGFuIHJlYWQgaXQgYmFjazogcmVhZHMgYXJlIGV2ZW50dWFsbHkgY29uc2lzdGVudCwgYW5kIGFcbiAgICogcmVhZC1iYWNrIHJhY2luZyByZXBsaWNhdGlvbiBjb3VsZCByZXR1cm4gdGhlIG1hcmtlciBmcm9tIGJlZm9yZSB0aGUgd3JpdGUuXG4gICAqL1xuICBhc3luYyB3cml0ZShcbiAgICB0YWc6IHN0cmluZyxcbiAgICBub3c6IG51bWJlcixcbiAgICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8VGFnTWFya2VyIHwgdW5kZWZpbmVkPiB7XG4gICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNsaWVudC5zZW5kKFxuICAgICAgbmV3IFVwZGF0ZUl0ZW1Db21tYW5kKHtcbiAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgS2V5OiB7XG4gICAgICAgICAgcGs6IHsgUzogdGhpcy5idWlsZElkIH0sXG4gICAgICAgICAgc2s6IHsgUzogc29ydEtleVRhZyh0YWcpIH0sXG4gICAgICAgIH0sXG4gICAgICAgIC4uLm1hcmtlclVwZGF0ZShub3csIGR1cmF0aW9ucyksXG4gICAgICAgIFJldHVyblZhbHVlczogXCJBTExfTkVXXCIsXG4gICAgICB9KSxcbiAgICApO1xuICAgIHJldHVybiByZXNwb25zZT8uQXR0cmlidXRlcyA/IG1hcmtlck9mKHJlc3BvbnNlLkF0dHJpYnV0ZXMpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBtYXJrZXIgcm93cyBmb3IgYHRhZ3NgIHRoYXQgZXhpc3QsIGJ5IHRhZywgaW4gb25lIGBCYXRjaEdldEl0ZW1gIHBlclxuICAgKiB7QGxpbmsgQkFUQ0hfR0VUX01BWF9LRVlTfSB0YWdzIHJhdGhlciB0aGFuIGEgYEdldEl0ZW1gIGVhY2g6IGEgcGFnZVxuICAgKiBjYXJyaWVzIGl0cyB3aG9sZSBpbXBsaWNpdCBgX05fVF8v4oCmYCBjaGFpbiBwbHVzIHRoZSBhcHAncyBvd24gdGFncywgYVxuICAgKiBwYWdlIHdpdGggYSBmZXcgZmV0Y2hlcyBjaGVja3MgZWFjaCBvZiB0aGVtIHRvbywgYW5kIGV2ZXJ5IG9uZSBpcyBvbiB0aGVcbiAgICogcmVxdWVzdCBwYXRoLiBBIHRhZyB3aXRoIG5vIHJvdyBpcyBhYnNlbnQgZnJvbSB0aGUgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgcmVhZCh0YWdzOiBzdHJpbmdbXSk6IFByb21pc2U8TWFwPHN0cmluZywgVGFnTWFya2VyPj4ge1xuICAgIGNvbnN0IHsgdGFibGVOYW1lLCBidWlsZElkIH0gPSB0aGlzO1xuICAgIGNvbnN0IHVuaXF1ZSA9IEFycmF5LmZyb20obmV3IFNldCh0YWdzKSk7XG4gICAgY29uc3QgbWFya2VycyA9IG5ldyBNYXA8c3RyaW5nLCBUYWdNYXJrZXI+KCk7XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHVuaXF1ZS5sZW5ndGg7IGkgKz0gQkFUQ0hfR0VUX01BWF9LRVlTKSB7XG4gICAgICAvLyBBIGhhc2hlZCBzb3J0IGtleSBuYW1lcyBubyB0YWcsIHNvIGVhY2ggcm93IGlzIG1hdGNoZWQgYmFjayBieSBrZXkuXG4gICAgICBjb25zdCB0YWdCeVNrID0gbmV3IE1hcChcbiAgICAgICAgdW5pcXVlXG4gICAgICAgICAgLnNsaWNlKGksIGkgKyBCQVRDSF9HRVRfTUFYX0tFWVMpXG4gICAgICAgICAgLm1hcCgodGFnKSA9PiBbc29ydEtleVRhZyh0YWcpLCB0YWddKSxcbiAgICAgICk7XG4gICAgICBsZXQga2V5czogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlVmFsdWU+W10gfCB1bmRlZmluZWQgPSBBcnJheS5mcm9tKFxuICAgICAgICB0YWdCeVNrLmtleXMoKSxcbiAgICAgICAgKHNrKSA9PiAoeyBwazogeyBTOiBidWlsZElkIH0sIHNrOiB7IFM6IHNrIH0gfSksXG4gICAgICApO1xuICAgICAgLy8gYFVucHJvY2Vzc2VkS2V5c2AgaXMgRHluYW1vREIgZGVjbGluaW5nIHBhcnQgb2YgdGhlIGJhdGNoIHVuZGVyIGxvYWQ7XG4gICAgICAvLyBhIG1hcmtlciBsZWZ0IHVucmVhZCBpcyBhIHJldmFsaWRhdGlvbiBtaXNzZWQsIHNvIGl0IGlzIGFza2VkIGFnYWluLlxuICAgICAgZm9yIChsZXQgYXR0ZW1wdCA9IDA7IGtleXM/Lmxlbmd0aCAmJiBhdHRlbXB0IDwgMzsgYXR0ZW1wdCsrKSB7XG4gICAgICAgIGNvbnN0IHJlc3BvbnNlOiBCYXRjaEdldEl0ZW1Db21tYW5kT3V0cHV0ID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgICBuZXcgQmF0Y2hHZXRJdGVtQ29tbWFuZCh7XG4gICAgICAgICAgICBSZXF1ZXN0SXRlbXM6IHtcbiAgICAgICAgICAgICAgW3RhYmxlTmFtZV06IHtcbiAgICAgICAgICAgICAgICBLZXlzOiBrZXlzLFxuICAgICAgICAgICAgICAgIFByb2plY3Rpb25FeHByZXNzaW9uOiBcInNrLCByZXZhbGlkYXRlZEF0LCBzdGFsZUF0LCBleHBpcmVkQXRcIixcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgfSksXG4gICAgICAgICk7XG4gICAgICAgIGZvciAoY29uc3QgaXRlbSBvZiByZXNwb25zZS5SZXNwb25zZXM/Llt0YWJsZU5hbWVdID8/IFtdKSB7XG4gICAgICAgICAgY29uc3QgdGFnID0gdGFnQnlTay5nZXQoaXRlbS5zaz8uUyA/PyBcIlwiKTtcbiAgICAgICAgICBpZiAodGFnICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIG1hcmtlcnMuc2V0KHRhZywgbWFya2VyT2YoaXRlbSkpO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBrZXlzID0gcmVzcG9uc2UuVW5wcm9jZXNzZWRLZXlzPy5bdGFibGVOYW1lXT8uS2V5cztcbiAgICAgIH1cbiAgICAgIGlmIChrZXlzPy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICAgIGBEeW5hbW9EQiBsZWZ0ICR7a2V5cy5sZW5ndGh9IHRhZyBtYXJrZXJzIHVucmVhZCBhZnRlciByZXRyeWluZ2AsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBtYXJrZXJzO1xuICB9XG59XG5cbi8qKlxuICogSG93IGxvbmcgYSByZXZhbGlkYXRpb24gbG9nIHJvdyBpcyBrZXB0IChgdHRsYCwgZXBvY2ggc2Vjb25kcykuIER5bmFtb0RCIG5ldmVyXG4gKiBkZWxldGVzIGFuIGl0ZW0gYmVmb3JlIGl0cyBUVEwsIG9ubHkgc29tZSB0aW1lIGFmdGVyLCBzbyBhIHJlYWRlciB0aGF0IGxhc3RcbiAqIHF1ZXJpZWQgbGVzcyB0aGFuIHRoaXMgbG9uZyBhZ28gKGxlc3MgYSBtYXJnaW4gZm9yIHdyaXRlcnMnIGNsb2NrcykgaXMgc3VyZVxuICogdG8gZmluZCBldmVyeSByb3cgaXQgaGFzIG5vdCBzZWVuIHlldC5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFVkFMSURBVElPTl9MT0dfVFRMX01TID0gMTUgKiA2MCAqIDEwMDA7XG5cbi8qKiBUaGUgbW9zdCBgUXVlcnlgIHBhZ2VzIG9uZSB7QGxpbmsgUmV2YWxpZGF0aW9uTG9nLnF1ZXJ5fSByZWFkcy4gKi9cbmV4cG9ydCBjb25zdCBSRVZBTElEQVRJT05fTE9HX01BWF9QQUdFUyA9IDU7XG5cbi8qKiBIb3cgbWFueSBzb3J0IGtleXMge0BsaW5rIFJldmFsaWRhdGlvbkxvZy5wdXR9IHRyaWVzIGJlZm9yZSBnaXZpbmcgdXAuICovXG5jb25zdCBMT0dfUFVUX0FUVEVNUFRTID0gNTtcblxuLyoqIERpZ2l0cyBhIGxvZyByb3cncyB0aW1lc3RhbXAgaXMgemVyby1wYWRkZWQgdG8sIHNvIHNvcnQga2V5cyBzb3J0IGJ5IHRpbWUuICovXG5jb25zdCBMT0dfU0tfRElHSVRTID0gMTU7XG5cbi8qKiBBIHJldmFsaWRhdGlvbiByZWFkIGJhY2sgZnJvbSB0aGUgbG9nLiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXZhbGlkYXRpb25Mb2dSb3cge1xuICAvKiogVGhlIHJvdydzIHNvcnQga2V5OiB1bmlxdWUgcGVyIHJldmFsaWRhdGlvbiBvZiBhIHRhZy4gKi9cbiAgc2s6IHN0cmluZztcbiAgLyoqIFdoZW4gaXQgd2FzIHdyaXR0ZW4sIG9uIHRoZSB3cml0ZXIncyBgRGF0ZS5ub3coKWAuICovXG4gIGF0OiBudW1iZXI7XG4gIHRhZzogc3RyaW5nO1xuICAvKiogVGhlIG1hcmtlciBmaWVsZHMgdGhlIHJldmFsaWRhdGlvbiBzZXQsIGFzIHtAbGluayBtYXJrZXJGb3J9IHJldHVybnMgdGhlbS4gKi9cbiAgbWFya2VyOiBUYWdNYXJrZXI7XG59XG5cbi8qKlxuICogVGhlIHJldmFsaWRhdGlvbiBsb2c6IG9uZSByb3cgcGVyIHRhZyByZXZhbGlkYXRpb24gKGBwayA9IDxidWlsZElkPiNsb2dgLFxuICogYHNrID0gPERhdGUubm93KCksIHplcm8tcGFkZGVkPiM8dGFnPmApLCB3aGljaCBleHBpcmVzIGFmdGVyXG4gKiB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19UVExfTVN9LiBBIHRhZyBwYXN0IHtAbGluayBNQVhfVEFHX0JZVEVTfSBpc1xuICoge0BsaW5rIGhhc2hlZFRhZ30gdGhlcmUsIGFuZCBzcGVsbGVkIG91dCBpbiB0aGUgcm93J3MgYGxvbmdUYWdgIGluc3RlYWQuXG4gKlxuICogVGhlIG1hcmtlciByb3dzIHN0YXkgdGhlIHNvdXJjZSBvZiB0cnV0aC4gVGhlIGxvZyBleGlzdHMgc28gYW4gaW5zdGFuY2VcbiAqIGNhbiBhc2sgXCJ3aGF0IHdhcyByZXZhbGlkYXRlZCBzaW5jZSBJIGxhc3QgbG9va2VkP1wiIGluIG9uZSBgUXVlcnlgLCBpbnN0ZWFkXG4gKiBvZiByZS1yZWFkaW5nIGV2ZXJ5IHRhZyBpdCB0cmFja3MgdG8gZmluZCBvdXQgdGhhdCBhbG1vc3Qgbm9uZSBjaGFuZ2VkLiBFdmVyeVxuICogbWFya2VyIHJvdyBvZiBhIGRlcGxveW1lbnQgc2hhcmVzIG9uZSBwYXJ0aXRpb24sIGFuZCB0aG9zZSByZS1yZWFkcyBmcm9tIGFcbiAqIGhhbmRmdWwgb2YgYnVzeSBpbnN0YW5jZXMgd2VyZSBlbm91Z2ggdG8gdGhyb3R0bGUgaXQuXG4gKlxuICogVGhlIHNvcnQga2V5J3MgdGltZXN0YW1wIGlzIHRoZSB3cml0ZXIncyB3YWxsIGNsb2NrIChgRGF0ZS5ub3coKWApLCBub3QgdGhlXG4gKiBwZXJmb3JtYW5jZSBjbG9jayAoe0BsaW5rIG1hcmtlckNsb2NrfSkgdGhlIG1hcmtlciB2YWx1ZXMgYXJlIHN0YW1wZWQgd2l0aCBieSBib3RoXG4gKiBoYW5kbGVyczogaXQgb25seSBvcmRlcnMgcm93cyBmb3IgcmVhZGVycycgY3Vyc29ycywgd2hpY2ggYXJlIG9uIHRoZWlyIG93blxuICogd2FsbCBjbG9ja3MsIGFuZCBpcyBuZXZlciBjb21wYXJlZCB3aXRoIGFuIGVudHJ5J3MgdGltZXN0YW1wLlxuICovXG5leHBvcnQgY2xhc3MgUmV2YWxpZGF0aW9uTG9nIHtcbiAgcHJpdmF0ZSByZWFkb25seSBwazogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBEeW5hbW9EQkNsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIGJ1aWxkSWQ6IHN0cmluZyxcbiAgKSB7XG4gICAgdGhpcy5wayA9IGAke2J1aWxkSWR9I2xvZ2A7XG4gIH1cblxuICAvKipcbiAgICogUmVjb3JkIHRoYXQgYHRhZ2Agd2FzIHJldmFsaWRhdGVkIGF0IGBhdGAgKGBEYXRlLm5vdygpYCksIHNldHRpbmcgYG1hcmtlcmAuXG4gICAqXG4gICAqIFR3byByZXZhbGlkYXRpb25zIG9mIGB0YWdgIGluIHRoZSBzYW1lIG1pbGxpc2Vjb25kIHdvdWxkIHNoYXJlIGEgc29ydCBrZXksXG4gICAqIGFuZCB0aGUgc2Vjb25kIHdvdWxkIG92ZXJ3cml0ZSB0aGUgZmlyc3QuIFNvIHRoZSByb3cgaXMgb25seSB3cml0dGVuIHdoZXJlXG4gICAqIGl0cyBrZXkgaXMgZnJlZSwgYW5kIG9uIGEgY29sbGlzaW9uIGl0IG1vdmVzIHRvIHRoZSBuZXh0IG1pbGxpc2Vjb25kLCB1cFxuICAgKiB0byB7QGxpbmsgTE9HX1BVVF9BVFRFTVBUU30gdGltZXMuXG4gICAqL1xuICBhc3luYyBwdXQodGFnOiBzdHJpbmcsIGF0OiBudW1iZXIsIG1hcmtlcjogVGFnTWFya2VyKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3Qgc2tUYWcgPSBzb3J0S2V5VGFnKHRhZyk7XG4gICAgZm9yIChsZXQgYXR0ZW1wdCA9IDE7IDsgYXR0ZW1wdCsrKSB7XG4gICAgICBjb25zdCBpdGVtOiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4gPSB7XG4gICAgICAgIHBrOiB7IFM6IHRoaXMucGsgfSxcbiAgICAgICAgc2s6IHsgUzogYCR7bG9nU2tQcmVmaXgoYXQpfSMke3NrVGFnfWAgfSxcbiAgICAgICAgdHRsOiB7IE46IFN0cmluZyhNYXRoLmNlaWwoKGF0ICsgUkVWQUxJREFUSU9OX0xPR19UVExfTVMpIC8gMTAwMCkpIH0sXG4gICAgICAgIC4uLihza1RhZyAhPT0gdGFnICYmIHsgbG9uZ1RhZzogeyBTOiB0YWcgfSB9KSxcbiAgICAgIH07XG4gICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIE1BUktFUl9GSUVMRFMpIHtcbiAgICAgICAgY29uc3QgdmFsdWUgPSBtYXJrZXJbZmllbGRdO1xuICAgICAgICBpZiAodmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgIGl0ZW1bZmllbGRdID0geyBOOiBTdHJpbmcodmFsdWUpIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRyeSB7XG4gICAgICAgIGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICAgICAgbmV3IFB1dEl0ZW1Db21tYW5kKHtcbiAgICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgICBJdGVtOiBpdGVtLFxuICAgICAgICAgICAgQ29uZGl0aW9uRXhwcmVzc2lvbjogXCJhdHRyaWJ1dGVfbm90X2V4aXN0cyhzaylcIixcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIChlcnJvciBhcyBFcnJvciB8IHVuZGVmaW5lZCk/Lm5hbWUgIT09XG4gICAgICAgICAgICBcIkNvbmRpdGlvbmFsQ2hlY2tGYWlsZWRFeGNlcHRpb25cIiB8fFxuICAgICAgICAgIGF0dGVtcHQgPj0gTE9HX1BVVF9BVFRFTVBUU1xuICAgICAgICApIHtcbiAgICAgICAgICB0aHJvdyBlcnJvcjtcbiAgICAgICAgfVxuICAgICAgICBhdCA9IE1hdGguZmxvb3IoYXQpICsgMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIHJvd3Mgd3JpdHRlbiBhdCBvciBhZnRlciBgc2luY2VgIChgRGF0ZS5ub3coKWApLCBvbGRlc3QgZmlyc3QuXG4gICAqIGB0cnVuY2F0ZWRgIHdoZW4gdGhlcmUgd2VyZSBtb3JlIHRoYW4ge0BsaW5rIFJFVkFMSURBVElPTl9MT0dfTUFYX1BBR0VTfVxuICAgKiBwYWdlcyBvZiB0aGVtLCBhbmQgYHJvd3NgIGlzIG9ubHkgdGhlIHN0YXJ0LlxuICAgKlxuICAgKiBFdmVudHVhbGx5IGNvbnNpc3RlbnQ6IGEgcm93IHdyaXR0ZW4gYSBtb21lbnQgYWdvIG1heSBub3Qgc2hvdyB5ZXQsIHdoaWNoXG4gICAqIGlzIHdoYXQgdGhlIHJlYWRlcidzIGxvb2tiYWNrIGlzIGZvci5cbiAgICovXG4gIGFzeW5jIHF1ZXJ5KFxuICAgIHNpbmNlOiBudW1iZXIsXG4gICk6IFByb21pc2U8eyByb3dzOiBSZXZhbGlkYXRpb25Mb2dSb3dbXTsgdHJ1bmNhdGVkOiBib29sZWFuIH0+IHtcbiAgICBjb25zdCByb3dzOiBSZXZhbGlkYXRpb25Mb2dSb3dbXSA9IFtdO1xuICAgIGxldCBzdGFydEtleTogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlVmFsdWU+IHwgdW5kZWZpbmVkO1xuICAgIGZvciAobGV0IHBhZ2UgPSAwOyBwYWdlIDwgUkVWQUxJREFUSU9OX0xPR19NQVhfUEFHRVM7IHBhZ2UrKykge1xuICAgICAgY29uc3QgcmVzcG9uc2U6IFF1ZXJ5Q29tbWFuZE91dHB1dCA9IGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICAgIG5ldyBRdWVyeUNvbW1hbmQoe1xuICAgICAgICAgIFRhYmxlTmFtZTogdGhpcy50YWJsZU5hbWUsXG4gICAgICAgICAgS2V5Q29uZGl0aW9uRXhwcmVzc2lvbjogXCJwayA9IDpwayBBTkQgc2sgPj0gOnNpbmNlXCIsXG4gICAgICAgICAgRXhwcmVzc2lvbkF0dHJpYnV0ZVZhbHVlczoge1xuICAgICAgICAgICAgXCI6cGtcIjogeyBTOiB0aGlzLnBrIH0sXG4gICAgICAgICAgICBcIjpzaW5jZVwiOiB7IFM6IGxvZ1NrUHJlZml4KE1hdGgubWF4KDAsIHNpbmNlKSkgfSxcbiAgICAgICAgICB9LFxuICAgICAgICAgIFByb2plY3Rpb25FeHByZXNzaW9uOlxuICAgICAgICAgICAgXCJzaywgbG9uZ1RhZywgcmV2YWxpZGF0ZWRBdCwgc3RhbGVBdCwgZXhwaXJlZEF0XCIsXG4gICAgICAgICAgRXhjbHVzaXZlU3RhcnRLZXk6IHN0YXJ0S2V5LFxuICAgICAgICB9KSxcbiAgICAgICk7XG4gICAgICBmb3IgKGNvbnN0IGl0ZW0gb2YgcmVzcG9uc2UuSXRlbXMgPz8gW10pIHtcbiAgICAgICAgY29uc3Qgc2sgPSBpdGVtLnNrPy5TO1xuICAgICAgICAvLyBgPGRpZ2l0cz4jPHRhZz5gOiB0aGUgdGFnIGlzIGV2ZXJ5dGhpbmcgYWZ0ZXIgdGhlIGZpeGVkLXdpZHRoXG4gICAgICAgIC8vIHRpbWVzdGFtcCwgYCNgcyBpbmNsdWRlZC5cbiAgICAgICAgaWYgKHNrID09PSB1bmRlZmluZWQgfHwgc2tbTE9HX1NLX0RJR0lUU10gIT09IFwiI1wiKSB7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICAgIH1cbiAgICAgICAgcm93cy5wdXNoKHtcbiAgICAgICAgICBzayxcbiAgICAgICAgICBhdDogTnVtYmVyKHNrLnNsaWNlKDAsIExPR19TS19ESUdJVFMpKSxcbiAgICAgICAgICB0YWc6IGl0ZW0ubG9uZ1RhZz8uUyA/PyBzay5zbGljZShMT0dfU0tfRElHSVRTICsgMSksXG4gICAgICAgICAgbWFya2VyOiBtYXJrZXJPZihpdGVtKSxcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgICBzdGFydEtleSA9IHJlc3BvbnNlLkxhc3RFdmFsdWF0ZWRLZXk7XG4gICAgICBpZiAoIXN0YXJ0S2V5KSB7XG4gICAgICAgIHJldHVybiB7IHJvd3MsIHRydW5jYXRlZDogZmFsc2UgfTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHsgcm93cywgdHJ1bmNhdGVkOiB0cnVlIH07XG4gIH1cbn1cblxuZnVuY3Rpb24gbG9nU2tQcmVmaXgoYXQ6IG51bWJlcik6IHN0cmluZyB7XG4gIHJldHVybiBTdHJpbmcoTWF0aC5mbG9vcihhdCkpLnBhZFN0YXJ0KExPR19TS19ESUdJVFMsIFwiMFwiKTtcbn1cblxuLyoqXG4gKiBIb3cgZmFyIGJlaGluZCB0aGUgbGFzdCBxdWVyeSdzIHN0YXJ0IHRoZSBuZXh0IG9uZSBzdGFydHMgcmVhZGluZyB0aGUgbG9nOlxuICogdGhlIHJvb20gZm9yIHRoZSBgUXVlcnlgIGJlaW5nIGV2ZW50dWFsbHkgY29uc2lzdGVudCBhbmQgZm9yIHdyaXRlcnMnIGNsb2Nrc1xuICogcnVubmluZyBiZWhpbmQgdGhlIHJlYWRlcidzLiBSb3dzIGluc2lkZSBpdCBhcmUgcmVhZCBhZ2FpbiwgYW5kIGRyb3BwZWQgYXNcbiAqIGFscmVhZHkgYXBwbGllZC5cbiAqL1xuZXhwb3J0IGNvbnN0IFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVMgPSA1MDAwO1xuXG4vKipcbiAqIFRoZSBsb25nZXN0IHtAbGluayBUcmFja2VkVGFnTWFya2Vyc30gdHJ1c3RzIHRoZSBsb2cgYWxvbmUgZm9yIGEgdGFnIGJlZm9yZVxuICogcmVhZGluZyBpdHMgbWFya2VyIHJvdyBhZ2Fpbi4gVGhlIGxvZyBpcyB0aGUgZmFzdCBwYXRoLCBidXQgdGhlIG1hcmtlciByb3dzXG4gKiBhcmUgdGhlIHNvdXJjZSBvZiB0cnV0aDogYSBsb2cgcm93IHdob3NlIHdyaXRlIGZhaWxlZCB3b3VsZCBvdGhlcndpc2UgYmVcbiAqIG1pc3NlZCBmb3IgYXMgbG9uZyBhcyB0aGUgdGFnIHN0YXlzIHRyYWNrZWQuXG4gKlxuICogUm9sbGluZywgbm90IGFsbCBhdCBvbmNlOiBlYWNoIHJlZnJlc2ggcmUtcmVhZHMgYXQgbW9zdFxuICoge0BsaW5rIEJBVENIX0dFVF9NQVhfS0VZU30gb2YgdGhlIHRhZ3MgZHVlLCBvbGRlc3QgZmlyc3QuIFJlLXJlYWRpbmcgdGhlbSBhbGxcbiAqIHRvZ2V0aGVyIGNvc3QgfjUwMCBSQ1UgYXQgMTAwMCB0YWdzIC0gYSBmbGVldCBzdGFydGVkIGJ5IG9uZSBsb2FkIHRlc3QgZGlkIGl0XG4gKiBpbiB0aGUgc2FtZSBtaW51dGUsIDEyLDgwMCBSQ1UsIGFuZCB0aHJvdHRsZWQgLSBhbmQgd291bGQgYmUgfjUsMDAwIFJDVSBhdFxuICoge0BsaW5rIERFRkFVTFRfTUFYX1RSQUNLRURfVEFHU30sIHBhc3Qgd2hhdCB0aGUgb25lIHBhcnRpdGlvbiBzZXJ2ZXMgaW4gYVxuICogc2Vjb25kLiBTcHJlYWQgb3V0LCAxMCwwMDAgdHJhY2tlZCB0YWdzIGNvc3QgfjggUkNVIGEgc2Vjb25kIHBlciBpbnN0YW5jZS5cbiAqXG4gKiBFYWNoIHRhZyBpcyBkdWUgYXQgYSByYW5kb20gNzUtMTAwJSBvZiB0aGlzIGFmdGVyIGl0IHdhcyBsYXN0IHJlYWQsIHNvIHRhZ3NcbiAqIGZpcnN0IHJlYWQgdG9nZXRoZXIgLSBhbiBpbnN0YW5jZSB3YXJtaW5nIHVwIC0gZG8gbm90IGFsbCBjb21lIGR1ZSB0b2dldGhlclxuICogYWdhaW4gZXZlcnkgaW50ZXJ2YWw6IHRoZSBsb2FkIHRlc3QgdGhhdCBtZWFzdXJlZCB0aGUgcm9sbGluZyByZS1yZWFkIHNhd1xuICogaXRzIHdhcm0tdXAncyByZWFkcyByZXR1cm4gYXMgYSAzMC0zNiBSQ1UvcyBidW1wIHRlbiBtaW51dGVzIGxhdGVyLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9UQUdfUkVTWU5DX01TID0gMTAgKiA2MCAqIDEwMDA7XG5cbi8qKiBUaGUgZnJhY3Rpb24gb2Yge0BsaW5rIERFRkFVTFRfVEFHX1JFU1lOQ19NU30gYSB0YWcgbWF5IGNvbWUgZHVlIGVhcmx5IGJ5LiAqL1xuY29uc3QgVEFHX1JFU1lOQ19KSVRURVIgPSAwLjI1O1xuXG4vKipcbiAqIEhvdyBsb25nIHNpbmNlIHRoZSBsYXN0IHN1Y2Nlc3NmdWwgbG9nIHF1ZXJ5IHRoZSBsb2cgY2FuIHN0aWxsIGJlIHRydXN0ZWQgdG9cbiAqIGhvbGQgZXZlcnkgcm93IG5vdCByZWFkIHlldDogaXRzIFRUTCBsZXNzIGEgbWFyZ2luIGZvciB3cml0ZXJzJyBjbG9ja3MuIFBhc3RcbiAqIGl0IC0gYSBMYW1iZGEgZnJvemVuIGJldHdlZW4gaW52b2NhdGlvbnMsIGEgcnVuIG9mIGZhaWxlZCBxdWVyaWVzIC0gdGhlXG4gKiB0cmFja2VkIG1hcmtlcnMgYXJlIGZvcmdvdHRlbiwgdG8gYmUgcmVhZCBhZ2FpbiBhcyB0aGV5IGFyZSBuZWVkZWQsIGFuZCB0aGVcbiAqIGxvZyBpcyBmb2xsb3dlZCBmcm9tIHRoZXJlLlxuICovXG5leHBvcnQgY29uc3QgTUFYX1JFVkFMSURBVElPTl9MT0dfR0FQX01TID1cbiAgUkVWQUxJREFUSU9OX0xPR19UVExfTVMgLSA1ICogNjAgKiAxMDAwO1xuXG4vKipcbiAqIFRoZSBtb3N0IHRhZ3Mgb25lIGluc3RhbmNlIHRyYWNrcy4gUGFzdCBpdCB0aGUgbGVhc3QgcmVjZW50bHkgdXNlZCBpc1xuICogZm9yZ290dGVuLCB3aGljaCBjb3N0cyBhIHJlYWQgdGhlIG5leHQgdGltZSBpdCBpcyBuZWVkZWQ6IGFuIHVudHJhY2tlZCB0YWdcbiAqIGlzIHJlYWQgYmVmb3JlIGl0IGlzIHRydXN0ZWQuXG4gKlxuICogQSB0cmFja2VkIHRhZyBjb3N0cyBtZW1vcnkgKH4yIE1CIGF0IHRoaXMgYm91bmQpIGFuZCBpdHMgc2hhcmUgb2YgdGhlIHJvbGxpbmdcbiAqIHJlLXJlYWQsIG5vdCBhIHJlYWQgZXZlcnkgcmVmcmVzaCwgc28gdGhlIGJvdW5kIGlzIHNldCBieSBob3cgbWFueSB0YWdzIGFuXG4gKiBpbnN0YW5jZSByZWFsbHkgdXNlcy4gRXZlcnkgcGF0aCBpcyBhIHRhZyBvZiBpdHMgb3duIChgX05fVF8vPHBhdGg+YCksIGFuZCBhdFxuICogMTAwMCBhbiBhcHAgb2YgMTAwMCB0YWdnZWQgcGFnZXMga2VwdCBldmljdGluZyB3aGF0IGl0IHdhcyBhYm91dCB0byBuZWVkOlxuICogaGFsZiBpdHMgcmVxdWVzdHMgcmUtcmVhZCBhIG1hcmtlci5cbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfTUFYX1RSQUNLRURfVEFHUyA9IDEwXzAwMDtcblxuLyoqXG4gKiBUaGUgcmV2YWxpZGF0aW9uIHRhYmxlJ3MgbWFya2VyIHJvd3MgYW5kIGl0cyBsb2csIHdoaWNoIGFyZSBvbmx5IGV2ZXIgdXNlZFxuICogdG9nZXRoZXIsIG9yIG5laXRoZXIgZm9yIHRhZ3MgbG9jYWwgdG8gdGhpcyBwcm9jZXNzLlxuICovXG5leHBvcnQgdHlwZSBUYWdUYWJsZSA9XG4gIHwgeyBtYXJrZXJzOiBUYWdNYXJrZXJUYWJsZTsgbG9nOiBSZXZhbGlkYXRpb25Mb2cgfVxuICB8IHsgbWFya2Vycz86IHVuZGVmaW5lZDsgbG9nPzogdW5kZWZpbmVkIH07XG5cbi8qKiBIb3cge0BsaW5rIFRyYWNrZWRUYWdNYXJrZXJzfSBpcyBidWlsdC4gKi9cbmV4cG9ydCB0eXBlIFRyYWNrZWRUYWdNYXJrZXJzT3B0aW9ucyA9IFRhZ1RhYmxlICYge1xuICAvKipcbiAgICogSG93IG9mdGVuLCBhdCBtb3N0LCB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnMucmVmcmVzaH0gcmVhZHMgYW55dGhpbmcuXG4gICAqIEBkZWZhdWx0IERFRkFVTFRfVEFHX1JFRlJFU0hfTVNcbiAgICovXG4gIHJlZnJlc2hJbnRlcnZhbE1zPzogbnVtYmVyO1xuICBtYXhUcmFja2VkVGFncz86IG51bWJlcjtcbiAgLyoqIEBzZWUgREVGQVVMVF9UQUdfUkVTWU5DX01TICovXG4gIHJlc3luY0ludGVydmFsTXM/OiBudW1iZXI7XG4gIC8qKiBUaGUgd2FsbCBjbG9jayB0aGUgbG9nJ3MgY3Vyc29yIGFuZCB0aGUgaW50ZXJ2YWxzIGFyZSBrZXB0IG9uLiAqL1xuICBjbG9jaz86ICgpID0+IG51bWJlcjtcbiAgLyoqIGBNYXRoLnJhbmRvbWAsIGZvciB3aGVuIGVhY2ggdGFnJ3MgcmUtcmVhZCBjb21lcyBkdWUuICovXG4gIHJhbmRvbT86ICgpID0+IG51bWJlcjtcbiAgZGVidWc/OiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkO1xuICAvKipcbiAgICogV2hldGhlciB0aGUgcHJvY2VzcyBjYW4gYmUgZnJvemVuIHdpdGggYSByZWZyZXNoIGluIGZsaWdodCwgYXMgYSBMYW1iZGFcbiAgICogc2FuZGJveCBpcyBiZXR3ZWVuIGludm9jYXRpb25zOiB0aGVuIGEgdGltZXIgY2hlY2tzIGl0IGtlcHQgcnVubmluZywgYW5kXG4gICAqIG9uZSB0aGF0IHNwYW5uZWQgYSBmcmVlemUgZG9lcyBub3QgY291bnQuIEEgY29udGFpbmVyIGlzIG5ldmVyIGZyb3plbixcbiAgICogc28gaXQgc2tpcHMgdGhlIHRpbWVyIGFuZCB3YWl0cyBmb3IgdGhlIHJlZnJlc2ggaW4gZmxpZ2h0LCBob3dldmVyIHNsb3cuXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICBjYW5GcmVlemU/OiBib29sZWFuO1xufTtcblxuLyoqXG4gKiBPbmUgaW5zdGFuY2UncyBjb3B5IG9mIHRoZSBtYXJrZXIgcm93cyBvZiB0aGUgdGFncyBpdCBoYXMgbmVlZGVkLCBrZXB0XG4gKiBjdXJyZW50IHRocm91Z2ggdGhlIHtAbGluayBSZXZhbGlkYXRpb25Mb2d9OiB0aGUgcHJvY2VzcydzIG9uZSB0YWcgbWFuaWZlc3RcbiAqIChgc2hhcmVkVGFnTWFuaWZlc3RgKSwgZm9yIHRoZSBgJ3VzZSBjYWNoZSdgIGhhbmRsZXJzIGFuZCB0aGUgaW5jcmVtZW50YWxcbiAqIGNhY2hlIGFsaWtlLlxuICpcbiAqIE5leHQuanMncyBidWlsdC1pbiBgJ3VzZSBjYWNoZSdgIGhhbmRsZXIga2VlcHMgdGFncyBpbiBhIG1vZHVsZS1sZXZlbCBtYXBcbiAqIChgdGFncy1tYW5pZmVzdC5leHRlcm5hbC5qc2ApIHRoYXQgb25seSBpdHMgb3duIGB1cGRhdGVUYWdzYCB3cml0ZXMsIGFuZCBpdHNcbiAqIGByZWZyZXNoVGFnc2AgaXMgYSBuby1vcCwgc28gYSBgcmV2YWxpZGF0ZVRhZ2Agb24gb25lIGluc3RhbmNlIG5ldmVyIHJlYWNoZXNcbiAqIHRoZSBvdGhlcnM6IHRoZXkga2VlcCBzZXJ2aW5nIHRoZSByZXZhbGlkYXRlZCBlbnRyeSwgaW5jbHVkaW5nIGluc2lkZSBwYWdlc1xuICogdGhhdCBhcmUgYmVpbmcgcmUtcmVuZGVyZWQgKmJlY2F1c2UqIG9mIHRoYXQgcmV2YWxpZGF0aW9uLiBUaGVcbiAqIGBjYWNoZUhhbmRsZXJzYCBpbnRlcmZhY2UncyBhbnN3ZXIgaXMgYHJlZnJlc2hUYWdzYCwgXCJjYWxsZWQgYmVmb3JlIHN0YXJ0aW5nXG4gKiBhIG5ldyByZXF1ZXN0IOKApiB0byByZWZyZXNoIHRoZSBsb2NhbCB0YWdzIG1hbmlmZXN0XCIsIGFuZCB0aGlzIGlzIHRoYXRcbiAqIG1hbmlmZXN0LCBiYWNrZWQgYnkgdGhlIHNhbWUgbWFya2VyIHJvd3MgdGhlIGluY3JlbWVudGFsIGNhY2hlJ3NcbiAqIGByZXZhbGlkYXRlVGFnYCB3cml0ZXMgKGBwayA9IGJ1aWxkSWRgLCBgc2sgPSB0YWdgKS5cbiAqXG4gKiBUaGUgY29zdCBpcyBib3VuZGVkIHBlciBpbnN0YW5jZSwgbm90IHBlciByZXF1ZXN0OlxuICogLSB7QGxpbmsgZW5zdXJlfSByZWFkcyBhIHRhZydzIG1hcmtlciB0aGUgZmlyc3QgdGltZSBpdCBpcyBuZWVkZWQgYW5kIG5vdFxuICogICBhZ2FpbiB1bnRpbCBpdCBpcyBldmljdGVkLCBzbyBhIHRhZyBjb3N0cyBvbmUgcmVhZCBwZXIgaW5zdGFuY2UsIG5vdCBvbmVcbiAqICAgcGVyIHJlcXVlc3QuIEFuIGVudHJ5IGNyZWF0ZWQgc2luY2Uge0BsaW5rIGNvbXBsZXRlU2luY2V9IG5lZWRzIG5vIHJlYWRcbiAqICAgYXQgYWxsLlxuICogLSB7QGxpbmsgcmVmcmVzaH0sIGF0IG1vc3Qgb25jZSBwZXIgYHJlZnJlc2hJbnRlcnZhbE1zYCwgc2VuZHMgb25lIGBRdWVyeWBcbiAqICAgZm9yIHRoZSBsb2cgcm93cyB3cml0dGVuIHNpbmNlIHRoZSBsYXN0IG9uZSwgYW5kIGFwcGxpZXMgdGhvc2Ugb2YgdGFnc1xuICogICB0aGlzIGluc3RhbmNlIHRyYWNrcy4gQ29uY3VycmVudCBjYWxsZXJzIHNoYXJlIGl0LiBBbG9uZ3NpZGUsIGl0IHJlLXJlYWRzXG4gKiAgIHRoZSBtYXJrZXJzIG9mIHVwIHRvIHtAbGluayBCQVRDSF9HRVRfTUFYX0tFWVN9IHRhZ3Mgbm90IHJlYWQgZm9yXG4gKiAgIHtAbGluayBERUZBVUxUX1RBR19SRVNZTkNfTVN9LCBpbiBvbmUgYEJhdGNoR2V0SXRlbWAuXG4gKiBBIHJldmFsaWRhdGlvbiBvbiBhbm90aGVyIGluc3RhbmNlIGlzIHRoZXJlZm9yZSBzZWVuIHdpdGhpblxuICogYHJlZnJlc2hJbnRlcnZhbE1zYCAocGx1cyB0aGUgcXVlcnkgaXRzZWxmKSAtIGJ5IGAndXNlIGNhY2hlJ2AsIGZyb20gdGhlXG4gKiBmaXJzdCByZXF1ZXN0IGFmdGVyIHRoZSBxdWVyeSByZXR1cm5zLCBzaW5jZSBpdHMgYHJlZnJlc2hUYWdzYCBkb2VzIG5vdCB3YWl0XG4gKiBmb3IgaXQgKHNlZSBgdGFnTWV0aG9kc2ApIHVubGVzcyB0aGUgaW5zdGFuY2UgaXMge0BsaW5rIGJlaGluZH0sIHdoaWNoIHRoZVxuICogcnVudGltZSBzZXR0bGVzIGJlZm9yZSBhIHBhZ2UgcmVuZGVyIHN0YXJ0cyAoe0BsaW5rIGNhdGNoVXB9KS4gVGhlIGluc3RhbmNlXG4gKiB0aGF0IHJhbiBpdCBhcHBsaWVzIGl0IGl0c2VsZiwgYXQgb25jZSwgd2l0aCB7QGxpbmsgc2V0fS5cbiAqL1xuZXhwb3J0IGNsYXNzIFRyYWNrZWRUYWdNYXJrZXJzIHtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXJrZXJzOiBUYWdNYXJrZXJUYWJsZSB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBsb2c6IFJldmFsaWRhdGlvbkxvZyB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSByZWZyZXNoSW50ZXJ2YWxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG1heFRyYWNrZWRUYWdzOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzeW5jSW50ZXJ2YWxNczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGNsb2NrOiAoKSA9PiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmFuZG9tOiAoKSA9PiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGVidWc6IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQ7XG4gIC8qKiBCeSB0YWcsIGxlYXN0IHJlY2VudGx5IHVzZWQgZmlyc3QuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdGFncyA9IG5ldyBNYXA8c3RyaW5nLCBUYWdNYXJrZXI+KCk7XG4gIC8qKlxuICAgKiBXaGVuIGVhY2ggdHJhY2tlZCB0YWcncyBtYXJrZXIgaXMgZHVlIHRvIGJlIHJlYWQgYWdhaW46IGEgcmFuZG9tIDc1LTEwMCVcbiAgICogb2YgYHJlc3luY0ludGVydmFsTXNgIGFmdGVyIGl0IHdhcyBsYXN0IGtub3duIGZyb20gdGhlIHRhYmxlIC0gcmVhZCxcbiAgICogd3JpdHRlbiBoZXJlLCBvciBuZXcuIEluIHRoZSBvcmRlciB0aGV5IGJlY2FtZSBrbm93biwgbGVhc3QgcmVjZW50IGZpcnN0LlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBkdWVBdCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVhZGluZyA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPHZvaWQ+PigpO1xuICAvKipcbiAgICogTG9nIHJvd3MgZm9yIHRhZ3Mgd2hvc2UgZmlyc3QgcmVhZCBpcyBpbiBmbGlnaHQsIG1lcmdlZCBieSB0YWc6IHRoZSByZWFkXG4gICAqIG1heSBoYXZlIGJlZW4gYW5zd2VyZWQgYmVmb3JlIHRoZSByZXZhbGlkYXRpb24sIHNvIHRoZXkgYXJlIGFwcGxpZWQgdG8gaXRzXG4gICAqIHJlc3VsdCByYXRoZXIgdGhhbiBkcm9wcGVkLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBwZW5kaW5nUm93cyA9IG5ldyBNYXA8c3RyaW5nLCBUYWdNYXJrZXI+KCk7XG4gIC8qKlxuICAgKiBMb2cgcm93cyBmb3IgdGFncyBub3QgdHJhY2tlZCBhbmQgbm90IGJlaW5nIHJlYWQsIG1lcmdlZCBieSB0YWcsIG9sZGVzdFxuICAgKiBmaXJzdDogd2hhdCB0aGUgbG9nIGhhcyBzYWlkIGFib3V0IHRoZW0gc2luY2Uge0BsaW5rIGNvbXBsZXRlU2luY2V9LiBUYWtlblxuICAgKiBpbnRvIGEgdGFnJ3MgbWFya2VyIHdoZW4gaXQgaXMgcmVhZCBvciB3cml0dGVuLlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBsb2dPbmx5ID0gbmV3IE1hcDxzdHJpbmcsIFRhZ01hcmtlcj4oKTtcbiAgLyoqIFNlZSB7QGxpbmsgY29tcGxldGVTaW5jZX0uICovXG4gIHByaXZhdGUgZmxvb3I6IG51bWJlcjtcbiAgLyoqXG4gICAqIFRoZSBmdXR1cmUgYGV4cGlyZWRBdGBzIG9mIG1hcmtlcnMgZHJvcHBlZCBzaW5jZSwgYXMgYFtmcm9tLCB0b11gLCBpblxuICAgKiBvcmRlcjogb25jZSBgZnJvbWAgaXMgcGFzdCwge0BsaW5rIGNvbXBsZXRlU2luY2V9IG1vdmVzIHRvIGB0b2AsIGFuZCBub3RcbiAgICogYmVmb3JlLCBzaW5jZSBvbmx5IHRoZW4gZG9lcyBpdCBleHBpcmUgYW55dGhpbmcuIGBmcm9tYCBhbmQgYHRvYCBhcmUgdGhlXG4gICAqIHNhbWUgdW50aWwgc3BhbnMgYXJlIG1lcmdlZCBmb3Igc3BhY2UgKHtAbGluayBsYXRlckZsb29yfSkuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGxhdGVyRmxvb3JzOiBbbnVtYmVyLCBudW1iZXJdW10gPSBbXTtcbiAgLyoqIFRoZSBpbi1tZW1vcnkgZW50cnkgc3RvcmVzIGp1ZGdlZCBieSB7QGxpbmsgY29tcGxldGVTaW5jZX0uICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZW50cnlTdG9yZXM6IHtcbiAgICBvbGRlc3RUaW1lc3RhbXA6IChzY2FuOiBib29sZWFuKSA9PiBudW1iZXI7XG4gICAgaG9sZHNBbnk6ICgpID0+IGJvb2xlYW47XG4gIH1bXSA9IFtdO1xuICAvKiogSG93IG1hbnkgdGltZXMge0BsaW5rIGZvcmdldH0gcmFuOiBhIHJlYWQgc3RhcnRlZCBiZWZvcmUgb25lIGlzIG1hZGUgYWdhaW4uICovXG4gIHByaXZhdGUgZm9yZ290dGVuID0gMDtcbiAgLyoqIFRyYWNrZWQgdGFncyB3aG9zZSByZWFkIGZhaWxlZCwgZm9yIHRoZSBuZXh0IHJlZnJlc2ggdG8gcmVhZCBhZ2Fpbi4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB1bnJlYWQgPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgLyoqXG4gICAqIFNldCBpbnNpZGUgYSBwYWdlIHJlbmRlciB7QGxpbmsgY2F0Y2hVcH0gbGV0IGdvLCBmb3IgdGhhdCByZW5kZXIgYWxvbmUuXG4gICAqIFNlZSB7QGxpbmsgYmVoaW5kSW5SZW5kZXJ9LlxuICAgKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjYXVnaHRVcFJlbmRlciA9IG5ldyBBc3luY0xvY2FsU3RvcmFnZTx0cnVlPigpO1xuICAvKiogV2hlbiBgc3luY2AgbGFzdCBzY2FubmVkIHRoZSBlbnRyeSBzdG9yZXMgKHtAbGluayBvbGRlc3RFbnRyeX0pLiAqL1xuICBwcml2YXRlIGxhc3RFbnRyeVNjYW4gPSAtSW5maW5pdHk7XG4gIC8qKlxuICAgKiBObyBgbG9nT25seWAgcm93IGlzIGtub3duIGJ5IGl0IG9yIGVhcmxpZXIsIHNvIGEge0BsaW5rIHBydW5lTG9nZ2VkfVxuICAgKiBhZ2FpbnN0IGl0IG9yIGVhcmxpZXIgZHJvcHMgbm90aGluZzogYSBtYXJrZXIgaXMgb25seSBldmVyIGtub3duIGJ5IGxhdGVyLFxuICAgKiBhcyBpdHMgYGV4cGlyZWRBdGAgcGFzc2VzLlxuICAgKi9cbiAgcHJpdmF0ZSBwcnVuZWRBZ2FpbnN0ID0gLUluZmluaXR5O1xuICAvKiogV2hlbiB0aGUgbGFzdCByZWZyZXNoIHN0YXJ0ZWQsIG9yIHdhcyBza2lwcGVkLiAqL1xuICBwcml2YXRlIGxhc3RSZWZyZXNoID0gLUluZmluaXR5O1xuICAvKipcbiAgICogVGhlIHJlZnJlc2ggaW4gZmxpZ2h0LiBPbmUgbGVmdCBvcGVuIGFjcm9zcyBhIGZyZWV6ZSBjb21lcyBiYWNrIGFmdGVyIHRoZVxuICAgKiB0aGF3IHdpdGggd2hhdCBpdCByZWFkIGJlZm9yZSwgc28ge0BsaW5rIHJlZnJlc2h9IHdhaXRzIGZvciBpdCBhbmQgdGhlblxuICAgKiBmb3IgYSBmcmVzaCBvbmUsIHJhdGhlciB0aGFuIHRoZSBydW50aW1lIHdhaXRpbmcgZm9yIGl0IGJlZm9yZSB0aGUgZnJlZXplOlxuICAgKiB0aGF0IHdvdWxkIGJpbGwgZXZlcnkgTGFtYmRhIGludm9jYXRpb24gZm9yIHRoZSBxdWVyeSdzIHRhaWwuXG4gICAqL1xuICBwcml2YXRlIHJlZnJlc2hpbmc6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBXaGVuIHtAbGluayByZWZyZXNoaW5nfSBsYXN0IHNob3dlZCB0aGUgcHJvY2VzcyBydW5uaW5nOiBhIHRpbWVyIHRpY2tzXG4gICAqIHdoaWxlIGl0IGlzIGluIGZsaWdodCwgYW5kIGEgdGljayB0aGF0IGNvbWVzIGxhdGUsIG9yIG5vbmUgYXQgYWxsLCBtZWFuc1xuICAgKiB0aGUgcHJvY2VzcyB3YXMgcGF1c2VkIC0gZnJvemVuIC0gc2luY2UgaXQgc3RhcnRlZC5cbiAgICovXG4gIHByaXZhdGUgbGFzdFRpY2sgPSAtSW5maW5pdHk7XG4gIC8qKiBXaGV0aGVyIGEgdGljayBjYW1lIGxhdGUgc2luY2Uge0BsaW5rIHJlZnJlc2hpbmd9IHN0YXJ0ZWQuICovXG4gIHByaXZhdGUgcGF1c2VkV2hpbGVSZWZyZXNoaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgdGlja2VyOiBSZXR1cm5UeXBlPHR5cGVvZiBzZXRJbnRlcnZhbD4gfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2FuRnJlZXplOiBib29sZWFuO1xuICAvKipcbiAgICogV2hlbiB0aGUgbGFzdCByZWZyZXNoIHNldHRsZWQsIGVpdGhlciB3YXksIHVubGVzcyBpdCBzcGFubmVkIGEgcGF1c2U6IHdoYXRcbiAgICogaXQga25vd3MgaXMgZnJvbSB0aGVuLiBTZWUge0BsaW5rIGJlaGluZH0uXG4gICAqL1xuICBwcml2YXRlIHNldHRsZWRBdDogbnVtYmVyO1xuICAvKipcbiAgICogV2hlcmUgdGhlIG5leHQgbG9nIHF1ZXJ5IHN0YXJ0cyAoYGNsb2NrKClgKTogdGhlIGxhc3Qgc3VjY2Vzc2Z1bCBvbmUnc1xuICAgKiBzdGFydCwgbGVzcyB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NU30uXG4gICAqL1xuICBwcml2YXRlIGN1cnNvcjogbnVtYmVyO1xuICAvKiogV2hlbiB0aGUgbGFzdCBzdWNjZXNzZnVsIGxvZyBxdWVyeSBzdGFydGVkLCBvciB0aGUgbG9nIHdhcyBmaXJzdCByZWFkLiAqL1xuICBwcml2YXRlIGxhc3RMb2dSZWFkOiBudW1iZXI7XG4gIC8qKiBMb2cgcm93cyBhdCBvciBhZnRlciB0aGUgY3Vyc29yIGFscmVhZHkgYXBwbGllZCwgYnkgc29ydCBrZXkuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgYXBwbGllZCA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XG4gIC8qKiB7QGxpbmsgdXBkYXRlfXMgb2YgdGhlIGN1cnJlbnQgdHVybiwgYnkgdGhlaXIgYXJndW1lbnRzLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHVwZGF0aW5nID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8Ym9vbGVhbj4+KCk7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogVHJhY2tlZFRhZ01hcmtlcnNPcHRpb25zKSB7XG4gICAgdGhpcy5tYXJrZXJzID0gb3B0aW9ucy5tYXJrZXJzO1xuICAgIHRoaXMubG9nID0gb3B0aW9ucy5sb2c7XG4gICAgdGhpcy5yZWZyZXNoSW50ZXJ2YWxNcyA9XG4gICAgICBvcHRpb25zLnJlZnJlc2hJbnRlcnZhbE1zID8/IERFRkFVTFRfVEFHX1JFRlJFU0hfTVM7XG4gICAgdGhpcy5tYXhUcmFja2VkVGFncyA9IG9wdGlvbnMubWF4VHJhY2tlZFRhZ3MgPz8gREVGQVVMVF9NQVhfVFJBQ0tFRF9UQUdTO1xuICAgIHRoaXMucmVzeW5jSW50ZXJ2YWxNcyA9IG9wdGlvbnMucmVzeW5jSW50ZXJ2YWxNcyA/PyBERUZBVUxUX1RBR19SRVNZTkNfTVM7XG4gICAgLy8gTG9va2VkIHVwIG9uIGVhY2ggY2FsbCByYXRoZXIgdGhhbiBib3VuZCBoZXJlLCBzbyBhIHRlc3QncyBgRGF0ZS5ub3dgXG4gICAgLy8gc3B5IGFwcGxpZXMuXG4gICAgdGhpcy5jbG9jayA9IG9wdGlvbnMuY2xvY2sgPz8gKCgpID0+IERhdGUubm93KCkpO1xuICAgIHRoaXMucmFuZG9tID0gb3B0aW9ucy5yYW5kb20gPz8gTWF0aC5yYW5kb207XG4gICAgdGhpcy5kZWJ1ZyA9IG9wdGlvbnMuZGVidWcgPz8gKCgpID0+IHt9KTtcbiAgICB0aGlzLmNhbkZyZWV6ZSA9IG9wdGlvbnMuY2FuRnJlZXplID8/IGZhbHNlO1xuICAgIC8vIE5vdGhpbmcgaXMgdHJhY2tlZCB5ZXQsIHNvIG5vdGhpbmcgYmVmb3JlIHRoaXMgY2FuIGJlIG1pc3NlZDogZXZlcnkgdGFnXG4gICAgLy8gaXMgcmVhZCBmcm9tIGl0cyBtYXJrZXIgdGhlIGZpcnN0IHRpbWUgaXQgaXMgbmVlZGVkLlxuICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgIHRoaXMuY3Vyc29yID0gYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TO1xuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgICB0aGlzLnNldHRsZWRBdCA9IGF0O1xuICAgIHRoaXMuZmxvb3IgPSBtYXJrZXJDbG9jaygpO1xuICB9XG5cbiAgLyoqIGB0YWdgJ3MgbWFya2VyIGFzIHRoaXMgaW5zdGFuY2Uga25vd3MgaXQsIGlmIGl0IHRyYWNrcyBgdGFnYC4gKi9cbiAgZ2V0KHRhZzogc3RyaW5nKTogVGFnTWFya2VyIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy50YWdzLmdldCh0YWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIFNpbmNlIHdoZW4gKGBtYXJrZXJDbG9jaygpYCkgdGhpcyBpbnN0YW5jZSBrbm93cyBvZiBldmVyeSByZXZhbGlkYXRpb24gb2ZcbiAgICogZXZlcnkgdGFnLCB0cmFja2VkIG9yIG5vdDogdHJhY2tlZCBvbmVzIGZyb20gdGhlaXIgbWFya2VycyBhbmQgdGhlIGxvZyxcbiAgICogdGhlIG90aGVycyBmcm9tIHRoZSBsb2cgYWxvbmUgKGBsb2dPbmx5YCkuIFNvIGFuIGVudHJ5IGNyZWF0ZWQgYXQgb3IgYWZ0ZXJcbiAgICogaXQgY2FuIGJlIGp1ZGdlZCBieSB7QGxpbmsgc3RhdGV9IGFuZCB7QGxpbmsgZXhwaXJhdGlvbn0gd2l0aG91dFxuICAgKiB7QGxpbmsgZW5zdXJlfSByZWFkaW5nIGFueXRoaW5nIC0gd2hpY2ggbWF0dGVycyBpbnNpZGUgYSBgJ3VzZSBjYWNoZSdgXG4gICAqIGxvb2t1cCwgd2hlcmUgTmV4dC5qcyB3YWl0cyBmb3IgdGhlIGFuc3dlciBhbmQgYSByZWFkIHB1c2hlcyB0aGUgZW50cnkgb3V0XG4gICAqIG9mIHRoZSBzdGF0aWMgc3RhZ2Ugb2YgYSBzdGFnZWQgcmVuZGVyLlxuICAgKlxuICAgKiBTdGFydHMgYXQgY29uc3RydWN0aW9uOiB0aGUgbG9nIGlzIGZvbGxvd2VkIGZyb20gYmVmb3JlIGl0LiBNb3ZlcyB0byBub3dcbiAgICogd2hlbiB0aGUgdHJhY2tlZCBtYXJrZXJzIGFyZSBmb3Jnb3R0ZW4sIGFuZCBwYXN0IHRoZSByZXZhbGlkYXRpb25zIG9mXG4gICAqIHdoYXRldmVyIGVsc2UgaXQgbGV0cyBnbyBvZiAtIGEgbWFya2VyIGV2aWN0ZWQgZm9yIHNwYWNlLCBhIGxvZyByb3dcbiAgICogcHJ1bmVkIC0gd2hpY2ggYXJlIG5vIGxvbmdlciBrbm93bjogdG8gaXRzIGBleHBpcmVkQXRgIG9ubHkgb25jZSB0aGF0IGlzXG4gICAqIHBhc3QsIHNpbmNlIGEgcHJvZmlsZSdzIGBleHBpcmVgIGNhbiBiZSBhIHllYXIgb3V0LCBhbmQgbW92aW5nIHRoZXJlIGF0XG4gICAqIG9uY2Ugd291bGQgdHVybiB0aGUgcmVhZC1mcmVlIHBhdGggb2ZmIGZvciB0aGUgaW5zdGFuY2UncyBsaWZlLlxuICAgKlxuICAgKiBBIHJvdyBpcyBwcnVuZWQgb25seSBvbmNlIGl0IGlzIG5vIGxhdGVyIHRoYW4gZXZlcnkgZW50cnkgaGVsZCwgc28gdGhhdFxuICAgKiBjb3N0cyB0aG9zZSBlbnRyaWVzIG5vdGhpbmcuIEFuIGVudHJ5IHN0b3JlZCBhZnRlcndhcmRzIHdpdGggYW4gb2xkZXJcbiAgICogYHRpbWVzdGFtcGAgLSBOZXh0LmpzIHN0YW1wcyB0aGUgc3RhcnQgb2YgaXRzIGdlbmVyYXRpb24sIHdoaWNoIGNhblxuICAgKiBvdXRsYXN0IGEgbG9va2JhY2sgLSBpcyBvbGRlciB0aGFuIHRoaXMgdG9vLCBhbmQgaXMgcmVhZCBmaXJzdC5cbiAgICpcbiAgICogSXQgZG9lcyBub3QgY292ZXIgYSByZXZhbGlkYXRpb24gb2xkZXIgdGhhbiB0aGUgbG9nJ3MgZmlyc3QgbG9va2JhY2tcbiAgICogd2hvc2UgYGV4cGlyZWRBdGAgaXMgc3RpbGwgdG8gY29tZSwgd2hpY2ggd291bGQgZXhwaXJlIGFuIGVudHJ5IGNyZWF0ZWRcbiAgICogYWZ0ZXIgaXQuIFNvIHRoZSBgJ3VzZSBjYWNoZSdgIGhhbmRsZXIgcmVhZHMgYW4gZW50cnkncyB0YWdzIGluIHRoZVxuICAgKiBiYWNrZ3JvdW5kIGFzIGl0IHN0b3JlcyBpdC5cbiAgICovXG4gIGdldCBjb21wbGV0ZVNpbmNlKCk6IG51bWJlciB7XG4gICAgY29uc3QgYXQgPSBtYXJrZXJDbG9jaygpO1xuICAgIHdoaWxlICh0aGlzLmxhdGVyRmxvb3JzLmxlbmd0aCA+IDAgJiYgdGhpcy5sYXRlckZsb29yc1swXVswXSA8PSBhdCkge1xuICAgICAgdGhpcy5mbG9vciA9IE1hdGgubWF4KHRoaXMuZmxvb3IsIHRoaXMubGF0ZXJGbG9vcnMuc2hpZnQoKSFbMV0pO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5mbG9vcjtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlciBhbiBpbi1tZW1vcnkgc3RvcmUgd2hvc2UgZW50cmllcyBhcmUganVkZ2VkIGJ5XG4gICAqIHtAbGluayBjb21wbGV0ZVNpbmNlfSwgYnkgdGhlIGB0aW1lc3RhbXBgIG9mIHRoZSBvbGRlc3QgZW50cnkgaXQgaG9sZHM6XG4gICAqIGBsb2dPbmx5YCBrZWVwcyB0aGUgcm93cyB0aGF0IGNvdWxkIHN0aWxsIGFwcGx5IHRvIG9uZSBvZiB0aGVtLCBhbmQgbm9cbiAgICogb3RoZXJzLiBXaXRoIG5vbmUgcmVnaXN0ZXJlZCBpdCBrZWVwcyBub3RoaW5nLiBBc2tlZCB3aXRoIGBzY2FuYCBmYWxzZSxcbiAgICogYG9sZGVzdFRpbWVzdGFtcGAgbWF5IGFuc3dlciBlYXJseSwgYnV0IG5ldmVyIGxhdGUsIHdpdGhvdXQgYSBzY2FuLlxuICAgKi9cbiAganVkZ2VFbnRyaWVzT2YoXG4gICAgb2xkZXN0VGltZXN0YW1wOiAoc2NhbjogYm9vbGVhbikgPT4gbnVtYmVyLFxuICAgIGhvbGRzQW55OiAoKSA9PiBib29sZWFuID0gKCkgPT4gb2xkZXN0VGltZXN0YW1wKGZhbHNlKSA8IEluZmluaXR5LFxuICApOiB2b2lkIHtcbiAgICB0aGlzLmVudHJ5U3RvcmVzLnB1c2goeyBvbGRlc3RUaW1lc3RhbXAsIGhvbGRzQW55IH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIGB0YWdgIHdpdGggYG1hcmtlcmA6IHdoYXQgdGhpcyBpbnN0YW5jZSBqdXN0IHdyb3RlLCB3aGljaCBpdCBrbm93c1xuICAgKiB3aXRob3V0IHJlYWRpbmcgaXQgYmFjay5cbiAgICovXG4gIHNldCh0YWc6IHN0cmluZywgbWFya2VyOiBUYWdNYXJrZXIpOiB2b2lkIHtcbiAgICBjb25zdCBsb2dnZWQgPSB0aGlzLmxvZ09ubHkuZ2V0KHRhZyk7XG4gICAgdGhpcy5sb2dPbmx5LmRlbGV0ZSh0YWcpO1xuICAgIHRoaXMucmVtZW1iZXIodGFnLCBtZXJnZU1hcmtlcnMobWFya2VyLCBsb2dnZWQpKTtcbiAgICB0aGlzLmtub3duKHRhZywgdGhpcy5jbG9jaygpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBOb3RlIGEgdXNlIG9mIGB0YWdzYDogdGhvc2Ugb2YgYW4gZW50cnkgdGhpcyBpbnN0YW5jZSBqdXN0IHN0b3JlZC5cbiAgICpcbiAgICogV2l0aCB0aGUgdGFibGUsIGEgdGFnIG5vdCB0cmFja2VkIHlldCBpcyBsZWZ0IHVudHJhY2tlZCwgdG8gYmUgcmVhZCBieVxuICAgKiB7QGxpbmsgZW5zdXJlfSB0aGUgZmlyc3QgdGltZSBhbiBlbnRyeSBuZWVkcyBpdC4gTm90aGluZyByZXZhbGlkYXRlZCBiZWZvcmVcbiAgICogdGhlIG5ldyBlbnRyeSB3YXMgY3JlYXRlZCBhcHBsaWVzIHRvICppdCosIGJ1dCB0cmFja2luZyBpcyBwZXIgdGFnLCBub3QgcGVyXG4gICAqIGVudHJ5OiB0cmFja2luZyB0aGUgdGFnIHdpdGggYW4gZW1wdHkgbWFya2VyIHdvdWxkIGFsc28gdm91Y2ggZm9yIGV2ZXJ5XG4gICAqIG9sZGVyIGVudHJ5IHRoYXQgY2FycmllcyBpdCAtIG9uZSBhbm90aGVyIGluc3RhbmNlIHN0b3JlZCBpbiBTMywgb3Igb25lXG4gICAqIHRoaXMgaW5zdGFuY2Uga2VwdCBpbiBtZW1vcnkgYWNyb3NzIGEge0BsaW5rIGZvcmdldH0gLSBhbmQgYSByZXZhbGlkYXRpb25cbiAgICogZnJvbSBiZWZvcmUgdGhlIGxvZydzIGN1cnNvciB3b3VsZCBnbyB1bnNlZW4gdW50aWwgdGhlIHJvbGxpbmcgcmUtcmVhZC5cbiAgICpcbiAgICogV2l0aG91dCB0aGUgdGFibGUgZXZlcnkgcmV2YWxpZGF0aW9uIGlzIHRoaXMgcHJvY2VzcydzIG93biwgYXBwbGllZCB3aXRoXG4gICAqIHtAbGluayBzZXR9LCBzbyBhIHRhZyBpcyB0cmFja2VkIGF0IG9uY2UuXG4gICAqL1xuICB0cmFjayh0YWdzOiByZWFkb25seSBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGlmICghdGhpcy5tYXJrZXJzKSB7XG4gICAgICB0aGlzLnRyYWNrVW5yZWFkKHRhZ3MpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICB0aGlzLnRvdWNoKHRhZyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRyYWNrIGB0YWdzYCBhcyB0aGV5IGFyZSBrbm93biBub3csIHdpdGhvdXQgcmVhZGluZyB0aGVtLCB3aXRoIGFuIGVtcHR5XG4gICAqIG1hcmtlciBmb3IgYW55IG5vdCB0cmFja2VkIHlldC5cbiAgICovXG4gIHByaXZhdGUgdHJhY2tVbnJlYWQodGFnczogcmVhZG9ubHkgc3RyaW5nW10pOiB2b2lkIHtcbiAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICBpZiAoIXRoaXMudGFncy5oYXModGFnKSkge1xuICAgICAgICB0aGlzLmtub3duKHRhZywgYXQpO1xuICAgICAgfVxuICAgICAgdGhpcy5yZW1lbWJlcih0YWcsIHRoaXMudGFncy5nZXQodGFnKSA/PyB7fSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgdGhlIG1hcmtlcnMgb2Ygd2hpY2hldmVyIG9mIGB0YWdzYCB0aGlzIGluc3RhbmNlIGRvZXMgbm90IHRyYWNrIHlldC5cbiAgICogTmVlZGVkIGJlZm9yZSBqdWRnaW5nIGFuIGVudHJ5IHRoaXMgaW5zdGFuY2UgZGlkIG5vdCBjcmVhdGUsIHNpbmNlIGl0c1xuICAgKiB0YWdzIG1heSBoYXZlIGJlZW4gcmV2YWxpZGF0ZWQgYXQgYW55IHRpbWUgYmVmb3JlLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKCF0aGlzLm1hcmtlcnMpIHtcbiAgICAgIHRoaXMudHJhY2tVbnJlYWQodGFncyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHdhaXRzOiBQcm9taXNlPHZvaWQ+W10gPSBbXTtcbiAgICBjb25zdCB1bnJlYWQ6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCB0YWcgb2YgbmV3IFNldCh0YWdzKSkge1xuICAgICAgLy8gVHJhY2tlZCBmaXJzdDogYSB0cmFja2VkIHRhZyBpbiBgcmVhZGluZ2AgaXMgb25seSBiZWluZyByZS1yZWFkIGluXG4gICAgICAvLyB0aGUgYmFja2dyb3VuZCAoYHN5bmNgKSwgd2hpY2ggbm90aGluZyBuZWVkcyB0byB3YWl0IGZvci5cbiAgICAgIGNvbnN0IGluRmxpZ2h0ID0gdGhpcy5yZWFkaW5nLmdldCh0YWcpO1xuICAgICAgaWYgKHRoaXMudGFncy5oYXModGFnKSkge1xuICAgICAgICB0aGlzLnRvdWNoKHRhZyk7XG4gICAgICB9IGVsc2UgaWYgKGluRmxpZ2h0KSB7XG4gICAgICAgIHdhaXRzLnB1c2goaW5GbGlnaHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdW5yZWFkLnB1c2godGFnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHVucmVhZC5sZW5ndGggPiAwKSB7XG4gICAgICB3YWl0cy5wdXNoKHRoaXMuc3RhcnRSZWFkKHVucmVhZCkpO1xuICAgIH1cbiAgICBhd2FpdCBQcm9taXNlLmFsbCh3YWl0cyk7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIHJlYWRJbnRvfSBgdGFnc2AsIGFzIHRoZSByZWFkIG9mIGVhY2ggdGhhdCB3aG9ldmVyIG5lZWRzIG9uZSBvZlxuICAgKiB0aGVtIG5leHQgd2FpdHMgb24gKHtAbGluayByZWFkaW5nfSkuIE5ldmVyIHJlamVjdHM6IGEgZmFpbGVkIHJlYWQgbGVhdmVzXG4gICAqIHRoZSB0YWdzIHRyYWNrZWQuXG4gICAqL1xuICBwcml2YXRlIHN0YXJ0UmVhZCh0YWdzOiBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHJlYWQgPSB0aGlzLnJlYWRJbnRvKHRhZ3MpLnRoZW4oKCkgPT4ge1xuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgICB0aGlzLnJlYWRpbmcuZGVsZXRlKHRhZyk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgdGhpcy5yZWFkaW5nLnNldCh0YWcsIHJlYWQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVhZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBsYXN0IHJlZnJlc2ggc2V0dGxlZCBtb3JlIHRoYW4gYHJlZnJlc2hJbnRlcnZhbE1zYCBwbHVzXG4gICAqIHtAbGluayBUQUdfUkVGUkVTSF9HUkFDRV9NU30gYWdvIC0gb25lIHRoYXQgc3Bhbm5lZCBhIGZyZWV6ZSBjb3VudHMgZnJvbVxuICAgKiB3aGVuIGl0IHN0YXJ0ZWQ6IGFmdGVyIHRoZSBpbnN0YW5jZSBzYXQgaWRsZSBvciBmcm96ZW4gLSBvciBhbHdheXMsIHdpdGhcbiAgICogYSBgcmVmcmVzaEludGVydmFsTXNgIG9mIGAwYC4gQW5zd2VyaW5nIGZyb20gd2hhdCBpdCBrbm93cyB0aGVuIGNvdWxkXG4gICAqIHNlcnZlIGFuIGVudHJ5IHJldmFsaWRhdGVkIGVsc2V3aGVyZSBzaW5jZSwgaG93ZXZlciBsb25nIGFnbyB0aGF0IHdhcywgc29cbiAgICogYHJlZnJlc2hUYWdzYCB3YWl0cyBmb3IgdGhlIHJlZnJlc2gsIGFuZCB0aGUgcnVudGltZSB3YWl0cyBmb3IgaXQgYmVmb3JlXG4gICAqIGEgcGFnZSByZW5kZXIgc3RhcnRzICh7QGxpbmsgY2F0Y2hVcH0pLlxuICAgKlxuICAgKiBGcm9tIHdoZW4gaXQgc2V0dGxlZCwgbm90IHdoZW4gaXQgc3RhcnRlZCwgc28gYSBzbG93IHF1ZXJ5IHRoZSBydW50aW1lXG4gICAqIHdhaXRlZCBmb3IgYmVmb3JlIHRoZSByZW5kZXIgZG9lcyBub3QgbGVhdmUgdGhlIGluc3RhbmNlIGJlaGluZCBpbnNpZGVcbiAgICogaXQuIEEgZmFpbGVkIG9uZSBjb3VudHMgdG9vLCBzbyBvbmUgcmVxdWVzdCBkb2VzIG5vdCB3YWl0IGZvciB0d286IHRoZVxuICAgKiBzYW1lIFwiYXNzdW1lIHRoZSBlbnRyeSBpcyB2YWxpZFwiIGEgZmFpbGVkIHJlYWQgYW5zd2VycyB3aXRoLCB1bnRpbCB0aGVcbiAgICogbmV4dCByZWZyZXNoLCBhdCBtb3N0IHRoZSBpbnRlcnZhbCBhbmQgdGhlIGdyYWNlIGxhdGVyLlxuICAgKi9cbiAgZ2V0IGJlaGluZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5sb2cgIT09IHVuZGVmaW5lZCAmJlxuICAgICAgLy8gYDBgIGFza3MgYmVmb3JlIGV2ZXJ5IGNoZWNrLCBzbyBldmVyeSBjaGVjayB3YWl0cyBmb3IgdGhlIGFuc3dlci5cbiAgICAgICh0aGlzLnJlZnJlc2hJbnRlcnZhbE1zID09PSAwIHx8IHRoaXMub3ZlcmR1ZSh0aGlzLnNldHRsZWRBdCkpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgYmVoaW5kfSwgYXMgYHJlZnJlc2hUYWdzYCBhc2tzIGl0OiBuZXZlciBpbnNpZGUgYSBwYWdlJ3MgcmVuZGVyXG4gICAqIHtAbGluayBjYXRjaFVwfSBjYXVnaHQgdXAsIHNpbmNlIHRoZSBydW50aW1lIHNldHRsZWQgaXQgZm9yIHRoYXQgcmVxdWVzdFxuICAgKiBiZWZvcmUgdGhlIHJlbmRlciBzdGFydGVkLCBhbmQgYSB3YWl0IGluc2lkZSBhIGAndXNlIGNhY2hlJ2AgbG9va3VwIGlzXG4gICAqIHdoYXQgaXQgc2V0dGxlZCBpdCB0byBhdm9pZCAtIGEgcmVuZGVyIGNyb3NzaW5nIHRoZSBsaW5lIHBhcnR3YXkgdGhyb3VnaFxuICAgKiB3b3VsZCBvdGhlcndpc2Ugd2FpdCBhZnRlciBhbGwuIFNvIGEgcmV2YWxpZGF0aW9uIGVsc2V3aGVyZSBjYW4gZ28gdW5zZWVuXG4gICAqIGZvciBhIHJlbmRlcidzIGR1cmF0aW9uIG9uIHRvcCBvZiB0aGUgdXN1YWwgd2luZG93LlxuICAgKlxuICAgKiBBIHJvdXRlIGhhbmRsZXIsIHdoaWNoIG5vIGNhdGNoLXVwIHByZWNlZGVzLCB3YWl0cyBhdCB0aGUgcGxhaW4gbGluZS5cbiAgICovXG4gIGdldCBiZWhpbmRJblJlbmRlcigpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5yZWZyZXNoSW50ZXJ2YWxNcyAhPT0gMCAmJiB0aGlzLmNhdWdodFVwUmVuZGVyLmdldFN0b3JlKClcbiAgICAgID8gZmFsc2VcbiAgICAgIDogdGhpcy5iZWhpbmQ7XG4gIH1cblxuICAvKipcbiAgICogV2hldGhlciBhIHJlZ2lzdGVyZWQgc3RvcmUgKHtAbGluayBqdWRnZUVudHJpZXNPZn0pIGhvbGRzIGFueSBlbnRyeTogb25lXG4gICAqIGEgcmVmcmVzaCBjb3VsZCBleHBpcmUuIFdpdGggbm9uZSB0aGVyZSBpcyBub3RoaW5nIHRvIHdhaXQgZm9yIGV2ZW4gd2hlblxuICAgKiB0aGUgaW5zdGFuY2UgaXMge0BsaW5rIGJlaGluZH0sIHNpbmNlIHdoYXRldmVyIGlzIHN0b3JlZCBmcm9tIGhlcmUgb24gaXNcbiAgICogbmV3ZXIgdGhhbiB3aGF0IHRoZSBsb2cgd291bGQgc2F5IC0gd2hpY2ggY292ZXJzIHRoZSBmaXJzdCBgJ3VzZSBjYWNoZSdgXG4gICAqIGNhbGwgb2YgYSBwcm9jZXNzLCB3aGljaCBjcmVhdGVzIHRoZSBoYW5kbGVyIGluc2lkZSB0aGUgcmVuZGVyLlxuICAgKi9cbiAgZ2V0IGhvbGRzRW50cmllcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5lbnRyeVN0b3Jlcy5zb21lKChzdG9yZSkgPT4gc3RvcmUuaG9sZHNBbnkoKSk7XG4gIH1cblxuICAvKipcbiAgICoge0BsaW5rIHJlZnJlc2h9LCB3YWl0ZWQgZm9yIHdoZW4gdGhlIGluc3RhbmNlIGlzIHtAbGluayBiZWhpbmR9LiBUaGVcbiAgICogcnVudGltZSBjYWxscyBpdCBiZWZvcmUgaGFuZGluZyBhIHBhZ2UgcmVxdWVzdCB0byBOZXh0LmpzLCBvdXRzaWRlIHRoZVxuICAgKiBzdGFnZWQgcmVuZGVyIHdob3NlIHN0YXRpYyBzdGFnZSBhIHdhaXQgaW5zaWRlIGEgYCd1c2UgY2FjaGUnYCBsb29rdXBcbiAgICogd291bGQgY3V0IHNob3J0LiBPbmx5IGZvciB0aGUgYCd1c2UgY2FjaGUnYCBoYW5kbGVyJ3MgZW50cmllc1xuICAgKiAoe0BsaW5rIGp1ZGdlRW50cmllc09mfSk6IHRoZSBvdGhlciBjYWNoZXMgd2FpdCBmb3IgdGhlIHJlZnJlc2ggd2hlcmUgdGhleVxuICAgKiByZWFkIGFueXdheS4gTm90IHdpdGggYSBgcmVmcmVzaEludGVydmFsTXNgIG9mIGAwYCBlaXRoZXIsIHdoZXJlXG4gICAqIGByZWZyZXNoVGFnc2AgYXNrcyBhZ2FpbiByZWdhcmRsZXNzLiBUaGVuIGByZW5kZXJgLCBtYXJrZWQgYXMgY2F1Z2h0IHVwXG4gICAqIGZvciAoe0BsaW5rIGJlaGluZEluUmVuZGVyfSkuIFJlamVjdHMgb25seSBhcyBgcmVuZGVyYCBkb2VzLlxuICAgKi9cbiAgYXN5bmMgY2F0Y2hVcDxUPihyZW5kZXI6ICgpID0+IFByb21pc2U8VD4pOiBQcm9taXNlPFQ+IHtcbiAgICBjb25zdCBsb2cgPSAoZXJyb3I6IHVua25vd24pID0+XG4gICAgICBjb25zb2xlLmVycm9yKFwiRXJyb3IgcmVmcmVzaGluZyBjYWNoZSB0YWdzOlwiLCBlcnJvcik7XG4gICAgaWYgKHRoaXMucmVmcmVzaEludGVydmFsTXMgPiAwICYmIHRoaXMuYmVoaW5kKSB7XG4gICAgICBpZiAoIXRoaXMuaG9sZHNFbnRyaWVzKSB7XG4gICAgICAgIC8vIE5vdCBjYXVnaHQgdXAsIHNvIG5vIGdyYWNlOiBhbiBlbnRyeSBzdG9yZWQgbWVhbndoaWxlLCBieSBhbm90aGVyXG4gICAgICAgIC8vIHJlcXVlc3QsIG1ha2VzIHRoZSByZW5kZXIncyBsb29rdXBzIHdhaXQgYXQgdGhlIHBsYWluIGxpbmUuXG4gICAgICAgIHJldHVybiByZW5kZXIoKTtcbiAgICAgIH1cbiAgICAgIGF3YWl0IHRoaXMucmVmcmVzaCgpLmNhdGNoKGxvZyk7XG4gICAgfSBlbHNlIGlmICh0aGlzLnJlZnJlc2hJbnRlcnZhbE1zID4gMCkge1xuICAgICAgLy8gU3RhcnRlZCwgbm90IHdhaXRlZCBmb3IsIGFzIGByZWZyZXNoVGFnc2Agd291bGQ6IGEgcGFnZSB0aGF0IHJlYWRzXG4gICAgICAvLyBubyBjYWNoZSBrZWVwcyB0aGUgaW5zdGFuY2UgY3VycmVudCB0b28sIHJhdGhlciB0aGFuIGZhbGxpbmcgYmVoaW5kXG4gICAgICAvLyBhbmQgbWFraW5nIGEgbGF0ZXIgcmVxdWVzdCB3YWl0LlxuICAgICAgdm9pZCB0aGlzLnJlZnJlc2goKS5jYXRjaChsb2cpO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5jYXVnaHRVcFJlbmRlci5ydW4odHJ1ZSwgcmVuZGVyKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGBhdGAgaXMgbW9yZSB0aGFuIHRoZSBpbnRlcnZhbCBhbmQgdGhlIGdyYWNlIGFnby4gKi9cbiAgcHJpdmF0ZSBvdmVyZHVlKGF0OiBudW1iZXIpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5jbG9jaygpIC0gYXQgPiB0aGlzLnJlZnJlc2hJbnRlcnZhbE1zICsgVEFHX1JFRlJFU0hfR1JBQ0VfTVM7XG4gIH1cblxuICAvKipcbiAgICogQ2F0Y2ggdXAgb24gcmV2YWxpZGF0aW9ucyBvdGhlciBpbnN0YW5jZXMgcmFuLCBhdCBtb3N0IG9uY2UgcGVyXG4gICAqIGByZWZyZXNoSW50ZXJ2YWxNc2AuIFNlZSB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnN9IGZvciB0aGUgY29zdC5cbiAgICovXG4gIGFzeW5jIHJlZnJlc2goKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgbG9nID0gdGhpcy5sb2c7XG4gICAgaWYgKCFsb2cpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMucmVmcmVzaGluZykge1xuICAgICAgLy8gT25lIHN0YXJ0ZWQgYmVmb3JlIGEgZnJlZXplIHJlYWQgdGhlIGxvZyBhcyBpdCB3YXMgdGhlbiwgYW5kIHNheXNcbiAgICAgIC8vIG5vdGhpbmcgb2Ygd2hhdCByYW4gbWVhbndoaWxlOiBhbiBpbnN0YW5jZSBiZWhpbmQgd2FpdHMgZm9yIGEgZnJlc2hcbiAgICAgIC8vIG9uZSwgYWZ0ZXIgaXQuIE9uZSB0aGF0IGlzIG1lcmVseSBzbG93IGlzIGFzIGZyZXNoIGFzIGFueS5cbiAgICAgIGlmICh0aGlzLmJlaGluZCAmJiB0aGlzLnBhdXNlZFNpbmNlUmVmcmVzaFN0YXJ0ZWQoKSkge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWZyZXNoaW5nLnRoZW4oKCkgPT4gdGhpcy5yZWZyZXNoKCkpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaGluZztcbiAgICB9XG4gICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgaWYgKGF0IC0gdGhpcy5sYXN0UmVmcmVzaCA8IHRoaXMucmVmcmVzaEludGVydmFsTXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5sYXN0UmVmcmVzaCA9IGF0O1xuICAgIC8vIFdoYXRldmVyIGdldHMgdHJhY2tlZCBiZWZvcmUgdGhlIG5leHQgcmVmcmVzaCBpcyByZWFkIGZyb20gaXRzIG1hcmtlcixcbiAgICAvLyBzbyB0aGVyZSBpcyBub3RoaW5nIHRvIGNhdGNoIHVwIG9uIHlldCAtIHVubGVzcyBhbiBlbnRyeSBpcyBqdWRnZWQgYnlcbiAgICAvLyBgY29tcGxldGVTaW5jZWAsIHdoaWNoIHJlbGllcyBvbiB0aGUgbG9nIGZvciBldmVyeSB0YWcuIEV2ZW4gd2l0aCBub25lXG4gICAgLy8gaGVsZDogYSByb3cgbGV0IGdvIG9mIHRoZW4gbW92ZXMgYGNvbXBsZXRlU2luY2VgIHBhc3QgaXQsIGZvciBhbiBlbnRyeVxuICAgIC8vIHdob3NlIGdlbmVyYXRpb24gc3RhcnRlZCBiZWZvcmUgdGhhdCByZXZhbGlkYXRpb24gYW5kIHRoYXQgaXMgc3RvcmVkXG4gICAgLy8gYWZ0ZXIgaXQuXG4gICAgaWYgKHRoaXMudGFncy5zaXplID09PSAwICYmIHRoaXMuZW50cnlTdG9yZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuc3RhcnRUaWNraW5nKCk7XG4gICAgdGhpcy5yZWZyZXNoaW5nID0gdGhpcy5zeW5jKGF0LCBsb2cpLmZpbmFsbHkoKCkgPT4ge1xuICAgICAgLy8gT25lIHRoYXQgc3Bhbm5lZCBhIHBhdXNlIGtub3dzIHRoZSBsb2cgYXMgb2YgaXRzIHN0YXJ0IGF0IGJlc3QuIFNvXG4gICAgICAvLyBkb2VzIG9uZSB0aGF0IG9ubHkgbG9va2VkIHBhdXNlZCwgaXRzIGV2ZW50IGxvb3AgaGVsZCB1cDogaXQgY291bnRzXG4gICAgICAvLyBhcyBubyBvbGRlciB0aGFuIGl0cyBzdGFydCwgYXMgaWYgaXQgaGFkIG5vdCBzZXR0bGVkIHNpbmNlLlxuICAgICAgdGhpcy5zZXR0bGVkQXQgPSBNYXRoLm1heChcbiAgICAgICAgdGhpcy5zZXR0bGVkQXQsXG4gICAgICAgIHRoaXMucGF1c2VkU2luY2VSZWZyZXNoU3RhcnRlZCgpID8gdGhpcy5sYXN0UmVmcmVzaCA6IHRoaXMuY2xvY2soKSxcbiAgICAgICk7XG4gICAgICB0aGlzLnN0b3BUaWNraW5nKCk7XG4gICAgICB0aGlzLnJlZnJlc2hpbmcgPSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVmcmVzaGluZztcbiAgfVxuXG4gIHByaXZhdGUgc3RhcnRUaWNraW5nKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5jYW5GcmVlemUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5sYXN0VGljayA9IHRoaXMuY2xvY2soKTtcbiAgICB0aGlzLnBhdXNlZFdoaWxlUmVmcmVzaGluZyA9IGZhbHNlO1xuICAgIHRoaXMudGlja2VyID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICAgICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgICBpZiAoYXQgLSB0aGlzLmxhc3RUaWNrID4gUkVGUkVTSF9QQVVTRV9NUykge1xuICAgICAgICB0aGlzLnBhdXNlZFdoaWxlUmVmcmVzaGluZyA9IHRydWU7XG4gICAgICB9XG4gICAgICB0aGlzLmxhc3RUaWNrID0gYXQ7XG4gICAgfSwgUkVGUkVTSF9USUNLX01TKTtcbiAgICAvLyBOZXZlciB3aGF0IGtlZXBzIGEgcHJvY2VzcyBhbGl2ZS5cbiAgICB0aGlzLnRpY2tlci51bnJlZj8uKCk7XG4gIH1cblxuICBwcml2YXRlIHN0b3BUaWNraW5nKCk6IHZvaWQge1xuICAgIGNsZWFySW50ZXJ2YWwodGhpcy50aWNrZXIpO1xuICAgIHRoaXMudGlja2VyID0gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIHByb2Nlc3Mgd2FzIHBhdXNlZCBzaW5jZSB7QGxpbmsgcmVmcmVzaGluZ30gc3RhcnRlZDogYSB0aWNrXG4gICAqIGNhbWUgbGF0ZSwgb3IgdGhlIG5leHQgb25lIGlzIG92ZXJkdWUgKGFmdGVyIGEgdGhhdywgYSByZXF1ZXN0IGNhbiBydW5cbiAgICogYmVmb3JlIHRoZSB0aW1lciBkb2VzKS5cbiAgICovXG4gIHByaXZhdGUgcGF1c2VkU2luY2VSZWZyZXNoU3RhcnRlZCgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gKFxuICAgICAgdGhpcy5jYW5GcmVlemUgJiZcbiAgICAgICh0aGlzLnBhdXNlZFdoaWxlUmVmcmVzaGluZyB8fFxuICAgICAgICB0aGlzLmNsb2NrKCkgLSB0aGlzLmxhc3RUaWNrID4gUkVGUkVTSF9QQVVTRV9NUylcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZCBhIHJldmFsaWRhdGlvbiBvZiBgdGFnc2A6IGhlcmUgYXQgb25jZSwgYW5kIGluIHRoZSByZXZhbGlkYXRpb25cbiAgICogdGFibGUgZm9yIGV2ZXJ5IG90aGVyIGluc3RhbmNlIC0gdGhlIG1hcmtlciByb3cgcGx1cyBhIGxvZyByb3cgcGVyIHRhZy5cbiAgICpcbiAgICogTmV4dC5qcyBjYWxscyBgcmV2YWxpZGF0ZVRhZ2Agb24gdGhlIGluY3JlbWVudGFsIGNhY2hlIGFuZCBgdXBkYXRlVGFnc2Agb25cbiAgICogZXZlcnkgZGlzdGluY3QgYGNhY2hlSGFuZGxlcnNgIGVudHJ5LCBhbGwgaW4gb25lIHN5bmNocm9ub3VzIGxvb3BcbiAgICogKGByZXZhbGlkYXRpb24tdXRpbHNgKSwgYW5kIGFsbCBvZiB0aGVtIHNoYXJlIHRoaXMgbWFuaWZlc3QuIFNvIGFuXG4gICAqIGlkZW50aWNhbCBjYWxsIGluIHRoZSBzYW1lIHR1cm4gam9pbnMgdGhlIGZpcnN0IGluc3RlYWQgb2Ygd3JpdGluZyB0aGVcbiAgICogcm93cyBhZ2Fpbi4gT25lIGluIGEgbGF0ZXIgdHVybiBpcyBhIHJldmFsaWRhdGlvbiBvZiBpdHMgb3duLCBldmVuIHdoaWxlXG4gICAqIHRoZSBmaXJzdCBvbmUncyB3cml0ZXMgYXJlIGluIGZsaWdodCwgYW5kIGdldHMgaXRzIG93biwgbGF0ZXIsIG1hcmtlci5cbiAgICogTmV2ZXIgcmVqZWN0czogcmVzb2x2ZXMgYGZhbHNlYCB3aGVuIGEgcm93IGZhaWxlZCB0byB3cml0ZSAodGhlIGVycm9yIGlzXG4gICAqIGxvZ2dlZCksIHNvIG90aGVyIGluc3RhbmNlcyBtYXkgbm90IHNlZSBpdC5cbiAgICovXG4gIGFzeW5jIHVwZGF0ZShcbiAgICB0YWdzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGtleSA9IEpTT04uc3RyaW5naWZ5KFt0YWdzLCBkdXJhdGlvbnMgPz8gbnVsbF0pO1xuICAgIGNvbnN0IGluRmxpZ2h0ID0gdGhpcy51cGRhdGluZy5nZXQoa2V5KTtcbiAgICBpZiAoaW5GbGlnaHQpIHtcbiAgICAgIHJldHVybiBpbkZsaWdodDtcbiAgICB9XG4gICAgY29uc3QgdXBkYXRlID0gdGhpcy53cml0ZSh0YWdzLCBkdXJhdGlvbnMpO1xuICAgIHRoaXMudXBkYXRpbmcuc2V0KGtleSwgdXBkYXRlKTtcbiAgICAvLyBGb3Jnb3R0ZW4gYXMgc29vbiBhcyB0aGUgY3VycmVudCB0dXJuJ3MgY2FsbHMgaGF2ZSBiZWVuIG1hZGUuXG4gICAgdm9pZCBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHRoaXMudXBkYXRpbmcuZGVsZXRlKGtleSkpO1xuICAgIHJldHVybiB1cGRhdGU7XG4gIH1cblxuICAvKipcbiAgICogV2hhdCB0aGUgdHJhY2tlZCBtYXJrZXJzIHNheSBhYm91dCBhbiBlbnRyeSBjYXJyeWluZyBgdGFnc2AsIGNyZWF0ZWQgYXRcbiAgICogYGNyZWF0ZWRBdGA6IHRoZSBtb3N0IHNldmVyZSBhbnN3ZXIgb2YgYW55IG9mIHRoZW0uXG4gICAqL1xuICBzdGF0ZSh0YWdzOiByZWFkb25seSBzdHJpbmdbXSwgY3JlYXRlZEF0OiBudW1iZXIpOiBSZXZhbGlkYXRpb25TdGF0ZSB7XG4gICAgLy8gYG1hcmtlckNsb2NrKClgLCBub3QgYERhdGUubm93KClgLCBoZXJlIGFuZCB3aGVyZXZlciBhIG1hcmtlciBpcyBzdGFtcGVkOlxuICAgIC8vIGBjcmVhdGVkQXRgIGlzIG9uIE5leHQuanMncyBjbG9jaywgYW5kIGEgbWFya2VyIG9uIHRoZSB3YWxsIGNsb2NrIHdvdWxkIGJlXG4gICAgLy8gY29tcGFyZWQgYWNyb3NzIHRoZSB0d28sIHNvIGFuIGVudHJ5IHJlZ2VuZXJhdGVkIGp1c3QgYWZ0ZXIgYVxuICAgIC8vIHJldmFsaWRhdGlvbiBjb3VsZCBzdGlsbCByZWFkIGFzIG9sZGVyIHRoYW4gaXQgd2hlcmV2ZXIgdGhleSBkcmlmdC5cbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgbGV0IHN0YXRlOiBSZXZhbGlkYXRpb25TdGF0ZSA9IFwiZnJlc2hcIjtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICBjb25zdCBtYXJrZXIgPSB0aGlzLmtub3duTWFya2VyKHRhZyk7XG4gICAgICBpZiAoIW1hcmtlcikge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IHRhZ1N0YXRlID0gbWFya2VyU3RhdGUobWFya2VyLCBjcmVhdGVkQXQsIGF0KTtcbiAgICAgIGlmICh0YWdTdGF0ZSA9PT0gXCJleHBpcmVkXCIpIHtcbiAgICAgICAgcmV0dXJuIFwiZXhwaXJlZFwiO1xuICAgICAgfVxuICAgICAgaWYgKHRhZ1N0YXRlID09PSBcInN0YWxlXCIpIHtcbiAgICAgICAgc3RhdGUgPSBcInN0YWxlXCI7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBgZ2V0RXhwaXJhdGlvbmAncyBhbnN3ZXI6IHRoZSBsYXRlc3QgdGltZSBhbnkgb2YgYHRhZ3NgIGV4cGlyZWQsIGAwYCBpZlxuICAgKiBub25lIGhhcy4gT25seSBleHBpcmF0aW9ucyBhbHJlYWR5IHBhc3QgY291bnQgLSBhIHByb2ZpbGUncyBmdXR1cmVcbiAgICogYGV4cGlyZWAgaXMgbm90IGFuIGV4cGlyYXRpb24geWV0IC0gYW5kIGEgc3RhbGUgbWFyayBkb2VzIG5vdCwgbWF0Y2hpbmdcbiAgICogTmV4dC5qcydzIGRlZmF1bHQgaGFuZGxlciwgd2hpY2ggcmVhZHMgb25seSBgZXhwaXJlZGAgZm9yIGltcGxpY2l0IHRhZ3MuXG4gICAqL1xuICBleHBpcmF0aW9uKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdKTogbnVtYmVyIHtcbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgbGV0IGxhdGVzdCA9IDA7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy5rbm93bk1hcmtlcih0YWcpO1xuICAgICAgaWYgKCFtYXJrZXIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAobWFya2VyLnJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsYXRlc3QgPSBNYXRoLm1heChsYXRlc3QsIG1hcmtlci5yZXZhbGlkYXRlZEF0KTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXJrZXIuZXhwaXJlZEF0ICE9PSB1bmRlZmluZWQgJiYgbWFya2VyLmV4cGlyZWRBdCA8PSBhdCkge1xuICAgICAgICBsYXRlc3QgPSBNYXRoLm1heChsYXRlc3QsIG1hcmtlci5leHBpcmVkQXQpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbGF0ZXN0O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3cml0ZShcbiAgICB0YWdzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGF0ID0gbWFya2VyQ2xvY2soKTtcbiAgICBjb25zdCBtYXJrZXIgPSBtYXJrZXJGb3IoYXQsIGR1cmF0aW9ucyk7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgdGhpcy5zZXQodGFnLCBhcHBseU1hcmtlcih0aGlzLmdldCh0YWcpLCBtYXJrZXIpKTtcbiAgICB9XG4gICAgY29uc3QgeyBtYXJrZXJzLCBsb2cgfSA9IHRoaXM7XG4gICAgaWYgKCFtYXJrZXJzIHx8ICFsb2cpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCB3cml0ZXM6IFtzdHJpbmcsIFByb21pc2U8dW5rbm93bj5dW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBuZXcgU2V0KHRhZ3MpKSB7XG4gICAgICB3cml0ZXMucHVzaChbXG4gICAgICAgIFwiRXJyb3Igd3JpdGluZyB0YWcgcmV2YWxpZGF0aW9uIG1hcmtlcjpcIixcbiAgICAgICAgLy8gVGhlIHJvdyBhcyBpdCBpcyBub3csIHdoaWNoIGNhcnJpZXMgYW55IGVhcmxpZXIgYHJldmFsaWRhdGVkQXRgXG4gICAgICAgIC8vIGFub3RoZXIgaW5zdGFuY2Ugd3JvdGU6IHRyYWNraW5nIG9ubHkgd2hhdCB0aGlzIGNhbGwgc2V0IHdvdWxkXG4gICAgICAgIC8vIGhpZGUgdGhhdCBvbmUgdW50aWwgdGhlIHJvbGxpbmcgcmUtcmVhZCwgYW5kIGFuIGVudHJ5IG9sZGVyIHRoYW4gaXRcbiAgICAgICAgLy8gd291bGQgcmVhZCBhcyBtZXJlbHkgc3RhbGUuXG4gICAgICAgIG1hcmtlcnMud3JpdGUodGFnLCBhdCwgZHVyYXRpb25zKS50aGVuKChyb3cpID0+IHtcbiAgICAgICAgICBpZiAocm93KSB7XG4gICAgICAgICAgICB0aGlzLnNldCh0YWcsIG1lcmdlTWFya2Vycyh0aGlzLmdldCh0YWcpLCByb3cpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgXSk7XG4gICAgICB3cml0ZXMucHVzaChbXG4gICAgICAgIFwiRXJyb3Igd3JpdGluZyB0YWcgcmV2YWxpZGF0aW9uIGxvZyByb3c6XCIsXG4gICAgICAgIHRoaXMucHV0TG9nUm93KGxvZywgdGFnLCBtYXJrZXIpLFxuICAgICAgXSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQod3JpdGVzLm1hcCgoWywgd3JpdGVdKSA9PiB3cml0ZSkpO1xuICAgIHJlc3VsdHMuZm9yRWFjaCgocmVzdWx0LCBpKSA9PiB7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3Iod3JpdGVzW2ldWzBdLCByZXN1bHQucmVhc29uKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cy5ldmVyeSgocmVzdWx0KSA9PiByZXN1bHQuc3RhdHVzID09PSBcImZ1bGZpbGxlZFwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXQgYHRhZ2AncyBsb2cgcm93LCBzdGFtcGVkIG9uIHRoZSB3YWxsIGNsb2NrICh0aGUgbWFya2VyIHZhbHVlcyBhcmUgb25cbiAgICogTmV4dC5qcydzOiBzZWUge0BsaW5rIFJldmFsaWRhdGlvbkxvZ30pLlxuICAgKlxuICAgKiBSZWFkZXJzIG9ubHkgbG9vayB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NU30gYmVoaW5kIHRoZWlyIGxhc3RcbiAgICogcXVlcnksIHNvIGEgcm93IHRoYXQgc2hvd3MgdXAgbXVjaCBsYXRlciB0aGFuIGl0cyB0aW1lc3RhbXAgLSBhIHNsb3dcbiAgICogY29ubmVjdGlvbiwgcmV0cmllcyB1bmRlciB0aHJvdHRsaW5nIC0gaXMgYmVoaW5kIGV2ZXJ5IGN1cnNvciBhbmQgbmV2ZXJcbiAgICogcmVhZC4gQSBzbG93IHB1dCBpcyB0aGVyZWZvcmUgbWFkZSBhZ2FpbiB1bmRlciBhIGZyZXNoIHRpbWVzdGFtcCwgd2hpY2hcbiAgICogcmVhZGVycyB3aWxsIHNlZTsgb25lIHNsb3cgdHdpY2UgaXMgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwdXRMb2dSb3coXG4gICAgbG9nOiBSZXZhbGlkYXRpb25Mb2csXG4gICAgdGFnOiBzdHJpbmcsXG4gICAgbWFya2VyOiBUYWdNYXJrZXIsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgMjsgYXR0ZW1wdCsrKSB7XG4gICAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICAgIGF3YWl0IGxvZy5wdXQodGFnLCBhdCwgbWFya2VyKTtcbiAgICAgIGlmICh0aGlzLmNsb2NrKCkgLSBhdCA8PSBNQVhfTE9HX1BVVF9NUykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUaGUgcmV2YWxpZGF0aW9uIGxvZyByb3cgZm9yICR7dGFnfSB0b29rIGxvbmdlciB0aGFuIHJlYWRlcnMgbG9vayBiYWNrYCxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIE9uZSByZWZyZXNoIHN0YXJ0ZWQgYXQgYGF0YDogdGhlIGxvZyByb3dzIHNpbmNlIHRoZSBjdXJzb3IsIGFuZCB0aGUgbmV4dFxuICAgKiBzbGljZSBvZiB0aGUgcm9sbGluZyByZS1yZWFkLlxuICAgKlxuICAgKiBBIGZhaWxlZCBxdWVyeSBjaGFuZ2VzIG5vdGhpbmcgYnV0IHRoZSBsb2c6IHRoZSB0YWdzIHN0YXkgdHJhY2tlZCBhcyB0aGV5XG4gICAqIHdlcmUsIGFuZCB0aGUgbmV4dCByZWZyZXNoIGFza3MgYWdhaW4gZnJvbSB0aGUgc2FtZSBjdXJzb3IuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHN5bmMoYXQ6IG51bWJlciwgbG9nOiBSZXZhbGlkYXRpb25Mb2cpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoYXQgLSB0aGlzLmxhc3RMb2dSZWFkID4gTUFYX1JFVkFMSURBVElPTl9MT0dfR0FQX01TKSB7XG4gICAgICB0aGlzLmZvcmdldChcbiAgICAgICAgYXQsXG4gICAgICAgIFwidGhlIHJldmFsaWRhdGlvbiBsb2cgbWF5IG5vdCBjb3ZlciB0aGUgZ2FwIHNpbmNlIGl0IHdhcyBsYXN0IHJlYWRcIixcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFRoZSByb2xsaW5nIHJlLXJlYWQgcnVucyBhbG9uZ3NpZGUsIG5vdCB3YWl0ZWQgZm9yOiBjYXRjaGluZyB1cCBuZWVkc1xuICAgIC8vIG9ubHkgdGhlIGxvZywgYW5kIGEgdGhyb3R0bGVkIGBCYXRjaEdldEl0ZW1gIHNob3VsZCBub3QgaG9sZCB0aGVcbiAgICAvLyByZXF1ZXN0IGBjYXRjaFVwYCBtYWtlcyB3YWl0LiBBIGZvcmdldCBtZWFud2hpbGUgcmVhZHMgaXQgYWdhaW4uXG4gICAgY29uc3QgZHVlID0gdGhpcy5kdWUoYXQpO1xuICAgIGlmIChkdWUubGVuZ3RoID4gMCkge1xuICAgICAgdm9pZCB0aGlzLnN0YXJ0UmVhZChkdWUpO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBsb2cucXVlcnkodGhpcy5jdXJzb3IpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHJlYWRpbmcgdGFnIHJldmFsaWRhdGlvbiBsb2c6XCIsIGVycm9yKTtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHJlc3VsdC50cnVuY2F0ZWQpIHtcbiAgICAgIHRoaXMuZm9yZ2V0KFxuICAgICAgICBhdCxcbiAgICAgICAgXCJ0aGUgcmV2YWxpZGF0aW9uIGxvZyBoYXMgbW9yZSByb3dzIHRoYW4gb25lIHF1ZXJ5IHJlYWRzXCIsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBBIHNjYW4gb2YgZXZlcnkgZW50cnkgaGVsZCwgd2hpY2ggYWxzbyBkcm9wcyB0aGUgZXhwaXJlZCBvbmVzLCBvbmNlIGluXG4gICAgLy8gYSB3aGlsZTogc28gZXhwaXJlZCBlbnRyaWVzIG5ldmVyIHJlYWQgYWdhaW4gZG9uJ3QgcGlsZSB1cCBhaGVhZCBvZlxuICAgIC8vIGxpdmUgb25lcy4gSW4gYmV0d2VlbiwgdGhlIHN0b3JlcyBhbnN3ZXIgZWFybHkgd2l0aG91dCBvbmUsIHdoaWNoIG9ubHlcbiAgICAvLyBrZWVwcyByb3dzIGluIGBsb2dPbmx5YCBhIGxpdHRsZSBsb25nZXIuXG4gICAgY29uc3Qgc2NhbiA9IGF0IC0gdGhpcy5sYXN0RW50cnlTY2FuID4gRU5UUllfU0NBTl9JTlRFUlZBTF9NUztcbiAgICBpZiAoc2Nhbikge1xuICAgICAgdGhpcy5sYXN0RW50cnlTY2FuID0gYXQ7XG4gICAgfVxuICAgIGNvbnN0IG9sZGVzdCA9IHRoaXMub2xkZXN0RW50cnkoc2Nhbik7XG4gICAgbGV0IGFwcGxpZWQgPSAwO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJlc3VsdC5yb3dzKSB7XG4gICAgICBpZiAodGhpcy5hcHBsaWVkLmhhcyhyb3cuc2spKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy50YWdzLmdldChyb3cudGFnKTtcbiAgICAgIGlmIChtYXJrZXIpIHtcbiAgICAgICAgLy8gYHNldGAgb24gYSBrZXkgYWxyZWFkeSB0aGVyZSBrZWVwcyBpdHMgcGxhY2UgaW4gdGhlIExSVSBvcmRlcjogYmVpbmdcbiAgICAgICAgLy8gcmV2YWxpZGF0ZWQgZWxzZXdoZXJlIGlzIG5vdCBhIHVzZS5cbiAgICAgICAgdGhpcy50YWdzLnNldChyb3cudGFnLCBtZXJnZU1hcmtlcnMobWFya2VyLCByb3cubWFya2VyKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMucmVhZGluZy5oYXMocm93LnRhZykpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nUm93cy5zZXQoXG4gICAgICAgICAgcm93LnRhZyxcbiAgICAgICAgICBtZXJnZU1hcmtlcnModGhpcy5wZW5kaW5nUm93cy5nZXQocm93LnRhZyksIHJvdy5tYXJrZXIpLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQSB0YWcgdGhpcyBpbnN0YW5jZSBkb2VzIG5vdCB0cmFjayBpcyByZWFkIGZyb20gaXRzIG1hcmtlciB3aGVuIGl0XG4gICAgICAgIC8vIGlzIG5leHQgbmVlZGVkIC0gYnV0IG5vdCB5ZXQgbWFya2VkIGFwcGxpZWQsIGJlY2F1c2UgdGhhdCByZWFkIG1heVxuICAgICAgICAvLyBtaXNzIHRoaXMgdmVyeSByZXZhbGlkYXRpb246IHRoZSB3cml0ZXIgcHV0cyB0aGUgbG9nIHJvdyBhbmQgdGhlXG4gICAgICAgIC8vIG1hcmtlciBhdCB0aGUgc2FtZSB0aW1lLCBhbmQgdGhlIHJlYWQgaXMgYW4gZXZlbnR1YWxseSBjb25zaXN0ZW50XG4gICAgICAgIC8vIGBCYXRjaEdldEl0ZW1gIHRoYXQgY2FuIGxhbmQgbWlsbGlzZWNvbmRzIGFmdGVyIHRoZSByb3cgc2hvd2VkIGhlcmUuXG4gICAgICAgIC8vIE1hcmtlZCBhcHBsaWVkLCB0aGUgcm93IHdhcyBza2lwcGVkIGJ5IGV2ZXJ5IHF1ZXJ5IHRoZSBsb29rYmFja1xuICAgICAgICAvLyByZXR1cm5lZCBpdCB0bywgYW5kIHRoZSBwcmUtcmV2YWxpZGF0aW9uIG1hcmtlciBzdG9vZCB1bnRpbCB0aGVcbiAgICAgICAgLy8gcm9sbGluZyByZS1yZWFkLiBMZWZ0IHVubWFya2VkLCB0aGUgbmV4dCByZWZyZXNoIGFwcGxpZXMgaXQgdG9cbiAgICAgICAgLy8gd2hhdGV2ZXIgdGhhdCByZWFkIGZvdW5kOyBpdCBjb3N0cyBubyByZWFkLCBvbmx5IHRoZSByb3cgYmVpbmdcbiAgICAgICAgLy8gbG9va2VkIGF0IGFnYWluIHdoaWxlIGl0IGlzIGluc2lkZSB0aGUgbG9va2JhY2suXG4gICAgICAgIC8vXG4gICAgICAgIC8vIEtlcHQgbWVhbndoaWxlIGluIGBsb2dPbmx5YCwgd2hpY2ggaXMgYWxsIGBjb21wbGV0ZVNpbmNlYCBuZWVkcy5cbiAgICAgICAgdGhpcy5yZW1lbWJlckxvZ2dlZChcbiAgICAgICAgICByb3cudGFnLFxuICAgICAgICAgIG1lcmdlTWFya2Vycyh0aGlzLmxvZ09ubHkuZ2V0KHJvdy50YWcpLCByb3cubWFya2VyKSxcbiAgICAgICAgICBvbGRlc3QsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5hcHBsaWVkLnNldChyb3cuc2ssIHJvdy5hdCk7XG4gICAgICBhcHBsaWVkKys7XG4gICAgfVxuICAgIGlmIChvbGRlc3QgPiB0aGlzLnBydW5lZEFnYWluc3QpIHtcbiAgICAgIHRoaXMucHJ1bmVMb2dnZWQob2xkZXN0KTtcbiAgICB9XG4gICAgLy8gVGhlIHJvd3MganVzdCBrZXB0IGFyZSBrbm93biBieSBsYXRlciB0aGFuIGBvbGRlc3RgIHRvby5cbiAgICB0aGlzLnBydW5lZEFnYWluc3QgPSBvbGRlc3Q7XG4gICAgdGhpcy5sYXN0TG9nUmVhZCA9IGF0O1xuICAgIHRoaXMuYWR2YW5jZShhdCAtIFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVMpO1xuICAgIHRoaXMuZGVidWcoXG4gICAgICBgcmVhZCAke3Jlc3VsdC5yb3dzLmxlbmd0aH0gcmV2YWxpZGF0aW9uIGxvZyByb3dzICgke2FwcGxpZWR9IGFwcGxpZWQpYCxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIFRoZSB0YWdzIHRvIHJlYWQgb24gdGhpcyByZWZyZXNoLCBhdCBtb3N0IG9uZSBgQmF0Y2hHZXRJdGVtYCdzIHdvcnRoOlxuICAgKiB0aG9zZSB3aG9zZSByZWFkIGZhaWxlZCwgdGhlbiB0aG9zZSB3aG9zZSByZS1yZWFkIGhhcyBjb21lIGR1ZSwgaW4gdGhlXG4gICAqIG9yZGVyIHRoZXkgd2VyZSBsYXN0IHJlYWQuXG4gICAqL1xuICBwcml2YXRlIGR1ZShhdDogbnVtYmVyKTogc3RyaW5nW10ge1xuICAgIGNvbnN0IGR1ZTogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0aGlzLnVucmVhZCkge1xuICAgICAgaWYgKGR1ZS5sZW5ndGggPj0gQkFUQ0hfR0VUX01BWF9LRVlTKSByZXR1cm4gZHVlO1xuICAgICAgaWYgKCF0aGlzLnJlYWRpbmcuaGFzKHRhZykpIHtcbiAgICAgICAgZHVlLnB1c2godGFnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gS25vd24gaW4gdGltZSBvcmRlciwgYW5kIGVhY2ggZHVlIGF0IG1vc3QgYGppdHRlcmAgZWFybGllciB0aGFuIHRoZVxuICAgIC8vIHRhZ3MgYWZ0ZXIgaXQ6IHBhc3QgYSB0YWcgZHVlIG1vcmUgdGhhbiB0aGF0IGZyb20gbm93LCBub25lIGlzIGR1ZS5cbiAgICBjb25zdCBqaXR0ZXIgPSB0aGlzLnJlc3luY0ludGVydmFsTXMgKiBUQUdfUkVTWU5DX0pJVFRFUjtcbiAgICBmb3IgKGNvbnN0IFt0YWcsIGR1ZUF0XSBvZiB0aGlzLmR1ZUF0KSB7XG4gICAgICBpZiAoZHVlLmxlbmd0aCA+PSBCQVRDSF9HRVRfTUFYX0tFWVMgfHwgZHVlQXQgLSBqaXR0ZXIgPiBhdCkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGlmIChkdWVBdCA8PSBhdCAmJiAhdGhpcy51bnJlYWQuaGFzKHRhZykgJiYgIXRoaXMucmVhZGluZy5oYXModGFnKSkge1xuICAgICAgICBkdWUucHVzaCh0YWcpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gZHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEZvcmdldCBldmVyeSB0cmFja2VkIG1hcmtlciwgYW5kIGZvbGxvdyB0aGUgbG9nIGZyb20gYGF0YDogd2hhdCBpcyBuZWVkZWRcbiAgICogbmV4dCBpcyByZWFkIGZyb20gaXRzIG1hcmtlciBhcyBpdCBpcyBuZWVkZWQsIHNwcmVhZCBvdmVyIHRoZSByZXF1ZXN0c1xuICAgKiB0aGF0IG5lZWQgaXQsIHJhdGhlciB0aGFuIGV2ZXJ5IHRyYWNrZWQgdGFnIHJlLXJlYWQgYXQgb25jZS5cbiAgICovXG4gIHByaXZhdGUgZm9yZ2V0KGF0OiBudW1iZXIsIHdoeTogc3RyaW5nKTogdm9pZCB7XG4gICAgdGhpcy5kZWJ1ZyhgZm9yZ2V0dGluZyAke3RoaXMudGFncy5zaXplfSB0cmFja2VkIHRhZ3M6ICR7d2h5fWApO1xuICAgIHRoaXMuZm9yZ290dGVuKys7XG4gICAgLy8gV2hhdCB0aGUgbWFya2VycyBleHBpcmUgbGF0ZXIgaXMgc3RpbGwgdG8gYXBwbHkgb25jZSBpdCBpcyBwYXN0LlxuICAgIGZvciAoY29uc3QgbWFya2VyIG9mIHRoaXMudGFncy52YWx1ZXMoKSkge1xuICAgICAgdGhpcy5yYWlzZUZsb29yKG1hcmtlcik7XG4gICAgfVxuICAgIGZvciAoY29uc3QgbWFya2VyIG9mIHRoaXMubG9nT25seS52YWx1ZXMoKSkge1xuICAgICAgdGhpcy5yYWlzZUZsb29yKG1hcmtlcik7XG4gICAgfVxuICAgIHRoaXMudGFncy5jbGVhcigpO1xuICAgIHRoaXMuZHVlQXQuY2xlYXIoKTtcbiAgICB0aGlzLnVucmVhZC5jbGVhcigpO1xuICAgIHRoaXMuYXBwbGllZC5jbGVhcigpO1xuICAgIHRoaXMubG9nT25seS5jbGVhcigpO1xuICAgIC8vIE5ldmVyIGJhY2s6IGEgbWFya2VyIGRyb3BwZWQgZWFybGllciBtYXkgaGF2ZSBleHBpcmVkIGVudHJpZXMgbGF0ZXIuXG4gICAgdGhpcy5mbG9vciA9IE1hdGgubWF4KHRoaXMuZmxvb3IsIG1hcmtlckNsb2NrKCkpO1xuICAgIHRoaXMuY3Vyc29yID0gYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TO1xuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgfVxuXG4gIC8qKlxuICAgKiBNb3ZlIHRoZSBjdXJzb3IgZm9yd2FyZCB0byBgY3Vyc29yYCwgZm9yZ2V0dGluZyBhcHBsaWVkIHJvd3MgYmVmb3JlIGl0OlxuICAgKiBubyBxdWVyeSByZXR1cm5zIHRoZW0gYWdhaW4uXG4gICAqL1xuICBwcml2YXRlIGFkdmFuY2UoY3Vyc29yOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoY3Vyc29yIDw9IHRoaXMuY3Vyc29yKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuY3Vyc29yID0gY3Vyc29yO1xuICAgIGZvciAoY29uc3QgW3NrLCBhdF0gb2YgdGhpcy5hcHBsaWVkKSB7XG4gICAgICBpZiAoYXQgPCBjdXJzb3IpIHtcbiAgICAgICAgdGhpcy5hcHBsaWVkLmRlbGV0ZShzayk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlYWQgYHRhZ3NgIGZyb20gdGhlIHRhYmxlLCBhbmQgcmVwb3J0IHdoZXRoZXIgdGhhdCB3b3JrZWQuIEEgcmVhZCB0aGF0XG4gICAqIGZhaWxzIGxlYXZlcyB0aGVtIHRyYWNrZWQgYXMgdGhleSB3ZXJlLCBhbmQgdGhlIG5leHQgcmVmcmVzaCByZWFkcyB0aGVtXG4gICAqIGFnYWluOiB0aGUgc2FtZSBcImFzc3VtZSB0aGUgZW50cnkgaXMgdmFsaWRcIiB0aGUgaW5jcmVtZW50YWwgY2FjaGUgaGFzXG4gICAqIGFsd2F5cyBhbnN3ZXJlZCB3aXRoLCByYXRoZXIgdGhhbiBhIHJlYWQgb24gZXZlcnkgcmVxdWVzdCB3aGlsZSBEeW5hbW9EQlxuICAgKiBpcyB1bmF2YWlsYWJsZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcmVhZEludG8odGFnczogc3RyaW5nW10sIGFnYWluID0gZmFsc2UpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBpZiAodGFncy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICBjb25zdCBmb3Jnb3R0ZW4gPSB0aGlzLmZvcmdvdHRlbjtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVhZCA9IGF3YWl0IHRoaXMubWFya2VycyEucmVhZCh0YWdzKTtcbiAgICAgIGlmICh0aGlzLmZvcmdvdHRlbiAhPT0gZm9yZ290dGVuICYmICFhZ2Fpbikge1xuICAgICAgICAvLyBSZWFkIGJlZm9yZSBhIGZvcmdldCAtIGFjcm9zcyBhIGZyZWV6ZSwgYXMgbGlrZSBhcyBub3QgLSBzbyBhc1xuICAgICAgICAvLyBzdGFsZSBhcyB3aGF0IGl0IGZvcmdvdC4gUmVhZCBhZ2FpbiByYXRoZXIgdGhhbiBsZWF2ZSB0aGUgdGFnc1xuICAgICAgICAvLyB1bnRyYWNrZWQ6IHdob2V2ZXIgd2FpdHMgb24gdGhpcyByZWFkIChgcmVhZGluZ2ApIGp1ZGdlcyBlbnRyaWVzXG4gICAgICAgIC8vIGJ5IGl0IG5leHQsIGFuZCBhbiB1bnRyYWNrZWQgdGFnIGNvdW50cyBmb3Igbm90aGluZy4gT25jZTogYSBydW5cbiAgICAgICAgLy8gb2YgZm9yZ2V0cyAoYSB0cnVuY2F0ZWQgbG9nLCBxdWVyeSBhZnRlciBxdWVyeSkgd291bGQgb3RoZXJ3aXNlXG4gICAgICAgIC8vIGtlZXAgdGhlbSB3YWl0aW5nLCBhbmQgdGhlIHNlY29uZCByZWFkIGJlZ2FuIGFmdGVyIHRoZSBmaXJzdC5cbiAgICAgICAgcmV0dXJuIGF3YWl0IHRoaXMucmVhZEludG8odGFncywgdHJ1ZSk7XG4gICAgICB9XG4gICAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICAgIHRoaXMudW5yZWFkLmRlbGV0ZSh0YWcpO1xuICAgICAgICB0aGlzLnJlbWVtYmVyKFxuICAgICAgICAgIHRhZyxcbiAgICAgICAgICBtZXJnZU1hcmtlcnMoXG4gICAgICAgICAgICBtZXJnZU1hcmtlcnModGhpcy50YWdzLmdldCh0YWcpLCByZWFkLmdldCh0YWcpKSxcbiAgICAgICAgICAgIHRoaXMudGFrZVBlbmRpbmdSb3dzKHRhZyksXG4gICAgICAgICAgKSxcbiAgICAgICAgKTtcbiAgICAgICAgdGhpcy5rbm93bih0YWcsIGF0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuZGVidWcoYHJlYWQgJHt0YWdzLmxlbmd0aH0gdGFnIG1hcmtlcnMgKCR7cmVhZC5zaXplfSBzZXQpYCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHJlYWRpbmcgdGFnIG1hcmtlcnM6XCIsIGVycm9yKTtcbiAgICAgIGlmICh0aGlzLmZvcmdvdHRlbiAhPT0gZm9yZ290dGVuICYmICFhZ2Fpbikge1xuICAgICAgICByZXR1cm4gdGhpcy5yZWFkSW50byh0YWdzLCB0cnVlKTtcbiAgICAgIH1cbiAgICAgIHRoaXMudHJhY2tVbnJlYWQodGFncyk7XG4gICAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICAgIHRoaXMudW5yZWFkLmFkZCh0YWcpO1xuICAgICAgICBjb25zdCBwZW5kaW5nID0gdGhpcy50YWtlUGVuZGluZ1Jvd3ModGFnKTtcbiAgICAgICAgaWYgKHBlbmRpbmcpIHtcbiAgICAgICAgICB0aGlzLnJlbWVtYmVyKHRhZywgbWVyZ2VNYXJrZXJzKHRoaXMudGFncy5nZXQodGFnKSwgcGVuZGluZykpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0YWtlUGVuZGluZ1Jvd3ModGFnOiBzdHJpbmcpOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLnBlbmRpbmdSb3dzLmdldCh0YWcpO1xuICAgIGNvbnN0IGxvZ2dlZCA9IHRoaXMubG9nT25seS5nZXQodGFnKTtcbiAgICB0aGlzLnBlbmRpbmdSb3dzLmRlbGV0ZSh0YWcpO1xuICAgIHRoaXMubG9nT25seS5kZWxldGUodGFnKTtcbiAgICByZXR1cm4gbG9nZ2VkID8gbWVyZ2VNYXJrZXJzKGxvZ2dlZCwgcGVuZGluZykgOiBwZW5kaW5nO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoYXQgdGhpcyBpbnN0YW5jZSBrbm93cyBvZiBgdGFnYDogdHJhY2tlZCwgb3IgZnJvbSB0aGUgbG9nIGFsb25lIC1cbiAgICogaW5jbHVkaW5nIHJvd3MgdGhhdCBhcnJpdmVkIHdoaWxlIGl0cyBmaXJzdCByZWFkIGlzIGluIGZsaWdodC5cbiAgICovXG4gIHByaXZhdGUga25vd25NYXJrZXIodGFnOiBzdHJpbmcpOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHRyYWNrZWQgPSB0aGlzLnRhZ3MuZ2V0KHRhZyk7XG4gICAgaWYgKHRyYWNrZWQpIHtcbiAgICAgIHJldHVybiB0cmFja2VkO1xuICAgIH1cbiAgICBjb25zdCBsb2dnZWQgPSB0aGlzLmxvZ09ubHkuZ2V0KHRhZyk7XG4gICAgY29uc3QgcGVuZGluZyA9IHRoaXMucGVuZGluZ1Jvd3MuZ2V0KHRhZyk7XG4gICAgcmV0dXJuIGxvZ2dlZCB8fCBwZW5kaW5nID8gbWVyZ2VNYXJrZXJzKGxvZ2dlZCwgcGVuZGluZykgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogS2VlcCBgdGFnYCdzIGxvZyByb3dzIGluIGBsb2dPbmx5YCwgdW5sZXNzIHRoZXkgY2Fubm90IGFwcGx5IHRvIGFuIGVudHJ5XG4gICAqIGhlbGQsIGBvbGRlc3RgIG9yIG5ld2VyIChzZWUge0BsaW5rIHBydW5lTG9nZ2VkfSksIGFzIGJvdW5kZWQgYXMgdGhlXG4gICAqIHRyYWNrZWQgdGFncy4gRWl0aGVyIHdheSBhIHJvdyBsZXQgZ28gb2YgdGFrZXMgd2hhdCBpdCBrbmV3IHdpdGggaXQsIHNvXG4gICAqIGBjb21wbGV0ZVNpbmNlYCBtb3ZlcyBwYXN0IGl0LlxuICAgKi9cbiAgcHJpdmF0ZSByZW1lbWJlckxvZ2dlZCh0YWc6IHN0cmluZywgbWFya2VyOiBUYWdNYXJrZXIsIG9sZGVzdDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5sb2dPbmx5LmRlbGV0ZSh0YWcpO1xuICAgIGlmIChrbm93bkJ5KG1hcmtlciwgbWFya2VyQ2xvY2soKSkgPD0gb2xkZXN0KSB7XG4gICAgICB0aGlzLnJhaXNlRmxvb3IobWFya2VyKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5sb2dPbmx5LnNldCh0YWcsIG1hcmtlcik7XG4gICAgZm9yIChjb25zdCBbZmlyc3QsIGRyb3BwZWRdIG9mIHRoaXMubG9nT25seSkge1xuICAgICAgaWYgKHRoaXMubG9nT25seS5zaXplIDw9IHRoaXMubWF4VHJhY2tlZFRhZ3MpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICB0aGlzLmxvZ09ubHkuZGVsZXRlKGZpcnN0KTtcbiAgICAgIHRoaXMucmFpc2VGbG9vcihkcm9wcGVkKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogRHJvcCB0aGUgYGxvZ09ubHlgIHJvd3MgdGhhdCBjYW5ub3QgYXBwbHkgdG8gYW4gZW50cnkgaGVsZCwgYG9sZGVzdGAgb3JcbiAgICogbmV3ZXI6IGV2ZXJ5IHJldmFsaWRhdGlvbiB0aGV5IG5hbWUgc28gZmFyIGlzIG5vIGxhdGVyIHRoYW4gaXQuIFRoYXRcbiAgICogbW92ZXMgYGNvbXBsZXRlU2luY2VgIG5vIGZ1cnRoZXIgdGhhbiBgb2xkZXN0YCwgd2hpY2ggY29zdHMgdGhlIGVudHJpZXNcbiAgICogaGVsZCBub3RoaW5nLCBhbmQgYSBwcm9maWxlJ3MgYGV4cGlyZWRBdGAgc3RpbGwgdG8gY29tZSB3YWl0cyBpblxuICAgKiBgbGF0ZXJGbG9vcnNgLiBXaXRob3V0IHRoaXMsIGEgZGVwbG95bWVudCByZXZhbGlkYXRpbmcgbWFueSBkaXN0aW5jdCB0YWdzXG4gICAqIGZpbGxlZCBgbG9nT25seWAgd2l0aCB0YWdzIG5vIGVudHJ5IGhlcmUgY2FycmllcywgYW5kIHRoZSBldmljdGlvbnMgcGFzdFxuICAgKiBpdHMgYm91bmQga2VwdCBtb3ZpbmcgYGNvbXBsZXRlU2luY2VgIHVwIHRvIHRoZSBwcmVzZW50LlxuICAgKi9cbiAgcHJpdmF0ZSBwcnVuZUxvZ2dlZChvbGRlc3Q6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IGF0ID0gbWFya2VyQ2xvY2soKTtcbiAgICBmb3IgKGNvbnN0IFt0YWcsIG1hcmtlcl0gb2YgdGhpcy5sb2dPbmx5KSB7XG4gICAgICBpZiAoa25vd25CeShtYXJrZXIsIGF0KSA8PSBvbGRlc3QpIHtcbiAgICAgICAgdGhpcy5sb2dPbmx5LmRlbGV0ZSh0YWcpO1xuICAgICAgICB0aGlzLnJhaXNlRmxvb3IobWFya2VyKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVGhlIG9sZGVzdCBlbnRyeSB0aW1lc3RhbXAgb2YgYW55IHJlZ2lzdGVyZWQgc3RvcmUsIGBJbmZpbml0eWAgd2l0aCBub25lOlxuICAgKiBlYXJseSwgbmV2ZXIgbGF0ZSwgdW5sZXNzIGBzY2FuYC5cbiAgICovXG4gIHByaXZhdGUgb2xkZXN0RW50cnkoc2NhbjogYm9vbGVhbik6IG51bWJlciB7XG4gICAgbGV0IG9sZGVzdCA9IEluZmluaXR5O1xuICAgIGZvciAoY29uc3QgeyBvbGRlc3RUaW1lc3RhbXAgfSBvZiB0aGlzLmVudHJ5U3RvcmVzKSB7XG4gICAgICBvbGRlc3QgPSBNYXRoLm1pbihvbGRlc3QsIG9sZGVzdFRpbWVzdGFtcChzY2FuKSk7XG4gICAgfVxuICAgIHJldHVybiBvbGRlc3Q7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSBgY29tcGxldGVTaW5jZWAgcGFzdCBgbWFya2VyYCdzIHJldmFsaWRhdGlvbnM6IHdoYXQgaXMgbm8gbG9uZ2VyXG4gICAqIGtub3duIGFib3V0IGEgdGFnIG9uY2UgaXRzIG1hcmtlciBpcyBkcm9wcGVkLiBBIGZ1dHVyZSBgZXhwaXJlZEF0YCB3YWl0c1xuICAgKiBpbiBgbGF0ZXJGbG9vcnNgIHVudGlsIGl0IGlzIHBhc3QuXG4gICAqL1xuICBwcml2YXRlIHJhaXNlRmxvb3IobWFya2VyOiBUYWdNYXJrZXIpOiB2b2lkIHtcbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgdGhpcy5mbG9vciA9IE1hdGgubWF4KHRoaXMuZmxvb3IsIGtub3duQnkobWFya2VyLCBhdCkpO1xuICAgIGNvbnN0IHsgZXhwaXJlZEF0IH0gPSBtYXJrZXI7XG4gICAgaWYgKGV4cGlyZWRBdCAhPT0gdW5kZWZpbmVkICYmIGV4cGlyZWRBdCA+IE1hdGgubWF4KGF0LCB0aGlzLmZsb29yKSkge1xuICAgICAgdGhpcy5sYXRlckZsb29yKGV4cGlyZWRBdCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEFkZCBgdGltZWAgdG8gYGxhdGVyRmxvb3JzYCwgaW4gb3JkZXIuIFBhc3QgdGhlIHRyYWNrZWQtdGFnIGJvdW5kIHRoZSB0d29cbiAgICogc3BhbnMgY2xvc2VzdCB0b2dldGhlciBhcmUgbWVyZ2VkOiBmcm9tIHRoZSBmaXJzdCdzIHN0YXJ0LFxuICAgKiBgY29tcGxldGVTaW5jZWAgaXMgdGhlIHNlY29uZCdzIGVuZCwgZWFybHkgLSB3aGljaCBvbmx5IGNvc3RzIHJlYWRzLCBhbmRcbiAgICogZm9yIGFzIHNob3J0IGEgdGltZSBhcyBhbnkgbWVyZ2UgYWxsb3dzLiBOZXZlciBsYXRlciB0aGFuIGl0cyB0aW1lLCB3aGljaFxuICAgKiB3b3VsZCBsZXQgYW4gZW50cnkgZXhwaXJlIHVuc2Vlbi5cbiAgICovXG4gIHByaXZhdGUgbGF0ZXJGbG9vcih0aW1lOiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBmbG9vcnMgPSB0aGlzLmxhdGVyRmxvb3JzO1xuICAgIGxldCBsb3cgPSAwO1xuICAgIGxldCBoaWdoID0gZmxvb3JzLmxlbmd0aDtcbiAgICB3aGlsZSAobG93IDwgaGlnaCkge1xuICAgICAgY29uc3QgbWlkID0gTWF0aC5mbG9vcigobG93ICsgaGlnaCkgLyAyKTtcbiAgICAgIGlmIChmbG9vcnNbbWlkXVswXSA8IHRpbWUpIHtcbiAgICAgICAgbG93ID0gbWlkICsgMTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGhpZ2ggPSBtaWQ7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEluc2lkZSBhIG1lcmdlZCBzcGFuIGFscmVhZHk6IGJ5IGl0cyBzdGFydCwgYGNvbXBsZXRlU2luY2VgIGlzIHBhc3QgaXQuXG4gICAgLy8gT3IgYWxyZWFkeSB0aGVyZTogYSBsb2cgcm93IGZvciBhbiB1bnRyYWNrZWQgdGFnIGlzIGFwcGxpZWQgYWdhaW4gYnlcbiAgICAvLyBldmVyeSBxdWVyeSBpdHMgbG9va2JhY2sgcmV0dXJucyBpdCB0by5cbiAgICBpZiAoKGxvdyA+IDAgJiYgZmxvb3JzW2xvdyAtIDFdWzFdID49IHRpbWUpIHx8IGZsb29yc1tsb3ddPy5bMF0gPT09IHRpbWUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZmxvb3JzLnNwbGljZShsb3csIDAsIFt0aW1lLCB0aW1lXSk7XG4gICAgLy8gQSBzY2FuLCBidXQgb25seSBvbmNlIHBhc3QgdGhlIGJvdW5kLiBNZXJnaW5nIHRoZSBuZXcgdGltZSBpbnRvIGFcbiAgICAvLyBuZWlnaGJvdXIgaW5zdGVhZCBjb3VsZCBqb2luIGFuIGhvdXItb3V0IHNwYW4gd2l0aCBhIHllYXItb3V0IG9uZSwgYW5kXG4gICAgLy8gaG9sZCBgY29tcGxldGVTaW5jZWAgYSB5ZWFyIGVhcmx5LlxuICAgIGlmIChmbG9vcnMubGVuZ3RoID4gdGhpcy5tYXhUcmFja2VkVGFncykge1xuICAgICAgbGV0IG1lcmdlID0gMDtcbiAgICAgIGZvciAobGV0IGkgPSAxOyBpIDwgZmxvb3JzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgZmxvb3JzW2kgKyAxXVsxXSAtIGZsb29yc1tpXVswXSA8XG4gICAgICAgICAgZmxvb3JzW21lcmdlICsgMV1bMV0gLSBmbG9vcnNbbWVyZ2VdWzBdXG4gICAgICAgICkge1xuICAgICAgICAgIG1lcmdlID0gaTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgZmxvb3JzLnNwbGljZShtZXJnZSwgMiwgW2Zsb29yc1ttZXJnZV1bMF0sIGZsb29yc1ttZXJnZSArIDFdWzFdXSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJlY29yZCB0aGF0IGB0YWdgJ3MgbWFya2VyIHdhcyBrbm93biBmcm9tIHRoZSB0YWJsZSBhdCBgYXRgLiAqL1xuICBwcml2YXRlIGtub3duKHRhZzogc3RyaW5nLCBhdDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5kdWVBdC5kZWxldGUodGFnKTtcbiAgICB0aGlzLmR1ZUF0LnNldChcbiAgICAgIHRhZyxcbiAgICAgIGF0ICsgdGhpcy5yZXN5bmNJbnRlcnZhbE1zICogKDEgLSBUQUdfUkVTWU5DX0pJVFRFUiAqIHRoaXMucmFuZG9tKCkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlbWVtYmVyKHRhZzogc3RyaW5nLCBtYXJrZXI6IFRhZ01hcmtlcik6IHZvaWQge1xuICAgIHRoaXMudGFncy5kZWxldGUodGFnKTtcbiAgICB0aGlzLnRhZ3Muc2V0KHRhZywgbWFya2VyKTtcbiAgICBmb3IgKGNvbnN0IG9sZGVzdCBvZiB0aGlzLnRhZ3Mua2V5cygpKSB7XG4gICAgICBpZiAodGhpcy50YWdzLnNpemUgPD0gdGhpcy5tYXhUcmFja2VkVGFncykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHRoaXMucmFpc2VGbG9vcih0aGlzLnRhZ3MuZ2V0KG9sZGVzdCkhKTtcbiAgICAgIHRoaXMudGFncy5kZWxldGUob2xkZXN0KTtcbiAgICAgIHRoaXMuZHVlQXQuZGVsZXRlKG9sZGVzdCk7XG4gICAgICB0aGlzLnVucmVhZC5kZWxldGUob2xkZXN0KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRvdWNoKHRhZzogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbWFya2VyID0gdGhpcy50YWdzLmdldCh0YWcpO1xuICAgIGlmIChtYXJrZXIpIHtcbiAgICAgIHRoaXMucmVtZW1iZXIodGFnLCBtYXJrZXIpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoZSBsYXRlc3QgcmV2YWxpZGF0aW9uIGBtYXJrZXJgIGhhcyBtYWRlIGtub3duIGJ5IGBhdGAsIGAtSW5maW5pdHlgIHdpdGhcbiAqIG5vbmU6IGEgZnV0dXJlIGBleHBpcmVkQXRgIGlzIHN0aWxsIHRvIGNvbWUuXG4gKi9cbmZ1bmN0aW9uIGtub3duQnkobWFya2VyOiBUYWdNYXJrZXIsIGF0OiBudW1iZXIpOiBudW1iZXIge1xuICBjb25zdCB7IHJldmFsaWRhdGVkQXQsIHN0YWxlQXQsIGV4cGlyZWRBdCB9ID0gbWFya2VyO1xuICByZXR1cm4gTWF0aC5tYXgoXG4gICAgcmV2YWxpZGF0ZWRBdCA/PyAtSW5maW5pdHksXG4gICAgc3RhbGVBdCA/PyAtSW5maW5pdHksXG4gICAgZXhwaXJlZEF0ICE9PSB1bmRlZmluZWQgJiYgZXhwaXJlZEF0IDw9IGF0ID8gZXhwaXJlZEF0IDogLUluZmluaXR5LFxuICApO1xufVxuXG4vKipcbiAqIFRoZSBsb25nZXN0IGEgbG9nIHJvdydzIHB1dCBtYXkgdGFrZSBhbmQgc3RpbGwgYmUgc2VlbiBieSBldmVyeSByZWFkZXI6IGhhbGZcbiAqIHRoZSBsb29rYmFjaywgbGVhdmluZyB0aGUgcmVzdCBmb3Igd3JpdGVycycgY2xvY2tzIGFuZCBldmVudHVhbGx5IGNvbnNpc3RlbnRcbiAqIHF1ZXJpZXMuXG4gKi9cbmNvbnN0IE1BWF9MT0dfUFVUX01TID0gUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUyAvIDI7XG5cbi8qKlxuICogSG93IG9mdGVuIGEgcmVmcmVzaCBzY2FucyB0aGUgZW50cnkgc3RvcmVzIGZvciB0aGVpciBvbGRlc3QgZW50cnksIGRyb3BwaW5nXG4gKiB0aGUgZXhwaXJlZCBvbmVzIG5vIHJlcXVlc3QgcmVhZHMgYWdhaW4uXG4gKi9cbmNvbnN0IEVOVFJZX1NDQU5fSU5URVJWQUxfTVMgPSA2MF8wMDA7XG5cbi8qKiBIb3cgb2Z0ZW4gYSByZWZyZXNoIGluIGZsaWdodCBjaGVja3MgdGhlIHByb2Nlc3MgaXMgcnVubmluZy4gKi9cbmNvbnN0IFJFRlJFU0hfVElDS19NUyA9IDI1MDtcblxuLyoqXG4gKiBIb3cgbGF0ZSBhIHRpY2sgbWF5IGNvbWUgYmVmb3JlIHRoZSBwcm9jZXNzIGNvdW50cyBhcyBwYXVzZWQgKGZyb3plbilcbiAqIHNpbmNlIHRoZSByZWZyZXNoIGluIGZsaWdodCBzdGFydGVkLiBBIGJ1c3kgZXZlbnQgbG9vcCBjYW4gZGVsYXkgb25lIHRvbzpcbiAqIHRoZSByZWZyZXNoIHRoZW4gY291bnRzIGFzIG5vIGZyZXNoZXIgdGhhbiBpdHMgc3RhcnQsIGFzIGJlZm9yZSB0aGUgcGF1c2VcbiAqIGNoZWNrLCBzbyBhIHJlcXVlc3Qgd2FpdHMgZm9yIHRoZSBuZXh0IG9uZSBvbmNlIHRoYXQgaXMgcGFzdCB0aGUgZ3JhY2UuXG4gKi9cbmNvbnN0IFJFRlJFU0hfUEFVU0VfTVMgPSAxMDAwO1xuXG4vKipcbiAqIEEgbWFya2VyIGFzIHJlYWQgZnJvbSB0aGUgdGFibGUgb3IgdGhlIGxvZywga2VlcGluZyB3aGF0ZXZlciB0aGlzIGluc3RhbmNlXG4gKiBhbHJlYWR5IGtub3dzIHRoYXQgdGhlIHJlYWQgZG9lcyBub3Qgc2hvdyB5ZXQ6IHJlYWRzIGFyZSBldmVudHVhbGx5XG4gKiBjb25zaXN0ZW50LCBhbmQgYSByZWFkIHN0cmFpZ2h0IGFmdGVyIHRoaXMgaW5zdGFuY2UncyBvd24gcmV2YWxpZGF0aW9uIGNvdWxkXG4gKiBvdGhlcndpc2UgdGFrZSBpdCBiYWNrLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWVyZ2VNYXJrZXJzKFxuICBsb2NhbDogVGFnTWFya2VyIHwgdW5kZWZpbmVkLFxuICByZW1vdGU6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCxcbik6IFRhZ01hcmtlciB7XG4gIGlmICghbG9jYWwpIHtcbiAgICByZXR1cm4gcmVtb3RlID8/IHt9O1xuICB9XG4gIGlmICghcmVtb3RlKSB7XG4gICAgcmV0dXJuIGxvY2FsO1xuICB9XG4gIC8vIGBleHBpcmVkQXRgIGlzIHdyaXR0ZW4gd2l0aCBgc3RhbGVBdGAsIHNvIGl0IGJlbG9uZ3MgdG8gd2hpY2hldmVyIGlzXG4gIC8vIG5ld2VyIC0gdW5sZXNzIHRoYXQgcmV2YWxpZGF0aW9uJ3MgcHJvZmlsZSBoYWQgbm8gYGV4cGlyZWAgYW5kIGxlZnQgaXQuXG4gIGNvbnN0IFtvbGRlciwgbmV3ZXJdID1cbiAgICAobG9jYWwuc3RhbGVBdCA/PyAtMSkgPiAocmVtb3RlLnN0YWxlQXQgPz8gLTEpXG4gICAgICA/IFtyZW1vdGUsIGxvY2FsXVxuICAgICAgOiBbbG9jYWwsIHJlbW90ZV07XG4gIHJldHVybiB7XG4gICAgLi4uYXBwbHlNYXJrZXIob2xkZXIsIG5ld2VyKSxcbiAgICByZXZhbGlkYXRlZEF0OiBtYXhEZWZpbmVkKGxvY2FsLnJldmFsaWRhdGVkQXQsIHJlbW90ZS5yZXZhbGlkYXRlZEF0KSxcbiAgfTtcbn1cblxuZnVuY3Rpb24gbWF4RGVmaW5lZChhOiBudW1iZXIgfCB1bmRlZmluZWQsIGI6IG51bWJlciB8IHVuZGVmaW5lZCkge1xuICBpZiAoYSA9PT0gdW5kZWZpbmVkKSByZXR1cm4gYjtcbiAgaWYgKGIgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGE7XG4gIHJldHVybiBNYXRoLm1heChhLCBiKTtcbn1cblxuLyoqXG4gKiBUaGUgY2FjaGUgYnVja2V0LCBhcyB0aGUgaGFuZGxlcnMgdXNlIGl0OiB3aG9sZSBvYmplY3RzIHJlYWQgYW5kIHdyaXR0ZW4gYXNcbiAqIFVURi04IHRleHQgdW5kZXIgdGhlIGtleXMgYWJvdmUuXG4gKi9cbmV4cG9ydCBjbGFzcyBDYWNoZUJ1Y2tldCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBTM0NsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGJ1Y2tldE5hbWU6IHN0cmluZyxcbiAgKSB7fVxuXG4gIC8qKlxuICAgKiBUaGUgYm9keSBvZiB0aGUgb2JqZWN0IGF0IGBrZXlgLCBvciBgdW5kZWZpbmVkYCB3aGVuIHRoZXJlIGlzIG5vbmUgKGBOb1N1Y2hLZXlgLCBvciBhblxuICAgKiBlbXB0eSByZXNwb25zZSBib2R5KS4gQW55IG90aGVyIGVycm9yIGlzIHRocm93bjogdGhlIGhhbmRsZXJzIGRpc2FncmVlIG9uXG4gICAqIHdoZXRoZXIgb25lIGlzIHdvcnRoIGxvZ2dpbmcuXG4gICAqL1xuICBhc3luYyBnZXQoa2V5OiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICAgIG5ldyBHZXRPYmplY3RDb21tYW5kKHsgQnVja2V0OiB0aGlzLmJ1Y2tldE5hbWUsIEtleToga2V5IH0pLFxuICAgICAgKTtcbiAgICAgIGlmICghcmVzcG9uc2UuQm9keSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGF3YWl0IHJlc3BvbnNlLkJvZHkudHJhbnNmb3JtVG9TdHJpbmcoXCJ1dGYtOFwiKTtcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgaWYgKGVycm9yIGluc3RhbmNlb2YgTm9TdWNoS2V5KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICB0aHJvdyBlcnJvcjtcbiAgICB9XG4gIH1cblxuICAvKiogV3JpdGUgYGJvZHlgIGFzIGEgSlNPTiBvYmplY3QgYXQgYGtleWAuICovXG4gIGFzeW5jIHB1dEpzb24oa2V5OiBzdHJpbmcsIGJvZHk6IHN0cmluZyk6IFByb21pc2U8dm9pZD4ge1xuICAgIGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICBuZXcgUHV0T2JqZWN0Q29tbWFuZCh7XG4gICAgICAgIEJ1Y2tldDogdGhpcy5idWNrZXROYW1lLFxuICAgICAgICBLZXk6IGtleSxcbiAgICAgICAgQm9keTogYm9keSxcbiAgICAgICAgQ29udGVudFR5cGU6IFwiYXBwbGljYXRpb24vanNvbjsgY2hhcnNldD11dGYtOFwiLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxufVxuIl19
|