@decaf-ts/decoration 0.0.7 → 0.0.9
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/dist/decoration.cjs +305 -169
- package/dist/decoration.esm.cjs +303 -170
- package/lib/constants.cjs +23 -23
- package/lib/constants.d.ts +22 -22
- package/lib/decoration/Decoration.cjs +55 -57
- package/lib/decoration/Decoration.d.ts +59 -61
- package/lib/decoration/types.cjs +1 -1
- package/lib/decoration/types.d.ts +34 -49
- package/lib/decorators.cjs +98 -27
- package/lib/decorators.d.ts +76 -26
- package/lib/esm/constants.d.ts +22 -22
- package/lib/esm/constants.js +23 -23
- package/lib/esm/decoration/Decoration.d.ts +59 -61
- package/lib/esm/decoration/Decoration.js +55 -57
- package/lib/esm/decoration/types.d.ts +34 -49
- package/lib/esm/decoration/types.js +1 -1
- package/lib/esm/decorators.d.ts +76 -26
- package/lib/esm/decorators.js +96 -28
- package/lib/esm/index.d.ts +4 -5
- package/lib/esm/index.js +5 -6
- package/lib/esm/metadata/Metadata.d.ts +101 -60
- package/lib/esm/metadata/Metadata.js +128 -60
- package/lib/esm/metadata/types.d.ts +22 -6
- package/lib/esm/metadata/types.js +1 -1
- package/lib/index.cjs +5 -6
- package/lib/index.d.ts +4 -5
- package/lib/metadata/Metadata.cjs +128 -60
- package/lib/metadata/Metadata.d.ts +101 -60
- package/lib/metadata/types.cjs +1 -1
- package/lib/metadata/types.d.ts +22 -6
- package/package.json +10 -3
|
@@ -6,12 +6,12 @@ exports.setValueBySplitter = setValueBySplitter;
|
|
|
6
6
|
const constants_1 = require("./../constants.cjs");
|
|
7
7
|
require("reflect-metadata");
|
|
8
8
|
/**
|
|
9
|
-
* @description Retrieves a nested value from an object given a path
|
|
10
|
-
* @summary Walks an object structure using a splitter-delimited path and returns the value at that location or undefined if any key is missing.
|
|
11
|
-
* @param {Record<string, any>} obj
|
|
12
|
-
* @param {string} path
|
|
13
|
-
* @param {string} [splitter=ObjectKeySplitter]
|
|
14
|
-
* @return {
|
|
9
|
+
* @description Retrieves a nested value from an object given a path.
|
|
10
|
+
* @summary Walks an object structure using a splitter-delimited path and returns the value at that location or `undefined` if any key is missing.
|
|
11
|
+
* @param {Record<string, any>} obj Object to traverse for the lookup.
|
|
12
|
+
* @param {string} path Splitter-delimited path to the desired value (e.g., "a.b.c").
|
|
13
|
+
* @param {string} [splitter=ObjectKeySplitter] Delimiter used to separate the path segments.
|
|
14
|
+
* @return {any|undefined} Value resolved at the given path or `undefined` when not found.
|
|
15
15
|
* @function getValueBySplitter
|
|
16
16
|
* @mermaid
|
|
17
17
|
* sequenceDiagram
|
|
@@ -42,12 +42,12 @@ function getValueBySplitter(obj, path, splitter = constants_1.ObjectKeySplitter)
|
|
|
42
42
|
return current;
|
|
43
43
|
}
|
|
44
44
|
/**
|
|
45
|
-
* @description Sets a nested value on an object given a path
|
|
45
|
+
* @description Sets a nested value on an object given a path.
|
|
46
46
|
* @summary Traverses or creates intermediate objects following a splitter-delimited path and assigns the provided value at the destination key.
|
|
47
|
-
* @param {Record<string, any>} obj
|
|
48
|
-
* @param {string} path
|
|
49
|
-
* @param {
|
|
50
|
-
* @param {string} [splitter=ObjectKeySplitter]
|
|
47
|
+
* @param {Record<string, any>} obj Object to mutate while drilling into nested keys.
|
|
48
|
+
* @param {string} path Splitter-delimited destination path (e.g., "a.b.c").
|
|
49
|
+
* @param {any} value Value to set at the destination node.
|
|
50
|
+
* @param {string} [splitter=ObjectKeySplitter] Delimiter used to separate the path segments.
|
|
51
51
|
* @return {void}
|
|
52
52
|
* @function setValueBySplitter
|
|
53
53
|
* @mermaid
|
|
@@ -85,10 +85,11 @@ function setValueBySplitter(obj, path, value, splitter = constants_1.ObjectKeySp
|
|
|
85
85
|
current[lastKey] = value;
|
|
86
86
|
}
|
|
87
87
|
/**
|
|
88
|
-
* @description Centralized runtime metadata store bound to constructors
|
|
88
|
+
* @description Centralized runtime metadata store bound to constructors.
|
|
89
89
|
* @summary Provides utilities to read and write structured metadata for classes and their members, with optional mirroring onto the constructor via a well-known symbol key. Supports nested key paths using a configurable splitter and offers both instance and static APIs.
|
|
90
|
-
* @template M The model type the metadata belongs to
|
|
91
|
-
* @template META Extends BasicMetadata<M> representing the metadata structure
|
|
90
|
+
* @template M The model type the metadata belongs to.
|
|
91
|
+
* @template META Extends BasicMetadata<M> representing the metadata structure.
|
|
92
|
+
* @param {string} [flavour=DefaultFlavour] Optional flavour identifier applied when instantiating helper builders.
|
|
92
93
|
* @class
|
|
93
94
|
* @example
|
|
94
95
|
* // Define and read metadata for a class
|
|
@@ -128,10 +129,10 @@ class Metadata {
|
|
|
128
129
|
static { this.mirror = true; }
|
|
129
130
|
constructor() { }
|
|
130
131
|
/**
|
|
131
|
-
* @description Lists known property keys for a model
|
|
132
|
+
* @description Lists known property keys for a model.
|
|
132
133
|
* @summary Reads the metadata entry and returns the names of properties that have recorded type information.
|
|
133
|
-
* @param {Constructor} model
|
|
134
|
-
* @return {string[]|undefined} Array of property names or undefined if no metadata exists
|
|
134
|
+
* @param {Constructor} model Target constructor whose property metadata should be inspected.
|
|
135
|
+
* @return {string[]|undefined} Array of property names or `undefined` if no metadata exists.
|
|
135
136
|
*/
|
|
136
137
|
static properties(model) {
|
|
137
138
|
const meta = this.get(model);
|
|
@@ -140,10 +141,10 @@ class Metadata {
|
|
|
140
141
|
return Object.keys(meta.properties);
|
|
141
142
|
}
|
|
142
143
|
/**
|
|
143
|
-
* @description Lists known methods for a model
|
|
144
|
+
* @description Lists known methods for a model.
|
|
144
145
|
* @summary Reads the metadata entry and returns the method names that have recorded signature metadata for the provided constructor.
|
|
145
|
-
* @param {Constructor} model
|
|
146
|
-
* @return {string[]|undefined} Array of
|
|
146
|
+
* @param {Constructor} model Target constructor whose method metadata should be inspected.
|
|
147
|
+
* @return {string[]|undefined} Array of method names or `undefined` if no metadata exists.
|
|
147
148
|
*/
|
|
148
149
|
static methods(model) {
|
|
149
150
|
const meta = this.get(model, constants_1.DecorationKeys.METHODS);
|
|
@@ -152,94 +153,142 @@ class Metadata {
|
|
|
152
153
|
return Object.keys(meta);
|
|
153
154
|
}
|
|
154
155
|
/**
|
|
155
|
-
* @description Retrieves a human-readable description for a class or a property
|
|
156
|
+
* @description Retrieves a human-readable description for a class or a property.
|
|
156
157
|
* @summary Looks up the description stored under the metadata "description" map. If a property key is provided, returns the property's description; otherwise returns the class description.
|
|
157
158
|
* @template M
|
|
158
|
-
* @param {Constructor<M>} model
|
|
159
|
-
* @param {string} [prop] Optional property key for which to fetch the description
|
|
160
|
-
* @return {string|undefined}
|
|
159
|
+
* @param {Constructor<M>} model Target constructor whose description is being retrieved.
|
|
160
|
+
* @param {string} [prop] Optional property key (typed as `keyof M`) for which to fetch the description.
|
|
161
|
+
* @return {string|undefined} Description text if present, otherwise `undefined`.
|
|
161
162
|
*/
|
|
162
163
|
static description(model, prop) {
|
|
163
164
|
return this.get(model, [constants_1.DecorationKeys.DESCRIPTION, prop ? prop : constants_1.DecorationKeys.CLASS].join(this.splitter));
|
|
164
165
|
}
|
|
165
166
|
/**
|
|
166
|
-
* @description Retrieves the recorded params for a method
|
|
167
|
-
* @summary Reads the metadata entry under
|
|
168
|
-
* @
|
|
169
|
-
* @param {
|
|
170
|
-
* @
|
|
167
|
+
* @description Retrieves the recorded params for a method.
|
|
168
|
+
* @summary Reads the metadata entry under `methods.<prop>.design:paramtypes` to return the parameter constructors for the given method.
|
|
169
|
+
* @template M
|
|
170
|
+
* @param {Constructor<M>} model Target constructor owning the method metadata.
|
|
171
|
+
* @param {string} prop Method name whose parameters should be fetched.
|
|
172
|
+
* @return {any[]|undefined} Array of constructor references describing each parameter or `undefined` when not available.
|
|
171
173
|
*/
|
|
172
174
|
static params(model, prop) {
|
|
173
175
|
return this.get(model, [constants_1.DecorationKeys.METHODS, prop, constants_1.DecorationKeys.DESIGN_PARAMS].join(this.splitter));
|
|
174
176
|
}
|
|
175
177
|
/**
|
|
176
|
-
* @description Retrieves
|
|
177
|
-
* @summary
|
|
178
|
-
* @
|
|
179
|
-
* @param {
|
|
180
|
-
* @
|
|
178
|
+
* @description Retrieves a single recorded parameter type for a method.
|
|
179
|
+
* @summary Looks up the parameter metadata for the provided index, enforcing bounds and returning the constructor reference for that argument.
|
|
180
|
+
* @template M
|
|
181
|
+
* @param {Constructor<M>} model Target constructor owning the method metadata.
|
|
182
|
+
* @param {string} prop Method name whose parameter should be returned.
|
|
183
|
+
* @param {number} index Zero-based index of the desired parameter metadata.
|
|
184
|
+
* @return {any|undefined} Constructor reference for the parameter or `undefined` if not recorded.
|
|
185
|
+
*/
|
|
186
|
+
static param(model, prop, index) {
|
|
187
|
+
const params = this.params(model, prop);
|
|
188
|
+
if (!params)
|
|
189
|
+
return undefined;
|
|
190
|
+
if (index > params.length - 1)
|
|
191
|
+
throw new Error(`Parameter index ${index} out of range for ${String(prop)}`);
|
|
192
|
+
return params[index];
|
|
193
|
+
}
|
|
194
|
+
/**
|
|
195
|
+
* @description Retrieves the recorded return type for a method.
|
|
196
|
+
* @summary Reads the metadata entry under `methods.<prop>.design:returntype` to return the return type for the given method.
|
|
197
|
+
* @template M
|
|
198
|
+
* @param {Constructor<M>} model Target constructor whose method metadata should be inspected.
|
|
199
|
+
* @param {string} prop Method name whose return type should be fetched.
|
|
200
|
+
* @return {any|undefined} Constructor reference for the return type or `undefined` when not available.
|
|
181
201
|
*/
|
|
182
202
|
static return(model, prop) {
|
|
183
203
|
return this.get(model, [constants_1.DecorationKeys.METHODS, prop, constants_1.DecorationKeys.DESIGN_RETURN].join(this.splitter));
|
|
184
204
|
}
|
|
185
205
|
/**
|
|
186
|
-
* @description Retrieves the recorded design type for a property
|
|
187
|
-
* @summary Reads the metadata entry under
|
|
188
|
-
* @param {Constructor} model
|
|
189
|
-
* @param {string} prop
|
|
190
|
-
* @return {Constructor|undefined}
|
|
206
|
+
* @description Retrieves the recorded design type for a property.
|
|
207
|
+
* @summary Reads the metadata entry under `properties.<prop>` to return the constructor recorded for the given property name.
|
|
208
|
+
* @param {Constructor} model Target constructor whose property metadata should be inspected.
|
|
209
|
+
* @param {string} prop Property name whose type metadata should be returned.
|
|
210
|
+
* @return {Constructor|undefined} Constructor reference for the property type or `undefined` if not available.
|
|
191
211
|
*/
|
|
192
212
|
static type(model, prop) {
|
|
193
213
|
return this.get(model, [constants_1.DecorationKeys.PROPERTIES, prop].join(this.splitter));
|
|
194
214
|
}
|
|
195
215
|
/**
|
|
196
|
-
* @description Resolves the canonical constructor associated with the provided model handle
|
|
197
|
-
* @summary Returns the stored constructor reference when the provided model is a proxy or reduced value. Falls back to the
|
|
198
|
-
* original model when no constructor metadata has been recorded yet.
|
|
216
|
+
* @description Resolves the canonical constructor associated with the provided model handle.
|
|
217
|
+
* @summary Returns the stored constructor reference when the provided model is a proxy or reduced value. Falls back to the original model when no constructor metadata has been recorded yet.
|
|
199
218
|
* @template M
|
|
200
|
-
* @param {Constructor<M>} model
|
|
201
|
-
* @return {Constructor<M
|
|
219
|
+
* @param {Constructor<M>} model Model used when recording metadata.
|
|
220
|
+
* @return {Constructor<M>|undefined} Canonical constructor if stored, otherwise `undefined`.
|
|
202
221
|
*/
|
|
203
222
|
static constr(model) {
|
|
204
|
-
return
|
|
223
|
+
return model[constants_1.DecorationKeys.CONSTRUCTOR];
|
|
205
224
|
}
|
|
206
225
|
/**
|
|
207
|
-
* @description Retrieves metadata for a model or a specific key within it
|
|
226
|
+
* @description Retrieves metadata for a model or a specific key within it.
|
|
208
227
|
* @summary When called with a constructor only, returns the entire metadata object associated with the model. When a key path is provided, returns the value stored at that nested key.
|
|
209
228
|
* @template M
|
|
210
229
|
* @template META
|
|
211
|
-
* @param {Constructor<M
|
|
212
|
-
* @param {string} [key] Optional nested key path to fetch a specific value
|
|
213
|
-
* @return {META|*|undefined}
|
|
230
|
+
* @param {Constructor<M>|string} model Target constructor used to locate the metadata record or a pre-resolved symbol identifier.
|
|
231
|
+
* @param {string} [key] Optional nested key path to fetch a specific value.
|
|
232
|
+
* @return {META|*|undefined} Metadata object, the value at the key path, or `undefined` if nothing exists.
|
|
214
233
|
*/
|
|
215
234
|
static get(model, key) {
|
|
235
|
+
if (key === constants_1.DecorationKeys.CONSTRUCTOR)
|
|
236
|
+
return this.constr(model);
|
|
216
237
|
if (key !== constants_1.DecorationKeys.CONSTRUCTOR)
|
|
217
238
|
model = this.constr(model) || model;
|
|
218
239
|
const symbol = Symbol.for(model.toString());
|
|
219
240
|
return this.innerGet(symbol, key);
|
|
220
241
|
}
|
|
242
|
+
/**
|
|
243
|
+
* @description Retrieves metadata stored under a symbol key.
|
|
244
|
+
* @summary Internal helper that resolves and optionally drills into the in-memory metadata map for the provided symbol and key path.
|
|
245
|
+
* @param {symbol} symbol Symbol representing the metadata bucket.
|
|
246
|
+
* @param {string|symbol} [key] Optional nested key referencing a specific metadata entry.
|
|
247
|
+
* @return {any} Stored metadata object or value for the provided key, or `undefined` when absent.
|
|
248
|
+
*/
|
|
221
249
|
static innerGet(symbol, key) {
|
|
222
250
|
if (!this._metadata[symbol])
|
|
223
251
|
return undefined;
|
|
224
252
|
if (!key)
|
|
225
253
|
return this._metadata[symbol];
|
|
226
|
-
|
|
254
|
+
if (typeof key === "string")
|
|
255
|
+
return getValueBySplitter(this._metadata[symbol], key, this.splitter);
|
|
256
|
+
return this._metadata[symbol][key];
|
|
227
257
|
}
|
|
258
|
+
/**
|
|
259
|
+
* @description Writes metadata under a symbol key.
|
|
260
|
+
* @summary Internal helper that ensures the metadata bucket exists for the provided symbol and persists the given value, drilling into nested structures when the key is a string path.
|
|
261
|
+
* @param {symbol} symbol Symbol representing the metadata bucket.
|
|
262
|
+
* @param {string|symbol} key Nested key path or direct symbol under which to store the metadata value.
|
|
263
|
+
* @param {any} value Value persisted in the metadata store.
|
|
264
|
+
* @return {void}
|
|
265
|
+
*/
|
|
228
266
|
static innerSet(symbol, key, value) {
|
|
229
267
|
if (!this._metadata[symbol])
|
|
230
268
|
this._metadata[symbol] = {};
|
|
231
|
-
|
|
269
|
+
if (typeof key === "string")
|
|
270
|
+
return setValueBySplitter(this._metadata[symbol], key, value, this.splitter);
|
|
271
|
+
this._metadata[symbol][key] = value;
|
|
232
272
|
}
|
|
233
273
|
/**
|
|
234
|
-
* @description Writes a metadata value at a given nested key path
|
|
274
|
+
* @description Writes a metadata value at a given nested key path.
|
|
235
275
|
* @summary Ensures the metadata record exists for the constructor, mirrors it on the constructor when enabled, and sets the provided value on the nested key path using the configured splitter.
|
|
236
276
|
* @template M
|
|
237
|
-
* @param {Constructor<M
|
|
238
|
-
* @param {string} key
|
|
239
|
-
* @param {
|
|
277
|
+
* @param {Constructor<M>|string} model Target constructor to which the metadata belongs or a direct identifier string.
|
|
278
|
+
* @param {string} key Nested key path at which to store the value.
|
|
279
|
+
* @param {any} value Value to store in the metadata.
|
|
240
280
|
* @return {void}
|
|
241
281
|
*/
|
|
242
282
|
static set(model, key, value) {
|
|
283
|
+
if (key === constants_1.DecorationKeys.CONSTRUCTOR) {
|
|
284
|
+
Object.defineProperty(model, constants_1.DecorationKeys.CONSTRUCTOR, {
|
|
285
|
+
enumerable: false,
|
|
286
|
+
configurable: false,
|
|
287
|
+
writable: false,
|
|
288
|
+
value: value,
|
|
289
|
+
});
|
|
290
|
+
return;
|
|
291
|
+
}
|
|
243
292
|
if (typeof model !== "string")
|
|
244
293
|
model = this.constr(model) || model;
|
|
245
294
|
const symbol = Symbol.for(model.toString());
|
|
@@ -255,11 +304,12 @@ class Metadata {
|
|
|
255
304
|
}
|
|
256
305
|
}
|
|
257
306
|
/**
|
|
258
|
-
* @description Registers a decoration-aware library and its version
|
|
307
|
+
* @description Registers a decoration-aware library and its version.
|
|
259
308
|
* @summary Stores the version string for an integrating library under the shared libraries metadata symbol, preventing duplicate registrations for the same library identifier.
|
|
260
|
-
* @param {string} library Package name or identifier to register
|
|
261
|
-
* @param {string} version Semantic version string associated with the library
|
|
262
|
-
* @
|
|
309
|
+
* @param {string} library Package name or identifier to register.
|
|
310
|
+
* @param {string} version Semantic version string associated with the library.
|
|
311
|
+
* @return {void}
|
|
312
|
+
* @throws {Error} If the library has already been registered.
|
|
263
313
|
*/
|
|
264
314
|
static registerLibrary(library, version) {
|
|
265
315
|
const symbol = Symbol.for(constants_1.DecorationKeys.LIBRARIES);
|
|
@@ -268,6 +318,24 @@ class Metadata {
|
|
|
268
318
|
throw new Error(`Library already ${library} registered with version ${version}`);
|
|
269
319
|
this.innerSet(symbol, library, version);
|
|
270
320
|
}
|
|
321
|
+
/**
|
|
322
|
+
* @description Lists registered decoration-aware libraries.
|
|
323
|
+
* @summary Returns the in-memory map of library identifiers to semantic versions that have been registered with the Decoration metadata store.
|
|
324
|
+
* @return {Record<string, string>} Map of registered library identifiers to their version strings.
|
|
325
|
+
*/
|
|
326
|
+
static libraries() {
|
|
327
|
+
const symbol = Symbol.for(constants_1.DecorationKeys.LIBRARIES);
|
|
328
|
+
return this.innerGet(symbol) || {};
|
|
329
|
+
}
|
|
330
|
+
/**
|
|
331
|
+
* @description Joins path segments using the current splitter.
|
|
332
|
+
* @summary Constructs a nested metadata key by concatenating string segments with the configured splitter for use with the metadata store.
|
|
333
|
+
* @param {...string} strs Key segments to join into a full metadata path.
|
|
334
|
+
* @return {string} Splitter-joined metadata key.
|
|
335
|
+
*/
|
|
336
|
+
static key(...strs) {
|
|
337
|
+
return strs.join(this.splitter);
|
|
338
|
+
}
|
|
271
339
|
}
|
|
272
340
|
exports.Metadata = Metadata;
|
|
273
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWV0YWRhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWV0YWRhdGEvTWV0YWRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBNEJBLGdEQW1CQztBQTRCRCxnREF5QkM7QUFuR0Qsa0RBQWlFO0FBQ2pFLDRCQUEwQjtBQUUxQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSCxTQUFnQixrQkFBa0IsQ0FDaEMsR0FBd0IsRUFDeEIsSUFBWSxFQUNaLFdBQW1CLDZCQUFpQjtJQUVwQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2xDLElBQUksT0FBTyxHQUFHLEdBQUcsQ0FBQztJQUVsQixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQ0UsT0FBTyxLQUFLLElBQUk7WUFDaEIsT0FBTyxLQUFLLFNBQVM7WUFDckIsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQztZQUVuRCxPQUFPLFNBQVMsQ0FBQztRQUNuQixPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5Qkc7QUFDSCxTQUFnQixrQkFBa0IsQ0FDaEMsR0FBd0IsRUFDeEIsSUFBWSxFQUNaLEtBQVUsRUFDVixRQUFRLEdBQUcsNkJBQWlCO0lBRTVCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzlELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTztJQUU5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QU1HO0lBQ0gsTUFBTSxDQUFDLGVBQWUsQ0FBQyxPQUFlLEVBQUUsT0FBZTtRQUNyRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLDBCQUFjLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDcEQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDM0MsSUFBSSxHQUFHO1lBQ0wsTUFBTSxJQUFJLEtBQUssQ0FDYixtQkFBbUIsT0FBTyw0QkFBNEIsT0FBTyxFQUFFLENBQ2hFLENBQUM7UUFDSixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUMsQ0FBQzs7QUF2TkgsNEJBd05DIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmFzaWNNZXRhZGF0YSwgQ29uc3RydWN0b3IgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgRGVjb3JhdGlvbktleXMsIE9iamVjdEtleVNwbGl0dGVyIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IFwicmVmbGVjdC1tZXRhZGF0YVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSBuZXN0ZWQgdmFsdWUgZnJvbSBhbiBvYmplY3QgZ2l2ZW4gYSBwYXRoXG4gKiBAc3VtbWFyeSBXYWxrcyBhbiBvYmplY3Qgc3RydWN0dXJlIHVzaW5nIGEgc3BsaXR0ZXItZGVsaW1pdGVkIHBhdGggYW5kIHJldHVybnMgdGhlIHZhbHVlIGF0IHRoYXQgbG9jYXRpb24gb3IgdW5kZWZpbmVkIGlmIGFueSBrZXkgaXMgbWlzc2luZy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gb2JqIFRoZSBvYmplY3QgdG8gdHJhdmVyc2VcbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFRoZSBwYXRoIHRvIHRoZSBkZXNpcmVkIHZhbHVlIChlLmcuLCBcImEuYi5jXCIpXG4gKiBAcGFyYW0ge3N0cmluZ30gW3NwbGl0dGVyPU9iamVjdEtleVNwbGl0dGVyXSBUaGUgZGVsaW1pdGVyIHVzZWQgdG8gc3BsaXQgdGhlIHBhdGhcbiAqIEByZXR1cm4geyp9IFRoZSByZXNvbHZlZCB2YWx1ZSBhdCB0aGUgZ2l2ZW4gcGF0aCBvciB1bmRlZmluZWQgaWYgbm90IGZvdW5kXG4gKiBAZnVuY3Rpb24gZ2V0VmFsdWVCeVNwbGl0dGVyXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IEYgYXMgZ2V0VmFsdWVCeVNwbGl0dGVyXG4gKiAgIHBhcnRpY2lwYW50IE8gYXMgT2JqZWN0XG4gKiAgIEMtPj5GOiAob2JqLCBwYXRoLCBzcGxpdHRlcilcbiAqICAgRi0+PkY6IHNwbGl0IHBhdGggaW50byBrZXlzXG4gKiAgIGxvb3AgZm9yIGVhY2gga2V5XG4gKiAgICAgRi0+Pk86IGFjY2VzcyBjdXJyZW50W2tleV1cbiAqICAgICBhbHQgbWlzc2luZyBvciBudWxsaXNoXG4gKiAgICAgICBGLS0+PkM6IHJldHVybiB1bmRlZmluZWRcbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKiAgIEYtLT4+QzogcmV0dXJuIGZpbmFsIHZhbHVlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRpb25cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFZhbHVlQnlTcGxpdHRlcihcbiAgb2JqOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICBwYXRoOiBzdHJpbmcsXG4gIHNwbGl0dGVyOiBzdHJpbmcgPSBPYmplY3RLZXlTcGxpdHRlclxuKTogYW55IHtcbiAgY29uc3Qga2V5cyA9IHBhdGguc3BsaXQoc3BsaXR0ZXIpO1xuICBsZXQgY3VycmVudCA9IG9iajtcblxuICBmb3IgKGNvbnN0IGtleSBvZiBrZXlzKSB7XG4gICAgaWYgKFxuICAgICAgY3VycmVudCA9PT0gbnVsbCB8fFxuICAgICAgY3VycmVudCA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKGN1cnJlbnQsIGtleSlcbiAgICApXG4gICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleV07XG4gIH1cblxuICByZXR1cm4gY3VycmVudDtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gU2V0cyBhIG5lc3RlZCB2YWx1ZSBvbiBhbiBvYmplY3QgZ2l2ZW4gYSBwYXRoXG4gKiBAc3VtbWFyeSBUcmF2ZXJzZXMgb3IgY3JlYXRlcyBpbnRlcm1lZGlhdGUgb2JqZWN0cyBmb2xsb3dpbmcgYSBzcGxpdHRlci1kZWxpbWl0ZWQgcGF0aCBhbmQgYXNzaWducyB0aGUgcHJvdmlkZWQgdmFsdWUgYXQgdGhlIGRlc3RpbmF0aW9uIGtleS5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gb2JqIFRoZSBvYmplY3QgdG8gbXV0YXRlXG4gKiBAcGFyYW0ge3N0cmluZ30gcGF0aCBUaGUgZGVzdGluYXRpb24gcGF0aCAoZS5nLiwgXCJhLmIuY1wiKVxuICogQHBhcmFtIHsqfSB2YWx1ZSBUaGUgdmFsdWUgdG8gc2V0IGF0IHRoZSBkZXN0aW5hdGlvblxuICogQHBhcmFtIHtzdHJpbmd9IFtzcGxpdHRlcj1PYmplY3RLZXlTcGxpdHRlcl0gVGhlIGRlbGltaXRlciB1c2VkIHRvIHNwbGl0IHRoZSBwYXRoXG4gKiBAcmV0dXJuIHt2b2lkfVxuICogQGZ1bmN0aW9uIHNldFZhbHVlQnlTcGxpdHRlclxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENhbGxlclxuICogICBwYXJ0aWNpcGFudCBGIGFzIHNldFZhbHVlQnlTcGxpdHRlclxuICogICBwYXJ0aWNpcGFudCBPIGFzIE9iamVjdFxuICogICBDLT4+RjogKG9iaiwgcGF0aCwgdmFsdWUsIHNwbGl0dGVyKVxuICogICBGLT4+Rjogc3BsaXQgcGF0aCBpbnRvIGtleXNcbiAqICAgbG9vcCBmb3IgZWFjaCBrZXlcbiAqICAgICBhbHQga2V5IG1pc3NpbmdcbiAqICAgICAgIEYtPj5POiBjcmVhdGUgaW50ZXJtZWRpYXRlIG9iamVjdFxuICogICAgIGVsc2Uga2V5IGV4aXN0c1xuICogICAgICAgRi0+Pk86IGRlc2NlbmQgaW50byBleGlzdGluZyBvYmplY3RcbiAqICAgICBlbmRcbiAqICAgZW5kXG4gKiAgIEYtLT4+Qzogdm9pZFxuICogQG1lbWJlck9mIG1vZHVsZTpkZWNvcmF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzZXRWYWx1ZUJ5U3BsaXR0ZXIoXG4gIG9iajogUmVjb3JkPHN0cmluZywgYW55PixcbiAgcGF0aDogc3RyaW5nLFxuICB2YWx1ZTogYW55LFxuICBzcGxpdHRlciA9IE9iamVjdEtleVNwbGl0dGVyXG4pOiB2b2lkIHtcbiAgY29uc3Qga2V5cyA9IHBhdGguc3BsaXQoc3BsaXR0ZXIpLmZpbHRlcigoaykgPT4gay5sZW5ndGggPiAwKTtcbiAgaWYgKGtleXMubGVuZ3RoID09PSAwKSByZXR1cm47XG5cbiAgbGV0IGN1cnJlbnQ6IFJlY29yZDxhbnksIGFueT4gPSBvYmo7XG5cbiAgZm9yIChsZXQgaSA9IDA7IGkgPCBrZXlzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgIGNvbnN0IGtleSA9IGtleXNbaV07XG4gICAgaWYgKFxuICAgICAgY3VycmVudFtrZXldID09PSB1bmRlZmluZWQgfHxcbiAgICAgIGN1cnJlbnRba2V5XSA9PT0gbnVsbCB8fFxuICAgICAgdHlwZW9mIGN1cnJlbnRba2V5XSAhPT0gXCJvYmplY3RcIlxuICAgICkge1xuICAgICAgY3VycmVudFtrZXldID0ge307XG4gICAgfVxuICAgIGN1cnJlbnQgPSBjdXJyZW50W2tleV07XG4gIH1cblxuICBjb25zdCBsYXN0S2V5ID0ga2V5c1trZXlzLmxlbmd0aCAtIDFdO1xuICBjdXJyZW50W2xhc3RLZXldID0gdmFsdWU7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENlbnRyYWxpemVkIHJ1bnRpbWUgbWV0YWRhdGEgc3RvcmUgYm91bmQgdG8gY29uc3RydWN0b3JzXG4gKiBAc3VtbWFyeSBQcm92aWRlcyB1dGlsaXRpZXMgdG8gcmVhZCBhbmQgd3JpdGUgc3RydWN0dXJlZCBtZXRhZGF0YSBmb3IgY2xhc3NlcyBhbmQgdGhlaXIgbWVtYmVycywgd2l0aCBvcHRpb25hbCBtaXJyb3Jpbmcgb250byB0aGUgY29uc3RydWN0b3IgdmlhIGEgd2VsbC1rbm93biBzeW1ib2wga2V5LiBTdXBwb3J0cyBuZXN0ZWQga2V5IHBhdGhzIHVzaW5nIGEgY29uZmlndXJhYmxlIHNwbGl0dGVyIGFuZCBvZmZlcnMgYm90aCBpbnN0YW5jZSBhbmQgc3RhdGljIEFQSXMuXG4gKiBAdGVtcGxhdGUgTSBUaGUgbW9kZWwgdHlwZSB0aGUgbWV0YWRhdGEgYmVsb25ncyB0b1xuICogQHRlbXBsYXRlIE1FVEEgRXh0ZW5kcyBCYXNpY01ldGFkYXRhPE0+IHJlcHJlc2VudGluZyB0aGUgbWV0YWRhdGEgc3RydWN0dXJlXG4gKiBAY2xhc3NcbiAqIEBleGFtcGxlXG4gKiAvLyBEZWZpbmUgYW5kIHJlYWQgbWV0YWRhdGEgZm9yIGEgY2xhc3NcbiAqIGNsYXNzIFVzZXIgeyBuYW1lITogc3RyaW5nIH1cbiAqIE1ldGFkYXRhLnNldChVc2VyLCBcImRlc2NyaXB0aW9uLmNsYXNzXCIsIFwiQSB1c2VyIG1vZGVsXCIpO1xuICogTWV0YWRhdGEuc2V0KFVzZXIsIFwicHJvcGVydGllcy5uYW1lXCIsIFN0cmluZyk7XG4gKiBjb25zdCBkZXNjID0gTWV0YWRhdGEuZ2V0KFVzZXIsIFwiZGVzY3JpcHRpb24uY2xhc3NcIik7IC8vIFwiQSB1c2VyIG1vZGVsXCJcbiAqIGNvbnN0IHR5cGUgPSBNZXRhZGF0YS50eXBlKFVzZXIsIFwibmFtZVwiKTsgLy8gU3RyaW5nXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ29uc3RydWN0b3JcbiAqICAgcGFydGljaXBhbnQgUyBhcyBNZXRhZGF0YSAoc3RhdGljKVxuICogICBDLT4+Uzogc2V0KFVzZXIsIFwicHJvcGVydGllcy5uYW1lXCIsIFN0cmluZylcbiAqICAgQy0+PlM6IGdldChVc2VyLCBcInByb3BlcnRpZXMubmFtZVwiKVxuICogICBTLS0+PkM6IFN0cmluZ1xuICovXG5leHBvcnQgY2xhc3MgTWV0YWRhdGEge1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIEluLW1lbW9yeSBzdG9yYWdlIG9mIG1ldGFkYXRhIGJ5IGNvbnN0cnVjdG9yIHN5bWJvbFxuICAgKiBAc3VtbWFyeSBNYXBzIGEgU3ltYm9sIGRlcml2ZWQgZnJvbSB0aGUgY29uc3RydWN0b3IgdG8gaXRzIG1ldGFkYXRhIG9iamVjdCwgZW5hYmxpbmcgZWZmaWNpZW50IGxvb2t1cC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9tZXRhZGF0YTogUmVjb3JkPHN5bWJvbCwgYW55PiA9IHt9O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUGF0aCBkZWxpbWl0ZXIgZm9yIG5lc3RlZCBtZXRhZGF0YSBrZXlzXG4gICAqIEBzdW1tYXJ5IFVzZWQgYnkgZ2V0L3NldCBvcGVyYXRpb25zIHRvIG5hdmlnYXRlIG5lc3RlZCBzdHJ1Y3R1cmVzLCBkZWZhdWx0cyB0byBPYmplY3RLZXlTcGxpdHRlci5cbiAgICovXG4gIHN0YXRpYyBzcGxpdHRlciA9IE9iamVjdEtleVNwbGl0dGVyO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFN5bWJvbCBrZXkgdXNlZCB0byBtaXJyb3IgbWV0YWRhdGEgb24gdGhlIGNvbnN0cnVjdG9yXG4gICAqIEBzdW1tYXJ5IFdoZW4gbWlycm9yaW5nIGlzIGVuYWJsZWQsIHRoZSBtZXRhZGF0YSBvYmplY3QgaXMgZGVmaW5lZCBvbiB0aGUgY29uc3RydWN0b3IgdW5kZXIgdGhpcyBub24tZW51bWVyYWJsZSBrZXkuXG4gICAqL1xuICBzdGF0aWMgYmFzZUtleSA9IERlY29yYXRpb25LZXlzLlJFRkxFQ1Q7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ29udHJvbHMgd2hldGhlciBtZXRhZGF0YSBpcyBtaXJyb3JlZCBvbnRvIHRoZSBjb25zdHJ1Y3RvclxuICAgKiBAc3VtbWFyeSBXaGVuIHRydWUsIHRoZSBtZXRhZGF0YSBvYmplY3QgaXMgZGVmaW5lZCBvbiB0aGUgY29uc3RydWN0b3IgdW5kZXIgdGhlIG5vbi1lbnVtZXJhYmxlIGJhc2VLZXkuXG4gICAqL1xuICBzdGF0aWMgbWlycm9yOiBib29sZWFuID0gdHJ1ZTtcblxuICBwcml2YXRlIGNvbnN0cnVjdG9yKCkge31cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExpc3RzIGtub3duIHByb3BlcnR5IGtleXMgZm9yIGEgbW9kZWxcbiAgICogQHN1bW1hcnkgUmVhZHMgdGhlIG1ldGFkYXRhIGVudHJ5IGFuZCByZXR1cm5zIHRoZSBuYW1lcyBvZiBwcm9wZXJ0aWVzIHRoYXQgaGF2ZSByZWNvcmRlZCB0eXBlIGluZm9ybWF0aW9uLlxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBtb2RlbCBUaGUgdGFyZ2V0IGNvbnN0cnVjdG9yXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfHVuZGVmaW5lZH0gQXJyYXkgb2YgcHJvcGVydHkgbmFtZXMgb3IgdW5kZWZpbmVkIGlmIG5vIG1ldGFkYXRhIGV4aXN0c1xuICAgKi9cbiAgc3RhdGljIHByb3BlcnRpZXMobW9kZWw6IENvbnN0cnVjdG9yKTogc3RyaW5nW10gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IG1ldGEgPSB0aGlzLmdldChtb2RlbCk7XG4gICAgaWYgKCFtZXRhKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIHJldHVybiBPYmplY3Qua2V5cyhtZXRhLnByb3BlcnRpZXMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMaXN0cyBrbm93biBtZXRob2RzIGZvciBhIG1vZGVsXG4gICAqIEBzdW1tYXJ5IFJlYWRzIHRoZSBtZXRhZGF0YSBlbnRyeSBhbmQgcmV0dXJucyB0aGUgbWV0aG9kIG5hbWVzIHRoYXQgaGF2ZSByZWNvcmRlZCBzaWduYXR1cmUgbWV0YWRhdGEgZm9yIHRoZSBwcm92aWRlZCBjb25zdHJ1Y3Rvci5cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gbW9kZWwgVGhlIHRhcmdldCBjb25zdHJ1Y3RvclxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXXx1bmRlZmluZWR9IEFycmF5IG9mIHByb3BlcnR5IG5hbWVzIG9yIHVuZGVmaW5lZCBpZiBubyBtZXRhZGF0YSBleGlzdHNcbiAgICovXG4gIHN0YXRpYyBtZXRob2RzKG1vZGVsOiBDb25zdHJ1Y3Rvcik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5nZXQobW9kZWwsIERlY29yYXRpb25LZXlzLk1FVEhPRFMpO1xuICAgIGlmICghbWV0YSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMobWV0YSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIGZvciBhIGNsYXNzIG9yIGEgcHJvcGVydHlcbiAgICogQHN1bW1hcnkgTG9va3MgdXAgdGhlIGRlc2NyaXB0aW9uIHN0b3JlZCB1bmRlciB0aGUgbWV0YWRhdGEgXCJkZXNjcmlwdGlvblwiIG1hcC4gSWYgYSBwcm9wZXJ0eSBrZXkgaXMgcHJvdmlkZWQsIHJldHVybnMgdGhlIHByb3BlcnR5J3MgZGVzY3JpcHRpb247IG90aGVyd2lzZSByZXR1cm5zIHRoZSBjbGFzcyBkZXNjcmlwdGlvbi5cbiAgICogQHRlbXBsYXRlIE1cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgVGhlIHRhcmdldCBjb25zdHJ1Y3RvciB3aG9zZSBkZXNjcmlwdGlvbiBpcyBiZWluZyByZXRyaWV2ZWRcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtwcm9wXSBPcHRpb25hbCBwcm9wZXJ0eSBrZXkgZm9yIHdoaWNoIHRvIGZldGNoIHRoZSBkZXNjcmlwdGlvblxuICAgKiBAcmV0dXJuIHtzdHJpbmd8dW5kZWZpbmVkfSBUaGUgZGVzY3JpcHRpb24gdGV4dCBpZiBwcmVzZW50LCBvdGhlcndpc2UgdW5kZWZpbmVkXG4gICAqL1xuICBzdGF0aWMgZGVzY3JpcHRpb248TT4oXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+LFxuICAgIHByb3A/OiBrZXlvZiBNXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0KFxuICAgICAgbW9kZWwsXG4gICAgICBbRGVjb3JhdGlvbktleXMuREVTQ1JJUFRJT04sIHByb3AgPyBwcm9wIDogRGVjb3JhdGlvbktleXMuQ0xBU1NdLmpvaW4oXG4gICAgICAgIHRoaXMuc3BsaXR0ZXJcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgdGhlIHJlY29yZGVkIHBhcmFtcyBmb3IgYSBtZXRob2RcbiAgICogQHN1bW1hcnkgUmVhZHMgdGhlIG1ldGFkYXRhIGVudHJ5IHVuZGVyIFwibWV0aG9kcy48cHJvcD4uZGVzaWduOnBhcmFtc1wiIHRvIHJldHVybiB0aGUgYXJndW1lbnRzIGZvciB0aGUgaXZlbiBtZXRob2QuXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IG1vZGVsIFRoZSB0YXJnZXQgY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtzdHJpbmd9IHByb3AgVGhlIG1ldGhvZCBuYW1lXG4gICAqIEByZXR1cm4ge2FueVtdIHwgdW5kZWZpbmVkfSBUaGUgYXJndW1lbnQgdHlwZXMgb2YgdGhlIG1ldGhvZCBvciB1bmRlZmluZWQgaWYgbm90IGF2YWlsYWJsZVxuICAgKi9cbiAgc3RhdGljIHBhcmFtczxNPihtb2RlbDogQ29uc3RydWN0b3I8TT4sIHByb3A6IHN0cmluZyk6IGFueVtdIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoXG4gICAgICBtb2RlbCxcbiAgICAgIFtEZWNvcmF0aW9uS2V5cy5NRVRIT0RTLCBwcm9wLCBEZWNvcmF0aW9uS2V5cy5ERVNJR05fUEFSQU1TXS5qb2luKFxuICAgICAgICB0aGlzLnNwbGl0dGVyXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSByZWNvcmRlZCByZXR1cm4gdHlwZSBmb3IgYSBtZXRob2RcbiAgICogQHN1bW1hcnkgUmVhZHMgdGhlIG1ldGFkYXRhIGVudHJ5IHVuZGVyIFwibWV0aG9kcy48cHJvcD4uZGVzaWduOnJldHVyblwiIHRvIHJldHVybiB0aGUgcmV0dXJuIHR5cGUgZm9yIHRoZSBnaXZlbiBtZXRob2QuXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IG1vZGVsIFRoZSB0YXJnZXQgY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHtzdHJpbmd9IHByb3AgVGhlIG1ldGhvZCBuYW1lXG4gICAqIEByZXR1cm4ge2FueXx1bmRlZmluZWR9IFRoZSByZXR1cm4gdHlwZSBvZiB0aGUgbWV0aG9kIG9yIHVuZGVmaW5lZCBpZiBub3QgYXZhaWxhYmxlXG4gICAqL1xuICBzdGF0aWMgcmV0dXJuPE0+KG1vZGVsOiBDb25zdHJ1Y3RvcjxNPiwgcHJvcDogc3RyaW5nKTogYW55IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoXG4gICAgICBtb2RlbCxcbiAgICAgIFtEZWNvcmF0aW9uS2V5cy5NRVRIT0RTLCBwcm9wLCBEZWNvcmF0aW9uS2V5cy5ERVNJR05fUkVUVVJOXS5qb2luKFxuICAgICAgICB0aGlzLnNwbGl0dGVyXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSByZWNvcmRlZCBkZXNpZ24gdHlwZSBmb3IgYSBwcm9wZXJ0eVxuICAgKiBAc3VtbWFyeSBSZWFkcyB0aGUgbWV0YWRhdGEgZW50cnkgdW5kZXIgXCJwcm9wZXJ0aWVzLjxwcm9wPlwiIHRvIHJldHVybiB0aGUgY29uc3RydWN0b3IgcmVjb3JkZWQgZm9yIHRoZSBnaXZlbiBwcm9wZXJ0eSBuYW1lLlxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBtb2RlbCBUaGUgdGFyZ2V0IGNvbnN0cnVjdG9yXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIFRoZSBwcm9wZXJ0eSBuYW1lIHdob3NlIHR5cGUgc2hvdWxkIGJlIHJldHVybmVkXG4gICAqIEByZXR1cm4ge0NvbnN0cnVjdG9yfHVuZGVmaW5lZH0gVGhlIGNvbnN0cnVjdG9yIHJlZmVyZW5jZSBvZiB0aGUgcHJvcGVydHkgdHlwZSBvciB1bmRlZmluZWQgaWYgbm90IGF2YWlsYWJsZVxuICAgKi9cbiAgc3RhdGljIHR5cGUobW9kZWw6IENvbnN0cnVjdG9yLCBwcm9wOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoXG4gICAgICBtb2RlbCxcbiAgICAgIFtEZWNvcmF0aW9uS2V5cy5QUk9QRVJUSUVTLCBwcm9wXS5qb2luKHRoaXMuc3BsaXR0ZXIpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVzb2x2ZXMgdGhlIGNhbm9uaWNhbCBjb25zdHJ1Y3RvciBhc3NvY2lhdGVkIHdpdGggdGhlIHByb3ZpZGVkIG1vZGVsIGhhbmRsZVxuICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSBzdG9yZWQgY29uc3RydWN0b3IgcmVmZXJlbmNlIHdoZW4gdGhlIHByb3ZpZGVkIG1vZGVsIGlzIGEgcHJveHkgb3IgcmVkdWNlZCB2YWx1ZS4gRmFsbHMgYmFjayB0byB0aGVcbiAgICogb3JpZ2luYWwgbW9kZWwgd2hlbiBubyBjb25zdHJ1Y3RvciBtZXRhZGF0YSBoYXMgYmVlbiByZWNvcmRlZCB5ZXQuXG4gICAqIEB0ZW1wbGF0ZSBNXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8TT59IG1vZGVsIFRoZSBtb2RlbCB1c2VkIHdoZW4gcmVjb3JkaW5nIG1ldGFkYXRhXG4gICAqIEByZXR1cm4ge0NvbnN0cnVjdG9yPE0+IHwgdW5kZWZpbmVkfSBUaGUgY2Fub25pY2FsIGNvbnN0cnVjdG9yIGlmIHN0b3JlZCwgb3RoZXJ3aXNlIHVuZGVmaW5lZFxuICAgKi9cbiAgc3RhdGljIGNvbnN0cjxNPihtb2RlbDogQ29uc3RydWN0b3I8TT4pIHtcbiAgICByZXR1cm4gdGhpcy5nZXQobW9kZWwsIERlY29yYXRpb25LZXlzLkNPTlNUUlVDVE9SKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG1ldGFkYXRhIGZvciBhIG1vZGVsIG9yIGEgc3BlY2lmaWMga2V5IHdpdGhpbiBpdFxuICAgKiBAc3VtbWFyeSBXaGVuIGNhbGxlZCB3aXRoIGEgY29uc3RydWN0b3Igb25seSwgcmV0dXJucyB0aGUgZW50aXJlIG1ldGFkYXRhIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIG1vZGVsLiBXaGVuIGEga2V5IHBhdGggaXMgcHJvdmlkZWQsIHJldHVybnMgdGhlIHZhbHVlIHN0b3JlZCBhdCB0aGF0IG5lc3RlZCBrZXkuXG4gICAqIEB0ZW1wbGF0ZSBNXG4gICAqIEB0ZW1wbGF0ZSBNRVRBXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8TT59IG1vZGVsIFRoZSB0YXJnZXQgY29uc3RydWN0b3IgdXNlZCB0byBsb2NhdGUgdGhlIG1ldGFkYXRhIHJlY29yZFxuICAgKiBAcmV0dXJuIHtNRVRBfHVuZGVmaW5lZH0gVGhlIG1ldGFkYXRhIG9iamVjdCwgdGhlIHZhbHVlIGF0IHRoZSBrZXkgcGF0aCwgb3IgdW5kZWZpbmVkIGlmIG5vdGhpbmcgZXhpc3RzXG4gICAqL1xuICBzdGF0aWMgZ2V0PE0sIE1FVEEgZXh0ZW5kcyBCYXNpY01ldGFkYXRhPE0+ID0gQmFzaWNNZXRhZGF0YTxNPj4oXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+XG4gICk6IE1FVEEgfCB1bmRlZmluZWQ7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG1ldGFkYXRhIGZvciBhIG1vZGVsIG9yIGEgc3BlY2lmaWMga2V5IHdpdGhpbiBpdFxuICAgKiBAc3VtbWFyeSBXaGVuIGNhbGxlZCB3aXRoIGEgY29uc3RydWN0b3Igb25seSwgcmV0dXJucyB0aGUgZW50aXJlIG1ldGFkYXRhIG9iamVjdCBhc3NvY2lhdGVkIHdpdGggdGhlIG1vZGVsLiBXaGVuIGEga2V5IHBhdGggaXMgcHJvdmlkZWQsIHJldHVybnMgdGhlIHZhbHVlIHN0b3JlZCBhdCB0aGF0IG5lc3RlZCBrZXkuXG4gICAqIEB0ZW1wbGF0ZSBNXG4gICAqIEB0ZW1wbGF0ZSBNRVRBXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8TT59IG1vZGVsIFRoZSB0YXJnZXQgY29uc3RydWN0b3IgdXNlZCB0byBsb2NhdGUgdGhlIG1ldGFkYXRhIHJlY29yZFxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IG5lc3RlZCBrZXkgcGF0aCB0byBmZXRjaCBhIHNwZWNpZmljIHZhbHVlXG4gICAqIEByZXR1cm4ge01FVEF8Knx1bmRlZmluZWR9IFRoZSBtZXRhZGF0YSBvYmplY3QsIHRoZSB2YWx1ZSBhdCB0aGUga2V5IHBhdGgsIG9yIHVuZGVmaW5lZCBpZiBub3RoaW5nIGV4aXN0c1xuICAgKi9cbiAgc3RhdGljIGdldChtb2RlbDogQ29uc3RydWN0b3IsIGtleTogc3RyaW5nKTogYW55O1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBtZXRhZGF0YSBmb3IgYSBtb2RlbCBvciBhIHNwZWNpZmljIGtleSB3aXRoaW4gaXRcbiAgICogQHN1bW1hcnkgV2hlbiBjYWxsZWQgd2l0aCBhIGNvbnN0cnVjdG9yIG9ubHksIHJldHVybnMgdGhlIGVudGlyZSBtZXRhZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBtb2RlbC4gV2hlbiBhIGtleSBwYXRoIGlzIHByb3ZpZGVkLCByZXR1cm5zIHRoZSB2YWx1ZSBzdG9yZWQgYXQgdGhhdCBuZXN0ZWQga2V5LlxuICAgKiBAdGVtcGxhdGUgTVxuICAgKiBAdGVtcGxhdGUgTUVUQVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+IHwgc3RyaW5nfSBtb2RlbCBUaGUgdGFyZ2V0IGNvbnN0cnVjdG9yIHVzZWQgdG8gbG9jYXRlIHRoZSBtZXRhZGF0YSByZWNvcmRcbiAgICogQHBhcmFtIHtzdHJpbmd9IFtrZXldIE9wdGlvbmFsIG5lc3RlZCBrZXkgcGF0aCB0byBmZXRjaCBhIHNwZWNpZmljIHZhbHVlXG4gICAqIEByZXR1cm4ge01FVEF8Knx1bmRlZmluZWR9IFRoZSBtZXRhZGF0YSBvYmplY3QsIHRoZSB2YWx1ZSBhdCB0aGUga2V5IHBhdGgsIG9yIHVuZGVmaW5lZCBpZiBub3RoaW5nIGV4aXN0c1xuICAgKi9cbiAgc3RhdGljIGdldChtb2RlbDogQ29uc3RydWN0b3IsIGtleT86IHN0cmluZykge1xuICAgIGlmIChrZXkgIT09IERlY29yYXRpb25LZXlzLkNPTlNUUlVDVE9SKSBtb2RlbCA9IHRoaXMuY29uc3RyKG1vZGVsKSB8fCBtb2RlbDtcbiAgICBjb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKG1vZGVsLnRvU3RyaW5nKCkpO1xuICAgIHJldHVybiB0aGlzLmlubmVyR2V0KHN5bWJvbCwga2V5KTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGlubmVyR2V0KHN5bWJvbDogc3ltYm9sLCBrZXk/OiBzdHJpbmcpIHtcbiAgICBpZiAoIXRoaXMuX21ldGFkYXRhW3N5bWJvbF0pIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKCFrZXkpIHJldHVybiB0aGlzLl9tZXRhZGF0YVtzeW1ib2xdO1xuICAgIHJldHVybiBnZXRWYWx1ZUJ5U3BsaXR0ZXIodGhpcy5fbWV0YWRhdGFbc3ltYm9sXSwga2V5LCB0aGlzLnNwbGl0dGVyKTtcbiAgfVxuXG4gIHByaXZhdGUgc3RhdGljIGlubmVyU2V0KHN5bWJvbDogc3ltYm9sLCBrZXk6IHN0cmluZywgdmFsdWU6IGFueSkge1xuICAgIGlmICghdGhpcy5fbWV0YWRhdGFbc3ltYm9sXSkgdGhpcy5fbWV0YWRhdGFbc3ltYm9sXSA9IHt9IGFzIGFueTtcbiAgICBzZXRWYWx1ZUJ5U3BsaXR0ZXIodGhpcy5fbWV0YWRhdGFbc3ltYm9sXSwga2V5LCB2YWx1ZSwgdGhpcy5zcGxpdHRlcik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFdyaXRlcyBhIG1ldGFkYXRhIHZhbHVlIGF0IGEgZ2l2ZW4gbmVzdGVkIGtleSBwYXRoXG4gICAqIEBzdW1tYXJ5IEVuc3VyZXMgdGhlIG1ldGFkYXRhIHJlY29yZCBleGlzdHMgZm9yIHRoZSBjb25zdHJ1Y3RvciwgbWlycm9ycyBpdCBvbiB0aGUgY29uc3RydWN0b3Igd2hlbiBlbmFibGVkLCBhbmQgc2V0cyB0aGUgcHJvdmlkZWQgdmFsdWUgb24gdGhlIG5lc3RlZCBrZXkgcGF0aCB1c2luZyB0aGUgY29uZmlndXJlZCBzcGxpdHRlci5cbiAgICogQHRlbXBsYXRlIE1cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPiB8IHN0cmluZ30gbW9kZWwgVGhlIHRhcmdldCBjb25zdHJ1Y3RvciB0byB3aGljaCB0aGUgbWV0YWRhdGEgYmVsb25nc1xuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IFRoZSBuZXN0ZWQga2V5IHBhdGggYXQgd2hpY2ggdG8gc3RvcmUgdGhlIHZhbHVlXG4gICAqIEBwYXJhbSB7Kn0gdmFsdWUgVGhlIHZhbHVlIHRvIHN0b3JlIGluIHRoZSBtZXRhZGF0YVxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgc3RhdGljIHNldChtb2RlbDogQ29uc3RydWN0b3IgfCBzdHJpbmcsIGtleTogc3RyaW5nLCB2YWx1ZTogYW55KTogdm9pZCB7XG4gICAgaWYgKHR5cGVvZiBtb2RlbCAhPT0gXCJzdHJpbmdcIikgbW9kZWwgPSB0aGlzLmNvbnN0cihtb2RlbCkgfHwgbW9kZWw7XG4gICAgY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtb2RlbC50b1N0cmluZygpKTtcbiAgICB0aGlzLmlubmVyU2V0KHN5bWJvbCwga2V5LCB2YWx1ZSk7XG4gICAgaWYgKFxuICAgICAgTWV0YWRhdGEubWlycm9yICYmXG4gICAgICAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZGVsLCB0aGlzLmJhc2VLZXkpXG4gICAgKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kZWwsIHRoaXMuYmFzZUtleSwge1xuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogdGhpcy5fbWV0YWRhdGFbc3ltYm9sXSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXJzIGEgZGVjb3JhdGlvbi1hd2FyZSBsaWJyYXJ5IGFuZCBpdHMgdmVyc2lvblxuICAgKiBAc3VtbWFyeSBTdG9yZXMgdGhlIHZlcnNpb24gc3RyaW5nIGZvciBhbiBpbnRlZ3JhdGluZyBsaWJyYXJ5IHVuZGVyIHRoZSBzaGFyZWQgbGlicmFyaWVzIG1ldGFkYXRhIHN5bWJvbCwgcHJldmVudGluZyBkdXBsaWNhdGUgcmVnaXN0cmF0aW9ucyBmb3IgdGhlIHNhbWUgbGlicmFyeSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbGlicmFyeSBQYWNrYWdlIG5hbWUgb3IgaWRlbnRpZmllciB0byByZWdpc3RlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gdmVyc2lvbiBTZW1hbnRpYyB2ZXJzaW9uIHN0cmluZyBhc3NvY2lhdGVkIHdpdGggdGhlIGxpYnJhcnlcbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBsaWJyYXJ5IGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZFxuICAgKi9cbiAgc3RhdGljIHJlZ2lzdGVyTGlicmFyeShsaWJyYXJ5OiBzdHJpbmcsIHZlcnNpb246IHN0cmluZykge1xuICAgIGNvbnN0IHN5bWJvbCA9IFN5bWJvbC5mb3IoRGVjb3JhdGlvbktleXMuTElCUkFSSUVTKTtcbiAgICBjb25zdCBsaWIgPSB0aGlzLmlubmVyR2V0KHN5bWJvbCwgbGlicmFyeSk7XG4gICAgaWYgKGxpYilcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgYExpYnJhcnkgYWxyZWFkeSAke2xpYnJhcnl9IHJlZ2lzdGVyZWQgd2l0aCB2ZXJzaW9uICR7dmVyc2lvbn1gXG4gICAgICApO1xuICAgIHRoaXMuaW5uZXJTZXQoc3ltYm9sLCBsaWJyYXJ5LCB2ZXJzaW9uKTtcbiAgfVxufVxuIl19
|
|
341
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTWV0YWRhdGEuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvbWV0YWRhdGEvTWV0YWRhdGEudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBNEJBLGdEQW1CQztBQTRCRCxnREF5QkM7QUFuR0Qsa0RBQWlFO0FBQ2pFLDRCQUEwQjtBQUUxQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F1Qkc7QUFDSCxTQUFnQixrQkFBa0IsQ0FDaEMsR0FBd0IsRUFDeEIsSUFBWSxFQUNaLFdBQW1CLDZCQUFpQjtJQUVwQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2xDLElBQUksT0FBTyxHQUFHLEdBQUcsQ0FBQztJQUVsQixLQUFLLE1BQU0sR0FBRyxJQUFJLElBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQ0UsT0FBTyxLQUFLLElBQUk7WUFDaEIsT0FBTyxLQUFLLFNBQVM7WUFDckIsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEdBQUcsQ0FBQztZQUVuRCxPQUFPLFNBQVMsQ0FBQztRQUNuQixPQUFPLEdBQUcsT0FBTyxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQ3pCLENBQUM7SUFFRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0F5Qkc7QUFDSCxTQUFnQixrQkFBa0IsQ0FDaEMsR0FBd0IsRUFDeEIsSUFBWSxFQUNaLEtBQVUsRUFDVixRQUFRLEdBQUcsNkJBQWlCO0lBRTVCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDO0lBQzlELElBQUksSUFBSSxDQUFDLE1BQU0sS0FBSyxDQUFDO1FBQUUsT0FBTztJQUU5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LEVBQUUsT0FBZTtRQUNyRCxNQUFNLE1BQU0sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLDBCQUFjLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDcEQsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsT0FBTyxDQUFDLENBQUM7UUFDM0MsSUFBSSxHQUFHO1lBQ0wsTUFBTSxJQUFJLEtBQUssQ0FDYixtQkFBbUIsT0FBTyw0QkFBNEIsT0FBTyxFQUFFLENBQ2hFLENBQUM7UUFDSixJQUFJLENBQUMsUUFBUSxDQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsT0FBTyxDQUFDLENBQUM7SUFDMUMsQ0FBQztJQUVEOzs7O09BSUc7SUFDSCxNQUFNLENBQUMsU0FBUztRQUNkLE1BQU0sTUFBTSxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsMEJBQWMsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNwRCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JDLENBQUM7SUFFRDs7Ozs7T0FLRztJQUNILE1BQU0sQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFjO1FBQzFCLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDbEMsQ0FBQzs7QUF0U0gsNEJBdVNDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQmFzaWNNZXRhZGF0YSwgQ29uc3RydWN0b3IgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgRGVjb3JhdGlvbktleXMsIE9iamVjdEtleVNwbGl0dGVyIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuaW1wb3J0IFwicmVmbGVjdC1tZXRhZGF0YVwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgYSBuZXN0ZWQgdmFsdWUgZnJvbSBhbiBvYmplY3QgZ2l2ZW4gYSBwYXRoLlxuICogQHN1bW1hcnkgV2Fsa3MgYW4gb2JqZWN0IHN0cnVjdHVyZSB1c2luZyBhIHNwbGl0dGVyLWRlbGltaXRlZCBwYXRoIGFuZCByZXR1cm5zIHRoZSB2YWx1ZSBhdCB0aGF0IGxvY2F0aW9uIG9yIGB1bmRlZmluZWRgIGlmIGFueSBrZXkgaXMgbWlzc2luZy5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gb2JqIE9iamVjdCB0byB0cmF2ZXJzZSBmb3IgdGhlIGxvb2t1cC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFNwbGl0dGVyLWRlbGltaXRlZCBwYXRoIHRvIHRoZSBkZXNpcmVkIHZhbHVlIChlLmcuLCBcImEuYi5jXCIpLlxuICogQHBhcmFtIHtzdHJpbmd9IFtzcGxpdHRlcj1PYmplY3RLZXlTcGxpdHRlcl0gRGVsaW1pdGVyIHVzZWQgdG8gc2VwYXJhdGUgdGhlIHBhdGggc2VnbWVudHMuXG4gKiBAcmV0dXJuIHthbnl8dW5kZWZpbmVkfSBWYWx1ZSByZXNvbHZlZCBhdCB0aGUgZ2l2ZW4gcGF0aCBvciBgdW5kZWZpbmVkYCB3aGVuIG5vdCBmb3VuZC5cbiAqIEBmdW5jdGlvbiBnZXRWYWx1ZUJ5U3BsaXR0ZXJcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgRiBhcyBnZXRWYWx1ZUJ5U3BsaXR0ZXJcbiAqICAgcGFydGljaXBhbnQgTyBhcyBPYmplY3RcbiAqICAgQy0+PkY6IChvYmosIHBhdGgsIHNwbGl0dGVyKVxuICogICBGLT4+Rjogc3BsaXQgcGF0aCBpbnRvIGtleXNcbiAqICAgbG9vcCBmb3IgZWFjaCBrZXlcbiAqICAgICBGLT4+TzogYWNjZXNzIGN1cnJlbnRba2V5XVxuICogICAgIGFsdCBtaXNzaW5nIG9yIG51bGxpc2hcbiAqICAgICAgIEYtLT4+QzogcmV0dXJuIHVuZGVmaW5lZFxuICogICAgIGVuZFxuICogICBlbmRcbiAqICAgRi0tPj5DOiByZXR1cm4gZmluYWwgdmFsdWVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsdWVCeVNwbGl0dGVyKFxuICBvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIHBhdGg6IHN0cmluZyxcbiAgc3BsaXR0ZXI6IHN0cmluZyA9IE9iamVjdEtleVNwbGl0dGVyXG4pOiBhbnkge1xuICBjb25zdCBrZXlzID0gcGF0aC5zcGxpdChzcGxpdHRlcik7XG4gIGxldCBjdXJyZW50ID0gb2JqO1xuXG4gIGZvciAoY29uc3Qga2V5IG9mIGtleXMpIHtcbiAgICBpZiAoXG4gICAgICBjdXJyZW50ID09PSBudWxsIHx8XG4gICAgICBjdXJyZW50ID09PSB1bmRlZmluZWQgfHxcbiAgICAgICFPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwoY3VycmVudCwga2V5KVxuICAgIClcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgY3VycmVudCA9IGN1cnJlbnRba2V5XTtcbiAgfVxuXG4gIHJldHVybiBjdXJyZW50O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBTZXRzIGEgbmVzdGVkIHZhbHVlIG9uIGFuIG9iamVjdCBnaXZlbiBhIHBhdGguXG4gKiBAc3VtbWFyeSBUcmF2ZXJzZXMgb3IgY3JlYXRlcyBpbnRlcm1lZGlhdGUgb2JqZWN0cyBmb2xsb3dpbmcgYSBzcGxpdHRlci1kZWxpbWl0ZWQgcGF0aCBhbmQgYXNzaWducyB0aGUgcHJvdmlkZWQgdmFsdWUgYXQgdGhlIGRlc3RpbmF0aW9uIGtleS5cbiAqIEBwYXJhbSB7UmVjb3JkPHN0cmluZywgYW55Pn0gb2JqIE9iamVjdCB0byBtdXRhdGUgd2hpbGUgZHJpbGxpbmcgaW50byBuZXN0ZWQga2V5cy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBwYXRoIFNwbGl0dGVyLWRlbGltaXRlZCBkZXN0aW5hdGlvbiBwYXRoIChlLmcuLCBcImEuYi5jXCIpLlxuICogQHBhcmFtIHthbnl9IHZhbHVlIFZhbHVlIHRvIHNldCBhdCB0aGUgZGVzdGluYXRpb24gbm9kZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbc3BsaXR0ZXI9T2JqZWN0S2V5U3BsaXR0ZXJdIERlbGltaXRlciB1c2VkIHRvIHNlcGFyYXRlIHRoZSBwYXRoIHNlZ21lbnRzLlxuICogQHJldHVybiB7dm9pZH1cbiAqIEBmdW5jdGlvbiBzZXRWYWx1ZUJ5U3BsaXR0ZXJcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgRiBhcyBzZXRWYWx1ZUJ5U3BsaXR0ZXJcbiAqICAgcGFydGljaXBhbnQgTyBhcyBPYmplY3RcbiAqICAgQy0+PkY6IChvYmosIHBhdGgsIHZhbHVlLCBzcGxpdHRlcilcbiAqICAgRi0+PkY6IHNwbGl0IHBhdGggaW50byBrZXlzXG4gKiAgIGxvb3AgZm9yIGVhY2gga2V5XG4gKiAgICAgYWx0IGtleSBtaXNzaW5nXG4gKiAgICAgICBGLT4+TzogY3JlYXRlIGludGVybWVkaWF0ZSBvYmplY3RcbiAqICAgICBlbHNlIGtleSBleGlzdHNcbiAqICAgICAgIEYtPj5POiBkZXNjZW5kIGludG8gZXhpc3Rpbmcgb2JqZWN0XG4gKiAgICAgZW5kXG4gKiAgIGVuZFxuICogICBGLS0+PkM6IHZvaWRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdGlvblxuICovXG5leHBvcnQgZnVuY3Rpb24gc2V0VmFsdWVCeVNwbGl0dGVyKFxuICBvYmo6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIHBhdGg6IHN0cmluZyxcbiAgdmFsdWU6IGFueSxcbiAgc3BsaXR0ZXIgPSBPYmplY3RLZXlTcGxpdHRlclxuKTogdm9pZCB7XG4gIGNvbnN0IGtleXMgPSBwYXRoLnNwbGl0KHNwbGl0dGVyKS5maWx0ZXIoKGspID0+IGsubGVuZ3RoID4gMCk7XG4gIGlmIChrZXlzLmxlbmd0aCA9PT0gMCkgcmV0dXJuO1xuXG4gIGxldCBjdXJyZW50OiBSZWNvcmQ8YW55LCBhbnk+ID0gb2JqO1xuXG4gIGZvciAobGV0IGkgPSAwOyBpIDwga2V5cy5sZW5ndGggLSAxOyBpKyspIHtcbiAgICBjb25zdCBrZXkgPSBrZXlzW2ldO1xuICAgIGlmIChcbiAgICAgIGN1cnJlbnRba2V5XSA9PT0gdW5kZWZpbmVkIHx8XG4gICAgICBjdXJyZW50W2tleV0gPT09IG51bGwgfHxcbiAgICAgIHR5cGVvZiBjdXJyZW50W2tleV0gIT09IFwib2JqZWN0XCJcbiAgICApIHtcbiAgICAgIGN1cnJlbnRba2V5XSA9IHt9O1xuICAgIH1cbiAgICBjdXJyZW50ID0gY3VycmVudFtrZXldO1xuICB9XG5cbiAgY29uc3QgbGFzdEtleSA9IGtleXNba2V5cy5sZW5ndGggLSAxXTtcbiAgY3VycmVudFtsYXN0S2V5XSA9IHZhbHVlO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDZW50cmFsaXplZCBydW50aW1lIG1ldGFkYXRhIHN0b3JlIGJvdW5kIHRvIGNvbnN0cnVjdG9ycy5cbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIHV0aWxpdGllcyB0byByZWFkIGFuZCB3cml0ZSBzdHJ1Y3R1cmVkIG1ldGFkYXRhIGZvciBjbGFzc2VzIGFuZCB0aGVpciBtZW1iZXJzLCB3aXRoIG9wdGlvbmFsIG1pcnJvcmluZyBvbnRvIHRoZSBjb25zdHJ1Y3RvciB2aWEgYSB3ZWxsLWtub3duIHN5bWJvbCBrZXkuIFN1cHBvcnRzIG5lc3RlZCBrZXkgcGF0aHMgdXNpbmcgYSBjb25maWd1cmFibGUgc3BsaXR0ZXIgYW5kIG9mZmVycyBib3RoIGluc3RhbmNlIGFuZCBzdGF0aWMgQVBJcy5cbiAqIEB0ZW1wbGF0ZSBNIFRoZSBtb2RlbCB0eXBlIHRoZSBtZXRhZGF0YSBiZWxvbmdzIHRvLlxuICogQHRlbXBsYXRlIE1FVEEgRXh0ZW5kcyBCYXNpY01ldGFkYXRhPE0+IHJlcHJlc2VudGluZyB0aGUgbWV0YWRhdGEgc3RydWN0dXJlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtmbGF2b3VyPURlZmF1bHRGbGF2b3VyXSBPcHRpb25hbCBmbGF2b3VyIGlkZW50aWZpZXIgYXBwbGllZCB3aGVuIGluc3RhbnRpYXRpbmcgaGVscGVyIGJ1aWxkZXJzLlxuICogQGNsYXNzXG4gKiBAZXhhbXBsZVxuICogLy8gRGVmaW5lIGFuZCByZWFkIG1ldGFkYXRhIGZvciBhIGNsYXNzXG4gKiBjbGFzcyBVc2VyIHsgbmFtZSE6IHN0cmluZyB9XG4gKiBNZXRhZGF0YS5zZXQoVXNlciwgXCJkZXNjcmlwdGlvbi5jbGFzc1wiLCBcIkEgdXNlciBtb2RlbFwiKTtcbiAqIE1ldGFkYXRhLnNldChVc2VyLCBcInByb3BlcnRpZXMubmFtZVwiLCBTdHJpbmcpO1xuICogY29uc3QgZGVzYyA9IE1ldGFkYXRhLmdldChVc2VyLCBcImRlc2NyaXB0aW9uLmNsYXNzXCIpOyAvLyBcIkEgdXNlciBtb2RlbFwiXG4gKiBjb25zdCB0eXBlID0gTWV0YWRhdGEudHlwZShVc2VyLCBcIm5hbWVcIik7IC8vIFN0cmluZ1xuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDIGFzIENvbnN0cnVjdG9yXG4gKiAgIHBhcnRpY2lwYW50IFMgYXMgTWV0YWRhdGEgKHN0YXRpYylcbiAqICAgQy0+PlM6IHNldChVc2VyLCBcInByb3BlcnRpZXMubmFtZVwiLCBTdHJpbmcpXG4gKiAgIEMtPj5TOiBnZXQoVXNlciwgXCJwcm9wZXJ0aWVzLm5hbWVcIilcbiAqICAgUy0tPj5DOiBTdHJpbmdcbiAqL1xuZXhwb3J0IGNsYXNzIE1ldGFkYXRhIHtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbi1tZW1vcnkgc3RvcmFnZSBvZiBtZXRhZGF0YSBieSBjb25zdHJ1Y3RvciBzeW1ib2xcbiAgICogQHN1bW1hcnkgTWFwcyBhIFN5bWJvbCBkZXJpdmVkIGZyb20gdGhlIGNvbnN0cnVjdG9yIHRvIGl0cyBtZXRhZGF0YSBvYmplY3QsIGVuYWJsaW5nIGVmZmljaWVudCBsb29rdXAuXG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBfbWV0YWRhdGE6IFJlY29yZDxzeW1ib2wsIGFueT4gPSB7fTtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFBhdGggZGVsaW1pdGVyIGZvciBuZXN0ZWQgbWV0YWRhdGEga2V5c1xuICAgKiBAc3VtbWFyeSBVc2VkIGJ5IGdldC9zZXQgb3BlcmF0aW9ucyB0byBuYXZpZ2F0ZSBuZXN0ZWQgc3RydWN0dXJlcywgZGVmYXVsdHMgdG8gT2JqZWN0S2V5U3BsaXR0ZXIuXG4gICAqL1xuICBzdGF0aWMgc3BsaXR0ZXIgPSBPYmplY3RLZXlTcGxpdHRlcjtcbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBTeW1ib2wga2V5IHVzZWQgdG8gbWlycm9yIG1ldGFkYXRhIG9uIHRoZSBjb25zdHJ1Y3RvclxuICAgKiBAc3VtbWFyeSBXaGVuIG1pcnJvcmluZyBpcyBlbmFibGVkLCB0aGUgbWV0YWRhdGEgb2JqZWN0IGlzIGRlZmluZWQgb24gdGhlIGNvbnN0cnVjdG9yIHVuZGVyIHRoaXMgbm9uLWVudW1lcmFibGUga2V5LlxuICAgKi9cbiAgc3RhdGljIGJhc2VLZXkgPSBEZWNvcmF0aW9uS2V5cy5SRUZMRUNUO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENvbnRyb2xzIHdoZXRoZXIgbWV0YWRhdGEgaXMgbWlycm9yZWQgb250byB0aGUgY29uc3RydWN0b3JcbiAgICogQHN1bW1hcnkgV2hlbiB0cnVlLCB0aGUgbWV0YWRhdGEgb2JqZWN0IGlzIGRlZmluZWQgb24gdGhlIGNvbnN0cnVjdG9yIHVuZGVyIHRoZSBub24tZW51bWVyYWJsZSBiYXNlS2V5LlxuICAgKi9cbiAgc3RhdGljIG1pcnJvcjogYm9vbGVhbiA9IHRydWU7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBMaXN0cyBrbm93biBwcm9wZXJ0eSBrZXlzIGZvciBhIG1vZGVsLlxuICAgKiBAc3VtbWFyeSBSZWFkcyB0aGUgbWV0YWRhdGEgZW50cnkgYW5kIHJldHVybnMgdGhlIG5hbWVzIG9mIHByb3BlcnRpZXMgdGhhdCBoYXZlIHJlY29yZGVkIHR5cGUgaW5mb3JtYXRpb24uXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3J9IG1vZGVsIFRhcmdldCBjb25zdHJ1Y3RvciB3aG9zZSBwcm9wZXJ0eSBtZXRhZGF0YSBzaG91bGQgYmUgaW5zcGVjdGVkLlxuICAgKiBAcmV0dXJuIHtzdHJpbmdbXXx1bmRlZmluZWR9IEFycmF5IG9mIHByb3BlcnR5IG5hbWVzIG9yIGB1bmRlZmluZWRgIGlmIG5vIG1ldGFkYXRhIGV4aXN0cy5cbiAgICovXG4gIHN0YXRpYyBwcm9wZXJ0aWVzKG1vZGVsOiBDb25zdHJ1Y3Rvcik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5nZXQobW9kZWwpO1xuICAgIGlmICghbWV0YSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMobWV0YS5wcm9wZXJ0aWVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gTGlzdHMga25vd24gbWV0aG9kcyBmb3IgYSBtb2RlbC5cbiAgICogQHN1bW1hcnkgUmVhZHMgdGhlIG1ldGFkYXRhIGVudHJ5IGFuZCByZXR1cm5zIHRoZSBtZXRob2QgbmFtZXMgdGhhdCBoYXZlIHJlY29yZGVkIHNpZ25hdHVyZSBtZXRhZGF0YSBmb3IgdGhlIHByb3ZpZGVkIGNvbnN0cnVjdG9yLlxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yfSBtb2RlbCBUYXJnZXQgY29uc3RydWN0b3Igd2hvc2UgbWV0aG9kIG1ldGFkYXRhIHNob3VsZCBiZSBpbnNwZWN0ZWQuXG4gICAqIEByZXR1cm4ge3N0cmluZ1tdfHVuZGVmaW5lZH0gQXJyYXkgb2YgbWV0aG9kIG5hbWVzIG9yIGB1bmRlZmluZWRgIGlmIG5vIG1ldGFkYXRhIGV4aXN0cy5cbiAgICovXG4gIHN0YXRpYyBtZXRob2RzKG1vZGVsOiBDb25zdHJ1Y3Rvcik6IHN0cmluZ1tdIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBtZXRhID0gdGhpcy5nZXQobW9kZWwsIERlY29yYXRpb25LZXlzLk1FVEhPRFMpO1xuICAgIGlmICghbWV0YSkgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICByZXR1cm4gT2JqZWN0LmtleXMobWV0YSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBhIGh1bWFuLXJlYWRhYmxlIGRlc2NyaXB0aW9uIGZvciBhIGNsYXNzIG9yIGEgcHJvcGVydHkuXG4gICAqIEBzdW1tYXJ5IExvb2tzIHVwIHRoZSBkZXNjcmlwdGlvbiBzdG9yZWQgdW5kZXIgdGhlIG1ldGFkYXRhIFwiZGVzY3JpcHRpb25cIiBtYXAuIElmIGEgcHJvcGVydHkga2V5IGlzIHByb3ZpZGVkLCByZXR1cm5zIHRoZSBwcm9wZXJ0eSdzIGRlc2NyaXB0aW9uOyBvdGhlcndpc2UgcmV0dXJucyB0aGUgY2xhc3MgZGVzY3JpcHRpb24uXG4gICAqIEB0ZW1wbGF0ZSBNXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8TT59IG1vZGVsIFRhcmdldCBjb25zdHJ1Y3RvciB3aG9zZSBkZXNjcmlwdGlvbiBpcyBiZWluZyByZXRyaWV2ZWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBbcHJvcF0gT3B0aW9uYWwgcHJvcGVydHkga2V5ICh0eXBlZCBhcyBga2V5b2YgTWApIGZvciB3aGljaCB0byBmZXRjaCB0aGUgZGVzY3JpcHRpb24uXG4gICAqIEByZXR1cm4ge3N0cmluZ3x1bmRlZmluZWR9IERlc2NyaXB0aW9uIHRleHQgaWYgcHJlc2VudCwgb3RoZXJ3aXNlIGB1bmRlZmluZWRgLlxuICAgKi9cbiAgc3RhdGljIGRlc2NyaXB0aW9uPE0+KFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBwcm9wPzoga2V5b2YgTVxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmdldChcbiAgICAgIG1vZGVsLFxuICAgICAgW0RlY29yYXRpb25LZXlzLkRFU0NSSVBUSU9OLCBwcm9wID8gcHJvcCA6IERlY29yYXRpb25LZXlzLkNMQVNTXS5qb2luKFxuICAgICAgICB0aGlzLnNwbGl0dGVyXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSByZWNvcmRlZCBwYXJhbXMgZm9yIGEgbWV0aG9kLlxuICAgKiBAc3VtbWFyeSBSZWFkcyB0aGUgbWV0YWRhdGEgZW50cnkgdW5kZXIgYG1ldGhvZHMuPHByb3A+LmRlc2lnbjpwYXJhbXR5cGVzYCB0byByZXR1cm4gdGhlIHBhcmFtZXRlciBjb25zdHJ1Y3RvcnMgZm9yIHRoZSBnaXZlbiBtZXRob2QuXG4gICAqIEB0ZW1wbGF0ZSBNXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8TT59IG1vZGVsIFRhcmdldCBjb25zdHJ1Y3RvciBvd25pbmcgdGhlIG1ldGhvZCBtZXRhZGF0YS5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHByb3AgTWV0aG9kIG5hbWUgd2hvc2UgcGFyYW1ldGVycyBzaG91bGQgYmUgZmV0Y2hlZC5cbiAgICogQHJldHVybiB7YW55W118dW5kZWZpbmVkfSBBcnJheSBvZiBjb25zdHJ1Y3RvciByZWZlcmVuY2VzIGRlc2NyaWJpbmcgZWFjaCBwYXJhbWV0ZXIgb3IgYHVuZGVmaW5lZGAgd2hlbiBub3QgYXZhaWxhYmxlLlxuICAgKi9cbiAgc3RhdGljIHBhcmFtczxNPihtb2RlbDogQ29uc3RydWN0b3I8TT4sIHByb3A6IHN0cmluZyk6IGFueVtdIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoXG4gICAgICBtb2RlbCxcbiAgICAgIFtEZWNvcmF0aW9uS2V5cy5NRVRIT0RTLCBwcm9wLCBEZWNvcmF0aW9uS2V5cy5ERVNJR05fUEFSQU1TXS5qb2luKFxuICAgICAgICB0aGlzLnNwbGl0dGVyXG4gICAgICApXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgc2luZ2xlIHJlY29yZGVkIHBhcmFtZXRlciB0eXBlIGZvciBhIG1ldGhvZC5cbiAgICogQHN1bW1hcnkgTG9va3MgdXAgdGhlIHBhcmFtZXRlciBtZXRhZGF0YSBmb3IgdGhlIHByb3ZpZGVkIGluZGV4LCBlbmZvcmNpbmcgYm91bmRzIGFuZCByZXR1cm5pbmcgdGhlIGNvbnN0cnVjdG9yIHJlZmVyZW5jZSBmb3IgdGhhdCBhcmd1bWVudC5cbiAgICogQHRlbXBsYXRlIE1cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgVGFyZ2V0IGNvbnN0cnVjdG9yIG93bmluZyB0aGUgbWV0aG9kIG1ldGFkYXRhLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gcHJvcCBNZXRob2QgbmFtZSB3aG9zZSBwYXJhbWV0ZXIgc2hvdWxkIGJlIHJldHVybmVkLlxuICAgKiBAcGFyYW0ge251bWJlcn0gaW5kZXggWmVyby1iYXNlZCBpbmRleCBvZiB0aGUgZGVzaXJlZCBwYXJhbWV0ZXIgbWV0YWRhdGEuXG4gICAqIEByZXR1cm4ge2FueXx1bmRlZmluZWR9IENvbnN0cnVjdG9yIHJlZmVyZW5jZSBmb3IgdGhlIHBhcmFtZXRlciBvciBgdW5kZWZpbmVkYCBpZiBub3QgcmVjb3JkZWQuXG4gICAqL1xuICBzdGF0aWMgcGFyYW08TT4oXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+LFxuICAgIHByb3A6IHN0cmluZyxcbiAgICBpbmRleDogbnVtYmVyXG4gICk6IGFueSB8IHVuZGVmaW5lZCB7XG4gICAgY29uc3QgcGFyYW1zID0gdGhpcy5wYXJhbXMobW9kZWwsIHByb3ApO1xuICAgIGlmICghcGFyYW1zKSByZXR1cm4gdW5kZWZpbmVkO1xuICAgIGlmIChpbmRleCA+IHBhcmFtcy5sZW5ndGggLSAxKVxuICAgICAgdGhyb3cgbmV3IEVycm9yKFxuICAgICAgICBgUGFyYW1ldGVyIGluZGV4ICR7aW5kZXh9IG91dCBvZiByYW5nZSBmb3IgJHtTdHJpbmcocHJvcCl9YFxuICAgICAgKTtcbiAgICByZXR1cm4gcGFyYW1zW2luZGV4XTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSByZWNvcmRlZCByZXR1cm4gdHlwZSBmb3IgYSBtZXRob2QuXG4gICAqIEBzdW1tYXJ5IFJlYWRzIHRoZSBtZXRhZGF0YSBlbnRyeSB1bmRlciBgbWV0aG9kcy48cHJvcD4uZGVzaWduOnJldHVybnR5cGVgIHRvIHJldHVybiB0aGUgcmV0dXJuIHR5cGUgZm9yIHRoZSBnaXZlbiBtZXRob2QuXG4gICAqIEB0ZW1wbGF0ZSBNXG4gICAqIEBwYXJhbSB7Q29uc3RydWN0b3I8TT59IG1vZGVsIFRhcmdldCBjb25zdHJ1Y3RvciB3aG9zZSBtZXRob2QgbWV0YWRhdGEgc2hvdWxkIGJlIGluc3BlY3RlZC5cbiAgICogQHBhcmFtIHtzdHJpbmd9IHByb3AgTWV0aG9kIG5hbWUgd2hvc2UgcmV0dXJuIHR5cGUgc2hvdWxkIGJlIGZldGNoZWQuXG4gICAqIEByZXR1cm4ge2FueXx1bmRlZmluZWR9IENvbnN0cnVjdG9yIHJlZmVyZW5jZSBmb3IgdGhlIHJldHVybiB0eXBlIG9yIGB1bmRlZmluZWRgIHdoZW4gbm90IGF2YWlsYWJsZS5cbiAgICovXG4gIHN0YXRpYyByZXR1cm48TT4obW9kZWw6IENvbnN0cnVjdG9yPE0+LCBwcm9wOiBzdHJpbmcpOiBhbnkgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLmdldChcbiAgICAgIG1vZGVsLFxuICAgICAgW0RlY29yYXRpb25LZXlzLk1FVEhPRFMsIHByb3AsIERlY29yYXRpb25LZXlzLkRFU0lHTl9SRVRVUk5dLmpvaW4oXG4gICAgICAgIHRoaXMuc3BsaXR0ZXJcbiAgICAgIClcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBSZXRyaWV2ZXMgdGhlIHJlY29yZGVkIGRlc2lnbiB0eXBlIGZvciBhIHByb3BlcnR5LlxuICAgKiBAc3VtbWFyeSBSZWFkcyB0aGUgbWV0YWRhdGEgZW50cnkgdW5kZXIgYHByb3BlcnRpZXMuPHByb3A+YCB0byByZXR1cm4gdGhlIGNvbnN0cnVjdG9yIHJlY29yZGVkIGZvciB0aGUgZ2l2ZW4gcHJvcGVydHkgbmFtZS5cbiAgICogQHBhcmFtIHtDb25zdHJ1Y3Rvcn0gbW9kZWwgVGFyZ2V0IGNvbnN0cnVjdG9yIHdob3NlIHByb3BlcnR5IG1ldGFkYXRhIHNob3VsZCBiZSBpbnNwZWN0ZWQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIFByb3BlcnR5IG5hbWUgd2hvc2UgdHlwZSBtZXRhZGF0YSBzaG91bGQgYmUgcmV0dXJuZWQuXG4gICAqIEByZXR1cm4ge0NvbnN0cnVjdG9yfHVuZGVmaW5lZH0gQ29uc3RydWN0b3IgcmVmZXJlbmNlIGZvciB0aGUgcHJvcGVydHkgdHlwZSBvciBgdW5kZWZpbmVkYCBpZiBub3QgYXZhaWxhYmxlLlxuICAgKi9cbiAgc3RhdGljIHR5cGUobW9kZWw6IENvbnN0cnVjdG9yLCBwcm9wOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gdGhpcy5nZXQoXG4gICAgICBtb2RlbCxcbiAgICAgIFtEZWNvcmF0aW9uS2V5cy5QUk9QRVJUSUVTLCBwcm9wXS5qb2luKHRoaXMuc3BsaXR0ZXIpXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVzb2x2ZXMgdGhlIGNhbm9uaWNhbCBjb25zdHJ1Y3RvciBhc3NvY2lhdGVkIHdpdGggdGhlIHByb3ZpZGVkIG1vZGVsIGhhbmRsZS5cbiAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgc3RvcmVkIGNvbnN0cnVjdG9yIHJlZmVyZW5jZSB3aGVuIHRoZSBwcm92aWRlZCBtb2RlbCBpcyBhIHByb3h5IG9yIHJlZHVjZWQgdmFsdWUuIEZhbGxzIGJhY2sgdG8gdGhlIG9yaWdpbmFsIG1vZGVsIHdoZW4gbm8gY29uc3RydWN0b3IgbWV0YWRhdGEgaGFzIGJlZW4gcmVjb3JkZWQgeWV0LlxuICAgKiBAdGVtcGxhdGUgTVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBtb2RlbCBNb2RlbCB1c2VkIHdoZW4gcmVjb3JkaW5nIG1ldGFkYXRhLlxuICAgKiBAcmV0dXJuIHtDb25zdHJ1Y3RvcjxNPnx1bmRlZmluZWR9IENhbm9uaWNhbCBjb25zdHJ1Y3RvciBpZiBzdG9yZWQsIG90aGVyd2lzZSBgdW5kZWZpbmVkYC5cbiAgICovXG4gIHN0YXRpYyBjb25zdHI8TT4obW9kZWw6IENvbnN0cnVjdG9yPE0+KSB7XG4gICAgcmV0dXJuIG1vZGVsW0RlY29yYXRpb25LZXlzLkNPTlNUUlVDVE9SIGFzIGtleW9mIHR5cGVvZiBtb2RlbF07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBtZXRhZGF0YSBmb3IgYSBtb2RlbCBvciBhIHNwZWNpZmljIGtleSB3aXRoaW4gaXQuXG4gICAqIEBzdW1tYXJ5IFdoZW4gY2FsbGVkIHdpdGggYSBjb25zdHJ1Y3RvciBvbmx5LCByZXR1cm5zIHRoZSBlbnRpcmUgbWV0YWRhdGEgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgbW9kZWwuIFdoZW4gYSBrZXkgcGF0aCBpcyBwcm92aWRlZCwgcmV0dXJucyB0aGUgdmFsdWUgc3RvcmVkIGF0IHRoYXQgbmVzdGVkIGtleS5cbiAgICogQHRlbXBsYXRlIE1cbiAgICogQHRlbXBsYXRlIE1FVEFcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgVGFyZ2V0IGNvbnN0cnVjdG9yIHVzZWQgdG8gbG9jYXRlIHRoZSBtZXRhZGF0YSByZWNvcmQuXG4gICAqIEByZXR1cm4ge01FVEF8dW5kZWZpbmVkfSBNZXRhZGF0YSBvYmplY3QsIHRoZSB2YWx1ZSBhdCB0aGUga2V5IHBhdGgsIG9yIGB1bmRlZmluZWRgIGlmIG5vdGhpbmcgZXhpc3RzLlxuICAgKi9cbiAgc3RhdGljIGdldDxNLCBNRVRBIGV4dGVuZHMgQmFzaWNNZXRhZGF0YTxNPiA9IEJhc2ljTWV0YWRhdGE8TT4+KFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPlxuICApOiBNRVRBIHwgdW5kZWZpbmVkO1xuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBtZXRhZGF0YSBmb3IgYSBtb2RlbCBvciBhIHNwZWNpZmljIGtleSB3aXRoaW4gaXQuXG4gICAqIEBzdW1tYXJ5IFdoZW4gY2FsbGVkIHdpdGggYSBjb25zdHJ1Y3RvciBvbmx5LCByZXR1cm5zIHRoZSBlbnRpcmUgbWV0YWRhdGEgb2JqZWN0IGFzc29jaWF0ZWQgd2l0aCB0aGUgbW9kZWwuIFdoZW4gYSBrZXkgcGF0aCBpcyBwcm92aWRlZCwgcmV0dXJucyB0aGUgdmFsdWUgc3RvcmVkIGF0IHRoYXQgbmVzdGVkIGtleS5cbiAgICogQHRlbXBsYXRlIE1cbiAgICogQHRlbXBsYXRlIE1FVEFcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgVGFyZ2V0IGNvbnN0cnVjdG9yIHVzZWQgdG8gbG9jYXRlIHRoZSBtZXRhZGF0YSByZWNvcmQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgTmVzdGVkIGtleSBwYXRoIHRvIGZldGNoIGEgc3BlY2lmaWMgdmFsdWUuXG4gICAqIEByZXR1cm4ge01FVEF8Knx1bmRlZmluZWR9IE1ldGFkYXRhIG9iamVjdCwgdGhlIHZhbHVlIGF0IHRoZSBrZXkgcGF0aCwgb3IgYHVuZGVmaW5lZGAgaWYgbm90aGluZyBleGlzdHMuXG4gICAqL1xuICBzdGF0aWMgZ2V0KG1vZGVsOiBDb25zdHJ1Y3Rvciwga2V5OiBzdHJpbmcpOiBhbnk7XG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG1ldGFkYXRhIGZvciBhIG1vZGVsIG9yIGEgc3BlY2lmaWMga2V5IHdpdGhpbiBpdC5cbiAgICogQHN1bW1hcnkgV2hlbiBjYWxsZWQgd2l0aCBhIGNvbnN0cnVjdG9yIG9ubHksIHJldHVybnMgdGhlIGVudGlyZSBtZXRhZGF0YSBvYmplY3QgYXNzb2NpYXRlZCB3aXRoIHRoZSBtb2RlbC4gV2hlbiBhIGtleSBwYXRoIGlzIHByb3ZpZGVkLCByZXR1cm5zIHRoZSB2YWx1ZSBzdG9yZWQgYXQgdGhhdCBuZXN0ZWQga2V5LlxuICAgKiBAdGVtcGxhdGUgTVxuICAgKiBAdGVtcGxhdGUgTUVUQVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fHN0cmluZ30gbW9kZWwgVGFyZ2V0IGNvbnN0cnVjdG9yIHVzZWQgdG8gbG9jYXRlIHRoZSBtZXRhZGF0YSByZWNvcmQgb3IgYSBwcmUtcmVzb2x2ZWQgc3ltYm9sIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBba2V5XSBPcHRpb25hbCBuZXN0ZWQga2V5IHBhdGggdG8gZmV0Y2ggYSBzcGVjaWZpYyB2YWx1ZS5cbiAgICogQHJldHVybiB7TUVUQXwqfHVuZGVmaW5lZH0gTWV0YWRhdGEgb2JqZWN0LCB0aGUgdmFsdWUgYXQgdGhlIGtleSBwYXRoLCBvciBgdW5kZWZpbmVkYCBpZiBub3RoaW5nIGV4aXN0cy5cbiAgICovXG4gIHN0YXRpYyBnZXQobW9kZWw6IENvbnN0cnVjdG9yLCBrZXk/OiBzdHJpbmcpIHtcbiAgICBpZiAoa2V5ID09PSBEZWNvcmF0aW9uS2V5cy5DT05TVFJVQ1RPUikgcmV0dXJuIHRoaXMuY29uc3RyKG1vZGVsKTtcbiAgICBpZiAoa2V5ICE9PSBEZWNvcmF0aW9uS2V5cy5DT05TVFJVQ1RPUikgbW9kZWwgPSB0aGlzLmNvbnN0cihtb2RlbCkgfHwgbW9kZWw7XG4gICAgY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtb2RlbC50b1N0cmluZygpKTtcbiAgICByZXR1cm4gdGhpcy5pbm5lckdldChzeW1ib2wsIGtleSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBtZXRhZGF0YSBzdG9yZWQgdW5kZXIgYSBzeW1ib2wga2V5LlxuICAgKiBAc3VtbWFyeSBJbnRlcm5hbCBoZWxwZXIgdGhhdCByZXNvbHZlcyBhbmQgb3B0aW9uYWxseSBkcmlsbHMgaW50byB0aGUgaW4tbWVtb3J5IG1ldGFkYXRhIG1hcCBmb3IgdGhlIHByb3ZpZGVkIHN5bWJvbCBhbmQga2V5IHBhdGguXG4gICAqIEBwYXJhbSB7c3ltYm9sfSBzeW1ib2wgU3ltYm9sIHJlcHJlc2VudGluZyB0aGUgbWV0YWRhdGEgYnVja2V0LlxuICAgKiBAcGFyYW0ge3N0cmluZ3xzeW1ib2x9IFtrZXldIE9wdGlvbmFsIG5lc3RlZCBrZXkgcmVmZXJlbmNpbmcgYSBzcGVjaWZpYyBtZXRhZGF0YSBlbnRyeS5cbiAgICogQHJldHVybiB7YW55fSBTdG9yZWQgbWV0YWRhdGEgb2JqZWN0IG9yIHZhbHVlIGZvciB0aGUgcHJvdmlkZWQga2V5LCBvciBgdW5kZWZpbmVkYCB3aGVuIGFic2VudC5cbiAgICovXG4gIHByaXZhdGUgc3RhdGljIGlubmVyR2V0KHN5bWJvbDogc3ltYm9sLCBrZXk/OiBzdHJpbmcgfCBzeW1ib2wpIHtcbiAgICBpZiAoIXRoaXMuX21ldGFkYXRhW3N5bWJvbF0pIHJldHVybiB1bmRlZmluZWQ7XG4gICAgaWYgKCFrZXkpIHJldHVybiB0aGlzLl9tZXRhZGF0YVtzeW1ib2xdO1xuICAgIGlmICh0eXBlb2Yga2V5ID09PSBcInN0cmluZ1wiKVxuICAgICAgcmV0dXJuIGdldFZhbHVlQnlTcGxpdHRlcih0aGlzLl9tZXRhZGF0YVtzeW1ib2xdLCBrZXksIHRoaXMuc3BsaXR0ZXIpO1xuICAgIHJldHVybiB0aGlzLl9tZXRhZGF0YVtzeW1ib2xdW2tleV07XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFdyaXRlcyBtZXRhZGF0YSB1bmRlciBhIHN5bWJvbCBrZXkuXG4gICAqIEBzdW1tYXJ5IEludGVybmFsIGhlbHBlciB0aGF0IGVuc3VyZXMgdGhlIG1ldGFkYXRhIGJ1Y2tldCBleGlzdHMgZm9yIHRoZSBwcm92aWRlZCBzeW1ib2wgYW5kIHBlcnNpc3RzIHRoZSBnaXZlbiB2YWx1ZSwgZHJpbGxpbmcgaW50byBuZXN0ZWQgc3RydWN0dXJlcyB3aGVuIHRoZSBrZXkgaXMgYSBzdHJpbmcgcGF0aC5cbiAgICogQHBhcmFtIHtzeW1ib2x9IHN5bWJvbCBTeW1ib2wgcmVwcmVzZW50aW5nIHRoZSBtZXRhZGF0YSBidWNrZXQuXG4gICAqIEBwYXJhbSB7c3RyaW5nfHN5bWJvbH0ga2V5IE5lc3RlZCBrZXkgcGF0aCBvciBkaXJlY3Qgc3ltYm9sIHVuZGVyIHdoaWNoIHRvIHN0b3JlIHRoZSBtZXRhZGF0YSB2YWx1ZS5cbiAgICogQHBhcmFtIHthbnl9IHZhbHVlIFZhbHVlIHBlcnNpc3RlZCBpbiB0aGUgbWV0YWRhdGEgc3RvcmUuXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBwcml2YXRlIHN0YXRpYyBpbm5lclNldChzeW1ib2w6IHN5bWJvbCwga2V5OiBzdHJpbmcgfCBzeW1ib2wsIHZhbHVlOiBhbnkpIHtcbiAgICBpZiAoIXRoaXMuX21ldGFkYXRhW3N5bWJvbF0pIHRoaXMuX21ldGFkYXRhW3N5bWJvbF0gPSB7fSBhcyBhbnk7XG4gICAgaWYgKHR5cGVvZiBrZXkgPT09IFwic3RyaW5nXCIpXG4gICAgICByZXR1cm4gc2V0VmFsdWVCeVNwbGl0dGVyKFxuICAgICAgICB0aGlzLl9tZXRhZGF0YVtzeW1ib2xdLFxuICAgICAgICBrZXksXG4gICAgICAgIHZhbHVlLFxuICAgICAgICB0aGlzLnNwbGl0dGVyXG4gICAgICApO1xuICAgIHRoaXMuX21ldGFkYXRhW3N5bWJvbF1ba2V5XSA9IHZhbHVlO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBXcml0ZXMgYSBtZXRhZGF0YSB2YWx1ZSBhdCBhIGdpdmVuIG5lc3RlZCBrZXkgcGF0aC5cbiAgICogQHN1bW1hcnkgRW5zdXJlcyB0aGUgbWV0YWRhdGEgcmVjb3JkIGV4aXN0cyBmb3IgdGhlIGNvbnN0cnVjdG9yLCBtaXJyb3JzIGl0IG9uIHRoZSBjb25zdHJ1Y3RvciB3aGVuIGVuYWJsZWQsIGFuZCBzZXRzIHRoZSBwcm92aWRlZCB2YWx1ZSBvbiB0aGUgbmVzdGVkIGtleSBwYXRoIHVzaW5nIHRoZSBjb25maWd1cmVkIHNwbGl0dGVyLlxuICAgKiBAdGVtcGxhdGUgTVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fHN0cmluZ30gbW9kZWwgVGFyZ2V0IGNvbnN0cnVjdG9yIHRvIHdoaWNoIHRoZSBtZXRhZGF0YSBiZWxvbmdzIG9yIGEgZGlyZWN0IGlkZW50aWZpZXIgc3RyaW5nLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IE5lc3RlZCBrZXkgcGF0aCBhdCB3aGljaCB0byBzdG9yZSB0aGUgdmFsdWUuXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZSBWYWx1ZSB0byBzdG9yZSBpbiB0aGUgbWV0YWRhdGEuXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgc2V0KG1vZGVsOiBDb25zdHJ1Y3RvciB8IHN0cmluZywga2V5OiBzdHJpbmcsIHZhbHVlOiBhbnkpOiB2b2lkIHtcbiAgICBpZiAoa2V5ID09PSBEZWNvcmF0aW9uS2V5cy5DT05TVFJVQ1RPUikge1xuICAgICAgT2JqZWN0LmRlZmluZVByb3BlcnR5KG1vZGVsLCBEZWNvcmF0aW9uS2V5cy5DT05TVFJVQ1RPUiwge1xuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICB9KTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHR5cGVvZiBtb2RlbCAhPT0gXCJzdHJpbmdcIikgbW9kZWwgPSB0aGlzLmNvbnN0cihtb2RlbCkgfHwgbW9kZWw7XG4gICAgY29uc3Qgc3ltYm9sID0gU3ltYm9sLmZvcihtb2RlbC50b1N0cmluZygpKTtcbiAgICB0aGlzLmlubmVyU2V0KHN5bWJvbCwga2V5LCB2YWx1ZSk7XG4gICAgaWYgKFxuICAgICAgTWV0YWRhdGEubWlycm9yICYmXG4gICAgICAhT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZGVsLCB0aGlzLmJhc2VLZXkpXG4gICAgKSB7XG4gICAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkobW9kZWwsIHRoaXMuYmFzZUtleSwge1xuICAgICAgICBlbnVtZXJhYmxlOiBmYWxzZSxcbiAgICAgICAgY29uZmlndXJhYmxlOiBmYWxzZSxcbiAgICAgICAgd3JpdGFibGU6IGZhbHNlLFxuICAgICAgICB2YWx1ZTogdGhpcy5fbWV0YWRhdGFbc3ltYm9sXSxcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmVnaXN0ZXJzIGEgZGVjb3JhdGlvbi1hd2FyZSBsaWJyYXJ5IGFuZCBpdHMgdmVyc2lvbi5cbiAgICogQHN1bW1hcnkgU3RvcmVzIHRoZSB2ZXJzaW9uIHN0cmluZyBmb3IgYW4gaW50ZWdyYXRpbmcgbGlicmFyeSB1bmRlciB0aGUgc2hhcmVkIGxpYnJhcmllcyBtZXRhZGF0YSBzeW1ib2wsIHByZXZlbnRpbmcgZHVwbGljYXRlIHJlZ2lzdHJhdGlvbnMgZm9yIHRoZSBzYW1lIGxpYnJhcnkgaWRlbnRpZmllci5cbiAgICogQHBhcmFtIHtzdHJpbmd9IGxpYnJhcnkgUGFja2FnZSBuYW1lIG9yIGlkZW50aWZpZXIgdG8gcmVnaXN0ZXIuXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB2ZXJzaW9uIFNlbWFudGljIHZlcnNpb24gc3RyaW5nIGFzc29jaWF0ZWQgd2l0aCB0aGUgbGlicmFyeS5cbiAgICogQHJldHVybiB7dm9pZH1cbiAgICogQHRocm93cyB7RXJyb3J9IElmIHRoZSBsaWJyYXJ5IGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZC5cbiAgICovXG4gIHN0YXRpYyByZWdpc3RlckxpYnJhcnkobGlicmFyeTogc3RyaW5nLCB2ZXJzaW9uOiBzdHJpbmcpIHtcbiAgICBjb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKERlY29yYXRpb25LZXlzLkxJQlJBUklFUyk7XG4gICAgY29uc3QgbGliID0gdGhpcy5pbm5lckdldChzeW1ib2wsIGxpYnJhcnkpO1xuICAgIGlmIChsaWIpXG4gICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBMaWJyYXJ5IGFscmVhZHkgJHtsaWJyYXJ5fSByZWdpc3RlcmVkIHdpdGggdmVyc2lvbiAke3ZlcnNpb259YFxuICAgICAgKTtcbiAgICB0aGlzLmlubmVyU2V0KHN5bWJvbCwgbGlicmFyeSwgdmVyc2lvbik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIExpc3RzIHJlZ2lzdGVyZWQgZGVjb3JhdGlvbi1hd2FyZSBsaWJyYXJpZXMuXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGluLW1lbW9yeSBtYXAgb2YgbGlicmFyeSBpZGVudGlmaWVycyB0byBzZW1hbnRpYyB2ZXJzaW9ucyB0aGF0IGhhdmUgYmVlbiByZWdpc3RlcmVkIHdpdGggdGhlIERlY29yYXRpb24gbWV0YWRhdGEgc3RvcmUuXG4gICAqIEByZXR1cm4ge1JlY29yZDxzdHJpbmcsIHN0cmluZz59IE1hcCBvZiByZWdpc3RlcmVkIGxpYnJhcnkgaWRlbnRpZmllcnMgdG8gdGhlaXIgdmVyc2lvbiBzdHJpbmdzLlxuICAgKi9cbiAgc3RhdGljIGxpYnJhcmllcygpOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHtcbiAgICBjb25zdCBzeW1ib2wgPSBTeW1ib2wuZm9yKERlY29yYXRpb25LZXlzLkxJQlJBUklFUyk7XG4gICAgcmV0dXJuIHRoaXMuaW5uZXJHZXQoc3ltYm9sKSB8fCB7fTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gSm9pbnMgcGF0aCBzZWdtZW50cyB1c2luZyB0aGUgY3VycmVudCBzcGxpdHRlci5cbiAgICogQHN1bW1hcnkgQ29uc3RydWN0cyBhIG5lc3RlZCBtZXRhZGF0YSBrZXkgYnkgY29uY2F0ZW5hdGluZyBzdHJpbmcgc2VnbWVudHMgd2l0aCB0aGUgY29uZmlndXJlZCBzcGxpdHRlciBmb3IgdXNlIHdpdGggdGhlIG1ldGFkYXRhIHN0b3JlLlxuICAgKiBAcGFyYW0gey4uLnN0cmluZ30gc3RycyBLZXkgc2VnbWVudHMgdG8gam9pbiBpbnRvIGEgZnVsbCBtZXRhZGF0YSBwYXRoLlxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFNwbGl0dGVyLWpvaW5lZCBtZXRhZGF0YSBrZXkuXG4gICAqL1xuICBzdGF0aWMga2V5KC4uLnN0cnM6IHN0cmluZ1tdKSB7XG4gICAgcmV0dXJuIHN0cnMuam9pbih0aGlzLnNwbGl0dGVyKTtcbiAgfVxufVxuIl19
|