cdk-nextjs 0.7.6 → 0.7.8
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 +3 -3
- 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 +154 -73
- package/lib/adapter/adapter.mjs +12 -3
- package/lib/adapter/aws-cache-store.d.ts +221 -3
- package/lib/adapter/aws-cache-store.js +481 -35
- package/lib/adapter/aws-cache-store.test.js +706 -3
- package/lib/adapter/cache-handler.d.ts +5 -3
- package/lib/adapter/cache-handler.js +16 -10
- package/lib/adapter/cache-handler.mjs +517 -49
- package/lib/adapter/cache-handler.test.js +44 -1
- package/lib/adapter/cache-utils.d.ts +22 -0
- package/lib/adapter/cache-utils.js +44 -1
- package/lib/adapter/function-groups.js +17 -4
- package/lib/adapter/function-groups.test.js +33 -1
- package/lib/adapter/memory-cache-handler.d.ts +5 -1
- package/lib/adapter/memory-cache-handler.js +6 -2
- package/lib/adapter/s3-cache-handler.d.ts +12 -1
- package/lib/adapter/s3-cache-handler.js +30 -8
- package/lib/adapter/s3-cache-handler.test.js +84 -2
- package/lib/adapter/use-cache-common.d.ts +66 -1
- package/lib/adapter/use-cache-common.js +142 -19
- package/lib/adapter/use-cache-common.test.js +174 -1
- package/lib/adapter/use-cache-default-handler.js +36 -6
- package/lib/adapter/use-cache-default-handler.mjs +553 -47
- package/lib/adapter/use-cache-handlers.test.js +247 -7
- package/lib/adapter/use-cache-remote-handler.js +9 -7
- package/lib/adapter/use-cache-remote-handler.mjs +542 -45
- 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.js +1 -1
- 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 +20 -4
- package/lib/runtime/core.test.js +17 -1
- package/lib/runtime/image-utils.d.ts +8 -9
- package/lib/runtime/image-utils.js +16 -1
- package/lib/runtime/image-utils.test.js +13 -1
- package/lib/runtime/image.js +9 -3
- package/lib/runtime/lambda.mjs +66 -18
- package/lib/runtime/server.mjs +66 -18
- package/lib/runtime/tag-manifest.d.ts +40 -0
- package/lib/runtime/tag-manifest.js +59 -0
- package/lib/runtime/tag-manifest.test.d.ts +1 -0
- package/lib/runtime/tag-manifest.test.js +47 -0
- package/package.json +3 -3
- package/scripts/e2e-deploy.sh +7 -2
- package/scripts/e2e-harness/README.md +72 -35
- package/scripts/e2e-harness/screen.mjs +148 -7
- package/scripts/playwright-install-deps.sh +40 -0
|
@@ -1,6 +1,6 @@
|
|
|
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.MAX_TAG_BYTES = exports.MAX_SORT_KEY_BYTES = 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
6
|
exports.s3ObjectKey = s3ObjectKey;
|
|
@@ -24,10 +24,12 @@ exports.mergeMarkers = mergeMarkers;
|
|
|
24
24
|
kinds of handler, and they must read each other's markers the same way.
|
|
25
25
|
*/
|
|
26
26
|
/* eslint-disable import/no-extraneous-dependencies */
|
|
27
|
+
const node_async_hooks_1 = require("node:async_hooks");
|
|
27
28
|
const node_path_1 = require("node:path");
|
|
28
29
|
const client_dynamodb_1 = require("@aws-sdk/client-dynamodb");
|
|
29
30
|
const client_s3_1 = require("@aws-sdk/client-s3");
|
|
30
31
|
const cache_utils_1 = require("./cache-utils");
|
|
32
|
+
const tag_manifest_1 = require("../runtime/tag-manifest");
|
|
31
33
|
/** The configuration from the environment. */
|
|
32
34
|
function resolveAwsCacheConfig() {
|
|
33
35
|
return {
|
|
@@ -164,6 +166,13 @@ exports.BATCH_GET_MAX_KEYS = 100;
|
|
|
164
166
|
* revalidation log, the reads scale with instances instead of requests or tags.
|
|
165
167
|
*/
|
|
166
168
|
exports.DEFAULT_TAG_REFRESH_MS = 1000;
|
|
169
|
+
/**
|
|
170
|
+
* How far past `refreshIntervalMs` the last refresh may have settled before a
|
|
171
|
+
* `'use cache'` request waits for the next one (see
|
|
172
|
+
* {@link TrackedTagMarkers.behind}). An instance serving steady traffic stays
|
|
173
|
+
* inside it; one that sat idle, or frozen between Lambda invocations, does not.
|
|
174
|
+
*/
|
|
175
|
+
exports.TAG_REFRESH_GRACE_MS = 1000;
|
|
167
176
|
/** DynamoDB's limit on a sort key, in UTF-8 bytes. */
|
|
168
177
|
exports.MAX_SORT_KEY_BYTES = 1024;
|
|
169
178
|
/**
|
|
@@ -464,15 +473,19 @@ exports.DEFAULT_MAX_TRACKED_TAGS = 10_000;
|
|
|
464
473
|
* The cost is bounded per instance, not per request:
|
|
465
474
|
* - {@link ensure} reads a tag's marker the first time it is needed and not
|
|
466
475
|
* again until it is evicted, so a tag costs one read per instance, not one
|
|
467
|
-
* per request.
|
|
476
|
+
* per request. An entry created since {@link completeSince} needs no read
|
|
477
|
+
* at all.
|
|
468
478
|
* - {@link refresh}, at most once per `refreshIntervalMs`, sends one `Query`
|
|
469
479
|
* for the log rows written since the last one, and applies those of tags
|
|
470
480
|
* this instance tracks. Concurrent callers share it. Alongside, it re-reads
|
|
471
481
|
* the markers of up to {@link BATCH_GET_MAX_KEYS} tags not read for
|
|
472
482
|
* {@link DEFAULT_TAG_RESYNC_MS}, in one `BatchGetItem`.
|
|
473
483
|
* A revalidation on another instance is therefore seen within
|
|
474
|
-
* `refreshIntervalMs` (plus the query itself)
|
|
475
|
-
*
|
|
484
|
+
* `refreshIntervalMs` (plus the query itself) - by `'use cache'`, from the
|
|
485
|
+
* first request after the query returns, since its `refreshTags` does not wait
|
|
486
|
+
* for it (see `tagMethods`) unless the instance is {@link behind}, which the
|
|
487
|
+
* runtime settles before a page render starts ({@link catchUp}). The instance
|
|
488
|
+
* that ran it applies it itself, at once, with {@link set}.
|
|
476
489
|
*/
|
|
477
490
|
class TrackedTagMarkers {
|
|
478
491
|
markers;
|
|
@@ -498,10 +511,64 @@ class TrackedTagMarkers {
|
|
|
498
511
|
* result rather than dropped.
|
|
499
512
|
*/
|
|
500
513
|
pendingRows = new Map();
|
|
514
|
+
/**
|
|
515
|
+
* Log rows for tags not tracked and not being read, merged by tag, oldest
|
|
516
|
+
* first: what the log has said about them since {@link completeSince}. Taken
|
|
517
|
+
* into a tag's marker when it is read or written.
|
|
518
|
+
*/
|
|
519
|
+
logOnly = new Map();
|
|
520
|
+
/** See {@link completeSince}. */
|
|
521
|
+
floor;
|
|
522
|
+
/**
|
|
523
|
+
* The future `expiredAt`s of markers dropped since, as `[from, to]`, in
|
|
524
|
+
* order: once `from` is past, {@link completeSince} moves to `to`, and not
|
|
525
|
+
* before, since only then does it expire anything. `from` and `to` are the
|
|
526
|
+
* same until spans are merged for space ({@link laterFloor}).
|
|
527
|
+
*/
|
|
528
|
+
laterFloors = [];
|
|
529
|
+
/** The in-memory entry stores judged by {@link completeSince}. */
|
|
530
|
+
entryStores = [];
|
|
531
|
+
/** How many times {@link forget} ran: a read started before one is made again. */
|
|
532
|
+
forgotten = 0;
|
|
501
533
|
/** Tracked tags whose read failed, for the next refresh to read again. */
|
|
502
534
|
unread = new Set();
|
|
535
|
+
/**
|
|
536
|
+
* Set inside a page render {@link catchUp} let go, for that render alone.
|
|
537
|
+
* See {@link behindInRender}.
|
|
538
|
+
*/
|
|
539
|
+
caughtUpRender = new node_async_hooks_1.AsyncLocalStorage();
|
|
540
|
+
/** When `sync` last scanned the entry stores ({@link oldestEntry}). */
|
|
541
|
+
lastEntryScan = -Infinity;
|
|
542
|
+
/**
|
|
543
|
+
* No `logOnly` row is known by it or earlier, so a {@link pruneLogged}
|
|
544
|
+
* against it or earlier drops nothing: a marker is only ever known by later,
|
|
545
|
+
* as its `expiredAt` passes.
|
|
546
|
+
*/
|
|
547
|
+
prunedAgainst = -Infinity;
|
|
548
|
+
/** When the last refresh started, or was skipped. */
|
|
503
549
|
lastRefresh = -Infinity;
|
|
550
|
+
/**
|
|
551
|
+
* The refresh in flight. One left open across a freeze comes back after the
|
|
552
|
+
* thaw with what it read before, so {@link refresh} waits for it and then
|
|
553
|
+
* for a fresh one, rather than the runtime waiting for it before the freeze:
|
|
554
|
+
* that would bill every Lambda invocation for the query's tail.
|
|
555
|
+
*/
|
|
504
556
|
refreshing;
|
|
557
|
+
/**
|
|
558
|
+
* When {@link refreshing} last showed the process running: a timer ticks
|
|
559
|
+
* while it is in flight, and a tick that comes late, or none at all, means
|
|
560
|
+
* the process was paused - frozen - since it started.
|
|
561
|
+
*/
|
|
562
|
+
lastTick = -Infinity;
|
|
563
|
+
/** Whether a tick came late since {@link refreshing} started. */
|
|
564
|
+
pausedWhileRefreshing = false;
|
|
565
|
+
ticker;
|
|
566
|
+
canFreeze;
|
|
567
|
+
/**
|
|
568
|
+
* When the last refresh settled, either way, unless it spanned a pause: what
|
|
569
|
+
* it knows is from then. See {@link behind}.
|
|
570
|
+
*/
|
|
571
|
+
settledAt;
|
|
505
572
|
/**
|
|
506
573
|
* Where the next log query starts (`clock()`): the last successful one's
|
|
507
574
|
* start, less {@link REVALIDATION_LOG_LOOKBACK_MS}.
|
|
@@ -525,22 +592,70 @@ class TrackedTagMarkers {
|
|
|
525
592
|
this.clock = options.clock ?? (() => Date.now());
|
|
526
593
|
this.random = options.random ?? Math.random;
|
|
527
594
|
this.debug = options.debug ?? (() => { });
|
|
595
|
+
this.canFreeze = options.canFreeze ?? false;
|
|
528
596
|
// Nothing is tracked yet, so nothing before this can be missed: every tag
|
|
529
597
|
// is read from its marker the first time it is needed.
|
|
530
598
|
const at = this.clock();
|
|
531
599
|
this.cursor = at - exports.REVALIDATION_LOG_LOOKBACK_MS;
|
|
532
600
|
this.lastLogRead = at;
|
|
601
|
+
this.settledAt = at;
|
|
602
|
+
this.floor = markerClock();
|
|
533
603
|
}
|
|
534
604
|
/** `tag`'s marker as this instance knows it, if it tracks `tag`. */
|
|
535
605
|
get(tag) {
|
|
536
606
|
return this.tags.get(tag);
|
|
537
607
|
}
|
|
608
|
+
/**
|
|
609
|
+
* Since when (`markerClock()`) this instance knows of every revalidation of
|
|
610
|
+
* every tag, tracked or not: tracked ones from their markers and the log,
|
|
611
|
+
* the others from the log alone (`logOnly`). So an entry created at or after
|
|
612
|
+
* it can be judged by {@link state} and {@link expiration} without
|
|
613
|
+
* {@link ensure} reading anything - which matters inside a `'use cache'`
|
|
614
|
+
* lookup, where Next.js waits for the answer and a read pushes the entry out
|
|
615
|
+
* of the static stage of a staged render.
|
|
616
|
+
*
|
|
617
|
+
* Starts at construction: the log is followed from before it. Moves to now
|
|
618
|
+
* when the tracked markers are forgotten, and past the revalidations of
|
|
619
|
+
* whatever else it lets go of - a marker evicted for space, a log row
|
|
620
|
+
* pruned - which are no longer known: to its `expiredAt` only once that is
|
|
621
|
+
* past, since a profile's `expire` can be a year out, and moving there at
|
|
622
|
+
* once would turn the read-free path off for the instance's life.
|
|
623
|
+
*
|
|
624
|
+
* A row is pruned only once it is no later than every entry held, so that
|
|
625
|
+
* costs those entries nothing. An entry stored afterwards with an older
|
|
626
|
+
* `timestamp` - Next.js stamps the start of its generation, which can
|
|
627
|
+
* outlast a lookback - is older than this too, and is read first.
|
|
628
|
+
*
|
|
629
|
+
* It does not cover a revalidation older than the log's first lookback
|
|
630
|
+
* whose `expiredAt` is still to come, which would expire an entry created
|
|
631
|
+
* after it. So the `'use cache'` handler reads an entry's tags in the
|
|
632
|
+
* background as it stores it.
|
|
633
|
+
*/
|
|
634
|
+
get completeSince() {
|
|
635
|
+
const at = markerClock();
|
|
636
|
+
while (this.laterFloors.length > 0 && this.laterFloors[0][0] <= at) {
|
|
637
|
+
this.floor = Math.max(this.floor, this.laterFloors.shift()[1]);
|
|
638
|
+
}
|
|
639
|
+
return this.floor;
|
|
640
|
+
}
|
|
641
|
+
/**
|
|
642
|
+
* Register an in-memory store whose entries are judged by
|
|
643
|
+
* {@link completeSince}, by the `timestamp` of the oldest entry it holds:
|
|
644
|
+
* `logOnly` keeps the rows that could still apply to one of them, and no
|
|
645
|
+
* others. With none registered it keeps nothing. Asked with `scan` false,
|
|
646
|
+
* `oldestTimestamp` may answer early, but never late, without a scan.
|
|
647
|
+
*/
|
|
648
|
+
judgeEntriesOf(oldestTimestamp, holdsAny = () => oldestTimestamp(false) < Infinity) {
|
|
649
|
+
this.entryStores.push({ oldestTimestamp, holdsAny });
|
|
650
|
+
}
|
|
538
651
|
/**
|
|
539
652
|
* Track `tag` with `marker`: what this instance just wrote, which it knows
|
|
540
653
|
* without reading it back.
|
|
541
654
|
*/
|
|
542
655
|
set(tag, marker) {
|
|
543
|
-
this.
|
|
656
|
+
const logged = this.logOnly.get(tag);
|
|
657
|
+
this.logOnly.delete(tag);
|
|
658
|
+
this.remember(tag, mergeMarkers(marker, logged));
|
|
544
659
|
this.known(tag, this.clock());
|
|
545
660
|
}
|
|
546
661
|
/**
|
|
@@ -592,31 +707,127 @@ class TrackedTagMarkers {
|
|
|
592
707
|
const waits = [];
|
|
593
708
|
const unread = [];
|
|
594
709
|
for (const tag of new Set(tags)) {
|
|
710
|
+
// Tracked first: a tracked tag in `reading` is only being re-read in
|
|
711
|
+
// the background (`sync`), which nothing needs to wait for.
|
|
595
712
|
const inFlight = this.reading.get(tag);
|
|
596
|
-
if (
|
|
597
|
-
waits.push(inFlight);
|
|
598
|
-
}
|
|
599
|
-
else if (this.tags.has(tag)) {
|
|
713
|
+
if (this.tags.has(tag)) {
|
|
600
714
|
this.touch(tag);
|
|
601
715
|
}
|
|
716
|
+
else if (inFlight) {
|
|
717
|
+
waits.push(inFlight);
|
|
718
|
+
}
|
|
602
719
|
else {
|
|
603
720
|
unread.push(tag);
|
|
604
721
|
}
|
|
605
722
|
}
|
|
606
723
|
if (unread.length > 0) {
|
|
607
|
-
|
|
608
|
-
const read = this.readInto(unread).then(() => {
|
|
609
|
-
for (const tag of unread) {
|
|
610
|
-
this.reading.delete(tag);
|
|
611
|
-
}
|
|
612
|
-
});
|
|
613
|
-
for (const tag of unread) {
|
|
614
|
-
this.reading.set(tag, read);
|
|
615
|
-
}
|
|
616
|
-
waits.push(read);
|
|
724
|
+
waits.push(this.startRead(unread));
|
|
617
725
|
}
|
|
618
726
|
await Promise.all(waits);
|
|
619
727
|
}
|
|
728
|
+
/**
|
|
729
|
+
* {@link readInto} `tags`, as the read of each that whoever needs one of
|
|
730
|
+
* them next waits on ({@link reading}). Never rejects: a failed read leaves
|
|
731
|
+
* the tags tracked.
|
|
732
|
+
*/
|
|
733
|
+
startRead(tags) {
|
|
734
|
+
const read = this.readInto(tags).then(() => {
|
|
735
|
+
for (const tag of tags) {
|
|
736
|
+
this.reading.delete(tag);
|
|
737
|
+
}
|
|
738
|
+
});
|
|
739
|
+
for (const tag of tags) {
|
|
740
|
+
this.reading.set(tag, read);
|
|
741
|
+
}
|
|
742
|
+
return read;
|
|
743
|
+
}
|
|
744
|
+
/**
|
|
745
|
+
* Whether the last refresh settled more than `refreshIntervalMs` plus
|
|
746
|
+
* {@link TAG_REFRESH_GRACE_MS} ago - one that spanned a freeze counts from
|
|
747
|
+
* when it started: after the instance sat idle or frozen - or always, with
|
|
748
|
+
* a `refreshIntervalMs` of `0`. Answering from what it knows then could
|
|
749
|
+
* serve an entry revalidated elsewhere since, however long ago that was, so
|
|
750
|
+
* `refreshTags` waits for the refresh, and the runtime waits for it before
|
|
751
|
+
* a page render starts ({@link catchUp}).
|
|
752
|
+
*
|
|
753
|
+
* From when it settled, not when it started, so a slow query the runtime
|
|
754
|
+
* waited for before the render does not leave the instance behind inside
|
|
755
|
+
* it. A failed one counts too, so one request does not wait for two: the
|
|
756
|
+
* same "assume the entry is valid" a failed read answers with, until the
|
|
757
|
+
* next refresh, at most the interval and the grace later.
|
|
758
|
+
*/
|
|
759
|
+
get behind() {
|
|
760
|
+
return (this.log !== undefined &&
|
|
761
|
+
// `0` asks before every check, so every check waits for the answer.
|
|
762
|
+
(this.refreshIntervalMs === 0 || this.overdue(this.settledAt)));
|
|
763
|
+
}
|
|
764
|
+
/**
|
|
765
|
+
* {@link behind}, as `refreshTags` asks it: never inside a page's render
|
|
766
|
+
* {@link catchUp} caught up, since the runtime settled it for that request
|
|
767
|
+
* before the render started, and a wait inside a `'use cache'` lookup is
|
|
768
|
+
* what it settled it to avoid - a render crossing the line partway through
|
|
769
|
+
* would otherwise wait after all. So a revalidation elsewhere can go unseen
|
|
770
|
+
* for a render's duration on top of the usual window.
|
|
771
|
+
*
|
|
772
|
+
* A route handler, which no catch-up precedes, waits at the plain line.
|
|
773
|
+
*/
|
|
774
|
+
get behindInRender() {
|
|
775
|
+
return this.refreshIntervalMs !== 0 && this.caughtUpRender.getStore()
|
|
776
|
+
? false
|
|
777
|
+
: this.behind;
|
|
778
|
+
}
|
|
779
|
+
/**
|
|
780
|
+
* Whether a registered store ({@link judgeEntriesOf}) holds any entry: one
|
|
781
|
+
* a refresh could expire. With none there is nothing to wait for even when
|
|
782
|
+
* the instance is {@link behind}, since whatever is stored from here on is
|
|
783
|
+
* newer than what the log would say - which covers the first `'use cache'`
|
|
784
|
+
* call of a process, which creates the handler inside the render.
|
|
785
|
+
*/
|
|
786
|
+
get holdsEntries() {
|
|
787
|
+
return this.entryStores.some((store) => store.holdsAny());
|
|
788
|
+
}
|
|
789
|
+
/**
|
|
790
|
+
* {@link refresh}, waited for when the instance is {@link behind}. The
|
|
791
|
+
* runtime calls it before handing a page request to Next.js, outside the
|
|
792
|
+
* staged render whose static stage a wait inside a `'use cache'` lookup
|
|
793
|
+
* would cut short. Only for the `'use cache'` handler's entries
|
|
794
|
+
* ({@link judgeEntriesOf}): the other caches wait for the refresh where they
|
|
795
|
+
* read anyway. Not with a `refreshIntervalMs` of `0` either, where
|
|
796
|
+
* `refreshTags` asks again regardless. Then `render`, marked as caught up
|
|
797
|
+
* for ({@link behindInRender}). Rejects only as `render` does.
|
|
798
|
+
*/
|
|
799
|
+
async catchUp(render) {
|
|
800
|
+
const log = (error) => console.error("Error refreshing cache tags:", error);
|
|
801
|
+
if (this.refreshIntervalMs > 0 && this.behind) {
|
|
802
|
+
if (!this.holdsEntries) {
|
|
803
|
+
// Not caught up, so no grace: an entry stored meanwhile, by another
|
|
804
|
+
// request, makes the render's lookups wait at the plain line.
|
|
805
|
+
return render();
|
|
806
|
+
}
|
|
807
|
+
await this.refresh().catch(log);
|
|
808
|
+
}
|
|
809
|
+
else if (this.refreshIntervalMs > 0) {
|
|
810
|
+
// Started, not waited for, as `refreshTags` would: a page that reads
|
|
811
|
+
// no cache keeps the instance current too, rather than falling behind
|
|
812
|
+
// and making a later request wait.
|
|
813
|
+
void this.refresh().catch(log);
|
|
814
|
+
}
|
|
815
|
+
return this.caughtUpRender.run(true, render);
|
|
816
|
+
}
|
|
817
|
+
/**
|
|
818
|
+
* Run `fn` outside the request's context (`outsideRequest`), keeping only
|
|
819
|
+
* whether the render was {@link catchUp caught up}: a cache handler method
|
|
820
|
+
* called from inside a staged render, whose clock reads and AWS SDK calls
|
|
821
|
+
* would otherwise end its static stage.
|
|
822
|
+
*/
|
|
823
|
+
outsideRender(fn) {
|
|
824
|
+
const caughtUp = this.caughtUpRender.getStore();
|
|
825
|
+
return (0, tag_manifest_1.outsideRequest)(() => caughtUp ? this.caughtUpRender.run(caughtUp, fn) : fn());
|
|
826
|
+
}
|
|
827
|
+
/** Whether `at` is more than the interval and the grace ago. */
|
|
828
|
+
overdue(at) {
|
|
829
|
+
return this.clock() - at > this.refreshIntervalMs + exports.TAG_REFRESH_GRACE_MS;
|
|
830
|
+
}
|
|
620
831
|
/**
|
|
621
832
|
* Catch up on revalidations other instances ran, at most once per
|
|
622
833
|
* `refreshIntervalMs`. See {@link TrackedTagMarkers} for the cost.
|
|
@@ -627,6 +838,12 @@ class TrackedTagMarkers {
|
|
|
627
838
|
return;
|
|
628
839
|
}
|
|
629
840
|
if (this.refreshing) {
|
|
841
|
+
// One started before a freeze read the log as it was then, and says
|
|
842
|
+
// nothing of what ran meanwhile: an instance behind waits for a fresh
|
|
843
|
+
// one, after it. One that is merely slow is as fresh as any.
|
|
844
|
+
if (this.behind && this.pausedSinceRefreshStarted()) {
|
|
845
|
+
return this.refreshing.then(() => this.refresh());
|
|
846
|
+
}
|
|
630
847
|
return this.refreshing;
|
|
631
848
|
}
|
|
632
849
|
const at = this.clock();
|
|
@@ -635,15 +852,55 @@ class TrackedTagMarkers {
|
|
|
635
852
|
}
|
|
636
853
|
this.lastRefresh = at;
|
|
637
854
|
// Whatever gets tracked before the next refresh is read from its marker,
|
|
638
|
-
// so there is nothing to catch up on yet
|
|
639
|
-
|
|
855
|
+
// so there is nothing to catch up on yet - unless an entry is judged by
|
|
856
|
+
// `completeSince`, which relies on the log for every tag. Even with none
|
|
857
|
+
// held: a row let go of then moves `completeSince` past it, for an entry
|
|
858
|
+
// whose generation started before that revalidation and that is stored
|
|
859
|
+
// after it.
|
|
860
|
+
if (this.tags.size === 0 && this.entryStores.length === 0) {
|
|
640
861
|
return;
|
|
641
862
|
}
|
|
863
|
+
this.startTicking();
|
|
642
864
|
this.refreshing = this.sync(at, log).finally(() => {
|
|
865
|
+
// One that spanned a pause knows the log as of its start at best. So
|
|
866
|
+
// does one that only looked paused, its event loop held up: it counts
|
|
867
|
+
// as no older than its start, as if it had not settled since.
|
|
868
|
+
this.settledAt = Math.max(this.settledAt, this.pausedSinceRefreshStarted() ? this.lastRefresh : this.clock());
|
|
869
|
+
this.stopTicking();
|
|
643
870
|
this.refreshing = undefined;
|
|
644
871
|
});
|
|
645
872
|
return this.refreshing;
|
|
646
873
|
}
|
|
874
|
+
startTicking() {
|
|
875
|
+
if (!this.canFreeze) {
|
|
876
|
+
return;
|
|
877
|
+
}
|
|
878
|
+
this.lastTick = this.clock();
|
|
879
|
+
this.pausedWhileRefreshing = false;
|
|
880
|
+
this.ticker = setInterval(() => {
|
|
881
|
+
const at = this.clock();
|
|
882
|
+
if (at - this.lastTick > REFRESH_PAUSE_MS) {
|
|
883
|
+
this.pausedWhileRefreshing = true;
|
|
884
|
+
}
|
|
885
|
+
this.lastTick = at;
|
|
886
|
+
}, REFRESH_TICK_MS);
|
|
887
|
+
// Never what keeps a process alive.
|
|
888
|
+
this.ticker.unref?.();
|
|
889
|
+
}
|
|
890
|
+
stopTicking() {
|
|
891
|
+
clearInterval(this.ticker);
|
|
892
|
+
this.ticker = undefined;
|
|
893
|
+
}
|
|
894
|
+
/**
|
|
895
|
+
* Whether the process was paused since {@link refreshing} started: a tick
|
|
896
|
+
* came late, or the next one is overdue (after a thaw, a request can run
|
|
897
|
+
* before the timer does).
|
|
898
|
+
*/
|
|
899
|
+
pausedSinceRefreshStarted() {
|
|
900
|
+
return (this.canFreeze &&
|
|
901
|
+
(this.pausedWhileRefreshing ||
|
|
902
|
+
this.clock() - this.lastTick > REFRESH_PAUSE_MS));
|
|
903
|
+
}
|
|
647
904
|
/**
|
|
648
905
|
* Record a revalidation of `tags`: here at once, and in the revalidation
|
|
649
906
|
* table for every other instance - the marker row plus a log row per tag.
|
|
@@ -681,7 +938,7 @@ class TrackedTagMarkers {
|
|
|
681
938
|
const at = markerClock();
|
|
682
939
|
let state = "fresh";
|
|
683
940
|
for (const tag of tags) {
|
|
684
|
-
const marker = this.
|
|
941
|
+
const marker = this.knownMarker(tag);
|
|
685
942
|
if (!marker) {
|
|
686
943
|
continue;
|
|
687
944
|
}
|
|
@@ -705,7 +962,7 @@ class TrackedTagMarkers {
|
|
|
705
962
|
const at = markerClock();
|
|
706
963
|
let latest = 0;
|
|
707
964
|
for (const tag of tags) {
|
|
708
|
-
const marker = this.
|
|
965
|
+
const marker = this.knownMarker(tag);
|
|
709
966
|
if (!marker) {
|
|
710
967
|
continue;
|
|
711
968
|
}
|
|
@@ -787,13 +1044,17 @@ class TrackedTagMarkers {
|
|
|
787
1044
|
this.forget(at, "the revalidation log may not cover the gap since it was last read");
|
|
788
1045
|
return;
|
|
789
1046
|
}
|
|
790
|
-
|
|
791
|
-
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
this.
|
|
796
|
-
|
|
1047
|
+
// The rolling re-read runs alongside, not waited for: catching up needs
|
|
1048
|
+
// only the log, and a throttled `BatchGetItem` should not hold the
|
|
1049
|
+
// request `catchUp` makes wait. A forget meanwhile reads it again.
|
|
1050
|
+
const due = this.due(at);
|
|
1051
|
+
if (due.length > 0) {
|
|
1052
|
+
void this.startRead(due);
|
|
1053
|
+
}
|
|
1054
|
+
const result = await log.query(this.cursor).catch((error) => {
|
|
1055
|
+
console.error("Error reading tag revalidation log:", error);
|
|
1056
|
+
return undefined;
|
|
1057
|
+
});
|
|
797
1058
|
if (!result) {
|
|
798
1059
|
return;
|
|
799
1060
|
}
|
|
@@ -801,6 +1062,15 @@ class TrackedTagMarkers {
|
|
|
801
1062
|
this.forget(at, "the revalidation log has more rows than one query reads");
|
|
802
1063
|
return;
|
|
803
1064
|
}
|
|
1065
|
+
// A scan of every entry held, which also drops the expired ones, once in
|
|
1066
|
+
// a while: so expired entries never read again don't pile up ahead of
|
|
1067
|
+
// live ones. In between, the stores answer early without one, which only
|
|
1068
|
+
// keeps rows in `logOnly` a little longer.
|
|
1069
|
+
const scan = at - this.lastEntryScan > ENTRY_SCAN_INTERVAL_MS;
|
|
1070
|
+
if (scan) {
|
|
1071
|
+
this.lastEntryScan = at;
|
|
1072
|
+
}
|
|
1073
|
+
const oldest = this.oldestEntry(scan);
|
|
804
1074
|
let applied = 0;
|
|
805
1075
|
for (const row of result.rows) {
|
|
806
1076
|
if (this.applied.has(row.sk)) {
|
|
@@ -826,11 +1096,19 @@ class TrackedTagMarkers {
|
|
|
826
1096
|
// rolling re-read. Left unmarked, the next refresh applies it to
|
|
827
1097
|
// whatever that read found; it costs no read, only the row being
|
|
828
1098
|
// looked at again while it is inside the lookback.
|
|
1099
|
+
//
|
|
1100
|
+
// Kept meanwhile in `logOnly`, which is all `completeSince` needs.
|
|
1101
|
+
this.rememberLogged(row.tag, mergeMarkers(this.logOnly.get(row.tag), row.marker), oldest);
|
|
829
1102
|
continue;
|
|
830
1103
|
}
|
|
831
1104
|
this.applied.set(row.sk, row.at);
|
|
832
1105
|
applied++;
|
|
833
1106
|
}
|
|
1107
|
+
if (oldest > this.prunedAgainst) {
|
|
1108
|
+
this.pruneLogged(oldest);
|
|
1109
|
+
}
|
|
1110
|
+
// The rows just kept are known by later than `oldest` too.
|
|
1111
|
+
this.prunedAgainst = oldest;
|
|
834
1112
|
this.lastLogRead = at;
|
|
835
1113
|
this.advance(at - exports.REVALIDATION_LOG_LOOKBACK_MS);
|
|
836
1114
|
this.debug(`read ${result.rows.length} revalidation log rows (${applied} applied)`);
|
|
@@ -845,7 +1123,9 @@ class TrackedTagMarkers {
|
|
|
845
1123
|
for (const tag of this.unread) {
|
|
846
1124
|
if (due.length >= exports.BATCH_GET_MAX_KEYS)
|
|
847
1125
|
return due;
|
|
848
|
-
|
|
1126
|
+
if (!this.reading.has(tag)) {
|
|
1127
|
+
due.push(tag);
|
|
1128
|
+
}
|
|
849
1129
|
}
|
|
850
1130
|
// Known in time order, and each due at most `jitter` earlier than the
|
|
851
1131
|
// tags after it: past a tag due more than that from now, none is due.
|
|
@@ -854,7 +1134,7 @@ class TrackedTagMarkers {
|
|
|
854
1134
|
if (due.length >= exports.BATCH_GET_MAX_KEYS || dueAt - jitter > at) {
|
|
855
1135
|
break;
|
|
856
1136
|
}
|
|
857
|
-
if (dueAt <= at && !this.unread.has(tag)) {
|
|
1137
|
+
if (dueAt <= at && !this.unread.has(tag) && !this.reading.has(tag)) {
|
|
858
1138
|
due.push(tag);
|
|
859
1139
|
}
|
|
860
1140
|
}
|
|
@@ -867,10 +1147,21 @@ class TrackedTagMarkers {
|
|
|
867
1147
|
*/
|
|
868
1148
|
forget(at, why) {
|
|
869
1149
|
this.debug(`forgetting ${this.tags.size} tracked tags: ${why}`);
|
|
1150
|
+
this.forgotten++;
|
|
1151
|
+
// What the markers expire later is still to apply once it is past.
|
|
1152
|
+
for (const marker of this.tags.values()) {
|
|
1153
|
+
this.raiseFloor(marker);
|
|
1154
|
+
}
|
|
1155
|
+
for (const marker of this.logOnly.values()) {
|
|
1156
|
+
this.raiseFloor(marker);
|
|
1157
|
+
}
|
|
870
1158
|
this.tags.clear();
|
|
871
1159
|
this.dueAt.clear();
|
|
872
1160
|
this.unread.clear();
|
|
873
1161
|
this.applied.clear();
|
|
1162
|
+
this.logOnly.clear();
|
|
1163
|
+
// Never back: a marker dropped earlier may have expired entries later.
|
|
1164
|
+
this.floor = Math.max(this.floor, markerClock());
|
|
874
1165
|
this.cursor = at - exports.REVALIDATION_LOG_LOOKBACK_MS;
|
|
875
1166
|
this.lastLogRead = at;
|
|
876
1167
|
}
|
|
@@ -896,13 +1187,23 @@ class TrackedTagMarkers {
|
|
|
896
1187
|
* always answered with, rather than a read on every request while DynamoDB
|
|
897
1188
|
* is unavailable.
|
|
898
1189
|
*/
|
|
899
|
-
async readInto(tags) {
|
|
1190
|
+
async readInto(tags, again = false) {
|
|
900
1191
|
if (tags.length === 0) {
|
|
901
1192
|
return true;
|
|
902
1193
|
}
|
|
903
1194
|
const at = this.clock();
|
|
1195
|
+
const forgotten = this.forgotten;
|
|
904
1196
|
try {
|
|
905
1197
|
const read = await this.markers.read(tags);
|
|
1198
|
+
if (this.forgotten !== forgotten && !again) {
|
|
1199
|
+
// Read before a forget - across a freeze, as like as not - so as
|
|
1200
|
+
// stale as what it forgot. Read again rather than leave the tags
|
|
1201
|
+
// untracked: whoever waits on this read (`reading`) judges entries
|
|
1202
|
+
// by it next, and an untracked tag counts for nothing. Once: a run
|
|
1203
|
+
// of forgets (a truncated log, query after query) would otherwise
|
|
1204
|
+
// keep them waiting, and the second read began after the first.
|
|
1205
|
+
return await this.readInto(tags, true);
|
|
1206
|
+
}
|
|
906
1207
|
for (const tag of tags) {
|
|
907
1208
|
this.unread.delete(tag);
|
|
908
1209
|
this.remember(tag, mergeMarkers(mergeMarkers(this.tags.get(tag), read.get(tag)), this.takePendingRows(tag)));
|
|
@@ -913,6 +1214,9 @@ class TrackedTagMarkers {
|
|
|
913
1214
|
}
|
|
914
1215
|
catch (error) {
|
|
915
1216
|
console.error("Error reading tag markers:", error);
|
|
1217
|
+
if (this.forgotten !== forgotten && !again) {
|
|
1218
|
+
return this.readInto(tags, true);
|
|
1219
|
+
}
|
|
916
1220
|
this.trackUnread(tags);
|
|
917
1221
|
for (const tag of tags) {
|
|
918
1222
|
this.unread.add(tag);
|
|
@@ -926,8 +1230,127 @@ class TrackedTagMarkers {
|
|
|
926
1230
|
}
|
|
927
1231
|
takePendingRows(tag) {
|
|
928
1232
|
const pending = this.pendingRows.get(tag);
|
|
1233
|
+
const logged = this.logOnly.get(tag);
|
|
929
1234
|
this.pendingRows.delete(tag);
|
|
930
|
-
|
|
1235
|
+
this.logOnly.delete(tag);
|
|
1236
|
+
return logged ? mergeMarkers(logged, pending) : pending;
|
|
1237
|
+
}
|
|
1238
|
+
/**
|
|
1239
|
+
* What this instance knows of `tag`: tracked, or from the log alone -
|
|
1240
|
+
* including rows that arrived while its first read is in flight.
|
|
1241
|
+
*/
|
|
1242
|
+
knownMarker(tag) {
|
|
1243
|
+
const tracked = this.tags.get(tag);
|
|
1244
|
+
if (tracked) {
|
|
1245
|
+
return tracked;
|
|
1246
|
+
}
|
|
1247
|
+
const logged = this.logOnly.get(tag);
|
|
1248
|
+
const pending = this.pendingRows.get(tag);
|
|
1249
|
+
return logged || pending ? mergeMarkers(logged, pending) : undefined;
|
|
1250
|
+
}
|
|
1251
|
+
/**
|
|
1252
|
+
* Keep `tag`'s log rows in `logOnly`, unless they cannot apply to an entry
|
|
1253
|
+
* held, `oldest` or newer (see {@link pruneLogged}), as bounded as the
|
|
1254
|
+
* tracked tags. Either way a row let go of takes what it knew with it, so
|
|
1255
|
+
* `completeSince` moves past it.
|
|
1256
|
+
*/
|
|
1257
|
+
rememberLogged(tag, marker, oldest) {
|
|
1258
|
+
this.logOnly.delete(tag);
|
|
1259
|
+
if (knownBy(marker, markerClock()) <= oldest) {
|
|
1260
|
+
this.raiseFloor(marker);
|
|
1261
|
+
return;
|
|
1262
|
+
}
|
|
1263
|
+
this.logOnly.set(tag, marker);
|
|
1264
|
+
for (const [first, dropped] of this.logOnly) {
|
|
1265
|
+
if (this.logOnly.size <= this.maxTrackedTags) {
|
|
1266
|
+
break;
|
|
1267
|
+
}
|
|
1268
|
+
this.logOnly.delete(first);
|
|
1269
|
+
this.raiseFloor(dropped);
|
|
1270
|
+
}
|
|
1271
|
+
}
|
|
1272
|
+
/**
|
|
1273
|
+
* Drop the `logOnly` rows that cannot apply to an entry held, `oldest` or
|
|
1274
|
+
* newer: every revalidation they name so far is no later than it. That
|
|
1275
|
+
* moves `completeSince` no further than `oldest`, which costs the entries
|
|
1276
|
+
* held nothing, and a profile's `expiredAt` still to come waits in
|
|
1277
|
+
* `laterFloors`. Without this, a deployment revalidating many distinct tags
|
|
1278
|
+
* filled `logOnly` with tags no entry here carries, and the evictions past
|
|
1279
|
+
* its bound kept moving `completeSince` up to the present.
|
|
1280
|
+
*/
|
|
1281
|
+
pruneLogged(oldest) {
|
|
1282
|
+
const at = markerClock();
|
|
1283
|
+
for (const [tag, marker] of this.logOnly) {
|
|
1284
|
+
if (knownBy(marker, at) <= oldest) {
|
|
1285
|
+
this.logOnly.delete(tag);
|
|
1286
|
+
this.raiseFloor(marker);
|
|
1287
|
+
}
|
|
1288
|
+
}
|
|
1289
|
+
}
|
|
1290
|
+
/**
|
|
1291
|
+
* The oldest entry timestamp of any registered store, `Infinity` with none:
|
|
1292
|
+
* early, never late, unless `scan`.
|
|
1293
|
+
*/
|
|
1294
|
+
oldestEntry(scan) {
|
|
1295
|
+
let oldest = Infinity;
|
|
1296
|
+
for (const { oldestTimestamp } of this.entryStores) {
|
|
1297
|
+
oldest = Math.min(oldest, oldestTimestamp(scan));
|
|
1298
|
+
}
|
|
1299
|
+
return oldest;
|
|
1300
|
+
}
|
|
1301
|
+
/**
|
|
1302
|
+
* Move `completeSince` past `marker`'s revalidations: what is no longer
|
|
1303
|
+
* known about a tag once its marker is dropped. A future `expiredAt` waits
|
|
1304
|
+
* in `laterFloors` until it is past.
|
|
1305
|
+
*/
|
|
1306
|
+
raiseFloor(marker) {
|
|
1307
|
+
const at = markerClock();
|
|
1308
|
+
this.floor = Math.max(this.floor, knownBy(marker, at));
|
|
1309
|
+
const { expiredAt } = marker;
|
|
1310
|
+
if (expiredAt !== undefined && expiredAt > Math.max(at, this.floor)) {
|
|
1311
|
+
this.laterFloor(expiredAt);
|
|
1312
|
+
}
|
|
1313
|
+
}
|
|
1314
|
+
/**
|
|
1315
|
+
* Add `time` to `laterFloors`, in order. Past the tracked-tag bound the two
|
|
1316
|
+
* spans closest together are merged: from the first's start,
|
|
1317
|
+
* `completeSince` is the second's end, early - which only costs reads, and
|
|
1318
|
+
* for as short a time as any merge allows. Never later than its time, which
|
|
1319
|
+
* would let an entry expire unseen.
|
|
1320
|
+
*/
|
|
1321
|
+
laterFloor(time) {
|
|
1322
|
+
const floors = this.laterFloors;
|
|
1323
|
+
let low = 0;
|
|
1324
|
+
let high = floors.length;
|
|
1325
|
+
while (low < high) {
|
|
1326
|
+
const mid = Math.floor((low + high) / 2);
|
|
1327
|
+
if (floors[mid][0] < time) {
|
|
1328
|
+
low = mid + 1;
|
|
1329
|
+
}
|
|
1330
|
+
else {
|
|
1331
|
+
high = mid;
|
|
1332
|
+
}
|
|
1333
|
+
}
|
|
1334
|
+
// Inside a merged span already: by its start, `completeSince` is past it.
|
|
1335
|
+
// Or already there: a log row for an untracked tag is applied again by
|
|
1336
|
+
// every query its lookback returns it to.
|
|
1337
|
+
if ((low > 0 && floors[low - 1][1] >= time) || floors[low]?.[0] === time) {
|
|
1338
|
+
return;
|
|
1339
|
+
}
|
|
1340
|
+
floors.splice(low, 0, [time, time]);
|
|
1341
|
+
// A scan, but only once past the bound. Merging the new time into a
|
|
1342
|
+
// neighbour instead could join an hour-out span with a year-out one, and
|
|
1343
|
+
// hold `completeSince` a year early.
|
|
1344
|
+
if (floors.length > this.maxTrackedTags) {
|
|
1345
|
+
let merge = 0;
|
|
1346
|
+
for (let i = 1; i < floors.length - 1; i++) {
|
|
1347
|
+
if (floors[i + 1][1] - floors[i][0] <
|
|
1348
|
+
floors[merge + 1][1] - floors[merge][0]) {
|
|
1349
|
+
merge = i;
|
|
1350
|
+
}
|
|
1351
|
+
}
|
|
1352
|
+
floors.splice(merge, 2, [floors[merge][0], floors[merge + 1][1]]);
|
|
1353
|
+
}
|
|
931
1354
|
}
|
|
932
1355
|
/** Record that `tag`'s marker was known from the table at `at`. */
|
|
933
1356
|
known(tag, at) {
|
|
@@ -941,6 +1364,7 @@ class TrackedTagMarkers {
|
|
|
941
1364
|
if (this.tags.size <= this.maxTrackedTags) {
|
|
942
1365
|
break;
|
|
943
1366
|
}
|
|
1367
|
+
this.raiseFloor(this.tags.get(oldest));
|
|
944
1368
|
this.tags.delete(oldest);
|
|
945
1369
|
this.dueAt.delete(oldest);
|
|
946
1370
|
this.unread.delete(oldest);
|
|
@@ -954,12 +1378,34 @@ class TrackedTagMarkers {
|
|
|
954
1378
|
}
|
|
955
1379
|
}
|
|
956
1380
|
exports.TrackedTagMarkers = TrackedTagMarkers;
|
|
1381
|
+
/**
|
|
1382
|
+
* The latest revalidation `marker` has made known by `at`, `-Infinity` with
|
|
1383
|
+
* none: a future `expiredAt` is still to come.
|
|
1384
|
+
*/
|
|
1385
|
+
function knownBy(marker, at) {
|
|
1386
|
+
const { revalidatedAt, staleAt, expiredAt } = marker;
|
|
1387
|
+
return Math.max(revalidatedAt ?? -Infinity, staleAt ?? -Infinity, expiredAt !== undefined && expiredAt <= at ? expiredAt : -Infinity);
|
|
1388
|
+
}
|
|
957
1389
|
/**
|
|
958
1390
|
* The longest a log row's put may take and still be seen by every reader: half
|
|
959
1391
|
* the lookback, leaving the rest for writers' clocks and eventually consistent
|
|
960
1392
|
* queries.
|
|
961
1393
|
*/
|
|
962
1394
|
const MAX_LOG_PUT_MS = exports.REVALIDATION_LOG_LOOKBACK_MS / 2;
|
|
1395
|
+
/**
|
|
1396
|
+
* How often a refresh scans the entry stores for their oldest entry, dropping
|
|
1397
|
+
* the expired ones no request reads again.
|
|
1398
|
+
*/
|
|
1399
|
+
const ENTRY_SCAN_INTERVAL_MS = 60_000;
|
|
1400
|
+
/** How often a refresh in flight checks the process is running. */
|
|
1401
|
+
const REFRESH_TICK_MS = 250;
|
|
1402
|
+
/**
|
|
1403
|
+
* How late a tick may come before the process counts as paused (frozen)
|
|
1404
|
+
* since the refresh in flight started. A busy event loop can delay one too:
|
|
1405
|
+
* the refresh then counts as no fresher than its start, as before the pause
|
|
1406
|
+
* check, so a request waits for the next one once that is past the grace.
|
|
1407
|
+
*/
|
|
1408
|
+
const REFRESH_PAUSE_MS = 1000;
|
|
963
1409
|
/**
|
|
964
1410
|
* A marker as read from the table or the log, keeping whatever this instance
|
|
965
1411
|
* already knows that the read does not show yet: reads are eventually
|
|
@@ -1032,4 +1478,4 @@ class CacheBucket {
|
|
|
1032
1478
|
}
|
|
1033
1479
|
}
|
|
1034
1480
|
exports.CacheBucket = CacheBucket;
|
|
1035
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLWNhY2hlLXN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvYXdzLWNhY2hlLXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQStDQSxzREFPQztBQVNELGdDQUVDO0FBR0Qsa0NBRUM7QUFtQkQsc0NBRUM7QUFxQ0Qsa0NBZ0JDO0FBV0Qsa0NBRUM7QUFXRCw4QkFXQztBQVFELGtDQVdDO0FBR0Qsb0NBZUM7QUF5Q0QsOEJBRUM7QUFZRCxnQ0FFQztBQXM0QkQsb0NBb0JDO0FBM3FDRDs7Ozs7Ozs7O0VBU0U7QUFDRixzREFBc0Q7QUFDdEQseUNBQWlDO0FBQ2pDLDhEQVNrQztBQUNsQyxrREFLNEI7QUFDNUIsK0NBQTZFO0FBa0I3RSw4Q0FBOEM7QUFDOUMsU0FBZ0IscUJBQXFCO0lBQ25DLE9BQU87UUFDTCxVQUFVLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyw0QkFBNEIsSUFBSSxFQUFFO1FBQzFELFNBQVMsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxJQUFJLEVBQUU7UUFDL0QsTUFBTSxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxJQUFJLFdBQVc7UUFDN0MsT0FBTyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsbUJBQW1CLElBQUksRUFBRTtLQUMvQyxDQUFDO0FBQ0osQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQWdCLFVBQVUsQ0FBQyxPQUFlLEVBQUUsUUFBZ0I7SUFDMUQsT0FBTyxJQUFBLGdCQUFJLEVBQUMsT0FBTyxFQUFFLElBQUEsOEJBQWdCLEVBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQztBQUNuRCxDQUFDO0FBRUQsbUZBQW1GO0FBQ25GLFNBQWdCLFdBQVcsQ0FBQyxPQUFlLEVBQUUsUUFBZ0I7SUFDM0QsT0FBTyxJQUFBLGdCQUFJLEVBQUMsT0FBTyxFQUFFLElBQUEsNkJBQWUsRUFBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ2xELENB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Q0FBQztRQUN4RCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLElBQUksS0FBSyxZQUFZLHFCQUFTLEVBQUUsQ0FBQztnQkFDL0IsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUNELE1BQU0sS0FBSyxDQUFDO1FBQ2QsQ0FBQztJQUNILENBQUM7SUFFRCw4Q0FBOEM7SUFDOUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFXLEVBQUUsSUFBWTtRQUNyQyxNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUNwQixJQUFJLDRCQUFnQixDQUFDO1lBQ25CLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVTtZQUN2QixHQUFHLEVBQUUsR0FBRztZQUNSLElBQUksRUFBRSxJQUFJO1lBQ1YsV0FBVyxFQUFFLGlDQUFpQztTQUMvQyxDQUFDLENBQ0gsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQXZDRCxrQ0F1Q0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKlxuICBUaGUgUzMgLyBEeW5hbW9EQiBwbHVtYmluZyBzaGFyZWQgYnkgZXZlcnkgY2RrLW5leHRqcyBjYWNoZSBoYW5kbGVyOiB0aGVcbiAgaW5jcmVtZW50YWwgYGNhY2hlSGFuZGxlcmAgKGBTM0NhY2hlSGFuZGxlcmApIGFuZCB0aGUgYGNhY2hlSGFuZGxlcnNgIGZvclxuICBgJ3VzZSBjYWNoZSdgIC8gYCd1c2UgY2FjaGU6IHJlbW90ZSdgLlxuXG4gIFdoYXQgbGl2ZXMgaGVyZSBpcyB3aGF0IGhhcyB0byBhZ3JlZSBiZXR3ZWVuIHRoZW0gLSB3aGVyZSB0aGUgY29uZmlndXJhdGlvblxuICBjb21lcyBmcm9tLCBob3cgYSBjYWNoZSBrZXkgYmVjb21lcyBhbiBTMyBrZXksIGFuZCB3aGF0IGEgdGFnJ3MgbWFya2VyIHJvdyBpblxuICB0aGUgcmV2YWxpZGF0aW9uIHRhYmxlIGxvb2tzIGxpa2UgYW5kIG1lYW5zLiBBIGByZXZhbGlkYXRlVGFnYCByZWFjaGVzIGJvdGhcbiAga2luZHMgb2YgaGFuZGxlciwgYW5kIHRoZXkgbXVzdCByZWFkIGVhY2ggb3RoZXIncyBtYXJrZXJzIHRoZSBzYW1lIHdheS5cbiovXG4vKiBlc2xpbnQtZGlzYWJsZSBpbXBvcnQvbm8tZXh0cmFuZW91cy1kZXBlbmRlbmNpZXMgKi9cbmltcG9ydCB7IGpvaW4gfSBmcm9tIFwibm9kZTpwYXRoXCI7XG5pbXBvcnQge1xuICBBdHRyaWJ1dGVWYWx1ZSxcbiAgQmF0Y2hHZXRJdGVtQ29tbWFuZCxcbiAgQmF0Y2hHZXRJdGVtQ29tbWFuZE91dHB1dCxcbiAgRHluYW1vREJDbGllbnQsXG4gIFB1dEl0ZW1Db21tYW5kLFxuICBRdWVyeUNvbW1hbmQsXG4gIFF1ZXJ5Q29tbWFuZE91dHB1dCxcbiAgVXBkYXRlSXRlbUNvbW1hbmQsXG59IGZyb20gXCJAYXdzLXNkay9jbGllbnQtZHluYW1vZGJcIjtcbmltcG9ydCB7XG4gIEdldE9iamVjdENvbW1hbmQsXG4gIE5vU3VjaEtleSxcbiAgUHV0T2JqZWN0Q29tbWFuZCxcbiAgUzNDbGllbnQsXG59IGZyb20gXCJAYXdzLXNkay9jbGllbnQtczNcIjtcbmltcG9ydCB7IGNhY2hlS2V5RmlsZU5hbWUsIGNhY2hlT2JqZWN0TmFtZSwgc2hhMjU2SGV4IH0gZnJvbSBcIi4vY2FjaGUtdXRpbHNcIjtcblxuLyoqXG4gKiBXaGVyZSB0aGUgY2FjaGUgbGl2ZXMsIGFzIHRoZSBjb25zdHJ1Y3RzIHBhc3MgaXQgdG8gdGhlIGNvbXB1dGUgdGhyb3VnaCB0aGVcbiAqIGVudmlyb25tZW50IChgTmV4dGpzRnVuY3Rpb25zYCwgYE5leHRqc0NvbnRhaW5lcnNgKS4gRW1wdHkgc3RyaW5ncyBmb3Igd2hhdCBpc1xuICogbm90IGNvbmZpZ3VyZWQsIHdoaWNoIGVhY2ggaGFuZGxlciByZWFkcyBhcyBcInRoYXQgbGF5ZXIgaXMgZGlzYWJsZWRcIi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBd3NDYWNoZUNvbmZpZyB7XG4gIC8qKiBgQ0RLX05FWFRKU19DQUNIRV9CVUNLRVRfTkFNRWAuICovXG4gIGJ1Y2tldE5hbWU6IHN0cmluZztcbiAgLyoqIGBDREtfTkVYVEpTX1JFVkFMSURBVElPTl9UQUJMRV9OQU1FYC4gKi9cbiAgdGFibGVOYW1lOiBzdHJpbmc7XG4gIC8qKiBgQVdTX1JFR0lPTmAsIGB1cy1lYXN0LTFgIHdoZW4gdW5zZXQuICovXG4gIHJlZ2lvbjogc3RyaW5nO1xuICAvKiogYENES19ORVhUSlNfQlVJTERfSURgOiBldmVyeSBTMyBrZXkgYW5kIGV2ZXJ5IG1hcmtlciByb3cgaXMgc2NvcGVkIHRvIGl0LiAqL1xuICBidWlsZElkOiBzdHJpbmc7XG59XG5cbi8qKiBUaGUgY29uZmlndXJhdGlvbiBmcm9tIHRoZSBlbnZpcm9ubWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQXdzQ2FjaGVDb25maWcoKTogQXdzQ2FjaGVDb25maWcge1xuICByZXR1cm4ge1xuICAgIGJ1Y2tldE5hbWU6IHByb2Nlc3MuZW52LkNES19ORVhUSlNfQ0FDSEVfQlVDS0VUX05BTUUgfHwgXCJcIixcbiAgICB0YWJsZU5hbWU6IHByb2Nlc3MuZW52LkNES19ORVhUSlNfUkVWQUxJREFUSU9OX1RBQkxFX05BTUUgfHwgXCJcIixcbiAgICByZWdpb246IHByb2Nlc3MuZW52LkFXU19SRUdJT04gfHwgXCJ1cy1lYXN0LTFcIixcbiAgICBidWlsZElkOiBwcm9jZXNzLmVudi5DREtfTkVYVEpTX0JVSUxEX0lEIHx8IFwiXCIsXG4gIH07XG59XG5cbi8qKlxuICogYHtidWlsZElkfS97Y2FjaGVLZXl9Lmpzb25gLCB0aGUgaW5jcmVtZW50YWwgY2FjaGUncyBrZXkgY29udmVudGlvbi5cbiAqXG4gKiBUaGUgcm9vdCBwYXRoIGJlY29tZXMgYGluZGV4YCwgYW5kIGEgbGVhZGluZyBzbGFzaCBpcyBkcm9wcGVkIHNvIHRoZXJlIGlzIG5vXG4gKiBlbXB0eSBmb2xkZXIgdW5kZXIgdGhlIGJ1aWxkIHByZWZpeC4gRXZlcnl0aGluZyB0aGlzIHJldHVybnMgZW5kcyBpbiBgLmpzb25gLFxuICogd2hpY2ggaXMgd2hhdCBrZWVwcyBpdCBkaXNqb2ludCBmcm9tIHtAbGluayB1c2VDYWNoZVMzS2V5fS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUzNLZXkoYnVpbGRJZDogc3RyaW5nLCBjYWNoZUtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oYnVpbGRJZCwgY2FjaGVLZXlGaWxlTmFtZShjYWNoZUtleSkpO1xufVxuXG4vKiogYHtidWlsZElkfS9gICsge0BsaW5rIGNhY2hlT2JqZWN0TmFtZX06IHRoZSBTMyBvYmplY3QgYW4gZW50cnkgaXMgc3RvcmVkIGluLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHMzT2JqZWN0S2V5KGJ1aWxkSWQ6IHN0cmluZywgY2FjaGVLZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGJ1aWxkSWQsIGNhY2hlT2JqZWN0TmFtZShjYWNoZUtleSkpO1xufVxuXG4vKipcbiAqIFRoZSBmb2xkZXIgdW5kZXIgdGhlIGJ1aWxkIHByZWZpeCB0aGF0IGAndXNlIGNhY2hlJ2AgZW50cmllcyBhcmUgc3RvcmVkIGluLlxuICogQHNlZSB1c2VDYWNoZVMzS2V5XG4gKi9cbmV4cG9ydCBjb25zdCBVU0VfQ0FDSEVfS0VZX1BSRUZJWCA9IFwiX3VzZS1jYWNoZVwiO1xuXG4vKipcbiAqIGB7YnVpbGRJZH0vX3VzZS1jYWNoZS97aGFzaH0uZW50cnlgLCB3aGVyZSBhIGBjYWNoZUhhbmRsZXJzYCBlbnRyeSBpcyBzdG9yZWQuXG4gKlxuICogSGFzaGVkIGJlY2F1c2UgYSBgJ3VzZSBjYWNoZSdgIGtleSBpcyB0aGUgc2VyaWFsaXplZCBhcmd1bWVudHMgb2YgdGhlIGNhbGwgYW5kXG4gKiBoYXMgbm8gbGVuZ3RoIGxpbWl0LCB3aGVyZSBhbiBTMyBrZXkgc3RvcHMgYXQgMTAyNCBieXRlcy4gVGhlIGAuZW50cnlgIHN1ZmZpeFxuICogcmF0aGVyIHRoYW4gYC5qc29uYCBpcyB3aGF0IG1ha2VzIGEgY29sbGlzaW9uIHdpdGggdGhlIGluY3JlbWVudGFsIGNhY2hlXG4gKiBpbXBvc3NpYmxlIHJhdGhlciB0aGFuIHVubGlrZWx5OiBldmVyeSBvYmplY3Qge0BsaW5rIHMzT2JqZWN0S2V5fSBuYW1lcyBlbmRzXG4gKiBpbiBgLmpzb25gIG9yIGAubG9uZ2AsIGluY2x1ZGluZyBvbmUgZm9yIGEgcm91dGUgdGhhdCBoYXBwZW5zIHRvIGJlIG5hbWVkXG4gKiBgL191c2UtY2FjaGUv4oCmYC5cbiAqIFN0aWxsIHVuZGVyIHRoZSBidWlsZCBwcmVmaXgsIHNvIHBvc3QtZGVwbG95IHBydW5pbmcgZHJvcHMgdGhlbSB3aXRoIHRoZSBidWlsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZUNhY2hlUzNLZXkoYnVpbGRJZDogc3RyaW5nLCBrZXlIYXNoOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihidWlsZElkLCBVU0VfQ0FDSEVfS0VZX1BSRUZJWCwgYCR7a2V5SGFzaH0uZW50cnlgKTtcbn1cblxuLyoqXG4gKiBUaGUgYGR1cmF0aW9uc2AgTmV4dC5qcyAxNiBwYXNzZXMgYSB0YWcgcmV2YWxpZGF0aW9uIGZvciBhIHByb2ZpbGU6XG4gKiBgcmV2YWxpZGF0ZVRhZyhcInBvc3RzXCIsIFwibWF4XCIpYCBhcnJpdmVzIGFzIGB7IGV4cGlyZTogPHRoZSBwcm9maWxlJ3MgZXhwaXJlPiB9YC5cbiAqIEFic2VudCBmb3IgYHVwZGF0ZVRhZ2AgYW5kIGEgYmFyZSBgcmV2YWxpZGF0ZVRhZ2AsIHdoaWNoIGV4cGlyZSBpbW1lZGlhdGVseS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXZhbGlkYXRlRHVyYXRpb25zIHtcbiAgZXhwaXJlPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEEgdGFnJ3MgbWFya2VyIHJvdywgYXMgdGltZXN0YW1wcyBpbiBtaWxsaXNlY29uZHMuIFdyaXR0ZW4gYnlcbiAqIHtAbGluayBtYXJrZXJVcGRhdGV9OyBlYWNoIGZpZWxkIGlzIGFic2VudCB1bnRpbCBhIHJldmFsaWRhdGlvbiBvZiB0aGF0IHNoYXBlXG4gKiBoYXMgaGFwcGVuZWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGFnTWFya2VyIHtcbiAgLyoqIEV4cGlyZWQgb3V0cmlnaHQ6IGB1cGRhdGVUYWdgLCBvciBgcmV2YWxpZGF0ZVRhZ2Agd2l0aCBubyBwcm9maWxlLiAqL1xuICByZXZhbGlkYXRlZEF0PzogbnVtYmVyO1xuICAvKiogU3RhbGUgZnJvbSBoZXJlOiBgcmV2YWxpZGF0ZVRhZyh0YWcsIHByb2ZpbGUpYC4gKi9cbiAgc3RhbGVBdD86IG51bWJlcjtcbiAgLyoqIFdoZW4gdGhlIHByb2ZpbGUncyBgZXhwaXJlYCBydW5zIG91dCwgd2hpY2ggbWF5IGJlIGluIHRoZSBmdXR1cmUuICovXG4gIGV4cGlyZWRBdD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBXaGF0IHRoZSB0YWcgbWFya2VycyBzYXkgYWJvdXQgYW4gZW50cnk6IHVudG91Y2hlZCwgc2VydmVkIHN0YWxlIHdoaWxlIGFcbiAqIGJhY2tncm91bmQgcmVuZGVyIHJlcGxhY2VzIGl0LCBvciBleHBpcmVkIGFuZCByZS1yZW5kZXJlZCBiZWZvcmUgYW5zd2VyaW5nLlxuICovXG5leHBvcnQgdHlwZSBSZXZhbGlkYXRpb25TdGF0ZSA9IFwiZnJlc2hcIiB8IFwic3RhbGVcIiB8IFwiZXhwaXJlZFwiO1xuXG4vKipcbiAqIFdoYXQgYG1hcmtlcmAgbWVhbnMgZm9yIGFuIGVudHJ5IGNyZWF0ZWQgYXQgYGNyZWF0ZWRBdGAsIGF0IGBub3dgLlxuICpcbiAqIGBleHBpcmVkQXRgIGluIHRoZSBmdXR1cmUgaXMgYSBwcm9maWxlJ3MgYGV4cGlyZWAgdGhhdCBoYXMgbm90IGNvbWUgeWV0LFxuICogY29tcGFyZWQgdGhlIHdheSBOZXh0LmpzJ3MgYGFyZVRhZ3NFeHBpcmVkYCBkb2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2VyU3RhdGUoXG4gIG1hcmtlcjogVGFnTWFya2VyLFxuICBjcmVhdGVkQXQ6IG51bWJlcixcbiAgbm93OiBudW1iZXIsXG4pOiBSZXZhbGlkYXRpb25TdGF0ZSB7XG4gIGNvbnN0IHsgcmV2YWxpZGF0ZWRBdCwgZXhwaXJlZEF0LCBzdGFsZUF0IH0gPSBtYXJrZXI7XG4gIGlmIChcbiAgICAocmV2YWxpZGF0ZWRBdCAhPT0gdW5kZWZpbmVkICYmIHJldmFsaWRhdGVkQXQgPiBjcmVhdGVkQXQpIHx8XG4gICAgKGV4cGlyZWRBdCAhPT0gdW5kZWZpbmVkICYmIGV4cGlyZWRBdCA8PSBub3cgJiYgZXhwaXJlZEF0ID4gY3JlYXRlZEF0KVxuICApIHtcbiAgICByZXR1cm4gXCJleHBpcmVkXCI7XG4gIH1cbiAgaWYgKHN0YWxlQXQgIT09IHVuZGVmaW5lZCAmJiBzdGFsZUF0ID4gY3JlYXRlZEF0KSB7XG4gICAgcmV0dXJuIFwic3RhbGVcIjtcbiAgfVxuICByZXR1cm4gXCJmcmVzaFwiO1xufVxuXG4vKipcbiAqIFRoZSBjbG9jayBldmVyeSB0YWcgbWFya2VyIGlzIHN0YW1wZWQgd2l0aCwgYW5kIGV2ZXJ5IGVudHJ5IHRpbWVzdGFtcCBpdCBpc1xuICogY29tcGFyZWQgYWdhaW5zdDogdGhlIG9uZSBOZXh0LmpzIHN0YW1wcyBgQ2FjaGVFbnRyeS50aW1lc3RhbXBgIHdpdGhcbiAqIChgcGVyZm9ybWFuY2UudGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpYCwgaW4gYHVzZS1jYWNoZS13cmFwcGVyLmpzYCBhbmRcbiAqIHRoZSBkZWZhdWx0IGhhbmRsZXIpLCByYXRoZXIgdGhhbiBgRGF0ZS5ub3coKWAuIEJvdGggaGFuZGxlcnMgd3JpdGUgdGhlIHNhbWVcbiAqIG1hcmtlciByb3dzLCBzbyBib3RoIGhhdmUgdG8gdXNlIGl0OiB0d28gY2xvY2tzIG9uIG9uZSByb3cgbGV0IHRoZSBsYXN0IHdyaXRlclxuICogZGVjaWRlIHdoaWNoIGNsb2NrIHRoZSBvdGhlcnMgY29tcGFyZSBhZ2FpbnN0LCBhbmQgdGhleSBkcmlmdCBhcGFydCBmb3IgYXNcbiAqIGxvbmcgYXMgYSBMYW1iZGEgc2FuZGJveCBvciBGYXJnYXRlIHRhc2sgbGl2ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJDbG9jaygpOiBudW1iZXIge1xuICByZXR1cm4gcGVyZm9ybWFuY2UudGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpO1xufVxuXG4vKipcbiAqIFRoZSBtYXJrZXIgZmllbGRzIGEgdGFnIHJldmFsaWRhdGVkIGF0IGBub3dgIHNldHMuXG4gKlxuICogV2l0aG91dCBgZHVyYXRpb25zYCAtIGB1cGRhdGVUYWdgLCBvciBgcmV2YWxpZGF0ZVRhZ2Agd2l0aCBubyBwcm9maWxlIC0gdGhlXG4gKiB0YWcncyBlbnRyaWVzIGV4cGlyZSBpbW1lZGlhdGVseSAoYHJldmFsaWRhdGVkQXRgKS4gV2l0aCB0aGVtIHRoZSBlbnRyaWVzIGdvXG4gKiBzdGFsZSBub3cgYW5kIGV4cGlyZSBhZnRlciB0aGUgcHJvZmlsZSdzIGBleHBpcmVgLCB0aGUgc2FtZSBwYWlyIG9mXG4gKiB0aW1lc3RhbXBzIE5leHQuanMncyBgRmlsZVN5c3RlbUNhY2hlLnJldmFsaWRhdGVUYWdgIHJlY29yZHMuIEEgcHJvZmlsZSB3aXRoXG4gKiBubyBgZXhwaXJlYCBzZXRzIG9ubHkgYHN0YWxlQXRgLCBhbmQgd2hhdGV2ZXIgYGV4cGlyZWRBdGAgdGhlIHRhZyBoYWQgc3RheXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJGb3IoXG4gIG5vdzogbnVtYmVyLFxuICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4pOiBUYWdNYXJrZXIge1xuICBpZiAoIWR1cmF0aW9ucykge1xuICAgIHJldHVybiB7IHJldmFsaWRhdGVkQXQ6IG5vdyB9O1xuICB9XG4gIGlmIChkdXJhdGlvbnMuZXhwaXJlID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4geyBzdGFsZUF0OiBub3cgfTtcbiAgfVxuICByZXR1cm4geyBzdGFsZUF0OiBub3csIGV4cGlyZWRBdDogbm93ICsgZHVyYXRpb25zLmV4cGlyZSAqIDEwMDAgfTtcbn1cblxuY29uc3QgTUFSS0VSX0ZJRUxEUyA9IFtcInJldmFsaWRhdGVkQXRcIiwgXCJzdGFsZUF0XCIsIFwiZXhwaXJlZEF0XCJdIGFzIGNvbnN0O1xuXG4vKipcbiAqIGBleGlzdGluZ2Agd2l0aCB0aGUgZmllbGRzIGB1cGRhdGVgIHNldHMsIGFzIGEge0BsaW5rIG1hcmtlclVwZGF0ZX0gbGVhdmVzXG4gKiB0aGUgcm93OiBhIGZpZWxkIGB1cGRhdGVgIGRvZXMgbm90IHNldCBrZWVwcyBpdHMgdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseU1hcmtlcihcbiAgZXhpc3Rpbmc6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCxcbiAgdXBkYXRlOiBUYWdNYXJrZXIsXG4pOiBUYWdNYXJrZXIge1xuICBjb25zdCBtYXJrZXIgPSB7IC4uLmV4aXN0aW5nIH07XG4gIGZvciAoY29uc3QgZmllbGQgb2YgTUFSS0VSX0ZJRUxEUykge1xuICAgIGlmICh1cGRhdGVbZmllbGRdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1hcmtlcltmaWVsZF0gPSB1cGRhdGVbZmllbGRdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWFya2VyO1xufVxuXG4vKiogVGhlIG1hcmtlci1yb3cgdXBkYXRlIHRoYXQgc2V0cyB7QGxpbmsgbWFya2VyRm9yfSdzIGZpZWxkcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJVcGRhdGUoXG4gIG5vdzogbnVtYmVyLFxuICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4pOiBQaWNrPFxuICBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIFVwZGF0ZUl0ZW1Db21tYW5kPlswXSxcbiAgXCJVcGRhdGVFeHByZXNzaW9uXCIgfCBcIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXNcIlxuPiB7XG4gIGNvbnN0IG1hcmtlciA9IG1hcmtlckZvcihub3csIGR1cmF0aW9ucyk7XG4gIGNvbnN0IGZpZWxkcyA9IE1BUktFUl9GSUVMRFMuZmlsdGVyKChmaWVsZCkgPT4gbWFya2VyW2ZpZWxkXSAhPT0gdW5kZWZpbmVkKTtcbiAgcmV0dXJuIHtcbiAgICBVcGRhdGVFeHByZXNzaW9uOiBgU0VUICR7ZmllbGRzLm1hcCgoZmllbGQpID0+IGAke2ZpZWxkfSA9IDoke2ZpZWxkfWApLmpvaW4oXCIsIFwiKX1gLFxuICAgIEV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXM6IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIGZpZWxkcy5tYXAoKGZpZWxkKSA9PiBbYDoke2ZpZWxkfWAsIHsgTjogU3RyaW5nKG1hcmtlcltmaWVsZF0pIH1dKSxcbiAgICApLFxuICB9O1xufVxuXG4vKiogQSBEeW5hbW9EQiBudW1iZXIgYXR0cmlidXRlIGFzIGEgbnVtYmVyLCBvciBgdW5kZWZpbmVkYCB3aGVuIGFic2VudC4gKi9cbmZ1bmN0aW9uIG51bWJlckF0dHJpYnV0ZShcbiAgdmFsdWU6IEF0dHJpYnV0ZVZhbHVlIHwgdW5kZWZpbmVkLFxuKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhbHVlPy5OID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBOdW1iZXIodmFsdWUuTik7XG59XG5cbi8qKiBUaGUgbWFya2VyIGZpZWxkcyBvZiBhIG1hcmtlciBvciBsb2cgcm93LiAqL1xuZnVuY3Rpb24gbWFya2VyT2YoaXRlbTogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlVmFsdWU+KTogVGFnTWFya2VyIHtcbiAgcmV0dXJuIHtcbiAgICByZXZhbGlkYXRlZEF0OiBudW1iZXJBdHRyaWJ1dGUoaXRlbS5yZXZhbGlkYXRlZEF0KSxcbiAgICBzdGFsZUF0OiBudW1iZXJBdHRyaWJ1dGUoaXRlbS5zdGFsZUF0KSxcbiAgICBleHBpcmVkQXQ6IG51bWJlckF0dHJpYnV0ZShpdGVtLmV4cGlyZWRBdCksXG4gIH07XG59XG5cbi8qKiBEeW5hbW9EQidzIGNhcCBvbiBrZXlzIGluIG9uZSBgQmF0Y2hHZXRJdGVtYC4gKi9cbmV4cG9ydCBjb25zdCBCQVRDSF9HRVRfTUFYX0tFWVMgPSAxMDA7XG5cbi8qKlxuICogSG93IG9mdGVuLCBhdCBtb3N0LCBhbiBpbnN0YW5jZSBjYXRjaGVzIHVwIG9uIHJldmFsaWRhdGlvbnMgb3RoZXIgaW5zdGFuY2VzXG4gKiByYW4sIHVubGVzcyBgQ0RLX05FWFRKU19UQUdfUkVGUkVTSF9NU2Agc2F5cyBvdGhlcndpc2U6IHRoZSBzdGFsZW5lc3Mgd2luZG93XG4gKiBmb3IgYSBgcmV2YWxpZGF0ZVRhZ2AgcnVuIGVsc2V3aGVyZS4gRXZlcnkgY2FjaGUgaGl0IGNoZWNrcyBpdHMgdGFncydcbiAqIG1hcmtlcnMsIGFuZCBldmVyeSBtYXJrZXIgb2YgYSBkZXBsb3ltZW50IHNoYXJlcyBvbmUgcGFydGl0aW9uIGtleSwgc29cbiAqIHJlYWRpbmcgdGhlbSBwZXIgcmVxdWVzdCBjYXBwZWQgYSByb3V0ZSdzIGNhY2hlIGhpdHMgYXQgdGhlIHBhcnRpdGlvbidzIHJlYWRcbiAqIHRocm91Z2hwdXQgKH4xLDkwMCByZXEvcyBvbiBOZXh0anNSZWdpb25hbEZ1bmN0aW9ucykuIE9uY2UgYSBzZWNvbmQsIGZyb20gdGhlXG4gKiByZXZhbGlkYXRpb24gbG9nLCB0aGUgcmVhZHMgc2NhbGUgd2l0aCBpbnN0YW5jZXMgaW5zdGVhZCBvZiByZXF1ZXN0cyBvciB0YWdzLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9UQUdfUkVGUkVTSF9NUyA9IDEwMDA7XG5cbi8qKiBEeW5hbW9EQidzIGxpbWl0IG9uIGEgc29ydCBrZXksIGluIFVURi04IGJ5dGVzLiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9TT1JUX0tFWV9CWVRFUyA9IDEwMjQ7XG5cbi8qKlxuICogYCM8c2hhMjU2KHRhZyk+YCwgc3RhbmRpbmcgaW4gZm9yIGEgdGFnIGluIGEgc29ydCBrZXkgaXQgd291bGQgcHVzaCBwYXN0XG4gKiB7QGxpbmsgTUFYX1NPUlRfS0VZX0JZVEVTfS4gTmV4dC5qcyBjYXBzIHRoZSB0YWdzIGFuIGFwcCBuYW1lcywgYnV0IG5vdCBhblxuICogaW1wbGljaXQgYF9OX1RfL+KApmAgdGFnLCB3aGljaCBpcyBhcyBsb25nIGFzIGl0cyBwYXRoLCBhbmQgYSByZWplY3RlZCB3cml0ZVxuICogbGVmdCBgcmV2YWxpZGF0ZVBhdGhgIG9uIGEgbG9uZyBwYXRoIHJlY29yZGVkIG5vd2hlcmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoZWRUYWcodGFnOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCMke3NoYTI1NkhleCh0YWcpfWA7XG59XG5cbi8qKlxuICogVGhlIGxvbmdlc3QgdGFnIGEgc29ydCBrZXkgc3BlbGxzIG91dDsgcGFzdCBpdCwge0BsaW5rIHNvcnRLZXlUYWd9IGhhc2hlc1xuICogaXQuIE9uZSBjYXAgZm9yIGV2ZXJ5IHJvdyB0aGUgdGFnIGlzIGluLCBzbyBhIHJvdydzIHdyaXRlciBhbmQgcmVhZGVyIGFncmVlXG4gKiB3aXRob3V0IGVhY2ggd29ya2luZyBvdXQgd2hhdCBlbHNlIHNoYXJlcyBpdHMga2V5LiBJdCBsZWF2ZXMgcm9vbSBmb3IgdGhlXG4gKiBtb3N0IGFueSByb3cgcHV0cyBiZXNpZGUgdGhlIHRhZzogYSBtYXBwaW5nIHJvdydzIGAjPGJ1aWxkSWQ+LyM8c2hhMjU2PmAsXG4gKiB3aXRoIHRoZSBidWlsZCBJRCBjYXBwZWQgYXQgYE1BWF9CVUlMRF9JRF9CWVRFU2AuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfVEFHX0JZVEVTID0gNzY4O1xuXG4vKiogYHRhZ2AgYXMgYSBzb3J0IGtleSBzcGVsbHMgaXQ6IGl0c2VsZiwgb3Ige0BsaW5rIGhhc2hlZFRhZ30gcGFzdCB7QGxpbmsgTUFYX1RBR19CWVRFU30uICovXG5leHBvcnQgZnVuY3Rpb24gc29ydEtleVRhZyh0YWc6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBCdWZmZXIuYnl0ZUxlbmd0aCh0YWcpIDw9IE1BWF9UQUdfQllURVMgPyB0YWcgOiBoYXNoZWRUYWcodGFnKTtcbn1cblxuLyoqXG4gKiBUaGUgYmFyZS10YWcgbWFya2VyIHJvd3Mgb2YgdGhlIHJldmFsaWRhdGlvbiB0YWJsZSAoYHBrID0gYnVpbGRJZGAsXG4gKiBgc2sgPSB0YWdgLCBvciB7QGxpbmsgaGFzaGVkVGFnfSBwYXN0IHtAbGluayBNQVhfVEFHX0JZVEVTfSksIHdoaWNoIHJlY29yZCB3aGVuIGEgdGFnXG4gKiB3YXMgbGFzdCByZXZhbGlkYXRlZCBhbmQgaG93LlxuICpcbiAqIFRoZSB0YWJsZSBhbHNvIGhvbGRzIHRoZSBpbmNyZW1lbnRhbCBjYWNoZSdzIGB0YWcjczNLZXlgIG1hcHBpbmcgcm93cywgd2hpY2hcbiAqIGFyZSBpdHMgb3duIGJ1c2luZXNzIGFuZCBzdGF5IGluIGBTM0NhY2hlSGFuZGxlcmA6IG9ubHkgdGhlIG1hcmtlcnMgbWVhbiB0aGVcbiAqIHNhbWUgdGhpbmcgdG8gZXZlcnkgaGFuZGxlci4gV2hhdCBhbiBpbnN0YW5jZSBrZWVwcyBvZiB0aGVtIGJldHdlZW4gcmVhZHMgaXNcbiAqIHtAbGluayBUcmFja2VkVGFnTWFya2Vyc30uXG4gKi9cbmV4cG9ydCBjbGFzcyBUYWdNYXJrZXJUYWJsZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBEeW5hbW9EQkNsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYnVpbGRJZDogc3RyaW5nLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIFJlY29yZCBgdGFnYCdzIHJldmFsaWRhdGlvbiBhdCBgbm93YC4gU2VlIHtAbGluayBtYXJrZXJVcGRhdGV9LlxuICAgKlxuICAgKiBSZXR1cm5zIHRoZSByb3cgYXMgdGhpcyB3cml0ZSBsZWZ0IGl0LCBzbyB0aGUgaW5zdGFuY2UgdGhhdCB3cm90ZSBpdCBjYW5cbiAgICogdHJhY2sgaXQgcmF0aGVyIHRoYW4gcmVhZCBpdCBiYWNrOiByZWFkcyBhcmUgZXZlbnR1YWxseSBjb25zaXN0ZW50LCBhbmQgYVxuICAgKiByZWFkLWJhY2sgcmFjaW5nIHJlcGxpY2F0aW9uIGNvdWxkIHJldHVybiB0aGUgbWFya2VyIGZyb20gYmVmb3JlIHRoZSB3cml0ZS5cbiAgICovXG4gIGFzeW5jIHdyaXRlKFxuICAgIHRhZzogc3RyaW5nLFxuICAgIG5vdzogbnVtYmVyLFxuICAgIGR1cmF0aW9uczogUmV2YWxpZGF0ZUR1cmF0aW9ucyB8IHVuZGVmaW5lZCxcbiAgKTogUHJvbWlzZTxUYWdNYXJrZXIgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICBuZXcgVXBkYXRlSXRlbUNvbW1hbmQoe1xuICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICBLZXk6IHtcbiAgICAgICAgICBwazogeyBTOiB0aGlzLmJ1aWxkSWQgfSxcbiAgICAgICAgICBzazogeyBTOiBzb3J0S2V5VGFnKHRhZykgfSxcbiAgICAgICAgfSxcbiAgICAgICAgLi4ubWFya2VyVXBkYXRlKG5vdywgZHVyYXRpb25zKSxcbiAgICAgICAgUmV0dXJuVmFsdWVzOiBcIkFMTF9ORVdcIixcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIHJlc3BvbnNlPy5BdHRyaWJ1dGVzID8gbWFya2VyT2YocmVzcG9uc2UuQXR0cmlidXRlcykgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG1hcmtlciByb3dzIGZvciBgdGFnc2AgdGhhdCBleGlzdCwgYnkgdGFnLCBpbiBvbmUgYEJhdGNoR2V0SXRlbWAgcGVyXG4gICAqIHtAbGluayBCQVRDSF9HRVRfTUFYX0tFWVN9IHRhZ3MgcmF0aGVyIHRoYW4gYSBgR2V0SXRlbWAgZWFjaDogYSBwYWdlXG4gICAqIGNhcnJpZXMgaXRzIHdob2xlIGltcGxpY2l0IGBfTl9UXy/igKZgIGNoYWluIHBsdXMgdGhlIGFwcCdzIG93biB0YWdzLCBhXG4gICAqIHBhZ2Ugd2l0aCBhIGZldyBmZXRjaGVzIGNoZWNrcyBlYWNoIG9mIHRoZW0gdG9vLCBhbmQgZXZlcnkgb25lIGlzIG9uIHRoZVxuICAgKiByZXF1ZXN0IHBhdGguIEEgdGFnIHdpdGggbm8gcm93IGlzIGFic2VudCBmcm9tIHRoZSByZXN1bHQuXG4gICAqL1xuICBhc3luYyByZWFkKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBUYWdNYXJrZXI+PiB7XG4gICAgY29uc3QgeyB0YWJsZU5hbWUsIGJ1aWxkSWQgfSA9IHRoaXM7XG4gICAgY29uc3QgdW5pcXVlID0gQXJyYXkuZnJvbShuZXcgU2V0KHRhZ3MpKTtcbiAgICBjb25zdCBtYXJrZXJzID0gbmV3IE1hcDxzdHJpbmcsIFRhZ01hcmtlcj4oKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdW5pcXVlLmxlbmd0aDsgaSArPSBCQVRDSF9HRVRfTUFYX0tFWVMpIHtcbiAgICAgIC8vIEEgaGFzaGVkIHNvcnQga2V5IG5hbWVzIG5vIHRhZywgc28gZWFjaCByb3cgaXMgbWF0Y2hlZCBiYWNrIGJ5IGtleS5cbiAgICAgIGNvbnN0IHRhZ0J5U2sgPSBuZXcgTWFwKFxuICAgICAgICB1bmlxdWVcbiAgICAgICAgICAuc2xpY2UoaSwgaSArIEJBVENIX0dFVF9NQVhfS0VZUylcbiAgICAgICAgICAubWFwKCh0YWcpID0+IFtzb3J0S2V5VGFnKHRhZyksIHRhZ10pLFxuICAgICAgKTtcbiAgICAgIGxldCBrZXlzOiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT5bXSB8IHVuZGVmaW5lZCA9IEFycmF5LmZyb20oXG4gICAgICAgIHRhZ0J5U2sua2V5cygpLFxuICAgICAgICAoc2spID0+ICh7IHBrOiB7IFM6IGJ1aWxkSWQgfSwgc2s6IHsgUzogc2sgfSB9KSxcbiAgICAgICk7XG4gICAgICAvLyBgVW5wcm9jZXNzZWRLZXlzYCBpcyBEeW5hbW9EQiBkZWNsaW5pbmcgcGFydCBvZiB0aGUgYmF0Y2ggdW5kZXIgbG9hZDtcbiAgICAgIC8vIGEgbWFya2VyIGxlZnQgdW5yZWFkIGlzIGEgcmV2YWxpZGF0aW9uIG1pc3NlZCwgc28gaXQgaXMgYXNrZWQgYWdhaW4uXG4gICAgICBmb3IgKGxldCBhdHRlbXB0ID0gMDsga2V5cz8ubGVuZ3RoICYmIGF0dGVtcHQgPCAzOyBhdHRlbXB0KyspIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2U6IEJhdGNoR2V0SXRlbUNvbW1hbmRPdXRwdXQgPSBhd2FpdCB0aGlzLmNsaWVudC5zZW5kKFxuICAgICAgICAgIG5ldyBCYXRjaEdldEl0ZW1Db21tYW5kKHtcbiAgICAgICAgICAgIFJlcXVlc3RJdGVtczoge1xuICAgICAgICAgICAgICBbdGFibGVOYW1lXToge1xuICAgICAgICAgICAgICAgIEtleXM6IGtleXMsXG4gICAgICAgICAgICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246IFwic2ssIHJldmFsaWRhdGVkQXQsIHN0YWxlQXQsIGV4cGlyZWRBdFwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHJlc3BvbnNlLlJlc3BvbnNlcz8uW3RhYmxlTmFtZV0gPz8gW10pIHtcbiAgICAgICAgICBjb25zdCB0YWcgPSB0YWdCeVNrLmdldChpdGVtLnNrPy5TID8/IFwiXCIpO1xuICAgICAgICAgIGlmICh0YWcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbWFya2Vycy5zZXQodGFnLCBtYXJrZXJPZihpdGVtKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGtleXMgPSByZXNwb25zZS5VbnByb2Nlc3NlZEtleXM/Llt0YWJsZU5hbWVdPy5LZXlzO1xuICAgICAgfVxuICAgICAgaWYgKGtleXM/Lmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYER5bmFtb0RCIGxlZnQgJHtrZXlzLmxlbmd0aH0gdGFnIG1hcmtlcnMgdW5yZWFkIGFmdGVyIHJldHJ5aW5nYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hcmtlcnM7XG4gIH1cbn1cblxuLyoqXG4gKiBIb3cgbG9uZyBhIHJldmFsaWRhdGlvbiBsb2cgcm93IGlzIGtlcHQgKGB0dGxgLCBlcG9jaCBzZWNvbmRzKS4gRHluYW1vREIgbmV2ZXJcbiAqIGRlbGV0ZXMgYW4gaXRlbSBiZWZvcmUgaXRzIFRUTCwgb25seSBzb21lIHRpbWUgYWZ0ZXIsIHNvIGEgcmVhZGVyIHRoYXQgbGFzdFxuICogcXVlcmllZCBsZXNzIHRoYW4gdGhpcyBsb25nIGFnbyAobGVzcyBhIG1hcmdpbiBmb3Igd3JpdGVycycgY2xvY2tzKSBpcyBzdXJlXG4gKiB0byBmaW5kIGV2ZXJ5IHJvdyBpdCBoYXMgbm90IHNlZW4geWV0LlxuICovXG5leHBvcnQgY29uc3QgUkVWQUxJREFUSU9OX0xPR19UVExfTVMgPSAxNSAqIDYwICogMTAwMDtcblxuLyoqIFRoZSBtb3N0IGBRdWVyeWAgcGFnZXMgb25lIHtAbGluayBSZXZhbGlkYXRpb25Mb2cucXVlcnl9IHJlYWRzLiAqL1xuZXhwb3J0IGNvbnN0IFJFVkFMSURBVElPTl9MT0dfTUFYX1BBR0VTID0gNTtcblxuLyoqIEhvdyBtYW55IHNvcnQga2V5cyB7QGxpbmsgUmV2YWxpZGF0aW9uTG9nLnB1dH0gdHJpZXMgYmVmb3JlIGdpdmluZyB1cC4gKi9cbmNvbnN0IExPR19QVVRfQVRURU1QVFMgPSA1O1xuXG4vKiogRGlnaXRzIGEgbG9nIHJvdydzIHRpbWVzdGFtcCBpcyB6ZXJvLXBhZGRlZCB0bywgc28gc29ydCBrZXlzIHNvcnQgYnkgdGltZS4gKi9cbmNvbnN0IExPR19TS19ESUdJVFMgPSAxNTtcblxuLyoqIEEgcmV2YWxpZGF0aW9uIHJlYWQgYmFjayBmcm9tIHRoZSBsb2cuICovXG5leHBvcnQgaW50ZXJmYWNlIFJldmFsaWRhdGlvbkxvZ1JvdyB7XG4gIC8qKiBUaGUgcm93J3Mgc29ydCBrZXk6IHVuaXF1ZSBwZXIgcmV2YWxpZGF0aW9uIG9mIGEgdGFnLiAqL1xuICBzazogc3RyaW5nO1xuICAvKiogV2hlbiBpdCB3YXMgd3JpdHRlbiwgb24gdGhlIHdyaXRlcidzIGBEYXRlLm5vdygpYC4gKi9cbiAgYXQ6IG51bWJlcjtcbiAgdGFnOiBzdHJpbmc7XG4gIC8qKiBUaGUgbWFya2VyIGZpZWxkcyB0aGUgcmV2YWxpZGF0aW9uIHNldCwgYXMge0BsaW5rIG1hcmtlckZvcn0gcmV0dXJucyB0aGVtLiAqL1xuICBtYXJrZXI6IFRhZ01hcmtlcjtcbn1cblxuLyoqXG4gKiBUaGUgcmV2YWxpZGF0aW9uIGxvZzogb25lIHJvdyBwZXIgdGFnIHJldmFsaWRhdGlvbiAoYHBrID0gPGJ1aWxkSWQ+I2xvZ2AsXG4gKiBgc2sgPSA8RGF0ZS5ub3coKSwgemVyby1wYWRkZWQ+Izx0YWc+YCksIHdoaWNoIGV4cGlyZXMgYWZ0ZXJcbiAqIHtAbGluayBSRVZBTElEQVRJT05fTE9HX1RUTF9NU30uIEEgdGFnIHBhc3Qge0BsaW5rIE1BWF9UQUdfQllURVN9IGlzXG4gKiB7QGxpbmsgaGFzaGVkVGFnfSB0aGVyZSwgYW5kIHNwZWxsZWQgb3V0IGluIHRoZSByb3cncyBgbG9uZ1RhZ2AgaW5zdGVhZC5cbiAqXG4gKiBUaGUgbWFya2VyIHJvd3Mgc3RheSB0aGUgc291cmNlIG9mIHRydXRoLiBUaGUgbG9nIGV4aXN0cyBzbyBhbiBpbnN0YW5jZVxuICogY2FuIGFzayBcIndoYXQgd2FzIHJldmFsaWRhdGVkIHNpbmNlIEkgbGFzdCBsb29rZWQ/XCIgaW4gb25lIGBRdWVyeWAsIGluc3RlYWRcbiAqIG9mIHJlLXJlYWRpbmcgZXZlcnkgdGFnIGl0IHRyYWNrcyB0byBmaW5kIG91dCB0aGF0IGFsbW9zdCBub25lIGNoYW5nZWQuIEV2ZXJ5XG4gKiBtYXJrZXIgcm93IG9mIGEgZGVwbG95bWVudCBzaGFyZXMgb25lIHBhcnRpdGlvbiwgYW5kIHRob3NlIHJlLXJlYWRzIGZyb20gYVxuICogaGFuZGZ1bCBvZiBidXN5IGluc3RhbmNlcyB3ZXJlIGVub3VnaCB0byB0aHJvdHRsZSBpdC5cbiAqXG4gKiBUaGUgc29ydCBrZXkncyB0aW1lc3RhbXAgaXMgdGhlIHdyaXRlcidzIHdhbGwgY2xvY2sgKGBEYXRlLm5vdygpYCksIG5vdCB0aGVcbiAqIHBlcmZvcm1hbmNlIGNsb2NrICh7QGxpbmsgbWFya2VyQ2xvY2t9KSB0aGUgbWFya2VyIHZhbHVlcyBhcmUgc3RhbXBlZCB3aXRoIGJ5IGJvdGhcbiAqIGhhbmRsZXJzOiBpdCBvbmx5IG9yZGVycyByb3dzIGZvciByZWFkZXJzJyBjdXJzb3JzLCB3aGljaCBhcmUgb24gdGhlaXIgb3duXG4gKiB3YWxsIGNsb2NrcywgYW5kIGlzIG5ldmVyIGNvbXBhcmVkIHdpdGggYW4gZW50cnkncyB0aW1lc3RhbXAuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXZhbGlkYXRpb25Mb2cge1xuICBwcml2YXRlIHJlYWRvbmx5IHBrOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IER5bmFtb0RCQ2xpZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgYnVpbGRJZDogc3RyaW5nLFxuICApIHtcbiAgICB0aGlzLnBrID0gYCR7YnVpbGRJZH0jbG9nYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgdGhhdCBgdGFnYCB3YXMgcmV2YWxpZGF0ZWQgYXQgYGF0YCAoYERhdGUubm93KClgKSwgc2V0dGluZyBgbWFya2VyYC5cbiAgICpcbiAgICogVHdvIHJldmFsaWRhdGlvbnMgb2YgYHRhZ2AgaW4gdGhlIHNhbWUgbWlsbGlzZWNvbmQgd291bGQgc2hhcmUgYSBzb3J0IGtleSxcbiAgICogYW5kIHRoZSBzZWNvbmQgd291bGQgb3ZlcndyaXRlIHRoZSBmaXJzdC4gU28gdGhlIHJvdyBpcyBvbmx5IHdyaXR0ZW4gd2hlcmVcbiAgICogaXRzIGtleSBpcyBmcmVlLCBhbmQgb24gYSBjb2xsaXNpb24gaXQgbW92ZXMgdG8gdGhlIG5leHQgbWlsbGlzZWNvbmQsIHVwXG4gICAqIHRvIHtAbGluayBMT0dfUFVUX0FUVEVNUFRTfSB0aW1lcy5cbiAgICovXG4gIGFzeW5jIHB1dCh0YWc6IHN0cmluZywgYXQ6IG51bWJlciwgbWFya2VyOiBUYWdNYXJrZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBza1RhZyA9IHNvcnRLZXlUYWcodGFnKTtcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgOyBhdHRlbXB0KyspIHtcbiAgICAgIGNvbnN0IGl0ZW06IFJlY29yZDxzdHJpbmcsIEF0dHJpYnV0ZVZhbHVlPiA9IHtcbiAgICAgICAgcGs6IHsgUzogdGhpcy5wayB9LFxuICAgICAgICBzazogeyBTOiBgJHtsb2dTa1ByZWZpeChhdCl9IyR7c2tUYWd9YCB9LFxuICAgICAgICB0dGw6IHsgTjogU3RyaW5nKE1hdGguY2VpbCgoYXQgKyBSRVZBTElEQVRJT05fTE9HX1RUTF9NUykgLyAxMDAwKSkgfSxcbiAgICAgICAgLi4uKHNrVGFnICE9PSB0YWcgJiYgeyBsb25nVGFnOiB7IFM6IHRhZyB9IH0pLFxuICAgICAgfTtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgTUFSS0VSX0ZJRUxEUykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG1hcmtlcltmaWVsZF07XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaXRlbVtmaWVsZF0gPSB7IE46IFN0cmluZyh2YWx1ZSkgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgICBuZXcgUHV0SXRlbUNvbW1hbmQoe1xuICAgICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICAgIEl0ZW06IGl0ZW0sXG4gICAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiBcImF0dHJpYnV0ZV9ub3RfZXhpc3RzKHNrKVwiLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKGVycm9yIGFzIEVycm9yIHwgdW5kZWZpbmVkKT8ubmFtZSAhPT1cbiAgICAgICAgICAgIFwiQ29uZGl0aW9uYWxDaGVja0ZhaWxlZEV4Y2VwdGlvblwiIHx8XG4gICAgICAgICAgYXR0ZW1wdCA+PSBMT0dfUFVUX0FUVEVNUFRTXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGF0ID0gTWF0aC5mbG9vcihhdCkgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcm93cyB3cml0dGVuIGF0IG9yIGFmdGVyIGBzaW5jZWAgKGBEYXRlLm5vdygpYCksIG9sZGVzdCBmaXJzdC5cbiAgICogYHRydW5jYXRlZGAgd2hlbiB0aGVyZSB3ZXJlIG1vcmUgdGhhbiB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19NQVhfUEFHRVN9XG4gICAqIHBhZ2VzIG9mIHRoZW0sIGFuZCBgcm93c2AgaXMgb25seSB0aGUgc3RhcnQuXG4gICAqXG4gICAqIEV2ZW50dWFsbHkgY29uc2lzdGVudDogYSByb3cgd3JpdHRlbiBhIG1vbWVudCBhZ28gbWF5IG5vdCBzaG93IHlldCwgd2hpY2hcbiAgICogaXMgd2hhdCB0aGUgcmVhZGVyJ3MgbG9va2JhY2sgaXMgZm9yLlxuICAgKi9cbiAgYXN5bmMgcXVlcnkoXG4gICAgc2luY2U6IG51bWJlcixcbiAgKTogUHJvbWlzZTx7IHJvd3M6IFJldmFsaWRhdGlvbkxvZ1Jvd1tdOyB0cnVuY2F0ZWQ6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IHJvd3M6IFJldmFsaWRhdGlvbkxvZ1Jvd1tdID0gW107XG4gICAgbGV0IHN0YXJ0S2V5OiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4gfCB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgcGFnZSA9IDA7IHBhZ2UgPCBSRVZBTElEQVRJT05fTE9HX01BWF9QQUdFUzsgcGFnZSsrKSB7XG4gICAgICBjb25zdCByZXNwb25zZTogUXVlcnlDb21tYW5kT3V0cHV0ID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgbmV3IFF1ZXJ5Q29tbWFuZCh7XG4gICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICBLZXlDb25kaXRpb25FeHByZXNzaW9uOiBcInBrID0gOnBrIEFORCBzayA+PSA6c2luY2VcIixcbiAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiB7XG4gICAgICAgICAgICBcIjpwa1wiOiB7IFM6IHRoaXMucGsgfSxcbiAgICAgICAgICAgIFwiOnNpbmNlXCI6IHsgUzogbG9nU2tQcmVmaXgoTWF0aC5tYXgoMCwgc2luY2UpKSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246XG4gICAgICAgICAgICBcInNrLCBsb25nVGFnLCByZXZhbGlkYXRlZEF0LCBzdGFsZUF0LCBleHBpcmVkQXRcIixcbiAgICAgICAgICBFeGNsdXNpdmVTdGFydEtleTogc3RhcnRLZXksXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiByZXNwb25zZS5JdGVtcyA/PyBbXSkge1xuICAgICAgICBjb25zdCBzayA9IGl0ZW0uc2s/LlM7XG4gICAgICAgIC8vIGA8ZGlnaXRzPiM8dGFnPmA6IHRoZSB0YWcgaXMgZXZlcnl0aGluZyBhZnRlciB0aGUgZml4ZWQtd2lkdGhcbiAgICAgICAgLy8gdGltZXN0YW1wLCBgI2BzIGluY2x1ZGVkLlxuICAgICAgICBpZiAoc2sgPT09IHVuZGVmaW5lZCB8fCBza1tMT0dfU0tfRElHSVRTXSAhPT0gXCIjXCIpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICByb3dzLnB1c2goe1xuICAgICAgICAgIHNrLFxuICAgICAgICAgIGF0OiBOdW1iZXIoc2suc2xpY2UoMCwgTE9HX1NLX0RJR0lUUykpLFxuICAgICAgICAgIHRhZzogaXRlbS5sb25nVGFnPy5TID8/IHNrLnNsaWNlKExPR19TS19ESUdJVFMgKyAxKSxcbiAgICAgICAgICBtYXJrZXI6IG1hcmtlck9mKGl0ZW0pLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0S2V5ID0gcmVzcG9uc2UuTGFzdEV2YWx1YXRlZEtleTtcbiAgICAgIGlmICghc3RhcnRLZXkpIHtcbiAgICAgICAgcmV0dXJuIHsgcm93cywgdHJ1bmNhdGVkOiBmYWxzZSB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyByb3dzLCB0cnVuY2F0ZWQ6IHRydWUgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBsb2dTa1ByZWZpeChhdDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIFN0cmluZyhNYXRoLmZsb29yKGF0KSkucGFkU3RhcnQoTE9HX1NLX0RJR0lUUywgXCIwXCIpO1xufVxuXG4vKipcbiAqIEhvdyBmYXIgYmVoaW5kIHRoZSBsYXN0IHF1ZXJ5J3Mgc3RhcnQgdGhlIG5leHQgb25lIHN0YXJ0cyByZWFkaW5nIHRoZSBsb2c6XG4gKiB0aGUgcm9vbSBmb3IgdGhlIGBRdWVyeWAgYmVpbmcgZXZlbnR1YWxseSBjb25zaXN0ZW50IGFuZCBmb3Igd3JpdGVycycgY2xvY2tzXG4gKiBydW5uaW5nIGJlaGluZCB0aGUgcmVhZGVyJ3MuIFJvd3MgaW5zaWRlIGl0IGFyZSByZWFkIGFnYWluLCBhbmQgZHJvcHBlZCBhc1xuICogYWxyZWFkeSBhcHBsaWVkLlxuICovXG5leHBvcnQgY29uc3QgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUyA9IDUwMDA7XG5cbi8qKlxuICogVGhlIGxvbmdlc3Qge0BsaW5rIFRyYWNrZWRUYWdNYXJrZXJzfSB0cnVzdHMgdGhlIGxvZyBhbG9uZSBmb3IgYSB0YWcgYmVmb3JlXG4gKiByZWFkaW5nIGl0cyBtYXJrZXIgcm93IGFnYWluLiBUaGUgbG9nIGlzIHRoZSBmYXN0IHBhdGgsIGJ1dCB0aGUgbWFya2VyIHJvd3NcbiAqIGFyZSB0aGUgc291cmNlIG9mIHRydXRoOiBhIGxvZyByb3cgd2hvc2Ugd3JpdGUgZmFpbGVkIHdvdWxkIG90aGVyd2lzZSBiZVxuICogbWlzc2VkIGZvciBhcyBsb25nIGFzIHRoZSB0YWcgc3RheXMgdHJhY2tlZC5cbiAqXG4gKiBSb2xsaW5nLCBub3QgYWxsIGF0IG9uY2U6IGVhY2ggcmVmcmVzaCByZS1yZWFkcyBhdCBtb3N0XG4gKiB7QGxpbmsgQkFUQ0hfR0VUX01BWF9LRVlTfSBvZiB0aGUgdGFncyBkdWUsIG9sZGVzdCBmaXJzdC4gUmUtcmVhZGluZyB0aGVtIGFsbFxuICogdG9nZXRoZXIgY29zdCB+NTAwIFJDVSBhdCAxMDAwIHRhZ3MgLSBhIGZsZWV0IHN0YXJ0ZWQgYnkgb25lIGxvYWQgdGVzdCBkaWQgaXRcbiAqIGluIHRoZSBzYW1lIG1pbnV0ZSwgMTIsODAwIFJDVSwgYW5kIHRocm90dGxlZCAtIGFuZCB3b3VsZCBiZSB+NSwwMDAgUkNVIGF0XG4gKiB7QGxpbmsgREVGQVVMVF9NQVhfVFJBQ0tFRF9UQUdTfSwgcGFzdCB3aGF0IHRoZSBvbmUgcGFydGl0aW9uIHNlcnZlcyBpbiBhXG4gKiBzZWNvbmQuIFNwcmVhZCBvdXQsIDEwLDAwMCB0cmFja2VkIHRhZ3MgY29zdCB+OCBSQ1UgYSBzZWNvbmQgcGVyIGluc3RhbmNlLlxuICpcbiAqIEVhY2ggdGFnIGlzIGR1ZSBhdCBhIHJhbmRvbSA3NS0xMDAlIG9mIHRoaXMgYWZ0ZXIgaXQgd2FzIGxhc3QgcmVhZCwgc28gdGFnc1xuICogZmlyc3QgcmVhZCB0b2dldGhlciAtIGFuIGluc3RhbmNlIHdhcm1pbmcgdXAgLSBkbyBub3QgYWxsIGNvbWUgZHVlIHRvZ2V0aGVyXG4gKiBhZ2FpbiBldmVyeSBpbnRlcnZhbDogdGhlIGxvYWQgdGVzdCB0aGF0IG1lYXN1cmVkIHRoZSByb2xsaW5nIHJlLXJlYWQgc2F3XG4gKiBpdHMgd2FybS11cCdzIHJlYWRzIHJldHVybiBhcyBhIDMwLTM2IFJDVS9zIGJ1bXAgdGVuIG1pbnV0ZXMgbGF0ZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX1RBR19SRVNZTkNfTVMgPSAxMCAqIDYwICogMTAwMDtcblxuLyoqIFRoZSBmcmFjdGlvbiBvZiB7QGxpbmsgREVGQVVMVF9UQUdfUkVTWU5DX01TfSBhIHRhZyBtYXkgY29tZSBkdWUgZWFybHkgYnkuICovXG5jb25zdCBUQUdfUkVTWU5DX0pJVFRFUiA9IDAuMjU7XG5cbi8qKlxuICogSG93IGxvbmcgc2luY2UgdGhlIGxhc3Qgc3VjY2Vzc2Z1bCBsb2cgcXVlcnkgdGhlIGxvZyBjYW4gc3RpbGwgYmUgdHJ1c3RlZCB0b1xuICogaG9sZCBldmVyeSByb3cgbm90IHJlYWQgeWV0OiBpdHMgVFRMIGxlc3MgYSBtYXJnaW4gZm9yIHdyaXRlcnMnIGNsb2Nrcy4gUGFzdFxuICogaXQgLSBhIExhbWJkYSBmcm96ZW4gYmV0d2VlbiBpbnZvY2F0aW9ucywgYSBydW4gb2YgZmFpbGVkIHF1ZXJpZXMgLSB0aGVcbiAqIHRyYWNrZWQgbWFya2VycyBhcmUgZm9yZ290dGVuLCB0byBiZSByZWFkIGFnYWluIGFzIHRoZXkgYXJlIG5lZWRlZCwgYW5kIHRoZVxuICogbG9nIGlzIGZvbGxvd2VkIGZyb20gdGhlcmUuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfUkVWQUxJREFUSU9OX0xPR19HQVBfTVMgPVxuICBSRVZBTElEQVRJT05fTE9HX1RUTF9NUyAtIDUgKiA2MCAqIDEwMDA7XG5cbi8qKlxuICogVGhlIG1vc3QgdGFncyBvbmUgaW5zdGFuY2UgdHJhY2tzLiBQYXN0IGl0IHRoZSBsZWFzdCByZWNlbnRseSB1c2VkIGlzXG4gKiBmb3Jnb3R0ZW4sIHdoaWNoIGNvc3RzIGEgcmVhZCB0aGUgbmV4dCB0aW1lIGl0IGlzIG5lZWRlZDogYW4gdW50cmFja2VkIHRhZ1xuICogaXMgcmVhZCBiZWZvcmUgaXQgaXMgdHJ1c3RlZC5cbiAqXG4gKiBBIHRyYWNrZWQgdGFnIGNvc3RzIG1lbW9yeSAofjIgTUIgYXQgdGhpcyBib3VuZCkgYW5kIGl0cyBzaGFyZSBvZiB0aGUgcm9sbGluZ1xuICogcmUtcmVhZCwgbm90IGEgcmVhZCBldmVyeSByZWZyZXNoLCBzbyB0aGUgYm91bmQgaXMgc2V0IGJ5IGhvdyBtYW55IHRhZ3MgYW5cbiAqIGluc3RhbmNlIHJlYWxseSB1c2VzLiBFdmVyeSBwYXRoIGlzIGEgdGFnIG9mIGl0cyBvd24gKGBfTl9UXy88cGF0aD5gKSwgYW5kIGF0XG4gKiAxMDAwIGFuIGFwcCBvZiAxMDAwIHRhZ2dlZCBwYWdlcyBrZXB0IGV2aWN0aW5nIHdoYXQgaXQgd2FzIGFib3V0IHRvIG5lZWQ6XG4gKiBoYWxmIGl0cyByZXF1ZXN0cyByZS1yZWFkIGEgbWFya2VyLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9NQVhfVFJBQ0tFRF9UQUdTID0gMTBfMDAwO1xuXG4vKipcbiAqIFRoZSByZXZhbGlkYXRpb24gdGFibGUncyBtYXJrZXIgcm93cyBhbmQgaXRzIGxvZywgd2hpY2ggYXJlIG9ubHkgZXZlciB1c2VkXG4gKiB0b2dldGhlciwgb3IgbmVpdGhlciBmb3IgdGFncyBsb2NhbCB0byB0aGlzIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCB0eXBlIFRhZ1RhYmxlID1cbiAgfCB7IG1hcmtlcnM6IFRhZ01hcmtlclRhYmxlOyBsb2c6IFJldmFsaWRhdGlvbkxvZyB9XG4gIHwgeyBtYXJrZXJzPzogdW5kZWZpbmVkOyBsb2c/OiB1bmRlZmluZWQgfTtcblxuLyoqIEhvdyB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnN9IGlzIGJ1aWx0LiAqL1xuZXhwb3J0IHR5cGUgVHJhY2tlZFRhZ01hcmtlcnNPcHRpb25zID0gVGFnVGFibGUgJiB7XG4gIC8qKlxuICAgKiBIb3cgb2Z0ZW4sIGF0IG1vc3QsIHtAbGluayBUcmFja2VkVGFnTWFya2Vycy5yZWZyZXNofSByZWFkcyBhbnl0aGluZy5cbiAgICogQGRlZmF1bHQgREVGQVVMVF9UQUdfUkVGUkVTSF9NU1xuICAgKi9cbiAgcmVmcmVzaEludGVydmFsTXM/OiBudW1iZXI7XG4gIG1heFRyYWNrZWRUYWdzPzogbnVtYmVyO1xuICAvKiogQHNlZSBERUZBVUxUX1RBR19SRVNZTkNfTVMgKi9cbiAgcmVzeW5jSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqIFRoZSB3YWxsIGNsb2NrIHRoZSBsb2cncyBjdXJzb3IgYW5kIHRoZSBpbnRlcnZhbHMgYXJlIGtlcHQgb24uICovXG4gIGNsb2NrPzogKCkgPT4gbnVtYmVyO1xuICAvKiogYE1hdGgucmFuZG9tYCwgZm9yIHdoZW4gZWFjaCB0YWcncyByZS1yZWFkIGNvbWVzIGR1ZS4gKi9cbiAgcmFuZG9tPzogKCkgPT4gbnVtYmVyO1xuICBkZWJ1Zz86IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQ7XG59O1xuXG4vKipcbiAqIE9uZSBpbnN0YW5jZSdzIGNvcHkgb2YgdGhlIG1hcmtlciByb3dzIG9mIHRoZSB0YWdzIGl0IGhhcyBuZWVkZWQsIGtlcHRcbiAqIGN1cnJlbnQgdGhyb3VnaCB0aGUge0BsaW5rIFJldmFsaWRhdGlvbkxvZ306IHRoZSBwcm9jZXNzJ3Mgb25lIHRhZyBtYW5pZmVzdFxuICogKGBzaGFyZWRUYWdNYW5pZmVzdGApLCBmb3IgdGhlIGAndXNlIGNhY2hlJ2AgaGFuZGxlcnMgYW5kIHRoZSBpbmNyZW1lbnRhbFxuICogY2FjaGUgYWxpa2UuXG4gKlxuICogTmV4dC5qcydzIGJ1aWx0LWluIGAndXNlIGNhY2hlJ2AgaGFuZGxlciBrZWVwcyB0YWdzIGluIGEgbW9kdWxlLWxldmVsIG1hcFxuICogKGB0YWdzLW1hbmlmZXN0LmV4dGVybmFsLmpzYCkgdGhhdCBvbmx5IGl0cyBvd24gYHVwZGF0ZVRhZ3NgIHdyaXRlcywgYW5kIGl0c1xuICogYHJlZnJlc2hUYWdzYCBpcyBhIG5vLW9wLCBzbyBhIGByZXZhbGlkYXRlVGFnYCBvbiBvbmUgaW5zdGFuY2UgbmV2ZXIgcmVhY2hlc1xuICogdGhlIG90aGVyczogdGhleSBrZWVwIHNlcnZpbmcgdGhlIHJldmFsaWRhdGVkIGVudHJ5LCBpbmNsdWRpbmcgaW5zaWRlIHBhZ2VzXG4gKiB0aGF0IGFyZSBiZWluZyByZS1yZW5kZXJlZCAqYmVjYXVzZSogb2YgdGhhdCByZXZhbGlkYXRpb24uIFRoZVxuICogYGNhY2hlSGFuZGxlcnNgIGludGVyZmFjZSdzIGFuc3dlciBpcyBgcmVmcmVzaFRhZ3NgLCBcImNhbGxlZCBiZWZvcmUgc3RhcnRpbmdcbiAqIGEgbmV3IHJlcXVlc3Qg4oCmIHRvIHJlZnJlc2ggdGhlIGxvY2FsIHRhZ3MgbWFuaWZlc3RcIiwgYW5kIHRoaXMgaXMgdGhhdFxuICogbWFuaWZlc3QsIGJhY2tlZCBieSB0aGUgc2FtZSBtYXJrZXIgcm93cyB0aGUgaW5jcmVtZW50YWwgY2FjaGUnc1xuICogYHJldmFsaWRhdGVUYWdgIHdyaXRlcyAoYHBrID0gYnVpbGRJZGAsIGBzayA9IHRhZ2ApLlxuICpcbiAqIFRoZSBjb3N0IGlzIGJvdW5kZWQgcGVyIGluc3RhbmNlLCBub3QgcGVyIHJlcXVlc3Q6XG4gKiAtIHtAbGluayBlbnN1cmV9IHJlYWRzIGEgdGFnJ3MgbWFya2VyIHRoZSBmaXJzdCB0aW1lIGl0IGlzIG5lZWRlZCBhbmQgbm90XG4gKiAgIGFnYWluIHVudGlsIGl0IGlzIGV2aWN0ZWQsIHNvIGEgdGFnIGNvc3RzIG9uZSByZWFkIHBlciBpbnN0YW5jZSwgbm90IG9uZVxuICogICBwZXIgcmVxdWVzdC5cbiAqIC0ge0BsaW5rIHJlZnJlc2h9LCBhdCBtb3N0IG9uY2UgcGVyIGByZWZyZXNoSW50ZXJ2YWxNc2AsIHNlbmRzIG9uZSBgUXVlcnlgXG4gKiAgIGZvciB0aGUgbG9nIHJvd3Mgd3JpdHRlbiBzaW5jZSB0aGUgbGFzdCBvbmUsIGFuZCBhcHBsaWVzIHRob3NlIG9mIHRhZ3NcbiAqICAgdGhpcyBpbnN0YW5jZSB0cmFja3MuIENvbmN1cnJlbnQgY2FsbGVycyBzaGFyZSBpdC4gQWxvbmdzaWRlLCBpdCByZS1yZWFkc1xuICogICB0aGUgbWFya2VycyBvZiB1cCB0byB7QGxpbmsgQkFUQ0hfR0VUX01BWF9LRVlTfSB0YWdzIG5vdCByZWFkIGZvclxuICogICB7QGxpbmsgREVGQVVMVF9UQUdfUkVTWU5DX01TfSwgaW4gb25lIGBCYXRjaEdldEl0ZW1gLlxuICogQSByZXZhbGlkYXRpb24gb24gYW5vdGhlciBpbnN0YW5jZSBpcyB0aGVyZWZvcmUgc2VlbiB3aXRoaW5cbiAqIGByZWZyZXNoSW50ZXJ2YWxNc2AgKHBsdXMgdGhlIHF1ZXJ5IGl0c2VsZikuIFRoZSBpbnN0YW5jZSB0aGF0IHJhbiBpdCBhcHBsaWVzXG4gKiBpdCBpdHNlbGYsIGF0IG9uY2UsIHdpdGgge0BsaW5rIHNldH0uXG4gKi9cbmV4cG9ydCBjbGFzcyBUcmFja2VkVGFnTWFya2VycyB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWFya2VyczogVGFnTWFya2VyVGFibGUgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgbG9nOiBSZXZhbGlkYXRpb25Mb2cgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVmcmVzaEludGVydmFsTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBtYXhUcmFja2VkVGFnczogbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlc3luY0ludGVydmFsTXM6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBjbG9jazogKCkgPT4gbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHJhbmRvbTogKCkgPT4gbnVtYmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IGRlYnVnOiAobWVzc2FnZTogc3RyaW5nKSA9PiB2b2lkO1xuICAvKiogQnkgdGFnLCBsZWFzdCByZWNlbnRseSB1c2VkIGZpcnN0LiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHRhZ3MgPSBuZXcgTWFwPHN0cmluZywgVGFnTWFya2VyPigpO1xuICAvKipcbiAgICogV2hlbiBlYWNoIHRyYWNrZWQgdGFnJ3MgbWFya2VyIGlzIGR1ZSB0byBiZSByZWFkIGFnYWluOiBhIHJhbmRvbSA3NS0xMDAlXG4gICAqIG9mIGByZXN5bmNJbnRlcnZhbE1zYCBhZnRlciBpdCB3YXMgbGFzdCBrbm93biBmcm9tIHRoZSB0YWJsZSAtIHJlYWQsXG4gICAqIHdyaXR0ZW4gaGVyZSwgb3IgbmV3LiBJbiB0aGUgb3JkZXIgdGhleSBiZWNhbWUga25vd24sIGxlYXN0IHJlY2VudCBmaXJzdC5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgZHVlQXQgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlYWRpbmcgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx2b2lkPj4oKTtcbiAgLyoqXG4gICAqIExvZyByb3dzIGZvciB0YWdzIHdob3NlIGZpcnN0IHJlYWQgaXMgaW4gZmxpZ2h0LCBtZXJnZWQgYnkgdGFnOiB0aGUgcmVhZFxuICAgKiBtYXkgaGF2ZSBiZWVuIGFuc3dlcmVkIGJlZm9yZSB0aGUgcmV2YWxpZGF0aW9uLCBzbyB0aGV5IGFyZSBhcHBsaWVkIHRvIGl0c1xuICAgKiByZXN1bHQgcmF0aGVyIHRoYW4gZHJvcHBlZC5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcGVuZGluZ1Jvd3MgPSBuZXcgTWFwPHN0cmluZywgVGFnTWFya2VyPigpO1xuICAvKiogVHJhY2tlZCB0YWdzIHdob3NlIHJlYWQgZmFpbGVkLCBmb3IgdGhlIG5leHQgcmVmcmVzaCB0byByZWFkIGFnYWluLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHVucmVhZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICBwcml2YXRlIGxhc3RSZWZyZXNoID0gLUluZmluaXR5O1xuICBwcml2YXRlIHJlZnJlc2hpbmc6IFByb21pc2U8dm9pZD4gfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBXaGVyZSB0aGUgbmV4dCBsb2cgcXVlcnkgc3RhcnRzIChgY2xvY2soKWApOiB0aGUgbGFzdCBzdWNjZXNzZnVsIG9uZSdzXG4gICAqIHN0YXJ0LCBsZXNzIHtAbGluayBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TfS5cbiAgICovXG4gIHByaXZhdGUgY3Vyc29yOiBudW1iZXI7XG4gIC8qKiBXaGVuIHRoZSBsYXN0IHN1Y2Nlc3NmdWwgbG9nIHF1ZXJ5IHN0YXJ0ZWQsIG9yIHRoZSBsb2cgd2FzIGZpcnN0IHJlYWQuICovXG4gIHByaXZhdGUgbGFzdExvZ1JlYWQ6IG51bWJlcjtcbiAgLyoqIExvZyByb3dzIGF0IG9yIGFmdGVyIHRoZSBjdXJzb3IgYWxyZWFkeSBhcHBsaWVkLCBieSBzb3J0IGtleS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBhcHBsaWVkID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgLyoqIHtAbGluayB1cGRhdGV9cyBvZiB0aGUgY3VycmVudCB0dXJuLCBieSB0aGVpciBhcmd1bWVudHMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdXBkYXRpbmcgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxib29sZWFuPj4oKTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBUcmFja2VkVGFnTWFya2Vyc09wdGlvbnMpIHtcbiAgICB0aGlzLm1hcmtlcnMgPSBvcHRpb25zLm1hcmtlcnM7XG4gICAgdGhpcy5sb2cgPSBvcHRpb25zLmxvZztcbiAgICB0aGlzLnJlZnJlc2hJbnRlcnZhbE1zID1cbiAgICAgIG9wdGlvbnMucmVmcmVzaEludGVydmFsTXMgPz8gREVGQVVMVF9UQUdfUkVGUkVTSF9NUztcbiAgICB0aGlzLm1heFRyYWNrZWRUYWdzID0gb3B0aW9ucy5tYXhUcmFja2VkVGFncyA/PyBERUZBVUxUX01BWF9UUkFDS0VEX1RBR1M7XG4gICAgdGhpcy5yZXN5bmNJbnRlcnZhbE1zID0gb3B0aW9ucy5yZXN5bmNJbnRlcnZhbE1zID8/IERFRkFVTFRfVEFHX1JFU1lOQ19NUztcbiAgICAvLyBMb29rZWQgdXAgb24gZWFjaCBjYWxsIHJhdGhlciB0aGFuIGJvdW5kIGhlcmUsIHNvIGEgdGVzdCdzIGBEYXRlLm5vd2BcbiAgICAvLyBzcHkgYXBwbGllcy5cbiAgICB0aGlzLmNsb2NrID0gb3B0aW9ucy5jbG9jayA/PyAoKCkgPT4gRGF0ZS5ub3coKSk7XG4gICAgdGhpcy5yYW5kb20gPSBvcHRpb25zLnJhbmRvbSA/PyBNYXRoLnJhbmRvbTtcbiAgICB0aGlzLmRlYnVnID0gb3B0aW9ucy5kZWJ1ZyA/PyAoKCkgPT4ge30pO1xuICAgIC8vIE5vdGhpbmcgaXMgdHJhY2tlZCB5ZXQsIHNvIG5vdGhpbmcgYmVmb3JlIHRoaXMgY2FuIGJlIG1pc3NlZDogZXZlcnkgdGFnXG4gICAgLy8gaXMgcmVhZCBmcm9tIGl0cyBtYXJrZXIgdGhlIGZpcnN0IHRpbWUgaXQgaXMgbmVlZGVkLlxuICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgIHRoaXMuY3Vyc29yID0gYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TO1xuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgfVxuXG4gIC8qKiBgdGFnYCdzIG1hcmtlciBhcyB0aGlzIGluc3RhbmNlIGtub3dzIGl0LCBpZiBpdCB0cmFja3MgYHRhZ2AuICovXG4gIGdldCh0YWc6IHN0cmluZyk6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMudGFncy5nZXQodGFnKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBgdGFnYCB3aXRoIGBtYXJrZXJgOiB3aGF0IHRoaXMgaW5zdGFuY2UganVzdCB3cm90ZSwgd2hpY2ggaXQga25vd3NcbiAgICogd2l0aG91dCByZWFkaW5nIGl0IGJhY2suXG4gICAqL1xuICBzZXQodGFnOiBzdHJpbmcsIG1hcmtlcjogVGFnTWFya2VyKTogdm9pZCB7XG4gICAgdGhpcy5yZW1lbWJlcih0YWcsIG1hcmtlcik7XG4gICAgdGhpcy5rbm93bih0YWcsIHRoaXMuY2xvY2soKSk7XG4gIH1cblxuICAvKipcbiAgICogTm90ZSBhIHVzZSBvZiBgdGFnc2A6IHRob3NlIG9mIGFuIGVudHJ5IHRoaXMgaW5zdGFuY2UganVzdCBzdG9yZWQuXG4gICAqXG4gICAqIFdpdGggdGhlIHRhYmxlLCBhIHRhZyBub3QgdHJhY2tlZCB5ZXQgaXMgbGVmdCB1bnRyYWNrZWQsIHRvIGJlIHJlYWQgYnlcbiAgICoge0BsaW5rIGVuc3VyZX0gdGhlIGZpcnN0IHRpbWUgYW4gZW50cnkgbmVlZHMgaXQuIE5vdGhpbmcgcmV2YWxpZGF0ZWQgYmVmb3JlXG4gICAqIHRoZSBuZXcgZW50cnkgd2FzIGNyZWF0ZWQgYXBwbGllcyB0byAqaXQqLCBidXQgdHJhY2tpbmcgaXMgcGVyIHRhZywgbm90IHBlclxuICAgKiBlbnRyeTogdHJhY2tpbmcgdGhlIHRhZyB3aXRoIGFuIGVtcHR5IG1hcmtlciB3b3VsZCBhbHNvIHZvdWNoIGZvciBldmVyeVxuICAgKiBvbGRlciBlbnRyeSB0aGF0IGNhcnJpZXMgaXQgLSBvbmUgYW5vdGhlciBpbnN0YW5jZSBzdG9yZWQgaW4gUzMsIG9yIG9uZVxuICAgKiB0aGlzIGluc3RhbmNlIGtlcHQgaW4gbWVtb3J5IGFjcm9zcyBhIHtAbGluayBmb3JnZXR9IC0gYW5kIGEgcmV2YWxpZGF0aW9uXG4gICAqIGZyb20gYmVmb3JlIHRoZSBsb2cncyBjdXJzb3Igd291bGQgZ28gdW5zZWVuIHVudGlsIHRoZSByb2xsaW5nIHJlLXJlYWQuXG4gICAqXG4gICAqIFdpdGhvdXQgdGhlIHRhYmxlIGV2ZXJ5IHJldmFsaWRhdGlvbiBpcyB0aGlzIHByb2Nlc3MncyBvd24sIGFwcGxpZWQgd2l0aFxuICAgKiB7QGxpbmsgc2V0fSwgc28gYSB0YWcgaXMgdHJhY2tlZCBhdCBvbmNlLlxuICAgKi9cbiAgdHJhY2sodGFnczogcmVhZG9ubHkgc3RyaW5nW10pOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubWFya2Vycykge1xuICAgICAgdGhpcy50cmFja1VucmVhZCh0YWdzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgdGhpcy50b3VjaCh0YWcpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUcmFjayBgdGFnc2AgYXMgdGhleSBhcmUga25vd24gbm93LCB3aXRob3V0IHJlYWRpbmcgdGhlbSwgd2l0aCBhbiBlbXB0eVxuICAgKiBtYXJrZXIgZm9yIGFueSBub3QgdHJhY2tlZCB5ZXQuXG4gICAqL1xuICBwcml2YXRlIHRyYWNrVW5yZWFkKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgaWYgKCF0aGlzLnRhZ3MuaGFzKHRhZykpIHtcbiAgICAgICAgdGhpcy5rbm93bih0YWcsIGF0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMucmVtZW1iZXIodGFnLCB0aGlzLnRhZ3MuZ2V0KHRhZykgPz8ge30pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIHRoZSBtYXJrZXJzIG9mIHdoaWNoZXZlciBvZiBgdGFnc2AgdGhpcyBpbnN0YW5jZSBkb2VzIG5vdCB0cmFjayB5ZXQuXG4gICAqIE5lZWRlZCBiZWZvcmUganVkZ2luZyBhbiBlbnRyeSB0aGlzIGluc3RhbmNlIGRpZCBub3QgY3JlYXRlLCBzaW5jZSBpdHNcbiAgICogdGFncyBtYXkgaGF2ZSBiZWVuIHJldmFsaWRhdGVkIGF0IGFueSB0aW1lIGJlZm9yZS5cbiAgICovXG4gIGFzeW5jIGVuc3VyZSh0YWdzOiByZWFkb25seSBzdHJpbmdbXSk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICghdGhpcy5tYXJrZXJzKSB7XG4gICAgICB0aGlzLnRyYWNrVW5yZWFkKHRhZ3MpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB3YWl0czogUHJvbWlzZTx2b2lkPltdID0gW107XG4gICAgY29uc3QgdW5yZWFkOiBzdHJpbmdbXSA9IFtdO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIG5ldyBTZXQodGFncykpIHtcbiAgICAgIGNvbnN0IGluRmxpZ2h0ID0gdGhpcy5yZWFkaW5nLmdldCh0YWcpO1xuICAgICAgaWYgKGluRmxpZ2h0KSB7XG4gICAgICAgIHdhaXRzLnB1c2goaW5GbGlnaHQpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnRhZ3MuaGFzKHRhZykpIHtcbiAgICAgICAgdGhpcy50b3VjaCh0YWcpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdW5yZWFkLnB1c2godGFnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKHVucmVhZC5sZW5ndGggPiAwKSB7XG4gICAgICAvLyBgcmVhZEludG9gIG5ldmVyIHJlamVjdHM6IGEgZmFpbGVkIHJlYWQgbGVhdmVzIHRoZSB0YWdzIHRyYWNrZWQuXG4gICAgICBjb25zdCByZWFkID0gdGhpcy5yZWFkSW50byh1bnJlYWQpLnRoZW4oKCkgPT4ge1xuICAgICAgICBmb3IgKGNvbnN0IHRhZyBvZiB1bnJlYWQpIHtcbiAgICAgICAgICB0aGlzLnJlYWRpbmcuZGVsZXRlKHRhZyk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdW5yZWFkKSB7XG4gICAgICAgIHRoaXMucmVhZGluZy5zZXQodGFnLCByZWFkKTtcbiAgICAgIH1cbiAgICAgIHdhaXRzLnB1c2gocmVhZCk7XG4gICAgfVxuICAgIGF3YWl0IFByb21pc2UuYWxsKHdhaXRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDYXRjaCB1cCBvbiByZXZhbGlkYXRpb25zIG90aGVyIGluc3RhbmNlcyByYW4sIGF0IG1vc3Qgb25jZSBwZXJcbiAgICogYHJlZnJlc2hJbnRlcnZhbE1zYC4gU2VlIHtAbGluayBUcmFja2VkVGFnTWFya2Vyc30gZm9yIHRoZSBjb3N0LlxuICAgKi9cbiAgYXN5bmMgcmVmcmVzaCgpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBsb2cgPSB0aGlzLmxvZztcbiAgICBpZiAoIWxvZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBpZiAodGhpcy5yZWZyZXNoaW5nKSB7XG4gICAgICByZXR1cm4gdGhpcy5yZWZyZXNoaW5nO1xuICAgIH1cbiAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICBpZiAoYXQgLSB0aGlzLmxhc3RSZWZyZXNoIDwgdGhpcy5yZWZyZXNoSW50ZXJ2YWxNcykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmxhc3RSZWZyZXNoID0gYXQ7XG4gICAgLy8gV2hhdGV2ZXIgZ2V0cyB0cmFja2VkIGJlZm9yZSB0aGUgbmV4dCByZWZyZXNoIGlzIHJlYWQgZnJvbSBpdHMgbWFya2VyLFxuICAgIC8vIHNvIHRoZXJlIGlzIG5vdGhpbmcgdG8gY2F0Y2ggdXAgb24geWV0LlxuICAgIGlmICh0aGlzLnRhZ3Muc2l6ZSA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnJlZnJlc2hpbmcgPSB0aGlzLnN5bmMoYXQsIGxvZykuZmluYWxseSgoKSA9PiB7XG4gICAgICB0aGlzLnJlZnJlc2hpbmcgPSB1bmRlZmluZWQ7XG4gICAgfSk7XG4gICAgcmV0dXJuIHRoaXMucmVmcmVzaGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgYSByZXZhbGlkYXRpb24gb2YgYHRhZ3NgOiBoZXJlIGF0IG9uY2UsIGFuZCBpbiB0aGUgcmV2YWxpZGF0aW9uXG4gICAqIHRhYmxlIGZvciBldmVyeSBvdGhlciBpbnN0YW5jZSAtIHRoZSBtYXJrZXIgcm93IHBsdXMgYSBsb2cgcm93IHBlciB0YWcuXG4gICAqXG4gICAqIE5leHQuanMgY2FsbHMgYHJldmFsaWRhdGVUYWdgIG9uIHRoZSBpbmNyZW1lbnRhbCBjYWNoZSBhbmQgYHVwZGF0ZVRhZ3NgIG9uXG4gICAqIGV2ZXJ5IGRpc3RpbmN0IGBjYWNoZUhhbmRsZXJzYCBlbnRyeSwgYWxsIGluIG9uZSBzeW5jaHJvbm91cyBsb29wXG4gICAqIChgcmV2YWxpZGF0aW9uLXV0aWxzYCksIGFuZCBhbGwgb2YgdGhlbSBzaGFyZSB0aGlzIG1hbmlmZXN0LiBTbyBhblxuICAgKiBpZGVudGljYWwgY2FsbCBpbiB0aGUgc2FtZSB0dXJuIGpvaW5zIHRoZSBmaXJzdCBpbnN0ZWFkIG9mIHdyaXRpbmcgdGhlXG4gICAqIHJvd3MgYWdhaW4uIE9uZSBpbiBhIGxhdGVyIHR1cm4gaXMgYSByZXZhbGlkYXRpb24gb2YgaXRzIG93biwgZXZlbiB3aGlsZVxuICAgKiB0aGUgZmlyc3Qgb25lJ3Mgd3JpdGVzIGFyZSBpbiBmbGlnaHQsIGFuZCBnZXRzIGl0cyBvd24sIGxhdGVyLCBtYXJrZXIuXG4gICAqIE5ldmVyIHJlamVjdHM6IHJlc29sdmVzIGBmYWxzZWAgd2hlbiBhIHJvdyBmYWlsZWQgdG8gd3JpdGUgKHRoZSBlcnJvciBpc1xuICAgKiBsb2dnZWQpLCBzbyBvdGhlciBpbnN0YW5jZXMgbWF5IG5vdCBzZWUgaXQuXG4gICAqL1xuICBhc3luYyB1cGRhdGUoXG4gICAgdGFnczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgZHVyYXRpb25zOiBSZXZhbGlkYXRlRHVyYXRpb25zIHwgdW5kZWZpbmVkLFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShbdGFncywgZHVyYXRpb25zID8/IG51bGxdKTtcbiAgICBjb25zdCBpbkZsaWdodCA9IHRoaXMudXBkYXRpbmcuZ2V0KGtleSk7XG4gICAgaWYgKGluRmxpZ2h0KSB7XG4gICAgICByZXR1cm4gaW5GbGlnaHQ7XG4gICAgfVxuICAgIGNvbnN0IHVwZGF0ZSA9IHRoaXMud3JpdGUodGFncywgZHVyYXRpb25zKTtcbiAgICB0aGlzLnVwZGF0aW5nLnNldChrZXksIHVwZGF0ZSk7XG4gICAgLy8gRm9yZ290dGVuIGFzIHNvb24gYXMgdGhlIGN1cnJlbnQgdHVybidzIGNhbGxzIGhhdmUgYmVlbiBtYWRlLlxuICAgIHZvaWQgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB0aGlzLnVwZGF0aW5nLmRlbGV0ZShrZXkpKTtcbiAgICByZXR1cm4gdXBkYXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoYXQgdGhlIHRyYWNrZWQgbWFya2VycyBzYXkgYWJvdXQgYW4gZW50cnkgY2FycnlpbmcgYHRhZ3NgLCBjcmVhdGVkIGF0XG4gICAqIGBjcmVhdGVkQXRgOiB0aGUgbW9zdCBzZXZlcmUgYW5zd2VyIG9mIGFueSBvZiB0aGVtLlxuICAgKi9cbiAgc3RhdGUodGFnczogcmVhZG9ubHkgc3RyaW5nW10sIGNyZWF0ZWRBdDogbnVtYmVyKTogUmV2YWxpZGF0aW9uU3RhdGUge1xuICAgIC8vIGBtYXJrZXJDbG9jaygpYCwgbm90IGBEYXRlLm5vdygpYCwgaGVyZSBhbmQgd2hlcmV2ZXIgYSBtYXJrZXIgaXMgc3RhbXBlZDpcbiAgICAvLyBgY3JlYXRlZEF0YCBpcyBvbiBOZXh0LmpzJ3MgY2xvY2ssIGFuZCBhIG1hcmtlciBvbiB0aGUgd2FsbCBjbG9jayB3b3VsZCBiZVxuICAgIC8vIGNvbXBhcmVkIGFjcm9zcyB0aGUgdHdvLCBzbyBhbiBlbnRyeSByZWdlbmVyYXRlZCBqdXN0IGFmdGVyIGFcbiAgICAvLyByZXZhbGlkYXRpb24gY291bGQgc3RpbGwgcmVhZCBhcyBvbGRlciB0aGFuIGl0IHdoZXJldmVyIHRoZXkgZHJpZnQuXG4gICAgY29uc3QgYXQgPSBtYXJrZXJDbG9jaygpO1xuICAgIGxldCBzdGF0ZTogUmV2YWxpZGF0aW9uU3RhdGUgPSBcImZyZXNoXCI7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy5nZXQodGFnKTtcbiAgICAgIGlmICghbWFya2VyKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgdGFnU3RhdGUgPSBtYXJrZXJTdGF0ZShtYXJrZXIsIGNyZWF0ZWRBdCwgYXQpO1xuICAgICAgaWYgKHRhZ1N0YXRlID09PSBcImV4cGlyZWRcIikge1xuICAgICAgICByZXR1cm4gXCJleHBpcmVkXCI7XG4gICAgICB9XG4gICAgICBpZiAodGFnU3RhdGUgPT09IFwic3RhbGVcIikge1xuICAgICAgICBzdGF0ZSA9IFwic3RhbGVcIjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHN0YXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIGBnZXRFeHBpcmF0aW9uYCdzIGFuc3dlcjogdGhlIGxhdGVzdCB0aW1lIGFueSBvZiBgdGFnc2AgZXhwaXJlZCwgYDBgIGlmXG4gICAqIG5vbmUgaGFzLiBPbmx5IGV4cGlyYXRpb25zIGFscmVhZHkgcGFzdCBjb3VudCAtIGEgcHJvZmlsZSdzIGZ1dHVyZVxuICAgKiBgZXhwaXJlYCBpcyBub3QgYW4gZXhwaXJhdGlvbiB5ZXQgLSBhbmQgYSBzdGFsZSBtYXJrIGRvZXMgbm90LCBtYXRjaGluZ1xuICAgKiBOZXh0LmpzJ3MgZGVmYXVsdCBoYW5kbGVyLCB3aGljaCByZWFkcyBvbmx5IGBleHBpcmVkYCBmb3IgaW1wbGljaXQgdGFncy5cbiAgICovXG4gIGV4cGlyYXRpb24odGFnczogcmVhZG9ubHkgc3RyaW5nW10pOiBudW1iZXIge1xuICAgIGNvbnN0IGF0ID0gbWFya2VyQ2xvY2soKTtcbiAgICBsZXQgbGF0ZXN0ID0gMDtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICBjb25zdCBtYXJrZXIgPSB0aGlzLmdldCh0YWcpO1xuICAgICAgaWYgKCFtYXJrZXIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBpZiAobWFya2VyLnJldmFsaWRhdGVkQXQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBsYXRlc3QgPSBNYXRoLm1heChsYXRlc3QsIG1hcmtlci5yZXZhbGlkYXRlZEF0KTtcbiAgICAgIH1cbiAgICAgIGlmIChtYXJrZXIuZXhwaXJlZEF0ICE9PSB1bmRlZmluZWQgJiYgbWFya2VyLmV4cGlyZWRBdCA8PSBhdCkge1xuICAgICAgICBsYXRlc3QgPSBNYXRoLm1heChsYXRlc3QsIG1hcmtlci5leHBpcmVkQXQpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbGF0ZXN0O1xuICB9XG5cbiAgcHJpdmF0ZSBhc3luYyB3cml0ZShcbiAgICB0YWdzOiByZWFkb25seSBzdHJpbmdbXSxcbiAgICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4gICk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGNvbnN0IGF0ID0gbWFya2VyQ2xvY2soKTtcbiAgICBjb25zdCBtYXJrZXIgPSBtYXJrZXJGb3IoYXQsIGR1cmF0aW9ucyk7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgdGhpcy5zZXQodGFnLCBhcHBseU1hcmtlcih0aGlzLmdldCh0YWcpLCBtYXJrZXIpKTtcbiAgICB9XG4gICAgY29uc3QgeyBtYXJrZXJzLCBsb2cgfSA9IHRoaXM7XG4gICAgaWYgKCFtYXJrZXJzIHx8ICFsb2cpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICBjb25zdCB3cml0ZXM6IFtzdHJpbmcsIFByb21pc2U8dW5rbm93bj5dW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBuZXcgU2V0KHRhZ3MpKSB7XG4gICAgICB3cml0ZXMucHVzaChbXG4gICAgICAgIFwiRXJyb3Igd3JpdGluZyB0YWcgcmV2YWxpZGF0aW9uIG1hcmtlcjpcIixcbiAgICAgICAgLy8gVGhlIHJvdyBhcyBpdCBpcyBub3csIHdoaWNoIGNhcnJpZXMgYW55IGVhcmxpZXIgYHJldmFsaWRhdGVkQXRgXG4gICAgICAgIC8vIGFub3RoZXIgaW5zdGFuY2Ugd3JvdGU6IHRyYWNraW5nIG9ubHkgd2hhdCB0aGlzIGNhbGwgc2V0IHdvdWxkXG4gICAgICAgIC8vIGhpZGUgdGhhdCBvbmUgdW50aWwgdGhlIHJvbGxpbmcgcmUtcmVhZCwgYW5kIGFuIGVudHJ5IG9sZGVyIHRoYW4gaXRcbiAgICAgICAgLy8gd291bGQgcmVhZCBhcyBtZXJlbHkgc3RhbGUuXG4gICAgICAgIG1hcmtlcnMud3JpdGUodGFnLCBhdCwgZHVyYXRpb25zKS50aGVuKChyb3cpID0+IHtcbiAgICAgICAgICBpZiAocm93KSB7XG4gICAgICAgICAgICB0aGlzLnNldCh0YWcsIG1lcmdlTWFya2Vycyh0aGlzLmdldCh0YWcpLCByb3cpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pLFxuICAgICAgXSk7XG4gICAgICB3cml0ZXMucHVzaChbXG4gICAgICAgIFwiRXJyb3Igd3JpdGluZyB0YWcgcmV2YWxpZGF0aW9uIGxvZyByb3c6XCIsXG4gICAgICAgIHRoaXMucHV0TG9nUm93KGxvZywgdGFnLCBtYXJrZXIpLFxuICAgICAgXSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdHMgPSBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQod3JpdGVzLm1hcCgoWywgd3JpdGVdKSA9PiB3cml0ZSkpO1xuICAgIHJlc3VsdHMuZm9yRWFjaCgocmVzdWx0LCBpKSA9PiB7XG4gICAgICBpZiAocmVzdWx0LnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3Iod3JpdGVzW2ldWzBdLCByZXN1bHQucmVhc29uKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0cy5ldmVyeSgocmVzdWx0KSA9PiByZXN1bHQuc3RhdHVzID09PSBcImZ1bGZpbGxlZFwiKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQdXQgYHRhZ2AncyBsb2cgcm93LCBzdGFtcGVkIG9uIHRoZSB3YWxsIGNsb2NrICh0aGUgbWFya2VyIHZhbHVlcyBhcmUgb25cbiAgICogTmV4dC5qcydzOiBzZWUge0BsaW5rIFJldmFsaWRhdGlvbkxvZ30pLlxuICAgKlxuICAgKiBSZWFkZXJzIG9ubHkgbG9vayB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NU30gYmVoaW5kIHRoZWlyIGxhc3RcbiAgICogcXVlcnksIHNvIGEgcm93IHRoYXQgc2hvd3MgdXAgbXVjaCBsYXRlciB0aGFuIGl0cyB0aW1lc3RhbXAgLSBhIHNsb3dcbiAgICogY29ubmVjdGlvbiwgcmV0cmllcyB1bmRlciB0aHJvdHRsaW5nIC0gaXMgYmVoaW5kIGV2ZXJ5IGN1cnNvciBhbmQgbmV2ZXJcbiAgICogcmVhZC4gQSBzbG93IHB1dCBpcyB0aGVyZWZvcmUgbWFkZSBhZ2FpbiB1bmRlciBhIGZyZXNoIHRpbWVzdGFtcCwgd2hpY2hcbiAgICogcmVhZGVycyB3aWxsIHNlZTsgb25lIHNsb3cgdHdpY2UgaXMgcmVwb3J0ZWQgYXMgYSBmYWlsdXJlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBwdXRMb2dSb3coXG4gICAgbG9nOiBSZXZhbGlkYXRpb25Mb2csXG4gICAgdGFnOiBzdHJpbmcsXG4gICAgbWFya2VyOiBUYWdNYXJrZXIsXG4gICk6IFByb21pc2U8dm9pZD4ge1xuICAgIGZvciAobGV0IGF0dGVtcHQgPSAwOyBhdHRlbXB0IDwgMjsgYXR0ZW1wdCsrKSB7XG4gICAgICBjb25zdCBhdCA9IHRoaXMuY2xvY2soKTtcbiAgICAgIGF3YWl0IGxvZy5wdXQodGFnLCBhdCwgbWFya2VyKTtcbiAgICAgIGlmICh0aGlzLmNsb2NrKCkgLSBhdCA8PSBNQVhfTE9HX1BVVF9NUykge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgIGBUaGUgcmV2YWxpZGF0aW9uIGxvZyByb3cgZm9yICR7dGFnfSB0b29rIGxvbmdlciB0aGFuIHJlYWRlcnMgbG9vayBiYWNrYCxcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIE9uZSByZWZyZXNoIHN0YXJ0ZWQgYXQgYGF0YDogdGhlIGxvZyByb3dzIHNpbmNlIHRoZSBjdXJzb3IsIGFuZCB0aGUgbmV4dFxuICAgKiBzbGljZSBvZiB0aGUgcm9sbGluZyByZS1yZWFkLlxuICAgKlxuICAgKiBBIGZhaWxlZCBxdWVyeSBjaGFuZ2VzIG5vdGhpbmcgYnV0IHRoZSBsb2c6IHRoZSB0YWdzIHN0YXkgdHJhY2tlZCBhcyB0aGV5XG4gICAqIHdlcmUsIGFuZCB0aGUgbmV4dCByZWZyZXNoIGFza3MgYWdhaW4gZnJvbSB0aGUgc2FtZSBjdXJzb3IuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHN5bmMoYXQ6IG51bWJlciwgbG9nOiBSZXZhbGlkYXRpb25Mb2cpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoYXQgLSB0aGlzLmxhc3RMb2dSZWFkID4gTUFYX1JFVkFMSURBVElPTl9MT0dfR0FQX01TKSB7XG4gICAgICB0aGlzLmZvcmdldChcbiAgICAgICAgYXQsXG4gICAgICAgIFwidGhlIHJldmFsaWRhdGlvbiBsb2cgbWF5IG5vdCBjb3ZlciB0aGUgZ2FwIHNpbmNlIGl0IHdhcyBsYXN0IHJlYWRcIixcbiAgICAgICk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IFtyZXN1bHRdID0gYXdhaXQgUHJvbWlzZS5hbGwoW1xuICAgICAgbG9nLnF1ZXJ5KHRoaXMuY3Vyc29yKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc29sZS5lcnJvcihcIkVycm9yIHJlYWRpbmcgdGFnIHJldmFsaWRhdGlvbiBsb2c6XCIsIGVycm9yKTtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH0pLFxuICAgICAgdGhpcy5yZWFkSW50byh0aGlzLmR1ZShhdCkpLFxuICAgIF0pO1xuICAgIGlmICghcmVzdWx0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyZXN1bHQudHJ1bmNhdGVkKSB7XG4gICAgICB0aGlzLmZvcmdldChcbiAgICAgICAgYXQsXG4gICAgICAgIFwidGhlIHJldmFsaWRhdGlvbiBsb2cgaGFzIG1vcmUgcm93cyB0aGFuIG9uZSBxdWVyeSByZWFkc1wiLFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgbGV0IGFwcGxpZWQgPSAwO1xuICAgIGZvciAoY29uc3Qgcm93IG9mIHJlc3VsdC5yb3dzKSB7XG4gICAgICBpZiAodGhpcy5hcHBsaWVkLmhhcyhyb3cuc2spKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy50YWdzLmdldChyb3cudGFnKTtcbiAgICAgIGlmIChtYXJrZXIpIHtcbiAgICAgICAgLy8gYHNldGAgb24gYSBrZXkgYWxyZWFkeSB0aGVyZSBrZWVwcyBpdHMgcGxhY2UgaW4gdGhlIExSVSBvcmRlcjogYmVpbmdcbiAgICAgICAgLy8gcmV2YWxpZGF0ZWQgZWxzZXdoZXJlIGlzIG5vdCBhIHVzZS5cbiAgICAgICAgdGhpcy50YWdzLnNldChyb3cudGFnLCBtZXJnZU1hcmtlcnMobWFya2VyLCByb3cubWFya2VyKSk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMucmVhZGluZy5oYXMocm93LnRhZykpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nUm93cy5zZXQoXG4gICAgICAgICAgcm93LnRhZyxcbiAgICAgICAgICBtZXJnZU1hcmtlcnModGhpcy5wZW5kaW5nUm93cy5nZXQocm93LnRhZyksIHJvdy5tYXJrZXIpLFxuICAgICAgICApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgLy8gQSB0YWcgdGhpcyBpbnN0YW5jZSBkb2VzIG5vdCB0cmFjayBpcyByZWFkIGZyb20gaXRzIG1hcmtlciB3aGVuIGl0XG4gICAgICAgIC8vIGlzIG5leHQgbmVlZGVkIC0gYnV0IG5vdCB5ZXQgbWFya2VkIGFwcGxpZWQsIGJlY2F1c2UgdGhhdCByZWFkIG1heVxuICAgICAgICAvLyBtaXNzIHRoaXMgdmVyeSByZXZhbGlkYXRpb246IHRoZSB3cml0ZXIgcHV0cyB0aGUgbG9nIHJvdyBhbmQgdGhlXG4gICAgICAgIC8vIG1hcmtlciBhdCB0aGUgc2FtZSB0aW1lLCBhbmQgdGhlIHJlYWQgaXMgYW4gZXZlbnR1YWxseSBjb25zaXN0ZW50XG4gICAgICAgIC8vIGBCYXRjaEdldEl0ZW1gIHRoYXQgY2FuIGxhbmQgbWlsbGlzZWNvbmRzIGFmdGVyIHRoZSByb3cgc2hvd2VkIGhlcmUuXG4gICAgICAgIC8vIE1hcmtlZCBhcHBsaWVkLCB0aGUgcm93IHdhcyBza2lwcGVkIGJ5IGV2ZXJ5IHF1ZXJ5IHRoZSBsb29rYmFja1xuICAgICAgICAvLyByZXR1cm5lZCBpdCB0bywgYW5kIHRoZSBwcmUtcmV2YWxpZGF0aW9uIG1hcmtlciBzdG9vZCB1bnRpbCB0aGVcbiAgICAgICAgLy8gcm9sbGluZyByZS1yZWFkLiBMZWZ0IHVubWFya2VkLCB0aGUgbmV4dCByZWZyZXNoIGFwcGxpZXMgaXQgdG9cbiAgICAgICAgLy8gd2hhdGV2ZXIgdGhhdCByZWFkIGZvdW5kOyBpdCBjb3N0cyBubyByZWFkLCBvbmx5IHRoZSByb3cgYmVpbmdcbiAgICAgICAgLy8gbG9va2VkIGF0IGFnYWluIHdoaWxlIGl0IGlzIGluc2lkZSB0aGUgbG9va2JhY2suXG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5hcHBsaWVkLnNldChyb3cuc2ssIHJvdy5hdCk7XG4gICAgICBhcHBsaWVkKys7XG4gICAgfVxuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgICB0aGlzLmFkdmFuY2UoYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TKTtcbiAgICB0aGlzLmRlYnVnKFxuICAgICAgYHJlYWQgJHtyZXN1bHQucm93cy5sZW5ndGh9IHJldmFsaWRhdGlvbiBsb2cgcm93cyAoJHthcHBsaWVkfSBhcHBsaWVkKWAsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdGFncyB0byByZWFkIG9uIHRoaXMgcmVmcmVzaCwgYXQgbW9zdCBvbmUgYEJhdGNoR2V0SXRlbWAncyB3b3J0aDpcbiAgICogdGhvc2Ugd2hvc2UgcmVhZCBmYWlsZWQsIHRoZW4gdGhvc2Ugd2hvc2UgcmUtcmVhZCBoYXMgY29tZSBkdWUsIGluIHRoZVxuICAgKiBvcmRlciB0aGV5IHdlcmUgbGFzdCByZWFkLlxuICAgKi9cbiAgcHJpdmF0ZSBkdWUoYXQ6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBkdWU6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGhpcy51bnJlYWQpIHtcbiAgICAgIGlmIChkdWUubGVuZ3RoID49IEJBVENIX0dFVF9NQVhfS0VZUykgcmV0dXJuIGR1ZTtcbiAgICAgIGR1ZS5wdXNoKHRhZyk7XG4gICAgfVxuICAgIC8vIEtub3duIGluIHRpbWUgb3JkZXIsIGFuZCBlYWNoIGR1ZSBhdCBtb3N0IGBqaXR0ZXJgIGVhcmxpZXIgdGhhbiB0aGVcbiAgICAvLyB0YWdzIGFmdGVyIGl0OiBwYXN0IGEgdGFnIGR1ZSBtb3JlIHRoYW4gdGhhdCBmcm9tIG5vdywgbm9uZSBpcyBkdWUuXG4gICAgY29uc3Qgaml0dGVyID0gdGhpcy5yZXN5bmNJbnRlcnZhbE1zICogVEFHX1JFU1lOQ19KSVRURVI7XG4gICAgZm9yIChjb25zdCBbdGFnLCBkdWVBdF0gb2YgdGhpcy5kdWVBdCkge1xuICAgICAgaWYgKGR1ZS5sZW5ndGggPj0gQkFUQ0hfR0VUX01BWF9LRVlTIHx8IGR1ZUF0IC0gaml0dGVyID4gYXQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoZHVlQXQgPD0gYXQgJiYgIXRoaXMudW5yZWFkLmhhcyh0YWcpKSB7XG4gICAgICAgIGR1ZS5wdXNoKHRhZyk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBkdWU7XG4gIH1cblxuICAvKipcbiAgICogRm9yZ2V0IGV2ZXJ5IHRyYWNrZWQgbWFya2VyLCBhbmQgZm9sbG93IHRoZSBsb2cgZnJvbSBgYXRgOiB3aGF0IGlzIG5lZWRlZFxuICAgKiBuZXh0IGlzIHJlYWQgZnJvbSBpdHMgbWFya2VyIGFzIGl0IGlzIG5lZWRlZCwgc3ByZWFkIG92ZXIgdGhlIHJlcXVlc3RzXG4gICAqIHRoYXQgbmVlZCBpdCwgcmF0aGVyIHRoYW4gZXZlcnkgdHJhY2tlZCB0YWcgcmUtcmVhZCBhdCBvbmNlLlxuICAgKi9cbiAgcHJpdmF0ZSBmb3JnZXQoYXQ6IG51bWJlciwgd2h5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmRlYnVnKGBmb3JnZXR0aW5nICR7dGhpcy50YWdzLnNpemV9IHRyYWNrZWQgdGFnczogJHt3aHl9YCk7XG4gICAgdGhpcy50YWdzLmNsZWFyKCk7XG4gICAgdGhpcy5kdWVBdC5jbGVhcigpO1xuICAgIHRoaXMudW5yZWFkLmNsZWFyKCk7XG4gICAgdGhpcy5hcHBsaWVkLmNsZWFyKCk7XG4gICAgdGhpcy5jdXJzb3IgPSBhdCAtIFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVM7XG4gICAgdGhpcy5sYXN0TG9nUmVhZCA9IGF0O1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgdGhlIGN1cnNvciBmb3J3YXJkIHRvIGBjdXJzb3JgLCBmb3JnZXR0aW5nIGFwcGxpZWQgcm93cyBiZWZvcmUgaXQ6XG4gICAqIG5vIHF1ZXJ5IHJldHVybnMgdGhlbSBhZ2Fpbi5cbiAgICovXG4gIHByaXZhdGUgYWR2YW5jZShjdXJzb3I6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChjdXJzb3IgPD0gdGhpcy5jdXJzb3IpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgdGhpcy5jdXJzb3IgPSBjdXJzb3I7XG4gICAgZm9yIChjb25zdCBbc2ssIGF0XSBvZiB0aGlzLmFwcGxpZWQpIHtcbiAgICAgIGlmIChhdCA8IGN1cnNvcikge1xuICAgICAgICB0aGlzLmFwcGxpZWQuZGVsZXRlKHNrKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVhZCBgdGFnc2AgZnJvbSB0aGUgdGFibGUsIGFuZCByZXBvcnQgd2hldGhlciB0aGF0IHdvcmtlZC4gQSByZWFkIHRoYXRcbiAgICogZmFpbHMgbGVhdmVzIHRoZW0gdHJhY2tlZCBhcyB0aGV5IHdlcmUsIGFuZCB0aGUgbmV4dCByZWZyZXNoIHJlYWRzIHRoZW1cbiAgICogYWdhaW46IHRoZSBzYW1lIFwiYXNzdW1lIHRoZSBlbnRyeSBpcyB2YWxpZFwiIHRoZSBpbmNyZW1lbnRhbCBjYWNoZSBoYXNcbiAgICogYWx3YXlzIGFuc3dlcmVkIHdpdGgsIHJhdGhlciB0aGFuIGEgcmVhZCBvbiBldmVyeSByZXF1ZXN0IHdoaWxlIER5bmFtb0RCXG4gICAqIGlzIHVuYXZhaWxhYmxlLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyByZWFkSW50byh0YWdzOiBzdHJpbmdbXSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICAgIGlmICh0YWdzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgIHRyeSB7XG4gICAgICBjb25zdCByZWFkID0gYXdhaXQgdGhpcy5tYXJrZXJzIS5yZWFkKHRhZ3MpO1xuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgICB0aGlzLnVucmVhZC5kZWxldGUodGFnKTtcbiAgICAgICAgdGhpcy5yZW1lbWJlcihcbiAgICAgICAgICB0YWcsXG4gICAgICAgICAgbWVyZ2VNYXJrZXJzKFxuICAgICAgICAgICAgbWVyZ2VNYXJrZXJzKHRoaXMudGFncy5nZXQodGFnKSwgcmVhZC5nZXQodGFnKSksXG4gICAgICAgICAgICB0aGlzLnRha2VQZW5kaW5nUm93cyh0YWcpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMua25vd24odGFnLCBhdCk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlYnVnKGByZWFkICR7dGFncy5sZW5ndGh9IHRhZyBtYXJrZXJzICgke3JlYWQuc2l6ZX0gc2V0KWApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciByZWFkaW5nIHRhZyBtYXJrZXJzOlwiLCBlcnJvcik7XG4gICAgICB0aGlzLnRyYWNrVW5yZWFkKHRhZ3MpO1xuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgICB0aGlzLnVucmVhZC5hZGQodGFnKTtcbiAgICAgICAgY29uc3QgcGVuZGluZyA9IHRoaXMudGFrZVBlbmRpbmdSb3dzKHRhZyk7XG4gICAgICAgIGlmIChwZW5kaW5nKSB7XG4gICAgICAgICAgdGhpcy5yZW1lbWJlcih0YWcsIG1lcmdlTWFya2Vycyh0aGlzLnRhZ3MuZ2V0KHRhZyksIHBlbmRpbmcpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdGFrZVBlbmRpbmdSb3dzKHRhZzogc3RyaW5nKTogVGFnTWFya2VyIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nUm93cy5nZXQodGFnKTtcbiAgICB0aGlzLnBlbmRpbmdSb3dzLmRlbGV0ZSh0YWcpO1xuICAgIHJldHVybiBwZW5kaW5nO1xuICB9XG5cbiAgLyoqIFJlY29yZCB0aGF0IGB0YWdgJ3MgbWFya2VyIHdhcyBrbm93biBmcm9tIHRoZSB0YWJsZSBhdCBgYXRgLiAqL1xuICBwcml2YXRlIGtub3duKHRhZzogc3RyaW5nLCBhdDogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy5kdWVBdC5kZWxldGUodGFnKTtcbiAgICB0aGlzLmR1ZUF0LnNldChcbiAgICAgIHRhZyxcbiAgICAgIGF0ICsgdGhpcy5yZXN5bmNJbnRlcnZhbE1zICogKDEgLSBUQUdfUkVTWU5DX0pJVFRFUiAqIHRoaXMucmFuZG9tKCkpLFxuICAgICk7XG4gIH1cblxuICBwcml2YXRlIHJlbWVtYmVyKHRhZzogc3RyaW5nLCBtYXJrZXI6IFRhZ01hcmtlcik6IHZvaWQge1xuICAgIHRoaXMudGFncy5kZWxldGUodGFnKTtcbiAgICB0aGlzLnRhZ3Muc2V0KHRhZywgbWFya2VyKTtcbiAgICBmb3IgKGNvbnN0IG9sZGVzdCBvZiB0aGlzLnRhZ3Mua2V5cygpKSB7XG4gICAgICBpZiAodGhpcy50YWdzLnNpemUgPD0gdGhpcy5tYXhUcmFja2VkVGFncykge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIHRoaXMudGFncy5kZWxldGUob2xkZXN0KTtcbiAgICAgIHRoaXMuZHVlQXQuZGVsZXRlKG9sZGVzdCk7XG4gICAgICB0aGlzLnVucmVhZC5kZWxldGUob2xkZXN0KTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHRvdWNoKHRhZzogc3RyaW5nKTogdm9pZCB7XG4gICAgY29uc3QgbWFya2VyID0gdGhpcy50YWdzLmdldCh0YWcpO1xuICAgIGlmIChtYXJrZXIpIHtcbiAgICAgIHRoaXMucmVtZW1iZXIodGFnLCBtYXJrZXIpO1xuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFRoZSBsb25nZXN0IGEgbG9nIHJvdydzIHB1dCBtYXkgdGFrZSBhbmQgc3RpbGwgYmUgc2VlbiBieSBldmVyeSByZWFkZXI6IGhhbGZcbiAqIHRoZSBsb29rYmFjaywgbGVhdmluZyB0aGUgcmVzdCBmb3Igd3JpdGVycycgY2xvY2tzIGFuZCBldmVudHVhbGx5IGNvbnNpc3RlbnRcbiAqIHF1ZXJpZXMuXG4gKi9cbmNvbnN0IE1BWF9MT0dfUFVUX01TID0gUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUyAvIDI7XG5cbi8qKlxuICogQSBtYXJrZXIgYXMgcmVhZCBmcm9tIHRoZSB0YWJsZSBvciB0aGUgbG9nLCBrZWVwaW5nIHdoYXRldmVyIHRoaXMgaW5zdGFuY2VcbiAqIGFscmVhZHkga25vd3MgdGhhdCB0aGUgcmVhZCBkb2VzIG5vdCBzaG93IHlldDogcmVhZHMgYXJlIGV2ZW50dWFsbHlcbiAqIGNvbnNpc3RlbnQsIGFuZCBhIHJlYWQgc3RyYWlnaHQgYWZ0ZXIgdGhpcyBpbnN0YW5jZSdzIG93biByZXZhbGlkYXRpb24gY291bGRcbiAqIG90aGVyd2lzZSB0YWtlIGl0IGJhY2suXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtZXJnZU1hcmtlcnMoXG4gIGxvY2FsOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQsXG4gIHJlbW90ZTogVGFnTWFya2VyIHwgdW5kZWZpbmVkLFxuKTogVGFnTWFya2VyIHtcbiAgaWYgKCFsb2NhbCkge1xuICAgIHJldHVybiByZW1vdGUgPz8ge307XG4gIH1cbiAgaWYgKCFyZW1vdGUpIHtcbiAgICByZXR1cm4gbG9jYWw7XG4gIH1cbiAgLy8gYGV4cGlyZWRBdGAgaXMgd3JpdHRlbiB3aXRoIGBzdGFsZUF0YCwgc28gaXQgYmVsb25ncyB0byB3aGljaGV2ZXIgaXNcbiAgLy8gbmV3ZXIgLSB1bmxlc3MgdGhhdCByZXZhbGlkYXRpb24ncyBwcm9maWxlIGhhZCBubyBgZXhwaXJlYCBhbmQgbGVmdCBpdC5cbiAgY29uc3QgW29sZGVyLCBuZXdlcl0gPVxuICAgIChsb2NhbC5zdGFsZUF0ID8/IC0xKSA+IChyZW1vdGUuc3RhbGVBdCA/PyAtMSlcbiAgICAgID8gW3JlbW90ZSwgbG9jYWxdXG4gICAgICA6IFtsb2NhbCwgcmVtb3RlXTtcbiAgcmV0dXJuIHtcbiAgICAuLi5hcHBseU1hcmtlcihvbGRlciwgbmV3ZXIpLFxuICAgIHJldmFsaWRhdGVkQXQ6IG1heERlZmluZWQobG9jYWwucmV2YWxpZGF0ZWRBdCwgcmVtb3RlLnJldmFsaWRhdGVkQXQpLFxuICB9O1xufVxuXG5mdW5jdGlvbiBtYXhEZWZpbmVkKGE6IG51bWJlciB8IHVuZGVmaW5lZCwgYjogbnVtYmVyIHwgdW5kZWZpbmVkKSB7XG4gIGlmIChhID09PSB1bmRlZmluZWQpIHJldHVybiBiO1xuICBpZiAoYiA9PT0gdW5kZWZpbmVkKSByZXR1cm4gYTtcbiAgcmV0dXJuIE1hdGgubWF4KGEsIGIpO1xufVxuXG4vKipcbiAqIFRoZSBjYWNoZSBidWNrZXQsIGFzIHRoZSBoYW5kbGVycyB1c2UgaXQ6IHdob2xlIG9iamVjdHMgcmVhZCBhbmQgd3JpdHRlbiBhc1xuICogVVRGLTggdGV4dCB1bmRlciB0aGUga2V5cyBhYm92ZS5cbiAqL1xuZXhwb3J0IGNsYXNzIENhY2hlQnVja2V0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IFMzQ2xpZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYnVja2V0TmFtZTogc3RyaW5nLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIFRoZSBib2R5IG9mIHRoZSBvYmplY3QgYXQgYGtleWAsIG9yIGB1bmRlZmluZWRgIHdoZW4gdGhlcmUgaXMgbm9uZSAoYE5vU3VjaEtleWAsIG9yIGFuXG4gICAqIGVtcHR5IHJlc3BvbnNlIGJvZHkpLiBBbnkgb3RoZXIgZXJyb3IgaXMgdGhyb3duOiB0aGUgaGFuZGxlcnMgZGlzYWdyZWUgb25cbiAgICogd2hldGhlciBvbmUgaXMgd29ydGggbG9nZ2luZy5cbiAgICovXG4gIGFzeW5jIGdldChrZXk6IHN0cmluZyk6IFByb21pc2U8c3RyaW5nIHwgdW5kZWZpbmVkPiB7XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlc3BvbnNlID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgbmV3IEdldE9iamVjdENvbW1hbmQoeyBCdWNrZXQ6IHRoaXMuYnVja2V0TmFtZSwgS2V5OiBrZXkgfSksXG4gICAgICApO1xuICAgICAgaWYgKCFyZXNwb25zZS5Cb2R5KSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gYXdhaXQgcmVzcG9uc2UuQm9keS50cmFuc2Zvcm1Ub1N0cmluZyhcInV0Zi04XCIpO1xuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBOb1N1Y2hLZXkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHRocm93IGVycm9yO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBXcml0ZSBgYm9keWAgYXMgYSBKU09OIG9iamVjdCBhdCBga2V5YC4gKi9cbiAgYXN5bmMgcHV0SnNvbihrZXk6IHN0cmluZywgYm9keTogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgIG5ldyBQdXRPYmplY3RDb21tYW5kKHtcbiAgICAgICAgQnVja2V0OiB0aGlzLmJ1Y2tldE5hbWUsXG4gICAgICAgIEtleToga2V5LFxuICAgICAgICBCb2R5OiBib2R5LFxuICAgICAgICBDb250ZW50VHlwZTogXCJhcHBsaWNhdGlvbi9qc29uOyBjaGFyc2V0PXV0Zi04XCIsXG4gICAgICB9KSxcbiAgICApO1xuICB9XG59XG4iXX0=
|
|
1481
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXdzLWNhY2hlLXN0b3JlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vc3JjL2FkYXB0ZXIvYXdzLWNhY2hlLXN0b3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7OztBQWlEQSxzREFPQztBQVNELGdDQUVDO0FBR0Qsa0NBRUM7QUFtQkQsc0NBRUM7QUFxQ0Qsa0NBZ0JDO0FBV0Qsa0NBRUM7QUFXRCw4QkFXQztBQVFELGtDQVdDO0FBR0Qsb0NBZUM7QUFpREQsOEJBRUM7QUFZRCxnQ0FFQztBQWkzQ0Qsb0NBb0JDO0FBaHFERDs7Ozs7Ozs7O0VBU0U7QUFDRixzREFBc0Q7QUFDdEQsdURBQXFEO0FBQ3JELHlDQUFpQztBQUNqQyw4REFTa0M7QUFDbEMsa0RBSzRCO0FBQzVCLCtDQUE2RTtBQUM3RSwwREFBeUQ7QUFrQnpELDhDQUE4QztBQUM5QyxTQUFnQixxQkFBcUI7SUFDbkMsT0FBTztRQUNMLFVBQVUsRUFBRSxPQUFPLENBQUMsR0FBRyxDQUFDLDRCQUE0QixJQUFJLEVBQUU7UUFDMUQsU0FBUyxFQUFFLE9BQU8sQ0FBQyxHQUFHLENBQUMsa0NBQWtDLElBQUksRUFBRTtRQUMvRCxNQUFNLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksV0FBVztRQUM3QyxPQUFPLEVBQUUsT0FBTyxDQUFDLEdBQUcsQ0FBQyxtQkFBbUIsSUFBSSxFQUFFO0tBQy9DLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBZ0IsVUFBVSxDQUFDLE9BQWUsRUFBRSxRQUFnQjtJQUMxRCxPQUFPLElBQUEsZ0JBQUksRUFBQyxPQUFPLEVBQUUsSUFBQSw4QkFBZ0IsRUFBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0FBQ25ELENBQUM7QUFFRCxtRkFBbUY7QUFDbkYsU0FBZ0IsV0FBVyxDQUFDLE9BQWUsRUFBRSxRQUFnQjtJQUMzRCxPQUFPLElBQUEsZ0JBQUksRUFBQyxPQUFPLEVBQUUsSUFBQSw2QkFBZSxFQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7QUFDbEQsQ0FBQztBQUVEOzs7R0FHRztBQUNVLFFBQUEsb0JBQW9CLEdBQUcsWUFBWSxDQUFDO0FBRWpEOzs7Ozs7Ozs7O0dBVUc7QUFDSCxTQUFnQixhQUFhLENBQUMsT0FBZSxFQUFFLE9BQWU7SUFDNUQsT0FBTyxJQUFBLGdCQUFJLEVBQUMsT0FBTyxFQUFFLDRCQUFvQixFQUFFLEdBQUcsT0FBTyxRQUFRLENBQUMsQ0FBQztBQUNqRSxDQUFDO0FBK0JEOzs7OztHQUtHO0FBQ0gsU0FBZ0IsV0FBVyxDQUN6QixNQUFpQixFQUNqQixTQUFpQixFQUNqQixHQUFXO0lBRVgsTUFBTSxFQUFFLGFBQWEsRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLEdBQUcsTUFBTSxDQUFDO0lBQ3JELElBQ0UsQ0FBQyxhQUFhLEtBQUssU0FBUyxJQUFJLGFBQWEsR0FBRyxTQUFTLENBQUM7UUFDMUQsQ0FBQyxTQUFTLEtBQUssU0FBUyxJQUFJLFNBQVMsSUFBSSxHQUFHLElBQUksU0FBUyxHQUFHLFNBQVMsQ0FBQyxFQUN0RSxDQUFDO1FBQ0QsT0FBTyxTQUFTLENBQUM7SUFDbkIsQ0FBQztJQUNELElBQUksT0FBTyxLQUFLLFNBQVMsSUFBSSxPQUFPLEdBQUcsU0FBUyxFQUFFLENBQUM7UUFDakQsT0FBTyxPQUFPLENBQUM7SUFDakIsQ0FBQztJQUNELE9BQU8sT0FBTyxDQUFDO0FBQ2pCLENBQUM7QUFFRDs7Ozs7Ozs7R0FRRztBQUNILFNBQWdCLFdBQVc7SUFDekIsT0FBTyxXQUFXLENBQUMsVUFBVSxHQUFHLFdBQVcsQ0FBQyxHQUFHLEVBQUUsQ0FBQztBQUNwRCxDQUFDO0FBRUQ7Ozs7Ozs7O0dBUUc7QUFDSCxTQUFnQixTQUFTLENBQ3ZCLEdBQVcsRUFDWCxTQUEwQztJQUUxQyxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7UUFDZixPQUFPLEVBQUUsYUFBYSxFQUFFLEdBQUcsRUFBRSxDQUFDO0lBQ2hDLENBQUM7SUFDRCxJQUFJLFNBQVMsQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7UUFDbkMsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQztJQUMxQixDQUFDO0lBQ0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxHQUFHLEVBQUUsU0FBUyxFQUFFLEdBQUcsR0FBRyxTQUFTLENBQUMsTUFBTSxHQUFHLElBQUksRUFBRSxDQUFDO0FBQ3BFLENBQUM7QUFFRCxNQUFNLGFBQWEsR0FBRyxDQUFDLGVBQWUsRUFBRSxTQUFTLEVBQUUsV0FBVyxDQUFVLENBQUM7QUFFekU7OztHQUdHO0FBQ0gsU0FBZ0IsV0FBVyxDQUN6QixRQUErQixFQUMvQixNQUFpQjtJQUVqQixNQUFNLE1BQU0sR0FBRyxFQUFFLEdBQUcsUUFBUSxFQUFFLENBQUM7SUFDL0IsS0FBSyxNQUFNLEtBQUssSUFBSSxhQUFhLEVBQUUsQ0FBQztRQUNsQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxTQUFTLEVBQUUsQ0FBQztZQUNoQyxNQUFNLENBQUMsS0FBSyxDQUFDLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ2hDLENBQUM7SUFDSCxDQUFDO0lBQ0QsT0FBTyxNQUFNLENBQUM7QUFDaEIsQ0FBQztBQUVELGtFQUFrRTtBQUNsRSxTQUFnQixZQUFZLENBQzFCLEdBQVcsRUFDWCxTQUEwQztJQUsxQyxNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQyxDQUFDO0lBQ3pDLE1BQU0sTUFBTSxHQUFHLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxTQUFTLENBQUMsQ0FBQztJQUM1RSxPQUFPO1FBQ0wsZ0JBQWdCLEVBQUUsT0FBTyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxHQUFHLEtBQUssT0FBTyxLQUFLLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUNuRix5QkFBeUIsRUFBRSxNQUFNLENBQUMsV0FBVyxDQUMzQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLElBQUksS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUNuRTtLQUNGLENBQUM7QUFDSixDQUFDO0FBRUQsMkVBQTJFO0FBQzNFLFNBQVMsZUFBZSxDQUN0QixLQUFpQztJQUVqQyxPQUFPLEtBQUssRUFBRSxDQUFDLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7QUFDOUQsQ0FBQztBQUVELGdEQUFnRDtBQUNoRCxTQUFTLFFBQVEsQ0FBQyxJQUFvQztJQUNwRCxPQUFPO1FBQ0wsYUFBYSxFQUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO1FBQ2xELE9BQU8sRUFBRSxlQUFlLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQztRQUN0QyxTQUFTLEVBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUM7S0FDM0MsQ0FBQztBQUNKLENBQUM7QUFFRCxvREFBb0Q7QUFDdkMsUUFBQSxrQkFBa0IsR0FBRyxHQUFHLENBQUM7QUFFdEM7Ozs7Ozs7O0dBUUc7QUFDVSxRQUFBLHNCQUFzQixHQUFHLElBQUksQ0FBQztBQUUzQzs7Ozs7R0FLRztBQUNVLFFBQUEsb0JBQW9CLEdBQUcsSUFBSSxDQUFDO0FBRXpDLHNEQUFzRDtBQUN6QyxRQUFBLGtCQUFrQixHQUFHLElBQUksQ0FBQztBQUV2Qzs7Ozs7R0FLRztBQUNILFNBQWdCLFNBQVMsQ0FBQyxHQUFXO0lBQ25DLE9BQU8sSUFBSSxJQUFBLHVCQUFTLEVBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztBQUM5QixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ1UsUUFBQSxhQUFhLEdBQUcsR0FBRyxDQUFDO0FBRWpDLDhGQUE4RjtBQUM5RixTQUFnQixVQUFVLENBQUMsR0FBVztJQUNwQyxPQUFPLE1BQU0sQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUkscUJBQWEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7QUFDeEUsQ0FBQztBQUVEOzs7Ozs7Ozs7R0FTRztBQUNILE1BQWEsY0FBYztJQUVOO0lBQ0E7SUFDQTtJQUhuQixZQUNtQixNQUFzQixFQUN0QixTQUFpQixFQUNqQixPQUFlO1FBRmYsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUFDdEIsY0FBUyxHQUFULFNBQVMsQ0FBUTtRQUNqQixZQUFPLEdBQVAsT0FBTyxDQUFRO0lBQy9CLENBQUM7SUFFSjs7Ozs7O09BTUc7SUFDSCxLQUFLLENBQUMsS0FBSyxDQUNULEdBQVcsRUFDWCxHQUFXLEVBQ1gsU0FBMEM7UUFFMUMsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDckMsSUFBSSxtQ0FBaUIsQ0FBQztZQUNwQixTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVM7WUFDekIsR0FBRyxFQUFFO2dCQUNILEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsT0FBTyxFQUFFO2dCQUN2QixFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFO2FBQzNCO1lBQ0QsR0FBRyxZQUFZLENBQUMsR0FBRyxFQUFFLFNBQVMsQ0FBQztZQUMvQixZQUFZLEVBQUUsU0FBUztTQUN4QixDQUFDLENBQ0gsQ0FBQztRQUNGLE9BQU8sUUFBUSxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQzFFLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxLQUFLLENBQUMsSUFBSSxDQUFDLElBQWM7UUFDdkIsTUFBTSxFQUFFLFNBQVMsRUFBRSxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDcEMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLE1BQU0sT0FBTyxHQUFHLElBQUksR0FBRyxFQUFxQixDQUFDO1FBRTdDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsSUFBSSwwQkFBa0IsRUFBRSxDQUFDO1lBQzNELHNFQUFzRTtZQUN0RSxNQUFNLE9BQU8sR0FBRyxJQUFJLEdBQUcsQ0FDckIsTUFBTTtpQkFDSCxLQUFLLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRywwQkFBa0IsQ0FBQztpQkFDaEMsR0FBRyxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUN4QyxDQUFDO1lBQ0YsSUFBSSxJQUFJLEdBQWlELEtBQUssQ0FBQyxJQUFJLENBQ2pFLE9BQU8sQ0FBQyxJQUFJLEVBQUUsRUFDZCxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUNoRCxDQUFDO1lBQ0Ysd0VBQXdFO1lBQ3hFLHVFQUF1RTtZQUN2RSxLQUFLLElBQUksT0FBTyxHQUFHLENBQUMsRUFBRSxJQUFJLEVBQUUsTUFBTSxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsT0FBTyxFQUFFLEVBQUUsQ0FBQztnQkFDN0QsTUFBTSxRQUFRLEdBQThCLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ2hFLElBQUkscUNBQW1CLENBQUM7b0JBQ3RCLFlBQVksRUFBRTt3QkFDWixDQUFDLFNBQVMsQ0FBQyxFQUFFOzRCQUNYLElBQUksRUFBRSxJQUFJOzRCQUNWLG9CQUFvQixFQUFFLHVDQUF1Qzt5QkFDOUQ7cUJBQ0Y7aUJBQ0YsQ0FBQyxDQUNILENBQUM7Z0JBQ0YsS0FBSyxNQUFNLElBQUksSUFBSSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxFQUFFLENBQUM7b0JBQ3pELE1BQU0sR0FBRyxHQUFHLE9BQU8sQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7b0JBQzFDLElBQUksR0FBRyxLQUFLLFNBQVMsRUFBRSxDQUFDO3dCQUN0QixPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDbkMsQ0FBQztnQkFDSCxDQUFDO2dCQUNELElBQUksR0FBRyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUMsU0FBUyxDQUFDLEVBQUUsSUFBSSxDQUFDO1lBQ3JELENBQUM7WUFDRCxJQUFJLElBQUksRUFBRSxNQUFNLEVBQUUsQ0FBQztnQkFDakIsTUFBTSxJQUFJLEtBQUssQ0FDYixpQkFBaUIsSUFBSSxDQUFDLE1BQU0sb0NBQW9DLENBQ2pFLENBQUM7WUFDSixDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sT0FBTyxDQUFDO0lBQ2pCLENBQUM7Q0FDRjtBQXJGRCx3Q0FxRkM7QUFFRDs7Ozs7R0FLRztBQUNVLFFBQUEsdUJBQXVCLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFdEQsc0VBQXNFO0FBQ3pELFFBQUEsMEJBQTBCLEdBQUcsQ0FBQyxDQUFDO0FBRTVDLDZFQUE2RTtBQUM3RSxNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztBQUUzQixpRkFBaUY7QUFDakYsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFDO0FBYXpCOzs7Ozs7Ozs7Ozs7Ozs7O0dBZ0JHO0FBQ0gsTUFBYSxlQUFlO0lBSVA7SUFDQTtJQUpGLEVBQUUsQ0FBUztJQUU1QixZQUNtQixNQUFzQixFQUN0QixTQUFpQixFQUNsQyxPQUFlO1FBRkUsV0FBTSxHQUFOLE1BQU0sQ0FBZ0I7UUFDdEIsY0FBUyxHQUFULFNBQVMsQ0FBUTtRQUdsQyxJQUFJLENBQUMsRUFBRSxHQUFHLEdBQUcsT0FBTyxNQUFNLENBQUM7SUFDN0IsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQVcsRUFBRSxFQUFVLEVBQUUsTUFBaUI7UUFDbEQsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzlCLEtBQUssSUFBSSxPQUFPLEdBQUcsQ0FBQyxHQUFJLE9BQU8sRUFBRSxFQUFFLENBQUM7WUFDbEMsTUFBTSxJQUFJLEdBQW1DO2dCQUMzQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtnQkFDbEIsRUFBRSxFQUFFLEVBQUUsQ0FBQyxFQUFFLEdBQUcsV0FBVyxDQUFDLEVBQUUsQ0FBQyxJQUFJLEtBQUssRUFBRSxFQUFFO2dCQUN4QyxHQUFHLEVBQUUsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFFLEdBQUcsK0JBQXVCLENBQUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxFQUFFO2dCQUNwRSxHQUFHLENBQUMsS0FBSyxLQUFLLEdBQUcsSUFBSSxFQUFFLE9BQU8sRUFBRSxFQUFFLENBQUMsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDO2FBQzlDLENBQUM7WUFDRixLQUFLLE1BQU0sS0FBSyxJQUFJLGFBQWEsRUFBRSxDQUFDO2dCQUNsQyxNQUFNLEtBQUssR0FBRyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQzVCLElBQUksS0FBSyxLQUFLLFNBQVMsRUFBRSxDQUFDO29CQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3JDLENBQUM7WUFDSCxDQUFDO1lBQ0QsSUFBSSxDQUFDO2dCQUNILE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3BCLElBQUksZ0NBQWMsQ0FBQztvQkFDakIsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO29CQUN6QixJQUFJLEVBQUUsSUFBSTtvQkFDVixtQkFBbUIsRUFBRSwwQkFBMEI7aUJBQ2hELENBQUMsQ0FDSCxDQUFDO2dCQUNGLE9BQU87WUFDVCxDQUFDO1lBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztnQkFDZixJQUNHLEtBQTJCLEVBQUUsSUFBSTtvQkFDaEMsaUNBQWlDO29CQUNuQyxPQUFPLElBQUksZ0JBQWdCLEVBQzNCLENBQUM7b0JBQ0QsTUFBTSxLQUFLLENBQUM7Z0JBQ2QsQ0FBQztnQkFDRCxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDMUIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxLQUFLLENBQ1QsS0FBYTtRQUViLE1BQU0sSUFBSSxHQUF5QixFQUFFLENBQUM7UUFDdEMsSUFBSSxRQUFvRCxDQUFDO1FBQ3pELEtBQUssSUFBSSxJQUFJLEdBQUcsQ0FBQyxFQUFFLElBQUksR0FBRyxrQ0FBMEIsRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQzdELE1BQU0sUUFBUSxHQUF1QixNQUFNLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUN6RCxJQUFJLDhCQUFZLENBQUM7Z0JBQ2YsU0FBUyxFQUFFLElBQUksQ0FBQyxTQUFTO2dCQUN6QixzQkFBc0IsRUFBRSwyQkFBMkI7Z0JBQ25ELHlCQUF5QixFQUFFO29CQUN6QixLQUFLLEVBQUUsRUFBRSxDQUFDLEVBQUUsSUFBSSxDQUFDLEVBQUUsRUFBRTtvQkFDckIsUUFBUSxFQUFFLEVBQUUsQ0FBQyxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLENBQUMsQ0FBQyxFQUFFO2lCQUNqRDtnQkFDRCxvQkFBb0IsRUFDbEIsZ0RBQWdEO2dCQUNsRCxpQkFBaUIsRUFBRSxRQUFRO2FBQzVCLENBQUMsQ0FDSCxDQUFDO1lBQ0YsS0FBSyxNQUFNLElBQUksSUFBSSxRQUFRLENBQUMsS0FBSyxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUN4QyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQztnQkFDdEIsZ0VBQWdFO2dCQUNoRSw0QkFBNEI7Z0JBQzVCLElBQUksRUFBRSxLQUFLLFNBQVMsSUFBSSxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssR0FBRyxFQUFFLENBQUM7b0JBQ2xELFNBQVM7Z0JBQ1gsQ0FBQztnQkFDRCxJQUFJLENBQUMsSUFBSSxDQUFDO29CQUNSLEVBQUU7b0JBQ0YsRUFBRSxFQUFFLE1BQU0sQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxhQUFhLENBQUMsQ0FBQztvQkFDdEMsR0FBRyxFQUFFLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxLQUFLLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQztvQkFDbkQsTUFBTSxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUM7aUJBQ3ZCLENBQUMsQ0FBQztZQUNMLENBQUM7WUFDRCxRQUFRLEdBQUcsUUFBUSxDQUFDLGdCQUFnQixDQUFDO1lBQ3JDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztnQkFDZCxPQUFPLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsQ0FBQztZQUNwQyxDQUFDO1FBQ0gsQ0FBQztRQUNELE9BQU8sRUFBRSxJQUFJLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxDQUFDO0lBQ25DLENBQUM7Q0FDRjtBQXhHRCwwQ0F3R0M7QUFFRCxTQUFTLFdBQVcsQ0FBQyxFQUFVO0lBQzdCLE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsYUFBYSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0FBQzdELENBQUM7QUFFRDs7Ozs7R0FLRztBQUNVLFFBQUEsNEJBQTRCLEdBQUcsSUFBSSxDQUFDO0FBRWpEOzs7Ozs7Ozs7Ozs7Ozs7OztHQWlCRztBQUNVLFFBQUEscUJBQXFCLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7QUFFcEQsaUZBQWlGO0FBQ2pGLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDO0FBRS9COzs7Ozs7R0FNRztBQUNVLFFBQUEsMkJBQTJCLEdBQ3RDLCtCQUF1QixHQUFHLENBQUMsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO0FBRTFDOzs7Ozs7Ozs7O0dBVUc7QUFDVSxRQUFBLHdCQUF3QixHQUFHLE1BQU0sQ0FBQztBQW1DL0M7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBZ0NHO0FBQ0gsTUFBYSxpQkFBaUI7SUFDWCxPQUFPLENBQTZCO0lBQ3BDLEdBQUcsQ0FBOEI7SUFDakMsaUJBQWlCLENBQVM7SUFDMUIsY0FBYyxDQUFTO0lBQ3ZCLGdCQUFnQixDQUFTO0lBQ3pCLEtBQUssQ0FBZTtJQUNwQixNQUFNLENBQWU7SUFDckIsS0FBSyxDQUE0QjtJQUNsRCx5Q0FBeUM7SUFDeEIsSUFBSSxHQUFHLElBQUksR0FBRyxFQUFxQixDQUFDO0lBQ3JEOzs7O09BSUc7SUFDYyxLQUFLLEdBQUcsSUFBSSxHQUFHLEVBQWtCLENBQUM7SUFDbEMsT0FBTyxHQUFHLElBQUksR0FBRyxFQUF5QixDQUFDO0lBQzVEOzs7O09BSUc7SUFDYyxXQUFXLEdBQUcsSUFBSSxHQUFHLEVBQXFCLENBQUM7SUFDNUQ7Ozs7T0FJRztJQUNjLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBcUIsQ0FBQztJQUN4RCxpQ0FBaUM7SUFDekIsS0FBSyxDQUFTO0lBQ3RCOzs7OztPQUtHO0lBQ2MsV0FBVyxHQUF1QixFQUFFLENBQUM7SUFDdEQsa0VBQWtFO0lBQ2pELFdBQVcsR0FHdEIsRUFBRSxDQUFDO0lBQ1Qsa0ZBQWtGO0lBQzFFLFNBQVMsR0FBRyxDQUFDLENBQUM7SUFDdEIsMEVBQTBFO0lBQ3pELE1BQU0sR0FBRyxJQUFJLEdBQUcsRUFBVSxDQUFDO0lBQzVDOzs7T0FHRztJQUNjLGNBQWMsR0FBRyxJQUFJLG9DQUFpQixFQUFRLENBQUM7SUFDaEUsdUVBQXVFO0lBQy9ELGFBQWEsR0FBRyxDQUFDLFFBQVEsQ0FBQztJQUNsQzs7OztPQUlHO0lBQ0ssYUFBYSxHQUFHLENBQUMsUUFBUSxDQUFDO0lBQ2xDLHFEQUFxRDtJQUM3QyxXQUFXLEdBQUcsQ0FBQyxRQUFRLENBQUM7SUFDaEM7Ozs7O09BS0c7SUFDSyxVQUFVLENBQTRCO0lBQzlDOzs7O09BSUc7SUFDSyxRQUFRLEdBQUcsQ0FBQyxRQUFRLENBQUM7SUFDN0IsaUVBQWlFO0lBQ3pELHFCQUFxQixHQUFHLEtBQUssQ0FBQztJQUM5QixNQUFNLENBQTZDO0lBQzFDLFNBQVMsQ0FBVTtJQUNwQzs7O09BR0c7SUFDSyxTQUFTLENBQVM7SUFDMUI7OztPQUdHO0lBQ0ssTUFBTSxDQUFTO0lBQ3ZCLDZFQUE2RTtJQUNyRSxXQUFXLENBQVM7SUFDNUIsb0VBQW9FO0lBQ25ELE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUNyRCwrREFBK0Q7SUFDOUMsUUFBUSxHQUFHLElBQUksR0FBRyxFQUE0QixDQUFDO0lBRWhFLFlBQVksT0FBaUM7UUFDM0MsSUFBSSxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsT0FBTyxDQUFDO1FBQy9CLElBQUksQ0FBQyxHQUFHLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQztRQUN2QixJQUFJLENBQUMsaUJBQWlCO1lBQ3BCLE9BQU8sQ0FBQyxpQkFBaUIsSUFBSSw4QkFBc0IsQ0FBQztRQUN0RCxJQUFJLENBQUMsY0FBYyxHQUFHLE9BQU8sQ0FBQyxjQUFjLElBQUksZ0NBQXdCLENBQUM7UUFDekUsSUFBSSxDQUFDLGdCQUFnQixHQUFHLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSw2QkFBcUIsQ0FBQztRQUMxRSx3RUFBd0U7UUFDeEUsZUFBZTtRQUNmLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzVDLElBQUksQ0FBQyxLQUFLLEdBQUcsT0FBTyxDQUFDLEtBQUssSUFBSSxDQUFDLEdBQUcsRUFBRSxHQUFFLENBQUMsQ0FBQyxDQUFDO1FBQ3pDLElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDLFNBQVMsSUFBSSxLQUFLLENBQUM7UUFDNUMsMEVBQTBFO1FBQzFFLHVEQUF1RDtRQUN2RCxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDeEIsSUFBSSxDQUFDLE1BQU0sR0FBRyxFQUFFLEdBQUcsb0NBQTRCLENBQUM7UUFDaEQsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLEtBQUssR0FBRyxXQUFXLEVBQUUsQ0FBQztJQUM3QixDQUFDO0lBRUQsb0VBQW9FO0lBQ3BFLEdBQUcsQ0FBQyxHQUFXO1FBQ2IsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM1QixDQUFDO0lBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7T0F5Qkc7SUFDSCxJQUFJLGFBQWE7UUFDZixNQUFNLEVBQUUsR0FBRyxXQUFXLEVBQUUsQ0FBQztRQUN6QixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDO1lBQ25FLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNsRSxDQUFDO1FBQ0QsT0FBTyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3BCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxjQUFjLENBQ1osZUFBMEMsRUFDMUMsV0FBMEIsR0FBRyxFQUFFLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxHQUFHLFFBQVE7UUFFakUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxlQUFlLEVBQUUsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUN2RCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsR0FBRyxDQUFDLEdBQVcsRUFBRSxNQUFpQjtRQUNoQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QixJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsRUFBRSxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDakQsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUM7SUFDaEMsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7O09BYUc7SUFDSCxLQUFLLENBQUMsSUFBdUI7UUFDM0IsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3ZCLE9BQU87UUFDVCxDQUFDO1FBQ0QsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2xCLENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssV0FBVyxDQUFDLElBQXVCO1FBQ3pDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUN4QixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ3ZCLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUN0QixDQUFDO1lBQ0QsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksRUFBRSxDQUFDLENBQUM7UUFDL0MsQ0FBQztJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLE1BQU0sQ0FBQyxJQUF1QjtRQUNsQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ2xCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDdkIsT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLEtBQUssR0FBb0IsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sTUFBTSxHQUFhLEVBQUUsQ0FBQztRQUM1QixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDaEMscUVBQXFFO1lBQ3JFLDREQUE0RDtZQUM1RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUN2QyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbEIsQ0FBQztpQkFBTSxJQUFJLFFBQVEsRUFBRSxDQUFDO2dCQUNwQixLQUFLLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ3ZCLENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ25CLENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQ3RCLEtBQUssQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFDRCxNQUFNLE9BQU8sQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDM0IsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxTQUFTLENBQUMsSUFBYztRQUM5QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUU7WUFDekMsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDM0IsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUIsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7OztPQWNHO0lBQ0gsSUFBSSxNQUFNO1FBQ1IsT0FBTyxDQUNMLElBQUksQ0FBQyxHQUFHLEtBQUssU0FBUztZQUN0QixvRUFBb0U7WUFDcEUsQ0FBQyxJQUFJLENBQUMsaUJBQWlCLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQy9ELENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsSUFBSSxjQUFjO1FBQ2hCLE9BQU8sSUFBSSxDQUFDLGlCQUFpQixLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRTtZQUNuRSxDQUFDLENBQUMsS0FBSztZQUNQLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDO0lBQ2xCLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxJQUFJLFlBQVk7UUFDZCxPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUM1RCxDQUFDO0lBRUQ7Ozs7Ozs7OztPQVNHO0lBQ0gsS0FBSyxDQUFDLE9BQU8sQ0FBSSxNQUF3QjtRQUN2QyxNQUFNLEdBQUcsR0FBRyxDQUFDLEtBQWMsRUFBRSxFQUFFLENBQzdCLE9BQU8sQ0FBQyxLQUFLLENBQUMsOEJBQThCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDdkQsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUM5QyxJQUFJLENBQUMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUN2QixvRUFBb0U7Z0JBQ3BFLDhEQUE4RDtnQkFDOUQsT0FBTyxNQUFNLEVBQUUsQ0FBQztZQUNsQixDQUFDO1lBQ0QsTUFBTSxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7YUFBTSxJQUFJLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUN0QyxxRUFBcUU7WUFDckUsc0VBQXNFO1lBQ3RFLG1DQUFtQztZQUNuQyxLQUFLLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDakMsQ0FBQztRQUNELE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILGFBQWEsQ0FBSSxFQUFXO1FBQzFCLE1BQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDaEQsT0FBTyxJQUFBLDZCQUFjLEVBQUMsR0FBRyxFQUFFLENBQ3pCLFFBQVEsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLGNBQWMsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FDeEQsQ0FBQztJQUNKLENBQUM7SUFFRCxnRUFBZ0U7SUFDeEQsT0FBTyxDQUFDLEVBQVU7UUFDeEIsT0FBTyxJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsR0FBRyw0QkFBb0IsQ0FBQztJQUMzRSxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLE9BQU87UUFDWCxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDO1FBQ3JCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNULE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7WUFDcEIsb0VBQW9FO1lBQ3BFLHNFQUFzRTtZQUN0RSw2REFBNkQ7WUFDN0QsSUFBSSxJQUFJLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxFQUFFLENBQUM7Z0JBQ3BELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7WUFDcEQsQ0FBQztZQUNELE9BQU8sSUFBSSxDQUFDLFVBQVUsQ0FBQztRQUN6QixDQUFDO1FBQ0QsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDbkQsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztRQUN0Qix5RUFBeUU7UUFDekUsd0VBQXdFO1FBQ3hFLHlFQUF5RTtRQUN6RSx5RUFBeUU7UUFDekUsdUVBQXVFO1FBQ3ZFLFlBQVk7UUFDWixJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMxRCxPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUNwQixJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxHQUFHLEVBQUU7WUFDaEQscUVBQXFFO1lBQ3JFLHNFQUFzRTtZQUN0RSw4REFBOEQ7WUFDOUQsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUN2QixJQUFJLENBQUMsU0FBUyxFQUNkLElBQUksQ0FBQyx5QkFBeUIsRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQ25FLENBQUM7WUFDRixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxTQUFTLENBQUM7UUFDOUIsQ0FBQyxDQUFDLENBQUM7UUFDSCxPQUFPLElBQUksQ0FBQyxVQUFVLENBQUM7SUFDekIsQ0FBQztJQUVPLFlBQVk7UUFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztZQUNwQixPQUFPO1FBQ1QsQ0FBQztRQUNELElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQzdCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7UUFDbkMsSUFBSSxDQUFDLE1BQU0sR0FBRyxXQUFXLENBQUMsR0FBRyxFQUFFO1lBQzdCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN4QixJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLGdCQUFnQixFQUFFLENBQUM7Z0JBQzFDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7WUFDcEMsQ0FBQztZQUNELElBQUksQ0FBQyxRQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ3JCLENBQUMsRUFBRSxlQUFlLENBQUMsQ0FBQztRQUNwQixvQ0FBb0M7UUFDcEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFTyxXQUFXO1FBQ2pCLGFBQWEsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0IsSUFBSSxDQUFDLE1BQU0sR0FBRyxTQUFTLENBQUM7SUFDMUIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSyx5QkFBeUI7UUFDL0IsT0FBTyxDQUNMLElBQUksQ0FBQyxTQUFTO1lBQ2QsQ0FBQyxJQUFJLENBQUMscUJBQXFCO2dCQUN6QixJQUFJLENBQUMsS0FBSyxFQUFFLEdBQUcsSUFBSSxDQUFDLFFBQVEsR0FBRyxnQkFBZ0IsQ0FBQyxDQUNuRCxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7Ozs7Ozs7T0FZRztJQUNILEtBQUssQ0FBQyxNQUFNLENBQ1YsSUFBdUIsRUFDdkIsU0FBMEM7UUFFMUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDLElBQUksRUFBRSxTQUFTLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztRQUN0RCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN4QyxJQUFJLFFBQVEsRUFBRSxDQUFDO1lBQ2IsT0FBTyxRQUFRLENBQUM7UUFDbEIsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1FBQzNDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMvQixnRUFBZ0U7UUFDaEUsS0FBSyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDN0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyxJQUF1QixFQUFFLFNBQWlCO1FBQzlDLDRFQUE0RTtRQUM1RSw2RUFBNkU7UUFDN0UsZ0VBQWdFO1FBQ2hFLHNFQUFzRTtRQUN0RSxNQUFNLEVBQUUsR0FBRyxXQUFXLEVBQUUsQ0FBQztRQUN6QixJQUFJLEtBQUssR0FBc0IsT0FBTyxDQUFDO1FBQ3ZDLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7WUFDdkIsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNyQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7Z0JBQ1osU0FBUztZQUNYLENBQUM7WUFDRCxNQUFNLFFBQVEsR0FBRyxXQUFXLENBQUMsTUFBTSxFQUFFLFNBQVMsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUNwRCxJQUFJLFFBQVEsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDM0IsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUNELElBQUksUUFBUSxLQUFLLE9BQU8sRUFBRSxDQUFDO2dCQUN6QixLQUFLLEdBQUcsT0FBTyxDQUFDO1lBQ2xCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxVQUFVLENBQUMsSUFBdUI7UUFDaEMsTUFBTSxFQUFFLEdBQUcsV0FBVyxFQUFFLENBQUM7UUFDekIsSUFBSSxNQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ2YsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3JDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztnQkFDWixTQUFTO1lBQ1gsQ0FBQztZQUNELElBQUksTUFBTSxDQUFDLGFBQWEsS0FBSyxTQUFTLEVBQUUsQ0FBQztnQkFDdkMsTUFBTSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNsRCxDQUFDO1lBQ0QsSUFBSSxNQUFNLENBQUMsU0FBUyxLQUFLLFNBQVMsSUFBSSxNQUFNLENBQUMsU0FBUyxJQUFJLEVBQUUsRUFBRSxDQUFDO2dCQUM3RCxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBQzlDLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxNQUFNLENBQUM7SUFDaEIsQ0FBQztJQUVPLEtBQUssQ0FBQyxLQUFLLENBQ2pCLElBQXVCLEVBQ3ZCLFNBQTBDO1FBRTFDLE1BQU0sRUFBRSxHQUFHLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLE1BQU0sTUFBTSxHQUFHLFNBQVMsQ0FBQyxFQUFFLEVBQUUsU0FBUyxDQUFDLENBQUM7UUFDeEMsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztZQUN2QixJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxXQUFXLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxNQUFNLENBQUMsQ0FBQyxDQUFDO1FBQ3BELENBQUM7UUFDRCxNQUFNLEVBQUUsT0FBTyxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQztRQUM5QixJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7WUFDckIsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsTUFBTSxNQUFNLEdBQWlDLEVBQUUsQ0FBQztRQUNoRCxLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDaEMsTUFBTSxDQUFDLElBQUksQ0FBQztnQkFDVix3Q0FBd0M7Z0JBQ3hDLGtFQUFrRTtnQkFDbEUsaUVBQWlFO2dCQUNqRSxzRUFBc0U7Z0JBQ3RFLDhCQUE4QjtnQkFDOUIsT0FBTyxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxFQUFFLFNBQVMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFO29CQUM3QyxJQUFJLEdBQUcsRUFBRSxDQUFDO3dCQUNSLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUM7b0JBQ2xELENBQUM7Z0JBQ0gsQ0FBQyxDQUFDO2FBQ0gsQ0FBQyxDQUFDO1lBQ0gsTUFBTSxDQUFDLElBQUksQ0FBQztnQkFDVix5Q0FBeUM7Z0JBQ3pDLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxNQUFNLENBQUM7YUFDakMsQ0FBQyxDQUFDO1FBQ0wsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFHLE1BQU0sT0FBTyxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO1FBQzNFLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7WUFDNUIsSUFBSSxNQUFNLENBQUMsTUFBTSxLQUFLLFVBQVUsRUFBRSxDQUFDO2dCQUNqQyxPQUFPLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDN0MsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsTUFBTSxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsTUFBTSxLQUFLLFdBQVcsQ0FBQyxDQUFDO0lBQ2xFLENBQUM7SUFFRDs7Ozs7Ozs7O09BU0c7SUFDSyxLQUFLLENBQUMsU0FBUyxDQUNyQixHQUFvQixFQUNwQixHQUFXLEVBQ1gsTUFBaUI7UUFFakIsS0FBSyxJQUFJLE9BQU8sR0FBRyxDQUFDLEVBQUUsT0FBTyxHQUFHLENBQUMsRUFBRSxPQUFPLEVBQUUsRUFBRSxDQUFDO1lBQzdDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUN4QixNQUFNLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLEVBQUUsRUFBRSxNQUFNLENBQUMsQ0FBQztZQUMvQixJQUFJLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLElBQUksY0FBYyxFQUFFLENBQUM7Z0JBQ3hDLE9BQU87WUFDVCxDQUFDO1FBQ0gsQ0FBQztRQUNELE1BQU0sSUFBSSxLQUFLLENBQ2IsZ0NBQWdDLEdBQUcscUNBQXFDLENBQ3pFLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0ssS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFVLEVBQUUsR0FBb0I7UUFDakQsSUFBSSxFQUFFLEdBQUcsSUFBSSxDQUFDLFdBQVcsR0FBRyxtQ0FBMkIsRUFBRSxDQUFDO1lBQ3hELElBQUksQ0FBQyxNQUFNLENBQ1QsRUFBRSxFQUNGLG1FQUFtRSxDQUNwRSxDQUFDO1lBQ0YsT0FBTztRQUNULENBQUM7UUFDRCx3RUFBd0U7UUFDeEUsbUVBQW1FO1FBQ25FLG1FQUFtRTtRQUNuRSxNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3pCLElBQUksR0FBRyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztZQUNuQixLQUFLLElBQUksQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDM0IsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUU7WUFDMUQsT0FBTyxDQUFDLEtBQUssQ0FBQyxxQ0FBcUMsRUFBRSxLQUFLLENBQUMsQ0FBQztZQUM1RCxPQUFPLFNBQVMsQ0FBQztRQUNuQixDQUFDLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNaLE9BQU87UUFDVCxDQUFDO1FBQ0QsSUFBSSxNQUFNLENBQUMsU0FBUyxFQUFFLENBQUM7WUFDckIsSUFBSSxDQUFDLE1BQU0sQ0FDVCxFQUFFLEVBQ0YseURBQXlELENBQzFELENBQUM7WUFDRixPQUFPO1FBQ1QsQ0FBQztRQUNELHlFQUF5RTtRQUN6RSxzRUFBc0U7UUFDdEUseUVBQXlFO1FBQ3pFLDJDQUEyQztRQUMzQyxNQUFNLElBQUksR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsR0FBRyxzQkFBc0IsQ0FBQztRQUM5RCxJQUFJLElBQUksRUFBRSxDQUFDO1lBQ1QsSUFBSSxDQUFDLGFBQWEsR0FBRyxFQUFFLENBQUM7UUFDMUIsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDdEMsSUFBSSxPQUFPLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLEtBQUssTUFBTSxHQUFHLElBQUksTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzlCLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUM7Z0JBQzdCLFNBQVM7WUFDWCxDQUFDO1lBQ0QsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ3RDLElBQUksTUFBTSxFQUFFLENBQUM7Z0JBQ1gsdUVBQXVFO2dCQUN2RSxzQ0FBc0M7Z0JBQ3RDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsWUFBWSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUMzRCxDQUFDO2lCQUFNLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ3JDLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUNsQixHQUFHLENBQUMsR0FBRyxFQUNQLFlBQVksQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUN4RCxDQUFDO1lBQ0osQ0FBQztpQkFBTSxDQUFDO2dCQUNOLHFFQUFxRTtnQkFDckUscUVBQXFFO2dCQUNyRSxtRUFBbUU7Z0JBQ25FLG9FQUFvRTtnQkFDcEUsdUVBQXVFO2dCQUN2RSxrRUFBa0U7Z0JBQ2xFLGtFQUFrRTtnQkFDbEUsaUVBQWlFO2dCQUNqRSxpRUFBaUU7Z0JBQ2pFLG1EQUFtRDtnQkFDbkQsRUFBRTtnQkFDRixtRUFBbUU7Z0JBQ25FLElBQUksQ0FBQyxjQUFjLENBQ2pCLEdBQUcsQ0FBQyxHQUFHLEVBQ1AsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLEVBQ25ELE1BQU0sQ0FDUCxDQUFDO2dCQUNGLFNBQVM7WUFDWCxDQUFDO1lBQ0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDakMsT0FBTyxFQUFFLENBQUM7UUFDWixDQUFDO1FBQ0QsSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ2hDLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0IsQ0FBQztRQUNELDJEQUEyRDtRQUMzRCxJQUFJLENBQUMsYUFBYSxHQUFHLE1BQU0sQ0FBQztRQUM1QixJQUFJLENBQUMsV0FBVyxHQUFHLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxvQ0FBNEIsQ0FBQyxDQUFDO1FBQ2hELElBQUksQ0FBQyxLQUFLLENBQ1IsUUFBUSxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sMkJBQTJCLE9BQU8sV0FBVyxDQUN4RSxDQUFDO0lBQ0osQ0FBQztJQUVEOzs7O09BSUc7SUFDSyxHQUFHLENBQUMsRUFBVTtRQUNwQixNQUFNLEdBQUcsR0FBYSxFQUFFLENBQUM7UUFDekIsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDOUIsSUFBSSxHQUFHLENBQUMsTUFBTSxJQUFJLDBCQUFrQjtnQkFBRSxPQUFPLEdBQUcsQ0FBQztZQUNqRCxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDM0IsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztZQUNoQixDQUFDO1FBQ0gsQ0FBQztRQUNELHNFQUFzRTtRQUN0RSxzRUFBc0U7UUFDdEUsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixHQUFHLGlCQUFpQixDQUFDO1FBQ3pELEtBQUssTUFBTSxDQUFDLEdBQUcsRUFBRSxLQUFLLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDdEMsSUFBSSxHQUFHLENBQUMsTUFBTSxJQUFJLDBCQUFrQixJQUFJLEtBQUssR0FBRyxNQUFNLEdBQUcsRUFBRSxFQUFFLENBQUM7Z0JBQzVELE1BQU07WUFDUixDQUFDO1lBQ0QsSUFBSSxLQUFLLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNuRSxHQUFHLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ2hCLENBQUM7UUFDSCxDQUFDO1FBQ0QsT0FBTyxHQUFHLENBQUM7SUFDYixDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLE1BQU0sQ0FBQyxFQUFVLEVBQUUsR0FBVztRQUNwQyxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLGtCQUFrQixHQUFHLEVBQUUsQ0FBQyxDQUFDO1FBQ2hFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztRQUNqQixtRUFBbUU7UUFDbkUsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDeEMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQixDQUFDO1FBQ0QsS0FBSyxNQUFNLE1BQU0sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUM7WUFDM0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQixDQUFDO1FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNsQixJQUFJLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ25CLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDcEIsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNyQixJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3JCLHVFQUF1RTtRQUN2RSxJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsQ0FBQyxDQUFDO1FBQ2pELElBQUksQ0FBQyxNQUFNLEdBQUcsRUFBRSxHQUFHLG9DQUE0QixDQUFDO1FBQ2hELElBQUksQ0FBQyxXQUFXLEdBQUcsRUFBRSxDQUFDO0lBQ3hCLENBQUM7SUFFRDs7O09BR0c7SUFDSyxPQUFPLENBQUMsTUFBYztRQUM1QixJQUFJLE1BQU0sSUFBSSxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDMUIsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixLQUFLLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3BDLElBQUksRUFBRSxHQUFHLE1BQU0sRUFBRSxDQUFDO2dCQUNoQixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUMxQixDQUFDO1FBQ0gsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQWMsRUFBRSxLQUFLLEdBQUcsS0FBSztRQUNsRCxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDdEIsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQ0QsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3hCLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUM7UUFDakMsSUFBSSxDQUFDO1lBQ0gsTUFBTSxJQUFJLEdBQUcsTUFBTSxJQUFJLENBQUMsT0FBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUM1QyxJQUFJLElBQUksQ0FBQyxTQUFTLEtBQUssU0FBUyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7Z0JBQzNDLGlFQUFpRTtnQkFDakUsaUVBQWlFO2dCQUNqRSxtRUFBbUU7Z0JBQ25FLG1FQUFtRTtnQkFDbkUsa0VBQWtFO2dCQUNsRSxnRUFBZ0U7Z0JBQ2hFLE9BQU8sTUFBTSxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztZQUN6QyxDQUFDO1lBQ0QsS0FBSyxNQUFNLEdBQUcsSUFBSSxJQUFJLEVBQUUsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxRQUFRLENBQ1gsR0FBRyxFQUNILFlBQVksQ0FDVixZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUMvQyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUMxQixDQUNGLENBQUM7Z0JBQ0YsSUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDdEIsQ0FBQztZQUNELElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxJQUFJLENBQUMsTUFBTSxpQkFBaUIsSUFBSSxDQUFDLElBQUksT0FBTyxDQUFDLENBQUM7WUFDakUsT0FBTyxJQUFJLENBQUM7UUFDZCxDQUFDO1FBQUMsT0FBTyxLQUFLLEVBQUUsQ0FBQztZQUNmLE9BQU8sQ0FBQyxLQUFLLENBQUMsNEJBQTRCLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDbkQsSUFBSSxJQUFJLENBQUMsU0FBUyxLQUFLLFNBQVMsSUFBSSxDQUFDLEtBQUssRUFBRSxDQUFDO2dCQUMzQyxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ25DLENBQUM7WUFDRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ3ZCLEtBQUssTUFBTSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7Z0JBQ3ZCLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUNyQixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxDQUFDO2dCQUMxQyxJQUFJLE9BQU8sRUFBRSxDQUFDO29CQUNaLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxFQUFFLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUNoRSxDQUFDO1lBQ0gsQ0FBQztZQUNELE9BQU8sS0FBSyxDQUFDO1FBQ2YsQ0FBQztJQUNILENBQUM7SUFFTyxlQUFlLENBQUMsR0FBVztRQUNqQyxNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMxQyxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNyQyxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUM3QixJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QixPQUFPLE1BQU0sQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDO0lBQzFELENBQUM7SUFFRDs7O09BR0c7SUFDSyxXQUFXLENBQUMsR0FBVztRQUM3QixNQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNuQyxJQUFJLE9BQU8sRUFBRSxDQUFDO1lBQ1osT0FBTyxPQUFPLENBQUM7UUFDakIsQ0FBQztRQUNELE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzFDLE9BQU8sTUFBTSxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ3ZFLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNLLGNBQWMsQ0FBQyxHQUFXLEVBQUUsTUFBaUIsRUFBRSxNQUFjO1FBQ25FLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3pCLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxXQUFXLEVBQUUsQ0FBQyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQzdDLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDeEIsT0FBTztRQUNULENBQUM7UUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDOUIsS0FBSyxNQUFNLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxJQUFJLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUM1QyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDN0MsTUFBTTtZQUNSLENBQUM7WUFDRCxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUMzQixJQUFJLENBQUMsVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQzNCLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSyxXQUFXLENBQUMsTUFBYztRQUNoQyxNQUFNLEVBQUUsR0FBRyxXQUFXLEVBQUUsQ0FBQztRQUN6QixLQUFLLE1BQU0sQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3pDLElBQUksT0FBTyxDQUFDLE1BQU0sRUFBRSxFQUFFLENBQUMsSUFBSSxNQUFNLEVBQUUsQ0FBQztnQkFDbEMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDMUIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0ssV0FBVyxDQUFDLElBQWE7UUFDL0IsSUFBSSxNQUFNLEdBQUcsUUFBUSxDQUFDO1FBQ3RCLEtBQUssTUFBTSxFQUFFLGVBQWUsRUFBRSxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUNuRCxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxNQUFNLEVBQUUsZUFBZSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDbkQsQ0FBQztRQUNELE9BQU8sTUFBTSxDQUFDO0lBQ2hCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssVUFBVSxDQUFDLE1BQWlCO1FBQ2xDLE1BQU0sRUFBRSxHQUFHLFdBQVcsRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQztRQUN2RCxNQUFNLEVBQUUsU0FBUyxFQUFFLEdBQUcsTUFBTSxDQUFDO1FBQzdCLElBQUksU0FBUyxLQUFLLFNBQVMsSUFBSSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDcEUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM3QixDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7Ozs7T0FNRztJQUNLLFVBQVUsQ0FBQyxJQUFZO1FBQzdCLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxXQUFXLENBQUM7UUFDaEMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1FBQ1osSUFBSSxJQUFJLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUN6QixPQUFPLEdBQUcsR0FBRyxJQUFJLEVBQUUsQ0FBQztZQUNsQixNQUFNLEdBQUcsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ3pDLElBQUksTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLElBQUksRUFBRSxDQUFDO2dCQUMxQixHQUFHLEdBQUcsR0FBRyxHQUFHLENBQUMsQ0FBQztZQUNoQixDQUFDO2lCQUFNLENBQUM7Z0JBQ04sSUFBSSxHQUFHLEdBQUcsQ0FBQztZQUNiLENBQUM7UUFDSCxDQUFDO1FBQ0QsMEVBQTBFO1FBQzFFLHVFQUF1RTtRQUN2RSwwQ0FBMEM7UUFDMUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDLElBQUksTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxNQUFNLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxJQUFJLEVBQUUsQ0FBQztZQUN6RSxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sQ0FBQyxNQUFNLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBQ3BDLG9FQUFvRTtRQUNwRSx5RUFBeUU7UUFDekUscUNBQXFDO1FBQ3JDLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFDeEMsSUFBSSxLQUFLLEdBQUcsQ0FBQyxDQUFDO1lBQ2QsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQzNDLElBQ0UsTUFBTSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUMvQixNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFDdkMsQ0FBQztvQkFDRCxLQUFLLEdBQUcsQ0FBQyxDQUFDO2dCQUNaLENBQUM7WUFDSCxDQUFDO1lBQ0QsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLE1BQU0sQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLENBQUM7SUFDSCxDQUFDO0lBRUQsbUVBQW1FO0lBQzNELEtBQUssQ0FBQyxHQUFXLEVBQUUsRUFBVTtRQUNuQyxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN2QixJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FDWixHQUFHLEVBQ0gsRUFBRSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxDQUFDLENBQUMsR0FBRyxpQkFBaUIsR0FBRyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FDckUsQ0FBQztJQUNKLENBQUM7SUFFTyxRQUFRLENBQUMsR0FBVyxFQUFFLE1BQWlCO1FBQzdDLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3RCLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUMzQixLQUFLLE1BQU0sTUFBTSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxFQUFFLEVBQUUsQ0FBQztZQUN0QyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDMUMsTUFBTTtZQUNSLENBQUM7WUFDRCxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBRSxDQUFDLENBQUM7WUFDeEMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDekIsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7SUFFTyxLQUFLLENBQUMsR0FBVztRQUN2QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNsQyxJQUFJLE1BQU0sRUFBRSxDQUFDO1lBQ1gsSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDN0IsQ0FBQztJQUNILENBQUM7Q0FDRjtBQTk4QkQsOENBODhCQztBQUVEOzs7R0FHRztBQUNILFNBQVMsT0FBTyxDQUFDLE1BQWlCLEVBQUUsRUFBVTtJQUM1QyxNQUFNLEVBQUUsYUFBYSxFQUFFLE9BQU8sRUFBRSxTQUFTLEVBQUUsR0FBRyxNQUFNLENBQUM7SUFDckQsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUNiLGFBQWEsSUFBSSxDQUFDLFFBQVEsRUFDMUIsT0FBTyxJQUFJLENBQUMsUUFBUSxFQUNwQixTQUFTLEtBQUssU0FBUyxJQUFJLFNBQVMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQ25FLENBQUM7QUFDSixDQUFDO0FBRUQ7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUFHLG9DQUE0QixHQUFHLENBQUMsQ0FBQztBQUV4RDs7O0dBR0c7QUFDSCxNQUFNLHNCQUFzQixHQUFHLE1BQU0sQ0FBQztBQUV0QyxtRUFBbUU7QUFDbkUsTUFBTSxlQUFlLEdBQUcsR0FBRyxDQUFDO0FBRTVCOzs7OztHQUtHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7QUFFOUI7Ozs7O0dBS0c7QUFDSCxTQUFnQixZQUFZLENBQzFCLEtBQTRCLEVBQzVCLE1BQTZCO0lBRTdCLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNYLE9BQU8sTUFBTSxJQUFJLEVBQUUsQ0FBQztJQUN0QixDQUFDO0lBQ0QsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsdUVBQXVFO0lBQ3ZFLDBFQUEwRTtJQUMxRSxNQUFNLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxHQUNsQixDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxPQUFPLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDNUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxFQUFFLEtBQUssQ0FBQztRQUNqQixDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDdEIsT0FBTztRQUNMLEdBQUcsV0FBVyxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUM7UUFDNUIsYUFBYSxFQUFFLFVBQVUsQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLE1BQU0sQ0FBQyxhQUFhLENBQUM7S0FDckUsQ0FBQztBQUNKLENBQUM7QUFFRCxTQUFTLFVBQVUsQ0FBQyxDQUFxQixFQUFFLENBQXFCO0lBQzlELElBQUksQ0FBQyxLQUFLLFNBQVM7UUFBRSxPQUFPLENBQUMsQ0FBQztJQUM5QixJQUFJLENBQUMsS0FBSyxTQUFTO1FBQUUsT0FBTyxDQUFDLENBQUM7SUFDOUIsT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQztBQUN4QixDQUFDO0FBRUQ7OztHQUdHO0FBQ0gsTUFBYSxXQUFXO0lBRUg7SUFDQTtJQUZuQixZQUNtQixNQUFnQixFQUNoQixVQUFrQjtRQURsQixXQUFNLEdBQU4sTUFBTSxDQUFVO1FBQ2hCLGVBQVUsR0FBVixVQUFVLENBQVE7SUFDbEMsQ0FBQztJQUVKOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsR0FBRyxDQUFDLEdBQVc7UUFDbkIsSUFBSSxDQUFDO1lBQ0gsTUFBTSxRQUFRLEdBQUcsTUFBTSxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FDckMsSUFBSSw0QkFBZ0IsQ0FBQyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUM1RCxDQUFDO1lBQ0YsSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztnQkFDbkIsT0FBTyxTQUFTLENBQUM7WUFDbkIsQ0FBQztZQUNELE9BQU8sTUFBTSxRQUFRLENBQUMsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3hELENBQUM7UUFBQyxPQUFPLEtBQUssRUFBRSxDQUFDO1lBQ2YsSUFBSSxLQUFLLFlBQVkscUJBQVMsRUFBRSxDQUFDO2dCQUMvQixPQUFPLFNBQVMsQ0FBQztZQUNuQixDQUFDO1lBQ0QsTUFBTSxLQUFLLENBQUM7UUFDZCxDQUFDO0lBQ0gsQ0FBQztJQUVELDhDQUE4QztJQUM5QyxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQVcsRUFBRSxJQUFZO1FBQ3JDLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQ3BCLElBQUksNEJBQWdCLENBQUM7WUFDbkIsTUFBTSxFQUFFLElBQUksQ0FBQyxVQUFVO1lBQ3ZCLEdBQUcsRUFBRSxHQUFHO1lBQ1IsSUFBSSxFQUFFLElBQUk7WUFDVixXQUFXLEVBQUUsaUNBQWlDO1NBQy9DLENBQUMsQ0FDSCxDQUFDO0lBQ0osQ0FBQztDQUNGO0FBdkNELGtDQXVDQyIsInNvdXJjZXNDb250ZW50IjpbIi8qXG4gIFRoZSBTMyAvIER5bmFtb0RCIHBsdW1iaW5nIHNoYXJlZCBieSBldmVyeSBjZGstbmV4dGpzIGNhY2hlIGhhbmRsZXI6IHRoZVxuICBpbmNyZW1lbnRhbCBgY2FjaGVIYW5kbGVyYCAoYFMzQ2FjaGVIYW5kbGVyYCkgYW5kIHRoZSBgY2FjaGVIYW5kbGVyc2AgZm9yXG4gIGAndXNlIGNhY2hlJ2AgLyBgJ3VzZSBjYWNoZTogcmVtb3RlJ2AuXG5cbiAgV2hhdCBsaXZlcyBoZXJlIGlzIHdoYXQgaGFzIHRvIGFncmVlIGJldHdlZW4gdGhlbSAtIHdoZXJlIHRoZSBjb25maWd1cmF0aW9uXG4gIGNvbWVzIGZyb20sIGhvdyBhIGNhY2hlIGtleSBiZWNvbWVzIGFuIFMzIGtleSwgYW5kIHdoYXQgYSB0YWcncyBtYXJrZXIgcm93IGluXG4gIHRoZSByZXZhbGlkYXRpb24gdGFibGUgbG9va3MgbGlrZSBhbmQgbWVhbnMuIEEgYHJldmFsaWRhdGVUYWdgIHJlYWNoZXMgYm90aFxuICBraW5kcyBvZiBoYW5kbGVyLCBhbmQgdGhleSBtdXN0IHJlYWQgZWFjaCBvdGhlcidzIG1hcmtlcnMgdGhlIHNhbWUgd2F5LlxuKi9cbi8qIGVzbGludC1kaXNhYmxlIGltcG9ydC9uby1leHRyYW5lb3VzLWRlcGVuZGVuY2llcyAqL1xuaW1wb3J0IHsgQXN5bmNMb2NhbFN0b3JhZ2UgfSBmcm9tIFwibm9kZTphc3luY19ob29rc1wiO1xuaW1wb3J0IHsgam9pbiB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7XG4gIEF0dHJpYnV0ZVZhbHVlLFxuICBCYXRjaEdldEl0ZW1Db21tYW5kLFxuICBCYXRjaEdldEl0ZW1Db21tYW5kT3V0cHV0LFxuICBEeW5hbW9EQkNsaWVudCxcbiAgUHV0SXRlbUNvbW1hbmQsXG4gIFF1ZXJ5Q29tbWFuZCxcbiAgUXVlcnlDb21tYW5kT3V0cHV0LFxuICBVcGRhdGVJdGVtQ29tbWFuZCxcbn0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1keW5hbW9kYlwiO1xuaW1wb3J0IHtcbiAgR2V0T2JqZWN0Q29tbWFuZCxcbiAgTm9TdWNoS2V5LFxuICBQdXRPYmplY3RDb21tYW5kLFxuICBTM0NsaWVudCxcbn0gZnJvbSBcIkBhd3Mtc2RrL2NsaWVudC1zM1wiO1xuaW1wb3J0IHsgY2FjaGVLZXlGaWxlTmFtZSwgY2FjaGVPYmplY3ROYW1lLCBzaGEyNTZIZXggfSBmcm9tIFwiLi9jYWNoZS11dGlsc1wiO1xuaW1wb3J0IHsgb3V0c2lkZVJlcXVlc3QgfSBmcm9tIFwiLi4vcnVudGltZS90YWctbWFuaWZlc3RcIjtcblxuLyoqXG4gKiBXaGVyZSB0aGUgY2FjaGUgbGl2ZXMsIGFzIHRoZSBjb25zdHJ1Y3RzIHBhc3MgaXQgdG8gdGhlIGNvbXB1dGUgdGhyb3VnaCB0aGVcbiAqIGVudmlyb25tZW50IChgTmV4dGpzRnVuY3Rpb25zYCwgYE5leHRqc0NvbnRhaW5lcnNgKS4gRW1wdHkgc3RyaW5ncyBmb3Igd2hhdCBpc1xuICogbm90IGNvbmZpZ3VyZWQsIHdoaWNoIGVhY2ggaGFuZGxlciByZWFkcyBhcyBcInRoYXQgbGF5ZXIgaXMgZGlzYWJsZWRcIi5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBd3NDYWNoZUNvbmZpZyB7XG4gIC8qKiBgQ0RLX05FWFRKU19DQUNIRV9CVUNLRVRfTkFNRWAuICovXG4gIGJ1Y2tldE5hbWU6IHN0cmluZztcbiAgLyoqIGBDREtfTkVYVEpTX1JFVkFMSURBVElPTl9UQUJMRV9OQU1FYC4gKi9cbiAgdGFibGVOYW1lOiBzdHJpbmc7XG4gIC8qKiBgQVdTX1JFR0lPTmAsIGB1cy1lYXN0LTFgIHdoZW4gdW5zZXQuICovXG4gIHJlZ2lvbjogc3RyaW5nO1xuICAvKiogYENES19ORVhUSlNfQlVJTERfSURgOiBldmVyeSBTMyBrZXkgYW5kIGV2ZXJ5IG1hcmtlciByb3cgaXMgc2NvcGVkIHRvIGl0LiAqL1xuICBidWlsZElkOiBzdHJpbmc7XG59XG5cbi8qKiBUaGUgY29uZmlndXJhdGlvbiBmcm9tIHRoZSBlbnZpcm9ubWVudC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNvbHZlQXdzQ2FjaGVDb25maWcoKTogQXdzQ2FjaGVDb25maWcge1xuICByZXR1cm4ge1xuICAgIGJ1Y2tldE5hbWU6IHByb2Nlc3MuZW52LkNES19ORVhUSlNfQ0FDSEVfQlVDS0VUX05BTUUgfHwgXCJcIixcbiAgICB0YWJsZU5hbWU6IHByb2Nlc3MuZW52LkNES19ORVhUSlNfUkVWQUxJREFUSU9OX1RBQkxFX05BTUUgfHwgXCJcIixcbiAgICByZWdpb246IHByb2Nlc3MuZW52LkFXU19SRUdJT04gfHwgXCJ1cy1lYXN0LTFcIixcbiAgICBidWlsZElkOiBwcm9jZXNzLmVudi5DREtfTkVYVEpTX0JVSUxEX0lEIHx8IFwiXCIsXG4gIH07XG59XG5cbi8qKlxuICogYHtidWlsZElkfS97Y2FjaGVLZXl9Lmpzb25gLCB0aGUgaW5jcmVtZW50YWwgY2FjaGUncyBrZXkgY29udmVudGlvbi5cbiAqXG4gKiBUaGUgcm9vdCBwYXRoIGJlY29tZXMgYGluZGV4YCwgYW5kIGEgbGVhZGluZyBzbGFzaCBpcyBkcm9wcGVkIHNvIHRoZXJlIGlzIG5vXG4gKiBlbXB0eSBmb2xkZXIgdW5kZXIgdGhlIGJ1aWxkIHByZWZpeC4gRXZlcnl0aGluZyB0aGlzIHJldHVybnMgZW5kcyBpbiBgLmpzb25gLFxuICogd2hpY2ggaXMgd2hhdCBrZWVwcyBpdCBkaXNqb2ludCBmcm9tIHtAbGluayB1c2VDYWNoZVMzS2V5fS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkUzNLZXkoYnVpbGRJZDogc3RyaW5nLCBjYWNoZUtleTogc3RyaW5nKTogc3RyaW5nIHtcbiAgcmV0dXJuIGpvaW4oYnVpbGRJZCwgY2FjaGVLZXlGaWxlTmFtZShjYWNoZUtleSkpO1xufVxuXG4vKiogYHtidWlsZElkfS9gICsge0BsaW5rIGNhY2hlT2JqZWN0TmFtZX06IHRoZSBTMyBvYmplY3QgYW4gZW50cnkgaXMgc3RvcmVkIGluLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHMzT2JqZWN0S2V5KGJ1aWxkSWQ6IHN0cmluZywgY2FjaGVLZXk6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBqb2luKGJ1aWxkSWQsIGNhY2hlT2JqZWN0TmFtZShjYWNoZUtleSkpO1xufVxuXG4vKipcbiAqIFRoZSBmb2xkZXIgdW5kZXIgdGhlIGJ1aWxkIHByZWZpeCB0aGF0IGAndXNlIGNhY2hlJ2AgZW50cmllcyBhcmUgc3RvcmVkIGluLlxuICogQHNlZSB1c2VDYWNoZVMzS2V5XG4gKi9cbmV4cG9ydCBjb25zdCBVU0VfQ0FDSEVfS0VZX1BSRUZJWCA9IFwiX3VzZS1jYWNoZVwiO1xuXG4vKipcbiAqIGB7YnVpbGRJZH0vX3VzZS1jYWNoZS97aGFzaH0uZW50cnlgLCB3aGVyZSBhIGBjYWNoZUhhbmRsZXJzYCBlbnRyeSBpcyBzdG9yZWQuXG4gKlxuICogSGFzaGVkIGJlY2F1c2UgYSBgJ3VzZSBjYWNoZSdgIGtleSBpcyB0aGUgc2VyaWFsaXplZCBhcmd1bWVudHMgb2YgdGhlIGNhbGwgYW5kXG4gKiBoYXMgbm8gbGVuZ3RoIGxpbWl0LCB3aGVyZSBhbiBTMyBrZXkgc3RvcHMgYXQgMTAyNCBieXRlcy4gVGhlIGAuZW50cnlgIHN1ZmZpeFxuICogcmF0aGVyIHRoYW4gYC5qc29uYCBpcyB3aGF0IG1ha2VzIGEgY29sbGlzaW9uIHdpdGggdGhlIGluY3JlbWVudGFsIGNhY2hlXG4gKiBpbXBvc3NpYmxlIHJhdGhlciB0aGFuIHVubGlrZWx5OiBldmVyeSBvYmplY3Qge0BsaW5rIHMzT2JqZWN0S2V5fSBuYW1lcyBlbmRzXG4gKiBpbiBgLmpzb25gIG9yIGAubG9uZ2AsIGluY2x1ZGluZyBvbmUgZm9yIGEgcm91dGUgdGhhdCBoYXBwZW5zIHRvIGJlIG5hbWVkXG4gKiBgL191c2UtY2FjaGUv4oCmYC5cbiAqIFN0aWxsIHVuZGVyIHRoZSBidWlsZCBwcmVmaXgsIHNvIHBvc3QtZGVwbG95IHBydW5pbmcgZHJvcHMgdGhlbSB3aXRoIHRoZSBidWlsZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZUNhY2hlUzNLZXkoYnVpbGRJZDogc3RyaW5nLCBrZXlIYXNoOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gam9pbihidWlsZElkLCBVU0VfQ0FDSEVfS0VZX1BSRUZJWCwgYCR7a2V5SGFzaH0uZW50cnlgKTtcbn1cblxuLyoqXG4gKiBUaGUgYGR1cmF0aW9uc2AgTmV4dC5qcyAxNiBwYXNzZXMgYSB0YWcgcmV2YWxpZGF0aW9uIGZvciBhIHByb2ZpbGU6XG4gKiBgcmV2YWxpZGF0ZVRhZyhcInBvc3RzXCIsIFwibWF4XCIpYCBhcnJpdmVzIGFzIGB7IGV4cGlyZTogPHRoZSBwcm9maWxlJ3MgZXhwaXJlPiB9YC5cbiAqIEFic2VudCBmb3IgYHVwZGF0ZVRhZ2AgYW5kIGEgYmFyZSBgcmV2YWxpZGF0ZVRhZ2AsIHdoaWNoIGV4cGlyZSBpbW1lZGlhdGVseS5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZXZhbGlkYXRlRHVyYXRpb25zIHtcbiAgZXhwaXJlPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEEgdGFnJ3MgbWFya2VyIHJvdywgYXMgdGltZXN0YW1wcyBpbiBtaWxsaXNlY29uZHMuIFdyaXR0ZW4gYnlcbiAqIHtAbGluayBtYXJrZXJVcGRhdGV9OyBlYWNoIGZpZWxkIGlzIGFic2VudCB1bnRpbCBhIHJldmFsaWRhdGlvbiBvZiB0aGF0IHNoYXBlXG4gKiBoYXMgaGFwcGVuZWQuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVGFnTWFya2VyIHtcbiAgLyoqIEV4cGlyZWQgb3V0cmlnaHQ6IGB1cGRhdGVUYWdgLCBvciBgcmV2YWxpZGF0ZVRhZ2Agd2l0aCBubyBwcm9maWxlLiAqL1xuICByZXZhbGlkYXRlZEF0PzogbnVtYmVyO1xuICAvKiogU3RhbGUgZnJvbSBoZXJlOiBgcmV2YWxpZGF0ZVRhZyh0YWcsIHByb2ZpbGUpYC4gKi9cbiAgc3RhbGVBdD86IG51bWJlcjtcbiAgLyoqIFdoZW4gdGhlIHByb2ZpbGUncyBgZXhwaXJlYCBydW5zIG91dCwgd2hpY2ggbWF5IGJlIGluIHRoZSBmdXR1cmUuICovXG4gIGV4cGlyZWRBdD86IG51bWJlcjtcbn1cblxuLyoqXG4gKiBXaGF0IHRoZSB0YWcgbWFya2VycyBzYXkgYWJvdXQgYW4gZW50cnk6IHVudG91Y2hlZCwgc2VydmVkIHN0YWxlIHdoaWxlIGFcbiAqIGJhY2tncm91bmQgcmVuZGVyIHJlcGxhY2VzIGl0LCBvciBleHBpcmVkIGFuZCByZS1yZW5kZXJlZCBiZWZvcmUgYW5zd2VyaW5nLlxuICovXG5leHBvcnQgdHlwZSBSZXZhbGlkYXRpb25TdGF0ZSA9IFwiZnJlc2hcIiB8IFwic3RhbGVcIiB8IFwiZXhwaXJlZFwiO1xuXG4vKipcbiAqIFdoYXQgYG1hcmtlcmAgbWVhbnMgZm9yIGFuIGVudHJ5IGNyZWF0ZWQgYXQgYGNyZWF0ZWRBdGAsIGF0IGBub3dgLlxuICpcbiAqIGBleHBpcmVkQXRgIGluIHRoZSBmdXR1cmUgaXMgYSBwcm9maWxlJ3MgYGV4cGlyZWAgdGhhdCBoYXMgbm90IGNvbWUgeWV0LFxuICogY29tcGFyZWQgdGhlIHdheSBOZXh0LmpzJ3MgYGFyZVRhZ3NFeHBpcmVkYCBkb2VzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gbWFya2VyU3RhdGUoXG4gIG1hcmtlcjogVGFnTWFya2VyLFxuICBjcmVhdGVkQXQ6IG51bWJlcixcbiAgbm93OiBudW1iZXIsXG4pOiBSZXZhbGlkYXRpb25TdGF0ZSB7XG4gIGNvbnN0IHsgcmV2YWxpZGF0ZWRBdCwgZXhwaXJlZEF0LCBzdGFsZUF0IH0gPSBtYXJrZXI7XG4gIGlmIChcbiAgICAocmV2YWxpZGF0ZWRBdCAhPT0gdW5kZWZpbmVkICYmIHJldmFsaWRhdGVkQXQgPiBjcmVhdGVkQXQpIHx8XG4gICAgKGV4cGlyZWRBdCAhPT0gdW5kZWZpbmVkICYmIGV4cGlyZWRBdCA8PSBub3cgJiYgZXhwaXJlZEF0ID4gY3JlYXRlZEF0KVxuICApIHtcbiAgICByZXR1cm4gXCJleHBpcmVkXCI7XG4gIH1cbiAgaWYgKHN0YWxlQXQgIT09IHVuZGVmaW5lZCAmJiBzdGFsZUF0ID4gY3JlYXRlZEF0KSB7XG4gICAgcmV0dXJuIFwic3RhbGVcIjtcbiAgfVxuICByZXR1cm4gXCJmcmVzaFwiO1xufVxuXG4vKipcbiAqIFRoZSBjbG9jayBldmVyeSB0YWcgbWFya2VyIGlzIHN0YW1wZWQgd2l0aCwgYW5kIGV2ZXJ5IGVudHJ5IHRpbWVzdGFtcCBpdCBpc1xuICogY29tcGFyZWQgYWdhaW5zdDogdGhlIG9uZSBOZXh0LmpzIHN0YW1wcyBgQ2FjaGVFbnRyeS50aW1lc3RhbXBgIHdpdGhcbiAqIChgcGVyZm9ybWFuY2UudGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpYCwgaW4gYHVzZS1jYWNoZS13cmFwcGVyLmpzYCBhbmRcbiAqIHRoZSBkZWZhdWx0IGhhbmRsZXIpLCByYXRoZXIgdGhhbiBgRGF0ZS5ub3coKWAuIEJvdGggaGFuZGxlcnMgd3JpdGUgdGhlIHNhbWVcbiAqIG1hcmtlciByb3dzLCBzbyBib3RoIGhhdmUgdG8gdXNlIGl0OiB0d28gY2xvY2tzIG9uIG9uZSByb3cgbGV0IHRoZSBsYXN0IHdyaXRlclxuICogZGVjaWRlIHdoaWNoIGNsb2NrIHRoZSBvdGhlcnMgY29tcGFyZSBhZ2FpbnN0LCBhbmQgdGhleSBkcmlmdCBhcGFydCBmb3IgYXNcbiAqIGxvbmcgYXMgYSBMYW1iZGEgc2FuZGJveCBvciBGYXJnYXRlIHRhc2sgbGl2ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJDbG9jaygpOiBudW1iZXIge1xuICByZXR1cm4gcGVyZm9ybWFuY2UudGltZU9yaWdpbiArIHBlcmZvcm1hbmNlLm5vdygpO1xufVxuXG4vKipcbiAqIFRoZSBtYXJrZXIgZmllbGRzIGEgdGFnIHJldmFsaWRhdGVkIGF0IGBub3dgIHNldHMuXG4gKlxuICogV2l0aG91dCBgZHVyYXRpb25zYCAtIGB1cGRhdGVUYWdgLCBvciBgcmV2YWxpZGF0ZVRhZ2Agd2l0aCBubyBwcm9maWxlIC0gdGhlXG4gKiB0YWcncyBlbnRyaWVzIGV4cGlyZSBpbW1lZGlhdGVseSAoYHJldmFsaWRhdGVkQXRgKS4gV2l0aCB0aGVtIHRoZSBlbnRyaWVzIGdvXG4gKiBzdGFsZSBub3cgYW5kIGV4cGlyZSBhZnRlciB0aGUgcHJvZmlsZSdzIGBleHBpcmVgLCB0aGUgc2FtZSBwYWlyIG9mXG4gKiB0aW1lc3RhbXBzIE5leHQuanMncyBgRmlsZVN5c3RlbUNhY2hlLnJldmFsaWRhdGVUYWdgIHJlY29yZHMuIEEgcHJvZmlsZSB3aXRoXG4gKiBubyBgZXhwaXJlYCBzZXRzIG9ubHkgYHN0YWxlQXRgLCBhbmQgd2hhdGV2ZXIgYGV4cGlyZWRBdGAgdGhlIHRhZyBoYWQgc3RheXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJGb3IoXG4gIG5vdzogbnVtYmVyLFxuICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4pOiBUYWdNYXJrZXIge1xuICBpZiAoIWR1cmF0aW9ucykge1xuICAgIHJldHVybiB7IHJldmFsaWRhdGVkQXQ6IG5vdyB9O1xuICB9XG4gIGlmIChkdXJhdGlvbnMuZXhwaXJlID09PSB1bmRlZmluZWQpIHtcbiAgICByZXR1cm4geyBzdGFsZUF0OiBub3cgfTtcbiAgfVxuICByZXR1cm4geyBzdGFsZUF0OiBub3csIGV4cGlyZWRBdDogbm93ICsgZHVyYXRpb25zLmV4cGlyZSAqIDEwMDAgfTtcbn1cblxuY29uc3QgTUFSS0VSX0ZJRUxEUyA9IFtcInJldmFsaWRhdGVkQXRcIiwgXCJzdGFsZUF0XCIsIFwiZXhwaXJlZEF0XCJdIGFzIGNvbnN0O1xuXG4vKipcbiAqIGBleGlzdGluZ2Agd2l0aCB0aGUgZmllbGRzIGB1cGRhdGVgIHNldHMsIGFzIGEge0BsaW5rIG1hcmtlclVwZGF0ZX0gbGVhdmVzXG4gKiB0aGUgcm93OiBhIGZpZWxkIGB1cGRhdGVgIGRvZXMgbm90IHNldCBrZWVwcyBpdHMgdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhcHBseU1hcmtlcihcbiAgZXhpc3Rpbmc6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCxcbiAgdXBkYXRlOiBUYWdNYXJrZXIsXG4pOiBUYWdNYXJrZXIge1xuICBjb25zdCBtYXJrZXIgPSB7IC4uLmV4aXN0aW5nIH07XG4gIGZvciAoY29uc3QgZmllbGQgb2YgTUFSS0VSX0ZJRUxEUykge1xuICAgIGlmICh1cGRhdGVbZmllbGRdICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIG1hcmtlcltmaWVsZF0gPSB1cGRhdGVbZmllbGRdO1xuICAgIH1cbiAgfVxuICByZXR1cm4gbWFya2VyO1xufVxuXG4vKiogVGhlIG1hcmtlci1yb3cgdXBkYXRlIHRoYXQgc2V0cyB7QGxpbmsgbWFya2VyRm9yfSdzIGZpZWxkcy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBtYXJrZXJVcGRhdGUoXG4gIG5vdzogbnVtYmVyLFxuICBkdXJhdGlvbnM6IFJldmFsaWRhdGVEdXJhdGlvbnMgfCB1bmRlZmluZWQsXG4pOiBQaWNrPFxuICBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIFVwZGF0ZUl0ZW1Db21tYW5kPlswXSxcbiAgXCJVcGRhdGVFeHByZXNzaW9uXCIgfCBcIkV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXNcIlxuPiB7XG4gIGNvbnN0IG1hcmtlciA9IG1hcmtlckZvcihub3csIGR1cmF0aW9ucyk7XG4gIGNvbnN0IGZpZWxkcyA9IE1BUktFUl9GSUVMRFMuZmlsdGVyKChmaWVsZCkgPT4gbWFya2VyW2ZpZWxkXSAhPT0gdW5kZWZpbmVkKTtcbiAgcmV0dXJuIHtcbiAgICBVcGRhdGVFeHByZXNzaW9uOiBgU0VUICR7ZmllbGRzLm1hcCgoZmllbGQpID0+IGAke2ZpZWxkfSA9IDoke2ZpZWxkfWApLmpvaW4oXCIsIFwiKX1gLFxuICAgIEV4cHJlc3Npb25BdHRyaWJ1dGVWYWx1ZXM6IE9iamVjdC5mcm9tRW50cmllcyhcbiAgICAgIGZpZWxkcy5tYXAoKGZpZWxkKSA9PiBbYDoke2ZpZWxkfWAsIHsgTjogU3RyaW5nKG1hcmtlcltmaWVsZF0pIH1dKSxcbiAgICApLFxuICB9O1xufVxuXG4vKiogQSBEeW5hbW9EQiBudW1iZXIgYXR0cmlidXRlIGFzIGEgbnVtYmVyLCBvciBgdW5kZWZpbmVkYCB3aGVuIGFic2VudC4gKi9cbmZ1bmN0aW9uIG51bWJlckF0dHJpYnV0ZShcbiAgdmFsdWU6IEF0dHJpYnV0ZVZhbHVlIHwgdW5kZWZpbmVkLFxuKTogbnVtYmVyIHwgdW5kZWZpbmVkIHtcbiAgcmV0dXJuIHZhbHVlPy5OID09PSB1bmRlZmluZWQgPyB1bmRlZmluZWQgOiBOdW1iZXIodmFsdWUuTik7XG59XG5cbi8qKiBUaGUgbWFya2VyIGZpZWxkcyBvZiBhIG1hcmtlciBvciBsb2cgcm93LiAqL1xuZnVuY3Rpb24gbWFya2VyT2YoaXRlbTogUmVjb3JkPHN0cmluZywgQXR0cmlidXRlVmFsdWU+KTogVGFnTWFya2VyIHtcbiAgcmV0dXJuIHtcbiAgICByZXZhbGlkYXRlZEF0OiBudW1iZXJBdHRyaWJ1dGUoaXRlbS5yZXZhbGlkYXRlZEF0KSxcbiAgICBzdGFsZUF0OiBudW1iZXJBdHRyaWJ1dGUoaXRlbS5zdGFsZUF0KSxcbiAgICBleHBpcmVkQXQ6IG51bWJlckF0dHJpYnV0ZShpdGVtLmV4cGlyZWRBdCksXG4gIH07XG59XG5cbi8qKiBEeW5hbW9EQidzIGNhcCBvbiBrZXlzIGluIG9uZSBgQmF0Y2hHZXRJdGVtYC4gKi9cbmV4cG9ydCBjb25zdCBCQVRDSF9HRVRfTUFYX0tFWVMgPSAxMDA7XG5cbi8qKlxuICogSG93IG9mdGVuLCBhdCBtb3N0LCBhbiBpbnN0YW5jZSBjYXRjaGVzIHVwIG9uIHJldmFsaWRhdGlvbnMgb3RoZXIgaW5zdGFuY2VzXG4gKiByYW4sIHVubGVzcyBgQ0RLX05FWFRKU19UQUdfUkVGUkVTSF9NU2Agc2F5cyBvdGhlcndpc2U6IHRoZSBzdGFsZW5lc3Mgd2luZG93XG4gKiBmb3IgYSBgcmV2YWxpZGF0ZVRhZ2AgcnVuIGVsc2V3aGVyZS4gRXZlcnkgY2FjaGUgaGl0IGNoZWNrcyBpdHMgdGFncydcbiAqIG1hcmtlcnMsIGFuZCBldmVyeSBtYXJrZXIgb2YgYSBkZXBsb3ltZW50IHNoYXJlcyBvbmUgcGFydGl0aW9uIGtleSwgc29cbiAqIHJlYWRpbmcgdGhlbSBwZXIgcmVxdWVzdCBjYXBwZWQgYSByb3V0ZSdzIGNhY2hlIGhpdHMgYXQgdGhlIHBhcnRpdGlvbidzIHJlYWRcbiAqIHRocm91Z2hwdXQgKH4xLDkwMCByZXEvcyBvbiBOZXh0anNSZWdpb25hbEZ1bmN0aW9ucykuIE9uY2UgYSBzZWNvbmQsIGZyb20gdGhlXG4gKiByZXZhbGlkYXRpb24gbG9nLCB0aGUgcmVhZHMgc2NhbGUgd2l0aCBpbnN0YW5jZXMgaW5zdGVhZCBvZiByZXF1ZXN0cyBvciB0YWdzLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9UQUdfUkVGUkVTSF9NUyA9IDEwMDA7XG5cbi8qKlxuICogSG93IGZhciBwYXN0IGByZWZyZXNoSW50ZXJ2YWxNc2AgdGhlIGxhc3QgcmVmcmVzaCBtYXkgaGF2ZSBzZXR0bGVkIGJlZm9yZSBhXG4gKiBgJ3VzZSBjYWNoZSdgIHJlcXVlc3Qgd2FpdHMgZm9yIHRoZSBuZXh0IG9uZSAoc2VlXG4gKiB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnMuYmVoaW5kfSkuIEFuIGluc3RhbmNlIHNlcnZpbmcgc3RlYWR5IHRyYWZmaWMgc3RheXNcbiAqIGluc2lkZSBpdDsgb25lIHRoYXQgc2F0IGlkbGUsIG9yIGZyb3plbiBiZXR3ZWVuIExhbWJkYSBpbnZvY2F0aW9ucywgZG9lcyBub3QuXG4gKi9cbmV4cG9ydCBjb25zdCBUQUdfUkVGUkVTSF9HUkFDRV9NUyA9IDEwMDA7XG5cbi8qKiBEeW5hbW9EQidzIGxpbWl0IG9uIGEgc29ydCBrZXksIGluIFVURi04IGJ5dGVzLiAqL1xuZXhwb3J0IGNvbnN0IE1BWF9TT1JUX0tFWV9CWVRFUyA9IDEwMjQ7XG5cbi8qKlxuICogYCM8c2hhMjU2KHRhZyk+YCwgc3RhbmRpbmcgaW4gZm9yIGEgdGFnIGluIGEgc29ydCBrZXkgaXQgd291bGQgcHVzaCBwYXN0XG4gKiB7QGxpbmsgTUFYX1NPUlRfS0VZX0JZVEVTfS4gTmV4dC5qcyBjYXBzIHRoZSB0YWdzIGFuIGFwcCBuYW1lcywgYnV0IG5vdCBhblxuICogaW1wbGljaXQgYF9OX1RfL+KApmAgdGFnLCB3aGljaCBpcyBhcyBsb25nIGFzIGl0cyBwYXRoLCBhbmQgYSByZWplY3RlZCB3cml0ZVxuICogbGVmdCBgcmV2YWxpZGF0ZVBhdGhgIG9uIGEgbG9uZyBwYXRoIHJlY29yZGVkIG5vd2hlcmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBoYXNoZWRUYWcodGFnOiBzdHJpbmcpOiBzdHJpbmcge1xuICByZXR1cm4gYCMke3NoYTI1NkhleCh0YWcpfWA7XG59XG5cbi8qKlxuICogVGhlIGxvbmdlc3QgdGFnIGEgc29ydCBrZXkgc3BlbGxzIG91dDsgcGFzdCBpdCwge0BsaW5rIHNvcnRLZXlUYWd9IGhhc2hlc1xuICogaXQuIE9uZSBjYXAgZm9yIGV2ZXJ5IHJvdyB0aGUgdGFnIGlzIGluLCBzbyBhIHJvdydzIHdyaXRlciBhbmQgcmVhZGVyIGFncmVlXG4gKiB3aXRob3V0IGVhY2ggd29ya2luZyBvdXQgd2hhdCBlbHNlIHNoYXJlcyBpdHMga2V5LiBJdCBsZWF2ZXMgcm9vbSBmb3IgdGhlXG4gKiBtb3N0IGFueSByb3cgcHV0cyBiZXNpZGUgdGhlIHRhZzogYSBtYXBwaW5nIHJvdydzIGAjPGJ1aWxkSWQ+LyM8c2hhMjU2PmAsXG4gKiB3aXRoIHRoZSBidWlsZCBJRCBjYXBwZWQgYXQgYE1BWF9CVUlMRF9JRF9CWVRFU2AuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfVEFHX0JZVEVTID0gNzY4O1xuXG4vKiogYHRhZ2AgYXMgYSBzb3J0IGtleSBzcGVsbHMgaXQ6IGl0c2VsZiwgb3Ige0BsaW5rIGhhc2hlZFRhZ30gcGFzdCB7QGxpbmsgTUFYX1RBR19CWVRFU30uICovXG5leHBvcnQgZnVuY3Rpb24gc29ydEtleVRhZyh0YWc6IHN0cmluZyk6IHN0cmluZyB7XG4gIHJldHVybiBCdWZmZXIuYnl0ZUxlbmd0aCh0YWcpIDw9IE1BWF9UQUdfQllURVMgPyB0YWcgOiBoYXNoZWRUYWcodGFnKTtcbn1cblxuLyoqXG4gKiBUaGUgYmFyZS10YWcgbWFya2VyIHJvd3Mgb2YgdGhlIHJldmFsaWRhdGlvbiB0YWJsZSAoYHBrID0gYnVpbGRJZGAsXG4gKiBgc2sgPSB0YWdgLCBvciB7QGxpbmsgaGFzaGVkVGFnfSBwYXN0IHtAbGluayBNQVhfVEFHX0JZVEVTfSksIHdoaWNoIHJlY29yZCB3aGVuIGEgdGFnXG4gKiB3YXMgbGFzdCByZXZhbGlkYXRlZCBhbmQgaG93LlxuICpcbiAqIFRoZSB0YWJsZSBhbHNvIGhvbGRzIHRoZSBpbmNyZW1lbnRhbCBjYWNoZSdzIGB0YWcjczNLZXlgIG1hcHBpbmcgcm93cywgd2hpY2hcbiAqIGFyZSBpdHMgb3duIGJ1c2luZXNzIGFuZCBzdGF5IGluIGBTM0NhY2hlSGFuZGxlcmA6IG9ubHkgdGhlIG1hcmtlcnMgbWVhbiB0aGVcbiAqIHNhbWUgdGhpbmcgdG8gZXZlcnkgaGFuZGxlci4gV2hhdCBhbiBpbnN0YW5jZSBrZWVwcyBvZiB0aGVtIGJldHdlZW4gcmVhZHMgaXNcbiAqIHtAbGluayBUcmFja2VkVGFnTWFya2Vyc30uXG4gKi9cbmV4cG9ydCBjbGFzcyBUYWdNYXJrZXJUYWJsZSB7XG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2xpZW50OiBEeW5hbW9EQkNsaWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRhYmxlTmFtZTogc3RyaW5nLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgYnVpbGRJZDogc3RyaW5nLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIFJlY29yZCBgdGFnYCdzIHJldmFsaWRhdGlvbiBhdCBgbm93YC4gU2VlIHtAbGluayBtYXJrZXJVcGRhdGV9LlxuICAgKlxuICAgKiBSZXR1cm5zIHRoZSByb3cgYXMgdGhpcyB3cml0ZSBsZWZ0IGl0LCBzbyB0aGUgaW5zdGFuY2UgdGhhdCB3cm90ZSBpdCBjYW5cbiAgICogdHJhY2sgaXQgcmF0aGVyIHRoYW4gcmVhZCBpdCBiYWNrOiByZWFkcyBhcmUgZXZlbnR1YWxseSBjb25zaXN0ZW50LCBhbmQgYVxuICAgKiByZWFkLWJhY2sgcmFjaW5nIHJlcGxpY2F0aW9uIGNvdWxkIHJldHVybiB0aGUgbWFya2VyIGZyb20gYmVmb3JlIHRoZSB3cml0ZS5cbiAgICovXG4gIGFzeW5jIHdyaXRlKFxuICAgIHRhZzogc3RyaW5nLFxuICAgIG5vdzogbnVtYmVyLFxuICAgIGR1cmF0aW9uczogUmV2YWxpZGF0ZUR1cmF0aW9ucyB8IHVuZGVmaW5lZCxcbiAgKTogUHJvbWlzZTxUYWdNYXJrZXIgfCB1bmRlZmluZWQ+IHtcbiAgICBjb25zdCByZXNwb25zZSA9IGF3YWl0IHRoaXMuY2xpZW50LnNlbmQoXG4gICAgICBuZXcgVXBkYXRlSXRlbUNvbW1hbmQoe1xuICAgICAgICBUYWJsZU5hbWU6IHRoaXMudGFibGVOYW1lLFxuICAgICAgICBLZXk6IHtcbiAgICAgICAgICBwazogeyBTOiB0aGlzLmJ1aWxkSWQgfSxcbiAgICAgICAgICBzazogeyBTOiBzb3J0S2V5VGFnKHRhZykgfSxcbiAgICAgICAgfSxcbiAgICAgICAgLi4ubWFya2VyVXBkYXRlKG5vdywgZHVyYXRpb25zKSxcbiAgICAgICAgUmV0dXJuVmFsdWVzOiBcIkFMTF9ORVdcIixcbiAgICAgIH0pLFxuICAgICk7XG4gICAgcmV0dXJuIHJlc3BvbnNlPy5BdHRyaWJ1dGVzID8gbWFya2VyT2YocmVzcG9uc2UuQXR0cmlidXRlcykgOiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogVGhlIG1hcmtlciByb3dzIGZvciBgdGFnc2AgdGhhdCBleGlzdCwgYnkgdGFnLCBpbiBvbmUgYEJhdGNoR2V0SXRlbWAgcGVyXG4gICAqIHtAbGluayBCQVRDSF9HRVRfTUFYX0tFWVN9IHRhZ3MgcmF0aGVyIHRoYW4gYSBgR2V0SXRlbWAgZWFjaDogYSBwYWdlXG4gICAqIGNhcnJpZXMgaXRzIHdob2xlIGltcGxpY2l0IGBfTl9UXy/igKZgIGNoYWluIHBsdXMgdGhlIGFwcCdzIG93biB0YWdzLCBhXG4gICAqIHBhZ2Ugd2l0aCBhIGZldyBmZXRjaGVzIGNoZWNrcyBlYWNoIG9mIHRoZW0gdG9vLCBhbmQgZXZlcnkgb25lIGlzIG9uIHRoZVxuICAgKiByZXF1ZXN0IHBhdGguIEEgdGFnIHdpdGggbm8gcm93IGlzIGFic2VudCBmcm9tIHRoZSByZXN1bHQuXG4gICAqL1xuICBhc3luYyByZWFkKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTxNYXA8c3RyaW5nLCBUYWdNYXJrZXI+PiB7XG4gICAgY29uc3QgeyB0YWJsZU5hbWUsIGJ1aWxkSWQgfSA9IHRoaXM7XG4gICAgY29uc3QgdW5pcXVlID0gQXJyYXkuZnJvbShuZXcgU2V0KHRhZ3MpKTtcbiAgICBjb25zdCBtYXJrZXJzID0gbmV3IE1hcDxzdHJpbmcsIFRhZ01hcmtlcj4oKTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdW5pcXVlLmxlbmd0aDsgaSArPSBCQVRDSF9HRVRfTUFYX0tFWVMpIHtcbiAgICAgIC8vIEEgaGFzaGVkIHNvcnQga2V5IG5hbWVzIG5vIHRhZywgc28gZWFjaCByb3cgaXMgbWF0Y2hlZCBiYWNrIGJ5IGtleS5cbiAgICAgIGNvbnN0IHRhZ0J5U2sgPSBuZXcgTWFwKFxuICAgICAgICB1bmlxdWVcbiAgICAgICAgICAuc2xpY2UoaSwgaSArIEJBVENIX0dFVF9NQVhfS0VZUylcbiAgICAgICAgICAubWFwKCh0YWcpID0+IFtzb3J0S2V5VGFnKHRhZyksIHRhZ10pLFxuICAgICAgKTtcbiAgICAgIGxldCBrZXlzOiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT5bXSB8IHVuZGVmaW5lZCA9IEFycmF5LmZyb20oXG4gICAgICAgIHRhZ0J5U2sua2V5cygpLFxuICAgICAgICAoc2spID0+ICh7IHBrOiB7IFM6IGJ1aWxkSWQgfSwgc2s6IHsgUzogc2sgfSB9KSxcbiAgICAgICk7XG4gICAgICAvLyBgVW5wcm9jZXNzZWRLZXlzYCBpcyBEeW5hbW9EQiBkZWNsaW5pbmcgcGFydCBvZiB0aGUgYmF0Y2ggdW5kZXIgbG9hZDtcbiAgICAgIC8vIGEgbWFya2VyIGxlZnQgdW5yZWFkIGlzIGEgcmV2YWxpZGF0aW9uIG1pc3NlZCwgc28gaXQgaXMgYXNrZWQgYWdhaW4uXG4gICAgICBmb3IgKGxldCBhdHRlbXB0ID0gMDsga2V5cz8ubGVuZ3RoICYmIGF0dGVtcHQgPCAzOyBhdHRlbXB0KyspIHtcbiAgICAgICAgY29uc3QgcmVzcG9uc2U6IEJhdGNoR2V0SXRlbUNvbW1hbmRPdXRwdXQgPSBhd2FpdCB0aGlzLmNsaWVudC5zZW5kKFxuICAgICAgICAgIG5ldyBCYXRjaEdldEl0ZW1Db21tYW5kKHtcbiAgICAgICAgICAgIFJlcXVlc3RJdGVtczoge1xuICAgICAgICAgICAgICBbdGFibGVOYW1lXToge1xuICAgICAgICAgICAgICAgIEtleXM6IGtleXMsXG4gICAgICAgICAgICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246IFwic2ssIHJldmFsaWRhdGVkQXQsIHN0YWxlQXQsIGV4cGlyZWRBdFwiLFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgfSxcbiAgICAgICAgICB9KSxcbiAgICAgICAgKTtcbiAgICAgICAgZm9yIChjb25zdCBpdGVtIG9mIHJlc3BvbnNlLlJlc3BvbnNlcz8uW3RhYmxlTmFtZV0gPz8gW10pIHtcbiAgICAgICAgICBjb25zdCB0YWcgPSB0YWdCeVNrLmdldChpdGVtLnNrPy5TID8/IFwiXCIpO1xuICAgICAgICAgIGlmICh0YWcgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgbWFya2Vycy5zZXQodGFnLCBtYXJrZXJPZihpdGVtKSk7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGtleXMgPSByZXNwb25zZS5VbnByb2Nlc3NlZEtleXM/Llt0YWJsZU5hbWVdPy5LZXlzO1xuICAgICAgfVxuICAgICAgaWYgKGtleXM/Lmxlbmd0aCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgYER5bmFtb0RCIGxlZnQgJHtrZXlzLmxlbmd0aH0gdGFnIG1hcmtlcnMgdW5yZWFkIGFmdGVyIHJldHJ5aW5nYCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG1hcmtlcnM7XG4gIH1cbn1cblxuLyoqXG4gKiBIb3cgbG9uZyBhIHJldmFsaWRhdGlvbiBsb2cgcm93IGlzIGtlcHQgKGB0dGxgLCBlcG9jaCBzZWNvbmRzKS4gRHluYW1vREIgbmV2ZXJcbiAqIGRlbGV0ZXMgYW4gaXRlbSBiZWZvcmUgaXRzIFRUTCwgb25seSBzb21lIHRpbWUgYWZ0ZXIsIHNvIGEgcmVhZGVyIHRoYXQgbGFzdFxuICogcXVlcmllZCBsZXNzIHRoYW4gdGhpcyBsb25nIGFnbyAobGVzcyBhIG1hcmdpbiBmb3Igd3JpdGVycycgY2xvY2tzKSBpcyBzdXJlXG4gKiB0byBmaW5kIGV2ZXJ5IHJvdyBpdCBoYXMgbm90IHNlZW4geWV0LlxuICovXG5leHBvcnQgY29uc3QgUkVWQUxJREFUSU9OX0xPR19UVExfTVMgPSAxNSAqIDYwICogMTAwMDtcblxuLyoqIFRoZSBtb3N0IGBRdWVyeWAgcGFnZXMgb25lIHtAbGluayBSZXZhbGlkYXRpb25Mb2cucXVlcnl9IHJlYWRzLiAqL1xuZXhwb3J0IGNvbnN0IFJFVkFMSURBVElPTl9MT0dfTUFYX1BBR0VTID0gNTtcblxuLyoqIEhvdyBtYW55IHNvcnQga2V5cyB7QGxpbmsgUmV2YWxpZGF0aW9uTG9nLnB1dH0gdHJpZXMgYmVmb3JlIGdpdmluZyB1cC4gKi9cbmNvbnN0IExPR19QVVRfQVRURU1QVFMgPSA1O1xuXG4vKiogRGlnaXRzIGEgbG9nIHJvdydzIHRpbWVzdGFtcCBpcyB6ZXJvLXBhZGRlZCB0bywgc28gc29ydCBrZXlzIHNvcnQgYnkgdGltZS4gKi9cbmNvbnN0IExPR19TS19ESUdJVFMgPSAxNTtcblxuLyoqIEEgcmV2YWxpZGF0aW9uIHJlYWQgYmFjayBmcm9tIHRoZSBsb2cuICovXG5leHBvcnQgaW50ZXJmYWNlIFJldmFsaWRhdGlvbkxvZ1JvdyB7XG4gIC8qKiBUaGUgcm93J3Mgc29ydCBrZXk6IHVuaXF1ZSBwZXIgcmV2YWxpZGF0aW9uIG9mIGEgdGFnLiAqL1xuICBzazogc3RyaW5nO1xuICAvKiogV2hlbiBpdCB3YXMgd3JpdHRlbiwgb24gdGhlIHdyaXRlcidzIGBEYXRlLm5vdygpYC4gKi9cbiAgYXQ6IG51bWJlcjtcbiAgdGFnOiBzdHJpbmc7XG4gIC8qKiBUaGUgbWFya2VyIGZpZWxkcyB0aGUgcmV2YWxpZGF0aW9uIHNldCwgYXMge0BsaW5rIG1hcmtlckZvcn0gcmV0dXJucyB0aGVtLiAqL1xuICBtYXJrZXI6IFRhZ01hcmtlcjtcbn1cblxuLyoqXG4gKiBUaGUgcmV2YWxpZGF0aW9uIGxvZzogb25lIHJvdyBwZXIgdGFnIHJldmFsaWRhdGlvbiAoYHBrID0gPGJ1aWxkSWQ+I2xvZ2AsXG4gKiBgc2sgPSA8RGF0ZS5ub3coKSwgemVyby1wYWRkZWQ+Izx0YWc+YCksIHdoaWNoIGV4cGlyZXMgYWZ0ZXJcbiAqIHtAbGluayBSRVZBTElEQVRJT05fTE9HX1RUTF9NU30uIEEgdGFnIHBhc3Qge0BsaW5rIE1BWF9UQUdfQllURVN9IGlzXG4gKiB7QGxpbmsgaGFzaGVkVGFnfSB0aGVyZSwgYW5kIHNwZWxsZWQgb3V0IGluIHRoZSByb3cncyBgbG9uZ1RhZ2AgaW5zdGVhZC5cbiAqXG4gKiBUaGUgbWFya2VyIHJvd3Mgc3RheSB0aGUgc291cmNlIG9mIHRydXRoLiBUaGUgbG9nIGV4aXN0cyBzbyBhbiBpbnN0YW5jZVxuICogY2FuIGFzayBcIndoYXQgd2FzIHJldmFsaWRhdGVkIHNpbmNlIEkgbGFzdCBsb29rZWQ/XCIgaW4gb25lIGBRdWVyeWAsIGluc3RlYWRcbiAqIG9mIHJlLXJlYWRpbmcgZXZlcnkgdGFnIGl0IHRyYWNrcyB0byBmaW5kIG91dCB0aGF0IGFsbW9zdCBub25lIGNoYW5nZWQuIEV2ZXJ5XG4gKiBtYXJrZXIgcm93IG9mIGEgZGVwbG95bWVudCBzaGFyZXMgb25lIHBhcnRpdGlvbiwgYW5kIHRob3NlIHJlLXJlYWRzIGZyb20gYVxuICogaGFuZGZ1bCBvZiBidXN5IGluc3RhbmNlcyB3ZXJlIGVub3VnaCB0byB0aHJvdHRsZSBpdC5cbiAqXG4gKiBUaGUgc29ydCBrZXkncyB0aW1lc3RhbXAgaXMgdGhlIHdyaXRlcidzIHdhbGwgY2xvY2sgKGBEYXRlLm5vdygpYCksIG5vdCB0aGVcbiAqIHBlcmZvcm1hbmNlIGNsb2NrICh7QGxpbmsgbWFya2VyQ2xvY2t9KSB0aGUgbWFya2VyIHZhbHVlcyBhcmUgc3RhbXBlZCB3aXRoIGJ5IGJvdGhcbiAqIGhhbmRsZXJzOiBpdCBvbmx5IG9yZGVycyByb3dzIGZvciByZWFkZXJzJyBjdXJzb3JzLCB3aGljaCBhcmUgb24gdGhlaXIgb3duXG4gKiB3YWxsIGNsb2NrcywgYW5kIGlzIG5ldmVyIGNvbXBhcmVkIHdpdGggYW4gZW50cnkncyB0aW1lc3RhbXAuXG4gKi9cbmV4cG9ydCBjbGFzcyBSZXZhbGlkYXRpb25Mb2cge1xuICBwcml2YXRlIHJlYWRvbmx5IHBrOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBjbGllbnQ6IER5bmFtb0RCQ2xpZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgdGFibGVOYW1lOiBzdHJpbmcsXG4gICAgYnVpbGRJZDogc3RyaW5nLFxuICApIHtcbiAgICB0aGlzLnBrID0gYCR7YnVpbGRJZH0jbG9nYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgdGhhdCBgdGFnYCB3YXMgcmV2YWxpZGF0ZWQgYXQgYGF0YCAoYERhdGUubm93KClgKSwgc2V0dGluZyBgbWFya2VyYC5cbiAgICpcbiAgICogVHdvIHJldmFsaWRhdGlvbnMgb2YgYHRhZ2AgaW4gdGhlIHNhbWUgbWlsbGlzZWNvbmQgd291bGQgc2hhcmUgYSBzb3J0IGtleSxcbiAgICogYW5kIHRoZSBzZWNvbmQgd291bGQgb3ZlcndyaXRlIHRoZSBmaXJzdC4gU28gdGhlIHJvdyBpcyBvbmx5IHdyaXR0ZW4gd2hlcmVcbiAgICogaXRzIGtleSBpcyBmcmVlLCBhbmQgb24gYSBjb2xsaXNpb24gaXQgbW92ZXMgdG8gdGhlIG5leHQgbWlsbGlzZWNvbmQsIHVwXG4gICAqIHRvIHtAbGluayBMT0dfUFVUX0FUVEVNUFRTfSB0aW1lcy5cbiAgICovXG4gIGFzeW5jIHB1dCh0YWc6IHN0cmluZywgYXQ6IG51bWJlciwgbWFya2VyOiBUYWdNYXJrZXIpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBjb25zdCBza1RhZyA9IHNvcnRLZXlUYWcodGFnKTtcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMTsgOyBhdHRlbXB0KyspIHtcbiAgICAgIGNvbnN0IGl0ZW06IFJlY29yZDxzdHJpbmcsIEF0dHJpYnV0ZVZhbHVlPiA9IHtcbiAgICAgICAgcGs6IHsgUzogdGhpcy5wayB9LFxuICAgICAgICBzazogeyBTOiBgJHtsb2dTa1ByZWZpeChhdCl9IyR7c2tUYWd9YCB9LFxuICAgICAgICB0dGw6IHsgTjogU3RyaW5nKE1hdGguY2VpbCgoYXQgKyBSRVZBTElEQVRJT05fTE9HX1RUTF9NUykgLyAxMDAwKSkgfSxcbiAgICAgICAgLi4uKHNrVGFnICE9PSB0YWcgJiYgeyBsb25nVGFnOiB7IFM6IHRhZyB9IH0pLFxuICAgICAgfTtcbiAgICAgIGZvciAoY29uc3QgZmllbGQgb2YgTUFSS0VSX0ZJRUxEUykge1xuICAgICAgICBjb25zdCB2YWx1ZSA9IG1hcmtlcltmaWVsZF07XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgaXRlbVtmaWVsZF0gPSB7IE46IFN0cmluZyh2YWx1ZSkgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgdHJ5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgICBuZXcgUHV0SXRlbUNvbW1hbmQoe1xuICAgICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICAgIEl0ZW06IGl0ZW0sXG4gICAgICAgICAgICBDb25kaXRpb25FeHByZXNzaW9uOiBcImF0dHJpYnV0ZV9ub3RfZXhpc3RzKHNrKVwiLFxuICAgICAgICAgIH0pLFxuICAgICAgICApO1xuICAgICAgICByZXR1cm47XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICBpZiAoXG4gICAgICAgICAgKGVycm9yIGFzIEVycm9yIHwgdW5kZWZpbmVkKT8ubmFtZSAhPT1cbiAgICAgICAgICAgIFwiQ29uZGl0aW9uYWxDaGVja0ZhaWxlZEV4Y2VwdGlvblwiIHx8XG4gICAgICAgICAgYXR0ZW1wdCA+PSBMT0dfUFVUX0FUVEVNUFRTXG4gICAgICAgICkge1xuICAgICAgICAgIHRocm93IGVycm9yO1xuICAgICAgICB9XG4gICAgICAgIGF0ID0gTWF0aC5mbG9vcihhdCkgKyAxO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgcm93cyB3cml0dGVuIGF0IG9yIGFmdGVyIGBzaW5jZWAgKGBEYXRlLm5vdygpYCksIG9sZGVzdCBmaXJzdC5cbiAgICogYHRydW5jYXRlZGAgd2hlbiB0aGVyZSB3ZXJlIG1vcmUgdGhhbiB7QGxpbmsgUkVWQUxJREFUSU9OX0xPR19NQVhfUEFHRVN9XG4gICAqIHBhZ2VzIG9mIHRoZW0sIGFuZCBgcm93c2AgaXMgb25seSB0aGUgc3RhcnQuXG4gICAqXG4gICAqIEV2ZW50dWFsbHkgY29uc2lzdGVudDogYSByb3cgd3JpdHRlbiBhIG1vbWVudCBhZ28gbWF5IG5vdCBzaG93IHlldCwgd2hpY2hcbiAgICogaXMgd2hhdCB0aGUgcmVhZGVyJ3MgbG9va2JhY2sgaXMgZm9yLlxuICAgKi9cbiAgYXN5bmMgcXVlcnkoXG4gICAgc2luY2U6IG51bWJlcixcbiAgKTogUHJvbWlzZTx7IHJvd3M6IFJldmFsaWRhdGlvbkxvZ1Jvd1tdOyB0cnVuY2F0ZWQ6IGJvb2xlYW4gfT4ge1xuICAgIGNvbnN0IHJvd3M6IFJldmFsaWRhdGlvbkxvZ1Jvd1tdID0gW107XG4gICAgbGV0IHN0YXJ0S2V5OiBSZWNvcmQ8c3RyaW5nLCBBdHRyaWJ1dGVWYWx1ZT4gfCB1bmRlZmluZWQ7XG4gICAgZm9yIChsZXQgcGFnZSA9IDA7IHBhZ2UgPCBSRVZBTElEQVRJT05fTE9HX01BWF9QQUdFUzsgcGFnZSsrKSB7XG4gICAgICBjb25zdCByZXNwb25zZTogUXVlcnlDb21tYW5kT3V0cHV0ID0gYXdhaXQgdGhpcy5jbGllbnQuc2VuZChcbiAgICAgICAgbmV3IFF1ZXJ5Q29tbWFuZCh7XG4gICAgICAgICAgVGFibGVOYW1lOiB0aGlzLnRhYmxlTmFtZSxcbiAgICAgICAgICBLZXlDb25kaXRpb25FeHByZXNzaW9uOiBcInBrID0gOnBrIEFORCBzayA+PSA6c2luY2VcIixcbiAgICAgICAgICBFeHByZXNzaW9uQXR0cmlidXRlVmFsdWVzOiB7XG4gICAgICAgICAgICBcIjpwa1wiOiB7IFM6IHRoaXMucGsgfSxcbiAgICAgICAgICAgIFwiOnNpbmNlXCI6IHsgUzogbG9nU2tQcmVmaXgoTWF0aC5tYXgoMCwgc2luY2UpKSB9LFxuICAgICAgICAgIH0sXG4gICAgICAgICAgUHJvamVjdGlvbkV4cHJlc3Npb246XG4gICAgICAgICAgICBcInNrLCBsb25nVGFnLCByZXZhbGlkYXRlZEF0LCBzdGFsZUF0LCBleHBpcmVkQXRcIixcbiAgICAgICAgICBFeGNsdXNpdmVTdGFydEtleTogc3RhcnRLZXksXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICAgIGZvciAoY29uc3QgaXRlbSBvZiByZXNwb25zZS5JdGVtcyA/PyBbXSkge1xuICAgICAgICBjb25zdCBzayA9IGl0ZW0uc2s/LlM7XG4gICAgICAgIC8vIGA8ZGlnaXRzPiM8dGFnPmA6IHRoZSB0YWcgaXMgZXZlcnl0aGluZyBhZnRlciB0aGUgZml4ZWQtd2lkdGhcbiAgICAgICAgLy8gdGltZXN0YW1wLCBgI2BzIGluY2x1ZGVkLlxuICAgICAgICBpZiAoc2sgPT09IHVuZGVmaW5lZCB8fCBza1tMT0dfU0tfRElHSVRTXSAhPT0gXCIjXCIpIHtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgICAgfVxuICAgICAgICByb3dzLnB1c2goe1xuICAgICAgICAgIHNrLFxuICAgICAgICAgIGF0OiBOdW1iZXIoc2suc2xpY2UoMCwgTE9HX1NLX0RJR0lUUykpLFxuICAgICAgICAgIHRhZzogaXRlbS5sb25nVGFnPy5TID8/IHNrLnNsaWNlKExPR19TS19ESUdJVFMgKyAxKSxcbiAgICAgICAgICBtYXJrZXI6IG1hcmtlck9mKGl0ZW0pLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIHN0YXJ0S2V5ID0gcmVzcG9uc2UuTGFzdEV2YWx1YXRlZEtleTtcbiAgICAgIGlmICghc3RhcnRLZXkpIHtcbiAgICAgICAgcmV0dXJuIHsgcm93cywgdHJ1bmNhdGVkOiBmYWxzZSB9O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4geyByb3dzLCB0cnVuY2F0ZWQ6IHRydWUgfTtcbiAgfVxufVxuXG5mdW5jdGlvbiBsb2dTa1ByZWZpeChhdDogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIFN0cmluZyhNYXRoLmZsb29yKGF0KSkucGFkU3RhcnQoTE9HX1NLX0RJR0lUUywgXCIwXCIpO1xufVxuXG4vKipcbiAqIEhvdyBmYXIgYmVoaW5kIHRoZSBsYXN0IHF1ZXJ5J3Mgc3RhcnQgdGhlIG5leHQgb25lIHN0YXJ0cyByZWFkaW5nIHRoZSBsb2c6XG4gKiB0aGUgcm9vbSBmb3IgdGhlIGBRdWVyeWAgYmVpbmcgZXZlbnR1YWxseSBjb25zaXN0ZW50IGFuZCBmb3Igd3JpdGVycycgY2xvY2tzXG4gKiBydW5uaW5nIGJlaGluZCB0aGUgcmVhZGVyJ3MuIFJvd3MgaW5zaWRlIGl0IGFyZSByZWFkIGFnYWluLCBhbmQgZHJvcHBlZCBhc1xuICogYWxyZWFkeSBhcHBsaWVkLlxuICovXG5leHBvcnQgY29uc3QgUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUyA9IDUwMDA7XG5cbi8qKlxuICogVGhlIGxvbmdlc3Qge0BsaW5rIFRyYWNrZWRUYWdNYXJrZXJzfSB0cnVzdHMgdGhlIGxvZyBhbG9uZSBmb3IgYSB0YWcgYmVmb3JlXG4gKiByZWFkaW5nIGl0cyBtYXJrZXIgcm93IGFnYWluLiBUaGUgbG9nIGlzIHRoZSBmYXN0IHBhdGgsIGJ1dCB0aGUgbWFya2VyIHJvd3NcbiAqIGFyZSB0aGUgc291cmNlIG9mIHRydXRoOiBhIGxvZyByb3cgd2hvc2Ugd3JpdGUgZmFpbGVkIHdvdWxkIG90aGVyd2lzZSBiZVxuICogbWlzc2VkIGZvciBhcyBsb25nIGFzIHRoZSB0YWcgc3RheXMgdHJhY2tlZC5cbiAqXG4gKiBSb2xsaW5nLCBub3QgYWxsIGF0IG9uY2U6IGVhY2ggcmVmcmVzaCByZS1yZWFkcyBhdCBtb3N0XG4gKiB7QGxpbmsgQkFUQ0hfR0VUX01BWF9LRVlTfSBvZiB0aGUgdGFncyBkdWUsIG9sZGVzdCBmaXJzdC4gUmUtcmVhZGluZyB0aGVtIGFsbFxuICogdG9nZXRoZXIgY29zdCB+NTAwIFJDVSBhdCAxMDAwIHRhZ3MgLSBhIGZsZWV0IHN0YXJ0ZWQgYnkgb25lIGxvYWQgdGVzdCBkaWQgaXRcbiAqIGluIHRoZSBzYW1lIG1pbnV0ZSwgMTIsODAwIFJDVSwgYW5kIHRocm90dGxlZCAtIGFuZCB3b3VsZCBiZSB+NSwwMDAgUkNVIGF0XG4gKiB7QGxpbmsgREVGQVVMVF9NQVhfVFJBQ0tFRF9UQUdTfSwgcGFzdCB3aGF0IHRoZSBvbmUgcGFydGl0aW9uIHNlcnZlcyBpbiBhXG4gKiBzZWNvbmQuIFNwcmVhZCBvdXQsIDEwLDAwMCB0cmFja2VkIHRhZ3MgY29zdCB+OCBSQ1UgYSBzZWNvbmQgcGVyIGluc3RhbmNlLlxuICpcbiAqIEVhY2ggdGFnIGlzIGR1ZSBhdCBhIHJhbmRvbSA3NS0xMDAlIG9mIHRoaXMgYWZ0ZXIgaXQgd2FzIGxhc3QgcmVhZCwgc28gdGFnc1xuICogZmlyc3QgcmVhZCB0b2dldGhlciAtIGFuIGluc3RhbmNlIHdhcm1pbmcgdXAgLSBkbyBub3QgYWxsIGNvbWUgZHVlIHRvZ2V0aGVyXG4gKiBhZ2FpbiBldmVyeSBpbnRlcnZhbDogdGhlIGxvYWQgdGVzdCB0aGF0IG1lYXN1cmVkIHRoZSByb2xsaW5nIHJlLXJlYWQgc2F3XG4gKiBpdHMgd2FybS11cCdzIHJlYWRzIHJldHVybiBhcyBhIDMwLTM2IFJDVS9zIGJ1bXAgdGVuIG1pbnV0ZXMgbGF0ZXIuXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX1RBR19SRVNZTkNfTVMgPSAxMCAqIDYwICogMTAwMDtcblxuLyoqIFRoZSBmcmFjdGlvbiBvZiB7QGxpbmsgREVGQVVMVF9UQUdfUkVTWU5DX01TfSBhIHRhZyBtYXkgY29tZSBkdWUgZWFybHkgYnkuICovXG5jb25zdCBUQUdfUkVTWU5DX0pJVFRFUiA9IDAuMjU7XG5cbi8qKlxuICogSG93IGxvbmcgc2luY2UgdGhlIGxhc3Qgc3VjY2Vzc2Z1bCBsb2cgcXVlcnkgdGhlIGxvZyBjYW4gc3RpbGwgYmUgdHJ1c3RlZCB0b1xuICogaG9sZCBldmVyeSByb3cgbm90IHJlYWQgeWV0OiBpdHMgVFRMIGxlc3MgYSBtYXJnaW4gZm9yIHdyaXRlcnMnIGNsb2Nrcy4gUGFzdFxuICogaXQgLSBhIExhbWJkYSBmcm96ZW4gYmV0d2VlbiBpbnZvY2F0aW9ucywgYSBydW4gb2YgZmFpbGVkIHF1ZXJpZXMgLSB0aGVcbiAqIHRyYWNrZWQgbWFya2VycyBhcmUgZm9yZ290dGVuLCB0byBiZSByZWFkIGFnYWluIGFzIHRoZXkgYXJlIG5lZWRlZCwgYW5kIHRoZVxuICogbG9nIGlzIGZvbGxvd2VkIGZyb20gdGhlcmUuXG4gKi9cbmV4cG9ydCBjb25zdCBNQVhfUkVWQUxJREFUSU9OX0xPR19HQVBfTVMgPVxuICBSRVZBTElEQVRJT05fTE9HX1RUTF9NUyAtIDUgKiA2MCAqIDEwMDA7XG5cbi8qKlxuICogVGhlIG1vc3QgdGFncyBvbmUgaW5zdGFuY2UgdHJhY2tzLiBQYXN0IGl0IHRoZSBsZWFzdCByZWNlbnRseSB1c2VkIGlzXG4gKiBmb3Jnb3R0ZW4sIHdoaWNoIGNvc3RzIGEgcmVhZCB0aGUgbmV4dCB0aW1lIGl0IGlzIG5lZWRlZDogYW4gdW50cmFja2VkIHRhZ1xuICogaXMgcmVhZCBiZWZvcmUgaXQgaXMgdHJ1c3RlZC5cbiAqXG4gKiBBIHRyYWNrZWQgdGFnIGNvc3RzIG1lbW9yeSAofjIgTUIgYXQgdGhpcyBib3VuZCkgYW5kIGl0cyBzaGFyZSBvZiB0aGUgcm9sbGluZ1xuICogcmUtcmVhZCwgbm90IGEgcmVhZCBldmVyeSByZWZyZXNoLCBzbyB0aGUgYm91bmQgaXMgc2V0IGJ5IGhvdyBtYW55IHRhZ3MgYW5cbiAqIGluc3RhbmNlIHJlYWxseSB1c2VzLiBFdmVyeSBwYXRoIGlzIGEgdGFnIG9mIGl0cyBvd24gKGBfTl9UXy88cGF0aD5gKSwgYW5kIGF0XG4gKiAxMDAwIGFuIGFwcCBvZiAxMDAwIHRhZ2dlZCBwYWdlcyBrZXB0IGV2aWN0aW5nIHdoYXQgaXQgd2FzIGFib3V0IHRvIG5lZWQ6XG4gKiBoYWxmIGl0cyByZXF1ZXN0cyByZS1yZWFkIGEgbWFya2VyLlxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9NQVhfVFJBQ0tFRF9UQUdTID0gMTBfMDAwO1xuXG4vKipcbiAqIFRoZSByZXZhbGlkYXRpb24gdGFibGUncyBtYXJrZXIgcm93cyBhbmQgaXRzIGxvZywgd2hpY2ggYXJlIG9ubHkgZXZlciB1c2VkXG4gKiB0b2dldGhlciwgb3IgbmVpdGhlciBmb3IgdGFncyBsb2NhbCB0byB0aGlzIHByb2Nlc3MuXG4gKi9cbmV4cG9ydCB0eXBlIFRhZ1RhYmxlID1cbiAgfCB7IG1hcmtlcnM6IFRhZ01hcmtlclRhYmxlOyBsb2c6IFJldmFsaWRhdGlvbkxvZyB9XG4gIHwgeyBtYXJrZXJzPzogdW5kZWZpbmVkOyBsb2c/OiB1bmRlZmluZWQgfTtcblxuLyoqIEhvdyB7QGxpbmsgVHJhY2tlZFRhZ01hcmtlcnN9IGlzIGJ1aWx0LiAqL1xuZXhwb3J0IHR5cGUgVHJhY2tlZFRhZ01hcmtlcnNPcHRpb25zID0gVGFnVGFibGUgJiB7XG4gIC8qKlxuICAgKiBIb3cgb2Z0ZW4sIGF0IG1vc3QsIHtAbGluayBUcmFja2VkVGFnTWFya2Vycy5yZWZyZXNofSByZWFkcyBhbnl0aGluZy5cbiAgICogQGRlZmF1bHQgREVGQVVMVF9UQUdfUkVGUkVTSF9NU1xuICAgKi9cbiAgcmVmcmVzaEludGVydmFsTXM/OiBudW1iZXI7XG4gIG1heFRyYWNrZWRUYWdzPzogbnVtYmVyO1xuICAvKiogQHNlZSBERUZBVUxUX1RBR19SRVNZTkNfTVMgKi9cbiAgcmVzeW5jSW50ZXJ2YWxNcz86IG51bWJlcjtcbiAgLyoqIFRoZSB3YWxsIGNsb2NrIHRoZSBsb2cncyBjdXJzb3IgYW5kIHRoZSBpbnRlcnZhbHMgYXJlIGtlcHQgb24uICovXG4gIGNsb2NrPzogKCkgPT4gbnVtYmVyO1xuICAvKiogYE1hdGgucmFuZG9tYCwgZm9yIHdoZW4gZWFjaCB0YWcncyByZS1yZWFkIGNvbWVzIGR1ZS4gKi9cbiAgcmFuZG9tPzogKCkgPT4gbnVtYmVyO1xuICBkZWJ1Zz86IChtZXNzYWdlOiBzdHJpbmcpID0+IHZvaWQ7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBwcm9jZXNzIGNhbiBiZSBmcm96ZW4gd2l0aCBhIHJlZnJlc2ggaW4gZmxpZ2h0LCBhcyBhIExhbWJkYVxuICAgKiBzYW5kYm94IGlzIGJldHdlZW4gaW52b2NhdGlvbnM6IHRoZW4gYSB0aW1lciBjaGVja3MgaXQga2VwdCBydW5uaW5nLCBhbmRcbiAgICogb25lIHRoYXQgc3Bhbm5lZCBhIGZyZWV6ZSBkb2VzIG5vdCBjb3VudC4gQSBjb250YWluZXIgaXMgbmV2ZXIgZnJvemVuLFxuICAgKiBzbyBpdCBza2lwcyB0aGUgdGltZXIgYW5kIHdhaXRzIGZvciB0aGUgcmVmcmVzaCBpbiBmbGlnaHQsIGhvd2V2ZXIgc2xvdy5cbiAgICogQGRlZmF1bHQgZmFsc2VcbiAgICovXG4gIGNhbkZyZWV6ZT86IGJvb2xlYW47XG59O1xuXG4vKipcbiAqIE9uZSBpbnN0YW5jZSdzIGNvcHkgb2YgdGhlIG1hcmtlciByb3dzIG9mIHRoZSB0YWdzIGl0IGhhcyBuZWVkZWQsIGtlcHRcbiAqIGN1cnJlbnQgdGhyb3VnaCB0aGUge0BsaW5rIFJldmFsaWRhdGlvbkxvZ306IHRoZSBwcm9jZXNzJ3Mgb25lIHRhZyBtYW5pZmVzdFxuICogKGBzaGFyZWRUYWdNYW5pZmVzdGApLCBmb3IgdGhlIGAndXNlIGNhY2hlJ2AgaGFuZGxlcnMgYW5kIHRoZSBpbmNyZW1lbnRhbFxuICogY2FjaGUgYWxpa2UuXG4gKlxuICogTmV4dC5qcydzIGJ1aWx0LWluIGAndXNlIGNhY2hlJ2AgaGFuZGxlciBrZWVwcyB0YWdzIGluIGEgbW9kdWxlLWxldmVsIG1hcFxuICogKGB0YWdzLW1hbmlmZXN0LmV4dGVybmFsLmpzYCkgdGhhdCBvbmx5IGl0cyBvd24gYHVwZGF0ZVRhZ3NgIHdyaXRlcywgYW5kIGl0c1xuICogYHJlZnJlc2hUYWdzYCBpcyBhIG5vLW9wLCBzbyBhIGByZXZhbGlkYXRlVGFnYCBvbiBvbmUgaW5zdGFuY2UgbmV2ZXIgcmVhY2hlc1xuICogdGhlIG90aGVyczogdGhleSBrZWVwIHNlcnZpbmcgdGhlIHJldmFsaWRhdGVkIGVudHJ5LCBpbmNsdWRpbmcgaW5zaWRlIHBhZ2VzXG4gKiB0aGF0IGFyZSBiZWluZyByZS1yZW5kZXJlZCAqYmVjYXVzZSogb2YgdGhhdCByZXZhbGlkYXRpb24uIFRoZVxuICogYGNhY2hlSGFuZGxlcnNgIGludGVyZmFjZSdzIGFuc3dlciBpcyBgcmVmcmVzaFRhZ3NgLCBcImNhbGxlZCBiZWZvcmUgc3RhcnRpbmdcbiAqIGEgbmV3IHJlcXVlc3Qg4oCmIHRvIHJlZnJlc2ggdGhlIGxvY2FsIHRhZ3MgbWFuaWZlc3RcIiwgYW5kIHRoaXMgaXMgdGhhdFxuICogbWFuaWZlc3QsIGJhY2tlZCBieSB0aGUgc2FtZSBtYXJrZXIgcm93cyB0aGUgaW5jcmVtZW50YWwgY2FjaGUnc1xuICogYHJldmFsaWRhdGVUYWdgIHdyaXRlcyAoYHBrID0gYnVpbGRJZGAsIGBzayA9IHRhZ2ApLlxuICpcbiAqIFRoZSBjb3N0IGlzIGJvdW5kZWQgcGVyIGluc3RhbmNlLCBub3QgcGVyIHJlcXVlc3Q6XG4gKiAtIHtAbGluayBlbnN1cmV9IHJlYWRzIGEgdGFnJ3MgbWFya2VyIHRoZSBmaXJzdCB0aW1lIGl0IGlzIG5lZWRlZCBhbmQgbm90XG4gKiAgIGFnYWluIHVudGlsIGl0IGlzIGV2aWN0ZWQsIHNvIGEgdGFnIGNvc3RzIG9uZSByZWFkIHBlciBpbnN0YW5jZSwgbm90IG9uZVxuICogICBwZXIgcmVxdWVzdC4gQW4gZW50cnkgY3JlYXRlZCBzaW5jZSB7QGxpbmsgY29tcGxldGVTaW5jZX0gbmVlZHMgbm8gcmVhZFxuICogICBhdCBhbGwuXG4gKiAtIHtAbGluayByZWZyZXNofSwgYXQgbW9zdCBvbmNlIHBlciBgcmVmcmVzaEludGVydmFsTXNgLCBzZW5kcyBvbmUgYFF1ZXJ5YFxuICogICBmb3IgdGhlIGxvZyByb3dzIHdyaXR0ZW4gc2luY2UgdGhlIGxhc3Qgb25lLCBhbmQgYXBwbGllcyB0aG9zZSBvZiB0YWdzXG4gKiAgIHRoaXMgaW5zdGFuY2UgdHJhY2tzLiBDb25jdXJyZW50IGNhbGxlcnMgc2hhcmUgaXQuIEFsb25nc2lkZSwgaXQgcmUtcmVhZHNcbiAqICAgdGhlIG1hcmtlcnMgb2YgdXAgdG8ge0BsaW5rIEJBVENIX0dFVF9NQVhfS0VZU30gdGFncyBub3QgcmVhZCBmb3JcbiAqICAge0BsaW5rIERFRkFVTFRfVEFHX1JFU1lOQ19NU30sIGluIG9uZSBgQmF0Y2hHZXRJdGVtYC5cbiAqIEEgcmV2YWxpZGF0aW9uIG9uIGFub3RoZXIgaW5zdGFuY2UgaXMgdGhlcmVmb3JlIHNlZW4gd2l0aGluXG4gKiBgcmVmcmVzaEludGVydmFsTXNgIChwbHVzIHRoZSBxdWVyeSBpdHNlbGYpIC0gYnkgYCd1c2UgY2FjaGUnYCwgZnJvbSB0aGVcbiAqIGZpcnN0IHJlcXVlc3QgYWZ0ZXIgdGhlIHF1ZXJ5IHJldHVybnMsIHNpbmNlIGl0cyBgcmVmcmVzaFRhZ3NgIGRvZXMgbm90IHdhaXRcbiAqIGZvciBpdCAoc2VlIGB0YWdNZXRob2RzYCkgdW5sZXNzIHRoZSBpbnN0YW5jZSBpcyB7QGxpbmsgYmVoaW5kfSwgd2hpY2ggdGhlXG4gKiBydW50aW1lIHNldHRsZXMgYmVmb3JlIGEgcGFnZSByZW5kZXIgc3RhcnRzICh7QGxpbmsgY2F0Y2hVcH0pLiBUaGUgaW5zdGFuY2VcbiAqIHRoYXQgcmFuIGl0IGFwcGxpZXMgaXQgaXRzZWxmLCBhdCBvbmNlLCB3aXRoIHtAbGluayBzZXR9LlxuICovXG5leHBvcnQgY2xhc3MgVHJhY2tlZFRhZ01hcmtlcnMge1xuICBwcml2YXRlIHJlYWRvbmx5IG1hcmtlcnM6IFRhZ01hcmtlclRhYmxlIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZzogUmV2YWxpZGF0aW9uTG9nIHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZnJlc2hJbnRlcnZhbE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWF4VHJhY2tlZFRhZ3M6IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSByZXN5bmNJbnRlcnZhbE1zOiBudW1iZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2xvY2s6ICgpID0+IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSByYW5kb206ICgpID0+IG51bWJlcjtcbiAgcHJpdmF0ZSByZWFkb25seSBkZWJ1ZzogKG1lc3NhZ2U6IHN0cmluZykgPT4gdm9pZDtcbiAgLyoqIEJ5IHRhZywgbGVhc3QgcmVjZW50bHkgdXNlZCBmaXJzdC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSB0YWdzID0gbmV3IE1hcDxzdHJpbmcsIFRhZ01hcmtlcj4oKTtcbiAgLyoqXG4gICAqIFdoZW4gZWFjaCB0cmFja2VkIHRhZydzIG1hcmtlciBpcyBkdWUgdG8gYmUgcmVhZCBhZ2FpbjogYSByYW5kb20gNzUtMTAwJVxuICAgKiBvZiBgcmVzeW5jSW50ZXJ2YWxNc2AgYWZ0ZXIgaXQgd2FzIGxhc3Qga25vd24gZnJvbSB0aGUgdGFibGUgLSByZWFkLFxuICAgKiB3cml0dGVuIGhlcmUsIG9yIG5ldy4gSW4gdGhlIG9yZGVyIHRoZXkgYmVjYW1lIGtub3duLCBsZWFzdCByZWNlbnQgZmlyc3QuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGR1ZUF0ID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSByZWFkaW5nID0gbmV3IE1hcDxzdHJpbmcsIFByb21pc2U8dm9pZD4+KCk7XG4gIC8qKlxuICAgKiBMb2cgcm93cyBmb3IgdGFncyB3aG9zZSBmaXJzdCByZWFkIGlzIGluIGZsaWdodCwgbWVyZ2VkIGJ5IHRhZzogdGhlIHJlYWRcbiAgICogbWF5IGhhdmUgYmVlbiBhbnN3ZXJlZCBiZWZvcmUgdGhlIHJldmFsaWRhdGlvbiwgc28gdGhleSBhcmUgYXBwbGllZCB0byBpdHNcbiAgICogcmVzdWx0IHJhdGhlciB0aGFuIGRyb3BwZWQuXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHBlbmRpbmdSb3dzID0gbmV3IE1hcDxzdHJpbmcsIFRhZ01hcmtlcj4oKTtcbiAgLyoqXG4gICAqIExvZyByb3dzIGZvciB0YWdzIG5vdCB0cmFja2VkIGFuZCBub3QgYmVpbmcgcmVhZCwgbWVyZ2VkIGJ5IHRhZywgb2xkZXN0XG4gICAqIGZpcnN0OiB3aGF0IHRoZSBsb2cgaGFzIHNhaWQgYWJvdXQgdGhlbSBzaW5jZSB7QGxpbmsgY29tcGxldGVTaW5jZX0uIFRha2VuXG4gICAqIGludG8gYSB0YWcncyBtYXJrZXIgd2hlbiBpdCBpcyByZWFkIG9yIHdyaXR0ZW4uXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGxvZ09ubHkgPSBuZXcgTWFwPHN0cmluZywgVGFnTWFya2VyPigpO1xuICAvKiogU2VlIHtAbGluayBjb21wbGV0ZVNpbmNlfS4gKi9cbiAgcHJpdmF0ZSBmbG9vcjogbnVtYmVyO1xuICAvKipcbiAgICogVGhlIGZ1dHVyZSBgZXhwaXJlZEF0YHMgb2YgbWFya2VycyBkcm9wcGVkIHNpbmNlLCBhcyBgW2Zyb20sIHRvXWAsIGluXG4gICAqIG9yZGVyOiBvbmNlIGBmcm9tYCBpcyBwYXN0LCB7QGxpbmsgY29tcGxldGVTaW5jZX0gbW92ZXMgdG8gYHRvYCwgYW5kIG5vdFxuICAgKiBiZWZvcmUsIHNpbmNlIG9ubHkgdGhlbiBkb2VzIGl0IGV4cGlyZSBhbnl0aGluZy4gYGZyb21gIGFuZCBgdG9gIGFyZSB0aGVcbiAgICogc2FtZSB1bnRpbCBzcGFucyBhcmUgbWVyZ2VkIGZvciBzcGFjZSAoe0BsaW5rIGxhdGVyRmxvb3J9KS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgbGF0ZXJGbG9vcnM6IFtudW1iZXIsIG51bWJlcl1bXSA9IFtdO1xuICAvKiogVGhlIGluLW1lbW9yeSBlbnRyeSBzdG9yZXMganVkZ2VkIGJ5IHtAbGluayBjb21wbGV0ZVNpbmNlfS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBlbnRyeVN0b3Jlczoge1xuICAgIG9sZGVzdFRpbWVzdGFtcDogKHNjYW46IGJvb2xlYW4pID0+IG51bWJlcjtcbiAgICBob2xkc0FueTogKCkgPT4gYm9vbGVhbjtcbiAgfVtdID0gW107XG4gIC8qKiBIb3cgbWFueSB0aW1lcyB7QGxpbmsgZm9yZ2V0fSByYW46IGEgcmVhZCBzdGFydGVkIGJlZm9yZSBvbmUgaXMgbWFkZSBhZ2Fpbi4gKi9cbiAgcHJpdmF0ZSBmb3Jnb3R0ZW4gPSAwO1xuICAvKiogVHJhY2tlZCB0YWdzIHdob3NlIHJlYWQgZmFpbGVkLCBmb3IgdGhlIG5leHQgcmVmcmVzaCB0byByZWFkIGFnYWluLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IHVucmVhZCA9IG5ldyBTZXQ8c3RyaW5nPigpO1xuICAvKipcbiAgICogU2V0IGluc2lkZSBhIHBhZ2UgcmVuZGVyIHtAbGluayBjYXRjaFVwfSBsZXQgZ28sIGZvciB0aGF0IHJlbmRlciBhbG9uZS5cbiAgICogU2VlIHtAbGluayBiZWhpbmRJblJlbmRlcn0uXG4gICAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGNhdWdodFVwUmVuZGVyID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlPHRydWU+KCk7XG4gIC8qKiBXaGVuIGBzeW5jYCBsYXN0IHNjYW5uZWQgdGhlIGVudHJ5IHN0b3JlcyAoe0BsaW5rIG9sZGVzdEVudHJ5fSkuICovXG4gIHByaXZhdGUgbGFzdEVudHJ5U2NhbiA9IC1JbmZpbml0eTtcbiAgLyoqXG4gICAqIE5vIGBsb2dPbmx5YCByb3cgaXMga25vd24gYnkgaXQgb3IgZWFybGllciwgc28gYSB7QGxpbmsgcHJ1bmVMb2dnZWR9XG4gICAqIGFnYWluc3QgaXQgb3IgZWFybGllciBkcm9wcyBub3RoaW5nOiBhIG1hcmtlciBpcyBvbmx5IGV2ZXIga25vd24gYnkgbGF0ZXIsXG4gICAqIGFzIGl0cyBgZXhwaXJlZEF0YCBwYXNzZXMuXG4gICAqL1xuICBwcml2YXRlIHBydW5lZEFnYWluc3QgPSAtSW5maW5pdHk7XG4gIC8qKiBXaGVuIHRoZSBsYXN0IHJlZnJlc2ggc3RhcnRlZCwgb3Igd2FzIHNraXBwZWQuICovXG4gIHByaXZhdGUgbGFzdFJlZnJlc2ggPSAtSW5maW5pdHk7XG4gIC8qKlxuICAgKiBUaGUgcmVmcmVzaCBpbiBmbGlnaHQuIE9uZSBsZWZ0IG9wZW4gYWNyb3NzIGEgZnJlZXplIGNvbWVzIGJhY2sgYWZ0ZXIgdGhlXG4gICAqIHRoYXcgd2l0aCB3aGF0IGl0IHJlYWQgYmVmb3JlLCBzbyB7QGxpbmsgcmVmcmVzaH0gd2FpdHMgZm9yIGl0IGFuZCB0aGVuXG4gICAqIGZvciBhIGZyZXNoIG9uZSwgcmF0aGVyIHRoYW4gdGhlIHJ1bnRpbWUgd2FpdGluZyBmb3IgaXQgYmVmb3JlIHRoZSBmcmVlemU6XG4gICAqIHRoYXQgd291bGQgYmlsbCBldmVyeSBMYW1iZGEgaW52b2NhdGlvbiBmb3IgdGhlIHF1ZXJ5J3MgdGFpbC5cbiAgICovXG4gIHByaXZhdGUgcmVmcmVzaGluZzogUHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZDtcbiAgLyoqXG4gICAqIFdoZW4ge0BsaW5rIHJlZnJlc2hpbmd9IGxhc3Qgc2hvd2VkIHRoZSBwcm9jZXNzIHJ1bm5pbmc6IGEgdGltZXIgdGlja3NcbiAgICogd2hpbGUgaXQgaXMgaW4gZmxpZ2h0LCBhbmQgYSB0aWNrIHRoYXQgY29tZXMgbGF0ZSwgb3Igbm9uZSBhdCBhbGwsIG1lYW5zXG4gICAqIHRoZSBwcm9jZXNzIHdhcyBwYXVzZWQgLSBmcm96ZW4gLSBzaW5jZSBpdCBzdGFydGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBsYXN0VGljayA9IC1JbmZpbml0eTtcbiAgLyoqIFdoZXRoZXIgYSB0aWNrIGNhbWUgbGF0ZSBzaW5jZSB7QGxpbmsgcmVmcmVzaGluZ30gc3RhcnRlZC4gKi9cbiAgcHJpdmF0ZSBwYXVzZWRXaGlsZVJlZnJlc2hpbmcgPSBmYWxzZTtcbiAgcHJpdmF0ZSB0aWNrZXI6IFJldHVyblR5cGU8dHlwZW9mIHNldEludGVydmFsPiB8IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSByZWFkb25seSBjYW5GcmVlemU6IGJvb2xlYW47XG4gIC8qKlxuICAgKiBXaGVuIHRoZSBsYXN0IHJlZnJlc2ggc2V0dGxlZCwgZWl0aGVyIHdheSwgdW5sZXNzIGl0IHNwYW5uZWQgYSBwYXVzZTogd2hhdFxuICAgKiBpdCBrbm93cyBpcyBmcm9tIHRoZW4uIFNlZSB7QGxpbmsgYmVoaW5kfS5cbiAgICovXG4gIHByaXZhdGUgc2V0dGxlZEF0OiBudW1iZXI7XG4gIC8qKlxuICAgKiBXaGVyZSB0aGUgbmV4dCBsb2cgcXVlcnkgc3RhcnRzIChgY2xvY2soKWApOiB0aGUgbGFzdCBzdWNjZXNzZnVsIG9uZSdzXG4gICAqIHN0YXJ0LCBsZXNzIHtAbGluayBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TfS5cbiAgICovXG4gIHByaXZhdGUgY3Vyc29yOiBudW1iZXI7XG4gIC8qKiBXaGVuIHRoZSBsYXN0IHN1Y2Nlc3NmdWwgbG9nIHF1ZXJ5IHN0YXJ0ZWQsIG9yIHRoZSBsb2cgd2FzIGZpcnN0IHJlYWQuICovXG4gIHByaXZhdGUgbGFzdExvZ1JlYWQ6IG51bWJlcjtcbiAgLyoqIExvZyByb3dzIGF0IG9yIGFmdGVyIHRoZSBjdXJzb3IgYWxyZWFkeSBhcHBsaWVkLCBieSBzb3J0IGtleS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBhcHBsaWVkID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcbiAgLyoqIHtAbGluayB1cGRhdGV9cyBvZiB0aGUgY3VycmVudCB0dXJuLCBieSB0aGVpciBhcmd1bWVudHMuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgdXBkYXRpbmcgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTxib29sZWFuPj4oKTtcblxuICBjb25zdHJ1Y3RvcihvcHRpb25zOiBUcmFja2VkVGFnTWFya2Vyc09wdGlvbnMpIHtcbiAgICB0aGlzLm1hcmtlcnMgPSBvcHRpb25zLm1hcmtlcnM7XG4gICAgdGhpcy5sb2cgPSBvcHRpb25zLmxvZztcbiAgICB0aGlzLnJlZnJlc2hJbnRlcnZhbE1zID1cbiAgICAgIG9wdGlvbnMucmVmcmVzaEludGVydmFsTXMgPz8gREVGQVVMVF9UQUdfUkVGUkVTSF9NUztcbiAgICB0aGlzLm1heFRyYWNrZWRUYWdzID0gb3B0aW9ucy5tYXhUcmFja2VkVGFncyA/PyBERUZBVUxUX01BWF9UUkFDS0VEX1RBR1M7XG4gICAgdGhpcy5yZXN5bmNJbnRlcnZhbE1zID0gb3B0aW9ucy5yZXN5bmNJbnRlcnZhbE1zID8/IERFRkFVTFRfVEFHX1JFU1lOQ19NUztcbiAgICAvLyBMb29rZWQgdXAgb24gZWFjaCBjYWxsIHJhdGhlciB0aGFuIGJvdW5kIGhlcmUsIHNvIGEgdGVzdCdzIGBEYXRlLm5vd2BcbiAgICAvLyBzcHkgYXBwbGllcy5cbiAgICB0aGlzLmNsb2NrID0gb3B0aW9ucy5jbG9jayA/PyAoKCkgPT4gRGF0ZS5ub3coKSk7XG4gICAgdGhpcy5yYW5kb20gPSBvcHRpb25zLnJhbmRvbSA/PyBNYXRoLnJhbmRvbTtcbiAgICB0aGlzLmRlYnVnID0gb3B0aW9ucy5kZWJ1ZyA/PyAoKCkgPT4ge30pO1xuICAgIHRoaXMuY2FuRnJlZXplID0gb3B0aW9ucy5jYW5GcmVlemUgPz8gZmFsc2U7XG4gICAgLy8gTm90aGluZyBpcyB0cmFja2VkIHlldCwgc28gbm90aGluZyBiZWZvcmUgdGhpcyBjYW4gYmUgbWlzc2VkOiBldmVyeSB0YWdcbiAgICAvLyBpcyByZWFkIGZyb20gaXRzIG1hcmtlciB0aGUgZmlyc3QgdGltZSBpdCBpcyBuZWVkZWQuXG4gICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgdGhpcy5jdXJzb3IgPSBhdCAtIFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVM7XG4gICAgdGhpcy5sYXN0TG9nUmVhZCA9IGF0O1xuICAgIHRoaXMuc2V0dGxlZEF0ID0gYXQ7XG4gICAgdGhpcy5mbG9vciA9IG1hcmtlckNsb2NrKCk7XG4gIH1cblxuICAvKiogYHRhZ2AncyBtYXJrZXIgYXMgdGhpcyBpbnN0YW5jZSBrbm93cyBpdCwgaWYgaXQgdHJhY2tzIGB0YWdgLiAqL1xuICBnZXQodGFnOiBzdHJpbmcpOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLnRhZ3MuZ2V0KHRhZyk7XG4gIH1cblxuICAvKipcbiAgICogU2luY2Ugd2hlbiAoYG1hcmtlckNsb2NrKClgKSB0aGlzIGluc3RhbmNlIGtub3dzIG9mIGV2ZXJ5IHJldmFsaWRhdGlvbiBvZlxuICAgKiBldmVyeSB0YWcsIHRyYWNrZWQgb3Igbm90OiB0cmFja2VkIG9uZXMgZnJvbSB0aGVpciBtYXJrZXJzIGFuZCB0aGUgbG9nLFxuICAgKiB0aGUgb3RoZXJzIGZyb20gdGhlIGxvZyBhbG9uZSAoYGxvZ09ubHlgKS4gU28gYW4gZW50cnkgY3JlYXRlZCBhdCBvciBhZnRlclxuICAgKiBpdCBjYW4gYmUganVkZ2VkIGJ5IHtAbGluayBzdGF0ZX0gYW5kIHtAbGluayBleHBpcmF0aW9ufSB3aXRob3V0XG4gICAqIHtAbGluayBlbnN1cmV9IHJlYWRpbmcgYW55dGhpbmcgLSB3aGljaCBtYXR0ZXJzIGluc2lkZSBhIGAndXNlIGNhY2hlJ2BcbiAgICogbG9va3VwLCB3aGVyZSBOZXh0LmpzIHdhaXRzIGZvciB0aGUgYW5zd2VyIGFuZCBhIHJlYWQgcHVzaGVzIHRoZSBlbnRyeSBvdXRcbiAgICogb2YgdGhlIHN0YXRpYyBzdGFnZSBvZiBhIHN0YWdlZCByZW5kZXIuXG4gICAqXG4gICAqIFN0YXJ0cyBhdCBjb25zdHJ1Y3Rpb246IHRoZSBsb2cgaXMgZm9sbG93ZWQgZnJvbSBiZWZvcmUgaXQuIE1vdmVzIHRvIG5vd1xuICAgKiB3aGVuIHRoZSB0cmFja2VkIG1hcmtlcnMgYXJlIGZvcmdvdHRlbiwgYW5kIHBhc3QgdGhlIHJldmFsaWRhdGlvbnMgb2ZcbiAgICogd2hhdGV2ZXIgZWxzZSBpdCBsZXRzIGdvIG9mIC0gYSBtYXJrZXIgZXZpY3RlZCBmb3Igc3BhY2UsIGEgbG9nIHJvd1xuICAgKiBwcnVuZWQgLSB3aGljaCBhcmUgbm8gbG9uZ2VyIGtub3duOiB0byBpdHMgYGV4cGlyZWRBdGAgb25seSBvbmNlIHRoYXQgaXNcbiAgICogcGFzdCwgc2luY2UgYSBwcm9maWxlJ3MgYGV4cGlyZWAgY2FuIGJlIGEgeWVhciBvdXQsIGFuZCBtb3ZpbmcgdGhlcmUgYXRcbiAgICogb25jZSB3b3VsZCB0dXJuIHRoZSByZWFkLWZyZWUgcGF0aCBvZmYgZm9yIHRoZSBpbnN0YW5jZSdzIGxpZmUuXG4gICAqXG4gICAqIEEgcm93IGlzIHBydW5lZCBvbmx5IG9uY2UgaXQgaXMgbm8gbGF0ZXIgdGhhbiBldmVyeSBlbnRyeSBoZWxkLCBzbyB0aGF0XG4gICAqIGNvc3RzIHRob3NlIGVudHJpZXMgbm90aGluZy4gQW4gZW50cnkgc3RvcmVkIGFmdGVyd2FyZHMgd2l0aCBhbiBvbGRlclxuICAgKiBgdGltZXN0YW1wYCAtIE5leHQuanMgc3RhbXBzIHRoZSBzdGFydCBvZiBpdHMgZ2VuZXJhdGlvbiwgd2hpY2ggY2FuXG4gICAqIG91dGxhc3QgYSBsb29rYmFjayAtIGlzIG9sZGVyIHRoYW4gdGhpcyB0b28sIGFuZCBpcyByZWFkIGZpcnN0LlxuICAgKlxuICAgKiBJdCBkb2VzIG5vdCBjb3ZlciBhIHJldmFsaWRhdGlvbiBvbGRlciB0aGFuIHRoZSBsb2cncyBmaXJzdCBsb29rYmFja1xuICAgKiB3aG9zZSBgZXhwaXJlZEF0YCBpcyBzdGlsbCB0byBjb21lLCB3aGljaCB3b3VsZCBleHBpcmUgYW4gZW50cnkgY3JlYXRlZFxuICAgKiBhZnRlciBpdC4gU28gdGhlIGAndXNlIGNhY2hlJ2AgaGFuZGxlciByZWFkcyBhbiBlbnRyeSdzIHRhZ3MgaW4gdGhlXG4gICAqIGJhY2tncm91bmQgYXMgaXQgc3RvcmVzIGl0LlxuICAgKi9cbiAgZ2V0IGNvbXBsZXRlU2luY2UoKTogbnVtYmVyIHtcbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgd2hpbGUgKHRoaXMubGF0ZXJGbG9vcnMubGVuZ3RoID4gMCAmJiB0aGlzLmxhdGVyRmxvb3JzWzBdWzBdIDw9IGF0KSB7XG4gICAgICB0aGlzLmZsb29yID0gTWF0aC5tYXgodGhpcy5mbG9vciwgdGhpcy5sYXRlckZsb29ycy5zaGlmdCgpIVsxXSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmZsb29yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVyIGFuIGluLW1lbW9yeSBzdG9yZSB3aG9zZSBlbnRyaWVzIGFyZSBqdWRnZWQgYnlcbiAgICoge0BsaW5rIGNvbXBsZXRlU2luY2V9LCBieSB0aGUgYHRpbWVzdGFtcGAgb2YgdGhlIG9sZGVzdCBlbnRyeSBpdCBob2xkczpcbiAgICogYGxvZ09ubHlgIGtlZXBzIHRoZSByb3dzIHRoYXQgY291bGQgc3RpbGwgYXBwbHkgdG8gb25lIG9mIHRoZW0sIGFuZCBub1xuICAgKiBvdGhlcnMuIFdpdGggbm9uZSByZWdpc3RlcmVkIGl0IGtlZXBzIG5vdGhpbmcuIEFza2VkIHdpdGggYHNjYW5gIGZhbHNlLFxuICAgKiBgb2xkZXN0VGltZXN0YW1wYCBtYXkgYW5zd2VyIGVhcmx5LCBidXQgbmV2ZXIgbGF0ZSwgd2l0aG91dCBhIHNjYW4uXG4gICAqL1xuICBqdWRnZUVudHJpZXNPZihcbiAgICBvbGRlc3RUaW1lc3RhbXA6IChzY2FuOiBib29sZWFuKSA9PiBudW1iZXIsXG4gICAgaG9sZHNBbnk6ICgpID0+IGJvb2xlYW4gPSAoKSA9PiBvbGRlc3RUaW1lc3RhbXAoZmFsc2UpIDwgSW5maW5pdHksXG4gICk6IHZvaWQge1xuICAgIHRoaXMuZW50cnlTdG9yZXMucHVzaCh7IG9sZGVzdFRpbWVzdGFtcCwgaG9sZHNBbnkgfSk7XG4gIH1cblxuICAvKipcbiAgICogVHJhY2sgYHRhZ2Agd2l0aCBgbWFya2VyYDogd2hhdCB0aGlzIGluc3RhbmNlIGp1c3Qgd3JvdGUsIHdoaWNoIGl0IGtub3dzXG4gICAqIHdpdGhvdXQgcmVhZGluZyBpdCBiYWNrLlxuICAgKi9cbiAgc2V0KHRhZzogc3RyaW5nLCBtYXJrZXI6IFRhZ01hcmtlcik6IHZvaWQge1xuICAgIGNvbnN0IGxvZ2dlZCA9IHRoaXMubG9nT25seS5nZXQodGFnKTtcbiAgICB0aGlzLmxvZ09ubHkuZGVsZXRlKHRhZyk7XG4gICAgdGhpcy5yZW1lbWJlcih0YWcsIG1lcmdlTWFya2VycyhtYXJrZXIsIGxvZ2dlZCkpO1xuICAgIHRoaXMua25vd24odGFnLCB0aGlzLmNsb2NrKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIE5vdGUgYSB1c2Ugb2YgYHRhZ3NgOiB0aG9zZSBvZiBhbiBlbnRyeSB0aGlzIGluc3RhbmNlIGp1c3Qgc3RvcmVkLlxuICAgKlxuICAgKiBXaXRoIHRoZSB0YWJsZSwgYSB0YWcgbm90IHRyYWNrZWQgeWV0IGlzIGxlZnQgdW50cmFja2VkLCB0byBiZSByZWFkIGJ5XG4gICAqIHtAbGluayBlbnN1cmV9IHRoZSBmaXJzdCB0aW1lIGFuIGVudHJ5IG5lZWRzIGl0LiBOb3RoaW5nIHJldmFsaWRhdGVkIGJlZm9yZVxuICAgKiB0aGUgbmV3IGVudHJ5IHdhcyBjcmVhdGVkIGFwcGxpZXMgdG8gKml0KiwgYnV0IHRyYWNraW5nIGlzIHBlciB0YWcsIG5vdCBwZXJcbiAgICogZW50cnk6IHRyYWNraW5nIHRoZSB0YWcgd2l0aCBhbiBlbXB0eSBtYXJrZXIgd291bGQgYWxzbyB2b3VjaCBmb3IgZXZlcnlcbiAgICogb2xkZXIgZW50cnkgdGhhdCBjYXJyaWVzIGl0IC0gb25lIGFub3RoZXIgaW5zdGFuY2Ugc3RvcmVkIGluIFMzLCBvciBvbmVcbiAgICogdGhpcyBpbnN0YW5jZSBrZXB0IGluIG1lbW9yeSBhY3Jvc3MgYSB7QGxpbmsgZm9yZ2V0fSAtIGFuZCBhIHJldmFsaWRhdGlvblxuICAgKiBmcm9tIGJlZm9yZSB0aGUgbG9nJ3MgY3Vyc29yIHdvdWxkIGdvIHVuc2VlbiB1bnRpbCB0aGUgcm9sbGluZyByZS1yZWFkLlxuICAgKlxuICAgKiBXaXRob3V0IHRoZSB0YWJsZSBldmVyeSByZXZhbGlkYXRpb24gaXMgdGhpcyBwcm9jZXNzJ3Mgb3duLCBhcHBsaWVkIHdpdGhcbiAgICoge0BsaW5rIHNldH0sIHNvIGEgdGFnIGlzIHRyYWNrZWQgYXQgb25jZS5cbiAgICovXG4gIHRyYWNrKHRhZ3M6IHJlYWRvbmx5IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLm1hcmtlcnMpIHtcbiAgICAgIHRoaXMudHJhY2tVbnJlYWQodGFncyk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIHRoaXMudG91Y2godGFnKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVHJhY2sgYHRhZ3NgIGFzIHRoZXkgYXJlIGtub3duIG5vdywgd2l0aG91dCByZWFkaW5nIHRoZW0sIHdpdGggYW4gZW1wdHlcbiAgICogbWFya2VyIGZvciBhbnkgbm90IHRyYWNrZWQgeWV0LlxuICAgKi9cbiAgcHJpdmF0ZSB0cmFja1VucmVhZCh0YWdzOiByZWFkb25seSBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIGlmICghdGhpcy50YWdzLmhhcyh0YWcpKSB7XG4gICAgICAgIHRoaXMua25vd24odGFnLCBhdCk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlbWVtYmVyKHRhZywgdGhpcy50YWdzLmdldCh0YWcpID8/IHt9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVhZCB0aGUgbWFya2VycyBvZiB3aGljaGV2ZXIgb2YgYHRhZ3NgIHRoaXMgaW5zdGFuY2UgZG9lcyBub3QgdHJhY2sgeWV0LlxuICAgKiBOZWVkZWQgYmVmb3JlIGp1ZGdpbmcgYW4gZW50cnkgdGhpcyBpbnN0YW5jZSBkaWQgbm90IGNyZWF0ZSwgc2luY2UgaXRzXG4gICAqIHRhZ3MgbWF5IGhhdmUgYmVlbiByZXZhbGlkYXRlZCBhdCBhbnkgdGltZSBiZWZvcmUuXG4gICAqL1xuICBhc3luYyBlbnN1cmUodGFnczogcmVhZG9ubHkgc3RyaW5nW10pOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAoIXRoaXMubWFya2Vycykge1xuICAgICAgdGhpcy50cmFja1VucmVhZCh0YWdzKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgd2FpdHM6IFByb21pc2U8dm9pZD5bXSA9IFtdO1xuICAgIGNvbnN0IHVucmVhZDogc3RyaW5nW10gPSBbXTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiBuZXcgU2V0KHRhZ3MpKSB7XG4gICAgICAvLyBUcmFja2VkIGZpcnN0OiBhIHRyYWNrZWQgdGFnIGluIGByZWFkaW5nYCBpcyBvbmx5IGJlaW5nIHJlLXJlYWQgaW5cbiAgICAgIC8vIHRoZSBiYWNrZ3JvdW5kIChgc3luY2ApLCB3aGljaCBub3RoaW5nIG5lZWRzIHRvIHdhaXQgZm9yLlxuICAgICAgY29uc3QgaW5GbGlnaHQgPSB0aGlzLnJlYWRpbmcuZ2V0KHRhZyk7XG4gICAgICBpZiAodGhpcy50YWdzLmhhcyh0YWcpKSB7XG4gICAgICAgIHRoaXMudG91Y2godGFnKTtcbiAgICAgIH0gZWxzZSBpZiAoaW5GbGlnaHQpIHtcbiAgICAgICAgd2FpdHMucHVzaChpbkZsaWdodCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB1bnJlYWQucHVzaCh0YWcpO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAodW5yZWFkLmxlbmd0aCA+IDApIHtcbiAgICAgIHdhaXRzLnB1c2godGhpcy5zdGFydFJlYWQodW5yZWFkKSk7XG4gICAgfVxuICAgIGF3YWl0IFByb21pc2UuYWxsKHdhaXRzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgcmVhZEludG99IGB0YWdzYCwgYXMgdGhlIHJlYWQgb2YgZWFjaCB0aGF0IHdob2V2ZXIgbmVlZHMgb25lIG9mXG4gICAqIHRoZW0gbmV4dCB3YWl0cyBvbiAoe0BsaW5rIHJlYWRpbmd9KS4gTmV2ZXIgcmVqZWN0czogYSBmYWlsZWQgcmVhZCBsZWF2ZXNcbiAgICogdGhlIHRhZ3MgdHJhY2tlZC5cbiAgICovXG4gIHByaXZhdGUgc3RhcnRSZWFkKHRhZ3M6IHN0cmluZ1tdKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgcmVhZCA9IHRoaXMucmVhZEludG8odGFncykudGhlbigoKSA9PiB7XG4gICAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICAgIHRoaXMucmVhZGluZy5kZWxldGUodGFnKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBmb3IgKGNvbnN0IHRhZyBvZiB0YWdzKSB7XG4gICAgICB0aGlzLnJlYWRpbmcuc2V0KHRhZywgcmVhZCk7XG4gICAgfVxuICAgIHJldHVybiByZWFkO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGxhc3QgcmVmcmVzaCBzZXR0bGVkIG1vcmUgdGhhbiBgcmVmcmVzaEludGVydmFsTXNgIHBsdXNcbiAgICoge0BsaW5rIFRBR19SRUZSRVNIX0dSQUNFX01TfSBhZ28gLSBvbmUgdGhhdCBzcGFubmVkIGEgZnJlZXplIGNvdW50cyBmcm9tXG4gICAqIHdoZW4gaXQgc3RhcnRlZDogYWZ0ZXIgdGhlIGluc3RhbmNlIHNhdCBpZGxlIG9yIGZyb3plbiAtIG9yIGFsd2F5cywgd2l0aFxuICAgKiBhIGByZWZyZXNoSW50ZXJ2YWxNc2Agb2YgYDBgLiBBbnN3ZXJpbmcgZnJvbSB3aGF0IGl0IGtub3dzIHRoZW4gY291bGRcbiAgICogc2VydmUgYW4gZW50cnkgcmV2YWxpZGF0ZWQgZWxzZXdoZXJlIHNpbmNlLCBob3dldmVyIGxvbmcgYWdvIHRoYXQgd2FzLCBzb1xuICAgKiBgcmVmcmVzaFRhZ3NgIHdhaXRzIGZvciB0aGUgcmVmcmVzaCwgYW5kIHRoZSBydW50aW1lIHdhaXRzIGZvciBpdCBiZWZvcmVcbiAgICogYSBwYWdlIHJlbmRlciBzdGFydHMgKHtAbGluayBjYXRjaFVwfSkuXG4gICAqXG4gICAqIEZyb20gd2hlbiBpdCBzZXR0bGVkLCBub3Qgd2hlbiBpdCBzdGFydGVkLCBzbyBhIHNsb3cgcXVlcnkgdGhlIHJ1bnRpbWVcbiAgICogd2FpdGVkIGZvciBiZWZvcmUgdGhlIHJlbmRlciBkb2VzIG5vdCBsZWF2ZSB0aGUgaW5zdGFuY2UgYmVoaW5kIGluc2lkZVxuICAgKiBpdC4gQSBmYWlsZWQgb25lIGNvdW50cyB0b28sIHNvIG9uZSByZXF1ZXN0IGRvZXMgbm90IHdhaXQgZm9yIHR3bzogdGhlXG4gICAqIHNhbWUgXCJhc3N1bWUgdGhlIGVudHJ5IGlzIHZhbGlkXCIgYSBmYWlsZWQgcmVhZCBhbnN3ZXJzIHdpdGgsIHVudGlsIHRoZVxuICAgKiBuZXh0IHJlZnJlc2gsIGF0IG1vc3QgdGhlIGludGVydmFsIGFuZCB0aGUgZ3JhY2UgbGF0ZXIuXG4gICAqL1xuICBnZXQgYmVoaW5kKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmxvZyAhPT0gdW5kZWZpbmVkICYmXG4gICAgICAvLyBgMGAgYXNrcyBiZWZvcmUgZXZlcnkgY2hlY2ssIHNvIGV2ZXJ5IGNoZWNrIHdhaXRzIGZvciB0aGUgYW5zd2VyLlxuICAgICAgKHRoaXMucmVmcmVzaEludGVydmFsTXMgPT09IDAgfHwgdGhpcy5vdmVyZHVlKHRoaXMuc2V0dGxlZEF0KSlcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIHtAbGluayBiZWhpbmR9LCBhcyBgcmVmcmVzaFRhZ3NgIGFza3MgaXQ6IG5ldmVyIGluc2lkZSBhIHBhZ2UncyByZW5kZXJcbiAgICoge0BsaW5rIGNhdGNoVXB9IGNhdWdodCB1cCwgc2luY2UgdGhlIHJ1bnRpbWUgc2V0dGxlZCBpdCBmb3IgdGhhdCByZXF1ZXN0XG4gICAqIGJlZm9yZSB0aGUgcmVuZGVyIHN0YXJ0ZWQsIGFuZCBhIHdhaXQgaW5zaWRlIGEgYCd1c2UgY2FjaGUnYCBsb29rdXAgaXNcbiAgICogd2hhdCBpdCBzZXR0bGVkIGl0IHRvIGF2b2lkIC0gYSByZW5kZXIgY3Jvc3NpbmcgdGhlIGxpbmUgcGFydHdheSB0aHJvdWdoXG4gICAqIHdvdWxkIG90aGVyd2lzZSB3YWl0IGFmdGVyIGFsbC4gU28gYSByZXZhbGlkYXRpb24gZWxzZXdoZXJlIGNhbiBnbyB1bnNlZW5cbiAgICogZm9yIGEgcmVuZGVyJ3MgZHVyYXRpb24gb24gdG9wIG9mIHRoZSB1c3VhbCB3aW5kb3cuXG4gICAqXG4gICAqIEEgcm91dGUgaGFuZGxlciwgd2hpY2ggbm8gY2F0Y2gtdXAgcHJlY2VkZXMsIHdhaXRzIGF0IHRoZSBwbGFpbiBsaW5lLlxuICAgKi9cbiAgZ2V0IGJlaGluZEluUmVuZGVyKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLnJlZnJlc2hJbnRlcnZhbE1zICE9PSAwICYmIHRoaXMuY2F1Z2h0VXBSZW5kZXIuZ2V0U3RvcmUoKVxuICAgICAgPyBmYWxzZVxuICAgICAgOiB0aGlzLmJlaGluZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIGEgcmVnaXN0ZXJlZCBzdG9yZSAoe0BsaW5rIGp1ZGdlRW50cmllc09mfSkgaG9sZHMgYW55IGVudHJ5OiBvbmVcbiAgICogYSByZWZyZXNoIGNvdWxkIGV4cGlyZS4gV2l0aCBub25lIHRoZXJlIGlzIG5vdGhpbmcgdG8gd2FpdCBmb3IgZXZlbiB3aGVuXG4gICAqIHRoZSBpbnN0YW5jZSBpcyB7QGxpbmsgYmVoaW5kfSwgc2luY2Ugd2hhdGV2ZXIgaXMgc3RvcmVkIGZyb20gaGVyZSBvbiBpc1xuICAgKiBuZXdlciB0aGFuIHdoYXQgdGhlIGxvZyB3b3VsZCBzYXkgLSB3aGljaCBjb3ZlcnMgdGhlIGZpcnN0IGAndXNlIGNhY2hlJ2BcbiAgICogY2FsbCBvZiBhIHByb2Nlc3MsIHdoaWNoIGNyZWF0ZXMgdGhlIGhhbmRsZXIgaW5zaWRlIHRoZSByZW5kZXIuXG4gICAqL1xuICBnZXQgaG9sZHNFbnRyaWVzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLmVudHJ5U3RvcmVzLnNvbWUoKHN0b3JlKSA9PiBzdG9yZS5ob2xkc0FueSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiB7QGxpbmsgcmVmcmVzaH0sIHdhaXRlZCBmb3Igd2hlbiB0aGUgaW5zdGFuY2UgaXMge0BsaW5rIGJlaGluZH0uIFRoZVxuICAgKiBydW50aW1lIGNhbGxzIGl0IGJlZm9yZSBoYW5kaW5nIGEgcGFnZSByZXF1ZXN0IHRvIE5leHQuanMsIG91dHNpZGUgdGhlXG4gICAqIHN0YWdlZCByZW5kZXIgd2hvc2Ugc3RhdGljIHN0YWdlIGEgd2FpdCBpbnNpZGUgYSBgJ3VzZSBjYWNoZSdgIGxvb2t1cFxuICAgKiB3b3VsZCBjdXQgc2hvcnQuIE9ubHkgZm9yIHRoZSBgJ3VzZSBjYWNoZSdgIGhhbmRsZXIncyBlbnRyaWVzXG4gICAqICh7QGxpbmsganVkZ2VFbnRyaWVzT2Z9KTogdGhlIG90aGVyIGNhY2hlcyB3YWl0IGZvciB0aGUgcmVmcmVzaCB3aGVyZSB0aGV5XG4gICAqIHJlYWQgYW55d2F5LiBOb3Qgd2l0aCBhIGByZWZyZXNoSW50ZXJ2YWxNc2Agb2YgYDBgIGVpdGhlciwgd2hlcmVcbiAgICogYHJlZnJlc2hUYWdzYCBhc2tzIGFnYWluIHJlZ2FyZGxlc3MuIFRoZW4gYHJlbmRlcmAsIG1hcmtlZCBhcyBjYXVnaHQgdXBcbiAgICogZm9yICh7QGxpbmsgYmVoaW5kSW5SZW5kZXJ9KS4gUmVqZWN0cyBvbmx5IGFzIGByZW5kZXJgIGRvZXMuXG4gICAqL1xuICBhc3luYyBjYXRjaFVwPFQ+KHJlbmRlcjogKCkgPT4gUHJvbWlzZTxUPik6IFByb21pc2U8VD4ge1xuICAgIGNvbnN0IGxvZyA9IChlcnJvcjogdW5rbm93bikgPT5cbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciByZWZyZXNoaW5nIGNhY2hlIHRhZ3M6XCIsIGVycm9yKTtcbiAgICBpZiAodGhpcy5yZWZyZXNoSW50ZXJ2YWxNcyA+IDAgJiYgdGhpcy5iZWhpbmQpIHtcbiAgICAgIGlmICghdGhpcy5ob2xkc0VudHJpZXMpIHtcbiAgICAgICAgLy8gTm90IGNhdWdodCB1cCwgc28gbm8gZ3JhY2U6IGFuIGVudHJ5IHN0b3JlZCBtZWFud2hpbGUsIGJ5IGFub3RoZXJcbiAgICAgICAgLy8gcmVxdWVzdCwgbWFrZXMgdGhlIHJlbmRlcidzIGxvb2t1cHMgd2FpdCBhdCB0aGUgcGxhaW4gbGluZS5cbiAgICAgICAgcmV0dXJuIHJlbmRlcigpO1xuICAgICAgfVxuICAgICAgYXdhaXQgdGhpcy5yZWZyZXNoKCkuY2F0Y2gobG9nKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMucmVmcmVzaEludGVydmFsTXMgPiAwKSB7XG4gICAgICAvLyBTdGFydGVkLCBub3Qgd2FpdGVkIGZvciwgYXMgYHJlZnJlc2hUYWdzYCB3b3VsZDogYSBwYWdlIHRoYXQgcmVhZHNcbiAgICAgIC8vIG5vIGNhY2hlIGtlZXBzIHRoZSBpbnN0YW5jZSBjdXJyZW50IHRvbywgcmF0aGVyIHRoYW4gZmFsbGluZyBiZWhpbmRcbiAgICAgIC8vIGFuZCBtYWtpbmcgYSBsYXRlciByZXF1ZXN0IHdhaXQuXG4gICAgICB2b2lkIHRoaXMucmVmcmVzaCgpLmNhdGNoKGxvZyk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLmNhdWdodFVwUmVuZGVyLnJ1bih0cnVlLCByZW5kZXIpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJ1biBgZm5gIG91dHNpZGUgdGhlIHJlcXVlc3QncyBjb250ZXh0IChgb3V0c2lkZVJlcXVlc3RgKSwga2VlcGluZyBvbmx5XG4gICAqIHdoZXRoZXIgdGhlIHJlbmRlciB3YXMge0BsaW5rIGNhdGNoVXAgY2F1Z2h0IHVwfTogYSBjYWNoZSBoYW5kbGVyIG1ldGhvZFxuICAgKiBjYWxsZWQgZnJvbSBpbnNpZGUgYSBzdGFnZWQgcmVuZGVyLCB3aG9zZSBjbG9jayByZWFkcyBhbmQgQVdTIFNESyBjYWxsc1xuICAgKiB3b3VsZCBvdGhlcndpc2UgZW5kIGl0cyBzdGF0aWMgc3RhZ2UuXG4gICAqL1xuICBvdXRzaWRlUmVuZGVyPFQ+KGZuOiAoKSA9PiBUKTogVCB7XG4gICAgY29uc3QgY2F1Z2h0VXAgPSB0aGlzLmNhdWdodFVwUmVuZGVyLmdldFN0b3JlKCk7XG4gICAgcmV0dXJuIG91dHNpZGVSZXF1ZXN0KCgpID0+XG4gICAgICBjYXVnaHRVcCA/IHRoaXMuY2F1Z2h0VXBSZW5kZXIucnVuKGNhdWdodFVwLCBmbikgOiBmbigpLFxuICAgICk7XG4gIH1cblxuICAvKiogV2hldGhlciBgYXRgIGlzIG1vcmUgdGhhbiB0aGUgaW50ZXJ2YWwgYW5kIHRoZSBncmFjZSBhZ28uICovXG4gIHByaXZhdGUgb3ZlcmR1ZShhdDogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuY2xvY2soKSAtIGF0ID4gdGhpcy5yZWZyZXNoSW50ZXJ2YWxNcyArIFRBR19SRUZSRVNIX0dSQUNFX01TO1xuICB9XG5cbiAgLyoqXG4gICAqIENhdGNoIHVwIG9uIHJldmFsaWRhdGlvbnMgb3RoZXIgaW5zdGFuY2VzIHJhbiwgYXQgbW9zdCBvbmNlIHBlclxuICAgKiBgcmVmcmVzaEludGVydmFsTXNgLiBTZWUge0BsaW5rIFRyYWNrZWRUYWdNYXJrZXJzfSBmb3IgdGhlIGNvc3QuXG4gICAqL1xuICBhc3luYyByZWZyZXNoKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IGxvZyA9IHRoaXMubG9nO1xuICAgIGlmICghbG9nKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLnJlZnJlc2hpbmcpIHtcbiAgICAgIC8vIE9uZSBzdGFydGVkIGJlZm9yZSBhIGZyZWV6ZSByZWFkIHRoZSBsb2cgYXMgaXQgd2FzIHRoZW4sIGFuZCBzYXlzXG4gICAgICAvLyBub3RoaW5nIG9mIHdoYXQgcmFuIG1lYW53aGlsZTogYW4gaW5zdGFuY2UgYmVoaW5kIHdhaXRzIGZvciBhIGZyZXNoXG4gICAgICAvLyBvbmUsIGFmdGVyIGl0LiBPbmUgdGhhdCBpcyBtZXJlbHkgc2xvdyBpcyBhcyBmcmVzaCBhcyBhbnkuXG4gICAgICBpZiAodGhpcy5iZWhpbmQgJiYgdGhpcy5wYXVzZWRTaW5jZVJlZnJlc2hTdGFydGVkKCkpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVmcmVzaGluZy50aGVuKCgpID0+IHRoaXMucmVmcmVzaCgpKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLnJlZnJlc2hpbmc7XG4gICAgfVxuICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgIGlmIChhdCAtIHRoaXMubGFzdFJlZnJlc2ggPCB0aGlzLnJlZnJlc2hJbnRlcnZhbE1zKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubGFzdFJlZnJlc2ggPSBhdDtcbiAgICAvLyBXaGF0ZXZlciBnZXRzIHRyYWNrZWQgYmVmb3JlIHRoZSBuZXh0IHJlZnJlc2ggaXMgcmVhZCBmcm9tIGl0cyBtYXJrZXIsXG4gICAgLy8gc28gdGhlcmUgaXMgbm90aGluZyB0byBjYXRjaCB1cCBvbiB5ZXQgLSB1bmxlc3MgYW4gZW50cnkgaXMganVkZ2VkIGJ5XG4gICAgLy8gYGNvbXBsZXRlU2luY2VgLCB3aGljaCByZWxpZXMgb24gdGhlIGxvZyBmb3IgZXZlcnkgdGFnLiBFdmVuIHdpdGggbm9uZVxuICAgIC8vIGhlbGQ6IGEgcm93IGxldCBnbyBvZiB0aGVuIG1vdmVzIGBjb21wbGV0ZVNpbmNlYCBwYXN0IGl0LCBmb3IgYW4gZW50cnlcbiAgICAvLyB3aG9zZSBnZW5lcmF0aW9uIHN0YXJ0ZWQgYmVmb3JlIHRoYXQgcmV2YWxpZGF0aW9uIGFuZCB0aGF0IGlzIHN0b3JlZFxuICAgIC8vIGFmdGVyIGl0LlxuICAgIGlmICh0aGlzLnRhZ3Muc2l6ZSA9PT0gMCAmJiB0aGlzLmVudHJ5U3RvcmVzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLnN0YXJ0VGlja2luZygpO1xuICAgIHRoaXMucmVmcmVzaGluZyA9IHRoaXMuc3luYyhhdCwgbG9nKS5maW5hbGx5KCgpID0+IHtcbiAgICAgIC8vIE9uZSB0aGF0IHNwYW5uZWQgYSBwYXVzZSBrbm93cyB0aGUgbG9nIGFzIG9mIGl0cyBzdGFydCBhdCBiZXN0LiBTb1xuICAgICAgLy8gZG9lcyBvbmUgdGhhdCBvbmx5IGxvb2tlZCBwYXVzZWQsIGl0cyBldmVudCBsb29wIGhlbGQgdXA6IGl0IGNvdW50c1xuICAgICAgLy8gYXMgbm8gb2xkZXIgdGhhbiBpdHMgc3RhcnQsIGFzIGlmIGl0IGhhZCBub3Qgc2V0dGxlZCBzaW5jZS5cbiAgICAgIHRoaXMuc2V0dGxlZEF0ID0gTWF0aC5tYXgoXG4gICAgICAgIHRoaXMuc2V0dGxlZEF0LFxuICAgICAgICB0aGlzLnBhdXNlZFNpbmNlUmVmcmVzaFN0YXJ0ZWQoKSA/IHRoaXMubGFzdFJlZnJlc2ggOiB0aGlzLmNsb2NrKCksXG4gICAgICApO1xuICAgICAgdGhpcy5zdG9wVGlja2luZygpO1xuICAgICAgdGhpcy5yZWZyZXNoaW5nID0gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIHJldHVybiB0aGlzLnJlZnJlc2hpbmc7XG4gIH1cblxuICBwcml2YXRlIHN0YXJ0VGlja2luZygpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuY2FuRnJlZXplKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubGFzdFRpY2sgPSB0aGlzLmNsb2NrKCk7XG4gICAgdGhpcy5wYXVzZWRXaGlsZVJlZnJlc2hpbmcgPSBmYWxzZTtcbiAgICB0aGlzLnRpY2tlciA9IHNldEludGVydmFsKCgpID0+IHtcbiAgICAgIGNvbnN0IGF0ID0gdGhpcy5jbG9jaygpO1xuICAgICAgaWYgKGF0IC0gdGhpcy5sYXN0VGljayA+IFJFRlJFU0hfUEFVU0VfTVMpIHtcbiAgICAgICAgdGhpcy5wYXVzZWRXaGlsZVJlZnJlc2hpbmcgPSB0cnVlO1xuICAgICAgfVxuICAgICAgdGhpcy5sYXN0VGljayA9IGF0O1xuICAgIH0sIFJFRlJFU0hfVElDS19NUyk7XG4gICAgLy8gTmV2ZXIgd2hhdCBrZWVwcyBhIHByb2Nlc3MgYWxpdmUuXG4gICAgdGhpcy50aWNrZXIudW5yZWY/LigpO1xuICB9XG5cbiAgcHJpdmF0ZSBzdG9wVGlja2luZygpOiB2b2lkIHtcbiAgICBjbGVhckludGVydmFsKHRoaXMudGlja2VyKTtcbiAgICB0aGlzLnRpY2tlciA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGV0aGVyIHRoZSBwcm9jZXNzIHdhcyBwYXVzZWQgc2luY2Uge0BsaW5rIHJlZnJlc2hpbmd9IHN0YXJ0ZWQ6IGEgdGlja1xuICAgKiBjYW1lIGxhdGUsIG9yIHRoZSBuZXh0IG9uZSBpcyBvdmVyZHVlIChhZnRlciBhIHRoYXcsIGEgcmVxdWVzdCBjYW4gcnVuXG4gICAqIGJlZm9yZSB0aGUgdGltZXIgZG9lcykuXG4gICAqL1xuICBwcml2YXRlIHBhdXNlZFNpbmNlUmVmcmVzaFN0YXJ0ZWQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIHRoaXMuY2FuRnJlZXplICYmXG4gICAgICAodGhpcy5wYXVzZWRXaGlsZVJlZnJlc2hpbmcgfHxcbiAgICAgICAgdGhpcy5jbG9jaygpIC0gdGhpcy5sYXN0VGljayA+IFJFRlJFU0hfUEFVU0VfTVMpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmQgYSByZXZhbGlkYXRpb24gb2YgYHRhZ3NgOiBoZXJlIGF0IG9uY2UsIGFuZCBpbiB0aGUgcmV2YWxpZGF0aW9uXG4gICAqIHRhYmxlIGZvciBldmVyeSBvdGhlciBpbnN0YW5jZSAtIHRoZSBtYXJrZXIgcm93IHBsdXMgYSBsb2cgcm93IHBlciB0YWcuXG4gICAqXG4gICAqIE5leHQuanMgY2FsbHMgYHJldmFsaWRhdGVUYWdgIG9uIHRoZSBpbmNyZW1lbnRhbCBjYWNoZSBhbmQgYHVwZGF0ZVRhZ3NgIG9uXG4gICAqIGV2ZXJ5IGRpc3RpbmN0IGBjYWNoZUhhbmRsZXJzYCBlbnRyeSwgYWxsIGluIG9uZSBzeW5jaHJvbm91cyBsb29wXG4gICAqIChgcmV2YWxpZGF0aW9uLXV0aWxzYCksIGFuZCBhbGwgb2YgdGhlbSBzaGFyZSB0aGlzIG1hbmlmZXN0LiBTbyBhblxuICAgKiBpZGVudGljYWwgY2FsbCBpbiB0aGUgc2FtZSB0dXJuIGpvaW5zIHRoZSBmaXJzdCBpbnN0ZWFkIG9mIHdyaXRpbmcgdGhlXG4gICAqIHJvd3MgYWdhaW4uIE9uZSBpbiBhIGxhdGVyIHR1cm4gaXMgYSByZXZhbGlkYXRpb24gb2YgaXRzIG93biwgZXZlbiB3aGlsZVxuICAgKiB0aGUgZmlyc3Qgb25lJ3Mgd3JpdGVzIGFyZSBpbiBmbGlnaHQsIGFuZCBnZXRzIGl0cyBvd24sIGxhdGVyLCBtYXJrZXIuXG4gICAqIE5ldmVyIHJlamVjdHM6IHJlc29sdmVzIGBmYWxzZWAgd2hlbiBhIHJvdyBmYWlsZWQgdG8gd3JpdGUgKHRoZSBlcnJvciBpc1xuICAgKiBsb2dnZWQpLCBzbyBvdGhlciBpbnN0YW5jZXMgbWF5IG5vdCBzZWUgaXQuXG4gICAqL1xuICBhc3luYyB1cGRhdGUoXG4gICAgdGFnczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgZHVyYXRpb25zOiBSZXZhbGlkYXRlRHVyYXRpb25zIHwgdW5kZWZpbmVkLFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBrZXkgPSBKU09OLnN0cmluZ2lmeShbdGFncywgZHVyYXRpb25zID8/IG51bGxdKTtcbiAgICBjb25zdCBpbkZsaWdodCA9IHRoaXMudXBkYXRpbmcuZ2V0KGtleSk7XG4gICAgaWYgKGluRmxpZ2h0KSB7XG4gICAgICByZXR1cm4gaW5GbGlnaHQ7XG4gICAgfVxuICAgIGNvbnN0IHVwZGF0ZSA9IHRoaXMud3JpdGUodGFncywgZHVyYXRpb25zKTtcbiAgICB0aGlzLnVwZGF0aW5nLnNldChrZXksIHVwZGF0ZSk7XG4gICAgLy8gRm9yZ290dGVuIGFzIHNvb24gYXMgdGhlIGN1cnJlbnQgdHVybidzIGNhbGxzIGhhdmUgYmVlbiBtYWRlLlxuICAgIHZvaWQgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB0aGlzLnVwZGF0aW5nLmRlbGV0ZShrZXkpKTtcbiAgICByZXR1cm4gdXBkYXRlO1xuICB9XG5cbiAgLyoqXG4gICAqIFdoYXQgdGhlIHRyYWNrZWQgbWFya2VycyBzYXkgYWJvdXQgYW4gZW50cnkgY2FycnlpbmcgYHRhZ3NgLCBjcmVhdGVkIGF0XG4gICAqIGBjcmVhdGVkQXRgOiB0aGUgbW9zdCBzZXZlcmUgYW5zd2VyIG9mIGFueSBvZiB0aGVtLlxuICAgKi9cbiAgc3RhdGUodGFnczogcmVhZG9ubHkgc3RyaW5nW10sIGNyZWF0ZWRBdDogbnVtYmVyKTogUmV2YWxpZGF0aW9uU3RhdGUge1xuICAgIC8vIGBtYXJrZXJDbG9jaygpYCwgbm90IGBEYXRlLm5vdygpYCwgaGVyZSBhbmQgd2hlcmV2ZXIgYSBtYXJrZXIgaXMgc3RhbXBlZDpcbiAgICAvLyBgY3JlYXRlZEF0YCBpcyBvbiBOZXh0LmpzJ3MgY2xvY2ssIGFuZCBhIG1hcmtlciBvbiB0aGUgd2FsbCBjbG9jayB3b3VsZCBiZVxuICAgIC8vIGNvbXBhcmVkIGFjcm9zcyB0aGUgdHdvLCBzbyBhbiBlbnRyeSByZWdlbmVyYXRlZCBqdXN0IGFmdGVyIGFcbiAgICAvLyByZXZhbGlkYXRpb24gY291bGQgc3RpbGwgcmVhZCBhcyBvbGRlciB0aGFuIGl0IHdoZXJldmVyIHRoZXkgZHJpZnQuXG4gICAgY29uc3QgYXQgPSBtYXJrZXJDbG9jaygpO1xuICAgIGxldCBzdGF0ZTogUmV2YWxpZGF0aW9uU3RhdGUgPSBcImZyZXNoXCI7XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgY29uc3QgbWFya2VyID0gdGhpcy5rbm93bk1hcmtlcih0YWcpO1xuICAgICAgaWYgKCFtYXJrZXIpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBjb25zdCB0YWdTdGF0ZSA9IG1hcmtlclN0YXRlKG1hcmtlciwgY3JlYXRlZEF0LCBhdCk7XG4gICAgICBpZiAodGFnU3RhdGUgPT09IFwiZXhwaXJlZFwiKSB7XG4gICAgICAgIHJldHVybiBcImV4cGlyZWRcIjtcbiAgICAgIH1cbiAgICAgIGlmICh0YWdTdGF0ZSA9PT0gXCJzdGFsZVwiKSB7XG4gICAgICAgIHN0YXRlID0gXCJzdGFsZVwiO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gc3RhdGU7XG4gIH1cblxuICAvKipcbiAgICogYGdldEV4cGlyYXRpb25gJ3MgYW5zd2VyOiB0aGUgbGF0ZXN0IHRpbWUgYW55IG9mIGB0YWdzYCBleHBpcmVkLCBgMGAgaWZcbiAgICogbm9uZSBoYXMuIE9ubHkgZXhwaXJhdGlvbnMgYWxyZWFkeSBwYXN0IGNvdW50IC0gYSBwcm9maWxlJ3MgZnV0dXJlXG4gICAqIGBleHBpcmVgIGlzIG5vdCBhbiBleHBpcmF0aW9uIHlldCAtIGFuZCBhIHN0YWxlIG1hcmsgZG9lcyBub3QsIG1hdGNoaW5nXG4gICAqIE5leHQuanMncyBkZWZhdWx0IGhhbmRsZXIsIHdoaWNoIHJlYWRzIG9ubHkgYGV4cGlyZWRgIGZvciBpbXBsaWNpdCB0YWdzLlxuICAgKi9cbiAgZXhwaXJhdGlvbih0YWdzOiByZWFkb25seSBzdHJpbmdbXSk6IG51bWJlciB7XG4gICAgY29uc3QgYXQgPSBtYXJrZXJDbG9jaygpO1xuICAgIGxldCBsYXRlc3QgPSAwO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIGNvbnN0IG1hcmtlciA9IHRoaXMua25vd25NYXJrZXIodGFnKTtcbiAgICAgIGlmICghbWFya2VyKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgaWYgKG1hcmtlci5yZXZhbGlkYXRlZEF0ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgbGF0ZXN0ID0gTWF0aC5tYXgobGF0ZXN0LCBtYXJrZXIucmV2YWxpZGF0ZWRBdCk7XG4gICAgICB9XG4gICAgICBpZiAobWFya2VyLmV4cGlyZWRBdCAhPT0gdW5kZWZpbmVkICYmIG1hcmtlci5leHBpcmVkQXQgPD0gYXQpIHtcbiAgICAgICAgbGF0ZXN0ID0gTWF0aC5tYXgobGF0ZXN0LCBtYXJrZXIuZXhwaXJlZEF0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxhdGVzdDtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgd3JpdGUoXG4gICAgdGFnczogcmVhZG9ubHkgc3RyaW5nW10sXG4gICAgZHVyYXRpb25zOiBSZXZhbGlkYXRlRHVyYXRpb25zIHwgdW5kZWZpbmVkLFxuICApOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgY29uc3QgbWFya2VyID0gbWFya2VyRm9yKGF0LCBkdXJhdGlvbnMpO1xuICAgIGZvciAoY29uc3QgdGFnIG9mIHRhZ3MpIHtcbiAgICAgIHRoaXMuc2V0KHRhZywgYXBwbHlNYXJrZXIodGhpcy5nZXQodGFnKSwgbWFya2VyKSk7XG4gICAgfVxuICAgIGNvbnN0IHsgbWFya2VycywgbG9nIH0gPSB0aGlzO1xuICAgIGlmICghbWFya2VycyB8fCAhbG9nKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3Qgd3JpdGVzOiBbc3RyaW5nLCBQcm9taXNlPHVua25vd24+XVtdID0gW107XG4gICAgZm9yIChjb25zdCB0YWcgb2YgbmV3IFNldCh0YWdzKSkge1xuICAgICAgd3JpdGVzLnB1c2goW1xuICAgICAgICBcIkVycm9yIHdyaXRpbmcgdGFnIHJldmFsaWRhdGlvbiBtYXJrZXI6XCIsXG4gICAgICAgIC8vIFRoZSByb3cgYXMgaXQgaXMgbm93LCB3aGljaCBjYXJyaWVzIGFueSBlYXJsaWVyIGByZXZhbGlkYXRlZEF0YFxuICAgICAgICAvLyBhbm90aGVyIGluc3RhbmNlIHdyb3RlOiB0cmFja2luZyBvbmx5IHdoYXQgdGhpcyBjYWxsIHNldCB3b3VsZFxuICAgICAgICAvLyBoaWRlIHRoYXQgb25lIHVudGlsIHRoZSByb2xsaW5nIHJlLXJlYWQsIGFuZCBhbiBlbnRyeSBvbGRlciB0aGFuIGl0XG4gICAgICAgIC8vIHdvdWxkIHJlYWQgYXMgbWVyZWx5IHN0YWxlLlxuICAgICAgICBtYXJrZXJzLndyaXRlKHRhZywgYXQsIGR1cmF0aW9ucykudGhlbigocm93KSA9PiB7XG4gICAgICAgICAgaWYgKHJvdykge1xuICAgICAgICAgICAgdGhpcy5zZXQodGFnLCBtZXJnZU1hcmtlcnModGhpcy5nZXQodGFnKSwgcm93KSk7XG4gICAgICAgICAgfVxuICAgICAgICB9KSxcbiAgICAgIF0pO1xuICAgICAgd3JpdGVzLnB1c2goW1xuICAgICAgICBcIkVycm9yIHdyaXRpbmcgdGFnIHJldmFsaWRhdGlvbiBsb2cgcm93OlwiLFxuICAgICAgICB0aGlzLnB1dExvZ1Jvdyhsb2csIHRhZywgbWFya2VyKSxcbiAgICAgIF0pO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKHdyaXRlcy5tYXAoKFssIHdyaXRlXSkgPT4gd3JpdGUpKTtcbiAgICByZXN1bHRzLmZvckVhY2goKHJlc3VsdCwgaSkgPT4ge1xuICAgICAgaWYgKHJlc3VsdC5zdGF0dXMgPT09IFwicmVqZWN0ZWRcIikge1xuICAgICAgICBjb25zb2xlLmVycm9yKHdyaXRlc1tpXVswXSwgcmVzdWx0LnJlYXNvbik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdHMuZXZlcnkoKHJlc3VsdCkgPT4gcmVzdWx0LnN0YXR1cyA9PT0gXCJmdWxmaWxsZWRcIik7XG4gIH1cblxuICAvKipcbiAgICogUHV0IGB0YWdgJ3MgbG9nIHJvdywgc3RhbXBlZCBvbiB0aGUgd2FsbCBjbG9jayAodGhlIG1hcmtlciB2YWx1ZXMgYXJlIG9uXG4gICAqIE5leHQuanMnczogc2VlIHtAbGluayBSZXZhbGlkYXRpb25Mb2d9KS5cbiAgICpcbiAgICogUmVhZGVycyBvbmx5IGxvb2sge0BsaW5rIFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVN9IGJlaGluZCB0aGVpciBsYXN0XG4gICAqIHF1ZXJ5LCBzbyBhIHJvdyB0aGF0IHNob3dzIHVwIG11Y2ggbGF0ZXIgdGhhbiBpdHMgdGltZXN0YW1wIC0gYSBzbG93XG4gICAqIGNvbm5lY3Rpb24sIHJldHJpZXMgdW5kZXIgdGhyb3R0bGluZyAtIGlzIGJlaGluZCBldmVyeSBjdXJzb3IgYW5kIG5ldmVyXG4gICAqIHJlYWQuIEEgc2xvdyBwdXQgaXMgdGhlcmVmb3JlIG1hZGUgYWdhaW4gdW5kZXIgYSBmcmVzaCB0aW1lc3RhbXAsIHdoaWNoXG4gICAqIHJlYWRlcnMgd2lsbCBzZWU7IG9uZSBzbG93IHR3aWNlIGlzIHJlcG9ydGVkIGFzIGEgZmFpbHVyZS5cbiAgICovXG4gIHByaXZhdGUgYXN5bmMgcHV0TG9nUm93KFxuICAgIGxvZzogUmV2YWxpZGF0aW9uTG9nLFxuICAgIHRhZzogc3RyaW5nLFxuICAgIG1hcmtlcjogVGFnTWFya2VyLFxuICApOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBmb3IgKGxldCBhdHRlbXB0ID0gMDsgYXR0ZW1wdCA8IDI7IGF0dGVtcHQrKykge1xuICAgICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgICBhd2FpdCBsb2cucHV0KHRhZywgYXQsIG1hcmtlcik7XG4gICAgICBpZiAodGhpcy5jbG9jaygpIC0gYXQgPD0gTUFYX0xPR19QVVRfTVMpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICBgVGhlIHJldmFsaWRhdGlvbiBsb2cgcm93IGZvciAke3RhZ30gdG9vayBsb25nZXIgdGhhbiByZWFkZXJzIGxvb2sgYmFja2AsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBPbmUgcmVmcmVzaCBzdGFydGVkIGF0IGBhdGA6IHRoZSBsb2cgcm93cyBzaW5jZSB0aGUgY3Vyc29yLCBhbmQgdGhlIG5leHRcbiAgICogc2xpY2Ugb2YgdGhlIHJvbGxpbmcgcmUtcmVhZC5cbiAgICpcbiAgICogQSBmYWlsZWQgcXVlcnkgY2hhbmdlcyBub3RoaW5nIGJ1dCB0aGUgbG9nOiB0aGUgdGFncyBzdGF5IHRyYWNrZWQgYXMgdGhleVxuICAgKiB3ZXJlLCBhbmQgdGhlIG5leHQgcmVmcmVzaCBhc2tzIGFnYWluIGZyb20gdGhlIHNhbWUgY3Vyc29yLlxuICAgKi9cbiAgcHJpdmF0ZSBhc3luYyBzeW5jKGF0OiBudW1iZXIsIGxvZzogUmV2YWxpZGF0aW9uTG9nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKGF0IC0gdGhpcy5sYXN0TG9nUmVhZCA+IE1BWF9SRVZBTElEQVRJT05fTE9HX0dBUF9NUykge1xuICAgICAgdGhpcy5mb3JnZXQoXG4gICAgICAgIGF0LFxuICAgICAgICBcInRoZSByZXZhbGlkYXRpb24gbG9nIG1heSBub3QgY292ZXIgdGhlIGdhcCBzaW5jZSBpdCB3YXMgbGFzdCByZWFkXCIsXG4gICAgICApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICAvLyBUaGUgcm9sbGluZyByZS1yZWFkIHJ1bnMgYWxvbmdzaWRlLCBub3Qgd2FpdGVkIGZvcjogY2F0Y2hpbmcgdXAgbmVlZHNcbiAgICAvLyBvbmx5IHRoZSBsb2csIGFuZCBhIHRocm90dGxlZCBgQmF0Y2hHZXRJdGVtYCBzaG91bGQgbm90IGhvbGQgdGhlXG4gICAgLy8gcmVxdWVzdCBgY2F0Y2hVcGAgbWFrZXMgd2FpdC4gQSBmb3JnZXQgbWVhbndoaWxlIHJlYWRzIGl0IGFnYWluLlxuICAgIGNvbnN0IGR1ZSA9IHRoaXMuZHVlKGF0KTtcbiAgICBpZiAoZHVlLmxlbmd0aCA+IDApIHtcbiAgICAgIHZvaWQgdGhpcy5zdGFydFJlYWQoZHVlKTtcbiAgICB9XG4gICAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbG9nLnF1ZXJ5KHRoaXMuY3Vyc29yKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciByZWFkaW5nIHRhZyByZXZhbGlkYXRpb24gbG9nOlwiLCBlcnJvcik7XG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIH0pO1xuICAgIGlmICghcmVzdWx0KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmIChyZXN1bHQudHJ1bmNhdGVkKSB7XG4gICAgICB0aGlzLmZvcmdldChcbiAgICAgICAgYXQsXG4gICAgICAgIFwidGhlIHJldmFsaWRhdGlvbiBsb2cgaGFzIG1vcmUgcm93cyB0aGFuIG9uZSBxdWVyeSByZWFkc1wiLFxuICAgICAgKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gQSBzY2FuIG9mIGV2ZXJ5IGVudHJ5IGhlbGQsIHdoaWNoIGFsc28gZHJvcHMgdGhlIGV4cGlyZWQgb25lcywgb25jZSBpblxuICAgIC8vIGEgd2hpbGU6IHNvIGV4cGlyZWQgZW50cmllcyBuZXZlciByZWFkIGFnYWluIGRvbid0IHBpbGUgdXAgYWhlYWQgb2ZcbiAgICAvLyBsaXZlIG9uZXMuIEluIGJldHdlZW4sIHRoZSBzdG9yZXMgYW5zd2VyIGVhcmx5IHdpdGhvdXQgb25lLCB3aGljaCBvbmx5XG4gICAgLy8ga2VlcHMgcm93cyBpbiBgbG9nT25seWAgYSBsaXR0bGUgbG9uZ2VyLlxuICAgIGNvbnN0IHNjYW4gPSBhdCAtIHRoaXMubGFzdEVudHJ5U2NhbiA+IEVOVFJZX1NDQU5fSU5URVJWQUxfTVM7XG4gICAgaWYgKHNjYW4pIHtcbiAgICAgIHRoaXMubGFzdEVudHJ5U2NhbiA9IGF0O1xuICAgIH1cbiAgICBjb25zdCBvbGRlc3QgPSB0aGlzLm9sZGVzdEVudHJ5KHNjYW4pO1xuICAgIGxldCBhcHBsaWVkID0gMDtcbiAgICBmb3IgKGNvbnN0IHJvdyBvZiByZXN1bHQucm93cykge1xuICAgICAgaWYgKHRoaXMuYXBwbGllZC5oYXMocm93LnNrKSkge1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IG1hcmtlciA9IHRoaXMudGFncy5nZXQocm93LnRhZyk7XG4gICAgICBpZiAobWFya2VyKSB7XG4gICAgICAgIC8vIGBzZXRgIG9uIGEga2V5IGFscmVhZHkgdGhlcmUga2VlcHMgaXRzIHBsYWNlIGluIHRoZSBMUlUgb3JkZXI6IGJlaW5nXG4gICAgICAgIC8vIHJldmFsaWRhdGVkIGVsc2V3aGVyZSBpcyBub3QgYSB1c2UuXG4gICAgICAgIHRoaXMudGFncy5zZXQocm93LnRhZywgbWVyZ2VNYXJrZXJzKG1hcmtlciwgcm93Lm1hcmtlcikpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLnJlYWRpbmcuaGFzKHJvdy50YWcpKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ1Jvd3Muc2V0KFxuICAgICAgICAgIHJvdy50YWcsXG4gICAgICAgICAgbWVyZ2VNYXJrZXJzKHRoaXMucGVuZGluZ1Jvd3MuZ2V0KHJvdy50YWcpLCByb3cubWFya2VyKSxcbiAgICAgICAgKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIEEgdGFnIHRoaXMgaW5zdGFuY2UgZG9lcyBub3QgdHJhY2sgaXMgcmVhZCBmcm9tIGl0cyBtYXJrZXIgd2hlbiBpdFxuICAgICAgICAvLyBpcyBuZXh0IG5lZWRlZCAtIGJ1dCBub3QgeWV0IG1hcmtlZCBhcHBsaWVkLCBiZWNhdXNlIHRoYXQgcmVhZCBtYXlcbiAgICAgICAgLy8gbWlzcyB0aGlzIHZlcnkgcmV2YWxpZGF0aW9uOiB0aGUgd3JpdGVyIHB1dHMgdGhlIGxvZyByb3cgYW5kIHRoZVxuICAgICAgICAvLyBtYXJrZXIgYXQgdGhlIHNhbWUgdGltZSwgYW5kIHRoZSByZWFkIGlzIGFuIGV2ZW50dWFsbHkgY29uc2lzdGVudFxuICAgICAgICAvLyBgQmF0Y2hHZXRJdGVtYCB0aGF0IGNhbiBsYW5kIG1pbGxpc2Vjb25kcyBhZnRlciB0aGUgcm93IHNob3dlZCBoZXJlLlxuICAgICAgICAvLyBNYXJrZWQgYXBwbGllZCwgdGhlIHJvdyB3YXMgc2tpcHBlZCBieSBldmVyeSBxdWVyeSB0aGUgbG9va2JhY2tcbiAgICAgICAgLy8gcmV0dXJuZWQgaXQgdG8sIGFuZCB0aGUgcHJlLXJldmFsaWRhdGlvbiBtYXJrZXIgc3Rvb2QgdW50aWwgdGhlXG4gICAgICAgIC8vIHJvbGxpbmcgcmUtcmVhZC4gTGVmdCB1bm1hcmtlZCwgdGhlIG5leHQgcmVmcmVzaCBhcHBsaWVzIGl0IHRvXG4gICAgICAgIC8vIHdoYXRldmVyIHRoYXQgcmVhZCBmb3VuZDsgaXQgY29zdHMgbm8gcmVhZCwgb25seSB0aGUgcm93IGJlaW5nXG4gICAgICAgIC8vIGxvb2tlZCBhdCBhZ2FpbiB3aGlsZSBpdCBpcyBpbnNpZGUgdGhlIGxvb2tiYWNrLlxuICAgICAgICAvL1xuICAgICAgICAvLyBLZXB0IG1lYW53aGlsZSBpbiBgbG9nT25seWAsIHdoaWNoIGlzIGFsbCBgY29tcGxldGVTaW5jZWAgbmVlZHMuXG4gICAgICAgIHRoaXMucmVtZW1iZXJMb2dnZWQoXG4gICAgICAgICAgcm93LnRhZyxcbiAgICAgICAgICBtZXJnZU1hcmtlcnModGhpcy5sb2dPbmx5LmdldChyb3cudGFnKSwgcm93Lm1hcmtlciksXG4gICAgICAgICAgb2xkZXN0LFxuICAgICAgICApO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIHRoaXMuYXBwbGllZC5zZXQocm93LnNrLCByb3cuYXQpO1xuICAgICAgYXBwbGllZCsrO1xuICAgIH1cbiAgICBpZiAob2xkZXN0ID4gdGhpcy5wcnVuZWRBZ2FpbnN0KSB7XG4gICAgICB0aGlzLnBydW5lTG9nZ2VkKG9sZGVzdCk7XG4gICAgfVxuICAgIC8vIFRoZSByb3dzIGp1c3Qga2VwdCBhcmUga25vd24gYnkgbGF0ZXIgdGhhbiBgb2xkZXN0YCB0b28uXG4gICAgdGhpcy5wcnVuZWRBZ2FpbnN0ID0gb2xkZXN0O1xuICAgIHRoaXMubGFzdExvZ1JlYWQgPSBhdDtcbiAgICB0aGlzLmFkdmFuY2UoYXQgLSBSRVZBTElEQVRJT05fTE9HX0xPT0tCQUNLX01TKTtcbiAgICB0aGlzLmRlYnVnKFxuICAgICAgYHJlYWQgJHtyZXN1bHQucm93cy5sZW5ndGh9IHJldmFsaWRhdGlvbiBsb2cgcm93cyAoJHthcHBsaWVkfSBhcHBsaWVkKWAsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgdGFncyB0byByZWFkIG9uIHRoaXMgcmVmcmVzaCwgYXQgbW9zdCBvbmUgYEJhdGNoR2V0SXRlbWAncyB3b3J0aDpcbiAgICogdGhvc2Ugd2hvc2UgcmVhZCBmYWlsZWQsIHRoZW4gdGhvc2Ugd2hvc2UgcmUtcmVhZCBoYXMgY29tZSBkdWUsIGluIHRoZVxuICAgKiBvcmRlciB0aGV5IHdlcmUgbGFzdCByZWFkLlxuICAgKi9cbiAgcHJpdmF0ZSBkdWUoYXQ6IG51bWJlcik6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBkdWU6IHN0cmluZ1tdID0gW107XG4gICAgZm9yIChjb25zdCB0YWcgb2YgdGhpcy51bnJlYWQpIHtcbiAgICAgIGlmIChkdWUubGVuZ3RoID49IEJBVENIX0dFVF9NQVhfS0VZUykgcmV0dXJuIGR1ZTtcbiAgICAgIGlmICghdGhpcy5yZWFkaW5nLmhhcyh0YWcpKSB7XG4gICAgICAgIGR1ZS5wdXNoKHRhZyk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEtub3duIGluIHRpbWUgb3JkZXIsIGFuZCBlYWNoIGR1ZSBhdCBtb3N0IGBqaXR0ZXJgIGVhcmxpZXIgdGhhbiB0aGVcbiAgICAvLyB0YWdzIGFmdGVyIGl0OiBwYXN0IGEgdGFnIGR1ZSBtb3JlIHRoYW4gdGhhdCBmcm9tIG5vdywgbm9uZSBpcyBkdWUuXG4gICAgY29uc3Qgaml0dGVyID0gdGhpcy5yZXN5bmNJbnRlcnZhbE1zICogVEFHX1JFU1lOQ19KSVRURVI7XG4gICAgZm9yIChjb25zdCBbdGFnLCBkdWVBdF0gb2YgdGhpcy5kdWVBdCkge1xuICAgICAgaWYgKGR1ZS5sZW5ndGggPj0gQkFUQ0hfR0VUX01BWF9LRVlTIHx8IGR1ZUF0IC0gaml0dGVyID4gYXQpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBpZiAoZHVlQXQgPD0gYXQgJiYgIXRoaXMudW5yZWFkLmhhcyh0YWcpICYmICF0aGlzLnJlYWRpbmcuaGFzKHRhZykpIHtcbiAgICAgICAgZHVlLnB1c2godGFnKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGR1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBGb3JnZXQgZXZlcnkgdHJhY2tlZCBtYXJrZXIsIGFuZCBmb2xsb3cgdGhlIGxvZyBmcm9tIGBhdGA6IHdoYXQgaXMgbmVlZGVkXG4gICAqIG5leHQgaXMgcmVhZCBmcm9tIGl0cyBtYXJrZXIgYXMgaXQgaXMgbmVlZGVkLCBzcHJlYWQgb3ZlciB0aGUgcmVxdWVzdHNcbiAgICogdGhhdCBuZWVkIGl0LCByYXRoZXIgdGhhbiBldmVyeSB0cmFja2VkIHRhZyByZS1yZWFkIGF0IG9uY2UuXG4gICAqL1xuICBwcml2YXRlIGZvcmdldChhdDogbnVtYmVyLCB3aHk6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuZGVidWcoYGZvcmdldHRpbmcgJHt0aGlzLnRhZ3Muc2l6ZX0gdHJhY2tlZCB0YWdzOiAke3doeX1gKTtcbiAgICB0aGlzLmZvcmdvdHRlbisrO1xuICAgIC8vIFdoYXQgdGhlIG1hcmtlcnMgZXhwaXJlIGxhdGVyIGlzIHN0aWxsIHRvIGFwcGx5IG9uY2UgaXQgaXMgcGFzdC5cbiAgICBmb3IgKGNvbnN0IG1hcmtlciBvZiB0aGlzLnRhZ3MudmFsdWVzKCkpIHtcbiAgICAgIHRoaXMucmFpc2VGbG9vcihtYXJrZXIpO1xuICAgIH1cbiAgICBmb3IgKGNvbnN0IG1hcmtlciBvZiB0aGlzLmxvZ09ubHkudmFsdWVzKCkpIHtcbiAgICAgIHRoaXMucmFpc2VGbG9vcihtYXJrZXIpO1xuICAgIH1cbiAgICB0aGlzLnRhZ3MuY2xlYXIoKTtcbiAgICB0aGlzLmR1ZUF0LmNsZWFyKCk7XG4gICAgdGhpcy51bnJlYWQuY2xlYXIoKTtcbiAgICB0aGlzLmFwcGxpZWQuY2xlYXIoKTtcbiAgICB0aGlzLmxvZ09ubHkuY2xlYXIoKTtcbiAgICAvLyBOZXZlciBiYWNrOiBhIG1hcmtlciBkcm9wcGVkIGVhcmxpZXIgbWF5IGhhdmUgZXhwaXJlZCBlbnRyaWVzIGxhdGVyLlxuICAgIHRoaXMuZmxvb3IgPSBNYXRoLm1heCh0aGlzLmZsb29yLCBtYXJrZXJDbG9jaygpKTtcbiAgICB0aGlzLmN1cnNvciA9IGF0IC0gUkVWQUxJREFUSU9OX0xPR19MT09LQkFDS19NUztcbiAgICB0aGlzLmxhc3RMb2dSZWFkID0gYXQ7XG4gIH1cblxuICAvKipcbiAgICogTW92ZSB0aGUgY3Vyc29yIGZvcndhcmQgdG8gYGN1cnNvcmAsIGZvcmdldHRpbmcgYXBwbGllZCByb3dzIGJlZm9yZSBpdDpcbiAgICogbm8gcXVlcnkgcmV0dXJucyB0aGVtIGFnYWluLlxuICAgKi9cbiAgcHJpdmF0ZSBhZHZhbmNlKGN1cnNvcjogbnVtYmVyKTogdm9pZCB7XG4gICAgaWYgKGN1cnNvciA8PSB0aGlzLmN1cnNvcikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmN1cnNvciA9IGN1cnNvcjtcbiAgICBmb3IgKGNvbnN0IFtzaywgYXRdIG9mIHRoaXMuYXBwbGllZCkge1xuICAgICAgaWYgKGF0IDwgY3Vyc29yKSB7XG4gICAgICAgIHRoaXMuYXBwbGllZC5kZWxldGUoc2spO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWFkIGB0YWdzYCBmcm9tIHRoZSB0YWJsZSwgYW5kIHJlcG9ydCB3aGV0aGVyIHRoYXQgd29ya2VkLiBBIHJlYWQgdGhhdFxuICAgKiBmYWlscyBsZWF2ZXMgdGhlbSB0cmFja2VkIGFzIHRoZXkgd2VyZSwgYW5kIHRoZSBuZXh0IHJlZnJlc2ggcmVhZHMgdGhlbVxuICAgKiBhZ2FpbjogdGhlIHNhbWUgXCJhc3N1bWUgdGhlIGVudHJ5IGlzIHZhbGlkXCIgdGhlIGluY3JlbWVudGFsIGNhY2hlIGhhc1xuICAgKiBhbHdheXMgYW5zd2VyZWQgd2l0aCwgcmF0aGVyIHRoYW4gYSByZWFkIG9uIGV2ZXJ5IHJlcXVlc3Qgd2hpbGUgRHluYW1vREJcbiAgICogaXMgdW5hdmFpbGFibGUuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIHJlYWRJbnRvKHRhZ3M6IHN0cmluZ1tdLCBhZ2FpbiA9IGZhbHNlKTogUHJvbWlzZTxib29sZWFuPiB7XG4gICAgaWYgKHRhZ3MubGVuZ3RoID09PSAwKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG4gICAgY29uc3QgYXQgPSB0aGlzLmNsb2NrKCk7XG4gICAgY29uc3QgZm9yZ290dGVuID0gdGhpcy5mb3Jnb3R0ZW47XG4gICAgdHJ5IHtcbiAgICAgIGNvbnN0IHJlYWQgPSBhd2FpdCB0aGlzLm1hcmtlcnMhLnJlYWQodGFncyk7XG4gICAgICBpZiAodGhpcy5mb3Jnb3R0ZW4gIT09IGZvcmdvdHRlbiAmJiAhYWdhaW4pIHtcbiAgICAgICAgLy8gUmVhZCBiZWZvcmUgYSBmb3JnZXQgLSBhY3Jvc3MgYSBmcmVlemUsIGFzIGxpa2UgYXMgbm90IC0gc28gYXNcbiAgICAgICAgLy8gc3RhbGUgYXMgd2hhdCBpdCBmb3Jnb3QuIFJlYWQgYWdhaW4gcmF0aGVyIHRoYW4gbGVhdmUgdGhlIHRhZ3NcbiAgICAgICAgLy8gdW50cmFja2VkOiB3aG9ldmVyIHdhaXRzIG9uIHRoaXMgcmVhZCAoYHJlYWRpbmdgKSBqdWRnZXMgZW50cmllc1xuICAgICAgICAvLyBieSBpdCBuZXh0LCBhbmQgYW4gdW50cmFja2VkIHRhZyBjb3VudHMgZm9yIG5vdGhpbmcuIE9uY2U6IGEgcnVuXG4gICAgICAgIC8vIG9mIGZvcmdldHMgKGEgdHJ1bmNhdGVkIGxvZywgcXVlcnkgYWZ0ZXIgcXVlcnkpIHdvdWxkIG90aGVyd2lzZVxuICAgICAgICAvLyBrZWVwIHRoZW0gd2FpdGluZywgYW5kIHRoZSBzZWNvbmQgcmVhZCBiZWdhbiBhZnRlciB0aGUgZmlyc3QuXG4gICAgICAgIHJldHVybiBhd2FpdCB0aGlzLnJlYWRJbnRvKHRhZ3MsIHRydWUpO1xuICAgICAgfVxuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgICB0aGlzLnVucmVhZC5kZWxldGUodGFnKTtcbiAgICAgICAgdGhpcy5yZW1lbWJlcihcbiAgICAgICAgICB0YWcsXG4gICAgICAgICAgbWVyZ2VNYXJrZXJzKFxuICAgICAgICAgICAgbWVyZ2VNYXJrZXJzKHRoaXMudGFncy5nZXQodGFnKSwgcmVhZC5nZXQodGFnKSksXG4gICAgICAgICAgICB0aGlzLnRha2VQZW5kaW5nUm93cyh0YWcpLFxuICAgICAgICAgICksXG4gICAgICAgICk7XG4gICAgICAgIHRoaXMua25vd24odGFnLCBhdCk7XG4gICAgICB9XG4gICAgICB0aGlzLmRlYnVnKGByZWFkICR7dGFncy5sZW5ndGh9IHRhZyBtYXJrZXJzICgke3JlYWQuc2l6ZX0gc2V0KWApO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNvbnNvbGUuZXJyb3IoXCJFcnJvciByZWFkaW5nIHRhZyBtYXJrZXJzOlwiLCBlcnJvcik7XG4gICAgICBpZiAodGhpcy5mb3Jnb3R0ZW4gIT09IGZvcmdvdHRlbiAmJiAhYWdhaW4pIHtcbiAgICAgICAgcmV0dXJuIHRoaXMucmVhZEludG8odGFncywgdHJ1ZSk7XG4gICAgICB9XG4gICAgICB0aGlzLnRyYWNrVW5yZWFkKHRhZ3MpO1xuICAgICAgZm9yIChjb25zdCB0YWcgb2YgdGFncykge1xuICAgICAgICB0aGlzLnVucmVhZC5hZGQodGFnKTtcbiAgICAgICAgY29uc3QgcGVuZGluZyA9IHRoaXMudGFrZVBlbmRpbmdSb3dzKHRhZyk7XG4gICAgICAgIGlmIChwZW5kaW5nKSB7XG4gICAgICAgICAgdGhpcy5yZW1lbWJlcih0YWcsIG1lcmdlTWFya2Vycyh0aGlzLnRhZ3MuZ2V0KHRhZyksIHBlbmRpbmcpKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgdGFrZVBlbmRpbmdSb3dzKHRhZzogc3RyaW5nKTogVGFnTWFya2VyIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nUm93cy5nZXQodGFnKTtcbiAgICBjb25zdCBsb2dnZWQgPSB0aGlzLmxvZ09ubHkuZ2V0KHRhZyk7XG4gICAgdGhpcy5wZW5kaW5nUm93cy5kZWxldGUodGFnKTtcbiAgICB0aGlzLmxvZ09ubHkuZGVsZXRlKHRhZyk7XG4gICAgcmV0dXJuIGxvZ2dlZCA/IG1lcmdlTWFya2Vycyhsb2dnZWQsIHBlbmRpbmcpIDogcGVuZGluZztcbiAgfVxuXG4gIC8qKlxuICAgKiBXaGF0IHRoaXMgaW5zdGFuY2Uga25vd3Mgb2YgYHRhZ2A6IHRyYWNrZWQsIG9yIGZyb20gdGhlIGxvZyBhbG9uZSAtXG4gICAqIGluY2x1ZGluZyByb3dzIHRoYXQgYXJyaXZlZCB3aGlsZSBpdHMgZmlyc3QgcmVhZCBpcyBpbiBmbGlnaHQuXG4gICAqL1xuICBwcml2YXRlIGtub3duTWFya2VyKHRhZzogc3RyaW5nKTogVGFnTWFya2VyIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCB0cmFja2VkID0gdGhpcy50YWdzLmdldCh0YWcpO1xuICAgIGlmICh0cmFja2VkKSB7XG4gICAgICByZXR1cm4gdHJhY2tlZDtcbiAgICB9XG4gICAgY29uc3QgbG9nZ2VkID0gdGhpcy5sb2dPbmx5LmdldCh0YWcpO1xuICAgIGNvbnN0IHBlbmRpbmcgPSB0aGlzLnBlbmRpbmdSb3dzLmdldCh0YWcpO1xuICAgIHJldHVybiBsb2dnZWQgfHwgcGVuZGluZyA/IG1lcmdlTWFya2Vycyhsb2dnZWQsIHBlbmRpbmcpIDogdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEtlZXAgYHRhZ2AncyBsb2cgcm93cyBpbiBgbG9nT25seWAsIHVubGVzcyB0aGV5IGNhbm5vdCBhcHBseSB0byBhbiBlbnRyeVxuICAgKiBoZWxkLCBgb2xkZXN0YCBvciBuZXdlciAoc2VlIHtAbGluayBwcnVuZUxvZ2dlZH0pLCBhcyBib3VuZGVkIGFzIHRoZVxuICAgKiB0cmFja2VkIHRhZ3MuIEVpdGhlciB3YXkgYSByb3cgbGV0IGdvIG9mIHRha2VzIHdoYXQgaXQga25ldyB3aXRoIGl0LCBzb1xuICAgKiBgY29tcGxldGVTaW5jZWAgbW92ZXMgcGFzdCBpdC5cbiAgICovXG4gIHByaXZhdGUgcmVtZW1iZXJMb2dnZWQodGFnOiBzdHJpbmcsIG1hcmtlcjogVGFnTWFya2VyLCBvbGRlc3Q6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMubG9nT25seS5kZWxldGUodGFnKTtcbiAgICBpZiAoa25vd25CeShtYXJrZXIsIG1hcmtlckNsb2NrKCkpIDw9IG9sZGVzdCkge1xuICAgICAgdGhpcy5yYWlzZUZsb29yKG1hcmtlcik7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMubG9nT25seS5zZXQodGFnLCBtYXJrZXIpO1xuICAgIGZvciAoY29uc3QgW2ZpcnN0LCBkcm9wcGVkXSBvZiB0aGlzLmxvZ09ubHkpIHtcbiAgICAgIGlmICh0aGlzLmxvZ09ubHkuc2l6ZSA8PSB0aGlzLm1heFRyYWNrZWRUYWdzKSB7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgdGhpcy5sb2dPbmx5LmRlbGV0ZShmaXJzdCk7XG4gICAgICB0aGlzLnJhaXNlRmxvb3IoZHJvcHBlZCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIERyb3AgdGhlIGBsb2dPbmx5YCByb3dzIHRoYXQgY2Fubm90IGFwcGx5IHRvIGFuIGVudHJ5IGhlbGQsIGBvbGRlc3RgIG9yXG4gICAqIG5ld2VyOiBldmVyeSByZXZhbGlkYXRpb24gdGhleSBuYW1lIHNvIGZhciBpcyBubyBsYXRlciB0aGFuIGl0LiBUaGF0XG4gICAqIG1vdmVzIGBjb21wbGV0ZVNpbmNlYCBubyBmdXJ0aGVyIHRoYW4gYG9sZGVzdGAsIHdoaWNoIGNvc3RzIHRoZSBlbnRyaWVzXG4gICAqIGhlbGQgbm90aGluZywgYW5kIGEgcHJvZmlsZSdzIGBleHBpcmVkQXRgIHN0aWxsIHRvIGNvbWUgd2FpdHMgaW5cbiAgICogYGxhdGVyRmxvb3JzYC4gV2l0aG91dCB0aGlzLCBhIGRlcGxveW1lbnQgcmV2YWxpZGF0aW5nIG1hbnkgZGlzdGluY3QgdGFnc1xuICAgKiBmaWxsZWQgYGxvZ09ubHlgIHdpdGggdGFncyBubyBlbnRyeSBoZXJlIGNhcnJpZXMsIGFuZCB0aGUgZXZpY3Rpb25zIHBhc3RcbiAgICogaXRzIGJvdW5kIGtlcHQgbW92aW5nIGBjb21wbGV0ZVNpbmNlYCB1cCB0byB0aGUgcHJlc2VudC5cbiAgICovXG4gIHByaXZhdGUgcHJ1bmVMb2dnZWQob2xkZXN0OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBhdCA9IG1hcmtlckNsb2NrKCk7XG4gICAgZm9yIChjb25zdCBbdGFnLCBtYXJrZXJdIG9mIHRoaXMubG9nT25seSkge1xuICAgICAgaWYgKGtub3duQnkobWFya2VyLCBhdCkgPD0gb2xkZXN0KSB7XG4gICAgICAgIHRoaXMubG9nT25seS5kZWxldGUodGFnKTtcbiAgICAgICAgdGhpcy5yYWlzZUZsb29yKG1hcmtlcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFRoZSBvbGRlc3QgZW50cnkgdGltZXN0YW1wIG9mIGFueSByZWdpc3RlcmVkIHN0b3JlLCBgSW5maW5pdHlgIHdpdGggbm9uZTpcbiAgICogZWFybHksIG5ldmVyIGxhdGUsIHVubGVzcyBgc2NhbmAuXG4gICAqL1xuICBwcml2YXRlIG9sZGVzdEVudHJ5KHNjYW46IGJvb2xlYW4pOiBudW1iZXIge1xuICAgIGxldCBvbGRlc3QgPSBJbmZpbml0eTtcbiAgICBmb3IgKGNvbnN0IHsgb2xkZXN0VGltZXN0YW1wIH0gb2YgdGhpcy5lbnRyeVN0b3Jlcykge1xuICAgICAgb2xkZXN0ID0gTWF0aC5taW4ob2xkZXN0LCBvbGRlc3RUaW1lc3RhbXAoc2NhbikpO1xuICAgIH1cbiAgICByZXR1cm4gb2xkZXN0O1xuICB9XG5cbiAgLyoqXG4gICAqIE1vdmUgYGNvbXBsZXRlU2luY2VgIHBhc3QgYG1hcmtlcmAncyByZXZhbGlkYXRpb25zOiB3aGF0IGlzIG5vIGxvbmdlclxuICAgKiBrbm93biBhYm91dCBhIHRhZyBvbmNlIGl0cyBtYXJrZXIgaXMgZHJvcHBlZC4gQSBmdXR1cmUgYGV4cGlyZWRBdGAgd2FpdHNcbiAgICogaW4gYGxhdGVyRmxvb3JzYCB1bnRpbCBpdCBpcyBwYXN0LlxuICAgKi9cbiAgcHJpdmF0ZSByYWlzZUZsb29yKG1hcmtlcjogVGFnTWFya2VyKTogdm9pZCB7XG4gICAgY29uc3QgYXQgPSBtYXJrZXJDbG9jaygpO1xuICAgIHRoaXMuZmxvb3IgPSBNYXRoLm1heCh0aGlzLmZsb29yLCBrbm93bkJ5KG1hcmtlciwgYXQpKTtcbiAgICBjb25zdCB7IGV4cGlyZWRBdCB9ID0gbWFya2VyO1xuICAgIGlmIChleHBpcmVkQXQgIT09IHVuZGVmaW5lZCAmJiBleHBpcmVkQXQgPiBNYXRoLm1heChhdCwgdGhpcy5mbG9vcikpIHtcbiAgICAgIHRoaXMubGF0ZXJGbG9vcihleHBpcmVkQXQpO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBZGQgYHRpbWVgIHRvIGBsYXRlckZsb29yc2AsIGluIG9yZGVyLiBQYXN0IHRoZSB0cmFja2VkLXRhZyBib3VuZCB0aGUgdHdvXG4gICAqIHNwYW5zIGNsb3Nlc3QgdG9nZXRoZXIgYXJlIG1lcmdlZDogZnJvbSB0aGUgZmlyc3QncyBzdGFydCxcbiAgICogYGNvbXBsZXRlU2luY2VgIGlzIHRoZSBzZWNvbmQncyBlbmQsIGVhcmx5IC0gd2hpY2ggb25seSBjb3N0cyByZWFkcywgYW5kXG4gICAqIGZvciBhcyBzaG9ydCBhIHRpbWUgYXMgYW55IG1lcmdlIGFsbG93cy4gTmV2ZXIgbGF0ZXIgdGhhbiBpdHMgdGltZSwgd2hpY2hcbiAgICogd291bGQgbGV0IGFuIGVudHJ5IGV4cGlyZSB1bnNlZW4uXG4gICAqL1xuICBwcml2YXRlIGxhdGVyRmxvb3IodGltZTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgZmxvb3JzID0gdGhpcy5sYXRlckZsb29ycztcbiAgICBsZXQgbG93ID0gMDtcbiAgICBsZXQgaGlnaCA9IGZsb29ycy5sZW5ndGg7XG4gICAgd2hpbGUgKGxvdyA8IGhpZ2gpIHtcbiAgICAgIGNvbnN0IG1pZCA9IE1hdGguZmxvb3IoKGxvdyArIGhpZ2gpIC8gMik7XG4gICAgICBpZiAoZmxvb3JzW21pZF1bMF0gPCB0aW1lKSB7XG4gICAgICAgIGxvdyA9IG1pZCArIDE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBoaWdoID0gbWlkO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBJbnNpZGUgYSBtZXJnZWQgc3BhbiBhbHJlYWR5OiBieSBpdHMgc3RhcnQsIGBjb21wbGV0ZVNpbmNlYCBpcyBwYXN0IGl0LlxuICAgIC8vIE9yIGFscmVhZHkgdGhlcmU6IGEgbG9nIHJvdyBmb3IgYW4gdW50cmFja2VkIHRhZyBpcyBhcHBsaWVkIGFnYWluIGJ5XG4gICAgLy8gZXZlcnkgcXVlcnkgaXRzIGxvb2tiYWNrIHJldHVybnMgaXQgdG8uXG4gICAgaWYgKChsb3cgPiAwICYmIGZsb29yc1tsb3cgLSAxXVsxXSA+PSB0aW1lKSB8fCBmbG9vcnNbbG93XT8uWzBdID09PSB0aW1lKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGZsb29ycy5zcGxpY2UobG93LCAwLCBbdGltZSwgdGltZV0pO1xuICAgIC8vIEEgc2NhbiwgYnV0IG9ubHkgb25jZSBwYXN0IHRoZSBib3VuZC4gTWVyZ2luZyB0aGUgbmV3IHRpbWUgaW50byBhXG4gICAgLy8gbmVpZ2hib3VyIGluc3RlYWQgY291bGQgam9pbiBhbiBob3VyLW91dCBzcGFuIHdpdGggYSB5ZWFyLW91dCBvbmUsIGFuZFxuICAgIC8vIGhvbGQgYGNvbXBsZXRlU2luY2VgIGEgeWVhciBlYXJseS5cbiAgICBpZiAoZmxvb3JzLmxlbmd0aCA+IHRoaXMubWF4VHJhY2tlZFRhZ3MpIHtcbiAgICAgIGxldCBtZXJnZSA9IDA7XG4gICAgICBmb3IgKGxldCBpID0gMTsgaSA8IGZsb29ycy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgICAgaWYgKFxuICAgICAgICAgIGZsb29yc1tpICsgMV1bMV0gLSBmbG9vcnNbaV1bMF0gPFxuICAgICAgICAgIGZsb29yc1ttZXJnZSArIDFdWzFdIC0gZmxvb3JzW21lcmdlXVswXVxuICAgICAgICApIHtcbiAgICAgICAgICBtZXJnZSA9IGk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGZsb29ycy5zcGxpY2UobWVyZ2UsIDIsIFtmbG9vcnNbbWVyZ2VdWzBdLCBmbG9vcnNbbWVyZ2UgKyAxXVsxXV0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBSZWNvcmQgdGhhdCBgdGFnYCdzIG1hcmtlciB3YXMga25vd24gZnJvbSB0aGUgdGFibGUgYXQgYGF0YC4gKi9cbiAgcHJpdmF0ZSBrbm93bih0YWc6IHN0cmluZywgYXQ6IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMuZHVlQXQuZGVsZXRlKHRhZyk7XG4gICAgdGhpcy5kdWVBdC5zZXQoXG4gICAgICB0YWcsXG4gICAgICBhdCArIHRoaXMucmVzeW5jSW50ZXJ2YWxNcyAqICgxIC0gVEFHX1JFU1lOQ19KSVRURVIgKiB0aGlzLnJhbmRvbSgpKSxcbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1lbWJlcih0YWc6IHN0cmluZywgbWFya2VyOiBUYWdNYXJrZXIpOiB2b2lkIHtcbiAgICB0aGlzLnRhZ3MuZGVsZXRlKHRhZyk7XG4gICAgdGhpcy50YWdzLnNldCh0YWcsIG1hcmtlcik7XG4gICAgZm9yIChjb25zdCBvbGRlc3Qgb2YgdGhpcy50YWdzLmtleXMoKSkge1xuICAgICAgaWYgKHRoaXMudGFncy5zaXplIDw9IHRoaXMubWF4VHJhY2tlZFRhZ3MpIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICB0aGlzLnJhaXNlRmxvb3IodGhpcy50YWdzLmdldChvbGRlc3QpISk7XG4gICAgICB0aGlzLnRhZ3MuZGVsZXRlKG9sZGVzdCk7XG4gICAgICB0aGlzLmR1ZUF0LmRlbGV0ZShvbGRlc3QpO1xuICAgICAgdGhpcy51bnJlYWQuZGVsZXRlKG9sZGVzdCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSB0b3VjaCh0YWc6IHN0cmluZyk6IHZvaWQge1xuICAgIGNvbnN0IG1hcmtlciA9IHRoaXMudGFncy5nZXQodGFnKTtcbiAgICBpZiAobWFya2VyKSB7XG4gICAgICB0aGlzLnJlbWVtYmVyKHRhZywgbWFya2VyKTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBUaGUgbGF0ZXN0IHJldmFsaWRhdGlvbiBgbWFya2VyYCBoYXMgbWFkZSBrbm93biBieSBgYXRgLCBgLUluZmluaXR5YCB3aXRoXG4gKiBub25lOiBhIGZ1dHVyZSBgZXhwaXJlZEF0YCBpcyBzdGlsbCB0byBjb21lLlxuICovXG5mdW5jdGlvbiBrbm93bkJ5KG1hcmtlcjogVGFnTWFya2VyLCBhdDogbnVtYmVyKTogbnVtYmVyIHtcbiAgY29uc3QgeyByZXZhbGlkYXRlZEF0LCBzdGFsZUF0LCBleHBpcmVkQXQgfSA9IG1hcmtlcjtcbiAgcmV0dXJuIE1hdGgubWF4KFxuICAgIHJldmFsaWRhdGVkQXQgPz8gLUluZmluaXR5LFxuICAgIHN0YWxlQXQgPz8gLUluZmluaXR5LFxuICAgIGV4cGlyZWRBdCAhPT0gdW5kZWZpbmVkICYmIGV4cGlyZWRBdCA8PSBhdCA/IGV4cGlyZWRBdCA6IC1JbmZpbml0eSxcbiAgKTtcbn1cblxuLyoqXG4gKiBUaGUgbG9uZ2VzdCBhIGxvZyByb3cncyBwdXQgbWF5IHRha2UgYW5kIHN0aWxsIGJlIHNlZW4gYnkgZXZlcnkgcmVhZGVyOiBoYWxmXG4gKiB0aGUgbG9va2JhY2ssIGxlYXZpbmcgdGhlIHJlc3QgZm9yIHdyaXRlcnMnIGNsb2NrcyBhbmQgZXZlbnR1YWxseSBjb25zaXN0ZW50XG4gKiBxdWVyaWVzLlxuICovXG5jb25zdCBNQVhfTE9HX1BVVF9NUyA9IFJFVkFMSURBVElPTl9MT0dfTE9PS0JBQ0tfTVMgLyAyO1xuXG4vKipcbiAqIEhvdyBvZnRlbiBhIHJlZnJlc2ggc2NhbnMgdGhlIGVudHJ5IHN0b3JlcyBmb3IgdGhlaXIgb2xkZXN0IGVudHJ5LCBkcm9wcGluZ1xuICogdGhlIGV4cGlyZWQgb25lcyBubyByZXF1ZXN0IHJlYWRzIGFnYWluLlxuICovXG5jb25zdCBFTlRSWV9TQ0FOX0lOVEVSVkFMX01TID0gNjBfMDAwO1xuXG4vKiogSG93IG9mdGVuIGEgcmVmcmVzaCBpbiBmbGlnaHQgY2hlY2tzIHRoZSBwcm9jZXNzIGlzIHJ1bm5pbmcuICovXG5jb25zdCBSRUZSRVNIX1RJQ0tfTVMgPSAyNTA7XG5cbi8qKlxuICogSG93IGxhdGUgYSB0aWNrIG1heSBjb21lIGJlZm9yZSB0aGUgcHJvY2VzcyBjb3VudHMgYXMgcGF1c2VkIChmcm96ZW4pXG4gKiBzaW5jZSB0aGUgcmVmcmVzaCBpbiBmbGlnaHQgc3RhcnRlZC4gQSBidXN5IGV2ZW50IGxvb3AgY2FuIGRlbGF5IG9uZSB0b286XG4gKiB0aGUgcmVmcmVzaCB0aGVuIGNvdW50cyBhcyBubyBmcmVzaGVyIHRoYW4gaXRzIHN0YXJ0LCBhcyBiZWZvcmUgdGhlIHBhdXNlXG4gKiBjaGVjaywgc28gYSByZXF1ZXN0IHdhaXRzIGZvciB0aGUgbmV4dCBvbmUgb25jZSB0aGF0IGlzIHBhc3QgdGhlIGdyYWNlLlxuICovXG5jb25zdCBSRUZSRVNIX1BBVVNFX01TID0gMTAwMDtcblxuLyoqXG4gKiBBIG1hcmtlciBhcyByZWFkIGZyb20gdGhlIHRhYmxlIG9yIHRoZSBsb2csIGtlZXBpbmcgd2hhdGV2ZXIgdGhpcyBpbnN0YW5jZVxuICogYWxyZWFkeSBrbm93cyB0aGF0IHRoZSByZWFkIGRvZXMgbm90IHNob3cgeWV0OiByZWFkcyBhcmUgZXZlbnR1YWxseVxuICogY29uc2lzdGVudCwgYW5kIGEgcmVhZCBzdHJhaWdodCBhZnRlciB0aGlzIGluc3RhbmNlJ3Mgb3duIHJldmFsaWRhdGlvbiBjb3VsZFxuICogb3RoZXJ3aXNlIHRha2UgaXQgYmFjay5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1lcmdlTWFya2VycyhcbiAgbG9jYWw6IFRhZ01hcmtlciB8IHVuZGVmaW5lZCxcbiAgcmVtb3RlOiBUYWdNYXJrZXIgfCB1bmRlZmluZWQsXG4pOiBUYWdNYXJrZXIge1xuICBpZiAoIWxvY2FsKSB7XG4gICAgcmV0dXJuIHJlbW90ZSA/PyB7fTtcbiAgfVxuICBpZiAoIXJlbW90ZSkge1xuICAgIHJldHVybiBsb2NhbDtcbiAgfVxuICAvLyBgZXhwaXJlZEF0YCBpcyB3cml0dGVuIHdpdGggYHN0YWxlQXRgLCBzbyBpdCBiZWxvbmdzIHRvIHdoaWNoZXZlciBpc1xuICAvLyBuZXdlciAtIHVubGVzcyB0aGF0IHJldmFsaWRhdGlvbidzIHByb2ZpbGUgaGFkIG5vIGBleHBpcmVgIGFuZCBsZWZ0IGl0LlxuICBjb25zdCBbb2xkZXIsIG5ld2VyXSA9XG4gICAgKGxvY2FsLnN0YWxlQXQgPz8gLTEpID4gKHJlbW90ZS5zdGFsZUF0ID8/IC0xKVxuICAgICAgPyBbcmVtb3RlLCBsb2NhbF1cbiAgICAgIDogW2xvY2FsLCByZW1vdGVdO1xuICByZXR1cm4ge1xuICAgIC4uLmFwcGx5TWFya2VyKG9sZGVyLCBuZXdlciksXG4gICAgcmV2YWxpZGF0ZWRBdDogbWF4RGVmaW5lZChsb2NhbC5yZXZhbGlkYXRlZEF0LCByZW1vdGUucmV2YWxpZGF0ZWRBdCksXG4gIH07XG59XG5cbmZ1bmN0aW9uIG1heERlZmluZWQoYTogbnVtYmVyIHwgdW5kZWZpbmVkLCBiOiBudW1iZXIgfCB1bmRlZmluZWQpIHtcbiAgaWYgKGEgPT09IHVuZGVmaW5lZCkgcmV0dXJuIGI7XG4gIGlmIChiID09PSB1bmRlZmluZWQpIHJldHVybiBhO1xuICByZXR1cm4gTWF0aC5tYXgoYSwgYik7XG59XG5cbi8qKlxuICogVGhlIGNhY2hlIGJ1Y2tldCwgYXMgdGhlIGhhbmRsZXJzIHVzZSBpdDogd2hvbGUgb2JqZWN0cyByZWFkIGFuZCB3cml0dGVuIGFzXG4gKiBVVEYtOCB0ZXh0IHVuZGVyIHRoZSBrZXlzIGFib3ZlLlxuICovXG5leHBvcnQgY2xhc3MgQ2FjaGVCdWNrZXQge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNsaWVudDogUzNDbGllbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBidWNrZXROYW1lOiBzdHJpbmcsXG4gICkge31cblxuICAvKipcbiAgICogVGhlIGJvZHkgb2YgdGhlIG9iamVjdCBhdCBga2V5YCwgb3IgYHVuZGVmaW5lZGAgd2hlbiB0aGVyZSBpcyBub25lIChgTm9TdWNoS2V5YCwgb3IgYW5cbiAgICogZW1wdHkgcmVzcG9uc2UgYm9keSkuIEFueSBvdGhlciBlcnJvciBpcyB0aHJvd246IHRoZSBoYW5kbGVycyBkaXNhZ3JlZSBvblxuICAgKiB3aGV0aGVyIG9uZSBpcyB3b3J0aCBsb2dnaW5nLlxuICAgKi9cbiAgYXN5bmMgZ2V0KGtleTogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+IHtcbiAgICB0cnkge1xuICAgICAgY29uc3QgcmVzcG9uc2UgPSBhd2FpdCB0aGlzLmNsaWVudC5zZW5kKFxuICAgICAgICBuZXcgR2V0T2JqZWN0Q29tbWFuZCh7IEJ1Y2tldDogdGhpcy5idWNrZXROYW1lLCBLZXk6IGtleSB9KSxcbiAgICAgICk7XG4gICAgICBpZiAoIXJlc3BvbnNlLkJvZHkpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBhd2FpdCByZXNwb25zZS5Cb2R5LnRyYW5zZm9ybVRvU3RyaW5nKFwidXRmLThcIik7XG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIE5vU3VjaEtleSkge1xuICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgICAgfVxuICAgICAgdGhyb3cgZXJyb3I7XG4gICAgfVxuICB9XG5cbiAgLyoqIFdyaXRlIGBib2R5YCBhcyBhIEpTT04gb2JqZWN0IGF0IGBrZXlgLiAqL1xuICBhc3luYyBwdXRKc29uKGtleTogc3RyaW5nLCBib2R5OiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBhd2FpdCB0aGlzLmNsaWVudC5zZW5kKFxuICAgICAgbmV3IFB1dE9iamVjdENvbW1hbmQoe1xuICAgICAgICBCdWNrZXQ6IHRoaXMuYnVja2V0TmFtZSxcbiAgICAgICAgS2V5OiBrZXksXG4gICAgICAgIEJvZHk6IGJvZHksXG4gICAgICAgIENvbnRlbnRUeXBlOiBcImFwcGxpY2F0aW9uL2pzb247IGNoYXJzZXQ9dXRmLThcIixcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cbn1cbiJdfQ==
|