velocious 1.0.495 → 1.0.496
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/database/record/index.js +2 -0
- package/build/database/record/validation-messages.js +50 -0
- package/build/database/record/validators/length.js +52 -0
- package/build/database/record/validators/presence.js +4 -1
- package/build/database/record/validators/uniqueness.js +4 -1
- package/build/frontend-model-resource/base-resource.js +175 -5
- package/build/frontend-models/resource-definition.js +46 -0
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +3 -1
- package/build/src/database/record/validation-messages.d.ts +38 -0
- package/build/src/database/record/validation-messages.d.ts.map +1 -0
- package/build/src/database/record/validation-messages.js +45 -0
- package/build/src/database/record/validators/length.d.ts +12 -0
- package/build/src/database/record/validators/length.d.ts.map +1 -0
- package/build/src/database/record/validators/length.js +45 -0
- package/build/src/database/record/validators/presence.d.ts.map +1 -1
- package/build/src/database/record/validators/presence.js +4 -2
- package/build/src/database/record/validators/uniqueness.d.ts.map +1 -1
- package/build/src/database/record/validators/uniqueness.js +4 -2
- package/build/src/frontend-model-resource/base-resource.d.ts +184 -5
- package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/base-resource.js +155 -6
- package/build/src/frontend-models/resource-definition.d.ts +41 -0
- package/build/src/frontend-models/resource-definition.d.ts.map +1 -1
- package/build/src/frontend-models/resource-definition.js +42 -1
- package/build/src/sync/sync-envelope-replay-service.d.ts +166 -3
- package/build/src/sync/sync-envelope-replay-service.d.ts.map +1 -1
- package/build/src/sync/sync-envelope-replay-service.js +304 -12
- package/build/src/sync/sync-replay-upsert-applier.d.ts +1 -0
- package/build/src/sync/sync-replay-upsert-applier.d.ts.map +1 -1
- package/build/src/sync/sync-replay-upsert-applier.js +2 -1
- package/build/src/sync/sync-resource-base.d.ts +16 -32
- package/build/src/sync/sync-resource-base.d.ts.map +1 -1
- package/build/src/sync/sync-resource-base.js +31 -43
- package/build/src/testing/test-runner.d.ts +12 -9
- package/build/src/testing/test-runner.d.ts.map +1 -1
- package/build/src/testing/test-runner.js +30 -9
- package/build/sync/sync-envelope-replay-service.js +350 -10
- package/build/sync/sync-replay-upsert-applier.js +1 -0
- package/build/sync/sync-resource-base.js +32 -45
- package/build/testing/test-runner.js +30 -8
- package/build/tsconfig.tsbuildinfo +1 -1
- package/package.json +1 -1
- package/scripts/run-tests.js +6 -0
- package/src/database/record/index.js +2 -0
- package/src/database/record/validation-messages.js +50 -0
- package/src/database/record/validators/length.js +52 -0
- package/src/database/record/validators/presence.js +4 -1
- package/src/database/record/validators/uniqueness.js +4 -1
- package/src/frontend-model-resource/base-resource.js +175 -5
- package/src/frontend-models/resource-definition.js +46 -0
- package/src/sync/sync-envelope-replay-service.js +350 -10
- package/src/sync/sync-replay-upsert-applier.js +1 -0
- package/src/sync/sync-resource-base.js +32 -45
- package/src/testing/test-runner.js +30 -8
- package/build/src/sync/sync-attribute-normalizer.d.ts +0 -105
- package/build/src/sync/sync-attribute-normalizer.d.ts.map +0 -1
- package/build/src/sync/sync-attribute-normalizer.js +0 -172
- package/build/sync/sync-attribute-normalizer.js +0 -186
- package/src/sync/sync-attribute-normalizer.js +0 -186
|
@@ -1,5 +1,8 @@
|
|
|
1
1
|
// @ts-check
|
|
2
|
+
import { resolveFrontendModelResourceClass } from "../frontend-models/resource-definition.js";
|
|
2
3
|
import SyncReplayUpsertApplier from "./sync-replay-upsert-applier.js";
|
|
4
|
+
import { ValidationError } from "../database/record/index.js";
|
|
5
|
+
import VelociousError from "../velocious-error.js";
|
|
3
6
|
/**
|
|
4
7
|
* One declarative broadcast fanned out after a mutation applies.
|
|
5
8
|
* @typedef {object} SyncReplayBroadcast
|
|
@@ -34,11 +37,16 @@ export default class SyncEnvelopeReplayService {
|
|
|
34
37
|
* @param {?} [args.authenticationTokenModel] - Token model enabling the default token-lookup authenticateReplay.
|
|
35
38
|
* @param {string} [args.authenticationTokenColumn] - Token model column holding the token. Defaults to "token".
|
|
36
39
|
* @param {string} [args.authenticationTokenParam] - Request param carrying the token. Defaults to "authenticationToken".
|
|
37
|
-
* @param {Record<string, ((args: Record<string, ?>) => Promise<?>) | ConstructorParameters<typeof SyncReplayUpsertApplier>[0]>} [args.applyHandlers] - Per-resourceType apply handlers (functions or declarative upsert-applier specs) enabling the default applyReplayMutation dispatch.
|
|
40
|
+
* @param {Record<string, ((args: Record<string, ?>) => Promise<?>) | ConstructorParameters<typeof SyncReplayUpsertApplier>[0]>} [args.applyHandlers] - Per-resourceType apply handlers (functions or declarative upsert-applier specs) enabling the default applyReplayMutation dispatch. Deprecated: prefer resource routing via `configuration`/`resourceTypeOverrides`; applyHandlers remain for released adopters and will be removed after their migration.
|
|
38
41
|
* @param {(args: Record<string, ?>) => Record<string, ?>} [args.persistExtraAttributes] - Extra attributes merged into the model-backed persisted row (e.g. an event scope column).
|
|
39
42
|
* @param {(args: {mutation: ?, applyResult: ?}) => ?} [args.persistSerializedData] - Overrides the persisted data payload (object results are JSON stringified).
|
|
40
43
|
* @param {(broadcast: {channel: string, params: Record<string, ?>, body: ?}) => Promise<void>} [args.broadcaster] - Delivers declarative broadcasts. Required when broadcasts are configured.
|
|
41
44
|
* @param {SyncReplayBroadcast[]} [args.broadcasts] - Broadcasts fanned out by the default afterReplayMutation.
|
|
45
|
+
* @param {{getBackendProjects: () => import("../configuration-types.js").BackendProjectConfiguration[]}} [args.configuration] - Configuration whose frontend-model registry routes mutations to resource classes.
|
|
46
|
+
* @param {Record<string, import("../configuration-types.js").FrontendModelResourceClassType | string>} [args.resourceTypeOverrides] - Per-resourceType routing overrides: a resource class, or a string alias resolved through the registry.
|
|
47
|
+
* @param {import("../authorization/ability.js").default} [args.ability] - Ability scoping routed record lookups and create membership checks.
|
|
48
|
+
* @param {Record<string, ?>} [args.abilityContext] - Ability context passed to routed resources.
|
|
49
|
+
* @param {Record<string, ?>} [args.locals] - Locals passed to routed resources.
|
|
42
50
|
*/
|
|
43
51
|
constructor(args = {}) {
|
|
44
52
|
this.logger = args.logger || console;
|
|
@@ -52,6 +60,13 @@ export default class SyncEnvelopeReplayService {
|
|
|
52
60
|
this.broadcaster = args.broadcaster || null;
|
|
53
61
|
this.broadcasts = args.broadcasts || null;
|
|
54
62
|
this.applyHandlers = args.applyHandlers ? this.builtApplyHandlers(args.applyHandlers) : null;
|
|
63
|
+
this.configuration = args.configuration || null;
|
|
64
|
+
this.resourceTypeOverrides = args.resourceTypeOverrides || null;
|
|
65
|
+
this.ability = args.ability || null;
|
|
66
|
+
this.abilityContext = args.abilityContext || null;
|
|
67
|
+
this.locals = args.locals || null;
|
|
68
|
+
/** @type {Map<string, SyncReplayResourceRegistration | null>} */
|
|
69
|
+
this._replayResourceRegistrations = new Map();
|
|
55
70
|
if (args.actorForeignKeyColumn !== undefined && (typeof args.actorForeignKeyColumn !== "string" || args.actorForeignKeyColumn.length < 1)) {
|
|
56
71
|
throw new Error(`actorForeignKeyColumn must be a non-blank string, got: ${String(args.actorForeignKeyColumn)}`);
|
|
57
72
|
}
|
|
@@ -107,9 +122,28 @@ export default class SyncEnvelopeReplayService {
|
|
|
107
122
|
}
|
|
108
123
|
const existingSync = await this.findExistingReplaySync({ actor: actorResult.actor, context, mutation });
|
|
109
124
|
const shouldApply = await this.shouldApplyReplayMutation({ actor: actorResult.actor, context, existingSync, mutation });
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
125
|
+
/** @type {?} */
|
|
126
|
+
let applyResult;
|
|
127
|
+
try {
|
|
128
|
+
applyResult = shouldApply
|
|
129
|
+
? await this.applyReplayMutation({ actor: actorResult.actor, context, existingSync, mutation })
|
|
130
|
+
: await this.skippedReplayMutation({ actor: actorResult.actor, context, existingSync, mutation });
|
|
131
|
+
}
|
|
132
|
+
catch (error) {
|
|
133
|
+
// Client-safe apply failures (schema validation, model validation,
|
|
134
|
+
// authorization denials, unknown resource types) fail this sync and
|
|
135
|
+
// keep the batch going; unexpected errors keep propagating.
|
|
136
|
+
if (error instanceof VelociousError && error.safeToExpose) {
|
|
137
|
+
syncResponses.push({
|
|
138
|
+
id: mutation.id,
|
|
139
|
+
syncState: "failed",
|
|
140
|
+
reason: error.code || "apply-failed",
|
|
141
|
+
message: error.message
|
|
142
|
+
});
|
|
143
|
+
continue;
|
|
144
|
+
}
|
|
145
|
+
throw error;
|
|
146
|
+
}
|
|
113
147
|
await this.persistReplayMutation({ actor: actorResult.actor, context, existingSync, applyResult, mutation, shouldApply });
|
|
114
148
|
await this.afterReplayMutation({ actor: actorResult.actor, context, existingSync, applyResult, mutation, shouldApply });
|
|
115
149
|
syncResponses.push({ id: mutation.id, syncState: "successful" });
|
|
@@ -279,18 +313,269 @@ export default class SyncEnvelopeReplayService {
|
|
|
279
313
|
/**
|
|
280
314
|
* Applies one normalized mutation to domain models.
|
|
281
315
|
*
|
|
282
|
-
*
|
|
283
|
-
* mutations without a
|
|
316
|
+
* Dispatches through the configured apply-handler registry first (compat
|
|
317
|
+
* precedence); mutations without a matching handler fall through to
|
|
318
|
+
* resource routing when a configuration or resourceTypeOverrides are
|
|
319
|
+
* configured, and otherwise fail loudly.
|
|
284
320
|
* @param {{actor: ?, context: Record<string, ?>, existingSync: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation}} args - Actor, batch context, existing sync row, and mutation.
|
|
285
321
|
* @returns {Promise<?>} Project-specific apply result.
|
|
286
322
|
*/
|
|
287
323
|
async applyReplayMutation(args) {
|
|
288
|
-
if (
|
|
324
|
+
if (this.applyHandlers) {
|
|
325
|
+
const applyHandler = this.applyHandlers[args.mutation.resourceType];
|
|
326
|
+
if (applyHandler)
|
|
327
|
+
return await applyHandler(args);
|
|
328
|
+
if (!this.routingConfigured())
|
|
329
|
+
throw new Error(`No sync apply handler registered for: ${args.mutation.resourceType}`);
|
|
330
|
+
}
|
|
331
|
+
if (this.routingConfigured())
|
|
332
|
+
return await this.applyRoutedReplayMutation(args);
|
|
333
|
+
return null;
|
|
334
|
+
}
|
|
335
|
+
/**
|
|
336
|
+
* Returns whether resource routing is configured on this service.
|
|
337
|
+
* @returns {boolean} Whether mutations route to frontend-model resources.
|
|
338
|
+
*/
|
|
339
|
+
routingConfigured() {
|
|
340
|
+
return Boolean(this.configuration || this.resourceTypeOverrides);
|
|
341
|
+
}
|
|
342
|
+
/**
|
|
343
|
+
* Resolves the routed resource registration for a resource type, memoized
|
|
344
|
+
* per replay service. Overrides win over the configuration registry; string
|
|
345
|
+
* overrides are aliases resolved through the registry.
|
|
346
|
+
* @param {string} resourceType - Mutation resource type.
|
|
347
|
+
* @returns {SyncReplayResourceRegistration | null} Resolved registration or null when unroutable.
|
|
348
|
+
*/
|
|
349
|
+
replayResourceRegistration(resourceType) {
|
|
350
|
+
const memoizedRegistration = this._replayResourceRegistrations.get(resourceType);
|
|
351
|
+
if (memoizedRegistration !== undefined)
|
|
352
|
+
return memoizedRegistration;
|
|
353
|
+
const registration = this.resolveReplayResourceRegistration(resourceType);
|
|
354
|
+
this._replayResourceRegistrations.set(resourceType, registration);
|
|
355
|
+
return registration;
|
|
356
|
+
}
|
|
357
|
+
/**
|
|
358
|
+
* Uncached routed-resource resolution behind {@link SyncEnvelopeReplayService#replayResourceRegistration}.
|
|
359
|
+
* @param {string} resourceType - Mutation resource type.
|
|
360
|
+
* @returns {SyncReplayResourceRegistration | null} Resolved registration or null when unroutable.
|
|
361
|
+
*/
|
|
362
|
+
resolveReplayResourceRegistration(resourceType) {
|
|
363
|
+
const override = this.resourceTypeOverrides?.[resourceType];
|
|
364
|
+
if (override && typeof override !== "string") {
|
|
365
|
+
return { modelName: resourceType, resourceClass: override, resourceConfiguration: null };
|
|
366
|
+
}
|
|
367
|
+
const registryResourceType = typeof override === "string" ? override : resourceType;
|
|
368
|
+
if (!this.configuration)
|
|
369
|
+
return null;
|
|
370
|
+
const resolvedRegistration = resolveFrontendModelResourceClass({ configuration: this.configuration, resourceType: registryResourceType });
|
|
371
|
+
if (!resolvedRegistration)
|
|
289
372
|
return null;
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
373
|
+
return {
|
|
374
|
+
modelName: resolvedRegistration.modelName,
|
|
375
|
+
resourceClass: resolvedRegistration.resourceClass,
|
|
376
|
+
resourceConfiguration: resolvedRegistration.resourceConfiguration
|
|
377
|
+
};
|
|
378
|
+
}
|
|
379
|
+
/**
|
|
380
|
+
* Builds the routed resource instance handling one mutation.
|
|
381
|
+
* @param {object} args - Options.
|
|
382
|
+
* @param {import("./sync-envelope-replay-service.js").SyncReplayMutation} args.mutation - Normalized replay mutation.
|
|
383
|
+
* @param {SyncReplayResourceRegistration} args.registration - Resolved resource registration.
|
|
384
|
+
* @returns {import("../frontend-model-resource/base-resource.js").default} Routed resource instance.
|
|
385
|
+
*/
|
|
386
|
+
buildReplayResource({ mutation, registration }) {
|
|
387
|
+
const ResourceClass = registration.resourceClass;
|
|
388
|
+
return new ResourceClass({
|
|
389
|
+
ability: this.ability || undefined,
|
|
390
|
+
context: this.abilityContext || {},
|
|
391
|
+
locals: this.locals || {},
|
|
392
|
+
modelName: registration.modelName,
|
|
393
|
+
params: mutation.data,
|
|
394
|
+
...(registration.resourceConfiguration ? { resourceConfiguration: registration.resourceConfiguration } : {})
|
|
395
|
+
});
|
|
396
|
+
}
|
|
397
|
+
/**
|
|
398
|
+
* Applies one mutation through its routed frontend-model resource:
|
|
399
|
+
* authorization, ability-scoped record lookup, schema normalization and
|
|
400
|
+
* assign/save for updates, save-then-check membership creates, destroys for
|
|
401
|
+
* deletes, and the resource's afterSyncApply tail. Client-safe failures
|
|
402
|
+
* throw safe errors that fail the single sync.
|
|
403
|
+
* @param {{actor: ?, context: Record<string, ?>, existingSync: ?, mutation: import("./sync-envelope-replay-service.js").SyncReplayMutation}} args - Actor, batch context, existing sync row, and mutation.
|
|
404
|
+
* @returns {Promise<Record<string, ?>>} Apply result with record, created/deleted flags, and afterSyncApply extras.
|
|
405
|
+
*/
|
|
406
|
+
async applyRoutedReplayMutation({ context, existingSync, mutation }) {
|
|
407
|
+
const registration = this.replayResourceRegistration(mutation.resourceType);
|
|
408
|
+
if (!registration) {
|
|
409
|
+
throw VelociousError.safe(`Unknown sync resource type: ${mutation.resourceType}.`, { code: "unknown-resource-type" });
|
|
410
|
+
}
|
|
411
|
+
const resource = this.buildReplayResource({ mutation, registration });
|
|
412
|
+
const customApplyResult = await resource.applySync({ context, existingSync, mutation });
|
|
413
|
+
if (customApplyResult !== null)
|
|
414
|
+
return customApplyResult;
|
|
415
|
+
const authorization = await resource.authorizeSyncMutation({ context, mutation });
|
|
416
|
+
if (!authorization.allowed) {
|
|
417
|
+
throw VelociousError.safe(`Sync mutation denied for: ${mutation.resourceType}.`, { code: authorization.reason || "access-denied" });
|
|
418
|
+
}
|
|
419
|
+
if (mutation.syncType === "delete")
|
|
420
|
+
return await this.applyRoutedReplayDelete({ mutation, resource });
|
|
421
|
+
return await this.applyRoutedReplayUpsert({ context, mutation, resource });
|
|
422
|
+
}
|
|
423
|
+
/**
|
|
424
|
+
* Applies a routed delete mutation.
|
|
425
|
+
* @param {object} args - Options.
|
|
426
|
+
* @param {import("./sync-envelope-replay-service.js").SyncReplayMutation} args.mutation - Normalized replay mutation.
|
|
427
|
+
* @param {import("../frontend-model-resource/base-resource.js").default} args.resource - Routed resource instance.
|
|
428
|
+
* @returns {Promise<Record<string, ?>>} Apply result with the deleted flag.
|
|
429
|
+
*/
|
|
430
|
+
async applyRoutedReplayDelete({ mutation, resource }) {
|
|
431
|
+
const record = await resource.findSyncRecord({ forDelete: true, mutation });
|
|
432
|
+
if (!record)
|
|
433
|
+
return { created: false, deleted: false, record: null };
|
|
434
|
+
await record.destroy();
|
|
435
|
+
return { created: false, deleted: true, record };
|
|
436
|
+
}
|
|
437
|
+
/**
|
|
438
|
+
* Applies a routed upsert mutation: permitted payload attributes are
|
|
439
|
+
* assigned and saved onto the found record (the record layer owns value
|
|
440
|
+
* casting and validation), and missing records are created with the
|
|
441
|
+
* client-generated primary key plus a save-then-check membership check.
|
|
442
|
+
* Model validation failures become client-safe per-sync failures carrying
|
|
443
|
+
* the translated validation message.
|
|
444
|
+
* @param {object} args - Options.
|
|
445
|
+
* @param {Record<string, ?>} args.context - Replay context.
|
|
446
|
+
* @param {import("./sync-envelope-replay-service.js").SyncReplayMutation} args.mutation - Normalized replay mutation.
|
|
447
|
+
* @param {import("../frontend-model-resource/base-resource.js").default} args.resource - Routed resource instance.
|
|
448
|
+
* @returns {Promise<Record<string, ?>>} Apply result with record, created flag, and afterSyncApply extras.
|
|
449
|
+
*/
|
|
450
|
+
async applyRoutedReplayUpsert({ context, mutation, resource }) {
|
|
451
|
+
const attributes = this.permittedRoutedAttributes({ mutation, resource });
|
|
452
|
+
const existingRecord = await resource.findSyncRecord({ mutation });
|
|
453
|
+
/** @type {import("../database/record/index.js").default | null} */
|
|
454
|
+
let record = existingRecord;
|
|
455
|
+
let created = false;
|
|
456
|
+
if (existingRecord) {
|
|
457
|
+
existingRecord.assign(attributes);
|
|
458
|
+
await this.saveRoutedReplayRecord(existingRecord);
|
|
459
|
+
}
|
|
460
|
+
else {
|
|
461
|
+
record = await this.createRoutedReplayRecord({ attributes, mutation, resource });
|
|
462
|
+
created = true;
|
|
463
|
+
}
|
|
464
|
+
const extras = await resource.afterSyncApply({ context, created, mutation, record });
|
|
465
|
+
return { created, deleted: false, record, ...extras };
|
|
466
|
+
}
|
|
467
|
+
/**
|
|
468
|
+
* Filters a routed mutation payload down to the resource's declared
|
|
469
|
+
* writable-attribute permit list. Accepted keys per permitted attribute are
|
|
470
|
+
* the camelCase attribute name plus the model's actual column name; unknown
|
|
471
|
+
* keys fail the sync loudly. The primary key is dropped when permitted
|
|
472
|
+
* (snapshot payloads) — the envelope's resourceId is the authoritative
|
|
473
|
+
* record identity, so a payload id can never retarget the row.
|
|
474
|
+
* @param {object} args - Options.
|
|
475
|
+
* @param {import("./sync-envelope-replay-service.js").SyncReplayMutation} args.mutation - Normalized replay mutation.
|
|
476
|
+
* @param {import("../frontend-model-resource/base-resource.js").default} args.resource - Routed resource instance.
|
|
477
|
+
* @returns {Record<string, ?>} Permitted attributes for record.assign.
|
|
478
|
+
*/
|
|
479
|
+
permittedRoutedAttributes({ mutation, resource }) {
|
|
480
|
+
const permittedAttributes = resource.declaredWritableAttributes();
|
|
481
|
+
if (!permittedAttributes) {
|
|
482
|
+
throw new Error(`${resource.constructor.name} must declare static writableAttributes to apply routed sync mutations for: ${mutation.resourceType}`);
|
|
483
|
+
}
|
|
484
|
+
const ModelClass = resource.modelClass();
|
|
485
|
+
const attributeNameToColumnName = ModelClass.getAttributeNameToColumnNameMap();
|
|
486
|
+
/** @type {Set<string>} */
|
|
487
|
+
const allowedKeys = new Set();
|
|
488
|
+
for (const attributeName of permittedAttributes) {
|
|
489
|
+
allowedKeys.add(attributeName);
|
|
490
|
+
const columnName = attributeNameToColumnName[attributeName];
|
|
491
|
+
if (columnName)
|
|
492
|
+
allowedKeys.add(columnName);
|
|
493
|
+
}
|
|
494
|
+
const primaryKey = ModelClass.primaryKey();
|
|
495
|
+
const primaryKeyAttribute = ModelClass.getColumnNameToAttributeNameMap()[primaryKey];
|
|
496
|
+
/** @type {Record<string, ?>} */
|
|
497
|
+
const attributes = {};
|
|
498
|
+
for (const [key, value] of Object.entries(mutation.data)) {
|
|
499
|
+
if (!allowedKeys.has(key)) {
|
|
500
|
+
throw resource.writableAttributeError(`Unknown attribute: ${key}.`, { code: "sync-unknown-attribute" });
|
|
501
|
+
}
|
|
502
|
+
if (key === primaryKey || key === primaryKeyAttribute)
|
|
503
|
+
continue;
|
|
504
|
+
attributes[key] = value;
|
|
505
|
+
}
|
|
506
|
+
return attributes;
|
|
507
|
+
}
|
|
508
|
+
/**
|
|
509
|
+
* Creates the routed record with the client-generated primary key, then
|
|
510
|
+
* verifies create-scope membership when an ability is configured: records
|
|
511
|
+
* outside the ability's create scope are destroyed again and fail the sync
|
|
512
|
+
* with the resource-declared reason. A record that already exists outside
|
|
513
|
+
* the resource's lookup scope fails the sync as an authorization denial
|
|
514
|
+
* instead of colliding on the primary key.
|
|
515
|
+
* @param {object} args - Options.
|
|
516
|
+
* @param {Record<string, ?>} args.attributes - Permitted payload attributes.
|
|
517
|
+
* @param {import("./sync-envelope-replay-service.js").SyncReplayMutation} args.mutation - Normalized replay mutation.
|
|
518
|
+
* @param {import("../frontend-model-resource/base-resource.js").default} args.resource - Routed resource instance.
|
|
519
|
+
* @returns {Promise<import("../database/record/index.js").default>} Created record.
|
|
520
|
+
*/
|
|
521
|
+
async createRoutedReplayRecord({ attributes, mutation, resource }) {
|
|
522
|
+
const ModelClass = resource.modelClass();
|
|
523
|
+
const primaryKey = ModelClass.primaryKey();
|
|
524
|
+
const conflictingIds = await ModelClass.where({ [primaryKey]: mutation.resourceId }).pluck(primaryKey);
|
|
525
|
+
if (conflictingIds.length > 0) {
|
|
526
|
+
throw VelociousError.safe(`Sync update denied for: ${mutation.resourceType}.`, {
|
|
527
|
+
code: resource.syncAuthorizationFailureReason({ action: "update", mutation }) || "access-denied"
|
|
528
|
+
});
|
|
529
|
+
}
|
|
530
|
+
/** @type {import("../database/record/index.js").default} */
|
|
531
|
+
let record;
|
|
532
|
+
try {
|
|
533
|
+
record = await ModelClass.create({ [primaryKey]: mutation.resourceId, ...attributes });
|
|
534
|
+
}
|
|
535
|
+
catch (error) {
|
|
536
|
+
throw this.routedReplaySaveError(error);
|
|
537
|
+
}
|
|
538
|
+
const ability = resource.ability;
|
|
539
|
+
if (ability) {
|
|
540
|
+
const memberIds = await ModelClass
|
|
541
|
+
.accessibleFor(resource.syncAbilityAction("create"), ability)
|
|
542
|
+
.where({ [primaryKey]: record.id() })
|
|
543
|
+
.pluck(primaryKey);
|
|
544
|
+
if (memberIds.length === 0) {
|
|
545
|
+
await record.destroy();
|
|
546
|
+
throw VelociousError.safe(`Sync create denied for: ${mutation.resourceType}.`, {
|
|
547
|
+
code: resource.syncAuthorizationFailureReason({ action: "create", mutation }) || "access-denied"
|
|
548
|
+
});
|
|
549
|
+
}
|
|
550
|
+
}
|
|
551
|
+
return record;
|
|
552
|
+
}
|
|
553
|
+
/**
|
|
554
|
+
* Saves a routed record, converting model validation failures into
|
|
555
|
+
* client-safe per-sync errors carrying the translated validation message.
|
|
556
|
+
* @param {import("../database/record/index.js").default} record - Record to save.
|
|
557
|
+
* @returns {Promise<void>} Resolves when saved.
|
|
558
|
+
*/
|
|
559
|
+
async saveRoutedReplayRecord(record) {
|
|
560
|
+
try {
|
|
561
|
+
await record.save();
|
|
562
|
+
}
|
|
563
|
+
catch (error) {
|
|
564
|
+
throw this.routedReplaySaveError(error);
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
/**
|
|
568
|
+
* Maps a routed save/create failure: model validation errors become
|
|
569
|
+
* client-safe errors with their translated messages, everything else
|
|
570
|
+
* propagates unchanged.
|
|
571
|
+
* @param {?} error - Thrown save/create error.
|
|
572
|
+
* @returns {Error} Error to rethrow.
|
|
573
|
+
*/
|
|
574
|
+
routedReplaySaveError(error) {
|
|
575
|
+
if (error instanceof ValidationError) {
|
|
576
|
+
return VelociousError.safe(error.message, { cause: error, code: "validation-error" });
|
|
577
|
+
}
|
|
578
|
+
return /** @type {Error} */ (error);
|
|
294
579
|
}
|
|
295
580
|
/**
|
|
296
581
|
* Resolves an apply result for stale mutations that should not touch domain models.
|
|
@@ -376,6 +661,13 @@ export default class SyncEnvelopeReplayService {
|
|
|
376
661
|
}
|
|
377
662
|
}
|
|
378
663
|
}
|
|
664
|
+
/**
|
|
665
|
+
* Resolved routed-resource registration for one replay resource type.
|
|
666
|
+
* @typedef {object} SyncReplayResourceRegistration
|
|
667
|
+
* @property {string} modelName - Effective frontend model name.
|
|
668
|
+
* @property {import("../configuration-types.js").FrontendModelResourceClassType} resourceClass - Routed resource class.
|
|
669
|
+
* @property {import("../configuration-types.js").NormalizedFrontendModelResourceConfiguration | null} resourceConfiguration - Normalized resource configuration when registry-resolved.
|
|
670
|
+
*/
|
|
379
671
|
/**
|
|
380
672
|
* @typedef {object} SyncReplayMutation
|
|
381
673
|
* @property {Date} clientUpdatedAt - Client-side mutation timestamp.
|
|
@@ -386,4 +678,4 @@ export default class SyncEnvelopeReplayService {
|
|
|
386
678
|
* @property {string} serializedData - JSON serialized mutation payload.
|
|
387
679
|
* @property {string} syncType - Sync operation type.
|
|
388
680
|
*/
|
|
389
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zeW5jL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sdUJBQXVCLE1BQU0saUNBQWlDLENBQUE7QUFFckU7Ozs7Ozs7R0FPRztBQUVIOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLE9BQU8sT0FBTyx5QkFBeUI7SUFDNUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQXFCRztJQUNILFlBQVksSUFBSSxHQUFHLEVBQUU7UUFDbkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQTtRQUNwQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFBO1FBQ3ZDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMscUJBQXFCLElBQUkseUJBQXlCLENBQUE7UUFDcEYsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQyx3QkFBd0IsSUFBSSxJQUFJLENBQUE7UUFDckUsSUFBSSxDQUFDLHlCQUF5QixHQUFHLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxPQUFPLENBQUE7UUFDMUUsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQyx3QkFBd0IsSUFBSSxxQkFBcUIsQ0FBQTtRQUN0RixJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixJQUFJLElBQUksQ0FBQTtRQUNqRSxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixJQUFJLElBQUksQ0FBQTtRQUMvRCxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQyxXQUFXLElBQUksSUFBSSxDQUFBO1FBQzNDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUE7UUFDekMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUE7UUFFNUYsSUFBSSxJQUFJLENBQUMscUJBQXFCLEtBQUssU0FBUyxJQUFJLENBQUMsT0FBTyxJQUFJLENBQUMscUJBQXFCLEtBQUssUUFBUSxJQUFJLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQztZQUMxSSxNQUFNLElBQUksS0FBSyxDQUFDLDBEQUEwRCxNQUFNLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsQ0FBQyxDQUFBO1FBQ2pILENBQUM7UUFDRCxJQUFJLElBQUksQ0FBQyxVQUFVLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDekMsTUFBTSxJQUFJLEtBQUssQ0FBQyxtRkFBbUYsQ0FBQyxDQUFBO1FBQ3RHLENBQUM7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILGtCQUFrQixDQUFDLGFBQWE7UUFDOUIsT0FBTyxNQUFNLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxZQUFZLEVBQUUsT0FBTyxDQUFDLEVBQUUsRUFBRTtZQUN0RixJQUFJLE9BQU8sT0FBTyxLQUFLLFVBQVU7Z0JBQUUsT0FBTyxDQUFDLFlBQVksRUFBRSxPQUFPLENBQUMsQ0FBQTtZQUVqRSxNQUFNLE9BQU8sR0FBRyxJQUFJLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxDQUFBO1lBRXBELE9BQU8sQ0FBQyxZQUFZLEVBQUUsQ0FBQyxnQ0FBZ0MsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLENBQUE7UUFDcEgsQ0FBQyxDQUFDLENBQUMsQ0FBQTtJQUNMLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLE1BQU0sQ0FBQyxNQUFNO1FBQ2pCLE1BQU0sV0FBVyxHQUFHLE1BQU0sSUFBSSxDQUFDLGtCQUFrQixDQUFDLE1BQU0sQ0FBQyxDQUFBO1FBRXpELElBQUksQ0FBQyxXQUFXLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDL0IsT0FBTztnQkFDTCxLQUFLLEVBQUUsRUFBRTtnQkFDVCxNQUFNLEVBQUUsT0FBTztnQkFDZixTQUFTLEVBQUUsV0FBVyxDQUFDLFNBQVM7Z0JBQ2hDLFlBQVksRUFBRSxXQUFXLENBQUMsWUFBWTthQUN2QyxDQUFBO1FBQ0gsQ0FBQztRQUVELE1BQU0sYUFBYSxHQUFHLEVBQUUsQ0FBQTtRQUN4QixNQUFNLE9BQU8sR0FBRyxNQUFNLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxFQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBQyxDQUFDLENBQUE7UUFFakYsS0FBSyxNQUFNLE9BQU8sSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FBQyxFQUFFLENBQUM7WUFDL0MsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsT0FBTyxDQUFDLENBQUE7WUFFMUQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsRUFBRSxDQUFDO2dCQUN6QixhQUFhLENBQUMsSUFBSSxDQUFDLGdCQUFnQixDQUFDLFFBQVEsQ0FBQyxDQUFBO2dCQUM3QyxTQUFRO1lBQ1YsQ0FBQztZQUVELE1BQU0sUUFBUSxHQUFHLGdCQUFnQixDQUFDLFFBQVEsQ0FBQTtZQUMxQyxNQUFNLFlBQVksR0FBRyxNQUFNLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxFQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUMsQ0FBQyxDQUFBO1lBRXRHLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxFQUFFLENBQUM7Z0JBQzFCLGFBQWEsQ0FBQyxJQUFJLENBQUM7b0JBQ2pCLEVBQUUsRUFBRSxRQUFRLENBQUMsRUFBRTtvQkFDZixTQUFTLEVBQUUsUUFBUTtvQkFDbkIsTUFBTSxFQUFFLFlBQVksQ0FBQyxNQUFNLElBQUksZUFBZTtpQkFDL0MsQ0FBQyxDQUFBO2dCQUNGLFNBQVE7WUFDVixDQUFDO1lBRUQsTUFBTSxZQUFZLEdBQUcsTUFBTSxJQUFJLENBQUMsc0JBQXNCLENBQUMsRUFBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQTtZQUNyRyxNQUFNLFdBQVcsR0FBRyxNQUFNLElBQUksQ0FBQyx5QkFBeUIsQ0FBQyxFQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQTtZQUNySCxNQUFNLFdBQVcsR0FBRyxXQUFXO2dCQUM3QixDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsbUJBQW1CLENBQUMsRUFBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBQyxDQUFDO2dCQUM3RixDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsRUFBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBQyxDQUFDLENBQUE7WUFFakcsTUFBTSxJQUFJLENBQUMscUJBQXFCLENBQUMsRUFBQyxLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUssRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFDLENBQUMsQ0FBQTtZQUN2SCxNQUFNLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxFQUFDLEtBQUssRUFBRSxXQUFXLENBQUMsS0FBSyxFQUFFLE9BQU8sRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUMsQ0FBQyxDQUFBO1lBRXJILGFBQWEsQ0FBQyxJQUFJLENBQUMsRUFBQyxFQUFFLEVBQUUsUUFBUSxDQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFDLENBQUMsQ0FBQTtRQUNoRSxDQUFDO1FBRUQsT0FBTyxFQUFDLEtBQUssRUFBRSxhQUFhLEVBQUMsQ0FBQTtJQUMvQixDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxrQkFBa0IsQ0FBQyxNQUFNO1FBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztZQUNuQyxNQUFNLElBQUksS0FBSyxDQUFDLDBHQUEwRyxDQUFDLENBQUE7UUFDN0gsQ0FBQztRQUVELE1BQU0sS0FBSyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsd0JBQXdCLENBQUMsQ0FBQTtRQUVuRCxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLEVBQUMsYUFBYSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsOEJBQThCLEVBQUUsWUFBWSxFQUFFLDhCQUE4QixFQUFDLENBQUE7UUFDeEgsQ0FBQztRQUVELE1BQU0sS0FBSyxHQUFHLE1BQU0sSUFBSSxDQUFDLHdCQUF3QixDQUFDLE1BQU0sQ0FBQyxFQUFDLENBQUMsSUFBSSxDQUFDLHlCQUF5QixDQUFDLEVBQUUsS0FBSyxFQUFDLENBQUMsQ0FBQTtRQUVuRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDWCxPQUFPLEVBQUMsYUFBYSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsOEJBQThCLEVBQUUsWUFBWSxFQUFFLDhCQUE4QixFQUFDLENBQUE7UUFDeEgsQ0FBQztRQUVELE9BQU8sRUFBQyxLQUFLLEVBQUUsYUFBYSxFQUFFLElBQUksRUFBQyxDQUFBO0lBQ3JDLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsS0FBSyxDQUFDLGtCQUFrQixDQUFDLEtBQUs7UUFDNUIsT0FBTyxFQUFFLENBQUE7SUFDWCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILFdBQVcsQ0FBQyxNQUFNO1FBQ2hCLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtJQUN4RCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILG1CQUFtQixDQUFDLE9BQU87UUFDekIsSUFBSSxDQUFDLE9BQU8sSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBRSxDQUFDO1lBQ3RFLE9BQU8sRUFBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsY0FBYyxFQUFDLEVBQUMsQ0FBQTtRQUM1RixDQUFDO1FBRUQsTUFBTSxJQUFJLEdBQUcsZ0NBQWdDLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQTtRQUN2RCxNQUFNLEVBQUMsZUFBZSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUMsR0FBRyxJQUFJLENBQUE7UUFFNUUsSUFBSSxPQUFPLFlBQVksS0FBSyxRQUFRLElBQUksWUFBWSxDQUFDLE1BQU0sR0FBRyxDQUFDLElBQUksVUFBVSxLQUFLLFNBQVMsSUFBSSxVQUFVLEtBQUssSUFBSSxJQUFJLE9BQU8sUUFBUSxLQUFLLFFBQVEsSUFBSSxRQUFRLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO1lBQzFLLE9BQU8sRUFBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxxQkFBcUIsRUFBQyxFQUFDLENBQUE7UUFDeEYsQ0FBQztRQUVELE1BQU0sZ0JBQWdCLEdBQUcsTUFBTSxDQUFDLFVBQVUsQ0FBQyxDQUFBO1FBQzNDLElBQUksbUJBQW1CLEdBQUcsT0FBTyxlQUFlLEtBQUssUUFBUSxJQUFJLGVBQWUsWUFBWSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLGVBQWUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLElBQUksRUFBRSxDQUFBO1FBRXpJLElBQUksTUFBTSxDQUFDLEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxPQUFPLEVBQUUsQ0FBQztZQUFFLG1CQUFtQixHQUFHLElBQUksSUFBSSxFQUFFLENBQUE7UUFFakYsTUFBTSxvQkFBb0IsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsRUFBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLFVBQVUsRUFBRSxnQkFBZ0IsRUFBRSxZQUFZLEVBQUMsQ0FBQyxDQUFBO1FBRWpILElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxFQUFFO1lBQUUsT0FBTyxvQkFBb0IsQ0FBQTtRQUV6RCxPQUFPO1lBQ0wsRUFBRSxFQUFFLElBQUk7WUFDUixRQUFRLEVBQUU7Z0JBQ1IsZUFBZSxFQUFFLG1CQUFtQjtnQkFDcEMsSUFBSSxFQUFFLG9CQUFvQixDQUFDLElBQUk7Z0JBQy9CLEVBQUU7Z0JBQ0YsVUFBVSxFQUFFLGdCQUFnQjtnQkFDNUIsWUFBWTtnQkFDWixjQUFjLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxvQkFBb0IsQ0FBQyxJQUFJLENBQUM7Z0JBQ3pELFFBQVE7YUFDVDtTQUNGLENBQUE7SUFDSCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILHVCQUF1QixDQUFDLEVBQUMsSUFBSSxFQUFFLEVBQUUsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFDO1FBQzFELElBQUksSUFBSSxLQUFLLFNBQVMsSUFBSSxJQUFJLEtBQUssSUFBSTtZQUFFLE9BQU8sRUFBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUMsQ0FBQTtRQUVwRSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQztnQkFDSCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFBO2dCQUVuQyxJQUFJLENBQUMsVUFBVSxJQUFJLE9BQU8sVUFBVSxLQUFLLFFBQVEsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQztvQkFBRSxPQUFPLEVBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFDLENBQUE7Z0JBRTNHLE9BQU8sRUFBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxnQ0FBZ0MsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxFQUFDLENBQUE7WUFDeEUsQ0FBQztZQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7Z0JBQ2YsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLEVBQUUsQ0FBQyx3QkFBd0IsRUFBRSxFQUFDLEtBQUssRUFBRSxFQUFFLEVBQUUsVUFBVSxFQUFFLFlBQVksRUFBQyxDQUFDLENBQUE7Z0JBQ25GLE9BQU8sRUFBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFFBQVEsRUFBRSxFQUFDLEVBQUUsRUFBRSxTQUFTLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxjQUFjLEVBQUMsRUFBQyxDQUFBO1lBQ2pGLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxPQUFPLElBQUksS0FBSyxRQUFRLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7WUFBRSxPQUFPLEVBQUMsRUFBRSxFQUFFLElBQUksRUFBRSxJQUFJLEVBQUUsRUFBRSxFQUFDLENBQUE7UUFFaEYsT0FBTyxFQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxFQUFDLENBQUE7SUFDM0QsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMsdUJBQXVCLENBQUMsS0FBSztRQUNqQyxPQUFPLEVBQUMsT0FBTyxFQUFFLElBQUksRUFBQyxDQUFBO0lBQ3hCLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLHNCQUFzQixDQUFDLEVBQUMsS0FBSyxFQUFFLFFBQVEsRUFBQztRQUM1QyxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLElBQUksQ0FBQTtRQUVoQyxPQUFPLE1BQU0sSUFBSSxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUM7WUFDakMsQ0FBQyxJQUFJLENBQUMscUJBQXFCLENBQUMsRUFBRSxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQztZQUN2RCxXQUFXLEVBQUUsUUFBUSxDQUFDLFVBQVU7WUFDaEMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxZQUFZO1NBQ3JDLENBQUMsQ0FBQTtJQUNKLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsYUFBYSxDQUFDLEtBQUs7UUFDakIsSUFBSSxDQUFDLEtBQUssSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLElBQUksT0FBTyxLQUFLLENBQUMsRUFBRSxLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQzFFLE1BQU0sSUFBSSxLQUFLLENBQUMsOEdBQThHLENBQUMsQ0FBQTtRQUNqSSxDQUFDO1FBRUQsT0FBTyxLQUFLLENBQUMsRUFBRSxFQUFFLENBQUE7SUFDbkIsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMseUJBQXlCLENBQUMsRUFBQyxZQUFZLEVBQUUsUUFBUSxFQUFDO1FBQ3RELE1BQU0sdUJBQXVCLEdBQUcsSUFBSSxDQUFDLGlDQUFpQyxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBRXBGLE9BQU8sQ0FBQyx1QkFBdUIsSUFBSSxRQUFRLENBQUMsZUFBZSxHQUFHLHVCQUF1QixDQUFBO0lBQ3ZGLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsaUNBQWlDLENBQUMsWUFBWTtRQUM1QyxJQUFJLENBQUMsWUFBWSxJQUFJLE9BQU8sWUFBWSxLQUFLLFFBQVE7WUFBRSxPQUFPLElBQUksQ0FBQTtRQUVsRSxNQUFNLFVBQVUsR0FBRyxnQ0FBZ0MsQ0FBQyxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBQ2xFLE1BQU0sS0FBSyxHQUFHLE9BQU8sVUFBVSxDQUFDLGVBQWUsS0FBSyxVQUFVO1lBQzVELENBQUMsQ0FBQyxVQUFVLENBQUMsZUFBZSxFQUFFO1lBQzlCLENBQUMsQ0FBQyxVQUFVLENBQUMsZUFBZSxDQUFBO1FBRTlCLElBQUksS0FBSyxZQUFZLElBQUk7WUFBRSxPQUFPLEtBQUssQ0FBQTtRQUV2QyxJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVE7WUFBRSxPQUFPLElBQUksQ0FBQTtRQUUxQyxNQUFNLFdBQVcsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQTtRQUVuQyxPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsV0FBVyxDQUFBO0lBQ2pFLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLG1CQUFtQixDQUFDLElBQUk7UUFDNUIsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhO1lBQUUsT0FBTyxJQUFJLENBQUE7UUFFcEMsTUFBTSxZQUFZLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQyxDQUFBO1FBRW5FLElBQUksQ0FBQyxZQUFZO1lBQUUsTUFBTSxJQUFJLEtBQUssQ0FBQyx5Q0FBeUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxDQUFBO1FBRXpHLE9BQU8sTUFBTSxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUE7SUFDakMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxLQUFLLENBQUMscUJBQXFCLENBQUMsS0FBSztRQUMvQixPQUFPLElBQUksQ0FBQTtJQUNiLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLHFCQUFxQixDQUFDLEVBQUMsS0FBSyxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsWUFBWSxFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUM7UUFDNUYsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTO1lBQUUsT0FBTTtRQUUzQixNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsdUJBQXVCLENBQUMsRUFBQyxLQUFLLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQTtRQUVsRSw0RUFBNEU7UUFDNUUsOERBQThEO1FBQzlELElBQUksSUFBSSxDQUFDLHNCQUFzQixJQUFJLFdBQVcsRUFBRSxDQUFDO1lBQy9DLE1BQU0sQ0FBQyxNQUFNLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxFQUFDLEtBQUssRUFBRSxXQUFXLEVBQUUsT0FBTyxFQUFFLFlBQVksRUFBRSxRQUFRLEVBQUUsV0FBVyxFQUFDLENBQUMsQ0FBQyxDQUFBO1FBQzVILENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxxQkFBcUIsSUFBSSxXQUFXLEVBQUUsQ0FBQztZQUM5QyxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMscUJBQXFCLENBQUMsRUFBQyxXQUFXLEVBQUUsUUFBUSxFQUFDLENBQUMsQ0FBQTtZQUUxRSxJQUFJLGNBQWMsS0FBSyxTQUFTLElBQUksY0FBYyxLQUFLLElBQUksRUFBRSxDQUFDO2dCQUM1RCxVQUFVLENBQUMsSUFBSSxHQUFHLE9BQU8sY0FBYyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxDQUFBO1lBQ3hHLENBQUM7UUFDSCxDQUFDO1FBRUQsSUFBSSxZQUFZLEVBQUUsQ0FBQztZQUNqQixNQUFNLHVCQUF1QixHQUFHLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxZQUFZLENBQUMsQ0FBQTtZQUVwRixJQUFJLHVCQUF1QixJQUFJLFFBQVEsQ0FBQyxlQUFlLElBQUksdUJBQXVCO2dCQUFFLE9BQU07WUFFMUYsWUFBWSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQTtZQUMvQixNQUFNLFlBQVksQ0FBQyxxQkFBcUIsRUFBRSxDQUFBO1lBQzFDLE1BQU0sWUFBWSxDQUFDLElBQUksRUFBRSxDQUFBO1FBQzNCLENBQUM7YUFBTSxDQUFDO1lBQ04sTUFBTSxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUN6QyxDQUFDO0lBQ0gsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCx1QkFBdUIsQ0FBQyxFQUFDLEtBQUssRUFBRSxRQUFRLEVBQUM7UUFDdkMsT0FBTztZQUNMLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUM7WUFDdkQsaUJBQWlCLEVBQUUsUUFBUSxDQUFDLGVBQWU7WUFDM0MsSUFBSSxFQUFFLFFBQVEsQ0FBQyxjQUFjO1lBQzdCLFdBQVcsRUFBRSxRQUFRLENBQUMsVUFBVTtZQUNoQyxhQUFhLEVBQUUsUUFBUSxDQUFDLFlBQVk7WUFDcEMsU0FBUyxFQUFFLFFBQVEsQ0FBQyxRQUFRO1NBQzdCLENBQUE7SUFDSCxDQUFDO0lBRUQ7Ozs7Ozs7T0FPRztJQUNILEtBQUssQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJO1FBQzVCLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVc7WUFBRSxPQUFNO1FBQ2pELDRFQUE0RTtRQUM1RSwrRUFBK0U7UUFDL0UsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXO1lBQUUsT0FBTTtRQUU3QixLQUFLLE1BQU0sU0FBUyxJQUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN4QyxJQUFJLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFBRSxTQUFRO1lBRXJELE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQztnQkFDckIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUMxQixPQUFPLEVBQUUsT0FBTyxTQUFTLENBQUMsT0FBTyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU87Z0JBQzlGLE1BQU0sRUFBRSxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQzthQUN4QyxDQUFDLENBQUE7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBRUQ7Ozs7Ozs7OztHQVNHIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBTeW5jUmVwbGF5VXBzZXJ0QXBwbGllciBmcm9tIFwiLi9zeW5jLXJlcGxheS11cHNlcnQtYXBwbGllci5qc1wiXG5cbi8qKlxuICogT25lIGRlY2xhcmF0aXZlIGJyb2FkY2FzdCBmYW5uZWQgb3V0IGFmdGVyIGEgbXV0YXRpb24gYXBwbGllcy5cbiAqIEB0eXBlZGVmIHtvYmplY3R9IFN5bmNSZXBsYXlCcm9hZGNhc3RcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nIHwgKChhcmdzOiBSZWNvcmQ8c3RyaW5nLCA/PikgPT4gc3RyaW5nKX0gY2hhbm5lbCAtIENoYW5uZWwgbmFtZSBvciByZXNvbHZlci5cbiAqIEBwcm9wZXJ0eSB7KGFyZ3M6IFJlY29yZDxzdHJpbmcsID8+KSA9PiBSZWNvcmQ8c3RyaW5nLCA/Pn0gYnJvYWRjYXN0UGFyYW1zIC0gQ2hhbm5lbCByb3V0aW5nIHBhcmFtcy5cbiAqIEBwcm9wZXJ0eSB7KGFyZ3M6IFJlY29yZDxzdHJpbmcsID8+KSA9PiA/fSBib2R5IC0gQnJvYWRjYXN0IGJvZHkuXG4gKiBAcHJvcGVydHkgeyhhcmdzOiBSZWNvcmQ8c3RyaW5nLCA/PikgPT4gYm9vbGVhbn0gW3doZW5dIC0gT3B0aW9uYWwgZ2F0ZTsgc2tpcHBlZCB3aGVuIGl0IHJldHVybnMgZmFsc2UuXG4gKi9cblxuLyoqXG4gKiBSZXBsYXlzIGNsaWVudCBzeW5jIGVudmVsb3BlcyB0aHJvdWdoIHByb2plY3Qgc3VwcGxpZWQgYXV0aGVudGljYXRpb24sXG4gKiBhdXRob3JpemF0aW9uLCBhcHBsaWNhdGlvbiwgYW5kIHBlcnNpc3RlbmNlIGhvb2tzLlxuICpcbiAqIFRoaXMgaXMgaW50ZW50aW9uYWxseSB0cmFuc3BvcnQvbW9kZWwgYWdub3N0aWM6IFZlbG9jaW91cyBvd25zIHRoZSBnZW5lcmljXG4gKiByZXBsYXkgbG9vcCwgbm9ybWFsaXphdGlvbiwgc3RhbGUtY2xpZW50IGNvbXBhcmlzb24sIGFuZCBwZXItc3luYyByZXN1bHRcbiAqIHNoYXBlIHdoaWxlIGVhY2ggYXBwIG93bnMgaXRzIHRva2VuIGxvb2t1cCwgbW9kZWwgaGFuZGxlcnMsIGFuZFxuICogZG9tYWluIGF1dGhvcml6YXRpb24gcnVsZXMuXG4gKi9cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFN5bmNFbnZlbG9wZVJlcGxheVNlcnZpY2Uge1xuICAvKipcbiAgICogQ3JlYXRlcyBhIHN5bmMgZW52ZWxvcGUgcmVwbGF5IHNlcnZpY2UuXG4gICAqXG4gICAqIFdoZW4gYSBzeW5jIG1vZGVsIGlzIGdpdmVuLCBgZmluZEV4aXN0aW5nUmVwbGF5U3luY2AgYW5kXG4gICAqIGBwZXJzaXN0UmVwbGF5TXV0YXRpb25gIGdldCBtb2RlbC1iYWNrZWQgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbnMuIFRoZSBzeW5jXG4gICAqIG1vZGVsIG11c3QgZXhwb3NlIGBmaW5kQnlgL2BjcmVhdGVgIHN0YXRpY3MgcGx1cyBpbnN0YW5jZVxuICAgKiBgYXNzaWduYC9gc2F2ZWAvYGNsaWVudFVwZGF0ZWRBdGAgYW5kIGBhZHZhbmNlU2VydmVyU2VxdWVuY2VgICh0aGVcbiAgICogY2hhbmdlLWZlZWQgc2VxdWVuY2UgY29udHJhY3QpLCBhbmQgdGhlIGFjdG9yIHJldHVybmVkIGZyb21cbiAgICogYGF1dGhlbnRpY2F0ZVJlcGxheWAgbXVzdCBleHBvc2UgYW4gYGlkKClgIG1ldGhvZC5cbiAgICogQHBhcmFtIHtvYmplY3R9IFthcmdzXSAtIENvbnN0cnVjdG9yIGFyZ3VtZW50cy5cbiAgICogQHBhcmFtIHt7ZGVidWc/OiAoLi4uYXJnczogQXJyYXk8dW5rbm93bj4pID0+IHZvaWQsIHdhcm4/OiAoLi4uYXJnczogQXJyYXk8dW5rbm93bj4pID0+IHZvaWR9fSBbYXJncy5sb2dnZXJdIC0gTG9nZ2VyIHVzZWQgZm9yIG5vcm1hbGl6YXRpb24gd2FybmluZ3MuXG4gICAqIEBwYXJhbSB7P30gW2FyZ3Muc3luY01vZGVsXSAtIFN5bmMvY2hhbmdlIG1vZGVsIGVuYWJsaW5nIG1vZGVsLWJhY2tlZCBkZWZhdWx0IGhvb2tzLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uXSAtIFN5bmMgbW9kZWwgY29sdW1uIGxpbmtpbmcgcm93cyB0byB0aGUgcmVwbGF5IGFjdG9yLlxuICAgKiBAcGFyYW0gez99IFthcmdzLmF1dGhlbnRpY2F0aW9uVG9rZW5Nb2RlbF0gLSBUb2tlbiBtb2RlbCBlbmFibGluZyB0aGUgZGVmYXVsdCB0b2tlbi1sb29rdXAgYXV0aGVudGljYXRlUmVwbGF5LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuYXV0aGVudGljYXRpb25Ub2tlbkNvbHVtbl0gLSBUb2tlbiBtb2RlbCBjb2x1bW4gaG9sZGluZyB0aGUgdG9rZW4uIERlZmF1bHRzIHRvIFwidG9rZW5cIi5cbiAgICogQHBhcmFtIHtzdHJpbmd9IFthcmdzLmF1dGhlbnRpY2F0aW9uVG9rZW5QYXJhbV0gLSBSZXF1ZXN0IHBhcmFtIGNhcnJ5aW5nIHRoZSB0b2tlbi4gRGVmYXVsdHMgdG8gXCJhdXRoZW50aWNhdGlvblRva2VuXCIuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgKChhcmdzOiBSZWNvcmQ8c3RyaW5nLCA/PikgPT4gUHJvbWlzZTw/PikgfCBDb25zdHJ1Y3RvclBhcmFtZXRlcnM8dHlwZW9mIFN5bmNSZXBsYXlVcHNlcnRBcHBsaWVyPlswXT59IFthcmdzLmFwcGx5SGFuZGxlcnNdIC0gUGVyLXJlc291cmNlVHlwZSBhcHBseSBoYW5kbGVycyAoZnVuY3Rpb25zIG9yIGRlY2xhcmF0aXZlIHVwc2VydC1hcHBsaWVyIHNwZWNzKSBlbmFibGluZyB0aGUgZGVmYXVsdCBhcHBseVJlcGxheU11dGF0aW9uIGRpc3BhdGNoLlxuICAgKiBAcGFyYW0geyhhcmdzOiBSZWNvcmQ8c3RyaW5nLCA/PikgPT4gUmVjb3JkPHN0cmluZywgPz59IFthcmdzLnBlcnNpc3RFeHRyYUF0dHJpYnV0ZXNdIC0gRXh0cmEgYXR0cmlidXRlcyBtZXJnZWQgaW50byB0aGUgbW9kZWwtYmFja2VkIHBlcnNpc3RlZCByb3cgKGUuZy4gYW4gZXZlbnQgc2NvcGUgY29sdW1uKS5cbiAgICogQHBhcmFtIHsoYXJnczoge211dGF0aW9uOiA/LCBhcHBseVJlc3VsdDogP30pID0+ID99IFthcmdzLnBlcnNpc3RTZXJpYWxpemVkRGF0YV0gLSBPdmVycmlkZXMgdGhlIHBlcnNpc3RlZCBkYXRhIHBheWxvYWQgKG9iamVjdCByZXN1bHRzIGFyZSBKU09OIHN0cmluZ2lmaWVkKS5cbiAgICogQHBhcmFtIHsoYnJvYWRjYXN0OiB7Y2hhbm5lbDogc3RyaW5nLCBwYXJhbXM6IFJlY29yZDxzdHJpbmcsID8+LCBib2R5OiA/fSkgPT4gUHJvbWlzZTx2b2lkPn0gW2FyZ3MuYnJvYWRjYXN0ZXJdIC0gRGVsaXZlcnMgZGVjbGFyYXRpdmUgYnJvYWRjYXN0cy4gUmVxdWlyZWQgd2hlbiBicm9hZGNhc3RzIGFyZSBjb25maWd1cmVkLlxuICAgKiBAcGFyYW0ge1N5bmNSZXBsYXlCcm9hZGNhc3RbXX0gW2FyZ3MuYnJvYWRjYXN0c10gLSBCcm9hZGNhc3RzIGZhbm5lZCBvdXQgYnkgdGhlIGRlZmF1bHQgYWZ0ZXJSZXBsYXlNdXRhdGlvbi5cbiAgICovXG4gIGNvbnN0cnVjdG9yKGFyZ3MgPSB7fSkge1xuICAgIHRoaXMubG9nZ2VyID0gYXJncy5sb2dnZXIgfHwgY29uc29sZVxuICAgIHRoaXMuc3luY01vZGVsID0gYXJncy5zeW5jTW9kZWwgfHwgbnVsbFxuICAgIHRoaXMuYWN0b3JGb3JlaWduS2V5Q29sdW1uID0gYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW4gfHwgXCJhdXRoZW50aWNhdGlvbl90b2tlbl9pZFwiXG4gICAgdGhpcy5hdXRoZW50aWNhdGlvblRva2VuTW9kZWwgPSBhcmdzLmF1dGhlbnRpY2F0aW9uVG9rZW5Nb2RlbCB8fCBudWxsXG4gICAgdGhpcy5hdXRoZW50aWNhdGlvblRva2VuQ29sdW1uID0gYXJncy5hdXRoZW50aWNhdGlvblRva2VuQ29sdW1uIHx8IFwidG9rZW5cIlxuICAgIHRoaXMuYXV0aGVudGljYXRpb25Ub2tlblBhcmFtID0gYXJncy5hdXRoZW50aWNhdGlvblRva2VuUGFyYW0gfHwgXCJhdXRoZW50aWNhdGlvblRva2VuXCJcbiAgICB0aGlzLnBlcnNpc3RFeHRyYUF0dHJpYnV0ZXMgPSBhcmdzLnBlcnNpc3RFeHRyYUF0dHJpYnV0ZXMgfHwgbnVsbFxuICAgIHRoaXMucGVyc2lzdFNlcmlhbGl6ZWREYXRhID0gYXJncy5wZXJzaXN0U2VyaWFsaXplZERhdGEgfHwgbnVsbFxuICAgIHRoaXMuYnJvYWRjYXN0ZXIgPSBhcmdzLmJyb2FkY2FzdGVyIHx8IG51bGxcbiAgICB0aGlzLmJyb2FkY2FzdHMgPSBhcmdzLmJyb2FkY2FzdHMgfHwgbnVsbFxuICAgIHRoaXMuYXBwbHlIYW5kbGVycyA9IGFyZ3MuYXBwbHlIYW5kbGVycyA/IHRoaXMuYnVpbHRBcHBseUhhbmRsZXJzKGFyZ3MuYXBwbHlIYW5kbGVycykgOiBudWxsXG5cbiAgICBpZiAoYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW4gIT09IHVuZGVmaW5lZCAmJiAodHlwZW9mIGFyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uICE9PSBcInN0cmluZ1wiIHx8IGFyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uLmxlbmd0aCA8IDEpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYGFjdG9yRm9yZWlnbktleUNvbHVtbiBtdXN0IGJlIGEgbm9uLWJsYW5rIHN0cmluZywgZ290OiAke1N0cmluZyhhcmdzLmFjdG9yRm9yZWlnbktleUNvbHVtbil9YClcbiAgICB9XG4gICAgaWYgKHRoaXMuYnJvYWRjYXN0cyAmJiAhdGhpcy5icm9hZGNhc3Rlcikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSBicm9hZGNhc3RzIHJlcXVpcmUgYSBicm9hZGNhc3RlciBvcHRpb24gZGVsaXZlcmluZyB0aGVtXCIpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFdyYXBzIGRlY2xhcmF0aXZlIGFwcGx5LWhhbmRsZXIgc3BlY3MgaW4gdXBzZXJ0IGFwcGxpZXJzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBhcHBseUhhbmRsZXJzIC0gUmF3IGFwcGx5IGhhbmRsZXJzLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgKGFyZ3M6IFJlY29yZDxzdHJpbmcsID8+KSA9PiBQcm9taXNlPD8+Pn0gQ2FsbGFibGUgaGFuZGxlcnMgYnkgcmVzb3VyY2UgdHlwZS5cbiAgICovXG4gIGJ1aWx0QXBwbHlIYW5kbGVycyhhcHBseUhhbmRsZXJzKSB7XG4gICAgcmV0dXJuIE9iamVjdC5mcm9tRW50cmllcyhPYmplY3QuZW50cmllcyhhcHBseUhhbmRsZXJzKS5tYXAoKFtyZXNvdXJjZVR5cGUsIGhhbmRsZXJdKSA9PiB7XG4gICAgICBpZiAodHlwZW9mIGhhbmRsZXIgPT09IFwiZnVuY3Rpb25cIikgcmV0dXJuIFtyZXNvdXJjZVR5cGUsIGhhbmRsZXJdXG5cbiAgICAgIGNvbnN0IGFwcGxpZXIgPSBuZXcgU3luY1JlcGxheVVwc2VydEFwcGxpZXIoaGFuZGxlcilcblxuICAgICAgcmV0dXJuIFtyZXNvdXJjZVR5cGUsICgvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyBhcHBseUFyZ3MpID0+IGFwcGxpZXIuYXBwbHkoLyoqIEB0eXBlIHs/fSAqLyAoYXBwbHlBcmdzKSldXG4gICAgfSkpXG4gIH1cblxuICAvKipcbiAgICogUmVwbGF5cyBhIHN5bmMgYmF0Y2guXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IHBhcmFtcyAtIFJlcXVlc3QgcGFyYW1zIGNhcnJ5aW5nIGF1dGhlbnRpY2F0aW9uIGFuZCBzeW5jcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8e3N5bmNzOiBBcnJheTxSZWNvcmQ8c3RyaW5nLCA/Pj4sIHN0YXR1cz86IHN0cmluZywgZXJyb3JDb2RlPzogc3RyaW5nLCBlcnJvck1lc3NhZ2U/OiBzdHJpbmd9Pn0gUmVwbGF5IHJlc3BvbnNlLlxuICAgKi9cbiAgYXN5bmMgcmVwbGF5KHBhcmFtcykge1xuICAgIGNvbnN0IGFjdG9yUmVzdWx0ID0gYXdhaXQgdGhpcy5hdXRoZW50aWNhdGVSZXBsYXkocGFyYW1zKVxuXG4gICAgaWYgKCFhY3RvclJlc3VsdC5hdXRoZW50aWNhdGVkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBzeW5jczogW10sXG4gICAgICAgIHN0YXR1czogXCJlcnJvclwiLFxuICAgICAgICBlcnJvckNvZGU6IGFjdG9yUmVzdWx0LmVycm9yQ29kZSxcbiAgICAgICAgZXJyb3JNZXNzYWdlOiBhY3RvclJlc3VsdC5lcnJvck1lc3NhZ2VcbiAgICAgIH1cbiAgICB9XG5cbiAgICBjb25zdCBzeW5jUmVzcG9uc2VzID0gW11cbiAgICBjb25zdCBjb250ZXh0ID0gYXdhaXQgdGhpcy5idWlsZFJlcGxheUNvbnRleHQoe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgcGFyYW1zfSlcblxuICAgIGZvciAoY29uc3QgcmF3U3luYyBvZiB0aGlzLnJlcGxheVN5bmNzKHBhcmFtcykpIHtcbiAgICAgIGNvbnN0IG5vcm1hbGl6ZWRSZXN1bHQgPSB0aGlzLm5vcm1hbGl6ZVJlcGxheVN5bmMocmF3U3luYylcblxuICAgICAgaWYgKCFub3JtYWxpemVkUmVzdWx0Lm9rKSB7XG4gICAgICAgIHN5bmNSZXNwb25zZXMucHVzaChub3JtYWxpemVkUmVzdWx0LnJlc3BvbnNlKVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBtdXRhdGlvbiA9IG5vcm1hbGl6ZWRSZXN1bHQubXV0YXRpb25cbiAgICAgIGNvbnN0IGFjY2Vzc1Jlc3VsdCA9IGF3YWl0IHRoaXMuYXV0aG9yaXplUmVwbGF5TXV0YXRpb24oe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgbXV0YXRpb259KVxuXG4gICAgICBpZiAoIWFjY2Vzc1Jlc3VsdC5hbGxvd2VkKSB7XG4gICAgICAgIHN5bmNSZXNwb25zZXMucHVzaCh7XG4gICAgICAgICAgaWQ6IG11dGF0aW9uLmlkLFxuICAgICAgICAgIHN5bmNTdGF0ZTogXCJmYWlsZWRcIixcbiAgICAgICAgICByZWFzb246IGFjY2Vzc1Jlc3VsdC5yZWFzb24gfHwgXCJhY2Nlc3MtZGVuaWVkXCJcbiAgICAgICAgfSlcbiAgICAgICAgY29udGludWVcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXhpc3RpbmdTeW5jID0gYXdhaXQgdGhpcy5maW5kRXhpc3RpbmdSZXBsYXlTeW5jKHthY3RvcjogYWN0b3JSZXN1bHQuYWN0b3IsIGNvbnRleHQsIG11dGF0aW9ufSlcbiAgICAgIGNvbnN0IHNob3VsZEFwcGx5ID0gYXdhaXQgdGhpcy5zaG91bGRBcHBseVJlcGxheU11dGF0aW9uKHthY3RvcjogYWN0b3JSZXN1bHQuYWN0b3IsIGNvbnRleHQsIGV4aXN0aW5nU3luYywgbXV0YXRpb259KVxuICAgICAgY29uc3QgYXBwbHlSZXN1bHQgPSBzaG91bGRBcHBseVxuICAgICAgICA/IGF3YWl0IHRoaXMuYXBwbHlSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIG11dGF0aW9ufSlcbiAgICAgICAgOiBhd2FpdCB0aGlzLnNraXBwZWRSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIG11dGF0aW9ufSlcblxuICAgICAgYXdhaXQgdGhpcy5wZXJzaXN0UmVwbGF5TXV0YXRpb24oe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBhcHBseVJlc3VsdCwgbXV0YXRpb24sIHNob3VsZEFwcGx5fSlcbiAgICAgIGF3YWl0IHRoaXMuYWZ0ZXJSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIGFwcGx5UmVzdWx0LCBtdXRhdGlvbiwgc2hvdWxkQXBwbHl9KVxuXG4gICAgICBzeW5jUmVzcG9uc2VzLnB1c2goe2lkOiBtdXRhdGlvbi5pZCwgc3luY1N0YXRlOiBcInN1Y2Nlc3NmdWxcIn0pXG4gICAgfVxuXG4gICAgcmV0dXJuIHtzeW5jczogc3luY1Jlc3BvbnNlc31cbiAgfVxuXG4gIC8qKlxuICAgKiBBdXRoZW50aWNhdGVzIHRoZSBzeW5jIGJhdGNoIGFjdG9yLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBhIHRva2VuLW1vZGVsIGxvb2t1cCB3aGVuIGBhdXRoZW50aWNhdGlvblRva2VuTW9kZWxgIGlzXG4gICAqIGNvbmZpZ3VyZWQ7IG90aGVyd2lzZSBhcHBzIG92ZXJyaWRlIHRoaXMgaG9vay5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gcGFyYW1zIC0gUmVxdWVzdCBwYXJhbXMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHthdXRoZW50aWNhdGVkOiB0cnVlLCBhY3RvcjogP30gfCB7YXV0aGVudGljYXRlZDogZmFsc2UsIGVycm9yQ29kZTogc3RyaW5nLCBlcnJvck1lc3NhZ2U6IHN0cmluZ30+fSBBdXRoIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIGF1dGhlbnRpY2F0ZVJlcGxheShwYXJhbXMpIHtcbiAgICBpZiAoIXRoaXMuYXV0aGVudGljYXRpb25Ub2tlbk1vZGVsKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jRW52ZWxvcGVSZXBsYXlTZXJ2aWNlLmF1dGhlbnRpY2F0ZVJlcGxheSBtdXN0IGJlIGltcGxlbWVudGVkIChvciBjb25maWd1cmUgYXV0aGVudGljYXRpb25Ub2tlbk1vZGVsKVwiKVxuICAgIH1cblxuICAgIGNvbnN0IHRva2VuID0gcGFyYW1zW3RoaXMuYXV0aGVudGljYXRpb25Ub2tlblBhcmFtXVxuXG4gICAgaWYgKCF0b2tlbikge1xuICAgICAgcmV0dXJuIHthdXRoZW50aWNhdGVkOiBmYWxzZSwgZXJyb3JDb2RlOiBcIm1pc3NpbmctYXV0aGVudGljYXRpb24tdG9rZW5cIiwgZXJyb3JNZXNzYWdlOiBcIk1pc3NpbmcgYXV0aGVudGljYXRpb24gdG9rZW5cIn1cbiAgICB9XG5cbiAgICBjb25zdCBhY3RvciA9IGF3YWl0IHRoaXMuYXV0aGVudGljYXRpb25Ub2tlbk1vZGVsLmZpbmRCeSh7W3RoaXMuYXV0aGVudGljYXRpb25Ub2tlbkNvbHVtbl06IHRva2VufSlcblxuICAgIGlmICghYWN0b3IpIHtcbiAgICAgIHJldHVybiB7YXV0aGVudGljYXRlZDogZmFsc2UsIGVycm9yQ29kZTogXCJpbnZhbGlkLWF1dGhlbnRpY2F0aW9uLXRva2VuXCIsIGVycm9yTWVzc2FnZTogXCJJbnZhbGlkIGF1dGhlbnRpY2F0aW9uIHRva2VuXCJ9XG4gICAgfVxuXG4gICAgcmV0dXJuIHthY3RvciwgYXV0aGVudGljYXRlZDogdHJ1ZX1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgcGVyLWJhdGNoIG11dGFibGUgY29udGV4dCBmb3IgY2FjaGVzIHNoYXJlZCBhY3Jvc3Mgc3luYyBpdGVtcy5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIHBhcmFtczogUmVjb3JkPHN0cmluZywgPz59fSBfYXJncyAtIEFjdG9yIGFuZCByZXF1ZXN0IHBhcmFtcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fSBSZXBsYXkgY29udGV4dC5cbiAgICovXG4gIGFzeW5jIGJ1aWxkUmVwbGF5Q29udGV4dChfYXJncykge1xuICAgIHJldHVybiB7fVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgcmF3IHN5bmMgZW50cmllcyBmcm9tIHJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBwYXJhbXMgLSBSZXF1ZXN0IHBhcmFtcy5cbiAgICogQHJldHVybnMge0FycmF5PD8+fSBSYXcgc3luYyBlbnRyaWVzLlxuICAgKi9cbiAgcmVwbGF5U3luY3MocGFyYW1zKSB7XG4gICAgcmV0dXJuIEFycmF5LmlzQXJyYXkocGFyYW1zLnN5bmNzKSA/IHBhcmFtcy5zeW5jcyA6IFtdXG4gIH1cblxuICAvKipcbiAgICogTm9ybWFsaXplcyBvbmUgc3luYyBlbnRyeS5cbiAgICogQHBhcmFtIHs/fSByYXdTeW5jIC0gUmF3IHN5bmMgZW50cnkuXG4gICAqIEByZXR1cm5zIHt7b2s6IHRydWUsIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufSB8IHtvazogZmFsc2UsIHJlc3BvbnNlOiBSZWNvcmQ8c3RyaW5nLCA/Pn19IE5vcm1hbGl6ZWQgbXV0YXRpb24gb3IgZmFpbGVkIHJlc3BvbnNlLlxuICAgKi9cbiAgbm9ybWFsaXplUmVwbGF5U3luYyhyYXdTeW5jKSB7XG4gICAgaWYgKCFyYXdTeW5jIHx8IHR5cGVvZiByYXdTeW5jICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkocmF3U3luYykpIHtcbiAgICAgIHJldHVybiB7b2s6IGZhbHNlLCByZXNwb25zZToge2lkOiB1bmRlZmluZWQsIHN5bmNTdGF0ZTogXCJmYWlsZWRcIiwgcmVhc29uOiBcImludmFsaWQtc3luY1wifX1cbiAgICB9XG5cbiAgICBjb25zdCBzeW5jID0gLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHJhd1N5bmMpXG4gICAgY29uc3Qge2NsaWVudFVwZGF0ZWRBdCwgZGF0YSwgaWQsIHJlc291cmNlSWQsIHJlc291cmNlVHlwZSwgc3luY1R5cGV9ID0gc3luY1xuXG4gICAgaWYgKHR5cGVvZiByZXNvdXJjZVR5cGUgIT09IFwic3RyaW5nXCIgfHwgcmVzb3VyY2VUeXBlLmxlbmd0aCA8IDEgfHwgcmVzb3VyY2VJZCA9PT0gdW5kZWZpbmVkIHx8IHJlc291cmNlSWQgPT09IG51bGwgfHwgdHlwZW9mIHN5bmNUeXBlICE9PSBcInN0cmluZ1wiIHx8IHN5bmNUeXBlLmxlbmd0aCA8IDEpIHtcbiAgICAgIHJldHVybiB7b2s6IGZhbHNlLCByZXNwb25zZToge2lkLCBzeW5jU3RhdGU6IFwiZmFpbGVkXCIsIHJlYXNvbjogXCJpbnZhbGlkLXJlc291cmNlLWlkXCJ9fVxuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlSWRTdHJpbmcgPSBTdHJpbmcocmVzb3VyY2VJZClcbiAgICBsZXQgY2xpZW50VXBkYXRlZEF0RGF0ZSA9IHR5cGVvZiBjbGllbnRVcGRhdGVkQXQgPT09IFwic3RyaW5nXCIgfHwgY2xpZW50VXBkYXRlZEF0IGluc3RhbmNlb2YgRGF0ZSA/IG5ldyBEYXRlKGNsaWVudFVwZGF0ZWRBdCkgOiBuZXcgRGF0ZSgpXG5cbiAgICBpZiAoTnVtYmVyLmlzTmFOKGNsaWVudFVwZGF0ZWRBdERhdGUuZ2V0VGltZSgpKSkgY2xpZW50VXBkYXRlZEF0RGF0ZSA9IG5ldyBEYXRlKClcblxuICAgIGNvbnN0IG5vcm1hbGl6ZWREYXRhUmVzdWx0ID0gdGhpcy5ub3JtYWxpemVSZXBsYXlTeW5jRGF0YSh7ZGF0YSwgaWQsIHJlc291cmNlSWQ6IHJlc291cmNlSWRTdHJpbmcsIHJlc291cmNlVHlwZX0pXG5cbiAgICBpZiAoIW5vcm1hbGl6ZWREYXRhUmVzdWx0Lm9rKSByZXR1cm4gbm9ybWFsaXplZERhdGFSZXN1bHRcblxuICAgIHJldHVybiB7XG4gICAgICBvazogdHJ1ZSxcbiAgICAgIG11dGF0aW9uOiB7XG4gICAgICAgIGNsaWVudFVwZGF0ZWRBdDogY2xpZW50VXBkYXRlZEF0RGF0ZSxcbiAgICAgICAgZGF0YTogbm9ybWFsaXplZERhdGFSZXN1bHQuZGF0YSxcbiAgICAgICAgaWQsXG4gICAgICAgIHJlc291cmNlSWQ6IHJlc291cmNlSWRTdHJpbmcsXG4gICAgICAgIHJlc291cmNlVHlwZSxcbiAgICAgICAgc2VyaWFsaXplZERhdGE6IEpTT04uc3RyaW5naWZ5KG5vcm1hbGl6ZWREYXRhUmVzdWx0LmRhdGEpLFxuICAgICAgICBzeW5jVHlwZVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIG9uZSBzeW5jIGRhdGEgcGF5bG9hZC5cbiAgICogQHBhcmFtIHt7ZGF0YTogPywgaWQ6ID8sIHJlc291cmNlSWQ6IHN0cmluZywgcmVzb3VyY2VUeXBlOiBzdHJpbmd9fSBhcmdzIC0gU3luYyBwYXlsb2FkIG5vcm1hbGl6YXRpb24gYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyB7e29rOiB0cnVlLCBkYXRhOiBSZWNvcmQ8c3RyaW5nLCA/Pn0gfCB7b2s6IGZhbHNlLCByZXNwb25zZTogUmVjb3JkPHN0cmluZywgPz59fSBOb3JtYWxpemVkIHBheWxvYWQgb3IgZmFpbGVkIHJlc3BvbnNlLlxuICAgKi9cbiAgbm9ybWFsaXplUmVwbGF5U3luY0RhdGEoe2RhdGEsIGlkLCByZXNvdXJjZUlkLCByZXNvdXJjZVR5cGV9KSB7XG4gICAgaWYgKGRhdGEgPT09IHVuZGVmaW5lZCB8fCBkYXRhID09PSBudWxsKSByZXR1cm4ge29rOiB0cnVlLCBkYXRhOiB7fX1cblxuICAgIGlmICh0eXBlb2YgZGF0YSA9PT0gXCJzdHJpbmdcIikge1xuICAgICAgdHJ5IHtcbiAgICAgICAgY29uc3QgcGFyc2VkRGF0YSA9IEpTT04ucGFyc2UoZGF0YSlcblxuICAgICAgICBpZiAoIXBhcnNlZERhdGEgfHwgdHlwZW9mIHBhcnNlZERhdGEgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShwYXJzZWREYXRhKSkgcmV0dXJuIHtvazogdHJ1ZSwgZGF0YToge319XG5cbiAgICAgICAgcmV0dXJuIHtvazogdHJ1ZSwgZGF0YTogLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKHBhcnNlZERhdGEpfVxuICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgdGhpcy5sb2dnZXIud2Fybj8uKFwiSW52YWxpZCBzeW5jIGRhdGEgSlNPTlwiLCB7ZXJyb3IsIGlkLCByZXNvdXJjZUlkLCByZXNvdXJjZVR5cGV9KVxuICAgICAgICByZXR1cm4ge29rOiBmYWxzZSwgcmVzcG9uc2U6IHtpZCwgc3luY1N0YXRlOiBcImZhaWxlZFwiLCByZWFzb246IFwiaW52YWxpZC1kYXRhXCJ9fVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmICh0eXBlb2YgZGF0YSAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGRhdGEpKSByZXR1cm4ge29rOiB0cnVlLCBkYXRhOiB7fX1cblxuICAgIHJldHVybiB7b2s6IHRydWUsIGRhdGE6IEpTT04ucGFyc2UoSlNPTi5zdHJpbmdpZnkoZGF0YSkpfVxuICB9XG5cbiAgLyoqXG4gICAqIEF1dGhvcml6ZXMgb25lIG5vcm1hbGl6ZWQgbXV0YXRpb24uXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBfYXJncyAtIEFjdG9yLCBiYXRjaCBjb250ZXh0LCBhbmQgbXV0YXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHthbGxvd2VkOiBib29sZWFuLCByZWFzb24/OiBzdHJpbmd9Pn0gQWNjZXNzIHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIGF1dGhvcml6ZVJlcGxheU11dGF0aW9uKF9hcmdzKSB7XG4gICAgcmV0dXJuIHthbGxvd2VkOiB0cnVlfVxuICB9XG5cbiAgLyoqXG4gICAqIExvYWRzIHRoZSBwcmV2aW91c2x5IHN0b3JlZCBzeW5jL2NoYW5nZSByb3cgZm9yIHN0YWxlLWNsaWVudCBjb21wYXJpc29uLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBhIHN5bmMtbW9kZWwgbG9va3VwIGJ5IGFjdG9yIGFuZCByZXNvdXJjZSBpZGVudGl0eSB3aGVuIGEgc3luY1xuICAgKiBtb2RlbCBpcyBjb25maWd1cmVkOyBvdGhlcndpc2UgYXBwcyBvdmVycmlkZSB0aGlzIGhvb2suXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBhcmdzIC0gQWN0b3IsIGJhdGNoIGNvbnRleHQsIGFuZCBtdXRhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Pz59IEV4aXN0aW5nIHN5bmMgcm93LlxuICAgKi9cbiAgYXN5bmMgZmluZEV4aXN0aW5nUmVwbGF5U3luYyh7YWN0b3IsIG11dGF0aW9ufSkge1xuICAgIGlmICghdGhpcy5zeW5jTW9kZWwpIHJldHVybiBudWxsXG5cbiAgICByZXR1cm4gYXdhaXQgdGhpcy5zeW5jTW9kZWwuZmluZEJ5KHtcbiAgICAgIFt0aGlzLmFjdG9yRm9yZWlnbktleUNvbHVtbl06IHRoaXMucmVwbGF5QWN0b3JJZChhY3RvciksXG4gICAgICByZXNvdXJjZV9pZDogbXV0YXRpb24ucmVzb3VyY2VJZCxcbiAgICAgIHJlc291cmNlX3R5cGU6IG11dGF0aW9uLnJlc291cmNlVHlwZVxuICAgIH0pXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgdGhlIHBlcnNpc3RlZCBhY3RvciBpZCB1c2VkIGJ5IG1vZGVsLWJhY2tlZCBkZWZhdWx0IGhvb2tzLlxuICAgKiBAcGFyYW0gez99IGFjdG9yIC0gQWN0b3IgcmV0dXJuZWQgZnJvbSBhdXRoZW50aWNhdGVSZXBsYXkuXG4gICAqIEByZXR1cm5zIHs/fSBBY3RvciBpZC5cbiAgICovXG4gIHJlcGxheUFjdG9ySWQoYWN0b3IpIHtcbiAgICBpZiAoIWFjdG9yIHx8IHR5cGVvZiBhY3RvciAhPT0gXCJvYmplY3RcIiB8fCB0eXBlb2YgYWN0b3IuaWQgIT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKFwiU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSBtb2RlbC1iYWNrZWQgZGVmYXVsdHMgcmVxdWlyZSBhbiBhY3RvciB3aXRoIGFuIGlkKCkgbWV0aG9kIGZyb20gYXV0aGVudGljYXRlUmVwbGF5XCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIGFjdG9yLmlkKClcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXIgYSBub3JtYWxpemVkIG11dGF0aW9uIHNob3VsZCBiZSBhcHBsaWVkIHRvIGRvbWFpbiBtb2RlbHMuXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgZXhpc3RpbmdTeW5jOiA/LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn19IGFyZ3MgLSBBY3RvciwgYmF0Y2ggY29udGV4dCwgZXhpc3Rpbmcgc3luYyByb3csIGFuZCBtdXRhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IFdoZXRoZXIgdG8gYXBwbHkgdGhlIG11dGF0aW9uLlxuICAgKi9cbiAgYXN5bmMgc2hvdWxkQXBwbHlSZXBsYXlNdXRhdGlvbih7ZXhpc3RpbmdTeW5jLCBtdXRhdGlvbn0pIHtcbiAgICBjb25zdCBleGlzdGluZ0NsaWVudFVwZGF0ZWRBdCA9IHRoaXMuZXhpc3RpbmdSZXBsYXlTeW5jQ2xpZW50VXBkYXRlZEF0KGV4aXN0aW5nU3luYylcblxuICAgIHJldHVybiAhZXhpc3RpbmdDbGllbnRVcGRhdGVkQXQgfHwgbXV0YXRpb24uY2xpZW50VXBkYXRlZEF0ID4gZXhpc3RpbmdDbGllbnRVcGRhdGVkQXRcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgY2xpZW50IHRpbWVzdGFtcCBmcm9tIGFuIGV4aXN0aW5nIHN5bmMgcm93LlxuICAgKiBAcGFyYW0gez99IGV4aXN0aW5nU3luYyAtIEV4aXN0aW5nIHN5bmMgcm93LlxuICAgKiBAcmV0dXJucyB7RGF0ZSB8IG51bGx9IEV4aXN0aW5nIGNsaWVudCB0aW1lc3RhbXAuXG4gICAqL1xuICBleGlzdGluZ1JlcGxheVN5bmNDbGllbnRVcGRhdGVkQXQoZXhpc3RpbmdTeW5jKSB7XG4gICAgaWYgKCFleGlzdGluZ1N5bmMgfHwgdHlwZW9mIGV4aXN0aW5nU3luYyAhPT0gXCJvYmplY3RcIikgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHN5bmNSZWNvcmQgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAoZXhpc3RpbmdTeW5jKVxuICAgIGNvbnN0IHZhbHVlID0gdHlwZW9mIHN5bmNSZWNvcmQuY2xpZW50VXBkYXRlZEF0ID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gc3luY1JlY29yZC5jbGllbnRVcGRhdGVkQXQoKVxuICAgICAgOiBzeW5jUmVjb3JkLmNsaWVudFVwZGF0ZWRBdFxuXG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgRGF0ZSkgcmV0dXJuIHZhbHVlXG5cbiAgICBpZiAodHlwZW9mIHZhbHVlICE9PSBcInN0cmluZ1wiKSByZXR1cm4gbnVsbFxuXG4gICAgY29uc3QgcGFyc2VkVmFsdWUgPSBuZXcgRGF0ZSh2YWx1ZSlcblxuICAgIHJldHVybiBOdW1iZXIuaXNOYU4ocGFyc2VkVmFsdWUuZ2V0VGltZSgpKSA/IG51bGwgOiBwYXJzZWRWYWx1ZVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgb25lIG5vcm1hbGl6ZWQgbXV0YXRpb24gdG8gZG9tYWluIG1vZGVscy5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gZGlzcGF0Y2hpbmcgdGhyb3VnaCB0aGUgY29uZmlndXJlZCBhcHBseS1oYW5kbGVyIHJlZ2lzdHJ5O1xuICAgKiBtdXRhdGlvbnMgd2l0aG91dCBhIHJlZ2lzdGVyZWQgaGFuZGxlciBmYWlsIGxvdWRseS5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsID8+LCBleGlzdGluZ1N5bmM6ID8sIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufX0gYXJncyAtIEFjdG9yLCBiYXRjaCBjb250ZXh0LCBleGlzdGluZyBzeW5jIHJvdywgYW5kIG11dGF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gUHJvamVjdC1zcGVjaWZpYyBhcHBseSByZXN1bHQuXG4gICAqL1xuICBhc3luYyBhcHBseVJlcGxheU11dGF0aW9uKGFyZ3MpIHtcbiAgICBpZiAoIXRoaXMuYXBwbHlIYW5kbGVycykgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IGFwcGx5SGFuZGxlciA9IHRoaXMuYXBwbHlIYW5kbGVyc1thcmdzLm11dGF0aW9uLnJlc291cmNlVHlwZV1cblxuICAgIGlmICghYXBwbHlIYW5kbGVyKSB0aHJvdyBuZXcgRXJyb3IoYE5vIHN5bmMgYXBwbHkgaGFuZGxlciByZWdpc3RlcmVkIGZvcjogJHthcmdzLm11dGF0aW9uLnJlc291cmNlVHlwZX1gKVxuXG4gICAgcmV0dXJuIGF3YWl0IGFwcGx5SGFuZGxlcihhcmdzKVxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIGFuIGFwcGx5IHJlc3VsdCBmb3Igc3RhbGUgbXV0YXRpb25zIHRoYXQgc2hvdWxkIG5vdCB0b3VjaCBkb21haW4gbW9kZWxzLlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgY29udGV4dDogUmVjb3JkPHN0cmluZywgPz4sIGV4aXN0aW5nU3luYzogPywgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBfYXJncyAtIEFjdG9yLCBiYXRjaCBjb250ZXh0LCBleGlzdGluZyBzeW5jIHJvdywgYW5kIG11dGF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gUHJvamVjdC1zcGVjaWZpYyBhcHBseSByZXN1bHQuXG4gICAqL1xuICBhc3luYyBza2lwcGVkUmVwbGF5TXV0YXRpb24oX2FyZ3MpIHtcbiAgICByZXR1cm4gbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIFBlcnNpc3RzIG9uZSBub3JtYWxpemVkIG11dGF0aW9uIGludG8gdGhlIGFwcCBzeW5jL2NoYW5nZSBzdG9yZS5cbiAgICpcbiAgICogRGVmYXVsdHMgdG8gYSBzdGFsZS1ndWFyZGVkIHN5bmMtbW9kZWwgdXBzZXJ0ICh3aXRoIHNlcnZlciByZS1zZXF1ZW5jaW5nIG9uXG4gICAqIHVwZGF0ZXMpIHdoZW4gYSBzeW5jIG1vZGVsIGlzIGNvbmZpZ3VyZWQ7IG90aGVyd2lzZSBhcHBzIG92ZXJyaWRlIHRoaXMgaG9vay5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsID8+LCBleGlzdGluZ1N5bmM6ID8sIGFwcGx5UmVzdWx0OiA/LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbiwgc2hvdWxkQXBwbHk6IGJvb2xlYW59fSBhcmdzIC0gUmVwbGF5IHBlcnNpc3RlbmNlIGFyZ3VtZW50cy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59XG4gICAqL1xuICBhc3luYyBwZXJzaXN0UmVwbGF5TXV0YXRpb24oe2FjdG9yLCBhcHBseVJlc3VsdCwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBtdXRhdGlvbiwgc2hvdWxkQXBwbHl9KSB7XG4gICAgaWYgKCF0aGlzLnN5bmNNb2RlbCkgcmV0dXJuXG5cbiAgICBjb25zdCBhdHRyaWJ1dGVzID0gdGhpcy5yZXBsYXlQZXJzaXN0QXR0cmlidXRlcyh7YWN0b3IsIG11dGF0aW9ufSlcblxuICAgIC8vIFN0YWxlIHJlcGxheXMgbmV2ZXIgYXBwbGllZCBhbnl0aGluZywgc28gdGhlIGFwcGx5UmVzdWx0LWRyaXZlbiBleHRlbnNpb25cbiAgICAvLyBob29rcyBtdXN0IG5vdCBydW4gYWdhaW5zdCB0aGUgZGVmYXVsdCBudWxsIHNraXBwZWQgcmVzdWx0LlxuICAgIGlmICh0aGlzLnBlcnNpc3RFeHRyYUF0dHJpYnV0ZXMgJiYgc2hvdWxkQXBwbHkpIHtcbiAgICAgIE9iamVjdC5hc3NpZ24oYXR0cmlidXRlcywgdGhpcy5wZXJzaXN0RXh0cmFBdHRyaWJ1dGVzKHthY3RvciwgYXBwbHlSZXN1bHQsIGNvbnRleHQsIGV4aXN0aW5nU3luYywgbXV0YXRpb24sIHNob3VsZEFwcGx5fSkpXG4gICAgfVxuXG4gICAgaWYgKHRoaXMucGVyc2lzdFNlcmlhbGl6ZWREYXRhICYmIHNob3VsZEFwcGx5KSB7XG4gICAgICBjb25zdCBzZXJpYWxpemVkRGF0YSA9IHRoaXMucGVyc2lzdFNlcmlhbGl6ZWREYXRhKHthcHBseVJlc3VsdCwgbXV0YXRpb259KVxuXG4gICAgICBpZiAoc2VyaWFsaXplZERhdGEgIT09IHVuZGVmaW5lZCAmJiBzZXJpYWxpemVkRGF0YSAhPT0gbnVsbCkge1xuICAgICAgICBhdHRyaWJ1dGVzLmRhdGEgPSB0eXBlb2Ygc2VyaWFsaXplZERhdGEgPT09IFwic3RyaW5nXCIgPyBzZXJpYWxpemVkRGF0YSA6IEpTT04uc3RyaW5naWZ5KHNlcmlhbGl6ZWREYXRhKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChleGlzdGluZ1N5bmMpIHtcbiAgICAgIGNvbnN0IGV4aXN0aW5nQ2xpZW50VXBkYXRlZEF0ID0gdGhpcy5leGlzdGluZ1JlcGxheVN5bmNDbGllbnRVcGRhdGVkQXQoZXhpc3RpbmdTeW5jKVxuXG4gICAgICBpZiAoZXhpc3RpbmdDbGllbnRVcGRhdGVkQXQgJiYgbXV0YXRpb24uY2xpZW50VXBkYXRlZEF0IDw9IGV4aXN0aW5nQ2xpZW50VXBkYXRlZEF0KSByZXR1cm5cblxuICAgICAgZXhpc3RpbmdTeW5jLmFzc2lnbihhdHRyaWJ1dGVzKVxuICAgICAgYXdhaXQgZXhpc3RpbmdTeW5jLmFkdmFuY2VTZXJ2ZXJTZXF1ZW5jZSgpXG4gICAgICBhd2FpdCBleGlzdGluZ1N5bmMuc2F2ZSgpXG4gICAgfSBlbHNlIHtcbiAgICAgIGF3YWl0IHRoaXMuc3luY01vZGVsLmNyZWF0ZShhdHRyaWJ1dGVzKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIHN5bmMtbW9kZWwgYXR0cmlidXRlcyBwZXJzaXN0ZWQgYnkgdGhlIG1vZGVsLWJhY2tlZCBkZWZhdWx0LlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBhcmdzIC0gQWN0b3IgYW5kIG11dGF0aW9uLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IFN5bmMgcm93IGF0dHJpYnV0ZXMuXG4gICAqL1xuICByZXBsYXlQZXJzaXN0QXR0cmlidXRlcyh7YWN0b3IsIG11dGF0aW9ufSkge1xuICAgIHJldHVybiB7XG4gICAgICBbdGhpcy5hY3RvckZvcmVpZ25LZXlDb2x1bW5dOiB0aGlzLnJlcGxheUFjdG9ySWQoYWN0b3IpLFxuICAgICAgY2xpZW50X3VwZGF0ZWRfYXQ6IG11dGF0aW9uLmNsaWVudFVwZGF0ZWRBdCxcbiAgICAgIGRhdGE6IG11dGF0aW9uLnNlcmlhbGl6ZWREYXRhLFxuICAgICAgcmVzb3VyY2VfaWQ6IG11dGF0aW9uLnJlc291cmNlSWQsXG4gICAgICByZXNvdXJjZV90eXBlOiBtdXRhdGlvbi5yZXNvdXJjZVR5cGUsXG4gICAgICBzeW5jX3R5cGU6IG11dGF0aW9uLnN5bmNUeXBlXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgc2lkZSBlZmZlY3RzIGFmdGVyIGEgc3VjY2Vzc2Z1bCBtdXRhdGlvbiByZXBsYXkgYW5kIHBlcnNpc3RlbmNlLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBmYW5uaW5nIHRoZSBhcHBsaWVkIHJlc3VsdCBvdXQgdGhyb3VnaCB0aGUgY29uZmlndXJlZFxuICAgKiBkZWNsYXJhdGl2ZSBicm9hZGNhc3RzLlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgY29udGV4dDogUmVjb3JkPHN0cmluZywgPz4sIGV4aXN0aW5nU3luYzogPywgYXBwbHlSZXN1bHQ6ID8sIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9uLCBzaG91bGRBcHBseTogYm9vbGVhbn19IGFyZ3MgLSBSZXBsYXkgc2lkZS1lZmZlY3QgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIGFmdGVyUmVwbGF5TXV0YXRpb24oYXJncykge1xuICAgIGlmICghdGhpcy5icm9hZGNhc3RzIHx8ICF0aGlzLmJyb2FkY2FzdGVyKSByZXR1cm5cbiAgICAvLyBTdGFsZSByZXBsYXlzIG5ldmVyIGFwcGxpZWQgYW55dGhpbmcgLSBicm9hZGNhc3RpbmcgdGhlaXIgc2tpcHBlZCByZXN1bHRzXG4gICAgLy8gd291bGQgZmFuIG91dCBzdGFsZSBzaWRlIGVmZmVjdHMgKG9yIGNyYXNoIG9uIHRoZSBkZWZhdWx0IG51bGwgYXBwbHlSZXN1bHQpLlxuICAgIGlmICghYXJncy5zaG91bGRBcHBseSkgcmV0dXJuXG5cbiAgICBmb3IgKGNvbnN0IGJyb2FkY2FzdCBvZiB0aGlzLmJyb2FkY2FzdHMpIHtcbiAgICAgIGlmIChicm9hZGNhc3Qud2hlbiAmJiAhYnJvYWRjYXN0LndoZW4oYXJncykpIGNvbnRpbnVlXG5cbiAgICAgIGF3YWl0IHRoaXMuYnJvYWRjYXN0ZXIoe1xuICAgICAgICBib2R5OiBicm9hZGNhc3QuYm9keShhcmdzKSxcbiAgICAgICAgY2hhbm5lbDogdHlwZW9mIGJyb2FkY2FzdC5jaGFubmVsID09PSBcImZ1bmN0aW9uXCIgPyBicm9hZGNhc3QuY2hhbm5lbChhcmdzKSA6IGJyb2FkY2FzdC5jaGFubmVsLFxuICAgICAgICBwYXJhbXM6IGJyb2FkY2FzdC5icm9hZGNhc3RQYXJhbXMoYXJncylcbiAgICAgIH0pXG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogQHR5cGVkZWYge29iamVjdH0gU3luY1JlcGxheU11dGF0aW9uXG4gKiBAcHJvcGVydHkge0RhdGV9IGNsaWVudFVwZGF0ZWRBdCAtIENsaWVudC1zaWRlIG11dGF0aW9uIHRpbWVzdGFtcC5cbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgPz59IGRhdGEgLSBQYXJzZWQgbXV0YXRpb24gcGF5bG9hZC5cbiAqIEBwcm9wZXJ0eSB7P30gaWQgLSBDbGllbnQgc3luYyByb3cgaWQgZm9yIHBlci1zeW5jIHJlc3BvbnNlcy5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSByZXNvdXJjZUlkIC0gUmVzb3VyY2UgaWQgYXMgYSBzdHJpbmcuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmVzb3VyY2VUeXBlIC0gUmVzb3VyY2UvbW9kZWwgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzZXJpYWxpemVkRGF0YSAtIEpTT04gc2VyaWFsaXplZCBtdXRhdGlvbiBwYXlsb2FkLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHN5bmNUeXBlIC0gU3luYyBvcGVyYXRpb24gdHlwZS5cbiAqL1xuIl19
|
|
681
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL3NyYy9zeW5jL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsWUFBWTtBQUVaLE9BQU8sRUFBQyxpQ0FBaUMsRUFBQyxNQUFNLDJDQUEyQyxDQUFBO0FBQzNGLE9BQU8sdUJBQXVCLE1BQU0saUNBQWlDLENBQUE7QUFDckUsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLDZCQUE2QixDQUFBO0FBQzNELE9BQU8sY0FBYyxNQUFNLHVCQUF1QixDQUFBO0FBRWxEOzs7Ozs7O0dBT0c7QUFFSDs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sQ0FBQyxPQUFPLE9BQU8seUJBQXlCO0lBQzVDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztPQTBCRztJQUNILFlBQVksSUFBSSxHQUFHLEVBQUU7UUFDbkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQTtRQUNwQyxJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFBO1FBQ3ZDLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUMscUJBQXFCLElBQUkseUJBQXlCLENBQUE7UUFDcEYsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQyx3QkFBd0IsSUFBSSxJQUFJLENBQUE7UUFDckUsSUFBSSxDQUFDLHlCQUF5QixHQUFHLElBQUksQ0FBQyx5QkFBeUIsSUFBSSxPQUFPLENBQUE7UUFDMUUsSUFBSSxDQUFDLHdCQUF3QixHQUFHLElBQUksQ0FBQyx3QkFBd0IsSUFBSSxxQkFBcUIsQ0FBQTtRQUN0RixJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixJQUFJLElBQUksQ0FBQTtRQUNqRSxJQUFJLENBQUMscUJBQXFCLEdBQUcsSUFBSSxD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QUFJLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUN4QyxJQUFJLFNBQVMsQ0FBQyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFBRSxTQUFRO1lBRXJELE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQztnQkFDckIsSUFBSSxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUMxQixPQUFPLEVBQUUsT0FBTyxTQUFTLENBQUMsT0FBTyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLE9BQU87Z0JBQzlGLE1BQU0sRUFBRSxTQUFTLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQzthQUN4QyxDQUFDLENBQUE7UUFDSixDQUFDO0lBQ0gsQ0FBQztDQUNGO0FBRUQ7Ozs7OztHQU1HO0FBRUg7Ozs7Ozs7OztHQVNHIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCB7cmVzb2x2ZUZyb250ZW5kTW9kZWxSZXNvdXJjZUNsYXNzfSBmcm9tIFwiLi4vZnJvbnRlbmQtbW9kZWxzL3Jlc291cmNlLWRlZmluaXRpb24uanNcIlxuaW1wb3J0IFN5bmNSZXBsYXlVcHNlcnRBcHBsaWVyIGZyb20gXCIuL3N5bmMtcmVwbGF5LXVwc2VydC1hcHBsaWVyLmpzXCJcbmltcG9ydCB7VmFsaWRhdGlvbkVycm9yfSBmcm9tIFwiLi4vZGF0YWJhc2UvcmVjb3JkL2luZGV4LmpzXCJcbmltcG9ydCBWZWxvY2lvdXNFcnJvciBmcm9tIFwiLi4vdmVsb2Npb3VzLWVycm9yLmpzXCJcblxuLyoqXG4gKiBPbmUgZGVjbGFyYXRpdmUgYnJvYWRjYXN0IGZhbm5lZCBvdXQgYWZ0ZXIgYSBtdXRhdGlvbiBhcHBsaWVzLlxuICogQHR5cGVkZWYge29iamVjdH0gU3luY1JlcGxheUJyb2FkY2FzdFxuICogQHByb3BlcnR5IHtzdHJpbmcgfCAoKGFyZ3M6IFJlY29yZDxzdHJpbmcsID8+KSA9PiBzdHJpbmcpfSBjaGFubmVsIC0gQ2hhbm5lbCBuYW1lIG9yIHJlc29sdmVyLlxuICogQHByb3BlcnR5IHsoYXJnczogUmVjb3JkPHN0cmluZywgPz4pID0+IFJlY29yZDxzdHJpbmcsID8+fSBicm9hZGNhc3RQYXJhbXMgLSBDaGFubmVsIHJvdXRpbmcgcGFyYW1zLlxuICogQHByb3BlcnR5IHsoYXJnczogUmVjb3JkPHN0cmluZywgPz4pID0+ID99IGJvZHkgLSBCcm9hZGNhc3QgYm9keS5cbiAqIEBwcm9wZXJ0eSB7KGFyZ3M6IFJlY29yZDxzdHJpbmcsID8+KSA9PiBib29sZWFufSBbd2hlbl0gLSBPcHRpb25hbCBnYXRlOyBza2lwcGVkIHdoZW4gaXQgcmV0dXJucyBmYWxzZS5cbiAqL1xuXG4vKipcbiAqIFJlcGxheXMgY2xpZW50IHN5bmMgZW52ZWxvcGVzIHRocm91Z2ggcHJvamVjdCBzdXBwbGllZCBhdXRoZW50aWNhdGlvbixcbiAqIGF1dGhvcml6YXRpb24sIGFwcGxpY2F0aW9uLCBhbmQgcGVyc2lzdGVuY2UgaG9va3MuXG4gKlxuICogVGhpcyBpcyBpbnRlbnRpb25hbGx5IHRyYW5zcG9ydC9tb2RlbCBhZ25vc3RpYzogVmVsb2Npb3VzIG93bnMgdGhlIGdlbmVyaWNcbiAqIHJlcGxheSBsb29wLCBub3JtYWxpemF0aW9uLCBzdGFsZS1jbGllbnQgY29tcGFyaXNvbiwgYW5kIHBlci1zeW5jIHJlc3VsdFxuICogc2hhcGUgd2hpbGUgZWFjaCBhcHAgb3ducyBpdHMgdG9rZW4gbG9va3VwLCBtb2RlbCBoYW5kbGVycywgYW5kXG4gKiBkb21haW4gYXV0aG9yaXphdGlvbiBydWxlcy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgY2xhc3MgU3luY0VudmVsb3BlUmVwbGF5U2VydmljZSB7XG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgc3luYyBlbnZlbG9wZSByZXBsYXkgc2VydmljZS5cbiAgICpcbiAgICogV2hlbiBhIHN5bmMgbW9kZWwgaXMgZ2l2ZW4sIGBmaW5kRXhpc3RpbmdSZXBsYXlTeW5jYCBhbmRcbiAgICogYHBlcnNpc3RSZXBsYXlNdXRhdGlvbmAgZ2V0IG1vZGVsLWJhY2tlZCBkZWZhdWx0IGltcGxlbWVudGF0aW9ucy4gVGhlIHN5bmNcbiAgICogbW9kZWwgbXVzdCBleHBvc2UgYGZpbmRCeWAvYGNyZWF0ZWAgc3RhdGljcyBwbHVzIGluc3RhbmNlXG4gICAqIGBhc3NpZ25gL2BzYXZlYC9gY2xpZW50VXBkYXRlZEF0YCBhbmQgYGFkdmFuY2VTZXJ2ZXJTZXF1ZW5jZWAgKHRoZVxuICAgKiBjaGFuZ2UtZmVlZCBzZXF1ZW5jZSBjb250cmFjdCksIGFuZCB0aGUgYWN0b3IgcmV0dXJuZWQgZnJvbVxuICAgKiBgYXV0aGVudGljYXRlUmVwbGF5YCBtdXN0IGV4cG9zZSBhbiBgaWQoKWAgbWV0aG9kLlxuICAgKiBAcGFyYW0ge29iamVjdH0gW2FyZ3NdIC0gQ29uc3RydWN0b3IgYXJndW1lbnRzLlxuICAgKiBAcGFyYW0ge3tkZWJ1Zz86ICguLi5hcmdzOiBBcnJheTx1bmtub3duPikgPT4gdm9pZCwgd2Fybj86ICguLi5hcmdzOiBBcnJheTx1bmtub3duPikgPT4gdm9pZH19IFthcmdzLmxvZ2dlcl0gLSBMb2dnZXIgdXNlZCBmb3Igbm9ybWFsaXphdGlvbiB3YXJuaW5ncy5cbiAgICogQHBhcmFtIHs/fSBbYXJncy5zeW5jTW9kZWxdIC0gU3luYy9jaGFuZ2UgbW9kZWwgZW5hYmxpbmcgbW9kZWwtYmFja2VkIGRlZmF1bHQgaG9va3MuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW5dIC0gU3luYyBtb2RlbCBjb2x1bW4gbGlua2luZyByb3dzIHRvIHRoZSByZXBsYXkgYWN0b3IuXG4gICAqIEBwYXJhbSB7P30gW2FyZ3MuYXV0aGVudGljYXRpb25Ub2tlbk1vZGVsXSAtIFRva2VuIG1vZGVsIGVuYWJsaW5nIHRoZSBkZWZhdWx0IHRva2VuLWxvb2t1cCBhdXRoZW50aWNhdGVSZXBsYXkuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbYXJncy5hdXRoZW50aWNhdGlvblRva2VuQ29sdW1uXSAtIFRva2VuIG1vZGVsIGNvbHVtbiBob2xkaW5nIHRoZSB0b2tlbi4gRGVmYXVsdHMgdG8gXCJ0b2tlblwiLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gW2FyZ3MuYXV0aGVudGljYXRpb25Ub2tlblBhcmFtXSAtIFJlcXVlc3QgcGFyYW0gY2FycnlpbmcgdGhlIHRva2VuLiBEZWZhdWx0cyB0byBcImF1dGhlbnRpY2F0aW9uVG9rZW5cIi5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCAoKGFyZ3M6IFJlY29yZDxzdHJpbmcsID8+KSA9PiBQcm9taXNlPD8+KSB8IENvbnN0cnVjdG9yUGFyYW1ldGVyczx0eXBlb2YgU3luY1JlcGxheVVwc2VydEFwcGxpZXI+WzBdPn0gW2FyZ3MuYXBwbHlIYW5kbGVyc10gLSBQZXItcmVzb3VyY2VUeXBlIGFwcGx5IGhhbmRsZXJzIChmdW5jdGlvbnMgb3IgZGVjbGFyYXRpdmUgdXBzZXJ0LWFwcGxpZXIgc3BlY3MpIGVuYWJsaW5nIHRoZSBkZWZhdWx0IGFwcGx5UmVwbGF5TXV0YXRpb24gZGlzcGF0Y2guIERlcHJlY2F0ZWQ6IHByZWZlciByZXNvdXJjZSByb3V0aW5nIHZpYSBgY29uZmlndXJhdGlvbmAvYHJlc291cmNlVHlwZU92ZXJyaWRlc2A7IGFwcGx5SGFuZGxlcnMgcmVtYWluIGZvciByZWxlYXNlZCBhZG9wdGVycyBhbmQgd2lsbCBiZSByZW1vdmVkIGFmdGVyIHRoZWlyIG1pZ3JhdGlvbi5cbiAgICogQHBhcmFtIHsoYXJnczogUmVjb3JkPHN0cmluZywgPz4pID0+IFJlY29yZDxzdHJpbmcsID8+fSBbYXJncy5wZXJzaXN0RXh0cmFBdHRyaWJ1dGVzXSAtIEV4dHJhIGF0dHJpYnV0ZXMgbWVyZ2VkIGludG8gdGhlIG1vZGVsLWJhY2tlZCBwZXJzaXN0ZWQgcm93IChlLmcuIGFuIGV2ZW50IHNjb3BlIGNvbHVtbikuXG4gICAqIEBwYXJhbSB7KGFyZ3M6IHttdXRhdGlvbjogPywgYXBwbHlSZXN1bHQ6ID99KSA9PiA/fSBbYXJncy5wZXJzaXN0U2VyaWFsaXplZERhdGFdIC0gT3ZlcnJpZGVzIHRoZSBwZXJzaXN0ZWQgZGF0YSBwYXlsb2FkIChvYmplY3QgcmVzdWx0cyBhcmUgSlNPTiBzdHJpbmdpZmllZCkuXG4gICAqIEBwYXJhbSB7KGJyb2FkY2FzdDoge2NoYW5uZWw6IHN0cmluZywgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCA/PiwgYm9keTogP30pID0+IFByb21pc2U8dm9pZD59IFthcmdzLmJyb2FkY2FzdGVyXSAtIERlbGl2ZXJzIGRlY2xhcmF0aXZlIGJyb2FkY2FzdHMuIFJlcXVpcmVkIHdoZW4gYnJvYWRjYXN0cyBhcmUgY29uZmlndXJlZC5cbiAgICogQHBhcmFtIHtTeW5jUmVwbGF5QnJvYWRjYXN0W119IFthcmdzLmJyb2FkY2FzdHNdIC0gQnJvYWRjYXN0cyBmYW5uZWQgb3V0IGJ5IHRoZSBkZWZhdWx0IGFmdGVyUmVwbGF5TXV0YXRpb24uXG4gICAqIEBwYXJhbSB7e2dldEJhY2tlbmRQcm9qZWN0czogKCkgPT4gaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5CYWNrZW5kUHJvamVjdENvbmZpZ3VyYXRpb25bXX19IFthcmdzLmNvbmZpZ3VyYXRpb25dIC0gQ29uZmlndXJhdGlvbiB3aG9zZSBmcm9udGVuZC1tb2RlbCByZWdpc3RyeSByb3V0ZXMgbXV0YXRpb25zIHRvIHJlc291cmNlIGNsYXNzZXMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDbGFzc1R5cGUgfCBzdHJpbmc+fSBbYXJncy5yZXNvdXJjZVR5cGVPdmVycmlkZXNdIC0gUGVyLXJlc291cmNlVHlwZSByb3V0aW5nIG92ZXJyaWRlczogYSByZXNvdXJjZSBjbGFzcywgb3IgYSBzdHJpbmcgYWxpYXMgcmVzb2x2ZWQgdGhyb3VnaCB0aGUgcmVnaXN0cnkuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHR9IFthcmdzLmFiaWxpdHldIC0gQWJpbGl0eSBzY29waW5nIHJvdXRlZCByZWNvcmQgbG9va3VwcyBhbmQgY3JlYXRlIG1lbWJlcnNoaXAgY2hlY2tzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBbYXJncy5hYmlsaXR5Q29udGV4dF0gLSBBYmlsaXR5IGNvbnRleHQgcGFzc2VkIHRvIHJvdXRlZCByZXNvdXJjZXMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IFthcmdzLmxvY2Fsc10gLSBMb2NhbHMgcGFzc2VkIHRvIHJvdXRlZCByZXNvdXJjZXMuXG4gICAqL1xuICBjb25zdHJ1Y3RvcihhcmdzID0ge30pIHtcbiAgICB0aGlzLmxvZ2dlciA9IGFyZ3MubG9nZ2VyIHx8IGNvbnNvbGVcbiAgICB0aGlzLnN5bmNNb2RlbCA9IGFyZ3Muc3luY01vZGVsIHx8IG51bGxcbiAgICB0aGlzLmFjdG9yRm9yZWlnbktleUNvbHVtbiA9IGFyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uIHx8IFwiYXV0aGVudGljYXRpb25fdG9rZW5faWRcIlxuICAgIHRoaXMuYXV0aGVudGljYXRpb25Ub2tlbk1vZGVsID0gYXJncy5hdXRoZW50aWNhdGlvblRva2VuTW9kZWwgfHwgbnVsbFxuICAgIHRoaXMuYXV0aGVudGljYXRpb25Ub2tlbkNvbHVtbiA9IGFyZ3MuYXV0aGVudGljYXRpb25Ub2tlbkNvbHVtbiB8fCBcInRva2VuXCJcbiAgICB0aGlzLmF1dGhlbnRpY2F0aW9uVG9rZW5QYXJhbSA9IGFyZ3MuYXV0aGVudGljYXRpb25Ub2tlblBhcmFtIHx8IFwiYXV0aGVudGljYXRpb25Ub2tlblwiXG4gICAgdGhpcy5wZXJzaXN0RXh0cmFBdHRyaWJ1dGVzID0gYXJncy5wZXJzaXN0RXh0cmFBdHRyaWJ1dGVzIHx8IG51bGxcbiAgICB0aGlzLnBlcnNpc3RTZXJpYWxpemVkRGF0YSA9IGFyZ3MucGVyc2lzdFNlcmlhbGl6ZWREYXRhIHx8IG51bGxcbiAgICB0aGlzLmJyb2FkY2FzdGVyID0gYXJncy5icm9hZGNhc3RlciB8fCBudWxsXG4gICAgdGhpcy5icm9hZGNhc3RzID0gYXJncy5icm9hZGNhc3RzIHx8IG51bGxcbiAgICB0aGlzLmFwcGx5SGFuZGxlcnMgPSBhcmdzLmFwcGx5SGFuZGxlcnMgPyB0aGlzLmJ1aWx0QXBwbHlIYW5kbGVycyhhcmdzLmFwcGx5SGFuZGxlcnMpIDogbnVsbFxuICAgIHRoaXMuY29uZmlndXJhdGlvbiA9IGFyZ3MuY29uZmlndXJhdGlvbiB8fCBudWxsXG4gICAgdGhpcy5yZXNvdXJjZVR5cGVPdmVycmlkZXMgPSBhcmdzLnJlc291cmNlVHlwZU92ZXJyaWRlcyB8fCBudWxsXG4gICAgdGhpcy5hYmlsaXR5ID0gYXJncy5hYmlsaXR5IHx8IG51bGxcbiAgICB0aGlzLmFiaWxpdHlDb250ZXh0ID0gYXJncy5hYmlsaXR5Q29udGV4dCB8fCBudWxsXG4gICAgdGhpcy5sb2NhbHMgPSBhcmdzLmxvY2FscyB8fCBudWxsXG4gICAgLyoqIEB0eXBlIHtNYXA8c3RyaW5nLCBTeW5jUmVwbGF5UmVzb3VyY2VSZWdpc3RyYXRpb24gfCBudWxsPn0gKi9cbiAgICB0aGlzLl9yZXBsYXlSZXNvdXJjZVJlZ2lzdHJhdGlvbnMgPSBuZXcgTWFwKClcblxuICAgIGlmIChhcmdzLmFjdG9yRm9yZWlnbktleUNvbHVtbiAhPT0gdW5kZWZpbmVkICYmICh0eXBlb2YgYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW4gIT09IFwic3RyaW5nXCIgfHwgYXJncy5hY3RvckZvcmVpZ25LZXlDb2x1bW4ubGVuZ3RoIDwgMSkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgYWN0b3JGb3JlaWduS2V5Q29sdW1uIG11c3QgYmUgYSBub24tYmxhbmsgc3RyaW5nLCBnb3Q6ICR7U3RyaW5nKGFyZ3MuYWN0b3JGb3JlaWduS2V5Q29sdW1uKX1gKVxuICAgIH1cbiAgICBpZiAodGhpcy5icm9hZGNhc3RzICYmICF0aGlzLmJyb2FkY2FzdGVyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jRW52ZWxvcGVSZXBsYXlTZXJ2aWNlIGJyb2FkY2FzdHMgcmVxdWlyZSBhIGJyb2FkY2FzdGVyIG9wdGlvbiBkZWxpdmVyaW5nIHRoZW1cIilcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogV3JhcHMgZGVjbGFyYXRpdmUgYXBwbHktaGFuZGxlciBzcGVjcyBpbiB1cHNlcnQgYXBwbGllcnMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IGFwcGx5SGFuZGxlcnMgLSBSYXcgYXBwbHkgaGFuZGxlcnMuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCAoYXJnczogUmVjb3JkPHN0cmluZywgPz4pID0+IFByb21pc2U8Pz4+fSBDYWxsYWJsZSBoYW5kbGVycyBieSByZXNvdXJjZSB0eXBlLlxuICAgKi9cbiAgYnVpbHRBcHBseUhhbmRsZXJzKGFwcGx5SGFuZGxlcnMpIHtcbiAgICByZXR1cm4gT2JqZWN0LmZyb21FbnRyaWVzKE9iamVjdC5lbnRyaWVzKGFwcGx5SGFuZGxlcnMpLm1hcCgoW3Jlc291cmNlVHlwZSwgaGFuZGxlcl0pID0+IHtcbiAgICAgIGlmICh0eXBlb2YgaGFuZGxlciA9PT0gXCJmdW5jdGlvblwiKSByZXR1cm4gW3Jlc291cmNlVHlwZSwgaGFuZGxlcl1cblxuICAgICAgY29uc3QgYXBwbGllciA9IG5ldyBTeW5jUmVwbGF5VXBzZXJ0QXBwbGllcihoYW5kbGVyKVxuXG4gICAgICByZXR1cm4gW3Jlc291cmNlVHlwZSwgKC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIGFwcGx5QXJncykgPT4gYXBwbGllci5hcHBseSgvKiogQHR5cGUgez99ICovIChhcHBseUFyZ3MpKV1cbiAgICB9KSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXBsYXlzIGEgc3luYyBiYXRjaC5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gcGFyYW1zIC0gUmVxdWVzdCBwYXJhbXMgY2FycnlpbmcgYXV0aGVudGljYXRpb24gYW5kIHN5bmNzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx7c3luY3M6IEFycmF5PFJlY29yZDxzdHJpbmcsID8+Piwgc3RhdHVzPzogc3RyaW5nLCBlcnJvckNvZGU/OiBzdHJpbmcsIGVycm9yTWVzc2FnZT86IHN0cmluZ30+fSBSZXBsYXkgcmVzcG9uc2UuXG4gICAqL1xuICBhc3luYyByZXBsYXkocGFyYW1zKSB7XG4gICAgY29uc3QgYWN0b3JSZXN1bHQgPSBhd2FpdCB0aGlzLmF1dGhlbnRpY2F0ZVJlcGxheShwYXJhbXMpXG5cbiAgICBpZiAoIWFjdG9yUmVzdWx0LmF1dGhlbnRpY2F0ZWQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHN5bmNzOiBbXSxcbiAgICAgICAgc3RhdHVzOiBcImVycm9yXCIsXG4gICAgICAgIGVycm9yQ29kZTogYWN0b3JSZXN1bHQuZXJyb3JDb2RlLFxuICAgICAgICBlcnJvck1lc3NhZ2U6IGFjdG9yUmVzdWx0LmVycm9yTWVzc2FnZVxuICAgICAgfVxuICAgIH1cblxuICAgIGNvbnN0IHN5bmNSZXNwb25zZXMgPSBbXVxuICAgIGNvbnN0IGNvbnRleHQgPSBhd2FpdCB0aGlzLmJ1aWxkUmVwbGF5Q29udGV4dCh7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBwYXJhbXN9KVxuXG4gICAgZm9yIChjb25zdCByYXdTeW5jIG9mIHRoaXMucmVwbGF5U3luY3MocGFyYW1zKSkge1xuICAgICAgY29uc3Qgbm9ybWFsaXplZFJlc3VsdCA9IHRoaXMubm9ybWFsaXplUmVwbGF5U3luYyhyYXdTeW5jKVxuXG4gICAgICBpZiAoIW5vcm1hbGl6ZWRSZXN1bHQub2spIHtcbiAgICAgICAgc3luY1Jlc3BvbnNlcy5wdXNoKG5vcm1hbGl6ZWRSZXN1bHQucmVzcG9uc2UpXG4gICAgICAgIGNvbnRpbnVlXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG11dGF0aW9uID0gbm9ybWFsaXplZFJlc3VsdC5tdXRhdGlvblxuICAgICAgY29uc3QgYWNjZXNzUmVzdWx0ID0gYXdhaXQgdGhpcy5hdXRob3JpemVSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBtdXRhdGlvbn0pXG5cbiAgICAgIGlmICghYWNjZXNzUmVzdWx0LmFsbG93ZWQpIHtcbiAgICAgICAgc3luY1Jlc3BvbnNlcy5wdXNoKHtcbiAgICAgICAgICBpZDogbXV0YXRpb24uaWQsXG4gICAgICAgICAgc3luY1N0YXRlOiBcImZhaWxlZFwiLFxuICAgICAgICAgIHJlYXNvbjogYWNjZXNzUmVzdWx0LnJlYXNvbiB8fCBcImFjY2Vzcy1kZW5pZWRcIlxuICAgICAgICB9KVxuICAgICAgICBjb250aW51ZVxuICAgICAgfVxuXG4gICAgICBjb25zdCBleGlzdGluZ1N5bmMgPSBhd2FpdCB0aGlzLmZpbmRFeGlzdGluZ1JlcGxheVN5bmMoe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgbXV0YXRpb259KVxuICAgICAgY29uc3Qgc2hvdWxkQXBwbHkgPSBhd2FpdCB0aGlzLnNob3VsZEFwcGx5UmVwbGF5TXV0YXRpb24oe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBtdXRhdGlvbn0pXG5cbiAgICAgIC8qKiBAdHlwZSB7P30gKi9cbiAgICAgIGxldCBhcHBseVJlc3VsdFxuXG4gICAgICB0cnkge1xuICAgICAgICBhcHBseVJlc3VsdCA9IHNob3VsZEFwcGx5XG4gICAgICAgICAgPyBhd2FpdCB0aGlzLmFwcGx5UmVwbGF5TXV0YXRpb24oe2FjdG9yOiBhY3RvclJlc3VsdC5hY3RvciwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBtdXRhdGlvbn0pXG4gICAgICAgICAgOiBhd2FpdCB0aGlzLnNraXBwZWRSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIG11dGF0aW9ufSlcbiAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgIC8vIENsaWVudC1zYWZlIGFwcGx5IGZhaWx1cmVzIChzY2hlbWEgdmFsaWRhdGlvbiwgbW9kZWwgdmFsaWRhdGlvbixcbiAgICAgICAgLy8gYXV0aG9yaXphdGlvbiBkZW5pYWxzLCB1bmtub3duIHJlc291cmNlIHR5cGVzKSBmYWlsIHRoaXMgc3luYyBhbmRcbiAgICAgICAgLy8ga2VlcCB0aGUgYmF0Y2ggZ29pbmc7IHVuZXhwZWN0ZWQgZXJyb3JzIGtlZXAgcHJvcGFnYXRpbmcuXG4gICAgICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFZlbG9jaW91c0Vycm9yICYmIGVycm9yLnNhZmVUb0V4cG9zZSkge1xuICAgICAgICAgIHN5bmNSZXNwb25zZXMucHVzaCh7XG4gICAgICAgICAgICBpZDogbXV0YXRpb24uaWQsXG4gICAgICAgICAgICBzeW5jU3RhdGU6IFwiZmFpbGVkXCIsXG4gICAgICAgICAgICByZWFzb246IGVycm9yLmNvZGUgfHwgXCJhcHBseS1mYWlsZWRcIixcbiAgICAgICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2VcbiAgICAgICAgICB9KVxuICAgICAgICAgIGNvbnRpbnVlXG4gICAgICAgIH1cblxuICAgICAgICB0aHJvdyBlcnJvclxuICAgICAgfVxuXG4gICAgICBhd2FpdCB0aGlzLnBlcnNpc3RSZXBsYXlNdXRhdGlvbih7YWN0b3I6IGFjdG9yUmVzdWx0LmFjdG9yLCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIGFwcGx5UmVzdWx0LCBtdXRhdGlvbiwgc2hvdWxkQXBwbHl9KVxuICAgICAgYXdhaXQgdGhpcy5hZnRlclJlcGxheU11dGF0aW9uKHthY3RvcjogYWN0b3JSZXN1bHQuYWN0b3IsIGNvbnRleHQsIGV4aXN0aW5nU3luYywgYXBwbHlSZXN1bHQsIG11dGF0aW9uLCBzaG91bGRBcHBseX0pXG5cbiAgICAgIHN5bmNSZXNwb25zZXMucHVzaCh7aWQ6IG11dGF0aW9uLmlkLCBzeW5jU3RhdGU6IFwic3VjY2Vzc2Z1bFwifSlcbiAgICB9XG5cbiAgICByZXR1cm4ge3N5bmNzOiBzeW5jUmVzcG9uc2VzfVxuICB9XG5cbiAgLyoqXG4gICAqIEF1dGhlbnRpY2F0ZXMgdGhlIHN5bmMgYmF0Y2ggYWN0b3IuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIGEgdG9rZW4tbW9kZWwgbG9va3VwIHdoZW4gYGF1dGhlbnRpY2F0aW9uVG9rZW5Nb2RlbGAgaXNcbiAgICogY29uZmlndXJlZDsgb3RoZXJ3aXNlIGFwcHMgb3ZlcnJpZGUgdGhpcyBob29rLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBwYXJhbXMgLSBSZXF1ZXN0IHBhcmFtcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8e2F1dGhlbnRpY2F0ZWQ6IHRydWUsIGFjdG9yOiA/fSB8IHthdXRoZW50aWNhdGVkOiBmYWxzZSwgZXJyb3JDb2RlOiBzdHJpbmcsIGVycm9yTWVzc2FnZTogc3RyaW5nfT59IEF1dGggcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgYXV0aGVudGljYXRlUmVwbGF5KHBhcmFtcykge1xuICAgIGlmICghdGhpcy5hdXRoZW50aWNhdGlvblRva2VuTW9kZWwpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIlN5bmNFbnZlbG9wZVJlcGxheVNlcnZpY2UuYXV0aGVudGljYXRlUmVwbGF5IG11c3QgYmUgaW1wbGVtZW50ZWQgKG9yIGNvbmZpZ3VyZSBhdXRoZW50aWNhdGlvblRva2VuTW9kZWwpXCIpXG4gICAgfVxuXG4gICAgY29uc3QgdG9rZW4gPSBwYXJhbXNbdGhpcy5hdXRoZW50aWNhdGlvblRva2VuUGFyYW1dXG5cbiAgICBpZiAoIXRva2VuKSB7XG4gICAgICByZXR1cm4ge2F1dGhlbnRpY2F0ZWQ6IGZhbHNlLCBlcnJvckNvZGU6IFwibWlzc2luZy1hdXRoZW50aWNhdGlvbi10b2tlblwiLCBlcnJvck1lc3NhZ2U6IFwiTWlzc2luZyBhdXRoZW50aWNhdGlvbiB0b2tlblwifVxuICAgIH1cblxuICAgIGNvbnN0IGFjdG9yID0gYXdhaXQgdGhpcy5hdXRoZW50aWNhdGlvblRva2VuTW9kZWwuZmluZEJ5KHtbdGhpcy5hdXRoZW50aWNhdGlvblRva2VuQ29sdW1uXTogdG9rZW59KVxuXG4gICAgaWYgKCFhY3Rvcikge1xuICAgICAgcmV0dXJuIHthdXRoZW50aWNhdGVkOiBmYWxzZSwgZXJyb3JDb2RlOiBcImludmFsaWQtYXV0aGVudGljYXRpb24tdG9rZW5cIiwgZXJyb3JNZXNzYWdlOiBcIkludmFsaWQgYXV0aGVudGljYXRpb24gdG9rZW5cIn1cbiAgICB9XG5cbiAgICByZXR1cm4ge2FjdG9yLCBhdXRoZW50aWNhdGVkOiB0cnVlfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyBwZXItYmF0Y2ggbXV0YWJsZSBjb250ZXh0IGZvciBjYWNoZXMgc2hhcmVkIGFjcm9zcyBzeW5jIGl0ZW1zLlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgcGFyYW1zOiBSZWNvcmQ8c3RyaW5nLCA/Pn19IF9hcmdzIC0gQWN0b3IgYW5kIHJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZWNvcmQ8c3RyaW5nLCA/Pj59IFJlcGxheSBjb250ZXh0LlxuICAgKi9cbiAgYXN5bmMgYnVpbGRSZXBsYXlDb250ZXh0KF9hcmdzKSB7XG4gICAgcmV0dXJuIHt9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyByYXcgc3luYyBlbnRyaWVzIGZyb20gcmVxdWVzdCBwYXJhbXMuXG4gICAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgPz59IHBhcmFtcyAtIFJlcXVlc3QgcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7QXJyYXk8Pz59IFJhdyBzeW5jIGVudHJpZXMuXG4gICAqL1xuICByZXBsYXlTeW5jcyhwYXJhbXMpIHtcbiAgICByZXR1cm4gQXJyYXkuaXNBcnJheShwYXJhbXMuc3luY3MpID8gcGFyYW1zLnN5bmNzIDogW11cbiAgfVxuXG4gIC8qKlxuICAgKiBOb3JtYWxpemVzIG9uZSBzeW5jIGVudHJ5LlxuICAgKiBAcGFyYW0gez99IHJhd1N5bmMgLSBSYXcgc3luYyBlbnRyeS5cbiAgICogQHJldHVybnMge3tvazogdHJ1ZSwgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259IHwge29rOiBmYWxzZSwgcmVzcG9uc2U6IFJlY29yZDxzdHJpbmcsID8+fX0gTm9ybWFsaXplZCBtdXRhdGlvbiBvciBmYWlsZWQgcmVzcG9uc2UuXG4gICAqL1xuICBub3JtYWxpemVSZXBsYXlTeW5jKHJhd1N5bmMpIHtcbiAgICBpZiAoIXJhd1N5bmMgfHwgdHlwZW9mIHJhd1N5bmMgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShyYXdTeW5jKSkge1xuICAgICAgcmV0dXJuIHtvazogZmFsc2UsIHJlc3BvbnNlOiB7aWQ6IHVuZGVmaW5lZCwgc3luY1N0YXRlOiBcImZhaWxlZFwiLCByZWFzb246IFwiaW52YWxpZC1zeW5jXCJ9fVxuICAgIH1cblxuICAgIGNvbnN0IHN5bmMgPSAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAocmF3U3luYylcbiAgICBjb25zdCB7Y2xpZW50VXBkYXRlZEF0LCBkYXRhLCBpZCwgcmVzb3VyY2VJZCwgcmVzb3VyY2VUeXBlLCBzeW5jVHlwZX0gPSBzeW5jXG5cbiAgICBpZiAodHlwZW9mIHJlc291cmNlVHlwZSAhPT0gXCJzdHJpbmdcIiB8fCByZXNvdXJjZVR5cGUubGVuZ3RoIDwgMSB8fCByZXNvdXJjZUlkID09PSB1bmRlZmluZWQgfHwgcmVzb3VyY2VJZCA9PT0gbnVsbCB8fCB0eXBlb2Ygc3luY1R5cGUgIT09IFwic3RyaW5nXCIgfHwgc3luY1R5cGUubGVuZ3RoIDwgMSkge1xuICAgICAgcmV0dXJuIHtvazogZmFsc2UsIHJlc3BvbnNlOiB7aWQsIHN5bmNTdGF0ZTogXCJmYWlsZWRcIiwgcmVhc29uOiBcImludmFsaWQtcmVzb3VyY2UtaWRcIn19XG4gICAgfVxuXG4gICAgY29uc3QgcmVzb3VyY2VJZFN0cmluZyA9IFN0cmluZyhyZXNvdXJjZUlkKVxuICAgIGxldCBjbGllbnRVcGRhdGVkQXREYXRlID0gdHlwZW9mIGNsaWVudFVwZGF0ZWRBdCA9PT0gXCJzdHJpbmdcIiB8fCBjbGllbnRVcGRhdGVkQXQgaW5zdGFuY2VvZiBEYXRlID8gbmV3IERhdGUoY2xpZW50VXBkYXRlZEF0KSA6IG5ldyBEYXRlKClcblxuICAgIGlmIChOdW1iZXIuaXNOYU4oY2xpZW50VXBkYXRlZEF0RGF0ZS5nZXRUaW1lKCkpKSBjbGllbnRVcGRhdGVkQXREYXRlID0gbmV3IERhdGUoKVxuXG4gICAgY29uc3Qgbm9ybWFsaXplZERhdGFSZXN1bHQgPSB0aGlzLm5vcm1hbGl6ZVJlcGxheVN5bmNEYXRhKHtkYXRhLCBpZCwgcmVzb3VyY2VJZDogcmVzb3VyY2VJZFN0cmluZywgcmVzb3VyY2VUeXBlfSlcblxuICAgIGlmICghbm9ybWFsaXplZERhdGFSZXN1bHQub2spIHJldHVybiBub3JtYWxpemVkRGF0YVJlc3VsdFxuXG4gICAgcmV0dXJuIHtcbiAgICAgIG9rOiB0cnVlLFxuICAgICAgbXV0YXRpb246IHtcbiAgICAgICAgY2xpZW50VXBkYXRlZEF0OiBjbGllbnRVcGRhdGVkQXREYXRlLFxuICAgICAgICBkYXRhOiBub3JtYWxpemVkRGF0YVJlc3VsdC5kYXRhLFxuICAgICAgICBpZCxcbiAgICAgICAgcmVzb3VyY2VJZDogcmVzb3VyY2VJZFN0cmluZyxcbiAgICAgICAgcmVzb3VyY2VUeXBlLFxuICAgICAgICBzZXJpYWxpemVkRGF0YTogSlNPTi5zdHJpbmdpZnkobm9ybWFsaXplZERhdGFSZXN1bHQuZGF0YSksXG4gICAgICAgIHN5bmNUeXBlXG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIE5vcm1hbGl6ZXMgb25lIHN5bmMgZGF0YSBwYXlsb2FkLlxuICAgKiBAcGFyYW0ge3tkYXRhOiA/LCBpZDogPywgcmVzb3VyY2VJZDogc3RyaW5nLCByZXNvdXJjZVR5cGU6IHN0cmluZ319IGFyZ3MgLSBTeW5jIHBheWxvYWQgbm9ybWFsaXphdGlvbiBhcmd1bWVudHMuXG4gICAqIEByZXR1cm5zIHt7b2s6IHRydWUsIGRhdGE6IFJlY29yZDxzdHJpbmcsID8+fSB8IHtvazogZmFsc2UsIHJlc3BvbnNlOiBSZWNvcmQ8c3RyaW5nLCA/Pn19IE5vcm1hbGl6ZWQgcGF5bG9hZCBvciBmYWlsZWQgcmVzcG9uc2UuXG4gICAqL1xuICBub3JtYWxpemVSZXBsYXlTeW5jRGF0YSh7ZGF0YSwgaWQsIHJlc291cmNlSWQsIHJlc291cmNlVHlwZX0pIHtcbiAgICBpZiAoZGF0YSA9PT0gdW5kZWZpbmVkIHx8IGRhdGEgPT09IG51bGwpIHJldHVybiB7b2s6IHRydWUsIGRhdGE6IHt9fVxuXG4gICAgaWYgKHR5cGVvZiBkYXRhID09PSBcInN0cmluZ1wiKSB7XG4gICAgICB0cnkge1xuICAgICAgICBjb25zdCBwYXJzZWREYXRhID0gSlNPTi5wYXJzZShkYXRhKVxuXG4gICAgICAgIGlmICghcGFyc2VkRGF0YSB8fCB0eXBlb2YgcGFyc2VkRGF0YSAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KHBhcnNlZERhdGEpKSByZXR1cm4ge29rOiB0cnVlLCBkYXRhOiB7fX1cblxuICAgICAgICByZXR1cm4ge29rOiB0cnVlLCBkYXRhOiAvKiogQHR5cGUge1JlY29yZDxzdHJpbmcsID8+fSAqLyAocGFyc2VkRGF0YSl9XG4gICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICB0aGlzLmxvZ2dlci53YXJuPy4oXCJJbnZhbGlkIHN5bmMgZGF0YSBKU09OXCIsIHtlcnJvciwgaWQsIHJlc291cmNlSWQsIHJlc291cmNlVHlwZX0pXG4gICAgICAgIHJldHVybiB7b2s6IGZhbHNlLCByZXNwb25zZToge2lkLCBzeW5jU3RhdGU6IFwiZmFpbGVkXCIsIHJlYXNvbjogXCJpbnZhbGlkLWRhdGFcIn19XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBkYXRhICE9PSBcIm9iamVjdFwiIHx8IEFycmF5LmlzQXJyYXkoZGF0YSkpIHJldHVybiB7b2s6IHRydWUsIGRhdGE6IHt9fVxuXG4gICAgcmV0dXJuIHtvazogdHJ1ZSwgZGF0YTogSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkYXRhKSl9XG4gIH1cblxuICAvKipcbiAgICogQXV0aG9yaXplcyBvbmUgbm9ybWFsaXplZCBtdXRhdGlvbi5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsID8+LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn19IF9hcmdzIC0gQWN0b3IsIGJhdGNoIGNvbnRleHQsIGFuZCBtdXRhdGlvbi5cbiAgICogQHJldHVybnMge1Byb21pc2U8e2FsbG93ZWQ6IGJvb2xlYW4sIHJlYXNvbj86IHN0cmluZ30+fSBBY2Nlc3MgcmVzdWx0LlxuICAgKi9cbiAgYXN5bmMgYXV0aG9yaXplUmVwbGF5TXV0YXRpb24oX2FyZ3MpIHtcbiAgICByZXR1cm4ge2FsbG93ZWQ6IHRydWV9XG4gIH1cblxuICAvKipcbiAgICogTG9hZHMgdGhlIHByZXZpb3VzbHkgc3RvcmVkIHN5bmMvY2hhbmdlIHJvdyBmb3Igc3RhbGUtY2xpZW50IGNvbXBhcmlzb24uXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIGEgc3luYy1tb2RlbCBsb29rdXAgYnkgYWN0b3IgYW5kIHJlc291cmNlIGlkZW50aXR5IHdoZW4gYSBzeW5jXG4gICAqIG1vZGVsIGlzIGNvbmZpZ3VyZWQ7IG90aGVyd2lzZSBhcHBzIG92ZXJyaWRlIHRoaXMgaG9vay5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsID8+LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn19IGFyZ3MgLSBBY3RvciwgYmF0Y2ggY29udGV4dCwgYW5kIG11dGF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTw/Pn0gRXhpc3Rpbmcgc3luYyByb3cuXG4gICAqL1xuICBhc3luYyBmaW5kRXhpc3RpbmdSZXBsYXlTeW5jKHthY3RvciwgbXV0YXRpb259KSB7XG4gICAgaWYgKCF0aGlzLnN5bmNNb2RlbCkgcmV0dXJuIG51bGxcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLnN5bmNNb2RlbC5maW5kQnkoe1xuICAgICAgW3RoaXMuYWN0b3JGb3JlaWduS2V5Q29sdW1uXTogdGhpcy5yZXBsYXlBY3RvcklkKGFjdG9yKSxcbiAgICAgIHJlc291cmNlX2lkOiBtdXRhdGlvbi5yZXNvdXJjZUlkLFxuICAgICAgcmVzb3VyY2VfdHlwZTogbXV0YXRpb24ucmVzb3VyY2VUeXBlXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgcGVyc2lzdGVkIGFjdG9yIGlkIHVzZWQgYnkgbW9kZWwtYmFja2VkIGRlZmF1bHQgaG9va3MuXG4gICAqIEBwYXJhbSB7P30gYWN0b3IgLSBBY3RvciByZXR1cm5lZCBmcm9tIGF1dGhlbnRpY2F0ZVJlcGxheS5cbiAgICogQHJldHVybnMgez99IEFjdG9yIGlkLlxuICAgKi9cbiAgcmVwbGF5QWN0b3JJZChhY3Rvcikge1xuICAgIGlmICghYWN0b3IgfHwgdHlwZW9mIGFjdG9yICE9PSBcIm9iamVjdFwiIHx8IHR5cGVvZiBhY3Rvci5pZCAhPT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJTeW5jRW52ZWxvcGVSZXBsYXlTZXJ2aWNlIG1vZGVsLWJhY2tlZCBkZWZhdWx0cyByZXF1aXJlIGFuIGFjdG9yIHdpdGggYW4gaWQoKSBtZXRob2QgZnJvbSBhdXRoZW50aWNhdGVSZXBsYXlcIilcbiAgICB9XG5cbiAgICByZXR1cm4gYWN0b3IuaWQoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgd2hldGhlciBhIG5vcm1hbGl6ZWQgbXV0YXRpb24gc2hvdWxkIGJlIGFwcGxpZWQgdG8gZG9tYWluIG1vZGVscy5cbiAgICogQHBhcmFtIHt7YWN0b3I6ID8sIGNvbnRleHQ6IFJlY29yZDxzdHJpbmcsID8+LCBleGlzdGluZ1N5bmM6ID8sIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufX0gYXJncyAtIEFjdG9yLCBiYXRjaCBjb250ZXh0LCBleGlzdGluZyBzeW5jIHJvdywgYW5kIG11dGF0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gV2hldGhlciB0byBhcHBseSB0aGUgbXV0YXRpb24uXG4gICAqL1xuICBhc3luYyBzaG91bGRBcHBseVJlcGxheU11dGF0aW9uKHtleGlzdGluZ1N5bmMsIG11dGF0aW9ufSkge1xuICAgIGNvbnN0IGV4aXN0aW5nQ2xpZW50VXBkYXRlZEF0ID0gdGhpcy5leGlzdGluZ1JlcGxheVN5bmNDbGllbnRVcGRhdGVkQXQoZXhpc3RpbmdTeW5jKVxuXG4gICAgcmV0dXJuICFleGlzdGluZ0NsaWVudFVwZGF0ZWRBdCB8fCBtdXRhdGlvbi5jbGllbnRVcGRhdGVkQXQgPiBleGlzdGluZ0NsaWVudFVwZGF0ZWRBdFxuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmVzIHRoZSBjbGllbnQgdGltZXN0YW1wIGZyb20gYW4gZXhpc3Rpbmcgc3luYyByb3cuXG4gICAqIEBwYXJhbSB7P30gZXhpc3RpbmdTeW5jIC0gRXhpc3Rpbmcgc3luYyByb3cuXG4gICAqIEByZXR1cm5zIHtEYXRlIHwgbnVsbH0gRXhpc3RpbmcgY2xpZW50IHRpbWVzdGFtcC5cbiAgICovXG4gIGV4aXN0aW5nUmVwbGF5U3luY0NsaWVudFVwZGF0ZWRBdChleGlzdGluZ1N5bmMpIHtcbiAgICBpZiAoIWV4aXN0aW5nU3luYyB8fCB0eXBlb2YgZXhpc3RpbmdTeW5jICE9PSBcIm9iamVjdFwiKSByZXR1cm4gbnVsbFxuXG4gICAgY29uc3Qgc3luY1JlY29yZCA9IC8qKiBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChleGlzdGluZ1N5bmMpXG4gICAgY29uc3QgdmFsdWUgPSB0eXBlb2Ygc3luY1JlY29yZC5jbGllbnRVcGRhdGVkQXQgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgPyBzeW5jUmVjb3JkLmNsaWVudFVwZGF0ZWRBdCgpXG4gICAgICA6IHN5bmNSZWNvcmQuY2xpZW50VXBkYXRlZEF0XG5cbiAgICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSByZXR1cm4gdmFsdWVcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwic3RyaW5nXCIpIHJldHVybiBudWxsXG5cbiAgICBjb25zdCBwYXJzZWRWYWx1ZSA9IG5ldyBEYXRlKHZhbHVlKVxuXG4gICAgcmV0dXJuIE51bWJlci5pc05hTihwYXJzZWRWYWx1ZS5nZXRUaW1lKCkpID8gbnVsbCA6IHBhcnNlZFZhbHVlXG4gIH1cblxuICAvKipcbiAgICogQXBwbGllcyBvbmUgbm9ybWFsaXplZCBtdXRhdGlvbiB0byBkb21haW4gbW9kZWxzLlxuICAgKlxuICAgKiBEaXNwYXRjaGVzIHRocm91Z2ggdGhlIGNvbmZpZ3VyZWQgYXBwbHktaGFuZGxlciByZWdpc3RyeSBmaXJzdCAoY29tcGF0XG4gICAqIHByZWNlZGVuY2UpOyBtdXRhdGlvbnMgd2l0aG91dCBhIG1hdGNoaW5nIGhhbmRsZXIgZmFsbCB0aHJvdWdoIHRvXG4gICAqIHJlc291cmNlIHJvdXRpbmcgd2hlbiBhIGNvbmZpZ3VyYXRpb24gb3IgcmVzb3VyY2VUeXBlT3ZlcnJpZGVzIGFyZVxuICAgKiBjb25maWd1cmVkLCBhbmQgb3RoZXJ3aXNlIGZhaWwgbG91ZGx5LlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgY29udGV4dDogUmVjb3JkPHN0cmluZywgPz4sIGV4aXN0aW5nU3luYzogPywgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBhcmdzIC0gQWN0b3IsIGJhdGNoIGNvbnRleHQsIGV4aXN0aW5nIHN5bmMgcm93LCBhbmQgbXV0YXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPD8+fSBQcm9qZWN0LXNwZWNpZmljIGFwcGx5IHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIGFwcGx5UmVwbGF5TXV0YXRpb24oYXJncykge1xuICAgIGlmICh0aGlzLmFwcGx5SGFuZGxlcnMpIHtcbiAgICAgIGNvbnN0IGFwcGx5SGFuZGxlciA9IHRoaXMuYXBwbHlIYW5kbGVyc1thcmdzLm11dGF0aW9uLnJlc291cmNlVHlwZV1cblxuICAgICAgaWYgKGFwcGx5SGFuZGxlcikgcmV0dXJuIGF3YWl0IGFwcGx5SGFuZGxlcihhcmdzKVxuICAgICAgaWYgKCF0aGlzLnJvdXRpbmdDb25maWd1cmVkKCkpIHRocm93IG5ldyBFcnJvcihgTm8gc3luYyBhcHBseSBoYW5kbGVyIHJlZ2lzdGVyZWQgZm9yOiAke2FyZ3MubXV0YXRpb24ucmVzb3VyY2VUeXBlfWApXG4gICAgfVxuXG4gICAgaWYgKHRoaXMucm91dGluZ0NvbmZpZ3VyZWQoKSkgcmV0dXJuIGF3YWl0IHRoaXMuYXBwbHlSb3V0ZWRSZXBsYXlNdXRhdGlvbihhcmdzKVxuXG4gICAgcmV0dXJuIG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHdoZXRoZXIgcmVzb3VyY2Ugcm91dGluZyBpcyBjb25maWd1cmVkIG9uIHRoaXMgc2VydmljZS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IFdoZXRoZXIgbXV0YXRpb25zIHJvdXRlIHRvIGZyb250ZW5kLW1vZGVsIHJlc291cmNlcy5cbiAgICovXG4gIHJvdXRpbmdDb25maWd1cmVkKCkge1xuICAgIHJldHVybiBCb29sZWFuKHRoaXMuY29uZmlndXJhdGlvbiB8fCB0aGlzLnJlc291cmNlVHlwZU92ZXJyaWRlcylcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlcyB0aGUgcm91dGVkIHJlc291cmNlIHJlZ2lzdHJhdGlvbiBmb3IgYSByZXNvdXJjZSB0eXBlLCBtZW1vaXplZFxuICAgKiBwZXIgcmVwbGF5IHNlcnZpY2UuIE92ZXJyaWRlcyB3aW4gb3ZlciB0aGUgY29uZmlndXJhdGlvbiByZWdpc3RyeTsgc3RyaW5nXG4gICAqIG92ZXJyaWRlcyBhcmUgYWxpYXNlcyByZXNvbHZlZCB0aHJvdWdoIHRoZSByZWdpc3RyeS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHJlc291cmNlVHlwZSAtIE11dGF0aW9uIHJlc291cmNlIHR5cGUuXG4gICAqIEByZXR1cm5zIHtTeW5jUmVwbGF5UmVzb3VyY2VSZWdpc3RyYXRpb24gfCBudWxsfSBSZXNvbHZlZCByZWdpc3RyYXRpb24gb3IgbnVsbCB3aGVuIHVucm91dGFibGUuXG4gICAqL1xuICByZXBsYXlSZXNvdXJjZVJlZ2lzdHJhdGlvbihyZXNvdXJjZVR5cGUpIHtcbiAgICBjb25zdCBtZW1vaXplZFJlZ2lzdHJhdGlvbiA9IHRoaXMuX3JlcGxheVJlc291cmNlUmVnaXN0cmF0aW9ucy5nZXQocmVzb3VyY2VUeXBlKVxuXG4gICAgaWYgKG1lbW9pemVkUmVnaXN0cmF0aW9uICE9PSB1bmRlZmluZWQpIHJldHVybiBtZW1vaXplZFJlZ2lzdHJhdGlvblxuXG4gICAgY29uc3QgcmVnaXN0cmF0aW9uID0gdGhpcy5yZXNvbHZlUmVwbGF5UmVzb3VyY2VSZWdpc3RyYXRpb24ocmVzb3VyY2VUeXBlKVxuXG4gICAgdGhpcy5fcmVwbGF5UmVzb3VyY2VSZWdpc3RyYXRpb25zLnNldChyZXNvdXJjZVR5cGUsIHJlZ2lzdHJhdGlvbilcblxuICAgIHJldHVybiByZWdpc3RyYXRpb25cbiAgfVxuXG4gIC8qKlxuICAgKiBVbmNhY2hlZCByb3V0ZWQtcmVzb3VyY2UgcmVzb2x1dGlvbiBiZWhpbmQge0BsaW5rIFN5bmNFbnZlbG9wZVJlcGxheVNlcnZpY2UjcmVwbGF5UmVzb3VyY2VSZWdpc3RyYXRpb259LlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcmVzb3VyY2VUeXBlIC0gTXV0YXRpb24gcmVzb3VyY2UgdHlwZS5cbiAgICogQHJldHVybnMge1N5bmNSZXBsYXlSZXNvdXJjZVJlZ2lzdHJhdGlvbiB8IG51bGx9IFJlc29sdmVkIHJlZ2lzdHJhdGlvbiBvciBudWxsIHdoZW4gdW5yb3V0YWJsZS5cbiAgICovXG4gIHJlc29sdmVSZXBsYXlSZXNvdXJjZVJlZ2lzdHJhdGlvbihyZXNvdXJjZVR5cGUpIHtcbiAgICBjb25zdCBvdmVycmlkZSA9IHRoaXMucmVzb3VyY2VUeXBlT3ZlcnJpZGVzPy5bcmVzb3VyY2VUeXBlXVxuXG4gICAgaWYgKG92ZXJyaWRlICYmIHR5cGVvZiBvdmVycmlkZSAhPT0gXCJzdHJpbmdcIikge1xuICAgICAgcmV0dXJuIHttb2RlbE5hbWU6IHJlc291cmNlVHlwZSwgcmVzb3VyY2VDbGFzczogb3ZlcnJpZGUsIHJlc291cmNlQ29uZmlndXJhdGlvbjogbnVsbH1cbiAgICB9XG5cbiAgICBjb25zdCByZWdpc3RyeVJlc291cmNlVHlwZSA9IHR5cGVvZiBvdmVycmlkZSA9PT0gXCJzdHJpbmdcIiA/IG92ZXJyaWRlIDogcmVzb3VyY2VUeXBlXG5cbiAgICBpZiAoIXRoaXMuY29uZmlndXJhdGlvbikgcmV0dXJuIG51bGxcblxuICAgIGNvbnN0IHJlc29sdmVkUmVnaXN0cmF0aW9uID0gcmVzb2x2ZUZyb250ZW5kTW9kZWxSZXNvdXJjZUNsYXNzKHtjb25maWd1cmF0aW9uOiB0aGlzLmNvbmZpZ3VyYXRpb24sIHJlc291cmNlVHlwZTogcmVnaXN0cnlSZXNvdXJjZVR5cGV9KVxuXG4gICAgaWYgKCFyZXNvbHZlZFJlZ2lzdHJhdGlvbikgcmV0dXJuIG51bGxcblxuICAgIHJldHVybiB7XG4gICAgICBtb2RlbE5hbWU6IHJlc29sdmVkUmVnaXN0cmF0aW9uLm1vZGVsTmFtZSxcbiAgICAgIHJlc291cmNlQ2xhc3M6IHJlc29sdmVkUmVnaXN0cmF0aW9uLnJlc291cmNlQ2xhc3MsXG4gICAgICByZXNvdXJjZUNvbmZpZ3VyYXRpb246IHJlc29sdmVkUmVnaXN0cmF0aW9uLnJlc291cmNlQ29uZmlndXJhdGlvblxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBCdWlsZHMgdGhlIHJvdXRlZCByZXNvdXJjZSBpbnN0YW5jZSBoYW5kbGluZyBvbmUgbXV0YXRpb24uXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufSBhcmdzLm11dGF0aW9uIC0gTm9ybWFsaXplZCByZXBsYXkgbXV0YXRpb24uXG4gICAqIEBwYXJhbSB7U3luY1JlcGxheVJlc291cmNlUmVnaXN0cmF0aW9ufSBhcmdzLnJlZ2lzdHJhdGlvbiAtIFJlc29sdmVkIHJlc291cmNlIHJlZ2lzdHJhdGlvbi5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2Zyb250ZW5kLW1vZGVsLXJlc291cmNlL2Jhc2UtcmVzb3VyY2UuanNcIikuZGVmYXVsdH0gUm91dGVkIHJlc291cmNlIGluc3RhbmNlLlxuICAgKi9cbiAgYnVpbGRSZXBsYXlSZXNvdXJjZSh7bXV0YXRpb24sIHJlZ2lzdHJhdGlvbn0pIHtcbiAgICBjb25zdCBSZXNvdXJjZUNsYXNzID0gcmVnaXN0cmF0aW9uLnJlc291cmNlQ2xhc3NcblxuICAgIHJldHVybiBuZXcgUmVzb3VyY2VDbGFzcyh7XG4gICAgICBhYmlsaXR5OiB0aGlzLmFiaWxpdHkgfHwgdW5kZWZpbmVkLFxuICAgICAgY29udGV4dDogdGhpcy5hYmlsaXR5Q29udGV4dCB8fCB7fSxcbiAgICAgIGxvY2FsczogdGhpcy5sb2NhbHMgfHwge30sXG4gICAgICBtb2RlbE5hbWU6IHJlZ2lzdHJhdGlvbi5tb2RlbE5hbWUsXG4gICAgICBwYXJhbXM6IG11dGF0aW9uLmRhdGEsXG4gICAgICAuLi4ocmVnaXN0cmF0aW9uLnJlc291cmNlQ29uZmlndXJhdGlvbiA/IHtyZXNvdXJjZUNvbmZpZ3VyYXRpb246IHJlZ2lzdHJhdGlvbi5yZXNvdXJjZUNvbmZpZ3VyYXRpb259IDoge30pXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBsaWVzIG9uZSBtdXRhdGlvbiB0aHJvdWdoIGl0cyByb3V0ZWQgZnJvbnRlbmQtbW9kZWwgcmVzb3VyY2U6XG4gICAqIGF1dGhvcml6YXRpb24sIGFiaWxpdHktc2NvcGVkIHJlY29yZCBsb29rdXAsIHNjaGVtYSBub3JtYWxpemF0aW9uIGFuZFxuICAgKiBhc3NpZ24vc2F2ZSBmb3IgdXBkYXRlcywgc2F2ZS10aGVuLWNoZWNrIG1lbWJlcnNoaXAgY3JlYXRlcywgZGVzdHJveXMgZm9yXG4gICAqIGRlbGV0ZXMsIGFuZCB0aGUgcmVzb3VyY2UncyBhZnRlclN5bmNBcHBseSB0YWlsLiBDbGllbnQtc2FmZSBmYWlsdXJlc1xuICAgKiB0aHJvdyBzYWZlIGVycm9ycyB0aGF0IGZhaWwgdGhlIHNpbmdsZSBzeW5jLlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgY29udGV4dDogUmVjb3JkPHN0cmluZywgPz4sIGV4aXN0aW5nU3luYzogPywgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb259fSBhcmdzIC0gQWN0b3IsIGJhdGNoIGNvbnRleHQsIGV4aXN0aW5nIHN5bmMgcm93LCBhbmQgbXV0YXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPFJlY29yZDxzdHJpbmcsID8+Pn0gQXBwbHkgcmVzdWx0IHdpdGggcmVjb3JkLCBjcmVhdGVkL2RlbGV0ZWQgZmxhZ3MsIGFuZCBhZnRlclN5bmNBcHBseSBleHRyYXMuXG4gICAqL1xuICBhc3luYyBhcHBseVJvdXRlZFJlcGxheU11dGF0aW9uKHtjb250ZXh0LCBleGlzdGluZ1N5bmMsIG11dGF0aW9ufSkge1xuICAgIGNvbnN0IHJlZ2lzdHJhdGlvbiA9IHRoaXMucmVwbGF5UmVzb3VyY2VSZWdpc3RyYXRpb24obXV0YXRpb24ucmVzb3VyY2VUeXBlKVxuXG4gICAgaWYgKCFyZWdpc3RyYXRpb24pIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoYFVua25vd24gc3luYyByZXNvdXJjZSB0eXBlOiAke211dGF0aW9uLnJlc291cmNlVHlwZX0uYCwge2NvZGU6IFwidW5rbm93bi1yZXNvdXJjZS10eXBlXCJ9KVxuICAgIH1cblxuICAgIGNvbnN0IHJlc291cmNlID0gdGhpcy5idWlsZFJlcGxheVJlc291cmNlKHttdXRhdGlvbiwgcmVnaXN0cmF0aW9ufSlcbiAgICBjb25zdCBjdXN0b21BcHBseVJlc3VsdCA9IGF3YWl0IHJlc291cmNlLmFwcGx5U3luYyh7Y29udGV4dCwgZXhpc3RpbmdTeW5jLCBtdXRhdGlvbn0pXG5cbiAgICBpZiAoY3VzdG9tQXBwbHlSZXN1bHQgIT09IG51bGwpIHJldHVybiBjdXN0b21BcHBseVJlc3VsdFxuXG4gICAgY29uc3QgYXV0aG9yaXphdGlvbiA9IGF3YWl0IHJlc291cmNlLmF1dGhvcml6ZVN5bmNNdXRhdGlvbih7Y29udGV4dCwgbXV0YXRpb259KVxuXG4gICAgaWYgKCFhdXRob3JpemF0aW9uLmFsbG93ZWQpIHtcbiAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoYFN5bmMgbXV0YXRpb24gZGVuaWVkIGZvcjogJHttdXRhdGlvbi5yZXNvdXJjZVR5cGV9LmAsIHtjb2RlOiBhdXRob3JpemF0aW9uLnJlYXNvbiB8fCBcImFjY2Vzcy1kZW5pZWRcIn0pXG4gICAgfVxuXG4gICAgaWYgKG11dGF0aW9uLnN5bmNUeXBlID09PSBcImRlbGV0ZVwiKSByZXR1cm4gYXdhaXQgdGhpcy5hcHBseVJvdXRlZFJlcGxheURlbGV0ZSh7bXV0YXRpb24sIHJlc291cmNlfSlcblxuICAgIHJldHVybiBhd2FpdCB0aGlzLmFwcGx5Um91dGVkUmVwbGF5VXBzZXJ0KHtjb250ZXh0LCBtdXRhdGlvbiwgcmVzb3VyY2V9KVxuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgYSByb3V0ZWQgZGVsZXRlIG11dGF0aW9uLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIE9wdGlvbnMuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn0gYXJncy5tdXRhdGlvbiAtIE5vcm1hbGl6ZWQgcmVwbGF5IG11dGF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Zyb250ZW5kLW1vZGVsLXJlc291cmNlL2Jhc2UtcmVzb3VyY2UuanNcIikuZGVmYXVsdH0gYXJncy5yZXNvdXJjZSAtIFJvdXRlZCByZXNvdXJjZSBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fSBBcHBseSByZXN1bHQgd2l0aCB0aGUgZGVsZXRlZCBmbGFnLlxuICAgKi9cbiAgYXN5bmMgYXBwbHlSb3V0ZWRSZXBsYXlEZWxldGUoe211dGF0aW9uLCByZXNvdXJjZX0pIHtcbiAgICBjb25zdCByZWNvcmQgPSBhd2FpdCByZXNvdXJjZS5maW5kU3luY1JlY29yZCh7Zm9yRGVsZXRlOiB0cnVlLCBtdXRhdGlvbn0pXG5cbiAgICBpZiAoIXJlY29yZCkgcmV0dXJuIHtjcmVhdGVkOiBmYWxzZSwgZGVsZXRlZDogZmFsc2UsIHJlY29yZDogbnVsbH1cblxuICAgIGF3YWl0IHJlY29yZC5kZXN0cm95KClcblxuICAgIHJldHVybiB7Y3JlYXRlZDogZmFsc2UsIGRlbGV0ZWQ6IHRydWUsIHJlY29yZH1cbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBsaWVzIGEgcm91dGVkIHVwc2VydCBtdXRhdGlvbjogcGVybWl0dGVkIHBheWxvYWQgYXR0cmlidXRlcyBhcmVcbiAgICogYXNzaWduZWQgYW5kIHNhdmVkIG9udG8gdGhlIGZvdW5kIHJlY29yZCAodGhlIHJlY29yZCBsYXllciBvd25zIHZhbHVlXG4gICAqIGNhc3RpbmcgYW5kIHZhbGlkYXRpb24pLCBhbmQgbWlzc2luZyByZWNvcmRzIGFyZSBjcmVhdGVkIHdpdGggdGhlXG4gICAqIGNsaWVudC1nZW5lcmF0ZWQgcHJpbWFyeSBrZXkgcGx1cyBhIHNhdmUtdGhlbi1jaGVjayBtZW1iZXJzaGlwIGNoZWNrLlxuICAgKiBNb2RlbCB2YWxpZGF0aW9uIGZhaWx1cmVzIGJlY29tZSBjbGllbnQtc2FmZSBwZXItc3luYyBmYWlsdXJlcyBjYXJyeWluZ1xuICAgKiB0aGUgdHJhbnNsYXRlZCB2YWxpZGF0aW9uIG1lc3NhZ2UuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gYXJncy5jb250ZXh0IC0gUmVwbGF5IGNvbnRleHQuXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn0gYXJncy5tdXRhdGlvbiAtIE5vcm1hbGl6ZWQgcmVwbGF5IG11dGF0aW9uLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2Zyb250ZW5kLW1vZGVsLXJlc291cmNlL2Jhc2UtcmVzb3VyY2UuanNcIikuZGVmYXVsdH0gYXJncy5yZXNvdXJjZSAtIFJvdXRlZCByZXNvdXJjZSBpbnN0YW5jZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgPz4+fSBBcHBseSByZXN1bHQgd2l0aCByZWNvcmQsIGNyZWF0ZWQgZmxhZywgYW5kIGFmdGVyU3luY0FwcGx5IGV4dHJhcy5cbiAgICovXG4gIGFzeW5jIGFwcGx5Um91dGVkUmVwbGF5VXBzZXJ0KHtjb250ZXh0LCBtdXRhdGlvbiwgcmVzb3VyY2V9KSB7XG4gICAgY29uc3QgYXR0cmlidXRlcyA9IHRoaXMucGVybWl0dGVkUm91dGVkQXR0cmlidXRlcyh7bXV0YXRpb24sIHJlc291cmNlfSlcbiAgICBjb25zdCBleGlzdGluZ1JlY29yZCA9IGF3YWl0IHJlc291cmNlLmZpbmRTeW5jUmVjb3JkKHttdXRhdGlvbn0pXG5cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0IHwgbnVsbH0gKi9cbiAgICBsZXQgcmVjb3JkID0gZXhpc3RpbmdSZWNvcmRcbiAgICBsZXQgY3JlYXRlZCA9IGZhbHNlXG5cbiAgICBpZiAoZXhpc3RpbmdSZWNvcmQpIHtcbiAgICAgIGV4aXN0aW5nUmVjb3JkLmFzc2lnbihhdHRyaWJ1dGVzKVxuICAgICAgYXdhaXQgdGhpcy5zYXZlUm91dGVkUmVwbGF5UmVjb3JkKGV4aXN0aW5nUmVjb3JkKVxuICAgIH0gZWxzZSB7XG4gICAgICByZWNvcmQgPSBhd2FpdCB0aGlzLmNyZWF0ZVJvdXRlZFJlcGxheVJlY29yZCh7YXR0cmlidXRlcywgbXV0YXRpb24sIHJlc291cmNlfSlcbiAgICAgIGNyZWF0ZWQgPSB0cnVlXG4gICAgfVxuXG4gICAgY29uc3QgZXh0cmFzID0gYXdhaXQgcmVzb3VyY2UuYWZ0ZXJTeW5jQXBwbHkoe2NvbnRleHQsIGNyZWF0ZWQsIG11dGF0aW9uLCByZWNvcmR9KVxuXG4gICAgcmV0dXJuIHtjcmVhdGVkLCBkZWxldGVkOiBmYWxzZSwgcmVjb3JkLCAuLi5leHRyYXN9XG4gIH1cblxuICAvKipcbiAgICogRmlsdGVycyBhIHJvdXRlZCBtdXRhdGlvbiBwYXlsb2FkIGRvd24gdG8gdGhlIHJlc291cmNlJ3MgZGVjbGFyZWRcbiAgICogd3JpdGFibGUtYXR0cmlidXRlIHBlcm1pdCBsaXN0LiBBY2NlcHRlZCBrZXlzIHBlciBwZXJtaXR0ZWQgYXR0cmlidXRlIGFyZVxuICAgKiB0aGUgY2FtZWxDYXNlIGF0dHJpYnV0ZSBuYW1lIHBsdXMgdGhlIG1vZGVsJ3MgYWN0dWFsIGNvbHVtbiBuYW1lOyB1bmtub3duXG4gICAqIGtleXMgZmFpbCB0aGUgc3luYyBsb3VkbHkuIFRoZSBwcmltYXJ5IGtleSBpcyBkcm9wcGVkIHdoZW4gcGVybWl0dGVkXG4gICAqIChzbmFwc2hvdCBwYXlsb2Fkcykg4oCUIHRoZSBlbnZlbG9wZSdzIHJlc291cmNlSWQgaXMgdGhlIGF1dGhvcml0YXRpdmVcbiAgICogcmVjb3JkIGlkZW50aXR5LCBzbyBhIHBheWxvYWQgaWQgY2FuIG5ldmVyIHJldGFyZ2V0IHRoZSByb3cuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufSBhcmdzLm11dGF0aW9uIC0gTm9ybWFsaXplZCByZXBsYXkgbXV0YXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZnJvbnRlbmQtbW9kZWwtcmVzb3VyY2UvYmFzZS1yZXNvdXJjZS5qc1wiKS5kZWZhdWx0fSBhcmdzLnJlc291cmNlIC0gUm91dGVkIHJlc291cmNlIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7UmVjb3JkPHN0cmluZywgPz59IFBlcm1pdHRlZCBhdHRyaWJ1dGVzIGZvciByZWNvcmQuYXNzaWduLlxuICAgKi9cbiAgcGVybWl0dGVkUm91dGVkQXR0cmlidXRlcyh7bXV0YXRpb24sIHJlc291cmNlfSkge1xuICAgIGNvbnN0IHBlcm1pdHRlZEF0dHJpYnV0ZXMgPSByZXNvdXJjZS5kZWNsYXJlZFdyaXRhYmxlQXR0cmlidXRlcygpXG5cbiAgICBpZiAoIXBlcm1pdHRlZEF0dHJpYnV0ZXMpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgJHtyZXNvdXJjZS5jb25zdHJ1Y3Rvci5uYW1lfSBtdXN0IGRlY2xhcmUgc3RhdGljIHdyaXRhYmxlQXR0cmlidXRlcyB0byBhcHBseSByb3V0ZWQgc3luYyBtdXRhdGlvbnMgZm9yOiAke211dGF0aW9uLnJlc291cmNlVHlwZX1gKVxuICAgIH1cblxuICAgIGNvbnN0IE1vZGVsQ2xhc3MgPSByZXNvdXJjZS5tb2RlbENsYXNzKClcbiAgICBjb25zdCBhdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lID0gTW9kZWxDbGFzcy5nZXRBdHRyaWJ1dGVOYW1lVG9Db2x1bW5OYW1lTWFwKClcblxuICAgIC8qKiBAdHlwZSB7U2V0PHN0cmluZz59ICovXG4gICAgY29uc3QgYWxsb3dlZEtleXMgPSBuZXcgU2V0KClcblxuICAgIGZvciAoY29uc3QgYXR0cmlidXRlTmFtZSBvZiBwZXJtaXR0ZWRBdHRyaWJ1dGVzKSB7XG4gICAgICBhbGxvd2VkS2V5cy5hZGQoYXR0cmlidXRlTmFtZSlcblxuICAgICAgY29uc3QgY29sdW1uTmFtZSA9IGF0dHJpYnV0ZU5hbWVUb0NvbHVtbk5hbWVbYXR0cmlidXRlTmFtZV1cblxuICAgICAgaWYgKGNvbHVtbk5hbWUpIGFsbG93ZWRLZXlzLmFkZChjb2x1bW5OYW1lKVxuICAgIH1cblxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSBNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIGNvbnN0IHByaW1hcnlLZXlBdHRyaWJ1dGUgPSBNb2RlbENsYXNzLmdldENvbHVtbk5hbWVUb0F0dHJpYnV0ZU5hbWVNYXAoKVtwcmltYXJ5S2V5XVxuXG4gICAgLyoqIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi9cbiAgICBjb25zdCBhdHRyaWJ1dGVzID0ge31cblxuICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKG11dGF0aW9uLmRhdGEpKSB7XG4gICAgICBpZiAoIWFsbG93ZWRLZXlzLmhhcyhrZXkpKSB7XG4gICAgICAgIHRocm93IHJlc291cmNlLndyaXRhYmxlQXR0cmlidXRlRXJyb3IoYFVua25vd24gYXR0cmlidXRlOiAke2tleX0uYCwge2NvZGU6IFwic3luYy11bmtub3duLWF0dHJpYnV0ZVwifSlcbiAgICAgIH1cblxuICAgICAgaWYgKGtleSA9PT0gcHJpbWFyeUtleSB8fCBrZXkgPT09IHByaW1hcnlLZXlBdHRyaWJ1dGUpIGNvbnRpbnVlXG5cbiAgICAgIGF0dHJpYnV0ZXNba2V5XSA9IHZhbHVlXG4gICAgfVxuXG4gICAgcmV0dXJuIGF0dHJpYnV0ZXNcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSByb3V0ZWQgcmVjb3JkIHdpdGggdGhlIGNsaWVudC1nZW5lcmF0ZWQgcHJpbWFyeSBrZXksIHRoZW5cbiAgICogdmVyaWZpZXMgY3JlYXRlLXNjb3BlIG1lbWJlcnNoaXAgd2hlbiBhbiBhYmlsaXR5IGlzIGNvbmZpZ3VyZWQ6IHJlY29yZHNcbiAgICogb3V0c2lkZSB0aGUgYWJpbGl0eSdzIGNyZWF0ZSBzY29wZSBhcmUgZGVzdHJveWVkIGFnYWluIGFuZCBmYWlsIHRoZSBzeW5jXG4gICAqIHdpdGggdGhlIHJlc291cmNlLWRlY2xhcmVkIHJlYXNvbi4gQSByZWNvcmQgdGhhdCBhbHJlYWR5IGV4aXN0cyBvdXRzaWRlXG4gICAqIHRoZSByZXNvdXJjZSdzIGxvb2t1cCBzY29wZSBmYWlscyB0aGUgc3luYyBhcyBhbiBhdXRob3JpemF0aW9uIGRlbmlhbFxuICAgKiBpbnN0ZWFkIG9mIGNvbGxpZGluZyBvbiB0aGUgcHJpbWFyeSBrZXkuXG4gICAqIEBwYXJhbSB7b2JqZWN0fSBhcmdzIC0gT3B0aW9ucy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gYXJncy5hdHRyaWJ1dGVzIC0gUGVybWl0dGVkIHBheWxvYWQgYXR0cmlidXRlcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9ufSBhcmdzLm11dGF0aW9uIC0gTm9ybWFsaXplZCByZXBsYXkgbXV0YXRpb24uXG4gICAqIEBwYXJhbSB7aW1wb3J0KFwiLi4vZnJvbnRlbmQtbW9kZWwtcmVzb3VyY2UvYmFzZS1yZXNvdXJjZS5qc1wiKS5kZWZhdWx0fSBhcmdzLnJlc291cmNlIC0gUm91dGVkIHJlc291cmNlIGluc3RhbmNlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxpbXBvcnQoXCIuLi9kYXRhYmFzZS9yZWNvcmQvaW5kZXguanNcIikuZGVmYXVsdD59IENyZWF0ZWQgcmVjb3JkLlxuICAgKi9cbiAgYXN5bmMgY3JlYXRlUm91dGVkUmVwbGF5UmVjb3JkKHthdHRyaWJ1dGVzLCBtdXRhdGlvbiwgcmVzb3VyY2V9KSB7XG4gICAgY29uc3QgTW9kZWxDbGFzcyA9IHJlc291cmNlLm1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSBNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIGNvbnN0IGNvbmZsaWN0aW5nSWRzID0gYXdhaXQgTW9kZWxDbGFzcy53aGVyZSh7W3ByaW1hcnlLZXldOiBtdXRhdGlvbi5yZXNvdXJjZUlkfSkucGx1Y2socHJpbWFyeUtleSlcblxuICAgIGlmIChjb25mbGljdGluZ0lkcy5sZW5ndGggPiAwKSB7XG4gICAgICB0aHJvdyBWZWxvY2lvdXNFcnJvci5zYWZlKGBTeW5jIHVwZGF0ZSBkZW5pZWQgZm9yOiAke211dGF0aW9uLnJlc291cmNlVHlwZX0uYCwge1xuICAgICAgICBjb2RlOiByZXNvdXJjZS5zeW5jQXV0aG9yaXphdGlvbkZhaWx1cmVSZWFzb24oe2FjdGlvbjogXCJ1cGRhdGVcIiwgbXV0YXRpb259KSB8fCBcImFjY2Vzcy1kZW5pZWRcIlxuICAgICAgfSlcbiAgICB9XG5cbiAgICAvKiogQHR5cGUge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSAqL1xuICAgIGxldCByZWNvcmRcblxuICAgIHRyeSB7XG4gICAgICByZWNvcmQgPSBhd2FpdCBNb2RlbENsYXNzLmNyZWF0ZSh7W3ByaW1hcnlLZXldOiBtdXRhdGlvbi5yZXNvdXJjZUlkLCAuLi5hdHRyaWJ1dGVzfSlcbiAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgdGhyb3cgdGhpcy5yb3V0ZWRSZXBsYXlTYXZlRXJyb3IoZXJyb3IpXG4gICAgfVxuXG4gICAgY29uc3QgYWJpbGl0eSA9IHJlc291cmNlLmFiaWxpdHlcblxuICAgIGlmIChhYmlsaXR5KSB7XG4gICAgICBjb25zdCBtZW1iZXJJZHMgPSBhd2FpdCBNb2RlbENsYXNzXG4gICAgICAgIC5hY2Nlc3NpYmxlRm9yKHJlc291cmNlLnN5bmNBYmlsaXR5QWN0aW9uKFwiY3JlYXRlXCIpLCBhYmlsaXR5KVxuICAgICAgICAud2hlcmUoe1twcmltYXJ5S2V5XTogcmVjb3JkLmlkKCl9KVxuICAgICAgICAucGx1Y2socHJpbWFyeUtleSlcblxuICAgICAgaWYgKG1lbWJlcklkcy5sZW5ndGggPT09IDApIHtcbiAgICAgICAgYXdhaXQgcmVjb3JkLmRlc3Ryb3koKVxuXG4gICAgICAgIHRocm93IFZlbG9jaW91c0Vycm9yLnNhZmUoYFN5bmMgY3JlYXRlIGRlbmllZCBmb3I6ICR7bXV0YXRpb24ucmVzb3VyY2VUeXBlfS5gLCB7XG4gICAgICAgICAgY29kZTogcmVzb3VyY2Uuc3luY0F1dGhvcml6YXRpb25GYWlsdXJlUmVhc29uKHthY3Rpb246IFwiY3JlYXRlXCIsIG11dGF0aW9ufSkgfHwgXCJhY2Nlc3MtZGVuaWVkXCJcbiAgICAgICAgfSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVjb3JkXG4gIH1cblxuICAvKipcbiAgICogU2F2ZXMgYSByb3V0ZWQgcmVjb3JkLCBjb252ZXJ0aW5nIG1vZGVsIHZhbGlkYXRpb24gZmFpbHVyZXMgaW50b1xuICAgKiBjbGllbnQtc2FmZSBwZXItc3luYyBlcnJvcnMgY2FycnlpbmcgdGhlIHRyYW5zbGF0ZWQgdmFsaWRhdGlvbiBtZXNzYWdlLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4uL2RhdGFiYXNlL3JlY29yZC9pbmRleC5qc1wiKS5kZWZhdWx0fSByZWNvcmQgLSBSZWNvcmQgdG8gc2F2ZS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFJlc29sdmVzIHdoZW4gc2F2ZWQuXG4gICAqL1xuICBhc3luYyBzYXZlUm91dGVkUmVwbGF5UmVjb3JkKHJlY29yZCkge1xuICAgIHRyeSB7XG4gICAgICBhd2FpdCByZWNvcmQuc2F2ZSgpXG4gICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgIHRocm93IHRoaXMucm91dGVkUmVwbGF5U2F2ZUVycm9yKGVycm9yKVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBNYXBzIGEgcm91dGVkIHNhdmUvY3JlYXRlIGZhaWx1cmU6IG1vZGVsIHZhbGlkYXRpb24gZXJyb3JzIGJlY29tZVxuICAgKiBjbGllbnQtc2FmZSBlcnJvcnMgd2l0aCB0aGVpciB0cmFuc2xhdGVkIG1lc3NhZ2VzLCBldmVyeXRoaW5nIGVsc2VcbiAgICogcHJvcGFnYXRlcyB1bmNoYW5nZWQuXG4gICAqIEBwYXJhbSB7P30gZXJyb3IgLSBUaHJvd24gc2F2ZS9jcmVhdGUgZXJyb3IuXG4gICAqIEByZXR1cm5zIHtFcnJvcn0gRXJyb3IgdG8gcmV0aHJvdy5cbiAgICovXG4gIHJvdXRlZFJlcGxheVNhdmVFcnJvcihlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIFZhbGlkYXRpb25FcnJvcikge1xuICAgICAgcmV0dXJuIFZlbG9jaW91c0Vycm9yLnNhZmUoZXJyb3IubWVzc2FnZSwge2NhdXNlOiBlcnJvciwgY29kZTogXCJ2YWxpZGF0aW9uLWVycm9yXCJ9KVxuICAgIH1cblxuICAgIHJldHVybiAvKiogQHR5cGUge0Vycm9yfSAqLyAoZXJyb3IpXG4gIH1cblxuICAvKipcbiAgICogUmVzb2x2ZXMgYW4gYXBwbHkgcmVzdWx0IGZvciBzdGFsZSBtdXRhdGlvbnMgdGhhdCBzaG91bGQgbm90IHRvdWNoIGRvbWFpbiBtb2RlbHMuXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgZXhpc3RpbmdTeW5jOiA/LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn19IF9hcmdzIC0gQWN0b3IsIGJhdGNoIGNvbnRleHQsIGV4aXN0aW5nIHN5bmMgcm93LCBhbmQgbXV0YXRpb24uXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPD8+fSBQcm9qZWN0LXNwZWNpZmljIGFwcGx5IHJlc3VsdC5cbiAgICovXG4gIGFzeW5jIHNraXBwZWRSZXBsYXlNdXRhdGlvbihfYXJncykge1xuICAgIHJldHVybiBudWxsXG4gIH1cblxuICAvKipcbiAgICogUGVyc2lzdHMgb25lIG5vcm1hbGl6ZWQgbXV0YXRpb24gaW50byB0aGUgYXBwIHN5bmMvY2hhbmdlIHN0b3JlLlxuICAgKlxuICAgKiBEZWZhdWx0cyB0byBhIHN0YWxlLWd1YXJkZWQgc3luYy1tb2RlbCB1cHNlcnQgKHdpdGggc2VydmVyIHJlLXNlcXVlbmNpbmcgb25cbiAgICogdXBkYXRlcykgd2hlbiBhIHN5bmMgbW9kZWwgaXMgY29uZmlndXJlZDsgb3RoZXJ3aXNlIGFwcHMgb3ZlcnJpZGUgdGhpcyBob29rLlxuICAgKiBAcGFyYW0ge3thY3RvcjogPywgY29udGV4dDogUmVjb3JkPHN0cmluZywgPz4sIGV4aXN0aW5nU3luYzogPywgYXBwbHlSZXN1bHQ6ID8sIG11dGF0aW9uOiBpbXBvcnQoXCIuL3N5bmMtZW52ZWxvcGUtcmVwbGF5LXNlcnZpY2UuanNcIikuU3luY1JlcGxheU11dGF0aW9uLCBzaG91bGRBcHBseTogYm9vbGVhbn19IGFyZ3MgLSBSZXBsYXkgcGVyc2lzdGVuY2UgYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn1cbiAgICovXG4gIGFzeW5jIHBlcnNpc3RSZXBsYXlNdXRhdGlvbih7YWN0b3IsIGFwcGx5UmVzdWx0LCBjb250ZXh0LCBleGlzdGluZ1N5bmMsIG11dGF0aW9uLCBzaG91bGRBcHBseX0pIHtcbiAgICBpZiAoIXRoaXMuc3luY01vZGVsKSByZXR1cm5cblxuICAgIGNvbnN0IGF0dHJpYnV0ZXMgPSB0aGlzLnJlcGxheVBlcnNpc3RBdHRyaWJ1dGVzKHthY3RvciwgbXV0YXRpb259KVxuXG4gICAgLy8gU3RhbGUgcmVwbGF5cyBuZXZlciBhcHBsaWVkIGFueXRoaW5nLCBzbyB0aGUgYXBwbHlSZXN1bHQtZHJpdmVuIGV4dGVuc2lvblxuICAgIC8vIGhvb2tzIG11c3Qgbm90IHJ1biBhZ2FpbnN0IHRoZSBkZWZhdWx0IG51bGwgc2tpcHBlZCByZXN1bHQuXG4gICAgaWYgKHRoaXMucGVyc2lzdEV4dHJhQXR0cmlidXRlcyAmJiBzaG91bGRBcHBseSkge1xuICAgICAgT2JqZWN0LmFzc2lnbihhdHRyaWJ1dGVzLCB0aGlzLnBlcnNpc3RFeHRyYUF0dHJpYnV0ZXMoe2FjdG9yLCBhcHBseVJlc3VsdCwgY29udGV4dCwgZXhpc3RpbmdTeW5jLCBtdXRhdGlvbiwgc2hvdWxkQXBwbHl9KSlcbiAgICB9XG5cbiAgICBpZiAodGhpcy5wZXJzaXN0U2VyaWFsaXplZERhdGEgJiYgc2hvdWxkQXBwbHkpIHtcbiAgICAgIGNvbnN0IHNlcmlhbGl6ZWREYXRhID0gdGhpcy5wZXJzaXN0U2VyaWFsaXplZERhdGEoe2FwcGx5UmVzdWx0LCBtdXRhdGlvbn0pXG5cbiAgICAgIGlmIChzZXJpYWxpemVkRGF0YSAhPT0gdW5kZWZpbmVkICYmIHNlcmlhbGl6ZWREYXRhICE9PSBudWxsKSB7XG4gICAgICAgIGF0dHJpYnV0ZXMuZGF0YSA9IHR5cGVvZiBzZXJpYWxpemVkRGF0YSA9PT0gXCJzdHJpbmdcIiA/IHNlcmlhbGl6ZWREYXRhIDogSlNPTi5zdHJpbmdpZnkoc2VyaWFsaXplZERhdGEpXG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGV4aXN0aW5nU3luYykge1xuICAgICAgY29uc3QgZXhpc3RpbmdDbGllbnRVcGRhdGVkQXQgPSB0aGlzLmV4aXN0aW5nUmVwbGF5U3luY0NsaWVudFVwZGF0ZWRBdChleGlzdGluZ1N5bmMpXG5cbiAgICAgIGlmIChleGlzdGluZ0NsaWVudFVwZGF0ZWRBdCAmJiBtdXRhdGlvbi5jbGllbnRVcGRhdGVkQXQgPD0gZXhpc3RpbmdDbGllbnRVcGRhdGVkQXQpIHJldHVyblxuXG4gICAgICBleGlzdGluZ1N5bmMuYXNzaWduKGF0dHJpYnV0ZXMpXG4gICAgICBhd2FpdCBleGlzdGluZ1N5bmMuYWR2YW5jZVNlcnZlclNlcXVlbmNlKClcbiAgICAgIGF3YWl0IGV4aXN0aW5nU3luYy5zYXZlKClcbiAgICB9IGVsc2Uge1xuICAgICAgYXdhaXQgdGhpcy5zeW5jTW9kZWwuY3JlYXRlKGF0dHJpYnV0ZXMpXG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEJ1aWxkcyB0aGUgc3luYy1tb2RlbCBhdHRyaWJ1dGVzIHBlcnNpc3RlZCBieSB0aGUgbW9kZWwtYmFja2VkIGRlZmF1bHQuXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBtdXRhdGlvbjogaW1wb3J0KFwiLi9zeW5jLWVudmVsb3BlLXJlcGxheS1zZXJ2aWNlLmpzXCIpLlN5bmNSZXBsYXlNdXRhdGlvbn19IGFyZ3MgLSBBY3RvciBhbmQgbXV0YXRpb24uXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gU3luYyByb3cgYXR0cmlidXRlcy5cbiAgICovXG4gIHJlcGxheVBlcnNpc3RBdHRyaWJ1dGVzKHthY3RvciwgbXV0YXRpb259KSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIFt0aGlzLmFjdG9yRm9yZWlnbktleUNvbHVtbl06IHRoaXMucmVwbGF5QWN0b3JJZChhY3RvciksXG4gICAgICBjbGllbnRfdXBkYXRlZF9hdDogbXV0YXRpb24uY2xpZW50VXBkYXRlZEF0LFxuICAgICAgZGF0YTogbXV0YXRpb24uc2VyaWFsaXplZERhdGEsXG4gICAgICByZXNvdXJjZV9pZDogbXV0YXRpb24ucmVzb3VyY2VJZCxcbiAgICAgIHJlc291cmNlX3R5cGU6IG11dGF0aW9uLnJlc291cmNlVHlwZSxcbiAgICAgIHN5bmNfdHlwZTogbXV0YXRpb24uc3luY1R5cGVcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBzaWRlIGVmZmVjdHMgYWZ0ZXIgYSBzdWNjZXNzZnVsIG11dGF0aW9uIHJlcGxheSBhbmQgcGVyc2lzdGVuY2UuXG4gICAqXG4gICAqIERlZmF1bHRzIHRvIGZhbm5pbmcgdGhlIGFwcGxpZWQgcmVzdWx0IG91dCB0aHJvdWdoIHRoZSBjb25maWd1cmVkXG4gICAqIGRlY2xhcmF0aXZlIGJyb2FkY2FzdHMuXG4gICAqIEBwYXJhbSB7e2FjdG9yOiA/LCBjb250ZXh0OiBSZWNvcmQ8c3RyaW5nLCA/PiwgZXhpc3RpbmdTeW5jOiA/LCBhcHBseVJlc3VsdDogPywgbXV0YXRpb246IGltcG9ydChcIi4vc3luYy1lbnZlbG9wZS1yZXBsYXktc2VydmljZS5qc1wiKS5TeW5jUmVwbGF5TXV0YXRpb24sIHNob3VsZEFwcGx5OiBib29sZWFufX0gYXJncyAtIFJlcGxheSBzaWRlLWVmZmVjdCBhcmd1bWVudHMuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fVxuICAgKi9cbiAgYXN5bmMgYWZ0ZXJSZXBsYXlNdXRhdGlvbihhcmdzKSB7XG4gICAgaWYgKCF0aGlzLmJyb2FkY2FzdHMgfHwgIXRoaXMuYnJvYWRjYXN0ZXIpIHJldHVyblxuICAgIC8vIFN0YWxlIHJlcGxheXMgbmV2ZXIgYXBwbGllZCBhbnl0aGluZyAtIGJyb2FkY2FzdGluZyB0aGVpciBza2lwcGVkIHJlc3VsdHNcbiAgICAvLyB3b3VsZCBmYW4gb3V0IHN0YWxlIHNpZGUgZWZmZWN0cyAob3IgY3Jhc2ggb24gdGhlIGRlZmF1bHQgbnVsbCBhcHBseVJlc3VsdCkuXG4gICAgaWYgKCFhcmdzLnNob3VsZEFwcGx5KSByZXR1cm5cblxuICAgIGZvciAoY29uc3QgYnJvYWRjYXN0IG9mIHRoaXMuYnJvYWRjYXN0cykge1xuICAgICAgaWYgKGJyb2FkY2FzdC53aGVuICYmICFicm9hZGNhc3Qud2hlbihhcmdzKSkgY29udGludWVcblxuICAgICAgYXdhaXQgdGhpcy5icm9hZGNhc3Rlcih7XG4gICAgICAgIGJvZHk6IGJyb2FkY2FzdC5ib2R5KGFyZ3MpLFxuICAgICAgICBjaGFubmVsOiB0eXBlb2YgYnJvYWRjYXN0LmNoYW5uZWwgPT09IFwiZnVuY3Rpb25cIiA/IGJyb2FkY2FzdC5jaGFubmVsKGFyZ3MpIDogYnJvYWRjYXN0LmNoYW5uZWwsXG4gICAgICAgIHBhcmFtczogYnJvYWRjYXN0LmJyb2FkY2FzdFBhcmFtcyhhcmdzKVxuICAgICAgfSlcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZXNvbHZlZCByb3V0ZWQtcmVzb3VyY2UgcmVnaXN0cmF0aW9uIGZvciBvbmUgcmVwbGF5IHJlc291cmNlIHR5cGUuXG4gKiBAdHlwZWRlZiB7b2JqZWN0fSBTeW5jUmVwbGF5UmVzb3VyY2VSZWdpc3RyYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBtb2RlbE5hbWUgLSBFZmZlY3RpdmUgZnJvbnRlbmQgbW9kZWwgbmFtZS5cbiAqIEBwcm9wZXJ0eSB7aW1wb3J0KFwiLi4vY29uZmlndXJhdGlvbi10eXBlcy5qc1wiKS5Gcm9udGVuZE1vZGVsUmVzb3VyY2VDbGFzc1R5cGV9IHJlc291cmNlQ2xhc3MgLSBSb3V0ZWQgcmVzb3VyY2UgY2xhc3MuXG4gKiBAcHJvcGVydHkge2ltcG9ydChcIi4uL2NvbmZpZ3VyYXRpb24tdHlwZXMuanNcIikuTm9ybWFsaXplZEZyb250ZW5kTW9kZWxSZXNvdXJjZUNvbmZpZ3VyYXRpb24gfCBudWxsfSByZXNvdXJjZUNvbmZpZ3VyYXRpb24gLSBOb3JtYWxpemVkIHJlc291cmNlIGNvbmZpZ3VyYXRpb24gd2hlbiByZWdpc3RyeS1yZXNvbHZlZC5cbiAqL1xuXG4vKipcbiAqIEB0eXBlZGVmIHtvYmplY3R9IFN5bmNSZXBsYXlNdXRhdGlvblxuICogQHByb3BlcnR5IHtEYXRlfSBjbGllbnRVcGRhdGVkQXQgLSBDbGllbnQtc2lkZSBtdXRhdGlvbiB0aW1lc3RhbXAuXG4gKiBAcHJvcGVydHkge1JlY29yZDxzdHJpbmcsID8+fSBkYXRhIC0gUGFyc2VkIG11dGF0aW9uIHBheWxvYWQuXG4gKiBAcHJvcGVydHkgez99IGlkIC0gQ2xpZW50IHN5bmMgcm93IGlkIGZvciBwZXItc3luYyByZXNwb25zZXMuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gcmVzb3VyY2VJZCAtIFJlc291cmNlIGlkIGFzIGEgc3RyaW5nLlxuICogQHByb3BlcnR5IHtzdHJpbmd9IHJlc291cmNlVHlwZSAtIFJlc291cmNlL21vZGVsIG5hbWUuXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc2VyaWFsaXplZERhdGEgLSBKU09OIHNlcmlhbGl6ZWQgbXV0YXRpb24gcGF5bG9hZC5cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBzeW5jVHlwZSAtIFN5bmMgb3BlcmF0aW9uIHR5cGUuXG4gKi9cbiJdfQ==
|