@pipeline-builder/api-core 4.0.3 → 4.1.0
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/lib/helpers/access-helpers.d.ts +16 -0
- package/lib/helpers/access-helpers.js +27 -7
- package/lib/middleware/auth.d.ts +39 -0
- package/lib/middleware/auth.js +38 -14
- package/lib/middleware/step-up.d.ts +12 -5
- package/lib/middleware/step-up.js +37 -24
- package/lib/utils/index.d.ts +1 -0
- package/lib/utils/index.js +2 -1
- package/lib/utils/secret-encryption.d.ts +23 -7
- package/lib/utils/secret-encryption.js +63 -13
- package/lib/utils/secure-compare.d.ts +15 -0
- package/lib/utils/secure-compare.js +29 -0
- package/package.json +1 -1
|
@@ -35,6 +35,22 @@ export interface VisibilityWriteTarget {
|
|
|
35
35
|
* ```
|
|
36
36
|
*/
|
|
37
37
|
export declare function requireVisibilityWriteAccess(req: Request, res: Response, resource: VisibilityWriteTarget, userId: string, publishPermission: Permission): boolean;
|
|
38
|
+
/** Why a write was refused, or `'ok'`. See {@link checkVisibilityWriteAccess}. */
|
|
39
|
+
export type VisibilityWriteVerdict = 'ok' | 'needs-publish' | 'not-author';
|
|
40
|
+
/**
|
|
41
|
+
* The visibility write rule as a PREDICATE, with no response side-effect.
|
|
42
|
+
*
|
|
43
|
+
* Extracted so BULK routes can apply the identical rule per row instead of
|
|
44
|
+
* re-deriving it. They used to reject anything not `private`, which contradicted
|
|
45
|
+
* this gate: `resolveVisibility` defaults pipelines and plugins to `org`, and
|
|
46
|
+
* this function happily allows an `org` write with plain `:write` — so a bulk
|
|
47
|
+
* delete/update 403'd the default case that single-row delete/update allowed.
|
|
48
|
+
*
|
|
49
|
+
* - `private` → author only
|
|
50
|
+
* - `org` → any member of the org
|
|
51
|
+
* - `public` → requires `publishPermission`
|
|
52
|
+
*/
|
|
53
|
+
export declare function checkVisibilityWriteAccess(req: Request, resource: VisibilityWriteTarget, userId: string, publishPermission: Permission): VisibilityWriteVerdict;
|
|
38
54
|
/**
|
|
39
55
|
* Resolve the effective visibility for an entity being created or updated.
|
|
40
56
|
*
|
|
@@ -30,19 +30,39 @@ import { sendError } from '../utils/response.js';
|
|
|
30
30
|
* ```
|
|
31
31
|
*/
|
|
32
32
|
export function requireVisibilityWriteAccess(req, res, resource, userId, publishPermission) {
|
|
33
|
-
|
|
33
|
+
const verdict = checkVisibilityWriteAccess(req, resource, userId, publishPermission);
|
|
34
|
+
if (verdict === 'ok')
|
|
34
35
|
return true;
|
|
36
|
+
sendError(res, 403, verdict === 'needs-publish'
|
|
37
|
+
? 'You lack permission to modify this public resource.'
|
|
38
|
+
: 'Only the author can modify a private resource.', ErrorCode.INSUFFICIENT_PERMISSIONS);
|
|
39
|
+
return false;
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* The visibility write rule as a PREDICATE, with no response side-effect.
|
|
43
|
+
*
|
|
44
|
+
* Extracted so BULK routes can apply the identical rule per row instead of
|
|
45
|
+
* re-deriving it. They used to reject anything not `private`, which contradicted
|
|
46
|
+
* this gate: `resolveVisibility` defaults pipelines and plugins to `org`, and
|
|
47
|
+
* this function happily allows an `org` write with plain `:write` — so a bulk
|
|
48
|
+
* delete/update 403'd the default case that single-row delete/update allowed.
|
|
49
|
+
*
|
|
50
|
+
* - `private` → author only
|
|
51
|
+
* - `org` → any member of the org
|
|
52
|
+
* - `public` → requires `publishPermission`
|
|
53
|
+
*/
|
|
54
|
+
export function checkVisibilityWriteAccess(req, resource, userId, publishPermission) {
|
|
55
|
+
if (isSystemAdmin(req))
|
|
56
|
+
return 'ok';
|
|
35
57
|
if (resource.visibility === 'public' && !userHasPermission(req, publishPermission)) {
|
|
36
|
-
|
|
37
|
-
return false;
|
|
58
|
+
return 'needs-publish';
|
|
38
59
|
}
|
|
39
60
|
// Fail closed on an anonymous/absent caller — an empty userId must never match
|
|
40
61
|
// an empty `createdBy` and hand over someone else's draft.
|
|
41
62
|
if (resource.visibility === 'private' && (!userId || resource.createdBy !== userId)) {
|
|
42
|
-
|
|
43
|
-
return false;
|
|
63
|
+
return 'not-author';
|
|
44
64
|
}
|
|
45
|
-
return
|
|
65
|
+
return 'ok';
|
|
46
66
|
}
|
|
47
67
|
/**
|
|
48
68
|
* Resolve the effective visibility for an entity being created or updated.
|
|
@@ -79,4 +99,4 @@ export function resolveVisibility(req, requested, publishPermission, fallback =
|
|
|
79
99
|
return 'private';
|
|
80
100
|
return fallback;
|
|
81
101
|
}
|
|
82
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
102
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYWNjZXNzLWhlbHBlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvaGVscGVycy9hY2Nlc3MtaGVscGVycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSwrQ0FBK0M7QUFDL0Msc0NBQXNDO0FBR3RDLE9BQU8sRUFBRSxhQUFhLEVBQUUsaUJBQWlCLEVBQUUsTUFBTSx1QkFBdUIsQ0FBQztBQUN6RSxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFHcEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBVWpEOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBeUJHO0FBQ0gsTUFBTSxVQUFVLDRCQUE0QixDQUMxQyxHQUFZLEVBQ1osR0FBYSxFQUNiLFFBQStCLEVBQy9CLE1BQWMsRUFDZCxpQkFBNkI7SUFFN0IsTUFBTSxPQUFPLEdBQUcsMEJBQTBCLENBQUMsR0FBRyxFQUFFLFFBQVEsRUFBRSxNQUFNLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztJQUNyRixJQUFJLE9BQU8sS0FBSyxJQUFJO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFDbEMsU0FBUyxDQUNQLEdBQUcsRUFDSCxHQUFHLEVBQ0gsT0FBTyxLQUFLLGVBQWU7UUFDekIsQ0FBQyxDQUFDLHFEQUFxRDtRQUN2RCxDQUFDLENBQUMsZ0RBQWdELEVBQ3BELFNBQVMsQ0FBQyx3QkFBd0IsQ0FDbkMsQ0FBQztJQUNGLE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQztBQUtEOzs7Ozs7Ozs7Ozs7R0FZRztBQUNILE1BQU0sVUFBVSwwQkFBMEIsQ0FDeEMsR0FBWSxFQUNaLFFBQStCLEVBQy9CLE1BQWMsRUFDZCxpQkFBNkI7SUFFN0IsSUFBSSxhQUFhLENBQUMsR0FBRyxDQUFDO1FBQUUsT0FBTyxJQUFJLENBQUM7SUFFcEMsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLFFBQVEsSUFBSSxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxFQUFFLENBQUM7UUFDbkYsT0FBTyxlQUFlLENBQUM7SUFDekIsQ0FBQztJQUVELCtFQUErRTtJQUMvRSwyREFBMkQ7SUFDM0QsSUFBSSxRQUFRLENBQUMsVUFBVSxLQUFLLFNBQVMsSUFBSSxDQUFDLENBQUMsTUFBTSxJQUFJLFFBQVEsQ0FBQyxTQUFTLEtBQUssTUFBTSxDQUFDLEVBQUUsQ0FBQztRQUNwRixPQUFPLFlBQVksQ0FBQztJQUN0QixDQUFDO0lBRUQsT0FBTyxJQUFJLENBQUM7QUFDZCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQXdCRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FDL0IsR0FBWSxFQUNaLFNBQTZCLEVBQzdCLGlCQUE2QixFQUM3QixRQUFRLEdBQWUsU0FBUztJQUVoQyxJQUFJLFNBQVMsS0FBSyxRQUFRLEVBQUUsQ0FBQztRQUMzQixPQUFPLGlCQUFpQixDQUFDLEdBQUcsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUN0RSxDQUFDO0lBQ0QsSUFBSSxTQUFTLEtBQUssS0FBSztRQUFFLE9BQU8sS0FBSyxDQUFDO0lBQ3RDLElBQUksU0FBUyxLQUFLLFNBQVM7UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUM5QyxPQUFPLFFBQVEsQ0FBQztBQUNsQixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbmltcG9ydCB0eXBlIHsgUmVxdWVzdCwgUmVzcG9uc2UgfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGlzU3lzdGVtQWRtaW4sIHVzZXJIYXNQZXJtaXNzaW9uIH0gZnJvbSAnLi4vbWlkZGxld2FyZS9hdXRoLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB0eXBlIHsgUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB0eXBlIHsgVmlzaWJpbGl0eSB9IGZyb20gJy4uL3R5cGVzL3Zpc2liaWxpdHkuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG4vKiogVGhlIHNsaWNlIG9mIGEgY2F0YWxvZyBlbnRpdHkgdGhlIHdyaXRlIGdhdGUgbmVlZHMuICovXG5leHBvcnQgaW50ZXJmYWNlIFZpc2liaWxpdHlXcml0ZVRhcmdldCB7XG4gIC8qKiBSdW5nIHRoZSByb3cgY3VycmVudGx5IHNpdHMgYXQg4oCUIHNlZSB7QGxpbmsgVmlzaWJpbGl0eX0uICovXG4gIHZpc2liaWxpdHk/OiBzdHJpbmc7XG4gIC8qKiBBdXRob3IuIFRoZSBvbmx5IG5vbi1hZG1pbiB3aG8gbWF5IHRvdWNoIGEgYHByaXZhdGVgIHJvdy4gKi9cbiAgY3JlYXRlZEJ5Pzogc3RyaW5nO1xufVxuXG4vKipcbiAqIENoZWNrIHdoZXRoZXIgdGhlIGNhbGxlciBtYXkgbW9kaWZ5IGEgY2F0YWxvZyBlbnRpdHksIHBlciBpdHMgdmlzaWJpbGl0eSBydW5nLlxuICogVGhlIHNpbmdsZSB3cml0ZSBnYXRlIGJlaGluZCBldmVyeSBwaXBlbGluZSAvIHBsdWdpbiAvIHRlbXBsYXRlIG11dGF0aW9uLlxuICpcbiAqIC0gYHB1YmxpY2Ag4oCUIGEgc3lzdGVtIGFkbWluLCBvciB0aGUgaG9sZGVyIG9mIGBwdWJsaXNoUGVybWlzc2lvbmAgKHRoZSBzYW1lXG4gKiAgIHBlcm1pc3Npb24gdGhhdCBsZXQgdGhlbSBwdWJsaXNoIGl0IGluIHRoZSBmaXJzdCBwbGFjZSwgc28gd2hvZXZlciBjYW5cbiAqICAgcHVibGlzaCBjYW4gYWxzbyBtYW5hZ2Ugd2hhdCB0aGV5IHB1Ymxpc2hlZClcbiAqIC0gYG9yZ2Ag4oCUIGFueW9uZSB3aG8gZ290IHRoaXMgZmFyOiB0aGUgcmVzb3VyY2UncyBgOndyaXRlYCBwZXJtaXNzaW9uIHBsdXMgdGhlXG4gKiAgIG9yZyBzY29waW5nIHRoZSBjYWxsZXIgYWxyZWFkeSBwYXNzZWQgSVMgdGhlIGdhdGVcbiAqIC0gYHByaXZhdGVgIOKAlCB0aGUgQVVUSE9SIGFsb25lIChwbHVzIHN5c3RlbSBhZG1pbnMpXG4gKlxuICogVGhlIGBwcml2YXRlYCBicmFuY2ggaXMgbG9hZC1iZWFyaW5nIG9uIHRoZSBUT01CU1RPTkUgcGF0aHMgKHJlc3RvcmUgLyBwdXJnZSksXG4gKiB3aGljaCBhcmUgb3JnLXNjb3BlZCByYXRoZXIgdGhhbiB2aXNpYmlsaXR5LXNjb3BlZCBiZWNhdXNlIHNvZnQtZGVsZXRlIGlzIG9uZVxuICogc2hhcmVkIGNvZGUgcGF0aCDigJQgd2l0aG91dCBpdCwgYW55IG9yZyBtZW1iZXIgY291bGQgcmVzdXJyZWN0IHNvbWVvbmUgZWxzZSdzXG4gKiBwZXJzb25hbCBkcmFmdC4gT24gdGhlIGxpdmUgcGF0aHMgdGhlIHJlYWQgcHJlZGljYXRlIGhhcyBhbHJlYWR5IGhpZGRlbiB0aGVcbiAqIHJvdywgbWFraW5nIHRoaXMgZGVmZW5zZSBpbiBkZXB0aC5cbiAqXG4gKiBSZXR1cm5zIGB0cnVlYCBpZiB0aGUgcmVxdWVzdCBtYXkgcHJvY2VlZDsgcmV0dXJucyBgZmFsc2VgIGhhdmluZyBBTFJFQURZIHNlbnRcbiAqIGEgNDAzLlxuICpcbiAqIEBleGFtcGxlXG4gKiBgYGB0eXBlc2NyaXB0XG4gKiBpZiAoIXJlcXVpcmVWaXNpYmlsaXR5V3JpdGVBY2Nlc3MocmVxLCByZXMsIHBpcGVsaW5lLCB1c2VySWQsICdwaXBlbGluZXM6cHVibGlzaCcpKSByZXR1cm47XG4gKiBhd2FpdCBwaXBlbGluZVNlcnZpY2UuZGVsZXRlKGlkLCBvcmdJZCwgdXNlcklkKTtcbiAqIGBgYFxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVZpc2liaWxpdHlXcml0ZUFjY2VzcyhcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICByZXNvdXJjZTogVmlzaWJpbGl0eVdyaXRlVGFyZ2V0LFxuICB1c2VySWQ6IHN0cmluZyxcbiAgcHVibGlzaFBlcm1pc3Npb246IFBlcm1pc3Npb24sXG4pOiBib29sZWFuIHtcbiAgY29uc3QgdmVyZGljdCA9IGNoZWNrVmlzaWJpbGl0eVdyaXRlQWNjZXNzKHJlcSwgcmVzb3VyY2UsIHVzZXJJZCwgcHVibGlzaFBlcm1pc3Npb24pO1xuICBpZiAodmVyZGljdCA9PT0gJ29rJykgcmV0dXJuIHRydWU7XG4gIHNlbmRFcnJvcihcbiAgICByZXMsXG4gICAgNDAzLFxuICAgIHZlcmRpY3QgPT09ICduZWVkcy1wdWJsaXNoJ1xuICAgICAgPyAnWW91IGxhY2sgcGVybWlzc2lvbiB0byBtb2RpZnkgdGhpcyBwdWJsaWMgcmVzb3VyY2UuJ1xuICAgICAgOiAnT25seSB0aGUgYXV0aG9yIGNhbiBtb2RpZnkgYSBwcml2YXRlIHJlc291cmNlLicsXG4gICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgKTtcbiAgcmV0dXJuIGZhbHNlO1xufVxuXG4vKiogV2h5IGEgd3JpdGUgd2FzIHJlZnVzZWQsIG9yIGAnb2snYC4gU2VlIHtAbGluayBjaGVja1Zpc2liaWxpdHlXcml0ZUFjY2Vzc30uICovXG5leHBvcnQgdHlwZSBWaXNpYmlsaXR5V3JpdGVWZXJkaWN0ID0gJ29rJyB8ICduZWVkcy1wdWJsaXNoJyB8ICdub3QtYXV0aG9yJztcblxuLyoqXG4gKiBUaGUgdmlzaWJpbGl0eSB3cml0ZSBydWxlIGFzIGEgUFJFRElDQVRFLCB3aXRoIG5vIHJlc3BvbnNlIHNpZGUtZWZmZWN0LlxuICpcbiAqIEV4dHJhY3RlZCBzbyBCVUxLIHJvdXRlcyBjYW4gYXBwbHkgdGhlIGlkZW50aWNhbCBydWxlIHBlciByb3cgaW5zdGVhZCBvZlxuICogcmUtZGVyaXZpbmcgaXQuIFRoZXkgdXNlZCB0byByZWplY3QgYW55dGhpbmcgbm90IGBwcml2YXRlYCwgd2hpY2ggY29udHJhZGljdGVkXG4gKiB0aGlzIGdhdGU6IGByZXNvbHZlVmlzaWJpbGl0eWAgZGVmYXVsdHMgcGlwZWxpbmVzIGFuZCBwbHVnaW5zIHRvIGBvcmdgLCBhbmRcbiAqIHRoaXMgZnVuY3Rpb24gaGFwcGlseSBhbGxvd3MgYW4gYG9yZ2Agd3JpdGUgd2l0aCBwbGFpbiBgOndyaXRlYCDigJQgc28gYSBidWxrXG4gKiBkZWxldGUvdXBkYXRlIDQwMydkIHRoZSBkZWZhdWx0IGNhc2UgdGhhdCBzaW5nbGUtcm93IGRlbGV0ZS91cGRhdGUgYWxsb3dlZC5cbiAqXG4gKiAgIC0gYHByaXZhdGVgIOKGkiBhdXRob3Igb25seVxuICogICAtIGBvcmdgICAgICDihpIgYW55IG1lbWJlciBvZiB0aGUgb3JnXG4gKiAgIC0gYHB1YmxpY2AgIOKGkiByZXF1aXJlcyBgcHVibGlzaFBlcm1pc3Npb25gXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjaGVja1Zpc2liaWxpdHlXcml0ZUFjY2VzcyhcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXNvdXJjZTogVmlzaWJpbGl0eVdyaXRlVGFyZ2V0LFxuICB1c2VySWQ6IHN0cmluZyxcbiAgcHVibGlzaFBlcm1pc3Npb246IFBlcm1pc3Npb24sXG4pOiBWaXNpYmlsaXR5V3JpdGVWZXJkaWN0IHtcbiAgaWYgKGlzU3lzdGVtQWRtaW4ocmVxKSkgcmV0dXJuICdvayc7XG5cbiAgaWYgKHJlc291cmNlLnZpc2liaWxpdHkgPT09ICdwdWJsaWMnICYmICF1c2VySGFzUGVybWlzc2lvbihyZXEsIHB1Ymxpc2hQZXJtaXNzaW9uKSkge1xuICAgIHJldHVybiAnbmVlZHMtcHVibGlzaCc7XG4gIH1cblxuICAvLyBGYWlsIGNsb3NlZCBvbiBhbiBhbm9ueW1vdXMvYWJzZW50IGNhbGxlciDigJQgYW4gZW1wdHkgdXNlcklkIG11c3QgbmV2ZXIgbWF0Y2hcbiAgLy8gYW4gZW1wdHkgYGNyZWF0ZWRCeWAgYW5kIGhhbmQgb3ZlciBzb21lb25lIGVsc2UncyBkcmFmdC5cbiAgaWYgKHJlc291cmNlLnZpc2liaWxpdHkgPT09ICdwcml2YXRlJyAmJiAoIXVzZXJJZCB8fCByZXNvdXJjZS5jcmVhdGVkQnkgIT09IHVzZXJJZCkpIHtcbiAgICByZXR1cm4gJ25vdC1hdXRob3InO1xuICB9XG5cbiAgcmV0dXJuICdvayc7XG59XG5cbi8qKlxuICogUmVzb2x2ZSB0aGUgZWZmZWN0aXZlIHZpc2liaWxpdHkgZm9yIGFuIGVudGl0eSBiZWluZyBjcmVhdGVkIG9yIHVwZGF0ZWQuXG4gKlxuICogYHB1YmxpY2AgcmVxdWlyZXMgdGhlIHB1Ymxpc2ggY2FwYWJpbGl0eSAoc3VwZXJhZG1pbnMgcGFzcyB2aWEgaW1wbGljaXQtYWxsKTtcbiAqIGEgY2FsbGVyIHdobyBhc2tzIGZvciBpdCB3aXRob3V0IHRoZSBwZXJtaXNzaW9uIGlzIGNsYW1wZWQgdG8gYG9yZ2AgcmF0aGVyXG4gKiB0aGFuIGRyb3BwZWQgdG8gYSBwZXJzb25hbCBkcmFmdCDigJQgdGhleSBhc2tlZCB0byBTSEFSRSBpdCwgYW5kIGBvcmdgIGlzIHRoZVxuICogd2lkZXN0IHJ1bmcgdGhleSBhcmUgZW50aXRsZWQgdG8uIEFueXRoaW5nIGVsc2UgcGFzc2VzIHRocm91Z2guXG4gKlxuICogYGZhbGxiYWNrYCBpcyB0aGUgcnVuZyBhbiBVTlNQRUNJRklFRCB2aXNpYmlsaXR5IGxhbmRzIG9uLCBhbmQgaXQgaXNcbiAqIGRlbGliZXJhdGVseSBwZXItZW50aXR5IGV2ZW4gdGhvdWdoIHRoZSBsYWRkZXIgaXRzZWxmIGlzIGlkZW50aWNhbCBldmVyeXdoZXJlOlxuICpcbiAqIC0gKip0ZW1wbGF0ZXMqKiBkZWZhdWx0IHRvIGBwcml2YXRlYCDigJQgZHJhZnQtZmlyc3QgaXMgdGhlIHdob2xlIHBvaW50IG9mIHRoZVxuICogICBwZXJzb25hbCBydW5nOyB5b3UgcG9saXNoIGEgc3RhcnRlciBiZWZvcmUgcHVibGlzaGluZyBpdC5cbiAqIC0gKipwaXBlbGluZXMgLyBwbHVnaW5zKiogZGVmYXVsdCB0byBgb3JnYCDigJQgdGhleSBhcmUgdGVhbSBhc3NldHMgdGhhdCBkZXBsb3lcbiAqICAgc2hhcmVkIGluZnJhc3RydWN0dXJlLCBzbyBjcmVhdGluZyBvbmUgbXVzdCBub3QgaGlkZSBpdCBmcm9tIHRoZSB0ZWFtLiBBXG4gKiAgIHBlcnNvbmFsIGRyYWZ0IHN0YXlzIGF2YWlsYWJsZSwgYnV0IG9wdC1pbi5cbiAqXG4gKiBTYW1lIGxhZGRlciwgc2FtZSBnYXRlLCBkaWZmZXJlbnQgY2VudHJlIG9mIGdyYXZpdHkg4oCUIGV4cHJlc3NlZCBhcyBhbiBhcmd1bWVudFxuICogcmF0aGVyIHRoYW4gYSBzZWNvbmQgY29kZSBwYXRoLlxuICpcbiAqIFBlcm1pc3Npb24tYmFzZWQgKG5vdCBjb2Fyc2Utcm9sZS1iYXNlZCk6IGEgYmVzcG9rZSBjdXN0b20gUm9sZSBjYW4gYmUgZ3JhbnRlZFxuICogcHVibGlzaCByaWdodHMgYW5kIGlzIG5vIGxvbmdlciBmb3JjZWQgcHJpdmF0ZSBieSBpdHMgYG1lbWJlcmAgbGFiZWwuIEJ1aWx0LWluXG4gKiBBZG1pbi9Pd25lciBidW5kbGVzIGNhcnJ5IHRoZSBwdWJsaXNoIHBlcm1pc3Npb25zOyB0aGUgYnVpbHQtaW4gTWVtYmVyIGJ1bmRsZVxuICogZG9lcyBub3QsIHNvIG1lbWJlcnMgdG9wIG91dCBhdCBgb3JnYC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlc29sdmVWaXNpYmlsaXR5KFxuICByZXE6IFJlcXVlc3QsXG4gIHJlcXVlc3RlZDogc3RyaW5nIHwgdW5kZWZpbmVkLFxuICBwdWJsaXNoUGVybWlzc2lvbjogUGVybWlzc2lvbixcbiAgZmFsbGJhY2s6IFZpc2liaWxpdHkgPSAncHJpdmF0ZScsXG4pOiBWaXNpYmlsaXR5IHtcbiAgaWYgKHJlcXVlc3RlZCA9PT0gJ3B1YmxpYycpIHtcbiAgICByZXR1cm4gdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwdWJsaXNoUGVybWlzc2lvbikgPyAncHVibGljJyA6ICdvcmcnO1xuICB9XG4gIGlmIChyZXF1ZXN0ZWQgPT09ICdvcmcnKSByZXR1cm4gJ29yZyc7XG4gIGlmIChyZXF1ZXN0ZWQgPT09ICdwcml2YXRlJykgcmV0dXJuICdwcml2YXRlJztcbiAgcmV0dXJuIGZhbGxiYWNrO1xufVxuIl19
|
package/lib/middleware/auth.d.ts
CHANGED
|
@@ -1,5 +1,44 @@
|
|
|
1
1
|
import type { Request, Response, NextFunction } from 'express';
|
|
2
|
+
import jwt from 'jsonwebtoken';
|
|
3
|
+
import type { JwtPayload } from '../types/common.js';
|
|
2
4
|
import { type Permission } from '../types/permissions.js';
|
|
5
|
+
/**
|
|
6
|
+
* Test-only: drop the cached JWT secrets so the next verify re-reads the env.
|
|
7
|
+
*
|
|
8
|
+
* Both secrets are cached for {@link JWT_SECRET_REFRESH_INTERVAL_MS}, so a test
|
|
9
|
+
* that sets `JWT_SECRET`/`JWT_SECRET_PREVIOUS` mid-run would otherwise keep
|
|
10
|
+
* verifying against the values read on first use. Don't call from production
|
|
11
|
+
* code — rotation is picked up by the refresh interval.
|
|
12
|
+
*/
|
|
13
|
+
export declare function _resetJwtSecretCacheForTests(): void;
|
|
14
|
+
/**
|
|
15
|
+
* The JWT verify options every token check in the fleet must share: pinned
|
|
16
|
+
* algorithm (blocks alg-confusion / `alg:none`) plus issuer/audience when the
|
|
17
|
+
* deployment configures them.
|
|
18
|
+
*
|
|
19
|
+
* Centralized because it was built inline at each call site and `step-up.ts`
|
|
20
|
+
* re-implemented it WITHOUT the issuer/audience pinning — so in a deployment
|
|
21
|
+
* that sets `JWT_ISSUER`/`JWT_AUDIENCE`, a step-up token minted by any other
|
|
22
|
+
* system sharing `JWT_SECRET` was accepted.
|
|
23
|
+
*/
|
|
24
|
+
export declare function buildJwtVerifyOptions(): jwt.VerifyOptions;
|
|
25
|
+
/**
|
|
26
|
+
* Verify a JWT against the primary secret, falling back to the previous secret
|
|
27
|
+
* (when `JWT_SECRET_PREVIOUS` is configured) ONLY on a signature/verification
|
|
28
|
+
* failure. This makes token verification survive a secret rotation with zero
|
|
29
|
+
* downtime: a token valid under EITHER secret passes.
|
|
30
|
+
*
|
|
31
|
+
* jsonwebtoken's `verify` takes a single secret, so this is try-primary-then-
|
|
32
|
+
* previous — NOT a secret array. No existing check is weakened:
|
|
33
|
+
* - `verifyOptions` (algorithm pinning + optional issuer/audience) is applied
|
|
34
|
+
* identically on BOTH attempts, so alg-confusion / `alg:none` stay blocked.
|
|
35
|
+
* - Expiry / not-before from the PRIMARY attempt are authoritative and are
|
|
36
|
+
* re-thrown without a previous-secret retry, so a `TokenExpiredError` is
|
|
37
|
+
* never masked into an "invalid signature".
|
|
38
|
+
* - When no previous secret is set, behaviour is byte-for-byte the original:
|
|
39
|
+
* the primary error propagates unchanged.
|
|
40
|
+
*/
|
|
41
|
+
export declare function verifyJwtWithRotation(token: string, verifyOptions: jwt.VerifyOptions): JwtPayload;
|
|
3
42
|
export interface RequireAuthOptions {
|
|
4
43
|
/**
|
|
5
44
|
* Allow x-org-id/x-org-name headers to override the JWT's organization fields.
|
package/lib/middleware/auth.js
CHANGED
|
@@ -51,6 +51,40 @@ function getJwtSecretPrevious() {
|
|
|
51
51
|
}
|
|
52
52
|
return _jwtSecretPrevious;
|
|
53
53
|
}
|
|
54
|
+
/**
|
|
55
|
+
* Test-only: drop the cached JWT secrets so the next verify re-reads the env.
|
|
56
|
+
*
|
|
57
|
+
* Both secrets are cached for {@link JWT_SECRET_REFRESH_INTERVAL_MS}, so a test
|
|
58
|
+
* that sets `JWT_SECRET`/`JWT_SECRET_PREVIOUS` mid-run would otherwise keep
|
|
59
|
+
* verifying against the values read on first use. Don't call from production
|
|
60
|
+
* code — rotation is picked up by the refresh interval.
|
|
61
|
+
*/
|
|
62
|
+
export function _resetJwtSecretCacheForTests() {
|
|
63
|
+
_jwtSecret = undefined;
|
|
64
|
+
_jwtSecretRefreshedAt = 0;
|
|
65
|
+
_jwtSecretPrevious = undefined;
|
|
66
|
+
_jwtSecretPreviousRefreshedAt = 0;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* The JWT verify options every token check in the fleet must share: pinned
|
|
70
|
+
* algorithm (blocks alg-confusion / `alg:none`) plus issuer/audience when the
|
|
71
|
+
* deployment configures them.
|
|
72
|
+
*
|
|
73
|
+
* Centralized because it was built inline at each call site and `step-up.ts`
|
|
74
|
+
* re-implemented it WITHOUT the issuer/audience pinning — so in a deployment
|
|
75
|
+
* that sets `JWT_ISSUER`/`JWT_AUDIENCE`, a step-up token minted by any other
|
|
76
|
+
* system sharing `JWT_SECRET` was accepted.
|
|
77
|
+
*/
|
|
78
|
+
export function buildJwtVerifyOptions() {
|
|
79
|
+
const verifyOptions = {
|
|
80
|
+
algorithms: [(process.env.JWT_ALGORITHM || 'HS256')],
|
|
81
|
+
};
|
|
82
|
+
if (process.env.JWT_ISSUER)
|
|
83
|
+
verifyOptions.issuer = process.env.JWT_ISSUER;
|
|
84
|
+
if (process.env.JWT_AUDIENCE)
|
|
85
|
+
verifyOptions.audience = process.env.JWT_AUDIENCE;
|
|
86
|
+
return verifyOptions;
|
|
87
|
+
}
|
|
54
88
|
/**
|
|
55
89
|
* Verify a JWT against the primary secret, falling back to the previous secret
|
|
56
90
|
* (when `JWT_SECRET_PREVIOUS` is configured) ONLY on a signature/verification
|
|
@@ -67,7 +101,7 @@ function getJwtSecretPrevious() {
|
|
|
67
101
|
* - When no previous secret is set, behaviour is byte-for-byte the original:
|
|
68
102
|
* the primary error propagates unchanged.
|
|
69
103
|
*/
|
|
70
|
-
function verifyJwtWithRotation(token, verifyOptions) {
|
|
104
|
+
export function verifyJwtWithRotation(token, verifyOptions) {
|
|
71
105
|
try {
|
|
72
106
|
return jwt.verify(token, getJwtSecret(), verifyOptions);
|
|
73
107
|
}
|
|
@@ -171,13 +205,7 @@ function _requireAuth(options, req, res, next) {
|
|
|
171
205
|
// verify — the classic alg-confusion vector (and a hard guard against
|
|
172
206
|
// `alg:none`). Env-driven so it stays in lockstep with how tokens are
|
|
173
207
|
// signed (see signServiceToken + platform's config.auth.jwt.algorithm).
|
|
174
|
-
const verifyOptions =
|
|
175
|
-
const expectedIssuer = process.env.JWT_ISSUER;
|
|
176
|
-
const expectedAudience = process.env.JWT_AUDIENCE;
|
|
177
|
-
if (expectedIssuer)
|
|
178
|
-
verifyOptions.issuer = expectedIssuer;
|
|
179
|
-
if (expectedAudience)
|
|
180
|
-
verifyOptions.audience = expectedAudience;
|
|
208
|
+
const verifyOptions = buildJwtVerifyOptions();
|
|
181
209
|
const decoded = verifyJwtWithRotation(parts[1], verifyOptions);
|
|
182
210
|
if (decoded.type !== 'access') {
|
|
183
211
|
return sendError(res, HttpStatus.UNAUTHORIZED, 'Only access tokens can be used for API requests', ErrorCode.TOKEN_INVALID);
|
|
@@ -568,11 +596,7 @@ export function verifyServicePrincipal(req) {
|
|
|
568
596
|
if (!parts || parts.length !== 2 || parts[0] !== 'Bearer')
|
|
569
597
|
return false;
|
|
570
598
|
try {
|
|
571
|
-
const verifyOptions =
|
|
572
|
-
if (process.env.JWT_ISSUER)
|
|
573
|
-
verifyOptions.issuer = process.env.JWT_ISSUER;
|
|
574
|
-
if (process.env.JWT_AUDIENCE)
|
|
575
|
-
verifyOptions.audience = process.env.JWT_AUDIENCE;
|
|
599
|
+
const verifyOptions = buildJwtVerifyOptions();
|
|
576
600
|
const decoded = verifyJwtWithRotation(parts[1], verifyOptions);
|
|
577
601
|
if (decoded.type !== 'access' || typeof decoded.sub !== 'string' || !decoded.sub.startsWith('service:'))
|
|
578
602
|
return false;
|
|
@@ -585,4 +609,4 @@ export function verifyServicePrincipal(req) {
|
|
|
585
609
|
return false;
|
|
586
610
|
}
|
|
587
611
|
}
|
|
588
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL2F1dGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRXBDLE9BQU8sR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUMvQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFekQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBbUIsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxXQUFXLEVBQXdCLE1BQU0sc0JBQXNCLENBQUM7QUFDekUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFakQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFFL0MsNERBQTREO0FBQzVELElBQUksVUFBOEIsQ0FBQztBQUNuQyxJQUFJLHFCQUFxQixHQUFHLENBQUMsQ0FBQztBQUM5Qiw4RUFBOEU7QUFDOUUsSUFBSSxrQkFBc0MsQ0FBQztBQUMzQyxJQUFJLDZCQUE2QixHQUFHLENBQUMsQ0FBQztBQUN0QyxNQUFNLDhCQUE4QixHQUFHLE9BQU8sQ0FBQyxDQUFDLFlBQVk7QUFFNUQsU0FBUyxZQUFZO0lBQ25CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN2QixJQUFJLENBQUMsVUFBVSxJQUFJLEdBQUcsR0FBRyxxQkFBcUIsR0FBRyw4QkFBOEIs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Q0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksT0FBTyxPQUFPLENBQUMsR0FBRyxLQUFLLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3RILDZFQUE2RTtRQUM3RSxnRkFBZ0Y7UUFDaEYsdUVBQXVFO1FBQ3ZFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlLCBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcbmltcG9ydCBqd3QgZnJvbSAnanNvbndlYnRva2VuJztcbmltcG9ydCB7IEh0dHBTdGF0dXMgfSBmcm9tICcuLi9jb25zdGFudHMvaHR0cC1zdGF0dXMuanMnO1xuaW1wb3J0IHR5cGUgeyBKd3RQYXlsb2FkIH0gZnJvbSAnLi4vdHlwZXMvY29tbW9uLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB0eXBlIHsgSHR0cFJlcXVlc3QgfSBmcm9tICcuLi90eXBlcy9odHRwLmpzJztcbmltcG9ydCB7IHR5cGUgUGVybWlzc2lvbiwgaGFzUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IGdldEhlYWRlclN0cmluZyB9IGZyb20gJy4uL3V0aWxzL2hlYWRlcnMuanMnO1xuaW1wb3J0IHsgZ2V0SWRlbnRpdHksIHR5cGUgUmVxdWVzdElkZW50aXR5IH0gZnJvbSAnLi4vdXRpbHMvaWRlbnRpdHkuanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2F1dGgtbWlkZGxld2FyZScpO1xuXG4vKiogQ2FjaGVkIEpXVCBzZWNyZXQgd2l0aCBwZXJpb2RpYyByZWZyZXNoIGZyb20gZW52IHZhci4gKi9cbmxldCBfand0U2VjcmV0OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5sZXQgX2p3dFNlY3JldFJlZnJlc2hlZEF0ID0gMDtcbi8qKiBDYWNoZWQgUFJFVklPVVMgSldUIHNlY3JldCAob3B0aW9uYWwpIOKAlCBlbmFibGVzIHplcm8tZG93bnRpbWUgcm90YXRpb24uICovXG5sZXQgX2p3dFNlY3JldFByZXZpb3VzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5sZXQgX2p3dFNlY3JldFByZXZpb3VzUmVmcmVzaGVkQXQgPSAwO1xuY29uc3QgSldUX1NFQ1JFVF9SRUZSRVNIX0lOVEVSVkFMX01TID0gMzAwXzAwMDsgLy8gNSBtaW51dGVzXG5cbmZ1bmN0aW9uIGdldEp3dFNlY3JldCgpOiBzdHJpbmcge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBpZiAoIV9qd3RTZWNyZXQgfHwgbm93IC0gX2p3dFNlY3JldFJlZnJlc2hlZEF0ID4gSldUX1NFQ1JFVF9SRUZSRVNIX0lOVEVSVkFMX01TKSB7XG4gICAgY29uc3Qgc2VjcmV0ID0gcHJvY2Vzcy5lbnYuSldUX1NFQ1JFVDtcbiAgICBpZiAoIXNlY3JldCkge1xuICAgICAgbG9nZ2VyLmVycm9yKCdKV1RfU0VDUkVUIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBzZXQnKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSldUX1NFQ1JFVCBlbnZpcm9ubWVudCB2YXJpYWJsZSBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBpZiAoX2p3dFNlY3JldCAmJiBfand0U2VjcmV0ICE9PSBzZWNyZXQpIHtcbiAgICAgIGxvZ2dlci5pbmZvKCdKV1Qgc2VjcmV0IHJvdGF0ZWQnKTtcbiAgICB9XG4gICAgX2p3dFNlY3JldCA9IHNlY3JldDtcbiAgICBfand0U2VjcmV0UmVmcmVzaGVkQXQgPSBub3c7XG4gIH1cbiAgcmV0dXJuIF9qd3RTZWNyZXQ7XG59XG5cbi8qKlxuICogVGhlIG9wdGlvbmFsIFBSRVZJT1VTIEpXVCBzZWNyZXQgKGBKV1RfU0VDUkVUX1BSRVZJT1VTYCksIGNhY2hlZCB3aXRoIHRoZSBzYW1lXG4gKiBUVEwgYXMgdGhlIHByaW1hcnkuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB1bnNldC4gRHVyaW5nIGEgYEpXVF9TRUNSRVRgXG4gKiByb3RhdGlvbiwgb3BlcmF0b3JzIHNldCBgSldUX1NFQ1JFVF9QUkVWSU9VU2AgdG8gdGhlIG9sZCB2YWx1ZSBzbyB0b2tlbnMgc2lnbmVkXG4gKiB3aXRoIEVJVEhFUiBzZWNyZXQga2VlcCB2ZXJpZnlpbmcg4oCUIGNsb3NpbmcgdGhlIGF1dGgtb3V0YWdlIHdpbmRvdyB3aGVyZVxuICogc3RpbGwtdmFsaWQgb2xkLXNpZ25lZCAob3IgZnJlc2hseSBuZXctc2lnbmVkKSB0b2tlbnMgd291bGQgb3RoZXJ3aXNlIGJlXG4gKiByZWplY3RlZC4gYHVuZGVmaW5lZGAgaXMgYSB2YWxpZCBjYWNoZWQgdmFsdWUsIHNvIHRoaXMgcmVmcmVzaGVzIHB1cmVseSBvbiB0aGVcbiAqIHRpbWUgaW50ZXJ2YWwgKG5vdCBvbiBlbXB0aW5lc3MpLlxuICovXG5mdW5jdGlvbiBnZXRKd3RTZWNyZXRQcmV2aW91cygpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBpZiAobm93IC0gX2p3dFNlY3JldFByZXZpb3VzUmVmcmVzaGVkQXQgPiBKV1RfU0VDUkVUX1JFRlJFU0hfSU5URVJWQUxfTVMpIHtcbiAgICBfand0U2VjcmV0UHJldmlvdXMgPSBwcm9jZXNzLmVudi5KV1RfU0VDUkVUX1BSRVZJT1VTIHx8IHVuZGVmaW5lZDtcbiAgICBfand0U2VjcmV0UHJldmlvdXNSZWZyZXNoZWRBdCA9IG5vdztcbiAgfVxuICByZXR1cm4gX2p3dFNlY3JldFByZXZpb3VzO1xufVxuXG4vKipcbiAqIFZlcmlmeSBhIEpXVCBhZ2FpbnN0IHRoZSBwcmltYXJ5IHNlY3JldCwgZmFsbGluZyBiYWNrIHRvIHRoZSBwcmV2aW91cyBzZWNyZXRcbiAqICh3aGVuIGBKV1RfU0VDUkVUX1BSRVZJT1VTYCBpcyBjb25maWd1cmVkKSBPTkxZIG9uIGEgc2lnbmF0dXJlL3ZlcmlmaWNhdGlvblxuICogZmFpbHVyZS4gVGhpcyBtYWtlcyB0b2tlbiB2ZXJpZmljYXRpb24gc3Vydml2ZSBhIHNlY3JldCByb3RhdGlvbiB3aXRoIHplcm9cbiAqIGRvd250aW1lOiBhIHRva2VuIHZhbGlkIHVuZGVyIEVJVEhFUiBzZWNyZXQgcGFzc2VzLlxuICpcbiAqIGpzb253ZWJ0b2tlbidzIGB2ZXJpZnlgIHRha2VzIGEgc2luZ2xlIHNlY3JldCwgc28gdGhpcyBpcyB0cnktcHJpbWFyeS10aGVuLVxuICogcHJldmlvdXMg4oCUIE5PVCBhIHNlY3JldCBhcnJheS4gTm8gZXhpc3RpbmcgY2hlY2sgaXMgd2Vha2VuZWQ6XG4gKiAgIC0gYHZlcmlmeU9wdGlvbnNgIChhbGdvcml0aG0gcGlubmluZyArIG9wdGlvbmFsIGlzc3Vlci9hdWRpZW5jZSkgaXMgYXBwbGllZFxuICogICAgIGlkZW50aWNhbGx5IG9uIEJPVEggYXR0ZW1wdHMsIHNvIGFsZy1jb25mdXNpb24gLyBgYWxnOm5vbmVgIHN0YXkgYmxvY2tlZC5cbiAqICAgLSBFeHBpcnkgLyBub3QtYmVmb3JlIGZyb20gdGhlIFBSSU1BUlkgYXR0ZW1wdCBhcmUgYXV0aG9yaXRhdGl2ZSBhbmQgYXJlXG4gKiAgICAgcmUtdGhyb3duIHdpdGhvdXQgYSBwcmV2aW91cy1zZWNyZXQgcmV0cnksIHNvIGEgYFRva2VuRXhwaXJlZEVycm9yYCBpc1xuICogICAgIG5ldmVyIG1hc2tlZCBpbnRvIGFuIFwiaW52YWxpZCBzaWduYXR1cmVcIi5cbiAqICAgLSBXaGVuIG5vIHByZXZpb3VzIHNlY3JldCBpcyBzZXQsIGJlaGF2aW91ciBpcyBieXRlLWZvci1ieXRlIHRoZSBvcmlnaW5hbDpcbiAqICAgICB0aGUgcHJpbWFyeSBlcnJvciBwcm9wYWdhdGVzIHVuY2hhbmdlZC5cbiAqL1xuZnVuY3Rpb24gdmVyaWZ5Snd0V2l0aFJvdGF0aW9uKHRva2VuOiBzdHJpbmcsIHZlcmlmeU9wdGlvbnM6IGp3dC5WZXJpZnlPcHRpb25zKTogSnd0UGF5bG9hZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGp3dC52ZXJpZnkodG9rZW4sIGdldEp3dFNlY3JldCgpLCB2ZXJpZnlPcHRpb25zKSBhcyBKd3RQYXlsb2FkO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IGdldEp3dFNlY3JldFByZXZpb3VzKCk7XG4gICAgLy8gRmFsbCBiYWNrIHRvIHRoZSBwcmV2aW91cyBzZWNyZXQgb25seSBmb3IgYSBzaWduYXR1cmUvdmVyaWZpY2F0aW9uIGZhaWx1cmVcbiAgICAvLyAoYSBwbGFpbiBKc29uV2ViVG9rZW5FcnJvcikuIEV4cGlyeSAvIG5vdC1iZWZvcmUgYXJlIGVuZm9yY2VkIHJlZ2FyZGxlc3Mgb2ZcbiAgICAvLyB3aGljaCBzZWNyZXQgc2lnbmVkIHRoZSB0b2tlbiwgc28gdGhvc2UgZXJyb3JzIG11c3Qgc3VyZmFjZSBhcy1pcy5cbiAgICBpZiAoXG4gICAgICBwcmV2aW91c1xuICAgICAgJiYgZXJyIGluc3RhbmNlb2Ygand0Lkpzb25XZWJUb2tlbkVycm9yXG4gICAgICAmJiAhKGVyciBpbnN0YW5jZW9mIGp3dC5Ub2tlbkV4cGlyZWRFcnJvcilcbiAgICAgICYmICEoZXJyIGluc3RhbmNlb2Ygand0Lk5vdEJlZm9yZUVycm9yKVxuICAgICkge1xuICAgICAgLy8gQSB0b2tlbiBzaWduZWQgYnkgdGhlIHByZXZpb3VzIHNlY3JldCB2ZXJpZmllcyBoZXJlOyBpZiBpdCBpcyBpbnN0ZWFkXG4gICAgICAvLyBleHBpcmVkL2ludmFsaWQgdW5kZXIgdGhlIHByZXZpb3VzIHNlY3JldCwgdGhhdCBlcnJvciBwcm9wYWdhdGVzIGFuZCBpc1xuICAgICAgLy8gaGFuZGxlZCBieSB0aGUgY2FsbGVyIGV4YWN0bHkgbGlrZSBhIHByaW1hcnkgZmFpbHVyZS5cbiAgICAgIHJldHVybiBqd3QudmVyaWZ5KHRva2VuLCBwcmV2aW91cywgdmVyaWZ5T3B0aW9ucykgYXMgSnd0UGF5bG9hZDtcbiAgICB9XG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWlyZUF1dGhPcHRpb25zIHtcbiAgLyoqXG4gICAqIEFsbG93IHgtb3JnLWlkL3gtb3JnLW5hbWUgaGVhZGVycyB0byBvdmVycmlkZSB0aGUgSldUJ3Mgb3JnYW5pemF0aW9uIGZpZWxkcy5cbiAgICpcbiAgICogV2hlbiBlbmFibGVkLCB0aGUgYHgtb3JnLWlkYC9geC1vcmctbmFtZWAgaGVhZGVycyBvdmVycmlkZSB0aGUgY2FsbGVyJ3Mgb3JnXG4gICAqIOKAlCBidXQgT05MWSBmb3IgYSB2ZXJpZmllZCBTWVMtQURNSU4gKGBpc1N1cGVyQWRtaW5gIGNsYWltKS4gRm9yIGFueSBvcmRpbmFyeVxuICAgKiBhdXRoZW50aWNhdGVkIHVzZXIgdGhlIGhlYWRlcnMgYXJlIGlnbm9yZWQsIHNvIGVuYWJsaW5nIHRoaXMgY2FuIG5ldmVyIGxldCBhXG4gICAqIG5vcm1hbCB1c2VyIGltcGVyc29uYXRlIGFub3RoZXIgdGVuYW50J3Mgb3JnLiBVc2UgZm9yIGNyb3NzLW9yZyBhZG1pbiB0b29saW5nXG4gICAqIChlLmcuIGEgc3lzYWRtaW4gbWFuYWdpbmcgYSBnaXZlbiBvcmcncyBiaWxsaW5nKS4gSWYgdW5zdXJlLCBsZWF2ZSBpdCBkaXNhYmxlZC5cbiAgICovXG4gIGFsbG93T3JnSGVhZGVyT3ZlcnJpZGU/OiBib29sZWFuO1xufVxuXG4vKiogSldUIGF1dGggbWlkZGxld2FyZS4gVXNlIGRpcmVjdGx5IG9yIGNhbGwgd2l0aCBvcHRpb25zLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBdXRoKFxuICByZXE6IFJlcXVlc3QsXG4gIHJlczogUmVzcG9uc2UsXG4gIG5leHQ6IE5leHRGdW5jdGlvbixcbik6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUF1dGgoXG4gIG9wdGlvbnM/OiBSZXF1aXJlQXV0aE9wdGlvbnMsXG4pOiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUF1dGgoXG4gIHJlcU9yT3B0aW9ucz86IFJlcXVlc3QgfCBSZXF1aXJlQXV0aE9wdGlvbnMsXG4gIHJlcz86IFJlc3BvbnNlLFxuICBuZXh0PzogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB8ICgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHZvaWQpIHtcbiAgaWYgKHJlcU9yT3B0aW9ucyAmJiByZXMgJiYgbmV4dCAmJiAnaGVhZGVycycgaW4gcmVxT3JPcHRpb25zKSB7XG4gICAgcmV0dXJuIF9yZXF1aXJlQXV0aCh7fSwgcmVxT3JPcHRpb25zIGFzIFJlcXVlc3QsIHJlcywgbmV4dCk7XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0gKHJlcU9yT3B0aW9ucyBhcyBSZXF1aXJlQXV0aE9wdGlvbnMpIHx8IHt9O1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzSW5uZXI6IFJlc3BvbnNlLCBuZXh0SW5uZXI6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIF9yZXF1aXJlQXV0aChvcHRpb25zLCByZXEsIHJlc0lubmVyLCBuZXh0SW5uZXIpO1xuICB9O1xufVxuXG4vKipcbiAqIEEgc291cmNlIG9mIHRoZSBDVVJSRU5UIGB0b2tlblZlcnNpb25gIGZvciBhIHVzZXIsIGJhY2tlZCBieSBhIHN0b3JlIHRoZVxuICogc3RhdGVsZXNzIHNlcnZpY2VzIGNhbiByZWFkIChpbiBwcmFjdGljZSBhIFJlZGlzIGtleSB0aGUgcGxhdGZvcm0gcHVibGlzaGVzXG4gKiB0byBvbiBldmVyeSBwcml2aWxlZ2UgY2hhbmdlKS4gUmVnaXN0ZXJlZCB2aWEge0BsaW5rIHNldFRva2VuUmV2b2NhdGlvblN0b3JlfS5cbiAqXG4gKiBgZ2V0Q3VycmVudFZlcnNpb25gIHJldHVybnMgdGhlIHVzZXIncyBjdXJyZW50IHZlcnNpb24sIG9yIGBudWxsYCB3aGVuIHRoZVxuICogc3RvcmUgaGFzIG5vIGVudHJ5IOKAlCBhIG1pc3MgaXMgdHJlYXRlZCBhcyBcIm5vIGtub3duIHJldm9jYXRpb25cIiAoZmFpbC1vcGVuKTpcbiAqIHJldm9jYXRpb24gZW50cmllcyBhcmUgcHVibGlzaGVkIHdpdGggYSBUVEwgbWF0Y2hpbmcgdGhlIGFjY2Vzcy10b2tlblxuICogbGlmZXRpbWUsIHNvIGEgbWlzc2luZyBlbnRyeSBtZWFucyBhbnkgdG9rZW4gb2xkIGVub3VnaCB0byBwcmVkYXRlIGl0IGhhc1xuICogYWxyZWFkeSBleHBpcmVkIG9uIGl0cyBvd24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9rZW5SZXZvY2F0aW9uU3RvcmUge1xuICBnZXRDdXJyZW50VmVyc2lvbih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD47XG59XG5cbmxldCB0b2tlblJldm9jYXRpb25TdG9yZTogVG9rZW5SZXZvY2F0aW9uU3RvcmUgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogUmVnaXN0ZXIgKG9yIGNsZWFyLCB3aXRoIGB1bmRlZmluZWRgKSB0aGUgcHJvY2Vzcy13aWRlIHRva2VuLXJldm9jYXRpb24gc3RvcmUuXG4gKiBXaGVuIHVuc2V0ICh0aGUgZGVmYXVsdCksIGByZXF1aXJlQXV0aGAgcGVyZm9ybXMgTk8gcmV2b2NhdGlvbiBjaGVjayAoaXQgcmVsaWVzXG4gKiBvbiB0aGUgc2hvcnQgYWNjZXNzLXRva2VuIFRUTCk7IHNlcnZpY2VzIG9wdCBpbiBhdCBib290IGJ5IHdpcmluZyB0aGVpciBSZWRpc1xuICogY2xpZW50LiBQbGF0Zm9ybSBrZWVwcyBpdHMgb3duIE1vbmdvLWJhY2tlZCBjaGVjayBhbmQgbmVlZCBub3QgcmVnaXN0ZXIgb25lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0VG9rZW5SZXZvY2F0aW9uU3RvcmUoc3RvcmU6IFRva2VuUmV2b2NhdGlvblN0b3JlIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gIHRva2VuUmV2b2NhdGlvblN0b3JlID0gc3RvcmU7XG4gIGlmIChzdG9yZSkgcmV2b2NhdGlvblN0b3JlTWlzc2luZ1dhcm5lZCA9IGZhbHNlOyAvLyByZS1hcm0gaWYgYSBzdG9yZSBpcyAocmUpcmVnaXN0ZXJlZFxufVxuXG4vKiogT25lLXNob3QgZ3VhcmQgc28gdGhlIFwicmV2b2NhdGlvbiBpbmFjdGl2ZVwiIHdhcm5pbmcgZG9lc24ndCBmbG9vZCB0aGUgbG9ncy4gKi9cbmxldCByZXZvY2F0aW9uU3RvcmVNaXNzaW5nV2FybmVkID0gZmFsc2U7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIHdoZW4gYGRlY29kZWRgIGhhcyBiZWVuIHJldm9rZWQgcGVyIHRoZSByZWdpc3RlcmVkIHN0b3JlOiBpdHNcbiAqIGVtYmVkZGVkIGB0b2tlblZlcnNpb25gIGlzIHN0cmljdGx5IGJlaGluZCB0aGUgc3RvcmUncyBjdXJyZW50IHZlcnNpb24uXG4gKiBGYWlsLW9wZW4g4oCUIGFueSBzdG9yZSBlcnJvciwgYSBtaXNzaW5nIGVudHJ5LCBvciBhIHRva2VuL3N0b3JlIHdpdGhvdXQgYVxuICogdXNhYmxlIHZlcnNpb24geWllbGRzIGBmYWxzZWAgKGFsbG93KS4gTmV2ZXIgdGhyb3dzLlxuICovXG5hc3luYyBmdW5jdGlvbiBpc1Rva2VuUmV2b2tlZChkZWNvZGVkOiBKd3RQYXlsb2FkKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHN0b3JlID0gdG9rZW5SZXZvY2F0aW9uU3RvcmU7XG4gIGlmICghc3RvcmUpIHtcbiAgICAvLyBNYWtlIHRoZSBcInJldm9jYXRpb24gaXMgT0ZGXCIgc3RhdGUgT0JTRVJWQUJMRTogYSBzZXJ2aWNlIHRoYXQgdmVyaWZpZXMgdXNlclxuICAgIC8vIHRva2VucyBidXQgZm9yZ290IGBzZXRUb2tlblJldm9jYXRpb25TdG9yZSgpYCBzaWxlbnRseSBkaXNhYmxlcyB0aGUgc2Vzc2lvblxuICAgIC8vIGtpbGwtc3dpdGNoLiBXYXJuIE9OQ0UgKG9ubHkgZm9yIGEgcmV2b2NhYmxlIHVzZXIgdG9rZW4pIHNvIGEgbWlzY29uZmlndXJlZFxuICAgIC8vIGJvb3Qgc3VyZmFjZXMgaW4gdGhlIGxvZ3MgaW5zdGVhZCBvZiBmYWlsaW5nIG9wZW4gaW52aXNpYmx5LlxuICAgIGlmICghcmV2b2NhdGlvblN0b3JlTWlzc2luZ1dhcm5lZCAmJiBkZWNvZGVkLnN1YiAmJiB0eXBlb2YgZGVjb2RlZC50b2tlblZlcnNpb24gPT09ICdudW1iZXInKSB7XG4gICAgICByZXZvY2F0aW9uU3RvcmVNaXNzaW5nV2FybmVkID0gdHJ1ZTtcbiAgICAgIGxvZ2dlci53YXJuKCdUb2tlbiByZXZvY2F0aW9uIHN0b3JlIE5PVCByZWdpc3RlcmVkIOKAlCByZXZvY2F0aW9uIGNoZWNrcyBhcmUgSU5BQ1RJVkUgKHNldFRva2VuUmV2b2NhdGlvblN0b3JlIHdhcyBuZXZlciBjYWxsZWQpOyByZXZva2VkL2NvbXByb21pc2VkIHNlc3Npb25zIHN0YXkgdmFsaWQgdW50aWwgbmF0dXJhbCBUVEwnKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICghZGVjb2RlZC5zdWIgfHwgdHlwZW9mIGRlY29kZWQudG9rZW5WZXJzaW9uICE9PSAnbnVtYmVyJykgcmV0dXJuIGZhbHNlO1xuICB0cnkge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCBzdG9yZS5nZXRDdXJyZW50VmVyc2lvbihkZWNvZGVkLnN1Yik7XG4gICAgcmV0dXJuIGN1cnJlbnQgIT09IG51bGwgJiYgZGVjb2RlZC50b2tlblZlcnNpb24gPCBjdXJyZW50O1xuICB9IGNhdGNoIHtcbiAgICAvLyBGYWlsLW9wZW46IGEgcmV2b2NhdGlvbi1zdG9yZSBvdXRhZ2UgbXVzdCBub3QgbG9jayBldmVyeSB1c2VyIG91dC5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBQdWJsaWMgcmV2b2NhdGlvbiBjaGVjayBmb3Igcm91dGVzIHRoYXQgdmVyaWZ5IGEgcGxhdGZvcm0gSldUIE9VVFNJREVcbiAqIGByZXF1aXJlQXV0aGAgKGUuZy4gdGhlIGltYWdlLXJlZ2lzdHJ5IGAvdG9rZW5gIG1pbnQgcGF0aCwgd2hpY2ggcmVzb2x2ZXNcbiAqIGlkZW50aXR5IGl0c2VsZikuIFJldHVybnMgdHJ1ZSB3aGVuIHRoZSB0b2tlbidzIGB0b2tlblZlcnNpb25gIGlzIHN0cmljdGx5XG4gKiBiZWhpbmQgdGhlIHN0b3JlJ3MgY3VycmVudCB2ZXJzaW9uLiBGYWlsLW9wZW4gKG5ldmVyIHRocm93cykg4oCUIGEgc3RvcmUgb3V0YWdlXG4gKiBvciBhIHRva2VuL3N0b3JlIHdpdGhvdXQgYSB1c2FibGUgdmVyc2lvbiB5aWVsZHMgZmFsc2UgKGFsbG93KSwgbWF0Y2hpbmdcbiAqIGByZXF1aXJlQXV0aGAuIFBhc3MgdGhlIHZlcmlmaWVkIEpXVCBjbGFpbXMgKGBzdWJgLCBgdG9rZW5WZXJzaW9uYCkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpc0FjY2Vzc1Rva2VuUmV2b2tlZChjbGFpbXM6IHsgc3ViPzogc3RyaW5nOyB0b2tlblZlcnNpb24/OiBudW1iZXIgfSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICByZXR1cm4gaXNUb2tlblJldm9rZWQoY2xhaW1zIGFzIEp3dFBheWxvYWQpO1xufVxuXG5mdW5jdGlvbiBfcmVxdWlyZUF1dGgoXG4gIG9wdGlvbnM6IFJlcXVpcmVBdXRoT3B0aW9ucyxcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICBuZXh0OiBOZXh0RnVuY3Rpb24sXG4pOiB2b2lkIHtcbiAgY29uc3QgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb247XG5cbiAgaWYgKCFhdXRoSGVhZGVyKSB7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aG9yaXphdGlvbiBoZWFkZXIgcmVxdWlyZWQnLCBFcnJvckNvZGUuVE9LRU5fTUlTU0lORyk7XG4gIH1cblxuICBjb25zdCBwYXJ0cyA9IGF1dGhIZWFkZXIuc3BsaXQoJyAnKTtcbiAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMiB8fCBwYXJ0c1swXSAhPT0gJ0JlYXJlcicpIHtcbiAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdJbnZhbGlkIGF1dGhvcml6YXRpb24gZm9ybWF0LiBVc2U6IEJlYXJlciA8dG9rZW4+JywgRXJyb3JDb2RlLlRPS0VOX0lOVkFMSUQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBQYXNzIHRocm91Z2ggb3B0aW9uYWwgaXNzdWVyL2F1ZGllbmNlIHZlcmlmaWNhdGlvbiB3aGVuIGVudi1jb25maWd1cmVkLlxuICAgIC8vIFdpdGhvdXQgdGhlc2UsIGEgSldUIHNpZ25lZCBieSBhbnkgc3lzdGVtIHRoYXQgaGFwcGVucyB0byBzaGFyZSB0aGVcbiAgICAvLyBzYW1lIEpXVF9TRUNSRVQgd291bGQgYmUgYWNjZXB0ZWQg4oCUIGRlZmVuY2UtaW4tZGVwdGggZm9yIHNoYXJlZC1zZWNyZXRcbiAgICAvLyBtaXNjb25maWd1cmF0aW9ucyBhY3Jvc3Mgc2VydmljZXMgLyBlbnZpcm9ubWVudHMuXG4gICAgLy8gUGluIHRoZSBhY2NlcHRlZCBhbGdvcml0aG0gdG8gdGhlIGNvbmZpZ3VyZWQgSE1BQyBhbGcgKGRlZmF1bHQgSFMyNTYpLlxuICAgIC8vIFdpdGhvdXQgYW4gYWxsb3ctbGlzdCwgYGp3dC52ZXJpZnlgIGFjY2VwdHMgYW55IGFsZ29yaXRobSB0aGUga2V5IGNhblxuICAgIC8vIHZlcmlmeSDigJQgdGhlIGNsYXNzaWMgYWxnLWNvbmZ1c2lvbiB2ZWN0b3IgKGFuZCBhIGhhcmQgZ3VhcmQgYWdhaW5zdFxuICAgIC8vIGBhbGc6bm9uZWApLiBFbnYtZHJpdmVuIHNvIGl0IHN0YXlzIGluIGxvY2tzdGVwIHdpdGggaG93IHRva2VucyBhcmVcbiAgICAvLyBzaWduZWQgKHNlZSBzaWduU2VydmljZVRva2VuICsgcGxhdGZvcm0ncyBjb25maWcuYXV0aC5qd3QuYWxnb3JpdGhtKS5cbiAgICBjb25zdCB2ZXJpZnlPcHRpb25zOiBqd3QuVmVyaWZ5T3B0aW9ucyA9IHsgYWxnb3JpdGhtczogWyhwcm9jZXNzLmVudi5KV1RfQUxHT1JJVEhNIHx8ICdIUzI1NicpIGFzIGp3dC5BbGdvcml0aG1dIH07XG4gICAgY29uc3QgZXhwZWN0ZWRJc3N1ZXIgPSBwcm9jZXNzLmVudi5KV1RfSVNTVUVSO1xuICAgIGNvbnN0IGV4cGVjdGVkQXVkaWVuY2UgPSBwcm9jZXNzLmVudi5KV1RfQVVESUVOQ0U7XG4gICAgaWYgKGV4cGVjdGVkSXNzdWVyKSB2ZXJpZnlPcHRpb25zLmlzc3VlciA9IGV4cGVjdGVkSXNzdWVyO1xuICAgIGlmIChleHBlY3RlZEF1ZGllbmNlKSB2ZXJpZnlPcHRpb25zLmF1ZGllbmNlID0gZXhwZWN0ZWRBdWRpZW5jZTtcbiAgICBjb25zdCBkZWNvZGVkID0gdmVyaWZ5Snd0V2l0aFJvdGF0aW9uKHBhcnRzWzFdLCB2ZXJpZnlPcHRpb25zKTtcblxuICAgIGlmIChkZWNvZGVkLnR5cGUgIT09ICdhY2Nlc3MnKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdPbmx5IGFjY2VzcyB0b2tlbnMgY2FuIGJlIHVzZWQgZm9yIEFQSSByZXF1ZXN0cycsIEVycm9yQ29kZS5UT0tFTl9JTlZBTElEKTtcbiAgICB9XG5cbiAgICBpZiAoIWRlY29kZWQuc3ViIHx8ICFkZWNvZGVkLnJvbGUpIHtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ1Rva2VuIG1pc3NpbmcgcmVxdWlyZWQgZmllbGRzJywgRXJyb3JDb2RlLlRPS0VOX0lOVkFMSUQpO1xuICAgIH1cblxuICAgIC8vIFNlcnZpY2UtdG9rZW4ga2lsbC1zd2l0Y2g6IHJlamVjdCBhIHNlcnZpY2UgcHJpbmNpcGFsIHdob3NlIHNlcnZpY2UgaGFzXG4gICAgLy8gYmVlbiBhZGRlZCB0byB0aGUgZGVueWxpc3QuIFJvdGF0aW5nIHRoZSBzaGFyZWQgSldUIHNlY3JldCBpcyB0aGUgb25seVxuICAgIC8vIG90aGVyIHdheSB0byBpbnZhbGlkYXRlIGEgc2VydmljZSB0b2tlbiBiZWZvcmUgaXRzIChzaG9ydCkgVFRMIOKAlCBidXQgdGhhdFxuICAgIC8vIG51a2VzIEVWRVJZIHNlcnZpY2UgdG9rZW4gZmxlZXQtd2lkZS4gVGhpcyBsZXRzIG9uZSBjb21wcm9taXNlZC9yb2d1ZVxuICAgIC8vIHNlcnZpY2UgYmUgY3V0IG9mZiBzdXJnaWNhbGx5LiBPKDEpIFNldCBsb29rdXAsIHplcm8gY29zdCB3aGVuIHRoZSBkZW55bGlzdFxuICAgIC8vIGlzIGVtcHR5ICh0aGUgZGVmYXVsdCksIHNvIGl0IG5ldmVyIHRheGVzIHRoZSBTMlMgaG90IHBhdGggdW5sZXNzIGFybWVkLlxuICAgIGlmIChkZWNvZGVkLnN1Yi5zdGFydHNXaXRoKCdzZXJ2aWNlOicpICYmIGlzU2VydmljZVRva2VuRGVuaWVkKGRlY29kZWQuc3ViKSkge1xuICAgICAgZW1pdENvdW50ZXIoJ3NlcnZpY2VfdG9rZW5fZGVuaWVkX3RvdGFsJywgeyBzZXJ2aWNlOiBkZWNvZGVkLnN1Yi5zbGljZSgnc2VydmljZTonLmxlbmd0aCkgfSk7XG4gICAgICBsb2dnZXIud2FybignUmVqZWN0ZWQgZGVueWxpc3RlZCBzZXJ2aWNlIHRva2VuJywgeyBzdWI6IGRlY29kZWQuc3ViIH0pO1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnU2VydmljZSB0b2tlbiByZXZva2VkJywgRXJyb3JDb2RlLlRPS0VOX1JFVk9LRUQpO1xuICAgIH1cblxuICAgIHJlcS51c2VyID0geyAuLi5kZWNvZGVkIH07XG5cbiAgICAvLyBUaGUgeC1vcmctaWQveC1vcmctbmFtZSBvdmVycmlkZSBsZXRzIGEgU1lTLUFETUlOIGFjdCBvbiBhIGNob3NlbiBvcmdcbiAgICAvLyAoY3Jvc3Mtb3JnIGFkbWluIHRvb2xpbmcpLiBJdCBpcyBnYXRlZCBvbiB0aGUgdmVyaWZpZWQgYGlzU3VwZXJBZG1pbmAgY2xhaW1cbiAgICAvLyBoZXJlIHNvIHRoYXQgZXZlbiBhIHJvdXRlIHdoaWNoIG1pc3Rha2VubHkgZW5hYmxlcyBgYWxsb3dPcmdIZWFkZXJPdmVycmlkZWBcbiAgICAvLyBjYW4gTkVWRVIgbGV0IGFuIG9yZGluYXJ5IGF1dGhlbnRpY2F0ZWQgdXNlciBzcG9vZiBhbm90aGVyIHRlbmFudCdzIG9yZyB2aWFcbiAgICAvLyB0aGUgaGVhZGVyIOKAlCBkZWZlbmNlLWluLWRlcHRoIGFnYWluc3QgdGhlIGNyb3NzLXRlbmFudCBicmVhayB0aGlzIGNhdXNlZC5cbiAgICBpZiAob3B0aW9ucy5hbGxvd09yZ0hlYWRlck92ZXJyaWRlICYmIGRlY29kZWQuaXNTdXBlckFkbWluID09PSB0cnVlKSB7XG4gICAgICBjb25zdCBoZWFkZXJPcmdJZCA9IGdldEhlYWRlclN0cmluZyhyZXEuaGVhZGVyc1sneC1vcmctaWQnXSk7XG4gICAgICBjb25zdCBoZWFkZXJPcmdOYW1lID0gZ2V0SGVhZGVyU3RyaW5nKHJlcS5oZWFkZXJzWyd4LW9yZy1uYW1lJ10pO1xuICAgICAgaWYgKGhlYWRlck9yZ0lkKSByZXEudXNlci5vcmdhbml6YXRpb25JZCA9IGhlYWRlck9yZ0lkO1xuICAgICAgaWYgKGhlYWRlck9yZ05hbWUpIHJlcS51c2VyLm9yZ2FuaXphdGlvbk5hbWUgPSBoZWFkZXJPcmdOYW1lO1xuICAgIH1cblxuICAgIC8vIFJlLWRlcml2ZSB0aGUgcmVxdWVzdCdzIHRlbmFudCBpZGVudGl0eSBmcm9tIHRoZSBOT1ctdmVyaWZpZWQgSldULlxuICAgIC8vXG4gICAgLy8gYGF0dGFjaFJlcXVlc3RDb250ZXh0YCBydW5zIGFzIGEgZ2xvYmFsIG1pZGRsZXdhcmUgQkVGT1JFIHRoaXMgcGVyLXJvdXRlXG4gICAgLy8gYHJlcXVpcmVBdXRoYCwgc28gaXQgY2FwdHVyZWQgYHJlcS5jb250ZXh0LmlkZW50aXR5YCB3aGlsZSBgcmVxLnVzZXJgIHdhc1xuICAgIC8vIHN0aWxsIHVuZGVmaW5lZCDigJQgYXQgd2hpY2ggcG9pbnQgYGdldElkZW50aXR5YCBmYWxscyBiYWNrIHRvIHRoZSByYXcsXG4gICAgLy8gY2xpZW50LXNldHRhYmxlIGB4LW9yZy1pZGAvYHgtdXNlci1pZGAgaGVhZGVycy4gRXZlcnkgZG93bnN0cmVhbSB0ZW5hbnQtXG4gICAgLy8gYXV0aG9yaXR5IGNvbnN1bWVyIChyZXF1aXJlT3JnSWQsIHdpdGhUZW5hbnRDb250ZXh0J3MgUkxTIHNjb3BlLCBjaGVja1F1b3RhLFxuICAgIC8vIHdpdGhSb3V0ZSwgYW5kIHRoZSBpZGVtcG90ZW5jeSBuYW1lc3BhY2UpIHJlYWRzIGByZXEuY29udGV4dC5pZGVudGl0eWAsIHNvXG4gICAgLy8gdGhhdCBmcm96ZW4gaGVhZGVyLWRlcml2ZWQgdmFsdWUg4oCUIG5vdCB0aGUgSldUIOKAlCB3YXMgZ292ZXJuaW5nIHRlbmFuY3kgb25cbiAgICAvLyBhbnkgbm9uLW5naW54IHBhdGguIFJlY29tcHV0aW5nIGhlcmUsIGF0IHRoZSBzaW5nbGUgcG9zdC12ZXJpZmljYXRpb24gY2hva2VcbiAgICAvLyBwb2ludCwgbWFrZXMgYGdldElkZW50aXR5YCBwcmVmZXIgdGhlIHZlcmlmaWVkIGByZXEudXNlcmAgKHNlZSBpZGVudGl0eS50cylcbiAgICAvLyBzbyB0ZW5hbmN5IGlzIEpXVC1hdXRob3JpdGF0aXZlLiBUaGUgbmdpbnggYHgtb3JnLWlkYCBvdmVyd3JpdGUgc3RheXMgYXNcbiAgICAvLyBkZWZlbmNlLWluLWRlcHRoLiBHdWFyZGVkIG9uIGByZXEuY29udGV4dGAgc28gc2VydmljZXMvcGF0aHMgdGhhdCBuZXZlclxuICAgIC8vIGF0dGFjaCBhIGNvbnRleHQgKG9yIHJ1biByZXF1aXJlQXV0aCBwcmUtY29udGV4dCkgYXJlIHVuYWZmZWN0ZWQuXG4gICAgY29uc3QgcmVxQ3R4ID0gKHJlcSBhcyBSZXF1ZXN0ICYgeyBjb250ZXh0PzogeyBpZGVudGl0eTogUmVxdWVzdElkZW50aXR5IH0gfSkuY29udGV4dDtcbiAgICBpZiAocmVxQ3R4KSB7XG4gICAgICByZXFDdHguaWRlbnRpdHkgPSBnZXRJZGVudGl0eShyZXEgYXMgdW5rbm93biBhcyBIdHRwUmVxdWVzdCk7XG4gICAgfVxuXG4gICAgLy8gU2Vzc2lvbi1pbnZhbGlkYXRpb24gY2hlY2sgZm9yIHRoZSBzdGF0ZWxlc3Mgc2VydmljZXM6IHJlamVjdCBhIHRva2VuXG4gICAgLy8gd2hvc2UgYHRva2VuVmVyc2lvbmAgaXMgYmVoaW5kIHRoZSByZXZvY2F0aW9uIHN0b3JlJ3MgY3VycmVudCB2YWx1ZSAoYVxuICAgIC8vIHByaXZpbGVnZSBjaGFuZ2UgdGhlIHBsYXRmb3JtIHB1Ymxpc2hlZCkuIE5vIHN0b3JlIHJlZ2lzdGVyZWQg4oeSIHRoaXMgaXMgYVxuICAgIC8vIG5vLW9wIGFuZCBjb250cm9sIHBhc3NlcyBzdHJhaWdodCB0aHJvdWdoLiBGYWlsLW9wZW4gb24gYW55IHN0b3JlIGVycm9yLlxuICAgIGlmICh0b2tlblJldm9jYXRpb25TdG9yZSAmJiBkZWNvZGVkLnN1YiAmJiB0eXBlb2YgZGVjb2RlZC50b2tlblZlcnNpb24gPT09ICdudW1iZXInKSB7XG4gICAgICAvLyBgLmNhdGNoKG5leHQpYCBmb3J3YXJkcyBhIERPV05TVFJFQU0gc3luY2hyb25vdXMgdGhyb3cgZnJvbSBgbmV4dCgpYCB0b1xuICAgICAgLy8gRXhwcmVzcydzIGVycm9yIG1pZGRsZXdhcmUg4oCUIHdpdGhvdXQgaXQsIHRoYXQgdGhyb3cgd291bGQgc3VyZmFjZSBhcyBhblxuICAgICAgLy8gdW5oYW5kbGVkIHJlamVjdGlvbiAodGhpcyBgbmV4dCgpYCBydW5zIGluIGEgbWljcm90YXNrLCBvdXRzaWRlIHRoZVxuICAgICAgLy8gc3Vycm91bmRpbmcgdHJ5L2NhdGNoIGFuZCBFeHByZXNzJ3MgcGVyLWxheWVyIGRpc3BhdGNoKS4gYGlzVG9rZW5SZXZva2VkYFxuICAgICAgLy8gaXRzZWxmIG5ldmVyIHJlamVjdHMgKGl0IGZhaWwtb3BlbnMgaW50ZXJuYWxseSksIHNvIHRoZSBjYXRjaCBvbmx5IGV2ZXJcbiAgICAgIC8vIHNlZXMgYSBnZW51aW5lIGRvd25zdHJlYW0gZXJyb3IuXG4gICAgICBpc1Rva2VuUmV2b2tlZChkZWNvZGVkKVxuICAgICAgICAudGhlbigocmV2b2tlZCkgPT4ge1xuICAgICAgICAgIGlmIChyZXZva2VkKSB7XG4gICAgICAgICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdTZXNzaW9uIGhhcyBiZWVuIHJldm9rZWQ7IHBsZWFzZSBzaWduIGluIGFnYWluJywgRXJyb3JDb2RlLlRPS0VOX1JFVk9LRUQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBuZXh0KCk7XG4gICAgICAgIH0pXG4gICAgICAgIC5jYXRjaChuZXh0KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBuZXh0KCk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2Ygand0LlRva2VuRXhwaXJlZEVycm9yKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdUb2tlbiBoYXMgZXhwaXJlZCcsIEVycm9yQ29kZS5UT0tFTl9FWFBJUkVEKTtcbiAgICB9XG5cbiAgICBpZiAoZXJyb3IgaW5zdGFuY2VvZiBqd3QuSnNvbldlYlRva2VuRXJyb3IpIHtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0ludmFsaWQgdG9rZW4nLCBFcnJvckNvZGUuVE9LRU5fSU5WQUxJRCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gZmFpbGVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gIH1cbn1cblxuLyoqXG4gKiBXaGV0aGVyIHRoZSByZXF1ZXN0J3MgdXNlciBob2xkcyBgcGVybWlzc2lvbmAuIFN1cGVyYWRtaW5zIGltcGxpY2l0bHkgaG9sZFxuICogZXZlcnkgcGVybWlzc2lvbi4gUmVhZHMgdGhlIHJlc29sdmVkIGBwZXJtaXNzaW9uc2AgY2xhaW0gKHNldCBhdCB0b2tlbiBpc3N1ZSxcbiAqIG9yIHJlLWRlcml2ZWQgcGVyIHJlcXVlc3QgYnkgdGhlIHBsYXRmb3JtKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHVzZXJIYXNQZXJtaXNzaW9uKHJlcTogUmVxdWVzdCwgcGVybWlzc2lvbjogUGVybWlzc2lvbik6IGJvb2xlYW4ge1xuICByZXR1cm4gaGFzUGVybWlzc2lvbihyZXEudXNlcj8ucGVybWlzc2lvbnMsIHBlcm1pc3Npb24sIHJlcS51c2VyPy5pc1N1cGVyQWRtaW4pO1xufVxuXG4vKipcbiAqIENvbnRleHQgcGFzc2VkIHRvIGEgcmVnaXN0ZXJlZCBhdXRob3JpemF0aW9uLWRlbmlhbCBhdWRpdG9yIHdoZW4gYVxuICogc3RhdGUtY2hhbmdpbmcgcmVxdWVzdCBpcyByZWplY3RlZCBieSBgcmVxdWlyZVBlcm1pc3Npb25gIC9cbiAqIGByZXF1aXJlU3lzdGVtQWRtaW5gLlxuICovXG5leHBvcnQgaW50ZXJmYWNlIEF1dGh6RGVuaWFsSW5mbyB7XG4gIC8qKiBUaGUgZGVuaWVkIHVzZXIncyBpZCAoYHN1YmApLCBpZiBhdXRoZW50aWNhdGVkLiAqL1xuICBhY3RvcklkPzogc3RyaW5nO1xuICBhY3RvckVtYWlsPzogc3RyaW5nO1xuICAvKiogVGhlIHVzZXIncyBhY3RpdmUgb3JnIGF0IGRlbmlhbCB0aW1lLiAqL1xuICBvcmdJZD86IHN0cmluZztcbiAgLyoqIEhUVFAgbWV0aG9kICsgcGF0aCBvZiB0aGUgcmVqZWN0ZWQgcmVxdWVzdC4gKi9cbiAgbWV0aG9kOiBzdHJpbmc7XG4gIHBhdGg6IHN0cmluZztcbiAgLyoqIFdoYXQgd2FzIHJlcXVpcmVkOiB0aGUgbWlzc2luZyBwZXJtaXNzaW9uKHMpLCBvciAnc3lzdGVtLWFkbWluJy4gKi9cbiAgcmVxdWlyZWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBPcHRpb25hbCBzaW5rIGZvciBkZW5pZWQtYXV0aG9yaXphdGlvbiBldmVudHMuIExlZnQgdW5zZXQgYnkgZGVmYXVsdCBzb1xuICogYXBpLWNvcmUgc3RheXMgZGVjb3VwbGVkIGZyb20gYW55IGF1ZGl0IHRyYW5zcG9ydCDigJQgYSBzZXJ2aWNlIHJlZ2lzdGVycyBvbmVcbiAqIGF0IGJvb3QgKHR5cGljYWxseSBmb3J3YXJkaW5nIHRvIGl0cyBgUmVtb3RlQXVkaXRDbGllbnRgIGFzIGFuXG4gKiBgYXV0aHouZGVuaWVkYCBldmVudCwgb3IsIG9uIHBsYXRmb3JtLCB0byB0aGUgbG9jYWwgYGF1ZGl0KClgIGhlbHBlcikuXG4gKiBNVVNUIGJlIGJlc3QtZWZmb3J0OiBpdCBpcyBpbnZva2VkIGluc2lkZSB0aGUgcmVxdWVzdCBwYXRoLCBzbyBpdCBtdXN0IG5ldmVyXG4gKiB0aHJvdyBvciBibG9jayAodGhlIGdhdGUgd3JhcHMgdGhlIGNhbGwgaW4gdHJ5L2NhdGNoIHJlZ2FyZGxlc3MpLlxuICovXG5sZXQgYXV0aHpEZW5pYWxBdWRpdG9yOiAoKGluZm86IEF1dGh6RGVuaWFsSW5mbykgPT4gdm9pZCkgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogUmVnaXN0ZXIgKG9yIGNsZWFyLCB3aXRoIGB1bmRlZmluZWRgKSB0aGUgcHJvY2Vzcy13aWRlIGF1dGhvcml6YXRpb24tZGVuaWFsXG4gKiBhdWRpdG9yLiBJZGVtcG90ZW50OyB0aGUgbGFzdCByZWdpc3RyYXRpb24gd2lucy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldEF1dGh6RGVuaWFsQXVkaXRvcihmbjogKChpbmZvOiBBdXRoekRlbmlhbEluZm8pID0+IHZvaWQpIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gIGF1dGh6RGVuaWFsQXVkaXRvciA9IGZuO1xufVxuXG4vKipcbiAqIEVtaXQgYSBkZW5pYWwgZXZlbnQsIGJlc3QtZWZmb3J0LiBPbmx5IGZpcmVzIGZvciBzdGF0ZS1jaGFuZ2luZyAobm9uLUdFVCxcbiAqIG5vbi1IRUFEL09QVElPTlMpIHJlcXVlc3RzIOKAlCBhIHJlamVjdGVkIEdFVCBpcyBsb3ctc2lnbmFsIHByb2Jpbmcgbm9pc2UgYW5kXG4gKiB3b3VsZCBhbXBsaWZ5IGF1ZGl0IHZvbHVtZSB1bmRlciBhIHNjYW4uIE5ldmVyIHRocm93cy5cbiAqL1xuZnVuY3Rpb24gYXVkaXRBdXRoekRlbmlhbChyZXE6IFJlcXVlc3QsIHJlcXVpcmVkOiBzdHJpbmcpOiB2b2lkIHtcbiAgY29uc3QgYXVkaXRvciA9IGF1dGh6RGVuaWFsQXVkaXRvcjtcbiAgaWYgKCFhdWRpdG9yKSByZXR1cm47XG4gIGNvbnN0IG1ldGhvZCA9IHJlcS5tZXRob2QudG9VcHBlckNhc2UoKTtcbiAgaWYgKG1ldGhvZCA9PT0gJ0dFVCcgfHwgbWV0aG9kID09PSAnSEVBRCcgfHwgbWV0aG9kID09PSAnT1BUSU9OUycpIHJldHVybjtcbiAgdHJ5IHtcbiAgICBhdWRpdG9yKHtcbiAgICAgIGFjdG9ySWQ6IHJlcS51c2VyPy5zdWIsXG4gICAgICBhY3RvckVtYWlsOiByZXEudXNlcj8uZW1haWwsXG4gICAgICBvcmdJZDogcmVxLnVzZXI/Lm9yZ2FuaXphdGlvbklkLFxuICAgICAgbWV0aG9kLFxuICAgICAgLy8gU3RyaXAgdGhlIHF1ZXJ5IHN0cmluZyDigJQgYSBkZW5pZWQgcmVxdWVzdCBtYXkgY2FycnkgYSB0b2tlbi9zZWNyZXQgYXMgYVxuICAgICAgLy8gcXVlcnkgcGFyYW0sIGFuZCB0aGlzIHBhdGggaXMgcGVyc2lzdGVkIHZlcmJhdGltIGludG8gdGhlIGF1ZGl0IGxvZy5cbiAgICAgIHBhdGg6IChyZXEub3JpZ2luYWxVcmwgfHwgcmVxLnVybCkuc3BsaXQoJz8nKVswXSxcbiAgICAgIHJlcXVpcmVkLFxuICAgIH0pO1xuICB9IGNhdGNoIHtcbiAgICAvLyBCZXN0LWVmZm9ydCDigJQgYSBicm9rZW4gYXVkaXRvciBtdXN0IG5ldmVyIGJyZWFrIHRoZSBhdXRoIGdhdGUuXG4gIH1cbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgQVQgTEVBU1QgT05FIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikuIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gTWlycm9ycyBgcmVxdWlyZVJvbGVgJ3MgYW55LW9mIHNlbWFudGljcztcbiAqIHBhc3MgYSBzaW5nbGUgcGVybWlzc2lvbiBmb3IgYSBzcGVjaWZpYyBhY3Rpb24sIG9yIHNldmVyYWwgd2hlbiBhbnkgb25lIG9mXG4gKiB0aGVtIHNob3VsZCBncmFudCBhY2Nlc3MuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlUGVybWlzc2lvbiguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcS51c2VyKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdBdXRoZW50aWNhdGlvbiByZXF1aXJlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICAgIH1cbiAgICAvLyB1c2VySGFzUGVybWlzc2lvbiDihpIgaGFzUGVybWlzc2lvbiBhbHJlYWR5IGdyYW50cyBzdXBlcmFkbWlucyBldmVyeVxuICAgIC8vIHBlcm1pc3Npb24sIHNvIHRoaXMgc2luZ2xlIGNoZWNrIGNvdmVycyBib3RoIHRoZSBzdXBlcmFkbWluIGJ5cGFzcyBhbmRcbiAgICAvLyB0aGUgYW55LW9mIG1lbWJlcnNoaXAgdGVzdCB3aXRob3V0IHJlLWlubGluaW5nIGVpdGhlci5cbiAgICBpZiAocGVybWlzc2lvbnMuc29tZSgocCkgPT4gdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSkpIHJldHVybiBuZXh0KCk7XG4gICAgYXVkaXRBdXRoekRlbmlhbChyZXEsIHBlcm1pc3Npb25zLmpvaW4oJyBvciAnKSk7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICBgTWlzc2luZyByZXF1aXJlZCBwZXJtaXNzaW9uOiAke3Blcm1pc3Npb25zLmpvaW4oJyBvciAnKX1gLFxuICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICApO1xuICB9O1xufVxuXG4vKipcbiAqIFJlcXVpcmVzIHRoYXQgdGhlIHVzZXIgaG9sZCBFVkVSWSBvbmUgb2YgdGhlIGdpdmVuIHBlcm1pc3Npb25zIChvciBiZSBhXG4gKiBzdXBlcmFkbWluKSDigJQgdGhlIEFORCBjb3VudGVycGFydCB0byBgcmVxdWlyZVBlcm1pc3Npb25gJ3MgYW55LW9mLiBVc2UgZm9yIGFcbiAqIHNlbnNpdGl2ZSBhY3Rpb24gdGhhdCBsZWdpdGltYXRlbHkgZGVtYW5kcyB0d28gZGlzdGluY3QgY2FwYWJpbGl0aWVzIGF0IG9uY2VcbiAqIChlLmcuIGEgY3Jvc3Mtc3VyZmFjZSBvcGVyYXRpb24pLCBzbyB0aGUgZ3VhcmFudGVlIGlzIGV4cGxpY2l0IHJhdGhlciB0aGFuXG4gKiBhcHByb3hpbWF0ZWQgYnkgY2hhaW5pbmcgdHdvIGByZXF1aXJlUGVybWlzc2lvbmAgZ2F0ZXMuIFN1cGVyYWRtaW5zIGJ5cGFzc1xuICogKHRoZXkgaW1wbGljaXRseSBob2xkIGV2ZXJ5IHBlcm1pc3Npb24pLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUFsbFBlcm1pc3Npb25zKC4uLnBlcm1pc3Npb25zOiBQZXJtaXNzaW9uW10pIHtcbiAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVxLnVzZXIpIHtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gICAgfVxuICAgIGNvbnN0IG1pc3NpbmcgPSBwZXJtaXNzaW9ucy5maWx0ZXIoKHApID0+ICF1c2VySGFzUGVybWlzc2lvbihyZXEsIHApKTtcbiAgICBpZiAobWlzc2luZy5sZW5ndGggPT09IDApIHJldHVybiBuZXh0KCk7XG4gICAgYXVkaXRBdXRoekRlbmlhbChyZXEsIHBlcm1pc3Npb25zLmpvaW4oJyBhbmQgJykpO1xuICAgIHJldHVybiBzZW5kRXJyb3IoXG4gICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHttaXNzaW5nLmpvaW4oJyBhbmQgJyl9YCxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBMaWtlIHtAbGluayByZXF1aXJlUGVybWlzc2lvbn0gKGFueS1vZikgYnV0IEFMU08gYWRtaXRzIGFuIGludGVybmFsIHNlcnZpY2VcbiAqIHByaW5jaXBhbCAoYSBgc2VydmljZToqYCBtYWNoaW5lIHRva2VuKS4gRm9yIFJFQUQgZW5kcG9pbnRzIHRoYXQgQk9USFxuICogaW50ZXJhY3RpdmUgdXNlcnMg4oCUIHdobyBtdXN0IGhvbGQgb25lIG9mIHRoZSBgOnJlYWRgIGNhcGFiaWxpdGllcyDigJQgQU5EXG4gKiBzZXJ2aWNlLXRvLXNlcnZpY2UgY2FsbGVycyBsZWdpdGltYXRlbHkgaGl0OyBzZXJ2aWNlIHRva2VucyBjYXJyeSBub1xuICogcGVybWlzc2lvbiBjbGFpbXMgKHRoZXkncmUgbGVhc3QtcHJpdmlsZWdlIGByb2xlOm1lbWJlcmApLCBzbyBhIHBsYWluXG4gKiBgcmVxdWlyZVBlcm1pc3Npb25gIHdvdWxkIHdyb25nbHkgNDAzIHRoZW0uIFN1cGVyYWRtaW5zIHBhc3MgdmlhXG4gKiBgdXNlckhhc1Blcm1pc3Npb25gJ3MgaW1wbGljaXQtYWxsLiBVc2Ugb25seSB3aGVyZSBhIHNlcnZpY2UgY2FsbGVyIGlzIGEga25vd24sXG4gKiBpbnRlbmRlZCBjb25zdW1lciBvZiB0aGUgcm91dGUgKHZlcmlmeSB0aGUgY2FsbGVycyk7IHByZWZlciBwbGFpblxuICogYHJlcXVpcmVQZXJtaXNzaW9uYCBmb3IgcHVyZWx5IHVzZXItZmFjaW5nIHJlYWRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVBlcm1pc3Npb25PclNlcnZpY2UoLi4ucGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSkge1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXEudXNlcikge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgICB9XG4gICAgaWYgKGlzU2VydmljZVByaW5jaXBhbChyZXEpIHx8IHBlcm1pc3Npb25zLnNvbWUoKHApID0+IHVzZXJIYXNQZXJtaXNzaW9uKHJlcSwgcCkpKSByZXR1cm4gbmV4dCgpO1xuICAgIGF1ZGl0QXV0aHpEZW5pYWwocmVxLCBwZXJtaXNzaW9ucy5qb2luKCcgb3IgJykpO1xuICAgIHJldHVybiBzZW5kRXJyb3IoXG4gICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHtwZXJtaXNzaW9ucy5qb2luKCcgb3IgJyl9YCxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBHYXRlIGFuIGVuZHBvaW50IHRvIGludGVybmFsIHNlcnZpY2UtdG8tc2VydmljZSBjYWxsZXJzIG9ubHkgKGEgYHNlcnZpY2U6KmBcbiAqIG1hY2hpbmUgcHJpbmNpcGFsIG1pbnRlZCB2aWEge0BsaW5rIHNpZ25TZXJ2aWNlVG9rZW59IC8gYGdldFNlcnZpY2VBdXRoSGVhZGVyYCkuXG4gKiBSZWplY3RzIGFueSB1c2VyIHRva2VuLiBGb3IgTk9OLXVzZXItZmFjaW5nIGVuZHBvaW50cyDigJQgZW50aXR5LWV2ZW50IGluZ2VzdCxcbiAqIGF1dG8tc3Vic2NyaWJlLCBhbmQgc2ltaWxhciBwZWVyLXNlcnZpY2UgaG9va3Mg4oCUIHRoYXQgYSBicm93c2VyIG11c3QgbmV2ZXJcbiAqIHJlYWNoLiBDb21wb3NlIGFmdGVyIGByZXF1aXJlQXV0aGAgc28gYHJlcS51c2VyYCBpcyBwb3B1bGF0ZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlU2VydmljZVByaW5jaXBhbChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQge1xuICBpZiAoIWlzU2VydmljZVByaW5jaXBhbChyZXEpKSB7XG4gICAgLy8gNDAzIChub3QgNDAwKSDigJQgdGhpcyBpcyBhbiBhdXRob3JpemF0aW9uIHJlZnVzYWw7IHN0YXR1cyBtdXN0IG1hdGNoIHRoZVxuICAgIC8vIElOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyBjb2RlIGFuZCB0aGUgc2libGluZyBnYXRlcyAocmVxdWlyZVBlcm1pc3Npb24sIGV0Yy4pLlxuICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTiwgJ0ludGVybmFsIHNlcnZpY2UgY2FsbHMgb25seScsIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMpO1xuICB9XG4gIG5leHQoKTtcbn1cblxuLyoqXG4gKiBUaGUgc3lzdGVtIHRlbmFudCdzIGNhbm9uaWNhbCBvcmcgKippZCoqIOKAlCBhIGZpeGVkLCB3ZWxsLWtub3duIE9iamVjdElkIChOT1RcbiAqIHRoZSBzdHJpbmcgJ3N5c3RlbScpLiBUaGlzIGlzIHRoZSBzaW5nbGUga25vYiBldmVyeSBzZXJ2aWNlIHJlc29sdmVzIHRoZVxuICogc3lzdGVtIHRlbmFudCB0aHJvdWdoOyBvdmVycmlkZSB2aWEgdGhlIGBTWVNURU1fT1JHX0lEYCBlbnYgZm9yIGFsdGVybmF0ZVxuICogaW5zdGFsbHMuIFRoZSBzeXN0ZW0gb3JnJ3MgaHVtYW4gaWRlbnRpZmllciBzdGF5cyB0aGUgc2x1Zy9uYW1lICdzeXN0ZW0nXG4gKiAoc2VlIHtAbGluayBTWVNURU1fT1JHX1NMVUd9KTsgb25seSBpdHMgYF9pZGAgaXMgdGhpcyBPYmplY3RJZC5cbiAqL1xuZXhwb3J0IGNvbnN0IFNZU1RFTV9PUkdfSUQgPSAocHJvY2Vzcy5lbnYuU1lTVEVNX09SR19JRCB8fCAnMDAwMDAwMDAwMDAwMDAwMDAwMDAwMDAxJykudG9Mb3dlckNhc2UoKTtcblxuLyoqIFRoZSBzeXN0ZW0gb3JnJ3Mgd2VsbC1rbm93biBzbHVnL25hbWUgKHRoZSBodW1hbiBpZGVudGlmaWVyOyBpdHMgYF9pZGAgaXMge0BsaW5rIFNZU1RFTV9PUkdfSUR9KS4gKi9cbmV4cG9ydCBjb25zdCBTWVNURU1fT1JHX1NMVUcgPSAnc3lzdGVtJztcblxuLyoqXG4gKiBDaGVjayBpZiBhbiBvcmdJZCBvciBvcmdOYW1lL3NsdWcgbWF0Y2hlcyB0aGUgc3lzdGVtIG9yZy4gVXNlIHRoaXMgaW5zdGVhZCBvZlxuICogY29tcGFyaW5nIGRpcmVjdGx5OiB0aGUgaWQgaXMgbm93IGFuIE9iamVjdElkICh7QGxpbmsgU1lTVEVNX09SR19JRH0pIHdoaWxlIHRoZVxuICogbmFtZS9zbHVnIGlzICdzeXN0ZW0nICh7QGxpbmsgU1lTVEVNX09SR19TTFVHfSksIHNvIHRoZSB0d28gYXJlIGNvbXBhcmVkIGFnYWluc3RcbiAqIHRoZWlyIHJlc3BlY3RpdmUgY2Fub25pY2FsIHZhbHVlcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU3lzdGVtT3JnSWQob3JnSWQ/OiBzdHJpbmcsIG9yZ05hbWU/OiBzdHJpbmcpOiBib29sZWFuIHtcbiAgcmV0dXJuIG9yZ0lkPy50b0xvd2VyQ2FzZSgpID09PSBTWVNURU1fT1JHX0lEIHx8IG9yZ05hbWU/LnRvTG93ZXJDYXNlKCkgPT09IFNZU1RFTV9PUkdfU0xVRztcbn1cblxuLyoqXG4gKiBDaGVjayBpZiB0aGUgcmVxdWVzdCBpcyBmcm9tIGEgc3lzdGVtIGFkbWluLlxuICpcbiAqIEF1dGhvcml0eSBpcyBncmFudGVkIHNvbGVseSBieSB0aGUgdXNlci1sZXZlbCBgaXNTdXBlckFkbWluYCBmbGFnIGNhcnJpZWRcbiAqIGluIHRoZSBKV1QuIFRoZSBcIm1lbWJlcnNoaXAgaW4gdGhlIHdlbGwta25vd24gJ3N5c3RlbScgb3JnIHdpdGggcm9sZVxuICogYWRtaW4vb3duZXJcIiBwYXRoIHdhcyByZW1vdmVkIOKAlCBpdCBjb25mbGF0ZWQgYSBQaXBlbGluZSBCdWlsZGVyIG9wZXJhdG9yXG4gKiB3aXRoIGEgcmVhbCBjdXN0b21lciB0ZW5hbnQgaW4gdGhlIGRhdGEgbW9kZWwsIGFuZCBtZWFudCBhbnkgdW5pbnRlbmRlZFxuICogd3JpdGUgdGhhdCBjcmVhdGVkIGEgJ3N5c3RlbSctbmFtZWQgb3JnIGNvdWxkIHF1aWV0bHkgZ3JhbnQgY3Jvc3Mtb3JnXG4gKiBhdXRob3JpdHkuIFRoZSBgc3lzdGVtYCBvcmcgc3RpbGwgZXhpc3RzIGFzIGEgKmNvbnRlbnQgaG9sZGVyKiBmb3Igc2hhcmVkXG4gKiBzYW1wbGUgZGF0YTsgaXQganVzdCBubyBsb25nZXIgY29uZmVycyBwcml2aWxlZ2UuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N5c3RlbUFkbWluKHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVxLnVzZXI/LmlzU3VwZXJBZG1pbiA9PT0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBXaGV0aGVyIHRoZSByZXF1ZXN0J3MgdG9rZW4gY2FycmllcyBhIHNwZWNpZmljIGNhcGFiaWxpdHkgYHNjb3BlYCAoZS5nLlxuICogYCdyZXBvcnRpbmc6aW5nZXN0J2ApLiBVc2VkIHRvIGdhdGUgZW5kcG9pbnRzIHRoYXQgYWNjZXB0IGEgbmFycm93IG1hY2hpbmVcbiAqIGlkZW50aXR5IOKAlCBhIG5vcm1hbCBpbnRlcmFjdGl2ZSB1c2VyIHRva2VuIGhhcyBubyBgc2NvcGVgIGFuZCByZXR1cm5zIGZhbHNlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaGFzU2NvcGUocmVxOiBSZXF1ZXN0LCBzY29wZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiByZXEudXNlcj8uc2NvcGUgPT09IHNjb3BlO1xufVxuXG4vKiogUmVxdWlyZXMgYSBzeXN0ZW0gYWRtaW4g4oCUIGdyYW50ZWQgc29sZWx5IGJ5IHRoZSBgaXNTdXBlckFkbWluYCB0b2tlbiBjbGFpbVxuICogICh0aGUgb3JnLW1lbWJlcnNoaXAgcGF0aCB3YXMgcmVtb3ZlZCkuIFVzZSBhZnRlciByZXF1aXJlQXV0aC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXF1aXJlU3lzdGVtQWRtaW4oXG4gIHJlcTogUmVxdWVzdCxcbiAgcmVzOiBSZXNwb25zZSxcbiAgbmV4dDogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB7XG4gIGlmICghaXNTeXN0ZW1BZG1pbihyZXEpKSB7XG4gICAgYXVkaXRBdXRoekRlbmlhbChyZXEsICdzeXN0ZW0tYWRtaW4nKTtcbiAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgcmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTixcbiAgICAgICdBY2Nlc3MgZGVuaWVkLiBPbmx5IHN5c3RlbSBhZG1pbmlzdHJhdG9ycyBjYW4gcGVyZm9ybSB0aGlzIGFjdGlvbi4nLFxuICAgICAgRXJyb3JDb2RlLklOU1VGRklDSUVOVF9QRVJNSVNTSU9OUyxcbiAgICApO1xuICB9XG4gIG5leHQoKTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlIGEgc3BlY2lmaWMgZmVhdHVyZSBmbGFnLiBVc2UgYWZ0ZXIgcmVxdWlyZUF1dGguXG4gKiBDaGVja3MgdGhlIGBmZWF0dXJlc2AgYXJyYXkgaW4gdGhlIEpXVCBwYXlsb2FkIChzZXQgYXQgdG9rZW4gaXNzdWFuY2UpLlxuICogU3lzYWRtaW5zIChpc1N1cGVyQWRtaW4pIGJ5cGFzcyDigJQgdGhleSBhbHdheXMgaGF2ZSBldmVyeSBmZWF0dXJlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUZlYXR1cmUoZmVhdHVyZTogc3RyaW5nKSB7XG4gIHJldHVybiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcS51c2VyKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdBdXRoZW50aWNhdGlvbiByZXF1aXJlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICAgIH1cblxuICAgIC8vIFN5c2FkbWlucyBnZXQgYWxsIGZlYXR1cmVzOyB0aGUgYGZlYXR1cmVzYCBhcnJheSBvbiB0aGVpciB0b2tlbiBpc1xuICAgIC8vIHBvcHVsYXRlZCB3aXRoIGV2ZXJ5IGZsYWcgYXQgaXNzdWFuY2UgdGltZSBidXQgdGhlIGJ5cGFzcyBoZXJlIGtlZXBzXG4gICAgLy8gdGhlIHJ1bGUgZXhwbGljaXQgYW5kIHN1cnZpdmVzIGEgdG9rZW4gaXNzdWVkIGJlZm9yZSBhIG5ldyBmZWF0dXJlXG4gICAgLy8gZmxhZyB3YXMgYWRkZWQuXG4gICAgaWYgKHJlcS51c2VyLmlzU3VwZXJBZG1pbiA9PT0gdHJ1ZSkgcmV0dXJuIG5leHQoKTtcblxuICAgIGlmICghcmVxLnVzZXIuZmVhdHVyZXM/LmluY2x1ZGVzKGZlYXR1cmUpKSB7XG4gICAgICAvLyBSb3V0ZSBmZWF0dXJlLWdhdGUgZGVuaWFscyB0aHJvdWdoIHRoZSBzYW1lIGF1ZGl0IHNpbmsgYXNcbiAgICAgIC8vIHJlcXVpcmVQZXJtaXNzaW9uIC8gcmVxdWlyZVN5c3RlbUFkbWluIHNvIGEgcHJvYmUgZm9yIGFuXG4gICAgICAvLyB1bmVudGl0bGVkIGNhcGFiaWxpdHkgbGVhdmVzIGEgdHJhaWwgKHN0YXRlLWNoYW5naW5nIG1ldGhvZHMgb25seSkuXG4gICAgICBhdWRpdEF1dGh6RGVuaWFsKHJlcSwgYGZlYXR1cmU6JHtmZWF0dXJlfWApO1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgICAgcmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTixcbiAgICAgICAgYFRoaXMgZmVhdHVyZSByZXF1aXJlcyBhIGhpZ2hlciBwbGFuICgke2ZlYXR1cmV9KWAsXG4gICAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgICApO1xuICAgIH1cblxuICAgIG5leHQoKTtcbiAgfTtcbn1cblxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG4vLyBTZXJ2aWNlLXRvLXNlcnZpY2UgdG9rZW5zXG4vL1xuLy8gSW50ZXItc2VydmljZSBIVFRQIGNhbGxzIChiaWxsaW5nIOKGkiBtZXNzYWdlLCBwbGF0Zm9ybSDihpIgY29tcGxpYW5jZSwgZXRjLilcbi8vIG5lZWQgdG8gc2F0aXNmeSB0aGUgc2FtZSBgcmVxdWlyZUF1dGhgIG1pZGRsZXdhcmUgYXMgdXNlciByZXF1ZXN0cy5cbi8vIGBzaWduU2VydmljZVRva2VuYCBtaW50cyBhIHNob3J0LWxpdmVkIEpXVCBzaWduZWQgd2l0aCB0aGUgc2hhcmVkXG4vLyBKV1RfU0VDUkVULCBpZGVudGlmeWluZyB0aGUgY2FsbGluZyBzZXJ2aWNlIHZpYSBgc3ViOiAnc2VydmljZTo8bmFtZT4nYC5cbi8vIGByZXF1aXJlQXV0aGAgYWNjZXB0cyB0aGVzZSB0b2tlbnMgdHJhbnNwYXJlbnRseSDigJQgdGhleSBwYXNzIGBkZWNvZGVkLnN1YmBcbi8vIGFuZCBgZGVjb2RlZC5yb2xlYCBjaGVja3MsIGFuZCBkb3duc3RyZWFtIGByZXF1aXJlT3JnYW5pemF0aW9uYCAvXG4vLyBgcmVxdWlyZVN5c3RlbUFkbWluYCByZWx5IG9uIHRoZSBvcmcvcm9sZSBlbWJlZGRlZCBpbiB0aGUgdG9rZW4uXG4vL1xuLy8gVG9rZW5zIGRlZmF1bHQgdG8gNS1taW51dGUgVFRMIOKAlCBsb25nIGVub3VnaCB0byBzdXJ2aXZlIGEgYmFja2VuZCBob3AsXG4vLyBzaG9ydCBlbm91Z2ggdGhhdCBhIGxlYWtlZCB0b2tlbiBpcyBsb3ctdmFsdWUuXG4vLyAtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuY29uc3QgREVGQVVMVF9TRVJWSUNFX1RPS0VOX1RUTF9TRUNPTkRTID0gMzAwO1xuXG4vKipcbiAqIERlbnlsaXN0IG9mIHNlcnZpY2UgTkFNRVMgKHRoZSBgPG5hbWU+YCBpbiBgc3ViOiBzZXJ2aWNlOjxuYW1lPmApIHdob3NlIHRva2Vuc1xuICogYHJlcXVpcmVBdXRoYCBtdXN0IHJlamVjdC4gU2VlZGVkIGZyb20gYFNFUlZJQ0VfVE9LRU5fREVOWUxJU1RgIChjb21tYS1zZXBhcmF0ZWQpXG4gKiBhdCBtb2R1bGUgbG9hZDsgYSBzZXJ2aWNlIGNhbiBwdXNoIGxpdmUgdXBkYXRlcyAoZS5nLiBmcm9tIGEgUmVkaXMtc3Vic2NyaWJlZFxuICoga2lsbC1zd2l0Y2gpIHZpYSB7QGxpbmsgc2V0U2VydmljZVRva2VuRGVueWxpc3R9IHNvIGEgY29tcHJvbWlzZWQgc2VydmljZSBjYW4gYmVcbiAqIGN1dCBvZmYgV0lUSE9VVCByb3RhdGluZyB0aGUgc2hhcmVkIEpXVCBzZWNyZXQgKHdoaWNoIGludmFsaWRhdGVzIGFsbCBvZiB0aGVtKS5cbiAqL1xubGV0IHNlcnZpY2VUb2tlbkRlbnlsaXN0ID0gbmV3IFNldChcbiAgKHByb2Nlc3MuZW52LlNFUlZJQ0VfVE9LRU5fREVOWUxJU1QgfHwgJycpXG4gICAgLnNwbGl0KCcsJylcbiAgICAubWFwKChzKSA9PiBzLnRyaW0oKSlcbiAgICAuZmlsdGVyKEJvb2xlYW4pLFxuKTtcblxuLyoqIFJlcGxhY2UgdGhlIHNlcnZpY2UtdG9rZW4gZGVueWxpc3QgKHNlcnZpY2UgbmFtZXMpLiBFbXB0eSDih5Iga2lsbC1zd2l0Y2ggb2ZmLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldFNlcnZpY2VUb2tlbkRlbnlsaXN0KG5hbWVzOiBJdGVyYWJsZTxzdHJpbmc+KTogdm9pZCB7XG4gIHNlcnZpY2VUb2tlbkRlbnlsaXN0ID0gbmV3IFNldChbLi4ubmFtZXNdLm1hcCgocykgPT4gcy50cmltKCkpLmZpbHRlcihCb29sZWFuKSk7XG59XG5cbi8qKiBUcnVlIHdoZW4gYHN1YmAgaXMgYHNlcnZpY2U6PG5hbWU+YCBhbmQgYDxuYW1lPmAgaXMgb24gdGhlIGRlbnlsaXN0LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzU2VydmljZVRva2VuRGVuaWVkKHN1Yjogc3RyaW5nKTogYm9vbGVhbiB7XG4gIGlmIChzZXJ2aWNlVG9rZW5EZW55bGlzdC5zaXplID09PSAwKSByZXR1cm4gZmFsc2U7XG4gIGlmICghc3ViLnN0YXJ0c1dpdGgoJ3NlcnZpY2U6JykpIHJldHVybiBmYWxzZTtcbiAgcmV0dXJuIHNlcnZpY2VUb2tlbkRlbnlsaXN0LmhhcyhzdWIuc2xpY2UoJ3NlcnZpY2U6Jy5sZW5ndGgpKTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBTZXJ2aWNlVG9rZW5PcHRpb25zIHtcbiAgLyoqIENhbGxpbmcgc2VydmljZSBpZGVudGlmaWVyIChlLmcuICdiaWxsaW5nJywgJ3BsYXRmb3JtJykuIEVtYmVkZGVkIGFzIGBzdWI6IHNlcnZpY2U6PG5hbWU+YC4gKi9cbiAgc2VydmljZU5hbWU6IHN0cmluZztcbiAgLyoqIEFjdGl2ZSBvcmcgY29udGV4dCBmb3IgdGhlIGNhbGwuIFVzZSB0aGUgdGFyZ2V0IHRlbmFudCdzIG9yZyBpZCwgb3IgdGhlXG4gICAqICB3ZWxsLWtub3duIGBTWVNURU1fT1JHX0lEYCAoYW4gT2JqZWN0SWQpIGZvciBzeXN0ZW0td2lkZSBvcHMg4oCUIE5PVCB0aGUgc3RyaW5nXG4gICAqICAnc3lzdGVtJywgd2hpY2ggaWQtYmFzZWQgc3lzdGVtLW9yZyBjaGVja3Mgd29uJ3QgcmVjb2duaXplLiAqL1xuICBvcmdJZD86IHN0cmluZztcbiAgLyoqIEFjdGl2ZSBvcmcgbmFtZS4gRGVmYXVsdHMgdG8gb3JnSWQuICovXG4gIG9yZ05hbWU/OiBzdHJpbmc7XG4gIC8qKiBUVEwgaW4gc2Vjb25kcyAoZGVmYXVsdCAzMDApLiAqL1xuICB0dGxTZWNvbmRzPzogbnVtYmVyO1xuICAvKipcbiAgICogUm9sZSB0aGUgdG9rZW4gY2FycmllcyAocmVxdWlyZWQg4oCUIG5vIGltcGxpY2l0IGRlZmF1bHQpLiAqKlBhc3MgdGhlIExPV0VTVFxuICAgKiByb2xlIHRoZSBjYWxsIGFjdHVhbGx5IG5lZWRzKiogKGAnbWVtYmVyJ2AgZm9yIHJlYWQgLyBkYXRhLXBsYW5lIGNhbGxzKSBzbyBhXG4gICAqIGxlYWtlZCBzZXJ2aWNlIHRva2VuIGNhbid0IHBlcmZvcm0gYWRtaW4gYWN0aW9ucyBpbiB0aGUgdGFyZ2V0IG9yZy5cbiAgICogYGlzQWRtaW5gIGlzIGRlcml2ZWQgZnJvbSB0aGlzIChhZG1pbnxvd25lciDihpIgdHJ1ZSkuXG4gICAqL1xuICByb2xlOiAnb3duZXInIHwgJ2FkbWluJyB8ICdtZW1iZXInO1xuICAvKipcbiAgICogT3B0aW9uYWwgZmluZS1ncmFpbmVkIHBlcm1pc3Npb24gY2xhaW0uIFByZWZlciB0aGlzICsgYHJvbGU6ICdtZW1iZXInYCBvdmVyIGFcbiAgICogaGlnaCByb2xlIHdoZW4gYSBjYWxsIG5lZWRzIE9ORSBzcGVjaWZpYyBjYXBhYmlsaXR5IChlLmcuIGBbJ3BsdWdpbnM6d3JpdGUnXWBcbiAgICogdG8gcHVzaCBhIHBsdWdpbiBpbWFnZSkg4oCUIHRoZSB0b2tlbiB0aGVuIHNhdGlzZmllcyB0aGF0IHBlcm1pc3Npb24gZ2F0ZVxuICAgKiBXSVRIT1VUIGNhcnJ5aW5nIGBpc0FkbWluYCwgc28gYSBsZWFrZWQgdG9rZW4gY2FuJ3QgcGVyZm9ybSBhZG1pbiBhY3Rpb25zLlxuICAgKi9cbiAgcGVybWlzc2lvbnM/OiBQZXJtaXNzaW9uW107XG59XG5cbi8qKlxuICogTWludCBhIEpXVCBpZGVudGlmeWluZyB0aGUgY2FsbGluZyBzZXJ2aWNlLiBVc2VkIGZvciBpbnRlci1zZXJ2aWNlIEhUVFAgY2FsbHMuXG4gKiBUaGUgdG9rZW4gc2F0aXNmaWVzIGByZXF1aXJlQXV0aGAgYW5kICh3aGVuIG9yZ0lkIGlzIHByZXNlbnQpIGByZXF1aXJlT3JnYW5pemF0aW9uYC5cbiAqIFNjb3BlIGl0IHdpdGggYG9wdHMucm9sZWAg4oCUIGxlYXN0IHByaXZpbGVnZSBrZWVwcyBhIGxlYWtlZCB0b2tlbiBsb3ctdmFsdWUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzaWduU2VydmljZVRva2VuKG9wdHM6IFNlcnZpY2VUb2tlbk9wdGlvbnMpOiBzdHJpbmcge1xuICBjb25zdCByb2xlID0gb3B0cy5yb2xlO1xuICBjb25zdCBwYXlsb2FkOiBKd3RQYXlsb2FkID0ge1xuICAgIHN1YjogYHNlcnZpY2U6JHtvcHRzLnNlcnZpY2VOYW1lfWAsXG4gICAgdXNlcm5hbWU6IGAke29wdHMuc2VydmljZU5hbWV9LXNlcnZpY2VgLFxuICAgIGVtYWlsOiBgJHtvcHRzLnNlcnZpY2VOYW1lfUBpbnRlcm5hbGAsXG4gICAgcm9sZSxcbiAgICBpc0FkbWluOiByb2xlID09PSAnb3duZXInIHx8IHJvbGUgPT09ICdhZG1pbicsXG4gICAgdHlwZTogJ2FjY2VzcycsXG4gICAgb3JnYW5pemF0aW9uSWQ6IG9wdHMub3JnSWQsXG4gICAgb3JnYW5pemF0aW9uTmFtZTogb3B0cy5vcmdOYW1lID8/IG9wdHMub3JnSWQsXG4gICAgLy8gTGVhc3QtcHJpdmlsZWdlIGNhcGFiaWxpdHkgY2xhaW0gKG9wdGlvbmFsKSDigJQgbGV0cyBhIG1lbWJlci1yb2xlIHRva2VuXG4gICAgLy8gc2F0aXNmeSBhIHNwZWNpZmljIHBlcm1pc3Npb24gZ2F0ZSB3aXRob3V0IGNhcnJ5aW5nIGlzQWRtaW4uXG4gICAgLi4uKG9wdHMucGVybWlzc2lvbnMgJiYgb3B0cy5wZXJtaXNzaW9ucy5sZW5ndGggPiAwID8geyBwZXJtaXNzaW9uczogb3B0cy5wZXJtaXNzaW9ucyB9IDoge30pLFxuICB9O1xuICAvLyBNYXRjaCB0aGUgb3B0aW9uYWwgaXNzdWVyL2F1ZGllbmNlIHRoYXQgcmVxdWlyZUF1dGggdmVyaWZpZXMsIHdoZW5cbiAgLy8gY29uZmlndXJlZC4gV2l0aG91dCB0aGVzZSwgYSBzZXJ2aWNlIHRva2VuIHNpZ25lZCBoZXJlIHdvdWxkIGZhaWxcbiAgLy8gcmVxdWlyZUF1dGggaW4gYSBkZXBsb3ltZW50IHRoYXQgaGFzIHNldCBKV1RfSVNTVUVSL0pXVF9BVURJRU5DRS5cbiAgY29uc3Qgc2lnbk9wdGlvbnM6IGp3dC5TaWduT3B0aW9ucyA9IHtcbiAgICBleHBpcmVzSW46IG9wdHMudHRsU2Vjb25kcyA/PyBERUZBVUxUX1NFUlZJQ0VfVE9LRU5fVFRMX1NFQ09ORFMsXG4gICAgLy8gU2lnbiB3aXRoIHRoZSBzYW1lIGNvbmZpZ3VyZWQgYWxnIHJlcXVpcmVBdXRoIHBpbnMgb24gdmVyaWZ5LCBzbyBzZXJ2aWNlXG4gICAgLy8gdG9rZW5zIHN0YXkgdmFsaWQgdW5kZXIgYSBub24tZGVmYXVsdCBKV1RfQUxHT1JJVEhNLlxuICAgIGFsZ29yaXRobTogKHByb2Nlc3MuZW52LkpXVF9BTEdPUklUSE0gfHwgJ0hTMjU2JykgYXMgand0LkFsZ29yaXRobSxcbiAgICAvLyBVbmlxdWUgdG9rZW4gaWQgb24gZXZlcnkgbWludC4gQ29tYmluZWQgd2l0aCB0aGUgc2hvcnQgKDMwMHMgZGVmYXVsdCkgVFRMXG4gICAgLy8gdGhpcyBnaXZlcyBlYWNoIHNlcnZpY2UgdG9rZW4gYSBkaXN0aW5jdCBpZGVudGl0eSDigJQgdGhlIGJ1aWxkaW5nIGJsb2NrIGZvclxuICAgIC8vIHJlcGxheSBkZXRlY3Rpb24gKGEgdmVyaWZpZXIgY2FuIHRyYWNrIHNlZW4ganRpcykgYW5kIHRoZSBjb3JyZWxhdGlvblxuICAgIC8vIGhhbmRsZSBmb3IgdHJhY2luZyB3aGljaCBtaW50IHBlcmZvcm1lZCBhIGNyb3NzLXNlcnZpY2UgYWN0aW9uLiBJdCBkb2VzXG4gICAgLy8gTk9UIGJ5IGl0c2VsZiBwcmV2ZW50IHJlcGxheSB3aXRoaW4gdGhlIFRUTCB3aW5kb3c7IHRydWUgcmVwbGF5IGRlZmVuY2VcbiAgICAvLyBuZWVkcyB0aGUgYXN5bW1ldHJpYy1rZXkgd29yayB0cmFja2VkIHNlcGFyYXRlbHkuXG4gICAgand0aWQ6IHJhbmRvbVVVSUQoKSxcbiAgfTtcbiAgaWYgKHByb2Nlc3MuZW52LkpXVF9JU1NVRVIpIHNpZ25PcHRpb25zLmlzc3VlciA9IHByb2Nlc3MuZW52LkpXVF9JU1NVRVI7XG4gIGlmIChwcm9jZXNzLmVudi5KV1RfQVVESUVOQ0UpIHNpZ25PcHRpb25zLmF1ZGllbmNlID0gcHJvY2Vzcy5lbnYuSldUX0FVRElFTkNFO1xuICByZXR1cm4gand0LnNpZ24ocGF5bG9hZCwgZ2V0Snd0U2VjcmV0KCksIHNpZ25PcHRpb25zKTtcbn1cblxuLyoqIENvbnZlbmllbmNlOiByZXR1cm5zIGEgYEJlYXJlciA8dG9rZW4+YCBoZWFkZXIgdmFsdWUgZm9yIGZldGNoL2F4aW9zIGNhbGxzLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNlcnZpY2VBdXRoSGVhZGVyKG9wdHM6IFNlcnZpY2VUb2tlbk9wdGlvbnMpOiBzdHJpbmcge1xuICByZXR1cm4gYEJlYXJlciAke3NpZ25TZXJ2aWNlVG9rZW4ob3B0cyl9YDtcbn1cblxuLyoqIFRydWUgd2hlbiBgcmVxLnVzZXIuc3ViYCB3YXMgaXNzdWVkIGJ5IGBzaWduU2VydmljZVRva2VuYCAoaS5lLiBzdGFydHMgd2l0aCBgc2VydmljZTpgKS4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NlcnZpY2VQcmluY2lwYWwocmVxOiBSZXF1ZXN0KTogYm9vbGVhbiB7XG4gIHJldHVybiByZXEudXNlcj8uc3ViPy5zdGFydHNXaXRoKCdzZXJ2aWNlOicpID8/IGZhbHNlO1xufVxuXG4vKipcbiAqIFBSRS1hdXRoIGNoZWNrOiBjcnlwdG9ncmFwaGljYWxseSB2ZXJpZnkgdGhlIHJlcXVlc3QgY2FycmllcyBhIHZhbGlkLCBzaWduZWRcbiAqIFNFUlZJQ0UgdG9rZW4gKGBzdWJgIHN0YXJ0cyB3aXRoIGBzZXJ2aWNlOmApLiBVbmxpa2Uge0BsaW5rIGlzU2VydmljZVByaW5jaXBhbH1cbiAqICh3aGljaCByZWFkcyB0aGUgYWxyZWFkeS1wb3B1bGF0ZWQgYHJlcS51c2VyYCksIHRoaXMgdmVyaWZpZXMgdGhlIGJlYXJlciB0b2tlblxuICogaXRzZWxmLCBzbyBpdCBpcyBzYWZlIHRvIGNhbGwgQkVGT1JFIGByZXF1aXJlQXV0aGAgcnVucyDigJQgZS5nLiB0aGUgZ2xvYmFsIHJhdGVcbiAqIGxpbWl0ZXIncyBgc2tpcGAsIHdoaWNoIG11c3Qgbm90IHRydXN0IHRoZSBzcG9vZmFibGUgYHgtaW50ZXJuYWwtc2VydmljZWBcbiAqIGhlYWRlci4gTWlycm9ycyBgcmVxdWlyZUF1dGhgJ3MgdmVyaWZpY2F0aW9uIChhbGdvcml0aG0gcGlubmluZyArIG9wdGlvbmFsXG4gKiBpc3N1ZXIvYXVkaWVuY2UpIGFuZCByZXR1cm5zIGBmYWxzZWAgb24gYW55IG1pc3NpbmcvaW52YWxpZC9ub24tc2VydmljZSB0b2tlbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmlmeVNlcnZpY2VQcmluY2lwYWwocmVxOiBSZXF1ZXN0KTogYm9vbGVhbiB7XG4gIGNvbnN0IHBhcnRzID0gcmVxLmhlYWRlcnMuYXV0aG9yaXphdGlvbj8uc3BsaXQoJyAnKTtcbiAgaWYgKCFwYXJ0cyB8fCBwYXJ0cy5sZW5ndGggIT09IDIgfHwgcGFydHNbMF0gIT09ICdCZWFyZXInKSByZXR1cm4gZmFsc2U7XG4gIHRyeSB7XG4gICAgY29uc3QgdmVyaWZ5T3B0aW9uczogand0LlZlcmlmeU9wdGlvbnMgPSB7IGFsZ29yaXRobXM6IFsocHJvY2Vzcy5lbnYuSldUX0FMR09SSVRITSB8fCAnSFMyNTYnKSBhcyBqd3QuQWxnb3JpdGhtXSB9O1xuICAgIGlmIChwcm9jZXNzLmVudi5KV1RfSVNTVUVSKSB2ZXJpZnlPcHRpb25zLmlzc3VlciA9IHByb2Nlc3MuZW52LkpXVF9JU1NVRVI7XG4gICAgaWYgKHByb2Nlc3MuZW52LkpXVF9BVURJRU5DRSkgdmVyaWZ5T3B0aW9ucy5hdWRpZW5jZSA9IHByb2Nlc3MuZW52LkpXVF9BVURJRU5DRTtcbiAgICBjb25zdCBkZWNvZGVkID0gdmVyaWZ5Snd0V2l0aFJvdGF0aW9uKHBhcnRzWzFdLCB2ZXJpZnlPcHRpb25zKTtcbiAgICBpZiAoZGVjb2RlZC50eXBlICE9PSAnYWNjZXNzJyB8fCB0eXBlb2YgZGVjb2RlZC5zdWIgIT09ICdzdHJpbmcnIHx8ICFkZWNvZGVkLnN1Yi5zdGFydHNXaXRoKCdzZXJ2aWNlOicpKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gQSBkZW55bGlzdGVkIChraWxsZWQpIHNlcnZpY2UgbXVzdCBOT1QgYmUgdHJlYXRlZCBhcyBhIHRydXN0ZWQgcHJpbmNpcGFsIOKAlFxuICAgIC8vIG90aGVyd2lzZSBpdCBrZWVwcyB0aGUgcmF0ZS1saW1pdGVyIGV4ZW1wdGlvbiBldmVuIHRob3VnaCByZXF1aXJlQXV0aCByZWplY3RzXG4gICAgLy8gaXQgb24gcmVhbCByb3V0ZXMuIEZvbGQgdGhlIGtpbGwtc3dpdGNoIGludG8gdGhlIHByZS1hdXRoIGNoZWNrIHRvby5cbiAgICByZXR1cm4gIWlzU2VydmljZVRva2VuRGVuaWVkKGRlY29kZWQuc3ViKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4iXX0=
|
|
612
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYXV0aC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL2F1dGgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRXBDLE9BQU8sR0FBRyxNQUFNLGNBQWMsQ0FBQztBQUMvQixPQUFPLEVBQUUsVUFBVSxFQUFFLE1BQU0sNkJBQTZCLENBQUM7QUFFekQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBRXBELE9BQU8sRUFBbUIsYUFBYSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFDekUsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBQ3RELE9BQU8sRUFBRSxXQUFXLEVBQXdCLE1BQU0sc0JBQXNCLENBQUM7QUFDekUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSw0QkFBNEIsQ0FBQztBQUN6RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFFakQsTUFBTSxNQUFNLEdBQUcsWUFBWSxDQUFDLGlCQUFpQixDQUFDLENBQUM7QUFFL0MsNERBQTREO0FBQzVELElBQUksVUFBOEIsQ0FBQztBQUNuQyxJQUFJLHFCQUFxQixHQUFHLENBQUMsQ0FBQztBQUM5Qiw4RUFBOEU7QUFDOUUsSUFBSSxrQkFBc0MsQ0FBQztBQUMzQyxJQUFJLDZCQUE2QixHQUFHLENBQUMsQ0FBQztBQUN0QyxNQUFNLDhCQUE4QixHQUFHLE9BQU8sQ0FBQyxDQUFDLFlBQVk7QUFFNUQsU0FBUyxZQUFZO0lBQ25CLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUN2QixJQUFJLENBQUMsVUFBVSxJQUFJLEdBQUcsR0FBRyxxQkFBcUIsR0FBRyw4QkFBOEIs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Q0FBQyxFQUFFLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELElBQUksT0FBTyxDQUFDLElBQUksS0FBSyxRQUFRLElBQUksT0FBTyxPQUFPLENBQUMsR0FBRyxLQUFLLFFBQVEsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFVBQVUsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3RILDZFQUE2RTtRQUM3RSxnRkFBZ0Y7UUFDaEYsdUVBQXVFO1FBQ3ZFLE9BQU8sQ0FBQyxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLENBQUM7SUFDNUMsQ0FBQztJQUFDLE1BQU0sQ0FBQztRQUNQLE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgcmFuZG9tVVVJRCB9IGZyb20gJ2NyeXB0byc7XG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlLCBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcbmltcG9ydCBqd3QgZnJvbSAnanNvbndlYnRva2VuJztcbmltcG9ydCB7IEh0dHBTdGF0dXMgfSBmcm9tICcuLi9jb25zdGFudHMvaHR0cC1zdGF0dXMuanMnO1xuaW1wb3J0IHR5cGUgeyBKd3RQYXlsb2FkIH0gZnJvbSAnLi4vdHlwZXMvY29tbW9uLmpzJztcbmltcG9ydCB7IEVycm9yQ29kZSB9IGZyb20gJy4uL3R5cGVzL2Vycm9yLWNvZGVzLmpzJztcbmltcG9ydCB0eXBlIHsgSHR0cFJlcXVlc3QgfSBmcm9tICcuLi90eXBlcy9odHRwLmpzJztcbmltcG9ydCB7IHR5cGUgUGVybWlzc2lvbiwgaGFzUGVybWlzc2lvbiB9IGZyb20gJy4uL3R5cGVzL3Blcm1pc3Npb25zLmpzJztcbmltcG9ydCB7IGdldEhlYWRlclN0cmluZyB9IGZyb20gJy4uL3V0aWxzL2hlYWRlcnMuanMnO1xuaW1wb3J0IHsgZ2V0SWRlbnRpdHksIHR5cGUgUmVxdWVzdElkZW50aXR5IH0gZnJvbSAnLi4vdXRpbHMvaWRlbnRpdHkuanMnO1xuaW1wb3J0IHsgY3JlYXRlTG9nZ2VyIH0gZnJvbSAnLi4vdXRpbHMvbG9nZ2VyLmpzJztcbmltcG9ydCB7IGVtaXRDb3VudGVyIH0gZnJvbSAnLi4vdXRpbHMvbWV0cmljLWVtaXR0ZXIuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ2F1dGgtbWlkZGxld2FyZScpO1xuXG4vKiogQ2FjaGVkIEpXVCBzZWNyZXQgd2l0aCBwZXJpb2RpYyByZWZyZXNoIGZyb20gZW52IHZhci4gKi9cbmxldCBfand0U2VjcmV0OiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5sZXQgX2p3dFNlY3JldFJlZnJlc2hlZEF0ID0gMDtcbi8qKiBDYWNoZWQgUFJFVklPVVMgSldUIHNlY3JldCAob3B0aW9uYWwpIOKAlCBlbmFibGVzIHplcm8tZG93bnRpbWUgcm90YXRpb24uICovXG5sZXQgX2p3dFNlY3JldFByZXZpb3VzOiBzdHJpbmcgfCB1bmRlZmluZWQ7XG5sZXQgX2p3dFNlY3JldFByZXZpb3VzUmVmcmVzaGVkQXQgPSAwO1xuY29uc3QgSldUX1NFQ1JFVF9SRUZSRVNIX0lOVEVSVkFMX01TID0gMzAwXzAwMDsgLy8gNSBtaW51dGVzXG5cbmZ1bmN0aW9uIGdldEp3dFNlY3JldCgpOiBzdHJpbmcge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBpZiAoIV9qd3RTZWNyZXQgfHwgbm93IC0gX2p3dFNlY3JldFJlZnJlc2hlZEF0ID4gSldUX1NFQ1JFVF9SRUZSRVNIX0lOVEVSVkFMX01TKSB7XG4gICAgY29uc3Qgc2VjcmV0ID0gcHJvY2Vzcy5lbnYuSldUX1NFQ1JFVDtcbiAgICBpZiAoIXNlY3JldCkge1xuICAgICAgbG9nZ2VyLmVycm9yKCdKV1RfU0VDUkVUIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIG5vdCBzZXQnKTtcbiAgICAgIHRocm93IG5ldyBFcnJvcignSldUX1NFQ1JFVCBlbnZpcm9ubWVudCB2YXJpYWJsZSBpcyByZXF1aXJlZCcpO1xuICAgIH1cbiAgICBpZiAoX2p3dFNlY3JldCAmJiBfand0U2VjcmV0ICE9PSBzZWNyZXQpIHtcbiAgICAgIGxvZ2dlci5pbmZvKCdKV1Qgc2VjcmV0IHJvdGF0ZWQnKTtcbiAgICB9XG4gICAgX2p3dFNlY3JldCA9IHNlY3JldDtcbiAgICBfand0U2VjcmV0UmVmcmVzaGVkQXQgPSBub3c7XG4gIH1cbiAgcmV0dXJuIF9qd3RTZWNyZXQ7XG59XG5cbi8qKlxuICogVGhlIG9wdGlvbmFsIFBSRVZJT1VTIEpXVCBzZWNyZXQgKGBKV1RfU0VDUkVUX1BSRVZJT1VTYCksIGNhY2hlZCB3aXRoIHRoZSBzYW1lXG4gKiBUVEwgYXMgdGhlIHByaW1hcnkuIFJldHVybnMgYHVuZGVmaW5lZGAgd2hlbiB1bnNldC4gRHVyaW5nIGEgYEpXVF9TRUNSRVRgXG4gKiByb3RhdGlvbiwgb3BlcmF0b3JzIHNldCBgSldUX1NFQ1JFVF9QUkVWSU9VU2AgdG8gdGhlIG9sZCB2YWx1ZSBzbyB0b2tlbnMgc2lnbmVkXG4gKiB3aXRoIEVJVEhFUiBzZWNyZXQga2VlcCB2ZXJpZnlpbmcg4oCUIGNsb3NpbmcgdGhlIGF1dGgtb3V0YWdlIHdpbmRvdyB3aGVyZVxuICogc3RpbGwtdmFsaWQgb2xkLXNpZ25lZCAob3IgZnJlc2hseSBuZXctc2lnbmVkKSB0b2tlbnMgd291bGQgb3RoZXJ3aXNlIGJlXG4gKiByZWplY3RlZC4gYHVuZGVmaW5lZGAgaXMgYSB2YWxpZCBjYWNoZWQgdmFsdWUsIHNvIHRoaXMgcmVmcmVzaGVzIHB1cmVseSBvbiB0aGVcbiAqIHRpbWUgaW50ZXJ2YWwgKG5vdCBvbiBlbXB0aW5lc3MpLlxuICovXG5mdW5jdGlvbiBnZXRKd3RTZWNyZXRQcmV2aW91cygpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBpZiAobm93IC0gX2p3dFNlY3JldFByZXZpb3VzUmVmcmVzaGVkQXQgPiBKV1RfU0VDUkVUX1JFRlJFU0hfSU5URVJWQUxfTVMpIHtcbiAgICBfand0U2VjcmV0UHJldmlvdXMgPSBwcm9jZXNzLmVudi5KV1RfU0VDUkVUX1BSRVZJT1VTIHx8IHVuZGVmaW5lZDtcbiAgICBfand0U2VjcmV0UHJldmlvdXNSZWZyZXNoZWRBdCA9IG5vdztcbiAgfVxuICByZXR1cm4gX2p3dFNlY3JldFByZXZpb3VzO1xufVxuXG4vKipcbiAqIFRlc3Qtb25seTogZHJvcCB0aGUgY2FjaGVkIEpXVCBzZWNyZXRzIHNvIHRoZSBuZXh0IHZlcmlmeSByZS1yZWFkcyB0aGUgZW52LlxuICpcbiAqIEJvdGggc2VjcmV0cyBhcmUgY2FjaGVkIGZvciB7QGxpbmsgSldUX1NFQ1JFVF9SRUZSRVNIX0lOVEVSVkFMX01TfSwgc28gYSB0ZXN0XG4gKiB0aGF0IHNldHMgYEpXVF9TRUNSRVRgL2BKV1RfU0VDUkVUX1BSRVZJT1VTYCBtaWQtcnVuIHdvdWxkIG90aGVyd2lzZSBrZWVwXG4gKiB2ZXJpZnlpbmcgYWdhaW5zdCB0aGUgdmFsdWVzIHJlYWQgb24gZmlyc3QgdXNlLiBEb24ndCBjYWxsIGZyb20gcHJvZHVjdGlvblxuICogY29kZSDigJQgcm90YXRpb24gaXMgcGlja2VkIHVwIGJ5IHRoZSByZWZyZXNoIGludGVydmFsLlxuICovXG5leHBvcnQgZnVuY3Rpb24gX3Jlc2V0Snd0U2VjcmV0Q2FjaGVGb3JUZXN0cygpOiB2b2lkIHtcbiAgX2p3dFNlY3JldCA9IHVuZGVmaW5lZDtcbiAgX2p3dFNlY3JldFJlZnJlc2hlZEF0ID0gMDtcbiAgX2p3dFNlY3JldFByZXZpb3VzID0gdW5kZWZpbmVkO1xuICBfand0U2VjcmV0UHJldmlvdXNSZWZyZXNoZWRBdCA9IDA7XG59XG5cbi8qKlxuICogVGhlIEpXVCB2ZXJpZnkgb3B0aW9ucyBldmVyeSB0b2tlbiBjaGVjayBpbiB0aGUgZmxlZXQgbXVzdCBzaGFyZTogcGlubmVkXG4gKiBhbGdvcml0aG0gKGJsb2NrcyBhbGctY29uZnVzaW9uIC8gYGFsZzpub25lYCkgcGx1cyBpc3N1ZXIvYXVkaWVuY2Ugd2hlbiB0aGVcbiAqIGRlcGxveW1lbnQgY29uZmlndXJlcyB0aGVtLlxuICpcbiAqIENlbnRyYWxpemVkIGJlY2F1c2UgaXQgd2FzIGJ1aWx0IGlubGluZSBhdCBlYWNoIGNhbGwgc2l0ZSBhbmQgYHN0ZXAtdXAudHNgXG4gKiByZS1pbXBsZW1lbnRlZCBpdCBXSVRIT1VUIHRoZSBpc3N1ZXIvYXVkaWVuY2UgcGlubmluZyDigJQgc28gaW4gYSBkZXBsb3ltZW50XG4gKiB0aGF0IHNldHMgYEpXVF9JU1NVRVJgL2BKV1RfQVVESUVOQ0VgLCBhIHN0ZXAtdXAgdG9rZW4gbWludGVkIGJ5IGFueSBvdGhlclxuICogc3lzdGVtIHNoYXJpbmcgYEpXVF9TRUNSRVRgIHdhcyBhY2NlcHRlZC5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGJ1aWxkSnd0VmVyaWZ5T3B0aW9ucygpOiBqd3QuVmVyaWZ5T3B0aW9ucyB7XG4gIGNvbnN0IHZlcmlmeU9wdGlvbnM6IGp3dC5WZXJpZnlPcHRpb25zID0ge1xuICAgIGFsZ29yaXRobXM6IFsocHJvY2Vzcy5lbnYuSldUX0FMR09SSVRITSB8fCAnSFMyNTYnKSBhcyBqd3QuQWxnb3JpdGhtXSxcbiAgfTtcbiAgaWYgKHByb2Nlc3MuZW52LkpXVF9JU1NVRVIpIHZlcmlmeU9wdGlvbnMuaXNzdWVyID0gcHJvY2Vzcy5lbnYuSldUX0lTU1VFUjtcbiAgaWYgKHByb2Nlc3MuZW52LkpXVF9BVURJRU5DRSkgdmVyaWZ5T3B0aW9ucy5hdWRpZW5jZSA9IHByb2Nlc3MuZW52LkpXVF9BVURJRU5DRTtcbiAgcmV0dXJuIHZlcmlmeU9wdGlvbnM7XG59XG5cbi8qKlxuICogVmVyaWZ5IGEgSldUIGFnYWluc3QgdGhlIHByaW1hcnkgc2VjcmV0LCBmYWxsaW5nIGJhY2sgdG8gdGhlIHByZXZpb3VzIHNlY3JldFxuICogKHdoZW4gYEpXVF9TRUNSRVRfUFJFVklPVVNgIGlzIGNvbmZpZ3VyZWQpIE9OTFkgb24gYSBzaWduYXR1cmUvdmVyaWZpY2F0aW9uXG4gKiBmYWlsdXJlLiBUaGlzIG1ha2VzIHRva2VuIHZlcmlmaWNhdGlvbiBzdXJ2aXZlIGEgc2VjcmV0IHJvdGF0aW9uIHdpdGggemVyb1xuICogZG93bnRpbWU6IGEgdG9rZW4gdmFsaWQgdW5kZXIgRUlUSEVSIHNlY3JldCBwYXNzZXMuXG4gKlxuICoganNvbndlYnRva2VuJ3MgYHZlcmlmeWAgdGFrZXMgYSBzaW5nbGUgc2VjcmV0LCBzbyB0aGlzIGlzIHRyeS1wcmltYXJ5LXRoZW4tXG4gKiBwcmV2aW91cyDigJQgTk9UIGEgc2VjcmV0IGFycmF5LiBObyBleGlzdGluZyBjaGVjayBpcyB3ZWFrZW5lZDpcbiAqICAgLSBgdmVyaWZ5T3B0aW9uc2AgKGFsZ29yaXRobSBwaW5uaW5nICsgb3B0aW9uYWwgaXNzdWVyL2F1ZGllbmNlKSBpcyBhcHBsaWVkXG4gKiAgICAgaWRlbnRpY2FsbHkgb24gQk9USCBhdHRlbXB0cywgc28gYWxnLWNvbmZ1c2lvbiAvIGBhbGc6bm9uZWAgc3RheSBibG9ja2VkLlxuICogICAtIEV4cGlyeSAvIG5vdC1iZWZvcmUgZnJvbSB0aGUgUFJJTUFSWSBhdHRlbXB0IGFyZSBhdXRob3JpdGF0aXZlIGFuZCBhcmVcbiAqICAgICByZS10aHJvd24gd2l0aG91dCBhIHByZXZpb3VzLXNlY3JldCByZXRyeSwgc28gYSBgVG9rZW5FeHBpcmVkRXJyb3JgIGlzXG4gKiAgICAgbmV2ZXIgbWFza2VkIGludG8gYW4gXCJpbnZhbGlkIHNpZ25hdHVyZVwiLlxuICogICAtIFdoZW4gbm8gcHJldmlvdXMgc2VjcmV0IGlzIHNldCwgYmVoYXZpb3VyIGlzIGJ5dGUtZm9yLWJ5dGUgdGhlIG9yaWdpbmFsOlxuICogICAgIHRoZSBwcmltYXJ5IGVycm9yIHByb3BhZ2F0ZXMgdW5jaGFuZ2VkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyaWZ5Snd0V2l0aFJvdGF0aW9uKHRva2VuOiBzdHJpbmcsIHZlcmlmeU9wdGlvbnM6IGp3dC5WZXJpZnlPcHRpb25zKTogSnd0UGF5bG9hZCB7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGp3dC52ZXJpZnkodG9rZW4sIGdldEp3dFNlY3JldCgpLCB2ZXJpZnlPcHRpb25zKSBhcyBKd3RQYXlsb2FkO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IGdldEp3dFNlY3JldFByZXZpb3VzKCk7XG4gICAgLy8gRmFsbCBiYWNrIHRvIHRoZSBwcmV2aW91cyBzZWNyZXQgb25seSBmb3IgYSBzaWduYXR1cmUvdmVyaWZpY2F0aW9uIGZhaWx1cmVcbiAgICAvLyAoYSBwbGFpbiBKc29uV2ViVG9rZW5FcnJvcikuIEV4cGlyeSAvIG5vdC1iZWZvcmUgYXJlIGVuZm9yY2VkIHJlZ2FyZGxlc3Mgb2ZcbiAgICAvLyB3aGljaCBzZWNyZXQgc2lnbmVkIHRoZSB0b2tlbiwgc28gdGhvc2UgZXJyb3JzIG11c3Qgc3VyZmFjZSBhcy1pcy5cbiAgICBpZiAoXG4gICAgICBwcmV2aW91c1xuICAgICAgJiYgZXJyIGluc3RhbmNlb2Ygand0Lkpzb25XZWJUb2tlbkVycm9yXG4gICAgICAmJiAhKGVyciBpbnN0YW5jZW9mIGp3dC5Ub2tlbkV4cGlyZWRFcnJvcilcbiAgICAgICYmICEoZXJyIGluc3RhbmNlb2Ygand0Lk5vdEJlZm9yZUVycm9yKVxuICAgICkge1xuICAgICAgLy8gQSB0b2tlbiBzaWduZWQgYnkgdGhlIHByZXZpb3VzIHNlY3JldCB2ZXJpZmllcyBoZXJlOyBpZiBpdCBpcyBpbnN0ZWFkXG4gICAgICAvLyBleHBpcmVkL2ludmFsaWQgdW5kZXIgdGhlIHByZXZpb3VzIHNlY3JldCwgdGhhdCBlcnJvciBwcm9wYWdhdGVzIGFuZCBpc1xuICAgICAgLy8gaGFuZGxlZCBieSB0aGUgY2FsbGVyIGV4YWN0bHkgbGlrZSBhIHByaW1hcnkgZmFpbHVyZS5cbiAgICAgIHJldHVybiBqd3QudmVyaWZ5KHRva2VuLCBwcmV2aW91cywgdmVyaWZ5T3B0aW9ucykgYXMgSnd0UGF5bG9hZDtcbiAgICB9XG4gICAgdGhyb3cgZXJyO1xuICB9XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVxdWlyZUF1dGhPcHRpb25zIHtcbiAgLyoqXG4gICAqIEFsbG93IHgtb3JnLWlkL3gtb3JnLW5hbWUgaGVhZGVycyB0byBvdmVycmlkZSB0aGUgSldUJ3Mgb3JnYW5pemF0aW9uIGZpZWxkcy5cbiAgICpcbiAgICogV2hlbiBlbmFibGVkLCB0aGUgYHgtb3JnLWlkYC9geC1vcmctbmFtZWAgaGVhZGVycyBvdmVycmlkZSB0aGUgY2FsbGVyJ3Mgb3JnXG4gICAqIOKAlCBidXQgT05MWSBmb3IgYSB2ZXJpZmllZCBTWVMtQURNSU4gKGBpc1N1cGVyQWRtaW5gIGNsYWltKS4gRm9yIGFueSBvcmRpbmFyeVxuICAgKiBhdXRoZW50aWNhdGVkIHVzZXIgdGhlIGhlYWRlcnMgYXJlIGlnbm9yZWQsIHNvIGVuYWJsaW5nIHRoaXMgY2FuIG5ldmVyIGxldCBhXG4gICAqIG5vcm1hbCB1c2VyIGltcGVyc29uYXRlIGFub3RoZXIgdGVuYW50J3Mgb3JnLiBVc2UgZm9yIGNyb3NzLW9yZyBhZG1pbiB0b29saW5nXG4gICAqIChlLmcuIGEgc3lzYWRtaW4gbWFuYWdpbmcgYSBnaXZlbiBvcmcncyBiaWxsaW5nKS4gSWYgdW5zdXJlLCBsZWF2ZSBpdCBkaXNhYmxlZC5cbiAgICovXG4gIGFsbG93T3JnSGVhZGVyT3ZlcnJpZGU/OiBib29sZWFuO1xufVxuXG4vKiogSldUIGF1dGggbWlkZGxld2FyZS4gVXNlIGRpcmVjdGx5IG9yIGNhbGwgd2l0aCBvcHRpb25zLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBdXRoKFxuICByZXE6IFJlcXVlc3QsXG4gIHJlczogUmVzcG9uc2UsXG4gIG5leHQ6IE5leHRGdW5jdGlvbixcbik6IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUF1dGgoXG4gIG9wdGlvbnM/OiBSZXF1aXJlQXV0aE9wdGlvbnMsXG4pOiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHZvaWQ7XG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZUF1dGgoXG4gIHJlcU9yT3B0aW9ucz86IFJlcXVlc3QgfCBSZXF1aXJlQXV0aE9wdGlvbnMsXG4gIHJlcz86IFJlc3BvbnNlLFxuICBuZXh0PzogTmV4dEZ1bmN0aW9uLFxuKTogdm9pZCB8ICgocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pID0+IHZvaWQpIHtcbiAgaWYgKHJlcU9yT3B0aW9ucyAmJiByZXMgJiYgbmV4dCAmJiAnaGVhZGVycycgaW4gcmVxT3JPcHRpb25zKSB7XG4gICAgcmV0dXJuIF9yZXF1aXJlQXV0aCh7fSwgcmVxT3JPcHRpb25zIGFzIFJlcXVlc3QsIHJlcywgbmV4dCk7XG4gIH1cblxuICBjb25zdCBvcHRpb25zID0gKHJlcU9yT3B0aW9ucyBhcyBSZXF1aXJlQXV0aE9wdGlvbnMpIHx8IHt9O1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzSW5uZXI6IFJlc3BvbnNlLCBuZXh0SW5uZXI6IE5leHRGdW5jdGlvbikgPT4ge1xuICAgIF9yZXF1aXJlQXV0aChvcHRpb25zLCByZXEsIHJlc0lubmVyLCBuZXh0SW5uZXIpO1xuICB9O1xufVxuXG4vKipcbiAqIEEgc291cmNlIG9mIHRoZSBDVVJSRU5UIGB0b2tlblZlcnNpb25gIGZvciBhIHVzZXIsIGJhY2tlZCBieSBhIHN0b3JlIHRoZVxuICogc3RhdGVsZXNzIHNlcnZpY2VzIGNhbiByZWFkIChpbiBwcmFjdGljZSBhIFJlZGlzIGtleSB0aGUgcGxhdGZvcm0gcHVibGlzaGVzXG4gKiB0byBvbiBldmVyeSBwcml2aWxlZ2UgY2hhbmdlKS4gUmVnaXN0ZXJlZCB2aWEge0BsaW5rIHNldFRva2VuUmV2b2NhdGlvblN0b3JlfS5cbiAqXG4gKiBgZ2V0Q3VycmVudFZlcnNpb25gIHJldHVybnMgdGhlIHVzZXIncyBjdXJyZW50IHZlcnNpb24sIG9yIGBudWxsYCB3aGVuIHRoZVxuICogc3RvcmUgaGFzIG5vIGVudHJ5IOKAlCBhIG1pc3MgaXMgdHJlYXRlZCBhcyBcIm5vIGtub3duIHJldm9jYXRpb25cIiAoZmFpbC1vcGVuKTpcbiAqIHJldm9jYXRpb24gZW50cmllcyBhcmUgcHVibGlzaGVkIHdpdGggYSBUVEwgbWF0Y2hpbmcgdGhlIGFjY2Vzcy10b2tlblxuICogbGlmZXRpbWUsIHNvIGEgbWlzc2luZyBlbnRyeSBtZWFucyBhbnkgdG9rZW4gb2xkIGVub3VnaCB0byBwcmVkYXRlIGl0IGhhc1xuICogYWxyZWFkeSBleHBpcmVkIG9uIGl0cyBvd24uXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgVG9rZW5SZXZvY2F0aW9uU3RvcmUge1xuICBnZXRDdXJyZW50VmVyc2lvbih1c2VySWQ6IHN0cmluZyk6IFByb21pc2U8bnVtYmVyIHwgbnVsbD47XG59XG5cbmxldCB0b2tlblJldm9jYXRpb25TdG9yZTogVG9rZW5SZXZvY2F0aW9uU3RvcmUgfCB1bmRlZmluZWQ7XG5cbi8qKlxuICogUmVnaXN0ZXIgKG9yIGNsZWFyLCB3aXRoIGB1bmRlZmluZWRgKSB0aGUgcHJvY2Vzcy13aWRlIHRva2VuLXJldm9jYXRpb24gc3RvcmUuXG4gKiBXaGVuIHVuc2V0ICh0aGUgZGVmYXVsdCksIGByZXF1aXJlQXV0aGAgcGVyZm9ybXMgTk8gcmV2b2NhdGlvbiBjaGVjayAoaXQgcmVsaWVzXG4gKiBvbiB0aGUgc2hvcnQgYWNjZXNzLXRva2VuIFRUTCk7IHNlcnZpY2VzIG9wdCBpbiBhdCBib290IGJ5IHdpcmluZyB0aGVpciBSZWRpc1xuICogY2xpZW50LiBQbGF0Zm9ybSBrZWVwcyBpdHMgb3duIE1vbmdvLWJhY2tlZCBjaGVjayBhbmQgbmVlZCBub3QgcmVnaXN0ZXIgb25lLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0VG9rZW5SZXZvY2F0aW9uU3RvcmUoc3RvcmU6IFRva2VuUmV2b2NhdGlvblN0b3JlIHwgdW5kZWZpbmVkKTogdm9pZCB7XG4gIHRva2VuUmV2b2NhdGlvblN0b3JlID0gc3RvcmU7XG4gIGlmIChzdG9yZSkgcmV2b2NhdGlvblN0b3JlTWlzc2luZ1dhcm5lZCA9IGZhbHNlOyAvLyByZS1hcm0gaWYgYSBzdG9yZSBpcyAocmUpcmVnaXN0ZXJlZFxufVxuXG4vKiogT25lLXNob3QgZ3VhcmQgc28gdGhlIFwicmV2b2NhdGlvbiBpbmFjdGl2ZVwiIHdhcm5pbmcgZG9lc24ndCBmbG9vZCB0aGUgbG9ncy4gKi9cbmxldCByZXZvY2F0aW9uU3RvcmVNaXNzaW5nV2FybmVkID0gZmFsc2U7XG5cbi8qKlxuICogUmV0dXJucyB0cnVlIHdoZW4gYGRlY29kZWRgIGhhcyBiZWVuIHJldm9rZWQgcGVyIHRoZSByZWdpc3RlcmVkIHN0b3JlOiBpdHNcbiAqIGVtYmVkZGVkIGB0b2tlblZlcnNpb25gIGlzIHN0cmljdGx5IGJlaGluZCB0aGUgc3RvcmUncyBjdXJyZW50IHZlcnNpb24uXG4gKiBGYWlsLW9wZW4g4oCUIGFueSBzdG9yZSBlcnJvciwgYSBtaXNzaW5nIGVudHJ5LCBvciBhIHRva2VuL3N0b3JlIHdpdGhvdXQgYVxuICogdXNhYmxlIHZlcnNpb24geWllbGRzIGBmYWxzZWAgKGFsbG93KS4gTmV2ZXIgdGhyb3dzLlxuICovXG5hc3luYyBmdW5jdGlvbiBpc1Rva2VuUmV2b2tlZChkZWNvZGVkOiBKd3RQYXlsb2FkKTogUHJvbWlzZTxib29sZWFuPiB7XG4gIGNvbnN0IHN0b3JlID0gdG9rZW5SZXZvY2F0aW9uU3RvcmU7XG4gIGlmICghc3RvcmUpIHtcbiAgICAvLyBNYWtlIHRoZSBcInJldm9jYXRpb24gaXMgT0ZGXCIgc3RhdGUgT0JTRVJWQUJMRTogYSBzZXJ2aWNlIHRoYXQgdmVyaWZpZXMgdXNlclxuICAgIC8vIHRva2VucyBidXQgZm9yZ290IGBzZXRUb2tlblJldm9jYXRpb25TdG9yZSgpYCBzaWxlbnRseSBkaXNhYmxlcyB0aGUgc2Vzc2lvblxuICAgIC8vIGtpbGwtc3dpdGNoLiBXYXJuIE9OQ0UgKG9ubHkgZm9yIGEgcmV2b2NhYmxlIHVzZXIgdG9rZW4pIHNvIGEgbWlzY29uZmlndXJlZFxuICAgIC8vIGJvb3Qgc3VyZmFjZXMgaW4gdGhlIGxvZ3MgaW5zdGVhZCBvZiBmYWlsaW5nIG9wZW4gaW52aXNpYmx5LlxuICAgIGlmICghcmV2b2NhdGlvblN0b3JlTWlzc2luZ1dhcm5lZCAmJiBkZWNvZGVkLnN1YiAmJiB0eXBlb2YgZGVjb2RlZC50b2tlblZlcnNpb24gPT09ICdudW1iZXInKSB7XG4gICAgICByZXZvY2F0aW9uU3RvcmVNaXNzaW5nV2FybmVkID0gdHJ1ZTtcbiAgICAgIGxvZ2dlci53YXJuKCdUb2tlbiByZXZvY2F0aW9uIHN0b3JlIE5PVCByZWdpc3RlcmVkIOKAlCByZXZvY2F0aW9uIGNoZWNrcyBhcmUgSU5BQ1RJVkUgKHNldFRva2VuUmV2b2NhdGlvblN0b3JlIHdhcyBuZXZlciBjYWxsZWQpOyByZXZva2VkL2NvbXByb21pc2VkIHNlc3Npb25zIHN0YXkgdmFsaWQgdW50aWwgbmF0dXJhbCBUVEwnKTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG4gIGlmICghZGVjb2RlZC5zdWIgfHwgdHlwZW9mIGRlY29kZWQudG9rZW5WZXJzaW9uICE9PSAnbnVtYmVyJykgcmV0dXJuIGZhbHNlO1xuICB0cnkge1xuICAgIGNvbnN0IGN1cnJlbnQgPSBhd2FpdCBzdG9yZS5nZXRDdXJyZW50VmVyc2lvbihkZWNvZGVkLnN1Yik7XG4gICAgcmV0dXJuIGN1cnJlbnQgIT09IG51bGwgJiYgZGVjb2RlZC50b2tlblZlcnNpb24gPCBjdXJyZW50O1xuICB9IGNhdGNoIHtcbiAgICAvLyBGYWlsLW9wZW46IGEgcmV2b2NhdGlvbi1zdG9yZSBvdXRhZ2UgbXVzdCBub3QgbG9jayBldmVyeSB1c2VyIG91dC5cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn1cblxuLyoqXG4gKiBQdWJsaWMgcmV2b2NhdGlvbiBjaGVjayBmb3Igcm91dGVzIHRoYXQgdmVyaWZ5IGEgcGxhdGZvcm0gSldUIE9VVFNJREVcbiAqIGByZXF1aXJlQXV0aGAgKGUuZy4gdGhlIGltYWdlLXJlZ2lzdHJ5IGAvdG9rZW5gIG1pbnQgcGF0aCwgd2hpY2ggcmVzb2x2ZXNcbiAqIGlkZW50aXR5IGl0c2VsZikuIFJldHVybnMgdHJ1ZSB3aGVuIHRoZSB0b2tlbidzIGB0b2tlblZlcnNpb25gIGlzIHN0cmljdGx5XG4gKiBiZWhpbmQgdGhlIHN0b3JlJ3MgY3VycmVudCB2ZXJzaW9uLiBGYWlsLW9wZW4gKG5ldmVyIHRocm93cykg4oCUIGEgc3RvcmUgb3V0YWdlXG4gKiBvciBhIHRva2VuL3N0b3JlIHdpdGhvdXQgYSB1c2FibGUgdmVyc2lvbiB5aWVsZHMgZmFsc2UgKGFsbG93KSwgbWF0Y2hpbmdcbiAqIGByZXF1aXJlQXV0aGAuIFBhc3MgdGhlIHZlcmlmaWVkIEpXVCBjbGFpbXMgKGBzdWJgLCBgdG9rZW5WZXJzaW9uYCkuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBpc0FjY2Vzc1Rva2VuUmV2b2tlZChjbGFpbXM6IHsgc3ViPzogc3RyaW5nOyB0b2tlblZlcnNpb24/OiBudW1iZXIgfSk6IFByb21pc2U8Ym9vbGVhbj4ge1xuICByZXR1cm4gaXNUb2tlblJldm9rZWQoY2xhaW1zIGFzIEp3dFBheWxvYWQpO1xufVxuXG5mdW5jdGlvbiBfcmVxdWlyZUF1dGgoXG4gIG9wdGlvbnM6IFJlcXVpcmVBdXRoT3B0aW9ucyxcbiAgcmVxOiBSZXF1ZXN0LFxuICByZXM6IFJlc3BvbnNlLFxuICBuZXh0OiBOZXh0RnVuY3Rpb24sXG4pOiB2b2lkIHtcbiAgY29uc3QgYXV0aEhlYWRlciA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb247XG5cbiAgaWYgKCFhdXRoSGVhZGVyKSB7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aG9yaXphdGlvbiBoZWFkZXIgcmVxdWlyZWQnLCBFcnJvckNvZGUuVE9LRU5fTUlTU0lORyk7XG4gIH1cblxuICBjb25zdCBwYXJ0cyA9IGF1dGhIZWFkZXIuc3BsaXQoJyAnKTtcbiAgaWYgKHBhcnRzLmxlbmd0aCAhPT0gMiB8fCBwYXJ0c1swXSAhPT0gJ0JlYXJlcicpIHtcbiAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdJbnZhbGlkIGF1dGhvcml6YXRpb24gZm9ybWF0LiBVc2U6IEJlYXJlciA8dG9rZW4+JywgRXJyb3JDb2RlLlRPS0VOX0lOVkFMSUQpO1xuICB9XG5cbiAgdHJ5IHtcbiAgICAvLyBQYXNzIHRocm91Z2ggb3B0aW9uYWwgaXNzdWVyL2F1ZGllbmNlIHZlcmlmaWNhdGlvbiB3aGVuIGVudi1jb25maWd1cmVkLlxuICAgIC8vIFdpdGhvdXQgdGhlc2UsIGEgSldUIHNpZ25lZCBieSBhbnkgc3lzdGVtIHRoYXQgaGFwcGVucyB0byBzaGFyZSB0aGVcbiAgICAvLyBzYW1lIEpXVF9TRUNSRVQgd291bGQgYmUgYWNjZXB0ZWQg4oCUIGRlZmVuY2UtaW4tZGVwdGggZm9yIHNoYXJlZC1zZWNyZXRcbiAgICAvLyBtaXNjb25maWd1cmF0aW9ucyBhY3Jvc3Mgc2VydmljZXMgLyBlbnZpcm9ubWVudHMuXG4gICAgLy8gUGluIHRoZSBhY2NlcHRlZCBhbGdvcml0aG0gdG8gdGhlIGNvbmZpZ3VyZWQgSE1BQyBhbGcgKGRlZmF1bHQgSFMyNTYpLlxuICAgIC8vIFdpdGhvdXQgYW4gYWxsb3ctbGlzdCwgYGp3dC52ZXJpZnlgIGFjY2VwdHMgYW55IGFsZ29yaXRobSB0aGUga2V5IGNhblxuICAgIC8vIHZlcmlmeSDigJQgdGhlIGNsYXNzaWMgYWxnLWNvbmZ1c2lvbiB2ZWN0b3IgKGFuZCBhIGhhcmQgZ3VhcmQgYWdhaW5zdFxuICAgIC8vIGBhbGc6bm9uZWApLiBFbnYtZHJpdmVuIHNvIGl0IHN0YXlzIGluIGxvY2tzdGVwIHdpdGggaG93IHRva2VucyBhcmVcbiAgICAvLyBzaWduZWQgKHNlZSBzaWduU2VydmljZVRva2VuICsgcGxhdGZvcm0ncyBjb25maWcuYXV0aC5qd3QuYWxnb3JpdGhtKS5cbiAgICBjb25zdCB2ZXJpZnlPcHRpb25zID0gYnVpbGRKd3RWZXJpZnlPcHRpb25zKCk7XG4gICAgY29uc3QgZGVjb2RlZCA9IHZlcmlmeUp3dFdpdGhSb3RhdGlvbihwYXJ0c1sxXSwgdmVyaWZ5T3B0aW9ucyk7XG5cbiAgICBpZiAoZGVjb2RlZC50eXBlICE9PSAnYWNjZXNzJykge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnT25seSBhY2Nlc3MgdG9rZW5zIGNhbiBiZSB1c2VkIGZvciBBUEkgcmVxdWVzdHMnLCBFcnJvckNvZGUuVE9LRU5fSU5WQUxJRCk7XG4gICAgfVxuXG4gICAgaWYgKCFkZWNvZGVkLnN1YiB8fCAhZGVjb2RlZC5yb2xlKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdUb2tlbiBtaXNzaW5nIHJlcXVpcmVkIGZpZWxkcycsIEVycm9yQ29kZS5UT0tFTl9JTlZBTElEKTtcbiAgICB9XG5cbiAgICAvLyBTZXJ2aWNlLXRva2VuIGtpbGwtc3dpdGNoOiByZWplY3QgYSBzZXJ2aWNlIHByaW5jaXBhbCB3aG9zZSBzZXJ2aWNlIGhhc1xuICAgIC8vIGJlZW4gYWRkZWQgdG8gdGhlIGRlbnlsaXN0LiBSb3RhdGluZyB0aGUgc2hhcmVkIEpXVCBzZWNyZXQgaXMgdGhlIG9ubHlcbiAgICAvLyBvdGhlciB3YXkgdG8gaW52YWxpZGF0ZSBhIHNlcnZpY2UgdG9rZW4gYmVmb3JlIGl0cyAoc2hvcnQpIFRUTCDigJQgYnV0IHRoYXRcbiAgICAvLyBudWtlcyBFVkVSWSBzZXJ2aWNlIHRva2VuIGZsZWV0LXdpZGUuIFRoaXMgbGV0cyBvbmUgY29tcHJvbWlzZWQvcm9ndWVcbiAgICAvLyBzZXJ2aWNlIGJlIGN1dCBvZmYgc3VyZ2ljYWxseS4gTygxKSBTZXQgbG9va3VwLCB6ZXJvIGNvc3Qgd2hlbiB0aGUgZGVueWxpc3RcbiAgICAvLyBpcyBlbXB0eSAodGhlIGRlZmF1bHQpLCBzbyBpdCBuZXZlciB0YXhlcyB0aGUgUzJTIGhvdCBwYXRoIHVubGVzcyBhcm1lZC5cbiAgICBpZiAoZGVjb2RlZC5zdWIuc3RhcnRzV2l0aCgnc2VydmljZTonKSAmJiBpc1NlcnZpY2VUb2tlbkRlbmllZChkZWNvZGVkLnN1YikpIHtcbiAgICAgIGVtaXRDb3VudGVyKCdzZXJ2aWNlX3Rva2VuX2RlbmllZF90b3RhbCcsIHsgc2VydmljZTogZGVjb2RlZC5zdWIuc2xpY2UoJ3NlcnZpY2U6Jy5sZW5ndGgpIH0pO1xuICAgICAgbG9nZ2VyLndhcm4oJ1JlamVjdGVkIGRlbnlsaXN0ZWQgc2VydmljZSB0b2tlbicsIHsgc3ViOiBkZWNvZGVkLnN1YiB9KTtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ1NlcnZpY2UgdG9rZW4gcmV2b2tlZCcsIEVycm9yQ29kZS5UT0tFTl9SRVZPS0VEKTtcbiAgICB9XG5cbiAgICByZXEudXNlciA9IHsgLi4uZGVjb2RlZCB9O1xuXG4gICAgLy8gVGhlIHgtb3JnLWlkL3gtb3JnLW5hbWUgb3ZlcnJpZGUgbGV0cyBhIFNZUy1BRE1JTiBhY3Qgb24gYSBjaG9zZW4gb3JnXG4gICAgLy8gKGNyb3NzLW9yZyBhZG1pbiB0b29saW5nKS4gSXQgaXMgZ2F0ZWQgb24gdGhlIHZlcmlmaWVkIGBpc1N1cGVyQWRtaW5gIGNsYWltXG4gICAgLy8gaGVyZSBzbyB0aGF0IGV2ZW4gYSByb3V0ZSB3aGljaCBtaXN0YWtlbmx5IGVuYWJsZXMgYGFsbG93T3JnSGVhZGVyT3ZlcnJpZGVgXG4gICAgLy8gY2FuIE5FVkVSIGxldCBhbiBvcmRpbmFyeSBhdXRoZW50aWNhdGVkIHVzZXIgc3Bvb2YgYW5vdGhlciB0ZW5hbnQncyBvcmcgdmlhXG4gICAgLy8gdGhlIGhlYWRlciDigJQgZGVmZW5jZS1pbi1kZXB0aCBhZ2FpbnN0IHRoZSBjcm9zcy10ZW5hbnQgYnJlYWsgdGhpcyBjYXVzZWQuXG4gICAgaWYgKG9wdGlvbnMuYWxsb3dPcmdIZWFkZXJPdmVycmlkZSAmJiBkZWNvZGVkLmlzU3VwZXJBZG1pbiA9PT0gdHJ1ZSkge1xuICAgICAgY29uc3QgaGVhZGVyT3JnSWQgPSBnZXRIZWFkZXJTdHJpbmcocmVxLmhlYWRlcnNbJ3gtb3JnLWlkJ10pO1xuICAgICAgY29uc3QgaGVhZGVyT3JnTmFtZSA9IGdldEhlYWRlclN0cmluZyhyZXEuaGVhZGVyc1sneC1vcmctbmFtZSddKTtcbiAgICAgIGlmIChoZWFkZXJPcmdJZCkgcmVxLnVzZXIub3JnYW5pemF0aW9uSWQgPSBoZWFkZXJPcmdJZDtcbiAgICAgIGlmIChoZWFkZXJPcmdOYW1lKSByZXEudXNlci5vcmdhbml6YXRpb25OYW1lID0gaGVhZGVyT3JnTmFtZTtcbiAgICB9XG5cbiAgICAvLyBSZS1kZXJpdmUgdGhlIHJlcXVlc3QncyB0ZW5hbnQgaWRlbnRpdHkgZnJvbSB0aGUgTk9XLXZlcmlmaWVkIEpXVC5cbiAgICAvL1xuICAgIC8vIGBhdHRhY2hSZXF1ZXN0Q29udGV4dGAgcnVucyBhcyBhIGdsb2JhbCBtaWRkbGV3YXJlIEJFRk9SRSB0aGlzIHBlci1yb3V0ZVxuICAgIC8vIGByZXF1aXJlQXV0aGAsIHNvIGl0IGNhcHR1cmVkIGByZXEuY29udGV4dC5pZGVudGl0eWAgd2hpbGUgYHJlcS51c2VyYCB3YXNcbiAgICAvLyBzdGlsbCB1bmRlZmluZWQg4oCUIGF0IHdoaWNoIHBvaW50IGBnZXRJZGVudGl0eWAgZmFsbHMgYmFjayB0byB0aGUgcmF3LFxuICAgIC8vIGNsaWVudC1zZXR0YWJsZSBgeC1vcmctaWRgL2B4LXVzZXItaWRgIGhlYWRlcnMuIEV2ZXJ5IGRvd25zdHJlYW0gdGVuYW50LVxuICAgIC8vIGF1dGhvcml0eSBjb25zdW1lciAocmVxdWlyZU9yZ0lkLCB3aXRoVGVuYW50Q29udGV4dCdzIFJMUyBzY29wZSwgY2hlY2tRdW90YSxcbiAgICAvLyB3aXRoUm91dGUsIGFuZCB0aGUgaWRlbXBvdGVuY3kgbmFtZXNwYWNlKSByZWFkcyBgcmVxLmNvbnRleHQuaWRlbnRpdHlgLCBzb1xuICAgIC8vIHRoYXQgZnJvemVuIGhlYWRlci1kZXJpdmVkIHZhbHVlIOKAlCBub3QgdGhlIEpXVCDigJQgd2FzIGdvdmVybmluZyB0ZW5hbmN5IG9uXG4gICAgLy8gYW55IG5vbi1uZ2lueCBwYXRoLiBSZWNvbXB1dGluZyBoZXJlLCBhdCB0aGUgc2luZ2xlIHBvc3QtdmVyaWZpY2F0aW9uIGNob2tlXG4gICAgLy8gcG9pbnQsIG1ha2VzIGBnZXRJZGVudGl0eWAgcHJlZmVyIHRoZSB2ZXJpZmllZCBgcmVxLnVzZXJgIChzZWUgaWRlbnRpdHkudHMpXG4gICAgLy8gc28gdGVuYW5jeSBpcyBKV1QtYXV0aG9yaXRhdGl2ZS4gVGhlIG5naW54IGB4LW9yZy1pZGAgb3ZlcndyaXRlIHN0YXlzIGFzXG4gICAgLy8gZGVmZW5jZS1pbi1kZXB0aC4gR3VhcmRlZCBvbiBgcmVxLmNvbnRleHRgIHNvIHNlcnZpY2VzL3BhdGhzIHRoYXQgbmV2ZXJcbiAgICAvLyBhdHRhY2ggYSBjb250ZXh0IChvciBydW4gcmVxdWlyZUF1dGggcHJlLWNvbnRleHQpIGFyZSB1bmFmZmVjdGVkLlxuICAgIGNvbnN0IHJlcUN0eCA9IChyZXEgYXMgUmVxdWVzdCAmIHsgY29udGV4dD86IHsgaWRlbnRpdHk6IFJlcXVlc3RJZGVudGl0eSB9IH0pLmNvbnRleHQ7XG4gICAgaWYgKHJlcUN0eCkge1xuICAgICAgcmVxQ3R4LmlkZW50aXR5ID0gZ2V0SWRlbnRpdHkocmVxIGFzIHVua25vd24gYXMgSHR0cFJlcXVlc3QpO1xuICAgIH1cblxuICAgIC8vIFNlc3Npb24taW52YWxpZGF0aW9uIGNoZWNrIGZvciB0aGUgc3RhdGVsZXNzIHNlcnZpY2VzOiByZWplY3QgYSB0b2tlblxuICAgIC8vIHdob3NlIGB0b2tlblZlcnNpb25gIGlzIGJlaGluZCB0aGUgcmV2b2NhdGlvbiBzdG9yZSdzIGN1cnJlbnQgdmFsdWUgKGFcbiAgICAvLyBwcml2aWxlZ2UgY2hhbmdlIHRoZSBwbGF0Zm9ybSBwdWJsaXNoZWQpLiBObyBzdG9yZSByZWdpc3RlcmVkIOKHkiB0aGlzIGlzIGFcbiAgICAvLyBuby1vcCBhbmQgY29udHJvbCBwYXNzZXMgc3RyYWlnaHQgdGhyb3VnaC4gRmFpbC1vcGVuIG9uIGFueSBzdG9yZSBlcnJvci5cbiAgICBpZiAodG9rZW5SZXZvY2F0aW9uU3RvcmUgJiYgZGVjb2RlZC5zdWIgJiYgdHlwZW9mIGRlY29kZWQudG9rZW5WZXJzaW9uID09PSAnbnVtYmVyJykge1xuICAgICAgLy8gYC5jYXRjaChuZXh0KWAgZm9yd2FyZHMgYSBET1dOU1RSRUFNIHN5bmNocm9ub3VzIHRocm93IGZyb20gYG5leHQoKWAgdG9cbiAgICAgIC8vIEV4cHJlc3MncyBlcnJvciBtaWRkbGV3YXJlIOKAlCB3aXRob3V0IGl0LCB0aGF0IHRocm93IHdvdWxkIHN1cmZhY2UgYXMgYW5cbiAgICAgIC8vIHVuaGFuZGxlZCByZWplY3Rpb24gKHRoaXMgYG5leHQoKWAgcnVucyBpbiBhIG1pY3JvdGFzaywgb3V0c2lkZSB0aGVcbiAgICAgIC8vIHN1cnJvdW5kaW5nIHRyeS9jYXRjaCBhbmQgRXhwcmVzcydzIHBlci1sYXllciBkaXNwYXRjaCkuIGBpc1Rva2VuUmV2b2tlZGBcbiAgICAgIC8vIGl0c2VsZiBuZXZlciByZWplY3RzIChpdCBmYWlsLW9wZW5zIGludGVybmFsbHkpLCBzbyB0aGUgY2F0Y2ggb25seSBldmVyXG4gICAgICAvLyBzZWVzIGEgZ2VudWluZSBkb3duc3RyZWFtIGVycm9yLlxuICAgICAgaXNUb2tlblJldm9rZWQoZGVjb2RlZClcbiAgICAgICAgLnRoZW4oKHJldm9rZWQpID0+IHtcbiAgICAgICAgICBpZiAocmV2b2tlZCkge1xuICAgICAgICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnU2Vzc2lvbiBoYXMgYmVlbiByZXZva2VkOyBwbGVhc2Ugc2lnbiBpbiBhZ2FpbicsIEVycm9yQ29kZS5UT0tFTl9SRVZPS0VEKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgbmV4dCgpO1xuICAgICAgICB9KVxuICAgICAgICAuY2F0Y2gobmV4dCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgbmV4dCgpO1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGlmIChlcnJvciBpbnN0YW5jZW9mIGp3dC5Ub2tlbkV4cGlyZWRFcnJvcikge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnVG9rZW4gaGFzIGV4cGlyZWQnLCBFcnJvckNvZGUuVE9LRU5fRVhQSVJFRCk7XG4gICAgfVxuXG4gICAgaWYgKGVycm9yIGluc3RhbmNlb2Ygand0Lkpzb25XZWJUb2tlbkVycm9yKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdJbnZhbGlkIHRva2VuJywgRXJyb3JDb2RlLlRPS0VOX0lOVkFMSUQpO1xuICAgIH1cblxuICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIGZhaWxlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICB9XG59XG5cbi8qKlxuICogV2hldGhlciB0aGUgcmVxdWVzdCdzIHVzZXIgaG9sZHMgYHBlcm1pc3Npb25gLiBTdXBlcmFkbWlucyBpbXBsaWNpdGx5IGhvbGRcbiAqIGV2ZXJ5IHBlcm1pc3Npb24uIFJlYWRzIHRoZSByZXNvbHZlZCBgcGVybWlzc2lvbnNgIGNsYWltIChzZXQgYXQgdG9rZW4gaXNzdWUsXG4gKiBvciByZS1kZXJpdmVkIHBlciByZXF1ZXN0IGJ5IHRoZSBwbGF0Zm9ybSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB1c2VySGFzUGVybWlzc2lvbihyZXE6IFJlcXVlc3QsIHBlcm1pc3Npb246IFBlcm1pc3Npb24pOiBib29sZWFuIHtcbiAgcmV0dXJuIGhhc1Blcm1pc3Npb24ocmVxLnVzZXI/LnBlcm1pc3Npb25zLCBwZXJtaXNzaW9uLCByZXEudXNlcj8uaXNTdXBlckFkbWluKTtcbn1cblxuLyoqXG4gKiBDb250ZXh0IHBhc3NlZCB0byBhIHJlZ2lzdGVyZWQgYXV0aG9yaXphdGlvbi1kZW5pYWwgYXVkaXRvciB3aGVuIGFcbiAqIHN0YXRlLWNoYW5naW5nIHJlcXVlc3QgaXMgcmVqZWN0ZWQgYnkgYHJlcXVpcmVQZXJtaXNzaW9uYCAvXG4gKiBgcmVxdWlyZVN5c3RlbUFkbWluYC5cbiAqL1xuZXhwb3J0IGludGVyZmFjZSBBdXRoekRlbmlhbEluZm8ge1xuICAvKiogVGhlIGRlbmllZCB1c2VyJ3MgaWQgKGBzdWJgKSwgaWYgYXV0aGVudGljYXRlZC4gKi9cbiAgYWN0b3JJZD86IHN0cmluZztcbiAgYWN0b3JFbWFpbD86IHN0cmluZztcbiAgLyoqIFRoZSB1c2VyJ3MgYWN0aXZlIG9yZyBhdCBkZW5pYWwgdGltZS4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG4gIC8qKiBIVFRQIG1ldGhvZCArIHBhdGggb2YgdGhlIHJlamVjdGVkIHJlcXVlc3QuICovXG4gIG1ldGhvZDogc3RyaW5nO1xuICBwYXRoOiBzdHJpbmc7XG4gIC8qKiBXaGF0IHdhcyByZXF1aXJlZDogdGhlIG1pc3NpbmcgcGVybWlzc2lvbihzKSwgb3IgJ3N5c3RlbS1hZG1pbicuICovXG4gIHJlcXVpcmVkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogT3B0aW9uYWwgc2luayBmb3IgZGVuaWVkLWF1dGhvcml6YXRpb24gZXZlbnRzLiBMZWZ0IHVuc2V0IGJ5IGRlZmF1bHQgc29cbiAqIGFwaS1jb3JlIHN0YXlzIGRlY291cGxlZCBmcm9tIGFueSBhdWRpdCB0cmFuc3BvcnQg4oCUIGEgc2VydmljZSByZWdpc3RlcnMgb25lXG4gKiBhdCBib290ICh0eXBpY2FsbHkgZm9yd2FyZGluZyB0byBpdHMgYFJlbW90ZUF1ZGl0Q2xpZW50YCBhcyBhblxuICogYGF1dGh6LmRlbmllZGAgZXZlbnQsIG9yLCBvbiBwbGF0Zm9ybSwgdG8gdGhlIGxvY2FsIGBhdWRpdCgpYCBoZWxwZXIpLlxuICogTVVTVCBiZSBiZXN0LWVmZm9ydDogaXQgaXMgaW52b2tlZCBpbnNpZGUgdGhlIHJlcXVlc3QgcGF0aCwgc28gaXQgbXVzdCBuZXZlclxuICogdGhyb3cgb3IgYmxvY2sgKHRoZSBnYXRlIHdyYXBzIHRoZSBjYWxsIGluIHRyeS9jYXRjaCByZWdhcmRsZXNzKS5cbiAqL1xubGV0IGF1dGh6RGVuaWFsQXVkaXRvcjogKChpbmZvOiBBdXRoekRlbmlhbEluZm8pID0+IHZvaWQpIHwgdW5kZWZpbmVkO1xuXG4vKipcbiAqIFJlZ2lzdGVyIChvciBjbGVhciwgd2l0aCBgdW5kZWZpbmVkYCkgdGhlIHByb2Nlc3Mtd2lkZSBhdXRob3JpemF0aW9uLWRlbmlhbFxuICogYXVkaXRvci4gSWRlbXBvdGVudDsgdGhlIGxhc3QgcmVnaXN0cmF0aW9uIHdpbnMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRBdXRoekRlbmlhbEF1ZGl0b3IoZm46ICgoaW5mbzogQXV0aHpEZW5pYWxJbmZvKSA9PiB2b2lkKSB8IHVuZGVmaW5lZCk6IHZvaWQge1xuICBhdXRoekRlbmlhbEF1ZGl0b3IgPSBmbjtcbn1cblxuLyoqXG4gKiBFbWl0IGEgZGVuaWFsIGV2ZW50LCBiZXN0LWVmZm9ydC4gT25seSBmaXJlcyBmb3Igc3RhdGUtY2hhbmdpbmcgKG5vbi1HRVQsXG4gKiBub24tSEVBRC9PUFRJT05TKSByZXF1ZXN0cyDigJQgYSByZWplY3RlZCBHRVQgaXMgbG93LXNpZ25hbCBwcm9iaW5nIG5vaXNlIGFuZFxuICogd291bGQgYW1wbGlmeSBhdWRpdCB2b2x1bWUgdW5kZXIgYSBzY2FuLiBOZXZlciB0aHJvd3MuXG4gKi9cbmZ1bmN0aW9uIGF1ZGl0QXV0aHpEZW5pYWwocmVxOiBSZXF1ZXN0LCByZXF1aXJlZDogc3RyaW5nKTogdm9pZCB7XG4gIGNvbnN0IGF1ZGl0b3IgPSBhdXRoekRlbmlhbEF1ZGl0b3I7XG4gIGlmICghYXVkaXRvcikgcmV0dXJuO1xuICBjb25zdCBtZXRob2QgPSByZXEubWV0aG9kLnRvVXBwZXJDYXNlKCk7XG4gIGlmIChtZXRob2QgPT09ICdHRVQnIHx8IG1ldGhvZCA9PT0gJ0hFQUQnIHx8IG1ldGhvZCA9PT0gJ09QVElPTlMnKSByZXR1cm47XG4gIHRyeSB7XG4gICAgYXVkaXRvcih7XG4gICAgICBhY3RvcklkOiByZXEudXNlcj8uc3ViLFxuICAgICAgYWN0b3JFbWFpbDogcmVxLnVzZXI/LmVtYWlsLFxuICAgICAgb3JnSWQ6IHJlcS51c2VyPy5vcmdhbml6YXRpb25JZCxcbiAgICAgIG1ldGhvZCxcbiAgICAgIC8vIFN0cmlwIHRoZSBxdWVyeSBzdHJpbmcg4oCUIGEgZGVuaWVkIHJlcXVlc3QgbWF5IGNhcnJ5IGEgdG9rZW4vc2VjcmV0IGFzIGFcbiAgICAgIC8vIHF1ZXJ5IHBhcmFtLCBhbmQgdGhpcyBwYXRoIGlzIHBlcnNpc3RlZCB2ZXJiYXRpbSBpbnRvIHRoZSBhdWRpdCBsb2cuXG4gICAgICBwYXRoOiAocmVxLm9yaWdpbmFsVXJsIHx8IHJlcS51cmwpLnNwbGl0KCc/JylbMF0sXG4gICAgICByZXF1aXJlZCxcbiAgICB9KTtcbiAgfSBjYXRjaCB7XG4gICAgLy8gQmVzdC1lZmZvcnQg4oCUIGEgYnJva2VuIGF1ZGl0b3IgbXVzdCBuZXZlciBicmVhayB0aGUgYXV0aCBnYXRlLlxuICB9XG59XG5cbi8qKlxuICogUmVxdWlyZXMgdGhhdCB0aGUgdXNlciBob2xkIEFUIExFQVNUIE9ORSBvZiB0aGUgZ2l2ZW4gcGVybWlzc2lvbnMgKG9yIGJlIGFcbiAqIHN1cGVyYWRtaW4pLiBVc2UgYWZ0ZXIgcmVxdWlyZUF1dGguIE1pcnJvcnMgYHJlcXVpcmVSb2xlYCdzIGFueS1vZiBzZW1hbnRpY3M7XG4gKiBwYXNzIGEgc2luZ2xlIHBlcm1pc3Npb24gZm9yIGEgc3BlY2lmaWMgYWN0aW9uLCBvciBzZXZlcmFsIHdoZW4gYW55IG9uZSBvZlxuICogdGhlbSBzaG91bGQgZ3JhbnQgYWNjZXNzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVBlcm1pc3Npb24oLi4ucGVybWlzc2lvbnM6IFBlcm1pc3Npb25bXSkge1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXEudXNlcikge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgICB9XG4gICAgLy8gdXNlckhhc1Blcm1pc3Npb24g4oaSIGhhc1Blcm1pc3Npb24gYWxyZWFkeSBncmFudHMgc3VwZXJhZG1pbnMgZXZlcnlcbiAgICAvLyBwZXJtaXNzaW9uLCBzbyB0aGlzIHNpbmdsZSBjaGVjayBjb3ZlcnMgYm90aCB0aGUgc3VwZXJhZG1pbiBieXBhc3MgYW5kXG4gICAgLy8gdGhlIGFueS1vZiBtZW1iZXJzaGlwIHRlc3Qgd2l0aG91dCByZS1pbmxpbmluZyBlaXRoZXIuXG4gICAgaWYgKHBlcm1pc3Npb25zLnNvbWUoKHApID0+IHVzZXJIYXNQZXJtaXNzaW9uKHJlcSwgcCkpKSByZXR1cm4gbmV4dCgpO1xuICAgIGF1ZGl0QXV0aHpEZW5pYWwocmVxLCBwZXJtaXNzaW9ucy5qb2luKCcgb3IgJykpO1xuICAgIHJldHVybiBzZW5kRXJyb3IoXG4gICAgICByZXMsIEh0dHBTdGF0dXMuRk9SQklEREVOLFxuICAgICAgYE1pc3NpbmcgcmVxdWlyZWQgcGVybWlzc2lvbjogJHtwZXJtaXNzaW9ucy5qb2luKCcgb3IgJyl9YCxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXF1aXJlcyB0aGF0IHRoZSB1c2VyIGhvbGQgRVZFUlkgb25lIG9mIHRoZSBnaXZlbiBwZXJtaXNzaW9ucyAob3IgYmUgYVxuICogc3VwZXJhZG1pbikg4oCUIHRoZSBBTkQgY291bnRlcnBhcnQgdG8gYHJlcXVpcmVQZXJtaXNzaW9uYCdzIGFueS1vZi4gVXNlIGZvciBhXG4gKiBzZW5zaXRpdmUgYWN0aW9uIHRoYXQgbGVnaXRpbWF0ZWx5IGRlbWFuZHMgdHdvIGRpc3RpbmN0IGNhcGFiaWxpdGllcyBhdCBvbmNlXG4gKiAoZS5nLiBhIGNyb3NzLXN1cmZhY2Ugb3BlcmF0aW9uKSwgc28gdGhlIGd1YXJhbnRlZSBpcyBleHBsaWNpdCByYXRoZXIgdGhhblxuICogYXBwcm94aW1hdGVkIGJ5IGNoYWluaW5nIHR3byBgcmVxdWlyZVBlcm1pc3Npb25gIGdhdGVzLiBTdXBlcmFkbWlucyBieXBhc3NcbiAqICh0aGV5IGltcGxpY2l0bHkgaG9sZCBldmVyeSBwZXJtaXNzaW9uKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVBbGxQZXJtaXNzaW9ucyguLi5wZXJtaXNzaW9uczogUGVybWlzc2lvbltdKSB7XG4gIHJldHVybiAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkID0+IHtcbiAgICBpZiAoIXJlcS51c2VyKSB7XG4gICAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5VTkFVVEhPUklaRUQsICdBdXRoZW50aWNhdGlvbiByZXF1aXJlZCcsIEVycm9yQ29kZS5VTkFVVEhPUklaRUQpO1xuICAgIH1cbiAgICBjb25zdCBtaXNzaW5nID0gcGVybWlzc2lvbnMuZmlsdGVyKChwKSA9PiAhdXNlckhhc1Blcm1pc3Npb24ocmVxLCBwKSk7XG4gICAgaWYgKG1pc3NpbmcubGVuZ3RoID09PSAwKSByZXR1cm4gbmV4dCgpO1xuICAgIGF1ZGl0QXV0aHpEZW5pYWwocmVxLCBwZXJtaXNzaW9ucy5qb2luKCcgYW5kICcpKTtcbiAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgcmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTixcbiAgICAgIGBNaXNzaW5nIHJlcXVpcmVkIHBlcm1pc3Npb246ICR7bWlzc2luZy5qb2luKCcgYW5kICcpfWAsXG4gICAgICBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TLFxuICAgICk7XG4gIH07XG59XG5cbi8qKlxuICogTGlrZSB7QGxpbmsgcmVxdWlyZVBlcm1pc3Npb259IChhbnktb2YpIGJ1dCBBTFNPIGFkbWl0cyBhbiBpbnRlcm5hbCBzZXJ2aWNlXG4gKiBwcmluY2lwYWwgKGEgYHNlcnZpY2U6KmAgbWFjaGluZSB0b2tlbikuIEZvciBSRUFEIGVuZHBvaW50cyB0aGF0IEJPVEhcbiAqIGludGVyYWN0aXZlIHVzZXJzIOKAlCB3aG8gbXVzdCBob2xkIG9uZSBvZiB0aGUgYDpyZWFkYCBjYXBhYmlsaXRpZXMg4oCUIEFORFxuICogc2VydmljZS10by1zZXJ2aWNlIGNhbGxlcnMgbGVnaXRpbWF0ZWx5IGhpdDsgc2VydmljZSB0b2tlbnMgY2Fycnkgbm9cbiAqIHBlcm1pc3Npb24gY2xhaW1zICh0aGV5J3JlIGxlYXN0LXByaXZpbGVnZSBgcm9sZTptZW1iZXJgKSwgc28gYSBwbGFpblxuICogYHJlcXVpcmVQZXJtaXNzaW9uYCB3b3VsZCB3cm9uZ2x5IDQwMyB0aGVtLiBTdXBlcmFkbWlucyBwYXNzIHZpYVxuICogYHVzZXJIYXNQZXJtaXNzaW9uYCdzIGltcGxpY2l0LWFsbC4gVXNlIG9ubHkgd2hlcmUgYSBzZXJ2aWNlIGNhbGxlciBpcyBhIGtub3duLFxuICogaW50ZW5kZWQgY29uc3VtZXIgb2YgdGhlIHJvdXRlICh2ZXJpZnkgdGhlIGNhbGxlcnMpOyBwcmVmZXIgcGxhaW5cbiAqIGByZXF1aXJlUGVybWlzc2lvbmAgZm9yIHB1cmVseSB1c2VyLWZhY2luZyByZWFkcy5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVQZXJtaXNzaW9uT3JTZXJ2aWNlKC4uLnBlcm1pc3Npb25zOiBQZXJtaXNzaW9uW10pIHtcbiAgcmV0dXJuIChyZXE6IFJlcXVlc3QsIHJlczogUmVzcG9uc2UsIG5leHQ6IE5leHRGdW5jdGlvbik6IHZvaWQgPT4ge1xuICAgIGlmICghcmVxLnVzZXIpIHtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IocmVzLCBIdHRwU3RhdHVzLlVOQVVUSE9SSVpFRCwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgRXJyb3JDb2RlLlVOQVVUSE9SSVpFRCk7XG4gICAgfVxuICAgIGlmIChpc1NlcnZpY2VQcmluY2lwYWwocmVxKSB8fCBwZXJtaXNzaW9ucy5zb21lKChwKSA9PiB1c2VySGFzUGVybWlzc2lvbihyZXEsIHApKSkgcmV0dXJuIG5leHQoKTtcbiAgICBhdWRpdEF1dGh6RGVuaWFsKHJlcSwgcGVybWlzc2lvbnMuam9pbignIG9yICcpKTtcbiAgICByZXR1cm4gc2VuZEVycm9yKFxuICAgICAgcmVzLCBIdHRwU3RhdHVzLkZPUkJJRERFTixcbiAgICAgIGBNaXNzaW5nIHJlcXVpcmVkIHBlcm1pc3Npb246ICR7cGVybWlzc2lvbnMuam9pbignIG9yICcpfWAsXG4gICAgICBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TLFxuICAgICk7XG4gIH07XG59XG5cbi8qKlxuICogR2F0ZSBhbiBlbmRwb2ludCB0byBpbnRlcm5hbCBzZXJ2aWNlLXRvLXNlcnZpY2UgY2FsbGVycyBvbmx5IChhIGBzZXJ2aWNlOipgXG4gKiBtYWNoaW5lIHByaW5jaXBhbCBtaW50ZWQgdmlhIHtAbGluayBzaWduU2VydmljZVRva2VufSAvIGBnZXRTZXJ2aWNlQXV0aEhlYWRlcmApLlxuICogUmVqZWN0cyBhbnkgdXNlciB0b2tlbi4gRm9yIE5PTi11c2VyLWZhY2luZyBlbmRwb2ludHMg4oCUIGVudGl0eS1ldmVudCBpbmdlc3QsXG4gKiBhdXRvLXN1YnNjcmliZSwgYW5kIHNpbWlsYXIgcGVlci1zZXJ2aWNlIGhvb2tzIOKAlCB0aGF0IGEgYnJvd3NlciBtdXN0IG5ldmVyXG4gKiByZWFjaC4gQ29tcG9zZSBhZnRlciBgcmVxdWlyZUF1dGhgIHNvIGByZXEudXNlcmAgaXMgcG9wdWxhdGVkLlxuICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVNlcnZpY2VQcmluY2lwYWwocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiB2b2lkIHtcbiAgaWYgKCFpc1NlcnZpY2VQcmluY2lwYWwocmVxKSkge1xuICAgIC8vIDQwMyAobm90IDQwMCkg4oCUIHRoaXMgaXMgYW4gYXV0aG9yaXphdGlvbiByZWZ1c2FsOyBzdGF0dXMgbXVzdCBtYXRjaCB0aGVcbiAgICAvLyBJTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMgY29kZSBhbmQgdGhlIHNpYmxpbmcgZ2F0ZXMgKHJlcXVpcmVQZXJtaXNzaW9uLCBldGMuKS5cbiAgICByZXR1cm4gc2VuZEVycm9yKHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sICdJbnRlcm5hbCBzZXJ2aWNlIGNhbGxzIG9ubHknLCBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TKTtcbiAgfVxuICBuZXh0KCk7XG59XG5cbi8qKlxuICogVGhlIHN5c3RlbSB0ZW5hbnQncyBjYW5vbmljYWwgb3JnICoqaWQqKiDigJQgYSBmaXhlZCwgd2VsbC1rbm93biBPYmplY3RJZCAoTk9UXG4gKiB0aGUgc3RyaW5nICdzeXN0ZW0nKS4gVGhpcyBpcyB0aGUgc2luZ2xlIGtub2IgZXZlcnkgc2VydmljZSByZXNvbHZlcyB0aGVcbiAqIHN5c3RlbSB0ZW5hbnQgdGhyb3VnaDsgb3ZlcnJpZGUgdmlhIHRoZSBgU1lTVEVNX09SR19JRGAgZW52IGZvciBhbHRlcm5hdGVcbiAqIGluc3RhbGxzLiBUaGUgc3lzdGVtIG9yZydzIGh1bWFuIGlkZW50aWZpZXIgc3RheXMgdGhlIHNsdWcvbmFtZSAnc3lzdGVtJ1xuICogKHNlZSB7QGxpbmsgU1lTVEVNX09SR19TTFVHfSk7IG9ubHkgaXRzIGBfaWRgIGlzIHRoaXMgT2JqZWN0SWQuXG4gKi9cbmV4cG9ydCBjb25zdCBTWVNURU1fT1JHX0lEID0gKHByb2Nlc3MuZW52LlNZU1RFTV9PUkdfSUQgfHwgJzAwMDAwMDAwMDAwMDAwMDAwMDAwMDAwMScpLnRvTG93ZXJDYXNlKCk7XG5cbi8qKiBUaGUgc3lzdGVtIG9yZydzIHdlbGwta25vd24gc2x1Zy9uYW1lICh0aGUgaHVtYW4gaWRlbnRpZmllcjsgaXRzIGBfaWRgIGlzIHtAbGluayBTWVNURU1fT1JHX0lEfSkuICovXG5leHBvcnQgY29uc3QgU1lTVEVNX09SR19TTFVHID0gJ3N5c3RlbSc7XG5cbi8qKlxuICogQ2hlY2sgaWYgYW4gb3JnSWQgb3Igb3JnTmFtZS9zbHVnIG1hdGNoZXMgdGhlIHN5c3RlbSBvcmcuIFVzZSB0aGlzIGluc3RlYWQgb2ZcbiAqIGNvbXBhcmluZyBkaXJlY3RseTogdGhlIGlkIGlzIG5vdyBhbiBPYmplY3RJZCAoe0BsaW5rIFNZU1RFTV9PUkdfSUR9KSB3aGlsZSB0aGVcbiAqIG5hbWUvc2x1ZyBpcyAnc3lzdGVtJyAoe0BsaW5rIFNZU1RFTV9PUkdfU0xVR30pLCBzbyB0aGUgdHdvIGFyZSBjb21wYXJlZCBhZ2FpbnN0XG4gKiB0aGVpciByZXNwZWN0aXZlIGNhbm9uaWNhbCB2YWx1ZXMuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1N5c3RlbU9yZ0lkKG9yZ0lkPzogc3RyaW5nLCBvcmdOYW1lPzogc3RyaW5nKTogYm9vbGVhbiB7XG4gIHJldHVybiBvcmdJZD8udG9Mb3dlckNhc2UoKSA9PT0gU1lTVEVNX09SR19JRCB8fCBvcmdOYW1lPy50b0xvd2VyQ2FzZSgpID09PSBTWVNURU1fT1JHX1NMVUc7XG59XG5cbi8qKlxuICogQ2hlY2sgaWYgdGhlIHJlcXVlc3QgaXMgZnJvbSBhIHN5c3RlbSBhZG1pbi5cbiAqXG4gKiBBdXRob3JpdHkgaXMgZ3JhbnRlZCBzb2xlbHkgYnkgdGhlIHVzZXItbGV2ZWwgYGlzU3VwZXJBZG1pbmAgZmxhZyBjYXJyaWVkXG4gKiBpbiB0aGUgSldULiBUaGUgXCJtZW1iZXJzaGlwIGluIHRoZSB3ZWxsLWtub3duICdzeXN0ZW0nIG9yZyB3aXRoIHJvbGVcbiAqIGFkbWluL293bmVyXCIgcGF0aCB3YXMgcmVtb3ZlZCDigJQgaXQgY29uZmxhdGVkIGEgUGlwZWxpbmUgQnVpbGRlciBvcGVyYXRvclxuICogd2l0aCBhIHJlYWwgY3VzdG9tZXIgdGVuYW50IGluIHRoZSBkYXRhIG1vZGVsLCBhbmQgbWVhbnQgYW55IHVuaW50ZW5kZWRcbiAqIHdyaXRlIHRoYXQgY3JlYXRlZCBhICdzeXN0ZW0nLW5hbWVkIG9yZyBjb3VsZCBxdWlldGx5IGdyYW50IGNyb3NzLW9yZ1xuICogYXV0aG9yaXR5LiBUaGUgYHN5c3RlbWAgb3JnIHN0aWxsIGV4aXN0cyBhcyBhICpjb250ZW50IGhvbGRlciogZm9yIHNoYXJlZFxuICogc2FtcGxlIGRhdGE7IGl0IGp1c3Qgbm8gbG9uZ2VyIGNvbmZlcnMgcHJpdmlsZWdlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTeXN0ZW1BZG1pbihyZXE6IFJlcXVlc3QpOiBib29sZWFuIHtcbiAgcmV0dXJuIHJlcS51c2VyPy5pc1N1cGVyQWRtaW4gPT09IHRydWU7XG59XG5cbi8qKlxuICogV2hldGhlciB0aGUgcmVxdWVzdCdzIHRva2VuIGNhcnJpZXMgYSBzcGVjaWZpYyBjYXBhYmlsaXR5IGBzY29wZWAgKGUuZy5cbiAqIGAncmVwb3J0aW5nOmluZ2VzdCdgKS4gVXNlZCB0byBnYXRlIGVuZHBvaW50cyB0aGF0IGFjY2VwdCBhIG5hcnJvdyBtYWNoaW5lXG4gKiBpZGVudGl0eSDigJQgYSBub3JtYWwgaW50ZXJhY3RpdmUgdXNlciB0b2tlbiBoYXMgbm8gYHNjb3BlYCBhbmQgcmV0dXJucyBmYWxzZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc1Njb3BlKHJlcTogUmVxdWVzdCwgc2NvcGU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVxLnVzZXI/LnNjb3BlID09PSBzY29wZTtcbn1cblxuLyoqIFJlcXVpcmVzIGEgc3lzdGVtIGFkbWluIOKAlCBncmFudGVkIHNvbGVseSBieSB0aGUgYGlzU3VwZXJBZG1pbmAgdG9rZW4gY2xhaW1cbiAqICAodGhlIG9yZy1tZW1iZXJzaGlwIHBhdGggd2FzIHJlbW92ZWQpLiBVc2UgYWZ0ZXIgcmVxdWlyZUF1dGguICovXG5leHBvcnQgZnVuY3Rpb24gcmVxdWlyZVN5c3RlbUFkbWluKFxuICByZXE6IFJlcXVlc3QsXG4gIHJlczogUmVzcG9uc2UsXG4gIG5leHQ6IE5leHRGdW5jdGlvbixcbik6IHZvaWQge1xuICBpZiAoIWlzU3lzdGVtQWRtaW4ocmVxKSkge1xuICAgIGF1ZGl0QXV0aHpEZW5pYWwocmVxLCAnc3lzdGVtLWFkbWluJyk7XG4gICAgcmV0dXJuIHNlbmRFcnJvcihcbiAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICAnQWNjZXNzIGRlbmllZC4gT25seSBzeXN0ZW0gYWRtaW5pc3RyYXRvcnMgY2FuIHBlcmZvcm0gdGhpcyBhY3Rpb24uJyxcbiAgICAgIEVycm9yQ29kZS5JTlNVRkZJQ0lFTlRfUEVSTUlTU0lPTlMsXG4gICAgKTtcbiAgfVxuICBuZXh0KCk7XG59XG5cbi8qKlxuICogUmVxdWlyZSBhIHNwZWNpZmljIGZlYXR1cmUgZmxhZy4gVXNlIGFmdGVyIHJlcXVpcmVBdXRoLlxuICogQ2hlY2tzIHRoZSBgZmVhdHVyZXNgIGFycmF5IGluIHRoZSBKV1QgcGF5bG9hZCAoc2V0IGF0IHRva2VuIGlzc3VhbmNlKS5cbiAqIFN5c2FkbWlucyAoaXNTdXBlckFkbWluKSBieXBhc3Mg4oCUIHRoZXkgYWx3YXlzIGhhdmUgZXZlcnkgZmVhdHVyZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHJlcXVpcmVGZWF0dXJlKGZlYXR1cmU6IHN0cmluZykge1xuICByZXR1cm4gKHJlcTogUmVxdWVzdCwgcmVzOiBSZXNwb25zZSwgbmV4dDogTmV4dEZ1bmN0aW9uKTogdm9pZCA9PiB7XG4gICAgaWYgKCFyZXEudXNlcikge1xuICAgICAgcmV0dXJuIHNlbmRFcnJvcihyZXMsIEh0dHBTdGF0dXMuVU5BVVRIT1JJWkVELCAnQXV0aGVudGljYXRpb24gcmVxdWlyZWQnLCBFcnJvckNvZGUuVU5BVVRIT1JJWkVEKTtcbiAgICB9XG5cbiAgICAvLyBTeXNhZG1pbnMgZ2V0IGFsbCBmZWF0dXJlczsgdGhlIGBmZWF0dXJlc2AgYXJyYXkgb24gdGhlaXIgdG9rZW4gaXNcbiAgICAvLyBwb3B1bGF0ZWQgd2l0aCBldmVyeSBmbGFnIGF0IGlzc3VhbmNlIHRpbWUgYnV0IHRoZSBieXBhc3MgaGVyZSBrZWVwc1xuICAgIC8vIHRoZSBydWxlIGV4cGxpY2l0IGFuZCBzdXJ2aXZlcyBhIHRva2VuIGlzc3VlZCBiZWZvcmUgYSBuZXcgZmVhdHVyZVxuICAgIC8vIGZsYWcgd2FzIGFkZGVkLlxuICAgIGlmIChyZXEudXNlci5pc1N1cGVyQWRtaW4gPT09IHRydWUpIHJldHVybiBuZXh0KCk7XG5cbiAgICBpZiAoIXJlcS51c2VyLmZlYXR1cmVzPy5pbmNsdWRlcyhmZWF0dXJlKSkge1xuICAgICAgLy8gUm91dGUgZmVhdHVyZS1nYXRlIGRlbmlhbHMgdGhyb3VnaCB0aGUgc2FtZSBhdWRpdCBzaW5rIGFzXG4gICAgICAvLyByZXF1aXJlUGVybWlzc2lvbiAvIHJlcXVpcmVTeXN0ZW1BZG1pbiBzbyBhIHByb2JlIGZvciBhblxuICAgICAgLy8gdW5lbnRpdGxlZCBjYXBhYmlsaXR5IGxlYXZlcyBhIHRyYWlsIChzdGF0ZS1jaGFuZ2luZyBtZXRob2RzIG9ubHkpLlxuICAgICAgYXVkaXRBdXRoekRlbmlhbChyZXEsIGBmZWF0dXJlOiR7ZmVhdHVyZX1gKTtcbiAgICAgIHJldHVybiBzZW5kRXJyb3IoXG4gICAgICAgIHJlcywgSHR0cFN0YXR1cy5GT1JCSURERU4sXG4gICAgICAgIGBUaGlzIGZlYXR1cmUgcmVxdWlyZXMgYSBoaWdoZXIgcGxhbiAoJHtmZWF0dXJlfSlgLFxuICAgICAgICBFcnJvckNvZGUuSU5TVUZGSUNJRU5UX1BFUk1JU1NJT05TLFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBuZXh0KCk7XG4gIH07XG59XG5cbi8vIC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuLy8gU2VydmljZS10by1zZXJ2aWNlIHRva2Vuc1xuLy9cbi8vIEludGVyLXNlcnZpY2UgSFRUUCBjYWxscyAoYmlsbGluZyDihpIgbWVzc2FnZSwgcGxhdGZvcm0g4oaSIGNvbXBsaWFuY2UsIGV0Yy4pXG4vLyBuZWVkIHRvIHNhdGlzZnkgdGhlIHNhbWUgYHJlcXVpcmVBdXRoYCBtaWRkbGV3YXJlIGFzIHVzZXIgcmVxdWVzdHMuXG4vLyBgc2lnblNlcnZpY2VUb2tlbmAgbWludHMgYSBzaG9ydC1saXZlZCBKV1Qgc2lnbmVkIHdpdGggdGhlIHNoYXJlZFxuLy8gSldUX1NFQ1JFVCwgaWRlbnRpZnlpbmcgdGhlIGNhbGxpbmcgc2VydmljZSB2aWEgYHN1YjogJ3NlcnZpY2U6PG5hbWU+J2AuXG4vLyBgcmVxdWlyZUF1dGhgIGFjY2VwdHMgdGhlc2UgdG9rZW5zIHRyYW5zcGFyZW50bHkg4oCUIHRoZXkgcGFzcyBgZGVjb2RlZC5zdWJgXG4vLyBhbmQgYGRlY29kZWQucm9sZWAgY2hlY2tzLCBhbmQgZG93bnN0cmVhbSBgcmVxdWlyZU9yZ2FuaXphdGlvbmAgL1xuLy8gYHJlcXVpcmVTeXN0ZW1BZG1pbmAgcmVseSBvbiB0aGUgb3JnL3JvbGUgZW1iZWRkZWQgaW4gdGhlIHRva2VuLlxuLy9cbi8vIFRva2VucyBkZWZhdWx0IHRvIDUtbWludXRlIFRUTCDigJQgbG9uZyBlbm91Z2ggdG8gc3Vydml2ZSBhIGJhY2tlbmQgaG9wLFxuLy8gc2hvcnQgZW5vdWdoIHRoYXQgYSBsZWFrZWQgdG9rZW4gaXMgbG93LXZhbHVlLlxuLy8gLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cbmNvbnN0IERFRkFVTFRfU0VSVklDRV9UT0tFTl9UVExfU0VDT05EUyA9IDMwMDtcblxuLyoqXG4gKiBEZW55bGlzdCBvZiBzZXJ2aWNlIE5BTUVTICh0aGUgYDxuYW1lPmAgaW4gYHN1Yjogc2VydmljZTo8bmFtZT5gKSB3aG9zZSB0b2tlbnNcbiAqIGByZXF1aXJlQXV0aGAgbXVzdCByZWplY3QuIFNlZWRlZCBmcm9tIGBTRVJWSUNFX1RPS0VOX0RFTllMSVNUYCAoY29tbWEtc2VwYXJhdGVkKVxuICogYXQgbW9kdWxlIGxvYWQ7IGEgc2VydmljZSBjYW4gcHVzaCBsaXZlIHVwZGF0ZXMgKGUuZy4gZnJvbSBhIFJlZGlzLXN1YnNjcmliZWRcbiAqIGtpbGwtc3dpdGNoKSB2aWEge0BsaW5rIHNldFNlcnZpY2VUb2tlbkRlbnlsaXN0fSBzbyBhIGNvbXByb21pc2VkIHNlcnZpY2UgY2FuIGJlXG4gKiBjdXQgb2ZmIFdJVEhPVVQgcm90YXRpbmcgdGhlIHNoYXJlZCBKV1Qgc2VjcmV0ICh3aGljaCBpbnZhbGlkYXRlcyBhbGwgb2YgdGhlbSkuXG4gKi9cbmxldCBzZXJ2aWNlVG9rZW5EZW55bGlzdCA9IG5ldyBTZXQoXG4gIChwcm9jZXNzLmVudi5TRVJWSUNFX1RPS0VOX0RFTllMSVNUIHx8ICcnKVxuICAgIC5zcGxpdCgnLCcpXG4gICAgLm1hcCgocykgPT4gcy50cmltKCkpXG4gICAgLmZpbHRlcihCb29sZWFuKSxcbik7XG5cbi8qKiBSZXBsYWNlIHRoZSBzZXJ2aWNlLXRva2VuIGRlbnlsaXN0IChzZXJ2aWNlIG5hbWVzKS4gRW1wdHkg4oeSIGtpbGwtc3dpdGNoIG9mZi4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRTZXJ2aWNlVG9rZW5EZW55bGlzdChuYW1lczogSXRlcmFibGU8c3RyaW5nPik6IHZvaWQge1xuICBzZXJ2aWNlVG9rZW5EZW55bGlzdCA9IG5ldyBTZXQoWy4uLm5hbWVzXS5tYXAoKHMpID0+IHMudHJpbSgpKS5maWx0ZXIoQm9vbGVhbikpO1xufVxuXG4vKiogVHJ1ZSB3aGVuIGBzdWJgIGlzIGBzZXJ2aWNlOjxuYW1lPmAgYW5kIGA8bmFtZT5gIGlzIG9uIHRoZSBkZW55bGlzdC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc1NlcnZpY2VUb2tlbkRlbmllZChzdWI6IHN0cmluZyk6IGJvb2xlYW4ge1xuICBpZiAoc2VydmljZVRva2VuRGVueWxpc3Quc2l6ZSA9PT0gMCkgcmV0dXJuIGZhbHNlO1xuICBpZiAoIXN1Yi5zdGFydHNXaXRoKCdzZXJ2aWNlOicpKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBzZXJ2aWNlVG9rZW5EZW55bGlzdC5oYXMoc3ViLnNsaWNlKCdzZXJ2aWNlOicubGVuZ3RoKSk7XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgU2VydmljZVRva2VuT3B0aW9ucyB7XG4gIC8qKiBDYWxsaW5nIHNlcnZpY2UgaWRlbnRpZmllciAoZS5nLiAnYmlsbGluZycsICdwbGF0Zm9ybScpLiBFbWJlZGRlZCBhcyBgc3ViOiBzZXJ2aWNlOjxuYW1lPmAuICovXG4gIHNlcnZpY2VOYW1lOiBzdHJpbmc7XG4gIC8qKiBBY3RpdmUgb3JnIGNvbnRleHQgZm9yIHRoZSBjYWxsLiBVc2UgdGhlIHRhcmdldCB0ZW5hbnQncyBvcmcgaWQsIG9yIHRoZVxuICAgKiAgd2VsbC1rbm93biBgU1lTVEVNX09SR19JRGAgKGFuIE9iamVjdElkKSBmb3Igc3lzdGVtLXdpZGUgb3BzIOKAlCBOT1QgdGhlIHN0cmluZ1xuICAgKiAgJ3N5c3RlbScsIHdoaWNoIGlkLWJhc2VkIHN5c3RlbS1vcmcgY2hlY2tzIHdvbid0IHJlY29nbml6ZS4gKi9cbiAgb3JnSWQ/OiBzdHJpbmc7XG4gIC8qKiBBY3RpdmUgb3JnIG5hbWUuIERlZmF1bHRzIHRvIG9yZ0lkLiAqL1xuICBvcmdOYW1lPzogc3RyaW5nO1xuICAvKiogVFRMIGluIHNlY29uZHMgKGRlZmF1bHQgMzAwKS4gKi9cbiAgdHRsU2Vjb25kcz86IG51bWJlcjtcbiAgLyoqXG4gICAqIFJvbGUgdGhlIHRva2VuIGNhcnJpZXMgKHJlcXVpcmVkIOKAlCBubyBpbXBsaWNpdCBkZWZhdWx0KS4gKipQYXNzIHRoZSBMT1dFU1RcbiAgICogcm9sZSB0aGUgY2FsbCBhY3R1YWxseSBuZWVkcyoqIChgJ21lbWJlcidgIGZvciByZWFkIC8gZGF0YS1wbGFuZSBjYWxscykgc28gYVxuICAgKiBsZWFrZWQgc2VydmljZSB0b2tlbiBjYW4ndCBwZXJmb3JtIGFkbWluIGFjdGlvbnMgaW4gdGhlIHRhcmdldCBvcmcuXG4gICAqIGBpc0FkbWluYCBpcyBkZXJpdmVkIGZyb20gdGhpcyAoYWRtaW58b3duZXIg4oaSIHRydWUpLlxuICAgKi9cbiAgcm9sZTogJ293bmVyJyB8ICdhZG1pbicgfCAnbWVtYmVyJztcbiAgLyoqXG4gICAqIE9wdGlvbmFsIGZpbmUtZ3JhaW5lZCBwZXJtaXNzaW9uIGNsYWltLiBQcmVmZXIgdGhpcyArIGByb2xlOiAnbWVtYmVyJ2Agb3ZlciBhXG4gICAqIGhpZ2ggcm9sZSB3aGVuIGEgY2FsbCBuZWVkcyBPTkUgc3BlY2lmaWMgY2FwYWJpbGl0eSAoZS5nLiBgWydwbHVnaW5zOndyaXRlJ11gXG4gICAqIHRvIHB1c2ggYSBwbHVnaW4gaW1hZ2UpIOKAlCB0aGUgdG9rZW4gdGhlbiBzYXRpc2ZpZXMgdGhhdCBwZXJtaXNzaW9uIGdhdGVcbiAgICogV0lUSE9VVCBjYXJyeWluZyBgaXNBZG1pbmAsIHNvIGEgbGVha2VkIHRva2VuIGNhbid0IHBlcmZvcm0gYWRtaW4gYWN0aW9ucy5cbiAgICovXG4gIHBlcm1pc3Npb25zPzogUGVybWlzc2lvbltdO1xufVxuXG4vKipcbiAqIE1pbnQgYSBKV1QgaWRlbnRpZnlpbmcgdGhlIGNhbGxpbmcgc2VydmljZS4gVXNlZCBmb3IgaW50ZXItc2VydmljZSBIVFRQIGNhbGxzLlxuICogVGhlIHRva2VuIHNhdGlzZmllcyBgcmVxdWlyZUF1dGhgIGFuZCAod2hlbiBvcmdJZCBpcyBwcmVzZW50KSBgcmVxdWlyZU9yZ2FuaXphdGlvbmAuXG4gKiBTY29wZSBpdCB3aXRoIGBvcHRzLnJvbGVgIOKAlCBsZWFzdCBwcml2aWxlZ2Uga2VlcHMgYSBsZWFrZWQgdG9rZW4gbG93LXZhbHVlLlxuICovXG5leHBvcnQgZnVuY3Rpb24gc2lnblNlcnZpY2VUb2tlbihvcHRzOiBTZXJ2aWNlVG9rZW5PcHRpb25zKTogc3RyaW5nIHtcbiAgY29uc3Qgcm9sZSA9IG9wdHMucm9sZTtcbiAgY29uc3QgcGF5bG9hZDogSnd0UGF5bG9hZCA9IHtcbiAgICBzdWI6IGBzZXJ2aWNlOiR7b3B0cy5zZXJ2aWNlTmFtZX1gLFxuICAgIHVzZXJuYW1lOiBgJHtvcHRzLnNlcnZpY2VOYW1lfS1zZXJ2aWNlYCxcbiAgICBlbWFpbDogYCR7b3B0cy5zZXJ2aWNlTmFtZX1AaW50ZXJuYWxgLFxuICAgIHJvbGUsXG4gICAgaXNBZG1pbjogcm9sZSA9PT0gJ293bmVyJyB8fCByb2xlID09PSAnYWRtaW4nLFxuICAgIHR5cGU6ICdhY2Nlc3MnLFxuICAgIG9yZ2FuaXphdGlvbklkOiBvcHRzLm9yZ0lkLFxuICAgIG9yZ2FuaXphdGlvbk5hbWU6IG9wdHMub3JnTmFtZSA/PyBvcHRzLm9yZ0lkLFxuICAgIC8vIExlYXN0LXByaXZpbGVnZSBjYXBhYmlsaXR5IGNsYWltIChvcHRpb25hbCkg4oCUIGxldHMgYSBtZW1iZXItcm9sZSB0b2tlblxuICAgIC8vIHNhdGlzZnkgYSBzcGVjaWZpYyBwZXJtaXNzaW9uIGdhdGUgd2l0aG91dCBjYXJyeWluZyBpc0FkbWluLlxuICAgIC4uLihvcHRzLnBlcm1pc3Npb25zICYmIG9wdHMucGVybWlzc2lvbnMubGVuZ3RoID4gMCA/IHsgcGVybWlzc2lvbnM6IG9wdHMucGVybWlzc2lvbnMgfSA6IHt9KSxcbiAgfTtcbiAgLy8gTWF0Y2ggdGhlIG9wdGlvbmFsIGlzc3Vlci9hdWRpZW5jZSB0aGF0IHJlcXVpcmVBdXRoIHZlcmlmaWVzLCB3aGVuXG4gIC8vIGNvbmZpZ3VyZWQuIFdpdGhvdXQgdGhlc2UsIGEgc2VydmljZSB0b2tlbiBzaWduZWQgaGVyZSB3b3VsZCBmYWlsXG4gIC8vIHJlcXVpcmVBdXRoIGluIGEgZGVwbG95bWVudCB0aGF0IGhhcyBzZXQgSldUX0lTU1VFUi9KV1RfQVVESUVOQ0UuXG4gIGNvbnN0IHNpZ25PcHRpb25zOiBqd3QuU2lnbk9wdGlvbnMgPSB7XG4gICAgZXhwaXJlc0luOiBvcHRzLnR0bFNlY29uZHMgPz8gREVGQVVMVF9TRVJWSUNFX1RPS0VOX1RUTF9TRUNPTkRTLFxuICAgIC8vIFNpZ24gd2l0aCB0aGUgc2FtZSBjb25maWd1cmVkIGFsZyByZXF1aXJlQXV0aCBwaW5zIG9uIHZlcmlmeSwgc28gc2VydmljZVxuICAgIC8vIHRva2VucyBzdGF5IHZhbGlkIHVuZGVyIGEgbm9uLWRlZmF1bHQgSldUX0FMR09SSVRITS5cbiAgICBhbGdvcml0aG06IChwcm9jZXNzLmVudi5KV1RfQUxHT1JJVEhNIHx8ICdIUzI1NicpIGFzIGp3dC5BbGdvcml0aG0sXG4gICAgLy8gVW5pcXVlIHRva2VuIGlkIG9uIGV2ZXJ5IG1pbnQuIENvbWJpbmVkIHdpdGggdGhlIHNob3J0ICgzMDBzIGRlZmF1bHQpIFRUTFxuICAgIC8vIHRoaXMgZ2l2ZXMgZWFjaCBzZXJ2aWNlIHRva2VuIGEgZGlzdGluY3QgaWRlbnRpdHkg4oCUIHRoZSBidWlsZGluZyBibG9jayBmb3JcbiAgICAvLyByZXBsYXkgZGV0ZWN0aW9uIChhIHZlcmlmaWVyIGNhbiB0cmFjayBzZWVuIGp0aXMpIGFuZCB0aGUgY29ycmVsYXRpb25cbiAgICAvLyBoYW5kbGUgZm9yIHRyYWNpbmcgd2hpY2ggbWludCBwZXJmb3JtZWQgYSBjcm9zcy1zZXJ2aWNlIGFjdGlvbi4gSXQgZG9lc1xuICAgIC8vIE5PVCBieSBpdHNlbGYgcHJldmVudCByZXBsYXkgd2l0aGluIHRoZSBUVEwgd2luZG93OyB0cnVlIHJlcGxheSBkZWZlbmNlXG4gICAgLy8gbmVlZHMgdGhlIGFzeW1tZXRyaWMta2V5IHdvcmsgdHJhY2tlZCBzZXBhcmF0ZWx5LlxuICAgIGp3dGlkOiByYW5kb21VVUlEKCksXG4gIH07XG4gIGlmIChwcm9jZXNzLmVudi5KV1RfSVNTVUVSKSBzaWduT3B0aW9ucy5pc3N1ZXIgPSBwcm9jZXNzLmVudi5KV1RfSVNTVUVSO1xuICBpZiAocHJvY2Vzcy5lbnYuSldUX0FVRElFTkNFKSBzaWduT3B0aW9ucy5hdWRpZW5jZSA9IHByb2Nlc3MuZW52LkpXVF9BVURJRU5DRTtcbiAgcmV0dXJuIGp3dC5zaWduKHBheWxvYWQsIGdldEp3dFNlY3JldCgpLCBzaWduT3B0aW9ucyk7XG59XG5cbi8qKiBDb252ZW5pZW5jZTogcmV0dXJucyBhIGBCZWFyZXIgPHRva2VuPmAgaGVhZGVyIHZhbHVlIGZvciBmZXRjaC9heGlvcyBjYWxscy4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRTZXJ2aWNlQXV0aEhlYWRlcihvcHRzOiBTZXJ2aWNlVG9rZW5PcHRpb25zKTogc3RyaW5nIHtcbiAgcmV0dXJuIGBCZWFyZXIgJHtzaWduU2VydmljZVRva2VuKG9wdHMpfWA7XG59XG5cbi8qKiBUcnVlIHdoZW4gYHJlcS51c2VyLnN1YmAgd2FzIGlzc3VlZCBieSBgc2lnblNlcnZpY2VUb2tlbmAgKGkuZS4gc3RhcnRzIHdpdGggYHNlcnZpY2U6YCkuICovXG5leHBvcnQgZnVuY3Rpb24gaXNTZXJ2aWNlUHJpbmNpcGFsKHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICByZXR1cm4gcmVxLnVzZXI/LnN1Yj8uc3RhcnRzV2l0aCgnc2VydmljZTonKSA/PyBmYWxzZTtcbn1cblxuLyoqXG4gKiBQUkUtYXV0aCBjaGVjazogY3J5cHRvZ3JhcGhpY2FsbHkgdmVyaWZ5IHRoZSByZXF1ZXN0IGNhcnJpZXMgYSB2YWxpZCwgc2lnbmVkXG4gKiBTRVJWSUNFIHRva2VuIChgc3ViYCBzdGFydHMgd2l0aCBgc2VydmljZTpgKS4gVW5saWtlIHtAbGluayBpc1NlcnZpY2VQcmluY2lwYWx9XG4gKiAod2hpY2ggcmVhZHMgdGhlIGFscmVhZHktcG9wdWxhdGVkIGByZXEudXNlcmApLCB0aGlzIHZlcmlmaWVzIHRoZSBiZWFyZXIgdG9rZW5cbiAqIGl0c2VsZiwgc28gaXQgaXMgc2FmZSB0byBjYWxsIEJFRk9SRSBgcmVxdWlyZUF1dGhgIHJ1bnMg4oCUIGUuZy4gdGhlIGdsb2JhbCByYXRlXG4gKiBsaW1pdGVyJ3MgYHNraXBgLCB3aGljaCBtdXN0IG5vdCB0cnVzdCB0aGUgc3Bvb2ZhYmxlIGB4LWludGVybmFsLXNlcnZpY2VgXG4gKiBoZWFkZXIuIE1pcnJvcnMgYHJlcXVpcmVBdXRoYCdzIHZlcmlmaWNhdGlvbiAoYWxnb3JpdGhtIHBpbm5pbmcgKyBvcHRpb25hbFxuICogaXNzdWVyL2F1ZGllbmNlKSBhbmQgcmV0dXJucyBgZmFsc2VgIG9uIGFueSBtaXNzaW5nL2ludmFsaWQvbm9uLXNlcnZpY2UgdG9rZW4uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnlTZXJ2aWNlUHJpbmNpcGFsKHJlcTogUmVxdWVzdCk6IGJvb2xlYW4ge1xuICBjb25zdCBwYXJ0cyA9IHJlcS5oZWFkZXJzLmF1dGhvcml6YXRpb24/LnNwbGl0KCcgJyk7XG4gIGlmICghcGFydHMgfHwgcGFydHMubGVuZ3RoICE9PSAyIHx8IHBhcnRzWzBdICE9PSAnQmVhcmVyJykgcmV0dXJuIGZhbHNlO1xuICB0cnkge1xuICAgIGNvbnN0IHZlcmlmeU9wdGlvbnMgPSBidWlsZEp3dFZlcmlmeU9wdGlvbnMoKTtcbiAgICBjb25zdCBkZWNvZGVkID0gdmVyaWZ5Snd0V2l0aFJvdGF0aW9uKHBhcnRzWzFdLCB2ZXJpZnlPcHRpb25zKTtcbiAgICBpZiAoZGVjb2RlZC50eXBlICE9PSAnYWNjZXNzJyB8fCB0eXBlb2YgZGVjb2RlZC5zdWIgIT09ICdzdHJpbmcnIHx8ICFkZWNvZGVkLnN1Yi5zdGFydHNXaXRoKCdzZXJ2aWNlOicpKSByZXR1cm4gZmFsc2U7XG4gICAgLy8gQSBkZW55bGlzdGVkIChraWxsZWQpIHNlcnZpY2UgbXVzdCBOT1QgYmUgdHJlYXRlZCBhcyBhIHRydXN0ZWQgcHJpbmNpcGFsIOKAlFxuICAgIC8vIG90aGVyd2lzZSBpdCBrZWVwcyB0aGUgcmF0ZS1saW1pdGVyIGV4ZW1wdGlvbiBldmVuIHRob3VnaCByZXF1aXJlQXV0aCByZWplY3RzXG4gICAgLy8gaXQgb24gcmVhbCByb3V0ZXMuIEZvbGQgdGhlIGtpbGwtc3dpdGNoIGludG8gdGhlIHByZS1hdXRoIGNoZWNrIHRvby5cbiAgICByZXR1cm4gIWlzU2VydmljZVRva2VuRGVuaWVkKGRlY29kZWQuc3ViKTtcbiAgfSBjYXRjaCB7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59XG4iXX0=
|
|
@@ -25,11 +25,18 @@ export interface StepUpTokenPayload {
|
|
|
25
25
|
}
|
|
26
26
|
/**
|
|
27
27
|
* Verify a step-up token: valid signature (primary `JWT_SECRET`, or
|
|
28
|
-
* `JWT_SECRET_PREVIOUS` during a rotation), allow-listed algorithm,
|
|
29
|
-
* `type: 'step-up'` + `jti` claims — a plain
|
|
30
|
-
* `sub`, so without asserting the step-up
|
|
31
|
-
* Throws on any failure. Does NOT bind to a
|
|
32
|
-
* `sub` match and single-use consume.
|
|
28
|
+
* `JWT_SECRET_PREVIOUS` during a rotation), allow-listed algorithm, issuer and
|
|
29
|
+
* audience when configured, AND the `type: 'step-up'` + `jti` claims — a plain
|
|
30
|
+
* access token shares the secret and `sub`, so without asserting the step-up
|
|
31
|
+
* shape it would bypass the gate. Throws on any failure. Does NOT bind to a
|
|
32
|
+
* caller — `requireStepUp` does the `sub` match and single-use consume.
|
|
33
|
+
*
|
|
34
|
+
* Delegates to `requireAuth`'s own primitives rather than re-implementing them.
|
|
35
|
+
* The hand-rolled copy this replaced dropped TWO of their guards: it never
|
|
36
|
+
* pinned issuer/audience (so a step-up token from any other system sharing
|
|
37
|
+
* `JWT_SECRET` was accepted wherever `JWT_ISSUER`/`JWT_AUDIENCE` are set), and
|
|
38
|
+
* its previous-secret retry had no expiry/not-before carve-out, so an EXPIRED
|
|
39
|
+
* token was retried and surfaced as a signature error instead of an expiry one.
|
|
33
40
|
*/
|
|
34
41
|
export declare function verifyStepUpToken(token: string): StepUpTokenPayload;
|
|
35
42
|
/**
|
|
@@ -1,39 +1,31 @@
|
|
|
1
1
|
// Copyright 2026 Pipeline Builder Contributors
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
-
import
|
|
4
|
-
import { isServicePrincipal } from './auth.js';
|
|
3
|
+
import { buildJwtVerifyOptions, verifyJwtWithRotation, isServicePrincipal } from './auth.js';
|
|
5
4
|
import { createEnvRedisClient } from '../services/env-redis.js';
|
|
6
5
|
import { getHeaderString } from '../utils/headers.js';
|
|
7
6
|
import { createLogger } from '../utils/logger.js';
|
|
8
7
|
import { sendError } from '../utils/response.js';
|
|
9
8
|
const logger = createLogger('step-up');
|
|
10
9
|
const HEADER = 'x-step-up-token';
|
|
11
|
-
function jwtAlgorithm() {
|
|
12
|
-
return (process.env.JWT_ALGORITHM || 'HS256');
|
|
13
|
-
}
|
|
14
10
|
/**
|
|
15
11
|
* Verify a step-up token: valid signature (primary `JWT_SECRET`, or
|
|
16
|
-
* `JWT_SECRET_PREVIOUS` during a rotation), allow-listed algorithm,
|
|
17
|
-
* `type: 'step-up'` + `jti` claims — a plain
|
|
18
|
-
* `sub`, so without asserting the step-up
|
|
19
|
-
* Throws on any failure. Does NOT bind to a
|
|
20
|
-
* `sub` match and single-use consume.
|
|
12
|
+
* `JWT_SECRET_PREVIOUS` during a rotation), allow-listed algorithm, issuer and
|
|
13
|
+
* audience when configured, AND the `type: 'step-up'` + `jti` claims — a plain
|
|
14
|
+
* access token shares the secret and `sub`, so without asserting the step-up
|
|
15
|
+
* shape it would bypass the gate. Throws on any failure. Does NOT bind to a
|
|
16
|
+
* caller — `requireStepUp` does the `sub` match and single-use consume.
|
|
17
|
+
*
|
|
18
|
+
* Delegates to `requireAuth`'s own primitives rather than re-implementing them.
|
|
19
|
+
* The hand-rolled copy this replaced dropped TWO of their guards: it never
|
|
20
|
+
* pinned issuer/audience (so a step-up token from any other system sharing
|
|
21
|
+
* `JWT_SECRET` was accepted wherever `JWT_ISSUER`/`JWT_AUDIENCE` are set), and
|
|
22
|
+
* its previous-secret retry had no expiry/not-before carve-out, so an EXPIRED
|
|
23
|
+
* token was retried and surfaced as a signature error instead of an expiry one.
|
|
21
24
|
*/
|
|
22
25
|
export function verifyStepUpToken(token) {
|
|
23
|
-
|
|
24
|
-
if (!secret)
|
|
26
|
+
if (!process.env.JWT_SECRET)
|
|
25
27
|
throw new Error('JWT_SECRET environment variable is required');
|
|
26
|
-
const
|
|
27
|
-
let payload;
|
|
28
|
-
try {
|
|
29
|
-
payload = jwt.verify(token, secret, opts);
|
|
30
|
-
}
|
|
31
|
-
catch (primaryErr) {
|
|
32
|
-
const previous = process.env.JWT_SECRET_PREVIOUS;
|
|
33
|
-
if (!previous)
|
|
34
|
-
throw primaryErr;
|
|
35
|
-
payload = jwt.verify(token, previous, opts);
|
|
36
|
-
}
|
|
28
|
+
const payload = verifyJwtWithRotation(token, buildJwtVerifyOptions());
|
|
37
29
|
if (payload.type !== 'step-up' || !payload.jti || !payload.sub) {
|
|
38
30
|
throw new Error('INVALID_STEP_UP_TOKEN');
|
|
39
31
|
}
|
|
@@ -61,6 +53,26 @@ const memSweep = setInterval(() => {
|
|
|
61
53
|
memJti.delete(jti);
|
|
62
54
|
}, 30_000);
|
|
63
55
|
memSweep.unref?.();
|
|
56
|
+
/**
|
|
57
|
+
* Hard ceiling on the process-local jti set.
|
|
58
|
+
*
|
|
59
|
+
* The 30s sweep alone does NOT bound it: entries only leave once their token's
|
|
60
|
+
* TTL has passed, so a burst of step-up traffic (or a flood of distinct forged
|
|
61
|
+
* jtis on a Redis-less deployment) grows the map faster than the sweep drains
|
|
62
|
+
* it. This is a replay guard, so shedding the OLDEST entries is the safe
|
|
63
|
+
* direction: the worst case is that a long-expired jti could be replayed, and
|
|
64
|
+
* expiry is enforced independently by the token's own `exp`.
|
|
65
|
+
*/
|
|
66
|
+
const MEM_JTI_MAX = 10_000;
|
|
67
|
+
/** Drop the soonest-to-expire entries until the map is under the ceiling. */
|
|
68
|
+
function evictOldestJti() {
|
|
69
|
+
if (memJti.size < MEM_JTI_MAX)
|
|
70
|
+
return;
|
|
71
|
+
const byExpiry = [...memJti.entries()].sort((a, b) => a[1] - b[1]);
|
|
72
|
+
const excess = memJti.size - MEM_JTI_MAX + 1;
|
|
73
|
+
for (let i = 0; i < excess; i += 1)
|
|
74
|
+
memJti.delete(byExpiry[i][0]);
|
|
75
|
+
}
|
|
64
76
|
/**
|
|
65
77
|
* Consume a step-up `jti` exactly once. Returns true if this call claimed it
|
|
66
78
|
* (first use), false if it was already consumed (replay). `expEpochSeconds` is
|
|
@@ -80,6 +92,7 @@ export async function consumeStepUpJti(jti, expEpochSeconds) {
|
|
|
80
92
|
// No Redis ⇒ single-instance deployment; the process-local map IS the store.
|
|
81
93
|
if (memJti.has(jti))
|
|
82
94
|
return false;
|
|
95
|
+
evictOldestJti();
|
|
83
96
|
memJti.set(jti, Date.now() + ttlSeconds * 1000);
|
|
84
97
|
return true;
|
|
85
98
|
}
|
|
@@ -135,4 +148,4 @@ export async function requireStepUp(req, res, next) {
|
|
|
135
148
|
}
|
|
136
149
|
next();
|
|
137
150
|
}
|
|
138
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC11cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL3N0ZXAtdXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQW9CdEMsT0FBTyxHQUFHLE1BQU0sY0FBYyxDQUFDO0FBQy9CLE9BQU8sRUFBRSxrQkFBa0IsRUFBRSxNQUFNLFdBQVcsQ0FBQztBQUMvQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdEQsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBQ2xELE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUVqRCxNQUFNLE1BQU0sR0FBRyxZQUFZLENBQUMsU0FBUyxDQUFDLENBQUM7QUFDdkMsTUFBTSxNQUFNLEdBQUcsaUJBQWlCLENBQUM7QUFXakMsU0FBUyxZQUFZO0lBQ25CLE9BQU8sQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLGFBQWEsSUFBSSxPQUFPLENBQWtCLENBQUM7QUFDakUsQ0FBQztBQUVEOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsS0FBYTtJQUM3QyxNQUFNLE1BQU0sR0FBRyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQztJQUN0QyxJQUFJLENBQUMsTUFBTTtRQUFFLE1BQU0sSUFBSSxLQUFLLENBQUMsNkNBQTZDLENBQUMsQ0FBQztJQUM1RSxNQUFNLElBQUksR0FBc0IsRUFBRSxVQUFVLEVBQUUsQ0FBQyxZQUFZLEVBQUUsQ0FBQyxFQUFFLENBQUM7SUFFakUsSUFBSSxPQUEyQixDQUFDO0lBQ2hDLElBQUksQ0FBQztRQUNILE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxDQUF1QixDQUFDO0lB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QkFBZ0IsQ0FBQyxDQUFDO1lBQy9FLE9BQU87UUFDVCxDQUFDO0lBQ0gsQ0FBQztJQUFDLE9BQU8sR0FBRyxFQUFFLENBQUM7UUFDYixNQUFNLENBQUMsS0FBSyxDQUFDLDZCQUE2QixFQUFFLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDcEUsU0FBUyxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsNkJBQTZCLEVBQUUsaUJBQWlCLENBQUMsQ0FBQztRQUN0RSxPQUFPO0lBQ1QsQ0FBQztJQUVELElBQUksRUFBRSxDQUFDO0FBQ1QsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqIGByZXF1aXJlU3RlcFVwYCDigJQgYSBzaGFyZWQgc3RlcC11cCAocmVjZW50LXBhc3N3b3JkLXJldmVyaWZ5KSBnYXRlIGZvciB0aGVcbiAqIHN0YXRlbGVzcyBhcGkgc2VydmljZXMsIG1pcnJvcmluZyB0aGUgcGxhdGZvcm0gbWlkZGxld2FyZSBvZiB0aGUgc2FtZSBuYW1lLlxuICpcbiAqIEZsb3c6IHRoZSBVSSBoaXRzIGBQT1NUIC9hcGkvYXV0aC9zdGVwLXVwYCAocGxhdGZvcm0pIHRvIHJlLXZlcmlmeSB0aGUgdXNlcidzXG4gKiBwYXNzd29yZDsgcGxhdGZvcm0gbWludHMgYSBzaG9ydC1saXZlZCAoNjBzKSBgc3RlcC11cGAgSldUIHNpZ25lZCB3aXRoIHRoZVxuICogU0FNRSBgSldUX1NFQ1JFVGAgdGhlc2Ugc2VydmljZXMgYWxyZWFkeSB2ZXJpZnkgYWNjZXNzIHRva2VucyB3aXRoLiBUaGUgVUlcbiAqIHJlcGxheXMgaXQgYXMgdGhlIGBYLVN0ZXAtVXAtVG9rZW5gIGhlYWRlciBvbiB0aGUgZGVzdHJ1Y3RpdmUvc2Vuc2l0aXZlIGNhbGw7XG4gKiB0aGlzIG1pZGRsZXdhcmUgdmVyaWZpZXMgaXQsIGJpbmRzIGl0IHRvIHRoZSBjYWxsZXIgKGBzdWJgIG1hdGNoKSwgYW5kXG4gKiBjb25zdW1lcyBpdHMgYGp0aWAgb25jZSAoUmVkaXMtYmFja2VkIGNyb3NzLWluc3RhbmNlIHdoZW4gY29uZmlndXJlZCwgZWxzZSBhXG4gKiBib3VuZGVkIHByb2Nlc3MtbG9jYWwgc2V0KSBzbyBhIHJlcGxheSBpbnNpZGUgdGhlIFRUTCBpcyByZWplY3RlZC5cbiAqXG4gKiBXSFkgaGVyZTogcmVzdG9yZSBlbmRwb2ludHMgb24gdGhlIGFwaSBzZXJ2aWNlcyAocGlwZWxpbmUvcGx1Z2luLy4uLikgYXJlXG4gKiBzdGVwLXVwLWdhdGVkLCBidXQgc3RlcC11cCBwcmV2aW91c2x5IGxpdmVkIG9ubHkgaW4gYHBsYXRmb3JtYC4gVGhpcyBwb3J0cyB0aGVcbiAqIHZlcmlmeSArIHNpbmdsZS11c2UganRpIGludG8gYXBpLWNvcmUgc28gYW55IHNlcnZpY2UgY2FuIHJlcXVpcmUgaXQuXG4gKi9cblxuaW1wb3J0IHR5cGUgeyBSZXF1ZXN0LCBSZXNwb25zZSwgTmV4dEZ1bmN0aW9uIH0gZnJvbSAnZXhwcmVzcyc7XG5pbXBvcnQgand0IGZyb20gJ2pzb253ZWJ0b2tlbic7XG5pbXBvcnQgeyBpc1NlcnZpY2VQcmluY2lwYWwgfSBmcm9tICcuL2F1dGguanMnO1xuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNDbGllbnQgfSBmcm9tICcuLi9zZXJ2aWNlcy9lbnYtcmVkaXMuanMnO1xuaW1wb3J0IHsgZ2V0SGVhZGVyU3RyaW5nIH0gZnJvbSAnLi4vdXRpbHMvaGVhZGVycy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3N0ZXAtdXAnKTtcbmNvbnN0IEhFQURFUiA9ICd4LXN0ZXAtdXAtdG9rZW4nO1xuXG4vKiogUGF5bG9hZCBvZiBhIHBsYXRmb3JtLWlzc3VlZCBzdGVwLXVwIHRva2VuIChzZWUgcGxhdGZvcm0gaXNzdWVTdGVwVXBUb2tlbikuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0ZXBVcFRva2VuUGF5bG9hZCB7XG4gIHR5cGU6ICdzdGVwLXVwJztcbiAgc3ViOiBzdHJpbmc7XG4gIGp0aTogc3RyaW5nO1xuICBpYXQ6IG51bWJlcjtcbiAgZXhwOiBudW1iZXI7XG59XG5cbmZ1bmN0aW9uIGp3dEFsZ29yaXRobSgpOiBqd3QuQWxnb3JpdGhtIHtcbiAgcmV0dXJuIChwcm9jZXNzLmVudi5KV1RfQUxHT1JJVEhNIHx8ICdIUzI1NicpIGFzIGp3dC5BbGdvcml0aG07XG59XG5cbi8qKlxuICogVmVyaWZ5IGEgc3RlcC11cCB0b2tlbjogdmFsaWQgc2lnbmF0dXJlIChwcmltYXJ5IGBKV1RfU0VDUkVUYCwgb3JcbiAqIGBKV1RfU0VDUkVUX1BSRVZJT1VTYCBkdXJpbmcgYSByb3RhdGlvbiksIGFsbG93LWxpc3RlZCBhbGdvcml0aG0sIEFORCB0aGVcbiAqIGB0eXBlOiAnc3RlcC11cCdgICsgYGp0aWAgY2xhaW1zIOKAlCBhIHBsYWluIGFjY2VzcyB0b2tlbiBzaGFyZXMgdGhlIHNlY3JldCBhbmRcbiAqIGBzdWJgLCBzbyB3aXRob3V0IGFzc2VydGluZyB0aGUgc3RlcC11cCBzaGFwZSBpdCB3b3VsZCBieXBhc3MgdGhlIGdhdGUuXG4gKiBUaHJvd3Mgb24gYW55IGZhaWx1cmUuIERvZXMgTk9UIGJpbmQgdG8gYSBjYWxsZXIg4oCUIGByZXF1aXJlU3RlcFVwYCBkb2VzIHRoZVxuICogYHN1YmAgbWF0Y2ggYW5kIHNpbmdsZS11c2UgY29uc3VtZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcmlmeVN0ZXBVcFRva2VuKHRva2VuOiBzdHJpbmcpOiBTdGVwVXBUb2tlblBheWxvYWQge1xuICBjb25zdCBzZWNyZXQgPSBwcm9jZXNzLmVudi5KV1RfU0VDUkVUO1xuICBpZiAoIXNlY3JldCkgdGhyb3cgbmV3IEVycm9yKCdKV1RfU0VDUkVUIGVudmlyb25tZW50IHZhcmlhYmxlIGlzIHJlcXVpcmVkJyk7XG4gIGNvbnN0IG9wdHM6IGp3dC5WZXJpZnlPcHRpb25zID0geyBhbGdvcml0aG1zOiBband0QWxnb3JpdGhtKCldIH07XG5cbiAgbGV0IHBheWxvYWQ6IFN0ZXBVcFRva2VuUGF5bG9hZDtcbiAgdHJ5IHtcbiAgICBwYXlsb2FkID0gand0LnZlcmlmeSh0b2tlbiwgc2VjcmV0LCBvcHRzKSBhcyBTdGVwVXBUb2tlblBheWxvYWQ7XG4gIH0gY2F0Y2ggKHByaW1hcnlFcnIpIHtcbiAgICBjb25zdCBwcmV2aW91cyA9IHByb2Nlc3MuZW52LkpXVF9TRUNSRVRfUFJFVklPVVM7XG4gICAgaWYgKCFwcmV2aW91cykgdGhyb3cgcHJpbWFyeUVycjtcbiAgICBwYXlsb2FkID0gand0LnZlcmlmeSh0b2tlbiwgcHJldmlvdXMsIG9wdHMpIGFzIFN0ZXBVcFRva2VuUGF5bG9hZDtcbiAgfVxuXG4gIGlmIChwYXlsb2FkLnR5cGUgIT09ICdzdGVwLXVwJyB8fCAhcGF5bG9hZC5qdGkgfHwgIXBheWxvYWQuc3ViKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJTlZBTElEX1NURVBfVVBfVE9LRU4nKTtcbiAgfVxuICByZXR1cm4gcGF5bG9hZDtcbn1cblxuLy8gLS0gU2luZ2xlLXVzZSBqdGkgc3RvcmUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJlZGlzIFNFVCBOWCBFWCB3aGVuIFJlZGlzIGlzIGNvbmZpZ3VyZWQgKGNyb3NzLWluc3RhbmNlIHNpbmdsZS11c2UpOyBlbHNlIGFcbi8vIGJvdW5kZWQgcHJvY2Vzcy1sb2NhbCBtYXAgd2l0aCBUVEwgc3dlZXAgKHBlci1wcm9jZXNzKS4gQSBzdGVwLXVwIHRva2VuIGlzXG4vLyA2MHMtbGl2ZWQuIFdoZW4gUmVkaXMgSVMgY29uZmlndXJlZCBpdCdzIHRoZSBhdXRob3JpdGF0aXZlIHN0b3JlOiBhIFJlZGlzXG4vLyBlcnJvciBGQUlMUyBDTE9TRUQgKHRocm93cyDihpIgU1RFUF9VUF9JTlZBTElELCB1c2VyIHJlLXZlcmlmaWVzKSByYXRoZXIgdGhhblxuLy8gZGVncmFkaW5nIHRvIHRoZSBwZXItaW5zdGFuY2UgbWVtIGd1YXJkLCB3aGljaCB3b3VsZCBhY2NlcHQgYSBjcm9zcy1pbnN0YW5jZVxuLy8gcmVwbGF5IGR1cmluZyB0aGUgb3V0YWdlLiBUaGUgbWVtIGd1YXJkIGlzIHVzZWQgT05MWSB3aGVuIFJlZGlzIGlzIGFic2VudC5cblxubGV0IF9yZWRpczogeyBzZXQ6ICguLi5hcmdzOiB1bmtub3duW10pID0+IFByb21pc2U8dW5rbm93bj4gfSB8IG51bGwgfCB1bmRlZmluZWQ7XG5mdW5jdGlvbiByZWRpcygpOiB7IHNldDogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gUHJvbWlzZTx1bmtub3duPiB9IHwgbnVsbCB7XG4gIGlmIChfcmVkaXMgPT09IHVuZGVmaW5lZCkge1xuICAgIF9yZWRpcyA9IGNyZWF0ZUVudlJlZGlzQ2xpZW50PHsgc2V0OiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHVua25vd24+IH0+KCdzdGVwLXVwLWp0aScpO1xuICB9XG4gIHJldHVybiBfcmVkaXM7XG59XG5cbmNvbnN0IG1lbUp0aSA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7IC8vIGp0aSAtPiBleHBpcnkgZXBvY2ggbXNcbmNvbnN0IG1lbVN3ZWVwID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBmb3IgKGNvbnN0IFtqdGksIGV4cF0gb2YgbWVtSnRpKSBpZiAoZXhwIDw9IG5vdykgbWVtSnRpLmRlbGV0ZShqdGkpO1xufSwgMzBfMDAwKTtcbm1lbVN3ZWVwLnVucmVmPy4oKTtcblxuLyoqXG4gKiBDb25zdW1lIGEgc3RlcC11cCBganRpYCBleGFjdGx5IG9uY2UuIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNhbGwgY2xhaW1lZCBpdFxuICogKGZpcnN0IHVzZSksIGZhbHNlIGlmIGl0IHdhcyBhbHJlYWR5IGNvbnN1bWVkIChyZXBsYXkpLiBgZXhwRXBvY2hTZWNvbmRzYCBpc1xuICogdGhlIHRva2VuJ3MgYGV4cGAsIHNvIHRoZSBtYXJrZXIgYXV0by1leHBpcmVzIHdpdGggdGhlIHRva2VuLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29uc3VtZVN0ZXBVcEp0aShqdGk6IHN0cmluZywgZXhwRXBvY2hTZWNvbmRzOiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgdHRsU2Vjb25kcyA9IE1hdGgubWF4KDEsIGV4cEVwb2NoU2Vjb25kcyAtIE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApKTtcbiAgY29uc3QgY2xpZW50ID0gcmVkaXMoKTtcbiAgaWYgKGNsaWVudCkge1xuICAgIC8vIFJlZGlzIGNvbmZpZ3VyZWQg4oeSIGF1dGhvcml0YXRpdmUgY3Jvc3MtaW5zdGFuY2Ugc3RvcmUuIFNFVCBOWCBFWCDihpIgJ09LJ1xuICAgIC8vIHdoZW4gbmV3bHkgc2V0LCBudWxsIHdoZW4gYWxyZWFkeSBjb25zdW1lZC4gQSB0aHJvd24gUmVkaXMgZXJyb3IgaXMgTk9UXG4gICAgLy8gY2F1Z2h0IGhlcmU6IGl0IHByb3BhZ2F0ZXMgc28gYHJlcXVpcmVTdGVwVXBgIGZhaWxzIGNsb3NlZCAoU1RFUF9VUF9JTlZBTElEKVxuICAgIC8vIGluc3RlYWQgb2Ygc2lsZW50bHkgZGVncmFkaW5nIHRvIHRoZSBwZXItaW5zdGFuY2UgbWVtIGd1YXJkLlxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGNsaWVudC5zZXQoYHN0ZXB1cDpqdGk6JHtqdGl9YCwgJzEnLCAnRVgnLCB0dGxTZWNvbmRzLCAnTlgnKTtcbiAgICByZXR1cm4gcmVzID09PSAnT0snO1xuICB9XG4gIC8vIE5vIFJlZGlzIOKHkiBzaW5nbGUtaW5zdGFuY2UgZGVwbG95bWVudDsgdGhlIHByb2Nlc3MtbG9jYWwgbWFwIElTIHRoZSBzdG9yZS5cbiAgaWYgKG1lbUp0aS5oYXMoanRpKSkgcmV0dXJuIGZhbHNlO1xuICBtZW1KdGkuc2V0KGp0aSwgRGF0ZS5ub3coKSArIHR0bFNlY29uZHMgKiAxMDAwKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogRXhwcmVzcyBtaWRkbGV3YXJlOiByZXF1aXJlIGEgdmFsaWQsIGNhbGxlci1ib3VuZCwgc2luZ2xlLXVzZSBzdGVwLXVwIHRva2VuIGluXG4gKiB0aGUgYFgtU3RlcC1VcC1Ub2tlbmAgaGVhZGVyLiBNdXN0IHJ1biBBRlRFUiBgcmVxdWlyZUF1dGhgIChuZWVkcyBgcmVxLnVzZXJgKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcXVpcmVTdGVwVXAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiBQcm9taXNlPHZvaWQ+IHtcbiAgLy8gVmVyaWZpZWQgaW50ZXJuYWwgc2VydmljZSBwcmluY2lwYWxzIGFyZSBFWEVNUFQ6IHN0ZXAtdXAgaXMgYSByZS12ZXJpZnktdGhlLVxuICAvLyBIVU1BTiBnYXRlICh0aGV5IHJlcGxheSBhIHBhc3N3b3JkLXJldmVyaWZ5IHRva2VuKSwgd2hpY2ggYSBzZXJ2aWNlIHRva2VuXG4gIC8vIHN0cnVjdHVyYWxseSBjYW5ub3QgcHJvZHVjZS4gU2VydmljZXMgYWxyZWFkeSBieXBhc3MgYHJlcXVpcmVQZXJtaXNzaW9uYCBvblxuICAvLyB0aGUgc2FtZSB0cnVzdCBiYXNpcyAoYSBzaWduZWQgc2VydmljZSBKV1QpLCBhbmQgaW50ZXJuYWwgY2FsbGVycyBvZiBhXG4gIC8vIHN0ZXAtdXAtZ2F0ZWQgcm91dGUg4oCUIGUuZy4gdGhlIHBsYXRmb3JtIG9yZy1jYXNjYWRlJ3MgYERFTEVURSAvcXVvdGFzLzpvcmdJZGBcbiAgLy8gb3IgdGhlIGJpbGxpbmfihpJxdW90YSBlbnRpdGxlbWVudCBzeW5jIOKAlCB3b3VsZCBvdGhlcndpc2UgYmUgaGFyZC1ibG9ja2VkLlxuICAvLyBTYWZlOiBhIHNlcnZpY2UgdG9rZW4gY2FuIG9ubHkgYmUgbWludGVkIHdpdGggYEpXVF9TRUNSRVRgLCBzbyB0aGlzIGNhbid0IGJlXG4gIC8vIHNwb29mZWQgYnkgYW4gZXh0ZXJuYWwgY2xpZW50IHRvIHNraXAgc3RlcC11cC5cbiAgaWYgKGlzU2VydmljZVByaW5jaXBhbChyZXEpKSB7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGNhbGxlclN1YiA9IChyZXEgYXMgUmVxdWVzdCAmIHsgdXNlcj86IHsgc3ViPzogc3RyaW5nIH0gfSkudXNlcj8uc3ViO1xuICBpZiAoIWNhbGxlclN1Yikge1xuICAgIHNlbmRFcnJvcihyZXMsIDQwMSwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgJ1VOQVVUSE9SSVpFRCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHRva2VuID0gZ2V0SGVhZGVyU3RyaW5nKHJlcS5oZWFkZXJzW0hFQURFUl0pO1xuICBpZiAoIXRva2VuKSB7XG4gICAgc2VuZEVycm9yKHJlcywgNDAxLCAnU3RlcC11cCB2ZXJpZmljYXRpb24gcmVxdWlyZWQnLCAnU1RFUF9VUF9SRVFVSVJFRCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBwYXlsb2FkOiBTdGVwVXBUb2tlblBheWxvYWQ7XG4gIHRyeSB7XG4gICAgcGF5bG9hZCA9IHZlcmlmeVN0ZXBVcFRva2VuKHRva2VuKTtcbiAgfSBjYXRjaCB7XG4gICAgc2VuZEVycm9yKHJlcywgNDAxLCAnU3RlcC11cCB0b2tlbiBpbnZhbGlkIG9yIGV4cGlyZWQnLCAnU1RFUF9VUF9JTlZBTElEJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHBheWxvYWQuc3ViICE9PSBjYWxsZXJTdWIpIHtcbiAgICBzZW5kRXJyb3IocmVzLCA0MDEsICdTdGVwLXVwIHRva2VuIGRvZXMgbm90IG1hdGNoIHNlc3Npb24nLCAnU1RFUF9VUF9NSVNNQVRDSCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgaWYgKCEoYXdhaXQgY29uc3VtZVN0ZXBVcEp0aShwYXlsb2FkLmp0aSwgcGF5bG9hZC5leHApKSkge1xuICAgICAgc2VuZEVycm9yKHJlcywgNDAxLCAnU3RlcC11cCB0b2tlbiBhbHJlYWR5IHVzZWQgb3IgZXhwaXJlZCcsICdTVEVQX1VQX1JFUExBWScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdTdGVwLXVwIGp0aSBjb25zdW1lIGVycm9yZWQnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KTtcbiAgICBzZW5kRXJyb3IocmVzLCA0MDEsICdTdGVwLXVwIHZlcmlmaWNhdGlvbiBmYWlsZWQnLCAnU1RFUF9VUF9JTlZBTElEJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbmV4dCgpO1xufVxuIl19
|
|
151
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RlcC11cC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9taWRkbGV3YXJlL3N0ZXAtdXAudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQW9CdEMsT0FBTyxFQUFFLHFCQUFxQixFQUFFLHFCQUFxQixFQUFFLGtCQUFrQixFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQzdGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBQ2hFLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUN0RCxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDbEQsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHNCQUFzQixDQUFDO0FBRWpELE1BQU0sTUFBTSxHQUFHLFlBQVksQ0FBQyxTQUFTLENBQUMsQ0FBQztBQUN2QyxNQUFNLE1BQU0sR0FBRyxpQkFBaUIsQ0FBQztBQVdqQzs7Ozs7Ozs7Ozs7Ozs7R0FjRztBQUNILE1BQU0sVUFBVSxpQkFBaUIsQ0FBQyxLQUFhO0lBQzdDLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLFVBQVU7UUFBRSxNQUFNLElBQUksS0FBSyxDQUFDLDZDQUE2QyxDQUFDLENBQUM7SUFDNUYsTUFBTSxPQUFPLEdBQUcscUJBQXFCLENBQUMsS0FBSyxFQUFFLHFCQUFxQixFQUFFLENBQWtDLENBQUM7SUFFdkcsSUFBSSxPQUFPLENBQUMsSUFBSSxLQUFLLFNBQVMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLENBQUM7UUFDL0QsTUFBTSxJQUFJLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFDRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBRUQsZ0ZBQWdGO0FBQ2hGLCtFQUErRTtBQUMvRSw2RUFBNkU7QUFDN0UsNEVBQTRF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QUMsR0FBRyxDQUFDLENBQUMsRUFBRSxDQUFDO1lBQ3hELFNBQVMsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLHVDQUF1QyxFQUFFLGdCQUFnQixDQUFDLENBQUM7WUFDL0UsT0FBTztRQUNULENBQUM7SUFDSCxDQUFDO0lBQUMsT0FBTyxHQUFHLEVBQUUsQ0FBQztRQUNiLE1BQU0sQ0FBQyxLQUFLLENBQUMsNkJBQTZCLEVBQUUsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNwRSxTQUFTLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSw2QkFBNkIsRUFBRSxpQkFBaUIsQ0FBQyxDQUFDO1FBQ3RFLE9BQU87SUFDVCxDQUFDO0lBRUQsSUFBSSxFQUFFLENBQUM7QUFDVCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogYHJlcXVpcmVTdGVwVXBgIOKAlCBhIHNoYXJlZCBzdGVwLXVwIChyZWNlbnQtcGFzc3dvcmQtcmV2ZXJpZnkpIGdhdGUgZm9yIHRoZVxuICogc3RhdGVsZXNzIGFwaSBzZXJ2aWNlcywgbWlycm9yaW5nIHRoZSBwbGF0Zm9ybSBtaWRkbGV3YXJlIG9mIHRoZSBzYW1lIG5hbWUuXG4gKlxuICogRmxvdzogdGhlIFVJIGhpdHMgYFBPU1QgL2FwaS9hdXRoL3N0ZXAtdXBgIChwbGF0Zm9ybSkgdG8gcmUtdmVyaWZ5IHRoZSB1c2VyJ3NcbiAqIHBhc3N3b3JkOyBwbGF0Zm9ybSBtaW50cyBhIHNob3J0LWxpdmVkICg2MHMpIGBzdGVwLXVwYCBKV1Qgc2lnbmVkIHdpdGggdGhlXG4gKiBTQU1FIGBKV1RfU0VDUkVUYCB0aGVzZSBzZXJ2aWNlcyBhbHJlYWR5IHZlcmlmeSBhY2Nlc3MgdG9rZW5zIHdpdGguIFRoZSBVSVxuICogcmVwbGF5cyBpdCBhcyB0aGUgYFgtU3RlcC1VcC1Ub2tlbmAgaGVhZGVyIG9uIHRoZSBkZXN0cnVjdGl2ZS9zZW5zaXRpdmUgY2FsbDtcbiAqIHRoaXMgbWlkZGxld2FyZSB2ZXJpZmllcyBpdCwgYmluZHMgaXQgdG8gdGhlIGNhbGxlciAoYHN1YmAgbWF0Y2gpLCBhbmRcbiAqIGNvbnN1bWVzIGl0cyBganRpYCBvbmNlIChSZWRpcy1iYWNrZWQgY3Jvc3MtaW5zdGFuY2Ugd2hlbiBjb25maWd1cmVkLCBlbHNlIGFcbiAqIGJvdW5kZWQgcHJvY2Vzcy1sb2NhbCBzZXQpIHNvIGEgcmVwbGF5IGluc2lkZSB0aGUgVFRMIGlzIHJlamVjdGVkLlxuICpcbiAqIFdIWSBoZXJlOiByZXN0b3JlIGVuZHBvaW50cyBvbiB0aGUgYXBpIHNlcnZpY2VzIChwaXBlbGluZS9wbHVnaW4vLi4uKSBhcmVcbiAqIHN0ZXAtdXAtZ2F0ZWQsIGJ1dCBzdGVwLXVwIHByZXZpb3VzbHkgbGl2ZWQgb25seSBpbiBgcGxhdGZvcm1gLiBUaGlzIHBvcnRzIHRoZVxuICogdmVyaWZ5ICsgc2luZ2xlLXVzZSBqdGkgaW50byBhcGktY29yZSBzbyBhbnkgc2VydmljZSBjYW4gcmVxdWlyZSBpdC5cbiAqL1xuXG5pbXBvcnQgdHlwZSB7IFJlcXVlc3QsIFJlc3BvbnNlLCBOZXh0RnVuY3Rpb24gfSBmcm9tICdleHByZXNzJztcbmltcG9ydCB7IGJ1aWxkSnd0VmVyaWZ5T3B0aW9ucywgdmVyaWZ5Snd0V2l0aFJvdGF0aW9uLCBpc1NlcnZpY2VQcmluY2lwYWwgfSBmcm9tICcuL2F1dGguanMnO1xuaW1wb3J0IHsgY3JlYXRlRW52UmVkaXNDbGllbnQgfSBmcm9tICcuLi9zZXJ2aWNlcy9lbnYtcmVkaXMuanMnO1xuaW1wb3J0IHsgZ2V0SGVhZGVyU3RyaW5nIH0gZnJvbSAnLi4vdXRpbHMvaGVhZGVycy5qcyc7XG5pbXBvcnQgeyBjcmVhdGVMb2dnZXIgfSBmcm9tICcuLi91dGlscy9sb2dnZXIuanMnO1xuaW1wb3J0IHsgc2VuZEVycm9yIH0gZnJvbSAnLi4vdXRpbHMvcmVzcG9uc2UuanMnO1xuXG5jb25zdCBsb2dnZXIgPSBjcmVhdGVMb2dnZXIoJ3N0ZXAtdXAnKTtcbmNvbnN0IEhFQURFUiA9ICd4LXN0ZXAtdXAtdG9rZW4nO1xuXG4vKiogUGF5bG9hZCBvZiBhIHBsYXRmb3JtLWlzc3VlZCBzdGVwLXVwIHRva2VuIChzZWUgcGxhdGZvcm0gaXNzdWVTdGVwVXBUb2tlbikuICovXG5leHBvcnQgaW50ZXJmYWNlIFN0ZXBVcFRva2VuUGF5bG9hZCB7XG4gIHR5cGU6ICdzdGVwLXVwJztcbiAgc3ViOiBzdHJpbmc7XG4gIGp0aTogc3RyaW5nO1xuICBpYXQ6IG51bWJlcjtcbiAgZXhwOiBudW1iZXI7XG59XG5cbi8qKlxuICogVmVyaWZ5IGEgc3RlcC11cCB0b2tlbjogdmFsaWQgc2lnbmF0dXJlIChwcmltYXJ5IGBKV1RfU0VDUkVUYCwgb3JcbiAqIGBKV1RfU0VDUkVUX1BSRVZJT1VTYCBkdXJpbmcgYSByb3RhdGlvbiksIGFsbG93LWxpc3RlZCBhbGdvcml0aG0sIGlzc3VlciBhbmRcbiAqIGF1ZGllbmNlIHdoZW4gY29uZmlndXJlZCwgQU5EIHRoZSBgdHlwZTogJ3N0ZXAtdXAnYCArIGBqdGlgIGNsYWltcyDigJQgYSBwbGFpblxuICogYWNjZXNzIHRva2VuIHNoYXJlcyB0aGUgc2VjcmV0IGFuZCBgc3ViYCwgc28gd2l0aG91dCBhc3NlcnRpbmcgdGhlIHN0ZXAtdXBcbiAqIHNoYXBlIGl0IHdvdWxkIGJ5cGFzcyB0aGUgZ2F0ZS4gVGhyb3dzIG9uIGFueSBmYWlsdXJlLiBEb2VzIE5PVCBiaW5kIHRvIGFcbiAqIGNhbGxlciDigJQgYHJlcXVpcmVTdGVwVXBgIGRvZXMgdGhlIGBzdWJgIG1hdGNoIGFuZCBzaW5nbGUtdXNlIGNvbnN1bWUuXG4gKlxuICogRGVsZWdhdGVzIHRvIGByZXF1aXJlQXV0aGAncyBvd24gcHJpbWl0aXZlcyByYXRoZXIgdGhhbiByZS1pbXBsZW1lbnRpbmcgdGhlbS5cbiAqIFRoZSBoYW5kLXJvbGxlZCBjb3B5IHRoaXMgcmVwbGFjZWQgZHJvcHBlZCBUV08gb2YgdGhlaXIgZ3VhcmRzOiBpdCBuZXZlclxuICogcGlubmVkIGlzc3Vlci9hdWRpZW5jZSAoc28gYSBzdGVwLXVwIHRva2VuIGZyb20gYW55IG90aGVyIHN5c3RlbSBzaGFyaW5nXG4gKiBgSldUX1NFQ1JFVGAgd2FzIGFjY2VwdGVkIHdoZXJldmVyIGBKV1RfSVNTVUVSYC9gSldUX0FVRElFTkNFYCBhcmUgc2V0KSwgYW5kXG4gKiBpdHMgcHJldmlvdXMtc2VjcmV0IHJldHJ5IGhhZCBubyBleHBpcnkvbm90LWJlZm9yZSBjYXJ2ZS1vdXQsIHNvIGFuIEVYUElSRURcbiAqIHRva2VuIHdhcyByZXRyaWVkIGFuZCBzdXJmYWNlZCBhcyBhIHNpZ25hdHVyZSBlcnJvciBpbnN0ZWFkIG9mIGFuIGV4cGlyeSBvbmUuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJpZnlTdGVwVXBUb2tlbih0b2tlbjogc3RyaW5nKTogU3RlcFVwVG9rZW5QYXlsb2FkIHtcbiAgaWYgKCFwcm9jZXNzLmVudi5KV1RfU0VDUkVUKSB0aHJvdyBuZXcgRXJyb3IoJ0pXVF9TRUNSRVQgZW52aXJvbm1lbnQgdmFyaWFibGUgaXMgcmVxdWlyZWQnKTtcbiAgY29uc3QgcGF5bG9hZCA9IHZlcmlmeUp3dFdpdGhSb3RhdGlvbih0b2tlbiwgYnVpbGRKd3RWZXJpZnlPcHRpb25zKCkpIGFzIHVua25vd24gYXMgU3RlcFVwVG9rZW5QYXlsb2FkO1xuXG4gIGlmIChwYXlsb2FkLnR5cGUgIT09ICdzdGVwLXVwJyB8fCAhcGF5bG9hZC5qdGkgfHwgIXBheWxvYWQuc3ViKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdJTlZBTElEX1NURVBfVVBfVE9LRU4nKTtcbiAgfVxuICByZXR1cm4gcGF5bG9hZDtcbn1cblxuLy8gLS0gU2luZ2xlLXVzZSBqdGkgc3RvcmUgLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbi8vIFJlZGlzIFNFVCBOWCBFWCB3aGVuIFJlZGlzIGlzIGNvbmZpZ3VyZWQgKGNyb3NzLWluc3RhbmNlIHNpbmdsZS11c2UpOyBlbHNlIGFcbi8vIGJvdW5kZWQgcHJvY2Vzcy1sb2NhbCBtYXAgd2l0aCBUVEwgc3dlZXAgKHBlci1wcm9jZXNzKS4gQSBzdGVwLXVwIHRva2VuIGlzXG4vLyA2MHMtbGl2ZWQuIFdoZW4gUmVkaXMgSVMgY29uZmlndXJlZCBpdCdzIHRoZSBhdXRob3JpdGF0aXZlIHN0b3JlOiBhIFJlZGlzXG4vLyBlcnJvciBGQUlMUyBDTE9TRUQgKHRocm93cyDihpIgU1RFUF9VUF9JTlZBTElELCB1c2VyIHJlLXZlcmlmaWVzKSByYXRoZXIgdGhhblxuLy8gZGVncmFkaW5nIHRvIHRoZSBwZXItaW5zdGFuY2UgbWVtIGd1YXJkLCB3aGljaCB3b3VsZCBhY2NlcHQgYSBjcm9zcy1pbnN0YW5jZVxuLy8gcmVwbGF5IGR1cmluZyB0aGUgb3V0YWdlLiBUaGUgbWVtIGd1YXJkIGlzIHVzZWQgT05MWSB3aGVuIFJlZGlzIGlzIGFic2VudC5cblxubGV0IF9yZWRpczogeyBzZXQ6ICguLi5hcmdzOiB1bmtub3duW10pID0+IFByb21pc2U8dW5rbm93bj4gfSB8IG51bGwgfCB1bmRlZmluZWQ7XG5mdW5jdGlvbiByZWRpcygpOiB7IHNldDogKC4uLmFyZ3M6IHVua25vd25bXSkgPT4gUHJvbWlzZTx1bmtub3duPiB9IHwgbnVsbCB7XG4gIGlmIChfcmVkaXMgPT09IHVuZGVmaW5lZCkge1xuICAgIF9yZWRpcyA9IGNyZWF0ZUVudlJlZGlzQ2xpZW50PHsgc2V0OiAoLi4uYXJnczogdW5rbm93bltdKSA9PiBQcm9taXNlPHVua25vd24+IH0+KCdzdGVwLXVwLWp0aScpO1xuICB9XG4gIHJldHVybiBfcmVkaXM7XG59XG5cbmNvbnN0IG1lbUp0aSA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7IC8vIGp0aSAtPiBleHBpcnkgZXBvY2ggbXNcbmNvbnN0IG1lbVN3ZWVwID0gc2V0SW50ZXJ2YWwoKCkgPT4ge1xuICBjb25zdCBub3cgPSBEYXRlLm5vdygpO1xuICBmb3IgKGNvbnN0IFtqdGksIGV4cF0gb2YgbWVtSnRpKSBpZiAoZXhwIDw9IG5vdykgbWVtSnRpLmRlbGV0ZShqdGkpO1xufSwgMzBfMDAwKTtcbm1lbVN3ZWVwLnVucmVmPy4oKTtcblxuLyoqXG4gKiBIYXJkIGNlaWxpbmcgb24gdGhlIHByb2Nlc3MtbG9jYWwganRpIHNldC5cbiAqXG4gKiBUaGUgMzBzIHN3ZWVwIGFsb25lIGRvZXMgTk9UIGJvdW5kIGl0OiBlbnRyaWVzIG9ubHkgbGVhdmUgb25jZSB0aGVpciB0b2tlbidzXG4gKiBUVEwgaGFzIHBhc3NlZCwgc28gYSBidXJzdCBvZiBzdGVwLXVwIHRyYWZmaWMgKG9yIGEgZmxvb2Qgb2YgZGlzdGluY3QgZm9yZ2VkXG4gKiBqdGlzIG9uIGEgUmVkaXMtbGVzcyBkZXBsb3ltZW50KSBncm93cyB0aGUgbWFwIGZhc3RlciB0aGFuIHRoZSBzd2VlcCBkcmFpbnNcbiAqIGl0LiBUaGlzIGlzIGEgcmVwbGF5IGd1YXJkLCBzbyBzaGVkZGluZyB0aGUgT0xERVNUIGVudHJpZXMgaXMgdGhlIHNhZmVcbiAqIGRpcmVjdGlvbjogdGhlIHdvcnN0IGNhc2UgaXMgdGhhdCBhIGxvbmctZXhwaXJlZCBqdGkgY291bGQgYmUgcmVwbGF5ZWQsIGFuZFxuICogZXhwaXJ5IGlzIGVuZm9yY2VkIGluZGVwZW5kZW50bHkgYnkgdGhlIHRva2VuJ3Mgb3duIGBleHBgLlxuICovXG5jb25zdCBNRU1fSlRJX01BWCA9IDEwXzAwMDtcblxuLyoqIERyb3AgdGhlIHNvb25lc3QtdG8tZXhwaXJlIGVudHJpZXMgdW50aWwgdGhlIG1hcCBpcyB1bmRlciB0aGUgY2VpbGluZy4gKi9cbmZ1bmN0aW9uIGV2aWN0T2xkZXN0SnRpKCk6IHZvaWQge1xuICBpZiAobWVtSnRpLnNpemUgPCBNRU1fSlRJX01BWCkgcmV0dXJuO1xuICBjb25zdCBieUV4cGlyeSA9IFsuLi5tZW1KdGkuZW50cmllcygpXS5zb3J0KChhLCBiKSA9PiBhWzFdIC0gYlsxXSk7XG4gIGNvbnN0IGV4Y2VzcyA9IG1lbUp0aS5zaXplIC0gTUVNX0pUSV9NQVggKyAxO1xuICBmb3IgKGxldCBpID0gMDsgaSA8IGV4Y2VzczsgaSArPSAxKSBtZW1KdGkuZGVsZXRlKGJ5RXhwaXJ5W2ldWzBdKTtcbn1cblxuLyoqXG4gKiBDb25zdW1lIGEgc3RlcC11cCBganRpYCBleGFjdGx5IG9uY2UuIFJldHVybnMgdHJ1ZSBpZiB0aGlzIGNhbGwgY2xhaW1lZCBpdFxuICogKGZpcnN0IHVzZSksIGZhbHNlIGlmIGl0IHdhcyBhbHJlYWR5IGNvbnN1bWVkIChyZXBsYXkpLiBgZXhwRXBvY2hTZWNvbmRzYCBpc1xuICogdGhlIHRva2VuJ3MgYGV4cGAsIHNvIHRoZSBtYXJrZXIgYXV0by1leHBpcmVzIHdpdGggdGhlIHRva2VuLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gY29uc3VtZVN0ZXBVcEp0aShqdGk6IHN0cmluZywgZXhwRXBvY2hTZWNvbmRzOiBudW1iZXIpOiBQcm9taXNlPGJvb2xlYW4+IHtcbiAgY29uc3QgdHRsU2Vjb25kcyA9IE1hdGgubWF4KDEsIGV4cEVwb2NoU2Vjb25kcyAtIE1hdGguZmxvb3IoRGF0ZS5ub3coKSAvIDEwMDApKTtcbiAgY29uc3QgY2xpZW50ID0gcmVkaXMoKTtcbiAgaWYgKGNsaWVudCkge1xuICAgIC8vIFJlZGlzIGNvbmZpZ3VyZWQg4oeSIGF1dGhvcml0YXRpdmUgY3Jvc3MtaW5zdGFuY2Ugc3RvcmUuIFNFVCBOWCBFWCDihpIgJ09LJ1xuICAgIC8vIHdoZW4gbmV3bHkgc2V0LCBudWxsIHdoZW4gYWxyZWFkeSBjb25zdW1lZC4gQSB0aHJvd24gUmVkaXMgZXJyb3IgaXMgTk9UXG4gICAgLy8gY2F1Z2h0IGhlcmU6IGl0IHByb3BhZ2F0ZXMgc28gYHJlcXVpcmVTdGVwVXBgIGZhaWxzIGNsb3NlZCAoU1RFUF9VUF9JTlZBTElEKVxuICAgIC8vIGluc3RlYWQgb2Ygc2lsZW50bHkgZGVncmFkaW5nIHRvIHRoZSBwZXItaW5zdGFuY2UgbWVtIGd1YXJkLlxuICAgIGNvbnN0IHJlcyA9IGF3YWl0IGNsaWVudC5zZXQoYHN0ZXB1cDpqdGk6JHtqdGl9YCwgJzEnLCAnRVgnLCB0dGxTZWNvbmRzLCAnTlgnKTtcbiAgICByZXR1cm4gcmVzID09PSAnT0snO1xuICB9XG4gIC8vIE5vIFJlZGlzIOKHkiBzaW5nbGUtaW5zdGFuY2UgZGVwbG95bWVudDsgdGhlIHByb2Nlc3MtbG9jYWwgbWFwIElTIHRoZSBzdG9yZS5cbiAgaWYgKG1lbUp0aS5oYXMoanRpKSkgcmV0dXJuIGZhbHNlO1xuICBldmljdE9sZGVzdEp0aSgpO1xuICBtZW1KdGkuc2V0KGp0aSwgRGF0ZS5ub3coKSArIHR0bFNlY29uZHMgKiAxMDAwKTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbi8qKlxuICogRXhwcmVzcyBtaWRkbGV3YXJlOiByZXF1aXJlIGEgdmFsaWQsIGNhbGxlci1ib3VuZCwgc2luZ2xlLXVzZSBzdGVwLXVwIHRva2VuIGluXG4gKiB0aGUgYFgtU3RlcC1VcC1Ub2tlbmAgaGVhZGVyLiBNdXN0IHJ1biBBRlRFUiBgcmVxdWlyZUF1dGhgIChuZWVkcyBgcmVxLnVzZXJgKS5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlcXVpcmVTdGVwVXAocmVxOiBSZXF1ZXN0LCByZXM6IFJlc3BvbnNlLCBuZXh0OiBOZXh0RnVuY3Rpb24pOiBQcm9taXNlPHZvaWQ+IHtcbiAgLy8gVmVyaWZpZWQgaW50ZXJuYWwgc2VydmljZSBwcmluY2lwYWxzIGFyZSBFWEVNUFQ6IHN0ZXAtdXAgaXMgYSByZS12ZXJpZnktdGhlLVxuICAvLyBIVU1BTiBnYXRlICh0aGV5IHJlcGxheSBhIHBhc3N3b3JkLXJldmVyaWZ5IHRva2VuKSwgd2hpY2ggYSBzZXJ2aWNlIHRva2VuXG4gIC8vIHN0cnVjdHVyYWxseSBjYW5ub3QgcHJvZHVjZS4gU2VydmljZXMgYWxyZWFkeSBieXBhc3MgYHJlcXVpcmVQZXJtaXNzaW9uYCBvblxuICAvLyB0aGUgc2FtZSB0cnVzdCBiYXNpcyAoYSBzaWduZWQgc2VydmljZSBKV1QpLCBhbmQgaW50ZXJuYWwgY2FsbGVycyBvZiBhXG4gIC8vIHN0ZXAtdXAtZ2F0ZWQgcm91dGUg4oCUIGUuZy4gdGhlIHBsYXRmb3JtIG9yZy1jYXNjYWRlJ3MgYERFTEVURSAvcXVvdGFzLzpvcmdJZGBcbiAgLy8gb3IgdGhlIGJpbGxpbmfihpJxdW90YSBlbnRpdGxlbWVudCBzeW5jIOKAlCB3b3VsZCBvdGhlcndpc2UgYmUgaGFyZC1ibG9ja2VkLlxuICAvLyBTYWZlOiBhIHNlcnZpY2UgdG9rZW4gY2FuIG9ubHkgYmUgbWludGVkIHdpdGggYEpXVF9TRUNSRVRgLCBzbyB0aGlzIGNhbid0IGJlXG4gIC8vIHNwb29mZWQgYnkgYW4gZXh0ZXJuYWwgY2xpZW50IHRvIHNraXAgc3RlcC11cC5cbiAgaWYgKGlzU2VydmljZVByaW5jaXBhbChyZXEpKSB7XG4gICAgbmV4dCgpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IGNhbGxlclN1YiA9IChyZXEgYXMgUmVxdWVzdCAmIHsgdXNlcj86IHsgc3ViPzogc3RyaW5nIH0gfSkudXNlcj8uc3ViO1xuICBpZiAoIWNhbGxlclN1Yikge1xuICAgIHNlbmRFcnJvcihyZXMsIDQwMSwgJ0F1dGhlbnRpY2F0aW9uIHJlcXVpcmVkJywgJ1VOQVVUSE9SSVpFRCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGNvbnN0IHRva2VuID0gZ2V0SGVhZGVyU3RyaW5nKHJlcS5oZWFkZXJzW0hFQURFUl0pO1xuICBpZiAoIXRva2VuKSB7XG4gICAgc2VuZEVycm9yKHJlcywgNDAxLCAnU3RlcC11cCB2ZXJpZmljYXRpb24gcmVxdWlyZWQnLCAnU1RFUF9VUF9SRVFVSVJFRCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIGxldCBwYXlsb2FkOiBTdGVwVXBUb2tlblBheWxvYWQ7XG4gIHRyeSB7XG4gICAgcGF5bG9hZCA9IHZlcmlmeVN0ZXBVcFRva2VuKHRva2VuKTtcbiAgfSBjYXRjaCB7XG4gICAgc2VuZEVycm9yKHJlcywgNDAxLCAnU3RlcC11cCB0b2tlbiBpbnZhbGlkIG9yIGV4cGlyZWQnLCAnU1RFUF9VUF9JTlZBTElEJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKHBheWxvYWQuc3ViICE9PSBjYWxsZXJTdWIpIHtcbiAgICBzZW5kRXJyb3IocmVzLCA0MDEsICdTdGVwLXVwIHRva2VuIGRvZXMgbm90IG1hdGNoIHNlc3Npb24nLCAnU1RFUF9VUF9NSVNNQVRDSCcpO1xuICAgIHJldHVybjtcbiAgfVxuXG4gIHRyeSB7XG4gICAgaWYgKCEoYXdhaXQgY29uc3VtZVN0ZXBVcEp0aShwYXlsb2FkLmp0aSwgcGF5bG9hZC5leHApKSkge1xuICAgICAgc2VuZEVycm9yKHJlcywgNDAxLCAnU3RlcC11cCB0b2tlbiBhbHJlYWR5IHVzZWQgb3IgZXhwaXJlZCcsICdTVEVQX1VQX1JFUExBWScpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgbG9nZ2VyLmVycm9yKCdTdGVwLXVwIGp0aSBjb25zdW1lIGVycm9yZWQnLCB7IGVycm9yOiBTdHJpbmcoZXJyKSB9KTtcbiAgICBzZW5kRXJyb3IocmVzLCA0MDEsICdTdGVwLXVwIHZlcmlmaWNhdGlvbiBmYWlsZWQnLCAnU1RFUF9VUF9JTlZBTElEJyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgbmV4dCgpO1xufVxuIl19
|
package/lib/utils/index.d.ts
CHANGED
package/lib/utils/index.js
CHANGED
|
@@ -2,6 +2,7 @@
|
|
|
2
2
|
// SPDX-License-Identifier: Apache-2.0
|
|
3
3
|
export * from './logger.js';
|
|
4
4
|
export * from './safe-require.js';
|
|
5
|
+
export * from './secure-compare.js';
|
|
5
6
|
export * from './crash-handlers.js';
|
|
6
7
|
export * from './response.js';
|
|
7
8
|
export * from './params.js';
|
|
@@ -17,4 +18,4 @@ export * from './aws-scrub.js';
|
|
|
17
18
|
export * from './ssrf.js';
|
|
18
19
|
export * from './env.js';
|
|
19
20
|
export * from './compliance-attributes.js';
|
|
20
|
-
//# sourceMappingURL=data:application/json;base64,
|
|
21
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLG1CQUFtQixDQUFDO0FBQ2xDLGNBQWMscUJBQXFCLENBQUM7QUFDcEMsY0FBYyxxQkFBcUIsQ0FBQztBQUNwQyxjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLGNBQWMsQ0FBQztBQUM3QixjQUFjLGVBQWUsQ0FBQztBQUM5QixjQUFjLGFBQWEsQ0FBQztBQUM1QixjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsa0JBQWtCLENBQUM7QUFDakMsY0FBYyxZQUFZLENBQUM7QUFDM0IsY0FBYyx3QkFBd0IsQ0FBQztBQUN2QyxjQUFjLHFCQUFxQixDQUFDO0FBQ3BDLGNBQWMsZ0JBQWdCLENBQUM7QUFDL0IsY0FBYyxXQUFXLENBQUM7QUFDMUIsY0FBYyxVQUFVLENBQUM7QUFDekIsY0FBYyw0QkFBNEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG5leHBvcnQgKiBmcm9tICcuL2xvZ2dlci5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3NhZmUtcmVxdWlyZS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3NlY3VyZS1jb21wYXJlLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vY3Jhc2gtaGFuZGxlcnMuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9yZXNwb25zZS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3BhcmFtcy5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2hlYWRlcnMuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9pZGVudGl0eS5qcyc7XG5leHBvcnQgKiBmcm9tICcuL29iamVjdC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL2FsaWFzLXJlc29sdmVyLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vY29uY3VycmVuY3kuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9hdWRpdC5qcyc7XG5leHBvcnQgKiBmcm9tICcuL3NlY3JldC1lbmNyeXB0aW9uLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vbWV0cmljLWVtaXR0ZXIuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9hd3Mtc2NydWIuanMnO1xuZXhwb3J0ICogZnJvbSAnLi9zc3JmLmpzJztcbmV4cG9ydCAqIGZyb20gJy4vZW52LmpzJztcbmV4cG9ydCAqIGZyb20gJy4vY29tcGxpYW5jZS1hdHRyaWJ1dGVzLmpzJztcbiJdfQ==
|
|
@@ -116,6 +116,10 @@ export declare class PerOrgKmsKeyProvider implements KeyProvider {
|
|
|
116
116
|
* Resolves to `null` for orgs with no per-org config — caller treats null as
|
|
117
117
|
* "fall through to the fallback provider", same as a cold cache miss. */
|
|
118
118
|
private readonly inFlight;
|
|
119
|
+
/** Orgs the resolver has PROVEN have no per-org config — the fallback provider
|
|
120
|
+
* is the correct answer for these, and `deriveKey` may serve them
|
|
121
|
+
* synchronously. Distinct from "not yet resolved", which must not guess. */
|
|
122
|
+
private readonly resolvedNoPerOrgConfig;
|
|
119
123
|
/** Provider used for orgs that have no per-org config. */
|
|
120
124
|
private readonly fallback;
|
|
121
125
|
private readonly resolver;
|
|
@@ -127,11 +131,23 @@ export declare class PerOrgKmsKeyProvider implements KeyProvider {
|
|
|
127
131
|
region?: string;
|
|
128
132
|
endpoint?: string;
|
|
129
133
|
});
|
|
130
|
-
/**
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
134
|
+
/**
|
|
135
|
+
* Sync derive. Only correct for an org whose config has already been
|
|
136
|
+
* RESOLVED — either it has a per-org master (use it) or it provably has no
|
|
137
|
+
* per-org config (the fallback is then the right answer).
|
|
138
|
+
*
|
|
139
|
+
* For an UNRESOLVED org this THROWS rather than guessing. It used to fall
|
|
140
|
+
* through to the fallback, which silently encrypted that org's secrets under
|
|
141
|
+
* the SHARED master and — because `kidFor` also returned undefined, so the
|
|
142
|
+
* both-kids-present mismatch guard could never fire — left them permanently
|
|
143
|
+
* undecryptable once the org warmed: `decipher.final()` then threw an opaque
|
|
144
|
+
* auth-tag error with no diagnostic. Failing loud here matches
|
|
145
|
+
* `KmsKeyProvider.deriveKey`, which has always refused to work cold.
|
|
146
|
+
*
|
|
147
|
+
* `encryptSecret`/`decryptSecret` are async and await `deriveKeyAsync`, so
|
|
148
|
+
* they resolve the org first and never hit this path; it is the backstop for
|
|
149
|
+
* a caller that reaches for the sync API directly.
|
|
150
|
+
*/
|
|
135
151
|
deriveKey(orgId: string): Buffer;
|
|
136
152
|
deriveKeyAsync(orgId: string): Promise<Buffer>;
|
|
137
153
|
kidFor(orgId: string): string | undefined;
|
|
@@ -157,7 +173,7 @@ export declare class PerOrgKmsKeyProvider implements KeyProvider {
|
|
|
157
173
|
* Empty strings round-trip as `null` so the calling model layer can treat
|
|
158
174
|
* "no secret set" identically to "field absent".
|
|
159
175
|
*/
|
|
160
|
-
export declare function encryptSecret(plaintext: string, orgId: string, provider?: KeyProvider): EncryptedBlob
|
|
176
|
+
export declare function encryptSecret(plaintext: string, orgId: string, provider?: KeyProvider): Promise<EncryptedBlob>;
|
|
161
177
|
/**
|
|
162
178
|
* Decrypt an `EncryptedBlob` written by `encryptSecret`. Throws on * - unknown `alg` (forces an explicit migration when the format changes)
|
|
163
179
|
* - wrong orgId (HKDF binding mismatch fails the auth tag)
|
|
@@ -166,7 +182,7 @@ export declare function encryptSecret(plaintext: string, orgId: string, provider
|
|
|
166
182
|
* Callers handle the throw masking the failure as `null` would hide
|
|
167
183
|
* silent corruption / wrong-org reads.
|
|
168
184
|
*/
|
|
169
|
-
export declare function decryptSecret(blob: EncryptedBlob, orgId: string, provider?: KeyProvider): string
|
|
185
|
+
export declare function decryptSecret(blob: EncryptedBlob, orgId: string, provider?: KeyProvider): Promise<string>;
|
|
170
186
|
/**
|
|
171
187
|
* Type guard handy for model layers that hold a column whose value may be
|
|
172
188
|
* either a clear-text string (legacy / unencrypted) OR an encrypted blob
|
|
@@ -217,6 +217,10 @@ export class PerOrgKmsKeyProvider {
|
|
|
217
217
|
* Resolves to `null` for orgs with no per-org config — caller treats null as
|
|
218
218
|
* "fall through to the fallback provider", same as a cold cache miss. */
|
|
219
219
|
inFlight = new Map();
|
|
220
|
+
/** Orgs the resolver has PROVEN have no per-org config — the fallback provider
|
|
221
|
+
* is the correct answer for these, and `deriveKey` may serve them
|
|
222
|
+
* synchronously. Distinct from "not yet resolved", which must not guess. */
|
|
223
|
+
resolvedNoPerOrgConfig = new Set();
|
|
220
224
|
/** Provider used for orgs that have no per-org config. */
|
|
221
225
|
fallback;
|
|
222
226
|
resolver;
|
|
@@ -228,15 +232,32 @@ export class PerOrgKmsKeyProvider {
|
|
|
228
232
|
this.region = opts.region ?? process.env.AWS_REGION ?? process.env.AWS_DEFAULT_REGION;
|
|
229
233
|
this.endpoint = opts.endpoint ?? process.env.AWS_KMS_ENDPOINT;
|
|
230
234
|
}
|
|
231
|
-
/**
|
|
232
|
-
*
|
|
233
|
-
*
|
|
234
|
-
*
|
|
235
|
-
*
|
|
235
|
+
/**
|
|
236
|
+
* Sync derive. Only correct for an org whose config has already been
|
|
237
|
+
* RESOLVED — either it has a per-org master (use it) or it provably has no
|
|
238
|
+
* per-org config (the fallback is then the right answer).
|
|
239
|
+
*
|
|
240
|
+
* For an UNRESOLVED org this THROWS rather than guessing. It used to fall
|
|
241
|
+
* through to the fallback, which silently encrypted that org's secrets under
|
|
242
|
+
* the SHARED master and — because `kidFor` also returned undefined, so the
|
|
243
|
+
* both-kids-present mismatch guard could never fire — left them permanently
|
|
244
|
+
* undecryptable once the org warmed: `decipher.final()` then threw an opaque
|
|
245
|
+
* auth-tag error with no diagnostic. Failing loud here matches
|
|
246
|
+
* `KmsKeyProvider.deriveKey`, which has always refused to work cold.
|
|
247
|
+
*
|
|
248
|
+
* `encryptSecret`/`decryptSecret` are async and await `deriveKeyAsync`, so
|
|
249
|
+
* they resolve the org first and never hit this path; it is the backstop for
|
|
250
|
+
* a caller that reaches for the sync API directly.
|
|
251
|
+
*/
|
|
236
252
|
deriveKey(orgId) {
|
|
237
253
|
const cached = this.masters.get(orgId);
|
|
238
|
-
if (!cached)
|
|
239
|
-
|
|
254
|
+
if (!cached) {
|
|
255
|
+
if (this.resolvedNoPerOrgConfig.has(orgId))
|
|
256
|
+
return this.fallback.deriveKey(orgId);
|
|
257
|
+
throw new Error(`PerOrgKmsKeyProvider has not resolved org ${orgId}. `
|
|
258
|
+
+ 'Call `await provider.ensureWarmed(orgId)` (or use the async encryptSecret/decryptSecret) '
|
|
259
|
+
+ 'before deriving a key — guessing the shared master would write secrets that cannot be decrypted later.');
|
|
260
|
+
}
|
|
240
261
|
const derived = hkdfSync('sha256', cached.key, Buffer.from(orgId, 'utf8'), 'secrets-v1', 32);
|
|
241
262
|
return Buffer.from(derived);
|
|
242
263
|
}
|
|
@@ -245,7 +266,14 @@ export class PerOrgKmsKeyProvider {
|
|
|
245
266
|
return this.deriveKey(orgId);
|
|
246
267
|
}
|
|
247
268
|
kidFor(orgId) {
|
|
248
|
-
|
|
269
|
+
const cached = this.masters.get(orgId);
|
|
270
|
+
if (cached)
|
|
271
|
+
return cached.kid;
|
|
272
|
+
// Only speak for an org whose config is resolved; an unresolved org has no
|
|
273
|
+
// meaningful kid, and claiming one would defeat the mismatch guard.
|
|
274
|
+
if (this.resolvedNoPerOrgConfig.has(orgId))
|
|
275
|
+
return this.fallback.kidFor?.(orgId);
|
|
276
|
+
return undefined;
|
|
249
277
|
}
|
|
250
278
|
/**
|
|
251
279
|
* Resolve the org's KMS config, call Decrypt, cache the master. Subsequent
|
|
@@ -272,6 +300,10 @@ export class PerOrgKmsKeyProvider {
|
|
|
272
300
|
const result = await promise;
|
|
273
301
|
if (result)
|
|
274
302
|
this.masters.set(orgId, result);
|
|
303
|
+
// Remember the NEGATIVE outcome too, so the sync `deriveKey` can tell
|
|
304
|
+
// "no per-org config, fallback is correct" from "not resolved yet".
|
|
305
|
+
else
|
|
306
|
+
this.resolvedNoPerOrgConfig.add(orgId);
|
|
275
307
|
}
|
|
276
308
|
async resolveAndDecrypt(orgId) {
|
|
277
309
|
let cfg = this.configs.get(orgId);
|
|
@@ -293,8 +325,22 @@ export class PerOrgKmsKeyProvider {
|
|
|
293
325
|
evict(orgId) {
|
|
294
326
|
this.masters.delete(orgId);
|
|
295
327
|
this.configs.delete(orgId);
|
|
328
|
+
// Also forget a NEGATIVE resolution, or an org that gains a per-org config
|
|
329
|
+
// after being resolved as "no config" would keep using the shared master.
|
|
330
|
+
this.resolvedNoPerOrgConfig.delete(orgId);
|
|
296
331
|
}
|
|
297
332
|
}
|
|
333
|
+
/**
|
|
334
|
+
* Derive the key for `orgId`, giving the provider a chance to do I/O first.
|
|
335
|
+
*
|
|
336
|
+
* This is why `encryptSecret`/`decryptSecret` are async: `PerOrgKmsKeyProvider`
|
|
337
|
+
* needs one KMS Decrypt the first time it sees an org, and deriving
|
|
338
|
+
* synchronously before that resolves would silently fall back to the shared
|
|
339
|
+
* master and produce secrets that cannot be decrypted afterwards.
|
|
340
|
+
*/
|
|
341
|
+
async function deriveKeyFor(provider, orgId) {
|
|
342
|
+
return provider.deriveKeyAsync ? provider.deriveKeyAsync(orgId) : provider.deriveKey(orgId);
|
|
343
|
+
}
|
|
298
344
|
/**
|
|
299
345
|
* Encrypt a plaintext string for storage. Returns an `EncryptedBlob` that
|
|
300
346
|
* can be JSON-serialized into the underlying column / Mongo document.
|
|
@@ -302,11 +348,13 @@ export class PerOrgKmsKeyProvider {
|
|
|
302
348
|
* Empty strings round-trip as `null` so the calling model layer can treat
|
|
303
349
|
* "no secret set" identically to "field absent".
|
|
304
350
|
*/
|
|
305
|
-
export function encryptSecret(plaintext, orgId, provider = getDefaultProvider()) {
|
|
351
|
+
export async function encryptSecret(plaintext, orgId, provider = getDefaultProvider()) {
|
|
306
352
|
if (!plaintext) {
|
|
307
353
|
throw new Error('Refusing to encrypt empty string; caller should store null instead');
|
|
308
354
|
}
|
|
309
|
-
|
|
355
|
+
// Resolve (and warm) the org BEFORE reading `kidFor` below, so a per-org KMS
|
|
356
|
+
// blob is always stamped with the key it was actually encrypted under.
|
|
357
|
+
const key = await deriveKeyFor(provider, orgId);
|
|
310
358
|
const iv = randomBytes(12);
|
|
311
359
|
const cipher = createCipheriv('aes-256-gcm', key, iv);
|
|
312
360
|
const enc = Buffer.concat([cipher.update(plaintext, 'utf8'), cipher.final()]);
|
|
@@ -333,10 +381,13 @@ export function encryptSecret(plaintext, orgId, provider = getDefaultProvider())
|
|
|
333
381
|
* Callers handle the throw masking the failure as `null` would hide
|
|
334
382
|
* silent corruption / wrong-org reads.
|
|
335
383
|
*/
|
|
336
|
-
export function decryptSecret(blob, orgId, provider = getDefaultProvider()) {
|
|
384
|
+
export async function decryptSecret(blob, orgId, provider = getDefaultProvider()) {
|
|
337
385
|
if (blob.alg !== 'aes-256-gcm-v1') {
|
|
338
386
|
throw new Error(`Unsupported encryption alg: ${blob.alg}`);
|
|
339
387
|
}
|
|
388
|
+
// Warm first: `kidFor` and `deriveKey` below must both speak for the org's
|
|
389
|
+
// real config, or the mismatch guard silently no-ops.
|
|
390
|
+
const key = await deriveKeyFor(provider, orgId);
|
|
340
391
|
// If both the provider AND the blob report a kid, they must match.
|
|
341
392
|
// Mismatch usually means an operator rotated/replaced an org's KMS
|
|
342
393
|
// config and is now reading a blob encrypted under the OLD key —
|
|
@@ -345,7 +396,6 @@ export function decryptSecret(blob, orgId, provider = getDefaultProvider()) {
|
|
|
345
396
|
if (providerKid !== undefined && blob.kid !== undefined && providerKid !== blob.kid) {
|
|
346
397
|
throw new Error(`KMS key id mismatch: blob was encrypted under ${blob.kid}, current provider uses ${providerKid} for org ${orgId}`);
|
|
347
398
|
}
|
|
348
|
-
const key = provider.deriveKey(orgId);
|
|
349
399
|
const iv = Buffer.from(blob.iv, 'base64');
|
|
350
400
|
const all = Buffer.from(blob.ciphertext, 'base64');
|
|
351
401
|
// Split off the 16-byte auth tag appended in encryptSecret. Any tampering
|
|
@@ -371,4 +421,4 @@ export function isEncryptedBlob(value) {
|
|
|
371
421
|
&& typeof value.iv === 'string'
|
|
372
422
|
&& typeof value.ciphertext === 'string');
|
|
373
423
|
}
|
|
374
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjcmV0LWVuY3J5cHRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvc2VjcmV0LWVuY3J5cHRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQkc7QUFFSCxPQUFPLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxRQUFRLENBQUM7QUE2QmpGOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUNSLFNBQVMsQ0FBUztJQUVuQyxZQUFZLGlCQUEwQjtRQUNwQyxNQUFNLEdBQUcsR0FBRyxpQkFBaUIsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDO1FBQ25FLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNULE1BQU0sSUFBSSxLQUFLLENBQUMsNkRBQTZELENBQUMsQ0FBQztRQUNqRixDQUFDO1FBQ0QsMEVBQTBFO1FBQzFFLHNEQUFzRDtRQUN0RCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxLQUFLLEVBQUUsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUMzRCxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMvQixJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssRUFBRSxFQUFFLENBQUM7WUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzREFBc0QsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDM0YsQ0FBQztRQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDO0lBQzNCLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBYTtRQUNy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LElBQUksQ0FBQyxVQUFVLEVBQUUsUUFBUSxDQUFDLENBQUM7SUFDbkQsMEVBQTBFO0lBQzFFLHFFQUFxRTtJQUNyRSxpRUFBaUU7SUFDakUsTUFBTSxHQUFHLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzFDLE1BQU0sR0FBRyxHQUFHLEdBQUcsQ0FBQyxRQUFRLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxNQUFNLEdBQUcsRUFBRSxDQUFDLENBQUM7SUFDN0MsTUFBTSxRQUFRLEdBQUcsZ0JBQWdCLENBQUMsYUFBYSxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztJQUMxRCxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLE1BQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDcEUsT0FBTyxHQUFHLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO0FBQzlCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILE1BQU0sVUFBVSxlQUFlLENBQUMsS0FBYztJQUM1QyxPQUFPLENBQUUsT0FBTyxLQUFLLEtBQUssUUFBUTtXQUM3QixLQUFLLEtBQUssSUFBSTtXQUNiLEtBQTJCLENBQUMsR0FBRyxLQUFLLGdCQUFnQjtXQUNyRCxPQUFRLEtBQTBCLENBQUMsRUFBRSxLQUFLLFFBQVE7V0FDbEQsT0FBUSxLQUFrQyxDQUFDLFVBQVUsS0FBSyxRQUFRLENBQ3RFLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ29weXJpZ2h0IDIwMjYgUGlwZWxpbmUgQnVpbGRlciBDb250cmlidXRvcnNcbi8vIFNQRFgtTGljZW5zZS1JZGVudGlmaWVyOiBBcGFjaGUtMi4wXG5cbi8qKlxuICogIFBlci1vcmcgZW52ZWxvcGUgZW5jcnlwdGlvbiBmb3Igc2VjcmV0IGNvbHVtbnMuXG4gKlxuICogVG9kYXkncyBwb3N0dXJlIGZvciBvcmctc2NvcGVkIHNlY3JldHMgKGFpUHJvdmlkZXJLZXlzLCB3ZWJob29rIFVSTHMsXG4gKiByZWdpc3RyeSBjcmVkZW50aWFscykgaXMgY2xlYXItdGV4dCBpbiBNb25nbyAvIFBvc3RncmVzIHdpdGggYXBwLWxheWVyXG4gKiBtYXNraW5nIG9uIG91dHB1dC4gVGhpcyBtb2R1bGUgaXMgdGhlIGVuY3J5cHRpb24gcHJpbWl0aXZlIHRoYXQgbGV0cyB0aGVcbiAqIG1vZGVsIGxheWVyIHN3YXAgY2xlYXItdGV4dCBzdHJpbmdzIGZvciBgRW5jcnlwdGVkQmxvYmAgdmFsdWVzIGF0IHdyaXRlXG4gKiB0aW1lIGFuZCBkZWNyeXB0IGF0IHJlYWQgdGltZS5cbiAqXG4gKiBDcnlwdG9ncmFwaHkgKiAtIEFFUy0yNTYtR0NNIChhdXRoZW50aWNhdGVkIGVuY3J5cHRpb24pLlxuICogLSBQZXItb3JnIGtleSBkZXJpdmVkIHZpYSBIS0RGLVNIQTI1NihtYXN0ZXJLZXksIHNhbHQ9b3JnSWQsIGluZm89J3NlY3JldHMtdjEnKS5cbiAqIEVhY2ggb3JnIGdldHMgYSB1bmlxdWUga2V5IHdpdGhvdXQgb3BlcmF0b3Iga2V5LW1hbmFnZW1lbnQgY2VyZW1vbnkuXG4gKiAtIDEyLWJ5dGUgSVYgZ2VuZXJhdGVkIHBlciBlbmNyeXB0aW9uIHdpdGggYGNyeXB0by5yYW5kb21CeXRlc2AuXG4gKiAtIDE2LWJ5dGUgYXV0aGVudGljYXRpb24gdGFnIGNvbmNhdGVuYXRlZCB3aXRoIGNpcGhlcnRleHQgKHN0YW5kYXJkIEdDTSkuXG4gKlxuICogT3BlcmF0b3IgY29uZmlndXJhdGlvbiAqIC0gYFNFQ1JFVF9FTkNSWVBUSU9OX0tFWWAgZW52OiBoZXgtIG9yIGJhc2U2NC1lbmNvZGVkIDMyLWJ5dGUgbWFzdGVyIGtleS5cbiAqIFJlcXVpcmVkIHdoZW4gYGVuY3J5cHRTZWNyZXRgL2BkZWNyeXB0U2VjcmV0YCBhcmUgY2FsbGVkLiBNaXNzaW5nIGtleVxuICogdGhyb3dzICBlbmNyeXB0aW9uIGlzIGZhaWwtY2xvc2VkOyB3ZSBuZXZlciBzaWxlbnRseSByb3VuZC10cmlwIGFcbiAqIHNlY3JldCBhcyBwbGFpbnRleHQuXG4gKlxuICogS01TIG1pZ3JhdGlvbiBwYXRoICogLSBUaGUgdHdvIGV4cG9ydGVkIGZ1bmN0aW9ucyB0YWtlIGEgYHByb3ZpZGVyYCBwYXJhbWV0ZXIuIFRoZSBkZWZhdWx0XG4gKiBgRW52S2V5UHJvdmlkZXJgIGltcGxlbWVudHMgSEtERiBkZXJpdmF0aW9uLiBBIGZ1dHVyZSBgQXdzS21zUHJvdmlkZXJgXG4gKiBwbHVncyBpbiBoZXJlOiBpdCBjYW4gY2FsbCBLTVMgYEVuY3J5cHRgIC8gYERlY3J5cHRgIHRvIHdyYXAgYSBERUtcbiAqIHJhdGhlciB0aGFuIGhvbGRpbmcgYSBtYXN0ZXIga2V5IGluIGVudi4gVGhlIG9uLWRpc2sgYmxvYiBzaGFwZVxuICogKGB7IGFsZywgaXYsIGNpcGhlcnRleHQsIGtpZD8gfWApIGlzIGZvcndhcmQtY29tcGF0aWJsZSAgYGtpZGBcbiAqIGNhcnJpZXMgdGhlIEtNUyBrZXkgaWQgd2hlbiB0aGUgcHJvdmlkZXIgbmVlZHMgaXQuXG4gKi9cblxuaW1wb3J0IHsgY3JlYXRlQ2lwaGVyaXYsIGNyZWF0ZURlY2lwaGVyaXYsIGhrZGZTeW5jLCByYW5kb21CeXRlcyB9IGZyb20gJ2NyeXB0byc7XG5cbi8qKiBPbi1kaXNrIHNoYXBlIG9mIGFuIGVuY3J5cHRlZCBzZWNyZXQuIEpTT04tc2VyaWFsaXphYmxlLiAqL1xuZXhwb3J0IGludGVyZmFjZSBFbmNyeXB0ZWRCbG9iIHtcbiAgLyoqIEFsZ29yaXRobSB0YWcuIEJ1bXAgb24gZm9ybWF0IGNoYW5nZSBzbyBhIGZ1dHVyZSBtaWdyYXRpb24gY2FuIGRldGVjdCBvbGQgYmxvYnMuICovXG4gIGFsZzogJ2Flcy0yNTYtZ2NtLXYxJztcbiAgLyoqIEJhc2U2NC1lbmNvZGVkIDEyLWJ5dGUgSVYuICovXG4gIGl2OiBzdHJpbmc7XG4gIC8qKiBCYXNlNjQtZW5jb2RlZCBjaXBoZXJ0ZXh0ICsgMTYtYnl0ZSBhdXRoZW50aWNhdGlvbiB0YWcgY29uY2F0ZW5hdGVkLiAqL1xuICBjaXBoZXJ0ZXh0OiBzdHJpbmc7XG4gIC8qKiBPcHRpb25hbCBrZXkgaWQgIHBvcHVsYXRlZCBieSBLTVMtYmFja2VkIHByb3ZpZGVycywgaWdub3JlZCBieSB0aGUgZW52IHByb3ZpZGVyLiAqL1xuICBraWQ/OiBzdHJpbmc7XG59XG5cbi8qKiBQbHVnZ2FibGUga2V5IHNvdXJjZS4gRW52LWJhY2tlZCBieSBkZWZhdWx0OyBLTVMtYmFja2VkIGF2YWlsYWJsZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgS2V5UHJvdmlkZXIge1xuICAvKiogRGVyaXZlIGEgMzItYnl0ZSBzeW1tZXRyaWMga2V5IGJvdW5kIHRvIGBvcmdJZGAuICovXG4gIGRlcml2ZUtleShvcmdJZDogc3RyaW5nKTogQnVmZmVyO1xuICAvKiogT3B0aW9uYWwgYXN5bmMgdmFyaWFudCBmb3IgcHJvdmlkZXJzIHRoYXQgbmVlZCB0byBkbyBJL08gKGUuZy5cbiAgICogIHBlci1vcmcgS01TIGxvb2t1cCB0aGUgZmlyc3QgdGltZSBhbiBvcmcgaXMgc2VlbikuIERlZmF1bHRcbiAgICogIGltcGxlbWVudGF0aW9uIGZvcndhcmRzIHRvIHRoZSBzeW5jIGBkZXJpdmVLZXlgLiAqL1xuICBkZXJpdmVLZXlBc3luYz8ob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPjtcbiAgLyoqIE9wdGlvbmFsIEtNUy1rZXktaWQgdGhpcyBwcm92aWRlciB1c2VkIGZvciBgb3JnSWRgLiBFbWJlZGRlZCBpbiB0aGVcbiAgICogIGBFbmNyeXB0ZWRCbG9iLmtpZGAgZmllbGQgb24gd3JpdGUgc28gZGVjcnlwdCBjYW4gdmVyaWZ5IHRoZSByaWdodFxuICAgKiAgS01TIENNSyBpcyBiZWluZyB1c2VkIChkZWZlbnNlIGFnYWluc3QgYW4gYXR0YWNrZXIgd2hvIHN3YXBzIGEgYmxvYlxuICAgKiAgYmV0d2VlbiBvcmdzKS4gRGVmYXVsdCByZXR1cm5zIHVuZGVmaW5lZCAoZW52IHByb3ZpZGVyKS4gKi9cbiAga2lkRm9yPyhvcmdJZDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuXG4vKipcbiAqIERlZmF1bHQgcHJvdmlkZXIgIGRlcml2ZXMgYSBwZXItb3JnIGtleSBmcm9tIGBTRUNSRVRfRU5DUllQVElPTl9LRVlgIHZpYVxuICogSEtERi1TSEEyNTYuIFN1aXRhYmxlIGZvciBzZWxmLWhvc3RlZCAvIGRldiB3aGVyZSBvcGVyYXRvcnMgZG9uJ3QgaGF2ZSBLTVMuXG4gKlxuICogRmFpbHMgZmFzdCBpZiB0aGUgZW52IGlzIG1pc3Npbmcgb3IgdGhlIGtleSBpcyB0aGUgd3JvbmcgbGVuZ3RoIHNvIG1pc2NvbmZpZ1xuICogc3VyZmFjZXMgYXQgZmlyc3QgdXNlIHJhdGhlciB0aGFuIHNpbGVudGx5IGZpbmdlcnByaW50aW5nIGFsbCB3cml0ZXMgd2l0aFxuICogYSBkZWZhdWx0IHplcm8ga2V5LlxuICovXG5leHBvcnQgY2xhc3MgRW52S2V5UHJvdmlkZXIgaW1wbGVtZW50cyBLZXlQcm92aWRlciB7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWFzdGVyS2V5OiBCdWZmZXI7XG5cbiAgY29uc3RydWN0b3IobWFzdGVyS2V5T3ZlcnJpZGU/OiBzdHJpbmcpIHtcbiAgICBjb25zdCByYXcgPSBtYXN0ZXJLZXlPdmVycmlkZSA/PyBwcm9jZXNzLmVudi5TRUNSRVRfRU5DUllQVElPTl9LRVk7XG4gICAgaWYgKCFyYXcpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignU0VDUkVUX0VOQ1JZUFRJT05fS0VZIGVudiBpcyByZXF1aXJlZCBmb3Igc2VjcmV0IGVuY3J5cHRpb24nKTtcbiAgICB9XG4gICAgLy8gQWNjZXB0IGVpdGhlciBoZXggKDY0IGNoYXJzKSBvciBiYXNlNjQgKDQ0IGNoYXJzIGluY2x1ZGluZyBwYWRkaW5nKSBmb3JcbiAgICAvLyBvcGVyYXRvciBjb252ZW5pZW5jZSAgYm90aCBkZWNvZGUgdG8gYSAzMi1ieXRlIGtleS5cbiAgICBjb25zdCBkZWNvZGVkID0gcmF3Lmxlbmd0aCA9PT0gNjQgJiYgL15bMC05YS1mXSskL2kudGVzdChyYXcpXG4gICAgICA/IEJ1ZmZlci5mcm9tKHJhdywgJ2hleCcpXG4gICAgICA6IEJ1ZmZlci5mcm9tKHJhdywgJ2Jhc2U2NCcpO1xuICAgIGlmIChkZWNvZGVkLmxlbmd0aCAhPT0gMzIpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgU0VDUkVUX0VOQ1JZUFRJT05fS0VZIG11c3QgZGVjb2RlIHRvIDMyIGJ5dGVzIChnb3QgJHtkZWNvZGVkLmxlbmd0aH0pYCk7XG4gICAgfVxuICAgIHRoaXMubWFzdGVyS2V5ID0gZGVjb2RlZDtcbiAgfVxuXG4gIGRlcml2ZUtleShvcmdJZDogc3RyaW5nKTogQnVmZmVyIHtcbiAgICAvLyBIS0RGIGJpbmRzIHRoZSBtYXN0ZXIga2V5IHRvIHRoZSBvcmcgc28gdHdvIG9yZ3MgZW5jcnlwdGluZyB0aGUgc2FtZVxuICAgIC8vIHBsYWludGV4dCBwcm9kdWNlIGRpZmZlcmVudCBjaXBoZXJ0ZXh0cyAga2VlcHMgYSBzdG9sZW4gREIgdW5hYmxlIHRvXG4gICAgLy8gdGVsbCB3aGljaCBvcmdzIHNoYXJlIHNlY3JldHMgdmlhIGNpcGhlcnRleHQgY29tcGFyaXNvbi5cbiAgICBjb25zdCBkZXJpdmVkID0gaGtkZlN5bmMoICdzaGEyNTYnLFxuICAgICAgdGhpcy5tYXN0ZXJLZXksXG4gICAgICBCdWZmZXIuZnJvbShvcmdJZCwgJ3V0ZjgnKSxcbiAgICAgICdzZWNyZXRzLXYxJyxcbiAgICAgIDMyLFxuICAgICk7XG4gICAgLy8gaGtkZlN5bmMgcmV0dXJucyBBcnJheUJ1ZmZlciBpbiBvbGRlciBOb2RlIHR5cGluZ3M7IG5vcm1hbGl6ZSB0byBCdWZmZXIuXG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRlcml2ZWQpO1xuICB9XG59XG5cbi8qKlxuICogIEFXUy1LTVMtYmFja2VkIEtleVByb3ZpZGVyLlxuICpcbiAqIFRyYWRlLW9mZiBwaWNrZWQ6IHN0b3JlIE9ORSBtYXN0ZXIga2V5IGVuY3J5cHRlZCB1bmRlciBhIEtNUyBDTUs7IG9uXG4gKiBmaXJzdCB1c2UsIGNhbGwgYGttczpEZWNyeXB0YCB0byByZWNvdmVyIHRoZSBtYXN0ZXIga2V5IGJ5dGVzOyBIS0RGLVxuICogZGVyaXZlIHBlci1vcmcgZnJvbSBpdCAoc2FtZSBhcyBFbnZLZXlQcm92aWRlcikuIFRoZSBwcm9jZXNzIHRoZW4gaG9sZHNcbiAqIHRoZSBwbGFpbnRleHQgbWFzdGVyIGtleSBpbiBtZW1vcnkgdW50aWwgcmVzdGFydC5cbiAqXG4gKiBQUk9TOiBvbmUgS01TIGNhbGwgcGVyIHByb2Nlc3MgbGlmZXRpbWUgKGNoZWFwLCBsb3cgcDk5IGltcGFjdCksXG4gKiB0aGUgZW5jcnlwdGVkLW1hc3Rlci1rZXkgYmxvYiBpcyBzYWZlIHRvIGNvbW1pdC9sb2cvY2hlY2tpbixcbiAqIEtNUyBhdWRpdCBsb2cgcmVjb3JkcyB3aGVuIHRoZSBtYXN0ZXIgaXMgcmVjb3ZlcmVkLlxuICogQ09OUzogcHJvY2VzcyBtZW1vcnkgc3RpbGwgaG9sZHMgdGhlIG1hc3RlciBrZXkgIHNhbWUgcG9zdHVyZSBhc1xuICogRW52S2V5UHJvdmlkZXIgb25jZSB3YXJtZWQgdXAuIEZvciBzdHJvbmdlciBpc29sYXRpb24gYW5cbiAqIG9wZXJhdG9yIGNhbiBtb3ZlIHRvIHBlci1yZWNvcmQgZW52ZWxvcGUgZW5jcnlwdGlvbiAoY2FsbFxuICogR2VuZXJhdGVEYXRhS2V5IG9uIGV2ZXJ5IHdyaXRlKTsgdGhhdCdzIGEgZm9sbG93LW9uLlxuICpcbiAqIE9wZXJhdG9yIHNldHVwICogMS4gQ3JlYXRlIGEgS01TIENNSyB3aXRoIGtleSBwb2xpY3kgYWxsb3dpbmcgdGhlIHBsYXRmb3JtIHNlcnZpY2Unc1xuICogSUFNIHJvbGUga21zOkRlY3J5cHQuXG4gKiAyLiBHZW5lcmF0ZSBhIHJhbmRvbSAzMi1ieXRlIG1hc3RlciAqIGhlYWQgLWMgMzIgL2Rldi91cmFuZG9tIHwgYmFzZTY0XG4gKiAzLiBXcmFwIGl0IHdpdGggS01TICogYXdzIGttcyBlbmNyeXB0IC0ta2V5LWlkIDxLRVlfSUQ+IFxcXG4gKiAtLXBsYWludGV4dCA8YmFzZTY0LWZyb20tc3RlcC0yPiAtLW91dHB1dCB0ZXh0IFxcXG4gKiAtLXF1ZXJ5IENpcGhlcnRleHRCbG9iXG4gKiA0LiBTZXQgb24gdGhlIHNlcnZpY2UgKiBTRUNSRVRfRU5DUllQVElPTl9LTVNfS0VZX0lEPTxLRVlfSUQ+XG4gKiBTRUNSRVRfRU5DUllQVElPTl9LTVNfQ0lQSEVSVEVYVD08YmFzZTY0LW91dHB1dC1vZi1zdGVwLTM+XG4gKiA1LiBQaWNrIHRoaXMgcHJvdmlkZXIgdmlhIGBzZXRLZXlQcm92aWRlcihuZXcgS21zS2V5UHJvdmlkZXIoKSlgLlxuICpcbiAqIENvbnN0cnVjdCBsYXppbHkgIGltcG9ydGluZyB0aGUgQVdTIFNESyBoYXMgYSBub24tdHJpdmlhbCBjb2xkLXN0YXJ0XG4gKiBjb3N0IHNvIGVudnMgdGhhdCBzdGF5IG9uIEVudktleVByb3ZpZGVyIG5ldmVyIGxvYWQgaXQuXG4gKi9cbi8qKlxuICogS01TLWRlY3J5cHQgYSBiYXNlNjQgY2lwaGVydGV4dCBpbnRvIGEgMzItYnl0ZSBrZXkuIFNoYXJlZCBieSBib3RoIEtNUyBrZXlcbiAqIHByb3ZpZGVycyAoc2luZ2xlLW1hc3RlciArIHBlci1vcmcpLCB3aGljaCBwcmV2aW91c2x5IGNvcHktcGFzdGVkIHRoaXNcbiAqIGR5bmFtaWMtaW1wb3J0ICsgRGVjcnlwdCArIGVtcHR5L2xlbmd0aCBndWFyZHMuIGBAYXdzLXNkay9jbGllbnQta21zYCBpc1xuICogZHluYW1pY2FsbHkgaW1wb3J0ZWQgc28gRW52S2V5UHJvdmlkZXItb25seSBlbnZzIG5ldmVyIGxvYWQgdGhlIFNESy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24ga21zRGVjcnlwdDMyKGtleUlkOiBzdHJpbmcsIGNpcGhlcnRleHRCNjQ6IHN0cmluZywgcmVnaW9uPzogc3RyaW5nLCBlbmRwb2ludD86IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPiB7XG4gIGNvbnN0IHsgS01TQ2xpZW50LCBEZWNyeXB0Q29tbWFuZCB9ID0gYXdhaXQgaW1wb3J0KCdAYXdzLXNkay9jbGllbnQta21zJyk7XG4gIGNvbnN0IGNsaWVudCA9IG5ldyBLTVNDbGllbnQoeyByZWdpb24sIC4uLihlbmRwb2ludCA/IHsgZW5kcG9pbnQgfSA6IHt9KSB9KTtcbiAgY29uc3QgcmVzcCA9IGF3YWl0IGNsaWVudC5zZW5kKG5ldyBEZWNyeXB0Q29tbWFuZCh7XG4gICAgS2V5SWQ6IGtleUlkLFxuICAgIENpcGhlcnRleHRCbG9iOiBCdWZmZXIuZnJvbShjaXBoZXJ0ZXh0QjY0LCAnYmFzZTY0JyksXG4gIH0pKTtcbiAgaWYgKCFyZXNwLlBsYWludGV4dCkgdGhyb3cgbmV3IEVycm9yKGBLTVMgRGVjcnlwdCByZXR1cm5lZCBhbiBlbXB0eSBQbGFpbnRleHQgZm9yIGtleSAke2tleUlkfWApO1xuICBjb25zdCBidWYgPSBCdWZmZXIuZnJvbShyZXNwLlBsYWludGV4dCk7XG4gIGlmIChidWYubGVuZ3RoICE9PSAzMikgdGhyb3cgbmV3IEVycm9yKGBLTVMgRGVjcnlwdCByZXR1cm5lZCAke2J1Zi5sZW5ndGh9LWJ5dGUga2V5IGZvciAke2tleUlkfTsgZXhwZWN0ZWQgMzJgKTtcbiAgcmV0dXJuIGJ1Zjtcbn1cblxuZXhwb3J0IGNsYXNzIEttc0tleVByb3ZpZGVyIGltcGxlbWVudHMgS2V5UHJvdmlkZXIge1xuICBwcml2YXRlIG1hc3RlcktleUNhY2hlOiBCdWZmZXIgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSByZWFkb25seSBrZXlJZDogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGNpcGhlcnRleHRCNjQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSByZWdpb24/OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgZW5kcG9pbnQ/OiBzdHJpbmc7XG4gIHByaXZhdGUgZGVjcnlwdEluRmxpZ2h0OiBQcm9taXNlPEJ1ZmZlcj4gfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihvcHRzPzogeyBrZXlJZD86IHN0cmluZzsgY2lwaGVydGV4dEJhc2U2ND86IHN0cmluZzsgcmVnaW9uPzogc3RyaW5nOyBlbmRwb2ludD86IHN0cmluZyB9KSB7XG4gICAgY29uc3Qga2V5SWQgPSBvcHRzPy5rZXlJZCA/PyBwcm9jZXNzLmVudi5TRUNSRVRfRU5DUllQVElPTl9LTVNfS0VZX0lEO1xuICAgIGNvbnN0IGNpcGhlcnRleHQgPSBvcHRzPy5jaXBoZXJ0ZXh0QmFzZTY0ID8/IHByb2Nlc3MuZW52LlNFQ1JFVF9FTkNSWVBUSU9OX0tNU19DSVBIRVJURVhUO1xuICAgIGlmICgha2V5SWQpIHRocm93IG5ldyBFcnJvcignU0VDUkVUX0VOQ1JZUFRJT05fS01TX0tFWV9JRCBlbnYgaXMgcmVxdWlyZWQgZm9yIEttc0tleVByb3ZpZGVyJyk7XG4gICAgaWYgKCFjaXBoZXJ0ZXh0KSB0aHJvdyBuZXcgRXJyb3IoJ1NFQ1JFVF9FTkNSWVBUSU9OX0tNU19DSVBIRVJURVhUIGVudiBpcyByZXF1aXJlZCBmb3IgS21zS2V5UHJvdmlkZXInKTtcbiAgICB0aGlzLmtleUlkID0ga2V5SWQ7XG4gICAgdGhpcy5jaXBoZXJ0ZXh0QjY0ID0gY2lwaGVydGV4dDtcbiAgICB0aGlzLnJlZ2lvbiA9IG9wdHM/LnJlZ2lvbiA/PyBwcm9jZXNzLmVudi5BV1NfUkVHSU9OID8/IHByb2Nlc3MuZW52LkFXU19ERUZBVUxUX1JFR0lPTjtcbiAgICB0aGlzLmVuZHBvaW50ID0gb3B0cz8uZW5kcG9pbnQgPz8gcHJvY2Vzcy5lbnYuQVdTX0tNU19FTkRQT0lOVDtcbiAgfVxuXG4gIGRlcml2ZUtleShvcmdJZDogc3RyaW5nKTogQnVmZmVyIHtcbiAgICBpZiAoIXRoaXMubWFzdGVyS2V5Q2FjaGUpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvciggJ0ttc0tleVByb3ZpZGVyIGlzIG5vdCB3YXJtZWQgdXAuIENhbGwgYGF3YWl0IHByb3ZpZGVyLndhcm11cCgpYCBvbmNlIGF0IHNlcnZpY2Ugc3RhcnR1cCBiZWZvcmUgYW55IGVuY3J5cHQvZGVjcnlwdC4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZGVyaXZlZCA9IGhrZGZTeW5jKCdzaGEyNTYnLCB0aGlzLm1hc3RlcktleUNhY2hlLCBCdWZmZXIuZnJvbShvcmdJZCwgJ3V0ZjgnKSwgJ3NlY3JldHMtdjEnLCAzMik7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRlcml2ZWQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVhZ2VybHkgcmVjb3ZlciB0aGUgbWFzdGVyIGtleSBmcm9tIEtNUyBzbyBzdWJzZXF1ZW50IGBkZXJpdmVLZXlgXG4gICAqIGNhbGxzIGFyZSBzeW5jLiBJZGVtcG90ZW50ICBjb25jdXJyZW50IGNhbGxlcnMgc2hhcmUgdGhlIHNhbWUgaW4tXG4gICAqIGZsaWdodCBwcm9taXNlIHNvIHdlIGRvbid0IHNwYXduIG11bHRpcGxlIEtNUyBEZWNyeXB0IHJlcXVlc3RzIGF0XG4gICAqIGJvb3QuIFRocm93cyBvbiBhbnkgS01TIGZhaWx1cmU7IHRoZSBjYWxsZXIgKHR5cGljYWxseSB0aGUgc2VydmljZSdzXG4gICAqIG9uQmVmb3JlU3RhcnQgaG9vaykgZGVjaWRlcyB3aGV0aGVyIHRvIGZhbGwgYmFjayB0byBhIGRpZmZlcmVudFxuICAgKiBwcm92aWRlciBvciBmYWlsLXN0YXJ0dXAuXG4gICAqL1xuICBhc3luYyB3YXJtdXAoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMubWFzdGVyS2V5Q2FjaGUpIHJldHVybjtcbiAgICBpZiAoIXRoaXMuZGVjcnlwdEluRmxpZ2h0KSB7XG4gICAgICB0aGlzLmRlY3J5cHRJbkZsaWdodCA9IHRoaXMuZmV0Y2hBbmREZWNyeXB0KCk7XG4gICAgfVxuICAgIHRyeSB7XG4gICAgICB0aGlzLm1hc3RlcktleUNhY2hlID0gYXdhaXQgdGhpcy5kZWNyeXB0SW5GbGlnaHQ7XG4gICAgfSBjYXRjaCAoZXJyKSB7XG4gICAgICAvLyBBIHRyYW5zaWVudCBLTVMgZmFpbHVyZSBtdXN0IG5vdCBwZXJtYW5lbnRseSBwb2lzb24gdGhlIHByb3ZpZGVyOiBjbGVhclxuICAgICAgLy8gdGhlIHJlamVjdGVkIGluLWZsaWdodCBwcm9taXNlIHNvIGEgbGF0ZXIgd2FybXVwKCkgcmV0cmllcyBpbnN0ZWFkIG9mXG4gICAgICAvLyByZS1hd2FpdGluZyB0aGUgc2FtZSByZWplY3Rpb24gZm9yZXZlciAobWF0Y2hlcyBQZXJPcmdLbXNLZXlQcm92aWRlcikuXG4gICAgICB0aGlzLmRlY3J5cHRJbkZsaWdodCA9IG51bGw7XG4gICAgICB0aHJvdyBlcnI7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaEFuZERlY3J5cHQoKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICByZXR1cm4ga21zRGVjcnlwdDMyKHRoaXMua2V5SWQsIHRoaXMuY2lwaGVydGV4dEI2NCwgdGhpcy5yZWdpb24sIHRoaXMuZW5kcG9pbnQpO1xuICB9XG59XG5cbi8vIExhenkgc2luZ2xldG9uICBvcGVyYXRvciBjb2RlIGluIGxvbmctbGl2ZWQgc2VydmljZXMgcGF5cyB0aGUgZW52LXBhcnNlXG4vLyBjb3N0IG9uY2UsIGFuZCB0ZXN0cyBjYW4gbWludCB0aGVpciBvd24gcHJvdmlkZXIgd2l0aCBhIGxpdGVyYWwga2V5LlxubGV0IGRlZmF1bHRQcm92aWRlcjogS2V5UHJvdmlkZXIgfCBudWxsID0gbnVsbDtcbmZ1bmN0aW9uIGdldERlZmF1bHRQcm92aWRlcigpOiBLZXlQcm92aWRlciB7XG4gIGlmICghZGVmYXVsdFByb3ZpZGVyKSBkZWZhdWx0UHJvdmlkZXIgPSBuZXcgRW52S2V5UHJvdmlkZXIoKTtcbiAgcmV0dXJuIGRlZmF1bHRQcm92aWRlcjtcbn1cblxuLyoqIFJlYWQgdGhlIGFjdGl2ZSBkZWZhdWx0IHByb3ZpZGVyLiBFeHBvc2VkIHNvIHNlcnZpY2UgY29kZSAoZS5nLiBhblxuICogIGFkbWluIGVuZHBvaW50IHRoYXQganVzdCByb3RhdGVkIGFuIG9yZydzIEtNUyBjb25maWcpIGNhbiBjYWxsXG4gKiAgYHByb3ZpZGVyLmV2aWN0KG9yZ0lkKWAgb24gdGhlIGxpdmUgcHJvdmlkZXIgcmF0aGVyIHRoYW4gcmVjb25zdHJ1Y3RpbmdcbiAqICBvbmUuIFRyaWdnZXJzIGxhenkgaW5pdGlhbGl6YXRpb24gb24gZmlyc3QgYWNjZXNzLCBzYW1lIGFzIHRoZSBpbnRlcm5hbFxuICogIGNhbGxlcnMgYmVsb3cuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0RGVmYXVsdEtleVByb3ZpZGVyKCk6IEtleVByb3ZpZGVyIHtcbiAgcmV0dXJuIGdldERlZmF1bHRQcm92aWRlcigpO1xufVxuXG4vKiogUmVzZXQgdGhlIGNhY2hlZCBkZWZhdWx0IHByb3ZpZGVyICBmb3IgdGVzdHMgdGhhdCBtdXRhdGUgYHByb2Nlc3MuZW52YC4gKi9cbmV4cG9ydCBmdW5jdGlvbiByZXNldERlZmF1bHRLZXlQcm92aWRlcigpOiB2b2lkIHsgZGVmYXVsdFByb3ZpZGVyID0gbnVsbDsgfVxuXG4vKiogUmVwbGFjZSB0aGUgZGVmYXVsdCBwcm92aWRlciAgc2VydmljZXMgdGhhdCBvcHQgaW50byBLTVMgY2FsbCB0aGlzXG4gKiBvbmNlIGF0IHN0YXJ0dXAgd2l0aCBhIHdhcm1lZC11cCBgS21zS2V5UHJvdmlkZXJgLiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNldEtleVByb3ZpZGVyKHByb3ZpZGVyOiBLZXlQcm92aWRlcik6IHZvaWQgeyBkZWZhdWx0UHJvdmlkZXIgPSBwcm92aWRlcjsgfVxuXG4vKiogUGVyLW9yZyBLTVMgY29uZmlnIHRoZSBvcGVyYXRvciBzdXBwbGllcy4gVGhlIGBrZXlJZGAgaWRlbnRpZmllcyB0aGVcbiAqICBLTVMgQ01LIHRvIGNhbGwgRGVjcnlwdCBvbjsgYGNpcGhlcnRleHRCYXNlNjRgIGlzIHRoZSB3cmFwcGVkIDMyLWJ5dGVcbiAqICBtYXN0ZXIgZ2VuZXJhdGVkIGJ5IGBhd3Mga21zIGVuY3J5cHRgIGFnYWluc3QgdGhhdCBrZXkuICovXG5leHBvcnQgaW50ZXJmYWNlIFBlck9yZ0ttc0NvbmZpZyB7XG4gIGtleUlkOiBzdHJpbmc7XG4gIGNpcGhlcnRleHRCYXNlNjQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBBc3luYyByZXNvbHZlciB0aGF0IG1hcHMgYW4gb3JnIGlkIHRvIGl0cyBLTVMgY29uZmlnLiBSZXR1cm5zIGBudWxsYCB3aGVuXG4gKiB0aGUgb3JnIGhhcyBubyBwZXItb3JnIGNvbmZpZyDigJQgdGhlIHByb3ZpZGVyIHRoZW4gZmFsbHMgYmFjayB0byB0aGVcbiAqIGBmYWxsYmFja2AgcHJvdmlkZXIgc3VwcGxpZWQgYXQgY29uc3RydWN0aW9uICh1c3VhbGx5IGFuIEVudktleVByb3ZpZGVyXG4gKiBvciBhIGRlZmF1bHQgS21zS2V5UHJvdmlkZXIpLlxuICovXG5leHBvcnQgdHlwZSBQZXJPcmdLbXNSZXNvbHZlciA9IChvcmdJZDogc3RyaW5nKSA9PiBQcm9taXNlPFBlck9yZ0ttc0NvbmZpZyB8IG51bGw+O1xuXG4vKipcbiAqIFBlci1vcmcgS01TLWJhY2tlZCBLZXlQcm92aWRlci4gVGhlIGJsYXN0IHJhZGl1cyBvZiBhIEtNUyBrZXkgY29tcHJvbWlzZVxuICogaXMgb25lIG9yZyBpbnN0ZWFkIG9mIGV2ZXJ5IG9yZyB1bmRlciBhIHNoYXJlZCBtYXN0ZXIuXG4gKlxuICogRWFjaCBvcmcgaGFzIGl0cyBvd24gS01TIENNSyArIGl0cyBvd24gd3JhcHBlZCBtYXN0ZXIgKHN0b3JlZCBpbiBNb25nb1xuICogdmlhIHRoZSBvcGVyYXRvcidzIHNldHVwIHNjcmlwdCkuIE9uIGZpcnN0IGVuY3J5cHQvZGVjcnlwdCBmb3IgYW4gb3JnLFxuICogdGhlIHByb3ZpZGVyOlxuICogICAxLiBDYWxscyB0aGUgcmVzb2x2ZXIgdG8gZmV0Y2ggdGhlIG9yZydzIEtNUyBjb25maWcuXG4gKiAgIDIuIENhbGxzIGBrbXM6RGVjcnlwdGAgdG8gcmVjb3ZlciB0aGUgMzItYnl0ZSBtYXN0ZXIuXG4gKiAgIDMuIENhY2hlcyB0aGUgcmVjb3ZlcmVkIG1hc3RlciBpbi1tZW1vcnkgZm9yIHRoZSBwcm9jZXNzIGxpZmV0aW1lLlxuICogICA0LiBIS0RGLWRlcml2ZXMgcGVyLWNhbGwgZnJvbSB0aGF0IG1hc3RlciArIHRoZSBvcmcgaWQgc2FsdC5cbiAqXG4gKiBCbG9icyBlbmNyeXB0ZWQgYnkgdGhpcyBwcm92aWRlciBjYXJyeSBga2lkID0gPGttcy1rZXktaWQ+YCBzbyB0aGVcbiAqIGRlY3J5cHQgcGF0aCBkZXRlY3RzIGEgc3RhbGUgY29uZmlnIChvcGVyYXRvciByb3RhdGVkIHRoZSBrZXkgYnV0XG4gKiBleGlzdGluZyByb3dzIHdlcmVuJ3QgcmUtZW5jcnlwdGVkKSBCRUZPUkUgQUVTLUdDTSB0aHJvd3MgYW4gb3BhcXVlXG4gKiBhdXRoZW50aWNhdGlvbi10YWcgZXJyb3IuXG4gKlxuICogT3JncyB3aXRob3V0IHBlci1vcmcgY29uZmlnIGZhbGwgdGhyb3VnaCB0byB0aGUgYGZhbGxiYWNrYCBwcm92aWRlciDigJRcbiAqIG1peGVkLW1vZGUgZGVwbG95bWVudHMgd2hlcmUgc29tZSBvcmdzIGhhdmUgS01TIGlzb2xhdGlvbiBhbmQgb3RoZXJzXG4gKiBzdGF5IG9uIHRoZSBzaGFyZWQgbWFzdGVyIGFyZSBleHBsaWNpdGx5IHN1cHBvcnRlZC5cbiAqL1xuZXhwb3J0IGNsYXNzIFBlck9yZ0ttc0tleVByb3ZpZGVyIGltcGxlbWVudHMgS2V5UHJvdmlkZXIge1xuICAvKiogQ2FjaGVkIHBlci1vcmcgbWFzdGVyIGtleXMsIGtleWVkIGJ5IG9yZ0lkLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IG1hc3RlcnMgPSBuZXcgTWFwPHN0cmluZywgeyBrZXk6IEJ1ZmZlcjsga2lkOiBzdHJpbmcgfT4oKTtcbiAgLyoqIFJlc29sdmVkIHBlci1vcmcgY29uZmlncyBjYWNoZWQgZm9yIHRoZSBwcm9jZXNzIGxpZmV0aW1lLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGNvbmZpZ3MgPSBuZXcgTWFwPHN0cmluZywgUGVyT3JnS21zQ29uZmlnPigpO1xuICAvKiogSW4tZmxpZ2h0IHJlc29sdmVyIHByb21pc2VzIHNvIGNvbmN1cnJlbnQgZmlyc3QtdG91Y2ggY2FsbGVycyBzaGFyZSBvbmUgS01TIERlY3J5cHQuXG4gICAqICBSZXNvbHZlcyB0byBgbnVsbGAgZm9yIG9yZ3Mgd2l0aCBubyBwZXItb3JnIGNvbmZpZyDigJQgY2FsbGVyIHRyZWF0cyBudWxsIGFzXG4gICAqICBcImZhbGwgdGhyb3VnaCB0byB0aGUgZmFsbGJhY2sgcHJvdmlkZXJcIiwgc2FtZSBhcyBhIGNvbGQgY2FjaGUgbWlzcy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBpbkZsaWdodCA9IG5ldyBNYXA8c3RyaW5nLCBQcm9taXNlPHsga2V5OiBCdWZmZXI7IGtpZDogc3RyaW5nIH0gfCBudWxsPj4oKTtcbiAgLyoqIFByb3ZpZGVyIHVzZWQgZm9yIG9yZ3MgdGhhdCBoYXZlIG5vIHBlci1vcmcgY29uZmlnLiAqL1xuICBwcml2YXRlIHJlYWRvbmx5IGZhbGxiYWNrOiBLZXlQcm92aWRlcjtcbiAgcHJpdmF0ZSByZWFkb25seSByZXNvbHZlcjogUGVyT3JnS21zUmVzb2x2ZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uPzogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGVuZHBvaW50Pzogc3RyaW5nO1xuXG4gIGNvbnN0cnVjdG9yKG9wdHM6IHtcbiAgICByZXNvbHZlcjogUGVyT3JnS21zUmVzb2x2ZXI7XG4gICAgZmFsbGJhY2s6IEtleVByb3ZpZGVyO1xuICAgIHJlZ2lvbj86IHN0cmluZztcbiAgICBlbmRwb2ludD86IHN0cmluZztcbiAgfSkge1xuICAgIHRoaXMucmVzb2x2ZXIgPSBvcHRzLnJlc29sdmVyO1xuICAgIHRoaXMuZmFsbGJhY2sgPSBvcHRzLmZhbGxiYWNrO1xuICAgIHRoaXMucmVnaW9uID0gb3B0cy5yZWdpb24gPz8gcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiA/PyBwcm9jZXNzLmVudi5BV1NfREVGQVVMVF9SRUdJT047XG4gICAgdGhpcy5lbmRwb2ludCA9IG9wdHMuZW5kcG9pbnQgPz8gcHJvY2Vzcy5lbnYuQVdTX0tNU19FTkRQT0lOVDtcbiAgfVxuXG4gIC8qKiBTeW5jIGBkZXJpdmVLZXlgIG9ubHkgd29ya3MgZm9yIGFscmVhZHktd2FybWVkIG9yZ3MuIENvbGQgb3JncyBmYWxsXG4gICAqICB0aHJvdWdoIHRvIHRoZSBmYWxsYmFjayBwcm92aWRlci4gQ2FsbGVycyB0aGF0IHdhbnQgcGVyLW9yZyBpc29sYXRpb25cbiAgICogIE1VU1QgYGF3YWl0IGRlcml2ZUtleUFzeW5jKG9yZ0lkKWAgb25jZSBmaXJzdCAoZS5nLiBkdXJpbmcgcmVxdWVzdCBzZXR1cFxuICAgKiAgb3IgYXMgcGFydCBvZiBhIHdhcm11cCBwYXNzKSDigJQgb3RoZXJ3aXNlIHRoZSBvcmcgc2lsZW50bHkgdXNlcyB0aGVcbiAgICogIHNoYXJlZCBtYXN0ZXIuICovXG4gIGRlcml2ZUtleShvcmdJZDogc3RyaW5nKTogQnVmZmVyIHtcbiAgICBjb25zdCBjYWNoZWQgPSB0aGlzLm1hc3RlcnMuZ2V0KG9yZ0lkKTtcbiAgICBpZiAoIWNhY2hlZCkgcmV0dXJuIHRoaXMuZmFsbGJhY2suZGVyaXZlS2V5KG9yZ0lkKTtcbiAgICBjb25zdCBkZXJpdmVkID0gaGtkZlN5bmMoJ3NoYTI1NicsIGNhY2hlZC5rZXksIEJ1ZmZlci5mcm9tKG9yZ0lkLCAndXRmOCcpLCAnc2VjcmV0cy12MScsIDMyKTtcbiAgICByZXR1cm4gQnVmZmVyLmZyb20oZGVyaXZlZCk7XG4gIH1cblxuICBhc3luYyBkZXJpdmVLZXlBc3luYyhvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICBhd2FpdCB0aGlzLmVuc3VyZVdhcm1lZChvcmdJZCk7XG4gICAgcmV0dXJuIHRoaXMuZGVyaXZlS2V5KG9yZ0lkKTtcbiAgfVxuXG4gIGtpZEZvcihvcmdJZDogc3RyaW5nKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5tYXN0ZXJzLmdldChvcmdJZCk/LmtpZCA/PyB0aGlzLmZhbGxiYWNrLmtpZEZvcj8uKG9yZ0lkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXNvbHZlIHRoZSBvcmcncyBLTVMgY29uZmlnLCBjYWxsIERlY3J5cHQsIGNhY2hlIHRoZSBtYXN0ZXIuIFN1YnNlcXVlbnRcbiAgICogY2FsbHMgZm9yIHRoZSBzYW1lIG9yZyBhcmUgbm8tb3BzLiBDb25jdXJyZW50IGNhbGxlcnMgc2hhcmUgdGhlIGluLWZsaWdodFxuICAgKiBEZWNyeXB0IHByb21pc2UuXG4gICAqXG4gICAqIFJldHVybnMgc2lsZW50bHkgd2hlbiB0aGUgb3JnIGhhcyBubyBwZXItb3JnIGNvbmZpZyDigJQgdGhlIGZhbGxiYWNrXG4gICAqIHByb3ZpZGVyIGhhbmRsZXMgdGhvc2Ugb3Jncy5cbiAgICovXG4gIGFzeW5jIGVuc3VyZVdhcm1lZChvcmdJZDogc3RyaW5nKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgaWYgKHRoaXMubWFzdGVycy5oYXMob3JnSWQpKSByZXR1cm47XG4gICAgLy8gSW5zdGFsbCB0aGUgaW4tZmxpZ2h0IHByb21pc2UgU1lOQ0hST05PVVNMWSBiZWZvcmUgeWllbGRpbmcgc28gY29uY3VycmVudFxuICAgIC8vIGNhbGxlcnMgZmluZCBpdCBvbiB0aGUgc2Vjb25kLWFuZC1sYXRlciBwYXNzZXMuIEF3YWl0aW5nIHRoZSByZXNvbHZlclxuICAgIC8vIGJlZm9yZSBwb3B1bGF0aW5nIHRoZSBtYXAgaXMgdGhlIGJ1ZyB0aGF0IGxldHMgYSBQcm9taXNlLmFsbCBvZiAzXG4gICAgLy8gY2FsbGVycyBmaXJlIDMgS01TIERlY3J5cHRzLlxuICAgIGxldCBwcm9taXNlID0gdGhpcy5pbkZsaWdodC5nZXQob3JnSWQpO1xuICAgIGlmICghcHJvbWlzZSkge1xuICAgICAgcHJvbWlzZSA9IHRoaXMucmVzb2x2ZUFuZERlY3J5cHQob3JnSWQpO1xuICAgICAgdGhpcy5pbkZsaWdodC5zZXQob3JnSWQsIHByb21pc2UpO1xuICAgICAgdm9pZCBwcm9taXNlLmZpbmFsbHkoKCkgPT4geyBpZiAodGhpcy5pbkZsaWdodC5nZXQob3JnSWQpID09PSBwcm9taXNlKSB0aGlzLmluRmxpZ2h0LmRlbGV0ZShvcmdJZCk7IH0pO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHQgPSBhd2FpdCBwcm9taXNlO1xuICAgIGlmIChyZXN1bHQpIHRoaXMubWFzdGVycy5zZXQob3JnSWQsIHJlc3VsdCk7XG4gIH1cblxuICBwcml2YXRlIGFzeW5jIHJlc29sdmVBbmREZWNyeXB0KG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPHsga2V5OiBCdWZmZXI7IGtpZDogc3RyaW5nIH0gfCBudWxsPiB7XG4gICAgbGV0IGNmZyA9IHRoaXMuY29uZmlncy5nZXQob3JnSWQpO1xuICAgIGlmICghY2ZnKSB7XG4gICAgICBjb25zdCByZXNvbHZlZCA9IGF3YWl0IHRoaXMucmVzb2x2ZXIob3JnSWQpO1xuICAgICAgaWYgKCFyZXNvbHZlZCkgcmV0dXJuIG51bGw7IC8vIG5vIHBlci1vcmcgY29uZmlnIOKGkiBjYWxsZXIgdXNlcyBmYWxsYmFja1xuICAgICAgY2ZnID0gcmVzb2x2ZWQ7XG4gICAgICB0aGlzLmNvbmZpZ3Muc2V0KG9yZ0lkLCBjZmcpO1xuICAgIH1cbiAgICBjb25zdCBrZXkgPSBhd2FpdCB0aGlzLmZldGNoQW5kRGVjcnlwdChjZmcpO1xuICAgIHJldHVybiB7IGtleSwga2lkOiBjZmcua2V5SWQgfTtcbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2hBbmREZWNyeXB0KGNmZzogUGVyT3JnS21zQ29uZmlnKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgICByZXR1cm4ga21zRGVjcnlwdDMyKGNmZy5rZXlJZCwgY2ZnLmNpcGhlcnRleHRCYXNlNjQsIHRoaXMucmVnaW9uLCB0aGlzLmVuZHBvaW50KTtcbiAgfVxuXG4gIC8qKiBFdmljdCBhIGNhY2hlZCBwZXItb3JnIG1hc3Rlci4gVXNlIGFmdGVyIGEga2V5IHJvdGF0aW9uIHNvIHRoZSBuZXh0XG4gICAqICB0b3VjaCByZS1mZXRjaGVzIHRoZSBuZXcgd3JhcHBlZCBtYXN0ZXIgZnJvbSB0aGUgcmVzb2x2ZXIuICovXG4gIGV2aWN0KG9yZ0lkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLm1hc3RlcnMuZGVsZXRlKG9yZ0lkKTtcbiAgICB0aGlzLmNvbmZpZ3MuZGVsZXRlKG9yZ0lkKTtcbiAgfVxufVxuXG4vKipcbiAqIEVuY3J5cHQgYSBwbGFpbnRleHQgc3RyaW5nIGZvciBzdG9yYWdlLiBSZXR1cm5zIGFuIGBFbmNyeXB0ZWRCbG9iYCB0aGF0XG4gKiBjYW4gYmUgSlNPTi1zZXJpYWxpemVkIGludG8gdGhlIHVuZGVybHlpbmcgY29sdW1uIC8gTW9uZ28gZG9jdW1lbnQuXG4gKlxuICogRW1wdHkgc3RyaW5ncyByb3VuZC10cmlwIGFzIGBudWxsYCBzbyB0aGUgY2FsbGluZyBtb2RlbCBsYXllciBjYW4gdHJlYXRcbiAqIFwibm8gc2VjcmV0IHNldFwiIGlkZW50aWNhbGx5IHRvIFwiZmllbGQgYWJzZW50XCIuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBlbmNyeXB0U2VjcmV0KCBwbGFpbnRleHQ6IHN0cmluZyxcbiAgb3JnSWQ6IHN0cmluZyxcbiAgcHJvdmlkZXI6IEtleVByb3ZpZGVyID0gZ2V0RGVmYXVsdFByb3ZpZGVyKCksXG4pOiBFbmNyeXB0ZWRCbG9iIHtcbiAgaWYgKCFwbGFpbnRleHQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoJ1JlZnVzaW5nIHRvIGVuY3J5cHQgZW1wdHkgc3RyaW5nOyBjYWxsZXIgc2hvdWxkIHN0b3JlIG51bGwgaW5zdGVhZCcpO1xuICB9XG4gIGNvbnN0IGtleSA9IHByb3ZpZGVyLmRlcml2ZUtleShvcmdJZCk7XG4gIGNvbnN0IGl2ID0gcmFuZG9tQnl0ZXMoMTIpO1xuICBjb25zdCBjaXBoZXIgPSBjcmVhdGVDaXBoZXJpdignYWVzLTI1Ni1nY20nLCBrZXksIGl2KTtcbiAgY29uc3QgZW5jID0gQnVmZmVyLmNvbmNhdChbY2lwaGVyLnVwZGF0ZShwbGFpbnRleHQsICd1dGY4JyksIGNpcGhlci5maW5hbCgpXSk7XG4gIGNvbnN0IHRhZyA9IGNpcGhlci5nZXRBdXRoVGFnKCk7XG4gIC8vIFBlck9yZ0ttc0tleVByb3ZpZGVyIHRhZ3MgYmxvYnMgd2l0aCB0aGUgS01TIGtleSBpZCB1c2VkIHNvIHRoZVxuICAvLyBkZWNyeXB0IHBhdGggY2FuIHJlZnVzZSB0byBvcGVyYXRlIGlmIHRoZSBvcGVyYXRvciBsYXRlciBzd2FwcyBpbiBhXG4gIC8vIGRpZmZlcmVudCBwZXItb3JnIGNvbmZpZyAoYSBtaXNjb25maWd1cmVkIHN3YXAgc2hvdWxkbid0IHNpbGVudGx5XG4gIC8vIGFjY2VwdCBhIHN0YWxlIGJsb2IgaXQgY2FuJ3QgdmVyaWZ5IGFnYWluc3QgdGhlIHJpZ2h0IENNSykuXG4gIGNvbnN0IGtpZCA9IHByb3ZpZGVyLmtpZEZvcj8uKG9yZ0lkKTtcbiAgcmV0dXJuIHtcbiAgICBhbGc6ICdhZXMtMjU2LWdjbS12MScsXG4gICAgaXY6IGl2LnRvU3RyaW5nKCdiYXNlNjQnKSxcbiAgICAvLyBHQ00gdGFnIE1VU1QgdHJhdmVsIHdpdGggdGhlIGNpcGhlcnRleHQgb3IgYGRlY3J5cHRTZWNyZXRgIGNhbid0XG4gICAgLy8gdmVyaWZ5IGludGVncml0eSAgY29uY2F0ZW5hdGUgc28gdGhlIG9uLWRpc2sgc2hhcGUgaXMgb25lIGZpZWxkLlxuICAgIGNpcGhlcnRleHQ6IEJ1ZmZlci5jb25jYXQoW2VuYywgdGFnXSkudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIC4uLihraWQgIT09IHVuZGVmaW5lZCA/IHsga2lkIH0gOiB7fSksXG4gIH07XG59XG5cbi8qKlxuICogRGVjcnlwdCBhbiBgRW5jcnlwdGVkQmxvYmAgd3JpdHRlbiBieSBgZW5jcnlwdFNlY3JldGAuIFRocm93cyBvbiAqIC0gdW5rbm93biBgYWxnYCAoZm9yY2VzIGFuIGV4cGxpY2l0IG1pZ3JhdGlvbiB3aGVuIHRoZSBmb3JtYXQgY2hhbmdlcylcbiAqIC0gd3Jvbmcgb3JnSWQgKEhLREYgYmluZGluZyBtaXNtYXRjaCBmYWlscyB0aGUgYXV0aCB0YWcpXG4gKiAtIHRhbXBlcmVkIGNpcGhlcnRleHQgKEdDTSBhdXRoIHRhZyBjaGVjayBmYWlscylcbiAqXG4gKiBDYWxsZXJzIGhhbmRsZSB0aGUgdGhyb3cgIG1hc2tpbmcgdGhlIGZhaWx1cmUgYXMgYG51bGxgIHdvdWxkIGhpZGVcbiAqIHNpbGVudCBjb3JydXB0aW9uIC8gd3Jvbmctb3JnIHJlYWRzLlxuICovXG5leHBvcnQgZnVuY3Rpb24gZGVjcnlwdFNlY3JldCggYmxvYjogRW5jcnlwdGVkQmxvYixcbiAgb3JnSWQ6IHN0cmluZyxcbiAgcHJvdmlkZXI6IEtleVByb3ZpZGVyID0gZ2V0RGVmYXVsdFByb3ZpZGVyKCksXG4pOiBzdHJpbmcge1xuICBpZiAoYmxvYi5hbGcgIT09ICdhZXMtMjU2LWdjbS12MScpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFVuc3VwcG9ydGVkIGVuY3J5cHRpb24gYWxnOiAke2Jsb2IuYWxnfWApO1xuICB9XG4gIC8vIElmIGJvdGggdGhlIHByb3ZpZGVyIEFORCB0aGUgYmxvYiByZXBvcnQgYSBraWQsIHRoZXkgbXVzdCBtYXRjaC5cbiAgLy8gTWlzbWF0Y2ggdXN1YWxseSBtZWFucyBhbiBvcGVyYXRvciByb3RhdGVkL3JlcGxhY2VkIGFuIG9yZydzIEtNU1xuICAvLyBjb25maWcgYW5kIGlzIG5vdyByZWFkaW5nIGEgYmxvYiBlbmNyeXB0ZWQgdW5kZXIgdGhlIE9MRCBrZXkg4oCUXG4gIC8vIGZhaWxpbmcgbG91ZCBoZXJlIGJlYXRzIGxldHRpbmcgQUVTLUdDTSB0aHJvdyBhbiBvcGFxdWUgYXV0aC10YWcgZXJyb3IuXG4gIGNvbnN0IHByb3ZpZGVyS2lkID0gcHJvdmlkZXIua2lkRm9yPy4ob3JnSWQpO1xuICBpZiAocHJvdmlkZXJLaWQgIT09IHVuZGVmaW5lZCAmJiBibG9iLmtpZCAhPT0gdW5kZWZpbmVkICYmIHByb3ZpZGVyS2lkICE9PSBibG9iLmtpZCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgS01TIGtleSBpZCBtaXNtYXRjaDogYmxvYiB3YXMgZW5jcnlwdGVkIHVuZGVyICR7YmxvYi5raWR9LCBjdXJyZW50IHByb3ZpZGVyIHVzZXMgJHtwcm92aWRlcktpZH0gZm9yIG9yZyAke29yZ0lkfWApO1xuICB9XG4gIGNvbnN0IGtleSA9IHByb3ZpZGVyLmRlcml2ZUtleShvcmdJZCk7XG4gIGNvbnN0IGl2ID0gQnVmZmVyLmZyb20oYmxvYi5pdiwgJ2Jhc2U2NCcpO1xuICBjb25zdCBhbGwgPSBCdWZmZXIuZnJvbShibG9iLmNpcGhlcnRleHQsICdiYXNlNjQnKTtcbiAgLy8gU3BsaXQgb2ZmIHRoZSAxNi1ieXRlIGF1dGggdGFnIGFwcGVuZGVkIGluIGVuY3J5cHRTZWNyZXQuIEFueSB0YW1wZXJpbmdcbiAgLy8gIHRvIGVpdGhlciB0aGUgY2lwaGVydGV4dCBPUiB0aGUgdGFnICBjYXVzZXMgdGhlIG5leHQgYGZpbmFsKClgIHRvXG4gIC8vIHRocm93IHdpdGggXCJVbnN1cHBvcnRlZCBzdGF0ZSBvciB1bmFibGUgdG8gYXV0aGVudGljYXRlIGRhdGFcIi5cbiAgY29uc3QgdGFnID0gYWxsLnN1YmFycmF5KGFsbC5sZW5ndGggLSAxNik7XG4gIGNvbnN0IGVuYyA9IGFsbC5zdWJhcnJheSgwLCBhbGwubGVuZ3RoIC0gMTYpO1xuICBjb25zdCBkZWNpcGhlciA9IGNyZWF0ZURlY2lwaGVyaXYoJ2Flcy0yNTYtZ2NtJywga2V5LCBpdik7XG4gIGRlY2lwaGVyLnNldEF1dGhUYWcodGFnKTtcbiAgY29uc3QgZGVjID0gQnVmZmVyLmNvbmNhdChbZGVjaXBoZXIudXBkYXRlKGVuYyksIGRlY2lwaGVyLmZpbmFsKCldKTtcbiAgcmV0dXJuIGRlYy50b1N0cmluZygndXRmOCcpO1xufVxuXG4vKipcbiAqIFR5cGUgZ3VhcmQgIGhhbmR5IGZvciBtb2RlbCBsYXllcnMgdGhhdCBob2xkIGEgY29sdW1uIHdob3NlIHZhbHVlIG1heSBiZVxuICogZWl0aGVyIGEgY2xlYXItdGV4dCBzdHJpbmcgKGxlZ2FjeSAvIHVuZW5jcnlwdGVkKSBPUiBhbiBlbmNyeXB0ZWQgYmxvYlxuICogKHBvc3QtbWlncmF0aW9uKS4gTWl4ZWQgc3RhdGVzIGFyaXNlIG1pZC1taWdyYXRpb247IHRoZSBtb2RlbCBkZWNpZGVzXG4gKiB3aGF0IHRvIGRvIChkZWNyeXB0IG9uIHJlYWQsIGVuY3J5cHQgb24gbmV4dCB3cml0ZSkuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc0VuY3J5cHRlZEJsb2IodmFsdWU6IHVua25vd24pOiB2YWx1ZSBpcyBFbmNyeXB0ZWRCbG9iIHtcbiAgcmV0dXJuICggdHlwZW9mIHZhbHVlID09PSAnb2JqZWN0J1xuICAgICYmIHZhbHVlICE9PSBudWxsXG4gICAgJiYgKHZhbHVlIGFzIHsgYWxnPzogdW5rbm93biB9KS5hbGcgPT09ICdhZXMtMjU2LWdjbS12MSdcbiAgICAmJiB0eXBlb2YgKHZhbHVlIGFzIHsgaXY/OiB1bmtub3duIH0pLml2ID09PSAnc3RyaW5nJ1xuICAgICYmIHR5cGVvZiAodmFsdWUgYXMgeyBjaXBoZXJ0ZXh0PzogdW5rbm93biB9KS5jaXBoZXJ0ZXh0ID09PSAnc3RyaW5nJ1xuICApO1xufVxuIl19
|
|
424
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjcmV0LWVuY3J5cHRpb24uanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvc2VjcmV0LWVuY3J5cHRpb24udHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0Qzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0EwQkc7QUFFSCxPQUFPLEVBQUUsY0FBYyxFQUFFLGdCQUFnQixFQUFFLFFBQVEsRUFBRSxXQUFXLEVBQUUsTUFBTSxRQUFRLENBQUM7QUE2QmpGOzs7Ozs7O0dBT0c7QUFDSCxNQUFNLE9BQU8sY0FBYztJQUNSLFNBQVMsQ0FBUztJQUVuQyxZQUFZLGlCQUEwQjtRQUNwQyxNQUFNLEdBQUcsR0FBRyxpQkFBaUIsSUFBSSxPQUFPLENBQUMsR0FBRyxDQUFDLHFCQUFxQixDQUFDO1FBQ25FLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztZQUNULE1BQU0sSUFBSSxLQUFLLENBQUMsNkRBQTZELENBQUMsQ0FBQztRQUNqRixDQUFDO1FBQ0QsMEVBQTBFO1FBQzFFLHNEQUFzRDtRQUN0RCxNQUFNLE9BQU8sR0FBRyxHQUFHLENBQUMsTUFBTSxLQUFLLEVBQUUsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQztZQUMzRCxDQUFDLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsS0FBSyxDQUFDO1lBQ3pCLENBQUMsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxRQUFRLENBQUMsQ0FBQztRQUMvQixJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssRUFBRSxFQUFFLENBQUM7WUFDMUIsTUFBTSxJQUFJLEtBQUssQ0FBQyxzREFBc0QsT0FBTyxDQUFDLE1BQU0sR0FBRyxDQUFDLENBQUM7UUFDM0YsQ0FBQztRQUNELElBQUksQ0FBQyxTQUFTLEdBQUcsT0FBTyxDQUFDO0lBQzNCLENBQUM7SUFFRCxTQUFTLENBQUMsS0FBYTtRQUNy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QUcsQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLE1BQU0sR0FBRyxFQUFFLENBQUMsQ0FBQztJQUMxQyxNQUFNLEdBQUcsR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsTUFBTSxHQUFHLEVBQUUsQ0FBQyxDQUFDO0lBQzdDLE1BQU0sUUFBUSxHQUFHLGdCQUFnQixDQUFDLGFBQWEsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDMUQsUUFBUSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUN6QixNQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsRUFBRSxRQUFRLENBQUMsS0FBSyxFQUFFLENBQUMsQ0FBQyxDQUFDO0lBQ3BFLE9BQU8sR0FBRyxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBRUQ7Ozs7O0dBS0c7QUFDSCxNQUFNLFVBQVUsZUFBZSxDQUFDLEtBQWM7SUFDNUMsT0FBTyxDQUFFLE9BQU8sS0FBSyxLQUFLLFFBQVE7V0FDN0IsS0FBSyxLQUFLLElBQUk7V0FDYixLQUEyQixDQUFDLEdBQUcsS0FBSyxnQkFBZ0I7V0FDckQsT0FBUSxLQUEwQixDQUFDLEVBQUUsS0FBSyxRQUFRO1dBQ2xELE9BQVEsS0FBa0MsQ0FBQyxVQUFVLEtBQUssUUFBUSxDQUN0RSxDQUFDO0FBQ0osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8vIENvcHlyaWdodCAyMDI2IFBpcGVsaW5lIEJ1aWxkZXIgQ29udHJpYnV0b3JzXG4vLyBTUERYLUxpY2Vuc2UtSWRlbnRpZmllcjogQXBhY2hlLTIuMFxuXG4vKipcbiAqICBQZXItb3JnIGVudmVsb3BlIGVuY3J5cHRpb24gZm9yIHNlY3JldCBjb2x1bW5zLlxuICpcbiAqIFRvZGF5J3MgcG9zdHVyZSBmb3Igb3JnLXNjb3BlZCBzZWNyZXRzIChhaVByb3ZpZGVyS2V5cywgd2ViaG9vayBVUkxzLFxuICogcmVnaXN0cnkgY3JlZGVudGlhbHMpIGlzIGNsZWFyLXRleHQgaW4gTW9uZ28gLyBQb3N0Z3JlcyB3aXRoIGFwcC1sYXllclxuICogbWFza2luZyBvbiBvdXRwdXQuIFRoaXMgbW9kdWxlIGlzIHRoZSBlbmNyeXB0aW9uIHByaW1pdGl2ZSB0aGF0IGxldHMgdGhlXG4gKiBtb2RlbCBsYXllciBzd2FwIGNsZWFyLXRleHQgc3RyaW5ncyBmb3IgYEVuY3J5cHRlZEJsb2JgIHZhbHVlcyBhdCB3cml0ZVxuICogdGltZSBhbmQgZGVjcnlwdCBhdCByZWFkIHRpbWUuXG4gKlxuICogQ3J5cHRvZ3JhcGh5ICogLSBBRVMtMjU2LUdDTSAoYXV0aGVudGljYXRlZCBlbmNyeXB0aW9uKS5cbiAqIC0gUGVyLW9yZyBrZXkgZGVyaXZlZCB2aWEgSEtERi1TSEEyNTYobWFzdGVyS2V5LCBzYWx0PW9yZ0lkLCBpbmZvPSdzZWNyZXRzLXYxJykuXG4gKiBFYWNoIG9yZyBnZXRzIGEgdW5pcXVlIGtleSB3aXRob3V0IG9wZXJhdG9yIGtleS1tYW5hZ2VtZW50IGNlcmVtb255LlxuICogLSAxMi1ieXRlIElWIGdlbmVyYXRlZCBwZXIgZW5jcnlwdGlvbiB3aXRoIGBjcnlwdG8ucmFuZG9tQnl0ZXNgLlxuICogLSAxNi1ieXRlIGF1dGhlbnRpY2F0aW9uIHRhZyBjb25jYXRlbmF0ZWQgd2l0aCBjaXBoZXJ0ZXh0IChzdGFuZGFyZCBHQ00pLlxuICpcbiAqIE9wZXJhdG9yIGNvbmZpZ3VyYXRpb24gKiAtIGBTRUNSRVRfRU5DUllQVElPTl9LRVlgIGVudjogaGV4LSBvciBiYXNlNjQtZW5jb2RlZCAzMi1ieXRlIG1hc3RlciBrZXkuXG4gKiBSZXF1aXJlZCB3aGVuIGBlbmNyeXB0U2VjcmV0YC9gZGVjcnlwdFNlY3JldGAgYXJlIGNhbGxlZC4gTWlzc2luZyBrZXlcbiAqIHRocm93cyAgZW5jcnlwdGlvbiBpcyBmYWlsLWNsb3NlZDsgd2UgbmV2ZXIgc2lsZW50bHkgcm91bmQtdHJpcCBhXG4gKiBzZWNyZXQgYXMgcGxhaW50ZXh0LlxuICpcbiAqIEtNUyBtaWdyYXRpb24gcGF0aCAqIC0gVGhlIHR3byBleHBvcnRlZCBmdW5jdGlvbnMgdGFrZSBhIGBwcm92aWRlcmAgcGFyYW1ldGVyLiBUaGUgZGVmYXVsdFxuICogYEVudktleVByb3ZpZGVyYCBpbXBsZW1lbnRzIEhLREYgZGVyaXZhdGlvbi4gQSBmdXR1cmUgYEF3c0ttc1Byb3ZpZGVyYFxuICogcGx1Z3MgaW4gaGVyZTogaXQgY2FuIGNhbGwgS01TIGBFbmNyeXB0YCAvIGBEZWNyeXB0YCB0byB3cmFwIGEgREVLXG4gKiByYXRoZXIgdGhhbiBob2xkaW5nIGEgbWFzdGVyIGtleSBpbiBlbnYuIFRoZSBvbi1kaXNrIGJsb2Igc2hhcGVcbiAqIChgeyBhbGcsIGl2LCBjaXBoZXJ0ZXh0LCBraWQ/IH1gKSBpcyBmb3J3YXJkLWNvbXBhdGlibGUgIGBraWRgXG4gKiBjYXJyaWVzIHRoZSBLTVMga2V5IGlkIHdoZW4gdGhlIHByb3ZpZGVyIG5lZWRzIGl0LlxuICovXG5cbmltcG9ydCB7IGNyZWF0ZUNpcGhlcml2LCBjcmVhdGVEZWNpcGhlcml2LCBoa2RmU3luYywgcmFuZG9tQnl0ZXMgfSBmcm9tICdjcnlwdG8nO1xuXG4vKiogT24tZGlzayBzaGFwZSBvZiBhbiBlbmNyeXB0ZWQgc2VjcmV0LiBKU09OLXNlcmlhbGl6YWJsZS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgRW5jcnlwdGVkQmxvYiB7XG4gIC8qKiBBbGdvcml0aG0gdGFnLiBCdW1wIG9uIGZvcm1hdCBjaGFuZ2Ugc28gYSBmdXR1cmUgbWlncmF0aW9uIGNhbiBkZXRlY3Qgb2xkIGJsb2JzLiAqL1xuICBhbGc6ICdhZXMtMjU2LWdjbS12MSc7XG4gIC8qKiBCYXNlNjQtZW5jb2RlZCAxMi1ieXRlIElWLiAqL1xuICBpdjogc3RyaW5nO1xuICAvKiogQmFzZTY0LWVuY29kZWQgY2lwaGVydGV4dCArIDE2LWJ5dGUgYXV0aGVudGljYXRpb24gdGFnIGNvbmNhdGVuYXRlZC4gKi9cbiAgY2lwaGVydGV4dDogc3RyaW5nO1xuICAvKiogT3B0aW9uYWwga2V5IGlkICBwb3B1bGF0ZWQgYnkgS01TLWJhY2tlZCBwcm92aWRlcnMsIGlnbm9yZWQgYnkgdGhlIGVudiBwcm92aWRlci4gKi9cbiAga2lkPzogc3RyaW5nO1xufVxuXG4vKiogUGx1Z2dhYmxlIGtleSBzb3VyY2UuIEVudi1iYWNrZWQgYnkgZGVmYXVsdDsgS01TLWJhY2tlZCBhdmFpbGFibGUuICovXG5leHBvcnQgaW50ZXJmYWNlIEtleVByb3ZpZGVyIHtcbiAgLyoqIERlcml2ZSBhIDMyLWJ5dGUgc3ltbWV0cmljIGtleSBib3VuZCB0byBgb3JnSWRgLiAqL1xuICBkZXJpdmVLZXkob3JnSWQ6IHN0cmluZyk6IEJ1ZmZlcjtcbiAgLyoqIE9wdGlvbmFsIGFzeW5jIHZhcmlhbnQgZm9yIHByb3ZpZGVycyB0aGF0IG5lZWQgdG8gZG8gSS9PIChlLmcuXG4gICAqICBwZXItb3JnIEtNUyBsb29rdXAgdGhlIGZpcnN0IHRpbWUgYW4gb3JnIGlzIHNlZW4pLiBEZWZhdWx0XG4gICAqICBpbXBsZW1lbnRhdGlvbiBmb3J3YXJkcyB0byB0aGUgc3luYyBgZGVyaXZlS2V5YC4gKi9cbiAgZGVyaXZlS2V5QXN5bmM/KG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPEJ1ZmZlcj47XG4gIC8qKiBPcHRpb25hbCBLTVMta2V5LWlkIHRoaXMgcHJvdmlkZXIgdXNlZCBmb3IgYG9yZ0lkYC4gRW1iZWRkZWQgaW4gdGhlXG4gICAqICBgRW5jcnlwdGVkQmxvYi5raWRgIGZpZWxkIG9uIHdyaXRlIHNvIGRlY3J5cHQgY2FuIHZlcmlmeSB0aGUgcmlnaHRcbiAgICogIEtNUyBDTUsgaXMgYmVpbmcgdXNlZCAoZGVmZW5zZSBhZ2FpbnN0IGFuIGF0dGFja2VyIHdobyBzd2FwcyBhIGJsb2JcbiAgICogIGJldHdlZW4gb3JncykuIERlZmF1bHQgcmV0dXJucyB1bmRlZmluZWQgKGVudiBwcm92aWRlcikuICovXG4gIGtpZEZvcj8ob3JnSWQ6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbn1cblxuLyoqXG4gKiBEZWZhdWx0IHByb3ZpZGVyICBkZXJpdmVzIGEgcGVyLW9yZyBrZXkgZnJvbSBgU0VDUkVUX0VOQ1JZUFRJT05fS0VZYCB2aWFcbiAqIEhLREYtU0hBMjU2LiBTdWl0YWJsZSBmb3Igc2VsZi1ob3N0ZWQgLyBkZXYgd2hlcmUgb3BlcmF0b3JzIGRvbid0IGhhdmUgS01TLlxuICpcbiAqIEZhaWxzIGZhc3QgaWYgdGhlIGVudiBpcyBtaXNzaW5nIG9yIHRoZSBrZXkgaXMgdGhlIHdyb25nIGxlbmd0aCBzbyBtaXNjb25maWdcbiAqIHN1cmZhY2VzIGF0IGZpcnN0IHVzZSByYXRoZXIgdGhhbiBzaWxlbnRseSBmaW5nZXJwcmludGluZyBhbGwgd3JpdGVzIHdpdGhcbiAqIGEgZGVmYXVsdCB6ZXJvIGtleS5cbiAqL1xuZXhwb3J0IGNsYXNzIEVudktleVByb3ZpZGVyIGltcGxlbWVudHMgS2V5UHJvdmlkZXIge1xuICBwcml2YXRlIHJlYWRvbmx5IG1hc3RlcktleTogQnVmZmVyO1xuXG4gIGNvbnN0cnVjdG9yKG1hc3RlcktleU92ZXJyaWRlPzogc3RyaW5nKSB7XG4gICAgY29uc3QgcmF3ID0gbWFzdGVyS2V5T3ZlcnJpZGUgPz8gcHJvY2Vzcy5lbnYuU0VDUkVUX0VOQ1JZUFRJT05fS0VZO1xuICAgIGlmICghcmF3KSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoJ1NFQ1JFVF9FTkNSWVBUSU9OX0tFWSBlbnYgaXMgcmVxdWlyZWQgZm9yIHNlY3JldCBlbmNyeXB0aW9uJyk7XG4gICAgfVxuICAgIC8vIEFjY2VwdCBlaXRoZXIgaGV4ICg2NCBjaGFycykgb3IgYmFzZTY0ICg0NCBjaGFycyBpbmNsdWRpbmcgcGFkZGluZykgZm9yXG4gICAgLy8gb3BlcmF0b3IgY29udmVuaWVuY2UgIGJvdGggZGVjb2RlIHRvIGEgMzItYnl0ZSBrZXkuXG4gICAgY29uc3QgZGVjb2RlZCA9IHJhdy5sZW5ndGggPT09IDY0ICYmIC9eWzAtOWEtZl0rJC9pLnRlc3QocmF3KVxuICAgICAgPyBCdWZmZXIuZnJvbShyYXcsICdoZXgnKVxuICAgICAgOiBCdWZmZXIuZnJvbShyYXcsICdiYXNlNjQnKTtcbiAgICBpZiAoZGVjb2RlZC5sZW5ndGggIT09IDMyKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoYFNFQ1JFVF9FTkNSWVBUSU9OX0tFWSBtdXN0IGRlY29kZSB0byAzMiBieXRlcyAoZ290ICR7ZGVjb2RlZC5sZW5ndGh9KWApO1xuICAgIH1cbiAgICB0aGlzLm1hc3RlcktleSA9IGRlY29kZWQ7XG4gIH1cblxuICBkZXJpdmVLZXkob3JnSWQ6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgLy8gSEtERiBiaW5kcyB0aGUgbWFzdGVyIGtleSB0byB0aGUgb3JnIHNvIHR3byBvcmdzIGVuY3J5cHRpbmcgdGhlIHNhbWVcbiAgICAvLyBwbGFpbnRleHQgcHJvZHVjZSBkaWZmZXJlbnQgY2lwaGVydGV4dHMgIGtlZXBzIGEgc3RvbGVuIERCIHVuYWJsZSB0b1xuICAgIC8vIHRlbGwgd2hpY2ggb3JncyBzaGFyZSBzZWNyZXRzIHZpYSBjaXBoZXJ0ZXh0IGNvbXBhcmlzb24uXG4gICAgY29uc3QgZGVyaXZlZCA9IGhrZGZTeW5jKCAnc2hhMjU2JyxcbiAgICAgIHRoaXMubWFzdGVyS2V5LFxuICAgICAgQnVmZmVyLmZyb20ob3JnSWQsICd1dGY4JyksXG4gICAgICAnc2VjcmV0cy12MScsXG4gICAgICAzMixcbiAgICApO1xuICAgIC8vIGhrZGZTeW5jIHJldHVybnMgQXJyYXlCdWZmZXIgaW4gb2xkZXIgTm9kZSB0eXBpbmdzOyBub3JtYWxpemUgdG8gQnVmZmVyLlxuICAgIHJldHVybiBCdWZmZXIuZnJvbShkZXJpdmVkKTtcbiAgfVxufVxuXG4vKipcbiAqICBBV1MtS01TLWJhY2tlZCBLZXlQcm92aWRlci5cbiAqXG4gKiBUcmFkZS1vZmYgcGlja2VkOiBzdG9yZSBPTkUgbWFzdGVyIGtleSBlbmNyeXB0ZWQgdW5kZXIgYSBLTVMgQ01LOyBvblxuICogZmlyc3QgdXNlLCBjYWxsIGBrbXM6RGVjcnlwdGAgdG8gcmVjb3ZlciB0aGUgbWFzdGVyIGtleSBieXRlczsgSEtERi1cbiAqIGRlcml2ZSBwZXItb3JnIGZyb20gaXQgKHNhbWUgYXMgRW52S2V5UHJvdmlkZXIpLiBUaGUgcHJvY2VzcyB0aGVuIGhvbGRzXG4gKiB0aGUgcGxhaW50ZXh0IG1hc3RlciBrZXkgaW4gbWVtb3J5IHVudGlsIHJlc3RhcnQuXG4gKlxuICogUFJPUzogb25lIEtNUyBjYWxsIHBlciBwcm9jZXNzIGxpZmV0aW1lIChjaGVhcCwgbG93IHA5OSBpbXBhY3QpLFxuICogdGhlIGVuY3J5cHRlZC1tYXN0ZXIta2V5IGJsb2IgaXMgc2FmZSB0byBjb21taXQvbG9nL2NoZWNraW4sXG4gKiBLTVMgYXVkaXQgbG9nIHJlY29yZHMgd2hlbiB0aGUgbWFzdGVyIGlzIHJlY292ZXJlZC5cbiAqIENPTlM6IHByb2Nlc3MgbWVtb3J5IHN0aWxsIGhvbGRzIHRoZSBtYXN0ZXIga2V5ICBzYW1lIHBvc3R1cmUgYXNcbiAqIEVudktleVByb3ZpZGVyIG9uY2Ugd2FybWVkIHVwLiBGb3Igc3Ryb25nZXIgaXNvbGF0aW9uIGFuXG4gKiBvcGVyYXRvciBjYW4gbW92ZSB0byBwZXItcmVjb3JkIGVudmVsb3BlIGVuY3J5cHRpb24gKGNhbGxcbiAqIEdlbmVyYXRlRGF0YUtleSBvbiBldmVyeSB3cml0ZSk7IHRoYXQncyBhIGZvbGxvdy1vbi5cbiAqXG4gKiBPcGVyYXRvciBzZXR1cCAqIDEuIENyZWF0ZSBhIEtNUyBDTUsgd2l0aCBrZXkgcG9saWN5IGFsbG93aW5nIHRoZSBwbGF0Zm9ybSBzZXJ2aWNlJ3NcbiAqIElBTSByb2xlIGttczpEZWNyeXB0LlxuICogMi4gR2VuZXJhdGUgYSByYW5kb20gMzItYnl0ZSBtYXN0ZXIgKiBoZWFkIC1jIDMyIC9kZXYvdXJhbmRvbSB8IGJhc2U2NFxuICogMy4gV3JhcCBpdCB3aXRoIEtNUyAqIGF3cyBrbXMgZW5jcnlwdCAtLWtleS1pZCA8S0VZX0lEPiBcXFxuICogLS1wbGFpbnRleHQgPGJhc2U2NC1mcm9tLXN0ZXAtMj4gLS1vdXRwdXQgdGV4dCBcXFxuICogLS1xdWVyeSBDaXBoZXJ0ZXh0QmxvYlxuICogNC4gU2V0IG9uIHRoZSBzZXJ2aWNlICogU0VDUkVUX0VOQ1JZUFRJT05fS01TX0tFWV9JRD08S0VZX0lEPlxuICogU0VDUkVUX0VOQ1JZUFRJT05fS01TX0NJUEhFUlRFWFQ9PGJhc2U2NC1vdXRwdXQtb2Ytc3RlcC0zPlxuICogNS4gUGljayB0aGlzIHByb3ZpZGVyIHZpYSBgc2V0S2V5UHJvdmlkZXIobmV3IEttc0tleVByb3ZpZGVyKCkpYC5cbiAqXG4gKiBDb25zdHJ1Y3QgbGF6aWx5ICBpbXBvcnRpbmcgdGhlIEFXUyBTREsgaGFzIGEgbm9uLXRyaXZpYWwgY29sZC1zdGFydFxuICogY29zdCBzbyBlbnZzIHRoYXQgc3RheSBvbiBFbnZLZXlQcm92aWRlciBuZXZlciBsb2FkIGl0LlxuICovXG4vKipcbiAqIEtNUy1kZWNyeXB0IGEgYmFzZTY0IGNpcGhlcnRleHQgaW50byBhIDMyLWJ5dGUga2V5LiBTaGFyZWQgYnkgYm90aCBLTVMga2V5XG4gKiBwcm92aWRlcnMgKHNpbmdsZS1tYXN0ZXIgKyBwZXItb3JnKSwgd2hpY2ggcHJldmlvdXNseSBjb3B5LXBhc3RlZCB0aGlzXG4gKiBkeW5hbWljLWltcG9ydCArIERlY3J5cHQgKyBlbXB0eS9sZW5ndGggZ3VhcmRzLiBgQGF3cy1zZGsvY2xpZW50LWttc2AgaXNcbiAqIGR5bmFtaWNhbGx5IGltcG9ydGVkIHNvIEVudktleVByb3ZpZGVyLW9ubHkgZW52cyBuZXZlciBsb2FkIHRoZSBTREsuXG4gKi9cbmFzeW5jIGZ1bmN0aW9uIGttc0RlY3J5cHQzMihrZXlJZDogc3RyaW5nLCBjaXBoZXJ0ZXh0QjY0OiBzdHJpbmcsIHJlZ2lvbj86IHN0cmluZywgZW5kcG9pbnQ/OiBzdHJpbmcpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICBjb25zdCB7IEtNU0NsaWVudCwgRGVjcnlwdENvbW1hbmQgfSA9IGF3YWl0IGltcG9ydCgnQGF3cy1zZGsvY2xpZW50LWttcycpO1xuICBjb25zdCBjbGllbnQgPSBuZXcgS01TQ2xpZW50KHsgcmVnaW9uLCAuLi4oZW5kcG9pbnQgPyB7IGVuZHBvaW50IH0gOiB7fSkgfSk7XG4gIGNvbnN0IHJlc3AgPSBhd2FpdCBjbGllbnQuc2VuZChuZXcgRGVjcnlwdENvbW1hbmQoe1xuICAgIEtleUlkOiBrZXlJZCxcbiAgICBDaXBoZXJ0ZXh0QmxvYjogQnVmZmVyLmZyb20oY2lwaGVydGV4dEI2NCwgJ2Jhc2U2NCcpLFxuICB9KSk7XG4gIGlmICghcmVzcC5QbGFpbnRleHQpIHRocm93IG5ldyBFcnJvcihgS01TIERlY3J5cHQgcmV0dXJuZWQgYW4gZW1wdHkgUGxhaW50ZXh0IGZvciBrZXkgJHtrZXlJZH1gKTtcbiAgY29uc3QgYnVmID0gQnVmZmVyLmZyb20ocmVzcC5QbGFpbnRleHQpO1xuICBpZiAoYnVmLmxlbmd0aCAhPT0gMzIpIHRocm93IG5ldyBFcnJvcihgS01TIERlY3J5cHQgcmV0dXJuZWQgJHtidWYubGVuZ3RofS1ieXRlIGtleSBmb3IgJHtrZXlJZH07IGV4cGVjdGVkIDMyYCk7XG4gIHJldHVybiBidWY7XG59XG5cbmV4cG9ydCBjbGFzcyBLbXNLZXlQcm92aWRlciBpbXBsZW1lbnRzIEtleVByb3ZpZGVyIHtcbiAgcHJpdmF0ZSBtYXN0ZXJLZXlDYWNoZTogQnVmZmVyIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgcmVhZG9ubHkga2V5SWQ6IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBjaXBoZXJ0ZXh0QjY0OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVnaW9uPzogc3RyaW5nO1xuICBwcml2YXRlIHJlYWRvbmx5IGVuZHBvaW50Pzogc3RyaW5nO1xuICBwcml2YXRlIGRlY3J5cHRJbkZsaWdodDogUHJvbWlzZTxCdWZmZXI+IHwgbnVsbCA9IG51bGw7XG5cbiAgY29uc3RydWN0b3Iob3B0cz86IHsga2V5SWQ/OiBzdHJpbmc7IGNpcGhlcnRleHRCYXNlNjQ/OiBzdHJpbmc7IHJlZ2lvbj86IHN0cmluZzsgZW5kcG9pbnQ/OiBzdHJpbmcgfSkge1xuICAgIGNvbnN0IGtleUlkID0gb3B0cz8ua2V5SWQgPz8gcHJvY2Vzcy5lbnYuU0VDUkVUX0VOQ1JZUFRJT05fS01TX0tFWV9JRDtcbiAgICBjb25zdCBjaXBoZXJ0ZXh0ID0gb3B0cz8uY2lwaGVydGV4dEJhc2U2NCA/PyBwcm9jZXNzLmVudi5TRUNSRVRfRU5DUllQVElPTl9LTVNfQ0lQSEVSVEVYVDtcbiAgICBpZiAoIWtleUlkKSB0aHJvdyBuZXcgRXJyb3IoJ1NFQ1JFVF9FTkNSWVBUSU9OX0tNU19LRVlfSUQgZW52IGlzIHJlcXVpcmVkIGZvciBLbXNLZXlQcm92aWRlcicpO1xuICAgIGlmICghY2lwaGVydGV4dCkgdGhyb3cgbmV3IEVycm9yKCdTRUNSRVRfRU5DUllQVElPTl9LTVNfQ0lQSEVSVEVYVCBlbnYgaXMgcmVxdWlyZWQgZm9yIEttc0tleVByb3ZpZGVyJyk7XG4gICAgdGhpcy5rZXlJZCA9IGtleUlkO1xuICAgIHRoaXMuY2lwaGVydGV4dEI2NCA9IGNpcGhlcnRleHQ7XG4gICAgdGhpcy5yZWdpb24gPSBvcHRzPy5yZWdpb24gPz8gcHJvY2Vzcy5lbnYuQVdTX1JFR0lPTiA/PyBwcm9jZXNzLmVudi5BV1NfREVGQVVMVF9SRUdJT047XG4gICAgdGhpcy5lbmRwb2ludCA9IG9wdHM/LmVuZHBvaW50ID8/IHByb2Nlc3MuZW52LkFXU19LTVNfRU5EUE9JTlQ7XG4gIH1cblxuICBkZXJpdmVLZXkob3JnSWQ6IHN0cmluZyk6IEJ1ZmZlciB7XG4gICAgaWYgKCF0aGlzLm1hc3RlcktleUNhY2hlKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoICdLbXNLZXlQcm92aWRlciBpcyBub3Qgd2FybWVkIHVwLiBDYWxsIGBhd2FpdCBwcm92aWRlci53YXJtdXAoKWAgb25jZSBhdCBzZXJ2aWNlIHN0YXJ0dXAgYmVmb3JlIGFueSBlbmNyeXB0L2RlY3J5cHQuJyxcbiAgICAgICk7XG4gICAgfVxuICAgIGNvbnN0IGRlcml2ZWQgPSBoa2RmU3luYygnc2hhMjU2JywgdGhpcy5tYXN0ZXJLZXlDYWNoZSwgQnVmZmVyLmZyb20ob3JnSWQsICd1dGY4JyksICdzZWNyZXRzLXYxJywgMzIpO1xuICAgIHJldHVybiBCdWZmZXIuZnJvbShkZXJpdmVkKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFYWdlcmx5IHJlY292ZXIgdGhlIG1hc3RlciBrZXkgZnJvbSBLTVMgc28gc3Vic2VxdWVudCBgZGVyaXZlS2V5YFxuICAgKiBjYWxscyBhcmUgc3luYy4gSWRlbXBvdGVudCAgY29uY3VycmVudCBjYWxsZXJzIHNoYXJlIHRoZSBzYW1lIGluLVxuICAgKiBmbGlnaHQgcHJvbWlzZSBzbyB3ZSBkb24ndCBzcGF3biBtdWx0aXBsZSBLTVMgRGVjcnlwdCByZXF1ZXN0cyBhdFxuICAgKiBib290LiBUaHJvd3Mgb24gYW55IEtNUyBmYWlsdXJlOyB0aGUgY2FsbGVyICh0eXBpY2FsbHkgdGhlIHNlcnZpY2Unc1xuICAgKiBvbkJlZm9yZVN0YXJ0IGhvb2spIGRlY2lkZXMgd2hldGhlciB0byBmYWxsIGJhY2sgdG8gYSBkaWZmZXJlbnRcbiAgICogcHJvdmlkZXIgb3IgZmFpbC1zdGFydHVwLlxuICAgKi9cbiAgYXN5bmMgd2FybXVwKCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGlmICh0aGlzLm1hc3RlcktleUNhY2hlKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLmRlY3J5cHRJbkZsaWdodCkge1xuICAgICAgdGhpcy5kZWNyeXB0SW5GbGlnaHQgPSB0aGlzLmZldGNoQW5kRGVjcnlwdCgpO1xuICAgIH1cbiAgICB0cnkge1xuICAgICAgdGhpcy5tYXN0ZXJLZXlDYWNoZSA9IGF3YWl0IHRoaXMuZGVjcnlwdEluRmxpZ2h0O1xuICAgIH0gY2F0Y2ggKGVycikge1xuICAgICAgLy8gQSB0cmFuc2llbnQgS01TIGZhaWx1cmUgbXVzdCBub3QgcGVybWFuZW50bHkgcG9pc29uIHRoZSBwcm92aWRlcjogY2xlYXJcbiAgICAgIC8vIHRoZSByZWplY3RlZCBpbi1mbGlnaHQgcHJvbWlzZSBzbyBhIGxhdGVyIHdhcm11cCgpIHJldHJpZXMgaW5zdGVhZCBvZlxuICAgICAgLy8gcmUtYXdhaXRpbmcgdGhlIHNhbWUgcmVqZWN0aW9uIGZvcmV2ZXIgKG1hdGNoZXMgUGVyT3JnS21zS2V5UHJvdmlkZXIpLlxuICAgICAgdGhpcy5kZWNyeXB0SW5GbGlnaHQgPSBudWxsO1xuICAgICAgdGhyb3cgZXJyO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZmV0Y2hBbmREZWNyeXB0KCk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgcmV0dXJuIGttc0RlY3J5cHQzMih0aGlzLmtleUlkLCB0aGlzLmNpcGhlcnRleHRCNjQsIHRoaXMucmVnaW9uLCB0aGlzLmVuZHBvaW50KTtcbiAgfVxufVxuXG4vLyBMYXp5IHNpbmdsZXRvbiAgb3BlcmF0b3IgY29kZSBpbiBsb25nLWxpdmVkIHNlcnZpY2VzIHBheXMgdGhlIGVudi1wYXJzZVxuLy8gY29zdCBvbmNlLCBhbmQgdGVzdHMgY2FuIG1pbnQgdGhlaXIgb3duIHByb3ZpZGVyIHdpdGggYSBsaXRlcmFsIGtleS5cbmxldCBkZWZhdWx0UHJvdmlkZXI6IEtleVByb3ZpZGVyIHwgbnVsbCA9IG51bGw7XG5mdW5jdGlvbiBnZXREZWZhdWx0UHJvdmlkZXIoKTogS2V5UHJvdmlkZXIge1xuICBpZiAoIWRlZmF1bHRQcm92aWRlcikgZGVmYXVsdFByb3ZpZGVyID0gbmV3IEVudktleVByb3ZpZGVyKCk7XG4gIHJldHVybiBkZWZhdWx0UHJvdmlkZXI7XG59XG5cbi8qKiBSZWFkIHRoZSBhY3RpdmUgZGVmYXVsdCBwcm92aWRlci4gRXhwb3NlZCBzbyBzZXJ2aWNlIGNvZGUgKGUuZy4gYW5cbiAqICBhZG1pbiBlbmRwb2ludCB0aGF0IGp1c3Qgcm90YXRlZCBhbiBvcmcncyBLTVMgY29uZmlnKSBjYW4gY2FsbFxuICogIGBwcm92aWRlci5ldmljdChvcmdJZClgIG9uIHRoZSBsaXZlIHByb3ZpZGVyIHJhdGhlciB0aGFuIHJlY29uc3RydWN0aW5nXG4gKiAgb25lLiBUcmlnZ2VycyBsYXp5IGluaXRpYWxpemF0aW9uIG9uIGZpcnN0IGFjY2Vzcywgc2FtZSBhcyB0aGUgaW50ZXJuYWxcbiAqICBjYWxsZXJzIGJlbG93LiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERlZmF1bHRLZXlQcm92aWRlcigpOiBLZXlQcm92aWRlciB7XG4gIHJldHVybiBnZXREZWZhdWx0UHJvdmlkZXIoKTtcbn1cblxuLyoqIFJlc2V0IHRoZSBjYWNoZWQgZGVmYXVsdCBwcm92aWRlciAgZm9yIHRlc3RzIHRoYXQgbXV0YXRlIGBwcm9jZXNzLmVudmAuICovXG5leHBvcnQgZnVuY3Rpb24gcmVzZXREZWZhdWx0S2V5UHJvdmlkZXIoKTogdm9pZCB7IGRlZmF1bHRQcm92aWRlciA9IG51bGw7IH1cblxuLyoqIFJlcGxhY2UgdGhlIGRlZmF1bHQgcHJvdmlkZXIgIHNlcnZpY2VzIHRoYXQgb3B0IGludG8gS01TIGNhbGwgdGhpc1xuICogb25jZSBhdCBzdGFydHVwIHdpdGggYSB3YXJtZWQtdXAgYEttc0tleVByb3ZpZGVyYC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRLZXlQcm92aWRlcihwcm92aWRlcjogS2V5UHJvdmlkZXIpOiB2b2lkIHsgZGVmYXVsdFByb3ZpZGVyID0gcHJvdmlkZXI7IH1cblxuLyoqIFBlci1vcmcgS01TIGNvbmZpZyB0aGUgb3BlcmF0b3Igc3VwcGxpZXMuIFRoZSBga2V5SWRgIGlkZW50aWZpZXMgdGhlXG4gKiAgS01TIENNSyB0byBjYWxsIERlY3J5cHQgb247IGBjaXBoZXJ0ZXh0QmFzZTY0YCBpcyB0aGUgd3JhcHBlZCAzMi1ieXRlXG4gKiAgbWFzdGVyIGdlbmVyYXRlZCBieSBgYXdzIGttcyBlbmNyeXB0YCBhZ2FpbnN0IHRoYXQga2V5LiAqL1xuZXhwb3J0IGludGVyZmFjZSBQZXJPcmdLbXNDb25maWcge1xuICBrZXlJZDogc3RyaW5nO1xuICBjaXBoZXJ0ZXh0QmFzZTY0OiBzdHJpbmc7XG59XG5cbi8qKlxuICogQXN5bmMgcmVzb2x2ZXIgdGhhdCBtYXBzIGFuIG9yZyBpZCB0byBpdHMgS01TIGNvbmZpZy4gUmV0dXJucyBgbnVsbGAgd2hlblxuICogdGhlIG9yZyBoYXMgbm8gcGVyLW9yZyBjb25maWcg4oCUIHRoZSBwcm92aWRlciB0aGVuIGZhbGxzIGJhY2sgdG8gdGhlXG4gKiBgZmFsbGJhY2tgIHByb3ZpZGVyIHN1cHBsaWVkIGF0IGNvbnN0cnVjdGlvbiAodXN1YWxseSBhbiBFbnZLZXlQcm92aWRlclxuICogb3IgYSBkZWZhdWx0IEttc0tleVByb3ZpZGVyKS5cbiAqL1xuZXhwb3J0IHR5cGUgUGVyT3JnS21zUmVzb2x2ZXIgPSAob3JnSWQ6IHN0cmluZykgPT4gUHJvbWlzZTxQZXJPcmdLbXNDb25maWcgfCBudWxsPjtcblxuLyoqXG4gKiBQZXItb3JnIEtNUy1iYWNrZWQgS2V5UHJvdmlkZXIuIFRoZSBibGFzdCByYWRpdXMgb2YgYSBLTVMga2V5IGNvbXByb21pc2VcbiAqIGlzIG9uZSBvcmcgaW5zdGVhZCBvZiBldmVyeSBvcmcgdW5kZXIgYSBzaGFyZWQgbWFzdGVyLlxuICpcbiAqIEVhY2ggb3JnIGhhcyBpdHMgb3duIEtNUyBDTUsgKyBpdHMgb3duIHdyYXBwZWQgbWFzdGVyIChzdG9yZWQgaW4gTW9uZ29cbiAqIHZpYSB0aGUgb3BlcmF0b3IncyBzZXR1cCBzY3JpcHQpLiBPbiBmaXJzdCBlbmNyeXB0L2RlY3J5cHQgZm9yIGFuIG9yZyxcbiAqIHRoZSBwcm92aWRlcjpcbiAqICAgMS4gQ2FsbHMgdGhlIHJlc29sdmVyIHRvIGZldGNoIHRoZSBvcmcncyBLTVMgY29uZmlnLlxuICogICAyLiBDYWxscyBga21zOkRlY3J5cHRgIHRvIHJlY292ZXIgdGhlIDMyLWJ5dGUgbWFzdGVyLlxuICogICAzLiBDYWNoZXMgdGhlIHJlY292ZXJlZCBtYXN0ZXIgaW4tbWVtb3J5IGZvciB0aGUgcHJvY2VzcyBsaWZldGltZS5cbiAqICAgNC4gSEtERi1kZXJpdmVzIHBlci1jYWxsIGZyb20gdGhhdCBtYXN0ZXIgKyB0aGUgb3JnIGlkIHNhbHQuXG4gKlxuICogQmxvYnMgZW5jcnlwdGVkIGJ5IHRoaXMgcHJvdmlkZXIgY2FycnkgYGtpZCA9IDxrbXMta2V5LWlkPmAgc28gdGhlXG4gKiBkZWNyeXB0IHBhdGggZGV0ZWN0cyBhIHN0YWxlIGNvbmZpZyAob3BlcmF0b3Igcm90YXRlZCB0aGUga2V5IGJ1dFxuICogZXhpc3Rpbmcgcm93cyB3ZXJlbid0IHJlLWVuY3J5cHRlZCkgQkVGT1JFIEFFUy1HQ00gdGhyb3dzIGFuIG9wYXF1ZVxuICogYXV0aGVudGljYXRpb24tdGFnIGVycm9yLlxuICpcbiAqIE9yZ3Mgd2l0aG91dCBwZXItb3JnIGNvbmZpZyBmYWxsIHRocm91Z2ggdG8gdGhlIGBmYWxsYmFja2AgcHJvdmlkZXIg4oCUXG4gKiBtaXhlZC1tb2RlIGRlcGxveW1lbnRzIHdoZXJlIHNvbWUgb3JncyBoYXZlIEtNUyBpc29sYXRpb24gYW5kIG90aGVyc1xuICogc3RheSBvbiB0aGUgc2hhcmVkIG1hc3RlciBhcmUgZXhwbGljaXRseSBzdXBwb3J0ZWQuXG4gKi9cbmV4cG9ydCBjbGFzcyBQZXJPcmdLbXNLZXlQcm92aWRlciBpbXBsZW1lbnRzIEtleVByb3ZpZGVyIHtcbiAgLyoqIENhY2hlZCBwZXItb3JnIG1hc3RlciBrZXlzLCBrZXllZCBieSBvcmdJZC4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBtYXN0ZXJzID0gbmV3IE1hcDxzdHJpbmcsIHsga2V5OiBCdWZmZXI7IGtpZDogc3RyaW5nIH0+KCk7XG4gIC8qKiBSZXNvbHZlZCBwZXItb3JnIGNvbmZpZ3MgY2FjaGVkIGZvciB0aGUgcHJvY2VzcyBsaWZldGltZS4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBjb25maWdzID0gbmV3IE1hcDxzdHJpbmcsIFBlck9yZ0ttc0NvbmZpZz4oKTtcbiAgLyoqIEluLWZsaWdodCByZXNvbHZlciBwcm9taXNlcyBzbyBjb25jdXJyZW50IGZpcnN0LXRvdWNoIGNhbGxlcnMgc2hhcmUgb25lIEtNUyBEZWNyeXB0LlxuICAgKiAgUmVzb2x2ZXMgdG8gYG51bGxgIGZvciBvcmdzIHdpdGggbm8gcGVyLW9yZyBjb25maWcg4oCUIGNhbGxlciB0cmVhdHMgbnVsbCBhc1xuICAgKiAgXCJmYWxsIHRocm91Z2ggdG8gdGhlIGZhbGxiYWNrIHByb3ZpZGVyXCIsIHNhbWUgYXMgYSBjb2xkIGNhY2hlIG1pc3MuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgaW5GbGlnaHQgPSBuZXcgTWFwPHN0cmluZywgUHJvbWlzZTx7IGtleTogQnVmZmVyOyBraWQ6IHN0cmluZyB9IHwgbnVsbD4+KCk7XG4gIC8qKiBPcmdzIHRoZSByZXNvbHZlciBoYXMgUFJPVkVOIGhhdmUgbm8gcGVyLW9yZyBjb25maWcg4oCUIHRoZSBmYWxsYmFjayBwcm92aWRlclxuICAgKiAgaXMgdGhlIGNvcnJlY3QgYW5zd2VyIGZvciB0aGVzZSwgYW5kIGBkZXJpdmVLZXlgIG1heSBzZXJ2ZSB0aGVtXG4gICAqICBzeW5jaHJvbm91c2x5LiBEaXN0aW5jdCBmcm9tIFwibm90IHlldCByZXNvbHZlZFwiLCB3aGljaCBtdXN0IG5vdCBndWVzcy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSByZXNvbHZlZE5vUGVyT3JnQ29uZmlnID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIC8qKiBQcm92aWRlciB1c2VkIGZvciBvcmdzIHRoYXQgaGF2ZSBubyBwZXItb3JnIGNvbmZpZy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBmYWxsYmFjazogS2V5UHJvdmlkZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVzb2x2ZXI6IFBlck9yZ0ttc1Jlc29sdmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlZ2lvbj86IHN0cmluZztcbiAgcHJpdmF0ZSByZWFkb25seSBlbmRwb2ludD86IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihvcHRzOiB7XG4gICAgcmVzb2x2ZXI6IFBlck9yZ0ttc1Jlc29sdmVyO1xuICAgIGZhbGxiYWNrOiBLZXlQcm92aWRlcjtcbiAgICByZWdpb24/OiBzdHJpbmc7XG4gICAgZW5kcG9pbnQ/OiBzdHJpbmc7XG4gIH0pIHtcbiAgICB0aGlzLnJlc29sdmVyID0gb3B0cy5yZXNvbHZlcjtcbiAgICB0aGlzLmZhbGxiYWNrID0gb3B0cy5mYWxsYmFjaztcbiAgICB0aGlzLnJlZ2lvbiA9IG9wdHMucmVnaW9uID8/IHByb2Nlc3MuZW52LkFXU19SRUdJT04gPz8gcHJvY2Vzcy5lbnYuQVdTX0RFRkFVTFRfUkVHSU9OO1xuICAgIHRoaXMuZW5kcG9pbnQgPSBvcHRzLmVuZHBvaW50ID8/IHByb2Nlc3MuZW52LkFXU19LTVNfRU5EUE9JTlQ7XG4gIH1cblxuICAvKipcbiAgICogU3luYyBkZXJpdmUuIE9ubHkgY29ycmVjdCBmb3IgYW4gb3JnIHdob3NlIGNvbmZpZyBoYXMgYWxyZWFkeSBiZWVuXG4gICAqIFJFU09MVkVEIOKAlCBlaXRoZXIgaXQgaGFzIGEgcGVyLW9yZyBtYXN0ZXIgKHVzZSBpdCkgb3IgaXQgcHJvdmFibHkgaGFzIG5vXG4gICAqIHBlci1vcmcgY29uZmlnICh0aGUgZmFsbGJhY2sgaXMgdGhlbiB0aGUgcmlnaHQgYW5zd2VyKS5cbiAgICpcbiAgICogRm9yIGFuIFVOUkVTT0xWRUQgb3JnIHRoaXMgVEhST1dTIHJhdGhlciB0aGFuIGd1ZXNzaW5nLiBJdCB1c2VkIHRvIGZhbGxcbiAgICogdGhyb3VnaCB0byB0aGUgZmFsbGJhY2ssIHdoaWNoIHNpbGVudGx5IGVuY3J5cHRlZCB0aGF0IG9yZydzIHNlY3JldHMgdW5kZXJcbiAgICogdGhlIFNIQVJFRCBtYXN0ZXIgYW5kIOKAlCBiZWNhdXNlIGBraWRGb3JgIGFsc28gcmV0dXJuZWQgdW5kZWZpbmVkLCBzbyB0aGVcbiAgICogYm90aC1raWRzLXByZXNlbnQgbWlzbWF0Y2ggZ3VhcmQgY291bGQgbmV2ZXIgZmlyZSDigJQgbGVmdCB0aGVtIHBlcm1hbmVudGx5XG4gICAqIHVuZGVjcnlwdGFibGUgb25jZSB0aGUgb3JnIHdhcm1lZDogYGRlY2lwaGVyLmZpbmFsKClgIHRoZW4gdGhyZXcgYW4gb3BhcXVlXG4gICAqIGF1dGgtdGFnIGVycm9yIHdpdGggbm8gZGlhZ25vc3RpYy4gRmFpbGluZyBsb3VkIGhlcmUgbWF0Y2hlc1xuICAgKiBgS21zS2V5UHJvdmlkZXIuZGVyaXZlS2V5YCwgd2hpY2ggaGFzIGFsd2F5cyByZWZ1c2VkIHRvIHdvcmsgY29sZC5cbiAgICpcbiAgICogYGVuY3J5cHRTZWNyZXRgL2BkZWNyeXB0U2VjcmV0YCBhcmUgYXN5bmMgYW5kIGF3YWl0IGBkZXJpdmVLZXlBc3luY2AsIHNvXG4gICAqIHRoZXkgcmVzb2x2ZSB0aGUgb3JnIGZpcnN0IGFuZCBuZXZlciBoaXQgdGhpcyBwYXRoOyBpdCBpcyB0aGUgYmFja3N0b3AgZm9yXG4gICAqIGEgY2FsbGVyIHRoYXQgcmVhY2hlcyBmb3IgdGhlIHN5bmMgQVBJIGRpcmVjdGx5LlxuICAgKi9cbiAgZGVyaXZlS2V5KG9yZ0lkOiBzdHJpbmcpOiBCdWZmZXIge1xuICAgIGNvbnN0IGNhY2hlZCA9IHRoaXMubWFzdGVycy5nZXQob3JnSWQpO1xuICAgIGlmICghY2FjaGVkKSB7XG4gICAgICBpZiAodGhpcy5yZXNvbHZlZE5vUGVyT3JnQ29uZmlnLmhhcyhvcmdJZCkpIHJldHVybiB0aGlzLmZhbGxiYWNrLmRlcml2ZUtleShvcmdJZCk7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoIGBQZXJPcmdLbXNLZXlQcm92aWRlciBoYXMgbm90IHJlc29sdmVkIG9yZyAke29yZ0lkfS4gYFxuICAgICAgICArICdDYWxsIGBhd2FpdCBwcm92aWRlci5lbnN1cmVXYXJtZWQob3JnSWQpYCAob3IgdXNlIHRoZSBhc3luYyBlbmNyeXB0U2VjcmV0L2RlY3J5cHRTZWNyZXQpICdcbiAgICAgICAgKyAnYmVmb3JlIGRlcml2aW5nIGEga2V5IOKAlCBndWVzc2luZyB0aGUgc2hhcmVkIG1hc3RlciB3b3VsZCB3cml0ZSBzZWNyZXRzIHRoYXQgY2Fubm90IGJlIGRlY3J5cHRlZCBsYXRlci4nLFxuICAgICAgKTtcbiAgICB9XG4gICAgY29uc3QgZGVyaXZlZCA9IGhrZGZTeW5jKCdzaGEyNTYnLCBjYWNoZWQua2V5LCBCdWZmZXIuZnJvbShvcmdJZCwgJ3V0ZjgnKSwgJ3NlY3JldHMtdjEnLCAzMik7XG4gICAgcmV0dXJuIEJ1ZmZlci5mcm9tKGRlcml2ZWQpO1xuICB9XG5cbiAgYXN5bmMgZGVyaXZlS2V5QXN5bmMob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8QnVmZmVyPiB7XG4gICAgYXdhaXQgdGhpcy5lbnN1cmVXYXJtZWQob3JnSWQpO1xuICAgIHJldHVybiB0aGlzLmRlcml2ZUtleShvcmdJZCk7XG4gIH1cblxuICBraWRGb3Iob3JnSWQ6IHN0cmluZyk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgY2FjaGVkID0gdGhpcy5tYXN0ZXJzLmdldChvcmdJZCk7XG4gICAgaWYgKGNhY2hlZCkgcmV0dXJuIGNhY2hlZC5raWQ7XG4gICAgLy8gT25seSBzcGVhayBmb3IgYW4gb3JnIHdob3NlIGNvbmZpZyBpcyByZXNvbHZlZDsgYW4gdW5yZXNvbHZlZCBvcmcgaGFzIG5vXG4gICAgLy8gbWVhbmluZ2Z1bCBraWQsIGFuZCBjbGFpbWluZyBvbmUgd291bGQgZGVmZWF0IHRoZSBtaXNtYXRjaCBndWFyZC5cbiAgICBpZiAodGhpcy5yZXNvbHZlZE5vUGVyT3JnQ29uZmlnLmhhcyhvcmdJZCkpIHJldHVybiB0aGlzLmZhbGxiYWNrLmtpZEZvcj8uKG9yZ0lkKTtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlc29sdmUgdGhlIG9yZydzIEtNUyBjb25maWcsIGNhbGwgRGVjcnlwdCwgY2FjaGUgdGhlIG1hc3Rlci4gU3Vic2VxdWVudFxuICAgKiBjYWxscyBmb3IgdGhlIHNhbWUgb3JnIGFyZSBuby1vcHMuIENvbmN1cnJlbnQgY2FsbGVycyBzaGFyZSB0aGUgaW4tZmxpZ2h0XG4gICAqIERlY3J5cHQgcHJvbWlzZS5cbiAgICpcbiAgICogUmV0dXJucyBzaWxlbnRseSB3aGVuIHRoZSBvcmcgaGFzIG5vIHBlci1vcmcgY29uZmlnIOKAlCB0aGUgZmFsbGJhY2tcbiAgICogcHJvdmlkZXIgaGFuZGxlcyB0aG9zZSBvcmdzLlxuICAgKi9cbiAgYXN5bmMgZW5zdXJlV2FybWVkKG9yZ0lkOiBzdHJpbmcpOiBQcm9taXNlPHZvaWQ+IHtcbiAgICBpZiAodGhpcy5tYXN0ZXJzLmhhcyhvcmdJZCkpIHJldHVybjtcbiAgICAvLyBJbnN0YWxsIHRoZSBpbi1mbGlnaHQgcHJvbWlzZSBTWU5DSFJPTk9VU0xZIGJlZm9yZSB5aWVsZGluZyBzbyBjb25jdXJyZW50XG4gICAgLy8gY2FsbGVycyBmaW5kIGl0IG9uIHRoZSBzZWNvbmQtYW5kLWxhdGVyIHBhc3Nlcy4gQXdhaXRpbmcgdGhlIHJlc29sdmVyXG4gICAgLy8gYmVmb3JlIHBvcHVsYXRpbmcgdGhlIG1hcCBpcyB0aGUgYnVnIHRoYXQgbGV0cyBhIFByb21pc2UuYWxsIG9mIDNcbiAgICAvLyBjYWxsZXJzIGZpcmUgMyBLTVMgRGVjcnlwdHMuXG4gICAgbGV0IHByb21pc2UgPSB0aGlzLmluRmxpZ2h0LmdldChvcmdJZCk7XG4gICAgaWYgKCFwcm9taXNlKSB7XG4gICAgICBwcm9taXNlID0gdGhpcy5yZXNvbHZlQW5kRGVjcnlwdChvcmdJZCk7XG4gICAgICB0aGlzLmluRmxpZ2h0LnNldChvcmdJZCwgcHJvbWlzZSk7XG4gICAgICB2b2lkIHByb21pc2UuZmluYWxseSgoKSA9PiB7IGlmICh0aGlzLmluRmxpZ2h0LmdldChvcmdJZCkgPT09IHByb21pc2UpIHRoaXMuaW5GbGlnaHQuZGVsZXRlKG9yZ0lkKTsgfSk7XG4gICAgfVxuICAgIGNvbnN0IHJlc3VsdCA9IGF3YWl0IHByb21pc2U7XG4gICAgaWYgKHJlc3VsdCkgdGhpcy5tYXN0ZXJzLnNldChvcmdJZCwgcmVzdWx0KTtcbiAgICAvLyBSZW1lbWJlciB0aGUgTkVHQVRJVkUgb3V0Y29tZSB0b28sIHNvIHRoZSBzeW5jIGBkZXJpdmVLZXlgIGNhbiB0ZWxsXG4gICAgLy8gXCJubyBwZXItb3JnIGNvbmZpZywgZmFsbGJhY2sgaXMgY29ycmVjdFwiIGZyb20gXCJub3QgcmVzb2x2ZWQgeWV0XCIuXG4gICAgZWxzZSB0aGlzLnJlc29sdmVkTm9QZXJPcmdDb25maWcuYWRkKG9yZ0lkKTtcbiAgfVxuXG4gIHByaXZhdGUgYXN5bmMgcmVzb2x2ZUFuZERlY3J5cHQob3JnSWQ6IHN0cmluZyk6IFByb21pc2U8eyBrZXk6IEJ1ZmZlcjsga2lkOiBzdHJpbmcgfSB8IG51bGw+IHtcbiAgICBsZXQgY2ZnID0gdGhpcy5jb25maWdzLmdldChvcmdJZCk7XG4gICAgaWYgKCFjZmcpIHtcbiAgICAgIGNvbnN0IHJlc29sdmVkID0gYXdhaXQgdGhpcy5yZXNvbHZlcihvcmdJZCk7XG4gICAgICBpZiAoIXJlc29sdmVkKSByZXR1cm4gbnVsbDsgLy8gbm8gcGVyLW9yZyBjb25maWcg4oaSIGNhbGxlciB1c2VzIGZhbGxiYWNrXG4gICAgICBjZmcgPSByZXNvbHZlZDtcbiAgICAgIHRoaXMuY29uZmlncy5zZXQob3JnSWQsIGNmZyk7XG4gICAgfVxuICAgIGNvbnN0IGtleSA9IGF3YWl0IHRoaXMuZmV0Y2hBbmREZWNyeXB0KGNmZyk7XG4gICAgcmV0dXJuIHsga2V5LCBraWQ6IGNmZy5rZXlJZCB9O1xuICB9XG5cbiAgcHJpdmF0ZSBmZXRjaEFuZERlY3J5cHQoY2ZnOiBQZXJPcmdLbXNDb25maWcpOiBQcm9taXNlPEJ1ZmZlcj4ge1xuICAgIHJldHVybiBrbXNEZWNyeXB0MzIoY2ZnLmtleUlkLCBjZmcuY2lwaGVydGV4dEJhc2U2NCwgdGhpcy5yZWdpb24sIHRoaXMuZW5kcG9pbnQpO1xuICB9XG5cbiAgLyoqIEV2aWN0IGEgY2FjaGVkIHBlci1vcmcgbWFzdGVyLiBVc2UgYWZ0ZXIgYSBrZXkgcm90YXRpb24gc28gdGhlIG5leHRcbiAgICogIHRvdWNoIHJlLWZldGNoZXMgdGhlIG5ldyB3cmFwcGVkIG1hc3RlciBmcm9tIHRoZSByZXNvbHZlci4gKi9cbiAgZXZpY3Qob3JnSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMubWFzdGVycy5kZWxldGUob3JnSWQpO1xuICAgIHRoaXMuY29uZmlncy5kZWxldGUob3JnSWQpO1xuICAgIC8vIEFsc28gZm9yZ2V0IGEgTkVHQVRJVkUgcmVzb2x1dGlvbiwgb3IgYW4gb3JnIHRoYXQgZ2FpbnMgYSBwZXItb3JnIGNvbmZpZ1xuICAgIC8vIGFmdGVyIGJlaW5nIHJlc29sdmVkIGFzIFwibm8gY29uZmlnXCIgd291bGQga2VlcCB1c2luZyB0aGUgc2hhcmVkIG1hc3Rlci5cbiAgICB0aGlzLnJlc29sdmVkTm9QZXJPcmdDb25maWcuZGVsZXRlKG9yZ0lkKTtcbiAgfVxufVxuXG4vKipcbiAqIERlcml2ZSB0aGUga2V5IGZvciBgb3JnSWRgLCBnaXZpbmcgdGhlIHByb3ZpZGVyIGEgY2hhbmNlIHRvIGRvIEkvTyBmaXJzdC5cbiAqXG4gKiBUaGlzIGlzIHdoeSBgZW5jcnlwdFNlY3JldGAvYGRlY3J5cHRTZWNyZXRgIGFyZSBhc3luYzogYFBlck9yZ0ttc0tleVByb3ZpZGVyYFxuICogbmVlZHMgb25lIEtNUyBEZWNyeXB0IHRoZSBmaXJzdCB0aW1lIGl0IHNlZXMgYW4gb3JnLCBhbmQgZGVyaXZpbmdcbiAqIHN5bmNocm9ub3VzbHkgYmVmb3JlIHRoYXQgcmVzb2x2ZXMgd291bGQgc2lsZW50bHkgZmFsbCBiYWNrIHRvIHRoZSBzaGFyZWRcbiAqIG1hc3RlciBhbmQgcHJvZHVjZSBzZWNyZXRzIHRoYXQgY2Fubm90IGJlIGRlY3J5cHRlZCBhZnRlcndhcmRzLlxuICovXG5hc3luYyBmdW5jdGlvbiBkZXJpdmVLZXlGb3IocHJvdmlkZXI6IEtleVByb3ZpZGVyLCBvcmdJZDogc3RyaW5nKTogUHJvbWlzZTxCdWZmZXI+IHtcbiAgcmV0dXJuIHByb3ZpZGVyLmRlcml2ZUtleUFzeW5jID8gcHJvdmlkZXIuZGVyaXZlS2V5QXN5bmMob3JnSWQpIDogcHJvdmlkZXIuZGVyaXZlS2V5KG9yZ0lkKTtcbn1cblxuLyoqXG4gKiBFbmNyeXB0IGEgcGxhaW50ZXh0IHN0cmluZyBmb3Igc3RvcmFnZS4gUmV0dXJucyBhbiBgRW5jcnlwdGVkQmxvYmAgdGhhdFxuICogY2FuIGJlIEpTT04tc2VyaWFsaXplZCBpbnRvIHRoZSB1bmRlcmx5aW5nIGNvbHVtbiAvIE1vbmdvIGRvY3VtZW50LlxuICpcbiAqIEVtcHR5IHN0cmluZ3Mgcm91bmQtdHJpcCBhcyBgbnVsbGAgc28gdGhlIGNhbGxpbmcgbW9kZWwgbGF5ZXIgY2FuIHRyZWF0XG4gKiBcIm5vIHNlY3JldCBzZXRcIiBpZGVudGljYWxseSB0byBcImZpZWxkIGFic2VudFwiLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5jcnlwdFNlY3JldCggcGxhaW50ZXh0OiBzdHJpbmcsXG4gIG9yZ0lkOiBzdHJpbmcsXG4gIHByb3ZpZGVyOiBLZXlQcm92aWRlciA9IGdldERlZmF1bHRQcm92aWRlcigpLFxuKTogUHJvbWlzZTxFbmNyeXB0ZWRCbG9iPiB7XG4gIGlmICghcGxhaW50ZXh0KSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdSZWZ1c2luZyB0byBlbmNyeXB0IGVtcHR5IHN0cmluZzsgY2FsbGVyIHNob3VsZCBzdG9yZSBudWxsIGluc3RlYWQnKTtcbiAgfVxuICAvLyBSZXNvbHZlIChhbmQgd2FybSkgdGhlIG9yZyBCRUZPUkUgcmVhZGluZyBga2lkRm9yYCBiZWxvdywgc28gYSBwZXItb3JnIEtNU1xuICAvLyBibG9iIGlzIGFsd2F5cyBzdGFtcGVkIHdpdGggdGhlIGtleSBpdCB3YXMgYWN0dWFsbHkgZW5jcnlwdGVkIHVuZGVyLlxuICBjb25zdCBrZXkgPSBhd2FpdCBkZXJpdmVLZXlGb3IocHJvdmlkZXIsIG9yZ0lkKTtcbiAgY29uc3QgaXYgPSByYW5kb21CeXRlcygxMik7XG4gIGNvbnN0IGNpcGhlciA9IGNyZWF0ZUNpcGhlcml2KCdhZXMtMjU2LWdjbScsIGtleSwgaXYpO1xuICBjb25zdCBlbmMgPSBCdWZmZXIuY29uY2F0KFtjaXBoZXIudXBkYXRlKHBsYWludGV4dCwgJ3V0ZjgnKSwgY2lwaGVyLmZpbmFsKCldKTtcbiAgY29uc3QgdGFnID0gY2lwaGVyLmdldEF1dGhUYWcoKTtcbiAgLy8gUGVyT3JnS21zS2V5UHJvdmlkZXIgdGFncyBibG9icyB3aXRoIHRoZSBLTVMga2V5IGlkIHVzZWQgc28gdGhlXG4gIC8vIGRlY3J5cHQgcGF0aCBjYW4gcmVmdXNlIHRvIG9wZXJhdGUgaWYgdGhlIG9wZXJhdG9yIGxhdGVyIHN3YXBzIGluIGFcbiAgLy8gZGlmZmVyZW50IHBlci1vcmcgY29uZmlnIChhIG1pc2NvbmZpZ3VyZWQgc3dhcCBzaG91bGRuJ3Qgc2lsZW50bHlcbiAgLy8gYWNjZXB0IGEgc3RhbGUgYmxvYiBpdCBjYW4ndCB2ZXJpZnkgYWdhaW5zdCB0aGUgcmlnaHQgQ01LKS5cbiAgY29uc3Qga2lkID0gcHJvdmlkZXIua2lkRm9yPy4ob3JnSWQpO1xuICByZXR1cm4ge1xuICAgIGFsZzogJ2Flcy0yNTYtZ2NtLXYxJyxcbiAgICBpdjogaXYudG9TdHJpbmcoJ2Jhc2U2NCcpLFxuICAgIC8vIEdDTSB0YWcgTVVTVCB0cmF2ZWwgd2l0aCB0aGUgY2lwaGVydGV4dCBvciBgZGVjcnlwdFNlY3JldGAgY2FuJ3RcbiAgICAvLyB2ZXJpZnkgaW50ZWdyaXR5ICBjb25jYXRlbmF0ZSBzbyB0aGUgb24tZGlzayBzaGFwZSBpcyBvbmUgZmllbGQuXG4gICAgY2lwaGVydGV4dDogQnVmZmVyLmNvbmNhdChbZW5jLCB0YWddKS50b1N0cmluZygnYmFzZTY0JyksXG4gICAgLi4uKGtpZCAhPT0gdW5kZWZpbmVkID8geyBraWQgfSA6IHt9KSxcbiAgfTtcbn1cblxuLyoqXG4gKiBEZWNyeXB0IGFuIGBFbmNyeXB0ZWRCbG9iYCB3cml0dGVuIGJ5IGBlbmNyeXB0U2VjcmV0YC4gVGhyb3dzIG9uICogLSB1bmtub3duIGBhbGdgIChmb3JjZXMgYW4gZXhwbGljaXQgbWlncmF0aW9uIHdoZW4gdGhlIGZvcm1hdCBjaGFuZ2VzKVxuICogLSB3cm9uZyBvcmdJZCAoSEtERiBiaW5kaW5nIG1pc21hdGNoIGZhaWxzIHRoZSBhdXRoIHRhZylcbiAqIC0gdGFtcGVyZWQgY2lwaGVydGV4dCAoR0NNIGF1dGggdGFnIGNoZWNrIGZhaWxzKVxuICpcbiAqIENhbGxlcnMgaGFuZGxlIHRoZSB0aHJvdyAgbWFza2luZyB0aGUgZmFpbHVyZSBhcyBgbnVsbGAgd291bGQgaGlkZVxuICogc2lsZW50IGNvcnJ1cHRpb24gLyB3cm9uZy1vcmcgcmVhZHMuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBkZWNyeXB0U2VjcmV0KCBibG9iOiBFbmNyeXB0ZWRCbG9iLFxuICBvcmdJZDogc3RyaW5nLFxuICBwcm92aWRlcjogS2V5UHJvdmlkZXIgPSBnZXREZWZhdWx0UHJvdmlkZXIoKSxcbik6IFByb21pc2U8c3RyaW5nPiB7XG4gIGlmIChibG9iLmFsZyAhPT0gJ2Flcy0yNTYtZ2NtLXYxJykge1xuICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgZW5jcnlwdGlvbiBhbGc6ICR7YmxvYi5hbGd9YCk7XG4gIH1cbiAgLy8gV2FybSBmaXJzdDogYGtpZEZvcmAgYW5kIGBkZXJpdmVLZXlgIGJlbG93IG11c3QgYm90aCBzcGVhayBmb3IgdGhlIG9yZydzXG4gIC8vIHJlYWwgY29uZmlnLCBvciB0aGUgbWlzbWF0Y2ggZ3VhcmQgc2lsZW50bHkgbm8tb3BzLlxuICBjb25zdCBrZXkgPSBhd2FpdCBkZXJpdmVLZXlGb3IocHJvdmlkZXIsIG9yZ0lkKTtcbiAgLy8gSWYgYm90aCB0aGUgcHJvdmlkZXIgQU5EIHRoZSBibG9iIHJlcG9ydCBhIGtpZCwgdGhleSBtdXN0IG1hdGNoLlxuICAvLyBNaXNtYXRjaCB1c3VhbGx5IG1lYW5zIGFuIG9wZXJhdG9yIHJvdGF0ZWQvcmVwbGFjZWQgYW4gb3JnJ3MgS01TXG4gIC8vIGNvbmZpZyBhbmQgaXMgbm93IHJlYWRpbmcgYSBibG9iIGVuY3J5cHRlZCB1bmRlciB0aGUgT0xEIGtleSDigJRcbiAgLy8gZmFpbGluZyBsb3VkIGhlcmUgYmVhdHMgbGV0dGluZyBBRVMtR0NNIHRocm93IGFuIG9wYXF1ZSBhdXRoLXRhZyBlcnJvci5cbiAgY29uc3QgcHJvdmlkZXJLaWQgPSBwcm92aWRlci5raWRGb3I/LihvcmdJZCk7XG4gIGlmIChwcm92aWRlcktpZCAhPT0gdW5kZWZpbmVkICYmIGJsb2Iua2lkICE9PSB1bmRlZmluZWQgJiYgcHJvdmlkZXJLaWQgIT09IGJsb2Iua2lkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBLTVMga2V5IGlkIG1pc21hdGNoOiBibG9iIHdhcyBlbmNyeXB0ZWQgdW5kZXIgJHtibG9iLmtpZH0sIGN1cnJlbnQgcHJvdmlkZXIgdXNlcyAke3Byb3ZpZGVyS2lkfSBmb3Igb3JnICR7b3JnSWR9YCk7XG4gIH1cbiAgY29uc3QgaXYgPSBCdWZmZXIuZnJvbShibG9iLml2LCAnYmFzZTY0Jyk7XG4gIGNvbnN0IGFsbCA9IEJ1ZmZlci5mcm9tKGJsb2IuY2lwaGVydGV4dCwgJ2Jhc2U2NCcpO1xuICAvLyBTcGxpdCBvZmYgdGhlIDE2LWJ5dGUgYXV0aCB0YWcgYXBwZW5kZWQgaW4gZW5jcnlwdFNlY3JldC4gQW55IHRhbXBlcmluZ1xuICAvLyAgdG8gZWl0aGVyIHRoZSBjaXBoZXJ0ZXh0IE9SIHRoZSB0YWcgIGNhdXNlcyB0aGUgbmV4dCBgZmluYWwoKWAgdG9cbiAgLy8gdGhyb3cgd2l0aCBcIlVuc3VwcG9ydGVkIHN0YXRlIG9yIHVuYWJsZSB0byBhdXRoZW50aWNhdGUgZGF0YVwiLlxuICBjb25zdCB0YWcgPSBhbGwuc3ViYXJyYXkoYWxsLmxlbmd0aCAtIDE2KTtcbiAgY29uc3QgZW5jID0gYWxsLnN1YmFycmF5KDAsIGFsbC5sZW5ndGggLSAxNik7XG4gIGNvbnN0IGRlY2lwaGVyID0gY3JlYXRlRGVjaXBoZXJpdignYWVzLTI1Ni1nY20nLCBrZXksIGl2KTtcbiAgZGVjaXBoZXIuc2V0QXV0aFRhZyh0YWcpO1xuICBjb25zdCBkZWMgPSBCdWZmZXIuY29uY2F0KFtkZWNpcGhlci51cGRhdGUoZW5jKSwgZGVjaXBoZXIuZmluYWwoKV0pO1xuICByZXR1cm4gZGVjLnRvU3RyaW5nKCd1dGY4Jyk7XG59XG5cbi8qKlxuICogVHlwZSBndWFyZCAgaGFuZHkgZm9yIG1vZGVsIGxheWVycyB0aGF0IGhvbGQgYSBjb2x1bW4gd2hvc2UgdmFsdWUgbWF5IGJlXG4gKiBlaXRoZXIgYSBjbGVhci10ZXh0IHN0cmluZyAobGVnYWN5IC8gdW5lbmNyeXB0ZWQpIE9SIGFuIGVuY3J5cHRlZCBibG9iXG4gKiAocG9zdC1taWdyYXRpb24pLiBNaXhlZCBzdGF0ZXMgYXJpc2UgbWlkLW1pZ3JhdGlvbjsgdGhlIG1vZGVsIGRlY2lkZXNcbiAqIHdoYXQgdG8gZG8gKGRlY3J5cHQgb24gcmVhZCwgZW5jcnlwdCBvbiBuZXh0IHdyaXRlKS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzRW5jcnlwdGVkQmxvYih2YWx1ZTogdW5rbm93bik6IHZhbHVlIGlzIEVuY3J5cHRlZEJsb2Ige1xuICByZXR1cm4gKCB0eXBlb2YgdmFsdWUgPT09ICdvYmplY3QnXG4gICAgJiYgdmFsdWUgIT09IG51bGxcbiAgICAmJiAodmFsdWUgYXMgeyBhbGc/OiB1bmtub3duIH0pLmFsZyA9PT0gJ2Flcy0yNTYtZ2NtLXYxJ1xuICAgICYmIHR5cGVvZiAodmFsdWUgYXMgeyBpdj86IHVua25vd24gfSkuaXYgPT09ICdzdHJpbmcnXG4gICAgJiYgdHlwZW9mICh2YWx1ZSBhcyB7IGNpcGhlcnRleHQ/OiB1bmtub3duIH0pLmNpcGhlcnRleHQgPT09ICdzdHJpbmcnXG4gICk7XG59XG4iXX0=
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Constant-time string equality, for comparing a presented secret against an
|
|
3
|
+
* expected one (scrape tokens, shared webhook secrets, signatures).
|
|
4
|
+
*
|
|
5
|
+
* `a === b` on secrets short-circuits at the first differing byte, which leaks
|
|
6
|
+
* the expected value a byte at a time to an attacker who can measure response
|
|
7
|
+
* latency. `timingSafeEqual` does not — but it THROWS when the two buffers
|
|
8
|
+
* differ in length, so length is compared first and the result is folded in
|
|
9
|
+
* without an early return.
|
|
10
|
+
*
|
|
11
|
+
* The length check itself is not constant-time, so this leaks the expected
|
|
12
|
+
* secret's LENGTH. That is acceptable for fixed-length tokens and is the
|
|
13
|
+
* standard trade-off; do not use this where the length is itself the secret.
|
|
14
|
+
*/
|
|
15
|
+
export declare function safeEqual(presented: string, expected: string): boolean;
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
// Copyright 2026 Pipeline Builder Contributors
|
|
2
|
+
// SPDX-License-Identifier: Apache-2.0
|
|
3
|
+
import { timingSafeEqual } from 'crypto';
|
|
4
|
+
/**
|
|
5
|
+
* Constant-time string equality, for comparing a presented secret against an
|
|
6
|
+
* expected one (scrape tokens, shared webhook secrets, signatures).
|
|
7
|
+
*
|
|
8
|
+
* `a === b` on secrets short-circuits at the first differing byte, which leaks
|
|
9
|
+
* the expected value a byte at a time to an attacker who can measure response
|
|
10
|
+
* latency. `timingSafeEqual` does not — but it THROWS when the two buffers
|
|
11
|
+
* differ in length, so length is compared first and the result is folded in
|
|
12
|
+
* without an early return.
|
|
13
|
+
*
|
|
14
|
+
* The length check itself is not constant-time, so this leaks the expected
|
|
15
|
+
* secret's LENGTH. That is acceptable for fixed-length tokens and is the
|
|
16
|
+
* standard trade-off; do not use this where the length is itself the secret.
|
|
17
|
+
*/
|
|
18
|
+
export function safeEqual(presented, expected) {
|
|
19
|
+
const a = Buffer.from(presented, 'utf8');
|
|
20
|
+
const b = Buffer.from(expected, 'utf8');
|
|
21
|
+
if (a.length !== b.length) {
|
|
22
|
+
// Still run a comparison of equal-length buffers so a wrong-length guess
|
|
23
|
+
// doesn't return measurably faster than a right-length one.
|
|
24
|
+
timingSafeEqual(a, a);
|
|
25
|
+
return false;
|
|
26
|
+
}
|
|
27
|
+
return timingSafeEqual(a, b);
|
|
28
|
+
}
|
|
29
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VjdXJlLWNvbXBhcmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvdXRpbHMvc2VjdXJlLWNvbXBhcmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsK0NBQStDO0FBQy9DLHNDQUFzQztBQUV0QyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sUUFBUSxDQUFDO0FBRXpDOzs7Ozs7Ozs7Ozs7O0dBYUc7QUFDSCxNQUFNLFVBQVUsU0FBUyxDQUFDLFNBQWlCLEVBQUUsUUFBZ0I7SUFDM0QsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDekMsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDeEMsSUFBSSxDQUFDLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUMxQix5RUFBeUU7UUFDekUsNERBQTREO1FBQzVELGVBQWUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDdEIsT0FBTyxLQUFLLENBQUM7SUFDZixDQUFDO0lBQ0QsT0FBTyxlQUFlLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDO0FBQy9CLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvLyBDb3B5cmlnaHQgMjAyNiBQaXBlbGluZSBCdWlsZGVyIENvbnRyaWJ1dG9yc1xuLy8gU1BEWC1MaWNlbnNlLUlkZW50aWZpZXI6IEFwYWNoZS0yLjBcblxuaW1wb3J0IHsgdGltaW5nU2FmZUVxdWFsIH0gZnJvbSAnY3J5cHRvJztcblxuLyoqXG4gKiBDb25zdGFudC10aW1lIHN0cmluZyBlcXVhbGl0eSwgZm9yIGNvbXBhcmluZyBhIHByZXNlbnRlZCBzZWNyZXQgYWdhaW5zdCBhblxuICogZXhwZWN0ZWQgb25lIChzY3JhcGUgdG9rZW5zLCBzaGFyZWQgd2ViaG9vayBzZWNyZXRzLCBzaWduYXR1cmVzKS5cbiAqXG4gKiBgYSA9PT0gYmAgb24gc2VjcmV0cyBzaG9ydC1jaXJjdWl0cyBhdCB0aGUgZmlyc3QgZGlmZmVyaW5nIGJ5dGUsIHdoaWNoIGxlYWtzXG4gKiB0aGUgZXhwZWN0ZWQgdmFsdWUgYSBieXRlIGF0IGEgdGltZSB0byBhbiBhdHRhY2tlciB3aG8gY2FuIG1lYXN1cmUgcmVzcG9uc2VcbiAqIGxhdGVuY3kuIGB0aW1pbmdTYWZlRXF1YWxgIGRvZXMgbm90IOKAlCBidXQgaXQgVEhST1dTIHdoZW4gdGhlIHR3byBidWZmZXJzXG4gKiBkaWZmZXIgaW4gbGVuZ3RoLCBzbyBsZW5ndGggaXMgY29tcGFyZWQgZmlyc3QgYW5kIHRoZSByZXN1bHQgaXMgZm9sZGVkIGluXG4gKiB3aXRob3V0IGFuIGVhcmx5IHJldHVybi5cbiAqXG4gKiBUaGUgbGVuZ3RoIGNoZWNrIGl0c2VsZiBpcyBub3QgY29uc3RhbnQtdGltZSwgc28gdGhpcyBsZWFrcyB0aGUgZXhwZWN0ZWRcbiAqIHNlY3JldCdzIExFTkdUSC4gVGhhdCBpcyBhY2NlcHRhYmxlIGZvciBmaXhlZC1sZW5ndGggdG9rZW5zIGFuZCBpcyB0aGVcbiAqIHN0YW5kYXJkIHRyYWRlLW9mZjsgZG8gbm90IHVzZSB0aGlzIHdoZXJlIHRoZSBsZW5ndGggaXMgaXRzZWxmIHRoZSBzZWNyZXQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzYWZlRXF1YWwocHJlc2VudGVkOiBzdHJpbmcsIGV4cGVjdGVkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgY29uc3QgYSA9IEJ1ZmZlci5mcm9tKHByZXNlbnRlZCwgJ3V0ZjgnKTtcbiAgY29uc3QgYiA9IEJ1ZmZlci5mcm9tKGV4cGVjdGVkLCAndXRmOCcpO1xuICBpZiAoYS5sZW5ndGggIT09IGIubGVuZ3RoKSB7XG4gICAgLy8gU3RpbGwgcnVuIGEgY29tcGFyaXNvbiBvZiBlcXVhbC1sZW5ndGggYnVmZmVycyBzbyBhIHdyb25nLWxlbmd0aCBndWVzc1xuICAgIC8vIGRvZXNuJ3QgcmV0dXJuIG1lYXN1cmFibHkgZmFzdGVyIHRoYW4gYSByaWdodC1sZW5ndGggb25lLlxuICAgIHRpbWluZ1NhZmVFcXVhbChhLCBhKTtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRpbWluZ1NhZmVFcXVhbChhLCBiKTtcbn1cbiJdfQ==
|