velocious 1.0.410 → 1.0.411
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +1 -0
- package/build/src/background-jobs/job-runner.js +2 -2
- package/build/src/background-jobs/store.js +3 -3
- package/build/src/background-jobs/worker.js +2 -2
- package/build/src/cli/commands/db/migrate.js +2 -2
- package/build/src/cli/commands/db/reset.js +2 -2
- package/build/src/cli/commands/db/rollback.js +2 -2
- package/build/src/cli/commands/db/tenants/check.js +2 -2
- package/build/src/cli/commands/db/tenants/migrate.js +2 -2
- package/build/src/cli/tenant-database-command-helper.js +2 -2
- package/build/src/configuration.d.ts +12 -4
- package/build/src/configuration.d.ts.map +1 -1
- package/build/src/configuration.js +25 -9
- package/build/src/database/annotations-async-hooks.d.ts +2 -0
- package/build/src/database/annotations-async-hooks.d.ts.map +1 -0
- package/build/src/database/annotations-async-hooks.js +34 -0
- package/build/src/database/annotations.d.ts +15 -0
- package/build/src/database/annotations.d.ts.map +1 -0
- package/build/src/database/annotations.js +27 -0
- package/build/src/database/drivers/base.d.ts +31 -2
- package/build/src/database/drivers/base.d.ts.map +1 -1
- package/build/src/database/drivers/base.js +64 -9
- package/build/src/database/drivers/mysql/index.d.ts.map +1 -1
- package/build/src/database/drivers/mysql/index.js +14 -1
- package/build/src/database/drivers/pgsql/index.d.ts.map +1 -1
- package/build/src/database/drivers/pgsql/index.js +19 -1
- package/build/src/database/migrator.js +3 -3
- package/build/src/database/pool/async-tracked-multi-connection.d.ts +23 -3
- package/build/src/database/pool/async-tracked-multi-connection.d.ts.map +1 -1
- package/build/src/database/pool/async-tracked-multi-connection.js +84 -25
- package/build/src/database/pool/base.d.ts +11 -3
- package/build/src/database/pool/base.d.ts.map +1 -1
- package/build/src/database/pool/base.js +10 -4
- package/build/src/database/pool/single-multi-use.d.ts +5 -0
- package/build/src/database/pool/single-multi-use.d.ts.map +1 -1
- package/build/src/database/pool/single-multi-use.js +22 -9
- package/build/src/database/record/attachments/store.js +2 -2
- package/build/src/database/record/index.js +2 -2
- package/build/src/database/use-database.js +2 -2
- package/build/src/environment-handlers/node/cli/commands/db/schema/dump.js +2 -2
- package/build/src/environment-handlers/node/cli/commands/db/schema/load.js +2 -2
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +2 -2
- package/build/src/environment-handlers/node.d.ts.map +1 -1
- package/build/src/environment-handlers/node.js +2 -1
- package/build/src/frontend-model-controller.js +2 -2
- package/build/src/frontend-models/websocket-channel.js +2 -2
- package/build/src/http-server/client/websocket-session.js +2 -2
- package/build/src/http-server/websocket-event-log-store.js +2 -2
- package/build/src/routes/resolver.js +2 -2
- package/build/src/templates/configuration.js +1 -1
- package/build/src/testing/test-runner.js +4 -4
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
|
@@ -2,6 +2,7 @@ export const CLOSED_CONNECTION: unique symbol;
|
|
|
2
2
|
/**
|
|
3
3
|
* @typedef {object} PendingCheckout
|
|
4
4
|
* @property {import("../../configuration-types.js").DatabaseConfigurationType} databaseConfig - Resolved database configuration needed by the checkout.
|
|
5
|
+
* @property {import("./base.js").ConnectionCheckoutOptions} options - Checkout options.
|
|
5
6
|
* @property {string} reuseKey - Database configuration reuse key needed by the checkout.
|
|
6
7
|
* @property {(connection: import("../drivers/base.js").default) => void} resolve - Resolves with an activated connection.
|
|
7
8
|
* @property {(error: Error) => void} reject - Rejects when checkout cannot complete.
|
|
@@ -84,9 +85,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
84
85
|
connectionMatchesReuseKey(connection: import("../drivers/base.js").default, reuseKey: string): boolean;
|
|
85
86
|
/**
|
|
86
87
|
* @param {import("../drivers/base.js").default} connection - Connection.
|
|
87
|
-
* @
|
|
88
|
+
* @param {import("./base.js").ConnectionCheckoutOptions} [options] - Checkout options.
|
|
89
|
+
* @returns {Promise<import("../drivers/base.js").default>} - Activated connection.
|
|
88
90
|
*/
|
|
89
|
-
activateConnection(connection: import("../drivers/base.js").default): import("../drivers/base.js").default
|
|
91
|
+
activateConnection(connection: import("../drivers/base.js").default, options?: import("./base.js").ConnectionCheckoutOptions): Promise<import("../drivers/base.js").default>;
|
|
90
92
|
/** @returns {number | undefined} - Configured max live connections. */
|
|
91
93
|
maxConnections(): number | undefined;
|
|
92
94
|
/** @returns {number} - Number of live and in-progress connections. */
|
|
@@ -102,13 +104,25 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
102
104
|
/**
|
|
103
105
|
* @param {import("../../configuration-types.js").DatabaseConfigurationType} databaseConfig - Resolved database config for the checkout.
|
|
104
106
|
* @param {string} reuseKey - Database configuration reuse key.
|
|
107
|
+
* @param {import("./base.js").ConnectionCheckoutOptions} [options] - Checkout options.
|
|
105
108
|
* @returns {Promise<import("../drivers/base.js").default>} - Resolves with an activated connection.
|
|
106
109
|
*/
|
|
107
|
-
waitForCheckout(databaseConfig: import("../../configuration-types.js").DatabaseConfigurationType, reuseKey: string): Promise<import("../drivers/base.js").default>;
|
|
110
|
+
waitForCheckout(databaseConfig: import("../../configuration-types.js").DatabaseConfigurationType, reuseKey: string, options?: import("./base.js").ConnectionCheckoutOptions): Promise<import("../drivers/base.js").default>;
|
|
108
111
|
/** @returns {Promise<void>} - Resolves when pending checkouts have been drained as far as possible. */
|
|
109
112
|
drainPendingCheckouts(): Promise<void>;
|
|
110
113
|
/** @returns {Promise<void>} - Resolves when pending checkouts have been drained as far as possible. */
|
|
111
114
|
drainPendingCheckoutsActual(): Promise<void>;
|
|
115
|
+
/**
|
|
116
|
+
* @param {PendingCheckout} checkout - Checkout request to resolve.
|
|
117
|
+
* @returns {Promise<void>} - Resolves when the checkout has been handled.
|
|
118
|
+
*/
|
|
119
|
+
spawnAndResolvePendingCheckout(checkout: PendingCheckout): Promise<void>;
|
|
120
|
+
/**
|
|
121
|
+
* @param {PendingCheckout} checkout - Checkout request to resolve.
|
|
122
|
+
* @param {import("../drivers/base.js").default} connection - Connection to activate.
|
|
123
|
+
* @returns {Promise<void>} - Resolves when the checkout has been handled.
|
|
124
|
+
*/
|
|
125
|
+
resolvePendingCheckout(checkout: PendingCheckout, connection: import("../drivers/base.js").default): Promise<void>;
|
|
112
126
|
/** @returns {Promise<boolean>} - Whether an idle connection was closed to free capacity. */
|
|
113
127
|
closeOneIdleConnectionForCapacity(): Promise<boolean>;
|
|
114
128
|
/**
|
|
@@ -134,6 +148,8 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
134
148
|
* @returns {import("../drivers/base.js").default | undefined} - The global connection for this pool identifier.
|
|
135
149
|
*/
|
|
136
150
|
getGlobalConnectionForIdentifier(): import("../drivers/base.js").default | undefined;
|
|
151
|
+
/** @returns {void} - No return value. */
|
|
152
|
+
clearGlobalConnectionForIdentifier(): void;
|
|
137
153
|
/** @returns {number | null} - Idle timeout in milliseconds, or null when disabled. */
|
|
138
154
|
idleTimeoutMillis(): number | null;
|
|
139
155
|
/** @returns {void} */
|
|
@@ -181,6 +197,10 @@ export type PendingCheckout = {
|
|
|
181
197
|
* - Resolved database configuration needed by the checkout.
|
|
182
198
|
*/
|
|
183
199
|
databaseConfig: import("../../configuration-types.js").DatabaseConfigurationType;
|
|
200
|
+
/**
|
|
201
|
+
* - Checkout options.
|
|
202
|
+
*/
|
|
203
|
+
options: import("./base.js").ConnectionCheckoutOptions;
|
|
184
204
|
/**
|
|
185
205
|
* - Database configuration reuse key needed by the checkout.
|
|
186
206
|
*/
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"async-tracked-multi-connection.d.ts","sourceRoot":"","sources":["../../../../src/database/pool/async-tracked-multi-connection.js"],"names":[],"mappings":"AAKA,8CAAoE;AAIpE
|
|
1
|
+
{"version":3,"file":"async-tracked-multi-connection.d.ts","sourceRoot":"","sources":["../../../../src/database/pool/async-tracked-multi-connection.js"],"names":[],"mappings":"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"}
|
|
@@ -7,6 +7,7 @@ const DEFAULT_IDLE_TIMEOUT_MILLIS = 5000;
|
|
|
7
7
|
/**
|
|
8
8
|
* @typedef {object} PendingCheckout
|
|
9
9
|
* @property {import("../../configuration-types.js").DatabaseConfigurationType} databaseConfig - Resolved database configuration needed by the checkout.
|
|
10
|
+
* @property {import("./base.js").ConnectionCheckoutOptions} options - Checkout options.
|
|
10
11
|
* @property {string} reuseKey - Database configuration reuse key needed by the checkout.
|
|
11
12
|
* @property {(connection: import("../drivers/base.js").default) => void} resolve - Resolves with an activated connection.
|
|
12
13
|
* @property {(error: Error) => void} reject - Rejects when checkout cannot complete.
|
|
@@ -79,6 +80,13 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
79
80
|
if (trackedConnection[CLOSED_CONNECTION])
|
|
80
81
|
return;
|
|
81
82
|
await this.rollbackLeftOpenTransaction(connection);
|
|
83
|
+
try {
|
|
84
|
+
await connection.clearConnectionCheckoutName();
|
|
85
|
+
}
|
|
86
|
+
catch (error) {
|
|
87
|
+
await this.closeConnection(connection);
|
|
88
|
+
throw error;
|
|
89
|
+
}
|
|
82
90
|
trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT] = Date.now();
|
|
83
91
|
this.connections.push(connection);
|
|
84
92
|
await this.drainPendingCheckouts();
|
|
@@ -89,17 +97,20 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
89
97
|
this.scheduleIdleConnectionReaper();
|
|
90
98
|
}
|
|
91
99
|
}
|
|
92
|
-
/**
|
|
93
|
-
|
|
100
|
+
/**
|
|
101
|
+
* @param {import("./base.js").ConnectionCheckoutOptions} [options] - Checkout options.
|
|
102
|
+
* @returns {Promise<import("../drivers/base.js").default>} - Resolves with the checkout.
|
|
103
|
+
*/
|
|
104
|
+
async checkout(options = {}) {
|
|
94
105
|
const databaseConfig = this.getConfiguration();
|
|
95
106
|
const reuseKey = this.getConfigurationReuseKey();
|
|
96
107
|
let connection = this.takeIdleConnectionForReuseKey(reuseKey);
|
|
97
108
|
if (connection)
|
|
98
|
-
return this.activateConnection(connection);
|
|
109
|
+
return await this.activateConnection(connection, options);
|
|
99
110
|
await this.reapIdleConnections();
|
|
100
111
|
connection = this.takeIdleConnectionForReuseKey(reuseKey);
|
|
101
112
|
if (connection)
|
|
102
|
-
return this.activateConnection(connection);
|
|
113
|
+
return await this.activateConnection(connection, options);
|
|
103
114
|
if (this.canSpawnConnection()) {
|
|
104
115
|
// Spawn via spawnConnection() so the tenant-aware configuration is resolved FRESH at
|
|
105
116
|
// spawn time for the current caller. Reusing the databaseConfig captured at the top of
|
|
@@ -107,9 +118,9 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
107
118
|
// per-request isolation (e.g. test truncation appearing not to take effect). The queued
|
|
108
119
|
// path below keeps the waiting caller's captured config via waitForCheckout().
|
|
109
120
|
connection = await this.spawnConnection();
|
|
110
|
-
return this.activateConnection(connection);
|
|
121
|
+
return await this.activateConnection(connection, options);
|
|
111
122
|
}
|
|
112
|
-
return await this.waitForCheckout(databaseConfig, reuseKey);
|
|
123
|
+
return await this.waitForCheckout(databaseConfig, reuseKey, options);
|
|
113
124
|
}
|
|
114
125
|
/**
|
|
115
126
|
* @param {string} reuseKey - Database configuration reuse key.
|
|
@@ -137,9 +148,10 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
137
148
|
}
|
|
138
149
|
/**
|
|
139
150
|
* @param {import("../drivers/base.js").default} connection - Connection.
|
|
140
|
-
* @
|
|
151
|
+
* @param {import("./base.js").ConnectionCheckoutOptions} [options] - Checkout options.
|
|
152
|
+
* @returns {Promise<import("../drivers/base.js").default>} - Activated connection.
|
|
141
153
|
*/
|
|
142
|
-
activateConnection(connection) {
|
|
154
|
+
async activateConnection(connection, options = {}) {
|
|
143
155
|
if (connection.getIdSeq() !== undefined)
|
|
144
156
|
throw new Error(`Connection already has an ID-seq - is it in use? ${connection.getIdSeq()}`);
|
|
145
157
|
const id = this.idSeq++;
|
|
@@ -147,6 +159,15 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
147
159
|
delete trackedConnection[IDLE_CONNECTION_CHECKED_IN_AT];
|
|
148
160
|
connection.setIdSeq(id);
|
|
149
161
|
this.connectionsInUse[id] = connection;
|
|
162
|
+
try {
|
|
163
|
+
await connection.setConnectionCheckoutName(options.name);
|
|
164
|
+
}
|
|
165
|
+
catch (error) {
|
|
166
|
+
delete this.connectionsInUse[id];
|
|
167
|
+
connection.setIdSeq(undefined);
|
|
168
|
+
await this.closeConnection(connection);
|
|
169
|
+
throw error;
|
|
170
|
+
}
|
|
150
171
|
return connection;
|
|
151
172
|
}
|
|
152
173
|
/** @returns {number | undefined} - Configured max live connections. */
|
|
@@ -191,11 +212,12 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
191
212
|
/**
|
|
192
213
|
* @param {import("../../configuration-types.js").DatabaseConfigurationType} databaseConfig - Resolved database config for the checkout.
|
|
193
214
|
* @param {string} reuseKey - Database configuration reuse key.
|
|
215
|
+
* @param {import("./base.js").ConnectionCheckoutOptions} [options] - Checkout options.
|
|
194
216
|
* @returns {Promise<import("../drivers/base.js").default>} - Resolves with an activated connection.
|
|
195
217
|
*/
|
|
196
|
-
async waitForCheckout(databaseConfig, reuseKey) {
|
|
218
|
+
async waitForCheckout(databaseConfig, reuseKey, options = {}) {
|
|
197
219
|
return await new Promise((resolve, reject) => {
|
|
198
|
-
this.pendingCheckouts.push({ databaseConfig, reject, resolve, reuseKey });
|
|
220
|
+
this.pendingCheckouts.push({ databaseConfig, options, reject, resolve, reuseKey });
|
|
199
221
|
void this.drainPendingCheckouts().catch((error) => {
|
|
200
222
|
const checkoutError = error instanceof Error ? error : new Error("Failed to drain pending database connection checkouts.", { cause: error });
|
|
201
223
|
this.rejectPendingCheckouts(checkoutError);
|
|
@@ -232,20 +254,41 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
232
254
|
}
|
|
233
255
|
if (!connection && this.canSpawnConnection()) {
|
|
234
256
|
this.pendingCheckouts.shift();
|
|
235
|
-
|
|
236
|
-
connection = await this.spawnConnectionForCheckout(checkout.databaseConfig, checkout.reuseKey);
|
|
237
|
-
}
|
|
238
|
-
catch (error) {
|
|
239
|
-
checkout.reject(error instanceof Error ? error : new Error("Failed to spawn database connection.", { cause: error }));
|
|
240
|
-
continue;
|
|
241
|
-
}
|
|
242
|
-
checkout.resolve(this.activateConnection(connection));
|
|
257
|
+
await this.spawnAndResolvePendingCheckout(checkout);
|
|
243
258
|
continue;
|
|
244
259
|
}
|
|
245
260
|
if (!connection)
|
|
246
261
|
return;
|
|
247
262
|
this.pendingCheckouts.shift();
|
|
248
|
-
|
|
263
|
+
await this.resolvePendingCheckout(checkout, connection);
|
|
264
|
+
}
|
|
265
|
+
}
|
|
266
|
+
/**
|
|
267
|
+
* @param {PendingCheckout} checkout - Checkout request to resolve.
|
|
268
|
+
* @returns {Promise<void>} - Resolves when the checkout has been handled.
|
|
269
|
+
*/
|
|
270
|
+
async spawnAndResolvePendingCheckout(checkout) {
|
|
271
|
+
let connection;
|
|
272
|
+
try {
|
|
273
|
+
connection = await this.spawnConnectionForCheckout(checkout.databaseConfig, checkout.reuseKey);
|
|
274
|
+
}
|
|
275
|
+
catch (error) {
|
|
276
|
+
checkout.reject(error instanceof Error ? error : new Error("Failed to spawn database connection.", { cause: error }));
|
|
277
|
+
return;
|
|
278
|
+
}
|
|
279
|
+
await this.resolvePendingCheckout(checkout, connection);
|
|
280
|
+
}
|
|
281
|
+
/**
|
|
282
|
+
* @param {PendingCheckout} checkout - Checkout request to resolve.
|
|
283
|
+
* @param {import("../drivers/base.js").default} connection - Connection to activate.
|
|
284
|
+
* @returns {Promise<void>} - Resolves when the checkout has been handled.
|
|
285
|
+
*/
|
|
286
|
+
async resolvePendingCheckout(checkout, connection) {
|
|
287
|
+
try {
|
|
288
|
+
checkout.resolve(await this.activateConnection(connection, checkout.options));
|
|
289
|
+
}
|
|
290
|
+
catch (error) {
|
|
291
|
+
checkout.reject(error instanceof Error ? error : new Error("Failed to activate database connection.", { cause: error }));
|
|
249
292
|
}
|
|
250
293
|
}
|
|
251
294
|
/** @returns {Promise<boolean>} - Whether an idle connection was closed to free capacity. */
|
|
@@ -259,15 +302,20 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
259
302
|
}
|
|
260
303
|
/**
|
|
261
304
|
* @template T
|
|
262
|
-
* @param {function(import("../drivers/base.js").default) : Promise<T>}
|
|
305
|
+
* @param {import("./base.js").ConnectionCheckoutOptions | function(import("../drivers/base.js").default) : Promise<T>} optionsOrCallback - Checkout options or callback to invoke with the connection.
|
|
306
|
+
* @param {function(import("../drivers/base.js").default) : Promise<T>} [callback] - Callback to invoke with the connection.
|
|
263
307
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
264
308
|
*/
|
|
265
|
-
async withConnection(callback) {
|
|
266
|
-
const
|
|
309
|
+
async withConnection(optionsOrCallback, callback) {
|
|
310
|
+
const options = typeof optionsOrCallback == "function" ? {} : optionsOrCallback;
|
|
311
|
+
const actualCallback = typeof optionsOrCallback == "function" ? optionsOrCallback : callback;
|
|
312
|
+
if (!actualCallback)
|
|
313
|
+
throw new Error("withConnection requires a callback");
|
|
314
|
+
const connection = await this.checkout(options);
|
|
267
315
|
const id = connection.getIdSeq();
|
|
268
316
|
return await this.asyncLocalStorage.run(id, async () => {
|
|
269
317
|
try {
|
|
270
|
-
return await
|
|
318
|
+
return await actualCallback(connection);
|
|
271
319
|
}
|
|
272
320
|
finally {
|
|
273
321
|
await this.checkin(connection);
|
|
@@ -364,6 +412,14 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
364
412
|
const mapForConfiguration = klass.globalConnections.get(this.configuration);
|
|
365
413
|
return mapForConfiguration?.[this.identifier];
|
|
366
414
|
}
|
|
415
|
+
/** @returns {void} - No return value. */
|
|
416
|
+
clearGlobalConnectionForIdentifier() {
|
|
417
|
+
const klass = /** @type {typeof VelociousDatabasePoolAsyncTrackedMultiConnection} */ (this.constructor);
|
|
418
|
+
const mapForConfiguration = klass.globalConnections.get(this.configuration);
|
|
419
|
+
if (!mapForConfiguration)
|
|
420
|
+
return;
|
|
421
|
+
delete mapForConfiguration[this.identifier];
|
|
422
|
+
}
|
|
367
423
|
/**
|
|
368
424
|
* Clears schema metadata cached by every live connection owned by this pool.
|
|
369
425
|
* @returns {void} - No return value.
|
|
@@ -549,10 +605,13 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
549
605
|
const connections = new Set([
|
|
550
606
|
...this.connections,
|
|
551
607
|
...Object.values(this.connectionsInUse),
|
|
552
|
-
this.
|
|
608
|
+
this.getGlobalConnectionForIdentifier(),
|
|
609
|
+
this._testSharedConnection
|
|
553
610
|
].filter(Boolean));
|
|
554
611
|
this.connections = [];
|
|
555
612
|
this.connectionsInUse = {};
|
|
613
|
+
this._testSharedConnection = undefined;
|
|
614
|
+
this.clearGlobalConnectionForIdentifier();
|
|
556
615
|
for (const connection of connections) {
|
|
557
616
|
if (!connection)
|
|
558
617
|
continue;
|
|
@@ -600,4 +659,4 @@ export default class VelociousDatabasePoolAsyncTrackedMultiConnection extends Ba
|
|
|
600
659
|
this.globalConnections.delete(configuration);
|
|
601
660
|
}
|
|
602
661
|
}
|
|
603
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RhdGFiYXNlL3Bvb2wvYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDN0MsT0FBTyxRQUFRLEVBQUUsRUFBQyxzQkFBc0IsRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUUxRCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtBQUNwRSxNQUFNLDZCQUE2QixHQUFHLE1BQU0sQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFBO0FBQ2xGLE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxDQUFBO0FBRXhDOzs7Ozs7R0FNRztBQUVILE1BQU0sQ0FBQyxPQUFPLE9BQU8sZ0RBQWlELFNBQVEsUUFBUTtJQUNwRjs7O09BR0c7SUFDSCxNQUFNLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQTtJQUV4QyxpQkFBaUIsR0FBRyxJQUFJLGlCQUFpQixFQUFFLENBQUE7SUFFM0M7Ozs7O09BS0c7SUFDSCxxQkFBcUIsR0FBRyxTQUFTLENBQUE7SUFFakMscURBQXFEO0lBQ3JELFdBQVcsR0FBRyxFQUFFLENBQUE7SUFFaEIsbUVBQW1FO0lBQ25FLGdCQUFnQixHQUFHLEVBQUUsQ0FBQTtJQUVyQixnQ0FBZ0M7SUFDaEMsZ0JBQWdCLEdBQUcsRUFBRSxDQUFBO0lBRXJCLHFCQUFxQjtJQUNyQix1QkFBdUIsR0FBRyxDQUFDLENBQUE7SUFFM0Isd0NBQXdDO0lBQ3hDLDJCQUEyQixHQUFHLFNBQVMsQ0FBQTtJQUV2Qyx3REFBd0Q7SUFDeEQseUJBQXlCLEdBQUcsU0FBUyxDQUFBO0lBRXJDOzs7Ozs7OztPQVFHO0lBQ0gsd0JBQXdCLEdBQUcs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OztPQUlHO0lBQ0gsTUFBTSxDQUFDLHNCQUFzQixDQUFDLGFBQWE7UUFDekMsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ25CLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFBO1lBQ3RDLE9BQU07UUFDUixDQUFDO1FBRUQsSUFBSSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7QXN5bmNMb2NhbFN0b3JhZ2V9IGZyb20gXCJhc3luY19ob29rc1wiXG5pbXBvcnQgQmFzZVBvb2wsIHtQT09MX0NPTkZJR1VSQVRJT05fS0VZfSBmcm9tIFwiLi9iYXNlLmpzXCJcblxuZXhwb3J0IGNvbnN0IENMT1NFRF9DT05ORUNUSU9OID0gU3ltYm9sKFwidmVsb2Npb3VzQ2xvc2VkQ29ubmVjdGlvblwiKVxuY29uc3QgSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVQgPSBTeW1ib2woXCJ2ZWxvY2lvdXNJZGxlQ29ubmVjdGlvbkNoZWNrZWRJbkF0XCIpXG5jb25zdCBERUZBVUxUX0lETEVfVElNRU9VVF9NSUxMSVMgPSA1MDAwXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gUGVuZGluZ0NoZWNrb3V0XG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRGF0YWJhc2VDb25maWd1cmF0aW9uVHlwZX0gZGF0YWJhc2VDb25maWcgLSBSZXNvbHZlZCBkYXRhYmFzZSBjb25maWd1cmF0aW9uIG5lZWRlZCBieSB0aGUgY2hlY2tvdXQuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleSBuZWVkZWQgYnkgdGhlIGNoZWNrb3V0LlxuICogQHByb3BlcnR5IHsoY29ubmVjdGlvbjogaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpID0+IHZvaWR9IHJlc29sdmUgLSBSZXNvbHZlcyB3aXRoIGFuIGFjdGl2YXRlZCBjb25uZWN0aW9uLlxuICogQHByb3BlcnR5IHsoZXJyb3I6IEVycm9yKSA9PiB2b2lkfSByZWplY3QgLSBSZWplY3RzIHdoZW4gY2hlY2tvdXQgY2Fubm90IGNvbXBsZXRlLlxuICovXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFZlbG9jaW91c0RhdGFiYXNlUG9vbEFzeW5jVHJhY2tlZE11bHRpQ29ubmVjdGlvbiBleHRlbmRzIEJhc2VQb29sIHtcbiAgLyoqXG4gICAqIEdsb2JhbCBmYWxsYmFjayBjb25uZWN0aW9ucyBrZXllZCBieSBjb25maWd1cmF0aW9uIGluc3RhbmNlIGFuZCBwb29sIGlkZW50aWZpZXIuXG4gICAqIEB0eXBlIHtXZWFrTWFwPGltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdCwgUmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+Pn1cbiAgICovXG4gIHN0YXRpYyBnbG9iYWxDb25uZWN0aW9ucyA9IG5ldyBXZWFrTWFwKClcblxuICBhc3luY0xvY2FsU3RvcmFnZSA9IG5ldyBBc3luY0xvY2FsU3RvcmFnZSgpXG5cbiAgLyoqXG4gICAqIFdoZW4gc2V0LCByZXR1cm5lZCBieSBnZXRDdXJyZW50Q29udGV4dENvbm5lY3Rpb24gd2hlbiBubyBhc3luYyBjb250ZXh0IGV4aXN0cy5cbiAgICogVXNlZCBieSB0aGUgdGVzdCBydW5uZXIgdG8gc2hhcmUgYSBjb25uZWN0aW9uIGJldHdlZW4gdGVzdCBjb2RlIGFuZCBIVFRQIGhhbmRsZXJzXG4gICAqIHJ1bm5pbmcgaW4gdGhlIHNhbWUgcHJvY2VzcyAoaW4tcHJvY2VzcyB0ZXN0IHNlcnZlciBtb2RlKS5cbiAgICogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfVxuICAgKi9cbiAgX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gdW5kZWZpbmVkXG5cbiAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSAqL1xuICBjb25uZWN0aW9ucyA9IFtdXG5cbiAgLyoqIEB0eXBlIHtSZWNvcmQ8bnVtYmVyLCBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59ICovXG4gIGNvbm5lY3Rpb25zSW5Vc2UgPSB7fVxuXG4gIC8qKiBAdHlwZSB7UGVuZGluZ0NoZWNrb3V0W119ICovXG4gIHBlbmRpbmdDaGVja291dHMgPSBbXVxuXG4gIC8qKiBAdHlwZSB7bnVtYmVyfSAqL1xuICBjb25uZWN0aW9uc0JlaW5nU3Bhd25lZCA9IDBcblxuICAvKiogQHR5cGUge1Byb21pc2U8dm9pZD4gfCB1bmRlZmluZWR9ICovXG4gIHBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZSA9IHVuZGVmaW5lZFxuXG4gIC8qKiBAdHlwZSB7UmV0dXJuVHlwZTx0eXBlb2Ygc2V0VGltZW91dD4gfCB1bmRlZmluZWR9ICovXG4gIGlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSB1bmRlZmluZWRcblxuICAvKipcbiAgICogSW4tZmxpZ2h0IGNvbm5lY3Rpb24tY2xvc2UgcHJvbWlzZXMuIFRoZSBpZGxlIHJlYXBlciBpcyBhcm1lZCBvbiBjaGVjay1pblxuICAgKiBhbmQgcnVucyBmaXJlLWFuZC1mb3JnZXQgd2hlbiBpdHMgdGltZXIgZmlyZXMsIHNvIGEgc2NoZWR1bGVkIHJlYXAgY2FuIGJlXG4gICAqIGNsb3NpbmcgYSBjb25uZWN0aW9uIHdoaWxlIGFuIGV4cGxpY2l0IGByZWFwSWRsZUNvbm5lY3Rpb25zKClgIChvclxuICAgKiBgY2xlYXJJZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKClgKSBydW5zLiBUcmFja2luZyB0aGUgaW4tZmxpZ2h0IGNsb3NlcyBsZXRzXG4gICAqIHRob3NlIGNhbGxlcnMgYXdhaXQgdGhlbSwgc28gb25jZSBhIHJlYXAgcmVzb2x2ZXMgdGhlIGNvbm5lY3Rpb25zIGl0XG4gICAqIGV4cGlyZWQgYXJlIGZ1bGx5IGNsb3NlZCBpbnN0ZWFkIG9mIGhhbGYtY2xvc2VkIG1pZC1gY2xvc2UoKWAuXG4gICAqIEB0eXBlIHtTZXQ8UHJvbWlzZTx2b2lkPj59XG4gICAqL1xuICBpbmZsaWdodENvbm5lY3Rpb25DbG9zZXMgPSBuZXcgU2V0KClcblxuICAvKipcbiAgICogSW4tZmxpZ2h0IGNsb3NlIHByb21pc2UgcGVyIGNvbm5lY3Rpb24sIHNvIGNvbmN1cnJlbnQgY2xvc2VzIG9mIHRoZSBzYW1lXG4gICAqIGNvbm5lY3Rpb24gYXdhaXQgdGhlIHNhbWUgY2xvc2UgcmF0aGVyIHRoYW4gY2xvc2luZyB0aGUgZHJpdmVyIGhhbmRsZSB0d2ljZS5cbiAgICogQHR5cGUge1dlYWtNYXA8b2JqZWN0LCBQcm9taXNlPHZvaWQ+Pn1cbiAgICovXG4gIGNvbm5lY3Rpb25DbG9zZVByb21pc2VzID0gbmV3IFdlYWtNYXAoKVxuXG4gIGlkU2VxID0gMFxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMgb2JqZWN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gYXJncy5jb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGFyZ3MuaWRlbnRpZmllciAtIElkZW50aWZpZXIuXG4gICAqL1xuICBjb25zdHJ1Y3Rvcih7Y29uZmlndXJhdGlvbiwgaWRlbnRpZmllcn0pIHtcbiAgICBzdXBlcih7Y29uZmlndXJhdGlvbiwgaWRlbnRpZmllcn0pXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIERhdGFiYXNlIGNvbm5lY3Rpb24gaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNvbm5lY3Rpb24gaXMgY2hlY2tlZCBpbiBvciBjbG9zZWQuXG4gICAqL1xuICBhc3luYyBjaGVja2luKGNvbm5lY3Rpb24pIHtcbiAgICBjb25zdCBpZCA9IGNvbm5lY3Rpb24uZ2V0SWRTZXEoKVxuXG4gICAgaWYgKHR5cGVvZiBpZCAhPT0gXCJudW1iZXJcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBpZFNlcSBvbiBjb25uZWN0aW9uIHdhc24ndCBzZXQ/ICcke3R5cGVvZiBpZH0nID0gJHtpZH1gKVxuICAgIH1cblxuICAgIGlmIChpZCBpbiB0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpIHtcbiAgICAgIGRlbGV0ZSB0aGlzLmNvbm5lY3Rpb25zSW5Vc2VbaWRdXG4gICAgfVxuXG4gICAgY29ubmVjdGlvbi5zZXRJZFNlcSh1bmRlZmluZWQpXG5cbiAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0NMT1NFRF9DT05ORUNUSU9OXT86IGJvb2xlYW4sIFtJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcblxuICAgIGlmICh0cmFja2VkQ29ubmVjdGlvbltDTE9TRURfQ09OTkVDVElPTl0pIHJldHVyblxuXG4gICAgYXdhaXQgdGhpcy5yb2xsYmFja0xlZnRPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbilcblxuICAgIHRyYWNrZWRDb25uZWN0aW9uW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXSA9IERhdGUubm93KClcbiAgICB0aGlzLmNvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbilcbiAgICBhd2FpdCB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0cygpXG5cbiAgICBpZiAodGhpcy5pZGxlVGltZW91dE1pbGxpcygpID09PSAwKSB7XG4gICAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnNjaGVkdWxlSWRsZUNvbm5lY3Rpb25SZWFwZXIoKVxuICAgIH1cblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjaGVja291dC4gICovXG4gIGFzeW5jIGNoZWNrb3V0KCkge1xuICAgIGNvbnN0IGRhdGFiYXNlQ29uZmlnID0gdGhpcy5nZXRDb25maWd1cmF0aW9uKClcbiAgICBjb25zdCByZXVzZUtleSA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvblJldXNlS2V5KClcbiAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkocmV1c2VLZXkpXG5cbiAgICBpZiAoY29ubmVjdGlvbikgcmV0dXJuIHRoaXMuYWN0aXZhdGVDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG5cbiAgICBhd2FpdCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKVxuICAgIGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KHJldXNlS2V5KVxuXG4gICAgaWYgKGNvbm5lY3Rpb24pIHJldHVybiB0aGlzLmFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgaWYgKHRoaXMuY2FuU3Bhd25Db25uZWN0aW9uKCkpIHtcbiAgICAgIC8vIFNwYXduIHZpYSBzcGF3bkNvbm5lY3Rpb24oKSBzbyB0aGUgdGVuYW50LWF3YXJlIGNvbmZpZ3VyYXRpb24gaXMgcmVzb2x2ZWQgRlJFU0ggYXRcbiAgICAgIC8vIHNwYXduIHRpbWUgZm9yIHRoZSBjdXJyZW50IGNhbGxlci4gUmV1c2luZyB0aGUgZGF0YWJhc2VDb25maWcgY2FwdHVyZWQgYXQgdGhlIHRvcCBvZlxuICAgICAgLy8gY2hlY2tvdXQoKSBjb3VsZCBiaW5kIHRoZSBjb25uZWN0aW9uIHRvIGEgc3RhbGUgdGVuYW50L2RhdGFiYXNlLCB3aGljaCBicmVha3NcbiAgICAgIC8vIHBlci1yZXF1ZXN0IGlzb2xhdGlvbiAoZS5nLiB0ZXN0IHRydW5jYXRpb24gYXBwZWFyaW5nIG5vdCB0byB0YWtlIGVmZmVjdCkuIFRoZSBxdWV1ZWRcbiAgICAgIC8vIHBhdGggYmVsb3cga2VlcHMgdGhlIHdhaXRpbmcgY2FsbGVyJ3MgY2FwdHVyZWQgY29uZmlnIHZpYSB3YWl0Rm9yQ2hlY2tvdXQoKS5cbiAgICAgIGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLnNwYXduQ29ubmVjdGlvbigpXG5cbiAgICAgIHJldHVybiB0aGlzLmFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuICAgIH1cblxuICAgIHJldHVybiBhd2FpdCB0aGlzLndhaXRGb3JDaGVja291dChkYXRhYmFzZUNvbmZpZywgcmV1c2VLZXkpXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtzdHJpbmd9IHJldXNlS2V5IC0gRGF0YWJhc2UgY29uZmlndXJhdGlvbiByZXVzZSBrZXkuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBbYXJnc10gLSBPcHRpb25zLlxuICAgKiBAcGFyYW0ge2Jvb2xlYW59IFthcmdzLmluY2x1ZGVPcGVuVHJhbnNhY3Rpb25zXSAtIFdoZXRoZXIgY29ubmVjdGlvbnMgd2l0aCBvcGVuIHRyYW5zYWN0aW9ucyBtYXkgYmUgcmV0dXJuZWQuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBNYXRjaGluZyBpZGxlIGNvbm5lY3Rpb24uXG4gICAqL1xuICB0YWtlSWRsZUNvbm5lY3Rpb25Gb3JSZXVzZUtleShyZXVzZUtleSwge2luY2x1ZGVPcGVuVHJhbnNhY3Rpb25zID0gdHJ1ZX0gPSB7fSkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25JbmRleCA9IHRoaXMuY29ubmVjdGlvbnMuZmluZEluZGV4KChxdWV1ZWRDb25uZWN0aW9uKSA9PiB7XG4gICAgICBpZiAoIWluY2x1ZGVPcGVuVHJhbnNhY3Rpb25zICYmIHRoaXMuY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihxdWV1ZWRDb25uZWN0aW9uKSkgcmV0dXJuIGZhbHNlXG5cbiAgICAgIHJldHVybiB0aGlzLmNvbm5lY3Rpb25NYXRjaGVzUmV1c2VLZXkocXVldWVkQ29ubmVjdGlvbiwgcmV1c2VLZXkpXG4gICAgfSlcbiAgICBjb25zdCBjb25uZWN0aW9uID0gY29ubmVjdGlvbkluZGV4ID09PSAtMSA/IHVuZGVmaW5lZCA6IHRoaXMuY29ubmVjdGlvbnMuc3BsaWNlKGNvbm5lY3Rpb25JbmRleCwgMSlbMF1cblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBjb25uZWN0aW9uIG1hdGNoZXMgdGhlIHJldXNlIGtleS5cbiAgICovXG4gIGNvbm5lY3Rpb25NYXRjaGVzUmV1c2VLZXkoY29ubmVjdGlvbiwgcmV1c2VLZXkpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uV2l0aFBvb2xLZXkgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tQT09MX0NPTkZJR1VSQVRJT05fS0VZXT86IHN0cmluZ319ICovIChjb25uZWN0aW9uKVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25XaXRoUG9vbEtleVtQT09MX0NPTkZJR1VSQVRJT05fS0VZXSA9PT0gcmV1c2VLZXlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSAtIEFjdGl2YXRlZCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYWN0aXZhdGVDb25uZWN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICBpZiAoY29ubmVjdGlvbi5nZXRJZFNlcSgpICE9PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiBhbHJlYWR5IGhhcyBhbiBJRC1zZXEgLSBpcyBpdCBpbiB1c2U/ICR7Y29ubmVjdGlvbi5nZXRJZFNlcSgpfWApXG5cbiAgICBjb25zdCBpZCA9IHRoaXMuaWRTZXErK1xuXG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICBkZWxldGUgdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG5cbiAgICBjb25uZWN0aW9uLnNldElkU2VxKGlkKVxuICAgIHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF0gPSBjb25uZWN0aW9uXG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtudW1iZXIgfCB1bmRlZmluZWR9IC0gQ29uZmlndXJlZCBtYXggbGl2ZSBjb25uZWN0aW9ucy4gKi9cbiAgbWF4Q29ubmVjdGlvbnMoKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5wb29sPy5tYXhcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+PSAxKSByZXR1cm4gdmFsdWVcblxuICAgIHJldHVyblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtudW1iZXJ9IC0gTnVtYmVyIG9mIGxpdmUgYW5kIGluLXByb2dyZXNzIGNvbm5lY3Rpb25zLiAqL1xuICBsaXZlQ29ubmVjdGlvbkNvdW50KCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldChbXG4gICAgICAuLi50aGlzLmNvbm5lY3Rpb25zLFxuICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpLFxuICAgICAgdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpXG4gICAgXS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICByZXR1cm4gY29ubmVjdGlvbnMuc2l6ZSArIHRoaXMuY29ubmVjdGlvbnNCZWluZ1NwYXduZWRcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGEgbmV3IGNvbm5lY3Rpb24gY2FuIGJlIHNwYXduZWQuICovXG4gIGNhblNwYXduQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBtYXhDb25uZWN0aW9ucyA9IHRoaXMubWF4Q29ubmVjdGlvbnMoKVxuXG4gICAgcmV0dXJuIG1heENvbm5lY3Rpb25zID09PSB1bmRlZmluZWQgfHwgdGhpcy5saXZlQ29ubmVjdGlvbkNvdW50KCkgPCBtYXhDb25uZWN0aW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSBkYXRhYmFzZUNvbmZpZyAtIFJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZyBmb3IgdGhlIGNoZWNrb3V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleSBmb3IgdGhlIGNoZWNrb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gU3Bhd25lZCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25Db25uZWN0aW9uRm9yQ2hlY2tvdXQoZGF0YWJhc2VDb25maWcsIHJldXNlS2V5KSB7XG4gICAgdGhpcy5jb25uZWN0aW9uc0JlaW5nU3Bhd25lZCsrXG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuc3Bhd25Db25uZWN0aW9uV2l0aENvbmZpZ3VyYXRpb24oZGF0YWJhc2VDb25maWcpXG4gICAgICBjb25zdCBjb25uZWN0aW9uV2l0aFBvb2xLZXkgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tQT09MX0NPTkZJR1VSQVRJT05fS0VZXT86IHN0cmluZ319ICovIChjb25uZWN0aW9uKVxuXG4gICAgICBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0gPSByZXVzZUtleVxuICAgICAgY29ubmVjdGlvbi5zZXRTY2hlbWFDYWNoZUludmFsaWRhdG9yKCgpID0+IHRoaXMuY2xlYXJTY2hlbWFDYWNoZSgpKVxuXG4gICAgICByZXR1cm4gY29ubmVjdGlvblxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkLS1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGRhdGFiYXNlQ29uZmlnIC0gUmVzb2x2ZWQgZGF0YWJhc2UgY29uZmlnIGZvciB0aGUgY2hlY2tvdXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gUmVzb2x2ZXMgd2l0aCBhbiBhY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIHdhaXRGb3JDaGVja291dChkYXRhYmFzZUNvbmZpZywgcmV1c2VLZXkpIHtcbiAgICByZXR1cm4gYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4ge1xuICAgICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXRzLnB1c2goe2RhdGFiYXNlQ29uZmlnLCByZWplY3QsIHJlc29sdmUsIHJldXNlS2V5fSlcbiAgICAgIHZvaWQgdGhpcy5kcmFpblBlbmRpbmdDaGVja291dHMoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgY29uc3QgY2hlY2tvdXRFcnJvciA9IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihcIkZhaWxlZCB0byBkcmFpbiBwZW5kaW5nIGRhdGFiYXNlIGNvbm5lY3Rpb24gY2hlY2tvdXRzLlwiLCB7Y2F1c2U6IGVycm9yfSlcblxuICAgICAgICB0aGlzLnJlamVjdFBlbmRpbmdDaGVja291dHMoY2hlY2tvdXRFcnJvcilcbiAgICAgIH0pXG4gICAgfSlcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHBlbmRpbmcgY2hlY2tvdXRzIGhhdmUgYmVlbiBkcmFpbmVkIGFzIGZhciBhcyBwb3NzaWJsZS4gKi9cbiAgYXN5bmMgZHJhaW5QZW5kaW5nQ2hlY2tvdXRzKCkge1xuICAgIGlmICh0aGlzLnBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZSkge1xuICAgICAgYXdhaXQgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2VcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlID0gdGhpcy5kcmFpblBlbmRpbmdDaGVja291dHNBY3R1YWwoKVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IHRoaXMucGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlXG4gICAgfSBmaW5hbGx5IHtcbiAgICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlID0gdW5kZWZpbmVkXG4gICAgfVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gcGVuZGluZyBjaGVja291dHMgaGF2ZSBiZWVuIGRyYWluZWQgYXMgZmFyIGFzIHBvc3NpYmxlLiAqL1xuICBhc3luYyBkcmFpblBlbmRpbmdDaGVja291dHNBY3R1YWwoKSB7XG4gICAgd2hpbGUgKHRoaXMucGVuZGluZ0NoZWNrb3V0cy5sZW5ndGggPiAwKSB7XG4gICAgICBjb25zdCBjaGVja291dCA9IHRoaXMucGVuZGluZ0NoZWNrb3V0c1swXVxuICAgICAgbGV0IGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KGNoZWNrb3V0LnJldXNlS2V5LCB7aW5jbHVkZU9wZW5UcmFuc2FjdGlvbnM6IGZhbHNlfSlcblxuICAgICAgaWYgKCFjb25uZWN0aW9uKSB7XG4gICAgICAgIGF3YWl0IHRoaXMucmVhcElkbGVDb25uZWN0aW9ucygpXG4gICAgICAgIGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KGNoZWNrb3V0LnJldXNlS2V5LCB7aW5jbHVkZU9wZW5UcmFuc2FjdGlvbnM6IGZhbHNlfSlcbiAgICAgIH1cblxuICAgICAgaWYgKCFjb25uZWN0aW9uICYmICF0aGlzLmNhblNwYXduQ29ubmVjdGlvbigpKSB7XG4gICAgICAgIGNvbnN0IGNsb3NlZENvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLmNsb3NlT25lSWRsZUNvbm5lY3Rpb25Gb3JDYXBhY2l0eSgpXG5cbiAgICAgICAgaWYgKGNsb3NlZENvbm5lY3Rpb24pIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmICghY29ubmVjdGlvbiAmJiB0aGlzLmNhblNwYXduQ29ubmVjdGlvbigpKSB7XG4gICAgICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5zaGlmdCgpXG5cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25Gb3JDaGVja291dChjaGVja291dC5kYXRhYmFzZUNvbmZpZywgY2hlY2tvdXQucmV1c2VLZXkpXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgY2hlY2tvdXQucmVqZWN0KGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihcIkZhaWxlZCB0byBzcGF3biBkYXRhYmFzZSBjb25uZWN0aW9uLlwiLCB7Y2F1c2U6IGVycm9yfSkpXG4gICAgICAgICAgY29udGludWVcbiAgICAgICAgfVxuXG4gICAgICAgIGNoZWNrb3V0LnJlc29sdmUodGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbikpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGlmICghY29ubmVjdGlvbikgcmV0dXJuXG5cbiAgICAgIHRoaXMucGVuZGluZ0NoZWNrb3V0cy5zaGlmdCgpXG4gICAgICBjaGVja291dC5yZXNvbHZlKHRoaXMuYWN0aXZhdGVDb25uZWN0aW9uKGNvbm5lY3Rpb24pKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIGFuIGlkbGUgY29ubmVjdGlvbiB3YXMgY2xvc2VkIHRvIGZyZWUgY2FwYWNpdHkuICovXG4gIGFzeW5jIGNsb3NlT25lSWRsZUNvbm5lY3Rpb25Gb3JDYXBhY2l0eSgpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5jb25uZWN0aW9ucy5maW5kKChjYW5kaWRhdGUpID0+ICF0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY2FuZGlkYXRlKSlcblxuICAgIGlmICghY29ubmVjdGlvbikgcmV0dXJuIGZhbHNlXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gdGhpcy5jb25uZWN0aW9ucy5maWx0ZXIoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlICE9PSBjb25uZWN0aW9uKVxuICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpIDogUHJvbWlzZTxUPn0gY2FsbGJhY2sgLSBDYWxsYmFjayB0byBpbnZva2Ugd2l0aCB0aGUgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8VD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2FsbGJhY2sgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgd2l0aENvbm5lY3Rpb24oY2FsbGJhY2spIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5jaGVja291dCgpXG4gICAgY29uc3QgaWQgPSBjb25uZWN0aW9uLmdldElkU2VxKClcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLnJ1bihpZCwgYXN5bmMgKCkgPT4ge1xuICAgICAgdHJ5IHtcbiAgICAgICAgcmV0dXJuIGF3YWl0IGNhbGxiYWNrKGNvbm5lY3Rpb24pXG4gICAgICB9IGZpbmFsbHkge1xuICAgICAgICBhd2FpdCB0aGlzLmNoZWNraW4oY29ubmVjdGlvbilcbiAgICAgIH1cbiAgICB9KVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gLSBUaGUgY3VycmVudCBjb25uZWN0aW9uLiAgKi9cbiAgZ2V0Q3VycmVudENvbm5lY3Rpb24oKSB7XG4gICAgY29uc3QgaWQgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKClcblxuICAgIGlmIChpZCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBjb25zdCBmYWxsYmFja0Nvbm5lY3Rpb24gPSB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb24oKVxuXG4gICAgICBpZiAoZmFsbGJhY2tDb25uZWN0aW9uKSB7XG4gICAgICAgIHJldHVybiBmYWxsYmFja0Nvbm5lY3Rpb25cbiAgICAgIH1cblxuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiSUQgaGFzbid0IGJlZW4gc2V0IGZvciB0aGlzIGFzeW5jIGNvbnRleHRcIilcbiAgICB9XG5cbiAgICBpZiAoIShpZCBpbiB0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvbm5lY3Rpb24gJHtpZH0gZG9lc24ndCBleGlzdCBhbnkgbW9yZSAtIGhhcyBpdCBiZWVuIGNoZWNrZWQgaW4gYWdhaW4/YClcbiAgICB9XG5cbiAgICBjb25zdCBjdXJyZW50Q29ubmVjdGlvbiA9IHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF1cblxuICAgIGlmICghY3VycmVudENvbm5lY3Rpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgQ291bGRuJ3QgZ2V0IGN1cnJlbnQgY29ubmVjdGlvbiBmcm9tIHRoYXQgSUQ6ICR7aWR9YClcbiAgICB9XG5cbiAgICByZXR1cm4gY3VycmVudENvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgYSBmYWxsYmFjayBjb25uZWN0aW9uIGZvciB0aGlzIHBvb2wgaWRlbnRpZmllciB0aGF0IHdpbGwgYmUgdXNlZCB3aGVuIG5vIGFzeW5jIGNvbnRleHQgaXMgYXZhaWxhYmxlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc2V0R2xvYmFsQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgY29uc3Qga2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb259ICovICh0aGlzLmNvbnN0cnVjdG9yKVxuICAgIGxldCBtYXBGb3JDb25maWd1cmF0aW9uID0ga2xhc3MuZ2xvYmFsQ29ubmVjdGlvbnMuZ2V0KHRoaXMuY29uZmlndXJhdGlvbilcblxuICAgIGlmICghbWFwRm9yQ29uZmlndXJhdGlvbikge1xuICAgICAgbWFwRm9yQ29uZmlndXJhdGlvbiA9IHt9XG4gICAgICBrbGFzcy5nbG9iYWxDb25uZWN0aW9ucy5zZXQodGhpcy5jb25maWd1cmF0aW9uLCBtYXBGb3JDb25maWd1cmF0aW9uKVxuICAgIH1cblxuICAgIG1hcEZvckNvbmZpZ3VyYXRpb25bdGhpcy5pZGVudGlmaWVyXSA9IGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBFbnN1cmVzIGEgZ2xvYmFsIGZhbGxiYWNrIGNvbm5lY3Rpb24gZXhpc3RzIGZvciB0aGlzIHBvb2wgaWRlbnRpZmllciBhbmQgcmV0dXJucyBpdC5cbiAgICogSWYgb25lIGlzIGFscmVhZHkgc2V0LCBpdCBpcyByZXR1cm5lZCBhbmQgYWxzbyBtYWRlIGF2YWlsYWJsZSBpbiB0aGUgcG9vbCBxdWV1ZS5cbiAgICogT3RoZXJ3aXNlIGEgbmV3IGNvbm5lY3Rpb24gaXMgc3Bhd25lZCwgcmVnaXN0ZXJlZCwgYW5kIHF1ZXVlZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQ+fSAtIFJlc29sdmVzIHdpdGggdGhlIGdsb2JhbCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlR2xvYmFsQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBleGlzdGluZyA9IHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbigpXG5cbiAgICBpZiAoZXhpc3RpbmcpIHJldHVybiBleGlzdGluZ1xuXG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuc3Bhd25Db25uZWN0aW9uKClcblxuICAgIHRoaXMuc2V0R2xvYmFsQ29ubmVjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgcmV0dXJuIGNvbm5lY3Rpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBTZXQgYSBzaGFyZWQgY29ubmVjdGlvbiBmb3IgdGVzdCBtb2RlIHNvIHRoYXQgSFRUUCBoYW5kbGVycyBydW5uaW5nXG4gICAqIGluIHRoZSBzYW1lIHByb2Nlc3MgY2FuIHJldXNlIHRoZSB0ZXN0IHJ1bm5lcidzIGRhdGFiYXNlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBTaGFyZWQgY29ubmVjdGlvbi5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBzZXRUZXN0U2hhcmVkQ29ubmVjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24gPSBjb25uZWN0aW9uXG4gIH1cblxuICAvKiogQHJldHVybnMge3ZvaWR9ICovXG4gIGNsZWFyVGVzdFNoYXJlZENvbm5lY3Rpb24oKSB7XG4gICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb24gPSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb25uZWN0aW9uIHRpZWQgdG8gdGhlIGN1cnJlbnQgYXN5bmMgY29udGV4dCwgaWYgYW55LlxuICAgKiBGYWxscyBiYWNrIHRvIHRoZSB0ZXN0IHNoYXJlZCBjb25uZWN0aW9uIHdoZW4gbm8gYXN5bmMgY29udGV4dCBleGlzdHMuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBUaGUgY3VycmVudCBjb250ZXh0IGNvbm5lY3Rpb24uXG4gICAqL1xuICBnZXRDdXJyZW50Q29udGV4dENvbm5lY3Rpb24oKSB7XG4gICAgY29uc3QgaWQgPSB0aGlzLmFzeW5jTG9jYWxTdG9yYWdlLmdldFN0b3JlKClcblxuICAgIGlmIChpZCA9PT0gdW5kZWZpbmVkKSByZXR1cm4gdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb25cblxuICAgIHJldHVybiB0aGlzLmdldEN1cnJlbnRDb25uZWN0aW9uKClcbiAgfVxuXG4gIC8qKlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGdsb2JhbCBjb25uZWN0aW9uLlxuICAgKi9cbiAgZ2V0R2xvYmFsQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpXG5cbiAgICBpZiAoIWNvbm5lY3Rpb24pIHJldHVyblxuICAgIGlmICghdGhpcy5jb25uZWN0aW9uTWF0Y2hlc0N1cnJlbnRDb25maWd1cmF0aW9uKGNvbm5lY3Rpb24pKSByZXR1cm5cblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSAtIFRoZSBnbG9iYWwgY29ubmVjdGlvbiBmb3IgdGhpcyBwb29sIGlkZW50aWZpZXIuXG4gICAqL1xuICBnZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpIHtcbiAgICBjb25zdCBrbGFzcyA9IC8qKiBAdHlwZSB7dHlwZW9mIFZlbG9jaW91c0RhdGFiYXNlUG9vbEFzeW5jVHJhY2tlZE11bHRpQ29ubmVjdGlvbn0gKi8gKHRoaXMuY29uc3RydWN0b3IpXG4gICAgY29uc3QgbWFwRm9yQ29uZmlndXJhdGlvbiA9IGtsYXNzLmdsb2JhbENvbm5lY3Rpb25zLmdldCh0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICByZXR1cm4gbWFwRm9yQ29uZmlndXJhdGlvbj8uW3RoaXMuaWRlbnRpZmllcl1cbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgc2NoZW1hIG1ldGFkYXRhIGNhY2hlZCBieSBldmVyeSBsaXZlIGNvbm5lY3Rpb24gb3duZWQgYnkgdGhpcyBwb29sLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBjbGVhclNjaGVtYUNhY2hlKCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldChbXG4gICAgICAuLi50aGlzLmNvbm5lY3Rpb25zLFxuICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpLFxuICAgICAgdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uKCksXG4gICAgICB0aGlzLl90ZXN0U2hhcmVkQ29ubmVjdGlvblxuICAgIF0uZmlsdGVyKEJvb2xlYW4pKVxuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICBpZiAoY29ubmVjdGlvbikgdGhpcy5fY2xlYXJDb25uZWN0aW9uU2NoZW1hQ2FjaGUoY29ubmVjdGlvbilcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge251bWJlciB8IG51bGx9IC0gSWRsZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcywgb3IgbnVsbCB3aGVuIGRpc2FibGVkLiAqL1xuICBpZGxlVGltZW91dE1pbGxpcygpIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpLnBvb2w/LmlkbGVUaW1lb3V0TWlsbGlzXG5cbiAgICBpZiAodmFsdWUgPT09IG51bGwpIHJldHVybiBudWxsXG4gICAgaWYgKHR5cGVvZiB2YWx1ZSA9PT0gXCJudW1iZXJcIiAmJiBOdW1iZXIuaXNGaW5pdGUodmFsdWUpICYmIHZhbHVlID49IDApIHJldHVybiB2YWx1ZVxuXG4gICAgcmV0dXJuIERFRkFVTFRfSURMRV9USU1FT1VUX01JTExJU1xuICB9XG5cbiAgLyoqIEByZXR1cm5zIHt2b2lkfSAqL1xuICBzY2hlZHVsZUlkbGVDb25uZWN0aW9uUmVhcGVyKCkge1xuICAgIGlmICh0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIpIHJldHVyblxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBjb25zdCBpZGxlVGltZW91dE1pbGxpcyA9IHRoaXMuaWRsZVRpbWVvdXRNaWxsaXMoKVxuXG4gICAgaWYgKGlkbGVUaW1lb3V0TWlsbGlzID09PSBudWxsKSByZXR1cm5cblxuICAgIGNvbnN0IGRlbGF5ID0gdGhpcy5uZXh0SWRsZUNvbm5lY3Rpb25SZWFwRGVsYXkoaWRsZVRpbWVvdXRNaWxsaXMpXG5cbiAgICB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lciA9IHVuZGVmaW5lZFxuICAgICAgdm9pZCB0aGlzLnJlYXBJZGxlQ29ubmVjdGlvbnMoKS5jYXRjaCgoZXJyb3IpID0+IHtcbiAgICAgICAgdGhpcy5sb2dnZXIud2FybigoKSA9PiBbXCJGYWlsZWQgdG8gcmVhcCBpZGxlIGRhdGFiYXNlIGNvbm5lY3Rpb25zOlwiLCBlcnJvcl0pXG4gICAgICB9KVxuICAgIH0sIGRlbGF5KVxuXG4gICAgaWYgKHR5cGVvZiB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIudW5yZWYgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyLnVucmVmKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtudW1iZXJ9IGlkbGVUaW1lb3V0TWlsbGlzIC0gSWRsZSB0aW1lb3V0IGluIG1pbGxpc2Vjb25kcy5cbiAgICogQHJldHVybnMge251bWJlcn0gLSBEZWxheSBiZWZvcmUgdGhlIG5leHQgcmVhcC5cbiAgICovXG4gIG5leHRJZGxlQ29ubmVjdGlvblJlYXBEZWxheShpZGxlVGltZW91dE1pbGxpcykge1xuICAgIGxldCBkZWxheSA9IGlkbGVUaW1lb3V0TWlsbGlzXG4gICAgY29uc3Qgbm93ID0gRGF0ZS5ub3coKVxuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIHRoaXMuY29ubmVjdGlvbnMpIHtcbiAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIGNvbnRpbnVlXG5cbiAgICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG4gICAgICBjb25zdCBjaGVja2VkSW5BdCA9IHRyYWNrZWRDb25uZWN0aW9uW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXVxuXG4gICAgICBpZiAodHlwZW9mIGNoZWNrZWRJbkF0ICE9PSBcIm51bWJlclwiKSBjb250aW51ZVxuXG4gICAgICBkZWxheSA9IE1hdGgubWluKGRlbGF5LCBNYXRoLm1heCgwLCBpZGxlVGltZW91dE1pbGxpcyAtIChub3cgLSBjaGVja2VkSW5BdCkpKVxuICAgIH1cblxuICAgIHJldHVybiBkZWxheVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyBpZGxlIGNoZWNrZWQtaW4gY29ubmVjdGlvbnMgdGhhdCBoYXZlIGV4Y2VlZGVkIHRoZSBjb25maWd1cmVkIHRpbWVvdXQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyByZWFwSWRsZUNvbm5lY3Rpb25zKCkge1xuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCA9PT0gMCkgcmV0dXJuXG5cbiAgICBjb25zdCBpZGxlVGltZW91dE1pbGxpcyA9IHRoaXMuaWRsZVRpbWVvdXRNaWxsaXMoKVxuXG4gICAgaWYgKGlkbGVUaW1lb3V0TWlsbGlzID09PSBudWxsKSByZXR1cm5cblxuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KClcbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W119ICovXG4gICAgY29uc3Qga2VwdENvbm5lY3Rpb25zID0gW11cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W119ICovXG4gICAgY29uc3QgZXhwaXJlZENvbm5lY3Rpb25zID0gW11cblxuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiB0aGlzLmNvbm5lY3Rpb25zKSB7XG4gICAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0NMT1NFRF9DT05ORUNUSU9OXT86IGJvb2xlYW4sIFtJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcblxuICAgICAgaWYgKHRyYWNrZWRDb25uZWN0aW9uW0NMT1NFRF9DT05ORUNUSU9OXSkgY29udGludWVcbiAgICAgIGlmICh0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIHtcbiAgICAgICAga2VwdENvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbilcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgY2hlY2tlZEluQXQgPSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cbiAgICAgIGNvbnN0IGV4cGlyZWQgPSB0eXBlb2YgY2hlY2tlZEluQXQgPT09IFwibnVtYmVyXCIgJiYgbm93IC0gY2hlY2tlZEluQXQgPj0gaWRsZVRpbWVvdXRNaWxsaXNcblxuICAgICAgaWYgKGV4cGlyZWQpIHtcbiAgICAgICAgZXhwaXJlZENvbm5lY3Rpb25zLnB1c2goY29ubmVjdGlvbilcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGtlcHRDb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pXG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IGtlcHRDb25uZWN0aW9uc1xuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGV4cGlyZWRDb25uZWN0aW9ucykge1xuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbilcbiAgICB9XG5cbiAgICAvLyBBIGNvbmN1cnJlbnQgZmlyZS1hbmQtZm9yZ2V0IHNjaGVkdWxlZCByZWFwIG1heSBhbHJlYWR5IGJlIGNsb3NpbmdcbiAgICAvLyBjb25uZWN0aW9ucyB0aGlzIGNhbGwgZGlkIG5vdCBleHBpcmUgaXRzZWxmIChpdCBtYXkgaGF2ZSByZW1vdmVkIHRoZW0gZnJvbVxuICAgIC8vIGB0aGlzLmNvbm5lY3Rpb25zYCBmaXJzdCkuIEF3YWl0IHRob3NlIGluLWZsaWdodCBjbG9zZXMgdG9vIHNvIGEgY2FsbGVyXG4gICAgLy8gdGhhdCBhd2FpdHMgYHJlYXBJZGxlQ29ubmVjdGlvbnMoKWAgaXMgZ3VhcmFudGVlZCB0aGUgcG9vbCdzIGlkbGVcbiAgICAvLyBjb25uZWN0aW9ucyBhcmUgZnVsbHkgY2xvc2VkLCBub3QgbWlkLWBjbG9zZSgpYC5cbiAgICBpZiAodGhpcy5pbmZsaWdodENvbm5lY3Rpb25DbG9zZXMuc2l6ZSA+IDApIHtcbiAgICAgIGF3YWl0IFByb21pc2UuYWxsU2V0dGxlZChbLi4udGhpcy5pbmZsaWdodENvbm5lY3Rpb25DbG9zZXNdKVxuICAgIH1cblxuICAgIGlmICh0aGlzLmNvbm5lY3Rpb25zLmxlbmd0aCA+IDApIHtcbiAgICAgIHRoaXMuc2NoZWR1bGVJZGxlQ29ubmVjdGlvblJlYXBlcigpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRvIGluc3BlY3QuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdGhlIGNvbm5lY3Rpb24gaGFzIGFuIG9wZW4gdHJhbnNhY3Rpb24uXG4gICAqL1xuICBjb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICByZXR1cm4gY29ubmVjdGlvbi5fdHJhbnNhY3Rpb25zQ291bnQgPiAwXG4gIH1cblxuICAvKipcbiAgICogUm9sbHMgYmFjayBhbnkgdHJhbnNhY3Rpb24gYSBwcmV2aW91cyBob2xkZXIgbGVmdCBvcGVuIGJlZm9yZSBhIGNvbm5lY3Rpb25cbiAgICogcmUtZW50ZXJzIHRoZSBpZGxlIHBvb2wuIEEgY29ubmVjdGlvbiByZXR1cm5lZCB0byB0aGUgcG9vbCB3aXRoIGFuIG9wZW5cbiAgICogdHJhbnNhY3Rpb24gd291bGQgb3RoZXJ3aXNlIGJlIGhhbmRlZCB0byBhbiB1bnJlbGF0ZWQgY2hlY2tvdXQsIHdob3NlXG4gICAqIHN0YXJ0VHJhbnNhY3Rpb24oKSB0aGVuIGZhaWxzIHdpdGggXCJBIHRyYW5zYWN0aW9uIGlzIGFscmVhZHkgcnVubmluZ1wiIGFuZFxuICAgKiBwb2lzb25zIGV2ZXJ5IGZvbGxvd2luZyBjYWxsZXIgdGhhdCByZXVzZXMgaXQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIGJlaW5nIGNoZWNrZWQgaW4uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNvbm5lY3Rpb24gaG9sZHMgbm8gb3BlbiB0cmFuc2FjdGlvbi5cbiAgICovXG4gIGFzeW5jIHJvbGxiYWNrTGVmdE9wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgaWYgKCF0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIHJldHVyblxuXG4gICAgdGhpcy5sb2dnZXIud2FybigoKSA9PiBbYFJvbGxpbmcgYmFjayBhIHRyYW5zYWN0aW9uIGxlZnQgb3BlbiBvbiBhIGNvbm5lY3Rpb24gYmVpbmcgY2hlY2tlZCBpbiAoaWRlbnRpZmllcj0ke3RoaXMuaWRlbnRpZmllcn0pLmBdKVxuXG4gICAgd2hpbGUgKHRoaXMuY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5yb2xsYmFja1RyYW5zYWN0aW9uKClcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gY2xvc2UuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gY29tcGxldGUuXG4gICAqL1xuICBhc3luYyBjbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbikge1xuICAgIC8vIElkZW1wb3RlbnQ6IGEgZmlyZS1hbmQtZm9yZ2V0IHNjaGVkdWxlZCByZWFwIGFuZCBhbiBleHBsaWNpdCByZWFwIGNhbiBib3RoXG4gICAgLy8gdGFyZ2V0IHRoZSBzYW1lIGNvbm5lY3Rpb24uIEF3YWl0IHRoZSBpbi1mbGlnaHQgY2xvc2UgaW5zdGVhZCBvZiBjbG9zaW5nXG4gICAgLy8gdHdpY2UgKHdoaWNoIGNhbiB0aHJvdyBvbiB0aGUgZHJpdmVyKSBvciByZXR1cm5pbmcgd2hpbGUgdGhlIHVuZGVybHlpbmdcbiAgICAvLyBoYW5kbGUgaXMgc3RpbGwgb3Blbi5cbiAgICBjb25zdCBleGlzdGluZ0Nsb3NlID0gdGhpcy5jb25uZWN0aW9uQ2xvc2VQcm9taXNlcy5nZXQoY29ubmVjdGlvbilcblxuICAgIGlmIChleGlzdGluZ0Nsb3NlKSB7XG4gICAgICByZXR1cm4gYXdhaXQgZXhpc3RpbmdDbG9zZVxuICAgIH1cblxuICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbQ0xPU0VEX0NPTk5FQ1RJT05dPzogYm9vbGVhbiwgW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuXG4gICAgdHJhY2tlZENvbm5lY3Rpb25bQ0xPU0VEX0NPTk5FQ1RJT05dID0gdHJ1ZVxuICAgIGRlbGV0ZSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cblxuICAgIGNvbnN0IGNsb3NlUHJvbWlzZSA9IChhc3luYyAoKSA9PiB7XG4gICAgICBpZiAodHlwZW9mIHRyYWNrZWRDb25uZWN0aW9uLmNsb3NlID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgICAgYXdhaXQgdHJhY2tlZENvbm5lY3Rpb24uY2xvc2UoKVxuICAgICAgfSBlbHNlIGlmICh0eXBlb2YgdHJhY2tlZENvbm5lY3Rpb24uZGlzY29ubmVjdCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGF3YWl0IHRyYWNrZWRDb25uZWN0aW9uLmRpc2Nvbm5lY3QoKVxuICAgICAgfVxuICAgIH0pKClcblxuICAgIHRoaXMuY29ubmVjdGlvbkNsb3NlUHJvbWlzZXMuc2V0KGNvbm5lY3Rpb24sIGNsb3NlUHJvbWlzZSlcbiAgICB0aGlzLmluZmxpZ2h0Q29ubmVjdGlvbkNsb3Nlcy5hZGQoY2xvc2VQcm9taXNlKVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNsb3NlUHJvbWlzZVxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmluZmxpZ2h0Q29ubmVjdGlvbkNsb3Nlcy5kZWxldGUoY2xvc2VQcm9taXNlKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7dm9pZH0gKi9cbiAgY2xlYXJJZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKCkge1xuICAgIGlmICghdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKSByZXR1cm5cblxuICAgIGNsZWFyVGltZW91dCh0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIpXG4gICAgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogQ2xvc2VzIGFsbCBhY3RpdmUgYW5kIGNhY2hlZCBjb25uZWN0aW9ucyBmb3IgdGhpcyBwb29sLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VBbGwoKSB7XG4gICAgdGhpcy5jbGVhcklkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIoKVxuICAgIHRoaXMucmVqZWN0UGVuZGluZ0NoZWNrb3V0cyhuZXcgRXJyb3IoXCJEYXRhYmFzZSBwb29sIHdhcyBjbG9zZWQgYmVmb3JlIGNoZWNrb3V0IGNvbXBsZXRlZC5cIikpXG5cbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IG5ldyBTZXQoW1xuICAgICAgLi4udGhpcy5jb25uZWN0aW9ucyxcbiAgICAgIC4uLk9iamVjdC52YWx1ZXModGhpcy5jb25uZWN0aW9uc0luVXNlKSxcbiAgICAgIHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbigpXG4gICAgXS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gW11cbiAgICB0aGlzLmNvbm5lY3Rpb25zSW5Vc2UgPSB7fVxuXG4gICAgZm9yIChjb25zdCBjb25uZWN0aW9uIG9mIGNvbm5lY3Rpb25zKSB7XG4gICAgICBpZiAoIWNvbm5lY3Rpb24pIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG4gICAgfVxuXG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtFcnJvcn0gZXJyb3IgLSBFcnJvciB0byByZWplY3QgcGVuZGluZyBjaGVja291dHMgd2l0aC5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICByZWplY3RQZW5kaW5nQ2hlY2tvdXRzKGVycm9yKSB7XG4gICAgY29uc3QgcGVuZGluZ0NoZWNrb3V0cyA9IHRoaXMucGVuZGluZ0NoZWNrb3V0c1xuXG4gICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXRzID0gW11cblxuICAgIGZvciAoY29uc3QgY2hlY2tvdXQgb2YgcGVuZGluZ0NoZWNrb3V0cykge1xuICAgICAgY2hlY2tvdXQucmVqZWN0KGVycm9yKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYWNlcyBhbGwgZ2xvYmFsbHkgcmVnaXN0ZXJlZCBmYWxsYmFjayBjb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IFtjb25uZWN0aW9uc10gLSBDb25uZWN0aW9ucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IFtjb25maWd1cmF0aW9uXSAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHN0YXRpYyBzZXRHbG9iYWxDb25uZWN0aW9ucyhjb25uZWN0aW9ucywgY29uZmlndXJhdGlvbikge1xuICAgIGlmICghY29ubmVjdGlvbnMgJiYgIWNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmdsb2JhbENvbm5lY3Rpb25zLnNldChjb25maWd1cmF0aW9uLCBjb25uZWN0aW9ucyB8fCB7fSlcbiAgfVxuXG4gIC8qKlxuICAgKiBDbGVhcnMgZ2xvYmFsbHkgcmVnaXN0ZXJlZCBmYWxsYmFjayBjb25uZWN0aW9ucyBmb3IgYWxsIGNvbmZpZ3VyYXRpb25zIG9yIGEgc2luZ2xlIGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBbY29uZmlndXJhdGlvbl0gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICBzdGF0aWMgY2xlYXJHbG9iYWxDb25uZWN0aW9ucyhjb25maWd1cmF0aW9uKSB7XG4gICAgaWYgKCFjb25maWd1cmF0aW9uKSB7XG4gICAgICB0aGlzLmdsb2JhbENvbm5lY3Rpb25zID0gbmV3IFdlYWtNYXAoKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5nbG9iYWxDb25uZWN0aW9ucy5kZWxldGUoY29uZmlndXJhdGlvbilcbiAgfVxufVxuIl19
|
|
662
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vc3JjL2RhdGFiYXNlL3Bvb2wvYXN5bmMtdHJhY2tlZC1tdWx0aS1jb25uZWN0aW9uLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLEVBQUMsaUJBQWlCLEVBQUMsTUFBTSxhQUFhLENBQUE7QUFDN0MsT0FBTyxRQUFRLEVBQUUsRUFBQyxzQkFBc0IsRUFBQyxNQUFNLFdBQVcsQ0FBQTtBQUUxRCxNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRyxNQUFNLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtBQUNwRSxNQUFNLDZCQUE2QixHQUFHLE1BQU0sQ0FBQyxvQ0FBb0MsQ0FBQyxDQUFBO0FBQ2xGLE1BQU0sMkJBQTJCLEdBQUcsSUFBSSxDQUFBO0FBRXhDOzs7Ozs7O0dBT0c7QUFFSCxNQUFNLENBQUMsT0FBTyxPQUFPLGdEQUFpRCxTQUFRLFFBQVE7SUFDcEY7OztPQUdHO0lBQ0gsTUFBTSxDQUFDLGlCQUFpQixHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7SUFFeEMsaUJBQWlCLEdBQUcsSUFBSSxpQkFBaUIsRUFBRSxDQUFBO0lBRTNDOzs7OztPQUtHO0lBQ0gscUJBQXFCLEdBQUcsU0FBUyxDQUFBO0lBRWpDLHFEQUFxRDtJQUNyRCxXQUFXLEdBQUcsRUFBRSxDQUFBO0lBRWhCLG1FQUFtRTtJQUNuRSxnQkFBZ0IsR0FBRyxFQUFFLENBQUE7SUFFckIsZ0NBQWdDO0lBQ2hDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQTtJQUVyQixxQkFBcUI7SUFDckIsdUJBQXVCLEdBQUcsQ0FBQyxDQUFBO0lBRTNCLHdDQUF3QztJQUN4QywyQkFBMkIsR0FBRyxTQUFTLENBQUE7SUFFdkMsd0RBQXdEO0lBQ3hELHlCQUF5QixHQUFHLFNBQVMsQ0FBQTtJQUVyQzs7Ozs7Ozs7T0FRRztJQUNILHdCQUF3QixHQUFH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SSxDQUFDLGlCQUFpQixDQUFDLE1BQU0sQ0FBQyxhQUFhLENBQUMsQ0FBQTtJQUM5QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7QXN5bmNMb2NhbFN0b3JhZ2V9IGZyb20gXCJhc3luY19ob29rc1wiXG5pbXBvcnQgQmFzZVBvb2wsIHtQT09MX0NPTkZJR1VSQVRJT05fS0VZfSBmcm9tIFwiLi9iYXNlLmpzXCJcblxuZXhwb3J0IGNvbnN0IENMT1NFRF9DT05ORUNUSU9OID0gU3ltYm9sKFwidmVsb2Npb3VzQ2xvc2VkQ29ubmVjdGlvblwiKVxuY29uc3QgSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVQgPSBTeW1ib2woXCJ2ZWxvY2lvdXNJZGxlQ29ubmVjdGlvbkNoZWNrZWRJbkF0XCIpXG5jb25zdCBERUZBVUxUX0lETEVfVElNRU9VVF9NSUxMSVMgPSA1MDAwXG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gUGVuZGluZ0NoZWNrb3V0XG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuRGF0YWJhc2VDb25maWd1cmF0aW9uVHlwZX0gZGF0YWJhc2VDb25maWcgLSBSZXNvbHZlZCBkYXRhYmFzZSBjb25maWd1cmF0aW9uIG5lZWRlZCBieSB0aGUgY2hlY2tvdXQuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5Db25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zfSBvcHRpb25zIC0gQ2hlY2tvdXQgb3B0aW9ucy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5IG5lZWRlZCBieSB0aGUgY2hlY2tvdXQuXG4gKiBAcHJvcGVydHkgeyhjb25uZWN0aW9uOiBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgPT4gdm9pZH0gcmVzb2x2ZSAtIFJlc29sdmVzIHdpdGggYW4gYWN0aXZhdGVkIGNvbm5lY3Rpb24uXG4gKiBAcHJvcGVydHkgeyhlcnJvcjogRXJyb3IpID0+IHZvaWR9IHJlamVjdCAtIFJlamVjdHMgd2hlbiBjaGVja291dCBjYW5ub3QgY29tcGxldGUuXG4gKi9cblxuZXhwb3J0IGRlZmF1bHQgY2xhc3MgVmVsb2Npb3VzRGF0YWJhc2VQb29sQXN5bmNUcmFja2VkTXVsdGlDb25uZWN0aW9uIGV4dGVuZHMgQmFzZVBvb2wge1xuICAvKipcbiAgICogR2xvYmFsIGZhbGxiYWNrIGNvbm5lY3Rpb25zIGtleWVkIGJ5IGNvbmZpZ3VyYXRpb24gaW5zdGFuY2UgYW5kIHBvb2wgaWRlbnRpZmllci5cbiAgICogQHR5cGUge1dlYWtNYXA8aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0LCBSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD4+fVxuICAgKi9cbiAgc3RhdGljIGdsb2JhbENvbm5lY3Rpb25zID0gbmV3IFdlYWtNYXAoKVxuXG4gIGFzeW5jTG9jYWxTdG9yYWdlID0gbmV3IEFzeW5jTG9jYWxTdG9yYWdlKClcblxuICAvKipcbiAgICogV2hlbiBzZXQsIHJldHVybmVkIGJ5IGdldEN1cnJlbnRDb250ZXh0Q29ubmVjdGlvbiB3aGVuIG5vIGFzeW5jIGNvbnRleHQgZXhpc3RzLlxuICAgKiBVc2VkIGJ5IHRoZSB0ZXN0IHJ1bm5lciB0byBzaGFyZSBhIGNvbm5lY3Rpb24gYmV0d2VlbiB0ZXN0IGNvZGUgYW5kIEhUVFAgaGFuZGxlcnNcbiAgICogcnVubmluZyBpbiB0aGUgc2FtZSBwcm9jZXNzIChpbi1wcm9jZXNzIHRlc3Qgc2VydmVyIG1vZGUpLlxuICAgKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9XG4gICAqL1xuICBfdGVzdFNoYXJlZENvbm5lY3Rpb24gPSB1bmRlZmluZWRcblxuICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0W119ICovXG4gIGNvbm5lY3Rpb25zID0gW11cblxuICAvKiogQHR5cGUge1JlY29yZDxudW1iZXIsIGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gKi9cbiAgY29ubmVjdGlvbnNJblVzZSA9IHt9XG5cbiAgLyoqIEB0eXBlIHtQZW5kaW5nQ2hlY2tvdXRbXX0gKi9cbiAgcGVuZGluZ0NoZWNrb3V0cyA9IFtdXG5cbiAgLyoqIEB0eXBlIHtudW1iZXJ9ICovXG4gIGNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkID0gMFxuXG4gIC8qKiBAdHlwZSB7UHJvbWlzZTx2b2lkPiB8IHVuZGVmaW5lZH0gKi9cbiAgcGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlID0gdW5kZWZpbmVkXG5cbiAgLyoqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBzZXRUaW1lb3V0PiB8IHVuZGVmaW5lZH0gKi9cbiAgaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lciA9IHVuZGVmaW5lZFxuXG4gIC8qKlxuICAgKiBJbi1mbGlnaHQgY29ubmVjdGlvbi1jbG9zZSBwcm9taXNlcy4gVGhlIGlkbGUgcmVhcGVyIGlzIGFybWVkIG9uIGNoZWNrLWluXG4gICAqIGFuZCBydW5zIGZpcmUtYW5kLWZvcmdldCB3aGVuIGl0cyB0aW1lciBmaXJlcywgc28gYSBzY2hlZHVsZWQgcmVhcCBjYW4gYmVcbiAgICogY2xvc2luZyBhIGNvbm5lY3Rpb24gd2hpbGUgYW4gZXhwbGljaXQgYHJlYXBJZGxlQ29ubmVjdGlvbnMoKWAgKG9yXG4gICAqIGBjbGVhcklkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIoKWApIHJ1bnMuIFRyYWNraW5nIHRoZSBpbi1mbGlnaHQgY2xvc2VzIGxldHNcbiAgICogdGhvc2UgY2FsbGVycyBhd2FpdCB0aGVtLCBzbyBvbmNlIGEgcmVhcCByZXNvbHZlcyB0aGUgY29ubmVjdGlvbnMgaXRcbiAgICogZXhwaXJlZCBhcmUgZnVsbHkgY2xvc2VkIGluc3RlYWQgb2YgaGFsZi1jbG9zZWQgbWlkLWBjbG9zZSgpYC5cbiAgICogQHR5cGUge1NldDxQcm9taXNlPHZvaWQ+Pn1cbiAgICovXG4gIGluZmxpZ2h0Q29ubmVjdGlvbkNsb3NlcyA9IG5ldyBTZXQoKVxuXG4gIC8qKlxuICAgKiBJbi1mbGlnaHQgY2xvc2UgcHJvbWlzZSBwZXIgY29ubmVjdGlvbiwgc28gY29uY3VycmVudCBjbG9zZXMgb2YgdGhlIHNhbWVcbiAgICogY29ubmVjdGlvbiBhd2FpdCB0aGUgc2FtZSBjbG9zZSByYXRoZXIgdGhhbiBjbG9zaW5nIHRoZSBkcml2ZXIgaGFuZGxlIHR3aWNlLlxuICAgKiBAdHlwZSB7V2Vha01hcDxvYmplY3QsIFByb21pc2U8dm9pZD4+fVxuICAgKi9cbiAgY29ubmVjdGlvbkNsb3NlUHJvbWlzZXMgPSBuZXcgV2Vha01hcCgpXG5cbiAgaWRTZXEgPSAwXG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucyBvYmplY3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi5qc1wiKS5kZWZhdWx0fSBhcmdzLmNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIGluc3RhbmNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gYXJncy5pZGVudGlmaWVyIC0gSWRlbnRpZmllci5cbiAgICovXG4gIGNvbnN0cnVjdG9yKHtjb25maWd1cmF0aW9uLCBpZGVudGlmaWVyfSkge1xuICAgIHN1cGVyKHtjb25maWd1cmF0aW9uLCBpZGVudGlmaWVyfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gRGF0YWJhc2UgY29ubmVjdGlvbiBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiB0aGUgY29ubmVjdGlvbiBpcyBjaGVja2VkIGluIG9yIGNsb3NlZC5cbiAgICovXG4gIGFzeW5jIGNoZWNraW4oY29ubmVjdGlvbikge1xuICAgIGNvbnN0IGlkID0gY29ubmVjdGlvbi5nZXRJZFNlcSgpXG5cbiAgICBpZiAodHlwZW9mIGlkICE9PSBcIm51bWJlclwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGlkU2VxIG9uIGNvbm5lY3Rpb24gd2Fzbid0IHNldD8gJyR7dHlwZW9mIGlkfScgPSAke2lkfWApXG4gICAgfVxuXG4gICAgaWYgKGlkIGluIHRoaXMuY29ubmVjdGlvbnNJblVzZSkge1xuICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF1cbiAgICB9XG5cbiAgICBjb25uZWN0aW9uLnNldElkU2VxKHVuZGVmaW5lZClcblxuICAgIGNvbnN0IHRyYWNrZWRDb25uZWN0aW9uID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbQ0xPU0VEX0NPTk5FQ1RJT05dPzogYm9vbGVhbiwgW0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuXG4gICAgaWYgKHRyYWNrZWRDb25uZWN0aW9uW0NMT1NFRF9DT05ORUNUSU9OXSkgcmV0dXJuXG5cbiAgICBhd2FpdCB0aGlzLnJvbGxiYWNrTGVmdE9wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKVxuXG4gICAgdHJ5IHtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24uY2xlYXJDb25uZWN0aW9uQ2hlY2tvdXROYW1lKClcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbilcblxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG5cbiAgICB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0gPSBEYXRlLm5vdygpXG4gICAgdGhpcy5jb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pXG4gICAgYXdhaXQgdGhpcy5kcmFpblBlbmRpbmdDaGVja291dHMoKVxuXG4gICAgaWYgKHRoaXMuaWRsZVRpbWVvdXRNaWxsaXMoKSA9PT0gMCkge1xuICAgICAgYXdhaXQgdGhpcy5yZWFwSWRsZUNvbm5lY3Rpb25zKClcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zY2hlZHVsZUlkbGVDb25uZWN0aW9uUmVhcGVyKClcbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5Db25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zfSBbb3B0aW9uc10gLSBDaGVja291dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gUmVzb2x2ZXMgd2l0aCB0aGUgY2hlY2tvdXQuXG4gICAqL1xuICBhc3luYyBjaGVja291dChvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCBkYXRhYmFzZUNvbmZpZyA9IHRoaXMuZ2V0Q29uZmlndXJhdGlvbigpXG4gICAgY29uc3QgcmV1c2VLZXkgPSB0aGlzLmdldENvbmZpZ3VyYXRpb25SZXVzZUtleSgpXG4gICAgbGV0IGNvbm5lY3Rpb24gPSB0aGlzLnRha2VJZGxlQ29ubmVjdGlvbkZvclJldXNlS2V5KHJldXNlS2V5KVxuXG4gICAgaWYgKGNvbm5lY3Rpb24pIHJldHVybiBhd2FpdCB0aGlzLmFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uLCBvcHRpb25zKVxuXG4gICAgYXdhaXQgdGhpcy5yZWFwSWRsZUNvbm5lY3Rpb25zKClcbiAgICBjb25uZWN0aW9uID0gdGhpcy50YWtlSWRsZUNvbm5lY3Rpb25Gb3JSZXVzZUtleShyZXVzZUtleSlcblxuICAgIGlmIChjb25uZWN0aW9uKSByZXR1cm4gYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgb3B0aW9ucylcblxuICAgIGlmICh0aGlzLmNhblNwYXduQ29ubmVjdGlvbigpKSB7XG4gICAgICAvLyBTcGF3biB2aWEgc3Bhd25Db25uZWN0aW9uKCkgc28gdGhlIHRlbmFudC1hd2FyZSBjb25maWd1cmF0aW9uIGlzIHJlc29sdmVkIEZSRVNIIGF0XG4gICAgICAvLyBzcGF3biB0aW1lIGZvciB0aGUgY3VycmVudCBjYWxsZXIuIFJldXNpbmcgdGhlIGRhdGFiYXNlQ29uZmlnIGNhcHR1cmVkIGF0IHRoZSB0b3Agb2ZcbiAgICAgIC8vIGNoZWNrb3V0KCkgY291bGQgYmluZCB0aGUgY29ubmVjdGlvbiB0byBhIHN0YWxlIHRlbmFudC9kYXRhYmFzZSwgd2hpY2ggYnJlYWtzXG4gICAgICAvLyBwZXItcmVxdWVzdCBpc29sYXRpb24gKGUuZy4gdGVzdCB0cnVuY2F0aW9uIGFwcGVhcmluZyBub3QgdG8gdGFrZSBlZmZlY3QpLiBUaGUgcXVldWVkXG4gICAgICAvLyBwYXRoIGJlbG93IGtlZXBzIHRoZSB3YWl0aW5nIGNhbGxlcidzIGNhcHR1cmVkIGNvbmZpZyB2aWEgd2FpdEZvckNoZWNrb3V0KCkuXG4gICAgICBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb24oKVxuXG4gICAgICByZXR1cm4gYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgb3B0aW9ucylcbiAgICB9XG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy53YWl0Rm9yQ2hlY2tvdXQoZGF0YWJhc2VDb25maWcsIHJldXNlS2V5LCBvcHRpb25zKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtib29sZWFufSBbYXJncy5pbmNsdWRlT3BlblRyYW5zYWN0aW9uc10gLSBXaGV0aGVyIGNvbm5lY3Rpb25zIHdpdGggb3BlbiB0cmFuc2FjdGlvbnMgbWF5IGJlIHJldHVybmVkLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gTWF0Y2hpbmcgaWRsZSBjb25uZWN0aW9uLlxuICAgKi9cbiAgdGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkocmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9ucyA9IHRydWV9ID0ge30pIHtcbiAgICBjb25zdCBjb25uZWN0aW9uSW5kZXggPSB0aGlzLmNvbm5lY3Rpb25zLmZpbmRJbmRleCgocXVldWVkQ29ubmVjdGlvbikgPT4ge1xuICAgICAgaWYgKCFpbmNsdWRlT3BlblRyYW5zYWN0aW9ucyAmJiB0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24ocXVldWVkQ29ubmVjdGlvbikpIHJldHVybiBmYWxzZVxuXG4gICAgICByZXR1cm4gdGhpcy5jb25uZWN0aW9uTWF0Y2hlc1JldXNlS2V5KHF1ZXVlZENvbm5lY3Rpb24sIHJldXNlS2V5KVxuICAgIH0pXG4gICAgY29uc3QgY29ubmVjdGlvbiA9IGNvbm5lY3Rpb25JbmRleCA9PT0gLTEgPyB1bmRlZmluZWQgOiB0aGlzLmNvbm5lY3Rpb25zLnNwbGljZShjb25uZWN0aW9uSW5kZXgsIDEpWzBdXG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGUgY29ubmVjdGlvbiBtYXRjaGVzIHRoZSByZXVzZSBrZXkuXG4gICAqL1xuICBjb25uZWN0aW9uTWF0Y2hlc1JldXNlS2V5KGNvbm5lY3Rpb24sIHJldXNlS2V5KSB7XG4gICAgY29uc3QgY29ubmVjdGlvbldpdGhQb29sS2V5ID0gLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCAmIHtbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0/OiBzdHJpbmd9fSAqLyAoY29ubmVjdGlvbilcblxuICAgIHJldHVybiBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0gPT09IHJldXNlS2V5XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnN9IFtvcHRpb25zXSAtIENoZWNrb3V0IG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBBY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGFjdGl2YXRlQ29ubmVjdGlvbihjb25uZWN0aW9uLCBvcHRpb25zID0ge30pIHtcbiAgICBpZiAoY29ubmVjdGlvbi5nZXRJZFNlcSgpICE9PSB1bmRlZmluZWQpIHRocm93IG5ldyBFcnJvcihgQ29ubmVjdGlvbiBhbHJlYWR5IGhhcyBhbiBJRC1zZXEgLSBpcyBpdCBpbiB1c2U/ICR7Y29ubmVjdGlvbi5nZXRJZFNlcSgpfWApXG5cbiAgICBjb25zdCBpZCA9IHRoaXMuaWRTZXErK1xuXG4gICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcbiAgICBkZWxldGUgdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG5cbiAgICBjb25uZWN0aW9uLnNldElkU2VxKGlkKVxuICAgIHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF0gPSBjb25uZWN0aW9uXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgY29ubmVjdGlvbi5zZXRDb25uZWN0aW9uQ2hlY2tvdXROYW1lKG9wdGlvbnMubmFtZSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgZGVsZXRlIHRoaXMuY29ubmVjdGlvbnNJblVzZVtpZF1cbiAgICAgIGNvbm5lY3Rpb24uc2V0SWRTZXEodW5kZWZpbmVkKVxuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbilcblxuICAgICAgdGhyb3cgZXJyb3JcbiAgICB9XG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtudW1iZXIgfCB1bmRlZmluZWR9IC0gQ29uZmlndXJlZCBtYXggbGl2ZSBjb25uZWN0aW9ucy4gKi9cbiAgbWF4Q29ubmVjdGlvbnMoKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5wb29sPy5tYXhcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+PSAxKSByZXR1cm4gdmFsdWVcblxuICAgIHJldHVyblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtudW1iZXJ9IC0gTnVtYmVyIG9mIGxpdmUgYW5kIGluLXByb2dyZXNzIGNvbm5lY3Rpb25zLiAqL1xuICBsaXZlQ29ubmVjdGlvbkNvdW50KCkge1xuICAgIGNvbnN0IGNvbm5lY3Rpb25zID0gbmV3IFNldChbXG4gICAgICAuLi50aGlzLmNvbm5lY3Rpb25zLFxuICAgICAgLi4uT2JqZWN0LnZhbHVlcyh0aGlzLmNvbm5lY3Rpb25zSW5Vc2UpLFxuICAgICAgdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpXG4gICAgXS5maWx0ZXIoQm9vbGVhbikpXG5cbiAgICByZXR1cm4gY29ubmVjdGlvbnMuc2l6ZSArIHRoaXMuY29ubmVjdGlvbnNCZWluZ1NwYXduZWRcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIGEgbmV3IGNvbm5lY3Rpb24gY2FuIGJlIHNwYXduZWQuICovXG4gIGNhblNwYXduQ29ubmVjdGlvbigpIHtcbiAgICBjb25zdCBtYXhDb25uZWN0aW9ucyA9IHRoaXMubWF4Q29ubmVjdGlvbnMoKVxuXG4gICAgcmV0dXJuIG1heENvbm5lY3Rpb25zID09PSB1bmRlZmluZWQgfHwgdGhpcy5saXZlQ29ubmVjdGlvbkNvdW50KCkgPCBtYXhDb25uZWN0aW9uc1xuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5EYXRhYmFzZUNvbmZpZ3VyYXRpb25UeXBlfSBkYXRhYmFzZUNvbmZpZyAtIFJlc29sdmVkIGRhdGFiYXNlIGNvbmZpZyBmb3IgdGhlIGNoZWNrb3V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmV1c2VLZXkgLSBEYXRhYmFzZSBjb25maWd1cmF0aW9uIHJldXNlIGtleSBmb3IgdGhlIGNoZWNrb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gU3Bhd25lZCBjb25uZWN0aW9uLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25Db25uZWN0aW9uRm9yQ2hlY2tvdXQoZGF0YWJhc2VDb25maWcsIHJldXNlS2V5KSB7XG4gICAgdGhpcy5jb25uZWN0aW9uc0JlaW5nU3Bhd25lZCsrXG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuc3Bhd25Db25uZWN0aW9uV2l0aENvbmZpZ3VyYXRpb24oZGF0YWJhc2VDb25maWcpXG4gICAgICBjb25zdCBjb25uZWN0aW9uV2l0aFBvb2xLZXkgPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tQT09MX0NPTkZJR1VSQVRJT05fS0VZXT86IHN0cmluZ319ICovIChjb25uZWN0aW9uKVxuXG4gICAgICBjb25uZWN0aW9uV2l0aFBvb2xLZXlbUE9PTF9DT05GSUdVUkFUSU9OX0tFWV0gPSByZXVzZUtleVxuICAgICAgY29ubmVjdGlvbi5zZXRTY2hlbWFDYWNoZUludmFsaWRhdG9yKCgpID0+IHRoaXMuY2xlYXJTY2hlbWFDYWNoZSgpKVxuXG4gICAgICByZXR1cm4gY29ubmVjdGlvblxuICAgIH0gZmluYWxseSB7XG4gICAgICB0aGlzLmNvbm5lY3Rpb25zQmVpbmdTcGF3bmVkLS1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLXR5cGVzLmpzXCIpLkRhdGFiYXNlQ29uZmlndXJhdGlvblR5cGV9IGRhdGFiYXNlQ29uZmlnIC0gUmVzb2x2ZWQgZGF0YWJhc2UgY29uZmlnIGZvciB0aGUgY2hlY2tvdXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSByZXVzZUtleSAtIERhdGFiYXNlIGNvbmZpZ3VyYXRpb24gcmV1c2Uga2V5LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vYmFzZS5qc1wiKS5Db25uZWN0aW9uQ2hlY2tvdXRPcHRpb25zfSBbb3B0aW9uc10gLSBDaGVja291dCBvcHRpb25zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdD59IC0gUmVzb2x2ZXMgd2l0aCBhbiBhY3RpdmF0ZWQgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIHdhaXRGb3JDaGVja291dChkYXRhYmFzZUNvbmZpZywgcmV1c2VLZXksIG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiBhd2FpdCBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnBlbmRpbmdDaGVja291dHMucHVzaCh7ZGF0YWJhc2VDb25maWcsIG9wdGlvbnMsIHJlamVjdCwgcmVzb2x2ZSwgcmV1c2VLZXl9KVxuICAgICAgdm9pZCB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0cygpLmNhdGNoKChlcnJvcikgPT4ge1xuICAgICAgICBjb25zdCBjaGVja291dEVycm9yID0gZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFwiRmFpbGVkIHRvIGRyYWluIHBlbmRpbmcgZGF0YWJhc2UgY29ubmVjdGlvbiBjaGVja291dHMuXCIsIHtjYXVzZTogZXJyb3J9KVxuXG4gICAgICAgIHRoaXMucmVqZWN0UGVuZGluZ0NoZWNrb3V0cyhjaGVja291dEVycm9yKVxuICAgICAgfSlcbiAgICB9KVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gcGVuZGluZyBjaGVja291dHMgaGF2ZSBiZWVuIGRyYWluZWQgYXMgZmFyIGFzIHBvc3NpYmxlLiAqL1xuICBhc3luYyBkcmFpblBlbmRpbmdDaGVja291dHMoKSB7XG4gICAgaWYgKHRoaXMucGVuZGluZ0NoZWNrb3V0RHJhaW5Qcm9taXNlKSB7XG4gICAgICBhd2FpdCB0aGlzLnBlbmRpbmdDaGVja291dERyYWluUHJvbWlzZVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UgPSB0aGlzLmRyYWluUGVuZGluZ0NoZWNrb3V0c0FjdHVhbCgpXG5cbiAgICB0cnkge1xuICAgICAgYXdhaXQgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2VcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXREcmFpblByb21pc2UgPSB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBwZW5kaW5nIGNoZWNrb3V0cyBoYXZlIGJlZW4gZHJhaW5lZCBhcyBmYXIgYXMgcG9zc2libGUuICovXG4gIGFzeW5jIGRyYWluUGVuZGluZ0NoZWNrb3V0c0FjdHVhbCgpIHtcbiAgICB3aGlsZSAodGhpcy5wZW5kaW5nQ2hlY2tvdXRzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGNoZWNrb3V0ID0gdGhpcy5wZW5kaW5nQ2hlY2tvdXRzWzBdXG4gICAgICBsZXQgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9uczogZmFsc2V9KVxuXG4gICAgICBpZiAoIWNvbm5lY3Rpb24pIHtcbiAgICAgICAgYXdhaXQgdGhpcy5yZWFwSWRsZUNvbm5lY3Rpb25zKClcbiAgICAgICAgY29ubmVjdGlvbiA9IHRoaXMudGFrZUlkbGVDb25uZWN0aW9uRm9yUmV1c2VLZXkoY2hlY2tvdXQucmV1c2VLZXksIHtpbmNsdWRlT3BlblRyYW5zYWN0aW9uczogZmFsc2V9KVxuICAgICAgfVxuXG4gICAgICBpZiAoIWNvbm5lY3Rpb24gJiYgIXRoaXMuY2FuU3Bhd25Db25uZWN0aW9uKCkpIHtcbiAgICAgICAgY29uc3QgY2xvc2VkQ29ubmVjdGlvbiA9IGF3YWl0IHRoaXMuY2xvc2VPbmVJZGxlQ29ubmVjdGlvbkZvckNhcGFjaXR5KClcblxuICAgICAgICBpZiAoY2xvc2VkQ29ubmVjdGlvbikgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKCFjb25uZWN0aW9uICYmIHRoaXMuY2FuU3Bhd25Db25uZWN0aW9uKCkpIHtcbiAgICAgICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXRzLnNoaWZ0KClcbiAgICAgICAgYXdhaXQgdGhpcy5zcGF3bkFuZFJlc29sdmVQZW5kaW5nQ2hlY2tvdXQoY2hlY2tvdXQpXG5cbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgaWYgKCFjb25uZWN0aW9uKSByZXR1cm5cblxuICAgICAgdGhpcy5wZW5kaW5nQ2hlY2tvdXRzLnNoaWZ0KClcbiAgICAgIGF3YWl0IHRoaXMucmVzb2x2ZVBlbmRpbmdDaGVja291dChjaGVja291dCwgY29ubmVjdGlvbilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogQHBhcmFtIHtQZW5kaW5nQ2hlY2tvdXR9IGNoZWNrb3V0IC0gQ2hlY2tvdXQgcmVxdWVzdCB0byByZXNvbHZlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHRoZSBjaGVja291dCBoYXMgYmVlbiBoYW5kbGVkLlxuICAgKi9cbiAgYXN5bmMgc3Bhd25BbmRSZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0KSB7XG4gICAgbGV0IGNvbm5lY3Rpb25cblxuICAgIHRyeSB7XG4gICAgICBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5zcGF3bkNvbm5lY3Rpb25Gb3JDaGVja291dChjaGVja291dC5kYXRhYmFzZUNvbmZpZywgY2hlY2tvdXQucmV1c2VLZXkpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gc3Bhd24gZGF0YWJhc2UgY29ubmVjdGlvbi5cIiwge2NhdXNlOiBlcnJvcn0pKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgYXdhaXQgdGhpcy5yZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7UGVuZGluZ0NoZWNrb3V0fSBjaGVja291dCAtIENoZWNrb3V0IHJlcXVlc3QgdG8gcmVzb2x2ZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24gdG8gYWN0aXZhdGUuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSAtIFJlc29sdmVzIHdoZW4gdGhlIGNoZWNrb3V0IGhhcyBiZWVuIGhhbmRsZWQuXG4gICAqL1xuICBhc3luYyByZXNvbHZlUGVuZGluZ0NoZWNrb3V0KGNoZWNrb3V0LCBjb25uZWN0aW9uKSB7XG4gICAgdHJ5IHtcbiAgICAgIGNoZWNrb3V0LnJlc29sdmUoYXdhaXQgdGhpcy5hY3RpdmF0ZUNvbm5lY3Rpb24oY29ubmVjdGlvbiwgY2hlY2tvdXQub3B0aW9ucykpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIGNoZWNrb3V0LnJlamVjdChlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoXCJGYWlsZWQgdG8gYWN0aXZhdGUgZGF0YWJhc2UgY29ubmVjdGlvbi5cIiwge2NhdXNlOiBlcnJvcn0pKVxuICAgIH1cbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gLSBXaGV0aGVyIGFuIGlkbGUgY29ubmVjdGlvbiB3YXMgY2xvc2VkIHRvIGZyZWUgY2FwYWNpdHkuICovXG4gIGFzeW5jIGNsb3NlT25lSWRsZUNvbm5lY3Rpb25Gb3JDYXBhY2l0eSgpIHtcbiAgICBjb25zdCBjb25uZWN0aW9uID0gdGhpcy5jb25uZWN0aW9ucy5maW5kKChjYW5kaWRhdGUpID0+ICF0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY2FuZGlkYXRlKSlcblxuICAgIGlmICghY29ubmVjdGlvbikgcmV0dXJuIGZhbHNlXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25zID0gdGhpcy5jb25uZWN0aW9ucy5maWx0ZXIoKGNhbmRpZGF0ZSkgPT4gY2FuZGlkYXRlICE9PSBjb25uZWN0aW9uKVxuICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG5cbiAgICByZXR1cm4gdHJ1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEB0ZW1wbGF0ZSBUXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9iYXNlLmpzXCIpLkNvbm5lY3Rpb25DaGVja291dE9wdGlvbnMgfCBmdW5jdGlvbihpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCkgOiBQcm9taXNlPFQ+fSBvcHRpb25zT3JDYWxsYmFjayAtIENoZWNrb3V0IG9wdGlvbnMgb3IgY2FsbGJhY2sgdG8gaW52b2tlIHdpdGggdGhlIGNvbm5lY3Rpb24uXG4gICAqIEBwYXJhbSB7ZnVuY3Rpb24oaW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQpIDogUHJvbWlzZTxUPn0gW2NhbGxiYWNrXSAtIENhbGxiYWNrIHRvIGludm9rZSB3aXRoIHRoZSBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxUPn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBjYWxsYmFjayByZXN1bHQuXG4gICAqL1xuICBhc3luYyB3aXRoQ29ubmVjdGlvbihvcHRpb25zT3JDYWxsYmFjaywgY2FsbGJhY2spIHtcbiAgICBjb25zdCBvcHRpb25zID0gdHlwZW9mIG9wdGlvbnNPckNhbGxiYWNrID09IFwiZnVuY3Rpb25cIiA/IHt9IDogb3B0aW9uc09yQ2FsbGJhY2tcbiAgICBjb25zdCBhY3R1YWxDYWxsYmFjayA9IHR5cGVvZiBvcHRpb25zT3JDYWxsYmFjayA9PSBcImZ1bmN0aW9uXCIgPyBvcHRpb25zT3JDYWxsYmFjayA6IGNhbGxiYWNrXG5cbiAgICBpZiAoIWFjdHVhbENhbGxiYWNrKSB0aHJvdyBuZXcgRXJyb3IoXCJ3aXRoQ29ubmVjdGlvbiByZXF1aXJlcyBhIGNhbGxiYWNrXCIpXG5cbiAgICBjb25zdCBjb25uZWN0aW9uID0gYXdhaXQgdGhpcy5jaGVja291dChvcHRpb25zKVxuICAgIGNvbnN0IGlkID0gY29ubmVjdGlvbi5nZXRJZFNlcSgpXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5ydW4oaWQsIGFzeW5jICgpID0+IHtcbiAgICAgIHRyeSB7XG4gICAgICAgIHJldHVybiBhd2FpdCBhY3R1YWxDYWxsYmFjayhjb25uZWN0aW9uKVxuICAgICAgfSBmaW5hbGx5IHtcbiAgICAgICAgYXdhaXQgdGhpcy5jaGVja2luKGNvbm5lY3Rpb24pXG4gICAgICB9XG4gICAgfSlcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IC0gVGhlIGN1cnJlbnQgY29ubmVjdGlvbi4gICovXG4gIGdldEN1cnJlbnRDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGlkID0gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5nZXRTdG9yZSgpXG5cbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgY29uc3QgZmFsbGJhY2tDb25uZWN0aW9uID0gdGhpcy5nZXRHbG9iYWxDb25uZWN0aW9uKClcblxuICAgICAgaWYgKGZhbGxiYWNrQ29ubmVjdGlvbikge1xuICAgICAgICByZXR1cm4gZmFsbGJhY2tDb25uZWN0aW9uXG4gICAgICB9XG5cbiAgICAgIHRocm93IG5ldyBFcnJvcihcIklEIGhhc24ndCBiZWVuIHNldCBmb3IgdGhpcyBhc3luYyBjb250ZXh0XCIpXG4gICAgfVxuXG4gICAgaWYgKCEoaWQgaW4gdGhpcy5jb25uZWN0aW9uc0luVXNlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBDb25uZWN0aW9uICR7aWR9IGRvZXNuJ3QgZXhpc3QgYW55IG1vcmUgLSBoYXMgaXQgYmVlbiBjaGVja2VkIGluIGFnYWluP2ApXG4gICAgfVxuXG4gICAgY29uc3QgY3VycmVudENvbm5lY3Rpb24gPSB0aGlzLmNvbm5lY3Rpb25zSW5Vc2VbaWRdXG5cbiAgICBpZiAoIWN1cnJlbnRDb25uZWN0aW9uKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYENvdWxkbid0IGdldCBjdXJyZW50IGNvbm5lY3Rpb24gZnJvbSB0aGF0IElEOiAke2lkfWApXG4gICAgfVxuXG4gICAgcmV0dXJuIGN1cnJlbnRDb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIGEgZmFsbGJhY2sgY29ubmVjdGlvbiBmb3IgdGhpcyBwb29sIGlkZW50aWZpZXIgdGhhdCB3aWxsIGJlIHVzZWQgd2hlbiBubyBhc3luYyBjb250ZXh0IGlzIGF2YWlsYWJsZS5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdH0gY29ubmVjdGlvbiAtIENvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHNldEdsb2JhbENvbm5lY3Rpb24oY29ubmVjdGlvbikge1xuICAgIGNvbnN0IGtsYXNzID0gLyoqIEB0eXBlIHt0eXBlb2YgVmVsb2Npb3VzRGF0YWJhc2VQb29sQXN5bmNUcmFja2VkTXVsdGlDb25uZWN0aW9ufSAqLyAodGhpcy5jb25zdHJ1Y3RvcilcbiAgICBsZXQgbWFwRm9yQ29uZmlndXJhdGlvbiA9IGtsYXNzLmdsb2JhbENvbm5lY3Rpb25zLmdldCh0aGlzLmNvbmZpZ3VyYXRpb24pXG5cbiAgICBpZiAoIW1hcEZvckNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIG1hcEZvckNvbmZpZ3VyYXRpb24gPSB7fVxuICAgICAga2xhc3MuZ2xvYmFsQ29ubmVjdGlvbnMuc2V0KHRoaXMuY29uZmlndXJhdGlvbiwgbWFwRm9yQ29uZmlndXJhdGlvbilcbiAgICB9XG5cbiAgICBtYXBGb3JDb25maWd1cmF0aW9uW3RoaXMuaWRlbnRpZmllcl0gPSBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogRW5zdXJlcyBhIGdsb2JhbCBmYWxsYmFjayBjb25uZWN0aW9uIGV4aXN0cyBmb3IgdGhpcyBwb29sIGlkZW50aWZpZXIgYW5kIHJldHVybnMgaXQuXG4gICAqIElmIG9uZSBpcyBhbHJlYWR5IHNldCwgaXQgaXMgcmV0dXJuZWQgYW5kIGFsc28gbWFkZSBhdmFpbGFibGUgaW4gdGhlIHBvb2wgcXVldWUuXG4gICAqIE90aGVyd2lzZSBhIG5ldyBjb25uZWN0aW9uIGlzIHNwYXduZWQsIHJlZ2lzdGVyZWQsIGFuZCBxdWV1ZWQuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gLSBSZXNvbHZlcyB3aXRoIHRoZSBnbG9iYWwgY29ubmVjdGlvbi5cbiAgICovXG4gIGFzeW5jIGVuc3VyZUdsb2JhbENvbm5lY3Rpb24oKSB7XG4gICAgY29uc3QgZXhpc3RpbmcgPSB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb24oKVxuXG4gICAgaWYgKGV4aXN0aW5nKSByZXR1cm4gZXhpc3RpbmdcblxuICAgIGNvbnN0IGNvbm5lY3Rpb24gPSBhd2FpdCB0aGlzLnNwYXduQ29ubmVjdGlvbigpXG5cbiAgICB0aGlzLnNldEdsb2JhbENvbm5lY3Rpb24oY29ubmVjdGlvbilcblxuICAgIHJldHVybiBjb25uZWN0aW9uXG4gIH1cblxuICAvKipcbiAgICogU2V0IGEgc2hhcmVkIGNvbm5lY3Rpb24gZm9yIHRlc3QgbW9kZSBzbyB0aGF0IEhUVFAgaGFuZGxlcnMgcnVubmluZ1xuICAgKiBpbiB0aGUgc2FtZSBwcm9jZXNzIGNhbiByZXVzZSB0aGUgdGVzdCBydW5uZXIncyBkYXRhYmFzZSBjb25uZWN0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gU2hhcmVkIGNvbm5lY3Rpb24uXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc2V0VGVzdFNoYXJlZENvbm5lY3Rpb24oY29ubmVjdGlvbikge1xuICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHt2b2lkfSAqL1xuICBjbGVhclRlc3RTaGFyZWRDb25uZWN0aW9uKCkge1xuICAgIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uID0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY29ubmVjdGlvbiB0aWVkIHRvIHRoZSBjdXJyZW50IGFzeW5jIGNvbnRleHQsIGlmIGFueS5cbiAgICogRmFsbHMgYmFjayB0byB0aGUgdGVzdCBzaGFyZWQgY29ubmVjdGlvbiB3aGVuIG5vIGFzeW5jIGNvbnRleHQgZXhpc3RzLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgfCB1bmRlZmluZWR9IC0gVGhlIGN1cnJlbnQgY29udGV4dCBjb25uZWN0aW9uLlxuICAgKi9cbiAgZ2V0Q3VycmVudENvbnRleHRDb25uZWN0aW9uKCkge1xuICAgIGNvbnN0IGlkID0gdGhpcy5hc3luY0xvY2FsU3RvcmFnZS5nZXRTdG9yZSgpXG5cbiAgICBpZiAoaWQgPT09IHVuZGVmaW5lZCkgcmV0dXJuIHRoaXMuX3Rlc3RTaGFyZWRDb25uZWN0aW9uXG5cbiAgICByZXR1cm4gdGhpcy5nZXRDdXJyZW50Q29ubmVjdGlvbigpXG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0IHwgdW5kZWZpbmVkfSAtIFRoZSBnbG9iYWwgY29ubmVjdGlvbi5cbiAgICovXG4gIGdldEdsb2JhbENvbm5lY3Rpb24oKSB7XG4gICAgY29uc3QgY29ubmVjdGlvbiA9IHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKVxuXG4gICAgaWYgKCFjb25uZWN0aW9uKSByZXR1cm5cbiAgICBpZiAoIXRoaXMuY29ubmVjdGlvbk1hdGNoZXNDdXJyZW50Q29uZmlndXJhdGlvbihjb25uZWN0aW9uKSkgcmV0dXJuXG5cbiAgICByZXR1cm4gY29ubmVjdGlvblxuICB9XG5cbiAgLyoqXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdCB8IHVuZGVmaW5lZH0gLSBUaGUgZ2xvYmFsIGNvbm5lY3Rpb24gZm9yIHRoaXMgcG9vbCBpZGVudGlmaWVyLlxuICAgKi9cbiAgZ2V0R2xvYmFsQ29ubmVjdGlvbkZvcklkZW50aWZpZXIoKSB7XG4gICAgY29uc3Qga2xhc3MgPSAvKiogQHR5cGUge3R5cGVvZiBWZWxvY2lvdXNEYXRhYmFzZVBvb2xBc3luY1RyYWNrZWRNdWx0aUNvbm5lY3Rpb259ICovICh0aGlzLmNvbnN0cnVjdG9yKVxuICAgIGNvbnN0IG1hcEZvckNvbmZpZ3VyYXRpb24gPSBrbGFzcy5nbG9iYWxDb25uZWN0aW9ucy5nZXQodGhpcy5jb25maWd1cmF0aW9uKVxuXG4gICAgcmV0dXJuIG1hcEZvckNvbmZpZ3VyYXRpb24/Llt0aGlzLmlkZW50aWZpZXJdXG4gIH1cblxuICAvKiogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLiAqL1xuICBjbGVhckdsb2JhbENvbm5lY3Rpb25Gb3JJZGVudGlmaWVyKCkge1xuICAgIGNvbnN0IGtsYXNzID0gLyoqIEB0eXBlIHt0eXBlb2YgVmVsb2Npb3VzRGF0YWJhc2VQb29sQXN5bmNUcmFja2VkTXVsdGlDb25uZWN0aW9ufSAqLyAodGhpcy5jb25zdHJ1Y3RvcilcbiAgICBjb25zdCBtYXBGb3JDb25maWd1cmF0aW9uID0ga2xhc3MuZ2xvYmFsQ29ubmVjdGlvbnMuZ2V0KHRoaXMuY29uZmlndXJhdGlvbilcblxuICAgIGlmICghbWFwRm9yQ29uZmlndXJhdGlvbikgcmV0dXJuXG5cbiAgICBkZWxldGUgbWFwRm9yQ29uZmlndXJhdGlvblt0aGlzLmlkZW50aWZpZXJdXG4gIH1cblxuICAvKipcbiAgICogQ2xlYXJzIHNjaGVtYSBtZXRhZGF0YSBjYWNoZWQgYnkgZXZlcnkgbGl2ZSBjb25uZWN0aW9uIG93bmVkIGJ5IHRoaXMgcG9vbC5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgY2xlYXJTY2hlbWFDYWNoZSgpIHtcbiAgICBjb25zdCBjb25uZWN0aW9ucyA9IG5ldyBTZXQoW1xuICAgICAgLi4udGhpcy5jb25uZWN0aW9ucyxcbiAgICAgIC4uLk9iamVjdC52YWx1ZXModGhpcy5jb25uZWN0aW9uc0luVXNlKSxcbiAgICAgIHRoaXMuZ2V0R2xvYmFsQ29ubmVjdGlvbigpLFxuICAgICAgdGhpcy5fdGVzdFNoYXJlZENvbm5lY3Rpb25cbiAgICBdLmZpbHRlcihCb29sZWFuKSlcblxuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBjb25uZWN0aW9ucykge1xuICAgICAgaWYgKGNvbm5lY3Rpb24pIHRoaXMuX2NsZWFyQ29ubmVjdGlvblNjaGVtYUNhY2hlKGNvbm5lY3Rpb24pXG4gICAgfVxuICB9XG5cbiAgLyoqIEByZXR1cm5zIHtudW1iZXIgfCBudWxsfSAtIElkbGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMsIG9yIG51bGwgd2hlbiBkaXNhYmxlZC4gKi9cbiAgaWRsZVRpbWVvdXRNaWxsaXMoKSB7XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldENvbmZpZ3VyYXRpb24oKS5wb29sPy5pZGxlVGltZW91dE1pbGxpc1xuXG4gICAgaWYgKHZhbHVlID09PSBudWxsKSByZXR1cm4gbnVsbFxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09IFwibnVtYmVyXCIgJiYgTnVtYmVyLmlzRmluaXRlKHZhbHVlKSAmJiB2YWx1ZSA+PSAwKSByZXR1cm4gdmFsdWVcblxuICAgIHJldHVybiBERUZBVUxUX0lETEVfVElNRU9VVF9NSUxMSVNcbiAgfVxuXG4gIC8qKiBAcmV0dXJucyB7dm9pZH0gKi9cbiAgc2NoZWR1bGVJZGxlQ29ubmVjdGlvblJlYXBlcigpIHtcbiAgICBpZiAodGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKSByZXR1cm5cbiAgICBpZiAodGhpcy5jb25uZWN0aW9ucy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgY29uc3QgaWRsZVRpbWVvdXRNaWxsaXMgPSB0aGlzLmlkbGVUaW1lb3V0TWlsbGlzKClcblxuICAgIGlmIChpZGxlVGltZW91dE1pbGxpcyA9PT0gbnVsbCkgcmV0dXJuXG5cbiAgICBjb25zdCBkZWxheSA9IHRoaXMubmV4dElkbGVDb25uZWN0aW9uUmVhcERlbGF5KGlkbGVUaW1lb3V0TWlsbGlzKVxuXG4gICAgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICB0aGlzLmlkbGVDb25uZWN0aW9uUmVhcGVyVGltZXIgPSB1bmRlZmluZWRcbiAgICAgIHZvaWQgdGhpcy5yZWFwSWRsZUNvbm5lY3Rpb25zKCkuY2F0Y2goKGVycm9yKSA9PiB7XG4gICAgICAgIHRoaXMubG9nZ2VyLndhcm4oKCkgPT4gW1wiRmFpbGVkIHRvIHJlYXAgaWRsZSBkYXRhYmFzZSBjb25uZWN0aW9uczpcIiwgZXJyb3JdKVxuICAgICAgfSlcbiAgICB9LCBkZWxheSlcblxuICAgIGlmICh0eXBlb2YgdGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyLnVucmVmID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lci51bnJlZigpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7bnVtYmVyfSBpZGxlVGltZW91dE1pbGxpcyAtIElkbGUgdGltZW91dCBpbiBtaWxsaXNlY29uZHMuXG4gICAqIEByZXR1cm5zIHtudW1iZXJ9IC0gRGVsYXkgYmVmb3JlIHRoZSBuZXh0IHJlYXAuXG4gICAqL1xuICBuZXh0SWRsZUNvbm5lY3Rpb25SZWFwRGVsYXkoaWRsZVRpbWVvdXRNaWxsaXMpIHtcbiAgICBsZXQgZGVsYXkgPSBpZGxlVGltZW91dE1pbGxpc1xuICAgIGNvbnN0IG5vdyA9IERhdGUubm93KClcblxuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiB0aGlzLmNvbm5lY3Rpb25zKSB7XG4gICAgICBpZiAodGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pKSBjb250aW51ZVxuXG4gICAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0lETEVfQ09OTkVDVElPTl9DSEVDS0VEX0lOX0FUXT86IG51bWJlcn19ICovIChjb25uZWN0aW9uKVxuICAgICAgY29uc3QgY2hlY2tlZEluQXQgPSB0cmFja2VkQ29ubmVjdGlvbltJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF1cblxuICAgICAgaWYgKHR5cGVvZiBjaGVja2VkSW5BdCAhPT0gXCJudW1iZXJcIikgY29udGludWVcblxuICAgICAgZGVsYXkgPSBNYXRoLm1pbihkZWxheSwgTWF0aC5tYXgoMCwgaWRsZVRpbWVvdXRNaWxsaXMgLSAobm93IC0gY2hlY2tlZEluQXQpKSlcbiAgICB9XG5cbiAgICByZXR1cm4gZGVsYXlcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgaWRsZSBjaGVja2VkLWluIGNvbm5lY3Rpb25zIHRoYXQgaGF2ZSBleGNlZWRlZCB0aGUgY29uZmlndXJlZCB0aW1lb3V0LlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgcmVhcElkbGVDb25uZWN0aW9ucygpIHtcbiAgICBpZiAodGhpcy5jb25uZWN0aW9ucy5sZW5ndGggPT09IDApIHJldHVyblxuXG4gICAgY29uc3QgaWRsZVRpbWVvdXRNaWxsaXMgPSB0aGlzLmlkbGVUaW1lb3V0TWlsbGlzKClcblxuICAgIGlmIChpZGxlVGltZW91dE1pbGxpcyA9PT0gbnVsbCkgcmV0dXJuXG5cbiAgICBjb25zdCBub3cgPSBEYXRlLm5vdygpXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSAqL1xuICAgIGNvbnN0IGtlcHRDb25uZWN0aW9ucyA9IFtdXG4gICAgLyoqIEB0eXBlIHtpbXBvcnQoXCIuLi9kcml2ZXJzL2Jhc2UuanNcIikuZGVmYXVsdFtdfSAqL1xuICAgIGNvbnN0IGV4cGlyZWRDb25uZWN0aW9ucyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgdGhpcy5jb25uZWN0aW9ucykge1xuICAgICAgY29uc3QgdHJhY2tlZENvbm5lY3Rpb24gPSAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0ICYge1tDTE9TRURfQ09OTkVDVElPTl0/OiBib29sZWFuLCBbSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdPzogbnVtYmVyfX0gKi8gKGNvbm5lY3Rpb24pXG5cbiAgICAgIGlmICh0cmFja2VkQ29ubmVjdGlvbltDTE9TRURfQ09OTkVDVElPTl0pIGNvbnRpbnVlXG4gICAgICBpZiAodGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pKSB7XG4gICAgICAgIGtlcHRDb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGNoZWNrZWRJbkF0ID0gdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG4gICAgICBjb25zdCBleHBpcmVkID0gdHlwZW9mIGNoZWNrZWRJbkF0ID09PSBcIm51bWJlclwiICYmIG5vdyAtIGNoZWNrZWRJbkF0ID49IGlkbGVUaW1lb3V0TWlsbGlzXG5cbiAgICAgIGlmIChleHBpcmVkKSB7XG4gICAgICAgIGV4cGlyZWRDb25uZWN0aW9ucy5wdXNoKGNvbm5lY3Rpb24pXG4gICAgICB9IGVsc2Uge1xuICAgICAgICBrZXB0Q29ubmVjdGlvbnMucHVzaChjb25uZWN0aW9uKVxuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuY29ubmVjdGlvbnMgPSBrZXB0Q29ubmVjdGlvbnNcblxuICAgIGZvciAoY29uc3QgY29ubmVjdGlvbiBvZiBleHBpcmVkQ29ubmVjdGlvbnMpIHtcbiAgICAgIGF3YWl0IHRoaXMuY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pXG4gICAgfVxuXG4gICAgLy8gQSBjb25jdXJyZW50IGZpcmUtYW5kLWZvcmdldCBzY2hlZHVsZWQgcmVhcCBtYXkgYWxyZWFkeSBiZSBjbG9zaW5nXG4gICAgLy8gY29ubmVjdGlvbnMgdGhpcyBjYWxsIGRpZCBub3QgZXhwaXJlIGl0c2VsZiAoaXQgbWF5IGhhdmUgcmVtb3ZlZCB0aGVtIGZyb21cbiAgICAvLyBgdGhpcy5jb25uZWN0aW9uc2AgZmlyc3QpLiBBd2FpdCB0aG9zZSBpbi1mbGlnaHQgY2xvc2VzIHRvbyBzbyBhIGNhbGxlclxuICAgIC8vIHRoYXQgYXdhaXRzIGByZWFwSWRsZUNvbm5lY3Rpb25zKClgIGlzIGd1YXJhbnRlZWQgdGhlIHBvb2wncyBpZGxlXG4gICAgLy8gY29ubmVjdGlvbnMgYXJlIGZ1bGx5IGNsb3NlZCwgbm90IG1pZC1gY2xvc2UoKWAuXG4gICAgaWYgKHRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzLnNpemUgPiAwKSB7XG4gICAgICBhd2FpdCBQcm9taXNlLmFsbFNldHRsZWQoWy4uLnRoaXMuaW5mbGlnaHRDb25uZWN0aW9uQ2xvc2VzXSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb25uZWN0aW9ucy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLnNjaGVkdWxlSWRsZUNvbm5lY3Rpb25SZWFwZXIoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiB0byBpbnNwZWN0LlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoZSBjb25uZWN0aW9uIGhhcyBhbiBvcGVuIHRyYW5zYWN0aW9uLlxuICAgKi9cbiAgY29ubmVjdGlvbkhhc09wZW5UcmFuc2FjdGlvbihjb25uZWN0aW9uKSB7XG4gICAgcmV0dXJuIGNvbm5lY3Rpb24uX3RyYW5zYWN0aW9uc0NvdW50ID4gMFxuICB9XG5cbiAgLyoqXG4gICAqIFJvbGxzIGJhY2sgYW55IHRyYW5zYWN0aW9uIGEgcHJldmlvdXMgaG9sZGVyIGxlZnQgb3BlbiBiZWZvcmUgYSBjb25uZWN0aW9uXG4gICAqIHJlLWVudGVycyB0aGUgaWRsZSBwb29sLiBBIGNvbm5lY3Rpb24gcmV0dXJuZWQgdG8gdGhlIHBvb2wgd2l0aCBhbiBvcGVuXG4gICAqIHRyYW5zYWN0aW9uIHdvdWxkIG90aGVyd2lzZSBiZSBoYW5kZWQgdG8gYW4gdW5yZWxhdGVkIGNoZWNrb3V0LCB3aG9zZVxuICAgKiBzdGFydFRyYW5zYWN0aW9uKCkgdGhlbiBmYWlscyB3aXRoIFwiQSB0cmFuc2FjdGlvbiBpcyBhbHJlYWR5IHJ1bm5pbmdcIiBhbmRcbiAgICogcG9pc29ucyBldmVyeSBmb2xsb3dpbmcgY2FsbGVyIHRoYXQgcmV1c2VzIGl0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0fSBjb25uZWN0aW9uIC0gQ29ubmVjdGlvbiBiZWluZyBjaGVja2VkIGluLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIHRoZSBjb25uZWN0aW9uIGhvbGRzIG5vIG9wZW4gdHJhbnNhY3Rpb24uXG4gICAqL1xuICBhc3luYyByb2xsYmFja0xlZnRPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikge1xuICAgIGlmICghdGhpcy5jb25uZWN0aW9uSGFzT3BlblRyYW5zYWN0aW9uKGNvbm5lY3Rpb24pKSByZXR1cm5cblxuICAgIHRoaXMubG9nZ2VyLndhcm4oKCkgPT4gW2BSb2xsaW5nIGJhY2sgYSB0cmFuc2FjdGlvbiBsZWZ0IG9wZW4gb24gYSBjb25uZWN0aW9uIGJlaW5nIGNoZWNrZWQgaW4gKGlkZW50aWZpZXI9JHt0aGlzLmlkZW50aWZpZXJ9KS5gXSlcblxuICAgIHdoaWxlICh0aGlzLmNvbm5lY3Rpb25IYXNPcGVuVHJhbnNhY3Rpb24oY29ubmVjdGlvbikpIHtcbiAgICAgIGF3YWl0IGNvbm5lY3Rpb24ucm9sbGJhY2tUcmFuc2FjdGlvbigpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHR9IGNvbm5lY3Rpb24gLSBDb25uZWN0aW9uIHRvIGNsb3NlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyB3aGVuIGNvbXBsZXRlLlxuICAgKi9cbiAgYXN5bmMgY2xvc2VDb25uZWN0aW9uKGNvbm5lY3Rpb24pIHtcbiAgICAvLyBJZGVtcG90ZW50OiBhIGZpcmUtYW5kLWZvcmdldCBzY2hlZHVsZWQgcmVhcCBhbmQgYW4gZXhwbGljaXQgcmVhcCBjYW4gYm90aFxuICAgIC8vIHRhcmdldCB0aGUgc2FtZSBjb25uZWN0aW9uLiBBd2FpdCB0aGUgaW4tZmxpZ2h0IGNsb3NlIGluc3RlYWQgb2YgY2xvc2luZ1xuICAgIC8vIHR3aWNlICh3aGljaCBjYW4gdGhyb3cgb24gdGhlIGRyaXZlcikgb3IgcmV0dXJuaW5nIHdoaWxlIHRoZSB1bmRlcmx5aW5nXG4gICAgLy8gaGFuZGxlIGlzIHN0aWxsIG9wZW4uXG4gICAgY29uc3QgZXhpc3RpbmdDbG9zZSA9IHRoaXMuY29ubmVjdGlvbkNsb3NlUHJvbWlzZXMuZ2V0KGNvbm5lY3Rpb24pXG5cbiAgICBpZiAoZXhpc3RpbmdDbG9zZSkge1xuICAgICAgcmV0dXJuIGF3YWl0IGV4aXN0aW5nQ2xvc2VcbiAgICB9XG5cbiAgICBjb25zdCB0cmFja2VkQ29ubmVjdGlvbiA9IC8qKiBAdHlwZSB7aW1wb3J0KFwiLi4vZHJpdmVycy9iYXNlLmpzXCIpLmRlZmF1bHQgJiB7W0NMT1NFRF9DT05ORUNUSU9OXT86IGJvb2xlYW4sIFtJRExFX0NPTk5FQ1RJT05fQ0hFQ0tFRF9JTl9BVF0/OiBudW1iZXJ9fSAqLyAoY29ubmVjdGlvbilcblxuICAgIHRyYWNrZWRDb25uZWN0aW9uW0NMT1NFRF9DT05ORUNUSU9OXSA9IHRydWVcbiAgICBkZWxldGUgdHJhY2tlZENvbm5lY3Rpb25bSURMRV9DT05ORUNUSU9OX0NIRUNLRURfSU5fQVRdXG5cbiAgICBjb25zdCBjbG9zZVByb21pc2UgPSAoYXN5bmMgKCkgPT4ge1xuICAgICAgaWYgKHR5cGVvZiB0cmFja2VkQ29ubmVjdGlvbi5jbG9zZSA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIGF3YWl0IHRyYWNrZWRDb25uZWN0aW9uLmNsb3NlKClcbiAgICAgIH0gZWxzZSBpZiAodHlwZW9mIHRyYWNrZWRDb25uZWN0aW9uLmRpc2Nvbm5lY3QgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICBhd2FpdCB0cmFja2VkQ29ubmVjdGlvbi5kaXNjb25uZWN0KClcbiAgICAgIH1cbiAgICB9KSgpXG5cbiAgICB0aGlzLmNvbm5lY3Rpb25DbG9zZVByb21pc2VzLnNldChjb25uZWN0aW9uLCBjbG9zZVByb21pc2UpXG4gICAgdGhpcy5pbmZsaWdodENvbm5lY3Rpb25DbG9zZXMuYWRkKGNsb3NlUHJvbWlzZSlcblxuICAgIHRyeSB7XG4gICAgICBhd2FpdCBjbG9zZVByb21pc2VcbiAgICB9IGZpbmFsbHkge1xuICAgICAgdGhpcy5pbmZsaWdodENvbm5lY3Rpb25DbG9zZXMuZGVsZXRlKGNsb3NlUHJvbWlzZSlcbiAgICB9XG4gIH1cblxuICAvKiogQHJldHVybnMge3ZvaWR9ICovXG4gIGNsZWFySWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lcigpIHtcbiAgICBpZiAoIXRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lcikgcmV0dXJuXG5cbiAgICBjbGVhclRpbWVvdXQodGhpcy5pZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKVxuICAgIHRoaXMuaWRsZUNvbm5lY3Rpb25SZWFwZXJUaW1lciA9IHVuZGVmaW5lZFxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyBhbGwgYWN0aXZlIGFuZCBjYWNoZWQgY29ubmVjdGlvbnMgZm9yIHRoaXMgcG9vbC5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IC0gUmVzb2x2ZXMgd2hlbiBjb21wbGV0ZS5cbiAgICovXG4gIGFzeW5jIGNsb3NlQWxsKCkge1xuICAgIHRoaXMuY2xlYXJJZGxlQ29ubmVjdGlvblJlYXBlclRpbWVyKClcbiAgICB0aGlzLnJlamVjdFBlbmRpbmdDaGVja291dHMobmV3IEVycm9yKFwiRGF0YWJhc2UgcG9vbCB3YXMgY2xvc2VkIGJlZm9yZSBjaGVja291dCBjb21wbGV0ZWQuXCIpKVxuXG4gICAgY29uc3QgY29ubmVjdGlvbnMgPSBuZXcgU2V0KFtcbiAgICAgIC4uLnRoaXMuY29ubmVjdGlvbnMsXG4gICAgICAuLi5PYmplY3QudmFsdWVzKHRoaXMuY29ubmVjdGlvbnNJblVzZSksXG4gICAgICB0aGlzLmdldEdsb2JhbENvbm5lY3Rpb25Gb3JJZGVudGlmaWVyKCksXG4gICAgICB0aGlzLl90ZXN0U2hhcmVkQ29ubmVjdGlvblxuICAgIF0uZmlsdGVyKEJvb2xlYW4pKVxuXG4gICAgdGhpcy5jb25uZWN0aW9ucyA9IFtdXG4gICAgdGhpcy5jb25uZWN0aW9uc0luVXNlID0ge31cbiAgICB0aGlzLl90ZXN0U2hhcmVkQ29ubmVjdGlvbiA9IHVuZGVmaW5lZFxuICAgIHRoaXMuY2xlYXJHbG9iYWxDb25uZWN0aW9uRm9ySWRlbnRpZmllcigpXG5cbiAgICBmb3IgKGNvbnN0IGNvbm5lY3Rpb24gb2YgY29ubmVjdGlvbnMpIHtcbiAgICAgIGlmICghY29ubmVjdGlvbikgY29udGludWVcblxuICAgICAgYXdhaXQgdGhpcy5jbG9zZUNvbm5lY3Rpb24oY29ubmVjdGlvbilcbiAgICB9XG5cbiAgfVxuXG4gIC8qKlxuICAgKiBAcGFyYW0ge0Vycm9yfSBlcnJvciAtIEVycm9yIHRvIHJlamVjdCBwZW5kaW5nIGNoZWNrb3V0cyB3aXRoLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHJlamVjdFBlbmRpbmdDaGVja291dHMoZXJyb3IpIHtcbiAgICBjb25zdCBwZW5kaW5nQ2hlY2tvdXRzID0gdGhpcy5wZW5kaW5nQ2hlY2tvdXRzXG5cbiAgICB0aGlzLnBlbmRpbmdDaGVja291dHMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBjaGVja291dCBvZiBwZW5kaW5nQ2hlY2tvdXRzKSB7XG4gICAgICBjaGVja291dC5yZWplY3QoZXJyb3IpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcGxhY2VzIGFsbCBnbG9iYWxseSByZWdpc3RlcmVkIGZhbGxiYWNrIGNvbm5lY3Rpb25zLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4uL2RyaXZlcnMvYmFzZS5qc1wiKS5kZWZhdWx0Pn0gW2Nvbm5lY3Rpb25zXSAtIENvbm5lY3Rpb25zLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uLy4uL2NvbmZpZ3VyYXRpb24uanNcIikuZGVmYXVsdH0gW2NvbmZpZ3VyYXRpb25dIC0gQ29uZmlndXJhdGlvbiBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge3ZvaWR9IC0gTm8gcmV0dXJuIHZhbHVlLlxuICAgKi9cbiAgc3RhdGljIHNldEdsb2JhbENvbm5lY3Rpb25zKGNvbm5lY3Rpb25zLCBjb25maWd1cmF0aW9uKSB7XG4gICAgaWYgKCFjb25uZWN0aW9ucyAmJiAhY29uZmlndXJhdGlvbikge1xuICAgICAgdGhpcy5nbG9iYWxDb25uZWN0aW9ucyA9IG5ldyBXZWFrTWFwKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICghY29uZmlndXJhdGlvbikge1xuICAgICAgdGhpcy5nbG9iYWxDb25uZWN0aW9ucyA9IG5ldyBXZWFrTWFwKClcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMuc2V0KGNvbmZpZ3VyYXRpb24sIGNvbm5lY3Rpb25zIHx8IHt9KVxuICB9XG5cbiAgLyoqXG4gICAqIENsZWFycyBnbG9iYWxseSByZWdpc3RlcmVkIGZhbGxiYWNrIGNvbm5lY3Rpb25zIGZvciBhbGwgY29uZmlndXJhdGlvbnMgb3IgYSBzaW5nbGUgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuLi8uLi9jb25maWd1cmF0aW9uLmpzXCIpLmRlZmF1bHR9IFtjb25maWd1cmF0aW9uXSAtIENvbmZpZ3VyYXRpb24gaW5zdGFuY2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIHN0YXRpYyBjbGVhckdsb2JhbENvbm5lY3Rpb25zKGNvbmZpZ3VyYXRpb24pIHtcbiAgICBpZiAoIWNvbmZpZ3VyYXRpb24pIHtcbiAgICAgIHRoaXMuZ2xvYmFsQ29ubmVjdGlvbnMgPSBuZXcgV2Vha01hcCgpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICB0aGlzLmdsb2JhbENvbm5lY3Rpb25zLmRlbGV0ZShjb25maWd1cmF0aW9uKVxuICB9XG59XG4iXX0=
|
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
export const POOL_CONFIGURATION_KEY: unique symbol;
|
|
2
2
|
export default VelociousDatabasePoolBase;
|
|
3
|
+
export type ConnectionCheckoutOptions = {
|
|
4
|
+
/**
|
|
5
|
+
* - Human-readable name for the checked-out connection.
|
|
6
|
+
*/
|
|
7
|
+
name?: string | undefined;
|
|
8
|
+
};
|
|
3
9
|
declare class VelociousDatabasePoolBase {
|
|
4
10
|
/**
|
|
5
11
|
* @returns {VelociousDatabasePoolBase} - The current.
|
|
@@ -29,9 +35,10 @@ declare class VelociousDatabasePoolBase {
|
|
|
29
35
|
checkin(_connection: import("../drivers/base.js").default): void;
|
|
30
36
|
/**
|
|
31
37
|
* @abstract
|
|
38
|
+
* @param {ConnectionCheckoutOptions} [_options] - Checkout options.
|
|
32
39
|
* @returns {Promise<import("../drivers/base.js").default>} - Resolves with the checkout.
|
|
33
40
|
*/
|
|
34
|
-
checkout(): Promise<import("../drivers/base.js").default>;
|
|
41
|
+
checkout(_options?: ConnectionCheckoutOptions): Promise<import("../drivers/base.js").default>;
|
|
35
42
|
/**
|
|
36
43
|
* @abstract
|
|
37
44
|
* @returns {import("../drivers/base.js").default} - The current connection.
|
|
@@ -93,10 +100,11 @@ declare class VelociousDatabasePoolBase {
|
|
|
93
100
|
/**
|
|
94
101
|
* @template T
|
|
95
102
|
* @abstract
|
|
96
|
-
* @param {function(import("../drivers/base.js").default) : Promise<T>}
|
|
103
|
+
* @param {ConnectionCheckoutOptions | function(import("../drivers/base.js").default) : Promise<T>} _optionsOrCallback - Checkout options or callback function.
|
|
104
|
+
* @param {function(import("../drivers/base.js").default) : Promise<T>} [_callback] - Callback function.
|
|
97
105
|
* @returns {Promise<T>} - Resolves with the callback result.
|
|
98
106
|
*/
|
|
99
|
-
withConnection<T>(
|
|
107
|
+
withConnection<T>(_optionsOrCallback: ConnectionCheckoutOptions | ((arg0: import("../drivers/base.js").default) => Promise<T>), _callback?: (arg0: import("../drivers/base.js").default) => Promise<T>): Promise<T>;
|
|
100
108
|
/**
|
|
101
109
|
* Ensures a reusable connection exists for contexts where AsyncLocalStorage isn't set.
|
|
102
110
|
* Default implementation just checks out a connection.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/database/pool/base.js"],"names":[],"mappings":"AAMA,mDAA6E
|
|
1
|
+
{"version":3,"file":"base.d.ts","sourceRoot":"","sources":["../../../../src/database/pool/base.js"],"names":[],"mappings":"AAMA,mDAA6E;;;;;;;;AAiC7E;IACE;;OAEG;IACH,kBAFa,yBAAyB,CAMrC;IAED;;;OAGG;IACH,iCAFa,IAAI,CAEiB;IAElC;;;;OAIG;IACH,2CAHG;QAA4B,aAAa,EAAjC,aAAa;QACA,UAAU,EAAvB,MAAM;KAChB,EASA;IAPC,6BAA6D;IAK7D,mBAA4B;IAC5B,eAA8B;IAGhC;;;OAGG;IACH,qBAFW,OAAO,oBAAoB,EAAE,OAAO,QAI9C;IAED;;;;OAIG;IACH,oBAHW,yBAAyB,GACvB,OAAO,CAAC,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAIzD;IAED;;;OAGG;IACH,wBAFa,OAAO,oBAAoB,EAAE,OAAO,CAIhD;IAED;;;;OAIG;IACH,+BAFa,OAAO,oBAAoB,EAAE,OAAO,GAAG,SAAS,CAI5D;IAED;;OAEG;IACH,oBAFa,OAAO,8BAA8B,EAAE,yBAAyB,CAI5E;IAED;;OAEG;IACH,4BAFa,MAAM,CAiBlB;IAED;;;OAGG;IACH,kDAHW,OAAO,oBAAoB,EAAE,OAAO,GAClC,OAAO,CAMnB;IAED;;;;OAIG;IACH,oBAFa,IAAI,CAIhB;IAED;;;OAGG;IACH,wCAHW,OAAO,oBAAoB,EAAE,OAAO,GAClC,IAAI,CAIhB;IAED;;;OAGG;IACH,kBAFa,MAAM,CAIlB;IAED;;OAEG;IACH,cAFa,IAAI,CAIhB;IAED;;OAEG;IACH,4BAFW,cAAc,oBAAoB,EAAE,OAAO,QAIrD;IADC,qEAA8B;IAGhC;;OAEG;IACH,mBAFa,OAAO,CAAC,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAiBzD;IAED;;;OAGG;IACH,yCAHW,OAAO,8BAA8B,EAAE,yBAAyB,GAC9D,OAAO,CAAC,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAYzD;IAED;;;;;;OAMG;IACH,eANa,CAAC,sBAEH,yBAAyB,IAAG,CAAS,IAAoC,EAApC,OAAO,oBAAoB,EAAE,OAAO,KAAI,OAAO,CAAC,CAAC,CAAC,CAAA,cACvF,CAAS,IAAoC,EAApC,OAAO,oBAAoB,EAAE,OAAO,KAAI,OAAO,CAAC,CAAC,CAAC,GACzD,OAAO,CAAC,CAAC,CAAC,CAItB;IAED;;;;OAIG;IACH,0BAFa,OAAO,CAAC,OAAO,oBAAoB,EAAE,OAAO,CAAC,CAIzD;IAED;;;OAGG;IACH,YAFa,OAAO,CAAC,IAAI,CAAC,CAEP;CACpB;0BA/OyB,wBAAwB;mBAC/B,iBAAiB"}
|