velocious 1.0.445 → 1.0.446
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 +37 -37
- package/build/environment-handlers/node/cli/commands/generate/base-models.js +67 -1
- package/build/environment-handlers/node/cli/commands/generate/frontend-models.js +169 -0
- package/build/frontend-model-controller.js +44 -12
- package/build/frontend-model-resource/base-resource.js +519 -129
- package/build/frontend-models/base.js +324 -118
- package/build/frontend-models/websocket-channel.js +39 -3
- package/build/src/database/record/index.d.ts +37 -37
- package/build/src/database/record/index.d.ts.map +1 -1
- package/build/src/database/record/index.js +38 -38
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts +13 -0
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/base-models.js +59 -2
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts +74 -0
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.d.ts.map +1 -1
- package/build/src/environment-handlers/node/cli/commands/generate/frontend-models.js +155 -1
- package/build/src/frontend-model-controller.d.ts +2 -1
- package/build/src/frontend-model-controller.d.ts.map +1 -1
- package/build/src/frontend-model-controller.js +38 -14
- package/build/src/frontend-model-resource/base-resource.d.ts +196 -21
- package/build/src/frontend-model-resource/base-resource.d.ts.map +1 -1
- package/build/src/frontend-model-resource/base-resource.js +467 -112
- package/build/src/frontend-models/base.d.ts +77 -4
- package/build/src/frontend-models/base.d.ts.map +1 -1
- package/build/src/frontend-models/base.js +278 -116
- package/build/src/frontend-models/websocket-channel.d.ts +8 -0
- package/build/src/frontend-models/websocket-channel.d.ts.map +1 -1
- package/build/src/frontend-models/websocket-channel.js +35 -4
- package/package.json +1 -1
- package/src/database/record/index.js +37 -37
- package/src/environment-handlers/node/cli/commands/generate/base-models.js +67 -1
- package/src/environment-handlers/node/cli/commands/generate/frontend-models.js +169 -0
- package/src/frontend-model-controller.js +44 -12
- package/src/frontend-model-resource/base-resource.js +519 -129
- package/src/frontend-models/base.js +324 -118
- package/src/frontend-models/websocket-channel.js +39 -3
|
@@ -100,6 +100,14 @@ export default class FrontendModelWebsocketChannel extends VelociousWebsocketCha
|
|
|
100
100
|
* @returns {import("../frontend-model-controller.js").default} - Synthetic controller used for resource serialization.
|
|
101
101
|
*/
|
|
102
102
|
_frontendModelController(FrontendModelController: typeof import("../frontend-model-controller.js").default, params?: Record<string, unknown>): import("../frontend-model-controller.js").default;
|
|
103
|
+
/**
|
|
104
|
+
* Whether the broadcast record is within the subscriber's authenticated ability scope. Used to gate
|
|
105
|
+
* unfiltered/unprojected create/update delivery so a scoped token never receives a record it cannot read.
|
|
106
|
+
* @param {string | number} id - Event record id.
|
|
107
|
+
* @param {typeof import("../frontend-model-controller.js").default} FrontendModelController - Server-side frontend-model controller class.
|
|
108
|
+
* @returns {Promise<boolean>} True when the record is readable by this subscription.
|
|
109
|
+
*/
|
|
110
|
+
_eventIsAccessible(id: string | number, FrontendModelController: typeof import("../frontend-model-controller.js").default): Promise<boolean>;
|
|
103
111
|
/**
|
|
104
112
|
* Runs matched event filter keys for event id.
|
|
105
113
|
* @param {string | number} id - Event record id.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"websocket-channel.d.ts","sourceRoot":"","sources":["../../../src/frontend-models/websocket-channel.js"],"names":[],"mappings":"AAQA;;;GAGG;AACH;;;GAGG;AACH;;;GAGG;AAEH;;;;;;;;;;;;;;;;;;GAkBG;AACH;IACE;;qEAEiE;IACjE,UADS,OAAO,6BAA6B,EAAE,OAAO,GAAG,IAAI,CAC9C;IAEf;;;OAGG;IACH,gBAFa,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"websocket-channel.d.ts","sourceRoot":"","sources":["../../../src/frontend-models/websocket-channel.js"],"names":[],"mappings":"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"}
|
|
@@ -54,7 +54,11 @@ export default class FrontendModelWebsocketChannel extends VelociousWebsocketCha
|
|
|
54
54
|
if (!ModelClass)
|
|
55
55
|
return false;
|
|
56
56
|
const ability = await configuration.resolveAbility?.({
|
|
57
|
-
params
|
|
57
|
+
// Forward the subscriber's params (e.g. authenticationToken) so token-authenticated clients
|
|
58
|
+
// resolve the same ability they would over HTTP. Without this only session/cookie auth on the
|
|
59
|
+
// upgrade request works, and param-based auth (like a scanner passing an authenticationToken)
|
|
60
|
+
// is dropped — leaving such subscribers with a guest ability and no read rule.
|
|
61
|
+
params: { ...this.params, model: modelName },
|
|
58
62
|
request: /**
|
|
59
63
|
* Narrows the runtime value to the documented type.
|
|
60
64
|
@type {import("../http-server/client/request.js").default} */ (this._syntheticRequest()),
|
|
@@ -101,6 +105,14 @@ export default class FrontendModelWebsocketChannel extends VelociousWebsocketCha
|
|
|
101
105
|
async _deliverBroadcast(body, meta) {
|
|
102
106
|
const hasEventFilters = this._hasEventFilterParams();
|
|
103
107
|
if (!this._hasProjectionParams() && !hasEventFilters) {
|
|
108
|
+
// Even unfiltered subscriptions must respect the subscriber's ability. A create/update carries
|
|
109
|
+
// the record, so only deliver it when the record is within the authenticated ability's scope.
|
|
110
|
+
// Destroys (and bodies without a usable id) carry no record, so pass them through unchanged.
|
|
111
|
+
if (body && typeof body === "object" && (body.action === "create" || body.action === "update") && body.id !== undefined && body.id !== null) {
|
|
112
|
+
const FrontendModelController = await this._frontendModelControllerClass();
|
|
113
|
+
if (!await this._eventIsAccessible(body.id, FrontendModelController))
|
|
114
|
+
return;
|
|
115
|
+
}
|
|
104
116
|
this.sendMessage(body, meta);
|
|
105
117
|
return;
|
|
106
118
|
}
|
|
@@ -301,6 +313,21 @@ export default class FrontendModelWebsocketChannel extends VelociousWebsocketCha
|
|
|
301
313
|
controller._frontendModelAbilityOverride = this._ability || undefined;
|
|
302
314
|
return controller;
|
|
303
315
|
}
|
|
316
|
+
/**
|
|
317
|
+
* Whether the broadcast record is within the subscriber's authenticated ability scope. Used to gate
|
|
318
|
+
* unfiltered/unprojected create/update delivery so a scoped token never receives a record it cannot read.
|
|
319
|
+
* @param {string | number} id - Event record id.
|
|
320
|
+
* @param {typeof import("../frontend-model-controller.js").default} FrontendModelController - Server-side frontend-model controller class.
|
|
321
|
+
* @returns {Promise<boolean>} True when the record is readable by this subscription.
|
|
322
|
+
*/
|
|
323
|
+
async _eventIsAccessible(id, FrontendModelController) {
|
|
324
|
+
const controller = this._frontendModelController(FrontendModelController);
|
|
325
|
+
await controller.ensureFrontendModelClassInitialized();
|
|
326
|
+
const ModelClass = controller.frontendModelClass();
|
|
327
|
+
const primaryKey = ModelClass.primaryKey();
|
|
328
|
+
const query = controller.frontendModelAuthorizedQuery("find").where({ [ModelClass.tableName()]: { [primaryKey]: id } });
|
|
329
|
+
return Boolean(await query.first());
|
|
330
|
+
}
|
|
304
331
|
/**
|
|
305
332
|
* Runs matched event filter keys for event id.
|
|
306
333
|
* @param {string | number} id - Event record id.
|
|
@@ -342,7 +369,9 @@ export default class FrontendModelWebsocketChannel extends VelociousWebsocketCha
|
|
|
342
369
|
const primaryKey = ModelClass.primaryKey();
|
|
343
370
|
const where = controller.frontendModelWhere();
|
|
344
371
|
const joins = controller.frontendModelJoins();
|
|
345
|
-
|
|
372
|
+
// Start from the subscriber's authorized scope so a filter can only ever match records the
|
|
373
|
+
// subscription's ability permits to read.
|
|
374
|
+
let query = controller.frontendModelAuthorizedQuery("find").where({ [ModelClass.tableName()]: { [primaryKey]: id } });
|
|
346
375
|
if (where)
|
|
347
376
|
controller.applyFrontendModelWhere({ query, where });
|
|
348
377
|
if (joins)
|
|
@@ -363,7 +392,9 @@ export default class FrontendModelWebsocketChannel extends VelociousWebsocketCha
|
|
|
363
392
|
await controller.ensureFrontendModelClassInitialized();
|
|
364
393
|
const ModelClass = controller.frontendModelClass();
|
|
365
394
|
const primaryKey = ModelClass.primaryKey();
|
|
366
|
-
|
|
395
|
+
// Reload through the subscriber's authorized scope so projected records are only ever sent for
|
|
396
|
+
// rows the subscription's ability permits to read.
|
|
397
|
+
let query = controller.frontendModelAuthorizedQuery("find").where({ [ModelClass.tableName()]: { [primaryKey]: id } });
|
|
367
398
|
const preload = controller.frontendModelPreload();
|
|
368
399
|
if (preload)
|
|
369
400
|
query = query.preload(preload);
|
|
@@ -431,4 +462,4 @@ export default class FrontendModelWebsocketChannel extends VelociousWebsocketCha
|
|
|
431
462
|
};
|
|
432
463
|
}
|
|
433
464
|
}
|
|
434
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LWNoYW5uZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZnJvbnRlbmQtbW9kZWxzL3dlYnNvY2tldC1jaGFubmVsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLHlCQUF5QixNQUFNLHFDQUFxQyxDQUFBO0FBQzNFLE9BQU8sUUFBUSxNQUFNLG1DQUFtQyxDQUFBO0FBQ3hELE9BQU8sRUFBQyxvQ0FBb0MsRUFBQyxNQUFNLDhCQUE4QixDQUFBO0FBRWpGLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFBO0FBRXhFOzs7R0FHRztBQUNIOzs7R0FHRztBQUNIOzs7R0FHRztBQUVIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLDZCQUE4QixTQUFRLHlCQUF5QjtJQUNsRjs7cUVBRWlFO0lBQ2pFLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFFZjs7O09BR0c7SUFDSCxLQUFLLENBQUMsWUFBWTtRQUNoQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUE7UUFFbkMsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLEtBQUssQ0FBQTtRQUM1QixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUE7UUFFcEIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUE7UUFDaEQsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDLGVBQWUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFBO1FBQzVELE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUUxQyxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU8sS0FBSyxDQUFBO1FBRTdCLE1BQU0sT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFDLGNBQWMs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Q0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUMsR0FBRyxRQUFRLEVBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztZQUNwRSxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsa0JBQWtCO1lBQzlCLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNO1lBQ3hCLGFBQWEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxhQUFhO1lBQ2xDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTTtTQUMvQixDQUFBO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBWZWxvY2lvdXNXZWJzb2NrZXRDaGFubmVsIGZyb20gXCIuLi9odHRwLXNlcnZlci93ZWJzb2NrZXQtY2hhbm5lbC5qc1wiXG5pbXBvcnQgUmVzcG9uc2UgZnJvbSBcIi4uL2h0dHAtc2VydmVyL2NsaWVudC9yZXNwb25zZS5qc1wiXG5pbXBvcnQge3NlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZX0gZnJvbSBcIi4vdHJhbnNwb3J0LXNlcmlhbGl6YXRpb24uanNcIlxuXG5jb25zdCBFVkVOVF9GSUxURVJfS0VZUyA9IG5ldyBTZXQoW1wiam9pbnNcIiwgXCJrZXlcIiwgXCJzZWFyY2hlc1wiLCBcIndoZXJlXCJdKVxuXG4vKipcbiAqIERlZmluZXMgdGhpcyB0eXBlZGVmLlxuICogQHR5cGVkZWYge3thY3Rpb24/OiBzdHJpbmcsIGlkPzogc3RyaW5nIHwgbnVtYmVyLCBtYXRjaGVkRXZlbnRGaWx0ZXJLZXlzPzogc3RyaW5nW10sIHJlY29yZD86IGltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlLCBba2V5OiBzdHJpbmddOiBpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkfX0gRnJvbnRlbmRNb2RlbExpZmVjeWNsZUJyb2FkY2FzdEJvZHlcbiAqL1xuLyoqXG4gKiBEZWZpbmVzIHRoaXMgdHlwZWRlZi5cbiAqIEB0eXBlZGVmIHt7aGVhZGVycz86ICgpID0+IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkPiwgcmVtb3RlQWRkcmVzcz86ICgpID0+IHN0cmluZyB8IHVuZGVmaW5lZH19IEZyb250ZW5kTW9kZWxXZWJzb2NrZXRVcGdyYWRlUmVxdWVzdFxuICovXG4vKipcbiAqIERlZmluZXMgdGhpcyB0eXBlZGVmLlxuICogQHR5cGVkZWYge3toZWFkZXJzOiAoKSA9PiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBzdHJpbmdbXSB8IHVuZGVmaW5lZD4sIGhlYWRlcjogKG5hbWU6IHN0cmluZykgPT4gc3RyaW5nIHwgc3RyaW5nW10gfCB1bmRlZmluZWQsIG1ldGFkYXRhOiAoa2V5Pzogc3RyaW5nKSA9PiBSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZT4gfCBpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSB8IHVuZGVmaW5lZCwgcGF0aDogKCkgPT4gc3RyaW5nLCBodHRwTWV0aG9kOiAoKSA9PiBzdHJpbmcsIHJlbW90ZUFkZHJlc3M6ICgpID0+IHN0cmluZyB8IHVuZGVmaW5lZCwgb3JpZ2luOiAoKSA9PiBzdHJpbmcgfCBzdHJpbmdbXSB8IHVuZGVmaW5lZH19IEZyb250ZW5kTW9kZWxXZWJzb2NrZXRTeW50aGV0aWNSZXF1ZXN0XG4gKi9cblxuLyoqXG4gKiBQZXItc2Vzc2lvbiBjaGFubmVsIHN1YnNjcmlwdGlvbiBmb3IgZnJvbnRlbmQtbW9kZWwgbGlmZWN5Y2xlIGV2ZW50cy5cbiAqIFJlcGxhY2VzIHRoZSBsZWdhY3kgYEZyb250ZW5kTW9kZWxXZWJzb2NrZXRDaGFubmVsYCAoUGhhc2UgMykuXG4gKlxuICogQXV0aCBtb2RlbDogc3Vic2NyaWJlLXRpbWUgb25seS4gYGNhblN1YnNjcmliZWAgcmVzb2x2ZXMgdGhlIGNhbGxlcidzXG4gKiBhYmlsaXR5IG9uY2UsIGNoZWNrcyB0aGF0IGF0IGxlYXN0IG9uZSBgYWxsb3dgIHJ1bGUgZXhpc3RzIGZvclxuICogYHJlYWRgIG9uIHRoZSByZXF1ZXN0ZWQgbW9kZWwgY2xhc3MsIGFuZCB0aGVuIGRlbGl2ZXJzIGZ1dHVyZVxuICogbGlmZWN5Y2xlIGJyb2FkY2FzdHMgZm9yIHRoYXQgbW9kZWwgd2l0aG91dCByZS1hdXRob3JpemluZyBwZXIgZXZlbnQuXG4gKiBUaGlzIG1hdGNoZXMgdGhlIGV4cGxpY2l0IGRlc2lnbiBkZWNpc2lvbiBpbiBQaGFzZSAzIHRvIHRyYWRlXG4gKiBwZXItcmVjb3JkIHZpc2liaWxpdHkgZ3VhcmFudGVlcyBmb3IgbWFzc2l2ZWx5IGNoZWFwZXIgYnJvYWRjYXN0IGZhbi1vdXQuXG4gKiBTdWJzY3JpYmVyLXByb3ZpZGVkIGV2ZW50IGZpbHRlcnMgY2FuIHN0aWxsIG5hcnJvdyB3aGljaCBjcmVhdGUvdXBkYXRlXG4gKiBldmVudHMgYXJlIGRlbGl2ZXJlZCwgYnV0IHRoZXkgYXJlIG1hdGNoaW5nIHByZWRpY2F0ZXMgcmF0aGVyIHRoYW5cbiAqIHBlci1yZWNvcmQgYXV0aG9yaXphdGlvbiBjaGVja3MuXG4gKlxuICogV2lyZTogc3Vic2NyaWJlIHdpdGggYHN1YnNjcmliZUNoYW5uZWwoXCJmcm9udGVuZC1tb2RlbHNcIiwge3BhcmFtczoge21vZGVsOiBNb2RlbE5hbWV9fSlgLlxuICogQmFja2VuZCBwdWJsaXNoZXMgYHthY3Rpb24sIGlkLCByZWNvcmR9YCB2aWFcbiAqIGBjb25maWd1cmF0aW9uLmJyb2FkY2FzdFRvQ2hhbm5lbChcImZyb250ZW5kLW1vZGVsc1wiLCB7bW9kZWw6IE1vZGVsTmFtZX0sIGJvZHkpYDtcbiAqIGBtYXRjaGVzKClgIHJvdXRlcyBieSBtb2RlbCBuYW1lLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGcm9udGVuZE1vZGVsV2Vic29ja2V0Q2hhbm5lbCBleHRlbmRzIFZlbG9jaW91c1dlYnNvY2tldENoYW5uZWwge1xuICAvKipcbiAgICogQWJpbGl0eS5cbiAgICBAdHlwZSB7aW1wb3J0KFwiLi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHQgfCBudWxsfSAqL1xuICBfYWJpbGl0eSA9IG51bGxcblxuICAvKipcbiAgICogUnVucyBjYW4gc3Vic2NyaWJlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gV2hldGhlciB0aGUgZnJvbnRlbmQtbW9kZWwgc3Vic2NyaXB0aW9uIGlzIGF1dGhvcml6ZWQuXG4gICAqL1xuICBhc3luYyBjYW5TdWJzY3JpYmUoKSB7XG4gICAgY29uc3QgbW9kZWxOYW1lID0gdGhpcy5fbW9kZWxOYW1lKClcblxuICAgIGlmICghbW9kZWxOYW1lKSByZXR1cm4gZmFsc2VcbiAgICB0aGlzLl9ldmVudEZpbHRlcnMoKVxuXG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9IHRoaXMuc2Vzc2lvbi5jb25maWd1cmF0aW9uXG4gICAgY29uc3QgbW9kZWxDbGFzc2VzID0gY29uZmlndXJhdGlvbi5nZXRNb2RlbENsYXNzZXM/LigpIHx8IHt9XG4gICAgY29uc3QgTW9kZWxDbGFzcyA9IG1vZGVsQ2xhc3Nlc1ttb2RlbE5hbWVdXG5cbiAgICBpZiAoIU1vZGVsQ2xhc3MpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3QgYWJpbGl0eSA9IGF3YWl0IGNvbmZpZ3VyYXRpb24ucmVzb2x2ZUFiaWxpdHk/Lih7XG4gICAgICBwYXJhbXM6IHttb2RlbDogbW9kZWxOYW1lfSxcbiAgICAgIHJlcXVlc3Q6IC8qKlxuICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi4vaHR0cC1zZXJ2ZXIvY2xpZW50L3JlcXVlc3QuanNcIikuZGVmYXVsdH0gKi8gKHRoaXMuX3N5bnRoZXRpY1JlcXVlc3QoKSksXG4gICAgICByZXNwb25zZTogbmV3IFJlc3BvbnNlKHtjb25maWd1cmF0aW9ufSlcbiAgICB9KVxuXG4gICAgaWYgKCFhYmlsaXR5KSByZXR1cm4gZmFsc2VcbiAgICB0aGlzLl9hYmlsaXR5ID0gYWJpbGl0eVxuXG4gICAgLy8gTG9hZCByZXNvdXJjZS1kZWNsYXJlZCBydWxlcyBmb3IgdGhpcyBtb2RlbCBjbGFzcyBiZWZvcmUgY2hlY2tpbmcsXG4gICAgLy8gb3RoZXJ3aXNlIGBydWxlc0ZvcmAgcmV0dXJucyBlbXB0eSBmb3IgYWJpbGl0aWVzIHdob3NlIHJlc291cmNlc1xuICAgIC8vIHJlZ2lzdGVyIHJ1bGVzIGxhemlseSB2aWEgYGFiaWxpdGllcygpYC5cbiAgICBpZiAodHlwZW9mIGFiaWxpdHkubG9hZEFiaWxpdGllc0Zvck1vZGVsQ2xhc3MgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgYWJpbGl0eS5sb2FkQWJpbGl0aWVzRm9yTW9kZWxDbGFzcyhNb2RlbENsYXNzKVxuICAgIH1cblxuICAgIGNvbnN0IHJlYWRSdWxlcyA9IHR5cGVvZiBhYmlsaXR5LnJ1bGVzRm9yID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gYWJpbGl0eS5ydWxlc0Zvcih7YWN0aW9uOiBcInJlYWRcIiwgbW9kZWxDbGFzczogTW9kZWxDbGFzc30pXG4gICAgICA6IFtdXG5cbiAgICByZXR1cm4gcmVhZFJ1bGVzLnNvbWUoKC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7e2VmZmVjdDogc3RyaW5nfX0gKi8gcnVsZSkgPT4gcnVsZS5lZmZlY3QgPT09IFwiYWxsb3dcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGRlbGl2ZXIgYnJvYWRjYXN0LlxuICAgKiBAcGFyYW0ge0Zyb250ZW5kTW9kZWxMaWZlY3ljbGVCcm9hZGNhc3RCb2R5fSBib2R5IC0gQnJvYWRjYXN0IGJvZHkuXG4gICAqIEBwYXJhbSB7e2V2ZW50SWQ/OiBzdHJpbmd9fSBbbWV0YV0gLSBPcHRpb25hbCBldmVudCBtZXRhZGF0YS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFJlc29sdmVzIGFmdGVyIGRlbGl2ZXJ5LlxuICAgKi9cbiAgYXN5bmMgZGVsaXZlckJyb2FkY2FzdChib2R5LCBtZXRhKSB7XG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9IHRoaXMuc2Vzc2lvbi5jb25maWd1cmF0aW9uXG5cbiAgICBpZiAoY29uZmlndXJhdGlvbiAmJiB0eXBlb2YgY29uZmlndXJhdGlvbi5lbnN1cmVDb25uZWN0aW9ucyA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgICBhd2FpdCBjb25maWd1cmF0aW9uLmVuc3VyZUNvbm5lY3Rpb25zKHtuYW1lOiBcIkZyb250ZW5kIG1vZGVsIHdlYnNvY2tldCBicm9hZGNhc3RcIn0sIGFzeW5jICgpID0+IHtcbiAgICAgICAgYXdhaXQgdGhpcy5fZGVsaXZlckJyb2FkY2FzdChib2R5LCBtZXRhKVxuICAgICAgfSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGF3YWl0IHRoaXMuX2RlbGl2ZXJCcm9hZGNhc3QoYm9keSwgbWV0YSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGRlbGl2ZXIgYnJvYWRjYXN0LlxuICAgKiBAcGFyYW0ge0Zyb250ZW5kTW9kZWxMaWZlY3ljbGVCcm9hZGNhc3RCb2R5fSBib2R5IC0gQnJvYWRjYXN0IGJvZHkuXG4gICAqIEBwYXJhbSB7e2V2ZW50SWQ/OiBzdHJpbmd9fSBbbWV0YV0gLSBPcHRpb25hbCBldmVudCBtZXRhZGF0YS5cbiAgICogQHJldHVybnMge1Byb21pc2U8dm9pZD59IFJlc29sdmVzIGFmdGVyIGRlbGl2ZXJ5LlxuICAgKi9cbiAgYXN5bmMgX2RlbGl2ZXJCcm9hZGNhc3QoYm9keSwgbWV0YSkge1xuICAgIGNvbnN0IGhhc0V2ZW50RmlsdGVycyA9IHRoaXMuX2hhc0V2ZW50RmlsdGVyUGFyYW1zKClcblxuICAgIGlmICghdGhpcy5faGFzUHJvamVjdGlvblBhcmFtcygpICYmICFoYXNFdmVudEZpbHRlcnMpIHtcbiAgICAgIHRoaXMuc2VuZE1lc3NhZ2UoYm9keSwgbWV0YSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmICghYm9keSB8fCB0eXBlb2YgYm9keSAhPT0gXCJvYmplY3RcIikge1xuICAgICAgaWYgKCFoYXNFdmVudEZpbHRlcnMgfHwgdGhpcy5faGFzVW5maWx0ZXJlZEV2ZW50RGVsaXZlcnkoKSkgdGhpcy5zZW5kTWVzc2FnZShib2R5LCBtZXRhKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGJvZHkuYWN0aW9uID09PSBcImRlc3Ryb3lcIikge1xuICAgICAgaWYgKCFoYXNFdmVudEZpbHRlcnMgfHwgdGhpcy5faGFzVW5maWx0ZXJlZEV2ZW50RGVsaXZlcnkoKSkgdGhpcy5zZW5kTWVzc2FnZShib2R5LCBtZXRhKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgaWYgKGJvZHkuaWQgPT09IHVuZGVmaW5lZCB8fCBib2R5LmlkID09PSBudWxsKSB7XG4gICAgICBpZiAoIWhhc0V2ZW50RmlsdGVycyB8fCB0aGlzLl9oYXNVbmZpbHRlcmVkRXZlbnREZWxpdmVyeSgpKSB0aGlzLnNlbmRNZXNzYWdlKGJvZHksIG1ldGEpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBjb25zdCBGcm9udGVuZE1vZGVsQ29udHJvbGxlciA9IGF3YWl0IHRoaXMuX2Zyb250ZW5kTW9kZWxDb250cm9sbGVyQ2xhc3MoKVxuICAgIGNvbnN0IG1hdGNoZWRFdmVudEZpbHRlcktleXMgPSBhd2FpdCB0aGlzLl9tYXRjaGVkRXZlbnRGaWx0ZXJLZXlzRm9yRXZlbnRJZChib2R5LmlkLCBGcm9udGVuZE1vZGVsQ29udHJvbGxlcilcblxuICAgIGlmIChoYXNFdmVudEZpbHRlcnMgJiYgbWF0Y2hlZEV2ZW50RmlsdGVyS2V5cy5sZW5ndGggPT09IDAgJiYgIXRoaXMuX2hhc1VuZmlsdGVyZWRFdmVudERlbGl2ZXJ5KCkpIHtcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIERlbGl2ZXIgYm9keS5cbiAgICAgIEB0eXBlIHtGcm9udGVuZE1vZGVsTGlmZWN5Y2xlQnJvYWRjYXN0Qm9keX0gKi9cbiAgICBsZXQgZGVsaXZlckJvZHkgPSBib2R5XG5cbiAgICBpZiAodGhpcy5faGFzUHJvamVjdGlvblBhcmFtcygpKSB7XG4gICAgICBjb25zdCBwcm9qZWN0ZWRSZWNvcmQgPSBhd2FpdCB0aGlzLl9wcm9qZWN0ZWRSZWNvcmRGb3JFdmVudElkKGJvZHkuaWQsIEZyb250ZW5kTW9kZWxDb250cm9sbGVyKVxuXG4gICAgICBpZiAoIXByb2plY3RlZFJlY29yZCkge1xuICAgICAgICByZXR1cm5cbiAgICAgIH1cblxuICAgICAgZGVsaXZlckJvZHkgPSB7XG4gICAgICAgIC4uLmRlbGl2ZXJCb2R5LFxuICAgICAgICByZWNvcmQ6IC8qKlxuICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgIEB0eXBlIHtpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZX0gKi8gKHNlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZShwcm9qZWN0ZWRSZWNvcmQpKVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChoYXNFdmVudEZpbHRlcnMpIHtcbiAgICAgIGRlbGl2ZXJCb2R5ID0ge1xuICAgICAgICAuLi5kZWxpdmVyQm9keSxcbiAgICAgICAgbWF0Y2hlZEV2ZW50RmlsdGVyS2V5c1xuICAgICAgfVxuICAgIH1cblxuICAgIHRoaXMuc2VuZE1lc3NhZ2UoZGVsaXZlckJvZHksIG1ldGEpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBtYXRjaGVzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlPn0gYnJvYWRjYXN0UGFyYW1zIC0gUGFyYW1zIGZyb20gYGJyb2FkY2FzdFRvQ2hhbm5lbGAuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSBXaGV0aGVyIHRoZSBicm9hZGNhc3QgbWF0Y2hlcyB0aGlzIHN1YnNjcmliZXIncyBtb2RlbC5cbiAgICovXG4gIG1hdGNoZXMoYnJvYWRjYXN0UGFyYW1zKSB7XG4gICAgcmV0dXJuIGJyb2FkY2FzdFBhcmFtcz8ubW9kZWwgPT09IHRoaXMuX21vZGVsTmFtZSgpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBkZWJ1ZyBzbmFwc2hvdC5cbiAgICogQHJldHVybnMge1JlY29yZDxzdHJpbmcsID8+fSBEZWJ1Zy1zYWZlIHN1YnNjcmlwdGlvbiBkZXRhaWxzLlxuICAgKi9cbiAgZGVidWdTbmFwc2hvdCgpIHtcbiAgICBjb25zdCBldmVudEZpbHRlcnMgPSB0aGlzLl9ldmVudEZpbHRlcnMoKVxuXG4gICAgcmV0dXJuIHtcbiAgICAgIGFiaWxpdGllczogdGhpcy5wYXJhbXMuYWJpbGl0aWVzICE9PSB1bmRlZmluZWQsXG4gICAgICBldmVudEZpbHRlckNvdW50OiBldmVudEZpbHRlcnMubGVuZ3RoLFxuICAgICAgbW9kZWw6IHRoaXMuX21vZGVsTmFtZSgpLFxuICAgICAgcHJlbG9hZDogdGhpcy5wYXJhbXMucHJlbG9hZCAhPT0gdW5kZWZpbmVkLFxuICAgICAgcXVlcnlEYXRhOiB0aGlzLnBhcmFtcy5xdWVyeURhdGEgIT09IHVuZGVmaW5lZCxcbiAgICAgIHNlbGVjdDogdGhpcy5wYXJhbXMuc2VsZWN0ICE9PSB1bmRlZmluZWQsXG4gICAgICBzZWxlY3RzRXh0cmE6IHRoaXMucGFyYW1zLnNlbGVjdHNFeHRyYSAhPT0gdW5kZWZpbmVkLFxuICAgICAgdW5maWx0ZXJlZEV2ZW50RGVsaXZlcnk6IHRoaXMucGFyYW1zLnVuZmlsdGVyZWRFdmVudERlbGl2ZXJ5ID09PSB0cnVlLFxuICAgICAgd2l0aENvdW50OiB0aGlzLnBhcmFtcy53aXRoQ291bnQgIT09IHVuZGVmaW5lZFxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG1vZGVsIG5hbWUuXG4gICAqIEByZXR1cm5zIHtzdHJpbmcgfCBudWxsfSAtIFJlcXVlc3RlZCBmcm9udGVuZC1tb2RlbCBuYW1lIG9yIG51bGwuXG4gICAqL1xuICBfbW9kZWxOYW1lKCkge1xuICAgIHJldHVybiB0eXBlb2YgdGhpcy5wYXJhbXM/Lm1vZGVsID09PSBcInN0cmluZ1wiICYmIHRoaXMucGFyYW1zLm1vZGVsLmxlbmd0aCA+IDBcbiAgICAgID8gdGhpcy5wYXJhbXMubW9kZWxcbiAgICAgIDogbnVsbFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFzIHByb2plY3Rpb24gcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoaXMgc3Vic2NyaXB0aW9uIHJlcXVlc3RlZCBwZXItZXZlbnQgcmVjb3JkIHByb2plY3Rpb24uXG4gICAqL1xuICBfaGFzUHJvamVjdGlvblBhcmFtcygpIHtcbiAgICByZXR1cm4gdGhpcy5wYXJhbXMuc2VsZWN0ICE9PSB1bmRlZmluZWRcbiAgICAgIHx8IHRoaXMucGFyYW1zLnNlbGVjdHNFeHRyYSAhPT0gdW5kZWZpbmVkXG4gICAgICB8fCB0aGlzLnBhcmFtcy5wcmVsb2FkICE9PSB1bmRlZmluZWRcbiAgICAgIHx8IHRoaXMucGFyYW1zLndpdGhDb3VudCAhPT0gdW5kZWZpbmVkXG4gICAgICB8fCB0aGlzLnBhcmFtcy5hYmlsaXRpZXMgIT09IHVuZGVmaW5lZFxuICAgICAgfHwgdGhpcy5wYXJhbXMucXVlcnlEYXRhICE9PSB1bmRlZmluZWRcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhcyBldmVudCBmaWx0ZXIgcGFyYW1zLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gLSBXaGV0aGVyIHRoaXMgc3Vic2NyaXB0aW9uIHJlcXVlc3RlZCBldmVudCBxdWVyeSBmaWx0ZXJzLlxuICAgKi9cbiAgX2hhc0V2ZW50RmlsdGVyUGFyYW1zKCkge1xuICAgIHJldHVybiB0aGlzLl9ldmVudEZpbHRlcnMoKS5sZW5ndGggPiAwXG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYXMgdW5maWx0ZXJlZCBldmVudCBkZWxpdmVyeS5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB1bmZpbHRlcmVkIGNhbGxiYWNrcyBzaG91bGQgcmVjZWl2ZSBldmVyeSBldmVudC5cbiAgICovXG4gIF9oYXNVbmZpbHRlcmVkRXZlbnREZWxpdmVyeSgpIHtcbiAgICByZXR1cm4gdGhpcy5wYXJhbXMudW5maWx0ZXJlZEV2ZW50RGVsaXZlcnkgPT09IHRydWVcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGV2ZW50IGZpbHRlcnMuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxFdmVudEZpbHRlclBheWxvYWRFbnRyeVtdfSAtIFZhbGlkIGV2ZW50IGZpbHRlcnMuXG4gICAqL1xuICBfZXZlbnRGaWx0ZXJzKCkge1xuICAgIGlmICh0aGlzLnBhcmFtcy5ldmVudEZpbHRlcnMgPT09IHVuZGVmaW5lZCkgcmV0dXJuIFtdXG4gICAgaWYgKCFBcnJheS5pc0FycmF5KHRoaXMucGFyYW1zLmV2ZW50RmlsdGVycykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcIkZyb250ZW5kIG1vZGVsIGV2ZW50RmlsdGVycyBtdXN0IGJlIGFuIGFycmF5XCIpXG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucGFyYW1zLmV2ZW50RmlsdGVycy5tYXAoKGVudHJ5KSA9PiB7XG4gICAgICBpZiAoIWVudHJ5IHx8IHR5cGVvZiBlbnRyeSAhPT0gXCJvYmplY3RcIiB8fCBBcnJheS5pc0FycmF5KGVudHJ5KSkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGcm9udGVuZCBtb2RlbCBldmVudEZpbHRlcnMgZW50cmllcyBtdXN0IGJlIG9iamVjdHNcIilcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXZlbnRGaWx0ZXIgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gKi8gKGVudHJ5KVxuICAgICAgY29uc3QgdW5rbm93bktleXMgPSBPYmplY3Qua2V5cyhldmVudEZpbHRlcikuZmlsdGVyKChrZXkpID0+ICFFVkVOVF9GSUxURVJfS0VZUy5oYXMoa2V5KSlcblxuICAgICAgaWYgKHVua25vd25LZXlzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGcm9udGVuZCBtb2RlbCBldmVudEZpbHRlcnMgZW50cmllcyBjYW5ub3QgaW5jbHVkZSAke3Vua25vd25LZXlzLmpvaW4oXCIsIFwiKX1gKVxuICAgICAgfVxuXG4gICAgICBpZiAodHlwZW9mIGV2ZW50RmlsdGVyLmtleSAhPT0gXCJzdHJpbmdcIiB8fCBldmVudEZpbHRlci5rZXkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcIkZyb250ZW5kIG1vZGVsIGV2ZW50RmlsdGVycyBlbnRyaWVzIHJlcXVpcmUgYSBrZXlcIilcbiAgICAgIH1cblxuICAgICAgLyoqXG4gICAgICAgKiBTYW5pdGl6ZWQgZXZlbnQgZmlsdGVyLlxuICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi9xdWVyeS5qc1wiKS5Gcm9udGVuZE1vZGVsRXZlbnRGaWx0ZXJQYXlsb2FkRW50cnl9ICovXG4gICAgICBjb25zdCBzYW5pdGl6ZWRFdmVudEZpbHRlciA9IHtrZXk6IGV2ZW50RmlsdGVyLmtleX1cblxuICAgICAgaWYgKGV2ZW50RmlsdGVyLmpvaW5zICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgc2FuaXRpemVkRXZlbnRGaWx0ZXIuam9pbnMgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi9xdWVyeS5qc1wiKS5Gcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWU+fSAqLyAoZXZlbnRGaWx0ZXIuam9pbnMpXG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudEZpbHRlci5zZWFyY2hlcyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNhbml0aXplZEV2ZW50RmlsdGVyLnNlYXJjaGVzID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbFNlYXJjaFtdfSAqLyAoZXZlbnRGaWx0ZXIuc2VhcmNoZXMpXG4gICAgICB9XG5cbiAgICAgIGlmIChldmVudEZpbHRlci53aGVyZSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNhbml0aXplZEV2ZW50RmlsdGVyLndoZXJlID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlPn0gKi8gKGV2ZW50RmlsdGVyLndoZXJlKVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gc2FuaXRpemVkRXZlbnRGaWx0ZXJcbiAgICB9KVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZnJvbnRlbmQgbW9kZWwgY29udHJvbGxlciBjbGFzcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8dHlwZW9mIGltcG9ydChcIi4uL2Zyb250ZW5kLW1vZGVsLWNvbnRyb2xsZXIuanNcIikuZGVmYXVsdD59IC0gRnJvbnRlbmQgbW9kZWwgY29udHJvbGxlciBjbGFzcy5cbiAgICovXG4gIGFzeW5jIF9mcm9udGVuZE1vZGVsQ29udHJvbGxlckNsYXNzKCkge1xuICAgIGNvbnN0IGZyb250ZW5kTW9kZWxDb250cm9sbGVyUGF0aCA9IFwiLi4vZnJvbnRlbmQtbW9kZWwtY29udHJvbGxlci5qc1wiXG4gICAgY29uc3Qge2RlZmF1bHQ6IEZyb250ZW5kTW9kZWxDb250cm9sbGVyfSA9IGF3YWl0IGltcG9ydChmcm9udGVuZE1vZGVsQ29udHJvbGxlclBhdGgpXG5cbiAgICByZXR1cm4gRnJvbnRlbmRNb2RlbENvbnRyb2xsZXJcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIGNvbnRyb2xsZXIuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4uL2Zyb250ZW5kLW1vZGVsLWNvbnRyb2xsZXIuanNcIikuZGVmYXVsdH0gRnJvbnRlbmRNb2RlbENvbnRyb2xsZXIgLSBTZXJ2ZXItc2lkZSBmcm9udGVuZC1tb2RlbCBjb250cm9sbGVyIGNsYXNzLlxuICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsID8+fSBbcGFyYW1zXSAtIE9wdGlvbmFsIHBhcmFtcyBvdmVycmlkZS5cbiAgICogQHJldHVybnMge2ltcG9ydChcIi4uL2Zyb250ZW5kLW1vZGVsLWNvbnRyb2xsZXIuanNcIikuZGVmYXVsdH0gLSBTeW50aGV0aWMgY29udHJvbGxlciB1c2VkIGZvciByZXNvdXJjZSBzZXJpYWxpemF0aW9uLlxuICAgKi9cbiAgX2Zyb250ZW5kTW9kZWxDb250cm9sbGVyKEZyb250ZW5kTW9kZWxDb250cm9sbGVyLCBwYXJhbXMgPSB7fSkge1xuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLnNlc3Npb24uY29uZmlndXJhdGlvblxuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSBuZXcgRnJvbnRlbmRNb2RlbENvbnRyb2xsZXIoe1xuICAgICAgYWN0aW9uOiBcIndlYnNvY2tldEV2ZW50XCIsXG4gICAgICBjb25maWd1cmF0aW9uLFxuICAgICAgY29udHJvbGxlcjogXCJmcm9udGVuZC1tb2RlbHNcIixcbiAgICAgIHBhcmFtczoge1xuICAgICAgICBhYmlsaXRpZXM6IHRoaXMucGFyYW1zLmFiaWxpdGllcyxcbiAgICAgICAgam9pbnM6IHRoaXMucGFyYW1zLmpvaW5zLFxuICAgICAgICBtb2RlbDogdGhpcy5fbW9kZWxOYW1lKCksXG4gICAgICAgIHByZWxvYWQ6IHRoaXMucGFyYW1zLnByZWxvYWQsXG4gICAgICAgIHF1ZXJ5RGF0YTogdGhpcy5wYXJhbXMucXVlcnlEYXRhLFxuICAgICAgICBzZWFyY2hlczogdGhpcy5wYXJhbXMuc2VhcmNoZXMsXG4gICAgICAgIHNlbGVjdDogdGhpcy5wYXJhbXMuc2VsZWN0LFxuICAgICAgICBzZWxlY3RzRXh0cmE6IHRoaXMucGFyYW1zLnNlbGVjdHNFeHRyYSxcbiAgICAgICAgd2hlcmU6IHRoaXMucGFyYW1zLndoZXJlLFxuICAgICAgICAuLi5wYXJhbXMsXG4gICAgICAgIHdpdGhDb3VudDogdGhpcy5wYXJhbXMud2l0aENvdW50XG4gICAgICB9LFxuICAgICAgcmVxdWVzdDogLyoqXG4gICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgIEB0eXBlIHtpbXBvcnQoXCIuLi9odHRwLXNlcnZlci9jbGllbnQvcmVxdWVzdC5qc1wiKS5kZWZhdWx0fSAqLyAodGhpcy5fc3ludGhldGljUmVxdWVzdCgpKSxcbiAgICAgIHJlc3BvbnNlOiBuZXcgUmVzcG9uc2Uoe2NvbmZpZ3VyYXRpb259KSxcbiAgICAgIHZpZXdQYXRoOiBcIi9cIlxuICAgIH0pXG5cbiAgICBjb250cm9sbGVyLl9mcm9udGVuZE1vZGVsQWJpbGl0eU92ZXJyaWRlID0gdGhpcy5fYWJpbGl0eSB8fCB1bmRlZmluZWRcblxuICAgIHJldHVybiBjb250cm9sbGVyXG4gIH1cblxuICAvKipcbiAgICogUnVucyBtYXRjaGVkIGV2ZW50IGZpbHRlciBrZXlzIGZvciBldmVudCBpZC5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IGlkIC0gRXZlbnQgcmVjb3JkIGlkLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuLi9mcm9udGVuZC1tb2RlbC1jb250cm9sbGVyLmpzXCIpLmRlZmF1bHR9IEZyb250ZW5kTW9kZWxDb250cm9sbGVyIC0gU2VydmVyLXNpZGUgZnJvbnRlbmQtbW9kZWwgY29udHJvbGxlciBjbGFzcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8c3RyaW5nW10+fSAtIEV2ZW50IGZpbHRlciBrZXlzIG1hdGNoZWQgYnkgdGhlIHJlY29yZC5cbiAgICovXG4gIGFzeW5jIF9tYXRjaGVkRXZlbnRGaWx0ZXJLZXlzRm9yRXZlbnRJZChpZCwgRnJvbnRlbmRNb2RlbENvbnRyb2xsZXIpIHtcbiAgICAvKipcbiAgICAgKiBNYXRjaGVkIGV2ZW50IGZpbHRlciBrZXlzLlxuICAgICAgQHR5cGUge3N0cmluZ1tdfSAqL1xuICAgIGNvbnN0IG1hdGNoZWRFdmVudEZpbHRlcktleXMgPSBbXVxuXG4gICAgZm9yIChjb25zdCBldmVudEZpbHRlciBvZiB0aGlzLl9ldmVudEZpbHRlcnMoKSkge1xuICAgICAgY29uc3QgbWF0Y2hlcyA9IGF3YWl0IHRoaXMuX2V2ZW50TWF0Y2hlc0ZpbHRlcih7XG4gICAgICAgIEZyb250ZW5kTW9kZWxDb250cm9sbGVyLFxuICAgICAgICBldmVudEZpbHRlcixcbiAgICAgICAgaWRcbiAgICAgIH0pXG5cbiAgICAgIGlmIChtYXRjaGVzKSBtYXRjaGVkRXZlbnRGaWx0ZXJLZXlzLnB1c2goZXZlbnRGaWx0ZXIua2V5KVxuICAgIH1cblxuICAgIHJldHVybiBtYXRjaGVkRXZlbnRGaWx0ZXJLZXlzXG4gIH1cblxuICAvKipcbiAgICogUnVucyBldmVudCBtYXRjaGVzIGZpbHRlci5cbiAgICogQHBhcmFtIHtvYmplY3R9IGFyZ3MgLSBGaWx0ZXIgYXJncy5cbiAgICogQHBhcmFtIHt0eXBlb2YgaW1wb3J0KFwiLi4vZnJvbnRlbmQtbW9kZWwtY29udHJvbGxlci5qc1wiKS5kZWZhdWx0fSBhcmdzLkZyb250ZW5kTW9kZWxDb250cm9sbGVyIC0gU2VydmVyLXNpZGUgZnJvbnRlbmQtbW9kZWwgY29udHJvbGxlciBjbGFzcy5cbiAgICogQHBhcmFtIHtpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxFdmVudEZpbHRlclBheWxvYWRFbnRyeX0gYXJncy5ldmVudEZpbHRlciAtIEV2ZW50IGZpbHRlciBwYXlsb2FkLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlcn0gYXJncy5pZCAtIEV2ZW50IHJlY29yZCBpZC5cbiAgICogQHJldHVybnMge1Byb21pc2U8Ym9vbGVhbj59IFdoZXRoZXIgdGhlIHJlY29yZCBtYXRjaGVzIHRoZSBmaWx0ZXIuXG4gICAqL1xuICBhc3luYyBfZXZlbnRNYXRjaGVzRmlsdGVyKHtGcm9udGVuZE1vZGVsQ29udHJvbGxlciwgZXZlbnRGaWx0ZXIsIGlkfSkge1xuICAgIGNvbnN0IGNvbnRyb2xsZXIgPSB0aGlzLl9mcm9udGVuZE1vZGVsQ29udHJvbGxlcihGcm9udGVuZE1vZGVsQ29udHJvbGxlciwge1xuICAgICAgam9pbnM6IGV2ZW50RmlsdGVyLmpvaW5zLFxuICAgICAgc2VhcmNoZXM6IGV2ZW50RmlsdGVyLnNlYXJjaGVzLFxuICAgICAgd2hlcmU6IGV2ZW50RmlsdGVyLndoZXJlXG4gICAgfSlcblxuICAgIGF3YWl0IGNvbnRyb2xsZXIuZW5zdXJlRnJvbnRlbmRNb2RlbENsYXNzSW5pdGlhbGl6ZWQoKVxuXG4gICAgY29uc3QgTW9kZWxDbGFzcyA9IGNvbnRyb2xsZXIuZnJvbnRlbmRNb2RlbENsYXNzKClcbiAgICBjb25zdCBwcmltYXJ5S2V5ID0gTW9kZWxDbGFzcy5wcmltYXJ5S2V5KClcbiAgICBjb25zdCB3aGVyZSA9IGNvbnRyb2xsZXIuZnJvbnRlbmRNb2RlbFdoZXJlKClcbiAgICBjb25zdCBqb2lucyA9IGNvbnRyb2xsZXIuZnJvbnRlbmRNb2RlbEpvaW5zKClcbiAgICBsZXQgcXVlcnkgPSBNb2RlbENsYXNzLndoZXJlKHtbTW9kZWxDbGFzcy50YWJsZU5hbWUoKV06IHtbcHJpbWFyeUtleV06IGlkfX0pXG5cbiAgICBpZiAod2hlcmUpIGNvbnRyb2xsZXIuYXBwbHlGcm9udGVuZE1vZGVsV2hlcmUoe3F1ZXJ5LCB3aGVyZX0pXG4gICAgaWYgKGpvaW5zKSBjb250cm9sbGVyLmFwcGx5RnJvbnRlbmRNb2RlbEpvaW5zKHtqb2lucywgcXVlcnl9KVxuXG4gICAgZm9yIChjb25zdCBzZWFyY2ggb2YgY29udHJvbGxlci5mcm9udGVuZE1vZGVsU2VhcmNoZXMoKSkge1xuICAgICAgY29udHJvbGxlci5hcHBseUZyb250ZW5kTW9kZWxTZWFyY2goe3F1ZXJ5LCBzZWFyY2h9KVxuICAgIH1cblxuICAgIHJldHVybiBCb29sZWFuKGF3YWl0IHF1ZXJ5LmZpcnN0KCkpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBwcm9qZWN0ZWQgcmVjb3JkIGZvciBldmVudCBpZC5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IGlkIC0gRXZlbnQgcmVjb3JkIGlkLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuLi9mcm9udGVuZC1tb2RlbC1jb250cm9sbGVyLmpzXCIpLmRlZmF1bHR9IEZyb250ZW5kTW9kZWxDb250cm9sbGVyIC0gU2VydmVyLXNpZGUgZnJvbnRlbmQtbW9kZWwgY29udHJvbGxlciBjbGFzcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi9xdWVyeS5qc1wiKS5Gcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWU+IHwgbnVsbD59IC0gU2VyaWFsaXplZCBwcm9qZWN0ZWQgcmVjb3JkLlxuICAgKi9cbiAgYXN5bmMgX3Byb2plY3RlZFJlY29yZEZvckV2ZW50SWQoaWQsIEZyb250ZW5kTW9kZWxDb250cm9sbGVyKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IHRoaXMuX2Zyb250ZW5kTW9kZWxDb250cm9sbGVyKEZyb250ZW5kTW9kZWxDb250cm9sbGVyKVxuXG4gICAgYXdhaXQgY29udHJvbGxlci5lbnN1cmVGcm9udGVuZE1vZGVsQ2xhc3NJbml0aWFsaXplZCgpXG5cbiAgICBjb25zdCBNb2RlbENsYXNzID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSBNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIGxldCBxdWVyeSA9IE1vZGVsQ2xhc3Mud2hlcmUoe1tNb2RlbENsYXNzLnRhYmxlTmFtZSgpXToge1twcmltYXJ5S2V5XTogaWR9fSlcbiAgICBjb25zdCBwcmVsb2FkID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsUHJlbG9hZCgpXG5cbiAgICBpZiAocHJlbG9hZCkgcXVlcnkgPSBxdWVyeS5wcmVsb2FkKHByZWxvYWQpXG5cbiAgICBmb3IgKGNvbnN0IGVudHJ5IG9mIGNvbnRyb2xsZXIuZnJvbnRlbmRNb2RlbFdpdGhDb3VudCgpKSB7XG4gICAgICAvKipcbiAgICAgICAqIFNwZWMuXG4gICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBib29sZWFuIHwge3JlbGF0aW9uc2hpcD86IHN0cmluZywgd2hlcmU/OiBSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZT59Pn0gKi9cbiAgICAgIGNvbnN0IHNwZWMgPSB7fVxuXG4gICAgICBzcGVjW2VudHJ5LmF0dHJpYnV0ZU5hbWVdID0ge1xuICAgICAgICByZWxhdGlvbnNoaXA6IGVudHJ5LnJlbGF0aW9uc2hpcE5hbWUsXG4gICAgICAgIHdoZXJlOiBlbnRyeS53aGVyZSA/IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlPn0gKi8gKGVudHJ5LndoZXJlKSA6IHVuZGVmaW5lZFxuICAgICAgfVxuICAgICAgcXVlcnkud2l0aENvdW50KHNwZWMpXG4gICAgfVxuXG4gICAgY29uc3QgcXVlcnlEYXRhID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsUXVlcnlEYXRhKClcblxuICAgIGlmIChxdWVyeURhdGEgIT09IG51bGwpIHF1ZXJ5LnF1ZXJ5RGF0YShxdWVyeURhdGEpXG5cbiAgICBxdWVyeSA9IGNvbnRyb2xsZXIuYXBwbHlGcm9udGVuZE1vZGVsVHJhbnNsYXRlZEF0dHJpYnV0ZVByZWxvYWRzKHtxdWVyeX0pXG5cbiAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHF1ZXJ5LmZpcnN0KClcblxuICAgIGlmICghbW9kZWwpIHJldHVybiBudWxsXG5cbiAgICBpZiAodGhpcy5wYXJhbXMuYWJpbGl0aWVzICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGF3YWl0IGNvbnRyb2xsZXIuZnJvbnRlbmRNb2RlbENvbXB1dGVBYmlsaXRpZXMoW21vZGVsXSlcbiAgICB9XG5cbiAgICBjb250cm9sbGVyLl9mcm9udGVuZE1vZGVsQWJpbGl0eU92ZXJyaWRlID0gdW5kZWZpbmVkXG5cbiAgICByZXR1cm4gYXdhaXQgY29udHJvbGxlci5mcm9udGVuZE1vZGVsUmVzb3VyY2VJbnN0YW5jZSgpLnNlcmlhbGl6ZShtb2RlbCwgXCJmaW5kXCIpXG4gIH1cblxuICAvKipcbiAgICogTWluaW1hbCBSZXF1ZXN0LWxpa2Ugc3R1YiB1c2VkIG9ubHkgZm9yIGFiaWxpdHkgcmVzb2x1dGlvbi4gQXZvaWRzXG4gICAqIGltcG9ydGluZyBgV2Vic29ja2V0UmVxdWVzdGAgaGVyZSBiZWNhdXNlIGl0cyBgbm9kZTpxdWVyeXN0cmluZ2BcbiAgICogZGVwZW5kZW5jeSB3b3VsZCBwdWxsIHNlcnZlci1vbmx5IGNvZGUgaW50byBicm93c2VyIGJ1bmRsZXMgdmlhXG4gICAqIHRoZSBgY29uZmlndXJhdGlvbiDihpIgbG9nZ2VyIOKGkiB3ZWJzb2NrZXQtcHVibGlzaGVyc2AgaW1wb3J0IGNoYWluLlxuICAgKiBIZWFkZXIgbmFtZXMgYXJlIG5vcm1hbGl6ZWQgdG8gbG93ZXJjYXNlIHNvIGBoZWFkZXIoXCJjb29raWVcIilgXG4gICAqIGZpbmRzIGEgdmFsdWUgcmVnYXJkbGVzcyBvZiB3aGV0aGVyIHRoZSB1cGdyYWRlLXJlcXVlc3QgaGVhZGVyc1xuICAgKiBtYXAgdXNlcyBgXCJDb29raWVcImAgb3IgYFwiY29va2llXCJgLiBTZXNzaW9uIG1ldGFkYXRhIHN0YXlzIHNlcGFyYXRlXG4gICAqIGZyb20gaGVhZGVycyBhbmQgaXMgZXhwb3NlZCB0aHJvdWdoIGBtZXRhZGF0YSguLi4pYCBmb3IgYWJpbGl0eVxuICAgKiByZXNvbHZlcnMgdGhhdCBuZWVkIHdlYnNvY2tldC1kZWxpdmVyZWQgc2Vzc2lvbiBkYXRhLlxuICAgKiBAcmV0dXJucyB7RnJvbnRlbmRNb2RlbFdlYnNvY2tldFN5bnRoZXRpY1JlcXVlc3R9IFJlcXVlc3QtbGlrZSBvYmplY3QgZm9yIGFiaWxpdHkgcmVzb2x1dGlvbi5cbiAgICovXG4gIF9zeW50aGV0aWNSZXF1ZXN0KCkge1xuICAgIGNvbnN0IHVwZ3JhZGVSZXF1ZXN0ID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtGcm9udGVuZE1vZGVsV2Vic29ja2V0VXBncmFkZVJlcXVlc3R9ICovICh0aGlzLnNlc3Npb24udXBncmFkZVJlcXVlc3QpXG4gICAgY29uc3QgcmF3SGVhZGVycyA9IHR5cGVvZiB1cGdyYWRlUmVxdWVzdD8uaGVhZGVycyA9PT0gXCJmdW5jdGlvblwiID8gdXBncmFkZVJlcXVlc3QuaGVhZGVycygpIDoge31cbiAgICBjb25zdCBtZXRhZGF0YSA9IHR5cGVvZiB0aGlzLnNlc3Npb24uZ2V0TWV0YWRhdGEgPT09IFwiZnVuY3Rpb25cIiA/IHRoaXMuc2Vzc2lvbi5nZXRNZXRhZGF0YSgpIDoge31cbiAgICBjb25zdCByZW1vdGVBZGRyZXNzID0gdHlwZW9mIHVwZ3JhZGVSZXF1ZXN0Py5yZW1vdGVBZGRyZXNzID09PSBcImZ1bmN0aW9uXCIgPyB1cGdyYWRlUmVxdWVzdC5yZW1vdGVBZGRyZXNzKCkgOiB1bmRlZmluZWRcbiAgICAvKipcbiAgICAgKiBIZWFkZXIgbWFwLlxuICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsIHN0cmluZyB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkPn0gKi9cbiAgICBjb25zdCBoZWFkZXJNYXAgPSB7fVxuXG4gICAgZm9yIChjb25zdCBrZXkgb2YgT2JqZWN0LmtleXMocmF3SGVhZGVycyB8fCB7fSkpIHtcbiAgICAgIGhlYWRlck1hcFtrZXkudG9Mb3dlckNhc2UoKV0gPSByYXdIZWFkZXJzW2tleV1cbiAgICB9XG5cbiAgICByZXR1cm4ge1xuICAgICAgaGVhZGVyczogKCkgPT4gaGVhZGVyTWFwLFxuICAgICAgaGVhZGVyOiAobmFtZSkgPT4gaGVhZGVyTWFwW1N0cmluZyhuYW1lKS50b0xvd2VyQ2FzZSgpXSxcbiAgICAgIG1ldGFkYXRhOiAoa2V5KSA9PiBrZXkgPT09IHVuZGVmaW5lZCA/IHsuLi5tZXRhZGF0YX0gOiBtZXRhZGF0YVtrZXldLFxuICAgICAgcGF0aDogKCkgPT4gXCIvZnJvbnRlbmQtbW9kZWxzXCIsXG4gICAgICBodHRwTWV0aG9kOiAoKSA9PiBcIlBPU1RcIixcbiAgICAgIHJlbW90ZUFkZHJlc3M6ICgpID0+IHJlbW90ZUFkZHJlc3MsXG4gICAgICBvcmlnaW46ICgpID0+IGhlYWRlck1hcC5vcmlnaW5cbiAgICB9XG4gIH1cbn1cbiJdfQ==
|
|
465
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoid2Vic29ja2V0LWNoYW5uZWwuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvZnJvbnRlbmQtbW9kZWxzL3dlYnNvY2tldC1jaGFubmVsLmpzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLFlBQVk7QUFFWixPQUFPLHlCQUF5QixNQUFNLHFDQUFxQyxDQUFBO0FBQzNFLE9BQU8sUUFBUSxNQUFNLG1DQUFtQyxDQUFBO0FBQ3hELE9BQU8sRUFBQyxvQ0FBb0MsRUFBQyxNQUFNLDhCQUE4QixDQUFBO0FBRWpGLE1BQU0saUJBQWlCLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxPQUFPLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBRSxPQUFPLENBQUMsQ0FBQyxDQUFBO0FBRXhFOzs7R0FHRztBQUNIOzs7R0FHRztBQUNIOzs7R0FHRztBQUVIOzs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FrQkc7QUFDSCxNQUFNLENBQUMsT0FBTyxPQUFPLDZCQUE4QixTQUFRLHlCQUF5QjtJQUNsRjs7cUVBRWlFO0lBQ2pFLFFBQVEsR0FBRyxJQUFJLENBQUE7SUFFZjs7O09BR0c7SUFDSCxLQUFLLENBQUMsWUFBWTtRQUNoQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUE7UUFFbkMsSUFBSSxDQUFDLFNBQVM7WUFBRSxPQUFPLEtBQUssQ0FBQTtRQUM1QixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUE7UUFFcEIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUE7UUFDaEQsTUFBTSxZQUFZLEdBQUcsYUFBYSxDQUFDLGVBQWUsRUFBRSxFQUFFLElBQUksRUFBRSxDQUFBO1FBQzVELE1BQU0sVUFBVSxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUUxQyxJQUFJLENBQUMsVUFBVTtZQUFFLE9BQU8sS0FBSyxDQUFBO1FBRTdCLE1BQU0sT0FBTyxHQUFHLE1BQU0sYUFBYSxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ25ELDRGQUE0RjtZQUM1Riw4RkFBOEY7WUFDOUYsOEZBQThGO1lBQzlGLCtFQUErRTtZQUMvRSxNQUFNLEVBQUUsRUFBQyxHQUFHLElBQUksQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBQztZQUMxQyxPQUFPLEVBQUU7O29GQUUrRCxDQUFDLENBQUMsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUM7WUFDbkcsUUFBUSxFQUFFLElBQUksUUFBUSxDQUFDLEVBQUMsYUFBYSxFQUFDLENBQUM7U0FDeEMsQ0FBQyxDQUFBO1FBRUYsSUFBSSxDQUFDLE9BQU87WUFBRSxPQUFPLEtBQUssQ0FBQTtRQUMxQixJQUFJLENBQUMsUUFBUSxHQUFHLE9BQU8sQ0FBQTtRQUV2QixxRUFBcUU7UUFDckUsbUVBQW1FO1FBQ25FLDJDQUEyQztRQUMzQyxJQUFJLE9BQU8sT0FBTyxDQUFDLDBCQUEwQixLQUFLLFVBQVUsRUFBRSxDQUFDO1lBQzdELE9BQU8sQ0FBQywwQkFBMEIsQ0FBQyxVQUFVLENBQUMsQ0FBQTtRQUNoRCxDQUFDO1FBRUQsTUFBTSxTQUFTLEdBQUcsT0FBTyxPQUFPLENBQUMsUUFBUSxLQUFLLFVBQVU7WUFDdEQsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBQyxNQUFNLEVBQUUsTUFBTSxFQUFFLFVBQVUsRUFBRSxVQUFVLEVBQUMsQ0FBQztZQUM1RCxDQUFDLENBQUMsRUFBRSxDQUFBO1FBRU4sT0FBTyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7OzREQUU2QixDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE1BQU0sS0FBSyxPQUFPLENBQUMsQ0FBQTtJQUN4RixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLElBQUk7UUFDL0IsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxhQUFhLENBQUE7UUFFaEQsSUFBSSxhQUFhLElBQUksT0FBTyxhQUFhLENBQUMsaUJBQWlCLEtBQUssVUFBVSxFQUFFLENBQUM7WUFDM0UsTUFBTSxhQUFhLENBQUMsaUJBQWlCLENBQUMsRUFBQyxJQUFJLEVBQUUsb0NBQW9DLEVBQUMsRUFBRSxLQUFLLElBQUksRUFBRTtnQkFDN0YsTUFBTSxJQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFBO1lBQzFDLENBQUMsQ0FBQyxDQUFBO1lBQ0YsT0FBTTtRQUNSLENBQUM7UUFFRCxNQUFNLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUE7SUFDMUMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLGlCQUFpQixDQUFDLElBQUksRUFBRSxJQUFJO1FBQ2hDLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxxQkFBcUIsRUFBRSxDQUFBO1FBRXBELElBQUksQ0FBQyxJQUFJLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3JELCtGQUErRjtZQUMvRiw4RkFBOEY7WUFDOUYsNkZBQTZGO1lBQzdGLElBQUksSUFBSSxJQUFJLE9BQU8sSUFBSSxLQUFLLFFBQVEsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEtBQUssUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssUUFBUSxDQUFDLElBQUksSUFBSSxDQUFDLEVBQUUsS0FBSyxTQUFTLElBQUksSUFBSSxDQUFDLEVBQUUsS0FBSyxJQUFJLEVBQUUsQ0FBQztnQkFDNUksTUFBTSx1QkFBdUIsR0FBRyxNQUFNLElBQUksQ0FBQyw2QkFBNkIsRUFBRSxDQUFBO2dCQUUxRSxJQUFJLENBQUMsTUFBTSxJQUFJLENBQUMsa0JBQWtCLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSx1QkFBdUIsQ0FBQztvQkFBRSxPQUFNO1lBQzlFLENBQUM7WUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQTtZQUM1QixPQUFNO1FBQ1IsQ0FBQztRQUVELElBQUksQ0FBQyxJQUFJLElBQUksT0FBTyxJQUFJLEtBQUssUUFBUSxFQUFFLENBQUM7WUFDdEMsSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsMkJBQTJCLEVBQUU7Z0JBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDeEYsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsMkJBQTJCLEVBQUU7Z0JBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDeEYsT0FBTTtRQUNSLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxFQUFFLEtBQUssU0FBUyxJQUFJLElBQUksQ0FBQyxFQUFFLEtBQUssSUFBSSxFQUFFLENBQUM7WUFDOUMsSUFBSSxDQUFDLGVBQWUsSUFBSSxJQUFJLENBQUMsMkJBQTJCLEVBQUU7Z0JBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUE7WUFDeEYsT0FBTTtRQUNSLENBQUM7UUFFRCxNQUFNLHVCQUF1QixHQUFHLE1BQU0sSUFBSSxDQUFDLDZCQUE2QixFQUFFLENBQUE7UUFDMUUsTUFBTSxzQkFBc0IsR0FBRyxNQUFNLElBQUksQ0FBQyxpQ0FBaUMsQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUFFLHVCQUF1QixDQUFDLENBQUE7UUFFN0csSUFBSSxlQUFlLElBQUksc0JBQXNCLENBQUMsTUFBTSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQywyQkFBMkIsRUFBRSxFQUFFLENBQUM7WUFDbEcsT0FBTTtRQUNSLENBQUM7UUFFRDs7d0RBRWdEO1FBQ2hELElBQUksV0FBVyxHQUFHLElBQUksQ0FBQTtRQUV0QixJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRSxFQUFFLENBQUM7WUFDaEMsTUFBTSxlQUFlLEdBQUcsTUFBTSxJQUFJLENBQUMsMEJBQTBCLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSx1QkFBdUIsQ0FBQyxDQUFBO1lBRS9GLElBQUksQ0FBQyxlQUFlLEVBQUUsQ0FBQztnQkFDckIsT0FBTTtZQUNSLENBQUM7WUFFRCxXQUFXLEdBQUc7Z0JBQ1osR0FBRyxXQUFXO2dCQUNkLE1BQU0sRUFBRTs7cUZBRTZELENBQUMsQ0FBQyxvQ0FBb0MsQ0FBQyxlQUFlLENBQUMsQ0FBQzthQUM5SCxDQUFBO1FBQ0gsQ0FBQztRQUVELElBQUksZUFBZSxFQUFFLENBQUM7WUFDcEIsV0FBVyxHQUFHO2dCQUNaLEdBQUcsV0FBVztnQkFDZCxzQkFBc0I7YUFDdkIsQ0FBQTtRQUNILENBQUM7UUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsQ0FBQTtJQUNyQyxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNILE9BQU8sQ0FBQyxlQUFlO1FBQ3JCLE9BQU8sZUFBZSxFQUFFLEtBQUssS0FBSyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUE7SUFDckQsQ0FBQztJQUVEOzs7T0FHRztJQUNILGFBQWE7UUFDWCxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUE7UUFFekMsT0FBTztZQUNMLFNBQVMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsS0FBSyxTQUFTO1lBQzlDLGdCQUFnQixFQUFFLFlBQVksQ0FBQyxNQUFNO1lBQ3JDLEtBQUssRUFBRSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ3hCLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sS0FBSyxTQUFTO1lBQzFDLFNBQVMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsS0FBSyxTQUFTO1lBQzlDLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxTQUFTO1lBQ3hDLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksS0FBSyxTQUFTO1lBQ3BELHVCQUF1QixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsdUJBQXVCLEtBQUssSUFBSTtZQUNyRSxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEtBQUssU0FBUztTQUMvQyxDQUFBO0lBQ0gsQ0FBQztJQUVEOzs7T0FHRztJQUNILFVBQVU7UUFDUixPQUFPLE9BQU8sSUFBSSxDQUFDLE1BQU0sRUFBRSxLQUFLLEtBQUssUUFBUSxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQzNFLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUs7WUFDbkIsQ0FBQyxDQUFDLElBQUksQ0FBQTtJQUNWLENBQUM7SUFFRDs7O09BR0c7SUFDSCxvQkFBb0I7UUFDbEIsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sS0FBSyxTQUFTO2VBQ2xDLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxLQUFLLFNBQVM7ZUFDdEMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLEtBQUssU0FBUztlQUNqQyxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsS0FBSyxTQUFTO2VBQ25DLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxLQUFLLFNBQVM7ZUFDbkMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEtBQUssU0FBUyxDQUFBO0lBQzFDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxxQkFBcUI7UUFDbkIsT0FBTyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQTtJQUN4QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsMkJBQTJCO1FBQ3pCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyx1QkFBdUIsS0FBSyxJQUFJLENBQUE7SUFDckQsQ0FBQztJQUVEOzs7T0FHRztJQUNILGFBQWE7UUFDWCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxLQUFLLFNBQVM7WUFBRSxPQUFPLEVBQUUsQ0FBQTtRQUNyRCxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVksQ0FBQyxFQUFFLENBQUM7WUFDN0MsTUFBTSxJQUFJLEtBQUssQ0FBQyw4Q0FBOEMsQ0FBQyxDQUFBO1FBQ2pFLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxNQUFNLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQzVDLElBQUksQ0FBQyxLQUFLLElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztnQkFDaEUsTUFBTSxJQUFJLEtBQUssQ0FBQyxxREFBcUQsQ0FBQyxDQUFBO1lBQ3hFLENBQUM7WUFFRCxNQUFNLFdBQVcsR0FBRzs7OERBRThCLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQTtZQUMxRCxNQUFNLFdBQVcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQyxpQkFBaUIsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQTtZQUV6RixJQUFJLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQzNCLE1BQU0sSUFBSSxLQUFLLENBQUMsc0RBQXNELFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFBO1lBQ2pHLENBQUM7WUFFRCxJQUFJLE9BQU8sV0FBVyxDQUFDLEdBQUcsS0FBSyxRQUFRLElBQUksV0FBVyxDQUFDLEdBQUcsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3hFLE1BQU0sSUFBSSxLQUFLLENBQUMsbURBQW1ELENBQUMsQ0FBQTtZQUN0RSxDQUFDO1lBRUQ7O2tGQUVzRTtZQUN0RSxNQUFNLG9CQUFvQixHQUFHLEVBQUMsR0FBRyxFQUFFLFdBQVcsQ0FBQyxHQUFHLEVBQUMsQ0FBQTtZQUVuRCxJQUFJLFdBQVcsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3BDLG9CQUFvQixDQUFDLEtBQUssR0FBRzs7MEhBRTZFO29CQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ2hJLENBQUM7WUFFRCxJQUFJLFdBQVcsQ0FBQyxRQUFRLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3ZDLG9CQUFvQixDQUFDLFFBQVEsR0FBRzs7dUdBRXVEO29CQUFDLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFBO1lBQ2hILENBQUM7WUFFRCxJQUFJLFdBQVcsQ0FBQyxLQUFLLEtBQUssU0FBUyxFQUFFLENBQUM7Z0JBQ3BDLG9CQUFvQixDQUFDLEtBQUssR0FBRzs7MEhBRTZFO29CQUFDLENBQUMsV0FBVyxDQUFDLEtBQUssQ0FBQyxDQUFBO1lBQ2hJLENBQUM7WUFFRCxPQUFPLG9CQUFvQixDQUFBO1FBQzdCLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztJQUVEOzs7T0FHRztJQUNILEtBQUssQ0FBQyw2QkFBNkI7UUFDakMsTUFBTSwyQkFBMkIsR0FBRyxpQ0FBaUMsQ0FBQTtRQUNyRSxNQUFNLEVBQUMsT0FBTyxFQUFFLHVCQUF1QixFQUFDLEdBQUcsTUFBTSxNQUFNLENBQUMsMkJBQTJCLENBQUMsQ0FBQTtRQUVwRixPQUFPLHVCQUF1QixDQUFBO0lBQ2hDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILHdCQUF3QixDQUFDLHVCQUF1QixFQUFFLE1BQU0sR0FBRyxFQUFFO1FBQzNELE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFBO1FBQ2hELE1BQU0sVUFBVSxHQUFHLElBQUksdUJBQXVCLENBQUM7WUFDN0MsTUFBTSxFQUFFLGdCQUFnQjtZQUN4QixhQUFhO1lBQ2IsVUFBVSxFQUFFLGlCQUFpQjtZQUM3QixNQUFNLEVBQUU7Z0JBQ04sU0FBUyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUztnQkFDaEMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsS0FBSztnQkFDeEIsS0FBSyxFQUFFLElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ3hCLE9BQU8sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU87Z0JBQzVCLFNBQVMsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVM7Z0JBQ2hDLFFBQVEsRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFFBQVE7Z0JBQzlCLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU07Z0JBQzFCLFlBQVksRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLFlBQVk7Z0JBQ3RDLEtBQUssRUFBRSxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUs7Z0JBQ3hCLEdBQUcsTUFBTTtnQkFDVCxTQUFTLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTO2FBQ2pDO1lBQ0QsT0FBTyxFQUFFOztvRkFFK0QsQ0FBQyxDQUFDLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDO1lBQ25HLFFBQVEsRUFBRSxJQUFJLFFBQVEsQ0FBQyxFQUFDLGFBQWEsRUFBQyxDQUFDO1lBQ3ZDLFFBQVEsRUFBRSxHQUFHO1NBQ2QsQ0FBQyxDQUFBO1FBRUYsVUFBVSxDQUFDLDZCQUE2QixHQUFHLElBQUksQ0FBQyxRQUFRLElBQUksU0FBUyxDQUFBO1FBRXJFLE9BQU8sVUFBVSxDQUFBO0lBQ25CLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxLQUFLLENBQUMsa0JBQWtCLENBQUMsRUFBRSxFQUFFLHVCQUF1QjtRQUNsRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMsdUJBQXVCLENBQUMsQ0FBQTtRQUV6RSxNQUFNLFVBQVUsQ0FBQyxtQ0FBbUMsRUFBRSxDQUFBO1FBRXRELE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO1FBQ2xELE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUMxQyxNQUFNLEtBQUssR0FBRyxVQUFVLENBQUMsNEJBQTRCLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFDLEVBQUMsQ0FBQyxDQUFBO1FBRW5ILE9BQU8sT0FBTyxDQUFDLE1BQU0sS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUE7SUFDckMsQ0FBQztJQUVEOzs7OztPQUtHO0lBQ0gsS0FBSyxDQUFDLGlDQUFpQyxDQUFDLEVBQUUsRUFBRSx1QkFBdUI7UUFDakU7OzZCQUVxQjtRQUNyQixNQUFNLHNCQUFzQixHQUFHLEVBQUUsQ0FBQTtRQUVqQyxLQUFLLE1BQU0sV0FBVyxJQUFJLElBQUksQ0FBQyxhQUFhLEVBQUUsRUFBRSxDQUFDO1lBQy9DLE1BQU0sT0FBTyxHQUFHLE1BQU0sSUFBSSxDQUFDLG1CQUFtQixDQUFDO2dCQUM3Qyx1QkFBdUI7Z0JBQ3ZCLFdBQVc7Z0JBQ1gsRUFBRTthQUNILENBQUMsQ0FBQTtZQUVGLElBQUksT0FBTztnQkFBRSxzQkFBc0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLEdBQUcsQ0FBQyxDQUFBO1FBQzNELENBQUM7UUFFRCxPQUFPLHNCQUFzQixDQUFBO0lBQy9CLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsS0FBSyxDQUFDLG1CQUFtQixDQUFDLEVBQUMsdUJBQXVCLEVBQUUsV0FBVyxFQUFFLEVBQUUsRUFBQztRQUNsRSxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMsdUJBQXVCLEVBQUU7WUFDeEUsS0FBSyxFQUFFLFdBQVcsQ0FBQyxLQUFLO1lBQ3hCLFFBQVEsRUFBRSxXQUFXLENBQUMsUUFBUTtZQUM5QixLQUFLLEVBQUUsV0FBVyxDQUFDLEtBQUs7U0FDekIsQ0FBQyxDQUFBO1FBRUYsTUFBTSxVQUFVLENBQUMsbUNBQW1DLEVBQUUsQ0FBQTtRQUV0RCxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsa0JBQWtCLEVBQUUsQ0FBQTtRQUNsRCxNQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsVUFBVSxFQUFFLENBQUE7UUFDMUMsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLGtCQUFrQixFQUFFLENBQUE7UUFDN0MsTUFBTSxLQUFLLEdBQUcsVUFBVSxDQUFDLGtCQUFrQixFQUFFLENBQUE7UUFDN0MsMkZBQTJGO1FBQzNGLDBDQUEwQztRQUMxQyxJQUFJLEtBQUssR0FBRyxVQUFVLENBQUMsNEJBQTRCLENBQUMsTUFBTSxDQUFDLENBQUMsS0FBSyxDQUFDLEVBQUMsQ0FBQyxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUMsRUFBRSxFQUFDLENBQUMsVUFBVSxDQUFDLEVBQUUsRUFBRSxFQUFDLEVBQUMsQ0FBQyxDQUFBO1FBRWpILElBQUksS0FBSztZQUFFLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFBO1FBQzdELElBQUksS0FBSztZQUFFLFVBQVUsQ0FBQyx1QkFBdUIsQ0FBQyxFQUFDLEtBQUssRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFBO1FBRTdELEtBQUssTUFBTSxNQUFNLElBQUksVUFBVSxDQUFDLHFCQUFxQixFQUFFLEVBQUUsQ0FBQztZQUN4RCxVQUFVLENBQUMsd0JBQXdCLENBQUMsRUFBQyxLQUFLLEVBQUUsTUFBTSxFQUFDLENBQUMsQ0FBQTtRQUN0RCxDQUFDO1FBRUQsT0FBTyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQTtJQUNyQyxDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxLQUFLLENBQUMsMEJBQTBCLENBQUMsRUFBRSxFQUFFLHVCQUF1QjtRQUMxRCxNQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsd0JBQXdCLENBQUMsdUJBQXVCLENBQUMsQ0FBQTtRQUV6RSxNQUFNLFVBQVUsQ0FBQyxtQ0FBbUMsRUFBRSxDQUFBO1FBRXRELE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFBO1FBQ2xELE1BQU0sVUFBVSxHQUFHLFVBQVUsQ0FBQyxVQUFVLEVBQUUsQ0FBQTtRQUMxQywrRkFBK0Y7UUFDL0YsbURBQW1EO1FBQ25ELElBQUksS0FBSyxHQUFHLFVBQVUsQ0FBQyw0QkFBNEIsQ0FBQyxNQUFNLENBQUMsQ0FBQyxLQUFLLENBQUMsRUFBQyxDQUFDLFVBQVUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxFQUFFLEVBQUMsQ0FBQyxVQUFVLENBQUMsRUFBRSxFQUFFLEVBQUMsRUFBQyxDQUFDLENBQUE7UUFDakgsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLG9CQUFvQixFQUFFLENBQUE7UUFFakQsSUFBSSxPQUFPO1lBQUUsS0FBSyxHQUFHLEtBQUssQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUE7UUFFM0MsS0FBSyxNQUFNLEtBQUssSUFBSSxVQUFVLENBQUMsc0JBQXNCLEVBQUUsRUFBRSxDQUFDO1lBQ3hEOztvSkFFd0k7WUFDeEksTUFBTSxJQUFJLEdBQUcsRUFBRSxDQUFBO1lBRWYsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLENBQUMsR0FBRztnQkFDMUIsWUFBWSxFQUFFLEtBQUssQ0FBQyxnQkFBZ0I7Z0JBQ3BDLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQzs7a0hBRTZFO29CQUFDLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTO2FBQzdILENBQUE7WUFDRCxLQUFLLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxDQUFBO1FBQ3ZCLENBQUM7UUFFRCxNQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsc0JBQXNCLEVBQUUsQ0FBQTtRQUVyRCxJQUFJLFNBQVMsS0FBSyxJQUFJO1lBQUUsS0FBSyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUMsQ0FBQTtRQUVsRCxLQUFLLEdBQUcsVUFBVSxDQUFDLDZDQUE2QyxDQUFDLEVBQUMsS0FBSyxFQUFDLENBQUMsQ0FBQTtRQUV6RSxNQUFNLEtBQUssR0FBRyxNQUFNLEtBQUssQ0FBQyxLQUFLLEVBQUUsQ0FBQTtRQUVqQyxJQUFJLENBQUMsS0FBSztZQUFFLE9BQU8sSUFBSSxDQUFBO1FBRXZCLElBQUksSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLEtBQUssU0FBUyxFQUFFLENBQUM7WUFDeEMsTUFBTSxVQUFVLENBQUMsNkJBQTZCLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFBO1FBQ3pELENBQUM7UUFFRCxVQUFVLENBQUMsNkJBQTZCLEdBQUcsU0FBUyxDQUFBO1FBRXBELE9BQU8sTUFBTSxVQUFVLENBQUMsNkJBQTZCLEVBQUUsQ0FBQyxTQUFTLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFBO0lBQ2xGLENBQUM7SUFFRDs7Ozs7Ozs7Ozs7T0FXRztJQUNILGlCQUFpQjtRQUNmLE1BQU0sY0FBYyxHQUFHOztnRkFFaUQsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLENBQUE7UUFDdEcsTUFBTSxVQUFVLEdBQUcsT0FBTyxjQUFjLEVBQUUsT0FBTyxLQUFLLFVBQVUsQ0FBQyxDQUFDLENBQUMsY0FBYyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUE7UUFDaEcsTUFBTSxRQUFRLEdBQUcsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLFdBQVcsS0FBSyxVQUFVLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQTtRQUNqRyxNQUFNLGFBQWEsR0FBRyxPQUFPLGNBQWMsRUFBRSxhQUFhLEtBQUssVUFBVSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsYUFBYSxFQUFFLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQTtRQUN0SDs7a0VBRTBEO1FBQzFELE1BQU0sU0FBUyxHQUFHLEVBQUUsQ0FBQTtRQUVwQixLQUFLLE1BQU0sR0FBRyxJQUFJLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLEVBQUUsQ0FBQyxFQUFFLENBQUM7WUFDaEQsU0FBUyxDQUFDLEdBQUcsQ0FBQyxXQUFXLEVBQUUsQ0FBQyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQTtRQUNoRCxDQUFDO1FBRUQsT0FBTztZQUNMLE9BQU8sRUFBRSxHQUFHLEVBQUUsQ0FBQyxTQUFTO1lBQ3hCLE1BQU0sRUFBRSxDQUFDLElBQUksRUFBRSxFQUFFLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLEVBQUUsQ0FBQztZQUN2RCxRQUFRLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUMsR0FBRyxRQUFRLEVBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLEdBQUcsQ0FBQztZQUNwRSxJQUFJLEVBQUUsR0FBRyxFQUFFLENBQUMsa0JBQWtCO1lBQzlCLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNO1lBQ3hCLGFBQWEsRUFBRSxHQUFHLEVBQUUsQ0FBQyxhQUFhO1lBQ2xDLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxTQUFTLENBQUMsTUFBTTtTQUMvQixDQUFBO0lBQ0gsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBWZWxvY2lvdXNXZWJzb2NrZXRDaGFubmVsIGZyb20gXCIuLi9odHRwLXNlcnZlci93ZWJzb2NrZXQtY2hhbm5lbC5qc1wiXG5pbXBvcnQgUmVzcG9uc2UgZnJvbSBcIi4uL2h0dHAtc2VydmVyL2NsaWVudC9yZXNwb25zZS5qc1wiXG5pbXBvcnQge3NlcmlhbGl6ZUZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZX0gZnJvbSBcIi4vdHJhbnNwb3J0LXNlcmlhbGl6YXRpb24uanNcIlxuXG5jb25zdCBFVkVOVF9GSUxURVJfS0VZUyA9IG5ldyBTZXQoW1wiam9pbnNcIiwgXCJrZXlcIiwgXCJzZWFyY2hlc1wiLCBcIndoZXJlXCJdKVxuXG4vKipcbiAqIERlZmluZXMgdGhpcyB0eXBlZGVmLlxuICogQHR5cGVkZWYge3thY3Rpb24/OiBzdHJpbmcsIGlkPzogc3RyaW5nIHwgbnVtYmVyLCBtYXRjaGVkRXZlbnRGaWx0ZXJLZXlzPzogc3RyaW5nW10sIHJlY29yZD86IGltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlLCBba2V5OiBzdHJpbmddOiBpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkfX0gRnJvbnRlbmRNb2RlbExpZmVjeWNsZUJyb2FkY2FzdEJvZHlcbiAqL1xuLyoqXG4gKiBEZWZpbmVzIHRoaXMgdHlwZWRlZi5cbiAqIEB0eXBlZGVmIHt7aGVhZGVycz86ICgpID0+IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHN0cmluZ1tdIHwgdW5kZWZpbmVkPiwgcmVtb3RlQWRkcmVzcz86ICgpID0+IHN0cmluZyB8IHVuZGVmaW5lZH19IEZyb250ZW5kTW9kZWxXZWJzb2NrZXRVcGdyYWRlUmVxdWVzdFxuICovXG4vKipcbiAqIERlZmluZXMgdGhpcyB0eXBlZGVmLlxuICogQHR5cGVkZWYge3toZWFkZXJzOiAoKSA9PiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCBzdHJpbmdbXSB8IHVuZGVmaW5lZD4sIGhlYWRlcjogKG5hbWU6IHN0cmluZykgPT4gc3RyaW5nIHwgc3RyaW5nW10gfCB1bmRlZmluZWQsIG1ldGFkYXRhOiAoa2V5Pzogc3RyaW5nKSA9PiBSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZT4gfCBpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZSB8IHVuZGVmaW5lZCwgcGF0aDogKCkgPT4gc3RyaW5nLCBodHRwTWV0aG9kOiAoKSA9PiBzdHJpbmcsIHJlbW90ZUFkZHJlc3M6ICgpID0+IHN0cmluZyB8IHVuZGVmaW5lZCwgb3JpZ2luOiAoKSA9PiBzdHJpbmcgfCBzdHJpbmdbXSB8IHVuZGVmaW5lZH19IEZyb250ZW5kTW9kZWxXZWJzb2NrZXRTeW50aGV0aWNSZXF1ZXN0XG4gKi9cblxuLyoqXG4gKiBQZXItc2Vzc2lvbiBjaGFubmVsIHN1YnNjcmlwdGlvbiBmb3IgZnJvbnRlbmQtbW9kZWwgbGlmZWN5Y2xlIGV2ZW50cy5cbiAqIFJlcGxhY2VzIHRoZSBsZWdhY3kgYEZyb250ZW5kTW9kZWxXZWJzb2NrZXRDaGFubmVsYCAoUGhhc2UgMykuXG4gKlxuICogQXV0aCBtb2RlbDogc3Vic2NyaWJlLXRpbWUgb25seS4gYGNhblN1YnNjcmliZWAgcmVzb2x2ZXMgdGhlIGNhbGxlcidzXG4gKiBhYmlsaXR5IG9uY2UsIGNoZWNrcyB0aGF0IGF0IGxlYXN0IG9uZSBgYWxsb3dgIHJ1bGUgZXhpc3RzIGZvclxuICogYHJlYWRgIG9uIHRoZSByZXF1ZXN0ZWQgbW9kZWwgY2xhc3MsIGFuZCB0aGVuIGRlbGl2ZXJzIGZ1dHVyZVxuICogbGlmZWN5Y2xlIGJyb2FkY2FzdHMgZm9yIHRoYXQgbW9kZWwgd2l0aG91dCByZS1hdXRob3JpemluZyBwZXIgZXZlbnQuXG4gKiBUaGlzIG1hdGNoZXMgdGhlIGV4cGxpY2l0IGRlc2lnbiBkZWNpc2lvbiBpbiBQaGFzZSAzIHRvIHRyYWRlXG4gKiBwZXItcmVjb3JkIHZpc2liaWxpdHkgZ3VhcmFudGVlcyBmb3IgbWFzc2l2ZWx5IGNoZWFwZXIgYnJvYWRjYXN0IGZhbi1vdXQuXG4gKiBTdWJzY3JpYmVyLXByb3ZpZGVkIGV2ZW50IGZpbHRlcnMgY2FuIHN0aWxsIG5hcnJvdyB3aGljaCBjcmVhdGUvdXBkYXRlXG4gKiBldmVudHMgYXJlIGRlbGl2ZXJlZCwgYnV0IHRoZXkgYXJlIG1hdGNoaW5nIHByZWRpY2F0ZXMgcmF0aGVyIHRoYW5cbiAqIHBlci1yZWNvcmQgYXV0aG9yaXphdGlvbiBjaGVja3MuXG4gKlxuICogV2lyZTogc3Vic2NyaWJlIHdpdGggYHN1YnNjcmliZUNoYW5uZWwoXCJmcm9udGVuZC1tb2RlbHNcIiwge3BhcmFtczoge21vZGVsOiBNb2RlbE5hbWV9fSlgLlxuICogQmFja2VuZCBwdWJsaXNoZXMgYHthY3Rpb24sIGlkLCByZWNvcmR9YCB2aWFcbiAqIGBjb25maWd1cmF0aW9uLmJyb2FkY2FzdFRvQ2hhbm5lbChcImZyb250ZW5kLW1vZGVsc1wiLCB7bW9kZWw6IE1vZGVsTmFtZX0sIGJvZHkpYDtcbiAqIGBtYXRjaGVzKClgIHJvdXRlcyBieSBtb2RlbCBuYW1lLlxuICovXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBGcm9udGVuZE1vZGVsV2Vic29ja2V0Q2hhbm5lbCBleHRlbmRzIFZlbG9jaW91c1dlYnNvY2tldENoYW5uZWwge1xuICAvKipcbiAgICogQWJpbGl0eS5cbiAgICBAdHlwZSB7aW1wb3J0KFwiLi4vYXV0aG9yaXphdGlvbi9hYmlsaXR5LmpzXCIpLmRlZmF1bHQgfCBudWxsfSAqL1xuICBfYWJpbGl0eSA9IG51bGxcblxuICAvKipcbiAgICogUnVucyBjYW4gc3Vic2NyaWJlLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gV2hldGhlciB0aGUgZnJvbnRlbmQtbW9kZWwgc3Vic2NyaXB0aW9uIGlzIGF1dGhvcml6ZWQuXG4gICAqL1xuICBhc3luYyBjYW5TdWJzY3JpYmUoKSB7XG4gICAgY29uc3QgbW9kZWxOYW1lID0gdGhpcy5fbW9kZWxOYW1lKClcblxuICAgIGlmICghbW9kZWxOYW1lKSByZXR1cm4gZmFsc2VcbiAgICB0aGlzLl9ldmVudEZpbHRlcnMoKVxuXG4gICAgY29uc3QgY29uZmlndXJhdGlvbiA9IHRoaXMuc2Vzc2lvbi5jb25maWd1cmF0aW9uXG4gICAgY29uc3QgbW9kZWxDbGFzc2VzID0gY29uZmlndXJhdGlvbi5nZXRNb2RlbENsYXNzZXM/LigpIHx8IHt9XG4gICAgY29uc3QgTW9kZWxDbGFzcyA9IG1vZGVsQ2xhc3Nlc1ttb2RlbE5hbWVdXG5cbiAgICBpZiAoIU1vZGVsQ2xhc3MpIHJldHVybiBmYWxzZVxuXG4gICAgY29uc3QgYWJpbGl0eSA9IGF3YWl0IGNvbmZpZ3VyYXRpb24ucmVzb2x2ZUFiaWxpdHk/Lih7XG4gICAgICAvLyBGb3J3YXJkIHRoZSBzdWJzY3JpYmVyJ3MgcGFyYW1zIChlLmcuIGF1dGhlbnRpY2F0aW9uVG9rZW4pIHNvIHRva2VuLWF1dGhlbnRpY2F0ZWQgY2xpZW50c1xuICAgICAgLy8gcmVzb2x2ZSB0aGUgc2FtZSBhYmlsaXR5IHRoZXkgd291bGQgb3ZlciBIVFRQLiBXaXRob3V0IHRoaXMgb25seSBzZXNzaW9uL2Nvb2tpZSBhdXRoIG9uIHRoZVxuICAgICAgLy8gdXBncmFkZSByZXF1ZXN0IHdvcmtzLCBhbmQgcGFyYW0tYmFzZWQgYXV0aCAobGlrZSBhIHNjYW5uZXIgcGFzc2luZyBhbiBhdXRoZW50aWNhdGlvblRva2VuKVxuICAgICAgLy8gaXMgZHJvcHBlZCDigJQgbGVhdmluZyBzdWNoIHN1YnNjcmliZXJzIHdpdGggYSBndWVzdCBhYmlsaXR5IGFuZCBubyByZWFkIHJ1bGUuXG4gICAgICBwYXJhbXM6IHsuLi50aGlzLnBhcmFtcywgbW9kZWw6IG1vZGVsTmFtZX0sXG4gICAgICByZXF1ZXN0OiAvKipcbiAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgQHR5cGUge2ltcG9ydChcIi4uL2h0dHAtc2VydmVyL2NsaWVudC9yZXF1ZXN0LmpzXCIpLmRlZmF1bHR9ICovICh0aGlzLl9zeW50aGV0aWNSZXF1ZXN0KCkpLFxuICAgICAgcmVzcG9uc2U6IG5ldyBSZXNwb25zZSh7Y29uZmlndXJhdGlvbn0pXG4gICAgfSlcblxuICAgIGlmICghYWJpbGl0eSkgcmV0dXJuIGZhbHNlXG4gICAgdGhpcy5fYWJpbGl0eSA9IGFiaWxpdHlcblxuICAgIC8vIExvYWQgcmVzb3VyY2UtZGVjbGFyZWQgcnVsZXMgZm9yIHRoaXMgbW9kZWwgY2xhc3MgYmVmb3JlIGNoZWNraW5nLFxuICAgIC8vIG90aGVyd2lzZSBgcnVsZXNGb3JgIHJldHVybnMgZW1wdHkgZm9yIGFiaWxpdGllcyB3aG9zZSByZXNvdXJjZXNcbiAgICAvLyByZWdpc3RlciBydWxlcyBsYXppbHkgdmlhIGBhYmlsaXRpZXMoKWAuXG4gICAgaWYgKHR5cGVvZiBhYmlsaXR5LmxvYWRBYmlsaXRpZXNGb3JNb2RlbENsYXNzID09PSBcImZ1bmN0aW9uXCIpIHtcbiAgICAgIGFiaWxpdHkubG9hZEFiaWxpdGllc0Zvck1vZGVsQ2xhc3MoTW9kZWxDbGFzcylcbiAgICB9XG5cbiAgICBjb25zdCByZWFkUnVsZXMgPSB0eXBlb2YgYWJpbGl0eS5ydWxlc0ZvciA9PT0gXCJmdW5jdGlvblwiXG4gICAgICA/IGFiaWxpdHkucnVsZXNGb3Ioe2FjdGlvbjogXCJyZWFkXCIsIG1vZGVsQ2xhc3M6IE1vZGVsQ2xhc3N9KVxuICAgICAgOiBbXVxuXG4gICAgcmV0dXJuIHJlYWRSdWxlcy5zb21lKCgvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge3tlZmZlY3Q6IHN0cmluZ319ICovIHJ1bGUpID0+IHJ1bGUuZWZmZWN0ID09PSBcImFsbG93XCIpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBkZWxpdmVyIGJyb2FkY2FzdC5cbiAgICogQHBhcmFtIHtGcm9udGVuZE1vZGVsTGlmZWN5Y2xlQnJvYWRjYXN0Qm9keX0gYm9keSAtIEJyb2FkY2FzdCBib2R5LlxuICAgKiBAcGFyYW0ge3tldmVudElkPzogc3RyaW5nfX0gW21ldGFdIC0gT3B0aW9uYWwgZXZlbnQgbWV0YWRhdGEuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyBhZnRlciBkZWxpdmVyeS5cbiAgICovXG4gIGFzeW5jIGRlbGl2ZXJCcm9hZGNhc3QoYm9keSwgbWV0YSkge1xuICAgIGNvbnN0IGNvbmZpZ3VyYXRpb24gPSB0aGlzLnNlc3Npb24uY29uZmlndXJhdGlvblxuXG4gICAgaWYgKGNvbmZpZ3VyYXRpb24gJiYgdHlwZW9mIGNvbmZpZ3VyYXRpb24uZW5zdXJlQ29ubmVjdGlvbnMgPT09IFwiZnVuY3Rpb25cIikge1xuICAgICAgYXdhaXQgY29uZmlndXJhdGlvbi5lbnN1cmVDb25uZWN0aW9ucyh7bmFtZTogXCJGcm9udGVuZCBtb2RlbCB3ZWJzb2NrZXQgYnJvYWRjYXN0XCJ9LCBhc3luYyAoKSA9PiB7XG4gICAgICAgIGF3YWl0IHRoaXMuX2RlbGl2ZXJCcm9hZGNhc3QoYm9keSwgbWV0YSlcbiAgICAgIH0pXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBhd2FpdCB0aGlzLl9kZWxpdmVyQnJvYWRjYXN0KGJvZHksIG1ldGEpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBkZWxpdmVyIGJyb2FkY2FzdC5cbiAgICogQHBhcmFtIHtGcm9udGVuZE1vZGVsTGlmZWN5Y2xlQnJvYWRjYXN0Qm9keX0gYm9keSAtIEJyb2FkY2FzdCBib2R5LlxuICAgKiBAcGFyYW0ge3tldmVudElkPzogc3RyaW5nfX0gW21ldGFdIC0gT3B0aW9uYWwgZXZlbnQgbWV0YWRhdGEuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHZvaWQ+fSBSZXNvbHZlcyBhZnRlciBkZWxpdmVyeS5cbiAgICovXG4gIGFzeW5jIF9kZWxpdmVyQnJvYWRjYXN0KGJvZHksIG1ldGEpIHtcbiAgICBjb25zdCBoYXNFdmVudEZpbHRlcnMgPSB0aGlzLl9oYXNFdmVudEZpbHRlclBhcmFtcygpXG5cbiAgICBpZiAoIXRoaXMuX2hhc1Byb2plY3Rpb25QYXJhbXMoKSAmJiAhaGFzRXZlbnRGaWx0ZXJzKSB7XG4gICAgICAvLyBFdmVuIHVuZmlsdGVyZWQgc3Vic2NyaXB0aW9ucyBtdXN0IHJlc3BlY3QgdGhlIHN1YnNjcmliZXIncyBhYmlsaXR5LiBBIGNyZWF0ZS91cGRhdGUgY2Fycmllc1xuICAgICAgLy8gdGhlIHJlY29yZCwgc28gb25seSBkZWxpdmVyIGl0IHdoZW4gdGhlIHJlY29yZCBpcyB3aXRoaW4gdGhlIGF1dGhlbnRpY2F0ZWQgYWJpbGl0eSdzIHNjb3BlLlxuICAgICAgLy8gRGVzdHJveXMgKGFuZCBib2RpZXMgd2l0aG91dCBhIHVzYWJsZSBpZCkgY2Fycnkgbm8gcmVjb3JkLCBzbyBwYXNzIHRoZW0gdGhyb3VnaCB1bmNoYW5nZWQuXG4gICAgICBpZiAoYm9keSAmJiB0eXBlb2YgYm9keSA9PT0gXCJvYmplY3RcIiAmJiAoYm9keS5hY3Rpb24gPT09IFwiY3JlYXRlXCIgfHwgYm9keS5hY3Rpb24gPT09IFwidXBkYXRlXCIpICYmIGJvZHkuaWQgIT09IHVuZGVmaW5lZCAmJiBib2R5LmlkICE9PSBudWxsKSB7XG4gICAgICAgIGNvbnN0IEZyb250ZW5kTW9kZWxDb250cm9sbGVyID0gYXdhaXQgdGhpcy5fZnJvbnRlbmRNb2RlbENvbnRyb2xsZXJDbGFzcygpXG5cbiAgICAgICAgaWYgKCFhd2FpdCB0aGlzLl9ldmVudElzQWNjZXNzaWJsZShib2R5LmlkLCBGcm9udGVuZE1vZGVsQ29udHJvbGxlcikpIHJldHVyblxuICAgICAgfVxuXG4gICAgICB0aGlzLnNlbmRNZXNzYWdlKGJvZHksIG1ldGEpXG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICBpZiAoIWJvZHkgfHwgdHlwZW9mIGJvZHkgIT09IFwib2JqZWN0XCIpIHtcbiAgICAgIGlmICghaGFzRXZlbnRGaWx0ZXJzIHx8IHRoaXMuX2hhc1VuZmlsdGVyZWRFdmVudERlbGl2ZXJ5KCkpIHRoaXMuc2VuZE1lc3NhZ2UoYm9keSwgbWV0YSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChib2R5LmFjdGlvbiA9PT0gXCJkZXN0cm95XCIpIHtcbiAgICAgIGlmICghaGFzRXZlbnRGaWx0ZXJzIHx8IHRoaXMuX2hhc1VuZmlsdGVyZWRFdmVudERlbGl2ZXJ5KCkpIHRoaXMuc2VuZE1lc3NhZ2UoYm9keSwgbWV0YSlcbiAgICAgIHJldHVyblxuICAgIH1cblxuICAgIGlmIChib2R5LmlkID09PSB1bmRlZmluZWQgfHwgYm9keS5pZCA9PT0gbnVsbCkge1xuICAgICAgaWYgKCFoYXNFdmVudEZpbHRlcnMgfHwgdGhpcy5faGFzVW5maWx0ZXJlZEV2ZW50RGVsaXZlcnkoKSkgdGhpcy5zZW5kTWVzc2FnZShib2R5LCBtZXRhKVxuICAgICAgcmV0dXJuXG4gICAgfVxuXG4gICAgY29uc3QgRnJvbnRlbmRNb2RlbENvbnRyb2xsZXIgPSBhd2FpdCB0aGlzLl9mcm9udGVuZE1vZGVsQ29udHJvbGxlckNsYXNzKClcbiAgICBjb25zdCBtYXRjaGVkRXZlbnRGaWx0ZXJLZXlzID0gYXdhaXQgdGhpcy5fbWF0Y2hlZEV2ZW50RmlsdGVyS2V5c0ZvckV2ZW50SWQoYm9keS5pZCwgRnJvbnRlbmRNb2RlbENvbnRyb2xsZXIpXG5cbiAgICBpZiAoaGFzRXZlbnRGaWx0ZXJzICYmIG1hdGNoZWRFdmVudEZpbHRlcktleXMubGVuZ3RoID09PSAwICYmICF0aGlzLl9oYXNVbmZpbHRlcmVkRXZlbnREZWxpdmVyeSgpKSB7XG4gICAgICByZXR1cm5cbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBEZWxpdmVyIGJvZHkuXG4gICAgICBAdHlwZSB7RnJvbnRlbmRNb2RlbExpZmVjeWNsZUJyb2FkY2FzdEJvZHl9ICovXG4gICAgbGV0IGRlbGl2ZXJCb2R5ID0gYm9keVxuXG4gICAgaWYgKHRoaXMuX2hhc1Byb2plY3Rpb25QYXJhbXMoKSkge1xuICAgICAgY29uc3QgcHJvamVjdGVkUmVjb3JkID0gYXdhaXQgdGhpcy5fcHJvamVjdGVkUmVjb3JkRm9yRXZlbnRJZChib2R5LmlkLCBGcm9udGVuZE1vZGVsQ29udHJvbGxlcilcblxuICAgICAgaWYgKCFwcm9qZWN0ZWRSZWNvcmQpIHtcbiAgICAgICAgcmV0dXJuXG4gICAgICB9XG5cbiAgICAgIGRlbGl2ZXJCb2R5ID0ge1xuICAgICAgICAuLi5kZWxpdmVyQm9keSxcbiAgICAgICAgcmVjb3JkOiAvKipcbiAgICAgICAgICAgICAgICAgKiBOYXJyb3dzIHRoZSBydW50aW1lIHZhbHVlIHRvIHRoZSBkb2N1bWVudGVkIHR5cGUuXG4gICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi9xdWVyeS5qc1wiKS5Gcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWV9ICovIChzZXJpYWxpemVGcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWUocHJvamVjdGVkUmVjb3JkKSlcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoaGFzRXZlbnRGaWx0ZXJzKSB7XG4gICAgICBkZWxpdmVyQm9keSA9IHtcbiAgICAgICAgLi4uZGVsaXZlckJvZHksXG4gICAgICAgIG1hdGNoZWRFdmVudEZpbHRlcktleXNcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLnNlbmRNZXNzYWdlKGRlbGl2ZXJCb2R5LCBtZXRhKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgbWF0Y2hlcy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZT59IGJyb2FkY2FzdFBhcmFtcyAtIFBhcmFtcyBmcm9tIGBicm9hZGNhc3RUb0NoYW5uZWxgLlxuICAgKiBAcmV0dXJucyB7Ym9vbGVhbn0gV2hldGhlciB0aGUgYnJvYWRjYXN0IG1hdGNoZXMgdGhpcyBzdWJzY3JpYmVyJ3MgbW9kZWwuXG4gICAqL1xuICBtYXRjaGVzKGJyb2FkY2FzdFBhcmFtcykge1xuICAgIHJldHVybiBicm9hZGNhc3RQYXJhbXM/Lm1vZGVsID09PSB0aGlzLl9tb2RlbE5hbWUoKVxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgZGVidWcgc25hcHNob3QuXG4gICAqIEByZXR1cm5zIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gRGVidWctc2FmZSBzdWJzY3JpcHRpb24gZGV0YWlscy5cbiAgICovXG4gIGRlYnVnU25hcHNob3QoKSB7XG4gICAgY29uc3QgZXZlbnRGaWx0ZXJzID0gdGhpcy5fZXZlbnRGaWx0ZXJzKClcblxuICAgIHJldHVybiB7XG4gICAgICBhYmlsaXRpZXM6IHRoaXMucGFyYW1zLmFiaWxpdGllcyAhPT0gdW5kZWZpbmVkLFxuICAgICAgZXZlbnRGaWx0ZXJDb3VudDogZXZlbnRGaWx0ZXJzLmxlbmd0aCxcbiAgICAgIG1vZGVsOiB0aGlzLl9tb2RlbE5hbWUoKSxcbiAgICAgIHByZWxvYWQ6IHRoaXMucGFyYW1zLnByZWxvYWQgIT09IHVuZGVmaW5lZCxcbiAgICAgIHF1ZXJ5RGF0YTogdGhpcy5wYXJhbXMucXVlcnlEYXRhICE9PSB1bmRlZmluZWQsXG4gICAgICBzZWxlY3Q6IHRoaXMucGFyYW1zLnNlbGVjdCAhPT0gdW5kZWZpbmVkLFxuICAgICAgc2VsZWN0c0V4dHJhOiB0aGlzLnBhcmFtcy5zZWxlY3RzRXh0cmEgIT09IHVuZGVmaW5lZCxcbiAgICAgIHVuZmlsdGVyZWRFdmVudERlbGl2ZXJ5OiB0aGlzLnBhcmFtcy51bmZpbHRlcmVkRXZlbnREZWxpdmVyeSA9PT0gdHJ1ZSxcbiAgICAgIHdpdGhDb3VudDogdGhpcy5wYXJhbXMud2l0aENvdW50ICE9PSB1bmRlZmluZWRcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUnVucyBtb2RlbCBuYW1lLlxuICAgKiBAcmV0dXJucyB7c3RyaW5nIHwgbnVsbH0gLSBSZXF1ZXN0ZWQgZnJvbnRlbmQtbW9kZWwgbmFtZSBvciBudWxsLlxuICAgKi9cbiAgX21vZGVsTmFtZSgpIHtcbiAgICByZXR1cm4gdHlwZW9mIHRoaXMucGFyYW1zPy5tb2RlbCA9PT0gXCJzdHJpbmdcIiAmJiB0aGlzLnBhcmFtcy5tb2RlbC5sZW5ndGggPiAwXG4gICAgICA/IHRoaXMucGFyYW1zLm1vZGVsXG4gICAgICA6IG51bGxcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGhhcyBwcm9qZWN0aW9uIHBhcmFtcy5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGlzIHN1YnNjcmlwdGlvbiByZXF1ZXN0ZWQgcGVyLWV2ZW50IHJlY29yZCBwcm9qZWN0aW9uLlxuICAgKi9cbiAgX2hhc1Byb2plY3Rpb25QYXJhbXMoKSB7XG4gICAgcmV0dXJuIHRoaXMucGFyYW1zLnNlbGVjdCAhPT0gdW5kZWZpbmVkXG4gICAgICB8fCB0aGlzLnBhcmFtcy5zZWxlY3RzRXh0cmEgIT09IHVuZGVmaW5lZFxuICAgICAgfHwgdGhpcy5wYXJhbXMucHJlbG9hZCAhPT0gdW5kZWZpbmVkXG4gICAgICB8fCB0aGlzLnBhcmFtcy53aXRoQ291bnQgIT09IHVuZGVmaW5lZFxuICAgICAgfHwgdGhpcy5wYXJhbXMuYWJpbGl0aWVzICE9PSB1bmRlZmluZWRcbiAgICAgIHx8IHRoaXMucGFyYW1zLnF1ZXJ5RGF0YSAhPT0gdW5kZWZpbmVkXG4gIH1cblxuICAvKipcbiAgICogUnVucyBoYXMgZXZlbnQgZmlsdGVyIHBhcmFtcy5cbiAgICogQHJldHVybnMge2Jvb2xlYW59IC0gV2hldGhlciB0aGlzIHN1YnNjcmlwdGlvbiByZXF1ZXN0ZWQgZXZlbnQgcXVlcnkgZmlsdGVycy5cbiAgICovXG4gIF9oYXNFdmVudEZpbHRlclBhcmFtcygpIHtcbiAgICByZXR1cm4gdGhpcy5fZXZlbnRGaWx0ZXJzKCkubGVuZ3RoID4gMFxuICB9XG5cbiAgLyoqXG4gICAqIFJ1bnMgaGFzIHVuZmlsdGVyZWQgZXZlbnQgZGVsaXZlcnkuXG4gICAqIEByZXR1cm5zIHtib29sZWFufSAtIFdoZXRoZXIgdW5maWx0ZXJlZCBjYWxsYmFja3Mgc2hvdWxkIHJlY2VpdmUgZXZlcnkgZXZlbnQuXG4gICAqL1xuICBfaGFzVW5maWx0ZXJlZEV2ZW50RGVsaXZlcnkoKSB7XG4gICAgcmV0dXJuIHRoaXMucGFyYW1zLnVuZmlsdGVyZWRFdmVudERlbGl2ZXJ5ID09PSB0cnVlXG4gIH1cblxuICAvKipcbiAgICogUnVucyBldmVudCBmaWx0ZXJzLlxuICAgKiBAcmV0dXJucyB7aW1wb3J0KFwiLi9xdWVyeS5qc1wiKS5Gcm9udGVuZE1vZGVsRXZlbnRGaWx0ZXJQYXlsb2FkRW50cnlbXX0gLSBWYWxpZCBldmVudCBmaWx0ZXJzLlxuICAgKi9cbiAgX2V2ZW50RmlsdGVycygpIHtcbiAgICBpZiAodGhpcy5wYXJhbXMuZXZlbnRGaWx0ZXJzID09PSB1bmRlZmluZWQpIHJldHVybiBbXVxuICAgIGlmICghQXJyYXkuaXNBcnJheSh0aGlzLnBhcmFtcy5ldmVudEZpbHRlcnMpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGcm9udGVuZCBtb2RlbCBldmVudEZpbHRlcnMgbXVzdCBiZSBhbiBhcnJheVwiKVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnBhcmFtcy5ldmVudEZpbHRlcnMubWFwKChlbnRyeSkgPT4ge1xuICAgICAgaWYgKCFlbnRyeSB8fCB0eXBlb2YgZW50cnkgIT09IFwib2JqZWN0XCIgfHwgQXJyYXkuaXNBcnJheShlbnRyeSkpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKFwiRnJvbnRlbmQgbW9kZWwgZXZlbnRGaWx0ZXJzIGVudHJpZXMgbXVzdCBiZSBvYmplY3RzXCIpXG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGV2ZW50RmlsdGVyID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgPz59ICovIChlbnRyeSlcbiAgICAgIGNvbnN0IHVua25vd25LZXlzID0gT2JqZWN0LmtleXMoZXZlbnRGaWx0ZXIpLmZpbHRlcigoa2V5KSA9PiAhRVZFTlRfRklMVEVSX0tFWVMuaGFzKGtleSkpXG5cbiAgICAgIGlmICh1bmtub3duS2V5cy5sZW5ndGggPiAwKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgRnJvbnRlbmQgbW9kZWwgZXZlbnRGaWx0ZXJzIGVudHJpZXMgY2Fubm90IGluY2x1ZGUgJHt1bmtub3duS2V5cy5qb2luKFwiLCBcIil9YClcbiAgICAgIH1cblxuICAgICAgaWYgKHR5cGVvZiBldmVudEZpbHRlci5rZXkgIT09IFwic3RyaW5nXCIgfHwgZXZlbnRGaWx0ZXIua2V5Lmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJGcm9udGVuZCBtb2RlbCBldmVudEZpbHRlcnMgZW50cmllcyByZXF1aXJlIGEga2V5XCIpXG4gICAgICB9XG5cbiAgICAgIC8qKlxuICAgICAgICogU2FuaXRpemVkIGV2ZW50IGZpbHRlci5cbiAgICAgICAgQHR5cGUge2ltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbEV2ZW50RmlsdGVyUGF5bG9hZEVudHJ5fSAqL1xuICAgICAgY29uc3Qgc2FuaXRpemVkRXZlbnRGaWx0ZXIgPSB7a2V5OiBldmVudEZpbHRlci5rZXl9XG5cbiAgICAgIGlmIChldmVudEZpbHRlci5qb2lucyAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHNhbml0aXplZEV2ZW50RmlsdGVyLmpvaW5zID0gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsIGltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlPn0gKi8gKGV2ZW50RmlsdGVyLmpvaW5zKVxuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnRGaWx0ZXIuc2VhcmNoZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzYW5pdGl6ZWRFdmVudEZpbHRlci5zZWFyY2hlcyA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxTZWFyY2hbXX0gKi8gKGV2ZW50RmlsdGVyLnNlYXJjaGVzKVxuICAgICAgfVxuXG4gICAgICBpZiAoZXZlbnRGaWx0ZXIud2hlcmUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICBzYW5pdGl6ZWRFdmVudEZpbHRlci53aGVyZSA9IC8qKlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIEB0eXBlIHtSZWNvcmQ8c3RyaW5nLCBpbXBvcnQoXCIuL3F1ZXJ5LmpzXCIpLkZyb250ZW5kTW9kZWxUcmFuc3BvcnRWYWx1ZT59ICovIChldmVudEZpbHRlci53aGVyZSlcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHNhbml0aXplZEV2ZW50RmlsdGVyXG4gICAgfSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGZyb250ZW5kIG1vZGVsIGNvbnRyb2xsZXIgY2xhc3MuXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPHR5cGVvZiBpbXBvcnQoXCIuLi9mcm9udGVuZC1tb2RlbC1jb250cm9sbGVyLmpzXCIpLmRlZmF1bHQ+fSAtIEZyb250ZW5kIG1vZGVsIGNvbnRyb2xsZXIgY2xhc3MuXG4gICAqL1xuICBhc3luYyBfZnJvbnRlbmRNb2RlbENvbnRyb2xsZXJDbGFzcygpIHtcbiAgICBjb25zdCBmcm9udGVuZE1vZGVsQ29udHJvbGxlclBhdGggPSBcIi4uL2Zyb250ZW5kLW1vZGVsLWNvbnRyb2xsZXIuanNcIlxuICAgIGNvbnN0IHtkZWZhdWx0OiBGcm9udGVuZE1vZGVsQ29udHJvbGxlcn0gPSBhd2FpdCBpbXBvcnQoZnJvbnRlbmRNb2RlbENvbnRyb2xsZXJQYXRoKVxuXG4gICAgcmV0dXJuIEZyb250ZW5kTW9kZWxDb250cm9sbGVyXG4gIH1cblxuICAvKipcbiAgICogUnVucyBmcm9udGVuZCBtb2RlbCBjb250cm9sbGVyLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuLi9mcm9udGVuZC1tb2RlbC1jb250cm9sbGVyLmpzXCIpLmRlZmF1bHR9IEZyb250ZW5kTW9kZWxDb250cm9sbGVyIC0gU2VydmVyLXNpZGUgZnJvbnRlbmQtbW9kZWwgY29udHJvbGxlciBjbGFzcy5cbiAgICogQHBhcmFtIHtSZWNvcmQ8c3RyaW5nLCA/Pn0gW3BhcmFtc10gLSBPcHRpb25hbCBwYXJhbXMgb3ZlcnJpZGUuXG4gICAqIEByZXR1cm5zIHtpbXBvcnQoXCIuLi9mcm9udGVuZC1tb2RlbC1jb250cm9sbGVyLmpzXCIpLmRlZmF1bHR9IC0gU3ludGhldGljIGNvbnRyb2xsZXIgdXNlZCBmb3IgcmVzb3VyY2Ugc2VyaWFsaXphdGlvbi5cbiAgICovXG4gIF9mcm9udGVuZE1vZGVsQ29udHJvbGxlcihGcm9udGVuZE1vZGVsQ29udHJvbGxlciwgcGFyYW1zID0ge30pIHtcbiAgICBjb25zdCBjb25maWd1cmF0aW9uID0gdGhpcy5zZXNzaW9uLmNvbmZpZ3VyYXRpb25cbiAgICBjb25zdCBjb250cm9sbGVyID0gbmV3IEZyb250ZW5kTW9kZWxDb250cm9sbGVyKHtcbiAgICAgIGFjdGlvbjogXCJ3ZWJzb2NrZXRFdmVudFwiLFxuICAgICAgY29uZmlndXJhdGlvbixcbiAgICAgIGNvbnRyb2xsZXI6IFwiZnJvbnRlbmQtbW9kZWxzXCIsXG4gICAgICBwYXJhbXM6IHtcbiAgICAgICAgYWJpbGl0aWVzOiB0aGlzLnBhcmFtcy5hYmlsaXRpZXMsXG4gICAgICAgIGpvaW5zOiB0aGlzLnBhcmFtcy5qb2lucyxcbiAgICAgICAgbW9kZWw6IHRoaXMuX21vZGVsTmFtZSgpLFxuICAgICAgICBwcmVsb2FkOiB0aGlzLnBhcmFtcy5wcmVsb2FkLFxuICAgICAgICBxdWVyeURhdGE6IHRoaXMucGFyYW1zLnF1ZXJ5RGF0YSxcbiAgICAgICAgc2VhcmNoZXM6IHRoaXMucGFyYW1zLnNlYXJjaGVzLFxuICAgICAgICBzZWxlY3Q6IHRoaXMucGFyYW1zLnNlbGVjdCxcbiAgICAgICAgc2VsZWN0c0V4dHJhOiB0aGlzLnBhcmFtcy5zZWxlY3RzRXh0cmEsXG4gICAgICAgIHdoZXJlOiB0aGlzLnBhcmFtcy53aGVyZSxcbiAgICAgICAgLi4ucGFyYW1zLFxuICAgICAgICB3aXRoQ291bnQ6IHRoaXMucGFyYW1zLndpdGhDb3VudFxuICAgICAgfSxcbiAgICAgIHJlcXVlc3Q6IC8qKlxuICAgICAgICAgICAgICAgICogTmFycm93cyB0aGUgcnVudGltZSB2YWx1ZSB0byB0aGUgZG9jdW1lbnRlZCB0eXBlLlxuICAgICAgICAgICAgICAgICBAdHlwZSB7aW1wb3J0KFwiLi4vaHR0cC1zZXJ2ZXIvY2xpZW50L3JlcXVlc3QuanNcIikuZGVmYXVsdH0gKi8gKHRoaXMuX3N5bnRoZXRpY1JlcXVlc3QoKSksXG4gICAgICByZXNwb25zZTogbmV3IFJlc3BvbnNlKHtjb25maWd1cmF0aW9ufSksXG4gICAgICB2aWV3UGF0aDogXCIvXCJcbiAgICB9KVxuXG4gICAgY29udHJvbGxlci5fZnJvbnRlbmRNb2RlbEFiaWxpdHlPdmVycmlkZSA9IHRoaXMuX2FiaWxpdHkgfHwgdW5kZWZpbmVkXG5cbiAgICByZXR1cm4gY29udHJvbGxlclxuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIGJyb2FkY2FzdCByZWNvcmQgaXMgd2l0aGluIHRoZSBzdWJzY3JpYmVyJ3MgYXV0aGVudGljYXRlZCBhYmlsaXR5IHNjb3BlLiBVc2VkIHRvIGdhdGVcbiAgICogdW5maWx0ZXJlZC91bnByb2plY3RlZCBjcmVhdGUvdXBkYXRlIGRlbGl2ZXJ5IHNvIGEgc2NvcGVkIHRva2VuIG5ldmVyIHJlY2VpdmVzIGEgcmVjb3JkIGl0IGNhbm5vdCByZWFkLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlcn0gaWQgLSBFdmVudCByZWNvcmQgaWQuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4uL2Zyb250ZW5kLW1vZGVsLWNvbnRyb2xsZXIuanNcIikuZGVmYXVsdH0gRnJvbnRlbmRNb2RlbENvbnRyb2xsZXIgLSBTZXJ2ZXItc2lkZSBmcm9udGVuZC1tb2RlbCBjb250cm9sbGVyIGNsYXNzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gVHJ1ZSB3aGVuIHRoZSByZWNvcmQgaXMgcmVhZGFibGUgYnkgdGhpcyBzdWJzY3JpcHRpb24uXG4gICAqL1xuICBhc3luYyBfZXZlbnRJc0FjY2Vzc2libGUoaWQsIEZyb250ZW5kTW9kZWxDb250cm9sbGVyKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IHRoaXMuX2Zyb250ZW5kTW9kZWxDb250cm9sbGVyKEZyb250ZW5kTW9kZWxDb250cm9sbGVyKVxuXG4gICAgYXdhaXQgY29udHJvbGxlci5lbnN1cmVGcm9udGVuZE1vZGVsQ2xhc3NJbml0aWFsaXplZCgpXG5cbiAgICBjb25zdCBNb2RlbENsYXNzID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSBNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIGNvbnN0IHF1ZXJ5ID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsQXV0aG9yaXplZFF1ZXJ5KFwiZmluZFwiKS53aGVyZSh7W01vZGVsQ2xhc3MudGFibGVOYW1lKCldOiB7W3ByaW1hcnlLZXldOiBpZH19KVxuXG4gICAgcmV0dXJuIEJvb2xlYW4oYXdhaXQgcXVlcnkuZmlyc3QoKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIG1hdGNoZWQgZXZlbnQgZmlsdGVyIGtleXMgZm9yIGV2ZW50IGlkLlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IG51bWJlcn0gaWQgLSBFdmVudCByZWNvcmQgaWQuXG4gICAqIEBwYXJhbSB7dHlwZW9mIGltcG9ydChcIi4uL2Zyb250ZW5kLW1vZGVsLWNvbnRyb2xsZXIuanNcIikuZGVmYXVsdH0gRnJvbnRlbmRNb2RlbENvbnRyb2xsZXIgLSBTZXJ2ZXItc2lkZSBmcm9udGVuZC1tb2RlbCBjb250cm9sbGVyIGNsYXNzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxzdHJpbmdbXT59IC0gRXZlbnQgZmlsdGVyIGtleXMgbWF0Y2hlZCBieSB0aGUgcmVjb3JkLlxuICAgKi9cbiAgYXN5bmMgX21hdGNoZWRFdmVudEZpbHRlcktleXNGb3JFdmVudElkKGlkLCBGcm9udGVuZE1vZGVsQ29udHJvbGxlcikge1xuICAgIC8qKlxuICAgICAqIE1hdGNoZWQgZXZlbnQgZmlsdGVyIGtleXMuXG4gICAgICBAdHlwZSB7c3RyaW5nW119ICovXG4gICAgY29uc3QgbWF0Y2hlZEV2ZW50RmlsdGVyS2V5cyA9IFtdXG5cbiAgICBmb3IgKGNvbnN0IGV2ZW50RmlsdGVyIG9mIHRoaXMuX2V2ZW50RmlsdGVycygpKSB7XG4gICAgICBjb25zdCBtYXRjaGVzID0gYXdhaXQgdGhpcy5fZXZlbnRNYXRjaGVzRmlsdGVyKHtcbiAgICAgICAgRnJvbnRlbmRNb2RlbENvbnRyb2xsZXIsXG4gICAgICAgIGV2ZW50RmlsdGVyLFxuICAgICAgICBpZFxuICAgICAgfSlcblxuICAgICAgaWYgKG1hdGNoZXMpIG1hdGNoZWRFdmVudEZpbHRlcktleXMucHVzaChldmVudEZpbHRlci5rZXkpXG4gICAgfVxuXG4gICAgcmV0dXJuIG1hdGNoZWRFdmVudEZpbHRlcktleXNcbiAgfVxuXG4gIC8qKlxuICAgKiBSdW5zIGV2ZW50IG1hdGNoZXMgZmlsdGVyLlxuICAgKiBAcGFyYW0ge29iamVjdH0gYXJncyAtIEZpbHRlciBhcmdzLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuLi9mcm9udGVuZC1tb2RlbC1jb250cm9sbGVyLmpzXCIpLmRlZmF1bHR9IGFyZ3MuRnJvbnRlbmRNb2RlbENvbnRyb2xsZXIgLSBTZXJ2ZXItc2lkZSBmcm9udGVuZC1tb2RlbCBjb250cm9sbGVyIGNsYXNzLlxuICAgKiBAcGFyYW0ge2ltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbEV2ZW50RmlsdGVyUGF5bG9hZEVudHJ5fSBhcmdzLmV2ZW50RmlsdGVyIC0gRXZlbnQgZmlsdGVyIHBheWxvYWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBhcmdzLmlkIC0gRXZlbnQgcmVjb3JkIGlkLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxib29sZWFuPn0gV2hldGhlciB0aGUgcmVjb3JkIG1hdGNoZXMgdGhlIGZpbHRlci5cbiAgICovXG4gIGFzeW5jIF9ldmVudE1hdGNoZXNGaWx0ZXIoe0Zyb250ZW5kTW9kZWxDb250cm9sbGVyLCBldmVudEZpbHRlciwgaWR9KSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IHRoaXMuX2Zyb250ZW5kTW9kZWxDb250cm9sbGVyKEZyb250ZW5kTW9kZWxDb250cm9sbGVyLCB7XG4gICAgICBqb2luczogZXZlbnRGaWx0ZXIuam9pbnMsXG4gICAgICBzZWFyY2hlczogZXZlbnRGaWx0ZXIuc2VhcmNoZXMsXG4gICAgICB3aGVyZTogZXZlbnRGaWx0ZXIud2hlcmVcbiAgICB9KVxuXG4gICAgYXdhaXQgY29udHJvbGxlci5lbnN1cmVGcm9udGVuZE1vZGVsQ2xhc3NJbml0aWFsaXplZCgpXG5cbiAgICBjb25zdCBNb2RlbENsYXNzID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSBNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIGNvbnN0IHdoZXJlID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsV2hlcmUoKVxuICAgIGNvbnN0IGpvaW5zID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsSm9pbnMoKVxuICAgIC8vIFN0YXJ0IGZyb20gdGhlIHN1YnNjcmliZXIncyBhdXRob3JpemVkIHNjb3BlIHNvIGEgZmlsdGVyIGNhbiBvbmx5IGV2ZXIgbWF0Y2ggcmVjb3JkcyB0aGVcbiAgICAvLyBzdWJzY3JpcHRpb24ncyBhYmlsaXR5IHBlcm1pdHMgdG8gcmVhZC5cbiAgICBsZXQgcXVlcnkgPSBjb250cm9sbGVyLmZyb250ZW5kTW9kZWxBdXRob3JpemVkUXVlcnkoXCJmaW5kXCIpLndoZXJlKHtbTW9kZWxDbGFzcy50YWJsZU5hbWUoKV06IHtbcHJpbWFyeUtleV06IGlkfX0pXG5cbiAgICBpZiAod2hlcmUpIGNvbnRyb2xsZXIuYXBwbHlGcm9udGVuZE1vZGVsV2hlcmUoe3F1ZXJ5LCB3aGVyZX0pXG4gICAgaWYgKGpvaW5zKSBjb250cm9sbGVyLmFwcGx5RnJvbnRlbmRNb2RlbEpvaW5zKHtqb2lucywgcXVlcnl9KVxuXG4gICAgZm9yIChjb25zdCBzZWFyY2ggb2YgY29udHJvbGxlci5mcm9udGVuZE1vZGVsU2VhcmNoZXMoKSkge1xuICAgICAgY29udHJvbGxlci5hcHBseUZyb250ZW5kTW9kZWxTZWFyY2goe3F1ZXJ5LCBzZWFyY2h9KVxuICAgIH1cblxuICAgIHJldHVybiBCb29sZWFuKGF3YWl0IHF1ZXJ5LmZpcnN0KCkpXG4gIH1cblxuICAvKipcbiAgICogUnVucyBwcm9qZWN0ZWQgcmVjb3JkIGZvciBldmVudCBpZC5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IGlkIC0gRXZlbnQgcmVjb3JkIGlkLlxuICAgKiBAcGFyYW0ge3R5cGVvZiBpbXBvcnQoXCIuLi9mcm9udGVuZC1tb2RlbC1jb250cm9sbGVyLmpzXCIpLmRlZmF1bHR9IEZyb250ZW5kTW9kZWxDb250cm9sbGVyIC0gU2VydmVyLXNpZGUgZnJvbnRlbmQtbW9kZWwgY29udHJvbGxlciBjbGFzcy5cbiAgICogQHJldHVybnMge1Byb21pc2U8UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi9xdWVyeS5qc1wiKS5Gcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWU+IHwgbnVsbD59IC0gU2VyaWFsaXplZCBwcm9qZWN0ZWQgcmVjb3JkLlxuICAgKi9cbiAgYXN5bmMgX3Byb2plY3RlZFJlY29yZEZvckV2ZW50SWQoaWQsIEZyb250ZW5kTW9kZWxDb250cm9sbGVyKSB7XG4gICAgY29uc3QgY29udHJvbGxlciA9IHRoaXMuX2Zyb250ZW5kTW9kZWxDb250cm9sbGVyKEZyb250ZW5kTW9kZWxDb250cm9sbGVyKVxuXG4gICAgYXdhaXQgY29udHJvbGxlci5lbnN1cmVGcm9udGVuZE1vZGVsQ2xhc3NJbml0aWFsaXplZCgpXG5cbiAgICBjb25zdCBNb2RlbENsYXNzID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsQ2xhc3MoKVxuICAgIGNvbnN0IHByaW1hcnlLZXkgPSBNb2RlbENsYXNzLnByaW1hcnlLZXkoKVxuICAgIC8vIFJlbG9hZCB0aHJvdWdoIHRoZSBzdWJzY3JpYmVyJ3MgYXV0aG9yaXplZCBzY29wZSBzbyBwcm9qZWN0ZWQgcmVjb3JkcyBhcmUgb25seSBldmVyIHNlbnQgZm9yXG4gICAgLy8gcm93cyB0aGUgc3Vic2NyaXB0aW9uJ3MgYWJpbGl0eSBwZXJtaXRzIHRvIHJlYWQuXG4gICAgbGV0IHF1ZXJ5ID0gY29udHJvbGxlci5mcm9udGVuZE1vZGVsQXV0aG9yaXplZFF1ZXJ5KFwiZmluZFwiKS53aGVyZSh7W01vZGVsQ2xhc3MudGFibGVOYW1lKCldOiB7W3ByaW1hcnlLZXldOiBpZH19KVxuICAgIGNvbnN0IHByZWxvYWQgPSBjb250cm9sbGVyLmZyb250ZW5kTW9kZWxQcmVsb2FkKClcblxuICAgIGlmIChwcmVsb2FkKSBxdWVyeSA9IHF1ZXJ5LnByZWxvYWQocHJlbG9hZClcblxuICAgIGZvciAoY29uc3QgZW50cnkgb2YgY29udHJvbGxlci5mcm9udGVuZE1vZGVsV2l0aENvdW50KCkpIHtcbiAgICAgIC8qKlxuICAgICAgICogU3BlYy5cbiAgICAgICAgQHR5cGUge1JlY29yZDxzdHJpbmcsIGJvb2xlYW4gfCB7cmVsYXRpb25zaGlwPzogc3RyaW5nLCB3aGVyZT86IFJlY29yZDxzdHJpbmcsIGltcG9ydChcIi4vcXVlcnkuanNcIikuRnJvbnRlbmRNb2RlbFRyYW5zcG9ydFZhbHVlPn0+fSAqL1xuICAgICAgY29uc3Qgc3BlYyA9IHt9XG5cbiAgICAgIHNwZWNbZW50cnkuYXR0cmlidXRlTmFtZV0gPSB7XG4gICAgICAgIHJlbGF0aW9uc2hpcDogZW50cnkucmVsYXRpb25zaGlwTmFtZSxcbiAgICAgICAgd2hlcmU6IGVudHJ5LndoZXJlID8gLyoqXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgaW1wb3J0KFwiLi9xdWVyeS5qc1wiKS5Gcm9udGVuZE1vZGVsVHJhbnNwb3J0VmFsdWU+fSAqLyAoZW50cnkud2hlcmUpIDogdW5kZWZpbmVkXG4gICAgICB9XG4gICAgICBxdWVyeS53aXRoQ291bnQoc3BlYylcbiAgICB9XG5cbiAgICBjb25zdCBxdWVyeURhdGEgPSBjb250cm9sbGVyLmZyb250ZW5kTW9kZWxRdWVyeURhdGEoKVxuXG4gICAgaWYgKHF1ZXJ5RGF0YSAhPT0gbnVsbCkgcXVlcnkucXVlcnlEYXRhKHF1ZXJ5RGF0YSlcblxuICAgIHF1ZXJ5ID0gY29udHJvbGxlci5hcHBseUZyb250ZW5kTW9kZWxUcmFuc2xhdGVkQXR0cmlidXRlUHJlbG9hZHMoe3F1ZXJ5fSlcblxuICAgIGNvbnN0IG1vZGVsID0gYXdhaXQgcXVlcnkuZmlyc3QoKVxuXG4gICAgaWYgKCFtb2RlbCkgcmV0dXJuIG51bGxcblxuICAgIGlmICh0aGlzLnBhcmFtcy5hYmlsaXRpZXMgIT09IHVuZGVmaW5lZCkge1xuICAgICAgYXdhaXQgY29udHJvbGxlci5mcm9udGVuZE1vZGVsQ29tcHV0ZUFiaWxpdGllcyhbbW9kZWxdKVxuICAgIH1cblxuICAgIGNvbnRyb2xsZXIuX2Zyb250ZW5kTW9kZWxBYmlsaXR5T3ZlcnJpZGUgPSB1bmRlZmluZWRcblxuICAgIHJldHVybiBhd2FpdCBjb250cm9sbGVyLmZyb250ZW5kTW9kZWxSZXNvdXJjZUluc3RhbmNlKCkuc2VyaWFsaXplKG1vZGVsLCBcImZpbmRcIilcbiAgfVxuXG4gIC8qKlxuICAgKiBNaW5pbWFsIFJlcXVlc3QtbGlrZSBzdHViIHVzZWQgb25seSBmb3IgYWJpbGl0eSByZXNvbHV0aW9uLiBBdm9pZHNcbiAgICogaW1wb3J0aW5nIGBXZWJzb2NrZXRSZXF1ZXN0YCBoZXJlIGJlY2F1c2UgaXRzIGBub2RlOnF1ZXJ5c3RyaW5nYFxuICAgKiBkZXBlbmRlbmN5IHdvdWxkIHB1bGwgc2VydmVyLW9ubHkgY29kZSBpbnRvIGJyb3dzZXIgYnVuZGxlcyB2aWFcbiAgICogdGhlIGBjb25maWd1cmF0aW9uIOKGkiBsb2dnZXIg4oaSIHdlYnNvY2tldC1wdWJsaXNoZXJzYCBpbXBvcnQgY2hhaW4uXG4gICAqIEhlYWRlciBuYW1lcyBhcmUgbm9ybWFsaXplZCB0byBsb3dlcmNhc2Ugc28gYGhlYWRlcihcImNvb2tpZVwiKWBcbiAgICogZmluZHMgYSB2YWx1ZSByZWdhcmRsZXNzIG9mIHdoZXRoZXIgdGhlIHVwZ3JhZGUtcmVxdWVzdCBoZWFkZXJzXG4gICAqIG1hcCB1c2VzIGBcIkNvb2tpZVwiYCBvciBgXCJjb29raWVcImAuIFNlc3Npb24gbWV0YWRhdGEgc3RheXMgc2VwYXJhdGVcbiAgICogZnJvbSBoZWFkZXJzIGFuZCBpcyBleHBvc2VkIHRocm91Z2ggYG1ldGFkYXRhKC4uLilgIGZvciBhYmlsaXR5XG4gICAqIHJlc29sdmVycyB0aGF0IG5lZWQgd2Vic29ja2V0LWRlbGl2ZXJlZCBzZXNzaW9uIGRhdGEuXG4gICAqIEByZXR1cm5zIHtGcm9udGVuZE1vZGVsV2Vic29ja2V0U3ludGhldGljUmVxdWVzdH0gUmVxdWVzdC1saWtlIG9iamVjdCBmb3IgYWJpbGl0eSByZXNvbHV0aW9uLlxuICAgKi9cbiAgX3N5bnRoZXRpY1JlcXVlc3QoKSB7XG4gICAgY29uc3QgdXBncmFkZVJlcXVlc3QgPSAvKipcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAqIE5hcnJvd3MgdGhlIHJ1bnRpbWUgdmFsdWUgdG8gdGhlIGRvY3VtZW50ZWQgdHlwZS5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgQHR5cGUge0Zyb250ZW5kTW9kZWxXZWJzb2NrZXRVcGdyYWRlUmVxdWVzdH0gKi8gKHRoaXMuc2Vzc2lvbi51cGdyYWRlUmVxdWVzdClcbiAgICBjb25zdCByYXdIZWFkZXJzID0gdHlwZW9mIHVwZ3JhZGVSZXF1ZXN0Py5oZWFkZXJzID09PSBcImZ1bmN0aW9uXCIgPyB1cGdyYWRlUmVxdWVzdC5oZWFkZXJzKCkgOiB7fVxuICAgIGNvbnN0IG1ldGFkYXRhID0gdHlwZW9mIHRoaXMuc2Vzc2lvbi5nZXRNZXRhZGF0YSA9PT0gXCJmdW5jdGlvblwiID8gdGhpcy5zZXNzaW9uLmdldE1ldGFkYXRhKCkgOiB7fVxuICAgIGNvbnN0IHJlbW90ZUFkZHJlc3MgPSB0eXBlb2YgdXBncmFkZVJlcXVlc3Q/LnJlbW90ZUFkZHJlc3MgPT09IFwiZnVuY3Rpb25cIiA/IHVwZ3JhZGVSZXF1ZXN0LnJlbW90ZUFkZHJlc3MoKSA6IHVuZGVmaW5lZFxuICAgIC8qKlxuICAgICAqIEhlYWRlciBtYXAuXG4gICAgICBAdHlwZSB7UmVjb3JkPHN0cmluZywgc3RyaW5nIHwgc3RyaW5nW10gfCB1bmRlZmluZWQ+fSAqL1xuICAgIGNvbnN0IGhlYWRlck1hcCA9IHt9XG5cbiAgICBmb3IgKGNvbnN0IGtleSBvZiBPYmplY3Qua2V5cyhyYXdIZWFkZXJzIHx8IHt9KSkge1xuICAgICAgaGVhZGVyTWFwW2tleS50b0xvd2VyQ2FzZSgpXSA9IHJhd0hlYWRlcnNba2V5XVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICBoZWFkZXJzOiAoKSA9PiBoZWFkZXJNYXAsXG4gICAgICBoZWFkZXI6IChuYW1lKSA9PiBoZWFkZXJNYXBbU3RyaW5nKG5hbWUpLnRvTG93ZXJDYXNlKCldLFxuICAgICAgbWV0YWRhdGE6IChrZXkpID0+IGtleSA9PT0gdW5kZWZpbmVkID8gey4uLm1ldGFkYXRhfSA6IG1ldGFkYXRhW2tleV0sXG4gICAgICBwYXRoOiAoKSA9PiBcIi9mcm9udGVuZC1tb2RlbHNcIixcbiAgICAgIGh0dHBNZXRob2Q6ICgpID0+IFwiUE9TVFwiLFxuICAgICAgcmVtb3RlQWRkcmVzczogKCkgPT4gcmVtb3RlQWRkcmVzcyxcbiAgICAgIG9yaWdpbjogKCkgPT4gaGVhZGVyTWFwLm9yaWdpblxuICAgIH1cbiAgfVxufVxuIl19
|
package/package.json
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
|
|
8
8
|
/**
|
|
9
9
|
* LifecycleCallbackType type.
|
|
10
|
-
* @template
|
|
10
|
+
* @template [T=VelociousDatabaseRecord]
|
|
11
11
|
* @typedef {((model: T) => void | Promise<void>) | string} LifecycleCallbackType
|
|
12
12
|
*/
|
|
13
13
|
|
|
@@ -507,101 +507,101 @@ class VelociousDatabaseRecord {
|
|
|
507
507
|
|
|
508
508
|
/**
|
|
509
509
|
* Runs before validation.
|
|
510
|
-
* @template
|
|
511
|
-
* @this {
|
|
512
|
-
* @param {LifecycleCallbackType<
|
|
510
|
+
* @template R
|
|
511
|
+
* @this {new (...args: Array<?>) => R}
|
|
512
|
+
* @param {LifecycleCallbackType<R>} callback - Callback function or instance method name.
|
|
513
513
|
* @returns {void}
|
|
514
514
|
*/
|
|
515
515
|
static beforeValidation(callback) {
|
|
516
|
-
|
|
516
|
+
VelociousDatabaseRecord.registerLifecycleCallback.call(this, "beforeValidation", /** @type {LifecycleCallbackType} */ (callback))
|
|
517
517
|
}
|
|
518
518
|
|
|
519
519
|
/**
|
|
520
520
|
* Runs before save.
|
|
521
|
-
* @template
|
|
522
|
-
* @this {
|
|
523
|
-
* @param {LifecycleCallbackType<
|
|
521
|
+
* @template R
|
|
522
|
+
* @this {new (...args: Array<?>) => R}
|
|
523
|
+
* @param {LifecycleCallbackType<R>} callback - Callback function or instance method name.
|
|
524
524
|
* @returns {void}
|
|
525
525
|
*/
|
|
526
526
|
static beforeSave(callback) {
|
|
527
|
-
|
|
527
|
+
VelociousDatabaseRecord.registerLifecycleCallback.call(this, "beforeSave", /** @type {LifecycleCallbackType} */ (callback))
|
|
528
528
|
}
|
|
529
529
|
|
|
530
530
|
/**
|
|
531
531
|
* Runs before create.
|
|
532
|
-
* @template
|
|
533
|
-
* @this {
|
|
534
|
-
* @param {LifecycleCallbackType<
|
|
532
|
+
* @template R
|
|
533
|
+
* @this {new (...args: Array<?>) => R}
|
|
534
|
+
* @param {LifecycleCallbackType<R>} callback - Callback function or instance method name.
|
|
535
535
|
* @returns {void}
|
|
536
536
|
*/
|
|
537
537
|
static beforeCreate(callback) {
|
|
538
|
-
|
|
538
|
+
VelociousDatabaseRecord.registerLifecycleCallback.call(this, "beforeCreate", /** @type {LifecycleCallbackType} */ (callback))
|
|
539
539
|
}
|
|
540
540
|
|
|
541
541
|
/**
|
|
542
542
|
* Runs before update.
|
|
543
|
-
* @template
|
|
544
|
-
* @this {
|
|
545
|
-
* @param {LifecycleCallbackType<
|
|
543
|
+
* @template R
|
|
544
|
+
* @this {new (...args: Array<?>) => R}
|
|
545
|
+
* @param {LifecycleCallbackType<R>} callback - Callback function or instance method name.
|
|
546
546
|
* @returns {void}
|
|
547
547
|
*/
|
|
548
548
|
static beforeUpdate(callback) {
|
|
549
|
-
|
|
549
|
+
VelociousDatabaseRecord.registerLifecycleCallback.call(this, "beforeUpdate", /** @type {LifecycleCallbackType} */ (callback))
|
|
550
550
|
}
|
|
551
551
|
|
|
552
552
|
/**
|
|
553
553
|
* Runs before destroy.
|
|
554
|
-
* @template
|
|
555
|
-
* @this {
|
|
556
|
-
* @param {LifecycleCallbackType<
|
|
554
|
+
* @template R
|
|
555
|
+
* @this {new (...args: Array<?>) => R}
|
|
556
|
+
* @param {LifecycleCallbackType<R>} callback - Callback function or instance method name.
|
|
557
557
|
* @returns {void}
|
|
558
558
|
*/
|
|
559
559
|
static beforeDestroy(callback) {
|
|
560
|
-
|
|
560
|
+
VelociousDatabaseRecord.registerLifecycleCallback.call(this, "beforeDestroy", /** @type {LifecycleCallbackType} */ (callback))
|
|
561
561
|
}
|
|
562
562
|
|
|
563
563
|
/**
|
|
564
564
|
* Runs after save.
|
|
565
|
-
* @template
|
|
566
|
-
* @this {
|
|
567
|
-
* @param {LifecycleCallbackType<
|
|
565
|
+
* @template R
|
|
566
|
+
* @this {new (...args: Array<?>) => R}
|
|
567
|
+
* @param {LifecycleCallbackType<R>} callback - Callback function or instance method name.
|
|
568
568
|
* @returns {void}
|
|
569
569
|
*/
|
|
570
570
|
static afterSave(callback) {
|
|
571
|
-
|
|
571
|
+
VelociousDatabaseRecord.registerLifecycleCallback.call(this, "afterSave", /** @type {LifecycleCallbackType} */ (callback))
|
|
572
572
|
}
|
|
573
573
|
|
|
574
574
|
/**
|
|
575
575
|
* Runs after create.
|
|
576
|
-
* @template
|
|
577
|
-
* @this {
|
|
578
|
-
* @param {LifecycleCallbackType<
|
|
576
|
+
* @template R
|
|
577
|
+
* @this {new (...args: Array<?>) => R}
|
|
578
|
+
* @param {LifecycleCallbackType<R>} callback - Callback function or instance method name.
|
|
579
579
|
* @returns {void}
|
|
580
580
|
*/
|
|
581
581
|
static afterCreate(callback) {
|
|
582
|
-
|
|
582
|
+
VelociousDatabaseRecord.registerLifecycleCallback.call(this, "afterCreate", /** @type {LifecycleCallbackType} */ (callback))
|
|
583
583
|
}
|
|
584
584
|
|
|
585
585
|
/**
|
|
586
586
|
* Runs after update.
|
|
587
|
-
* @template
|
|
588
|
-
* @this {
|
|
589
|
-
* @param {LifecycleCallbackType<
|
|
587
|
+
* @template R
|
|
588
|
+
* @this {new (...args: Array<?>) => R}
|
|
589
|
+
* @param {LifecycleCallbackType<R>} callback - Callback function or instance method name.
|
|
590
590
|
* @returns {void}
|
|
591
591
|
*/
|
|
592
592
|
static afterUpdate(callback) {
|
|
593
|
-
|
|
593
|
+
VelociousDatabaseRecord.registerLifecycleCallback.call(this, "afterUpdate", /** @type {LifecycleCallbackType} */ (callback))
|
|
594
594
|
}
|
|
595
595
|
|
|
596
596
|
/**
|
|
597
597
|
* Runs after destroy.
|
|
598
|
-
* @template
|
|
599
|
-
* @this {
|
|
600
|
-
* @param {LifecycleCallbackType<
|
|
598
|
+
* @template R
|
|
599
|
+
* @this {new (...args: Array<?>) => R}
|
|
600
|
+
* @param {LifecycleCallbackType<R>} callback - Callback function or instance method name.
|
|
601
601
|
* @returns {void}
|
|
602
602
|
*/
|
|
603
603
|
static afterDestroy(callback) {
|
|
604
|
-
|
|
604
|
+
VelociousDatabaseRecord.registerLifecycleCallback.call(this, "afterDestroy", /** @type {LifecycleCallbackType} */ (callback))
|
|
605
605
|
}
|
|
606
606
|
|
|
607
607
|
/**
|
|
@@ -115,12 +115,48 @@ export default class DbGenerateModel extends BaseCommand {
|
|
|
115
115
|
velociousPath = "velocious/build/src"
|
|
116
116
|
}
|
|
117
117
|
|
|
118
|
+
const columns = await table.getColumns()
|
|
119
|
+
const writeAttributeTypeName = `${modelNameCamelized}WriteAttributes`
|
|
120
|
+
const nestedWriteAttributes = this.nestedWriteAttributesForModel({modelClass})
|
|
121
|
+
|
|
118
122
|
fileContent += `import DatabaseRecord from "${velociousPath}/database/record/index.js"\n\n`
|
|
123
|
+
fileContent += "/**\n"
|
|
124
|
+
fileContent += ` * Attributes accepted when creating or updating ${modelNameCamelized} records.\n`
|
|
125
|
+
fileContent += ` * @typedef {object} ${writeAttributeTypeName}\n`
|
|
126
|
+
for (const column of columns) {
|
|
127
|
+
const deburredColumnName = deburrColumnName(column.getName())
|
|
128
|
+
const camelizedColumnName = inflection.camelize(deburredColumnName, true)
|
|
129
|
+
const setterJsdocType = this.jsDocSetterTypeFromColumn(column, modelClass)
|
|
130
|
+
|
|
131
|
+
if (setterJsdocType) {
|
|
132
|
+
fileContent += ` * @property {${setterJsdocType}${column.getNull() ? " | null" : ""}} [${camelizedColumnName}] - Value for the ${camelizedColumnName} attribute.\n`
|
|
133
|
+
}
|
|
134
|
+
}
|
|
135
|
+
for (const nestedWriteAttribute of nestedWriteAttributes) {
|
|
136
|
+
fileContent += ` * @property {${nestedWriteAttribute.propertyType}} [${nestedWriteAttribute.propertyName}] - Nested ${nestedWriteAttribute.relationshipName} attributes.\n`
|
|
137
|
+
}
|
|
138
|
+
fileContent += " */\n\n"
|
|
119
139
|
|
|
120
140
|
const hasManyRelationFilePath = `${velociousPath}/database/record/instance-relationships/has-many.js`
|
|
121
141
|
|
|
122
142
|
fileContent += `export default class ${modelNameCamelized}Base extends DatabaseRecord {\n`
|
|
123
143
|
|
|
144
|
+
fileContent += " /**\n"
|
|
145
|
+
fileContent += ` * Creates a ${modelNameCamelized} record.\n`
|
|
146
|
+
fileContent += ` * @template {typeof ${modelNameCamelized}Base} T\n`
|
|
147
|
+
fileContent += " * @this {T}\n"
|
|
148
|
+
fileContent += ` * @param {${writeAttributeTypeName}} [attributes] - Attributes for the new record.\n`
|
|
149
|
+
fileContent += " * @returns {Promise<InstanceType<T>>} - Persisted record.\n"
|
|
150
|
+
fileContent += " */\n"
|
|
151
|
+
fileContent += " static async create(attributes) { return /** @type {Promise<InstanceType<T>>} */ (super.create(attributes)) }\n\n"
|
|
152
|
+
|
|
153
|
+
fileContent += " /**\n"
|
|
154
|
+
fileContent += ` * Updates this ${modelNameCamelized} record.\n`
|
|
155
|
+
fileContent += ` * @param {${writeAttributeTypeName}} attributes - Attributes to assign before saving.\n`
|
|
156
|
+
fileContent += " * @returns {Promise<void>} - Resolves when the record is saved.\n"
|
|
157
|
+
fileContent += " */\n"
|
|
158
|
+
fileContent += " async update(attributes) { return await super.update(attributes) }\n\n"
|
|
159
|
+
|
|
124
160
|
// --- getModelClass() override (fixes polymorphic typing in JS/JSDoc) ---
|
|
125
161
|
if (await fileExists(sourceModelFullFilePath)) {
|
|
126
162
|
// Model file exists (e.g. src/models/ticket.js) → return typeof Ticket
|
|
@@ -138,7 +174,6 @@ export default class DbGenerateModel extends BaseCommand {
|
|
|
138
174
|
fileContent += ` getModelClass() { return /** @type {typeof ${modelNameCamelized}Base} */ (this.constructor) }\n\n`
|
|
139
175
|
}
|
|
140
176
|
|
|
141
|
-
const columns = await table.getColumns()
|
|
142
177
|
let methodsCount = 0
|
|
143
178
|
|
|
144
179
|
for (const column of columns) {
|
|
@@ -416,4 +451,35 @@ export default class DbGenerateModel extends BaseCommand {
|
|
|
416
451
|
|
|
417
452
|
return this.jsDocTypeFromColumn(column, modelClass)
|
|
418
453
|
}
|
|
454
|
+
|
|
455
|
+
/**
|
|
456
|
+
* Runs nested write attributes for model.
|
|
457
|
+
* @param {object} args - Arguments.
|
|
458
|
+
* @param {typeof import("../../../../../database/record/index.js").default} args.modelClass - Model class.
|
|
459
|
+
* @returns {Array<{propertyName: string, propertyType: string, relationshipName: string}>} - Nested write attributes.
|
|
460
|
+
*/
|
|
461
|
+
nestedWriteAttributesForModel({modelClass}) {
|
|
462
|
+
const acceptedNestedAttributes = modelClass._acceptedNestedAttributes || {}
|
|
463
|
+
const nestedWriteAttributes = []
|
|
464
|
+
|
|
465
|
+
for (const relationshipName of Object.keys(acceptedNestedAttributes)) {
|
|
466
|
+
const relationship = modelClass.getRelationshipByName(relationshipName)
|
|
467
|
+
const relationshipType = relationship.getType()
|
|
468
|
+
const targetModelClass = relationship.getTargetModelClass()
|
|
469
|
+
|
|
470
|
+
if (!targetModelClass) throw new Error(`Relationship '${relationshipName}' on '${modelClass.getModelName()}' has no target model class`)
|
|
471
|
+
|
|
472
|
+
const targetModelFileName = inflection.dasherize(inflection.underscore(targetModelClass.getModelName()))
|
|
473
|
+
const targetWriteTypeName = `${inflection.camelize(targetModelClass.getModelName().replaceAll("-", "_"))}WriteAttributes`
|
|
474
|
+
const nestedType = `import("./${targetModelFileName}.js").${targetWriteTypeName}${acceptedNestedAttributes[relationshipName]?.allowDestroy ? " & {_destroy?: boolean}" : ""}`
|
|
475
|
+
|
|
476
|
+
nestedWriteAttributes.push({
|
|
477
|
+
propertyName: `${relationshipName}Attributes`,
|
|
478
|
+
propertyType: relationshipType == "hasMany" ? `Array<${nestedType}>` : nestedType,
|
|
479
|
+
relationshipName
|
|
480
|
+
})
|
|
481
|
+
}
|
|
482
|
+
|
|
483
|
+
return nestedWriteAttributes
|
|
484
|
+
}
|
|
419
485
|
}
|