velocious 1.0.669 → 1.0.671

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -3,11 +3,10 @@ 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";
8
6
  import { declaredSyncScopeAttributes } from "./sync-scope-attributes.js";
9
- import { deliverDeclaredBroadcasts, upsertSyncRow } from "./sync-change-fanout.js";
7
+ import { deliverDeclaredBroadcasts } from "./sync-change-fanout.js";
10
8
  import { isPublishingSuppressed } from "./sync-publish-suppression.js";
9
+ import { upsertServerOriginSyncRow } from "./upsert-server-origin-sync-row.js";
11
10
  import { VELOCIOUS_SYNC_CHANNEL } from "./sync-channel-name.js";
12
11
  /** @type {{create: "afterCreate", update: "afterUpdate", destroy: "afterDestroy"}} */
13
12
  const PUBLISHED_CALLBACK_NAMES = { create: "afterCreate", destroy: "afterDestroy", update: "afterUpdate" };
@@ -186,8 +185,13 @@ export default class SyncPublisher {
186
185
  : this.config.syncModel;
187
186
  await record.connection().afterCommit(async () => {
188
187
  try {
189
- const scopeColumnNames = resourceConfig.scopePlan.map(({ columnName }) => columnName);
190
- const syncRow = await this.upsertPublishedSyncRow(attributes, operationScope, scopeColumnNames);
188
+ const syncRow = await upsertServerOriginSyncRow({
189
+ actorForeignKeyColumn: this.config.actorForeignKeyColumn,
190
+ attributes,
191
+ persistenceModel: operationScope,
192
+ scopeColumnNames: resourceConfig.scopePlan.map(({ columnName }) => columnName),
193
+ syncModel: this.config.syncModel
194
+ });
191
195
  await this.broadcaster()({
192
196
  body: {
193
197
  echoOrigin: null,
@@ -315,47 +319,6 @@ export default class SyncPublisher {
315
319
  }
316
320
  return entry;
317
321
  }
318
- /**
319
- * Upserts the published server-origin sync row for a resource identity:
320
- * server-origin rows carry a null actor column (no device to echo the
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.
329
- * @param {Record<string, ReturnType<typeof JSON.parse>>} attributes - Snapshotted sync row attributes.
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.
332
- * @returns {Promise<ReturnType<typeof JSON.parse>>} Upserted sync row.
333
- */
334
- async upsertPublishedSyncRow(attributes, syncModel = this.config.syncModel, scopeColumnNames = []) {
335
- /** @type {Record<string, ReturnType<typeof JSON.parse>>} */
336
- const identity = {
337
- [this.config.actorForeignKeyColumn]: null,
338
- resource_id: attributes.resource_id,
339
- resource_type: attributes.resource_type
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 });
358
- }
359
322
  /**
360
323
  * Returns the broadcaster delivering declared broadcasts: the injected one,
361
324
  * or the configuration's channel broadcast awaited through the pending
@@ -402,38 +365,6 @@ export default class SyncPublisher {
402
365
  return this._logger;
403
366
  }
404
367
  }
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
- }
437
368
  /**
438
369
  * Resolves a model class's active publish declaration from `static sync`.
439
370
  * Opted-out (`publish: false`) and undeclared models resolve to null; every
@@ -605,4 +536,4 @@ function isoDate(value) {
605
536
  }
606
537
  return value.toISOString();
607
538
  }
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=
539
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1wdWJsaXNoZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3luYy9zeW5jLXB1Ymxpc2hlci5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxhQUFhLE1BQU0scUJBQXFCLENBQUE7QUFDL0MsT0FBTyxNQUFNLE1BQU0sY0FBYyxDQUFBO0FBQ2pDLE9BQU8sRUFBQywwQkFBMEIsRUFBQyxNQUFNLCtCQUErQixDQUFBO0FBQ3hFLE9BQU8sYUFBYSxNQUFNLDZCQUE2QixDQUFBO0FBRXZELE9BQU8sRUFBQywyQkFBMkIsRUFBQyxNQUFNLDRCQUE0QixDQUFBO0FBQ3RFLE9BQU8sRUFBQyx5QkFBeUIsRUFBQyxNQUFNLHlCQUF5QixDQUFBO0FBQ2pFLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLCtCQUErQixDQUFBO0FBQ3BFLE9BQU8sRUFBQyx5QkFBeUIsRUFBQyxNQUFNLG9DQUFvQyxDQUFBO0FBQzVFLE9BQU8sRUFBQyxzQkFBc0IsRUFBQyxNQUFNLHdCQUF3QixDQUFBO0FBRTdELHNGQUFzRjtBQUN0RixNQUFNLHdCQUF3QixHQUFHLEVBQUMsTUFBTSxFQUFFLGFBQWEsRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sRUFBRSxhQUFhLEVBQUMsQ0FBQTtBQUV4Rzs7Ozs7O29EQU1vRDtBQUNwRCxNQUFNLDRCQUE0QixHQUFHLENBQUMsUUFBUSxFQUFFLFFBQVEsQ0FBQyxDQUFBO0FBRXpELG9EQUFvRDtBQUNwRCxNQUFNLGdDQUFnQyxHQUFHLElBQUksT0FBTyxFQUFFLENBQUE7QUFFdEQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBNkJHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyxhQUFhO0lBQ2hDOzs7Ozs7OztPQVFHO0lBQ0gsWUFBWSxPQUFPLEdBQUcsRUFBRTtRQUN0QixNQUFNLEVBQUMscUJBQXFCLEdBQUcseUJBQXlCLEVBQUUsV0FBVyxFQUFF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QUErQixFQUFFLENBQUMsY0FBYyxDQUFDLENBQUE7SUFFOUUsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ2hCLE1BQU0sSUFBSSxLQUFLLENBQUMsR0FBRyxTQUFTLENBQUMsSUFBSSxzQ0FBc0MsY0FBYyxvQ0FBb0MsQ0FBQyxDQUFBO0lBQzVILENBQUM7SUFFRCxPQUFPLFVBQVUsQ0FBQTtBQUNuQixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxTQUFTLDJCQUEyQixDQUFDLE1BQU07SUFDekMsNERBQTREO0lBQzVELE1BQU0sVUFBVSxHQUFHLEVBQUMsR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLEVBQUMsQ0FBQTtJQUUzQyxLQUFLLE1BQU0sQ0FBQyxhQUFhLEVBQUUsS0FBSyxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQ2hFLElBQUksS0FBSyxZQUFZLElBQUk7WUFBRSxVQUFVLENBQUMsYUFBYSxDQUFDLEdBQUcsS0FBSyxDQUFDLFdBQVcsRUFBRSxDQUFBO0lBQzVFLENBQUM7SUFFRCxPQUFPLFVBQVUsQ0FBQTtBQUNuQixDQUFDO0FBRUQ7Ozs7OztHQU1HO0FBQ0gsU0FBUyxPQUFPLENBQUMsS0FBSztJQUNwQixJQUFJLENBQUMsQ0FBQyxLQUFLLFlBQVksSUFBSSxDQUFDLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxDQUFDO1FBQzlELE1BQU0sSUFBSSxLQUFLLENBQUMsMkRBQTJELENBQUMsQ0FBQTtJQUM5RSxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUMsV0FBVyxFQUFFLENBQUE7QUFDNUIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIEB0cy1jaGVja1xuXG5pbXBvcnQgQ29uZmlndXJhdGlvbiBmcm9tIFwiLi4vY29uZmlndXJhdGlvbi5qc1wiXG5pbXBvcnQgTG9nZ2VyIGZyb20gXCIuLi9sb2dnZXIuanNcIlxuaW1wb3J0IHtzY2FsYXJNb2RlbFByaW1hcnlLZXlWYWx1ZX0gZnJvbSBcIi4uL3V0aWxzL21vZGVsLXByaW1hcnkta2V5LmpzXCJcbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuXG5pbXBvcnQge2RlY2xhcmVkU3luY1Njb3BlQXR0cmlidXRlc30gZnJvbSBcIi4vc3luYy1zY29wZS1hdHRyaWJ1dGVzLmpzXCJcbmltcG9ydCB7ZGVsaXZlckRlY2xhcmVkQnJvYWRjYXN0c30gZnJvbSBcIi4vc3luYy1jaGFuZ2UtZmFub3V0LmpzXCJcbmltcG9ydCB7aXNQdWJsaXNoaW5nU3VwcHJlc3NlZH0gZnJvbSBcIi4vc3luYy1wdWJsaXNoLXN1cHByZXNzaW9uLmpzXCJcbmltcG9ydCB7dXBzZXJ0U2VydmVyT3JpZ2luU3luY1Jvd30gZnJvbSBcIi4vdXBzZXJ0LXNlcnZlci1vcmlnaW4tc3luYy1yb3cuanNcIlxuaW1wb3J0IHtWRUxPQ0lPVVNfU1lOQ19DSEFOTkVMfSBmcm9tIFwiLi9zeW5jLWNoYW5uZWwtbmFtZS5qc1wiXG5cbi8qKiBAdHlwZSB7e2NyZWF0ZTogXCJhZnRlckNyZWF0ZVwiLCB1cGRhdGU6IFwiYWZ0ZXJVcGRhdGVcIiwgZGVzdHJveTogXCJhZnRlckRlc3Ryb3lcIn19ICovXG5jb25zdCBQVUJMSVNIRURfQ0FMTEJBQ0tfTkFNRVMgPSB7Y3JlYXRlOiBcImFmdGVyQ3JlYXRlXCIsIGRlc3Ryb3k6IFwiYWZ0ZXJEZXN0cm95XCIsIHVwZGF0ZTogXCJhZnRlclVwZGF0ZVwifVxuXG4vKipcbiAqIE9wZXJhdGlvbnMgcHVibGlzaGVkIGJ5IGRlZmF1bHQgZm9yIG1vZGVscyBkZWNsYXJpbmcgYHN0YXRpYyBzeW5jYCBwdWJsaXNoXG4gKiB3aXRob3V0IGFuIGBvcGVyYXRpb25zYCBrZXk6IHNlcnZlci1zaWRlIGNyZWF0ZXMgYW5kIHVwZGF0ZXMgcHVibGlzaFxuICogYXV0b21hdGljYWxseS4gRGVzdHJveXMgYXJlIG5vdCBwdWJsaXNoZWQgYnkgZGVmYXVsdCBiZWNhdXNlIGEgc2VydmVyXG4gKiBkZXN0cm95IGlzIG9mdGVuIGNsZWFudXAgcmF0aGVyIHRoYW4gYSBzeW5jZWQgZGVsZXRlOyBvcHQgaW4gd2l0aCBhblxuICogb3BlcmF0aW9ucyBsaXN0LlxuICogQHR5cGUge0FycmF5PFwiY3JlYXRlXCIgfCBcInVwZGF0ZVwiIHwgXCJkZXN0cm95XCI+fSAqL1xuY29uc3QgREVGQVVMVF9QVUJMSVNIRURfT1BFUkFUSU9OUyA9IFtcImNyZWF0ZVwiLCBcInVwZGF0ZVwiXVxuXG4vKiogQHR5cGUge1dlYWtNYXA8Q29uZmlndXJhdGlvbiwgU3luY1B1Ymxpc2hlcj59ICovXG5jb25zdCBzdGFydGVkUHVibGlzaGVyc0J5Q29uZmlndXJhdGlvbiA9IG5ldyBXZWFrTWFwKClcblxuLyoqXG4gKiBEZWNsYXJhdGl2ZSBzZXJ2ZXItc2lkZSBzeW5jIHB1Ymxpc2hlciDigJQgdGhlIHNlcnZlciBtaXJyb3Igb2YgdGhlIGNsaWVudCdzXG4gKiB0cmFjay1ieS1kZWZhdWx0IG11dGF0aW9uIHRyYWNraW5nLlxuICpcbiAqIFNlcnZlciBtb2RlbHMgZGVjbGFyZSB3aGF0IHRvIHB1Ymxpc2ggdGhyb3VnaCBgc3RhdGljIHN5bmNgJ3MgYHB1Ymxpc2hgXG4gKiBrZXksIGFuZCBWZWxvY2lvdXMgd3JpdGVzIGV2ZXJ5IGNvbW1pdHRlZCBzZXJ2ZXItc2lkZSBjaGFuZ2UgdG8gdGhlIHN5bmNcbiAqIGNoYW5nZSBmZWVkIChtb2RlbC1iYWNrZWQgU3luYy1yb3cgdXBzZXJ0IHdpdGggc2VydmVyIHJlLXNlcXVlbmNpbmcpIGFuZFxuICogYnJvYWRjYXN0cyB0aGUgc3RhbmRhcmQgc3luYyBlbnZlbG9wZSAoYHtlY2hvT3JpZ2luLCBzeW5jczogWy4uLl19YCkgb24gdGhlXG4gKiBmcmFtZXdvcmsgc3luYyBjaGFubmVsICh7QGxpbmsgVkVMT0NJT1VTX1NZTkNfQ0hBTk5FTH0pIHNjb3BlZCBieSB0aGVcbiAqIGNoYW5nZSdzIGRlcml2ZWQgc2NvcGUtcGFydGl0aW9uIHZhbHVlcywgc28gZGV2aWNlcyByZWNlaXZlIHNlcnZlci1vcmlnaW5cbiAqIGNoYW5nZXMgd2l0aG91dCBhcHAgY29kZSBkZWNsYXJpbmcgY2hhbm5lbHMgb3IgY2FsbGluZyBtYW51YWxcbiAqIHVwc2VydC9icm9hZGNhc3QgaGVscGVyczpcbiAqXG4gKiAgICAgc3RhdGljIHN5bmMgPSB7cHVibGlzaDogdHJ1ZX0gLy8gZGVmYXVsdCBwYXlsb2FkIChhdHRyaWJ1dGVzKSArIGRlZmF1bHQgc2NvcGUgcGFydGl0aW9uXG4gKiAgICAgc3RhdGljIHN5bmMgPSB7cHVibGlzaDoge3NlcmlhbGl6ZTogKHJlY29yZCkgPT4gKHtpZDogcmVjb3JkLmlkKCksIHBpbjogcmVjb3JkLnBpbigpfSl9fVxuICpcbiAqIFRoZSBzY29wZSBwYXJ0aXRpb24gY29tZXMgZnJvbSB0aGUgc3luYyBtb2RlbCdzIGBzdGF0aWNcbiAqIHN5bmNTY29wZUF0dHJpYnV0ZXNgIGRlY2xhcmF0aW9uIChmb3IgZXhhbXBsZSBgW1wiZXZlbnRJZFwiXWAgb3JcbiAqIGBbXCJhY2NvdW50SWRcIl1gIOKAlCBWZWxvY2lvdXMgaGFzIG5vIGJ1aWx0LWluIHBhcnRpdGlvbiBuYW1lKTogZWFjaCBkZWNsYXJlZFxuICogc2NvcGUgYXR0cmlidXRlIHJlYWRzIHRoZSByZWNvcmQncyBhdHRyaWJ1dGUgb2YgdGhlIHNhbWUgbmFtZSB3aGVuIHRoZVxuICogbW9kZWwgaGFzIG9uZSwgZWxzZSB0aGUgcmVjb3JkJ3Mgb3duIGlkIChzY29wZS1yb290IG1vZGVscyksIG92ZXJyaWRhYmxlXG4gKiBwZXIgbW9kZWwgdGhyb3VnaCBgcHVibGlzaDoge3Njb3BlQXR0cmlidXRlczoge2FjY291bnRJZDogXCJvd25lcklkXCJ9fWAuXG4gKiBUaGUgcHJlLWZyYW1ld29yay1jaGFubmVsIGBicm9hZGNhc3RzYCBsaXN0IGFuZCB0aGUgYGV2ZW50SWRgXG4gKiBzdHJpbmcvcmVzb2x2ZXItZnVuY3Rpb24gZGVjbGFyYXRpb24gZm9ybXMga2VlcCB3b3JraW5nIGJ1dCBhcmUgZGVwcmVjYXRlZC5cbiAqXG4gKiBSZXBsYXllZCBkZXZpY2UgbXV0YXRpb25zIG5ldmVyIGRvdWJsZS1wdWJsaXNoOiB0aGUgZnJhbWV3b3JrJ3Mgcm91dGVkXG4gKiByZXBsYXkgYXBwbHkgbWFya3MgaXRzIHdyaXR0ZW4gcmVjb3JkcyB0aHJvdWdoIGBtYXJrU2VydmVyQXBwbHkocmVjb3JkKWBcbiAqIChzZWUgc3luYy1wdWJsaXNoLXN1cHByZXNzaW9uLmpzKSwgYW5kIGFwcCBjb2RlIGFwcGx5aW5nIGFscmVhZHktc3luY2VkXG4gKiBkYXRhIGNhbiB1c2UgYG1hcmtTZXJ2ZXJBcHBseWAvYHdpdGhvdXRQdWJsaXNoaW5nYCB0aGUgc2FtZSB3YXkuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN5bmNQdWJsaXNoZXIge1xuICAvKipcbiAgICogQnVpbGRzIHRoZSBzeW5jIHB1Ymxpc2hlciBieSBkZXJpdmluZyBwdWJsaXNoZWQgcmVzb3VyY2VzIGZyb20gdGhlXG4gICAqIGNvbmZpZ3VyYXRpb24ncyByZWdpc3RlcmVkIG1vZGVsczogZXZlcnkgbW9kZWwgZGVjbGFyaW5nIGBzdGF0aWMgc3luY2BcbiAgICogd2l0aCBhIGBwdWJsaXNoYCBkZWNsYXJhdGlvbiBiZWNvbWVzIGEgcHVibGlzaGVkIHJlc291cmNlXG4gICAqIChgcHVibGlzaDogZmFsc2VgIG9wdHMgb3V0KS4gVGhlIHN5bmMvY2hhbmdlIG1vZGVsIGlzIHRoZSByZWdpc3RlcmVkXG4gICAqIFwiU3luY1wiIG1vZGVsIGFuZCBicm9hZGNhc3RzIGRlZmF1bHQgdG8gdGhlIGNvbmZpZ3VyYXRpb24ncyBjaGFubmVsXG4gICAqIGJyb2FkY2FzdC5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJPcHRpb25zfSBbb3B0aW9uc10gLSBPcHRpb25hbCBvdmVycmlkZXMuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihvcHRpb25zID0ge30pIHtcbiAgICBjb25zdCB7YWN0b3JGb3JlaWduS2V5Q29sdW1uID0gXCJhdXRoZW50aWNhdGlvbl90b2tlbl9pZFwiLCBicm9hZGNhc3RlciwgY29uZmlndXJhdGlvbiA9IENvbmZpZ3VyYXRpb24uY3VycmVudCgpLCBvbkVycm9yLCBzeW5jTW9kZWwsIC4uLnJlc3RPcHRpb25zfSA9IG9wdGlvbnNcblxuICAgIHJlc3RBcmdzRXJyb3IocmVzdE9wdGlvbnMpXG5cbiAgICBjb25zdCBtb2RlbENsYXNzZXMgPSBjb25maWd1cmF0aW9uLmdldE1vZGVsQ2xhc3NlcygpXG4gICAgY29uc3QgcHVibGlzaGluZ01vZGVsQ2xhc3NlcyA9IE9iamVjdC52YWx1ZXMobW9kZWxDbGFzc2VzKS5maWx0ZXIoKG1vZGVsQ2xhc3MpID0+IHB1Ymxpc2hEZWNsYXJhdGlvbkZvcihtb2RlbENsYXNzKSlcblxuICAgIGlmIChwdWJsaXNoaW5nTW9kZWxDbGFzc2VzLmxlbmd0aCA9PT0gMCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY1B1Ymxpc2hlciBmb3VuZCBubyByZWdpc3RlcmVkIG1vZGVscyBkZWNsYXJpbmcgc3RhdGljIHN5bmMgcHVibGlzaCAtIGRlY2xhcmUgYHN0YXRpYyBzeW5jID0ge3B1Ymxpc2g6IHtzZXJpYWxpemV9fWAgb24gdGhlIG1vZGVscyB3aG9zZSBzZXJ2ZXItc2lkZSBjaGFuZ2VzIHNob3VsZCBwdWJsaXNoIHRvIHRoZSBzeW5jIGZlZWRcIilcbiAgICB9XG5cbiAgICBjb25zdCByZXNvbHZlZFN5bmNNb2RlbCA9IHN5bmNNb2RlbCB8fCBtb2RlbENsYXNzZXMuU3luY1xuXG4gICAgaWYgKCFyZXNvbHZlZFN5bmNNb2RlbCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY1B1Ymxpc2hlciByZXF1aXJlcyBhIHJlZ2lzdGVyZWQgXFxcIlN5bmNcXFwiIG1vZGVsIGZvciBwdWJsaXNoZWQgc3luYyBjaGFuZ2Ugcm93cyAob3IgcGFzcyBvcHRpb25zLnN5bmNNb2RlbClcIilcbiAgICB9XG5cbiAgICBjb25zdCBzY29wZUF0dHJpYnV0ZXMgPSBkZWNsYXJlZFN5bmNTY29wZUF0dHJpYnV0ZXMocmVzb2x2ZWRTeW5jTW9kZWwpXG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJSZXNvdXJjZUNvbmZpZz59ICovXG4gICAgY29uc3QgcmVzb3VyY2VzID0ge31cblxuICAgIGZvciAoY29uc3QgbW9kZWxDbGFzcyBvZiBwdWJsaXNoaW5nTW9kZWxDbGFzc2VzKSB7XG4gICAgICBjb25zdCBwdWJsaXNoID0gcHVibGlzaERlY2xhcmF0aW9uRm9yKG1vZGVsQ2xhc3MpXG4gICAgICBjb25zdCByZXNvdXJjZUNvbmZpZyA9IHJlc291cmNlQ29uZmlnRnJvbVB1Ymxpc2hEZWNsYXJhdGlvbih7bW9kZWxDbGFzcywgcHVibGlzaCwgc2NvcGVBdHRyaWJ1dGVzLCBzeW5jTW9kZWw6IHJlc29sdmVkU3luY01vZGVsfSlcblxuICAgICAgcmVzb3VyY2VzW3Jlc291cmNlQ29uZmlnLnJlc291cmNlVHlwZV0gPSByZXNvdXJjZUNvbmZpZ1xuICAgIH1cblxuICAgIC8qKiBAdHlwZSB7e2FjdG9yRm9yZWlnbktleUNvbHVtbjogc3RyaW5nLCBicm9hZGNhc3RlcjogaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyT3B0aW9uc1tcImJyb2FkY2FzdGVyXCJdLCBjb25maWd1cmF0aW9uOiBDb25maWd1cmF0aW9uLCBvbkVycm9yOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJPcHRpb25zW1wib25FcnJvclwiXSwgcmVzb3VyY2VzOiBSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJSZXNvdXJjZUNvbmZpZz4sIHN5bmNNb2RlbDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59fSAqL1xuICAgIHRoaXMuY29uZmlnID0ge2FjdG9yRm9yZWlnbktleUNvbHVtbiwgYnJvYWRjYXN0ZXIsIGNvbmZpZ3VyYXRpb24sIG9uRXJyb3IsIHJlc291cmNlcywgc3luY01vZGVsOiByZXNvbHZlZFN5bmNNb2RlbH1cbiAgICAvKiogQHR5cGUge0FycmF5PHtjYWxsYmFjazogKHJlY29yZDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4pID0+IFByb21pc2U8dm9pZD4sIGNhbGxiYWNrTmFtZTogXCJhZnRlckNyZWF0ZVwiIHwgXCJhZnRlclVwZGF0ZVwiIHwgXCJhZnRlckRlc3Ryb3lcIiwgbW9kZWxDbGFzczogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59Pn0gKi9cbiAgICB0aGlzLl9wdWJsaXNoZWRDYWxsYmFja3MgPSBbXVxuICAgIC8qKiBAdHlwZSB7TG9nZ2VyIHwgbnVsbH0gKi9cbiAgICB0aGlzLl9sb2dnZXIgPSBudWxsXG4gICAgdGhpcy5fc3RhcnRlZCA9IGZhbHNlXG4gIH1cblxuICAvKipcbiAgICogQnVpbGRzIGEgc3luYyBwdWJsaXNoZXIgZGVyaXZlZCBmcm9tIHRoZSBnaXZlbiBjb25maWd1cmF0aW9uLiBBbGlhcyBmb3JcbiAgICogYG5ldyBTeW5jUHVibGlzaGVyKHtjb25maWd1cmF0aW9uLCAuLi5vcHRpb25zfSlgLlxuICAgKiBAcGFyYW0ge0NvbmZpZ3VyYXRpb259IFtjb25maWd1cmF0aW9uXSAtIENvbmZpZ3VyYXRpb24gb3duaW5nIHRoZSByZWdpc3RlcmVkIG1vZGVscy4gRGVmYXVsdHMgdG8gdGhlIGN1cnJlbnQgY29uZmlndXJhdGlvbi5cbiAgICogQHBhcmFtIHtPbWl0PGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlck9wdGlvbnMsIFwiY29uZmlndXJhdGlvblwiPn0gW29wdGlvbnNdIC0gT3B0aW9uYWwgb3ZlcnJpZGVzLlxuICAgKiBAcmV0dXJucyB7U3luY1B1Ymxpc2hlcn0gU3luYyBwdWJsaXNoZXIgZGVyaXZlZCBmcm9tIHRoZSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgc3RhdGljIGZyb21Db25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb24gPSBDb25maWd1cmF0aW9uLmN1cnJlbnQoKSwgb3B0aW9ucyA9IHt9KSB7XG4gICAgcmV0dXJuIG5ldyBTeW5jUHVibGlzaGVyKHsuLi5vcHRpb25zLCBjb25maWd1cmF0aW9ufSlcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydHMgKGFuZCBtZW1vaXplcyBwZXIgY29uZmlndXJhdGlvbikgdGhlIHN5bmMgcHVibGlzaGVyIGZvciBhIHNlcnZlclxuICAgKiBib290OiBuby1vcCB3aGVuIG5vIHJlZ2lzdGVyZWQgbW9kZWwgZGVjbGFyZXMgYSBwdWJsaXNoIGNvbmZpZywgZ3VhcmRlZCBzb1xuICAgKiByZXBlYXRlZCBib290cyB3aXRoIHRoZSBzYW1lIGNvbmZpZ3VyYXRpb24gcmVnaXN0ZXIgdGhlIHB1Ymxpc2ggY2FsbGJhY2tzXG4gICAqIG9ubHkgb25jZS5cbiAgICogQHBhcmFtIHtDb25maWd1cmF0aW9ufSBjb25maWd1cmF0aW9uIC0gQ29uZmlndXJhdGlvbiBvd25pbmcgdGhlIHJlZ2lzdGVyZWQgbW9kZWxzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxTeW5jUHVibGlzaGVyIHwgbnVsbD59IFN0YXJ0ZWQgcHVibGlzaGVyLCBvciBudWxsIHdoZW4gbm8gbW9kZWxzIGRlY2xhcmUgcHVibGlzaC5cbiAgICovXG4gIHN0YXRpYyBhc3luYyBzdGFydEZyb21Db25maWd1cmF0aW9uKGNvbmZpZ3VyYXRpb24pIHtcbiAgICBjb25zdCBzdGFydGVkUHVibGlzaGVyID0gc3RhcnRlZFB1Ymxpc2hlcnNCeUNvbmZpZ3VyYXRpb24uZ2V0KGNvbmZpZ3VyYXRpb24pXG5cbiAgICBpZiAoc3RhcnRlZFB1Ymxpc2hlcikgcmV0dXJuIHN0YXJ0ZWRQdWJsaXNoZXJcblxuICAgIGlmICghT2JqZWN0LnZhbHVlcyhjb25maWd1cmF0aW9uLmdldE1vZGVsQ2xhc3NlcygpKS5zb21lKChtb2RlbENsYXNzKSA9PiBwdWJsaXNoRGVjbGFyYXRpb25Gb3IobW9kZWxDbGFzcykpKSByZXR1cm4gbnVsbFxuXG4gICAgY29uc3QgcHVibGlzaGVyID0gbmV3IFN5bmNQdWJsaXNoZXIoe2NvbmZpZ3VyYXRpb259KVxuXG4gICAgc3RhcnRlZFB1Ymxpc2hlcnNCeUNvbmZpZ3VyYXRpb24uc2V0KGNvbmZpZ3VyYXRpb24sIHB1Ymxpc2hlcilcbiAgICBhd2FpdCBwdWJsaXNoZXIuc3RhcnQoKVxuXG4gICAgcmV0dXJuIHB1Ymxpc2hlclxuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyB0aGUgcHVibGlzaCBjYWxsYmFja3MgZm9yIGV2ZXJ5IHB1Ymxpc2hlZCByZXNvdXJjZTogc2VydmVyLXNpZGVcbiAgICogY3JlYXRlcyBhbmQgdXBkYXRlcyAoZGVzdHJveXMgd2hlbiBvcHRlZCBpbikgdXBzZXJ0IGEgc3luYyBjaGFuZ2Ugcm93IGFuZFxuICAgKiBmYW4gb3V0IHRoZSBkZWNsYXJlZCBicm9hZGNhc3RzIG9uY2UgdGhlaXIgdHJhbnNhY3Rpb24gY29tbWl0cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBzdGFydCgpIHtcbiAgICBpZiAodGhpcy5fc3RhcnRlZCkgcmV0dXJuXG5cbiAgICB0aGlzLl9zdGFydGVkID0gdHJ1ZVxuXG4gICAgZm9yIChjb25zdCByZXNvdXJjZUNvbmZpZyBvZiBPYmplY3QudmFsdWVzKHRoaXMuY29uZmlnLnJlc291cmNlcykpIHtcbiAgICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIHJlc291cmNlQ29uZmlnLm9wZXJhdGlvbnMpIHtcbiAgICAgICAgY29uc3QgY2FsbGJhY2tOYW1lID0gUFVCTElTSEVEX0NBTExCQUNLX05BTUVTW29wZXJhdGlvbl1cbiAgICAgICAgY29uc3QgY2FsbGJhY2sgPSB0aGlzLnB1Ymxpc2hlZE11dGF0aW9uQ2FsbGJhY2soe29wZXJhdGlvbiwgcmVzb3VyY2VDb25maWd9KVxuXG4gICAgICAgIHJlc291cmNlQ29uZmlnLm1vZGVsQ2xhc3NbY2FsbGJhY2tOYW1lXShjYWxsYmFjaylcbiAgICAgICAgdGhpcy5fcHVibGlzaGVkQ2FsbGJhY2tzLnB1c2goe2NhbGxiYWNrLCBjYWxsYmFja05hbWUsIG1vZGVsQ2xhc3M6IHJlc291cmNlQ29uZmlnLm1vZGVsQ2xhc3N9KVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBVbnJlZ2lzdGVycyBhbGwgcHVibGlzaCBjYWxsYmFja3MgKHRlc3RzLCBzaHV0ZG93bikuXG4gICAqIEByZXR1cm5zIHt2b2lkfVxuICAgKi9cbiAgc3RvcCgpIHtcbiAgICBmb3IgKGNvbnN0IHtjYWxsYmFjaywgY2FsbGJhY2tOYW1lLCBtb2RlbENsYXNzfSBvZiB0aGlzLl9wdWJsaXNoZWRDYWxsYmFja3MpIHtcbiAgICAgIG1vZGVsQ2xhc3MudW5yZWdpc3RlckxpZmVjeWNsZUNhbGxiYWNrKGNhbGxiYWNrTmFtZSwgY2FsbGJhY2spXG4gICAgfVxuXG4gICAgdGhpcy5fcHVibGlzaGVkQ2FsbGJhY2tzID0gW11cbiAgICB0aGlzLl9zdGFydGVkID0gZmFsc2VcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIGxpZmVjeWNsZSBjYWxsYmFjayBwdWJsaXNoaW5nIG9uZSBzZXJ2ZXItc2lkZSBtdXRhdGlvbi4gVGhlXG4gICAqIHB1Ymxpc2hlZCBwYXlsb2FkIChkZWNsYXJhdGlvbiBgc2VyaWFsaXplYCksIGV2ZW50IHNjb3BlLCBhbmQgc3luYyB0eXBlXG4gICAqIGFyZSBzbmFwc2hvdHRlZCBhdCBtdXRhdGlvbi1jYWxsYmFjayB0aW1lLCBzbyBhZnRlclNhdmUgaG9va3MgYXNzaWduaW5nXG4gICAqIHVuc2F2ZWQgYXR0cmlidXRlcyAob3IgYW55IGxhdGVyIGRyaWZ0IG9uIHRoZSByZWNvcmQpIGNhbm5vdCBjaGFuZ2Ugd2hhdFxuICAgKiBnZXRzIHB1Ymxpc2hlZCB2cyB3aGF0IHdhcyBjb21taXR0ZWQuIFBlcnNpc3RpbmcgYW5kIGJyb2FkY2FzdGluZyBhcmVcbiAgICogZGVmZXJyZWQgdGhyb3VnaCB0aGUgbW9kZWwgY29ubmVjdGlvbidzIGFmdGVyQ29tbWl0IGhvb2sgc28gdGhleSBvbmx5IHJ1blxuICAgKiBvbmNlIHRoZSBtdXRhdGlvbidzIHRyYW5zYWN0aW9uIGhhcyBjb21taXR0ZWQgKGltbWVkaWF0ZWx5IHdoZW4gbm9cbiAgICogdHJhbnNhY3Rpb24gaXMgb3BlbikgLSByb2xsZWQtYmFjayBtdXRhdGlvbnMgbmV2ZXIgcHVibGlzaC4gUG9zdC1jb21taXRcbiAgICogcHVibGlzaCBmYWlsdXJlcyBhcmUgcmVwb3J0ZWQgd2l0aG91dCByZXRocm93aW5nIGludG8gdGhlIGRyaXZlcidzXG4gICAqIGFmdGVyQ29tbWl0IGNoYWluIChzZWUgcmVwb3J0QWZ0ZXJDb21taXRFcnJvcikuXG4gICAqIEBwYXJhbSB7e29wZXJhdGlvbjogXCJjcmVhdGVcIiB8IFwidXBkYXRlXCIgfCBcImRlc3Ryb3lcIiwgcmVzb3VyY2VDb25maWc6IGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlclJlc291cmNlQ29uZmlnfX0gYXJncyAtIE9wZXJhdGlvbiBhbmQgcmVzb3VyY2UgY29uZmlnLlxuICAgKiBAcmV0dXJucyB7KHJlY29yZDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4pID0+IFByb21pc2U8dm9pZD59IExpZmVjeWNsZSBjYWxsYmFjay5cbiAgICovXG4gIHB1Ymxpc2hlZE11dGF0aW9uQ2FsbGJhY2soe29wZXJhdGlvbiwgcmVzb3VyY2VDb25maWd9KSB7XG4gICAgcmV0dXJuIGFzeW5jIChyZWNvcmQpID0+IHtcbiAgICAgIGlmIChpc1B1Ymxpc2hpbmdTdXBwcmVzc2VkKHJlY29yZCkpIHJldHVyblxuXG4gICAgICBjb25zdCBkYXRhID0gYXdhaXQgcmVzb3VyY2VDb25maWcuc2VyaWFsaXplKHJlY29yZClcbiAgICAgIGNvbnN0IHJlc291cmNlSWQgPSBTdHJpbmcoc2NhbGFyTW9kZWxQcmltYXJ5S2V5VmFsdWUocmVjb3JkLmlkKCksIGBTeW5jIHB1Ymxpc2hpbmcgZm9yICR7cmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlfWApKVxuICAgICAgY29uc3Qgc3luY1R5cGUgPSBvcGVyYXRpb24gPT09IFwiZGVzdHJveVwiID8gXCJkZWxldGVcIiA6IFwidXBkYXRlXCJcbiAgICAgIGNvbnN0IHNjb3BlVmFsdWVzID0gYXdhaXQgdGhpcy5wdWJsaXNoZWRTY29wZVZhbHVlcyh7cmVjb3JkLCByZXNvdXJjZUNvbmZpZ30pXG4gICAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gKi9cbiAgICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSB7XG4gICAgICAgIFt0aGlzLmNvbmZpZy5hY3RvckZvcmVpZ25LZXlDb2x1bW5dOiBudWxsLFxuICAgICAgICBjbGllbnRfdXBkYXRlZF9hdDogbmV3IERhdGUoKSxcbiAgICAgICAgZGF0YTogSlNPTi5zdHJpbmdpZnkoZGF0YSksXG4gICAgICAgIHJlc291cmNlX2lkOiByZXNvdXJjZUlkLFxuICAgICAgICByZXNvdXJjZV90eXBlOiByZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGUsXG4gICAgICAgIHN5bmNfdHlwZTogc3luY1R5cGUsXG4gICAgICAgIC4uLnNjb3BlVmFsdWVzLmNvbHVtbnNcbiAgICAgIH1cbiAgICAgIGNvbnN0IGRhdGFiYXNlT3BlcmF0aW9uID0gcmVjb3JkLmRhdGFiYXNlT3BlcmF0aW9uKClcbiAgICAgIGNvbnN0IG9wZXJhdGlvblNjb3BlID0gZGF0YWJhc2VPcGVyYXRpb25cbiAgICAgICAgPyBkYXRhYmFzZU9wZXJhdGlvbi5mb3JNb2RlbCh0aGlzLmNvbmZpZy5zeW5jTW9kZWwpXG4gICAgICAgIDogdGhpcy5jb25maWcuc3luY01vZGVsXG5cbiAgICAgIGF3YWl0IHJlY29yZC5jb25uZWN0aW9uKCkuYWZ0ZXJDb21taXQoYXN5bmMgKCkgPT4ge1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGNvbnN0IHN5bmNSb3cgPSBhd2FpdCB1cHNlcnRTZXJ2ZXJPcmlnaW5TeW5jUm93KHtcbiAgICAgICAgICAgIGFjdG9yRm9yZWlnbktleUNvbHVtbjogdGhpcy5jb25maWcuYWN0b3JGb3JlaWduS2V5Q29sdW1uLFxuICAgICAgICAgICAgYXR0cmlidXRlcyxcbiAgICAgICAgICAgIHBlcnNpc3RlbmNlTW9kZWw6IG9wZXJhdGlvblNjb3BlLFxuICAgICAgICAgICAgc2NvcGVDb2x1bW5OYW1lczogcmVzb3VyY2VDb25maWcuc2NvcGVQbGFuLm1hcCgoe2NvbHVtbk5hbWV9KSA9PiBjb2x1bW5OYW1lKSxcbiAgICAgICAgICAgIHN5bmNNb2RlbDogdGhpcy5jb25maWcuc3luY01vZGVsXG4gICAgICAgICAgfSlcblxuICAgICAgICAgIGF3YWl0IHRoaXMuYnJvYWRjYXN0ZXIoKSh7XG4gICAgICAgICAgICBib2R5OiB7XG4gICAgICAgICAgICAgIGVjaG9PcmlnaW46IG51bGwsXG4gICAgICAgICAgICAgIHN5bmNzOiBbdGhpcy5wdWJsaXNoZWRTeW5jRW50cnkoe2RhdGEsIHJlc291cmNlQ29uZmlnLCByZXNvdXJjZUlkLCBzeW5jUm93LCBzeW5jVHlwZX0pXVxuICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIGNoYW5uZWw6IFZFTE9DSU9VU19TWU5DX0NIQU5ORUwsXG4gICAgICAgICAgICBwYXJhbXM6IHsuLi5zY29wZVZhbHVlcy5wYXJhbXMsIHJlc291cmNlVHlwZTogcmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlfVxuICAgICAgICAgIH0pXG5cbiAgICAgICAgICBpZiAocmVzb3VyY2VDb25maWcuYnJvYWRjYXN0cykge1xuICAgICAgICAgICAgYXdhaXQgZGVsaXZlckRlY2xhcmVkQnJvYWRjYXN0cyh7XG4gICAgICAgICAgICAgIGFyZ3M6IHtkYXRhLCBvcGVyYXRpb24sIHJlY29yZCwgcmVzb3VyY2VJZCwgcmVzb3VyY2VUeXBlOiByZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGUsIHN5bmNSb3csIHN5bmNUeXBlfSxcbiAgICAgICAgICAgICAgYnJvYWRjYXN0ZXI6IHRoaXMuYnJvYWRjYXN0ZXIoKSxcbiAgICAgICAgICAgICAgYnJvYWRjYXN0czogcmVzb3VyY2VDb25maWcuYnJvYWRjYXN0c1xuICAgICAgICAgICAgfSlcbiAgICAgICAgICB9XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgYXdhaXQgdGhpcy5yZXBvcnRBZnRlckNvbW1pdEVycm9yKC8qKiBAdHlwZSB7RXJyb3J9ICovIChlcnJvcikpXG4gICAgICAgIH1cbiAgICAgIH0pXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSBzY29wZS1wYXJ0aXRpb24gdmFsdWVzIGZvciBvbmUgcHVibGlzaGVkIG11dGF0aW9uIGZyb20gdGhlXG4gICAqIHJlc291cmNlJ3MgZGVyaXZlZCBzY29wZSBwbGFuOiBlYWNoIGVudHJ5IHJlYWRzIGl0cyByZWNvcmQgYXR0cmlidXRlIChvclxuICAgKiB0aGUgcmVjb3JkJ3Mgb3duIGlkIGZvciBzY29wZS1yb290IG1vZGVscywgb3IgdGhlIGRlcHJlY2F0ZWQgcmVzb2x2ZXJcbiAgICogZnVuY3Rpb24pLiBUaGUgdmFsdWVzIGFyZSBwZXJzaXN0ZWQgb250byB0aGUgc3luYyByb3cncyBwYXJ0aXRpb24gY29sdW1uc1xuICAgKiBhbmQgYnJvYWRjYXN0IGFzIHRoZSBmcmFtZXdvcmsgc3luYyBjaGFubmVsJ3Mgc2NvcGluZyBwYXJhbXMuXG4gICAqIEBwYXJhbSB7e3JlY29yZDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4sIHJlc291cmNlQ29uZmlnOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJSZXNvdXJjZUNvbmZpZ319IGFyZ3MgLSBNdXRhdGVkIHJlY29yZCBhbmQgcmVzb3VyY2UgY29uZmlnLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7Y29sdW1uczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVsbD4sIHBhcmFtczogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVsbD59Pn0gU2NvcGUgdmFsdWVzIGtleWVkIGJ5IHN5bmMtcm93IGNvbHVtbiBhbmQgYnkgc2NvcGUgYXR0cmlidXRlLlxuICAgKi9cbiAgYXN5bmMgcHVibGlzaGVkU2NvcGVWYWx1ZXMoe3JlY29yZCwgcmVzb3VyY2VDb25maWd9KSB7XG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudWxsPn0gKi9cbiAgICBjb25zdCBjb2x1bW5zID0ge31cbiAgICAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZyB8IG51bGw+fSAqL1xuICAgIGNvbnN0IHBhcmFtcyA9IHt9XG4gICAgY29uc3QgY29tcHV0ZWRTY29wZUF0dHJpYnV0ZXMgPSByZXNvdXJjZUNvbmZpZy5zY29wZUF0dHJpYnV0ZXNSZXNvbHZlclxuICAgICAgPyBhd2FpdCB0aGlzLnJlc29sdmVDb21wdXRlZFNjb3BlQXR0cmlidXRlcyh7cmVjb3JkLCByZXNvdXJjZUNvbmZpZ30pXG4gICAgICA6IG51bGxcblxuICAgIGZvciAoY29uc3Qgc2NvcGVQbGFuRW50cnkgb2YgcmVzb3VyY2VDb25maWcuc2NvcGVQbGFuKSB7XG4gICAgICAvKiogQHR5cGUge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSAqL1xuICAgICAgbGV0IHJhd1ZhbHVlXG5cbiAgICAgIGlmIChjb21wdXRlZFNjb3BlQXR0cmlidXRlcykge1xuICAgICAgICByYXdWYWx1ZSA9IGNvbXB1dGVkU2NvcGVBdHRyaWJ1dGVzW3Njb3BlUGxhbkVudHJ5LnNjb3BlQXR0cmlidXRlXVxuICAgICAgfSBlbHNlIGlmIChzY29wZVBsYW5FbnRyeS5yZXNvbHZlcikge1xuICAgICAgICByYXdWYWx1ZSA9IGF3YWl0IHNjb3BlUGxhbkVudHJ5LnJlc29sdmVyKHJlY29yZClcbiAgICAgIH0gZWxzZSBpZiAoc2NvcGVQbGFuRW50cnkucmVjb3JkQXR0cmlidXRlKSB7XG4gICAgICAgIHJhd1ZhbHVlID0gcmVjb3JkLnJlYWRBdHRyaWJ1dGUoc2NvcGVQbGFuRW50cnkucmVjb3JkQXR0cmlidXRlKVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmF3VmFsdWUgPSBzY2FsYXJNb2RlbFByaW1hcnlLZXlWYWx1ZShyZWNvcmQuaWQoKSwgYFN5bmMgc2NvcGUgcHVibGlzaGluZyBmb3IgJHtyZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGV9YClcbiAgICAgIH1cblxuICAgICAgY29uc3QgdmFsdWUgPSByYXdWYWx1ZSA9PT0gdW5kZWZpbmVkIHx8IHJhd1ZhbHVlID09PSBudWxsID8gbnVsbCA6IFN0cmluZyhyYXdWYWx1ZSlcblxuICAgICAgY29sdW1uc1tzY29wZVBsYW5FbnRyeS5jb2x1bW5OYW1lXSA9IHZhbHVlXG4gICAgICBwYXJhbXNbc2NvcGVQbGFuRW50cnkuc2NvcGVBdHRyaWJ1dGVdID0gdmFsdWVcbiAgICB9XG5cbiAgICByZXR1cm4ge2NvbHVtbnMsIHBhcmFtc31cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyBhbmQgdmFsaWRhdGVzIG9uZSBjb21wdXRlZCBzY29wZS1hdHRyaWJ1dGVzIGRlY2xhcmF0aW9uLiBUaGVcbiAgICogcmVzb2x2ZXIgcnVucyBvbmNlIHBlciBwdWJsaXNoZWQgbXV0YXRpb24gd2l0aCB0aGUgZXhhY3QgY29ubmVjdGlvbiB0aGF0XG4gICAqIG93bnMgdGhhdCBtdXRhdGlvbjsgZXZlcnkgZGVjbGFyZWQgc2NvcGUgdmFsdWUgaXMgdGhlbiByZXVzZWQgZm9yIHJvd1xuICAgKiBwZXJzaXN0ZW5jZSBhbmQgYnJvYWRjYXN0IHJvdXRpbmcgc28gdGhvc2UgdHdvIGlkZW50aXRpZXMgY2Fubm90IGRyaWZ0LlxuICAgKiBAcGFyYW0ge3tyZWNvcmQ6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+LCByZXNvdXJjZUNvbmZpZzogaW1wb3J0KFwiLi9zeW5jLXB1Ymxpc2hlci10eXBlcy5qc1wiKS5TeW5jUHVibGlzaGVyUmVzb3VyY2VDb25maWd9fSBhcmdzIC0gUmVjb3JkIGFuZCByZXNvdXJjZSBjb25maWd1cmF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBudW1iZXIgfCBudWxsPj59IENvbXBsZXRlIGNvbXB1dGVkIHNjb3BlIHZhbHVlcy5cbiAgICovXG4gIGFzeW5jIHJlc29sdmVDb21wdXRlZFNjb3BlQXR0cmlidXRlcyh7cmVjb3JkLCByZXNvdXJjZUNvbmZpZ30pIHtcbiAgICBjb25zdCByZXNvbHZlciA9IHJlc291cmNlQ29uZmlnLnNjb3BlQXR0cmlidXRlc1Jlc29sdmVyXG5cbiAgICBpZiAoIXJlc29sdmVyKSB0aHJvdyBuZXcgRXJyb3IoYE5vIGNvbXB1dGVkIHNjb3BlLWF0dHJpYnV0ZXMgcmVzb2x2ZXIgY29uZmlndXJlZCBmb3IgJHtyZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGV9YClcblxuICAgIGNvbnN0IHJlc29sdmVkID0gYXdhaXQgcmVzb2x2ZXIoe1xuICAgICAgY29uZmlndXJhdGlvbjogdGhpcy5jb25maWcuY29uZmlndXJhdGlvbixcbiAgICAgIGNvbm5lY3Rpb246IHJlY29yZC5jb25uZWN0aW9uKCksXG4gICAgICByZWNvcmRcbiAgICB9KVxuXG4gICAgaWYgKCFpc1BsYWluT2JqZWN0KHJlc29sdmVkKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3Jlc291cmNlQ29uZmlnLnJlc291cmNlVHlwZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzY29wZUF0dHJpYnV0ZXMgcmVzb2x2ZXIgbXVzdCByZXNvbHZlIHRvIGEgcGxhaW4gb2JqZWN0YClcbiAgICB9XG5cbiAgICBjb25zdCBkZWNsYXJlZEF0dHJpYnV0ZXMgPSByZXNvdXJjZUNvbmZpZy5zY29wZVBsYW4ubWFwKCh7c2NvcGVBdHRyaWJ1dGV9KSA9PiBzY29wZUF0dHJpYnV0ZSlcblxuICAgIGZvciAoY29uc3Qgc2NvcGVBdHRyaWJ1dGUgb2YgT2JqZWN0LmtleXMocmVzb2x2ZWQpKSB7XG4gICAgICBpZiAoIWRlY2xhcmVkQXR0cmlidXRlcy5pbmNsdWRlcyhzY29wZUF0dHJpYnV0ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3Jlc291cmNlQ29uZmlnLnJlc291cmNlVHlwZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzY29wZUF0dHJpYnV0ZXMgcmVzb2x2ZXIgcmV0dXJuZWQgdW5rbm93biBzY29wZSBhdHRyaWJ1dGU6ICR7c2NvcGVBdHRyaWJ1dGV9ICh0aGUgc3luYyBtb2RlbCBkZWNsYXJlczogJHtkZWNsYXJlZEF0dHJpYnV0ZXMuam9pbihcIiwgXCIpfSlgKVxuICAgICAgfVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgc2NvcGVBdHRyaWJ1dGUgb2YgZGVjbGFyZWRBdHRyaWJ1dGVzKSB7XG4gICAgICBpZiAoIU9iamVjdC5oYXNPd24ocmVzb2x2ZWQsIHNjb3BlQXR0cmlidXRlKSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7cmVzb3VyY2VDb25maWcucmVzb3VyY2VUeXBlfSBzdGF0aWMgc3luYyBwdWJsaXNoIHNjb3BlQXR0cmlidXRlcyByZXNvbHZlciBtdXN0IHJlc29sdmUgdGhlIGRlY2xhcmVkIHNjb3BlIGF0dHJpYnV0ZSAke3Njb3BlQXR0cmlidXRlfWApXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHZhbHVlID0gcmVzb2x2ZWRbc2NvcGVBdHRyaWJ1dGVdXG5cbiAgICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgJiYgdHlwZW9mIHZhbHVlICE9PSBcIm51bWJlclwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHtyZXNvdXJjZUNvbmZpZy5yZXNvdXJjZVR5cGV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggc2NvcGUgYXR0cmlidXRlICR7c2NvcGVBdHRyaWJ1dGV9IG11c3QgYmUgYSBzdHJpbmcsIG51bWJlciwgb3IgbnVsbGApXG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgbnVtYmVyIHwgbnVsbD59ICovIChyZXNvbHZlZClcbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIGZyYW1ld29yayBzeW5jIGNoYW5uZWwgZW50cnkgZm9yIG9uZSBwdWJsaXNoZWQgY2hhbmdlOiB0aGVcbiAgICogc25hcHNob3R0ZWQgcGF5bG9hZCBwbHVzIHRoZSBwZXJzaXN0ZWQgc3luYyByb3cncyBwdWJsaWMgZXhhY3Qtcm93IG1ldGFkYXRhXG4gICAqIChpZCwgc2VydmVyIHNlcXVlbmNlLCB1cGRhdGVkLWF0LCBhbmQgZGVjbGFyZWQgc2NvcGUtcGFydGl0aW9uIGF0dHJpYnV0ZXMpLlxuICAgKiBVc2VzIHRoZSBzeW5jIG1vZGVsJ3MgZ2VuZXJhdGVkIHR5cGVkIGFjY2Vzc29ycyBhbmQgZm9sbG93cyB0aGVcbiAgICogY2hhbmdlLWZlZWQgc2VyaWFsaXplcidzIHB1YmxpYyBmaWVsZCBjb252ZW50aW9uLlxuICAgKiBAcGFyYW0ge3tkYXRhOiBSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj4sIHJlc291cmNlQ29uZmlnOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJSZXNvdXJjZUNvbmZpZywgcmVzb3VyY2VJZDogc3RyaW5nLCBzeW5jUm93OiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPiwgc3luY1R5cGU6IHN0cmluZ319IGFyZ3MgLSBQdWJsaXNoIGFyZ3MuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59IEJyb2FkY2FzdCBzeW5jIGVudHJ5LlxuICAgKi9cbiAgcHVibGlzaGVkU3luY0VudHJ5KHtkYXRhLCByZXNvdXJjZUNvbmZpZywgcmVzb3VyY2VJZCwgc3luY1Jvdywgc3luY1R5cGV9KSB7XG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovXG4gICAgY29uc3QgZW50cnkgPSB7XG4gICAgICBkYXRhLFxuICAgICAgaWQ6IHN5bmNSb3cuaWQoKSxcbiAgICAgIHJlc291cmNlSWQsXG4gICAgICByZXNvdXJjZVR5cGU6IHJlc291cmNlQ29uZmlnLnJlc291cmNlVHlwZSxcbiAgICAgIHNlcnZlclNlcXVlbmNlOiBzeW5jUm93LnNlcnZlclNlcXVlbmNlKCksXG4gICAgICBzeW5jVHlwZSxcbiAgICAgIHVwZGF0ZWRBdDogaXNvRGF0ZShzeW5jUm93LnVwZGF0ZWRBdCgpKVxuICAgIH1cblxuICAgIGNvbnN0IHNjb3BlQXR0cmlidXRlcyA9IGRlY2xhcmVkU3luY1Njb3BlQXR0cmlidXRlcyh0aGlzLmNvbmZpZy5zeW5jTW9kZWwpXG5cbiAgICBmb3IgKGNvbnN0IHNjb3BlQXR0cmlidXRlIG9mIHNjb3BlQXR0cmlidXRlcyB8fCBbXSkge1xuICAgICAgY29uc3Qgc2NvcGVBY2Nlc3NvciA9IHN5bmNSb3dbc2NvcGVBdHRyaWJ1dGVdXG5cbiAgICAgIGlmICh0eXBlb2Ygc2NvcGVBY2Nlc3NvciAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgUHVibGlzaGVkIHN5bmMgcm93IGlzIG1pc3NpbmcgdGhlIGRlY2xhcmVkIHNjb3BlIGFjY2Vzc29yICR7c2NvcGVBdHRyaWJ1dGV9KCkuYClcbiAgICAgIH1cblxuICAgICAgZW50cnlbc2NvcGVBdHRyaWJ1dGVdID0gc2NvcGVBY2Nlc3Nvci5jYWxsKHN5bmNSb3cpXG4gICAgfVxuXG4gICAgcmV0dXJuIGVudHJ5XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYnJvYWRjYXN0ZXIgZGVsaXZlcmluZyBkZWNsYXJlZCBicm9hZGNhc3RzOiB0aGUgaW5qZWN0ZWQgb25lLFxuICAgKiBvciB0aGUgY29uZmlndXJhdGlvbidzIGNoYW5uZWwgYnJvYWRjYXN0IGF3YWl0ZWQgdGhyb3VnaCB0aGUgcGVuZGluZ1xuICAgKiBicm9hZGNhc3QgcXVldWUuXG4gICAqIEByZXR1cm5zIHtOb25OdWxsYWJsZTxpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoZXJPcHRpb25zW1wiYnJvYWRjYXN0ZXJcIl0+fSBCcm9hZGNhc3QgZGVsaXZlcmVyLlxuICAgKi9cbiAgYnJvYWRjYXN0ZXIoKSB7XG4gICAgaWYgKHRoaXMuY29uZmlnLmJyb2FkY2FzdGVyKSByZXR1cm4gdGhpcy5jb25maWcuYnJvYWRjYXN0ZXJcblxuICAgIHJldHVybiBhc3luYyAoe2JvZHksIGNoYW5uZWwsIHBhcmFtc30pID0+IHtcbiAgICAgIHRoaXMuY29uZmlnLmNvbmZpZ3VyYXRpb24uYnJvYWRjYXN0VG9DaGFubmVsKGNoYW5uZWwsIHBhcmFtcywgYm9keSlcbiAgICAgIGF3YWl0IHRoaXMuY29uZmlnLmNvbmZpZ3VyYXRpb24uYXdhaXRQZW5kaW5nQnJvYWRjYXN0cygpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJlcG9ydHMgYSBwb3N0LWNvbW1pdCBwdWJsaXNoIGZhaWx1cmUuIFRoZSB0cmFuc2FjdGlvbiBoYXMgYWxyZWFkeVxuICAgKiBjb21taXR0ZWQgd2hlbiBhZnRlckNvbW1pdCBjYWxsYmFja3MgcnVuLCBzbyByZXRocm93aW5nIGhlcmUgd291bGQgcG9pc29uXG4gICAqIHRoZSBkcml2ZXIncyBhd2FpdGVkIGFmdGVyQ29tbWl0IGNoYWluIChicmVha2luZyB1bnJlbGF0ZWQgY2FsbGJhY2tzKSAtXG4gICAqIGluc3RlYWQgdGhlIGZhaWx1cmUgZ29lcyB0byB0aGUgY29uZmlndXJlZCBvbkVycm9yIGhvb2ssIG9yIGlzIGVtaXR0ZWQgb25cbiAgICogdGhlIGNvbmZpZ3VyYXRpb24ncyBmcmFtZXdvcmstZXJyb3IvYWxsLWVycm9yIGNoYW5uZWxzIChzbyBwcm9kdWN0aW9uIGJ1Z1xuICAgKiByZXBvcnRpbmcgdmlhIGBjb25maWd1cmF0aW9uLmdldEVycm9yRXZlbnRzKClgIHNlZXMgYSBicm9rZW4gcHVibGlzaFxuICAgKiBwYXRoKSBhbmQgbG9nZ2VkIGxvdWRseSB0aHJvdWdoIHRoZSBwdWJsaXNoZXIncyBsb2dnZXIgd2hlbiBub25lIGlzXG4gICAqIGNvbmZpZ3VyZWQuXG4gICAqIEBwYXJhbSB7RXJyb3J9IGVycm9yIC0gUG9zdC1jb21taXQgcHVibGlzaCBmYWlsdXJlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIHJlcG9ydEFmdGVyQ29tbWl0RXJyb3IoZXJyb3IpIHtcbiAgICBpZiAodGhpcy5jb25maWcub25FcnJvcikge1xuICAgICAgdGhpcy5jb25maWcub25FcnJvcihlcnJvcilcblxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgZXJyb3JFdmVudHMgPSB0aGlzLmNvbmZpZy5jb25maWd1cmF0aW9uLmdldEVycm9yRXZlbnRzKClcbiAgICBjb25zdCBwYXlsb2FkID0ge2NvbnRleHQ6IHtzdGFnZTogXCJzeW5jLXB1Ymxpc2gtYWZ0ZXItY29tbWl0XCJ9LCBlcnJvcn1cblxuICAgIGVycm9yRXZlbnRzLmVtaXQoXCJmcmFtZXdvcmstZXJyb3JcIiwgcGF5bG9hZClcbiAgICBlcnJvckV2ZW50cy5lbWl0KFwiYWxsLWVycm9yXCIsIHsuLi5wYXlsb2FkLCBlcnJvclR5cGU6IFwiZnJhbWV3b3JrLWVycm9yXCJ9KVxuXG4gICAgYXdhaXQgdGhpcy5sb2dnZXIoKS5lcnJvcihcIlN5bmNQdWJsaXNoZXIgZmFpbGVkIHRvIHB1Ymxpc2ggYSBzZXJ2ZXItc2lkZSBzeW5jIGNoYW5nZSBhZnRlciBjb21taXRcIiwgZXJyb3IpXG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgbGF6aWx5IGJ1aWx0IHB1Ymxpc2hlciBsb2dnZXIuXG4gICAqIEByZXR1cm5zIHtMb2dnZXJ9IFB1Ymxpc2hlciBsb2dnZXIuXG4gICAqL1xuICBsb2dnZXIoKSB7XG4gICAgdGhpcy5fbG9nZ2VyIHx8PSBuZXcgTG9nZ2VyKFwiU3luY1B1Ymxpc2hlclwiLCB7Y29uZmlndXJhdGlvbjogdGhpcy5jb25maWcuY29uZmlndXJhdGlvbn0pXG5cbiAgICByZXR1cm4gdGhpcy5fbG9nZ2VyXG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlcyBhIG1vZGVsIGNsYXNzJ3MgYWN0aXZlIHB1Ymxpc2ggZGVjbGFyYXRpb24gZnJvbSBgc3RhdGljIHN5bmNgLlxuICogT3B0ZWQtb3V0IChgcHVibGlzaDogZmFsc2VgKSBhbmQgdW5kZWNsYXJlZCBtb2RlbHMgcmVzb2x2ZSB0byBudWxsOyBldmVyeVxuICogb3RoZXIgZGVjbGFyZWQgdmFsdWUgZmxvd3MgaW50byBsb3VkIGRlY2xhcmF0aW9uIHZhbGlkYXRpb24uXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBtb2RlbENsYXNzIC0gUmVnaXN0ZXJlZCBtb2RlbCBjbGFzcy5cbiAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoRGVjbGFyYXRpb24gfCBudWxsfSBBY3RpdmUgcHVibGlzaCBkZWNsYXJhdGlvbiwgb3IgbnVsbC5cbiAqL1xuZnVuY3Rpb24gcHVibGlzaERlY2xhcmF0aW9uRm9yKG1vZGVsQ2xhc3MpIHtcbiAgY29uc3QgZGVjbGFyYXRpb24gPSBtb2RlbENsYXNzLnN5bmNcblxuICBpZiAoIWRlY2xhcmF0aW9uIHx8IHR5cGVvZiBkZWNsYXJhdGlvbiAhPT0gXCJvYmplY3RcIiB8fCBkZWNsYXJhdGlvbi5wdWJsaXNoID09PSB1bmRlZmluZWQgfHwgZGVjbGFyYXRpb24ucHVibGlzaCA9PT0gZmFsc2UpIHJldHVybiBudWxsXG5cbiAgcmV0dXJuIGRlY2xhcmF0aW9uLnB1Ymxpc2hcbn1cblxuLyoqXG4gKiBCdWlsZHMgb25lIHB1Ymxpc2hlZCByZXNvdXJjZSBjb25maWcgZnJvbSBhIG1vZGVsJ3MgYHN0YXRpYyBzeW5jYCBwdWJsaXNoXG4gKiBkZWNsYXJhdGlvbi4gYHB1Ymxpc2g6IHRydWVgIG9wdHMgaW4gd2l0aCBhbGwgZGVmYXVsdHMgKGF0dHJpYnV0ZSBwYXlsb2FkLFxuICogZGVyaXZlZCBzY29wZSBwYXJ0aXRpb24sIGNyZWF0ZWQvdXBkYXRlZCBvcGVyYXRpb25zKS5cbiAqIEBwYXJhbSB7e21vZGVsQ2xhc3M6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+LCBwdWJsaXNoOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoRGVjbGFyYXRpb24gfCBudWxsLCBzY29wZUF0dHJpYnV0ZXM6IHN0cmluZ1tdIHwgbnVsbCwgc3luY01vZGVsOiBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn19IGFyZ3MgLSBEZWNsYXJhdGlvbiBhcmdzIHBsdXMgdGhlIHN5bmMgbW9kZWwncyBkZWNsYXJlZCBzY29wZSBhdHRyaWJ1dGVzLlxuICogQHJldHVybnMge2ltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlclJlc291cmNlQ29uZmlnfSBEZXJpdmVkIHJlc291cmNlIGNvbmZpZy5cbiAqL1xuZnVuY3Rpb24gcmVzb3VyY2VDb25maWdGcm9tUHVibGlzaERlY2xhcmF0aW9uKHttb2RlbENsYXNzLCBwdWJsaXNoLCBzY29wZUF0dHJpYnV0ZXM6IHN5bmNTY29wZUF0dHJpYnV0ZXMsIHN5bmNNb2RlbH0pIHtcbiAgY29uc3QgbW9kZWxOYW1lID0gbW9kZWxDbGFzcy5nZXRNb2RlbE5hbWUoKVxuICBjb25zdCBub3JtYWxpemVkUHVibGlzaCA9IHB1Ymxpc2ggPT09IHRydWUgPyB7fSA6IHB1Ymxpc2hcblxuICBpZiAoIW5vcm1hbGl6ZWRQdWJsaXNoIHx8IHR5cGVvZiBub3JtYWxpemVkUHVibGlzaCAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KG5vcm1hbGl6ZWRQdWJsaXNoKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggbXVzdCBiZSB0cnVlLCBmYWxzZSBvciBhIHB1Ymxpc2ggZGVjbGFyYXRpb24gb2JqZWN0LCBnb3Q6ICR7U3RyaW5nKHB1Ymxpc2gpfWApXG4gIH1cblxuICBjb25zdCB7YnJvYWRjYXN0cywgZXZlbnRJZCwgb3BlcmF0aW9ucywgcmVzb3VyY2VUeXBlLCBzY29wZUF0dHJpYnV0ZXMsIHNlcmlhbGl6ZSwgLi4ucmVzdERlY2xhcmF0aW9ufSA9IG5vcm1hbGl6ZWRQdWJsaXNoXG4gIGNvbnN0IHVua25vd25LZXlzID0gT2JqZWN0LmtleXMocmVzdERlY2xhcmF0aW9uKVxuXG4gIGlmICh1bmtub3duS2V5cy5sZW5ndGggPiAwKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCByZWNlaXZlZCB1bmtub3duIGtleXM6ICR7dW5rbm93bktleXMuam9pbihcIiwgXCIpfSAoc3VwcG9ydGVkOiBicm9hZGNhc3RzLCBldmVudElkIChkZXByZWNhdGVkKSwgb3BlcmF0aW9ucywgcmVzb3VyY2VUeXBlLCBzY29wZUF0dHJpYnV0ZXMsIHNlcmlhbGl6ZSlgKVxuICB9XG4gIGlmIChzZXJpYWxpemUgIT09IHVuZGVmaW5lZCAmJiB0eXBlb2Ygc2VyaWFsaXplICE9PSBcImZ1bmN0aW9uXCIpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIHNlcmlhbGl6ZSBtdXN0IGJlIGEgZnVuY3Rpb24gYnVpbGRpbmcgdGhlIHB1Ymxpc2hlZCBwYXlsb2FkLCBnb3Q6ICR7U3RyaW5nKHNlcmlhbGl6ZSl9YClcbiAgfVxuICBpZiAob3BlcmF0aW9ucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKCFBcnJheS5pc0FycmF5KG9wZXJhdGlvbnMpIHx8IG9wZXJhdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIG9wZXJhdGlvbnMgbXVzdCBiZSBhIG5vbi1lbXB0eSBhcnJheSBvZiBjcmVhdGUvdXBkYXRlL2Rlc3Ryb3lgKVxuICAgIH1cblxuICAgIGZvciAoY29uc3Qgb3BlcmF0aW9uIG9mIG9wZXJhdGlvbnMpIHtcbiAgICAgIGlmICghKG9wZXJhdGlvbiBpbiBQVUJMSVNIRURfQ0FMTEJBQ0tfTkFNRVMpKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggb3BlcmF0aW9ucyBtdXN0IGJlIGNyZWF0ZS91cGRhdGUvZGVzdHJveSwgZ290OiAke1N0cmluZyhvcGVyYXRpb24pfWApXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY29uc3Qgc2NvcGVQbGFuID0gc2NvcGVQbGFuRm9yKHtldmVudElkLCBtb2RlbENsYXNzLCBtb2RlbE5hbWUsIHNjb3BlQXR0cmlidXRlcywgc3luY01vZGVsLCBzeW5jU2NvcGVBdHRyaWJ1dGVzfSlcblxuICByZXR1cm4ge1xuICAgIGJyb2FkY2FzdHMsXG4gICAgbW9kZWxDbGFzcyxcbiAgICBvcGVyYXRpb25zOiBvcGVyYXRpb25zID09PSB1bmRlZmluZWQgPyBERUZBVUxUX1BVQkxJU0hFRF9PUEVSQVRJT05TIDogb3BlcmF0aW9ucyxcbiAgICByZXNvdXJjZVR5cGU6IHJlc291cmNlVHlwZSA9PT0gdW5kZWZpbmVkID8gbW9kZWxOYW1lIDogcmVzb3VyY2VUeXBlLFxuICAgIHNjb3BlQXR0cmlidXRlc1Jlc29sdmVyOiB0eXBlb2Ygc2NvcGVBdHRyaWJ1dGVzID09PSBcImZ1bmN0aW9uXCIgPyBzY29wZUF0dHJpYnV0ZXMgOiB1bmRlZmluZWQsXG4gICAgc2NvcGVQbGFuLFxuICAgIHNlcmlhbGl6ZTogc2VyaWFsaXplID09PSB1bmRlZmluZWQgPyBkZWZhdWx0U2VyaWFsaXplZEF0dHJpYnV0ZXMgOiBzZXJpYWxpemVcbiAgfVxufVxuXG4vKipcbiAqIERlcml2ZXMgdGhlIHNjb3BlIHBsYW4gcGFydGl0aW9uaW5nIGEgcHVibGlzaGVkIG1vZGVsJ3MgY2hhbmdlczogb25lIGVudHJ5XG4gKiBwZXIgc2NvcGUgYXR0cmlidXRlIGRlY2xhcmVkIG9uIHRoZSBzeW5jIG1vZGVsIChgc3RhdGljXG4gKiBzeW5jU2NvcGVBdHRyaWJ1dGVzYCksIGVhY2ggcmVhZGluZyB0aGUgcmVjb3JkIGF0dHJpYnV0ZSBuYW1lZCBsaWtlIHRoZVxuICogc2NvcGUgYXR0cmlidXRlIChvdmVycmlkYWJsZSB0aHJvdWdoIHRoZSBkZWNsYXJhdGlvbidzIGBzY29wZUF0dHJpYnV0ZXNgXG4gKiBuYW1lIG1hcCksIG9yIHRoZSByZWNvcmQncyBvd24gaWQgd2hlbiB0aGUgbW9kZWwgaGFzIG5vIHN1Y2ggYXR0cmlidXRlXG4gKiAoc2NvcGUtcm9vdCBtb2RlbHMpLiBUaGUgZGVwcmVjYXRlZCBgZXZlbnRJZGAgZGVjbGFyYXRpb24gZm9ybXMgbWFwIHRvIGFcbiAqIGZpeGVkIGBldmVudElkYC9gZXZlbnRfaWRgIHBsYW4gZm9yIDEuMC41MDMgY29tcGF0aWJpbGl0eS5cbiAqIEBwYXJhbSB7e2V2ZW50SWQ6IGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hEZWNsYXJhdGlvbkNvbmZpZ1tcImV2ZW50SWRcIl0sIG1vZGVsQ2xhc3M6IFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+LCBtb2RlbE5hbWU6IHN0cmluZywgc2NvcGVBdHRyaWJ1dGVzOiBpbXBvcnQoXCIuL3N5bmMtcHVibGlzaGVyLXR5cGVzLmpzXCIpLlN5bmNQdWJsaXNoRGVjbGFyYXRpb25Db25maWdbXCJzY29wZUF0dHJpYnV0ZXNcIl0sIHN5bmNNb2RlbDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4sIHN5bmNTY29wZUF0dHJpYnV0ZXM6IHN0cmluZ1tdIHwgbnVsbH19IGFyZ3MgLSBEZWNsYXJhdGlvbiBhbmQgc3luYy1tb2RlbCBzY29wZSBhcmdzLlxuICogQHJldHVybnMge0FycmF5PGltcG9ydChcIi4vc3luYy1wdWJsaXNoZXItdHlwZXMuanNcIikuU3luY1B1Ymxpc2hlclNjb3BlUGxhbkVudHJ5Pn0gRGVyaXZlZCBzY29wZSBwbGFuLlxuICovXG5mdW5jdGlvbiBzY29wZVBsYW5Gb3Ioe2V2ZW50SWQsIG1vZGVsQ2xhc3MsIG1vZGVsTmFtZSwgc2NvcGVBdHRyaWJ1dGVzLCBzeW5jTW9kZWwsIHN5bmNTY29wZUF0dHJpYnV0ZXN9KSB7XG4gIGNvbnN0IGF0dHJpYnV0ZU5hbWVzID0gT2JqZWN0LnZhbHVlcyhtb2RlbENsYXNzLmdldENvbHVtbk5hbWVUb0F0dHJpYnV0ZU5hbWVNYXAoKSlcblxuICBpZiAoZXZlbnRJZCAhPT0gdW5kZWZpbmVkKSB7XG4gICAgaWYgKHNjb3BlQXR0cmlidXRlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYCR7bW9kZWxOYW1lfSBzdGF0aWMgc3luYyBwdWJsaXNoIGNhbid0IGRlY2xhcmUgYm90aCBzY29wZUF0dHJpYnV0ZXMgYW5kIHRoZSBkZXByZWNhdGVkIGV2ZW50SWQgZm9ybWApXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZXZlbnRJZCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICByZXR1cm4gW3tjb2x1bW5OYW1lOiBcImV2ZW50X2lkXCIsIHJlY29yZEF0dHJpYnV0ZTogbnVsbCwgcmVzb2x2ZXI6IGV2ZW50SWQsIHNjb3BlQXR0cmlidXRlOiBcImV2ZW50SWRcIn1dXG4gICAgfVxuICAgIGlmICh0eXBlb2YgZXZlbnRJZCAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBldmVudElkIG11c3QgYmUgYW4gYXR0cmlidXRlLW5hbWUgc3RyaW5nIChvciBhIGRlcHJlY2F0ZWQgcmVzb2x2ZXIgZnVuY3Rpb24pLCBnb3Q6ICR7U3RyaW5nKGV2ZW50SWQpfWApXG4gICAgfVxuICAgIGlmICghYXR0cmlidXRlTmFtZXMuaW5jbHVkZXMoZXZlbnRJZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHttb2RlbE5hbWV9IHN0YXRpYyBzeW5jIHB1Ymxpc2ggZXZlbnRJZCBhdHRyaWJ1dGUgZG9lc24ndCBleGlzdCBvbiB0aGUgbW9kZWw6ICR7ZXZlbnRJZH1gKVxuICAgIH1cblxuICAgIHJldHVybiBbe2NvbHVtbk5hbWU6IFwiZXZlbnRfaWRcIiwgcmVjb3JkQXR0cmlidXRlOiBldmVudElkLCByZXNvbHZlcjogdW5kZWZpbmVkLCBzY29wZUF0dHJpYnV0ZTogXCJldmVudElkXCJ9XVxuICB9XG5cbiAgaWYgKHNjb3BlQXR0cmlidXRlcyAhPT0gdW5kZWZpbmVkICYmICFzeW5jU2NvcGVBdHRyaWJ1dGVzKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBkZWNsYXJlcyBzY29wZUF0dHJpYnV0ZXMgYnV0IHRoZSBzeW5jIG1vZGVsIGRlY2xhcmVzIG5vIHN0YXRpYyBzeW5jU2NvcGVBdHRyaWJ1dGVzYClcbiAgfVxuXG4gIGlmICghc3luY1Njb3BlQXR0cmlidXRlcykgcmV0dXJuIFtdXG5cbiAgaWYgKHR5cGVvZiBzY29wZUF0dHJpYnV0ZXMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgIHJldHVybiBzeW5jU2NvcGVBdHRyaWJ1dGVzLm1hcCgoc2NvcGVBdHRyaWJ1dGUpID0+ICh7XG4gICAgICBjb2x1bW5OYW1lOiBzeW5jU2NvcGVDb2x1bW5OYW1lKHtzY29wZUF0dHJpYnV0ZSwgc3luY01vZGVsfSksXG4gICAgICByZWNvcmRBdHRyaWJ1dGU6IG51bGwsXG4gICAgICByZXNvbHZlcjogdW5kZWZpbmVkLFxuICAgICAgc2NvcGVBdHRyaWJ1dGVcbiAgICB9KSlcbiAgfVxuXG4gIGlmIChzY29wZUF0dHJpYnV0ZXMgIT09IHVuZGVmaW5lZCAmJiAodHlwZW9mIHNjb3BlQXR0cmlidXRlcyAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHNjb3BlQXR0cmlidXRlcykpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzY29wZUF0dHJpYnV0ZXMgbXVzdCBiZSBhbiBvYmplY3QgbWFwcGluZyBzY29wZSBhdHRyaWJ1dGVzIHRvIHJlY29yZCBhdHRyaWJ1dGUgbmFtZXMsIGdvdDogJHtTdHJpbmcoc2NvcGVBdHRyaWJ1dGVzKX1gKVxuICB9XG5cbiAgZm9yIChjb25zdCBzY29wZUF0dHJpYnV0ZSBvZiBPYmplY3Qua2V5cyhzY29wZUF0dHJpYnV0ZXMgfHwge30pKSB7XG4gICAgaWYgKCFzeW5jU2NvcGVBdHRyaWJ1dGVzLmluY2x1ZGVzKHNjb3BlQXR0cmlidXRlKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzY29wZUF0dHJpYnV0ZXMgcmVjZWl2ZWQgdW5rbm93biBzY29wZSBhdHRyaWJ1dGU6ICR7c2NvcGVBdHRyaWJ1dGV9ICh0aGUgc3luYyBtb2RlbCBkZWNsYXJlczogJHtzeW5jU2NvcGVBdHRyaWJ1dGVzLmpvaW4oXCIsIFwiKX0pYClcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3luY1Njb3BlQXR0cmlidXRlcy5tYXAoKHNjb3BlQXR0cmlidXRlKSA9PiB7XG4gICAgY29uc3QgZGVjbGFyZWRSZWNvcmRBdHRyaWJ1dGUgPSBzY29wZUF0dHJpYnV0ZXM/LltzY29wZUF0dHJpYnV0ZV1cblxuICAgIGlmIChkZWNsYXJlZFJlY29yZEF0dHJpYnV0ZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICBpZiAodHlwZW9mIGRlY2xhcmVkUmVjb3JkQXR0cmlidXRlICE9PSBcInN0cmluZ1wiIHx8ICFhdHRyaWJ1dGVOYW1lcy5pbmNsdWRlcyhkZWNsYXJlZFJlY29yZEF0dHJpYnV0ZSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke21vZGVsTmFtZX0gc3RhdGljIHN5bmMgcHVibGlzaCBzY29wZUF0dHJpYnV0ZXMuJHtzY29wZUF0dHJpYnV0ZX0gbXVzdCBuYW1lIGFuIGV4aXN0aW5nIHJlY29yZCBhdHRyaWJ1dGUsIGdvdDogJHtTdHJpbmcoZGVjbGFyZWRSZWNvcmRBdHRyaWJ1dGUpfWApXG4gICAgICB9XG5cbiAgICAgIHJldHVybiB7Y29sdW1uTmFtZTogc3luY1Njb3BlQ29sdW1uTmFtZSh7c2NvcGVBdHRyaWJ1dGUsIHN5bmNNb2RlbH0pLCByZWNvcmRBdHRyaWJ1dGU6IGRlY2xhcmVkUmVjb3JkQXR0cmlidXRlLCByZXNvbHZlcjogdW5kZWZpbmVkLCBzY29wZUF0dHJpYnV0ZX1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgY29sdW1uTmFtZTogc3luY1Njb3BlQ29sdW1uTmFtZSh7c2NvcGVBdHRyaWJ1dGUsIHN5bmNNb2RlbH0pLFxuICAgICAgcmVjb3JkQXR0cmlidXRlOiBhdHRyaWJ1dGVOYW1lcy5pbmNsdWRlcyhzY29wZUF0dHJpYnV0ZSkgPyBzY29wZUF0dHJpYnV0ZSA6IG51bGwsXG4gICAgICByZXNvbHZlcjogdW5kZWZpbmVkLFxuICAgICAgc2NvcGVBdHRyaWJ1dGVcbiAgICB9XG4gIH0pXG59XG5cbi8qKlxuICogQ2hlY2tzIHRoYXQgYSBjb21wdXRlZCBkZWNsYXJhdGlvbiByZXR1cm5lZCBhbiBvcmRpbmFyeSBrZXkvdmFsdWUgb2JqZWN0LlxuICogQHBhcmFtIHt1bmtub3dufSB2YWx1ZSAtIFJlc29sdmVyIHJlc3VsdC5cbiAqIEByZXR1cm5zIHt2YWx1ZSBpcyBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPn0gV2hldGhlciB0aGUgdmFsdWUgaXMgYSBwbGFpbiBvYmplY3QuXG4gKi9cbmZ1bmN0aW9uIGlzUGxhaW5PYmplY3QodmFsdWUpIHtcbiAgaWYgKCF2YWx1ZSB8fCB0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheSh2YWx1ZSkpIHJldHVybiBmYWxzZVxuXG4gIGNvbnN0IHByb3RvdHlwZSA9IE9iamVjdC5nZXRQcm90b3R5cGVPZih2YWx1ZSlcblxuICByZXR1cm4gcHJvdG90eXBlID09PSBPYmplY3QucHJvdG90eXBlIHx8IHByb3RvdHlwZSA9PT0gbnVsbFxufVxuXG4vKipcbiAqIFJlc29sdmVzIHRoZSBzeW5jLXJvdyBjb2x1bW4gcGVyc2lzdGluZyBhIGRlY2xhcmVkIHNjb3BlIGF0dHJpYnV0ZS5cbiAqIEBwYXJhbSB7e3Njb3BlQXR0cmlidXRlOiBzdHJpbmcsIHN5bmNNb2RlbDogUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT59fSBhcmdzIC0gU2NvcGUgYXR0cmlidXRlIGFuZCBzeW5jIG1vZGVsLlxuICogQHJldHVybnMge3N0cmluZ30gU3luYy1yb3cgY29sdW1uIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIHN5bmNTY29wZUNvbHVtbk5hbWUoe3Njb3BlQXR0cmlidXRlLCBzeW5jTW9kZWx9KSB7XG4gIGNvbnN0IGNvbHVtbk5hbWUgPSBzeW5jTW9kZWwuZ2V0QXR0cmlidXRlTmFtZVRvQ29sdW1uTmFtZU1hcCgpW3Njb3BlQXR0cmlidXRlXVxuXG4gIGlmICghY29sdW1uTmFtZSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgJHtzeW5jTW9kZWwubmFtZX0gZGVjbGFyZXMgdGhlIHN5bmMgc2NvcGUgYXR0cmlidXRlICR7c2NvcGVBdHRyaWJ1dGV9IGJ1dCBoYXMgbm8gbWF0Y2hpbmcgY29sdW1uIGZvciBpdGApXG4gIH1cblxuICByZXR1cm4gY29sdW1uTmFtZVxufVxuXG4vKipcbiAqIERlZmF1bHQgcHVibGlzaCBzZXJpYWxpemVyOiB0aGUgcmVjb3JkJ3MgYXR0cmlidXRlcyB3aXRoIERhdGUgdmFsdWVzXG4gKiBzZXJpYWxpemVkIHRvIElTTyBzdHJpbmdzLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gcmVjb3JkIC0gTXV0YXRlZCBzZXJ2ZXIgbW9kZWwgcmVjb3JkLlxuICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsIFJldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+Pn0gU2VyaWFsaXplZCBhdHRyaWJ1dGVzIHBheWxvYWQuXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRTZXJpYWxpemVkQXR0cmlidXRlcyhyZWNvcmQpIHtcbiAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovXG4gIGNvbnN0IGF0dHJpYnV0ZXMgPSB7Li4ucmVjb3JkLmF0dHJpYnV0ZXMoKX1cblxuICBmb3IgKGNvbnN0IFthdHRyaWJ1dGVOYW1lLCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoYXR0cmlidXRlcykpIHtcbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSBhdHRyaWJ1dGVzW2F0dHJpYnV0ZU5hbWVdID0gdmFsdWUudG9JU09TdHJpbmcoKVxuICB9XG5cbiAgcmV0dXJuIGF0dHJpYnV0ZXNcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyBhIGRhdGUtbGlrZSB2YWx1ZSB0byBhbiBJU08gc3RyaW5nLCBtYXRjaGluZyB0aGUgY2hhbmdlLWZlZWRcbiAqIHNlcmlhbGl6ZXIncyBjb252ZW50aW9uIGZvciB0aGUgc3luYyBlbnRyeSdzIHB1YmxpYyB1cGRhdGVkLWF0IG1ldGFkYXRhLlxuICogQHBhcmFtIHtEYXRlIHwgbnVsbH0gdmFsdWUgLSBQZXJzaXN0ZWQgdXBkYXRlZC1hdCB2YWx1ZS5cbiAqIEByZXR1cm5zIHtzdHJpbmd9IElTTyBkYXRlLlxuICogQHRocm93cyB7RXJyb3J9IFdoZW4gdGhlIHBlcnNpc3RlZCByb3cgaGFzIG5vIHZhbGlkIHVwZGF0ZWQtYXQgdGltZXN0YW1wLlxuICovXG5mdW5jdGlvbiBpc29EYXRlKHZhbHVlKSB7XG4gIGlmICghKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgfHwgTnVtYmVyLmlzTmFOKHZhbHVlLmdldFRpbWUoKSkpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJQdWJsaXNoZWQgc3luYyByb3cgbXVzdCBoYXZlIGEgdmFsaWQgdXBkYXRlZEF0IHRpbWVzdGFtcC5cIilcbiAgfVxuXG4gIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpXG59XG4iXX0=
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Atomically reconciles and upserts one server-origin sync row by its complete,
3
+ * null-safe logical identity. The identity contains the null actor, resource
4
+ * type/id, and either every scope column declared by the sync model or the
5
+ * caller's explicit effective scope columns for a supported legacy publisher.
6
+ * A stable portable advisory lock serializes runtime publication and maintenance/backfill calls;
7
+ * legacy duplicates converge to the newest server sequence, then the lowest
8
+ * immutable id, before the survivor is updated and re-sequenced.
9
+ *
10
+ * The lock is acquired through the static sync model on a dedicated connection.
11
+ * `persistenceModel` may be an operation-bound model facade so reads/writes keep
12
+ * their owning operation while sharing the same identity lock as ordinary
13
+ * publisher calls.
14
+ * @param {object} args - Persistence arguments.
15
+ * @param {string} [args.actorForeignKeyColumn] - Persisted actor foreign-key column.
16
+ * @param {Record<string, ReturnType<typeof JSON.parse>>} args.attributes - Complete sync-row mutation attributes.
17
+ * @param {ReturnType<typeof JSON.parse>} [args.persistenceModel] - Optional operation-bound model used for row reads/writes.
18
+ * @param {string[]} [args.scopeColumnNames] - Exact persisted scope columns overriding model declarations for a supported legacy publisher identity.
19
+ * @param {ReturnType<typeof JSON.parse>} args.syncModel - Static sync model owning scope metadata and the advisory lock.
20
+ * @returns {Promise<ReturnType<typeof JSON.parse>>} Created or reconciled sync row.
21
+ */
22
+ export declare function upsertServerOriginSyncRow({ actorForeignKeyColumn, attributes, persistenceModel, scopeColumnNames, syncModel, ...restArgs }: {
23
+ actorForeignKeyColumn?: string;
24
+ attributes: Record<string, ReturnType<typeof JSON.parse>>;
25
+ persistenceModel?: ReturnType<typeof JSON.parse>;
26
+ scopeColumnNames?: string[];
27
+ syncModel: ReturnType<typeof JSON.parse>;
28
+ }): Promise<ReturnType<typeof JSON.parse>>;
29
+ //# sourceMappingURL=upsert-server-origin-sync-row.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"upsert-server-origin-sync-row.d.ts","sourceRoot":"","sources":["../../../src/sync/upsert-server-origin-sync-row.js"],"names":[],"mappings":"AASA;;;;;;;;;;;;;;;;;;;;GAoBG;AACH,wBAAsB,yBAAyB,CAAC,EAC9C,qBAAiD,EACjD,UAAU,EACV,gBAAgB,EAChB,gBAAgB,EAChB,SAAS,EACT,GAAG,QAAQ,EACZ,EAdE;IAAsB,qBAAqB,AAA3C,CACA,EADQ,MAAM,CACd;IAA4D,UAAU,EAA9D,MAAM,CAAC,MAAM,EAAE,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CACrD;IAA6C,gBAAgB,AAA7D,CACA,EADQ,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACrC;IAAwB,gBAAgB,AAAxC,CACA,EADQ,MAAM,EAAE,CAChB;IAA4C,SAAS,EAA7C,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CACrC;CASF,GATY,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAoFlD"}
@@ -0,0 +1,128 @@
1
+ // @ts-check
2
+ import restArgsError from "../utils/rest-args-error.js";
3
+ import sha256Hex from "../utils/sha256-hex.js";
4
+ import stableJsonStringify from "../utils/stable-json.js";
5
+ import { upsertSyncRow } from "./sync-change-fanout.js";
6
+ import { declaredSyncScopeAttributes } from "./sync-scope-attributes.js";
7
+ /**
8
+ * Atomically reconciles and upserts one server-origin sync row by its complete,
9
+ * null-safe logical identity. The identity contains the null actor, resource
10
+ * type/id, and either every scope column declared by the sync model or the
11
+ * caller's explicit effective scope columns for a supported legacy publisher.
12
+ * A stable portable advisory lock serializes runtime publication and maintenance/backfill calls;
13
+ * legacy duplicates converge to the newest server sequence, then the lowest
14
+ * immutable id, before the survivor is updated and re-sequenced.
15
+ *
16
+ * The lock is acquired through the static sync model on a dedicated connection.
17
+ * `persistenceModel` may be an operation-bound model facade so reads/writes keep
18
+ * their owning operation while sharing the same identity lock as ordinary
19
+ * publisher calls.
20
+ * @param {object} args - Persistence arguments.
21
+ * @param {string} [args.actorForeignKeyColumn] - Persisted actor foreign-key column.
22
+ * @param {Record<string, ReturnType<typeof JSON.parse>>} args.attributes - Complete sync-row mutation attributes.
23
+ * @param {ReturnType<typeof JSON.parse>} [args.persistenceModel] - Optional operation-bound model used for row reads/writes.
24
+ * @param {string[]} [args.scopeColumnNames] - Exact persisted scope columns overriding model declarations for a supported legacy publisher identity.
25
+ * @param {ReturnType<typeof JSON.parse>} args.syncModel - Static sync model owning scope metadata and the advisory lock.
26
+ * @returns {Promise<ReturnType<typeof JSON.parse>>} Created or reconciled sync row.
27
+ */
28
+ export async function upsertServerOriginSyncRow({ actorForeignKeyColumn = "authentication_token_id", attributes, persistenceModel, scopeColumnNames, syncModel, ...restArgs }) {
29
+ restArgsError(restArgs);
30
+ if (typeof actorForeignKeyColumn !== "string" || !actorForeignKeyColumn) {
31
+ throw new Error("Server-origin sync row actorForeignKeyColumn must be a non-empty string");
32
+ }
33
+ if (!attributes || typeof attributes !== "object" || Array.isArray(attributes)) {
34
+ throw new Error("Server-origin sync row attributes must be a plain object");
35
+ }
36
+ if (!Object.hasOwn(attributes, actorForeignKeyColumn) || attributes[actorForeignKeyColumn] === undefined) {
37
+ throw new Error(`Server-origin sync row identity must include the actor column ${actorForeignKeyColumn}`);
38
+ }
39
+ if (attributes[actorForeignKeyColumn] !== null) {
40
+ throw new Error(`Server-origin sync row actor column ${actorForeignKeyColumn} must be null`);
41
+ }
42
+ validateRequiredIdentityString({ attributes, columnName: "resource_id" });
43
+ validateRequiredIdentityString({ attributes, columnName: "resource_type" });
44
+ /** @type {Record<string, ReturnType<typeof JSON.parse>>} */
45
+ const identity = {
46
+ [actorForeignKeyColumn]: null,
47
+ resource_id: attributes.resource_id,
48
+ resource_type: attributes.resource_type
49
+ };
50
+ const attributeToColumnName = syncModel.getAttributeNameToColumnNameMap();
51
+ const scopeColumns = new Set(scopeColumnNames || []);
52
+ if (scopeColumnNames === undefined) {
53
+ for (const scopeAttribute of declaredSyncScopeAttributes(syncModel) || []) {
54
+ const columnName = attributeToColumnName[scopeAttribute];
55
+ if (!columnName) {
56
+ throw new Error(`${syncModel.name} declares the sync scope attribute ${scopeAttribute} but has no matching column for it`);
57
+ }
58
+ scopeColumns.add(columnName);
59
+ }
60
+ }
61
+ for (const columnName of scopeColumns) {
62
+ if (typeof columnName !== "string" || !columnName || !Object.values(attributeToColumnName).includes(columnName)) {
63
+ throw new Error(`Server-origin sync row received an unknown scope column: ${String(columnName)}`);
64
+ }
65
+ if (!Object.hasOwn(attributes, columnName) || attributes[columnName] === undefined) {
66
+ throw new Error(`Server-origin sync row identity must include the declared scope column ${columnName}`);
67
+ }
68
+ const value = attributes[columnName];
69
+ if (value !== null && typeof value !== "string" && (typeof value !== "number" || !Number.isFinite(value))) {
70
+ throw new Error(`Server-origin sync row scope column ${columnName} must be a string, finite number, or null`);
71
+ }
72
+ identity[columnName] = value;
73
+ }
74
+ const rowModel = persistenceModel || syncModel;
75
+ return await syncModel.withAdvisoryLock(serverOriginSyncRowLockName(identity), async () => {
76
+ const matchingSyncs = await rowModel
77
+ .where(identity)
78
+ .toArray();
79
+ matchingSyncs.sort(compareServerOriginSyncRowsByRecency);
80
+ const [existingSync, ...duplicateSyncs] = matchingSyncs;
81
+ for (const duplicateSync of duplicateSyncs) {
82
+ await duplicateSync.destroy();
83
+ }
84
+ return await upsertSyncRow({ attributes, existingSync, syncModel: rowModel });
85
+ }, { dedicatedConnection: true });
86
+ }
87
+ /**
88
+ * Validates one required string component of the server-origin identity.
89
+ * @param {{attributes: Record<string, ReturnType<typeof JSON.parse>>, columnName: "resource_id" | "resource_type"}} args - Attributes and required column.
90
+ * @returns {void}
91
+ */
92
+ function validateRequiredIdentityString({ attributes, columnName }) {
93
+ const value = attributes[columnName];
94
+ if (typeof value !== "string" || !value) {
95
+ throw new Error(`Server-origin sync row ${columnName} must be a non-empty string`);
96
+ }
97
+ }
98
+ /**
99
+ * Returns the stable MySQL-safe advisory-lock name shared by every caller of a
100
+ * complete server-origin identity. Stable JSON preserves null identity values,
101
+ * while the truncated SHA-256 digest keeps the name under GET_LOCK's limit.
102
+ * @param {Record<string, ReturnType<typeof JSON.parse>>} identity - Complete sync-row identity in column form.
103
+ * @returns {string} Advisory-lock name.
104
+ */
105
+ function serverOriginSyncRowLockName(identity) {
106
+ const hash = sha256Hex(stableJsonStringify(identity)).slice(0, 32);
107
+ return `vsp:${hash}`;
108
+ }
109
+ /**
110
+ * Orders matching rows with the canonical deterministic survivor first:
111
+ * newest server sequence, then lowest immutable id. A null legacy sequence is
112
+ * older than every assigned sequence.
113
+ * @param {ReturnType<typeof JSON.parse>} left - First matching sync row.
114
+ * @param {ReturnType<typeof JSON.parse>} right - Second matching sync row.
115
+ * @returns {number} Sort comparison.
116
+ */
117
+ function compareServerOriginSyncRowsByRecency(left, right) {
118
+ const leftSequence = left.serverSequence();
119
+ const rightSequence = right.serverSequence();
120
+ if (leftSequence === null && rightSequence !== null)
121
+ return 1;
122
+ if (leftSequence !== null && rightSequence === null)
123
+ return -1;
124
+ if (leftSequence !== rightSequence)
125
+ return rightSequence - leftSequence;
126
+ return left.id().localeCompare(right.id());
127
+ }
128
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXBzZXJ0LXNlcnZlci1vcmlnaW4tc3luYy1yb3cuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc3luYy91cHNlcnQtc2VydmVyLW9yaWdpbi1zeW5jLXJvdy5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxhQUFhLE1BQU0sNkJBQTZCLENBQUE7QUFDdkQsT0FBTyxTQUFTLE1BQU0sd0JBQXdCLENBQUE7QUFDOUMsT0FBTyxtQkFBbUIsTUFBTSx5QkFBeUIsQ0FBQTtBQUV6RCxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0seUJBQXlCLENBQUE7QUFDckQsT0FBTyxFQUFDLDJCQUEyQixFQUFDLE1BQU0sNEJBQTRCLENBQUE7QUFFdEU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSx5QkFBeUIsQ0FBQyxFQUM5QyxxQkFBcUIsR0FBRyx5QkFBeUIsRUFDakQsVUFBVSxFQUNWLGdCQUFnQixFQUNoQixnQkFBZ0IsRUFDaEIsU0FBUyxFQUNULEdBQUcsUUFBUSxFQUNaO0lBQ0MsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFBO0lBRXZCLElBQUksT0FBTyxxQkFBcUIsS0FBSyxRQUFRLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFDO1FBQ3hFLE1BQU0sSUFBSSxLQUFLLENBQUMseUVBQXlFLENBQUMsQ0FBQTtJQUM1RixDQUFDO0lBQ0QsSUFBSSxDQUFDLFVBQVUsSUFBSSxPQUFPLFVBQVUsS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDO1FBQy9FLE1BQU0sSUFBSSxLQUFLLENBQUMsMERBQTBELENBQUMsQ0FBQTtJQUM3RSxDQUFDO0lBQ0QsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLHFCQUFxQixDQUFDLElBQUksVUFBVSxDQUFDLHFCQUFxQixDQUFDLEtBQUssU0FBUyxF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SUFFNUMsSUFBSSxZQUFZLEtBQUssSUFBSSxJQUFJLGFBQWEsS0FBSyxJQUFJO1FBQUUsT0FBTyxDQUFDLENBQUE7SUFDN0QsSUFBSSxZQUFZLEtBQUssSUFBSSxJQUFJLGFBQWEsS0FBSyxJQUFJO1FBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQTtJQUM5RCxJQUFJLFlBQVksS0FBSyxhQUFhO1FBQUUsT0FBTyxhQUFhLEdBQUcsWUFBWSxDQUFBO0lBRXZFLE9BQU8sSUFBSSxDQUFDLEVBQUUsRUFBRSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQTtBQUM1QyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCByZXN0QXJnc0Vycm9yIGZyb20gXCIuLi91dGlscy9yZXN0LWFyZ3MtZXJyb3IuanNcIlxuaW1wb3J0IHNoYTI1NkhleCBmcm9tIFwiLi4vdXRpbHMvc2hhMjU2LWhleC5qc1wiXG5pbXBvcnQgc3RhYmxlSnNvblN0cmluZ2lmeSBmcm9tIFwiLi4vdXRpbHMvc3RhYmxlLWpzb24uanNcIlxuXG5pbXBvcnQge3Vwc2VydFN5bmNSb3d9IGZyb20gXCIuL3N5bmMtY2hhbmdlLWZhbm91dC5qc1wiXG5pbXBvcnQge2RlY2xhcmVkU3luY1Njb3BlQXR0cmlidXRlc30gZnJvbSBcIi4vc3luYy1zY29wZS1hdHRyaWJ1dGVzLmpzXCJcblxuLyoqXG4gKiBBdG9taWNhbGx5IHJlY29uY2lsZXMgYW5kIHVwc2VydHMgb25lIHNlcnZlci1vcmlnaW4gc3luYyByb3cgYnkgaXRzIGNvbXBsZXRlLFxuICogbnVsbC1zYWZlIGxvZ2ljYWwgaWRlbnRpdHkuIFRoZSBpZGVudGl0eSBjb250YWlucyB0aGUgbnVsbCBhY3RvciwgcmVzb3VyY2VcbiAqIHR5cGUvaWQsIGFuZCBlaXRoZXIgZXZlcnkgc2NvcGUgY29sdW1uIGRlY2xhcmVkIGJ5IHRoZSBzeW5jIG1vZGVsIG9yIHRoZVxuICogY2FsbGVyJ3MgZXhwbGljaXQgZWZmZWN0aXZlIHNjb3BlIGNvbHVtbnMgZm9yIGEgc3VwcG9ydGVkIGxlZ2FjeSBwdWJsaXNoZXIuXG4gKiBBIHN0YWJsZSBwb3J0YWJsZSBhZHZpc29yeSBsb2NrIHNlcmlhbGl6ZXMgcnVudGltZSBwdWJsaWNhdGlvbiBhbmQgbWFpbnRlbmFuY2UvYmFja2ZpbGwgY2FsbHM7XG4gKiBsZWdhY3kgZHVwbGljYXRlcyBjb252ZXJnZSB0byB0aGUgbmV3ZXN0IHNlcnZlciBzZXF1ZW5jZSwgdGhlbiB0aGUgbG93ZXN0XG4gKiBpbW11dGFibGUgaWQsIGJlZm9yZSB0aGUgc3Vydml2b3IgaXMgdXBkYXRlZCBhbmQgcmUtc2VxdWVuY2VkLlxuICpcbiAqIFRoZSBsb2NrIGlzIGFjcXVpcmVkIHRocm91Z2ggdGhlIHN0YXRpYyBzeW5jIG1vZGVsIG9uIGEgZGVkaWNhdGVkIGNvbm5lY3Rpb24uXG4gKiBgcGVyc2lzdGVuY2VNb2RlbGAgbWF5IGJlIGFuIG9wZXJhdGlvbi1ib3VuZCBtb2RlbCBmYWNhZGUgc28gcmVhZHMvd3JpdGVzIGtlZXBcbiAqIHRoZWlyIG93bmluZyBvcGVyYXRpb24gd2hpbGUgc2hhcmluZyB0aGUgc2FtZSBpZGVudGl0eSBsb2NrIGFzIG9yZGluYXJ5XG4gKiBwdWJsaXNoZXIgY2FsbHMuXG4gKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIFBlcnNpc3RlbmNlIGFyZ3VtZW50cy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW5dIC0gUGVyc2lzdGVkIGFjdG9yIGZvcmVpZ24ta2V5IGNvbHVtbi5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgUmV0dXJuVHlwZTx0eXBlb2YgSlNPTi5wYXJzZT4+fSBhcmdzLmF0dHJpYnV0ZXMgLSBDb21wbGV0ZSBzeW5jLXJvdyBtdXRhdGlvbiBhdHRyaWJ1dGVzLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gW2FyZ3MucGVyc2lzdGVuY2VNb2RlbF0gLSBPcHRpb25hbCBvcGVyYXRpb24tYm91bmQgbW9kZWwgdXNlZCBmb3Igcm93IHJlYWRzL3dyaXRlcy5cbiAqIEBwYXJhbSB7c3RyaW5nW119IFthcmdzLnNjb3BlQ29sdW1uTmFtZXNdIC0gRXhhY3QgcGVyc2lzdGVkIHNjb3BlIGNvbHVtbnMgb3ZlcnJpZGluZyBtb2RlbCBkZWNsYXJhdGlvbnMgZm9yIGEgc3VwcG9ydGVkIGxlZ2FjeSBwdWJsaXNoZXIgaWRlbnRpdHkuXG4gKiBAcGFyYW0ge1JldHVyblR5cGU8dHlwZW9mIEpTT04ucGFyc2U+fSBhcmdzLnN5bmNNb2RlbCAtIFN0YXRpYyBzeW5jIG1vZGVsIG93bmluZyBzY29wZSBtZXRhZGF0YSBhbmQgdGhlIGFkdmlzb3J5IGxvY2suXG4gKiBAcmV0dXJucyB7UHJvbWlzZTxSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59IENyZWF0ZWQgb3IgcmVjb25jaWxlZCBzeW5jIHJvdy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHVwc2VydFNlcnZlck9yaWdpblN5bmNSb3coe1xuICBhY3RvckZvcmVpZ25LZXlDb2x1bW4gPSBcImF1dGhlbnRpY2F0aW9uX3Rva2VuX2lkXCIsXG4gIGF0dHJpYnV0ZXMsXG4gIHBlcnNpc3RlbmNlTW9kZWwsXG4gIHNjb3BlQ29sdW1uTmFtZXMsXG4gIHN5bmNNb2RlbCxcbiAgLi4ucmVzdEFyZ3Ncbn0pIHtcbiAgcmVzdEFyZ3NFcnJvcihyZXN0QXJncylcblxuICBpZiAodHlwZW9mIGFjdG9yRm9yZWlnbktleUNvbHVtbiAhPT0gXCJzdHJpbmdcIiB8fCAhYWN0b3JGb3JlaWduS2V5Q29sdW1uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKFwiU2VydmVyLW9yaWdpbiBzeW5jIHJvdyBhY3RvckZvcmVpZ25LZXlDb2x1bW4gbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmdcIilcbiAgfVxuICBpZiAoIWF0dHJpYnV0ZXMgfHwgdHlwZW9mIGF0dHJpYnV0ZXMgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShhdHRyaWJ1dGVzKSkge1xuICAgIHRocm93IG5ldyBFcnJvcihcIlNlcnZlci1vcmlnaW4gc3luYyByb3cgYXR0cmlidXRlcyBtdXN0IGJlIGEgcGxhaW4gb2JqZWN0XCIpXG4gIH1cbiAgaWYgKCFPYmplY3QuaGFzT3duKGF0dHJpYnV0ZXMsIGFjdG9yRm9yZWlnbktleUNvbHVtbikgfHwgYXR0cmlidXRlc1thY3RvckZvcmVpZ25LZXlDb2x1bW5dID09PSB1bmRlZmluZWQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFNlcnZlci1vcmlnaW4gc3luYyByb3cgaWRlbnRpdHkgbXVzdCBpbmNsdWRlIHRoZSBhY3RvciBjb2x1bW4gJHthY3RvckZvcmVpZ25LZXlDb2x1bW59YClcbiAgfVxuICBpZiAoYXR0cmlidXRlc1thY3RvckZvcmVpZ25LZXlDb2x1bW5dICE9PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBTZXJ2ZXItb3JpZ2luIHN5bmMgcm93IGFjdG9yIGNvbHVtbiAke2FjdG9yRm9yZWlnbktleUNvbHVtbn0gbXVzdCBiZSBudWxsYClcbiAgfVxuXG4gIHZhbGlkYXRlUmVxdWlyZWRJZGVudGl0eVN0cmluZyh7YXR0cmlidXRlcywgY29sdW1uTmFtZTogXCJyZXNvdXJjZV9pZFwifSlcbiAgdmFsaWRhdGVSZXF1aXJlZElkZW50aXR5U3RyaW5nKHthdHRyaWJ1dGVzLCBjb2x1bW5OYW1lOiBcInJlc291cmNlX3R5cGVcIn0pXG5cbiAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59ICovXG4gIGNvbnN0IGlkZW50aXR5ID0ge1xuICAgIFthY3RvckZvcmVpZ25LZXlDb2x1bW5dOiBudWxsLFxuICAgIHJlc291cmNlX2lkOiBhdHRyaWJ1dGVzLnJlc291cmNlX2lkLFxuICAgIHJlc291cmNlX3R5cGU6IGF0dHJpYnV0ZXMucmVzb3VyY2VfdHlwZVxuICB9XG4gIGNvbnN0IGF0dHJpYnV0ZVRvQ29sdW1uTmFtZSA9IHN5bmNNb2RlbC5nZXRBdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwKClcbiAgY29uc3Qgc2NvcGVDb2x1bW5zID0gbmV3IFNldChzY29wZUNvbHVtbk5hbWVzIHx8IFtdKVxuXG4gIGlmIChzY29wZUNvbHVtbk5hbWVzID09PSB1bmRlZmluZWQpIHtcbiAgICBmb3IgKGNvbnN0IHNjb3BlQXR0cmlidXRlIG9mIGRlY2xhcmVkU3luY1Njb3BlQXR0cmlidXRlcyhzeW5jTW9kZWwpIHx8IFtdKSB7XG4gICAgICBjb25zdCBjb2x1bW5OYW1lID0gYXR0cmlidXRlVG9Db2x1bW5OYW1lW3Njb3BlQXR0cmlidXRlXVxuXG4gICAgICBpZiAoIWNvbHVtbk5hbWUpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGAke3N5bmNNb2RlbC5uYW1lfSBkZWNsYXJlcyB0aGUgc3luYyBzY29wZSBhdHRyaWJ1dGUgJHtzY29wZUF0dHJpYnV0ZX0gYnV0IGhhcyBubyBtYXRjaGluZyBjb2x1bW4gZm9yIGl0YClcbiAgICAgIH1cblxuICAgICAgc2NvcGVDb2x1bW5zLmFkZChjb2x1bW5OYW1lKVxuICAgIH1cbiAgfVxuXG4gIGZvciAoY29uc3QgY29sdW1uTmFtZSBvZiBzY29wZUNvbHVtbnMpIHtcbiAgICBpZiAodHlwZW9mIGNvbHVtbk5hbWUgIT09IFwic3RyaW5nXCIgfHwgIWNvbHVtbk5hbWUgfHwgIU9iamVjdC52YWx1ZXMoYXR0cmlidXRlVG9Db2x1bW5OYW1lKS5pbmNsdWRlcyhjb2x1bW5OYW1lKSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBTZXJ2ZXItb3JpZ2luIHN5bmMgcm93IHJlY2VpdmVkIGFuIHVua25vd24gc2NvcGUgY29sdW1uOiAke1N0cmluZyhjb2x1bW5OYW1lKX1gKVxuICAgIH1cblxuICAgIGlmICghT2JqZWN0Lmhhc093bihhdHRyaWJ1dGVzLCBjb2x1bW5OYW1lKSB8fCBhdHRyaWJ1dGVzW2NvbHVtbk5hbWVdID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU2VydmVyLW9yaWdpbiBzeW5jIHJvdyBpZGVudGl0eSBtdXN0IGluY2x1ZGUgdGhlIGRlY2xhcmVkIHNjb3BlIGNvbHVtbiAke2NvbHVtbk5hbWV9YClcbiAgICB9XG5cbiAgICBjb25zdCB2YWx1ZSA9IGF0dHJpYnV0ZXNbY29sdW1uTmFtZV1cblxuICAgIGlmICh2YWx1ZSAhPT0gbnVsbCAmJiB0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgJiYgKHR5cGVvZiB2YWx1ZSAhPT0gXCJudW1iZXJcIiB8fCAhTnVtYmVyLmlzRmluaXRlKHZhbHVlKSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU2VydmVyLW9yaWdpbiBzeW5jIHJvdyBzY29wZSBjb2x1bW4gJHtjb2x1bW5OYW1lfSBtdXN0IGJlIGEgc3RyaW5nLCBmaW5pdGUgbnVtYmVyLCBvciBudWxsYClcbiAgICB9XG5cbiAgICBpZGVudGl0eVtjb2x1bW5OYW1lXSA9IHZhbHVlXG4gIH1cblxuICBjb25zdCByb3dNb2RlbCA9IHBlcnNpc3RlbmNlTW9kZWwgfHwgc3luY01vZGVsXG5cbiAgcmV0dXJuIGF3YWl0IHN5bmNNb2RlbC53aXRoQWR2aXNvcnlMb2NrKHNlcnZlck9yaWdpblN5bmNSb3dMb2NrTmFtZShpZGVudGl0eSksIGFzeW5jICgpID0+IHtcbiAgICBjb25zdCBtYXRjaGluZ1N5bmNzID0gYXdhaXQgcm93TW9kZWxcbiAgICAgIC53aGVyZShpZGVudGl0eSlcbiAgICAgIC50b0FycmF5KClcblxuICAgIG1hdGNoaW5nU3luY3Muc29ydChjb21wYXJlU2VydmVyT3JpZ2luU3luY1Jvd3NCeVJlY2VuY3kpXG5cbiAgICBjb25zdCBbZXhpc3RpbmdTeW5jLCAuLi5kdXBsaWNhdGVTeW5jc10gPSBtYXRjaGluZ1N5bmNzXG5cbiAgICBmb3IgKGNvbnN0IGR1cGxpY2F0ZVN5bmMgb2YgZHVwbGljYXRlU3luY3MpIHtcbiAgICAgIGF3YWl0IGR1cGxpY2F0ZVN5bmMuZGVzdHJveSgpXG4gICAgfVxuXG4gICAgcmV0dXJuIGF3YWl0IHVwc2VydFN5bmNSb3coe2F0dHJpYnV0ZXMsIGV4aXN0aW5nU3luYywgc3luY01vZGVsOiByb3dNb2RlbH0pXG4gIH0sIHtkZWRpY2F0ZWRDb25uZWN0aW9uOiB0cnVlfSlcbn1cblxuLyoqXG4gKiBWYWxpZGF0ZXMgb25lIHJlcXVpcmVkIHN0cmluZyBjb21wb25lbnQgb2YgdGhlIHNlcnZlci1vcmlnaW4gaWRlbnRpdHkuXG4gKiBAcGFyYW0ge3thdHRyaWJ1dGVzOiBSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj4sIGNvbHVtbk5hbWU6IFwicmVzb3VyY2VfaWRcIiB8IFwicmVzb3VyY2VfdHlwZVwifX0gYXJncyAtIEF0dHJpYnV0ZXMgYW5kIHJlcXVpcmVkIGNvbHVtbi5cbiAqIEByZXR1cm5zIHt2b2lkfVxuICovXG5mdW5jdGlvbiB2YWxpZGF0ZVJlcXVpcmVkSWRlbnRpdHlTdHJpbmcoe2F0dHJpYnV0ZXMsIGNvbHVtbk5hbWV9KSB7XG4gIGNvbnN0IHZhbHVlID0gYXR0cmlidXRlc1tjb2x1bW5OYW1lXVxuXG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIgfHwgIXZhbHVlKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBTZXJ2ZXItb3JpZ2luIHN5bmMgcm93ICR7Y29sdW1uTmFtZX0gbXVzdCBiZSBhIG5vbi1lbXB0eSBzdHJpbmdgKVxuICB9XG59XG5cbi8qKlxuICogUmV0dXJucyB0aGUgc3RhYmxlIE15U1FMLXNhZmUgYWR2aXNvcnktbG9jayBuYW1lIHNoYXJlZCBieSBldmVyeSBjYWxsZXIgb2YgYVxuICogY29tcGxldGUgc2VydmVyLW9yaWdpbiBpZGVudGl0eS4gU3RhYmxlIEpTT04gcHJlc2VydmVzIG51bGwgaWRlbnRpdHkgdmFsdWVzLFxuICogd2hpbGUgdGhlIHRydW5jYXRlZCBTSEEtMjU2IGRpZ2VzdCBrZWVwcyB0aGUgbmFtZSB1bmRlciBHRVRfTE9DSydzIGxpbWl0LlxuICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59IGlkZW50aXR5IC0gQ29tcGxldGUgc3luYy1yb3cgaWRlbnRpdHkgaW4gY29sdW1uIGZvcm0uXG4gKiBAcmV0dXJucyB7c3RyaW5nfSBBZHZpc29yeS1sb2NrIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIHNlcnZlck9yaWdpblN5bmNSb3dMb2NrTmFtZShpZGVudGl0eSkge1xuICBjb25zdCBoYXNoID0gc2hhMjU2SGV4KHN0YWJsZUpzb25TdHJpbmdpZnkoaWRlbnRpdHkpKS5zbGljZSgwLCAzMilcblxuICByZXR1cm4gYHZzcDoke2hhc2h9YFxufVxuXG4vKipcbiAqIE9yZGVycyBtYXRjaGluZyByb3dzIHdpdGggdGhlIGNhbm9uaWNhbCBkZXRlcm1pbmlzdGljIHN1cnZpdm9yIGZpcnN0OlxuICogbmV3ZXN0IHNlcnZlciBzZXF1ZW5jZSwgdGhlbiBsb3dlc3QgaW1tdXRhYmxlIGlkLiBBIG51bGwgbGVnYWN5IHNlcXVlbmNlIGlzXG4gKiBvbGRlciB0aGFuIGV2ZXJ5IGFzc2lnbmVkIHNlcXVlbmNlLlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gbGVmdCAtIEZpcnN0IG1hdGNoaW5nIHN5bmMgcm93LlxuICogQHBhcmFtIHtSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPn0gcmlnaHQgLSBTZWNvbmQgbWF0Y2hpbmcgc3luYyByb3cuXG4gKiBAcmV0dXJucyB7bnVtYmVyfSBTb3J0IGNvbXBhcmlzb24uXG4gKi9cbmZ1bmN0aW9uIGNvbXBhcmVTZXJ2ZXJPcmlnaW5TeW5jUm93c0J5UmVjZW5jeShsZWZ0LCByaWdodCkge1xuICBjb25zdCBsZWZ0U2VxdWVuY2UgPSBsZWZ0LnNlcnZlclNlcXVlbmNlKClcbiAgY29uc3QgcmlnaHRTZXF1ZW5jZSA9IHJpZ2h0LnNlcnZlclNlcXVlbmNlKClcblxuICBpZiAobGVmdFNlcXVlbmNlID09PSBudWxsICYmIHJpZ2h0U2VxdWVuY2UgIT09IG51bGwpIHJldHVybiAxXG4gIGlmIChsZWZ0U2VxdWVuY2UgIT09IG51bGwgJiYgcmlnaHRTZXF1ZW5jZSA9PT0gbnVsbCkgcmV0dXJuIC0xXG4gIGlmIChsZWZ0U2VxdWVuY2UgIT09IHJpZ2h0U2VxdWVuY2UpIHJldHVybiByaWdodFNlcXVlbmNlIC0gbGVmdFNlcXVlbmNlXG5cbiAgcmV0dXJuIGxlZnQuaWQoKS5sb2NhbGVDb21wYXJlKHJpZ2h0LmlkKCkpXG59XG4iXX0=