velocious 1.0.418 → 1.0.419

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.
@@ -3,10 +3,12 @@ import { AsyncLocalStorage } from "async_hooks";
3
3
  import BasePool, { POOL_CONFIGURATION_KEY } from "./base.js";
4
4
  export const CLOSED_CONNECTION = Symbol("velociousClosedConnection");
5
5
  const IDLE_CONNECTION_CHECKED_IN_AT = Symbol("velociousIdleConnectionCheckedInAt");
6
+ const CONNECTION_CHECKED_OUT_AT = Symbol("velociousConnectionCheckedOutAt");
6
7
  const DEFAULT_IDLE_TIMEOUT_MILLIS = 5000;
7
8
  /**
8
9
  * @typedef {object} PendingCheckout
9
10
  * @property {import("../../configuration-types.js").DatabaseConfigurationType} databaseConfig - Resolved database configuration needed by the checkout.
11
+ * @property {number} enqueuedAt - Timestamp when the checkout started waiting.
10
12
  * @property {import("./base.js").ConnectionCheckoutOptions} options - Checkout options.
11
13
  * @property {string} reuseKey - Database configuration reuse key needed by the checkout.
12
14
  * @property {(connection: import("../drivers/base.js").default) => void} resolve - Resolves with an activated connection.
@@ -69,14 +71,8 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
69
71
  */
70
72
  async checkin(connection) {
71
73
  const id = connection.getIdSeq();
72
- if (typeof id !== "number") {
73
- throw new Error(`idSeq on connection wasn't set? '${typeof id}' = ${id}`);
74
- }
75
- if (id in this.connectionsInUse) {
76
- delete this.connectionsInUse[id];
77
- }
78
- connection.setIdSeq(undefined);
79
- const trackedConnection = /** @type {import("../drivers/base.js").default & {[CLOSED_CONNECTION]?: boolean, [IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
74
+ this.untrackConnectionInUse(connection, id);
75
+ const trackedConnection = /** @type {import("../drivers/base.js").default & {[CLOSED_CONNECTION]?: boolean, [CONNECTION_CHECKED_OUT_AT]?: number, [IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
80
76
  if (trackedConnection[CLOSED_CONNECTION])
81
77
  return;
82
78
  await this.rollbackLeftOpenTransaction(connection);
@@ -88,8 +84,25 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
88
84
  throw error;
89
85
  }
90
86
  trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT] = Date.now();
87
+ delete trackedConnection[CONNECTION_CHECKED_OUT_AT];
91
88
  this.connections.push(connection);
92
89
  await this.drainPendingCheckouts();
90
+ await this.handleCheckedInIdleConnection();
91
+ }
92
+ /**
93
+ * @param {import("../drivers/base.js").default} connection - Connection being checked in.
94
+ * @param {number | undefined} id - Connection checkout id.
95
+ * @returns {void}
96
+ */
97
+ untrackConnectionInUse(connection, id) {
98
+ if (typeof id !== "number") {
99
+ throw new Error(`idSeq on connection wasn't set? '${typeof id}' = ${id}`);
100
+ }
101
+ delete this.connectionsInUse[id];
102
+ connection.setIdSeq(undefined);
103
+ }
104
+ /** @returns {Promise<void>} - Resolves once idle reaping has been scheduled or run. */
105
+ async handleCheckedInIdleConnection() {
93
106
  if (this.idleTimeoutMillis() === 0) {
94
107
  await this.reapIdleConnections();
95
108
  }
@@ -155,8 +168,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
155
168
  if (connection.getIdSeq() !== undefined)
156
169
  throw new Error(`Connection already has an ID-seq - is it in use? ${connection.getIdSeq()}`);
157
170
  const id = this.idSeq++;
158
- const trackedConnection = /** @type {import("../drivers/base.js").default & {[IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
171
+ const trackedConnection = /** @type {import("../drivers/base.js").default & {[CONNECTION_CHECKED_OUT_AT]?: number, [IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
159
172
  delete trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
173
+ trackedConnection[CONNECTION_CHECKED_OUT_AT] = Date.now();
160
174
  connection.setIdSeq(id);
161
175
  this.connectionsInUse[id] = connection;
162
176
  try {
@@ -173,10 +187,17 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
173
187
  /** @returns {number | undefined} - Configured max live connections. */
174
188
  maxConnections() {
175
189
  const value = this.getConfiguration().pool?.max;
176
- if (typeof value === "number" && Number.isFinite(value) && value >= 1)
190
+ if (this.validMaxConnections(value))
177
191
  return value;
178
192
  return;
179
193
  }
194
+ /**
195
+ * @param {unknown} value - Candidate max connection count.
196
+ * @returns {value is number} - Whether the value is a valid max connection count.
197
+ */
198
+ validMaxConnections(value) {
199
+ return typeof value === "number" && Number.isFinite(value) && value >= 1;
200
+ }
180
201
  /** @returns {number} - Number of live and in-progress connections. */
181
202
  liveConnectionCount() {
182
203
  const connections = new Set([
@@ -220,7 +241,7 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
220
241
  */
221
242
  async waitForCheckout(databaseConfig, reuseKey, options = {}) {
222
243
  return await new Promise((resolve, reject) => {
223
- this.pendingCheckouts.push({ databaseConfig, options, reject, resolve, reuseKey });
244
+ this.pendingCheckouts.push({ databaseConfig, enqueuedAt: Date.now(), options, reject, resolve, reuseKey });
224
245
  void this.drainPendingCheckouts().catch((error) => {
225
246
  const checkoutError = error instanceof Error ? error : new Error("Failed to drain pending database connection checkouts.", { cause: error });
226
247
  this.rejectPendingCheckouts(checkoutError);
@@ -245,27 +266,52 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
245
266
  async drainPendingCheckoutsActual() {
246
267
  while (this.pendingCheckouts.length > 0) {
247
268
  const checkout = this.pendingCheckouts[0];
248
- let connection = this.takeIdleConnectionForReuseKey(checkout.reuseKey, { includeOpenTransactions: false });
249
- if (!connection) {
250
- await this.reapIdleConnections();
251
- connection = this.takeIdleConnectionForReuseKey(checkout.reuseKey, { includeOpenTransactions: false });
252
- }
253
- if (!connection && !this.canSpawnConnection()) {
254
- const closedConnection = await this.closeOneIdleConnectionForCapacity();
255
- if (closedConnection)
256
- continue;
257
- }
258
- if (!connection && this.canSpawnConnection()) {
269
+ if (await this.closeIdleConnectionForPendingCheckoutCapacity(checkout))
270
+ continue;
271
+ if (this.canSpawnConnection()) {
259
272
  this.pendingCheckouts.shift();
260
273
  await this.spawnAndResolvePendingCheckout(checkout);
261
274
  continue;
262
275
  }
276
+ const connection = await this.idleConnectionForPendingCheckout(checkout);
263
277
  if (!connection)
264
278
  return;
265
279
  this.pendingCheckouts.shift();
266
280
  await this.resolvePendingCheckout(checkout, connection);
267
281
  }
268
282
  }
283
+ /**
284
+ * @param {PendingCheckout} checkout - Checkout waiting for a connection.
285
+ * @returns {Promise<boolean>} - Whether an idle connection was closed to free capacity.
286
+ */
287
+ async closeIdleConnectionForPendingCheckoutCapacity(checkout) {
288
+ const connection = this.findIdleConnectionForReuseKey(checkout.reuseKey);
289
+ if (connection)
290
+ return false;
291
+ await this.reapIdleConnections();
292
+ if (this.findIdleConnectionForReuseKey(checkout.reuseKey))
293
+ return false;
294
+ return this.canSpawnConnection() ? false : await this.closeOneIdleConnectionForCapacity();
295
+ }
296
+ /**
297
+ * @param {string} reuseKey - Database configuration reuse key.
298
+ * @returns {import("../drivers/base.js").default | undefined} - Matching idle connection, if present.
299
+ */
300
+ findIdleConnectionForReuseKey(reuseKey) {
301
+ return this.connections.find((connection) => !this.connectionHasOpenTransaction(connection) && this.connectionMatchesReuseKey(connection, reuseKey));
302
+ }
303
+ /**
304
+ * @param {PendingCheckout} checkout - Checkout waiting for a connection.
305
+ * @returns {Promise<import("../drivers/base.js").default | undefined>} - Matching idle connection, if one can be reused.
306
+ */
307
+ async idleConnectionForPendingCheckout(checkout) {
308
+ let connection = this.takeIdleConnectionForReuseKey(checkout.reuseKey, { includeOpenTransactions: false });
309
+ if (connection)
310
+ return connection;
311
+ await this.reapIdleConnections();
312
+ connection = this.takeIdleConnectionForReuseKey(checkout.reuseKey, { includeOpenTransactions: false });
313
+ return connection;
314
+ }
269
315
  /**
270
316
  * @param {PendingCheckout} checkout - Checkout request to resolve.
271
317
  * @returns {Promise<void>} - Resolves when the checkout has been handled.
@@ -328,22 +374,31 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
328
374
  /** @returns {import("../drivers/base.js").default} - The current connection. */
329
375
  getCurrentConnection() {
330
376
  const id = this.asyncLocalStorage.getStore();
331
- if (id === undefined) {
332
- const fallbackConnection = this.getGlobalConnection();
333
- if (fallbackConnection) {
334
- return fallbackConnection;
335
- }
336
- throw new Error("ID hasn't been set for this async context");
337
- }
338
- if (!(id in this.connectionsInUse)) {
339
- throw new Error(`Connection ${id} doesn't exist any more - has it been checked in again?`);
340
- }
377
+ if (id === undefined)
378
+ return this.currentFallbackConnectionOrFail();
379
+ this.ensureConnectionIsInUse(id);
341
380
  const currentConnection = this.connectionsInUse[id];
342
381
  if (!currentConnection) {
343
382
  throw new Error(`Couldn't get current connection from that ID: ${id}`);
344
383
  }
345
384
  return currentConnection;
346
385
  }
386
+ /** @returns {import("../drivers/base.js").default} - Fallback connection, if present. */
387
+ currentFallbackConnectionOrFail() {
388
+ const fallbackConnection = this.getGlobalConnection();
389
+ if (fallbackConnection)
390
+ return fallbackConnection;
391
+ throw new Error("ID hasn't been set for this async context");
392
+ }
393
+ /**
394
+ * @param {number} id - Checked-out connection id.
395
+ * @returns {void}
396
+ */
397
+ ensureConnectionIsInUse(id) {
398
+ if (!(id in this.connectionsInUse)) {
399
+ throw new Error(`Connection ${id} doesn't exist any more - has it been checked in again?`);
400
+ }
401
+ }
347
402
  /**
348
403
  * Registers a fallback connection for this pool identifier that will be used when no async context is available.
349
404
  * @param {import("../drivers/base.js").default} connection - Connection.
@@ -399,13 +454,49 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
399
454
  /** @returns {import("./base.js").DatabasePoolDebugSnapshot} - Diagnostic snapshot for this pool. */
400
455
  getDebugSnapshot() {
401
456
  const snapshot = super.getDebugSnapshot();
457
+ const now = Date.now();
458
+ const { connections } = this.debugConnectionSnapshots(now);
459
+ return {
460
+ ...snapshot,
461
+ connections,
462
+ connectionsBeingSpawned: this.connectionsBeingSpawned,
463
+ idleCount: this.connections.length,
464
+ inUseCount: Object.keys(this.connectionsInUse).length,
465
+ pendingCheckouts: this.pendingCheckoutDebugSnapshots(now),
466
+ pendingCheckoutCount: this.pendingCheckouts.length
467
+ };
468
+ }
469
+ /**
470
+ * @param {number} now - Current timestamp.
471
+ * @returns {{connections: Array<Record<string, unknown>>, seenConnections: Set<import("../drivers/base.js").default>}} - Connection snapshots and seen set.
472
+ */
473
+ debugConnectionSnapshots(now) {
474
+ /** @type {Array<Record<string, unknown>>} */
402
475
  const connections = [];
403
476
  const seenConnections = new Set();
404
- const now = Date.now();
477
+ this.addInUseDebugConnectionSnapshots({ connections, now, seenConnections });
478
+ this.addIdleDebugConnectionSnapshots({ connections, now, seenConnections });
479
+ this.addFallbackDebugConnectionSnapshots({ connections, seenConnections });
480
+ return { connections, seenConnections };
481
+ }
482
+ /**
483
+ * @param {{connections: Array<Record<string, unknown>>, now: number, seenConnections: Set<import("../drivers/base.js").default>}} args - Snapshot collection state.
484
+ * @returns {void}
485
+ */
486
+ addInUseDebugConnectionSnapshots({ connections, now, seenConnections }) {
405
487
  for (const [id, connection] of Object.entries(this.connectionsInUse)) {
488
+ const trackedConnection = /** @type {import("../drivers/base.js").default & {[CONNECTION_CHECKED_OUT_AT]?: number}} */ (connection);
489
+ const checkedOutAt = trackedConnection[CONNECTION_CHECKED_OUT_AT];
490
+ const checkedOutForMs = typeof checkedOutAt === "number" ? Math.max(0, now - checkedOutAt) : undefined;
406
491
  seenConnections.add(connection);
407
- connections.push(this.debugConnectionSnapshot(connection, { checkoutId: id, state: "in-use" }));
492
+ connections.push(this.debugConnectionSnapshot(connection, { checkedOutAt, checkedOutForMs, checkoutId: id, state: "in-use" }));
408
493
  }
494
+ }
495
+ /**
496
+ * @param {{connections: Array<Record<string, unknown>>, now: number, seenConnections: Set<import("../drivers/base.js").default>}} args - Snapshot collection state.
497
+ * @returns {void}
498
+ */
499
+ addIdleDebugConnectionSnapshots({ connections, now, seenConnections }) {
409
500
  for (const connection of this.connections) {
410
501
  if (seenConnections.has(connection))
411
502
  continue;
@@ -413,24 +504,39 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
413
504
  const trackedConnection = /** @type {import("../drivers/base.js").default & {[IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
414
505
  const checkedInAt = trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
415
506
  const idleForMs = typeof checkedInAt === "number" ? Math.max(0, now - checkedInAt) : undefined;
416
- connections.push(this.debugConnectionSnapshot(connection, { idleForMs, state: "idle" }));
507
+ connections.push(this.debugConnectionSnapshot(connection, { checkedInAt, idleForMs, state: "idle" }));
417
508
  }
418
- const globalConnection = this.getGlobalConnectionForIdentifier();
419
- if (globalConnection && !seenConnections.has(globalConnection)) {
420
- seenConnections.add(globalConnection);
421
- connections.push(this.debugConnectionSnapshot(globalConnection, { state: "global" }));
422
- }
423
- if (this._testSharedConnection && !seenConnections.has(this._testSharedConnection)) {
424
- connections.push(this.debugConnectionSnapshot(this._testSharedConnection, { state: "test-shared" }));
425
- }
426
- return {
427
- ...snapshot,
428
- connections,
429
- connectionsBeingSpawned: this.connectionsBeingSpawned,
430
- idleCount: this.connections.length,
431
- inUseCount: Object.keys(this.connectionsInUse).length,
432
- pendingCheckoutCount: this.pendingCheckouts.length
433
- };
509
+ }
510
+ /**
511
+ * @param {{connections: Array<Record<string, unknown>>, seenConnections: Set<import("../drivers/base.js").default>}} args - Snapshot collection state.
512
+ * @returns {void}
513
+ */
514
+ addFallbackDebugConnectionSnapshots({ connections, seenConnections }) {
515
+ this.addDebugConnectionSnapshotIfUnseen({ connection: this.getGlobalConnectionForIdentifier(), connections, seenConnections, state: "global" });
516
+ this.addDebugConnectionSnapshotIfUnseen({ connection: this._testSharedConnection, connections, seenConnections, state: "test-shared" });
517
+ }
518
+ /**
519
+ * @param {{connection: import("../drivers/base.js").default | undefined, connections: Array<Record<string, unknown>>, seenConnections: Set<import("../drivers/base.js").default>, state: string}} args - Snapshot collection state.
520
+ * @returns {void}
521
+ */
522
+ addDebugConnectionSnapshotIfUnseen({ connection, connections, seenConnections, state }) {
523
+ if (!connection || seenConnections.has(connection))
524
+ return;
525
+ seenConnections.add(connection);
526
+ connections.push(this.debugConnectionSnapshot(connection, { state }));
527
+ }
528
+ /**
529
+ * @param {number} now - Current timestamp.
530
+ * @returns {Array<Record<string, unknown>>} - Pending checkout snapshots.
531
+ */
532
+ pendingCheckoutDebugSnapshots(now) {
533
+ return this.pendingCheckouts.map((checkout, index) => ({
534
+ checkoutName: checkout.options.name,
535
+ enqueuedAt: checkout.enqueuedAt,
536
+ index,
537
+ reuseKey: checkout.reuseKey,
538
+ waitingForMs: Math.max(0, now - checkout.enqueuedAt)
539
+ }));
434
540
  }
435
541
  /**
436
542
  * @returns {import("../drivers/base.js").default | undefined} - The global connection.
@@ -480,20 +586,24 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
480
586
  const value = this.getConfiguration().pool?.idleTimeoutMillis;
481
587
  if (value === null)
482
588
  return null;
483
- if (typeof value === "number" && Number.isFinite(value) && value >= 0)
589
+ if (this.validIdleTimeoutMillis(value))
484
590
  return value;
485
591
  return DEFAULT_IDLE_TIMEOUT_MILLIS;
486
592
  }
593
+ /**
594
+ * @param {unknown} value - Candidate idle timeout value.
595
+ * @returns {value is number} - Whether the value is a valid idle timeout.
596
+ */
597
+ validIdleTimeoutMillis(value) {
598
+ return typeof value === "number" && Number.isFinite(value) && value >= 0;
599
+ }
487
600
  /** @returns {void} */
488
601
  scheduleIdleConnectionReaper() {
489
602
  if (this.idleConnectionReaperTimer)
490
603
  return;
491
- if (this.connections.length === 0)
492
- return;
493
- const idleTimeoutMillis = this.idleTimeoutMillis();
494
- if (idleTimeoutMillis === null)
604
+ if (!this.hasIdleConnectionsToReap())
495
605
  return;
496
- const delay = this.nextIdleConnectionReapDelay(idleTimeoutMillis);
606
+ const delay = this.nextIdleConnectionReapDelay(/** @type {number} */ (this.idleTimeoutMillis()));
497
607
  this.idleConnectionReaperTimer = setTimeout(() => {
498
608
  this.idleConnectionReaperTimer = undefined;
499
609
  void this.reapIdleConnections().catch((error) => {
@@ -504,6 +614,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
504
614
  this.idleConnectionReaperTimer.unref();
505
615
  }
506
616
  }
617
+ /** @returns {boolean} - Whether an idle reaper timer should be scheduled. */
618
+ hasIdleConnectionsToReap() {
619
+ return this.connections.length > 0 && this.idleTimeoutMillis() !== null;
620
+ }
507
621
  /**
508
622
  * @param {number} idleTimeoutMillis - Idle timeout in milliseconds.
509
623
  * @returns {number} - Delay before the next reap.
@@ -532,43 +646,72 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
532
646
  const idleTimeoutMillis = this.idleTimeoutMillis();
533
647
  if (idleTimeoutMillis === null)
534
648
  return;
535
- const now = Date.now();
536
- /** @type {import("../drivers/base.js").default[]} */
537
- const keptConnections = [];
538
- /** @type {import("../drivers/base.js").default[]} */
539
- const expiredConnections = [];
540
- for (const connection of this.connections) {
541
- const trackedConnection = /** @type {import("../drivers/base.js").default & {[CLOSED_CONNECTION]?: boolean, [IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
542
- if (trackedConnection[CLOSED_CONNECTION])
543
- continue;
544
- if (this.connectionHasOpenTransaction(connection)) {
545
- keptConnections.push(connection);
546
- continue;
547
- }
548
- const checkedInAt = trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
549
- const expired = typeof checkedInAt === "number" && now - checkedInAt >= idleTimeoutMillis;
550
- if (expired) {
551
- expiredConnections.push(connection);
552
- }
553
- else {
554
- keptConnections.push(connection);
555
- }
556
- }
649
+ const { expiredConnections, keptConnections } = this.classifyIdleConnectionsForReaping({ idleTimeoutMillis, now: Date.now() });
557
650
  this.connections = keptConnections;
651
+ await this.closeExpiredIdleConnections(expiredConnections);
652
+ await this.awaitInflightConnectionCloses();
653
+ if (this.connections.length > 0)
654
+ this.scheduleIdleConnectionReaper();
655
+ }
656
+ /**
657
+ * @param {import("../drivers/base.js").default[]} expiredConnections - Connections to close.
658
+ * @returns {Promise<void>} - Resolves when closed.
659
+ */
660
+ async closeExpiredIdleConnections(expiredConnections) {
558
661
  for (const connection of expiredConnections) {
559
662
  await this.closeConnection(connection);
560
663
  }
561
- // A concurrent fire-and-forget scheduled reap may already be closing
562
- // connections this call did not expire itself (it may have removed them from
563
- // `this.connections` first). Await those in-flight closes too so a caller
564
- // that awaits `reapIdleConnections()` is guaranteed the pool's idle
565
- // connections are fully closed, not mid-`close()`.
664
+ }
665
+ /** @returns {Promise<void>} - Resolves once in-flight connection closes settle. */
666
+ async awaitInflightConnectionCloses() {
566
667
  if (this.inflightConnectionCloses.size > 0) {
567
668
  await Promise.allSettled([...this.inflightConnectionCloses]);
568
669
  }
569
- if (this.connections.length > 0) {
570
- this.scheduleIdleConnectionReaper();
670
+ }
671
+ /**
672
+ * @param {{idleTimeoutMillis: number, now: number}} args - Reaper classification inputs.
673
+ * @returns {{expiredConnections: import("../drivers/base.js").default[], keptConnections: import("../drivers/base.js").default[]}} - Classified idle connections.
674
+ */
675
+ classifyIdleConnectionsForReaping({ idleTimeoutMillis, now }) {
676
+ /** @type {import("../drivers/base.js").default[]} */
677
+ const keptConnections = [];
678
+ /** @type {import("../drivers/base.js").default[]} */
679
+ const expiredConnections = [];
680
+ for (const connection of this.connections) {
681
+ this.classifyIdleConnectionForReaping({ connection, expiredConnections, idleTimeoutMillis, keptConnections, now });
571
682
  }
683
+ return { expiredConnections, keptConnections };
684
+ }
685
+ /**
686
+ * @param {{connection: import("../drivers/base.js").default, expiredConnections: import("../drivers/base.js").default[], idleTimeoutMillis: number, keptConnections: import("../drivers/base.js").default[], now: number}} args - Classification state.
687
+ * @returns {void}
688
+ */
689
+ classifyIdleConnectionForReaping({ connection, expiredConnections, idleTimeoutMillis, keptConnections, now }) {
690
+ if (this.connectionIsClosed(connection))
691
+ return;
692
+ if (this.connectionHasOpenTransaction(connection)) {
693
+ keptConnections.push(connection);
694
+ return;
695
+ }
696
+ const target = this.idleConnectionExpired({ connection, idleTimeoutMillis, now }) ? expiredConnections : keptConnections;
697
+ target.push(connection);
698
+ }
699
+ /**
700
+ * @param {import("../drivers/base.js").default} connection - Connection to inspect.
701
+ * @returns {boolean} - Whether the connection is marked closed.
702
+ */
703
+ connectionIsClosed(connection) {
704
+ const trackedConnection = /** @type {import("../drivers/base.js").default & {[CLOSED_CONNECTION]?: boolean}} */ (connection);
705
+ return Boolean(trackedConnection[CLOSED_CONNECTION]);
706
+ }
707
+ /**
708
+ * @param {{connection: import("../drivers/base.js").default, idleTimeoutMillis: number, now: number}} args - Expiry inputs.
709
+ * @returns {boolean} - Whether the idle connection expired.
710
+ */
711
+ idleConnectionExpired({ connection, idleTimeoutMillis, now }) {
712
+ const trackedConnection = /** @type {import("../drivers/base.js").default & {[IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
713
+ const checkedInAt = trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
714
+ return typeof checkedInAt === "number" && now - checkedInAt >= idleTimeoutMillis;
572
715
  }
573
716
  /**
574
717
  * @param {import("../drivers/base.js").default} connection - Connection to inspect.
@@ -607,8 +750,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
607
750
  if (existingClose) {
608
751
  return await existingClose;
609
752
  }
610
- const trackedConnection = /** @type {import("../drivers/base.js").default & {[CLOSED_CONNECTION]?: boolean, [IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
753
+ const trackedConnection = /** @type {import("../drivers/base.js").default & {[CLOSED_CONNECTION]?: boolean, [CONNECTION_CHECKED_OUT_AT]?: number, [IDLE_CONNECTION_CHECKED_IN_AT]?: number}} */ (connection);
611
754
  trackedConnection[CLOSED_CONNECTION] = true;
755
+ delete trackedConnection[CONNECTION_CHECKED_OUT_AT];
612
756
  delete trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
613
757
  const closePromise = (async () => {
614
758
  await trackedConnection.close();
@@ -670,10 +814,6 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
670
814
  * @returns {void} - No return value.
671
815
  */
672
816
  static setGlobalConnections(connections, configuration) {
673
- if (!connections && !configuration) {
674
- this.globalConnections = new WeakMap();
675
- return;
676
- }
677
817
  if (!configuration) {
678
818
  this.globalConnections = new WeakMap();
679
819
  return;
@@ -693,4 +833,4 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
693
833
  this.globalConnections.delete(configuration);
694
834
  }
695
835
  }
696
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RhdGFiYXNlL3Bvb2wvYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDN0MsT0FBTyxRQUFRLEVBQUUsRUFBQyxzQkFBc0IsRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUUxRCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtBQUNwRSxNQUFNLDZCQUE2QixHQUFHLE1BQU0sQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFBO0FBQ2xGLE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxDQUFBO0FBRXhDOzs7Ozs7O0dBT0c7QUFFSCxNQUFNLENBQUMsT0FBTyxPQUFPLGdEQUFpRCxTQUFRLFFBQVE7SUFDcEY7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLGlCQUFpQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7SUFFeEMsaUJBQWlCLEdBQUcsSUFBSSxpQkFBaUIsRUFBRSxDQUFBO0lBRTNDOzs7OztPQUtHO0lBQ0gscUJBQXFCLEdBQUcsU0FBUyxDQUFBO0lBRWpDLHFEQUFxRDtJQUNyRCxXQUFXLEdBQUcsRUFBRSxDQUFBO0lBRWhCLG1FQUFtRTtJQUNuRSxnQkFBZ0IsR0FBRyxFQUFFLENBQUE7SUFFckIsZ0NBQWdDO0lBQ2hDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQTtJQUVyQixxQkFBcUI7SUFDckIsdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO0lBRTNCLHdDQUF3QztJQUN4QywyQkFBMkIsR0FBRyxTQUFTLENBQUE7SUFFdkMsd0RBQXdEO0lBQ3hELHlCQUF5QixHQUFHLFNBQVMsQ0FBQTtJQUVyQzs7Ozs7Ozs7T0FRRztJQUNILHdCQUF3QixHQUFH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Q0FBQztJQUVILENBQUM7SUFFRDs7O09BR0c7SUFDSCxzQkFBc0IsQ0FBQyxLQUFLO1FBQzFCLE1BQU0sZ0JBQWdCLEdBQUcsSUFBSSxDQUFDLGdCQUFnQixDQUFBO1FBRTlDLElBQUksQ0FBQyxnQkFBZ0IsR0FBRyxFQUFFLENBQUE7UUFFMUIsS0FBSyxNQUFNLFFBQVEsSUFBSSxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3hDLFFBQVEsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDeEIsQ0FBQztJQUNILENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxXQUFXLEVBQUUsYUFBYTtRQUNwRCxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDbkMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7WUFDdEMsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7WUFDdEMsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsR0FBRyxDQUFDLGFBQWEsRUFBRSxXQUFXLElBQUksRUFBRSxDQUFDLENBQUE7SUFDOUQsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsc0JBQXNCLENBQUMsYUFBYTtRQUN6QyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDbkIsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7WUFDdEMsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFBO0lBQzlDLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IHtBc3luY0xvY2FsU3RvcmFnZX0gZnJvbSBcImFzeW5jX2hvb2tzXCJcbmltcG9ydCBCYXNlUG9vbCwge1BPT0xfQ09ORklHVVJBVElPTl9LRVl9IGZyb20gXCIuL2Jhc2UuanNcIlxuXG5leHBvcnQgY29uc3QgQ0xPU0VEX0NPTk5FQ1RJT04gPSBTeW1ib2woXCJ2ZWxvY2lvdXNDbG9zZWRDb25uZWN0aW9uXCIpXG5jb25zdCBJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVCA9IFN5bWJvbChcInZlbG9jaW91c0lkbGVDb25uZWN0aW9uQ2hlY2tlZEluQXRcIilcbmNvbnN0IERFRkFVTFRfSURMRV9USU1FT1VUX01JTExJUyA9IDUwMDBcblxuLyoqXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBQZW5kaW5nQ2hlY2tvdXRcbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSBkYXRhYmFzZUNvbmZpZyAtIFJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZ3VyYXRpb24gbmVlZGVkIGJ5IHRoZSBjaGVja291dC5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IG9wdGlvbnMgLSBDaGVja291dCBvcHRpb25zLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHJldXNlS2V5IC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiByZXVzZSBrZXkgbmVlZGVkIGJ5IHRoZSBjaGVja291dC5cbiAqIEBwcm9wZXJ0eSB7KGNvbm5lY3Rpb246IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0KSA9PiB2b2lkfSByZXNvbHZlIC0gUmVzb2x2ZXMgd2l0aCBhbiBhY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAqIEBwcm9wZXJ0eSB7KGVycm9yOiBFcnJvcikgPT4gdm9pZH0gcmVqZWN0IC0gUmVqZWN0cyB3aGVuIGNoZWNrb3V0IGNhbm5vdCBjb21wbGV0ZS5cbiAqL1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb24gZXh0ZW5kcyBCYXNlUG9vbCB7XG4gIC8qKlxuICAgKiBHbG9iYWwgZmFsbGJhY2sgY29ubmVjdGlvbnMga2V5ZWQgYnkgY29uZmlndXJhdGlvbiBpbnN0YW5jZSBhbmQgcG9vbCBpZGVudGlmaWVyLlxuICAgKiBAdHlwZSB7V2Vha01hcDxpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHQsIFJlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pj59XG4gICAqL1xuICBzdGF0aWMgZ2xvYmFsQ29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpXG5cbiAgYXN5bmNMb2NhbFN0b3JhZ2UgPSBuZXcgQXN5bmNMb2NhbFN0b3JhZ2UoKVxuXG4gIC8qKlxuICAgKiBXaGVuIHNldCwgcmV0dXJuZWQgYnkgZ2V0Q3VycmVudENvbnRleHRDb25uZWN0aW9uIHdoZW4gbm8gYXN5bmMgY29udGV4dCBleGlzdHMuXG4gICAqIFVzZWQgYnkgdGhlIHRlc3QgcnVubmVyIHRvIHNoYXJlIGEgY29ubmVjdGlvbiBiZXR3ZWVuIHRlc3QgY29kZSBhbmQgSFRUUCBoYW5kbGVyc1xuICAgKiBydW5uaW5nIGluIHRoZSBzYW1lIHByb2Nlc3MgKGluLXByb2Nlc3MgdGVzdCBzZXJ2ZXIgbW9kZSkuXG4gICAqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH1cbiAgICovXG4gIF90ZXN0U2hhcmVkQ29ubmVjdGlvbiA9IHVuZGVmaW5lZFxuXG4gIC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHRbXX0gKi9cbiAgY29ubmVjdGlvbnMgPSBbXVxuXG4gIC8qKiBAdHlwZSB7UmVjb3JkPG51bWJlciwgaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSAqL1xuICBjb25uZWN0aW9uc0luVXNlID0ge31cblxuICAvKiogQHR5cGUge1BlbmRpbmdDaGVja291dFtdfSAqL1xuICBwZW5kaW5nQ2hlY2tvdXRzID0gW11cblxuICAvKiogQHR5cGUge251bWJlcn0gKi9cbiAgY29ubmVjdGlvbnNCZWluZ1NwYXduZWQgPSAwXG5cbiAgLyoqIEB0eXBlIHtQcm9taXNlPHZvaWQ+IHwgdW5kZWZpbmVkfSAqL1xuICBwZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UgPSB1bmRlZmluZWRcblxuICAvKiogQHR5cGUge1JldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkfSAqL1xuICBpZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyID0gdW5kZWZpbmVkXG5cbiAgLyoqXG4gICAqIEluLWZsaWdodCBjb25uZWN0aW9uLWNsb3NlIHByb21pc2VzLiBUaGUgaWRsZSByZWFwZXIgaXMgYXJtZWQgb24gY2hlY2staW5cbiAgICogYW5kIHJ1bnMgZmlyZS1hbmQtZm9yZ2V0IHdoZW4gaXRzIHRpbWVyIGZpcmVzLCBzbyBhIHNjaGVkdWxlZCByZWFwIGNhbiBiZVxuICAgKiBjbG9zaW5nIGEgY29ubmVjdGlvbiB3aGlsZSBhbiBleHBsaWNpdCBgcmVhcElkbGVDb25uZWN0aW9ucygpYCAob3JcbiAgICogYGNsZWFySWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lcigpYCkgcnVucy4gVHJhY2tpbmcgdGhlIGluLWZsaWdodCBjbG9zZXMgbGV0c1xuICAgKiB0aG9zZSBjYWxsZXJzIGF3YWl0IHRoZW0sIHNvIG9uY2UgYSByZWFwIHJlc29sdmVzIHRoZSBjb25uZWN0aW9ucyBpdFxuICAgKiBleHBpcmVkIGFyZSBmdWxseSBjbG9zZWQgaW5zdGVhZCBvZiBoYWxmLWNsb3NlZCBtaWQtYGNsb3NlKClgLlxuICAgKiBAdHlwZSB7U2V0PFByb21pc2U8dm9pZD4+fVxuICAgKi9cbiAgaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzID0gbmV3IFNldCgpXG5cbiAgLyoqXG4gICAqIEluLWZsaWdodCBjbG9zZSBwcm9taXNlIHBlciBjb25uZWN0aW9uLCBzbyBjb25jdXJyZW50IGNsb3NlcyBvZiB0aGUgc2FtZVxuICAgKiBjb25uZWN0aW9uIGF3YWl0IHRoZSBzYW1lIGNsb3NlIHJhdGhlciB0aGFuIGNsb3NpbmcgdGhlIGRyaXZlciBoYW5kbGUgdHdpY2UuXG4gICAqIEB0eXBlIHtXZWFrTWFwPG9iamVjdCwgUHJvbWlzZTx2b2lkPj59XG4gICAqL1xuICBjb25uZWN0aW9uQ2xvc2VQcm9taXNlcyA9IG5ldyBXZWFrTWFwKClcblxuICBpZFNlcSA9IDBcblxuICAvKipcbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBPcHRpb25zIG9iamVjdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IGFyZ3MuY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBhcmdzLmlkZW50aWZpZXIgLSBJZGVudGlmaWVyLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2NvbmZpZ3VyYXRpb24sIGlkZW50aWZpZXJ9KSB7XG4gICAgc3VwZXIoe2NvbmZpZ3VyYXRpb24sIGlkZW50aWZpZXJ9KVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBEYXRhYmFzZSBjb25uZWN0aW9uIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHRoZSBjb25uZWN0aW9uIGlzIGNoZWNrZWQgaW4gb3IgY2xvc2VkLlxuICAgKi9cbiAgYXN5bmMgY2hlY2tpbihjb25uZWN0aW9uKSB7XG4gICAgY29uc3QgaWQgPSBjb25uZWN0aW9uLmdldElkU2VxKClcblxuICAgIGlmICh0eXBlb2YgaWQgIT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgaWRTZXEgb24gY29ubmVjdGlvbiB3YXNuJ3Qgc2V0PyAnJHt0eXBlb2YgaWR9JyA9ICR7aWR9YClcbiAgICB9XG5cbiAgICBpZiAoaWQgaW4gdGhpcy5jb25uZWN0aW9uc0luVXNlKSB7XG4gICAgICBkZWxldGUgdGhpcy5jb25uZWN0aW9uc0luVXNlW2lkXVxuICAgIH1cblxuICAgIGNvbm5lY3Rpb24uc2V0SWRTZXEodW5kZWZpbmVkKVxuXG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tDTE9TRURfQ09OTkVDVElPTl0/OiBib29sZWFuLCBbSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICBpZiAodHJhY2tlZENvbm5lY3Rpb25bQ0xPU0VEX0NPTk5FQ1RJT05dKSByZXR1cm5cblxuICAgIGF3YWl0IHRoaXMucm9sbGJhY2tMZWZ0T3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5jbGVhckNvbm5lY3Rpb25DaGVja291dE5hbWUoKVxuICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICBhd2FpdCB0aGlzLmNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgICB0aHJvdyBlcnJvclxuICAgIH1cblxuICAgIHRyYWNrZWRDb25uZWN0aW9uW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXSA9IERhdGUubm93KClcbiAgICB0aGlzLmNvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbilcbiAgICBhd2FpdCB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0cygpXG5cbiAgICBpZiAodGhpcy5pZGxlVGltZW91dE1pbGxpcygpID09PSAwKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjaGVkdWxlSWRsZUNvbm5lY3Rpb25SZWFwZXIoKVxuICAgIH1cblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IFtvcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjaGVja291dC5cbiAgICovXG4gIGFzeW5jIGNoZWNrb3V0KG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlnID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCByZXVzZUtleSA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvblJldXNlS2V5KClcbiAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkocmV1c2VLZXkpXG5cbiAgICBpZiAoY29ubmVjdGlvbikgcmV0dXJuIGF3YWl0IHRoaXMuYWN0aXZhdGVDb25uZWN0aW9uKGNvbm5lY3Rpb24sIG9wdGlvbnMpXG5cbiAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KHJldXNlS2V5KVxuXG4gICAgaWYgKGNvbm5lY3Rpb24pIHJldHVybiBhd2FpdCB0aGlzLmFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uLCBvcHRpb25zKVxuXG4gICAgaWYgKHRoaXMuY2FuU3Bhd25Db25uZWN0aW9uKCkpIHtcbiAgICAgIC8vIFNwYXduIHZpYSBzcGF3bkNvbm5lY3Rpb24oKSBzbyB0aGUgdGVuYW50LWF3YXJlIGNvbmZpZ3VyYXRpb24gaXMgcmVzb2x2ZWQgRlJFU0ggYXRcbiAgICAgIC8vIHNwYXduIHRpbWUgZm9yIHRoZSBjdXJyZW50IGNhbGxlci4gUmV1c2luZyB0aGUgZGF0YWJhc2VDb25maWcgY2FwdHVyZWQgYXQgdGhlIHRvcCBvZlxuICAgICAgLy8gY2hlY2tvdXQoKSBjb3VsZCBiaW5kIHRoZSBjb25uZWN0aW9uIHRvIGEgc3RhbGUgdGVuYW50L2RhdGFiYXNlLCB3aGljaCBicmVha3NcbiAgICAgIC8vIHBlci1yZXF1ZXN0IGlzb2xhdGlvbiAoZS5nLiB0ZXN0IHRydW5jYXRpb24gYXBwZWFyaW5nIG5vdCB0byB0YWtlIGVmZmVjdCkuIFRoZSBxdWV1ZWRcbiAgICAgIC8vIHBhdGggYmVsb3cga2VlcHMgdGhlIHdhaXRpbmcgY2FsbGVyJ3MgY2FwdHVyZWQgY29uZmlnIHZpYSB3YWl0Rm9yQ2hlY2tvdXQoKS5cbiAgICAgIGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLnNwYXduQ29ubmVjdGlvbkZvckNoZWNrb3V0KHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLCB0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpKVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgb3B0aW9ucylcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy53YWl0Rm9yQ2hlY2tvdXQoZGF0YWJhc2VDb25maWcsIHJldXNlS2V5LCBvcHRpb25zKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5pbmNsdWRlT3BlblRyYW5zYWN0aW9uc10gLSBXaGV0aGVyIGNvbm5lY3Rpb25zIHdpdGggb3BlbiB0cmFuc2FjdGlvbnMgbWF5IGJlIHJldHVybmVkLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gTWF0Y2hpbmcgaWRsZSBjb25uZWN0aW9uLlxuICAgKi9cbiAgdGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkocmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9ucyA9IHRydWV9ID0ge30pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uSW5kZXggPSB0aGlzLmNvbm5lY3Rpb25zLmZpbmRJbmRleCgocXVldWVkQ29ubmVjdGlvbikgPT4ge1xuICAgICAgaWYgKCFpbmNsdWRlT3BlblRyYW5zYWN0aW9ucyAmJiB0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24ocXVldWVkQ29ubmVjdGlvbikpIHJldHVybiBmYWxzZVxuXG4gICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uTWF0Y2hlc1JldXNlS2V5KHF1ZXVlZENvbm5lY3Rpb24sIHJldXNlS2V5KVxuICAgIH0pXG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25JbmRleCA9PT0gLTEgPyB1bmRlZmluZWQgOiB0aGlzLmNvbm5lY3Rpb25zLnNwbGljZShjb25uZWN0aW9uSW5kZXgsIDEpWzBdXG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgY29ubmVjdGlvbiBtYXRjaGVzIHRoZSByZXVzZSBrZXkuXG4gICAqL1xuICBjb25uZWN0aW9uTWF0Y2hlc1JldXNlS2V5KGNvbm5lY3Rpb24sIHJldXNlS2V5KSB7XG4gICAgY29uc3QgY29ubmVjdGlvbldpdGhQb29sS2V5ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0/OiBzdHJpbmd9fSAqLyAoY29ubmVjdGlvbilcblxuICAgIHJldHVybiBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0gPT09IHJldXNlS2V5XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IFtvcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBBY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAoY29ubmVjdGlvbi5nZXRJZFNlcSgpICE9PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiBhbHJlYWR5IGhhcyBhbiBJRC1zZXEgLSBpcyBpdCBpbiB1c2U/ICR7Y29ubmVjdGlvbi5nZXRJZFNlcSgpfWApXG5cbiAgICBjb25zdCBpZCA9IHRoaXMuaWRTZXErK1xuXG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICBkZWxldGUgdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG5cbiAgICBjb25uZWN0aW9uLnNldElkU2VxKGlkKVxuICAgIHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF0gPSBjb25uZWN0aW9uXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5zZXRDb25uZWN0aW9uQ2hlY2tvdXROYW1lKG9wdGlvbnMubmFtZSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF1cbiAgICAgIGNvbm5lY3Rpb24uc2V0SWRTZXEodW5kZWZpbmVkKVxuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbilcblxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtudW1iZXIgfCB1bmRlZmluZWR9IC0gQ29uZmlndXJlZCBtYXggbGl2ZSBjb25uZWN0aW9ucy4gKi9cbiAgbWF4Q29ubmVjdGlvbnMoKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5wb29sPy5tYXhcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+PSAxKSByZXR1cm4gdmFsdWVcblxuICAgIHJldHVyblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtudW1iZXJ9IC0gTnVtYmVyIG9mIGxpdmUgYW5kIGluLXByb2dyZXNzIGNvbm5lY3Rpb25zLiAqL1xuICBsaXZlQ29ubmVjdGlvbkNvdW50KCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldChbXG4gICAgICAuLi50aGlzLmNvbm5lY3Rpb25zLFxuICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpLFxuICAgICAgdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpXG4gICAgXS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICByZXR1cm4gY29ubmVjdGlvbnMuc2l6ZSArIHRoaXMuY29ubmVjdGlvbnNCZWluZ1NwYXduZWRcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGEgbmV3IGNvbm5lY3Rpb24gY2FuIGJlIHNwYXduZWQuICovXG4gIGNhblNwYXduQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBtYXhDb25uZWN0aW9ucyA9IHRoaXMubWF4Q29ubmVjdGlvbnMoKVxuXG4gICAgcmV0dXJuIG1heENvbm5lY3Rpb25zID09PSB1bmRlZmluZWQgfHwgdGhpcy5saXZlQ29ubmVjdGlvbkNvdW50KCkgPCBtYXhDb25uZWN0aW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSBkYXRhYmFzZUNvbmZpZyAtIFJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZyBmb3IgdGhlIGNoZWNrb3V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleSBmb3IgdGhlIGNoZWNrb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gU3Bhd25lZCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25Db25uZWN0aW9uRm9yQ2hlY2tvdXQoZGF0YWJhc2VDb25maWcsIHJldXNlS2V5KSB7XG4gICAgdGhpcy5jb25uZWN0aW9uc0JlaW5nU3Bhd25lZCsrXG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuc3Bhd25Db25uZWN0aW9uV2l0aENvbmZpZ3VyYXRpb24oZGF0YWJhc2VDb25maWcpXG4gICAgICBjb25zdCBjb25uZWN0aW9uV2l0aFBvb2xLZXkgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tQT09MX0NPTkZJR1VSQVRJT05fS0VZXT86IHN0cmluZ319ICovIChjb25uZWN0aW9uKVxuXG4gICAgICBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0gPSByZXVzZUtleVxuICAgICAgY29ubmVjdGlvbi5zZXRTY2hlbWFDYWNoZUludmFsaWRhdG9yKCgpID0+IHtcbiAgICAgICAgdGhpcy5jbGVhclNjaGVtYUNhY2hlKClcbiAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLmNsZWFyU2NoZW1hQ2FjaGVzRm9yUmV1c2VLZXkocmV1c2VLZXkpXG4gICAgICB9KVxuXG4gICAgICByZXR1cm4gY29ubmVjdGlvblxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkLS1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGRhdGFiYXNlQ29uZmlnIC0gUmVzb2x2ZWQgZGF0YWJhc2UgY29uZmlnIGZvciB0aGUgY2hlY2tvdXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5Db25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zfSBbb3B0aW9uc10gLSBDaGVja291dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gUmVzb2x2ZXMgd2l0aCBhbiBhY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIHdhaXRGb3JDaGVja291dChkYXRhYmFzZUNvbmZpZywgcmV1c2VLZXksIG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdDaGVja291dHMucHVzaCh7ZGF0YWJhc2VDb25maWcsIG9wdGlvbnMsIHJlamVjdCwgcmVzb2x2ZSwgcmV1c2VLZXl9KVxuICAgICAgdm9pZCB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0cygpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zdCBjaGVja291dEVycm9yID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFwiRmFpbGVkIHRvIGRyYWluIHBlbmRpbmcgZGF0YWJhc2UgY29ubmVjdGlvbiBjaGVja291dHMuXCIsIHtjYXVzZTogZXJyb3J9KVxuXG4gICAgICAgIHRoaXMucmVqZWN0UGVuZGluZ0NoZWNrb3V0cyhjaGVja291dEVycm9yKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gcGVuZGluZyBjaGVja291dHMgaGF2ZSBiZWVuIGRyYWluZWQgYXMgZmFyIGFzIHBvc3NpYmxlLiAqL1xuICBhc3luYyBkcmFpblBlbmRpbmdDaGVja291dHMoKSB7XG4gICAgaWYgKHRoaXMucGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlKSB7XG4gICAgICBhd2FpdCB0aGlzLnBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UgPSB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0c0FjdHVhbCgpXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2VcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UgPSB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBwZW5kaW5nIGNoZWNrb3V0cyBoYXZlIGJlZW4gZHJhaW5lZCBhcyBmYXIgYXMgcG9zc2libGUuICovXG4gIGFzeW5jIGRyYWluUGVuZGluZ0NoZWNrb3V0c0FjdHVhbCgpIHtcbiAgICB3aGlsZSAodGhpcy5wZW5kaW5nQ2hlY2tvdXRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGNoZWNrb3V0ID0gdGhpcy5wZW5kaW5nQ2hlY2tvdXRzWzBdXG4gICAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9uczogZmFsc2V9KVxuXG4gICAgICBpZiAoIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWFwSWRsZUNvbm5lY3Rpb25zKClcbiAgICAgICAgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9uczogZmFsc2V9KVxuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbm5lY3Rpb24gJiYgIXRoaXMuY2FuU3Bhd25Db25uZWN0aW9uKCkpIHtcbiAgICAgICAgY29uc3QgY2xvc2VkQ29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuY2xvc2VPbmVJZGxlQ29ubmVjdGlvbkZvckNhcGFjaXR5KClcblxuICAgICAgICBpZiAoY2xvc2VkQ29ubmVjdGlvbikgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKCFjb25uZWN0aW9uICYmIHRoaXMuY2FuU3Bhd25Db25uZWN0aW9uKCkpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXRzLnNoaWZ0KClcbiAgICAgICAgYXdhaXQgdGhpcy5zcGF3bkFuZFJlc29sdmVQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQpXG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKCFjb25uZWN0aW9uKSByZXR1cm5cblxuICAgICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXRzLnNoaWZ0KClcbiAgICAgIGF3YWl0IHRoaXMucmVzb2x2ZVBlbmRpbmdDaGVja291dChjaGVja291dCwgY29ubmVjdGlvbilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtQZW5kaW5nQ2hlY2tvdXR9IGNoZWNrb3V0IC0gQ2hlY2tvdXQgcmVxdWVzdCB0byByZXNvbHZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHRoZSBjaGVja291dCBoYXMgYmVlbiBoYW5kbGVkLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25BbmRSZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0KSB7XG4gICAgbGV0IGNvbm5lY3Rpb25cblxuICAgIHRyeSB7XG4gICAgICBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25Gb3JDaGVja291dChjaGVja291dC5kYXRhYmFzZUNvbmZpZywgY2hlY2tvdXQucmV1c2VLZXkpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gc3Bhd24gZGF0YWJhc2UgY29ubmVjdGlvbi5cIiwge2NhdXNlOiBlcnJvcn0pKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UGVuZGluZ0NoZWNrb3V0fSBjaGVja291dCAtIENoZWNrb3V0IHJlcXVlc3QgdG8gcmVzb2x2ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gYWN0aXZhdGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNoZWNrb3V0IGhhcyBiZWVuIGhhbmRsZWQuXG4gICAqL1xuICBhc3luYyByZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNoZWNrb3V0LnJlc29sdmUoYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgY2hlY2tvdXQub3B0aW9ucykpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gYWN0aXZhdGUgZGF0YWJhc2UgY29ubmVjdGlvbi5cIiwge2NhdXNlOiBlcnJvcn0pKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIGFuIGlkbGUgY29ubmVjdGlvbiB3YXMgY2xvc2VkIHRvIGZyZWUgY2FwYWNpdHkuICovXG4gIGFzeW5jIGNsb3NlT25lSWRsZUNvbm5lY3Rpb25Gb3JDYXBhY2l0eSgpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5jb25uZWN0aW9ucy5maW5kKChjYW5kaWRhdGUpID0+ICF0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY2FuZGlkYXRlKSlcblxuICAgIGlmICghY29ubmVjdGlvbikgcmV0dXJuIGZhbHNlXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gdGhpcy5jb25uZWN0aW9ucy5maWx0ZXIoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlICE9PSBjb25uZWN0aW9uKVxuICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnMgfCBmdW5jdGlvbihpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgOiBQcm9taXNlPFQ+fSBvcHRpb25zT3JDYWxsYmFjayAtIENoZWNrb3V0IG9wdGlvbnMgb3IgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggdGhlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpIDogUHJvbWlzZTxUPn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIHRvIGludm9rZSB3aXRoIHRoZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoQ29ubmVjdGlvbihvcHRpb25zT3JDYWxsYmFjaywgY2FsbGJhY2spIHtcbiAgICBjb25zdCBvcHRpb25zID0gdHlwZW9mIG9wdGlvbnNPckNhbGxiYWNrID09IFwiZnVuY3Rpb25cIiA/IHt9IDogb3B0aW9uc09yQ2FsbGJhY2tcbiAgICBjb25zdCBhY3R1YWxDYWxsYmFjayA9IHR5cGVvZiBvcHRpb25zT3JDYWxsYmFjayA9PSBcImZ1bmN0aW9uXCIgPyBvcHRpb25zT3JDYWxsYmFjayA6IGNhbGxiYWNrXG5cbiAgICBpZiAoIWFjdHVhbENhbGxiYWNrKSB0aHJvdyBuZXcgRXJyb3IoXCJ3aXRoQ29ubmVjdGlvbiByZXF1aXJlcyBhIGNhbGxiYWNrXCIpXG5cbiAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5jaGVja291dChvcHRpb25zKVxuICAgIGNvbnN0IGlkID0gY29ubmVjdGlvbi5nZXRJZFNlcSgpXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oaWQsIGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBhY3R1YWxDYWxsYmFjayhjb25uZWN0aW9uKVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja2luKGNvbm5lY3Rpb24pXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IC0gVGhlIGN1cnJlbnQgY29ubmVjdGlvbi4gICovXG4gIGdldEN1cnJlbnRDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGlkID0gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5nZXRTdG9yZSgpXG5cbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZmFsbGJhY2tDb25uZWN0aW9uID0gdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uKClcblxuICAgICAgaWYgKGZhbGxiYWNrQ29ubmVjdGlvbikge1xuICAgICAgICByZXR1cm4gZmFsbGJhY2tDb25uZWN0aW9uXG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcIklEIGhhc24ndCBiZWVuIHNldCBmb3IgdGhpcyBhc3luYyBjb250ZXh0XCIpXG4gICAgfVxuXG4gICAgaWYgKCEoaWQgaW4gdGhpcy5jb25uZWN0aW9uc0luVXNlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb25uZWN0aW9uICR7aWR9IGRvZXNuJ3QgZXhpc3QgYW55IG1vcmUgLSBoYXMgaXQgYmVlbiBjaGVja2VkIGluIGFnYWluP2ApXG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudENvbm5lY3Rpb24gPSB0aGlzLmNvbm5lY3Rpb25zSW5Vc2VbaWRdXG5cbiAgICBpZiAoIWN1cnJlbnRDb25uZWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkbid0IGdldCBjdXJyZW50IGNvbm5lY3Rpb24gZnJvbSB0aGF0IElEOiAke2lkfWApXG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRDb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgZmFsbGJhY2sgY29ubmVjdGlvbiBmb3IgdGhpcyBwb29sIGlkZW50aWZpZXIgdGhhdCB3aWxsIGJlIHVzZWQgd2hlbiBubyBhc3luYyBjb250ZXh0IGlzIGF2YWlsYWJsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHNldEdsb2JhbENvbm5lY3Rpb24oY29ubmVjdGlvbikge1xuICAgIGNvbnN0IGtsYXNzID0gLyoqIEB0eXBlIHt0eXBlb2YgVmVsb2Npb3VzRGF0YWJhc2VQb29sQXN5bmNUcmFja2VkTXVsdGlDb25uZWN0aW9ufSAqLyAodGhpcy5jb25zdHJ1Y3RvcilcbiAgICBsZXQgbWFwRm9yQ29uZmlndXJhdGlvbiA9IGtsYXNzLmdsb2JhbENvbm5lY3Rpb25zLmdldCh0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICBpZiAoIW1hcEZvckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIG1hcEZvckNvbmZpZ3VyYXRpb24gPSB7fVxuICAgICAga2xhc3MuZ2xvYmFsQ29ubmVjdGlvbnMuc2V0KHRoaXMuY29uZmlndXJhdGlvbiwgbWFwRm9yQ29uZmlndXJhdGlvbilcbiAgICB9XG5cbiAgICBtYXBGb3JDb25maWd1cmF0aW9uW3RoaXMuaWRlbnRpZmllcl0gPSBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyBhIGdsb2JhbCBmYWxsYmFjayBjb25uZWN0aW9uIGV4aXN0cyBmb3IgdGhpcyBwb29sIGlkZW50aWZpZXIgYW5kIHJldHVybnMgaXQuXG4gICAqIElmIG9uZSBpcyBhbHJlYWR5IHNldCwgaXQgaXMgcmV0dXJuZWQgYW5kIGFsc28gbWFkZSBhdmFpbGFibGUgaW4gdGhlIHBvb2wgcXVldWUuXG4gICAqIE90aGVyd2lzZSBhIG5ldyBjb25uZWN0aW9uIGlzIHNwYXduZWQsIHJlZ2lzdGVyZWQsIGFuZCBxdWV1ZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBnbG9iYWwgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGVuc3VyZUdsb2JhbENvbm5lY3Rpb24oKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb24oKVxuXG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3RpbmdcblxuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLnNwYXduQ29ubmVjdGlvbigpXG5cbiAgICB0aGlzLnNldEdsb2JhbENvbm5lY3Rpb24oY29ubmVjdGlvbilcblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogU2V0IGEgc2hhcmVkIGNvbm5lY3Rpb24gZm9yIHRlc3QgbW9kZSBzbyB0aGF0IEhUVFAgaGFuZGxlcnMgcnVubmluZ1xuICAgKiBpbiB0aGUgc2FtZSBwcm9jZXNzIGNhbiByZXVzZSB0aGUgdGVzdCBydW5uZXIncyBkYXRhYmFzZSBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gU2hhcmVkIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc2V0VGVzdFNoYXJlZENvbm5lY3Rpb24oY29ubmVjdGlvbikge1xuICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHt2b2lkfSAqL1xuICBjbGVhclRlc3RTaGFyZWRDb25uZWN0aW9uKCkge1xuICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29ubmVjdGlvbiB0aWVkIHRvIHRoZSBjdXJyZW50IGFzeW5jIGNvbnRleHQsIGlmIGFueS5cbiAgICogRmFsbHMgYmFjayB0byB0aGUgdGVzdCBzaGFyZWQgY29ubmVjdGlvbiB3aGVuIG5vIGFzeW5jIGNvbnRleHQgZXhpc3RzLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGN1cnJlbnQgY29udGV4dCBjb25uZWN0aW9uLlxuICAgKi9cbiAgZ2V0Q3VycmVudENvbnRleHRDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGlkID0gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5nZXRTdG9yZSgpXG5cbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uXG5cbiAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50Q29ubmVjdGlvbigpXG4gIH1cblxuICAvKiogQHJldHVybnMge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5EYXRhYmFzZVBvb2xEZWJ1Z1NuYXBzaG90fSAtIERpYWdub3N0aWMgc25hcHNob3QgZm9yIHRoaXMgcG9vbC4gKi9cbiAgZ2V0RGVidWdTbmFwc2hvdCgpIHtcbiAgICBjb25zdCBzbmFwc2hvdCA9IHN1cGVyLmdldERlYnVnU25hcHNob3QoKVxuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gW11cbiAgICBjb25zdCBzZWVuQ29ubmVjdGlvbnMgPSBuZXcgU2V0KClcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpXG5cbiAgICBmb3IgKGNvbnN0IFtpZCwgY29ubmVjdGlvbl0gb2YgT2JqZWN0LmVudHJpZXModGhpcy5jb25uZWN0aW9uc0luVXNlKSkge1xuICAgICAgc2VlbkNvbm5lY3Rpb25zLmFkZChjb25uZWN0aW9uKVxuICAgICAgY29ubmVjdGlvbnMucHVzaCh0aGlzLmRlYnVnQ29ubmVjdGlvblNuYXBzaG90KGNvbm5lY3Rpb24sIHtjaGVja291dElkOiBpZCwgc3RhdGU6IFwiaW4tdXNlXCJ9KSlcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgdGhpcy5jb25uZWN0aW9ucykge1xuICAgICAgaWYgKHNlZW5Db25uZWN0aW9ucy5oYXMoY29ubmVjdGlvbikpIGNvbnRpbnVlXG5cbiAgICAgIHNlZW5Db25uZWN0aW9ucy5hZGQoY29ubmVjdGlvbilcblxuICAgICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICAgIGNvbnN0IGNoZWNrZWRJbkF0ID0gdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG4gICAgICBjb25zdCBpZGxlRm9yTXMgPSB0eXBlb2YgY2hlY2tlZEluQXQgPT09IFwibnVtYmVyXCIgPyBNYXRoLm1heCgwLCBub3cgLSBjaGVja2VkSW5BdCkgOiB1bmRlZmluZWRcblxuICAgICAgY29ubmVjdGlvbnMucHVzaCh0aGlzLmRlYnVnQ29ubmVjdGlvblNuYXBzaG90KGNvbm5lY3Rpb24sIHtpZGxlRm9yTXMsIHN0YXRlOiBcImlkbGVcIn0pKVxuICAgIH1cblxuICAgIGNvbnN0IGdsb2JhbENvbm5lY3Rpb24gPSB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb25Gb3JJZGVudGlmaWVyKClcblxuICAgIGlmIChnbG9iYWxDb25uZWN0aW9uICYmICFzZWVuQ29ubmVjdGlvbnMuaGFzKGdsb2JhbENvbm5lY3Rpb24pKSB7XG4gICAgICBzZWVuQ29ubmVjdGlvbnMuYWRkKGdsb2JhbENvbm5lY3Rpb24pXG4gICAgICBjb25uZWN0aW9ucy5wdXNoKHRoaXMuZGVidWdDb25uZWN0aW9uU25hcHNob3QoZ2xvYmFsQ29ubmVjdGlvbiwge3N0YXRlOiBcImdsb2JhbFwifSkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uICYmICFzZWVuQ29ubmVjdGlvbnMuaGFzKHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uKSkge1xuICAgICAgY29ubmVjdGlvbnMucHVzaCh0aGlzLmRlYnVnQ29ubmVjdGlvblNuYXBzaG90KHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uLCB7c3RhdGU6IFwidGVzdC1zaGFyZWRcIn0pKVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICAuLi5zbmFwc2hvdCxcbiAgICAgIGNvbm5lY3Rpb25zLFxuICAgICAgY29ubmVjdGlvbnNCZWluZ1NwYXduZWQ6IHRoaXMuY29ubmVjdGlvbnNCZWluZ1NwYXduZWQsXG4gICAgICBpZGxlQ291bnQ6IHRoaXMuY29ubmVjdGlvbnMubGVuZ3RoLFxuICAgICAgaW5Vc2VDb3VudDogT2JqZWN0LmtleXModGhpcy5jb25uZWN0aW9uc0luVXNlKS5sZW5ndGgsXG4gICAgICBwZW5kaW5nQ2hlY2tvdXRDb3VudDogdGhpcy5wZW5kaW5nQ2hlY2tvdXRzLmxlbmd0aFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGdsb2JhbCBjb25uZWN0aW9uLlxuICAgKi9cbiAgZ2V0R2xvYmFsQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpXG5cbiAgICBpZiAoIWNvbm5lY3Rpb24pIHJldHVyblxuICAgIGlmICghdGhpcy5jb25uZWN0aW9uTWF0Y2hlc0N1cnJlbnRDb25maWd1cmF0aW9uKGNvbm5lY3Rpb24pKSByZXR1cm5cblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSAtIFRoZSBnbG9iYWwgY29ubmVjdGlvbiBmb3IgdGhpcyBwb29sIGlkZW50aWZpZXIuXG4gICAqL1xuICBnZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpIHtcbiAgICBjb25zdCBrbGFzcyA9IC8qKiBAdHlwZSB7dHlwZW9mIFZlbG9jaW91c0RhdGFiYXNlUG9vbEFzeW5jVHJhY2tlZE11bHRpQ29ubmVjdGlvbn0gKi8gKHRoaXMuY29uc3RydWN0b3IpXG4gICAgY29uc3QgbWFwRm9yQ29uZmlndXJhdGlvbiA9IGtsYXNzLmdsb2JhbENvbm5lY3Rpb25zLmdldCh0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICByZXR1cm4gbWFwRm9yQ29uZmlndXJhdGlvbj8uW3RoaXMuaWRlbnRpZmllcl1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuICovXG4gIGNsZWFyR2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKSB7XG4gICAgY29uc3Qga2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb259ICovICh0aGlzLmNvbnN0cnVjdG9yKVxuICAgIGNvbnN0IG1hcEZvckNvbmZpZ3VyYXRpb24gPSBrbGFzcy5nbG9iYWxDb25uZWN0aW9ucy5nZXQodGhpcy5jb25maWd1cmF0aW9uKVxuXG4gICAgaWYgKCFtYXBGb3JDb25maWd1cmF0aW9uKSByZXR1cm5cblxuICAgIGRlbGV0ZSBtYXBGb3JDb25maWd1cmF0aW9uW3RoaXMuaWRlbnRpZmllcl1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgc2NoZW1hIG1ldGFkYXRhIGNhY2hlZCBieSBldmVyeSBsaXZlIGNvbm5lY3Rpb24gb3duZWQgYnkgdGhpcyBwb29sLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBjbGVhclNjaGVtYUNhY2hlKCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldChbXG4gICAgICAuLi50aGlzLmNvbm5lY3Rpb25zLFxuICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpLFxuICAgICAgdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uKCksXG4gICAgICB0aGlzLl90ZXN0U2hhcmVkQ29ubmVjdGlvblxuICAgIF0uZmlsdGVyKEJvb2xlYW4pKVxuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICBpZiAoY29ubmVjdGlvbikgdGhpcy5fY2xlYXJDb25uZWN0aW9uU2NoZW1hQ2FjaGUoY29ubmVjdGlvbilcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge251bWJlciB8IG51bGx9IC0gSWRsZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcywgb3IgbnVsbCB3aGVuIGRpc2FibGVkLiAqL1xuICBpZGxlVGltZW91dE1pbGxpcygpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLnBvb2w/LmlkbGVUaW1lb3V0TWlsbGlzXG5cbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHJldHVybiBudWxsXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpICYmIHZhbHVlID49IDApIHJldHVybiB2YWx1ZVxuXG4gICAgcmV0dXJuIERFRkFVTFRfSURMRV9USU1FT1VUX01JTExJU1xuICB9XG5cbiAgLyoqIEByZXR1cm5zIHt2b2lkfSAqL1xuICBzY2hlZHVsZUlkbGVDb25uZWN0aW9uUmVhcGVyKCkge1xuICAgIGlmICh0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIpIHJldHVyblxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBjb25zdCBpZGxlVGltZW91dE1pbGxpcyA9IHRoaXMuaWRsZVRpbWVvdXRNaWxsaXMoKVxuXG4gICAgaWYgKGlkbGVUaW1lb3V0TWlsbGlzID09PSBudWxsKSByZXR1cm5cblxuICAgIGNvbnN0IGRlbGF5ID0gdGhpcy5uZXh0SWRsZUNvbm5lY3Rpb25SZWFwRGVsYXkoaWRsZVRpbWVvdXRNaWxsaXMpXG5cbiAgICB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lciA9IHVuZGVmaW5lZFxuICAgICAgdm9pZCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIud2FybigoKSA9PiBbXCJGYWlsZWQgdG8gcmVhcCBpZGxlIGRhdGFiYXNlIGNvbm5lY3Rpb25zOlwiLCBlcnJvcl0pXG4gICAgICB9KVxuICAgIH0sIGRlbGF5KVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIudW5yZWYgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyLnVucmVmKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGlkbGVUaW1lb3V0TWlsbGlzIC0gSWRsZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcy5cbiAgICogQHJldHVybnMge251bWJlcn0gLSBEZWxheSBiZWZvcmUgdGhlIG5leHQgcmVhcC5cbiAgICovXG4gIG5leHRJZGxlQ29ubmVjdGlvblJlYXBEZWxheShpZGxlVGltZW91dE1pbGxpcykge1xuICAgIGxldCBkZWxheSA9IGlkbGVUaW1lb3V0TWlsbGlzXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIHRoaXMuY29ubmVjdGlvbnMpIHtcbiAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG4gICAgICBjb25zdCBjaGVja2VkSW5BdCA9IHRyYWNrZWRDb25uZWN0aW9uW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXVxuXG4gICAgICBpZiAodHlwZW9mIGNoZWNrZWRJbkF0ICE9PSBcIm51bWJlclwiKSBjb250aW51ZVxuXG4gICAgICBkZWxheSA9IE1hdGgubWluKGRlbGF5LCBNYXRoLm1heCgwLCBpZGxlVGltZW91dE1pbGxpcyAtIChub3cgLSBjaGVja2VkSW5BdCkpKVxuICAgIH1cblxuICAgIHJldHVybiBkZWxheVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyBpZGxlIGNoZWNrZWQtaW4gY29ubmVjdGlvbnMgdGhhdCBoYXZlIGV4Y2VlZGVkIHRoZSBjb25maWd1cmVkIHRpbWVvdXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyByZWFwSWRsZUNvbm5lY3Rpb25zKCkge1xuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBjb25zdCBpZGxlVGltZW91dE1pbGxpcyA9IHRoaXMuaWRsZVRpbWVvdXRNaWxsaXMoKVxuXG4gICAgaWYgKGlkbGVUaW1lb3V0TWlsbGlzID09PSBudWxsKSByZXR1cm5cblxuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KClcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W119ICovXG4gICAgY29uc3Qga2VwdENvbm5lY3Rpb25zID0gW11cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W119ICovXG4gICAgY29uc3QgZXhwaXJlZENvbm5lY3Rpb25zID0gW11cblxuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiB0aGlzLmNvbm5lY3Rpb25zKSB7XG4gICAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0NMT1NFRF9DT05ORUNUSU9OXT86IGJvb2xlYW4sIFtJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcblxuICAgICAgaWYgKHRyYWNrZWRDb25uZWN0aW9uW0NMT1NFRF9DT05ORUNUSU9OXSkgY29udGludWVcbiAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIHtcbiAgICAgICAga2VwdENvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbilcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hlY2tlZEluQXQgPSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cbiAgICAgIGNvbnN0IGV4cGlyZWQgPSB0eXBlb2YgY2hlY2tlZEluQXQgPT09IFwibnVtYmVyXCIgJiYgbm93IC0gY2hlY2tlZEluQXQgPj0gaWRsZVRpbWVvdXRNaWxsaXNcblxuICAgICAgaWYgKGV4cGlyZWQpIHtcbiAgICAgICAgZXhwaXJlZENvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGtlcHRDb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IGtlcHRDb25uZWN0aW9uc1xuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGV4cGlyZWRDb25uZWN0aW9ucykge1xuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbilcbiAgICB9XG5cbiAgICAvLyBBIGNvbmN1cnJlbnQgZmlyZS1hbmQtZm9yZ2V0IHNjaGVkdWxlZCByZWFwIG1heSBhbHJlYWR5IGJlIGNsb3NpbmdcbiAgICAvLyBjb25uZWN0aW9ucyB0aGlzIGNhbGwgZGlkIG5vdCBleHBpcmUgaXRzZWxmIChpdCBtYXkgaGF2ZSByZW1vdmVkIHRoZW0gZnJvbVxuICAgIC8vIGB0aGlzLmNvbm5lY3Rpb25zYCBmaXJzdCkuIEF3YWl0IHRob3NlIGluLWZsaWdodCBjbG9zZXMgdG9vIHNvIGEgY2FsbGVyXG4gICAgLy8gdGhhdCBhd2FpdHMgYHJlYXBJZGxlQ29ubmVjdGlvbnMoKWAgaXMgZ3VhcmFudGVlZCB0aGUgcG9vbCdzIGlkbGVcbiAgICAvLyBjb25uZWN0aW9ucyBhcmUgZnVsbHkgY2xvc2VkLCBub3QgbWlkLWBjbG9zZSgpYC5cbiAgICBpZiAodGhpcy5pbmZsaWdodENvbm5lY3Rpb25DbG9zZXMuc2l6ZSA+IDApIHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbLi4udGhpcy5pbmZsaWdodENvbm5lY3Rpb25DbG9zZXNdKVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2NoZWR1bGVJZGxlQ29ubmVjdGlvblJlYXBlcigpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIGNvbm5lY3Rpb24gaGFzIGFuIG9wZW4gdHJhbnNhY3Rpb24uXG4gICAqL1xuICBjb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICByZXR1cm4gY29ubmVjdGlvbi5fdHJhbnNhY3Rpb25zQ291bnQgPiAwXG4gIH1cblxuICAvKipcbiAgICogUm9sbHMgYmFjayBhbnkgdHJhbnNhY3Rpb24gYSBwcmV2aW91cyBob2xkZXIgbGVmdCBvcGVuIGJlZm9yZSBhIGNvbm5lY3Rpb25cbiAgICogcmUtZW50ZXJzIHRoZSBpZGxlIHBvb2wuIEEgY29ubmVjdGlvbiByZXR1cm5lZCB0byB0aGUgcG9vbCB3aXRoIGFuIG9wZW5cbiAgICogdHJhbnNhY3Rpb24gd291bGQgb3RoZXJ3aXNlIGJlIGhhbmRlZCB0byBhbiB1bnJlbGF0ZWQgY2hlY2tvdXQsIHdob3NlXG4gICAqIHN0YXJ0VHJhbnNhY3Rpb24oKSB0aGVuIGZhaWxzIHdpdGggXCJBIHRyYW5zYWN0aW9uIGlzIGFscmVhZHkgcnVubmluZ1wiIGFuZFxuICAgKiBwb2lzb25zIGV2ZXJ5IGZvbGxvd2luZyBjYWxsZXIgdGhhdCByZXVzZXMgaXQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIGJlaW5nIGNoZWNrZWQgaW4uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNvbm5lY3Rpb24gaG9sZHMgbm8gb3BlbiB0cmFuc2FjdGlvbi5cbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrTGVmdE9wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgaWYgKCF0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIHJldHVyblxuXG4gICAgdGhpcy5sb2dnZXIud2FybigoKSA9PiBbYFJvbGxpbmcgYmFjayBhIHRyYW5zYWN0aW9uIGxlZnQgb3BlbiBvbiBhIGNvbm5lY3Rpb24gYmVpbmcgY2hlY2tlZCBpbiAoaWRlbnRpZmllcj0ke3RoaXMuaWRlbnRpZmllcn0pLmBdKVxuXG4gICAgd2hpbGUgKHRoaXMuY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5yb2xsYmFja1RyYW5zYWN0aW9uKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gY2xvc2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbikge1xuICAgIC8vIElkZW1wb3RlbnQ6IGEgZmlyZS1hbmQtZm9yZ2V0IHNjaGVkdWxlZCByZWFwIGFuZCBhbiBleHBsaWNpdCByZWFwIGNhbiBib3RoXG4gICAgLy8gdGFyZ2V0IHRoZSBzYW1lIGNvbm5lY3Rpb24uIEF3YWl0IHRoZSBpbi1mbGlnaHQgY2xvc2UgaW5zdGVhZCBvZiBjbG9zaW5nXG4gICAgLy8gdHdpY2UgKHdoaWNoIGNhbiB0aHJvdyBvbiB0aGUgZHJpdmVyKSBvciByZXR1cm5pbmcgd2hpbGUgdGhlIHVuZGVybHlpbmdcbiAgICAvLyBoYW5kbGUgaXMgc3RpbGwgb3Blbi5cbiAgICBjb25zdCBleGlzdGluZ0Nsb3NlID0gdGhpcy5jb25uZWN0aW9uQ2xvc2VQcm9taXNlcy5nZXQoY29ubmVjdGlvbilcblxuICAgIGlmIChleGlzdGluZ0Nsb3NlKSB7XG4gICAgICByZXR1cm4gYXdhaXQgZXhpc3RpbmdDbG9zZVxuICAgIH1cblxuICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbQ0xPU0VEX0NPTk5FQ1RJT05dPzogYm9vbGVhbiwgW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuXG4gICAgdHJhY2tlZENvbm5lY3Rpb25bQ0xPU0VEX0NPTk5FQ1RJT05dID0gdHJ1ZVxuICAgIGRlbGV0ZSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cblxuICAgIGNvbnN0IGNsb3NlUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0cmFja2VkQ29ubmVjdGlvbi5jbG9zZSgpXG4gICAgfSkoKVxuXG4gICAgdGhpcy5jb25uZWN0aW9uQ2xvc2VQcm9taXNlcy5zZXQoY29ubmVjdGlvbiwgY2xvc2VQcm9taXNlKVxuICAgIHRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzLmFkZChjbG9zZVByb21pc2UpXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY2xvc2VQcm9taXNlXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzLmRlbGV0ZShjbG9zZVByb21pc2UpXG4gICAgfVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHt2b2lkfSAqL1xuICBjbGVhcklkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIoKSB7XG4gICAgaWYgKCF0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIpIHJldHVyblxuXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lcilcbiAgICB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgYWxsIGFjdGl2ZSBhbmQgY2FjaGVkIGNvbm5lY3Rpb25zIGZvciB0aGlzIHBvb2wuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjbG9zZUFsbCgpIHtcbiAgICB0aGlzLmNsZWFySWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lcigpXG4gICAgdGhpcy5yZWplY3RQZW5kaW5nQ2hlY2tvdXRzKG5ldyBFcnJvcihcIkRhdGFiYXNlIHBvb2wgd2FzIGNsb3NlZCBiZWZvcmUgY2hlY2tvdXQgY29tcGxldGVkLlwiKSlcblxuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldChbXG4gICAgICAuLi50aGlzLmNvbm5lY3Rpb25zLFxuICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpLFxuICAgICAgdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpLFxuICAgICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb25cbiAgICBdLmZpbHRlcihCb29sZWFuKSlcblxuICAgIHRoaXMuY29ubmVjdGlvbnMgPSBbXVxuICAgIHRoaXMuY29ubmVjdGlvbnNJblVzZSA9IHt9XG4gICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24gPSB1bmRlZmluZWRcbiAgICB0aGlzLmNsZWFyR2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKVxuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICBpZiAoIWNvbm5lY3Rpb24pIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG4gICAgfVxuXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFcnJvcn0gZXJyb3IgLSBFcnJvciB0byByZWplY3QgcGVuZGluZyBjaGVja291dHMgd2l0aC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZWplY3RQZW5kaW5nQ2hlY2tvdXRzKGVycm9yKSB7XG4gICAgY29uc3QgcGVuZGluZ0NoZWNrb3V0cyA9IHRoaXMucGVuZGluZ0NoZWNrb3V0c1xuXG4gICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXRzID0gW11cblxuICAgIGZvciAoY29uc3QgY2hlY2tvdXQgb2YgcGVuZGluZ0NoZWNrb3V0cykge1xuICAgICAgY2hlY2tvdXQucmVqZWN0KGVycm9yKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhbGwgZ2xvYmFsbHkgcmVnaXN0ZXJlZCBmYWxsYmFjayBjb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IFtjb25uZWN0aW9uc10gLSBDb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IFtjb25maWd1cmF0aW9uXSAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHN0YXRpYyBzZXRHbG9iYWxDb25uZWN0aW9ucyhjb25uZWN0aW9ucywgY29uZmlndXJhdGlvbikge1xuICAgIGlmICghY29ubmVjdGlvbnMgJiYgIWNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmdsb2JhbENvbm5lY3Rpb25zLnNldChjb25maWd1cmF0aW9uLCBjb25uZWN0aW9ucyB8fCB7fSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgZ2xvYmFsbHkgcmVnaXN0ZXJlZCBmYWxsYmFjayBjb25uZWN0aW9ucyBmb3IgYWxsIGNvbmZpZ3VyYXRpb25zIG9yIGEgc2luZ2xlIGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBbY29uZmlndXJhdGlvbl0gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzdGF0aWMgY2xlYXJHbG9iYWxDb25uZWN0aW9ucyhjb25maWd1cmF0aW9uKSB7XG4gICAgaWYgKCFjb25maWd1cmF0aW9uKSB7XG4gICAgICB0aGlzLmdsb2JhbENvbm5lY3Rpb25zID0gbmV3IFdlYWtNYXAoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5nbG9iYWxDb25uZWN0aW9ucy5kZWxldGUoY29uZmlndXJhdGlvbilcbiAgfVxufVxuIl19
836
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RhdGFiYXNlL3Bvb2wvYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDN0MsT0FBTyxRQUFRLEVBQUUsRUFBQyxzQkFBc0IsRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUUxRCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtBQUNwRSxNQUFNLDZCQUE2QixHQUFHLE1BQU0sQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFBO0FBQ2xGLE1BQU0seUJBQXlCLEdBQUcsTUFBTSxDQUFDLGlDQUFpQyxDQUFDLENBQUE7QUFDM0UsTUFBTSwyQkFBMkIsR0FBRyxJQUFJLENBQUE7QUFFeEM7Ozs7Ozs7O0dBUUc7QUFFSCxNQUFNLENBQUMsT0FBTyxPQUFPLGdEQUFpRCxTQUFRLFFBQVE7SUFDcEY7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLGlCQUFpQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7SUFFeEMsaUJBQWlCLEdBQUcsSUFBSSxpQkFBaUIsRUFBRSxDQUFBO0lBRTNDOzs7OztPQUtHO0lBQ0gscUJBQXFCLEdBQUcsU0FBUyxDQUFBO0lBRWpDLHFEQUFxRDtJQUNyRCxXQUFXLEdBQUcsRUFBRSxDQUFBO0lBRWhCLG1FQUFtRTtJQUNuRSxnQkFBZ0IsR0FBRyxFQUFFLENBQUE7SUFFckIsZ0NBQWdDO0lBQ2hDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQTtJQUVyQixxQkFBcUI7SUFDckIsdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO0lBRTNCLHdDQUF3QztJQUN4QywyQkFBMkIsR0FBRyxTQUFTLENBQUE7SUFFdkMsd0RBQXdEO0lBQ3hELHlCQUF5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SUFDSCxNQUFNLENBQUMsb0JBQW9CLENBQUMsV0FBVyxFQUFFLGFBQWE7UUFDcEQsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFBO1lBQ3RDLE9BQU07UUFDUixDQUFDO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxhQUFhLEVBQUUsV0FBVyxJQUFJLEVBQUUsQ0FBQyxDQUFBO0lBQzlELENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsTUFBTSxDQUFDLHNCQUFzQixDQUFDLGFBQWE7UUFDekMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFBO1lBQ3RDLE9BQU07UUFDUixDQUFDO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7QXN5bmNMb2NhbFN0b3JhZ2V9IGZyb20gXCJhc3luY19ob29rc1wiXG5pbXBvcnQgQmFzZVBvb2wsIHtQT09MX0NPTkZJR1VSQVRJT05fS0VZfSBmcm9tIFwiLi9iYXNlLmpzXCJcblxuZXhwb3J0IGNvbnN0IENMT1NFRF9DT05ORUNUSU9OID0gU3ltYm9sKFwidmVsb2Npb3VzQ2xvc2VkQ29ubmVjdGlvblwiKVxuY29uc3QgSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVQgPSBTeW1ib2woXCJ2ZWxvY2lvdXNJZGxlQ29ubmVjdGlvbkNoZWNrZWRJbkF0XCIpXG5jb25zdCBDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUID0gU3ltYm9sKFwidmVsb2Npb3VzQ29ubmVjdGlvbkNoZWNrZWRPdXRBdFwiKVxuY29uc3QgREVGQVVMVF9JRExFX1RJTUVPVVRfTUlMTElTID0gNTAwMFxuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFBlbmRpbmdDaGVja291dFxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGRhdGFiYXNlQ29uZmlnIC0gUmVzb2x2ZWQgZGF0YWJhc2UgY29uZmlndXJhdGlvbiBuZWVkZWQgYnkgdGhlIGNoZWNrb3V0LlxuICogQHByb3BlcnR5IHtudW1iZXJ9IGVucXVldWVkQXQgLSBUaW1lc3RhbXAgd2hlbiB0aGUgY2hlY2tvdXQgc3RhcnRlZCB3YWl0aW5nLlxuICogQHByb3BlcnR5IHtpbXBvcnQoXCIuL2Jhc2UuanNcIikuQ29ubmVjdGlvbkNoZWNrb3V0T3B0aW9uc30gb3B0aW9ucyAtIENoZWNrb3V0IG9wdGlvbnMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleSBuZWVkZWQgYnkgdGhlIGNoZWNrb3V0LlxuICogQHByb3BlcnR5IHsoY29ubmVjdGlvbjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpID0+IHZvaWR9IHJlc29sdmUgLSBSZXNvbHZlcyB3aXRoIGFuIGFjdGl2YXRlZCBjb25uZWN0aW9uLlxuICogQHByb3BlcnR5IHsoZXJyb3I6IEVycm9yKSA9PiB2b2lkfSByZWplY3QgLSBSZWplY3RzIHdoZW4gY2hlY2tvdXQgY2Fubm90IGNvbXBsZXRlLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0RhdGFiYXNlUG9vbEFzeW5jVHJhY2tlZE11bHRpQ29ubmVjdGlvbiBleHRlbmRzIEJhc2VQb29sIHtcbiAgLyoqXG4gICAqIEdsb2JhbCBmYWxsYmFjayBjb25uZWN0aW9ucyBrZXllZCBieSBjb25maWd1cmF0aW9uIGluc3RhbmNlIGFuZCBwb29sIGlkZW50aWZpZXIuXG4gICAqIEB0eXBlIHtXZWFrTWFwPGltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdCwgUmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+Pn1cbiAgICovXG4gIHN0YXRpYyBnbG9iYWxDb25uZWN0aW9ucyA9IG5ldyBXZWFrTWFwKClcblxuICBhc3luY0xvY2FsU3RvcmFnZSA9IG5ldyBBc3luY0xvY2FsU3RvcmFnZSgpXG5cbiAgLyoqXG4gICAqIFdoZW4gc2V0LCByZXR1cm5lZCBieSBnZXRDdXJyZW50Q29udGV4dENvbm5lY3Rpb24gd2hlbiBubyBhc3luYyBjb250ZXh0IGV4aXN0cy5cbiAgICogVXNlZCBieSB0aGUgdGVzdCBydW5uZXIgdG8gc2hhcmUgYSBjb25uZWN0aW9uIGJldHdlZW4gdGVzdCBjb2RlIGFuZCBIVFRQIGhhbmRsZXJzXG4gICAqIHJ1bm5pbmcgaW4gdGhlIHNhbWUgcHJvY2VzcyAoaW4tcHJvY2VzcyB0ZXN0IHNlcnZlciBtb2RlKS5cbiAgICogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfVxuICAgKi9cbiAgX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gdW5kZWZpbmVkXG5cbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSAqL1xuICBjb25uZWN0aW9ucyA9IFtdXG5cbiAgLyoqIEB0eXBlIHtSZWNvcmQ8bnVtYmVyLCBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59ICovXG4gIGNvbm5lY3Rpb25zSW5Vc2UgPSB7fVxuXG4gIC8qKiBAdHlwZSB7UGVuZGluZ0NoZWNrb3V0W119ICovXG4gIHBlbmRpbmdDaGVja291dHMgPSBbXVxuXG4gIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICBjb25uZWN0aW9uc0JlaW5nU3Bhd25lZCA9IDBcblxuICAvKiogQHR5cGUge1Byb21pc2U8dm9pZD4gfCB1bmRlZmluZWR9ICovXG4gIHBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZSA9IHVuZGVmaW5lZFxuXG4gIC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCB1bmRlZmluZWR9ICovXG4gIGlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSB1bmRlZmluZWRcblxuICAvKipcbiAgICogSW4tZmxpZ2h0IGNvbm5lY3Rpb24tY2xvc2UgcHJvbWlzZXMuIFRoZSBpZGxlIHJlYXBlciBpcyBhcm1lZCBvbiBjaGVjay1pblxuICAgKiBhbmQgcnVucyBmaXJlLWFuZC1mb3JnZXQgd2hlbiBpdHMgdGltZXIgZmlyZXMsIHNvIGEgc2NoZWR1bGVkIHJlYXAgY2FuIGJlXG4gICAqIGNsb3NpbmcgYSBjb25uZWN0aW9uIHdoaWxlIGFuIGV4cGxpY2l0IGByZWFwSWRsZUNvbm5lY3Rpb25zKClgIChvclxuICAgKiBgY2xlYXJJZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKClgKSBydW5zLiBUcmFja2luZyB0aGUgaW4tZmxpZ2h0IGNsb3NlcyBsZXRzXG4gICAqIHRob3NlIGNhbGxlcnMgYXdhaXQgdGhlbSwgc28gb25jZSBhIHJlYXAgcmVzb2x2ZXMgdGhlIGNvbm5lY3Rpb25zIGl0XG4gICAqIGV4cGlyZWQgYXJlIGZ1bGx5IGNsb3NlZCBpbnN0ZWFkIG9mIGhhbGYtY2xvc2VkIG1pZC1gY2xvc2UoKWAuXG4gICAqIEB0eXBlIHtTZXQ8UHJvbWlzZTx2b2lkPj59XG4gICAqL1xuICBpbmZsaWdodENvbm5lY3Rpb25DbG9zZXMgPSBuZXcgU2V0KClcblxuICAvKipcbiAgICogSW4tZmxpZ2h0IGNsb3NlIHByb21pc2UgcGVyIGNvbm5lY3Rpb24sIHNvIGNvbmN1cnJlbnQgY2xvc2VzIG9mIHRoZSBzYW1lXG4gICAqIGNvbm5lY3Rpb24gYXdhaXQgdGhlIHNhbWUgY2xvc2UgcmF0aGVyIHRoYW4gY2xvc2luZyB0aGUgZHJpdmVyIGhhbmRsZSB0d2ljZS5cbiAgICogQHR5cGUge1dlYWtNYXA8b2JqZWN0LCBQcm9taXNlPHZvaWQ+Pn1cbiAgICovXG4gIGNvbm5lY3Rpb25DbG9zZVByb21pc2VzID0gbmV3IFdlYWtNYXAoKVxuXG4gIGlkU2VxID0gMFxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuaWRlbnRpZmllciAtIElkZW50aWZpZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgaWRlbnRpZmllcn0pIHtcbiAgICBzdXBlcih7Y29uZmlndXJhdGlvbiwgaWRlbnRpZmllcn0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIERhdGFiYXNlIGNvbm5lY3Rpb24gaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgY2hlY2tlZCBpbiBvciBjbG9zZWQuXG4gICAqL1xuICBhc3luYyBjaGVja2luKGNvbm5lY3Rpb24pIHtcbiAgICBjb25zdCBpZCA9IGNvbm5lY3Rpb24uZ2V0SWRTZXEoKVxuXG4gICAgdGhpcy51bnRyYWNrQ29ubmVjdGlvbkluVXNlKGNvbm5lY3Rpb24sIGlkKVxuXG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tDTE9TRURfQ09OTkVDVElPTl0/OiBib29sZWFuLCBbQ09OTkVDVElPTl9DSEVDS0VEX09VVF9BVF0/OiBudW1iZXIsIFtJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcblxuICAgIGlmICh0cmFja2VkQ29ubmVjdGlvbltDTE9TRURfQ09OTkVDVElPTl0pIHJldHVyblxuXG4gICAgYXdhaXQgdGhpcy5yb2xsYmFja0xlZnRPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbilcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjb25uZWN0aW9uLmNsZWFyQ29ubmVjdGlvbkNoZWNrb3V0TmFtZSgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG5cbiAgICAgIHRocm93IGVycm9yXG4gICAgfVxuXG4gICAgdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdID0gRGF0ZS5ub3coKVxuICAgIGRlbGV0ZSB0cmFja2VkQ29ubmVjdGlvbltDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXVxuICAgIHRoaXMuY29ubmVjdGlvbnMucHVzaChjb25uZWN0aW9uKVxuICAgIGF3YWl0IHRoaXMuZHJhaW5QZW5kaW5nQ2hlY2tvdXRzKClcbiAgICBhd2FpdCB0aGlzLmhhbmRsZUNoZWNrZWRJbklkbGVDb25uZWN0aW9uKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiBiZWluZyBjaGVja2VkIGluLlxuICAgKiBAcGFyYW0ge251bWJlciB8IHVuZGVmaW5lZH0gaWQgLSBDb25uZWN0aW9uIGNoZWNrb3V0IGlkLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHVudHJhY2tDb25uZWN0aW9uSW5Vc2UoY29ubmVjdGlvbiwgaWQpIHtcbiAgICBpZiAodHlwZW9mIGlkICE9PSBcIm51bWJlclwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGlkU2VxIG9uIGNvbm5lY3Rpb24gd2Fzbid0IHNldD8gJyR7dHlwZW9mIGlkfScgPSAke2lkfWApXG4gICAgfVxuXG4gICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF1cbiAgICBjb25uZWN0aW9uLnNldElkU2VxKHVuZGVmaW5lZClcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBvbmNlIGlkbGUgcmVhcGluZyBoYXMgYmVlbiBzY2hlZHVsZWQgb3IgcnVuLiAqL1xuICBhc3luYyBoYW5kbGVDaGVja2VkSW5JZGxlQ29ubmVjdGlvbigpIHtcbiAgICBpZiAodGhpcy5pZGxlVGltZW91dE1pbGxpcygpID09PSAwKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjaGVkdWxlSWRsZUNvbm5lY3Rpb25SZWFwZXIoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5Db25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zfSBbb3B0aW9uc10gLSBDaGVja291dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2hlY2tvdXQuXG4gICAqL1xuICBhc3luYyBjaGVja291dChvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBkYXRhYmFzZUNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpXG4gICAgY29uc3QgcmV1c2VLZXkgPSB0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpXG4gICAgbGV0IGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KHJldXNlS2V5KVxuXG4gICAgaWYgKGNvbm5lY3Rpb24pIHJldHVybiBhd2FpdCB0aGlzLmFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uLCBvcHRpb25zKVxuXG4gICAgYXdhaXQgdGhpcy5yZWFwSWRsZUNvbm5lY3Rpb25zKClcbiAgICBjb25uZWN0aW9uID0gdGhpcy50YWtlSWRsZUNvbm5lY3Rpb25Gb3JSZXVzZUtleShyZXVzZUtleSlcblxuICAgIGlmIChjb25uZWN0aW9uKSByZXR1cm4gYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgb3B0aW9ucylcblxuICAgIGlmICh0aGlzLmNhblNwYXduQ29ubmVjdGlvbigpKSB7XG4gICAgICAvLyBTcGF3biB2aWEgc3Bhd25Db25uZWN0aW9uKCkgc28gdGhlIHRlbmFudC1hd2FyZSBjb25maWd1cmF0aW9uIGlzIHJlc29sdmVkIEZSRVNIIGF0XG4gICAgICAvLyBzcGF3biB0aW1lIGZvciB0aGUgY3VycmVudCBjYWxsZXIuIFJldXNpbmcgdGhlIGRhdGFiYXNlQ29uZmlnIGNhcHR1cmVkIGF0IHRoZSB0b3Agb2ZcbiAgICAgIC8vIGNoZWNrb3V0KCkgY291bGQgYmluZCB0aGUgY29ubmVjdGlvbiB0byBhIHN0YWxlIHRlbmFudC9kYXRhYmFzZSwgd2hpY2ggYnJlYWtzXG4gICAgICAvLyBwZXItcmVxdWVzdCBpc29sYXRpb24gKGUuZy4gdGVzdCB0cnVuY2F0aW9uIGFwcGVhcmluZyBub3QgdG8gdGFrZSBlZmZlY3QpLiBUaGUgcXVldWVkXG4gICAgICAvLyBwYXRoIGJlbG93IGtlZXBzIHRoZSB3YWl0aW5nIGNhbGxlcidzIGNhcHR1cmVkIGNvbmZpZyB2aWEgd2FpdEZvckNoZWNrb3V0KCkuXG4gICAgICBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25Gb3JDaGVja291dCh0aGlzLmdldENvbmZpZ3VyYXRpb24oKSwgdGhpcy5nZXRDb25maWd1cmF0aW9uUmV1c2VLZXkoKSlcblxuICAgICAgcmV0dXJuIGF3YWl0IHRoaXMuYWN0aXZhdGVDb25uZWN0aW9uKGNvbm5lY3Rpb24sIG9wdGlvbnMpXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMud2FpdEZvckNoZWNrb3V0KGRhdGFiYXNlQ29uZmlnLCByZXVzZUtleSwgb3B0aW9ucylcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleS5cbiAgICogQHBhcmFtIHtvYmplY3R9IFthcmdzXSAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gW2FyZ3MuaW5jbHVkZU9wZW5UcmFuc2FjdGlvbnNdIC0gV2hldGhlciBjb25uZWN0aW9ucyB3aXRoIG9wZW4gdHJhbnNhY3Rpb25zIG1heSBiZSByZXR1cm5lZC5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSAtIE1hdGNoaW5nIGlkbGUgY29ubmVjdGlvbi5cbiAgICovXG4gIHRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KHJldXNlS2V5LCB7aW5jbHVkZU9wZW5UcmFuc2FjdGlvbnMgPSB0cnVlfSA9IHt9KSB7XG4gICAgY29uc3QgY29ubmVjdGlvbkluZGV4ID0gdGhpcy5jb25uZWN0aW9ucy5maW5kSW5kZXgoKHF1ZXVlZENvbm5lY3Rpb24pID0+IHtcbiAgICAgIGlmICghaW5jbHVkZU9wZW5UcmFuc2FjdGlvbnMgJiYgdGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKHF1ZXVlZENvbm5lY3Rpb24pKSByZXR1cm4gZmFsc2VcblxuICAgICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbk1hdGNoZXNSZXVzZUtleShxdWV1ZWRDb25uZWN0aW9uLCByZXVzZUtleSlcbiAgICB9KVxuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBjb25uZWN0aW9uSW5kZXggPT09IC0xID8gdW5kZWZpbmVkIDogdGhpcy5jb25uZWN0aW9ucy5zcGxpY2UoY29ubmVjdGlvbkluZGV4LCAxKVswXVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHJldXNlS2V5IC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiByZXVzZSBrZXkuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIGNvbm5lY3Rpb24gbWF0Y2hlcyB0aGUgcmV1c2Uga2V5LlxuICAgKi9cbiAgY29ubmVjdGlvbk1hdGNoZXNSZXVzZUtleShjb25uZWN0aW9uLCByZXVzZUtleSkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25XaXRoUG9vbEtleSA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W1BPT0xfQ09ORklHVVJBVElPTl9LRVldPzogc3RyaW5nfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gY29ubmVjdGlvbldpdGhQb29sS2V5W1BPT0xfQ09ORklHVVJBVElPTl9LRVldID09PSByZXVzZUtleVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5Db25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zfSBbb3B0aW9uc10gLSBDaGVja291dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gQWN0aXZhdGVkIGNvbm5lY3Rpb24uXG4gICAqL1xuICBhc3luYyBhY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgb3B0aW9ucyA9IHt9KSB7XG4gICAgaWYgKGNvbm5lY3Rpb24uZ2V0SWRTZXEoKSAhPT0gdW5kZWZpbmVkKSB0aHJvdyBuZXcgRXJyb3IoYENvbm5lY3Rpb24gYWxyZWFkeSBoYXMgYW4gSUQtc2VxIC0gaXMgaXQgaW4gdXNlPyAke2Nvbm5lY3Rpb24uZ2V0SWRTZXEoKX1gKVxuXG4gICAgY29uc3QgaWQgPSB0aGlzLmlkU2VxKytcblxuICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbQ09OTkVDVElPTl9DSEVDS0VEX09VVF9BVF0/OiBudW1iZXIsIFtJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICBkZWxldGUgdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG4gICAgdHJhY2tlZENvbm5lY3Rpb25bQ09OTkVDVElPTl9DSEVDS0VEX09VVF9BVF0gPSBEYXRlLm5vdygpXG5cbiAgICBjb25uZWN0aW9uLnNldElkU2VxKGlkKVxuICAgIHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF0gPSBjb25uZWN0aW9uXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5zZXRDb25uZWN0aW9uQ2hlY2tvdXROYW1lKG9wdGlvbnMubmFtZSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF1cbiAgICAgIGNvbm5lY3Rpb24uc2V0SWRTZXEodW5kZWZpbmVkKVxuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbilcblxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtudW1iZXIgfCB1bmRlZmluZWR9IC0gQ29uZmlndXJlZCBtYXggbGl2ZSBjb25uZWN0aW9ucy4gKi9cbiAgbWF4Q29ubmVjdGlvbnMoKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5wb29sPy5tYXhcblxuICAgIGlmICh0aGlzLnZhbGlkTWF4Q29ubmVjdGlvbnModmFsdWUpKSByZXR1cm4gdmFsdWVcblxuICAgIHJldHVyblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7dW5rbm93bn0gdmFsdWUgLSBDYW5kaWRhdGUgbWF4IGNvbm5lY3Rpb24gY291bnQuXG4gICAqIEByZXR1cm5zIHt2YWx1ZSBpcyBudW1iZXJ9IC0gV2hldGhlciB0aGUgdmFsdWUgaXMgYSB2YWxpZCBtYXggY29ubmVjdGlvbiBjb3VudC5cbiAgICovXG4gIHZhbGlkTWF4Q29ubmVjdGlvbnModmFsdWUpIHtcbiAgICByZXR1cm4gdHlwZW9mIHZhbHVlID09PSBcIm51bWJlclwiICYmIE51bWJlci5pc0Zpbml0ZSh2YWx1ZSkgJiYgdmFsdWUgPj0gMVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtudW1iZXJ9IC0gTnVtYmVyIG9mIGxpdmUgYW5kIGluLXByb2dyZXNzIGNvbm5lY3Rpb25zLiAqL1xuICBsaXZlQ29ubmVjdGlvbkNvdW50KCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldChbXG4gICAgICAuLi50aGlzLmNvbm5lY3Rpb25zLFxuICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpLFxuICAgICAgdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpXG4gICAgXS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICByZXR1cm4gY29ubmVjdGlvbnMuc2l6ZSArIHRoaXMuY29ubmVjdGlvbnNCZWluZ1NwYXduZWRcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGEgbmV3IGNvbm5lY3Rpb24gY2FuIGJlIHNwYXduZWQuICovXG4gIGNhblNwYXduQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBtYXhDb25uZWN0aW9ucyA9IHRoaXMubWF4Q29ubmVjdGlvbnMoKVxuXG4gICAgcmV0dXJuIG1heENvbm5lY3Rpb25zID09PSB1bmRlZmluZWQgfHwgdGhpcy5saXZlQ29ubmVjdGlvbkNvdW50KCkgPCBtYXhDb25uZWN0aW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSBkYXRhYmFzZUNvbmZpZyAtIFJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZyBmb3IgdGhlIGNoZWNrb3V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleSBmb3IgdGhlIGNoZWNrb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gU3Bhd25lZCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25Db25uZWN0aW9uRm9yQ2hlY2tvdXQoZGF0YWJhc2VDb25maWcsIHJldXNlS2V5KSB7XG4gICAgdGhpcy5jb25uZWN0aW9uc0JlaW5nU3Bhd25lZCsrXG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuc3Bhd25Db25uZWN0aW9uV2l0aENvbmZpZ3VyYXRpb24oZGF0YWJhc2VDb25maWcpXG4gICAgICBjb25zdCBjb25uZWN0aW9uV2l0aFBvb2xLZXkgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tQT09MX0NPTkZJR1VSQVRJT05fS0VZXT86IHN0cmluZ319ICovIChjb25uZWN0aW9uKVxuXG4gICAgICBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0gPSByZXVzZUtleVxuICAgICAgY29ubmVjdGlvbi5zZXRTY2hlbWFDYWNoZUludmFsaWRhdG9yKCgpID0+IHtcbiAgICAgICAgdGhpcy5jbGVhclNjaGVtYUNhY2hlKClcbiAgICAgICAgdGhpcy5jb25maWd1cmF0aW9uLmNsZWFyU2NoZW1hQ2FjaGVzRm9yUmV1c2VLZXkocmV1c2VLZXkpXG4gICAgICB9KVxuXG4gICAgICByZXR1cm4gY29ubmVjdGlvblxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkLS1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGRhdGFiYXNlQ29uZmlnIC0gUmVzb2x2ZWQgZGF0YWJhc2UgY29uZmlnIGZvciB0aGUgY2hlY2tvdXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5Db25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zfSBbb3B0aW9uc10gLSBDaGVja291dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gUmVzb2x2ZXMgd2l0aCBhbiBhY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIHdhaXRGb3JDaGVja291dChkYXRhYmFzZUNvbmZpZywgcmV1c2VLZXksIG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdDaGVja291dHMucHVzaCh7ZGF0YWJhc2VDb25maWcsIGVucXVldWVkQXQ6IERhdGUubm93KCksIG9wdGlvbnMsIHJlamVjdCwgcmVzb2x2ZSwgcmV1c2VLZXl9KVxuICAgICAgdm9pZCB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0cygpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zdCBjaGVja291dEVycm9yID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFwiRmFpbGVkIHRvIGRyYWluIHBlbmRpbmcgZGF0YWJhc2UgY29ubmVjdGlvbiBjaGVja291dHMuXCIsIHtjYXVzZTogZXJyb3J9KVxuXG4gICAgICAgIHRoaXMucmVqZWN0UGVuZGluZ0NoZWNrb3V0cyhjaGVja291dEVycm9yKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gcGVuZGluZyBjaGVja291dHMgaGF2ZSBiZWVuIGRyYWluZWQgYXMgZmFyIGFzIHBvc3NpYmxlLiAqL1xuICBhc3luYyBkcmFpblBlbmRpbmdDaGVja291dHMoKSB7XG4gICAgaWYgKHRoaXMucGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlKSB7XG4gICAgICBhd2FpdCB0aGlzLnBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UgPSB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0c0FjdHVhbCgpXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2VcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UgPSB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBwZW5kaW5nIGNoZWNrb3V0cyBoYXZlIGJlZW4gZHJhaW5lZCBhcyBmYXIgYXMgcG9zc2libGUuICovXG4gIGFzeW5jIGRyYWluUGVuZGluZ0NoZWNrb3V0c0FjdHVhbCgpIHtcbiAgICB3aGlsZSAodGhpcy5wZW5kaW5nQ2hlY2tvdXRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGNoZWNrb3V0ID0gdGhpcy5wZW5kaW5nQ2hlY2tvdXRzWzBdXG5cbiAgICAgIGlmIChhd2FpdCB0aGlzLmNsb3NlSWRsZUNvbm5lY3Rpb25Gb3JQZW5kaW5nQ2hlY2tvdXRDYXBhY2l0eShjaGVja291dCkpIGNvbnRpbnVlXG4gICAgICBpZiAodGhpcy5jYW5TcGF3bkNvbm5lY3Rpb24oKSkge1xuICAgICAgICB0aGlzLnBlbmRpbmdDaGVja291dHMuc2hpZnQoKVxuICAgICAgICBhd2FpdCB0aGlzLnNwYXduQW5kUmVzb2x2ZVBlbmRpbmdDaGVja291dChjaGVja291dClcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuaWRsZUNvbm5lY3Rpb25Gb3JQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQpXG5cbiAgICAgIGlmICghY29ubmVjdGlvbikgcmV0dXJuXG5cbiAgICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5zaGlmdCgpXG4gICAgICBhd2FpdCB0aGlzLnJlc29sdmVQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQsIGNvbm5lY3Rpb24pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UGVuZGluZ0NoZWNrb3V0fSBjaGVja291dCAtIENoZWNrb3V0IHdhaXRpbmcgZm9yIGEgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IC0gV2hldGhlciBhbiBpZGxlIGNvbm5lY3Rpb24gd2FzIGNsb3NlZCB0byBmcmVlIGNhcGFjaXR5LlxuICAgKi9cbiAgYXN5bmMgY2xvc2VJZGxlQ29ubmVjdGlvbkZvclBlbmRpbmdDaGVja291dENhcGFjaXR5KGNoZWNrb3V0KSB7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuZmluZElkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXkpXG5cbiAgICBpZiAoY29ubmVjdGlvbikgcmV0dXJuIGZhbHNlXG5cbiAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuXG4gICAgaWYgKHRoaXMuZmluZElkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXkpKSByZXR1cm4gZmFsc2VcblxuICAgIHJldHVybiB0aGlzLmNhblNwYXduQ29ubmVjdGlvbigpID8gZmFsc2UgOiBhd2FpdCB0aGlzLmNsb3NlT25lSWRsZUNvbm5lY3Rpb25Gb3JDYXBhY2l0eSgpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJldXNlS2V5IC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiByZXVzZSBrZXkuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBNYXRjaGluZyBpZGxlIGNvbm5lY3Rpb24sIGlmIHByZXNlbnQuXG4gICAqL1xuICBmaW5kSWRsZUNvbm5lY3Rpb25Gb3JSZXVzZUtleShyZXVzZUtleSkge1xuICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25zLmZpbmQoKGNvbm5lY3Rpb24pID0+ICF0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikgJiYgdGhpcy5jb25uZWN0aW9uTWF0Y2hlc1JldXNlS2V5KGNvbm5lY3Rpb24sIHJldXNlS2V5KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge1BlbmRpbmdDaGVja291dH0gY2hlY2tvdXQgLSBDaGVja291dCB3YWl0aW5nIGZvciBhIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkPn0gLSBNYXRjaGluZyBpZGxlIGNvbm5lY3Rpb24sIGlmIG9uZSBjYW4gYmUgcmV1c2VkLlxuICAgKi9cbiAgYXN5bmMgaWRsZUNvbm5lY3Rpb25Gb3JQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQpIHtcbiAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9uczogZmFsc2V9KVxuXG4gICAgaWYgKGNvbm5lY3Rpb24pIHJldHVybiBjb25uZWN0aW9uXG5cbiAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KGNoZWNrb3V0LnJldXNlS2V5LCB7aW5jbHVkZU9wZW5UcmFuc2FjdGlvbnM6IGZhbHNlfSlcblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtQZW5kaW5nQ2hlY2tvdXR9IGNoZWNrb3V0IC0gQ2hlY2tvdXQgcmVxdWVzdCB0byByZXNvbHZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHRoZSBjaGVja291dCBoYXMgYmVlbiBoYW5kbGVkLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25BbmRSZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0KSB7XG4gICAgbGV0IGNvbm5lY3Rpb25cblxuICAgIHRyeSB7XG4gICAgICBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25Gb3JDaGVja291dChjaGVja291dC5kYXRhYmFzZUNvbmZpZywgY2hlY2tvdXQucmV1c2VLZXkpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gc3Bhd24gZGF0YWJhc2UgY29ubmVjdGlvbi5cIiwge2NhdXNlOiBlcnJvcn0pKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UGVuZGluZ0NoZWNrb3V0fSBjaGVja291dCAtIENoZWNrb3V0IHJlcXVlc3QgdG8gcmVzb2x2ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gYWN0aXZhdGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNoZWNrb3V0IGhhcyBiZWVuIGhhbmRsZWQuXG4gICAqL1xuICBhc3luYyByZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNoZWNrb3V0LnJlc29sdmUoYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgY2hlY2tvdXQub3B0aW9ucykpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gYWN0aXZhdGUgZGF0YWJhc2UgY29ubmVjdGlvbi5cIiwge2NhdXNlOiBlcnJvcn0pKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIGFuIGlkbGUgY29ubmVjdGlvbiB3YXMgY2xvc2VkIHRvIGZyZWUgY2FwYWNpdHkuICovXG4gIGFzeW5jIGNsb3NlT25lSWRsZUNvbm5lY3Rpb25Gb3JDYXBhY2l0eSgpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5jb25uZWN0aW9ucy5maW5kKChjYW5kaWRhdGUpID0+ICF0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY2FuZGlkYXRlKSlcblxuICAgIGlmICghY29ubmVjdGlvbikgcmV0dXJuIGZhbHNlXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gdGhpcy5jb25uZWN0aW9ucy5maWx0ZXIoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlICE9PSBjb25uZWN0aW9uKVxuICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnMgfCBmdW5jdGlvbihpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgOiBQcm9taXNlPFQ+fSBvcHRpb25zT3JDYWxsYmFjayAtIENoZWNrb3V0IG9wdGlvbnMgb3IgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggdGhlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpIDogUHJvbWlzZTxUPn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIHRvIGludm9rZSB3aXRoIHRoZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoQ29ubmVjdGlvbihvcHRpb25zT3JDYWxsYmFjaywgY2FsbGJhY2spIHtcbiAgICBjb25zdCBvcHRpb25zID0gdHlwZW9mIG9wdGlvbnNPckNhbGxiYWNrID09IFwiZnVuY3Rpb25cIiA/IHt9IDogb3B0aW9uc09yQ2FsbGJhY2tcbiAgICBjb25zdCBhY3R1YWxDYWxsYmFjayA9IHR5cGVvZiBvcHRpb25zT3JDYWxsYmFjayA9PSBcImZ1bmN0aW9uXCIgPyBvcHRpb25zT3JDYWxsYmFjayA6IGNhbGxiYWNrXG5cbiAgICBpZiAoIWFjdHVhbENhbGxiYWNrKSB0aHJvdyBuZXcgRXJyb3IoXCJ3aXRoQ29ubmVjdGlvbiByZXF1aXJlcyBhIGNhbGxiYWNrXCIpXG5cbiAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5jaGVja291dChvcHRpb25zKVxuICAgIGNvbnN0IGlkID0gY29ubmVjdGlvbi5nZXRJZFNlcSgpXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oaWQsIGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBhY3R1YWxDYWxsYmFjayhjb25uZWN0aW9uKVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja2luKGNvbm5lY3Rpb24pXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IC0gVGhlIGN1cnJlbnQgY29ubmVjdGlvbi4gICovXG4gIGdldEN1cnJlbnRDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGlkID0gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5nZXRTdG9yZSgpXG5cbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRoaXMuY3VycmVudEZhbGxiYWNrQ29ubmVjdGlvbk9yRmFpbCgpXG5cbiAgICB0aGlzLmVuc3VyZUNvbm5lY3Rpb25Jc0luVXNlKGlkKVxuXG4gICAgY29uc3QgY3VycmVudENvbm5lY3Rpb24gPSB0aGlzLmNvbm5lY3Rpb25zSW5Vc2VbaWRdXG5cbiAgICBpZiAoIWN1cnJlbnRDb25uZWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkbid0IGdldCBjdXJyZW50IGNvbm5lY3Rpb24gZnJvbSB0aGF0IElEOiAke2lkfWApXG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRDb25uZWN0aW9uXG4gIH1cblxuICAvKiogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSAtIEZhbGxiYWNrIGNvbm5lY3Rpb24sIGlmIHByZXNlbnQuICovXG4gIGN1cnJlbnRGYWxsYmFja0Nvbm5lY3Rpb25PckZhaWwoKSB7XG4gICAgY29uc3QgZmFsbGJhY2tDb25uZWN0aW9uID0gdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uKClcblxuICAgIGlmIChmYWxsYmFja0Nvbm5lY3Rpb24pIHJldHVybiBmYWxsYmFja0Nvbm5lY3Rpb25cblxuICAgIHRocm93IG5ldyBFcnJvcihcIklEIGhhc24ndCBiZWVuIHNldCBmb3IgdGhpcyBhc3luYyBjb250ZXh0XCIpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGlkIC0gQ2hlY2tlZC1vdXQgY29ubmVjdGlvbiBpZC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBlbnN1cmVDb25uZWN0aW9uSXNJblVzZShpZCkge1xuICAgIGlmICghKGlkIGluIHRoaXMuY29ubmVjdGlvbnNJblVzZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiAke2lkfSBkb2Vzbid0IGV4aXN0IGFueSBtb3JlIC0gaGFzIGl0IGJlZW4gY2hlY2tlZCBpbiBhZ2Fpbj9gKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBmYWxsYmFjayBjb25uZWN0aW9uIGZvciB0aGlzIHBvb2wgaWRlbnRpZmllciB0aGF0IHdpbGwgYmUgdXNlZCB3aGVuIG5vIGFzeW5jIGNvbnRleHQgaXMgYXZhaWxhYmxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc2V0R2xvYmFsQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgY29uc3Qga2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb259ICovICh0aGlzLmNvbnN0cnVjdG9yKVxuICAgIGxldCBtYXBGb3JDb25maWd1cmF0aW9uID0ga2xhc3MuZ2xvYmFsQ29ubmVjdGlvbnMuZ2V0KHRoaXMuY29uZmlndXJhdGlvbilcblxuICAgIGlmICghbWFwRm9yQ29uZmlndXJhdGlvbikge1xuICAgICAgbWFwRm9yQ29uZmlndXJhdGlvbiA9IHt9XG4gICAgICBrbGFzcy5nbG9iYWxDb25uZWN0aW9ucy5zZXQodGhpcy5jb25maWd1cmF0aW9uLCBtYXBGb3JDb25maWd1cmF0aW9uKVxuICAgIH1cblxuICAgIG1hcEZvckNvbmZpZ3VyYXRpb25bdGhpcy5pZGVudGlmaWVyXSA9IGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIGEgZ2xvYmFsIGZhbGxiYWNrIGNvbm5lY3Rpb24gZXhpc3RzIGZvciB0aGlzIHBvb2wgaWRlbnRpZmllciBhbmQgcmV0dXJucyBpdC5cbiAgICogSWYgb25lIGlzIGFscmVhZHkgc2V0LCBpdCBpcyByZXR1cm5lZCBhbmQgYWxzbyBtYWRlIGF2YWlsYWJsZSBpbiB0aGUgcG9vbCBxdWV1ZS5cbiAgICogT3RoZXJ3aXNlIGEgbmV3IGNvbm5lY3Rpb24gaXMgc3Bhd25lZCwgcmVnaXN0ZXJlZCwgYW5kIHF1ZXVlZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGdsb2JhbCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlR2xvYmFsQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbigpXG5cbiAgICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZ1xuXG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuc3Bhd25Db25uZWN0aW9uKClcblxuICAgIHRoaXMuc2V0R2xvYmFsQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYSBzaGFyZWQgY29ubmVjdGlvbiBmb3IgdGVzdCBtb2RlIHNvIHRoYXQgSFRUUCBoYW5kbGVycyBydW5uaW5nXG4gICAqIGluIHRoZSBzYW1lIHByb2Nlc3MgY2FuIHJldXNlIHRoZSB0ZXN0IHJ1bm5lcidzIGRhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBTaGFyZWQgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBzZXRUZXN0U2hhcmVkQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24gPSBjb25uZWN0aW9uXG4gIH1cblxuICAvKiogQHJldHVybnMge3ZvaWR9ICovXG4gIGNsZWFyVGVzdFNoYXJlZENvbm5lY3Rpb24oKSB7XG4gICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24gPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb25uZWN0aW9uIHRpZWQgdG8gdGhlIGN1cnJlbnQgYXN5bmMgY29udGV4dCwgaWYgYW55LlxuICAgKiBGYWxscyBiYWNrIHRvIHRoZSB0ZXN0IHNoYXJlZCBjb25uZWN0aW9uIHdoZW4gbm8gYXN5bmMgY29udGV4dCBleGlzdHMuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBUaGUgY3VycmVudCBjb250ZXh0IGNvbm5lY3Rpb24uXG4gICAqL1xuICBnZXRDdXJyZW50Q29udGV4dENvbm5lY3Rpb24oKSB7XG4gICAgY29uc3QgaWQgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKClcblxuICAgIGlmIChpZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb25cblxuICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnRDb25uZWN0aW9uKClcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkRhdGFiYXNlUG9vbERlYnVnU25hcHNob3R9IC0gRGlhZ25vc3RpYyBzbmFwc2hvdCBmb3IgdGhpcyBwb29sLiAqL1xuICBnZXREZWJ1Z1NuYXBzaG90KCkge1xuICAgIGNvbnN0IHNuYXBzaG90ID0gc3VwZXIuZ2V0RGVidWdTbmFwc2hvdCgpXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuICAgIGNvbnN0IHtjb25uZWN0aW9uc30gPSB0aGlzLmRlYnVnQ29ubmVjdGlvblNuYXBzaG90cyhub3cpXG5cbiAgICByZXR1cm4ge1xuICAgICAgLi4uc25hcHNob3QsXG4gICAgICBjb25uZWN0aW9ucyxcbiAgICAgIGNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkOiB0aGlzLmNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkLFxuICAgICAgaWRsZUNvdW50OiB0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCxcbiAgICAgIGluVXNlQ291bnQ6IE9iamVjdC5rZXlzKHRoaXMuY29ubmVjdGlvbnNJblVzZSkubGVuZ3RoLFxuICAgICAgcGVuZGluZ0NoZWNrb3V0czogdGhpcy5wZW5kaW5nQ2hlY2tvdXREZWJ1Z1NuYXBzaG90cyhub3cpLFxuICAgICAgcGVuZGluZ0NoZWNrb3V0Q291bnQ6IHRoaXMucGVuZGluZ0NoZWNrb3V0cy5sZW5ndGhcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IG5vdyAtIEN1cnJlbnQgdGltZXN0YW1wLlxuICAgKiBAcmV0dXJucyB7e2Nvbm5lY3Rpb25zOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sIHNlZW5Db25uZWN0aW9uczogU2V0PGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn19IC0gQ29ubmVjdGlvbiBzbmFwc2hvdHMgYW5kIHNlZW4gc2V0LlxuICAgKi9cbiAgZGVidWdDb25uZWN0aW9uU25hcHNob3RzKG5vdykge1xuICAgIC8qKiBAdHlwZSB7QXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+fSAqL1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gW11cbiAgICBjb25zdCBzZWVuQ29ubmVjdGlvbnMgPSBuZXcgU2V0KClcblxuICAgIHRoaXMuYWRkSW5Vc2VEZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdHMoe2Nvbm5lY3Rpb25zLCBub3csIHNlZW5Db25uZWN0aW9uc30pXG4gICAgdGhpcy5hZGRJZGxlRGVidWdDb25uZWN0aW9uU25hcHNob3RzKHtjb25uZWN0aW9ucywgbm93LCBzZWVuQ29ubmVjdGlvbnN9KVxuICAgIHRoaXMuYWRkRmFsbGJhY2tEZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdHMoe2Nvbm5lY3Rpb25zLCBzZWVuQ29ubmVjdGlvbnN9KVxuXG4gICAgcmV0dXJuIHtjb25uZWN0aW9ucywgc2VlbkNvbm5lY3Rpb25zfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7e2Nvbm5lY3Rpb25zOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sIG5vdzogbnVtYmVyLCBzZWVuQ29ubmVjdGlvbnM6IFNldDxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59fSBhcmdzIC0gU25hcHNob3QgY29sbGVjdGlvbiBzdGF0ZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhZGRJblVzZURlYnVnQ29ubmVjdGlvblNuYXBzaG90cyh7Y29ubmVjdGlvbnMsIG5vdywgc2VlbkNvbm5lY3Rpb25zfSkge1xuICAgIGZvciAoY29uc3QgW2lkLCBjb25uZWN0aW9uXSBvZiBPYmplY3QuZW50cmllcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpKSB7XG4gICAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0NPTk5FQ1RJT05fQ0hFQ0tFRF9PVVRfQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG4gICAgICBjb25zdCBjaGVja2VkT3V0QXQgPSB0cmFja2VkQ29ubmVjdGlvbltDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXVxuICAgICAgY29uc3QgY2hlY2tlZE91dEZvck1zID0gdHlwZW9mIGNoZWNrZWRPdXRBdCA9PT0gXCJudW1iZXJcIiA/IE1hdGgubWF4KDAsIG5vdyAtIGNoZWNrZWRPdXRBdCkgOiB1bmRlZmluZWRcblxuICAgICAgc2VlbkNvbm5lY3Rpb25zLmFkZChjb25uZWN0aW9uKVxuICAgICAgY29ubmVjdGlvbnMucHVzaCh0aGlzLmRlYnVnQ29ubmVjdGlvblNuYXBzaG90KGNvbm5lY3Rpb24sIHtjaGVja2VkT3V0QXQsIGNoZWNrZWRPdXRGb3JNcywgY2hlY2tvdXRJZDogaWQsIHN0YXRlOiBcImluLXVzZVwifSkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7e2Nvbm5lY3Rpb25zOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sIG5vdzogbnVtYmVyLCBzZWVuQ29ubmVjdGlvbnM6IFNldDxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59fSBhcmdzIC0gU25hcHNob3QgY29sbGVjdGlvbiBzdGF0ZS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBhZGRJZGxlRGVidWdDb25uZWN0aW9uU25hcHNob3RzKHtjb25uZWN0aW9ucywgbm93LCBzZWVuQ29ubmVjdGlvbnN9KSB7XG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIHRoaXMuY29ubmVjdGlvbnMpIHtcbiAgICAgIGlmIChzZWVuQ29ubmVjdGlvbnMuaGFzKGNvbm5lY3Rpb24pKSBjb250aW51ZVxuXG4gICAgICBzZWVuQ29ubmVjdGlvbnMuYWRkKGNvbm5lY3Rpb24pXG5cbiAgICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG4gICAgICBjb25zdCBjaGVja2VkSW5BdCA9IHRyYWNrZWRDb25uZWN0aW9uW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXVxuICAgICAgY29uc3QgaWRsZUZvck1zID0gdHlwZW9mIGNoZWNrZWRJbkF0ID09PSBcIm51bWJlclwiID8gTWF0aC5tYXgoMCwgbm93IC0gY2hlY2tlZEluQXQpIDogdW5kZWZpbmVkXG5cbiAgICAgIGNvbm5lY3Rpb25zLnB1c2godGhpcy5kZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdChjb25uZWN0aW9uLCB7Y2hlY2tlZEluQXQsIGlkbGVGb3JNcywgc3RhdGU6IFwiaWRsZVwifSkpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7e2Nvbm5lY3Rpb25zOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sIHNlZW5Db25uZWN0aW9uczogU2V0PGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn19IGFyZ3MgLSBTbmFwc2hvdCBjb2xsZWN0aW9uIHN0YXRlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFkZEZhbGxiYWNrRGVidWdDb25uZWN0aW9uU25hcHNob3RzKHtjb25uZWN0aW9ucywgc2VlbkNvbm5lY3Rpb25zfSkge1xuICAgIHRoaXMuYWRkRGVidWdDb25uZWN0aW9uU25hcHNob3RJZlVuc2Vlbih7Y29ubmVjdGlvbjogdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpLCBjb25uZWN0aW9ucywgc2VlbkNvbm5lY3Rpb25zLCBzdGF0ZTogXCJnbG9iYWxcIn0pXG4gICAgdGhpcy5hZGREZWJ1Z0Nvbm5lY3Rpb25TbmFwc2hvdElmVW5zZWVuKHtjb25uZWN0aW9uOiB0aGlzLl90ZXN0U2hhcmVkQ29ubmVjdGlvbiwgY29ubmVjdGlvbnMsIHNlZW5Db25uZWN0aW9ucywgc3RhdGU6IFwidGVzdC1zaGFyZWRcIn0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt7Y29ubmVjdGlvbjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWQsIGNvbm5lY3Rpb25zOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCB1bmtub3duPj4sIHNlZW5Db25uZWN0aW9uczogU2V0PGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Piwgc3RhdGU6IHN0cmluZ319IGFyZ3MgLSBTbmFwc2hvdCBjb2xsZWN0aW9uIHN0YXRlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGFkZERlYnVnQ29ubmVjdGlvblNuYXBzaG90SWZVbnNlZW4oe2Nvbm5lY3Rpb24sIGNvbm5lY3Rpb25zLCBzZWVuQ29ubmVjdGlvbnMsIHN0YXRlfSkge1xuICAgIGlmICghY29ubmVjdGlvbiB8fCBzZWVuQ29ubmVjdGlvbnMuaGFzKGNvbm5lY3Rpb24pKSByZXR1cm5cblxuICAgIHNlZW5Db25uZWN0aW9ucy5hZGQoY29ubmVjdGlvbilcbiAgICBjb25uZWN0aW9ucy5wdXNoKHRoaXMuZGVidWdDb25uZWN0aW9uU25hcHNob3QoY29ubmVjdGlvbiwge3N0YXRlfSkpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IG5vdyAtIEN1cnJlbnQgdGltZXN0YW1wLlxuICAgKiBAcmV0dXJucyB7QXJyYXk8UmVjb3JkPHN0cmluZywgdW5rbm93bj4+fSAtIFBlbmRpbmcgY2hlY2tvdXQgc25hcHNob3RzLlxuICAgKi9cbiAgcGVuZGluZ0NoZWNrb3V0RGVidWdTbmFwc2hvdHMobm93KSB7XG4gICAgcmV0dXJuIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5tYXAoKGNoZWNrb3V0LCBpbmRleCkgPT4gKHtcbiAgICAgIGNoZWNrb3V0TmFtZTogY2hlY2tvdXQub3B0aW9ucy5uYW1lLFxuICAgICAgZW5xdWV1ZWRBdDogY2hlY2tvdXQuZW5xdWV1ZWRBdCxcbiAgICAgIGluZGV4LFxuICAgICAgcmV1c2VLZXk6IGNoZWNrb3V0LnJldXNlS2V5LFxuICAgICAgd2FpdGluZ0Zvck1zOiBNYXRoLm1heCgwLCBub3cgLSBjaGVja291dC5lbnF1ZXVlZEF0KVxuICAgIH0pKVxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBUaGUgZ2xvYmFsIGNvbm5lY3Rpb24uXG4gICAqL1xuICBnZXRHbG9iYWxDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb25Gb3JJZGVudGlmaWVyKClcblxuICAgIGlmICghY29ubmVjdGlvbikgcmV0dXJuXG4gICAgaWYgKCF0aGlzLmNvbm5lY3Rpb25NYXRjaGVzQ3VycmVudENvbmZpZ3VyYXRpb24oY29ubmVjdGlvbikpIHJldHVyblxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGdsb2JhbCBjb25uZWN0aW9uIGZvciB0aGlzIHBvb2wgaWRlbnRpZmllci5cbiAgICovXG4gIGdldEdsb2JhbENvbm5lY3Rpb25Gb3JJZGVudGlmaWVyKCkge1xuICAgIGNvbnN0IGtsYXNzID0gLyoqIEB0eXBlIHt0eXBlb2YgVmVsb2Npb3VzRGF0YWJhc2VQb29sQXN5bmNUcmFja2VkTXVsdGlDb25uZWN0aW9ufSAqLyAodGhpcy5jb25zdHJ1Y3RvcilcbiAgICBjb25zdCBtYXBGb3JDb25maWd1cmF0aW9uID0ga2xhc3MuZ2xvYmFsQ29ubmVjdGlvbnMuZ2V0KHRoaXMuY29uZmlndXJhdGlvbilcblxuICAgIHJldHVybiBtYXBGb3JDb25maWd1cmF0aW9uPy5bdGhpcy5pZGVudGlmaWVyXVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS4gKi9cbiAgY2xlYXJHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpIHtcbiAgICBjb25zdCBrbGFzcyA9IC8qKiBAdHlwZSB7dHlwZW9mIFZlbG9jaW91c0RhdGFiYXNlUG9vbEFzeW5jVHJhY2tlZE11bHRpQ29ubmVjdGlvbn0gKi8gKHRoaXMuY29uc3RydWN0b3IpXG4gICAgY29uc3QgbWFwRm9yQ29uZmlndXJhdGlvbiA9IGtsYXNzLmdsb2JhbENvbm5lY3Rpb25zLmdldCh0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICBpZiAoIW1hcEZvckNvbmZpZ3VyYXRpb24pIHJldHVyblxuXG4gICAgZGVsZXRlIG1hcEZvckNvbmZpZ3VyYXRpb25bdGhpcy5pZGVudGlmaWVyXVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyBzY2hlbWEgbWV0YWRhdGEgY2FjaGVkIGJ5IGV2ZXJ5IGxpdmUgY29ubmVjdGlvbiBvd25lZCBieSB0aGlzIHBvb2wuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIGNsZWFyU2NoZW1hQ2FjaGUoKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSBuZXcgU2V0KFtcbiAgICAgIC4uLnRoaXMuY29ubmVjdGlvbnMsXG4gICAgICAuLi5PYmplY3QudmFsdWVzKHRoaXMuY29ubmVjdGlvbnNJblVzZSksXG4gICAgICB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb24oKSxcbiAgICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uXG4gICAgXS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgY29ubmVjdGlvbnMpIHtcbiAgICAgIGlmIChjb25uZWN0aW9uKSB0aGlzLl9jbGVhckNvbm5lY3Rpb25TY2hlbWFDYWNoZShjb25uZWN0aW9uKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7bnVtYmVyIHwgbnVsbH0gLSBJZGxlIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLCBvciBudWxsIHdoZW4gZGlzYWJsZWQuICovXG4gIGlkbGVUaW1lb3V0TWlsbGlzKCkge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKCkucG9vbD8uaWRsZVRpbWVvdXRNaWxsaXNcblxuICAgIGlmICh2YWx1ZSA9PT0gbnVsbCkgcmV0dXJuIG51bGxcbiAgICBpZiAodGhpcy52YWxpZElkbGVUaW1lb3V0TWlsbGlzKHZhbHVlKSkgcmV0dXJuIHZhbHVlXG5cbiAgICByZXR1cm4gREVGQVVMVF9JRExFX1RJTUVPVVRfTUlMTElTXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIENhbmRpZGF0ZSBpZGxlIHRpbWVvdXQgdmFsdWUuXG4gICAqIEByZXR1cm5zIHt2YWx1ZSBpcyBudW1iZXJ9IC0gV2hldGhlciB0aGUgdmFsdWUgaXMgYSB2YWxpZCBpZGxlIHRpbWVvdXQuXG4gICAqL1xuICB2YWxpZElkbGVUaW1lb3V0TWlsbGlzKHZhbHVlKSB7XG4gICAgcmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpICYmIHZhbHVlID49IDBcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7dm9pZH0gKi9cbiAgc2NoZWR1bGVJZGxlQ29ubmVjdGlvblJlYXBlcigpIHtcbiAgICBpZiAodGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKSByZXR1cm5cbiAgICBpZiAoIXRoaXMuaGFzSWRsZUNvbm5lY3Rpb25zVG9SZWFwKCkpIHJldHVyblxuXG4gICAgY29uc3QgZGVsYXkgPSB0aGlzLm5leHRJZGxlQ29ubmVjdGlvblJlYXBEZWxheSgvKiogQHR5cGUge251bWJlcn0gKi8gKHRoaXMuaWRsZVRpbWVvdXRNaWxsaXMoKSkpXG5cbiAgICB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lciA9IHVuZGVmaW5lZFxuICAgICAgdm9pZCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIud2FybigoKSA9PiBbXCJGYWlsZWQgdG8gcmVhcCBpZGxlIGRhdGFiYXNlIGNvbm5lY3Rpb25zOlwiLCBlcnJvcl0pXG4gICAgICB9KVxuICAgIH0sIGRlbGF5KVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIudW5yZWYgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyLnVucmVmKClcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciBhbiBpZGxlIHJlYXBlciB0aW1lciBzaG91bGQgYmUgc2NoZWR1bGVkLiAqL1xuICBoYXNJZGxlQ29ubmVjdGlvbnNUb1JlYXAoKSB7XG4gICAgcmV0dXJuIHRoaXMuY29ubmVjdGlvbnMubGVuZ3RoID4gMCAmJiB0aGlzLmlkbGVUaW1lb3V0TWlsbGlzKCkgIT09IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge251bWJlcn0gaWRsZVRpbWVvdXRNaWxsaXMgLSBJZGxlIHRpbWVvdXQgaW4gbWlsbGlzZWNvbmRzLlxuICAgKiBAcmV0dXJucyB7bnVtYmVyfSAtIERlbGF5IGJlZm9yZSB0aGUgbmV4dCByZWFwLlxuICAgKi9cbiAgbmV4dElkbGVDb25uZWN0aW9uUmVhcERlbGF5KGlkbGVUaW1lb3V0TWlsbGlzKSB7XG4gICAgbGV0IGRlbGF5ID0gaWRsZVRpbWVvdXRNaWxsaXNcbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpXG5cbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgdGhpcy5jb25uZWN0aW9ucykge1xuICAgICAgaWYgKHRoaXMuY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSkgY29udGludWVcblxuICAgICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICAgIGNvbnN0IGNoZWNrZWRJbkF0ID0gdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG5cbiAgICAgIGlmICh0eXBlb2YgY2hlY2tlZEluQXQgIT09IFwibnVtYmVyXCIpIGNvbnRpbnVlXG5cbiAgICAgIGRlbGF5ID0gTWF0aC5taW4oZGVsYXksIE1hdGgubWF4KDAsIGlkbGVUaW1lb3V0TWlsbGlzIC0gKG5vdyAtIGNoZWNrZWRJbkF0KSkpXG4gICAgfVxuXG4gICAgcmV0dXJuIGRlbGF5XG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGlkbGUgY2hlY2tlZC1pbiBjb25uZWN0aW9ucyB0aGF0IGhhdmUgZXhjZWVkZWQgdGhlIGNvbmZpZ3VyZWQgdGltZW91dC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIHJlYXBJZGxlQ29ubmVjdGlvbnMoKSB7XG4gICAgaWYgKHRoaXMuY29ubmVjdGlvbnMubGVuZ3RoID09PSAwKSByZXR1cm5cblxuICAgIGNvbnN0IGlkbGVUaW1lb3V0TWlsbGlzID0gdGhpcy5pZGxlVGltZW91dE1pbGxpcygpXG5cbiAgICBpZiAoaWRsZVRpbWVvdXRNaWxsaXMgPT09IG51bGwpIHJldHVyblxuXG4gICAgY29uc3Qge2V4cGlyZWRDb25uZWN0aW9ucywga2VwdENvbm5lY3Rpb25zfSA9IHRoaXMuY2xhc3NpZnlJZGxlQ29ubmVjdGlvbnNGb3JSZWFwaW5nKHtpZGxlVGltZW91dE1pbGxpcywgbm93OiBEYXRlLm5vdygpfSlcblxuICAgIHRoaXMuY29ubmVjdGlvbnMgPSBrZXB0Q29ubmVjdGlvbnNcbiAgICBhd2FpdCB0aGlzLmNsb3NlRXhwaXJlZElkbGVDb25uZWN0aW9ucyhleHBpcmVkQ29ubmVjdGlvbnMpXG4gICAgYXdhaXQgdGhpcy5hd2FpdEluZmxpZ2h0Q29ubmVjdGlvbkNsb3NlcygpXG4gICAgaWYgKHRoaXMuY29ubmVjdGlvbnMubGVuZ3RoID4gMCkgdGhpcy5zY2hlZHVsZUlkbGVDb25uZWN0aW9uUmVhcGVyKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W119IGV4cGlyZWRDb25uZWN0aW9ucyAtIENvbm5lY3Rpb25zIHRvIGNsb3NlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNsb3NlZC5cbiAgICovXG4gIGFzeW5jIGNsb3NlRXhwaXJlZElkbGVDb25uZWN0aW9ucyhleHBpcmVkQ29ubmVjdGlvbnMpIHtcbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgZXhwaXJlZENvbm5lY3Rpb25zKSB7XG4gICAgICBhd2FpdCB0aGlzLmNsb3NlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBvbmNlIGluLWZsaWdodCBjb25uZWN0aW9uIGNsb3NlcyBzZXR0bGUuICovXG4gIGFzeW5jIGF3YWl0SW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzKCkge1xuICAgIGlmICh0aGlzLmluZmxpZ2h0Q29ubmVjdGlvbkNsb3Nlcy5zaXplID4gMCkge1xuICAgICAgYXdhaXQgUHJvbWlzZS5hbGxTZXR0bGVkKFsuLi50aGlzLmluZmxpZ2h0Q29ubmVjdGlvbkNsb3Nlc10pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7e2lkbGVUaW1lb3V0TWlsbGlzOiBudW1iZXIsIG5vdzogbnVtYmVyfX0gYXJncyAtIFJlYXBlciBjbGFzc2lmaWNhdGlvbiBpbnB1dHMuXG4gICAqIEByZXR1cm5zIHt7ZXhwaXJlZENvbm5lY3Rpb25zOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdLCBrZXB0Q29ubmVjdGlvbnM6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W119fSAtIENsYXNzaWZpZWQgaWRsZSBjb25uZWN0aW9ucy5cbiAgICovXG4gIGNsYXNzaWZ5SWRsZUNvbm5lY3Rpb25zRm9yUmVhcGluZyh7aWRsZVRpbWVvdXRNaWxsaXMsIG5vd30pIHtcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W119ICovXG4gICAgY29uc3Qga2VwdENvbm5lY3Rpb25zID0gW11cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W119ICovXG4gICAgY29uc3QgZXhwaXJlZENvbm5lY3Rpb25zID0gW11cblxuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiB0aGlzLmNvbm5lY3Rpb25zKSB7XG4gICAgICB0aGlzLmNsYXNzaWZ5SWRsZUNvbm5lY3Rpb25Gb3JSZWFwaW5nKHtjb25uZWN0aW9uLCBleHBpcmVkQ29ubmVjdGlvbnMsIGlkbGVUaW1lb3V0TWlsbGlzLCBrZXB0Q29ubmVjdGlvbnMsIG5vd30pXG4gICAgfVxuXG4gICAgcmV0dXJuIHtleHBpcmVkQ29ubmVjdGlvbnMsIGtlcHRDb25uZWN0aW9uc31cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge3tjb25uZWN0aW9uOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCwgZXhwaXJlZENvbm5lY3Rpb25zOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdLCBpZGxlVGltZW91dE1pbGxpczogbnVtYmVyLCBrZXB0Q29ubmVjdGlvbnM6IGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W10sIG5vdzogbnVtYmVyfX0gYXJncyAtIENsYXNzaWZpY2F0aW9uIHN0YXRlLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIGNsYXNzaWZ5SWRsZUNvbm5lY3Rpb25Gb3JSZWFwaW5nKHtjb25uZWN0aW9uLCBleHBpcmVkQ29ubmVjdGlvbnMsIGlkbGVUaW1lb3V0TWlsbGlzLCBrZXB0Q29ubmVjdGlvbnMsIG5vd30pIHtcbiAgICBpZiAodGhpcy5jb25uZWN0aW9uSXNDbG9zZWQoY29ubmVjdGlvbikpIHJldHVyblxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIHtcbiAgICAgIGtlcHRDb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCB0YXJnZXQgPSB0aGlzLmlkbGVDb25uZWN0aW9uRXhwaXJlZCh7Y29ubmVjdGlvbiwgaWRsZVRpbWVvdXRNaWxsaXMsIG5vd30pID8gZXhwaXJlZENvbm5lY3Rpb25zIDoga2VwdENvbm5lY3Rpb25zXG5cbiAgICB0YXJnZXQucHVzaChjb25uZWN0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIGNvbm5lY3Rpb24gaXMgbWFya2VkIGNsb3NlZC5cbiAgICovXG4gIGNvbm5lY3Rpb25Jc0Nsb3NlZChjb25uZWN0aW9uKSB7XG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tDTE9TRURfQ09OTkVDVElPTl0/OiBib29sZWFufX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gQm9vbGVhbih0cmFja2VkQ29ubmVjdGlvbltDTE9TRURfQ09OTkVDVElPTl0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHt7Y29ubmVjdGlvbjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQsIGlkbGVUaW1lb3V0TWlsbGlzOiBudW1iZXIsIG5vdzogbnVtYmVyfX0gYXJncyAtIEV4cGlyeSBpbnB1dHMuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIGlkbGUgY29ubmVjdGlvbiBleHBpcmVkLlxuICAgKi9cbiAgaWRsZUNvbm5lY3Rpb25FeHBpcmVkKHtjb25uZWN0aW9uLCBpZGxlVGltZW91dE1pbGxpcywgbm93fSkge1xuICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG4gICAgY29uc3QgY2hlY2tlZEluQXQgPSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cblxuICAgIHJldHVybiB0eXBlb2YgY2hlY2tlZEluQXQgPT09IFwibnVtYmVyXCIgJiYgbm93IC0gY2hlY2tlZEluQXQgPj0gaWRsZVRpbWVvdXRNaWxsaXNcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBjb25uZWN0aW9uIGhhcyBhbiBvcGVuIHRyYW5zYWN0aW9uLlxuICAgKi9cbiAgY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuIGNvbm5lY3Rpb24uX3RyYW5zYWN0aW9uc0NvdW50ID4gMFxuICB9XG5cbiAgLyoqXG4gICAqIFJvbGxzIGJhY2sgYW55IHRyYW5zYWN0aW9uIGEgcHJldmlvdXMgaG9sZGVyIGxlZnQgb3BlbiBiZWZvcmUgYSBjb25uZWN0aW9uXG4gICAqIHJlLWVudGVycyB0aGUgaWRsZSBwb29sLiBBIGNvbm5lY3Rpb24gcmV0dXJuZWQgdG8gdGhlIHBvb2wgd2l0aCBhbiBvcGVuXG4gICAqIHRyYW5zYWN0aW9uIHdvdWxkIG90aGVyd2lzZSBiZSBoYW5kZWQgdG8gYW4gdW5yZWxhdGVkIGNoZWNrb3V0LCB3aG9zZVxuICAgKiBzdGFydFRyYW5zYWN0aW9uKCkgdGhlbiBmYWlscyB3aXRoIFwiQSB0cmFuc2FjdGlvbiBpcyBhbHJlYWR5IHJ1bm5pbmdcIiBhbmRcbiAgICogcG9pc29ucyBldmVyeSBmb2xsb3dpbmcgY2FsbGVyIHRoYXQgcmV1c2VzIGl0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiBiZWluZyBjaGVja2VkIGluLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHRoZSBjb25uZWN0aW9uIGhvbGRzIG5vIG9wZW4gdHJhbnNhY3Rpb24uXG4gICAqL1xuICBhc3luYyByb2xsYmFja0xlZnRPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikge1xuICAgIGlmICghdGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pKSByZXR1cm5cblxuICAgIHRoaXMubG9nZ2VyLndhcm4oKCkgPT4gW2BSb2xsaW5nIGJhY2sgYSB0cmFuc2FjdGlvbiBsZWZ0IG9wZW4gb24gYSBjb25uZWN0aW9uIGJlaW5nIGNoZWNrZWQgaW4gKGlkZW50aWZpZXI9JHt0aGlzLmlkZW50aWZpZXJ9KS5gXSlcblxuICAgIHdoaWxlICh0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIHtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucm9sbGJhY2tUcmFuc2FjdGlvbigpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRvIGNsb3NlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAvLyBJZGVtcG90ZW50OiBhIGZpcmUtYW5kLWZvcmdldCBzY2hlZHVsZWQgcmVhcCBhbmQgYW4gZXhwbGljaXQgcmVhcCBjYW4gYm90aFxuICAgIC8vIHRhcmdldCB0aGUgc2FtZSBjb25uZWN0aW9uLiBBd2FpdCB0aGUgaW4tZmxpZ2h0IGNsb3NlIGluc3RlYWQgb2YgY2xvc2luZ1xuICAgIC8vIHR3aWNlICh3aGljaCBjYW4gdGhyb3cgb24gdGhlIGRyaXZlcikgb3IgcmV0dXJuaW5nIHdoaWxlIHRoZSB1bmRlcmx5aW5nXG4gICAgLy8gaGFuZGxlIGlzIHN0aWxsIG9wZW4uXG4gICAgY29uc3QgZXhpc3RpbmdDbG9zZSA9IHRoaXMuY29ubmVjdGlvbkNsb3NlUHJvbWlzZXMuZ2V0KGNvbm5lY3Rpb24pXG5cbiAgICBpZiAoZXhpc3RpbmdDbG9zZSkge1xuICAgICAgcmV0dXJuIGF3YWl0IGV4aXN0aW5nQ2xvc2VcbiAgICB9XG5cbiAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0NMT1NFRF9DT05ORUNUSU9OXT86IGJvb2xlYW4sIFtDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXT86IG51bWJlciwgW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuXG4gICAgdHJhY2tlZENvbm5lY3Rpb25bQ0xPU0VEX0NPTk5FQ1RJT05dID0gdHJ1ZVxuICAgIGRlbGV0ZSB0cmFja2VkQ29ubmVjdGlvbltDT05ORUNUSU9OX0NIRUNLRURfT1VUX0FUXVxuICAgIGRlbGV0ZSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cblxuICAgIGNvbnN0IGNsb3NlUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBhd2FpdCB0cmFja2VkQ29ubmVjdGlvbi5jbG9zZSgpXG4gICAgfSkoKVxuXG4gICAgdGhpcy5jb25uZWN0aW9uQ2xvc2VQcm9taXNlcy5zZXQoY29ubmVjdGlvbiwgY2xvc2VQcm9taXNlKVxuICAgIHRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzLmFkZChjbG9zZVByb21pc2UpXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY2xvc2VQcm9taXNlXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzLmRlbGV0ZShjbG9zZVByb21pc2UpXG4gICAgfVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHt2b2lkfSAqL1xuICBjbGVhcklkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIoKSB7XG4gICAgaWYgKCF0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIpIHJldHVyblxuXG4gICAgY2xlYXJUaW1lb3V0KHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lcilcbiAgICB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgYWxsIGFjdGl2ZSBhbmQgY2FjaGVkIGNvbm5lY3Rpb25zIGZvciB0aGlzIHBvb2wuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjbG9zZUFsbCgpIHtcbiAgICB0aGlzLmNsZWFySWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lcigpXG4gICAgdGhpcy5yZWplY3RQZW5kaW5nQ2hlY2tvdXRzKG5ldyBFcnJvcihcIkRhdGFiYXNlIHBvb2wgd2FzIGNsb3NlZCBiZWZvcmUgY2hlY2tvdXQgY29tcGxldGVkLlwiKSlcblxuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldChbXG4gICAgICAuLi50aGlzLmNvbm5lY3Rpb25zLFxuICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpLFxuICAgICAgdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpLFxuICAgICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb25cbiAgICBdLmZpbHRlcihCb29sZWFuKSlcblxuICAgIHRoaXMuY29ubmVjdGlvbnMgPSBbXVxuICAgIHRoaXMuY29ubmVjdGlvbnNJblVzZSA9IHt9XG4gICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24gPSB1bmRlZmluZWRcbiAgICB0aGlzLmNsZWFyR2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKVxuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICBpZiAoIWNvbm5lY3Rpb24pIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG4gICAgfVxuXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFcnJvcn0gZXJyb3IgLSBFcnJvciB0byByZWplY3QgcGVuZGluZyBjaGVja291dHMgd2l0aC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZWplY3RQZW5kaW5nQ2hlY2tvdXRzKGVycm9yKSB7XG4gICAgY29uc3QgcGVuZGluZ0NoZWNrb3V0cyA9IHRoaXMucGVuZGluZ0NoZWNrb3V0c1xuXG4gICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXRzID0gW11cblxuICAgIGZvciAoY29uc3QgY2hlY2tvdXQgb2YgcGVuZGluZ0NoZWNrb3V0cykge1xuICAgICAgY2hlY2tvdXQucmVqZWN0KGVycm9yKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhbGwgZ2xvYmFsbHkgcmVnaXN0ZXJlZCBmYWxsYmFjayBjb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IFtjb25uZWN0aW9uc10gLSBDb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IFtjb25maWd1cmF0aW9uXSAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHN0YXRpYyBzZXRHbG9iYWxDb25uZWN0aW9ucyhjb25uZWN0aW9ucywgY29uZmlndXJhdGlvbikge1xuICAgIGlmICghY29uZmlndXJhdGlvbikge1xuICAgICAgdGhpcy5nbG9iYWxDb25uZWN0aW9ucyA9IG5ldyBXZWFrTWFwKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMuc2V0KGNvbmZpZ3VyYXRpb24sIGNvbm5lY3Rpb25zIHx8IHt9KVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyBnbG9iYWxseSByZWdpc3RlcmVkIGZhbGxiYWNrIGNvbm5lY3Rpb25zIGZvciBhbGwgY29uZmlndXJhdGlvbnMgb3IgYSBzaW5nbGUgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IFtjb25maWd1cmF0aW9uXSAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHN0YXRpYyBjbGVhckdsb2JhbENvbm5lY3Rpb25zKGNvbmZpZ3VyYXRpb24pIHtcbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmdsb2JhbENvbm5lY3Rpb25zLmRlbGV0ZShjb25maWd1cmF0aW9uKVxuICB9XG59XG4iXX0=