@decaf-ts/decorator-validation 1.7.7 → 1.7.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.
Files changed (77) hide show
  1. package/dist/decorator-validation.cjs +629 -254
  2. package/dist/decorator-validation.esm.cjs +622 -255
  3. package/lib/constants/validation.cjs +3 -2
  4. package/lib/constants/validation.d.ts +1 -0
  5. package/lib/esm/constants/validation.d.ts +1 -0
  6. package/lib/esm/constants/validation.js +2 -1
  7. package/lib/esm/index.d.ts +1 -1
  8. package/lib/esm/index.js +1 -1
  9. package/lib/esm/mcp/ModelContextProtocol.d.ts +14 -22
  10. package/lib/esm/mcp/ModelContextProtocol.js +55 -51
  11. package/lib/esm/model/Model.d.ts +11 -8
  12. package/lib/esm/model/Model.js +12 -6
  13. package/lib/esm/model/decorators.js +1 -1
  14. package/lib/esm/model/types.d.ts +37 -9
  15. package/lib/esm/model/types.js +1 -1
  16. package/lib/esm/model/utils.d.ts +14 -1
  17. package/lib/esm/model/utils.js +15 -1
  18. package/lib/esm/model/validation.d.ts +107 -5
  19. package/lib/esm/model/validation.js +329 -124
  20. package/lib/esm/types/index.d.ts +1 -0
  21. package/lib/esm/types/index.js +2 -0
  22. package/lib/esm/types/validation.d.ts +25 -0
  23. package/lib/esm/types/validation.js +2 -0
  24. package/lib/esm/validation/Validators/AsyncValidator.d.ts +72 -0
  25. package/lib/esm/validation/Validators/AsyncValidator.js +61 -0
  26. package/lib/esm/validation/Validators/BaseValidator.d.ts +118 -0
  27. package/lib/esm/validation/Validators/BaseValidator.js +117 -0
  28. package/lib/esm/validation/Validators/ListValidator.js +2 -2
  29. package/lib/esm/validation/Validators/MinLengthValidator.d.ts +1 -1
  30. package/lib/esm/validation/Validators/MinLengthValidator.js +2 -2
  31. package/lib/esm/validation/Validators/TypeValidator.js +1 -1
  32. package/lib/esm/validation/Validators/Validator.d.ts +28 -68
  33. package/lib/esm/validation/Validators/Validator.js +30 -86
  34. package/lib/esm/validation/Validators/constants.d.ts +12 -11
  35. package/lib/esm/validation/Validators/constants.js +14 -12
  36. package/lib/esm/validation/Validators/index.d.ts +1 -0
  37. package/lib/esm/validation/Validators/index.js +2 -1
  38. package/lib/esm/validation/decorators.d.ts +2 -1
  39. package/lib/esm/validation/decorators.js +31 -8
  40. package/lib/esm/validation/types.d.ts +19 -0
  41. package/lib/esm/validation/types.js +1 -1
  42. package/lib/index.cjs +1 -1
  43. package/lib/index.d.ts +1 -1
  44. package/lib/mcp/ModelContextProtocol.cjs +55 -51
  45. package/lib/mcp/ModelContextProtocol.d.ts +14 -22
  46. package/lib/model/Model.cjs +11 -5
  47. package/lib/model/Model.d.ts +11 -8
  48. package/lib/model/decorators.cjs +1 -1
  49. package/lib/model/types.cjs +1 -1
  50. package/lib/model/types.d.ts +37 -9
  51. package/lib/model/utils.cjs +16 -1
  52. package/lib/model/utils.d.ts +14 -1
  53. package/lib/model/validation.cjs +334 -125
  54. package/lib/model/validation.d.ts +107 -5
  55. package/lib/types/index.cjs +18 -0
  56. package/lib/types/index.d.ts +1 -0
  57. package/lib/types/validation.cjs +3 -0
  58. package/lib/types/validation.d.ts +25 -0
  59. package/lib/validation/Validators/AsyncValidator.cjs +65 -0
  60. package/lib/validation/Validators/AsyncValidator.d.ts +72 -0
  61. package/lib/validation/Validators/BaseValidator.cjs +121 -0
  62. package/lib/validation/Validators/BaseValidator.d.ts +118 -0
  63. package/lib/validation/Validators/ListValidator.cjs +2 -2
  64. package/lib/validation/Validators/MinLengthValidator.cjs +2 -2
  65. package/lib/validation/Validators/MinLengthValidator.d.ts +1 -1
  66. package/lib/validation/Validators/TypeValidator.cjs +1 -1
  67. package/lib/validation/Validators/Validator.cjs +30 -86
  68. package/lib/validation/Validators/Validator.d.ts +28 -68
  69. package/lib/validation/Validators/constants.cjs +14 -12
  70. package/lib/validation/Validators/constants.d.ts +12 -11
  71. package/lib/validation/Validators/index.cjs +2 -1
  72. package/lib/validation/Validators/index.d.ts +1 -0
  73. package/lib/validation/decorators.cjs +32 -8
  74. package/lib/validation/decorators.d.ts +2 -1
  75. package/lib/validation/types.cjs +1 -1
  76. package/lib/validation/types.d.ts +19 -0
  77. package/package.json +1 -1
@@ -1,152 +1,361 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getValidationDecorators = getValidationDecorators;
4
+ exports.getValidatableProperties = getValidatableProperties;
5
+ exports.validateDecorator = validateDecorator;
6
+ exports.validateDecorators = validateDecorators;
3
7
  exports.validate = validate;
4
8
  const ModelErrorDefinition_1 = require("./ModelErrorDefinition.cjs");
5
- const reflection_1 = require("@decaf-ts/reflection");
6
9
  const constants_1 = require("./../utils/constants.cjs");
7
- const constants_2 = require("./constants.cjs");
8
- const constants_3 = require("./../constants/index.cjs");
9
10
  const Model_1 = require("./Model.cjs");
10
11
  const Validation_1 = require("./../validation/Validation.cjs");
11
- const constants_4 = require("./../validation/Validators/constants.cjs");
12
+ const constants_2 = require("./../validation/Validators/constants.cjs");
12
13
  const PathProxy_1 = require("./../utils/PathProxy.cjs");
14
+ const constants_3 = require("./../constants/index.cjs");
15
+ const reflection_1 = require("@decaf-ts/reflection");
16
+ const utils_1 = require("./utils.cjs");
17
+ /**
18
+ * Retrieves the validation metadata decorators associated with a specific property of a model,
19
+ * using the reflective metadata key.
20
+ *
21
+ * @param model - The model instance or class containing the decorated property.
22
+ * @param {string} prop - The name of the property whose decorators should be retrieved.
23
+ * @param {string} reflectKey - The metadata key used to retrieve the decorators.
24
+ * Defaults to `ValidationKeys.REFLECT`.
25
+ *
26
+ * @returns The validation decorators applied to the property
27
+ */
28
+ function getValidationDecorators(model, prop, reflectKey = constants_2.ValidationKeys.REFLECT) {
29
+ return reflection_1.Reflection.getPropertyDecorators(reflectKey, model, prop);
30
+ }
31
+ /**
32
+ * @description
33
+ * Retrieves all validatable property decorators from a given model, excluding specified properties.
34
+ *
35
+ * @summary
36
+ * Iterates through the own enumerable properties of a model instance, filtering out any properties
37
+ * listed in the `propsToIgnore` array. For each remaining property, it checks whether validation
38
+ * decorators are present using `getValidationDecorators`, and if so, collects them in the result array.
39
+ *
40
+ * @template M - A generic parameter extending the `Model` class, representing the model type being inspected.
41
+ *
42
+ * @param {M} model - An instance of a class extending `Model` from which validatable properties will be extracted.
43
+ * @param {string[]} propsToIgnore - An array of property names that should be excluded from validation inspection.
44
+ *
45
+ * @return {ValidationPropertyDecoratorDefinition[]} An array of validation decorator definitions
46
+ * associated with the model's properties, excluding those listed in `propsToIgnore`.
47
+ *
48
+ * @function getValidatableProperties
49
+ */
50
+ function getValidatableProperties(model, propsToIgnore) {
51
+ const decoratedProperties = [];
52
+ for (const prop in model) {
53
+ if (Object.prototype.hasOwnProperty.call(model, prop) &&
54
+ !propsToIgnore.includes(prop)) {
55
+ const dec = getValidationDecorators(model, prop);
56
+ if (dec)
57
+ decoratedProperties.push(dec);
58
+ }
59
+ }
60
+ return decoratedProperties;
61
+ }
62
+ /**
63
+ * Safely sets temporary metadata on an object
64
+ */
65
+ function setTemporaryContext(target, key, value) {
66
+ if (!Object.hasOwnProperty.call(target, key))
67
+ target[key] = value;
68
+ }
69
+ /**
70
+ * Safely removes temporary metadata from an object
71
+ */
72
+ function cleanupTemporaryContext(target, key) {
73
+ if (Object.hasOwnProperty.call(target, key))
74
+ delete target[key];
75
+ }
76
+ /**
77
+ * Executes validation with temporary context and returns the validation result
78
+ *
79
+ * @param nestedModel - The instance to validate
80
+ * @param parentModel - Reference to a parent object for nested validation
81
+ * @param isAsync - Whether to perform async validation
82
+ * @returns Validation result from hasErrors()
83
+ */
84
+ function getNestedValidationErrors(nestedModel, parentModel, isAsync) {
85
+ // Set temporary context for nested models
86
+ if (parentModel) {
87
+ setTemporaryContext(nestedModel, constants_3.VALIDATION_PARENT_KEY, parentModel);
88
+ }
89
+ setTemporaryContext(nestedModel, constants_3.ASYNC_META_KEY, !!isAsync);
90
+ const errs = nestedModel.hasErrors();
91
+ cleanupTemporaryContext(nestedModel, constants_3.VALIDATION_PARENT_KEY);
92
+ cleanupTemporaryContext(nestedModel, constants_3.ASYNC_META_KEY);
93
+ return errs;
94
+ }
95
+ function validateDecorator(model, value, decorator, async) {
96
+ const validator = Validation_1.Validation.get(decorator.key);
97
+ if (!validator) {
98
+ throw new Error(`Missing validator for ${decorator.key}`);
99
+ }
100
+ // skip async decorators if validateDecorators is called synchronously (async = false)
101
+ if (!async && decorator.props.async)
102
+ return undefined;
103
+ const decoratorProps = decorator.key === constants_1.ModelKeys.TYPE
104
+ ? [decorator.props]
105
+ : decorator.props || {};
106
+ const context = PathProxy_1.PathProxyEngine.create(model, {
107
+ ignoreUndefined: true,
108
+ ignoreNull: true,
109
+ });
110
+ const maybeAsyncErrors = validator.hasErrors(value, decoratorProps, context);
111
+ return (0, utils_1.toConditionalPromise)(maybeAsyncErrors, async);
112
+ }
13
113
  /**
14
- * @summary Analyses the decorations of the properties and validates the obj according to them
114
+ * @description
115
+ * Executes validation logic for a set of decorators applied to a model's property, handling both
116
+ * synchronous and asynchronous validations, including support for nested validations and lists.
117
+ *
118
+ * @summary
119
+ * Iterates over an array of decorator metadata objects and applies each validation rule to the
120
+ * provided value. For list decorators (`ValidationKeys.LIST`), it performs element-wise validation,
121
+ * supporting nested model validation and type checks. If the `async` flag is set, asynchronous
122
+ * validation is supported using `Promise.all`. The result is a record mapping validation keys to
123
+ * error messages, or `undefined` if no errors are found.
124
+ *
125
+ * @template M - A type parameter extending `Model`, representing the model type being validated.
126
+ * @template Async - A boolean indicating whether validation should be performed asynchronously.
127
+ *
128
+ * @param {M} model - The model instance that the validation is associated with.
129
+ * @param {any} value - The value to be validated against the provided decorators.
130
+ * @param {DecoratorMetadataAsync[]} decorators - An array of metadata objects representing validation decorators.
131
+ * @param {Async} [async] - Optional flag indicating whether validation should be performed asynchronously.
15
132
  *
16
- * @typedef M extends Model
17
- * @prop {M} obj Model object to validate
18
- * @prop {string[]} [propsToIgnore] object properties to ignore in the validation
133
+ * @return {ConditionalAsync<Async, Record<string, string>> | undefined}
134
+ * Returns either a record of validation errors (keyed by the decorator key) or `undefined` if no errors are found.
135
+ * If `async` is true, the return value is a Promise resolving to the same structure.
19
136
  *
137
+ * @function validateDecorators
138
+ */
139
+ function validateDecorators(model, value, decorators, async) {
140
+ const result = {};
141
+ for (const decorator of decorators) {
142
+ // skip async decorators if validateDecorators is called synchronously (async = false)
143
+ if (!async && decorator.props.async)
144
+ continue;
145
+ let validationErrors = validateDecorator(model, value, decorator, async);
146
+ /*
147
+ If the decorator is a list, each element must be checked.
148
+ When 'async' is true, the 'err' will always be a pending promise initially,
149
+ so the '!err' check will evaluate to false (even if the promise later resolves with no errors)
150
+ */
151
+ if (decorator.key === constants_2.ValidationKeys.LIST && (!validationErrors || async)) {
152
+ const values = value instanceof Set ? [...value] : value;
153
+ if (values && values.length > 0) {
154
+ const types = decorator.props.class ||
155
+ decorator.props.clazz ||
156
+ decorator.props.customTypes;
157
+ const allowedTypes = [types].flat().map((t) => String(t).toLowerCase());
158
+ // const reserved = Object.values(ReservedModels).map((v) => v.toLowerCase()) as string[];
159
+ const errs = values.map((childValue) => {
160
+ // if (Model.isModel(v) && !reserved.includes(v) {
161
+ if (Model_1.Model.isModel(childValue)) {
162
+ return getNestedValidationErrors(childValue, model, async);
163
+ }
164
+ return allowedTypes.includes(typeof childValue)
165
+ ? undefined
166
+ : "Value has no validatable type";
167
+ });
168
+ if (async) {
169
+ validationErrors = Promise.all(errs).then((result) => {
170
+ const allEmpty = result.every((r) => !r);
171
+ return allEmpty ? undefined : result;
172
+ });
173
+ }
174
+ else {
175
+ const allEmpty = errs.every((r) => !r);
176
+ validationErrors = errs.length > 0 && !allEmpty ? errs : undefined;
177
+ }
178
+ }
179
+ }
180
+ if (validationErrors)
181
+ result[decorator.key] = validationErrors;
182
+ }
183
+ if (!async)
184
+ return Object.keys(result).length > 0
185
+ ? result
186
+ : undefined;
187
+ const keys = Object.keys(result);
188
+ const promises = Object.values(result);
189
+ return Promise.all(promises).then((resolvedValues) => {
190
+ const res = {};
191
+ for (let i = 0; i < resolvedValues.length; i++) {
192
+ const val = resolvedValues[i];
193
+ if (val !== undefined) {
194
+ res[keys[i]] = val;
195
+ }
196
+ }
197
+ return Object.keys(res).length > 0 ? res : undefined;
198
+ });
199
+ }
200
+ /**
20
201
  * @function validate
202
+ * @template M
203
+ * @template Async
21
204
  * @memberOf module:decorator-validation
22
205
  * @category Model
206
+ *
207
+ * @description
208
+ * Validates the properties of a {@link Model} instance using registered decorators.
209
+ * Supports both synchronous and asynchronous validation flows, depending on the `async` flag.
210
+ *
211
+ * @summary
212
+ * This function inspects a given model object, identifies decorated properties that require validation,
213
+ * and applies the corresponding validation rules. It also supports nested model validation and gracefully
214
+ * merges any validation errors. For collections (Array/Set), it enforces the presence of the `@list` decorator
215
+ * and checks the type of elements. If a property is a nested model, it will call `hasErrors` on it and flatten
216
+ * the nested error keys using dot notation.
217
+ *
218
+ * @param {M} model - The model instance to be validated. Must extend from {@link Model}.
219
+ * @param {Async} [async] - A flag indicating whether validation should be asynchronous.
220
+ * @param {...string} propsToIgnore - A variadic list of property names that should be skipped during validation.
221
+ *
222
+ * @returns {ConditionalAsync<Async, ModelErrorDefinition | undefined>}
223
+ * Returns either a {@link ModelErrorDefinition} containing validation errors,
224
+ * or `undefined` if no errors are found. When `async` is `true`, returns a Promise.
225
+ *
226
+ * @see {@link Model}
227
+ * @see {@link ModelErrorDefinition}
228
+ * @see {@link validateDecorators}
229
+ * @see {@link getValidatableProperties}
230
+ *
231
+ * @mermaid
232
+ * sequenceDiagram
233
+ * participant Caller
234
+ * participant validate
235
+ * participant getValidatableProperties
236
+ * participant validateDecorators
237
+ * participant ModelInstance
238
+ * Caller->>validate: call with obj, async, propsToIgnore
239
+ * validate->>getValidatableProperties: retrieve decorated props
240
+ * loop for each property
241
+ * validate->>validateDecorators: validate using decorators
242
+ * alt is nested model
243
+ * validate->>ModelInstance: call hasErrors()
244
+ * end
245
+ * end
246
+ * alt async
247
+ * validate->>validate: Promise.allSettled for errors
248
+ * end
249
+ * validate-->>Caller: return ModelErrorDefinition | undefined
23
250
  */
24
- function validate(obj, ...propsToIgnore) {
25
- const decoratedProperties = [];
26
- for (const prop in obj)
27
- if (Object.prototype.hasOwnProperty.call(obj, prop) &&
28
- propsToIgnore.indexOf(prop) === -1) {
29
- decoratedProperties.push(
30
- // @ts-ignore
31
- reflection_1.Reflection.getPropertyDecorators(constants_4.ValidationKeys.REFLECT, obj, prop));
32
- }
33
- let result = undefined;
34
- for (const decoratedProperty of decoratedProperties) {
35
- const { prop, decorators } = decoratedProperty;
36
- if (!decorators || !decorators.length)
251
+ function validate(model, async, ...propsToIgnore) {
252
+ const decoratedProperties = getValidatableProperties(model, propsToIgnore);
253
+ const result = {};
254
+ const nestedErrors = {};
255
+ for (const { prop, decorators } of decoratedProperties) {
256
+ const propKey = String(prop);
257
+ let propValue = model[prop];
258
+ if (!decorators?.length)
259
+ continue;
260
+ // Get the default type validator
261
+ const designTypeDec = decorators.find((d) => {
262
+ return [constants_1.ModelKeys.TYPE, constants_2.ValidationKeys.TYPE].includes(d.key);
263
+ });
264
+ if (!designTypeDec)
37
265
  continue;
38
- const defaultTypeDecorator = decorators[0];
39
- // tries to find any type decorators or other decorators that already enforce type (the ones with the allowed types property defined). if so, skip the default type verification
40
- if (decorators.find((d) => {
41
- if (d.key === constants_4.ValidationKeys.TYPE)
42
- return true;
43
- return !!d.props.types?.find((t) => t === defaultTypeDecorator.props.name);
44
- })) {
45
- decorators.shift(); // remove the design:type decorator, since the type will already be checked
266
+ const designType = designTypeDec.props.name;
267
+ // Handle array or Set types and enforce the presence of @list decorator
268
+ if ([Array.name, Set.name].includes(designType)) {
269
+ if (!decorators.some((d) => d.key === constants_2.ValidationKeys.LIST)) {
270
+ result[propKey] = {
271
+ [constants_2.ValidationKeys.TYPE]: `Array or Set property '${propKey}' requires a @list decorator`,
272
+ };
273
+ continue;
274
+ }
275
+ if (propValue &&
276
+ !(Array.isArray(propValue) || propValue instanceof Set)) {
277
+ result[propKey] = {
278
+ [constants_2.ValidationKeys.TYPE]: `Property '${String(prop)}' must be either an Array or a Set`,
279
+ };
280
+ continue;
281
+ }
282
+ // Remove design:type decorator, since @list decorator already ensures type
283
+ for (let i = decorators.length - 1; i >= 0; i--) {
284
+ if (decorators[i].key === constants_1.ModelKeys.TYPE) {
285
+ decorators.splice(i, 1);
286
+ }
287
+ }
288
+ propValue = propValue instanceof Set ? [...propValue] : propValue;
46
289
  }
47
- let errs = undefined;
48
- for (const decorator of decorators) {
49
- const validator = Validation_1.Validation.get(decorator.key);
50
- if (!validator) {
51
- throw new Error(`Missing validator for ${decorator.key}`);
290
+ const propErrors = validateDecorators(model, propValue, decorators, async) || {};
291
+ // Check for nested properties.
292
+ // To prevent unnecessary processing, "propValue" must be defined and validatable
293
+ // let nestedErrors: Record<string, any> = {};
294
+ const isConstr = Model_1.Model.isPropertyModel(model, propKey);
295
+ // if propValue !== undefined, null
296
+ if (propValue && isConstr) {
297
+ const instance = propValue;
298
+ const isInvalidModel = typeof instance !== "object" ||
299
+ !instance.hasErrors ||
300
+ typeof instance.hasErrors !== "function";
301
+ if (isInvalidModel) {
302
+ // propErrors[ValidationKeys.TYPE] = "Model should be validatable but it's not.";
303
+ console.warn("Model should be validatable but it's not.");
52
304
  }
53
- const decoratorProps = decorator.key === constants_1.ModelKeys.TYPE
54
- ? [decorator.props]
55
- : decorator.props || {};
56
- const err = validator.hasErrors(obj[prop.toString()], decoratorProps, PathProxy_1.PathProxyEngine.create(obj, { ignoreUndefined: true, ignoreNull: true }));
57
- if (err) {
58
- errs = errs || {};
59
- errs[decorator.key] = err;
305
+ else {
306
+ nestedErrors[propKey] = getNestedValidationErrors(instance, model, async);
60
307
  }
61
308
  }
62
- if (errs) {
63
- result = result || {};
64
- result[decoratedProperty.prop.toString()] = errs;
309
+ // Add to the result if we have any errors
310
+ // Async mode returns a Promise that resolves to undefined when no errors exist
311
+ if (Object.keys(propErrors).length > 0 || async)
312
+ result[propKey] = propErrors;
313
+ // Then merge any nested errors
314
+ if (!async) {
315
+ Object.entries(nestedErrors[propKey] || {}).forEach(([key, error]) => {
316
+ if (error !== undefined) {
317
+ result[`${propKey}.${key}`] = error;
318
+ }
319
+ });
65
320
  }
66
321
  }
67
- // tests nested classes
68
- for (const prop of Object.keys(obj).filter((k) => !result || !result[k])) {
69
- let err;
70
- // if a nested Model
71
- const allDecorators = reflection_1.Reflection.getPropertyDecorators(constants_4.ValidationKeys.REFLECT, obj, prop).decorators;
72
- const decorators = reflection_1.Reflection.getPropertyDecorators(constants_4.ValidationKeys.REFLECT, obj, prop).decorators.filter((d) => [constants_1.ModelKeys.TYPE, constants_4.ValidationKeys.TYPE].indexOf(d.key) !== -1);
73
- if (!decorators || !decorators.length)
74
- continue;
75
- const dec = decorators.pop();
76
- const clazz = dec.props.name
77
- ? [dec.props.name]
78
- : Array.isArray(dec.props.customTypes)
79
- ? dec.props.customTypes
80
- : [dec.props.customTypes];
81
- const reserved = Object.values(constants_2.ReservedModels).map((v) => v.toLowerCase());
82
- for (const c of clazz) {
83
- if (reserved.indexOf(c.toLowerCase()) === -1) {
84
- const typeDecoratorKey = Array.isArray(obj[prop])
85
- ? constants_4.ValidationKeys.LIST
86
- : constants_4.ValidationKeys.TYPE;
87
- const types = allDecorators.find((d) => d.key === typeDecoratorKey) || {};
88
- let allowedTypes = [];
89
- if (types && types.props) {
90
- const customTypes = Array.isArray(obj[prop])
91
- ? types.props.class
92
- : types.props.customTypes;
93
- if (customTypes)
94
- allowedTypes = Array.isArray(customTypes)
95
- ? customTypes.map((t) => `${t}`.toLowerCase())
96
- : [customTypes.toLowerCase()];
97
- }
98
- const validate = (prop, value) => {
99
- if (typeof value !== "object" && typeof value !== "function")
100
- return undefined;
101
- try {
102
- if (value && !value[constants_3.VALIDATION_PARENT_KEY])
103
- value[constants_3.VALIDATION_PARENT_KEY] = obj; // TODO: freeze?
104
- return Model_1.Model.isModel(value)
105
- ? value.hasErrors()
106
- : allowedTypes.includes(typeof value)
107
- ? undefined
108
- : "Value has no validatable type";
109
- }
110
- finally {
111
- if (value && value[constants_3.VALIDATION_PARENT_KEY])
112
- delete value[constants_3.VALIDATION_PARENT_KEY];
322
+ // Synchronous return
323
+ if (!async) {
324
+ return (Object.keys(result).length > 0
325
+ ? new ModelErrorDefinition_1.ModelErrorDefinition(result)
326
+ : undefined);
327
+ }
328
+ const merged = result; // TODO: apply filtering
329
+ const keys = Object.keys(merged);
330
+ const promises = Object.values(merged);
331
+ return Promise.allSettled(promises).then(async (results) => {
332
+ const result = {};
333
+ for (const [parentProp, nestedErrPromise] of Object.entries(nestedErrors)) {
334
+ const nestedPropDecErrors = (await nestedErrPromise);
335
+ if (nestedPropDecErrors)
336
+ Object.entries(nestedPropDecErrors).forEach(([nestedProp, nestedPropDecError]) => {
337
+ if (nestedPropDecError !== undefined) {
338
+ const nestedKey = [parentProp, nestedProp].join(".");
339
+ result[nestedKey] = nestedPropDecError;
113
340
  }
114
- };
115
- switch (c) {
116
- case Array.name:
117
- case Set.name:
118
- if (allDecorators.length) {
119
- const listDec = allDecorators.find((d) => d.key === constants_4.ValidationKeys.LIST);
120
- if (listDec) {
121
- err = (c === Array.name
122
- ? obj[prop]
123
- : // If it's a Set
124
- obj[prop].values())
125
- .map((v) => validate(prop, v))
126
- .filter((e) => !!e);
127
- if (!err?.length) {
128
- // if the result is an empty list...
129
- err = undefined;
130
- }
131
- }
132
- }
133
- break;
134
- default:
135
- try {
136
- if (obj[prop])
137
- err = validate(prop, obj[prop]);
138
- }
139
- catch (e) {
140
- console.warn(`Model should be validatable but its not: ${e}`);
141
- }
142
- }
341
+ });
342
+ }
343
+ for (let i = 0; i < results.length; i++) {
344
+ const key = keys[i];
345
+ const res = results[i];
346
+ if (res.status === "fulfilled" && res.value !== undefined) {
347
+ result[key] = res.value;
143
348
  }
144
- if (err) {
145
- result = result || {};
146
- result[prop] = err;
349
+ else if (res.status === "rejected") {
350
+ result[key] =
351
+ res.reason instanceof Error
352
+ ? res.reason.message
353
+ : String(res.reason || "Validation failed");
147
354
  }
148
355
  }
149
- }
150
- return result ? new ModelErrorDefinition_1.ModelErrorDefinition(result) : undefined;
356
+ return Object.keys(result).length > 0
357
+ ? new ModelErrorDefinition_1.ModelErrorDefinition(result)
358
+ : undefined;
359
+ });
151
360
  }
152
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlbC92YWxpZGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBK0JBLDRCQW1MQztBQWxORCxxRUFBOEQ7QUFDOUQscURBSThCO0FBQzlCLHdEQUErQztBQUMvQywrQ0FBNkM7QUFDN0Msd0RBQXFEO0FBRXJELHVDQUFnQztBQUNoQywrREFBc0Q7QUFDdEQsd0VBQW9FO0FBTXBFLHdEQUFxRDtBQUVyRDs7Ozs7Ozs7OztHQVVHO0FBQ0gsU0FBZ0IsUUFBUSxDQUN0QixHQUFNLEVBQ04sR0FBRyxhQUF1QjtJQUUxQixNQUFNLG1CQUFtQixHQUE0QyxFQUFFLENBQUM7SUFDeEUsS0FBSyxNQUFNLElBQUksSUFBSSxHQUFHO1FBQ3BCLElBQ0UsTUFBTSxDQUFDLFNBQVMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUM7WUFDL0MsYUFBYSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsRUFDbEMsQ0FBQztZQUNELG1CQUFtQixDQUFDLElBQUk7WUFDdEIsYUFBYTtZQUNiLHVCQUFVLENBQUMscUJBQXFCLENBQzlCLDBCQUFjLENBQUMsT0FBTyxFQUN0QixHQUFHLEVBQ0gsSUFBSSxDQUN3QixDQUMvQixDQUFDO1FBQ0osQ0FBQztJQUVILElBQUksTUFBTSxHQUE0QixTQUFTLENBQUM7SUFFaEQsS0FBSyxNQUFNLGlCQUFpQixJQUFJLG1CQUFtQixFQUFFLENBQUM7UUFDcEQsTUFBTSxFQUFFLElBQUksRUFBRSxVQUFVLEVBQUUsR0FBRyxpQkFBaUIsQ0FBQztRQUUvQyxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsVUFBVSxDQUFDLE1BQU07WUFBRSxTQUFTO1FBRWhELE1BQU0sb0JBQW9CLEdBQXNCLFVBQVUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUU5RCxnTEFBZ0w7UUFDaEwsSUFDRSxVQUFV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QUFFLENBQUMsQ0FBQzt3QkFDaEUsQ0FBQztnQkFDTCxDQUFDO1lBQ0gsQ0FBQztZQUNELElBQUksR0FBRyxFQUFFLENBQUM7Z0JBQ1IsTUFBTSxHQUFHLE1BQU0sSUFBSSxFQUFFLENBQUM7Z0JBQ3RCLE1BQU0sQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFVLENBQUM7WUFDNUIsQ0FBQztRQUNILENBQUM7SUFDSCxDQUFDO0lBRUQsT0FBTyxNQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksMkNBQW9CLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztBQUMvRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTW9kZWxFcnJvckRlZmluaXRpb24gfSBmcm9tIFwiLi9Nb2RlbEVycm9yRGVmaW5pdGlvblwiO1xuaW1wb3J0IHtcbiAgRGVjb3JhdG9yTWV0YWRhdGEsXG4gIFJlZmxlY3Rpb24sXG4gIEZ1bGxQcm9wZXJ0eURlY29yYXRvckxpc3QsXG59IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIi4uL3V0aWxzL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgUmVzZXJ2ZWRNb2RlbHMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFZBTElEQVRJT05fUEFSRU5UX0tFWSB9IGZyb20gXCIuLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IFZhbGlkYXRhYmxlIH0gZnJvbSBcIi4vdHlwZXNcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4vTW9kZWxcIjtcbmltcG9ydCB7IFZhbGlkYXRpb24gfSBmcm9tIFwiLi4vdmFsaWRhdGlvbi9WYWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuLi92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBNb2RlbEVycm9ycyxcbiAgVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvbixcbiAgVmFsaWRhdG9yT3B0aW9ucyxcbn0gZnJvbSBcIi4uL3ZhbGlkYXRpb24vdHlwZXNcIjtcbmltcG9ydCB7IFBhdGhQcm94eUVuZ2luZSB9IGZyb20gXCIuLi91dGlscy9QYXRoUHJveHlcIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBBbmFseXNlcyB0aGUgZGVjb3JhdGlvbnMgb2YgdGhlIHByb3BlcnRpZXMgYW5kIHZhbGlkYXRlcyB0aGUgb2JqIGFjY29yZGluZyB0byB0aGVtXG4gKlxuICogQHR5cGVkZWYgTSBleHRlbmRzIE1vZGVsXG4gKiBAcHJvcCB7TX0gb2JqIE1vZGVsIG9iamVjdCB0byB2YWxpZGF0ZVxuICogQHByb3Age3N0cmluZ1tdfSBbcHJvcHNUb0lnbm9yZV0gb2JqZWN0IHByb3BlcnRpZXMgdG8gaWdub3JlIGluIHRoZSB2YWxpZGF0aW9uXG4gKlxuICogQGZ1bmN0aW9uIHZhbGlkYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRlY29yYXRvci12YWxpZGF0aW9uXG4gKiBAY2F0ZWdvcnkgTW9kZWxcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIG9iajogTSxcbiAgLi4ucHJvcHNUb0lnbm9yZTogc3RyaW5nW11cbik6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZGVjb3JhdGVkUHJvcGVydGllczogVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvbltdID0gW107XG4gIGZvciAoY29uc3QgcHJvcCBpbiBvYmopXG4gICAgaWYgKFxuICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG9iaiwgcHJvcCkgJiZcbiAgICAgIHByb3BzVG9JZ25vcmUuaW5kZXhPZihwcm9wKSA9PT0gLTFcbiAgICApIHtcbiAgICAgIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChcbiAgICAgICAgLy8gQHRzLWlnbm9yZVxuICAgICAgICBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgICAgICBWYWxpZGF0aW9uS2V5cy5SRUZMRUNULFxuICAgICAgICAgIG9iaixcbiAgICAgICAgICBwcm9wXG4gICAgICAgICkgYXMgRnVsbFByb3BlcnR5RGVjb3JhdG9yTGlzdFxuICAgICAgKTtcbiAgICB9XG5cbiAgbGV0IHJlc3VsdDogTW9kZWxFcnJvcnMgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgZm9yIChjb25zdCBkZWNvcmF0ZWRQcm9wZXJ0eSBvZiBkZWNvcmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgY29uc3QgeyBwcm9wLCBkZWNvcmF0b3JzIH0gPSBkZWNvcmF0ZWRQcm9wZXJ0eTtcblxuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuXG4gICAgY29uc3QgZGVmYXVsdFR5cGVEZWNvcmF0b3I6IERlY29yYXRvck1ldGFkYXRhID0gZGVjb3JhdG9yc1swXTtcblxuICAgIC8vIHRyaWVzIHRvIGZpbmQgYW55IHR5cGUgZGVjb3JhdG9ycyBvciBvdGhlciBkZWNvcmF0b3JzIHRoYXQgYWxyZWFkeSBlbmZvcmNlIHR5cGUgKHRoZSBvbmVzIHdpdGggdGhlIGFsbG93ZWQgdHlwZXMgcHJvcGVydHkgZGVmaW5lZCkuIGlmIHNvLCBza2lwIHRoZSBkZWZhdWx0IHR5cGUgdmVyaWZpY2F0aW9uXG4gICAgaWYgKFxuICAgICAgZGVjb3JhdG9ycy5maW5kKChkKSA9PiB7XG4gICAgICAgIGlmIChkLmtleSA9PT0gVmFsaWRhdGlvbktleXMuVFlQRSkgcmV0dXJuIHRydWU7XG4gICAgICAgIHJldHVybiAhIWQucHJvcHMudHlwZXM/LmZpbmQoXG4gICAgICAgICAgKHQpID0+IHQgPT09IGRlZmF1bHRUeXBlRGVjb3JhdG9yLnByb3BzLm5hbWVcbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKSB7XG4gICAgICBkZWNvcmF0b3JzLnNoaWZ0KCk7IC8vIHJlbW92ZSB0aGUgZGVzaWduOnR5cGUgZGVjb3JhdG9yLCBzaW5jZSB0aGUgdHlwZSB3aWxsIGFscmVhZHkgYmUgY2hlY2tlZFxuICAgIH1cblxuICAgIGxldCBlcnJzOiBSZWNvcmQ8c3RyaW5nLCBzdHJpbmcgfCB1bmRlZmluZWQ+IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgZm9yIChjb25zdCBkZWNvcmF0b3Igb2YgZGVjb3JhdG9ycykge1xuICAgICAgY29uc3QgdmFsaWRhdG9yID0gVmFsaWRhdGlvbi5nZXQoZGVjb3JhdG9yLmtleSk7XG4gICAgICBpZiAoIXZhbGlkYXRvcikge1xuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgdmFsaWRhdG9yIGZvciAke2RlY29yYXRvci5rZXl9YCk7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IGRlY29yYXRvclByb3BzID1cbiAgICAgICAgZGVjb3JhdG9yLmtleSA9PT0gTW9kZWxLZXlzLlRZUEVcbiAgICAgICAgICA/IFtkZWNvcmF0b3IucHJvcHNdXG4gICAgICAgICAgOiBkZWNvcmF0b3IucHJvcHMgfHwge307XG5cbiAgICAgIGNvbnN0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkID0gdmFsaWRhdG9yLmhhc0Vycm9ycyhcbiAgICAgICAgKG9iaiBhcyBhbnkpW3Byb3AudG9TdHJpbmcoKV0sXG4gICAgICAgIGRlY29yYXRvclByb3BzIGFzIFZhbGlkYXRvck9wdGlvbnMsXG4gICAgICAgIFBhdGhQcm94eUVuZ2luZS5jcmVhdGUob2JqLCB7IGlnbm9yZVVuZGVmaW5lZDogdHJ1ZSwgaWdub3JlTnVsbDogdHJ1ZSB9KVxuICAgICAgKTtcblxuICAgICAgaWYgKGVycikge1xuICAgICAgICBlcnJzID0gZXJycyB8fCB7fTtcbiAgICAgICAgZXJyc1tkZWNvcmF0b3Iua2V5XSA9IGVycjtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoZXJycykge1xuICAgICAgcmVzdWx0ID0gcmVzdWx0IHx8IHt9O1xuICAgICAgcmVzdWx0W2RlY29yYXRlZFByb3BlcnR5LnByb3AudG9TdHJpbmcoKV0gPSBlcnJzO1xuICAgIH1cbiAgfVxuXG4gIC8vIHRlc3RzIG5lc3RlZCBjbGFzc2VzXG4gIGZvciAoY29uc3QgcHJvcCBvZiBPYmplY3Qua2V5cyhvYmopLmZpbHRlcigoaykgPT4gIXJlc3VsdCB8fCAhcmVzdWx0W2tdKSkge1xuICAgIGxldCBlcnI6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAvLyBpZiBhIG5lc3RlZCBNb2RlbFxuICAgIGNvbnN0IGFsbERlY29yYXRvcnMgPSBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICBvYmosXG4gICAgICBwcm9wXG4gICAgKS5kZWNvcmF0b3JzO1xuICAgIGNvbnN0IGRlY29yYXRvcnMgPSBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgIFZhbGlkYXRpb25LZXlzLlJFRkxFQ1QsXG4gICAgICBvYmosXG4gICAgICBwcm9wXG4gICAgKS5kZWNvcmF0b3JzLmZpbHRlcihcbiAgICAgIChkOiB7IGtleTogc3RyaW5nIH0pID0+XG4gICAgICAgIFtNb2RlbEtleXMuVFlQRSwgVmFsaWRhdGlvbktleXMuVFlQRSBhcyBzdHJpbmddLmluZGV4T2YoZC5rZXkpICE9PSAtMVxuICAgICk7XG4gICAgaWYgKCFkZWNvcmF0b3JzIHx8ICFkZWNvcmF0b3JzLmxlbmd0aCkgY29udGludWU7XG4gICAgY29uc3QgZGVjID0gZGVjb3JhdG9ycy5wb3AoKSBhcyBEZWNvcmF0b3JNZXRhZGF0YTtcbiAgICBjb25zdCBjbGF6eiA9IGRlYy5wcm9wcy5uYW1lXG4gICAgICA/IFtkZWMucHJvcHMubmFtZV1cbiAgICAgIDogQXJyYXkuaXNBcnJheShkZWMucHJvcHMuY3VzdG9tVHlwZXMpXG4gICAgICAgID8gZGVjLnByb3BzLmN1c3RvbVR5cGVzXG4gICAgICAgIDogW2RlYy5wcm9wcy5jdXN0b21UeXBlc107XG4gICAgY29uc3QgcmVzZXJ2ZWQgPSBPYmplY3QudmFsdWVzKFJlc2VydmVkTW9kZWxzKS5tYXAoKHYpID0+XG4gICAgICB2LnRvTG93ZXJDYXNlKClcbiAgICApIGFzIHN0cmluZ1tdO1xuXG4gICAgZm9yIChjb25zdCBjIG9mIGNsYXp6KSB7XG4gICAgICBpZiAocmVzZXJ2ZWQuaW5kZXhPZihjLnRvTG93ZXJDYXNlKCkpID09PSAtMSkge1xuICAgICAgICBjb25zdCB0eXBlRGVjb3JhdG9yS2V5ID0gQXJyYXkuaXNBcnJheSgob2JqIGFzIGFueSlbcHJvcF0pXG4gICAgICAgICAgPyBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgICAgOiBWYWxpZGF0aW9uS2V5cy5UWVBFO1xuICAgICAgICBjb25zdCB0eXBlczogYW55ID1cbiAgICAgICAgICBhbGxEZWNvcmF0b3JzLmZpbmQoXG4gICAgICAgICAgICAoZDogeyBrZXk6IHN0cmluZyB9KSA9PiBkLmtleSA9PT0gdHlwZURlY29yYXRvcktleVxuICAgICAgICAgICkgfHwge307XG4gICAgICAgIGxldCBhbGxvd2VkVHlwZXM6IHN0cmluZ1tdID0gW107XG4gICAgICAgIGlmICh0eXBlcyAmJiB0eXBlcy5wcm9wcykge1xuICAgICAgICAgIGNvbnN0IGN1c3RvbVR5cGVzID0gQXJyYXkuaXNBcnJheSgob2JqIGFzIGFueSlbcHJvcF0pXG4gICAgICAgICAgICA/IHR5cGVzLnByb3BzLmNsYXNzXG4gICAgICAgICAgICA6IHR5cGVzLnByb3BzLmN1c3RvbVR5cGVzO1xuICAgICAgICAgIGlmIChjdXN0b21UeXBlcylcbiAgICAgICAgICAgIGFsbG93ZWRUeXBlcyA9IEFycmF5LmlzQXJyYXkoY3VzdG9tVHlwZXMpXG4gICAgICAgICAgICAgID8gY3VzdG9tVHlwZXMubWFwKCh0KSA9PiBgJHt0fWAudG9Mb3dlckNhc2UoKSlcbiAgICAgICAgICAgICAgOiBbY3VzdG9tVHlwZXMudG9Mb3dlckNhc2UoKV07XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2YWxpZGF0ZSA9IChwcm9wOiBzdHJpbmcsIHZhbHVlOiBhbnkpOiBhbnkgPT4ge1xuICAgICAgICAgIGlmICh0eXBlb2YgdmFsdWUgIT09IFwib2JqZWN0XCIgJiYgdHlwZW9mIHZhbHVlICE9PSBcImZ1bmN0aW9uXCIpXG4gICAgICAgICAgICByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGlmICh2YWx1ZSAmJiAhdmFsdWVbVkFMSURBVElPTl9QQVJFTlRfS0VZXSlcbiAgICAgICAgICAgICAgdmFsdWVbVkFMSURBVElPTl9QQVJFTlRfS0VZXSA9IG9iajsgLy8gVE9ETzogZnJlZXplP1xuXG4gICAgICAgICAgICByZXR1cm4gTW9kZWwuaXNNb2RlbCh2YWx1ZSlcbiAgICAgICAgICAgICAgPyB2YWx1ZS5oYXNFcnJvcnMoKVxuICAgICAgICAgICAgICA6IGFsbG93ZWRUeXBlcy5pbmNsdWRlcyh0eXBlb2YgdmFsdWUpXG4gICAgICAgICAgICAgICAgPyB1bmRlZmluZWRcbiAgICAgICAgICAgICAgICA6IFwiVmFsdWUgaGFzIG5vIHZhbGlkYXRhYmxlIHR5cGVcIjtcbiAgICAgICAgICB9IGZpbmFsbHkge1xuICAgICAgICAgICAgaWYgKHZhbHVlICYmIHZhbHVlW1ZBTElEQVRJT05fUEFSRU5UX0tFWV0pXG4gICAgICAgICAgICAgIGRlbGV0ZSB2YWx1ZVtWQUxJREFUSU9OX1BBUkVOVF9LRVldO1xuICAgICAgICAgIH1cbiAgICAgICAgfTtcblxuICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICBjYXNlIEFycmF5Lm5hbWU6XG4gICAgICAgICAgY2FzZSBTZXQubmFtZTpcbiAgICAgICAgICAgIGlmIChhbGxEZWNvcmF0b3JzLmxlbmd0aCkge1xuICAgICAgICAgICAgICBjb25zdCBsaXN0RGVjID0gYWxsRGVjb3JhdG9ycy5maW5kKFxuICAgICAgICAgICAgICAgIChkOiB7IGtleTogc3RyaW5nIH0pID0+IGQua2V5ID09PSBWYWxpZGF0aW9uS2V5cy5MSVNUXG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIGlmIChsaXN0RGVjKSB7XG4gICAgICAgICAgICAgICAgZXJyID0gKFxuICAgICAgICAgICAgICAgICAgYyA9PT0gQXJyYXkubmFtZVxuICAgICAgICAgICAgICAgICAgICA/IChvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF1cbiAgICAgICAgICAgICAgICAgICAgOiAvLyBJZiBpdCdzIGEgU2V0XG4gICAgICAgICAgICAgICAgICAgICAgKG9iaiBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXS52YWx1ZXMoKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgIC5tYXAoKHY6IFZhbGlkYXRhYmxlKSA9PiB2YWxpZGF0ZShwcm9wLCB2KSlcbiAgICAgICAgICAgICAgICAgIC5maWx0ZXIoKGU6IGFueSkgPT4gISFlKSBhcyBhbnk7XG4gICAgICAgICAgICAgICAgaWYgKCFlcnI/Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHJlc3VsdCBpcyBhbiBlbXB0eSBsaXN0Li4uXG4gICAgICAgICAgICAgICAgICBlcnIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaWYgKChvYmogYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF0pXG4gICAgICAgICAgICAgICAgZXJyID0gdmFsaWRhdGUocHJvcCwgKG9iaiBhcyBhbnkpW3Byb3BdKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICAgICAgY29uc29sZS53YXJuKGBNb2RlbCBzaG91bGQgYmUgdmFsaWRhdGFibGUgYnV0IGl0cyBub3Q6ICR7ZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgaWYgKGVycikge1xuICAgICAgICByZXN1bHQgPSByZXN1bHQgfHwge307XG4gICAgICAgIHJlc3VsdFtwcm9wXSA9IGVyciBhcyBhbnk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdCA/IG5ldyBNb2RlbEVycm9yRGVmaW5pdGlvbihyZXN1bHQpIDogdW5kZWZpbmVkO1xufVxuIl19
361
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidmFsaWRhdGlvbi5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9tb2RlbC92YWxpZGF0aW9uLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBMkJBLDBEQVVDO0FBcUJELDREQWlCQztBQWdERCw4Q0FrQ0M7QUE0QkQsZ0RBNEVDO0FBcURELDRCQXNKQztBQWhkRCxxRUFBOEQ7QUFDOUQsd0RBQStDO0FBQy9DLHVDQUFnQztBQUNoQywrREFBc0Q7QUFDdEQsd0VBQW9FO0FBTXBFLHdEQUFxRDtBQUNyRCx3REFBcUU7QUFFckUscURBQWtEO0FBQ2xELHVDQUErQztBQUUvQzs7Ozs7Ozs7OztHQVVHO0FBQ0gsU0FBZ0IsdUJBQXVCLENBQ3JDLEtBQTBCLEVBQzFCLElBQVksRUFDWixhQUFxQiwwQkFBYyxDQUFDLE9BQU87SUFFM0MsT0FBTyx1QkFBVSxDQUFDLHFCQUFxQixDQUNyQyxVQUFVLEVBQ1YsS0FBSyxFQUNMLElBQUksQ0FDK0MsQ0FBQztBQUN4RCxDQUFDO0FBRUQ7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQWtCRztBQUNILFNBQWdCLHdCQUF3QixDQUN0QyxLQUFRLEVBQ1IsYUFBdUI7SUFFdkIsTUFBTSxtQkFBbUIsR0FBNEMsRUFBRSxDQUFDO0lBRXhFLEtBQUssTUFBTSxJQUFJLElBQUksS0FBSyxFQUFFLENBQUM7UUFDekIsSUFDRSxNQUFNLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQztZQUNqRCxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLEVBQzdCLENBQUM7WUFDRCxNQUFNLEdBQUcsR0FBRyx1QkFBdUIsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUM7WUFDakQsSUFBSSxHQUFHO2dCQUFFLG1CQUFtQixDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUN6QyxDQUFDO0lBQ0gsQ0FBQztJQUVELE9BQU8sbUJBQW1CLENBQUM7QUFD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LENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDO1lBQ25DLENBQUMsQ0FBQyxJQUFJLDJDQUFvQixDQUFDLE1BQU0sQ0FBQztZQUNsQyxDQUFDLENBQUMsU0FBUyxDQUFDO0lBQ2hCLENBQUMsQ0FBUSxDQUFDO0FBQ1osQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE1vZGVsRXJyb3JEZWZpbml0aW9uIH0gZnJvbSBcIi4vTW9kZWxFcnJvckRlZmluaXRpb25cIjtcbmltcG9ydCB7IE1vZGVsS2V5cyB9IGZyb20gXCIuLi91dGlscy9jb25zdGFudHNcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIi4vTW9kZWxcIjtcbmltcG9ydCB7IFZhbGlkYXRpb24gfSBmcm9tIFwiLi4vdmFsaWRhdGlvbi9WYWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuLi92YWxpZGF0aW9uL1ZhbGlkYXRvcnMvY29uc3RhbnRzXCI7XG5pbXBvcnQge1xuICBNb2RlbEVycm9ycyxcbiAgVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvbixcbiAgVmFsaWRhdG9yT3B0aW9ucyxcbn0gZnJvbSBcIi4uL3ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFBhdGhQcm94eUVuZ2luZSB9IGZyb20gXCIuLi91dGlscy9QYXRoUHJveHlcIjtcbmltcG9ydCB7IEFTWU5DX01FVEFfS0VZLCBWQUxJREFUSU9OX1BBUkVOVF9LRVkgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDb25kaXRpb25hbEFzeW5jLCBEZWNvcmF0b3JNZXRhZGF0YUFzeW5jIH0gZnJvbSBcIi4uL3R5cGVzXCI7XG5pbXBvcnQgeyBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyB0b0NvbmRpdGlvbmFsUHJvbWlzZSB9IGZyb20gXCIuL3V0aWxzXCI7XG5cbi8qKlxuICogUmV0cmlldmVzIHRoZSB2YWxpZGF0aW9uIG1ldGFkYXRhIGRlY29yYXRvcnMgYXNzb2NpYXRlZCB3aXRoIGEgc3BlY2lmaWMgcHJvcGVydHkgb2YgYSBtb2RlbCxcbiAqIHVzaW5nIHRoZSByZWZsZWN0aXZlIG1ldGFkYXRhIGtleS5cbiAqXG4gKiBAcGFyYW0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2Ugb3IgY2xhc3MgY29udGFpbmluZyB0aGUgZGVjb3JhdGVkIHByb3BlcnR5LlxuICogQHBhcmFtIHtzdHJpbmd9IHByb3AgLSBUaGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgd2hvc2UgZGVjb3JhdG9ycyBzaG91bGQgYmUgcmV0cmlldmVkLlxuICogQHBhcmFtIHtzdHJpbmd9IHJlZmxlY3RLZXkgLSBUaGUgbWV0YWRhdGEga2V5IHVzZWQgdG8gcmV0cmlldmUgdGhlIGRlY29yYXRvcnMuXG4gKiAgICAgICAgICAgICAgICAgICAgIERlZmF1bHRzIHRvIGBWYWxpZGF0aW9uS2V5cy5SRUZMRUNUYC5cbiAqXG4gKiBAcmV0dXJucyBUaGUgdmFsaWRhdGlvbiBkZWNvcmF0b3JzIGFwcGxpZWQgdG8gdGhlIHByb3BlcnR5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRWYWxpZGF0aW9uRGVjb3JhdG9ycyhcbiAgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gIHByb3A6IHN0cmluZyxcbiAgcmVmbGVjdEtleTogc3RyaW5nID0gVmFsaWRhdGlvbktleXMuUkVGTEVDVFxuKTogVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvbiB7XG4gIHJldHVybiBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICByZWZsZWN0S2V5LFxuICAgIG1vZGVsLFxuICAgIHByb3BcbiAgKSBhcyB1bmtub3duIGFzIFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb247XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uXG4gKiBSZXRyaWV2ZXMgYWxsIHZhbGlkYXRhYmxlIHByb3BlcnR5IGRlY29yYXRvcnMgZnJvbSBhIGdpdmVuIG1vZGVsLCBleGNsdWRpbmcgc3BlY2lmaWVkIHByb3BlcnRpZXMuXG4gKlxuICogQHN1bW1hcnlcbiAqIEl0ZXJhdGVzIHRocm91Z2ggdGhlIG93biBlbnVtZXJhYmxlIHByb3BlcnRpZXMgb2YgYSBtb2RlbCBpbnN0YW5jZSwgZmlsdGVyaW5nIG91dCBhbnkgcHJvcGVydGllc1xuICogbGlzdGVkIGluIHRoZSBgcHJvcHNUb0lnbm9yZWAgYXJyYXkuIEZvciBlYWNoIHJlbWFpbmluZyBwcm9wZXJ0eSwgaXQgY2hlY2tzIHdoZXRoZXIgdmFsaWRhdGlvblxuICogZGVjb3JhdG9ycyBhcmUgcHJlc2VudCB1c2luZyBgZ2V0VmFsaWRhdGlvbkRlY29yYXRvcnNgLCBhbmQgaWYgc28sIGNvbGxlY3RzIHRoZW0gaW4gdGhlIHJlc3VsdCBhcnJheS5cbiAqXG4gKiBAdGVtcGxhdGUgTSAtIEEgZ2VuZXJpYyBwYXJhbWV0ZXIgZXh0ZW5kaW5nIHRoZSBgTW9kZWxgIGNsYXNzLCByZXByZXNlbnRpbmcgdGhlIG1vZGVsIHR5cGUgYmVpbmcgaW5zcGVjdGVkLlxuICpcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBBbiBpbnN0YW5jZSBvZiBhIGNsYXNzIGV4dGVuZGluZyBgTW9kZWxgIGZyb20gd2hpY2ggdmFsaWRhdGFibGUgcHJvcGVydGllcyB3aWxsIGJlIGV4dHJhY3RlZC5cbiAqIEBwYXJhbSB7c3RyaW5nW119IHByb3BzVG9JZ25vcmUgLSBBbiBhcnJheSBvZiBwcm9wZXJ0eSBuYW1lcyB0aGF0IHNob3VsZCBiZSBleGNsdWRlZCBmcm9tIHZhbGlkYXRpb24gaW5zcGVjdGlvbi5cbiAqXG4gKiBAcmV0dXJuIHtWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uW119IEFuIGFycmF5IG9mIHZhbGlkYXRpb24gZGVjb3JhdG9yIGRlZmluaXRpb25zXG4gKiBhc3NvY2lhdGVkIHdpdGggdGhlIG1vZGVsJ3MgcHJvcGVydGllcywgZXhjbHVkaW5nIHRob3NlIGxpc3RlZCBpbiBgcHJvcHNUb0lnbm9yZWAuXG4gKlxuICogQGZ1bmN0aW9uIGdldFZhbGlkYXRhYmxlUHJvcGVydGllc1xuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0VmFsaWRhdGFibGVQcm9wZXJ0aWVzPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBNLFxuICBwcm9wc1RvSWdub3JlOiBzdHJpbmdbXVxuKTogVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvbltdIHtcbiAgY29uc3QgZGVjb3JhdGVkUHJvcGVydGllczogVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvbltdID0gW107XG5cbiAgZm9yIChjb25zdCBwcm9wIGluIG1vZGVsKSB7XG4gICAgaWYgKFxuICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG1vZGVsLCBwcm9wKSAmJlxuICAgICAgIXByb3BzVG9JZ25vcmUuaW5jbHVkZXMocHJvcClcbiAgICApIHtcbiAgICAgIGNvbnN0IGRlYyA9IGdldFZhbGlkYXRpb25EZWNvcmF0b3JzKG1vZGVsLCBwcm9wKTtcbiAgICAgIGlmIChkZWMpIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChkZWMpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkZWNvcmF0ZWRQcm9wZXJ0aWVzO1xufVxuXG4vKipcbiAqIFNhZmVseSBzZXRzIHRlbXBvcmFyeSBtZXRhZGF0YSBvbiBhbiBvYmplY3RcbiAqL1xuZnVuY3Rpb24gc2V0VGVtcG9yYXJ5Q29udGV4dChcbiAgdGFyZ2V0OiBhbnksXG4gIGtleTogc3ltYm9sIHwgc3RyaW5nLFxuICB2YWx1ZTogdW5rbm93blxuKTogdm9pZCB7XG4gIGlmICghT2JqZWN0Lmhhc093blByb3BlcnR5LmNhbGwodGFyZ2V0LCBrZXkpKSB0YXJnZXRba2V5XSA9IHZhbHVlO1xufVxuXG4vKipcbiAqIFNhZmVseSByZW1vdmVzIHRlbXBvcmFyeSBtZXRhZGF0YSBmcm9tIGFuIG9iamVjdFxuICovXG5mdW5jdGlvbiBjbGVhbnVwVGVtcG9yYXJ5Q29udGV4dCh0YXJnZXQ6IGFueSwga2V5OiBzeW1ib2wgfCBzdHJpbmcpOiB2b2lkIHtcbiAgaWYgKE9iamVjdC5oYXNPd25Qcm9wZXJ0eS5jYWxsKHRhcmdldCwga2V5KSkgZGVsZXRlIHRhcmdldFtrZXldO1xufVxuXG4vKipcbiAqIEV4ZWN1dGVzIHZhbGlkYXRpb24gd2l0aCB0ZW1wb3JhcnkgY29udGV4dCBhbmQgcmV0dXJucyB0aGUgdmFsaWRhdGlvbiByZXN1bHRcbiAqXG4gKiBAcGFyYW0gbmVzdGVkTW9kZWwgLSBUaGUgaW5zdGFuY2UgdG8gdmFsaWRhdGVcbiAqIEBwYXJhbSBwYXJlbnRNb2RlbCAtIFJlZmVyZW5jZSB0byBhIHBhcmVudCBvYmplY3QgZm9yIG5lc3RlZCB2YWxpZGF0aW9uXG4gKiBAcGFyYW0gaXNBc3luYyAtIFdoZXRoZXIgdG8gcGVyZm9ybSBhc3luYyB2YWxpZGF0aW9uXG4gKiBAcmV0dXJucyBWYWxpZGF0aW9uIHJlc3VsdCBmcm9tIGhhc0Vycm9ycygpXG4gKi9cbmZ1bmN0aW9uIGdldE5lc3RlZFZhbGlkYXRpb25FcnJvcnM8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgQXN5bmMgZXh0ZW5kcyBib29sZWFuID0gZmFsc2UsXG4+KFxuICBuZXN0ZWRNb2RlbDogTSxcbiAgcGFyZW50TW9kZWw/OiBNLFxuICBpc0FzeW5jPzogQXN5bmNcbik6IENvbmRpdGlvbmFsQXN5bmM8QXN5bmMsIE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkPiB7XG4gIC8vIFNldCB0ZW1wb3JhcnkgY29udGV4dCBmb3IgbmVzdGVkIG1vZGVsc1xuICBpZiAocGFyZW50TW9kZWwpIHtcbiAgICBzZXRUZW1wb3JhcnlDb250ZXh0KG5lc3RlZE1vZGVsLCBWQUxJREFUSU9OX1BBUkVOVF9LRVksIHBhcmVudE1vZGVsKTtcbiAgfVxuICBzZXRUZW1wb3JhcnlDb250ZXh0KG5lc3RlZE1vZGVsLCBBU1lOQ19NRVRBX0tFWSwgISFpc0FzeW5jKTtcblxuICBjb25zdCBlcnJzID0gbmVzdGVkTW9kZWwuaGFzRXJyb3JzKCk7XG4gIGNsZWFudXBUZW1wb3JhcnlDb250ZXh0KG5lc3RlZE1vZGVsLCBWQUxJREFUSU9OX1BBUkVOVF9LRVkpO1xuICBjbGVhbnVwVGVtcG9yYXJ5Q29udGV4dChuZXN0ZWRNb2RlbCwgQVNZTkNfTUVUQV9LRVkpO1xuICByZXR1cm4gZXJycyBhcyBhbnk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZURlY29yYXRvcjxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBBc3luYyBleHRlbmRzIGJvb2xlYW4gPSBmYWxzZSxcbj4oXG4gIG1vZGVsOiBNLFxuICB2YWx1ZTogYW55LFxuICBkZWNvcmF0b3I6IERlY29yYXRvck1ldGFkYXRhQXN5bmMsXG4gIGFzeW5jPzogQXN5bmNcbik6IENvbmRpdGlvbmFsQXN5bmM8QXN5bmMsIHN0cmluZyB8IHVuZGVmaW5lZD4ge1xuICBjb25zdCB2YWxpZGF0b3IgPSBWYWxpZGF0aW9uLmdldChkZWNvcmF0b3Iua2V5KTtcbiAgaWYgKCF2YWxpZGF0b3IpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYE1pc3NpbmcgdmFsaWRhdG9yIGZvciAke2RlY29yYXRvci5rZXl9YCk7XG4gIH1cblxuICAvLyBza2lwIGFzeW5jIGRlY29yYXRvcnMgaWYgdmFsaWRhdGVEZWNvcmF0b3JzIGlzIGNhbGxlZCBzeW5jaHJvbm91c2x5IChhc3luYyA9IGZhbHNlKVxuICBpZiAoIWFzeW5jICYmIGRlY29yYXRvci5wcm9wcy5hc3luYykgcmV0dXJuIHVuZGVmaW5lZCBhcyBhbnk7XG5cbiAgY29uc3QgZGVjb3JhdG9yUHJvcHMgPVxuICAgIGRlY29yYXRvci5rZXkgPT09IE1vZGVsS2V5cy5UWVBFXG4gICAgICA/IFtkZWNvcmF0b3IucHJvcHNdXG4gICAgICA6IGRlY29yYXRvci5wcm9wcyB8fCB7fTtcblxuICBjb25zdCBjb250ZXh0ID0gUGF0aFByb3h5RW5naW5lLmNyZWF0ZShtb2RlbCwge1xuICAgIGlnbm9yZVVuZGVmaW5lZDogdHJ1ZSxcbiAgICBpZ25vcmVOdWxsOiB0cnVlLFxuICB9KTtcblxuICBjb25zdCBtYXliZUFzeW5jRXJyb3JzID0gdmFsaWRhdG9yLmhhc0Vycm9ycyhcbiAgICB2YWx1ZSxcbiAgICBkZWNvcmF0b3JQcm9wcyBhcyBWYWxpZGF0b3JPcHRpb25zLFxuICAgIGNvbnRleHRcbiAgKTtcblxuICByZXR1cm4gdG9Db25kaXRpb25hbFByb21pc2UobWF5YmVBc3luY0Vycm9ycywgYXN5bmMpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvblxuICogRXhlY3V0ZXMgdmFsaWRhdGlvbiBsb2dpYyBmb3IgYSBzZXQgb2YgZGVjb3JhdG9ycyBhcHBsaWVkIHRvIGEgbW9kZWwncyBwcm9wZXJ0eSwgaGFuZGxpbmcgYm90aFxuICogc3luY2hyb25vdXMgYW5kIGFzeW5jaHJvbm91cyB2YWxpZGF0aW9ucywgaW5jbHVkaW5nIHN1cHBvcnQgZm9yIG5lc3RlZCB2YWxpZGF0aW9ucyBhbmQgbGlzdHMuXG4gKlxuICogQHN1bW1hcnlcbiAqIEl0ZXJhdGVzIG92ZXIgYW4gYXJyYXkgb2YgZGVjb3JhdG9yIG1ldGFkYXRhIG9iamVjdHMgYW5kIGFwcGxpZXMgZWFjaCB2YWxpZGF0aW9uIHJ1bGUgdG8gdGhlXG4gKiBwcm92aWRlZCB2YWx1ZS4gRm9yIGxpc3QgZGVjb3JhdG9ycyAoYFZhbGlkYXRpb25LZXlzLkxJU1RgKSwgaXQgcGVyZm9ybXMgZWxlbWVudC13aXNlIHZhbGlkYXRpb24sXG4gKiBzdXBwb3J0aW5nIG5lc3RlZCBtb2RlbCB2YWxpZGF0aW9uIGFuZCB0eXBlIGNoZWNrcy4gSWYgdGhlIGBhc3luY2AgZmxhZyBpcyBzZXQsIGFzeW5jaHJvbm91c1xuICogdmFsaWRhdGlvbiBpcyBzdXBwb3J0ZWQgdXNpbmcgYFByb21pc2UuYWxsYC4gVGhlIHJlc3VsdCBpcyBhIHJlY29yZCBtYXBwaW5nIHZhbGlkYXRpb24ga2V5cyB0b1xuICogZXJyb3IgbWVzc2FnZXMsIG9yIGB1bmRlZmluZWRgIGlmIG5vIGVycm9ycyBhcmUgZm91bmQuXG4gKlxuICogQHRlbXBsYXRlIE0gLSBBIHR5cGUgcGFyYW1ldGVyIGV4dGVuZGluZyBgTW9kZWxgLCByZXByZXNlbnRpbmcgdGhlIG1vZGVsIHR5cGUgYmVpbmcgdmFsaWRhdGVkLlxuICogQHRlbXBsYXRlIEFzeW5jIC0gQSBib29sZWFuIGluZGljYXRpbmcgd2hldGhlciB2YWxpZGF0aW9uIHNob3VsZCBiZSBwZXJmb3JtZWQgYXN5bmNocm9ub3VzbHkuXG4gKlxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSB0aGF0IHRoZSB2YWxpZGF0aW9uIGlzIGFzc29jaWF0ZWQgd2l0aC5cbiAqIEBwYXJhbSB7YW55fSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byBiZSB2YWxpZGF0ZWQgYWdhaW5zdCB0aGUgcHJvdmlkZWQgZGVjb3JhdG9ycy5cbiAqIEBwYXJhbSB7RGVjb3JhdG9yTWV0YWRhdGFBc3luY1tdfSBkZWNvcmF0b3JzIC0gQW4gYXJyYXkgb2YgbWV0YWRhdGEgb2JqZWN0cyByZXByZXNlbnRpbmcgdmFsaWRhdGlvbiBkZWNvcmF0b3JzLlxuICogQHBhcmFtIHtBc3luY30gW2FzeW5jXSAtIE9wdGlvbmFsIGZsYWcgaW5kaWNhdGluZyB3aGV0aGVyIHZhbGlkYXRpb24gc2hvdWxkIGJlIHBlcmZvcm1lZCBhc3luY2hyb25vdXNseS5cbiAqXG4gKiBAcmV0dXJuIHtDb25kaXRpb25hbEFzeW5jPEFzeW5jLCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+PiB8IHVuZGVmaW5lZH1cbiAqIFJldHVybnMgZWl0aGVyIGEgcmVjb3JkIG9mIHZhbGlkYXRpb24gZXJyb3JzIChrZXllZCBieSB0aGUgZGVjb3JhdG9yIGtleSkgb3IgYHVuZGVmaW5lZGAgaWYgbm8gZXJyb3JzIGFyZSBmb3VuZC5cbiAqIElmIGBhc3luY2AgaXMgdHJ1ZSwgdGhlIHJldHVybiB2YWx1ZSBpcyBhIFByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBzYW1lIHN0cnVjdHVyZS5cbiAqXG4gKiBAZnVuY3Rpb24gdmFsaWRhdGVEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2YWxpZGF0ZURlY29yYXRvcnM8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgQXN5bmMgZXh0ZW5kcyBib29sZWFuID0gZmFsc2UsXG4+KFxuICBtb2RlbDogTSxcbiAgdmFsdWU6IGFueSxcbiAgZGVjb3JhdG9yczogRGVjb3JhdG9yTWV0YWRhdGFBc3luY1tdLFxuICBhc3luYz86IEFzeW5jXG4pOiBDb25kaXRpb25hbEFzeW5jPEFzeW5jLCBSZWNvcmQ8c3RyaW5nLCBzdHJpbmc+IHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IHJlc3VsdDogUmVjb3JkPHN0cmluZywgc3RyaW5nIHwgUHJvbWlzZTxzdHJpbmc+PiA9IHt9O1xuXG4gIGZvciAoY29uc3QgZGVjb3JhdG9yIG9mIGRlY29yYXRvcnMpIHtcbiAgICAvLyBza2lwIGFzeW5jIGRlY29yYXRvcnMgaWYgdmFsaWRhdGVEZWNvcmF0b3JzIGlzIGNhbGxlZCBzeW5jaHJvbm91c2x5IChhc3luYyA9IGZhbHNlKVxuICAgIGlmICghYXN5bmMgJiYgZGVjb3JhdG9yLnByb3BzLmFzeW5jKSBjb250aW51ZTtcblxuICAgIGxldCB2YWxpZGF0aW9uRXJyb3JzID0gdmFsaWRhdGVEZWNvcmF0b3IobW9kZWwsIHZhbHVlLCBkZWNvcmF0b3IsIGFzeW5jKTtcblxuICAgIC8qXG4gICAgSWYgdGhlIGRlY29yYXRvciBpcyBhIGxpc3QsIGVhY2ggZWxlbWVudCBtdXN0IGJlIGNoZWNrZWQuXG4gICAgV2hlbiAnYXN5bmMnIGlzIHRydWUsIHRoZSAnZXJyJyB3aWxsIGFsd2F5cyBiZSBhIHBlbmRpbmcgcHJvbWlzZSBpbml0aWFsbHksXG4gICAgc28gdGhlICchZXJyJyBjaGVjayB3aWxsIGV2YWx1YXRlIHRvIGZhbHNlIChldmVuIGlmIHRoZSBwcm9taXNlIGxhdGVyIHJlc29sdmVzIHdpdGggbm8gZXJyb3JzKVxuICAgICovXG4gICAgaWYgKGRlY29yYXRvci5rZXkgPT09IFZhbGlkYXRpb25LZXlzLkxJU1QgJiYgKCF2YWxpZGF0aW9uRXJyb3JzIHx8IGFzeW5jKSkge1xuICAgICAgY29uc3QgdmFsdWVzID0gdmFsdWUgaW5zdGFuY2VvZiBTZXQgPyBbLi4udmFsdWVdIDogdmFsdWU7XG4gICAgICBpZiAodmFsdWVzICYmIHZhbHVlcy5sZW5ndGggPiAwKSB7XG4gICAgICAgIGNvbnN0IHR5cGVzID1cbiAgICAgICAgICBkZWNvcmF0b3IucHJvcHMuY2xhc3MgfHxcbiAgICAgICAgICBkZWNvcmF0b3IucHJvcHMuY2xhenogfHxcbiAgICAgICAgICBkZWNvcmF0b3IucHJvcHMuY3VzdG9tVHlwZXM7XG5cbiAgICAgICAgY29uc3QgYWxsb3dlZFR5cGVzID0gW3R5cGVzXS5mbGF0KCkubWFwKCh0KSA9PiBTdHJpbmcodCkudG9Mb3dlckNhc2UoKSk7XG4gICAgICAgIC8vIGNvbnN0IHJlc2VydmVkID0gT2JqZWN0LnZhbHVlcyhSZXNlcnZlZE1vZGVscykubWFwKCh2KSA9PiB2LnRvTG93ZXJDYXNlKCkpIGFzIHN0cmluZ1tdO1xuXG4gICAgICAgIGNvbnN0IGVycnMgPSB2YWx1ZXMubWFwKChjaGlsZFZhbHVlOiBhbnkpID0+IHtcbiAgICAgICAgICAvLyBpZiAoTW9kZWwuaXNNb2RlbCh2KSAmJiAhcmVzZXJ2ZWQuaW5jbHVkZXModikge1xuICAgICAgICAgIGlmIChNb2RlbC5pc01vZGVsKGNoaWxkVmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gZ2V0TmVzdGVkVmFsaWRhdGlvbkVycm9ycyhjaGlsZFZhbHVlLCBtb2RlbCwgYXN5bmMpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIHJldHVybiBhbGxvd2VkVHlwZXMuaW5jbHVkZXModHlwZW9mIGNoaWxkVmFsdWUpXG4gICAgICAgICAgICA/IHVuZGVmaW5lZFxuICAgICAgICAgICAgOiBcIlZhbHVlIGhhcyBubyB2YWxpZGF0YWJsZSB0eXBlXCI7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmIChhc3luYykge1xuICAgICAgICAgIHZhbGlkYXRpb25FcnJvcnMgPSBQcm9taXNlLmFsbChlcnJzKS50aGVuKChyZXN1bHQpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGFsbEVtcHR5ID0gcmVzdWx0LmV2ZXJ5KChyKSA9PiAhcik7XG4gICAgICAgICAgICByZXR1cm4gYWxsRW1wdHkgPyB1bmRlZmluZWQgOiByZXN1bHQ7XG4gICAgICAgICAgfSkgYXMgYW55O1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IGFsbEVtcHR5ID0gZXJycy5ldmVyeSgocjogc3RyaW5nIHwgdW5kZWZpbmVkKSA9PiAhcik7XG4gICAgICAgICAgdmFsaWRhdGlvbkVycm9ycyA9IGVycnMubGVuZ3RoID4gMCAmJiAhYWxsRW1wdHkgPyBlcnJzIDogdW5kZWZpbmVkO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHZhbGlkYXRpb25FcnJvcnMpIChyZXN1bHQgYXMgYW55KVtkZWNvcmF0b3Iua2V5XSA9IHZhbGlkYXRpb25FcnJvcnM7XG4gIH1cblxuICBpZiAoIWFzeW5jKVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhyZXN1bHQpLmxlbmd0aCA+IDBcbiAgICAgID8gKHJlc3VsdCBhcyBhbnkpXG4gICAgICA6ICh1bmRlZmluZWQgYXMgYW55KTtcblxuICBjb25zdCBrZXlzID0gT2JqZWN0LmtleXMocmVzdWx0KTtcbiAgY29uc3QgcHJvbWlzZXMgPSBPYmplY3QudmFsdWVzKHJlc3VsdCkgYXMgUHJvbWlzZTxzdHJpbmcgfCB1bmRlZmluZWQ+W107XG4gIHJldHVybiBQcm9taXNlLmFsbChwcm9taXNlcykudGhlbigocmVzb2x2ZWRWYWx1ZXMpID0+IHtcbiAgICBjb25zdCByZXM6IFJlY29yZDxzdHJpbmcsIHN0cmluZz4gPSB7fTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc29sdmVkVmFsdWVzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCB2YWwgPSByZXNvbHZlZFZhbHVlc1tpXTtcbiAgICAgIGlmICh2YWwgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXNba2V5c1tpXV0gPSB2YWw7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBPYmplY3Qua2V5cyhyZXMpLmxlbmd0aCA+IDAgPyByZXMgOiB1bmRlZmluZWQ7XG4gIH0pIGFzIGFueTtcbn1cblxuLyoqXG4gKiBAZnVuY3Rpb24gdmFsaWRhdGVcbiAqIEB0ZW1wbGF0ZSBNXG4gKiBAdGVtcGxhdGUgQXN5bmNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGVjb3JhdG9yLXZhbGlkYXRpb25cbiAqIEBjYXRlZ29yeSBNb2RlbFxuICpcbiAqIEBkZXNjcmlwdGlvblxuICogVmFsaWRhdGVzIHRoZSBwcm9wZXJ0aWVzIG9mIGEge0BsaW5rIE1vZGVsfSBpbnN0YW5jZSB1c2luZyByZWdpc3RlcmVkIGRlY29yYXRvcnMuXG4gKiBTdXBwb3J0cyBib3RoIHN5bmNocm9ub3VzIGFuZCBhc3luY2hyb25vdXMgdmFsaWRhdGlvbiBmbG93cywgZGVwZW5kaW5nIG9uIHRoZSBgYXN5bmNgIGZsYWcuXG4gKlxuICogQHN1bW1hcnlcbiAqIFRoaXMgZnVuY3Rpb24gaW5zcGVjdHMgYSBnaXZlbiBtb2RlbCBvYmplY3QsIGlkZW50aWZpZXMgZGVjb3JhdGVkIHByb3BlcnRpZXMgdGhhdCByZXF1aXJlIHZhbGlkYXRpb24sXG4gKiBhbmQgYXBwbGllcyB0aGUgY29ycmVzcG9uZGluZyB2YWxpZGF0aW9uIHJ1bGVzLiBJdCBhbHNvIHN1cHBvcnRzIG5lc3RlZCBtb2RlbCB2YWxpZGF0aW9uIGFuZCBncmFjZWZ1bGx5XG4gKiBtZXJnZXMgYW55IHZhbGlkYXRpb24gZXJyb3JzLiBGb3IgY29sbGVjdGlvbnMgKEFycmF5L1NldCksIGl0IGVuZm9yY2VzIHRoZSBwcmVzZW5jZSBvZiB0aGUgYEBsaXN0YCBkZWNvcmF0b3JcbiAqIGFuZCBjaGVja3MgdGhlIHR5cGUgb2YgZWxlbWVudHMuIElmIGEgcHJvcGVydHkgaXMgYSBuZXN0ZWQgbW9kZWwsIGl0IHdpbGwgY2FsbCBgaGFzRXJyb3JzYCBvbiBpdCBhbmQgZmxhdHRlblxuICogdGhlIG5lc3RlZCBlcnJvciBrZXlzIHVzaW5nIGRvdCBub3RhdGlvbi5cbiAqXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIGJlIHZhbGlkYXRlZC4gTXVzdCBleHRlbmQgZnJvbSB7QGxpbmsgTW9kZWx9LlxuICogQHBhcmFtIHtBc3luY30gW2FzeW5jXSAtIEEgZmxhZyBpbmRpY2F0aW5nIHdoZXRoZXIgdmFsaWRhdGlvbiBzaG91bGQgYmUgYXN5bmNocm9ub3VzLlxuICogQHBhcmFtIHsuLi5zdHJpbmd9IHByb3BzVG9JZ25vcmUgLSBBIHZhcmlhZGljIGxpc3Qgb2YgcHJvcGVydHkgbmFtZXMgdGhhdCBzaG91bGQgYmUgc2tpcHBlZCBkdXJpbmcgdmFsaWRhdGlvbi5cbiAqXG4gKiBAcmV0dXJucyB7Q29uZGl0aW9uYWxBc3luYzxBc3luYywgTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQ+fVxuICogUmV0dXJucyBlaXRoZXIgYSB7QGxpbmsgTW9kZWxFcnJvckRlZmluaXRpb259IGNvbnRhaW5pbmcgdmFsaWRhdGlvbiBlcnJvcnMsXG4gKiBvciBgdW5kZWZpbmVkYCBpZiBubyBlcnJvcnMgYXJlIGZvdW5kLiBXaGVuIGBhc3luY2AgaXMgYHRydWVgLCByZXR1cm5zIGEgUHJvbWlzZS5cbiAqXG4gKiBAc2VlIHtAbGluayBNb2RlbH1cbiAqIEBzZWUge0BsaW5rIE1vZGVsRXJyb3JEZWZpbml0aW9ufVxuICogQHNlZSB7QGxpbmsgdmFsaWRhdGVEZWNvcmF0b3JzfVxuICogQHNlZSB7QGxpbmsgZ2V0VmFsaWRhdGFibGVQcm9wZXJ0aWVzfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgICBwYXJ0aWNpcGFudCB2YWxpZGF0ZVxuICogICAgIHBhcnRpY2lwYW50IGdldFZhbGlkYXRhYmxlUHJvcGVydGllc1xuICogICAgIHBhcnRpY2lwYW50IHZhbGlkYXRlRGVjb3JhdG9yc1xuICogICAgIHBhcnRpY2lwYW50IE1vZGVsSW5zdGFuY2VcbiAqICAgICBDYWxsZXItPj52YWxpZGF0ZTogY2FsbCB3aXRoIG9iaiwgYXN5bmMsIHByb3BzVG9JZ25vcmVcbiAqICAgICB2YWxpZGF0ZS0+PmdldFZhbGlkYXRhYmxlUHJvcGVydGllczogcmV0cmlldmUgZGVjb3JhdGVkIHByb3BzXG4gKiAgICAgbG9vcCBmb3IgZWFjaCBwcm9wZXJ0eVxuICogICAgICAgICB2YWxpZGF0ZS0+PnZhbGlkYXRlRGVjb3JhdG9yczogdmFsaWRhdGUgdXNpbmcgZGVjb3JhdG9yc1xuICogICAgICAgICBhbHQgaXMgbmVzdGVkIG1vZGVsXG4gKiAgICAgICAgICAgICB2YWxpZGF0ZS0+Pk1vZGVsSW5zdGFuY2U6IGNhbGwgaGFzRXJyb3JzKClcbiAqICAgICAgICAgZW5kXG4gKiAgICAgZW5kXG4gKiAgICAgYWx0IGFzeW5jXG4gKiAgICAgICAgIHZhbGlkYXRlLT4+dmFsaWRhdGU6IFByb21pc2UuYWxsU2V0dGxlZCBmb3IgZXJyb3JzXG4gKiAgICAgZW5kXG4gKiAgICAgdmFsaWRhdGUtLT4+Q2FsbGVyOiByZXR1cm4gTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWw8Ym9vbGVhbj4sXG4gIEFzeW5jIGV4dGVuZHMgYm9vbGVhbiA9IGZhbHNlLFxuPihcbiAgbW9kZWw6IE0sXG4gIGFzeW5jOiBBc3luYyxcbiAgLi4ucHJvcHNUb0lnbm9yZTogc3RyaW5nW11cbik6IENvbmRpdGlvbmFsQXN5bmM8QXN5bmMsIE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkPiB7XG4gIGNvbnN0IGRlY29yYXRlZFByb3BlcnRpZXM6IFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb25bXSA9XG4gICAgZ2V0VmFsaWRhdGFibGVQcm9wZXJ0aWVzKG1vZGVsLCBwcm9wc1RvSWdub3JlKTtcblxuICBjb25zdCByZXN1bHQ6IFJlY29yZDxzdHJpbmcsIGFueT4gPSB7fTtcbiAgY29uc3QgbmVzdGVkRXJyb3JzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG5cbiAgZm9yIChjb25zdCB7IHByb3AsIGRlY29yYXRvcnMgfSBvZiBkZWNvcmF0ZWRQcm9wZXJ0aWVzKSB7XG4gICAgY29uc3QgcHJvcEtleSA9IFN0cmluZyhwcm9wKTtcbiAgICBsZXQgcHJvcFZhbHVlID0gKG1vZGVsIGFzIGFueSlbcHJvcF07XG5cbiAgICBpZiAoIWRlY29yYXRvcnM/Lmxlbmd0aCkgY29udGludWU7XG5cbiAgICAvLyBHZXQgdGhlIGRlZmF1bHQgdHlwZSB2YWxpZGF0b3JcbiAgICBjb25zdCBkZXNpZ25UeXBlRGVjID0gZGVjb3JhdG9ycy5maW5kKChkKSA9PiB7XG4gICAgICByZXR1cm4gW01vZGVsS2V5cy5UWVBFLCBWYWxpZGF0aW9uS2V5cy5UWVBFXS5pbmNsdWRlcyhkLmtleSBhcyBhbnkpO1xuICAgIH0pO1xuXG4gICAgaWYgKCFkZXNpZ25UeXBlRGVjKSBjb250aW51ZTtcblxuICAgIGNvbnN0IGRlc2lnblR5cGUgPSBkZXNpZ25UeXBlRGVjLnByb3BzLm5hbWU7XG5cbiAgICAvLyBIYW5kbGUgYXJyYXkgb3IgU2V0IHR5cGVzIGFuZCBlbmZvcmNlIHRoZSBwcmVzZW5jZSBvZiBAbGlzdCBkZWNvcmF0b3JcbiAgICBpZiAoW0FycmF5Lm5hbWUsIFNldC5uYW1lXS5pbmNsdWRlcyhkZXNpZ25UeXBlKSkge1xuICAgICAgaWYgKCFkZWNvcmF0b3JzLnNvbWUoKGQpID0+IGQua2V5ID09PSBWYWxpZGF0aW9uS2V5cy5MSVNUKSkge1xuICAgICAgICByZXN1bHRbcHJvcEtleV0gPSB7XG4gICAgICAgICAgW1ZhbGlkYXRpb25LZXlzLlRZUEVdOiBgQXJyYXkgb3IgU2V0IHByb3BlcnR5ICcke3Byb3BLZXl9JyByZXF1aXJlcyBhIEBsaXN0IGRlY29yYXRvcmAsXG4gICAgICAgIH07XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuXG4gICAgICBpZiAoXG4gICAgICAgIHByb3BWYWx1ZSAmJlxuICAgICAgICAhKEFycmF5LmlzQXJyYXkocHJvcFZhbHVlKSB8fCBwcm9wVmFsdWUgaW5zdGFuY2VvZiBTZXQpXG4gICAgICApIHtcbiAgICAgICAgcmVzdWx0W3Byb3BLZXldID0ge1xuICAgICAgICAgIFtWYWxpZGF0aW9uS2V5cy5UWVBFXTogYFByb3BlcnR5ICcke1N0cmluZyhwcm9wKX0nIG11c3QgYmUgZWl0aGVyIGFuIEFycmF5IG9yIGEgU2V0YCxcbiAgICAgICAgfTtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbW92ZSBkZXNpZ246dHlwZSBkZWNvcmF0b3IsIHNpbmNlIEBsaXN0IGRlY29yYXRvciBhbHJlYWR5IGVuc3VyZXMgdHlwZVxuICAgICAgZm9yIChsZXQgaSA9IGRlY29yYXRvcnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgICAgaWYgKGRlY29yYXRvcnNbaV0ua2V5ID09PSBNb2RlbEtleXMuVFlQRSkge1xuICAgICAgICAgIGRlY29yYXRvcnMuc3BsaWNlKGksIDEpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBwcm9wVmFsdWUgPSBwcm9wVmFsdWUgaW5zdGFuY2VvZiBTZXQgPyBbLi4ucHJvcFZhbHVlXSA6IHByb3BWYWx1ZTtcbiAgICB9XG5cbiAgICBjb25zdCBwcm9wRXJyb3JzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID1cbiAgICAgIHZhbGlkYXRlRGVjb3JhdG9ycyhtb2RlbCwgcHJvcFZhbHVlLCBkZWNvcmF0b3JzLCBhc3luYykgfHwge307XG5cbiAgICAvLyBDaGVjayBmb3IgbmVzdGVkIHByb3BlcnRpZXMuXG4gICAgLy8gVG8gcHJldmVudCB1bm5lY2Vzc2FyeSBwcm9jZXNzaW5nLCBcInByb3BWYWx1ZVwiIG11c3QgYmUgZGVmaW5lZCBhbmQgdmFsaWRhdGFibGVcbiAgICAvLyBsZXQgbmVzdGVkRXJyb3JzOiBSZWNvcmQ8c3RyaW5nLCBhbnk+ID0ge307XG4gICAgY29uc3QgaXNDb25zdHIgPSBNb2RlbC5pc1Byb3BlcnR5TW9kZWwobW9kZWwsIHByb3BLZXkpO1xuICAgIC8vIGlmIHByb3BWYWx1ZSAhPT0gdW5kZWZpbmVkLCBudWxsXG4gICAgaWYgKHByb3BWYWx1ZSAmJiBpc0NvbnN0cikge1xuICAgICAgY29uc3QgaW5zdGFuY2U6IE1vZGVsID0gcHJvcFZhbHVlO1xuICAgICAgY29uc3QgaXNJbnZhbGlkTW9kZWwgPVxuICAgICAgICB0eXBlb2YgaW5zdGFuY2UgIT09IFwib2JqZWN0XCIgfHxcbiAgICAgICAgIWluc3RhbmNlLmhhc0Vycm9ycyB8fFxuICAgICAgICB0eXBlb2YgaW5zdGFuY2UuaGFzRXJyb3JzICE9PSBcImZ1bmN0aW9uXCI7XG5cbiAgICAgIGlmIChpc0ludmFsaWRNb2RlbCkge1xuICAgICAgICAvLyBwcm9wRXJyb3JzW1ZhbGlkYXRpb25LZXlzLlRZUEVdID0gXCJNb2RlbCBzaG91bGQgYmUgdmFsaWRhdGFibGUgYnV0IGl0J3Mgbm90LlwiO1xuICAgICAgICBjb25zb2xlLndhcm4oXCJNb2RlbCBzaG91bGQgYmUgdmFsaWRhdGFibGUgYnV0IGl0J3Mgbm90LlwiKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5lc3RlZEVycm9yc1twcm9wS2V5XSA9IGdldE5lc3RlZFZhbGlkYXRpb25FcnJvcnMoXG4gICAgICAgICAgaW5zdGFuY2UsXG4gICAgICAgICAgbW9kZWwsXG4gICAgICAgICAgYXN5bmNcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBBZGQgdG8gdGhlIHJlc3VsdCBpZiB3ZSBoYXZlIGFueSBlcnJvcnNcbiAgICAvLyBBc3luYyBtb2RlIHJldHVybnMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdW5kZWZpbmVkIHdoZW4gbm8gZXJyb3JzIGV4aXN0XG4gICAgaWYgKE9iamVjdC5rZXlzKHByb3BFcnJvcnMpLmxlbmd0aCA+IDAgfHwgYXN5bmMpXG4gICAgICByZXN1bHRbcHJvcEtleV0gPSBwcm9wRXJyb3JzO1xuXG4gICAgLy8gVGhlbiBtZXJnZSBhbnkgbmVzdGVkIGVycm9yc1xuICAgIGlmICghYXN5bmMpIHtcbiAgICAgIE9iamVjdC5lbnRyaWVzKG5lc3RlZEVycm9yc1twcm9wS2V5XSB8fCB7fSkuZm9yRWFjaCgoW2tleSwgZXJyb3JdKSA9PiB7XG4gICAgICAgIGlmIChlcnJvciAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmVzdWx0W2Ake3Byb3BLZXl9LiR7a2V5fWBdID0gZXJyb3I7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIFN5bmNocm9ub3VzIHJldHVyblxuICBpZiAoIWFzeW5jKSB7XG4gICAgcmV0dXJuIChcbiAgICAgIE9iamVjdC5rZXlzKHJlc3VsdCkubGVuZ3RoID4gMFxuICAgICAgICA/IG5ldyBNb2RlbEVycm9yRGVmaW5pdGlvbihyZXN1bHQpXG4gICAgICAgIDogdW5kZWZpbmVkXG4gICAgKSBhcyBhbnk7XG4gIH1cblxuICBjb25zdCBtZXJnZWQ6IGFueSA9IHJlc3VsdDsgLy8gVE9ETzogYXBwbHkgZmlsdGVyaW5nXG5cbiAgY29uc3Qga2V5cyA9IE9iamVjdC5rZXlzKG1lcmdlZCk7XG4gIGNvbnN0IHByb21pc2VzID0gT2JqZWN0LnZhbHVlcyhtZXJnZWQpO1xuICByZXR1cm4gUHJvbWlzZS5hbGxTZXR0bGVkKHByb21pc2VzKS50aGVuKGFzeW5jIChyZXN1bHRzKSA9PiB7XG4gICAgY29uc3QgcmVzdWx0OiBNb2RlbEVycm9ycyA9IHt9O1xuXG4gICAgZm9yIChjb25zdCBbcGFyZW50UHJvcCwgbmVzdGVkRXJyUHJvbWlzZV0gb2YgT2JqZWN0LmVudHJpZXMobmVzdGVkRXJyb3JzKSkge1xuICAgICAgY29uc3QgbmVzdGVkUHJvcERlY0Vycm9ycyA9IChhd2FpdCBuZXN0ZWRFcnJQcm9taXNlKSBhcyBSZWNvcmQ8XG4gICAgICAgIHN0cmluZyxcbiAgICAgICAgYW55XG4gICAgICA+O1xuXG4gICAgICBpZiAobmVzdGVkUHJvcERlY0Vycm9ycylcbiAgICAgICAgT2JqZWN0LmVudHJpZXMobmVzdGVkUHJvcERlY0Vycm9ycykuZm9yRWFjaChcbiAgICAgICAgICAoW25lc3RlZFByb3AsIG5lc3RlZFByb3BEZWNFcnJvcl0pID0+IHtcbiAgICAgICAgICAgIGlmIChuZXN0ZWRQcm9wRGVjRXJyb3IgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICBjb25zdCBuZXN0ZWRLZXkgPSBbcGFyZW50UHJvcCwgbmVzdGVkUHJvcF0uam9pbihcIi5cIik7XG4gICAgICAgICAgICAgIHJlc3VsdFtuZXN0ZWRLZXldID0gbmVzdGVkUHJvcERlY0Vycm9yO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgKTtcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IHJlc3VsdHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGtleSA9IGtleXNbaV07XG4gICAgICBjb25zdCByZXMgPSByZXN1bHRzW2ldO1xuXG4gICAgICBpZiAocmVzLnN0YXR1cyA9PT0gXCJmdWxmaWxsZWRcIiAmJiByZXMudmFsdWUgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAocmVzdWx0IGFzIGFueSlba2V5XSA9IHJlcy52YWx1ZTtcbiAgICAgIH0gZWxzZSBpZiAocmVzLnN0YXR1cyA9PT0gXCJyZWplY3RlZFwiKSB7XG4gICAgICAgIChyZXN1bHQgYXMgYW55KVtrZXldID1cbiAgICAgICAgICByZXMucmVhc29uIGluc3RhbmNlb2YgRXJyb3JcbiAgICAgICAgICAgID8gcmVzLnJlYXNvbi5tZXNzYWdlXG4gICAgICAgICAgICA6IFN0cmluZyhyZXMucmVhc29uIHx8IFwiVmFsaWRhdGlvbiBmYWlsZWRcIik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIE9iamVjdC5rZXlzKHJlc3VsdCkubGVuZ3RoID4gMFxuICAgICAgPyBuZXcgTW9kZWxFcnJvckRlZmluaXRpb24ocmVzdWx0KVxuICAgICAgOiB1bmRlZmluZWQ7XG4gIH0pIGFzIGFueTtcbn1cbiJdfQ==