@decaf-ts/db-decorators 0.6.1 → 0.6.2

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 (141) hide show
  1. package/LICENSE.md +21 -157
  2. package/README.md +571 -10
  3. package/dist/db-decorators.cjs +1352 -322
  4. package/dist/db-decorators.esm.cjs +1352 -323
  5. package/lib/esm/identity/decorators.d.ts +7 -0
  6. package/lib/esm/identity/decorators.js +11 -4
  7. package/lib/esm/identity/index.js +3 -3
  8. package/lib/esm/identity/utils.d.ts +36 -23
  9. package/lib/esm/identity/utils.js +38 -25
  10. package/lib/esm/index.d.ts +12 -27
  11. package/lib/esm/index.js +13 -28
  12. package/lib/esm/interfaces/BulkCrudOperator.d.ts +39 -0
  13. package/lib/esm/interfaces/BulkCrudOperator.js +1 -1
  14. package/lib/esm/interfaces/Contextual.d.ts +17 -0
  15. package/lib/esm/interfaces/Contextual.js +1 -1
  16. package/lib/esm/interfaces/CrudOperator.d.ts +26 -23
  17. package/lib/esm/interfaces/CrudOperator.js +1 -1
  18. package/lib/esm/interfaces/IRepository.d.ts +10 -2
  19. package/lib/esm/interfaces/IRepository.js +1 -1
  20. package/lib/esm/interfaces/index.js +5 -5
  21. package/lib/esm/model/constants.d.ts +11 -13
  22. package/lib/esm/model/constants.js +12 -14
  23. package/lib/esm/model/decorators.d.ts +112 -23
  24. package/lib/esm/model/decorators.js +119 -29
  25. package/lib/esm/model/index.d.ts +1 -0
  26. package/lib/esm/model/index.js +7 -6
  27. package/lib/esm/model/model.d.ts +2 -141
  28. package/lib/esm/model/model.js +2 -13
  29. package/lib/esm/model/overrides.d.ts +1 -0
  30. package/lib/esm/model/overrides.js +23 -0
  31. package/lib/esm/model/utils.d.ts +39 -0
  32. package/lib/esm/model/utils.js +42 -3
  33. package/lib/esm/model/validation.d.ts +26 -8
  34. package/lib/esm/model/validation.js +29 -11
  35. package/lib/esm/operations/Operations.d.ts +65 -3
  36. package/lib/esm/operations/Operations.js +68 -6
  37. package/lib/esm/operations/OperationsRegistry.d.ts +44 -16
  38. package/lib/esm/operations/OperationsRegistry.js +46 -18
  39. package/lib/esm/operations/constants.d.ts +27 -8
  40. package/lib/esm/operations/constants.js +16 -9
  41. package/lib/esm/operations/decorators.d.ts +140 -134
  42. package/lib/esm/operations/decorators.js +152 -137
  43. package/lib/esm/operations/index.js +6 -6
  44. package/lib/esm/operations/types.d.ts +10 -0
  45. package/lib/esm/operations/types.js +1 -1
  46. package/lib/esm/repository/BaseRepository.d.ts +322 -0
  47. package/lib/esm/repository/BaseRepository.js +297 -7
  48. package/lib/esm/repository/Context.d.ts +153 -2
  49. package/lib/esm/repository/Context.js +154 -6
  50. package/lib/esm/repository/Repository.d.ts +89 -0
  51. package/lib/esm/repository/Repository.js +96 -7
  52. package/lib/esm/repository/constants.d.ts +7 -0
  53. package/lib/esm/repository/constants.js +8 -1
  54. package/lib/esm/repository/errors.d.ts +61 -34
  55. package/lib/esm/repository/errors.js +62 -35
  56. package/lib/esm/repository/index.js +9 -9
  57. package/lib/esm/repository/types.d.ts +25 -0
  58. package/lib/esm/repository/types.js +1 -1
  59. package/lib/esm/repository/utils.d.ts +11 -0
  60. package/lib/esm/repository/utils.js +4 -4
  61. package/lib/esm/repository/wrappers.d.ts +2 -2
  62. package/lib/esm/repository/wrappers.js +5 -5
  63. package/lib/esm/validation/constants.d.ts +20 -5
  64. package/lib/esm/validation/constants.js +22 -7
  65. package/lib/esm/validation/decorators.d.ts +101 -19
  66. package/lib/esm/validation/decorators.js +109 -27
  67. package/lib/esm/validation/index.js +5 -5
  68. package/lib/esm/validation/validation.js +10 -2
  69. package/lib/esm/validation/validators/ReadOnlyValidator.d.ts +32 -8
  70. package/lib/esm/validation/validators/ReadOnlyValidator.js +34 -10
  71. package/lib/esm/validation/validators/TimestampValidator.d.ts +37 -3
  72. package/lib/esm/validation/validators/TimestampValidator.js +39 -5
  73. package/lib/esm/validation/validators/UpdateValidator.d.ts +28 -11
  74. package/lib/esm/validation/validators/UpdateValidator.js +23 -8
  75. package/lib/esm/validation/validators/index.js +4 -4
  76. package/lib/identity/decorators.cjs +8 -1
  77. package/lib/identity/decorators.d.ts +7 -0
  78. package/lib/identity/utils.cjs +35 -22
  79. package/lib/identity/utils.d.ts +36 -23
  80. package/lib/index.cjs +14 -28
  81. package/lib/index.d.ts +12 -27
  82. package/lib/interfaces/BulkCrudOperator.cjs +1 -1
  83. package/lib/interfaces/BulkCrudOperator.d.ts +39 -0
  84. package/lib/interfaces/Contextual.cjs +1 -1
  85. package/lib/interfaces/Contextual.d.ts +17 -0
  86. package/lib/interfaces/CrudOperator.cjs +1 -1
  87. package/lib/interfaces/CrudOperator.d.ts +26 -23
  88. package/lib/interfaces/IRepository.cjs +1 -1
  89. package/lib/interfaces/IRepository.d.ts +10 -2
  90. package/lib/model/constants.cjs +12 -14
  91. package/lib/model/constants.d.ts +11 -13
  92. package/lib/model/decorators.cjs +114 -24
  93. package/lib/model/decorators.d.ts +112 -23
  94. package/lib/model/index.cjs +2 -1
  95. package/lib/model/index.d.ts +1 -0
  96. package/lib/model/model.cjs +1 -13
  97. package/lib/model/model.d.ts +2 -141
  98. package/lib/model/overrides.cjs +25 -0
  99. package/lib/model/overrides.d.ts +1 -0
  100. package/lib/model/utils.cjs +40 -1
  101. package/lib/model/utils.d.ts +39 -0
  102. package/lib/model/validation.cjs +27 -9
  103. package/lib/model/validation.d.ts +26 -8
  104. package/lib/operations/Operations.cjs +66 -4
  105. package/lib/operations/Operations.d.ts +65 -3
  106. package/lib/operations/OperationsRegistry.cjs +45 -17
  107. package/lib/operations/OperationsRegistry.d.ts +44 -16
  108. package/lib/operations/constants.cjs +16 -9
  109. package/lib/operations/constants.d.ts +27 -8
  110. package/lib/operations/decorators.cjs +150 -135
  111. package/lib/operations/decorators.d.ts +140 -134
  112. package/lib/operations/types.cjs +1 -1
  113. package/lib/operations/types.d.ts +10 -0
  114. package/lib/repository/BaseRepository.cjs +291 -1
  115. package/lib/repository/BaseRepository.d.ts +322 -0
  116. package/lib/repository/Context.cjs +153 -5
  117. package/lib/repository/Context.d.ts +153 -2
  118. package/lib/repository/Repository.cjs +90 -1
  119. package/lib/repository/Repository.d.ts +89 -0
  120. package/lib/repository/constants.cjs +8 -1
  121. package/lib/repository/constants.d.ts +7 -0
  122. package/lib/repository/errors.cjs +62 -35
  123. package/lib/repository/errors.d.ts +61 -34
  124. package/lib/repository/types.cjs +1 -1
  125. package/lib/repository/types.d.ts +25 -0
  126. package/lib/repository/utils.cjs +1 -1
  127. package/lib/repository/utils.d.ts +11 -0
  128. package/lib/repository/wrappers.cjs +3 -3
  129. package/lib/repository/wrappers.d.ts +2 -2
  130. package/lib/validation/constants.cjs +21 -6
  131. package/lib/validation/constants.d.ts +20 -5
  132. package/lib/validation/decorators.cjs +102 -20
  133. package/lib/validation/decorators.d.ts +101 -19
  134. package/lib/validation/validation.cjs +9 -1
  135. package/lib/validation/validators/ReadOnlyValidator.cjs +33 -9
  136. package/lib/validation/validators/ReadOnlyValidator.d.ts +32 -8
  137. package/lib/validation/validators/TimestampValidator.cjs +38 -4
  138. package/lib/validation/validators/TimestampValidator.d.ts +37 -3
  139. package/lib/validation/validators/UpdateValidator.cjs +23 -8
  140. package/lib/validation/validators/UpdateValidator.d.ts +28 -11
  141. package/package.json +2 -2
@@ -5,10 +5,10 @@
5
5
  })(this, (function (exports, decoratorValidation, tslib, reflection, typedObjectAccumulator) { 'use strict';
6
6
 
7
7
  /**
8
- * @summary Holds the Model reflection keys
8
+ * @description Database reflection keys
9
+ * @summary Collection of keys used for reflection metadata in database operations
9
10
  * @const DBKeys
10
- *
11
- * @memberOf module:db-decorators.Model
11
+ * @memberOf module:db-decorators
12
12
  */
13
13
  const DBKeys = {
14
14
  REFLECT: `${decoratorValidation.ModelKeys.REFLECT}persistence.`,
@@ -27,27 +27,35 @@
27
27
  ORIGINAL: "__originalObj",
28
28
  };
29
29
  /**
30
- * @summary The default separator when concatenating indexes
31
- *
32
- * @const DefaultIndexSeparator
33
- *
34
- * @category Managers
35
- * @subcategory Constants
30
+ * @description Default separator character for composite indexes
31
+ * @summary The default separator character used when concatenating multiple fields into a single index
32
+ * @const DefaultSeparator
33
+ * @memberOf module:db-decorators
36
34
  */
37
35
  const DefaultSeparator = "_";
38
36
  /**
39
- * @summary Holds the default timestamp date format
40
- * @constant DEFAULT_TIMESTAMP_FORMAT
41
- *
42
- * @memberOf module:db-decorators.Model
37
+ * @description Default format for timestamp fields
38
+ * @summary Standard date format string used for timestamp fields in database models
39
+ * @const DEFAULT_TIMESTAMP_FORMAT
40
+ * @memberOf module:db-decorators
43
41
  */
44
42
  const DEFAULT_TIMESTAMP_FORMAT = "dd/MM/yyyy HH:mm:ss:S";
45
43
 
46
44
  /**
47
- * @summary holds the default error messages
45
+ * @description Collection of default error messages used by validators.
46
+ * @summary Holds the default error messages for various validation scenarios including ID validation, readonly properties, and timestamps.
47
+ * @typedef {Object} ErrorMessages
48
+ * @property {Object} ID - Error messages for ID validation
49
+ * @property {string} ID.INVALID - Error message when an ID is invalid
50
+ * @property {string} ID.REQUIRED - Error message when an ID is missing
51
+ * @property {Object} READONLY - Error messages for readonly properties
52
+ * @property {string} READONLY.INVALID - Error message when attempting to update a readonly property
53
+ * @property {Object} TIMESTAMP - Error messages for timestamp validation
54
+ * @property {string} TIMESTAMP.REQUIRED - Error message when a timestamp is missing
55
+ * @property {string} TIMESTAMP.DATE - Error message when a timestamp is not a valid date
56
+ * @property {string} TIMESTAMP.INVALID - Error message when a timestamp is not increasing
48
57
  * @const DEFAULT_ERROR_MESSAGES
49
- *
50
- * @memberOf module:db-decorators.Model
58
+ * @memberOf module:validation
51
59
  */
52
60
  const DEFAULT_ERROR_MESSAGES = {
53
61
  ID: {
@@ -64,9 +72,14 @@
64
72
  },
65
73
  };
66
74
  /**
67
- * @summary Update reflection keys
75
+ * @description Constants used for reflection-based validation during update operations.
76
+ * @summary Keys used for storing and retrieving validation metadata on model properties during update operations.
77
+ * @typedef {Object} ValidationKeys
78
+ * @property {string} REFLECT - Base reflection key prefix for update validation
79
+ * @property {string} TIMESTAMP - Key for timestamp validation
80
+ * @property {string} READONLY - Key for readonly property validation
68
81
  * @const UpdateValidationKeys
69
- * @memberOf module:db-decorators.Operations
82
+ * @memberOf module:validation
70
83
  */
71
84
  const UpdateValidationKeys = {
72
85
  REFLECT: "db.update.validation.",
@@ -75,11 +88,29 @@
75
88
  };
76
89
 
77
90
  /**
78
- * @summary Validator for the {@link readonly} decorator
79
- *
91
+ * @description A validator that ensures properties marked as readonly cannot be modified during updates.
92
+ * @summary Validator for the {@link readonly} decorator that checks if a value has been changed during an update operation. It compares the new value with the old value and returns an error message if they are not equal.
93
+ * @param {any} value - The value to be validated
94
+ * @param {any} oldValue - The previous value to compare against
95
+ * @param {string} [message] - Optional custom error message
80
96
  * @class ReadOnlyValidator
81
- * @extends Validator
82
- *
97
+ * @example
98
+ * // Using ReadOnlyValidator with a readonly property
99
+ * class User {
100
+ * @readonly()
101
+ * id: string;
102
+ *
103
+ * name: string;
104
+ *
105
+ * constructor(id: string, name: string) {
106
+ * this.id = id;
107
+ * this.name = name;
108
+ * }
109
+ * }
110
+ *
111
+ * // This will trigger validation error when trying to update
112
+ * const user = new User('123', 'John');
113
+ * user.id = '456'; // Will be prevented by ReadOnlyValidator
83
114
  * @category Validators
84
115
  */
85
116
  exports.ReadOnlyValidator = class ReadOnlyValidator extends decoratorValidation.Validator {
@@ -87,17 +118,23 @@
87
118
  super(DEFAULT_ERROR_MESSAGES.READONLY.INVALID);
88
119
  }
89
120
  /**
90
- * @inheritDoc
121
+ * @description Implementation of the base validator's hasErrors method.
122
+ * @summary This method is required by the Validator interface but not used in this validator as validation only happens during updates.
123
+ * @param {any} value - The value to validate
124
+ * @param {any[]} args - Additional arguments
125
+ * @return {string | undefined} Always returns undefined as this validator only works during updates
91
126
  */
92
127
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
93
128
  hasErrors(value, ...args) {
94
129
  return undefined;
95
130
  }
96
131
  /**
97
- * @summary Validates a value has not changed
98
- * @param {any} value
99
- * @param {any} oldValue
100
- * @param {string} [message] the error message override
132
+ * @description Checks if a value has been modified during an update operation.
133
+ * @summary Validates a value has not changed by comparing it with the previous value using deep equality.
134
+ * @param {any} value - The new value to validate
135
+ * @param {any} oldValue - The original value to compare against
136
+ * @param {string} [message] - Optional custom error message to override the default
137
+ * @return {string | undefined} An error message if validation fails, undefined otherwise
101
138
  */
102
139
  updateHasErrors(value, oldValue, message) {
103
140
  if (value === undefined)
@@ -113,21 +150,55 @@
113
150
  ], exports.ReadOnlyValidator);
114
151
 
115
152
  /**
116
- * @summary Validates the update of a timestamp
117
- *
153
+ * @description A validator that ensures timestamp values are only updated with newer timestamps.
154
+ * @summary Validates the update of a timestamp by comparing the new timestamp with the old one, ensuring the new timestamp is more recent.
155
+ * @param {Date|string|number} value - The timestamp value to validate
156
+ * @param {Date|string|number} oldValue - The previous timestamp to compare against
157
+ * @param {string} [message] - Optional custom error message
118
158
  * @class TimestampValidator
119
- * @extends Validator
120
- *
159
+ * @example
160
+ * // Using TimestampValidator with a timestamp property
161
+ * class Document {
162
+ * @timestamp()
163
+ * updatedAt: Date;
164
+ *
165
+ * title: string;
166
+ *
167
+ * constructor(title: string) {
168
+ * this.title = title;
169
+ * this.updatedAt = new Date();
170
+ * }
171
+ * }
172
+ *
173
+ * // This will trigger validation error when trying to update with an older timestamp
174
+ * const doc = new Document('My Document');
175
+ * const oldDate = new Date(2020, 0, 1);
176
+ * doc.updatedAt = oldDate; // Will be prevented by TimestampValidator
121
177
  * @category Validators
122
178
  */
123
179
  exports.TimestampValidator = class TimestampValidator extends decoratorValidation.Validator {
124
180
  constructor() {
125
181
  super(DEFAULT_ERROR_MESSAGES.TIMESTAMP.INVALID);
126
182
  }
183
+ /**
184
+ * @description Implementation of the base validator's hasErrors method.
185
+ * @summary This method is required by the Validator interface but not used in this validator as validation only happens during updates.
186
+ * @param {any} value - The timestamp value to validate
187
+ * @param {any[]} args - Additional arguments
188
+ * @return {string | undefined} Always returns undefined as this validator only works during updates
189
+ */
127
190
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
128
191
  hasErrors(value, ...args) {
129
192
  return undefined;
130
193
  }
194
+ /**
195
+ * @description Validates that a timestamp is newer than its previous value.
196
+ * @summary Checks if a timestamp has been updated with a more recent value by converting both values to Date objects and comparing them.
197
+ * @param {Date|string|number} value - The new timestamp value to validate
198
+ * @param {Date|string|number} oldValue - The original timestamp to compare against
199
+ * @param {string} [message] - Optional custom error message to override the default
200
+ * @return {string | undefined} An error message if validation fails (new timestamp is not newer), undefined otherwise
201
+ */
131
202
  updateHasErrors(value, oldValue, message) {
132
203
  if (value === undefined)
133
204
  return;
@@ -149,15 +220,30 @@
149
220
  ], exports.TimestampValidator);
150
221
 
151
222
  /**
152
- * @summary Base class for an Update validator
153
- *
154
- * @param {string} [message] error message. defaults to {@link DecoratorMessages#DEFAULT}
155
- * @param {string[]} [acceptedTypes] the accepted value types by the decorator
156
- *
223
+ * @description Abstract base class for validators that compare new values with old values during updates.
224
+ * @summary Base class for an Update validator that provides a framework for implementing validation logic that compares a new value with its previous state.
225
+ * @param {string} [message] - Error message. Defaults to {@link DecoratorMessages#DEFAULT}
226
+ * @param {string[]} [acceptedTypes] - The accepted value types by the decorator
157
227
  * @class UpdateValidator
158
- * @abstract
159
- * @extends Validator
160
- *
228
+ * @example
229
+ * // Extending UpdateValidator to create a custom validator
230
+ * class MyCustomValidator extends UpdateValidator {
231
+ * constructor() {
232
+ * super("Custom validation failed");
233
+ * }
234
+ *
235
+ * public updateHasErrors(value: any, oldValue: any): string | undefined {
236
+ * // Custom validation logic
237
+ * if (value === oldValue) {
238
+ * return this.message;
239
+ * }
240
+ * return undefined;
241
+ * }
242
+ *
243
+ * hasErrors(value: any): string | undefined {
244
+ * return undefined; // Not used for update validators
245
+ * }
246
+ * }
161
247
  * @category Validators
162
248
  */
163
249
  class UpdateValidator extends decoratorValidation.Validator {
@@ -166,15 +252,24 @@
166
252
  }
167
253
  }
168
254
 
255
+ /**
256
+ * @description Generates a key for update validation metadata.
257
+ * @summary Builds the key to store as metadata under Reflections for update validation by prefixing the provided key with the update validation prefix.
258
+ * @param {string} key - The base key to be prefixed
259
+ * @return {string} The complete metadata key for update validation
260
+ * @function updateKey
261
+ * @memberOf module:db-decorators
262
+ */
169
263
  decoratorValidation.Validation.updateKey = function (key) {
170
264
  return UpdateValidationKeys.REFLECT + key;
171
265
  };
172
266
 
173
267
  /**
174
- * @summary Set of constants to define db CRUD operations and their equivalent 'on' and 'after' phases
175
- * @const OperationKeys
176
- *
177
- * @memberOf module:db-decorators.Operations
268
+ * @description Database operation key constants
269
+ * @summary Enum defining CRUD operations and their lifecycle phases
270
+ * @enum {string}
271
+ * @readonly
272
+ * @memberOf module:db-decorators
178
273
  */
179
274
  exports.OperationKeys = void 0;
180
275
  (function (OperationKeys) {
@@ -186,6 +281,13 @@
186
281
  OperationKeys["ON"] = "on.";
187
282
  OperationKeys["AFTER"] = "after.";
188
283
  })(exports.OperationKeys || (exports.OperationKeys = {}));
284
+ /**
285
+ * @description Bulk database operation key constants
286
+ * @summary Enum defining bulk CRUD operations for handling multiple records at once
287
+ * @enum {string}
288
+ * @readonly
289
+ * @memberOf module:db-decorators
290
+ */
189
291
  exports.BulkCrudOperationKeys = void 0;
190
292
  (function (BulkCrudOperationKeys) {
191
293
  BulkCrudOperationKeys["CREATE_ALL"] = "createAll";
@@ -194,11 +296,10 @@
194
296
  BulkCrudOperationKeys["DELETE_ALL"] = "deleteAll";
195
297
  })(exports.BulkCrudOperationKeys || (exports.BulkCrudOperationKeys = {}));
196
298
  /**
299
+ * @description Grouped CRUD operations for decorator mapping
197
300
  * @summary Maps out groups of CRUD operations for easier mapping of decorators
198
- *
199
- * @constant DBOperations
200
- *
201
- * @memberOf module:db-decorators.Operations
301
+ * @const DBOperations
302
+ * @memberOf module:db-decorators
202
303
  */
203
304
  const DBOperations = {
204
305
  CREATE: [exports.OperationKeys.CREATE],
@@ -216,26 +317,47 @@
216
317
  };
217
318
 
218
319
  /**
219
- * @summary Holds the registered operation handlers
220
- *
320
+ * @description Registry for database operation handlers
321
+ * @summary Manages and stores operation handlers for different model properties and operations
221
322
  * @class OperationsRegistry
222
- * @implements IRegistry<OperationHandler<any>>
223
- *
224
- * @see OperationHandler
225
- *
226
- * @category Operations
323
+ * @template M - Model type
324
+ * @template R - Repository type
325
+ * @template V - Metadata type
326
+ * @template F - Repository flags
327
+ * @template C - Context type
328
+ * @example
329
+ * // Create a registry and register a handler
330
+ * const registry = new OperationsRegistry();
331
+ * registry.register(myHandler, OperationKeys.CREATE, targetModel, 'propertyName');
332
+ *
333
+ * // Get handlers for a specific operation
334
+ * const handlers = registry.get(targetModel.constructor.name, 'propertyName', 'onCreate');
335
+ *
336
+ * @mermaid
337
+ * classDiagram
338
+ * class OperationsRegistry {
339
+ * -cache: Record~string, Record~string|symbol, Record~string, Record~string, OperationHandler~~~~
340
+ * +get(target, propKey, operation, accum)
341
+ * +register(handler, operation, target, propKey)
342
+ * }
227
343
  */
228
344
  class OperationsRegistry {
229
345
  constructor() {
230
346
  this.cache = {};
231
347
  }
232
348
  /**
233
- * @summary retrieves an {@link OperationHandler} if it exists
234
- * @param {string} target
235
- * @param {string} propKey
236
- * @param {string} operation
237
- * @param accum
238
- * @return {OperationHandler | undefined}
349
+ * @description Retrieves operation handlers for a specific target and operation
350
+ * @summary Finds all registered handlers for a given target, property, and operation, including from parent classes
351
+ * @template M - Model type extending Model
352
+ * @template R - Repository type extending IRepository
353
+ * @template V - Metadata type
354
+ * @template F - Repository flags extending RepositoryFlags
355
+ * @template C - Context type extending Context<F>
356
+ * @param {string | Record<string, any>} target - The target class name or object
357
+ * @param {string} propKey - The property key to get handlers for
358
+ * @param {string} operation - The operation key to get handlers for
359
+ * @param {OperationHandler[]} [accum] - Accumulator for recursive calls
360
+ * @return {OperationHandler[] | undefined} Array of handlers or undefined if none found
239
361
  */
240
362
  get(target, propKey, operation, accum) {
241
363
  accum = accum || [];
@@ -257,11 +379,18 @@
257
379
  return this.get(proto, propKey, operation, accum);
258
380
  }
259
381
  /**
260
- * @summary Registers an {@link OperationHandler}
261
- * @param {OperationHandler} handler
262
- * @param {string} operation
263
- * @param {{}} target
264
- * @param {string | symbol} propKey
382
+ * @description Registers an operation handler for a specific target and operation
383
+ * @summary Stores a handler in the registry for a given target, property, and operation
384
+ * @template M - Model type extending Model
385
+ * @template R - Repository type extending IRepository
386
+ * @template V - Metadata type
387
+ * @template F - Repository flags extending RepositoryFlags
388
+ * @template C - Context type extending Context<F>
389
+ * @param {OperationHandler} handler - The handler function to register
390
+ * @param {OperationKeys} operation - The operation key to register the handler for
391
+ * @param {M} target - The target model instance
392
+ * @param {string | symbol} propKey - The property key to register the handler for
393
+ * @return {void}
265
394
  */
266
395
  register(handler, operation, target, propKey) {
267
396
  const name = target.constructor.name;
@@ -279,259 +408,336 @@
279
408
  }
280
409
 
281
410
  /**
282
- * @summary Static class holding common Operation Functionality
283
- *
411
+ * @description Static utility class for database operation management
412
+ * @summary Provides functionality for registering, retrieving, and managing database operation handlers
284
413
  * @class Operations
285
- *
286
- * @category Operations
414
+ * @template M - Model type
415
+ * @template R - Repository type
416
+ * @template V - Metadata type
417
+ * @template F - Repository flags
418
+ * @template C - Context type
419
+ * @example
420
+ * // Register a handler for a create operation
421
+ * Operations.register(myHandler, OperationKeys.CREATE, targetModel, 'propertyName');
422
+ *
423
+ * // Get handlers for a specific operation
424
+ * const handlers = Operations.get(targetModel.constructor.name, 'propertyName', 'onCreate');
425
+ *
426
+ * @mermaid
427
+ * classDiagram
428
+ * class Operations {
429
+ * -registry: OperationsRegistry
430
+ * +getHandlerName(handler)
431
+ * +key(str)
432
+ * +get(targetName, propKey, operation)
433
+ * -getOpRegistry()
434
+ * +register(handler, operation, target, propKey)
435
+ * }
436
+ * Operations --> OperationsRegistry : uses
287
437
  */
288
438
  class Operations {
289
439
  constructor() { }
440
+ /**
441
+ * @description Gets a unique name for an operation handler
442
+ * @summary Returns the name of the handler function or generates a hash if name is not available
443
+ * @param {OperationHandler<any, any, any, any, any>} handler - The handler function to get the name for
444
+ * @return {string} The name of the handler or a generated hash
445
+ */
290
446
  static getHandlerName(handler) {
291
447
  if (handler.name)
292
448
  return handler.name;
293
449
  console.warn("Handler name not defined. A name will be generated, but this is not desirable. please avoid using anonymous functions");
294
450
  return decoratorValidation.Hashing.hash(handler.toString());
295
451
  }
452
+ /**
453
+ * @description Generates a reflection metadata key
454
+ * @summary Creates a fully qualified metadata key by prefixing with the reflection namespace
455
+ * @param {string} str - The operation key string to prefix
456
+ * @return {string} The fully qualified metadata key
457
+ */
296
458
  static key(str) {
297
459
  return exports.OperationKeys.REFLECT + str;
298
460
  }
461
+ /**
462
+ * @description Retrieves operation handlers for a specific target and operation
463
+ * @summary Gets registered handlers from the operations registry for a given target, property, and operation
464
+ * @template M - Model type extending Model
465
+ * @template R - Repository type extending IRepository
466
+ * @template V - Metadata type, defaults to object
467
+ * @template F - Repository flags extending RepositoryFlags
468
+ * @template C - Context type extending Context<F>
469
+ * @param {string | Record<string, any>} targetName - The target class name or object
470
+ * @param {string} propKey - The property key to get handlers for
471
+ * @param {string} operation - The operation key to get handlers for
472
+ * @return {any} The registered handlers for the specified target, property, and operation
473
+ */
299
474
  static get(targetName, propKey, operation) {
300
475
  return Operations.registry.get(targetName, propKey, operation);
301
476
  }
477
+ /**
478
+ * @description Gets or initializes the operations registry
479
+ * @summary Returns the existing registry or creates a new one if it doesn't exist
480
+ * @return {OperationsRegistry} The operations registry instance
481
+ * @private
482
+ */
302
483
  static getOpRegistry() {
303
484
  if (!Operations.registry)
304
485
  Operations.registry = new OperationsRegistry();
305
486
  return Operations.registry;
306
487
  }
488
+ /**
489
+ * @description Registers an operation handler for a specific target and operation
490
+ * @summary Adds a handler to the operations registry for a given target, property, and operation
491
+ * @template V - Model type extending Model
492
+ * @param {OperationHandler<V, any, any>} handler - The handler function to register
493
+ * @param {OperationKeys} operation - The operation key to register the handler for
494
+ * @param {V} target - The target model instance
495
+ * @param {string | symbol} propKey - The property key to register the handler for
496
+ * @return {void}
497
+ */
307
498
  static register(handler, operation, target, propKey) {
308
499
  Operations.getOpRegistry().register(handler, operation, target, propKey);
309
500
  }
310
501
  }
311
502
 
503
+ /**
504
+ * @description Internal function to register operation handlers
505
+ * @summary Registers an operation handler for a specific operation key on a target property
506
+ * @param {OperationKeys} op - The operation key to handle
507
+ * @param {OperationHandler<any, any, any, any, any>} handler - The handler function to register
508
+ * @return {PropertyDecorator} A decorator that registers the handler
509
+ * @function handle
510
+ * @category Property Decorators
511
+ */
312
512
  function handle(op, handler) {
313
513
  return (target, propertyKey) => {
314
514
  Operations.register(handler, op, target, propertyKey);
315
515
  };
316
516
  }
317
517
  /**
318
- * @summary Defines a behaviour to set on the defined {@link DBOperations.CREATE_UPDATE}
319
- *
320
- * @param {OnOperationHandler<any>} handler The method called upon the operation
321
- * @param data
322
- * @param {any[]} [args] Arguments that will be passed in order to the handler method
323
- *
324
- * @see on
325
- *
518
+ * @description Decorator for handling create and update operations
519
+ * @summary Defines a behavior to execute during both create and update operations
520
+ * @template V - Type for metadata, defaults to object
521
+ * @param {StandardOperationHandler<any, any, V, any, any> | UpdateOperationHandler<any, any, V, any, any>} handler - The method called upon the operation
522
+ * @param {V} [data] - Optional metadata to pass to the handler
523
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
326
524
  * @function onCreateUpdate
327
- *
328
- * @category Decorators
525
+ * @category Property Decorators
329
526
  */
330
527
  function onCreateUpdate(handler, data) {
331
528
  return on(DBOperations.CREATE_UPDATE, handler, data);
332
529
  }
333
530
  /**
334
- * @summary Defines a behaviour to set on the defined {@link DBOperations.UPDATE}
335
- *
336
- * @param {OnOperationHandler<any>} handler The method called upon the operation
337
- * @param data
338
- * @param {any[]} [args] Arguments that will be passed in order to the handler method
339
- *
340
- * @see on
341
- *
531
+ * @description Decorator for handling update operations
532
+ * @summary Defines a behavior to execute during update operations
533
+ * @template V - Type for metadata, defaults to object
534
+ * @param {UpdateOperationHandler<any, any, V, any>} handler - The method called upon the operation
535
+ * @param {V} [data] - Optional metadata to pass to the handler
536
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
342
537
  * @function onUpdate
343
- *
344
- * @category Decorators
538
+ * @category Property Decorators
345
539
  */
346
540
  function onUpdate(handler, data) {
347
541
  return on(DBOperations.UPDATE, handler, data);
348
542
  }
349
543
  /**
350
- * @summary Defines a behaviour to set on the defined {@link DBOperations.CREATE}
351
- *
352
- * @param {OnOperationHandler<any>} handler The method called upon the operation
353
- * @param data
354
- *
355
- * @see on
356
- *
544
+ * @description Decorator for handling create operations
545
+ * @summary Defines a behavior to execute during create operations
546
+ * @template V - Type for metadata, defaults to object
547
+ * @param {StandardOperationHandler<any, any, V, any, any>} handler - The method called upon the operation
548
+ * @param {V} [data] - Optional metadata to pass to the handler
549
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
357
550
  * @function onCreate
358
- *
359
- * @category Decorators
551
+ * @category Property Decorators
360
552
  */
361
553
  function onCreate(handler, data) {
362
554
  return on(DBOperations.CREATE, handler, data);
363
555
  }
364
556
  /**
365
- * @summary Defines a behaviour to set on the defined {@link DBOperations.READ}
366
- *
367
- * @param {OnOperationHandler<any>} handler The method called upon the operation
368
- * @param data
369
- *
370
- * @see on
371
- *
557
+ * @description Decorator for handling read operations
558
+ * @summary Defines a behavior to execute during read operations
559
+ * @template V - Type for metadata, defaults to object
560
+ * @param {IdOperationHandler<any, any, V, any, any>} handler - The method called upon the operation
561
+ * @param {V} [data] - Optional metadata to pass to the handler
562
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
372
563
  * @function onRead
373
- *
374
- * @category Decorators
564
+ * @category Property Decorators
375
565
  */
376
566
  function onRead(handler, data) {
377
567
  return on(DBOperations.READ, handler, data);
378
568
  }
379
569
  /**
380
- * @summary Defines a behaviour to set on the defined {@link DBOperations.DELETE}
381
- *
382
- * @param {OnOperationHandler<any>} handler The method called upon the operation
383
- * @param data
384
- *
385
- * @see on
386
- *
570
+ * @description Decorator for handling delete operations
571
+ * @summary Defines a behavior to execute during delete operations
572
+ * @template V - Type for metadata, defaults to object
573
+ * @param {OperationHandler<any, any, V, any, any>} handler - The method called upon the operation
574
+ * @param {V} [data] - Optional metadata to pass to the handler
575
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
387
576
  * @function onDelete
388
- *
389
- * @category Decorators
577
+ * @category Property Decorators
390
578
  */
391
579
  function onDelete(handler, data) {
392
580
  return on(DBOperations.DELETE, handler, data);
393
581
  }
394
582
  /**
395
- * @summary Defines a behaviour to set on the defined {@link DBOperations.DELETE}
396
- *
397
- * @param {OnOperationHandler<any>} handler The method called upon the operation
398
- * @param data
399
- *
400
- * @see on
401
- *
583
+ * @description Decorator for handling all operation types
584
+ * @summary Defines a behavior to execute during any database operation
585
+ * @template V - Type for metadata, defaults to object
586
+ * @param {OperationHandler<any, any, V, any, any>} handler - The method called upon the operation
587
+ * @param {V} [data] - Optional metadata to pass to the handler
588
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
402
589
  * @function onAny
403
- *
404
- * @category Decorators
590
+ * @category Property Decorators
405
591
  */
406
592
  function onAny(handler, data) {
407
593
  return on(DBOperations.ALL, handler, data);
408
594
  }
409
595
  /**
410
- * @summary Defines a behaviour to set on the defined {@link DBOperations}
411
- *
412
- * @param {OperationKeys[] | DBOperations} op One of {@link DBOperations}
413
- * @param {OnOperationHandler<any>} handler The method called upon the operation
414
- * @param data
415
- *
416
- * ex: handler(...args, ...props.map(p => target[p]))
417
- *
596
+ * @description Base decorator for handling database operations
597
+ * @summary Defines a behavior to execute during specified database operations
598
+ * @template V - Type for metadata, defaults to object
599
+ * @param {OperationKeys[] | DBOperations} [op=DBOperations.ALL] - One or more operation types to handle
600
+ * @param {OperationHandler<any, any, V, any, any>} handler - The method called upon the operation
601
+ * @param {V} [data] - Optional metadata to pass to the handler
602
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
418
603
  * @function on
419
- *
420
- * @category Decorators
604
+ * @category Property Decorators
605
+ * @example
606
+ * // Example usage:
607
+ * class MyModel {
608
+ * @on(DBOperations.CREATE, myHandler)
609
+ * myProperty: string;
610
+ * }
421
611
  */
422
612
  function on(op = DBOperations.ALL, handler, data) {
423
613
  return operation(exports.OperationKeys.ON, op, handler, data);
424
614
  }
425
615
  /**
426
- * @summary Defines a behaviour to set after the defined {@link DBOperations.CREATE_UPDATE}
427
- *
428
- * @param {AfterOperationHandler<any>} handler The method called upon the operation
429
- * @param data
430
- *
431
- * @see after
432
- *
616
+ * @description Decorator for handling post-create and post-update operations
617
+ * @summary Defines a behavior to execute after both create and update operations
618
+ * @template V - Type for metadata, defaults to object
619
+ * @param {StandardOperationHandler<any, any, V, any, any> | UpdateOperationHandler<any, any, V, any, any>} handler - The method called after the operation
620
+ * @param {V} [data] - Optional metadata to pass to the handler
621
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
433
622
  * @function afterCreateUpdate
434
- *
435
- * @category Decorators
623
+ * @category Property Decorators
436
624
  */
437
625
  function afterCreateUpdate(handler, data) {
438
626
  return after(DBOperations.CREATE_UPDATE, handler, data);
439
627
  }
440
628
  /**
441
- * @summary Defines a behaviour to set after the defined {@link DBOperations.UPDATE}
442
- *
443
- * @param {AfterOperationHandler<any>} handler The method called upon the operation
444
- * @param data
445
- *
446
- * @see after
447
- *
629
+ * @description Decorator for handling post-update operations
630
+ * @summary Defines a behavior to execute after update operations
631
+ * @template V - Type for metadata, defaults to object
632
+ * @param {UpdateOperationHandler<any, any, V, any, any>} handler - The method called after the operation
633
+ * @param {V} [data] - Optional metadata to pass to the handler
634
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
448
635
  * @function afterUpdate
449
- *
450
- * @category Decorators
636
+ * @category Property Decorators
451
637
  */
452
638
  function afterUpdate(handler, data) {
453
639
  return after(DBOperations.UPDATE, handler, data);
454
640
  }
455
641
  /**
456
- * @summary Defines a behaviour to set after the defined {@link DBOperations.CREATE}
457
- *
458
- * @param {AfterOperationHandler<any>} handler The method called upon the operation
459
- * @param data
460
- *
461
- * @see after
462
- *
642
+ * @description Decorator for handling post-create operations
643
+ * @summary Defines a behavior to execute after create operations
644
+ * @template V - Type for metadata, defaults to object
645
+ * @param {StandardOperationHandler<any, any, V, any, any>} handler - The method called after the operation
646
+ * @param {V} [data] - Optional metadata to pass to the handler
647
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
463
648
  * @function afterCreate
464
- *
465
- * @category Decorators
649
+ * @category Property Decorators
466
650
  */
467
651
  function afterCreate(handler, data) {
468
652
  return after(DBOperations.CREATE, handler, data);
469
653
  }
470
654
  /**
471
- * @summary Defines a behaviour to set after the defined {@link DBOperations.READ}
472
- *
473
- * @param {AfterOperationHandler<any>} handler The method called upon the operation
474
- * @param data
475
- * @param {any[]} [args] Arguments that will be passed in order to the handler method
476
- *
477
- * @see after
478
- *
655
+ * @description Decorator for handling post-read operations
656
+ * @summary Defines a behavior to execute after read operations
657
+ * @template V - Type for metadata, defaults to object
658
+ * @param {StandardOperationHandler<any, any, V, any, any>} handler - The method called after the operation
659
+ * @param {V} [data] - Optional metadata to pass to the handler
660
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
479
661
  * @function afterRead
480
- *
481
- * @category Decorators
662
+ * @category Property Decorators
482
663
  */
483
664
  function afterRead(handler, data) {
484
665
  return after(DBOperations.READ, handler, data);
485
666
  }
486
667
  /**
487
- * @summary Defines a behaviour to set after the defined {@link DBOperations.DELETE}
488
- *
489
- * @param {AfterOperationHandler<any>} handler The method called upon the operation
490
- * @param data
491
- * @param {any[]} [args] Arguments that will be passed in order to the handler method
492
- *
493
- * @see after
494
- *
668
+ * @description Decorator for handling post-delete operations
669
+ * @summary Defines a behavior to execute after delete operations
670
+ * @template V - Type for metadata, defaults to object
671
+ * @param {StandardOperationHandler<any, any, V, any, any>} handler - The method called after the operation
672
+ * @param {V} [data] - Optional metadata to pass to the handler
673
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
495
674
  * @function afterDelete
496
- *
497
- * @category Decorators
675
+ * @category Property Decorators
498
676
  */
499
677
  function afterDelete(handler, data) {
500
678
  return after(DBOperations.DELETE, handler, data);
501
679
  }
502
680
  /**
503
- * @summary Defines a behaviour to set after the defined {@link DBOperations.DELETE}
504
- *
505
- * @param {AfterOperationHandler<any>} handler The method called upon the operation
506
- * @param data
507
- * @param {any[]} [args] Arguments that will be passed in order to the handler method
508
- *
509
- * @see after
510
- *
681
+ * @description Decorator for handling post-operation for all operation types
682
+ * @summary Defines a behavior to execute after any database operation
683
+ * @template V - Type for metadata, defaults to object
684
+ * @param {StandardOperationHandler<any, any, V, any, any>} handler - The method called after the operation
685
+ * @param {V} [data] - Optional metadata to pass to the handler
686
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
511
687
  * @function afterAny
512
- *
513
- * @category Decorators
688
+ * @category Property Decorators
514
689
  */
515
690
  function afterAny(handler, data) {
516
691
  return after(DBOperations.ALL, handler, data);
517
692
  }
518
693
  /**
519
- * @summary Defines a behaviour to set on the defined {@link DBOperations}
520
- *
521
- * @param {OperationKeys[] | DBOperations} op One of {@link DBOperations}
522
- * @param {AfterOperationHandler<any>} handler The method called upon the operation
523
- *
524
- * ex: handler(...args, ...props.map(p => target[p]))
525
- *
526
- * @param data
527
- * @param args
694
+ * @description Base decorator for handling post-operation behaviors
695
+ * @summary Defines a behavior to execute after specified database operations
696
+ * @template V - Type for metadata, defaults to object
697
+ * @param {OperationKeys[] | DBOperations} [op=DBOperations.ALL] - One or more operation types to handle
698
+ * @param {OperationHandler<any, any, V, any, any>} handler - The method called after the operation
699
+ * @param {V} [data] - Optional metadata to pass to the handler
700
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
528
701
  * @function after
529
- *
530
- * @category Decorators
702
+ * @category Property Decorators
703
+ * @example
704
+ * // Example usage:
705
+ * class MyModel {
706
+ * @after(DBOperations.CREATE, myHandler)
707
+ * myProperty: string;
708
+ * }
531
709
  */
532
710
  function after(op = DBOperations.ALL, handler, data) {
533
711
  return operation(exports.OperationKeys.AFTER, op, handler, data);
534
712
  }
713
+ /**
714
+ * @description Core decorator factory for operation handlers
715
+ * @summary Creates decorators that register handlers for database operations
716
+ * @template V - Type for metadata, defaults to object
717
+ * @param {OperationKeys.ON | OperationKeys.AFTER} baseOp - Whether the handler runs during or after the operation
718
+ * @param {OperationKeys[]} [operation=DBOperations.ALL] - The specific operations to handle
719
+ * @param {OperationHandler<any, any, V, any, any>} handler - The handler function to execute
720
+ * @param {V} [dataToAdd] - Optional metadata to pass to the handler
721
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
722
+ * @function operation
723
+ * @category Property Decorators
724
+ * @mermaid
725
+ * sequenceDiagram
726
+ * participant Client
727
+ * participant Decorator as @operation
728
+ * participant Operations as Operations Registry
729
+ * participant Handler
730
+ *
731
+ * Client->>Decorator: Apply to property
732
+ * Decorator->>Operations: Register handler
733
+ * Decorator->>Decorator: Store metadata
734
+ *
735
+ * Note over Client,Handler: Later, during operation execution
736
+ * Client->>Operations: Execute operation
737
+ * Operations->>Handler: Call registered handler
738
+ * Handler-->>Operations: Return result
739
+ * Operations-->>Client: Return final result
740
+ */
535
741
  function operation(baseOp, operation = DBOperations.ALL, handler, dataToAdd) {
536
742
  return (target, propertyKey) => {
537
743
  const name = target.constructor.name;
@@ -562,12 +768,16 @@
562
768
  }
563
769
 
564
770
  /**
565
- * @summary Base Error
566
- *
567
- * @param {string} msg the error message
568
- *
569
- * @class BaseDLTError
570
- * @extends Error
771
+ * @description Base error class for the repository module
772
+ * @summary Abstract base error class that all other error types extend from. Provides common error handling functionality.
773
+ * @param {string} name - The name of the error
774
+ * @param {string|Error} msg - The error message or Error object
775
+ * @param {number} code - The HTTP status code associated with this error
776
+ * @class BaseError
777
+ * @example
778
+ * // This is an abstract class and should not be instantiated directly
779
+ * // Instead, use one of the concrete error classes:
780
+ * throw new ValidationError('Invalid data provided');
571
781
  */
572
782
  class BaseError extends Error {
573
783
  constructor(name, msg, code = 500) {
@@ -581,12 +791,16 @@
581
791
  }
582
792
  }
583
793
  /**
584
- * @summary Represents a failure in the Model details
585
- *
586
- * @param {string} msg the error message
587
- *
794
+ * @description Error thrown when validation fails
795
+ * @summary Represents a failure in the Model details, typically thrown when data validation fails
796
+ * @param {string|Error} msg - The error message or Error object
797
+ * @return {ValidationError} A new ValidationError instance
588
798
  * @class ValidationError
589
- * @extends BaseError
799
+ * @example
800
+ * // Throw a validation error when data is invalid
801
+ * if (!isValid(data)) {
802
+ * throw new ValidationError('Invalid data format');
803
+ * }
590
804
  */
591
805
  class ValidationError extends BaseError {
592
806
  constructor(msg) {
@@ -594,12 +808,18 @@
594
808
  }
595
809
  }
596
810
  /**
597
- * @summary Represents an internal failure (should mean an error in code)
598
- *
599
- * @param {string} msg the error message
600
- *
811
+ * @description Error thrown for internal system failures
812
+ * @summary Represents an internal failure (should mean an error in code) with HTTP 500 status code
813
+ * @param {string|Error} msg - The error message or Error object
814
+ * @return {InternalError} A new InternalError instance
601
815
  * @class InternalError
602
- * @extends BaseError
816
+ * @example
817
+ * // Throw an internal error when an unexpected condition occurs
818
+ * try {
819
+ * // Some operation
820
+ * } catch (error) {
821
+ * throw new InternalError('Unexpected internal error occurred');
822
+ * }
603
823
  */
604
824
  class InternalError extends BaseError {
605
825
  constructor(msg) {
@@ -607,13 +827,18 @@
607
827
  }
608
828
  }
609
829
  /**
610
- * @summary Represents a failure in the Model de/serialization
611
- *
612
- * @param {string} msg the error message
613
- *
830
+ * @description Error thrown when serialization or deserialization fails
831
+ * @summary Represents a failure in the Model de/serialization, typically when converting between data formats
832
+ * @param {string|Error} msg - The error message or Error object
833
+ * @return {SerializationError} A new SerializationError instance
614
834
  * @class SerializationError
615
- * @extends BaseError
616
- *
835
+ * @example
836
+ * // Throw a serialization error when JSON parsing fails
837
+ * try {
838
+ * const data = JSON.parse(invalidJson);
839
+ * } catch (error) {
840
+ * throw new SerializationError('Failed to parse JSON data');
841
+ * }
617
842
  */
618
843
  class SerializationError extends BaseError {
619
844
  constructor(msg) {
@@ -621,13 +846,17 @@
621
846
  }
622
847
  }
623
848
  /**
624
- * @summary Represents a failure in finding a model
625
- *
626
- * @param {string} msg the error message
627
- *
849
+ * @description Error thrown when a requested resource is not found
850
+ * @summary Represents a failure in finding a model, resulting in a 404 HTTP status code
851
+ * @param {string|Error} msg - The error message or Error object
852
+ * @return {NotFoundError} A new NotFoundError instance
628
853
  * @class NotFoundError
629
- * @extends BaseError
630
- *
854
+ * @example
855
+ * // Throw a not found error when a record doesn't exist
856
+ * const user = await repository.findById(id);
857
+ * if (!user) {
858
+ * throw new NotFoundError(`User with ID ${id} not found`);
859
+ * }
631
860
  */
632
861
  class NotFoundError extends BaseError {
633
862
  constructor(msg) {
@@ -635,13 +864,17 @@
635
864
  }
636
865
  }
637
866
  /**
638
- * @summary Represents a conflict in the storage
639
- *
640
- * @param {string} msg the error message
641
- *
867
+ * @description Error thrown when a conflict occurs in the storage
868
+ * @summary Represents a conflict in the storage, typically when trying to create a duplicate resource
869
+ * @param {string|Error} msg - The error message or Error object
870
+ * @return {ConflictError} A new ConflictError instance
642
871
  * @class ConflictError
643
- * @extends BaseError
644
- *
872
+ * @example
873
+ * // Throw a conflict error when trying to create a duplicate record
874
+ * const existingUser = await repository.findByEmail(email);
875
+ * if (existingUser) {
876
+ * throw new ConflictError(`User with email ${email} already exists`);
877
+ * }
645
878
  */
646
879
  class ConflictError extends BaseError {
647
880
  constructor(msg) {
@@ -819,6 +1052,13 @@
819
1052
  return getAllPropertyDecoratorsRecursive(proto, accumulator, ...prefixes);
820
1053
  };
821
1054
 
1055
+ /**
1056
+ * @description Default configuration flags for repository operations.
1057
+ * @summary Provides default values for repository operation flags, excluding the timestamp property.
1058
+ * These flags control behavior such as context handling, validation, error handling, and more.
1059
+ * @const DefaultRepositoryFlags
1060
+ * @memberOf module:db-decorators
1061
+ */
822
1062
  const DefaultRepositoryFlags = {
823
1063
  parentContext: undefined,
824
1064
  childContexts: [],
@@ -831,16 +1071,95 @@
831
1071
  rebuildWithTransient: true,
832
1072
  };
833
1073
 
1074
+ /**
1075
+ * @description Default factory for creating context instances.
1076
+ * @summary A factory function that creates new Context instances with the provided repository flags.
1077
+ * It automatically adds a timestamp to the context and returns a properly typed context instance.
1078
+ * @const DefaultContextFactory
1079
+ * @memberOf module:db-decorators
1080
+ */
834
1081
  const DefaultContextFactory = (arg) => {
835
1082
  return new Context().accumulate(Object.assign({}, arg, { timestamp: new Date() }));
836
1083
  };
1084
+ /**
1085
+ * @description A context management class for handling repository operations.
1086
+ * @summary The Context class provides a mechanism for managing repository operations with flags,
1087
+ * parent-child relationships, and state accumulation. It allows for hierarchical context chains
1088
+ * and maintains operation-specific configurations while supporting type safety through generics.
1089
+ *
1090
+ * @template F - Type extending RepositoryFlags that defines the context configuration
1091
+ *
1092
+ * @param {ObjectAccumulator<F>} cache - The internal cache storing accumulated values
1093
+ *
1094
+ * @class
1095
+ *
1096
+ * @example
1097
+ * ```typescript
1098
+ * // Creating a new context with repository flags
1099
+ * const context = new Context<RepositoryFlags>();
1100
+ *
1101
+ * // Accumulating values
1102
+ * const enrichedContext = context.accumulate({
1103
+ * writeOperation: true,
1104
+ * affectedTables: ['users'],
1105
+ * operation: OperationKeys.CREATE
1106
+ * });
1107
+ *
1108
+ * // Accessing values
1109
+ * const isWrite = enrichedContext.get('writeOperation'); // true
1110
+ * const tables = enrichedContext.get('affectedTables'); // ['users']
1111
+ * ```
1112
+ *
1113
+ * @mermaid
1114
+ * sequenceDiagram
1115
+ * participant C as Client
1116
+ * participant Ctx as Context
1117
+ * participant Cache as ObjectAccumulator
1118
+ *
1119
+ * C->>Ctx: new Context()
1120
+ * Ctx->>Cache: create cache
1121
+ *
1122
+ * C->>Ctx: accumulate(value)
1123
+ * Ctx->>Cache: accumulate(value)
1124
+ * Cache-->>Ctx: updated cache
1125
+ * Ctx-->>C: updated context
1126
+ *
1127
+ * C->>Ctx: get(key)
1128
+ * Ctx->>Cache: get(key)
1129
+ * alt Key exists in cache
1130
+ * Cache-->>Ctx: value
1131
+ * else Key not found
1132
+ * Ctx->>Ctx: check parent context
1133
+ * alt Parent exists
1134
+ * Ctx->>Parent: get(key)
1135
+ * Parent-->>Ctx: value
1136
+ * else No parent
1137
+ * Ctx-->>C: throw error
1138
+ * end
1139
+ * end
1140
+ * Ctx-->>C: requested value
1141
+ */
837
1142
  class Context {
838
- static { this.factory = DefaultContextFactory; }
839
- constructor(obj) {
1143
+ constructor() {
840
1144
  this.cache = new typedObjectAccumulator.ObjectAccumulator();
841
- if (obj)
842
- return this.accumulate(obj);
1145
+ Object.defineProperty(this, "cache", {
1146
+ value: new typedObjectAccumulator.ObjectAccumulator(),
1147
+ writable: false,
1148
+ enumerable: false,
1149
+ configurable: true,
1150
+ });
843
1151
  }
1152
+ static { this.factory = DefaultContextFactory; }
1153
+ /**
1154
+ * @description Accumulates new values into the context.
1155
+ * @summary Merges the provided value object with the existing context state,
1156
+ * creating a new immutable cache state.
1157
+ *
1158
+ * @template F - current accumulator type
1159
+ * @template V - Type extending object for the values to accumulate
1160
+ * @param {V} value - The object containing values to accumulate
1161
+ * @returns A new context instance with accumulated values
1162
+ */
844
1163
  accumulate(value) {
845
1164
  Object.defineProperty(this, "cache", {
846
1165
  value: this.cache.accumulate(value),
@@ -853,6 +1172,17 @@
853
1172
  get timestamp() {
854
1173
  return this.cache.timestamp;
855
1174
  }
1175
+ /**
1176
+ * @description Retrieves a value from the context by key.
1177
+ * @summary Attempts to get a value from the current context's cache.
1178
+ * If not found, traverses up the parent context chain.
1179
+ *
1180
+ * @template K - Type extending keyof F for the key to retrieve
1181
+ * @template F - Accumulator type
1182
+ * @param {K} key - The key to retrieve from the context
1183
+ * @returns The value associated with the key
1184
+ * @throws {Error} If the key is not found in the context chain
1185
+ */
856
1186
  get(key) {
857
1187
  try {
858
1188
  return this.cache.get(key);
@@ -863,15 +1193,46 @@
863
1193
  throw e;
864
1194
  }
865
1195
  }
1196
+ /**
1197
+ * @description Creates a child context
1198
+ * @summary Generates a new context instance with current context as parent
1199
+ *
1200
+ * @template M - Type extending Model
1201
+ * @param {OperationKeys} operation - The operation type
1202
+ * @param {Constructor<M>} [model] - Optional model constructor
1203
+ * @returns {C} New child context instance
1204
+ */
866
1205
  child(operation, model) {
867
1206
  return Context.childFrom(this, {
868
1207
  operation: operation,
869
1208
  affectedTables: model ? [model] : [],
870
1209
  });
871
1210
  }
1211
+ /**
1212
+ * @description Creates a child context from another context
1213
+ * @summary Generates a new context instance with parent reference
1214
+ *
1215
+ * @template F - Type extending Repository Flags
1216
+ * @template C - Type extending Context<F>
1217
+ * @param {C} context - The parent context
1218
+ * @param {Partial<F>} [overrides] - Optional flag overrides
1219
+ * @returns {C} New child context instance
1220
+ */
872
1221
  static childFrom(context, overrides) {
873
1222
  return Context.factory(Object.assign({}, context.cache, overrides || {}));
874
1223
  }
1224
+ /**
1225
+ * @description Creates a new context from operation parameters
1226
+ * @summary Generates a context instance for specific operation
1227
+ *
1228
+ * @template F - Type extending Repository Flags
1229
+ * @template M - Type extending Model
1230
+ * @param {OperationKeys.DELETE} operation - The operation type
1231
+ * @param {Partial<F>} overrides - Flag overrides
1232
+ * @param {Constructor<M>} model - The model constructor
1233
+ * @param {any} args - Operation arguments
1234
+ * @returns {Promise<C>} Promise resolving to new context
1235
+ */
875
1236
  static async from(operation, overrides, model,
876
1237
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
877
1238
  ...args) {
@@ -880,6 +1241,33 @@
880
1241
  model: model,
881
1242
  }));
882
1243
  }
1244
+ /**
1245
+ * @description Prepares arguments for context operations
1246
+ * @summary Creates a context args object with the specified operation parameters
1247
+ *
1248
+ * @template F - Type extending {@link RepositoryFlags}
1249
+ * @template M - Type extending {@link Model}
1250
+ * @param {OperationKeys.DELETE} operation - The operation type
1251
+ * @param {Constructor<M>} model - The model constructor
1252
+ * @param {any[]} args - Operation arguments
1253
+ * @param {Contextual<F>} [contextual] - Optional contextual object
1254
+ * @param {Partial<F>} [overrides] - Optional flag overrides
1255
+ * @returns {Promise<ContextArgs>} Promise resolving to context arguments
1256
+ *
1257
+ * @mermaid
1258
+ * sequenceDiagram
1259
+ * participant C as Context
1260
+ * participant M as Model
1261
+ * participant A as Args
1262
+ *
1263
+ * C->>C: Receive operation request
1264
+ * C->>M: Validate model constructor
1265
+ * C->>C: Create child context
1266
+ * C->>A: Process operation args
1267
+ * A->>C: Return context args
1268
+ * C->>C: Apply overrides
1269
+ * C->>C: Return final context
1270
+ */
883
1271
  static async args(operation, model, args, contextual, overrides) {
884
1272
  const last = args.pop();
885
1273
  async function getContext() {
@@ -915,7 +1303,7 @@
915
1303
  *
916
1304
  * @function prefixMethod
917
1305
  *
918
- * @memberOf module:db-decorators.Repository
1306
+ * @memberOf module:db-decorators
919
1307
  */
920
1308
  function prefixMethod(obj, after, prefix, afterName) {
921
1309
  async function wrapper(...args) {
@@ -969,7 +1357,7 @@
969
1357
  *
970
1358
  * @function wrapMethodWithContext
971
1359
  *
972
- * @memberOf module:db-decorators.Repository
1360
+ * @memberOf module:db-decorators
973
1361
  */
974
1362
  function wrapMethodWithContext(obj, before, method, after, methodName) {
975
1363
  const name = methodName ? methodName : method.name;
@@ -993,17 +1381,24 @@
993
1381
  }
994
1382
 
995
1383
  /**
996
- * @summary Returns the primary key attribute for a {@link Model}
997
- * @description searches in all the properties in the object for an {@link id} decorated property
998
- *
999
- * @param {Model} model
1000
- *
1001
- * @throws {InternalError} if no property or more than one properties are {@link id} decorated
1002
- * or no value is set in that property
1003
- *
1384
+ * @description Finds the primary key attribute for a model
1385
+ * @summary Searches in all the properties in the object for an {@link id} decorated property and returns the property key and metadata
1386
+ * @param {Model} model - The model object to search for primary key
1387
+ * @return {Object} An object containing the id property name and its metadata
1004
1388
  * @function findPrimaryKey
1005
- *
1006
- * @category managers
1389
+ * @mermaid
1390
+ * sequenceDiagram
1391
+ * participant Caller
1392
+ * participant findPrimaryKey
1393
+ * participant getAllPropertyDecoratorsRecursive
1394
+ *
1395
+ * Caller->>findPrimaryKey: model
1396
+ * findPrimaryKey->>getAllPropertyDecoratorsRecursive: get decorators
1397
+ * getAllPropertyDecoratorsRecursive-->>findPrimaryKey: decorators
1398
+ * findPrimaryKey->>findPrimaryKey: filter ID decorators
1399
+ * findPrimaryKey->>findPrimaryKey: validate single ID property
1400
+ * findPrimaryKey-->>Caller: {id, props}
1401
+ * @memberOf module:db-decorators
1007
1402
  */
1008
1403
  function findPrimaryKey(model) {
1009
1404
  const decorators = getAllPropertyDecoratorsRecursive(model, undefined, DBKeys.REFLECT + DBKeys.ID);
@@ -1028,19 +1423,25 @@
1028
1423
  };
1029
1424
  }
1030
1425
  /**
1031
- * @summary Returns the primary key value for a {@link Model}
1032
- * @description searches in all the properties in the object for an {@link pk} decorated property
1033
- *
1034
- * @param {Model} model
1035
- * @param {boolean} [returnEmpty]
1036
- * @return {string | number | bigint} primary key
1037
- *
1038
- * @throws {InternalError} if no property or more than one properties are {@link pk} decorated
1039
- * @throws {NotFoundError} returnEmpty is false and no value is set on the {@link pk} decorated property
1040
- *
1041
- * @function findModelID
1042
- *
1043
- * @category managers
1426
+ * @description Retrieves the primary key value from a model
1427
+ * @summary Searches for the ID-decorated property in the model and returns its value
1428
+ * @param {Model} model - The model object to extract the ID from
1429
+ * @param {boolean} [returnEmpty=false] - Whether to return undefined if no ID value is found
1430
+ * @return {string | number | bigint} The primary key value
1431
+ * @function findModelId
1432
+ * @mermaid
1433
+ * sequenceDiagram
1434
+ * participant Caller
1435
+ * participant findModelId
1436
+ * participant findPrimaryKey
1437
+ *
1438
+ * Caller->>findModelId: model, returnEmpty
1439
+ * findModelId->>findPrimaryKey: model
1440
+ * findPrimaryKey-->>findModelId: {id, props}
1441
+ * findModelId->>findModelId: extract model[id]
1442
+ * findModelId->>findModelId: validate ID exists if required
1443
+ * findModelId-->>Caller: ID value
1444
+ * @memberOf module:db-decorators
1044
1445
  */
1045
1446
  function findModelId(model, returnEmpty = false) {
1046
1447
  const idProp = findPrimaryKey(model).id;
@@ -1050,12 +1451,115 @@
1050
1451
  return modelId;
1051
1452
  }
1052
1453
 
1454
+ /**
1455
+ * @description Base repository implementation providing CRUD operations for models.
1456
+ * @summary The BaseRepository class serves as a foundation for repository implementations, providing
1457
+ * abstract and concrete methods for creating, reading, updating, and deleting model instances.
1458
+ * It handles operation lifecycles including prefix and suffix operations, and enforces decorators.
1459
+ * @template M - The model type extending Model
1460
+ * @template F - The repository flags type, defaults to RepositoryFlags
1461
+ * @template C - The context type, defaults to Context<F>
1462
+ * @param {Constructor<M>} clazz - The constructor for the model class
1463
+ * @class BaseRepository
1464
+ * @example
1465
+ * class UserModel extends Model {
1466
+ * @id()
1467
+ * id: string;
1468
+ *
1469
+ * @required()
1470
+ * name: string;
1471
+ * }
1472
+ *
1473
+ * class UserRepository extends BaseRepository<UserModel> {
1474
+ * constructor() {
1475
+ * super(UserModel);
1476
+ * }
1477
+ *
1478
+ * async create(model: UserModel): Promise<UserModel> {
1479
+ * // Implementation
1480
+ * return model;
1481
+ * }
1482
+ *
1483
+ * async read(key: string): Promise<UserModel> {
1484
+ * // Implementation
1485
+ * return new UserModel({ id: key, name: 'User' });
1486
+ * }
1487
+ *
1488
+ * async update(model: UserModel): Promise<UserModel> {
1489
+ * // Implementation
1490
+ * return model;
1491
+ * }
1492
+ *
1493
+ * async delete(key: string): Promise<UserModel> {
1494
+ * // Implementation
1495
+ * const model = await this.read(key);
1496
+ * return model;
1497
+ * }
1498
+ * }
1499
+ *
1500
+ * @mermaid
1501
+ * sequenceDiagram
1502
+ * participant C as Client
1503
+ * participant R as Repository
1504
+ * participant P as Prefix Methods
1505
+ * participant D as Database
1506
+ * participant S as Suffix Methods
1507
+ * participant V as Validators/Decorators
1508
+ *
1509
+ * Note over C,V: Create Operation
1510
+ * C->>R: create(model)
1511
+ * R->>P: createPrefix(model)
1512
+ * P->>V: enforceDBDecorators(ON)
1513
+ * P->>D: Database operation
1514
+ * D->>S: createSuffix(model)
1515
+ * S->>V: enforceDBDecorators(AFTER)
1516
+ * S->>C: Return model
1517
+ *
1518
+ * Note over C,V: Read Operation
1519
+ * C->>R: read(key)
1520
+ * R->>P: readPrefix(key)
1521
+ * P->>V: enforceDBDecorators(ON)
1522
+ * P->>D: Database operation
1523
+ * D->>S: readSuffix(model)
1524
+ * S->>V: enforceDBDecorators(AFTER)
1525
+ * S->>C: Return model
1526
+ *
1527
+ * Note over C,V: Update Operation
1528
+ * C->>R: update(model)
1529
+ * R->>P: updatePrefix(model)
1530
+ * P->>V: enforceDBDecorators(ON)
1531
+ * P->>D: Database operation
1532
+ * D->>S: updateSuffix(model)
1533
+ * S->>V: enforceDBDecorators(AFTER)
1534
+ * S->>C: Return model
1535
+ *
1536
+ * Note over C,V: Delete Operation
1537
+ * C->>R: delete(key)
1538
+ * R->>P: deletePrefix(key)
1539
+ * P->>V: enforceDBDecorators(ON)
1540
+ * P->>D: Database operation
1541
+ * D->>S: deleteSuffix(model)
1542
+ * S->>V: enforceDBDecorators(AFTER)
1543
+ * S->>C: Return model
1544
+ */
1053
1545
  class BaseRepository {
1546
+ /**
1547
+ * @description Gets the model class constructor.
1548
+ * @summary Retrieves the constructor for the model class associated with this repository.
1549
+ * Throws an error if no class definition is found.
1550
+ * @return {Constructor<M>} The constructor for the model class
1551
+ */
1054
1552
  get class() {
1055
1553
  if (!this._class)
1056
1554
  throw new InternalError(`No class definition found for this repository`);
1057
1555
  return this._class;
1058
1556
  }
1557
+ /**
1558
+ * @description Gets the primary key property name of the model.
1559
+ * @summary Retrieves the name of the property that serves as the primary key for the model.
1560
+ * If not already determined, it finds the primary key using the model's decorators.
1561
+ * @return The name of the primary key property
1562
+ */
1059
1563
  get pk() {
1060
1564
  if (!this._pk) {
1061
1565
  const { id, props } = findPrimaryKey(new this.class());
@@ -1064,6 +1568,12 @@
1064
1568
  }
1065
1569
  return this._pk;
1066
1570
  }
1571
+ /**
1572
+ * @description Gets the primary key properties.
1573
+ * @summary Retrieves the properties associated with the primary key of the model.
1574
+ * If not already determined, it triggers the pk getter to find the primary key properties.
1575
+ * @return {any} The properties of the primary key
1576
+ */
1067
1577
  get pkProps() {
1068
1578
  if (!this._pkProps) {
1069
1579
  // eslint-disable-next-line @typescript-eslint/no-unused-vars
@@ -1081,19 +1591,53 @@
1081
1591
  wrapMethodWithContext(self, self[name + "Prefix"], m, self[name + "Suffix"]);
1082
1592
  });
1083
1593
  }
1594
+ /**
1595
+ * @description Creates multiple model instances in the repository.
1596
+ * @summary Persists multiple model instances to the underlying data store by calling
1597
+ * the create method for each model in the array.
1598
+ * @param {M[]} models - The array of model instances to create
1599
+ * @param {any[]} args - Additional arguments for the create operation
1600
+ * @return {Promise<M[]>} A promise that resolves to an array of created model instances
1601
+ */
1084
1602
  async createAll(models, ...args) {
1085
1603
  return Promise.all(models.map((m) => this.create(m, ...args)));
1086
1604
  }
1605
+ /**
1606
+ * @description Prepares a model for creation and executes pre-creation operations.
1607
+ * @summary Processes a model before it is created in the data store. This includes
1608
+ * creating a context, instantiating a new model instance, and enforcing any decorators
1609
+ * that should be applied before creation.
1610
+ * @param {M} model - The model instance to prepare for creation
1611
+ * @param {any[]} args - Additional arguments for the create operation
1612
+ * @return A promise that resolves to an array containing the prepared model and context arguments
1613
+ */
1087
1614
  async createPrefix(model, ...args) {
1088
1615
  const contextArgs = await Context.args(exports.OperationKeys.CREATE, this.class, args);
1089
1616
  model = new this.class(model);
1090
1617
  await enforceDBDecorators(this, contextArgs.context, model, exports.OperationKeys.CREATE, exports.OperationKeys.ON);
1091
1618
  return [model, ...contextArgs.args];
1092
1619
  }
1620
+ /**
1621
+ * @description Processes a model after creation and executes post-creation operations.
1622
+ * @summary Finalizes a model after it has been created in the data store. This includes
1623
+ * enforcing any decorators that should be applied after creation.
1624
+ * @param {M} model - The model instance that was created
1625
+ * @param {C} context - The context for the operation
1626
+ * @return {Promise<M>} A promise that resolves to the processed model instance
1627
+ */
1093
1628
  async createSuffix(model, context) {
1094
1629
  await enforceDBDecorators(this, context, model, exports.OperationKeys.CREATE, exports.OperationKeys.AFTER);
1095
1630
  return model;
1096
1631
  }
1632
+ /**
1633
+ * @description Prepares multiple models for creation and executes pre-creation operations.
1634
+ * @summary Processes multiple models before they are created in the data store. This includes
1635
+ * creating a context, instantiating new model instances, and enforcing any decorators
1636
+ * that should be applied before creation for each model.
1637
+ * @param {M[]} models - The array of model instances to prepare for creation
1638
+ * @param {any[]} args - Additional arguments for the create operation
1639
+ * @return A promise that resolves to an array containing the prepared models and context arguments
1640
+ */
1097
1641
  async createAllPrefix(models, ...args) {
1098
1642
  const contextArgs = await Context.args(exports.OperationKeys.CREATE, this.class, args);
1099
1643
  await Promise.all(models.map(async (m) => {
@@ -1103,17 +1647,50 @@
1103
1647
  }));
1104
1648
  return [models, ...contextArgs.args];
1105
1649
  }
1650
+ /**
1651
+ * @description Processes multiple models after creation and executes post-creation operations.
1652
+ * @summary Finalizes multiple models after they have been created in the data store. This includes
1653
+ * enforcing any decorators that should be applied after creation for each model.
1654
+ * @param {M[]} models - The array of model instances that were created
1655
+ * @param {C} context - The context for the operation
1656
+ * @return {Promise<M[]>} A promise that resolves to the array of processed model instances
1657
+ */
1106
1658
  async createAllSuffix(models, context) {
1107
1659
  await Promise.all(models.map((m) => enforceDBDecorators(this, context, m, exports.OperationKeys.CREATE, exports.OperationKeys.AFTER)));
1108
1660
  return models;
1109
1661
  }
1662
+ /**
1663
+ * @description Retrieves multiple model instances from the repository by their primary keys.
1664
+ * @summary Fetches multiple model instances from the underlying data store using their primary keys
1665
+ * by calling the read method for each key in the array.
1666
+ * @param {string[] | number[]} keys - The array of primary keys of the models to retrieve
1667
+ * @param {any[]} args - Additional arguments for the read operation
1668
+ * @return {Promise<M[]>} A promise that resolves to an array of retrieved model instances
1669
+ */
1110
1670
  async readAll(keys, ...args) {
1111
1671
  return await Promise.all(keys.map((id) => this.read(id, ...args)));
1112
1672
  }
1673
+ /**
1674
+ * @description Processes a model after retrieval and executes post-read operations.
1675
+ * @summary Finalizes a model after it has been retrieved from the data store. This includes
1676
+ * enforcing any decorators that should be applied after reading.
1677
+ * @param {M} model - The model instance that was retrieved
1678
+ * @param {C} context - The context for the operation
1679
+ * @return {Promise<M>} A promise that resolves to the processed model instance
1680
+ */
1113
1681
  async readSuffix(model, context) {
1114
1682
  await enforceDBDecorators(this, context, model, exports.OperationKeys.READ, exports.OperationKeys.AFTER);
1115
1683
  return model;
1116
1684
  }
1685
+ /**
1686
+ * @description Prepares for reading a model and executes pre-read operations.
1687
+ * @summary Processes a key before a model is read from the data store. This includes
1688
+ * creating a context, instantiating a new model instance with the key, and enforcing any decorators
1689
+ * that should be applied before reading.
1690
+ * @param {string} key - The primary key of the model to read
1691
+ * @param {any[]} args - Additional arguments for the read operation
1692
+ * @return A promise that resolves to an array containing the key and context arguments
1693
+ */
1117
1694
  async readPrefix(key, ...args) {
1118
1695
  const contextArgs = await Context.args(exports.OperationKeys.READ, this.class, args);
1119
1696
  const model = new this.class();
@@ -1121,6 +1698,15 @@
1121
1698
  await enforceDBDecorators(this, contextArgs.context, model, exports.OperationKeys.READ, exports.OperationKeys.ON);
1122
1699
  return [key, ...contextArgs.args];
1123
1700
  }
1701
+ /**
1702
+ * @description Prepares for reading multiple models and executes pre-read operations.
1703
+ * @summary Processes multiple keys before models are read from the data store. This includes
1704
+ * creating a context, instantiating new model instances with the keys, and enforcing any decorators
1705
+ * that should be applied before reading for each key.
1706
+ * @param {string[] | number[]} keys - The array of primary keys of the models to read
1707
+ * @param {any[]} args - Additional arguments for the read operation
1708
+ * @return A promise that resolves to an array containing the keys and context arguments
1709
+ */
1124
1710
  async readAllPrefix(keys, ...args) {
1125
1711
  const contextArgs = await Context.args(exports.OperationKeys.READ, this.class, args);
1126
1712
  await Promise.all(keys.map(async (k) => {
@@ -1130,17 +1716,50 @@
1130
1716
  }));
1131
1717
  return [keys, ...contextArgs.args];
1132
1718
  }
1719
+ /**
1720
+ * @description Processes multiple models after retrieval and executes post-read operations.
1721
+ * @summary Finalizes multiple models after they have been retrieved from the data store. This includes
1722
+ * enforcing any decorators that should be applied after reading for each model.
1723
+ * @param {M[]} models - The array of model instances that were retrieved
1724
+ * @param {C} context - The context for the operation
1725
+ * @return {Promise<M[]>} A promise that resolves to the array of processed model instances
1726
+ */
1133
1727
  async readAllSuffix(models, context) {
1134
1728
  await Promise.all(models.map((m) => enforceDBDecorators(this, context, m, exports.OperationKeys.READ, exports.OperationKeys.AFTER)));
1135
1729
  return models;
1136
1730
  }
1731
+ /**
1732
+ * @description Updates multiple model instances in the repository.
1733
+ * @summary Updates multiple model instances in the underlying data store by calling
1734
+ * the update method for each model in the array.
1735
+ * @param {M[]} models - The array of model instances to update
1736
+ * @param {any[]} args - Additional arguments for the update operation
1737
+ * @return {Promise<M[]>} A promise that resolves to an array of updated model instances
1738
+ */
1137
1739
  async updateAll(models, ...args) {
1138
1740
  return Promise.all(models.map((m) => this.update(m, ...args)));
1139
1741
  }
1742
+ /**
1743
+ * @description Processes a model after update and executes post-update operations.
1744
+ * @summary Finalizes a model after it has been updated in the data store. This includes
1745
+ * enforcing any decorators that should be applied after updating.
1746
+ * @param {M} model - The model instance that was updated
1747
+ * @param {C} context - The context for the operation
1748
+ * @return {Promise<M>} A promise that resolves to the processed model instance
1749
+ */
1140
1750
  async updateSuffix(model, context) {
1141
1751
  await enforceDBDecorators(this, context, model, exports.OperationKeys.UPDATE, exports.OperationKeys.AFTER);
1142
1752
  return model;
1143
1753
  }
1754
+ /**
1755
+ * @description Prepares a model for update and executes pre-update operations.
1756
+ * @summary Processes a model before it is updated in the data store. This includes
1757
+ * creating a context, validating the primary key, retrieving the existing model,
1758
+ * and enforcing any decorators that should be applied before updating.
1759
+ * @param {M} model - The model instance to prepare for update
1760
+ * @param {any[]} args - Additional arguments for the update operation
1761
+ * @return A promise that resolves to an array containing the prepared model and context arguments
1762
+ */
1144
1763
  async updatePrefix(model, ...args) {
1145
1764
  const contextArgs = await Context.args(exports.OperationKeys.UPDATE, this.class, args);
1146
1765
  const id = model[this.pk];
@@ -1150,6 +1769,15 @@
1150
1769
  await enforceDBDecorators(this, contextArgs.context, model, exports.OperationKeys.UPDATE, exports.OperationKeys.ON, oldModel);
1151
1770
  return [model, ...contextArgs.args];
1152
1771
  }
1772
+ /**
1773
+ * @description Prepares multiple models for update and executes pre-update operations.
1774
+ * @summary Processes multiple models before they are updated in the data store. This includes
1775
+ * creating a context, instantiating new model instances, and enforcing any decorators
1776
+ * that should be applied before updating for each model.
1777
+ * @param {M[]} models - The array of model instances to prepare for update
1778
+ * @param {any[]} args - Additional arguments for the update operation
1779
+ * @return A promise that resolves to an array containing the prepared models and context arguments
1780
+ */
1153
1781
  async updateAllPrefix(models, ...args) {
1154
1782
  const contextArgs = await Context.args(exports.OperationKeys.UPDATE, this.class, args);
1155
1783
  await Promise.all(models.map((m) => {
@@ -1159,23 +1787,65 @@
1159
1787
  }));
1160
1788
  return [models, ...contextArgs.args];
1161
1789
  }
1790
+ /**
1791
+ * @description Processes multiple models after update and executes post-update operations.
1792
+ * @summary Finalizes multiple models after they have been updated in the data store. This includes
1793
+ * enforcing any decorators that should be applied after updating for each model.
1794
+ * @param {M[]} models - The array of model instances that were updated
1795
+ * @param {C} context - The context for the operation
1796
+ * @return {Promise<M[]>} A promise that resolves to the array of processed model instances
1797
+ */
1162
1798
  async updateAllSuffix(models, context) {
1163
1799
  await Promise.all(models.map((m) => enforceDBDecorators(this, context, m, exports.OperationKeys.UPDATE, exports.OperationKeys.AFTER)));
1164
1800
  return models;
1165
1801
  }
1802
+ /**
1803
+ * @description Deletes multiple model instances from the repository by their primary keys.
1804
+ * @summary Removes multiple model instances from the underlying data store using their primary keys
1805
+ * by calling the delete method for each key in the array.
1806
+ * @param {string[] | number[]} keys - The array of primary keys of the models to delete
1807
+ * @param {any[]} args - Additional arguments for the delete operation
1808
+ * @return {Promise<M[]>} A promise that resolves to an array of deleted model instances
1809
+ */
1166
1810
  async deleteAll(keys, ...args) {
1167
1811
  return Promise.all(keys.map((k) => this.delete(k, ...args)));
1168
1812
  }
1813
+ /**
1814
+ * @description Processes a model after deletion and executes post-delete operations.
1815
+ * @summary Finalizes a model after it has been deleted from the data store. This includes
1816
+ * enforcing any decorators that should be applied after deletion.
1817
+ * @param {M} model - The model instance that was deleted
1818
+ * @param {C} context - The context for the operation
1819
+ * @return {Promise<M>} A promise that resolves to the processed model instance
1820
+ */
1169
1821
  async deleteSuffix(model, context) {
1170
1822
  await enforceDBDecorators(this, context, model, exports.OperationKeys.DELETE, exports.OperationKeys.AFTER);
1171
1823
  return model;
1172
1824
  }
1825
+ /**
1826
+ * @description Prepares for deleting a model and executes pre-delete operations.
1827
+ * @summary Processes a key before a model is deleted from the data store. This includes
1828
+ * creating a context, retrieving the model to be deleted, and enforcing any decorators
1829
+ * that should be applied before deletion.
1830
+ * @param {any} key - The primary key of the model to delete
1831
+ * @param {any[]} args - Additional arguments for the delete operation
1832
+ * @return A promise that resolves to an array containing the key and context arguments
1833
+ */
1173
1834
  async deletePrefix(key, ...args) {
1174
1835
  const contextArgs = await Context.args(exports.OperationKeys.DELETE, this.class, args);
1175
1836
  const model = await this.read(key, ...contextArgs.args);
1176
1837
  await enforceDBDecorators(this, contextArgs.context, model, exports.OperationKeys.DELETE, exports.OperationKeys.ON);
1177
1838
  return [key, ...contextArgs.args];
1178
1839
  }
1840
+ /**
1841
+ * @description Prepares for deleting multiple models and executes pre-delete operations.
1842
+ * @summary Processes multiple keys before models are deleted from the data store. This includes
1843
+ * creating a context, retrieving the models to be deleted, and enforcing any decorators
1844
+ * that should be applied before deletion for each model.
1845
+ * @param {string[] | number[]} keys - The array of primary keys of the models to delete
1846
+ * @param {any[]} args - Additional arguments for the delete operation
1847
+ * @return A promise that resolves to an array containing the keys and context arguments
1848
+ */
1179
1849
  async deleteAllPrefix(keys, ...args) {
1180
1850
  const contextArgs = await Context.args(exports.OperationKeys.DELETE, this.class, args);
1181
1851
  const models = await this.readAll(keys, ...contextArgs.args);
@@ -1184,10 +1854,26 @@
1184
1854
  }));
1185
1855
  return [keys, ...contextArgs.args];
1186
1856
  }
1857
+ /**
1858
+ * @description Processes multiple models after deletion and executes post-delete operations.
1859
+ * @summary Finalizes multiple models after they have been deleted from the data store. This includes
1860
+ * enforcing any decorators that should be applied after deletion for each model.
1861
+ * @param {M[]} models - The array of model instances that were deleted
1862
+ * @param {C} context - The context for the operation
1863
+ * @return {Promise<M[]>} A promise that resolves to the array of processed model instances
1864
+ */
1187
1865
  async deleteAllSuffix(models, context) {
1188
1866
  await Promise.all(models.map((m) => enforceDBDecorators(this, context, m, exports.OperationKeys.DELETE, exports.OperationKeys.AFTER)));
1189
1867
  return models;
1190
1868
  }
1869
+ /**
1870
+ * @description Merges two model instances into a new instance.
1871
+ * @summary Creates a new model instance by combining properties from an old model and a new model.
1872
+ * Properties from the new model override properties from the old model if they are defined.
1873
+ * @param {M} oldModel - The original model instance
1874
+ * @param {M} model - The new model instance with updated properties
1875
+ * @return {M} A new model instance with merged properties
1876
+ */
1191
1877
  merge(oldModel, model) {
1192
1878
  const extract = (model) => Object.entries(model).reduce((accum, [key, val]) => {
1193
1879
  if (typeof val !== "undefined")
@@ -1196,15 +1882,68 @@
1196
1882
  }, {});
1197
1883
  return new this.class(Object.assign({}, extract(oldModel), extract(model)));
1198
1884
  }
1885
+ /**
1886
+ * @description Returns a string representation of the repository.
1887
+ * @summary Creates a string that identifies this repository by the name of its model class.
1888
+ * @return {string} A string representation of the repository
1889
+ */
1199
1890
  toString() {
1200
1891
  return `${this.class.name} Repository`;
1201
1892
  }
1202
1893
  }
1203
1894
 
1895
+ /**
1896
+ * @description Concrete repository implementation with validation support.
1897
+ * @summary The Repository class extends BaseRepository to provide additional validation
1898
+ * functionality. It overrides prefix methods to perform model validation before database
1899
+ * operations and throws ValidationError when validation fails.
1900
+ * @template M - The model type extending Model
1901
+ * @template F - The repository flags type, defaults to RepositoryFlags
1902
+ * @template C - The context type, defaults to Context<F>
1903
+ * @class Repository
1904
+ * @example
1905
+ * class UserModel extends Model {
1906
+ * @id()
1907
+ * id: string;
1908
+ *
1909
+ * @required()
1910
+ * @minLength(3)
1911
+ * name: string;
1912
+ * }
1913
+ *
1914
+ * class UserRepository extends Repository<UserModel> {
1915
+ * constructor() {
1916
+ * super(UserModel);
1917
+ * }
1918
+ *
1919
+ * async create(model: UserModel): Promise<UserModel> {
1920
+ * // Implementation with automatic validation
1921
+ * return model;
1922
+ * }
1923
+ * }
1924
+ *
1925
+ * // Using the repository
1926
+ * const repo = new UserRepository();
1927
+ * try {
1928
+ * const user = await repo.create({ name: 'Jo' }); // Will throw ValidationError
1929
+ * } catch (error) {
1930
+ * console.error(error); // ValidationError: name must be at least 3 characters
1931
+ * }
1932
+ */
1204
1933
  class Repository extends BaseRepository {
1205
1934
  constructor(clazz) {
1206
1935
  super(clazz);
1207
1936
  }
1937
+ /**
1938
+ * @description Prepares a model for creation with validation.
1939
+ * @summary Overrides the base createPrefix method to add validation checks.
1940
+ * Creates a context, instantiates a new model, enforces decorators, and validates
1941
+ * the model before allowing creation to proceed.
1942
+ * @param {M} model - The model instance to prepare for creation
1943
+ * @param {any[]} args - Additional arguments for the create operation
1944
+ * @return A promise that resolves to an array containing the validated model and context arguments
1945
+ * @throws {ValidationError} If the model fails validation
1946
+ */
1208
1947
  async createPrefix(model, ...args) {
1209
1948
  const contextArgs = await Context.args(exports.OperationKeys.CREATE, this.class, args);
1210
1949
  model = new this.class(model);
@@ -1214,6 +1953,16 @@
1214
1953
  throw new ValidationError(errors.toString());
1215
1954
  return [model, ...contextArgs.args];
1216
1955
  }
1956
+ /**
1957
+ * @description Prepares multiple models for creation with validation.
1958
+ * @summary Overrides the base createAllPrefix method to add validation checks for multiple models.
1959
+ * Creates a context, instantiates new models, enforces decorators, and validates
1960
+ * each model before allowing creation to proceed. Collects validation errors from all models.
1961
+ * @param {M[]} models - The array of model instances to prepare for creation
1962
+ * @param {any[]} args - Additional arguments for the create operation
1963
+ * @return {Promise<any[]>} A promise that resolves to an array containing the validated models and context arguments
1964
+ * @throws {ValidationError} If any model fails validation, with details about which models failed
1965
+ */
1217
1966
  async createAllPrefix(models, ...args) {
1218
1967
  const contextArgs = await Context.args(exports.OperationKeys.CREATE, this.class, args);
1219
1968
  await Promise.all(models.map(async (m) => {
@@ -1235,6 +1984,18 @@
1235
1984
  throw new ValidationError(errors);
1236
1985
  return [models, ...contextArgs.args];
1237
1986
  }
1987
+ /**
1988
+ * @description Prepares a model for update with validation.
1989
+ * @summary Overrides the base updatePrefix method to add validation checks.
1990
+ * Creates a context, validates the primary key, retrieves the existing model,
1991
+ * merges the old and new models, enforces decorators, and validates the model
1992
+ * before allowing the update to proceed.
1993
+ * @param {M} model - The model instance to prepare for update
1994
+ * @param {any[]} args - Additional arguments for the update operation
1995
+ * @return A promise that resolves to an array containing the validated model and context arguments
1996
+ * @throws {InternalError} If the model doesn't have a primary key value
1997
+ * @throws {ValidationError} If the model fails validation
1998
+ */
1238
1999
  async updatePrefix(model, ...args) {
1239
2000
  const contextArgs = await Context.args(exports.OperationKeys.UPDATE, this.class, args);
1240
2001
  const pk = model[this.pk];
@@ -1248,6 +2009,18 @@
1248
2009
  throw new ValidationError(errors.toString());
1249
2010
  return [model, ...contextArgs.args];
1250
2011
  }
2012
+ /**
2013
+ * @description Prepares multiple models for update with validation.
2014
+ * @summary Overrides the base updateAllPrefix method to add validation checks for multiple models.
2015
+ * Creates a context, validates primary keys, retrieves existing models, merges old and new models,
2016
+ * enforces decorators, and validates each model before allowing updates to proceed.
2017
+ * Collects validation errors from all models.
2018
+ * @param {M[]} models - The array of model instances to prepare for update
2019
+ * @param {any[]} args - Additional arguments for the update operation
2020
+ * @return A promise that resolves to an array containing the validated models and context arguments
2021
+ * @throws {InternalError} If any model doesn't have a primary key value
2022
+ * @throws {ValidationError} If any model fails validation, with details about which models failed
2023
+ */
1251
2024
  async updateAllPrefix(models, ...args) {
1252
2025
  const contextArgs = await Context.args(exports.OperationKeys.UPDATE, this.class, args);
1253
2026
  const ids = models.map((m) => {
@@ -1273,19 +2046,25 @@
1273
2046
  throw new ValidationError(errors);
1274
2047
  return [models, ...contextArgs.args];
1275
2048
  }
2049
+ /**
2050
+ * @description Creates a reflection key for database operations.
2051
+ * @summary Generates a key for storing metadata in the reflection system by prefixing
2052
+ * the provided key with the database reflection prefix.
2053
+ * @param {string} key - The base key to prefix
2054
+ * @return {string} The prefixed reflection key
2055
+ */
1276
2056
  static key(key) {
1277
2057
  return DBKeys.REFLECT + key;
1278
2058
  }
1279
2059
  }
1280
2060
 
1281
2061
  /**
1282
- * Marks the property as readonly.
1283
- *
1284
- * @param {string} [message] the error message. Defaults to {@link DEFAULT_ERROR_MESSAGES.READONLY.INVALID}
1285
- *
1286
- * @decorator readonly
1287
- *
1288
- * @category Decorators
2062
+ * @description Prevents a property from being modified after initial creation.
2063
+ * @summary Marks the property as readonly, causing validation errors if attempts are made to modify it during updates.
2064
+ * @param {string} [message] - The error message to display when validation fails. Defaults to {@link DEFAULT_ERROR_MESSAGES.READONLY.INVALID}
2065
+ * @return {PropertyDecorator} A decorator function that can be applied to class properties
2066
+ * @function readonly
2067
+ * @category Property Decorators
1289
2068
  */
1290
2069
  function readonly(message = DEFAULT_ERROR_MESSAGES.READONLY.INVALID) {
1291
2070
  const key = decoratorValidation.Validation.updateKey(DBKeys.READONLY);
@@ -1295,13 +2074,28 @@
1295
2074
  }))
1296
2075
  .apply();
1297
2076
  }
2077
+ /**
2078
+ * @description Handler function that sets a timestamp property to the current timestamp.
2079
+ * @summary Updates a model property with the current timestamp from the repository context.
2080
+ * @template M - The model type extending Model
2081
+ * @template R - The repository type extending IRepository
2082
+ * @template V - The data type for the operation
2083
+ * @template F - The repository flags type
2084
+ * @template C - The context type
2085
+ * @param {C} context - The repository context containing the current timestamp
2086
+ * @param {V} data - The data being processed
2087
+ * @param key - The property key to update
2088
+ * @param {M} model - The model instance being updated
2089
+ * @return {Promise<void>} A promise that resolves when the timestamp has been set
2090
+ * @function timestampHandler
2091
+ * @memberOf module:db-decorators
2092
+ */
1298
2093
  async function timestampHandler(context, data, key, model) {
1299
2094
  model[key] = context.timestamp;
1300
2095
  }
1301
2096
  /**
1302
- * Marks the property as timestamp.
1303
- * Makes it {@link required}
1304
- * Makes it a {@link date}
2097
+ * @description Automatically manages timestamp properties for tracking creation and update times.
2098
+ * @summary Marks the property as a timestamp, making it required and ensuring it's a valid date. The property will be automatically updated with the current timestamp during specified operations.
1305
2099
  *
1306
2100
  * Date Format:
1307
2101
  *
@@ -1321,13 +2115,30 @@
1321
2115
  * S = miliseconds
1322
2116
  * </pre>
1323
2117
  *
1324
- * @param {string[]} operation The {@link DBOperations} to act on. Defaults to {@link DBOperations.CREATE_UPDATE}
1325
- * @param {string} [format] The TimeStamp format. defaults to {@link DEFAULT_TIMESTAMP_FORMAT}
1326
- * @param {{new: UpdateValidator}} [validator] defaults to {@link TimestampValidator}
1327
- *
1328
- * @decorator timestamp
1329
- *
1330
- * @category Decorators
2118
+ * @param {OperationKeys[]} operation - The operations to act on. Defaults to {@link DBOperations.CREATE_UPDATE}
2119
+ * @param {string} [format] - The timestamp format. Defaults to {@link DEFAULT_TIMESTAMP_FORMAT}
2120
+ * @return {PropertyDecorator} A decorator function that can be applied to class properties
2121
+ * @function timestamp
2122
+ * @category Property Decorators
2123
+ * @mermaid
2124
+ * sequenceDiagram
2125
+ * participant C as Client
2126
+ * participant M as Model
2127
+ * participant T as TimestampDecorator
2128
+ * participant V as Validator
2129
+ *
2130
+ * C->>M: Create/Update model
2131
+ * M->>T: Process timestamp property
2132
+ * T->>M: Apply required validation
2133
+ * T->>M: Apply date format validation
2134
+ *
2135
+ * alt Update operation
2136
+ * T->>V: Register timestamp validator
2137
+ * V->>M: Validate timestamp is newer
2138
+ * end
2139
+ *
2140
+ * T->>M: Set current timestamp
2141
+ * M->>C: Return updated model
1331
2142
  */
1332
2143
  function timestamp(operation = DBOperations.CREATE_UPDATE, format = DEFAULT_TIMESTAMP_FORMAT) {
1333
2144
  const key = decoratorValidation.Validation.updateKey(DBKeys.TIMESTAMP);
@@ -1344,6 +2155,22 @@
1344
2155
  .define(...decorators)
1345
2156
  .apply();
1346
2157
  }
2158
+ /**
2159
+ * @description Handler function that serializes a property to JSON string during create and update operations.
2160
+ * @summary Converts a complex object property to a JSON string before storing it in the database.
2161
+ * @template M - The model type extending Model
2162
+ * @template R - The repository type extending IRepository
2163
+ * @template V - The data type for the operation
2164
+ * @template F - The repository flags type
2165
+ * @template C - The context type
2166
+ * @param {C} context - The repository context
2167
+ * @param {V} data - The data being processed
2168
+ * @param key - The property key to serialize
2169
+ * @param {M} model - The model instance being processed
2170
+ * @return {Promise<void>} A promise that resolves when the property has been serialized
2171
+ * @function serializeOnCreateUpdate
2172
+ * @memberOf module:db-decorators
2173
+ */
1347
2174
  async function serializeOnCreateUpdate(context, data, key, model) {
1348
2175
  if (!model[key])
1349
2176
  return;
@@ -1355,6 +2182,22 @@
1355
2182
  throw new SerializationError(`Failed to serialize ${key.toString()} property of model ${model.constructor.name}: e`);
1356
2183
  }
1357
2184
  }
2185
+ /**
2186
+ * @description Handler function that deserializes a property from JSON string after database operations.
2187
+ * @summary Converts a JSON string property back to its original complex object form after retrieving it from the database.
2188
+ * @template M - The model type extending Model
2189
+ * @template R - The repository type extending IRepository
2190
+ * @template V - The data type for the operation
2191
+ * @template F - The repository flags type
2192
+ * @template C - The context type
2193
+ * @param {C} context - The repository context
2194
+ * @param {V} data - The data being processed
2195
+ * @param key - The property key to deserialize
2196
+ * @param {M} model - The model instance being processed
2197
+ * @return {Promise<void>} A promise that resolves when the property has been deserialized
2198
+ * @function serializeAfterAll
2199
+ * @memberOf module:db-decorators
2200
+ */
1358
2201
  async function serializeAfterAll(context, data, key, model) {
1359
2202
  if (!model[key])
1360
2203
  return;
@@ -1368,32 +2211,76 @@
1368
2211
  }
1369
2212
  }
1370
2213
  /**
1371
- * @summary Serialize Decorator
1372
- * @description properties decorated will the serialized before stored in the db
1373
- *
2214
+ * @description Enables automatic JSON serialization and deserialization for complex object properties.
2215
+ * @summary Decorator that automatically converts complex objects to JSON strings before storing in the database and back to objects when retrieving them.
2216
+ * @return {PropertyDecorator} A decorator function that can be applied to class properties
1374
2217
  * @function serialize
1375
- *
1376
- * @memberOf module:wallet-db.Decorators
2218
+ * @category Property Decorators
2219
+ * @mermaid
2220
+ * sequenceDiagram
2221
+ * participant C as Client
2222
+ * participant M as Model
2223
+ * participant S as SerializeDecorator
2224
+ * participant DB as Database
2225
+ *
2226
+ * Note over C,DB: Create/Update Flow
2227
+ * C->>M: Set complex object property
2228
+ * M->>S: Process property (create/update)
2229
+ * S->>M: Convert to JSON string
2230
+ * M->>DB: Store serialized data
2231
+ *
2232
+ * Note over C,DB: Retrieval Flow
2233
+ * C->>M: Request model
2234
+ * M->>DB: Fetch data
2235
+ * DB->>M: Return with serialized property
2236
+ * M->>S: Process property (after all ops)
2237
+ * S->>M: Parse JSON back to object
2238
+ * M->>C: Return model with deserialized property
1377
2239
  */
1378
2240
  function serialize() {
1379
2241
  return reflection.apply(onCreateUpdate(serializeOnCreateUpdate), after(DBOperations.ALL, serializeAfterAll), decoratorValidation.type([String.name, Object.name]), reflection.metadata(Repository.key(DBKeys.SERIALIZE), {}));
1380
2242
  }
1381
2243
 
2244
+ /**
2245
+ * @description Decorator that marks a property as an ID field
2246
+ * @summary Creates a composite decorator that marks a property as required, readonly, and as the ID field for database operations
2247
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
2248
+ * @function id
2249
+ * @category Property Decorators
2250
+ */
1382
2251
  function id() {
1383
2252
  return reflection.apply(decoratorValidation.required(), readonly(), decoratorValidation.propMetadata(Repository.key(DBKeys.ID), {}));
1384
2253
  }
1385
2254
 
1386
2255
  /**
1387
- * @summary Validates the update of a model
1388
- *
1389
- * @param {T} oldModel
1390
- * @param {T} newModel
1391
- * @param {string[]} [exceptions]
1392
- *
2256
+ * @description Validates changes between two model versions
2257
+ * @summary Compares an old and new model version to validate update operations
2258
+ * @template M - Type extending Model
2259
+ * @param {M} oldModel - The original model version
2260
+ * @param {M} newModel - The updated model version
2261
+ * @param {...string[]} exceptions - Properties to exclude from validation
2262
+ * @return {ModelErrorDefinition|undefined} Error definition if validation fails, undefined otherwise
1393
2263
  * @function validateCompare
1394
- * @return {ModelErrorDefinition | undefined}
1395
- *
1396
- * @memberOf module:db-decorators.Model
2264
+ * @memberOf module:db-decorators
2265
+ * @mermaid
2266
+ * sequenceDiagram
2267
+ * participant Caller
2268
+ * participant validateCompare
2269
+ * participant Reflection
2270
+ * participant Validation
2271
+ *
2272
+ * Caller->>validateCompare: oldModel, newModel, exceptions
2273
+ * validateCompare->>Reflection: get decorated properties
2274
+ * Reflection-->>validateCompare: property decorators
2275
+ * loop For each decorated property
2276
+ * validateCompare->>Validation: get validator
2277
+ * Validation-->>validateCompare: validator
2278
+ * validateCompare->>validateCompare: validate property update
2279
+ * end
2280
+ * loop For nested models
2281
+ * validateCompare->>validateCompare: validate nested models
2282
+ * end
2283
+ * validateCompare-->>Caller: validation errors or undefined
1397
2284
  */
1398
2285
  function validateCompare(oldModel, newModel, ...exceptions) {
1399
2286
  const decoratedProperties = [];
@@ -1505,9 +2392,21 @@
1505
2392
  }
1506
2393
 
1507
2394
  /**
1508
- *
1509
- * @param {str} str
1510
- * @memberOf db-decorators.model
2395
+ * @description Hashes a property value during create or update operations
2396
+ * @summary Callback function used by the hash decorator to apply hashing to a property value
2397
+ * @template M - Type extending Model
2398
+ * @template R - Type extending IRepository
2399
+ * @template V - Type for metadata
2400
+ * @template F - Type extending RepositoryFlags
2401
+ * @template C - Type extending Context
2402
+ * @param {C} context - The operation context
2403
+ * @param {V} data - Metadata for the operation
2404
+ * @param key - The property key to hash
2405
+ * @param {M} model - The model being processed
2406
+ * @param {M} [oldModel] - The previous model state (for updates)
2407
+ * @return {void}
2408
+ * @function hashOnCreateUpdate
2409
+ * @memberOf module:db-decorators
1511
2410
  */
1512
2411
  function hashOnCreateUpdate(context, data, key, model, oldModel) {
1513
2412
  if (typeof model[key] === "undefined")
@@ -1517,9 +2416,32 @@
1517
2416
  return;
1518
2417
  model[key] = hash;
1519
2418
  }
2419
+ /**
2420
+ * @description Creates a decorator that hashes a property value
2421
+ * @summary Decorator that automatically hashes a property value during create and update operations
2422
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
2423
+ * @function hash
2424
+ * @category Property Decorators
2425
+ */
1520
2426
  function hash() {
1521
2427
  return reflection.apply(onCreateUpdate(hashOnCreateUpdate), decoratorValidation.propMetadata(Repository.key(DBKeys.HASH), {}));
1522
2428
  }
2429
+ /**
2430
+ * @description Composes a property value from other properties during create or update operations
2431
+ * @summary Callback function used by composed decorators to generate a property value from other properties
2432
+ * @template M - Type extending Model
2433
+ * @template R - Type extending IRepository
2434
+ * @template V - Type extending ComposedFromMetadata
2435
+ * @template F - Type extending RepositoryFlags
2436
+ * @template C - Type extending Context
2437
+ * @param {C} context - The operation context
2438
+ * @param {V} data - Metadata for the composition
2439
+ * @param key - The property key to set the composed value on
2440
+ * @param {M} model - The model being processed
2441
+ * @return {void}
2442
+ * @function composedFromCreateUpdate
2443
+ * @memberOf module:db-decorators
2444
+ */
1523
2445
  function composedFromCreateUpdate(context, data, key, model) {
1524
2446
  try {
1525
2447
  const { args, type, prefix, suffix, separator } = data;
@@ -1542,6 +2464,19 @@
1542
2464
  throw new InternalError(`Failed to compose value: ${e}`);
1543
2465
  }
1544
2466
  }
2467
+ /**
2468
+ * @description Creates a decorator that composes a property value from other properties
2469
+ * @summary Base function for creating property composition decorators
2470
+ * @param {string[]} args - Property names to compose from
2471
+ * @param {boolean} [hashResult=false] - Whether to hash the composed result
2472
+ * @param {string} [separator=DefaultSeparator] - Character used to join the composed values
2473
+ * @param {"keys"|"values"} [type="values"] - Whether to use property keys or values
2474
+ * @param {string} [prefix=""] - Optional prefix to add to the composed value
2475
+ * @param {string} [suffix=""] - Optional suffix to add to the composed value
2476
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
2477
+ * @function composedFrom
2478
+ * @category PropertyDecorators
2479
+ */
1545
2480
  function composedFrom(args, hashResult = false, separator = DefaultSeparator, type = "values", prefix = "", suffix = "") {
1546
2481
  const data = {
1547
2482
  args: args,
@@ -1559,27 +2494,65 @@
1559
2494
  decorators.push(hash());
1560
2495
  return reflection.apply(...decorators);
1561
2496
  }
2497
+ /**
2498
+ * @description Creates a decorator that composes a property value from property keys
2499
+ * @summary Decorator that generates a property value by joining the names of other properties
2500
+ * @param {string[]} args - Property names to compose from
2501
+ * @param {string} [separator=DefaultSeparator] - Character used to join the property names
2502
+ * @param {boolean} [hash=false] - Whether to hash the composed result
2503
+ * @param {string} [prefix=""] - Optional prefix to add to the composed value
2504
+ * @param {string} [suffix=""] - Optional suffix to add to the composed value
2505
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
2506
+ * @function composedFromKeys
2507
+ * @category PropertyDecorators
2508
+ */
1562
2509
  function composedFromKeys(args, separator = DefaultSeparator, hash = false, prefix = "", suffix = "") {
1563
2510
  return composedFrom(args, hash, separator, "keys", prefix, suffix);
1564
2511
  }
2512
+ /**
2513
+ * @description Creates a decorator that composes a property value from property values
2514
+ * @summary Decorator that generates a property value by joining the values of other properties
2515
+ * @param {string[]} args - Property names whose values will be composed
2516
+ * @param {string} [separator=DefaultSeparator] - Character used to join the property values
2517
+ * @param {boolean} [hash=false] - Whether to hash the composed result
2518
+ * @param {string} [prefix=""] - Optional prefix to add to the composed value
2519
+ * @param {string} [suffix=""] - Optional suffix to add to the composed value
2520
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
2521
+ * @function composed
2522
+ * @category PropertyDecorators
2523
+ */
1565
2524
  function composed(args, separator = DefaultSeparator, hash = false, prefix = "", suffix = "") {
1566
2525
  return composedFrom(args, hash, separator, "values", prefix, suffix);
1567
2526
  }
1568
2527
  /**
1569
- * Creates a decorator function that updates the version of a model during create or update operations.
1570
- *
1571
- * @param {CrudOperations} operation - The type of operation being performed (CREATE or UPDATE).
1572
- * @returns {function} A function that updates the version of the model based on the operation type.
1573
- *
2528
+ * @description Creates a function that updates a version property during operations
2529
+ * @summary Factory function that generates a callback for incrementing version numbers
2530
+ * @param {CrudOperations} operation - The type of operation (CREATE or UPDATE)
2531
+ * @return {Function} A callback function that updates the version property
1574
2532
  * @template M - Type extending Model
1575
- * @template V - Type extending IRepository<M>
1576
- *
1577
- * @this {V} - The repository instance
1578
- * @param {Context<M>} context - The context of the operation
1579
- * @param {unknown} data - Additional data for the operation (not used in this function)
1580
- * @param {string} key - The key of the version property in the model
1581
- * @param {M} model - The model being updated
1582
- * @throws {InternalError} If an invalid operation is provided or if version update fails
2533
+ * @template R - Type extending IRepository
2534
+ * @template V - Type for metadata
2535
+ * @template F - Type extending RepositoryFlags
2536
+ * @template C - Type extending Context
2537
+ * @function versionCreateUpdate
2538
+ * @memberOf module:db-decorators
2539
+ * @mermaid
2540
+ * sequenceDiagram
2541
+ * participant Caller
2542
+ * participant versionCreateUpdate
2543
+ *
2544
+ * Caller->>versionCreateUpdate: operation
2545
+ * versionCreateUpdate-->>Caller: callback function
2546
+ * Note over Caller,versionCreateUpdate: When callback is executed:
2547
+ * Caller->>versionCreateUpdate: context, data, key, model
2548
+ * alt operation is CREATE
2549
+ * versionCreateUpdate->>versionCreateUpdate: set version to 1
2550
+ * else operation is UPDATE
2551
+ * versionCreateUpdate->>versionCreateUpdate: increment version
2552
+ * else invalid operation
2553
+ * versionCreateUpdate->>versionCreateUpdate: throw error
2554
+ * end
2555
+ * versionCreateUpdate-->>Caller: void
1583
2556
  */
1584
2557
  function versionCreateUpdate(operation) {
1585
2558
  return function versionCreateUpdate(context, data, key, model) {
@@ -1601,18 +2574,22 @@
1601
2574
  };
1602
2575
  }
1603
2576
  /**
1604
- * @description Creates a decorator for versioning a property in a model.
1605
- * @summary This decorator applies multiple sub-decorators to handle version management during create and update operations.
1606
- *
1607
- * @returns {Function} A composite decorator that:
1608
- * - Sets the type of the property to Number
1609
- * - Applies a version update on create operations
1610
- * - Applies a version update on update operations
1611
- * - Adds metadata indicating this property is used for versioning
2577
+ * @description Creates a decorator for versioning a property in a model
2578
+ * @summary This decorator applies multiple sub-decorators to handle version management during create and update operations
2579
+ * @return {PropertyDecorator} A composite decorator that sets the type to Number, manages version updates, and adds versioning metadata
2580
+ * @function version
2581
+ * @category PropertyDecorators
1612
2582
  */
1613
2583
  function version() {
1614
2584
  return reflection.apply(decoratorValidation.type(Number.name), onCreate(versionCreateUpdate(exports.OperationKeys.CREATE)), onUpdate(versionCreateUpdate(exports.OperationKeys.UPDATE)), decoratorValidation.propMetadata(Repository.key(DBKeys.VERSION), true));
1615
2585
  }
2586
+ /**
2587
+ * @description Creates a decorator that marks a property as transient
2588
+ * @summary Decorator that indicates a property should not be persisted to the database
2589
+ * @return {PropertyDecorator} A decorator that can be applied to class properties
2590
+ * @function transient
2591
+ * @category PropertyDecorators
2592
+ */
1616
2593
  function transient() {
1617
2594
  return function transient(model, attribute) {
1618
2595
  decoratorValidation.propMetadata(Repository.key(DBKeys.TRANSIENT), true)(model, attribute);
@@ -1631,10 +2608,49 @@
1631
2608
  return validateCompare(previousVersion, this, ...exclusions);
1632
2609
  };
1633
2610
 
2611
+ /**
2612
+ * @description Checks if a model is marked as transient
2613
+ * @summary Determines whether a model class has been decorated with the transient decorator
2614
+ * @template M - Type extending Model
2615
+ * @param {M} model - The model instance to check
2616
+ * @return {boolean} True if the model is transient, false otherwise
2617
+ * @function isTransient
2618
+ * @memberOf module:db-decorators
2619
+ */
1634
2620
  function isTransient(model) {
1635
2621
  return !!(Reflect.getMetadata(Repository.key(DBKeys.TRANSIENT), model.constructor) ||
1636
2622
  Reflect.getMetadata(Repository.key(DBKeys.TRANSIENT), decoratorValidation.Model.get(model.constructor.name)));
1637
2623
  }
2624
+ /**
2625
+ * @description Separates transient properties from a model
2626
+ * @summary Extracts properties marked as transient into a separate object
2627
+ * @template M - Type extending Model
2628
+ * @param {M} model - The model instance to process
2629
+ * @return {Object} Object containing the model without transient properties and a separate transient object
2630
+ * @property {M} model - The model with transient properties removed
2631
+ * @property {Record<string, any>} [transient] - Object containing the transient properties
2632
+ * @function modelToTransient
2633
+ * @memberOf module:db-decorators
2634
+ * @mermaid
2635
+ * sequenceDiagram
2636
+ * participant Caller
2637
+ * participant modelToTransient
2638
+ * participant isTransient
2639
+ * participant getAllPropertyDecoratorsRecursive
2640
+ *
2641
+ * Caller->>modelToTransient: model
2642
+ * modelToTransient->>isTransient: check if model is transient
2643
+ * isTransient-->>modelToTransient: transient status
2644
+ * alt model is not transient
2645
+ * modelToTransient-->>Caller: {model}
2646
+ * else model is transient
2647
+ * modelToTransient->>getAllPropertyDecoratorsRecursive: get transient properties
2648
+ * getAllPropertyDecoratorsRecursive-->>modelToTransient: property decorators
2649
+ * modelToTransient->>modelToTransient: separate properties
2650
+ * modelToTransient->>Model.build: rebuild model without transient props
2651
+ * modelToTransient-->>Caller: {model, transient}
2652
+ * end
2653
+ */
1638
2654
  function modelToTransient(model) {
1639
2655
  if (!isTransient(model))
1640
2656
  return { model: model };
@@ -1660,6 +2676,19 @@
1660
2676
  return result;
1661
2677
  }
1662
2678
 
2679
+ /**
2680
+ * @description Database decorators for TypeScript applications
2681
+ * @summary A comprehensive library providing decorators and utilities for database operations, model definitions, validation, and repository patterns in TypeScript applications
2682
+ * @module db-decorators
2683
+ */
2684
+ /**
2685
+ * @description Current version of the reflection package
2686
+ * @summary Stores the semantic version number of the package
2687
+ * @const VERSION
2688
+ * @memberOf module:db-decorators
2689
+ */
2690
+ const VERSION = "0.6.2";
2691
+
1663
2692
  exports.BaseError = BaseError;
1664
2693
  exports.BaseRepository = BaseRepository;
1665
2694
  exports.ConflictError = ConflictError;
@@ -1679,6 +2708,7 @@
1679
2708
  exports.SerializationError = SerializationError;
1680
2709
  exports.UpdateValidationKeys = UpdateValidationKeys;
1681
2710
  exports.UpdateValidator = UpdateValidator;
2711
+ exports.VERSION = VERSION;
1682
2712
  exports.ValidationError = ValidationError;
1683
2713
  exports.after = after;
1684
2714
  exports.afterAny = afterAny;
@@ -1724,4 +2754,4 @@
1724
2754
  exports.wrapMethodWithContext = wrapMethodWithContext;
1725
2755
 
1726
2756
  }));
1727
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGItZGVjb3JhdG9ycy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9tb2RlbC9jb25zdGFudHMudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9jb25zdGFudHMudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi92YWxpZGF0b3JzL1JlYWRPbmx5VmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vdmFsaWRhdG9ycy9UaW1lc3RhbXBWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi92YWxpZGF0b3JzL1VwZGF0ZVZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL3ZhbGlkYXRpb24udHMiLCIuLi9zcmMvb3BlcmF0aW9ucy9jb25zdGFudHMudHMiLCIuLi9zcmMvb3BlcmF0aW9ucy9PcGVyYXRpb25zUmVnaXN0cnkudHMiLCIuLi9zcmMvb3BlcmF0aW9ucy9PcGVyYXRpb25zLnRzIiwiLi4vc3JjL29wZXJhdGlvbnMvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L2Vycm9ycy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L3V0aWxzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvQ29udGV4dC50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L3dyYXBwZXJzLnRzIiwiLi4vc3JjL2lkZW50aXR5L3V0aWxzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvQmFzZVJlcG9zaXRvcnkudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS9SZXBvc2l0b3J5LnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9pZGVudGl0eS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL21vZGVsL3ZhbGlkYXRpb24udHMiLCIuLi9zcmMvbW9kZWwvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9tb2RlbC9tb2RlbC50cyIsIi4uL3NyYy9tb2RlbC91dGlscy50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBNb2RlbEtleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgSG9sZHMgdGhlIE1vZGVsIHJlZmxlY3Rpb24ga2V5c1xuICogQGNvbnN0IERCS2V5c1xuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5Nb2RlbFxuICovXG5leHBvcnQgY29uc3QgREJLZXlzID0ge1xuICBSRUZMRUNUOiBgJHtNb2RlbEtleXMuUkVGTEVDVH1wZXJzaXN0ZW5jZS5gLFxuICBSRVBPU0lUT1JZOiBcInJlcG9zaXRvcnlcIixcbiAgQ0xBU1M6IFwiX2NsYXNzXCIsXG4gIElEOiBcImlkXCIsXG4gIElOREVYOiBcImluZGV4XCIsXG4gIFVOSVFVRTogXCJ1bmlxdWVcIixcbiAgU0VSSUFMSVpFOiBcInNlcmlhbGl6ZVwiLFxuICBSRUFET05MWTogXCJyZWFkb25seVwiLFxuICBUSU1FU1RBTVA6IFwidGltZXN0YW1wXCIsXG4gIFRSQU5TSUVOVDogXCJ0cmFuc2llbnRcIixcbiAgSEFTSDogXCJoYXNoXCIsXG4gIENPTVBPU0VEOiBcImNvbXBvc2VkXCIsXG4gIFZFUlNJT046IFwidmVyc2lvblwiLFxuICBPUklHSU5BTDogXCJfX29yaWdpbmFsT2JqXCIsXG59O1xuXG4vKipcbiAqIEBzdW1tYXJ5IFRoZSBkZWZhdWx0IHNlcGFyYXRvciB3aGVuIGNvbmNhdGVuYXRpbmcgaW5kZXhlc1xuICpcbiAqIEBjb25zdCBEZWZhdWx0SW5kZXhTZXBhcmF0b3JcbiAqXG4gKiBAY2F0ZWdvcnkgTWFuYWdlcnNcbiAqIEBzdWJjYXRlZ29yeSBDb25zdGFudHNcbiAqL1xuZXhwb3J0IGNvbnN0IERlZmF1bHRTZXBhcmF0b3IgPSBcIl9cIjtcblxuLyoqXG4gKiBAc3VtbWFyeSBIb2xkcyB0aGUgZGVmYXVsdCB0aW1lc3RhbXAgZGF0ZSBmb3JtYXRcbiAqIEBjb25zdGFudCBERUZBVUxUX1RJTUVTVEFNUF9GT1JNQVRcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuTW9kZWxcbiAqL1xuZXhwb3J0IGNvbnN0IERFRkFVTFRfVElNRVNUQU1QX0ZPUk1BVCA9IFwiZGQvTU0veXl5eSBISDptbTpzczpTXCI7XG4iLCJpbXBvcnQgeyBEQktleXMgfSBmcm9tIFwiLi4vbW9kZWwvY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgaG9sZHMgdGhlIGRlZmF1bHQgZXJyb3IgbWVzc2FnZXNcbiAqIEBjb25zdCBERUZBVUxUX0VSUk9SX01FU1NBR0VTXG4gKlxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzLk1vZGVsXG4gKi9cbmV4cG9ydCBjb25zdCBERUZBVUxUX0VSUk9SX01FU1NBR0VTID0ge1xuICBJRDoge1xuICAgIElOVkFMSUQ6IFwiVGhpcyBJZCBpcyBpbnZhbGlkXCIsXG4gICAgUkVRVUlSRUQ6IFwiVGhlIElkIGlzIG1hbmRhdG9yeVwiLFxuICB9LFxuICBSRUFET05MWToge1xuICAgIElOVkFMSUQ6IFwiVGhpcyBjYW5ub3QgYmUgdXBkYXRlZFwiLFxuICB9LFxuICBUSU1FU1RBTVA6IHtcbiAgICBSRVFVSVJFRDogXCJUaW1lc3RhbXAgaXMgTWFuZGF0b3J5XCIsXG4gICAgREFURTogXCJUaGUgVGltZXN0YW1wIG11c3QgdGhlIGEgdmFsaWQgZGF0ZVwiLFxuICAgIElOVkFMSUQ6IFwiVGhpcyB2YWx1ZSBtdXN0IGFsd2F5cyBpbmNyZWFzZVwiLFxuICB9LFxufTtcblxuLyoqXG4gKiBAc3VtbWFyeSBVcGRhdGUgcmVmbGVjdGlvbiBrZXlzXG4gKiBAY29uc3QgVXBkYXRlVmFsaWRhdGlvbktleXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5PcGVyYXRpb25zXG4gKi9cbmV4cG9ydCBjb25zdCBVcGRhdGVWYWxpZGF0aW9uS2V5cyA9IHtcbiAgUkVGTEVDVDogXCJkYi51cGRhdGUudmFsaWRhdGlvbi5cIixcbiAgVElNRVNUQU1QOiBEQktleXMuVElNRVNUQU1QLFxuICBSRUFET05MWTogREJLZXlzLlJFQURPTkxZLFxufTtcbiIsImltcG9ydCB7IHZhbGlkYXRvciwgVmFsaWRhdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVXBkYXRlVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBpc0VxdWFsIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVmFsaWRhdG9yIGZvciB0aGUge0BsaW5rIHJlYWRvbmx5fSBkZWNvcmF0b3JcbiAqXG4gKiBAY2xhc3MgUmVhZE9ubHlWYWxpZGF0b3JcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVXBkYXRlVmFsaWRhdGlvbktleXMuUkVBRE9OTFkpXG5leHBvcnQgY2xhc3MgUmVhZE9ubHlWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihERUZBVUxUX0VSUk9SX01FU1NBR0VTLlJFQURPTkxZLklOVkFMSUQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBpbmhlcml0RG9jXG4gICAqL1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGhhc0Vycm9ycyh2YWx1ZTogYW55LCAuLi5hcmdzOiBhbnlbXSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSB2YWx1ZSBoYXMgbm90IGNoYW5nZWRcbiAgICogQHBhcmFtIHthbnl9IHZhbHVlXG4gICAqIEBwYXJhbSB7YW55fSBvbGRWYWx1ZVxuICAgKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlIG92ZXJyaWRlXG4gICAqL1xuICBwdWJsaWMgdXBkYXRlSGFzRXJyb3JzKFxuICAgIHZhbHVlOiBhbnksXG4gICAgb2xkVmFsdWU6IGFueSxcbiAgICBtZXNzYWdlPzogc3RyaW5nLFxuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG5cbiAgICByZXR1cm4gaXNFcXVhbCh2YWx1ZSwgb2xkVmFsdWUpXG4gICAgICA/IHVuZGVmaW5lZFxuICAgICAgOiB0aGlzLmdldE1lc3NhZ2UobWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuICB9XG59XG4iLCJpbXBvcnQgeyB2YWxpZGF0b3IsIFZhbGlkYXRvciB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMsIFVwZGF0ZVZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4uL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGUgdXBkYXRlIG9mIGEgdGltZXN0YW1wXG4gKlxuICogQGNsYXNzIFRpbWVzdGFtcFZhbGlkYXRvclxuICogQGV4dGVuZHMgVmFsaWRhdG9yXG4gKlxuICogQGNhdGVnb3J5IFZhbGlkYXRvcnNcbiAqL1xuQHZhbGlkYXRvcihVcGRhdGVWYWxpZGF0aW9uS2V5cy5USU1FU1RBTVApXG5leHBvcnQgY2xhc3MgVGltZXN0YW1wVmFsaWRhdG9yIGV4dGVuZHMgVmFsaWRhdG9yIHtcbiAgY29uc3RydWN0b3IoKSB7XG4gICAgc3VwZXIoREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5USU1FU1RBTVAuSU5WQUxJRCk7XG4gIH1cblxuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIGhhc0Vycm9ycyh2YWx1ZTogYW55LCAuLi5hcmdzOiBhbnlbXSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgfVxuXG4gIHB1YmxpYyB1cGRhdGVIYXNFcnJvcnMoXG4gICAgdmFsdWU6IERhdGUgfCBzdHJpbmcgfCBudW1iZXIsXG4gICAgb2xkVmFsdWU6IERhdGUgfCBzdHJpbmcgfCBudW1iZXIsXG4gICAgbWVzc2FnZT86IHN0cmluZ1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG5cbiAgICBtZXNzYWdlID0gbWVzc2FnZSB8fCB0aGlzLmdldE1lc3NhZ2UobWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhbHVlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgb2xkVmFsdWUgPSBuZXcgRGF0ZShvbGRWYWx1ZSk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlIDw9IG9sZFZhbHVlID8gbWVzc2FnZSA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyBhcyBEZWNvcmF0b3JNZXNzYWdlcyxcbiAgVmFsaWRhdG9yLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgQmFzZSBjbGFzcyBmb3IgYW4gVXBkYXRlIHZhbGlkYXRvclxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gZXJyb3IgbWVzc2FnZS4gZGVmYXVsdHMgdG8ge0BsaW5rIERlY29yYXRvck1lc3NhZ2VzI0RFRkFVTFR9XG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBbYWNjZXB0ZWRUeXBlc10gdGhlIGFjY2VwdGVkIHZhbHVlIHR5cGVzIGJ5IHRoZSBkZWNvcmF0b3JcbiAqXG4gKiBAY2xhc3MgVXBkYXRlVmFsaWRhdG9yXG4gKiBAYWJzdHJhY3RcbiAqIEBleHRlbmRzIFZhbGlkYXRvclxuICpcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBVcGRhdGVWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3Ige1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nID0gRGVjb3JhdG9yTWVzc2FnZXMuREVGQVVMVCxcbiAgICAuLi5hY2NlcHRlZFR5cGVzOiBzdHJpbmdbXVxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlLCAuLi5hY2NlcHRlZFR5cGVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSB2YWxpZGF0ZXMgYSB2YWx1ZSBieSBjb21wYXJpbmcgdG8gaXRzIG9sZCB2ZXJzaW9uXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZVxuICAgKiBAcGFyYW0ge2FueX0gb2xkVmFsdWVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJnc1xuICAgKi9cbiAgcHVibGljIGFic3RyYWN0IHVwZGF0ZUhhc0Vycm9ycyhcbiAgICB2YWx1ZTogYW55LFxuICAgIG9sZFZhbHVlOiBhbnksXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogc3RyaW5nIHwgdW5kZWZpbmVkO1xufVxuIiwiaW1wb3J0IHtcbiAgVmFsaWRhdG9yLFxuICBWYWxpZGF0aW9uLFxuICBWYWxpZGF0b3JEZWZpbml0aW9uLFxuICBJVmFsaWRhdG9yUmVnaXN0cnksXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IFVwZGF0ZVZhbGlkYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cblZhbGlkYXRpb24udXBkYXRlS2V5ID0gZnVuY3Rpb24gKGtleTogc3RyaW5nKSB7XG4gIHJldHVybiBVcGRhdGVWYWxpZGF0aW9uS2V5cy5SRUZMRUNUICsga2V5O1xufTtcblxuZGVjbGFyZSBtb2R1bGUgXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnRcbiAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICBkZWNsYXJlIGNsYXNzIFZhbGlkYXRpb24ge1xuICAgIHByaXZhdGUgc3RhdGljIGFjdGluZ1ZhbGlkYXRvclJlZ2lzdHJ5PztcbiAgICBwcml2YXRlIGNvbnN0cnVjdG9yKCk7XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgRGVmaW5lcyB0aGUgYWN0aW5nIFZhbGlkYXRvclJlZ2lzdHJ5XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge0lWYWxpZGF0b3JSZWdpc3RyeX0gdmFsaWRhdG9yUmVnaXN0cnkgdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiBvZiB0aGUgdmFsaWRhdG9yIFJlZ2lzdHJ5XG4gICAgICogQHBhcmFtIHtmdW5jdGlvbihWYWxpZGF0b3IpOiBWYWxpZGF0b3J9IFttaWdyYXRpb25IYW5kbGVyXSB0aGUgbWV0aG9kIHRvIG1hcCB0aGUgdmFsaWRhdG9yIGlmIHJlcXVpcmVkO1xuICAgICAqL1xuICAgIHN0YXRpYyBzZXRSZWdpc3RyeShcbiAgICAgIHZhbGlkYXRvclJlZ2lzdHJ5OiBJVmFsaWRhdG9yUmVnaXN0cnk8VmFsaWRhdG9yPixcbiAgICAgIG1pZ3JhdGlvbkhhbmRsZXI/OiAodmFsaWRhdG9yOiBWYWxpZGF0b3IpID0+IFZhbGlkYXRvclxuICAgICk6IHZvaWQ7XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgUmV0dXJucyB0aGUgY3VycmVudCBWYWxpZGF0b3JSZWdpc3RyeVxuICAgICAqXG4gICAgICogQHJldHVybiBJVmFsaWRhdG9yUmVnaXN0cnksIGRlZmF1bHRzIHRvIHtAbGluayBWYWxpZGF0b3JSZWdpc3RyeX1cbiAgICAgKi9cbiAgICBwcml2YXRlIHN0YXRpYyBnZXRSZWdpc3RyeTtcbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBSZXRyaWV2ZXMgYSB2YWxpZGF0b3JcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSB2YWxpZGF0b3JLZXkgb25lIG9mIHRoZSB7QGxpbmsgVmFsaWRhdGlvbktleXN9XG4gICAgICogQHJldHVybiB7VmFsaWRhdG9yIHwgdW5kZWZpbmVkfSB0aGUgcmVnaXN0ZXJlZCBWYWxpZGF0b3Igb3IgdW5kZWZpbmVkIGlmIHRoZXJlIGlzIG5vbm8gbWF0Y2hpbmcgdGhlIHByb3ZpZGVkIGtleVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXQ8VCBleHRlbmRzIFZhbGlkYXRvcj4odmFsaWRhdG9yS2V5OiBzdHJpbmcpOiBUIHwgdW5kZWZpbmVkO1xuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IFJlZ2lzdGVycyB0aGUgcHJvdmlkZWQgdmFsaWRhdG9ycyBvbnRvIHRoZSByZWdpc3RyeVxuICAgICAqXG4gICAgICogQHBhcmFtIHtUW10gfCBWYWxpZGF0b3JEZWZpbml0aW9uW119IHZhbGlkYXRvclxuICAgICAqL1xuICAgIHN0YXRpYyByZWdpc3RlcjxUIGV4dGVuZHMgVmFsaWRhdG9yPihcbiAgICAgIC4uLnZhbGlkYXRvcjogKFZhbGlkYXRvckRlZmluaXRpb24gfCBUKVtdXG4gICAgKTogdm9pZDtcbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBCdWlsZHMgdGhlIGtleSB0byBzdG9yZSBhcyBNZXRhZGF0YSB1bmRlciBSZWZsZWN0aW9uc1xuICAgICAqIEBkZXNjcmlwdGlvbiBjb25jYXRlbmF0ZXMge0BsaW5rIFZhbGlkYXRpb25LZXlzI1JFRkxFQ1R9IHdpdGggdGhlIHByb3ZpZGVkIGtleVxuICAgICAqXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IGtleVxuICAgICAqL1xuICAgIHN0YXRpYyBrZXkoa2V5OiBzdHJpbmcpOiBzdHJpbmc7XG5cbiAgICBzdGF0aWMgdXBkYXRlS2V5KGtleTogc3RyaW5nKTogc3RyaW5nO1xuICB9XG59XG4iLCIvKipcbiAqIEBzdW1tYXJ5IFNldCBvZiBjb25zdGFudHMgdG8gZGVmaW5lIGRiIENSVUQgb3BlcmF0aW9ucyBhbmQgdGhlaXIgZXF1aXZhbGVudCAnb24nIGFuZCAnYWZ0ZXInIHBoYXNlc1xuICogQGNvbnN0IE9wZXJhdGlvbktleXNcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuT3BlcmF0aW9uc1xuICovXG5leHBvcnQgZW51bSBPcGVyYXRpb25LZXlzIHtcbiAgUkVGTEVDVCA9IFwiZGVjYWYubW9kZWwuZGIub3BlcmF0aW9ucy5cIixcbiAgQ1JFQVRFID0gXCJjcmVhdGVcIixcbiAgUkVBRCA9IFwicmVhZFwiLFxuICBVUERBVEUgPSBcInVwZGF0ZVwiLFxuICBERUxFVEUgPSBcImRlbGV0ZVwiLFxuICBPTiA9IFwib24uXCIsXG4gIEFGVEVSID0gXCJhZnRlci5cIixcbn1cblxuZXhwb3J0IHR5cGUgQ3J1ZE9wZXJhdGlvbnMgPVxuICB8IE9wZXJhdGlvbktleXMuQ1JFQVRFXG4gIHwgT3BlcmF0aW9uS2V5cy5SRUFEXG4gIHwgT3BlcmF0aW9uS2V5cy5VUERBVEVcbiAgfCBPcGVyYXRpb25LZXlzLkRFTEVURTtcblxuZXhwb3J0IGVudW0gQnVsa0NydWRPcGVyYXRpb25LZXlzIHtcbiAgQ1JFQVRFX0FMTCA9IFwiY3JlYXRlQWxsXCIsXG4gIFJFQURfQUxMID0gXCJyZWFkQWxsXCIsXG4gIFVQREFURV9BTEwgPSBcInVwZGF0ZUFsbFwiLFxuICBERUxFVEVfQUxMID0gXCJkZWxldGVBbGxcIixcbn1cblxuZXhwb3J0IHR5cGUgQnVsa0NydWRPcGVyYXRpb25zID1cbiAgfCBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuQ1JFQVRFX0FMTFxuICB8IEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5SRUFEX0FMTFxuICB8IEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5VUERBVEVfQUxMXG4gIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzLkRFTEVURV9BTEw7XG5cbi8qKlxuICogQHN1bW1hcnkgTWFwcyBvdXQgZ3JvdXBzIG9mIENSVUQgb3BlcmF0aW9ucyBmb3IgZWFzaWVyIG1hcHBpbmcgb2YgZGVjb3JhdG9yc1xuICpcbiAqIEBjb25zdGFudCBEQk9wZXJhdGlvbnNcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuT3BlcmF0aW9uc1xuICovXG5leHBvcnQgY29uc3QgREJPcGVyYXRpb25zOiBSZWNvcmQ8c3RyaW5nLCBDcnVkT3BlcmF0aW9uc1tdPiA9IHtcbiAgQ1JFQVRFOiBbT3BlcmF0aW9uS2V5cy5DUkVBVEVdLFxuICBSRUFEOiBbT3BlcmF0aW9uS2V5cy5SRUFEXSxcbiAgVVBEQVRFOiBbT3BlcmF0aW9uS2V5cy5VUERBVEVdLFxuICBERUxFVEU6IFtPcGVyYXRpb25LZXlzLkRFTEVURV0sXG4gIENSRUFURV9VUERBVEU6IFtPcGVyYXRpb25LZXlzLkNSRUFURSwgT3BlcmF0aW9uS2V5cy5VUERBVEVdLFxuICBSRUFEX0NSRUFURTogW09wZXJhdGlvbktleXMuUkVBRCwgT3BlcmF0aW9uS2V5cy5DUkVBVEVdLFxuICBBTEw6IFtcbiAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gIF0sXG59O1xuIiwiaW1wb3J0IHsgT3BlcmF0aW9uSGFuZGxlciB9IGZyb20gXCIuL3R5cGVzXCI7XG5pbXBvcnQgeyBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBJUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL0lSZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBPcGVyYXRpb25zIH0gZnJvbSBcIi4vT3BlcmF0aW9uc1wiO1xuaW1wb3J0IHsgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnlGbGFncyB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgSG9sZHMgdGhlIHJlZ2lzdGVyZWQgb3BlcmF0aW9uIGhhbmRsZXJzXG4gKlxuICogQGNsYXNzIE9wZXJhdGlvbnNSZWdpc3RyeVxuICogQGltcGxlbWVudHMgSVJlZ2lzdHJ5PE9wZXJhdGlvbkhhbmRsZXI8YW55Pj5cbiAqXG4gKiBAc2VlIE9wZXJhdGlvbkhhbmRsZXJcbiAqXG4gKiBAY2F0ZWdvcnkgT3BlcmF0aW9uc1xuICovXG5leHBvcnQgY2xhc3MgT3BlcmF0aW9uc1JlZ2lzdHJ5IHtcbiAgcHJpdmF0ZSByZWFkb25seSBjYWNoZTogUmVjb3JkPFxuICAgIHN0cmluZyxcbiAgICBSZWNvcmQ8XG4gICAgICBzdHJpbmcgfCBzeW1ib2wsXG4gICAgICBSZWNvcmQ8c3RyaW5nLCBSZWNvcmQ8c3RyaW5nLCBPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBhbnksIGFueSwgYW55Pj4+XG4gICAgPlxuICA+ID0ge307XG5cbiAgLyoqXG4gICAqIEBzdW1tYXJ5IHJldHJpZXZlcyBhbiB7QGxpbmsgT3BlcmF0aW9uSGFuZGxlcn0gaWYgaXQgZXhpc3RzXG4gICAqIEBwYXJhbSB7c3RyaW5nfSB0YXJnZXRcbiAgICogQHBhcmFtIHtzdHJpbmd9IHByb3BLZXlcbiAgICogQHBhcmFtIHtzdHJpbmd9IG9wZXJhdGlvblxuICAgKiBAcGFyYW0gYWNjdW1cbiAgICogQHJldHVybiB7T3BlcmF0aW9uSGFuZGxlciB8IHVuZGVmaW5lZH1cbiAgICovXG4gIGdldDxcbiAgICBNIGV4dGVuZHMgTW9kZWwsXG4gICAgUiBleHRlbmRzIElSZXBvc2l0b3J5PE0sIEYsIEM+LFxuICAgIFYsXG4gICAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbiAgPihcbiAgICB0YXJnZXQ6IHN0cmluZyB8IFJlY29yZDxzdHJpbmcsIGFueT4sXG4gICAgcHJvcEtleTogc3RyaW5nLFxuICAgIG9wZXJhdGlvbjogc3RyaW5nLFxuICAgIGFjY3VtPzogT3BlcmF0aW9uSGFuZGxlcjxNLCBSLCBWLCBGLCBDPltdXG4gICk6IE9wZXJhdGlvbkhhbmRsZXI8TSwgUiwgViwgRiwgQz5bXSB8IHVuZGVmaW5lZCB7XG4gICAgYWNjdW0gPSBhY2N1bSB8fCBbXTtcbiAgICBsZXQgbmFtZTtcbiAgICB0cnkge1xuICAgICAgbmFtZSA9IHR5cGVvZiB0YXJnZXQgPT09IFwic3RyaW5nXCIgPyB0YXJnZXQgOiB0YXJnZXQuY29uc3RydWN0b3IubmFtZTtcbiAgICAgIGFjY3VtLnVuc2hpZnQoXG4gICAgICAgIC4uLk9iamVjdC52YWx1ZXModGhpcy5jYWNoZVtuYW1lXVtwcm9wS2V5XVtvcGVyYXRpb25dIHx8IFtdKVxuICAgICAgKTtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICBpZiAoXG4gICAgICAgIHR5cGVvZiB0YXJnZXQgPT09IFwic3RyaW5nXCIgfHxcbiAgICAgICAgdGFyZ2V0ID09PSBPYmplY3QucHJvdG90eXBlIHx8XG4gICAgICAgIE9iamVjdC5nZXRQcm90b3R5cGVPZih0YXJnZXQpID09PSBPYmplY3QucHJvdG90eXBlXG4gICAgICApXG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9XG5cbiAgICBsZXQgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGFyZ2V0KTtcbiAgICBpZiAocHJvdG8uY29uc3RydWN0b3IubmFtZSA9PT0gbmFtZSkgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuXG4gICAgcmV0dXJuIHRoaXMuZ2V0PE0sIFIsIFYsIEYsIEM+KHByb3RvLCBwcm9wS2V5LCBvcGVyYXRpb24sIGFjY3VtKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAc3VtbWFyeSBSZWdpc3RlcnMgYW4ge0BsaW5rIE9wZXJhdGlvbkhhbmRsZXJ9XG4gICAqIEBwYXJhbSB7T3BlcmF0aW9uSGFuZGxlcn0gaGFuZGxlclxuICAgKiBAcGFyYW0ge3N0cmluZ30gb3BlcmF0aW9uXG4gICAqIEBwYXJhbSB7e319IHRhcmdldFxuICAgKiBAcGFyYW0ge3N0cmluZyB8IHN5bWJvbH0gcHJvcEtleVxuICAgKi9cbiAgcmVnaXN0ZXI8XG4gICAgTSBleHRlbmRzIE1vZGVsLFxuICAgIFIgZXh0ZW5kcyBJUmVwb3NpdG9yeTxNLCBGLCBDPixcbiAgICBWLFxuICAgIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gICAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4gID4oXG4gICAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxNLCBSLCBWLCBGLCBDPixcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgdGFyZ2V0OiBNLFxuICAgIHByb3BLZXk6IHN0cmluZyB8IHN5bWJvbFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBuYW1lID0gdGFyZ2V0LmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgY29uc3QgaGFuZGxlck5hbWUgPSBPcGVyYXRpb25zLmdldEhhbmRsZXJOYW1lKGhhbmRsZXIpO1xuXG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdKSB0aGlzLmNhY2hlW25hbWVdID0ge307XG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldKSB0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldID0ge307XG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldW29wZXJhdGlvbl0pXG4gICAgICB0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldW29wZXJhdGlvbl0gPSB7fTtcbiAgICBpZiAodGhpcy5jYWNoZVtuYW1lXVtwcm9wS2V5XVtvcGVyYXRpb25dW2hhbmRsZXJOYW1lXSkgcmV0dXJuO1xuICAgIHRoaXMuY2FjaGVbbmFtZV1bcHJvcEtleV1bb3BlcmF0aW9uXVtoYW5kbGVyTmFtZV0gPSBoYW5kbGVyO1xuICB9XG59XG4iLCJpbXBvcnQgeyBIYXNoaW5nLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IE9wZXJhdGlvbkhhbmRsZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgT3BlcmF0aW9uc1JlZ2lzdHJ5IH0gZnJvbSBcIi4vT3BlcmF0aW9uc1JlZ2lzdHJ5XCI7XG5pbXBvcnQgeyBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBJUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnlGbGFncyB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L3R5cGVzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgU3RhdGljIGNsYXNzIGhvbGRpbmcgY29tbW9uIE9wZXJhdGlvbiBGdW5jdGlvbmFsaXR5XG4gKlxuICogQGNsYXNzIE9wZXJhdGlvbnNcbiAqXG4gKiBAY2F0ZWdvcnkgT3BlcmF0aW9uc1xuICovXG5leHBvcnQgY2xhc3MgT3BlcmF0aW9ucyB7XG4gIHByaXZhdGUgc3RhdGljIHJlZ2lzdHJ5OiBPcGVyYXRpb25zUmVnaXN0cnk7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgc3RhdGljIGdldEhhbmRsZXJOYW1lKGhhbmRsZXI6IE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIGFueSwgYW55LCBhbnk+KSB7XG4gICAgaWYgKGhhbmRsZXIubmFtZSkgcmV0dXJuIGhhbmRsZXIubmFtZTtcblxuICAgIGNvbnNvbGUud2FybihcbiAgICAgIFwiSGFuZGxlciBuYW1lIG5vdCBkZWZpbmVkLiBBIG5hbWUgd2lsbCBiZSBnZW5lcmF0ZWQsIGJ1dCB0aGlzIGlzIG5vdCBkZXNpcmFibGUuIHBsZWFzZSBhdm9pZCB1c2luZyBhbm9ueW1vdXMgZnVuY3Rpb25zXCJcbiAgICApO1xuICAgIHJldHVybiBIYXNoaW5nLmhhc2goaGFuZGxlci50b1N0cmluZygpKTtcbiAgfVxuXG4gIHN0YXRpYyBrZXkoc3RyOiBzdHJpbmcpIHtcbiAgICByZXR1cm4gT3BlcmF0aW9uS2V5cy5SRUZMRUNUICsgc3RyO1xuICB9XG5cbiAgc3RhdGljIGdldDxcbiAgICBNIGV4dGVuZHMgTW9kZWwsXG4gICAgUiBleHRlbmRzIElSZXBvc2l0b3J5PE0sIEYsIEM+LFxuICAgIFYgPSBvYmplY3QsXG4gICAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4gID4oXG4gICAgdGFyZ2V0TmFtZTogc3RyaW5nIHwgUmVjb3JkPHN0cmluZywgYW55PixcbiAgICBwcm9wS2V5OiBzdHJpbmcsXG4gICAgb3BlcmF0aW9uOiBzdHJpbmdcbiAgKSB7XG4gICAgcmV0dXJuIE9wZXJhdGlvbnMucmVnaXN0cnkuZ2V0PE0sIFIsIFYsIEYsIEM+KFxuICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgIHByb3BLZXksXG4gICAgICBvcGVyYXRpb25cbiAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0T3BSZWdpc3RyeSgpIHtcbiAgICBpZiAoIU9wZXJhdGlvbnMucmVnaXN0cnkpIE9wZXJhdGlvbnMucmVnaXN0cnkgPSBuZXcgT3BlcmF0aW9uc1JlZ2lzdHJ5KCk7XG4gICAgcmV0dXJuIE9wZXJhdGlvbnMucmVnaXN0cnk7XG4gIH1cblxuICBzdGF0aWMgcmVnaXN0ZXI8ViBleHRlbmRzIE1vZGVsPihcbiAgICBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPFYsIGFueSwgYW55PixcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgdGFyZ2V0OiBWLFxuICAgIHByb3BLZXk6IHN0cmluZyB8IHN5bWJvbFxuICApIHtcbiAgICBPcGVyYXRpb25zLmdldE9wUmVnaXN0cnkoKS5yZWdpc3RlcihcbiAgICAgIGhhbmRsZXIgYXMgYW55LFxuICAgICAgb3BlcmF0aW9uLFxuICAgICAgdGFyZ2V0LFxuICAgICAgcHJvcEtleVxuICAgICk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIElkT3BlcmF0aW9uSGFuZGxlcixcbiAgT3BlcmF0aW9uSGFuZGxlcixcbiAgU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyLFxuICBVcGRhdGVPcGVyYXRpb25IYW5kbGVyLFxufSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgREJPcGVyYXRpb25zLCBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBPcGVyYXRpb25zIH0gZnJvbSBcIi4vT3BlcmF0aW9uc1wiO1xuaW1wb3J0IHsgYXBwbHkgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IHByb3BNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuZnVuY3Rpb24gaGFuZGxlKFxuICBvcDogT3BlcmF0aW9uS2V5cyxcbiAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT5cbikge1xuICByZXR1cm4gKHRhcmdldDogYW55LCBwcm9wZXJ0eUtleTogc3RyaW5nKSA9PiB7XG4gICAgT3BlcmF0aW9ucy5yZWdpc3RlcihoYW5kbGVyLCBvcCwgdGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gIH07XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgb24gdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5DUkVBVEVfVVBEQVRFfVxuICpcbiAqIEBwYXJhbSB7T25PcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIEFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIGluIG9yZGVyIHRvIHRoZSBoYW5kbGVyIG1ldGhvZFxuICpcbiAqIEBzZWUgb25cbiAqXG4gKiBAZnVuY3Rpb24gb25DcmVhdGVVcGRhdGVcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25DcmVhdGVVcGRhdGU8ViA9IG9iamVjdD4oXG4gIGhhbmRsZXI6XG4gICAgfCBTdGFuZGFyZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55PlxuICAgIHwgVXBkYXRlT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+LFxuICBkYXRhPzogVlxuKSB7XG4gIHJldHVybiBvbihEQk9wZXJhdGlvbnMuQ1JFQVRFX1VQREFURSwgaGFuZGxlciwgZGF0YSk7XG59XG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvdXIgdG8gc2V0IG9uIHRoZSBkZWZpbmVkIHtAbGluayBEQk9wZXJhdGlvbnMuVVBEQVRFfVxuICpcbiAqIEBwYXJhbSB7T25PcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIEFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIGluIG9yZGVyIHRvIHRoZSBoYW5kbGVyIG1ldGhvZFxuICpcbiAqIEBzZWUgb25cbiAqXG4gKiBAZnVuY3Rpb24gb25VcGRhdGVcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25VcGRhdGU8ViA9IG9iamVjdD4oXG4gIGhhbmRsZXI6IFVwZGF0ZU9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueT4sXG4gIGRhdGE/OiBWXG4pIHtcbiAgcmV0dXJuIG9uKERCT3BlcmF0aW9ucy5VUERBVEUsIGhhbmRsZXIsIGRhdGEpO1xufVxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3VyIHRvIHNldCBvbiB0aGUgZGVmaW5lZCB7QGxpbmsgREJPcGVyYXRpb25zLkNSRUFURX1cbiAqXG4gKiBAcGFyYW0ge09uT3BlcmF0aW9uSGFuZGxlcjxhbnk+fSBoYW5kbGVyIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIGRhdGFcbiAqXG4gKiBAc2VlIG9uXG4gKlxuICogQGZ1bmN0aW9uIG9uQ3JlYXRlXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQ3JlYXRlPFYgPSBvYmplY3Q+KFxuICBoYW5kbGVyOiBTdGFuZGFyZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55PixcbiAgZGF0YT86IFZcbikge1xuICByZXR1cm4gb24oREJPcGVyYXRpb25zLkNSRUFURSwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgb24gdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5SRUFEfVxuICpcbiAqIEBwYXJhbSB7T25PcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICpcbiAqIEBzZWUgb25cbiAqXG4gKiBAZnVuY3Rpb24gb25SZWFkXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uUmVhZDxWID0gb2JqZWN0PihcbiAgaGFuZGxlcjogSWRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE6IFZcbikge1xuICByZXR1cm4gb24oREJPcGVyYXRpb25zLlJFQUQsIGhhbmRsZXIsIGRhdGEpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvdXIgdG8gc2V0IG9uIHRoZSBkZWZpbmVkIHtAbGluayBEQk9wZXJhdGlvbnMuREVMRVRFfVxuICpcbiAqIEBwYXJhbSB7T25PcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICpcbiAqIEBzZWUgb25cbiAqXG4gKiBAZnVuY3Rpb24gb25EZWxldGVcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25EZWxldGU8ViA9IG9iamVjdD4oXG4gIGhhbmRsZXI6IE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55PixcbiAgZGF0YTogVlxuKSB7XG4gIHJldHVybiBvbihEQk9wZXJhdGlvbnMuREVMRVRFLCBoYW5kbGVyLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3VyIHRvIHNldCBvbiB0aGUgZGVmaW5lZCB7QGxpbmsgREJPcGVyYXRpb25zLkRFTEVURX1cbiAqXG4gKiBAcGFyYW0ge09uT3BlcmF0aW9uSGFuZGxlcjxhbnk+fSBoYW5kbGVyIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIGRhdGFcbiAqXG4gKiBAc2VlIG9uXG4gKlxuICogQGZ1bmN0aW9uIG9uQW55XG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQW55PFYgPSBvYmplY3Q+KFxuICBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE6IFZcbikge1xuICByZXR1cm4gb24oREJPcGVyYXRpb25zLkFMTCwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgb24gdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9uc31cbiAqXG4gKiBAcGFyYW0ge09wZXJhdGlvbktleXNbXSB8IERCT3BlcmF0aW9uc30gb3AgT25lIG9mIHtAbGluayBEQk9wZXJhdGlvbnN9XG4gKiBAcGFyYW0ge09uT3BlcmF0aW9uSGFuZGxlcjxhbnk+fSBoYW5kbGVyIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIGRhdGFcbiAqXG4gKiBleDogaGFuZGxlciguLi5hcmdzLCAuLi5wcm9wcy5tYXAocCA9PiB0YXJnZXRbcF0pKVxuICpcbiAqIEBmdW5jdGlvbiBvblxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbjxWID0gb2JqZWN0PihcbiAgb3A6IE9wZXJhdGlvbktleXNbXSA9IERCT3BlcmF0aW9ucy5BTEwsXG4gIGhhbmRsZXI6IE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55PixcbiAgZGF0YT86IFZcbikge1xuICByZXR1cm4gb3BlcmF0aW9uKE9wZXJhdGlvbktleXMuT04sIG9wLCBoYW5kbGVyLCBkYXRhKTtcbn1cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgYWZ0ZXIgdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5DUkVBVEVfVVBEQVRFfVxuICpcbiAqIEBwYXJhbSB7QWZ0ZXJPcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICpcbiAqIEBzZWUgYWZ0ZXJcbiAqXG4gKiBAZnVuY3Rpb24gYWZ0ZXJDcmVhdGVVcGRhdGVcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWZ0ZXJDcmVhdGVVcGRhdGU8ViA9IG9iamVjdD4oXG4gIGhhbmRsZXI6XG4gICAgfCBTdGFuZGFyZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55PlxuICAgIHwgVXBkYXRlT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+LFxuICBkYXRhOiBWXG4pIHtcbiAgcmV0dXJuIGFmdGVyKERCT3BlcmF0aW9ucy5DUkVBVEVfVVBEQVRFLCBoYW5kbGVyLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3VyIHRvIHNldCBhZnRlciB0aGUgZGVmaW5lZCB7QGxpbmsgREJPcGVyYXRpb25zLlVQREFURX1cbiAqXG4gKiBAcGFyYW0ge0FmdGVyT3BlcmF0aW9uSGFuZGxlcjxhbnk+fSBoYW5kbGVyIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIGRhdGFcbiAqXG4gKiBAc2VlIGFmdGVyXG4gKlxuICogQGZ1bmN0aW9uIGFmdGVyVXBkYXRlXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFmdGVyVXBkYXRlPFYgPSBvYmplY3Q+KFxuICBoYW5kbGVyOiBVcGRhdGVPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE6IFZcbikge1xuICByZXR1cm4gYWZ0ZXIoREJPcGVyYXRpb25zLlVQREFURSwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgYWZ0ZXIgdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5DUkVBVEV9XG4gKlxuICogQHBhcmFtIHtBZnRlck9wZXJhdGlvbkhhbmRsZXI8YW55Pn0gaGFuZGxlciBUaGUgbWV0aG9kIGNhbGxlZCB1cG9uIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSBkYXRhXG4gKlxuICogQHNlZSBhZnRlclxuICpcbiAqIEBmdW5jdGlvbiBhZnRlckNyZWF0ZVxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlckNyZWF0ZTxWID0gb2JqZWN0PihcbiAgaGFuZGxlcjogU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE6IFZcbikge1xuICByZXR1cm4gYWZ0ZXIoREJPcGVyYXRpb25zLkNSRUFURSwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgYWZ0ZXIgdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5SRUFEfVxuICpcbiAqIEBwYXJhbSB7QWZ0ZXJPcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIEFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIGluIG9yZGVyIHRvIHRoZSBoYW5kbGVyIG1ldGhvZFxuICpcbiAqIEBzZWUgYWZ0ZXJcbiAqXG4gKiBAZnVuY3Rpb24gYWZ0ZXJSZWFkXG4gKlxuICogQGNhdGVnb3J5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFmdGVyUmVhZDxWID0gb2JqZWN0PihcbiAgaGFuZGxlcjogU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE/OiBWXG4pIHtcbiAgcmV0dXJuIGFmdGVyKERCT3BlcmF0aW9ucy5SRUFELCBoYW5kbGVyLCBkYXRhKTtcbn1cbi8qKlxuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW91ciB0byBzZXQgYWZ0ZXIgdGhlIGRlZmluZWQge0BsaW5rIERCT3BlcmF0aW9ucy5ERUxFVEV9XG4gKlxuICogQHBhcmFtIHtBZnRlck9wZXJhdGlvbkhhbmRsZXI8YW55Pn0gaGFuZGxlciBUaGUgbWV0aG9kIGNhbGxlZCB1cG9uIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSBkYXRhXG4gKiBAcGFyYW0ge2FueVtdfSBbYXJnc10gQXJndW1lbnRzIHRoYXQgd2lsbCBiZSBwYXNzZWQgaW4gb3JkZXIgdG8gdGhlIGhhbmRsZXIgbWV0aG9kXG4gKlxuICogQHNlZSBhZnRlclxuICpcbiAqIEBmdW5jdGlvbiBhZnRlckRlbGV0ZVxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlckRlbGV0ZTxWID0gb2JqZWN0PihcbiAgaGFuZGxlcjogU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE/OiBWXG4pIHtcbiAgcmV0dXJuIGFmdGVyKERCT3BlcmF0aW9ucy5ERUxFVEUsIGhhbmRsZXIsIGRhdGEpO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvdXIgdG8gc2V0IGFmdGVyIHRoZSBkZWZpbmVkIHtAbGluayBEQk9wZXJhdGlvbnMuREVMRVRFfVxuICpcbiAqIEBwYXJhbSB7QWZ0ZXJPcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIHthbnlbXX0gW2FyZ3NdIEFyZ3VtZW50cyB0aGF0IHdpbGwgYmUgcGFzc2VkIGluIG9yZGVyIHRvIHRoZSBoYW5kbGVyIG1ldGhvZFxuICpcbiAqIEBzZWUgYWZ0ZXJcbiAqXG4gKiBAZnVuY3Rpb24gYWZ0ZXJBbnlcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWZ0ZXJBbnk8ViA9IG9iamVjdD4oXG4gIGhhbmRsZXI6IFN0YW5kYXJkT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+LFxuICBkYXRhPzogVlxuKSB7XG4gIHJldHVybiBhZnRlcihEQk9wZXJhdGlvbnMuQUxMLCBoYW5kbGVyLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3VyIHRvIHNldCBvbiB0aGUgZGVmaW5lZCB7QGxpbmsgREJPcGVyYXRpb25zfVxuICpcbiAqIEBwYXJhbSB7T3BlcmF0aW9uS2V5c1tdIHwgREJPcGVyYXRpb25zfSBvcCBPbmUgb2Yge0BsaW5rIERCT3BlcmF0aW9uc31cbiAqIEBwYXJhbSB7QWZ0ZXJPcGVyYXRpb25IYW5kbGVyPGFueT59IGhhbmRsZXIgVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKlxuICogZXg6IGhhbmRsZXIoLi4uYXJncywgLi4ucHJvcHMubWFwKHAgPT4gdGFyZ2V0W3BdKSlcbiAqXG4gKiBAcGFyYW0gZGF0YVxuICogQHBhcmFtIGFyZ3NcbiAqIEBmdW5jdGlvbiBhZnRlclxuICpcbiAqIEBjYXRlZ29yeSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlcjxWID0gb2JqZWN0PihcbiAgb3A6IE9wZXJhdGlvbktleXNbXSA9IERCT3BlcmF0aW9ucy5BTEwsXG4gIGhhbmRsZXI6IE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55PixcbiAgZGF0YT86IFZcbikge1xuICByZXR1cm4gb3BlcmF0aW9uKE9wZXJhdGlvbktleXMuQUZURVIsIG9wLCBoYW5kbGVyLCBkYXRhKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIG9wZXJhdGlvbjxWID0gb2JqZWN0PihcbiAgYmFzZU9wOiBPcGVyYXRpb25LZXlzLk9OIHwgT3BlcmF0aW9uS2V5cy5BRlRFUixcbiAgb3BlcmF0aW9uOiBPcGVyYXRpb25LZXlzW10gPSBEQk9wZXJhdGlvbnMuQUxMLFxuICBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGFUb0FkZD86IFZcbikge1xuICByZXR1cm4gKHRhcmdldDogb2JqZWN0LCBwcm9wZXJ0eUtleT86IGFueSkgPT4ge1xuICAgIGNvbnN0IG5hbWUgPSB0YXJnZXQuY29uc3RydWN0b3IubmFtZTtcbiAgICBjb25zdCBkZWNvcmF0b3JzID0gb3BlcmF0aW9uLnJlZHVjZSgoYWNjdW06IGFueVtdLCBvcCkgPT4ge1xuICAgICAgY29uc3QgY29tcG91bmRLZXkgPSBiYXNlT3AgKyBvcDtcbiAgICAgIGxldCBkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgT3BlcmF0aW9ucy5rZXkoY29tcG91bmRLZXkpLFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgIHByb3BlcnR5S2V5XG4gICAgICApO1xuICAgICAgaWYgKCFkYXRhKVxuICAgICAgICBkYXRhID0ge1xuICAgICAgICAgIG9wZXJhdGlvbjogb3AsXG4gICAgICAgICAgaGFuZGxlcnM6IHt9LFxuICAgICAgICB9O1xuXG4gICAgICBjb25zdCBoYW5kbGVyS2V5ID0gT3BlcmF0aW9ucy5nZXRIYW5kbGVyTmFtZShoYW5kbGVyKTtcblxuICAgICAgaWYgKFxuICAgICAgICAhZGF0YS5oYW5kbGVyc1tuYW1lXSB8fFxuICAgICAgICAhZGF0YS5oYW5kbGVyc1tuYW1lXVtwcm9wZXJ0eUtleV0gfHxcbiAgICAgICAgIShoYW5kbGVyS2V5IGluIGRhdGEuaGFuZGxlcnNbbmFtZV1bcHJvcGVydHlLZXldKVxuICAgICAgKSB7XG4gICAgICAgIGRhdGEuaGFuZGxlcnNbbmFtZV0gPSBkYXRhLmhhbmRsZXJzW25hbWVdIHx8IHt9O1xuICAgICAgICBkYXRhLmhhbmRsZXJzW25hbWVdW3Byb3BlcnR5S2V5XSA9XG4gICAgICAgICAgZGF0YS5oYW5kbGVyc1tuYW1lXVtwcm9wZXJ0eUtleV0gfHwge307XG4gICAgICAgIGRhdGEuaGFuZGxlcnNbbmFtZV1bcHJvcGVydHlLZXldW2hhbmRsZXJLZXldID0ge1xuICAgICAgICAgIGRhdGE6IGRhdGFUb0FkZCxcbiAgICAgICAgfTtcblxuICAgICAgICBhY2N1bS5wdXNoKFxuICAgICAgICAgIGhhbmRsZShjb21wb3VuZEtleSBhcyBPcGVyYXRpb25LZXlzLCBoYW5kbGVyKSxcbiAgICAgICAgICBwcm9wTWV0YWRhdGEoT3BlcmF0aW9ucy5rZXkoY29tcG91bmRLZXkpLCBkYXRhKVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sIFtdKTtcbiAgICByZXR1cm4gYXBwbHkoLi4uZGVjb3JhdG9ycykodGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gIH07XG59XG4iLCIvKipcbiAqIEBzdW1tYXJ5IEJhc2UgRXJyb3JcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbXNnIHRoZSBlcnJvciBtZXNzYWdlXG4gKlxuICogQGNsYXNzIEJhc2VETFRFcnJvclxuICogQGV4dGVuZHMgRXJyb3JcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VFcnJvciBleHRlbmRzIEVycm9yIHtcbiAgcmVhZG9ubHkgY29kZSE6IG51bWJlcjtcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKG5hbWU6IHN0cmluZywgbXNnOiBzdHJpbmcgfCBFcnJvciwgY29kZTogbnVtYmVyID0gNTAwKSB7XG4gICAgaWYgKG1zZyBpbnN0YW5jZW9mIEJhc2VFcnJvcikgcmV0dXJuIG1zZztcbiAgICBjb25zdCBtZXNzYWdlID0gYFske25hbWV9XSAke21zZyBpbnN0YW5jZW9mIEVycm9yID8gbXNnLm1lc3NhZ2UgOiBtc2d9YDtcbiAgICBzdXBlcihtZXNzYWdlKTtcbiAgICB0aGlzLmNvZGUgPSBjb2RlO1xuICAgIGlmIChtc2cgaW5zdGFuY2VvZiBFcnJvcikgdGhpcy5zdGFjayA9IG1zZy5zdGFjaztcbiAgfVxufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBmYWlsdXJlIGluIHRoZSBNb2RlbCBkZXRhaWxzXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1zZyB0aGUgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjbGFzcyBWYWxpZGF0aW9uRXJyb3JcbiAqIEBleHRlbmRzIEJhc2VFcnJvclxuICovXG5leHBvcnQgY2xhc3MgVmFsaWRhdGlvbkVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKFZhbGlkYXRpb25FcnJvci5uYW1lLCBtc2csIDQyMik7XG4gIH1cbn1cbi8qKlxuICogQHN1bW1hcnkgUmVwcmVzZW50cyBhbiBpbnRlcm5hbCBmYWlsdXJlIChzaG91bGQgbWVhbiBhbiBlcnJvciBpbiBjb2RlKVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtc2cgdGhlIGVycm9yIG1lc3NhZ2VcbiAqXG4gKiBAY2xhc3MgSW50ZXJuYWxFcnJvclxuICogQGV4dGVuZHMgQmFzZUVycm9yXG4gKi9cbmV4cG9ydCBjbGFzcyBJbnRlcm5hbEVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKEludGVybmFsRXJyb3IubmFtZSwgbXNnLCA1MDApO1xuICB9XG59XG4vKipcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBmYWlsdXJlIGluIHRoZSBNb2RlbCBkZS9zZXJpYWxpemF0aW9uXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1zZyB0aGUgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjbGFzcyBTZXJpYWxpemF0aW9uRXJyb3JcbiAqIEBleHRlbmRzIEJhc2VFcnJvclxuICpcbiAqL1xuZXhwb3J0IGNsYXNzIFNlcmlhbGl6YXRpb25FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihTZXJpYWxpemF0aW9uRXJyb3IubmFtZSwgbXNnLCA0MjIpO1xuICB9XG59XG5cbi8qKlxuICogQHN1bW1hcnkgUmVwcmVzZW50cyBhIGZhaWx1cmUgaW4gZmluZGluZyBhIG1vZGVsXG4gKlxuICogQHBhcmFtIHtzdHJpbmd9IG1zZyB0aGUgZXJyb3IgbWVzc2FnZVxuICpcbiAqIEBjbGFzcyBOb3RGb3VuZEVycm9yXG4gKiBAZXh0ZW5kcyBCYXNlRXJyb3JcbiAqXG4gKi9cbmV4cG9ydCBjbGFzcyBOb3RGb3VuZEVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKE5vdEZvdW5kRXJyb3IubmFtZSwgbXNnLCA0MDQpO1xuICB9XG59XG4vKipcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBjb25mbGljdCBpbiB0aGUgc3RvcmFnZVxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBtc2cgdGhlIGVycm9yIG1lc3NhZ2VcbiAqXG4gKiBAY2xhc3MgQ29uZmxpY3RFcnJvclxuICogQGV4dGVuZHMgQmFzZUVycm9yXG4gKlxuICovXG5leHBvcnQgY2xhc3MgQ29uZmxpY3RFcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihDb25mbGljdEVycm9yLm5hbWUsIG1zZywgNDA5KTtcbiAgfVxufVxuIiwiaW1wb3J0IHsgT3BlcmF0aW9ucyB9IGZyb20gXCIuLi9vcGVyYXRpb25zL09wZXJhdGlvbnNcIjtcbmltcG9ydCB7IE9wZXJhdGlvbkhhbmRsZXIsIFVwZGF0ZU9wZXJhdGlvbkhhbmRsZXIgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy90eXBlc1wiO1xuaW1wb3J0IHsgSVJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9JUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgRGVjb3JhdG9yTWV0YWRhdGEsIFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCwgTW9kZWxLZXlzIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuL0NvbnRleHRcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnlGbGFncyB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCB0eXBlIENvbnRleHRBcmdzPFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzID0gUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4+ID0ge1xuICBjb250ZXh0OiBDO1xuICBhcmdzOiBhbnlbXTtcbn07XG5cbi8qKlxuICogQHN1bW1hcnkgcmV0cmlldmVzIHRoZSBhcmd1bWVudHMgZm9yIHRoZSBoYW5kbGVyXG4gKiBAcGFyYW0ge2FueX0gZGVjIHRoZSBkZWNvcmF0b3JcbiAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wIHRoZSBwcm9wZXJ0eSBuYW1lXG4gKiBAcGFyYW0ge3t9fSBtIHRoZSBtb2RlbFxuICogQHBhcmFtIHt7fX0gW2FjY3VtXSBhY2N1bXVsYXRvciB1c2VkIGZvciBpbnRlcm5hbCByZWN1cnNpdmVuZXNzXG4gKlxuICogQGZ1bmN0aW9uIGdldEhhbmRsZXJBcmdzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuUmVwb3NpdG9yeVxuICovXG5leHBvcnQgY29uc3QgZ2V0SGFuZGxlckFyZ3MgPSBmdW5jdGlvbiAoXG4gIGRlYzogYW55LFxuICBwcm9wOiBzdHJpbmcsXG4gIG06IENvbnN0cnVjdG9yPGFueT4sXG4gIGFjY3VtPzogUmVjb3JkPHN0cmluZywgeyBhcmdzOiBzdHJpbmdbXSB9PlxuKTogUmVjb3JkPHN0cmluZywgeyBhcmdzOiBzdHJpbmdbXSB9PiB8IHZvaWQge1xuICBjb25zdCBuYW1lID0gbS5jb25zdHJ1Y3Rvci5uYW1lO1xuICBpZiAoIW5hbWUpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiQ291bGQgbm90IGRldGVybWluZSBtb2RlbCBjbGFzc1wiKTtcbiAgYWNjdW0gPSBhY2N1bSB8fCB7fTtcblxuICBpZiAoZGVjLnByb3BzLmhhbmRsZXJzW25hbWVdICYmIGRlYy5wcm9wcy5oYW5kbGVyc1tuYW1lXVtwcm9wXSlcbiAgICBhY2N1bSA9IHsgLi4uZGVjLnByb3BzLmhhbmRsZXJzW25hbWVdW3Byb3BdLCAuLi5hY2N1bSB9O1xuXG4gIGxldCBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihtKTtcbiAgaWYgKHByb3RvID09PSBPYmplY3QucHJvdG90eXBlKSByZXR1cm4gYWNjdW07XG4gIGlmIChwcm90by5jb25zdHJ1Y3Rvci5uYW1lID09PSBuYW1lKSBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90byk7XG5cbiAgcmV0dXJuIGdldEhhbmRsZXJBcmdzKGRlYywgcHJvcCwgcHJvdG8sIGFjY3VtKTtcbn07XG5cbi8qKlxuICpcbiAqIEBwYXJhbSB7SVJlcG9zaXRvcnk8VD59IHJlcG9cbiAqIEBwYXJhbSBjb250ZXh0XG4gKiBAcGFyYW0ge1R9IG1vZGVsXG4gKiBAcGFyYW0gb3BlcmF0aW9uXG4gKiBAcGFyYW0gcHJlZml4XG4gKlxuICogQHBhcmFtIG9sZE1vZGVsXG4gKiBAZnVuY3Rpb24gZW5mb3JjZURCUHJvcGVydHlEZWNvcmF0b3JzQXN5bmNcbiAqXG4gKiBAbWVtYmVyT2YgZGItZGVjb3JhdG9ycy51dGlsc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZW5mb3JjZURCRGVjb3JhdG9yczxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBvYmplY3QgPSBvYmplY3QsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4oXG4gIHJlcG86IFIsXG4gIGNvbnRleHQ6IEMsXG4gIG1vZGVsOiBNLFxuICBvcGVyYXRpb246IHN0cmluZyxcbiAgcHJlZml4OiBzdHJpbmcsXG4gIG9sZE1vZGVsPzogTVxuKTogUHJvbWlzZTx2b2lkPiB7XG4gIGNvbnN0IGRlY29yYXRvcnM6IFJlY29yZDxzdHJpbmcsIERlY29yYXRvck1ldGFkYXRhW10+IHwgdW5kZWZpbmVkID1cbiAgICBnZXREYkRlY29yYXRvcnMobW9kZWwsIG9wZXJhdGlvbiwgcHJlZml4KTtcblxuICBpZiAoIWRlY29yYXRvcnMpIHJldHVybjtcblxuICBmb3IgKGNvbnN0IHByb3AgaW4gZGVjb3JhdG9ycykge1xuICAgIGNvbnN0IGRlY3M6IERlY29yYXRvck1ldGFkYXRhW10gPSBkZWNvcmF0b3JzW3Byb3BdO1xuICAgIGZvciAoY29uc3QgZGVjIG9mIGRlY3MpIHtcbiAgICAgIGNvbnN0IHsga2V5IH0gPSBkZWM7XG4gICAgICBjb25zdCBoYW5kbGVyczogT3BlcmF0aW9uSGFuZGxlcjxNLCBSLCBWLCBGLCBDPltdIHwgdW5kZWZpbmVkID1cbiAgICAgICAgT3BlcmF0aW9ucy5nZXQ8TSwgUiwgViwgRiwgQz4obW9kZWwsIHByb3AsIHByZWZpeCArIGtleSk7XG4gICAgICBpZiAoIWhhbmRsZXJzIHx8ICFoYW5kbGVycy5sZW5ndGgpXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgIGBDb3VsZCBub3QgZmluZCByZWdpc3RlcmVkIGhhbmRsZXIgZm9yIHRoZSBvcGVyYXRpb24gJHtwcmVmaXggKyBrZXl9IHVuZGVyIHByb3BlcnR5ICR7cHJvcH1gXG4gICAgICAgICk7XG5cbiAgICAgIGNvbnN0IGhhbmRsZXJBcmdzID0gZ2V0SGFuZGxlckFyZ3MoZGVjLCBwcm9wLCBtb2RlbCBhcyBhbnkpO1xuXG4gICAgICBpZiAoIWhhbmRsZXJBcmdzIHx8IE9iamVjdC52YWx1ZXMoaGFuZGxlckFyZ3MpLmxlbmd0aCAhPT0gaGFuZGxlcnMubGVuZ3RoKVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkFyZ3MgYW5kIGhhbmRsZXJzIGxlbmd0aCBkbyBub3QgbWF0Y2hcIik7XG5cbiAgICAgIGxldCBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPE0sIFIsIFYsIEYsIEM+O1xuICAgICAgbGV0IGRhdGE6IGFueTtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaGFuZGxlcnMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgaGFuZGxlciA9IGhhbmRsZXJzW2ldO1xuICAgICAgICBkYXRhID0gT2JqZWN0LnZhbHVlcyhoYW5kbGVyQXJncylbaV07XG5cbiAgICAgICAgY29uc3QgYXJnczogYW55W10gPSBbY29udGV4dCwgZGF0YS5kYXRhLCBwcm9wLCBtb2RlbF07XG5cbiAgICAgICAgaWYgKG9wZXJhdGlvbiA9PT0gT3BlcmF0aW9uS2V5cy5VUERBVEUgJiYgcHJlZml4ID09PSBPcGVyYXRpb25LZXlzLk9OKSB7XG4gICAgICAgICAgaWYgKCFvbGRNb2RlbClcbiAgICAgICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzc2luZyBvbGQgbW9kZWwgZm9yIHVwZGF0ZSBvcGVyYXRpb25cIik7XG4gICAgICAgICAgYXJncy5wdXNoKG9sZE1vZGVsKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIGF3YWl0IChoYW5kbGVyIGFzIFVwZGF0ZU9wZXJhdGlvbkhhbmRsZXI8TSwgUiwgViwgRiwgQz4pLmFwcGx5KFxuICAgICAgICAgICAgcmVwbyxcbiAgICAgICAgICAgIGFyZ3MgYXMgW0MsIFYsIGtleW9mIE0sIE0sIE1dXG4gICAgICAgICAgKTtcbiAgICAgICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgICAgIGNvbnN0IG1zZyA9IGBGYWlsZWQgdG8gZXhlY3V0ZSBoYW5kbGVyICR7aGFuZGxlci5uYW1lfSBmb3IgJHtwcm9wfSBvbiAke21vZGVsLmNvbnN0cnVjdG9yLm5hbWV9IGR1ZSB0byBlcnJvcjogJHtlfWA7XG4gICAgICAgICAgaWYgKGNvbnRleHQuZ2V0KFwiYnJlYWtPbkhhbmRsZXJFcnJvclwiKSkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IobXNnKTtcbiAgICAgICAgICBjb25zb2xlLmxvZyhtc2cpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8qKlxuICogU3BlY2lmaWMgZm9yIERCIERlY29yYXRvcnNcbiAqIEBwYXJhbSB7VH0gbW9kZWxcbiAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRpb24gQ1JVRCB7QGxpbmsgT3BlcmF0aW9uS2V5c31cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZXh0cmFQcmVmaXhdXG4gKlxuICogQGZ1bmN0aW9uIGdldERiUHJvcGVydHlEZWNvcmF0b3JzXG4gKlxuICogQG1lbWJlck9mIGRiLWRlY29yYXRvcnMudXRpbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldERiRGVjb3JhdG9yczxUIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogVCxcbiAgb3BlcmF0aW9uOiBzdHJpbmcsXG4gIGV4dHJhUHJlZml4Pzogc3RyaW5nXG4pOiBSZWNvcmQ8c3RyaW5nLCBEZWNvcmF0b3JNZXRhZGF0YVtdPiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGRlY29yYXRvcnM6IFJlY29yZDxzdHJpbmcsIERlY29yYXRvck1ldGFkYXRhW10+IHwgdW5kZWZpbmVkID1cbiAgICBSZWZsZWN0aW9uLmdldEFsbFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgIG1vZGVsLFxuICAgICAgLy8gdW5kZWZpbmVkLFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUZMRUNUICsgKGV4dHJhUHJlZml4ID8gZXh0cmFQcmVmaXggOiBcIlwiKVxuICAgICk7XG4gIGlmICghZGVjb3JhdG9ycykgcmV0dXJuO1xuICByZXR1cm4gT2JqZWN0LmtleXMoZGVjb3JhdG9ycykucmVkdWNlKFxuICAgIChhY2N1bTogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGFbXT4gfCB1bmRlZmluZWQsIGRlY29yYXRvcikgPT4ge1xuICAgICAgY29uc3QgZGVjID0gZGVjb3JhdG9yc1tkZWNvcmF0b3JdLmZpbHRlcigoZCkgPT4gZC5rZXkgPT09IG9wZXJhdGlvbik7XG4gICAgICBpZiAoZGVjICYmIGRlYy5sZW5ndGgpIHtcbiAgICAgICAgaWYgKCFhY2N1bSkgYWNjdW0gPSB7fTtcbiAgICAgICAgYWNjdW1bZGVjb3JhdG9yXSA9IGRlYztcbiAgICAgIH1cbiAgICAgIHJldHVybiBhY2N1bTtcbiAgICB9LFxuICAgIHVuZGVmaW5lZFxuICApO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgZGVjb3JhdG9ycyBmb3IgYW4gb2JqZWN0J3MgcHJvcGVydGllcyBwcmVmaXhlZCBieSB7QHBhcmFtIHByZWZpeGVzfSByZWN1cnNpdmVseVxuICogQHBhcmFtIG1vZGVsXG4gKiBAcGFyYW0gYWNjdW1cbiAqIEBwYXJhbSBwcmVmaXhlc1xuICpcbiAqIEBmdW5jdGlvbiBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5SZXBvc2l0b3J5XG4gKi9cbmV4cG9ydCBjb25zdCBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUgPSBmdW5jdGlvbiA8VCBleHRlbmRzIE1vZGVsPihcbiAgbW9kZWw6IFQsXG4gIGFjY3VtOiB7IFtpbmRleGVyOiBzdHJpbmddOiBhbnlbXSB9IHwgdW5kZWZpbmVkLFxuICAuLi5wcmVmaXhlczogc3RyaW5nW11cbik6IHsgW2luZGV4ZXI6IHN0cmluZ106IGFueVtdIH0gfCB1bmRlZmluZWQge1xuICBjb25zdCBhY2N1bXVsYXRvciA9IGFjY3VtIHx8IHt9O1xuICBjb25zdCBtZXJnZURlY29yYXRvcnMgPSBmdW5jdGlvbiAoZGVjczogeyBbaW5kZXhlcjogc3RyaW5nXTogYW55W10gfSkge1xuICAgIGNvbnN0IHB1c2hPclNxdWFzaCA9IChrZXk6IHN0cmluZywgLi4udmFsdWVzOiBhbnlbXSkgPT4ge1xuICAgICAgdmFsdWVzLmZvckVhY2goKHZhbCkgPT4ge1xuICAgICAgICBsZXQgbWF0Y2g6IGFueTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICEobWF0Y2ggPSBhY2N1bXVsYXRvcltrZXldLmZpbmQoKGUpID0+IGUua2V5ID09PSB2YWwua2V5KSkgfHxcbiAgICAgICAgICBtYXRjaC5wcm9wcy5vcGVyYXRpb24gIT09IHZhbC5wcm9wcy5vcGVyYXRpb25cbiAgICAgICAgKSB7XG4gICAgICAgICAgYWNjdW11bGF0b3Jba2V5XS5wdXNoKHZhbCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHZhbC5rZXkgPT09IE1vZGVsS2V5cy5UWVBFKSByZXR1cm47XG5cbiAgICAgICAgY29uc3QgeyBoYW5kbGVycywgb3BlcmF0aW9uIH0gPSB2YWwucHJvcHM7XG5cbiAgICAgICAgaWYgKFxuICAgICAgICAgICFvcGVyYXRpb24gfHxcbiAgICAgICAgICAhb3BlcmF0aW9uLm1hdGNoKFxuICAgICAgICAgICAgbmV3IFJlZ0V4cChcbiAgICAgICAgICAgICAgYF4oOj8ke09wZXJhdGlvbktleXMuT059fCR7T3BlcmF0aW9uS2V5cy5BRlRFUn0pKDo/JHtPcGVyYXRpb25LZXlzLkNSRUFURX18JHtPcGVyYXRpb25LZXlzLlJFQUR9fCR7T3BlcmF0aW9uS2V5cy5VUERBVEV9fCR7T3BlcmF0aW9uS2V5cy5ERUxFVEV9KSRgXG4gICAgICAgICAgICApXG4gICAgICAgICAgKVxuICAgICAgICApIHtcbiAgICAgICAgICBhY2N1bXVsYXRvcltrZXldLnB1c2godmFsKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhY2N1bUhhbmRsZXJzID0gbWF0Y2gucHJvcHMuaGFuZGxlcnM7XG5cbiAgICAgICAgT2JqZWN0LmVudHJpZXMoaGFuZGxlcnMpLmZvckVhY2goKFtjbGF6eiwgaGFuZGxlckRlZl0pID0+IHtcbiAgICAgICAgICBpZiAoIShjbGF6eiBpbiBhY2N1bUhhbmRsZXJzKSkge1xuICAgICAgICAgICAgYWNjdW1IYW5kbGVyc1tjbGF6el0gPSBoYW5kbGVyRGVmO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIE9iamVjdC5lbnRyaWVzKGhhbmRsZXJEZWYgYXMgb2JqZWN0KS5mb3JFYWNoKFxuICAgICAgICAgICAgKFtoYW5kbGVyUHJvcCwgaGFuZGxlcl0pID0+IHtcbiAgICAgICAgICAgICAgaWYgKCEoaGFuZGxlclByb3AgaW4gYWNjdW1IYW5kbGVyc1tjbGF6el0pKSB7XG4gICAgICAgICAgICAgICAgYWNjdW1IYW5kbGVyc1tjbGF6el1baGFuZGxlclByb3BdID0gaGFuZGxlcjtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICBPYmplY3QuZW50cmllcyhoYW5kbGVyIGFzIG9iamVjdCkuZm9yRWFjaChcbiAgICAgICAgICAgICAgICAoW2hhbmRsZXJLZXksIGFyZ3NPYmpdKSA9PiB7XG4gICAgICAgICAgICAgICAgICBpZiAoIShoYW5kbGVyS2V5IGluIGFjY3VtSGFuZGxlcnNbY2xhenpdW2hhbmRsZXJQcm9wXSkpIHtcbiAgICAgICAgICAgICAgICAgICAgYWNjdW1IYW5kbGVyc1tjbGF6el1baGFuZGxlclByb3BdW2hhbmRsZXJLZXldID0gYXJnc09iajtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgY29uc29sZS53YXJuKFxuICAgICAgICAgICAgICAgICAgICBgU2tpcHBpbmcgaGFuZGxlciByZWdpc3RyYXRpb24gZm9yICR7Y2xhenp9IHVuZGVyIHByb3AgJHtoYW5kbGVyUHJvcH0gYmVjYXVzZSBoYW5kbGVyIGlzIHRoZSBzYW1lYFxuICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgKTtcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9O1xuXG4gICAgT2JqZWN0LmVudHJpZXMoZGVjcykuZm9yRWFjaCgoW2tleSwgdmFsdWVdKSA9PiB7XG4gICAgICBhY2N1bXVsYXRvcltrZXldID0gYWNjdW11bGF0b3Jba2V5XSB8fCBbXTtcbiAgICAgIHB1c2hPclNxdWFzaChrZXksIC4uLnZhbHVlKTtcbiAgICB9KTtcbiAgfTtcblxuICBjb25zdCBkZWNzOiB7IFtpbmRleGVyOiBzdHJpbmddOiBhbnlbXSB9IHwgdW5kZWZpbmVkID1cbiAgICBSZWZsZWN0aW9uLmdldEFsbFByb3BlcnR5RGVjb3JhdG9ycyhtb2RlbCwgLi4ucHJlZml4ZXMpO1xuICBpZiAoZGVjcykgbWVyZ2VEZWNvcmF0b3JzKGRlY3MpO1xuXG4gIGlmIChPYmplY3QuZ2V0UHJvdG90eXBlT2YobW9kZWwpID09PSBPYmplY3QucHJvdG90eXBlKSByZXR1cm4gYWNjdW11bGF0b3I7XG5cbiAgLy8gY29uc3QgbmFtZSA9IG1vZGVsLmNvbnN0cnVjdG9yLm5hbWU7XG4gIGNvbnN0IHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKG1vZGVsKTtcbiAgaWYgKCFwcm90bykgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAvLyBpZiAocHJvdG8uY29uc3RydWN0b3IgJiYgcHJvdG8uY29uc3RydWN0b3IubmFtZSA9PT0gbmFtZSlcbiAgLy8gICAgIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKVxuICByZXR1cm4gZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlKHByb3RvLCBhY2N1bXVsYXRvciwgLi4ucHJlZml4ZXMpO1xufTtcbiIsImltcG9ydCB7IFJlcG9zaXRvcnlGbGFncyB9IGZyb20gXCIuL3R5cGVzXCI7XG5cbmV4cG9ydCBjb25zdCBEZWZhdWx0UmVwb3NpdG9yeUZsYWdzOiBPbWl0PFJlcG9zaXRvcnlGbGFncywgXCJ0aW1lc3RhbXBcIj4gPSB7XG4gIHBhcmVudENvbnRleHQ6IHVuZGVmaW5lZCxcbiAgY2hpbGRDb250ZXh0czogW10sXG4gIGlnbm9yZWRWYWxpZGF0aW9uUHJvcGVydGllczogW10sXG4gIGNhbGxBcmdzOiBbXSxcbiAgd3JpdGVPcGVyYXRpb246IGZhbHNlLFxuICBhZmZlY3RlZFRhYmxlczogW10sXG4gIG9wZXJhdGlvbjogdW5kZWZpbmVkLFxuICBicmVha09uSGFuZGxlckVycm9yOiB0cnVlLFxuICByZWJ1aWxkV2l0aFRyYW5zaWVudDogdHJ1ZSxcbn07XG4iLCJpbXBvcnQgeyBDb250ZXh0QXJncyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBDb250ZXh0dWFsIH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvQ29udGV4dHVhbFwiO1xuaW1wb3J0IHsgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgRGVmYXVsdFJlcG9zaXRvcnlGbGFncyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgT2JqZWN0QWNjdW11bGF0b3IgfSBmcm9tIFwidHlwZWQtb2JqZWN0LWFjY3VtdWxhdG9yXCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5leHBvcnQgdHlwZSBDb250ZXh0RmFjdG9yeTxGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzPiA9IDxDIGV4dGVuZHMgQ29udGV4dDxGPj4oXG4gIGFyZzogT21pdDxGLCBcInRpbWVzdGFtcFwiPlxuKSA9PiBDO1xuXG5leHBvcnQgY29uc3QgRGVmYXVsdENvbnRleHRGYWN0b3J5OiBDb250ZXh0RmFjdG9yeTxhbnk+ID0gPFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIGFyZzogT21pdDxGLCBcInRpbWVzdGFtcFwiPlxuKSA9PiB7XG4gIHJldHVybiBuZXcgQ29udGV4dDxGPigpLmFjY3VtdWxhdGUoXG4gICAgT2JqZWN0LmFzc2lnbih7fSwgYXJnLCB7IHRpbWVzdGFtcDogbmV3IERhdGUoKSB9KSBhcyBGXG4gICkgYXMgQztcbn07XG5cbmV4cG9ydCBjbGFzcyBDb250ZXh0PEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3M+IHtcbiAgc3RhdGljIGZhY3Rvcnk6IENvbnRleHRGYWN0b3J5PGFueT4gPSBEZWZhdWx0Q29udGV4dEZhY3Rvcnk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjYWNoZTogRiAmIE9iamVjdEFjY3VtdWxhdG9yPEY+ID1cbiAgICBuZXcgT2JqZWN0QWNjdW11bGF0b3IoKSBhcyBGICYgT2JqZWN0QWNjdW11bGF0b3I8Rj47XG5cbiAgY29uc3RydWN0b3Iob2JqPzogRikge1xuICAgIGlmIChvYmopIHJldHVybiB0aGlzLmFjY3VtdWxhdGUob2JqKTtcbiAgfVxuXG4gIGFjY3VtdWxhdGU8ViBleHRlbmRzIG9iamVjdD4odmFsdWU6IFYpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJjYWNoZVwiLCB7XG4gICAgICB2YWx1ZTogdGhpcy5jYWNoZS5hY2N1bXVsYXRlKHZhbHVlKSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzIGFzIHVua25vd24gYXMgQ29udGV4dDxGICYgVj47XG4gIH1cblxuICBnZXQgdGltZXN0YW1wKCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlLnRpbWVzdGFtcDtcbiAgfVxuXG4gIGdldDxLIGV4dGVuZHMga2V5b2YgRj4oa2V5OiBLKTogRltLXSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiB0aGlzLmNhY2hlLmdldChrZXkpO1xuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIGlmICh0aGlzLmNhY2hlLnBhcmVudENvbnRleHQpIHJldHVybiB0aGlzLmNhY2hlLnBhcmVudENvbnRleHQuZ2V0KGtleSk7XG4gICAgICB0aHJvdyBlO1xuICAgIH1cbiAgfVxuXG4gIGNoaWxkPE0gZXh0ZW5kcyBNb2RlbCwgQyBleHRlbmRzIENvbnRleHQ8Rj4+KFxuICAgIG9wZXJhdGlvbjogT3BlcmF0aW9uS2V5cyxcbiAgICBtb2RlbD86IENvbnN0cnVjdG9yPE0+XG4gICk6IEMge1xuICAgIHJldHVybiBDb250ZXh0LmNoaWxkRnJvbTxGLCBDPihcbiAgICAgIHRoaXMgYXMgdW5rbm93biBhcyBDLFxuICAgICAge1xuICAgICAgICBvcGVyYXRpb246IG9wZXJhdGlvbixcbiAgICAgICAgYWZmZWN0ZWRUYWJsZXM6IG1vZGVsID8gW21vZGVsXSA6IFtdLFxuICAgICAgfSBhcyB1bmtub3duIGFzIFBhcnRpYWw8Rj5cbiAgICApO1xuICB9XG5cbiAgc3RhdGljIGNoaWxkRnJvbTxGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLCBDIGV4dGVuZHMgQ29udGV4dDxGPj4oXG4gICAgY29udGV4dDogQyxcbiAgICBvdmVycmlkZXM/OiBQYXJ0aWFsPEY+XG4gICk6IEMge1xuICAgIHJldHVybiBDb250ZXh0LmZhY3RvcnkoXG4gICAgICBPYmplY3QuYXNzaWduKHt9LCBjb250ZXh0LmNhY2hlLCBvdmVycmlkZXMgfHwge30pXG4gICAgKSBhcyB1bmtub3duIGFzIEM7XG4gIH1cblxuICBzdGF0aWMgYXN5bmMgZnJvbTxcbiAgICBNIGV4dGVuZHMgTW9kZWwsXG4gICAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyxcbiAgICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbiAgPihcbiAgICBvcGVyYXRpb246XG4gICAgICB8IE9wZXJhdGlvbktleXMuQ1JFQVRFXG4gICAgICB8IE9wZXJhdGlvbktleXMuUkVBRFxuICAgICAgfCBPcGVyYXRpb25LZXlzLlVQREFURVxuICAgICAgfCBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICBvdmVycmlkZXM6IFBhcnRpYWw8Rj4sXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+LFxuICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPEM+IHtcbiAgICByZXR1cm4gQ29udGV4dC5mYWN0b3J5KFxuICAgICAgT2JqZWN0LmFzc2lnbih7fSwgRGVmYXVsdFJlcG9zaXRvcnlGbGFncywgb3ZlcnJpZGVzLCB7XG4gICAgICAgIG9wZXJhdGlvbjogb3BlcmF0aW9uLFxuICAgICAgICBtb2RlbDogbW9kZWwsXG4gICAgICB9KVxuICAgICkgYXMgQztcbiAgfVxuXG4gIHN0YXRpYyBhc3luYyBhcmdzPFxuICAgIE0gZXh0ZW5kcyBNb2RlbCxcbiAgICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbiAgICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICA+KFxuICAgIG9wZXJhdGlvbjpcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5DUkVBVEVcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5SRUFEXG4gICAgICB8IE9wZXJhdGlvbktleXMuVVBEQVRFXG4gICAgICB8IE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICBhcmdzOiBhbnlbXSxcbiAgICBjb250ZXh0dWFsPzogQ29udGV4dHVhbDxGPixcbiAgICBvdmVycmlkZXM/OiBQYXJ0aWFsPEY+XG4gICk6IFByb21pc2U8Q29udGV4dEFyZ3M8RiwgQz4+IHtcbiAgICBjb25zdCBsYXN0ID0gYXJncy5wb3AoKTtcblxuICAgIGFzeW5jIGZ1bmN0aW9uIGdldENvbnRleHQoKSB7XG4gICAgICBpZiAoY29udGV4dHVhbClcbiAgICAgICAgcmV0dXJuIGNvbnRleHR1YWwuY29udGV4dChvcGVyYXRpb24sIG92ZXJyaWRlcyB8fCB7fSwgbW9kZWwsIC4uLmFyZ3MpO1xuICAgICAgcmV0dXJuIENvbnRleHQuZnJvbShvcGVyYXRpb24sIG92ZXJyaWRlcyB8fCB7fSwgbW9kZWwsIC4uLmFyZ3MpO1xuICAgIH1cblxuICAgIGxldCBjOiBDO1xuICAgIGlmIChsYXN0KSB7XG4gICAgICBpZiAobGFzdCBpbnN0YW5jZW9mIENvbnRleHQpIHtcbiAgICAgICAgYyA9IGxhc3QgYXMgQztcbiAgICAgICAgYXJncy5wdXNoKGxhc3QpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYyA9IChhd2FpdCBnZXRDb250ZXh0KCkpIGFzIEM7XG4gICAgICAgIGFyZ3MucHVzaChsYXN0LCBjKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYyA9IChhd2FpdCBnZXRDb250ZXh0KCkpIGFzIEM7XG4gICAgICBhcmdzLnB1c2goYyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgY29udGV4dDogYywgYXJnczogYXJncyB9O1xuICB9XG59XG4iLCJpbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4vQ29udGV4dFwiO1xuaW1wb3J0IHsgSW50ZXJuYWxFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgbWV0aG9kIHRvIGNoYW5nZSBhIG1ldGhvZCBvZiBhbiBvYmplY3QgcHJlZml4aW5nIGl0IHdpdGggYW5vdGhlclxuICogQHBhcmFtIHthbnl9IG9iaiBUaGUgQmFzZSBPYmplY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGFmdGVyIFRoZSBvcmlnaW5hbCBtZXRob2RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IHByZWZpeCBUaGUgUHJlZml4IG1ldGhvZC4gVGhlIG91dHB1dCB3aWxsIGJlIHVzZWQgYXMgYXJndW1lbnRzIGluIHRoZSBvcmlnaW5hbCBtZXRob2RcbiAqIEBwYXJhbSB7c3RyaW5nfSBbYWZ0ZXJOYW1lXSBXaGVuIHRoZSBhZnRlciBmdW5jdGlvbiBhbm1lIGNhbm5vdCBiZSBleHRyYWN0ZWQsIHBhc3MgaXQgaGVyZVxuICpcbiAqIEBmdW5jdGlvbiBwcmVmaXhNZXRob2RcbiAqXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuUmVwb3NpdG9yeVxuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlZml4TWV0aG9kKFxuICBvYmo6IGFueSxcbiAgYWZ0ZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBwcmVmaXg6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBhZnRlck5hbWU/OiBzdHJpbmdcbikge1xuICBhc3luYyBmdW5jdGlvbiB3cmFwcGVyKHRoaXM6IGFueSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHByZWZpeC5jYWxsKHRoaXMsIC4uLmFyZ3MpKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGFmdGVyLmFwcGx5KHRoaXMsIHJlc3VsdHMpKTtcbiAgfVxuICBjb25zdCB3cmFwcGVkID0gd3JhcHBlci5iaW5kKG9iaik7XG4gIGNvbnN0IG5hbWUgPSBhZnRlck5hbWUgPyBhZnRlck5hbWUgOiBhZnRlci5uYW1lO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkod3JhcHBlZCwgXCJuYW1lXCIsIHtcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IG5hbWUsXG4gIH0pO1xuICBvYmpbbmFtZV0gPSB3cmFwcGVkO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgbWV0aG9kIHRvIGNoYW5nZSBhIG1ldGhvZCBvZiBhbiBvYmplY3Qgc3VmZml4aW5nIGl0IHdpdGggYW5vdGhlclxuICogQHBhcmFtIHthbnl9IG9iaiBUaGUgQmFzZSBPYmplY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGJlZm9yZSBUaGUgb3JpZ2luYWwgbWV0aG9kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzdWZmaXggVGhlIFByZWZpeCBtZXRob2QuIFRoZSBvdXRwdXQgd2lsbCBiZSB1c2VkIGFzIGFyZ3VtZW50cyBpbiB0aGUgb3JpZ2luYWwgbWV0aG9kXG4gKiBAcGFyYW0ge3N0cmluZ30gW2JlZm9yZU5hbWVdIFdoZW4gdGhlIGFmdGVyIGZ1bmN0aW9uIGFubWUgY2Fubm90IGJlIGV4dHJhY3RlZCwgcGFzcyBpdCBoZXJlXG4gKlxuICogQGZ1bmN0aW9uIHN1ZmZpeE1ldGhvZFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5SZXBvc2l0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdWZmaXhNZXRob2QoXG4gIG9iajogYW55LFxuICBiZWZvcmU6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBzdWZmaXg6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBiZWZvcmVOYW1lPzogc3RyaW5nXG4pIHtcbiAgYXN5bmMgZnVuY3Rpb24gd3JhcHBlcih0aGlzOiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UucmVzb2x2ZShiZWZvcmUuY2FsbCh0aGlzLCAuLi5hcmdzKSk7XG4gICAgcmV0dXJuIHN1ZmZpeC5jYWxsKHRoaXMsIC4uLnJlc3VsdHMpO1xuICB9XG4gIGNvbnN0IHdyYXBwZWQgPSB3cmFwcGVyLmJpbmQob2JqKTtcbiAgY29uc3QgbmFtZSA9IGJlZm9yZU5hbWUgPyBiZWZvcmVOYW1lIDogYmVmb3JlLm5hbWU7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3cmFwcGVkLCBcIm5hbWVcIiwge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogbmFtZSxcbiAgfSk7XG4gIG9ialtuYW1lXSA9IHdyYXBwZWQ7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBtZXRob2QgdG8gd3JhcCBhIG1ldGhvZCBvZiBhbiBvYmplY3Qgd2l0aCBhZGRpdGlvbmFsIGxvZ2ljXG4gKlxuICogQHBhcmFtIHthbnl9IG9iaiBUaGUgQmFzZSBPYmplY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGJlZm9yZSB0aGUgbWV0aG9kIHRvIGJlIHByZWZpeGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgdGhlIG1ldGhvZCB0byBiZSB3cmFwcGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBhZnRlciBUaGUgbWV0aG9kIHRvIGJlIHN1ZmZpeGVkXG4gKiBAcGFyYW0ge3N0cmluZ30gW21ldGhvZE5hbWVdIFdoZW4gdGhlIGFmdGVyIGZ1bmN0aW9uIGFubWUgY2Fubm90IGJlIGV4dHJhY3RlZCwgcGFzcyBpdCBoZXJlXG4gKlxuICogQGZ1bmN0aW9uIHdyYXBNZXRob2RXaXRoQ29udGV4dFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5SZXBvc2l0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB3cmFwTWV0aG9kV2l0aENvbnRleHQoXG4gIG9iajogYW55LFxuICBiZWZvcmU6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBtZXRob2Q6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBhZnRlcjogKC4uLmFyZ3M6IGFueVtdKSA9PiBhbnksXG4gIG1ldGhvZE5hbWU/OiBzdHJpbmdcbikge1xuICBjb25zdCBuYW1lID0gbWV0aG9kTmFtZSA/IG1ldGhvZE5hbWUgOiBtZXRob2QubmFtZTtcbiAgb2JqW25hbWVdID0gbmV3IFByb3h5KG9ialtuYW1lXSwge1xuICAgIGFwcGx5OiBhc3luYyAodGFyZ2V0LCB0aGlzQXJnLCBhcmdBcnJheSkgPT4ge1xuICAgICAgbGV0IHRyYW5zZm9ybWVkQXJncyA9IGJlZm9yZS5jYWxsKHRoaXNBcmcsIC4uLmFyZ0FycmF5KTtcbiAgICAgIGlmICh0cmFuc2Zvcm1lZEFyZ3MgaW5zdGFuY2VvZiBQcm9taXNlKVxuICAgICAgICB0cmFuc2Zvcm1lZEFyZ3MgPSBhd2FpdCB0cmFuc2Zvcm1lZEFyZ3M7XG4gICAgICBjb25zdCBjb250ZXh0ID0gdHJhbnNmb3JtZWRBcmdzW3RyYW5zZm9ybWVkQXJncy5sZW5ndGggLSAxXSBhcyBhbnk7XG4gICAgICBpZiAoIShjb250ZXh0IGluc3RhbmNlb2YgQ29udGV4dCkpXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFwiTWlzc2luZyBhIGNvbnRleHRcIik7XG4gICAgICBsZXQgcmVzdWx0cyA9IGF3YWl0IHRhcmdldC5jYWxsKHRoaXNBcmcsIC4uLnRyYW5zZm9ybWVkQXJncyk7XG4gICAgICBpZiAocmVzdWx0cyBpbnN0YW5jZW9mIFByb21pc2UpIHJlc3VsdHMgPSBhd2FpdCByZXN1bHRzO1xuICAgICAgcmVzdWx0cyA9IGFmdGVyLmNhbGwodGhpc0FyZywgcmVzdWx0cywgY29udGV4dCk7XG4gICAgICBpZiAocmVzdWx0cyBpbnN0YW5jZW9mIFByb21pc2UpIHJlc3VsdHMgPSBhd2FpdCByZXN1bHRzO1xuICAgICAgcmV0dXJuIHJlc3VsdHM7XG4gICAgfSxcbiAgfSk7XG59XG4iLCJpbXBvcnQgeyBEQktleXMgfSBmcm9tIFwiLi4vbW9kZWwvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS91dGlsc1wiO1xuaW1wb3J0IHsgTW9kZWwsIE1vZGVsS2V5cywgc2YgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvZXJyb3JzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgUmV0dXJucyB0aGUgcHJpbWFyeSBrZXkgYXR0cmlidXRlIGZvciBhIHtAbGluayBNb2RlbH1cbiAqIEBkZXNjcmlwdGlvbiBzZWFyY2hlcyBpbiBhbGwgdGhlIHByb3BlcnRpZXMgaW4gdGhlIG9iamVjdCBmb3IgYW4ge0BsaW5rIGlkfSBkZWNvcmF0ZWQgcHJvcGVydHlcbiAqXG4gKiBAcGFyYW0ge01vZGVsfSBtb2RlbFxuICpcbiAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IGlmIG5vIHByb3BlcnR5IG9yIG1vcmUgdGhhbiBvbmUgcHJvcGVydGllcyBhcmUge0BsaW5rIGlkfSBkZWNvcmF0ZWRcbiAqIG9yIG5vIHZhbHVlIGlzIHNldCBpbiB0aGF0IHByb3BlcnR5XG4gKlxuICogQGZ1bmN0aW9uIGZpbmRQcmltYXJ5S2V5XG4gKlxuICogQGNhdGVnb3J5IG1hbmFnZXJzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kUHJpbWFyeUtleTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gIGNvbnN0IGRlY29yYXRvcnMgPSBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUoXG4gICAgbW9kZWwsXG4gICAgdW5kZWZpbmVkLFxuICAgIERCS2V5cy5SRUZMRUNUICsgREJLZXlzLklEXG4gICk7XG4gIGNvbnN0IGlkRGVjb3JhdG9ycyA9IE9iamVjdC5lbnRyaWVzKGRlY29yYXRvcnMgYXMgb2JqZWN0KS5yZWR1Y2UoXG4gICAgKGFjY3VtOiB7IFtpbmRleGVyOiBzdHJpbmddOiBhbnlbXSB9LCBbcHJvcCwgZGVjc10pID0+IHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkID0gKGRlY3MgYXMgeyBrZXk6IHN0cmluZyB9W10pLmZpbHRlcihcbiAgICAgICAgKGQpID0+IGQua2V5ICE9PSBNb2RlbEtleXMuVFlQRVxuICAgICAgKTtcbiAgICAgIGlmIChmaWx0ZXJlZCAmJiBmaWx0ZXJlZC5sZW5ndGgpIHtcbiAgICAgICAgYWNjdW1bcHJvcF0gPSBhY2N1bVtwcm9wXSB8fCBbXTtcbiAgICAgICAgYWNjdW1bcHJvcF0ucHVzaCguLi5maWx0ZXJlZCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSxcbiAgICB7fVxuICApO1xuXG4gIGlmICghaWREZWNvcmF0b3JzIHx8ICFPYmplY3Qua2V5cyhpZERlY29yYXRvcnMpLmxlbmd0aClcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkNvdWxkIG5vdCBmaW5kIElEIGRlY29yYXRlZCBQcm9wZXJ0eVwiKTtcbiAgaWYgKE9iamVjdC5rZXlzKGlkRGVjb3JhdG9ycykubGVuZ3RoID4gMSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihzZihPYmplY3Qua2V5cyhpZERlY29yYXRvcnMpLmpvaW4oXCIsIFwiKSkpO1xuICBjb25zdCBpZFByb3AgPSBPYmplY3Qua2V5cyhpZERlY29yYXRvcnMpWzBdO1xuICBpZiAoIWlkUHJvcCkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJDb3VsZCBub3QgZmluZCBJRCBkZWNvcmF0ZWQgUHJvcGVydHlcIik7XG4gIHJldHVybiB7XG4gICAgaWQ6IGlkUHJvcCBhcyBrZXlvZiBNLFxuICAgIHByb3BzOiBpZERlY29yYXRvcnNbaWRQcm9wXVswXS5wcm9wcyxcbiAgfTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSBwcmltYXJ5IGtleSB2YWx1ZSBmb3IgYSB7QGxpbmsgTW9kZWx9XG4gKiBAZGVzY3JpcHRpb24gc2VhcmNoZXMgaW4gYWxsIHRoZSBwcm9wZXJ0aWVzIGluIHRoZSBvYmplY3QgZm9yIGFuIHtAbGluayBwa30gZGVjb3JhdGVkIHByb3BlcnR5XG4gKlxuICogQHBhcmFtIHtNb2RlbH0gbW9kZWxcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JldHVybkVtcHR5XVxuICogQHJldHVybiB7c3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50fSBwcmltYXJ5IGtleVxuICpcbiAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IGlmIG5vIHByb3BlcnR5IG9yIG1vcmUgdGhhbiBvbmUgcHJvcGVydGllcyBhcmUge0BsaW5rIHBrfSBkZWNvcmF0ZWRcbiAqIEB0aHJvd3Mge05vdEZvdW5kRXJyb3J9IHJldHVybkVtcHR5IGlzIGZhbHNlIGFuZCBubyB2YWx1ZSBpcyBzZXQgb24gdGhlIHtAbGluayBwa30gZGVjb3JhdGVkIHByb3BlcnR5XG4gKlxuICogQGZ1bmN0aW9uIGZpbmRNb2RlbElEXG4gKlxuICogQGNhdGVnb3J5IG1hbmFnZXJzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTW9kZWxJZDxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogTSxcbiAgcmV0dXJuRW1wdHkgPSBmYWxzZVxuKTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHtcbiAgY29uc3QgaWRQcm9wID0gZmluZFByaW1hcnlLZXkobW9kZWwpLmlkO1xuICBjb25zdCBtb2RlbElkID0gbW9kZWxbaWRQcm9wXTtcbiAgaWYgKHR5cGVvZiBtb2RlbElkID09PSBcInVuZGVmaW5lZFwiICYmICFyZXR1cm5FbXB0eSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBObyB2YWx1ZSBmb3IgdGhlIElkIGlzIGRlZmluZWQgdW5kZXIgdGhlIHByb3BlcnR5ICR7aWRQcm9wIGFzIHN0cmluZ31gXG4gICAgKTtcbiAgcmV0dXJuIG1vZGVsSWQgYXMgc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50O1xufVxuIiwiaW1wb3J0IHsgSVJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9JUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgZW5mb3JjZURCRGVjb3JhdG9ycyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4uL29wZXJhdGlvbnMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyB3cmFwTWV0aG9kV2l0aENvbnRleHQgfSBmcm9tIFwiLi93cmFwcGVyc1wiO1xuaW1wb3J0IHsgZmluZFByaW1hcnlLZXkgfSBmcm9tIFwiLi4vaWRlbnRpdHkvdXRpbHNcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9Db250ZXh0XCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZVJlcG9zaXRvcnk8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4gPSBDb250ZXh0PEY+LFxuPiBpbXBsZW1lbnRzIElSZXBvc2l0b3J5PE0sIEYsIEM+XG57XG4gIHByaXZhdGUgcmVhZG9ubHkgX2NsYXNzITogQ29uc3RydWN0b3I8TT47XG4gIHByaXZhdGUgX3BrIToga2V5b2YgTTtcbiAgcHJpdmF0ZSBfcGtQcm9wcyE6IGFueTtcblxuICBnZXQgY2xhc3MoKSB7XG4gICAgaWYgKCF0aGlzLl9jbGFzcylcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBObyBjbGFzcyBkZWZpbml0aW9uIGZvdW5kIGZvciB0aGlzIHJlcG9zaXRvcnlgKTtcbiAgICByZXR1cm4gdGhpcy5fY2xhc3M7XG4gIH1cblxuICBnZXQgcGsoKToga2V5b2YgTSB7XG4gICAgaWYgKCF0aGlzLl9waykge1xuICAgICAgY29uc3QgeyBpZCwgcHJvcHMgfSA9IGZpbmRQcmltYXJ5S2V5KG5ldyB0aGlzLmNsYXNzKCkpO1xuICAgICAgdGhpcy5fcGsgPSBpZDtcbiAgICAgIHRoaXMuX3BrUHJvcHMgPSBwcm9wcztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3BrO1xuICB9XG5cbiAgcHJvdGVjdGVkIGdldCBwa1Byb3BzKCk6IGFueSB7XG4gICAgaWYgKCF0aGlzLl9wa1Byb3BzKSB7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgICBjb25zdCBwayA9IHRoaXMucGs7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9wa1Byb3BzO1xuICB9XG5cbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGNsYXp6PzogQ29uc3RydWN0b3I8TT4pIHtcbiAgICBpZiAoY2xhenopIHRoaXMuX2NsYXNzID0gY2xheno7XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby10aGlzLWFsaWFzXG4gICAgY29uc3Qgc2VsZiA9IHRoaXM7XG4gICAgW3RoaXMuY3JlYXRlLCB0aGlzLnJlYWQsIHRoaXMudXBkYXRlLCB0aGlzLmRlbGV0ZV0uZm9yRWFjaCgobSkgPT4ge1xuICAgICAgY29uc3QgbmFtZSA9IG0ubmFtZTtcbiAgICAgIHdyYXBNZXRob2RXaXRoQ29udGV4dChcbiAgICAgICAgc2VsZixcbiAgICAgICAgKHNlbGYgYXMgYW55KVtuYW1lICsgXCJQcmVmaXhcIl0sXG4gICAgICAgIG0sXG4gICAgICAgIChzZWxmIGFzIGFueSlbbmFtZSArIFwiU3VmZml4XCJdXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgYWJzdHJhY3QgY3JlYXRlKG1vZGVsOiBNLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT47XG5cbiAgYXN5bmMgY3JlYXRlQWxsKG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKG1vZGVscy5tYXAoKG0pID0+IHRoaXMuY3JlYXRlKG0sIC4uLmFyZ3MpKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlUHJlZml4KG1vZGVsOiBNLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzPE0sIEMsIEY+KFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgbW9kZWwgPSBuZXcgdGhpcy5jbGFzcyhtb2RlbCk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICApO1xuICAgIHJldHVybiBbbW9kZWwsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGNyZWF0ZVN1ZmZpeChtb2RlbDogTSwgY29udGV4dDogQykge1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLkFGVEVSXG4gICAgKTtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlQWxsUHJlZml4KG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzPE0sIEMsIEY+KFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKGFzeW5jIChtKSA9PiB7XG4gICAgICAgIG0gPSBuZXcgdGhpcy5jbGFzcyhtKTtcbiAgICAgICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBtO1xuICAgICAgfSlcbiAgICApO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBjcmVhdGVBbGxTdWZmaXgobW9kZWxzOiBNW10sIGNvbnRleHQ6IEMpIHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoKG0pID0+XG4gICAgICAgIGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5BRlRFUlxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcbiAgICByZXR1cm4gbW9kZWxzO1xuICB9XG5cbiAgYWJzdHJhY3QgcmVhZChrZXk6IHN0cmluZyB8IG51bWJlciwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+O1xuXG4gIGFzeW5jIHJlYWRBbGwoa2V5czogc3RyaW5nW10gfCBudW1iZXJbXSwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE1bXT4ge1xuICAgIHJldHVybiBhd2FpdCBQcm9taXNlLmFsbChrZXlzLm1hcCgoaWQpID0+IHRoaXMucmVhZChpZCwgLi4uYXJncykpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyByZWFkU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDKSB7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICBPcGVyYXRpb25LZXlzLkFGVEVSXG4gICAgKTtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgcmVhZFByZWZpeChrZXk6IHN0cmluZywgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJnczxNLCBDLCBGPihcbiAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBjb25zdCBtb2RlbDogTSA9IG5ldyB0aGlzLmNsYXNzKCk7XG4gICAgbW9kZWxbdGhpcy5wa10gPSBrZXkgYXMgYW55O1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICk7XG4gICAgcmV0dXJuIFtrZXksIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIHJlYWRBbGxQcmVmaXgoa2V5czogc3RyaW5nW10gfCBudW1iZXJbXSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJnczxNLCBDLCBGPihcbiAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGtleXMubWFwKGFzeW5jIChrKSA9PiB7XG4gICAgICAgIGNvbnN0IG0gPSBuZXcgdGhpcy5jbGFzcygpO1xuICAgICAgICBtW3RoaXMucGtdID0gayBhcyBhbnk7XG4gICAgICAgIHJldHVybiBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgICAgICk7XG4gICAgICB9KVxuICAgICk7XG4gICAgcmV0dXJuIFtrZXlzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyByZWFkQWxsU3VmZml4KG1vZGVsczogTVtdLCBjb250ZXh0OiBDKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKChtKSA9PlxuICAgICAgICBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkFGVEVSXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuICAgIHJldHVybiBtb2RlbHM7XG4gIH1cblxuICBhYnN0cmFjdCB1cGRhdGUobW9kZWw6IE0sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNPjtcblxuICBhc3luYyB1cGRhdGVBbGwobW9kZWxzOiBNW10sIC4uLmFyZ3M6IGFueSk6IFByb21pc2U8TVtdPiB7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKG1vZGVscy5tYXAoKG0pID0+IHRoaXMudXBkYXRlKG0sIC4uLmFyZ3MpKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgdXBkYXRlU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDKSB7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICApO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB1cGRhdGVQcmVmaXgobW9kZWw6IE0sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3M8TSwgQywgRj4oXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBjb25zdCBpZCA9IG1vZGVsW3RoaXMucGtdO1xuICAgIGlmICghaWQpXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYE5vIHZhbHVlIGZvciB0aGUgSWQgaXMgZGVmaW5lZCB1bmRlciB0aGUgcHJvcGVydHkgJHt0aGlzLnBrIGFzIHN0cmluZ31gXG4gICAgICApO1xuICAgIGNvbnN0IG9sZE1vZGVsID0gYXdhaXQgdGhpcy5yZWFkKGlkIGFzIHN0cmluZyk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT04sXG4gICAgICBvbGRNb2RlbFxuICAgICk7XG4gICAgcmV0dXJuIFttb2RlbCwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgdXBkYXRlQWxsUHJlZml4KG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzPE0sIEMsIEY+KFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKChtKSA9PiB7XG4gICAgICAgIG0gPSBuZXcgdGhpcy5jbGFzcyhtKTtcbiAgICAgICAgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgICAgICk7XG4gICAgICAgIHJldHVybiBtO1xuICAgICAgfSlcbiAgICApO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyB1cGRhdGVBbGxTdWZmaXgobW9kZWxzOiBNW10sIGNvbnRleHQ6IEMpIHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoKG0pID0+XG4gICAgICAgIGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5BRlRFUlxuICAgICAgICApXG4gICAgICApXG4gICAgKTtcbiAgICByZXR1cm4gbW9kZWxzO1xuICB9XG5cbiAgYWJzdHJhY3QgZGVsZXRlKGtleTogc3RyaW5nIHwgbnVtYmVyLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT47XG5cbiAgYXN5bmMgZGVsZXRlQWxsKGtleXM6IHN0cmluZ1tdIHwgbnVtYmVyW10sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNW10+IHtcbiAgICByZXR1cm4gUHJvbWlzZS5hbGwoa2V5cy5tYXAoKGspID0+IHRoaXMuZGVsZXRlKGssIC4uLmFyZ3MpKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZGVsZXRlU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDKSB7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICApO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIHByb3RlY3RlZCBhc3luYyBkZWxldGVQcmVmaXgoa2V5OiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3M8TSwgQywgRj4oXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMucmVhZChrZXksIC4uLmNvbnRleHRBcmdzLmFyZ3MpO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgKTtcbiAgICByZXR1cm4gW2tleSwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBwcm90ZWN0ZWQgYXN5bmMgZGVsZXRlQWxsUHJlZml4KGtleXM6IHN0cmluZ1tdIHwgbnVtYmVyW10sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3M8TSwgQywgRj4oXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCB0aGlzLnJlYWRBbGwoa2V5cywgLi4uY29udGV4dEFyZ3MuYXJncyk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKGFzeW5jIChtKSA9PiB7XG4gICAgICAgIHJldHVybiBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gW2tleXMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIGFzeW5jIGRlbGV0ZUFsbFN1ZmZpeChtb2RlbHM6IE1bXSwgY29udGV4dDogQykge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcCgobSkgPT5cbiAgICAgICAgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkFGVEVSXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuICAgIHJldHVybiBtb2RlbHM7XG4gIH1cblxuICBwcm90ZWN0ZWQgbWVyZ2Uob2xkTW9kZWw6IE0sIG1vZGVsOiBNKTogTSB7XG4gICAgY29uc3QgZXh0cmFjdCA9IChtb2RlbDogTSkgPT5cbiAgICAgIE9iamVjdC5lbnRyaWVzKG1vZGVsKS5yZWR1Y2UoKGFjY3VtOiBSZWNvcmQ8c3RyaW5nLCBhbnk+LCBba2V5LCB2YWxdKSA9PiB7XG4gICAgICAgIGlmICh0eXBlb2YgdmFsICE9PSBcInVuZGVmaW5lZFwiKSBhY2N1bVtrZXldID0gdmFsO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB7fSk7XG5cbiAgICByZXR1cm4gbmV3IHRoaXMuY2xhc3MoT2JqZWN0LmFzc2lnbih7fSwgZXh0cmFjdChvbGRNb2RlbCksIGV4dHJhY3QobW9kZWwpKSk7XG4gIH1cblxuICB0b1N0cmluZygpIHtcbiAgICByZXR1cm4gYCR7dGhpcy5jbGFzcy5uYW1lfSBSZXBvc2l0b3J5YDtcbiAgfVxufVxuIiwiaW1wb3J0IHsgZW5mb3JjZURCRGVjb3JhdG9ycyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4uL29wZXJhdGlvbnMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yLCBWYWxpZGF0aW9uRXJyb3IgfSBmcm9tIFwiLi9lcnJvcnNcIjtcbmltcG9ydCB7IEJhc2VSZXBvc2l0b3J5IH0gZnJvbSBcIi4vQmFzZVJlcG9zaXRvcnlcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IERCS2V5cyB9IGZyb20gXCIuLi9tb2RlbC9jb25zdGFudHNcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9Db250ZXh0XCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgUmVwb3NpdG9yeTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzID0gUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4+IGV4dGVuZHMgQmFzZVJlcG9zaXRvcnk8TSwgRiwgQz4ge1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xheno/OiBDb25zdHJ1Y3RvcjxNPikge1xuICAgIHN1cGVyKGNsYXp6KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyBjcmVhdGVQcmVmaXgoXG4gICAgbW9kZWw6IE0sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxbTSwgLi4uYW55W11dPiB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBtb2RlbCA9IG5ldyB0aGlzLmNsYXNzKG1vZGVsKTtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICk7XG5cbiAgICBjb25zdCBlcnJvcnMgPSBtb2RlbC5oYXNFcnJvcnMoKTtcbiAgICBpZiAoZXJyb3JzKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGVycm9ycy50b1N0cmluZygpKTtcblxuICAgIHJldHVybiBbbW9kZWwsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIGNyZWF0ZUFsbFByZWZpeChcbiAgICBtb2RlbHM6IE1bXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPGFueVtdPiB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoYXN5bmMgKG0pID0+IHtcbiAgICAgICAgbSA9IG5ldyB0aGlzLmNsYXNzKG0pO1xuICAgICAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIG07XG4gICAgICB9KVxuICAgICk7XG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWxzXG4gICAgICAubWFwKChtKSA9PiBtLmhhc0Vycm9ycygpKVxuICAgICAgLnJlZHVjZSgoYWNjdW06IHN0cmluZyB8IHVuZGVmaW5lZCwgZSwgaSkgPT4ge1xuICAgICAgICBpZiAoZSlcbiAgICAgICAgICBhY2N1bSA9XG4gICAgICAgICAgICB0eXBlb2YgYWNjdW0gPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgPyBhY2N1bSArIGBcXG4gLSAke2l9OiAke2UudG9TdHJpbmcoKX1gXG4gICAgICAgICAgICAgIDogYCAtICR7aX06ICR7ZS50b1N0cmluZygpfWA7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIHVuZGVmaW5lZCk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMpO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSBhc3luYyB1cGRhdGVQcmVmaXgoXG4gICAgbW9kZWw6IE0sXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxbTSwgLi4uYXJnczogYW55W11dPiB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBjb25zdCBwayA9IChtb2RlbCBhcyBhbnkpW3RoaXMucGtdO1xuICAgIGlmICghcGspXG4gICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgYE5vIHZhbHVlIGZvciB0aGUgSWQgaXMgZGVmaW5lZCB1bmRlciB0aGUgcHJvcGVydHkgJHt0aGlzLnBrIGFzIHN0cmluZ31gXG4gICAgICApO1xuXG4gICAgY29uc3Qgb2xkTW9kZWw6IE0gPSBhd2FpdCB0aGlzLnJlYWQocGspO1xuXG4gICAgbW9kZWwgPSB0aGlzLm1lcmdlKG9sZE1vZGVsLCBtb2RlbCk7XG5cbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTixcbiAgICAgIG9sZE1vZGVsXG4gICAgKTtcblxuICAgIGNvbnN0IGVycm9ycyA9IG1vZGVsLmhhc0Vycm9ycyhvbGRNb2RlbCBhcyBhbnkpO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzLnRvU3RyaW5nKCkpO1xuICAgIHJldHVybiBbbW9kZWwsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIHVwZGF0ZUFsbFByZWZpeChtb2RlbHM6IE1bXSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJncyhcbiAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3NcbiAgICApO1xuICAgIGNvbnN0IGlkcyA9IG1vZGVscy5tYXAoKG0pID0+IHtcbiAgICAgIGNvbnN0IGlkID0gbVt0aGlzLnBrXTtcbiAgICAgIGlmICh0eXBlb2YgaWQgPT09IFwidW5kZWZpbmVkXCIpXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKFxuICAgICAgICAgIGBObyB2YWx1ZSBmb3IgdGhlIElkIGlzIGRlZmluZWQgdW5kZXIgdGhlIHByb3BlcnR5ICR7dGhpcy5wayBhcyBzdHJpbmd9YFxuICAgICAgICApO1xuICAgICAgcmV0dXJuIGlkIGFzIHN0cmluZztcbiAgICB9KTtcbiAgICBjb25zdCBvbGRNb2RlbHM6IE1bXSA9IGF3YWl0IHRoaXMucmVhZEFsbChpZHMsIC4uLmNvbnRleHRBcmdzLmFyZ3MpO1xuICAgIG1vZGVscyA9IG1vZGVscy5tYXAoKG0sIGkpID0+IHRoaXMubWVyZ2Uob2xkTW9kZWxzW2ldLCBtKSk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKChtLCBpKSA9PlxuICAgICAgICBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT04sXG4gICAgICAgICAgb2xkTW9kZWxzW2ldXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuXG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWxzXG4gICAgICAubWFwKChtLCBpKSA9PiBtLmhhc0Vycm9ycyhvbGRNb2RlbHNbaV0gYXMgYW55KSlcbiAgICAgIC5yZWR1Y2UoKGFjY3VtOiBzdHJpbmcgfCB1bmRlZmluZWQsIGUsIGkpID0+IHtcbiAgICAgICAgaWYgKGUpXG4gICAgICAgICAgYWNjdW0gPVxuICAgICAgICAgICAgdHlwZW9mIGFjY3VtID09PSBcInN0cmluZ1wiXG4gICAgICAgICAgICAgID8gYWNjdW0gKyBgXFxuIC0gJHtpfTogJHtlLnRvU3RyaW5nKCl9YFxuICAgICAgICAgICAgICA6IGAgLSAke2l9OiAke2UudG9TdHJpbmcoKX1gO1xuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgICB9LCB1bmRlZmluZWQpO1xuICAgIGlmIChlcnJvcnMpIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoZXJyb3JzKTtcbiAgICByZXR1cm4gW21vZGVscywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICBzdGF0aWMga2V5KGtleTogc3RyaW5nKSB7XG4gICAgcmV0dXJuIERCS2V5cy5SRUZMRUNUICsga2V5O1xuICB9XG59XG4iLCJpbXBvcnQgXCIuL3ZhbGlkYXRpb25cIjtcbmltcG9ydCB7XG4gIGRhdGUsXG4gIERlY29yYXRpb24sXG4gIE1vZGVsLFxuICBwcm9wTWV0YWRhdGEsXG4gIHJlcXVpcmVkLFxuICB0eXBlLFxuICBWYWxpZGF0aW9uLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBEQktleXMsIERFRkFVTFRfVElNRVNUQU1QX0ZPUk1BVCB9IGZyb20gXCIuLi9tb2RlbC9jb25zdGFudHNcIjtcbmltcG9ydCB7IERFRkFVTFRfRVJST1JfTUVTU0FHRVMgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IERCT3BlcmF0aW9ucywgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgYWZ0ZXIsIG9uLCBvbkNyZWF0ZVVwZGF0ZSB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IElSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvSVJlcG9zaXRvcnlcIjtcbmltcG9ydCB7IFNlcmlhbGl6YXRpb25FcnJvciB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L2Vycm9yc1wiO1xuaW1wb3J0IHsgYXBwbHksIG1ldGFkYXRhIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9Db250ZXh0XCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS90eXBlc1wiO1xuXG4vKipcbiAqIE1hcmtzIHRoZSBwcm9wZXJ0eSBhcyByZWFkb25seS5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIHRoZSBlcnJvciBtZXNzYWdlLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5SRUFET05MWS5JTlZBTElEfVxuICpcbiAqIEBkZWNvcmF0b3IgcmVhZG9ubHlcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZG9ubHkoXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUkVBRE9OTFkuSU5WQUxJRFxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24udXBkYXRlS2V5KERCS2V5cy5SRUFET05MWSk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YShrZXksIHtcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gdGltZXN0YW1wSGFuZGxlcjxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4odGhpczogUiwgY29udGV4dDogQywgZGF0YTogViwga2V5OiBrZXlvZiBNLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICAobW9kZWwgYXMgYW55KVtrZXldID0gY29udGV4dC50aW1lc3RhbXA7XG59XG5cbi8qKlxuICogTWFya3MgdGhlIHByb3BlcnR5IGFzIHRpbWVzdGFtcC5cbiAqIE1ha2VzIGl0IHtAbGluayByZXF1aXJlZH1cbiAqIE1ha2VzIGl0IGEge0BsaW5rIGRhdGV9XG4gKlxuICogRGF0ZSBGb3JtYXQ6XG4gKlxuICogPHByZT5cbiAqICAgICAgVXNpbmcgc2ltaWxhciBmb3JtYXR0aW5nIGFzIE1vbWVudC5qcywgQ2xhc3MgRGF0ZVRpbWVGb3JtYXR0ZXIgKEphdmEpLCBhbmQgQ2xhc3MgU2ltcGxlRGF0ZUZvcm1hdCAoSmF2YSksXG4gKiAgICAgIEkgaW1wbGVtZW50ZWQgYSBjb21wcmVoZW5zaXZlIHNvbHV0aW9uIGZvcm1hdERhdGUoZGF0ZSwgcGF0dGVyblN0cikgd2hlcmUgdGhlIGNvZGUgaXMgZWFzeSB0byByZWFkIGFuZCBtb2RpZnkuXG4gKiAgICAgIFlvdSBjYW4gZGlzcGxheSBkYXRlLCB0aW1lLCBBTS9QTSwgZXRjLlxuICpcbiAqICAgICAgRGF0ZSBhbmQgVGltZSBQYXR0ZXJuc1xuICogICAgICB5eSA9IDItZGlnaXQgeWVhcjsgeXl5eSA9IGZ1bGwgeWVhclxuICogICAgICBNID0gZGlnaXQgbW9udGg7IE1NID0gMi1kaWdpdCBtb250aDsgTU1NID0gc2hvcnQgbW9udGggbmFtZTsgTU1NTSA9IGZ1bGwgbW9udGggbmFtZVxuICogICAgICBFRUVFID0gZnVsbCB3ZWVrZGF5IG5hbWU7IEVFRSA9IHNob3J0IHdlZWtkYXkgbmFtZVxuICogICAgICBkID0gZGlnaXQgZGF5OyBkZCA9IDItZGlnaXQgZGF5XG4gKiAgICAgIGggPSBob3VycyBhbS9wbTsgaGggPSAyLWRpZ2l0IGhvdXJzIGFtL3BtOyBIID0gaG91cnM7IEhIID0gMi1kaWdpdCBob3Vyc1xuICogICAgICBtID0gbWludXRlczsgbW0gPSAyLWRpZ2l0IG1pbnV0ZXM7IGFhYSA9IEFNL1BNXG4gKiAgICAgIHMgPSBzZWNvbmRzOyBzcyA9IDItZGlnaXQgc2Vjb25kc1xuICogICAgICBTID0gbWlsaXNlY29uZHNcbiAqIDwvcHJlPlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nW119IG9wZXJhdGlvbiBUaGUge0BsaW5rIERCT3BlcmF0aW9uc30gdG8gYWN0IG9uLiBEZWZhdWx0cyB0byB7QGxpbmsgREJPcGVyYXRpb25zLkNSRUFURV9VUERBVEV9XG4gKiBAcGFyYW0ge3N0cmluZ30gW2Zvcm1hdF0gVGhlIFRpbWVTdGFtcCBmb3JtYXQuIGRlZmF1bHRzIHRvIHtAbGluayBERUZBVUxUX1RJTUVTVEFNUF9GT1JNQVR9XG4gKiBAcGFyYW0ge3tuZXc6IFVwZGF0ZVZhbGlkYXRvcn19IFt2YWxpZGF0b3JdIGRlZmF1bHRzIHRvIHtAbGluayBUaW1lc3RhbXBWYWxpZGF0b3J9XG4gKlxuICogQGRlY29yYXRvciB0aW1lc3RhbXBcbiAqXG4gKiBAY2F0ZWdvcnkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdGltZXN0YW1wKFxuICBvcGVyYXRpb246IE9wZXJhdGlvbktleXNbXSA9IERCT3BlcmF0aW9ucy5DUkVBVEVfVVBEQVRFIGFzIHVua25vd24gYXMgT3BlcmF0aW9uS2V5c1tdLFxuICBmb3JtYXQ6IHN0cmluZyA9IERFRkFVTFRfVElNRVNUQU1QX0ZPUk1BVFxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24udXBkYXRlS2V5KERCS2V5cy5USU1FU1RBTVApO1xuXG4gIGNvbnN0IGRlY29yYXRvcnM6IGFueVtdID0gW1xuICAgIGRhdGUoZm9ybWF0LCBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlRJTUVTVEFNUC5EQVRFKSxcbiAgICByZXF1aXJlZChERUZBVUxUX0VSUk9SX01FU1NBR0VTLlRJTUVTVEFNUC5SRVFVSVJFRCksXG4gICAgb24ob3BlcmF0aW9uLCB0aW1lc3RhbXBIYW5kbGVyKSxcbiAgXTtcblxuICBpZiAob3BlcmF0aW9uLmluZGV4T2YoT3BlcmF0aW9uS2V5cy5VUERBVEUpICE9PSAtMSlcbiAgICBkZWNvcmF0b3JzLnB1c2goXG4gICAgICBwcm9wTWV0YWRhdGEoVmFsaWRhdGlvbi51cGRhdGVLZXkoREJLZXlzLlRJTUVTVEFNUCksIHtcbiAgICAgICAgbWVzc2FnZTogREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5USU1FU1RBTVAuSU5WQUxJRCxcbiAgICAgIH0pXG4gICAgKTtcbiAgcmV0dXJuIERlY29yYXRpb24uZm9yKGtleSlcbiAgICAuZGVmaW5lKC4uLmRlY29yYXRvcnMpXG4gICAgLmFwcGx5KCk7XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXJpYWxpemVPbkNyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4odGhpczogUiwgY29udGV4dDogQywgZGF0YTogViwga2V5OiBrZXlvZiBNLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIW1vZGVsW2tleV0pIHJldHVybjtcbiAgdHJ5IHtcbiAgICBtb2RlbFtrZXldID0gSlNPTi5zdHJpbmdpZnkobW9kZWxba2V5XSkgYXMgTVtrZXlvZiBNXTtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgYEZhaWxlZCB0byBzZXJpYWxpemUgJHtrZXkudG9TdHJpbmcoKX0gcHJvcGVydHkgb2YgbW9kZWwgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfTogZWBcbiAgICApO1xuICB9XG59XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzZXJpYWxpemVBZnRlckFsbDxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4odGhpczogUiwgY29udGV4dDogQywgZGF0YTogViwga2V5OiBrZXlvZiBNLCBtb2RlbDogTSk6IFByb21pc2U8dm9pZD4ge1xuICBpZiAoIW1vZGVsW2tleV0pIHJldHVybjtcbiAgaWYgKHR5cGVvZiBtb2RlbFtrZXldICE9PSBcInN0cmluZ1wiKSByZXR1cm47XG5cbiAgdHJ5IHtcbiAgICBtb2RlbFtrZXldID0gSlNPTi5wYXJzZShtb2RlbFtrZXldKTtcbiAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoXG4gICAgICBgRmFpbGVkIHRvIGRlc2VyaWFsaXplICR7a2V5LnRvU3RyaW5nKCl9IHByb3BlcnR5IG9mIG1vZGVsICR7bW9kZWwuY29uc3RydWN0b3IubmFtZX06ICR7ZX1gXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFNlcmlhbGl6ZSBEZWNvcmF0b3JcbiAqIEBkZXNjcmlwdGlvbiBwcm9wZXJ0aWVzIGRlY29yYXRlZCB3aWxsIHRoZSBzZXJpYWxpemVkIGJlZm9yZSBzdG9yZWQgaW4gdGhlIGRiXG4gKlxuICogQGZ1bmN0aW9uIHNlcmlhbGl6ZVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6d2FsbGV0LWRiLkRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZSgpIHtcbiAgcmV0dXJuIGFwcGx5KFxuICAgIG9uQ3JlYXRlVXBkYXRlKHNlcmlhbGl6ZU9uQ3JlYXRlVXBkYXRlKSxcbiAgICBhZnRlcihEQk9wZXJhdGlvbnMuQUxMLCBzZXJpYWxpemVBZnRlckFsbCksXG4gICAgdHlwZShbU3RyaW5nLm5hbWUsIE9iamVjdC5uYW1lXSksXG4gICAgbWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLlNFUklBTElaRSksIHt9KVxuICApO1xufVxuIiwiaW1wb3J0IHsgcHJvcE1ldGFkYXRhLCByZXF1aXJlZCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IHJlYWRvbmx5IH0gZnJvbSBcIi4uL3ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IERCS2V5cyB9IGZyb20gXCIuLi9tb2RlbC9jb25zdGFudHNcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgYXBwbHkgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcblxuZXhwb3J0IGZ1bmN0aW9uIGlkKCkge1xuICByZXR1cm4gYXBwbHkoXG4gICAgcmVxdWlyZWQoKSxcbiAgICByZWFkb25seSgpLFxuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShEQktleXMuSUQpLCB7fSlcbiAgKTtcbn1cbiIsImltcG9ydCB7XG4gIE1vZGVsLFxuICBNb2RlbEVycm9yRGVmaW5pdGlvbixcbiAgTW9kZWxFcnJvcnMsXG4gIE1vZGVsS2V5cyxcbiAgUmVzZXJ2ZWRNb2RlbHMsXG4gIHNmLFxuICBWYWxpZGF0YWJsZSxcbiAgVmFsaWRhdGlvbixcbiAgVmFsaWRhdGlvbktleXMsXG4gIFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb24sXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IERlY29yYXRvck1ldGFkYXRhLCBSZWZsZWN0aW9uIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5pbXBvcnQgeyBVcGRhdGVWYWxpZGF0aW9uS2V5cywgVXBkYXRlVmFsaWRhdG9yIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IGZpbmRNb2RlbElkIH0gZnJvbSBcIi4uL2lkZW50aXR5XCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoZSB1cGRhdGUgb2YgYSBtb2RlbFxuICpcbiAqIEBwYXJhbSB7VH0gb2xkTW9kZWxcbiAqIEBwYXJhbSB7VH0gbmV3TW9kZWxcbiAqIEBwYXJhbSB7c3RyaW5nW119IFtleGNlcHRpb25zXVxuICpcbiAqIEBmdW5jdGlvbiB2YWxpZGF0ZUNvbXBhcmVcbiAqIEByZXR1cm4ge01vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkfVxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5Nb2RlbFxuICovXG5leHBvcnQgZnVuY3Rpb24gdmFsaWRhdGVDb21wYXJlPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIG9sZE1vZGVsOiBNLFxuICBuZXdNb2RlbDogTSxcbiAgLi4uZXhjZXB0aW9uczogc3RyaW5nW11cbik6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgZGVjb3JhdGVkUHJvcGVydGllczogVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvbltdID0gW107XG4gIGZvciAoY29uc3QgcHJvcCBpbiBuZXdNb2RlbClcbiAgICBpZiAoXG4gICAgICBPYmplY3QucHJvdG90eXBlLmhhc093blByb3BlcnR5LmNhbGwobmV3TW9kZWwsIHByb3ApICYmXG4gICAgICBleGNlcHRpb25zLmluZGV4T2YocHJvcCkgPT09IC0xXG4gICAgKVxuICAgICAgZGVjb3JhdGVkUHJvcGVydGllcy5wdXNoKFxuICAgICAgICBSZWZsZWN0aW9uLmdldFByb3BlcnR5RGVjb3JhdG9ycyhcbiAgICAgICAgICBVcGRhdGVWYWxpZGF0aW9uS2V5cy5SRUZMRUNULFxuICAgICAgICAgIG5ld01vZGVsLFxuICAgICAgICAgIHByb3BcbiAgICAgICAgKSBhcyBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uXG4gICAgICApO1xuXG4gIGxldCByZXN1bHQ6IE1vZGVsRXJyb3JzIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gIGZvciAoY29uc3QgZGVjb3JhdGVkUHJvcGVydHkgb2YgZGVjb3JhdGVkUHJvcGVydGllcykge1xuICAgIGNvbnN0IHsgcHJvcCwgZGVjb3JhdG9ycyB9ID0gZGVjb3JhdGVkUHJvcGVydHk7XG5cbiAgICBkZWNvcmF0b3JzLnNoaWZ0KCk7IC8vIHJlbW92ZSB0aGUgZGVzaWduOnR5cGUgZGVjb3JhdG9yLCBzaW5jZSB0aGUgdHlwZSB3aWxsIGFscmVhZHkgYmUgY2hlY2tlZFxuXG4gICAgaWYgKCFkZWNvcmF0b3JzIHx8ICFkZWNvcmF0b3JzLmxlbmd0aCkgY29udGludWU7XG4gICAgbGV0IGVycnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgICBmb3IgKGNvbnN0IGRlY29yYXRvciBvZiBkZWNvcmF0b3JzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0b3I6IFVwZGF0ZVZhbGlkYXRvciA9IFZhbGlkYXRpb24uZ2V0KFxuICAgICAgICBkZWNvcmF0b3Iua2V5XG4gICAgICApIGFzIFVwZGF0ZVZhbGlkYXRvcjtcbiAgICAgIGlmICghdmFsaWRhdG9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgYENvdWxkIG5vdCBmaW5kIE1hdGNoaW5nIHZhbGlkYXRvciBmb3IgJHtkZWNvcmF0b3Iua2V5fSBmb3IgcHJvcGVydHkgJHtTdHJpbmcoZGVjb3JhdGVkUHJvcGVydHkucHJvcCl9YFxuICAgICAgICApO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXJyOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB2YWxpZGF0b3IudXBkYXRlSGFzRXJyb3JzKFxuICAgICAgICAobmV3TW9kZWwgYXMgYW55KVtwcm9wLnRvU3RyaW5nKCldLFxuICAgICAgICAob2xkTW9kZWwgYXMgYW55KVtwcm9wLnRvU3RyaW5nKCldLFxuICAgICAgICAuLi5PYmplY3QudmFsdWVzKGRlY29yYXRvci5wcm9wcylcbiAgICAgICk7XG5cbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgZXJycyA9IGVycnMgfHwge307XG4gICAgICAgIGVycnNbZGVjb3JhdG9yLmtleV0gPSBlcnI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVycnMpIHtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdCB8fCB7fTtcbiAgICAgIHJlc3VsdFtkZWNvcmF0ZWRQcm9wZXJ0eS5wcm9wLnRvU3RyaW5nKCldID0gZXJycztcbiAgICB9XG4gIH1cbiAgLy8gdGVzdHMgbmVzdGVkIGNsYXNzZXNcbiAgZm9yIChjb25zdCBwcm9wIG9mIE9iamVjdC5rZXlzKG5ld01vZGVsKS5maWx0ZXIoKGspID0+IHtcbiAgICBpZiAoZXhjZXB0aW9ucy5pbmNsdWRlcyhrKSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiAhcmVzdWx0IHx8ICFyZXN1bHRba107XG4gIH0pKSB7XG4gICAgbGV0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIC8vIGlmIGEgbmVzdGVkIE1vZGVsXG4gICAgY29uc3QgYWxsRGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgIG5ld01vZGVsLFxuICAgICAgcHJvcFxuICAgICkuZGVjb3JhdG9ycztcbiAgICBjb25zdCBkZWNvcmF0b3JzID0gUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICBWYWxpZGF0aW9uS2V5cy5SRUZMRUNULFxuICAgICAgbmV3TW9kZWwsXG4gICAgICBwcm9wXG4gICAgKS5kZWNvcmF0b3JzLmZpbHRlcihcbiAgICAgIChkKSA9PiBbTW9kZWxLZXlzLlRZUEUsIFZhbGlkYXRpb25LZXlzLlRZUEVdLmluZGV4T2YoZC5rZXkgYXMgYW55KSAhPT0gLTFcbiAgICApO1xuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGRlYyA9IGRlY29yYXRvcnMucG9wKCkgYXMgRGVjb3JhdG9yTWV0YWRhdGE7XG4gICAgY29uc3QgY2xhenogPSBkZWMucHJvcHMubmFtZVxuICAgICAgPyBbZGVjLnByb3BzLm5hbWVdXG4gICAgICA6IEFycmF5LmlzQXJyYXkoZGVjLnByb3BzLmN1c3RvbVR5cGVzKVxuICAgICAgICA/IGRlYy5wcm9wcy5jdXN0b21UeXBlc1xuICAgICAgICA6IFtkZWMucHJvcHMuY3VzdG9tVHlwZXNdO1xuICAgIGNvbnN0IHJlc2VydmVkID0gT2JqZWN0LnZhbHVlcyhSZXNlcnZlZE1vZGVscykubWFwKCh2KSA9PlxuICAgICAgdi50b0xvd2VyQ2FzZSgpXG4gICAgKSBhcyBzdHJpbmdbXTtcblxuICAgIGZvciAoY29uc3QgYyBvZiBjbGF6eikge1xuICAgICAgaWYgKHJlc2VydmVkLmluZGV4T2YoYy50b0xvd2VyQ2FzZSgpKSA9PT0gLTEpIHtcbiAgICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgICAgY2FzZSBBcnJheS5uYW1lOlxuICAgICAgICAgIGNhc2UgU2V0Lm5hbWU6XG4gICAgICAgICAgICBpZiAoYWxsRGVjb3JhdG9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgbGlzdERlYyA9IGFsbERlY29yYXRvcnMuZmluZChcbiAgICAgICAgICAgICAgICAoZCkgPT4gZC5rZXkgPT09IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgaWYgKGxpc3REZWMpIHtcbiAgICAgICAgICAgICAgICBsZXQgY3VycmVudExpc3QsIG9sZExpc3Q7XG5cbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgQXJyYXkubmFtZTpcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudExpc3QgPSAobmV3TW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF07XG4gICAgICAgICAgICAgICAgICAgIG9sZExpc3QgPSAob2xkTW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgY2FzZSBTZXQubmFtZTpcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudExpc3QgPSAobmV3TW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbXG4gICAgICAgICAgICAgICAgICAgICAgcHJvcFxuICAgICAgICAgICAgICAgICAgICBdLnZhbHVlcygpO1xuICAgICAgICAgICAgICAgICAgICBvbGRMaXN0ID0gKG9sZE1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdLnZhbHVlcygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhdHRyaWJ1dGUgdHlwZSAke2N9YCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXJyID0gY3VycmVudExpc3RcbiAgICAgICAgICAgICAgICAgIC5tYXAoKHY6IFZhbGlkYXRhYmxlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gZmluZE1vZGVsSWQodiBhcyBhbnksIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWlkKSByZXR1cm4gXCJGYWlsZWQgdG8gZmluZCBtb2RlbCBpZFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRNb2RlbCA9IG9sZExpc3QuZmluZChcbiAgICAgICAgICAgICAgICAgICAgICAoZWw6IGFueSkgPT4gaWQgPT09IGZpbmRNb2RlbElkKGVsLCB0cnVlKVxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghb2xkTW9kZWwpIHJldHVybjsgLy8gbm90aGluZyB0byBjb21wYXJlIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHYuaGFzRXJyb3JzKG9sZE1vZGVsKTtcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAuZmlsdGVyKChlOiBhbnkpID0+ICEhZSkgYXMgYW55O1xuXG4gICAgICAgICAgICAgICAgaWYgKCFlcnI/Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHJlc3VsdCBpcyBhbiBlbXB0eSBsaXN0Li4uXG4gICAgICAgICAgICAgICAgICBlcnIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIChuZXdNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSAmJlxuICAgICAgICAgICAgICAgIChvbGRNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgZXJyID0gKG5ld01vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdLmhhc0Vycm9ycyhcbiAgICAgICAgICAgICAgICAgIChvbGRNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oc2YoXCJNb2RlbCBzaG91bGQgYmUgdmFsaWRhdGFibGUgYnV0IGl0cyBub3RcIikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdCB8fCB7fTtcbiAgICAgICAgcmVzdWx0W3Byb3BdID0gZXJyIGFzIGFueTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdCA/IG5ldyBNb2RlbEVycm9yRGVmaW5pdGlvbihyZXN1bHQpIDogdW5kZWZpbmVkO1xufVxuIiwiaW1wb3J0IHsgREJLZXlzLCBEZWZhdWx0U2VwYXJhdG9yIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBhcHBseSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHtcbiAgSGFzaGluZyxcbiAgTW9kZWwsXG4gIHByb3BNZXRhZGF0YSxcbiAgdHlwZSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgb25DcmVhdGUsIG9uQ3JlYXRlVXBkYXRlLCBvblVwZGF0ZSB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IElSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvSVJlcG9zaXRvcnlcIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9lcnJvcnNcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvQ29udGV4dFwiO1xuaW1wb3J0IHsgQ3J1ZE9wZXJhdGlvbnMsIE9wZXJhdGlvbktleXMgfSBmcm9tIFwiLi4vb3BlcmF0aW9uc1wiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeUZsYWdzIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvdHlwZXNcIjtcblxuLyoqXG4gKlxuICogQHBhcmFtIHtzdHJ9IHN0clxuICogQG1lbWJlck9mIGRiLWRlY29yYXRvcnMubW9kZWxcbiAqL1xuXG5leHBvcnQgZnVuY3Rpb24gaGFzaE9uQ3JlYXRlVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBJUmVwb3NpdG9yeTxNLCBGLCBDPixcbiAgViBleHRlbmRzIG9iamVjdCxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4gPSBDb250ZXh0PEY+LFxuPih0aGlzOiBSLCBjb250ZXh0OiBDLCBkYXRhOiBWLCBrZXk6IGtleW9mIE0sIG1vZGVsOiBNLCBvbGRNb2RlbD86IE0pOiB2b2lkIHtcbiAgaWYgKHR5cGVvZiBtb2RlbFtrZXldID09PSBcInVuZGVmaW5lZFwiKSByZXR1cm47XG4gIGNvbnN0IGhhc2ggPSBIYXNoaW5nLmhhc2goKG1vZGVsIGFzIGFueSlba2V5XSk7XG4gIGlmIChvbGRNb2RlbCAmJiAobW9kZWwgYXMgYW55KVtrZXldID09PSBoYXNoKSByZXR1cm47XG4gIG1vZGVsW2tleV0gPSBoYXNoO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gaGFzaCgpIHtcbiAgcmV0dXJuIGFwcGx5KFxuICAgIG9uQ3JlYXRlVXBkYXRlKGhhc2hPbkNyZWF0ZVVwZGF0ZSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KERCS2V5cy5IQVNIKSwge30pXG4gICk7XG59XG5cbmV4cG9ydCB0eXBlIENvbXBvc2VkRnJvbU1ldGFkYXRhID0ge1xuICBhcmdzOiBzdHJpbmdbXTtcbiAgc2VwYXJhdG9yOiBzdHJpbmc7XG4gIGhhc2hSZXN1bHQ6IGJvb2xlYW47XG4gIHR5cGU6IFwia2V5c1wiIHwgXCJ2YWx1ZXNcIjtcbiAgcHJlZml4Pzogc3RyaW5nO1xuICBzdWZmaXg/OiBzdHJpbmc7XG59O1xuXG5leHBvcnQgZnVuY3Rpb24gY29tcG9zZWRGcm9tQ3JlYXRlVXBkYXRlPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBJUmVwb3NpdG9yeTxNLCBGLCBDPixcbiAgViBleHRlbmRzIENvbXBvc2VkRnJvbU1ldGFkYXRhLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzID0gUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4+KHRoaXM6IFIsIGNvbnRleHQ6IEMsIGRhdGE6IFYsIGtleToga2V5b2YgTSwgbW9kZWw6IE0pIHtcbiAgdHJ5IHtcbiAgICBjb25zdCB7IGFyZ3MsIHR5cGUsIHByZWZpeCwgc3VmZml4LCBzZXBhcmF0b3IgfSA9IGRhdGE7XG4gICAgY29uc3QgY29tcG9zZWQgPSBhcmdzLm1hcCgoYXJnOiBzdHJpbmcpID0+IHtcbiAgICAgIGlmICghKGFyZyBpbiBtb2RlbCkpXG4gICAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBQcm9wZXJ0eSAke2FyZ30gbm90IGZvdW5kIHRvIGNvbXBvc2UgZnJvbWApO1xuICAgICAgaWYgKHR5cGUgPT09IFwia2V5c1wiKSByZXR1cm4gYXJnO1xuICAgICAgaWYgKHR5cGVvZiAobW9kZWwgYXMgYW55KVthcmddID09PSBcInVuZGVmaW5lZFwiKVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICBgUHJvcGVydHkgJHthcmdzfSBkb2VzIG5vdCBjb250YWluIGEgdmFsdWUgdG8gY29tcG9zZSBmcm9tYFxuICAgICAgICApO1xuICAgICAgcmV0dXJuICgobW9kZWwgYXMgYW55KVthcmddIGFzIGFueSkudG9TdHJpbmcoKTtcbiAgICB9KTtcblxuICAgIGlmIChwcmVmaXgpIGNvbXBvc2VkLnVuc2hpZnQocHJlZml4KTtcbiAgICBpZiAoc3VmZml4KSBjb21wb3NlZC5wdXNoKHN1ZmZpeCk7XG5cbiAgICAobW9kZWwgYXMgYW55KVtrZXldID0gY29tcG9zZWQuam9pbihzZXBhcmF0b3IpO1xuICB9IGNhdGNoIChlOiBhbnkpIHtcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgRmFpbGVkIHRvIGNvbXBvc2UgdmFsdWU6ICR7ZX1gKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjb21wb3NlZEZyb20oXG4gIGFyZ3M6IHN0cmluZ1tdLFxuICBoYXNoUmVzdWx0OiBib29sZWFuID0gZmFsc2UsXG4gIHNlcGFyYXRvcjogc3RyaW5nID0gRGVmYXVsdFNlcGFyYXRvcixcbiAgdHlwZTogXCJrZXlzXCIgfCBcInZhbHVlc1wiID0gXCJ2YWx1ZXNcIixcbiAgcHJlZml4ID0gXCJcIixcbiAgc3VmZml4ID0gXCJcIlxuKSB7XG4gIGNvbnN0IGRhdGE6IENvbXBvc2VkRnJvbU1ldGFkYXRhID0ge1xuICAgIGFyZ3M6IGFyZ3MsXG4gICAgaGFzaFJlc3VsdDogaGFzaFJlc3VsdCxcbiAgICBzZXBhcmF0b3I6IHNlcGFyYXRvcixcbiAgICB0eXBlOiB0eXBlLFxuICAgIHByZWZpeDogcHJlZml4LFxuICAgIHN1ZmZpeDogc3VmZml4LFxuICB9O1xuXG4gIGNvbnN0IGRlY29yYXRvcnMgPSBbXG4gICAgb25DcmVhdGVVcGRhdGUoY29tcG9zZWRGcm9tQ3JlYXRlVXBkYXRlLCBkYXRhKSxcbiAgICBwcm9wTWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLkNPTVBPU0VEKSwgZGF0YSksXG4gIF07XG4gIGlmIChoYXNoUmVzdWx0KSBkZWNvcmF0b3JzLnB1c2goaGFzaCgpKTtcbiAgcmV0dXJuIGFwcGx5KC4uLmRlY29yYXRvcnMpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gY29tcG9zZWRGcm9tS2V5cyhcbiAgYXJnczogc3RyaW5nW10sXG4gIHNlcGFyYXRvcjogc3RyaW5nID0gRGVmYXVsdFNlcGFyYXRvcixcbiAgaGFzaDogYm9vbGVhbiA9IGZhbHNlLFxuICBwcmVmaXggPSBcIlwiLFxuICBzdWZmaXggPSBcIlwiXG4pIHtcbiAgcmV0dXJuIGNvbXBvc2VkRnJvbShhcmdzLCBoYXNoLCBzZXBhcmF0b3IsIFwia2V5c1wiLCBwcmVmaXgsIHN1ZmZpeCk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wb3NlZChcbiAgYXJnczogc3RyaW5nW10sXG4gIHNlcGFyYXRvcjogc3RyaW5nID0gRGVmYXVsdFNlcGFyYXRvcixcbiAgaGFzaDogYm9vbGVhbiA9IGZhbHNlLFxuICBwcmVmaXggPSBcIlwiLFxuICBzdWZmaXggPSBcIlwiXG4pIHtcbiAgcmV0dXJuIGNvbXBvc2VkRnJvbShhcmdzLCBoYXNoLCBzZXBhcmF0b3IsIFwidmFsdWVzXCIsIHByZWZpeCwgc3VmZml4KTtcbn1cblxuLyoqXG4gKiBDcmVhdGVzIGEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgdXBkYXRlcyB0aGUgdmVyc2lvbiBvZiBhIG1vZGVsIGR1cmluZyBjcmVhdGUgb3IgdXBkYXRlIG9wZXJhdGlvbnMuXG4gKlxuICogQHBhcmFtIHtDcnVkT3BlcmF0aW9uc30gb3BlcmF0aW9uIC0gVGhlIHR5cGUgb2Ygb3BlcmF0aW9uIGJlaW5nIHBlcmZvcm1lZCAoQ1JFQVRFIG9yIFVQREFURSkuXG4gKiBAcmV0dXJucyB7ZnVuY3Rpb259IEEgZnVuY3Rpb24gdGhhdCB1cGRhdGVzIHRoZSB2ZXJzaW9uIG9mIHRoZSBtb2RlbCBiYXNlZCBvbiB0aGUgb3BlcmF0aW9uIHR5cGUuXG4gKlxuICogQHRlbXBsYXRlIE0gLSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFYgLSBUeXBlIGV4dGVuZGluZyBJUmVwb3NpdG9yeTxNPlxuICpcbiAqIEB0aGlzIHtWfSAtIFRoZSByZXBvc2l0b3J5IGluc3RhbmNlXG4gKiBAcGFyYW0ge0NvbnRleHQ8TT59IGNvbnRleHQgLSBUaGUgY29udGV4dCBvZiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge3Vua25vd259IGRhdGEgLSBBZGRpdGlvbmFsIGRhdGEgZm9yIHRoZSBvcGVyYXRpb24gKG5vdCB1c2VkIGluIHRoaXMgZnVuY3Rpb24pXG4gKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIGtleSBvZiB0aGUgdmVyc2lvbiBwcm9wZXJ0eSBpbiB0aGUgbW9kZWxcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgYmVpbmcgdXBkYXRlZFxuICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgYW4gaW52YWxpZCBvcGVyYXRpb24gaXMgcHJvdmlkZWQgb3IgaWYgdmVyc2lvbiB1cGRhdGUgZmFpbHNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcnNpb25DcmVhdGVVcGRhdGUob3BlcmF0aW9uOiBDcnVkT3BlcmF0aW9ucykge1xuICByZXR1cm4gZnVuY3Rpb24gdmVyc2lvbkNyZWF0ZVVwZGF0ZTxcbiAgICBNIGV4dGVuZHMgTW9kZWwsXG4gICAgUiBleHRlbmRzIElSZXBvc2l0b3J5PE0sIEYsIEM+LFxuICAgIFYgZXh0ZW5kcyBvYmplY3QsXG4gICAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4gID4odGhpczogUiwgY29udGV4dDogQywgZGF0YTogViwga2V5OiBrZXlvZiBNLCBtb2RlbDogTSkge1xuICAgIHRyeSB7XG4gICAgICBzd2l0Y2ggKG9wZXJhdGlvbikge1xuICAgICAgICBjYXNlIE9wZXJhdGlvbktleXMuQ1JFQVRFOlxuICAgICAgICAgIChtb2RlbCBhcyBhbnkpW2tleV0gPSAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIE9wZXJhdGlvbktleXMuVVBEQVRFOlxuICAgICAgICAgIChtb2RlbCBhcyBhbnkpW2tleV0rKztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgSW52YWxpZCBvcGVyYXRpb246ICR7b3BlcmF0aW9ufWApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBGYWlsZWQgdG8gdXBkYXRlIHZlcnNpb246ICR7ZX1gKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBkZWNvcmF0b3IgZm9yIHZlcnNpb25pbmcgYSBwcm9wZXJ0eSBpbiBhIG1vZGVsLlxuICogQHN1bW1hcnkgVGhpcyBkZWNvcmF0b3IgYXBwbGllcyBtdWx0aXBsZSBzdWItZGVjb3JhdG9ycyB0byBoYW5kbGUgdmVyc2lvbiBtYW5hZ2VtZW50IGR1cmluZyBjcmVhdGUgYW5kIHVwZGF0ZSBvcGVyYXRpb25zLlxuICpcbiAqIEByZXR1cm5zIHtGdW5jdGlvbn0gQSBjb21wb3NpdGUgZGVjb3JhdG9yIHRoYXQ6XG4gKiAgIC0gU2V0cyB0aGUgdHlwZSBvZiB0aGUgcHJvcGVydHkgdG8gTnVtYmVyXG4gKiAgIC0gQXBwbGllcyBhIHZlcnNpb24gdXBkYXRlIG9uIGNyZWF0ZSBvcGVyYXRpb25zXG4gKiAgIC0gQXBwbGllcyBhIHZlcnNpb24gdXBkYXRlIG9uIHVwZGF0ZSBvcGVyYXRpb25zXG4gKiAgIC0gQWRkcyBtZXRhZGF0YSBpbmRpY2F0aW5nIHRoaXMgcHJvcGVydHkgaXMgdXNlZCBmb3IgdmVyc2lvbmluZ1xuICovXG5leHBvcnQgZnVuY3Rpb24gdmVyc2lvbigpIHtcbiAgcmV0dXJuIGFwcGx5KFxuICAgIHR5cGUoTnVtYmVyLm5hbWUpLFxuICAgIG9uQ3JlYXRlKHZlcnNpb25DcmVhdGVVcGRhdGUoT3BlcmF0aW9uS2V5cy5DUkVBVEUpKSxcbiAgICBvblVwZGF0ZSh2ZXJzaW9uQ3JlYXRlVXBkYXRlKE9wZXJhdGlvbktleXMuVVBEQVRFKSksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KERCS2V5cy5WRVJTSU9OKSwgdHJ1ZSlcbiAgKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIHRyYW5zaWVudCgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uIHRyYW5zaWVudChtb2RlbDogYW55LCBhdHRyaWJ1dGU6IHN0cmluZykge1xuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShEQktleXMuVFJBTlNJRU5UKSwgdHJ1ZSkobW9kZWwsIGF0dHJpYnV0ZSk7XG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KERCS2V5cy5UUkFOU0lFTlQpLCB0cnVlKShtb2RlbC5jb25zdHJ1Y3Rvcik7XG4gIH07XG59XG4iLCJpbXBvcnQge1xuICBDb21wYXJhYmxlLFxuICBIYXNoYWJsZSxcbiAgTW9kZWxBcmcsXG4gIE1vZGVsRXJyb3JEZWZpbml0aW9uLFxuICBTZXJpYWxpemFibGUsXG4gIFZhbGlkYXRhYmxlLFxuICBNb2RlbCxcbiAgdmFsaWRhdGUsXG4gIENvbnN0cnVjdG9yLFxuICBNb2RlbEJ1aWxkZXJGdW5jdGlvbixcbiAgQnVpbGRlclJlZ2lzdHJ5LFxuICBNb2RlbENvbnN0cnVjdG9yLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyB2YWxpZGF0ZUNvbXBhcmUgfSBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5cbk1vZGVsLnByb3RvdHlwZS5oYXNFcnJvcnMgPSBmdW5jdGlvbiA8TSBleHRlbmRzIE1vZGVsPihcbiAgdGhpczogTSxcbiAgcHJldmlvdXNWZXJzaW9uPzogTSB8IGFueSxcbiAgLi4uZXhjbHVzaW9uczogYW55W11cbik6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkIHtcbiAgaWYgKHByZXZpb3VzVmVyc2lvbiAmJiAhKHByZXZpb3VzVmVyc2lvbiBpbnN0YW5jZW9mIE1vZGVsKSkge1xuICAgIGV4Y2x1c2lvbnMudW5zaGlmdChwcmV2aW91c1ZlcnNpb24pO1xuICAgIHByZXZpb3VzVmVyc2lvbiA9IHVuZGVmaW5lZDtcbiAgfVxuXG4gIGNvbnN0IGVycnMgPSB2YWxpZGF0ZSh0aGlzLCAuLi5leGNsdXNpb25zKTtcbiAgaWYgKGVycnMgfHwgIXByZXZpb3VzVmVyc2lvbikgcmV0dXJuIGVycnM7XG5cbiAgcmV0dXJuIHZhbGlkYXRlQ29tcGFyZShwcmV2aW91c1ZlcnNpb24sIHRoaXMsIC4uLmV4Y2x1c2lvbnMpO1xufTtcblxuZGVjbGFyZSBtb2R1bGUgXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIiB7XG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvYmFuLXRzLWNvbW1lbnRcbiAgLy8gQHRzLWV4cGVjdC1lcnJvclxuICBkZWNsYXJlIGFic3RyYWN0IGNsYXNzIE1vZGVsXG4gICAgaW1wbGVtZW50cyBWYWxpZGF0YWJsZSwgU2VyaWFsaXphYmxlLCBIYXNoYWJsZSwgQ29tcGFyYWJsZTxNb2RlbD5cbiAge1xuICAgIHByb3RlY3RlZCBjb25zdHJ1Y3Rvcihhcmc/OiBNb2RlbEFyZzxNb2RlbD4pO1xuXG4gICAgaGFzRXJyb3JzKC4uLmV4Y2x1c2lvbnM6IGFueVtdKTogTW9kZWxFcnJvckRlZmluaXRpb24gfCB1bmRlZmluZWQ7XG4gICAgaGFzRXJyb3JzKFxuICAgICAgcHJldmlvdXNWZXJzaW9uPzogTW9kZWwgfCBhbnksXG4gICAgICAuLi5leGNsdXNpb25zOiBhbnlbXVxuICAgICk6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQ29tcGFyZSBvYmplY3QgZXF1YWxpdHkgcmVjdXJzaXZlbHlcbiAgICAgKiBAcGFyYW0ge2FueX0gb2JqIG9iamVjdCB0byBjb21wYXJlIHRvXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtleGNlcHRpb25zXSBwcm9wZXJ0eSBuYW1lcyB0byBiZSBleGNsdWRlZCBmcm9tIHRoZSBjb21wYXJpc29uXG4gICAgICovXG4gICAgZXF1YWxzKG9iajogYW55LCAuLi5leGNlcHRpb25zOiBzdHJpbmdbXSk6IGJvb2xlYW47XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBSZXR1cm5zIHRoZSBzZXJpYWxpemVkIG1vZGVsIGFjY29yZGluZyB0byB0aGUgY3VycmVudGx5IGRlZmluZWQge0BsaW5rIFNlcmlhbGl6ZXJ9XG4gICAgICovXG4gICAgc2VyaWFsaXplKCk6IHN0cmluZztcblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IE92ZXJyaWRlIHRoZSBpbXBsZW1lbnRhdGlvbiBmb3IganMncyAndG9TdHJpbmcoKScgd2hpY2ggc3Vja3MuLi5cbiAgICAgKiBAb3ZlcnJpZGVcbiAgICAgKi9cbiAgICB0b1N0cmluZygpOiBzdHJpbmc7XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBEZWZpbmVzIGEgZGVmYXVsdCBpbXBsZW1lbnRhdGlvbiBmb3Igb2JqZWN0IGhhc2guIFJlbGllcyBvbiBhIHZlcnkgYmFzaWMgaW1wbGVtZW50YXRpb24gYmFzZWQgb24gSmF2YSdzIHN0cmluZyBoYXNoO1xuICAgICAqL1xuICAgIGhhc2goKTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgRGVzZXJpYWxpemVzIGEgTW9kZWxcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gc3RyXG4gICAgICpcbiAgICAgKiBAdGhyb3dzIHtFcnJvcn0gSWYgaXQgZmFpbHMgdG8gcGFyc2UgdGhlIHN0cmluZywgb3IgaWYgaXQgZmFpbHMgdG8gYnVpbGQgdGhlIG1vZGVsXG4gICAgICovXG4gICAgc3RhdGljIGRlc2VyaWFsaXplKHN0cjogc3RyaW5nKTogYW55O1xuXG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgUmVwb3B1bGF0ZXMgdGhlIE9iamVjdCBwcm9wZXJ0aWVzIHdpdGggdGhlIG9uZXMgZnJvbSB0aGUgbmV3IG9iamVjdFxuICAgICAqIEBkZXNjcmlwdGlvbiBJdGVyYXRlcyBhbGwgY29tbW9uIHByb3BlcnRpZXMgb2Ygb2JqIChpZiBleGlzdGluZykgYW5kIHNlbGYsIGFuZCBjb3BpZXMgdGhlbSBvbnRvIHNlbGZcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7VH0gc2VsZlxuICAgICAqIEBwYXJhbSB7VCB8IFJlY29yZDxzdHJpbmcsIGFueT59IFtvYmpdXG4gICAgICpcbiAgICAgKi9cbiAgICBzdGF0aWMgZnJvbU9iamVjdDxUIGV4dGVuZHMgTW9kZWw+KFxuICAgICAgc2VsZjogVCxcbiAgICAgIG9iaj86IFQgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgKTogVDtcblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IFJlcG9wdWxhdGVzIHRoZSBpbnN0YW5jZSB3aXRoIHRoZSBvbmVzIGZyb20gdGhlIG5ldyBNb2RlbCBPYmplY3RcbiAgICAgKiBAZGVzY3JpcHRpb24gSXRlcmF0ZXMgYWxsIGNvbW1vbiBwcm9wZXJ0aWVzIG9mIG9iaiAoaWYgZXhpc3RpbmcpIGFuZCBzZWxmLCBhbmQgY29waWVzIHRoZW0gb250byBzZWxmLlxuICAgICAqIElzIGF3YXJlIG9mIG5lc3RlZCBNb2RlbCBPYmplY3RzIGFuZCByZWJ1aWxkcyB0aGVtIGFsc28uXG4gICAgICogV2hlbiBMaXN0IHByb3BlcnRpZXMgYXJlIGRlY29yYXRlZCB3aXRoIHtAbGluayBsaXN0fSwgdGhleSBsaXN0IGl0ZW1zIHdpbGwgYWxzbyBiZSByZWJ1aWx0XG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1R9IHNlbGZcbiAgICAgKiBAcGFyYW0ge1QgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+fSBbb2JqXVxuICAgICAqXG4gICAgICovXG4gICAgc3RhdGljIGZyb21Nb2RlbDxUIGV4dGVuZHMgTW9kZWw+KFxuICAgICAgc2VsZjogVCxcbiAgICAgIG9iaj86IFQgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+XG4gICAgKTogVDtcblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IFNldHMgdGhlIEdsb2JhbCB7QGxpbmsgTW9kZWxCdWlsZGVyRnVuY3Rpb259XG4gICAgICogQHBhcmFtIHtNb2RlbEJ1aWxkZXJGdW5jdGlvbn0gW2J1aWxkZXJdXG4gICAgICovXG4gICAgc3RhdGljIHNldEJ1aWxkZXIoYnVpbGRlcj86IE1vZGVsQnVpbGRlckZ1bmN0aW9uKTogdm9pZDtcblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgY3VycmVudCBnbG9iYWwge0BsaW5rIE1vZGVsQnVpbGRlckZ1bmN0aW9ufVxuICAgICAqL1xuICAgIHN0YXRpYyBnZXRCdWlsZGVyKCk6IE1vZGVsQnVpbGRlckZ1bmN0aW9uIHwgdW5kZWZpbmVkO1xuXG4gICAgLyoqXG4gICAgICogUmV0dXJucyB0aGUgY3VycmVudCB7QGxpbmsgTW9kZWxSZWdpc3RyeU1hbmFnZXJ9XG4gICAgICpcbiAgICAgKiBAcmV0dXJuIE1vZGVsUmVnaXN0cnksIGRlZmF1bHRzIHRvIHtAbGluayBNb2RlbFJlZ2lzdHJ5TWFuYWdlcn1cbiAgICAgKi9cbiAgICBwcml2YXRlIHN0YXRpYyBnZXRSZWdpc3RyeTtcblxuICAgIC8qKlxuICAgICAqIFJldHVybnMgdGhlIGN1cnJlbnQgYWN0aW5nTW9kZWxSZWdpc3RyeVxuICAgICAqXG4gICAgICogQHBhcmFtIHtCdWlsZGVyUmVnaXN0cnl9IG1vZGVsUmVnaXN0cnkgdGhlIG5ldyBpbXBsZW1lbnRhdGlvbiBvZiBSZWdpc3RyeVxuICAgICAqL1xuICAgIHN0YXRpYyBzZXRSZWdpc3RyeShtb2RlbFJlZ2lzdHJ5OiBCdWlsZGVyUmVnaXN0cnk8YW55Pik6IHZvaWQ7XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSByZWdpc3RlciBuZXcgTW9kZWxzXG4gICAgICogQHBhcmFtIHthbnl9IGNvbnN0cnVjdG9yXG4gICAgICogQHBhcmFtIHtzdHJpbmd9IFtuYW1lXSB3aGVuIG5vdCBkZWZpbmVkLCB0aGUgbmFtZSBvZiB0aGUgY29uc3RydWN0b3Igd2lsbCBiZSB1c2VkXG4gICAgICpcbiAgICAgKiBAc2VlIE1vZGVsUmVnaXN0cnlcbiAgICAgKi9cbiAgICBzdGF0aWMgcmVnaXN0ZXI8VCBleHRlbmRzIE1vZGVsPihcbiAgICAgIGNvbnN0cnVjdG9yOiBNb2RlbENvbnN0cnVjdG9yPFQ+LFxuICAgICAgbmFtZT86IHN0cmluZ1xuICAgICk6IHZvaWQ7XG5cbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBHZXRzIGEgcmVnaXN0ZXJlZCBNb2RlbCB7QGxpbmsgTW9kZWxDb25zdHJ1Y3Rvcn1cbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gbmFtZVxuICAgICAqXG4gICAgICogQHNlZSBNb2RlbFJlZ2lzdHJ5XG4gICAgICovXG4gICAgc3RhdGljIGdldDxUIGV4dGVuZHMgTW9kZWw+KG5hbWU6IHN0cmluZyk6IE1vZGVsQ29uc3RydWN0b3I8VD4gfCB1bmRlZmluZWQ7XG5cbiAgICAvKipcbiAgICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IG9ialxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBbY2xhenpdIHdoZW4gcHJvdmlkZWQsIGl0IHdpbGwgYXR0ZW1wdCB0byBmaW5kIHRoZSBtYXRjaGluZyBjb25zdHJ1Y3RvclxuICAgICAqXG4gICAgICogQHRocm93cyBFcnJvciBJZiBjbGF6eiBpcyBub3QgZm91bmQsIG9yIG9iaiBpcyBub3QgYSB7QGxpbmsgTW9kZWx9IG1lYW5pbmcgaXQgaGFzIG5vIHtAbGluayBNb2RlbEtleXMuQU5DSE9SfSBwcm9wZXJ0eVxuICAgICAqXG4gICAgICogQHNlZSBNb2RlbFJlZ2lzdHJ5XG4gICAgICovXG4gICAgc3RhdGljIGJ1aWxkPFQgZXh0ZW5kcyBNb2RlbD4ob2JqPzogUmVjb3JkPHN0cmluZywgYW55PiwgY2xheno/OiBzdHJpbmcpOiBUO1xuXG4gICAgc3RhdGljIGdldE1ldGFkYXRhPFYgZXh0ZW5kcyBNb2RlbD4obW9kZWw6IFYpOiBhbnk7XG5cbiAgICBzdGF0aWMgZ2V0QXR0cmlidXRlczxWIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBDb25zdHJ1Y3RvcjxWPiB8IFYpOiBzdHJpbmdbXTtcblxuICAgIHN0YXRpYyBlcXVhbHM8TSBleHRlbmRzIE1vZGVsPihcbiAgICAgIG9iajE6IE0sXG4gICAgICBvYmoyOiBNLFxuICAgICAgLi4uZXhjZXB0aW9uczogYW55W11cbiAgICApOiBib29sZWFuO1xuXG4gICAgc3RhdGljIGhhc0Vycm9yczxNIGV4dGVuZHMgTW9kZWw+KFxuICAgICAgbW9kZWw6IE0sXG4gICAgICAuLi5wcm9wc1RvSWdub3JlOiBzdHJpbmdbXVxuICAgICk6IE1vZGVsRXJyb3JEZWZpbml0aW9uIHwgdW5kZWZpbmVkO1xuXG4gICAgc3RhdGljIHNlcmlhbGl6ZTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKTogYW55O1xuXG4gICAgc3RhdGljIGhhc2g8TSBleHRlbmRzIE1vZGVsPihtb2RlbDogTSk6IGFueTtcblxuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IEJ1aWxkcyB0aGUga2V5IHRvIHN0b3JlIGFzIE1ldGFkYXRhIHVuZGVyIFJlZmxlY3Rpb25zXG4gICAgICogQGRlc2NyaXB0aW9uIGNvbmNhdGVuYXRlcyB7QGxpbmsgTW9kZWxLZXlzI1JFRkxFQ1R9IHdpdGggdGhlIHByb3ZpZGVkIGtleVxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBzdHJcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5KHN0cjogc3RyaW5nKTogc3RyaW5nO1xuXG4gICAgLyoqXG4gICAgICogQGRlc2NyaXB0aW9uIERldGVybWluZXMgaWYgYW4gb2JqZWN0IGlzIGEgbW9kZWwgaW5zdGFuY2Ugb3IgaGFzIG1vZGVsIG1ldGFkYXRhXG4gICAgICogQHN1bW1hcnkgQ2hlY2tzIHdoZXRoZXIgYSBnaXZlbiBvYmplY3QgaXMgZWl0aGVyIGFuIGluc3RhbmNlIG9mIHRoZSBNb2RlbCBjbGFzcyBvclxuICAgICAqIGhhcyBtb2RlbCBtZXRhZGF0YSBhdHRhY2hlZCB0byBpdC4gVGhpcyBmdW5jdGlvbiBpcyBlc3NlbnRpYWwgZm9yIHNlcmlhbGl6YXRpb24gYW5kXG4gICAgICogZGVzZXJpYWxpemF0aW9uIHByb2Nlc3NlcywgYXMgaXQgaGVscHMgaWRlbnRpZnkgbW9kZWwgb2JqZWN0cyB0aGF0IG5lZWQgc3BlY2lhbCBoYW5kbGluZy5cbiAgICAgKiBJdCBzYWZlbHkgaGFuZGxlcyBwb3RlbnRpYWwgZXJyb3JzIGR1cmluZyBtZXRhZGF0YSByZXRyaWV2YWwuXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge1JlY29yZDxzdHJpbmcsIGFueT59IHRhcmdldCAtIFRoZSBvYmplY3QgdG8gY2hlY2tcbiAgICAgKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBvYmplY3QgaXMgYSBtb2RlbCBpbnN0YW5jZSBvciBoYXMgbW9kZWwgbWV0YWRhdGEsIGZhbHNlIG90aGVyd2lzZVxuICAgICAqXG4gICAgICogQGV4YW1wbGVcbiAgICAgKiBgYGB0eXBlc2NyaXB0XG4gICAgICogLy8gQ2hlY2sgaWYgYW4gb2JqZWN0IGlzIGEgbW9kZWxcbiAgICAgKiBjb25zdCB1c2VyID0gbmV3IFVzZXIoeyBuYW1lOiBcIkpvaG5cIiB9KTtcbiAgICAgKiBjb25zdCBpc1VzZXJNb2RlbCA9IGlzTW9kZWwodXNlcik7IC8vIHRydWVcbiAgICAgKlxuICAgICAqIC8vIENoZWNrIGEgcGxhaW4gb2JqZWN0XG4gICAgICogY29uc3QgcGxhaW5PYmplY3QgPSB7IG5hbWU6IFwiSm9oblwiIH07XG4gICAgICogY29uc3QgaXNQbGFpbk9iamVjdE1vZGVsID0gaXNNb2RlbChwbGFpbk9iamVjdCk7IC8vIGZhbHNlXG4gICAgICogYGBgXG4gICAgICovXG4gICAgc3RhdGljIGlzTW9kZWwodGFyZ2V0OiBSZWNvcmQ8c3RyaW5nLCBhbnk+KTogYm9vbGVhbjtcblxuICAgIC8qKlxuICAgICAqIEBkZXNjcmlwdGlvbiBDaGVja3MgaWYgYSBwcm9wZXJ0eSBvZiBhIG1vZGVsIGlzIGl0c2VsZiBhIG1vZGVsIG9yIGhhcyBhIG1vZGVsIHR5cGVcbiAgICAgKiBAc3VtbWFyeSBEZXRlcm1pbmVzIHdoZXRoZXIgYSBzcGVjaWZpYyBwcm9wZXJ0eSBvZiBhIG1vZGVsIGluc3RhbmNlIGlzIGVpdGhlciBhIG1vZGVsIGluc3RhbmNlXG4gICAgICogb3IgaGFzIGEgdHlwZSB0aGF0IGlzIHJlZ2lzdGVyZWQgYXMgYSBtb2RlbC4gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIGZvciBtb2RlbCBzZXJpYWxpemF0aW9uXG4gICAgICogYW5kIGRlc2VyaWFsaXphdGlvbiB0byBwcm9wZXJseSBoYW5kbGUgbmVzdGVkIG1vZGVscy5cbiAgICAgKiBAdGVtcGxhdGUgTSBleHRlbmRzIHtAbGluayBNb2RlbH1cbiAgICAgKiBAcGFyYW0ge019IHRhcmdldCAtIFRoZSBtb2RlbCBpbnN0YW5jZSB0byBjaGVja1xuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBhdHRyaWJ1dGUgLSBUaGUgcHJvcGVydHkgbmFtZSB0byBjaGVja1xuICAgICAqIEByZXR1cm4ge2Jvb2xlYW4gfCBzdHJpbmcgfCB1bmRlZmluZWR9IFJldHVybnMgdHJ1ZSBpZiB0aGUgcHJvcGVydHkgaXMgYSBtb2RlbCBpbnN0YW5jZSxcbiAgICAgKiB0aGUgbW9kZWwgbmFtZSBpZiB0aGUgcHJvcGVydHkgaGFzIGEgbW9kZWwgdHlwZSwgb3IgdW5kZWZpbmVkIGlmIG5vdCBhIG1vZGVsXG4gICAgICovXG4gICAgc3RhdGljIGlzUHJvcGVydHlNb2RlbDxNIGV4dGVuZHMgTW9kZWw+KFxuICAgICAgdGFyZ2V0OiBNLFxuICAgICAgYXR0cmlidXRlOiBzdHJpbmdcbiAgICApOiBib29sZWFuIHwgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICB9XG59XG4iLCJpbXBvcnQge1xuICBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUsXG4gIFJlcG9zaXRvcnksXG4gIFNlcmlhbGl6YXRpb25FcnJvcixcbn0gZnJvbSBcIi4uL3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgREJLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1RyYW5zaWVudDxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gIHJldHVybiAhIShcbiAgICBSZWZsZWN0LmdldE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KERCS2V5cy5UUkFOU0lFTlQpLCBtb2RlbC5jb25zdHJ1Y3RvcikgfHxcbiAgICBSZWZsZWN0LmdldE1ldGFkYXRhKFxuICAgICAgUmVwb3NpdG9yeS5rZXkoREJLZXlzLlRSQU5TSUVOVCksXG4gICAgICBNb2RlbC5nZXQobW9kZWwuY29uc3RydWN0b3IubmFtZSkgYXMgYW55XG4gICAgKVxuICApO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gbW9kZWxUb1RyYW5zaWVudDxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogTVxuKTogeyBtb2RlbDogTTsgdHJhbnNpZW50PzogUmVjb3JkPHN0cmluZywgYW55PiB9IHtcbiAgaWYgKCFpc1RyYW5zaWVudChtb2RlbCkpIHJldHVybiB7IG1vZGVsOiBtb2RlbCB9O1xuICBjb25zdCBkZWNzOiBSZWNvcmQ8c3RyaW5nLCBhbnlbXT4gPSBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUoXG4gICAgbW9kZWwsXG4gICAgdW5kZWZpbmVkLFxuICAgIFJlcG9zaXRvcnkua2V5KERCS2V5cy5UUkFOU0lFTlQpXG4gICkgYXMgUmVjb3JkPHN0cmluZywgYW55W10+O1xuXG4gIGNvbnN0IHJlc3VsdCA9IE9iamVjdC5lbnRyaWVzKGRlY3MpLnJlZHVjZShcbiAgICAoXG4gICAgICBhY2N1bTogeyBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PjsgdHJhbnNpZW50PzogUmVjb3JkPHN0cmluZywgYW55PiB9LFxuICAgICAgW2ssIHZhbF1cbiAgICApID0+IHtcbiAgICAgIGNvbnN0IHRyYW5zaWVudCA9IHZhbC5maW5kKChlbCkgPT4gZWwua2V5ID09PSBcIlwiKTtcbiAgICAgIGlmICh0cmFuc2llbnQpIHtcbiAgICAgICAgYWNjdW0udHJhbnNpZW50ID0gYWNjdW0udHJhbnNpZW50IHx8IHt9O1xuICAgICAgICB0cnkge1xuICAgICAgICAgIGFjY3VtLnRyYW5zaWVudFtrXSA9IG1vZGVsW2sgYXMga2V5b2YgTV07XG4gICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICB0aHJvdyBuZXcgU2VyaWFsaXphdGlvbkVycm9yKFxuICAgICAgICAgICAgYEZhaWxlZCB0byBzZXJpYWxpemUgdHJhbnNpZW50IHByb3BlcnR5ICR7a306ICR7ZX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWNjdW0ubW9kZWwgPSBhY2N1bS5tb2RlbCB8fCB7fTtcbiAgICAgICAgYWNjdW0ubW9kZWxba10gPSAobW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55Pilba107XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSxcbiAgICB7fSBhcyB7IG1vZGVsOiBSZWNvcmQ8c3RyaW5nLCBhbnk+OyB0cmFuc2llbnQ/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IH1cbiAgKTtcbiAgcmVzdWx0Lm1vZGVsID0gTW9kZWwuYnVpbGQocmVzdWx0Lm1vZGVsLCBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lKTtcbiAgcmV0dXJuIHJlc3VsdCBhcyB7IG1vZGVsOiBNOyB0cmFuc2llbnQ/OiBSZWNvcmQ8c3RyaW5nLCBhbnk+IH07XG59XG4iXSwibmFtZXMiOlsiTW9kZWxLZXlzIiwiUmVhZE9ubHlWYWxpZGF0b3IiLCJWYWxpZGF0b3IiLCJpc0VxdWFsIiwiX19kZWNvcmF0ZSIsInZhbGlkYXRvciIsIlRpbWVzdGFtcFZhbGlkYXRvciIsIkRlY29yYXRvck1lc3NhZ2VzIiwiVmFsaWRhdGlvbiIsIk9wZXJhdGlvbktleXMiLCJCdWxrQ3J1ZE9wZXJhdGlvbktleXMiLCJIYXNoaW5nIiwicHJvcE1ldGFkYXRhIiwiYXBwbHkiLCJSZWZsZWN0aW9uIiwiT2JqZWN0QWNjdW11bGF0b3IiLCJzZiIsIkRlY29yYXRpb24iLCJkYXRlIiwicmVxdWlyZWQiLCJ0eXBlIiwibWV0YWRhdGEiLCJWYWxpZGF0aW9uS2V5cyIsIlJlc2VydmVkTW9kZWxzIiwiTW9kZWxFcnJvckRlZmluaXRpb24iLCJNb2RlbCIsInZhbGlkYXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7SUFFQTs7Ozs7SUFLRztBQUNVLFVBQUEsTUFBTSxHQUFHO0lBQ3BCLElBQUEsT0FBTyxFQUFFLENBQUEsRUFBR0EsNkJBQVMsQ0FBQyxPQUFPLENBQWMsWUFBQSxDQUFBO0lBQzNDLElBQUEsVUFBVSxFQUFFLFlBQVk7SUFDeEIsSUFBQSxLQUFLLEVBQUUsUUFBUTtJQUNmLElBQUEsRUFBRSxFQUFFLElBQUk7SUFDUixJQUFBLEtB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
2757
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGItZGVjb3JhdG9ycy5janMiLCJzb3VyY2VzIjpbIi4uL3NyYy9tb2RlbC9jb25zdGFudHMudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi9jb25zdGFudHMudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi92YWxpZGF0b3JzL1JlYWRPbmx5VmFsaWRhdG9yLnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vdmFsaWRhdG9ycy9UaW1lc3RhbXBWYWxpZGF0b3IudHMiLCIuLi9zcmMvdmFsaWRhdGlvbi92YWxpZGF0b3JzL1VwZGF0ZVZhbGlkYXRvci50cyIsIi4uL3NyYy92YWxpZGF0aW9uL3ZhbGlkYXRpb24udHMiLCIuLi9zcmMvb3BlcmF0aW9ucy9jb25zdGFudHMudHMiLCIuLi9zcmMvb3BlcmF0aW9ucy9PcGVyYXRpb25zUmVnaXN0cnkudHMiLCIuLi9zcmMvb3BlcmF0aW9ucy9PcGVyYXRpb25zLnRzIiwiLi4vc3JjL29wZXJhdGlvbnMvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L2Vycm9ycy50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L3V0aWxzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvY29uc3RhbnRzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvQ29udGV4dC50cyIsIi4uL3NyYy9yZXBvc2l0b3J5L3dyYXBwZXJzLnRzIiwiLi4vc3JjL2lkZW50aXR5L3V0aWxzLnRzIiwiLi4vc3JjL3JlcG9zaXRvcnkvQmFzZVJlcG9zaXRvcnkudHMiLCIuLi9zcmMvcmVwb3NpdG9yeS9SZXBvc2l0b3J5LnRzIiwiLi4vc3JjL3ZhbGlkYXRpb24vZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9pZGVudGl0eS9kZWNvcmF0b3JzLnRzIiwiLi4vc3JjL21vZGVsL3ZhbGlkYXRpb24udHMiLCIuLi9zcmMvbW9kZWwvZGVjb3JhdG9ycy50cyIsIi4uL3NyYy9tb2RlbC9vdmVycmlkZXMudHMiLCIuLi9zcmMvbW9kZWwvdXRpbHMudHMiLCIuLi9zcmMvaW5kZXgudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgTW9kZWxLZXlzIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEYXRhYmFzZSByZWZsZWN0aW9uIGtleXNcbiAqIEBzdW1tYXJ5IENvbGxlY3Rpb24gb2Yga2V5cyB1c2VkIGZvciByZWZsZWN0aW9uIG1ldGFkYXRhIGluIGRhdGFiYXNlIG9wZXJhdGlvbnNcbiAqIEBjb25zdCBEQktleXNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgREJLZXlzID0ge1xuICBSRUZMRUNUOiBgJHtNb2RlbEtleXMuUkVGTEVDVH1wZXJzaXN0ZW5jZS5gLFxuICBSRVBPU0lUT1JZOiBcInJlcG9zaXRvcnlcIixcbiAgQ0xBU1M6IFwiX2NsYXNzXCIsXG4gIElEOiBcImlkXCIsXG4gIElOREVYOiBcImluZGV4XCIsXG4gIFVOSVFVRTogXCJ1bmlxdWVcIixcbiAgU0VSSUFMSVpFOiBcInNlcmlhbGl6ZVwiLFxuICBSRUFET05MWTogXCJyZWFkb25seVwiLFxuICBUSU1FU1RBTVA6IFwidGltZXN0YW1wXCIsXG4gIFRSQU5TSUVOVDogXCJ0cmFuc2llbnRcIixcbiAgSEFTSDogXCJoYXNoXCIsXG4gIENPTVBPU0VEOiBcImNvbXBvc2VkXCIsXG4gIFZFUlNJT046IFwidmVyc2lvblwiLFxuICBPUklHSU5BTDogXCJfX29yaWdpbmFsT2JqXCIsXG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IHNlcGFyYXRvciBjaGFyYWN0ZXIgZm9yIGNvbXBvc2l0ZSBpbmRleGVzXG4gKiBAc3VtbWFyeSBUaGUgZGVmYXVsdCBzZXBhcmF0b3IgY2hhcmFjdGVyIHVzZWQgd2hlbiBjb25jYXRlbmF0aW5nIG11bHRpcGxlIGZpZWxkcyBpbnRvIGEgc2luZ2xlIGluZGV4XG4gKiBAY29uc3QgRGVmYXVsdFNlcGFyYXRvclxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBjb25zdCBEZWZhdWx0U2VwYXJhdG9yID0gXCJfXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgZm9ybWF0IGZvciB0aW1lc3RhbXAgZmllbGRzXG4gKiBAc3VtbWFyeSBTdGFuZGFyZCBkYXRlIGZvcm1hdCBzdHJpbmcgdXNlZCBmb3IgdGltZXN0YW1wIGZpZWxkcyBpbiBkYXRhYmFzZSBtb2RlbHNcbiAqIEBjb25zdCBERUZBVUxUX1RJTUVTVEFNUF9GT1JNQVRcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9USU1FU1RBTVBfRk9STUFUID0gXCJkZC9NTS95eXl5IEhIOm1tOnNzOlNcIjtcbiIsImltcG9ydCB7IERCS2V5cyB9IGZyb20gXCIuLi9tb2RlbC9jb25zdGFudHNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29sbGVjdGlvbiBvZiBkZWZhdWx0IGVycm9yIG1lc3NhZ2VzIHVzZWQgYnkgdmFsaWRhdG9ycy5cbiAqIEBzdW1tYXJ5IEhvbGRzIHRoZSBkZWZhdWx0IGVycm9yIG1lc3NhZ2VzIGZvciB2YXJpb3VzIHZhbGlkYXRpb24gc2NlbmFyaW9zIGluY2x1ZGluZyBJRCB2YWxpZGF0aW9uLCByZWFkb25seSBwcm9wZXJ0aWVzLCBhbmQgdGltZXN0YW1wcy5cbiAqIEB0eXBlZGVmIHtPYmplY3R9IEVycm9yTWVzc2FnZXNcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBJRCAtIEVycm9yIG1lc3NhZ2VzIGZvciBJRCB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gSUQuSU5WQUxJRCAtIEVycm9yIG1lc3NhZ2Ugd2hlbiBhbiBJRCBpcyBpbnZhbGlkXG4gKiBAcHJvcGVydHkge3N0cmluZ30gSUQuUkVRVUlSRUQgLSBFcnJvciBtZXNzYWdlIHdoZW4gYW4gSUQgaXMgbWlzc2luZ1xuICogQHByb3BlcnR5IHtPYmplY3R9IFJFQURPTkxZIC0gRXJyb3IgbWVzc2FnZXMgZm9yIHJlYWRvbmx5IHByb3BlcnRpZXNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBSRUFET05MWS5JTlZBTElEIC0gRXJyb3IgbWVzc2FnZSB3aGVuIGF0dGVtcHRpbmcgdG8gdXBkYXRlIGEgcmVhZG9ubHkgcHJvcGVydHlcbiAqIEBwcm9wZXJ0eSB7T2JqZWN0fSBUSU1FU1RBTVAgLSBFcnJvciBtZXNzYWdlcyBmb3IgdGltZXN0YW1wIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUSU1FU1RBTVAuUkVRVUlSRUQgLSBFcnJvciBtZXNzYWdlIHdoZW4gYSB0aW1lc3RhbXAgaXMgbWlzc2luZ1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFRJTUVTVEFNUC5EQVRFIC0gRXJyb3IgbWVzc2FnZSB3aGVuIGEgdGltZXN0YW1wIGlzIG5vdCBhIHZhbGlkIGRhdGVcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUSU1FU1RBTVAuSU5WQUxJRCAtIEVycm9yIG1lc3NhZ2Ugd2hlbiBhIHRpbWVzdGFtcCBpcyBub3QgaW5jcmVhc2luZ1xuICogQGNvbnN0IERFRkFVTFRfRVJST1JfTUVTU0FHRVNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6dmFsaWRhdGlvblxuICovXG5leHBvcnQgY29uc3QgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyA9IHtcbiAgSUQ6IHtcbiAgICBJTlZBTElEOiBcIlRoaXMgSWQgaXMgaW52YWxpZFwiLFxuICAgIFJFUVVJUkVEOiBcIlRoZSBJZCBpcyBtYW5kYXRvcnlcIixcbiAgfSxcbiAgUkVBRE9OTFk6IHtcbiAgICBJTlZBTElEOiBcIlRoaXMgY2Fubm90IGJlIHVwZGF0ZWRcIixcbiAgfSxcbiAgVElNRVNUQU1QOiB7XG4gICAgUkVRVUlSRUQ6IFwiVGltZXN0YW1wIGlzIE1hbmRhdG9yeVwiLFxuICAgIERBVEU6IFwiVGhlIFRpbWVzdGFtcCBtdXN0IHRoZSBhIHZhbGlkIGRhdGVcIixcbiAgICBJTlZBTElEOiBcIlRoaXMgdmFsdWUgbXVzdCBhbHdheXMgaW5jcmVhc2VcIixcbiAgfSxcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENvbnN0YW50cyB1c2VkIGZvciByZWZsZWN0aW9uLWJhc2VkIHZhbGlkYXRpb24gZHVyaW5nIHVwZGF0ZSBvcGVyYXRpb25zLlxuICogQHN1bW1hcnkgS2V5cyB1c2VkIGZvciBzdG9yaW5nIGFuZCByZXRyaWV2aW5nIHZhbGlkYXRpb24gbWV0YWRhdGEgb24gbW9kZWwgcHJvcGVydGllcyBkdXJpbmcgdXBkYXRlIG9wZXJhdGlvbnMuXG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBWYWxpZGF0aW9uS2V5c1xuICogQHByb3BlcnR5IHtzdHJpbmd9IFJFRkxFQ1QgLSBCYXNlIHJlZmxlY3Rpb24ga2V5IHByZWZpeCBmb3IgdXBkYXRlIHZhbGlkYXRpb25cbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBUSU1FU1RBTVAgLSBLZXkgZm9yIHRpbWVzdGFtcCB2YWxpZGF0aW9uXG4gKiBAcHJvcGVydHkge3N0cmluZ30gUkVBRE9OTFkgLSBLZXkgZm9yIHJlYWRvbmx5IHByb3BlcnR5IHZhbGlkYXRpb25cbiAqIEBjb25zdCBVcGRhdGVWYWxpZGF0aW9uS2V5c1xuICogQG1lbWJlck9mIG1vZHVsZTp2YWxpZGF0aW9uXG4gKi9cbmV4cG9ydCBjb25zdCBVcGRhdGVWYWxpZGF0aW9uS2V5cyA9IHtcbiAgUkVGTEVDVDogXCJkYi51cGRhdGUudmFsaWRhdGlvbi5cIixcbiAgVElNRVNUQU1QOiBEQktleXMuVElNRVNUQU1QLFxuICBSRUFET05MWTogREJLZXlzLlJFQURPTkxZLFxufTtcbiIsImltcG9ydCB7IHZhbGlkYXRvciwgVmFsaWRhdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVXBkYXRlVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBpc0VxdWFsIH0gZnJvbSBcIkBkZWNhZi10cy9yZWZsZWN0aW9uXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgdmFsaWRhdG9yIHRoYXQgZW5zdXJlcyBwcm9wZXJ0aWVzIG1hcmtlZCBhcyByZWFkb25seSBjYW5ub3QgYmUgbW9kaWZpZWQgZHVyaW5nIHVwZGF0ZXMuXG4gKiBAc3VtbWFyeSBWYWxpZGF0b3IgZm9yIHRoZSB7QGxpbmsgcmVhZG9ubHl9IGRlY29yYXRvciB0aGF0IGNoZWNrcyBpZiBhIHZhbHVlIGhhcyBiZWVuIGNoYW5nZWQgZHVyaW5nIGFuIHVwZGF0ZSBvcGVyYXRpb24uIEl0IGNvbXBhcmVzIHRoZSBuZXcgdmFsdWUgd2l0aCB0aGUgb2xkIHZhbHVlIGFuZCByZXR1cm5zIGFuIGVycm9yIG1lc3NhZ2UgaWYgdGhleSBhcmUgbm90IGVxdWFsLlxuICogQHBhcmFtIHthbnl9IHZhbHVlIC0gVGhlIHZhbHVlIHRvIGJlIHZhbGlkYXRlZFxuICogQHBhcmFtIHthbnl9IG9sZFZhbHVlIC0gVGhlIHByZXZpb3VzIHZhbHVlIHRvIGNvbXBhcmUgYWdhaW5zdFxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSAtIE9wdGlvbmFsIGN1c3RvbSBlcnJvciBtZXNzYWdlXG4gKiBAY2xhc3MgUmVhZE9ubHlWYWxpZGF0b3JcbiAqIEBleGFtcGxlXG4gKiAvLyBVc2luZyBSZWFkT25seVZhbGlkYXRvciB3aXRoIGEgcmVhZG9ubHkgcHJvcGVydHlcbiAqIGNsYXNzIFVzZXIge1xuICogICBAcmVhZG9ubHkoKVxuICogICBpZDogc3RyaW5nO1xuICogICBcbiAqICAgbmFtZTogc3RyaW5nO1xuICogICBcbiAqICAgY29uc3RydWN0b3IoaWQ6IHN0cmluZywgbmFtZTogc3RyaW5nKSB7XG4gKiAgICAgdGhpcy5pZCA9IGlkO1xuICogICAgIHRoaXMubmFtZSA9IG5hbWU7XG4gKiAgIH1cbiAqIH1cbiAqIFxuICogLy8gVGhpcyB3aWxsIHRyaWdnZXIgdmFsaWRhdGlvbiBlcnJvciB3aGVuIHRyeWluZyB0byB1cGRhdGVcbiAqIGNvbnN0IHVzZXIgPSBuZXcgVXNlcignMTIzJywgJ0pvaG4nKTtcbiAqIHVzZXIuaWQgPSAnNDU2JzsgLy8gV2lsbCBiZSBwcmV2ZW50ZWQgYnkgUmVhZE9ubHlWYWxpZGF0b3JcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVXBkYXRlVmFsaWRhdGlvbktleXMuUkVBRE9OTFkpXG5leHBvcnQgY2xhc3MgUmVhZE9ubHlWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3Ige1xuICBjb25zdHJ1Y3RvcigpIHtcbiAgICBzdXBlcihERUZBVUxUX0VSUk9SX01FU1NBR0VTLlJFQURPTkxZLklOVkFMSUQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgYmFzZSB2YWxpZGF0b3IncyBoYXNFcnJvcnMgbWV0aG9kLlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBpcyByZXF1aXJlZCBieSB0aGUgVmFsaWRhdG9yIGludGVyZmFjZSBidXQgbm90IHVzZWQgaW4gdGhpcyB2YWxpZGF0b3IgYXMgdmFsaWRhdGlvbiBvbmx5IGhhcHBlbnMgZHVyaW5nIHVwZGF0ZXMuXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZSAtIFRoZSB2YWx1ZSB0byB2YWxpZGF0ZVxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHNcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfSBBbHdheXMgcmV0dXJucyB1bmRlZmluZWQgYXMgdGhpcyB2YWxpZGF0b3Igb25seSB3b3JrcyBkdXJpbmcgdXBkYXRlc1xuICAgKi9cbiAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICBoYXNFcnJvcnModmFsdWU6IGFueSwgLi4uYXJnczogYW55W10pOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiBhIHZhbHVlIGhhcyBiZWVuIG1vZGlmaWVkIGR1cmluZyBhbiB1cGRhdGUgb3BlcmF0aW9uLlxuICAgKiBAc3VtbWFyeSBWYWxpZGF0ZXMgYSB2YWx1ZSBoYXMgbm90IGNoYW5nZWQgYnkgY29tcGFyaW5nIGl0IHdpdGggdGhlIHByZXZpb3VzIHZhbHVlIHVzaW5nIGRlZXAgZXF1YWxpdHkuXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZSAtIFRoZSBuZXcgdmFsdWUgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHthbnl9IG9sZFZhbHVlIC0gVGhlIG9yaWdpbmFsIHZhbHVlIHRvIGNvbXBhcmUgYWdhaW5zdFxuICAgKiBAcGFyYW0ge3N0cmluZ30gW21lc3NhZ2VdIC0gT3B0aW9uYWwgY3VzdG9tIGVycm9yIG1lc3NhZ2UgdG8gb3ZlcnJpZGUgdGhlIGRlZmF1bHRcbiAgICogQHJldHVybiB7c3RyaW5nIHwgdW5kZWZpbmVkfSBBbiBlcnJvciBtZXNzYWdlIGlmIHZhbGlkYXRpb24gZmFpbHMsIHVuZGVmaW5lZCBvdGhlcndpc2VcbiAgICovXG4gIHB1YmxpYyB1cGRhdGVIYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvbGRWYWx1ZTogYW55LFxuICAgIG1lc3NhZ2U/OiBzdHJpbmcsXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gICAgaWYgKHZhbHVlID09PSB1bmRlZmluZWQpIHJldHVybjtcblxuICAgIHJldHVybiBpc0VxdWFsKHZhbHVlLCBvbGRWYWx1ZSlcbiAgICAgID8gdW5kZWZpbmVkXG4gICAgICA6IHRoaXMuZ2V0TWVzc2FnZShtZXNzYWdlIHx8IHRoaXMubWVzc2FnZSk7XG4gIH1cbn1cbiIsImltcG9ydCB7IHZhbGlkYXRvciwgVmFsaWRhdG9yIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUywgVXBkYXRlVmFsaWRhdGlvbktleXMgfSBmcm9tIFwiLi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgdmFsaWRhdG9yIHRoYXQgZW5zdXJlcyB0aW1lc3RhbXAgdmFsdWVzIGFyZSBvbmx5IHVwZGF0ZWQgd2l0aCBuZXdlciB0aW1lc3RhbXBzLlxuICogQHN1bW1hcnkgVmFsaWRhdGVzIHRoZSB1cGRhdGUgb2YgYSB0aW1lc3RhbXAgYnkgY29tcGFyaW5nIHRoZSBuZXcgdGltZXN0YW1wIHdpdGggdGhlIG9sZCBvbmUsIGVuc3VyaW5nIHRoZSBuZXcgdGltZXN0YW1wIGlzIG1vcmUgcmVjZW50LlxuICogQHBhcmFtIHtEYXRlfHN0cmluZ3xudW1iZXJ9IHZhbHVlIC0gVGhlIHRpbWVzdGFtcCB2YWx1ZSB0byB2YWxpZGF0ZVxuICogQHBhcmFtIHtEYXRlfHN0cmluZ3xudW1iZXJ9IG9sZFZhbHVlIC0gVGhlIHByZXZpb3VzIHRpbWVzdGFtcCB0byBjb21wYXJlIGFnYWluc3RcbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWVzc2FnZV0gLSBPcHRpb25hbCBjdXN0b20gZXJyb3IgbWVzc2FnZVxuICogQGNsYXNzIFRpbWVzdGFtcFZhbGlkYXRvclxuICogQGV4YW1wbGVcbiAqIC8vIFVzaW5nIFRpbWVzdGFtcFZhbGlkYXRvciB3aXRoIGEgdGltZXN0YW1wIHByb3BlcnR5XG4gKiBjbGFzcyBEb2N1bWVudCB7XG4gKiAgIEB0aW1lc3RhbXAoKVxuICogICB1cGRhdGVkQXQ6IERhdGU7XG4gKiAgIFxuICogICB0aXRsZTogc3RyaW5nO1xuICogICBcbiAqICAgY29uc3RydWN0b3IodGl0bGU6IHN0cmluZykge1xuICogICAgIHRoaXMudGl0bGUgPSB0aXRsZTtcbiAqICAgICB0aGlzLnVwZGF0ZWRBdCA9IG5ldyBEYXRlKCk7XG4gKiAgIH1cbiAqIH1cbiAqIFxuICogLy8gVGhpcyB3aWxsIHRyaWdnZXIgdmFsaWRhdGlvbiBlcnJvciB3aGVuIHRyeWluZyB0byB1cGRhdGUgd2l0aCBhbiBvbGRlciB0aW1lc3RhbXBcbiAqIGNvbnN0IGRvYyA9IG5ldyBEb2N1bWVudCgnTXkgRG9jdW1lbnQnKTtcbiAqIGNvbnN0IG9sZERhdGUgPSBuZXcgRGF0ZSgyMDIwLCAwLCAxKTtcbiAqIGRvYy51cGRhdGVkQXQgPSBvbGREYXRlOyAvLyBXaWxsIGJlIHByZXZlbnRlZCBieSBUaW1lc3RhbXBWYWxpZGF0b3JcbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbkB2YWxpZGF0b3IoVXBkYXRlVmFsaWRhdGlvbktleXMuVElNRVNUQU1QKVxuZXhwb3J0IGNsYXNzIFRpbWVzdGFtcFZhbGlkYXRvciBleHRlbmRzIFZhbGlkYXRvciB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIHN1cGVyKERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVElNRVNUQU1QLklOVkFMSUQpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBJbXBsZW1lbnRhdGlvbiBvZiB0aGUgYmFzZSB2YWxpZGF0b3IncyBoYXNFcnJvcnMgbWV0aG9kLlxuICAgKiBAc3VtbWFyeSBUaGlzIG1ldGhvZCBpcyByZXF1aXJlZCBieSB0aGUgVmFsaWRhdG9yIGludGVyZmFjZSBidXQgbm90IHVzZWQgaW4gdGhpcyB2YWxpZGF0b3IgYXMgdmFsaWRhdGlvbiBvbmx5IGhhcHBlbnMgZHVyaW5nIHVwZGF0ZXMuXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZSAtIFRoZSB0aW1lc3RhbXAgdmFsdWUgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gQWx3YXlzIHJldHVybnMgdW5kZWZpbmVkIGFzIHRoaXMgdmFsaWRhdG9yIG9ubHkgd29ya3MgZHVyaW5nIHVwZGF0ZXNcbiAgICovXG4gIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgaGFzRXJyb3JzKHZhbHVlOiBhbnksIC4uLmFyZ3M6IGFueVtdKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBWYWxpZGF0ZXMgdGhhdCBhIHRpbWVzdGFtcCBpcyBuZXdlciB0aGFuIGl0cyBwcmV2aW91cyB2YWx1ZS5cbiAgICogQHN1bW1hcnkgQ2hlY2tzIGlmIGEgdGltZXN0YW1wIGhhcyBiZWVuIHVwZGF0ZWQgd2l0aCBhIG1vcmUgcmVjZW50IHZhbHVlIGJ5IGNvbnZlcnRpbmcgYm90aCB2YWx1ZXMgdG8gRGF0ZSBvYmplY3RzIGFuZCBjb21wYXJpbmcgdGhlbS5cbiAgICogQHBhcmFtIHtEYXRlfHN0cmluZ3xudW1iZXJ9IHZhbHVlIC0gVGhlIG5ldyB0aW1lc3RhbXAgdmFsdWUgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHtEYXRlfHN0cmluZ3xudW1iZXJ9IG9sZFZhbHVlIC0gVGhlIG9yaWdpbmFsIHRpbWVzdGFtcCB0byBjb21wYXJlIGFnYWluc3RcbiAgICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSAtIE9wdGlvbmFsIGN1c3RvbSBlcnJvciBtZXNzYWdlIHRvIG92ZXJyaWRlIHRoZSBkZWZhdWx0XG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gQW4gZXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzIChuZXcgdGltZXN0YW1wIGlzIG5vdCBuZXdlciksIHVuZGVmaW5lZCBvdGhlcndpc2VcbiAgICovXG4gIHB1YmxpYyB1cGRhdGVIYXNFcnJvcnMoXG4gICAgdmFsdWU6IERhdGUgfCBzdHJpbmcgfCBudW1iZXIsXG4gICAgb2xkVmFsdWU6IERhdGUgfCBzdHJpbmcgfCBudW1iZXIsXG4gICAgbWVzc2FnZT86IHN0cmluZ1xuICApOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICAgIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSByZXR1cm47XG5cbiAgICBtZXNzYWdlID0gbWVzc2FnZSB8fCB0aGlzLmdldE1lc3NhZ2UobWVzc2FnZSB8fCB0aGlzLm1lc3NhZ2UpO1xuXG4gICAgdHJ5IHtcbiAgICAgIHZhbHVlID0gbmV3IERhdGUodmFsdWUpO1xuICAgICAgb2xkVmFsdWUgPSBuZXcgRGF0ZShvbGRWYWx1ZSk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgcmV0dXJuIG1lc3NhZ2U7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlIDw9IG9sZFZhbHVlID8gbWVzc2FnZSA6IHVuZGVmaW5lZDtcbiAgfVxufVxuIiwiaW1wb3J0IHtcbiAgREVGQVVMVF9FUlJPUl9NRVNTQUdFUyBhcyBEZWNvcmF0b3JNZXNzYWdlcyxcbiAgVmFsaWRhdG9yLFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEFic3RyYWN0IGJhc2UgY2xhc3MgZm9yIHZhbGlkYXRvcnMgdGhhdCBjb21wYXJlIG5ldyB2YWx1ZXMgd2l0aCBvbGQgdmFsdWVzIGR1cmluZyB1cGRhdGVzLlxuICogQHN1bW1hcnkgQmFzZSBjbGFzcyBmb3IgYW4gVXBkYXRlIHZhbGlkYXRvciB0aGF0IHByb3ZpZGVzIGEgZnJhbWV3b3JrIGZvciBpbXBsZW1lbnRpbmcgdmFsaWRhdGlvbiBsb2dpYyB0aGF0IGNvbXBhcmVzIGEgbmV3IHZhbHVlIHdpdGggaXRzIHByZXZpb3VzIHN0YXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSAtIEVycm9yIG1lc3NhZ2UuIERlZmF1bHRzIHRvIHtAbGluayBEZWNvcmF0b3JNZXNzYWdlcyNERUZBVUxUfVxuICogQHBhcmFtIHtzdHJpbmdbXX0gW2FjY2VwdGVkVHlwZXNdIC0gVGhlIGFjY2VwdGVkIHZhbHVlIHR5cGVzIGJ5IHRoZSBkZWNvcmF0b3JcbiAqIEBjbGFzcyBVcGRhdGVWYWxpZGF0b3JcbiAqIEBleGFtcGxlXG4gKiAvLyBFeHRlbmRpbmcgVXBkYXRlVmFsaWRhdG9yIHRvIGNyZWF0ZSBhIGN1c3RvbSB2YWxpZGF0b3JcbiAqIGNsYXNzIE15Q3VzdG9tVmFsaWRhdG9yIGV4dGVuZHMgVXBkYXRlVmFsaWRhdG9yIHtcbiAqICAgY29uc3RydWN0b3IoKSB7XG4gKiAgICAgc3VwZXIoXCJDdXN0b20gdmFsaWRhdGlvbiBmYWlsZWRcIik7XG4gKiAgIH1cbiAqICAgXG4gKiAgIHB1YmxpYyB1cGRhdGVIYXNFcnJvcnModmFsdWU6IGFueSwgb2xkVmFsdWU6IGFueSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gKiAgICAgLy8gQ3VzdG9tIHZhbGlkYXRpb24gbG9naWNcbiAqICAgICBpZiAodmFsdWUgPT09IG9sZFZhbHVlKSB7XG4gKiAgICAgICByZXR1cm4gdGhpcy5tZXNzYWdlO1xuICogICAgIH1cbiAqICAgICByZXR1cm4gdW5kZWZpbmVkO1xuICogICB9XG4gKiAgIFxuICogICBoYXNFcnJvcnModmFsdWU6IGFueSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XG4gKiAgICAgcmV0dXJuIHVuZGVmaW5lZDsgLy8gTm90IHVzZWQgZm9yIHVwZGF0ZSB2YWxpZGF0b3JzXG4gKiAgIH1cbiAqIH1cbiAqIEBjYXRlZ29yeSBWYWxpZGF0b3JzXG4gKi9cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBVcGRhdGVWYWxpZGF0b3IgZXh0ZW5kcyBWYWxpZGF0b3Ige1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoXG4gICAgbWVzc2FnZTogc3RyaW5nID0gRGVjb3JhdG9yTWVzc2FnZXMuREVGQVVMVCxcbiAgICAuLi5hY2NlcHRlZFR5cGVzOiBzdHJpbmdbXVxuICApIHtcbiAgICBzdXBlcihtZXNzYWdlLCAuLi5hY2NlcHRlZFR5cGVzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQWJzdHJhY3QgbWV0aG9kIHRoYXQgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBzdWJjbGFzc2VzIHRvIHBlcmZvcm0gdXBkYXRlIHZhbGlkYXRpb24uXG4gICAqIEBzdW1tYXJ5IFZhbGlkYXRlcyBhIHZhbHVlIGJ5IGNvbXBhcmluZyBpdCB0byBpdHMgb2xkIHZlcnNpb24gdG8gZGV0ZXJtaW5lIGlmIHRoZSB1cGRhdGUgaXMgdmFsaWQuXG4gICAqIEBwYXJhbSB7YW55fSB2YWx1ZSAtIFRoZSBuZXcgdmFsdWUgdG8gdmFsaWRhdGVcbiAgICogQHBhcmFtIHthbnl9IG9sZFZhbHVlIC0gVGhlIHByZXZpb3VzIHZhbHVlIHRvIGNvbXBhcmUgYWdhaW5zdFxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgdGhhdCBtYXkgYmUgbmVlZGVkIGZvciB2YWxpZGF0aW9uXG4gICAqIEByZXR1cm4ge3N0cmluZyB8IHVuZGVmaW5lZH0gQW4gZXJyb3IgbWVzc2FnZSBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgaWYgdmFsaWRhdGlvbiBwYXNzZXNcbiAgICovXG4gIHB1YmxpYyBhYnN0cmFjdCB1cGRhdGVIYXNFcnJvcnMoXG4gICAgdmFsdWU6IGFueSxcbiAgICBvbGRWYWx1ZTogYW55LFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IHN0cmluZyB8IHVuZGVmaW5lZDtcbn1cbiIsImltcG9ydCB7XG4gIFZhbGlkYXRvcixcbiAgVmFsaWRhdGlvbixcbiAgVmFsaWRhdG9yRGVmaW5pdGlvbixcbiAgSVZhbGlkYXRvclJlZ2lzdHJ5LFxufSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBVcGRhdGVWYWxpZGF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgYSBrZXkgZm9yIHVwZGF0ZSB2YWxpZGF0aW9uIG1ldGFkYXRhLlxuICogQHN1bW1hcnkgQnVpbGRzIHRoZSBrZXkgdG8gc3RvcmUgYXMgbWV0YWRhdGEgdW5kZXIgUmVmbGVjdGlvbnMgZm9yIHVwZGF0ZSB2YWxpZGF0aW9uIGJ5IHByZWZpeGluZyB0aGUgcHJvdmlkZWQga2V5IHdpdGggdGhlIHVwZGF0ZSB2YWxpZGF0aW9uIHByZWZpeC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBrZXkgLSBUaGUgYmFzZSBrZXkgdG8gYmUgcHJlZml4ZWRcbiAqIEByZXR1cm4ge3N0cmluZ30gVGhlIGNvbXBsZXRlIG1ldGFkYXRhIGtleSBmb3IgdXBkYXRlIHZhbGlkYXRpb25cbiAqIEBmdW5jdGlvbiB1cGRhdGVLZXlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5WYWxpZGF0aW9uLnVwZGF0ZUtleSA9IGZ1bmN0aW9uIChrZXk6IHN0cmluZykge1xuICByZXR1cm4gVXBkYXRlVmFsaWRhdGlvbktleXMuUkVGTEVDVCArIGtleTtcbn07XG5cbmRlY2xhcmUgbW9kdWxlIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCIge1xuICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L2Jhbi10cy1jb21tZW50XG4gIC8vIEB0cy1leHBlY3QtZXJyb3JcbiAgZGVjbGFyZSBjbGFzcyBWYWxpZGF0aW9uIHtcbiAgICBwcml2YXRlIHN0YXRpYyBhY3RpbmdWYWxpZGF0b3JSZWdpc3RyeT87XG4gICAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpO1xuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IERlZmluZXMgdGhlIGFjdGluZyBWYWxpZGF0b3JSZWdpc3RyeVxuICAgICAqXG4gICAgICogQHBhcmFtIHtJVmFsaWRhdG9yUmVnaXN0cnl9IHZhbGlkYXRvclJlZ2lzdHJ5IHRoZSBuZXcgaW1wbGVtZW50YXRpb24gb2YgdGhlIHZhbGlkYXRvciBSZWdpc3RyeVxuICAgICAqIEBwYXJhbSB7ZnVuY3Rpb24oVmFsaWRhdG9yKTogVmFsaWRhdG9yfSBbbWlncmF0aW9uSGFuZGxlcl0gdGhlIG1ldGhvZCB0byBtYXAgdGhlIHZhbGlkYXRvciBpZiByZXF1aXJlZDtcbiAgICAgKi9cbiAgICBzdGF0aWMgc2V0UmVnaXN0cnkoXG4gICAgICB2YWxpZGF0b3JSZWdpc3RyeTogSVZhbGlkYXRvclJlZ2lzdHJ5PFZhbGlkYXRvcj4sXG4gICAgICBtaWdyYXRpb25IYW5kbGVyPzogKHZhbGlkYXRvcjogVmFsaWRhdG9yKSA9PiBWYWxpZGF0b3JcbiAgICApOiB2b2lkO1xuICAgIC8qKlxuICAgICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGN1cnJlbnQgVmFsaWRhdG9yUmVnaXN0cnlcbiAgICAgKlxuICAgICAqIEByZXR1cm4gSVZhbGlkYXRvclJlZ2lzdHJ5LCBkZWZhdWx0cyB0byB7QGxpbmsgVmFsaWRhdG9yUmVnaXN0cnl9XG4gICAgICovXG4gICAgcHJpdmF0ZSBzdGF0aWMgZ2V0UmVnaXN0cnk7XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgUmV0cmlldmVzIGEgdmFsaWRhdG9yXG4gICAgICpcbiAgICAgKiBAcGFyYW0ge3N0cmluZ30gdmFsaWRhdG9yS2V5IG9uZSBvZiB0aGUge0BsaW5rIFZhbGlkYXRpb25LZXlzfVxuICAgICAqIEByZXR1cm4ge1ZhbGlkYXRvciB8IHVuZGVmaW5lZH0gdGhlIHJlZ2lzdGVyZWQgVmFsaWRhdG9yIG9yIHVuZGVmaW5lZCBpZiB0aGVyZSBpcyBub25vIG1hdGNoaW5nIHRoZSBwcm92aWRlZCBrZXlcbiAgICAgKi9cbiAgICBzdGF0aWMgZ2V0PFQgZXh0ZW5kcyBWYWxpZGF0b3I+KHZhbGlkYXRvcktleTogc3RyaW5nKTogVCB8IHVuZGVmaW5lZDtcbiAgICAvKipcbiAgICAgKiBAc3VtbWFyeSBSZWdpc3RlcnMgdGhlIHByb3ZpZGVkIHZhbGlkYXRvcnMgb250byB0aGUgcmVnaXN0cnlcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7VFtdIHwgVmFsaWRhdG9yRGVmaW5pdGlvbltdfSB2YWxpZGF0b3JcbiAgICAgKi9cbiAgICBzdGF0aWMgcmVnaXN0ZXI8VCBleHRlbmRzIFZhbGlkYXRvcj4oXG4gICAgICAuLi52YWxpZGF0b3I6IChWYWxpZGF0b3JEZWZpbml0aW9uIHwgVClbXVxuICAgICk6IHZvaWQ7XG4gICAgLyoqXG4gICAgICogQHN1bW1hcnkgQnVpbGRzIHRoZSBrZXkgdG8gc3RvcmUgYXMgTWV0YWRhdGEgdW5kZXIgUmVmbGVjdGlvbnNcbiAgICAgKiBAZGVzY3JpcHRpb24gY29uY2F0ZW5hdGVzIHtAbGluayBWYWxpZGF0aW9uS2V5cyNSRUZMRUNUfSB3aXRoIHRoZSBwcm92aWRlZCBrZXlcbiAgICAgKlxuICAgICAqIEBwYXJhbSB7c3RyaW5nfSBrZXlcbiAgICAgKi9cbiAgICBzdGF0aWMga2V5KGtleTogc3RyaW5nKTogc3RyaW5nO1xuXG4gICAgc3RhdGljIHVwZGF0ZUtleShrZXk6IHN0cmluZyk6IHN0cmluZztcbiAgfVxufVxuIiwiLyoqXG4gKiBAZGVzY3JpcHRpb24gRGF0YWJhc2Ugb3BlcmF0aW9uIGtleSBjb25zdGFudHNcbiAqIEBzdW1tYXJ5IEVudW0gZGVmaW5pbmcgQ1JVRCBvcGVyYXRpb25zIGFuZCB0aGVpciBsaWZlY3ljbGUgcGhhc2VzXG4gKiBAZW51bSB7c3RyaW5nfVxuICogQHJlYWRvbmx5XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGVudW0gT3BlcmF0aW9uS2V5cyB7XG4gIFJFRkxFQ1QgPSBcImRlY2FmLm1vZGVsLmRiLm9wZXJhdGlvbnMuXCIsXG4gIENSRUFURSA9IFwiY3JlYXRlXCIsXG4gIFJFQUQgPSBcInJlYWRcIixcbiAgVVBEQVRFID0gXCJ1cGRhdGVcIixcbiAgREVMRVRFID0gXCJkZWxldGVcIixcbiAgT04gPSBcIm9uLlwiLFxuICBBRlRFUiA9IFwiYWZ0ZXIuXCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFR5cGUgZm9yIGJhc2ljIENSVUQgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgVW5pb24gdHlwZSBvZiB0aGUgZm91ciBiYXNpYyBkYXRhYmFzZSBvcGVyYXRpb25zOiBjcmVhdGUsIHJlYWQsIHVwZGF0ZSwgZGVsZXRlXG4gKiBAdHlwZWRlZiB7c3RyaW5nfSBDcnVkT3BlcmF0aW9uc1xuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCB0eXBlIENydWRPcGVyYXRpb25zID1cbiAgfCBPcGVyYXRpb25LZXlzLkNSRUFURVxuICB8IE9wZXJhdGlvbktleXMuUkVBRFxuICB8IE9wZXJhdGlvbktleXMuVVBEQVRFXG4gIHwgT3BlcmF0aW9uS2V5cy5ERUxFVEU7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEJ1bGsgZGF0YWJhc2Ugb3BlcmF0aW9uIGtleSBjb25zdGFudHNcbiAqIEBzdW1tYXJ5IEVudW0gZGVmaW5pbmcgYnVsayBDUlVEIG9wZXJhdGlvbnMgZm9yIGhhbmRsaW5nIG11bHRpcGxlIHJlY29yZHMgYXQgb25jZVxuICogQGVudW0ge3N0cmluZ31cbiAqIEByZWFkb25seVxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBlbnVtIEJ1bGtDcnVkT3BlcmF0aW9uS2V5cyB7XG4gIENSRUFURV9BTEwgPSBcImNyZWF0ZUFsbFwiLFxuICBSRUFEX0FMTCA9IFwicmVhZEFsbFwiLFxuICBVUERBVEVfQUxMID0gXCJ1cGRhdGVBbGxcIixcbiAgREVMRVRFX0FMTCA9IFwiZGVsZXRlQWxsXCIsXG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFR5cGUgZm9yIGJ1bGsgQ1JVRCBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBVbmlvbiB0eXBlIG9mIHRoZSBmb3VyIGJ1bGsgZGF0YWJhc2Ugb3BlcmF0aW9ucyBmb3IgaGFuZGxpbmcgbXVsdGlwbGUgcmVjb3JkcyBhdCBvbmNlXG4gKiBAdHlwZWRlZiB7c3RyaW5nfSBCdWxrQ3J1ZE9wZXJhdGlvbnNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5leHBvcnQgdHlwZSBCdWxrQ3J1ZE9wZXJhdGlvbnMgPVxuICB8IEJ1bGtDcnVkT3BlcmF0aW9uS2V5cy5DUkVBVEVfQUxMXG4gIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzLlJFQURfQUxMXG4gIHwgQnVsa0NydWRPcGVyYXRpb25LZXlzLlVQREFURV9BTExcbiAgfCBCdWxrQ3J1ZE9wZXJhdGlvbktleXMuREVMRVRFX0FMTDtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gR3JvdXBlZCBDUlVEIG9wZXJhdGlvbnMgZm9yIGRlY29yYXRvciBtYXBwaW5nXG4gKiBAc3VtbWFyeSBNYXBzIG91dCBncm91cHMgb2YgQ1JVRCBvcGVyYXRpb25zIGZvciBlYXNpZXIgbWFwcGluZyBvZiBkZWNvcmF0b3JzXG4gKiBAY29uc3QgREJPcGVyYXRpb25zXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IERCT3BlcmF0aW9uczogUmVjb3JkPHN0cmluZywgQ3J1ZE9wZXJhdGlvbnNbXT4gPSB7XG4gIENSRUFURTogW09wZXJhdGlvbktleXMuQ1JFQVRFXSxcbiAgUkVBRDogW09wZXJhdGlvbktleXMuUkVBRF0sXG4gIFVQREFURTogW09wZXJhdGlvbktleXMuVVBEQVRFXSxcbiAgREVMRVRFOiBbT3BlcmF0aW9uS2V5cy5ERUxFVEVdLFxuICBDUkVBVEVfVVBEQVRFOiBbT3BlcmF0aW9uS2V5cy5DUkVBVEUsIE9wZXJhdGlvbktleXMuVVBEQVRFXSxcbiAgUkVBRF9DUkVBVEU6IFtPcGVyYXRpb25LZXlzLlJFQUQsIE9wZXJhdGlvbktleXMuQ1JFQVRFXSxcbiAgQUxMOiBbXG4gICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICBdLFxufTtcbiIsImltcG9ydCB7IE9wZXJhdGlvbkhhbmRsZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCIuL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgSVJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9JUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgT3BlcmF0aW9ucyB9IGZyb20gXCIuL09wZXJhdGlvbnNcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gXCIuLi9yZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBSZWdpc3RyeSBmb3IgZGF0YWJhc2Ugb3BlcmF0aW9uIGhhbmRsZXJzXG4gKiBAc3VtbWFyeSBNYW5hZ2VzIGFuZCBzdG9yZXMgb3BlcmF0aW9uIGhhbmRsZXJzIGZvciBkaWZmZXJlbnQgbW9kZWwgcHJvcGVydGllcyBhbmQgb3BlcmF0aW9uc1xuICogQGNsYXNzIE9wZXJhdGlvbnNSZWdpc3RyeVxuICogQHRlbXBsYXRlIE0gLSBNb2RlbCB0eXBlXG4gKiBAdGVtcGxhdGUgUiAtIFJlcG9zaXRvcnkgdHlwZVxuICogQHRlbXBsYXRlIFYgLSBNZXRhZGF0YSB0eXBlXG4gKiBAdGVtcGxhdGUgRiAtIFJlcG9zaXRvcnkgZmxhZ3NcbiAqIEB0ZW1wbGF0ZSBDIC0gQ29udGV4dCB0eXBlXG4gKiBAZXhhbXBsZVxuICogLy8gQ3JlYXRlIGEgcmVnaXN0cnkgYW5kIHJlZ2lzdGVyIGEgaGFuZGxlclxuICogY29uc3QgcmVnaXN0cnkgPSBuZXcgT3BlcmF0aW9uc1JlZ2lzdHJ5KCk7XG4gKiByZWdpc3RyeS5yZWdpc3RlcihteUhhbmRsZXIsIE9wZXJhdGlvbktleXMuQ1JFQVRFLCB0YXJnZXRNb2RlbCwgJ3Byb3BlcnR5TmFtZScpO1xuICpcbiAqIC8vIEdldCBoYW5kbGVycyBmb3IgYSBzcGVjaWZpYyBvcGVyYXRpb25cbiAqIGNvbnN0IGhhbmRsZXJzID0gcmVnaXN0cnkuZ2V0KHRhcmdldE1vZGVsLmNvbnN0cnVjdG9yLm5hbWUsICdwcm9wZXJ0eU5hbWUnLCAnb25DcmVhdGUnKTtcbiAqXG4gKiBAbWVybWFpZFxuICogY2xhc3NEaWFncmFtXG4gKiAgIGNsYXNzIE9wZXJhdGlvbnNSZWdpc3RyeSB7XG4gKiAgICAgLWNhY2hlOiBSZWNvcmR+c3RyaW5nLCBSZWNvcmR+c3RyaW5nfHN5bWJvbCwgUmVjb3JkfnN0cmluZywgUmVjb3JkfnN0cmluZywgT3BlcmF0aW9uSGFuZGxlcn5+fn5cbiAqICAgICArZ2V0KHRhcmdldCwgcHJvcEtleSwgb3BlcmF0aW9uLCBhY2N1bSlcbiAqICAgICArcmVnaXN0ZXIoaGFuZGxlciwgb3BlcmF0aW9uLCB0YXJnZXQsIHByb3BLZXkpXG4gKiAgIH1cbiAqL1xuZXhwb3J0IGNsYXNzIE9wZXJhdGlvbnNSZWdpc3RyeSB7XG4gIHByaXZhdGUgcmVhZG9ubHkgY2FjaGU6IFJlY29yZDxcbiAgICBzdHJpbmcsXG4gICAgUmVjb3JkPFxuICAgICAgc3RyaW5nIHwgc3ltYm9sLFxuICAgICAgUmVjb3JkPHN0cmluZywgUmVjb3JkPHN0cmluZywgT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT4+PlxuICAgID5cbiAgPiA9IHt9O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG9wZXJhdGlvbiBoYW5kbGVycyBmb3IgYSBzcGVjaWZpYyB0YXJnZXQgYW5kIG9wZXJhdGlvblxuICAgKiBAc3VtbWFyeSBGaW5kcyBhbGwgcmVnaXN0ZXJlZCBoYW5kbGVycyBmb3IgYSBnaXZlbiB0YXJnZXQsIHByb3BlcnR5LCBhbmQgb3BlcmF0aW9uLCBpbmNsdWRpbmcgZnJvbSBwYXJlbnQgY2xhc3Nlc1xuICAgKiBAdGVtcGxhdGUgTSAtIE1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gICAqIEB0ZW1wbGF0ZSBSIC0gUmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBJUmVwb3NpdG9yeVxuICAgKiBAdGVtcGxhdGUgViAtIE1ldGFkYXRhIHR5cGVcbiAgICogQHRlbXBsYXRlIEYgLSBSZXBvc2l0b3J5IGZsYWdzIGV4dGVuZGluZyBSZXBvc2l0b3J5RmxhZ3NcbiAgICogQHRlbXBsYXRlIEMgLSBDb250ZXh0IHR5cGUgZXh0ZW5kaW5nIENvbnRleHQ8Rj5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+fSB0YXJnZXQgLSBUaGUgdGFyZ2V0IGNsYXNzIG5hbWUgb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wS2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byBnZXQgaGFuZGxlcnMgZm9yXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRpb24gLSBUaGUgb3BlcmF0aW9uIGtleSB0byBnZXQgaGFuZGxlcnMgZm9yXG4gICAqIEBwYXJhbSB7T3BlcmF0aW9uSGFuZGxlcltdfSBbYWNjdW1dIC0gQWNjdW11bGF0b3IgZm9yIHJlY3Vyc2l2ZSBjYWxsc1xuICAgKiBAcmV0dXJuIHtPcGVyYXRpb25IYW5kbGVyW10gfCB1bmRlZmluZWR9IEFycmF5IG9mIGhhbmRsZXJzIG9yIHVuZGVmaW5lZCBpZiBub25lIGZvdW5kXG4gICAqL1xuICBnZXQ8XG4gICAgTSBleHRlbmRzIE1vZGVsLFxuICAgIFIgZXh0ZW5kcyBJUmVwb3NpdG9yeTxNLCBGLCBDPixcbiAgICBWLFxuICAgIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gICAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4gID4oXG4gICAgdGFyZ2V0OiBzdHJpbmcgfCBSZWNvcmQ8c3RyaW5nLCBhbnk+LFxuICAgIHByb3BLZXk6IHN0cmluZyxcbiAgICBvcGVyYXRpb246IHN0cmluZyxcbiAgICBhY2N1bT86IE9wZXJhdGlvbkhhbmRsZXI8TSwgUiwgViwgRiwgQz5bXVxuICApOiBPcGVyYXRpb25IYW5kbGVyPE0sIFIsIFYsIEYsIEM+W10gfCB1bmRlZmluZWQge1xuICAgIGFjY3VtID0gYWNjdW0gfHwgW107XG4gICAgbGV0IG5hbWU7XG4gICAgdHJ5IHtcbiAgICAgIG5hbWUgPSB0eXBlb2YgdGFyZ2V0ID09PSBcInN0cmluZ1wiID8gdGFyZ2V0IDogdGFyZ2V0LmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgICBhY2N1bS51bnNoaWZ0KFxuICAgICAgICAuLi5PYmplY3QudmFsdWVzKHRoaXMuY2FjaGVbbmFtZV1bcHJvcEtleV1bb3BlcmF0aW9uXSB8fCBbXSlcbiAgICAgICk7XG4gICAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgaWYgKFxuICAgICAgICB0eXBlb2YgdGFyZ2V0ID09PSBcInN0cmluZ1wiIHx8XG4gICAgICAgIHRhcmdldCA9PT0gT2JqZWN0LnByb3RvdHlwZSB8fFxuICAgICAgICBPYmplY3QuZ2V0UHJvdG90eXBlT2YodGFyZ2V0KSA9PT0gT2JqZWN0LnByb3RvdHlwZVxuICAgICAgKVxuICAgICAgICByZXR1cm4gYWNjdW07XG4gICAgfVxuXG4gICAgbGV0IHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHRhcmdldCk7XG4gICAgaWYgKHByb3RvLmNvbnN0cnVjdG9yLm5hbWUgPT09IG5hbWUpIHByb3RvID0gT2JqZWN0LmdldFByb3RvdHlwZU9mKHByb3RvKTtcblxuICAgIHJldHVybiB0aGlzLmdldDxNLCBSLCBWLCBGLCBDPihwcm90bywgcHJvcEtleSwgb3BlcmF0aW9uLCBhY2N1bSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyBhbiBvcGVyYXRpb24gaGFuZGxlciBmb3IgYSBzcGVjaWZpYyB0YXJnZXQgYW5kIG9wZXJhdGlvblxuICAgKiBAc3VtbWFyeSBTdG9yZXMgYSBoYW5kbGVyIGluIHRoZSByZWdpc3RyeSBmb3IgYSBnaXZlbiB0YXJnZXQsIHByb3BlcnR5LCBhbmQgb3BlcmF0aW9uXG4gICAqIEB0ZW1wbGF0ZSBNIC0gTW9kZWwgdHlwZSBleHRlbmRpbmcgTW9kZWxcbiAgICogQHRlbXBsYXRlIFIgLSBSZXBvc2l0b3J5IHR5cGUgZXh0ZW5kaW5nIElSZXBvc2l0b3J5XG4gICAqIEB0ZW1wbGF0ZSBWIC0gTWV0YWRhdGEgdHlwZVxuICAgKiBAdGVtcGxhdGUgRiAtIFJlcG9zaXRvcnkgZmxhZ3MgZXh0ZW5kaW5nIFJlcG9zaXRvcnlGbGFnc1xuICAgKiBAdGVtcGxhdGUgQyAtIENvbnRleHQgdHlwZSBleHRlbmRpbmcgQ29udGV4dDxGPlxuICAgKiBAcGFyYW0ge09wZXJhdGlvbkhhbmRsZXJ9IGhhbmRsZXIgLSBUaGUgaGFuZGxlciBmdW5jdGlvbiB0byByZWdpc3RlclxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN9IG9wZXJhdGlvbiAtIFRoZSBvcGVyYXRpb24ga2V5IHRvIHJlZ2lzdGVyIHRoZSBoYW5kbGVyIGZvclxuICAgKiBAcGFyYW0ge019IHRhcmdldCAtIFRoZSB0YXJnZXQgbW9kZWwgaW5zdGFuY2VcbiAgICogQHBhcmFtIHtzdHJpbmcgfCBzeW1ib2x9IHByb3BLZXkgLSBUaGUgcHJvcGVydHkga2V5IHRvIHJlZ2lzdGVyIHRoZSBoYW5kbGVyIGZvclxuICAgKiBAcmV0dXJuIHt2b2lkfVxuICAgKi9cbiAgcmVnaXN0ZXI8XG4gICAgTSBleHRlbmRzIE1vZGVsLFxuICAgIFIgZXh0ZW5kcyBJUmVwb3NpdG9yeTxNLCBGLCBDPixcbiAgICBWLFxuICAgIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gICAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4gID4oXG4gICAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxNLCBSLCBWLCBGLCBDPixcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgdGFyZ2V0OiBNLFxuICAgIHByb3BLZXk6IHN0cmluZyB8IHN5bWJvbFxuICApOiB2b2lkIHtcbiAgICBjb25zdCBuYW1lID0gdGFyZ2V0LmNvbnN0cnVjdG9yLm5hbWU7XG4gICAgY29uc3QgaGFuZGxlck5hbWUgPSBPcGVyYXRpb25zLmdldEhhbmRsZXJOYW1lKGhhbmRsZXIpO1xuXG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdKSB0aGlzLmNhY2hlW25hbWVdID0ge307XG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldKSB0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldID0ge307XG4gICAgaWYgKCF0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldW29wZXJhdGlvbl0pXG4gICAgICB0aGlzLmNhY2hlW25hbWVdW3Byb3BLZXldW29wZXJhdGlvbl0gPSB7fTtcbiAgICBpZiAodGhpcy5jYWNoZVtuYW1lXVtwcm9wS2V5XVtvcGVyYXRpb25dW2hhbmRsZXJOYW1lXSkgcmV0dXJuO1xuICAgIHRoaXMuY2FjaGVbbmFtZV1bcHJvcEtleV1bb3BlcmF0aW9uXVtoYW5kbGVyTmFtZV0gPSBoYW5kbGVyO1xuICB9XG59XG4iLCJpbXBvcnQgeyBIYXNoaW5nLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IE9wZXJhdGlvbkhhbmRsZXIgfSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgT3BlcmF0aW9uc1JlZ2lzdHJ5IH0gZnJvbSBcIi4vT3BlcmF0aW9uc1JlZ2lzdHJ5XCI7XG5pbXBvcnQgeyBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBJUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzXCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnlGbGFncyB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L3R5cGVzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFN0YXRpYyB1dGlsaXR5IGNsYXNzIGZvciBkYXRhYmFzZSBvcGVyYXRpb24gbWFuYWdlbWVudFxuICogQHN1bW1hcnkgUHJvdmlkZXMgZnVuY3Rpb25hbGl0eSBmb3IgcmVnaXN0ZXJpbmcsIHJldHJpZXZpbmcsIGFuZCBtYW5hZ2luZyBkYXRhYmFzZSBvcGVyYXRpb24gaGFuZGxlcnNcbiAqIEBjbGFzcyBPcGVyYXRpb25zXG4gKiBAdGVtcGxhdGUgTSAtIE1vZGVsIHR5cGVcbiAqIEB0ZW1wbGF0ZSBSIC0gUmVwb3NpdG9yeSB0eXBlXG4gKiBAdGVtcGxhdGUgViAtIE1ldGFkYXRhIHR5cGVcbiAqIEB0ZW1wbGF0ZSBGIC0gUmVwb3NpdG9yeSBmbGFnc1xuICogQHRlbXBsYXRlIEMgLSBDb250ZXh0IHR5cGVcbiAqIEBleGFtcGxlXG4gKiAvLyBSZWdpc3RlciBhIGhhbmRsZXIgZm9yIGEgY3JlYXRlIG9wZXJhdGlvblxuICogT3BlcmF0aW9ucy5yZWdpc3RlcihteUhhbmRsZXIsIE9wZXJhdGlvbktleXMuQ1JFQVRFLCB0YXJnZXRNb2RlbCwgJ3Byb3BlcnR5TmFtZScpO1xuICogXG4gKiAvLyBHZXQgaGFuZGxlcnMgZm9yIGEgc3BlY2lmaWMgb3BlcmF0aW9uXG4gKiBjb25zdCBoYW5kbGVycyA9IE9wZXJhdGlvbnMuZ2V0KHRhcmdldE1vZGVsLmNvbnN0cnVjdG9yLm5hbWUsICdwcm9wZXJ0eU5hbWUnLCAnb25DcmVhdGUnKTtcbiAqIFxuICogQG1lcm1haWRcbiAqIGNsYXNzRGlhZ3JhbVxuICogICBjbGFzcyBPcGVyYXRpb25zIHtcbiAqICAgICAtcmVnaXN0cnk6IE9wZXJhdGlvbnNSZWdpc3RyeVxuICogICAgICtnZXRIYW5kbGVyTmFtZShoYW5kbGVyKVxuICogICAgICtrZXkoc3RyKVxuICogICAgICtnZXQodGFyZ2V0TmFtZSwgcHJvcEtleSwgb3BlcmF0aW9uKVxuICogICAgIC1nZXRPcFJlZ2lzdHJ5KClcbiAqICAgICArcmVnaXN0ZXIoaGFuZGxlciwgb3BlcmF0aW9uLCB0YXJnZXQsIHByb3BLZXkpXG4gKiAgIH1cbiAqICAgT3BlcmF0aW9ucyAtLT4gT3BlcmF0aW9uc1JlZ2lzdHJ5IDogdXNlc1xuICovXG5leHBvcnQgY2xhc3MgT3BlcmF0aW9ucyB7XG4gIHByaXZhdGUgc3RhdGljIHJlZ2lzdHJ5OiBPcGVyYXRpb25zUmVnaXN0cnk7XG5cbiAgcHJpdmF0ZSBjb25zdHJ1Y3RvcigpIHt9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIGEgdW5pcXVlIG5hbWUgZm9yIGFuIG9wZXJhdGlvbiBoYW5kbGVyXG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIG5hbWUgb2YgdGhlIGhhbmRsZXIgZnVuY3Rpb24gb3IgZ2VuZXJhdGVzIGEgaGFzaCBpZiBuYW1lIGlzIG5vdCBhdmFpbGFibGVcbiAgICogQHBhcmFtIHtPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBhbnksIGFueSwgYW55Pn0gaGFuZGxlciAtIFRoZSBoYW5kbGVyIGZ1bmN0aW9uIHRvIGdldCB0aGUgbmFtZSBmb3JcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgbmFtZSBvZiB0aGUgaGFuZGxlciBvciBhIGdlbmVyYXRlZCBoYXNoXG4gICAqL1xuICBzdGF0aWMgZ2V0SGFuZGxlck5hbWUoaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgYW55LCBhbnksIGFueT4pIHtcbiAgICBpZiAoaGFuZGxlci5uYW1lKSByZXR1cm4gaGFuZGxlci5uYW1lO1xuXG4gICAgY29uc29sZS53YXJuKFxuICAgICAgXCJIYW5kbGVyIG5hbWUgbm90IGRlZmluZWQuIEEgbmFtZSB3aWxsIGJlIGdlbmVyYXRlZCwgYnV0IHRoaXMgaXMgbm90IGRlc2lyYWJsZS4gcGxlYXNlIGF2b2lkIHVzaW5nIGFub255bW91cyBmdW5jdGlvbnNcIlxuICAgICk7XG4gICAgcmV0dXJuIEhhc2hpbmcuaGFzaChoYW5kbGVyLnRvU3RyaW5nKCkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZW5lcmF0ZXMgYSByZWZsZWN0aW9uIG1ldGFkYXRhIGtleVxuICAgKiBAc3VtbWFyeSBDcmVhdGVzIGEgZnVsbHkgcXVhbGlmaWVkIG1ldGFkYXRhIGtleSBieSBwcmVmaXhpbmcgd2l0aCB0aGUgcmVmbGVjdGlvbiBuYW1lc3BhY2VcbiAgICogQHBhcmFtIHtzdHJpbmd9IHN0ciAtIFRoZSBvcGVyYXRpb24ga2V5IHN0cmluZyB0byBwcmVmaXhcbiAgICogQHJldHVybiB7c3RyaW5nfSBUaGUgZnVsbHkgcXVhbGlmaWVkIG1ldGFkYXRhIGtleVxuICAgKi9cbiAgc3RhdGljIGtleShzdHI6IHN0cmluZykge1xuICAgIHJldHVybiBPcGVyYXRpb25LZXlzLlJFRkxFQ1QgKyBzdHI7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJldHJpZXZlcyBvcGVyYXRpb24gaGFuZGxlcnMgZm9yIGEgc3BlY2lmaWMgdGFyZ2V0IGFuZCBvcGVyYXRpb25cbiAgICogQHN1bW1hcnkgR2V0cyByZWdpc3RlcmVkIGhhbmRsZXJzIGZyb20gdGhlIG9wZXJhdGlvbnMgcmVnaXN0cnkgZm9yIGEgZ2l2ZW4gdGFyZ2V0LCBwcm9wZXJ0eSwgYW5kIG9wZXJhdGlvblxuICAgKiBAdGVtcGxhdGUgTSAtIE1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gICAqIEB0ZW1wbGF0ZSBSIC0gUmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBJUmVwb3NpdG9yeVxuICAgKiBAdGVtcGxhdGUgViAtIE1ldGFkYXRhIHR5cGUsIGRlZmF1bHRzIHRvIG9iamVjdFxuICAgKiBAdGVtcGxhdGUgRiAtIFJlcG9zaXRvcnkgZmxhZ3MgZXh0ZW5kaW5nIFJlcG9zaXRvcnlGbGFnc1xuICAgKiBAdGVtcGxhdGUgQyAtIENvbnRleHQgdHlwZSBleHRlbmRpbmcgQ29udGV4dDxGPlxuICAgKiBAcGFyYW0ge3N0cmluZyB8IFJlY29yZDxzdHJpbmcsIGFueT59IHRhcmdldE5hbWUgLSBUaGUgdGFyZ2V0IGNsYXNzIG5hbWUgb3Igb2JqZWN0XG4gICAqIEBwYXJhbSB7c3RyaW5nfSBwcm9wS2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byBnZXQgaGFuZGxlcnMgZm9yXG4gICAqIEBwYXJhbSB7c3RyaW5nfSBvcGVyYXRpb24gLSBUaGUgb3BlcmF0aW9uIGtleSB0byBnZXQgaGFuZGxlcnMgZm9yXG4gICAqIEByZXR1cm4ge2FueX0gVGhlIHJlZ2lzdGVyZWQgaGFuZGxlcnMgZm9yIHRoZSBzcGVjaWZpZWQgdGFyZ2V0LCBwcm9wZXJ0eSwgYW5kIG9wZXJhdGlvblxuICAgKi9cbiAgc3RhdGljIGdldDxcbiAgICBNIGV4dGVuZHMgTW9kZWwsXG4gICAgUiBleHRlbmRzIElSZXBvc2l0b3J5PE0sIEYsIEM+LFxuICAgIFYgPSBvYmplY3QsXG4gICAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4gID4oXG4gICAgdGFyZ2V0TmFtZTogc3RyaW5nIHwgUmVjb3JkPHN0cmluZywgYW55PixcbiAgICBwcm9wS2V5OiBzdHJpbmcsXG4gICAgb3BlcmF0aW9uOiBzdHJpbmdcbiAgKSB7XG4gICAgcmV0dXJuIE9wZXJhdGlvbnMucmVnaXN0cnkuZ2V0PE0sIFIsIFYsIEYsIEM+KFxuICAgICAgdGFyZ2V0TmFtZSxcbiAgICAgIHByb3BLZXksXG4gICAgICBvcGVyYXRpb25cbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIG9yIGluaXRpYWxpemVzIHRoZSBvcGVyYXRpb25zIHJlZ2lzdHJ5XG4gICAqIEBzdW1tYXJ5IFJldHVybnMgdGhlIGV4aXN0aW5nIHJlZ2lzdHJ5IG9yIGNyZWF0ZXMgYSBuZXcgb25lIGlmIGl0IGRvZXNuJ3QgZXhpc3RcbiAgICogQHJldHVybiB7T3BlcmF0aW9uc1JlZ2lzdHJ5fSBUaGUgb3BlcmF0aW9ucyByZWdpc3RyeSBpbnN0YW5jZVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBzdGF0aWMgZ2V0T3BSZWdpc3RyeSgpIHtcbiAgICBpZiAoIU9wZXJhdGlvbnMucmVnaXN0cnkpIE9wZXJhdGlvbnMucmVnaXN0cnkgPSBuZXcgT3BlcmF0aW9uc1JlZ2lzdHJ5KCk7XG4gICAgcmV0dXJuIE9wZXJhdGlvbnMucmVnaXN0cnk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFJlZ2lzdGVycyBhbiBvcGVyYXRpb24gaGFuZGxlciBmb3IgYSBzcGVjaWZpYyB0YXJnZXQgYW5kIG9wZXJhdGlvblxuICAgKiBAc3VtbWFyeSBBZGRzIGEgaGFuZGxlciB0byB0aGUgb3BlcmF0aW9ucyByZWdpc3RyeSBmb3IgYSBnaXZlbiB0YXJnZXQsIHByb3BlcnR5LCBhbmQgb3BlcmF0aW9uXG4gICAqIEB0ZW1wbGF0ZSBWIC0gTW9kZWwgdHlwZSBleHRlbmRpbmcgTW9kZWxcbiAgICogQHBhcmFtIHtPcGVyYXRpb25IYW5kbGVyPFYsIGFueSwgYW55Pn0gaGFuZGxlciAtIFRoZSBoYW5kbGVyIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyXG4gICAqIEBwYXJhbSB7T3BlcmF0aW9uS2V5c30gb3BlcmF0aW9uIC0gVGhlIG9wZXJhdGlvbiBrZXkgdG8gcmVnaXN0ZXIgdGhlIGhhbmRsZXIgZm9yXG4gICAqIEBwYXJhbSB7Vn0gdGFyZ2V0IC0gVGhlIHRhcmdldCBtb2RlbCBpbnN0YW5jZVxuICAgKiBAcGFyYW0ge3N0cmluZyB8IHN5bWJvbH0gcHJvcEtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgdG8gcmVnaXN0ZXIgdGhlIGhhbmRsZXIgZm9yXG4gICAqIEByZXR1cm4ge3ZvaWR9XG4gICAqL1xuICBzdGF0aWMgcmVnaXN0ZXI8ViBleHRlbmRzIE1vZGVsPihcbiAgICBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPFYsIGFueSwgYW55PixcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgdGFyZ2V0OiBWLFxuICAgIHByb3BLZXk6IHN0cmluZyB8IHN5bWJvbFxuICApIHtcbiAgICBPcGVyYXRpb25zLmdldE9wUmVnaXN0cnkoKS5yZWdpc3RlcihcbiAgICAgIGhhbmRsZXIgYXMgYW55LFxuICAgICAgb3BlcmF0aW9uLFxuICAgICAgdGFyZ2V0LFxuICAgICAgcHJvcEtleVxuICAgICk7XG4gIH1cbn1cbiIsImltcG9ydCB7XG4gIElkT3BlcmF0aW9uSGFuZGxlcixcbiAgT3BlcmF0aW9uSGFuZGxlcixcbiAgU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyLFxuICBVcGRhdGVPcGVyYXRpb25IYW5kbGVyLFxufSBmcm9tIFwiLi90eXBlc1wiO1xuaW1wb3J0IHsgREJPcGVyYXRpb25zLCBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBPcGVyYXRpb25zIH0gZnJvbSBcIi4vT3BlcmF0aW9uc1wiO1xuaW1wb3J0IHsgYXBwbHkgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IHByb3BNZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSW50ZXJuYWwgZnVuY3Rpb24gdG8gcmVnaXN0ZXIgb3BlcmF0aW9uIGhhbmRsZXJzXG4gKiBAc3VtbWFyeSBSZWdpc3RlcnMgYW4gb3BlcmF0aW9uIGhhbmRsZXIgZm9yIGEgc3BlY2lmaWMgb3BlcmF0aW9uIGtleSBvbiBhIHRhcmdldCBwcm9wZXJ0eVxuICogQHBhcmFtIHtPcGVyYXRpb25LZXlzfSBvcCAtIFRoZSBvcGVyYXRpb24ga2V5IHRvIGhhbmRsZVxuICogQHBhcmFtIHtPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBhbnksIGFueSwgYW55Pn0gaGFuZGxlciAtIFRoZSBoYW5kbGVyIGZ1bmN0aW9uIHRvIHJlZ2lzdGVyXG4gKiBAcmV0dXJuIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBkZWNvcmF0b3IgdGhhdCByZWdpc3RlcnMgdGhlIGhhbmRsZXJcbiAqIEBmdW5jdGlvbiBoYW5kbGVcbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKi9cbmZ1bmN0aW9uIGhhbmRsZShcbiAgb3A6IE9wZXJhdGlvbktleXMsXG4gIGhhbmRsZXI6IE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIGFueSwgYW55LCBhbnk+XG4pIHtcbiAgcmV0dXJuICh0YXJnZXQ6IGFueSwgcHJvcGVydHlLZXk6IHN0cmluZykgPT4ge1xuICAgIE9wZXJhdGlvbnMucmVnaXN0ZXIoaGFuZGxlciwgb3AsIHRhcmdldCwgcHJvcGVydHlLZXkpO1xuICB9O1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgZm9yIGhhbmRsaW5nIGNyZWF0ZSBhbmQgdXBkYXRlIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvciB0byBleGVjdXRlIGR1cmluZyBib3RoIGNyZWF0ZSBhbmQgdXBkYXRlIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBmb3IgbWV0YWRhdGEsIGRlZmF1bHRzIHRvIG9iamVjdFxuICogQHBhcmFtIHtTdGFuZGFyZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55PiB8IFVwZGF0ZU9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55Pn0gaGFuZGxlciAtIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBbZGF0YV0gLSBPcHRpb25hbCBtZXRhZGF0YSB0byBwYXNzIHRvIHRoZSBoYW5kbGVyXG4gKiBAcmV0dXJuIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBkZWNvcmF0b3IgdGhhdCBjYW4gYmUgYXBwbGllZCB0byBjbGFzcyBwcm9wZXJ0aWVzXG4gKiBAZnVuY3Rpb24gb25DcmVhdGVVcGRhdGVcbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkNyZWF0ZVVwZGF0ZTxWID0gb2JqZWN0PihcbiAgaGFuZGxlcjpcbiAgICB8IFN0YW5kYXJkT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+XG4gICAgfCBVcGRhdGVPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE/OiBWXG4pIHtcbiAgcmV0dXJuIG9uKERCT3BlcmF0aW9ucy5DUkVBVEVfVVBEQVRFLCBoYW5kbGVyLCBkYXRhKTtcbn1cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciBmb3IgaGFuZGxpbmcgdXBkYXRlIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvciB0byBleGVjdXRlIGR1cmluZyB1cGRhdGUgb3BlcmF0aW9uc1xuICogQHRlbXBsYXRlIFYgLSBUeXBlIGZvciBtZXRhZGF0YSwgZGVmYXVsdHMgdG8gb2JqZWN0XG4gKiBAcGFyYW0ge1VwZGF0ZU9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueT59IGhhbmRsZXIgLSBUaGUgbWV0aG9kIGNhbGxlZCB1cG9uIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gW2RhdGFdIC0gT3B0aW9uYWwgbWV0YWRhdGEgdG8gcGFzcyB0byB0aGUgaGFuZGxlclxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIG9uVXBkYXRlXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25VcGRhdGU8ViA9IG9iamVjdD4oXG4gIGhhbmRsZXI6IFVwZGF0ZU9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueT4sXG4gIGRhdGE/OiBWXG4pIHtcbiAgcmV0dXJuIG9uKERCT3BlcmF0aW9ucy5VUERBVEUsIGhhbmRsZXIsIGRhdGEpO1xufVxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIGZvciBoYW5kbGluZyBjcmVhdGUgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW9yIHRvIGV4ZWN1dGUgZHVyaW5nIGNyZWF0ZSBvcGVyYXRpb25zXG4gKiBAdGVtcGxhdGUgViAtIFR5cGUgZm9yIG1ldGFkYXRhLCBkZWZhdWx0cyB0byBvYmplY3RcbiAqIEBwYXJhbSB7U3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT59IGhhbmRsZXIgLSBUaGUgbWV0aG9kIGNhbGxlZCB1cG9uIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gW2RhdGFdIC0gT3B0aW9uYWwgbWV0YWRhdGEgdG8gcGFzcyB0byB0aGUgaGFuZGxlclxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIG9uQ3JlYXRlXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25DcmVhdGU8ViA9IG9iamVjdD4oXG4gIGhhbmRsZXI6IFN0YW5kYXJkT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+LFxuICBkYXRhPzogVlxuKSB7XG4gIHJldHVybiBvbihEQk9wZXJhdGlvbnMuQ1JFQVRFLCBoYW5kbGVyLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIGZvciBoYW5kbGluZyByZWFkIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvciB0byBleGVjdXRlIGR1cmluZyByZWFkIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBmb3IgbWV0YWRhdGEsIGRlZmF1bHRzIHRvIG9iamVjdFxuICogQHBhcmFtIHtJZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55Pn0gaGFuZGxlciAtIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBbZGF0YV0gLSBPcHRpb25hbCBtZXRhZGF0YSB0byBwYXNzIHRvIHRoZSBoYW5kbGVyXG4gKiBAcmV0dXJuIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBkZWNvcmF0b3IgdGhhdCBjYW4gYmUgYXBwbGllZCB0byBjbGFzcyBwcm9wZXJ0aWVzXG4gKiBAZnVuY3Rpb24gb25SZWFkXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gb25SZWFkPFYgPSBvYmplY3Q+KFxuICBoYW5kbGVyOiBJZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55PixcbiAgZGF0YTogVlxuKSB7XG4gIHJldHVybiBvbihEQk9wZXJhdGlvbnMuUkVBRCwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciBmb3IgaGFuZGxpbmcgZGVsZXRlIG9wZXJhdGlvbnNcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvciB0byBleGVjdXRlIGR1cmluZyBkZWxldGUgb3BlcmF0aW9uc1xuICogQHRlbXBsYXRlIFYgLSBUeXBlIGZvciBtZXRhZGF0YSwgZGVmYXVsdHMgdG8gb2JqZWN0XG4gKiBAcGFyYW0ge09wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55Pn0gaGFuZGxlciAtIFRoZSBtZXRob2QgY2FsbGVkIHVwb24gdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBbZGF0YV0gLSBPcHRpb25hbCBtZXRhZGF0YSB0byBwYXNzIHRvIHRoZSBoYW5kbGVyXG4gKiBAcmV0dXJuIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBkZWNvcmF0b3IgdGhhdCBjYW4gYmUgYXBwbGllZCB0byBjbGFzcyBwcm9wZXJ0aWVzXG4gKiBAZnVuY3Rpb24gb25EZWxldGVcbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBvbkRlbGV0ZTxWID0gb2JqZWN0PihcbiAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+LFxuICBkYXRhOiBWXG4pIHtcbiAgcmV0dXJuIG9uKERCT3BlcmF0aW9ucy5ERUxFVEUsIGhhbmRsZXIsIGRhdGEpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgZm9yIGhhbmRsaW5nIGFsbCBvcGVyYXRpb24gdHlwZXNcbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBiZWhhdmlvciB0byBleGVjdXRlIGR1cmluZyBhbnkgZGF0YWJhc2Ugb3BlcmF0aW9uXG4gKiBAdGVtcGxhdGUgViAtIFR5cGUgZm9yIG1ldGFkYXRhLCBkZWZhdWx0cyB0byBvYmplY3RcbiAqIEBwYXJhbSB7T3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+fSBoYW5kbGVyIC0gVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IFtkYXRhXSAtIE9wdGlvbmFsIG1ldGFkYXRhIHRvIHBhc3MgdG8gdGhlIGhhbmRsZXJcbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGRlY29yYXRvciB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGNsYXNzIHByb3BlcnRpZXNcbiAqIEBmdW5jdGlvbiBvbkFueVxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uQW55PFYgPSBvYmplY3Q+KFxuICBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE6IFZcbikge1xuICByZXR1cm4gb24oREJPcGVyYXRpb25zLkFMTCwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEJhc2UgZGVjb3JhdG9yIGZvciBoYW5kbGluZyBkYXRhYmFzZSBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3IgdG8gZXhlY3V0ZSBkdXJpbmcgc3BlY2lmaWVkIGRhdGFiYXNlIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBmb3IgbWV0YWRhdGEsIGRlZmF1bHRzIHRvIG9iamVjdFxuICogQHBhcmFtIHtPcGVyYXRpb25LZXlzW10gfCBEQk9wZXJhdGlvbnN9IFtvcD1EQk9wZXJhdGlvbnMuQUxMXSAtIE9uZSBvciBtb3JlIG9wZXJhdGlvbiB0eXBlcyB0byBoYW5kbGVcbiAqIEBwYXJhbSB7T3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+fSBoYW5kbGVyIC0gVGhlIG1ldGhvZCBjYWxsZWQgdXBvbiB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IFtkYXRhXSAtIE9wdGlvbmFsIG1ldGFkYXRhIHRvIHBhc3MgdG8gdGhlIGhhbmRsZXJcbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGRlY29yYXRvciB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGNsYXNzIHByb3BlcnRpZXNcbiAqIEBmdW5jdGlvbiBvblxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIHVzYWdlOlxuICogY2xhc3MgTXlNb2RlbCB7XG4gKiAgIEBvbihEQk9wZXJhdGlvbnMuQ1JFQVRFLCBteUhhbmRsZXIpXG4gKiAgIG15UHJvcGVydHk6IHN0cmluZztcbiAqIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9uPFYgPSBvYmplY3Q+KFxuICBvcDogT3BlcmF0aW9uS2V5c1tdID0gREJPcGVyYXRpb25zLkFMTCxcbiAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+LFxuICBkYXRhPzogVlxuKSB7XG4gIHJldHVybiBvcGVyYXRpb24oT3BlcmF0aW9uS2V5cy5PTiwgb3AsIGhhbmRsZXIsIGRhdGEpO1xufVxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIGZvciBoYW5kbGluZyBwb3N0LWNyZWF0ZSBhbmQgcG9zdC11cGRhdGUgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW9yIHRvIGV4ZWN1dGUgYWZ0ZXIgYm90aCBjcmVhdGUgYW5kIHVwZGF0ZSBvcGVyYXRpb25zXG4gKiBAdGVtcGxhdGUgViAtIFR5cGUgZm9yIG1ldGFkYXRhLCBkZWZhdWx0cyB0byBvYmplY3RcbiAqIEBwYXJhbSB7U3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4gfCBVcGRhdGVPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT59IGhhbmRsZXIgLSBUaGUgbWV0aG9kIGNhbGxlZCBhZnRlciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IFtkYXRhXSAtIE9wdGlvbmFsIG1ldGFkYXRhIHRvIHBhc3MgdG8gdGhlIGhhbmRsZXJcbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGRlY29yYXRvciB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGNsYXNzIHByb3BlcnRpZXNcbiAqIEBmdW5jdGlvbiBhZnRlckNyZWF0ZVVwZGF0ZVxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFmdGVyQ3JlYXRlVXBkYXRlPFYgPSBvYmplY3Q+KFxuICBoYW5kbGVyOlxuICAgIHwgU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT5cbiAgICB8IFVwZGF0ZU9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55PixcbiAgZGF0YTogVlxuKSB7XG4gIHJldHVybiBhZnRlcihEQk9wZXJhdGlvbnMuQ1JFQVRFX1VQREFURSwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciBmb3IgaGFuZGxpbmcgcG9zdC11cGRhdGUgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW9yIHRvIGV4ZWN1dGUgYWZ0ZXIgdXBkYXRlIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBmb3IgbWV0YWRhdGEsIGRlZmF1bHRzIHRvIG9iamVjdFxuICogQHBhcmFtIHtVcGRhdGVPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT59IGhhbmRsZXIgLSBUaGUgbWV0aG9kIGNhbGxlZCBhZnRlciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IFtkYXRhXSAtIE9wdGlvbmFsIG1ldGFkYXRhIHRvIHBhc3MgdG8gdGhlIGhhbmRsZXJcbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGRlY29yYXRvciB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGNsYXNzIHByb3BlcnRpZXNcbiAqIEBmdW5jdGlvbiBhZnRlclVwZGF0ZVxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFmdGVyVXBkYXRlPFYgPSBvYmplY3Q+KFxuICBoYW5kbGVyOiBVcGRhdGVPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE6IFZcbikge1xuICByZXR1cm4gYWZ0ZXIoREJPcGVyYXRpb25zLlVQREFURSwgaGFuZGxlciwgZGF0YSk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciBmb3IgaGFuZGxpbmcgcG9zdC1jcmVhdGUgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW9yIHRvIGV4ZWN1dGUgYWZ0ZXIgY3JlYXRlIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBmb3IgbWV0YWRhdGEsIGRlZmF1bHRzIHRvIG9iamVjdFxuICogQHBhcmFtIHtTdGFuZGFyZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55Pn0gaGFuZGxlciAtIFRoZSBtZXRob2QgY2FsbGVkIGFmdGVyIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gW2RhdGFdIC0gT3B0aW9uYWwgbWV0YWRhdGEgdG8gcGFzcyB0byB0aGUgaGFuZGxlclxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIGFmdGVyQ3JlYXRlXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWZ0ZXJDcmVhdGU8ViA9IG9iamVjdD4oXG4gIGhhbmRsZXI6IFN0YW5kYXJkT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+LFxuICBkYXRhOiBWXG4pIHtcbiAgcmV0dXJuIGFmdGVyKERCT3BlcmF0aW9ucy5DUkVBVEUsIGhhbmRsZXIsIGRhdGEpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWNvcmF0b3IgZm9yIGhhbmRsaW5nIHBvc3QtcmVhZCBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3IgdG8gZXhlY3V0ZSBhZnRlciByZWFkIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBmb3IgbWV0YWRhdGEsIGRlZmF1bHRzIHRvIG9iamVjdFxuICogQHBhcmFtIHtTdGFuZGFyZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55Pn0gaGFuZGxlciAtIFRoZSBtZXRob2QgY2FsbGVkIGFmdGVyIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gW2RhdGFdIC0gT3B0aW9uYWwgbWV0YWRhdGEgdG8gcGFzcyB0byB0aGUgaGFuZGxlclxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIGFmdGVyUmVhZFxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFmdGVyUmVhZDxWID0gb2JqZWN0PihcbiAgaGFuZGxlcjogU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE/OiBWXG4pIHtcbiAgcmV0dXJuIGFmdGVyKERCT3BlcmF0aW9ucy5SRUFELCBoYW5kbGVyLCBkYXRhKTtcbn1cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlY29yYXRvciBmb3IgaGFuZGxpbmcgcG9zdC1kZWxldGUgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW9yIHRvIGV4ZWN1dGUgYWZ0ZXIgZGVsZXRlIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBmb3IgbWV0YWRhdGEsIGRlZmF1bHRzIHRvIG9iamVjdFxuICogQHBhcmFtIHtTdGFuZGFyZE9wZXJhdGlvbkhhbmRsZXI8YW55LCBhbnksIFYsIGFueSwgYW55Pn0gaGFuZGxlciAtIFRoZSBtZXRob2QgY2FsbGVkIGFmdGVyIHRoZSBvcGVyYXRpb25cbiAqIEBwYXJhbSB7Vn0gW2RhdGFdIC0gT3B0aW9uYWwgbWV0YWRhdGEgdG8gcGFzcyB0byB0aGUgaGFuZGxlclxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIGFmdGVyRGVsZXRlXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gYWZ0ZXJEZWxldGU8ViA9IG9iamVjdD4oXG4gIGhhbmRsZXI6IFN0YW5kYXJkT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+LFxuICBkYXRhPzogVlxuKSB7XG4gIHJldHVybiBhZnRlcihEQk9wZXJhdGlvbnMuREVMRVRFLCBoYW5kbGVyLCBkYXRhKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIGZvciBoYW5kbGluZyBwb3N0LW9wZXJhdGlvbiBmb3IgYWxsIG9wZXJhdGlvbiB0eXBlc1xuICogQHN1bW1hcnkgRGVmaW5lcyBhIGJlaGF2aW9yIHRvIGV4ZWN1dGUgYWZ0ZXIgYW55IGRhdGFiYXNlIG9wZXJhdGlvblxuICogQHRlbXBsYXRlIFYgLSBUeXBlIGZvciBtZXRhZGF0YSwgZGVmYXVsdHMgdG8gb2JqZWN0XG4gKiBAcGFyYW0ge1N0YW5kYXJkT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+fSBoYW5kbGVyIC0gVGhlIG1ldGhvZCBjYWxsZWQgYWZ0ZXIgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtWfSBbZGF0YV0gLSBPcHRpb25hbCBtZXRhZGF0YSB0byBwYXNzIHRvIHRoZSBoYW5kbGVyXG4gKiBAcmV0dXJuIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBkZWNvcmF0b3IgdGhhdCBjYW4gYmUgYXBwbGllZCB0byBjbGFzcyBwcm9wZXJ0aWVzXG4gKiBAZnVuY3Rpb24gYWZ0ZXJBbnlcbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBhZnRlckFueTxWID0gb2JqZWN0PihcbiAgaGFuZGxlcjogU3RhbmRhcmRPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGE/OiBWXG4pIHtcbiAgcmV0dXJuIGFmdGVyKERCT3BlcmF0aW9ucy5BTEwsIGhhbmRsZXIsIGRhdGEpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBCYXNlIGRlY29yYXRvciBmb3IgaGFuZGxpbmcgcG9zdC1vcGVyYXRpb24gYmVoYXZpb3JzXG4gKiBAc3VtbWFyeSBEZWZpbmVzIGEgYmVoYXZpb3IgdG8gZXhlY3V0ZSBhZnRlciBzcGVjaWZpZWQgZGF0YWJhc2Ugb3BlcmF0aW9uc1xuICogQHRlbXBsYXRlIFYgLSBUeXBlIGZvciBtZXRhZGF0YSwgZGVmYXVsdHMgdG8gb2JqZWN0XG4gKiBAcGFyYW0ge09wZXJhdGlvbktleXNbXSB8IERCT3BlcmF0aW9uc30gW29wPURCT3BlcmF0aW9ucy5BTExdIC0gT25lIG9yIG1vcmUgb3BlcmF0aW9uIHR5cGVzIHRvIGhhbmRsZVxuICogQHBhcmFtIHtPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT59IGhhbmRsZXIgLSBUaGUgbWV0aG9kIGNhbGxlZCBhZnRlciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ge1Z9IFtkYXRhXSAtIE9wdGlvbmFsIG1ldGFkYXRhIHRvIHBhc3MgdG8gdGhlIGhhbmRsZXJcbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGRlY29yYXRvciB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGNsYXNzIHByb3BlcnRpZXNcbiAqIEBmdW5jdGlvbiBhZnRlclxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqIEBleGFtcGxlXG4gKiAvLyBFeGFtcGxlIHVzYWdlOlxuICogY2xhc3MgTXlNb2RlbCB7XG4gKiAgIEBhZnRlcihEQk9wZXJhdGlvbnMuQ1JFQVRFLCBteUhhbmRsZXIpXG4gKiAgIG15UHJvcGVydHk6IHN0cmluZztcbiAqIH1cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGFmdGVyPFYgPSBvYmplY3Q+KFxuICBvcDogT3BlcmF0aW9uS2V5c1tdID0gREJPcGVyYXRpb25zLkFMTCxcbiAgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+LFxuICBkYXRhPzogVlxuKSB7XG4gIHJldHVybiBvcGVyYXRpb24oT3BlcmF0aW9uS2V5cy5BRlRFUiwgb3AsIGhhbmRsZXIsIGRhdGEpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb3JlIGRlY29yYXRvciBmYWN0b3J5IGZvciBvcGVyYXRpb24gaGFuZGxlcnNcbiAqIEBzdW1tYXJ5IENyZWF0ZXMgZGVjb3JhdG9ycyB0aGF0IHJlZ2lzdGVyIGhhbmRsZXJzIGZvciBkYXRhYmFzZSBvcGVyYXRpb25zXG4gKiBAdGVtcGxhdGUgViAtIFR5cGUgZm9yIG1ldGFkYXRhLCBkZWZhdWx0cyB0byBvYmplY3RcbiAqIEBwYXJhbSB7T3BlcmF0aW9uS2V5cy5PTiB8IE9wZXJhdGlvbktleXMuQUZURVJ9IGJhc2VPcCAtIFdoZXRoZXIgdGhlIGhhbmRsZXIgcnVucyBkdXJpbmcgb3IgYWZ0ZXIgdGhlIG9wZXJhdGlvblxuICogQHBhcmFtIHtPcGVyYXRpb25LZXlzW119IFtvcGVyYXRpb249REJPcGVyYXRpb25zLkFMTF0gLSBUaGUgc3BlY2lmaWMgb3BlcmF0aW9ucyB0byBoYW5kbGVcbiAqIEBwYXJhbSB7T3BlcmF0aW9uSGFuZGxlcjxhbnksIGFueSwgViwgYW55LCBhbnk+fSBoYW5kbGVyIC0gVGhlIGhhbmRsZXIgZnVuY3Rpb24gdG8gZXhlY3V0ZVxuICogQHBhcmFtIHtWfSBbZGF0YVRvQWRkXSAtIE9wdGlvbmFsIG1ldGFkYXRhIHRvIHBhc3MgdG8gdGhlIGhhbmRsZXJcbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGRlY29yYXRvciB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGNsYXNzIHByb3BlcnRpZXNcbiAqIEBmdW5jdGlvbiBvcGVyYXRpb25cbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eSBEZWNvcmF0b3JzXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENsaWVudFxuICogICBwYXJ0aWNpcGFudCBEZWNvcmF0b3IgYXMgQG9wZXJhdGlvblxuICogICBwYXJ0aWNpcGFudCBPcGVyYXRpb25zIGFzIE9wZXJhdGlvbnMgUmVnaXN0cnlcbiAqICAgcGFydGljaXBhbnQgSGFuZGxlclxuICpcbiAqICAgQ2xpZW50LT4+RGVjb3JhdG9yOiBBcHBseSB0byBwcm9wZXJ0eVxuICogICBEZWNvcmF0b3ItPj5PcGVyYXRpb25zOiBSZWdpc3RlciBoYW5kbGVyXG4gKiAgIERlY29yYXRvci0+PkRlY29yYXRvcjogU3RvcmUgbWV0YWRhdGFcbiAqXG4gKiAgIE5vdGUgb3ZlciBDbGllbnQsSGFuZGxlcjogTGF0ZXIsIGR1cmluZyBvcGVyYXRpb24gZXhlY3V0aW9uXG4gKiAgIENsaWVudC0+Pk9wZXJhdGlvbnM6IEV4ZWN1dGUgb3BlcmF0aW9uXG4gKiAgIE9wZXJhdGlvbnMtPj5IYW5kbGVyOiBDYWxsIHJlZ2lzdGVyZWQgaGFuZGxlclxuICogICBIYW5kbGVyLS0+Pk9wZXJhdGlvbnM6IFJldHVybiByZXN1bHRcbiAqICAgT3BlcmF0aW9ucy0tPj5DbGllbnQ6IFJldHVybiBmaW5hbCByZXN1bHRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG9wZXJhdGlvbjxWID0gb2JqZWN0PihcbiAgYmFzZU9wOiBPcGVyYXRpb25LZXlzLk9OIHwgT3BlcmF0aW9uS2V5cy5BRlRFUixcbiAgb3BlcmF0aW9uOiBPcGVyYXRpb25LZXlzW10gPSBEQk9wZXJhdGlvbnMuQUxMLFxuICBoYW5kbGVyOiBPcGVyYXRpb25IYW5kbGVyPGFueSwgYW55LCBWLCBhbnksIGFueT4sXG4gIGRhdGFUb0FkZD86IFZcbikge1xuICByZXR1cm4gKHRhcmdldDogb2JqZWN0LCBwcm9wZXJ0eUtleT86IGFueSkgPT4ge1xuICAgIGNvbnN0IG5hbWUgPSB0YXJnZXQuY29uc3RydWN0b3IubmFtZTtcbiAgICBjb25zdCBkZWNvcmF0b3JzID0gb3BlcmF0aW9uLnJlZHVjZSgoYWNjdW06IGFueVtdLCBvcCkgPT4ge1xuICAgICAgY29uc3QgY29tcG91bmRLZXkgPSBiYXNlT3AgKyBvcDtcbiAgICAgIGxldCBkYXRhID0gUmVmbGVjdC5nZXRNZXRhZGF0YShcbiAgICAgICAgT3BlcmF0aW9ucy5rZXkoY29tcG91bmRLZXkpLFxuICAgICAgICB0YXJnZXQsXG4gICAgICAgIHByb3BlcnR5S2V5XG4gICAgICApO1xuICAgICAgaWYgKCFkYXRhKVxuICAgICAgICBkYXRhID0ge1xuICAgICAgICAgIG9wZXJhdGlvbjogb3AsXG4gICAgICAgICAgaGFuZGxlcnM6IHt9LFxuICAgICAgICB9O1xuXG4gICAgICBjb25zdCBoYW5kbGVyS2V5ID0gT3BlcmF0aW9ucy5nZXRIYW5kbGVyTmFtZShoYW5kbGVyKTtcblxuICAgICAgaWYgKFxuICAgICAgICAhZGF0YS5oYW5kbGVyc1tuYW1lXSB8fFxuICAgICAgICAhZGF0YS5oYW5kbGVyc1tuYW1lXVtwcm9wZXJ0eUtleV0gfHxcbiAgICAgICAgIShoYW5kbGVyS2V5IGluIGRhdGEuaGFuZGxlcnNbbmFtZV1bcHJvcGVydHlLZXldKVxuICAgICAgKSB7XG4gICAgICAgIGRhdGEuaGFuZGxlcnNbbmFtZV0gPSBkYXRhLmhhbmRsZXJzW25hbWVdIHx8IHt9O1xuICAgICAgICBkYXRhLmhhbmRsZXJzW25hbWVdW3Byb3BlcnR5S2V5XSA9XG4gICAgICAgICAgZGF0YS5oYW5kbGVyc1tuYW1lXVtwcm9wZXJ0eUtleV0gfHwge307XG4gICAgICAgIGRhdGEuaGFuZGxlcnNbbmFtZV1bcHJvcGVydHlLZXldW2hhbmRsZXJLZXldID0ge1xuICAgICAgICAgIGRhdGE6IGRhdGFUb0FkZCxcbiAgICAgICAgfTtcblxuICAgICAgICBhY2N1bS5wdXNoKFxuICAgICAgICAgIGhhbmRsZShjb21wb3VuZEtleSBhcyBPcGVyYXRpb25LZXlzLCBoYW5kbGVyKSxcbiAgICAgICAgICBwcm9wTWV0YWRhdGEoT3BlcmF0aW9ucy5rZXkoY29tcG91bmRLZXkpLCBkYXRhKVxuICAgICAgICApO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sIFtdKTtcbiAgICByZXR1cm4gYXBwbHkoLi4uZGVjb3JhdG9ycykodGFyZ2V0LCBwcm9wZXJ0eUtleSk7XG4gIH07XG59XG4iLCIvKipcbiAqIEBkZXNjcmlwdGlvbiBCYXNlIGVycm9yIGNsYXNzIGZvciB0aGUgcmVwb3NpdG9yeSBtb2R1bGVcbiAqIEBzdW1tYXJ5IEFic3RyYWN0IGJhc2UgZXJyb3IgY2xhc3MgdGhhdCBhbGwgb3RoZXIgZXJyb3IgdHlwZXMgZXh0ZW5kIGZyb20uIFByb3ZpZGVzIGNvbW1vbiBlcnJvciBoYW5kbGluZyBmdW5jdGlvbmFsaXR5LlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZXJyb3JcbiAqIEBwYXJhbSB7c3RyaW5nfEVycm9yfSBtc2cgLSBUaGUgZXJyb3IgbWVzc2FnZSBvciBFcnJvciBvYmplY3RcbiAqIEBwYXJhbSB7bnVtYmVyfSBjb2RlIC0gVGhlIEhUVFAgc3RhdHVzIGNvZGUgYXNzb2NpYXRlZCB3aXRoIHRoaXMgZXJyb3JcbiAqIEBjbGFzcyBCYXNlRXJyb3JcbiAqIEBleGFtcGxlXG4gKiAvLyBUaGlzIGlzIGFuIGFic3RyYWN0IGNsYXNzIGFuZCBzaG91bGQgbm90IGJlIGluc3RhbnRpYXRlZCBkaXJlY3RseVxuICogLy8gSW5zdGVhZCwgdXNlIG9uZSBvZiB0aGUgY29uY3JldGUgZXJyb3IgY2xhc3NlczpcbiAqIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0ludmFsaWQgZGF0YSBwcm92aWRlZCcpO1xuICovXG5leHBvcnQgYWJzdHJhY3QgY2xhc3MgQmFzZUVycm9yIGV4dGVuZHMgRXJyb3Ige1xuICByZWFkb25seSBjb2RlITogbnVtYmVyO1xuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IobmFtZTogc3RyaW5nLCBtc2c6IHN0cmluZyB8IEVycm9yLCBjb2RlOiBudW1iZXIgPSA1MDApIHtcbiAgICBpZiAobXNnIGluc3RhbmNlb2YgQmFzZUVycm9yKSByZXR1cm4gbXNnO1xuICAgIGNvbnN0IG1lc3NhZ2UgPSBgWyR7bmFtZX1dICR7bXNnIGluc3RhbmNlb2YgRXJyb3IgPyBtc2cubWVzc2FnZSA6IG1zZ31gO1xuICAgIHN1cGVyKG1lc3NhZ2UpO1xuICAgIHRoaXMuY29kZSA9IGNvZGU7XG4gICAgaWYgKG1zZyBpbnN0YW5jZW9mIEVycm9yKSB0aGlzLnN0YWNrID0gbXNnLnN0YWNrO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVycm9yIHRocm93biB3aGVuIHZhbGlkYXRpb24gZmFpbHNcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBmYWlsdXJlIGluIHRoZSBNb2RlbCBkZXRhaWxzLCB0eXBpY2FsbHkgdGhyb3duIHdoZW4gZGF0YSB2YWxpZGF0aW9uIGZhaWxzXG4gKiBAcGFyYW0ge3N0cmluZ3xFcnJvcn0gbXNnIC0gVGhlIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0XG4gKiBAcmV0dXJuIHtWYWxpZGF0aW9uRXJyb3J9IEEgbmV3IFZhbGlkYXRpb25FcnJvciBpbnN0YW5jZVxuICogQGNsYXNzIFZhbGlkYXRpb25FcnJvclxuICogQGV4YW1wbGVcbiAqIC8vIFRocm93IGEgdmFsaWRhdGlvbiBlcnJvciB3aGVuIGRhdGEgaXMgaW52YWxpZFxuICogaWYgKCFpc1ZhbGlkKGRhdGEpKSB7XG4gKiAgIHRocm93IG5ldyBWYWxpZGF0aW9uRXJyb3IoJ0ludmFsaWQgZGF0YSBmb3JtYXQnKTtcbiAqIH1cbiAqL1xuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihWYWxpZGF0aW9uRXJyb3IubmFtZSwgbXNnLCA0MjIpO1xuICB9XG59XG4vKipcbiAqIEBkZXNjcmlwdGlvbiBFcnJvciB0aHJvd24gZm9yIGludGVybmFsIHN5c3RlbSBmYWlsdXJlc1xuICogQHN1bW1hcnkgUmVwcmVzZW50cyBhbiBpbnRlcm5hbCBmYWlsdXJlIChzaG91bGQgbWVhbiBhbiBlcnJvciBpbiBjb2RlKSB3aXRoIEhUVFAgNTAwIHN0YXR1cyBjb2RlXG4gKiBAcGFyYW0ge3N0cmluZ3xFcnJvcn0gbXNnIC0gVGhlIGVycm9yIG1lc3NhZ2Ugb3IgRXJyb3Igb2JqZWN0XG4gKiBAcmV0dXJuIHtJbnRlcm5hbEVycm9yfSBBIG5ldyBJbnRlcm5hbEVycm9yIGluc3RhbmNlXG4gKiBAY2xhc3MgSW50ZXJuYWxFcnJvclxuICogQGV4YW1wbGVcbiAqIC8vIFRocm93IGFuIGludGVybmFsIGVycm9yIHdoZW4gYW4gdW5leHBlY3RlZCBjb25kaXRpb24gb2NjdXJzXG4gKiB0cnkge1xuICogICAvLyBTb21lIG9wZXJhdGlvblxuICogfSBjYXRjaCAoZXJyb3IpIHtcbiAqICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoJ1VuZXhwZWN0ZWQgaW50ZXJuYWwgZXJyb3Igb2NjdXJyZWQnKTtcbiAqIH1cbiAqL1xuZXhwb3J0IGNsYXNzIEludGVybmFsRXJyb3IgZXh0ZW5kcyBCYXNlRXJyb3Ige1xuICBjb25zdHJ1Y3Rvcihtc2c6IHN0cmluZyB8IEVycm9yKSB7XG4gICAgc3VwZXIoSW50ZXJuYWxFcnJvci5uYW1lLCBtc2csIDUwMCk7XG4gIH1cbn1cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVycm9yIHRocm93biB3aGVuIHNlcmlhbGl6YXRpb24gb3IgZGVzZXJpYWxpemF0aW9uIGZhaWxzXG4gKiBAc3VtbWFyeSBSZXByZXNlbnRzIGEgZmFpbHVyZSBpbiB0aGUgTW9kZWwgZGUvc2VyaWFsaXphdGlvbiwgdHlwaWNhbGx5IHdoZW4gY29udmVydGluZyBiZXR3ZWVuIGRhdGEgZm9ybWF0c1xuICogQHBhcmFtIHtzdHJpbmd8RXJyb3J9IG1zZyAtIFRoZSBlcnJvciBtZXNzYWdlIG9yIEVycm9yIG9iamVjdFxuICogQHJldHVybiB7U2VyaWFsaXphdGlvbkVycm9yfSBBIG5ldyBTZXJpYWxpemF0aW9uRXJyb3IgaW5zdGFuY2VcbiAqIEBjbGFzcyBTZXJpYWxpemF0aW9uRXJyb3JcbiAqIEBleGFtcGxlXG4gKiAvLyBUaHJvdyBhIHNlcmlhbGl6YXRpb24gZXJyb3Igd2hlbiBKU09OIHBhcnNpbmcgZmFpbHNcbiAqIHRyeSB7XG4gKiAgIGNvbnN0IGRhdGEgPSBKU09OLnBhcnNlKGludmFsaWRKc29uKTtcbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIHRocm93IG5ldyBTZXJpYWxpemF0aW9uRXJyb3IoJ0ZhaWxlZCB0byBwYXJzZSBKU09OIGRhdGEnKTtcbiAqIH1cbiAqL1xuZXhwb3J0IGNsYXNzIFNlcmlhbGl6YXRpb25FcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihTZXJpYWxpemF0aW9uRXJyb3IubmFtZSwgbXNnLCA0MjIpO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVycm9yIHRocm93biB3aGVuIGEgcmVxdWVzdGVkIHJlc291cmNlIGlzIG5vdCBmb3VuZFxuICogQHN1bW1hcnkgUmVwcmVzZW50cyBhIGZhaWx1cmUgaW4gZmluZGluZyBhIG1vZGVsLCByZXN1bHRpbmcgaW4gYSA0MDQgSFRUUCBzdGF0dXMgY29kZVxuICogQHBhcmFtIHtzdHJpbmd8RXJyb3J9IG1zZyAtIFRoZSBlcnJvciBtZXNzYWdlIG9yIEVycm9yIG9iamVjdFxuICogQHJldHVybiB7Tm90Rm91bmRFcnJvcn0gQSBuZXcgTm90Rm91bmRFcnJvciBpbnN0YW5jZVxuICogQGNsYXNzIE5vdEZvdW5kRXJyb3JcbiAqIEBleGFtcGxlXG4gKiAvLyBUaHJvdyBhIG5vdCBmb3VuZCBlcnJvciB3aGVuIGEgcmVjb3JkIGRvZXNuJ3QgZXhpc3RcbiAqIGNvbnN0IHVzZXIgPSBhd2FpdCByZXBvc2l0b3J5LmZpbmRCeUlkKGlkKTtcbiAqIGlmICghdXNlcikge1xuICogICB0aHJvdyBuZXcgTm90Rm91bmRFcnJvcihgVXNlciB3aXRoIElEICR7aWR9IG5vdCBmb3VuZGApO1xuICogfVxuICovXG5leHBvcnQgY2xhc3MgTm90Rm91bmRFcnJvciBleHRlbmRzIEJhc2VFcnJvciB7XG4gIGNvbnN0cnVjdG9yKG1zZzogc3RyaW5nIHwgRXJyb3IpIHtcbiAgICBzdXBlcihOb3RGb3VuZEVycm9yLm5hbWUsIG1zZywgNDA0KTtcbiAgfVxufVxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRXJyb3IgdGhyb3duIHdoZW4gYSBjb25mbGljdCBvY2N1cnMgaW4gdGhlIHN0b3JhZ2VcbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgYSBjb25mbGljdCBpbiB0aGUgc3RvcmFnZSwgdHlwaWNhbGx5IHdoZW4gdHJ5aW5nIHRvIGNyZWF0ZSBhIGR1cGxpY2F0ZSByZXNvdXJjZVxuICogQHBhcmFtIHtzdHJpbmd8RXJyb3J9IG1zZyAtIFRoZSBlcnJvciBtZXNzYWdlIG9yIEVycm9yIG9iamVjdFxuICogQHJldHVybiB7Q29uZmxpY3RFcnJvcn0gQSBuZXcgQ29uZmxpY3RFcnJvciBpbnN0YW5jZVxuICogQGNsYXNzIENvbmZsaWN0RXJyb3JcbiAqIEBleGFtcGxlXG4gKiAvLyBUaHJvdyBhIGNvbmZsaWN0IGVycm9yIHdoZW4gdHJ5aW5nIHRvIGNyZWF0ZSBhIGR1cGxpY2F0ZSByZWNvcmRcbiAqIGNvbnN0IGV4aXN0aW5nVXNlciA9IGF3YWl0IHJlcG9zaXRvcnkuZmluZEJ5RW1haWwoZW1haWwpO1xuICogaWYgKGV4aXN0aW5nVXNlcikge1xuICogICB0aHJvdyBuZXcgQ29uZmxpY3RFcnJvcihgVXNlciB3aXRoIGVtYWlsICR7ZW1haWx9IGFscmVhZHkgZXhpc3RzYCk7XG4gKiB9XG4gKi9cbmV4cG9ydCBjbGFzcyBDb25mbGljdEVycm9yIGV4dGVuZHMgQmFzZUVycm9yIHtcbiAgY29uc3RydWN0b3IobXNnOiBzdHJpbmcgfCBFcnJvcikge1xuICAgIHN1cGVyKENvbmZsaWN0RXJyb3IubmFtZSwgbXNnLCA0MDkpO1xuICB9XG59XG4iLCJpbXBvcnQgeyBPcGVyYXRpb25zIH0gZnJvbSBcIi4uL29wZXJhdGlvbnMvT3BlcmF0aW9uc1wiO1xuaW1wb3J0IHsgT3BlcmF0aW9uSGFuZGxlciwgVXBkYXRlT3BlcmF0aW9uSGFuZGxlciB9IGZyb20gXCIuLi9vcGVyYXRpb25zL3R5cGVzXCI7XG5pbXBvcnQgeyBJUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL0lSZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4uL29wZXJhdGlvbnMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBEZWNvcmF0b3JNZXRhZGF0YSwgUmVmbGVjdGlvbiB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgSW50ZXJuYWxFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsLCBNb2RlbEtleXMgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4vQ29udGV4dFwiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeUZsYWdzIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29udGV4dCBhcmd1bWVudHMgZm9yIHJlcG9zaXRvcnkgb3BlcmF0aW9ucy5cbiAqIEBzdW1tYXJ5IFJlcHJlc2VudHMgdGhlIGNvbnRleHQgYW5kIGFyZ3VtZW50cyBmb3IgcmVwb3NpdG9yeSBvcGVyYXRpb25zLlxuICogVGhpcyB0eXBlIGlzIHVzZWQgdG8gcGFzcyBjb250ZXh0IGFuZCBhcmd1bWVudHMgYmV0d2VlbiByZXBvc2l0b3J5IG1ldGhvZHMuXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGUsIGRlZmF1bHRzIHRvIFJlcG9zaXRvcnlGbGFnc1xuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlLCBkZWZhdWx0cyB0byBDb250ZXh0PEY+XG4gKiBAdHlwZWRlZiB7T2JqZWN0fSBDb250ZXh0QXJnc1xuICogQHByb3BlcnR5IHtDfSBjb250ZXh0IC0gVGhlIG9wZXJhdGlvbiBjb250ZXh0XG4gKiBAcHJvcGVydHkge2FueVtdfSBhcmdzIC0gVGhlIG9wZXJhdGlvbiBhcmd1bWVudHNcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5leHBvcnQgdHlwZSBDb250ZXh0QXJnczxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4gPSBDb250ZXh0PEY+LFxuPiA9IHtcbiAgY29udGV4dDogQztcbiAgYXJnczogYW55W107XG59O1xuXG4vKipcbiAqIEBzdW1tYXJ5IHJldHJpZXZlcyB0aGUgYXJndW1lbnRzIGZvciB0aGUgaGFuZGxlclxuICogQHBhcmFtIHthbnl9IGRlYyB0aGUgZGVjb3JhdG9yXG4gKiBAcGFyYW0ge3N0cmluZ30gcHJvcCB0aGUgcHJvcGVydHkgbmFtZVxuICogQHBhcmFtIHt7fX0gbSB0aGUgbW9kZWxcbiAqIEBwYXJhbSB7e319IFthY2N1bV0gYWNjdW11bGF0b3IgdXNlZCBmb3IgaW50ZXJuYWwgcmVjdXJzaXZlbmVzc1xuICpcbiAqIEBmdW5jdGlvbiBnZXRIYW5kbGVyQXJnc1xuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzLlJlcG9zaXRvcnlcbiAqL1xuZXhwb3J0IGNvbnN0IGdldEhhbmRsZXJBcmdzID0gZnVuY3Rpb24gKFxuICBkZWM6IGFueSxcbiAgcHJvcDogc3RyaW5nLFxuICBtOiBDb25zdHJ1Y3Rvcjxhbnk+LFxuICBhY2N1bT86IFJlY29yZDxzdHJpbmcsIHsgYXJnczogc3RyaW5nW10gfT5cbik6IFJlY29yZDxzdHJpbmcsIHsgYXJnczogc3RyaW5nW10gfT4gfCB2b2lkIHtcbiAgY29uc3QgbmFtZSA9IG0uY29uc3RydWN0b3IubmFtZTtcbiAgaWYgKCFuYW1lKSB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkNvdWxkIG5vdCBkZXRlcm1pbmUgbW9kZWwgY2xhc3NcIik7XG4gIGFjY3VtID0gYWNjdW0gfHwge307XG5cbiAgaWYgKGRlYy5wcm9wcy5oYW5kbGVyc1tuYW1lXSAmJiBkZWMucHJvcHMuaGFuZGxlcnNbbmFtZV1bcHJvcF0pXG4gICAgYWNjdW0gPSB7IC4uLmRlYy5wcm9wcy5oYW5kbGVyc1tuYW1lXVtwcm9wXSwgLi4uYWNjdW0gfTtcblxuICBsZXQgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YobSk7XG4gIGlmIChwcm90byA9PT0gT2JqZWN0LnByb3RvdHlwZSkgcmV0dXJuIGFjY3VtO1xuICBpZiAocHJvdG8uY29uc3RydWN0b3IubmFtZSA9PT0gbmFtZSkgcHJvdG8gPSBPYmplY3QuZ2V0UHJvdG90eXBlT2YocHJvdG8pO1xuXG4gIHJldHVybiBnZXRIYW5kbGVyQXJncyhkZWMsIHByb3AsIHByb3RvLCBhY2N1bSk7XG59O1xuXG4vKipcbiAqXG4gKiBAcGFyYW0ge0lSZXBvc2l0b3J5PFQ+fSByZXBvXG4gKiBAcGFyYW0gY29udGV4dFxuICogQHBhcmFtIHtUfSBtb2RlbFxuICogQHBhcmFtIG9wZXJhdGlvblxuICogQHBhcmFtIHByZWZpeFxuICpcbiAqIEBwYXJhbSBvbGRNb2RlbFxuICogQGZ1bmN0aW9uIGVuZm9yY2VEQlByb3BlcnR5RGVjb3JhdG9yc0FzeW5jXG4gKlxuICogQG1lbWJlck9mIGRiLWRlY29yYXRvcnMudXRpbHNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGVuZm9yY2VEQkRlY29yYXRvcnM8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIElSZXBvc2l0b3J5PE0sIEYsIEM+LFxuICBWIGV4dGVuZHMgb2JqZWN0ID0gb2JqZWN0LFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzID0gUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4+KFxuICByZXBvOiBSLFxuICBjb250ZXh0OiBDLFxuICBtb2RlbDogTSxcbiAgb3BlcmF0aW9uOiBzdHJpbmcsXG4gIHByZWZpeDogc3RyaW5nLFxuICBvbGRNb2RlbD86IE1cbik6IFByb21pc2U8dm9pZD4ge1xuICBjb25zdCBkZWNvcmF0b3JzOiBSZWNvcmQ8c3RyaW5nLCBEZWNvcmF0b3JNZXRhZGF0YVtdPiB8IHVuZGVmaW5lZCA9XG4gICAgZ2V0RGJEZWNvcmF0b3JzKG1vZGVsLCBvcGVyYXRpb24sIHByZWZpeCk7XG5cbiAgaWYgKCFkZWNvcmF0b3JzKSByZXR1cm47XG5cbiAgZm9yIChjb25zdCBwcm9wIGluIGRlY29yYXRvcnMpIHtcbiAgICBjb25zdCBkZWNzOiBEZWNvcmF0b3JNZXRhZGF0YVtdID0gZGVjb3JhdG9yc1twcm9wXTtcbiAgICBmb3IgKGNvbnN0IGRlYyBvZiBkZWNzKSB7XG4gICAgICBjb25zdCB7IGtleSB9ID0gZGVjO1xuICAgICAgY29uc3QgaGFuZGxlcnM6IE9wZXJhdGlvbkhhbmRsZXI8TSwgUiwgViwgRiwgQz5bXSB8IHVuZGVmaW5lZCA9XG4gICAgICAgIE9wZXJhdGlvbnMuZ2V0PE0sIFIsIFYsIEYsIEM+KG1vZGVsLCBwcm9wLCBwcmVmaXggKyBrZXkpO1xuICAgICAgaWYgKCFoYW5kbGVycyB8fCAhaGFuZGxlcnMubGVuZ3RoKVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgICAgICBgQ291bGQgbm90IGZpbmQgcmVnaXN0ZXJlZCBoYW5kbGVyIGZvciB0aGUgb3BlcmF0aW9uICR7cHJlZml4ICsga2V5fSB1bmRlciBwcm9wZXJ0eSAke3Byb3B9YFxuICAgICAgICApO1xuXG4gICAgICBjb25zdCBoYW5kbGVyQXJncyA9IGdldEhhbmRsZXJBcmdzKGRlYywgcHJvcCwgbW9kZWwgYXMgYW55KTtcblxuICAgICAgaWYgKCFoYW5kbGVyQXJncyB8fCBPYmplY3QudmFsdWVzKGhhbmRsZXJBcmdzKS5sZW5ndGggIT09IGhhbmRsZXJzLmxlbmd0aClcbiAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJBcmdzIGFuZCBoYW5kbGVycyBsZW5ndGggZG8gbm90IG1hdGNoXCIpO1xuXG4gICAgICBsZXQgaGFuZGxlcjogT3BlcmF0aW9uSGFuZGxlcjxNLCBSLCBWLCBGLCBDPjtcbiAgICAgIGxldCBkYXRhOiBhbnk7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGhhbmRsZXJzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIGhhbmRsZXIgPSBoYW5kbGVyc1tpXTtcbiAgICAgICAgZGF0YSA9IE9iamVjdC52YWx1ZXMoaGFuZGxlckFyZ3MpW2ldO1xuXG4gICAgICAgIGNvbnN0IGFyZ3M6IGFueVtdID0gW2NvbnRleHQsIGRhdGEuZGF0YSwgcHJvcCwgbW9kZWxdO1xuXG4gICAgICAgIGlmIChvcGVyYXRpb24gPT09IE9wZXJhdGlvbktleXMuVVBEQVRFICYmIHByZWZpeCA9PT0gT3BlcmF0aW9uS2V5cy5PTikge1xuICAgICAgICAgIGlmICghb2xkTW9kZWwpXG4gICAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIk1pc3Npbmcgb2xkIG1vZGVsIGZvciB1cGRhdGUgb3BlcmF0aW9uXCIpO1xuICAgICAgICAgIGFyZ3MucHVzaChvbGRNb2RlbCk7XG4gICAgICAgIH1cbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhd2FpdCAoaGFuZGxlciBhcyBVcGRhdGVPcGVyYXRpb25IYW5kbGVyPE0sIFIsIFYsIEYsIEM+KS5hcHBseShcbiAgICAgICAgICAgIHJlcG8sXG4gICAgICAgICAgICBhcmdzIGFzIFtDLCBWLCBrZXlvZiBNLCBNLCBNXVxuICAgICAgICAgICk7XG4gICAgICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgICAgICBjb25zdCBtc2cgPSBgRmFpbGVkIHRvIGV4ZWN1dGUgaGFuZGxlciAke2hhbmRsZXIubmFtZX0gZm9yICR7cHJvcH0gb24gJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfSBkdWUgdG8gZXJyb3I6ICR7ZX1gO1xuICAgICAgICAgIGlmIChjb250ZXh0LmdldChcImJyZWFrT25IYW5kbGVyRXJyb3JcIikpIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKG1zZyk7XG4gICAgICAgICAgY29uc29sZS5sb2cobXNnKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNwZWNpZmljIGZvciBEQiBEZWNvcmF0b3JzXG4gKiBAcGFyYW0ge1R9IG1vZGVsXG4gKiBAcGFyYW0ge3N0cmluZ30gb3BlcmF0aW9uIENSVUQge0BsaW5rIE9wZXJhdGlvbktleXN9XG4gKiBAcGFyYW0ge3N0cmluZ30gW2V4dHJhUHJlZml4XVxuICpcbiAqIEBmdW5jdGlvbiBnZXREYlByb3BlcnR5RGVjb3JhdG9yc1xuICpcbiAqIEBtZW1iZXJPZiBkYi1kZWNvcmF0b3JzLnV0aWxzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREYkRlY29yYXRvcnM8VCBleHRlbmRzIE1vZGVsPihcbiAgbW9kZWw6IFQsXG4gIG9wZXJhdGlvbjogc3RyaW5nLFxuICBleHRyYVByZWZpeD86IHN0cmluZ1xuKTogUmVjb3JkPHN0cmluZywgRGVjb3JhdG9yTWV0YWRhdGFbXT4gfCB1bmRlZmluZWQge1xuICBjb25zdCBkZWNvcmF0b3JzOiBSZWNvcmQ8c3RyaW5nLCBEZWNvcmF0b3JNZXRhZGF0YVtdPiB8IHVuZGVmaW5lZCA9XG4gICAgUmVmbGVjdGlvbi5nZXRBbGxQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICBtb2RlbCxcbiAgICAgIC8vIHVuZGVmaW5lZCxcbiAgICAgIE9wZXJhdGlvbktleXMuUkVGTEVDVCArIChleHRyYVByZWZpeCA/IGV4dHJhUHJlZml4IDogXCJcIilcbiAgICApO1xuICBpZiAoIWRlY29yYXRvcnMpIHJldHVybjtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKGRlY29yYXRvcnMpLnJlZHVjZShcbiAgICAoYWNjdW06IFJlY29yZDxzdHJpbmcsIERlY29yYXRvck1ldGFkYXRhW10+IHwgdW5kZWZpbmVkLCBkZWNvcmF0b3IpID0+IHtcbiAgICAgIGNvbnN0IGRlYyA9IGRlY29yYXRvcnNbZGVjb3JhdG9yXS5maWx0ZXIoKGQpID0+IGQua2V5ID09PSBvcGVyYXRpb24pO1xuICAgICAgaWYgKGRlYyAmJiBkZWMubGVuZ3RoKSB7XG4gICAgICAgIGlmICghYWNjdW0pIGFjY3VtID0ge307XG4gICAgICAgIGFjY3VtW2RlY29yYXRvcl0gPSBkZWM7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSxcbiAgICB1bmRlZmluZWRcbiAgKTtcbn1cblxuLyoqXG4gKiBAc3VtbWFyeSBSZXRyaWV2ZXMgdGhlIGRlY29yYXRvcnMgZm9yIGFuIG9iamVjdCdzIHByb3BlcnRpZXMgcHJlZml4ZWQgYnkge0BwYXJhbSBwcmVmaXhlc30gcmVjdXJzaXZlbHlcbiAqIEBwYXJhbSBtb2RlbFxuICogQHBhcmFtIGFjY3VtXG4gKiBAcGFyYW0gcHJlZml4ZXNcbiAqXG4gKiBAZnVuY3Rpb24gZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnMuUmVwb3NpdG9yeVxuICovXG5leHBvcnQgY29uc3QgZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlID0gZnVuY3Rpb24gPFQgZXh0ZW5kcyBNb2RlbD4oXG4gIG1vZGVsOiBULFxuICBhY2N1bTogeyBbaW5kZXhlcjogc3RyaW5nXTogYW55W10gfSB8IHVuZGVmaW5lZCxcbiAgLi4ucHJlZml4ZXM6IHN0cmluZ1tdXG4pOiB7IFtpbmRleGVyOiBzdHJpbmddOiBhbnlbXSB9IHwgdW5kZWZpbmVkIHtcbiAgY29uc3QgYWNjdW11bGF0b3IgPSBhY2N1bSB8fCB7fTtcbiAgY29uc3QgbWVyZ2VEZWNvcmF0b3JzID0gZnVuY3Rpb24gKGRlY3M6IHsgW2luZGV4ZXI6IHN0cmluZ106IGFueVtdIH0pIHtcbiAgICBjb25zdCBwdXNoT3JTcXVhc2ggPSAoa2V5OiBzdHJpbmcsIC4uLnZhbHVlczogYW55W10pID0+IHtcbiAgICAgIHZhbHVlcy5mb3JFYWNoKCh2YWwpID0+IHtcbiAgICAgICAgbGV0IG1hdGNoOiBhbnk7XG4gICAgICAgIGlmIChcbiAgICAgICAgICAhKG1hdGNoID0gYWNjdW11bGF0b3Jba2V5XS5maW5kKChlKSA9PiBlLmtleSA9PT0gdmFsLmtleSkpIHx8XG4gICAgICAgICAgbWF0Y2gucHJvcHMub3BlcmF0aW9uICE9PSB2YWwucHJvcHMub3BlcmF0aW9uXG4gICAgICAgICkge1xuICAgICAgICAgIGFjY3VtdWxhdG9yW2tleV0ucHVzaCh2YWwpO1xuICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh2YWwua2V5ID09PSBNb2RlbEtleXMuVFlQRSkgcmV0dXJuO1xuXG4gICAgICAgIGNvbnN0IHsgaGFuZGxlcnMsIG9wZXJhdGlvbiB9ID0gdmFsLnByb3BzO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAhb3BlcmF0aW9uIHx8XG4gICAgICAgICAgIW9wZXJhdGlvbi5tYXRjaChcbiAgICAgICAgICAgIG5ldyBSZWdFeHAoXG4gICAgICAgICAgICAgIGBeKDo/JHtPcGVyYXRpb25LZXlzLk9OfXwke09wZXJhdGlvbktleXMuQUZURVJ9KSg6PyR7T3BlcmF0aW9uS2V5cy5DUkVBVEV9fCR7T3BlcmF0aW9uS2V5cy5SRUFEfXwke09wZXJhdGlvbktleXMuVVBEQVRFfXwke09wZXJhdGlvbktleXMuREVMRVRFfSkkYFxuICAgICAgICAgICAgKVxuICAgICAgICAgIClcbiAgICAgICAgKSB7XG4gICAgICAgICAgYWNjdW11bGF0b3Jba2V5XS5wdXNoKHZhbCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYWNjdW1IYW5kbGVycyA9IG1hdGNoLnByb3BzLmhhbmRsZXJzO1xuXG4gICAgICAgIE9iamVjdC5lbnRyaWVzKGhhbmRsZXJzKS5mb3JFYWNoKChbY2xhenosIGhhbmRsZXJEZWZdKSA9PiB7XG4gICAgICAgICAgaWYgKCEoY2xhenogaW4gYWNjdW1IYW5kbGVycykpIHtcbiAgICAgICAgICAgIGFjY3VtSGFuZGxlcnNbY2xhenpdID0gaGFuZGxlckRlZjtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICB9XG5cbiAgICAgICAgICBPYmplY3QuZW50cmllcyhoYW5kbGVyRGVmIGFzIG9iamVjdCkuZm9yRWFjaChcbiAgICAgICAgICAgIChbaGFuZGxlclByb3AsIGhhbmRsZXJdKSA9PiB7XG4gICAgICAgICAgICAgIGlmICghKGhhbmRsZXJQcm9wIGluIGFjY3VtSGFuZGxlcnNbY2xhenpdKSkge1xuICAgICAgICAgICAgICAgIGFjY3VtSGFuZGxlcnNbY2xhenpdW2hhbmRsZXJQcm9wXSA9IGhhbmRsZXI7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgT2JqZWN0LmVudHJpZXMoaGFuZGxlciBhcyBvYmplY3QpLmZvckVhY2goXG4gICAgICAgICAgICAgICAgKFtoYW5kbGVyS2V5LCBhcmdzT2JqXSkgPT4ge1xuICAgICAgICAgICAgICAgICAgaWYgKCEoaGFuZGxlcktleSBpbiBhY2N1bUhhbmRsZXJzW2NsYXp6XVtoYW5kbGVyUHJvcF0pKSB7XG4gICAgICAgICAgICAgICAgICAgIGFjY3VtSGFuZGxlcnNbY2xhenpdW2hhbmRsZXJQcm9wXVtoYW5kbGVyS2V5XSA9IGFyZ3NPYmo7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgIGNvbnNvbGUud2FybihcbiAgICAgICAgICAgICAgICAgICAgYFNraXBwaW5nIGhhbmRsZXIgcmVnaXN0cmF0aW9uIGZvciAke2NsYXp6fSB1bmRlciBwcm9wICR7aGFuZGxlclByb3B9IGJlY2F1c2UgaGFuZGxlciBpcyB0aGUgc2FtZWBcbiAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICk7XG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfTtcblxuICAgIE9iamVjdC5lbnRyaWVzKGRlY3MpLmZvckVhY2goKFtrZXksIHZhbHVlXSkgPT4ge1xuICAgICAgYWNjdW11bGF0b3Jba2V5XSA9IGFjY3VtdWxhdG9yW2tleV0gfHwgW107XG4gICAgICBwdXNoT3JTcXVhc2goa2V5LCAuLi52YWx1ZSk7XG4gICAgfSk7XG4gIH07XG5cbiAgY29uc3QgZGVjczogeyBbaW5kZXhlcjogc3RyaW5nXTogYW55W10gfSB8IHVuZGVmaW5lZCA9XG4gICAgUmVmbGVjdGlvbi5nZXRBbGxQcm9wZXJ0eURlY29yYXRvcnMobW9kZWwsIC4uLnByZWZpeGVzKTtcbiAgaWYgKGRlY3MpIG1lcmdlRGVjb3JhdG9ycyhkZWNzKTtcblxuICBpZiAoT2JqZWN0LmdldFByb3RvdHlwZU9mKG1vZGVsKSA9PT0gT2JqZWN0LnByb3RvdHlwZSkgcmV0dXJuIGFjY3VtdWxhdG9yO1xuXG4gIC8vIGNvbnN0IG5hbWUgPSBtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lO1xuICBjb25zdCBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihtb2RlbCk7XG4gIGlmICghcHJvdG8pIHJldHVybiBhY2N1bXVsYXRvcjtcbiAgLy8gaWYgKHByb3RvLmNvbnN0cnVjdG9yICYmIHByb3RvLmNvbnN0cnVjdG9yLm5hbWUgPT09IG5hbWUpXG4gIC8vICAgICBwcm90byA9IE9iamVjdC5nZXRQcm90b3R5cGVPZihwcm90bylcbiAgcmV0dXJuIGdldEFsbFByb3BlcnR5RGVjb3JhdG9yc1JlY3Vyc2l2ZShwcm90bywgYWNjdW11bGF0b3IsIC4uLnByZWZpeGVzKTtcbn07XG4iLCJpbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBEZWZhdWx0IGNvbmZpZ3VyYXRpb24gZmxhZ3MgZm9yIHJlcG9zaXRvcnkgb3BlcmF0aW9ucy5cbiAqIEBzdW1tYXJ5IFByb3ZpZGVzIGRlZmF1bHQgdmFsdWVzIGZvciByZXBvc2l0b3J5IG9wZXJhdGlvbiBmbGFncywgZXhjbHVkaW5nIHRoZSB0aW1lc3RhbXAgcHJvcGVydHkuXG4gKiBUaGVzZSBmbGFncyBjb250cm9sIGJlaGF2aW9yIHN1Y2ggYXMgY29udGV4dCBoYW5kbGluZywgdmFsaWRhdGlvbiwgZXJyb3IgaGFuZGxpbmcsIGFuZCBtb3JlLlxuICogQGNvbnN0IERlZmF1bHRSZXBvc2l0b3J5RmxhZ3NcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdFJlcG9zaXRvcnlGbGFnczogT21pdDxSZXBvc2l0b3J5RmxhZ3MsIFwidGltZXN0YW1wXCI+ID0ge1xuICBwYXJlbnRDb250ZXh0OiB1bmRlZmluZWQsXG4gIGNoaWxkQ29udGV4dHM6IFtdLFxuICBpZ25vcmVkVmFsaWRhdGlvblByb3BlcnRpZXM6IFtdLFxuICBjYWxsQXJnczogW10sXG4gIHdyaXRlT3BlcmF0aW9uOiBmYWxzZSxcbiAgYWZmZWN0ZWRUYWJsZXM6IFtdLFxuICBvcGVyYXRpb246IHVuZGVmaW5lZCxcbiAgYnJlYWtPbkhhbmRsZXJFcnJvcjogdHJ1ZSxcbiAgcmVidWlsZFdpdGhUcmFuc2llbnQ6IHRydWUsXG59O1xuIiwiaW1wb3J0IHsgQ29udGV4dEFyZ3MgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgQ29udGV4dHVhbCB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL0NvbnRleHR1YWxcIjtcbmltcG9ydCB7IE9wZXJhdGlvbktleXMgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy9jb25zdGFudHNcIjtcbmltcG9ydCB7IENvbnN0cnVjdG9yLCBNb2RlbCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IERlZmF1bHRSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi9jb25zdGFudHNcIjtcbmltcG9ydCB7IE9iamVjdEFjY3VtdWxhdG9yIH0gZnJvbSBcInR5cGVkLW9iamVjdC1hY2N1bXVsYXRvclwiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeUZsYWdzIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRmFjdG9yeSB0eXBlIGZvciBjcmVhdGluZyBjb250ZXh0IGluc3RhbmNlcy5cbiAqIEBzdW1tYXJ5IERlZmluZXMgYSBmdW5jdGlvbiB0eXBlIHRoYXQgY3JlYXRlcyBjb250ZXh0IGluc3RhbmNlcyB3aXRoIHNwZWNpZmljIHJlcG9zaXRvcnkgZmxhZ3MuXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGUgZXh0ZW5kaW5nIFJlcG9zaXRvcnlGbGFnc1xuICogQHR5cGVkZWYge0Z1bmN0aW9ufSBDb250ZXh0RmFjdG9yeVxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCB0eXBlIENvbnRleHRGYWN0b3J5PEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3M+ID0gPEMgZXh0ZW5kcyBDb250ZXh0PEY+PihcbiAgYXJnOiBPbWl0PEYsIFwidGltZXN0YW1wXCI+XG4pID0+IEM7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERlZmF1bHQgZmFjdG9yeSBmb3IgY3JlYXRpbmcgY29udGV4dCBpbnN0YW5jZXMuXG4gKiBAc3VtbWFyeSBBIGZhY3RvcnkgZnVuY3Rpb24gdGhhdCBjcmVhdGVzIG5ldyBDb250ZXh0IGluc3RhbmNlcyB3aXRoIHRoZSBwcm92aWRlZCByZXBvc2l0b3J5IGZsYWdzLlxuICogSXQgYXV0b21hdGljYWxseSBhZGRzIGEgdGltZXN0YW1wIHRvIHRoZSBjb250ZXh0IGFuZCByZXR1cm5zIGEgcHJvcGVybHkgdHlwZWQgY29udGV4dCBpbnN0YW5jZS5cbiAqIEBjb25zdCBEZWZhdWx0Q29udGV4dEZhY3RvcnlcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5leHBvcnQgY29uc3QgRGVmYXVsdENvbnRleHRGYWN0b3J5OiBDb250ZXh0RmFjdG9yeTxhbnk+ID0gPFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPixcbj4oXG4gIGFyZzogT21pdDxGLCBcInRpbWVzdGFtcFwiPlxuKSA9PiB7XG4gIHJldHVybiBuZXcgQ29udGV4dDxGPigpLmFjY3VtdWxhdGUoXG4gICAgT2JqZWN0LmFzc2lnbih7fSwgYXJnLCB7IHRpbWVzdGFtcDogbmV3IERhdGUoKSB9KSBhcyBGXG4gICkgYXMgQztcbn07XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEEgY29udGV4dCBtYW5hZ2VtZW50IGNsYXNzIGZvciBoYW5kbGluZyByZXBvc2l0b3J5IG9wZXJhdGlvbnMuXG4gKiBAc3VtbWFyeSBUaGUgQ29udGV4dCBjbGFzcyBwcm92aWRlcyBhIG1lY2hhbmlzbSBmb3IgbWFuYWdpbmcgcmVwb3NpdG9yeSBvcGVyYXRpb25zIHdpdGggZmxhZ3MsXG4gKiBwYXJlbnQtY2hpbGQgcmVsYXRpb25zaGlwcywgYW5kIHN0YXRlIGFjY3VtdWxhdGlvbi4gSXQgYWxsb3dzIGZvciBoaWVyYXJjaGljYWwgY29udGV4dCBjaGFpbnNcbiAqIGFuZCBtYWludGFpbnMgb3BlcmF0aW9uLXNwZWNpZmljIGNvbmZpZ3VyYXRpb25zIHdoaWxlIHN1cHBvcnRpbmcgdHlwZSBzYWZldHkgdGhyb3VnaCBnZW5lcmljcy5cbiAqXG4gKiBAdGVtcGxhdGUgRiAtIFR5cGUgZXh0ZW5kaW5nIFJlcG9zaXRvcnlGbGFncyB0aGF0IGRlZmluZXMgdGhlIGNvbnRleHQgY29uZmlndXJhdGlvblxuICpcbiAqIEBwYXJhbSB7T2JqZWN0QWNjdW11bGF0b3I8Rj59IGNhY2hlIC0gVGhlIGludGVybmFsIGNhY2hlIHN0b3JpbmcgYWNjdW11bGF0ZWQgdmFsdWVzXG4gKlxuICogQGNsYXNzXG4gKlxuICogQGV4YW1wbGVcbiAqIGBgYHR5cGVzY3JpcHRcbiAqIC8vIENyZWF0aW5nIGEgbmV3IGNvbnRleHQgd2l0aCByZXBvc2l0b3J5IGZsYWdzXG4gKiBjb25zdCBjb250ZXh0ID0gbmV3IENvbnRleHQ8UmVwb3NpdG9yeUZsYWdzPigpO1xuICpcbiAqIC8vIEFjY3VtdWxhdGluZyB2YWx1ZXNcbiAqIGNvbnN0IGVucmljaGVkQ29udGV4dCA9IGNvbnRleHQuYWNjdW11bGF0ZSh7XG4gKiAgIHdyaXRlT3BlcmF0aW9uOiB0cnVlLFxuICogICBhZmZlY3RlZFRhYmxlczogWyd1c2VycyddLFxuICogICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMuQ1JFQVRFXG4gKiB9KTtcbiAqXG4gKiAvLyBBY2Nlc3NpbmcgdmFsdWVzXG4gKiBjb25zdCBpc1dyaXRlID0gZW5yaWNoZWRDb250ZXh0LmdldCgnd3JpdGVPcGVyYXRpb24nKTsgLy8gdHJ1ZVxuICogY29uc3QgdGFibGVzID0gZW5yaWNoZWRDb250ZXh0LmdldCgnYWZmZWN0ZWRUYWJsZXMnKTsgLy8gWyd1c2VycyddXG4gKiBgYGBcbiAqXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IEMgYXMgQ2xpZW50XG4gKiAgIHBhcnRpY2lwYW50IEN0eCBhcyBDb250ZXh0XG4gKiAgIHBhcnRpY2lwYW50IENhY2hlIGFzIE9iamVjdEFjY3VtdWxhdG9yXG4gKlxuICogICBDLT4+Q3R4OiBuZXcgQ29udGV4dCgpXG4gKiAgIEN0eC0+PkNhY2hlOiBjcmVhdGUgY2FjaGVcbiAqXG4gKiAgIEMtPj5DdHg6IGFjY3VtdWxhdGUodmFsdWUpXG4gKiAgIEN0eC0+PkNhY2hlOiBhY2N1bXVsYXRlKHZhbHVlKVxuICogICBDYWNoZS0tPj5DdHg6IHVwZGF0ZWQgY2FjaGVcbiAqICAgQ3R4LS0+PkM6IHVwZGF0ZWQgY29udGV4dFxuICpcbiAqICAgQy0+PkN0eDogZ2V0KGtleSlcbiAqICAgQ3R4LT4+Q2FjaGU6IGdldChrZXkpXG4gKiAgIGFsdCBLZXkgZXhpc3RzIGluIGNhY2hlXG4gKiAgICAgQ2FjaGUtLT4+Q3R4OiB2YWx1ZVxuICogICBlbHNlIEtleSBub3QgZm91bmRcbiAqICAgICBDdHgtPj5DdHg6IGNoZWNrIHBhcmVudCBjb250ZXh0XG4gKiAgICAgYWx0IFBhcmVudCBleGlzdHNcbiAqICAgICAgIEN0eC0+PlBhcmVudDogZ2V0KGtleSlcbiAqICAgICAgIFBhcmVudC0tPj5DdHg6IHZhbHVlXG4gKiAgICAgZWxzZSBObyBwYXJlbnRcbiAqICAgICAgIEN0eC0tPj5DOiB0aHJvdyBlcnJvclxuICogICAgIGVuZFxuICogICBlbmRcbiAqICAgQ3R4LS0+PkM6IHJlcXVlc3RlZCB2YWx1ZVxuICovXG5leHBvcnQgY2xhc3MgQ29udGV4dDxGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzPiB7XG4gIGNvbnN0cnVjdG9yKCkge1xuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh0aGlzLCBcImNhY2hlXCIsIHtcbiAgICAgIHZhbHVlOiBuZXcgT2JqZWN0QWNjdW11bGF0b3I8Rj4oKSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIH0pO1xuICB9XG5cbiAgc3RhdGljIGZhY3Rvcnk6IENvbnRleHRGYWN0b3J5PGFueT4gPSBEZWZhdWx0Q29udGV4dEZhY3Rvcnk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBjYWNoZTogRiAmIE9iamVjdEFjY3VtdWxhdG9yPEY+ID1cbiAgICBuZXcgT2JqZWN0QWNjdW11bGF0b3IoKSBhcyBGICYgT2JqZWN0QWNjdW11bGF0b3I8Rj47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBBY2N1bXVsYXRlcyBuZXcgdmFsdWVzIGludG8gdGhlIGNvbnRleHQuXG4gICAqIEBzdW1tYXJ5IE1lcmdlcyB0aGUgcHJvdmlkZWQgdmFsdWUgb2JqZWN0IHdpdGggdGhlIGV4aXN0aW5nIGNvbnRleHQgc3RhdGUsXG4gICAqIGNyZWF0aW5nIGEgbmV3IGltbXV0YWJsZSBjYWNoZSBzdGF0ZS5cbiAgICpcbiAgICogQHRlbXBsYXRlIEYgLSBjdXJyZW50IGFjY3VtdWxhdG9yIHR5cGVcbiAgICogQHRlbXBsYXRlIFYgLSBUeXBlIGV4dGVuZGluZyBvYmplY3QgZm9yIHRoZSB2YWx1ZXMgdG8gYWNjdW11bGF0ZVxuICAgKiBAcGFyYW0ge1Z9IHZhbHVlIC0gVGhlIG9iamVjdCBjb250YWluaW5nIHZhbHVlcyB0byBhY2N1bXVsYXRlXG4gICAqIEByZXR1cm5zIEEgbmV3IGNvbnRleHQgaW5zdGFuY2Ugd2l0aCBhY2N1bXVsYXRlZCB2YWx1ZXNcbiAgICovXG4gIGFjY3VtdWxhdGU8ViBleHRlbmRzIG9iamVjdD4odmFsdWU6IFYpIHtcbiAgICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgXCJjYWNoZVwiLCB7XG4gICAgICB2YWx1ZTogdGhpcy5jYWNoZS5hY2N1bXVsYXRlKHZhbHVlKSxcbiAgICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICAgIGVudW1lcmFibGU6IGZhbHNlLFxuICAgICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIH0pO1xuICAgIHJldHVybiB0aGlzIGFzIHVua25vd24gYXMgQ29udGV4dDxGICYgVj47XG4gIH1cblxuICBnZXQgdGltZXN0YW1wKCkge1xuICAgIHJldHVybiB0aGlzLmNhY2hlLnRpbWVzdGFtcDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgdmFsdWUgZnJvbSB0aGUgY29udGV4dCBieSBrZXkuXG4gICAqIEBzdW1tYXJ5IEF0dGVtcHRzIHRvIGdldCBhIHZhbHVlIGZyb20gdGhlIGN1cnJlbnQgY29udGV4dCdzIGNhY2hlLlxuICAgKiBJZiBub3QgZm91bmQsIHRyYXZlcnNlcyB1cCB0aGUgcGFyZW50IGNvbnRleHQgY2hhaW4uXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBLIC0gVHlwZSBleHRlbmRpbmcga2V5b2YgRiBmb3IgdGhlIGtleSB0byByZXRyaWV2ZVxuICAgKiBAdGVtcGxhdGUgRiAtIEFjY3VtdWxhdG9yIHR5cGVcbiAgICogQHBhcmFtIHtLfSBrZXkgLSBUaGUga2V5IHRvIHJldHJpZXZlIGZyb20gdGhlIGNvbnRleHRcbiAgICogQHJldHVybnMgVGhlIHZhbHVlIGFzc29jaWF0ZWQgd2l0aCB0aGUga2V5XG4gICAqIEB0aHJvd3Mge0Vycm9yfSBJZiB0aGUga2V5IGlzIG5vdCBmb3VuZCBpbiB0aGUgY29udGV4dCBjaGFpblxuICAgKi9cbiAgZ2V0PEsgZXh0ZW5kcyBrZXlvZiBGPihrZXk6IEspOiBGW0tdIHtcbiAgICB0cnkge1xuICAgICAgcmV0dXJuIHRoaXMuY2FjaGUuZ2V0KGtleSk7XG4gICAgfSBjYXRjaCAoZTogdW5rbm93bikge1xuICAgICAgaWYgKHRoaXMuY2FjaGUucGFyZW50Q29udGV4dCkgcmV0dXJuIHRoaXMuY2FjaGUucGFyZW50Q29udGV4dC5nZXQoa2V5KTtcbiAgICAgIHRocm93IGU7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgY2hpbGQgY29udGV4dFxuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgYSBuZXcgY29udGV4dCBpbnN0YW5jZSB3aXRoIGN1cnJlbnQgY29udGV4dCBhcyBwYXJlbnRcbiAgICpcbiAgICogQHRlbXBsYXRlIE0gLSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXN9IG9wZXJhdGlvbiAtIFRoZSBvcGVyYXRpb24gdHlwZVxuICAgKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBbbW9kZWxdIC0gT3B0aW9uYWwgbW9kZWwgY29uc3RydWN0b3JcbiAgICogQHJldHVybnMge0N9IE5ldyBjaGlsZCBjb250ZXh0IGluc3RhbmNlXG4gICAqL1xuICBjaGlsZDxNIGV4dGVuZHMgTW9kZWwsIEMgZXh0ZW5kcyBDb250ZXh0PEY+PihcbiAgICBvcGVyYXRpb246IE9wZXJhdGlvbktleXMsXG4gICAgbW9kZWw/OiBDb25zdHJ1Y3RvcjxNPlxuICApOiBDIHtcbiAgICByZXR1cm4gQ29udGV4dC5jaGlsZEZyb208RiwgQz4oXG4gICAgICB0aGlzIGFzIHVua25vd24gYXMgQyxcbiAgICAgIHtcbiAgICAgICAgb3BlcmF0aW9uOiBvcGVyYXRpb24sXG4gICAgICAgIGFmZmVjdGVkVGFibGVzOiBtb2RlbCA/IFttb2RlbF0gOiBbXSxcbiAgICAgIH0gYXMgdW5rbm93biBhcyBQYXJ0aWFsPEY+XG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGNoaWxkIGNvbnRleHQgZnJvbSBhbm90aGVyIGNvbnRleHRcbiAgICogQHN1bW1hcnkgR2VuZXJhdGVzIGEgbmV3IGNvbnRleHQgaW5zdGFuY2Ugd2l0aCBwYXJlbnQgcmVmZXJlbmNlXG4gICAqXG4gICAqIEB0ZW1wbGF0ZSBGIC0gVHlwZSBleHRlbmRpbmcgUmVwb3NpdG9yeSBGbGFnc1xuICAgKiBAdGVtcGxhdGUgQyAtIFR5cGUgZXh0ZW5kaW5nIENvbnRleHQ8Rj5cbiAgICogQHBhcmFtIHtDfSBjb250ZXh0IC0gVGhlIHBhcmVudCBjb250ZXh0XG4gICAqIEBwYXJhbSB7UGFydGlhbDxGPn0gW292ZXJyaWRlc10gLSBPcHRpb25hbCBmbGFnIG92ZXJyaWRlc1xuICAgKiBAcmV0dXJucyB7Q30gTmV3IGNoaWxkIGNvbnRleHQgaW5zdGFuY2VcbiAgICovXG4gIHN0YXRpYyBjaGlsZEZyb208RiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncywgQyBleHRlbmRzIENvbnRleHQ8Rj4+KFxuICAgIGNvbnRleHQ6IEMsXG4gICAgb3ZlcnJpZGVzPzogUGFydGlhbDxGPlxuICApOiBDIHtcbiAgICByZXR1cm4gQ29udGV4dC5mYWN0b3J5KFxuICAgICAgT2JqZWN0LmFzc2lnbih7fSwgY29udGV4dC5jYWNoZSwgb3ZlcnJpZGVzIHx8IHt9KVxuICAgICkgYXMgdW5rbm93biBhcyBDO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgbmV3IGNvbnRleHQgZnJvbSBvcGVyYXRpb24gcGFyYW1ldGVyc1xuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgYSBjb250ZXh0IGluc3RhbmNlIGZvciBzcGVjaWZpYyBvcGVyYXRpb25cbiAgICpcbiAgICogQHRlbXBsYXRlIEYgLSBUeXBlIGV4dGVuZGluZyBSZXBvc2l0b3J5IEZsYWdzXG4gICAqIEB0ZW1wbGF0ZSBNIC0gVHlwZSBleHRlbmRpbmcgTW9kZWxcbiAgICogQHBhcmFtIHtPcGVyYXRpb25LZXlzLkRFTEVURX0gb3BlcmF0aW9uIC0gVGhlIG9wZXJhdGlvbiB0eXBlXG4gICAqIEBwYXJhbSB7UGFydGlhbDxGPn0gb3ZlcnJpZGVzIC0gRmxhZyBvdmVycmlkZXNcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgLSBUaGUgbW9kZWwgY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHthbnl9IGFyZ3MgLSBPcGVyYXRpb24gYXJndW1lbnRzXG4gICAqIEByZXR1cm5zIHtQcm9taXNlPEM+fSBQcm9taXNlIHJlc29sdmluZyB0byBuZXcgY29udGV4dFxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGZyb208XG4gICAgTSBleHRlbmRzIE1vZGVsLFxuICAgIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gICAgQyBleHRlbmRzIENvbnRleHQ8Rj4sXG4gID4oXG4gICAgb3BlcmF0aW9uOlxuICAgICAgfCBPcGVyYXRpb25LZXlzLkNSRUFURVxuICAgICAgfCBPcGVyYXRpb25LZXlzLlJFQURcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5VUERBVEVcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgb3ZlcnJpZGVzOiBQYXJ0aWFsPEY+LFxuICAgIG1vZGVsOiBDb25zdHJ1Y3RvcjxNPixcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXG4gICAgLi4uYXJnczogYW55W11cbiAgKTogUHJvbWlzZTxDPiB7XG4gICAgcmV0dXJuIENvbnRleHQuZmFjdG9yeShcbiAgICAgIE9iamVjdC5hc3NpZ24oe30sIERlZmF1bHRSZXBvc2l0b3J5RmxhZ3MsIG92ZXJyaWRlcywge1xuICAgICAgICBvcGVyYXRpb246IG9wZXJhdGlvbixcbiAgICAgICAgbW9kZWw6IG1vZGVsLFxuICAgICAgfSlcbiAgICApIGFzIEM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGFyZ3VtZW50cyBmb3IgY29udGV4dCBvcGVyYXRpb25zXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBjb250ZXh0IGFyZ3Mgb2JqZWN0IHdpdGggdGhlIHNwZWNpZmllZCBvcGVyYXRpb24gcGFyYW1ldGVyc1xuICAgKlxuICAgKiBAdGVtcGxhdGUgRiAtIFR5cGUgZXh0ZW5kaW5nIHtAbGluayBSZXBvc2l0b3J5RmxhZ3N9XG4gICAqIEB0ZW1wbGF0ZSBNIC0gVHlwZSBleHRlbmRpbmcge0BsaW5rIE1vZGVsfVxuICAgKiBAcGFyYW0ge09wZXJhdGlvbktleXMuREVMRVRFfSBvcGVyYXRpb24gLSBUaGUgb3BlcmF0aW9uIHR5cGVcbiAgICogQHBhcmFtIHtDb25zdHJ1Y3RvcjxNPn0gbW9kZWwgLSBUaGUgbW9kZWwgY29uc3RydWN0b3JcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyAtIE9wZXJhdGlvbiBhcmd1bWVudHNcbiAgICogQHBhcmFtIHtDb250ZXh0dWFsPEY+fSBbY29udGV4dHVhbF0gLSBPcHRpb25hbCBjb250ZXh0dWFsIG9iamVjdFxuICAgKiBAcGFyYW0ge1BhcnRpYWw8Rj59IFtvdmVycmlkZXNdIC0gT3B0aW9uYWwgZmxhZyBvdmVycmlkZXNcbiAgICogQHJldHVybnMge1Byb21pc2U8Q29udGV4dEFyZ3M+fSBQcm9taXNlIHJlc29sdmluZyB0byBjb250ZXh0IGFyZ3VtZW50c1xuICAgKlxuICAgKiBAbWVybWFpZFxuICAgKiBzZXF1ZW5jZURpYWdyYW1cbiAgICogICBwYXJ0aWNpcGFudCBDIGFzIENvbnRleHRcbiAgICogICBwYXJ0aWNpcGFudCBNIGFzIE1vZGVsXG4gICAqICAgcGFydGljaXBhbnQgQSBhcyBBcmdzXG4gICAqXG4gICAqICAgQy0+PkM6IFJlY2VpdmUgb3BlcmF0aW9uIHJlcXVlc3RcbiAgICogICBDLT4+TTogVmFsaWRhdGUgbW9kZWwgY29uc3RydWN0b3JcbiAgICogICBDLT4+QzogQ3JlYXRlIGNoaWxkIGNvbnRleHRcbiAgICogICBDLT4+QTogUHJvY2VzcyBvcGVyYXRpb24gYXJnc1xuICAgKiAgIEEtPj5DOiBSZXR1cm4gY29udGV4dCBhcmdzXG4gICAqICAgQy0+PkM6IEFwcGx5IG92ZXJyaWRlc1xuICAgKiAgIEMtPj5DOiBSZXR1cm4gZmluYWwgY29udGV4dFxuICAgKi9cbiAgc3RhdGljIGFzeW5jIGFyZ3M8XG4gICAgTSBleHRlbmRzIE1vZGVsLFxuICAgIEMgZXh0ZW5kcyBDb250ZXh0PEY+LFxuICAgIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MsXG4gID4oXG4gICAgb3BlcmF0aW9uOlxuICAgICAgfCBPcGVyYXRpb25LZXlzLkNSRUFURVxuICAgICAgfCBPcGVyYXRpb25LZXlzLlJFQURcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5VUERBVEVcbiAgICAgIHwgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgbW9kZWw6IENvbnN0cnVjdG9yPE0+LFxuICAgIGFyZ3M6IGFueVtdLFxuICAgIGNvbnRleHR1YWw/OiBDb250ZXh0dWFsPEY+LFxuICAgIG92ZXJyaWRlcz86IFBhcnRpYWw8Rj5cbiAgKTogUHJvbWlzZTxDb250ZXh0QXJnczxGLCBDPj4ge1xuICAgIGNvbnN0IGxhc3QgPSBhcmdzLnBvcCgpO1xuXG4gICAgYXN5bmMgZnVuY3Rpb24gZ2V0Q29udGV4dCgpIHtcbiAgICAgIGlmIChjb250ZXh0dWFsKVxuICAgICAgICByZXR1cm4gY29udGV4dHVhbC5jb250ZXh0KG9wZXJhdGlvbiwgb3ZlcnJpZGVzIHx8IHt9LCBtb2RlbCwgLi4uYXJncyk7XG4gICAgICByZXR1cm4gQ29udGV4dC5mcm9tKG9wZXJhdGlvbiwgb3ZlcnJpZGVzIHx8IHt9LCBtb2RlbCwgLi4uYXJncyk7XG4gICAgfVxuXG4gICAgbGV0IGM6IEM7XG4gICAgaWYgKGxhc3QpIHtcbiAgICAgIGlmIChsYXN0IGluc3RhbmNlb2YgQ29udGV4dCkge1xuICAgICAgICBjID0gbGFzdCBhcyBDO1xuICAgICAgICBhcmdzLnB1c2gobGFzdCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjID0gKGF3YWl0IGdldENvbnRleHQoKSkgYXMgQztcbiAgICAgICAgYXJncy5wdXNoKGxhc3QsIGMpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjID0gKGF3YWl0IGdldENvbnRleHQoKSkgYXMgQztcbiAgICAgIGFyZ3MucHVzaChjKTtcbiAgICB9XG5cbiAgICByZXR1cm4geyBjb250ZXh0OiBjLCBhcmdzOiBhcmdzIH07XG4gIH1cbn1cbiIsImltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9Db250ZXh0XCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBtZXRob2QgdG8gY2hhbmdlIGEgbWV0aG9kIG9mIGFuIG9iamVjdCBwcmVmaXhpbmcgaXQgd2l0aCBhbm90aGVyXG4gKiBAcGFyYW0ge2FueX0gb2JqIFRoZSBCYXNlIE9iamVjdFxuICogQHBhcmFtIHtGdW5jdGlvbn0gYWZ0ZXIgVGhlIG9yaWdpbmFsIG1ldGhvZFxuICogQHBhcmFtIHtGdW5jdGlvbn0gcHJlZml4IFRoZSBQcmVmaXggbWV0aG9kLiBUaGUgb3V0cHV0IHdpbGwgYmUgdXNlZCBhcyBhcmd1bWVudHMgaW4gdGhlIG9yaWdpbmFsIG1ldGhvZFxuICogQHBhcmFtIHtzdHJpbmd9IFthZnRlck5hbWVdIFdoZW4gdGhlIGFmdGVyIGZ1bmN0aW9uIGFubWUgY2Fubm90IGJlIGV4dHJhY3RlZCwgcGFzcyBpdCBoZXJlXG4gKlxuICogQGZ1bmN0aW9uIHByZWZpeE1ldGhvZFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcHJlZml4TWV0aG9kKFxuICBvYmo6IGFueSxcbiAgYWZ0ZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBwcmVmaXg6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBhZnRlck5hbWU/OiBzdHJpbmdcbikge1xuICBhc3luYyBmdW5jdGlvbiB3cmFwcGVyKHRoaXM6IGFueSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCByZXN1bHRzID0gYXdhaXQgUHJvbWlzZS5yZXNvbHZlKHByZWZpeC5jYWxsKHRoaXMsIC4uLmFyZ3MpKTtcbiAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKGFmdGVyLmFwcGx5KHRoaXMsIHJlc3VsdHMpKTtcbiAgfVxuICBjb25zdCB3cmFwcGVkID0gd3JhcHBlci5iaW5kKG9iaik7XG4gIGNvbnN0IG5hbWUgPSBhZnRlck5hbWUgPyBhZnRlck5hbWUgOiBhZnRlci5uYW1lO1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkod3JhcHBlZCwgXCJuYW1lXCIsIHtcbiAgICBlbnVtZXJhYmxlOiB0cnVlLFxuICAgIGNvbmZpZ3VyYWJsZTogdHJ1ZSxcbiAgICB3cml0YWJsZTogZmFsc2UsXG4gICAgdmFsdWU6IG5hbWUsXG4gIH0pO1xuICBvYmpbbmFtZV0gPSB3cmFwcGVkO1xufVxuXG4vKipcbiAqIEBzdW1tYXJ5IFV0aWwgbWV0aG9kIHRvIGNoYW5nZSBhIG1ldGhvZCBvZiBhbiBvYmplY3Qgc3VmZml4aW5nIGl0IHdpdGggYW5vdGhlclxuICogQHBhcmFtIHthbnl9IG9iaiBUaGUgQmFzZSBPYmplY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGJlZm9yZSBUaGUgb3JpZ2luYWwgbWV0aG9kXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBzdWZmaXggVGhlIFByZWZpeCBtZXRob2QuIFRoZSBvdXRwdXQgd2lsbCBiZSB1c2VkIGFzIGFyZ3VtZW50cyBpbiB0aGUgb3JpZ2luYWwgbWV0aG9kXG4gKiBAcGFyYW0ge3N0cmluZ30gW2JlZm9yZU5hbWVdIFdoZW4gdGhlIGFmdGVyIGZ1bmN0aW9uIGFubWUgY2Fubm90IGJlIGV4dHJhY3RlZCwgcGFzcyBpdCBoZXJlXG4gKlxuICogQGZ1bmN0aW9uIHN1ZmZpeE1ldGhvZFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9ycy5SZXBvc2l0b3J5XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBzdWZmaXhNZXRob2QoXG4gIG9iajogYW55LFxuICBiZWZvcmU6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBzdWZmaXg6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBiZWZvcmVOYW1lPzogc3RyaW5nXG4pIHtcbiAgYXN5bmMgZnVuY3Rpb24gd3JhcHBlcih0aGlzOiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgcmVzdWx0cyA9IGF3YWl0IFByb21pc2UucmVzb2x2ZShiZWZvcmUuY2FsbCh0aGlzLCAuLi5hcmdzKSk7XG4gICAgcmV0dXJuIHN1ZmZpeC5jYWxsKHRoaXMsIC4uLnJlc3VsdHMpO1xuICB9XG4gIGNvbnN0IHdyYXBwZWQgPSB3cmFwcGVyLmJpbmQob2JqKTtcbiAgY29uc3QgbmFtZSA9IGJlZm9yZU5hbWUgPyBiZWZvcmVOYW1lIDogYmVmb3JlLm5hbWU7XG4gIE9iamVjdC5kZWZpbmVQcm9wZXJ0eSh3cmFwcGVkLCBcIm5hbWVcIiwge1xuICAgIGVudW1lcmFibGU6IHRydWUsXG4gICAgY29uZmlndXJhYmxlOiB0cnVlLFxuICAgIHdyaXRhYmxlOiBmYWxzZSxcbiAgICB2YWx1ZTogbmFtZSxcbiAgfSk7XG4gIG9ialtuYW1lXSA9IHdyYXBwZWQ7XG59XG5cbi8qKlxuICogQHN1bW1hcnkgVXRpbCBtZXRob2QgdG8gd3JhcCBhIG1ldGhvZCBvZiBhbiBvYmplY3Qgd2l0aCBhZGRpdGlvbmFsIGxvZ2ljXG4gKlxuICogQHBhcmFtIHthbnl9IG9iaiBUaGUgQmFzZSBPYmplY3RcbiAqIEBwYXJhbSB7RnVuY3Rpb259IGJlZm9yZSB0aGUgbWV0aG9kIHRvIGJlIHByZWZpeGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBtZXRob2QgdGhlIG1ldGhvZCB0byBiZSB3cmFwcGVkXG4gKiBAcGFyYW0ge0Z1bmN0aW9ufSBhZnRlciBUaGUgbWV0aG9kIHRvIGJlIHN1ZmZpeGVkXG4gKiBAcGFyYW0ge3N0cmluZ30gW21ldGhvZE5hbWVdIFdoZW4gdGhlIGFmdGVyIGZ1bmN0aW9uIGFubWUgY2Fubm90IGJlIGV4dHJhY3RlZCwgcGFzcyBpdCBoZXJlXG4gKlxuICogQGZ1bmN0aW9uIHdyYXBNZXRob2RXaXRoQ29udGV4dFxuICpcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gd3JhcE1ldGhvZFdpdGhDb250ZXh0KFxuICBvYmo6IGFueSxcbiAgYmVmb3JlOiAoLi4uYXJnczogYW55W10pID0+IGFueSxcbiAgbWV0aG9kOiAoLi4uYXJnczogYW55W10pID0+IGFueSxcbiAgYWZ0ZXI6ICguLi5hcmdzOiBhbnlbXSkgPT4gYW55LFxuICBtZXRob2ROYW1lPzogc3RyaW5nXG4pIHtcbiAgY29uc3QgbmFtZSA9IG1ldGhvZE5hbWUgPyBtZXRob2ROYW1lIDogbWV0aG9kLm5hbWU7XG4gIG9ialtuYW1lXSA9IG5ldyBQcm94eShvYmpbbmFtZV0sIHtcbiAgICBhcHBseTogYXN5bmMgKHRhcmdldCwgdGhpc0FyZywgYXJnQXJyYXkpID0+IHtcbiAgICAgIGxldCB0cmFuc2Zvcm1lZEFyZ3MgPSBiZWZvcmUuY2FsbCh0aGlzQXJnLCAuLi5hcmdBcnJheSk7XG4gICAgICBpZiAodHJhbnNmb3JtZWRBcmdzIGluc3RhbmNlb2YgUHJvbWlzZSlcbiAgICAgICAgdHJhbnNmb3JtZWRBcmdzID0gYXdhaXQgdHJhbnNmb3JtZWRBcmdzO1xuICAgICAgY29uc3QgY29udGV4dCA9IHRyYW5zZm9ybWVkQXJnc1t0cmFuc2Zvcm1lZEFyZ3MubGVuZ3RoIC0gMV0gYXMgYW55O1xuICAgICAgaWYgKCEoY29udGV4dCBpbnN0YW5jZW9mIENvbnRleHQpKVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIk1pc3NpbmcgYSBjb250ZXh0XCIpO1xuICAgICAgbGV0IHJlc3VsdHMgPSBhd2FpdCB0YXJnZXQuY2FsbCh0aGlzQXJnLCAuLi50cmFuc2Zvcm1lZEFyZ3MpO1xuICAgICAgaWYgKHJlc3VsdHMgaW5zdGFuY2VvZiBQcm9taXNlKSByZXN1bHRzID0gYXdhaXQgcmVzdWx0cztcbiAgICAgIHJlc3VsdHMgPSBhZnRlci5jYWxsKHRoaXNBcmcsIHJlc3VsdHMsIGNvbnRleHQpO1xuICAgICAgaWYgKHJlc3VsdHMgaW5zdGFuY2VvZiBQcm9taXNlKSByZXN1bHRzID0gYXdhaXQgcmVzdWx0cztcbiAgICAgIHJldHVybiByZXN1bHRzO1xuICAgIH0sXG4gIH0pO1xufVxuIiwiaW1wb3J0IHsgREJLZXlzIH0gZnJvbSBcIi4uL21vZGVsL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvdXRpbHNcIjtcbmltcG9ydCB7IE1vZGVsLCBNb2RlbEtleXMsIHNmIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgSW50ZXJuYWxFcnJvciB9IGZyb20gXCIuLi9yZXBvc2l0b3J5L2Vycm9yc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBGaW5kcyB0aGUgcHJpbWFyeSBrZXkgYXR0cmlidXRlIGZvciBhIG1vZGVsXG4gKiBAc3VtbWFyeSBTZWFyY2hlcyBpbiBhbGwgdGhlIHByb3BlcnRpZXMgaW4gdGhlIG9iamVjdCBmb3IgYW4ge0BsaW5rIGlkfSBkZWNvcmF0ZWQgcHJvcGVydHkgYW5kIHJldHVybnMgdGhlIHByb3BlcnR5IGtleSBhbmQgbWV0YWRhdGFcbiAqIEBwYXJhbSB7TW9kZWx9IG1vZGVsIC0gVGhlIG1vZGVsIG9iamVjdCB0byBzZWFyY2ggZm9yIHByaW1hcnkga2V5XG4gKiBAcmV0dXJuIHtPYmplY3R9IEFuIG9iamVjdCBjb250YWluaW5nIHRoZSBpZCBwcm9wZXJ0eSBuYW1lIGFuZCBpdHMgbWV0YWRhdGFcbiAqIEBmdW5jdGlvbiBmaW5kUHJpbWFyeUtleVxuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgZmluZFByaW1hcnlLZXlcbiAqICAgcGFydGljaXBhbnQgZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlXG4gKlxuICogICBDYWxsZXItPj5maW5kUHJpbWFyeUtleTogbW9kZWxcbiAqICAgZmluZFByaW1hcnlLZXktPj5nZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmU6IGdldCBkZWNvcmF0b3JzXG4gKiAgIGdldEFsbFByb3BlcnR5RGVjb3JhdG9yc1JlY3Vyc2l2ZS0tPj5maW5kUHJpbWFyeUtleTogZGVjb3JhdG9yc1xuICogICBmaW5kUHJpbWFyeUtleS0+PmZpbmRQcmltYXJ5S2V5OiBmaWx0ZXIgSUQgZGVjb3JhdG9yc1xuICogICBmaW5kUHJpbWFyeUtleS0+PmZpbmRQcmltYXJ5S2V5OiB2YWxpZGF0ZSBzaW5nbGUgSUQgcHJvcGVydHlcbiAqICAgZmluZFByaW1hcnlLZXktLT4+Q2FsbGVyOiB7aWQsIHByb3BzfVxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kUHJpbWFyeUtleTxNIGV4dGVuZHMgTW9kZWw+KG1vZGVsOiBNKSB7XG4gIGNvbnN0IGRlY29yYXRvcnMgPSBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUoXG4gICAgbW9kZWwsXG4gICAgdW5kZWZpbmVkLFxuICAgIERCS2V5cy5SRUZMRUNUICsgREJLZXlzLklEXG4gICk7XG4gIGNvbnN0IGlkRGVjb3JhdG9ycyA9IE9iamVjdC5lbnRyaWVzKGRlY29yYXRvcnMgYXMgb2JqZWN0KS5yZWR1Y2UoXG4gICAgKGFjY3VtOiB7IFtpbmRleGVyOiBzdHJpbmddOiBhbnlbXSB9LCBbcHJvcCwgZGVjc10pID0+IHtcbiAgICAgIGNvbnN0IGZpbHRlcmVkID0gKGRlY3MgYXMgeyBrZXk6IHN0cmluZyB9W10pLmZpbHRlcihcbiAgICAgICAgKGQpID0+IGQua2V5ICE9PSBNb2RlbEtleXMuVFlQRVxuICAgICAgKTtcbiAgICAgIGlmIChmaWx0ZXJlZCAmJiBmaWx0ZXJlZC5sZW5ndGgpIHtcbiAgICAgICAgYWNjdW1bcHJvcF0gPSBhY2N1bVtwcm9wXSB8fCBbXTtcbiAgICAgICAgYWNjdW1bcHJvcF0ucHVzaCguLi5maWx0ZXJlZCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW07XG4gICAgfSxcbiAgICB7fVxuICApO1xuXG4gIGlmICghaWREZWNvcmF0b3JzIHx8ICFPYmplY3Qua2V5cyhpZERlY29yYXRvcnMpLmxlbmd0aClcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcIkNvdWxkIG5vdCBmaW5kIElEIGRlY29yYXRlZCBQcm9wZXJ0eVwiKTtcbiAgaWYgKE9iamVjdC5rZXlzKGlkRGVjb3JhdG9ycykubGVuZ3RoID4gMSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihzZihPYmplY3Qua2V5cyhpZERlY29yYXRvcnMpLmpvaW4oXCIsIFwiKSkpO1xuICBjb25zdCBpZFByb3AgPSBPYmplY3Qua2V5cyhpZERlY29yYXRvcnMpWzBdO1xuICBpZiAoIWlkUHJvcCkgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXCJDb3VsZCBub3QgZmluZCBJRCBkZWNvcmF0ZWQgUHJvcGVydHlcIik7XG4gIHJldHVybiB7XG4gICAgaWQ6IGlkUHJvcCBhcyBrZXlvZiBNLFxuICAgIHByb3BzOiBpZERlY29yYXRvcnNbaWRQcm9wXVswXS5wcm9wcyxcbiAgfTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIHRoZSBwcmltYXJ5IGtleSB2YWx1ZSBmcm9tIGEgbW9kZWxcbiAqIEBzdW1tYXJ5IFNlYXJjaGVzIGZvciB0aGUgSUQtZGVjb3JhdGVkIHByb3BlcnR5IGluIHRoZSBtb2RlbCBhbmQgcmV0dXJucyBpdHMgdmFsdWVcbiAqIEBwYXJhbSB7TW9kZWx9IG1vZGVsIC0gVGhlIG1vZGVsIG9iamVjdCB0byBleHRyYWN0IHRoZSBJRCBmcm9tXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtyZXR1cm5FbXB0eT1mYWxzZV0gLSBXaGV0aGVyIHRvIHJldHVybiB1bmRlZmluZWQgaWYgbm8gSUQgdmFsdWUgaXMgZm91bmRcbiAqIEByZXR1cm4ge3N0cmluZyB8IG51bWJlciB8IGJpZ2ludH0gVGhlIHByaW1hcnkga2V5IHZhbHVlXG4gKiBAZnVuY3Rpb24gZmluZE1vZGVsSWRcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IGZpbmRNb2RlbElkXG4gKiAgIHBhcnRpY2lwYW50IGZpbmRQcmltYXJ5S2V5XG4gKlxuICogICBDYWxsZXItPj5maW5kTW9kZWxJZDogbW9kZWwsIHJldHVybkVtcHR5XG4gKiAgIGZpbmRNb2RlbElkLT4+ZmluZFByaW1hcnlLZXk6IG1vZGVsXG4gKiAgIGZpbmRQcmltYXJ5S2V5LS0+PmZpbmRNb2RlbElkOiB7aWQsIHByb3BzfVxuICogICBmaW5kTW9kZWxJZC0+PmZpbmRNb2RlbElkOiBleHRyYWN0IG1vZGVsW2lkXVxuICogICBmaW5kTW9kZWxJZC0+PmZpbmRNb2RlbElkOiB2YWxpZGF0ZSBJRCBleGlzdHMgaWYgcmVxdWlyZWRcbiAqICAgZmluZE1vZGVsSWQtLT4+Q2FsbGVyOiBJRCB2YWx1ZVxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBmaW5kTW9kZWxJZDxNIGV4dGVuZHMgTW9kZWw+KFxuICBtb2RlbDogTSxcbiAgcmV0dXJuRW1wdHkgPSBmYWxzZVxuKTogc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50IHtcbiAgY29uc3QgaWRQcm9wID0gZmluZFByaW1hcnlLZXkobW9kZWwpLmlkO1xuICBjb25zdCBtb2RlbElkID0gbW9kZWxbaWRQcm9wXTtcbiAgaWYgKHR5cGVvZiBtb2RlbElkID09PSBcInVuZGVmaW5lZFwiICYmICFyZXR1cm5FbXB0eSlcbiAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihcbiAgICAgIGBObyB2YWx1ZSBmb3IgdGhlIElkIGlzIGRlZmluZWQgdW5kZXIgdGhlIHByb3BlcnR5ICR7aWRQcm9wIGFzIHN0cmluZ31gXG4gICAgKTtcbiAgcmV0dXJuIG1vZGVsSWQgYXMgc3RyaW5nIHwgbnVtYmVyIHwgYmlnaW50O1xufVxuIiwiaW1wb3J0IHsgSVJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vaW50ZXJmYWNlcy9JUmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgQ29uc3RydWN0b3IsIE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgZW5mb3JjZURCRGVjb3JhdG9ycyB9IGZyb20gXCIuL3V0aWxzXCI7XG5pbXBvcnQgeyBPcGVyYXRpb25LZXlzIH0gZnJvbSBcIi4uL29wZXJhdGlvbnMvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBJbnRlcm5hbEVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyB3cmFwTWV0aG9kV2l0aENvbnRleHQgfSBmcm9tIFwiLi93cmFwcGVyc1wiO1xuaW1wb3J0IHsgZmluZFByaW1hcnlLZXkgfSBmcm9tIFwiLi4vaWRlbnRpdHkvdXRpbHNcIjtcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tIFwiLi9Db250ZXh0XCI7XG5pbXBvcnQgeyBSZXBvc2l0b3J5RmxhZ3MgfSBmcm9tIFwiLi90eXBlc1wiO1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBCYXNlIHJlcG9zaXRvcnkgaW1wbGVtZW50YXRpb24gcHJvdmlkaW5nIENSVUQgb3BlcmF0aW9ucyBmb3IgbW9kZWxzLlxuICogQHN1bW1hcnkgVGhlIEJhc2VSZXBvc2l0b3J5IGNsYXNzIHNlcnZlcyBhcyBhIGZvdW5kYXRpb24gZm9yIHJlcG9zaXRvcnkgaW1wbGVtZW50YXRpb25zLCBwcm92aWRpbmdcbiAqIGFic3RyYWN0IGFuZCBjb25jcmV0ZSBtZXRob2RzIGZvciBjcmVhdGluZywgcmVhZGluZywgdXBkYXRpbmcsIGFuZCBkZWxldGluZyBtb2RlbCBpbnN0YW5jZXMuXG4gKiBJdCBoYW5kbGVzIG9wZXJhdGlvbiBsaWZlY3ljbGVzIGluY2x1ZGluZyBwcmVmaXggYW5kIHN1ZmZpeCBvcGVyYXRpb25zLCBhbmQgZW5mb3JjZXMgZGVjb3JhdG9ycy5cbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGUsIGRlZmF1bHRzIHRvIFJlcG9zaXRvcnlGbGFnc1xuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlLCBkZWZhdWx0cyB0byBDb250ZXh0PEY+XG4gKiBAcGFyYW0ge0NvbnN0cnVjdG9yPE0+fSBjbGF6eiAtIFRoZSBjb25zdHJ1Y3RvciBmb3IgdGhlIG1vZGVsIGNsYXNzXG4gKiBAY2xhc3MgQmFzZVJlcG9zaXRvcnlcbiAqIEBleGFtcGxlXG4gKiBjbGFzcyBVc2VyTW9kZWwgZXh0ZW5kcyBNb2RlbCB7XG4gKiAgIEBpZCgpXG4gKiAgIGlkOiBzdHJpbmc7XG4gKlxuICogICBAcmVxdWlyZWQoKVxuICogICBuYW1lOiBzdHJpbmc7XG4gKiB9XG4gKlxuICogY2xhc3MgVXNlclJlcG9zaXRvcnkgZXh0ZW5kcyBCYXNlUmVwb3NpdG9yeTxVc2VyTW9kZWw+IHtcbiAqICAgY29uc3RydWN0b3IoKSB7XG4gKiAgICAgc3VwZXIoVXNlck1vZGVsKTtcbiAqICAgfVxuICpcbiAqICAgYXN5bmMgY3JlYXRlKG1vZGVsOiBVc2VyTW9kZWwpOiBQcm9taXNlPFVzZXJNb2RlbD4ge1xuICogICAgIC8vIEltcGxlbWVudGF0aW9uXG4gKiAgICAgcmV0dXJuIG1vZGVsO1xuICogICB9XG4gKlxuICogICBhc3luYyByZWFkKGtleTogc3RyaW5nKTogUHJvbWlzZTxVc2VyTW9kZWw+IHtcbiAqICAgICAvLyBJbXBsZW1lbnRhdGlvblxuICogICAgIHJldHVybiBuZXcgVXNlck1vZGVsKHsgaWQ6IGtleSwgbmFtZTogJ1VzZXInIH0pO1xuICogICB9XG4gKlxuICogICBhc3luYyB1cGRhdGUobW9kZWw6IFVzZXJNb2RlbCk6IFByb21pc2U8VXNlck1vZGVsPiB7XG4gKiAgICAgLy8gSW1wbGVtZW50YXRpb25cbiAqICAgICByZXR1cm4gbW9kZWw7XG4gKiAgIH1cbiAqXG4gKiAgIGFzeW5jIGRlbGV0ZShrZXk6IHN0cmluZyk6IFByb21pc2U8VXNlck1vZGVsPiB7XG4gKiAgICAgLy8gSW1wbGVtZW50YXRpb25cbiAqICAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMucmVhZChrZXkpO1xuICogICAgIHJldHVybiBtb2RlbDtcbiAqICAgfVxuICogfVxuICpcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgUiBhcyBSZXBvc2l0b3J5XG4gKiAgIHBhcnRpY2lwYW50IFAgYXMgUHJlZml4IE1ldGhvZHNcbiAqICAgcGFydGljaXBhbnQgRCBhcyBEYXRhYmFzZVxuICogICBwYXJ0aWNpcGFudCBTIGFzIFN1ZmZpeCBNZXRob2RzXG4gKiAgIHBhcnRpY2lwYW50IFYgYXMgVmFsaWRhdG9ycy9EZWNvcmF0b3JzXG4gKlxuICogICBOb3RlIG92ZXIgQyxWOiBDcmVhdGUgT3BlcmF0aW9uXG4gKiAgIEMtPj5SOiBjcmVhdGUobW9kZWwpXG4gKiAgIFItPj5QOiBjcmVhdGVQcmVmaXgobW9kZWwpXG4gKiAgIFAtPj5WOiBlbmZvcmNlREJEZWNvcmF0b3JzKE9OKVxuICogICBQLT4+RDogRGF0YWJhc2Ugb3BlcmF0aW9uXG4gKiAgIEQtPj5TOiBjcmVhdGVTdWZmaXgobW9kZWwpXG4gKiAgIFMtPj5WOiBlbmZvcmNlREJEZWNvcmF0b3JzKEFGVEVSKVxuICogICBTLT4+QzogUmV0dXJuIG1vZGVsXG4gKlxuICogICBOb3RlIG92ZXIgQyxWOiBSZWFkIE9wZXJhdGlvblxuICogICBDLT4+UjogcmVhZChrZXkpXG4gKiAgIFItPj5QOiByZWFkUHJlZml4KGtleSlcbiAqICAgUC0+PlY6IGVuZm9yY2VEQkRlY29yYXRvcnMoT04pXG4gKiAgIFAtPj5EOiBEYXRhYmFzZSBvcGVyYXRpb25cbiAqICAgRC0+PlM6IHJlYWRTdWZmaXgobW9kZWwpXG4gKiAgIFMtPj5WOiBlbmZvcmNlREJEZWNvcmF0b3JzKEFGVEVSKVxuICogICBTLT4+QzogUmV0dXJuIG1vZGVsXG4gKlxuICogICBOb3RlIG92ZXIgQyxWOiBVcGRhdGUgT3BlcmF0aW9uXG4gKiAgIEMtPj5SOiB1cGRhdGUobW9kZWwpXG4gKiAgIFItPj5QOiB1cGRhdGVQcmVmaXgobW9kZWwpXG4gKiAgIFAtPj5WOiBlbmZvcmNlREJEZWNvcmF0b3JzKE9OKVxuICogICBQLT4+RDogRGF0YWJhc2Ugb3BlcmF0aW9uXG4gKiAgIEQtPj5TOiB1cGRhdGVTdWZmaXgobW9kZWwpXG4gKiAgIFMtPj5WOiBlbmZvcmNlREJEZWNvcmF0b3JzKEFGVEVSKVxuICogICBTLT4+QzogUmV0dXJuIG1vZGVsXG4gKlxuICogICBOb3RlIG92ZXIgQyxWOiBEZWxldGUgT3BlcmF0aW9uXG4gKiAgIEMtPj5SOiBkZWxldGUoa2V5KVxuICogICBSLT4+UDogZGVsZXRlUHJlZml4KGtleSlcbiAqICAgUC0+PlY6IGVuZm9yY2VEQkRlY29yYXRvcnMoT04pXG4gKiAgIFAtPj5EOiBEYXRhYmFzZSBvcGVyYXRpb25cbiAqICAgRC0+PlM6IGRlbGV0ZVN1ZmZpeChtb2RlbClcbiAqICAgUy0+PlY6IGVuZm9yY2VEQkRlY29yYXRvcnMoQUZURVIpXG4gKiAgIFMtPj5DOiBSZXR1cm4gbW9kZWxcbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIEJhc2VSZXBvc2l0b3J5PFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4gaW1wbGVtZW50cyBJUmVwb3NpdG9yeTxNLCBGLCBDPlxue1xuICBwcml2YXRlIHJlYWRvbmx5IF9jbGFzcyE6IENvbnN0cnVjdG9yPE0+O1xuICBwcml2YXRlIF9wayE6IGtleW9mIE07XG4gIHByaXZhdGUgX3BrUHJvcHMhOiBhbnk7XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBHZXRzIHRoZSBtb2RlbCBjbGFzcyBjb25zdHJ1Y3Rvci5cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBjb25zdHJ1Y3RvciBmb3IgdGhlIG1vZGVsIGNsYXNzIGFzc29jaWF0ZWQgd2l0aCB0aGlzIHJlcG9zaXRvcnkuXG4gICAqIFRocm93cyBhbiBlcnJvciBpZiBubyBjbGFzcyBkZWZpbml0aW9uIGlzIGZvdW5kLlxuICAgKiBAcmV0dXJuIHtDb25zdHJ1Y3RvcjxNPn0gVGhlIGNvbnN0cnVjdG9yIGZvciB0aGUgbW9kZWwgY2xhc3NcbiAgICovXG4gIGdldCBjbGFzcygpIHtcbiAgICBpZiAoIXRoaXMuX2NsYXNzKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYE5vIGNsYXNzIGRlZmluaXRpb24gZm91bmQgZm9yIHRoaXMgcmVwb3NpdG9yeWApO1xuICAgIHJldHVybiB0aGlzLl9jbGFzcztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgcHJpbWFyeSBrZXkgcHJvcGVydHkgbmFtZSBvZiB0aGUgbW9kZWwuXG4gICAqIEBzdW1tYXJ5IFJldHJpZXZlcyB0aGUgbmFtZSBvZiB0aGUgcHJvcGVydHkgdGhhdCBzZXJ2ZXMgYXMgdGhlIHByaW1hcnkga2V5IGZvciB0aGUgbW9kZWwuXG4gICAqIElmIG5vdCBhbHJlYWR5IGRldGVybWluZWQsIGl0IGZpbmRzIHRoZSBwcmltYXJ5IGtleSB1c2luZyB0aGUgbW9kZWwncyBkZWNvcmF0b3JzLlxuICAgKiBAcmV0dXJuIFRoZSBuYW1lIG9mIHRoZSBwcmltYXJ5IGtleSBwcm9wZXJ0eVxuICAgKi9cbiAgZ2V0IHBrKCk6IGtleW9mIE0ge1xuICAgIGlmICghdGhpcy5fcGspIHtcbiAgICAgIGNvbnN0IHsgaWQsIHByb3BzIH0gPSBmaW5kUHJpbWFyeUtleShuZXcgdGhpcy5jbGFzcygpKTtcbiAgICAgIHRoaXMuX3BrID0gaWQ7XG4gICAgICB0aGlzLl9wa1Byb3BzID0gcHJvcHM7XG4gICAgfVxuICAgIHJldHVybiB0aGlzLl9waztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gR2V0cyB0aGUgcHJpbWFyeSBrZXkgcHJvcGVydGllcy5cbiAgICogQHN1bW1hcnkgUmV0cmlldmVzIHRoZSBwcm9wZXJ0aWVzIGFzc29jaWF0ZWQgd2l0aCB0aGUgcHJpbWFyeSBrZXkgb2YgdGhlIG1vZGVsLlxuICAgKiBJZiBub3QgYWxyZWFkeSBkZXRlcm1pbmVkLCBpdCB0cmlnZ2VycyB0aGUgcGsgZ2V0dGVyIHRvIGZpbmQgdGhlIHByaW1hcnkga2V5IHByb3BlcnRpZXMuXG4gICAqIEByZXR1cm4ge2FueX0gVGhlIHByb3BlcnRpZXMgb2YgdGhlIHByaW1hcnkga2V5XG4gICAqL1xuICBwcm90ZWN0ZWQgZ2V0IHBrUHJvcHMoKTogYW55IHtcbiAgICBpZiAoIXRoaXMuX3BrUHJvcHMpIHtcbiAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgIGNvbnN0IHBrID0gdGhpcy5waztcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuX3BrUHJvcHM7XG4gIH1cblxuICBwcm90ZWN0ZWQgY29uc3RydWN0b3IoY2xheno/OiBDb25zdHJ1Y3RvcjxNPikge1xuICAgIGlmIChjbGF6eikgdGhpcy5fY2xhc3MgPSBjbGF6ejtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXRoaXMtYWxpYXNcbiAgICBjb25zdCBzZWxmID0gdGhpcztcbiAgICBbdGhpcy5jcmVhdGUsIHRoaXMucmVhZCwgdGhpcy51cGRhdGUsIHRoaXMuZGVsZXRlXS5mb3JFYWNoKChtKSA9PiB7XG4gICAgICBjb25zdCBuYW1lID0gbS5uYW1lO1xuICAgICAgd3JhcE1ldGhvZFdpdGhDb250ZXh0KFxuICAgICAgICBzZWxmLFxuICAgICAgICAoc2VsZiBhcyBhbnkpW25hbWUgKyBcIlByZWZpeFwiXSxcbiAgICAgICAgbSxcbiAgICAgICAgKHNlbGYgYXMgYW55KVtuYW1lICsgXCJTdWZmaXhcIl1cbiAgICAgICk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBuZXcgbW9kZWwgaW5zdGFuY2UgaW4gdGhlIHJlcG9zaXRvcnkuXG4gICAqIEBzdW1tYXJ5IFBlcnNpc3RzIGEgbmV3IG1vZGVsIGluc3RhbmNlIHRvIHRoZSB1bmRlcmx5aW5nIGRhdGEgc3RvcmUuXG4gICAqIFRoaXMgbWV0aG9kIG11c3QgYmUgaW1wbGVtZW50ZWQgYnkgY29uY3JldGUgcmVwb3NpdG9yeSBjbGFzc2VzLlxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIGNyZWF0ZVxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIHRoZSBjcmVhdGUgb3BlcmF0aW9uXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBjcmVhdGVkIG1vZGVsIGluc3RhbmNlXG4gICAqL1xuICBhYnN0cmFjdCBjcmVhdGUobW9kZWw6IE0sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgbXVsdGlwbGUgbW9kZWwgaW5zdGFuY2VzIGluIHRoZSByZXBvc2l0b3J5LlxuICAgKiBAc3VtbWFyeSBQZXJzaXN0cyBtdWx0aXBsZSBtb2RlbCBpbnN0YW5jZXMgdG8gdGhlIHVuZGVybHlpbmcgZGF0YSBzdG9yZSBieSBjYWxsaW5nXG4gICAqIHRoZSBjcmVhdGUgbWV0aG9kIGZvciBlYWNoIG1vZGVsIGluIHRoZSBhcnJheS5cbiAgICogQHBhcmFtIHtNW119IG1vZGVscyAtIFRoZSBhcnJheSBvZiBtb2RlbCBpbnN0YW5jZXMgdG8gY3JlYXRlXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBmb3IgdGhlIGNyZWF0ZSBvcGVyYXRpb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxNW10+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiBjcmVhdGVkIG1vZGVsIGluc3RhbmNlc1xuICAgKi9cbiAgYXN5bmMgY3JlYXRlQWxsKG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKG1vZGVscy5tYXAoKG0pID0+IHRoaXMuY3JlYXRlKG0sIC4uLmFyZ3MpKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGEgbW9kZWwgZm9yIGNyZWF0aW9uIGFuZCBleGVjdXRlcyBwcmUtY3JlYXRpb24gb3BlcmF0aW9ucy5cbiAgICogQHN1bW1hcnkgUHJvY2Vzc2VzIGEgbW9kZWwgYmVmb3JlIGl0IGlzIGNyZWF0ZWQgaW4gdGhlIGRhdGEgc3RvcmUuIFRoaXMgaW5jbHVkZXNcbiAgICogY3JlYXRpbmcgYSBjb250ZXh0LCBpbnN0YW50aWF0aW5nIGEgbmV3IG1vZGVsIGluc3RhbmNlLCBhbmQgZW5mb3JjaW5nIGFueSBkZWNvcmF0b3JzXG4gICAqIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgYmVmb3JlIGNyZWF0aW9uLlxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIHByZXBhcmUgZm9yIGNyZWF0aW9uXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBmb3IgdGhlIGNyZWF0ZSBvcGVyYXRpb25cbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBjb250YWluaW5nIHRoZSBwcmVwYXJlZCBtb2RlbCBhbmQgY29udGV4dCBhcmd1bWVudHNcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyBjcmVhdGVQcmVmaXgobW9kZWw6IE0sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3M8TSwgQywgRj4oXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBtb2RlbCA9IG5ldyB0aGlzLmNsYXNzKG1vZGVsKTtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICk7XG4gICAgcmV0dXJuIFttb2RlbCwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByb2Nlc3NlcyBhIG1vZGVsIGFmdGVyIGNyZWF0aW9uIGFuZCBleGVjdXRlcyBwb3N0LWNyZWF0aW9uIG9wZXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IEZpbmFsaXplcyBhIG1vZGVsIGFmdGVyIGl0IGhhcyBiZWVuIGNyZWF0ZWQgaW4gdGhlIGRhdGEgc3RvcmUuIFRoaXMgaW5jbHVkZXNcbiAgICogZW5mb3JjaW5nIGFueSBkZWNvcmF0b3JzIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgYWZ0ZXIgY3JlYXRpb24uXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdGhhdCB3YXMgY3JlYXRlZFxuICAgKiBAcGFyYW0ge0N9IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPE0+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgcHJvY2Vzc2VkIG1vZGVsIGluc3RhbmNlXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDKSB7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICApO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgbXVsdGlwbGUgbW9kZWxzIGZvciBjcmVhdGlvbiBhbmQgZXhlY3V0ZXMgcHJlLWNyZWF0aW9uIG9wZXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBtdWx0aXBsZSBtb2RlbHMgYmVmb3JlIHRoZXkgYXJlIGNyZWF0ZWQgaW4gdGhlIGRhdGEgc3RvcmUuIFRoaXMgaW5jbHVkZXNcbiAgICogY3JlYXRpbmcgYSBjb250ZXh0LCBpbnN0YW50aWF0aW5nIG5ldyBtb2RlbCBpbnN0YW5jZXMsIGFuZCBlbmZvcmNpbmcgYW55IGRlY29yYXRvcnNcbiAgICogdGhhdCBzaG91bGQgYmUgYXBwbGllZCBiZWZvcmUgY3JlYXRpb24gZm9yIGVhY2ggbW9kZWwuXG4gICAqIEBwYXJhbSB7TVtdfSBtb2RlbHMgLSBUaGUgYXJyYXkgb2YgbW9kZWwgaW5zdGFuY2VzIHRvIHByZXBhcmUgZm9yIGNyZWF0aW9uXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBmb3IgdGhlIGNyZWF0ZSBvcGVyYXRpb25cbiAgICogQHJldHVybiAgQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgY29udGFpbmluZyB0aGUgcHJlcGFyZWQgbW9kZWxzIGFuZCBjb250ZXh0IGFyZ3VtZW50c1xuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGNyZWF0ZUFsbFByZWZpeChtb2RlbHM6IE1bXSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJnczxNLCBDLCBGPihcbiAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgdGhpcy5jbGFzcyxcbiAgICAgIGFyZ3NcbiAgICApO1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcChhc3luYyAobSkgPT4ge1xuICAgICAgICBtID0gbmV3IHRoaXMuY2xhc3MobSk7XG4gICAgICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5PTlxuICAgICAgICApO1xuICAgICAgICByZXR1cm4gbTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gW21vZGVscywgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByb2Nlc3NlcyBtdWx0aXBsZSBtb2RlbHMgYWZ0ZXIgY3JlYXRpb24gYW5kIGV4ZWN1dGVzIHBvc3QtY3JlYXRpb24gb3BlcmF0aW9ucy5cbiAgICogQHN1bW1hcnkgRmluYWxpemVzIG11bHRpcGxlIG1vZGVscyBhZnRlciB0aGV5IGhhdmUgYmVlbiBjcmVhdGVkIGluIHRoZSBkYXRhIHN0b3JlLiBUaGlzIGluY2x1ZGVzXG4gICAqIGVuZm9yY2luZyBhbnkgZGVjb3JhdG9ycyB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIGFmdGVyIGNyZWF0aW9uIGZvciBlYWNoIG1vZGVsLlxuICAgKiBAcGFyYW0ge01bXX0gbW9kZWxzIC0gVGhlIGFycmF5IG9mIG1vZGVsIGluc3RhbmNlcyB0aGF0IHdlcmUgY3JlYXRlZFxuICAgKiBAcGFyYW0ge0N9IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPE1bXT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBhcnJheSBvZiBwcm9jZXNzZWQgbW9kZWwgaW5zdGFuY2VzXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgY3JlYXRlQWxsU3VmZml4KG1vZGVsczogTVtdLCBjb250ZXh0OiBDKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKChtKSA9PlxuICAgICAgICBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICAgICAgKVxuICAgICAgKVxuICAgICk7XG4gICAgcmV0dXJuIG1vZGVscztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIGEgbW9kZWwgaW5zdGFuY2UgZnJvbSB0aGUgcmVwb3NpdG9yeSBieSBpdHMgcHJpbWFyeSBrZXkuXG4gICAqIEBzdW1tYXJ5IEZldGNoZXMgYSBtb2RlbCBpbnN0YW5jZSBmcm9tIHRoZSB1bmRlcmx5aW5nIGRhdGEgc3RvcmUgdXNpbmcgaXRzIHByaW1hcnkga2V5LlxuICAgKiBUaGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGNvbmNyZXRlIHJlcG9zaXRvcnkgY2xhc3Nlcy5cbiAgICogQHBhcmFtIHtzdHJpbmcgfCBudW1iZXJ9IGtleSAtIFRoZSBwcmltYXJ5IGtleSBvZiB0aGUgbW9kZWwgdG8gcmV0cmlldmVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIGZvciB0aGUgcmVhZCBvcGVyYXRpb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxNPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHJldHJpZXZlZCBtb2RlbCBpbnN0YW5jZVxuICAgKi9cbiAgYWJzdHJhY3QgcmVhZChrZXk6IHN0cmluZyB8IG51bWJlciwgLi4uYXJnczogYW55W10pOiBQcm9taXNlPE0+O1xuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0cmlldmVzIG11bHRpcGxlIG1vZGVsIGluc3RhbmNlcyBmcm9tIHRoZSByZXBvc2l0b3J5IGJ5IHRoZWlyIHByaW1hcnkga2V5cy5cbiAgICogQHN1bW1hcnkgRmV0Y2hlcyBtdWx0aXBsZSBtb2RlbCBpbnN0YW5jZXMgZnJvbSB0aGUgdW5kZXJseWluZyBkYXRhIHN0b3JlIHVzaW5nIHRoZWlyIHByaW1hcnkga2V5c1xuICAgKiBieSBjYWxsaW5nIHRoZSByZWFkIG1ldGhvZCBmb3IgZWFjaCBrZXkgaW4gdGhlIGFycmF5LlxuICAgKiBAcGFyYW0ge3N0cmluZ1tdIHwgbnVtYmVyW119IGtleXMgLSBUaGUgYXJyYXkgb2YgcHJpbWFyeSBrZXlzIG9mIHRoZSBtb2RlbHMgdG8gcmV0cmlldmVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIGZvciB0aGUgcmVhZCBvcGVyYXRpb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxNW10+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiByZXRyaWV2ZWQgbW9kZWwgaW5zdGFuY2VzXG4gICAqL1xuICBhc3luYyByZWFkQWxsKGtleXM6IHN0cmluZ1tdIHwgbnVtYmVyW10sIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNW10+IHtcbiAgICByZXR1cm4gYXdhaXQgUHJvbWlzZS5hbGwoa2V5cy5tYXAoKGlkKSA9PiB0aGlzLnJlYWQoaWQsIC4uLmFyZ3MpKSk7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByb2Nlc3NlcyBhIG1vZGVsIGFmdGVyIHJldHJpZXZhbCBhbmQgZXhlY3V0ZXMgcG9zdC1yZWFkIG9wZXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IEZpbmFsaXplcyBhIG1vZGVsIGFmdGVyIGl0IGhhcyBiZWVuIHJldHJpZXZlZCBmcm9tIHRoZSBkYXRhIHN0b3JlLiBUaGlzIGluY2x1ZGVzXG4gICAqIGVuZm9yY2luZyBhbnkgZGVjb3JhdG9ycyB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIGFmdGVyIHJlYWRpbmcuXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdGhhdCB3YXMgcmV0cmlldmVkXG4gICAqIEBwYXJhbSB7Q30gY29udGV4dCAtIFRoZSBjb250ZXh0IGZvciB0aGUgb3BlcmF0aW9uXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBwcm9jZXNzZWQgbW9kZWwgaW5zdGFuY2VcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyByZWFkU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDKSB7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICBPcGVyYXRpb25LZXlzLkFGVEVSXG4gICAgKTtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGZvciByZWFkaW5nIGEgbW9kZWwgYW5kIGV4ZWN1dGVzIHByZS1yZWFkIG9wZXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBhIGtleSBiZWZvcmUgYSBtb2RlbCBpcyByZWFkIGZyb20gdGhlIGRhdGEgc3RvcmUuIFRoaXMgaW5jbHVkZXNcbiAgICogY3JlYXRpbmcgYSBjb250ZXh0LCBpbnN0YW50aWF0aW5nIGEgbmV3IG1vZGVsIGluc3RhbmNlIHdpdGggdGhlIGtleSwgYW5kIGVuZm9yY2luZyBhbnkgZGVjb3JhdG9yc1xuICAgKiB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIGJlZm9yZSByZWFkaW5nLlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIHByaW1hcnkga2V5IG9mIHRoZSBtb2RlbCB0byByZWFkXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBmb3IgdGhlIHJlYWQgb3BlcmF0aW9uXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgY29udGFpbmluZyB0aGUga2V5IGFuZCBjb250ZXh0IGFyZ3VtZW50c1xuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIHJlYWRQcmVmaXgoa2V5OiBzdHJpbmcsIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3M8TSwgQywgRj4oXG4gICAgICBPcGVyYXRpb25LZXlzLlJFQUQsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgY29uc3QgbW9kZWw6IE0gPSBuZXcgdGhpcy5jbGFzcygpO1xuICAgIG1vZGVsW3RoaXMucGtdID0ga2V5IGFzIGFueTtcbiAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgdGhpcyxcbiAgICAgIGNvbnRleHRBcmdzLmNvbnRleHQsXG4gICAgICBtb2RlbCxcbiAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICApO1xuICAgIHJldHVybiBba2V5LCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgZm9yIHJlYWRpbmcgbXVsdGlwbGUgbW9kZWxzIGFuZCBleGVjdXRlcyBwcmUtcmVhZCBvcGVyYXRpb25zLlxuICAgKiBAc3VtbWFyeSBQcm9jZXNzZXMgbXVsdGlwbGUga2V5cyBiZWZvcmUgbW9kZWxzIGFyZSByZWFkIGZyb20gdGhlIGRhdGEgc3RvcmUuIFRoaXMgaW5jbHVkZXNcbiAgICogY3JlYXRpbmcgYSBjb250ZXh0LCBpbnN0YW50aWF0aW5nIG5ldyBtb2RlbCBpbnN0YW5jZXMgd2l0aCB0aGUga2V5cywgYW5kIGVuZm9yY2luZyBhbnkgZGVjb3JhdG9yc1xuICAgKiB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIGJlZm9yZSByZWFkaW5nIGZvciBlYWNoIGtleS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IG51bWJlcltdfSBrZXlzIC0gVGhlIGFycmF5IG9mIHByaW1hcnkga2V5cyBvZiB0aGUgbW9kZWxzIHRvIHJlYWRcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIGZvciB0aGUgcmVhZCBvcGVyYXRpb25cbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBjb250YWluaW5nIHRoZSBrZXlzIGFuZCBjb250ZXh0IGFyZ3VtZW50c1xuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIHJlYWRBbGxQcmVmaXgoa2V5czogc3RyaW5nW10gfCBudW1iZXJbXSwgLi4uYXJnczogYW55W10pIHtcbiAgICBjb25zdCBjb250ZXh0QXJncyA9IGF3YWl0IENvbnRleHQuYXJnczxNLCBDLCBGPihcbiAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIGtleXMubWFwKGFzeW5jIChrKSA9PiB7XG4gICAgICAgIGNvbnN0IG0gPSBuZXcgdGhpcy5jbGFzcygpO1xuICAgICAgICBtW3RoaXMucGtdID0gayBhcyBhbnk7XG4gICAgICAgIHJldHVybiBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuUkVBRCxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgICAgICk7XG4gICAgICB9KVxuICAgICk7XG4gICAgcmV0dXJuIFtrZXlzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJvY2Vzc2VzIG11bHRpcGxlIG1vZGVscyBhZnRlciByZXRyaWV2YWwgYW5kIGV4ZWN1dGVzIHBvc3QtcmVhZCBvcGVyYXRpb25zLlxuICAgKiBAc3VtbWFyeSBGaW5hbGl6ZXMgbXVsdGlwbGUgbW9kZWxzIGFmdGVyIHRoZXkgaGF2ZSBiZWVuIHJldHJpZXZlZCBmcm9tIHRoZSBkYXRhIHN0b3JlLiBUaGlzIGluY2x1ZGVzXG4gICAqIGVuZm9yY2luZyBhbnkgZGVjb3JhdG9ycyB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIGFmdGVyIHJlYWRpbmcgZm9yIGVhY2ggbW9kZWwuXG4gICAqIEBwYXJhbSB7TVtdfSBtb2RlbHMgLSBUaGUgYXJyYXkgb2YgbW9kZWwgaW5zdGFuY2VzIHRoYXQgd2VyZSByZXRyaWV2ZWRcbiAgICogQHBhcmFtIHtDfSBjb250ZXh0IC0gVGhlIGNvbnRleHQgZm9yIHRoZSBvcGVyYXRpb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxNW10+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgYXJyYXkgb2YgcHJvY2Vzc2VkIG1vZGVsIGluc3RhbmNlc1xuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIHJlYWRBbGxTdWZmaXgobW9kZWxzOiBNW10sIGNvbnRleHQ6IEMpIHtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoKG0pID0+XG4gICAgICAgIGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5SRUFELFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICAgICAgKVxuICAgICAgKVxuICAgICk7XG4gICAgcmV0dXJuIG1vZGVscztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gVXBkYXRlcyBhbiBleGlzdGluZyBtb2RlbCBpbnN0YW5jZSBpbiB0aGUgcmVwb3NpdG9yeS5cbiAgICogQHN1bW1hcnkgVXBkYXRlcyBhbiBleGlzdGluZyBtb2RlbCBpbnN0YW5jZSBpbiB0aGUgdW5kZXJseWluZyBkYXRhIHN0b3JlLlxuICAgKiBUaGlzIG1ldGhvZCBtdXN0IGJlIGltcGxlbWVudGVkIGJ5IGNvbmNyZXRlIHJlcG9zaXRvcnkgY2xhc3Nlcy5cbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSB0byB1cGRhdGVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIGZvciB0aGUgdXBkYXRlIG9wZXJhdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPE0+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgdXBkYXRlZCBtb2RlbCBpbnN0YW5jZVxuICAgKi9cbiAgYWJzdHJhY3QgdXBkYXRlKG1vZGVsOiBNLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TT47XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBVcGRhdGVzIG11bHRpcGxlIG1vZGVsIGluc3RhbmNlcyBpbiB0aGUgcmVwb3NpdG9yeS5cbiAgICogQHN1bW1hcnkgVXBkYXRlcyBtdWx0aXBsZSBtb2RlbCBpbnN0YW5jZXMgaW4gdGhlIHVuZGVybHlpbmcgZGF0YSBzdG9yZSBieSBjYWxsaW5nXG4gICAqIHRoZSB1cGRhdGUgbWV0aG9kIGZvciBlYWNoIG1vZGVsIGluIHRoZSBhcnJheS5cbiAgICogQHBhcmFtIHtNW119IG1vZGVscyAtIFRoZSBhcnJheSBvZiBtb2RlbCBpbnN0YW5jZXMgdG8gdXBkYXRlXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBmb3IgdGhlIHVwZGF0ZSBvcGVyYXRpb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxNW10+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBvZiB1cGRhdGVkIG1vZGVsIGluc3RhbmNlc1xuICAgKi9cbiAgYXN5bmMgdXBkYXRlQWxsKG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnkpOiBQcm9taXNlPE1bXT4ge1xuICAgIHJldHVybiBQcm9taXNlLmFsbChtb2RlbHMubWFwKChtKSA9PiB0aGlzLnVwZGF0ZShtLCAuLi5hcmdzKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcm9jZXNzZXMgYSBtb2RlbCBhZnRlciB1cGRhdGUgYW5kIGV4ZWN1dGVzIHBvc3QtdXBkYXRlIG9wZXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IEZpbmFsaXplcyBhIG1vZGVsIGFmdGVyIGl0IGhhcyBiZWVuIHVwZGF0ZWQgaW4gdGhlIGRhdGEgc3RvcmUuIFRoaXMgaW5jbHVkZXNcbiAgICogZW5mb3JjaW5nIGFueSBkZWNvcmF0b3JzIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgYWZ0ZXIgdXBkYXRpbmcuXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdGhhdCB3YXMgdXBkYXRlZFxuICAgKiBAcGFyYW0ge0N9IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPE0+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgcHJvY2Vzc2VkIG1vZGVsIGluc3RhbmNlXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgdXBkYXRlU3VmZml4KG1vZGVsOiBNLCBjb250ZXh0OiBDKSB7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICApO1xuICAgIHJldHVybiBtb2RlbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgYSBtb2RlbCBmb3IgdXBkYXRlIGFuZCBleGVjdXRlcyBwcmUtdXBkYXRlIG9wZXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBhIG1vZGVsIGJlZm9yZSBpdCBpcyB1cGRhdGVkIGluIHRoZSBkYXRhIHN0b3JlLiBUaGlzIGluY2x1ZGVzXG4gICAqIGNyZWF0aW5nIGEgY29udGV4dCwgdmFsaWRhdGluZyB0aGUgcHJpbWFyeSBrZXksIHJldHJpZXZpbmcgdGhlIGV4aXN0aW5nIG1vZGVsLFxuICAgKiBhbmQgZW5mb3JjaW5nIGFueSBkZWNvcmF0b3JzIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgYmVmb3JlIHVwZGF0aW5nLlxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIHByZXBhcmUgZm9yIHVwZGF0ZVxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIHRoZSB1cGRhdGUgb3BlcmF0aW9uXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgY29udGFpbmluZyB0aGUgcHJlcGFyZWQgbW9kZWwgYW5kIGNvbnRleHQgYXJndW1lbnRzXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgdXBkYXRlUHJlZml4KG1vZGVsOiBNLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzPE0sIEMsIEY+KFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgY29uc3QgaWQgPSBtb2RlbFt0aGlzLnBrXTtcbiAgICBpZiAoIWlkKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBObyB2YWx1ZSBmb3IgdGhlIElkIGlzIGRlZmluZWQgdW5kZXIgdGhlIHByb3BlcnR5ICR7dGhpcy5wayBhcyBzdHJpbmd9YFxuICAgICAgKTtcbiAgICBjb25zdCBvbGRNb2RlbCA9IGF3YWl0IHRoaXMucmVhZChpZCBhcyBzdHJpbmcpO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OLFxuICAgICAgb2xkTW9kZWxcbiAgICApO1xuICAgIHJldHVybiBbbW9kZWwsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcmVwYXJlcyBtdWx0aXBsZSBtb2RlbHMgZm9yIHVwZGF0ZSBhbmQgZXhlY3V0ZXMgcHJlLXVwZGF0ZSBvcGVyYXRpb25zLlxuICAgKiBAc3VtbWFyeSBQcm9jZXNzZXMgbXVsdGlwbGUgbW9kZWxzIGJlZm9yZSB0aGV5IGFyZSB1cGRhdGVkIGluIHRoZSBkYXRhIHN0b3JlLiBUaGlzIGluY2x1ZGVzXG4gICAqIGNyZWF0aW5nIGEgY29udGV4dCwgaW5zdGFudGlhdGluZyBuZXcgbW9kZWwgaW5zdGFuY2VzLCBhbmQgZW5mb3JjaW5nIGFueSBkZWNvcmF0b3JzXG4gICAqIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgYmVmb3JlIHVwZGF0aW5nIGZvciBlYWNoIG1vZGVsLlxuICAgKiBAcGFyYW0ge01bXX0gbW9kZWxzIC0gVGhlIGFycmF5IG9mIG1vZGVsIGluc3RhbmNlcyB0byBwcmVwYXJlIGZvciB1cGRhdGVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIGZvciB0aGUgdXBkYXRlIG9wZXJhdGlvblxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIHByZXBhcmVkIG1vZGVscyBhbmQgY29udGV4dCBhcmd1bWVudHNcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyB1cGRhdGVBbGxQcmVmaXgobW9kZWxzOiBNW10sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3M8TSwgQywgRj4oXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoKG0pID0+IHtcbiAgICAgICAgbSA9IG5ldyB0aGlzLmNsYXNzKG0pO1xuICAgICAgICBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIG07XG4gICAgICB9KVxuICAgICk7XG4gICAgcmV0dXJuIFttb2RlbHMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcm9jZXNzZXMgbXVsdGlwbGUgbW9kZWxzIGFmdGVyIHVwZGF0ZSBhbmQgZXhlY3V0ZXMgcG9zdC11cGRhdGUgb3BlcmF0aW9ucy5cbiAgICogQHN1bW1hcnkgRmluYWxpemVzIG11bHRpcGxlIG1vZGVscyBhZnRlciB0aGV5IGhhdmUgYmVlbiB1cGRhdGVkIGluIHRoZSBkYXRhIHN0b3JlLiBUaGlzIGluY2x1ZGVzXG4gICAqIGVuZm9yY2luZyBhbnkgZGVjb3JhdG9ycyB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIGFmdGVyIHVwZGF0aW5nIGZvciBlYWNoIG1vZGVsLlxuICAgKiBAcGFyYW0ge01bXX0gbW9kZWxzIC0gVGhlIGFycmF5IG9mIG1vZGVsIGluc3RhbmNlcyB0aGF0IHdlcmUgdXBkYXRlZFxuICAgKiBAcGFyYW0ge0N9IGNvbnRleHQgLSBUaGUgY29udGV4dCBmb3IgdGhlIG9wZXJhdGlvblxuICAgKiBAcmV0dXJuIHtQcm9taXNlPE1bXT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBhcnJheSBvZiBwcm9jZXNzZWQgbW9kZWwgaW5zdGFuY2VzXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgdXBkYXRlQWxsU3VmZml4KG1vZGVsczogTVtdLCBjb250ZXh0OiBDKSB7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKChtKSA9PlxuICAgICAgICBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuVVBEQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQUZURVJcbiAgICAgICAgKVxuICAgICAgKVxuICAgICk7XG4gICAgcmV0dXJuIG1vZGVscztcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gRGVsZXRlcyBhIG1vZGVsIGluc3RhbmNlIGZyb20gdGhlIHJlcG9zaXRvcnkgYnkgaXRzIHByaW1hcnkga2V5LlxuICAgKiBAc3VtbWFyeSBSZW1vdmVzIGEgbW9kZWwgaW5zdGFuY2UgZnJvbSB0aGUgdW5kZXJseWluZyBkYXRhIHN0b3JlIHVzaW5nIGl0cyBwcmltYXJ5IGtleS5cbiAgICogVGhpcyBtZXRob2QgbXVzdCBiZSBpbXBsZW1lbnRlZCBieSBjb25jcmV0ZSByZXBvc2l0b3J5IGNsYXNzZXMuXG4gICAqIEBwYXJhbSB7c3RyaW5nIHwgbnVtYmVyfSBrZXkgLSBUaGUgcHJpbWFyeSBrZXkgb2YgdGhlIG1vZGVsIHRvIGRlbGV0ZVxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIHRoZSBkZWxldGUgb3BlcmF0aW9uXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TT59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBkZWxldGVkIG1vZGVsIGluc3RhbmNlXG4gICAqL1xuICBhYnN0cmFjdCBkZWxldGUoa2V5OiBzdHJpbmcgfCBudW1iZXIsIC4uLmFyZ3M6IGFueVtdKTogUHJvbWlzZTxNPjtcblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIERlbGV0ZXMgbXVsdGlwbGUgbW9kZWwgaW5zdGFuY2VzIGZyb20gdGhlIHJlcG9zaXRvcnkgYnkgdGhlaXIgcHJpbWFyeSBrZXlzLlxuICAgKiBAc3VtbWFyeSBSZW1vdmVzIG11bHRpcGxlIG1vZGVsIGluc3RhbmNlcyBmcm9tIHRoZSB1bmRlcmx5aW5nIGRhdGEgc3RvcmUgdXNpbmcgdGhlaXIgcHJpbWFyeSBrZXlzXG4gICAqIGJ5IGNhbGxpbmcgdGhlIGRlbGV0ZSBtZXRob2QgZm9yIGVhY2gga2V5IGluIHRoZSBhcnJheS5cbiAgICogQHBhcmFtIHtzdHJpbmdbXSB8IG51bWJlcltdfSBrZXlzIC0gVGhlIGFycmF5IG9mIHByaW1hcnkga2V5cyBvZiB0aGUgbW9kZWxzIHRvIGRlbGV0ZVxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIHRoZSBkZWxldGUgb3BlcmF0aW9uXG4gICAqIEByZXR1cm4ge1Byb21pc2U8TVtdPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgb2YgZGVsZXRlZCBtb2RlbCBpbnN0YW5jZXNcbiAgICovXG4gIGFzeW5jIGRlbGV0ZUFsbChrZXlzOiBzdHJpbmdbXSB8IG51bWJlcltdLCAuLi5hcmdzOiBhbnlbXSk6IFByb21pc2U8TVtdPiB7XG4gICAgcmV0dXJuIFByb21pc2UuYWxsKGtleXMubWFwKChrKSA9PiB0aGlzLmRlbGV0ZShrLCAuLi5hcmdzKSkpO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcm9jZXNzZXMgYSBtb2RlbCBhZnRlciBkZWxldGlvbiBhbmQgZXhlY3V0ZXMgcG9zdC1kZWxldGUgb3BlcmF0aW9ucy5cbiAgICogQHN1bW1hcnkgRmluYWxpemVzIGEgbW9kZWwgYWZ0ZXIgaXQgaGFzIGJlZW4gZGVsZXRlZCBmcm9tIHRoZSBkYXRhIHN0b3JlLiBUaGlzIGluY2x1ZGVzXG4gICAqIGVuZm9yY2luZyBhbnkgZGVjb3JhdG9ycyB0aGF0IHNob3VsZCBiZSBhcHBsaWVkIGFmdGVyIGRlbGV0aW9uLlxuICAgKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRoYXQgd2FzIGRlbGV0ZWRcbiAgICogQHBhcmFtIHtDfSBjb250ZXh0IC0gVGhlIGNvbnRleHQgZm9yIHRoZSBvcGVyYXRpb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxNPn0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIHByb2Nlc3NlZCBtb2RlbCBpbnN0YW5jZVxuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGRlbGV0ZVN1ZmZpeChtb2RlbDogTSwgY29udGV4dDogQykge1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLkFGVEVSXG4gICAgKTtcbiAgICByZXR1cm4gbW9kZWw7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGZvciBkZWxldGluZyBhIG1vZGVsIGFuZCBleGVjdXRlcyBwcmUtZGVsZXRlIG9wZXJhdGlvbnMuXG4gICAqIEBzdW1tYXJ5IFByb2Nlc3NlcyBhIGtleSBiZWZvcmUgYSBtb2RlbCBpcyBkZWxldGVkIGZyb20gdGhlIGRhdGEgc3RvcmUuIFRoaXMgaW5jbHVkZXNcbiAgICogY3JlYXRpbmcgYSBjb250ZXh0LCByZXRyaWV2aW5nIHRoZSBtb2RlbCB0byBiZSBkZWxldGVkLCBhbmQgZW5mb3JjaW5nIGFueSBkZWNvcmF0b3JzXG4gICAqIHRoYXQgc2hvdWxkIGJlIGFwcGxpZWQgYmVmb3JlIGRlbGV0aW9uLlxuICAgKiBAcGFyYW0ge2FueX0ga2V5IC0gVGhlIHByaW1hcnkga2V5IG9mIHRoZSBtb2RlbCB0byBkZWxldGVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIGZvciB0aGUgZGVsZXRlIG9wZXJhdGlvblxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIGtleSBhbmQgY29udGV4dCBhcmd1bWVudHNcbiAgICovXG4gIHByb3RlY3RlZCBhc3luYyBkZWxldGVQcmVmaXgoa2V5OiBhbnksIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3M8TSwgQywgRj4oXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBjb25zdCBtb2RlbCA9IGF3YWl0IHRoaXMucmVhZChrZXksIC4uLmNvbnRleHRBcmdzLmFyZ3MpO1xuICAgIGF3YWl0IGVuZm9yY2VEQkRlY29yYXRvcnM8TSwgdHlwZW9mIHRoaXMsIGFueSwgRiwgQz4oXG4gICAgICB0aGlzLFxuICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgIG1vZGVsLFxuICAgICAgT3BlcmF0aW9uS2V5cy5ERUxFVEUsXG4gICAgICBPcGVyYXRpb25LZXlzLk9OXG4gICAgKTtcbiAgICByZXR1cm4gW2tleSwgLi4uY29udGV4dEFyZ3MuYXJnc107XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGZvciBkZWxldGluZyBtdWx0aXBsZSBtb2RlbHMgYW5kIGV4ZWN1dGVzIHByZS1kZWxldGUgb3BlcmF0aW9ucy5cbiAgICogQHN1bW1hcnkgUHJvY2Vzc2VzIG11bHRpcGxlIGtleXMgYmVmb3JlIG1vZGVscyBhcmUgZGVsZXRlZCBmcm9tIHRoZSBkYXRhIHN0b3JlLiBUaGlzIGluY2x1ZGVzXG4gICAqIGNyZWF0aW5nIGEgY29udGV4dCwgcmV0cmlldmluZyB0aGUgbW9kZWxzIHRvIGJlIGRlbGV0ZWQsIGFuZCBlbmZvcmNpbmcgYW55IGRlY29yYXRvcnNcbiAgICogdGhhdCBzaG91bGQgYmUgYXBwbGllZCBiZWZvcmUgZGVsZXRpb24gZm9yIGVhY2ggbW9kZWwuXG4gICAqIEBwYXJhbSB7c3RyaW5nW10gfCBudW1iZXJbXX0ga2V5cyAtIFRoZSBhcnJheSBvZiBwcmltYXJ5IGtleXMgb2YgdGhlIG1vZGVscyB0byBkZWxldGVcbiAgICogQHBhcmFtIHthbnlbXX0gYXJncyAtIEFkZGl0aW9uYWwgYXJndW1lbnRzIGZvciB0aGUgZGVsZXRlIG9wZXJhdGlvblxuICAgKiBAcmV0dXJuIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIGFycmF5IGNvbnRhaW5pbmcgdGhlIGtleXMgYW5kIGNvbnRleHQgYXJndW1lbnRzXG4gICAqL1xuICBwcm90ZWN0ZWQgYXN5bmMgZGVsZXRlQWxsUHJlZml4KGtleXM6IHN0cmluZ1tdIHwgbnVtYmVyW10sIC4uLmFyZ3M6IGFueVtdKSB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3M8TSwgQywgRj4oXG4gICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBjb25zdCBtb2RlbHMgPSBhd2FpdCB0aGlzLnJlYWRBbGwoa2V5cywgLi4uY29udGV4dEFyZ3MuYXJncyk7XG4gICAgYXdhaXQgUHJvbWlzZS5hbGwoXG4gICAgICBtb2RlbHMubWFwKGFzeW5jIChtKSA9PiB7XG4gICAgICAgIHJldHVybiBlbmZvcmNlREJEZWNvcmF0b3JzPE0sIHR5cGVvZiB0aGlzLCBhbnksIEYsIEM+KFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuREVMRVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgIH0pXG4gICAgKTtcbiAgICByZXR1cm4gW2tleXMsIC4uLmNvbnRleHRBcmdzLmFyZ3NdO1xuICB9XG5cbiAgLyoqXG4gICAqIEBkZXNjcmlwdGlvbiBQcm9jZXNzZXMgbXVsdGlwbGUgbW9kZWxzIGFmdGVyIGRlbGV0aW9uIGFuZCBleGVjdXRlcyBwb3N0LWRlbGV0ZSBvcGVyYXRpb25zLlxuICAgKiBAc3VtbWFyeSBGaW5hbGl6ZXMgbXVsdGlwbGUgbW9kZWxzIGFmdGVyIHRoZXkgaGF2ZSBiZWVuIGRlbGV0ZWQgZnJvbSB0aGUgZGF0YSBzdG9yZS4gVGhpcyBpbmNsdWRlc1xuICAgKiBlbmZvcmNpbmcgYW55IGRlY29yYXRvcnMgdGhhdCBzaG91bGQgYmUgYXBwbGllZCBhZnRlciBkZWxldGlvbiBmb3IgZWFjaCBtb2RlbC5cbiAgICogQHBhcmFtIHtNW119IG1vZGVscyAtIFRoZSBhcnJheSBvZiBtb2RlbCBpbnN0YW5jZXMgdGhhdCB3ZXJlIGRlbGV0ZWRcbiAgICogQHBhcmFtIHtDfSBjb250ZXh0IC0gVGhlIGNvbnRleHQgZm9yIHRoZSBvcGVyYXRpb25cbiAgICogQHJldHVybiB7UHJvbWlzZTxNW10+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgYXJyYXkgb2YgcHJvY2Vzc2VkIG1vZGVsIGluc3RhbmNlc1xuICAgKi9cbiAgcHJvdGVjdGVkIGFzeW5jIGRlbGV0ZUFsbFN1ZmZpeChtb2RlbHM6IE1bXSwgY29udGV4dDogQykge1xuICAgIGF3YWl0IFByb21pc2UuYWxsKFxuICAgICAgbW9kZWxzLm1hcCgobSkgPT5cbiAgICAgICAgZW5mb3JjZURCRGVjb3JhdG9yczxNLCB0eXBlb2YgdGhpcywgYW55LCBGLCBDPihcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIGNvbnRleHQsXG4gICAgICAgICAgbSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkRFTEVURSxcbiAgICAgICAgICBPcGVyYXRpb25LZXlzLkFGVEVSXG4gICAgICAgIClcbiAgICAgIClcbiAgICApO1xuICAgIHJldHVybiBtb2RlbHM7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIE1lcmdlcyB0d28gbW9kZWwgaW5zdGFuY2VzIGludG8gYSBuZXcgaW5zdGFuY2UuXG4gICAqIEBzdW1tYXJ5IENyZWF0ZXMgYSBuZXcgbW9kZWwgaW5zdGFuY2UgYnkgY29tYmluaW5nIHByb3BlcnRpZXMgZnJvbSBhbiBvbGQgbW9kZWwgYW5kIGEgbmV3IG1vZGVsLlxuICAgKiBQcm9wZXJ0aWVzIGZyb20gdGhlIG5ldyBtb2RlbCBvdmVycmlkZSBwcm9wZXJ0aWVzIGZyb20gdGhlIG9sZCBtb2RlbCBpZiB0aGV5IGFyZSBkZWZpbmVkLlxuICAgKiBAcGFyYW0ge019IG9sZE1vZGVsIC0gVGhlIG9yaWdpbmFsIG1vZGVsIGluc3RhbmNlXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbmV3IG1vZGVsIGluc3RhbmNlIHdpdGggdXBkYXRlZCBwcm9wZXJ0aWVzXG4gICAqIEByZXR1cm4ge019IEEgbmV3IG1vZGVsIGluc3RhbmNlIHdpdGggbWVyZ2VkIHByb3BlcnRpZXNcbiAgICovXG4gIHByb3RlY3RlZCBtZXJnZShvbGRNb2RlbDogTSwgbW9kZWw6IE0pOiBNIHtcbiAgICBjb25zdCBleHRyYWN0ID0gKG1vZGVsOiBNKSA9PlxuICAgICAgT2JqZWN0LmVudHJpZXMobW9kZWwpLnJlZHVjZSgoYWNjdW06IFJlY29yZDxzdHJpbmcsIGFueT4sIFtrZXksIHZhbF0pID0+IHtcbiAgICAgICAgaWYgKHR5cGVvZiB2YWwgIT09IFwidW5kZWZpbmVkXCIpIGFjY3VtW2tleV0gPSB2YWw7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIHt9KTtcblxuICAgIHJldHVybiBuZXcgdGhpcy5jbGFzcyhPYmplY3QuYXNzaWduKHt9LCBleHRyYWN0KG9sZE1vZGVsKSwgZXh0cmFjdChtb2RlbCkpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUmV0dXJucyBhIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVwb3NpdG9yeS5cbiAgICogQHN1bW1hcnkgQ3JlYXRlcyBhIHN0cmluZyB0aGF0IGlkZW50aWZpZXMgdGhpcyByZXBvc2l0b3J5IGJ5IHRoZSBuYW1lIG9mIGl0cyBtb2RlbCBjbGFzcy5cbiAgICogQHJldHVybiB7c3RyaW5nfSBBIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiB0aGUgcmVwb3NpdG9yeVxuICAgKi9cbiAgdG9TdHJpbmcoKSB7XG4gICAgcmV0dXJuIGAke3RoaXMuY2xhc3MubmFtZX0gUmVwb3NpdG9yeWA7XG4gIH1cbn1cbiIsImltcG9ydCB7IGVuZm9yY2VEQkRlY29yYXRvcnMgfSBmcm9tIFwiLi91dGlsc1wiO1xuaW1wb3J0IHsgT3BlcmF0aW9uS2V5cyB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2NvbnN0YW50c1wiO1xuaW1wb3J0IHsgSW50ZXJuYWxFcnJvciwgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBCYXNlUmVwb3NpdG9yeSB9IGZyb20gXCIuL0Jhc2VSZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBDb25zdHJ1Y3RvciwgTW9kZWwgfSBmcm9tIFwiQGRlY2FmLXRzL2RlY29yYXRvci12YWxpZGF0aW9uXCI7XG5pbXBvcnQgeyBEQktleXMgfSBmcm9tIFwiLi4vbW9kZWwvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4vQ29udGV4dFwiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeUZsYWdzIH0gZnJvbSBcIi4vdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ29uY3JldGUgcmVwb3NpdG9yeSBpbXBsZW1lbnRhdGlvbiB3aXRoIHZhbGlkYXRpb24gc3VwcG9ydC5cbiAqIEBzdW1tYXJ5IFRoZSBSZXBvc2l0b3J5IGNsYXNzIGV4dGVuZHMgQmFzZVJlcG9zaXRvcnkgdG8gcHJvdmlkZSBhZGRpdGlvbmFsIHZhbGlkYXRpb25cbiAqIGZ1bmN0aW9uYWxpdHkuIEl0IG92ZXJyaWRlcyBwcmVmaXggbWV0aG9kcyB0byBwZXJmb3JtIG1vZGVsIHZhbGlkYXRpb24gYmVmb3JlIGRhdGFiYXNlXG4gKiBvcGVyYXRpb25zIGFuZCB0aHJvd3MgVmFsaWRhdGlvbkVycm9yIHdoZW4gdmFsaWRhdGlvbiBmYWlscy5cbiAqIEB0ZW1wbGF0ZSBNIC0gVGhlIG1vZGVsIHR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGUsIGRlZmF1bHRzIHRvIFJlcG9zaXRvcnlGbGFnc1xuICogQHRlbXBsYXRlIEMgLSBUaGUgY29udGV4dCB0eXBlLCBkZWZhdWx0cyB0byBDb250ZXh0PEY+XG4gKiBAY2xhc3MgUmVwb3NpdG9yeVxuICogQGV4YW1wbGVcbiAqIGNsYXNzIFVzZXJNb2RlbCBleHRlbmRzIE1vZGVsIHtcbiAqICAgQGlkKClcbiAqICAgaWQ6IHN0cmluZztcbiAqXG4gKiAgIEByZXF1aXJlZCgpXG4gKiAgIEBtaW5MZW5ndGgoMylcbiAqICAgbmFtZTogc3RyaW5nO1xuICogfVxuICpcbiAqIGNsYXNzIFVzZXJSZXBvc2l0b3J5IGV4dGVuZHMgUmVwb3NpdG9yeTxVc2VyTW9kZWw+IHtcbiAqICAgY29uc3RydWN0b3IoKSB7XG4gKiAgICAgc3VwZXIoVXNlck1vZGVsKTtcbiAqICAgfVxuICpcbiAqICAgYXN5bmMgY3JlYXRlKG1vZGVsOiBVc2VyTW9kZWwpOiBQcm9taXNlPFVzZXJNb2RlbD4ge1xuICogICAgIC8vIEltcGxlbWVudGF0aW9uIHdpdGggYXV0b21hdGljIHZhbGlkYXRpb25cbiAqICAgICByZXR1cm4gbW9kZWw7XG4gKiAgIH1cbiAqIH1cbiAqXG4gKiAvLyBVc2luZyB0aGUgcmVwb3NpdG9yeVxuICogY29uc3QgcmVwbyA9IG5ldyBVc2VyUmVwb3NpdG9yeSgpO1xuICogdHJ5IHtcbiAqICAgY29uc3QgdXNlciA9IGF3YWl0IHJlcG8uY3JlYXRlKHsgbmFtZTogJ0pvJyB9KTsgLy8gV2lsbCB0aHJvdyBWYWxpZGF0aW9uRXJyb3JcbiAqIH0gY2F0Y2ggKGVycm9yKSB7XG4gKiAgIGNvbnNvbGUuZXJyb3IoZXJyb3IpOyAvLyBWYWxpZGF0aW9uRXJyb3I6IG5hbWUgbXVzdCBiZSBhdCBsZWFzdCAzIGNoYXJhY3RlcnNcbiAqIH1cbiAqL1xuZXhwb3J0IGFic3RyYWN0IGNsYXNzIFJlcG9zaXRvcnk8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4gPSBDb250ZXh0PEY+LFxuPiBleHRlbmRzIEJhc2VSZXBvc2l0b3J5PE0sIEYsIEM+IHtcbiAgcHJvdGVjdGVkIGNvbnN0cnVjdG9yKGNsYXp6PzogQ29uc3RydWN0b3I8TT4pIHtcbiAgICBzdXBlcihjbGF6eik7XG4gIH1cblxuICAvKipcbiAgICogQGRlc2NyaXB0aW9uIFByZXBhcmVzIGEgbW9kZWwgZm9yIGNyZWF0aW9uIHdpdGggdmFsaWRhdGlvbi5cbiAgICogQHN1bW1hcnkgT3ZlcnJpZGVzIHRoZSBiYXNlIGNyZWF0ZVByZWZpeCBtZXRob2QgdG8gYWRkIHZhbGlkYXRpb24gY2hlY2tzLlxuICAgKiBDcmVhdGVzIGEgY29udGV4dCwgaW5zdGFudGlhdGVzIGEgbmV3IG1vZGVsLCBlbmZvcmNlcyBkZWNvcmF0b3JzLCBhbmQgdmFsaWRhdGVzXG4gICAqIHRoZSBtb2RlbCBiZWZvcmUgYWxsb3dpbmcgY3JlYXRpb24gdG8gcHJvY2VlZC5cbiAgICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSB0byBwcmVwYXJlIGZvciBjcmVhdGlvblxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIHRoZSBjcmVhdGUgb3BlcmF0aW9uXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgY29udGFpbmluZyB0aGUgdmFsaWRhdGVkIG1vZGVsIGFuZCBjb250ZXh0IGFyZ3VtZW50c1xuICAgKiBAdGhyb3dzIHtWYWxpZGF0aW9uRXJyb3J9IElmIHRoZSBtb2RlbCBmYWlscyB2YWxpZGF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgY3JlYXRlUHJlZml4KFxuICAgIG1vZGVsOiBNLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8W00sIC4uLmFueVtdXT4ge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5DUkVBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgbW9kZWwgPSBuZXcgdGhpcy5jbGFzcyhtb2RlbCk7XG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICApO1xuXG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWwuaGFzRXJyb3JzKCk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMudG9TdHJpbmcoKSk7XG5cbiAgICByZXR1cm4gW21vZGVsLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgbXVsdGlwbGUgbW9kZWxzIGZvciBjcmVhdGlvbiB3aXRoIHZhbGlkYXRpb24uXG4gICAqIEBzdW1tYXJ5IE92ZXJyaWRlcyB0aGUgYmFzZSBjcmVhdGVBbGxQcmVmaXggbWV0aG9kIHRvIGFkZCB2YWxpZGF0aW9uIGNoZWNrcyBmb3IgbXVsdGlwbGUgbW9kZWxzLlxuICAgKiBDcmVhdGVzIGEgY29udGV4dCwgaW5zdGFudGlhdGVzIG5ldyBtb2RlbHMsIGVuZm9yY2VzIGRlY29yYXRvcnMsIGFuZCB2YWxpZGF0ZXNcbiAgICogZWFjaCBtb2RlbCBiZWZvcmUgYWxsb3dpbmcgY3JlYXRpb24gdG8gcHJvY2VlZC4gQ29sbGVjdHMgdmFsaWRhdGlvbiBlcnJvcnMgZnJvbSBhbGwgbW9kZWxzLlxuICAgKiBAcGFyYW0ge01bXX0gbW9kZWxzIC0gVGhlIGFycmF5IG9mIG1vZGVsIGluc3RhbmNlcyB0byBwcmVwYXJlIGZvciBjcmVhdGlvblxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIHRoZSBjcmVhdGUgb3BlcmF0aW9uXG4gICAqIEByZXR1cm4ge1Byb21pc2U8YW55W10+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBjb250YWluaW5nIHRoZSB2YWxpZGF0ZWQgbW9kZWxzIGFuZCBjb250ZXh0IGFyZ3VtZW50c1xuICAgKiBAdGhyb3dzIHtWYWxpZGF0aW9uRXJyb3J9IElmIGFueSBtb2RlbCBmYWlscyB2YWxpZGF0aW9uLCB3aXRoIGRldGFpbHMgYWJvdXQgd2hpY2ggbW9kZWxzIGZhaWxlZFxuICAgKi9cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGFzeW5jIGNyZWF0ZUFsbFByZWZpeChcbiAgICBtb2RlbHM6IE1bXSxcbiAgICAuLi5hcmdzOiBhbnlbXVxuICApOiBQcm9taXNlPGFueVtdPiB7XG4gICAgY29uc3QgY29udGV4dEFyZ3MgPSBhd2FpdCBDb250ZXh0LmFyZ3MoXG4gICAgICBPcGVyYXRpb25LZXlzLkNSRUFURSxcbiAgICAgIHRoaXMuY2xhc3MsXG4gICAgICBhcmdzXG4gICAgKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoYXN5bmMgKG0pID0+IHtcbiAgICAgICAgbSA9IG5ldyB0aGlzLmNsYXNzKG0pO1xuICAgICAgICBhd2FpdCBlbmZvcmNlREJEZWNvcmF0b3JzKFxuICAgICAgICAgIHRoaXMsXG4gICAgICAgICAgY29udGV4dEFyZ3MuY29udGV4dCxcbiAgICAgICAgICBtLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuQ1JFQVRFLFxuICAgICAgICAgIE9wZXJhdGlvbktleXMuT05cbiAgICAgICAgKTtcbiAgICAgICAgcmV0dXJuIG07XG4gICAgICB9KVxuICAgICk7XG4gICAgY29uc3QgZXJyb3JzID0gbW9kZWxzXG4gICAgICAubWFwKChtKSA9PiBtLmhhc0Vycm9ycygpKVxuICAgICAgLnJlZHVjZSgoYWNjdW06IHN0cmluZyB8IHVuZGVmaW5lZCwgZSwgaSkgPT4ge1xuICAgICAgICBpZiAoZSlcbiAgICAgICAgICBhY2N1bSA9XG4gICAgICAgICAgICB0eXBlb2YgYWNjdW0gPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgPyBhY2N1bSArIGBcXG4gLSAke2l9OiAke2UudG9TdHJpbmcoKX1gXG4gICAgICAgICAgICAgIDogYCAtICR7aX06ICR7ZS50b1N0cmluZygpfWA7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIHVuZGVmaW5lZCk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMpO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgYSBtb2RlbCBmb3IgdXBkYXRlIHdpdGggdmFsaWRhdGlvbi5cbiAgICogQHN1bW1hcnkgT3ZlcnJpZGVzIHRoZSBiYXNlIHVwZGF0ZVByZWZpeCBtZXRob2QgdG8gYWRkIHZhbGlkYXRpb24gY2hlY2tzLlxuICAgKiBDcmVhdGVzIGEgY29udGV4dCwgdmFsaWRhdGVzIHRoZSBwcmltYXJ5IGtleSwgcmV0cmlldmVzIHRoZSBleGlzdGluZyBtb2RlbCxcbiAgICogbWVyZ2VzIHRoZSBvbGQgYW5kIG5ldyBtb2RlbHMsIGVuZm9yY2VzIGRlY29yYXRvcnMsIGFuZCB2YWxpZGF0ZXMgdGhlIG1vZGVsXG4gICAqIGJlZm9yZSBhbGxvd2luZyB0aGUgdXBkYXRlIHRvIHByb2NlZWQuXG4gICAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgdG8gcHJlcGFyZSBmb3IgdXBkYXRlXG4gICAqIEBwYXJhbSB7YW55W119IGFyZ3MgLSBBZGRpdGlvbmFsIGFyZ3VtZW50cyBmb3IgdGhlIHVwZGF0ZSBvcGVyYXRpb25cbiAgICogQHJldHVybiBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBhcnJheSBjb250YWluaW5nIHRoZSB2YWxpZGF0ZWQgbW9kZWwgYW5kIGNvbnRleHQgYXJndW1lbnRzXG4gICAqIEB0aHJvd3Mge0ludGVybmFsRXJyb3J9IElmIHRoZSBtb2RlbCBkb2Vzbid0IGhhdmUgYSBwcmltYXJ5IGtleSB2YWx1ZVxuICAgKiBAdGhyb3dzIHtWYWxpZGF0aW9uRXJyb3J9IElmIHRoZSBtb2RlbCBmYWlscyB2YWxpZGF0aW9uXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgdXBkYXRlUHJlZml4KFxuICAgIG1vZGVsOiBNLFxuICAgIC4uLmFyZ3M6IGFueVtdXG4gICk6IFByb21pc2U8W00sIC4uLmFyZ3M6IGFueVtdXT4ge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgY29uc3QgcGsgPSAobW9kZWwgYXMgYW55KVt0aGlzLnBrXTtcbiAgICBpZiAoIXBrKVxuICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgIGBObyB2YWx1ZSBmb3IgdGhlIElkIGlzIGRlZmluZWQgdW5kZXIgdGhlIHByb3BlcnR5ICR7dGhpcy5wayBhcyBzdHJpbmd9YFxuICAgICAgKTtcblxuICAgIGNvbnN0IG9sZE1vZGVsOiBNID0gYXdhaXQgdGhpcy5yZWFkKHBrKTtcblxuICAgIG1vZGVsID0gdGhpcy5tZXJnZShvbGRNb2RlbCwgbW9kZWwpO1xuXG4gICAgYXdhaXQgZW5mb3JjZURCRGVjb3JhdG9ycyhcbiAgICAgIHRoaXMsXG4gICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgbW9kZWwsXG4gICAgICBPcGVyYXRpb25LZXlzLlVQREFURSxcbiAgICAgIE9wZXJhdGlvbktleXMuT04sXG4gICAgICBvbGRNb2RlbFxuICAgICk7XG5cbiAgICBjb25zdCBlcnJvcnMgPSBtb2RlbC5oYXNFcnJvcnMob2xkTW9kZWwgYXMgYW55KTtcbiAgICBpZiAoZXJyb3JzKSB0aHJvdyBuZXcgVmFsaWRhdGlvbkVycm9yKGVycm9ycy50b1N0cmluZygpKTtcbiAgICByZXR1cm4gW21vZGVsLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gUHJlcGFyZXMgbXVsdGlwbGUgbW9kZWxzIGZvciB1cGRhdGUgd2l0aCB2YWxpZGF0aW9uLlxuICAgKiBAc3VtbWFyeSBPdmVycmlkZXMgdGhlIGJhc2UgdXBkYXRlQWxsUHJlZml4IG1ldGhvZCB0byBhZGQgdmFsaWRhdGlvbiBjaGVja3MgZm9yIG11bHRpcGxlIG1vZGVscy5cbiAgICogQ3JlYXRlcyBhIGNvbnRleHQsIHZhbGlkYXRlcyBwcmltYXJ5IGtleXMsIHJldHJpZXZlcyBleGlzdGluZyBtb2RlbHMsIG1lcmdlcyBvbGQgYW5kIG5ldyBtb2RlbHMsXG4gICAqIGVuZm9yY2VzIGRlY29yYXRvcnMsIGFuZCB2YWxpZGF0ZXMgZWFjaCBtb2RlbCBiZWZvcmUgYWxsb3dpbmcgdXBkYXRlcyB0byBwcm9jZWVkLlxuICAgKiBDb2xsZWN0cyB2YWxpZGF0aW9uIGVycm9ycyBmcm9tIGFsbCBtb2RlbHMuXG4gICAqIEBwYXJhbSB7TVtdfSBtb2RlbHMgLSBUaGUgYXJyYXkgb2YgbW9kZWwgaW5zdGFuY2VzIHRvIHByZXBhcmUgZm9yIHVwZGF0ZVxuICAgKiBAcGFyYW0ge2FueVtdfSBhcmdzIC0gQWRkaXRpb25hbCBhcmd1bWVudHMgZm9yIHRoZSB1cGRhdGUgb3BlcmF0aW9uXG4gICAqIEByZXR1cm4gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gYXJyYXkgY29udGFpbmluZyB0aGUgdmFsaWRhdGVkIG1vZGVscyBhbmQgY29udGV4dCBhcmd1bWVudHNcbiAgICogQHRocm93cyB7SW50ZXJuYWxFcnJvcn0gSWYgYW55IG1vZGVsIGRvZXNuJ3QgaGF2ZSBhIHByaW1hcnkga2V5IHZhbHVlXG4gICAqIEB0aHJvd3Mge1ZhbGlkYXRpb25FcnJvcn0gSWYgYW55IG1vZGVsIGZhaWxzIHZhbGlkYXRpb24sIHdpdGggZGV0YWlscyBhYm91dCB3aGljaCBtb2RlbHMgZmFpbGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgYXN5bmMgdXBkYXRlQWxsUHJlZml4KG1vZGVsczogTVtdLCAuLi5hcmdzOiBhbnlbXSkge1xuICAgIGNvbnN0IGNvbnRleHRBcmdzID0gYXdhaXQgQ29udGV4dC5hcmdzKFxuICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICB0aGlzLmNsYXNzLFxuICAgICAgYXJnc1xuICAgICk7XG4gICAgY29uc3QgaWRzID0gbW9kZWxzLm1hcCgobSkgPT4ge1xuICAgICAgY29uc3QgaWQgPSBtW3RoaXMucGtdO1xuICAgICAgaWYgKHR5cGVvZiBpZCA9PT0gXCJ1bmRlZmluZWRcIilcbiAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgYE5vIHZhbHVlIGZvciB0aGUgSWQgaXMgZGVmaW5lZCB1bmRlciB0aGUgcHJvcGVydHkgJHt0aGlzLnBrIGFzIHN0cmluZ31gXG4gICAgICAgICk7XG4gICAgICByZXR1cm4gaWQgYXMgc3RyaW5nO1xuICAgIH0pO1xuICAgIGNvbnN0IG9sZE1vZGVsczogTVtdID0gYXdhaXQgdGhpcy5yZWFkQWxsKGlkcywgLi4uY29udGV4dEFyZ3MuYXJncyk7XG4gICAgbW9kZWxzID0gbW9kZWxzLm1hcCgobSwgaSkgPT4gdGhpcy5tZXJnZShvbGRNb2RlbHNbaV0sIG0pKTtcbiAgICBhd2FpdCBQcm9taXNlLmFsbChcbiAgICAgIG1vZGVscy5tYXAoKG0sIGkpID0+XG4gICAgICAgIGVuZm9yY2VEQkRlY29yYXRvcnMoXG4gICAgICAgICAgdGhpcyxcbiAgICAgICAgICBjb250ZXh0QXJncy5jb250ZXh0LFxuICAgICAgICAgIG0sXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5VUERBVEUsXG4gICAgICAgICAgT3BlcmF0aW9uS2V5cy5PTixcbiAgICAgICAgICBvbGRNb2RlbHNbaV1cbiAgICAgICAgKVxuICAgICAgKVxuICAgICk7XG5cbiAgICBjb25zdCBlcnJvcnMgPSBtb2RlbHNcbiAgICAgIC5tYXAoKG0sIGkpID0+IG0uaGFzRXJyb3JzKG9sZE1vZGVsc1tpXSBhcyBhbnkpKVxuICAgICAgLnJlZHVjZSgoYWNjdW06IHN0cmluZyB8IHVuZGVmaW5lZCwgZSwgaSkgPT4ge1xuICAgICAgICBpZiAoZSlcbiAgICAgICAgICBhY2N1bSA9XG4gICAgICAgICAgICB0eXBlb2YgYWNjdW0gPT09IFwic3RyaW5nXCJcbiAgICAgICAgICAgICAgPyBhY2N1bSArIGBcXG4gLSAke2l9OiAke2UudG9TdHJpbmcoKX1gXG4gICAgICAgICAgICAgIDogYCAtICR7aX06ICR7ZS50b1N0cmluZygpfWA7XG4gICAgICAgIHJldHVybiBhY2N1bTtcbiAgICAgIH0sIHVuZGVmaW5lZCk7XG4gICAgaWYgKGVycm9ycykgdGhyb3cgbmV3IFZhbGlkYXRpb25FcnJvcihlcnJvcnMpO1xuICAgIHJldHVybiBbbW9kZWxzLCAuLi5jb250ZXh0QXJncy5hcmdzXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIHJlZmxlY3Rpb24ga2V5IGZvciBkYXRhYmFzZSBvcGVyYXRpb25zLlxuICAgKiBAc3VtbWFyeSBHZW5lcmF0ZXMgYSBrZXkgZm9yIHN0b3JpbmcgbWV0YWRhdGEgaW4gdGhlIHJlZmxlY3Rpb24gc3lzdGVtIGJ5IHByZWZpeGluZ1xuICAgKiB0aGUgcHJvdmlkZWQga2V5IHdpdGggdGhlIGRhdGFiYXNlIHJlZmxlY3Rpb24gcHJlZml4LlxuICAgKiBAcGFyYW0ge3N0cmluZ30ga2V5IC0gVGhlIGJhc2Uga2V5IHRvIHByZWZpeFxuICAgKiBAcmV0dXJuIHtzdHJpbmd9IFRoZSBwcmVmaXhlZCByZWZsZWN0aW9uIGtleVxuICAgKi9cbiAgc3RhdGljIGtleShrZXk6IHN0cmluZykge1xuICAgIHJldHVybiBEQktleXMuUkVGTEVDVCArIGtleTtcbiAgfVxufVxuIiwiaW1wb3J0IFwiLi92YWxpZGF0aW9uXCI7XG5pbXBvcnQge1xuICBkYXRlLFxuICBEZWNvcmF0aW9uLFxuICBNb2RlbCxcbiAgcHJvcE1ldGFkYXRhLFxuICByZXF1aXJlZCxcbiAgdHlwZSxcbiAgVmFsaWRhdGlvbixcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgREJLZXlzLCBERUZBVUxUX1RJTUVTVEFNUF9GT1JNQVQgfSBmcm9tIFwiLi4vbW9kZWwvY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBERUZBVUxUX0VSUk9SX01FU1NBR0VTIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBEQk9wZXJhdGlvbnMsIE9wZXJhdGlvbktleXMgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy9jb25zdGFudHNcIjtcbmltcG9ydCB7IGFmdGVyLCBvbiwgb25DcmVhdGVVcGRhdGUgfSBmcm9tIFwiLi4vb3BlcmF0aW9ucy9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBJUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9pbnRlcmZhY2VzL0lSZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBTZXJpYWxpemF0aW9uRXJyb3IgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9lcnJvcnNcIjtcbmltcG9ydCB7IGFwcGx5LCBtZXRhZGF0YSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeSB9IGZyb20gXCIuLi9yZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvQ29udGV4dFwiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeUZsYWdzIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gUHJldmVudHMgYSBwcm9wZXJ0eSBmcm9tIGJlaW5nIG1vZGlmaWVkIGFmdGVyIGluaXRpYWwgY3JlYXRpb24uXG4gKiBAc3VtbWFyeSBNYXJrcyB0aGUgcHJvcGVydHkgYXMgcmVhZG9ubHksIGNhdXNpbmcgdmFsaWRhdGlvbiBlcnJvcnMgaWYgYXR0ZW1wdHMgYXJlIG1hZGUgdG8gbW9kaWZ5IGl0IGR1cmluZyB1cGRhdGVzLlxuICogQHBhcmFtIHtzdHJpbmd9IFttZXNzYWdlXSAtIFRoZSBlcnJvciBtZXNzYWdlIHRvIGRpc3BsYXkgd2hlbiB2YWxpZGF0aW9uIGZhaWxzLiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9FUlJPUl9NRVNTQUdFUy5SRUFET05MWS5JTlZBTElEfVxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIHJlYWRvbmx5XG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gcmVhZG9ubHkoXG4gIG1lc3NhZ2U6IHN0cmluZyA9IERFRkFVTFRfRVJST1JfTUVTU0FHRVMuUkVBRE9OTFkuSU5WQUxJRFxuKSB7XG4gIGNvbnN0IGtleSA9IFZhbGlkYXRpb24udXBkYXRlS2V5KERCS2V5cy5SRUFET05MWSk7XG4gIHJldHVybiBEZWNvcmF0aW9uLmZvcihrZXkpXG4gICAgLmRlZmluZShcbiAgICAgIHByb3BNZXRhZGF0YShrZXksIHtcbiAgICAgICAgbWVzc2FnZTogbWVzc2FnZSxcbiAgICAgIH0pXG4gICAgKVxuICAgIC5hcHBseSgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBIYW5kbGVyIGZ1bmN0aW9uIHRoYXQgc2V0cyBhIHRpbWVzdGFtcCBwcm9wZXJ0eSB0byB0aGUgY3VycmVudCB0aW1lc3RhbXAuXG4gKiBAc3VtbWFyeSBVcGRhdGVzIGEgbW9kZWwgcHJvcGVydHkgd2l0aCB0aGUgY3VycmVudCB0aW1lc3RhbXAgZnJvbSB0aGUgcmVwb3NpdG9yeSBjb250ZXh0LlxuICogQHRlbXBsYXRlIE0gLSBUaGUgbW9kZWwgdHlwZSBleHRlbmRpbmcgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBSIC0gVGhlIHJlcG9zaXRvcnkgdHlwZSBleHRlbmRpbmcgSVJlcG9zaXRvcnlcbiAqIEB0ZW1wbGF0ZSBWIC0gVGhlIGRhdGEgdHlwZSBmb3IgdGhlIG9wZXJhdGlvblxuICogQHRlbXBsYXRlIEYgLSBUaGUgcmVwb3NpdG9yeSBmbGFncyB0eXBlXG4gKiBAdGVtcGxhdGUgQyAtIFRoZSBjb250ZXh0IHR5cGVcbiAqIEBwYXJhbSB7Q30gY29udGV4dCAtIFRoZSByZXBvc2l0b3J5IGNvbnRleHQgY29udGFpbmluZyB0aGUgY3VycmVudCB0aW1lc3RhbXBcbiAqIEBwYXJhbSB7Vn0gZGF0YSAtIFRoZSBkYXRhIGJlaW5nIHByb2Nlc3NlZFxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgdG8gdXBkYXRlXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIGJlaW5nIHVwZGF0ZWRcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIHRpbWVzdGFtcCBoYXMgYmVlbiBzZXRcbiAqIEBmdW5jdGlvbiB0aW1lc3RhbXBIYW5kbGVyXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHRpbWVzdGFtcEhhbmRsZXI8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIElSZXBvc2l0b3J5PE0sIEYsIEM+LFxuICBWLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzID0gUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4+KHRoaXM6IFIsIGNvbnRleHQ6IEMsIGRhdGE6IFYsIGtleToga2V5b2YgTSwgbW9kZWw6IE0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgKG1vZGVsIGFzIGFueSlba2V5XSA9IGNvbnRleHQudGltZXN0YW1wO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBBdXRvbWF0aWNhbGx5IG1hbmFnZXMgdGltZXN0YW1wIHByb3BlcnRpZXMgZm9yIHRyYWNraW5nIGNyZWF0aW9uIGFuZCB1cGRhdGUgdGltZXMuXG4gKiBAc3VtbWFyeSBNYXJrcyB0aGUgcHJvcGVydHkgYXMgYSB0aW1lc3RhbXAsIG1ha2luZyBpdCByZXF1aXJlZCBhbmQgZW5zdXJpbmcgaXQncyBhIHZhbGlkIGRhdGUuIFRoZSBwcm9wZXJ0eSB3aWxsIGJlIGF1dG9tYXRpY2FsbHkgdXBkYXRlZCB3aXRoIHRoZSBjdXJyZW50IHRpbWVzdGFtcCBkdXJpbmcgc3BlY2lmaWVkIG9wZXJhdGlvbnMuXG4gKlxuICogRGF0ZSBGb3JtYXQ6XG4gKlxuICogPHByZT5cbiAqICAgICAgVXNpbmcgc2ltaWxhciBmb3JtYXR0aW5nIGFzIE1vbWVudC5qcywgQ2xhc3MgRGF0ZVRpbWVGb3JtYXR0ZXIgKEphdmEpLCBhbmQgQ2xhc3MgU2ltcGxlRGF0ZUZvcm1hdCAoSmF2YSksXG4gKiAgICAgIEkgaW1wbGVtZW50ZWQgYSBjb21wcmVoZW5zaXZlIHNvbHV0aW9uIGZvcm1hdERhdGUoZGF0ZSwgcGF0dGVyblN0cikgd2hlcmUgdGhlIGNvZGUgaXMgZWFzeSB0byByZWFkIGFuZCBtb2RpZnkuXG4gKiAgICAgIFlvdSBjYW4gZGlzcGxheSBkYXRlLCB0aW1lLCBBTS9QTSwgZXRjLlxuICpcbiAqICAgICAgRGF0ZSBhbmQgVGltZSBQYXR0ZXJuc1xuICogICAgICB5eSA9IDItZGlnaXQgeWVhcjsgeXl5eSA9IGZ1bGwgeWVhclxuICogICAgICBNID0gZGlnaXQgbW9udGg7IE1NID0gMi1kaWdpdCBtb250aDsgTU1NID0gc2hvcnQgbW9udGggbmFtZTsgTU1NTSA9IGZ1bGwgbW9udGggbmFtZVxuICogICAgICBFRUVFID0gZnVsbCB3ZWVrZGF5IG5hbWU7IEVFRSA9IHNob3J0IHdlZWtkYXkgbmFtZVxuICogICAgICBkID0gZGlnaXQgZGF5OyBkZCA9IDItZGlnaXQgZGF5XG4gKiAgICAgIGggPSBob3VycyBhbS9wbTsgaGggPSAyLWRpZ2l0IGhvdXJzIGFtL3BtOyBIID0gaG91cnM7IEhIID0gMi1kaWdpdCBob3Vyc1xuICogICAgICBtID0gbWludXRlczsgbW0gPSAyLWRpZ2l0IG1pbnV0ZXM7IGFhYSA9IEFNL1BNXG4gKiAgICAgIHMgPSBzZWNvbmRzOyBzcyA9IDItZGlnaXQgc2Vjb25kc1xuICogICAgICBTID0gbWlsaXNlY29uZHNcbiAqIDwvcHJlPlxuICpcbiAqIEBwYXJhbSB7T3BlcmF0aW9uS2V5c1tdfSBvcGVyYXRpb24gLSBUaGUgb3BlcmF0aW9ucyB0byBhY3Qgb24uIERlZmF1bHRzIHRvIHtAbGluayBEQk9wZXJhdGlvbnMuQ1JFQVRFX1VQREFURX1cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZm9ybWF0XSAtIFRoZSB0aW1lc3RhbXAgZm9ybWF0LiBEZWZhdWx0cyB0byB7QGxpbmsgREVGQVVMVF9USU1FU1RBTVBfRk9STUFUfVxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIHRpbWVzdGFtcFxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgTSBhcyBNb2RlbFxuICogICBwYXJ0aWNpcGFudCBUIGFzIFRpbWVzdGFtcERlY29yYXRvclxuICogICBwYXJ0aWNpcGFudCBWIGFzIFZhbGlkYXRvclxuICpcbiAqICAgQy0+Pk06IENyZWF0ZS9VcGRhdGUgbW9kZWxcbiAqICAgTS0+PlQ6IFByb2Nlc3MgdGltZXN0YW1wIHByb3BlcnR5XG4gKiAgIFQtPj5NOiBBcHBseSByZXF1aXJlZCB2YWxpZGF0aW9uXG4gKiAgIFQtPj5NOiBBcHBseSBkYXRlIGZvcm1hdCB2YWxpZGF0aW9uXG4gKlxuICogICBhbHQgVXBkYXRlIG9wZXJhdGlvblxuICogICAgIFQtPj5WOiBSZWdpc3RlciB0aW1lc3RhbXAgdmFsaWRhdG9yXG4gKiAgICAgVi0+Pk06IFZhbGlkYXRlIHRpbWVzdGFtcCBpcyBuZXdlclxuICogICBlbmRcbiAqXG4gKiAgIFQtPj5NOiBTZXQgY3VycmVudCB0aW1lc3RhbXBcbiAqICAgTS0+PkM6IFJldHVybiB1cGRhdGVkIG1vZGVsXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB0aW1lc3RhbXAoXG4gIG9wZXJhdGlvbjogT3BlcmF0aW9uS2V5c1tdID0gREJPcGVyYXRpb25zLkNSRUFURV9VUERBVEUgYXMgdW5rbm93biBhcyBPcGVyYXRpb25LZXlzW10sXG4gIGZvcm1hdDogc3RyaW5nID0gREVGQVVMVF9USU1FU1RBTVBfRk9STUFUXG4pIHtcbiAgY29uc3Qga2V5ID0gVmFsaWRhdGlvbi51cGRhdGVLZXkoREJLZXlzLlRJTUVTVEFNUCk7XG5cbiAgY29uc3QgZGVjb3JhdG9yczogYW55W10gPSBbXG4gICAgZGF0ZShmb3JtYXQsIERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVElNRVNUQU1QLkRBVEUpLFxuICAgIHJlcXVpcmVkKERFRkFVTFRfRVJST1JfTUVTU0FHRVMuVElNRVNUQU1QLlJFUVVJUkVEKSxcbiAgICBvbihvcGVyYXRpb24sIHRpbWVzdGFtcEhhbmRsZXIpLFxuICBdO1xuXG4gIGlmIChvcGVyYXRpb24uaW5kZXhPZihPcGVyYXRpb25LZXlzLlVQREFURSkgIT09IC0xKVxuICAgIGRlY29yYXRvcnMucHVzaChcbiAgICAgIHByb3BNZXRhZGF0YShWYWxpZGF0aW9uLnVwZGF0ZUtleShEQktleXMuVElNRVNUQU1QKSwge1xuICAgICAgICBtZXNzYWdlOiBERUZBVUxUX0VSUk9SX01FU1NBR0VTLlRJTUVTVEFNUC5JTlZBTElELFxuICAgICAgfSlcbiAgICApO1xuICByZXR1cm4gRGVjb3JhdGlvbi5mb3Ioa2V5KVxuICAgIC5kZWZpbmUoLi4uZGVjb3JhdG9ycylcbiAgICAuYXBwbHkoKTtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSGFuZGxlciBmdW5jdGlvbiB0aGF0IHNlcmlhbGl6ZXMgYSBwcm9wZXJ0eSB0byBKU09OIHN0cmluZyBkdXJpbmcgY3JlYXRlIGFuZCB1cGRhdGUgb3BlcmF0aW9ucy5cbiAqIEBzdW1tYXJ5IENvbnZlcnRzIGEgY29tcGxleCBvYmplY3QgcHJvcGVydHkgdG8gYSBKU09OIHN0cmluZyBiZWZvcmUgc3RvcmluZyBpdCBpbiB0aGUgZGF0YWJhc2UuXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUaGUgcmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBJUmVwb3NpdG9yeVxuICogQHRlbXBsYXRlIFYgLSBUaGUgZGF0YSB0eXBlIGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEB0ZW1wbGF0ZSBDIC0gVGhlIGNvbnRleHQgdHlwZVxuICogQHBhcmFtIHtDfSBjb250ZXh0IC0gVGhlIHJlcG9zaXRvcnkgY29udGV4dFxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIGRhdGEgYmVpbmcgcHJvY2Vzc2VkXG4gKiBAcGFyYW0ga2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byBzZXJpYWxpemVcbiAqIEBwYXJhbSB7TX0gbW9kZWwgLSBUaGUgbW9kZWwgaW5zdGFuY2UgYmVpbmcgcHJvY2Vzc2VkXG4gKiBAcmV0dXJuIHtQcm9taXNlPHZvaWQ+fSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB3aGVuIHRoZSBwcm9wZXJ0eSBoYXMgYmVlbiBzZXJpYWxpemVkXG4gKiBAZnVuY3Rpb24gc2VyaWFsaXplT25DcmVhdGVVcGRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gc2VyaWFsaXplT25DcmVhdGVVcGRhdGU8XG4gIE0gZXh0ZW5kcyBNb2RlbCxcbiAgUiBleHRlbmRzIElSZXBvc2l0b3J5PE0sIEYsIEM+LFxuICBWLFxuICBGIGV4dGVuZHMgUmVwb3NpdG9yeUZsYWdzID0gUmVwb3NpdG9yeUZsYWdzLFxuICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4+KHRoaXM6IFIsIGNvbnRleHQ6IEMsIGRhdGE6IFYsIGtleToga2V5b2YgTSwgbW9kZWw6IE0pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKCFtb2RlbFtrZXldKSByZXR1cm47XG4gIHRyeSB7XG4gICAgbW9kZWxba2V5XSA9IEpTT04uc3RyaW5naWZ5KG1vZGVsW2tleV0pIGFzIE1ba2V5b2YgTV07XG4gICAgLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xuICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgIGBGYWlsZWQgdG8gc2VyaWFsaXplICR7a2V5LnRvU3RyaW5nKCl9IHByb3BlcnR5IG9mIG1vZGVsICR7bW9kZWwuY29uc3RydWN0b3IubmFtZX06IGVgXG4gICAgKTtcbiAgfVxufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBIYW5kbGVyIGZ1bmN0aW9uIHRoYXQgZGVzZXJpYWxpemVzIGEgcHJvcGVydHkgZnJvbSBKU09OIHN0cmluZyBhZnRlciBkYXRhYmFzZSBvcGVyYXRpb25zLlxuICogQHN1bW1hcnkgQ29udmVydHMgYSBKU09OIHN0cmluZyBwcm9wZXJ0eSBiYWNrIHRvIGl0cyBvcmlnaW5hbCBjb21wbGV4IG9iamVjdCBmb3JtIGFmdGVyIHJldHJpZXZpbmcgaXQgZnJvbSB0aGUgZGF0YWJhc2UuXG4gKiBAdGVtcGxhdGUgTSAtIFRoZSBtb2RlbCB0eXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUaGUgcmVwb3NpdG9yeSB0eXBlIGV4dGVuZGluZyBJUmVwb3NpdG9yeVxuICogQHRlbXBsYXRlIFYgLSBUaGUgZGF0YSB0eXBlIGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAdGVtcGxhdGUgRiAtIFRoZSByZXBvc2l0b3J5IGZsYWdzIHR5cGVcbiAqIEB0ZW1wbGF0ZSBDIC0gVGhlIGNvbnRleHQgdHlwZVxuICogQHBhcmFtIHtDfSBjb250ZXh0IC0gVGhlIHJlcG9zaXRvcnkgY29udGV4dFxuICogQHBhcmFtIHtWfSBkYXRhIC0gVGhlIGRhdGEgYmVpbmcgcHJvY2Vzc2VkXG4gKiBAcGFyYW0ga2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byBkZXNlcmlhbGl6ZVxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBpbnN0YW5jZSBiZWluZyBwcm9jZXNzZWRcbiAqIEByZXR1cm4ge1Byb21pc2U8dm9pZD59IEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIHByb3BlcnR5IGhhcyBiZWVuIGRlc2VyaWFsaXplZFxuICogQGZ1bmN0aW9uIHNlcmlhbGl6ZUFmdGVyQWxsXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHNlcmlhbGl6ZUFmdGVyQWxsPFxuICBNIGV4dGVuZHMgTW9kZWwsXG4gIFIgZXh0ZW5kcyBJUmVwb3NpdG9yeTxNLCBGLCBDPixcbiAgVixcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4gPSBDb250ZXh0PEY+LFxuPih0aGlzOiBSLCBjb250ZXh0OiBDLCBkYXRhOiBWLCBrZXk6IGtleW9mIE0sIG1vZGVsOiBNKTogUHJvbWlzZTx2b2lkPiB7XG4gIGlmICghbW9kZWxba2V5XSkgcmV0dXJuO1xuICBpZiAodHlwZW9mIG1vZGVsW2tleV0gIT09IFwic3RyaW5nXCIpIHJldHVybjtcblxuICB0cnkge1xuICAgIG1vZGVsW2tleV0gPSBKU09OLnBhcnNlKG1vZGVsW2tleV0pO1xuICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgIGBGYWlsZWQgdG8gZGVzZXJpYWxpemUgJHtrZXkudG9TdHJpbmcoKX0gcHJvcGVydHkgb2YgbW9kZWwgJHttb2RlbC5jb25zdHJ1Y3Rvci5uYW1lfTogJHtlfWBcbiAgICApO1xuICB9XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIEVuYWJsZXMgYXV0b21hdGljIEpTT04gc2VyaWFsaXphdGlvbiBhbmQgZGVzZXJpYWxpemF0aW9uIGZvciBjb21wbGV4IG9iamVjdCBwcm9wZXJ0aWVzLlxuICogQHN1bW1hcnkgRGVjb3JhdG9yIHRoYXQgYXV0b21hdGljYWxseSBjb252ZXJ0cyBjb21wbGV4IG9iamVjdHMgdG8gSlNPTiBzdHJpbmdzIGJlZm9yZSBzdG9yaW5nIGluIHRoZSBkYXRhYmFzZSBhbmQgYmFjayB0byBvYmplY3RzIHdoZW4gcmV0cmlldmluZyB0aGVtLlxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIGZ1bmN0aW9uIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIHNlcmlhbGl6ZVxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQyBhcyBDbGllbnRcbiAqICAgcGFydGljaXBhbnQgTSBhcyBNb2RlbFxuICogICBwYXJ0aWNpcGFudCBTIGFzIFNlcmlhbGl6ZURlY29yYXRvclxuICogICBwYXJ0aWNpcGFudCBEQiBhcyBEYXRhYmFzZVxuICpcbiAqICAgTm90ZSBvdmVyIEMsREI6IENyZWF0ZS9VcGRhdGUgRmxvd1xuICogICBDLT4+TTogU2V0IGNvbXBsZXggb2JqZWN0IHByb3BlcnR5XG4gKiAgIE0tPj5TOiBQcm9jZXNzIHByb3BlcnR5IChjcmVhdGUvdXBkYXRlKVxuICogICBTLT4+TTogQ29udmVydCB0byBKU09OIHN0cmluZ1xuICogICBNLT4+REI6IFN0b3JlIHNlcmlhbGl6ZWQgZGF0YVxuICpcbiAqICAgTm90ZSBvdmVyIEMsREI6IFJldHJpZXZhbCBGbG93XG4gKiAgIEMtPj5NOiBSZXF1ZXN0IG1vZGVsXG4gKiAgIE0tPj5EQjogRmV0Y2ggZGF0YVxuICogICBEQi0+Pk06IFJldHVybiB3aXRoIHNlcmlhbGl6ZWQgcHJvcGVydHlcbiAqICAgTS0+PlM6IFByb2Nlc3MgcHJvcGVydHkgKGFmdGVyIGFsbCBvcHMpXG4gKiAgIFMtPj5NOiBQYXJzZSBKU09OIGJhY2sgdG8gb2JqZWN0XG4gKiAgIE0tPj5DOiBSZXR1cm4gbW9kZWwgd2l0aCBkZXNlcmlhbGl6ZWQgcHJvcGVydHlcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHNlcmlhbGl6ZSgpIHtcbiAgcmV0dXJuIGFwcGx5KFxuICAgIG9uQ3JlYXRlVXBkYXRlKHNlcmlhbGl6ZU9uQ3JlYXRlVXBkYXRlKSxcbiAgICBhZnRlcihEQk9wZXJhdGlvbnMuQUxMLCBzZXJpYWxpemVBZnRlckFsbCksXG4gICAgdHlwZShbU3RyaW5nLm5hbWUsIE9iamVjdC5uYW1lXSksXG4gICAgbWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLlNFUklBTElaRSksIHt9KVxuICApO1xufVxuIiwiaW1wb3J0IHsgcHJvcE1ldGFkYXRhLCByZXF1aXJlZCB9IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcbmltcG9ydCB7IHJlYWRvbmx5IH0gZnJvbSBcIi4uL3ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IERCS2V5cyB9IGZyb20gXCIuLi9tb2RlbC9jb25zdGFudHNcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeVwiO1xuaW1wb3J0IHsgYXBwbHkgfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gRGVjb3JhdG9yIHRoYXQgbWFya3MgYSBwcm9wZXJ0eSBhcyBhbiBJRCBmaWVsZFxuICogQHN1bW1hcnkgQ3JlYXRlcyBhIGNvbXBvc2l0ZSBkZWNvcmF0b3IgdGhhdCBtYXJrcyBhIHByb3BlcnR5IGFzIHJlcXVpcmVkLCByZWFkb25seSwgYW5kIGFzIHRoZSBJRCBmaWVsZCBmb3IgZGF0YWJhc2Ugb3BlcmF0aW9uc1xuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIGlkXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHkgRGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gaWQoKSB7XG4gIHJldHVybiBhcHBseShcbiAgICByZXF1aXJlZCgpLFxuICAgIHJlYWRvbmx5KCksXG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KERCS2V5cy5JRCksIHt9KVxuICApO1xufVxuIiwiaW1wb3J0IHtcbiAgTW9kZWwsXG4gIE1vZGVsRXJyb3JEZWZpbml0aW9uLFxuICBNb2RlbEVycm9ycyxcbiAgTW9kZWxLZXlzLFxuICBSZXNlcnZlZE1vZGVscyxcbiAgc2YsXG4gIFZhbGlkYXRhYmxlLFxuICBWYWxpZGF0aW9uLFxuICBWYWxpZGF0aW9uS2V5cyxcbiAgVmFsaWRhdGlvblByb3BlcnR5RGVjb3JhdG9yRGVmaW5pdGlvbixcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgRGVjb3JhdG9yTWV0YWRhdGEsIFJlZmxlY3Rpb24gfSBmcm9tIFwiQGRlY2FmLXRzL3JlZmxlY3Rpb25cIjtcbmltcG9ydCB7IFVwZGF0ZVZhbGlkYXRpb25LZXlzLCBVcGRhdGVWYWxpZGF0b3IgfSBmcm9tIFwiLi4vdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgZmluZE1vZGVsSWQgfSBmcm9tIFwiLi4vaWRlbnRpdHlcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdGVzIGNoYW5nZXMgYmV0d2VlbiB0d28gbW9kZWwgdmVyc2lvbnNcbiAqIEBzdW1tYXJ5IENvbXBhcmVzIGFuIG9sZCBhbmQgbmV3IG1vZGVsIHZlcnNpb24gdG8gdmFsaWRhdGUgdXBkYXRlIG9wZXJhdGlvbnNcbiAqIEB0ZW1wbGF0ZSBNIC0gVHlwZSBleHRlbmRpbmcgTW9kZWxcbiAqIEBwYXJhbSB7TX0gb2xkTW9kZWwgLSBUaGUgb3JpZ2luYWwgbW9kZWwgdmVyc2lvblxuICogQHBhcmFtIHtNfSBuZXdNb2RlbCAtIFRoZSB1cGRhdGVkIG1vZGVsIHZlcnNpb25cbiAqIEBwYXJhbSB7Li4uc3RyaW5nW119IGV4Y2VwdGlvbnMgLSBQcm9wZXJ0aWVzIHRvIGV4Y2x1ZGUgZnJvbSB2YWxpZGF0aW9uXG4gKiBAcmV0dXJuIHtNb2RlbEVycm9yRGVmaW5pdGlvbnx1bmRlZmluZWR9IEVycm9yIGRlZmluaXRpb24gaWYgdmFsaWRhdGlvbiBmYWlscywgdW5kZWZpbmVkIG90aGVyd2lzZVxuICogQGZ1bmN0aW9uIHZhbGlkYXRlQ29tcGFyZVxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzXG4gKiBAbWVybWFpZFxuICogc2VxdWVuY2VEaWFncmFtXG4gKiAgIHBhcnRpY2lwYW50IENhbGxlclxuICogICBwYXJ0aWNpcGFudCB2YWxpZGF0ZUNvbXBhcmVcbiAqICAgcGFydGljaXBhbnQgUmVmbGVjdGlvblxuICogICBwYXJ0aWNpcGFudCBWYWxpZGF0aW9uXG4gKlxuICogICBDYWxsZXItPj52YWxpZGF0ZUNvbXBhcmU6IG9sZE1vZGVsLCBuZXdNb2RlbCwgZXhjZXB0aW9uc1xuICogICB2YWxpZGF0ZUNvbXBhcmUtPj5SZWZsZWN0aW9uOiBnZXQgZGVjb3JhdGVkIHByb3BlcnRpZXNcbiAqICAgUmVmbGVjdGlvbi0tPj52YWxpZGF0ZUNvbXBhcmU6IHByb3BlcnR5IGRlY29yYXRvcnNcbiAqICAgbG9vcCBGb3IgZWFjaCBkZWNvcmF0ZWQgcHJvcGVydHlcbiAqICAgICB2YWxpZGF0ZUNvbXBhcmUtPj5WYWxpZGF0aW9uOiBnZXQgdmFsaWRhdG9yXG4gKiAgICAgVmFsaWRhdGlvbi0tPj52YWxpZGF0ZUNvbXBhcmU6IHZhbGlkYXRvclxuICogICAgIHZhbGlkYXRlQ29tcGFyZS0+PnZhbGlkYXRlQ29tcGFyZTogdmFsaWRhdGUgcHJvcGVydHkgdXBkYXRlXG4gKiAgIGVuZFxuICogICBsb29wIEZvciBuZXN0ZWQgbW9kZWxzXG4gKiAgICAgdmFsaWRhdGVDb21wYXJlLT4+dmFsaWRhdGVDb21wYXJlOiB2YWxpZGF0ZSBuZXN0ZWQgbW9kZWxzXG4gKiAgIGVuZFxuICogICB2YWxpZGF0ZUNvbXBhcmUtLT4+Q2FsbGVyOiB2YWxpZGF0aW9uIGVycm9ycyBvciB1bmRlZmluZWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZhbGlkYXRlQ29tcGFyZTxNIGV4dGVuZHMgTW9kZWw+KFxuICBvbGRNb2RlbDogTSxcbiAgbmV3TW9kZWw6IE0sXG4gIC4uLmV4Y2VwdGlvbnM6IHN0cmluZ1tdXG4pOiBNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCB7XG4gIGNvbnN0IGRlY29yYXRlZFByb3BlcnRpZXM6IFZhbGlkYXRpb25Qcm9wZXJ0eURlY29yYXRvckRlZmluaXRpb25bXSA9IFtdO1xuICBmb3IgKGNvbnN0IHByb3AgaW4gbmV3TW9kZWwpXG4gICAgaWYgKFxuICAgICAgT2JqZWN0LnByb3RvdHlwZS5oYXNPd25Qcm9wZXJ0eS5jYWxsKG5ld01vZGVsLCBwcm9wKSAmJlxuICAgICAgZXhjZXB0aW9ucy5pbmRleE9mKHByb3ApID09PSAtMVxuICAgIClcbiAgICAgIGRlY29yYXRlZFByb3BlcnRpZXMucHVzaChcbiAgICAgICAgUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICAgICAgVXBkYXRlVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgICAgICBuZXdNb2RlbCxcbiAgICAgICAgICBwcm9wXG4gICAgICAgICkgYXMgdW5rbm93biBhcyBWYWxpZGF0aW9uUHJvcGVydHlEZWNvcmF0b3JEZWZpbml0aW9uXG4gICAgICApO1xuXG4gIGxldCByZXN1bHQ6IE1vZGVsRXJyb3JzIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gIGZvciAoY29uc3QgZGVjb3JhdGVkUHJvcGVydHkgb2YgZGVjb3JhdGVkUHJvcGVydGllcykge1xuICAgIGNvbnN0IHsgcHJvcCwgZGVjb3JhdG9ycyB9ID0gZGVjb3JhdGVkUHJvcGVydHk7XG5cbiAgICBkZWNvcmF0b3JzLnNoaWZ0KCk7IC8vIHJlbW92ZSB0aGUgZGVzaWduOnR5cGUgZGVjb3JhdG9yLCBzaW5jZSB0aGUgdHlwZSB3aWxsIGFscmVhZHkgYmUgY2hlY2tlZFxuXG4gICAgaWYgKCFkZWNvcmF0b3JzIHx8ICFkZWNvcmF0b3JzLmxlbmd0aCkgY29udGludWU7XG4gICAgbGV0IGVycnM6IFJlY29yZDxzdHJpbmcsIHN0cmluZyB8IHVuZGVmaW5lZD4gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgICBmb3IgKGNvbnN0IGRlY29yYXRvciBvZiBkZWNvcmF0b3JzKSB7XG4gICAgICBjb25zdCB2YWxpZGF0b3I6IFVwZGF0ZVZhbGlkYXRvciA9IFZhbGlkYXRpb24uZ2V0KFxuICAgICAgICBkZWNvcmF0b3Iua2V5XG4gICAgICApIGFzIFVwZGF0ZVZhbGlkYXRvcjtcbiAgICAgIGlmICghdmFsaWRhdG9yKSB7XG4gICAgICAgIGNvbnNvbGUuZXJyb3IoXG4gICAgICAgICAgYENvdWxkIG5vdCBmaW5kIE1hdGNoaW5nIHZhbGlkYXRvciBmb3IgJHtkZWNvcmF0b3Iua2V5fSBmb3IgcHJvcGVydHkgJHtTdHJpbmcoZGVjb3JhdGVkUHJvcGVydHkucHJvcCl9YFxuICAgICAgICApO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgZXJyOiBzdHJpbmcgfCB1bmRlZmluZWQgPSB2YWxpZGF0b3IudXBkYXRlSGFzRXJyb3JzKFxuICAgICAgICAobmV3TW9kZWwgYXMgYW55KVtwcm9wLnRvU3RyaW5nKCldLFxuICAgICAgICAob2xkTW9kZWwgYXMgYW55KVtwcm9wLnRvU3RyaW5nKCldLFxuICAgICAgICAuLi5PYmplY3QudmFsdWVzKGRlY29yYXRvci5wcm9wcylcbiAgICAgICk7XG5cbiAgICAgIGlmIChlcnIpIHtcbiAgICAgICAgZXJycyA9IGVycnMgfHwge307XG4gICAgICAgIGVycnNbZGVjb3JhdG9yLmtleV0gPSBlcnI7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGVycnMpIHtcbiAgICAgIHJlc3VsdCA9IHJlc3VsdCB8fCB7fTtcbiAgICAgIHJlc3VsdFtkZWNvcmF0ZWRQcm9wZXJ0eS5wcm9wLnRvU3RyaW5nKCldID0gZXJycztcbiAgICB9XG4gIH1cbiAgLy8gdGVzdHMgbmVzdGVkIGNsYXNzZXNcbiAgZm9yIChjb25zdCBwcm9wIG9mIE9iamVjdC5rZXlzKG5ld01vZGVsKS5maWx0ZXIoKGspID0+IHtcbiAgICBpZiAoZXhjZXB0aW9ucy5pbmNsdWRlcyhrKSkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiAhcmVzdWx0IHx8ICFyZXN1bHRba107XG4gIH0pKSB7XG4gICAgbGV0IGVycjogc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgIC8vIGlmIGEgbmVzdGVkIE1vZGVsXG4gICAgY29uc3QgYWxsRGVjb3JhdG9ycyA9IFJlZmxlY3Rpb24uZ2V0UHJvcGVydHlEZWNvcmF0b3JzKFxuICAgICAgVmFsaWRhdGlvbktleXMuUkVGTEVDVCxcbiAgICAgIG5ld01vZGVsLFxuICAgICAgcHJvcFxuICAgICkuZGVjb3JhdG9ycztcbiAgICBjb25zdCBkZWNvcmF0b3JzID0gUmVmbGVjdGlvbi5nZXRQcm9wZXJ0eURlY29yYXRvcnMoXG4gICAgICBWYWxpZGF0aW9uS2V5cy5SRUZMRUNULFxuICAgICAgbmV3TW9kZWwsXG4gICAgICBwcm9wXG4gICAgKS5kZWNvcmF0b3JzLmZpbHRlcihcbiAgICAgIChkKSA9PiBbTW9kZWxLZXlzLlRZUEUsIFZhbGlkYXRpb25LZXlzLlRZUEVdLmluZGV4T2YoZC5rZXkgYXMgYW55KSAhPT0gLTFcbiAgICApO1xuICAgIGlmICghZGVjb3JhdG9ycyB8fCAhZGVjb3JhdG9ycy5sZW5ndGgpIGNvbnRpbnVlO1xuICAgIGNvbnN0IGRlYyA9IGRlY29yYXRvcnMucG9wKCkgYXMgRGVjb3JhdG9yTWV0YWRhdGE7XG4gICAgY29uc3QgY2xhenogPSBkZWMucHJvcHMubmFtZVxuICAgICAgPyBbZGVjLnByb3BzLm5hbWVdXG4gICAgICA6IEFycmF5LmlzQXJyYXkoZGVjLnByb3BzLmN1c3RvbVR5cGVzKVxuICAgICAgICA/IGRlYy5wcm9wcy5jdXN0b21UeXBlc1xuICAgICAgICA6IFtkZWMucHJvcHMuY3VzdG9tVHlwZXNdO1xuICAgIGNvbnN0IHJlc2VydmVkID0gT2JqZWN0LnZhbHVlcyhSZXNlcnZlZE1vZGVscykubWFwKCh2KSA9PlxuICAgICAgdi50b0xvd2VyQ2FzZSgpXG4gICAgKSBhcyBzdHJpbmdbXTtcblxuICAgIGZvciAoY29uc3QgYyBvZiBjbGF6eikge1xuICAgICAgaWYgKHJlc2VydmVkLmluZGV4T2YoYy50b0xvd2VyQ2FzZSgpKSA9PT0gLTEpIHtcbiAgICAgICAgc3dpdGNoIChjKSB7XG4gICAgICAgICAgY2FzZSBBcnJheS5uYW1lOlxuICAgICAgICAgIGNhc2UgU2V0Lm5hbWU6XG4gICAgICAgICAgICBpZiAoYWxsRGVjb3JhdG9ycy5sZW5ndGgpIHtcbiAgICAgICAgICAgICAgY29uc3QgbGlzdERlYyA9IGFsbERlY29yYXRvcnMuZmluZChcbiAgICAgICAgICAgICAgICAoZCkgPT4gZC5rZXkgPT09IFZhbGlkYXRpb25LZXlzLkxJU1RcbiAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgaWYgKGxpc3REZWMpIHtcbiAgICAgICAgICAgICAgICBsZXQgY3VycmVudExpc3QsIG9sZExpc3Q7XG5cbiAgICAgICAgICAgICAgICBzd2l0Y2ggKGMpIHtcbiAgICAgICAgICAgICAgICAgIGNhc2UgQXJyYXkubmFtZTpcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudExpc3QgPSAobmV3TW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF07XG4gICAgICAgICAgICAgICAgICAgIG9sZExpc3QgPSAob2xkTW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbcHJvcF07XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgY2FzZSBTZXQubmFtZTpcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudExpc3QgPSAobmV3TW9kZWwgYXMgUmVjb3JkPHN0cmluZywgYW55PilbXG4gICAgICAgICAgICAgICAgICAgICAgcHJvcFxuICAgICAgICAgICAgICAgICAgICBdLnZhbHVlcygpO1xuICAgICAgICAgICAgICAgICAgICBvbGRMaXN0ID0gKG9sZE1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdLnZhbHVlcygpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBhdHRyaWJ1dGUgdHlwZSAke2N9YCk7XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgZXJyID0gY3VycmVudExpc3RcbiAgICAgICAgICAgICAgICAgIC5tYXAoKHY6IFZhbGlkYXRhYmxlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGlkID0gZmluZE1vZGVsSWQodiBhcyBhbnksIHRydWUpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWlkKSByZXR1cm4gXCJGYWlsZWQgdG8gZmluZCBtb2RlbCBpZFwiO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBvbGRNb2RlbCA9IG9sZExpc3QuZmluZChcbiAgICAgICAgICAgICAgICAgICAgICAoZWw6IGFueSkgPT4gaWQgPT09IGZpbmRNb2RlbElkKGVsLCB0cnVlKVxuICAgICAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgICAgIGlmICghb2xkTW9kZWwpIHJldHVybjsgLy8gbm90aGluZyB0byBjb21wYXJlIHdpdGhcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHYuaGFzRXJyb3JzKG9sZE1vZGVsKTtcbiAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAuZmlsdGVyKChlOiBhbnkpID0+ICEhZSkgYXMgYW55O1xuXG4gICAgICAgICAgICAgICAgaWYgKCFlcnI/Lmxlbmd0aCkge1xuICAgICAgICAgICAgICAgICAgLy8gaWYgdGhlIHJlc3VsdCBpcyBhbiBlbXB0eSBsaXN0Li4uXG4gICAgICAgICAgICAgICAgICBlcnIgPSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIChuZXdNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXSAmJlxuICAgICAgICAgICAgICAgIChvbGRNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXVxuICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgZXJyID0gKG5ld01vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW3Byb3BdLmhhc0Vycm9ycyhcbiAgICAgICAgICAgICAgICAgIChvbGRNb2RlbCBhcyBSZWNvcmQ8c3RyaW5nLCBhbnk+KVtwcm9wXVxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgIC8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tdW51c2VkLXZhcnNcbiAgICAgICAgICAgIH0gY2F0Y2ggKGU6IGFueSkge1xuICAgICAgICAgICAgICBjb25zb2xlLndhcm4oc2YoXCJNb2RlbCBzaG91bGQgYmUgdmFsaWRhdGFibGUgYnV0IGl0cyBub3RcIikpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZXJyKSB7XG4gICAgICAgIHJlc3VsdCA9IHJlc3VsdCB8fCB7fTtcbiAgICAgICAgcmVzdWx0W3Byb3BdID0gZXJyIGFzIGFueTtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgcmV0dXJuIHJlc3VsdCA/IG5ldyBNb2RlbEVycm9yRGVmaW5pdGlvbihyZXN1bHQpIDogdW5kZWZpbmVkO1xufVxuIiwiaW1wb3J0IHsgREJLZXlzLCBEZWZhdWx0U2VwYXJhdG9yIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5pbXBvcnQgeyBhcHBseSB9IGZyb20gXCJAZGVjYWYtdHMvcmVmbGVjdGlvblwiO1xuaW1wb3J0IHtcbiAgSGFzaGluZyxcbiAgTW9kZWwsXG4gIHByb3BNZXRhZGF0YSxcbiAgdHlwZSxcbn0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgb25DcmVhdGUsIG9uQ3JlYXRlVXBkYXRlLCBvblVwZGF0ZSB9IGZyb20gXCIuLi9vcGVyYXRpb25zL2RlY29yYXRvcnNcIjtcbmltcG9ydCB7IElSZXBvc2l0b3J5IH0gZnJvbSBcIi4uL2ludGVyZmFjZXMvSVJlcG9zaXRvcnlcIjtcbmltcG9ydCB7IEludGVybmFsRXJyb3IgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9lcnJvcnNcIjtcbmltcG9ydCB7IFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yeS9SZXBvc2l0b3J5XCI7XG5pbXBvcnQgeyBDb250ZXh0IH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvQ29udGV4dFwiO1xuaW1wb3J0IHsgQ3J1ZE9wZXJhdGlvbnMsIE9wZXJhdGlvbktleXMgfSBmcm9tIFwiLi4vb3BlcmF0aW9uc1wiO1xuaW1wb3J0IHsgUmVwb3NpdG9yeUZsYWdzIH0gZnJvbSBcIi4uL3JlcG9zaXRvcnkvdHlwZXNcIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gSGFzaGVzIGEgcHJvcGVydHkgdmFsdWUgZHVyaW5nIGNyZWF0ZSBvciB1cGRhdGUgb3BlcmF0aW9uc1xuICogQHN1bW1hcnkgQ2FsbGJhY2sgZnVuY3Rpb24gdXNlZCBieSB0aGUgaGFzaCBkZWNvcmF0b3IgdG8gYXBwbHkgaGFzaGluZyB0byBhIHByb3BlcnR5IHZhbHVlXG4gKiBAdGVtcGxhdGUgTSAtIFR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAdGVtcGxhdGUgUiAtIFR5cGUgZXh0ZW5kaW5nIElSZXBvc2l0b3J5XG4gKiBAdGVtcGxhdGUgViAtIFR5cGUgZm9yIG1ldGFkYXRhXG4gKiBAdGVtcGxhdGUgRiAtIFR5cGUgZXh0ZW5kaW5nIFJlcG9zaXRvcnlGbGFnc1xuICogQHRlbXBsYXRlIEMgLSBUeXBlIGV4dGVuZGluZyBDb250ZXh0XG4gKiBAcGFyYW0ge0N9IGNvbnRleHQgLSBUaGUgb3BlcmF0aW9uIGNvbnRleHRcbiAqIEBwYXJhbSB7Vn0gZGF0YSAtIE1ldGFkYXRhIGZvciB0aGUgb3BlcmF0aW9uXG4gKiBAcGFyYW0ga2V5IC0gVGhlIHByb3BlcnR5IGtleSB0byBoYXNoXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGJlaW5nIHByb2Nlc3NlZFxuICogQHBhcmFtIHtNfSBbb2xkTW9kZWxdIC0gVGhlIHByZXZpb3VzIG1vZGVsIHN0YXRlIChmb3IgdXBkYXRlcylcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKiBAZnVuY3Rpb24gaGFzaE9uQ3JlYXRlVXBkYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc2hPbkNyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBvYmplY3QsXG4gIEYgZXh0ZW5kcyBSZXBvc2l0b3J5RmxhZ3MgPSBSZXBvc2l0b3J5RmxhZ3MsXG4gIEMgZXh0ZW5kcyBDb250ZXh0PEY+ID0gQ29udGV4dDxGPixcbj4odGhpczogUiwgY29udGV4dDogQywgZGF0YTogViwga2V5OiBrZXlvZiBNLCBtb2RlbDogTSwgb2xkTW9kZWw/OiBNKTogdm9pZCB7XG4gIGlmICh0eXBlb2YgbW9kZWxba2V5XSA9PT0gXCJ1bmRlZmluZWRcIikgcmV0dXJuO1xuICBjb25zdCBoYXNoID0gSGFzaGluZy5oYXNoKChtb2RlbCBhcyBhbnkpW2tleV0pO1xuICBpZiAob2xkTW9kZWwgJiYgKG1vZGVsIGFzIGFueSlba2V5XSA9PT0gaGFzaCkgcmV0dXJuO1xuICBtb2RlbFtrZXldID0gaGFzaDtcbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGRlY29yYXRvciB0aGF0IGhhc2hlcyBhIHByb3BlcnR5IHZhbHVlXG4gKiBAc3VtbWFyeSBEZWNvcmF0b3IgdGhhdCBhdXRvbWF0aWNhbGx5IGhhc2hlcyBhIHByb3BlcnR5IHZhbHVlIGR1cmluZyBjcmVhdGUgYW5kIHVwZGF0ZSBvcGVyYXRpb25zXG4gKiBAcmV0dXJuIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBkZWNvcmF0b3IgdGhhdCBjYW4gYmUgYXBwbGllZCB0byBjbGFzcyBwcm9wZXJ0aWVzXG4gKiBAZnVuY3Rpb24gaGFzaFxuICogQGNhdGVnb3J5IFByb3BlcnR5IERlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGhhc2goKSB7XG4gIHJldHVybiBhcHBseShcbiAgICBvbkNyZWF0ZVVwZGF0ZShoYXNoT25DcmVhdGVVcGRhdGUpLFxuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShEQktleXMuSEFTSCksIHt9KVxuICApO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBNZXRhZGF0YSBmb3IgY29tcG9zZWQgcHJvcGVydHkgZGVjb3JhdG9yc1xuICogQHN1bW1hcnkgQ29uZmlndXJhdGlvbiBvcHRpb25zIGZvciBwcm9wZXJ0eSBjb21wb3NpdGlvbiBmcm9tIG90aGVyIHByb3BlcnRpZXNcbiAqIEB0eXBlZGVmIHtPYmplY3R9IENvbXBvc2VkRnJvbU1ldGFkYXRhXG4gKiBAcHJvcGVydHkge3N0cmluZ1tdfSBhcmdzIC0gUHJvcGVydHkgbmFtZXMgdG8gY29tcG9zZSBmcm9tXG4gKiBAcHJvcGVydHkge3N0cmluZ30gc2VwYXJhdG9yIC0gQ2hhcmFjdGVyIHVzZWQgdG8gam9pbiB0aGUgY29tcG9zZWQgdmFsdWVzXG4gKiBAcHJvcGVydHkge2Jvb2xlYW59IGhhc2hSZXN1bHQgLSBXaGV0aGVyIHRvIGhhc2ggdGhlIGNvbXBvc2VkIHJlc3VsdFxuICogQHByb3BlcnR5IHtcImtleXNcInxcInZhbHVlc1wifSB0eXBlIC0gV2hldGhlciB0byB1c2UgcHJvcGVydHkga2V5cyBvciB2YWx1ZXNcbiAqIEBwcm9wZXJ0eSB7c3RyaW5nfSBbcHJlZml4XSAtIE9wdGlvbmFsIHByZWZpeCB0byBhZGQgdG8gdGhlIGNvbXBvc2VkIHZhbHVlXG4gKiBAcHJvcGVydHkge3N0cmluZ30gW3N1ZmZpeF0gLSBPcHRpb25hbCBzdWZmaXggdG8gYWRkIHRvIHRoZSBjb21wb3NlZCB2YWx1ZVxuICogQG1lbWJlck9mIG1vZHVsZTpkYi1kZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCB0eXBlIENvbXBvc2VkRnJvbU1ldGFkYXRhID0ge1xuICBhcmdzOiBzdHJpbmdbXTtcbiAgc2VwYXJhdG9yOiBzdHJpbmc7XG4gIGhhc2hSZXN1bHQ6IGJvb2xlYW47XG4gIHR5cGU6IFwia2V5c1wiIHwgXCJ2YWx1ZXNcIjtcbiAgcHJlZml4Pzogc3RyaW5nO1xuICBzdWZmaXg/OiBzdHJpbmc7XG59O1xuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDb21wb3NlcyBhIHByb3BlcnR5IHZhbHVlIGZyb20gb3RoZXIgcHJvcGVydGllcyBkdXJpbmcgY3JlYXRlIG9yIHVwZGF0ZSBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBDYWxsYmFjayBmdW5jdGlvbiB1c2VkIGJ5IGNvbXBvc2VkIGRlY29yYXRvcnMgdG8gZ2VuZXJhdGUgYSBwcm9wZXJ0eSB2YWx1ZSBmcm9tIG90aGVyIHByb3BlcnRpZXNcbiAqIEB0ZW1wbGF0ZSBNIC0gVHlwZSBleHRlbmRpbmcgTW9kZWxcbiAqIEB0ZW1wbGF0ZSBSIC0gVHlwZSBleHRlbmRpbmcgSVJlcG9zaXRvcnlcbiAqIEB0ZW1wbGF0ZSBWIC0gVHlwZSBleHRlbmRpbmcgQ29tcG9zZWRGcm9tTWV0YWRhdGFcbiAqIEB0ZW1wbGF0ZSBGIC0gVHlwZSBleHRlbmRpbmcgUmVwb3NpdG9yeUZsYWdzXG4gKiBAdGVtcGxhdGUgQyAtIFR5cGUgZXh0ZW5kaW5nIENvbnRleHRcbiAqIEBwYXJhbSB7Q30gY29udGV4dCAtIFRoZSBvcGVyYXRpb24gY29udGV4dFxuICogQHBhcmFtIHtWfSBkYXRhIC0gTWV0YWRhdGEgZm9yIHRoZSBjb21wb3NpdGlvblxuICogQHBhcmFtIGtleSAtIFRoZSBwcm9wZXJ0eSBrZXkgdG8gc2V0IHRoZSBjb21wb3NlZCB2YWx1ZSBvblxuICogQHBhcmFtIHtNfSBtb2RlbCAtIFRoZSBtb2RlbCBiZWluZyBwcm9jZXNzZWRcbiAqIEByZXR1cm4ge3ZvaWR9XG4gKiBAZnVuY3Rpb24gY29tcG9zZWRGcm9tQ3JlYXRlVXBkYXRlXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvc2VkRnJvbUNyZWF0ZVVwZGF0ZTxcbiAgTSBleHRlbmRzIE1vZGVsLFxuICBSIGV4dGVuZHMgSVJlcG9zaXRvcnk8TSwgRiwgQz4sXG4gIFYgZXh0ZW5kcyBDb21wb3NlZEZyb21NZXRhZGF0YSxcbiAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgQyBleHRlbmRzIENvbnRleHQ8Rj4gPSBDb250ZXh0PEY+LFxuPih0aGlzOiBSLCBjb250ZXh0OiBDLCBkYXRhOiBWLCBrZXk6IGtleW9mIE0sIG1vZGVsOiBNKSB7XG4gIHRyeSB7XG4gICAgY29uc3QgeyBhcmdzLCB0eXBlLCBwcmVmaXgsIHN1ZmZpeCwgc2VwYXJhdG9yIH0gPSBkYXRhO1xuICAgIGNvbnN0IGNvbXBvc2VkID0gYXJncy5tYXAoKGFyZzogc3RyaW5nKSA9PiB7XG4gICAgICBpZiAoIShhcmcgaW4gbW9kZWwpKVxuICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgUHJvcGVydHkgJHthcmd9IG5vdCBmb3VuZCB0byBjb21wb3NlIGZyb21gKTtcbiAgICAgIGlmICh0eXBlID09PSBcImtleXNcIikgcmV0dXJuIGFyZztcbiAgICAgIGlmICh0eXBlb2YgKG1vZGVsIGFzIGFueSlbYXJnXSA9PT0gXCJ1bmRlZmluZWRcIilcbiAgICAgICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoXG4gICAgICAgICAgYFByb3BlcnR5ICR7YXJnc30gZG9lcyBub3QgY29udGFpbiBhIHZhbHVlIHRvIGNvbXBvc2UgZnJvbWBcbiAgICAgICAgKTtcbiAgICAgIHJldHVybiAoKG1vZGVsIGFzIGFueSlbYXJnXSBhcyBhbnkpLnRvU3RyaW5nKCk7XG4gICAgfSk7XG5cbiAgICBpZiAocHJlZml4KSBjb21wb3NlZC51bnNoaWZ0KHByZWZpeCk7XG4gICAgaWYgKHN1ZmZpeCkgY29tcG9zZWQucHVzaChzdWZmaXgpO1xuXG4gICAgKG1vZGVsIGFzIGFueSlba2V5XSA9IGNvbXBvc2VkLmpvaW4oc2VwYXJhdG9yKTtcbiAgfSBjYXRjaCAoZTogYW55KSB7XG4gICAgdGhyb3cgbmV3IEludGVybmFsRXJyb3IoYEZhaWxlZCB0byBjb21wb3NlIHZhbHVlOiAke2V9YCk7XG4gIH1cbn1cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3JlYXRlcyBhIGRlY29yYXRvciB0aGF0IGNvbXBvc2VzIGEgcHJvcGVydHkgdmFsdWUgZnJvbSBvdGhlciBwcm9wZXJ0aWVzXG4gKiBAc3VtbWFyeSBCYXNlIGZ1bmN0aW9uIGZvciBjcmVhdGluZyBwcm9wZXJ0eSBjb21wb3NpdGlvbiBkZWNvcmF0b3JzXG4gKiBAcGFyYW0ge3N0cmluZ1tdfSBhcmdzIC0gUHJvcGVydHkgbmFtZXMgdG8gY29tcG9zZSBmcm9tXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtoYXNoUmVzdWx0PWZhbHNlXSAtIFdoZXRoZXIgdG8gaGFzaCB0aGUgY29tcG9zZWQgcmVzdWx0XG4gKiBAcGFyYW0ge3N0cmluZ30gW3NlcGFyYXRvcj1EZWZhdWx0U2VwYXJhdG9yXSAtIENoYXJhY3RlciB1c2VkIHRvIGpvaW4gdGhlIGNvbXBvc2VkIHZhbHVlc1xuICogQHBhcmFtIHtcImtleXNcInxcInZhbHVlc1wifSBbdHlwZT1cInZhbHVlc1wiXSAtIFdoZXRoZXIgdG8gdXNlIHByb3BlcnR5IGtleXMgb3IgdmFsdWVzXG4gKiBAcGFyYW0ge3N0cmluZ30gW3ByZWZpeD1cIlwiXSAtIE9wdGlvbmFsIHByZWZpeCB0byBhZGQgdG8gdGhlIGNvbXBvc2VkIHZhbHVlXG4gKiBAcGFyYW0ge3N0cmluZ30gW3N1ZmZpeD1cIlwiXSAtIE9wdGlvbmFsIHN1ZmZpeCB0byBhZGQgdG8gdGhlIGNvbXBvc2VkIHZhbHVlXG4gKiBAcmV0dXJuIHtQcm9wZXJ0eURlY29yYXRvcn0gQSBkZWNvcmF0b3IgdGhhdCBjYW4gYmUgYXBwbGllZCB0byBjbGFzcyBwcm9wZXJ0aWVzXG4gKiBAZnVuY3Rpb24gY29tcG9zZWRGcm9tXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHlEZWNvcmF0b3JzXG4gKi9cbmZ1bmN0aW9uIGNvbXBvc2VkRnJvbShcbiAgYXJnczogc3RyaW5nW10sXG4gIGhhc2hSZXN1bHQ6IGJvb2xlYW4gPSBmYWxzZSxcbiAgc2VwYXJhdG9yOiBzdHJpbmcgPSBEZWZhdWx0U2VwYXJhdG9yLFxuICB0eXBlOiBcImtleXNcIiB8IFwidmFsdWVzXCIgPSBcInZhbHVlc1wiLFxuICBwcmVmaXggPSBcIlwiLFxuICBzdWZmaXggPSBcIlwiXG4pIHtcbiAgY29uc3QgZGF0YTogQ29tcG9zZWRGcm9tTWV0YWRhdGEgPSB7XG4gICAgYXJnczogYXJncyxcbiAgICBoYXNoUmVzdWx0OiBoYXNoUmVzdWx0LFxuICAgIHNlcGFyYXRvcjogc2VwYXJhdG9yLFxuICAgIHR5cGU6IHR5cGUsXG4gICAgcHJlZml4OiBwcmVmaXgsXG4gICAgc3VmZml4OiBzdWZmaXgsXG4gIH07XG5cbiAgY29uc3QgZGVjb3JhdG9ycyA9IFtcbiAgICBvbkNyZWF0ZVVwZGF0ZShjb21wb3NlZEZyb21DcmVhdGVVcGRhdGUsIGRhdGEpLFxuICAgIHByb3BNZXRhZGF0YShSZXBvc2l0b3J5LmtleShEQktleXMuQ09NUE9TRUQpLCBkYXRhKSxcbiAgXTtcbiAgaWYgKGhhc2hSZXN1bHQpIGRlY29yYXRvcnMucHVzaChoYXNoKCkpO1xuICByZXR1cm4gYXBwbHkoLi4uZGVjb3JhdG9ycyk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBkZWNvcmF0b3IgdGhhdCBjb21wb3NlcyBhIHByb3BlcnR5IHZhbHVlIGZyb20gcHJvcGVydHkga2V5c1xuICogQHN1bW1hcnkgRGVjb3JhdG9yIHRoYXQgZ2VuZXJhdGVzIGEgcHJvcGVydHkgdmFsdWUgYnkgam9pbmluZyB0aGUgbmFtZXMgb2Ygb3RoZXIgcHJvcGVydGllc1xuICogQHBhcmFtIHtzdHJpbmdbXX0gYXJncyAtIFByb3BlcnR5IG5hbWVzIHRvIGNvbXBvc2UgZnJvbVxuICogQHBhcmFtIHtzdHJpbmd9IFtzZXBhcmF0b3I9RGVmYXVsdFNlcGFyYXRvcl0gLSBDaGFyYWN0ZXIgdXNlZCB0byBqb2luIHRoZSBwcm9wZXJ0eSBuYW1lc1xuICogQHBhcmFtIHtib29sZWFufSBbaGFzaD1mYWxzZV0gLSBXaGV0aGVyIHRvIGhhc2ggdGhlIGNvbXBvc2VkIHJlc3VsdFxuICogQHBhcmFtIHtzdHJpbmd9IFtwcmVmaXg9XCJcIl0gLSBPcHRpb25hbCBwcmVmaXggdG8gYWRkIHRvIHRoZSBjb21wb3NlZCB2YWx1ZVxuICogQHBhcmFtIHtzdHJpbmd9IFtzdWZmaXg9XCJcIl0gLSBPcHRpb25hbCBzdWZmaXggdG8gYWRkIHRvIHRoZSBjb21wb3NlZCB2YWx1ZVxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIGNvbXBvc2VkRnJvbUtleXNcbiAqIEBjYXRlZ29yeSBQcm9wZXJ0eURlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbXBvc2VkRnJvbUtleXMoXG4gIGFyZ3M6IHN0cmluZ1tdLFxuICBzZXBhcmF0b3I6IHN0cmluZyA9IERlZmF1bHRTZXBhcmF0b3IsXG4gIGhhc2g6IGJvb2xlYW4gPSBmYWxzZSxcbiAgcHJlZml4ID0gXCJcIixcbiAgc3VmZml4ID0gXCJcIlxuKSB7XG4gIHJldHVybiBjb21wb3NlZEZyb20oYXJncywgaGFzaCwgc2VwYXJhdG9yLCBcImtleXNcIiwgcHJlZml4LCBzdWZmaXgpO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgY29tcG9zZXMgYSBwcm9wZXJ0eSB2YWx1ZSBmcm9tIHByb3BlcnR5IHZhbHVlc1xuICogQHN1bW1hcnkgRGVjb3JhdG9yIHRoYXQgZ2VuZXJhdGVzIGEgcHJvcGVydHkgdmFsdWUgYnkgam9pbmluZyB0aGUgdmFsdWVzIG9mIG90aGVyIHByb3BlcnRpZXNcbiAqIEBwYXJhbSB7c3RyaW5nW119IGFyZ3MgLSBQcm9wZXJ0eSBuYW1lcyB3aG9zZSB2YWx1ZXMgd2lsbCBiZSBjb21wb3NlZFxuICogQHBhcmFtIHtzdHJpbmd9IFtzZXBhcmF0b3I9RGVmYXVsdFNlcGFyYXRvcl0gLSBDaGFyYWN0ZXIgdXNlZCB0byBqb2luIHRoZSBwcm9wZXJ0eSB2YWx1ZXNcbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2hhc2g9ZmFsc2VdIC0gV2hldGhlciB0byBoYXNoIHRoZSBjb21wb3NlZCByZXN1bHRcbiAqIEBwYXJhbSB7c3RyaW5nfSBbcHJlZml4PVwiXCJdIC0gT3B0aW9uYWwgcHJlZml4IHRvIGFkZCB0byB0aGUgY29tcG9zZWQgdmFsdWVcbiAqIEBwYXJhbSB7c3RyaW5nfSBbc3VmZml4PVwiXCJdIC0gT3B0aW9uYWwgc3VmZml4IHRvIGFkZCB0byB0aGUgY29tcG9zZWQgdmFsdWVcbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGRlY29yYXRvciB0aGF0IGNhbiBiZSBhcHBsaWVkIHRvIGNsYXNzIHByb3BlcnRpZXNcbiAqIEBmdW5jdGlvbiBjb21wb3NlZFxuICogQGNhdGVnb3J5IFByb3BlcnR5RGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gY29tcG9zZWQoXG4gIGFyZ3M6IHN0cmluZ1tdLFxuICBzZXBhcmF0b3I6IHN0cmluZyA9IERlZmF1bHRTZXBhcmF0b3IsXG4gIGhhc2g6IGJvb2xlYW4gPSBmYWxzZSxcbiAgcHJlZml4ID0gXCJcIixcbiAgc3VmZml4ID0gXCJcIlxuKSB7XG4gIHJldHVybiBjb21wb3NlZEZyb20oYXJncywgaGFzaCwgc2VwYXJhdG9yLCBcInZhbHVlc1wiLCBwcmVmaXgsIHN1ZmZpeCk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBmdW5jdGlvbiB0aGF0IHVwZGF0ZXMgYSB2ZXJzaW9uIHByb3BlcnR5IGR1cmluZyBvcGVyYXRpb25zXG4gKiBAc3VtbWFyeSBGYWN0b3J5IGZ1bmN0aW9uIHRoYXQgZ2VuZXJhdGVzIGEgY2FsbGJhY2sgZm9yIGluY3JlbWVudGluZyB2ZXJzaW9uIG51bWJlcnNcbiAqIEBwYXJhbSB7Q3J1ZE9wZXJhdGlvbnN9IG9wZXJhdGlvbiAtIFRoZSB0eXBlIG9mIG9wZXJhdGlvbiAoQ1JFQVRFIG9yIFVQREFURSlcbiAqIEByZXR1cm4ge0Z1bmN0aW9ufSBBIGNhbGxiYWNrIGZ1bmN0aW9uIHRoYXQgdXBkYXRlcyB0aGUgdmVyc2lvbiBwcm9wZXJ0eVxuICogQHRlbXBsYXRlIE0gLSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHRlbXBsYXRlIFIgLSBUeXBlIGV4dGVuZGluZyBJUmVwb3NpdG9yeVxuICogQHRlbXBsYXRlIFYgLSBUeXBlIGZvciBtZXRhZGF0YVxuICogQHRlbXBsYXRlIEYgLSBUeXBlIGV4dGVuZGluZyBSZXBvc2l0b3J5RmxhZ3NcbiAqIEB0ZW1wbGF0ZSBDIC0gVHlwZSBleHRlbmRpbmcgQ29udGV4dFxuICogQGZ1bmN0aW9uIHZlcnNpb25DcmVhdGVVcGRhdGVcbiAqIEBtZW1iZXJPZiBtb2R1bGU6ZGItZGVjb3JhdG9yc1xuICogQG1lcm1haWRcbiAqIHNlcXVlbmNlRGlhZ3JhbVxuICogICBwYXJ0aWNpcGFudCBDYWxsZXJcbiAqICAgcGFydGljaXBhbnQgdmVyc2lvbkNyZWF0ZVVwZGF0ZVxuICpcbiAqICAgQ2FsbGVyLT4+dmVyc2lvbkNyZWF0ZVVwZGF0ZTogb3BlcmF0aW9uXG4gKiAgIHZlcnNpb25DcmVhdGVVcGRhdGUtLT4+Q2FsbGVyOiBjYWxsYmFjayBmdW5jdGlvblxuICogICBOb3RlIG92ZXIgQ2FsbGVyLHZlcnNpb25DcmVhdGVVcGRhdGU6IFdoZW4gY2FsbGJhY2sgaXMgZXhlY3V0ZWQ6XG4gKiAgIENhbGxlci0+PnZlcnNpb25DcmVhdGVVcGRhdGU6IGNvbnRleHQsIGRhdGEsIGtleSwgbW9kZWxcbiAqICAgYWx0IG9wZXJhdGlvbiBpcyBDUkVBVEVcbiAqICAgICB2ZXJzaW9uQ3JlYXRlVXBkYXRlLT4+dmVyc2lvbkNyZWF0ZVVwZGF0ZTogc2V0IHZlcnNpb24gdG8gMVxuICogICBlbHNlIG9wZXJhdGlvbiBpcyBVUERBVEVcbiAqICAgICB2ZXJzaW9uQ3JlYXRlVXBkYXRlLT4+dmVyc2lvbkNyZWF0ZVVwZGF0ZTogaW5jcmVtZW50IHZlcnNpb25cbiAqICAgZWxzZSBpbnZhbGlkIG9wZXJhdGlvblxuICogICAgIHZlcnNpb25DcmVhdGVVcGRhdGUtPj52ZXJzaW9uQ3JlYXRlVXBkYXRlOiB0aHJvdyBlcnJvclxuICogICBlbmRcbiAqICAgdmVyc2lvbkNyZWF0ZVVwZGF0ZS0tPj5DYWxsZXI6IHZvaWRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHZlcnNpb25DcmVhdGVVcGRhdGUob3BlcmF0aW9uOiBDcnVkT3BlcmF0aW9ucykge1xuICByZXR1cm4gZnVuY3Rpb24gdmVyc2lvbkNyZWF0ZVVwZGF0ZTxcbiAgICBNIGV4dGVuZHMgTW9kZWwsXG4gICAgUiBleHRlbmRzIElSZXBvc2l0b3J5PE0sIEYsIEM+LFxuICAgIFYgZXh0ZW5kcyBvYmplY3QsXG4gICAgRiBleHRlbmRzIFJlcG9zaXRvcnlGbGFncyA9IFJlcG9zaXRvcnlGbGFncyxcbiAgICBDIGV4dGVuZHMgQ29udGV4dDxGPiA9IENvbnRleHQ8Rj4sXG4gID4odGhpczogUiwgY29udGV4dDogQywgZGF0YTogViwga2V5OiBrZXlvZiBNLCBtb2RlbDogTSkge1xuICAgIHRyeSB7XG4gICAgICBzd2l0Y2ggKG9wZXJhdGlvbikge1xuICAgICAgICBjYXNlIE9wZXJhdGlvbktleXMuQ1JFQVRFOlxuICAgICAgICAgIChtb2RlbCBhcyBhbnkpW2tleV0gPSAxO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIE9wZXJhdGlvbktleXMuVVBEQVRFOlxuICAgICAgICAgIChtb2RlbCBhcyBhbnkpW2tleV0rKztcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICB0aHJvdyBuZXcgSW50ZXJuYWxFcnJvcihgSW52YWxpZCBvcGVyYXRpb246ICR7b3BlcmF0aW9ufWApO1xuICAgICAgfVxuICAgIH0gY2F0Y2ggKGU6IHVua25vd24pIHtcbiAgICAgIHRocm93IG5ldyBJbnRlcm5hbEVycm9yKGBGYWlsZWQgdG8gdXBkYXRlIHZlcnNpb246ICR7ZX1gKTtcbiAgICB9XG4gIH07XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENyZWF0ZXMgYSBkZWNvcmF0b3IgZm9yIHZlcnNpb25pbmcgYSBwcm9wZXJ0eSBpbiBhIG1vZGVsXG4gKiBAc3VtbWFyeSBUaGlzIGRlY29yYXRvciBhcHBsaWVzIG11bHRpcGxlIHN1Yi1kZWNvcmF0b3JzIHRvIGhhbmRsZSB2ZXJzaW9uIG1hbmFnZW1lbnQgZHVyaW5nIGNyZWF0ZSBhbmQgdXBkYXRlIG9wZXJhdGlvbnNcbiAqIEByZXR1cm4ge1Byb3BlcnR5RGVjb3JhdG9yfSBBIGNvbXBvc2l0ZSBkZWNvcmF0b3IgdGhhdCBzZXRzIHRoZSB0eXBlIHRvIE51bWJlciwgbWFuYWdlcyB2ZXJzaW9uIHVwZGF0ZXMsIGFuZCBhZGRzIHZlcnNpb25pbmcgbWV0YWRhdGFcbiAqIEBmdW5jdGlvbiB2ZXJzaW9uXG4gKiBAY2F0ZWdvcnkgUHJvcGVydHlEZWNvcmF0b3JzXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiB2ZXJzaW9uKCkge1xuICByZXR1cm4gYXBwbHkoXG4gICAgdHlwZShOdW1iZXIubmFtZSksXG4gICAgb25DcmVhdGUodmVyc2lvbkNyZWF0ZVVwZGF0ZShPcGVyYXRpb25LZXlzLkNSRUFURSkpLFxuICAgIG9uVXBkYXRlKHZlcnNpb25DcmVhdGVVcGRhdGUoT3BlcmF0aW9uS2V5cy5VUERBVEUpKSxcbiAgICBwcm9wTWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLlZFUlNJT04pLCB0cnVlKVxuICApO1xufVxuXG4vKipcbiAqIEBkZXNjcmlwdGlvbiBDcmVhdGVzIGEgZGVjb3JhdG9yIHRoYXQgbWFya3MgYSBwcm9wZXJ0eSBhcyB0cmFuc2llbnRcbiAqIEBzdW1tYXJ5IERlY29yYXRvciB0aGF0IGluZGljYXRlcyBhIHByb3BlcnR5IHNob3VsZCBub3QgYmUgcGVyc2lzdGVkIHRvIHRoZSBkYXRhYmFzZVxuICogQHJldHVybiB7UHJvcGVydHlEZWNvcmF0b3J9IEEgZGVjb3JhdG9yIHRoYXQgY2FuIGJlIGFwcGxpZWQgdG8gY2xhc3MgcHJvcGVydGllc1xuICogQGZ1bmN0aW9uIHRyYW5zaWVudFxuICogQGNhdGVnb3J5IFByb3BlcnR5RGVjb3JhdG9yc1xuICovXG5leHBvcnQgZnVuY3Rpb24gdHJhbnNpZW50KCkge1xuICByZXR1cm4gZnVuY3Rpb24gdHJhbnNpZW50KG1vZGVsOiBhbnksIGF0dHJpYnV0ZTogc3RyaW5nKSB7XG4gICAgcHJvcE1ldGFkYXRhKFJlcG9zaXRvcnkua2V5KERCS2V5cy5UUkFOU0lFTlQpLCB0cnVlKShtb2RlbCwgYXR0cmlidXRlKTtcbiAgICBwcm9wTWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLlRSQU5TSUVOVCksIHRydWUpKG1vZGVsLmNvbnN0cnVjdG9yKTtcbiAgfTtcbn1cbiIsImltcG9ydCB7XG4gIE1vZGVsLFxuICBNb2RlbEVycm9yRGVmaW5pdGlvbixcbiAgdmFsaWRhdGUsXG59IGZyb20gXCJAZGVjYWYtdHMvZGVjb3JhdG9yLXZhbGlkYXRpb25cIjtcblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gVmFsaWRhdGVzIHRoZSBtb2RlbCBhbmQgY2hlY2tzIGZvciBlcnJvcnNcbiAqIEBzdW1tYXJ5IFZhbGlkYXRlcyB0aGUgY3VycmVudCBtb2RlbCBzdGF0ZSBhbmQgb3B0aW9uYWxseSBjb21wYXJlcyB3aXRoIGEgcHJldmlvdXMgdmVyc2lvblxuICogQHRlbXBsYXRlIE0gLSBUeXBlIGV4dGVuZGluZyBNb2RlbFxuICogQHBhcmFtIHtNfGFueX0gW3ByZXZpb3VzVmVyc2lvbl0gLSBPcHRpb25hbCBwcmV2aW91cyB2ZXJzaW9uIG9mIHRoZSBtb2RlbCBmb3IgY29tcGFyaXNvblxuICogQHBhcmFtIHsuLi5hbnlbXX0gZXhjbHVzaW9ucyAtIFByb3BlcnRpZXMgdG8gZXhjbHVkZSBmcm9tIHZhbGlkYXRpb25cbiAqIEByZXR1cm4ge01vZGVsRXJyb3JEZWZpbml0aW9ufHVuZGVmaW5lZH0gRXJyb3IgZGVmaW5pdGlvbiBpZiB2YWxpZGF0aW9uIGZhaWxzLCB1bmRlZmluZWQgb3RoZXJ3aXNlXG4gKiBAZnVuY3Rpb24gaGFzRXJyb3JzXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqL1xuaW1wb3J0IHsgdmFsaWRhdGVDb21wYXJlIH0gZnJvbSBcIi4vdmFsaWRhdGlvblwiO1xuXG5Nb2RlbC5wcm90b3R5cGUuaGFzRXJyb3JzID0gZnVuY3Rpb24gPE0gZXh0ZW5kcyBNb2RlbD4oXG4gIHRoaXM6IE0sXG4gIHByZXZpb3VzVmVyc2lvbj86IE0gfCBhbnksXG4gIC4uLmV4Y2x1c2lvbnM6IGFueVtdXG4pOiBNb2RlbEVycm9yRGVmaW5pdGlvbiB8IHVuZGVmaW5lZCB7XG4gIGlmIChwcmV2aW91c1ZlcnNpb24gJiYgIShwcmV2aW91c1ZlcnNpb24gaW5zdGFuY2VvZiBNb2RlbCkpIHtcbiAgICBleGNsdXNpb25zLnVuc2hpZnQocHJldmlvdXNWZXJzaW9uKTtcbiAgICBwcmV2aW91c1ZlcnNpb24gPSB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCBlcnJzID0gdmFsaWRhdGUodGhpcywgLi4uZXhjbHVzaW9ucyk7XG4gIGlmIChlcnJzIHx8ICFwcmV2aW91c1ZlcnNpb24pIHJldHVybiBlcnJzO1xuXG4gIHJldHVybiB2YWxpZGF0ZUNvbXBhcmUocHJldmlvdXNWZXJzaW9uLCB0aGlzLCAuLi5leGNsdXNpb25zKTtcbn07XG4iLCJpbXBvcnQge1xuICBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUsXG4gIFJlcG9zaXRvcnksXG4gIFNlcmlhbGl6YXRpb25FcnJvcixcbn0gZnJvbSBcIi4uL3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IE1vZGVsIH0gZnJvbSBcIkBkZWNhZi10cy9kZWNvcmF0b3ItdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgREJLZXlzIH0gZnJvbSBcIi4vY29uc3RhbnRzXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIENoZWNrcyBpZiBhIG1vZGVsIGlzIG1hcmtlZCBhcyB0cmFuc2llbnRcbiAqIEBzdW1tYXJ5IERldGVybWluZXMgd2hldGhlciBhIG1vZGVsIGNsYXNzIGhhcyBiZWVuIGRlY29yYXRlZCB3aXRoIHRoZSB0cmFuc2llbnQgZGVjb3JhdG9yXG4gKiBAdGVtcGxhdGUgTSAtIFR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIGNoZWNrXG4gKiBAcmV0dXJuIHtib29sZWFufSBUcnVlIGlmIHRoZSBtb2RlbCBpcyB0cmFuc2llbnQsIGZhbHNlIG90aGVyd2lzZVxuICogQGZ1bmN0aW9uIGlzVHJhbnNpZW50XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGlzVHJhbnNpZW50PE0gZXh0ZW5kcyBNb2RlbD4obW9kZWw6IE0pIHtcbiAgcmV0dXJuICEhKFxuICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoUmVwb3NpdG9yeS5rZXkoREJLZXlzLlRSQU5TSUVOVCksIG1vZGVsLmNvbnN0cnVjdG9yKSB8fFxuICAgIFJlZmxlY3QuZ2V0TWV0YWRhdGEoXG4gICAgICBSZXBvc2l0b3J5LmtleShEQktleXMuVFJBTlNJRU5UKSxcbiAgICAgIE1vZGVsLmdldChtb2RlbC5jb25zdHJ1Y3Rvci5uYW1lKSBhcyBhbnlcbiAgICApXG4gICk7XG59XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIFNlcGFyYXRlcyB0cmFuc2llbnQgcHJvcGVydGllcyBmcm9tIGEgbW9kZWxcbiAqIEBzdW1tYXJ5IEV4dHJhY3RzIHByb3BlcnRpZXMgbWFya2VkIGFzIHRyYW5zaWVudCBpbnRvIGEgc2VwYXJhdGUgb2JqZWN0XG4gKiBAdGVtcGxhdGUgTSAtIFR5cGUgZXh0ZW5kaW5nIE1vZGVsXG4gKiBAcGFyYW0ge019IG1vZGVsIC0gVGhlIG1vZGVsIGluc3RhbmNlIHRvIHByb2Nlc3NcbiAqIEByZXR1cm4ge09iamVjdH0gT2JqZWN0IGNvbnRhaW5pbmcgdGhlIG1vZGVsIHdpdGhvdXQgdHJhbnNpZW50IHByb3BlcnRpZXMgYW5kIGEgc2VwYXJhdGUgdHJhbnNpZW50IG9iamVjdFxuICogQHByb3BlcnR5IHtNfSBtb2RlbCAtIFRoZSBtb2RlbCB3aXRoIHRyYW5zaWVudCBwcm9wZXJ0aWVzIHJlbW92ZWRcbiAqIEBwcm9wZXJ0eSB7UmVjb3JkPHN0cmluZywgYW55Pn0gW3RyYW5zaWVudF0gLSBPYmplY3QgY29udGFpbmluZyB0aGUgdHJhbnNpZW50IHByb3BlcnRpZXNcbiAqIEBmdW5jdGlvbiBtb2RlbFRvVHJhbnNpZW50XG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqIEBtZXJtYWlkXG4gKiBzZXF1ZW5jZURpYWdyYW1cbiAqICAgcGFydGljaXBhbnQgQ2FsbGVyXG4gKiAgIHBhcnRpY2lwYW50IG1vZGVsVG9UcmFuc2llbnRcbiAqICAgcGFydGljaXBhbnQgaXNUcmFuc2llbnRcbiAqICAgcGFydGljaXBhbnQgZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlXG4gKlxuICogICBDYWxsZXItPj5tb2RlbFRvVHJhbnNpZW50OiBtb2RlbFxuICogICBtb2RlbFRvVHJhbnNpZW50LT4+aXNUcmFuc2llbnQ6IGNoZWNrIGlmIG1vZGVsIGlzIHRyYW5zaWVudFxuICogICBpc1RyYW5zaWVudC0tPj5tb2RlbFRvVHJhbnNpZW50OiB0cmFuc2llbnQgc3RhdHVzXG4gKiAgIGFsdCBtb2RlbCBpcyBub3QgdHJhbnNpZW50XG4gKiAgICAgbW9kZWxUb1RyYW5zaWVudC0tPj5DYWxsZXI6IHttb2RlbH1cbiAqICAgZWxzZSBtb2RlbCBpcyB0cmFuc2llbnRcbiAqICAgICBtb2RlbFRvVHJhbnNpZW50LT4+Z2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlOiBnZXQgdHJhbnNpZW50IHByb3BlcnRpZXNcbiAqICAgICBnZXRBbGxQcm9wZXJ0eURlY29yYXRvcnNSZWN1cnNpdmUtLT4+bW9kZWxUb1RyYW5zaWVudDogcHJvcGVydHkgZGVjb3JhdG9yc1xuICogICAgIG1vZGVsVG9UcmFuc2llbnQtPj5tb2RlbFRvVHJhbnNpZW50OiBzZXBhcmF0ZSBwcm9wZXJ0aWVzXG4gKiAgICAgbW9kZWxUb1RyYW5zaWVudC0+Pk1vZGVsLmJ1aWxkOiByZWJ1aWxkIG1vZGVsIHdpdGhvdXQgdHJhbnNpZW50IHByb3BzXG4gKiAgICAgbW9kZWxUb1RyYW5zaWVudC0tPj5DYWxsZXI6IHttb2RlbCwgdHJhbnNpZW50fVxuICogICBlbmRcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1vZGVsVG9UcmFuc2llbnQ8TSBleHRlbmRzIE1vZGVsPihcbiAgbW9kZWw6IE1cbik6IHsgbW9kZWw6IE07IHRyYW5zaWVudD86IFJlY29yZDxzdHJpbmcsIGFueT4gfSB7XG4gIGlmICghaXNUcmFuc2llbnQobW9kZWwpKSByZXR1cm4geyBtb2RlbDogbW9kZWwgfTtcbiAgY29uc3QgZGVjczogUmVjb3JkPHN0cmluZywgYW55W10+ID0gZ2V0QWxsUHJvcGVydHlEZWNvcmF0b3JzUmVjdXJzaXZlKFxuICAgIG1vZGVsLFxuICAgIHVuZGVmaW5lZCxcbiAgICBSZXBvc2l0b3J5LmtleShEQktleXMuVFJBTlNJRU5UKVxuICApIGFzIFJlY29yZDxzdHJpbmcsIGFueVtdPjtcblxuICBjb25zdCByZXN1bHQgPSBPYmplY3QuZW50cmllcyhkZWNzKS5yZWR1Y2UoXG4gICAgKFxuICAgICAgYWNjdW06IHsgbW9kZWw6IFJlY29yZDxzdHJpbmcsIGFueT47IHRyYW5zaWVudD86IFJlY29yZDxzdHJpbmcsIGFueT4gfSxcbiAgICAgIFtrLCB2YWxdXG4gICAgKSA9PiB7XG4gICAgICBjb25zdCB0cmFuc2llbnQgPSB2YWwuZmluZCgoZWwpID0+IGVsLmtleSA9PT0gXCJcIik7XG4gICAgICBpZiAodHJhbnNpZW50KSB7XG4gICAgICAgIGFjY3VtLnRyYW5zaWVudCA9IGFjY3VtLnRyYW5zaWVudCB8fCB7fTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBhY2N1bS50cmFuc2llbnRba10gPSBtb2RlbFtrIGFzIGtleW9mIE1dO1xuICAgICAgICB9IGNhdGNoIChlOiB1bmtub3duKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IFNlcmlhbGl6YXRpb25FcnJvcihcbiAgICAgICAgICAgIGBGYWlsZWQgdG8gc2VyaWFsaXplIHRyYW5zaWVudCBwcm9wZXJ0eSAke2t9OiAke2V9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjY3VtLm1vZGVsID0gYWNjdW0ubW9kZWwgfHwge307XG4gICAgICAgIGFjY3VtLm1vZGVsW2tdID0gKG1vZGVsIGFzIFJlY29yZDxzdHJpbmcsIGFueT4pW2tdO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGFjY3VtO1xuICAgIH0sXG4gICAge30gYXMgeyBtb2RlbDogUmVjb3JkPHN0cmluZywgYW55PjsgdHJhbnNpZW50PzogUmVjb3JkPHN0cmluZywgYW55PiB9XG4gICk7XG4gIHJlc3VsdC5tb2RlbCA9IE1vZGVsLmJ1aWxkKHJlc3VsdC5tb2RlbCwgbW9kZWwuY29uc3RydWN0b3IubmFtZSk7XG4gIHJldHVybiByZXN1bHQgYXMgeyBtb2RlbDogTTsgdHJhbnNpZW50PzogUmVjb3JkPHN0cmluZywgYW55PiB9O1xufVxuIiwiZXhwb3J0ICogZnJvbSBcIi4vaWRlbnRpdHlcIjtcbmV4cG9ydCAqIGZyb20gXCIuL2ludGVyZmFjZXNcIjtcbmV4cG9ydCAqIGZyb20gXCIuL21vZGVsXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9vcGVyYXRpb25zXCI7XG5leHBvcnQgKiBmcm9tIFwiLi9yZXBvc2l0b3J5XCI7XG5leHBvcnQgKiBmcm9tIFwiLi92YWxpZGF0aW9uXCI7XG5cbi8qKlxuICogQGRlc2NyaXB0aW9uIERhdGFiYXNlIGRlY29yYXRvcnMgZm9yIFR5cGVTY3JpcHQgYXBwbGljYXRpb25zXG4gKiBAc3VtbWFyeSBBIGNvbXByZWhlbnNpdmUgbGlicmFyeSBwcm92aWRpbmcgZGVjb3JhdG9ycyBhbmQgdXRpbGl0aWVzIGZvciBkYXRhYmFzZSBvcGVyYXRpb25zLCBtb2RlbCBkZWZpbml0aW9ucywgdmFsaWRhdGlvbiwgYW5kIHJlcG9zaXRvcnkgcGF0dGVybnMgaW4gVHlwZVNjcmlwdCBhcHBsaWNhdGlvbnNcbiAqIEBtb2R1bGUgZGItZGVjb3JhdG9yc1xuICovXG5cblxuLyoqXG4gKiBAZGVzY3JpcHRpb24gQ3VycmVudCB2ZXJzaW9uIG9mIHRoZSByZWZsZWN0aW9uIHBhY2thZ2VcbiAqIEBzdW1tYXJ5IFN0b3JlcyB0aGUgc2VtYW50aWMgdmVyc2lvbiBudW1iZXIgb2YgdGhlIHBhY2thZ2VcbiAqIEBjb25zdCBWRVJTSU9OXG4gKiBAbWVtYmVyT2YgbW9kdWxlOmRiLWRlY29yYXRvcnNcbiAqL1xuZXhwb3J0IGNvbnN0IFZFUlNJT04gPSBcIiMjVkVSU0lPTiMjXCI7XG4iXSwibmFtZXMiOlsiTW9kZWxLZXlzIiwiUmVhZE9ubHlWYWxpZGF0b3IiLCJWYWxpZGF0b3IiLCJpc0VxdWFsIiwiX19kZWNvcmF0ZSIsInZhbGlkYXRvciIsIlRpbWVzdGFtcFZhbGlkYXRvciIsIkRlY29yYXRvck1lc3NhZ2VzIiwiVmFsaWRhdGlvbiIsIk9wZXJhdGlvbktleXMiLCJCdWxrQ3J1ZE9wZXJhdGlvbktleXMiLCJIYXNoaW5nIiwicHJvcE1ldGFkYXRhIiwiYXBwbHkiLCJSZWZsZWN0aW9uIiwiT2JqZWN0QWNjdW11bGF0b3IiLCJzZiIsIkRlY29yYXRpb24iLCJkYXRlIiwicmVxdWlyZWQiLCJ0eXBlIiwibWV0YWRhdGEiLCJWYWxpZGF0aW9uS2V5cyIsIlJlc2VydmVkTW9kZWxzIiwiTW9kZWxFcnJvckRlZmluaXRpb24iLCJNb2RlbCIsInZhbGlkYXRlIl0sIm1hcHBpbmdzIjoiOzs7Ozs7SUFFQTs7Ozs7SUFLRztBQUNVLFVBQUEsTUFBTSxHQUFHO0lBQ3BCLElBQUEsT0FBTyxFQUFFLENBQUEsRUFBR0EsNkJBQVMsQ0FBQyxPQUFPLENBQWMsWUFBQSxDQUFBO0lBQzNDLElBQUEsVUFBVSxFQUFFLFlBQVk7SUFDeEIsSUFBQSxLQUFLLEVBQUUsUUFBUTtJQUNmLElBQUEsRUFBRSxFQUFFLElBQUk7SUFDUixJQUFBLEtBQUssRUFBRSxPQUFPO0lBQ2QsSUFBQSxNQUFNLEVBQUUsUUFBUTtJQUNoQixJQUFBLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLElBQUEsUUFBUSxFQUFFLFVBQVU7SUFDcEIsSUFBQSxTQUFTLEVBQUUsV0FBVztJQUN0QixJQUFBLFNBQVMsRUFBRSxXQUFXO0lBQ3RCLElBQUEsSUFBSSxFQUFFLE1BQU07SUFDWixJQUFBLFFBQVEsRUFBRSxVQUFVO0lBQ3BCLElBQUEsT0FBTyxFQUFFLFNBQVM7SUFDbEIsSUFBQSxRQUFRLEVBQUUsZUFBZTs7SUFHM0I7Ozs7O0lBS0c7QUFDSSxVQUFNLGdCQUFnQixHQUFHO0lBRWhDOzs7OztJQUtHO0FBQ0ksVUFBTSx3QkFBd0IsR0FBRzs7SUNyQ3hDOzs7Ozs7Ozs7Ozs7Ozs7SUFlRztBQUNVLFVBQUEsc0JBQXNCLEdBQUc7SUFDcEMsSUFBQSxFQUFFLEVBQUU7SUFDRixRQUFBLE9BQU8sRUFBRSxvQkFBb0I7SUFDN0IsUUFBQSxRQUFRLEVBQUUscUJBQXFCO0lBQ2hDLEtBQUE7SUFDRCxJQUFBLFFBQVEsRUFBRTtJQUNSLFFBQUEsT0FBTyxFQUFFLHdCQUF3QjtJQUNsQyxLQUFBO0lBQ0QsSUFBQSxTQUFTLEVBQUU7SUFDVCxRQUFBLFFBQVEsRUFBRSx3QkFBd0I7SUFDbEMsUUFBQSxJQUFJLEVBQUUscUNBQXFDO0lBQzNDLFFBQUEsT0FBTyxFQUFFLGlDQUFpQztJQUMzQyxLQUFBOztJ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