velocious 1.0.663 → 1.0.665

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.
Files changed (50) hide show
  1. package/README.md +2 -2
  2. package/build/background-jobs/client.js +36 -6
  3. package/build/configuration-types.js +3 -3
  4. package/build/database/query/alter-table-base.js +11 -1
  5. package/build/src/background-jobs/client.d.ts.map +1 -1
  6. package/build/src/background-jobs/client.js +35 -6
  7. package/build/src/configuration-types.d.ts +8 -4
  8. package/build/src/configuration-types.d.ts.map +1 -1
  9. package/build/src/configuration-types.js +4 -4
  10. package/build/src/database/query/alter-table-base.d.ts.map +1 -1
  11. package/build/src/database/query/alter-table-base.js +12 -2
  12. package/build/src/sync/sync-api-client.d.ts +36 -10
  13. package/build/src/sync/sync-api-client.d.ts.map +1 -1
  14. package/build/src/sync/sync-api-client.js +58 -14
  15. package/build/src/sync/sync-client-types.d.ts +41 -2
  16. package/build/src/sync/sync-client-types.d.ts.map +1 -1
  17. package/build/src/sync/sync-client-types.js +20 -3
  18. package/build/src/sync/sync-client.d.ts +112 -3
  19. package/build/src/sync/sync-client.d.ts.map +1 -1
  20. package/build/src/sync/sync-client.js +306 -60
  21. package/build/src/sync/sync-publisher-types.d.ts +36 -3
  22. package/build/src/sync/sync-publisher-types.d.ts.map +1 -1
  23. package/build/src/sync/sync-publisher-types.js +16 -2
  24. package/build/src/sync/sync-publisher.d.ts +22 -3
  25. package/build/src/sync/sync-publisher.d.ts.map +1 -1
  26. package/build/src/sync/sync-publisher.js +134 -13
  27. package/build/src/sync/sync-realtime-bridge.d.ts +11 -5
  28. package/build/src/sync/sync-realtime-bridge.d.ts.map +1 -1
  29. package/build/src/sync/sync-realtime-bridge.js +37 -13
  30. package/build/src/sync/sync-scope-store.d.ts +32 -0
  31. package/build/src/sync/sync-scope-store.d.ts.map +1 -1
  32. package/build/src/sync/sync-scope-store.js +74 -4
  33. package/build/sync/sync-api-client.js +58 -13
  34. package/build/sync/sync-client-types.js +22 -2
  35. package/build/sync/sync-client.js +333 -63
  36. package/build/sync/sync-publisher-types.js +17 -1
  37. package/build/sync/sync-publisher.js +156 -15
  38. package/build/sync/sync-realtime-bridge.js +37 -12
  39. package/build/sync/sync-scope-store.js +79 -3
  40. package/package.json +1 -1
  41. package/src/background-jobs/client.js +36 -6
  42. package/src/configuration-types.js +3 -3
  43. package/src/database/query/alter-table-base.js +11 -1
  44. package/src/sync/sync-api-client.js +58 -13
  45. package/src/sync/sync-client-types.js +22 -2
  46. package/src/sync/sync-client.js +333 -63
  47. package/src/sync/sync-publisher-types.js +17 -1
  48. package/src/sync/sync-publisher.js +156 -15
  49. package/src/sync/sync-realtime-bridge.js +37 -12
  50. package/src/sync/sync-scope-store.js +79 -3
@@ -3,6 +3,8 @@ import Configuration from "../configuration.js";
3
3
  import Logger from "../logger.js";
4
4
  import { scalarModelPrimaryKeyValue } from "../utils/model-primary-key.js";
5
5
  import restArgsError from "../utils/rest-args-error.js";
6
+ import sha256Hex from "../utils/sha256-hex.js";
7
+ import stableJsonStringify from "../utils/stable-json.js";
6
8
  import { declaredSyncScopeAttributes } from "./sync-scope-attributes.js";
7
9
  import { deliverDeclaredBroadcasts, upsertSyncRow } from "./sync-change-fanout.js";
8
10
  import { isPublishingSuppressed } from "./sync-publish-suppression.js";
@@ -184,7 +186,8 @@ export default class SyncPublisher {
184
186
  : this.config.syncModel;
185
187
  await record.connection().afterCommit(async () => {
186
188
  try {
187
- const syncRow = await this.upsertPublishedSyncRow(attributes, operationScope);
189
+ const scopeColumnNames = resourceConfig.scopePlan.map(({ columnName }) => columnName);
190
+ const syncRow = await this.upsertPublishedSyncRow(attributes, operationScope, scopeColumnNames);
188
191
  await this.broadcaster()({
189
192
  body: {
190
193
  echoOrigin: null,
@@ -221,10 +224,16 @@ export default class SyncPublisher {
221
224
  const columns = {};
222
225
  /** @type {Record<string, string | null>} */
223
226
  const params = {};
227
+ const computedScopeAttributes = resourceConfig.scopeAttributesResolver
228
+ ? await this.resolveComputedScopeAttributes({ record, resourceConfig })
229
+ : null;
224
230
  for (const scopePlanEntry of resourceConfig.scopePlan) {
225
231
  /** @type {ReturnType<typeof JSON.parse>} */
226
232
  let rawValue;
227
- if (scopePlanEntry.resolver) {
233
+ if (computedScopeAttributes) {
234
+ rawValue = computedScopeAttributes[scopePlanEntry.scopeAttribute];
235
+ }
236
+ else if (scopePlanEntry.resolver) {
228
237
  rawValue = await scopePlanEntry.resolver(record);
229
238
  }
230
239
  else if (scopePlanEntry.recordAttribute) {
@@ -239,6 +248,43 @@ export default class SyncPublisher {
239
248
  }
240
249
  return { columns, params };
241
250
  }
251
+ /**
252
+ * Resolves and validates one computed scope-attributes declaration. The
253
+ * resolver runs once per published mutation with the exact connection that
254
+ * owns that mutation; every declared scope value is then reused for row
255
+ * persistence and broadcast routing so those two identities cannot drift.
256
+ * @param {{record: ReturnType<typeof JSON.parse>, resourceConfig: import("./sync-publisher-types.js").SyncPublisherResourceConfig}} args - Record and resource configuration.
257
+ * @returns {Promise<Record<string, string | number | null>>} Complete computed scope values.
258
+ */
259
+ async resolveComputedScopeAttributes({ record, resourceConfig }) {
260
+ const resolver = resourceConfig.scopeAttributesResolver;
261
+ if (!resolver)
262
+ throw new Error(`No computed scope-attributes resolver configured for ${resourceConfig.resourceType}`);
263
+ const resolved = await resolver({
264
+ configuration: this.config.configuration,
265
+ connection: record.connection(),
266
+ record
267
+ });
268
+ if (!isPlainObject(resolved)) {
269
+ throw new Error(`${resourceConfig.resourceType} static sync publish scopeAttributes resolver must resolve to a plain object`);
270
+ }
271
+ const declaredAttributes = resourceConfig.scopePlan.map(({ scopeAttribute }) => scopeAttribute);
272
+ for (const scopeAttribute of Object.keys(resolved)) {
273
+ if (!declaredAttributes.includes(scopeAttribute)) {
274
+ throw new Error(`${resourceConfig.resourceType} static sync publish scopeAttributes resolver returned unknown scope attribute: ${scopeAttribute} (the sync model declares: ${declaredAttributes.join(", ")})`);
275
+ }
276
+ }
277
+ for (const scopeAttribute of declaredAttributes) {
278
+ if (!Object.hasOwn(resolved, scopeAttribute)) {
279
+ throw new Error(`${resourceConfig.resourceType} static sync publish scopeAttributes resolver must resolve the declared scope attribute ${scopeAttribute}`);
280
+ }
281
+ const value = resolved[scopeAttribute];
282
+ if (value !== null && typeof value !== "string" && typeof value !== "number") {
283
+ throw new Error(`${resourceConfig.resourceType} static sync publish scope attribute ${scopeAttribute} must be a string, number, or null`);
284
+ }
285
+ }
286
+ return /** @type {Record<string, string | number | null>} */ (resolved);
287
+ }
242
288
  /**
243
289
  * Builds the framework sync channel entry for one published change: the
244
290
  * snapshotted payload plus the persisted sync row's public exact-row metadata
@@ -272,21 +318,43 @@ export default class SyncPublisher {
272
318
  /**
273
319
  * Upserts the published server-origin sync row for a resource identity:
274
320
  * server-origin rows carry a null actor column (no device to echo the
275
- * change back to), so repeated server changes to one resource reuse and
276
- * re-sequence one feed row.
321
+ * change back to), so repeated server changes to one complete resource and
322
+ * scope identity reuse and re-sequence one feed row. A database advisory
323
+ * lock serializes reconciliation plus the shared upsert because unique
324
+ * constraints containing nullable actor/scope columns do not enforce this
325
+ * identity portably across supported databases. Reconciliation retains the
326
+ * row with the newest feed sequence (then lowest id for a deterministic tie)
327
+ * and removes older matching server-origin rows before applying the current
328
+ * mutation.
277
329
  * @param {Record<string, ReturnType<typeof JSON.parse>>} attributes - Snapshotted sync row attributes.
278
330
  * @param {ReturnType<typeof JSON.parse>} syncModel - Operation-bound or static Sync model interface.
331
+ * @param {string[]} scopeColumnNames - Persisted scope columns participating in the complete identity.
279
332
  * @returns {Promise<ReturnType<typeof JSON.parse>>} Upserted sync row.
280
333
  */
281
- async upsertPublishedSyncRow(attributes, syncModel = this.config.syncModel) {
282
- const existingSync = await syncModel
283
- .where({
334
+ async upsertPublishedSyncRow(attributes, syncModel = this.config.syncModel, scopeColumnNames = []) {
335
+ /** @type {Record<string, ReturnType<typeof JSON.parse>>} */
336
+ const identity = {
284
337
  [this.config.actorForeignKeyColumn]: null,
285
338
  resource_id: attributes.resource_id,
286
339
  resource_type: attributes.resource_type
287
- })
288
- .first();
289
- return await upsertSyncRow({ attributes, existingSync, syncModel });
340
+ };
341
+ for (const columnName of scopeColumnNames) {
342
+ if (!Object.hasOwn(attributes, columnName)) {
343
+ throw new Error(`Published sync row identity is missing the scope column ${columnName}`);
344
+ }
345
+ identity[columnName] = attributes[columnName];
346
+ }
347
+ return await this.config.syncModel.withAdvisoryLock(syncPublisherIdentityLockName(identity), async () => {
348
+ const matchingSyncs = await syncModel
349
+ .where(identity)
350
+ .toArray();
351
+ matchingSyncs.sort(comparePublishedSyncRowsByRecency);
352
+ const [existingSync, ...duplicateSyncs] = matchingSyncs;
353
+ for (const duplicateSync of duplicateSyncs) {
354
+ await duplicateSync.destroy();
355
+ }
356
+ return await upsertSyncRow({ attributes, existingSync, syncModel });
357
+ }, { dedicatedConnection: true });
290
358
  }
291
359
  /**
292
360
  * Returns the broadcaster delivering declared broadcasts: the injected one,
@@ -334,6 +402,38 @@ export default class SyncPublisher {
334
402
  return this._logger;
335
403
  }
336
404
  }
405
+ /**
406
+ * Returns a deterministic, MySQL-safe advisory-lock name for one complete
407
+ * server-origin publisher identity. Stable JSON preserves null actor/scope
408
+ * components distinctly from strings, and the truncated SHA-256 digest keeps
409
+ * the final name below MySQL/MariaDB's 64-character `GET_LOCK` limit.
410
+ * @param {Record<string, ReturnType<typeof JSON.parse>>} identity - Complete sync-row identity in column form.
411
+ * @returns {string} Advisory-lock name.
412
+ */
413
+ function syncPublisherIdentityLockName(identity) {
414
+ const hash = sha256Hex(stableJsonStringify(identity)).slice(0, 32);
415
+ return `vsp:${hash}`;
416
+ }
417
+ /**
418
+ * Orders matching published rows by the feed's public recency contract so
419
+ * legacy duplicates have one deterministic survivor. Server sequences are
420
+ * positive and monotonic; a legacy null sequence is older than any assigned
421
+ * sequence, and the immutable row id breaks otherwise-equal ties.
422
+ * @param {ReturnType<typeof JSON.parse>} left - First matching sync row.
423
+ * @param {ReturnType<typeof JSON.parse>} right - Second matching sync row.
424
+ * @returns {number} Sort comparison with the canonical survivor first.
425
+ */
426
+ function comparePublishedSyncRowsByRecency(left, right) {
427
+ const leftSequence = left.serverSequence();
428
+ const rightSequence = right.serverSequence();
429
+ if (leftSequence === null && rightSequence !== null)
430
+ return 1;
431
+ if (leftSequence !== null && rightSequence === null)
432
+ return -1;
433
+ if (leftSequence !== rightSequence)
434
+ return rightSequence - leftSequence;
435
+ return left.id().localeCompare(right.id());
436
+ }
337
437
  /**
338
438
  * Resolves a model class's active publish declaration from `static sync`.
339
439
  * Opted-out (`publish: false`) and undeclared models resolve to null; every
@@ -378,12 +478,14 @@ function resourceConfigFromPublishDeclaration({ modelClass, publish, scopeAttrib
378
478
  }
379
479
  }
380
480
  }
481
+ const scopePlan = scopePlanFor({ eventId, modelClass, modelName, scopeAttributes, syncModel, syncScopeAttributes });
381
482
  return {
382
483
  broadcasts,
383
484
  modelClass,
384
485
  operations: operations === undefined ? DEFAULT_PUBLISHED_OPERATIONS : operations,
385
486
  resourceType: resourceType === undefined ? modelName : resourceType,
386
- scopePlan: scopePlanFor({ eventId, modelClass, modelName, scopeAttributes, syncModel, syncScopeAttributes }),
487
+ scopeAttributesResolver: typeof scopeAttributes === "function" ? scopeAttributes : undefined,
488
+ scopePlan,
387
489
  serialize: serialize === undefined ? defaultSerializedAttributes : serialize
388
490
  };
389
491
  }
@@ -395,7 +497,7 @@ function resourceConfigFromPublishDeclaration({ modelClass, publish, scopeAttrib
395
497
  * name map), or the record's own id when the model has no such attribute
396
498
  * (scope-root models). The deprecated `eventId` declaration forms map to a
397
499
  * fixed `eventId`/`event_id` plan for 1.0.503 compatibility.
398
- * @param {{eventId: import("./sync-publisher-types.js").SyncPublishDeclarationConfig["eventId"], modelClass: ReturnType<typeof JSON.parse>, modelName: string, scopeAttributes: Record<string, string> | undefined, syncModel: ReturnType<typeof JSON.parse>, syncScopeAttributes: string[] | null}} args - Declaration and sync-model scope args.
500
+ * @param {{eventId: import("./sync-publisher-types.js").SyncPublishDeclarationConfig["eventId"], modelClass: ReturnType<typeof JSON.parse>, modelName: string, scopeAttributes: import("./sync-publisher-types.js").SyncPublishDeclarationConfig["scopeAttributes"], syncModel: ReturnType<typeof JSON.parse>, syncScopeAttributes: string[] | null}} args - Declaration and sync-model scope args.
399
501
  * @returns {Array<import("./sync-publisher-types.js").SyncPublisherScopePlanEntry>} Derived scope plan.
400
502
  */
401
503
  function scopePlanFor({ eventId, modelClass, modelName, scopeAttributes, syncModel, syncScopeAttributes }) {
@@ -420,6 +522,14 @@ function scopePlanFor({ eventId, modelClass, modelName, scopeAttributes, syncMod
420
522
  }
421
523
  if (!syncScopeAttributes)
422
524
  return [];
525
+ if (typeof scopeAttributes === "function") {
526
+ return syncScopeAttributes.map((scopeAttribute) => ({
527
+ columnName: syncScopeColumnName({ scopeAttribute, syncModel }),
528
+ recordAttribute: null,
529
+ resolver: undefined,
530
+ scopeAttribute
531
+ }));
532
+ }
423
533
  if (scopeAttributes !== undefined && (typeof scopeAttributes !== "object" || Array.isArray(scopeAttributes))) {
424
534
  throw new Error(`${modelName} static sync publish scopeAttributes must be an object mapping scope attributes to record attribute names, got: ${String(scopeAttributes)}`);
425
535
  }
@@ -444,6 +554,17 @@ function scopePlanFor({ eventId, modelClass, modelName, scopeAttributes, syncMod
444
554
  };
445
555
  });
446
556
  }
557
+ /**
558
+ * Checks that a computed declaration returned an ordinary key/value object.
559
+ * @param {unknown} value - Resolver result.
560
+ * @returns {value is Record<string, unknown>} Whether the value is a plain object.
561
+ */
562
+ function isPlainObject(value) {
563
+ if (!value || typeof value !== "object" || Array.isArray(value))
564
+ return false;
565
+ const prototype = Object.getPrototypeOf(value);
566
+ return prototype === Object.prototype || prototype === null;
567
+ }
447
568
  /**
448
569
  * Resolves the sync-row column persisting a declared scope attribute.
449
570
  * @param {{scopeAttribute: string, syncModel: ReturnType<typeof JSON.parse>}} args - Scope attribute and sync model.
@@ -484,4 +605,4 @@ function isoDate(value) {
484
605
  }
485
606
  return value.toISOString();
486
607
  }
487
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1wdWJsaXNoZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3luYy9zeW5jLXB1Ymxpc2hlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxhQUFhLE1BQU0scUJBQXFCLENBQUE7QUFDL0MsT0FBTyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBQ2pDLE9BQU8sRUFBQywwQkFBMEIsRUFBQyxNQUFNLCtCQUErQixDQUFBO0FBQ3hFLE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBRXZELE9BQU8sRUFBQywyQkFBMkIsRUFBQyxNQUFNLDRCQUE0QixDQUFBO0FBQ3RFLE9BQU8sRUFBQyx5QkFBeUIsRUFBRSxhQUFhLEVBQUMsTUFBTSx5QkFBeUIsQ0FBQTtBQUNoRixPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSwrQkFBK0IsQ0FBQTtBQUNwRSxPQUFPLEVBQUMsc0JBQXNCLEVBQUMsTUFBTSx3QkFBd0IsQ0FBQTtBQUU3RCxzRkFBc0Y7QUFDdEYsTUFBTSx3QkFBd0IsR0FBRyxFQUFDLE1BQU0sRUFBRSxhQUFhLEVBQUUsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLEVBQUUsYUFBYSxFQUFDLENBQUE7QUFFeEc7Ozs7OztvREFNb0Q7QUFDcEQsTUFBTSw0QkFBNEIsR0FBRyxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUMsQ0FBQTtBQUV6RCxvREFBb0Q7QUFDcEQsTUFBTSxnQ0FBZ0MsR0FBRyxJQUFJLE9BQU8sRUFBRSxDQUFBO0FBRXREOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQTZCRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8sYUFBYTtJQUNoQzs7Ozs7Ozs7T0FRRztJQUNILFlBQVksT0FBTyxHQUFHLEVBQUU7UUFDdEIsTUFBTSxFQUFDLHFCQUFxQixHQUFHLHlCQUF5QixFQUFFLFdBQVcsRUFBRSxhQUFhLEdBQUcsYUFBYSxDQUFDLE9BQU8sRUFBRSxFQUFF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U0FBUywyQkFBMkIsQ0FBQyxNQUFNO0lBQ3pDLDREQUE0RDtJQUM1RCxNQUFNLFVBQVUsR0FBRyxFQUFDLEdBQUcsTUFBTSxDQUFDLFVBQVUsRUFBRSxFQUFDLENBQUE7SUFFM0MsS0FBSyxNQUFNLENBQUMsYUFBYSxFQUFFLEtBQUssQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLEVBQUUsQ0FBQztRQUNoRSxJQUFJLEtBQUssWUFBWSxJQUFJO1lBQUUsVUFBVSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQTtJQUM1RSxDQUFDO0lBRUQsT0FBTyxVQUFVLENBQUE7QUFDbkIsQ0FBQztBQUVEOzs7Ozs7R0FNRztBQUNILFNBQVMsT0FBTyxDQUFDLEtBQUs7SUFDcEIsSUFBSSxDQUFDLENBQUMsS0FBSyxZQUFZLElBQUksQ0FBQyxJQUFJLE1BQU0sQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsQ0FBQztRQUM5RCxNQUFNLElBQUksS0FBSyxDQUFDLDJEQUEyRCxDQUFDLENBQUE7SUFDOUUsQ0FBQztJQUVELE9BQU8sS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFBO0FBQzVCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBAdHMtY2hlY2tcblxuaW1wb3J0IENvbmZpZ3VyYXRpb24gZnJvbSBcIi4uL2NvbmZpZ3VyYXRpb24uanNcIlxuaW1wb3J0IExvZ2dlciBmcm9tIFwiLi4vbG9nZ2VyLmpzXCJcbmltcG9ydCB7c2NhbGFyTW9kZWxQcmltYXJ5S2V5VmFsdWV9IGZyb20gXCIuLi91dGlscy9tb2RlbC1wcmltYXJ5LWtleS5qc1wiXG5pbXBvcnQgcmVzdEFyZ3NFcnJvciBmcm9tIFwiLi4vdXRpbHMvcmVzdC1hcmdzLWVycm9yLmpzXCJcblxuaW1wb3J0IHtkZWNsYXJlZFN5bmNTY29wZUF0dHJpYnV0ZXN9IGZyb20gXCIuL3N5bmMtc2NvcGUtYXR0cmlidXRlcy5qc1wiXG5pbXBvcnQge2RlbGl2ZXJEZWNsYXJlZEJyb2FkY2FzdHMsIHVwc2VydFN5bmNSb3d9IGZyb20gXCIuL3N5bmMtY2hhbmdlLWZhbm91dC5qc1wiXG5pbXBvcnQge2lzUHVibGlzaGluZ1N1cHByZXNzZWR9IGZyb20gXCIuL3N5bmMtcHVibGlzaC1zdXBwcmVzc2lvbi5qc1wiXG5pbXBvcnQge1ZFTE9DSU9VU19TWU5DX0NIQU5ORUx9IGZyb20gXCIuL3N5bmMtY2hhbm5lbC1uYW1lLmpzXCJcblxuLyoqIEB0eXBlIHt7Y3JlYXRlOiBcImFmdGVyQ3JlYXRlXCIsIHVwZGF0ZTogXCJhZnRlclVwZGF0ZVwiLCBkZXN0cm95OiBcImFmdGVyRGVzdHJveVwifX0gKi9cbmNvbnN0IFBVQkxJU0hFRF9DQUxMQkFDS19OQU1FUyA9IHtjcmVhdGU6IFwiYWZ0ZXJDcmVhdGVcIiwgZGVzdHJveTogXCJhZnRlckRlc3Ryb3lcIiwgdXBkYXRlOiBcImFmdGVyVXBkYXRlXCJ9XG5cbi8qKlxuICogT3BlcmF0aW9ucyBwdWJsaXNoZWQgYnkgZGVmYXVsdCBmb3IgbW9kZWxzIGRlY2xhcmluZyBgc3RhdGljIHN5bmNgIHB1Ymxpc2hcbiAqIHdpdGhvdXQgYW4gYG9wZXJhdGlvbnNgIGtleTogc2VydmVyLXNpZGUgY3JlYXRlcyBhbmQgdXBkYXRlcyBwdWJsaXNoXG4gKiBhdXRvbWF0aWNhbGx5LiBEZXN0cm95cyBhcmUgbm90IHB1Ymxpc2hlZCBieSBkZWZhdWx0IGJlY2F1c2UgYSBzZXJ2ZXJcbiAqIGRlc3Ryb3kgaXMgb2Z0ZW4gY2xlYW51cCByYXRoZXIgdGhhbiBhIHN5bmNlZCBkZWxldGU7IG9wdCBpbiB3aXRoIGFuXG4gKiBvcGVyYXRpb25zIGxpc3QuXG4gKiBAdHlwZSB7QXJyYXk8XCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIj59ICovXG5jb25zdCBERUZBVUxUX1BVQkxJU0hFRF9PUEVSQVRJT05TID0gW1wiY3JlYXRlXCIsIFwidXBkYXRlXCJdXG5cbi8qKiBAdHlwZSB7V2Vha01hcDxDb25maWd1cmF0aW9uLCBTeW5jUHVibGlzaGVyPn0gKi9cbmNvbnN0IHN0YXJ0ZWRQdWJsaXNoZXJzQnlDb25maWd1cmF0aW9uID0gbmV3IFdlYWtNYXAoKVxuXG4vKipcbiAqIERlY2xhcmF0aXZlIHNlcnZlci1zaWRlIHN5bmMgcHVibGlzaGVyIOKAlCB0aGUgc2VydmVyIG1pcnJvciBvZiB0aGUgY2xpZW50J3NcbiAqIHRyYWNrLWJ5LWRlZmF1bHQgbXV0YXRpb24gdHJhY2tpbmcuXG4gKlxuICogU2VydmVyIG1vZGVscyBkZWNsYXJlIHdoYXQgdG8gcHVibGlzaCB0aHJvdWdoIGBzdGF0aWMgc3luY2AncyBgcHVibGlzaGBcbiAqIGtleSwgYW5kIFZlbG9jaW91cyB3cml0ZXMgZXZlcnkgY29tbWl0dGVkIHNlcnZlci1zaWRlIGNoYW5nZSB0byB0aGUgc3luY1xuICogY2hhbmdlIGZlZWQgKG1vZGVsLWJhY2tlZCBTeW5jLXJvdyB1cHNlcnQgd2l0aCBzZXJ2ZXIgcmUtc2VxdWVuY2luZykgYW5kXG4gKiBicm9hZGNhc3RzIHRoZSBzdGFuZGFyZCBzeW5jIGVudmVsb3BlIChge2VjaG9PcmlnaW4sIHN5bmNzOiBbLi4uXX1gKSBvbiB0aGVcbiAqIGZyYW1ld29yayBzeW5jIGNoYW5uZWwgKHtAbGluayBWRUxPQ0lPVVNfU1lOQ19DSEFOTkVMfSkgc2NvcGVkIGJ5IHRoZVxuICogY2hhbmdlJ3MgZGVyaXZlZCBzY29wZS1wYXJ0aXRpb24gdmFsdWVzLCBzbyBkZXZpY2VzIHJlY2VpdmUgc2VydmVyLW9yaWdpblxuICogY2hhbmdlcyB3aXRob3V0IGFwcCBjb2RlIGRlY2xhcmluZyBjaGFubmVscyBvciBjYWxsaW5nIG1hbnVhbFxuICogdXBzZXJ0L2Jyb2FkY2FzdCBoZWxwZXJzOlxuICpcbiAqICAgICBzdGF0aWMgc3luYyA9IHtwdWJsaXNoOiB0cnVlfSAvLyBkZWZhdWx0IHBheWxvYWQgKGF0dHJpYnV0ZXMpICsgZGVmYXVsdCBzY29wZSBwYXJ0aXRpb25cbiAqICAgICBzdGF0aWMgc3luYyA9IHtwdWJsaXNoOiB7c2VyaWFsaXplOiAocmVjb3JkKSA9PiAoe2lkOiByZWNvcmQuaWQoKSwgcGluOiByZWNvcmQucGluKCl9KX19XG4gKlxuICogVGhlIHNjb3BlIHBhcnRpdGlvbiBjb21lcyBmcm9tIHRoZSBzeW5jIG1vZGVsJ3MgYHN0YXRpY1xuICogc3luY1Njb3BlQXR0cmlidXRlc2AgZGVjbGFyYXRpb24gKGZvciBleGFtcGxlIGBbXCJldmVudElkXCJdYCBvclxuICogYFtcImFjY291bnRJZFwiXWAg4oCUIFZlbG9jaW91cyBoYXMgbm8gYnVpbHQtaW4gcGFydGl0aW9uIG5hbWUpOiBlYWNoIGRlY2xhcmVkXG4gKiBzY29wZSBhdHRyaWJ1dGUgcmVhZHMgdGhlIHJlY29yZCdzIGF0dHJpYnV0ZSBvZiB0aGUgc2FtZSBuYW1lIHdoZW4gdGhlXG4gKiBtb2RlbCBoYXMgb25lLCBlbHNlIHRoZSByZWNvcmQncyBvd24gaWQgKHNjb3BlLXJvb3QgbW9kZWxzKSwgb3ZlcnJpZGFibGVcbiAqIHBlciBtb2RlbCB0aHJvdWdoIGBwdWJsaXNoOiB7c2NvcGVBdHRyaWJ1dGVzOiB7YWNjb3VudElkOiBcIm93bmVySWRcIn19YC5cbiAqIFRoZSBwcmUtZnJhbWV3b3JrLWNoYW5uZWwgYGJyb2FkY2FzdHNgIGxpc3QgYW5kIHRoZSBgZXZlbnRJZGBcbiAqIHN0cmluZy9yZXNvbHZlci1mdW5jdGlvbiBkZWNsYXJhdGlvbiBmb3JtcyBrZWVwIHdvcmtpbmcgYnV0IGFyZSBkZXByZWNhdGVkLlxuICpcbiAqIFJlcGxheWVkIGRldmljZSBtdXRhdGlvbnMgbmV2ZXIgZG91YmxlLXB1Ymxpc2g6IHRoZSBmcmFtZXdvcmsncyByb3V0ZWRcbiAqIHJlcGxheSBhcHBseSBtYXJrcyBpdHMgd3JpdHRlbiByZWNvcmRzIHRocm91Z2ggYG1hcmtTZXJ2ZXJBcHBseShyZWNvcmQpYFxuICogKHNlZSBzeW5jLXB1Ymxpc2gtc3VwcHJlc3Npb24uanMpLCBhbmQgYXBwIGNvZGUgYXBwbHlpbmcgYWxyZWFkeS1zeW5jZWRcbiAqIGRhdGEgY2FuIHVzZSBgbWFya1NlcnZlckFwcGx5YC9gd2l0aG91dFB1Ymxpc2hpbmdgIHRoZSBzYW1lIHdheS5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3luY1B1Ymxpc2hlciB7XG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIHN5bmMgcHVibGlzaGVyIGJ5IGRlcml2aW5nIHB1Ymxpc2hlZCByZXNvdXJjZXMgZnJvbSB0aGVcbiAgICogY29uZmlndXJhdGlvbidzIHJlZ2lzdGVyZWQgbW9kZWxzOiBldmVyeSBtb2RlbCBkZWNsYXJpbmcgYHN0YXRpYyBzeW5jYFxuICAgKiB3aXRoIGEgYHB1Ymxpc2hgIGRlY2xhcmF0aW9uIGJlY29tZXMgYSBwdWJsaXNoZWQgcmVzb3VyY2VcbiAgICogKGBwdWJsaXNoOiBmYWxzZWAgb3B0cyBvdXQpLiBUaGUgc3luYy9jaGFuZ2UgbW9kZWwgaXMgdGhlIHJlZ2lzdGVyZWRcbiAgICogXCJTeW5jXCIgbW9kZWwgYW5kIGJyb2FkY2FzdHMgZGVmYXVsdCB0byB0aGUgY29uZmlndXJhdGlvbidzIGNoYW5uZWxcbiAgICogYnJvYWRjYXN0LlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlck9wdGlvbnN9IFtvcHRpb25zXSAtIE9wdGlvbmFsIG92ZXJyaWRlcy5cbiAgICovXG4gIGNvbnN0cnVjdG9yKG9wdGlvbnMgPSB7fSkge1xuICAgIGNvbnN0IHthY3RvckZvcmVpZ25LZXlDb2x1bW4gPSBcImF1dGhlbnRpY2F0aW9uX3Rva2VuX2lkXCIsIGJyb2FkY2FzdGVyLCBjb25maWd1cmF0aW9uID0gQ29uZmlndXJhdGlvbi5jdXJyZW50KCksIG9uRXJyb3IsIHN5bmNNb2RlbCwgLi4ucmVzdE9wdGlvbnN9ID0gb3B0aW9uc1xuXG4gICAgcmVzdEFyZ3NFcnJvcihyZXN0T3B0aW9ucylcblxuICAgIGNvbnN0IG1vZGVsQ2xhc3NlcyA9IGNvbmZpZ3VyYXRpb24uZ2V0TW9kZWxDbGFzc2VzKClcbiAgICBjb25zdCBwdWJsaXNoaW5nTW9kZWxDbGFzc2VzID0gT2JqZWN0LnZhbHVlcyhtb2RlbENsYXNzZXMpLmZpbHRlcigobW9kZWxDbGFzcykgPT4gcHVibGlzaERlY2xhcmF0aW9uRm9yKG1vZGVsQ2xhc3MpKVxuXG4gICAgaWYgKHB1Ymxpc2hpbmdNb2RlbENsYXNzZXMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jUHVibGlzaGVyIGZvdW5kIG5vIHJlZ2lzdGVyZWQgbW9kZWxzIGRlY2xhcmluZyBzdGF0aWMgc3luYyBwdWJsaXNoIC0gZGVjbGFyZSBgc3RhdGljIHN5bmMgPSB7cHVibGlzaDoge3NlcmlhbGl6ZX19YCBvbiB0aGUgbW9kZWxzIHdob3NlIHNlcnZlci1zaWRlIGNoYW5nZXMgc2hvdWxkIHB1Ymxpc2ggdG8gdGhlIHN5bmMgZmVlZFwiKVxuICAgIH1cblxuICAgIGNvbnN0IHJlc29sdmVkU3luY01vZGVsID0gc3luY01vZGVsIHx8IG1vZGVsQ2xhc3Nlcy5TeW5jXG5cbiAgICBpZiAoIXJlc29sdmVkU3luY01vZGVsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jUHVibGlzaGVyIHJlcXVpcmVzIGEgcmVnaXN0ZXJlZCBcXFwiU3luY1xcXCIgbW9kZWwgZm9yIHB1Ymxpc2hlZCBzeW5jIGNoYW5nZSByb3dzIChvciBwYXNzIG9wdGlvbnMuc3luY01vZGVsKVwiKVxuICAgIH1cblxuICAgIGNvbnN0IHNjb3BlQXR0cmlidXRlcyA9IGRlY2xhcmVkU3luY1Njb3BlQXR0cmlidXRlcyhyZXNvbHZlZFN5bmNNb2RlbClcbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlclJlc291cmNlQ29uZmlnPn0gKi9cbiAgICBjb25zdCByZXNvdXJjZXMgPSB7fVxuXG4gICAgZm9yIChjb25zdCBtb2RlbENsYXNzIG9mIHB1Ymxpc2hpbmdNb2RlbENsYXNzZXMpIHtcbiAgICAgIGNvbnN0IHB1Ymxpc2ggPSBwdWJsaXNoRGVjbGFyYXRpb25Gb3IobW9kZWxDbGFzcylcbiAgICAgIGNvbnN0IHJlc291cmNlQ29uZmlnID0gcmVzb3VyY2VDb25maWdGcm9tUHVibGlzaERlY2xhcmF0aW9uKHttb2RlbENsYXNzLCBwdWJsaXNoLCBzY29wZUF0dHJpYnV0ZXMsIHN5bmNNb2RlbDogcmVzb2x2ZWRTeW5jTW9kZWx9KVxuXG4gICAgICByZXNvdXJjZXNbcmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlXSA9IHJlc291cmNlQ29uZmlnXG4gICAgfVxuXG4gICAgLyoqIEB0eXBlIHt7YWN0b3JGb3JlaWduS2V5Q29sdW1uOiBzdHJpbmcsIGJyb2FkY2FzdGVyOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJPcHRpb25zW1wiYnJvYWRjYXN0ZXJcIl0sIGNvbmZpZ3VyYXRpb246IENvbmZpZ3VyYXRpb24sIG9uRXJyb3I6IGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlck9wdGlvbnNbXCJvbkVycm9yXCJdLCByZXNvdXJjZXM6IFJlY29yZDxzdHJpbmcsIGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlclJlc291cmNlQ29uZmlnPiwgc3luY01vZGVsOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn19ICovXG4gICAgdGhpcy5jb25maWcgPSB7YWN0b3JGb3JlaWduS2V5Q29sdW1uLCBicm9hZGNhc3RlciwgY29uZmlndXJhdGlvbiwgb25FcnJvciwgcmVzb3VyY2VzLCBzeW5jTW9kZWw6IHJlc29sdmVkU3luY01vZGVsfVxuICAgIC8qKiBAdHlwZSB7QXJyYXk8e2NhbGxiYWNrOiAocmVjb3JkOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPikgPT4gUHJvbWlzZTx2b2lkPiwgY2FsbGJhY2tOYW1lOiBcImFmdGVyQ3JlYXRlXCIgfCBcImFmdGVyVXBkYXRlXCIgfCBcImFmdGVyRGVzdHJveVwiLCBtb2RlbENsYXNzOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0+fSAqL1xuICAgIHRoaXMuX3B1Ymxpc2hlZENhbGxiYWNrcyA9IFtdXG4gICAgLyoqIEB0eXBlIHtMb2dnZXIgfCBudWxsfSAqL1xuICAgIHRoaXMuX2xvZ2dlciA9IG51bGxcbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgYSBzeW5jIHB1Ymxpc2hlciBkZXJpdmVkIGZyb20gdGhlIGdpdmVuIGNvbmZpZ3VyYXRpb24uIEFsaWFzIGZvclxuICAgKiBgbmV3IFN5bmNQdWJsaXNoZXIoe2NvbmZpZ3VyYXRpb24sIC4uLm9wdGlvbnN9KWAuXG4gICAqIEBwYXJhbSB7Q29uZmlndXJhdGlvbn0gW2NvbmZpZ3VyYXRpb25dIC0gQ29uZmlndXJhdGlvbiBvd25pbmcgdGhlIHJlZ2lzdGVyZWQgbW9kZWxzLiBEZWZhdWx0cyB0byB0aGUgY3VycmVudCBjb25maWd1cmF0aW9uLlxuICAgKiBAcGFyYW0ge09taXQ8aW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyT3B0aW9ucywgXCJjb25maWd1cmF0aW9uXCI+fSBbb3B0aW9uc10gLSBPcHRpb25hbCBvdmVycmlkZXMuXG4gICAqIEByZXR1cm5zIHtTeW5jUHVibGlzaGVyfSBTeW5jIHB1Ymxpc2hlciBkZXJpdmVkIGZyb20gdGhlIGNvbmZpZ3VyYXRpb24uXG4gICAqL1xuICBzdGF0aWMgZnJvbUNvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbiA9IENvbmZpZ3VyYXRpb24uY3VycmVudCgpLCBvcHRpb25zID0ge30pIHtcbiAgICByZXR1cm4gbmV3IFN5bmNQdWJsaXNoZXIoey4uLm9wdGlvbnMsIGNvbmZpZ3VyYXRpb259KVxuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0cyAoYW5kIG1lbW9pemVzIHBlciBjb25maWd1cmF0aW9uKSB0aGUgc3luYyBwdWJsaXNoZXIgZm9yIGEgc2VydmVyXG4gICAqIGJvb3Q6IG5vLW9wIHdoZW4gbm8gcmVnaXN0ZXJlZCBtb2RlbCBkZWNsYXJlcyBhIHB1Ymxpc2ggY29uZmlnLCBndWFyZGVkIHNvXG4gICAqIHJlcGVhdGVkIGJvb3RzIHdpdGggdGhlIHNhbWUgY29uZmlndXJhdGlvbiByZWdpc3RlciB0aGUgcHVibGlzaCBjYWxsYmFja3NcbiAgICogb25seSBvbmNlLlxuICAgKiBAcGFyYW0ge0NvbmZpZ3VyYXRpb259IGNvbmZpZ3VyYXRpb24gLSBDb25maWd1cmF0aW9uIG93bmluZyB0aGUgcmVnaXN0ZXJlZCBtb2RlbHMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFN5bmNQdWJsaXNoZXIgfCBudWxsPn0gU3RhcnRlZCBwdWJsaXNoZXIsIG9yIG51bGwgd2hlbiBubyBtb2RlbHMgZGVjbGFyZSBwdWJsaXNoLlxuICAgKi9cbiAgc3RhdGljIGFzeW5jIHN0YXJ0RnJvbUNvbmZpZ3VyYXRpb24oY29uZmlndXJhdGlvbikge1xuICAgIGNvbnN0IHN0YXJ0ZWRQdWJsaXNoZXIgPSBzdGFydGVkUHVibGlzaGVyc0J5Q29uZmlndXJhdGlvbi5nZXQoY29uZmlndXJhdGlvbilcblxuICAgIGlmIChzdGFydGVkUHVibGlzaGVyKSByZXR1cm4gc3RhcnRlZFB1Ymxpc2hlclxuXG4gICAgaWYgKCFPYmplY3QudmFsdWVzKGNvbmZpZ3VyYXRpb24uZ2V0TW9kZWxDbGFzc2VzKCkpLnNvbWUoKG1vZGVsQ2xhc3MpID0+IHB1Ymxpc2hEZWNsYXJhdGlvbkZvcihtb2RlbENsYXNzKSkpIHJldHVybiBudWxsXG5cbiAgICBjb25zdCBwdWJsaXNoZXIgPSBuZXcgU3luY1B1Ymxpc2hlcih7Y29uZmlndXJhdGlvbn0pXG5cbiAgICBzdGFydGVkUHVibGlzaGVyc0J5Q29uZmlndXJhdGlvbi5zZXQoY29uZmlndXJhdGlvbiwgcHVibGlzaGVyKVxuICAgIGF3YWl0IHB1Ymxpc2hlci5zdGFydCgpXG5cbiAgICByZXR1cm4gcHVibGlzaGVyXG4gIH1cblxuICAvKipcbiAgICogUmVnaXN0ZXJzIHRoZSBwdWJsaXNoIGNhbGxiYWNrcyBmb3IgZXZlcnkgcHVibGlzaGVkIHJlc291cmNlOiBzZXJ2ZXItc2lkZVxuICAgKiBjcmVhdGVzIGFuZCB1cGRhdGVzIChkZXN0cm95cyB3aGVuIG9wdGVkIGluKSB1cHNlcnQgYSBzeW5jIGNoYW5nZSByb3cgYW5kXG4gICAqIGZhbiBvdXQgdGhlIGRlY2xhcmVkIGJyb2FkY2FzdHMgb25jZSB0aGVpciB0cmFuc2FjdGlvbiBjb21taXRzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIHN0YXJ0KCkge1xuICAgIGlmICh0aGlzLl9zdGFydGVkKSByZXR1cm5cblxuICAgIHRoaXMuX3N0YXJ0ZWQgPSB0cnVlXG5cbiAgICBmb3IgKGNvbnN0IHJlc291cmNlQ29uZmlnIG9mIE9iamVjdC52YWx1ZXModGhpcy5jb25maWcucmVzb3VyY2VzKSkge1xuICAgICAgZm9yIChjb25zdCBvcGVyYXRpb24gb2YgcmVzb3VyY2VDb25maWcub3BlcmF0aW9ucykge1xuICAgICAgICBjb25zdCBjYWxsYmFja05hbWUgPSBQVUJMSVNIRURfQ0FMTEJBQ0tfTkFNRVNbb3BlcmF0aW9uXVxuICAgICAgICBjb25zdCBjYWxsYmFjayA9IHRoaXMucHVibGlzaGVkTXV0YXRpb25DYWxsYmFjayh7b3BlcmF0aW9uLCByZXNvdXJjZUNvbmZpZ30pXG5cbiAgICAgICAgcmVzb3VyY2VDb25maWcubW9kZWxDbGFzc1tjYWxsYmFja05hbWVdKGNhbGxiYWNrKVxuICAgICAgICB0aGlzLl9wdWJsaXNoZWRDYWxsYmFja3MucHVzaCh7Y2FsbGJhY2ssIGNhbGxiYWNrTmFtZSwgbW9kZWxDbGFzczogcmVzb3VyY2VDb25maWcubW9kZWxDbGFzc30pXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFVucmVnaXN0ZXJzIGFsbCBwdWJsaXNoIGNhbGxiYWNrcyAodGVzdHMsIHNodXRkb3duKS5cbiAgICogQHJldHVybnMge3ZvaWR9XG4gICAqL1xuICBzdG9wKCkge1xuICAgIGZvciAoY29uc3Qge2NhbGxiYWNrLCBjYWxsYmFja05hbWUsIG1vZGVsQ2xhc3N9IG9mIHRoaXMuX3B1Ymxpc2hlZENhbGxiYWNrcykge1xuICAgICAgbW9kZWxDbGFzcy51bnJlZ2lzdGVyTGlmZWN5Y2xlQ2FsbGJhY2soY2FsbGJhY2tOYW1lLCBjYWxsYmFjaylcbiAgICB9XG5cbiAgICB0aGlzLl9wdWJsaXNoZWRDYWxsYmFja3MgPSBbXVxuICAgIHRoaXMuX3N0YXJ0ZWQgPSBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgbGlmZWN5Y2xlIGNhbGxiYWNrIHB1Ymxpc2hpbmcgb25lIHNlcnZlci1zaWRlIG11dGF0aW9uLiBUaGVcbiAgICogcHVibGlzaGVkIHBheWxvYWQgKGRlY2xhcmF0aW9uIGBzZXJpYWxpemVgKSwgZXZlbnQgc2NvcGUsIGFuZCBzeW5jIHR5cGVcbiAgICogYXJlIHNuYXBzaG90dGVkIGF0IG11dGF0aW9uLWNhbGxiYWNrIHRpbWUsIHNvIGFmdGVyU2F2ZSBob29rcyBhc3NpZ25pbmdcbiAgICogdW5zYXZlZCBhdHRyaWJ1dGVzIChvciBhbnkgbGF0ZXIgZHJpZnQgb24gdGhlIHJlY29yZCkgY2Fubm90IGNoYW5nZSB3aGF0XG4gICAqIGdldHMgcHVibGlzaGVkIHZzIHdoYXQgd2FzIGNvbW1pdHRlZC4gUGVyc2lzdGluZyBhbmQgYnJvYWRjYXN0aW5nIGFyZVxuICAgKiBkZWZlcnJlZCB0aHJvdWdoIHRoZSBtb2RlbCBjb25uZWN0aW9uJ3MgYWZ0ZXJDb21taXQgaG9vayBzbyB0aGV5IG9ubHkgcnVuXG4gICAqIG9uY2UgdGhlIG11dGF0aW9uJ3MgdHJhbnNhY3Rpb24gaGFzIGNvbW1pdHRlZCAoaW1tZWRpYXRlbHkgd2hlbiBub1xuICAgKiB0cmFuc2FjdGlvbiBpcyBvcGVuKSAtIHJvbGxlZC1iYWNrIG11dGF0aW9ucyBuZXZlciBwdWJsaXNoLiBQb3N0LWNvbW1pdFxuICAgKiBwdWJsaXNoIGZhaWx1cmVzIGFyZSByZXBvcnRlZCB3aXRob3V0IHJldGhyb3dpbmcgaW50byB0aGUgZHJpdmVyJ3NcbiAgICogYWZ0ZXJDb21taXQgY2hhaW4gKHNlZSByZXBvcnRBZnRlckNvbW1pdEVycm9yKS5cbiAgICogQHBhcmFtIHt7b3BlcmF0aW9uOiBcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiLCByZXNvdXJjZUNvbmZpZzogaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyUmVzb3VyY2VDb25maWd9fSBhcmdzIC0gT3BlcmF0aW9uIGFuZCByZXNvdXJjZSBjb25maWcuXG4gICAqIEByZXR1cm5zIHsocmVjb3JkOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPikgPT4gUHJvbWlzZTx2b2lkPn0gTGlmZWN5Y2xlIGNhbGxiYWNrLlxuICAgKi9cbiAgcHVibGlzaGVkTXV0YXRpb25DYWxsYmFjayh7b3BlcmF0aW9uLCByZXNvdXJjZUNvbmZpZ30pIHtcbiAgICByZXR1cm4gYXN5bmMgKHJlY29yZCkgPT4ge1xuICAgICAgaWYgKGlzUHVibGlzaGluZ1N1cHByZXNzZWQocmVjb3JkKSkgcmV0dXJuXG5cbiAgICAgIGNvbnN0IGRhdGEgPSBhd2FpdCByZXNvdXJjZUNvbmZpZy5zZXJpYWxpemUocmVjb3JkKVxuICAgICAgY29uc3QgcmVzb3VyY2VJZCA9IFN0cmluZyhzY2FsYXJNb2RlbFByaW1hcnlLZXlWYWx1ZShyZWNvcmQuaWQoKSwgYFN5bmMgcHVibGlzaGluZyBmb3IgJHtyZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGV9YCkpXG4gICAgICBjb25zdCBzeW5jVHlwZSA9IG9wZXJhdGlvbiA9PT0gXCJkZXN0cm95XCIgPyBcImRlbGV0ZVwiIDogXCJ1cGRhdGVcIlxuICAgICAgY29uc3Qgc2NvcGVWYWx1ZXMgPSBhd2FpdCB0aGlzLnB1Ymxpc2hlZFNjb3BlVmFsdWVzKHtyZWNvcmQsIHJlc291cmNlQ29uZmlnfSlcbiAgICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSAqL1xuICAgICAgY29uc3QgYXR0cmlidXRlcyA9IHtcbiAgICAgICAgW3RoaXMuY29uZmlnLmFjdG9yRm9yZWlnbktleUNvbHVtbl06IG51bGwsXG4gICAgICAgIGNsaWVudF91cGRhdGVkX2F0OiBuZXcgRGF0ZSgpLFxuICAgICAgICBkYXRhOiBKU09OLnN0cmluZ2lmeShkYXRhKSxcbiAgICAgICAgcmVzb3VyY2VfaWQ6IHJlc291cmNlSWQsXG4gICAgICAgIHJlc291cmNlX3R5cGU6IHJlc291cmNlQ29uZmlnLnJlc291cmNlVHlwZSxcbiAgICAgICAgc3luY190eXBlOiBzeW5jVHlwZSxcbiAgICAgICAgLi4uc2NvcGVWYWx1ZXMuY29sdW1uc1xuICAgICAgfVxuICAgICAgY29uc3QgZGF0YWJhc2VPcGVyYXRpb24gPSByZWNvcmQuZGF0YWJhc2VPcGVyYXRpb24oKVxuICAgICAgY29uc3Qgb3BlcmF0aW9uU2NvcGUgPSBkYXRhYmFzZU9wZXJhdGlvblxuICAgICAgICA/IGRhdGFiYXNlT3BlcmF0aW9uLmZvck1vZGVsKHRoaXMuY29uZmlnLnN5bmNNb2RlbClcbiAgICAgICAgOiB0aGlzLmNvbmZpZy5zeW5jTW9kZWxcblxuICAgICAgYXdhaXQgcmVjb3JkLmNvbm5lY3Rpb24oKS5hZnRlckNvbW1pdChhc3luYyAoKSA9PiB7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgY29uc3Qgc3luY1JvdyA9IGF3YWl0IHRoaXMudXBzZXJ0UHVibGlzaGVkU3luY1JvdyhhdHRyaWJ1dGVzLCBvcGVyYXRpb25TY29wZSlcblxuICAgICAgICAgIGF3YWl0IHRoaXMuYnJvYWRjYXN0ZXIoKSh7XG4gICAgICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICAgIGVjaG9PcmlnaW46IG51bGwsXG4gICAgICAgICAgICAgIHN5bmNzOiBbdGhpcy5wdWJsaXNoZWRTeW5jRW50cnkoe2RhdGEsIHJlc291cmNlQ29uZmlnLCByZXNvdXJjZUlkLCBzeW5jUm93LCBzeW5jVHlwZX0pXVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNoYW5uZWw6IFZFTE9DSU9VU19TWU5DX0NIQU5ORUwsXG4gICAgICAgICAgICBwYXJhbXM6IHsuLi5zY29wZVZhbHVlcy5wYXJhbXMsIHJlc291cmNlVHlwZTogcmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlfVxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBpZiAocmVzb3VyY2VDb25maWcuYnJvYWRjYXN0cykge1xuICAgICAgICAgICAgYXdhaXQgZGVsaXZlckRlY2xhcmVkQnJvYWRjYXN0cyh7XG4gICAgICAgICAgICAgIGFyZ3M6IHtkYXRhLCBvcGVyYXRpb24sIHJlY29yZCwgcmVzb3VyY2VJZCwgcmVzb3VyY2VUeXBlOiByZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGUsIHN5bmNSb3csIHN5bmNUeXBlfSxcbiAgICAgICAgICAgICAgYnJvYWRjYXN0ZXI6IHRoaXMuYnJvYWRjYXN0ZXIoKSxcbiAgICAgICAgICAgICAgYnJvYWRjYXN0czogcmVzb3VyY2VDb25maWcuYnJvYWRjYXN0c1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5yZXBvcnRBZnRlckNvbW1pdEVycm9yKC8qKiBAdHlwZSB7RXJyb3J9ICovIChlcnJvcikpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSBzY29wZS1wYXJ0aXRpb24gdmFsdWVzIGZvciBvbmUgcHVibGlzaGVkIG11dGF0aW9uIGZyb20gdGhlXG4gICAqIHJlc291cmNlJ3MgZGVyaXZlZCBzY29wZSBwbGFuOiBlYWNoIGVudHJ5IHJlYWRzIGl0cyByZWNvcmQgYXR0cmlidXRlIChvclxuICAgKiB0aGUgcmVjb3JkJ3Mgb3duIGlkIGZvciBzY29wZS1yb290IG1vZGVscywgb3IgdGhlIGRlcHJlY2F0ZWQgcmVzb2x2ZXJcbiAgICogZnVuY3Rpb24pLiBUaGUgdmFsdWVzIGFyZSBwZXJzaXN0ZWQgb250byB0aGUgc3luYyByb3cncyBwYXJ0aXRpb24gY29sdW1uc1xuICAgKiBhbmQgYnJvYWRjYXN0IGFzIHRoZSBmcmFtZXdvcmsgc3luYyBjaGFubmVsJ3Mgc2NvcGluZyBwYXJhbXMuXG4gICAqIEBwYXJhbSB7e3JlY29yZDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4sIHJlc291cmNlQ29uZmlnOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJSZXNvdXJjZUNvbmZpZ319IGFyZ3MgLSBNdXRhdGVkIHJlY29yZCBhbmQgcmVzb3VyY2UgY29uZmlnLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7Y29sdW1uczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVsbD4sIHBhcmFtczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVsbD59Pn0gU2NvcGUgdmFsdWVzIGtleWVkIGJ5IHN5bmMtcm93IGNvbHVtbiBhbmQgYnkgc2NvcGUgYXR0cmlidXRlLlxuICAgKi9cbiAgYXN5bmMgcHVibGlzaGVkU2NvcGVWYWx1ZXMoe3JlY29yZCwgcmVzb3VyY2VDb25maWd9KSB7XG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudWxsPn0gKi9cbiAgICBjb25zdCBjb2x1bW5zID0ge31cbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bGw+fSAqL1xuICAgIGNvbnN0IHBhcmFtcyA9IHt9XG5cbiAgICBmb3IgKGNvbnN0IHNjb3BlUGxhbkVudHJ5IG9mIHJlc291cmNlQ29uZmlnLnNjb3BlUGxhbikge1xuICAgICAgLyoqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gKi9cbiAgICAgIGxldCByYXdWYWx1ZVxuXG4gICAgICBpZiAoc2NvcGVQbGFuRW50cnkucmVzb2x2ZXIpIHtcbiAgICAgICAgcmF3VmFsdWUgPSBhd2FpdCBzY29wZVBsYW5FbnRyeS5yZXNvbHZlcihyZWNvcmQpXG4gICAgICB9IGVsc2UgaWYgKHNjb3BlUGxhbkVudHJ5LnJlY29yZEF0dHJpYnV0ZSkge1xuICAgICAgICByYXdWYWx1ZSA9IHJlY29yZC5yZWFkQXR0cmlidXRlKHNjb3BlUGxhbkVudHJ5LnJlY29yZEF0dHJpYnV0ZSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJhd1ZhbHVlID0gc2NhbGFyTW9kZWxQcmltYXJ5S2V5VmFsdWUocmVjb3JkLmlkKCksIGBTeW5jIHNjb3BlIHB1Ymxpc2hpbmcgZm9yICR7cmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlfWApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gcmF3VmFsdWUgPT09IHVuZGVmaW5lZCB8fCByYXdWYWx1ZSA9PT0gbnVsbCA/IG51bGwgOiBTdHJpbmcocmF3VmFsdWUpXG5cbiAgICAgIGNvbHVtbnNbc2NvcGVQbGFuRW50cnkuY29sdW1uTmFtZV0gPSB2YWx1ZVxuICAgICAgcGFyYW1zW3Njb3BlUGxhbkVudHJ5LnNjb3BlQXR0cmlidXRlXSA9IHZhbHVlXG4gICAgfVxuXG4gICAgcmV0dXJuIHtjb2x1bW5zLCBwYXJhbXN9XG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIHRoZSBmcmFtZXdvcmsgc3luYyBjaGFubmVsIGVudHJ5IGZvciBvbmUgcHVibGlzaGVkIGNoYW5nZTogdGhlXG4gICAqIHNuYXBzaG90dGVkIHBheWxvYWQgcGx1cyB0aGUgcGVyc2lzdGVkIHN5bmMgcm93J3MgcHVibGljIGV4YWN0LXJvdyBtZXRhZGF0YVxuICAgKiAoaWQsIHNlcnZlciBzZXF1ZW5jZSwgdXBkYXRlZC1hdCwgYW5kIGRlY2xhcmVkIHNjb3BlLXBhcnRpdGlvbiBhdHRyaWJ1dGVzKS5cbiAgICogVXNlcyB0aGUgc3luYyBtb2RlbCdzIGdlbmVyYXRlZCB0eXBlZCBhY2Nlc3NvcnMgYW5kIGZvbGxvd3MgdGhlXG4gICAqIGNoYW5nZS1mZWVkIHNlcmlhbGl6ZXIncyBwdWJsaWMgZmllbGQgY29udmVudGlvbi5cbiAgICogQHBhcmFtIHt7ZGF0YTogUmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+LCByZXNvdXJjZUNvbmZpZzogaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyUmVzb3VyY2VDb25maWcsIHJlc291cmNlSWQ6IHN0cmluZywgc3luY1JvdzogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4sIHN5bmNUeXBlOiBzdHJpbmd9fSBhcmdzIC0gUHVibGlzaCBhcmdzLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSBCcm9hZGNhc3Qgc3luYyBlbnRyeS5cbiAgICovXG4gIHB1Ymxpc2hlZFN5bmNFbnRyeSh7ZGF0YSwgcmVzb3VyY2VDb25maWcsIHJlc291cmNlSWQsIHN5bmNSb3csIHN5bmNUeXBlfSkge1xuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSAqL1xuICAgIGNvbnN0IGVudHJ5ID0ge1xuICAgICAgZGF0YSxcbiAgICAgIGlkOiBzeW5jUm93LmlkKCksXG4gICAgICByZXNvdXJjZUlkLFxuICAgICAgcmVzb3VyY2VUeXBlOiByZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGUsXG4gICAgICBzZXJ2ZXJTZXF1ZW5jZTogc3luY1Jvdy5zZXJ2ZXJTZXF1ZW5jZSgpLFxuICAgICAgc3luY1R5cGUsXG4gICAgICB1cGRhdGVkQXQ6IGlzb0RhdGUoc3luY1Jvdy51cGRhdGVkQXQoKSlcbiAgICB9XG5cbiAgICBjb25zdCBzY29wZUF0dHJpYnV0ZXMgPSBkZWNsYXJlZFN5bmNTY29wZUF0dHJpYnV0ZXModGhpcy5jb25maWcuc3luY01vZGVsKVxuXG4gICAgZm9yIChjb25zdCBzY29wZUF0dHJpYnV0ZSBvZiBzY29wZUF0dHJpYnV0ZXMgfHwgW10pIHtcbiAgICAgIGNvbnN0IHNjb3BlQWNjZXNzb3IgPSBzeW5jUm93W3Njb3BlQXR0cmlidXRlXVxuXG4gICAgICBpZiAodHlwZW9mIHNjb3BlQWNjZXNzb3IgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFB1Ymxpc2hlZCBzeW5jIHJvdyBpcyBtaXNzaW5nIHRoZSBkZWNsYXJlZCBzY29wZSBhY2Nlc3NvciAke3Njb3BlQXR0cmlidXRlfSgpLmApXG4gICAgICB9XG5cbiAgICAgIGVudHJ5W3Njb3BlQXR0cmlidXRlXSA9IHNjb3BlQWNjZXNzb3IuY2FsbChzeW5jUm93KVxuICAgIH1cblxuICAgIHJldHVybiBlbnRyeVxuICB9XG5cbiAgLyoqXG4gICAqIFVwc2VydHMgdGhlIHB1Ymxpc2hlZCBzZXJ2ZXItb3JpZ2luIHN5bmMgcm93IGZvciBhIHJlc291cmNlIGlkZW50aXR5OlxuICAgKiBzZXJ2ZXItb3JpZ2luIHJvd3MgY2FycnkgYSBudWxsIGFjdG9yIGNvbHVtbiAobm8gZGV2aWNlIHRvIGVjaG8gdGhlXG4gICAqIGNoYW5nZSBiYWNrIHRvKSwgc28gcmVwZWF0ZWQgc2VydmVyIGNoYW5nZXMgdG8gb25lIHJlc291cmNlIHJldXNlIGFuZFxuICAgKiByZS1zZXF1ZW5jZSBvbmUgZmVlZCByb3cuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSBhdHRyaWJ1dGVzIC0gU25hcHNob3R0ZWQgc3luYyByb3cgYXR0cmlidXRlcy5cbiAgICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gc3luY01vZGVsIC0gT3BlcmF0aW9uLWJvdW5kIG9yIHN0YXRpYyBTeW5jIG1vZGVsIGludGVyZmFjZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSBVcHNlcnRlZCBzeW5jIHJvdy5cbiAgICovXG4gIGFzeW5jIHVwc2VydFB1Ymxpc2hlZFN5bmNSb3coYXR0cmlidXRlcywgc3luY01vZGVsID0gdGhpcy5jb25maWcuc3luY01vZGVsKSB7XG4gICAgY29uc3QgZXhpc3RpbmdTeW5jID0gYXdhaXQgc3luY01vZGVsXG4gICAgICAud2hlcmUoe1xuICAgICAgICBbdGhpcy5jb25maWcuYWN0b3JGb3JlaWduS2V5Q29sdW1uXTogbnVsbCxcbiAgICAgICAgcmVzb3VyY2VfaWQ6IGF0dHJpYnV0ZXMucmVzb3VyY2VfaWQsXG4gICAgICAgIHJlc291cmNlX3R5cGU6IGF0dHJpYnV0ZXMucmVzb3VyY2VfdHlwZVxuICAgICAgfSlcbiAgICAgIC5maXJzdCgpXG5cbiAgICByZXR1cm4gYXdhaXQgdXBzZXJ0U3luY1Jvdyh7YXR0cmlidXRlcywgZXhpc3RpbmdTeW5jLCBzeW5jTW9kZWx9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGJyb2FkY2FzdGVyIGRlbGl2ZXJpbmcgZGVjbGFyZWQgYnJvYWRjYXN0czogdGhlIGluamVjdGVkIG9uZSxcbiAgICogb3IgdGhlIGNvbmZpZ3VyYXRpb24ncyBjaGFubmVsIGJyb2FkY2FzdCBhd2FpdGVkIHRocm91Z2ggdGhlIHBlbmRpbmdcbiAgICogYnJvYWRjYXN0IHF1ZXVlLlxuICAgKiBAcmV0dXJucyB7Tm9uTnVsbGFibGU8aW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyT3B0aW9uc1tcImJyb2FkY2FzdGVyXCJdPn0gQnJvYWRjYXN0IGRlbGl2ZXJlci5cbiAgICovXG4gIGJyb2FkY2FzdGVyKCkge1xuICAgIGlmICh0aGlzLmNvbmZpZy5icm9hZGNhc3RlcikgcmV0dXJuIHRoaXMuY29uZmlnLmJyb2FkY2FzdGVyXG5cbiAgICByZXR1cm4gYXN5bmMgKHtib2R5LCBjaGFubmVsLCBwYXJhbXN9KSA9PiB7XG4gICAgICB0aGlzLmNvbmZpZy5jb25maWd1cmF0aW9uLmJyb2FkY2FzdFRvQ2hhbm5lbChjaGFubmVsLCBwYXJhbXMsIGJvZHkpXG4gICAgICBhd2FpdCB0aGlzLmNvbmZpZy5jb25maWd1cmF0aW9uLmF3YWl0UGVuZGluZ0Jyb2FkY2FzdHMoKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBvcnRzIGEgcG9zdC1jb21taXQgcHVibGlzaCBmYWlsdXJlLiBUaGUgdHJhbnNhY3Rpb24gaGFzIGFscmVhZHlcbiAgICogY29tbWl0dGVkIHdoZW4gYWZ0ZXJDb21taXQgY2FsbGJhY2tzIHJ1biwgc28gcmV0aHJvd2luZyBoZXJlIHdvdWxkIHBvaXNvblxuICAgKiB0aGUgZHJpdmVyJ3MgYXdhaXRlZCBhZnRlckNvbW1pdCBjaGFpbiAoYnJlYWtpbmcgdW5yZWxhdGVkIGNhbGxiYWNrcykgLVxuICAgKiBpbnN0ZWFkIHRoZSBmYWlsdXJlIGdvZXMgdG8gdGhlIGNvbmZpZ3VyZWQgb25FcnJvciBob29rLCBvciBpcyBlbWl0dGVkIG9uXG4gICAqIHRoZSBjb25maWd1cmF0aW9uJ3MgZnJhbWV3b3JrLWVycm9yL2FsbC1lcnJvciBjaGFubmVscyAoc28gcHJvZHVjdGlvbiBidWdcbiAgICogcmVwb3J0aW5nIHZpYSBgY29uZmlndXJhdGlvbi5nZXRFcnJvckV2ZW50cygpYCBzZWVzIGEgYnJva2VuIHB1Ymxpc2hcbiAgICogcGF0aCkgYW5kIGxvZ2dlZCBsb3VkbHkgdGhyb3VnaCB0aGUgcHVibGlzaGVyJ3MgbG9nZ2VyIHdoZW4gbm9uZSBpc1xuICAgKiBjb25maWd1cmVkLlxuICAgKiBAcGFyYW0ge0Vycm9yfSBlcnJvciAtIFBvc3QtY29tbWl0IHB1Ymxpc2ggZmFpbHVyZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyByZXBvcnRBZnRlckNvbW1pdEVycm9yKGVycm9yKSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLm9uRXJyb3IpIHtcbiAgICAgIHRoaXMuY29uZmlnLm9uRXJyb3IoZXJyb3IpXG5cbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGNvbnN0IGVycm9yRXZlbnRzID0gdGhpcy5jb25maWcuY29uZmlndXJhdGlvbi5nZXRFcnJvckV2ZW50cygpXG4gICAgY29uc3QgcGF5bG9hZCA9IHtjb250ZXh0OiB7c3RhZ2U6IFwic3luYy1wdWJsaXNoLWFmdGVyLWNvbW1pdFwifSwgZXJyb3J9XG5cbiAgICBlcnJvckV2ZW50cy5lbWl0KFwiZnJhbWV3b3JrLWVycm9yXCIsIHBheWxvYWQpXG4gICAgZXJyb3JFdmVudHMuZW1pdChcImFsbC1lcnJvclwiLCB7Li4ucGF5bG9hZCwgZXJyb3JUeXBlOiBcImZyYW1ld29yay1lcnJvclwifSlcblxuICAgIGF3YWl0IHRoaXMubG9nZ2VyKCkuZXJyb3IoXCJTeW5jUHVibGlzaGVyIGZhaWxlZCB0byBwdWJsaXNoIGEgc2VydmVyLXNpZGUgc3luYyBjaGFuZ2UgYWZ0ZXIgY29tbWl0XCIsIGVycm9yKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGxhemlseSBidWlsdCBwdWJsaXNoZXIgbG9nZ2VyLlxuICAgKiBAcmV0dXJucyB7TG9nZ2VyfSBQdWJsaXNoZXIgbG9nZ2VyLlxuICAgKi9cbiAgbG9nZ2VyKCkge1xuICAgIHRoaXMuX2xvZ2dlciB8fD0gbmV3IExvZ2dlcihcIlN5bmNQdWJsaXNoZXJcIiwge2NvbmZpZ3VyYXRpb246IHRoaXMuY29uZmlnLmNvbmZpZ3VyYXRpb259KVxuXG4gICAgcmV0dXJuIHRoaXMuX2xvZ2dlclxuICB9XG59XG5cbi8qKlxuICogUmVzb2x2ZXMgYSBtb2RlbCBjbGFzcydzIGFjdGl2ZSBwdWJsaXNoIGRlY2xhcmF0aW9uIGZyb20gYHN0YXRpYyBzeW5jYC5cbiAqIE9wdGVkLW91dCAoYHB1Ymxpc2g6IGZhbHNlYCkgYW5kIHVuZGVjbGFyZWQgbW9kZWxzIHJlc29sdmUgdG8gbnVsbDsgZXZlcnlcbiAqIG90aGVyIGRlY2xhcmVkIHZhbHVlIGZsb3dzIGludG8gbG91ZCBkZWNsYXJhdGlvbiB2YWxpZGF0aW9uLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gbW9kZWxDbGFzcyAtIFJlZ2lzdGVyZWQgbW9kZWwgY2xhc3MuXG4gKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaERlY2xhcmF0aW9uIHwgbnVsbH0gQWN0aXZlIHB1Ymxpc2ggZGVjbGFyYXRpb24sIG9yIG51bGwuXG4gKi9cbmZ1bmN0aW9uIHB1Ymxpc2hEZWNsYXJhdGlvbkZvcihtb2RlbENsYXNzKSB7XG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gbW9kZWxDbGFzcy5zeW5jXG5cbiAgaWYgKCFkZWNsYXJhdGlvbiB8fCB0eXBlb2YgZGVjbGFyYXRpb24gIT09IFwib2JqZWN0XCIgfHwgZGVjbGFyYXRpb24ucHVibGlzaCA9PT0gdW5kZWZpbmVkIHx8IGRlY2xhcmF0aW9uLnB1Ymxpc2ggPT09IGZhbHNlKSByZXR1cm4gbnVsbFxuXG4gIHJldHVybiBkZWNsYXJhdGlvbi5wdWJsaXNoXG59XG5cbi8qKlxuICogQnVpbGRzIG9uZSBwdWJsaXNoZWQgcmVzb3VyY2UgY29uZmlnIGZyb20gYSBtb2RlbCdzIGBzdGF0aWMgc3luY2AgcHVibGlzaFxuICogZGVjbGFyYXRpb24uIGBwdWJsaXNoOiB0cnVlYCBvcHRzIGluIHdpdGggYWxsIGRlZmF1bHRzIChhdHRyaWJ1dGUgcGF5bG9hZCxcbiAqIGRlcml2ZWQgc2NvcGUgcGFydGl0aW9uLCBjcmVhdGVkL3VwZGF0ZWQgb3BlcmF0aW9ucykuXG4gKiBAcGFyYW0ge3ttb2RlbENsYXNzOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPiwgcHVibGlzaDogaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaERlY2xhcmF0aW9uIHwgbnVsbCwgc2NvcGVBdHRyaWJ1dGVzOiBzdHJpbmdbXSB8IG51bGwsIHN5bmNNb2RlbDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59fSBhcmdzIC0gRGVjbGFyYXRpb24gYXJncyBwbHVzIHRoZSBzeW5jIG1vZGVsJ3MgZGVjbGFyZWQgc2NvcGUgYXR0cmlidXRlcy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJSZXNvdXJjZUNvbmZpZ30gRGVyaXZlZCByZXNvdXJjZSBjb25maWcuXG4gKi9cbmZ1bmN0aW9uIHJlc291cmNlQ29uZmlnRnJvbVB1Ymxpc2hEZWNsYXJhdGlvbih7bW9kZWxDbGFzcywgcHVibGlzaCwgc2NvcGVBdHRyaWJ1dGVzOiBzeW5jU2NvcGVBdHRyaWJ1dGVzLCBzeW5jTW9kZWx9KSB7XG4gIGNvbnN0IG1vZGVsTmFtZSA9IG1vZGVsQ2xhc3MuZ2V0TW9kZWxOYW1lKClcbiAgY29uc3Qgbm9ybWFsaXplZFB1Ymxpc2ggPSBwdWJsaXNoID09PSB0cnVlID8ge30gOiBwdWJsaXNoXG5cbiAgaWYgKCFub3JtYWxpemVkUHVibGlzaCB8fCB0eXBlb2Ygbm9ybWFsaXplZFB1Ymxpc2ggIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShub3JtYWxpemVkUHVibGlzaCkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIG11c3QgYmUgdHJ1ZSwgZmFsc2Ugb3IgYSBwdWJsaXNoIGRlY2xhcmF0aW9uIG9iamVjdCwgZ290OiAke1N0cmluZyhwdWJsaXNoKX1gKVxuICB9XG5cbiAgY29uc3Qge2Jyb2FkY2FzdHMsIGV2ZW50SWQsIG9wZXJhdGlvbnMsIHJlc291cmNlVHlwZSwgc2NvcGVBdHRyaWJ1dGVzLCBzZXJpYWxpemUsIC4uLnJlc3REZWNsYXJhdGlvbn0gPSBub3JtYWxpemVkUHVibGlzaFxuICBjb25zdCB1bmtub3duS2V5cyA9IE9iamVjdC5rZXlzKHJlc3REZWNsYXJhdGlvbilcblxuICBpZiAodW5rbm93bktleXMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggcmVjZWl2ZWQgdW5rbm93biBrZXlzOiAke3Vua25vd25LZXlzLmpvaW4oXCIsIFwiKX0gKHN1cHBvcnRlZDogYnJvYWRjYXN0cywgZXZlbnRJZCAoZGVwcmVjYXRlZCksIG9wZXJhdGlvbnMsIHJlc291cmNlVHlwZSwgc2NvcGVBdHRyaWJ1dGVzLCBzZXJpYWxpemUpYClcbiAgfVxuICBpZiAoc2VyaWFsaXplICE9PSB1bmRlZmluZWQgJiYgdHlwZW9mIHNlcmlhbGl6ZSAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzZXJpYWxpemUgbXVzdCBiZSBhIGZ1bmN0aW9uIGJ1aWxkaW5nIHRoZSBwdWJsaXNoZWQgcGF5bG9hZCwgZ290OiAke1N0cmluZyhzZXJpYWxpemUpfWApXG4gIH1cbiAgaWYgKG9wZXJhdGlvbnMgIT09IHVuZGVmaW5lZCkge1xuICAgIGlmICghQXJyYXkuaXNBcnJheShvcGVyYXRpb25zKSB8fCBvcGVyYXRpb25zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBvcGVyYXRpb25zIG11c3QgYmUgYSBub24tZW1wdHkgYXJyYXkgb2YgY3JlYXRlL3VwZGF0ZS9kZXN0cm95YClcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IG9wZXJhdGlvbiBvZiBvcGVyYXRpb25zKSB7XG4gICAgICBpZiAoIShvcGVyYXRpb24gaW4gUFVCTElTSEVEX0NBTExCQUNLX05BTUVTKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIG9wZXJhdGlvbnMgbXVzdCBiZSBjcmVhdGUvdXBkYXRlL2Rlc3Ryb3ksIGdvdDogJHtTdHJpbmcob3BlcmF0aW9uKX1gKVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiB7XG4gICAgYnJvYWRjYXN0cyxcbiAgICBtb2RlbENsYXNzLFxuICAgIG9wZXJhdGlvbnM6IG9wZXJhdGlvbnMgPT09IHVuZGVmaW5lZCA/IERFRkFVTFRfUFVCTElTSEVEX09QRVJBVElPTlMgOiBvcGVyYXRpb25zLFxuICAgIHJlc291cmNlVHlwZTogcmVzb3VyY2VUeXBlID09PSB1bmRlZmluZWQgPyBtb2RlbE5hbWUgOiByZXNvdXJjZVR5cGUsXG4gICAgc2NvcGVQbGFuOiBzY29wZVBsYW5Gb3Ioe2V2ZW50SWQsIG1vZGVsQ2xhc3MsIG1vZGVsTmFtZSwgc2NvcGVBdHRyaWJ1dGVzLCBzeW5jTW9kZWwsIHN5bmNTY29wZUF0dHJpYnV0ZXN9KSxcbiAgICBzZXJpYWxpemU6IHNlcmlhbGl6ZSA9PT0gdW5kZWZpbmVkID8gZGVmYXVsdFNlcmlhbGl6ZWRBdHRyaWJ1dGVzIDogc2VyaWFsaXplXG4gIH1cbn1cblxuLyoqXG4gKiBEZXJpdmVzIHRoZSBzY29wZSBwbGFuIHBhcnRpdGlvbmluZyBhIHB1Ymxpc2hlZCBtb2RlbCdzIGNoYW5nZXM6IG9uZSBlbnRyeVxuICogcGVyIHNjb3BlIGF0dHJpYnV0ZSBkZWNsYXJlZCBvbiB0aGUgc3luYyBtb2RlbCAoYHN0YXRpY1xuICogc3luY1Njb3BlQXR0cmlidXRlc2ApLCBlYWNoIHJlYWRpbmcgdGhlIHJlY29yZCBhdHRyaWJ1dGUgbmFtZWQgbGlrZSB0aGVcbiAqIHNjb3BlIGF0dHJpYnV0ZSAob3ZlcnJpZGFibGUgdGhyb3VnaCB0aGUgZGVjbGFyYXRpb24ncyBgc2NvcGVBdHRyaWJ1dGVzYFxuICogbmFtZSBtYXApLCBvciB0aGUgcmVjb3JkJ3Mgb3duIGlkIHdoZW4gdGhlIG1vZGVsIGhhcyBubyBzdWNoIGF0dHJpYnV0ZVxuICogKHNjb3BlLXJvb3QgbW9kZWxzKS4gVGhlIGRlcHJlY2F0ZWQgYGV2ZW50SWRgIGRlY2xhcmF0aW9uIGZvcm1zIG1hcCB0byBhXG4gKiBmaXhlZCBgZXZlbnRJZGAvYGV2ZW50X2lkYCBwbGFuIGZvciAxLjAuNTAzIGNvbXBhdGliaWxpdHkuXG4gKiBAcGFyYW0ge3tldmVudElkOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoRGVjbGFyYXRpb25Db25maWdbXCJldmVudElkXCJdLCBtb2RlbENsYXNzOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPiwgbW9kZWxOYW1lOiBzdHJpbmcsIHNjb3BlQXR0cmlidXRlczogUmVjb3JkPHN0cmluZywgc3RyaW5nPiB8IHVuZGVmaW5lZCwgc3luY01vZGVsOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPiwgc3luY1Njb3BlQXR0cmlidXRlczogc3RyaW5nW10gfCBudWxsfX0gYXJncyAtIERlY2xhcmF0aW9uIGFuZCBzeW5jLW1vZGVsIHNjb3BlIGFyZ3MuXG4gKiBAcmV0dXJucyB7QXJyYXk8aW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyU2NvcGVQbGFuRW50cnk+fSBEZXJpdmVkIHNjb3BlIHBsYW4uXG4gKi9cbmZ1bmN0aW9uIHNjb3BlUGxhbkZvcih7ZXZlbnRJZCwgbW9kZWxDbGFzcywgbW9kZWxOYW1lLCBzY29wZUF0dHJpYnV0ZXMsIHN5bmNNb2RlbCwgc3luY1Njb3BlQXR0cmlidXRlc30pIHtcbiAgY29uc3QgYXR0cmlidXRlTmFtZXMgPSBPYmplY3QudmFsdWVzKG1vZGVsQ2xhc3MuZ2V0Q29sdW1uTmFtZVRvQXR0cmlidXRlTmFtZU1hcCgpKVxuXG4gIGlmIChldmVudElkICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoc2NvcGVBdHRyaWJ1dGVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggY2FuJ3QgZGVjbGFyZSBib3RoIHNjb3BlQXR0cmlidXRlcyBhbmQgdGhlIGRlcHJlY2F0ZWQgZXZlbnRJZCBmb3JtYClcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBldmVudElkID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIHJldHVybiBbe2NvbHVtbk5hbWU6IFwiZXZlbnRfaWRcIiwgcmVjb3JkQXR0cmlidXRlOiBudWxsLCByZXNvbHZlcjogZXZlbnRJZCwgc2NvcGVBdHRyaWJ1dGU6IFwiZXZlbnRJZFwifV1cbiAgICB9XG4gICAgaWYgKHR5cGVvZiBldmVudElkICE9PSBcInN0cmluZ1wiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIGV2ZW50SWQgbXVzdCBiZSBhbiBhdHRyaWJ1dGUtbmFtZSBzdHJpbmcgKG9yIGEgZGVwcmVjYXRlZCByZXNvbHZlciBmdW5jdGlvbiksIGdvdDogJHtTdHJpbmcoZXZlbnRJZCl9YClcbiAgICB9XG4gICAgaWYgKCFhdHRyaWJ1dGVOYW1lcy5pbmNsdWRlcyhldmVudElkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBldmVudElkIGF0dHJpYnV0ZSBkb2Vzbid0IGV4aXN0IG9uIHRoZSBtb2RlbDogJHtldmVudElkfWApXG4gICAgfVxuXG4gICAgcmV0dXJuIFt7Y29sdW1uTmFtZTogXCJldmVudF9pZFwiLCByZWNvcmRBdHRyaWJ1dGU6IGV2ZW50SWQsIHJlc29sdmVyOiB1bmRlZmluZWQsIHNjb3BlQXR0cmlidXRlOiBcImV2ZW50SWRcIn1dXG4gIH1cblxuICBpZiAoc2NvcGVBdHRyaWJ1dGVzICE9PSB1bmRlZmluZWQgJiYgIXN5bmNTY29wZUF0dHJpYnV0ZXMpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIGRlY2xhcmVzIHNjb3BlQXR0cmlidXRlcyBidXQgdGhlIHN5bmMgbW9kZWwgZGVjbGFyZXMgbm8gc3RhdGljIHN5bmNTY29wZUF0dHJpYnV0ZXNgKVxuICB9XG5cbiAgaWYgKCFzeW5jU2NvcGVBdHRyaWJ1dGVzKSByZXR1cm4gW11cblxuICBpZiAoc2NvcGVBdHRyaWJ1dGVzICE9PSB1bmRlZmluZWQgJiYgKHR5cGVvZiBzY29wZUF0dHJpYnV0ZXMgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShzY29wZUF0dHJpYnV0ZXMpKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggc2NvcGVBdHRyaWJ1dGVzIG11c3QgYmUgYW4gb2JqZWN0IG1hcHBpbmcgc2NvcGUgYXR0cmlidXRlcyB0byByZWNvcmQgYXR0cmlidXRlIG5hbWVzLCBnb3Q6ICR7U3RyaW5nKHNjb3BlQXR0cmlidXRlcyl9YClcbiAgfVxuXG4gIGZvciAoY29uc3Qgc2NvcGVBdHRyaWJ1dGUgb2YgT2JqZWN0LmtleXMoc2NvcGVBdHRyaWJ1dGVzIHx8IHt9KSkge1xuICAgIGlmICghc3luY1Njb3BlQXR0cmlidXRlcy5pbmNsdWRlcyhzY29wZUF0dHJpYnV0ZSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggc2NvcGVBdHRyaWJ1dGVzIHJlY2VpdmVkIHVua25vd24gc2NvcGUgYXR0cmlidXRlOiAke3Njb3BlQXR0cmlidXRlfSAodGhlIHN5bmMgbW9kZWwgZGVjbGFyZXM6ICR7c3luY1Njb3BlQXR0cmlidXRlcy5qb2luKFwiLCBcIil9KWApXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHN5bmNTY29wZUF0dHJpYnV0ZXMubWFwKChzY29wZUF0dHJpYnV0ZSkgPT4ge1xuICAgIGNvbnN0IGRlY2xhcmVkUmVjb3JkQXR0cmlidXRlID0gc2NvcGVBdHRyaWJ1dGVzPy5bc2NvcGVBdHRyaWJ1dGVdXG5cbiAgICBpZiAoZGVjbGFyZWRSZWNvcmRBdHRyaWJ1dGUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgaWYgKHR5cGVvZiBkZWNsYXJlZFJlY29yZEF0dHJpYnV0ZSAhPT0gXCJzdHJpbmdcIiB8fCAhYXR0cmlidXRlTmFtZXMuaW5jbHVkZXMoZGVjbGFyZWRSZWNvcmRBdHRyaWJ1dGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggc2NvcGVBdHRyaWJ1dGVzLiR7c2NvcGVBdHRyaWJ1dGV9IG11c3QgbmFtZSBhbiBleGlzdGluZyByZWNvcmQgYXR0cmlidXRlLCBnb3Q6ICR7U3RyaW5nKGRlY2xhcmVkUmVjb3JkQXR0cmlidXRlKX1gKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4ge2NvbHVtbk5hbWU6IHN5bmNTY29wZUNvbHVtbk5hbWUoe3Njb3BlQXR0cmlidXRlLCBzeW5jTW9kZWx9KSwgcmVjb3JkQXR0cmlidXRlOiBkZWNsYXJlZFJlY29yZEF0dHJpYnV0ZSwgcmVzb2x2ZXI6IHVuZGVmaW5lZCwgc2NvcGVBdHRyaWJ1dGV9XG4gICAgfVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGNvbHVtbk5hbWU6IHN5bmNTY29wZUNvbHVtbk5hbWUoe3Njb3BlQXR0cmlidXRlLCBzeW5jTW9kZWx9KSxcbiAgICAgIHJlY29yZEF0dHJpYnV0ZTogYXR0cmlidXRlTmFtZXMuaW5jbHVkZXMoc2NvcGVBdHRyaWJ1dGUpID8gc2NvcGVBdHRyaWJ1dGUgOiBudWxsLFxuICAgICAgcmVzb2x2ZXI6IHVuZGVmaW5lZCxcbiAgICAgIHNjb3BlQXR0cmlidXRlXG4gICAgfVxuICB9KVxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBzeW5jLXJvdyBjb2x1bW4gcGVyc2lzdGluZyBhIGRlY2xhcmVkIHNjb3BlIGF0dHJpYnV0ZS5cbiAqIEBwYXJhbSB7e3Njb3BlQXR0cmlidXRlOiBzdHJpbmcsIHN5bmNNb2RlbDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59fSBhcmdzIC0gU2NvcGUgYXR0cmlidXRlIGFuZCBzeW5jIG1vZGVsLlxuICogQHJldHVybnMge3N0cmluZ30gU3luYy1yb3cgY29sdW1uIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIHN5bmNTY29wZUNvbHVtbk5hbWUoe3Njb3BlQXR0cmlidXRlLCBzeW5jTW9kZWx9KSB7XG4gIGNvbnN0IGNvbHVtbk5hbWUgPSBzeW5jTW9kZWwuZ2V0QXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcCgpW3Njb3BlQXR0cmlidXRlXVxuXG4gIGlmICghY29sdW1uTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtzeW5jTW9kZWwubmFtZX0gZGVjbGFyZXMgdGhlIHN5bmMgc2NvcGUgYXR0cmlidXRlICR7c2NvcGVBdHRyaWJ1dGV9IGJ1dCBoYXMgbm8gbWF0Y2hpbmcgY29sdW1uIGZvciBpdGApXG4gIH1cblxuICByZXR1cm4gY29sdW1uTmFtZVxufVxuXG4vKipcbiAqIERlZmF1bHQgcHVibGlzaCBzZXJpYWxpemVyOiB0aGUgcmVjb3JkJ3MgYXR0cmlidXRlcyB3aXRoIERhdGUgdmFsdWVzXG4gKiBzZXJpYWxpemVkIHRvIElTTyBzdHJpbmdzLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gcmVjb3JkIC0gTXV0YXRlZCBzZXJ2ZXIgbW9kZWwgcmVjb3JkLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gU2VyaWFsaXplZCBhdHRyaWJ1dGVzIHBheWxvYWQuXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRTZXJpYWxpemVkQXR0cmlidXRlcyhyZWNvcmQpIHtcbiAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovXG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSB7Li4ucmVjb3JkLmF0dHJpYnV0ZXMoKX1cblxuICBmb3IgKGNvbnN0IFthdHRyaWJ1dGVOYW1lLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYXR0cmlidXRlcykpIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSBhdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdID0gdmFsdWUudG9JU09TdHJpbmcoKVxuICB9XG5cbiAgcmV0dXJuIGF0dHJpYnV0ZXNcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIGRhdGUtbGlrZSB2YWx1ZSB0byBhbiBJU08gc3RyaW5nLCBtYXRjaGluZyB0aGUgY2hhbmdlLWZlZWRcbiAqIHNlcmlhbGl6ZXIncyBjb252ZW50aW9uIGZvciB0aGUgc3luYyBlbnRyeSdzIHB1YmxpYyB1cGRhdGVkLWF0IG1ldGFkYXRhLlxuICogQHBhcmFtIHtEYXRlIHwgbnVsbH0gdmFsdWUgLSBQZXJzaXN0ZWQgdXBkYXRlZC1hdCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IElTTyBkYXRlLlxuICogQHRocm93cyB7RXJyb3J9IFdoZW4gdGhlIHBlcnNpc3RlZCByb3cgaGFzIG5vIHZhbGlkIHVwZGF0ZWQtYXQgdGltZXN0YW1wLlxuICovXG5mdW5jdGlvbiBpc29EYXRlKHZhbHVlKSB7XG4gIGlmICghKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgfHwgTnVtYmVyLmlzTmFOKHZhbHVlLmdldFRpbWUoKSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJQdWJsaXNoZWQgc3luYyByb3cgbXVzdCBoYXZlIGEgdmFsaWQgdXBkYXRlZEF0IHRpbWVzdGFtcC5cIilcbiAgfVxuXG4gIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpXG59XG4iXX0=
608
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1wdWJsaXNoZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3luYy9zeW5jLXB1Ymxpc2hlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxhQUFhLE1BQU0scUJBQXFCLENBQUE7QUFDL0MsT0FBTyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBQ2pDLE9BQU8sRUFBQywwQkFBMEIsRUFBQyxNQUFNLCtCQUErQixDQUFBO0FBQ3hFLE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBQ3ZELE9BQU8sU0FBUyxNQUFNLHdCQUF3QixDQUFBO0FBQzlDLE9BQU8sbUJBQW1CLE1BQU0seUJBQXlCLENBQUE7QUFFekQsT0FBTyxFQUFDLDJCQUEyQixFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFDdEUsT0FBTyxFQUFDLHlCQUF5QixFQUFFLGFBQWEsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQ2hGLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLCtCQUErQixDQUFBO0FBQ3BFLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBRTdELHNGQUFzRjtBQUN0RixNQUFNLHdCQUF3QixHQUFHLEVBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUMsQ0FBQTtBQUV4Rzs7Ozs7O29EQU1vRDtBQUNwRCxNQUFNLDRCQUE0QixHQUFHLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFBO0FBRXpELG9EQUFvRDtBQUNwRCxNQUFNLGdDQUFnQyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7QUFFdEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkJHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyxhQUFhO0lBQ2hDOzs7Ozs7OztPQVFHO0lBQ0gsWUFBWSxPQUFPLEdBQUcsRUFBRTtRQUN0QixNQUFNLEVBQUMs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NERBQTREO0lBQzVELE1BQU0sVUFBVSxHQUFHLEVBQUMsR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLEVBQUMsQ0FBQTtJQUUzQyxLQUFLLE1BQU0sQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQ2hFLElBQUksS0FBSyxZQUFZLElBQUk7WUFBRSxVQUFVLENBQUMsYUFBYSxDQUFDLEdBQUcsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFBO0lBQzVFLENBQUM7SUFFRCxPQUFPLFVBQVUsQ0FBQTtBQUNuQixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBUyxPQUFPLENBQUMsS0FBSztJQUNwQixJQUFJLENBQUMsQ0FBQyxLQUFLLFlBQVksSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQzlELE1BQU0sSUFBSSxLQUFLLENBQUMsMkRBQTJELENBQUMsQ0FBQTtJQUM5RSxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUE7QUFDNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgQ29uZmlndXJhdGlvbiBmcm9tIFwiLi4vY29uZmlndXJhdGlvbi5qc1wiXG5pbXBvcnQgTG9nZ2VyIGZyb20gXCIuLi9sb2dnZXIuanNcIlxuaW1wb3J0IHtzY2FsYXJNb2RlbFByaW1hcnlLZXlWYWx1ZX0gZnJvbSBcIi4uL3V0aWxzL21vZGVsLXByaW1hcnkta2V5LmpzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuaW1wb3J0IHNoYTI1NkhleCBmcm9tIFwiLi4vdXRpbHMvc2hhMjU2LWhleC5qc1wiXG5pbXBvcnQgc3RhYmxlSnNvblN0cmluZ2lmeSBmcm9tIFwiLi4vdXRpbHMvc3RhYmxlLWpzb24uanNcIlxuXG5pbXBvcnQge2RlY2xhcmVkU3luY1Njb3BlQXR0cmlidXRlc30gZnJvbSBcIi4vc3luYy1zY29wZS1hdHRyaWJ1dGVzLmpzXCJcbmltcG9ydCB7ZGVsaXZlckRlY2xhcmVkQnJvYWRjYXN0cywgdXBzZXJ0U3luY1Jvd30gZnJvbSBcIi4vc3luYy1jaGFuZ2UtZmFub3V0LmpzXCJcbmltcG9ydCB7aXNQdWJsaXNoaW5nU3VwcHJlc3NlZH0gZnJvbSBcIi4vc3luYy1wdWJsaXNoLXN1cHByZXNzaW9uLmpzXCJcbmltcG9ydCB7VkVMT0NJT1VTX1NZTkNfQ0hBTk5FTH0gZnJvbSBcIi4vc3luYy1jaGFubmVsLW5hbWUuanNcIlxuXG4vKiogQHR5cGUge3tjcmVhdGU6IFwiYWZ0ZXJDcmVhdGVcIiwgdXBkYXRlOiBcImFmdGVyVXBkYXRlXCIsIGRlc3Ryb3k6IFwiYWZ0ZXJEZXN0cm95XCJ9fSAqL1xuY29uc3QgUFVCTElTSEVEX0NBTExCQUNLX05BTUVTID0ge2NyZWF0ZTogXCJhZnRlckNyZWF0ZVwiLCBkZXN0cm95OiBcImFmdGVyRGVzdHJveVwiLCB1cGRhdGU6IFwiYWZ0ZXJVcGRhdGVcIn1cblxuLyoqXG4gKiBPcGVyYXRpb25zIHB1Ymxpc2hlZCBieSBkZWZhdWx0IGZvciBtb2RlbHMgZGVjbGFyaW5nIGBzdGF0aWMgc3luY2AgcHVibGlzaFxuICogd2l0aG91dCBhbiBgb3BlcmF0aW9uc2Aga2V5OiBzZXJ2ZXItc2lkZSBjcmVhdGVzIGFuZCB1cGRhdGVzIHB1Ymxpc2hcbiAqIGF1dG9tYXRpY2FsbHkuIERlc3Ryb3lzIGFyZSBub3QgcHVibGlzaGVkIGJ5IGRlZmF1bHQgYmVjYXVzZSBhIHNlcnZlclxuICogZGVzdHJveSBpcyBvZnRlbiBjbGVhbnVwIHJhdGhlciB0aGFuIGEgc3luY2VkIGRlbGV0ZTsgb3B0IGluIHdpdGggYW5cbiAqIG9wZXJhdGlvbnMgbGlzdC5cbiAqIEB0eXBlIHtBcnJheTxcImNyZWF0ZVwiIHwgXCJ1cGRhdGVcIiB8IFwiZGVzdHJveVwiPn0gKi9cbmNvbnN0IERFRkFVTFRfUFVCTElTSEVEX09QRVJBVElPTlMgPSBbXCJjcmVhdGVcIiwgXCJ1cGRhdGVcIl1cblxuLyoqIEB0eXBlIHtXZWFrTWFwPENvbmZpZ3VyYXRpb24sIFN5bmNQdWJsaXNoZXI+fSAqL1xuY29uc3Qgc3RhcnRlZFB1Ymxpc2hlcnNCeUNvbmZpZ3VyYXRpb24gPSBuZXcgV2Vha01hcCgpXG5cbi8qKlxuICogRGVjbGFyYXRpdmUgc2VydmVyLXNpZGUgc3luYyBwdWJsaXNoZXIg4oCUIHRoZSBzZXJ2ZXIgbWlycm9yIG9mIHRoZSBjbGllbnQnc1xuICogdHJhY2stYnktZGVmYXVsdCBtdXRhdGlvbiB0cmFja2luZy5cbiAqXG4gKiBTZXJ2ZXIgbW9kZWxzIGRlY2xhcmUgd2hhdCB0byBwdWJsaXNoIHRocm91Z2ggYHN0YXRpYyBzeW5jYCdzIGBwdWJsaXNoYFxuICoga2V5LCBhbmQgVmVsb2Npb3VzIHdyaXRlcyBldmVyeSBjb21taXR0ZWQgc2VydmVyLXNpZGUgY2hhbmdlIHRvIHRoZSBzeW5jXG4gKiBjaGFuZ2UgZmVlZCAobW9kZWwtYmFja2VkIFN5bmMtcm93IHVwc2VydCB3aXRoIHNlcnZlciByZS1zZXF1ZW5jaW5nKSBhbmRcbiAqIGJyb2FkY2FzdHMgdGhlIHN0YW5kYXJkIHN5bmMgZW52ZWxvcGUgKGB7ZWNob09yaWdpbiwgc3luY3M6IFsuLi5dfWApIG9uIHRoZVxuICogZnJhbWV3b3JrIHN5bmMgY2hhbm5lbCAoe0BsaW5rIFZFTE9DSU9VU19TWU5DX0NIQU5ORUx9KSBzY29wZWQgYnkgdGhlXG4gKiBjaGFuZ2UncyBkZXJpdmVkIHNjb3BlLXBhcnRpdGlvbiB2YWx1ZXMsIHNvIGRldmljZXMgcmVjZWl2ZSBzZXJ2ZXItb3JpZ2luXG4gKiBjaGFuZ2VzIHdpdGhvdXQgYXBwIGNvZGUgZGVjbGFyaW5nIGNoYW5uZWxzIG9yIGNhbGxpbmcgbWFudWFsXG4gKiB1cHNlcnQvYnJvYWRjYXN0IGhlbHBlcnM6XG4gKlxuICogICAgIHN0YXRpYyBzeW5jID0ge3B1Ymxpc2g6IHRydWV9IC8vIGRlZmF1bHQgcGF5bG9hZCAoYXR0cmlidXRlcykgKyBkZWZhdWx0IHNjb3BlIHBhcnRpdGlvblxuICogICAgIHN0YXRpYyBzeW5jID0ge3B1Ymxpc2g6IHtzZXJpYWxpemU6IChyZWNvcmQpID0+ICh7aWQ6IHJlY29yZC5pZCgpLCBwaW46IHJlY29yZC5waW4oKX0pfX1cbiAqXG4gKiBUaGUgc2NvcGUgcGFydGl0aW9uIGNvbWVzIGZyb20gdGhlIHN5bmMgbW9kZWwncyBgc3RhdGljXG4gKiBzeW5jU2NvcGVBdHRyaWJ1dGVzYCBkZWNsYXJhdGlvbiAoZm9yIGV4YW1wbGUgYFtcImV2ZW50SWRcIl1gIG9yXG4gKiBgW1wiYWNjb3VudElkXCJdYCDigJQgVmVsb2Npb3VzIGhhcyBubyBidWlsdC1pbiBwYXJ0aXRpb24gbmFtZSk6IGVhY2ggZGVjbGFyZWRcbiAqIHNjb3BlIGF0dHJpYnV0ZSByZWFkcyB0aGUgcmVjb3JkJ3MgYXR0cmlidXRlIG9mIHRoZSBzYW1lIG5hbWUgd2hlbiB0aGVcbiAqIG1vZGVsIGhhcyBvbmUsIGVsc2UgdGhlIHJlY29yZCdzIG93biBpZCAoc2NvcGUtcm9vdCBtb2RlbHMpLCBvdmVycmlkYWJsZVxuICogcGVyIG1vZGVsIHRocm91Z2ggYHB1Ymxpc2g6IHtzY29wZUF0dHJpYnV0ZXM6IHthY2NvdW50SWQ6IFwib3duZXJJZFwifX1gLlxuICogVGhlIHByZS1mcmFtZXdvcmstY2hhbm5lbCBgYnJvYWRjYXN0c2AgbGlzdCBhbmQgdGhlIGBldmVudElkYFxuICogc3RyaW5nL3Jlc29sdmVyLWZ1bmN0aW9uIGRlY2xhcmF0aW9uIGZvcm1zIGtlZXAgd29ya2luZyBidXQgYXJlIGRlcHJlY2F0ZWQuXG4gKlxuICogUmVwbGF5ZWQgZGV2aWNlIG11dGF0aW9ucyBuZXZlciBkb3VibGUtcHVibGlzaDogdGhlIGZyYW1ld29yaydzIHJvdXRlZFxuICogcmVwbGF5IGFwcGx5IG1hcmtzIGl0cyB3cml0dGVuIHJlY29yZHMgdGhyb3VnaCBgbWFya1NlcnZlckFwcGx5KHJlY29yZClgXG4gKiAoc2VlIHN5bmMtcHVibGlzaC1zdXBwcmVzc2lvbi5qcyksIGFuZCBhcHAgY29kZSBhcHBseWluZyBhbHJlYWR5LXN5bmNlZFxuICogZGF0YSBjYW4gdXNlIGBtYXJrU2VydmVyQXBwbHlgL2B3aXRob3V0UHVibGlzaGluZ2AgdGhlIHNhbWUgd2F5LlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBTeW5jUHVibGlzaGVyIHtcbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgc3luYyBwdWJsaXNoZXIgYnkgZGVyaXZpbmcgcHVibGlzaGVkIHJlc291cmNlcyBmcm9tIHRoZVxuICAgKiBjb25maWd1cmF0aW9uJ3MgcmVnaXN0ZXJlZCBtb2RlbHM6IGV2ZXJ5IG1vZGVsIGRlY2xhcmluZyBgc3RhdGljIHN5bmNgXG4gICAqIHdpdGggYSBgcHVibGlzaGAgZGVjbGFyYXRpb24gYmVjb21lcyBhIHB1Ymxpc2hlZCByZXNvdXJjZVxuICAgKiAoYHB1Ymxpc2g6IGZhbHNlYCBvcHRzIG91dCkuIFRoZSBzeW5jL2NoYW5nZSBtb2RlbCBpcyB0aGUgcmVnaXN0ZXJlZFxuICAgKiBcIlN5bmNcIiBtb2RlbCBhbmQgYnJvYWRjYXN0cyBkZWZhdWx0IHRvIHRoZSBjb25maWd1cmF0aW9uJ3MgY2hhbm5lbFxuICAgKiBicm9hZGNhc3QuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyT3B0aW9uc30gW29wdGlvbnNdIC0gT3B0aW9uYWwgb3ZlcnJpZGVzLlxuICAgKi9cbiAgY29uc3RydWN0b3Iob3B0aW9ucyA9IHt9KSB7XG4gICAgY29uc3Qge2FjdG9yRm9yZWlnbktleUNvbHVtbiA9IFwiYXV0aGVudGljYXRpb25fdG9rZW5faWRcIiwgYnJvYWRjYXN0ZXIsIGNvbmZpZ3VyYXRpb24gPSBDb25maWd1cmF0aW9uLmN1cnJlbnQoKSwgb25FcnJvciwgc3luY01vZGVsLCAuLi5yZXN0T3B0aW9uc30gPSBvcHRpb25zXG5cbiAgICByZXN0QXJnc0Vycm9yKHJlc3RPcHRpb25zKVxuXG4gICAgY29uc3QgbW9kZWxDbGFzc2VzID0gY29uZmlndXJhdGlvbi5nZXRNb2RlbENsYXNzZXMoKVxuICAgIGNvbnN0IHB1Ymxpc2hpbmdNb2RlbENsYXNzZXMgPSBPYmplY3QudmFsdWVzKG1vZGVsQ2xhc3NlcykuZmlsdGVyKChtb2RlbENsYXNzKSA9PiBwdWJsaXNoRGVjbGFyYXRpb25Gb3IobW9kZWxDbGFzcykpXG5cbiAgICBpZiAocHVibGlzaGluZ01vZGVsQ2xhc3Nlcy5sZW5ndGggPT09IDApIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmNQdWJsaXNoZXIgZm91bmQgbm8gcmVnaXN0ZXJlZCBtb2RlbHMgZGVjbGFyaW5nIHN0YXRpYyBzeW5jIHB1Ymxpc2ggLSBkZWNsYXJlIGBzdGF0aWMgc3luYyA9IHtwdWJsaXNoOiB7c2VyaWFsaXplfX1gIG9uIHRoZSBtb2RlbHMgd2hvc2Ugc2VydmVyLXNpZGUgY2hhbmdlcyBzaG91bGQgcHVibGlzaCB0byB0aGUgc3luYyBmZWVkXCIpXG4gICAgfVxuXG4gICAgY29uc3QgcmVzb2x2ZWRTeW5jTW9kZWwgPSBzeW5jTW9kZWwgfHwgbW9kZWxDbGFzc2VzLlN5bmNcblxuICAgIGlmICghcmVzb2x2ZWRTeW5jTW9kZWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmNQdWJsaXNoZXIgcmVxdWlyZXMgYSByZWdpc3RlcmVkIFxcXCJTeW5jXFxcIiBtb2RlbCBmb3IgcHVibGlzaGVkIHN5bmMgY2hhbmdlIHJvd3MgKG9yIHBhc3Mgb3B0aW9ucy5zeW5jTW9kZWwpXCIpXG4gICAgfVxuXG4gICAgY29uc3Qgc2NvcGVBdHRyaWJ1dGVzID0gZGVjbGFyZWRTeW5jU2NvcGVBdHRyaWJ1dGVzKHJlc29sdmVkU3luY01vZGVsKVxuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyUmVzb3VyY2VDb25maWc+fSAqL1xuICAgIGNvbnN0IHJlc291cmNlcyA9IHt9XG5cbiAgICBmb3IgKGNvbnN0IG1vZGVsQ2xhc3Mgb2YgcHVibGlzaGluZ01vZGVsQ2xhc3Nlcykge1xuICAgICAgY29uc3QgcHVibGlzaCA9IHB1Ymxpc2hEZWNsYXJhdGlvbkZvcihtb2RlbENsYXNzKVxuICAgICAgY29uc3QgcmVzb3VyY2VDb25maWcgPSByZXNvdXJjZUNvbmZpZ0Zyb21QdWJsaXNoRGVjbGFyYXRpb24oe21vZGVsQ2xhc3MsIHB1Ymxpc2gsIHNjb3BlQXR0cmlidXRlcywgc3luY01vZGVsOiByZXNvbHZlZFN5bmNNb2RlbH0pXG5cbiAgICAgIHJlc291cmNlc1tyZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGVdID0gcmVzb3VyY2VDb25maWdcbiAgICB9XG5cbiAgICAvKiogQHR5cGUge3thY3RvckZvcmVpZ25LZXlDb2x1bW46IHN0cmluZywgYnJvYWRjYXN0ZXI6IGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlck9wdGlvbnNbXCJicm9hZGNhc3RlclwiXSwgY29uZmlndXJhdGlvbjogQ29uZmlndXJhdGlvbiwgb25FcnJvcjogaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyT3B0aW9uc1tcIm9uRXJyb3JcIl0sIHJlc291cmNlczogUmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyUmVzb3VyY2VDb25maWc+LCBzeW5jTW9kZWw6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fX0gKi9cbiAgICB0aGlzLmNvbmZpZyA9IHthY3RvckZvcmVpZ25LZXlDb2x1bW4sIGJyb2FkY2FzdGVyLCBjb25maWd1cmF0aW9uLCBvbkVycm9yLCByZXNvdXJjZXMsIHN5bmNNb2RlbDogcmVzb2x2ZWRTeW5jTW9kZWx9XG4gICAgLyoqIEB0eXBlIHtBcnJheTx7Y2FsbGJhY2s6IChyZWNvcmQ6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+KSA9PiBQcm9taXNlPHZvaWQ+LCBjYWxsYmFja05hbWU6IFwiYWZ0ZXJDcmVhdGVcIiB8IFwiYWZ0ZXJVcGRhdGVcIiB8IFwiYWZ0ZXJEZXN0cm95XCIsIG1vZGVsQ2xhc3M6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fT59ICovXG4gICAgdGhpcy5fcHVibGlzaGVkQ2FsbGJhY2tzID0gW11cbiAgICAvKiogQHR5cGUge0xvZ2dlciB8IG51bGx9ICovXG4gICAgdGhpcy5fbG9nZ2VyID0gbnVsbFxuICAgIHRoaXMuX3N0YXJ0ZWQgPSBmYWxzZVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBhIHN5bmMgcHVibGlzaGVyIGRlcml2ZWQgZnJvbSB0aGUgZ2l2ZW4gY29uZmlndXJhdGlvbi4gQWxpYXMgZm9yXG4gICAqIGBuZXcgU3luY1B1Ymxpc2hlcih7Y29uZmlndXJhdGlvbiwgLi4ub3B0aW9uc30pYC5cbiAgICogQHBhcmFtIHtDb25maWd1cmF0aW9ufSBbY29uZmlndXJhdGlvbl0gLSBDb25maWd1cmF0aW9uIG93bmluZyB0aGUgcmVnaXN0ZXJlZCBtb2RlbHMuIERlZmF1bHRzIHRvIHRoZSBjdXJyZW50IGNvbmZpZ3VyYXRpb24uXG4gICAqIEBwYXJhbSB7T21pdDxpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJPcHRpb25zLCBcImNvbmZpZ3VyYXRpb25cIj59IFtvcHRpb25zXSAtIE9wdGlvbmFsIG92ZXJyaWRlcy5cbiAgICogQHJldHVybnMge1N5bmNQdWJsaXNoZXJ9IFN5bmMgcHVibGlzaGVyIGRlcml2ZWQgZnJvbSB0aGUgY29uZmlndXJhdGlvbi5cbiAgICovXG4gIHN0YXRpYyBmcm9tQ29uZmlndXJhdGlvbihjb25maWd1cmF0aW9uID0gQ29uZmlndXJhdGlvbi5jdXJyZW50KCksIG9wdGlvbnMgPSB7fSkge1xuICAgIHJldHVybiBuZXcgU3luY1B1Ymxpc2hlcih7Li4ub3B0aW9ucywgY29uZmlndXJhdGlvbn0pXG4gIH1cblxuICAvKipcbiAgICogU3RhcnRzIChhbmQgbWVtb2l6ZXMgcGVyIGNvbmZpZ3VyYXRpb24pIHRoZSBzeW5jIHB1Ymxpc2hlciBmb3IgYSBzZXJ2ZXJcbiAgICogYm9vdDogbm8tb3Agd2hlbiBubyByZWdpc3RlcmVkIG1vZGVsIGRlY2xhcmVzIGEgcHVibGlzaCBjb25maWcsIGd1YXJkZWQgc29cbiAgICogcmVwZWF0ZWQgYm9vdHMgd2l0aCB0aGUgc2FtZSBjb25maWd1cmF0aW9uIHJlZ2lzdGVyIHRoZSBwdWJsaXNoIGNhbGxiYWNrc1xuICAgKiBvbmx5IG9uY2UuXG4gICAqIEBwYXJhbSB7Q29uZmlndXJhdGlvbn0gY29uZmlndXJhdGlvbiAtIENvbmZpZ3VyYXRpb24gb3duaW5nIHRoZSByZWdpc3RlcmVkIG1vZGVscy5cbiAgICogQHJldHVybnMge1Byb21pc2U8U3luY1B1Ymxpc2hlciB8IG51bGw+fSBTdGFydGVkIHB1Ymxpc2hlciwgb3IgbnVsbCB3aGVuIG5vIG1vZGVscyBkZWNsYXJlIHB1Ymxpc2guXG4gICAqL1xuICBzdGF0aWMgYXN5bmMgc3RhcnRGcm9tQ29uZmlndXJhdGlvbihjb25maWd1cmF0aW9uKSB7XG4gICAgY29uc3Qgc3RhcnRlZFB1Ymxpc2hlciA9IHN0YXJ0ZWRQdWJsaXNoZXJzQnlDb25maWd1cmF0aW9uLmdldChjb25maWd1cmF0aW9uKVxuXG4gICAgaWYgKHN0YXJ0ZWRQdWJsaXNoZXIpIHJldHVybiBzdGFydGVkUHVibGlzaGVyXG5cbiAgICBpZiAoIU9iamVjdC52YWx1ZXMoY29uZmlndXJhdGlvbi5nZXRNb2RlbENsYXNzZXMoKSkuc29tZSgobW9kZWxDbGFzcykgPT4gcHVibGlzaERlY2xhcmF0aW9uRm9yKG1vZGVsQ2xhc3MpKSkgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHB1Ymxpc2hlciA9IG5ldyBTeW5jUHVibGlzaGVyKHtjb25maWd1cmF0aW9ufSlcblxuICAgIHN0YXJ0ZWRQdWJsaXNoZXJzQnlDb25maWd1cmF0aW9uLnNldChjb25maWd1cmF0aW9uLCBwdWJsaXNoZXIpXG4gICAgYXdhaXQgcHVibGlzaGVyLnN0YXJ0KClcblxuICAgIHJldHVybiBwdWJsaXNoZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWdpc3RlcnMgdGhlIHB1Ymxpc2ggY2FsbGJhY2tzIGZvciBldmVyeSBwdWJsaXNoZWQgcmVzb3VyY2U6IHNlcnZlci1zaWRlXG4gICAqIGNyZWF0ZXMgYW5kIHVwZGF0ZXMgKGRlc3Ryb3lzIHdoZW4gb3B0ZWQgaW4pIHVwc2VydCBhIHN5bmMgY2hhbmdlIHJvdyBhbmRcbiAgICogZmFuIG91dCB0aGUgZGVjbGFyZWQgYnJvYWRjYXN0cyBvbmNlIHRoZWlyIHRyYW5zYWN0aW9uIGNvbW1pdHMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgc3RhcnQoKSB7XG4gICAgaWYgKHRoaXMuX3N0YXJ0ZWQpIHJldHVyblxuXG4gICAgdGhpcy5fc3RhcnRlZCA9IHRydWVcblxuICAgIGZvciAoY29uc3QgcmVzb3VyY2VDb25maWcgb2YgT2JqZWN0LnZhbHVlcyh0aGlzLmNvbmZpZy5yZXNvdXJjZXMpKSB7XG4gICAgICBmb3IgKGNvbnN0IG9wZXJhdGlvbiBvZiByZXNvdXJjZUNvbmZpZy5vcGVyYXRpb25zKSB7XG4gICAgICAgIGNvbnN0IGNhbGxiYWNrTmFtZSA9IFBVQkxJU0hFRF9DQUxMQkFDS19OQU1FU1tvcGVyYXRpb25dXG4gICAgICAgIGNvbnN0IGNhbGxiYWNrID0gdGhpcy5wdWJsaXNoZWRNdXRhdGlvbkNhbGxiYWNrKHtvcGVyYXRpb24sIHJlc291cmNlQ29uZmlnfSlcblxuICAgICAgICByZXNvdXJjZUNvbmZpZy5tb2RlbENsYXNzW2NhbGxiYWNrTmFtZV0oY2FsbGJhY2spXG4gICAgICAgIHRoaXMuX3B1Ymxpc2hlZENhbGxiYWNrcy5wdXNoKHtjYWxsYmFjaywgY2FsbGJhY2tOYW1lLCBtb2RlbENsYXNzOiByZXNvdXJjZUNvbmZpZy5tb2RlbENsYXNzfSlcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogVW5yZWdpc3RlcnMgYWxsIHB1Ymxpc2ggY2FsbGJhY2tzICh0ZXN0cywgc2h1dGRvd24pLlxuICAgKiBAcmV0dXJucyB7dm9pZH1cbiAgICovXG4gIHN0b3AoKSB7XG4gICAgZm9yIChjb25zdCB7Y2FsbGJhY2ssIGNhbGxiYWNrTmFtZSwgbW9kZWxDbGFzc30gb2YgdGhpcy5fcHVibGlzaGVkQ2FsbGJhY2tzKSB7XG4gICAgICBtb2RlbENsYXNzLnVucmVnaXN0ZXJMaWZlY3ljbGVDYWxsYmFjayhjYWxsYmFja05hbWUsIGNhbGxiYWNrKVxuICAgIH1cblxuICAgIHRoaXMuX3B1Ymxpc2hlZENhbGxiYWNrcyA9IFtdXG4gICAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIHRoZSBsaWZlY3ljbGUgY2FsbGJhY2sgcHVibGlzaGluZyBvbmUgc2VydmVyLXNpZGUgbXV0YXRpb24uIFRoZVxuICAgKiBwdWJsaXNoZWQgcGF5bG9hZCAoZGVjbGFyYXRpb24gYHNlcmlhbGl6ZWApLCBldmVudCBzY29wZSwgYW5kIHN5bmMgdHlwZVxuICAgKiBhcmUgc25hcHNob3R0ZWQgYXQgbXV0YXRpb24tY2FsbGJhY2sgdGltZSwgc28gYWZ0ZXJTYXZlIGhvb2tzIGFzc2lnbmluZ1xuICAgKiB1bnNhdmVkIGF0dHJpYnV0ZXMgKG9yIGFueSBsYXRlciBkcmlmdCBvbiB0aGUgcmVjb3JkKSBjYW5ub3QgY2hhbmdlIHdoYXRcbiAgICogZ2V0cyBwdWJsaXNoZWQgdnMgd2hhdCB3YXMgY29tbWl0dGVkLiBQZXJzaXN0aW5nIGFuZCBicm9hZGNhc3RpbmcgYXJlXG4gICAqIGRlZmVycmVkIHRocm91Z2ggdGhlIG1vZGVsIGNvbm5lY3Rpb24ncyBhZnRlckNvbW1pdCBob29rIHNvIHRoZXkgb25seSBydW5cbiAgICogb25jZSB0aGUgbXV0YXRpb24ncyB0cmFuc2FjdGlvbiBoYXMgY29tbWl0dGVkIChpbW1lZGlhdGVseSB3aGVuIG5vXG4gICAqIHRyYW5zYWN0aW9uIGlzIG9wZW4pIC0gcm9sbGVkLWJhY2sgbXV0YXRpb25zIG5ldmVyIHB1Ymxpc2guIFBvc3QtY29tbWl0XG4gICAqIHB1Ymxpc2ggZmFpbHVyZXMgYXJlIHJlcG9ydGVkIHdpdGhvdXQgcmV0aHJvd2luZyBpbnRvIHRoZSBkcml2ZXInc1xuICAgKiBhZnRlckNvbW1pdCBjaGFpbiAoc2VlIHJlcG9ydEFmdGVyQ29tbWl0RXJyb3IpLlxuICAgKiBAcGFyYW0ge3tvcGVyYXRpb246IFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCIsIHJlc291cmNlQ29uZmlnOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJSZXNvdXJjZUNvbmZpZ319IGFyZ3MgLSBPcGVyYXRpb24gYW5kIHJlc291cmNlIGNvbmZpZy5cbiAgICogQHJldHVybnMgeyhyZWNvcmQ6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+KSA9PiBQcm9taXNlPHZvaWQ+fSBMaWZlY3ljbGUgY2FsbGJhY2suXG4gICAqL1xuICBwdWJsaXNoZWRNdXRhdGlvbkNhbGxiYWNrKHtvcGVyYXRpb24sIHJlc291cmNlQ29uZmlnfSkge1xuICAgIHJldHVybiBhc3luYyAocmVjb3JkKSA9PiB7XG4gICAgICBpZiAoaXNQdWJsaXNoaW5nU3VwcHJlc3NlZChyZWNvcmQpKSByZXR1cm5cblxuICAgICAgY29uc3QgZGF0YSA9IGF3YWl0IHJlc291cmNlQ29uZmlnLnNlcmlhbGl6ZShyZWNvcmQpXG4gICAgICBjb25zdCByZXNvdXJjZUlkID0gU3RyaW5nKHNjYWxhck1vZGVsUHJpbWFyeUtleVZhbHVlKHJlY29yZC5pZCgpLCBgU3luYyBwdWJsaXNoaW5nIGZvciAke3Jlc291cmNlQ29uZmlnLnJlc291cmNlVHlwZX1gKSlcbiAgICAgIGNvbnN0IHN5bmNUeXBlID0gb3BlcmF0aW9uID09PSBcImRlc3Ryb3lcIiA/IFwiZGVsZXRlXCIgOiBcInVwZGF0ZVwiXG4gICAgICBjb25zdCBzY29wZVZhbHVlcyA9IGF3YWl0IHRoaXMucHVibGlzaGVkU2NvcGVWYWx1ZXMoe3JlY29yZCwgcmVzb3VyY2VDb25maWd9KVxuICAgICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovXG4gICAgICBjb25zdCBhdHRyaWJ1dGVzID0ge1xuICAgICAgICBbdGhpcy5jb25maWcuYWN0b3JGb3JlaWduS2V5Q29sdW1uXTogbnVsbCxcbiAgICAgICAgY2xpZW50X3VwZGF0ZWRfYXQ6IG5ldyBEYXRlKCksXG4gICAgICAgIGRhdGE6IEpTT04uc3RyaW5naWZ5KGRhdGEpLFxuICAgICAgICByZXNvdXJjZV9pZDogcmVzb3VyY2VJZCxcbiAgICAgICAgcmVzb3VyY2VfdHlwZTogcmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlLFxuICAgICAgICBzeW5jX3R5cGU6IHN5bmNUeXBlLFxuICAgICAgICAuLi5zY29wZVZhbHVlcy5jb2x1bW5zXG4gICAgICB9XG4gICAgICBjb25zdCBkYXRhYmFzZU9wZXJhdGlvbiA9IHJlY29yZC5kYXRhYmFzZU9wZXJhdGlvbigpXG4gICAgICBjb25zdCBvcGVyYXRpb25TY29wZSA9IGRhdGFiYXNlT3BlcmF0aW9uXG4gICAgICAgID8gZGF0YWJhc2VPcGVyYXRpb24uZm9yTW9kZWwodGhpcy5jb25maWcuc3luY01vZGVsKVxuICAgICAgICA6IHRoaXMuY29uZmlnLnN5bmNNb2RlbFxuXG4gICAgICBhd2FpdCByZWNvcmQuY29ubmVjdGlvbigpLmFmdGVyQ29tbWl0KGFzeW5jICgpID0+IHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBjb25zdCBzY29wZUNvbHVtbk5hbWVzID0gcmVzb3VyY2VDb25maWcuc2NvcGVQbGFuLm1hcCgoe2NvbHVtbk5hbWV9KSA9PiBjb2x1bW5OYW1lKVxuICAgICAgICAgIGNvbnN0IHN5bmNSb3cgPSBhd2FpdCB0aGlzLnVwc2VydFB1Ymxpc2hlZFN5bmNSb3coYXR0cmlidXRlcywgb3BlcmF0aW9uU2NvcGUsIHNjb3BlQ29sdW1uTmFtZXMpXG5cbiAgICAgICAgICBhd2FpdCB0aGlzLmJyb2FkY2FzdGVyKCkoe1xuICAgICAgICAgICAgYm9keToge1xuICAgICAgICAgICAgICBlY2hvT3JpZ2luOiBudWxsLFxuICAgICAgICAgICAgICBzeW5jczogW3RoaXMucHVibGlzaGVkU3luY0VudHJ5KHtkYXRhLCByZXNvdXJjZUNvbmZpZywgcmVzb3VyY2VJZCwgc3luY1Jvdywgc3luY1R5cGV9KV1cbiAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBjaGFubmVsOiBWRUxPQ0lPVVNfU1lOQ19DSEFOTkVMLFxuICAgICAgICAgICAgcGFyYW1zOiB7Li4uc2NvcGVWYWx1ZXMucGFyYW1zLCByZXNvdXJjZVR5cGU6IHJlc291cmNlQ29uZmlnLnJlc291cmNlVHlwZX1cbiAgICAgICAgICB9KVxuXG4gICAgICAgICAgaWYgKHJlc291cmNlQ29uZmlnLmJyb2FkY2FzdHMpIHtcbiAgICAgICAgICAgIGF3YWl0IGRlbGl2ZXJEZWNsYXJlZEJyb2FkY2FzdHMoe1xuICAgICAgICAgICAgICBhcmdzOiB7ZGF0YSwgb3BlcmF0aW9uLCByZWNvcmQsIHJlc291cmNlSWQsIHJlc291cmNlVHlwZTogcmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlLCBzeW5jUm93LCBzeW5jVHlwZX0sXG4gICAgICAgICAgICAgIGJyb2FkY2FzdGVyOiB0aGlzLmJyb2FkY2FzdGVyKCksXG4gICAgICAgICAgICAgIGJyb2FkY2FzdHM6IHJlc291cmNlQ29uZmlnLmJyb2FkY2FzdHNcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgfVxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgIGF3YWl0IHRoaXMucmVwb3J0QWZ0ZXJDb21taXRFcnJvcigvKiogQHR5cGUge0Vycm9yfSAqLyAoZXJyb3IpKVxuICAgICAgICB9XG4gICAgICB9KVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgc2NvcGUtcGFydGl0aW9uIHZhbHVlcyBmb3Igb25lIHB1Ymxpc2hlZCBtdXRhdGlvbiBmcm9tIHRoZVxuICAgKiByZXNvdXJjZSdzIGRlcml2ZWQgc2NvcGUgcGxhbjogZWFjaCBlbnRyeSByZWFkcyBpdHMgcmVjb3JkIGF0dHJpYnV0ZSAob3JcbiAgICogdGhlIHJlY29yZCdzIG93biBpZCBmb3Igc2NvcGUtcm9vdCBtb2RlbHMsIG9yIHRoZSBkZXByZWNhdGVkIHJlc29sdmVyXG4gICAqIGZ1bmN0aW9uKS4gVGhlIHZhbHVlcyBhcmUgcGVyc2lzdGVkIG9udG8gdGhlIHN5bmMgcm93J3MgcGFydGl0aW9uIGNvbHVtbnNcbiAgICogYW5kIGJyb2FkY2FzdCBhcyB0aGUgZnJhbWV3b3JrIHN5bmMgY2hhbm5lbCdzIHNjb3BpbmcgcGFyYW1zLlxuICAgKiBAcGFyYW0ge3tyZWNvcmQ6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+LCByZXNvdXJjZUNvbmZpZzogaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyUmVzb3VyY2VDb25maWd9fSBhcmdzIC0gTXV0YXRlZCByZWNvcmQgYW5kIHJlc291cmNlIGNvbmZpZy5cbiAgICogQHJldHVybnMge1Byb21pc2U8e2NvbHVtbnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bGw+LCBwYXJhbXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bGw+fT59IFNjb3BlIHZhbHVlcyBrZXllZCBieSBzeW5jLXJvdyBjb2x1bW4gYW5kIGJ5IHNjb3BlIGF0dHJpYnV0ZS5cbiAgICovXG4gIGFzeW5jIHB1Ymxpc2hlZFNjb3BlVmFsdWVzKHtyZWNvcmQsIHJlc291cmNlQ29uZmlnfSkge1xuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVsbD59ICovXG4gICAgY29uc3QgY29sdW1ucyA9IHt9XG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudWxsPn0gKi9cbiAgICBjb25zdCBwYXJhbXMgPSB7fVxuICAgIGNvbnN0IGNvbXB1dGVkU2NvcGVBdHRyaWJ1dGVzID0gcmVzb3VyY2VDb25maWcuc2NvcGVBdHRyaWJ1dGVzUmVzb2x2ZXJcbiAgICAgID8gYXdhaXQgdGhpcy5yZXNvbHZlQ29tcHV0ZWRTY29wZUF0dHJpYnV0ZXMoe3JlY29yZCwgcmVzb3VyY2VDb25maWd9KVxuICAgICAgOiBudWxsXG5cbiAgICBmb3IgKGNvbnN0IHNjb3BlUGxhbkVudHJ5IG9mIHJlc291cmNlQ29uZmlnLnNjb3BlUGxhbikge1xuICAgICAgLyoqIEB0eXBlIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gKi9cbiAgICAgIGxldCByYXdWYWx1ZVxuXG4gICAgICBpZiAoY29tcHV0ZWRTY29wZUF0dHJpYnV0ZXMpIHtcbiAgICAgICAgcmF3VmFsdWUgPSBjb21wdXRlZFNjb3BlQXR0cmlidXRlc1tzY29wZVBsYW5FbnRyeS5zY29wZUF0dHJpYnV0ZV1cbiAgICAgIH0gZWxzZSBpZiAoc2NvcGVQbGFuRW50cnkucmVzb2x2ZXIpIHtcbiAgICAgICAgcmF3VmFsdWUgPSBhd2FpdCBzY29wZVBsYW5FbnRyeS5yZXNvbHZlcihyZWNvcmQpXG4gICAgICB9IGVsc2UgaWYgKHNjb3BlUGxhbkVudHJ5LnJlY29yZEF0dHJpYnV0ZSkge1xuICAgICAgICByYXdWYWx1ZSA9IHJlY29yZC5yZWFkQXR0cmlidXRlKHNjb3BlUGxhbkVudHJ5LnJlY29yZEF0dHJpYnV0ZSlcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJhd1ZhbHVlID0gc2NhbGFyTW9kZWxQcmltYXJ5S2V5VmFsdWUocmVjb3JkLmlkKCksIGBTeW5jIHNjb3BlIHB1Ymxpc2hpbmcgZm9yICR7cmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlfWApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gcmF3VmFsdWUgPT09IHVuZGVmaW5lZCB8fCByYXdWYWx1ZSA9PT0gbnVsbCA/IG51bGwgOiBTdHJpbmcocmF3VmFsdWUpXG5cbiAgICAgIGNvbHVtbnNbc2NvcGVQbGFuRW50cnkuY29sdW1uTmFtZV0gPSB2YWx1ZVxuICAgICAgcGFyYW1zW3Njb3BlUGxhbkVudHJ5LnNjb3BlQXR0cmlidXRlXSA9IHZhbHVlXG4gICAgfVxuXG4gICAgcmV0dXJuIHtjb2x1bW5zLCBwYXJhbXN9XG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgYW5kIHZhbGlkYXRlcyBvbmUgY29tcHV0ZWQgc2NvcGUtYXR0cmlidXRlcyBkZWNsYXJhdGlvbi4gVGhlXG4gICAqIHJlc29sdmVyIHJ1bnMgb25jZSBwZXIgcHVibGlzaGVkIG11dGF0aW9uIHdpdGggdGhlIGV4YWN0IGNvbm5lY3Rpb24gdGhhdFxuICAgKiBvd25zIHRoYXQgbXV0YXRpb247IGV2ZXJ5IGRlY2xhcmVkIHNjb3BlIHZhbHVlIGlzIHRoZW4gcmV1c2VkIGZvciByb3dcbiAgICogcGVyc2lzdGVuY2UgYW5kIGJyb2FkY2FzdCByb3V0aW5nIHNvIHRob3NlIHR3byBpZGVudGl0aWVzIGNhbm5vdCBkcmlmdC5cbiAgICogQHBhcmFtIHt7cmVjb3JkOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPiwgcmVzb3VyY2VDb25maWc6IGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlclJlc291cmNlQ29uZmlnfX0gYXJncyAtIFJlY29yZCBhbmQgcmVzb3VyY2UgY29uZmlndXJhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyIHwgbnVsbD4+fSBDb21wbGV0ZSBjb21wdXRlZCBzY29wZSB2YWx1ZXMuXG4gICAqL1xuICBhc3luYyByZXNvbHZlQ29tcHV0ZWRTY29wZUF0dHJpYnV0ZXMoe3JlY29yZCwgcmVzb3VyY2VDb25maWd9KSB7XG4gICAgY29uc3QgcmVzb2x2ZXIgPSByZXNvdXJjZUNvbmZpZy5zY29wZUF0dHJpYnV0ZXNSZXNvbHZlclxuXG4gICAgaWYgKCFyZXNvbHZlcikgdGhyb3cgbmV3IEVycm9yKGBObyBjb21wdXRlZCBzY29wZS1hdHRyaWJ1dGVzIHJlc29sdmVyIGNvbmZpZ3VyZWQgZm9yICR7cmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlfWApXG5cbiAgICBjb25zdCByZXNvbHZlZCA9IGF3YWl0IHJlc29sdmVyKHtcbiAgICAgIGNvbmZpZ3VyYXRpb246IHRoaXMuY29uZmlnLmNvbmZpZ3VyYXRpb24sXG4gICAgICBjb25uZWN0aW9uOiByZWNvcmQuY29ubmVjdGlvbigpLFxuICAgICAgcmVjb3JkXG4gICAgfSlcblxuICAgIGlmICghaXNQbGFpbk9iamVjdChyZXNvbHZlZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtyZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggc2NvcGVBdHRyaWJ1dGVzIHJlc29sdmVyIG11c3QgcmVzb2x2ZSB0byBhIHBsYWluIG9iamVjdGApXG4gICAgfVxuXG4gICAgY29uc3QgZGVjbGFyZWRBdHRyaWJ1dGVzID0gcmVzb3VyY2VDb25maWcuc2NvcGVQbGFuLm1hcCgoe3Njb3BlQXR0cmlidXRlfSkgPT4gc2NvcGVBdHRyaWJ1dGUpXG5cbiAgICBmb3IgKGNvbnN0IHNjb3BlQXR0cmlidXRlIG9mIE9iamVjdC5rZXlzKHJlc29sdmVkKSkge1xuICAgICAgaWYgKCFkZWNsYXJlZEF0dHJpYnV0ZXMuaW5jbHVkZXMoc2NvcGVBdHRyaWJ1dGUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtyZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggc2NvcGVBdHRyaWJ1dGVzIHJlc29sdmVyIHJldHVybmVkIHVua25vd24gc2NvcGUgYXR0cmlidXRlOiAke3Njb3BlQXR0cmlidXRlfSAodGhlIHN5bmMgbW9kZWwgZGVjbGFyZXM6ICR7ZGVjbGFyZWRBdHRyaWJ1dGVzLmpvaW4oXCIsIFwiKX0pYClcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IHNjb3BlQXR0cmlidXRlIG9mIGRlY2xhcmVkQXR0cmlidXRlcykge1xuICAgICAgaWYgKCFPYmplY3QuaGFzT3duKHJlc29sdmVkLCBzY29wZUF0dHJpYnV0ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3Jlc291cmNlQ29uZmlnLnJlc291cmNlVHlwZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzY29wZUF0dHJpYnV0ZXMgcmVzb2x2ZXIgbXVzdCByZXNvbHZlIHRoZSBkZWNsYXJlZCBzY29wZSBhdHRyaWJ1dGUgJHtzY29wZUF0dHJpYnV0ZX1gKVxuICAgICAgfVxuXG4gICAgICBjb25zdCB2YWx1ZSA9IHJlc29sdmVkW3Njb3BlQXR0cmlidXRlXVxuXG4gICAgICBpZiAodmFsdWUgIT09IG51bGwgJiYgdHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiICYmIHR5cGVvZiB2YWx1ZSAhPT0gXCJudW1iZXJcIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7cmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlfSBzdGF0aWMgc3luYyBwdWJsaXNoIHNjb3BlIGF0dHJpYnV0ZSAke3Njb3BlQXR0cmlidXRlfSBtdXN0IGJlIGEgc3RyaW5nLCBudW1iZXIsIG9yIG51bGxgKVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bWJlciB8IG51bGw+fSAqLyAocmVzb2x2ZWQpXG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIHRoZSBmcmFtZXdvcmsgc3luYyBjaGFubmVsIGVudHJ5IGZvciBvbmUgcHVibGlzaGVkIGNoYW5nZTogdGhlXG4gICAqIHNuYXBzaG90dGVkIHBheWxvYWQgcGx1cyB0aGUgcGVyc2lzdGVkIHN5bmMgcm93J3MgcHVibGljIGV4YWN0LXJvdyBtZXRhZGF0YVxuICAgKiAoaWQsIHNlcnZlciBzZXF1ZW5jZSwgdXBkYXRlZC1hdCwgYW5kIGRlY2xhcmVkIHNjb3BlLXBhcnRpdGlvbiBhdHRyaWJ1dGVzKS5cbiAgICogVXNlcyB0aGUgc3luYyBtb2RlbCdzIGdlbmVyYXRlZCB0eXBlZCBhY2Nlc3NvcnMgYW5kIGZvbGxvd3MgdGhlXG4gICAqIGNoYW5nZS1mZWVkIHNlcmlhbGl6ZXIncyBwdWJsaWMgZmllbGQgY29udmVudGlvbi5cbiAgICogQHBhcmFtIHt7ZGF0YTogUmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+LCByZXNvdXJjZUNvbmZpZzogaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyUmVzb3VyY2VDb25maWcsIHJlc291cmNlSWQ6IHN0cmluZywgc3luY1JvdzogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4sIHN5bmNUeXBlOiBzdHJpbmd9fSBhcmdzIC0gUHVibGlzaCBhcmdzLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSBCcm9hZGNhc3Qgc3luYyBlbnRyeS5cbiAgICovXG4gIHB1Ymxpc2hlZFN5bmNFbnRyeSh7ZGF0YSwgcmVzb3VyY2VDb25maWcsIHJlc291cmNlSWQsIHN5bmNSb3csIHN5bmNUeXBlfSkge1xuICAgIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSAqL1xuICAgIGNvbnN0IGVudHJ5ID0ge1xuICAgICAgZGF0YSxcbiAgICAgIGlkOiBzeW5jUm93LmlkKCksXG4gICAgICByZXNvdXJjZUlkLFxuICAgICAgcmVzb3VyY2VUeXBlOiByZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGUsXG4gICAgICBzZXJ2ZXJTZXF1ZW5jZTogc3luY1Jvdy5zZXJ2ZXJTZXF1ZW5jZSgpLFxuICAgICAgc3luY1R5cGUsXG4gICAgICB1cGRhdGVkQXQ6IGlzb0RhdGUoc3luY1Jvdy51cGRhdGVkQXQoKSlcbiAgICB9XG5cbiAgICBjb25zdCBzY29wZUF0dHJpYnV0ZXMgPSBkZWNsYXJlZFN5bmNTY29wZUF0dHJpYnV0ZXModGhpcy5jb25maWcuc3luY01vZGVsKVxuXG4gICAgZm9yIChjb25zdCBzY29wZUF0dHJpYnV0ZSBvZiBzY29wZUF0dHJpYnV0ZXMgfHwgW10pIHtcbiAgICAgIGNvbnN0IHNjb3BlQWNjZXNzb3IgPSBzeW5jUm93W3Njb3BlQXR0cmlidXRlXVxuXG4gICAgICBpZiAodHlwZW9mIHNjb3BlQWNjZXNzb3IgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFB1Ymxpc2hlZCBzeW5jIHJvdyBpcyBtaXNzaW5nIHRoZSBkZWNsYXJlZCBzY29wZSBhY2Nlc3NvciAke3Njb3BlQXR0cmlidXRlfSgpLmApXG4gICAgICB9XG5cbiAgICAgIGVudHJ5W3Njb3BlQXR0cmlidXRlXSA9IHNjb3BlQWNjZXNzb3IuY2FsbChzeW5jUm93KVxuICAgIH1cblxuICAgIHJldHVybiBlbnRyeVxuICB9XG5cbiAgLyoqXG4gICAqIFVwc2VydHMgdGhlIHB1Ymxpc2hlZCBzZXJ2ZXItb3JpZ2luIHN5bmMgcm93IGZvciBhIHJlc291cmNlIGlkZW50aXR5OlxuICAgKiBzZXJ2ZXItb3JpZ2luIHJvd3MgY2FycnkgYSBudWxsIGFjdG9yIGNvbHVtbiAobm8gZGV2aWNlIHRvIGVjaG8gdGhlXG4gICAqIGNoYW5nZSBiYWNrIHRvKSwgc28gcmVwZWF0ZWQgc2VydmVyIGNoYW5nZXMgdG8gb25lIGNvbXBsZXRlIHJlc291cmNlIGFuZFxuICAgKiBzY29wZSBpZGVudGl0eSByZXVzZSBhbmQgcmUtc2VxdWVuY2Ugb25lIGZlZWQgcm93LiBBIGRhdGFiYXNlIGFkdmlzb3J5XG4gICAqIGxvY2sgc2VyaWFsaXplcyByZWNvbmNpbGlhdGlvbiBwbHVzIHRoZSBzaGFyZWQgdXBzZXJ0IGJlY2F1c2UgdW5pcXVlXG4gICAqIGNvbnN0cmFpbnRzIGNvbnRhaW5pbmcgbnVsbGFibGUgYWN0b3Ivc2NvcGUgY29sdW1ucyBkbyBub3QgZW5mb3JjZSB0aGlzXG4gICAqIGlkZW50aXR5IHBvcnRhYmx5IGFjcm9zcyBzdXBwb3J0ZWQgZGF0YWJhc2VzLiBSZWNvbmNpbGlhdGlvbiByZXRhaW5zIHRoZVxuICAgKiByb3cgd2l0aCB0aGUgbmV3ZXN0IGZlZWQgc2VxdWVuY2UgKHRoZW4gbG93ZXN0IGlkIGZvciBhIGRldGVybWluaXN0aWMgdGllKVxuICAgKiBhbmQgcmVtb3ZlcyBvbGRlciBtYXRjaGluZyBzZXJ2ZXItb3JpZ2luIHJvd3MgYmVmb3JlIGFwcGx5aW5nIHRoZSBjdXJyZW50XG4gICAqIG11dGF0aW9uLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gYXR0cmlidXRlcyAtIFNuYXBzaG90dGVkIHN5bmMgcm93IGF0dHJpYnV0ZXMuXG4gICAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHN5bmNNb2RlbCAtIE9wZXJhdGlvbi1ib3VuZCBvciBzdGF0aWMgU3luYyBtb2RlbCBpbnRlcmZhY2UuXG4gICAqIEBwYXJhbSB7c3RyaW5nW119IHNjb3BlQ29sdW1uTmFtZXMgLSBQZXJzaXN0ZWQgc2NvcGUgY29sdW1ucyBwYXJ0aWNpcGF0aW5nIGluIHRoZSBjb21wbGV0ZSBpZGVudGl0eS5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSBVcHNlcnRlZCBzeW5jIHJvdy5cbiAgICovXG4gIGFzeW5jIHVwc2VydFB1Ymxpc2hlZFN5bmNSb3coYXR0cmlidXRlcywgc3luY01vZGVsID0gdGhpcy5jb25maWcuc3luY01vZGVsLCBzY29wZUNvbHVtbk5hbWVzID0gW10pIHtcbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gKi9cbiAgICBjb25zdCBpZGVudGl0eSA9IHtcbiAgICAgIFt0aGlzLmNvbmZpZy5hY3RvckZvcmVpZ25LZXlDb2x1bW5dOiBudWxsLFxuICAgICAgcmVzb3VyY2VfaWQ6IGF0dHJpYnV0ZXMucmVzb3VyY2VfaWQsXG4gICAgICByZXNvdXJjZV90eXBlOiBhdHRyaWJ1dGVzLnJlc291cmNlX3R5cGVcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGNvbHVtbk5hbWUgb2Ygc2NvcGVDb2x1bW5OYW1lcykge1xuICAgICAgaWYgKCFPYmplY3QuaGFzT3duKGF0dHJpYnV0ZXMsIGNvbHVtbk5hbWUpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUHVibGlzaGVkIHN5bmMgcm93IGlkZW50aXR5IGlzIG1pc3NpbmcgdGhlIHNjb3BlIGNvbHVtbiAke2NvbHVtbk5hbWV9YClcbiAgICAgIH1cblxuICAgICAgaWRlbnRpdHlbY29sdW1uTmFtZV0gPSBhdHRyaWJ1dGVzW2NvbHVtbk5hbWVdXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHRoaXMuY29uZmlnLnN5bmNNb2RlbC53aXRoQWR2aXNvcnlMb2NrKHN5bmNQdWJsaXNoZXJJZGVudGl0eUxvY2tOYW1lKGlkZW50aXR5KSwgYXN5bmMgKCkgPT4ge1xuICAgICAgY29uc3QgbWF0Y2hpbmdTeW5jcyA9IGF3YWl0IHN5bmNNb2RlbFxuICAgICAgICAud2hlcmUoaWRlbnRpdHkpXG4gICAgICAgIC50b0FycmF5KClcblxuICAgICAgbWF0Y2hpbmdTeW5jcy5zb3J0KGNvbXBhcmVQdWJsaXNoZWRTeW5jUm93c0J5UmVjZW5jeSlcblxuICAgICAgY29uc3QgW2V4aXN0aW5nU3luYywgLi4uZHVwbGljYXRlU3luY3NdID0gbWF0Y2hpbmdTeW5jc1xuXG4gICAgICBmb3IgKGNvbnN0IGR1cGxpY2F0ZVN5bmMgb2YgZHVwbGljYXRlU3luY3MpIHtcbiAgICAgICAgYXdhaXQgZHVwbGljYXRlU3luYy5kZXN0cm95KClcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIGF3YWl0IHVwc2VydFN5bmNSb3coe2F0dHJpYnV0ZXMsIGV4aXN0aW5nU3luYywgc3luY01vZGVsfSlcbiAgICB9LCB7ZGVkaWNhdGVkQ29ubmVjdGlvbjogdHJ1ZX0pXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYnJvYWRjYXN0ZXIgZGVsaXZlcmluZyBkZWNsYXJlZCBicm9hZGNhc3RzOiB0aGUgaW5qZWN0ZWQgb25lLFxuICAgKiBvciB0aGUgY29uZmlndXJhdGlvbidzIGNoYW5uZWwgYnJvYWRjYXN0IGF3YWl0ZWQgdGhyb3VnaCB0aGUgcGVuZGluZ1xuICAgKiBicm9hZGNhc3QgcXVldWUuXG4gICAqIEByZXR1cm5zIHtOb25OdWxsYWJsZTxpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJPcHRpb25zW1wiYnJvYWRjYXN0ZXJcIl0+fSBCcm9hZGNhc3QgZGVsaXZlcmVyLlxuICAgKi9cbiAgYnJvYWRjYXN0ZXIoKSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLmJyb2FkY2FzdGVyKSByZXR1cm4gdGhpcy5jb25maWcuYnJvYWRjYXN0ZXJcblxuICAgIHJldHVybiBhc3luYyAoe2JvZHksIGNoYW5uZWwsIHBhcmFtc30pID0+IHtcbiAgICAgIHRoaXMuY29uZmlnLmNvbmZpZ3VyYXRpb24uYnJvYWRjYXN0VG9DaGFubmVsKGNoYW5uZWwsIHBhcmFtcywgYm9keSlcbiAgICAgIGF3YWl0IHRoaXMuY29uZmlnLmNvbmZpZ3VyYXRpb24uYXdhaXRQZW5kaW5nQnJvYWRjYXN0cygpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcG9ydHMgYSBwb3N0LWNvbW1pdCBwdWJsaXNoIGZhaWx1cmUuIFRoZSB0cmFuc2FjdGlvbiBoYXMgYWxyZWFkeVxuICAgKiBjb21taXR0ZWQgd2hlbiBhZnRlckNvbW1pdCBjYWxsYmFja3MgcnVuLCBzbyByZXRocm93aW5nIGhlcmUgd291bGQgcG9pc29uXG4gICAqIHRoZSBkcml2ZXIncyBhd2FpdGVkIGFmdGVyQ29tbWl0IGNoYWluIChicmVha2luZyB1bnJlbGF0ZWQgY2FsbGJhY2tzKSAtXG4gICAqIGluc3RlYWQgdGhlIGZhaWx1cmUgZ29lcyB0byB0aGUgY29uZmlndXJlZCBvbkVycm9yIGhvb2ssIG9yIGlzIGVtaXR0ZWQgb25cbiAgICogdGhlIGNvbmZpZ3VyYXRpb24ncyBmcmFtZXdvcmstZXJyb3IvYWxsLWVycm9yIGNoYW5uZWxzIChzbyBwcm9kdWN0aW9uIGJ1Z1xuICAgKiByZXBvcnRpbmcgdmlhIGBjb25maWd1cmF0aW9uLmdldEVycm9yRXZlbnRzKClgIHNlZXMgYSBicm9rZW4gcHVibGlzaFxuICAgKiBwYXRoKSBhbmQgbG9nZ2VkIGxvdWRseSB0aHJvdWdoIHRoZSBwdWJsaXNoZXIncyBsb2dnZXIgd2hlbiBub25lIGlzXG4gICAqIGNvbmZpZ3VyZWQuXG4gICAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gUG9zdC1jb21taXQgcHVibGlzaCBmYWlsdXJlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIHJlcG9ydEFmdGVyQ29tbWl0RXJyb3IoZXJyb3IpIHtcbiAgICBpZiAodGhpcy5jb25maWcub25FcnJvcikge1xuICAgICAgdGhpcy5jb25maWcub25FcnJvcihlcnJvcilcblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JFdmVudHMgPSB0aGlzLmNvbmZpZy5jb25maWd1cmF0aW9uLmdldEVycm9yRXZlbnRzKClcbiAgICBjb25zdCBwYXlsb2FkID0ge2NvbnRleHQ6IHtzdGFnZTogXCJzeW5jLXB1Ymxpc2gtYWZ0ZXItY29tbWl0XCJ9LCBlcnJvcn1cblxuICAgIGVycm9yRXZlbnRzLmVtaXQoXCJmcmFtZXdvcmstZXJyb3JcIiwgcGF5bG9hZClcbiAgICBlcnJvckV2ZW50cy5lbWl0KFwiYWxsLWVycm9yXCIsIHsuLi5wYXlsb2FkLCBlcnJvclR5cGU6IFwiZnJhbWV3b3JrLWVycm9yXCJ9KVxuXG4gICAgYXdhaXQgdGhpcy5sb2dnZXIoKS5lcnJvcihcIlN5bmNQdWJsaXNoZXIgZmFpbGVkIHRvIHB1Ymxpc2ggYSBzZXJ2ZXItc2lkZSBzeW5jIGNoYW5nZSBhZnRlciBjb21taXRcIiwgZXJyb3IpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbGF6aWx5IGJ1aWx0IHB1Ymxpc2hlciBsb2dnZXIuXG4gICAqIEByZXR1cm5zIHtMb2dnZXJ9IFB1Ymxpc2hlciBsb2dnZXIuXG4gICAqL1xuICBsb2dnZXIoKSB7XG4gICAgdGhpcy5fbG9nZ2VyIHx8PSBuZXcgTG9nZ2VyKFwiU3luY1B1Ymxpc2hlclwiLCB7Y29uZmlndXJhdGlvbjogdGhpcy5jb25maWcuY29uZmlndXJhdGlvbn0pXG5cbiAgICByZXR1cm4gdGhpcy5fbG9nZ2VyXG4gIH1cbn1cblxuLyoqXG4gKiBSZXR1cm5zIGEgZGV0ZXJtaW5pc3RpYywgTXlTUUwtc2FmZSBhZHZpc29yeS1sb2NrIG5hbWUgZm9yIG9uZSBjb21wbGV0ZVxuICogc2VydmVyLW9yaWdpbiBwdWJsaXNoZXIgaWRlbnRpdHkuIFN0YWJsZSBKU09OIHByZXNlcnZlcyBudWxsIGFjdG9yL3Njb3BlXG4gKiBjb21wb25lbnRzIGRpc3RpbmN0bHkgZnJvbSBzdHJpbmdzLCBhbmQgdGhlIHRydW5jYXRlZCBTSEEtMjU2IGRpZ2VzdCBrZWVwc1xuICogdGhlIGZpbmFsIG5hbWUgYmVsb3cgTXlTUUwvTWFyaWFEQidzIDY0LWNoYXJhY3RlciBgR0VUX0xPQ0tgIGxpbWl0LlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59IGlkZW50aXR5IC0gQ29tcGxldGUgc3luYy1yb3cgaWRlbnRpdHkgaW4gY29sdW1uIGZvcm0uXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBBZHZpc29yeS1sb2NrIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIHN5bmNQdWJsaXNoZXJJZGVudGl0eUxvY2tOYW1lKGlkZW50aXR5KSB7XG4gIGNvbnN0IGhhc2ggPSBzaGEyNTZIZXgoc3RhYmxlSnNvblN0cmluZ2lmeShpZGVudGl0eSkpLnNsaWNlKDAsIDMyKVxuXG4gIHJldHVybiBgdnNwOiR7aGFzaH1gXG59XG5cbi8qKlxuICogT3JkZXJzIG1hdGNoaW5nIHB1Ymxpc2hlZCByb3dzIGJ5IHRoZSBmZWVkJ3MgcHVibGljIHJlY2VuY3kgY29udHJhY3Qgc29cbiAqIGxlZ2FjeSBkdXBsaWNhdGVzIGhhdmUgb25lIGRldGVybWluaXN0aWMgc3Vydml2b3IuIFNlcnZlciBzZXF1ZW5jZXMgYXJlXG4gKiBwb3NpdGl2ZSBhbmQgbW9ub3RvbmljOyBhIGxlZ2FjeSBudWxsIHNlcXVlbmNlIGlzIG9sZGVyIHRoYW4gYW55IGFzc2lnbmVkXG4gKiBzZXF1ZW5jZSwgYW5kIHRoZSBpbW11dGFibGUgcm93IGlkIGJyZWFrcyBvdGhlcndpc2UtZXF1YWwgdGllcy5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IGxlZnQgLSBGaXJzdCBtYXRjaGluZyBzeW5jIHJvdy5cbiAqIEBwYXJhbSB7UmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59IHJpZ2h0IC0gU2Vjb25kIG1hdGNoaW5nIHN5bmMgcm93LlxuICogQHJldHVybnMge251bWJlcn0gU29ydCBjb21wYXJpc29uIHdpdGggdGhlIGNhbm9uaWNhbCBzdXJ2aXZvciBmaXJzdC5cbiAqL1xuZnVuY3Rpb24gY29tcGFyZVB1Ymxpc2hlZFN5bmNSb3dzQnlSZWNlbmN5KGxlZnQsIHJpZ2h0KSB7XG4gIGNvbnN0IGxlZnRTZXF1ZW5jZSA9IGxlZnQuc2VydmVyU2VxdWVuY2UoKVxuICBjb25zdCByaWdodFNlcXVlbmNlID0gcmlnaHQuc2VydmVyU2VxdWVuY2UoKVxuXG4gIGlmIChsZWZ0U2VxdWVuY2UgPT09IG51bGwgJiYgcmlnaHRTZXF1ZW5jZSAhPT0gbnVsbCkgcmV0dXJuIDFcbiAgaWYgKGxlZnRTZXF1ZW5jZSAhPT0gbnVsbCAmJiByaWdodFNlcXVlbmNlID09PSBudWxsKSByZXR1cm4gLTFcbiAgaWYgKGxlZnRTZXF1ZW5jZSAhPT0gcmlnaHRTZXF1ZW5jZSkgcmV0dXJuIHJpZ2h0U2VxdWVuY2UgLSBsZWZ0U2VxdWVuY2VcblxuICByZXR1cm4gbGVmdC5pZCgpLmxvY2FsZUNvbXBhcmUocmlnaHQuaWQoKSlcbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhIG1vZGVsIGNsYXNzJ3MgYWN0aXZlIHB1Ymxpc2ggZGVjbGFyYXRpb24gZnJvbSBgc3RhdGljIHN5bmNgLlxuICogT3B0ZWQtb3V0IChgcHVibGlzaDogZmFsc2VgKSBhbmQgdW5kZWNsYXJlZCBtb2RlbHMgcmVzb2x2ZSB0byBudWxsOyBldmVyeVxuICogb3RoZXIgZGVjbGFyZWQgdmFsdWUgZmxvd3MgaW50byBsb3VkIGRlY2xhcmF0aW9uIHZhbGlkYXRpb24uXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBtb2RlbENsYXNzIC0gUmVnaXN0ZXJlZCBtb2RlbCBjbGFzcy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoRGVjbGFyYXRpb24gfCBudWxsfSBBY3RpdmUgcHVibGlzaCBkZWNsYXJhdGlvbiwgb3IgbnVsbC5cbiAqL1xuZnVuY3Rpb24gcHVibGlzaERlY2xhcmF0aW9uRm9yKG1vZGVsQ2xhc3MpIHtcbiAgY29uc3QgZGVjbGFyYXRpb24gPSBtb2RlbENsYXNzLnN5bmNcblxuICBpZiAoIWRlY2xhcmF0aW9uIHx8IHR5cGVvZiBkZWNsYXJhdGlvbiAhPT0gXCJvYmplY3RcIiB8fCBkZWNsYXJhdGlvbi5wdWJsaXNoID09PSB1bmRlZmluZWQgfHwgZGVjbGFyYXRpb24ucHVibGlzaCA9PT0gZmFsc2UpIHJldHVybiBudWxsXG5cbiAgcmV0dXJuIGRlY2xhcmF0aW9uLnB1Ymxpc2hcbn1cblxuLyoqXG4gKiBCdWlsZHMgb25lIHB1Ymxpc2hlZCByZXNvdXJjZSBjb25maWcgZnJvbSBhIG1vZGVsJ3MgYHN0YXRpYyBzeW5jYCBwdWJsaXNoXG4gKiBkZWNsYXJhdGlvbi4gYHB1Ymxpc2g6IHRydWVgIG9wdHMgaW4gd2l0aCBhbGwgZGVmYXVsdHMgKGF0dHJpYnV0ZSBwYXlsb2FkLFxuICogZGVyaXZlZCBzY29wZSBwYXJ0aXRpb24sIGNyZWF0ZWQvdXBkYXRlZCBvcGVyYXRpb25zKS5cbiAqIEBwYXJhbSB7e21vZGVsQ2xhc3M6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+LCBwdWJsaXNoOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoRGVjbGFyYXRpb24gfCBudWxsLCBzY29wZUF0dHJpYnV0ZXM6IHN0cmluZ1tdIHwgbnVsbCwgc3luY01vZGVsOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn19IGFyZ3MgLSBEZWNsYXJhdGlvbiBhcmdzIHBsdXMgdGhlIHN5bmMgbW9kZWwncyBkZWNsYXJlZCBzY29wZSBhdHRyaWJ1dGVzLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlclJlc291cmNlQ29uZmlnfSBEZXJpdmVkIHJlc291cmNlIGNvbmZpZy5cbiAqL1xuZnVuY3Rpb24gcmVzb3VyY2VDb25maWdGcm9tUHVibGlzaERlY2xhcmF0aW9uKHttb2RlbENsYXNzLCBwdWJsaXNoLCBzY29wZUF0dHJpYnV0ZXM6IHN5bmNTY29wZUF0dHJpYnV0ZXMsIHN5bmNNb2RlbH0pIHtcbiAgY29uc3QgbW9kZWxOYW1lID0gbW9kZWxDbGFzcy5nZXRNb2RlbE5hbWUoKVxuICBjb25zdCBub3JtYWxpemVkUHVibGlzaCA9IHB1Ymxpc2ggPT09IHRydWUgPyB7fSA6IHB1Ymxpc2hcblxuICBpZiAoIW5vcm1hbGl6ZWRQdWJsaXNoIHx8IHR5cGVvZiBub3JtYWxpemVkUHVibGlzaCAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KG5vcm1hbGl6ZWRQdWJsaXNoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggbXVzdCBiZSB0cnVlLCBmYWxzZSBvciBhIHB1Ymxpc2ggZGVjbGFyYXRpb24gb2JqZWN0LCBnb3Q6ICR7U3RyaW5nKHB1Ymxpc2gpfWApXG4gIH1cblxuICBjb25zdCB7YnJvYWRjYXN0cywgZXZlbnRJZCwgb3BlcmF0aW9ucywgcmVzb3VyY2VUeXBlLCBzY29wZUF0dHJpYnV0ZXMsIHNlcmlhbGl6ZSwgLi4ucmVzdERlY2xhcmF0aW9ufSA9IG5vcm1hbGl6ZWRQdWJsaXNoXG4gIGNvbnN0IHVua25vd25LZXlzID0gT2JqZWN0LmtleXMocmVzdERlY2xhcmF0aW9uKVxuXG4gIGlmICh1bmtub3duS2V5cy5sZW5ndGggPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCByZWNlaXZlZCB1bmtub3duIGtleXM6ICR7dW5rbm93bktleXMuam9pbihcIiwgXCIpfSAoc3VwcG9ydGVkOiBicm9hZGNhc3RzLCBldmVudElkIChkZXByZWNhdGVkKSwgb3BlcmF0aW9ucywgcmVzb3VyY2VUeXBlLCBzY29wZUF0dHJpYnV0ZXMsIHNlcmlhbGl6ZSlgKVxuICB9XG4gIGlmIChzZXJpYWxpemUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc2VyaWFsaXplICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIHNlcmlhbGl6ZSBtdXN0IGJlIGEgZnVuY3Rpb24gYnVpbGRpbmcgdGhlIHB1Ymxpc2hlZCBwYXlsb2FkLCBnb3Q6ICR7U3RyaW5nKHNlcmlhbGl6ZSl9YClcbiAgfVxuICBpZiAob3BlcmF0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wZXJhdGlvbnMpIHx8IG9wZXJhdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIG9wZXJhdGlvbnMgbXVzdCBiZSBhIG5vbi1lbXB0eSBhcnJheSBvZiBjcmVhdGUvdXBkYXRlL2Rlc3Ryb3lgKVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIG9wZXJhdGlvbnMpIHtcbiAgICAgIGlmICghKG9wZXJhdGlvbiBpbiBQVUJMSVNIRURfQ0FMTEJBQ0tfTkFNRVMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggb3BlcmF0aW9ucyBtdXN0IGJlIGNyZWF0ZS91cGRhdGUvZGVzdHJveSwgZ290OiAke1N0cmluZyhvcGVyYXRpb24pfWApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc2NvcGVQbGFuID0gc2NvcGVQbGFuRm9yKHtldmVudElkLCBtb2RlbENsYXNzLCBtb2RlbE5hbWUsIHNjb3BlQXR0cmlidXRlcywgc3luY01vZGVsLCBzeW5jU2NvcGVBdHRyaWJ1dGVzfSlcblxuICByZXR1cm4ge1xuICAgIGJyb2FkY2FzdHMsXG4gICAgbW9kZWxDbGFzcyxcbiAgICBvcGVyYXRpb25zOiBvcGVyYXRpb25zID09PSB1bmRlZmluZWQgPyBERUZBVUxUX1BVQkxJU0hFRF9PUEVSQVRJT05TIDogb3BlcmF0aW9ucyxcbiAgICByZXNvdXJjZVR5cGU6IHJlc291cmNlVHlwZSA9PT0gdW5kZWZpbmVkID8gbW9kZWxOYW1lIDogcmVzb3VyY2VUeXBlLFxuICAgIHNjb3BlQXR0cmlidXRlc1Jlc29sdmVyOiB0eXBlb2Ygc2NvcGVBdHRyaWJ1dGVzID09PSBcImZ1bmN0aW9uXCIgPyBzY29wZUF0dHJpYnV0ZXMgOiB1bmRlZmluZWQsXG4gICAgc2NvcGVQbGFuLFxuICAgIHNlcmlhbGl6ZTogc2VyaWFsaXplID09PSB1bmRlZmluZWQgPyBkZWZhdWx0U2VyaWFsaXplZEF0dHJpYnV0ZXMgOiBzZXJpYWxpemVcbiAgfVxufVxuXG4vKipcbiAqIERlcml2ZXMgdGhlIHNjb3BlIHBsYW4gcGFydGl0aW9uaW5nIGEgcHVibGlzaGVkIG1vZGVsJ3MgY2hhbmdlczogb25lIGVudHJ5XG4gKiBwZXIgc2NvcGUgYXR0cmlidXRlIGRlY2xhcmVkIG9uIHRoZSBzeW5jIG1vZGVsIChgc3RhdGljXG4gKiBzeW5jU2NvcGVBdHRyaWJ1dGVzYCksIGVhY2ggcmVhZGluZyB0aGUgcmVjb3JkIGF0dHJpYnV0ZSBuYW1lZCBsaWtlIHRoZVxuICogc2NvcGUgYXR0cmlidXRlIChvdmVycmlkYWJsZSB0aHJvdWdoIHRoZSBkZWNsYXJhdGlvbidzIGBzY29wZUF0dHJpYnV0ZXNgXG4gKiBuYW1lIG1hcCksIG9yIHRoZSByZWNvcmQncyBvd24gaWQgd2hlbiB0aGUgbW9kZWwgaGFzIG5vIHN1Y2ggYXR0cmlidXRlXG4gKiAoc2NvcGUtcm9vdCBtb2RlbHMpLiBUaGUgZGVwcmVjYXRlZCBgZXZlbnRJZGAgZGVjbGFyYXRpb24gZm9ybXMgbWFwIHRvIGFcbiAqIGZpeGVkIGBldmVudElkYC9gZXZlbnRfaWRgIHBsYW4gZm9yIDEuMC41MDMgY29tcGF0aWJpbGl0eS5cbiAqIEBwYXJhbSB7e2V2ZW50SWQ6IGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hEZWNsYXJhdGlvbkNvbmZpZ1tcImV2ZW50SWRcIl0sIG1vZGVsQ2xhc3M6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+LCBtb2RlbE5hbWU6IHN0cmluZywgc2NvcGVBdHRyaWJ1dGVzOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoRGVjbGFyYXRpb25Db25maWdbXCJzY29wZUF0dHJpYnV0ZXNcIl0sIHN5bmNNb2RlbDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4sIHN5bmNTY29wZUF0dHJpYnV0ZXM6IHN0cmluZ1tdIHwgbnVsbH19IGFyZ3MgLSBEZWNsYXJhdGlvbiBhbmQgc3luYy1tb2RlbCBzY29wZSBhcmdzLlxuICogQHJldHVybnMge0FycmF5PGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlclNjb3BlUGxhbkVudHJ5Pn0gRGVyaXZlZCBzY29wZSBwbGFuLlxuICovXG5mdW5jdGlvbiBzY29wZVBsYW5Gb3Ioe2V2ZW50SWQsIG1vZGVsQ2xhc3MsIG1vZGVsTmFtZSwgc2NvcGVBdHRyaWJ1dGVzLCBzeW5jTW9kZWwsIHN5bmNTY29wZUF0dHJpYnV0ZXN9KSB7XG4gIGNvbnN0IGF0dHJpYnV0ZU5hbWVzID0gT2JqZWN0LnZhbHVlcyhtb2RlbENsYXNzLmdldENvbHVtbk5hbWVUb0F0dHJpYnV0ZU5hbWVNYXAoKSlcblxuICBpZiAoZXZlbnRJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHNjb3BlQXR0cmlidXRlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIGNhbid0IGRlY2xhcmUgYm90aCBzY29wZUF0dHJpYnV0ZXMgYW5kIHRoZSBkZXByZWNhdGVkIGV2ZW50SWQgZm9ybWApXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZXZlbnRJZCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICByZXR1cm4gW3tjb2x1bW5OYW1lOiBcImV2ZW50X2lkXCIsIHJlY29yZEF0dHJpYnV0ZTogbnVsbCwgcmVzb2x2ZXI6IGV2ZW50SWQsIHNjb3BlQXR0cmlidXRlOiBcImV2ZW50SWRcIn1dXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZXZlbnRJZCAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBldmVudElkIG11c3QgYmUgYW4gYXR0cmlidXRlLW5hbWUgc3RyaW5nIChvciBhIGRlcHJlY2F0ZWQgcmVzb2x2ZXIgZnVuY3Rpb24pLCBnb3Q6ICR7U3RyaW5nKGV2ZW50SWQpfWApXG4gICAgfVxuICAgIGlmICghYXR0cmlidXRlTmFtZXMuaW5jbHVkZXMoZXZlbnRJZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggZXZlbnRJZCBhdHRyaWJ1dGUgZG9lc24ndCBleGlzdCBvbiB0aGUgbW9kZWw6ICR7ZXZlbnRJZH1gKVxuICAgIH1cblxuICAgIHJldHVybiBbe2NvbHVtbk5hbWU6IFwiZXZlbnRfaWRcIiwgcmVjb3JkQXR0cmlidXRlOiBldmVudElkLCByZXNvbHZlcjogdW5kZWZpbmVkLCBzY29wZUF0dHJpYnV0ZTogXCJldmVudElkXCJ9XVxuICB9XG5cbiAgaWYgKHNjb3BlQXR0cmlidXRlcyAhPT0gdW5kZWZpbmVkICYmICFzeW5jU2NvcGVBdHRyaWJ1dGVzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBkZWNsYXJlcyBzY29wZUF0dHJpYnV0ZXMgYnV0IHRoZSBzeW5jIG1vZGVsIGRlY2xhcmVzIG5vIHN0YXRpYyBzeW5jU2NvcGVBdHRyaWJ1dGVzYClcbiAgfVxuXG4gIGlmICghc3luY1Njb3BlQXR0cmlidXRlcykgcmV0dXJuIFtdXG5cbiAgaWYgKHR5cGVvZiBzY29wZUF0dHJpYnV0ZXMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIHJldHVybiBzeW5jU2NvcGVBdHRyaWJ1dGVzLm1hcCgoc2NvcGVBdHRyaWJ1dGUpID0+ICh7XG4gICAgICBjb2x1bW5OYW1lOiBzeW5jU2NvcGVDb2x1bW5OYW1lKHtzY29wZUF0dHJpYnV0ZSwgc3luY01vZGVsfSksXG4gICAgICByZWNvcmRBdHRyaWJ1dGU6IG51bGwsXG4gICAgICByZXNvbHZlcjogdW5kZWZpbmVkLFxuICAgICAgc2NvcGVBdHRyaWJ1dGVcbiAgICB9KSlcbiAgfVxuXG4gIGlmIChzY29wZUF0dHJpYnV0ZXMgIT09IHVuZGVmaW5lZCAmJiAodHlwZW9mIHNjb3BlQXR0cmlidXRlcyAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHNjb3BlQXR0cmlidXRlcykpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzY29wZUF0dHJpYnV0ZXMgbXVzdCBiZSBhbiBvYmplY3QgbWFwcGluZyBzY29wZSBhdHRyaWJ1dGVzIHRvIHJlY29yZCBhdHRyaWJ1dGUgbmFtZXMsIGdvdDogJHtTdHJpbmcoc2NvcGVBdHRyaWJ1dGVzKX1gKVxuICB9XG5cbiAgZm9yIChjb25zdCBzY29wZUF0dHJpYnV0ZSBvZiBPYmplY3Qua2V5cyhzY29wZUF0dHJpYnV0ZXMgfHwge30pKSB7XG4gICAgaWYgKCFzeW5jU2NvcGVBdHRyaWJ1dGVzLmluY2x1ZGVzKHNjb3BlQXR0cmlidXRlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzY29wZUF0dHJpYnV0ZXMgcmVjZWl2ZWQgdW5rbm93biBzY29wZSBhdHRyaWJ1dGU6ICR7c2NvcGVBdHRyaWJ1dGV9ICh0aGUgc3luYyBtb2RlbCBkZWNsYXJlczogJHtzeW5jU2NvcGVBdHRyaWJ1dGVzLmpvaW4oXCIsIFwiKX0pYClcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3luY1Njb3BlQXR0cmlidXRlcy5tYXAoKHNjb3BlQXR0cmlidXRlKSA9PiB7XG4gICAgY29uc3QgZGVjbGFyZWRSZWNvcmRBdHRyaWJ1dGUgPSBzY29wZUF0dHJpYnV0ZXM/LltzY29wZUF0dHJpYnV0ZV1cblxuICAgIGlmIChkZWNsYXJlZFJlY29yZEF0dHJpYnV0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIGRlY2xhcmVkUmVjb3JkQXR0cmlidXRlICE9PSBcInN0cmluZ1wiIHx8ICFhdHRyaWJ1dGVOYW1lcy5pbmNsdWRlcyhkZWNsYXJlZFJlY29yZEF0dHJpYnV0ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzY29wZUF0dHJpYnV0ZXMuJHtzY29wZUF0dHJpYnV0ZX0gbXVzdCBuYW1lIGFuIGV4aXN0aW5nIHJlY29yZCBhdHRyaWJ1dGUsIGdvdDogJHtTdHJpbmcoZGVjbGFyZWRSZWNvcmRBdHRyaWJ1dGUpfWApXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7Y29sdW1uTmFtZTogc3luY1Njb3BlQ29sdW1uTmFtZSh7c2NvcGVBdHRyaWJ1dGUsIHN5bmNNb2RlbH0pLCByZWNvcmRBdHRyaWJ1dGU6IGRlY2xhcmVkUmVjb3JkQXR0cmlidXRlLCByZXNvbHZlcjogdW5kZWZpbmVkLCBzY29wZUF0dHJpYnV0ZX1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29sdW1uTmFtZTogc3luY1Njb3BlQ29sdW1uTmFtZSh7c2NvcGVBdHRyaWJ1dGUsIHN5bmNNb2RlbH0pLFxuICAgICAgcmVjb3JkQXR0cmlidXRlOiBhdHRyaWJ1dGVOYW1lcy5pbmNsdWRlcyhzY29wZUF0dHJpYnV0ZSkgPyBzY29wZUF0dHJpYnV0ZSA6IG51bGwsXG4gICAgICByZXNvbHZlcjogdW5kZWZpbmVkLFxuICAgICAgc2NvcGVBdHRyaWJ1dGVcbiAgICB9XG4gIH0pXG59XG5cbi8qKlxuICogQ2hlY2tzIHRoYXQgYSBjb21wdXRlZCBkZWNsYXJhdGlvbiByZXR1cm5lZCBhbiBvcmRpbmFyeSBrZXkvdmFsdWUgb2JqZWN0LlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIFJlc29sdmVyIHJlc3VsdC5cbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gV2hldGhlciB0aGUgdmFsdWUgaXMgYSBwbGFpbiBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiBmYWxzZVxuXG4gIGNvbnN0IHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSlcblxuICByZXR1cm4gcHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlIHx8IHByb3RvdHlwZSA9PT0gbnVsbFxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBzeW5jLXJvdyBjb2x1bW4gcGVyc2lzdGluZyBhIGRlY2xhcmVkIHNjb3BlIGF0dHJpYnV0ZS5cbiAqIEBwYXJhbSB7e3Njb3BlQXR0cmlidXRlOiBzdHJpbmcsIHN5bmNNb2RlbDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59fSBhcmdzIC0gU2NvcGUgYXR0cmlidXRlIGFuZCBzeW5jIG1vZGVsLlxuICogQHJldHVybnMge3N0cmluZ30gU3luYy1yb3cgY29sdW1uIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIHN5bmNTY29wZUNvbHVtbk5hbWUoe3Njb3BlQXR0cmlidXRlLCBzeW5jTW9kZWx9KSB7XG4gIGNvbnN0IGNvbHVtbk5hbWUgPSBzeW5jTW9kZWwuZ2V0QXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcCgpW3Njb3BlQXR0cmlidXRlXVxuXG4gIGlmICghY29sdW1uTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtzeW5jTW9kZWwubmFtZX0gZGVjbGFyZXMgdGhlIHN5bmMgc2NvcGUgYXR0cmlidXRlICR7c2NvcGVBdHRyaWJ1dGV9IGJ1dCBoYXMgbm8gbWF0Y2hpbmcgY29sdW1uIGZvciBpdGApXG4gIH1cblxuICByZXR1cm4gY29sdW1uTmFtZVxufVxuXG4vKipcbiAqIERlZmF1bHQgcHVibGlzaCBzZXJpYWxpemVyOiB0aGUgcmVjb3JkJ3MgYXR0cmlidXRlcyB3aXRoIERhdGUgdmFsdWVzXG4gKiBzZXJpYWxpemVkIHRvIElTTyBzdHJpbmdzLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gcmVjb3JkIC0gTXV0YXRlZCBzZXJ2ZXIgbW9kZWwgcmVjb3JkLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gU2VyaWFsaXplZCBhdHRyaWJ1dGVzIHBheWxvYWQuXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRTZXJpYWxpemVkQXR0cmlidXRlcyhyZWNvcmQpIHtcbiAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovXG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSB7Li4ucmVjb3JkLmF0dHJpYnV0ZXMoKX1cblxuICBmb3IgKGNvbnN0IFthdHRyaWJ1dGVOYW1lLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYXR0cmlidXRlcykpIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSBhdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdID0gdmFsdWUudG9JU09TdHJpbmcoKVxuICB9XG5cbiAgcmV0dXJuIGF0dHJpYnV0ZXNcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIGRhdGUtbGlrZSB2YWx1ZSB0byBhbiBJU08gc3RyaW5nLCBtYXRjaGluZyB0aGUgY2hhbmdlLWZlZWRcbiAqIHNlcmlhbGl6ZXIncyBjb252ZW50aW9uIGZvciB0aGUgc3luYyBlbnRyeSdzIHB1YmxpYyB1cGRhdGVkLWF0IG1ldGFkYXRhLlxuICogQHBhcmFtIHtEYXRlIHwgbnVsbH0gdmFsdWUgLSBQZXJzaXN0ZWQgdXBkYXRlZC1hdCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IElTTyBkYXRlLlxuICogQHRocm93cyB7RXJyb3J9IFdoZW4gdGhlIHBlcnNpc3RlZCByb3cgaGFzIG5vIHZhbGlkIHVwZGF0ZWQtYXQgdGltZXN0YW1wLlxuICovXG5mdW5jdGlvbiBpc29EYXRlKHZhbHVlKSB7XG4gIGlmICghKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgfHwgTnVtYmVyLmlzTmFOKHZhbHVlLmdldFRpbWUoKSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJQdWJsaXNoZWQgc3luYyByb3cgbXVzdCBoYXZlIGEgdmFsaWQgdXBkYXRlZEF0IHRpbWVzdGFtcC5cIilcbiAgfVxuXG4gIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpXG59XG4iXX0=
@@ -49,9 +49,12 @@ export default class SyncRealtimeBridge {
49
49
  * an active subscription is kept as-is and a concurrent subscribe awaits the
50
50
  * in-flight attempt. Call `unsubscribe()` first to change the context.
51
51
  * @param {ReturnType<typeof JSON.parse>} [context] - App context passed to the deprecated `sync.client.realtime.channels` callback (runtime scope values).
52
+ * @param {{signal?: AbortSignal}} [options] - Subscription lifecycle options.
52
53
  * @returns {Promise<void>}
53
54
  */
54
- subscribe(context?: ReturnType<typeof JSON.parse>): Promise<void>;
55
+ subscribe(context?: ReturnType<typeof JSON.parse>, { signal }?: {
56
+ signal?: AbortSignal;
57
+ }): Promise<void>;
55
58
  /**
56
59
  * Connects the websocket client, subscribes every derived channel, and waits
57
60
  * for each subscription's server acknowledgement before the gap-closing pull,
@@ -60,9 +63,10 @@ export default class SyncRealtimeBridge {
60
63
  * is live; an unsubscribe arriving during any await marks this attempt stale
61
64
  * and it tears its own resources down instead of resubscribing.
62
65
  * @param {ReturnType<typeof JSON.parse>} context - App context passed to the channels callback.
66
+ * @param {AbortSignal | undefined} signal - Subscription lifecycle signal.
63
67
  * @returns {Promise<void>}
64
68
  */
65
- _subscribe(context: ReturnType<typeof JSON.parse>): Promise<void>;
69
+ _subscribe(context: ReturnType<typeof JSON.parse>, signal: AbortSignal | undefined): Promise<void>;
66
70
  /**
67
71
  * Closes every channel subscription (idempotent). The websocket is
68
72
  * disconnected only when the bridge owns it (deprecated per-cycle
@@ -137,11 +141,12 @@ export default class SyncRealtimeBridge {
137
141
  /**
138
142
  * Chains one pushed message onto the serialized apply queue so changes apply
139
143
  * in arrival order; failures go to the sync client's error reporting.
140
- * @param {{body: ReturnType<typeof JSON.parse>, resourceType: string | null}} args - Message args.
144
+ * @param {{body: ReturnType<typeof JSON.parse>, generation?: number, resourceType: string | null}} args - Message args.
141
145
  * @returns {void}
142
146
  */
143
- enqueueApply({ body, resourceType }: {
147
+ enqueueApply({ body, generation, resourceType }: {
144
148
  body: ReturnType<typeof JSON.parse>;
149
+ generation?: number;
145
150
  resourceType: string | null;
146
151
  }): void;
147
152
  /**
@@ -159,8 +164,9 @@ export default class SyncRealtimeBridge {
159
164
  * Schedules a coalesced background pull closing offline gaps after
160
165
  * (re)subscription readiness. Resumes arriving while a pull is already
161
166
  * scheduled or in flight coalesce into that pull instead of stacking.
167
+ * @param {number} [generation] - Subscription generation owning the resume/readiness callback.
162
168
  * @returns {void}
163
169
  */
164
- schedulePull(): void;
170
+ schedulePull(generation?: number): void;
165
171
  }
166
172
  //# sourceMappingURL=sync-realtime-bridge.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"sync-realtime-bridge.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-realtime-bridge.js"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"sync-realtime-bridge.d.ts","sourceRoot":"","sources":["../../../src/sync/sync-realtime-bridge.js"],"names":[],"mappings":"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"}