ts2famix 2.1.0-beta.2 → 3.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (192) hide show
  1. package/.eslintrc.json +24 -24
  2. package/LICENSE +24 -24
  3. package/README.md +78 -78
  4. package/dist/analyze.js +3 -3
  5. package/dist/analyze_functions/process_functions.js +92 -62
  6. package/dist/famix_functions/EntityDictionary.js +672 -597
  7. package/dist/famix_functions/helpers_creation.js +18 -12
  8. package/dist/fqn.js +351 -18
  9. package/dist/lib/famix/famix_JSON_exporter.js +1 -1
  10. package/dist/lib/famix/famix_base_element.js +1 -1
  11. package/dist/lib/famix/famix_repository.js +14 -5
  12. package/dist/lib/famix/index.js +1 -1
  13. package/dist/lib/famix/model/famix/access.js +1 -1
  14. package/dist/lib/famix/model/famix/accessor.js +1 -1
  15. package/dist/lib/famix/model/famix/alias.js +1 -1
  16. package/dist/lib/famix/model/famix/arrow_function.js +1 -1
  17. package/dist/lib/famix/model/famix/behavioral_entity.js +1 -1
  18. package/dist/lib/famix/model/famix/class.js +1 -1
  19. package/dist/lib/famix/model/famix/comment.js +1 -1
  20. package/dist/lib/famix/model/famix/concretisation.js +1 -1
  21. package/dist/lib/famix/model/famix/container_entity.js +1 -1
  22. package/dist/lib/famix/model/famix/decorator.js +1 -1
  23. package/dist/lib/famix/model/famix/entity.js +1 -1
  24. package/dist/lib/famix/model/famix/enum.js +1 -1
  25. package/dist/lib/famix/model/famix/enum_value.js +1 -1
  26. package/dist/lib/famix/model/famix/function.js +1 -1
  27. package/dist/lib/famix/model/famix/import_clause.js +1 -1
  28. package/dist/lib/famix/model/famix/index.js +1 -1
  29. package/dist/lib/famix/model/famix/indexed_file_anchor.js +1 -1
  30. package/dist/lib/famix/model/famix/inheritance.js +1 -1
  31. package/dist/lib/famix/model/famix/interface.js +1 -1
  32. package/dist/lib/famix/model/famix/invocation.js +1 -1
  33. package/dist/lib/famix/model/famix/method.js +1 -1
  34. package/dist/lib/famix/model/famix/module.js +2 -2
  35. package/dist/lib/famix/model/famix/named_entity.js +1 -1
  36. package/dist/lib/famix/model/famix/parameter.js +1 -1
  37. package/dist/lib/famix/model/famix/parameter_concretisation.js +1 -1
  38. package/dist/lib/famix/model/famix/parameter_type.js +1 -1
  39. package/dist/lib/famix/model/famix/parametric_arrow_function.js +1 -1
  40. package/dist/lib/famix/model/famix/parametric_class.js +1 -1
  41. package/dist/lib/famix/model/famix/parametric_function.js +1 -1
  42. package/dist/lib/famix/model/famix/parametric_interface.js +1 -1
  43. package/dist/lib/famix/model/famix/parametric_method.js +1 -1
  44. package/dist/lib/famix/model/famix/primitive_type.js +1 -1
  45. package/dist/lib/famix/model/famix/property.js +1 -1
  46. package/dist/lib/famix/model/famix/reference.js +1 -1
  47. package/dist/lib/famix/model/famix/scoping_entity.js +1 -1
  48. package/dist/lib/famix/model/famix/script_entity.js +1 -1
  49. package/dist/lib/famix/model/famix/source_anchor.js +1 -1
  50. package/dist/lib/famix/model/famix/source_language.js +1 -1
  51. package/dist/lib/famix/model/famix/sourced_entity.js +1 -1
  52. package/dist/lib/famix/model/famix/structural_entity.js +1 -1
  53. package/dist/lib/famix/model/famix/type.js +1 -1
  54. package/dist/lib/famix/model/famix/variable.js +1 -1
  55. package/dist/lib/ts-complex/cyclomatic-service.js +1 -1
  56. package/dist/refactorer/refactor-getter-setter.js +1 -1
  57. package/dist/ts2famix-cli-wrapper.js +1 -1
  58. package/dist/ts2famix-cli.js +1 -1
  59. package/doc-uml/famix-typescript-model.puml +619 -607
  60. package/doc-uml/famix-typescript-model.svg +1 -1
  61. package/eslint.config.mjs +28 -28
  62. package/jest.config.json +1 -1
  63. package/package.json +70 -70
  64. package/src/analyze.ts +120 -120
  65. package/src/analyze_functions/process_functions.ts +1069 -1040
  66. package/src/famix_functions/EntityDictionary.ts +2061 -2016
  67. package/src/famix_functions/helpers_creation.ts +143 -135
  68. package/src/fqn.ts +416 -50
  69. package/src/generate_uml.sh +20 -20
  70. package/src/lib/famix/License.md +22 -22
  71. package/src/lib/famix/famix_JSON_exporter.ts +56 -56
  72. package/src/lib/famix/famix_base_element.ts +22 -22
  73. package/src/lib/famix/famix_repository.ts +288 -278
  74. package/src/lib/famix/index.ts +8 -8
  75. package/src/lib/famix/model/famix/access.ts +50 -50
  76. package/src/lib/famix/model/famix/accessor.ts +15 -15
  77. package/src/lib/famix/model/famix/alias.ts +39 -39
  78. package/src/lib/famix/model/famix/arrow_function.ts +15 -15
  79. package/src/lib/famix/model/famix/behavioral_entity.ts +97 -97
  80. package/src/lib/famix/model/famix/class.ts +85 -85
  81. package/src/lib/famix/model/famix/comment.ts +47 -47
  82. package/src/lib/famix/model/famix/concretisation.ts +40 -40
  83. package/src/lib/famix/model/famix/container_entity.ts +160 -160
  84. package/src/lib/famix/model/famix/decorator.ts +37 -37
  85. package/src/lib/famix/model/famix/entity.ts +15 -15
  86. package/src/lib/famix/model/famix/enum.ts +30 -30
  87. package/src/lib/famix/model/famix/enum_value.ts +28 -28
  88. package/src/lib/famix/model/famix/function.ts +15 -15
  89. package/src/lib/famix/model/famix/import_clause.ts +51 -51
  90. package/src/lib/famix/model/famix/index.ts +41 -41
  91. package/src/lib/famix/model/famix/indexed_file_anchor.ts +46 -46
  92. package/src/lib/famix/model/famix/inheritance.ts +40 -40
  93. package/src/lib/famix/model/famix/interface.ts +75 -75
  94. package/src/lib/famix/model/famix/invocation.ts +65 -65
  95. package/src/lib/famix/model/famix/method.ts +89 -89
  96. package/src/lib/famix/model/famix/module.ts +71 -71
  97. package/src/lib/famix/model/famix/named_entity.ts +95 -95
  98. package/src/lib/famix/model/famix/parameter.ts +28 -28
  99. package/src/lib/famix/model/famix/parameter_concretisation.ts +51 -51
  100. package/src/lib/famix/model/famix/parameter_type.ts +58 -58
  101. package/src/lib/famix/model/famix/parametric_arrow_function.ts +32 -32
  102. package/src/lib/famix/model/famix/parametric_class.ts +49 -49
  103. package/src/lib/famix/model/famix/parametric_function.ts +32 -32
  104. package/src/lib/famix/model/famix/parametric_interface.ts +49 -49
  105. package/src/lib/famix/model/famix/parametric_method.ts +32 -32
  106. package/src/lib/famix/model/famix/primitive_type.ts +15 -15
  107. package/src/lib/famix/model/famix/property.ts +94 -94
  108. package/src/lib/famix/model/famix/reference.ts +40 -40
  109. package/src/lib/famix/model/famix/scoping_entity.ts +35 -35
  110. package/src/lib/famix/model/famix/script_entity.ts +34 -34
  111. package/src/lib/famix/model/famix/source_anchor.ts +30 -30
  112. package/src/lib/famix/model/famix/source_language.ts +35 -35
  113. package/src/lib/famix/model/famix/sourced_entity.ts +70 -70
  114. package/src/lib/famix/model/famix/structural_entity.ts +43 -43
  115. package/src/lib/famix/model/famix/type.ts +87 -87
  116. package/src/lib/famix/model/famix/variable.ts +27 -27
  117. package/src/lib/famix/package.json +28 -28
  118. package/src/lib/ts-complex/cyclomatic-service.ts +83 -83
  119. package/src/refactorer/refactor-getter-setter.ts +140 -140
  120. package/src/ts2famix-cli-wrapper.ts +21 -21
  121. package/src/ts2famix-cli.ts +60 -60
  122. package/tsconfig.check-tests.json +14 -14
  123. package/tsconfig.json +73 -72
  124. package/.vscode/settings.json +0 -4
  125. package/TODO +0 -1
  126. package/arwea-fix.json +0 -1
  127. package/bogus.ts +0 -3
  128. package/class-diagram.puml +0 -792
  129. package/debug.txt +0 -13332
  130. package/debuglog.txt +0 -12073
  131. package/dist/famix2puml.js +0 -126
  132. package/dist/getClasses-arrow-body.js +0 -43
  133. package/dist/lib/famix/src/famix_JSON_exporter.js +0 -55
  134. package/dist/lib/famix/src/famix_base_element.js +0 -18
  135. package/dist/lib/famix/src/famix_repository.js +0 -224
  136. package/dist/lib/famix/src/index.js +0 -31
  137. package/dist/lib/famix/src/model/famix/access.js +0 -40
  138. package/dist/lib/famix/src/model/famix/accessor.js +0 -17
  139. package/dist/lib/famix/src/model/famix/alias.js +0 -33
  140. package/dist/lib/famix/src/model/famix/arrowFunction.js +0 -17
  141. package/dist/lib/famix/src/model/famix/arrow_function.js +0 -17
  142. package/dist/lib/famix/src/model/famix/behavioral_entity.js +0 -79
  143. package/dist/lib/famix/src/model/famix/class.js +0 -71
  144. package/dist/lib/famix/src/model/famix/comment.js +0 -39
  145. package/dist/lib/famix/src/model/famix/concretisation.js +0 -31
  146. package/dist/lib/famix/src/model/famix/container_entity.js +0 -126
  147. package/dist/lib/famix/src/model/famix/decorator.js +0 -32
  148. package/dist/lib/famix/src/model/famix/entity.js +0 -17
  149. package/dist/lib/famix/src/model/famix/enum.js +0 -31
  150. package/dist/lib/famix/src/model/famix/enum_value.js +0 -25
  151. package/dist/lib/famix/src/model/famix/function.js +0 -17
  152. package/dist/lib/famix/src/model/famix/implicit_variable.js +0 -17
  153. package/dist/lib/famix/src/model/famix/import_clause.js +0 -41
  154. package/dist/lib/famix/src/model/famix/index.js +0 -86
  155. package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +0 -38
  156. package/dist/lib/famix/src/model/famix/inheritance.js +0 -33
  157. package/dist/lib/famix/src/model/famix/interface.js +0 -64
  158. package/dist/lib/famix/src/model/famix/invocation.js +0 -54
  159. package/dist/lib/famix/src/model/famix/method.js +0 -67
  160. package/dist/lib/famix/src/model/famix/module.js +0 -60
  161. package/dist/lib/famix/src/model/famix/named_entity.js +0 -78
  162. package/dist/lib/famix/src/model/famix/parameter.js +0 -25
  163. package/dist/lib/famix/src/model/famix/parameterConcretisation.js +0 -44
  164. package/dist/lib/famix/src/model/famix/parameter_concretisation.js +0 -44
  165. package/dist/lib/famix/src/model/famix/parameter_type.js +0 -45
  166. package/dist/lib/famix/src/model/famix/parametricArrowFunction.js +0 -29
  167. package/dist/lib/famix/src/model/famix/parametric_arrow_function.js +0 -31
  168. package/dist/lib/famix/src/model/famix/parametric_class.js +0 -44
  169. package/dist/lib/famix/src/model/famix/parametric_function.js +0 -31
  170. package/dist/lib/famix/src/model/famix/parametric_interface.js +0 -44
  171. package/dist/lib/famix/src/model/famix/parametric_method.js +0 -31
  172. package/dist/lib/famix/src/model/famix/primitive_type.js +0 -17
  173. package/dist/lib/famix/src/model/famix/property.js +0 -73
  174. package/dist/lib/famix/src/model/famix/reference.js +0 -33
  175. package/dist/lib/famix/src/model/famix/scoping_entity.js +0 -36
  176. package/dist/lib/famix/src/model/famix/script_entity.js +0 -29
  177. package/dist/lib/famix/src/model/famix/source_anchor.js +0 -27
  178. package/dist/lib/famix/src/model/famix/source_language.js +0 -35
  179. package/dist/lib/famix/src/model/famix/sourced_entity.js +0 -60
  180. package/dist/lib/famix/src/model/famix/structural_entity.js +0 -39
  181. package/dist/lib/famix/src/model/famix/text_anchor.js +0 -38
  182. package/dist/lib/famix/src/model/famix/type.js +0 -73
  183. package/dist/lib/famix/src/model/famix/variable.js +0 -24
  184. package/fqn-model.json +0 -1
  185. package/iterateGenericTypes.ts +0 -69
  186. package/out/class-diagram/class-diagram.svg +0 -1
  187. package/sample.json +0 -1
  188. package/sample.ts +0 -1
  189. package/stats.txt +0 -3091
  190. package/tabby-debug-output.txt +0 -19433
  191. package/ts2famix.log +0 -22656
  192. package/validate-references.js +0 -103
@@ -43,12 +43,12 @@ var __importDefault = (this && this.__importDefault) || function (mod) {
43
43
  Object.defineProperty(exports, "__esModule", { value: true });
44
44
  exports.EntityDictionary = void 0;
45
45
  exports.isPrimitiveType = isPrimitiveType;
46
+ exports.getPrimitiveTypeName = getPrimitiveTypeName;
46
47
  const ts_morph_1 = require("ts-morph");
47
48
  const process_functions_1 = require("../analyze_functions/process_functions");
48
49
  const Famix = __importStar(require("../lib/famix/model/famix"));
49
50
  const famix_repository_1 = require("../lib/famix/famix_repository");
50
51
  const analyze_1 = require("../analyze");
51
- // import GraphemeSplitter from "grapheme-splitter";
52
52
  // eslint-disable-next-line @typescript-eslint/no-require-imports
53
53
  const GraphemeSplitter = require("grapheme-splitter");
54
54
  const Helpers = __importStar(require("./helpers_creation"));
@@ -280,31 +280,31 @@ class EntityDictionary {
280
280
  }
281
281
  /**
282
282
  * Creates a Famix alias
283
- * @param a An alias
283
+ * @param typeAliasDeclaration An alias
284
284
  * @returns The Famix model of the alias
285
285
  */
286
- createFamixAlias(a) {
286
+ createFamixAlias(typeAliasDeclaration) {
287
287
  let fmxAlias;
288
- const aliasName = a.getName();
288
+ const aliasName = typeAliasDeclaration.getName();
289
289
  //const aliasFullyQualifiedName = a.getType().getText(); // FQNFunctions.getFQN(a);
290
- const aliasFullyQualifiedName = FQNFunctions.getFQN(a);
290
+ const aliasFullyQualifiedName = FQNFunctions.getFQN(typeAliasDeclaration);
291
291
  const foundAlias = this.fmxAliasMap.get(aliasFullyQualifiedName);
292
292
  if (!foundAlias) {
293
293
  fmxAlias = new Famix.Alias();
294
- fmxAlias.name = a.getName();
295
- const aliasNameWithGenerics = aliasName + (a.getTypeParameters().length ? ("<" + a.getTypeParameters().map(tp => tp.getName()).join(", ") + ">") : "");
294
+ fmxAlias.name = typeAliasDeclaration.getName();
295
+ const aliasNameWithGenerics = aliasName + (typeAliasDeclaration.getTypeParameters().length ? ("<" + typeAliasDeclaration.getTypeParameters().map(tp => tp.getName()).join(", ") + ">") : "");
296
296
  analyze_1.logger.debug(`> NOTE: alias ${aliasName} has fully qualified name ${aliasFullyQualifiedName} and name with generics ${aliasNameWithGenerics}.`);
297
- const fmxType = this.createOrGetFamixType(aliasNameWithGenerics, a);
297
+ const fmxType = this.createOrGetFamixType(aliasNameWithGenerics, typeAliasDeclaration.getType(), typeAliasDeclaration);
298
298
  fmxAlias.aliasedEntity = fmxType;
299
- initFQN(a, fmxAlias);
300
- this.makeFamixIndexFileAnchor(a, fmxAlias);
299
+ initFQN(typeAliasDeclaration, fmxAlias);
300
+ this.makeFamixIndexFileAnchor(typeAliasDeclaration, fmxAlias);
301
301
  this.fmxAliasMap.set(aliasFullyQualifiedName, fmxAlias);
302
302
  this.famixRep.addElement(fmxAlias);
303
303
  }
304
304
  else {
305
305
  fmxAlias = foundAlias;
306
306
  }
307
- this.fmxElementObjectMap.set(fmxAlias, a);
307
+ this.fmxElementObjectMap.set(fmxAlias, typeAliasDeclaration);
308
308
  return fmxAlias;
309
309
  }
310
310
  /**
@@ -377,51 +377,61 @@ class EntityDictionary {
377
377
  * @param concreteArguments concrete arguments
378
378
  * @returns A parametric Element
379
379
  */
380
- // public createOrGetFamixConcreteElement(concreteElement : ParametricVariantType,
381
- // concreteElementDeclaration : ConcreteElementTSMorphType,
382
- // concreteArguments: TypeNode[]): ParametricVariantType {
383
- // let fullyQualifiedFilename = concreteElement.fullyQualifiedName;
384
- // let params = "";
385
- // concreteArguments.map((param) => {
386
- // params = params+param.getText()+',';
387
- // });
388
- // params = params.substring(0, params.length - 1)
389
- // fullyQualifiedFilename = Helpers.replaceLastBetweenTags(fullyQualifiedFilename,params);
390
- // let concElement: ParametricVariantType;
391
- // if (!this.fmxInterfaceMap.has(fullyQualifiedFilename) &&
392
- // !this.fmxClassMap.has(fullyQualifiedFilename) &&
393
- // !this.fmxFunctionAndMethodMap.has(fullyQualifiedFilename)){
394
- // concElement = _.cloneDeep(concreteElement);
395
- // concElement.fullyQualifiedName = fullyQualifiedFilename;
396
- // concElement.clearGenericParameters();
397
- // concreteArguments.map((param) => {
398
- // const parameter = this.createOrGetFamixConcreteType(param);
399
- // concElement.addConcreteParameter(parameter);
400
- // })
401
- // if (concreteElement instanceof Famix.ParametricClass) {
402
- // this.fmxClassMap.set(fullyQualifiedFilename, concElement as Famix.ParametricClass);
403
- // } else if (concreteElement instanceof Famix.ParametricInterface) {
404
- // this.fmxInterfaceMap.set(fullyQualifiedFilename, concElement as Famix.ParametricInterface);
405
- // } else if (concreteElement instanceof Famix.ParametricFunction) {
406
- // this.fmxFunctionAndMethodMap.set(fullyQualifiedFilename, concElement as Famix.ParametricFunction);
407
- // } else { // if (concreteElement instanceof Famix.ParametricMethod) {
408
- // this.fmxFunctionAndMethodMap.set(fullyQualifiedFilename, concElement as Famix.ParametricMethod);
409
- // }
410
- // this.famixRep.addElement(concElement);
411
- // this.fmxElementObjectMap.set(concElement,concreteElementDeclaration);
412
- // } else {
413
- // if (concreteElement instanceof Famix.ParametricClass) {
414
- // concElement = this.fmxClassMap.get(fullyQualifiedFilename) as Famix.ParametricClass;
415
- // } else if (concreteElement instanceof Famix.ParametricInterface) {
416
- // concElement = this.fmxInterfaceMap.get(fullyQualifiedFilename) as Famix.ParametricInterface;
417
- // } else if (concreteElement instanceof Famix.ParametricFunction) {
418
- // concElement = this.fmxFunctionAndMethodMap.get(fullyQualifiedFilename) as Famix.ParametricFunction;
419
- // } else { // if (concreteElement instanceof Famix.ParametricMethod) {
420
- // concElement = this.fmxFunctionAndMethodMap.get(fullyQualifiedFilename) as Famix.ParametricMethod;
421
- // }
422
- // }
423
- // return concElement;
424
- // }
380
+ createOrGetFamixConcreteElement(concreteElement, concreteElementDeclaration, concreteArguments) {
381
+ let fullyQualifiedFilename = concreteElement.fullyQualifiedName;
382
+ let params = "";
383
+ concreteArguments.map((param) => {
384
+ params = params + param.getText() + ',';
385
+ });
386
+ params = params.substring(0, params.length - 1);
387
+ fullyQualifiedFilename = Helpers.replaceLastBetweenTags(fullyQualifiedFilename, params);
388
+ let concElement;
389
+ if (!this.fmxInterfaceMap.has(fullyQualifiedFilename) &&
390
+ !this.fmxClassMap.has(fullyQualifiedFilename) &&
391
+ !this.fmxFunctionAndMethodMap.has(fullyQualifiedFilename)) {
392
+ concElement = lodash_1.default.cloneDeep(concreteElement);
393
+ concElement.fullyQualifiedName = fullyQualifiedFilename;
394
+ concElement.clearGenericParameters();
395
+ concreteArguments.map((param) => {
396
+ if (param instanceof ts_morph_1.TypeParameterDeclaration) {
397
+ const parameter = this.createOrGetFamixType(param.getText(), param.getType(), param);
398
+ concElement.addConcreteParameter(parameter);
399
+ }
400
+ else {
401
+ analyze_1.logger.warn(`> WARNING: concrete argument ${param.getText()} is not a TypeParameterDeclaration. It is a ${param.getKindName()}.`);
402
+ }
403
+ });
404
+ if (concreteElement instanceof Famix.ParametricClass) {
405
+ this.fmxClassMap.set(fullyQualifiedFilename, concElement);
406
+ }
407
+ else if (concreteElement instanceof Famix.ParametricInterface) {
408
+ this.fmxInterfaceMap.set(fullyQualifiedFilename, concElement);
409
+ }
410
+ else if (concreteElement instanceof Famix.ParametricFunction) {
411
+ this.fmxFunctionAndMethodMap.set(fullyQualifiedFilename, concElement);
412
+ }
413
+ else { // if (concreteElement instanceof Famix.ParametricMethod) {
414
+ this.fmxFunctionAndMethodMap.set(fullyQualifiedFilename, concElement);
415
+ }
416
+ this.famixRep.addElement(concElement);
417
+ this.fmxElementObjectMap.set(concElement, concreteElementDeclaration);
418
+ }
419
+ else {
420
+ if (concreteElement instanceof Famix.ParametricClass) {
421
+ concElement = this.fmxClassMap.get(fullyQualifiedFilename);
422
+ }
423
+ else if (concreteElement instanceof Famix.ParametricInterface) {
424
+ concElement = this.fmxInterfaceMap.get(fullyQualifiedFilename);
425
+ }
426
+ else if (concreteElement instanceof Famix.ParametricFunction) {
427
+ concElement = this.fmxFunctionAndMethodMap.get(fullyQualifiedFilename);
428
+ }
429
+ else { // if (concreteElement instanceof Famix.ParametricMethod) {
430
+ concElement = this.fmxFunctionAndMethodMap.get(fullyQualifiedFilename);
431
+ }
432
+ }
433
+ return concElement;
434
+ }
425
435
  /**
426
436
  * Creates a Famix property
427
437
  * @param property A property
@@ -438,7 +448,7 @@ class EntityDictionary {
438
448
  catch (error) {
439
449
  analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for property: ${property.getName()}. Continuing...`);
440
450
  }
441
- const fmxType = this.createOrGetFamixType(propTypeName, property);
451
+ const fmxType = this.createOrGetFamixType(propTypeName, property.getType(), property);
442
452
  fmxProperty.declaredType = fmxType;
443
453
  // add the visibility (public, private, etc.) to the fmxProperty
444
454
  fmxProperty.visibility = "";
@@ -485,10 +495,16 @@ class EntityDictionary {
485
495
  * @returns The Famix model of the method or the accessor
486
496
  */
487
497
  createOrGetFamixMethod(method, currentCC) {
488
- let fmxMethod;
489
- const isGeneric = method.getTypeParameters().length > 0;
490
- const functionFullyQualifiedName = FQNFunctions.getFQN(method);
491
- if (!this.fmxFunctionAndMethodMap.has(functionFullyQualifiedName)) {
498
+ // console.log(`\n=== Creating/Getting Method ===`);
499
+ // console.log(`Method kind: ${method.getKindName()}`);
500
+ // console.log(`Method text: ${method.getText().slice(0, 50)}...`);
501
+ const fqn = FQNFunctions.getFQN(method);
502
+ // console.log(`Method FQN: ${fqn}`);
503
+ analyze_1.logger.debug(`Processing method ${fqn}`);
504
+ let fmxMethod = this.fmxFunctionAndMethodMap.get(fqn);
505
+ if (!fmxMethod) {
506
+ // console.log('Method not found in map, creating new');
507
+ const isGeneric = method.getTypeParameters().length > 0;
492
508
  if (method instanceof ts_morph_1.GetAccessorDeclaration || method instanceof ts_morph_1.SetAccessorDeclaration) {
493
509
  fmxMethod = new Famix.Accessor();
494
510
  const isGetter = method instanceof ts_morph_1.GetAccessorDeclaration;
@@ -499,15 +515,9 @@ class EntityDictionary {
499
515
  if (isSetter) {
500
516
  fmxMethod.kind = "setter";
501
517
  }
502
- this.famixRep.addElement(fmxMethod);
503
518
  }
504
519
  else {
505
- if (isGeneric) {
506
- fmxMethod = new Famix.ParametricMethod();
507
- }
508
- else {
509
- fmxMethod = new Famix.Method();
510
- }
520
+ fmxMethod = isGeneric ? new Famix.ParametricMethod() : new Famix.Method();
511
521
  }
512
522
  const isConstructor = method instanceof ts_morph_1.ConstructorDeclaration;
513
523
  const isSignature = method instanceof ts_morph_1.MethodSignature;
@@ -522,59 +532,41 @@ class EntityDictionary {
522
532
  }
523
533
  fmxMethod.isAbstract = isAbstract;
524
534
  fmxMethod.isClassSide = isStatic;
525
- fmxMethod.isPrivate = (method instanceof ts_morph_1.MethodDeclaration || method instanceof ts_morph_1.GetAccessorDeclaration || method instanceof ts_morph_1.SetAccessorDeclaration) ? (method.getModifiers().find(x => x.getText() === 'private')) !== undefined : false;
526
- fmxMethod.isProtected = (method instanceof ts_morph_1.MethodDeclaration || method instanceof ts_morph_1.GetAccessorDeclaration || method instanceof ts_morph_1.SetAccessorDeclaration) ? (method.getModifiers().find(x => x.getText() === 'protected')) !== undefined : false;
535
+ fmxMethod.isPrivate = (method instanceof ts_morph_1.MethodDeclaration || method instanceof ts_morph_1.GetAccessorDeclaration || method instanceof ts_morph_1.SetAccessorDeclaration)
536
+ ? !!method.getModifiers().find(x => x.getText() === 'private') : false;
537
+ fmxMethod.isProtected = (method instanceof ts_morph_1.MethodDeclaration || method instanceof ts_morph_1.GetAccessorDeclaration || method instanceof ts_morph_1.SetAccessorDeclaration)
538
+ ? !!method.getModifiers().find(x => x.getText() === 'protected') : false;
527
539
  fmxMethod.signature = Helpers.computeSignature(method.getText());
528
- let methodName;
529
- if (isConstructor) {
530
- methodName = "constructor";
531
- }
532
- else {
533
- methodName = method.getName();
534
- }
540
+ const methodName = isConstructor ? "constructor" : method.getName();
535
541
  fmxMethod.name = methodName;
536
- if (!isConstructor) {
537
- if (method.getName().substring(0, 1) === "#") {
538
- fmxMethod.isPrivate = true;
539
- }
540
- }
541
- if (!fmxMethod.isPrivate && !fmxMethod.isProtected) {
542
- fmxMethod.isPublic = true;
543
- }
544
- else {
545
- fmxMethod.isPublic = false;
546
- }
547
- if (!isSignature) {
548
- fmxMethod.cyclomaticComplexity = currentCC[fmxMethod.name];
549
- }
550
- else {
551
- fmxMethod.cyclomaticComplexity = 0;
542
+ if (!isConstructor && methodName.startsWith("#")) {
543
+ fmxMethod.isPrivate = true;
552
544
  }
545
+ fmxMethod.isPublic = !fmxMethod.isPrivate && !fmxMethod.isProtected;
546
+ fmxMethod.cyclomaticComplexity = isSignature ? 0 : (currentCC[methodName] || 0);
553
547
  let methodTypeName = this.UNKNOWN_VALUE;
554
548
  try {
555
549
  methodTypeName = method.getReturnType().getText().trim();
550
+ analyze_1.logger.debug(`Method return type: ${methodTypeName}`);
556
551
  }
557
552
  catch (error) {
558
- analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for return type of method: ${fmxMethod.name}. Continuing...`);
553
+ analyze_1.logger.error(`Failed to get return type for ${fqn}: ${error}`);
559
554
  }
560
- const fmxType = this.createOrGetFamixType(methodTypeName, method);
555
+ const fmxType = this.createOrGetFamixType(methodTypeName, method.getType(), method);
556
+ // console.log(`Created/retrieved return type with FQN: ${fmxType.fullyQualifiedName}`);
561
557
  fmxMethod.declaredType = fmxType;
562
558
  fmxMethod.numberOfLinesOfCode = method.getEndLineNumber() - method.getStartLineNumber();
563
- const parameters = method.getParameters();
564
- fmxMethod.numberOfParameters = parameters.length;
565
- if (!isSignature) {
566
- fmxMethod.numberOfStatements = method.getStatements().length;
567
- }
568
- else {
569
- fmxMethod.numberOfStatements = 0;
570
- }
559
+ fmxMethod.numberOfParameters = method.getParameters().length;
560
+ fmxMethod.numberOfStatements = isSignature ? 0 : method.getStatements().length;
561
+ // Add to famixRep
571
562
  initFQN(method, fmxMethod);
572
563
  this.famixRep.addElement(fmxMethod);
573
564
  this.makeFamixIndexFileAnchor(method, fmxMethod);
574
- this.fmxFunctionAndMethodMap.set(functionFullyQualifiedName, fmxMethod);
565
+ this.fmxFunctionAndMethodMap.set(fqn, fmxMethod);
566
+ analyze_1.logger.debug(`Added method ${fqn} to famixRep`);
575
567
  }
576
568
  else {
577
- fmxMethod = this.fmxFunctionAndMethodMap.get(functionFullyQualifiedName);
569
+ analyze_1.logger.debug(`Method ${fqn} already exists`);
578
570
  }
579
571
  this.fmxElementObjectMap.set(fmxMethod, method);
580
572
  return fmxMethod;
@@ -614,7 +606,7 @@ class EntityDictionary {
614
606
  catch (error) {
615
607
  analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for return type of function: ${func.getName()}. Continuing...`);
616
608
  }
617
- const fmxType = this.createOrGetFamixType(functionTypeName, func);
609
+ const fmxType = this.createOrGetFamixType(functionTypeName, func.getType(), func);
618
610
  fmxFunction.declaredType = fmxType;
619
611
  fmxFunction.numberOfLinesOfCode = func.getEndLineNumber() - func.getStartLineNumber();
620
612
  const parameters = func.getParameters();
@@ -653,7 +645,7 @@ class EntityDictionary {
653
645
  catch (error) {
654
646
  analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for parameter: ${param.getName()}. Continuing...`);
655
647
  }
656
- const fmxType = this.createOrGetFamixType(paramTypeName, param);
648
+ const fmxType = this.createOrGetFamixType(paramTypeName, param.getType(), param);
657
649
  fmxParam.declaredType = fmxType;
658
650
  fmxParam.name = param.getName();
659
651
  initFQN(param, fmxParam);
@@ -677,84 +669,88 @@ class EntityDictionary {
677
669
  this.fmxElementObjectMap.set(fmxParameterType, tp);
678
670
  return fmxParameterType;
679
671
  }
680
- /**
681
- * Creates a Famix type in the context of concretizations
682
- * @param typeName A type name
683
- * @param element An element
684
- * @returns The Famix model of the type
685
- */
686
- createOrGetFamixConcreteType(element) {
687
- // TODO - refactor to stop using names as a key in the maps, use ts-morph element instead
688
- const typeParameterDeclaration = element.getSymbol()?.getDeclarations()[0];
689
- const parameterTypeName = element.getText();
690
- let fmxParameterType = undefined;
691
- // get a TypeReference from a TypeNode
692
- const typeReference = element.getType();
693
- // get a TypeDeclaration from a TypeReference
694
- const typeDeclaration = typeReference.getSymbol()?.getDeclarations()[0];
695
- let isClassOrInterface = false;
696
- if (this.fmxClassMap.has(parameterTypeName)) {
697
- this.fmxClassMap.forEach((obj, name) => {
698
- if (obj instanceof Famix.ParametricClass) {
699
- if (name === element.getText() && obj.genericParameters.size > 0) {
700
- fmxParameterType = obj;
701
- isClassOrInterface = true;
702
- }
703
- }
704
- else {
705
- if (name === element.getText()) {
706
- fmxParameterType = obj;
707
- isClassOrInterface = true;
708
- }
709
- }
710
- });
711
- }
712
- if (this.fmxInterfaceMap.has(parameterTypeName)) {
713
- this.fmxInterfaceMap.forEach((obj, name) => {
714
- if (obj instanceof Famix.ParametricInterface) {
715
- if (name === element.getText() && obj.genericParameters.size > 0) {
716
- fmxParameterType = obj;
717
- isClassOrInterface = true;
718
- }
719
- }
720
- else {
721
- if (name === element.getText()) {
722
- fmxParameterType = obj;
723
- isClassOrInterface = true;
724
- }
725
- }
726
- });
727
- }
728
- if (!isClassOrInterface) {
729
- if (!this.fmxTypeMap.has(typeDeclaration)) {
730
- // TODO refactor
731
- if (isPrimitiveType(parameterTypeName)) {
732
- fmxParameterType = new Famix.PrimitiveType();
733
- fmxParameterType.isStub = true;
734
- }
735
- else {
736
- fmxParameterType = new Famix.ParameterType();
737
- }
738
- fmxParameterType.name = parameterTypeName;
739
- this.famixRep.addElement(fmxParameterType);
740
- this.fmxTypeMap.set(typeDeclaration, fmxParameterType);
741
- this.fmxElementObjectMap.set(fmxParameterType, typeParameterDeclaration);
742
- }
743
- else {
744
- const result = this.fmxTypeMap.get(typeDeclaration);
745
- if (result) {
746
- fmxParameterType = result;
747
- }
748
- else {
749
- throw new Error(`Famix type ${typeDeclaration} is not found in the Type map.`);
750
- }
751
- }
752
- }
753
- if (!fmxParameterType) {
754
- throw new Error(`fmxParameterType was undefined for parameterTypeName ${parameterTypeName}`);
755
- }
756
- return fmxParameterType;
757
- }
672
+ // /**
673
+ // * Creates a Famix type in the context of concretizations
674
+ // * @param typeName A type name
675
+ // * @param element An element
676
+ // * @returns The Famix model of the type
677
+ // */
678
+ // public createOrGetFamixConcreteType(element: TypeNode):
679
+ // Famix.ParameterType | Famix.PrimitiveType | Famix.Class | Famix.Interface {
680
+ // if (this.fmxTypeMap.has(element)) {
681
+ // const rType = this.fmxTypeMap.get(element);
682
+ // if (rType) {
683
+ // return rType;
684
+ // } else {
685
+ // throw new Error(`Famix type ${element.getText()} is not found in the type map.`);
686
+ // }
687
+ // }
688
+ // const typeParameterDeclaration = element.getSymbol()?.getDeclarations()[0] as TypeParameterDeclaration;
689
+ // // const parameterTypeName : string = element.getText();
690
+ // const parameterTypeName = getPrimitiveTypeName(element.getType()) || element.getText();
691
+ // let fmxParameterType: Famix.Type | Famix.Class | Famix.Interface | undefined = undefined;
692
+ // // get a TypeReference from a TypeNode
693
+ // const typeReference = element.getType();
694
+ // // get a TypeDeclaration from a TypeReference
695
+ // const typeDeclaration = typeReference.getSymbol()?.getDeclarations()[0] as TSMorphTypeDeclaration;
696
+ // let isClassOrInterface = false;
697
+ // if (this.fmxClassMap.has(parameterTypeName)){
698
+ // this.fmxClassMap.forEach((obj, name) => {
699
+ // if(obj instanceof Famix.ParametricClass){
700
+ // if (name === element.getText() && obj.genericParameters.size>0) {
701
+ // fmxParameterType = obj;
702
+ // isClassOrInterface = true;
703
+ // }
704
+ // } else {
705
+ // if (name === element.getText()) {
706
+ // fmxParameterType = obj;
707
+ // isClassOrInterface = true;
708
+ // }
709
+ // }
710
+ // });
711
+ // }
712
+ // if (this.fmxInterfaceMap.has(parameterTypeName)){
713
+ // this.fmxInterfaceMap.forEach((obj, name) => {
714
+ // if(obj instanceof Famix.ParametricInterface){
715
+ // if (name === element.getText() && obj.genericParameters.size>0) {
716
+ // fmxParameterType = obj;
717
+ // isClassOrInterface = true;
718
+ // }
719
+ // } else {
720
+ // if (name === element.getText()) {
721
+ // fmxParameterType = obj;
722
+ // isClassOrInterface = true;
723
+ // }
724
+ // }
725
+ // });
726
+ // }
727
+ // if(!isClassOrInterface){
728
+ // if (!this.fmxTypeMap.has(typeDeclaration)) {
729
+ // // TODO refactor
730
+ // if (isPrimitiveType(parameterTypeName)) {
731
+ // fmxParameterType = this.createOrGetFamixPrimitiveType(parameterTypeName);
732
+ // } else {
733
+ // fmxParameterType = new Famix.ParameterType();
734
+ // }
735
+ // fmxParameterType.name = parameterTypeName;
736
+ // this.famixRep.addElement(fmxParameterType);
737
+ // this.fmxTypeMap.set(typeDeclaration, fmxParameterType);
738
+ // this.fmxElementObjectMap.set(fmxParameterType,typeParameterDeclaration);
739
+ // }
740
+ // else {
741
+ // const result = this.fmxTypeMap.get(typeDeclaration);
742
+ // if (result) {
743
+ // fmxParameterType = result;
744
+ // } else {
745
+ // throw new Error(`Famix type ${typeDeclaration} is not found in the Type map.`);
746
+ // }
747
+ // }
748
+ // }
749
+ // if (!fmxParameterType) {
750
+ // throw new Error(`fmxParameterType was undefined for parameterTypeName ${parameterTypeName}`);
751
+ // }
752
+ // return fmxParameterType;
753
+ // }
758
754
  /**
759
755
  * Creates a Famix variable
760
756
  * @param variable A variable
@@ -778,7 +774,7 @@ class EntityDictionary {
778
774
  catch (error) {
779
775
  analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for variable: ${variable.getName()}. Continuing...`);
780
776
  }
781
- const fmxType = this.createOrGetFamixType(variableTypeName, variable);
777
+ const fmxType = this.createOrGetFamixType(variableTypeName, variable.getType(), variable);
782
778
  fmxVariable.declaredType = fmxType;
783
779
  fmxVariable.name = variable.getName();
784
780
  initFQN(variable, fmxVariable);
@@ -826,7 +822,7 @@ class EntityDictionary {
826
822
  catch (error) {
827
823
  analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for enum value: ${enumMember.getName()}. Continuing...`);
828
824
  }
829
- const fmxType = this.createOrGetFamixType(enumValueTypeName, enumMember);
825
+ const fmxType = this.createOrGetFamixType(enumValueTypeName, enumMember.getType(), enumMember);
830
826
  fmxEnumValue.declaredType = fmxType;
831
827
  fmxEnumValue.name = enumMember.getName();
832
828
  initFQN(enumMember, fmxEnumValue);
@@ -879,59 +875,92 @@ class EntityDictionary {
879
875
  * @param element A ts-morph element
880
876
  * @returns The Famix model of the type
881
877
  */
882
- createOrGetFamixType(typeName, element) {
883
- let fmxType;
884
- const isPrimitive = isPrimitiveType(typeName);
885
- const isParametricType = element instanceof ts_morph_1.ClassDeclaration && element.getTypeParameters().length > 0 ||
886
- element instanceof ts_morph_1.InterfaceDeclaration && element.getTypeParameters().length > 0;
887
- // Functions and methods aren't types!
888
- // ||
889
- // element instanceof FunctionDeclaration && element.getTypeParameters().length > 0 ||
890
- // element instanceof MethodDeclaration && element.getTypeParameters().length > 0 ||
891
- // element instanceof ArrowFunction && element.getTypeParameters().length > 0;
892
- analyze_1.logger.debug("Creating (or getting) type: '" + typeName + "' of element: " + element?.getText() + " of kind: " + element?.getKindName());
893
- if (isPrimitive) {
878
+ createOrGetFamixType(typeNameArg, tsMorphType, element) {
879
+ analyze_1.logger.debug(`Creating (or getting) type: '${tsMorphType?.getText() || "undefined"}' of element: '${element?.getText().slice(0, 50)}...' of kind: ${element?.getKindName()}`);
880
+ // convert type to correct primitive name (workaround for unique symbole primitive type)
881
+ // don't convert to primitive if it's a generic type
882
+ const typeName = !typeNameArg.includes("<") && tsMorphType && getPrimitiveTypeName(tsMorphType) || typeNameArg;
883
+ if (isPrimitiveType(typeName)) {
894
884
  return this.createOrGetFamixPrimitiveType(typeName);
895
885
  }
886
+ if (element.isKind(ts_morph_1.SyntaxKind.MethodSignature) || element.isKind(ts_morph_1.SyntaxKind.MethodDeclaration)) {
887
+ const methodFQN = FQNFunctions.getFQN(element);
888
+ const returnTypeFQN = `${methodFQN.replace(/\[Method(Signature|Declaration)\]$/, '')}[ReturnType]`;
889
+ // Check if we already have this return type in the repository
890
+ const existingType = this.famixRep.getFamixEntityByFullyQualifiedName(returnTypeFQN);
891
+ if (existingType) {
892
+ // console.log(`Found existing return type with FQN: ${returnTypeFQN}`);
893
+ return existingType;
894
+ }
895
+ // console.log(`Creating return type with distinct FQN: ${returnTypeFQN}`);
896
+ const fmxType = new Famix.Type();
897
+ fmxType.name = typeName;
898
+ fmxType.fullyQualifiedName = returnTypeFQN;
899
+ // Set container (same as method's container)
900
+ const methodAncestor = Helpers.findTypeAncestor(element);
901
+ if (methodAncestor) {
902
+ const ancestorFQN = FQNFunctions.getFQN(methodAncestor);
903
+ const ancestor = this.famixRep.getFamixEntityByFullyQualifiedName(ancestorFQN);
904
+ if (ancestor) {
905
+ fmxType.container = ancestor;
906
+ }
907
+ }
908
+ this.famixRep.addElement(fmxType);
909
+ this.fmxTypeMap.set(element, fmxType);
910
+ this.fmxElementObjectMap.set(fmxType, element);
911
+ return fmxType;
912
+ }
913
+ const isParametricType = (element instanceof ts_morph_1.ClassDeclaration && element.getTypeParameters().length > 0) ||
914
+ (element instanceof ts_morph_1.InterfaceDeclaration && element.getTypeParameters().length > 0);
896
915
  if (isParametricType) {
897
- // narrow the type
898
- const parametricElement = element;
899
- return this.createOrGetFamixParametricType(typeName, parametricElement);
916
+ return this.createOrGetFamixParametricType(typeName, element);
900
917
  }
901
918
  if (!this.fmxTypeMap.has(element)) {
902
- let ancestor = undefined;
903
- if (element !== undefined) {
919
+ // console.log('Type not found in map, creating new');
920
+ let ancestor;
921
+ if (element) {
904
922
  const typeAncestor = Helpers.findTypeAncestor(element);
905
- if (!typeAncestor) {
906
- throw new Error(`Ancestor not found for element ${element.getText()}.`);
923
+ // console.log(`Type ancestor found: ${typeAncestor?.getKindName()}`);
924
+ if (typeAncestor) {
925
+ const ancestorFullyQualifiedName = FQNFunctions.getFQN(typeAncestor);
926
+ // console.log(`Ancestor FQN: ${ancestorFullyQualifiedName}`);
927
+ ancestor = this.famixRep.getFamixEntityByFullyQualifiedName(ancestorFullyQualifiedName);
928
+ if (!ancestor) {
929
+ ancestor = this.createOrGetFamixType(typeAncestor.getText(), typeAncestor.getType(), typeAncestor);
930
+ // console.log('Ancestor not found in repo, creating it');
931
+ }
932
+ else {
933
+ console.log(`Found ancestor in famixRep: ${ancestor.fullyQualifiedName}`);
934
+ }
907
935
  }
908
- const ancestorFullyQualifiedName = FQNFunctions.getFQN(typeAncestor);
909
- ancestor = this.famixRep.getFamixEntityByFullyQualifiedName(ancestorFullyQualifiedName);
910
- if (!ancestor) {
911
- analyze_1.logger.debug(`Ancestor ${FQNFunctions.getFQN(typeAncestor)} not found. Adding the new type.`);
912
- ancestor = this.createOrGetFamixType(typeAncestor.getText(), typeAncestor);
936
+ else {
937
+ console.log(`No type ancestor found for ${typeName} - proceeding without container`);
913
938
  }
914
939
  }
915
- fmxType = new Famix.Type();
940
+ const fmxType = new Famix.Type();
916
941
  fmxType.name = typeName;
917
- if (!ancestor) {
942
+ // console.log(`Created new type with name: ${typeName}`);
943
+ if (ancestor) {
944
+ fmxType.container = ancestor;
945
+ }
946
+ else {
918
947
  throw new Error(`Ancestor not found for type ${typeName}.`);
919
948
  }
920
- fmxType.container = ancestor;
921
949
  initFQN(element, fmxType);
950
+ // console.log(`Type FQN after init: ${fmxType.fullyQualifiedName}`);
922
951
  this.makeFamixIndexFileAnchor(element, fmxType);
923
952
  this.famixRep.addElement(fmxType);
953
+ // console.log('Added type to repository');
924
954
  this.fmxTypeMap.set(element, fmxType);
925
955
  }
926
956
  else {
927
- const result = this.fmxTypeMap.get(element);
928
- if (result) {
929
- fmxType = result;
930
- }
931
- else {
957
+ const fmxType = this.fmxTypeMap.get(element);
958
+ if (!fmxType) {
932
959
  throw new Error(`Famix type ${typeName} is not found in the Type map.`);
933
960
  }
961
+ return fmxType;
934
962
  }
963
+ const fmxType = this.fmxTypeMap.get(element);
935
964
  this.fmxElementObjectMap.set(fmxType, element);
936
965
  return fmxType;
937
966
  }
@@ -1030,6 +1059,7 @@ class EntityDictionary {
1030
1059
  fmxType = new Famix.PrimitiveType();
1031
1060
  fmxType.isStub = true;
1032
1061
  fmxType.name = typeName;
1062
+ fmxType.fullyQualifiedName = typeName + "[PrimitiveType]";
1033
1063
  this.fmxPrimitiveTypeMap.set(typeName, fmxType);
1034
1064
  this.famixRep.addElement(fmxType);
1035
1065
  }
@@ -1050,22 +1080,25 @@ class EntityDictionary {
1050
1080
  }
1051
1081
  analyze_1.logger.debug(`Creating FamixAccess. Node: [${node.getKindName()}] '${node.getText()}' at line ${node.getStartLineNumber()} in ${node.getSourceFile().getBaseName()}, id: ${id} refers to fmxVar '${fmxVar.fullyQualifiedName}'.`);
1052
1082
  const nodeReferenceAncestor = Helpers.findAncestor(node);
1083
+ if (!nodeReferenceAncestor) {
1084
+ analyze_1.logger.error(`No ancestor found for node '${node.getText()}'`);
1085
+ return;
1086
+ }
1053
1087
  const ancestorFullyQualifiedName = FQNFunctions.getFQN(nodeReferenceAncestor);
1054
1088
  const accessor = this.famixRep.getFamixEntityByFullyQualifiedName(ancestorFullyQualifiedName);
1055
1089
  if (!accessor) {
1056
1090
  analyze_1.logger.error(`Ancestor ${ancestorFullyQualifiedName} of kind ${nodeReferenceAncestor.getKindName()} not found.`);
1057
- // accessor = this.createOrGetFamixType(ancestorFullyQualifiedName, nodeReferenceAncestor as TypeDeclaration);
1058
- return; // bail out TODO: this is probably wrong
1091
+ return; // Bail out for now
1059
1092
  }
1060
1093
  else {
1061
1094
  analyze_1.logger.debug(`Found accessor to be ${accessor.fullyQualifiedName}.`);
1062
1095
  }
1063
- // make sure accessor is a method, function, script or module
1096
+ // Ensure accessor is a method, function, script, or module
1064
1097
  if (!(accessor instanceof Famix.Method) && !(accessor instanceof Famix.ArrowFunction) && !(accessor instanceof Famix.Function) && !(accessor instanceof Famix.ScriptEntity) && !(accessor instanceof Famix.Module)) {
1065
1098
  analyze_1.logger.error(`Accessor ${accessor.fullyQualifiedName} is not a method, function, etc.`);
1066
1099
  return;
1067
1100
  }
1068
- // don't create any duplicates (e.g. if the same variable is accessed multiple times by same accessor)
1101
+ // Avoid duplicates
1069
1102
  const foundAccess = this.famixRep.getFamixAccessByAccessorAndVariable(accessor, fmxVar);
1070
1103
  if (foundAccess) {
1071
1104
  analyze_1.logger.debug(`FamixAccess already exists for accessor ${accessor.fullyQualifiedName} and variable ${fmxVar.fullyQualifiedName}.`);
@@ -1076,6 +1109,7 @@ class EntityDictionary {
1076
1109
  fmxAccess.variable = fmxVar;
1077
1110
  this.famixRep.addElement(fmxAccess);
1078
1111
  this.fmxElementObjectMap.set(fmxAccess, node);
1112
+ analyze_1.logger.debug(`Created access: ${accessor.fullyQualifiedName} -> ${fmxVar.fullyQualifiedName}`);
1079
1113
  }
1080
1114
  /**
1081
1115
  * Creates a Famix invocation
@@ -1112,98 +1146,70 @@ class EntityDictionary {
1112
1146
  }
1113
1147
  /**
1114
1148
  * Creates a Famix inheritance
1115
- * @param cls A class or an interface (subclass)
1116
- * @param inhClass The inherited class or interface (superclass)
1149
+ * @param baseClassOrInterface A class or an interface (subclass)
1150
+ * @param inheritedClassOrInterface The inherited class or interface (superclass)
1117
1151
  */
1118
- createOrGetFamixInheritance(cls, inhClass) {
1119
- // // need a key to see if the inheritance already exists
1120
- // const classFullyQualifiedName = FQNFunctions.getFQN(cls);
1121
- // let inKeyword: string;
1122
- // let inhClassFullyQualifiedName: string;
1123
- // let inhClassName: string | undefined;
1124
- // // if inhClass is an ExpressionWithTypeArguments, it is an interface
1125
- // if (inhClass instanceof ExpressionWithTypeArguments) {
1126
- // inhClassName = inhClass.getExpression().getText();
1127
- // // what is inhClassFullyQualifiedName? TODO
1128
- // inhClassFullyQualifiedName = 'Undefined_Scope_from_importer.' + inhClassName;
1129
- // } else {
1130
- // inhClassName = inhClass.getName();
1131
- // if (!inhClassName) {
1132
- // throw new Error(`Inherited class or interface name not found for ${inhClass.getText()}.`);
1133
- // }
1134
- // inhClassFullyQualifiedName = FQNFunctions.getFQN(inhClass);
1135
- // }
1136
- // // build the unique key of the inheritance
1137
- // if ((cls instanceof ClassDeclaration && inhClass instanceof ClassDeclaration)
1138
- // || (cls instanceof InterfaceDeclaration && inhClass instanceof InterfaceDeclaration)) {
1139
- // inKeyword = " extends ";
1140
- // } else if (cls instanceof ClassDeclaration && (inhClass instanceof InterfaceDeclaration || inhClass instanceof ExpressionWithTypeArguments)) {
1141
- // inKeyword = " implements ";
1142
- // } else {
1143
- // throw new Error(`Inheritance ${cls.getText()} and ${inhClass.getText()} is not valid.`);
1144
- // }
1145
- // const inheritanceFullyQualifiedName = FQNFunctions.getFQN(cls) + inKeyword + inhClassFullyQualifiedName;
1146
- // if (this.fmxInheritanceMap.has(inheritanceFullyQualifiedName)) {
1147
- // const rInheritance = this.fmxInheritanceMap.get(inheritanceFullyQualifiedName);
1148
- // if (rInheritance) {
1149
- // return; // don't do anything
1150
- // } else {
1151
- // throw new Error(`Inheritance ${cls.getText()} is not found in the inheritance map.`);
1152
- // }
1153
- // }
1152
+ createOrGetFamixInheritance(baseClassOrInterface, inheritedClassOrInterface) {
1153
+ analyze_1.logger.debug(`Creating FamixInheritance for ${baseClassOrInterface.getText()} and ${inheritedClassOrInterface.getText()} [${inheritedClassOrInterface.constructor.name}].`);
1154
1154
  const fmxInheritance = new Famix.Inheritance();
1155
- // logger.debug(`createFamixInheritance: classFullyQualifiedName: class fqn = ${classFullyQualifiedName}`);
1156
1155
  let subClass;
1157
- if (cls instanceof ts_morph_1.ClassDeclaration) {
1158
- subClass = this.createOrGetFamixClass(cls);
1156
+ if (baseClassOrInterface instanceof ts_morph_1.ClassDeclaration) {
1157
+ subClass = this.createOrGetFamixClass(baseClassOrInterface);
1159
1158
  }
1160
1159
  else {
1161
- subClass = this.createOrGetFamixInterface(cls);
1160
+ subClass = this.createOrGetFamixInterface(baseClassOrInterface);
1162
1161
  }
1163
1162
  if (!subClass) {
1164
- throw new Error(`Subclass ${cls} not found in Class or Interface maps.`);
1163
+ throw new Error(`Subclass ${baseClassOrInterface} not found in Class or Interface maps.`);
1165
1164
  }
1166
1165
  let superClass;
1167
- // if (inhClass instanceof ClassDeclaration || inhClass instanceof InterfaceDeclaration) {
1168
- // inhClassName = inhClass.getName();
1169
- // if (!inhClassName) {
1170
- // throw new Error(`Inherited class or interface name not found for ${inhClass.getText()}.`);
1171
- // }
1172
- // inhClassFullyQualifiedName = FQNFunctions.getFQN(inhClass);
1173
- // if (inhClass instanceof ClassDeclaration) {
1174
- // superClass = this.fmxClassMap.get(inhClassFullyQualifiedName);
1175
- // }
1176
- // else {
1177
- // superClass = this.fmxInterfaceMap.get(inhClassFullyQualifiedName);
1178
- // }
1179
- // if (!superClass) {
1180
- // throw new Error(`Superclass ${classFullyQualifiedName} not found in Class or Interface maps.`);
1181
- // }
1182
- // }
1183
- // // it shouldn't add the class/interface again to the Map, it should use createOrGet (?)
1184
- // if (superClass === undefined) {
1185
- if (inhClass instanceof ts_morph_1.ClassDeclaration) {
1186
- // superClass = new Famix.Class();
1187
- superClass = this.createOrGetFamixClass(inhClass);
1188
- // this.fmxClassMap.set(inhClassFullyQualifiedName, superClass);
1189
- }
1190
- else if (inhClass instanceof ts_morph_1.InterfaceDeclaration) {
1191
- // superClass = new Famix.Interface();
1192
- superClass = this.createOrGetFamixInterface(inhClass);
1193
- // this.fmxInterfaceMap.set(inhClassFullyQualifiedName, superClass);
1166
+ if (inheritedClassOrInterface instanceof ts_morph_1.ClassDeclaration) {
1167
+ superClass = this.createOrGetFamixClass(inheritedClassOrInterface);
1168
+ }
1169
+ else if (inheritedClassOrInterface instanceof ts_morph_1.InterfaceDeclaration) {
1170
+ superClass = this.createOrGetFamixInterface(inheritedClassOrInterface);
1194
1171
  }
1195
1172
  else {
1196
- // inhClass instanceof ExpressionWithTypeArguments
1197
- const interfaceDeclaration = getInterfaceDeclarationFromExpression(inhClass);
1198
- if (interfaceDeclaration !== undefined) {
1199
- superClass = this.createOrGetFamixInterface(interfaceDeclaration);
1173
+ // inheritedClassOrInterface instanceof ExpressionWithTypeArguments
1174
+ // must determine if inheritedClassOrInterface is a class or an interface
1175
+ // then find the declaration, else it's a stub
1176
+ const heritageClause = inheritedClassOrInterface.getParent();
1177
+ if (heritageClause instanceof ts_morph_1.HeritageClause) {
1178
+ // cases: 1) class extends class, 2) class implements interface, 3) interface extends interface
1179
+ // class extends class
1180
+ if (heritageClause.getText().startsWith("extends") && baseClassOrInterface instanceof ts_morph_1.ClassDeclaration) {
1181
+ const classDeclaration = getInterfaceOrClassDeclarationFromExpression(inheritedClassOrInterface);
1182
+ if (classDeclaration !== undefined && classDeclaration instanceof ts_morph_1.ClassDeclaration) {
1183
+ superClass = this.createOrGetFamixClass(classDeclaration);
1184
+ }
1185
+ else {
1186
+ analyze_1.logger.error(`Class declaration not found for ${inheritedClassOrInterface.getText()}.`);
1187
+ superClass = this.createOrGetFamixClassStub(inheritedClassOrInterface);
1188
+ }
1189
+ }
1190
+ else if (heritageClause.getText().startsWith("implements") && baseClassOrInterface instanceof ts_morph_1.ClassDeclaration // class implements interface
1191
+ || (heritageClause.getText().startsWith("extends") && baseClassOrInterface instanceof ts_morph_1.InterfaceDeclaration)) { // interface extends interface
1192
+ const interfaceOrClassDeclaration = getInterfaceOrClassDeclarationFromExpression(inheritedClassOrInterface);
1193
+ if (interfaceOrClassDeclaration !== undefined && interfaceOrClassDeclaration instanceof ts_morph_1.InterfaceDeclaration) {
1194
+ superClass = this.createOrGetFamixInterface(interfaceOrClassDeclaration);
1195
+ }
1196
+ else {
1197
+ analyze_1.logger.error(`Interface declaration not found for ${inheritedClassOrInterface.getText()}.`);
1198
+ superClass = this.createOrGetFamixInterfaceStub(inheritedClassOrInterface);
1199
+ }
1200
+ }
1201
+ else {
1202
+ // throw new Error(`Parent of ${inheritedClassOrInterface.getText()} is not a class or an interface.`);
1203
+ analyze_1.logger.error(`Parent of ${inheritedClassOrInterface.getText()} is not a class or an interface.`);
1204
+ superClass = this.createOrGetFamixInterfaceStub(inheritedClassOrInterface);
1205
+ }
1200
1206
  }
1201
1207
  else {
1202
- throw new Error(`Interface declaration not found for ${inhClass.getText()}.`);
1208
+ throw new Error(`Heritage clause not found for ${inheritedClassOrInterface.getText()}.`);
1203
1209
  }
1204
1210
  }
1205
- this.fmxElementObjectMap.set(superClass, inhClass);
1206
- this.makeFamixIndexFileAnchor(inhClass, superClass);
1211
+ this.fmxElementObjectMap.set(superClass, inheritedClassOrInterface);
1212
+ this.makeFamixIndexFileAnchor(inheritedClassOrInterface, superClass);
1207
1213
  this.famixRep.addElement(superClass);
1208
1214
  fmxInheritance.subclass = subClass;
1209
1215
  fmxInheritance.superclass = superClass;
@@ -1212,6 +1218,42 @@ class EntityDictionary {
1212
1218
  // We don't map inheritance to the source code element because there are two elements (super, sub)
1213
1219
  // this.fmxElementObjectMap.set(fmxInheritance, null);
1214
1220
  }
1221
+ createOrGetFamixClassStub(unresolvedInheritedClass) {
1222
+ // make a FQN for the stub
1223
+ const fqn = FQNFunctions.getFQNUnresolvedInheritedClassOrInterface(unresolvedInheritedClass);
1224
+ analyze_1.logger.debug(`createOrGetFamixClassStub: fqn: ${fqn}`);
1225
+ const fmxClass = this.famixRep.getFamixEntityByFullyQualifiedName(fqn);
1226
+ if (fmxClass) {
1227
+ return fmxClass;
1228
+ }
1229
+ else {
1230
+ const stub = new Famix.Class();
1231
+ stub.name = unresolvedInheritedClass.getText();
1232
+ stub.isStub = true;
1233
+ stub.fullyQualifiedName = fqn;
1234
+ this.famixRep.addElement(stub);
1235
+ this.fmxElementObjectMap.set(stub, unresolvedInheritedClass);
1236
+ return stub;
1237
+ }
1238
+ }
1239
+ createOrGetFamixInterfaceStub(unresolvedInheritedInterface) {
1240
+ // make a FQN for the stub
1241
+ const fqn = FQNFunctions.getFQNUnresolvedInheritedClassOrInterface(unresolvedInheritedInterface);
1242
+ analyze_1.logger.debug(`createOrGetFamixInterfaceStub: fqn: ${fqn}`);
1243
+ const fmxInterface = this.famixRep.getFamixEntityByFullyQualifiedName(fqn);
1244
+ if (fmxInterface) {
1245
+ return fmxInterface;
1246
+ }
1247
+ else {
1248
+ const stub = new Famix.Interface();
1249
+ stub.name = unresolvedInheritedInterface.getText();
1250
+ stub.isStub = true;
1251
+ stub.fullyQualifiedName = fqn;
1252
+ this.famixRep.addElement(stub);
1253
+ this.fmxElementObjectMap.set(stub, unresolvedInheritedInterface);
1254
+ return stub;
1255
+ }
1256
+ }
1215
1257
  createFamixImportClause(importedEntity, importingEntity) {
1216
1258
  const fmxImportClause = new Famix.ImportClause();
1217
1259
  fmxImportClause.importedEntity = importedEntity;
@@ -1234,7 +1276,8 @@ class EntityDictionary {
1234
1276
  if (importDeclaration && this.fmxImportClauseMap.has(importDeclaration)) {
1235
1277
  const rImportClause = this.fmxImportClauseMap.get(importDeclaration);
1236
1278
  if (rImportClause) {
1237
- return; // don't do anything
1279
+ analyze_1.logger.debug(`Import clause ${importElement.getText()} already exists in map, skipping.`);
1280
+ return;
1238
1281
  }
1239
1282
  else {
1240
1283
  throw new Error(`Import clause ${importElement.getText()} is not found in the import clause map.`);
@@ -1246,21 +1289,19 @@ class EntityDictionary {
1246
1289
  let importedEntityName;
1247
1290
  const absolutePathProject = this.famixRep.getAbsolutePath();
1248
1291
  const absolutePath = path_1.default.normalize(moduleSpecifierFilePath);
1249
- // convert the path and remove any windows backslashes introduced by path.normalize
1250
1292
  analyze_1.logger.debug(`createFamixImportClause: absolutePath: ${absolutePath}`);
1251
1293
  analyze_1.logger.debug(`createFamixImportClause: convertToRelativePath: ${this.convertToRelativePath(absolutePath, absolutePathProject)}`);
1252
1294
  const pathInProject = this.convertToRelativePath(absolutePath, absolutePathProject).replace(/\\/g, "/");
1253
1295
  analyze_1.logger.debug(`createFamixImportClause: pathInProject: ${pathInProject}`);
1254
1296
  let pathName = "{" + pathInProject + "}.";
1255
1297
  analyze_1.logger.debug(`createFamixImportClause: pathName: ${pathName}`);
1256
- // Named imports, e.g. import { ClassW } from "./complexExportModule";
1257
- // Start with simple import clause (without referring to the actual variable)
1258
1298
  if (importDeclaration instanceof ts_morph_1.ImportDeclaration
1259
1299
  && importElement instanceof ts_morph_1.ImportSpecifier) {
1260
1300
  importedEntityName = importElement.getName();
1261
1301
  pathName = pathName + importedEntityName;
1262
1302
  if (isInExports) {
1263
1303
  importedEntity = this.famixRep.getFamixEntityByFullyQualifiedName(pathName);
1304
+ analyze_1.logger.debug(`Found exported entity: ${pathName}`);
1264
1305
  }
1265
1306
  if (importedEntity === undefined) {
1266
1307
  importedEntity = new Famix.NamedEntity();
@@ -1268,39 +1309,38 @@ class EntityDictionary {
1268
1309
  if (!isInExports) {
1269
1310
  importedEntity.isStub = true;
1270
1311
  }
1271
- // logger.debug(`createFamixImportClause: Creating named entity ${importedEntityName} with FQN ${pathName}`);
1272
- // importedEntity.fullyQualifiedName = pathName;
1312
+ analyze_1.logger.debug(`Creating named entity ${importedEntityName} for ImportSpecifier ${importElement.getText()}`);
1273
1313
  initFQN(importElement, importedEntity);
1314
+ analyze_1.logger.debug(`Assigned FQN to entity: ${importedEntity.fullyQualifiedName}`);
1274
1315
  this.makeFamixIndexFileAnchor(importElement, importedEntity);
1275
- // must add entity to repository
1276
1316
  this.famixRep.addElement(importedEntity);
1317
+ analyze_1.logger.debug(`Added entity to repository: ${importedEntity.fullyQualifiedName}`);
1277
1318
  }
1278
1319
  }
1279
- // handle import equals declarations, e.g. import myModule = require("./complexExportModule");
1280
- // TypeScript can't determine the type of the imported module, so we create a Module entity
1281
1320
  else if (importDeclaration instanceof ts_morph_1.ImportEqualsDeclaration) {
1282
1321
  importedEntityName = importDeclaration?.getName();
1283
1322
  pathName = pathName + importedEntityName;
1284
1323
  importedEntity = new Famix.StructuralEntity();
1285
1324
  importedEntity.name = importedEntityName;
1286
1325
  initFQN(importDeclaration, importedEntity);
1326
+ analyze_1.logger.debug(`Assigned FQN to ImportEquals entity: ${importedEntity.fullyQualifiedName}`);
1287
1327
  this.makeFamixIndexFileAnchor(importElement, importedEntity);
1288
- // importedEntity.fullyQualifiedName = pathName;
1289
- const anyType = this.createOrGetFamixType('any', importDeclaration);
1328
+ const anyType = this.createOrGetFamixType('any', undefined, importDeclaration);
1290
1329
  importedEntity.declaredType = anyType;
1291
1330
  }
1292
- else { // default imports, e.g. import ClassW from "./complexExportModule";
1331
+ else {
1293
1332
  importedEntityName = importElement.getText();
1294
1333
  pathName = pathName + (isDefaultExport ? "defaultExport" : "namespaceExport");
1295
1334
  importedEntity = new Famix.NamedEntity();
1296
1335
  importedEntity.name = importedEntityName;
1297
- // importedEntity.fullyQualifiedName = pathName;
1298
1336
  initFQN(importElement, importedEntity);
1337
+ analyze_1.logger.debug(`Assigned FQN to default/namespace entity: ${importedEntity.fullyQualifiedName}`);
1299
1338
  this.makeFamixIndexFileAnchor(importElement, importedEntity);
1300
1339
  }
1301
- // I don't think it should be added to the repository if it exists already
1302
- if (!isInExports)
1340
+ if (!isInExports) {
1303
1341
  this.famixRep.addElement(importedEntity);
1342
+ analyze_1.logger.debug(`Added non-exported entity to repository: ${importedEntity.fullyQualifiedName}`);
1343
+ }
1304
1344
  const importerFullyQualifiedName = FQNFunctions.getFQN(importer);
1305
1345
  const fmxImporter = this.famixRep.getFamixEntityByFullyQualifiedName(importerFullyQualifiedName);
1306
1346
  fmxImportClause.importingEntity = fmxImporter;
@@ -1311,7 +1351,7 @@ class EntityDictionary {
1311
1351
  else {
1312
1352
  fmxImportClause.moduleSpecifier = importDeclaration?.getModuleSpecifierValue();
1313
1353
  }
1314
- analyze_1.logger.debug(`createFamixImportClause: ${fmxImportClause.importedEntity?.name} (of type ${Helpers.getSubTypeName(fmxImportClause.importedEntity)}) is imported by ${fmxImportClause.importingEntity?.name}`);
1354
+ analyze_1.logger.debug(`ImportClause: ${fmxImportClause.importedEntity?.name} (type=${Helpers.getSubTypeName(fmxImportClause.importedEntity)}) imported by ${fmxImportClause.importingEntity?.name}`);
1315
1355
  fmxImporter.addOutgoingImport(fmxImportClause);
1316
1356
  this.famixRep.addElement(fmxImportClause);
1317
1357
  if (importDeclaration) {
@@ -1361,7 +1401,7 @@ class EntityDictionary {
1361
1401
  catch (error) {
1362
1402
  analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for return type of function: ${functionName}. Continuing...`);
1363
1403
  }
1364
- const fmxType = this.createOrGetFamixType(functionTypeName, arrowFunction);
1404
+ const fmxType = this.createOrGetFamixType(functionTypeName, arrowFunction.getReturnType(), arrowFunction);
1365
1405
  fmxArrowFunction.declaredType = fmxType;
1366
1406
  fmxArrowFunction.numberOfLinesOfCode = arrowFunction.getEndLineNumber() - arrowFunction.getStartLineNumber();
1367
1407
  const parameters = arrowFunction.getParameters();
@@ -1383,282 +1423,283 @@ class EntityDictionary {
1383
1423
  * @param cls A class
1384
1424
  * @returns The Famix model of the concretisation
1385
1425
  */
1386
- // public createFamixConcretisation(conEntity : Famix.ParametricClass | Famix.ParametricInterface | Famix.ParametricFunction | Famix.ParametricMethod ,genEntity : Famix.ParametricClass | Famix.ParametricInterface | Famix.ParametricFunction | Famix.ParametricMethod): Famix.Concretisation {
1387
- // const fmxConcretisation : Famix.Concretisation = new Famix.Concretisation();
1388
- // fmxConcretisation.concreteEntity = conEntity;
1389
- // fmxConcretisation.genericEntity = genEntity;
1390
- // // this.fmxElementObjectMap.set(fmxConcretisation,null);
1391
- // this.famixRep.addElement(fmxConcretisation);
1392
- // const parameterConcretisation = this.createFamixParameterConcretisation(fmxConcretisation);
1393
- // return fmxConcretisation;
1394
- // }
1426
+ createFamixConcretisation(conEntity, genEntity) {
1427
+ const fmxConcretisation = new Famix.Concretisation();
1428
+ fmxConcretisation.concreteEntity = conEntity;
1429
+ fmxConcretisation.genericEntity = genEntity;
1430
+ // this.fmxElementObjectMap.set(fmxConcretisation,null);
1431
+ this.famixRep.addElement(fmxConcretisation);
1432
+ // const parameterConcretisation = this.createFamixParameterConcretisation(fmxConcretisation);
1433
+ return fmxConcretisation;
1434
+ }
1395
1435
  /**
1396
1436
  * Creates a Famix concretisation
1397
1437
  * @param concretisation A FamixConcretisation
1398
1438
  * @returns The Famix model of the ParameterConcrestisation
1399
1439
  */
1400
- // public createFamixParameterConcretisation(concretisation: Famix.Concretisation): Famix.ParameterConcretisation | undefined{
1401
- // const conClass = concretisation.concreteEntity;
1402
- // const genClass = concretisation.genericEntity;
1403
- // logger.debug(`Creating parameter concretisation between ${conClass.fullyQualifiedName} and ${genClass.fullyQualifiedName}`);
1404
- // const parameterConcretisations = this.famixRep._getAllEntitiesWithType("ParameterConcretisation") as Set<Famix.ParameterConcretisation>;
1405
- // const concreteParameters = conClass.concreteParameters;
1406
- // const genericParameters = genClass.genericParameters;
1407
- // let conClassTypeParametersIterator = concreteParameters.values();
1408
- // let genClassTypeParametersIterator = genericParameters.values();
1409
- // let fmxParameterConcretisation : Famix.ParameterConcretisation | undefined = undefined;
1410
- // for (let i = 0; i < genericParameters.size; i++) {
1411
- // const conClassTypeParameter = conClassTypeParametersIterator.next().value as Famix.ParameterType;
1412
- // const genClassTypeParameter = genClassTypeParametersIterator.next().value as Famix.ParameterType;
1413
- // let createParameterConcretisation : boolean = true;
1414
- // if(conClassTypeParameter && genClassTypeParameter && conClassTypeParameter.name != genClassTypeParameter.name){
1415
- // parameterConcretisations.forEach((param : Famix.ParameterConcretisation) => {
1416
- // if (conClassTypeParameter.name == param.concreteParameter.name && genClassTypeParameter.name == param.genericParameter.name) {
1417
- // createParameterConcretisation = false;
1418
- // fmxParameterConcretisation = param;
1419
- // }
1420
- // })
1421
- // if (createParameterConcretisation) {
1422
- // fmxParameterConcretisation = new Famix.ParameterConcretisation();
1423
- // fmxParameterConcretisation.genericParameter = genClassTypeParameter;
1424
- // fmxParameterConcretisation.concreteParameter = conClassTypeParameter;
1425
- // fmxParameterConcretisation.addConcretisation(concretisation);
1426
- // // this.fmxElementObjectMap.set(fmxParameterConcretisation,null);
1427
- // } else {
1428
- // if (!fmxParameterConcretisation) {
1429
- // throw new Error(`fmxParameterConcretisation was undefined for concretisation with generic parameter ${genClassTypeParameter.name} and concrete parameter ${conClassTypeParameter.name}`);
1430
- // }
1431
- // fmxParameterConcretisation.addConcretisation(concretisation);
1432
- // }
1433
- // this.famixRep.addElement(fmxParameterConcretisation);
1434
- // }
1435
- // }
1436
- // if (!fmxParameterConcretisation) {
1437
- // logger.error(`fmxParameterConcretisation was undefined for concretisation with concrete entity ${conClass.fullyQualifiedName} and generic entity ${genClass.fullyQualifiedName}`);
1438
- // }
1439
- // return fmxParameterConcretisation;
1440
- // }
1440
+ createFamixParameterConcretisation(concretisation) {
1441
+ const conClass = concretisation.concreteEntity;
1442
+ const genClass = concretisation.genericEntity;
1443
+ analyze_1.logger.debug(`Creating parameter concretisation between ${conClass.fullyQualifiedName} and ${genClass.fullyQualifiedName}`);
1444
+ const parameterConcretisations = this.famixRep._getAllEntitiesWithType("ParameterConcretisation");
1445
+ const concreteParameters = conClass.concreteParameters;
1446
+ const genericParameters = genClass.genericParameters;
1447
+ const conClassTypeParametersIterator = concreteParameters.values();
1448
+ const genClassTypeParametersIterator = genericParameters.values();
1449
+ let fmxParameterConcretisation = undefined;
1450
+ for (let i = 0; i < genericParameters.size; i++) {
1451
+ const conClassTypeParameter = conClassTypeParametersIterator.next().value;
1452
+ const genClassTypeParameter = genClassTypeParametersIterator.next().value;
1453
+ let createParameterConcretisation = true;
1454
+ if (conClassTypeParameter && genClassTypeParameter && conClassTypeParameter.name != genClassTypeParameter.name) {
1455
+ parameterConcretisations.forEach((param) => {
1456
+ if (conClassTypeParameter.name == param.concreteParameter.name && genClassTypeParameter.name == param.genericParameter.name) {
1457
+ createParameterConcretisation = false;
1458
+ fmxParameterConcretisation = param;
1459
+ }
1460
+ });
1461
+ if (createParameterConcretisation) {
1462
+ fmxParameterConcretisation = new Famix.ParameterConcretisation();
1463
+ fmxParameterConcretisation.genericParameter = genClassTypeParameter;
1464
+ fmxParameterConcretisation.concreteParameter = conClassTypeParameter;
1465
+ fmxParameterConcretisation.addConcretisation(concretisation);
1466
+ // this.fmxElementObjectMap.set(fmxParameterConcretisation,null);
1467
+ }
1468
+ else {
1469
+ if (!fmxParameterConcretisation) {
1470
+ throw new Error(`fmxParameterConcretisation was undefined for concretisation with generic parameter ${genClassTypeParameter.name} and concrete parameter ${conClassTypeParameter.name}`);
1471
+ }
1472
+ fmxParameterConcretisation.addConcretisation(concretisation);
1473
+ }
1474
+ this.famixRep.addElement(fmxParameterConcretisation);
1475
+ }
1476
+ }
1477
+ if (!fmxParameterConcretisation) {
1478
+ analyze_1.logger.error(`fmxParameterConcretisation was undefined for concretisation with concrete entity ${conClass.fullyQualifiedName} and generic entity ${genClass.fullyQualifiedName}`);
1479
+ }
1480
+ return fmxParameterConcretisation;
1481
+ }
1441
1482
  /**
1442
1483
  * Creates a Famix concretisation between two classes or two interfaces
1443
1484
  * @param element A class or an Interface
1444
1485
  */
1445
- // public createFamixConcretisationClassOrInterfaceSpecialisation(element: ClassDeclaration | InterfaceDeclaration){
1446
- // const superEntity = element.getExtends();
1447
- // let superEntityArray;
1448
- // if (superEntity){
1449
- // superEntityArray = Array.isArray(superEntity) ? superEntity : [superEntity];
1450
- // }
1451
- // if (superEntityArray && superEntityArray.length > 0) {
1452
- // superEntityArray.forEach(entity => {
1453
- // let entityIsGeneric;
1454
- // const superEntitySymbol = entity.getExpression().getSymbolOrThrow();
1455
- // let superEntityDeclaration;
1456
- // if (superEntity instanceof ExpressionWithTypeArguments) {
1457
- // superEntityDeclaration = superEntitySymbol.getDeclarations()[0].asKind(ts.SyntaxKind.ClassDeclaration);
1458
- // } else {
1459
- // superEntityDeclaration = superEntitySymbol.getDeclarations()[0].asKind(ts.SyntaxKind.InterfaceDeclaration);
1460
- // }
1461
- // if (superEntityDeclaration) {
1462
- // entityIsGeneric = superEntityDeclaration.getTypeParameters().length > 0;
1463
- // }
1464
- // if (entityIsGeneric) {
1465
- // let EntityDeclaration;
1466
- // let genEntity;
1467
- // if (superEntity instanceof ExpressionWithTypeArguments) {
1468
- // EntityDeclaration = entity.getExpression().getSymbol()?.getDeclarations()[0] as ClassDeclaration;
1469
- // genEntity = this.createOrGetFamixClass(EntityDeclaration) as Famix.ParametricClass;
1470
- // } else {
1471
- // EntityDeclaration = entity.getExpression().getSymbol()?.getDeclarations()[0] as InterfaceDeclaration;
1472
- // genEntity = this.createOrGetFamixInterface(EntityDeclaration) as Famix.ParametricInterface;
1473
- // }
1474
- // const genParams = EntityDeclaration.getTypeParameters().map((param) => param.getText());
1475
- // const args = element.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments()
1476
- // const conParams = element.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments().map((param) => param.getText());
1477
- // if (!Helpers.arraysAreEqual(conParams,genParams)) {
1478
- // let conEntity;
1479
- // conEntity = this.createOrGetFamixConcreteElement(genEntity,EntityDeclaration,args);
1480
- // const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation") as Set<Famix.Concretisation>;
1481
- // let createConcretisation : boolean = true;
1482
- // concretisations.forEach((conc : Famix.Concretisation) => {
1483
- // if (genEntity.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == conEntity.fullyQualifiedName){
1484
- // createConcretisation = false;
1485
- // }
1486
- // });
1487
- // if (createConcretisation) {
1488
- // const fmxConcretisation : Famix.Concretisation = this.createFamixConcretisation(conEntity,genEntity);
1489
- // }
1490
- // }
1491
- // }
1492
- // });
1493
- // }
1494
- // // TODO: This function seems unfinished
1495
- // }
1486
+ createFamixConcretisationClassOrInterfaceSpecialisation(element) {
1487
+ const superEntity = element.getExtends();
1488
+ let superEntityArray;
1489
+ if (superEntity) {
1490
+ superEntityArray = Array.isArray(superEntity) ? superEntity : [superEntity];
1491
+ }
1492
+ if (superEntityArray && superEntityArray.length > 0) {
1493
+ superEntityArray.forEach(entity => {
1494
+ let entityIsGeneric;
1495
+ const superEntitySymbol = entity.getExpression().getSymbolOrThrow();
1496
+ let superEntityDeclaration;
1497
+ if (superEntity instanceof ts_morph_1.ExpressionWithTypeArguments) {
1498
+ superEntityDeclaration = superEntitySymbol.getDeclarations()[0].asKind(ts_morph_1.ts.SyntaxKind.ClassDeclaration);
1499
+ }
1500
+ else {
1501
+ superEntityDeclaration = superEntitySymbol.getDeclarations()[0].asKind(ts_morph_1.ts.SyntaxKind.InterfaceDeclaration);
1502
+ }
1503
+ if (superEntityDeclaration) {
1504
+ entityIsGeneric = superEntityDeclaration.getTypeParameters().length > 0;
1505
+ }
1506
+ if (entityIsGeneric) {
1507
+ let EntityDeclaration;
1508
+ let genEntity;
1509
+ if (superEntity instanceof ts_morph_1.ExpressionWithTypeArguments) {
1510
+ EntityDeclaration = entity.getExpression().getSymbol()?.getDeclarations()[0];
1511
+ genEntity = this.createOrGetFamixClass(EntityDeclaration);
1512
+ }
1513
+ else {
1514
+ EntityDeclaration = entity.getExpression().getSymbol()?.getDeclarations()[0];
1515
+ genEntity = this.createOrGetFamixInterface(EntityDeclaration);
1516
+ }
1517
+ const genParams = EntityDeclaration.getTypeParameters().map((param) => param.getText());
1518
+ const args = element.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments();
1519
+ const conParams = element.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments().map((param) => param.getText());
1520
+ if (!Helpers.arraysAreEqual(conParams, genParams)) {
1521
+ const conEntity = this.createOrGetFamixConcreteElement(genEntity, EntityDeclaration, args);
1522
+ const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
1523
+ let createConcretisation = true;
1524
+ concretisations.forEach((conc) => {
1525
+ if (genEntity.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == conEntity.fullyQualifiedName) {
1526
+ createConcretisation = false;
1527
+ }
1528
+ });
1529
+ if (createConcretisation) {
1530
+ const fmxConcretisation = this.createFamixConcretisation(conEntity, genEntity);
1531
+ }
1532
+ }
1533
+ }
1534
+ });
1535
+ }
1536
+ // TODO: This function seems unfinished
1537
+ }
1496
1538
  /**
1497
1539
  * Creates a Famix concretisation between a class and its instanciations
1498
1540
  * @param cls A class
1499
1541
  */
1500
- // public createFamixConcretisationGenericInstantiation(cls: ClassDeclaration){
1501
- // const isGeneric = cls.getTypeParameters().length > 0;
1502
- // if (isGeneric) {
1503
- // const instances = cls.getSourceFile().getDescendantsOfKind(ts.SyntaxKind.NewExpression)
1504
- // .filter(newExpr => {
1505
- // const expression = newExpr.getExpression();
1506
- // return expression.getText() === cls.getName();
1507
- // });
1508
- // instances.forEach(instance => {
1509
- // const instanceIsGeneric = instance.getTypeArguments().length > 0;
1510
- // if (instanceIsGeneric) {
1511
- // const conParams = instance.getTypeArguments().map((param) => param.getText());
1512
- // const genEntity = this.createOrGetFamixClass(cls) as Famix.ParametricClass;
1513
- // const genParams = cls.getTypeParameters().map((param) => param.getText());
1514
- // if (!Helpers.arraysAreEqual(conParams,genParams)) {
1515
- // let conEntity;
1516
- // conEntity = this.createOrGetFamixConcreteElement(genEntity,cls,instance.getTypeArguments());
1517
- // const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation") as Set<Famix.Concretisation>;
1518
- // let createConcretisation : boolean = true;
1519
- // concretisations.forEach((conc : Famix.Concretisation) => {
1520
- // if (genEntity.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == conEntity.fullyQualifiedName){
1521
- // createConcretisation = false;
1522
- // }
1523
- // });
1524
- // if (createConcretisation) {
1525
- // const fmxConcretisation : Famix.Concretisation = this.createFamixConcretisation(conEntity,genEntity);
1526
- // }
1527
- // }
1528
- // }
1529
- // })
1530
- // }
1531
- // // TODO: This function seems unfinished
1532
- // }
1542
+ createFamixConcretisationGenericInstantiation(cls) {
1543
+ const isGeneric = cls.getTypeParameters().length > 0;
1544
+ if (isGeneric) {
1545
+ const instances = cls.getSourceFile().getDescendantsOfKind(ts_morph_1.ts.SyntaxKind.NewExpression)
1546
+ .filter(newExpr => {
1547
+ const expression = newExpr.getExpression();
1548
+ return expression.getText() === cls.getName();
1549
+ });
1550
+ instances.forEach(instance => {
1551
+ const instanceIsGeneric = instance.getTypeArguments().length > 0;
1552
+ if (instanceIsGeneric) {
1553
+ const conParams = instance.getTypeArguments().map((param) => param.getText());
1554
+ const genEntity = this.createOrGetFamixClass(cls);
1555
+ const genParams = cls.getTypeParameters().map((param) => param.getText());
1556
+ if (!Helpers.arraysAreEqual(conParams, genParams)) {
1557
+ const conEntity = this.createOrGetFamixConcreteElement(genEntity, cls, instance.getTypeArguments());
1558
+ const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
1559
+ let createConcretisation = true;
1560
+ concretisations.forEach((conc) => {
1561
+ if (genEntity.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == conEntity.fullyQualifiedName) {
1562
+ createConcretisation = false;
1563
+ }
1564
+ });
1565
+ if (createConcretisation) {
1566
+ const fmxConcretisation = this.createFamixConcretisation(conEntity, genEntity);
1567
+ }
1568
+ }
1569
+ }
1570
+ });
1571
+ }
1572
+ // TODO: This function seems unfinished
1573
+ }
1533
1574
  /**
1534
1575
  * Creates a Famix concretisation between a class and its instanciations
1535
1576
  * @param func A function
1536
1577
  */
1537
- // public createFamixConcretisationFunctionInstantiation(element: FunctionDeclaration | MethodDeclaration){
1538
- // const isGeneric = element.getTypeParameters().length > 0;
1539
- // if (isGeneric) {
1540
- // const genParams = element.getTypeParameters().map(param => param.getText());
1541
- // const uses = element.findReferencesAsNodes();
1542
- // uses.forEach(usage => {
1543
- // let currentNode: Node | undefined = usage;
1544
- // while (currentNode) {
1545
- // if (currentNode.getKind() === SyntaxKind.CallExpression) {
1546
- // const callExpression = currentNode.asKind(SyntaxKind.CallExpression);
1547
- // if (!callExpression) {
1548
- // throw new Error(`CallExpression not found for ${currentNode.getText()}`);
1549
- // }
1550
- // const instanceIsGeneric = callExpression.getTypeArguments().length > 0;
1551
- // if (instanceIsGeneric) {
1552
- // const args = callExpression.getTypeArguments();
1553
- // const conParams = callExpression.getTypeArguments().map(param => param.getText());
1554
- // if (!Helpers.arraysAreEqual(conParams,genParams)) {
1555
- // let genElement;
1556
- // if(element instanceof FunctionDeclaration){
1557
- // genElement = this.createOrGetFamixFunction(element, {}) as Famix.ParametricFunction;
1558
- // } else {
1559
- // genElement = this.createOrGetFamixMethod(element, {}) as Famix.ParametricMethod;
1560
- // }
1561
- // let concElement;
1562
- // concElement = this.createOrGetFamixConcreteElement(genElement,element,args);
1563
- // const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation") as Set<Famix.Concretisation>;
1564
- // let createConcretisation : boolean = true;
1565
- // concretisations.forEach((conc : Famix.Concretisation) => {
1566
- // if (genElement.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == concElement.fullyQualifiedName){
1567
- // createConcretisation = false;
1568
- // }
1569
- // });
1570
- // if (createConcretisation) {
1571
- // const fmxConcretisation : Famix.Concretisation = this.createFamixConcretisation(concElement,genElement);
1572
- // }
1573
- // }
1574
- // }
1575
- // break;
1576
- // }
1577
- // // Remonter à l'élément parent (utile si le nœud de référence est un enfant)
1578
- // currentNode = currentNode.getParent();
1579
- // }
1580
- // });
1581
- // }
1582
- // }
1578
+ createFamixConcretisationFunctionInstantiation(element) {
1579
+ const isGeneric = element.getTypeParameters().length > 0;
1580
+ if (isGeneric) {
1581
+ const genParams = element.getTypeParameters().map(param => param.getText());
1582
+ const uses = element.findReferencesAsNodes();
1583
+ uses.forEach(usage => {
1584
+ let currentNode = usage;
1585
+ while (currentNode) {
1586
+ if (currentNode.getKind() === ts_morph_1.SyntaxKind.CallExpression) {
1587
+ const callExpression = currentNode.asKind(ts_morph_1.SyntaxKind.CallExpression);
1588
+ if (!callExpression) {
1589
+ throw new Error(`CallExpression not found for ${currentNode.getText()}`);
1590
+ }
1591
+ const instanceIsGeneric = callExpression.getTypeArguments().length > 0;
1592
+ if (instanceIsGeneric) {
1593
+ const args = callExpression.getTypeArguments();
1594
+ const conParams = callExpression.getTypeArguments().map(param => param.getText());
1595
+ if (!Helpers.arraysAreEqual(conParams, genParams)) {
1596
+ let genElement;
1597
+ if (element instanceof ts_morph_1.FunctionDeclaration) {
1598
+ genElement = this.createOrGetFamixFunction(element, {});
1599
+ }
1600
+ else {
1601
+ genElement = this.createOrGetFamixMethod(element, {});
1602
+ }
1603
+ const concElement = this.createOrGetFamixConcreteElement(genElement, element, args);
1604
+ const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
1605
+ let createConcretisation = true;
1606
+ concretisations.forEach((conc) => {
1607
+ if (genElement.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == concElement.fullyQualifiedName) {
1608
+ createConcretisation = false;
1609
+ }
1610
+ });
1611
+ if (createConcretisation) {
1612
+ const fmxConcretisation = this.createFamixConcretisation(concElement, genElement);
1613
+ }
1614
+ }
1615
+ }
1616
+ break;
1617
+ }
1618
+ // Remonter à l'élément parent (utile si le nœud de référence est un enfant)
1619
+ currentNode = currentNode.getParent();
1620
+ }
1621
+ });
1622
+ }
1623
+ }
1583
1624
  /**
1584
1625
  * Creates a Famix concretisation between a class and an interface
1585
1626
  * @param cls A class
1586
1627
  */
1587
- // public createFamixConcretisationInterfaceClass(cls: ClassDeclaration){
1588
- // const superInterfaces = cls.getImplements();
1589
- // superInterfaces.forEach(interfaceType => {
1590
- // const interfaceIsGeneric = interfaceType.getTypeArguments().length>0;
1591
- // if (interfaceIsGeneric) {
1592
- // const interfaceDeclaration = interfaceType.getExpression().getSymbol()?.getDeclarations()[0] as InterfaceDeclaration;
1593
- // const genParams = interfaceDeclaration.getTypeParameters().map((param) => param.getText());
1594
- // const conParams = cls.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments().map((param) => param.getText());
1595
- // const args = cls.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments();
1596
- // if (!Helpers.arraysAreEqual(conParams,genParams)) {
1597
- // const genInterface = this.createOrGetFamixInterface(interfaceDeclaration) as Famix.ParametricInterface;
1598
- // const conInterface = this.createOrGetFamixConcreteElement(genInterface,interfaceDeclaration,args);
1599
- // const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation") as Set<Famix.Concretisation>;
1600
- // let createConcretisation : boolean = true;
1601
- // concretisations.forEach((conc : Famix.Concretisation) => {
1602
- // if (genInterface.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == conInterface.fullyQualifiedName){
1603
- // createConcretisation = false;
1604
- // }
1605
- // });
1606
- // if (createConcretisation) {
1607
- // const fmxConcretisation : Famix.Concretisation = this.createFamixConcretisation(conInterface,genInterface);
1608
- // }
1609
- // }
1610
- // }
1611
- // });
1612
- // }
1628
+ createFamixConcretisationInterfaceClass(cls) {
1629
+ const superInterfaces = cls.getImplements();
1630
+ superInterfaces.forEach(interfaceType => {
1631
+ const interfaceIsGeneric = interfaceType.getTypeArguments().length > 0;
1632
+ if (interfaceIsGeneric) {
1633
+ const interfaceDeclaration = interfaceType.getExpression().getSymbol()?.getDeclarations()[0];
1634
+ const genParams = interfaceDeclaration.getTypeParameters().map((param) => param.getText());
1635
+ const conParams = cls.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments().map((param) => param.getText());
1636
+ const args = cls.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments();
1637
+ if (!Helpers.arraysAreEqual(conParams, genParams)) {
1638
+ const genInterface = this.createOrGetFamixInterface(interfaceDeclaration);
1639
+ const conInterface = this.createOrGetFamixConcreteElement(genInterface, interfaceDeclaration, args);
1640
+ const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
1641
+ let createConcretisation = true;
1642
+ concretisations.forEach((conc) => {
1643
+ if (genInterface.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == conInterface.fullyQualifiedName) {
1644
+ createConcretisation = false;
1645
+ }
1646
+ });
1647
+ if (createConcretisation) {
1648
+ const fmxConcretisation = this.createFamixConcretisation(conInterface, genInterface);
1649
+ }
1650
+ }
1651
+ }
1652
+ });
1653
+ }
1613
1654
  /**
1614
1655
  * Creates a Famix concretisation between an interface and a Type
1615
1656
  * @param element A variable or a function
1616
1657
  * @param inter An interface
1617
1658
  */
1618
- // public createFamixConcretisationTypeInstanciation(element: InterfaceDeclaration | ClassDeclaration){
1619
- // const isGeneric = element.getTypeParameters().length > 0;
1620
- // if (isGeneric) {
1621
- // const genParams = element.getTypeParameters().map(param => param.getText());
1622
- // const uses = element.findReferencesAsNodes();
1623
- // uses.forEach(use => {
1624
- // let parentNode = use.getParent();
1625
- // while (parentNode) {
1626
- // if (parentNode.getKind() === SyntaxKind.TypeReference) {
1627
- // const typeReferenceNode = parentNode.asKind(SyntaxKind.TypeReference);
1628
- // if (!typeReferenceNode) {
1629
- // throw new Error(`TypeReferenceNode not found for ${parentNode.getText()}`);
1630
- // }
1631
- // const typeReferenceNodeIsGeneric = typeReferenceNode.getTypeArguments().length > 0;
1632
- // if (typeReferenceNodeIsGeneric) {}
1633
- // const args = typeReferenceNode.getTypeArguments();
1634
- // const conParams = typeReferenceNode.getTypeArguments().map(param => param.getText());
1635
- // if (!Helpers.arraysAreEqual(conParams,genParams)) {
1636
- // let genElement;
1637
- // if(element instanceof ClassDeclaration){
1638
- // genElement = this.createOrGetFamixClass(element) as Famix.ParametricClass;
1639
- // } else {
1640
- // genElement = this.createOrGetFamixInterface(element) as Famix.ParametricInterface;
1641
- // }
1642
- // let concElement;
1643
- // concElement = this.createOrGetFamixConcreteElement(genElement,element,args);
1644
- // const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation") as Set<Famix.Concretisation>;
1645
- // let createConcretisation : boolean = true;
1646
- // concretisations.forEach((conc : Famix.Concretisation) => {
1647
- // if (genElement.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == concElement.fullyQualifiedName){
1648
- // createConcretisation = false;
1649
- // }
1650
- // });
1651
- // if (createConcretisation) {
1652
- // const fmxConcretisation : Famix.Concretisation = this.createFamixConcretisation(concElement,genElement);
1653
- // }
1654
- // }
1655
- // break;
1656
- // }
1657
- // parentNode = parentNode.getParent();
1658
- // }
1659
- // });
1660
- // }
1661
- // }
1659
+ createFamixConcretisationTypeInstanciation(element) {
1660
+ const isGeneric = element.getTypeParameters().length > 0;
1661
+ if (isGeneric) {
1662
+ const genParams = element.getTypeParameters().map(param => param.getText());
1663
+ const uses = element.findReferencesAsNodes();
1664
+ uses.forEach(use => {
1665
+ let parentNode = use.getParent();
1666
+ while (parentNode) {
1667
+ if (parentNode.getKind() === ts_morph_1.SyntaxKind.TypeReference) {
1668
+ const typeReferenceNode = parentNode.asKind(ts_morph_1.SyntaxKind.TypeReference);
1669
+ if (!typeReferenceNode) {
1670
+ throw new Error(`TypeReferenceNode not found for ${parentNode.getText()}`);
1671
+ }
1672
+ const typeReferenceNodeIsGeneric = typeReferenceNode.getTypeArguments().length > 0;
1673
+ if (typeReferenceNodeIsGeneric) { }
1674
+ const args = typeReferenceNode.getTypeArguments();
1675
+ const conParams = typeReferenceNode.getTypeArguments().map(param => param.getText());
1676
+ if (!Helpers.arraysAreEqual(conParams, genParams)) {
1677
+ let genElement;
1678
+ if (element instanceof ts_morph_1.ClassDeclaration) {
1679
+ genElement = this.createOrGetFamixClass(element);
1680
+ }
1681
+ else {
1682
+ genElement = this.createOrGetFamixInterface(element);
1683
+ }
1684
+ const concElement = this.createOrGetFamixConcreteElement(genElement, element, args);
1685
+ const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
1686
+ let createConcretisation = true;
1687
+ concretisations.forEach((conc) => {
1688
+ if (genElement.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == concElement.fullyQualifiedName) {
1689
+ createConcretisation = false;
1690
+ }
1691
+ });
1692
+ if (createConcretisation) {
1693
+ const fmxConcretisation = this.createFamixConcretisation(concElement, genElement);
1694
+ }
1695
+ }
1696
+ break;
1697
+ }
1698
+ parentNode = parentNode.getParent();
1699
+ }
1700
+ });
1701
+ }
1702
+ }
1662
1703
  convertToRelativePath(absolutePath, absolutePathProject) {
1663
1704
  analyze_1.logger.debug(`convertToRelativePath: absolutePath: '${absolutePath}', absolutePathProject: '${absolutePathProject}'`);
1664
1705
  if (absolutePath.startsWith(absolutePathProject)) {
@@ -1679,6 +1720,7 @@ function isPrimitiveType(typeName) {
1679
1720
  typeName === "boolean" ||
1680
1721
  typeName === "bigint" ||
1681
1722
  typeName === "symbol" ||
1723
+ typeName === "unique symbol" ||
1682
1724
  typeName === "undefined" ||
1683
1725
  typeName === "null" ||
1684
1726
  typeName === "any" ||
@@ -1704,29 +1746,32 @@ function initFQN(sourceElement, famixElement) {
1704
1746
  }
1705
1747
  }
1706
1748
  function isTypeContext(sourceElement) {
1707
- return sourceElement instanceof ts_morph_1.ConstructorDeclaration
1708
- || sourceElement instanceof ts_morph_1.MethodDeclaration
1709
- || sourceElement instanceof ts_morph_1.FunctionDeclaration
1710
- || sourceElement instanceof ts_morph_1.FunctionExpression
1711
- || sourceElement instanceof ts_morph_1.ArrowFunction
1712
- ||
1713
- sourceElement instanceof ts_morph_1.ParameterDeclaration ||
1714
- sourceElement instanceof ts_morph_1.VariableDeclaration ||
1715
- sourceElement instanceof ts_morph_1.PropertyDeclaration ||
1716
- sourceElement instanceof ts_morph_1.PropertySignature ||
1717
- sourceElement instanceof ts_morph_1.TypeParameterDeclaration ||
1718
- sourceElement instanceof ts_morph_1.Identifier ||
1719
- sourceElement instanceof ts_morph_1.Decorator ||
1720
- sourceElement instanceof ts_morph_1.GetAccessorDeclaration ||
1721
- sourceElement instanceof ts_morph_1.SetAccessorDeclaration ||
1722
- sourceElement instanceof ts_morph_1.ImportSpecifier ||
1723
- sourceElement instanceof ts_morph_1.EnumDeclaration ||
1724
- sourceElement instanceof ts_morph_1.EnumMember ||
1725
- sourceElement instanceof ts_morph_1.TypeAliasDeclaration
1726
- || sourceElement instanceof ts_morph_1.ImportDeclaration
1727
- || sourceElement instanceof ts_morph_1.ExpressionWithTypeArguments;
1749
+ // Just keep the existing SyntaxKind set as it is
1750
+ const typeContextKinds = new Set([
1751
+ ts_morph_1.SyntaxKind.Constructor,
1752
+ ts_morph_1.SyntaxKind.MethodDeclaration,
1753
+ ts_morph_1.SyntaxKind.FunctionDeclaration,
1754
+ ts_morph_1.SyntaxKind.FunctionExpression,
1755
+ ts_morph_1.SyntaxKind.ArrowFunction,
1756
+ ts_morph_1.SyntaxKind.Parameter,
1757
+ ts_morph_1.SyntaxKind.VariableDeclaration,
1758
+ ts_morph_1.SyntaxKind.PropertyDeclaration,
1759
+ ts_morph_1.SyntaxKind.PropertySignature,
1760
+ ts_morph_1.SyntaxKind.TypeParameter,
1761
+ ts_morph_1.SyntaxKind.Identifier,
1762
+ ts_morph_1.SyntaxKind.Decorator,
1763
+ ts_morph_1.SyntaxKind.GetAccessor,
1764
+ ts_morph_1.SyntaxKind.SetAccessor,
1765
+ ts_morph_1.SyntaxKind.ImportSpecifier,
1766
+ ts_morph_1.SyntaxKind.EnumDeclaration,
1767
+ ts_morph_1.SyntaxKind.EnumMember,
1768
+ ts_morph_1.SyntaxKind.TypeAliasDeclaration,
1769
+ ts_morph_1.SyntaxKind.ImportDeclaration,
1770
+ ts_morph_1.SyntaxKind.ExpressionWithTypeArguments
1771
+ ]);
1772
+ return typeContextKinds.has(sourceElement.getKind());
1728
1773
  }
1729
- function getInterfaceDeclarationFromExpression(expression) {
1774
+ function getInterfaceOrClassDeclarationFromExpression(expression) {
1730
1775
  // Step 1: Get the type of the expression
1731
1776
  const type = expression.getType();
1732
1777
  // Step 2: Get the symbol associated with the type
@@ -1743,19 +1788,21 @@ function getInterfaceDeclarationFromExpression(expression) {
1743
1788
  }
1744
1789
  }
1745
1790
  // Step 3: Resolve the symbol to find the actual declaration
1746
- const interfaceDeclaration = resolveSymbolToInterfaceDeclaration(symbol);
1791
+ const interfaceDeclaration = resolveSymbolToInterfaceOrClassDeclaration(symbol);
1747
1792
  if (!interfaceDeclaration) {
1748
1793
  analyze_1.logger.error(`Interface declaration not found for ${expression.getText()}.`);
1749
1794
  }
1750
1795
  return interfaceDeclaration;
1751
1796
  }
1752
- function resolveSymbolToInterfaceDeclaration(symbol) {
1797
+ const lodash_1 = __importDefault(require("lodash"));
1798
+ function resolveSymbolToInterfaceOrClassDeclaration(symbol) {
1753
1799
  // Get the declarations associated with the symbol
1754
1800
  const declarations = symbol.getDeclarations();
1755
- // Filter for InterfaceDeclaration
1756
- const interfaceDeclaration = declarations.find(declaration => declaration instanceof ts_morph_1.InterfaceDeclaration);
1757
- if (interfaceDeclaration) {
1758
- return interfaceDeclaration;
1801
+ // Filter for InterfaceDeclaration or ClassDeclaration
1802
+ const interfaceOrClassDeclaration = declarations.find(declaration => declaration instanceof ts_morph_1.InterfaceDeclaration ||
1803
+ declaration instanceof ts_morph_1.ClassDeclaration);
1804
+ if (interfaceOrClassDeclaration) {
1805
+ return interfaceOrClassDeclaration;
1759
1806
  }
1760
1807
  // Handle imports: If the symbol is imported, resolve the import to find the actual declaration
1761
1808
  for (const declaration of declarations) {
@@ -1767,13 +1814,41 @@ function resolveSymbolToInterfaceDeclaration(symbol) {
1767
1814
  const exportedSymbols = moduleSpecifier.getExportSymbols();
1768
1815
  const exportedSymbol = exportedSymbols.find(symbol => symbol.getName() === importSpecifier.getName());
1769
1816
  if (exportedSymbol) {
1770
- return resolveSymbolToInterfaceDeclaration(exportedSymbol);
1817
+ return resolveSymbolToInterfaceOrClassDeclaration(exportedSymbol);
1771
1818
  }
1772
1819
  }
1773
1820
  }
1774
1821
  }
1775
1822
  return undefined;
1776
1823
  }
1824
+ function getPrimitiveTypeName(type) {
1825
+ const flags = type.compilerType.flags;
1826
+ if (flags & ts_morph_1.ts.TypeFlags.String)
1827
+ return "string";
1828
+ if (flags & ts_morph_1.ts.TypeFlags.Number)
1829
+ return "number";
1830
+ if (flags & ts_morph_1.ts.TypeFlags.Boolean)
1831
+ return "boolean";
1832
+ if (flags & ts_morph_1.ts.TypeFlags.BigInt)
1833
+ return "bigint";
1834
+ if (flags & ts_morph_1.ts.TypeFlags.UniqueESSymbol)
1835
+ return "unique symbol";
1836
+ if (flags & ts_morph_1.ts.TypeFlags.ESSymbol)
1837
+ return "symbol";
1838
+ if (flags & ts_morph_1.ts.TypeFlags.Undefined)
1839
+ return "undefined";
1840
+ if (flags & ts_morph_1.ts.TypeFlags.Null)
1841
+ return "null";
1842
+ if (flags & ts_morph_1.ts.TypeFlags.Void)
1843
+ return "void";
1844
+ if (flags & ts_morph_1.ts.TypeFlags.Never)
1845
+ return "never";
1846
+ if (flags & ts_morph_1.ts.TypeFlags.Any)
1847
+ return "any";
1848
+ if (flags & ts_morph_1.ts.TypeFlags.Unknown)
1849
+ return "unknown";
1850
+ return undefined;
1851
+ }
1777
1852
  // function oldGetInterfaceDeclarationFromExpression(expression: ExpressionWithTypeArguments): InterfaceDeclaration | undefined {
1778
1853
  // // Two cases:
1779
1854
  // // class A implements ImportedInterface, DeclaredInterface {}
@@ -1800,4 +1875,4 @@ function resolveSymbolToInterfaceDeclaration(symbol) {
1800
1875
  // }
1801
1876
  // return interfaceDeclaration;
1802
1877
  // }
1803
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW50aXR5RGljdGlvbmFyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9mYW1peF9mdW5jdGlvbnMvRW50aXR5RGljdGlvbmFyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7R0FJRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBbzBESCwwQ0FZQztBQTcwREQsdUNBQTZrQjtBQUM3a0IsOEVBQWdGO0FBQ2hGLGdFQUFrRDtBQUNsRCxvRUFBZ0U7QUFDaEUsd0NBQTRDO0FBQzVDLG9EQUFvRDtBQUNwRCxpRUFBaUU7QUFDakUsc0RBQXVEO0FBQ3ZELDREQUE4QztBQUM5QyxxREFBdUM7QUFDdkMsZ0RBQXdCO0FBZXhCLE1BQWEsZ0JBQWdCO0lBcUJ6QjtRQW5CTyxhQUFRLEdBQUcsSUFBSSxrQ0FBZSxFQUFFLENBQUM7UUFDaEMsZ0JBQVcsR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQyxDQUFDLDRDQUE0QztRQUMxRixnQkFBVyxHQUFHLElBQUksR0FBRyxFQUErQyxDQUFDLENBQUMsNERBQTREO1FBQ2xJLG9CQUFlLEdBQUcsSUFBSSxHQUFHLEVBQXVELENBQUMsQ0FBQyxnREFBZ0Q7UUFDbEksaUJBQVksR0FBRyxJQUFJLEdBQUcsRUFBbUMsQ0FBQyxDQUFDLGdEQUFnRDtRQUMzRyxlQUFVLEdBQUcsSUFBSSxHQUFHLEVBQTZDLENBQUMsQ0FBQyxrREFBa0Q7UUFDckgsZUFBVSxHQUFHLElBQUksR0FBRyxFQUE0RCxDQUFDLENBQUMsbURBQW1EO1FBQ3JJLHdCQUFtQixHQUFHLElBQUksR0FBRyxFQUErQixDQUFDLENBQUMscURBQXFEO1FBQ25ILDRCQUF1QixHQUFHLElBQUksR0FBOEYsQ0FBQyxDQUFDLCtDQUErQztRQUM3Syx3QkFBbUIsR0FBRyxJQUFJLEdBQWdDLENBQUMsQ0FBQywrQ0FBK0M7UUFDM0csb0JBQWUsR0FBRyxJQUFJLEdBQUcsRUFBeUMsQ0FBQyxDQUFDLDJD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LE9BQU8sbUNBQW1DLENBQUMsY0FBYyxDQUFDLENBQUM7Z0JBQy9ELENBQUM7WUFDTCxDQUFDO1FBQ0wsQ0FBQztJQUNMLENBQUM7SUFFRCxPQUFPLFNBQVMsQ0FBQztBQUNyQixDQUFDO0FBRUQsaUlBQWlJO0FBQ2pJLG9CQUFvQjtBQUNwQixvRUFBb0U7QUFDcEUseUNBQXlDO0FBRXpDLGdEQUFnRDtBQUNoRCxzRkFBc0Y7QUFFdEYscUJBQXFCO0FBQ3JCLDZJQUE2STtBQUM3SSx5RkFBeUY7QUFDekYsNkJBQTZCO0FBQzdCLG9GQUFvRjtBQUNwRixZQUFZO0FBQ1osMkNBQTJDO0FBQzNDLHlCQUF5QjtBQUN6QixnRkFBZ0Y7QUFDaEYsWUFBWTtBQUNaLFFBQVE7QUFFUixpRUFBaUU7QUFDakUscURBQXFEO0FBRXJELGlEQUFpRDtBQUNqRCxzSkFBc0o7QUFFdEosbUNBQW1DO0FBQ25DLDJGQUEyRjtBQUMzRixRQUFRO0FBRVIsbUNBQW1DO0FBQ25DLElBQUkiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcclxuICogYSBmdW5jdGlvbiBnZXRPckNyZWF0ZVhUeXBlIHRha2VzIGFyZ3VtZW50cyBuYW1lOiBzdHJpbmcgYW5kIGVsZW1lbnQ6IHRzLW1vcnBoLXR5cGUgYW5kIHJldHVybnMgYSBGYW1peC5UeXBlXHJcbiAqIFRoZSBnb2FsIGlzIHRvIGtlZXAgdHJhY2sgb2YgdGhlIHR5cGVzIChlLmcuLCBhIG1ldGhvZCdzIGRlZmluZWRUeXBlKSwgZm9yIHRoZSBtb2RlbC5cclxuICogVGhlIG5hbWUgZG9lc24ndCBuZWVkIHRvIGJlIGZ1bGx5IHF1YWxpZmllZCAoaXQncyB0aGUgbmFtZSB1c2VkIGluIHRoZSBzb3VyY2UgY29kZSwgb3IgdGhlIEZhbWl4IG1vZGVsKS5cclxuICovXHJcblxyXG5cclxuaW1wb3J0IHsgQ2xhc3NEZWNsYXJhdGlvbiwgQ29uc3RydWN0b3JEZWNsYXJhdGlvbiwgRnVuY3Rpb25EZWNsYXJhdGlvbiwgSWRlbnRpZmllciwgSW50ZXJmYWNlRGVjbGFyYXRpb24sIE1ldGhvZERlY2xhcmF0aW9uLCBNZXRob2RTaWduYXR1cmUsIE1vZHVsZURlY2xhcmF0aW9uLCBQcm9wZXJ0eURlY2xhcmF0aW9uLCBQcm9wZXJ0eVNpZ25hdHVyZSwgU291cmNlRmlsZSwgVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uLCBWYXJpYWJsZURlY2xhcmF0aW9uLCBQYXJhbWV0ZXJEZWNsYXJhdGlvbiwgRGVjb3JhdG9yLCBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uLCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uLCBJbXBvcnRTcGVjaWZpZXIsIENvbW1lbnRSYW5nZSwgRW51bURlY2xhcmF0aW9uLCBFbnVtTWVtYmVyLCBUeXBlQWxpYXNEZWNsYXJhdGlvbiwgRnVuY3Rpb25FeHByZXNzaW9uLCBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHMsIEltcG9ydERlY2xhcmF0aW9uLCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiwgU3ludGF4S2luZCwgRXhwcmVzc2lvbiwgVHlwZU5vZGUsIFNjb3BlLCBBcnJvd0Z1bmN0aW9uIH0gZnJvbSBcInRzLW1vcnBoXCI7XHJcbmltcG9ydCB7IGlzQW1iaWVudCwgaXNOYW1lc3BhY2UgfSBmcm9tIFwiLi4vYW5hbHl6ZV9mdW5jdGlvbnMvcHJvY2Vzc19mdW5jdGlvbnNcIjtcclxuaW1wb3J0ICogYXMgRmFtaXggZnJvbSBcIi4uL2xpYi9mYW1peC9tb2RlbC9mYW1peFwiO1xyXG5pbXBvcnQgeyBGYW1peFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vbGliL2ZhbWl4L2ZhbWl4X3JlcG9zaXRvcnlcIjtcclxuaW1wb3J0IHsgbG9nZ2VyLCBjb25maWcgfSBmcm9tIFwiLi4vYW5hbHl6ZVwiO1xyXG4vLyBpbXBvcnQgR3JhcGhlbWVTcGxpdHRlciBmcm9tIFwiZ3JhcGhlbWUtc3BsaXR0ZXJcIjtcclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby1yZXF1aXJlLWltcG9ydHNcclxuaW1wb3J0IEdyYXBoZW1lU3BsaXR0ZXIgPSByZXF1aXJlKCdncmFwaGVtZS1zcGxpdHRlcicpO1xyXG5pbXBvcnQgKiBhcyBIZWxwZXJzIGZyb20gXCIuL2hlbHBlcnNfY3JlYXRpb25cIjtcclxuaW1wb3J0ICogYXMgRlFORnVuY3Rpb25zIGZyb20gXCIuLi9mcW5cIjtcclxuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcclxuLy8gaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcclxuXHJcbmV4cG9ydCB0eXBlIFRTTW9ycGhPYmplY3RUeXBlID0gSW1wb3J0RGVjbGFyYXRpb24gfCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiB8IFNvdXJjZUZpbGUgfCBNb2R1bGVEZWNsYXJhdGlvbiB8IENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IE1ldGhvZERlY2xhcmF0aW9uIHwgQ29uc3RydWN0b3JEZWNsYXJhdGlvbiB8IE1ldGhvZFNpZ25hdHVyZSB8IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24gfCBQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IFZhcmlhYmxlRGVjbGFyYXRpb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uIHwgUHJvcGVydHlTaWduYXR1cmUgfCBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24gfCBJZGVudGlmaWVyIHwgRGVjb3JhdG9yIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBJbXBvcnRTcGVjaWZpZXIgfCBDb21tZW50UmFuZ2UgfCBFbnVtRGVjbGFyYXRpb24gfCBFbnVtTWVtYmVyIHwgVHlwZUFsaWFzRGVjbGFyYXRpb24gfCBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHMgfCBUU01vcnBoUGFyYW1ldHJpY1R5cGU7XHJcblxyXG5leHBvcnQgdHlwZSBUU01vcnBoVHlwZURlY2xhcmF0aW9uID0gVHlwZUFsaWFzRGVjbGFyYXRpb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uIHwgUHJvcGVydHlTaWduYXR1cmUgfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgTWV0aG9kU2lnbmF0dXJlIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24gfCBQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IFZhcmlhYmxlRGVjbGFyYXRpb24gfCBFbnVtTWVtYmVyIHwgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24gfCBUU01vcnBoUGFyYW1ldHJpY1R5cGUgfCBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb247XHJcblxyXG5leHBvcnQgdHlwZSBUU01vcnBoUGFyYW1ldHJpY1R5cGUgPSBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgTWV0aG9kRGVjbGFyYXRpb24gfCBBcnJvd0Z1bmN0aW9uO1xyXG5cclxuLy8gdHlwZSBQYXJhbWV0cmljVmFyaWFudFR5cGUgPSBGYW1peC5QYXJhbWV0cmljQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZDtcclxuXHJcbi8vIHR5cGUgQ29uY3JldGVFbGVtZW50VFNNb3JwaFR5cGUgPSBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgTWV0aG9kRGVjbGFyYXRpb247XHJcblxyXG5leHBvcnQgdHlwZSBJbnZvY2FibGVUeXBlID0gTWV0aG9kRGVjbGFyYXRpb24gfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgRnVuY3Rpb25FeHByZXNzaW9uIHwgQXJyb3dGdW5jdGlvbjtcclxuXHJcbmV4cG9ydCBjbGFzcyBFbnRpdHlEaWN0aW9uYXJ5IHtcclxuICAgIFxyXG4gICAgcHVibGljIGZhbWl4UmVwID0gbmV3IEZhbWl4UmVwb3NpdG9yeSgpO1xyXG4gICAgcHJpdmF0ZSBmbXhBbGlhc01hcCA9IG5ldyBNYXA8c3RyaW5nLCBGYW1peC5BbGlhcz4oKTsgLy8gTWFwcyB0aGUgYWxpYXMgbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcclxuICAgIHByaXZhdGUgZm14Q2xhc3NNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljQ2xhc3M+KCk7IC8vIE1hcHMgdGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxyXG4gICAgcHJpdmF0ZSBmbXhJbnRlcmZhY2VNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguSW50ZXJmYWNlIHwgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZT4oKTsgLy8gTWFwcyB0aGUgaW50ZXJmYWNlIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXHJcbiAgICBwcml2YXRlIGZteE1vZHVsZU1hcCA9IG5ldyBNYXA8TW9kdWxlRGVjbGFyYXRpb24sIEZhbWl4Lk1vZHVsZT4oKTsgLy8gTWFwcyB0aGUgbmFtZXNwYWNlIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXHJcbiAgICBwcml2YXRlIGZteEZpbGVNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguU2NyaXB0RW50aXR5IHwgRmFtaXguTW9kdWxlPigpOyAvLyBNYXBzIHRoZSBzb3VyY2UgZmlsZSBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxyXG4gICAgcHJpdmF0ZSBmbXhUeXBlTWFwID0gbmV3IE1hcDxUU01vcnBoVHlwZURlY2xhcmF0aW9uLCBGYW1peC5UeXBlIHwgRmFtaXguUGFyYW1ldGVyVHlwZT4oKTsgLy8gTWFwcyB0aGUgdHlwZXMgZGVjbGFyYXRpb25zIHRvIHRoZWlyIEZhbWl4IG1vZGVsXHJcbiAgICBwcml2YXRlIGZteFByaW1pdGl2ZVR5cGVNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguUHJpbWl0aXZlVHlwZT4oKTsgLy8gTWFwcyB0aGUgcHJpbWl0aXZlIHR5cGUgbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcclxuICAgIHByaXZhdGUgZm14RnVuY3Rpb25BbmRNZXRob2RNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24gfCBGYW1peC5NZXRob2QgfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kPjsgLy8gTWFwcyB0aGUgZnVuY3Rpb24gbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcclxuICAgIHByaXZhdGUgZm14QXJyb3dGdW5jdGlvbk1hcCA9IG5ldyBNYXA8c3RyaW5nLCBGYW1peC5BcnJvd0Z1bmN0aW9uPjsgLy8gTWFwcyB0aGUgZnVuY3Rpb24gbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcclxuICAgIHByaXZhdGUgZm14UGFyYW1ldGVyTWFwID0gbmV3IE1hcDxQYXJhbWV0ZXJEZWNsYXJhdGlvbiwgRmFtaXguUGFyYW1ldGVyPigpOyAvLyBNYXBzIHRoZSBwYXJhbWV0ZXJzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXHJcbiAgICBwcml2YXRlIGZteFZhcmlhYmxlTWFwID0gbmV3IE1hcDxWYXJpYWJsZURlY2xhcmF0aW9uLCBGYW1peC5WYXJpYWJsZT4oKTsgLy8gTWFwcyB0aGUgdmFyaWFibGVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXHJcbiAgICBwcml2YXRlIGZteEltcG9ydENsYXVzZU1hcCA9IG5ldyBNYXA8SW1wb3J0RGVjbGFyYXRpb24gfCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiwgRmFtaXguSW1wb3J0Q2xhdXNlPigpOyAvLyBNYXBzIHRoZSBpbXBvcnQgY2xhdXNlcyB0byB0aGVpciBGYW1peCBtb2RlbFxyXG4gICAgcHJpdmF0ZSBmbXhFbnVtTWFwID0gbmV3IE1hcDxFbnVtRGVjbGFyYXRpb24sIEZhbWl4LkVudW0+KCk7IC8vIE1hcHMgdGhlIGVudW0gbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcclxuICAgIHByaXZhdGUgZm14SW5oZXJpdGFuY2VNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguSW5oZXJpdGFuY2U+KCk7IC8vIE1hcHMgdGhlIGluaGVyaXRhbmNlIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXHJcbiAgICBwcml2YXRlIFVOS05PV05fVkFMVUUgPSAnKHVua25vd24gZHVlIHRvIHBhcnNpbmcgZXJyb3IpJzsgLy8gVGhlIHZhbHVlIHRvIHVzZSB3aGVuIGEgbmFtZSBpcyBub3QgdXNhYmxlXHJcbiAgICBwdWJsaWMgZm14RWxlbWVudE9iamVjdE1hcCA9IG5ldyBNYXA8RmFtaXguRW50aXR5LFRTTW9ycGhPYmplY3RUeXBlPigpO1xyXG4gICAgcHVibGljIHRzTW9ycGhFbGVtZW50T2JqZWN0TWFwID0gbmV3IE1hcDxUU01vcnBoT2JqZWN0VHlwZSxGYW1peC5FbnRpdHk+KCk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgY29uc3RydWN0b3IoKSB7XHJcbiAgICAgICAgdGhpcy5mYW1peFJlcC5zZXRGbXhFbGVtZW50T2JqZWN0TWFwKHRoaXMuZm14RWxlbWVudE9iamVjdE1hcCk7ICAgICAgXHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIGFkZFNvdXJjZUFuY2hvcihmbXg6IEZhbWl4LlNvdXJjZWRFbnRpdHksIG5vZGU6IFRTTW9ycGhPYmplY3RUeXBlKTogRmFtaXguSW5kZXhlZEZpbGVBbmNob3Ige1xyXG4gICAgICAgIGNvbnN0IHNvdXJjZUFuY2hvcjogRmFtaXguSW5kZXhlZEZpbGVBbmNob3IgPSBuZXcgRmFtaXguSW5kZXhlZEZpbGVBbmNob3IoKTtcclxuICAgICAgICBsZXQgc291cmNlU3RhcnQsIHNvdXJjZUVuZDogbnVtYmVyO1xyXG4gICAgICAgIGlmIChmbXggJiYgbm9kZSkge1xyXG4gICAgICAgICAgICAvLyBmaW5kIHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiB0aGUgc291cmNlIGVsZW1lbnRcclxuICAgICAgICAgICAgaWYgKCEobm9kZSBpbnN0YW5jZW9mIENvbW1lbnRSYW5nZSkpIHtcclxuICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gbm9kZS5nZXRTdGFydCgpO1xyXG4gICAgICAgICAgICAgICAgc291cmNlRW5kID0gbm9kZS5nZXRFbmQoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gbm9kZS5nZXRQb3MoKTtcclxuICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IG5vZGUuZ2V0RW5kKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgIFxyXG4gICAgICAgICAgICBpZiAoY29uZmlnLmV4cGVjdEdyYXBoZW1lcykge1xyXG4gICAgICAgICAgICAgICAgLyoqXHJcbiAgICAgICAgICAgICAgICAgKiBUaGUgZm9sbG93aW5nIGxvZ2ljIGhhbmRsZXMgdGhlIGNhc2Ugb2YgbXVsdGktY29kZSBwb2ludCBjaGFyYWN0ZXJzIChlLmcuIGVtb2ppKSBpbiB0aGUgc291cmNlIHRleHQuXHJcbiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlIFBoYXJvL1NtYWxsdGFsayB0cmVhdHMgbXVsdGktY29kZSBwb2ludCBjaGFyYWN0ZXJzIGFzIGEgc2luZ2xlIGNoYXJhY3RlciwgXHJcbiAgICAgICAgICAgICAgICAgKiBidXQgSmF2YVNjcmlwdCB0cmVhdHMgdGhlbSBhcyBtdWx0aXBsZSBjaGFyYWN0ZXJzLiBUaGlzIG1lYW5zIHRoYXQgdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zXHJcbiAgICAgICAgICAgICAgICAgKiBvZiBhIHNvdXJjZSBlbGVtZW50IGluIFBoYXJvL1NtYWxsdGFsayB3aWxsIGJlIGRpZmZlcmVudCB0aGFuIHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiB0aGVcclxuICAgICAgICAgICAgICAgICAqIHNhbWUgc291cmNlIGVsZW1lbnQgaW4gSmF2YVNjcmlwdC4gVGhpcyBsb2dpYyBmaW5kcyB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgb2YgdGhlIHNvdXJjZVxyXG4gICAgICAgICAgICAgICAgICogZWxlbWVudCBpbiBKYXZhU2NyaXB0IGFuZCB0aGVuIHVzZXMgdGhvc2UgcG9zaXRpb25zIHRvIHNldCB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgb2YgdGhlXHJcbiAgICAgICAgICAgICAgICAgKiBGYW1peCBpbmRleCBmaWxlIGFuY2hvci5cclxuICAgICAgICAgICAgICAgICAqIEl0IGRlcGVuZHMgb24gY29kZSBpbiB0aGUgJ2dyYXBoZW1lLXNwbGl0dGVyJyBwYWNrYWdlIGluIG5wbS5cclxuICAgICAgICAgICAgICAgICAqL1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc3BsaXR0ZXIgPSBuZXcgR3JhcGhlbWVTcGxpdHRlcigpO1xyXG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlRmlsZVRleHQgPSBub2RlLmdldFNvdXJjZUZpbGUoKS5nZXRGdWxsVGV4dCgpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgaGFzR3JhcGhlbWVDbHVzdGVycyA9IHNwbGl0dGVyLmNvdW50R3JhcGhlbWVzKHNvdXJjZUZpbGVUZXh0KSA+IDE7XHJcbiAgICAgICAgICAgICAgICBpZiAoaGFzR3JhcGhlbWVDbHVzdGVycykge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUVsZW1lbnRUZXh0ID0gc291cmNlRmlsZVRleHQuc3Vic3RyaW5nKHNvdXJjZVN0YXJ0LCBzb3VyY2VFbmQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUVsZW1lbnRUZXh0R3JhcGhlbWVzID0gc3BsaXR0ZXIuc3BsaXRHcmFwaGVtZXMoc291cmNlRWxlbWVudFRleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUZpbGVUZXh0R3JhcGhlbWVzID0gc3BsaXR0ZXIuc3BsaXRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mR3JhcGhlbWVDbHVzdGVyc0JlZm9yZVN0YXJ0ID0gc3BsaXR0ZXIuY291bnRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQuc3Vic3RyaW5nKDAsIHNvdXJjZVN0YXJ0KSk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgICAgICAgICAgLy8gZmluZCB0aGUgc3RhcnQgb2YgdGhlIHNvdXJjZUVsZW1lbnRUZXh0R3JhcGhlbWVzIGFycmF5IGluIHRoZSBzb3VyY2VGaWxlVGV4dEdyYXBoZW1lcyBhcnJheVxyXG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gSGVscGVycy5pbmRleE9mU3BsaXRBcnJheSh7c2VhcmNoQXJyYXk6IHNvdXJjZUZpbGVUZXh0R3JhcGhlbWVzLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YXJnZXRBcnJheTogc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMsIFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBzb3VyY2VTdGFydCAtIG51bWJlck9mR3JhcGhlbWVDbHVzdGVyc0JlZm9yZVN0YXJ0fSk7XHJcbiAgICAgICAgICAgICAgICAgICAgc291cmNlRW5kID0gc291cmNlU3RhcnQgKyBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcy5sZW5ndGg7XHJcbiAgICAgICAgICAgICAgICB9IFxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBUaGUgKzEgaXMgYmVjYXVzZSB0aGUgc291cmNlIGFuY2hvciAoUGhhcm8pIGlzIDEtYmFzZWQsIGJ1dCB0cy1tb3JwaCBpcyAwLWJhc2VkXHJcbiAgICAgICAgICAgIHNvdXJjZUFuY2hvci5zdGFydFBvcyA9IHNvdXJjZVN0YXJ0ICsgMTtcclxuICAgICAgICAgICAgc291cmNlQW5jaG9yLmVuZFBvcyA9IHNvdXJjZUVuZCArIDE7XHJcblxyXG4gICAgICAgICAgICBsZXQgZmlsZU5hbWUgPSBub2RlLmdldFNvdXJjZUZpbGUoKS5nZXRGaWxlUGF0aCgpIGFzIHN0cmluZztcclxuICAgICAgICAgICAgaWYgKGZpbGVOYW1lLnN0YXJ0c1dpdGgoXCIvXCIpKSB7XHJcbiAgICAgICAgICAgICAgICBmaWxlTmFtZSA9IGZpbGVOYW1lLnN1YnN0cmluZygxKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBzb3VyY2VBbmNob3IuZWxlbWVudCA9IGZteDtcclxuICAgICAgICAgICAgc291cmNlQW5jaG9yLmZpbGVOYW1lID0gZmlsZU5hbWU7XHJcbiAgICAgICAgICAgIGZteC5zb3VyY2VBbmNob3IgPSBzb3VyY2VBbmNob3I7XHJcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChzb3VyY2VBbmNob3IpO1xyXG5cclxuICAgICAgICB9XHJcbiAgICAgICAgcmV0dXJuIHNvdXJjZUFuY2hvcjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIE1ha2VzIGEgRmFtaXggaW5kZXggZmlsZSBhbmNob3JcclxuICAgICAqIEBwYXJhbSBzb3VyY2VFbGVtZW50IEEgc291cmNlIGVsZW1lbnRcclxuICAgICAqIEBwYXJhbSBmYW1peEVsZW1lbnQgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBzb3VyY2UgZWxlbWVudFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgbWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKHNvdXJjZUVsZW1lbnQ6IFRTTW9ycGhPYmplY3RUeXBlLCBmYW1peEVsZW1lbnQ6IEZhbWl4LlNvdXJjZWRFbnRpdHkpOiB2b2lkIHtcclxuICAgICAgICAvLyBGYW1peC5Db21tZW50IGlzIG5vdCBhIG5hbWVkIGVudGl0eSAoZG9lcyBub3QgaGF2ZSBhIGZ1bGx5UXVhbGlmaWVkTmFtZSlcclxuICAgICAgICBpZiAoIShmYW1peEVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5Db21tZW50KSkgeyAgLy8gbXVzdCBiZSBhIG5hbWVkIGVudGl0eVxyXG4gICAgICAgICAgICAvLyBpbnNhbml0eSBjaGVjazogbmFtZWQgZW50aXRpZXMgc2hvdWxkIGhhdmUgZnVsbHlRdWFsaWZpZWROYW1lXHJcbiAgICAgICAgICAgIGNvbnN0IGZ1bGx5UXVhbGlmaWVkTmFtZSA9IChmYW1peEVsZW1lbnQgYXMgRmFtaXguTmFtZWRFbnRpdHkpLmZ1bGx5UXVhbGlmaWVkTmFtZTtcclxuICAgICAgICAgICAgaWYgKCFmdWxseVF1YWxpZmllZE5hbWUgfHwgZnVsbHlRdWFsaWZpZWROYW1lID09PSB0aGlzLlVOS05PV05fVkFMVUUpIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggZWxlbWVudCAke2ZhbWl4RWxlbWVudC5jb25zdHJ1Y3Rvci5uYW1lfSBoYXMgbm8gdmFsaWQgZnVsbHlRdWFsaWZpZWROYW1lLmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsb2dnZXIuZGVidWcoXCJtYWtpbmcgaW5kZXggZmlsZSBhbmNob3IgZm9yICdcIiArIHNvdXJjZUVsZW1lbnQ/LmdldFRleHQoKSArIFwiJyB3aXRoIGZhbWl4RWxlbWVudCBcIiArIGZhbWl4RWxlbWVudC5nZXRKU09OKCkpO1xyXG4gICAgICAgIGNvbnN0IGZteEluZGV4RmlsZUFuY2hvciA9IG5ldyBGYW1peC5JbmRleGVkRmlsZUFuY2hvcigpO1xyXG4gICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5lbGVtZW50ID0gZmFtaXhFbGVtZW50O1xyXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZmFtaXhFbGVtZW50LCBzb3VyY2VFbGVtZW50KTtcclxuXHJcbiAgICAgICAgaWYgKHNvdXJjZUVsZW1lbnQgIT09IG51bGwpIHtcclxuICAgICAgICAgICAgY29uc3QgYWJzb2x1dGVQYXRoUHJvamVjdCA9IHRoaXMuZmFtaXhSZXAuZ2V0QWJzb2x1dGVQYXRoKCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgubm9ybWFsaXplKHNvdXJjZUVsZW1lbnQuZ2V0U291cmNlRmlsZSgpLmdldEZpbGVQYXRoKCkpO1xyXG5cclxuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25Ob2RlTW9kdWxlcyA9IGFic29sdXRlUGF0aC5pbmRleE9mKCdub2RlX21vZHVsZXMnKTtcclxuXHJcbiAgICAgICAgICAgIGxldCBwYXRoSW5Qcm9qZWN0OiBzdHJpbmcgPSBcIlwiO1xyXG5cclxuICAgICAgICAgICAgaWYgKHBvc2l0aW9uTm9kZU1vZHVsZXMgIT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYXRoRnJvbU5vZGVNb2R1bGVzID0gYWJzb2x1dGVQYXRoLnN1YnN0cmluZyhwb3NpdGlvbk5vZGVNb2R1bGVzKTtcclxuICAgICAgICAgICAgICAgIHBhdGhJblByb2plY3QgPSBwYXRoRnJvbU5vZGVNb2R1bGVzO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcGF0aEluUHJvamVjdCA9IHRoaXMuY29udmVydFRvUmVsYXRpdmVQYXRoKGFic29sdXRlUGF0aCwgYWJzb2x1dGVQYXRoUHJvamVjdCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIHJldmVydCBhbnkgYmFja3NsYXNoZXMgdG8gZm9yd2FyZCBzbGFzaGVzIChwYXRoLm5vcm1hbGl6ZSBvbiB3aW5kb3dzIGludHJvZHVjZXMgdGhlbSlcclxuICAgICAgICAgICAgcGF0aEluUHJvamVjdCA9IHBhdGhJblByb2plY3QucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XHJcblxyXG4gICAgICAgICAgICBpZiAocGF0aEluUHJvamVjdC5zdGFydHNXaXRoKFwiL1wiKSkge1xyXG4gICAgICAgICAgICAgICAgcGF0aEluUHJvamVjdCA9IHBhdGhJblByb2plY3Quc3Vic3RyaW5nKDEpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmbXhJbmRleEZpbGVBbmNob3IuZmlsZU5hbWUgPSBwYXRoSW5Qcm9qZWN0O1xyXG4gICAgICAgICAgICBsZXQgc291cmNlU3RhcnQsIHNvdXJjZUVuZFxyXG4gICAgICAgICAgICAvLyAsc291cmNlTGluZVN0YXJ0LCBzb3VyY2VMaW5lRW5kXHJcbiAgICAgICAgICAgIDogbnVtYmVyO1xyXG4gICAgICAgICAgICBpZiAoIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSkge1xyXG4gICAgICAgICAgICAgICAgc291cmNlU3RhcnQgPSBzb3VyY2VFbGVtZW50LmdldFN0YXJ0KCk7XHJcbiAgICAgICAgICAgICAgICBzb3VyY2VFbmQgPSBzb3VyY2VFbGVtZW50LmdldEVuZCgpO1xyXG4gICAgICAgICAgICAgICAgLy8gc291cmNlTGluZVN0YXJ0ID0gc291cmNlRWxlbWVudC5nZXRTdGFydExpbmVOdW1iZXIoKTtcclxuICAgICAgICAgICAgICAgIC8vIHNvdXJjZUxpbmVFbmQgPSBzb3VyY2VFbGVtZW50LmdldEVuZExpbmVOdW1iZXIoKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gc291cmNlRWxlbWVudC5nZXRQb3MoKTtcclxuICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IHNvdXJjZUVsZW1lbnQuZ2V0RW5kKCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgaWYgKGNvbmZpZy5leHBlY3RHcmFwaGVtZXMpIHtcclxuICAgICAgICAgICAgICAgIC8qKlxyXG4gICAgICAgICAgICAgICAgICogVGhlIGZvbGxvd2luZyBsb2dpYyBoYW5kbGVzIHRoZSBjYXNlIG9mIG11bHRpLWNvZGUgcG9pbnQgY2hhcmFjdGVycyAoZS5nLiBlbW9qaSkgaW4gdGhlIHNvdXJjZSB0ZXh0LlxyXG4gICAgICAgICAgICAgICAgICogVGhpcyBpcyBuZWVkZWQgYmVjYXVzZSBQaGFyby9TbWFsbHRhbGsgdHJlYXRzIG11bHRpLWNvZGUgcG9pbnQgY2hhcmFjdGVycyBhcyBhIHNpbmdsZSBjaGFyYWN0ZXIsIFxyXG4gICAgICAgICAgICAgICAgICogYnV0IEphdmFTY3JpcHQgdHJlYXRzIHRoZW0gYXMgbXVsdGlwbGUgY2hhcmFjdGVycy4gVGhpcyBtZWFucyB0aGF0IHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9uc1xyXG4gICAgICAgICAgICAgICAgICogb2YgYSBzb3VyY2UgZWxlbWVudCBpbiBQaGFyby9TbWFsbHRhbGsgd2lsbCBiZSBkaWZmZXJlbnQgdGhhbiB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgb2YgdGhlXHJcbiAgICAgICAgICAgICAgICAgKiBzYW1lIHNvdXJjZSBlbGVtZW50IGluIEphdmFTY3JpcHQuIFRoaXMgbG9naWMgZmluZHMgdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIHRoZSBzb3VyY2VcclxuICAgICAgICAgICAgICAgICAqIGVsZW1lbnQgaW4gSmF2YVNjcmlwdCBhbmQgdGhlbiB1c2VzIHRob3NlIHBvc2l0aW9ucyB0byBzZXQgdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIHRoZVxyXG4gICAgICAgICAgICAgICAgICogRmFtaXggaW5kZXggZmlsZSBhbmNob3IuXHJcbiAgICAgICAgICAgICAgICAgKiBJdCBkZXBlbmRzIG9uIGNvZGUgaW4gdGhlICdncmFwaGVtZS1zcGxpdHRlcicgcGFja2FnZSBpbiBucG0uXHJcbiAgICAgICAgICAgICAgICAgKi9cclxuICAgICAgICAgICAgICAgIGNvbnN0IHNwbGl0dGVyID0gbmV3IEdyYXBoZW1lU3BsaXR0ZXIoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUZpbGVUZXh0ID0gc291cmNlRWxlbWVudC5nZXRTb3VyY2VGaWxlKCkuZ2V0RnVsbFRleHQoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGhhc0dyYXBoZW1lQ2x1c3RlcnMgPSBzcGxpdHRlci5jb3VudEdyYXBoZW1lcyhzb3VyY2VGaWxlVGV4dCkgPiAxO1xyXG4gICAgICAgICAgICAgICAgaWYgKGhhc0dyYXBoZW1lQ2x1c3RlcnMpIHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50VGV4dCA9IHNvdXJjZUZpbGVUZXh0LnN1YnN0cmluZyhzb3VyY2VTdGFydCwgc291cmNlRW5kKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcyA9IHNwbGl0dGVyLnNwbGl0R3JhcGhlbWVzKHNvdXJjZUVsZW1lbnRUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VGaWxlVGV4dEdyYXBoZW1lcyA9IHNwbGl0dGVyLnNwbGl0R3JhcGhlbWVzKHNvdXJjZUZpbGVUZXh0KTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZkdyYXBoZW1lQ2x1c3RlcnNCZWZvcmVTdGFydCA9IHNwbGl0dGVyLmNvdW50R3JhcGhlbWVzKHNvdXJjZUZpbGVUZXh0LnN1YnN0cmluZygwLCBzb3VyY2VTdGFydCkpO1xyXG4gICAgICAgIFxyXG4gICAgICAgICAgICAgICAgICAgIC8vIGZpbmQgdGhlIHN0YXJ0IG9mIHRoZSBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcyBhcnJheSBpbiB0aGUgc291cmNlRmlsZVRleHRHcmFwaGVtZXMgYXJyYXlcclxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VTdGFydCA9IEhlbHBlcnMuaW5kZXhPZlNwbGl0QXJyYXkoe3NlYXJjaEFycmF5OiBzb3VyY2VGaWxlVGV4dEdyYXBoZW1lcywgXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0QXJyYXk6IHNvdXJjZUVsZW1lbnRUZXh0R3JhcGhlbWVzLCBcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFydDogc291cmNlU3RhcnQgLSBudW1iZXJPZkdyYXBoZW1lQ2x1c3RlcnNCZWZvcmVTdGFydH0pO1xyXG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IHNvdXJjZVN0YXJ0ICsgc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMubGVuZ3RoO1xyXG4gICAgICAgICAgICAgICAgfSBcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAvLyBub3RlOiB0aGUgKzEgaXMgYmVjYXVzZSB0aGUgc291cmNlIGFuY2hvciBpcyAxLWJhc2VkLCBidXQgdHMtbW9ycGggaXMgMC1iYXNlZFxyXG4gICAgICAgICAgICBmbXhJbmRleEZpbGVBbmNob3Iuc3RhcnRQb3MgPSBzb3VyY2VTdGFydCArIDE7XHJcbiAgICAgICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5lbmRQb3MgPSBzb3VyY2VFbmQgKyAxO1xyXG5cclxuICAgICAgICAgICAgLy8gaWYgKCEoZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguSW1wb3J0Q2xhdXNlIHx8IGZhbWl4RWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LkFjY2VzcyB8fCBmYW1peEVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5SZWZlcmVuY2UgfHwgZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguSW52b2NhdGlvbiB8fCBmYW1peEVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5Jbmhlcml0YW5jZSkgJiYgIShmYW1peEVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5Db21tZW50KSAmJiAhKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBDb21tZW50UmFuZ2UpICYmICEoc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIElkZW50aWZpZXIpICYmICEoc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIEltcG9ydFNwZWNpZmllcikgJiYgIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKSkge1xyXG4gICAgICAgICAgICAvLyAgICBpbml0RlFOKHNvdXJjZUVsZW1lbnQsIGZhbWl4RWxlbWVudCk7XHJcbiAgICAgICAgICAgIC8vIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBzb3VyY2VFbGVtZW50IGlzIG51bGxcclxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXCJzb3VyY2VFbGVtZW50IGlzIG51bGwgZm9yIGZhbWl4RWxlbWVudCBcIiArIGZhbWl4RWxlbWVudC5nZXRKU09OKCkpO1xyXG4gICAgICAgICAgICBmbXhJbmRleEZpbGVBbmNob3IuZmlsZU5hbWUgPSBcInVua25vd25cIjtcclxuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLnN0YXJ0UG9zID0gMDtcclxuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLmVuZFBvcyA9IDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW5kZXhGaWxlQW5jaG9yKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgb3IgZ2V0cyBhIEZhbWl4IHNjcmlwdCBlbnRpdHkgb3IgbW9kdWxlXHJcbiAgICAgKiBAcGFyYW0gZiBBIHNvdXJjZSBmaWxlXHJcbiAgICAgKiBAcGFyYW0gaXNNb2R1bGUgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIHNvdXJjZSBmaWxlIGlzIGEgbW9kdWxlXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHNvdXJjZSBmaWxlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4RmlsZShmOiBTb3VyY2VGaWxlLCBpc01vZHVsZTogYm9vbGVhbik6IEZhbWl4LlNjcmlwdEVudGl0eSB8IEZhbWl4Lk1vZHVsZSB7XHJcbiAgICAgICAgbGV0IGZteEZpbGU6IEZhbWl4LlNjcmlwdEVudGl0eTsgLy8gfCBGYW1peC5Nb2R1bGU7XHJcblxyXG4gICAgICAgIGNvbnN0IGZpbGVOYW1lID0gZi5nZXRCYXNlTmFtZSgpO1xyXG4gICAgICAgIGNvbnN0IGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUgPSBmLmdldEZpbGVQYXRoKCk7XHJcbiAgICAgICAgY29uc3QgZm91bmRGaWxlTmFtZSA9IHRoaXMuZm14RmlsZU1hcC5nZXQoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSk7XHJcbiAgICAgICAgaWYgKCFmb3VuZEZpbGVOYW1lKSB7XHJcbiAgICAgICAgICAgIGlmIChpc01vZHVsZSkge1xyXG4gICAgICAgICAgICAgICAgZm14RmlsZSA9IG5ldyBGYW1peC5Nb2R1bGUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZteEZpbGUgPSBuZXcgRmFtaXguU2NyaXB0RW50aXR5KCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZm14RmlsZS5uYW1lID0gZmlsZU5hbWU7XHJcbiAgICAgICAgICAgIGZteEZpbGUubnVtYmVyT2ZMaW5lc09mVGV4dCA9IGYuZ2V0RW5kTGluZU51bWJlcigpIC0gZi5nZXRTdGFydExpbmVOdW1iZXIoKTtcclxuICAgICAgICAgICAgZm14RmlsZS5udW1iZXJPZkNoYXJhY3RlcnMgPSBmLmdldEZ1bGxUZXh0KCkubGVuZ3RoO1xyXG5cclxuICAgICAgICAgICAgaW5pdEZRTihmLCBmbXhGaWxlKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGYsIGZteEZpbGUpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5mbXhGaWxlTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBmbXhGaWxlKTtcclxuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEZpbGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZm14RmlsZSA9IGZvdW5kRmlsZU5hbWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEZpbGUsZik7XHJcbiAgICAgICAgcmV0dXJuIGZteEZpbGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBNb2R1bGVcclxuICAgICAqIEBwYXJhbSBtb2R1bGVEZWNsYXJhdGlvbiBBIG1vZHVsZVxyXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBtb2R1bGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhNb2R1bGUobW9kdWxlRGVjbGFyYXRpb246IE1vZHVsZURlY2xhcmF0aW9uKTogRmFtaXguTW9kdWxlIHtcclxuICAgICAgICBpZiAodGhpcy5mbXhNb2R1bGVNYXAuaGFzKG1vZHVsZURlY2xhcmF0aW9uKSkge1xyXG4gICAgICAgICAgICBjb25zdCByTW9kdWxlID0gdGhpcy5mbXhNb2R1bGVNYXAuZ2V0KG1vZHVsZURlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgaWYgKHJNb2R1bGUpIHsgXHJcbiAgICAgICAgICAgICAgIHJldHVybiByTW9kdWxlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYW1peCBtb2R1bGUgJHttb2R1bGVEZWNsYXJhdGlvbi5nZXROYW1lKCl9IGlzIG5vdCBmb3VuZCBpbiB0aGUgbW9kdWxlIG1hcC5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZm14TW9kdWxlID0gbmV3IEZhbWl4Lk1vZHVsZSgpO1xyXG4gICAgICAgIGNvbnN0IG1vZHVsZU5hbWUgPSBtb2R1bGVEZWNsYXJhdGlvbi5nZXROYW1lKCk7XHJcbiAgICAgICAgZm14TW9kdWxlLm5hbWUgPSBtb2R1bGVOYW1lO1xyXG4gICAgICAgIGZteE1vZHVsZS5pc0FtYmllbnQgPSBpc0FtYmllbnQobW9kdWxlRGVjbGFyYXRpb24pO1xyXG4gICAgICAgIGZteE1vZHVsZS5pc05hbWVzcGFjZSA9IGlzTmFtZXNwYWNlKG1vZHVsZURlY2xhcmF0aW9uKTtcclxuICAgICAgICBmbXhNb2R1bGUuaXNNb2R1bGUgPSAhZm14TW9kdWxlLmlzTmFtZXNwYWNlICYmICFmbXhNb2R1bGUuaXNBbWJpZW50O1xyXG5cclxuICAgICAgICBpbml0RlFOKG1vZHVsZURlY2xhcmF0aW9uLCBmbXhNb2R1bGUpO1xyXG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKG1vZHVsZURlY2xhcmF0aW9uLCBmbXhNb2R1bGUpO1xyXG5cclxuICAgICAgICB0aGlzLmZteE1vZHVsZU1hcC5zZXQobW9kdWxlRGVjbGFyYXRpb24sIGZteE1vZHVsZSk7XHJcblxyXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhNb2R1bGUpO1xyXG5cclxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteE1vZHVsZSxtb2R1bGVEZWNsYXJhdGlvbik7XHJcbiAgICAgICAgcmV0dXJuIGZteE1vZHVsZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBhbGlhc1xyXG4gICAgICogQHBhcmFtIGEgQW4gYWxpYXNcclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgYWxpYXNcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4QWxpYXMoYTogVHlwZUFsaWFzRGVjbGFyYXRpb24pOiBGYW1peC5BbGlhcyB7XHJcbiAgICAgICAgbGV0IGZteEFsaWFzOiBGYW1peC5BbGlhcztcclxuICAgICAgICBjb25zdCBhbGlhc05hbWUgPSBhLmdldE5hbWUoKTtcclxuICAgICAgICAvL2NvbnN0IGFsaWFzRnVsbHlRdWFsaWZpZWROYW1lID0gYS5nZXRUeXBlKCkuZ2V0VGV4dCgpOyAvLyBGUU5GdW5jdGlvbnMuZ2V0RlFOKGEpO1xyXG4gICAgICAgIGNvbnN0IGFsaWFzRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihhKTtcclxuICAgICAgICBjb25zdCBmb3VuZEFsaWFzID0gdGhpcy5mbXhBbGlhc01hcC5nZXQoYWxpYXNGdWxseVF1YWxpZmllZE5hbWUpO1xyXG4gICAgICAgIGlmICghZm91bmRBbGlhcykge1xyXG4gICAgICAgICAgICBmbXhBbGlhcyA9IG5ldyBGYW1peC5BbGlhcygpO1xyXG4gICAgICAgICAgICBmbXhBbGlhcy5uYW1lID0gYS5nZXROYW1lKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IGFsaWFzTmFtZVdpdGhHZW5lcmljcyA9IGFsaWFzTmFtZSArIChhLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID8gKFwiPFwiICsgYS5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCh0cCA9PiB0cC5nZXROYW1lKCkpLmpvaW4oXCIsIFwiKSArIFwiPlwiKSA6IFwiXCIpO1xyXG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYD4gTk9URTogYWxpYXMgJHthbGlhc05hbWV9IGhhcyBmdWxseSBxdWFsaWZpZWQgbmFtZSAke2FsaWFzRnVsbHlRdWFsaWZpZWROYW1lfSBhbmQgbmFtZSB3aXRoIGdlbmVyaWNzICR7YWxpYXNOYW1lV2l0aEdlbmVyaWNzfS5gKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGFsaWFzTmFtZVdpdGhHZW5lcmljcywgYSk7XHJcbiAgICAgICAgICAgIGZteEFsaWFzLmFsaWFzZWRFbnRpdHkgPSBmbXhUeXBlO1xyXG4gICAgICAgICAgICBpbml0RlFOKGEsIGZteEFsaWFzKTtcclxuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoYSwgZm14QWxpYXMpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5mbXhBbGlhc01hcC5zZXQoYWxpYXNGdWxseVF1YWxpZmllZE5hbWUsIGZteEFsaWFzKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhBbGlhcyk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBmbXhBbGlhcyA9IGZvdW5kQWxpYXM7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14QWxpYXMsYSk7XHJcblxyXG4gICAgICAgIHJldHVybiBmbXhBbGlhcztcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgb3IgZ2V0cyBhIEZhbWl4IGNsYXNzIG9yIHBhcmFtZXRlcml6YWJsZSBjbGFzc1xyXG4gICAgICogQHBhcmFtIGNscyBBIGNsYXNzXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGNsYXNzXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4Q2xhc3MoY2xzOiBDbGFzc0RlY2xhcmF0aW9uKTogRmFtaXguQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljQ2xhc3Mge1xyXG4gICAgICAgIGxldCBmbXhDbGFzczogRmFtaXguQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljQ2xhc3M7XHJcbiAgICAgICAgY29uc3QgaXNBYnN0cmFjdCA9IGNscy5pc0Fic3RyYWN0KCk7XHJcbiAgICAgICAgY29uc3QgY2xhc3NGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGNscyk7XHJcbiAgICAgICAgY29uc3QgY2xzTmFtZSA9IGNscy5nZXROYW1lKCkgfHwgdGhpcy5VTktOT1dOX1ZBTFVFO1xyXG4gICAgICAgIGNvbnN0IGlzR2VuZXJpYyA9IGNscy5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aDtcclxuICAgICAgICBjb25zdCBmb3VuZENsYXNzID0gdGhpcy5mbXhDbGFzc01hcC5nZXQoY2xhc3NGdWxseVF1YWxpZmllZE5hbWUpO1xyXG4gICAgICAgIGlmICghZm91bmRDbGFzcykge1xyXG4gICAgICAgICAgICBpZiAoaXNHZW5lcmljKSB7XHJcbiAgICAgICAgICAgICAgICBmbXhDbGFzcyA9IG5ldyBGYW1peC5QYXJhbWV0cmljQ2xhc3MoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZteENsYXNzID0gbmV3IEZhbWl4LkNsYXNzKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZteENsYXNzLm5hbWUgPSBjbHNOYW1lO1xyXG4gICAgICAgICAgICBpbml0RlFOKGNscywgZm14Q2xhc3MpO1xyXG4gICAgICAgICAgICAvLyBmbXhDbGFzcy5mdWxseVF1YWxpZmllZE5hbWUgPSBjbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZTtcclxuICAgICAgICAgICAgZm14Q2xhc3MuaXNBYnN0cmFjdCA9IGlzQWJzdHJhY3Q7XHJcblxyXG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihjbHMsIGZteENsYXNzKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZm14Q2xhc3NNYXAuc2V0KGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lLCBmbXhDbGFzcyk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14Q2xhc3MpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhDbGFzcyxjbHMpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZm14Q2xhc3MgPSBmb3VuZENsYXNzO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGZteENsYXNzO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggaW50ZXJmYWNlIG9yIHBhcmFtZXRlcml6YWJsZSBpbnRlcmZhY2VcclxuICAgICAqIEBwYXJhbSBpbnRlciBBbiBpbnRlcmZhY2VcclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgaW50ZXJmYWNlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlKGludGVyOiBJbnRlcmZhY2VEZWNsYXJhdGlvbik6IEZhbWl4LkludGVyZmFjZSB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2Uge1xyXG5cclxuICAgICAgICBsZXQgZm14SW50ZXJmYWNlOiBGYW1peC5JbnRlcmZhY2UgfCBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlO1xyXG4gICAgICAgIGNvbnN0IGludGVyTmFtZSA9IGludGVyLmdldE5hbWUoKTtcclxuICAgICAgICBjb25zdCBpbnRlckZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oaW50ZXIpO1xyXG4gICAgICAgIGNvbnN0IGZvdW5kSW50ZXJmYWNlID0gdGhpcy5mbXhJbnRlcmZhY2VNYXAuZ2V0KGludGVyRnVsbHlRdWFsaWZpZWROYW1lKTtcclxuICAgICAgICBpZiAoIWZvdW5kSW50ZXJmYWNlKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IGlzR2VuZXJpYyA9IGludGVyLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoO1xyXG4gICAgICAgICAgICBpZiAoaXNHZW5lcmljKSB7XHJcbiAgICAgICAgICAgICAgICBmbXhJbnRlcmZhY2UgPSBuZXcgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZm14SW50ZXJmYWNlID0gbmV3IEZhbWl4LkludGVyZmFjZSgpO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBmbXhJbnRlcmZhY2UubmFtZSA9IGludGVyTmFtZTtcclxuICAgICAgICAgICAgaW5pdEZRTihpbnRlciwgZm14SW50ZXJmYWNlKTtcclxuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoaW50ZXIsIGZteEludGVyZmFjZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmZteEludGVyZmFjZU1hcC5zZXQoaW50ZXJGdWxseVF1YWxpZmllZE5hbWUsIGZteEludGVyZmFjZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW50ZXJmYWNlKTtcclxuXHJcbiAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14SW50ZXJmYWNlLGludGVyKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIGZteEludGVyZmFjZSA9IGZvdW5kSW50ZXJmYWNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZm14SW50ZXJmYWNlO1xyXG4gICAgfVxyXG5cclxuICAgIFxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBjb25jcmV0ZSBlbGVtZW50XHJcbiAgICAgKiBAcGFyYW0gY29uY3JldGVFbGVtZW50IEEgcGFyYW1ldHJpYyBFbGVtZW50ICAgXHJcbiAgICAgKiBAcGFyYW0gY29uY3JldGVFbGVtZW50RGVjbGFyYXRpb24gdGhlIGVsZW1lbnQgZGVjbGFyYXRpb25cclxuICAgICAqIEBwYXJhbSBjb25jcmV0ZUFyZ3VtZW50cyBjb25jcmV0ZSBhcmd1bWVudHNcclxuICAgICAqIEByZXR1cm5zIEEgcGFyYW1ldHJpYyBFbGVtZW50ICBcclxuICAgICAqL1xyXG4gICAgLy8gcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhDb25jcmV0ZUVsZW1lbnQoY29uY3JldGVFbGVtZW50IDogUGFyYW1ldHJpY1ZhcmlhbnRUeXBlLCBcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmNyZXRlRWxlbWVudERlY2xhcmF0aW9uIDogQ29uY3JldGVFbGVtZW50VFNNb3JwaFR5cGUsIFxyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uY3JldGVBcmd1bWVudHM6IFR5cGVOb2RlW10pOiBQYXJhbWV0cmljVmFyaWFudFR5cGUge1xyXG4gICAgICAgIFxyXG4gICAgLy8gICAgIGxldCBmdWxseVF1YWxpZmllZEZpbGVuYW1lID0gY29uY3JldGVFbGVtZW50LmZ1bGx5UXVhbGlmaWVkTmFtZTtcclxuICAgIC8vICAgICBsZXQgcGFyYW1zID0gXCJcIjtcclxuICAgICAgICBcclxuICAgIC8vICAgICBjb25jcmV0ZUFyZ3VtZW50cy5tYXAoKHBhcmFtKSA9PiB7XHJcbiAgICAvLyAgICAgICAgIHBhcmFtcyA9IHBhcmFtcytwYXJhbS5nZXRUZXh0KCkrJywnO1xyXG4gICAgLy8gICAgIH0pO1xyXG4gICAgICAgIFxyXG4gICAgLy8gICAgIHBhcmFtcyA9IHBhcmFtcy5zdWJzdHJpbmcoMCwgcGFyYW1zLmxlbmd0aCAtIDEpXHJcbiAgICAgICAgICAgICAgICBcclxuICAgIC8vICAgICBmdWxseVF1YWxpZmllZEZpbGVuYW1lID0gSGVscGVycy5yZXBsYWNlTGFzdEJldHdlZW5UYWdzKGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUscGFyYW1zKTtcclxuXHJcbiAgICAvLyAgICAgbGV0IGNvbmNFbGVtZW50OiBQYXJhbWV0cmljVmFyaWFudFR5cGU7XHJcblxyXG4gICAgLy8gICAgIGlmICghdGhpcy5mbXhJbnRlcmZhY2VNYXAuaGFzKGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpICYmIFxyXG4gICAgLy8gICAgICAgICAhdGhpcy5mbXhDbGFzc01hcC5oYXMoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSkgJiYgXHJcbiAgICAvLyAgICAgICAgICF0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmhhcyhmdWxseVF1YWxpZmllZEZpbGVuYW1lKSl7XHJcbiAgICAvLyAgICAgICAgIGNvbmNFbGVtZW50ID0gXy5jbG9uZURlZXAoY29uY3JldGVFbGVtZW50KTsgXHJcbiAgICAvLyAgICAgICAgIGNvbmNFbGVtZW50LmZ1bGx5UXVhbGlmaWVkTmFtZSA9IGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWU7XHJcbiAgICAvLyAgICAgICAgIGNvbmNFbGVtZW50LmNsZWFyR2VuZXJpY1BhcmFtZXRlcnMoKTtcclxuICAgIC8vICAgICAgICAgY29uY3JldGVBcmd1bWVudHMubWFwKChwYXJhbSkgPT4ge1xyXG4gICAgLy8gICAgICAgICAgICAgY29uc3QgcGFyYW1ldGVyID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVUeXBlKHBhcmFtKTtcclxuICAgIC8vICAgICAgICAgICAgIGNvbmNFbGVtZW50LmFkZENvbmNyZXRlUGFyYW1ldGVyKHBhcmFtZXRlcik7XHJcbiAgICAvLyAgICAgICAgIH0pXHJcbiAgICAgICAgICAgIFxyXG4gICAgLy8gICAgICAgICBpZiAoY29uY3JldGVFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0NsYXNzKSB7XHJcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmZteENsYXNzTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljQ2xhc3MpO1xyXG4gICAgLy8gICAgICAgICB9IGVsc2UgaWYgKGNvbmNyZXRlRWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UpIHtcclxuICAgIC8vICAgICAgICAgICAgIHRoaXMuZm14SW50ZXJmYWNlTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlKTtcclxuICAgIC8vICAgICAgICAgfSBlbHNlIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24pIHtcclxuICAgIC8vICAgICAgICAgICAgIHRoaXMuZm14RnVuY3Rpb25BbmRNZXRob2RNYXAuc2V0KGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUsIGNvbmNFbGVtZW50IGFzIEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbik7XHJcbiAgICAvLyAgICAgICAgIH0gZWxzZSB7IC8vIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljTWV0aG9kKSB7XHJcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljTWV0aG9kKTtcclxuICAgIC8vICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoY29uY0VsZW1lbnQpO1xyXG4gICAgLy8gICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGNvbmNFbGVtZW50LGNvbmNyZXRlRWxlbWVudERlY2xhcmF0aW9uKTtcclxuICAgIC8vICAgICB9IGVsc2Uge1xyXG4gICAgLy8gICAgICAgICBpZiAoY29uY3JldGVFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0NsYXNzKSB7XHJcbiAgICAvLyAgICAgICAgICAgICBjb25jRWxlbWVudCA9IHRoaXMuZm14Q2xhc3NNYXAuZ2V0KGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpIGFzIEZhbWl4LlBhcmFtZXRyaWNDbGFzcztcclxuICAgIC8vICAgICAgICAgfSBlbHNlIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlKSB7XHJcbiAgICAvLyAgICAgICAgICAgICBjb25jRWxlbWVudCA9IHRoaXMuZm14SW50ZXJmYWNlTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKSBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlO1xyXG4gICAgLy8gICAgICAgICB9IGVsc2UgaWYgKGNvbmNyZXRlRWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbikge1xyXG4gICAgLy8gICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKSBhcyBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb247XHJcbiAgICAvLyAgICAgICAgIH0gZWxzZSB7ICAvLyBpZiAoY29uY3JldGVFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY01ldGhvZCkge1xyXG4gICAgLy8gICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKSBhcyBGYW1peC5QYXJhbWV0cmljTWV0aG9kO1xyXG4gICAgLy8gICAgICAgICB9XHJcbiAgICAvLyAgICAgfVxyXG4gICAgLy8gICAgIHJldHVybiBjb25jRWxlbWVudDtcclxuICAgIC8vIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBwcm9wZXJ0eVxyXG4gICAgICogQHBhcmFtIHByb3BlcnR5IEEgcHJvcGVydHlcclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgcHJvcGVydHlcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4UHJvcGVydHkocHJvcGVydHk6IFByb3BlcnR5RGVjbGFyYXRpb24gfCBQcm9wZXJ0eVNpZ25hdHVyZSk6IEZhbWl4LlByb3BlcnR5IHtcclxuICAgICAgICBjb25zdCBmbXhQcm9wZXJ0eSA9IG5ldyBGYW1peC5Qcm9wZXJ0eSgpO1xyXG4gICAgICAgIGNvbnN0IGlzU2lnbmF0dXJlID0gcHJvcGVydHkgaW5zdGFuY2VvZiBQcm9wZXJ0eVNpZ25hdHVyZTtcclxuICAgICAgICBmbXhQcm9wZXJ0eS5uYW1lID0gcHJvcGVydHkuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBsZXQgcHJvcFR5cGVOYW1lID0gdGhpcy5VTktOT1dOX1ZBTFVFO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHByb3BUeXBlTmFtZSA9IHByb3BlcnR5LmdldFR5cGUoKS5nZXRUZXh0KCkudHJpbSgpO1xyXG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XHJcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciBwcm9wZXJ0eTogJHtwcm9wZXJ0eS5nZXROYW1lKCl9LiBDb250aW51aW5nLi4uYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBjb25zdCBmbXhUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShwcm9wVHlwZU5hbWUsIHByb3BlcnR5KTtcclxuICAgICAgICBmbXhQcm9wZXJ0eS5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xyXG5cclxuICAgICAgICAvLyBhZGQgdGhlIHZpc2liaWxpdHkgKHB1YmxpYywgcHJpdmF0ZSwgZXRjLikgdG8gdGhlIGZteFByb3BlcnR5XHJcbiAgICAgICAgZm14UHJvcGVydHkudmlzaWJpbGl0eSA9IFwiXCI7XHJcblxyXG4gICAgICAgIHByb3BlcnR5LmdldE1vZGlmaWVycygpLmZvckVhY2gobSA9PiB7XHJcbiAgICAgICAgICAgIHN3aXRjaCAobS5nZXRUZXh0KCkpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgU2NvcGUuUHVibGljOlxyXG4gICAgICAgICAgICAgICAgICAgIGZteFByb3BlcnR5LnZpc2liaWxpdHkgPSBcInB1YmxpY1wiO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBTY29wZS5Qcm90ZWN0ZWQ6XHJcbiAgICAgICAgICAgICAgICAgICAgZm14UHJvcGVydHkudmlzaWJpbGl0eSA9IFwicHJvdGVjdGVkXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgICAgICBjYXNlIFNjb3BlLlByaXZhdGU6XHJcbiAgICAgICAgICAgICAgICAgICAgZm14UHJvcGVydHkudmlzaWJpbGl0eSA9IFwicHJpdmF0ZVwiO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSBcInN0YXRpY1wiOlxyXG4gICAgICAgICAgICAgICAgICAgIGZteFByb3BlcnR5LmlzQ2xhc3NTaWRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGNhc2UgXCJyZWFkb25seVwiOlxyXG4gICAgICAgICAgICAgICAgICAgIGZteFByb3BlcnR5LnJlYWRPbmx5ID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgaWYgKCFpc1NpZ25hdHVyZSAmJiBwcm9wZXJ0eS5nZXRFeGNsYW1hdGlvblRva2VuTm9kZSgpKSB7XHJcbiAgICAgICAgICAgIGZteFByb3BlcnR5LmlzRGVmaW5pdGVseUFzc2lnbmVkID0gdHJ1ZTtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKHByb3BlcnR5LmdldFF1ZXN0aW9uVG9rZW5Ob2RlKCkpIHtcclxuICAgICAgICAgICAgZm14UHJvcGVydHkuaXNPcHRpb25hbCA9IHRydWU7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGlmIChwcm9wZXJ0eS5nZXROYW1lKCkuc3Vic3RyaW5nKDAsIDEpID09PSBcIiNcIikge1xyXG4gICAgICAgICAgICBmbXhQcm9wZXJ0eS5pc0phdmFTY3JpcHRQcml2YXRlID0gdHJ1ZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGluaXRGUU4ocHJvcGVydHksIGZteFByb3BlcnR5KTtcclxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihwcm9wZXJ0eSwgZm14UHJvcGVydHkpO1xyXG5cclxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14UHJvcGVydHkpO1xyXG5cclxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteFByb3BlcnR5LHByb3BlcnR5KTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGZteFByb3BlcnR5O1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IG1ldGhvZCBvciBhY2Nlc3NvclxyXG4gICAgICogQHBhcmFtIG1ldGhvZCBBIG1ldGhvZCBvciBhbiBhY2Nlc3NvclxyXG4gICAgICogQHBhcmFtIGN1cnJlbnRDQyBUaGUgY3ljbG9tYXRpYyBjb21wbGV4aXR5IG1ldHJpY3Mgb2YgdGhlIGN1cnJlbnQgc291cmNlIGZpbGVcclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgbWV0aG9kIG9yIHRoZSBhY2Nlc3NvclxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY3JlYXRlT3JHZXRGYW1peE1ldGhvZChtZXRob2Q6IE1ldGhvZERlY2xhcmF0aW9uIHwgQ29uc3RydWN0b3JEZWNsYXJhdGlvbiB8IE1ldGhvZFNpZ25hdHVyZSB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uLCBjdXJyZW50Q0M6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0pOiBGYW1peC5NZXRob2QgfCBGYW1peC5BY2Nlc3NvciB8IEZhbWl4LlBhcmFtZXRyaWNNZXRob2Qge1xyXG4gICAgICAgIGxldCBmbXhNZXRob2Q6IEZhbWl4Lk1ldGhvZCB8IEZhbWl4LkFjY2Vzc29yIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZDtcclxuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBtZXRob2QuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwO1xyXG4gICAgICAgIGNvbnN0IGZ1bmN0aW9uRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihtZXRob2QpO1xyXG4gICAgICAgIGlmICghdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5oYXMoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpKSB7XHJcblxyXG4gICAgICAgICAgICBpZiAobWV0aG9kIGluc3RhbmNlb2YgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8fCBtZXRob2QgaW5zdGFuY2VvZiBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICBmbXhNZXRob2QgPSBuZXcgRmFtaXguQWNjZXNzb3IoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGlzR2V0dGVyID0gbWV0aG9kIGluc3RhbmNlb2YgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbjtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGlzU2V0dGVyID0gbWV0aG9kIGluc3RhbmNlb2YgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbjtcclxuICAgICAgICAgICAgICAgIGlmIChpc0dldHRlcikgeyhmbXhNZXRob2QgYXMgRmFtaXguQWNjZXNzb3IpLmtpbmQgPSBcImdldHRlclwiO31cclxuICAgICAgICAgICAgICAgIGlmIChpc1NldHRlcikgeyhmbXhNZXRob2QgYXMgRmFtaXguQWNjZXNzb3IpLmtpbmQgPSBcInNldHRlclwiO31cclxuICAgICAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhNZXRob2QpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgaWYgKGlzR2VuZXJpYykge1xyXG4gICAgICAgICAgICAgICAgICAgIGZteE1ldGhvZCA9IG5ldyBGYW1peC5QYXJhbWV0cmljTWV0aG9kKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBmbXhNZXRob2QgPSBuZXcgRmFtaXguTWV0aG9kKCk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgY29uc3QgaXNDb25zdHJ1Y3RvciA9IG1ldGhvZCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yRGVjbGFyYXRpb247XHJcbiAgICAgICAgICAgIGNvbnN0IGlzU2lnbmF0dXJlID0gbWV0aG9kIGluc3RhbmNlb2YgTWV0aG9kU2lnbmF0dXJlO1xyXG5cclxuICAgICAgICAgICAgbGV0IGlzQWJzdHJhY3QgPSBmYWxzZTtcclxuICAgICAgICAgICAgbGV0IGlzU3RhdGljID0gZmFsc2U7XHJcbiAgICAgICAgICAgIGlmIChtZXRob2QgaW5zdGFuY2VvZiBNZXRob2REZWNsYXJhdGlvbiB8fCBtZXRob2QgaW5zdGFuY2VvZiBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIFNldEFjY2Vzc29yRGVjbGFyYXRpb24pIHtcclxuICAgICAgICAgICAgICAgIGlzQWJzdHJhY3QgPSBtZXRob2QuaXNBYnN0cmFjdCgpO1xyXG4gICAgICAgICAgICAgICAgaXNTdGF0aWMgPSBtZXRob2QuaXNTdGF0aWMoKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGlzQ29uc3RydWN0b3IpIHsoZm14TWV0aG9kIGFzIEZhbWl4LkFjY2Vzc29yKS5raW5kID0gXCJjb25zdHJ1Y3RvclwiO31cclxuICAgICAgICAgICAgZm14TWV0aG9kLmlzQWJzdHJhY3QgPSBpc0Fic3RyYWN0O1xyXG4gICAgICAgICAgICBmbXhNZXRob2QuaXNDbGFzc1NpZGUgPSBpc1N0YXRpYztcclxuICAgICAgICAgICAgZm14TWV0aG9kLmlzUHJpdmF0ZSA9IChtZXRob2QgaW5zdGFuY2VvZiBNZXRob2REZWNsYXJhdGlvbiB8fCBtZXRob2QgaW5zdGFuY2VvZiBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIFNldEFjY2Vzc29yRGVjbGFyYXRpb24pID8gKG1ldGhvZC5nZXRNb2RpZmllcnMoKS5maW5kKHggPT4geC5nZXRUZXh0KCkgPT09ICdwcml2YXRlJykpICE9PSB1bmRlZmluZWQgOiBmYWxzZTtcclxuICAgICAgICAgICAgZm14TWV0aG9kLmlzUHJvdGVjdGVkID0gKG1ldGhvZCBpbnN0YW5jZW9mIE1ldGhvZERlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbikgPyAobWV0aG9kLmdldE1vZGlmaWVycygpLmZpbmQoeCA9PiB4LmdldFRleHQoKSA9PT0gJ3Byb3RlY3RlZCcpKSAhPT0gdW5kZWZpbmVkIDogZmFsc2U7XHJcbiAgICAgICAgICAgIGZteE1ldGhvZC5zaWduYXR1cmUgPSBIZWxwZXJzLmNvbXB1dGVTaWduYXR1cmUobWV0aG9kLmdldFRleHQoKSk7XHJcblxyXG4gICAgICAgICAgICBsZXQgbWV0aG9kTmFtZTogc3RyaW5nO1xyXG4gICAgICAgICAgICBpZiAoaXNDb25zdHJ1Y3Rvcikge1xyXG4gICAgICAgICAgICAgICAgbWV0aG9kTmFtZSA9IFwiY29uc3RydWN0b3JcIjtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIG1ldGhvZE5hbWUgPSAobWV0aG9kIGFzIE1ldGhvZERlY2xhcmF0aW9uIHwgTWV0aG9kU2lnbmF0dXJlIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24pLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBmbXhNZXRob2QubmFtZSA9IG1ldGhvZE5hbWU7XHJcblxyXG4gICAgICAgICAgICBpZiAoIWlzQ29uc3RydWN0b3IpIHtcclxuICAgICAgICAgICAgICAgIGlmIChtZXRob2QuZ2V0TmFtZSgpLnN1YnN0cmluZygwLCAxKSA9PT0gXCIjXCIpIHtcclxuICAgICAgICAgICAgICAgICAgICBmbXhNZXRob2QuaXNQcml2YXRlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCFmbXhNZXRob2QuaXNQcml2YXRlICYmICFmbXhNZXRob2QuaXNQcm90ZWN0ZWQpIHtcclxuICAgICAgICAgICAgICAgIGZteE1ldGhvZC5pc1B1YmxpYyA9IHRydWU7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgICAgICBmbXhNZXRob2QuaXNQdWJsaWMgPSBmYWxzZTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKCFpc1NpZ25hdHVyZSkge1xyXG4gICAgICAgICAgICAgICAgZm14TWV0aG9kLmN5Y2xvbWF0aWNDb21wbGV4aXR5ID0gY3VycmVudENDW2ZteE1ldGhvZC5uYW1lXTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZteE1ldGhvZC5jeWNsb21hdGljQ29tcGxleGl0eSA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGxldCBtZXRob2RUeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTsgXHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBtZXRob2RUeXBlTmFtZSA9IG1ldGhvZC5nZXRSZXR1cm5UeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTsgICAgICAgICAgICBcclxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciByZXR1cm4gdHlwZSBvZiBtZXRob2Q6ICR7Zm14TWV0aG9kLm5hbWV9LiBDb250aW51aW5nLi4uYCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKG1ldGhvZFR5cGVOYW1lLCBtZXRob2QpO1xyXG4gICAgICAgICAgICBmbXhNZXRob2QuZGVjbGFyZWRUeXBlID0gZm14VHlwZTtcclxuICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mTGluZXNPZkNvZGUgPSBtZXRob2QuZ2V0RW5kTGluZU51bWJlcigpIC0gbWV0aG9kLmdldFN0YXJ0TGluZU51bWJlcigpO1xyXG4gICAgICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gbWV0aG9kLmdldFBhcmFtZXRlcnMoKTtcclxuICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mUGFyYW1ldGVycyA9IHBhcmFtZXRlcnMubGVuZ3RoO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFpc1NpZ25hdHVyZSkge1xyXG4gICAgICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mU3RhdGVtZW50cyA9IG1ldGhvZC5nZXRTdGF0ZW1lbnRzKCkubGVuZ3RoO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mU3RhdGVtZW50cyA9IDA7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgXHJcbiAgICAgICAgICAgIGluaXRGUU4obWV0aG9kLCBmbXhNZXRob2QpO1xyXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14TWV0aG9kKTtcclxuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IobWV0aG9kLCBmbXhNZXRob2QpO1xyXG5cclxuICAgICAgICAgICAgdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5zZXQoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUsIGZteE1ldGhvZCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICBmbXhNZXRob2QgPSB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmdldChmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgKEZhbWl4Lk1ldGhvZCB8IEZhbWl4LkFjY2Vzc29yIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteE1ldGhvZCxtZXRob2QpO1xyXG4gICAgICAgIFxyXG4gICAgICAgIHJldHVybiBmbXhNZXRob2Q7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSBmdW5jIEEgZnVuY3Rpb25cclxuICAgICAqIEBwYXJhbSBjdXJyZW50Q0MgVGhlIGN5Y2xvbWF0aWMgY29tcGxleGl0eSBtZXRyaWNzIG9mIHRoZSBjdXJyZW50IHNvdXJjZSBmaWxlXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGZ1bmN0aW9uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4RnVuY3Rpb24oZnVuYzogRnVuY3Rpb25EZWNsYXJhdGlvbiB8IEZ1bmN0aW9uRXhwcmVzc2lvbiwgY3VycmVudENDOiB7IFtrZXk6IHN0cmluZ106IG51bWJlciB9KTogRmFtaXguRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24ge1xyXG4gICAgICAgIGxldCBmbXhGdW5jdGlvbjogRmFtaXguRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb247XHJcbiAgICAgICAgY29uc3QgaXNHZW5lcmljID0gZnVuYy5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDA7XHJcbiAgICAgICAgY29uc3QgZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGZ1bmMpO1xyXG4gICAgICAgIGlmICghdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5oYXMoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpKSB7XHJcbiAgICAgICAgICAgIGlmIChpc0dlbmVyaWMpIHtcclxuICAgICAgICAgICAgICAgIGZteEZ1bmN0aW9uID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZm14RnVuY3Rpb24gPSBuZXcgRmFtaXguRnVuY3Rpb24oKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgXHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBmdW5jLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgaWYgKG5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGZteEZ1bmN0aW9uLm5hbWUgPSBuYW1lO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZm14RnVuY3Rpb24ubmFtZSA9IFwiYW5vbnltb3VzXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLnNpZ25hdHVyZSA9IEhlbHBlcnMuY29tcHV0ZVNpZ25hdHVyZShmdW5jLmdldFRleHQoKSk7XHJcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLmN5Y2xvbWF0aWNDb21wbGV4aXR5ID0gY3VycmVudENDW2ZteEZ1bmN0aW9uLm5hbWVdO1xyXG4gICAgICAgICAgICBpbml0RlFOKGZ1bmMsIGZteEZ1bmN0aW9uKTtcclxuICAgICAgICAgICAgLy8gZm14RnVuY3Rpb24uZnVsbHlRdWFsaWZpZWROYW1lID0gZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWU7XHJcbiAgICBcclxuICAgICAgICAgICAgbGV0IGZ1bmN0aW9uVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvblR5cGVOYW1lID0gZnVuYy5nZXRSZXR1cm5UeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciByZXR1cm4gdHlwZSBvZiBmdW5jdGlvbjogJHtmdW5jLmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgXHJcbiAgICAgICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGZ1bmN0aW9uVHlwZU5hbWUsIGZ1bmMpO1xyXG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xyXG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5udW1iZXJPZkxpbmVzT2ZDb2RlID0gZnVuYy5nZXRFbmRMaW5lTnVtYmVyKCkgLSBmdW5jLmdldFN0YXJ0TGluZU51bWJlcigpO1xyXG4gICAgICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gZnVuYy5nZXRQYXJhbWV0ZXJzKCk7XHJcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLm51bWJlck9mUGFyYW1ldGVycyA9IHBhcmFtZXRlcnMubGVuZ3RoO1xyXG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5udW1iZXJPZlN0YXRlbWVudHMgPSBmdW5jLmdldFN0YXRlbWVudHMoKS5sZW5ndGg7XHJcbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGZ1bmMsIGZteEZ1bmN0aW9uKTtcclxuICAgIFxyXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14RnVuY3Rpb24pO1xyXG4gICAgXHJcbiAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14RnVuY3Rpb24sZnVuYyk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSwgZm14RnVuY3Rpb24pO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgZm14RnVuY3Rpb24gPSB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmdldChmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgKEZhbWl4LkZ1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBmbXhGdW5jdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBwYXJhbWV0ZXJcclxuICAgICAqIEBwYXJhbSBwYXJhbSBBIHBhcmFtZXRlclxyXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBwYXJhbWV0ZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhQYXJhbWV0ZXIocGFyYW06IFBhcmFtZXRlckRlY2xhcmF0aW9uKTogRmFtaXguUGFyYW1ldGVyIHtcclxuICAgICAgICBpZiAodGhpcy5mbXhQYXJhbWV0ZXJNYXAuaGFzKHBhcmFtKSkge1xyXG4gICAgICAgICAgICBjb25zdCByUGFyYW1ldGVyID0gdGhpcy5mbXhQYXJhbWV0ZXJNYXAuZ2V0KHBhcmFtKTtcclxuICAgICAgICAgICAgaWYgKHJQYXJhbWV0ZXIpIHsgXHJcbiAgICAgICAgICAgICAgIHJldHVybiByUGFyYW1ldGVyO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYW1peCBwYXJhbWV0ZXIgJHtwYXJhbS5nZXROYW1lKCl9IGlzIG5vdCBmb3VuZCBpbiB0aGUgcGFyYW1ldGVyIG1hcC5gKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZm14UGFyYW0gPSBuZXcgRmFtaXguUGFyYW1ldGVyKCk7XHJcblxyXG4gICAgICAgIGxldCBwYXJhbVR5cGVOYW1lID0gdGhpcy5VTktOT1dOX1ZBTFVFO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIHBhcmFtVHlwZU5hbWUgPSBwYXJhbS5nZXRUeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcclxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYD4gV0FSTklORzogZ290IGV4Y2VwdGlvbiAke2Vycm9yfS4gRmFpbGVkIHRvIGdldCB1c2FibGUgbmFtZSBmb3IgcGFyYW1ldGVyOiAke3BhcmFtLmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKHBhcmFtVHlwZU5hbWUsIHBhcmFtKTtcclxuICAgICAgICBmbXhQYXJhbS5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xyXG4gICAgICAgIGZteFBhcmFtLm5hbWUgPSBwYXJhbS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGluaXRGUU4ocGFyYW0sIGZteFBhcmFtKTtcclxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihwYXJhbSwgZm14UGFyYW0pO1xyXG5cclxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14UGFyYW0pO1xyXG5cclxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteFBhcmFtLCBwYXJhbSk7XHJcbiAgICAgICAgdGhpcy5mbXhQYXJhbWV0ZXJNYXAuc2V0KHBhcmFtLCBmbXhQYXJhbSk7XHJcblxyXG4gICAgICAgIHJldHVybiBmbXhQYXJhbTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBGYW1peCB0eXBlIHBhcmFtZXRlclxyXG4gICAgICogQHBhcmFtIHRwIEEgdHlwZSBwYXJhbWV0ZXJcclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgdHlwZSBwYXJhbWV0ZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4UGFyYW1ldGVyVHlwZSh0cDogVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uKTogRmFtaXguUGFyYW1ldGVyVHlwZSB7XHJcbiAgICAgICAgXHJcbiAgICAgICAgY29uc3QgZm14UGFyYW1ldGVyVHlwZSA9IG5ldyBGYW1peC5QYXJhbWV0ZXJUeXBlKCk7XHJcbiAgIFxyXG4gICAgICAgIGZteFBhcmFtZXRlclR5cGUubmFtZSA9IHRwLmdldE5hbWUoKTsgICAgICBcclxuICAgICAgICBpbml0RlFOKHRwLCBmbXhQYXJhbWV0ZXJUeXBlKTtcclxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcih0cCwgZm14UGFyYW1ldGVyVHlwZSk7XHJcblxyXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhQYXJhbWV0ZXJUeXBlKTtcclxuXHJcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhQYXJhbWV0ZXJUeXBlLHRwKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGZteFBhcmFtZXRlclR5cGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggdHlwZSBpbiB0aGUgY29udGV4dCBvZiBjb25jcmV0aXphdGlvbnNcclxuICAgICAqIEBwYXJhbSB0eXBlTmFtZSBBIHR5cGUgbmFtZVxyXG4gICAgICogQHBhcmFtIGVsZW1lbnQgQW4gZWxlbWVudFxyXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSB0eXBlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4Q29uY3JldGVUeXBlKGVsZW1lbnQ6IFR5cGVOb2RlKTogXHJcbiAgICAgICAgRmFtaXguUGFyYW1ldGVyVHlwZSB8IEZhbWl4LlByaW1pdGl2ZVR5cGUgfCBGYW1peC5DbGFzcyB8IEZhbWl4LkludGVyZmFjZSB7XHJcbiAgICAgICAgLy8gVE9ETyAtIHJlZmFjdG9yIHRvIHN0b3AgdXNpbmcgbmFtZXMgYXMgYSBrZXkgaW4gdGhlIG1hcHMsIHVzZSB0cy1tb3JwaCBlbGVtZW50IGluc3RlYWRcclxuICAgICAgICBjb25zdCB0eXBlUGFyYW1ldGVyRGVjbGFyYXRpb24gPSBlbGVtZW50LmdldFN5bWJvbCgpPy5nZXREZWNsYXJhdGlvbnMoKVswXSBhcyBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb247XHJcbiAgICAgICAgY29uc3QgcGFyYW1ldGVyVHlwZU5hbWUgOiBzdHJpbmcgPSBlbGVtZW50LmdldFRleHQoKTtcclxuICAgICAgICBsZXQgZm14UGFyYW1ldGVyVHlwZTogRmFtaXguVHlwZSB8IEZhbWl4LkNsYXNzIHwgRmFtaXguSW50ZXJmYWNlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAvLyBnZXQgYSBUeXBlUmVmZXJlbmNlIGZyb20gYSBUeXBlTm9kZVxyXG4gICAgICAgIGNvbnN0IHR5cGVSZWZlcmVuY2UgPSBlbGVtZW50LmdldFR5cGUoKTtcclxuICAgICAgICAvLyBnZXQgYSBUeXBlRGVjbGFyYXRpb24gZnJvbSBhIFR5cGVSZWZlcmVuY2VcclxuICAgICAgICBjb25zdCB0eXBlRGVjbGFyYXRpb24gPSB0eXBlUmVmZXJlbmNlLmdldFN5bWJvbCgpPy5nZXREZWNsYXJhdGlvbnMoKVswXSBhcyBUU01vcnBoVHlwZURlY2xhcmF0aW9uO1xyXG5cclxuICAgICAgICBsZXQgaXNDbGFzc09ySW50ZXJmYWNlID0gZmFsc2U7XHJcbiAgICAgICAgaWYgKHRoaXMuZm14Q2xhc3NNYXAuaGFzKHBhcmFtZXRlclR5cGVOYW1lKSl7XHJcbiAgICAgICAgICAgIHRoaXMuZm14Q2xhc3NNYXAuZm9yRWFjaCgob2JqLCBuYW1lKSA9PiB7XHJcbiAgICAgICAgICAgICAgICBpZihvYmogaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljQ2xhc3Mpe1xyXG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBlbGVtZW50LmdldFRleHQoKSAmJiBvYmouZ2VuZXJpY1BhcmFtZXRlcnMuc2l6ZT4wKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2xhc3NPckludGVyZmFjZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IGVsZW1lbnQuZ2V0VGV4dCgpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2xhc3NPckludGVyZmFjZSA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICAgICAgfSBcclxuICAgICAgICAgICAgICAgIH0gICBcclxuICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAodGhpcy5mbXhJbnRlcmZhY2VNYXAuaGFzKHBhcmFtZXRlclR5cGVOYW1lKSl7XHJcbiAgICAgICAgICAgIHRoaXMuZm14SW50ZXJmYWNlTWFwLmZvckVhY2goKG9iaiwgbmFtZSkgPT4ge1xyXG4gICAgICAgICAgICAgICAgaWYob2JqIGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSl7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IGVsZW1lbnQuZ2V0VGV4dCgpICYmIG9iai5nZW5lcmljUGFyYW1ldGVycy5zaXplPjApIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZSA9IG9iajtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXNDbGFzc09ySW50ZXJmYWNlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9IFxyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBpZiAobmFtZSA9PT0gZWxlbWVudC5nZXRUZXh0KCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZSA9IG9iajtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaXNDbGFzc09ySW50ZXJmYWNlID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgICAgICB9IFxyXG4gICAgICAgICAgICAgICAgfSAgIFxyXG4gICAgICAgICAgICB9KTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmKCFpc0NsYXNzT3JJbnRlcmZhY2Upe1xyXG4gICAgICAgICAgICBpZiAoIXRoaXMuZm14VHlwZU1hcC5oYXModHlwZURlY2xhcmF0aW9uKSkgeyAgICBcclxuICAgICAgICAgICAgICAgIC8vIFRPRE8gcmVmYWN0b3IgXHJcbiAgICAgICAgICAgICAgICBpZiAoaXNQcmltaXRpdmVUeXBlKHBhcmFtZXRlclR5cGVOYW1lKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBuZXcgRmFtaXguUHJpbWl0aXZlVHlwZSgpO1xyXG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUuaXNTdHViID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZSA9IG5ldyBGYW1peC5QYXJhbWV0ZXJUeXBlKCk7XHJcbiAgICAgICAgICAgICAgICB9IFxyXG4gICAgXHJcbiAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJUeXBlLm5hbWUgPSBwYXJhbWV0ZXJUeXBlTmFtZTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhQYXJhbWV0ZXJUeXBlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZm14VHlwZU1hcC5zZXQodHlwZURlY2xhcmF0aW9uLCBmbXhQYXJhbWV0ZXJUeXBlKTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14UGFyYW1ldGVyVHlwZSx0eXBlUGFyYW1ldGVyRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5mbXhUeXBlTWFwLmdldCh0eXBlRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSByZXN1bHQ7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggdHlwZSAke3R5cGVEZWNsYXJhdGlvbn0gaXMgbm90IGZvdW5kIGluIHRoZSBUeXBlIG1hcC5gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWZteFBhcmFtZXRlclR5cGUpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmbXhQYXJhbWV0ZXJUeXBlIHdhcyB1bmRlZmluZWQgZm9yIHBhcmFtZXRlclR5cGVOYW1lICR7cGFyYW1ldGVyVHlwZU5hbWV9YCk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHJldHVybiBmbXhQYXJhbWV0ZXJUeXBlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IHZhcmlhYmxlXHJcbiAgICAgKiBAcGFyYW0gdmFyaWFibGUgQSB2YXJpYWJsZVxyXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSB2YXJpYWJsZVxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY3JlYXRlT3JHZXRGYW1peFZhcmlhYmxlKHZhcmlhYmxlOiBWYXJpYWJsZURlY2xhcmF0aW9uKTogRmFtaXguVmFyaWFibGUge1xyXG4gICAgICAgIGlmICh0aGlzLmZteFZhcmlhYmxlTWFwLmhhcyh2YXJpYWJsZSkpIHtcclxuICAgICAgICAgICAgY29uc3QgclZhcmlhYmxlID0gdGhpcy5mbXhWYXJpYWJsZU1hcC5nZXQodmFyaWFibGUpO1xyXG4gICAgICAgICAgICBpZiAoclZhcmlhYmxlKSB7IFxyXG4gICAgICAgICAgICAgICByZXR1cm4gclZhcmlhYmxlO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYW1peCBwYXJhbWV0ZXIgJHt2YXJpYWJsZS5nZXROYW1lKCl9IGlzIG5vdCBmb3VuZCBpbiB0aGUgdmFyaWFibGUgbWFwLmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGZteFZhcmlhYmxlID0gbmV3IEZhbWl4LlZhcmlhYmxlKCk7XHJcbiAgICBcclxuICAgICAgICBsZXQgdmFyaWFibGVUeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTtcclxuICAgICAgICB0cnkge1xyXG4gICAgICAgICAgICB2YXJpYWJsZVR5cGVOYW1lID0gdmFyaWFibGUuZ2V0VHlwZSgpLmdldFRleHQoKS50cmltKCk7XHJcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGA+IFdBUk5JTkc6IGdvdCBleGNlcHRpb24gJHtlcnJvcn0uIEZhaWxlZCB0byBnZXQgdXNhYmxlIG5hbWUgZm9yIHZhcmlhYmxlOiAke3ZhcmlhYmxlLmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcclxuICAgICAgICB9XHJcbiAgICBcclxuICAgICAgICBjb25zdCBmbXhUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZSh2YXJpYWJsZVR5cGVOYW1lLCB2YXJpYWJsZSk7XHJcbiAgICAgICAgZm14VmFyaWFibGUuZGVjbGFyZWRUeXBlID0gZm14VHlwZTtcclxuICAgICAgICBmbXhWYXJpYWJsZS5uYW1lID0gdmFyaWFibGUuZ2V0TmFtZSgpO1xyXG4gICAgICAgIGluaXRGUU4odmFyaWFibGUsIGZteFZhcmlhYmxlKTtcclxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcih2YXJpYWJsZSwgZm14VmFyaWFibGUpO1xyXG4gICAgXHJcbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFZhcmlhYmxlKTtcclxuICAgIFxyXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14VmFyaWFibGUsdmFyaWFibGUpO1xyXG4gICAgICAgIHRoaXMuZm14VmFyaWFibGVNYXAuc2V0KHZhcmlhYmxlLCBmbXhWYXJpYWJsZSk7XHJcbiAgICBcclxuICAgICAgICByZXR1cm4gZm14VmFyaWFibGU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggZW51bVxyXG4gICAgICogQHBhcmFtIGVudW1FbnRpdHkgQW4gZW51bVxyXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBlbnVtXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4RW51bShlbnVtRW50aXR5OiBFbnVtRGVjbGFyYXRpb24pOiBGYW1peC5FbnVtIHtcclxuICAgICAgICBpZiAodGhpcy5mbXhFbnVtTWFwLmhhcyhlbnVtRW50aXR5KSkge1xyXG4gICAgICAgICAgICBjb25zdCByRW51bSA9IHRoaXMuZm14RW51bU1hcC5nZXQoZW51bUVudGl0eSk7XHJcbiAgICAgICAgICAgIGlmIChyRW51bSkgeyBcclxuICAgICAgICAgICAgICAgcmV0dXJuIHJFbnVtO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYW1peCBlbnVtICR7ZW51bUVudGl0eS5nZXROYW1lKCl9IGlzIG5vdCBmb3VuZCBpbiB0aGUgZW51bSBtYXAuYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgY29uc3QgZm14RW51bSA9IG5ldyBGYW1peC5FbnVtKCk7XHJcbiAgICAgICAgZm14RW51bS5uYW1lID0gZW51bUVudGl0eS5nZXROYW1lKCk7XHJcbiAgICAgICAgaW5pdEZRTihlbnVtRW50aXR5LCBmbXhFbnVtKTtcclxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihlbnVtRW50aXR5LCBmbXhFbnVtKTtcclxuXHJcbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEVudW0pO1xyXG5cclxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEVudW0sZW51bUVudGl0eSk7XHJcbiAgICAgICAgdGhpcy5mbXhFbnVtTWFwLnNldChlbnVtRW50aXR5LCBmbXhFbnVtKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGZteEVudW07XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggZW51bSB2YWx1ZVxyXG4gICAgICogQHBhcmFtIGVudW1NZW1iZXIgQW4gZW51bSBtZW1iZXJcclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgZW51bSBtZW1iZXJcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4RW51bVZhbHVlKGVudW1NZW1iZXI6IEVudW1NZW1iZXIpOiBGYW1peC5FbnVtVmFsdWUge1xyXG4gICAgICAgIGNvbnN0IGZteEVudW1WYWx1ZSA9IG5ldyBGYW1peC5FbnVtVmFsdWUoKTtcclxuXHJcbiAgICAgICAgbGV0IGVudW1WYWx1ZVR5cGVOYW1lID0gdGhpcy5VTktOT1dOX1ZBTFVFO1xyXG4gICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgIGVudW1WYWx1ZVR5cGVOYW1lID0gZW51bU1lbWJlci5nZXRUeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcclxuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xyXG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYD4gV0FSTklORzogZ290IGV4Y2VwdGlvbiAke2Vycm9yfS4gRmFpbGVkIHRvIGdldCB1c2FibGUgbmFtZSBmb3IgZW51bSB2YWx1ZTogJHtlbnVtTWVtYmVyLmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGVudW1WYWx1ZVR5cGVOYW1lLCBlbnVtTWVtYmVyKTtcclxuICAgICAgICBmbXhFbnVtVmFsdWUuZGVjbGFyZWRUeXBlID0gZm14VHlwZTtcclxuICAgICAgICBmbXhFbnVtVmFsdWUubmFtZSA9IGVudW1NZW1iZXIuZ2V0TmFtZSgpO1xyXG4gICAgICAgIGluaXRGUU4oZW51bU1lbWJlciwgZm14RW51bVZhbHVlKTtcclxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihlbnVtTWVtYmVyLCBmbXhFbnVtVmFsdWUpO1xyXG5cclxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14RW51bVZhbHVlKTtcclxuXHJcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhFbnVtVmFsdWUsZW51bU1lbWJlcik7XHJcblxyXG4gICAgICAgIHJldHVybiBmbXhFbnVtVmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBkZWNvcmF0b3JcclxuICAgICAqIEBwYXJhbSBkZWNvcmF0b3IgQSBkZWNvcmF0b3JcclxuICAgICAqIEBwYXJhbSBkZWNvcmF0ZWRFbnRpdHkgQSBjbGFzcywgYSBtZXRob2QsIGEgcGFyYW1ldGVyIG9yIGEgcHJvcGVydHlcclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgZGVjb3JhdG9yXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4RGVjb3JhdG9yKGRlY29yYXRvcjogRGVjb3JhdG9yLCBkZWNvcmF0ZWRFbnRpdHk6IENsYXNzRGVjbGFyYXRpb24gfCBNZXRob2REZWNsYXJhdGlvbiB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgUGFyYW1ldGVyRGVjbGFyYXRpb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uKTogRmFtaXguRGVjb3JhdG9yIHtcclxuICAgICAgICBjb25zdCBmbXhEZWNvcmF0b3IgPSBuZXcgRmFtaXguRGVjb3JhdG9yKCk7XHJcbiAgICAgICAgY29uc3QgZGVjb3JhdG9yTmFtZSA9IFwiQFwiICsgZGVjb3JhdG9yLmdldE5hbWUoKTtcclxuICAgICAgICBjb25zdCBkZWNvcmF0b3JFeHByZXNzaW9uID0gZGVjb3JhdG9yLmdldFRleHQoKS5zdWJzdHJpbmcoMSk7XHJcblxyXG4gICAgICAgIGZteERlY29yYXRvci5uYW1lID0gZGVjb3JhdG9yTmFtZTtcclxuICAgICAgICBmbXhEZWNvcmF0b3IuZGVjb3JhdG9yRXhwcmVzc2lvbiA9IGRlY29yYXRvckV4cHJlc3Npb247XHJcbiAgICAgICAgY29uc3QgZGVjb3JhdGVkRW50aXR5RnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihkZWNvcmF0ZWRFbnRpdHkpO1xyXG4gICAgICAgIGNvbnN0IGZteERlY29yYXRlZEVudGl0eSA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShkZWNvcmF0ZWRFbnRpdHlGdWxseVF1YWxpZmllZE5hbWUpIGFzIEZhbWl4Lk5hbWVkRW50aXR5O1xyXG4gICAgICAgIGZteERlY29yYXRvci5kZWNvcmF0ZWRFbnRpdHkgPSBmbXhEZWNvcmF0ZWRFbnRpdHk7XHJcbiAgICAgICAgaW5pdEZRTihkZWNvcmF0b3IsIGZteERlY29yYXRvcik7XHJcbiAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoZGVjb3JhdG9yLCBmbXhEZWNvcmF0b3IpO1xyXG5cclxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14RGVjb3JhdG9yKTtcclxuXHJcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhEZWNvcmF0b3IsZGVjb3JhdG9yKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIGZteERlY29yYXRvcjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb21tZW50XHJcbiAgICAgKiBAcGFyYW0gY29tbWVudCBBIGNvbW1lbnRcclxuICAgICAqIEBwYXJhbSBmbXhTY29wZSBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGNvbW1lbnQncyBjb250YWluZXJcclxuICAgICAqIEBwYXJhbSBpc0pTRG9jIEEgYm9vbGVhbiBpbmRpY2F0aW5nIGlmIHRoZSBjb21tZW50IGlzIGEgSlNEb2NcclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgY29tbWVudFxyXG4gICAgICovXHJcbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb21tZW50KGNvbW1lbnQ6IENvbW1lbnRSYW5nZSwgZm14U2NvcGU6IEZhbWl4Lk5hbWVkRW50aXR5LCBpc0pTRG9jOiBib29sZWFuKTogRmFtaXguQ29tbWVudCB7XHJcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGA+IE5PVEU6IGNyZWF0aW5nIGNvbW1lbnQgJHtjb21tZW50LmdldFRleHQoKX0gaW4gc2NvcGUgJHtmbXhTY29wZS5uYW1lfS5gKTtcclxuICAgICAgICBjb25zdCBmbXhDb21tZW50ID0gbmV3IEZhbWl4LkNvbW1lbnQoKTtcclxuICAgICAgICBmbXhDb21tZW50LmNvbnRhaW5lciA9IGZteFNjb3BlOyAgLy8gYWRkcyBjb21tZW50IHRvIHRoZSBjb250YWluZXIncyBjb21tZW50cyBjb2xsZWN0aW9uXHJcbiAgICAgICAgZm14Q29tbWVudC5pc0pTRG9jID0gaXNKU0RvYztcclxuXHJcbiAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoY29tbWVudCwgZm14Q29tbWVudCk7XHJcblxyXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhDb21tZW50KTtcclxuXHJcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhDb21tZW50LGNvbW1lbnQpO1xyXG5cclxuICAgICAgICByZXR1cm4gZm14Q29tbWVudDtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgb3IgZ2V0cyBhIEZhbWl4IHR5cGVcclxuICAgICAqIEBwYXJhbSB0eXBlTmFtZSBBIHR5cGUgbmFtZVxyXG4gICAgICogQHBhcmFtIGVsZW1lbnQgQSB0cy1tb3JwaCBlbGVtZW50XHJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHR5cGVcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhUeXBlKHR5cGVOYW1lOiBzdHJpbmcsIGVsZW1lbnQ6IFRTTW9ycGhUeXBlRGVjbGFyYXRpb24pOiBGYW1peC5UeXBlIHtcclxuICAgICAgICBsZXQgZm14VHlwZTogRmFtaXguVHlwZTtcclxuICAgICAgICBjb25zdCBpc1ByaW1pdGl2ZSA9IGlzUHJpbWl0aXZlVHlwZSh0eXBlTmFtZSk7XHJcbiAgICAgICAgY29uc3QgaXNQYXJhbWV0cmljVHlwZSA9XHJcbiAgICAgICAgICAgIGVsZW1lbnQgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uICYmIGVsZW1lbnQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwIHx8XHJcbiAgICAgICAgICAgIGVsZW1lbnQgaW5zdGFuY2VvZiBJbnRlcmZhY2VEZWNsYXJhdGlvbiAmJiBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDsgXHJcblxyXG4gICAgICAgICAgICAvLyBGdW5jdGlvbnMgYW5kIG1ldGhvZHMgYXJlbid0IHR5cGVzIVxyXG4gICAgICAgICAgICAvLyB8fFxyXG4gICAgICAgICAgICAvLyBlbGVtZW50IGluc3RhbmNlb2YgRnVuY3Rpb25EZWNsYXJhdGlvbiAmJiBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMCB8fFxyXG4gICAgICAgICAgICAvLyBlbGVtZW50IGluc3RhbmNlb2YgTWV0aG9kRGVjbGFyYXRpb24gJiYgZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDAgfHxcclxuICAgICAgICAgICAgLy8gZWxlbWVudCBpbnN0YW5jZW9mIEFycm93RnVuY3Rpb24gJiYgZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDA7XHJcblxyXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhcIkNyZWF0aW5nIChvciBnZXR0aW5nKSB0eXBlOiAnXCIgKyB0eXBlTmFtZSArIFwiJyBvZiBlbGVtZW50OiBcIiArIGVsZW1lbnQ/LmdldFRleHQoKSArIFwiIG9mIGtpbmQ6IFwiICsgZWxlbWVudD8uZ2V0S2luZE5hbWUoKSk7XHJcblxyXG4gICAgICAgIGlmIChpc1ByaW1pdGl2ZSkge1xyXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPckdldEZhbWl4UHJpbWl0aXZlVHlwZSh0eXBlTmFtZSk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoaXNQYXJhbWV0cmljVHlwZSkge1xyXG4gICAgICAgICAgICAvLyBuYXJyb3cgdGhlIHR5cGVcclxuICAgICAgICAgICAgY29uc3QgcGFyYW1ldHJpY0VsZW1lbnQgPSBlbGVtZW50IGFzIFRTTW9ycGhQYXJhbWV0cmljVHlwZTtcclxuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlT3JHZXRGYW1peFBhcmFtZXRyaWNUeXBlKHR5cGVOYW1lLCBwYXJhbWV0cmljRWxlbWVudCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXRoaXMuZm14VHlwZU1hcC5oYXMoZWxlbWVudCkpIHtcclxuICAgICAgICAgICAgbGV0IGFuY2VzdG9yOiBGYW1peC5Db250YWluZXJFbnRpdHkgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XHJcbiBcclxuICAgICAgICAgICAgaWYgKGVsZW1lbnQgIT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgdHlwZUFuY2VzdG9yID0gSGVscGVycy5maW5kVHlwZUFuY2VzdG9yKGVsZW1lbnQpO1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0eXBlQW5jZXN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFuY2VzdG9yIG5vdCBmb3VuZCBmb3IgZWxlbWVudCAke2VsZW1lbnQuZ2V0VGV4dCgpfS5gKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIGNvbnN0IGFuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTih0eXBlQW5jZXN0b3IpO1xyXG4gICAgICAgICAgICAgICAgYW5jZXN0b3IgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUoYW5jZXN0b3JGdWxseVF1YWxpZmllZE5hbWUpIGFzIEZhbWl4LkNvbnRhaW5lckVudGl0eTtcclxuICAgICAgICAgICAgICAgIGlmICghYW5jZXN0b3IpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYEFuY2VzdG9yICR7RlFORnVuY3Rpb25zLmdldEZRTih0eXBlQW5jZXN0b3IpfSBub3QgZm91bmQuIEFkZGluZyB0aGUgbmV3IHR5cGUuYCk7XHJcbiAgICAgICAgICAgICAgICAgICAgYW5jZXN0b3IgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKHR5cGVBbmNlc3Rvci5nZXRUZXh0KCksIHR5cGVBbmNlc3RvciBhcyBUU01vcnBoVHlwZURlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgZm14VHlwZSA9IG5ldyBGYW1peC5UeXBlKCk7XHJcbiAgICAgICAgICAgIGZteFR5cGUubmFtZSA9IHR5cGVOYW1lO1xyXG5cclxuICAgICAgICAgICAgaWYgKCFhbmNlc3Rvcikge1xyXG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBbmNlc3RvciBub3QgZm91bmQgZm9yIHR5cGUgJHt0eXBlTmFtZX0uYCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgZm14VHlwZS5jb250YWluZXIgPSBhbmNlc3RvcjtcclxuICAgICAgICAgICAgaW5pdEZRTihlbGVtZW50LCBmbXhUeXBlKTtcclxuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoZWxlbWVudCwgZm14VHlwZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14VHlwZSk7XHJcblxyXG4gICAgICAgICAgICB0aGlzLmZteFR5cGVNYXAuc2V0KGVsZW1lbnQsIGZteFR5cGUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5mbXhUeXBlTWFwLmdldChlbGVtZW50KTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgZm14VHlwZSA9IHJlc3VsdDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggdHlwZSAke3R5cGVOYW1lfSBpcyBub3QgZm91bmQgaW4gdGhlIFR5cGUgbWFwLmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteFR5cGUsZWxlbWVudCk7XHJcblxyXG4gICAgICAgIHJldHVybiBmbXhUeXBlO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggdHlwZSB0aGF0IGlzIHBhcmFtZXRyaWNcclxuICAgICAqIEBwYXJhbSB0eXBlTmFtZSBBIHR5cGUgbmFtZVxyXG4gICAgICogQHBhcmFtIGVsZW1lbnQgQSB0cy1tb3JwaCBlbGVtZW50XHJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHBhcmFtZXRlciB0eXBlXHJcbiAgICAgKi9cclxuICAgIGNyZWF0ZU9yR2V0RmFtaXhQYXJhbWV0cmljVHlwZSh0eXBlTmFtZTogc3RyaW5nLCBlbGVtZW50OiBUU01vcnBoUGFyYW1ldHJpY1R5cGUpOiBGYW1peC5UeXBlIHtcclxuXHJcbiAgICAgICAgaWYgKHRoaXMuZm14VHlwZU1hcC5oYXMoZWxlbWVudCkgPT09IHRydWUpIHtcclxuICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5mbXhUeXBlTWFwLmdldChlbGVtZW50KTtcclxuICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIHJlc3VsdDtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggdHlwZSAke3R5cGVOYW1lfSBpcyBub3QgZm91bmQgKHVuZGVmaW5lZCkgaW4gdGhlIFR5cGUgbWFwLmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBBIHBhcmFtZXRyaWMgdHlwZSBpcyBhIHR5cGUgdGhhdCBoYXMgdHlwZSBwYXJhbWV0ZXJzLCBlLmcuLCBMaXN0PFQ+XHJcbiAgICAgICAgLy8gSW4gVFMgaXQgY2FuIGJlIGEgY2xhc3MsIGFuIGludGVyZmFjZSwgYSBmdW5jdGlvbiwgYW4gYXJyb3cgZnVuY3Rpb24sIG9yIGEgbWV0aG9kXHJcblxyXG4gICAgICAgIC8vIGNyZWF0ZSB0aGUgRmFtaXggUGFyYW1ldHJpYyBUeXBlIChtYXliZSBpdCdzIGp1c3QgYW4gSW50ZXJmYWNlLCBldGMuKVxyXG4gICAgICAgIGxldCBmbXhUeXBlOiBGYW1peC5UeXBlO1xyXG5cclxuICAgICAgICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIENsYXNzRGVjbGFyYXRpb24pIHtcclxuICAgICAgICAgICAgZm14VHlwZSA9IG5ldyBGYW1peC5QYXJhbWV0cmljQ2xhc3MoKTtcclxuICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBJbnRlcmZhY2VEZWNsYXJhdGlvbikge1xyXG4gICAgICAgICAgICBmbXhUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gZnVuY3Rpb25zIGFuZCBtZXRob2RzIGFyZSBub3QgdHlwZXMgXHJcbiAgICAgICAgLy8gZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEZ1bmN0aW9uRGVjbGFyYXRpb24pIHtcclxuICAgICAgICAvLyAgICAgZm14VHlwZSA9IG5ldyBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24oKTtcclxuICAgICAgICAvLyB9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBBcnJvd0Z1bmN0aW9uKSB7XHJcbiAgICAgICAgLy8gICAgIGZteFR5cGUgPSBuZXcgRmFtaXguUGFyYW1ldHJpY0Fycm93RnVuY3Rpb24oKTtcclxuICAgICAgICAvLyB9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBNZXRob2REZWNsYXJhdGlvbikge1xyXG4gICAgICAgIC8vICAgICBmbXhUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNNZXRob2QoKTtcclxuICAgICAgICAvLyB9IFxyXG4gICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEVsZW1lbnQgaXMgbm90IGEgY2xhc3MsIGludGVyZmFjZSwgZnVuY3Rpb24sIGFycm93IGZ1bmN0aW9uLCBvciBtZXRob2QuYCk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBjb25zdCBwYXJhbWV0ZXJzID0gZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpO1xyXG5cclxuICAgICAgICAvLyAvLyBmb3IgZWFjaCBwYXJhbWV0ZXIsIGdldE9yQ3JlYXRlIHRoZSBGYW1peFBhcmFtZXRlclR5cGVcclxuICAgICAgICAvLyBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBwYXJhbWV0ZXJzKSB7XHJcbiAgICAgICAgLy8gICAgIHRoaXMuY3JlYXRlT3JHZXRGYW1peFBhcmFtZXRlclR5cGUocGFyYW1ldGVyLmdldE5hbWUoKSwgcGFyYW1ldGVyKTtcclxuICAgICAgICAvLyB9XHJcblxyXG4gICAgICAgIC8vIC8vIFRPRE86IHRoZSBmb2xsb3dpbmcgY29kZSBpcyBub3QgY29ycmVjdCwgaXQgaXMganVzdCBhIHBsYWNlaG9sZGVyXHJcbiAgICAgICAgLy8gY29uc3QgcGFyYW1ldGVyVHlwZU5hbWVzID0gdHlwZU5hbWUuc3Vic3RyaW5nKHR5cGVOYW1lLmluZGV4T2YoXCI8XCIpICsgMSwgdHlwZU5hbWUuaW5kZXhPZihcIj5cIikpXHJcbiAgICAgICAgLy8gICAgIC5zcGxpdChcIixcIikubWFwKHMgPT4gcy50cmltKCkpO1xyXG4gICAgICAgIC8vIGNvbnN0IGJhc2VUeXBlTmFtZSA9IHR5cGVOYW1lLnN1YnN0cmluZygwLCB0eXBlTmFtZS5pbmRleE9mKFwiPFwiKSkudHJpbSgpO1xyXG4gICAgICAgIC8vIHBhcmFtZXRlclR5cGVOYW1lcy5mb3JFYWNoKHBhcmFtZXRlclR5cGVOYW1lID0+IHtcclxuICAgICAgICAvLyAgICAgY29uc3QgZm14UGFyYW1ldGVyVHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFBhcmFtZXRlclR5cGUocGFyYW1ldGVyVHlwZU5hbWUsIGVsZW1lbnQpO1xyXG4gICAgICAgIC8vICAgICAoZm14VHlwZSBhcyBGYW1peC5QYXJhbWV0ZXJUeXBlKS5hZGRBcmd1bWVudChmbXhQYXJhbWV0ZXJUeXBlKTtcclxuICAgICAgICAvLyB9KTtcclxuICAgICAgICAvLyBjb25zdCBmbXhCYXNlVHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoYmFzZVR5cGVOYW1lLCBlbGVtZW50KTtcclxuXHJcbiAgICAgICAgLy8gKGZteFR5cGUgYXMgRmFtaXguUGFyYW1ldGVyVHlwZSkuYmFzZVR5cGUgPSBmbXhCYXNlVHlwZTtcclxuXHJcbiAgICAgICAgZm14VHlwZS5uYW1lID0gdHlwZU5hbWU7XHJcbiAgICAgICAgaW5pdEZRTihlbGVtZW50LCBmbXhUeXBlKTtcclxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14VHlwZSk7XHJcbiAgICAgICAgdGhpcy5mbXhUeXBlTWFwLnNldChlbGVtZW50LCBmbXhUeXBlKTtcclxuICAgICAgICByZXR1cm4gZm14VHlwZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSB0eXBlIGZvciBhIHBhcmFtZXRlciBpbiBhIHBhcmFtZXRyaWMgdHlwZSwgZS5nLiwgVCBpbiBMaXN0PFQ+XHJcbiAgICAgKiBAcGFyYW0gcGFyYW1ldGVyVHlwZU5hbWUgXHJcbiAgICAgKiBAcGFyYW0gZWxlbWVudCB0aGUgVHlwZVNjcmlwdCBlbGVtZW50IChUU01vcnBoUGFyYW1ldHJpY1R5cGUpIHRoYXQgdGhlIHR5cGUgaXMgYXNzb2NpYXRlZCB3aXRoXHJcbiAgICAgKiBAcmV0dXJucyBcclxuICAgICAqL1xyXG4gICAgLy8gY3JlYXRlT3JHZXRGYW1peFBhcmFtZXRlclR5cGUocGFyYW1ldGVyVHlwZU5hbWU6IHN0cmluZywgZWxlbWVudDogUGFyYW1ldGVyRGVjbGFyYXRpb24pIHtcclxuICAgIC8vICAgICBpZiAodGhpcy5mbXhUeXBlTWFwLmhhcyhlbGVtZW50KSkge1xyXG4gICAgLy8gICAgICAgICByZXR1cm4gdGhpcy5mbXhUeXBlTWFwLmdldChlbGVtZW50KSBhcyBGYW1peC5QYXJhbWV0ZXJUeXBlO1xyXG4gICAgLy8gICAgIH1cclxuXHJcbiAgICAvLyAgICAgLy8gZGV0ZXJtaW5lIGlmIGVsZW1lbnQgaXMgYSBcclxuICAgIC8vICAgICBjb25zdCBmbXhUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRlclR5cGUoKTtcclxuICAgIC8vICAgICAvLyBjb25zdCBwYXJhbWV0ZXJUeXBlTmFtZXMgPSB0eXBlTmFtZS5zdWJzdHJpbmcodHlwZU5hbWUuaW5kZXhPZihcIjxcIikgKyAxLCB0eXBlTmFtZS5pbmRleE9mKFwiPlwiKSlcclxuICAgIC8vICAgICAvLyAgICAgLnNwbGl0KFwiLFwiKS5tYXAocyA9PiBzLnRyaW0oKSk7XHJcbiAgICAvLyAgICAgLy8gY29uc3QgYmFzZVR5cGVOYW1lID0gdHlwZU5hbWUuc3Vic3RyaW5nKDAsIHR5cGVOYW1lLmluZGV4T2YoXCI8XCIpKS50cmltKCk7XHJcbiAgICAvLyAgICAgLy8gcGFyYW1ldGVyVHlwZU5hbWVzLmZvckVhY2gocGFyYW1ldGVyVHlwZU5hbWUgPT4ge1xyXG4gICAgLy8gICAgIC8vICAgICBjb25zdCBmbXhQYXJhbWV0ZXJUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4UGFyYW1ldGVyVHlwZShwYXJhbWV0ZXJUeXBlTmFtZSwgZWxlbWVudCk7XHJcbiAgICAvLyAgICAgLy8gICAgIChmbXhUeXBlIGFzIEZhbWl4LlBhcmFtZXRlclR5cGUpLmFkZEFyZ3VtZW50KGZteFBhcmFtZXRlclR5cGUpO1xyXG4gICAgLy8gICAgIC8vIH0pO1xyXG4gICAgLy8gICAgIGNvbnN0IGZteEJhc2VUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShiYXNlVHlwZU5hbWUsIGVsZW1lbnQpO1xyXG4gICAgLy8gICAgIChmbXhUeXBlIGFzIEZhbWl4LlBhcmFtZXRlclR5cGUpLmJhc2VUeXBlID0gZm14QmFzZVR5cGU7XHJcbiAgICAvLyAgICAgaW5pdEZRTihlbGVtZW50LCBmbXhUeXBlKTtcclxuICAgIC8vICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14VHlwZSk7XHJcbiAgICAvLyAgICAgdGhpcy5mbXhUeXBlTWFwLnNldChlbGVtZW50LCBmbXhUeXBlKTtcclxuICAgIC8vICAgICByZXR1cm4gZm14VHlwZTtcclxuICAgIC8vIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgb3IgZ2V0cyBhIEZhbWl4IHByaW1pdGl2ZSB0eXBlXHJcbiAgICAgKiBAcGFyYW0gdHlwZU5hbWUgQSB0eXBlIG5hbWVcclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgcHJpbWl0aXZlIHR5cGVcclxuICAgICAqL1xyXG4gICAgY3JlYXRlT3JHZXRGYW1peFByaW1pdGl2ZVR5cGUodHlwZU5hbWU6IHN0cmluZyk6IEZhbWl4LlByaW1pdGl2ZVR5cGUge1xyXG4gICAgICAgIGxldCBmbXhUeXBlOiBGYW1peC5QcmltaXRpdmVUeXBlID0gbmV3IEZhbWl4LlByaW1pdGl2ZVR5cGUoKTtcclxuICAgICAgICBpZiAoIXRoaXMuZm14UHJpbWl0aXZlVHlwZU1hcC5oYXModHlwZU5hbWUpKSB7XHJcbiAgICAgICAgICAgIGZteFR5cGUgPSBuZXcgRmFtaXguUHJpbWl0aXZlVHlwZSgpO1xyXG4gICAgICAgICAgICBmbXhUeXBlLmlzU3R1YiA9IHRydWU7XHJcbiAgICAgICAgICAgIGZteFR5cGUubmFtZSA9IHR5cGVOYW1lO1xyXG4gICAgICAgICAgICB0aGlzLmZteFByaW1pdGl2ZVR5cGVNYXAuc2V0KHR5cGVOYW1lLCBmbXhUeXBlKTtcclxuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFR5cGUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGZteFR5cGUgPSB0aGlzLmZteFByaW1pdGl2ZVR5cGVNYXAuZ2V0KHR5cGVOYW1lKSBhcyBGYW1peC5QcmltaXRpdmVUeXBlO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gZm14VHlwZTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBhY2Nlc3NcclxuICAgICAqIEBwYXJhbSBub2RlIEEgbm9kZVxyXG4gICAgICogQHBhcmFtIGlkIEFuIGlkIG9mIGEgcGFyYW1ldGVyLCBhIHZhcmlhYmxlLCBhIHByb3BlcnR5IG9yIGFuIGVudW0gbWVtYmVyXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVGYW1peEFjY2Vzcyhub2RlOiBJZGVudGlmaWVyLCBpZDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICAgICAgY29uc3QgZm14VmFyID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5SWQoaWQpIGFzIEZhbWl4LlN0cnVjdHVyYWxFbnRpdHk7XHJcbiAgICAgICAgaWYgKCFmbXhWYXIpIHtcclxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYW1peCBlbnRpdHkgd2l0aCBpZCAke2lkfSBub3QgZm91bmQsIGZvciBub2RlICR7bm9kZS5nZXRUZXh0KCl9IGluICR7bm9kZS5nZXRTb3VyY2VGaWxlKCkuZ2V0QmFzZU5hbWUoKX0gYXQgbGluZSAke25vZGUuZ2V0U3RhcnRMaW5lTnVtYmVyKCl9LmApO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBGYW1peEFjY2Vzcy4gTm9kZTogWyR7bm9kZS5nZXRLaW5kTmFtZSgpfV0gJyR7bm9kZS5nZXRUZXh0KCl9JyBhdCBsaW5lICR7bm9kZS5nZXRTdGFydExpbmVOdW1iZXIoKX0gaW4gJHtub2RlLmdldFNvdXJjZUZpbGUoKS5nZXRCYXNlTmFtZSgpfSwgaWQ6ICR7aWR9IHJlZmVycyB0byBmbXhWYXIgJyR7Zm14VmFyLmZ1bGx5UXVhbGlmaWVkTmFtZX0nLmApO1xyXG5cclxuICAgICAgICBjb25zdCBub2RlUmVmZXJlbmNlQW5jZXN0b3IgPSBIZWxwZXJzLmZpbmRBbmNlc3Rvcihub2RlKTtcclxuICAgICAgICBjb25zdCBhbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4obm9kZVJlZmVyZW5jZUFuY2VzdG9yKTtcclxuICAgICAgICBjb25zdCBhY2Nlc3NvciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShhbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgRmFtaXguQ29udGFpbmVyRW50aXR5O1xyXG4gICAgICAgIGlmICghYWNjZXNzb3IpIHtcclxuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBBbmNlc3RvciAke2FuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lfSBvZiBraW5kICR7bm9kZVJlZmVyZW5jZUFuY2VzdG9yLmdldEtpbmROYW1lKCl9IG5vdCBmb3VuZC5gKTtcclxuICAgICAgICAgICAgLy8gYWNjZXNzb3IgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGFuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lLCBub2RlUmVmZXJlbmNlQW5jZXN0b3IgYXMgVHlwZURlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgcmV0dXJuOyAvLyBiYWlsIG91dCBUT0RPOiB0aGlzIGlzIHByb2JhYmx5IHdyb25nXHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCBhY2Nlc3NvciB0byBiZSAke2FjY2Vzc29yLmZ1bGx5UXVhbGlmaWVkTmFtZX0uYCk7XHJcbiAgICAgICAgfVxyXG5cclxuXHJcbiAgICAgICAgLy8gbWFrZSBzdXJlIGFjY2Vzc29yIGlzIGEgbWV0aG9kLCBmdW5jdGlvbiwgc2NyaXB0IG9yIG1vZHVsZVxyXG4gICAgICAgIGlmICghKGFjY2Vzc29yIGluc3RhbmNlb2YgRmFtaXguTWV0aG9kKSAmJiAhKGFjY2Vzc29yIGluc3RhbmNlb2YgRmFtaXguQXJyb3dGdW5jdGlvbikgJiYgIShhY2Nlc3NvciBpbnN0YW5jZW9mIEZhbWl4LkZ1bmN0aW9uKSAmJiAhKGFjY2Vzc29yIGluc3RhbmNlb2YgRmFtaXguU2NyaXB0RW50aXR5KSAmJiAhKGFjY2Vzc29yIGluc3RhbmNlb2YgRmFtaXguTW9kdWxlKSkge1xyXG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYEFjY2Vzc29yICR7YWNjZXNzb3IuZnVsbHlRdWFsaWZpZWROYW1lfSBpcyBub3QgYSBtZXRob2QsIGZ1bmN0aW9uLCBldGMuYCk7XHJcbiAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIGRvbid0IGNyZWF0ZSBhbnkgZHVwbGljYXRlcyAoZS5nLiBpZiB0aGUgc2FtZSB2YXJpYWJsZSBpcyBhY2Nlc3NlZCBtdWx0aXBsZSB0aW1lcyBieSBzYW1lIGFjY2Vzc29yKVxyXG4gICAgICAgIGNvbnN0IGZvdW5kQWNjZXNzID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEFjY2Vzc0J5QWNjZXNzb3JBbmRWYXJpYWJsZShhY2Nlc3NvciwgZm14VmFyKTtcclxuICAgICAgICBpZiAoZm91bmRBY2Nlc3MpIHtcclxuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBGYW1peEFjY2VzcyBhbHJlYWR5IGV4aXN0cyBmb3IgYWNjZXNzb3IgJHthY2Nlc3Nvci5mdWxseVF1YWxpZmllZE5hbWV9IGFuZCB2YXJpYWJsZSAke2ZteFZhci5mdWxseVF1YWxpZmllZE5hbWV9LmApO1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IGZteEFjY2VzcyA9IG5ldyBGYW1peC5BY2Nlc3MoKTtcclxuICAgICAgICBmbXhBY2Nlc3MuYWNjZXNzb3IgPSBhY2Nlc3NvcjtcclxuICAgICAgICBmbXhBY2Nlc3MudmFyaWFibGUgPSBmbXhWYXI7XHJcblxyXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhBY2Nlc3MpO1xyXG5cclxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEFjY2Vzcyxub2RlKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBpbnZvY2F0aW9uXHJcbiAgICAgKiBAcGFyYW0gbm9kZVJlZmVycmluZ1RvSW52b2NhYmxlIEEgbm9kZVxyXG4gICAgICogQHBhcmFtIGludm9jYWJsZSBBIG1ldGhvZCBvciBhIGZ1bmN0aW9uXHJcbiAgICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBtZXRob2Qgb3IgdGhlIGZ1bmN0aW9uXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVGYW1peEludm9jYXRpb24obm9kZVJlZmVycmluZ1RvSW52b2NhYmxlOiBJZGVudGlmaWVyLCBpbnZvY2FibGU6IEludm9jYWJsZVR5cGUsIGlkOiBudW1iZXIpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBmbXhJbnZvY2FibGUgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlJZChpZCkgYXMgRmFtaXguQmVoYXZpb3JhbEVudGl0eTtcclxuICAgICAgICAvLyBzaW5jZSB0aGUgbm9kZSBpcyBpbiB0aGUgQVNULCB3ZSBuZWVkIHRvIGZpbmQgdGhlIGFuY2VzdG9yIHRoYXQgaXMgaW4gdGhlIEZhbWl4IG1vZGVsXHJcbiAgICAgICAgY29uc3QgY29udGFpbmVyT2ZOb2RlID0gSGVscGVycy5maW5kQW5jZXN0b3Iobm9kZVJlZmVycmluZ1RvSW52b2NhYmxlKTtcclxuICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGNvbnRhaW5lciAoYW5jZXN0b3IpICR7Y29udGFpbmVyT2ZOb2RlLmdldEtpbmROYW1lKCl9IGZvciBBU1Qgbm9kZSAke25vZGVSZWZlcnJpbmdUb0ludm9jYWJsZS5nZXRUZXh0KCl9LmApO1xyXG4gICAgICAgIGNvbnN0IGNvbnRhaW5lckZRTiA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oY29udGFpbmVyT2ZOb2RlKTtcclxuICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGNvbnRhaW5lckZRTiAke2NvbnRhaW5lckZRTn0uYCk7XHJcbiAgICAgICAgbGV0IHNlbmRlciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShjb250YWluZXJGUU4pIGFzIEZhbWl4LkNvbnRhaW5lckVudGl0eTtcclxuICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGEgc2VuZGVyIHRoYXQgbWF0Y2hlcyAke3NlbmRlci5mdWxseVF1YWxpZmllZE5hbWV9LmApO1xyXG4gICAgICAgIGlmIChzZW5kZXIgaW5zdGFuY2VvZiBGYW1peC5UeXBlKSB7XHJcbiAgICAgICAgICAgIC8vIFRPRE8gdGhpcyBtaWdodCBiZSBhbiBlcnJvciBpbiBnZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lXHJcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgT29wcyEgU2VuZGVyIGlzIGEgdHlwZSwgd2hpY2ggaXMgbm90IHZhbGlkIGZvciBhbiBJbnZvY2F0aW9uLiBUcnlpbmcgdG8gZmluZCBhIGNvbnRhaW5lciBmb3IgJHtzZW5kZXIuZnVsbHlRdWFsaWZpZWROYW1lfS5gKTtcclxuICAgICAgICAgICAgY29uc3Qgc2VuZGVyQ29udGFpbmVyID0gc2VuZGVyLmNvbnRhaW5lcjtcclxuICAgICAgICAgICAgaWYgKHNlbmRlckNvbnRhaW5lcikge1xyXG4gICAgICAgICAgICAgICAgc2VuZGVyID0gc2VuZGVyQ29udGFpbmVyO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IHJlY2VpdmVyRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihpbnZvY2FibGUuZ2V0UGFyZW50KCkpO1xyXG4gICAgICAgIGNvbnN0IHJlY2VpdmVyID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lKHJlY2VpdmVyRnVsbHlRdWFsaWZpZWROYW1lKSBhcyBGYW1peC5OYW1lZEVudGl0eTtcclxuXHJcbiAgICAgICAgY29uc3QgZm14SW52b2NhdGlvbiA9IG5ldyBGYW1peC5JbnZvY2F0aW9uKCk7XHJcbiAgICAgICAgZm14SW52b2NhdGlvbi5zZW5kZXIgPSBzZW5kZXI7XHJcbiAgICAgICAgZm14SW52b2NhdGlvbi5yZWNlaXZlciA9IHJlY2VpdmVyO1xyXG4gICAgICAgIGZteEludm9jYXRpb24uYWRkQ2FuZGlkYXRlKGZteEludm9jYWJsZSk7XHJcbiAgICAgICAgZm14SW52b2NhdGlvbi5zaWduYXR1cmUgPSBmbXhJbnZvY2FibGUuc2lnbmF0dXJlO1xyXG5cclxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW52b2NhdGlvbik7XHJcblxyXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14SW52b2NhdGlvbixub2RlUmVmZXJyaW5nVG9JbnZvY2FibGUpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGluaGVyaXRhbmNlXHJcbiAgICAgKiBAcGFyYW0gY2xzIEEgY2xhc3Mgb3IgYW4gaW50ZXJmYWNlIChzdWJjbGFzcylcclxuICAgICAqIEBwYXJhbSBpbmhDbGFzcyBUaGUgaW5oZXJpdGVkIGNsYXNzIG9yIGludGVyZmFjZSAoc3VwZXJjbGFzcylcclxuICAgICAqL1xyXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhJbmhlcml0YW5jZShjbHM6IENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbiwgaW5oQ2xhc3M6IENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cyk6IHZvaWQge1xyXG4gICAgICAgIC8vIC8vIG5lZWQgYSBrZXkgdG8gc2VlIGlmIHRoZSBpbmhlcml0YW5jZSBhbHJlYWR5IGV4aXN0c1xyXG4gICAgICAgIC8vIGNvbnN0IGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihjbHMpO1xyXG4gICAgICAgIC8vIGxldCBpbktleXdvcmQ6IHN0cmluZztcclxuICAgICAgICAvLyBsZXQgaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWU6IHN0cmluZztcclxuICAgICAgICAvLyBsZXQgaW5oQ2xhc3NOYW1lOiBzdHJpbmcgfCB1bmRlZmluZWQ7XHJcbiAgICAgICAgLy8gLy8gaWYgaW5oQ2xhc3MgaXMgYW4gRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzLCBpdCBpcyBhbiBpbnRlcmZhY2VcclxuICAgICAgICAvLyBpZiAoaW5oQ2xhc3MgaW5zdGFuY2VvZiBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHMpIHtcclxuICAgICAgICAvLyAgICAgaW5oQ2xhc3NOYW1lID0gaW5oQ2xhc3MuZ2V0RXhwcmVzc2lvbigpLmdldFRleHQoKTtcclxuICAgICAgICAvLyAgICAgLy8gd2hhdCBpcyBpbmhDbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZT8gVE9ET1xyXG4gICAgICAgIC8vICAgICBpbmhDbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZSA9ICdVbmRlZmluZWRfU2NvcGVfZnJvbV9pbXBvcnRlci4nICsgaW5oQ2xhc3NOYW1lO1xyXG4gICAgICAgIC8vIH0gZWxzZSB7XHJcbiAgICAgICAgLy8gICAgIGluaENsYXNzTmFtZSA9IGluaENsYXNzLmdldE5hbWUoKTtcclxuICAgICAgICAvLyAgICAgaWYgKCFpbmhDbGFzc05hbWUpIHtcclxuICAgICAgICAvLyAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW5oZXJpdGVkIGNsYXNzIG9yIGludGVyZmFjZSBuYW1lIG5vdCBmb3VuZCBmb3IgJHtpbmhDbGFzcy5nZXRUZXh0KCl9LmApO1xyXG4gICAgICAgIC8vICAgICB9XHJcbiAgICAgICAgLy8gICAgIGluaENsYXNzRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihpbmhDbGFzcyk7XHJcbiAgICAgICAgLy8gfVxyXG4gICAgICAgIC8vIC8vIGJ1aWxkIHRoZSB1bmlxdWUga2V5IG9mIHRoZSBpbmhlcml0YW5jZVxyXG4gICAgICAgIC8vIGlmICgoY2xzIGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbiAmJiBpbmhDbGFzcyBpbnN0YW5jZW9mIENsYXNzRGVjbGFyYXRpb24pIFxyXG4gICAgICAgIC8vICAgICB8fCAoY2xzIGluc3RhbmNlb2YgSW50ZXJmYWNlRGVjbGFyYXRpb24gJiYgaW5oQ2xhc3MgaW5zdGFuY2VvZiBJbnRlcmZhY2VEZWNsYXJhdGlvbikpIHtcclxuICAgICAgICAvLyAgICAgaW5LZXl3b3JkID0gXCIgZXh0ZW5kcyBcIjtcclxuICAgICAgICAvLyB9IGVsc2UgaWYgKGNscyBpbnN0YW5jZW9mIENsYXNzRGVjbGFyYXRpb24gJiYgKGluaENsYXNzIGluc3RhbmNlb2YgSW50ZXJmYWNlRGVjbGFyYXRpb24gfHwgaW5oQ2xhc3MgaW5zdGFuY2VvZiBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHMpKSB7XHJcbiAgICAgICAgLy8gICAgIGluS2V5d29yZCA9IFwiIGltcGxlbWVudHMgXCI7XHJcbiAgICAgICAgLy8gfSBlbHNlIHtcclxuICAgICAgICAvLyAgICAgdGhyb3cgbmV3IEVycm9yKGBJbmhlcml0YW5jZSAke2Nscy5nZXRUZXh0KCl9IGFuZCAke2luaENsYXNzLmdldFRleHQoKX0gaXMgbm90IHZhbGlkLmApO1xyXG4gICAgICAgIC8vIH1cclxuXHJcbiAgICAgICAgLy8gY29uc3QgaW5oZXJpdGFuY2VGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGNscykgKyBpbktleXdvcmQgKyBpbmhDbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZTtcclxuICAgICAgICAvLyBpZiAodGhpcy5mbXhJbmhlcml0YW5jZU1hcC5oYXMoaW5oZXJpdGFuY2VGdWxseVF1YWxpZmllZE5hbWUpKSB7XHJcbiAgICAgICAgLy8gICAgIGNvbnN0IHJJbmhlcml0YW5jZSA9IHRoaXMuZm14SW5oZXJpdGFuY2VNYXAuZ2V0KGluaGVyaXRhbmNlRnVsbHlRdWFsaWZpZWROYW1lKTtcclxuICAgICAgICAvLyAgICAgaWYgKHJJbmhlcml0YW5jZSkgeyBcclxuICAgICAgICAvLyAgICAgICAgcmV0dXJuOyAvLyBkb24ndCBkbyBhbnl0aGluZ1xyXG4gICAgICAgIC8vICAgICB9IGVsc2Uge1xyXG4gICAgICAgIC8vICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbmhlcml0YW5jZSAke2Nscy5nZXRUZXh0KCl9IGlzIG5vdCBmb3VuZCBpbiB0aGUgaW5oZXJpdGFuY2UgbWFwLmApO1xyXG4gICAgICAgIC8vICAgICB9XHJcbiAgICAgICAgLy8gfVxyXG5cclxuICAgICAgICBjb25zdCBmbXhJbmhlcml0YW5jZSA9IG5ldyBGYW1peC5Jbmhlcml0YW5jZSgpO1xyXG5cclxuICAgICAgICAvLyBsb2dnZXIuZGVidWcoYGNyZWF0ZUZhbWl4SW5oZXJpdGFuY2U6IGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lOiBjbGFzcyBmcW4gPSAke2NsYXNzRnVsbHlRdWFsaWZpZWROYW1lfWApO1xyXG5cclxuICAgICAgICBsZXQgc3ViQ2xhc3M6IEZhbWl4LkNsYXNzIHwgRmFtaXguSW50ZXJmYWNlIHwgdW5kZWZpbmVkO1xyXG4gICAgICAgIGlmIChjbHMgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uKSB7XHJcbiAgICAgICAgICAgIHN1YkNsYXNzID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoY2xzKTtcclxuICAgICAgICB9XHJcbiAgICAgICAgZWxzZSB7XHJcbiAgICAgICAgICAgIHN1YkNsYXNzID0gdGhpcy5jcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlKGNscyk7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIXN1YkNsYXNzKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3ViY2xhc3MgJHtjbHN9IG5vdCBmb3VuZCBpbiBDbGFzcyBvciBJbnRlcmZhY2UgbWFwcy5gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBzdXBlckNsYXNzOiBGYW1peC5DbGFzcyB8IEZhbWl4LkludGVyZmFjZSB8IHVuZGVmaW5lZDtcclxuICAgICAgICAvLyBpZiAoaW5oQ2xhc3MgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uIHx8IGluaENsYXNzIGluc3RhbmNlb2YgSW50ZXJmYWNlRGVjbGFyYXRpb24pIHtcclxuICAgICAgICAvLyAgICAgaW5oQ2xhc3NOYW1lID0gaW5oQ2xhc3MuZ2V0TmFtZSgpO1xyXG4gICAgICAgIC8vICAgICBpZiAoIWluaENsYXNzTmFtZSkge1xyXG4gICAgICAgIC8vICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbmhlcml0ZWQgY2xhc3Mgb3IgaW50ZXJmYWNlIG5hbWUgbm90IGZvdW5kIGZvciAke2luaENsYXNzLmdldFRleHQoKX0uYCk7XHJcbiAgICAgICAgLy8gICAgIH1cclxuICAgICAgICAvLyAgICAgaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGluaENsYXNzKTtcclxuICAgICAgICAvLyAgICAgaWYgKGluaENsYXNzIGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbikge1xyXG4gICAgICAgIC8vICAgICAgICAgc3VwZXJDbGFzcyA9IHRoaXMuZm14Q2xhc3NNYXAuZ2V0KGluaENsYXNzRnVsbHlRdWFsaWZpZWROYW1lKTtcclxuICAgICAgICAvLyAgICAgfVxyXG4gICAgICAgIC8vICAgICBlbHNlIHtcclxuICAgICAgICAvLyAgICAgICAgIHN1cGVyQ2xhc3MgPSB0aGlzLmZteEludGVyZmFjZU1hcC5nZXQoaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUpO1xyXG4gICAgICAgIC8vICAgICB9XHJcbiAgICAgICAgLy8gICAgIGlmICghc3VwZXJDbGFzcykge1xyXG4gICAgICAgIC8vICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTdXBlcmNsYXNzICR7Y2xhc3NGdWxseVF1YWxpZmllZE5hbWV9IG5vdCBmb3VuZCBpbiBDbGFzcyBvciBJbnRlcmZhY2UgbWFwcy5gKTtcclxuICAgICAgICAvLyAgICAgfVxyXG4gICAgICAgIC8vIH1cclxuXHJcbiAgICAgICAgLy8gLy8gaXQgc2hvdWxkbid0IGFkZCB0aGUgY2xhc3MvaW50ZXJmYWNlIGFnYWluIHRvIHRoZSBNYXAsIGl0IHNob3VsZCB1c2UgY3JlYXRlT3JHZXQgKD8pXHJcbiAgICAgICAgLy8gaWYgKHN1cGVyQ2xhc3MgPT09IHVuZGVmaW5lZCkge1xyXG5cclxuICAgICAgICBpZiAoaW5oQ2xhc3MgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uKSB7XHJcbiAgICAgICAgICAgIC8vIHN1cGVyQ2xhc3MgPSBuZXcgRmFtaXguQ2xhc3MoKTtcclxuICAgICAgICAgICAgc3VwZXJDbGFzcyA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENsYXNzKGluaENsYXNzKTtcclxuICAgICAgICAgICAgLy8gdGhpcy5mbXhDbGFzc01hcC5zZXQoaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUsIHN1cGVyQ2xhc3MpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChpbmhDbGFzcyBpbnN0YW5jZW9mIEludGVyZmFjZURlY2xhcmF0aW9uKSB7XHJcbiAgICAgICAgICAgIC8vIHN1cGVyQ2xhc3MgPSBuZXcgRmFtaXguSW50ZXJmYWNlKCk7XHJcbiAgICAgICAgICAgIHN1cGVyQ2xhc3MgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoaW5oQ2xhc3MpO1xyXG4gICAgICAgICAgICAvLyB0aGlzLmZteEludGVyZmFjZU1hcC5zZXQoaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUsIHN1cGVyQ2xhc3MpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIGluaENsYXNzIGluc3RhbmNlb2YgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzXHJcbiAgICAgICAgICAgIGNvbnN0IGludGVyZmFjZURlY2xhcmF0aW9uID0gZ2V0SW50ZXJmYWNlRGVjbGFyYXRpb25Gcm9tRXhwcmVzc2lvbihpbmhDbGFzcyk7XHJcbiAgICAgICAgICAgIGlmIChpbnRlcmZhY2VEZWNsYXJhdGlvbiAhPT0gdW5kZWZpbmVkKSB7XHJcbiAgICAgICAgICAgICAgICBzdXBlckNsYXNzID0gdGhpcy5jcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlKGludGVyZmFjZURlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW50ZXJmYWNlIGRlY2xhcmF0aW9uIG5vdCBmb3VuZCBmb3IgJHtpbmhDbGFzcy5nZXRUZXh0KCl9LmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KHN1cGVyQ2xhc3MsIGluaENsYXNzKTtcclxuXHJcbiAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoaW5oQ2xhc3MsIHN1cGVyQ2xhc3MpO1xyXG5cclxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoc3VwZXJDbGFzcyk7XHJcblxyXG4gICAgICAgIGZteEluaGVyaXRhbmNlLnN1YmNsYXNzID0gc3ViQ2xhc3M7XHJcbiAgICAgICAgZm14SW5oZXJpdGFuY2Uuc3VwZXJjbGFzcyA9IHN1cGVyQ2xhc3M7XHJcblxyXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhJbmhlcml0YW5jZSk7XHJcbiAgICAgICAgLy8gbm8gRlFOIGZvciBpbmhlcml0YW5jZVxyXG5cclxuICAgICAgICAvLyBXZSBkb24ndCBtYXAgaW5oZXJpdGFuY2UgdG8gdGhlIHNvdXJjZSBjb2RlIGVsZW1lbnQgYmVjYXVzZSB0aGVyZSBhcmUgdHdvIGVsZW1lbnRzIChzdXBlciwgc3ViKVxyXG4gICAgICAgIC8vIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14SW5oZXJpdGFuY2UsIG51bGwpO1xyXG5cclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhJbXBvcnRDbGF1c2UoaW1wb3J0ZWRFbnRpdHk6IEZhbWl4Lk5hbWVkRW50aXR5LCBpbXBvcnRpbmdFbnRpdHk6IEZhbWl4Lk1vZHVsZSkge1xyXG4gICAgICAgIGNvbnN0IGZteEltcG9ydENsYXVzZSA9IG5ldyBGYW1peC5JbXBvcnRDbGF1c2UoKTtcclxuICAgICAgICBmbXhJbXBvcnRDbGF1c2UuaW1wb3J0ZWRFbnRpdHkgPSBpbXBvcnRlZEVudGl0eTtcclxuICAgICAgICBmbXhJbXBvcnRDbGF1c2UuaW1wb3J0aW5nRW50aXR5ID0gaW1wb3J0aW5nRW50aXR5O1xyXG4gICAgICAgIGltcG9ydGluZ0VudGl0eS5hZGRPdXRnb2luZ0ltcG9ydChmbXhJbXBvcnRDbGF1c2UpO1xyXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhJbXBvcnRDbGF1c2UpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGltcG9ydCBjbGF1c2VcclxuICAgICAqIEBwYXJhbSBpbXBvcnRDbGF1c2VJbmZvIFRoZSBpbmZvcm1hdGlvbiBuZWVkZWQgdG8gY3JlYXRlIGEgRmFtaXggaW1wb3J0IGNsYXVzZVxyXG4gICAgICogQHBhcmFtIGltcG9ydERlY2xhcmF0aW9uIFRoZSBpbXBvcnQgZGVjbGFyYXRpb25cclxuICAgICAqIEBwYXJhbSBpbXBvcnRlciBBIHNvdXJjZSBmaWxlIHdoaWNoIGlzIGEgbW9kdWxlXHJcbiAgICAgKiBAcGFyYW0gbW9kdWxlU3BlY2lmaWVyRmlsZVBhdGggVGhlIHBhdGggb2YgdGhlIG1vZHVsZSB3aGVyZSB0aGUgZXhwb3J0IGRlY2xhcmF0aW9uIGlzXHJcbiAgICAgKiBAcGFyYW0gaW1wb3J0RWxlbWVudCBUaGUgaW1wb3J0ZWQgZW50aXR5XHJcbiAgICAgKiBAcGFyYW0gaXNJbkV4cG9ydHMgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIGltcG9ydGVkIGVudGl0eSBpcyBpbiB0aGUgZXhwb3J0c1xyXG4gICAgICogQHBhcmFtIGlzRGVmYXVsdEV4cG9ydCBBIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgaW1wb3J0ZWQgZW50aXR5IGlzIGEgZGVmYXVsdCBleHBvcnRcclxuICAgICAqL1xyXG4gICAgcHVibGljIG9sZENyZWF0ZU9yR2V0RmFtaXhJbXBvcnRDbGF1c2UoaW1wb3J0Q2xhdXNlSW5mbzoge2ltcG9ydERlY2xhcmF0aW9uPzogSW1wb3J0RGVjbGFyYXRpb24gfCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiwgaW1wb3J0ZXJTb3VyY2VGaWxlOiBTb3VyY2VGaWxlLCBtb2R1bGVTcGVjaWZpZXJGaWxlUGF0aDogc3RyaW5nLCBpbXBvcnRFbGVtZW50OiBJbXBvcnRTcGVjaWZpZXIgfCBJZGVudGlmaWVyLCBpc0luRXhwb3J0czogYm9vbGVhbiwgaXNEZWZhdWx0RXhwb3J0OiBib29sZWFufSk6IHZvaWQge1xyXG4gICAgICAgIGNvbnN0IHtpbXBvcnREZWNsYXJhdGlvbiwgaW1wb3J0ZXJTb3VyY2VGaWxlOiBpbXBvcnRlciwgbW9kdWxlU3BlY2lmaWVyRmlsZVBhdGgsIGltcG9ydEVsZW1lbnQsIGlzSW5FeHBvcnRzLCBpc0RlZmF1bHRFeHBvcnR9ID0gaW1wb3J0Q2xhdXNlSW5mbztcclxuICAgICAgICBpZiAoaW1wb3J0RGVjbGFyYXRpb24gJiYgdGhpcy5mbXhJbXBvcnRDbGF1c2VNYXAuaGFzKGltcG9ydERlY2xhcmF0aW9uKSkge1xyXG4gICAgICAgICAgICBjb25zdCBySW1wb3J0Q2xhdXNlID0gdGhpcy5mbXhJbXBvcnRDbGF1c2VNYXAuZ2V0KGltcG9ydERlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgaWYgKHJJbXBvcnRDbGF1c2UpIHsgXHJcbiAgICAgICAgICAgICAgIHJldHVybjsgLy8gZG9uJ3QgZG8gYW55dGhpbmdcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW1wb3J0IGNsYXVzZSAke2ltcG9ydEVsZW1lbnQuZ2V0VGV4dCgpfSBpcyBub3QgZm91bmQgaW4gdGhlIGltcG9ydCBjbGF1c2UgbWFwLmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsb2dnZXIuaW5mbyhgY3JlYXRpbmcgYSBuZXcgRmFtaXhJbXBvcnRDbGF1c2UgZm9yICR7aW1wb3J0RGVjbGFyYXRpb24/LmdldFRleHQoKX0gaW4gJHtpbXBvcnRlci5nZXRCYXNlTmFtZSgpfS5gKTtcclxuICAgICAgICBjb25zdCBmbXhJbXBvcnRDbGF1c2UgPSBuZXcgRmFtaXguSW1wb3J0Q2xhdXNlKCk7XHJcblxyXG4gICAgICAgIGxldCBpbXBvcnRlZEVudGl0eTogRmFtaXguTmFtZWRFbnRpdHkgfCBGYW1peC5TdHJ1Y3R1cmFsRW50aXR5IHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xyXG4gICAgICAgIGxldCBpbXBvcnRlZEVudGl0eU5hbWU6IHN0cmluZztcclxuXHJcbiAgICAgICAgY29uc3QgYWJzb2x1dGVQYXRoUHJvamVjdCA9IHRoaXMuZmFtaXhSZXAuZ2V0QWJzb2x1dGVQYXRoKCk7XHJcbiAgICAgICAgXHJcbiAgICAgICAgY29uc3QgYWJzb2x1dGVQYXRoID0gcGF0aC5ub3JtYWxpemUobW9kdWxlU3BlY2lmaWVyRmlsZVBhdGgpO1xyXG4gICAgICAgIC8vIGNvbnZlcnQgdGhlIHBhdGggYW5kIHJlbW92ZSBhbnkgd2luZG93cyBiYWNrc2xhc2hlcyBpbnRyb2R1Y2VkIGJ5IHBhdGgubm9ybWFsaXplXHJcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBjcmVhdGVGYW1peEltcG9ydENsYXVzZTogYWJzb2x1dGVQYXRoOiAke2Fic29sdXRlUGF0aH1gKTtcclxuICAgICAgICBsb2dnZXIuZGVidWcoYGNyZWF0ZUZhbWl4SW1wb3J0Q2xhdXNlOiBjb252ZXJ0VG9SZWxhdGl2ZVBhdGg6ICR7dGhpcy5jb252ZXJ0VG9SZWxhdGl2ZVBhdGgoYWJzb2x1dGVQYXRoLCBhYnNvbHV0ZVBhdGhQcm9qZWN0KX1gKTtcclxuICAgICAgICBjb25zdCBwYXRoSW5Qcm9qZWN0OiBzdHJpbmcgPSB0aGlzLmNvbnZlcnRUb1JlbGF0aXZlUGF0aChhYnNvbHV0ZVBhdGgsIGFic29sdXRlUGF0aFByb2plY3QpLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xyXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgY3JlYXRlRmFtaXhJbXBvcnRDbGF1c2U6IHBhdGhJblByb2plY3Q6ICR7cGF0aEluUHJvamVjdH1gKTtcclxuICAgICAgICBsZXQgcGF0aE5hbWUgPSBcIntcIiArIHBhdGhJblByb2plY3QgKyBcIn0uXCI7XHJcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBjcmVhdGVGYW1peEltcG9ydENsYXVzZTogcGF0aE5hbWU6ICR7cGF0aE5hbWV9YCk7XHJcblxyXG4gICAgICAgIC8vIE5hbWVkIGltcG9ydHMsIGUuZy4gaW1wb3J0IHsgQ2xhc3NXIH0gZnJvbSBcIi4vY29tcGxleEV4cG9ydE1vZHVsZVwiO1xyXG5cclxuICAgICAgICAvLyBTdGFydCB3aXRoIHNpbXBsZSBpbXBvcnQgY2xhdXNlICh3aXRob3V0IHJlZmVycmluZyB0byB0aGUgYWN0dWFsIHZhcmlhYmxlKVxyXG5cclxuICAgICAgICBpZiAoaW1wb3J0RGVjbGFyYXRpb24gaW5zdGFuY2VvZiBJbXBvcnREZWNsYXJhdGlvbiBcclxuICAgICAgICAgICAgJiYgaW1wb3J0RWxlbWVudCBpbnN0YW5jZW9mIEltcG9ydFNwZWNpZmllcikgeyBcclxuICAgICAgICAgICAgICAgIGltcG9ydGVkRW50aXR5TmFtZSA9IGltcG9ydEVsZW1lbnQuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICBwYXRoTmFtZSA9IHBhdGhOYW1lICsgaW1wb3J0ZWRFbnRpdHlOYW1lO1xyXG4gICAgICAgICAgICBpZiAoaXNJbkV4cG9ydHMpIHtcclxuICAgICAgICAgICAgICAgIGltcG9ydGVkRW50aXR5ID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lKHBhdGhOYW1lKSBhcyBGYW1peC5OYW1lZEVudGl0eTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAoaW1wb3J0ZWRFbnRpdHkgPT09IHVuZGVmaW5lZCkge1xyXG4gICAgICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSBuZXcgRmFtaXguTmFtZWRFbnRpdHkoKTtcclxuICAgICAgICAgICAgICAgIGltcG9ydGVkRW50aXR5Lm5hbWUgPSBpbXBvcnRlZEVudGl0eU5hbWU7XHJcbiAgICAgICAgICAgICAgICBpZiAoIWlzSW5FeHBvcnRzKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkuaXNTdHViID0gdHJ1ZTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIC8vIGxvZ2dlci5kZWJ1ZyhgY3JlYXRlRmFtaXhJbXBvcnRDbGF1c2U6IENyZWF0aW5nIG5hbWVkIGVudGl0eSAke2ltcG9ydGVkRW50aXR5TmFtZX0gd2l0aCBGUU4gJHtwYXRoTmFtZX1gKTtcclxuICAgICAgICAgICAgICAgIC8vIGltcG9ydGVkRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9IHBhdGhOYW1lO1xyXG4gICAgICAgICAgICAgICAgaW5pdEZRTihpbXBvcnRFbGVtZW50LCBpbXBvcnRlZEVudGl0eSk7XHJcblxyXG4gICAgICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoaW1wb3J0RWxlbWVudCwgaW1wb3J0ZWRFbnRpdHkpO1xyXG4gICAgICAgICAgICAgICAgLy8gbXVzdCBhZGQgZW50aXR5IHRvIHJlcG9zaXRvcnlcclxuICAgICAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChpbXBvcnRlZEVudGl0eSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gaGFuZGxlIGltcG9ydCBlcXVhbHMgZGVjbGFyYXRpb25zLCBlLmcuIGltcG9ydCBteU1vZHVsZSA9IHJlcXVpcmUoXCIuL2NvbXBsZXhFeHBvcnRNb2R1bGVcIik7XHJcbiAgICAgICAgLy8gVHlwZVNjcmlwdCBjYW4ndCBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgdGhlIGltcG9ydGVkIG1vZHVsZSwgc28gd2UgY3JlYXRlIGEgTW9kdWxlIGVudGl0eVxyXG4gICAgICAgIGVsc2UgaWYgKGltcG9ydERlY2xhcmF0aW9uIGluc3RhbmNlb2YgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24pIHtcclxuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHlOYW1lID0gaW1wb3J0RGVjbGFyYXRpb24/LmdldE5hbWUoKTtcclxuICAgICAgICAgICAgcGF0aE5hbWUgPSBwYXRoTmFtZSArIGltcG9ydGVkRW50aXR5TmFtZTtcclxuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSBuZXcgRmFtaXguU3RydWN0dXJhbEVudGl0eSgpO1xyXG4gICAgICAgICAgICBpbXBvcnRlZEVudGl0eS5uYW1lID0gaW1wb3J0ZWRFbnRpdHlOYW1lO1xyXG4gICAgICAgICAgICBpbml0RlFOKGltcG9ydERlY2xhcmF0aW9uLCBpbXBvcnRlZEVudGl0eSk7XHJcbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGltcG9ydEVsZW1lbnQsIGltcG9ydGVkRW50aXR5KTtcclxuICAgICAgICAgICAgLy8gaW1wb3J0ZWRFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lID0gcGF0aE5hbWU7XHJcbiAgICAgICAgICAgIGNvbnN0IGFueVR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKCdhbnknLCBpbXBvcnREZWNsYXJhdGlvbik7XHJcbiAgICAgICAgICAgIChpbXBvcnRlZEVudGl0eSBhcyBGYW1peC5TdHJ1Y3R1cmFsRW50aXR5KS5kZWNsYXJlZFR5cGUgPSBhbnlUeXBlO1xyXG4gICAgICAgIH0gZWxzZSB7ICAvLyBkZWZhdWx0IGltcG9ydHMsIGUuZy4gaW1wb3J0IENsYXNzVyBmcm9tIFwiLi9jb21wbGV4RXhwb3J0TW9kdWxlXCI7ICBcclxuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHlOYW1lID0gaW1wb3J0RWxlbWVudC5nZXRUZXh0KCk7XHJcbiAgICAgICAgICAgIHBhdGhOYW1lID0gcGF0aE5hbWUgKyAoaXNEZWZhdWx0RXhwb3J0ID8gXCJkZWZhdWx0RXhwb3J0XCIgOiBcIm5hbWVzcGFjZUV4cG9ydFwiKTtcclxuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSBuZXcgRmFtaXguTmFtZWRFbnRpdHkoKTtcclxuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkubmFtZSA9IGltcG9ydGVkRW50aXR5TmFtZTtcclxuICAgICAgICAgICAgLy8gaW1wb3J0ZWRFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lID0gcGF0aE5hbWU7XHJcbiAgICAgICAgICAgIGluaXRGUU4oaW1wb3J0RWxlbWVudCwgaW1wb3J0ZWRFbnRpdHkpO1xyXG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihpbXBvcnRFbGVtZW50LCBpbXBvcnRlZEVudGl0eSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIEkgZG9uJ3QgdGhpbmsgaXQgc2hvdWxkIGJlIGFkZGVkIHRvIHRoZSByZXBvc2l0b3J5IGlmIGl0IGV4aXN0cyBhbHJlYWR5XHJcbiAgICAgICAgaWYgKCFpc0luRXhwb3J0cykgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGltcG9ydGVkRW50aXR5KTtcclxuICAgICAgICBjb25zdCBpbXBvcnRlckZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oaW1wb3J0ZXIpO1xyXG4gICAgICAgIGNvbnN0IGZteEltcG9ydGVyID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lKGltcG9ydGVyRnVsbHlRdWFsaWZpZWROYW1lKSBhcyBGYW1peC5Nb2R1bGU7XHJcbiAgICAgICAgZm14SW1wb3J0Q2xhdXNlLmltcG9ydGluZ0VudGl0eSA9IGZteEltcG9ydGVyO1xyXG4gICAgICAgIGZteEltcG9ydENsYXVzZS5pbXBvcnRlZEVudGl0eSA9IGltcG9ydGVkRW50aXR5O1xyXG4gICAgICAgIGlmIChpbXBvcnREZWNsYXJhdGlvbiBpbnN0YW5jZW9mIEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uKSB7XHJcbiAgICAgICAgICAgIGZteEltcG9ydENsYXVzZS5tb2R1bGVTcGVjaWZpZXIgPSBpbXBvcnREZWNsYXJhdGlvbj8uZ2V0TW9kdWxlUmVmZXJlbmNlKCkuZ2V0VGV4dCgpIGFzIHN0cmluZztcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBmbXhJbXBvcnRDbGF1c2UubW9kdWxlU3BlY2lmaWVyID0gaW1wb3J0RGVjbGFyYXRpb24/LmdldE1vZHVsZVNwZWNpZmllclZhbHVlKCkgYXMgc3RyaW5nO1xyXG4gICAgICAgIH1cclxuICAgIFxyXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgY3JlYXRlRmFtaXhJbXBvcnRDbGF1c2U6ICR7Zm14SW1wb3J0Q2xhdXNlLmltcG9ydGVkRW50aXR5Py5uYW1lfSAob2YgdHlwZSAke1xyXG4gICAgICAgICAgICBIZWxwZXJzLmdldFN1YlR5cGVOYW1lKGZteEltcG9ydENsYXVzZS5pbXBvcnRlZEVudGl0eSl9KSBpcyBpbXBvcnRlZCBieSAke2ZteEltcG9ydENsYXVzZS5pbXBvcnRpbmdFbnRpdHk/Lm5hbWV9YCk7XHJcblxyXG4gICAgICAgIGZteEltcG9ydGVyLmFkZE91dGdvaW5nSW1wb3J0KGZteEltcG9ydENsYXVzZSk7XHJcblxyXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhJbXBvcnRDbGF1c2UpO1xyXG5cclxuICAgICAgICBpZiAoaW1wb3J0RGVjbGFyYXRpb24pIHtcclxuICAgICAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhJbXBvcnRDbGF1c2UsIGltcG9ydERlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgdGhpcy5mbXhJbXBvcnRDbGF1c2VNYXAuc2V0KGltcG9ydERlY2xhcmF0aW9uLCBmbXhJbXBvcnRDbGF1c2UpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBBcnJvdyBGdW5jdGlvblxyXG4gICAgICogQHBhcmFtIGFycm93RXhwcmVzc2lvbiBBbiBFeHByZXNzaW9uXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHZhcmlhYmxlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4QXJyb3dGdW5jdGlvbihhcnJvd0V4cHJlc3Npb246IEV4cHJlc3Npb24sIGN1cnJlbnRDQzogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSApOiBGYW1peC5BcnJvd0Z1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Fycm93RnVuY3Rpb24ge1xyXG4gICAgICAgIFxyXG4gICAgICAgIGxldCBmbXhBcnJvd0Z1bmN0aW9uOiBGYW1peC5BcnJvd0Z1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Fycm93RnVuY3Rpb247XHJcbiAgICAgICAgY29uc3QgZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGFycm93RXhwcmVzc2lvbik7XHJcblxyXG4gICAgICAgIGlmICghdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5oYXMoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpKSB7XHJcblxyXG4gICAgICAgICAgICBjb25zdCBhcnJvd0Z1bmN0aW9uID0gYXJyb3dFeHByZXNzaW9uLmFzS2luZE9yVGhyb3coU3ludGF4S2luZC5BcnJvd0Z1bmN0aW9uKTtcclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGlzR2VuZXJpYyA9IGFycm93RnVuY3Rpb24uZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwO1xyXG5cclxuICAgICAgICAgICAgaWYgKGlzR2VuZXJpYykge1xyXG4gICAgICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbiA9IG5ldyBGYW1peC5QYXJhbWV0cmljQXJyb3dGdW5jdGlvbigpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbiA9IG5ldyBGYW1peC5BcnJvd0Z1bmN0aW9uKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIEdldCB0aGUgcGFyZW50IG9mIHRoZSBhcnJvdyBmdW5jdGlvbiAodGhlIHZhcmlhYmxlIGRlY2xhcmF0aW9uKVxyXG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBhcnJvd0Z1bmN0aW9uLmdldFBhcmVudElmS2luZChTeW50YXhLaW5kLlZhcmlhYmxlRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBsZXQgZnVuY3Rpb25OYW1lID0gJyhOT19OQU1FKSc7XHJcblxyXG4gICAgICAgICAgICBpZiAocGFyZW50ICYmIHBhcmVudCBpbnN0YW5jZW9mIFZhcmlhYmxlRGVjbGFyYXRpb24pIHtcclxuICAgICAgICAgICAgICAgIC8vIEdldCB0aGUgbmFtZSBvZiB0aGUgdmFyaWFibGVcclxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSA9IHBhcmVudC5nZXROYW1lKCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGlmIChmdW5jdGlvbk5hbWUpIHtcclxuICAgICAgICAgICAgICAgIGZteEFycm93RnVuY3Rpb24ubmFtZSA9IGZ1bmN0aW9uTmFtZTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBlbHNlIHtcclxuICAgICAgICAgICAgICAgIGZteEFycm93RnVuY3Rpb24ubmFtZSA9IFwiYW5vbnltb3VzXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIC8vIFNpZ25hdHVyZSBvZiBhbiBhcnJvdyBmdW5jdGlvbiBpcyAocGFyYW1ldGVycykgPT4gcmV0dXJuX3R5cGVcclxuICAgICAgICAgICAgY29uc3QgcGFyYW1ldGVyc1NpZ25hdHVyZSA9IGFycm93RnVuY3Rpb24uZ2V0UGFyYW1ldGVycygpLm1hcChwID0+IHAuZ2V0VGV4dCgpKS5qb2luKFwiLCBcIik7XHJcbiAgICAgICAgICAgIGNvbnN0IHJldHVyblR5cGVTaWduYXR1cmUgPSBhcnJvd0Z1bmN0aW9uLmdldFJldHVyblR5cGUoKS5nZXRUZXh0KCk7XHJcbiAgICAgICAgICAgIGZteEFycm93RnVuY3Rpb24uc2lnbmF0dXJlID0gYCgke3BhcmFtZXRlcnNTaWduYXR1cmV9KSA9PiAke3JldHVyblR5cGVTaWduYXR1cmV9YDtcclxuICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5jeWNsb21hdGljQ29tcGxleGl0eSA9IGN1cnJlbnRDQ1tmbXhBcnJvd0Z1bmN0aW9uLm5hbWVdO1xyXG5cclxuICAgICAgICAgICAgbGV0IGZ1bmN0aW9uVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7XHJcbiAgICAgICAgICAgIHRyeSB7XHJcbiAgICAgICAgICAgICAgICBmdW5jdGlvblR5cGVOYW1lID0gYXJyb3dGdW5jdGlvbi5nZXRSZXR1cm5UeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcclxuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcclxuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciByZXR1cm4gdHlwZSBvZiBmdW5jdGlvbjogJHtmdW5jdGlvbk5hbWV9LiBDb250aW51aW5nLi4uYCk7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGZ1bmN0aW9uVHlwZU5hbWUsIGFycm93RnVuY3Rpb24gYXMgdW5rbm93biBhcyBGdW5jdGlvbkRlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xyXG4gICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLm51bWJlck9mTGluZXNPZkNvZGUgPSBhcnJvd0Z1bmN0aW9uLmdldEVuZExpbmVOdW1iZXIoKSAtIGFycm93RnVuY3Rpb24uZ2V0U3RhcnRMaW5lTnVtYmVyKCk7XHJcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBhcnJvd0Z1bmN0aW9uLmdldFBhcmFtZXRlcnMoKTtcclxuICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5udW1iZXJPZlBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzLmxlbmd0aDtcclxuICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5udW1iZXJPZlN0YXRlbWVudHMgPSBhcnJvd0Z1bmN0aW9uLmdldFN0YXRlbWVudHMoKS5sZW5ndGg7XHJcbiAgICAgICAgICAgIGluaXRGUU4oYXJyb3dFeHByZXNzaW9uIGFzIHVua25vd24gYXMgVFNNb3JwaE9iamVjdFR5cGUsIGZteEFycm93RnVuY3Rpb24pO1xyXG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihhcnJvd0V4cHJlc3Npb24gYXMgdW5rbm93biBhcyBUU01vcnBoT2JqZWN0VHlwZSwgZm14QXJyb3dGdW5jdGlvbik7XHJcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhBcnJvd0Z1bmN0aW9uKTtcclxuICAgICAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhBcnJvd0Z1bmN0aW9uLGFycm93RnVuY3Rpb24gYXMgdW5rbm93biBhcyBUU01vcnBoT2JqZWN0VHlwZSk7XHJcbiAgICAgICAgICAgIHRoaXMuZm14RnVuY3Rpb25BbmRNZXRob2RNYXAuc2V0KGZ1bmN0aW9uRnVsbHlRdWFsaWZpZWROYW1lLCBmbXhBcnJvd0Z1bmN0aW9uKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uID0gdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5nZXQoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpIGFzIEZhbWl4LkFycm93RnVuY3Rpb247XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZm14QXJyb3dGdW5jdGlvbjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvblxyXG4gICAgICogQHBhcmFtIGNscyBBIGNsYXNzXHJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGNvbmNyZXRpc2F0aW9uXHJcbiAgICAgKi9cclxuICAgIC8vIHB1YmxpYyBjcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbkVudGl0eSA6IEZhbWl4LlBhcmFtZXRyaWNDbGFzcyB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UgfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kICxnZW5FbnRpdHkgOiBGYW1peC5QYXJhbWV0cmljQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZCk6IEZhbWl4LkNvbmNyZXRpc2F0aW9uIHtcclxuICAgICAgICBcclxuICAgIC8vICAgICBjb25zdCBmbXhDb25jcmV0aXNhdGlvbiA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gbmV3IEZhbWl4LkNvbmNyZXRpc2F0aW9uKCk7ICAgICAgICAgICAgICBcclxuICAgICAgICBcclxuICAgIC8vICAgICBmbXhDb25jcmV0aXNhdGlvbi5jb25jcmV0ZUVudGl0eSA9IGNvbkVudGl0eTtcclxuICAgIC8vICAgICBmbXhDb25jcmV0aXNhdGlvbi5nZW5lcmljRW50aXR5ID0gZ2VuRW50aXR5O1xyXG4gICAgLy8gICAgIC8vIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14Q29uY3JldGlzYXRpb24sbnVsbCk7XHJcbiAgICAvLyAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteENvbmNyZXRpc2F0aW9uKTsgICAgXHJcbiAgICAvLyAgICAgY29uc3QgcGFyYW1ldGVyQ29uY3JldGlzYXRpb24gPSB0aGlzLmNyZWF0ZUZhbWl4UGFyYW1ldGVyQ29uY3JldGlzYXRpb24oZm14Q29uY3JldGlzYXRpb24pO1xyXG4gICAgICAgICAgICBcclxuICAgIC8vICAgICByZXR1cm4gZm14Q29uY3JldGlzYXRpb247XHJcbiAgICAvLyB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggY29uY3JldGlzYXRpb25cclxuICAgICAqIEBwYXJhbSBjb25jcmV0aXNhdGlvbiBBIEZhbWl4Q29uY3JldGlzYXRpb25cclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgUGFyYW1ldGVyQ29uY3Jlc3Rpc2F0aW9uXHJcbiAgICAgKi9cclxuICAgIC8vIHB1YmxpYyBjcmVhdGVGYW1peFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uKGNvbmNyZXRpc2F0aW9uOiBGYW1peC5Db25jcmV0aXNhdGlvbik6IEZhbWl4LlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uIHwgdW5kZWZpbmVke1xyXG4gICAgLy8gICAgIGNvbnN0IGNvbkNsYXNzID0gY29uY3JldGlzYXRpb24uY29uY3JldGVFbnRpdHk7XHJcbiAgICAvLyAgICAgY29uc3QgZ2VuQ2xhc3MgPSBjb25jcmV0aXNhdGlvbi5nZW5lcmljRW50aXR5O1xyXG4gICAgLy8gICAgIGxvZ2dlci5kZWJ1ZyhgQ3JlYXRpbmcgcGFyYW1ldGVyIGNvbmNyZXRpc2F0aW9uIGJldHdlZW4gJHtjb25DbGFzcy5mdWxseVF1YWxpZmllZE5hbWV9IGFuZCAke2dlbkNsYXNzLmZ1bGx5UXVhbGlmaWVkTmFtZX1gKTtcclxuICAgIC8vICAgICBjb25zdCBwYXJhbWV0ZXJDb25jcmV0aXNhdGlvbnMgPSB0aGlzLmZhbWl4UmVwLl9nZXRBbGxFbnRpdGllc1dpdGhUeXBlKFwiUGFyYW1ldGVyQ29uY3JldGlzYXRpb25cIikgYXMgU2V0PEZhbWl4LlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uPjtcclxuICAgIC8vICAgICBjb25zdCBjb25jcmV0ZVBhcmFtZXRlcnMgPSBjb25DbGFzcy5jb25jcmV0ZVBhcmFtZXRlcnM7XHJcbiAgICAvLyAgICAgY29uc3QgZ2VuZXJpY1BhcmFtZXRlcnMgPSBnZW5DbGFzcy5nZW5lcmljUGFyYW1ldGVycztcclxuICAgICAgICBcclxuICAgIC8vICAgICBsZXQgY29uQ2xhc3NUeXBlUGFyYW1ldGVyc0l0ZXJhdG9yID0gY29uY3JldGVQYXJhbWV0ZXJzLnZhbHVlcygpO1xyXG4gICAgLy8gICAgIGxldCBnZW5DbGFzc1R5cGVQYXJhbWV0ZXJzSXRlcmF0b3IgPSBnZW5lcmljUGFyYW1ldGVycy52YWx1ZXMoKTtcclxuICAgIC8vICAgICBsZXQgZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24gOiBGYW1peC5QYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcclxuXHJcbiAgICAvLyAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnZW5lcmljUGFyYW1ldGVycy5zaXplOyBpKyspIHtcclxuICAgIC8vICAgICAgICAgY29uc3QgY29uQ2xhc3NUeXBlUGFyYW1ldGVyID0gY29uQ2xhc3NUeXBlUGFyYW1ldGVyc0l0ZXJhdG9yLm5leHQoKS52YWx1ZSBhcyBGYW1peC5QYXJhbWV0ZXJUeXBlO1xyXG4gICAgLy8gICAgICAgICBjb25zdCBnZW5DbGFzc1R5cGVQYXJhbWV0ZXIgPSBnZW5DbGFzc1R5cGVQYXJhbWV0ZXJzSXRlcmF0b3IubmV4dCgpLnZhbHVlIGFzIEZhbWl4LlBhcmFtZXRlclR5cGU7XHJcbiAgICAvLyAgICAgICAgIGxldCBjcmVhdGVQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgLy8gICAgICAgICBpZihjb25DbGFzc1R5cGVQYXJhbWV0ZXIgJiYgZ2VuQ2xhc3NUeXBlUGFyYW1ldGVyICYmIGNvbkNsYXNzVHlwZVBhcmFtZXRlci5uYW1lICE9IGdlbkNsYXNzVHlwZVBhcmFtZXRlci5uYW1lKXtcclxuICAgIC8vICAgICAgICAgICAgIHBhcmFtZXRlckNvbmNyZXRpc2F0aW9ucy5mb3JFYWNoKChwYXJhbSA6IEZhbWl4LlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uKSA9PiB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgaWYgKGNvbkNsYXNzVHlwZVBhcmFtZXRlci5uYW1lID09IHBhcmFtLmNvbmNyZXRlUGFyYW1ldGVyLm5hbWUgJiYgZ2VuQ2xhc3NUeXBlUGFyYW1ldGVyLm5hbWUgPT0gcGFyYW0uZ2VuZXJpY1BhcmFtZXRlci5uYW1lKSB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVBhcmFtZXRlckNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uID0gcGFyYW07XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICAgICAgfSlcclxuICAgIC8vICAgICAgICAgICAgIGlmIChjcmVhdGVQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbikge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uID0gbmV3IEZhbWl4LlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uKCk7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24uZ2VuZXJpY1BhcmFtZXRlciA9IGdlbkNsYXNzVHlwZVBhcmFtZXRlcjtcclxuICAgIC8vICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbi5jb25jcmV0ZVBhcmFtZXRlciA9IGNvbkNsYXNzVHlwZVBhcmFtZXRlcjtcclxuICAgIC8vICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbi5hZGRDb25jcmV0aXNhdGlvbihjb25jcmV0aXNhdGlvbik7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgLy8gdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbixudWxsKTtcclxuICAgIC8vICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgaWYgKCFmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbikge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uIHdhcyB1bmRlZmluZWQgZm9yIGNvbmNyZXRpc2F0aW9uIHdpdGggZ2VuZXJpYyBwYXJhbWV0ZXIgJHtnZW5DbGFzc1R5cGVQYXJhbWV0ZXIubmFtZX0gYW5kIGNvbmNyZXRlIHBhcmFtZXRlciAke2NvbkNsYXNzVHlwZVBhcmFtZXRlci5uYW1lfWApO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbi5hZGRDb25jcmV0aXNhdGlvbihjb25jcmV0aXNhdGlvbik7XHJcbiAgICAvLyAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24pO1xyXG4gICAgLy8gICAgICAgICB9XHJcbiAgICAvLyAgICAgfVxyXG4gICAgLy8gICAgIGlmICghZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24pIHtcclxuICAgIC8vICAgICAgICAgbG9nZ2VyLmVycm9yKGBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiB3YXMgdW5kZWZpbmVkIGZvciBjb25jcmV0aXNhdGlvbiB3aXRoIGNvbmNyZXRlIGVudGl0eSAke2NvbkNsYXNzLmZ1bGx5UXVhbGlmaWVkTmFtZX0gYW5kIGdlbmVyaWMgZW50aXR5ICR7Z2VuQ2xhc3MuZnVsbHlRdWFsaWZpZWROYW1lfWApO1xyXG4gICAgLy8gICAgIH1cclxuICAgIC8vICAgICByZXR1cm4gZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb247XHJcblxyXG4gICAgLy8gfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uIGJldHdlZW4gdHdvIGNsYXNzZXMgb3IgdHdvIGludGVyZmFjZXNcclxuICAgICAqIEBwYXJhbSBlbGVtZW50IEEgY2xhc3Mgb3IgYW4gSW50ZXJmYWNlXHJcbiAgICAgKi9cclxuICAgIC8vIHB1YmxpYyBjcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uQ2xhc3NPckludGVyZmFjZVNwZWNpYWxpc2F0aW9uKGVsZW1lbnQ6IENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbil7XHJcbiAgICAgICAgXHJcbiAgICAvLyAgICAgY29uc3Qgc3VwZXJFbnRpdHkgPSBlbGVtZW50LmdldEV4dGVuZHMoKTtcclxuICAgIC8vICAgICBsZXQgc3VwZXJFbnRpdHlBcnJheTtcclxuICAgIC8vICAgICBpZiAoc3VwZXJFbnRpdHkpe1xyXG4gICAgLy8gICAgICAgICBzdXBlckVudGl0eUFycmF5ID0gQXJyYXkuaXNBcnJheShzdXBlckVudGl0eSkgPyBzdXBlckVudGl0eSA6IFtzdXBlckVudGl0eV07XHJcbiAgICAvLyAgICAgfVxyXG4gICAgLy8gICAgIGlmIChzdXBlckVudGl0eUFycmF5ICYmIHN1cGVyRW50aXR5QXJyYXkubGVuZ3RoID4gMCkge1xyXG4gICAgLy8gICAgICAgICBzdXBlckVudGl0eUFycmF5LmZvckVhY2goZW50aXR5ID0+IHtcclxuICAgIC8vICAgICAgICAgICAgIGxldCBlbnRpdHlJc0dlbmVyaWM7XHJcbiAgICAvLyAgICAgICAgICAgICBjb25zdCBzdXBlckVudGl0eVN5bWJvbCA9IGVudGl0eS5nZXRFeHByZXNzaW9uKCkuZ2V0U3ltYm9sT3JUaHJvdygpO1xyXG4gICAgLy8gICAgICAgICAgICAgbGV0IHN1cGVyRW50aXR5RGVjbGFyYXRpb247XHJcbiAgICAvLyAgICAgICAgICAgICBpZiAoc3VwZXJFbnRpdHkgaW5zdGFuY2VvZiBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHMpIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICBzdXBlckVudGl0eURlY2xhcmF0aW9uID0gc3VwZXJFbnRpdHlTeW1ib2wuZ2V0RGVjbGFyYXRpb25zKClbMF0uYXNLaW5kKHRzLlN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbik7XHJcbiAgICAvLyAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIHN1cGVyRW50aXR5RGVjbGFyYXRpb24gPSBzdXBlckVudGl0eVN5bWJvbC5nZXREZWNsYXJhdGlvbnMoKVswXS5hc0tpbmQodHMuU3ludGF4S2luZC5JbnRlcmZhY2VEZWNsYXJhdGlvbik7XHJcbiAgICAvLyAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICBpZiAoc3VwZXJFbnRpdHlEZWNsYXJhdGlvbikge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGVudGl0eUlzR2VuZXJpYyA9IHN1cGVyRW50aXR5RGVjbGFyYXRpb24uZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwO1xyXG4gICAgLy8gICAgICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICAgICAgaWYgKGVudGl0eUlzR2VuZXJpYykge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGxldCBFbnRpdHlEZWNsYXJhdGlvbjtcclxuICAgIC8vICAgICAgICAgICAgICAgICBsZXQgZ2VuRW50aXR5O1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGlmIChzdXBlckVudGl0eSBpbnN0YW5jZW9mIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cykge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICBFbnRpdHlEZWNsYXJhdGlvbiA9IGVudGl0eS5nZXRFeHByZXNzaW9uKCkuZ2V0U3ltYm9sKCk/LmdldERlY2xhcmF0aW9ucygpWzBdIGFzIENsYXNzRGVjbGFyYXRpb247XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGdlbkVudGl0eSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENsYXNzKEVudGl0eURlY2xhcmF0aW9uKSBhcyBGYW1peC5QYXJhbWV0cmljQ2xhc3M7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgRW50aXR5RGVjbGFyYXRpb24gPSBlbnRpdHkuZ2V0RXhwcmVzc2lvbigpLmdldFN5bWJvbCgpPy5nZXREZWNsYXJhdGlvbnMoKVswXSBhcyBJbnRlcmZhY2VEZWNsYXJhdGlvbjtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgZ2VuRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlKEVudGl0eURlY2xhcmF0aW9uKSBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgICAgICBjb25zdCBnZW5QYXJhbXMgPSBFbnRpdHlEZWNsYXJhdGlvbi5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCgocGFyYW0pID0+IHBhcmFtLmdldFRleHQoKSk7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgY29uc3QgYXJncyA9IGVsZW1lbnQuZ2V0SGVyaXRhZ2VDbGF1c2VzKClbMF0uZ2V0VHlwZU5vZGVzKClbMF0uZ2V0VHlwZUFyZ3VtZW50cygpXHJcbiAgICAvLyAgICAgICAgICAgICAgICAgY29uc3QgY29uUGFyYW1zID0gZWxlbWVudC5nZXRIZXJpdGFnZUNsYXVzZXMoKVswXS5nZXRUeXBlTm9kZXMoKVswXS5nZXRUeXBlQXJndW1lbnRzKCkubWFwKChwYXJhbSkgPT4gcGFyYW0uZ2V0VGV4dCgpKTtcclxuICAgIC8vICAgICAgICAgICAgICAgICBpZiAoIUhlbHBlcnMuYXJyYXlzQXJlRXF1YWwoY29uUGFyYW1zLGdlblBhcmFtcykpIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbkVudGl0eTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgY29uRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGdlbkVudGl0eSxFbnRpdHlEZWNsYXJhdGlvbixhcmdzKTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uY3JldGlzYXRpb25zID0gdGhpcy5mYW1peFJlcC5fZ2V0QWxsRW50aXRpZXNXaXRoVHlwZShcIkNvbmNyZXRpc2F0aW9uXCIpIGFzIFNldDxGYW1peC5Db25jcmV0aXNhdGlvbj47XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGxldCBjcmVhdGVDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2VuRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25jLmdlbmVyaWNFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lICYmIGNvbmMuY29uY3JldGVFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lID09IGNvbkVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUpe1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWF0ZUNvbmNyZXRpc2F0aW9uKSB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmbXhDb25jcmV0aXNhdGlvbiA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gdGhpcy5jcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbkVudGl0eSxnZW5FbnRpdHkpO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICB9KTtcclxuICAgIC8vICAgICB9XHJcbiAgICAvLyAgICAgLy8gVE9ETzogVGhpcyBmdW5jdGlvbiBzZWVtcyB1bmZpbmlzaGVkXHJcbiAgICAvLyB9ICAgIFxyXG4gICAgXHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggY29uY3JldGlzYXRpb24gYmV0d2VlbiBhIGNsYXNzIGFuZCBpdHMgaW5zdGFuY2lhdGlvbnNcclxuICAgICAqIEBwYXJhbSBjbHMgQSBjbGFzc1xyXG4gICAgICovXHJcbiAgICAvLyBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkdlbmVyaWNJbnN0YW50aWF0aW9uKGNsczogQ2xhc3NEZWNsYXJhdGlvbil7XHJcbiAgICAgICBcclxuICAgIC8vICAgICBjb25zdCBpc0dlbmVyaWMgPSBjbHMuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwO1xyXG4gICAgLy8gICAgIGlmIChpc0dlbmVyaWMpIHtcclxuICAgIC8vICAgICAgICAgY29uc3QgaW5zdGFuY2VzID0gY2xzLmdldFNvdXJjZUZpbGUoKS5nZXREZXNjZW5kYW50c09mS2luZCh0cy5TeW50YXhLaW5kLk5ld0V4cHJlc3Npb24pXHJcbiAgICAvLyAgICAgICAgICAgICAuZmlsdGVyKG5ld0V4cHIgPT4ge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBuZXdFeHByLmdldEV4cHJlc3Npb24oKTtcclxuICAgIC8vICAgICAgICAgICAgICAgICByZXR1cm4gZXhwcmVzc2lvbi5nZXRUZXh0KCkgPT09IGNscy5nZXROYW1lKCk7XHJcbiAgICAvLyAgICAgICAgIH0pO1xyXG5cclxuICAgIC8vICAgICAgICAgaW5zdGFuY2VzLmZvckVhY2goaW5zdGFuY2UgPT4ge1xyXG4gICAgLy8gICAgICAgICAgICAgY29uc3QgaW5zdGFuY2VJc0dlbmVyaWMgPSBpbnN0YW5jZS5nZXRUeXBlQXJndW1lbnRzKCkubGVuZ3RoID4gMDtcclxuICAgIC8vICAgICAgICAgICAgIGlmIChpbnN0YW5jZUlzR2VuZXJpYykge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGNvbnN0IGNvblBhcmFtcyA9IGluc3RhbmNlLmdldFR5cGVBcmd1bWVudHMoKS5tYXAoKHBhcmFtKSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGNvbnN0IGdlbkVudGl0eSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENsYXNzKGNscykgYXMgRmFtaXguUGFyYW1ldHJpY0NsYXNzO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIGNvbnN0IGdlblBhcmFtcyA9IGNscy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCgocGFyYW0pID0+IHBhcmFtLmdldFRleHQoKSk7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgaWYgKCFIZWxwZXJzLmFycmF5c0FyZUVxdWFsKGNvblBhcmFtcyxnZW5QYXJhbXMpKSB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGxldCBjb25FbnRpdHk7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGNvbkVudGl0eSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENvbmNyZXRlRWxlbWVudChnZW5FbnRpdHksY2xzLGluc3RhbmNlLmdldFR5cGVBcmd1bWVudHMoKSk7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbmNyZXRpc2F0aW9ucyA9IHRoaXMuZmFtaXhSZXAuX2dldEFsbEVudGl0aWVzV2l0aFR5cGUoXCJDb25jcmV0aXNhdGlvblwiKSBhcyBTZXQ8RmFtaXguQ29uY3JldGlzYXRpb24+O1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICBsZXQgY3JlYXRlQ29uY3JldGlzYXRpb24gOiBib29sZWFuID0gdHJ1ZTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgY29uY3JldGlzYXRpb25zLmZvckVhY2goKGNvbmMgOiBGYW1peC5Db25jcmV0aXNhdGlvbikgPT4ge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdlbkVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uYy5nZW5lcmljRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSAmJiBjb25jLmNvbmNyZXRlRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25FbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lKXtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb25jcmV0aXNhdGlvbiA9IGZhbHNlO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgXHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGlmIChjcmVhdGVDb25jcmV0aXNhdGlvbikge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb24gOiBGYW1peC5Db25jcmV0aXNhdGlvbiA9IHRoaXMuY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbihjb25FbnRpdHksZ2VuRW50aXR5KTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgfSlcclxuICAgIC8vICAgICB9XHJcbiAgICAvLyAgICAgLy8gVE9ETzogVGhpcyBmdW5jdGlvbiBzZWVtcyB1bmZpbmlzaGVkXHJcbiAgICAvLyB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggY29uY3JldGlzYXRpb24gYmV0d2VlbiBhIGNsYXNzIGFuZCBpdHMgaW5zdGFuY2lhdGlvbnNcclxuICAgICAqIEBwYXJhbSBmdW5jIEEgZnVuY3Rpb25cclxuICAgICAqL1xyXG4gICAgLy8gcHVibGljIGNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb25GdW5jdGlvbkluc3RhbnRpYXRpb24oZWxlbWVudDogRnVuY3Rpb25EZWNsYXJhdGlvbiB8IE1ldGhvZERlY2xhcmF0aW9uKXtcclxuICAgIC8vICAgICBjb25zdCBpc0dlbmVyaWMgPSBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcclxuICAgIC8vICAgICBpZiAoaXNHZW5lcmljKSB7XHJcbiAgICAvLyAgICAgICAgIGNvbnN0IGdlblBhcmFtcyA9IGVsZW1lbnQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAocGFyYW0gPT4gcGFyYW0uZ2V0VGV4dCgpKTtcclxuICAgIC8vICAgICAgICAgY29uc3QgdXNlcyA9IGVsZW1lbnQuZmluZFJlZmVyZW5jZXNBc05vZGVzKCk7ICAgIFxyXG4gICAgLy8gICAgICAgICB1c2VzLmZvckVhY2godXNhZ2UgPT4ge1xyXG4gICAgLy8gICAgICAgICAgICAgbGV0IGN1cnJlbnROb2RlOiBOb2RlIHwgdW5kZWZpbmVkID0gdXNhZ2U7XHJcblxyXG4gICAgLy8gICAgICAgICAgICAgd2hpbGUgKGN1cnJlbnROb2RlKSB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnROb2RlLmdldEtpbmQoKSA9PT0gU3ludGF4S2luZC5DYWxsRXhwcmVzc2lvbikge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICBjb25zdCBjYWxsRXhwcmVzc2lvbiA9IGN1cnJlbnROb2RlLmFzS2luZChTeW50YXhLaW5kLkNhbGxFeHByZXNzaW9uKTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgaWYgKCFjYWxsRXhwcmVzc2lvbikge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYWxsRXhwcmVzc2lvbiBub3QgZm91bmQgZm9yICR7Y3VycmVudE5vZGUuZ2V0VGV4dCgpfWApO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlSXNHZW5lcmljID0gY2FsbEV4cHJlc3Npb24uZ2V0VHlwZUFyZ3VtZW50cygpLmxlbmd0aCA+IDA7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZUlzR2VuZXJpYykge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJncyA9IGNhbGxFeHByZXNzaW9uLmdldFR5cGVBcmd1bWVudHMoKTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvblBhcmFtcyA9IGNhbGxFeHByZXNzaW9uLmdldFR5cGVBcmd1bWVudHMoKS5tYXAocGFyYW0gPT4gcGFyYW0uZ2V0VGV4dCgpKTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghSGVscGVycy5hcnJheXNBcmVFcXVhbChjb25QYXJhbXMsZ2VuUGFyYW1zKSkge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBnZW5FbGVtZW50O1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGVsZW1lbnQgaW5zdGFuY2VvZiBGdW5jdGlvbkRlY2xhcmF0aW9uKXtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuRWxlbWVudCA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peEZ1bmN0aW9uKGVsZW1lbnQsIHt9KSBhcyBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb247XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuRWxlbWVudCA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peE1ldGhvZChlbGVtZW50LCB7fSkgYXMgRmFtaXguUGFyYW1ldHJpY01ldGhvZDtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbmNFbGVtZW50O1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmNFbGVtZW50ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGdlbkVsZW1lbnQsZWxlbWVudCxhcmdzKTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25jcmV0aXNhdGlvbnMgPSB0aGlzLmZhbWl4UmVwLl9nZXRBbGxFbnRpdGllc1dpdGhUeXBlKFwiQ29uY3JldGlzYXRpb25cIikgYXMgU2V0PEZhbWl4LkNvbmNyZXRpc2F0aW9uPjtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY3JlYXRlQ29uY3JldGlzYXRpb24gOiBib29sZWFuID0gdHJ1ZTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnZW5FbGVtZW50LmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25jLmdlbmVyaWNFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lICYmIGNvbmMuY29uY3JldGVFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lID09IGNvbmNFbGVtZW50LmZ1bGx5UXVhbGlmaWVkTmFtZSl7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb25jcmV0aXNhdGlvbiA9IGZhbHNlO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgXHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWF0ZUNvbmNyZXRpc2F0aW9uKSB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZteENvbmNyZXRpc2F0aW9uIDogRmFtaXguQ29uY3JldGlzYXRpb24gPSB0aGlzLmNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb24oY29uY0VsZW1lbnQsZ2VuRWxlbWVudCk7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgICAgICAvLyBSZW1vbnRlciDDoCBsJ8OpbMOpbWVudCBwYXJlbnQgKHV0aWxlIHNpIGxlIG7Fk3VkIGRlIHLDqWbDqXJlbmNlIGVzdCB1biBlbmZhbnQpXHJcbiAgICAvLyAgICAgICAgICAgICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5nZXRQYXJlbnQoKTtcclxuICAgIC8vICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgfSk7XHJcbiAgICAvLyAgICAgfVxyXG4gICAgLy8gfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uIGJldHdlZW4gYSBjbGFzcyBhbmQgYW4gaW50ZXJmYWNlXHJcbiAgICAgKiBAcGFyYW0gY2xzIEEgY2xhc3NcclxuICAgICAqL1xyXG4gICAgLy8gcHVibGljIGNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb25JbnRlcmZhY2VDbGFzcyhjbHM6IENsYXNzRGVjbGFyYXRpb24pe1xyXG4gICAgXHJcbiAgICAvLyAgICAgY29uc3Qgc3VwZXJJbnRlcmZhY2VzID0gY2xzLmdldEltcGxlbWVudHMoKTtcclxuICAgIC8vICAgICBzdXBlckludGVyZmFjZXMuZm9yRWFjaChpbnRlcmZhY2VUeXBlID0+IHtcclxuICAgIC8vICAgICAgICAgY29uc3QgaW50ZXJmYWNlSXNHZW5lcmljID0gaW50ZXJmYWNlVHlwZS5nZXRUeXBlQXJndW1lbnRzKCkubGVuZ3RoPjA7XHJcbiAgICAvLyAgICAgICAgIGlmIChpbnRlcmZhY2VJc0dlbmVyaWMpIHtcclxuICAgIC8vICAgICAgICAgICAgIGNvbnN0IGludGVyZmFjZURlY2xhcmF0aW9uID0gaW50ZXJmYWNlVHlwZS5nZXRFeHByZXNzaW9uKCkuZ2V0U3ltYm9sKCk/LmdldERlY2xhcmF0aW9ucygpWzBdIGFzIEludGVyZmFjZURlY2xhcmF0aW9uO1xyXG4gICAgLy8gICAgICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gaW50ZXJmYWNlRGVjbGFyYXRpb24uZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAoKHBhcmFtKSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xyXG4gICAgLy8gICAgICAgICAgICAgY29uc3QgY29uUGFyYW1zID0gY2xzLmdldEhlcml0YWdlQ2xhdXNlcygpWzBdLmdldFR5cGVOb2RlcygpWzBdLmdldFR5cGVBcmd1bWVudHMoKS5tYXAoKHBhcmFtKSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xyXG4gICAgLy8gICAgICAgICAgICAgY29uc3QgYXJncyA9IGNscy5nZXRIZXJpdGFnZUNsYXVzZXMoKVswXS5nZXRUeXBlTm9kZXMoKVswXS5nZXRUeXBlQXJndW1lbnRzKCk7XHJcbiAgICAvLyAgICAgICAgICAgICBpZiAoIUhlbHBlcnMuYXJyYXlzQXJlRXF1YWwoY29uUGFyYW1zLGdlblBhcmFtcykpIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICBjb25zdCBnZW5JbnRlcmZhY2UgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoaW50ZXJmYWNlRGVjbGFyYXRpb24pIGFzIEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2U7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgY29uc3QgY29uSW50ZXJmYWNlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGdlbkludGVyZmFjZSxpbnRlcmZhY2VEZWNsYXJhdGlvbixhcmdzKTtcclxuICAgIC8vICAgICAgICAgICAgICAgICBjb25zdCBjb25jcmV0aXNhdGlvbnMgPSB0aGlzLmZhbWl4UmVwLl9nZXRBbGxFbnRpdGllc1dpdGhUeXBlKFwiQ29uY3JldGlzYXRpb25cIikgYXMgU2V0PEZhbWl4LkNvbmNyZXRpc2F0aW9uPjtcclxuICAgIC8vICAgICAgICAgICAgICAgICBsZXQgY3JlYXRlQ29uY3JldGlzYXRpb24gOiBib29sZWFuID0gdHJ1ZTtcclxuICAgIC8vICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGlmIChnZW5JbnRlcmZhY2UuZnVsbHlRdWFsaWZpZWROYW1lID09IGNvbmMuZ2VuZXJpY0VudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgJiYgY29uYy5jb25jcmV0ZUVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uSW50ZXJmYWNlLmZ1bGx5UXVhbGlmaWVkTmFtZSl7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb25jcmV0aXNhdGlvbiA9IGZhbHNlO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgIFxyXG4gICAgLy8gICAgICAgICAgICAgICAgIGlmIChjcmVhdGVDb25jcmV0aXNhdGlvbikge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICBjb25zdCBmbXhDb25jcmV0aXNhdGlvbiA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gdGhpcy5jcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbkludGVyZmFjZSxnZW5JbnRlcmZhY2UpO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgfVxyXG4gICAgLy8gICAgIH0pO1xyXG4gICAgLy8gfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uIGJldHdlZW4gYW4gaW50ZXJmYWNlIGFuZCBhIFR5cGVcclxuICAgICAqIEBwYXJhbSBlbGVtZW50IEEgdmFyaWFibGUgb3IgYSBmdW5jdGlvblxyXG4gICAgICogQHBhcmFtIGludGVyIEFuIGludGVyZmFjZVxyXG4gICAgICovXHJcbiAgICAvLyBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvblR5cGVJbnN0YW5jaWF0aW9uKGVsZW1lbnQ6IEludGVyZmFjZURlY2xhcmF0aW9uIHwgQ2xhc3NEZWNsYXJhdGlvbil7XHJcblxyXG4gICAgLy8gICAgIGNvbnN0IGlzR2VuZXJpYyA9IGVsZW1lbnQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwO1xyXG4gICAgLy8gICAgIGlmIChpc0dlbmVyaWMpIHtcclxuICAgIC8vICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpLm1hcChwYXJhbSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xyXG4gICAgLy8gICAgICAgICBjb25zdCB1c2VzID0gZWxlbWVudC5maW5kUmVmZXJlbmNlc0FzTm9kZXMoKTtcclxuICAgIC8vICAgICAgICAgdXNlcy5mb3JFYWNoKHVzZSA9PiB7ICAgICAgICBcclxuICAgIC8vICAgICAgICAgICAgIGxldCBwYXJlbnROb2RlID0gdXNlLmdldFBhcmVudCgpO1xyXG4gICAgLy8gICAgICAgICAgICAgd2hpbGUgKHBhcmVudE5vZGUpIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZS5nZXRLaW5kKCkgPT09IFN5bnRheEtpbmQuVHlwZVJlZmVyZW5jZSkge1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlUmVmZXJlbmNlTm9kZSA9IHBhcmVudE5vZGUuYXNLaW5kKFN5bnRheEtpbmQuVHlwZVJlZmVyZW5jZSk7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGlmICghdHlwZVJlZmVyZW5jZU5vZGUpIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVHlwZVJlZmVyZW5jZU5vZGUgbm90IGZvdW5kIGZvciAke3BhcmVudE5vZGUuZ2V0VGV4dCgpfWApO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVSZWZlcmVuY2VOb2RlSXNHZW5lcmljID0gdHlwZVJlZmVyZW5jZU5vZGUuZ2V0VHlwZUFyZ3VtZW50cygpLmxlbmd0aCA+IDA7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlUmVmZXJlbmNlTm9kZUlzR2VuZXJpYykge31cclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSB0eXBlUmVmZXJlbmNlTm9kZS5nZXRUeXBlQXJndW1lbnRzKCk7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25QYXJhbXMgPSB0eXBlUmVmZXJlbmNlTm9kZS5nZXRUeXBlQXJndW1lbnRzKCkubWFwKHBhcmFtID0+IHBhcmFtLmdldFRleHQoKSk7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUhlbHBlcnMuYXJyYXlzQXJlRXF1YWwoY29uUGFyYW1zLGdlblBhcmFtcykpIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZ2VuRWxlbWVudDtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihlbGVtZW50IGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbil7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbkVsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhDbGFzcyhlbGVtZW50KSBhcyBGYW1peC5QYXJhbWV0cmljQ2xhc3M7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuRWxlbWVudCA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peEludGVyZmFjZShlbGVtZW50KSBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29uY0VsZW1lbnQ7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhDb25jcmV0ZUVsZW1lbnQoZ2VuRWxlbWVudCxlbGVtZW50LGFyZ3MpO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbmNyZXRpc2F0aW9ucyA9IHRoaXMuZmFtaXhSZXAuX2dldEFsbEVudGl0aWVzV2l0aFR5cGUoXCJDb25jcmV0aXNhdGlvblwiKSBhcyBTZXQ8RmFtaXguQ29uY3JldGlzYXRpb24+O1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjcmVhdGVDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmNyZXRpc2F0aW9ucy5mb3JFYWNoKChjb25jIDogRmFtaXguQ29uY3JldGlzYXRpb24pID0+IHtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdlbkVsZW1lbnQuZnVsbHlRdWFsaWZpZWROYW1lID09IGNvbmMuZ2VuZXJpY0VudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgJiYgY29uYy5jb25jcmV0ZUVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uY0VsZW1lbnQuZnVsbHlRdWFsaWZpZWROYW1lKXtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICBcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3JlYXRlQ29uY3JldGlzYXRpb24pIHtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb24gOiBGYW1peC5Db25jcmV0aXNhdGlvbiA9IHRoaXMuY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbihjb25jRWxlbWVudCxnZW5FbGVtZW50KTtcclxuICAgIC8vICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgLy8gICAgICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcGFyZW50Tm9kZS5nZXRQYXJlbnQoKTtcclxuICAgIC8vICAgICAgICAgICAgIH1cclxuICAgIC8vICAgICAgICAgfSk7XHJcbiAgICAvLyAgICAgfVxyXG4gICAgLy8gfVxyXG5cclxuICAgIHB1YmxpYyBjb252ZXJ0VG9SZWxhdGl2ZVBhdGgoYWJzb2x1dGVQYXRoOiBzdHJpbmcsIGFic29sdXRlUGF0aFByb2plY3Q6IHN0cmluZykge1xyXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgY29udmVydFRvUmVsYXRpdmVQYXRoOiBhYnNvbHV0ZVBhdGg6ICcke2Fic29sdXRlUGF0aH0nLCBhYnNvbHV0ZVBhdGhQcm9qZWN0OiAnJHthYnNvbHV0ZVBhdGhQcm9qZWN0fSdgKTtcclxuICAgICAgICBpZiAoYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgoYWJzb2x1dGVQYXRoUHJvamVjdCkpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFic29sdXRlUGF0aC5yZXBsYWNlKGFic29sdXRlUGF0aFByb2plY3QsIFwiXCIpLnNsaWNlKDEpO1xyXG4gICAgICAgIH0gZWxzZSBpZiAoYWJzb2x1dGVQYXRoLnN0YXJ0c1dpdGgoXCIvXCIpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBhYnNvbHV0ZVBhdGguc2xpY2UoMSk7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIGFic29sdXRlUGF0aDtcclxuICAgICAgICB9XHJcbiAgICB9XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBpc1ByaW1pdGl2ZVR5cGUodHlwZU5hbWU6IHN0cmluZykge1xyXG4gICAgcmV0dXJuIHR5cGVOYW1lID09PSBcIm51bWJlclwiIHx8XHJcbiAgICAgICAgdHlwZU5hbWUgPT09IFwic3RyaW5nXCIgfHxcclxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJib29sZWFuXCIgfHxcclxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJiaWdpbnRcIiB8fFxyXG4gICAgICAgIHR5cGVOYW1lID09PSBcInN5bWJvbFwiIHx8XHJcbiAgICAgICAgdHlwZU5hbWUgPT09IFwidW5kZWZpbmVkXCIgfHxcclxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJudWxsXCIgfHxcclxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJhbnlcIiB8fFxyXG4gICAgICAgIHR5cGVOYW1lID09PSBcInVua25vd25cIiB8fFxyXG4gICAgICAgIHR5cGVOYW1lID09PSBcIm5ldmVyXCIgfHxcclxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJ2b2lkXCI7XHJcbn1cclxuXHJcbmZ1bmN0aW9uIGluaXRGUU4oc291cmNlRWxlbWVudDogVFNNb3JwaE9iamVjdFR5cGUsIGZhbWl4RWxlbWVudDogRmFtaXguU291cmNlZEVudGl0eSkge1xyXG4gICAgLy8gaGFuZGxlIHNwZWNpYWwgY2FzZXMgd2hlcmUgYW4gZWxlbWVudCBpcyBhIFR5cGUgLS0gbmVlZCB0byBjaGFuZ2UgaXRzIG5hbWVcclxuICAgIGlmIChmYW1peEVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5UeXBlICYmICEoc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIENvbW1lbnRSYW5nZSkgJiYgaXNUeXBlQ29udGV4dChzb3VyY2VFbGVtZW50KSkge1xyXG4gICAgICAgIGxldCBmcW4gPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKHNvdXJjZUVsZW1lbnQpO1xyXG4gICAgICAgIC8vIHVzaW5nIHJlZ2V4LCByZXBsYWNlIFtibGFoXSB3aXRoIFtibGFoVHlwZV1cclxuICAgICAgICBmcW4gPSBmcW4ucmVwbGFjZSgvXFxbKFteXFxdXSspXFxdL2csIFwiWyQxVHlwZV1cIik7XHJcbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiU2V0dGluZyBmdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgXCIgKyBmYW1peEVsZW1lbnQuZ2V0SlNPTigpICsgXCIgdG8gXCIgKyBmcW4pO1xyXG4gICAgICAgIGZhbWl4RWxlbWVudC5mdWxseVF1YWxpZmllZE5hbWUgPSBmcW47XHJcbiAgICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG4gICAgLy8gY2F0Y2ggYWxsIChleGNlcHQgY29tbWVudHMpXHJcbiAgICBpZiAoIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSkge1xyXG4gICAgICAgIGNvbnN0IGZxbiA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oc291cmNlRWxlbWVudCk7XHJcbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiU2V0dGluZyBmdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgXCIgKyBmYW1peEVsZW1lbnQuZ2V0SlNPTigpICsgXCIgdG8gXCIgKyBmcW4pO1xyXG4gICAgICAgIChmYW1peEVsZW1lbnQgYXMgRmFtaXguTmFtZWRFbnRpdHkpLmZ1bGx5UXVhbGlmaWVkTmFtZSA9IGZxbjtcclxuICAgIH0gXHJcbn1cclxuXHJcblxyXG5mdW5jdGlvbiBpc1R5cGVDb250ZXh0KHNvdXJjZUVsZW1lbnQ6IEltcG9ydERlY2xhcmF0aW9uIHwgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24gfCBTb3VyY2VGaWxlIHwgTW9kdWxlRGVjbGFyYXRpb24gfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgTWV0aG9kU2lnbmF0dXJlIHwgRnVuY3Rpb25FeHByZXNzaW9uIHwgUGFyYW1ldGVyRGVjbGFyYXRpb24gfCBWYXJpYWJsZURlY2xhcmF0aW9uIHwgUHJvcGVydHlEZWNsYXJhdGlvbiB8IFByb3BlcnR5U2lnbmF0dXJlIHwgVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uIHwgSWRlbnRpZmllciB8IERlY29yYXRvciB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgSW1wb3J0U3BlY2lmaWVyIHwgRW51bURlY2xhcmF0aW9uIHwgRW51bU1lbWJlciB8IFR5cGVBbGlhc0RlY2xhcmF0aW9uIHwgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzIHwgVFNNb3JwaFBhcmFtZXRyaWNUeXBlKSB7XHJcbiAgICByZXR1cm4gc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yRGVjbGFyYXRpb25cclxuICAgICAgICB8fCBzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgTWV0aG9kRGVjbGFyYXRpb24gIFxyXG4gICAgICAgIHx8IHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBGdW5jdGlvbkRlY2xhcmF0aW9uIFxyXG4gICAgICAgIHx8IHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBGdW5jdGlvbkV4cHJlc3Npb24gXHJcbiAgICAgICAgfHwgc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIEFycm93RnVuY3Rpb25cclxuICAgICAgICB8fFxyXG4gICAgICAgIHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8fFxyXG4gICAgICAgIHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBWYXJpYWJsZURlY2xhcmF0aW9uIHx8XHJcbiAgICAgICAgc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIFByb3BlcnR5RGVjbGFyYXRpb24gfHxcclxuICAgICAgICBzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgUHJvcGVydHlTaWduYXR1cmUgfHxcclxuICAgICAgICBzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uIHx8XHJcbiAgICAgICAgc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIElkZW50aWZpZXIgfHxcclxuICAgICAgICBzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgRGVjb3JhdG9yIHx8XHJcbiAgICAgICAgc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfHxcclxuICAgICAgICBzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8fFxyXG4gICAgICAgIHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBJbXBvcnRTcGVjaWZpZXIgfHxcclxuICAgICAgICBzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgRW51bURlY2xhcmF0aW9uIHx8XHJcbiAgICAgICAgc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIEVudW1NZW1iZXIgfHxcclxuICAgICAgICBzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgVHlwZUFsaWFzRGVjbGFyYXRpb25cclxuICAgICAgICB8fCBzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgSW1wb3J0RGVjbGFyYXRpb25cclxuICAgICAgICB8fCBzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzO1xyXG59XHJcblxyXG5cclxuZnVuY3Rpb24gZ2V0SW50ZXJmYWNlRGVjbGFyYXRpb25Gcm9tRXhwcmVzc2lvbihleHByZXNzaW9uOiBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHMpOiBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZCB7XHJcbiAgICAvLyBTdGVwIDE6IEdldCB0aGUgdHlwZSBvZiB0aGUgZXhwcmVzc2lvblxyXG4gICAgY29uc3QgdHlwZSA9IGV4cHJlc3Npb24uZ2V0VHlwZSgpO1xyXG5cclxuICAgIC8vIFN0ZXAgMjogR2V0IHRoZSBzeW1ib2wgYXNzb2NpYXRlZCB3aXRoIHRoZSB0eXBlXHJcbiAgICBsZXQgc3ltYm9sID0gdHlwZS5nZXRTeW1ib2woKTtcclxuXHJcbiAgICBpZiAoIXN5bWJvbCkge1xyXG4gICAgICAgIC8vIElmIHN5bWJvbCBpcyBub3QgZm91bmQsIHRyeSB0byBnZXQgdGhlIHN5bWJvbCBmcm9tIHRoZSBpZGVudGlmaWVyXHJcbiAgICAgICAgY29uc3QgaWRlbnRpZmllciA9IGV4cHJlc3Npb24uZ2V0Rmlyc3REZXNjZW5kYW50QnlLaW5kKFN5bnRheEtpbmQuSWRlbnRpZmllcik7XHJcbiAgICAgICAgaWYgKCFpZGVudGlmaWVyKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSWRlbnRpZmllciBub3QgZm91bmQgZm9yICR7ZXhwcmVzc2lvbi5nZXRUZXh0KCl9LmApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBzeW1ib2wgPSBpZGVudGlmaWVyLmdldFN5bWJvbCgpO1xyXG4gICAgICAgIGlmICghc3ltYm9sKSB7XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3ltYm9sIG5vdCBmb3VuZCBmb3IgJHtpZGVudGlmaWVyLmdldFRleHQoKX0uYCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFN0ZXAgMzogUmVzb2x2ZSB0aGUgc3ltYm9sIHRvIGZpbmQgdGhlIGFjdHVhbCBkZWNsYXJhdGlvblxyXG4gICAgY29uc3QgaW50ZXJmYWNlRGVjbGFyYXRpb24gPSByZXNvbHZlU3ltYm9sVG9JbnRlcmZhY2VEZWNsYXJhdGlvbihzeW1ib2wpO1xyXG5cclxuICAgIGlmICghaW50ZXJmYWNlRGVjbGFyYXRpb24pIHtcclxuICAgICAgICBsb2dnZXIuZXJyb3IoYEludGVyZmFjZSBkZWNsYXJhdGlvbiBub3QgZm91bmQgZm9yICR7ZXhwcmVzc2lvbi5nZXRUZXh0KCl9LmApO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBpbnRlcmZhY2VEZWNsYXJhdGlvbjtcclxufVxyXG5cclxuaW1wb3J0IHsgU3ltYm9sIGFzIFRTTW9ycGhTeW1ib2wgfSBmcm9tIFwidHMtbW9ycGhcIjtcclxuXHJcbmZ1bmN0aW9uIHJlc29sdmVTeW1ib2xUb0ludGVyZmFjZURlY2xhcmF0aW9uKHN5bWJvbDogVFNNb3JwaFN5bWJvbCk6IEludGVyZmFjZURlY2xhcmF0aW9uIHwgdW5kZWZpbmVkIHtcclxuICAgIC8vIEdldCB0aGUgZGVjbGFyYXRpb25zIGFzc29jaWF0ZWQgd2l0aCB0aGUgc3ltYm9sXHJcbiAgICBjb25zdCBkZWNsYXJhdGlvbnMgPSBzeW1ib2wuZ2V0RGVjbGFyYXRpb25zKCk7XHJcblxyXG4gICAgLy8gRmlsdGVyIGZvciBJbnRlcmZhY2VEZWNsYXJhdGlvblxyXG4gICAgY29uc3QgaW50ZXJmYWNlRGVjbGFyYXRpb24gPSBkZWNsYXJhdGlvbnMuZmluZChkZWNsYXJhdGlvbiA9PiBkZWNsYXJhdGlvbiBpbnN0YW5jZW9mIEludGVyZmFjZURlY2xhcmF0aW9uKSBhcyBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZDtcclxuXHJcbiAgICBpZiAoaW50ZXJmYWNlRGVjbGFyYXRpb24pIHtcclxuICAgICAgICByZXR1cm4gaW50ZXJmYWNlRGVjbGFyYXRpb247XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSGFuZGxlIGltcG9ydHM6IElmIHRoZSBzeW1ib2wgaXMgaW1wb3J0ZWQsIHJlc29sdmUgdGhlIGltcG9ydCB0byBmaW5kIHRoZSBhY3R1YWwgZGVjbGFyYXRpb25cclxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgZGVjbGFyYXRpb25zKSB7XHJcbiAgICAgICAgaWYgKGRlY2xhcmF0aW9uLmdldEtpbmQoKSA9PT0gU3ludGF4S2luZC5JbXBvcnRTcGVjaWZpZXIpIHtcclxuICAgICAgICAgICAgY29uc3QgaW1wb3J0U3BlY2lmaWVyID0gZGVjbGFyYXRpb24gYXMgSW1wb3J0U3BlY2lmaWVyO1xyXG4gICAgICAgICAgICBjb25zdCBpbXBvcnREZWNsYXJhdGlvbiA9IGltcG9ydFNwZWNpZmllci5nZXRJbXBvcnREZWNsYXJhdGlvbigpO1xyXG4gICAgICAgICAgICBjb25zdCBtb2R1bGVTcGVjaWZpZXIgPSBpbXBvcnREZWNsYXJhdGlvbi5nZXRNb2R1bGVTcGVjaWZpZXJTb3VyY2VGaWxlKCk7XHJcblxyXG4gICAgICAgICAgICBpZiAobW9kdWxlU3BlY2lmaWVyKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBleHBvcnRlZFN5bWJvbHMgPSBtb2R1bGVTcGVjaWZpZXIuZ2V0RXhwb3J0U3ltYm9scygpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgZXhwb3J0ZWRTeW1ib2wgPSBleHBvcnRlZFN5bWJvbHMuZmluZChzeW1ib2wgPT4gc3ltYm9sLmdldE5hbWUoKSA9PT0gaW1wb3J0U3BlY2lmaWVyLmdldE5hbWUoKSk7XHJcbiAgICAgICAgICAgICAgICBpZiAoZXhwb3J0ZWRTeW1ib2wpIHtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gcmVzb2x2ZVN5bWJvbFRvSW50ZXJmYWNlRGVjbGFyYXRpb24oZXhwb3J0ZWRTeW1ib2wpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiB1bmRlZmluZWQ7XHJcbn1cclxuXHJcbi8vIGZ1bmN0aW9uIG9sZEdldEludGVyZmFjZURlY2xhcmF0aW9uRnJvbUV4cHJlc3Npb24oZXhwcmVzc2lvbjogRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKTogSW50ZXJmYWNlRGVjbGFyYXRpb24gfCB1bmRlZmluZWQge1xyXG4vLyAgICAgLy8gVHdvIGNhc2VzOlxyXG4vLyAgICAgLy8gY2xhc3MgQSBpbXBsZW1lbnRzIEltcG9ydGVkSW50ZXJmYWNlLCBEZWNsYXJlZEludGVyZmFjZSB7fVxyXG4vLyAgICAgY29uc3QgdHlwZSA9IGV4cHJlc3Npb24uZ2V0VHlwZSgpO1xyXG5cclxuLy8gICAgIC8vIEltcG9ydGVkSW50ZXJmYWNlOiB0eXBlIHdpbGwgYSBzeW1ib2wgXHJcbi8vICAgICBsZXQgc3ltYm9sID0gdHlwZS5nZXRBbGlhc1N5bWJvbCgpOyAgLy8gd2lsbCBiZSBkZWZpbmVkIGZvciBpbXBvcnRlZCBpbnRlcmZhY2VzXHJcblxyXG4vLyAgICAgaWYgKCFzeW1ib2wpIHtcclxuLy8gICAgICAgICAvLyBEZWNsYXJlZEludGVyZmFjZTogdHlwZSB3aWxsIGJlIGFuIEludGVyZmFjZURlY2xhcmF0aW9uIG9uIElkZW50aWZpZXIgbm9kZSB0aGF0IGlzIHRoZSBjaGlsZCBvZiB0aGUgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzXHJcbi8vICAgICAgICAgY29uc3QgaWRlbnRpZmllciA9IGV4cHJlc3Npb24uZ2V0Rmlyc3REZXNjZW5kYW50QnlLaW5kKFN5bnRheEtpbmQuSWRlbnRpZmllcik7XHJcbi8vICAgICAgICAgaWYgKCFpZGVudGlmaWVyKSB7XHJcbi8vICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSWRlbnRpZmllciBub3QgZm91bmQgZm9yICR7ZXhwcmVzc2lvbi5nZXRUZXh0KCl9LmApO1xyXG4vLyAgICAgICAgIH1cclxuLy8gICAgICAgICBzeW1ib2wgPSBpZGVudGlmaWVyLmdldFN5bWJvbCgpO1xyXG4vLyAgICAgICAgIGlmICghc3ltYm9sKSB7XHJcbi8vICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgU3ltYm9sIG5vdCBmb3VuZCBmb3IgJHtpZGVudGlmaWVyLmdldFRleHQoKX0uYCk7XHJcbi8vICAgICAgICAgfVxyXG4vLyAgICAgfVxyXG5cclxuLy8gICAgIC8vIFN0ZXAgMzogR2V0IHRoZSBkZWNsYXJhdGlvbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzeW1ib2xcclxuLy8gICAgIGNvbnN0IGRlY2xhcmF0aW9ucyA9IHN5bWJvbC5nZXREZWNsYXJhdGlvbnMoKTtcclxuXHJcbi8vICAgICAvLyBTdGVwIDQ6IEZpbHRlciBmb3IgSW50ZXJmYWNlRGVjbGFyYXRpb25cclxuLy8gICAgIGNvbnN0IGludGVyZmFjZURlY2xhcmF0aW9uID0gZGVjbGFyYXRpb25zLmZpbmQoZGVjbGFyYXRpb24gPT4gZGVjbGFyYXRpb24gaW5zdGFuY2VvZiBJbnRlcmZhY2VEZWNsYXJhdGlvbikgYXMgSW50ZXJmYWNlRGVjbGFyYXRpb24gfCB1bmRlZmluZWQ7XHJcblxyXG4vLyAgICAgaWYgKCFpbnRlcmZhY2VEZWNsYXJhdGlvbikge1xyXG4vLyAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW50ZXJmYWNlIGRlY2xhcmF0aW9uIG5vdCBmb3VuZCBmb3IgJHtleHByZXNzaW9uLmdldFRleHQoKX0uYCk7XHJcbi8vICAgICB9XHJcblxyXG4vLyAgICAgcmV0dXJuIGludGVyZmFjZURlY2xhcmF0aW9uO1xyXG4vLyB9XHJcbiJdfQ==
1878
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW50aXR5RGljdGlvbmFyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9mYW1peF9mdW5jdGlvbnMvRW50aXR5RGljdGlvbmFyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7R0FJRzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBczFESCwwQ0FhQztBQW1IRCxvREFpQkM7QUFwK0RELHVDQUF1bUI7QUFDdm1CLDhFQUFnRjtBQUNoRixnRUFBa0Q7QUFDbEQsb0VBQWdFO0FBQ2hFLHdDQUE0QztBQUM1QyxpRUFBaUU7QUFDakUsc0RBQXVEO0FBQ3ZELDREQUE4QztBQUM5QyxxREFBdUM7QUFDdkMsZ0RBQXdCO0FBY3hCLE1BQWEsZ0JBQWdCO0lBcUJ6QjtRQW5CTyxhQUFRLEdBQUcsSUFBSSxrQ0FBZSxFQUFFLENBQUM7UUFDaEMsZ0JBQVcsR0FBRyxJQUFJLEdBQUcsRUFBdUIsQ0FBQyxDQUFDLDRDQUE0QztRQUMxRixnQkFBVyxHQUFHLElBQUksR0FBRyxFQUErQyxDQUFDLENBQUMsNERBQTREO1FBQ2xJLG9CQUFlLEdBQUcsSUFBSSxHQUFHLEVBQXVELENBQUMsQ0FBQyxnREFBZ0Q7UUFDbEksaUJBQVksR0FBRyxJQUFJLEdBQUcsRUFBbUMsQ0FBQyxDQUFDLGdEQUFnRDtRQUMzRyxlQUFVLEdBQUcsSUFBSSxHQUFHLEVBQTZDLENBQUMsQ0FBQyxrREFBa0Q7UUFDckgsZUFBVSxHQUFHLElBQUksR0FBRyxFQUE0RCxDQUFDLENBQUMsbURBQW1EO1FBQ3JJLHdCQUFtQixHQUFHLElBQUksR0FBRyxFQUErQixDQUFDLENBQUMscURBQXFEO1FBQ25ILDRCQUF1QixHQUFHLElBQUksR0FBOEYsQ0FBQyxDQUFDLCtDQUErQztRQUM3Syx3QkFBbUIsR0FBRyxJQUFJLEdBQWdDLENBQUMsQ0FBQywrQ0FBK0M7UUFDM0csb0JBQWUsR0FBRyxJQUFJLEdBQUcsRUFBeUMsQ0FBQyxDQUFDLDJD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QztJQUNuRCxJQUFJLEtBQUssR0FBRyxhQUFFLENBQUMsU0FBUyxDQUFDLFNBQVM7UUFBRSxPQUFPLFdBQVcsQ0FBQztJQUN2RCxJQUFJLEtBQUssR0FBRyxhQUFFLENBQUMsU0FBUyxDQUFDLElBQUk7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUM3QyxJQUFJLEtBQUssR0FBRyxhQUFFLENBQUMsU0FBUyxDQUFDLElBQUk7UUFBRSxPQUFPLE1BQU0sQ0FBQztJQUM3QyxJQUFJLEtBQUssR0FBRyxhQUFFLENBQUMsU0FBUyxDQUFDLEtBQUs7UUFBRSxPQUFPLE9BQU8sQ0FBQztJQUMvQyxJQUFJLEtBQUssR0FBRyxhQUFFLENBQUMsU0FBUyxDQUFDLEdBQUc7UUFBRSxPQUFPLEtBQUssQ0FBQztJQUMzQyxJQUFJLEtBQUssR0FBRyxhQUFFLENBQUMsU0FBUyxDQUFDLE9BQU87UUFBRSxPQUFPLFNBQVMsQ0FBQztJQUVuRCxPQUFPLFNBQVMsQ0FBQztBQUNuQixDQUFDO0FBRUQsaUlBQWlJO0FBQ2pJLG9CQUFvQjtBQUNwQixvRUFBb0U7QUFDcEUseUNBQXlDO0FBRXpDLGdEQUFnRDtBQUNoRCxzRkFBc0Y7QUFFdEYscUJBQXFCO0FBQ3JCLDZJQUE2STtBQUM3SSx5RkFBeUY7QUFDekYsNkJBQTZCO0FBQzdCLG9GQUFvRjtBQUNwRixZQUFZO0FBQ1osMkNBQTJDO0FBQzNDLHlCQUF5QjtBQUN6QixnRkFBZ0Y7QUFDaEYsWUFBWTtBQUNaLFFBQVE7QUFFUixpRUFBaUU7QUFDakUscURBQXFEO0FBRXJELGlEQUFpRDtBQUNqRCxzSkFBc0o7QUFFdEosbUNBQW1DO0FBQ25DLDJGQUEyRjtBQUMzRixRQUFRO0FBRVIsbUNBQW1DO0FBQ25DLElBQUkiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIGEgZnVuY3Rpb24gZ2V0T3JDcmVhdGVYVHlwZSB0YWtlcyBhcmd1bWVudHMgbmFtZTogc3RyaW5nIGFuZCBlbGVtZW50OiB0cy1tb3JwaC10eXBlIGFuZCByZXR1cm5zIGEgRmFtaXguVHlwZVxuICogVGhlIGdvYWwgaXMgdG8ga2VlcCB0cmFjayBvZiB0aGUgdHlwZXMgKGUuZy4sIGEgbWV0aG9kJ3MgZGVmaW5lZFR5cGUpLCBmb3IgdGhlIG1vZGVsLlxuICogVGhlIG5hbWUgZG9lc24ndCBuZWVkIHRvIGJlIGZ1bGx5IHF1YWxpZmllZCAoaXQncyB0aGUgbmFtZSB1c2VkIGluIHRoZSBzb3VyY2UgY29kZSwgb3IgdGhlIEZhbWl4IG1vZGVsKS5cbiAqL1xuXG5cbmltcG9ydCB7IENsYXNzRGVjbGFyYXRpb24sIENvbnN0cnVjdG9yRGVjbGFyYXRpb24sIEZ1bmN0aW9uRGVjbGFyYXRpb24sIElkZW50aWZpZXIsIEludGVyZmFjZURlY2xhcmF0aW9uLCBNZXRob2REZWNsYXJhdGlvbiwgTWV0aG9kU2lnbmF0dXJlLCBNb2R1bGVEZWNsYXJhdGlvbiwgUHJvcGVydHlEZWNsYXJhdGlvbiwgUHJvcGVydHlTaWduYXR1cmUsIFNvdXJjZUZpbGUsIFR5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbiwgVmFyaWFibGVEZWNsYXJhdGlvbiwgUGFyYW1ldGVyRGVjbGFyYXRpb24sIERlY29yYXRvciwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiwgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbiwgSW1wb3J0U3BlY2lmaWVyLCBDb21tZW50UmFuZ2UsIEVudW1EZWNsYXJhdGlvbiwgRW51bU1lbWJlciwgVHlwZUFsaWFzRGVjbGFyYXRpb24sIEZ1bmN0aW9uRXhwcmVzc2lvbiwgSW1wb3J0RGVjbGFyYXRpb24sIEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uLCBTeW50YXhLaW5kLCBFeHByZXNzaW9uLCBUeXBlTm9kZSwgU2NvcGUsIEFycm93RnVuY3Rpb24sIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cywgSGVyaXRhZ2VDbGF1c2UsIHRzLCBUeXBlIH0gZnJvbSBcInRzLW1vcnBoXCI7XG5pbXBvcnQgeyBpc0FtYmllbnQsIGlzTmFtZXNwYWNlIH0gZnJvbSBcIi4uL2FuYWx5emVfZnVuY3Rpb25zL3Byb2Nlc3NfZnVuY3Rpb25zXCI7XG5pbXBvcnQgKiBhcyBGYW1peCBmcm9tIFwiLi4vbGliL2ZhbWl4L21vZGVsL2ZhbWl4XCI7XG5pbXBvcnQgeyBGYW1peFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vbGliL2ZhbWl4L2ZhbWl4X3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IGxvZ2dlciwgY29uZmlnIH0gZnJvbSBcIi4uL2FuYWx5emVcIjtcbi8vIGVzbGludC1kaXNhYmxlLW5leHQtbGluZSBAdHlwZXNjcmlwdC1lc2xpbnQvbm8tcmVxdWlyZS1pbXBvcnRzXG5pbXBvcnQgR3JhcGhlbWVTcGxpdHRlciA9IHJlcXVpcmUoJ2dyYXBoZW1lLXNwbGl0dGVyJyk7XG5pbXBvcnQgKiBhcyBIZWxwZXJzIGZyb20gXCIuL2hlbHBlcnNfY3JlYXRpb25cIjtcbmltcG9ydCAqIGFzIEZRTkZ1bmN0aW9ucyBmcm9tIFwiLi4vZnFuXCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuXG5leHBvcnQgdHlwZSBUU01vcnBoT2JqZWN0VHlwZSA9IEltcG9ydERlY2xhcmF0aW9uIHwgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24gfCBTb3VyY2VGaWxlIHwgTW9kdWxlRGVjbGFyYXRpb24gfCBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBNZXRob2REZWNsYXJhdGlvbiB8IENvbnN0cnVjdG9yRGVjbGFyYXRpb24gfCBNZXRob2RTaWduYXR1cmUgfCBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgRnVuY3Rpb25FeHByZXNzaW9uIHwgUGFyYW1ldGVyRGVjbGFyYXRpb24gfCBWYXJpYWJsZURlY2xhcmF0aW9uIHwgUHJvcGVydHlEZWNsYXJhdGlvbiB8IFByb3BlcnR5U2lnbmF0dXJlIHwgVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uIHwgSWRlbnRpZmllciB8IERlY29yYXRvciB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgSW1wb3J0U3BlY2lmaWVyIHwgQ29tbWVudFJhbmdlIHwgRW51bURlY2xhcmF0aW9uIHwgRW51bU1lbWJlciB8IFR5cGVBbGlhc0RlY2xhcmF0aW9uIHwgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzIHwgVFNNb3JwaFBhcmFtZXRyaWNUeXBlO1xuXG5leHBvcnQgdHlwZSBUU01vcnBoVHlwZURlY2xhcmF0aW9uID0gVHlwZUFsaWFzRGVjbGFyYXRpb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uIHwgUHJvcGVydHlTaWduYXR1cmUgfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgTWV0aG9kU2lnbmF0dXJlIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24gfCBQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IFZhcmlhYmxlRGVjbGFyYXRpb24gfCBFbnVtTWVtYmVyIHwgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24gfCBUU01vcnBoUGFyYW1ldHJpY1R5cGUgfCBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24gO1xuXG5leHBvcnQgdHlwZSBUU01vcnBoUGFyYW1ldHJpY1R5cGUgPSBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgTWV0aG9kRGVjbGFyYXRpb24gfCBBcnJvd0Z1bmN0aW9uO1xuXG50eXBlIFBhcmFtZXRyaWNWYXJpYW50VHlwZSA9IEZhbWl4LlBhcmFtZXRyaWNDbGFzcyB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UgfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kO1xuXG50eXBlIENvbmNyZXRlRWxlbWVudFRTTW9ycGhUeXBlID0gQ2xhc3NEZWNsYXJhdGlvbiB8IEludGVyZmFjZURlY2xhcmF0aW9uIHwgRnVuY3Rpb25EZWNsYXJhdGlvbiB8IE1ldGhvZERlY2xhcmF0aW9uO1xuXG5leHBvcnQgdHlwZSBJbnZvY2FibGVUeXBlID0gTWV0aG9kRGVjbGFyYXRpb24gfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgRnVuY3Rpb25FeHByZXNzaW9uIHwgQXJyb3dGdW5jdGlvbjtcblxuZXhwb3J0IGNsYXNzIEVudGl0eURpY3Rpb25hcnkge1xuICAgIFxuICAgIHB1YmxpYyBmYW1peFJlcCA9IG5ldyBGYW1peFJlcG9zaXRvcnkoKTtcbiAgICBwcml2YXRlIGZteEFsaWFzTWFwID0gbmV3IE1hcDxzdHJpbmcsIEZhbWl4LkFsaWFzPigpOyAvLyBNYXBzIHRoZSBhbGlhcyBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxuICAgIHByaXZhdGUgZm14Q2xhc3NNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljQ2xhc3M+KCk7IC8vIE1hcHMgdGhlIGZ1bGx5IHF1YWxpZmllZCBjbGFzcyBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxuICAgIHByaXZhdGUgZm14SW50ZXJmYWNlTWFwID0gbmV3IE1hcDxzdHJpbmcsIEZhbWl4LkludGVyZmFjZSB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2U+KCk7IC8vIE1hcHMgdGhlIGludGVyZmFjZSBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxuICAgIHByaXZhdGUgZm14TW9kdWxlTWFwID0gbmV3IE1hcDxNb2R1bGVEZWNsYXJhdGlvbiwgRmFtaXguTW9kdWxlPigpOyAvLyBNYXBzIHRoZSBuYW1lc3BhY2UgbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIGZteEZpbGVNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguU2NyaXB0RW50aXR5IHwgRmFtaXguTW9kdWxlPigpOyAvLyBNYXBzIHRoZSBzb3VyY2UgZmlsZSBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxuICAgIHByaXZhdGUgZm14VHlwZU1hcCA9IG5ldyBNYXA8VFNNb3JwaFR5cGVEZWNsYXJhdGlvbiwgRmFtaXguVHlwZSB8IEZhbWl4LlBhcmFtZXRlclR5cGU+KCk7IC8vIE1hcHMgdGhlIHR5cGVzIGRlY2xhcmF0aW9ucyB0byB0aGVpciBGYW1peCBtb2RlbFxuICAgIHByaXZhdGUgZm14UHJpbWl0aXZlVHlwZU1hcCA9IG5ldyBNYXA8c3RyaW5nLCBGYW1peC5QcmltaXRpdmVUeXBlPigpOyAvLyBNYXBzIHRoZSBwcmltaXRpdmUgdHlwZSBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxuICAgIHByaXZhdGUgZm14RnVuY3Rpb25BbmRNZXRob2RNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24gfCBGYW1peC5NZXRob2QgfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kPjsgLy8gTWFwcyB0aGUgZnVuY3Rpb24gbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIGZteEFycm93RnVuY3Rpb25NYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguQXJyb3dGdW5jdGlvbj47IC8vIE1hcHMgdGhlIGZ1bmN0aW9uIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXG4gICAgcHJpdmF0ZSBmbXhQYXJhbWV0ZXJNYXAgPSBuZXcgTWFwPFBhcmFtZXRlckRlY2xhcmF0aW9uLCBGYW1peC5QYXJhbWV0ZXI+KCk7IC8vIE1hcHMgdGhlIHBhcmFtZXRlcnMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIGZteFZhcmlhYmxlTWFwID0gbmV3IE1hcDxWYXJpYWJsZURlY2xhcmF0aW9uLCBGYW1peC5WYXJpYWJsZT4oKTsgLy8gTWFwcyB0aGUgdmFyaWFibGVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXG4gICAgcHJpdmF0ZSBmbXhJbXBvcnRDbGF1c2VNYXAgPSBuZXcgTWFwPEltcG9ydERlY2xhcmF0aW9uIHwgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24sIEZhbWl4LkltcG9ydENsYXVzZT4oKTsgLy8gTWFwcyB0aGUgaW1wb3J0IGNsYXVzZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIGZteEVudW1NYXAgPSBuZXcgTWFwPEVudW1EZWNsYXJhdGlvbiwgRmFtaXguRW51bT4oKTsgLy8gTWFwcyB0aGUgZW51bSBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxuICAgIHByaXZhdGUgZm14SW5oZXJpdGFuY2VNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguSW5oZXJpdGFuY2U+KCk7IC8vIE1hcHMgdGhlIGluaGVyaXRhbmNlIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXG4gICAgcHJpdmF0ZSBVTktOT1dOX1ZBTFVFID0gJyh1bmtub3duIGR1ZSB0byBwYXJzaW5nIGVycm9yKSc7IC8vIFRoZSB2YWx1ZSB0byB1c2Ugd2hlbiBhIG5hbWUgaXMgbm90IHVzYWJsZVxuICAgIHB1YmxpYyBmbXhFbGVtZW50T2JqZWN0TWFwID0gbmV3IE1hcDxGYW1peC5FbnRpdHksVFNNb3JwaE9iamVjdFR5cGU+KCk7XG4gICAgcHVibGljIHRzTW9ycGhFbGVtZW50T2JqZWN0TWFwID0gbmV3IE1hcDxUU01vcnBoT2JqZWN0VHlwZSxGYW1peC5FbnRpdHk+KCk7XG4gICAgICAgICAgICBcbiAgICBjb25zdHJ1Y3RvcigpIHtcbiAgICAgICAgdGhpcy5mYW1peFJlcC5zZXRGbXhFbGVtZW50T2JqZWN0TWFwKHRoaXMuZm14RWxlbWVudE9iamVjdE1hcCk7ICAgICAgXG4gICAgfVxuXG4gICAgcHVibGljIGFkZFNvdXJjZUFuY2hvcihmbXg6IEZhbWl4LlNvdXJjZWRFbnRpdHksIG5vZGU6IFRTTW9ycGhPYmplY3RUeXBlKTogRmFtaXguSW5kZXhlZEZpbGVBbmNob3Ige1xuICAgICAgICBjb25zdCBzb3VyY2VBbmNob3I6IEZhbWl4LkluZGV4ZWRGaWxlQW5jaG9yID0gbmV3IEZhbWl4LkluZGV4ZWRGaWxlQW5jaG9yKCk7XG4gICAgICAgIGxldCBzb3VyY2VTdGFydCwgc291cmNlRW5kOiBudW1iZXI7XG4gICAgICAgIGlmIChmbXggJiYgbm9kZSkge1xuICAgICAgICAgICAgLy8gZmluZCB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgb2YgdGhlIHNvdXJjZSBlbGVtZW50XG4gICAgICAgICAgICBpZiAoIShub2RlIGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSkge1xuICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gbm9kZS5nZXRTdGFydCgpO1xuICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IG5vZGUuZ2V0RW5kKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gbm9kZS5nZXRQb3MoKTtcbiAgICAgICAgICAgICAgICBzb3VyY2VFbmQgPSBub2RlLmdldEVuZCgpO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgaWYgKGNvbmZpZy5leHBlY3RHcmFwaGVtZXMpIHtcbiAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgKiBUaGUgZm9sbG93aW5nIGxvZ2ljIGhhbmRsZXMgdGhlIGNhc2Ugb2YgbXVsdGktY29kZSBwb2ludCBjaGFyYWN0ZXJzIChlLmcuIGVtb2ppKSBpbiB0aGUgc291cmNlIHRleHQuXG4gICAgICAgICAgICAgICAgICogVGhpcyBpcyBuZWVkZWQgYmVjYXVzZSBQaGFyby9TbWFsbHRhbGsgdHJlYXRzIG11bHRpLWNvZGUgcG9pbnQgY2hhcmFjdGVycyBhcyBhIHNpbmdsZSBjaGFyYWN0ZXIsIFxuICAgICAgICAgICAgICAgICAqIGJ1dCBKYXZhU2NyaXB0IHRyZWF0cyB0aGVtIGFzIG11bHRpcGxlIGNoYXJhY3RlcnMuIFRoaXMgbWVhbnMgdGhhdCB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnNcbiAgICAgICAgICAgICAgICAgKiBvZiBhIHNvdXJjZSBlbGVtZW50IGluIFBoYXJvL1NtYWxsdGFsayB3aWxsIGJlIGRpZmZlcmVudCB0aGFuIHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiB0aGVcbiAgICAgICAgICAgICAgICAgKiBzYW1lIHNvdXJjZSBlbGVtZW50IGluIEphdmFTY3JpcHQuIFRoaXMgbG9naWMgZmluZHMgdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIHRoZSBzb3VyY2VcbiAgICAgICAgICAgICAgICAgKiBlbGVtZW50IGluIEphdmFTY3JpcHQgYW5kIHRoZW4gdXNlcyB0aG9zZSBwb3NpdGlvbnMgdG8gc2V0IHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiB0aGVcbiAgICAgICAgICAgICAgICAgKiBGYW1peCBpbmRleCBmaWxlIGFuY2hvci5cbiAgICAgICAgICAgICAgICAgKiBJdCBkZXBlbmRzIG9uIGNvZGUgaW4gdGhlICdncmFwaGVtZS1zcGxpdHRlcicgcGFja2FnZSBpbiBucG0uXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3Qgc3BsaXR0ZXIgPSBuZXcgR3JhcGhlbWVTcGxpdHRlcigpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUZpbGVUZXh0ID0gbm9kZS5nZXRTb3VyY2VGaWxlKCkuZ2V0RnVsbFRleHQoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBoYXNHcmFwaGVtZUNsdXN0ZXJzID0gc3BsaXR0ZXIuY291bnRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQpID4gMTtcbiAgICAgICAgICAgICAgICBpZiAoaGFzR3JhcGhlbWVDbHVzdGVycykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50VGV4dCA9IHNvdXJjZUZpbGVUZXh0LnN1YnN0cmluZyhzb3VyY2VTdGFydCwgc291cmNlRW5kKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMgPSBzcGxpdHRlci5zcGxpdEdyYXBoZW1lcyhzb3VyY2VFbGVtZW50VGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUZpbGVUZXh0R3JhcGhlbWVzID0gc3BsaXR0ZXIuc3BsaXRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZkdyYXBoZW1lQ2x1c3RlcnNCZWZvcmVTdGFydCA9IHNwbGl0dGVyLmNvdW50R3JhcGhlbWVzKHNvdXJjZUZpbGVUZXh0LnN1YnN0cmluZygwLCBzb3VyY2VTdGFydCkpO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgLy8gZmluZCB0aGUgc3RhcnQgb2YgdGhlIHNvdXJjZUVsZW1lbnRUZXh0R3JhcGhlbWVzIGFycmF5IGluIHRoZSBzb3VyY2VGaWxlVGV4dEdyYXBoZW1lcyBhcnJheVxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VTdGFydCA9IEhlbHBlcnMuaW5kZXhPZlNwbGl0QXJyYXkoe3NlYXJjaEFycmF5OiBzb3VyY2VGaWxlVGV4dEdyYXBoZW1lcywgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEFycmF5OiBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcywgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBzb3VyY2VTdGFydCAtIG51bWJlck9mR3JhcGhlbWVDbHVzdGVyc0JlZm9yZVN0YXJ0fSk7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IHNvdXJjZVN0YXJ0ICsgc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFRoZSArMSBpcyBiZWNhdXNlIHRoZSBzb3VyY2UgYW5jaG9yIChQaGFybykgaXMgMS1iYXNlZCwgYnV0IHRzLW1vcnBoIGlzIDAtYmFzZWRcbiAgICAgICAgICAgIHNvdXJjZUFuY2hvci5zdGFydFBvcyA9IHNvdXJjZVN0YXJ0ICsgMTtcbiAgICAgICAgICAgIHNvdXJjZUFuY2hvci5lbmRQb3MgPSBzb3VyY2VFbmQgKyAxO1xuXG4gICAgICAgICAgICBsZXQgZmlsZU5hbWUgPSBub2RlLmdldFNvdXJjZUZpbGUoKS5nZXRGaWxlUGF0aCgpIGFzIHN0cmluZztcbiAgICAgICAgICAgIGlmIChmaWxlTmFtZS5zdGFydHNXaXRoKFwiL1wiKSkge1xuICAgICAgICAgICAgICAgIGZpbGVOYW1lID0gZmlsZU5hbWUuc3Vic3RyaW5nKDEpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgc291cmNlQW5jaG9yLmVsZW1lbnQgPSBmbXg7XG4gICAgICAgICAgICBzb3VyY2VBbmNob3IuZmlsZU5hbWUgPSBmaWxlTmFtZTtcbiAgICAgICAgICAgIGZteC5zb3VyY2VBbmNob3IgPSBzb3VyY2VBbmNob3I7XG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoc291cmNlQW5jaG9yKTtcblxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzb3VyY2VBbmNob3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYSBGYW1peCBpbmRleCBmaWxlIGFuY2hvclxuICAgICAqIEBwYXJhbSBzb3VyY2VFbGVtZW50IEEgc291cmNlIGVsZW1lbnRcbiAgICAgKiBAcGFyYW0gZmFtaXhFbGVtZW50IFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgc291cmNlIGVsZW1lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgbWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKHNvdXJjZUVsZW1lbnQ6IFRTTW9ycGhPYmplY3RUeXBlLCBmYW1peEVsZW1lbnQ6IEZhbWl4LlNvdXJjZWRFbnRpdHkpOiB2b2lkIHtcbiAgICAgICAgLy8gRmFtaXguQ29tbWVudCBpcyBub3QgYSBuYW1lZCBlbnRpdHkgKGRvZXMgbm90IGhhdmUgYSBmdWxseVF1YWxpZmllZE5hbWUpXG4gICAgICAgIGlmICghKGZhbWl4RWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LkNvbW1lbnQpKSB7ICAvLyBtdXN0IGJlIGEgbmFtZWQgZW50aXR5XG4gICAgICAgICAgICAvLyBpbnNhbml0eSBjaGVjazogbmFtZWQgZW50aXRpZXMgc2hvdWxkIGhhdmUgZnVsbHlRdWFsaWZpZWROYW1lXG4gICAgICAgICAgICBjb25zdCBmdWxseVF1YWxpZmllZE5hbWUgPSAoZmFtaXhFbGVtZW50IGFzIEZhbWl4Lk5hbWVkRW50aXR5KS5mdWxseVF1YWxpZmllZE5hbWU7XG4gICAgICAgICAgICBpZiAoIWZ1bGx5UXVhbGlmaWVkTmFtZSB8fCBmdWxseVF1YWxpZmllZE5hbWUgPT09IHRoaXMuVU5LTk9XTl9WQUxVRSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggZWxlbWVudCAke2ZhbWl4RWxlbWVudC5jb25zdHJ1Y3Rvci5uYW1lfSBoYXMgbm8gdmFsaWQgZnVsbHlRdWFsaWZpZWROYW1lLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwibWFraW5nIGluZGV4IGZpbGUgYW5jaG9yIGZvciAnXCIgKyBzb3VyY2VFbGVtZW50Py5nZXRUZXh0KCkgKyBcIicgd2l0aCBmYW1peEVsZW1lbnQgXCIgKyBmYW1peEVsZW1lbnQuZ2V0SlNPTigpKTtcbiAgICAgICAgY29uc3QgZm14SW5kZXhGaWxlQW5jaG9yID0gbmV3IEZhbWl4LkluZGV4ZWRGaWxlQW5jaG9yKCk7XG4gICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5lbGVtZW50ID0gZmFtaXhFbGVtZW50O1xuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZhbWl4RWxlbWVudCwgc291cmNlRWxlbWVudCk7XG5cbiAgICAgICAgaWYgKHNvdXJjZUVsZW1lbnQgIT09IG51bGwpIHtcbiAgICAgICAgICAgIGNvbnN0IGFic29sdXRlUGF0aFByb2plY3QgPSB0aGlzLmZhbWl4UmVwLmdldEFic29sdXRlUGF0aCgpO1xuICAgICAgICBcbiAgICAgICAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgubm9ybWFsaXplKHNvdXJjZUVsZW1lbnQuZ2V0U291cmNlRmlsZSgpLmdldEZpbGVQYXRoKCkpO1xuXG4gICAgICAgICAgICBjb25zdCBwb3NpdGlvbk5vZGVNb2R1bGVzID0gYWJzb2x1dGVQYXRoLmluZGV4T2YoJ25vZGVfbW9kdWxlcycpO1xuXG4gICAgICAgICAgICBsZXQgcGF0aEluUHJvamVjdDogc3RyaW5nID0gXCJcIjtcblxuICAgICAgICAgICAgaWYgKHBvc2l0aW9uTm9kZU1vZHVsZXMgIT09IC0xKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcGF0aEZyb21Ob2RlTW9kdWxlcyA9IGFic29sdXRlUGF0aC5zdWJzdHJpbmcocG9zaXRpb25Ob2RlTW9kdWxlcyk7XG4gICAgICAgICAgICAgICAgcGF0aEluUHJvamVjdCA9IHBhdGhGcm9tTm9kZU1vZHVsZXM7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHBhdGhJblByb2plY3QgPSB0aGlzLmNvbnZlcnRUb1JlbGF0aXZlUGF0aChhYnNvbHV0ZVBhdGgsIGFic29sdXRlUGF0aFByb2plY3QpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyByZXZlcnQgYW55IGJhY2tzbGFzaGVzIHRvIGZvcndhcmQgc2xhc2hlcyAocGF0aC5ub3JtYWxpemUgb24gd2luZG93cyBpbnRyb2R1Y2VzIHRoZW0pXG4gICAgICAgICAgICBwYXRoSW5Qcm9qZWN0ID0gcGF0aEluUHJvamVjdC5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKTtcblxuICAgICAgICAgICAgaWYgKHBhdGhJblByb2plY3Quc3RhcnRzV2l0aChcIi9cIikpIHtcbiAgICAgICAgICAgICAgICBwYXRoSW5Qcm9qZWN0ID0gcGF0aEluUHJvamVjdC5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5maWxlTmFtZSA9IHBhdGhJblByb2plY3Q7XG4gICAgICAgICAgICBsZXQgc291cmNlU3RhcnQsIHNvdXJjZUVuZFxuICAgICAgICAgICAgLy8gLHNvdXJjZUxpbmVTdGFydCwgc291cmNlTGluZUVuZFxuICAgICAgICAgICAgOiBudW1iZXI7XG4gICAgICAgICAgICBpZiAoIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSkge1xuICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gc291cmNlRWxlbWVudC5nZXRTdGFydCgpO1xuICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IHNvdXJjZUVsZW1lbnQuZ2V0RW5kKCk7XG4gICAgICAgICAgICAgICAgLy8gc291cmNlTGluZVN0YXJ0ID0gc291cmNlRWxlbWVudC5nZXRTdGFydExpbmVOdW1iZXIoKTtcbiAgICAgICAgICAgICAgICAvLyBzb3VyY2VMaW5lRW5kID0gc291cmNlRWxlbWVudC5nZXRFbmRMaW5lTnVtYmVyKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gc291cmNlRWxlbWVudC5nZXRQb3MoKTtcbiAgICAgICAgICAgICAgICBzb3VyY2VFbmQgPSBzb3VyY2VFbGVtZW50LmdldEVuZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbmZpZy5leHBlY3RHcmFwaGVtZXMpIHtcbiAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgKiBUaGUgZm9sbG93aW5nIGxvZ2ljIGhhbmRsZXMgdGhlIGNhc2Ugb2YgbXVsdGktY29kZSBwb2ludCBjaGFyYWN0ZXJzIChlLmcuIGVtb2ppKSBpbiB0aGUgc291cmNlIHRleHQuXG4gICAgICAgICAgICAgICAgICogVGhpcyBpcyBuZWVkZWQgYmVjYXVzZSBQaGFyby9TbWFsbHRhbGsgdHJlYXRzIG11bHRpLWNvZGUgcG9pbnQgY2hhcmFjdGVycyBhcyBhIHNpbmdsZSBjaGFyYWN0ZXIsIFxuICAgICAgICAgICAgICAgICAqIGJ1dCBKYXZhU2NyaXB0IHRyZWF0cyB0aGVtIGFzIG11bHRpcGxlIGNoYXJhY3RlcnMuIFRoaXMgbWVhbnMgdGhhdCB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnNcbiAgICAgICAgICAgICAgICAgKiBvZiBhIHNvdXJjZSBlbGVtZW50IGluIFBoYXJvL1NtYWxsdGFsayB3aWxsIGJlIGRpZmZlcmVudCB0aGFuIHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiB0aGVcbiAgICAgICAgICAgICAgICAgKiBzYW1lIHNvdXJjZSBlbGVtZW50IGluIEphdmFTY3JpcHQuIFRoaXMgbG9naWMgZmluZHMgdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIHRoZSBzb3VyY2VcbiAgICAgICAgICAgICAgICAgKiBlbGVtZW50IGluIEphdmFTY3JpcHQgYW5kIHRoZW4gdXNlcyB0aG9zZSBwb3NpdGlvbnMgdG8gc2V0IHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiB0aGVcbiAgICAgICAgICAgICAgICAgKiBGYW1peCBpbmRleCBmaWxlIGFuY2hvci5cbiAgICAgICAgICAgICAgICAgKiBJdCBkZXBlbmRzIG9uIGNvZGUgaW4gdGhlICdncmFwaGVtZS1zcGxpdHRlcicgcGFja2FnZSBpbiBucG0uXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3Qgc3BsaXR0ZXIgPSBuZXcgR3JhcGhlbWVTcGxpdHRlcigpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUZpbGVUZXh0ID0gc291cmNlRWxlbWVudC5nZXRTb3VyY2VGaWxlKCkuZ2V0RnVsbFRleHQoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBoYXNHcmFwaGVtZUNsdXN0ZXJzID0gc3BsaXR0ZXIuY291bnRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQpID4gMTtcbiAgICAgICAgICAgICAgICBpZiAoaGFzR3JhcGhlbWVDbHVzdGVycykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50VGV4dCA9IHNvdXJjZUZpbGVUZXh0LnN1YnN0cmluZyhzb3VyY2VTdGFydCwgc291cmNlRW5kKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMgPSBzcGxpdHRlci5zcGxpdEdyYXBoZW1lcyhzb3VyY2VFbGVtZW50VGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUZpbGVUZXh0R3JhcGhlbWVzID0gc3BsaXR0ZXIuc3BsaXRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZkdyYXBoZW1lQ2x1c3RlcnNCZWZvcmVTdGFydCA9IHNwbGl0dGVyLmNvdW50R3JhcGhlbWVzKHNvdXJjZUZpbGVUZXh0LnN1YnN0cmluZygwLCBzb3VyY2VTdGFydCkpO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgLy8gZmluZCB0aGUgc3RhcnQgb2YgdGhlIHNvdXJjZUVsZW1lbnRUZXh0R3JhcGhlbWVzIGFycmF5IGluIHRoZSBzb3VyY2VGaWxlVGV4dEdyYXBoZW1lcyBhcnJheVxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VTdGFydCA9IEhlbHBlcnMuaW5kZXhPZlNwbGl0QXJyYXkoe3NlYXJjaEFycmF5OiBzb3VyY2VGaWxlVGV4dEdyYXBoZW1lcywgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEFycmF5OiBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcywgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBzb3VyY2VTdGFydCAtIG51bWJlck9mR3JhcGhlbWVDbHVzdGVyc0JlZm9yZVN0YXJ0fSk7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IHNvdXJjZVN0YXJ0ICsgc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBub3RlOiB0aGUgKzEgaXMgYmVjYXVzZSB0aGUgc291cmNlIGFuY2hvciBpcyAxLWJhc2VkLCBidXQgdHMtbW9ycGggaXMgMC1iYXNlZFxuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLnN0YXJ0UG9zID0gc291cmNlU3RhcnQgKyAxO1xuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLmVuZFBvcyA9IHNvdXJjZUVuZCArIDE7XG5cbiAgICAgICAgICAgIC8vIGlmICghKGZhbWl4RWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LkltcG9ydENsYXVzZSB8fCBmYW1peEVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5BY2Nlc3MgfHwgZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUmVmZXJlbmNlIHx8IGZhbWl4RWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4Lkludm9jYXRpb24gfHwgZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguSW5oZXJpdGFuY2UpICYmICEoZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguQ29tbWVudCkgJiYgIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSAmJiAhKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBJZGVudGlmaWVyKSAmJiAhKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBJbXBvcnRTcGVjaWZpZXIpICYmICEoc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cykpIHtcbiAgICAgICAgICAgIC8vICAgIGluaXRGUU4oc291cmNlRWxlbWVudCwgZmFtaXhFbGVtZW50KTtcbiAgICAgICAgICAgIC8vIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHNvdXJjZUVsZW1lbnQgaXMgbnVsbFxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXCJzb3VyY2VFbGVtZW50IGlzIG51bGwgZm9yIGZhbWl4RWxlbWVudCBcIiArIGZhbWl4RWxlbWVudC5nZXRKU09OKCkpO1xuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLmZpbGVOYW1lID0gXCJ1bmtub3duXCI7XG4gICAgICAgICAgICBmbXhJbmRleEZpbGVBbmNob3Iuc3RhcnRQb3MgPSAwO1xuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLmVuZFBvcyA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW5kZXhGaWxlQW5jaG9yKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBzY3JpcHQgZW50aXR5IG9yIG1vZHVsZVxuICAgICAqIEBwYXJhbSBmIEEgc291cmNlIGZpbGVcbiAgICAgKiBAcGFyYW0gaXNNb2R1bGUgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIHNvdXJjZSBmaWxlIGlzIGEgbW9kdWxlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBzb3VyY2UgZmlsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4RmlsZShmOiBTb3VyY2VGaWxlLCBpc01vZHVsZTogYm9vbGVhbik6IEZhbWl4LlNjcmlwdEVudGl0eSB8IEZhbWl4Lk1vZHVsZSB7XG4gICAgICAgIGxldCBmbXhGaWxlOiBGYW1peC5TY3JpcHRFbnRpdHk7IC8vIHwgRmFtaXguTW9kdWxlO1xuXG4gICAgICAgIGNvbnN0IGZpbGVOYW1lID0gZi5nZXRCYXNlTmFtZSgpO1xuICAgICAgICBjb25zdCBmdWxseVF1YWxpZmllZEZpbGVuYW1lID0gZi5nZXRGaWxlUGF0aCgpO1xuICAgICAgICBjb25zdCBmb3VuZEZpbGVOYW1lID0gdGhpcy5mbXhGaWxlTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKTtcbiAgICAgICAgaWYgKCFmb3VuZEZpbGVOYW1lKSB7XG4gICAgICAgICAgICBpZiAoaXNNb2R1bGUpIHtcbiAgICAgICAgICAgICAgICBmbXhGaWxlID0gbmV3IEZhbWl4Lk1vZHVsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm14RmlsZSA9IG5ldyBGYW1peC5TY3JpcHRFbnRpdHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZteEZpbGUubmFtZSA9IGZpbGVOYW1lO1xuICAgICAgICAgICAgZm14RmlsZS5udW1iZXJPZkxpbmVzT2ZUZXh0ID0gZi5nZXRFbmRMaW5lTnVtYmVyKCkgLSBmLmdldFN0YXJ0TGluZU51bWJlcigpO1xuICAgICAgICAgICAgZm14RmlsZS5udW1iZXJPZkNoYXJhY3RlcnMgPSBmLmdldEZ1bGxUZXh0KCkubGVuZ3RoO1xuXG4gICAgICAgICAgICBpbml0RlFOKGYsIGZteEZpbGUpO1xuXG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihmLCBmbXhGaWxlKTtcblxuICAgICAgICAgICAgdGhpcy5mbXhGaWxlTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBmbXhGaWxlKTtcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhGaWxlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZteEZpbGUgPSBmb3VuZEZpbGVOYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhGaWxlLGYpO1xuICAgICAgICByZXR1cm4gZm14RmlsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBNb2R1bGVcbiAgICAgKiBAcGFyYW0gbW9kdWxlRGVjbGFyYXRpb24gQSBtb2R1bGVcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIG1vZHVsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4TW9kdWxlKG1vZHVsZURlY2xhcmF0aW9uOiBNb2R1bGVEZWNsYXJhdGlvbik6IEZhbWl4Lk1vZHVsZSB7XG4gICAgICAgIGlmICh0aGlzLmZteE1vZHVsZU1hcC5oYXMobW9kdWxlRGVjbGFyYXRpb24pKSB7XG4gICAgICAgICAgICBjb25zdCByTW9kdWxlID0gdGhpcy5mbXhNb2R1bGVNYXAuZ2V0KG1vZHVsZURlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgIGlmIChyTW9kdWxlKSB7IFxuICAgICAgICAgICAgICAgcmV0dXJuIHJNb2R1bGU7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggbW9kdWxlICR7bW9kdWxlRGVjbGFyYXRpb24uZ2V0TmFtZSgpfSBpcyBub3QgZm91bmQgaW4gdGhlIG1vZHVsZSBtYXAuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmbXhNb2R1bGUgPSBuZXcgRmFtaXguTW9kdWxlKCk7XG4gICAgICAgIGNvbnN0IG1vZHVsZU5hbWUgPSBtb2R1bGVEZWNsYXJhdGlvbi5nZXROYW1lKCk7XG4gICAgICAgIGZteE1vZHVsZS5uYW1lID0gbW9kdWxlTmFtZTtcbiAgICAgICAgZm14TW9kdWxlLmlzQW1iaWVudCA9IGlzQW1iaWVudChtb2R1bGVEZWNsYXJhdGlvbik7XG4gICAgICAgIGZteE1vZHVsZS5pc05hbWVzcGFjZSA9IGlzTmFtZXNwYWNlKG1vZHVsZURlY2xhcmF0aW9uKTtcbiAgICAgICAgZm14TW9kdWxlLmlzTW9kdWxlID0gIWZteE1vZHVsZS5pc05hbWVzcGFjZSAmJiAhZm14TW9kdWxlLmlzQW1iaWVudDtcblxuICAgICAgICBpbml0RlFOKG1vZHVsZURlY2xhcmF0aW9uLCBmbXhNb2R1bGUpO1xuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihtb2R1bGVEZWNsYXJhdGlvbiwgZm14TW9kdWxlKTtcblxuICAgICAgICB0aGlzLmZteE1vZHVsZU1hcC5zZXQobW9kdWxlRGVjbGFyYXRpb24sIGZteE1vZHVsZSk7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteE1vZHVsZSk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhNb2R1bGUsbW9kdWxlRGVjbGFyYXRpb24pO1xuICAgICAgICByZXR1cm4gZm14TW9kdWxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBhbGlhc1xuICAgICAqIEBwYXJhbSB0eXBlQWxpYXNEZWNsYXJhdGlvbiBBbiBhbGlhc1xuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgYWxpYXNcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhBbGlhcyh0eXBlQWxpYXNEZWNsYXJhdGlvbjogVHlwZUFsaWFzRGVjbGFyYXRpb24pOiBGYW1peC5BbGlhcyB7XG4gICAgICAgIGxldCBmbXhBbGlhczogRmFtaXguQWxpYXM7XG4gICAgICAgIGNvbnN0IGFsaWFzTmFtZSA9IHR5cGVBbGlhc0RlY2xhcmF0aW9uLmdldE5hbWUoKTtcbiAgICAgICAgLy9jb25zdCBhbGlhc0Z1bGx5UXVhbGlmaWVkTmFtZSA9IGEuZ2V0VHlwZSgpLmdldFRleHQoKTsgLy8gRlFORnVuY3Rpb25zLmdldEZRTihhKTtcbiAgICAgICAgY29uc3QgYWxpYXNGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKHR5cGVBbGlhc0RlY2xhcmF0aW9uKTtcbiAgICAgICAgY29uc3QgZm91bmRBbGlhcyA9IHRoaXMuZm14QWxpYXNNYXAuZ2V0KGFsaWFzRnVsbHlRdWFsaWZpZWROYW1lKTtcbiAgICAgICAgaWYgKCFmb3VuZEFsaWFzKSB7XG4gICAgICAgICAgICBmbXhBbGlhcyA9IG5ldyBGYW1peC5BbGlhcygpO1xuICAgICAgICAgICAgZm14QWxpYXMubmFtZSA9IHR5cGVBbGlhc0RlY2xhcmF0aW9uLmdldE5hbWUoKTtcbiAgICAgICAgICAgIGNvbnN0IGFsaWFzTmFtZVdpdGhHZW5lcmljcyA9IGFsaWFzTmFtZSArICh0eXBlQWxpYXNEZWNsYXJhdGlvbi5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA/IChcIjxcIiArIHR5cGVBbGlhc0RlY2xhcmF0aW9uLmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCIpIDogXCJcIik7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYD4gTk9URTogYWxpYXMgJHthbGlhc05hbWV9IGhhcyBmdWxseSBxdWFsaWZpZWQgbmFtZSAke2FsaWFzRnVsbHlRdWFsaWZpZWROYW1lfSBhbmQgbmFtZSB3aXRoIGdlbmVyaWNzICR7YWxpYXNOYW1lV2l0aEdlbmVyaWNzfS5gKTtcblxuICAgICAgICAgICAgY29uc3QgZm14VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoYWxpYXNOYW1lV2l0aEdlbmVyaWNzLCB0eXBlQWxpYXNEZWNsYXJhdGlvbi5nZXRUeXBlKCksIHR5cGVBbGlhc0RlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgIGZteEFsaWFzLmFsaWFzZWRFbnRpdHkgPSBmbXhUeXBlO1xuICAgICAgICAgICAgaW5pdEZRTih0eXBlQWxpYXNEZWNsYXJhdGlvbiwgZm14QWxpYXMpO1xuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IodHlwZUFsaWFzRGVjbGFyYXRpb24sIGZteEFsaWFzKTtcblxuICAgICAgICAgICAgdGhpcy5mbXhBbGlhc01hcC5zZXQoYWxpYXNGdWxseVF1YWxpZmllZE5hbWUsIGZteEFsaWFzKTtcblxuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEFsaWFzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZteEFsaWFzID0gZm91bmRBbGlhcztcbiAgICAgICAgfVxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEFsaWFzLHR5cGVBbGlhc0RlY2xhcmF0aW9uKTtcblxuICAgICAgICByZXR1cm4gZm14QWxpYXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggY2xhc3Mgb3IgcGFyYW1ldGVyaXphYmxlIGNsYXNzXG4gICAgICogQHBhcmFtIGNscyBBIGNsYXNzXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBjbGFzc1xuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4Q2xhc3MoY2xzOiBDbGFzc0RlY2xhcmF0aW9uKTogRmFtaXguQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljQ2xhc3Mge1xuICAgICAgICBsZXQgZm14Q2xhc3M6IEZhbWl4LkNsYXNzIHwgRmFtaXguUGFyYW1ldHJpY0NsYXNzO1xuICAgICAgICBjb25zdCBpc0Fic3RyYWN0ID0gY2xzLmlzQWJzdHJhY3QoKTtcbiAgICAgICAgY29uc3QgY2xhc3NGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGNscyk7XG4gICAgICAgIGNvbnN0IGNsc05hbWUgPSBjbHMuZ2V0TmFtZSgpIHx8IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgY29uc3QgaXNHZW5lcmljID0gY2xzLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoO1xuICAgICAgICBjb25zdCBmb3VuZENsYXNzID0gdGhpcy5mbXhDbGFzc01hcC5nZXQoY2xhc3NGdWxseVF1YWxpZmllZE5hbWUpO1xuICAgICAgICBpZiAoIWZvdW5kQ2xhc3MpIHtcbiAgICAgICAgICAgIGlmIChpc0dlbmVyaWMpIHtcbiAgICAgICAgICAgICAgICBmbXhDbGFzcyA9IG5ldyBGYW1peC5QYXJhbWV0cmljQ2xhc3MoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZteENsYXNzID0gbmV3IEZhbWl4LkNsYXNzKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZteENsYXNzLm5hbWUgPSBjbHNOYW1lO1xuICAgICAgICAgICAgaW5pdEZRTihjbHMsIGZteENsYXNzKTtcbiAgICAgICAgICAgIC8vIGZteENsYXNzLmZ1bGx5UXVhbGlmaWVkTmFtZSA9IGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lO1xuICAgICAgICAgICAgZm14Q2xhc3MuaXNBYnN0cmFjdCA9IGlzQWJzdHJhY3Q7XG5cbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGNscywgZm14Q2xhc3MpO1xuXG4gICAgICAgICAgICB0aGlzLmZteENsYXNzTWFwLnNldChjbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZSwgZm14Q2xhc3MpO1xuXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14Q2xhc3MpO1xuXG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteENsYXNzLGNscyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmbXhDbGFzcyA9IGZvdW5kQ2xhc3M7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZm14Q2xhc3M7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggaW50ZXJmYWNlIG9yIHBhcmFtZXRlcml6YWJsZSBpbnRlcmZhY2VcbiAgICAgKiBAcGFyYW0gaW50ZXIgQW4gaW50ZXJmYWNlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBpbnRlcmZhY2VcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlT3JHZXRGYW1peEludGVyZmFjZShpbnRlcjogSW50ZXJmYWNlRGVjbGFyYXRpb24pOiBGYW1peC5JbnRlcmZhY2UgfCBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlIHtcblxuICAgICAgICBsZXQgZm14SW50ZXJmYWNlOiBGYW1peC5JbnRlcmZhY2UgfCBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlO1xuICAgICAgICBjb25zdCBpbnRlck5hbWUgPSBpbnRlci5nZXROYW1lKCk7XG4gICAgICAgIGNvbnN0IGludGVyRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihpbnRlcik7XG4gICAgICAgIGNvbnN0IGZvdW5kSW50ZXJmYWNlID0gdGhpcy5mbXhJbnRlcmZhY2VNYXAuZ2V0KGludGVyRnVsbHlRdWFsaWZpZWROYW1lKTtcbiAgICAgICAgaWYgKCFmb3VuZEludGVyZmFjZSkge1xuICAgICAgICAgICAgY29uc3QgaXNHZW5lcmljID0gaW50ZXIuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGg7XG4gICAgICAgICAgICBpZiAoaXNHZW5lcmljKSB7XG4gICAgICAgICAgICAgICAgZm14SW50ZXJmYWNlID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZteEludGVyZmFjZSA9IG5ldyBGYW1peC5JbnRlcmZhY2UoKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm14SW50ZXJmYWNlLm5hbWUgPSBpbnRlck5hbWU7XG4gICAgICAgICAgICBpbml0RlFOKGludGVyLCBmbXhJbnRlcmZhY2UpO1xuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoaW50ZXIsIGZteEludGVyZmFjZSk7XG5cbiAgICAgICAgICAgIHRoaXMuZm14SW50ZXJmYWNlTWFwLnNldChpbnRlckZ1bGx5UXVhbGlmaWVkTmFtZSwgZm14SW50ZXJmYWNlKTtcblxuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEludGVyZmFjZSk7XG5cbiAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14SW50ZXJmYWNlLGludGVyKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZteEludGVyZmFjZSA9IGZvdW5kSW50ZXJmYWNlO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmbXhJbnRlcmZhY2U7XG4gICAgfVxuXG4gICAgXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggY29uY3JldGUgZWxlbWVudFxuICAgICAqIEBwYXJhbSBjb25jcmV0ZUVsZW1lbnQgQSBwYXJhbWV0cmljIEVsZW1lbnQgICBcbiAgICAgKiBAcGFyYW0gY29uY3JldGVFbGVtZW50RGVjbGFyYXRpb24gdGhlIGVsZW1lbnQgZGVjbGFyYXRpb25cbiAgICAgKiBAcGFyYW0gY29uY3JldGVBcmd1bWVudHMgY29uY3JldGUgYXJndW1lbnRzXG4gICAgICogQHJldHVybnMgQSBwYXJhbWV0cmljIEVsZW1lbnQgIFxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGNvbmNyZXRlRWxlbWVudCA6IFBhcmFtZXRyaWNWYXJpYW50VHlwZSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uY3JldGVFbGVtZW50RGVjbGFyYXRpb24gOiBDb25jcmV0ZUVsZW1lbnRUU01vcnBoVHlwZSwgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uY3JldGVBcmd1bWVudHM6IFR5cGVOb2RlW10pOiBQYXJhbWV0cmljVmFyaWFudFR5cGUge1xuICAgICAgICBcbiAgICAgICAgbGV0IGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUgPSBjb25jcmV0ZUVsZW1lbnQuZnVsbHlRdWFsaWZpZWROYW1lO1xuICAgICAgICBsZXQgcGFyYW1zID0gXCJcIjtcbiAgICAgICAgXG4gICAgICAgIGNvbmNyZXRlQXJndW1lbnRzLm1hcCgocGFyYW0pID0+IHtcbiAgICAgICAgICAgIHBhcmFtcyA9IHBhcmFtcytwYXJhbS5nZXRUZXh0KCkrJywnO1xuICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgIHBhcmFtcyA9IHBhcmFtcy5zdWJzdHJpbmcoMCwgcGFyYW1zLmxlbmd0aCAtIDEpO1xuICAgICAgICAgICAgICAgIFxuICAgICAgICBmdWxseVF1YWxpZmllZEZpbGVuYW1lID0gSGVscGVycy5yZXBsYWNlTGFzdEJldHdlZW5UYWdzKGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUscGFyYW1zKTtcblxuICAgICAgICBsZXQgY29uY0VsZW1lbnQ6IFBhcmFtZXRyaWNWYXJpYW50VHlwZTtcblxuICAgICAgICBpZiAoIXRoaXMuZm14SW50ZXJmYWNlTWFwLmhhcyhmdWxseVF1YWxpZmllZEZpbGVuYW1lKSAmJiBcbiAgICAgICAgICAgICF0aGlzLmZteENsYXNzTWFwLmhhcyhmdWxseVF1YWxpZmllZEZpbGVuYW1lKSAmJiBcbiAgICAgICAgICAgICF0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmhhcyhmdWxseVF1YWxpZmllZEZpbGVuYW1lKSl7XG4gICAgICAgICAgICBjb25jRWxlbWVudCA9IF8uY2xvbmVEZWVwKGNvbmNyZXRlRWxlbWVudCk7IFxuICAgICAgICAgICAgY29uY0VsZW1lbnQuZnVsbHlRdWFsaWZpZWROYW1lID0gZnVsbHlRdWFsaWZpZWRGaWxlbmFtZTtcbiAgICAgICAgICAgIGNvbmNFbGVtZW50LmNsZWFyR2VuZXJpY1BhcmFtZXRlcnMoKTtcbiAgICAgICAgICAgIGNvbmNyZXRlQXJndW1lbnRzLm1hcCgocGFyYW0pID0+IHtcbiAgICAgICAgICAgICAgICBpZiAocGFyYW0gaW5zdGFuY2VvZiBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcGFyYW1ldGVyID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShwYXJhbS5nZXRUZXh0KCkscGFyYW0uZ2V0VHlwZSgpLCBwYXJhbSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbmNFbGVtZW50LmFkZENvbmNyZXRlUGFyYW1ldGVyKHBhcmFtZXRlcik7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLndhcm4oYD4gV0FSTklORzogY29uY3JldGUgYXJndW1lbnQgJHtwYXJhbS5nZXRUZXh0KCl9IGlzIG5vdCBhIFR5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbi4gSXQgaXMgYSAke3BhcmFtLmdldEtpbmROYW1lKCl9LmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICBpZiAoY29uY3JldGVFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0NsYXNzKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mbXhDbGFzc01hcC5zZXQoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSwgY29uY0VsZW1lbnQgYXMgRmFtaXguUGFyYW1ldHJpY0NsYXNzKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29uY3JldGVFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZm14SW50ZXJmYWNlTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29uY3JldGVFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5zZXQoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSwgY29uY0VsZW1lbnQgYXMgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uKTtcbiAgICAgICAgICAgIH0gZWxzZSB7IC8vIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljTWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5zZXQoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSwgY29uY0VsZW1lbnQgYXMgRmFtaXguUGFyYW1ldHJpY01ldGhvZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoY29uY0VsZW1lbnQpO1xuICAgICAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChjb25jRWxlbWVudCxjb25jcmV0ZUVsZW1lbnREZWNsYXJhdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBpZiAoY29uY3JldGVFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0NsYXNzKSB7XG4gICAgICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmZteENsYXNzTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKSBhcyBGYW1peC5QYXJhbWV0cmljQ2xhc3M7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbmNyZXRlRWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UpIHtcbiAgICAgICAgICAgICAgICBjb25jRWxlbWVudCA9IHRoaXMuZm14SW50ZXJmYWNlTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKSBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24pIHtcbiAgICAgICAgICAgICAgICBjb25jRWxlbWVudCA9IHRoaXMuZm14RnVuY3Rpb25BbmRNZXRob2RNYXAuZ2V0KGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpIGFzIEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbjtcbiAgICAgICAgICAgIH0gZWxzZSB7ICAvLyBpZiAoY29uY3JldGVFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY01ldGhvZCkge1xuICAgICAgICAgICAgICAgIGNvbmNFbGVtZW50ID0gdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5nZXQoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSkgYXMgRmFtaXguUGFyYW1ldHJpY01ldGhvZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29uY0VsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IHByb3BlcnR5XG4gICAgICogQHBhcmFtIHByb3BlcnR5IEEgcHJvcGVydHlcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHByb3BlcnR5XG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4UHJvcGVydHkocHJvcGVydHk6IFByb3BlcnR5RGVjbGFyYXRpb24gfCBQcm9wZXJ0eVNpZ25hdHVyZSk6IEZhbWl4LlByb3BlcnR5IHtcbiAgICAgICAgY29uc3QgZm14UHJvcGVydHkgPSBuZXcgRmFtaXguUHJvcGVydHkoKTtcbiAgICAgICAgY29uc3QgaXNTaWduYXR1cmUgPSBwcm9wZXJ0eSBpbnN0YW5jZW9mIFByb3BlcnR5U2lnbmF0dXJlO1xuICAgICAgICBmbXhQcm9wZXJ0eS5uYW1lID0gcHJvcGVydHkuZ2V0TmFtZSgpO1xuXG4gICAgICAgIGxldCBwcm9wVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwcm9wVHlwZU5hbWUgPSBwcm9wZXJ0eS5nZXRUeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciBwcm9wZXJ0eTogJHtwcm9wZXJ0eS5nZXROYW1lKCl9LiBDb250aW51aW5nLi4uYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmbXhUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShwcm9wVHlwZU5hbWUsIHByb3BlcnR5LmdldFR5cGUoKSwgcHJvcGVydHkpO1xuICAgICAgICBmbXhQcm9wZXJ0eS5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xuXG4gICAgICAgIC8vIGFkZCB0aGUgdmlzaWJpbGl0eSAocHVibGljLCBwcml2YXRlLCBldGMuKSB0byB0aGUgZm14UHJvcGVydHlcbiAgICAgICAgZm14UHJvcGVydHkudmlzaWJpbGl0eSA9IFwiXCI7XG5cbiAgICAgICAgcHJvcGVydHkuZ2V0TW9kaWZpZXJzKCkuZm9yRWFjaChtID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAobS5nZXRUZXh0KCkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFNjb3BlLlB1YmxpYzpcbiAgICAgICAgICAgICAgICAgICAgZm14UHJvcGVydHkudmlzaWJpbGl0eSA9IFwicHVibGljXCI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgU2NvcGUuUHJvdGVjdGVkOlxuICAgICAgICAgICAgICAgICAgICBmbXhQcm9wZXJ0eS52aXNpYmlsaXR5ID0gXCJwcm90ZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBTY29wZS5Qcml2YXRlOlxuICAgICAgICAgICAgICAgICAgICBmbXhQcm9wZXJ0eS52aXNpYmlsaXR5ID0gXCJwcml2YXRlXCI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzdGF0aWNcIjpcbiAgICAgICAgICAgICAgICAgICAgZm14UHJvcGVydHkuaXNDbGFzc1NpZGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwicmVhZG9ubHlcIjpcbiAgICAgICAgICAgICAgICAgICAgZm14UHJvcGVydHkucmVhZE9ubHkgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFpc1NpZ25hdHVyZSAmJiBwcm9wZXJ0eS5nZXRFeGNsYW1hdGlvblRva2VuTm9kZSgpKSB7XG4gICAgICAgICAgICBmbXhQcm9wZXJ0eS5pc0RlZmluaXRlbHlBc3NpZ25lZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BlcnR5LmdldFF1ZXN0aW9uVG9rZW5Ob2RlKCkpIHtcbiAgICAgICAgICAgIGZteFByb3BlcnR5LmlzT3B0aW9uYWwgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wZXJ0eS5nZXROYW1lKCkuc3Vic3RyaW5nKDAsIDEpID09PSBcIiNcIikge1xuICAgICAgICAgICAgZm14UHJvcGVydHkuaXNKYXZhU2NyaXB0UHJpdmF0ZSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpbml0RlFOKHByb3BlcnR5LCBmbXhQcm9wZXJ0eSk7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKHByb3BlcnR5LCBmbXhQcm9wZXJ0eSk7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFByb3BlcnR5KTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteFByb3BlcnR5LHByb3BlcnR5KTtcblxuICAgICAgICByZXR1cm4gZm14UHJvcGVydHk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IG1ldGhvZCBvciBhY2Nlc3NvclxuICAgICAqIEBwYXJhbSBtZXRob2QgQSBtZXRob2Qgb3IgYW4gYWNjZXNzb3JcbiAgICAgKiBAcGFyYW0gY3VycmVudENDIFRoZSBjeWNsb21hdGljIGNvbXBsZXhpdHkgbWV0cmljcyBvZiB0aGUgY3VycmVudCBzb3VyY2UgZmlsZVxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgbWV0aG9kIG9yIHRoZSBhY2Nlc3NvclxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4TWV0aG9kKFxuICAgICAgICBtZXRob2Q6IE1ldGhvZERlY2xhcmF0aW9uIHwgQ29uc3RydWN0b3JEZWNsYXJhdGlvbiB8IE1ldGhvZFNpZ25hdHVyZSB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uLFxuICAgICAgICBjdXJyZW50Q0M6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH1cbiAgICApOiBGYW1peC5NZXRob2QgfCBGYW1peC5BY2Nlc3NvciB8IEZhbWl4LlBhcmFtZXRyaWNNZXRob2QgeyBcbiAgICAgICAgLy8gY29uc29sZS5sb2coYFxcbj09PSBDcmVhdGluZy9HZXR0aW5nIE1ldGhvZCA9PT1gKTtcbiAgICAgICAgLy8gY29uc29sZS5sb2coYE1ldGhvZCBraW5kOiAke21ldGhvZC5nZXRLaW5kTmFtZSgpfWApO1xuICAgICAgICAvLyBjb25zb2xlLmxvZyhgTWV0aG9kIHRleHQ6ICR7bWV0aG9kLmdldFRleHQoKS5zbGljZSgwLCA1MCl9Li4uYCk7XG4gICAgICAgIGNvbnN0IGZxbiA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4obWV0aG9kKTtcbiAgICAgICAgLy8gY29uc29sZS5sb2coYE1ldGhvZCBGUU46ICR7ZnFufWApO1xuICAgICAgICBsb2dnZXIuZGVidWcoYFByb2Nlc3NpbmcgbWV0aG9kICR7ZnFufWApO1xuICAgICAgIFxuICAgIFxuICAgICAgICBsZXQgZm14TWV0aG9kID0gdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5nZXQoZnFuKSBhcyBGYW1peC5NZXRob2QgfCBGYW1peC5BY2Nlc3NvciB8IEZhbWl4LlBhcmFtZXRyaWNNZXRob2Q7XG4gICAgICAgIGlmICghZm14TWV0aG9kKSB7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnTWV0aG9kIG5vdCBmb3VuZCBpbiBtYXAsIGNyZWF0aW5nIG5ldycpO1xuICAgICAgICAgICAgY29uc3QgaXNHZW5lcmljID0gbWV0aG9kLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgICAgIGlmIChtZXRob2QgaW5zdGFuY2VvZiBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIFNldEFjY2Vzc29yRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgICAgICBmbXhNZXRob2QgPSBuZXcgRmFtaXguQWNjZXNzb3IoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBpc0dldHRlciA9IG1ldGhvZCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgY29uc3QgaXNTZXR0ZXIgPSBtZXRob2QgaW5zdGFuY2VvZiBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uO1xuICAgICAgICAgICAgICAgIGlmIChpc0dldHRlcikgeyAoZm14TWV0aG9kIGFzIEZhbWl4LkFjY2Vzc29yKS5raW5kID0gXCJnZXR0ZXJcIjsgfVxuICAgICAgICAgICAgICAgIGlmIChpc1NldHRlcikgeyAoZm14TWV0aG9kIGFzIEZhbWl4LkFjY2Vzc29yKS5raW5kID0gXCJzZXR0ZXJcIjsgfVxuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhNZXRob2QgPSBpc0dlbmVyaWMgPyBuZXcgRmFtaXguUGFyYW1ldHJpY01ldGhvZCgpIDogbmV3IEZhbWl4Lk1ldGhvZCgpO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgY29uc3QgaXNDb25zdHJ1Y3RvciA9IG1ldGhvZCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yRGVjbGFyYXRpb247XG4gICAgICAgICAgICBjb25zdCBpc1NpZ25hdHVyZSA9IG1ldGhvZCBpbnN0YW5jZW9mIE1ldGhvZFNpZ25hdHVyZTtcbiAgICAgICAgICAgIGxldCBpc0Fic3RyYWN0ID0gZmFsc2U7XG4gICAgICAgICAgICBsZXQgaXNTdGF0aWMgPSBmYWxzZTtcbiAgICAgICAgICAgIGlmIChtZXRob2QgaW5zdGFuY2VvZiBNZXRob2REZWNsYXJhdGlvbiB8fCBtZXRob2QgaW5zdGFuY2VvZiBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIFNldEFjY2Vzc29yRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgICAgICBpc0Fic3RyYWN0ID0gbWV0aG9kLmlzQWJzdHJhY3QoKTtcbiAgICAgICAgICAgICAgICBpc1N0YXRpYyA9IG1ldGhvZC5pc1N0YXRpYygpO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgaWYgKGlzQ29uc3RydWN0b3IpIHsgKGZteE1ldGhvZCBhcyBGYW1peC5BY2Nlc3Nvcikua2luZCA9IFwiY29uc3RydWN0b3JcIjsgfVxuICAgICAgICAgICAgZm14TWV0aG9kLmlzQWJzdHJhY3QgPSBpc0Fic3RyYWN0O1xuICAgICAgICAgICAgZm14TWV0aG9kLmlzQ2xhc3NTaWRlID0gaXNTdGF0aWM7XG4gICAgICAgICAgICBmbXhNZXRob2QuaXNQcml2YXRlID0gKG1ldGhvZCBpbnN0YW5jZW9mIE1ldGhvZERlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbilcbiAgICAgICAgICAgICAgICA/ICEhbWV0aG9kLmdldE1vZGlmaWVycygpLmZpbmQoeCA9PiB4LmdldFRleHQoKSA9PT0gJ3ByaXZhdGUnKSA6IGZhbHNlO1xuICAgICAgICAgICAgZm14TWV0aG9kLmlzUHJvdGVjdGVkID0gKG1ldGhvZCBpbnN0YW5jZW9mIE1ldGhvZERlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbilcbiAgICAgICAgICAgICAgICA/ICEhbWV0aG9kLmdldE1vZGlmaWVycygpLmZpbmQoeCA9PiB4LmdldFRleHQoKSA9PT0gJ3Byb3RlY3RlZCcpIDogZmFsc2U7XG4gICAgICAgICAgICBmbXhNZXRob2Quc2lnbmF0dXJlID0gSGVscGVycy5jb21wdXRlU2lnbmF0dXJlKG1ldGhvZC5nZXRUZXh0KCkpO1xuICAgIFxuICAgICAgICAgICAgY29uc3QgbWV0aG9kTmFtZSA9IGlzQ29uc3RydWN0b3IgPyBcImNvbnN0cnVjdG9yXCIgOiBtZXRob2QuZ2V0TmFtZSgpO1xuICAgICAgICAgICAgZm14TWV0aG9kLm5hbWUgPSBtZXRob2ROYW1lO1xuICAgIFxuICAgICAgICAgICAgaWYgKCFpc0NvbnN0cnVjdG9yICYmIG1ldGhvZE5hbWUuc3RhcnRzV2l0aChcIiNcIikpIHtcbiAgICAgICAgICAgICAgICBmbXhNZXRob2QuaXNQcml2YXRlID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZteE1ldGhvZC5pc1B1YmxpYyA9ICFmbXhNZXRob2QuaXNQcml2YXRlICYmICFmbXhNZXRob2QuaXNQcm90ZWN0ZWQ7XG4gICAgXG4gICAgICAgICAgICBmbXhNZXRob2QuY3ljbG9tYXRpY0NvbXBsZXhpdHkgPSBpc1NpZ25hdHVyZSA/IDAgOiAoY3VycmVudENDW21ldGhvZE5hbWVdIHx8IDApO1xuICAgICAgICAgICAgbGV0IG1ldGhvZFR5cGVOYW1lID0gdGhpcy5VTktOT1dOX1ZBTFVFO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtZXRob2RUeXBlTmFtZSA9IG1ldGhvZC5nZXRSZXR1cm5UeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYE1ldGhvZCByZXR1cm4gdHlwZTogJHttZXRob2RUeXBlTmFtZX1gKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBGYWlsZWQgdG8gZ2V0IHJldHVybiB0eXBlIGZvciAke2Zxbn06ICR7ZXJyb3J9YCk7XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICBjb25zdCBmbXhUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShtZXRob2RUeXBlTmFtZSwgbWV0aG9kLmdldFR5cGUoKSwgbWV0aG9kKTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBDcmVhdGVkL3JldHJpZXZlZCByZXR1cm4gdHlwZSB3aXRoIEZRTjogJHtmbXhUeXBlLmZ1bGx5UXVhbGlmaWVkTmFtZX1gKTtcbiAgICAgICAgICAgIGZteE1ldGhvZC5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xuICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mTGluZXNPZkNvZGUgPSBtZXRob2QuZ2V0RW5kTGluZU51bWJlcigpIC0gbWV0aG9kLmdldFN0YXJ0TGluZU51bWJlcigpO1xuICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mUGFyYW1ldGVycyA9IG1ldGhvZC5nZXRQYXJhbWV0ZXJzKCkubGVuZ3RoO1xuICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mU3RhdGVtZW50cyA9IGlzU2lnbmF0dXJlID8gMCA6IG1ldGhvZC5nZXRTdGF0ZW1lbnRzKCkubGVuZ3RoO1xuICAgIFxuICAgICAgICAgICAgLy8gQWRkIHRvIGZhbWl4UmVwXG4gICAgICAgICAgICBpbml0RlFOKG1ldGhvZCwgZm14TWV0aG9kKTtcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhNZXRob2QpO1xuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IobWV0aG9kLCBmbXhNZXRob2QpO1xuICAgICAgICAgICAgdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5zZXQoZnFuLCBmbXhNZXRob2QpO1xuICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBBZGRlZCBtZXRob2QgJHtmcW59IHRvIGZhbWl4UmVwYCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYE1ldGhvZCAke2Zxbn0gYWxyZWFkeSBleGlzdHNgKTtcbiAgICAgICAgfVxuICAgIFxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteE1ldGhvZCwgbWV0aG9kKTtcbiAgICAgICAgcmV0dXJuIGZteE1ldGhvZDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gZnVuYyBBIGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIGN1cnJlbnRDQyBUaGUgY3ljbG9tYXRpYyBjb21wbGV4aXR5IG1ldHJpY3Mgb2YgdGhlIGN1cnJlbnQgc291cmNlIGZpbGVcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhGdW5jdGlvbihmdW5jOiBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgRnVuY3Rpb25FeHByZXNzaW9uLCBjdXJyZW50Q0M6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0pOiBGYW1peC5GdW5jdGlvbiB8IEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbiB7XG4gICAgICAgIGxldCBmbXhGdW5jdGlvbjogRmFtaXguRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb247XG4gICAgICAgIGNvbnN0IGlzR2VuZXJpYyA9IGZ1bmMuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwO1xuICAgICAgICBjb25zdCBmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oZnVuYyk7XG4gICAgICAgIGlmICghdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5oYXMoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpKSB7XG4gICAgICAgICAgICBpZiAoaXNHZW5lcmljKSB7XG4gICAgICAgICAgICAgICAgZm14RnVuY3Rpb24gPSBuZXcgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhGdW5jdGlvbiA9IG5ldyBGYW1peC5GdW5jdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgY29uc3QgbmFtZSA9IGZ1bmMuZ2V0TmFtZSgpO1xuICAgICAgICAgICAgaWYgKG5hbWUpIHtcbiAgICAgICAgICAgICAgICBmbXhGdW5jdGlvbi5uYW1lID0gbmFtZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZteEZ1bmN0aW9uLm5hbWUgPSBcImFub255bW91c1wiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5zaWduYXR1cmUgPSBIZWxwZXJzLmNvbXB1dGVTaWduYXR1cmUoZnVuYy5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgZm14RnVuY3Rpb24uY3ljbG9tYXRpY0NvbXBsZXhpdHkgPSBjdXJyZW50Q0NbZm14RnVuY3Rpb24ubmFtZV07XG4gICAgICAgICAgICBpbml0RlFOKGZ1bmMsIGZteEZ1bmN0aW9uKTtcbiAgICAgICAgICAgIC8vIGZteEZ1bmN0aW9uLmZ1bGx5UXVhbGlmaWVkTmFtZSA9IGZ1bmN0aW9uRnVsbHlRdWFsaWZpZWROYW1lO1xuICAgIFxuICAgICAgICAgICAgbGV0IGZ1bmN0aW9uVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uVHlwZU5hbWUgPSBmdW5jLmdldFJldHVyblR5cGUoKS5nZXRUZXh0KCkudHJpbSgpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYD4gV0FSTklORzogZ290IGV4Y2VwdGlvbiAke2Vycm9yfS4gRmFpbGVkIHRvIGdldCB1c2FibGUgbmFtZSBmb3IgcmV0dXJuIHR5cGUgb2YgZnVuY3Rpb246ICR7ZnVuYy5nZXROYW1lKCl9LiBDb250aW51aW5nLi4uYCk7XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICBjb25zdCBmbXhUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShmdW5jdGlvblR5cGVOYW1lLCBmdW5jLmdldFR5cGUoKSwgZnVuYyk7XG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xuICAgICAgICAgICAgZm14RnVuY3Rpb24ubnVtYmVyT2ZMaW5lc09mQ29kZSA9IGZ1bmMuZ2V0RW5kTGluZU51bWJlcigpIC0gZnVuYy5nZXRTdGFydExpbmVOdW1iZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBmdW5jLmdldFBhcmFtZXRlcnMoKTtcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLm51bWJlck9mUGFyYW1ldGVycyA9IHBhcmFtZXRlcnMubGVuZ3RoO1xuICAgICAgICAgICAgZm14RnVuY3Rpb24ubnVtYmVyT2ZTdGF0ZW1lbnRzID0gZnVuYy5nZXRTdGF0ZW1lbnRzKCkubGVuZ3RoO1xuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoZnVuYywgZm14RnVuY3Rpb24pO1xuICAgIFxuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEZ1bmN0aW9uKTtcbiAgICBcbiAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14RnVuY3Rpb24sZnVuYyk7XG5cbiAgICAgICAgICAgIHRoaXMuZm14RnVuY3Rpb25BbmRNZXRob2RNYXAuc2V0KGZ1bmN0aW9uRnVsbHlRdWFsaWZpZWROYW1lLCBmbXhGdW5jdGlvbik7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmbXhGdW5jdGlvbiA9IHRoaXMuZm14RnVuY3Rpb25BbmRNZXRob2RNYXAuZ2V0KGZ1bmN0aW9uRnVsbHlRdWFsaWZpZWROYW1lKSBhcyAoRmFtaXguRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZteEZ1bmN0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBwYXJhbWV0ZXJcbiAgICAgKiBAcGFyYW0gcGFyYW0gQSBwYXJhbWV0ZXJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHBhcmFtZXRlclxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4UGFyYW1ldGVyKHBhcmFtOiBQYXJhbWV0ZXJEZWNsYXJhdGlvbik6IEZhbWl4LlBhcmFtZXRlciB7XG4gICAgICAgIGlmICh0aGlzLmZteFBhcmFtZXRlck1hcC5oYXMocGFyYW0pKSB7XG4gICAgICAgICAgICBjb25zdCByUGFyYW1ldGVyID0gdGhpcy5mbXhQYXJhbWV0ZXJNYXAuZ2V0KHBhcmFtKTtcbiAgICAgICAgICAgIGlmIChyUGFyYW1ldGVyKSB7IFxuICAgICAgICAgICAgICAgcmV0dXJuIHJQYXJhbWV0ZXI7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggcGFyYW1ldGVyICR7cGFyYW0uZ2V0TmFtZSgpfSBpcyBub3QgZm91bmQgaW4gdGhlIHBhcmFtZXRlciBtYXAuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmbXhQYXJhbSA9IG5ldyBGYW1peC5QYXJhbWV0ZXIoKTtcblxuICAgICAgICBsZXQgcGFyYW1UeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHBhcmFtVHlwZU5hbWUgPSBwYXJhbS5nZXRUeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciBwYXJhbWV0ZXI6ICR7cGFyYW0uZ2V0TmFtZSgpfS4gQ29udGludWluZy4uLmApO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZm14VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUocGFyYW1UeXBlTmFtZSwgcGFyYW0uZ2V0VHlwZSgpLCBwYXJhbSk7XG4gICAgICAgIGZteFBhcmFtLmRlY2xhcmVkVHlwZSA9IGZteFR5cGU7XG4gICAgICAgIGZteFBhcmFtLm5hbWUgPSBwYXJhbS5nZXROYW1lKCk7XG5cbiAgICAgICAgaW5pdEZRTihwYXJhbSwgZm14UGFyYW0pO1xuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihwYXJhbSwgZm14UGFyYW0pO1xuXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhQYXJhbSk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhQYXJhbSwgcGFyYW0pO1xuICAgICAgICB0aGlzLmZteFBhcmFtZXRlck1hcC5zZXQocGFyYW0sIGZteFBhcmFtKTtcblxuICAgICAgICByZXR1cm4gZm14UGFyYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IHR5cGUgcGFyYW1ldGVyXG4gICAgICogQHBhcmFtIHRwIEEgdHlwZSBwYXJhbWV0ZXJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHR5cGUgcGFyYW1ldGVyXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4UGFyYW1ldGVyVHlwZSh0cDogVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uKTogRmFtaXguUGFyYW1ldGVyVHlwZSB7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBmbXhQYXJhbWV0ZXJUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRlclR5cGUoKTtcbiAgIFxuICAgICAgICBmbXhQYXJhbWV0ZXJUeXBlLm5hbWUgPSB0cC5nZXROYW1lKCk7ICAgICAgXG4gICAgICAgIGluaXRGUU4odHAsIGZteFBhcmFtZXRlclR5cGUpO1xuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcih0cCwgZm14UGFyYW1ldGVyVHlwZSk7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFBhcmFtZXRlclR5cGUpO1xuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14UGFyYW1ldGVyVHlwZSx0cCk7XG5cbiAgICAgICAgcmV0dXJuIGZteFBhcmFtZXRlclR5cGU7XG4gICAgfVxuXG5cbiAgICAvLyAvKipcbiAgICAvLyAgKiBDcmVhdGVzIGEgRmFtaXggdHlwZSBpbiB0aGUgY29udGV4dCBvZiBjb25jcmV0aXphdGlvbnNcbiAgICAvLyAgKiBAcGFyYW0gdHlwZU5hbWUgQSB0eXBlIG5hbWVcbiAgICAvLyAgKiBAcGFyYW0gZWxlbWVudCBBbiBlbGVtZW50XG4gICAgLy8gICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSB0eXBlXG4gICAgLy8gICovXG4gICAgLy8gcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhDb25jcmV0ZVR5cGUoZWxlbWVudDogVHlwZU5vZGUpOiBcbiAgICAvLyAgICAgRmFtaXguUGFyYW1ldGVyVHlwZSB8IEZhbWl4LlByaW1pdGl2ZVR5cGUgfCBGYW1peC5DbGFzcyB8IEZhbWl4LkludGVyZmFjZSB7XG4gICAgLy8gICAgICAgICBpZiAodGhpcy5mbXhUeXBlTWFwLmhhcyhlbGVtZW50KSkge1xuICAgIC8vICAgICAgICAgICAgIGNvbnN0IHJUeXBlID0gdGhpcy5mbXhUeXBlTWFwLmdldChlbGVtZW50KTtcbiAgICAvLyAgICAgICAgICAgICBpZiAoclR5cGUpIHsgXG4gICAgLy8gICAgICAgICAgICAgICAgcmV0dXJuIHJUeXBlO1xuICAgIC8vICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgLy8gICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggdHlwZSAke2VsZW1lbnQuZ2V0VGV4dCgpfSBpcyBub3QgZm91bmQgaW4gdGhlIHR5cGUgbWFwLmApO1xuICAgIC8vICAgICAgICAgICAgIH1cbiAgICAvLyAgICAgICAgIH1cblxuICAgIC8vICAgICBjb25zdCB0eXBlUGFyYW1ldGVyRGVjbGFyYXRpb24gPSBlbGVtZW50LmdldFN5bWJvbCgpPy5nZXREZWNsYXJhdGlvbnMoKVswXSBhcyBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb247XG4gICAgLy8gICAgIC8vIGNvbnN0IHBhcmFtZXRlclR5cGVOYW1lIDogc3RyaW5nID0gZWxlbWVudC5nZXRUZXh0KCk7XG4gICAgLy8gICAgIGNvbnN0IHBhcmFtZXRlclR5cGVOYW1lID0gZ2V0UHJpbWl0aXZlVHlwZU5hbWUoZWxlbWVudC5nZXRUeXBlKCkpIHx8IGVsZW1lbnQuZ2V0VGV4dCgpO1xuICAgIC8vICAgICBsZXQgZm14UGFyYW1ldGVyVHlwZTogRmFtaXguVHlwZSB8IEZhbWl4LkNsYXNzIHwgRmFtaXguSW50ZXJmYWNlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgLy8gICAgIC8vIGdldCBhIFR5cGVSZWZlcmVuY2UgZnJvbSBhIFR5cGVOb2RlXG4gICAgLy8gICAgIGNvbnN0IHR5cGVSZWZlcmVuY2UgPSBlbGVtZW50LmdldFR5cGUoKTtcbiAgICAvLyAgICAgLy8gZ2V0IGEgVHlwZURlY2xhcmF0aW9uIGZyb20gYSBUeXBlUmVmZXJlbmNlXG4gICAgLy8gICAgIGNvbnN0IHR5cGVEZWNsYXJhdGlvbiA9IHR5cGVSZWZlcmVuY2UuZ2V0U3ltYm9sKCk/LmdldERlY2xhcmF0aW9ucygpWzBdIGFzIFRTTW9ycGhUeXBlRGVjbGFyYXRpb247XG5cbiAgICAvLyAgICAgbGV0IGlzQ2xhc3NPckludGVyZmFjZSA9IGZhbHNlO1xuICAgIC8vICAgICBpZiAodGhpcy5mbXhDbGFzc01hcC5oYXMocGFyYW1ldGVyVHlwZU5hbWUpKXtcbiAgICAvLyAgICAgICAgIHRoaXMuZm14Q2xhc3NNYXAuZm9yRWFjaCgob2JqLCBuYW1lKSA9PiB7XG4gICAgLy8gICAgICAgICAgICAgaWYob2JqIGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0NsYXNzKXtcbiAgICAvLyAgICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IGVsZW1lbnQuZ2V0VGV4dCgpICYmIG9iai5nZW5lcmljUGFyYW1ldGVycy5zaXplPjApIHtcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XG4gICAgLy8gICAgICAgICAgICAgICAgICAgICBpc0NsYXNzT3JJbnRlcmZhY2UgPSB0cnVlO1xuICAgIC8vICAgICAgICAgICAgICAgICB9IFxuICAgIC8vICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgLy8gICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBlbGVtZW50LmdldFRleHQoKSkge1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZSA9IG9iajtcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGlzQ2xhc3NPckludGVyZmFjZSA9IHRydWU7XG4gICAgLy8gICAgICAgICAgICAgICAgIH0gXG4gICAgLy8gICAgICAgICAgICAgfSAgIFxuICAgIC8vICAgICAgICAgfSk7XG4gICAgLy8gICAgIH1cblxuICAgIC8vICAgICBpZiAodGhpcy5mbXhJbnRlcmZhY2VNYXAuaGFzKHBhcmFtZXRlclR5cGVOYW1lKSl7XG4gICAgLy8gICAgICAgICB0aGlzLmZteEludGVyZmFjZU1hcC5mb3JFYWNoKChvYmosIG5hbWUpID0+IHtcbiAgICAvLyAgICAgICAgICAgICBpZihvYmogaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlKXtcbiAgICAvLyAgICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IGVsZW1lbnQuZ2V0VGV4dCgpICYmIG9iai5nZW5lcmljUGFyYW1ldGVycy5zaXplPjApIHtcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XG4gICAgLy8gICAgICAgICAgICAgICAgICAgICBpc0NsYXNzT3JJbnRlcmZhY2UgPSB0cnVlO1xuICAgIC8vICAgICAgICAgICAgICAgICB9IFxuICAgIC8vICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgLy8gICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBlbGVtZW50LmdldFRleHQoKSkge1xuICAgIC8vICAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZSA9IG9iajtcbiAgICAvLyAgICAgICAgICAgICAgICAgICAgIGlzQ2xhc3NPckludGVyZmFjZSA9IHRydWU7XG4gICAgLy8gICAgICAgICAgICAgICAgIH0gXG4gICAgLy8gICAgICAgICAgICAgfSAgIFxuICAgIC8vICAgICAgICAgfSk7XG4gICAgLy8gICAgIH1cblxuICAgIC8vICAgICBpZighaXNDbGFzc09ySW50ZXJmYWNlKXtcbiAgICAvLyAgICAgICAgIGlmICghdGhpcy5mbXhUeXBlTWFwLmhhcyh0eXBlRGVjbGFyYXRpb24pKSB7ICAgIFxuICAgIC8vICAgICAgICAgICAgIC8vIFRPRE8gcmVmYWN0b3IgXG4gICAgLy8gICAgICAgICAgICAgaWYgKGlzUHJpbWl0aXZlVHlwZShwYXJhbWV0ZXJUeXBlTmFtZSkpIHtcbiAgICAvLyAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFByaW1pdGl2ZVR5cGUocGFyYW1ldGVyVHlwZU5hbWUpO1xuICAgIC8vICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgLy8gICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBuZXcgRmFtaXguUGFyYW1ldGVyVHlwZSgpO1xuICAgIC8vICAgICAgICAgICAgIH0gXG4gICAgXG4gICAgLy8gICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZS5uYW1lID0gcGFyYW1ldGVyVHlwZU5hbWU7XG4gICAgLy8gICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFBhcmFtZXRlclR5cGUpO1xuICAgIC8vICAgICAgICAgICAgIHRoaXMuZm14VHlwZU1hcC5zZXQodHlwZURlY2xhcmF0aW9uLCBmbXhQYXJhbWV0ZXJUeXBlKTtcbiAgICAvLyAgICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteFBhcmFtZXRlclR5cGUsdHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uKTtcbiAgICAvLyAgICAgICAgIH1cbiAgICAvLyAgICAgICAgIGVsc2Uge1xuICAgIC8vICAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuZm14VHlwZU1hcC5nZXQodHlwZURlY2xhcmF0aW9uKTtcbiAgICAvLyAgICAgICAgICAgICBpZiAocmVzdWx0KSB7XG4gICAgLy8gICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSByZXN1bHQ7XG4gICAgLy8gICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAvLyAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBGYW1peCB0eXBlICR7dHlwZURlY2xhcmF0aW9ufSBpcyBub3QgZm91bmQgaW4gdGhlIFR5cGUgbWFwLmApO1xuICAgIC8vICAgICAgICAgICAgIH1cbiAgICAvLyAgICAgICAgIH1cbiAgICAvLyAgICAgfVxuICAgIC8vICAgICBpZiAoIWZteFBhcmFtZXRlclR5cGUpIHtcbiAgICAvLyAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZm14UGFyYW1ldGVyVHlwZSB3YXMgdW5kZWZpbmVkIGZvciBwYXJhbWV0ZXJUeXBlTmFtZSAke3BhcmFtZXRlclR5cGVOYW1lfWApO1xuICAgIC8vICAgICB9XG4gICAgLy8gICAgIHJldHVybiBmbXhQYXJhbWV0ZXJUeXBlO1xuICAgIC8vIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCB2YXJpYWJsZVxuICAgICAqIEBwYXJhbSB2YXJpYWJsZSBBIHZhcmlhYmxlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSB2YXJpYWJsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4VmFyaWFibGUodmFyaWFibGU6IFZhcmlhYmxlRGVjbGFyYXRpb24pOiBGYW1peC5WYXJpYWJsZSB7XG4gICAgICAgIGlmICh0aGlzLmZteFZhcmlhYmxlTWFwLmhhcyh2YXJpYWJsZSkpIHtcbiAgICAgICAgICAgIGNvbnN0IHJWYXJpYWJsZSA9IHRoaXMuZm14VmFyaWFibGVNYXAuZ2V0KHZhcmlhYmxlKTtcbiAgICAgICAgICAgIGlmIChyVmFyaWFibGUpIHsgXG4gICAgICAgICAgICAgICByZXR1cm4gclZhcmlhYmxlO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhbWl4IHBhcmFtZXRlciAke3ZhcmlhYmxlLmdldE5hbWUoKX0gaXMgbm90IGZvdW5kIGluIHRoZSB2YXJpYWJsZSBtYXAuYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZm14VmFyaWFibGUgPSBuZXcgRmFtaXguVmFyaWFibGUoKTtcbiAgICBcbiAgICAgICAgbGV0IHZhcmlhYmxlVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICB2YXJpYWJsZVR5cGVOYW1lID0gdmFyaWFibGUuZ2V0VHlwZSgpLmdldFRleHQoKS50cmltKCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYD4gV0FSTklORzogZ290IGV4Y2VwdGlvbiAke2Vycm9yfS4gRmFpbGVkIHRvIGdldCB1c2FibGUgbmFtZSBmb3IgdmFyaWFibGU6ICR7dmFyaWFibGUuZ2V0TmFtZSgpfS4gQ29udGludWluZy4uLmApO1xuICAgICAgICB9XG4gICAgXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKHZhcmlhYmxlVHlwZU5hbWUsIHZhcmlhYmxlLmdldFR5cGUoKSwgdmFyaWFibGUpO1xuICAgICAgICBmbXhWYXJpYWJsZS5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xuICAgICAgICBmbXhWYXJpYWJsZS5uYW1lID0gdmFyaWFibGUuZ2V0TmFtZSgpO1xuICAgICAgICBpbml0RlFOKHZhcmlhYmxlLCBmbXhWYXJpYWJsZSk7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKHZhcmlhYmxlLCBmbXhWYXJpYWJsZSk7XG4gICAgXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhWYXJpYWJsZSk7XG4gICAgXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14VmFyaWFibGUsdmFyaWFibGUpO1xuICAgICAgICB0aGlzLmZteFZhcmlhYmxlTWFwLnNldCh2YXJpYWJsZSwgZm14VmFyaWFibGUpO1xuICAgIFxuICAgICAgICByZXR1cm4gZm14VmFyaWFibGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGVudW1cbiAgICAgKiBAcGFyYW0gZW51bUVudGl0eSBBbiBlbnVtXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBlbnVtXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhFbnVtKGVudW1FbnRpdHk6IEVudW1EZWNsYXJhdGlvbik6IEZhbWl4LkVudW0ge1xuICAgICAgICBpZiAodGhpcy5mbXhFbnVtTWFwLmhhcyhlbnVtRW50aXR5KSkge1xuICAgICAgICAgICAgY29uc3QgckVudW0gPSB0aGlzLmZteEVudW1NYXAuZ2V0KGVudW1FbnRpdHkpO1xuICAgICAgICAgICAgaWYgKHJFbnVtKSB7IFxuICAgICAgICAgICAgICAgcmV0dXJuIHJFbnVtO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhbWl4IGVudW0gJHtlbnVtRW50aXR5LmdldE5hbWUoKX0gaXMgbm90IGZvdW5kIGluIHRoZSBlbnVtIG1hcC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmbXhFbnVtID0gbmV3IEZhbWl4LkVudW0oKTtcbiAgICAgICAgZm14RW51bS5uYW1lID0gZW51bUVudGl0eS5nZXROYW1lKCk7XG4gICAgICAgIGluaXRGUU4oZW51bUVudGl0eSwgZm14RW51bSk7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGVudW1FbnRpdHksIGZteEVudW0pO1xuXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhFbnVtKTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEVudW0sZW51bUVudGl0eSk7XG4gICAgICAgIHRoaXMuZm14RW51bU1hcC5zZXQoZW51bUVudGl0eSwgZm14RW51bSk7XG5cbiAgICAgICAgcmV0dXJuIGZteEVudW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGVudW0gdmFsdWVcbiAgICAgKiBAcGFyYW0gZW51bU1lbWJlciBBbiBlbnVtIG1lbWJlclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgZW51bSBtZW1iZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhFbnVtVmFsdWUoZW51bU1lbWJlcjogRW51bU1lbWJlcik6IEZhbWl4LkVudW1WYWx1ZSB7XG4gICAgICAgIGNvbnN0IGZteEVudW1WYWx1ZSA9IG5ldyBGYW1peC5FbnVtVmFsdWUoKTtcblxuICAgICAgICBsZXQgZW51bVZhbHVlVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBlbnVtVmFsdWVUeXBlTmFtZSA9IGVudW1NZW1iZXIuZ2V0VHlwZSgpLmdldFRleHQoKS50cmltKCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYD4gV0FSTklORzogZ290IGV4Y2VwdGlvbiAke2Vycm9yfS4gRmFpbGVkIHRvIGdldCB1c2FibGUgbmFtZSBmb3IgZW51bSB2YWx1ZTogJHtlbnVtTWVtYmVyLmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGVudW1WYWx1ZVR5cGVOYW1lLCBlbnVtTWVtYmVyLmdldFR5cGUoKSwgZW51bU1lbWJlcik7XG4gICAgICAgIGZteEVudW1WYWx1ZS5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xuICAgICAgICBmbXhFbnVtVmFsdWUubmFtZSA9IGVudW1NZW1iZXIuZ2V0TmFtZSgpO1xuICAgICAgICBpbml0RlFOKGVudW1NZW1iZXIsIGZteEVudW1WYWx1ZSk7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGVudW1NZW1iZXIsIGZteEVudW1WYWx1ZSk7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEVudW1WYWx1ZSk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhFbnVtVmFsdWUsZW51bU1lbWJlcik7XG5cbiAgICAgICAgcmV0dXJuIGZteEVudW1WYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBkZWNvcmF0b3JcbiAgICAgKiBAcGFyYW0gZGVjb3JhdG9yIEEgZGVjb3JhdG9yXG4gICAgICogQHBhcmFtIGRlY29yYXRlZEVudGl0eSBBIGNsYXNzLCBhIG1ldGhvZCwgYSBwYXJhbWV0ZXIgb3IgYSBwcm9wZXJ0eVxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgZGVjb3JhdG9yXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhEZWNvcmF0b3IoZGVjb3JhdG9yOiBEZWNvcmF0b3IsIGRlY29yYXRlZEVudGl0eTogQ2xhc3NEZWNsYXJhdGlvbiB8IE1ldGhvZERlY2xhcmF0aW9uIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IFByb3BlcnR5RGVjbGFyYXRpb24pOiBGYW1peC5EZWNvcmF0b3Ige1xuICAgICAgICBjb25zdCBmbXhEZWNvcmF0b3IgPSBuZXcgRmFtaXguRGVjb3JhdG9yKCk7XG4gICAgICAgIGNvbnN0IGRlY29yYXRvck5hbWUgPSBcIkBcIiArIGRlY29yYXRvci5nZXROYW1lKCk7XG4gICAgICAgIGNvbnN0IGRlY29yYXRvckV4cHJlc3Npb24gPSBkZWNvcmF0b3IuZ2V0VGV4dCgpLnN1YnN0cmluZygxKTtcblxuICAgICAgICBmbXhEZWNvcmF0b3IubmFtZSA9IGRlY29yYXRvck5hbWU7XG4gICAgICAgIGZteERlY29yYXRvci5kZWNvcmF0b3JFeHByZXNzaW9uID0gZGVjb3JhdG9yRXhwcmVzc2lvbjtcbiAgICAgICAgY29uc3QgZGVjb3JhdGVkRW50aXR5RnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihkZWNvcmF0ZWRFbnRpdHkpO1xuICAgICAgICBjb25zdCBmbXhEZWNvcmF0ZWRFbnRpdHkgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUoZGVjb3JhdGVkRW50aXR5RnVsbHlRdWFsaWZpZWROYW1lKSBhcyBGYW1peC5OYW1lZEVudGl0eTtcbiAgICAgICAgZm14RGVjb3JhdG9yLmRlY29yYXRlZEVudGl0eSA9IGZteERlY29yYXRlZEVudGl0eTtcbiAgICAgICAgaW5pdEZRTihkZWNvcmF0b3IsIGZteERlY29yYXRvcik7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGRlY29yYXRvciwgZm14RGVjb3JhdG9yKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14RGVjb3JhdG9yKTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteERlY29yYXRvcixkZWNvcmF0b3IpO1xuXG4gICAgICAgIHJldHVybiBmbXhEZWNvcmF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbW1lbnRcbiAgICAgKiBAcGFyYW0gY29tbWVudCBBIGNvbW1lbnRcbiAgICAgKiBAcGFyYW0gZm14U2NvcGUgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBjb21tZW50J3MgY29udGFpbmVyXG4gICAgICogQHBhcmFtIGlzSlNEb2MgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIGNvbW1lbnQgaXMgYSBKU0RvY1xuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgY29tbWVudFxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peENvbW1lbnQoY29tbWVudDogQ29tbWVudFJhbmdlLCBmbXhTY29wZTogRmFtaXguTmFtZWRFbnRpdHksIGlzSlNEb2M6IGJvb2xlYW4pOiBGYW1peC5Db21tZW50IHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGA+IE5PVEU6IGNyZWF0aW5nIGNvbW1lbnQgJHtjb21tZW50LmdldFRleHQoKX0gaW4gc2NvcGUgJHtmbXhTY29wZS5uYW1lfS5gKTtcbiAgICAgICAgY29uc3QgZm14Q29tbWVudCA9IG5ldyBGYW1peC5Db21tZW50KCk7XG4gICAgICAgIGZteENvbW1lbnQuY29udGFpbmVyID0gZm14U2NvcGU7ICAvLyBhZGRzIGNvbW1lbnQgdG8gdGhlIGNvbnRhaW5lcidzIGNvbW1lbnRzIGNvbGxlY3Rpb25cbiAgICAgICAgZm14Q29tbWVudC5pc0pTRG9jID0gaXNKU0RvYztcblxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihjb21tZW50LCBmbXhDb21tZW50KTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14Q29tbWVudCk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhDb21tZW50LGNvbW1lbnQpO1xuXG4gICAgICAgIHJldHVybiBmbXhDb21tZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgb3IgZ2V0cyBhIEZhbWl4IHR5cGVcbiAgICAgKiBAcGFyYW0gdHlwZU5hbWUgQSB0eXBlIG5hbWVcbiAgICAgKiBAcGFyYW0gZWxlbWVudCBBIHRzLW1vcnBoIGVsZW1lbnRcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHR5cGVcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlT3JHZXRGYW1peFR5cGUodHlwZU5hbWVBcmc6IHN0cmluZywgdHNNb3JwaFR5cGU6IFR5cGUgfCB1bmRlZmluZWQsIGVsZW1lbnQ6IFRTTW9ycGhUeXBlRGVjbGFyYXRpb24pOiBGYW1peC5UeXBlIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyAob3IgZ2V0dGluZykgdHlwZTogJyR7dHNNb3JwaFR5cGU/LmdldFRleHQoKSB8fCBcInVuZGVmaW5lZFwifScgb2YgZWxlbWVudDogJyR7ZWxlbWVudD8uZ2V0VGV4dCgpLnNsaWNlKDAsIDUwKX0uLi4nIG9mIGtpbmQ6ICR7ZWxlbWVudD8uZ2V0S2luZE5hbWUoKX1gKTtcblxuICAgICAgICAvLyBjb252ZXJ0IHR5cGUgdG8gY29ycmVjdCBwcmltaXRpdmUgbmFtZSAod29ya2Fyb3VuZCBmb3IgdW5pcXVlIHN5bWJvbGUgcHJpbWl0aXZlIHR5cGUpXG4gICAgICAgIC8vIGRvbid0IGNvbnZlcnQgdG8gcHJpbWl0aXZlIGlmIGl0J3MgYSBnZW5lcmljIHR5cGVcbiAgICAgICAgY29uc3QgdHlwZU5hbWUgPSAhdHlwZU5hbWVBcmcuaW5jbHVkZXMoXCI8XCIpICYmIHRzTW9ycGhUeXBlICYmIGdldFByaW1pdGl2ZVR5cGVOYW1lKHRzTW9ycGhUeXBlKSB8fCB0eXBlTmFtZUFyZztcblxuICAgICAgICBpZiAoaXNQcmltaXRpdmVUeXBlKHR5cGVOYW1lKSkge1xuICAgICAgICAgICAgcmV0dXJuIHRoaXMuY3JlYXRlT3JHZXRGYW1peFByaW1pdGl2ZVR5cGUodHlwZU5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGVsZW1lbnQuaXNLaW5kKFN5bnRheEtpbmQuTWV0aG9kU2lnbmF0dXJlKSB8fCBlbGVtZW50LmlzS2luZChTeW50YXhLaW5kLk1ldGhvZERlY2xhcmF0aW9uKSkge1xuICAgICAgICAgICAgY29uc3QgbWV0aG9kRlFOID0gRlFORnVuY3Rpb25zLmdldEZRTihlbGVtZW50KTtcbiAgICAgICAgICAgIGNvbnN0IHJldHVyblR5cGVGUU4gPSBgJHttZXRob2RGUU4ucmVwbGFjZSgvXFxbTWV0aG9kKFNpZ25hdHVyZXxEZWNsYXJhdGlvbilcXF0kLywgJycpfVtSZXR1cm5UeXBlXWA7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIC8vIENoZWNrIGlmIHdlIGFscmVhZHkgaGF2ZSB0aGlzIHJldHVybiB0eXBlIGluIHRoZSByZXBvc2l0b3J5XG4gICAgICAgICAgICBjb25zdCBleGlzdGluZ1R5cGUgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUocmV0dXJuVHlwZUZRTik7XG4gICAgICAgICAgICBpZiAoZXhpc3RpbmdUeXBlKSB7XG4gICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYEZvdW5kIGV4aXN0aW5nIHJldHVybiB0eXBlIHdpdGggRlFOOiAke3JldHVyblR5cGVGUU59YCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuIGV4aXN0aW5nVHlwZSBhcyBGYW1peC5UeXBlO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYENyZWF0aW5nIHJldHVybiB0eXBlIHdpdGggZGlzdGluY3QgRlFOOiAke3JldHVyblR5cGVGUU59YCk7XG4gICAgICAgICAgICBjb25zdCBmbXhUeXBlID0gbmV3IEZhbWl4LlR5cGUoKTtcbiAgICAgICAgICAgIGZteFR5cGUubmFtZSA9IHR5cGVOYW1lO1xuICAgICAgICAgICAgZm14VHlwZS5mdWxseVF1YWxpZmllZE5hbWUgPSByZXR1cm5UeXBlRlFOO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAvLyBTZXQgY29udGFpbmVyIChzYW1lIGFzIG1ldGhvZCdzIGNvbnRhaW5lcilcbiAgICAgICAgICAgIGNvbnN0IG1ldGhvZEFuY2VzdG9yID0gSGVscGVycy5maW5kVHlwZUFuY2VzdG9yKGVsZW1lbnQpO1xuICAgICAgICAgICAgaWYgKG1ldGhvZEFuY2VzdG9yKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgYW5jZXN0b3JGUU4gPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKG1ldGhvZEFuY2VzdG9yKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhbmNlc3RvciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShhbmNlc3RvckZRTikgYXMgRmFtaXguQ29udGFpbmVyRW50aXR5O1xuICAgICAgICAgICAgICAgIGlmIChhbmNlc3Rvcikge1xuICAgICAgICAgICAgICAgICAgICBmbXhUeXBlLmNvbnRhaW5lciA9IGFuY2VzdG9yO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhUeXBlKTtcbiAgICAgICAgICAgIHRoaXMuZm14VHlwZU1hcC5zZXQoZWxlbWVudCwgZm14VHlwZSk7XG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteFR5cGUsIGVsZW1lbnQpO1xuICAgICAgICAgICAgcmV0dXJuIGZteFR5cGU7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBpc1BhcmFtZXRyaWNUeXBlID1cbiAgICAgICAgICAgIChlbGVtZW50IGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbiAmJiBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMCkgfHxcbiAgICAgICAgICAgIChlbGVtZW50IGluc3RhbmNlb2YgSW50ZXJmYWNlRGVjbGFyYXRpb24gJiYgZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApO1xuICAgICAgICAgICAgXG4gICAgICAgIGlmIChpc1BhcmFtZXRyaWNUeXBlKSB7XG4gICAgICAgICAgICByZXR1cm4gdGhpcy5jcmVhdGVPckdldEZhbWl4UGFyYW1ldHJpY1R5cGUodHlwZU5hbWUsIGVsZW1lbnQgYXMgVFNNb3JwaFBhcmFtZXRyaWNUeXBlKTtcbiAgICAgICAgfVxuICAgIFxuICAgICAgICBpZiAoIXRoaXMuZm14VHlwZU1hcC5oYXMoZWxlbWVudCkpIHtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCdUeXBlIG5vdCBmb3VuZCBpbiBtYXAsIGNyZWF0aW5nIG5ldycpOyBcbiAgICAgICAgICAgIGxldCBhbmNlc3RvcjogRmFtaXguQ29udGFpbmVyRW50aXR5IHwgdW5kZWZpbmVkOyAgICBcbiAgICAgICAgICAgIGlmIChlbGVtZW50KSB7XG4gICAgICAgICAgICAgICAgY29uc3QgdHlwZUFuY2VzdG9yID0gSGVscGVycy5maW5kVHlwZUFuY2VzdG9yKGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBUeXBlIGFuY2VzdG9yIGZvdW5kOiAke3R5cGVBbmNlc3Rvcj8uZ2V0S2luZE5hbWUoKX1gKTtcbiAgICBcbiAgICAgICAgICAgICAgICBpZiAodHlwZUFuY2VzdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGFuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTih0eXBlQW5jZXN0b3IpO1xuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgQW5jZXN0b3IgRlFOOiAke2FuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lfWApO1xuICAgICAgICAgICAgICAgICAgICBhbmNlc3RvciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShhbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgRmFtaXguQ29udGFpbmVyRW50aXR5O1xuICAgICAgICAgICAgICAgICAgICBpZiAoIWFuY2VzdG9yKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBhbmNlc3RvciA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUodHlwZUFuY2VzdG9yLmdldFRleHQoKSwgdHlwZUFuY2VzdG9yLmdldFR5cGUoKSwgdHlwZUFuY2VzdG9yIGFzIFRTTW9ycGhUeXBlRGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc29sZS5sb2coJ0FuY2VzdG9yIG5vdCBmb3VuZCBpbiByZXBvLCBjcmVhdGluZyBpdCcpO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc29sZS5sb2coYEZvdW5kIGFuY2VzdG9yIGluIGZhbWl4UmVwOiAke2FuY2VzdG9yLmZ1bGx5UXVhbGlmaWVkTmFtZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnNvbGUubG9nKGBObyB0eXBlIGFuY2VzdG9yIGZvdW5kIGZvciAke3R5cGVOYW1lfSAtIHByb2NlZWRpbmcgd2l0aG91dCBjb250YWluZXJgKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICBjb25zdCBmbXhUeXBlID0gbmV3IEZhbWl4LlR5cGUoKTtcbiAgICAgICAgICAgIGZteFR5cGUubmFtZSA9IHR5cGVOYW1lO1xuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYENyZWF0ZWQgbmV3IHR5cGUgd2l0aCBuYW1lOiAke3R5cGVOYW1lfWApOyAgICBcbiAgICAgICAgICAgIGlmIChhbmNlc3Rvcikge1xuICAgICAgICAgICAgICAgIGZteFR5cGUuY29udGFpbmVyID0gYW5jZXN0b3I7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQW5jZXN0b3Igbm90IGZvdW5kIGZvciB0eXBlICR7dHlwZU5hbWV9LmApO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgaW5pdEZRTihlbGVtZW50LCBmbXhUeXBlKTtcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBUeXBlIEZRTiBhZnRlciBpbml0OiAke2ZteFR5cGUuZnVsbHlRdWFsaWZpZWROYW1lfWApO1xuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoZWxlbWVudCwgZm14VHlwZSk7XG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14VHlwZSk7XG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZygnQWRkZWQgdHlwZSB0byByZXBvc2l0b3J5Jyk7XG4gICAgICAgICAgICB0aGlzLmZteFR5cGVNYXAuc2V0KGVsZW1lbnQsIGZteFR5cGUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgY29uc3QgZm14VHlwZSA9IHRoaXMuZm14VHlwZU1hcC5nZXQoZWxlbWVudCk7XG4gICAgICAgICAgICBpZiAoIWZteFR5cGUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhbWl4IHR5cGUgJHt0eXBlTmFtZX0gaXMgbm90IGZvdW5kIGluIHRoZSBUeXBlIG1hcC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiBmbXhUeXBlO1xuICAgICAgICB9XG4gICAgXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmZteFR5cGVNYXAuZ2V0KGVsZW1lbnQpITtcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhUeXBlLCBlbGVtZW50KTtcbiAgICAgICAgcmV0dXJuIGZteFR5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggdHlwZSB0aGF0IGlzIHBhcmFtZXRyaWNcbiAgICAgKiBAcGFyYW0gdHlwZU5hbWUgQSB0eXBlIG5hbWVcbiAgICAgKiBAcGFyYW0gZWxlbWVudCBBIHRzLW1vcnBoIGVsZW1lbnRcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHBhcmFtZXRlciB0eXBlXG4gICAgICovXG4gICAgY3JlYXRlT3JHZXRGYW1peFBhcmFtZXRyaWNUeXBlKHR5cGVOYW1lOiBzdHJpbmcsIGVsZW1lbnQ6IFRTTW9ycGhQYXJhbWV0cmljVHlwZSk6IEZhbWl4LlR5cGUge1xuXG4gICAgICAgIGlmICh0aGlzLmZteFR5cGVNYXAuaGFzKGVsZW1lbnQpID09PSB0cnVlKSB7XG4gICAgICAgICAgICBjb25zdCByZXN1bHQgPSB0aGlzLmZteFR5cGVNYXAuZ2V0KGVsZW1lbnQpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggdHlwZSAke3R5cGVOYW1lfSBpcyBub3QgZm91bmQgKHVuZGVmaW5lZCkgaW4gdGhlIFR5cGUgbWFwLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gQSBwYXJhbWV0cmljIHR5cGUgaXMgYSB0eXBlIHRoYXQgaGFzIHR5cGUgcGFyYW1ldGVycywgZS5nLiwgTGlzdDxUPlxuICAgICAgICAvLyBJbiBUUyBpdCBjYW4gYmUgYSBjbGFzcywgYW4gaW50ZXJmYWNlLCBhIGZ1bmN0aW9uLCBhbiBhcnJvdyBmdW5jdGlvbiwgb3IgYSBtZXRob2RcblxuICAgICAgICAvLyBjcmVhdGUgdGhlIEZhbWl4IFBhcmFtZXRyaWMgVHlwZSAobWF5YmUgaXQncyBqdXN0IGFuIEludGVyZmFjZSwgZXRjLilcbiAgICAgICAgbGV0IGZteFR5cGU6IEZhbWl4LlR5cGU7XG5cbiAgICAgICAgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICBmbXhUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNDbGFzcygpO1xuICAgICAgICB9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBJbnRlcmZhY2VEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgZm14VHlwZSA9IG5ldyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlKCk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gZnVuY3Rpb25zIGFuZCBtZXRob2RzIGFyZSBub3QgdHlwZXMgXG4gICAgICAgIC8vIGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBGdW5jdGlvbkRlY2xhcmF0aW9uKSB7XG4gICAgICAgIC8vICAgICBmbXhUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbigpO1xuICAgICAgICAvLyB9IGVsc2UgaWYgKGVsZW1lbnQgaW5zdGFuY2VvZiBBcnJvd0Z1bmN0aW9uKSB7XG4gICAgICAgIC8vICAgICBmbXhUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNBcnJvd0Z1bmN0aW9uKCk7XG4gICAgICAgIC8vIH0gZWxzZSBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIE1ldGhvZERlY2xhcmF0aW9uKSB7XG4gICAgICAgIC8vICAgICBmbXhUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNNZXRob2QoKTtcbiAgICAgICAgLy8gfSBcbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEVsZW1lbnQgaXMgbm90IGEgY2xhc3MsIGludGVyZmFjZSwgZnVuY3Rpb24sIGFycm93IGZ1bmN0aW9uLCBvciBtZXRob2QuYCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBjb25zdCBwYXJhbWV0ZXJzID0gZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpO1xuXG4gICAgICAgIC8vIC8vIGZvciBlYWNoIHBhcmFtZXRlciwgZ2V0T3JDcmVhdGUgdGhlIEZhbWl4UGFyYW1ldGVyVHlwZVxuICAgICAgICAvLyBmb3IgKGNvbnN0IHBhcmFtZXRlciBvZiBwYXJhbWV0ZXJzKSB7XG4gICAgICAgIC8vICAgICB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhQYXJhbWV0ZXJUeXBlKHBhcmFtZXRlci5nZXROYW1lKCksIHBhcmFtZXRlcik7XG4gICAgICAgIC8vIH1cblxuICAgICAgICAvLyAvLyBUT0RPOiB0aGUgZm9sbG93aW5nIGNvZGUgaXMgbm90IGNvcnJlY3QsIGl0IGlzIGp1c3QgYSBwbGFjZWhvbGRlclxuICAgICAgICAvLyBjb25zdCBwYXJhbWV0ZXJUeXBlTmFtZXMgPSB0eXBlTmFtZS5zdWJzdHJpbmcodHlwZU5hbWUuaW5kZXhPZihcIjxcIikgKyAxLCB0eXBlTmFtZS5pbmRleE9mKFwiPlwiKSlcbiAgICAgICAgLy8gICAgIC5zcGxpdChcIixcIikubWFwKHMgPT4gcy50cmltKCkpO1xuICAgICAgICAvLyBjb25zdCBiYXNlVHlwZU5hbWUgPSB0eXBlTmFtZS5zdWJzdHJpbmcoMCwgdHlwZU5hbWUuaW5kZXhPZihcIjxcIikpLnRyaW0oKTtcbiAgICAgICAgLy8gcGFyYW1ldGVyVHlwZU5hbWVzLmZvckVhY2gocGFyYW1ldGVyVHlwZU5hbWUgPT4ge1xuICAgICAgICAvLyAgICAgY29uc3QgZm14UGFyYW1ldGVyVHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFBhcmFtZXRlclR5cGUocGFyYW1ldGVyVHlwZU5hbWUsIGVsZW1lbnQpO1xuICAgICAgICAvLyAgICAgKGZteFR5cGUgYXMgRmFtaXguUGFyYW1ldGVyVHlwZSkuYWRkQXJndW1lbnQoZm14UGFyYW1ldGVyVHlwZSk7XG4gICAgICAgIC8vIH0pO1xuICAgICAgICAvLyBjb25zdCBmbXhCYXNlVHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoYmFzZVR5cGVOYW1lLCBlbGVtZW50KTtcblxuICAgICAgICAvLyAoZm14VHlwZSBhcyBGYW1peC5QYXJhbWV0ZXJUeXBlKS5iYXNlVHlwZSA9IGZteEJhc2VUeXBlO1xuXG4gICAgICAgIGZteFR5cGUubmFtZSA9IHR5cGVOYW1lO1xuICAgICAgICBpbml0RlFOKGVsZW1lbnQsIGZteFR5cGUpO1xuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14VHlwZSk7XG4gICAgICAgIHRoaXMuZm14VHlwZU1hcC5zZXQoZWxlbWVudCwgZm14VHlwZSk7XG4gICAgICAgIHJldHVybiBmbXhUeXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSB0eXBlIGZvciBhIHBhcmFtZXRlciBpbiBhIHBhcmFtZXRyaWMgdHlwZSwgZS5nLiwgVCBpbiBMaXN0PFQ+XG4gICAgICogQHBhcmFtIHBhcmFtZXRlclR5cGVOYW1lIFxuICAgICAqIEBwYXJhbSBlbGVtZW50IHRoZSBUeXBlU2NyaXB0IGVsZW1lbnQgKFRTTW9ycGhQYXJhbWV0cmljVHlwZSkgdGhhdCB0aGUgdHlwZSBpcyBhc3NvY2lhdGVkIHdpdGhcbiAgICAgKiBAcmV0dXJucyBcbiAgICAgKi9cbiAgICAvLyBjcmVhdGVPckdldEZhbWl4UGFyYW1ldGVyVHlwZShwYXJhbWV0ZXJUeXBlTmFtZTogc3RyaW5nLCBlbGVtZW50OiBQYXJhbWV0ZXJEZWNsYXJhdGlvbikge1xuICAgIC8vICAgICBpZiAodGhpcy5mbXhUeXBlTWFwLmhhcyhlbGVtZW50KSkge1xuICAgIC8vICAgICAgICAgcmV0dXJuIHRoaXMuZm14VHlwZU1hcC5nZXQoZWxlbWVudCkgYXMgRmFtaXguUGFyYW1ldGVyVHlwZTtcbiAgICAvLyAgICAgfVxuXG4gICAgLy8gICAgIC8vIGRldGVybWluZSBpZiBlbGVtZW50IGlzIGEgXG4gICAgLy8gICAgIGNvbnN0IGZteFR5cGUgPSBuZXcgRmFtaXguUGFyYW1ldGVyVHlwZSgpO1xuICAgIC8vICAgICAvLyBjb25zdCBwYXJhbWV0ZXJUeXBlTmFtZXMgPSB0eXBlTmFtZS5zdWJzdHJpbmcodHlwZU5hbWUuaW5kZXhPZihcIjxcIikgKyAxLCB0eXBlTmFtZS5pbmRleE9mKFwiPlwiKSlcbiAgICAvLyAgICAgLy8gICAgIC5zcGxpdChcIixcIikubWFwKHMgPT4gcy50cmltKCkpO1xuICAgIC8vICAgICAvLyBjb25zdCBiYXNlVHlwZU5hbWUgPSB0eXBlTmFtZS5zdWJzdHJpbmcoMCwgdHlwZU5hbWUuaW5kZXhPZihcIjxcIikpLnRyaW0oKTtcbiAgICAvLyAgICAgLy8gcGFyYW1ldGVyVHlwZU5hbWVzLmZvckVhY2gocGFyYW1ldGVyVHlwZU5hbWUgPT4ge1xuICAgIC8vICAgICAvLyAgICAgY29uc3QgZm14UGFyYW1ldGVyVHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFBhcmFtZXRlclR5cGUocGFyYW1ldGVyVHlwZU5hbWUsIGVsZW1lbnQpO1xuICAgIC8vICAgICAvLyAgICAgKGZteFR5cGUgYXMgRmFtaXguUGFyYW1ldGVyVHlwZSkuYWRkQXJndW1lbnQoZm14UGFyYW1ldGVyVHlwZSk7XG4gICAgLy8gICAgIC8vIH0pO1xuICAgIC8vICAgICBjb25zdCBmbXhCYXNlVHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoYmFzZVR5cGVOYW1lLCBlbGVtZW50KTtcbiAgICAvLyAgICAgKGZteFR5cGUgYXMgRmFtaXguUGFyYW1ldGVyVHlwZSkuYmFzZVR5cGUgPSBmbXhCYXNlVHlwZTtcbiAgICAvLyAgICAgaW5pdEZRTihlbGVtZW50LCBmbXhUeXBlKTtcbiAgICAvLyAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFR5cGUpO1xuICAgIC8vICAgICB0aGlzLmZteFR5cGVNYXAuc2V0KGVsZW1lbnQsIGZteFR5cGUpO1xuICAgIC8vICAgICByZXR1cm4gZm14VHlwZTtcbiAgICAvLyB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBwcmltaXRpdmUgdHlwZVxuICAgICAqIEBwYXJhbSB0eXBlTmFtZSBBIHR5cGUgbmFtZVxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgcHJpbWl0aXZlIHR5cGVcbiAgICAgKi9cbiAgICBjcmVhdGVPckdldEZhbWl4UHJpbWl0aXZlVHlwZSh0eXBlTmFtZTogc3RyaW5nKTogRmFtaXguUHJpbWl0aXZlVHlwZSB7XG4gICAgICAgIGxldCBmbXhUeXBlOiBGYW1peC5QcmltaXRpdmVUeXBlID0gbmV3IEZhbWl4LlByaW1pdGl2ZVR5cGUoKTtcbiAgICAgICAgaWYgKCF0aGlzLmZteFByaW1pdGl2ZVR5cGVNYXAuaGFzKHR5cGVOYW1lKSkge1xuICAgICAgICAgICAgZm14VHlwZSA9IG5ldyBGYW1peC5QcmltaXRpdmVUeXBlKCk7XG4gICAgICAgICAgICBmbXhUeXBlLmlzU3R1YiA9IHRydWU7XG4gICAgICAgICAgICBmbXhUeXBlLm5hbWUgPSB0eXBlTmFtZTtcbiAgICAgICAgICAgIGZteFR5cGUuZnVsbHlRdWFsaWZpZWROYW1lID0gdHlwZU5hbWUgKyBcIltQcmltaXRpdmVUeXBlXVwiO1xuICAgICAgICAgICAgdGhpcy5mbXhQcmltaXRpdmVUeXBlTWFwLnNldCh0eXBlTmFtZSwgZm14VHlwZSk7XG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14VHlwZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmbXhUeXBlID0gdGhpcy5mbXhQcmltaXRpdmVUeXBlTWFwLmdldCh0eXBlTmFtZSkgYXMgRmFtaXguUHJpbWl0aXZlVHlwZTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZm14VHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggYWNjZXNzXG4gICAgICogQHBhcmFtIG5vZGUgQSBub2RlXG4gICAgICogQHBhcmFtIGlkIEFuIGlkIG9mIGEgcGFyYW1ldGVyLCBhIHZhcmlhYmxlLCBhIHByb3BlcnR5IG9yIGFuIGVudW0gbWVtYmVyXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4QWNjZXNzKG5vZGU6IElkZW50aWZpZXIsIGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZm14VmFyID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5SWQoaWQpIGFzIEZhbWl4LlN0cnVjdHVyYWxFbnRpdHk7XG4gICAgICAgIGlmICghZm14VmFyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhbWl4IGVudGl0eSB3aXRoIGlkICR7aWR9IG5vdCBmb3VuZCwgZm9yIG5vZGUgJHtub2RlLmdldFRleHQoKX0gaW4gJHtub2RlLmdldFNvdXJjZUZpbGUoKS5nZXRCYXNlTmFtZSgpfSBhdCBsaW5lICR7bm9kZS5nZXRTdGFydExpbmVOdW1iZXIoKX0uYCk7XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBGYW1peEFjY2Vzcy4gTm9kZTogWyR7bm9kZS5nZXRLaW5kTmFtZSgpfV0gJyR7bm9kZS5nZXRUZXh0KCl9JyBhdCBsaW5lICR7bm9kZS5nZXRTdGFydExpbmVOdW1iZXIoKX0gaW4gJHtub2RlLmdldFNvdXJjZUZpbGUoKS5nZXRCYXNlTmFtZSgpfSwgaWQ6ICR7aWR9IHJlZmVycyB0byBmbXhWYXIgJyR7Zm14VmFyLmZ1bGx5UXVhbGlmaWVkTmFtZX0nLmApO1xuICAgIFxuICAgICAgICBjb25zdCBub2RlUmVmZXJlbmNlQW5jZXN0b3IgPSBIZWxwZXJzLmZpbmRBbmNlc3Rvcihub2RlKTtcbiAgICAgICAgaWYgKCFub2RlUmVmZXJlbmNlQW5jZXN0b3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgTm8gYW5jZXN0b3IgZm91bmQgZm9yIG5vZGUgJyR7bm9kZS5nZXRUZXh0KCl9J2ApO1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgXG4gICAgICAgIGNvbnN0IGFuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihub2RlUmVmZXJlbmNlQW5jZXN0b3IpO1xuICAgICAgICBjb25zdCBhY2Nlc3NvciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShhbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgRmFtaXguQ29udGFpbmVyRW50aXR5O1xuICAgICAgICBpZiAoIWFjY2Vzc29yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYEFuY2VzdG9yICR7YW5jZXN0b3JGdWxseVF1YWxpZmllZE5hbWV9IG9mIGtpbmQgJHtub2RlUmVmZXJlbmNlQW5jZXN0b3IuZ2V0S2luZE5hbWUoKX0gbm90IGZvdW5kLmApO1xuICAgICAgICAgICAgcmV0dXJuOyAvLyBCYWlsIG91dCBmb3Igbm93XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGFjY2Vzc29yIHRvIGJlICR7YWNjZXNzb3IuZnVsbHlRdWFsaWZpZWROYW1lfS5gKTtcbiAgICAgICAgfVxuICAgIFxuICAgICAgICAvLyBFbnN1cmUgYWNjZXNzb3IgaXMgYSBtZXRob2QsIGZ1bmN0aW9uLCBzY3JpcHQsIG9yIG1vZHVsZVxuICAgICAgICBpZiAoIShhY2Nlc3NvciBpbnN0YW5jZW9mIEZhbWl4Lk1ldGhvZCkgJiYgIShhY2Nlc3NvciBpbnN0YW5jZW9mIEZhbWl4LkFycm93RnVuY3Rpb24pICYmICEoYWNjZXNzb3IgaW5zdGFuY2VvZiBGYW1peC5GdW5jdGlvbikgJiYgIShhY2Nlc3NvciBpbnN0YW5jZW9mIEZhbWl4LlNjcmlwdEVudGl0eSkgJiYgIShhY2Nlc3NvciBpbnN0YW5jZW9mIEZhbWl4Lk1vZHVsZSkpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgQWNjZXNzb3IgJHthY2Nlc3Nvci5mdWxseVF1YWxpZmllZE5hbWV9IGlzIG5vdCBhIG1ldGhvZCwgZnVuY3Rpb24sIGV0Yy5gKTtcbiAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgfVxuICAgIFxuICAgICAgICAvLyBBdm9pZCBkdXBsaWNhdGVzXG4gICAgICAgIGNvbnN0IGZvdW5kQWNjZXNzID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEFjY2Vzc0J5QWNjZXNzb3JBbmRWYXJpYWJsZShhY2Nlc3NvciwgZm14VmFyKTtcbiAgICAgICAgaWYgKGZvdW5kQWNjZXNzKSB7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYEZhbWl4QWNjZXNzIGFscmVhZHkgZXhpc3RzIGZvciBhY2Nlc3NvciAke2FjY2Vzc29yLmZ1bGx5UXVhbGlmaWVkTmFtZX0gYW5kIHZhcmlhYmxlICR7Zm14VmFyLmZ1bGx5UXVhbGlmaWVkTmFtZX0uYCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgY29uc3QgZm14QWNjZXNzID0gbmV3IEZhbWl4LkFjY2VzcygpO1xuICAgICAgICBmbXhBY2Nlc3MuYWNjZXNzb3IgPSBhY2Nlc3NvcjtcbiAgICAgICAgZm14QWNjZXNzLnZhcmlhYmxlID0gZm14VmFyO1xuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14QWNjZXNzKTtcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhBY2Nlc3MsIG5vZGUpO1xuICAgICAgICBsb2dnZXIuZGVidWcoYENyZWF0ZWQgYWNjZXNzOiAke2FjY2Vzc29yLmZ1bGx5UXVhbGlmaWVkTmFtZX0gLT4gJHtmbXhWYXIuZnVsbHlRdWFsaWZpZWROYW1lfWApO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBpbnZvY2F0aW9uXG4gICAgICogQHBhcmFtIG5vZGVSZWZlcnJpbmdUb0ludm9jYWJsZSBBIG5vZGVcbiAgICAgKiBAcGFyYW0gaW52b2NhYmxlIEEgbWV0aG9kIG9yIGEgZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBtZXRob2Qgb3IgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4SW52b2NhdGlvbihub2RlUmVmZXJyaW5nVG9JbnZvY2FibGU6IElkZW50aWZpZXIsIGludm9jYWJsZTogSW52b2NhYmxlVHlwZSwgaWQ6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBmbXhJbnZvY2FibGUgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlJZChpZCkgYXMgRmFtaXguQmVoYXZpb3JhbEVudGl0eTtcbiAgICAgICAgLy8gc2luY2UgdGhlIG5vZGUgaXMgaW4gdGhlIEFTVCwgd2UgbmVlZCB0byBmaW5kIHRoZSBhbmNlc3RvciB0aGF0IGlzIGluIHRoZSBGYW1peCBtb2RlbFxuICAgICAgICBjb25zdCBjb250YWluZXJPZk5vZGUgPSBIZWxwZXJzLmZpbmRBbmNlc3Rvcihub2RlUmVmZXJyaW5nVG9JbnZvY2FibGUpO1xuICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGNvbnRhaW5lciAoYW5jZXN0b3IpICR7Y29udGFpbmVyT2ZOb2RlLmdldEtpbmROYW1lKCl9IGZvciBBU1Qgbm9kZSAke25vZGVSZWZlcnJpbmdUb0ludm9jYWJsZS5nZXRUZXh0KCl9LmApO1xuICAgICAgICBjb25zdCBjb250YWluZXJGUU4gPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGNvbnRhaW5lck9mTm9kZSk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgRm91bmQgY29udGFpbmVyRlFOICR7Y29udGFpbmVyRlFOfS5gKTtcbiAgICAgICAgbGV0IHNlbmRlciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShjb250YWluZXJGUU4pIGFzIEZhbWl4LkNvbnRhaW5lckVudGl0eTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBGb3VuZCBhIHNlbmRlciB0aGF0IG1hdGNoZXMgJHtzZW5kZXIuZnVsbHlRdWFsaWZpZWROYW1lfS5gKTtcbiAgICAgICAgaWYgKHNlbmRlciBpbnN0YW5jZW9mIEZhbWl4LlR5cGUpIHtcbiAgICAgICAgICAgIC8vIFRPRE8gdGhpcyBtaWdodCBiZSBhbiBlcnJvciBpbiBnZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lXG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYE9vcHMhIFNlbmRlciBpcyBhIHR5cGUsIHdoaWNoIGlzIG5vdCB2YWxpZCBmb3IgYW4gSW52b2NhdGlvbi4gVHJ5aW5nIHRvIGZpbmQgYSBjb250YWluZXIgZm9yICR7c2VuZGVyLmZ1bGx5UXVhbGlmaWVkTmFtZX0uYCk7XG4gICAgICAgICAgICBjb25zdCBzZW5kZXJDb250YWluZXIgPSBzZW5kZXIuY29udGFpbmVyO1xuICAgICAgICAgICAgaWYgKHNlbmRlckNvbnRhaW5lcikge1xuICAgICAgICAgICAgICAgIHNlbmRlciA9IHNlbmRlckNvbnRhaW5lcjtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb25zdCByZWNlaXZlckZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oaW52b2NhYmxlLmdldFBhcmVudCgpKTtcbiAgICAgICAgY29uc3QgcmVjZWl2ZXIgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUocmVjZWl2ZXJGdWxseVF1YWxpZmllZE5hbWUpIGFzIEZhbWl4Lk5hbWVkRW50aXR5O1xuXG4gICAgICAgIGNvbnN0IGZteEludm9jYXRpb24gPSBuZXcgRmFtaXguSW52b2NhdGlvbigpO1xuICAgICAgICBmbXhJbnZvY2F0aW9uLnNlbmRlciA9IHNlbmRlcjtcbiAgICAgICAgZm14SW52b2NhdGlvbi5yZWNlaXZlciA9IHJlY2VpdmVyO1xuICAgICAgICBmbXhJbnZvY2F0aW9uLmFkZENhbmRpZGF0ZShmbXhJbnZvY2FibGUpO1xuICAgICAgICBmbXhJbnZvY2F0aW9uLnNpZ25hdHVyZSA9IGZteEludm9jYWJsZS5zaWduYXR1cmU7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEludm9jYXRpb24pO1xuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14SW52b2NhdGlvbixub2RlUmVmZXJyaW5nVG9JbnZvY2FibGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBpbmhlcml0YW5jZVxuICAgICAqIEBwYXJhbSBiYXNlQ2xhc3NPckludGVyZmFjZSBBIGNsYXNzIG9yIGFuIGludGVyZmFjZSAoc3ViY2xhc3MpXG4gICAgICogQHBhcmFtIGluaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UgVGhlIGluaGVyaXRlZCBjbGFzcyBvciBpbnRlcmZhY2UgKHN1cGVyY2xhc3MpXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhJbmhlcml0YW5jZShiYXNlQ2xhc3NPckludGVyZmFjZTogQ2xhc3NEZWNsYXJhdGlvbiB8IEludGVyZmFjZURlY2xhcmF0aW9uLCBpbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlOiBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHMpOiB2b2lkIHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBGYW1peEluaGVyaXRhbmNlIGZvciAke2Jhc2VDbGFzc09ySW50ZXJmYWNlLmdldFRleHQoKX0gYW5kICR7aW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZS5nZXRUZXh0KCl9IFske2luaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UuY29uc3RydWN0b3IubmFtZX1dLmApO1xuICAgICAgICBjb25zdCBmbXhJbmhlcml0YW5jZSA9IG5ldyBGYW1peC5Jbmhlcml0YW5jZSgpO1xuXG4gICAgICAgIGxldCBzdWJDbGFzczogRmFtaXguQ2xhc3MgfCBGYW1peC5JbnRlcmZhY2UgfCB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChiYXNlQ2xhc3NPckludGVyZmFjZSBpbnN0YW5jZW9mIENsYXNzRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgIHN1YkNsYXNzID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoYmFzZUNsYXNzT3JJbnRlcmZhY2UpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgc3ViQ2xhc3MgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoYmFzZUNsYXNzT3JJbnRlcmZhY2UpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFzdWJDbGFzcykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTdWJjbGFzcyAke2Jhc2VDbGFzc09ySW50ZXJmYWNlfSBub3QgZm91bmQgaW4gQ2xhc3Mgb3IgSW50ZXJmYWNlIG1hcHMuYCk7XG4gICAgICAgIH1cblxuICAgICAgICBsZXQgc3VwZXJDbGFzczogRmFtaXguQ2xhc3MgfCBGYW1peC5JbnRlcmZhY2UgfCB1bmRlZmluZWQ7XG5cbiAgICAgICAgaWYgKGluaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICBzdXBlckNsYXNzID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoaW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZSk7XG4gICAgICAgIH0gZWxzZSBpZiAoaW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZSBpbnN0YW5jZW9mIEludGVyZmFjZURlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICBzdXBlckNsYXNzID0gdGhpcy5jcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlKGluaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UpO1xuICAgICAgICB9IGVsc2UgIHtcbiAgICAgICAgICAgIC8vIGluaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UgaW5zdGFuY2VvZiBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHNcbiAgICAgICAgICAgIC8vIG11c3QgZGV0ZXJtaW5lIGlmIGluaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UgaXMgYSBjbGFzcyBvciBhbiBpbnRlcmZhY2VcbiAgICAgICAgICAgIC8vIHRoZW4gZmluZCB0aGUgZGVjbGFyYXRpb24sIGVsc2UgaXQncyBhIHN0dWJcblxuICAgICAgICAgICAgY29uc3QgaGVyaXRhZ2VDbGF1c2UgPSBpbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlLmdldFBhcmVudCgpO1xuICAgICAgICAgICAgaWYgKGhlcml0YWdlQ2xhdXNlIGluc3RhbmNlb2YgSGVyaXRhZ2VDbGF1c2UpIHtcbiAgICAgICAgICAgICAgICAvLyBjYXNlczogMSkgY2xhc3MgZXh0ZW5kcyBjbGFzcywgMikgY2xhc3MgaW1wbGVtZW50cyBpbnRlcmZhY2UsIDMpIGludGVyZmFjZSBleHRlbmRzIGludGVyZmFjZVxuXG4gICAgICAgICAgICAgICAgLy8gY2xhc3MgZXh0ZW5kcyBjbGFzc1xuICAgICAgICAgICAgICAgIGlmIChoZXJpdGFnZUNsYXVzZS5nZXRUZXh0KCkuc3RhcnRzV2l0aChcImV4dGVuZHNcIikgJiYgYmFzZUNsYXNzT3JJbnRlcmZhY2UgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNsYXNzRGVjbGFyYXRpb24gPSBnZXRJbnRlcmZhY2VPckNsYXNzRGVjbGFyYXRpb25Gcm9tRXhwcmVzc2lvbihpbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNsYXNzRGVjbGFyYXRpb24gIT09IHVuZGVmaW5lZCAmJiBjbGFzc0RlY2xhcmF0aW9uIGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXJDbGFzcyA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENsYXNzKGNsYXNzRGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBDbGFzcyBkZWNsYXJhdGlvbiBub3QgZm91bmQgZm9yICR7aW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZS5nZXRUZXh0KCl9LmApO1xuICAgICAgICAgICAgICAgICAgICAgICAgc3VwZXJDbGFzcyA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENsYXNzU3R1Yihpbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoaGVyaXRhZ2VDbGF1c2UuZ2V0VGV4dCgpLnN0YXJ0c1dpdGgoXCJpbXBsZW1lbnRzXCIpICYmIGJhc2VDbGFzc09ySW50ZXJmYWNlIGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbiAvLyBjbGFzcyBpbXBsZW1lbnRzIGludGVyZmFjZVxuICAgICAgICAgICAgICAgICAgICB8fCAoaGVyaXRhZ2VDbGF1c2UuZ2V0VGV4dCgpLnN0YXJ0c1dpdGgoXCJleHRlbmRzXCIpICYmIGJhc2VDbGFzc09ySW50ZXJmYWNlIGluc3RhbmNlb2YgSW50ZXJmYWNlRGVjbGFyYXRpb24pKSB7IC8vIGludGVyZmFjZSBleHRlbmRzIGludGVyZmFjZVxuXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGludGVyZmFjZU9yQ2xhc3NEZWNsYXJhdGlvbiA9IGdldEludGVyZmFjZU9yQ2xhc3NEZWNsYXJhdGlvbkZyb21FeHByZXNzaW9uKGluaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UpO1xuICAgICAgICAgICAgICAgICAgICBpZiAoaW50ZXJmYWNlT3JDbGFzc0RlY2xhcmF0aW9uICE9PSB1bmRlZmluZWQgJiYgaW50ZXJmYWNlT3JDbGFzc0RlY2xhcmF0aW9uIGluc3RhbmNlb2YgSW50ZXJmYWNlRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHN1cGVyQ2xhc3MgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoaW50ZXJmYWNlT3JDbGFzc0RlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgSW50ZXJmYWNlIGRlY2xhcmF0aW9uIG5vdCBmb3VuZCBmb3IgJHtpbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlLmdldFRleHQoKX0uYCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBzdXBlckNsYXNzID0gdGhpcy5jcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlU3R1Yihpbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRocm93IG5ldyBFcnJvcihgUGFyZW50IG9mICR7aW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZS5nZXRUZXh0KCl9IGlzIG5vdCBhIGNsYXNzIG9yIGFuIGludGVyZmFjZS5gKTtcbiAgICAgICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBQYXJlbnQgb2YgJHtpbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlLmdldFRleHQoKX0gaXMgbm90IGEgY2xhc3Mgb3IgYW4gaW50ZXJmYWNlLmApO1xuICAgICAgICAgICAgICAgICAgICBzdXBlckNsYXNzID0gdGhpcy5jcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlU3R1Yihpbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSGVyaXRhZ2UgY2xhdXNlIG5vdCBmb3VuZCBmb3IgJHtpbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlLmdldFRleHQoKX0uYCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoc3VwZXJDbGFzcywgaW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZSk7XG5cbiAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoaW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZSwgc3VwZXJDbGFzcyk7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KHN1cGVyQ2xhc3MpO1xuXG4gICAgICAgIGZteEluaGVyaXRhbmNlLnN1YmNsYXNzID0gc3ViQ2xhc3M7XG4gICAgICAgIGZteEluaGVyaXRhbmNlLnN1cGVyY2xhc3MgPSBzdXBlckNsYXNzO1xuXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhJbmhlcml0YW5jZSk7XG4gICAgICAgIC8vIG5vIEZRTiBmb3IgaW5oZXJpdGFuY2VcblxuICAgICAgICAvLyBXZSBkb24ndCBtYXAgaW5oZXJpdGFuY2UgdG8gdGhlIHNvdXJjZSBjb2RlIGVsZW1lbnQgYmVjYXVzZSB0aGVyZSBhcmUgdHdvIGVsZW1lbnRzIChzdXBlciwgc3ViKVxuICAgICAgICAvLyB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEluaGVyaXRhbmNlLCBudWxsKTtcblxuICAgIH1cbiAgICBjcmVhdGVPckdldEZhbWl4Q2xhc3NTdHViKHVucmVzb2x2ZWRJbmhlcml0ZWRDbGFzczogRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKTogRmFtaXguQ2xhc3Mge1xuICAgICAgICAvLyBtYWtlIGEgRlFOIGZvciB0aGUgc3R1YlxuICAgICAgICBjb25zdCBmcW4gPSBGUU5GdW5jdGlvbnMuZ2V0RlFOVW5yZXNvbHZlZEluaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UodW5yZXNvbHZlZEluaGVyaXRlZENsYXNzKTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBjcmVhdGVPckdldEZhbWl4Q2xhc3NTdHViOiBmcW46ICR7ZnFufWApO1xuICAgICAgICBjb25zdCBmbXhDbGFzcyA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShmcW4pIGFzIEZhbWl4LkNsYXNzO1xuICAgICAgICBpZiAoZm14Q2xhc3MpIHtcbiAgICAgICAgICAgIHJldHVybiBmbXhDbGFzcztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHN0dWIgPSBuZXcgRmFtaXguQ2xhc3MoKTtcbiAgICAgICAgICAgIHN0dWIubmFtZSA9IHVucmVzb2x2ZWRJbmhlcml0ZWRDbGFzcy5nZXRUZXh0KCk7XG4gICAgICAgICAgICBzdHViLmlzU3R1YiA9IHRydWU7XG4gICAgICAgICAgICBzdHViLmZ1bGx5UXVhbGlmaWVkTmFtZSA9IGZxbjtcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChzdHViKTtcbiAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoc3R1YiwgdW5yZXNvbHZlZEluaGVyaXRlZENsYXNzKTtcbiAgICAgICAgICAgIHJldHVybiBzdHViO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgY3JlYXRlT3JHZXRGYW1peEludGVyZmFjZVN0dWIodW5yZXNvbHZlZEluaGVyaXRlZEludGVyZmFjZTogRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKTogRmFtaXguSW50ZXJmYWNlIHtcbiAgICAgICAgLy8gbWFrZSBhIEZRTiBmb3IgdGhlIHN0dWJcbiAgICAgICAgY29uc3QgZnFuID0gRlFORnVuY3Rpb25zLmdldEZRTlVucmVzb2x2ZWRJbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlKHVucmVzb2x2ZWRJbmhlcml0ZWRJbnRlcmZhY2UpO1xuICAgICAgICBsb2dnZXIuZGVidWcoYGNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2VTdHViOiBmcW46ICR7ZnFufWApO1xuICAgICAgICBjb25zdCBmbXhJbnRlcmZhY2UgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUoZnFuKSBhcyBGYW1peC5JbnRlcmZhY2U7XG4gICAgICAgIGlmIChmbXhJbnRlcmZhY2UpIHtcbiAgICAgICAgICAgIHJldHVybiBmbXhJbnRlcmZhY2U7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCBzdHViID0gbmV3IEZhbWl4LkludGVyZmFjZSgpO1xuICAgICAgICAgICAgc3R1Yi5uYW1lID0gdW5yZXNvbHZlZEluaGVyaXRlZEludGVyZmFjZS5nZXRUZXh0KCk7XG4gICAgICAgICAgICBzdHViLmlzU3R1YiA9IHRydWU7XG4gICAgICAgICAgICBzdHViLmZ1bGx5UXVhbGlmaWVkTmFtZSA9IGZxbjtcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChzdHViKTtcbiAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoc3R1YiwgdW5yZXNvbHZlZEluaGVyaXRlZEludGVyZmFjZSk7XG4gICAgICAgICAgICByZXR1cm4gc3R1YjtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVGYW1peEltcG9ydENsYXVzZShpbXBvcnRlZEVudGl0eTogRmFtaXguTmFtZWRFbnRpdHksIGltcG9ydGluZ0VudGl0eTogRmFtaXguTW9kdWxlKSB7XG4gICAgICAgIGNvbnN0IGZteEltcG9ydENsYXVzZSA9IG5ldyBGYW1peC5JbXBvcnRDbGF1c2UoKTtcbiAgICAgICAgZm14SW1wb3J0Q2xhdXNlLmltcG9ydGVkRW50aXR5ID0gaW1wb3J0ZWRFbnRpdHk7XG4gICAgICAgIGZteEltcG9ydENsYXVzZS5pbXBvcnRpbmdFbnRpdHkgPSBpbXBvcnRpbmdFbnRpdHk7XG4gICAgICAgIGltcG9ydGluZ0VudGl0eS5hZGRPdXRnb2luZ0ltcG9ydChmbXhJbXBvcnRDbGF1c2UpO1xuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW1wb3J0Q2xhdXNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggaW1wb3J0IGNsYXVzZVxuICAgICAqIEBwYXJhbSBpbXBvcnRDbGF1c2VJbmZvIFRoZSBpbmZvcm1hdGlvbiBuZWVkZWQgdG8gY3JlYXRlIGEgRmFtaXggaW1wb3J0IGNsYXVzZVxuICAgICAqIEBwYXJhbSBpbXBvcnREZWNsYXJhdGlvbiBUaGUgaW1wb3J0IGRlY2xhcmF0aW9uXG4gICAgICogQHBhcmFtIGltcG9ydGVyIEEgc291cmNlIGZpbGUgd2hpY2ggaXMgYSBtb2R1bGVcbiAgICAgKiBAcGFyYW0gbW9kdWxlU3BlY2lmaWVyRmlsZVBhdGggVGhlIHBhdGggb2YgdGhlIG1vZHVsZSB3aGVyZSB0aGUgZXhwb3J0IGRlY2xhcmF0aW9uIGlzXG4gICAgICogQHBhcmFtIGltcG9ydEVsZW1lbnQgVGhlIGltcG9ydGVkIGVudGl0eVxuICAgICAqIEBwYXJhbSBpc0luRXhwb3J0cyBBIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgaW1wb3J0ZWQgZW50aXR5IGlzIGluIHRoZSBleHBvcnRzXG4gICAgICogQHBhcmFtIGlzRGVmYXVsdEV4cG9ydCBBIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgaW1wb3J0ZWQgZW50aXR5IGlzIGEgZGVmYXVsdCBleHBvcnRcbiAgICAgKi9cbiAgICBwdWJsaWMgb2xkQ3JlYXRlT3JHZXRGYW1peEltcG9ydENsYXVzZShpbXBvcnRDbGF1c2VJbmZvOiB7aW1wb3J0RGVjbGFyYXRpb24/OiBJbXBvcnREZWNsYXJhdGlvbiB8IEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uLCBpbXBvcnRlclNvdXJjZUZpbGU6IFNvdXJjZUZpbGUsIG1vZHVsZVNwZWNpZmllckZpbGVQYXRoOiBzdHJpbmcsIGltcG9ydEVsZW1lbnQ6IEltcG9ydFNwZWNpZmllciB8IElkZW50aWZpZXIsIGlzSW5FeHBvcnRzOiBib29sZWFuLCBpc0RlZmF1bHRFeHBvcnQ6IGJvb2xlYW59KTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHtpbXBvcnREZWNsYXJhdGlvbiwgaW1wb3J0ZXJTb3VyY2VGaWxlOiBpbXBvcnRlciwgbW9kdWxlU3BlY2lmaWVyRmlsZVBhdGgsIGltcG9ydEVsZW1lbnQsIGlzSW5FeHBvcnRzLCBpc0RlZmF1bHRFeHBvcnR9ID0gaW1wb3J0Q2xhdXNlSW5mbztcbiAgICAgICAgaWYgKGltcG9ydERlY2xhcmF0aW9uICYmIHRoaXMuZm14SW1wb3J0Q2xhdXNlTWFwLmhhcyhpbXBvcnREZWNsYXJhdGlvbikpIHtcbiAgICAgICAgICAgIGNvbnN0IHJJbXBvcnRDbGF1c2UgPSB0aGlzLmZteEltcG9ydENsYXVzZU1hcC5nZXQoaW1wb3J0RGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgaWYgKHJJbXBvcnRDbGF1c2UpIHsgXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBJbXBvcnQgY2xhdXNlICR7aW1wb3J0RWxlbWVudC5nZXRUZXh0KCl9IGFscmVhZHkgZXhpc3RzIGluIG1hcCwgc2tpcHBpbmcuYCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEltcG9ydCBjbGF1c2UgJHtpbXBvcnRFbGVtZW50LmdldFRleHQoKX0gaXMgbm90IGZvdW5kIGluIHRoZSBpbXBvcnQgY2xhdXNlIG1hcC5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIFxuICAgICAgICBsb2dnZXIuaW5mbyhgY3JlYXRpbmcgYSBuZXcgRmFtaXhJbXBvcnRDbGF1c2UgZm9yICR7aW1wb3J0RGVjbGFyYXRpb24/LmdldFRleHQoKX0gaW4gJHtpbXBvcnRlci5nZXRCYXNlTmFtZSgpfS5gKTtcbiAgICAgICAgY29uc3QgZm14SW1wb3J0Q2xhdXNlID0gbmV3IEZhbWl4LkltcG9ydENsYXVzZSgpO1xuICAgIFxuICAgICAgICBsZXQgaW1wb3J0ZWRFbnRpdHk6IEZhbWl4Lk5hbWVkRW50aXR5IHwgRmFtaXguU3RydWN0dXJhbEVudGl0eSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGltcG9ydGVkRW50aXR5TmFtZTogc3RyaW5nO1xuICAgIFxuICAgICAgICBjb25zdCBhYnNvbHV0ZVBhdGhQcm9qZWN0ID0gdGhpcy5mYW1peFJlcC5nZXRBYnNvbHV0ZVBhdGgoKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgubm9ybWFsaXplKG1vZHVsZVNwZWNpZmllckZpbGVQYXRoKTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBjcmVhdGVGYW1peEltcG9ydENsYXVzZTogYWJzb2x1dGVQYXRoOiAke2Fic29sdXRlUGF0aH1gKTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBjcmVhdGVGYW1peEltcG9ydENsYXVzZTogY29udmVydFRvUmVsYXRpdmVQYXRoOiAke3RoaXMuY29udmVydFRvUmVsYXRpdmVQYXRoKGFic29sdXRlUGF0aCwgYWJzb2x1dGVQYXRoUHJvamVjdCl9YCk7XG4gICAgICAgIGNvbnN0IHBhdGhJblByb2plY3Q6IHN0cmluZyA9IHRoaXMuY29udmVydFRvUmVsYXRpdmVQYXRoKGFic29sdXRlUGF0aCwgYWJzb2x1dGVQYXRoUHJvamVjdCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgY3JlYXRlRmFtaXhJbXBvcnRDbGF1c2U6IHBhdGhJblByb2plY3Q6ICR7cGF0aEluUHJvamVjdH1gKTtcbiAgICAgICAgbGV0IHBhdGhOYW1lID0gXCJ7XCIgKyBwYXRoSW5Qcm9qZWN0ICsgXCJ9LlwiO1xuICAgICAgICBsb2dnZXIuZGVidWcoYGNyZWF0ZUZhbWl4SW1wb3J0Q2xhdXNlOiBwYXRoTmFtZTogJHtwYXRoTmFtZX1gKTtcbiAgICBcbiAgICAgICAgaWYgKGltcG9ydERlY2xhcmF0aW9uIGluc3RhbmNlb2YgSW1wb3J0RGVjbGFyYXRpb24gXG4gICAgICAgICAgICAmJiBpbXBvcnRFbGVtZW50IGluc3RhbmNlb2YgSW1wb3J0U3BlY2lmaWVyKSB7IFxuICAgICAgICAgICAgICAgIGltcG9ydGVkRW50aXR5TmFtZSA9IGltcG9ydEVsZW1lbnQuZ2V0TmFtZSgpO1xuICAgICAgICAgICAgcGF0aE5hbWUgPSBwYXRoTmFtZSArIGltcG9ydGVkRW50aXR5TmFtZTtcbiAgICAgICAgICAgIGlmIChpc0luRXhwb3J0cykge1xuICAgICAgICAgICAgICAgIGltcG9ydGVkRW50aXR5ID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lKHBhdGhOYW1lKSBhcyBGYW1peC5OYW1lZEVudGl0eTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGV4cG9ydGVkIGVudGl0eTogJHtwYXRoTmFtZX1gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbXBvcnRlZEVudGl0eSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSBuZXcgRmFtaXguTmFtZWRFbnRpdHkoKTtcbiAgICAgICAgICAgICAgICBpbXBvcnRlZEVudGl0eS5uYW1lID0gaW1wb3J0ZWRFbnRpdHlOYW1lO1xuICAgICAgICAgICAgICAgIGlmICghaXNJbkV4cG9ydHMpIHtcbiAgICAgICAgICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkuaXNTdHViID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBDcmVhdGluZyBuYW1lZCBlbnRpdHkgJHtpbXBvcnRlZEVudGl0eU5hbWV9IGZvciBJbXBvcnRTcGVjaWZpZXIgJHtpbXBvcnRFbGVtZW50LmdldFRleHQoKX1gKTtcbiAgICAgICAgICAgICAgICBpbml0RlFOKGltcG9ydEVsZW1lbnQsIGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYEFzc2lnbmVkIEZRTiB0byBlbnRpdHk6ICR7aW1wb3J0ZWRFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lfWApO1xuICAgICAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGltcG9ydEVsZW1lbnQsIGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoaW1wb3J0ZWRFbnRpdHkpO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgQWRkZWQgZW50aXR5IHRvIHJlcG9zaXRvcnk6ICR7aW1wb3J0ZWRFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lfWApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKGltcG9ydERlY2xhcmF0aW9uIGluc3RhbmNlb2YgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5TmFtZSA9IGltcG9ydERlY2xhcmF0aW9uPy5nZXROYW1lKCk7XG4gICAgICAgICAgICBwYXRoTmFtZSA9IHBhdGhOYW1lICsgaW1wb3J0ZWRFbnRpdHlOYW1lO1xuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSBuZXcgRmFtaXguU3RydWN0dXJhbEVudGl0eSgpO1xuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkubmFtZSA9IGltcG9ydGVkRW50aXR5TmFtZTtcbiAgICAgICAgICAgIGluaXRGUU4oaW1wb3J0RGVjbGFyYXRpb24sIGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgQXNzaWduZWQgRlFOIHRvIEltcG9ydEVxdWFscyBlbnRpdHk6ICR7aW1wb3J0ZWRFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lfWApO1xuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoaW1wb3J0RWxlbWVudCwgaW1wb3J0ZWRFbnRpdHkpO1xuICAgICAgICAgICAgY29uc3QgYW55VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoJ2FueScsIHVuZGVmaW5lZCwgaW1wb3J0RGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgKGltcG9ydGVkRW50aXR5IGFzIEZhbWl4LlN0cnVjdHVyYWxFbnRpdHkpLmRlY2xhcmVkVHlwZSA9IGFueVR5cGU7XG4gICAgICAgIH0gZWxzZSB7ICBcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5TmFtZSA9IGltcG9ydEVsZW1lbnQuZ2V0VGV4dCgpO1xuICAgICAgICAgICAgcGF0aE5hbWUgPSBwYXRoTmFtZSArIChpc0RlZmF1bHRFeHBvcnQgPyBcImRlZmF1bHRFeHBvcnRcIiA6IFwibmFtZXNwYWNlRXhwb3J0XCIpO1xuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSBuZXcgRmFtaXguTmFtZWRFbnRpdHkoKTtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5Lm5hbWUgPSBpbXBvcnRlZEVudGl0eU5hbWU7XG4gICAgICAgICAgICBpbml0RlFOKGltcG9ydEVsZW1lbnQsIGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgQXNzaWduZWQgRlFOIHRvIGRlZmF1bHQvbmFtZXNwYWNlIGVudGl0eTogJHtpbXBvcnRlZEVudGl0eS5mdWxseVF1YWxpZmllZE5hbWV9YCk7XG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihpbXBvcnRFbGVtZW50LCBpbXBvcnRlZEVudGl0eSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFpc0luRXhwb3J0cykge1xuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgQWRkZWQgbm9uLWV4cG9ydGVkIGVudGl0eSB0byByZXBvc2l0b3J5OiAke2ltcG9ydGVkRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZX1gKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbXBvcnRlckZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oaW1wb3J0ZXIpO1xuICAgICAgICBjb25zdCBmbXhJbXBvcnRlciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShpbXBvcnRlckZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgRmFtaXguTW9kdWxlO1xuICAgICAgICBmbXhJbXBvcnRDbGF1c2UuaW1wb3J0aW5nRW50aXR5ID0gZm14SW1wb3J0ZXI7XG4gICAgICAgIGZteEltcG9ydENsYXVzZS5pbXBvcnRlZEVudGl0eSA9IGltcG9ydGVkRW50aXR5O1xuICAgICAgICBpZiAoaW1wb3J0RGVjbGFyYXRpb24gaW5zdGFuY2VvZiBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgZm14SW1wb3J0Q2xhdXNlLm1vZHVsZVNwZWNpZmllciA9IGltcG9ydERlY2xhcmF0aW9uPy5nZXRNb2R1bGVSZWZlcmVuY2UoKS5nZXRUZXh0KCkgYXMgc3RyaW5nO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZm14SW1wb3J0Q2xhdXNlLm1vZHVsZVNwZWNpZmllciA9IGltcG9ydERlY2xhcmF0aW9uPy5nZXRNb2R1bGVTcGVjaWZpZXJWYWx1ZSgpIGFzIHN0cmluZztcbiAgICAgICAgfVxuICAgIFxuICAgICAgICBsb2dnZXIuZGVidWcoYEltcG9ydENsYXVzZTogJHtmbXhJbXBvcnRDbGF1c2UuaW1wb3J0ZWRFbnRpdHk/Lm5hbWV9ICh0eXBlPSR7SGVscGVycy5nZXRTdWJUeXBlTmFtZShmbXhJbXBvcnRDbGF1c2UuaW1wb3J0ZWRFbnRpdHkpfSkgaW1wb3J0ZWQgYnkgJHtmbXhJbXBvcnRDbGF1c2UuaW1wb3J0aW5nRW50aXR5Py5uYW1lfWApO1xuICAgIFxuICAgICAgICBmbXhJbXBvcnRlci5hZGRPdXRnb2luZ0ltcG9ydChmbXhJbXBvcnRDbGF1c2UpO1xuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW1wb3J0Q2xhdXNlKTtcbiAgICBcbiAgICAgICAgaWYgKGltcG9ydERlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEltcG9ydENsYXVzZSwgaW1wb3J0RGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgdGhpcy5mbXhJbXBvcnRDbGF1c2VNYXAuc2V0KGltcG9ydERlY2xhcmF0aW9uLCBmbXhJbXBvcnRDbGF1c2UpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IEFycm93IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIGFycm93RXhwcmVzc2lvbiBBbiBFeHByZXNzaW9uXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSB2YXJpYWJsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4QXJyb3dGdW5jdGlvbihhcnJvd0V4cHJlc3Npb246IEV4cHJlc3Npb24sIGN1cnJlbnRDQzogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSApOiBGYW1peC5BcnJvd0Z1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Fycm93RnVuY3Rpb24ge1xuICAgICAgICBcbiAgICAgICAgbGV0IGZteEFycm93RnVuY3Rpb246IEZhbWl4LkFycm93RnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljQXJyb3dGdW5jdGlvbjtcbiAgICAgICAgY29uc3QgZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGFycm93RXhwcmVzc2lvbik7XG5cbiAgICAgICAgaWYgKCF0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmhhcyhmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSkpIHtcblxuICAgICAgICAgICAgY29uc3QgYXJyb3dGdW5jdGlvbiA9IGFycm93RXhwcmVzc2lvbi5hc0tpbmRPclRocm93KFN5bnRheEtpbmQuQXJyb3dGdW5jdGlvbik7XG5cbiAgICAgICAgICAgIGNvbnN0IGlzR2VuZXJpYyA9IGFycm93RnVuY3Rpb24uZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwO1xuXG4gICAgICAgICAgICBpZiAoaXNHZW5lcmljKSB7XG4gICAgICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbiA9IG5ldyBGYW1peC5QYXJhbWV0cmljQXJyb3dGdW5jdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbiA9IG5ldyBGYW1peC5BcnJvd0Z1bmN0aW9uKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIEdldCB0aGUgcGFyZW50IG9mIHRoZSBhcnJvdyBmdW5jdGlvbiAodGhlIHZhcmlhYmxlIGRlY2xhcmF0aW9uKVxuICAgICAgICAgICAgY29uc3QgcGFyZW50ID0gYXJyb3dGdW5jdGlvbi5nZXRQYXJlbnRJZktpbmQoU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgIGxldCBmdW5jdGlvbk5hbWUgPSAnKE5PX05BTUUpJztcblxuICAgICAgICAgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQgaW5zdGFuY2VvZiBWYXJpYWJsZURlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgLy8gR2V0IHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZVxuICAgICAgICAgICAgICAgIGZ1bmN0aW9uTmFtZSA9IHBhcmVudC5nZXROYW1lKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChmdW5jdGlvbk5hbWUpIHtcbiAgICAgICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLm5hbWUgPSBmdW5jdGlvbk5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLm5hbWUgPSBcImFub255bW91c1wiO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAvLyBTaWduYXR1cmUgb2YgYW4gYXJyb3cgZnVuY3Rpb24gaXMgKHBhcmFtZXRlcnMpID0+IHJldHVybl90eXBlXG4gICAgICAgICAgICBjb25zdCBwYXJhbWV0ZXJzU2lnbmF0dXJlID0gYXJyb3dGdW5jdGlvbi5nZXRQYXJhbWV0ZXJzKCkubWFwKHAgPT4gcC5nZXRUZXh0KCkpLmpvaW4oXCIsIFwiKTtcbiAgICAgICAgICAgIGNvbnN0IHJldHVyblR5cGVTaWduYXR1cmUgPSBhcnJvd0Z1bmN0aW9uLmdldFJldHVyblR5cGUoKS5nZXRUZXh0KCk7XG4gICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLnNpZ25hdHVyZSA9IGAoJHtwYXJhbWV0ZXJzU2lnbmF0dXJlfSkgPT4gJHtyZXR1cm5UeXBlU2lnbmF0dXJlfWA7XG4gICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLmN5Y2xvbWF0aWNDb21wbGV4aXR5ID0gY3VycmVudENDW2ZteEFycm93RnVuY3Rpb24ubmFtZV07XG5cbiAgICAgICAgICAgIGxldCBmdW5jdGlvblR5cGVOYW1lID0gdGhpcy5VTktOT1dOX1ZBTFVFO1xuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBmdW5jdGlvblR5cGVOYW1lID0gYXJyb3dGdW5jdGlvbi5nZXRSZXR1cm5UeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGA+IFdBUk5JTkc6IGdvdCBleGNlcHRpb24gJHtlcnJvcn0uIEZhaWxlZCB0byBnZXQgdXNhYmxlIG5hbWUgZm9yIHJldHVybiB0eXBlIG9mIGZ1bmN0aW9uOiAke2Z1bmN0aW9uTmFtZX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZm14VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoZnVuY3Rpb25UeXBlTmFtZSwgYXJyb3dGdW5jdGlvbi5nZXRSZXR1cm5UeXBlKCksIGFycm93RnVuY3Rpb24gYXMgdW5rbm93biBhcyBGdW5jdGlvbkRlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgIGZteEFycm93RnVuY3Rpb24uZGVjbGFyZWRUeXBlID0gZm14VHlwZTtcbiAgICAgICAgICAgIGZteEFycm93RnVuY3Rpb24ubnVtYmVyT2ZMaW5lc09mQ29kZSA9IGFycm93RnVuY3Rpb24uZ2V0RW5kTGluZU51bWJlcigpIC0gYXJyb3dGdW5jdGlvbi5nZXRTdGFydExpbmVOdW1iZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBhcnJvd0Z1bmN0aW9uLmdldFBhcmFtZXRlcnMoKTtcbiAgICAgICAgICAgIGZteEFycm93RnVuY3Rpb24ubnVtYmVyT2ZQYXJhbWV0ZXJzID0gcGFyYW1ldGVycy5sZW5ndGg7XG4gICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLm51bWJlck9mU3RhdGVtZW50cyA9IGFycm93RnVuY3Rpb24uZ2V0U3RhdGVtZW50cygpLmxlbmd0aDtcbiAgICAgICAgICAgIGluaXRGUU4oYXJyb3dFeHByZXNzaW9uIGFzIHVua25vd24gYXMgVFNNb3JwaE9iamVjdFR5cGUsIGZteEFycm93RnVuY3Rpb24pO1xuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoYXJyb3dFeHByZXNzaW9uIGFzIHVua25vd24gYXMgVFNNb3JwaE9iamVjdFR5cGUsIGZteEFycm93RnVuY3Rpb24pO1xuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEFycm93RnVuY3Rpb24pO1xuICAgICAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhBcnJvd0Z1bmN0aW9uLGFycm93RnVuY3Rpb24gYXMgdW5rbm93biBhcyBUU01vcnBoT2JqZWN0VHlwZSk7XG4gICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSwgZm14QXJyb3dGdW5jdGlvbik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uID0gdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5nZXQoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpIGFzIEZhbWl4LkFycm93RnVuY3Rpb247XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZm14QXJyb3dGdW5jdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggY29uY3JldGlzYXRpb25cbiAgICAgKiBAcGFyYW0gY2xzIEEgY2xhc3NcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGNvbmNyZXRpc2F0aW9uXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb24oY29uRW50aXR5IDogRmFtaXguUGFyYW1ldHJpY0NsYXNzIHwgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSB8IEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbiB8IEZhbWl4LlBhcmFtZXRyaWNNZXRob2QgLGdlbkVudGl0eSA6IEZhbWl4LlBhcmFtZXRyaWNDbGFzcyB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UgfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kKTogRmFtaXguQ29uY3JldGlzYXRpb24ge1xuICAgICAgICBcbiAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb24gOiBGYW1peC5Db25jcmV0aXNhdGlvbiA9IG5ldyBGYW1peC5Db25jcmV0aXNhdGlvbigpOyAgICAgICAgICAgICAgXG4gICAgICAgIFxuICAgICAgICBmbXhDb25jcmV0aXNhdGlvbi5jb25jcmV0ZUVudGl0eSA9IGNvbkVudGl0eTtcbiAgICAgICAgZm14Q29uY3JldGlzYXRpb24uZ2VuZXJpY0VudGl0eSA9IGdlbkVudGl0eTtcbiAgICAgICAgLy8gdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhDb25jcmV0aXNhdGlvbixudWxsKTtcbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteENvbmNyZXRpc2F0aW9uKTtcbiAgICAgICAgLy8gY29uc3QgcGFyYW1ldGVyQ29uY3JldGlzYXRpb24gPSB0aGlzLmNyZWF0ZUZhbWl4UGFyYW1ldGVyQ29uY3JldGlzYXRpb24oZm14Q29uY3JldGlzYXRpb24pO1xuICAgICAgICAgICAgXG4gICAgICAgIHJldHVybiBmbXhDb25jcmV0aXNhdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggY29uY3JldGlzYXRpb25cbiAgICAgKiBAcGFyYW0gY29uY3JldGlzYXRpb24gQSBGYW1peENvbmNyZXRpc2F0aW9uXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBQYXJhbWV0ZXJDb25jcmVzdGlzYXRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbihjb25jcmV0aXNhdGlvbjogRmFtaXguQ29uY3JldGlzYXRpb24pOiBGYW1peC5QYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiB8IHVuZGVmaW5lZHtcbiAgICAgICAgY29uc3QgY29uQ2xhc3MgPSBjb25jcmV0aXNhdGlvbi5jb25jcmV0ZUVudGl0eTtcbiAgICAgICAgY29uc3QgZ2VuQ2xhc3MgPSBjb25jcmV0aXNhdGlvbi5nZW5lcmljRW50aXR5O1xuICAgICAgICBsb2dnZXIuZGVidWcoYENyZWF0aW5nIHBhcmFtZXRlciBjb25jcmV0aXNhdGlvbiBiZXR3ZWVuICR7Y29uQ2xhc3MuZnVsbHlRdWFsaWZpZWROYW1lfSBhbmQgJHtnZW5DbGFzcy5mdWxseVF1YWxpZmllZE5hbWV9YCk7XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlckNvbmNyZXRpc2F0aW9ucyA9IHRoaXMuZmFtaXhSZXAuX2dldEFsbEVudGl0aWVzV2l0aFR5cGUoXCJQYXJhbWV0ZXJDb25jcmV0aXNhdGlvblwiKSBhcyBTZXQ8RmFtaXguUGFyYW1ldGVyQ29uY3JldGlzYXRpb24+O1xuICAgICAgICBjb25zdCBjb25jcmV0ZVBhcmFtZXRlcnMgPSBjb25DbGFzcy5jb25jcmV0ZVBhcmFtZXRlcnM7XG4gICAgICAgIGNvbnN0IGdlbmVyaWNQYXJhbWV0ZXJzID0gZ2VuQ2xhc3MuZ2VuZXJpY1BhcmFtZXRlcnM7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBjb25DbGFzc1R5cGVQYXJhbWV0ZXJzSXRlcmF0b3IgPSBjb25jcmV0ZVBhcmFtZXRlcnMudmFsdWVzKCk7XG4gICAgICAgIGNvbnN0IGdlbkNsYXNzVHlwZVBhcmFtZXRlcnNJdGVyYXRvciA9IGdlbmVyaWNQYXJhbWV0ZXJzLnZhbHVlcygpO1xuICAgICAgICBsZXQgZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24gOiBGYW1peC5QYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdlbmVyaWNQYXJhbWV0ZXJzLnNpemU7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgY29uQ2xhc3NUeXBlUGFyYW1ldGVyID0gY29uQ2xhc3NUeXBlUGFyYW1ldGVyc0l0ZXJhdG9yLm5leHQoKS52YWx1ZSBhcyBGYW1peC5QYXJhbWV0ZXJUeXBlO1xuICAgICAgICAgICAgY29uc3QgZ2VuQ2xhc3NUeXBlUGFyYW1ldGVyID0gZ2VuQ2xhc3NUeXBlUGFyYW1ldGVyc0l0ZXJhdG9yLm5leHQoKS52YWx1ZSBhcyBGYW1peC5QYXJhbWV0ZXJUeXBlO1xuICAgICAgICAgICAgbGV0IGNyZWF0ZVBhcmFtZXRlckNvbmNyZXRpc2F0aW9uIDogYm9vbGVhbiA9IHRydWU7XG4gICAgICAgICAgICBpZihjb25DbGFzc1R5cGVQYXJhbWV0ZXIgJiYgZ2VuQ2xhc3NUeXBlUGFyYW1ldGVyICYmIGNvbkNsYXNzVHlwZVBhcmFtZXRlci5uYW1lICE9IGdlbkNsYXNzVHlwZVBhcmFtZXRlci5uYW1lKXtcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJDb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgocGFyYW0gOiBGYW1peC5QYXJhbWV0ZXJDb25jcmV0aXNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29uQ2xhc3NUeXBlUGFyYW1ldGVyLm5hbWUgPT0gcGFyYW0uY29uY3JldGVQYXJhbWV0ZXIubmFtZSAmJiBnZW5DbGFzc1R5cGVQYXJhbWV0ZXIubmFtZSA9PSBwYXJhbS5nZW5lcmljUGFyYW1ldGVyLm5hbWUpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVBhcmFtZXRlckNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiA9IHBhcmFtO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgaWYgKGNyZWF0ZVBhcmFtZXRlckNvbmNyZXRpc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uID0gbmV3IEZhbWl4LlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uLmdlbmVyaWNQYXJhbWV0ZXIgPSBnZW5DbGFzc1R5cGVQYXJhbWV0ZXI7XG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uLmNvbmNyZXRlUGFyYW1ldGVyID0gY29uQ2xhc3NUeXBlUGFyYW1ldGVyO1xuICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbi5hZGRDb25jcmV0aXNhdGlvbihjb25jcmV0aXNhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24sbnVsbCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiB3YXMgdW5kZWZpbmVkIGZvciBjb25jcmV0aXNhdGlvbiB3aXRoIGdlbmVyaWMgcGFyYW1ldGVyICR7Z2VuQ2xhc3NUeXBlUGFyYW1ldGVyLm5hbWV9IGFuZCBjb25jcmV0ZSBwYXJhbWV0ZXIgJHtjb25DbGFzc1R5cGVQYXJhbWV0ZXIubmFtZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbi5hZGRDb25jcmV0aXNhdGlvbihjb25jcmV0aXNhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiB3YXMgdW5kZWZpbmVkIGZvciBjb25jcmV0aXNhdGlvbiB3aXRoIGNvbmNyZXRlIGVudGl0eSAke2NvbkNsYXNzLmZ1bGx5UXVhbGlmaWVkTmFtZX0gYW5kIGdlbmVyaWMgZW50aXR5ICR7Z2VuQ2xhc3MuZnVsbHlRdWFsaWZpZWROYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbjtcblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvbiBiZXR3ZWVuIHR3byBjbGFzc2VzIG9yIHR3byBpbnRlcmZhY2VzXG4gICAgICogQHBhcmFtIGVsZW1lbnQgQSBjbGFzcyBvciBhbiBJbnRlcmZhY2VcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkNsYXNzT3JJbnRlcmZhY2VTcGVjaWFsaXNhdGlvbihlbGVtZW50OiBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24pe1xuICAgICAgICBcbiAgICAgICAgY29uc3Qgc3VwZXJFbnRpdHkgPSBlbGVtZW50LmdldEV4dGVuZHMoKTtcbiAgICAgICAgbGV0IHN1cGVyRW50aXR5QXJyYXk7XG4gICAgICAgIGlmIChzdXBlckVudGl0eSl7XG4gICAgICAgICAgICBzdXBlckVudGl0eUFycmF5ID0gQXJyYXkuaXNBcnJheShzdXBlckVudGl0eSkgPyBzdXBlckVudGl0eSA6IFtzdXBlckVudGl0eV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN1cGVyRW50aXR5QXJyYXkgJiYgc3VwZXJFbnRpdHlBcnJheS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzdXBlckVudGl0eUFycmF5LmZvckVhY2goZW50aXR5ID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgZW50aXR5SXNHZW5lcmljO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN1cGVyRW50aXR5U3ltYm9sID0gZW50aXR5LmdldEV4cHJlc3Npb24oKS5nZXRTeW1ib2xPclRocm93KCk7XG4gICAgICAgICAgICAgICAgbGV0IHN1cGVyRW50aXR5RGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgaWYgKHN1cGVyRW50aXR5IGluc3RhbmNlb2YgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1cGVyRW50aXR5RGVjbGFyYXRpb24gPSBzdXBlckVudGl0eVN5bWJvbC5nZXREZWNsYXJhdGlvbnMoKVswXS5hc0tpbmQodHMuU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdXBlckVudGl0eURlY2xhcmF0aW9uID0gc3VwZXJFbnRpdHlTeW1ib2wuZ2V0RGVjbGFyYXRpb25zKClbMF0uYXNLaW5kKHRzLlN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3VwZXJFbnRpdHlEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBlbnRpdHlJc0dlbmVyaWMgPSBzdXBlckVudGl0eURlY2xhcmF0aW9uLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGVudGl0eUlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgRW50aXR5RGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgICAgIGxldCBnZW5FbnRpdHk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdXBlckVudGl0eSBpbnN0YW5jZW9mIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgRW50aXR5RGVjbGFyYXRpb24gPSBlbnRpdHkuZ2V0RXhwcmVzc2lvbigpLmdldFN5bWJvbCgpPy5nZXREZWNsYXJhdGlvbnMoKVswXSBhcyBDbGFzc0RlY2xhcmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2VuRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoRW50aXR5RGVjbGFyYXRpb24pIGFzIEZhbWl4LlBhcmFtZXRyaWNDbGFzcztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEVudGl0eURlY2xhcmF0aW9uID0gZW50aXR5LmdldEV4cHJlc3Npb24oKS5nZXRTeW1ib2woKT8uZ2V0RGVjbGFyYXRpb25zKClbMF0gYXMgSW50ZXJmYWNlRGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBnZW5FbnRpdHkgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoRW50aXR5RGVjbGFyYXRpb24pIGFzIEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gRW50aXR5RGVjbGFyYXRpb24uZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAoKHBhcmFtKSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhcmdzID0gZWxlbWVudC5nZXRIZXJpdGFnZUNsYXVzZXMoKVswXS5nZXRUeXBlTm9kZXMoKVswXS5nZXRUeXBlQXJndW1lbnRzKCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvblBhcmFtcyA9IGVsZW1lbnQuZ2V0SGVyaXRhZ2VDbGF1c2VzKClbMF0uZ2V0VHlwZU5vZGVzKClbMF0uZ2V0VHlwZUFyZ3VtZW50cygpLm1hcCgocGFyYW0pID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSGVscGVycy5hcnJheXNBcmVFcXVhbChjb25QYXJhbXMsZ2VuUGFyYW1zKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGdlbkVudGl0eSxFbnRpdHlEZWNsYXJhdGlvbixhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbmNyZXRpc2F0aW9ucyA9IHRoaXMuZmFtaXhSZXAuX2dldEFsbEVudGl0aWVzV2l0aFR5cGUoXCJDb25jcmV0aXNhdGlvblwiKSBhcyBTZXQ8RmFtaXguQ29uY3JldGlzYXRpb24+O1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNyZWF0ZUNvbmNyZXRpc2F0aW9uIDogYm9vbGVhbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdlbkVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uYy5nZW5lcmljRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSAmJiBjb25jLmNvbmNyZXRlRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25FbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lKXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ29uY3JldGlzYXRpb24gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWF0ZUNvbmNyZXRpc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb24gOiBGYW1peC5Db25jcmV0aXNhdGlvbiA9IHRoaXMuY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbihjb25FbnRpdHksZ2VuRW50aXR5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IFRoaXMgZnVuY3Rpb24gc2VlbXMgdW5maW5pc2hlZFxuICAgIH0gICAgXG4gICAgXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggY29uY3JldGlzYXRpb24gYmV0d2VlbiBhIGNsYXNzIGFuZCBpdHMgaW5zdGFuY2lhdGlvbnNcbiAgICAgKiBAcGFyYW0gY2xzIEEgY2xhc3NcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkdlbmVyaWNJbnN0YW50aWF0aW9uKGNsczogQ2xhc3NEZWNsYXJhdGlvbil7XG4gICAgICAgXG4gICAgICAgIGNvbnN0IGlzR2VuZXJpYyA9IGNscy5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDA7XG4gICAgICAgIGlmIChpc0dlbmVyaWMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlcyA9IGNscy5nZXRTb3VyY2VGaWxlKCkuZ2V0RGVzY2VuZGFudHNPZktpbmQodHMuU3ludGF4S2luZC5OZXdFeHByZXNzaW9uKVxuICAgICAgICAgICAgICAgIC5maWx0ZXIobmV3RXhwciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBuZXdFeHByLmdldEV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4cHJlc3Npb24uZ2V0VGV4dCgpID09PSBjbHMuZ2V0TmFtZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGluc3RhbmNlcy5mb3JFYWNoKGluc3RhbmNlID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnN0YW5jZUlzR2VuZXJpYyA9IGluc3RhbmNlLmdldFR5cGVBcmd1bWVudHMoKS5sZW5ndGggPiAwO1xuICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZUlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25QYXJhbXMgPSBpbnN0YW5jZS5nZXRUeXBlQXJndW1lbnRzKCkubWFwKChwYXJhbSkgPT4gcGFyYW0uZ2V0VGV4dCgpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2VuRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoY2xzKSBhcyBGYW1peC5QYXJhbWV0cmljQ2xhc3M7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdlblBhcmFtcyA9IGNscy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCgocGFyYW0pID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSGVscGVycy5hcnJheXNBcmVFcXVhbChjb25QYXJhbXMsZ2VuUGFyYW1zKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGdlbkVudGl0eSxjbHMsaW5zdGFuY2UuZ2V0VHlwZUFyZ3VtZW50cygpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbmNyZXRpc2F0aW9ucyA9IHRoaXMuZmFtaXhSZXAuX2dldEFsbEVudGl0aWVzV2l0aFR5cGUoXCJDb25jcmV0aXNhdGlvblwiKSBhcyBTZXQ8RmFtaXguQ29uY3JldGlzYXRpb24+O1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNyZWF0ZUNvbmNyZXRpc2F0aW9uIDogYm9vbGVhbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdlbkVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uYy5nZW5lcmljRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSAmJiBjb25jLmNvbmNyZXRlRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25FbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lKXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ29uY3JldGlzYXRpb24gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWF0ZUNvbmNyZXRpc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb24gOiBGYW1peC5Db25jcmV0aXNhdGlvbiA9IHRoaXMuY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbihjb25FbnRpdHksZ2VuRW50aXR5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IFRoaXMgZnVuY3Rpb24gc2VlbXMgdW5maW5pc2hlZFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvbiBiZXR3ZWVuIGEgY2xhc3MgYW5kIGl0cyBpbnN0YW5jaWF0aW9uc1xuICAgICAqIEBwYXJhbSBmdW5jIEEgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkZ1bmN0aW9uSW5zdGFudGlhdGlvbihlbGVtZW50OiBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgTWV0aG9kRGVjbGFyYXRpb24pe1xuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgaWYgKGlzR2VuZXJpYykge1xuICAgICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpLm1hcChwYXJhbSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgY29uc3QgdXNlcyA9IGVsZW1lbnQuZmluZFJlZmVyZW5jZXNBc05vZGVzKCk7ICAgIFxuICAgICAgICAgICAgdXNlcy5mb3JFYWNoKHVzYWdlID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgY3VycmVudE5vZGU6IFRzTW9ycGhOb2RlIHwgdW5kZWZpbmVkID0gdXNhZ2U7XG5cbiAgICAgICAgICAgICAgICB3aGlsZSAoY3VycmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGN1cnJlbnROb2RlLmdldEtpbmQoKSA9PT0gU3ludGF4S2luZC5DYWxsRXhwcmVzc2lvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY2FsbEV4cHJlc3Npb24gPSBjdXJyZW50Tm9kZS5hc0tpbmQoU3ludGF4S2luZC5DYWxsRXhwcmVzc2lvbik7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWNhbGxFeHByZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBDYWxsRXhwcmVzc2lvbiBub3QgZm91bmQgZm9yICR7Y3VycmVudE5vZGUuZ2V0VGV4dCgpfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgaW5zdGFuY2VJc0dlbmVyaWMgPSBjYWxsRXhwcmVzc2lvbi5nZXRUeXBlQXJndW1lbnRzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZUlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBjYWxsRXhwcmVzc2lvbi5nZXRUeXBlQXJndW1lbnRzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uUGFyYW1zID0gY2FsbEV4cHJlc3Npb24uZ2V0VHlwZUFyZ3VtZW50cygpLm1hcChwYXJhbSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghSGVscGVycy5hcnJheXNBcmVFcXVhbChjb25QYXJhbXMsZ2VuUGFyYW1zKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZ2VuRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZWxlbWVudCBpbnN0YW5jZW9mIEZ1bmN0aW9uRGVjbGFyYXRpb24pe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuRWxlbWVudCA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peEZ1bmN0aW9uKGVsZW1lbnQsIHt9KSBhcyBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb247XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5FbGVtZW50ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4TWV0aG9kKGVsZW1lbnQsIHt9KSBhcyBGYW1peC5QYXJhbWV0cmljTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbmNFbGVtZW50ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGdlbkVsZW1lbnQsZWxlbWVudCxhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uY3JldGlzYXRpb25zID0gdGhpcy5mYW1peFJlcC5fZ2V0QWxsRW50aXRpZXNXaXRoVHlwZShcIkNvbmNyZXRpc2F0aW9uXCIpIGFzIFNldDxGYW1peC5Db25jcmV0aXNhdGlvbj47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjcmVhdGVDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2VuRWxlbWVudC5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uYy5nZW5lcmljRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSAmJiBjb25jLmNvbmNyZXRlRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25jRWxlbWVudC5mdWxseVF1YWxpZmllZE5hbWUpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWF0ZUNvbmNyZXRpc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmbXhDb25jcmV0aXNhdGlvbiA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gdGhpcy5jcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbmNFbGVtZW50LGdlbkVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gUmVtb250ZXIgw6AgbCfDqWzDqW1lbnQgcGFyZW50ICh1dGlsZSBzaSBsZSBuxZN1ZCBkZSByw6lmw6lyZW5jZSBlc3QgdW4gZW5mYW50KVxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLmdldFBhcmVudCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uIGJldHdlZW4gYSBjbGFzcyBhbmQgYW4gaW50ZXJmYWNlXG4gICAgICogQHBhcmFtIGNscyBBIGNsYXNzXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb25JbnRlcmZhY2VDbGFzcyhjbHM6IENsYXNzRGVjbGFyYXRpb24pe1xuICAgIFxuICAgICAgICBjb25zdCBzdXBlckludGVyZmFjZXMgPSBjbHMuZ2V0SW1wbGVtZW50cygpO1xuICAgICAgICBzdXBlckludGVyZmFjZXMuZm9yRWFjaChpbnRlcmZhY2VUeXBlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGludGVyZmFjZUlzR2VuZXJpYyA9IGludGVyZmFjZVR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpLmxlbmd0aD4wO1xuICAgICAgICAgICAgaWYgKGludGVyZmFjZUlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGludGVyZmFjZURlY2xhcmF0aW9uID0gaW50ZXJmYWNlVHlwZS5nZXRFeHByZXNzaW9uKCkuZ2V0U3ltYm9sKCk/LmdldERlY2xhcmF0aW9ucygpWzBdIGFzIEludGVyZmFjZURlY2xhcmF0aW9uO1xuICAgICAgICAgICAgICAgIGNvbnN0IGdlblBhcmFtcyA9IGludGVyZmFjZURlY2xhcmF0aW9uLmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKChwYXJhbSkgPT4gcGFyYW0uZ2V0VGV4dCgpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBjb25QYXJhbXMgPSBjbHMuZ2V0SGVyaXRhZ2VDbGF1c2VzKClbMF0uZ2V0VHlwZU5vZGVzKClbMF0uZ2V0VHlwZUFyZ3VtZW50cygpLm1hcCgocGFyYW0pID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICAgICAgY29uc3QgYXJncyA9IGNscy5nZXRIZXJpdGFnZUNsYXVzZXMoKVswXS5nZXRUeXBlTm9kZXMoKVswXS5nZXRUeXBlQXJndW1lbnRzKCk7XG4gICAgICAgICAgICAgICAgaWYgKCFIZWxwZXJzLmFycmF5c0FyZUVxdWFsKGNvblBhcmFtcyxnZW5QYXJhbXMpKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdlbkludGVyZmFjZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peEludGVyZmFjZShpbnRlcmZhY2VEZWNsYXJhdGlvbikgYXMgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uSW50ZXJmYWNlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGdlbkludGVyZmFjZSxpbnRlcmZhY2VEZWNsYXJhdGlvbixhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uY3JldGlzYXRpb25zID0gdGhpcy5mYW1peFJlcC5fZ2V0QWxsRW50aXRpZXNXaXRoVHlwZShcIkNvbmNyZXRpc2F0aW9uXCIpIGFzIFNldDxGYW1peC5Db25jcmV0aXNhdGlvbj47XG4gICAgICAgICAgICAgICAgICAgIGxldCBjcmVhdGVDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2VuSW50ZXJmYWNlLmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25jLmdlbmVyaWNFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lICYmIGNvbmMuY29uY3JldGVFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lID09IGNvbkludGVyZmFjZS5mdWxseVF1YWxpZmllZE5hbWUpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIGlmIChjcmVhdGVDb25jcmV0aXNhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb24gOiBGYW1peC5Db25jcmV0aXNhdGlvbiA9IHRoaXMuY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbihjb25JbnRlcmZhY2UsZ2VuSW50ZXJmYWNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uIGJldHdlZW4gYW4gaW50ZXJmYWNlIGFuZCBhIFR5cGVcbiAgICAgKiBAcGFyYW0gZWxlbWVudCBBIHZhcmlhYmxlIG9yIGEgZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gaW50ZXIgQW4gaW50ZXJmYWNlXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb25UeXBlSW5zdGFuY2lhdGlvbihlbGVtZW50OiBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IENsYXNzRGVjbGFyYXRpb24pIHtcblxuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgaWYgKGlzR2VuZXJpYykge1xuICAgICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpLm1hcChwYXJhbSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgY29uc3QgdXNlcyA9IGVsZW1lbnQuZmluZFJlZmVyZW5jZXNBc05vZGVzKCk7XG4gICAgICAgICAgICB1c2VzLmZvckVhY2godXNlID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgcGFyZW50Tm9kZSA9IHVzZS5nZXRQYXJlbnQoKTtcbiAgICAgICAgICAgICAgICB3aGlsZSAocGFyZW50Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAocGFyZW50Tm9kZS5nZXRLaW5kKCkgPT09IFN5bnRheEtpbmQuVHlwZVJlZmVyZW5jZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZVJlZmVyZW5jZU5vZGUgPSBwYXJlbnROb2RlLmFzS2luZChTeW50YXhLaW5kLlR5cGVSZWZlcmVuY2UpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCF0eXBlUmVmZXJlbmNlTm9kZSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgVHlwZVJlZmVyZW5jZU5vZGUgbm90IGZvdW5kIGZvciAke3BhcmVudE5vZGUuZ2V0VGV4dCgpfWApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgdHlwZVJlZmVyZW5jZU5vZGVJc0dlbmVyaWMgPSB0eXBlUmVmZXJlbmNlTm9kZS5nZXRUeXBlQXJndW1lbnRzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICh0eXBlUmVmZXJlbmNlTm9kZUlzR2VuZXJpYykgeyB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcmdzID0gdHlwZVJlZmVyZW5jZU5vZGUuZ2V0VHlwZUFyZ3VtZW50cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uUGFyYW1zID0gdHlwZVJlZmVyZW5jZU5vZGUuZ2V0VHlwZUFyZ3VtZW50cygpLm1hcChwYXJhbSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFIZWxwZXJzLmFycmF5c0FyZUVxdWFsKGNvblBhcmFtcywgZ2VuUGFyYW1zKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBnZW5FbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChlbGVtZW50IGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5FbGVtZW50ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoZWxlbWVudCkgYXMgRmFtaXguUGFyYW1ldHJpY0NsYXNzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbkVsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoZWxlbWVudCkgYXMgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uY0VsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhDb25jcmV0ZUVsZW1lbnQoZ2VuRWxlbWVudCwgZWxlbWVudCwgYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uY3JldGlzYXRpb25zID0gdGhpcy5mYW1peFJlcC5fZ2V0QWxsRW50aXRpZXNXaXRoVHlwZShcIkNvbmNyZXRpc2F0aW9uXCIpIGFzIFNldDxGYW1peC5Db25jcmV0aXNhdGlvbj47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNyZWF0ZUNvbmNyZXRpc2F0aW9uOiBib29sZWFuID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYzogRmFtaXguQ29uY3JldGlzYXRpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdlbkVsZW1lbnQuZnVsbHlRdWFsaWZpZWROYW1lID09IGNvbmMuZ2VuZXJpY0VudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgJiYgY29uYy5jb25jcmV0ZUVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uY0VsZW1lbnQuZnVsbHlRdWFsaWZpZWROYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb25jcmV0aXNhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3JlYXRlQ29uY3JldGlzYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb246IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gdGhpcy5jcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbmNFbGVtZW50LCBnZW5FbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBwYXJlbnROb2RlID0gcGFyZW50Tm9kZS5nZXRQYXJlbnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBjb252ZXJ0VG9SZWxhdGl2ZVBhdGgoYWJzb2x1dGVQYXRoOiBzdHJpbmcsIGFic29sdXRlUGF0aFByb2plY3Q6IHN0cmluZykge1xuICAgICAgICBsb2dnZXIuZGVidWcoYGNvbnZlcnRUb1JlbGF0aXZlUGF0aDogYWJzb2x1dGVQYXRoOiAnJHthYnNvbHV0ZVBhdGh9JywgYWJzb2x1dGVQYXRoUHJvamVjdDogJyR7YWJzb2x1dGVQYXRoUHJvamVjdH0nYCk7XG4gICAgICAgIGlmIChhYnNvbHV0ZVBhdGguc3RhcnRzV2l0aChhYnNvbHV0ZVBhdGhQcm9qZWN0KSkge1xuICAgICAgICAgICAgcmV0dXJuIGFic29sdXRlUGF0aC5yZXBsYWNlKGFic29sdXRlUGF0aFByb2plY3QsIFwiXCIpLnNsaWNlKDEpO1xuICAgICAgICB9IGVsc2UgaWYgKGFic29sdXRlUGF0aC5zdGFydHNXaXRoKFwiL1wiKSkge1xuICAgICAgICAgICAgcmV0dXJuIGFic29sdXRlUGF0aC5zbGljZSgxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJldHVybiBhYnNvbHV0ZVBhdGg7XG4gICAgICAgIH1cbiAgICB9XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBpc1ByaW1pdGl2ZVR5cGUodHlwZU5hbWU6IHN0cmluZykge1xuICAgIHJldHVybiB0eXBlTmFtZSA9PT0gXCJudW1iZXJcIiB8fFxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJzdHJpbmdcIiB8fFxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJib29sZWFuXCIgfHxcbiAgICAgICAgdHlwZU5hbWUgPT09IFwiYmlnaW50XCIgfHxcbiAgICAgICAgdHlwZU5hbWUgPT09IFwic3ltYm9sXCIgfHxcbiAgICAgICAgdHlwZU5hbWUgPT09IFwidW5pcXVlIHN5bWJvbFwiIHx8XG4gICAgICAgIHR5cGVOYW1lID09PSBcInVuZGVmaW5lZFwiIHx8XG4gICAgICAgIHR5cGVOYW1lID09PSBcIm51bGxcIiB8fFxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJhbnlcIiB8fFxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJ1bmtub3duXCIgfHxcbiAgICAgICAgdHlwZU5hbWUgPT09IFwibmV2ZXJcIiB8fFxuICAgICAgICB0eXBlTmFtZSA9PT0gXCJ2b2lkXCI7XG59XG5cbmZ1bmN0aW9uIGluaXRGUU4oc291cmNlRWxlbWVudDogVFNNb3JwaE9iamVjdFR5cGUsIGZhbWl4RWxlbWVudDogRmFtaXguU291cmNlZEVudGl0eSkge1xuICAgIC8vIGhhbmRsZSBzcGVjaWFsIGNhc2VzIHdoZXJlIGFuIGVsZW1lbnQgaXMgYSBUeXBlIC0tIG5lZWQgdG8gY2hhbmdlIGl0cyBuYW1lXG4gICAgaWYgKGZhbWl4RWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LlR5cGUgJiYgIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSAmJiBpc1R5cGVDb250ZXh0KHNvdXJjZUVsZW1lbnQpKSB7XG4gICAgICAgIGxldCBmcW4gPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKHNvdXJjZUVsZW1lbnQpO1xuICAgICAgICAvLyB1c2luZyByZWdleCwgcmVwbGFjZSBbYmxhaF0gd2l0aCBbYmxhaFR5cGVdXG4gICAgICAgIGZxbiA9IGZxbi5yZXBsYWNlKC9cXFsoW15cXF1dKylcXF0vZywgXCJbJDFUeXBlXVwiKTtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiU2V0dGluZyBmdWxseSBxdWFsaWZpZWQgbmFtZSBmb3IgXCIgKyBmYW1peEVsZW1lbnQuZ2V0SlNPTigpICsgXCIgdG8gXCIgKyBmcW4pO1xuICAgICAgICBmYW1peEVsZW1lbnQuZnVsbHlRdWFsaWZpZWROYW1lID0gZnFuO1xuICAgICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIGNhdGNoIGFsbCAoZXhjZXB0IGNvbW1lbnRzKVxuICAgIGlmICghKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBDb21tZW50UmFuZ2UpKSB7XG4gICAgICAgIGNvbnN0IGZxbiA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oc291cmNlRWxlbWVudCk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhcIlNldHRpbmcgZnVsbHkgcXVhbGlmaWVkIG5hbWUgZm9yIFwiICsgZmFtaXhFbGVtZW50LmdldEpTT04oKSArIFwiIHRvIFwiICsgZnFuKTtcbiAgICAgICAgKGZhbWl4RWxlbWVudCBhcyBGYW1peC5OYW1lZEVudGl0eSkuZnVsbHlRdWFsaWZpZWROYW1lID0gZnFuO1xuICAgIH0gXG59XG5cblxuZnVuY3Rpb24gaXNUeXBlQ29udGV4dChzb3VyY2VFbGVtZW50OiBUU01vcnBoT2JqZWN0VHlwZSk6IGJvb2xlYW4ge1xuICAgIC8vIEp1c3Qga2VlcCB0aGUgZXhpc3RpbmcgU3ludGF4S2luZCBzZXQgYXMgaXQgaXNcbiAgICBjb25zdCB0eXBlQ29udGV4dEtpbmRzID0gbmV3IFNldChbXG4gICAgICAgIFN5bnRheEtpbmQuQ29uc3RydWN0b3IsXG4gICAgICAgIFN5bnRheEtpbmQuTWV0aG9kRGVjbGFyYXRpb24sXG4gICAgICAgIFN5bnRheEtpbmQuRnVuY3Rpb25EZWNsYXJhdGlvbixcbiAgICAgICAgU3ludGF4S2luZC5GdW5jdGlvbkV4cHJlc3Npb24sXG4gICAgICAgIFN5bnRheEtpbmQuQXJyb3dGdW5jdGlvbixcbiAgICAgICAgU3ludGF4S2luZC5QYXJhbWV0ZXIsXG4gICAgICAgIFN5bnRheEtpbmQuVmFyaWFibGVEZWNsYXJhdGlvbixcbiAgICAgICAgU3ludGF4S2luZC5Qcm9wZXJ0eURlY2xhcmF0aW9uLFxuICAgICAgICBTeW50YXhLaW5kLlByb3BlcnR5U2lnbmF0dXJlLFxuICAgICAgICBTeW50YXhLaW5kLlR5cGVQYXJhbWV0ZXIsXG4gICAgICAgIFN5bnRheEtpbmQuSWRlbnRpZmllcixcbiAgICAgICAgU3ludGF4S2luZC5EZWNvcmF0b3IsXG4gICAgICAgIFN5bnRheEtpbmQuR2V0QWNjZXNzb3IsXG4gICAgICAgIFN5bnRheEtpbmQuU2V0QWNjZXNzb3IsXG4gICAgICAgIFN5bnRheEtpbmQuSW1wb3J0U3BlY2lmaWVyLFxuICAgICAgICBTeW50YXhLaW5kLkVudW1EZWNsYXJhdGlvbixcbiAgICAgICAgU3ludGF4S2luZC5FbnVtTWVtYmVyLFxuICAgICAgICBTeW50YXhLaW5kLlR5cGVBbGlhc0RlY2xhcmF0aW9uLFxuICAgICAgICBTeW50YXhLaW5kLkltcG9ydERlY2xhcmF0aW9uLFxuICAgICAgICBTeW50YXhLaW5kLkV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50c1xuICAgIF0pO1xuXG4gICAgcmV0dXJuIHR5cGVDb250ZXh0S2luZHMuaGFzKHNvdXJjZUVsZW1lbnQuZ2V0S2luZCgpKTtcbn1cblxuZnVuY3Rpb24gZ2V0SW50ZXJmYWNlT3JDbGFzc0RlY2xhcmF0aW9uRnJvbUV4cHJlc3Npb24oZXhwcmVzc2lvbjogRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKTogSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBDbGFzc0RlY2xhcmF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICAvLyBTdGVwIDE6IEdldCB0aGUgdHlwZSBvZiB0aGUgZXhwcmVzc2lvblxuICAgIGNvbnN0IHR5cGUgPSBleHByZXNzaW9uLmdldFR5cGUoKTtcblxuICAgIC8vIFN0ZXAgMjogR2V0IHRoZSBzeW1ib2wgYXNzb2NpYXRlZCB3aXRoIHRoZSB0eXBlXG4gICAgbGV0IHN5bWJvbCA9IHR5cGUuZ2V0U3ltYm9sKCk7XG5cbiAgICBpZiAoIXN5bWJvbCkge1xuICAgICAgICAvLyBJZiBzeW1ib2wgaXMgbm90IGZvdW5kLCB0cnkgdG8gZ2V0IHRoZSBzeW1ib2wgZnJvbSB0aGUgaWRlbnRpZmllclxuICAgICAgICBjb25zdCBpZGVudGlmaWVyID0gZXhwcmVzc2lvbi5nZXRGaXJzdERlc2NlbmRhbnRCeUtpbmQoU3ludGF4S2luZC5JZGVudGlmaWVyKTtcbiAgICAgICAgaWYgKCFpZGVudGlmaWVyKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYElkZW50aWZpZXIgbm90IGZvdW5kIGZvciAke2V4cHJlc3Npb24uZ2V0VGV4dCgpfS5gKTtcbiAgICAgICAgfVxuICAgICAgICBzeW1ib2wgPSBpZGVudGlmaWVyLmdldFN5bWJvbCgpO1xuICAgICAgICBpZiAoIXN5bWJvbCkge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTeW1ib2wgbm90IGZvdW5kIGZvciAke2lkZW50aWZpZXIuZ2V0VGV4dCgpfS5gKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFN0ZXAgMzogUmVzb2x2ZSB0aGUgc3ltYm9sIHRvIGZpbmQgdGhlIGFjdHVhbCBkZWNsYXJhdGlvblxuICAgIGNvbnN0IGludGVyZmFjZURlY2xhcmF0aW9uID0gcmVzb2x2ZVN5bWJvbFRvSW50ZXJmYWNlT3JDbGFzc0RlY2xhcmF0aW9uKHN5bWJvbCk7XG5cbiAgICBpZiAoIWludGVyZmFjZURlY2xhcmF0aW9uKSB7XG4gICAgICAgIGxvZ2dlci5lcnJvcihgSW50ZXJmYWNlIGRlY2xhcmF0aW9uIG5vdCBmb3VuZCBmb3IgJHtleHByZXNzaW9uLmdldFRleHQoKX0uYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGludGVyZmFjZURlY2xhcmF0aW9uO1xufVxuXG5pbXBvcnQgeyBTeW1ib2wgYXMgVFNNb3JwaFN5bWJvbCwgTm9kZSBhcyBUc01vcnBoTm9kZSB9IGZyb20gXCJ0cy1tb3JwaFwiO1xuaW1wb3J0IF8gZnJvbSBcImxvZGFzaFwiO1xuXG5mdW5jdGlvbiByZXNvbHZlU3ltYm9sVG9JbnRlcmZhY2VPckNsYXNzRGVjbGFyYXRpb24oc3ltYm9sOiBUU01vcnBoU3ltYm9sKTogSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBDbGFzc0RlY2xhcmF0aW9uIHwgdW5kZWZpbmVkIHtcbiAgICAvLyBHZXQgdGhlIGRlY2xhcmF0aW9ucyBhc3NvY2lhdGVkIHdpdGggdGhlIHN5bWJvbFxuICAgIGNvbnN0IGRlY2xhcmF0aW9ucyA9IHN5bWJvbC5nZXREZWNsYXJhdGlvbnMoKTtcblxuICAgIC8vIEZpbHRlciBmb3IgSW50ZXJmYWNlRGVjbGFyYXRpb24gb3IgQ2xhc3NEZWNsYXJhdGlvblxuICAgIGNvbnN0IGludGVyZmFjZU9yQ2xhc3NEZWNsYXJhdGlvbiA9IGRlY2xhcmF0aW9ucy5maW5kKFxuICAgICAgICBkZWNsYXJhdGlvbiA9PiBcbiAgICAgICAgICAgIGRlY2xhcmF0aW9uIGluc3RhbmNlb2YgSW50ZXJmYWNlRGVjbGFyYXRpb24gfHwgXG4gICAgICAgICAgICBkZWNsYXJhdGlvbiBpbnN0YW5jZW9mIENsYXNzRGVjbGFyYXRpb24pIGFzIEludGVyZmFjZURlY2xhcmF0aW9uIHwgQ2xhc3NEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZDtcblxuICAgIGlmIChpbnRlcmZhY2VPckNsYXNzRGVjbGFyYXRpb24pIHtcbiAgICAgICAgcmV0dXJuIGludGVyZmFjZU9yQ2xhc3NEZWNsYXJhdGlvbjtcbiAgICB9XG5cbiAgICAvLyBIYW5kbGUgaW1wb3J0czogSWYgdGhlIHN5bWJvbCBpcyBpbXBvcnRlZCwgcmVzb2x2ZSB0aGUgaW1wb3J0IHRvIGZpbmQgdGhlIGFjdHVhbCBkZWNsYXJhdGlvblxuICAgIGZvciAoY29uc3QgZGVjbGFyYXRpb24gb2YgZGVjbGFyYXRpb25zKSB7XG4gICAgICAgIGlmIChkZWNsYXJhdGlvbi5nZXRLaW5kKCkgPT09IFN5bnRheEtpbmQuSW1wb3J0U3BlY2lmaWVyKSB7XG4gICAgICAgICAgICBjb25zdCBpbXBvcnRTcGVjaWZpZXIgPSBkZWNsYXJhdGlvbiBhcyBJbXBvcnRTcGVjaWZpZXI7XG4gICAgICAgICAgICBjb25zdCBpbXBvcnREZWNsYXJhdGlvbiA9IGltcG9ydFNwZWNpZmllci5nZXRJbXBvcnREZWNsYXJhdGlvbigpO1xuICAgICAgICAgICAgY29uc3QgbW9kdWxlU3BlY2lmaWVyID0gaW1wb3J0RGVjbGFyYXRpb24uZ2V0TW9kdWxlU3BlY2lmaWVyU291cmNlRmlsZSgpO1xuXG4gICAgICAgICAgICBpZiAobW9kdWxlU3BlY2lmaWVyKSB7XG4gICAgICAgICAgICAgICAgY29uc3QgZXhwb3J0ZWRTeW1ib2xzID0gbW9kdWxlU3BlY2lmaWVyLmdldEV4cG9ydFN5bWJvbHMoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBleHBvcnRlZFN5bWJvbCA9IGV4cG9ydGVkU3ltYm9scy5maW5kKHN5bWJvbCA9PiBzeW1ib2wuZ2V0TmFtZSgpID09PSBpbXBvcnRTcGVjaWZpZXIuZ2V0TmFtZSgpKTtcbiAgICAgICAgICAgICAgICBpZiAoZXhwb3J0ZWRTeW1ib2wpIHtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIHJlc29sdmVTeW1ib2xUb0ludGVyZmFjZU9yQ2xhc3NEZWNsYXJhdGlvbihleHBvcnRlZFN5bWJvbCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuICAgIHJldHVybiB1bmRlZmluZWQ7XG59XG5cblxuZXhwb3J0IGZ1bmN0aW9uIGdldFByaW1pdGl2ZVR5cGVOYW1lKHR5cGU6IFR5cGUpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuICBjb25zdCBmbGFncyA9IHR5cGUuY29tcGlsZXJUeXBlLmZsYWdzO1xuXG4gIGlmIChmbGFncyAmIHRzLlR5cGVGbGFncy5TdHJpbmcpIHJldHVybiBcInN0cmluZ1wiO1xuICBpZiAoZmxhZ3MgJiB0cy5UeXBlRmxhZ3MuTnVtYmVyKSByZXR1cm4gXCJudW1iZXJcIjtcbiAgaWYgKGZsYWdzICYgdHMuVHlwZUZsYWdzLkJvb2xlYW4pIHJldHVybiBcImJvb2xlYW5cIjtcbiAgaWYgKGZsYWdzICYgdHMuVHlwZUZsYWdzLkJpZ0ludCkgcmV0dXJuIFwiYmlnaW50XCI7XG4gIGlmIChmbGFncyAmIHRzLlR5cGVGbGFncy5VbmlxdWVFU1N5bWJvbCkgcmV0dXJuIFwidW5pcXVlIHN5bWJvbFwiO1xuICBpZiAoZmxhZ3MgJiB0cy5UeXBlRmxhZ3MuRVNTeW1ib2wpIHJldHVybiBcInN5bWJvbFwiO1xuICBpZiAoZmxhZ3MgJiB0cy5UeXBlRmxhZ3MuVW5kZWZpbmVkKSByZXR1cm4gXCJ1bmRlZmluZWRcIjtcbiAgaWYgKGZsYWdzICYgdHMuVHlwZUZsYWdzLk51bGwpIHJldHVybiBcIm51bGxcIjtcbiAgaWYgKGZsYWdzICYgdHMuVHlwZUZsYWdzLlZvaWQpIHJldHVybiBcInZvaWRcIjtcbiAgaWYgKGZsYWdzICYgdHMuVHlwZUZsYWdzLk5ldmVyKSByZXR1cm4gXCJuZXZlclwiO1xuICBpZiAoZmxhZ3MgJiB0cy5UeXBlRmxhZ3MuQW55KSByZXR1cm4gXCJhbnlcIjtcbiAgaWYgKGZsYWdzICYgdHMuVHlwZUZsYWdzLlVua25vd24pIHJldHVybiBcInVua25vd25cIjtcblxuICByZXR1cm4gdW5kZWZpbmVkO1xufVxuXG4vLyBmdW5jdGlvbiBvbGRHZXRJbnRlcmZhY2VEZWNsYXJhdGlvbkZyb21FeHByZXNzaW9uKGV4cHJlc3Npb246IEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cyk6IEludGVyZmFjZURlY2xhcmF0aW9uIHwgdW5kZWZpbmVkIHtcbi8vICAgICAvLyBUd28gY2FzZXM6XG4vLyAgICAgLy8gY2xhc3MgQSBpbXBsZW1lbnRzIEltcG9ydGVkSW50ZXJmYWNlLCBEZWNsYXJlZEludGVyZmFjZSB7fVxuLy8gICAgIGNvbnN0IHR5cGUgPSBleHByZXNzaW9uLmdldFR5cGUoKTtcblxuLy8gICAgIC8vIEltcG9ydGVkSW50ZXJmYWNlOiB0eXBlIHdpbGwgYSBzeW1ib2wgXG4vLyAgICAgbGV0IHN5bWJvbCA9IHR5cGUuZ2V0QWxpYXNTeW1ib2woKTsgIC8vIHdpbGwgYmUgZGVmaW5lZCBmb3IgaW1wb3J0ZWQgaW50ZXJmYWNlc1xuXG4vLyAgICAgaWYgKCFzeW1ib2wpIHtcbi8vICAgICAgICAgLy8gRGVjbGFyZWRJbnRlcmZhY2U6IHR5cGUgd2lsbCBiZSBhbiBJbnRlcmZhY2VEZWNsYXJhdGlvbiBvbiBJZGVudGlmaWVyIG5vZGUgdGhhdCBpcyB0aGUgY2hpbGQgb2YgdGhlIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50c1xuLy8gICAgICAgICBjb25zdCBpZGVudGlmaWVyID0gZXhwcmVzc2lvbi5nZXRGaXJzdERlc2NlbmRhbnRCeUtpbmQoU3ludGF4S2luZC5JZGVudGlmaWVyKTtcbi8vICAgICAgICAgaWYgKCFpZGVudGlmaWVyKSB7XG4vLyAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYElkZW50aWZpZXIgbm90IGZvdW5kIGZvciAke2V4cHJlc3Npb24uZ2V0VGV4dCgpfS5gKTtcbi8vICAgICAgICAgfVxuLy8gICAgICAgICBzeW1ib2wgPSBpZGVudGlmaWVyLmdldFN5bWJvbCgpO1xuLy8gICAgICAgICBpZiAoIXN5bWJvbCkge1xuLy8gICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTeW1ib2wgbm90IGZvdW5kIGZvciAke2lkZW50aWZpZXIuZ2V0VGV4dCgpfS5gKTtcbi8vICAgICAgICAgfVxuLy8gICAgIH1cblxuLy8gICAgIC8vIFN0ZXAgMzogR2V0IHRoZSBkZWNsYXJhdGlvbnMgYXNzb2NpYXRlZCB3aXRoIHRoZSBzeW1ib2xcbi8vICAgICBjb25zdCBkZWNsYXJhdGlvbnMgPSBzeW1ib2wuZ2V0RGVjbGFyYXRpb25zKCk7XG5cbi8vICAgICAvLyBTdGVwIDQ6IEZpbHRlciBmb3IgSW50ZXJmYWNlRGVjbGFyYXRpb25cbi8vICAgICBjb25zdCBpbnRlcmZhY2VEZWNsYXJhdGlvbiA9IGRlY2xhcmF0aW9ucy5maW5kKGRlY2xhcmF0aW9uID0+IGRlY2xhcmF0aW9uIGluc3RhbmNlb2YgSW50ZXJmYWNlRGVjbGFyYXRpb24pIGFzIEludGVyZmFjZURlY2xhcmF0aW9uIHwgdW5kZWZpbmVkO1xuXG4vLyAgICAgaWYgKCFpbnRlcmZhY2VEZWNsYXJhdGlvbikge1xuLy8gICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEludGVyZmFjZSBkZWNsYXJhdGlvbiBub3QgZm91bmQgZm9yICR7ZXhwcmVzc2lvbi5nZXRUZXh0KCl9LmApO1xuLy8gICAgIH1cblxuLy8gICAgIHJldHVybiBpbnRlcmZhY2VEZWNsYXJhdGlvbjtcbi8vIH1cbiJdfQ==