ts2famix 2.1.0-beta.1 → 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 (193) hide show
  1. package/.eslintrc.json +24 -24
  2. package/LICENSE +24 -24
  3. package/README.md +78 -78
  4. package/dist/analyze.js +20 -10
  5. package/dist/analyze_functions/process_functions.js +109 -69
  6. package/dist/famix_functions/EntityDictionary.js +691 -606
  7. package/dist/famix_functions/helpers_creation.js +35 -19
  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 +31 -12
  12. package/dist/lib/famix/index.js +18 -8
  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 +18 -8
  57. package/dist/ts2famix-cli-wrapper.js +18 -8
  58. package/dist/ts2famix-cli.js +18 -8
  59. package/dist/ts2famix-tsconfig.js +18 -8
  60. package/doc-uml/famix-typescript-model.puml +619 -607
  61. package/doc-uml/famix-typescript-model.svg +1 -1
  62. package/eslint.config.mjs +28 -28
  63. package/jest.config.json +1 -1
  64. package/package.json +70 -70
  65. package/src/analyze.ts +120 -120
  66. package/src/analyze_functions/process_functions.ts +1069 -1040
  67. package/src/famix_functions/EntityDictionary.ts +2061 -2016
  68. package/src/famix_functions/helpers_creation.ts +143 -135
  69. package/src/fqn.ts +416 -50
  70. package/src/generate_uml.sh +20 -20
  71. package/src/lib/famix/License.md +22 -22
  72. package/src/lib/famix/famix_JSON_exporter.ts +56 -56
  73. package/src/lib/famix/famix_base_element.ts +22 -22
  74. package/src/lib/famix/famix_repository.ts +288 -278
  75. package/src/lib/famix/index.ts +8 -8
  76. package/src/lib/famix/model/famix/access.ts +50 -50
  77. package/src/lib/famix/model/famix/accessor.ts +15 -15
  78. package/src/lib/famix/model/famix/alias.ts +39 -39
  79. package/src/lib/famix/model/famix/arrow_function.ts +15 -15
  80. package/src/lib/famix/model/famix/behavioral_entity.ts +97 -97
  81. package/src/lib/famix/model/famix/class.ts +85 -85
  82. package/src/lib/famix/model/famix/comment.ts +47 -47
  83. package/src/lib/famix/model/famix/concretisation.ts +40 -40
  84. package/src/lib/famix/model/famix/container_entity.ts +160 -160
  85. package/src/lib/famix/model/famix/decorator.ts +37 -37
  86. package/src/lib/famix/model/famix/entity.ts +15 -15
  87. package/src/lib/famix/model/famix/enum.ts +30 -30
  88. package/src/lib/famix/model/famix/enum_value.ts +28 -28
  89. package/src/lib/famix/model/famix/function.ts +15 -15
  90. package/src/lib/famix/model/famix/import_clause.ts +51 -51
  91. package/src/lib/famix/model/famix/index.ts +41 -41
  92. package/src/lib/famix/model/famix/indexed_file_anchor.ts +46 -46
  93. package/src/lib/famix/model/famix/inheritance.ts +40 -40
  94. package/src/lib/famix/model/famix/interface.ts +75 -75
  95. package/src/lib/famix/model/famix/invocation.ts +65 -65
  96. package/src/lib/famix/model/famix/method.ts +89 -89
  97. package/src/lib/famix/model/famix/module.ts +71 -71
  98. package/src/lib/famix/model/famix/named_entity.ts +95 -95
  99. package/src/lib/famix/model/famix/parameter.ts +28 -28
  100. package/src/lib/famix/model/famix/parameter_concretisation.ts +51 -51
  101. package/src/lib/famix/model/famix/parameter_type.ts +58 -58
  102. package/src/lib/famix/model/famix/parametric_arrow_function.ts +32 -32
  103. package/src/lib/famix/model/famix/parametric_class.ts +49 -49
  104. package/src/lib/famix/model/famix/parametric_function.ts +32 -32
  105. package/src/lib/famix/model/famix/parametric_interface.ts +49 -49
  106. package/src/lib/famix/model/famix/parametric_method.ts +32 -32
  107. package/src/lib/famix/model/famix/primitive_type.ts +15 -15
  108. package/src/lib/famix/model/famix/property.ts +94 -94
  109. package/src/lib/famix/model/famix/reference.ts +40 -40
  110. package/src/lib/famix/model/famix/scoping_entity.ts +35 -35
  111. package/src/lib/famix/model/famix/script_entity.ts +34 -34
  112. package/src/lib/famix/model/famix/source_anchor.ts +30 -30
  113. package/src/lib/famix/model/famix/source_language.ts +35 -35
  114. package/src/lib/famix/model/famix/sourced_entity.ts +70 -70
  115. package/src/lib/famix/model/famix/structural_entity.ts +43 -43
  116. package/src/lib/famix/model/famix/type.ts +87 -87
  117. package/src/lib/famix/model/famix/variable.ts +27 -27
  118. package/src/lib/famix/package.json +28 -28
  119. package/src/lib/ts-complex/cyclomatic-service.ts +83 -83
  120. package/src/refactorer/refactor-getter-setter.ts +140 -140
  121. package/src/ts2famix-cli-wrapper.ts +21 -21
  122. package/src/ts2famix-cli.ts +60 -60
  123. package/tsconfig.check-tests.json +14 -14
  124. package/tsconfig.json +73 -72
  125. package/.vscode/settings.json +0 -4
  126. package/TODO +0 -1
  127. package/arwea-fix.json +0 -1
  128. package/bogus.ts +0 -3
  129. package/class-diagram.puml +0 -792
  130. package/debug.txt +0 -13332
  131. package/debuglog.txt +0 -12073
  132. package/dist/famix2puml.js +0 -126
  133. package/dist/getClasses-arrow-body.js +0 -43
  134. package/dist/lib/famix/src/famix_JSON_exporter.js +0 -55
  135. package/dist/lib/famix/src/famix_base_element.js +0 -18
  136. package/dist/lib/famix/src/famix_repository.js +0 -224
  137. package/dist/lib/famix/src/index.js +0 -31
  138. package/dist/lib/famix/src/model/famix/access.js +0 -40
  139. package/dist/lib/famix/src/model/famix/accessor.js +0 -17
  140. package/dist/lib/famix/src/model/famix/alias.js +0 -33
  141. package/dist/lib/famix/src/model/famix/arrowFunction.js +0 -17
  142. package/dist/lib/famix/src/model/famix/arrow_function.js +0 -17
  143. package/dist/lib/famix/src/model/famix/behavioral_entity.js +0 -79
  144. package/dist/lib/famix/src/model/famix/class.js +0 -71
  145. package/dist/lib/famix/src/model/famix/comment.js +0 -39
  146. package/dist/lib/famix/src/model/famix/concretisation.js +0 -31
  147. package/dist/lib/famix/src/model/famix/container_entity.js +0 -126
  148. package/dist/lib/famix/src/model/famix/decorator.js +0 -32
  149. package/dist/lib/famix/src/model/famix/entity.js +0 -17
  150. package/dist/lib/famix/src/model/famix/enum.js +0 -31
  151. package/dist/lib/famix/src/model/famix/enum_value.js +0 -25
  152. package/dist/lib/famix/src/model/famix/function.js +0 -17
  153. package/dist/lib/famix/src/model/famix/implicit_variable.js +0 -17
  154. package/dist/lib/famix/src/model/famix/import_clause.js +0 -41
  155. package/dist/lib/famix/src/model/famix/index.js +0 -86
  156. package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +0 -38
  157. package/dist/lib/famix/src/model/famix/inheritance.js +0 -33
  158. package/dist/lib/famix/src/model/famix/interface.js +0 -64
  159. package/dist/lib/famix/src/model/famix/invocation.js +0 -54
  160. package/dist/lib/famix/src/model/famix/method.js +0 -67
  161. package/dist/lib/famix/src/model/famix/module.js +0 -60
  162. package/dist/lib/famix/src/model/famix/named_entity.js +0 -78
  163. package/dist/lib/famix/src/model/famix/parameter.js +0 -25
  164. package/dist/lib/famix/src/model/famix/parameterConcretisation.js +0 -44
  165. package/dist/lib/famix/src/model/famix/parameter_concretisation.js +0 -44
  166. package/dist/lib/famix/src/model/famix/parameter_type.js +0 -45
  167. package/dist/lib/famix/src/model/famix/parametricArrowFunction.js +0 -29
  168. package/dist/lib/famix/src/model/famix/parametric_arrow_function.js +0 -31
  169. package/dist/lib/famix/src/model/famix/parametric_class.js +0 -44
  170. package/dist/lib/famix/src/model/famix/parametric_function.js +0 -31
  171. package/dist/lib/famix/src/model/famix/parametric_interface.js +0 -44
  172. package/dist/lib/famix/src/model/famix/parametric_method.js +0 -31
  173. package/dist/lib/famix/src/model/famix/primitive_type.js +0 -17
  174. package/dist/lib/famix/src/model/famix/property.js +0 -73
  175. package/dist/lib/famix/src/model/famix/reference.js +0 -33
  176. package/dist/lib/famix/src/model/famix/scoping_entity.js +0 -36
  177. package/dist/lib/famix/src/model/famix/script_entity.js +0 -29
  178. package/dist/lib/famix/src/model/famix/source_anchor.js +0 -27
  179. package/dist/lib/famix/src/model/famix/source_language.js +0 -35
  180. package/dist/lib/famix/src/model/famix/sourced_entity.js +0 -60
  181. package/dist/lib/famix/src/model/famix/structural_entity.js +0 -39
  182. package/dist/lib/famix/src/model/famix/text_anchor.js +0 -38
  183. package/dist/lib/famix/src/model/famix/type.js +0 -73
  184. package/dist/lib/famix/src/model/famix/variable.js +0 -24
  185. package/fqn-model.json +0 -1
  186. package/iterateGenericTypes.ts +0 -69
  187. package/out/class-diagram/class-diagram.svg +0 -1
  188. package/sample.json +0 -1
  189. package/sample.ts +0 -1
  190. package/stats.txt +0 -3091
  191. package/tabby-debug-output.txt +0 -19433
  192. package/ts2famix.log +0 -22656
  193. package/validate-references.js +0 -103
package/dist/fqn.js CHANGED
@@ -7,6 +7,7 @@ exports.getFQN = getFQN;
7
7
  exports.getUniqueFQN = getUniqueFQN;
8
8
  exports.getNameOfNode = getNameOfNode;
9
9
  exports.getParameters = getParameters;
10
+ exports.getFQNUnresolvedInheritedClassOrInterface = getFQNUnresolvedInheritedClassOrInterface;
10
11
  const ts_morph_1 = require("ts-morph");
11
12
  const analyze_1 = require("./analyze");
12
13
  const path_1 = __importDefault(require("path"));
@@ -14,11 +15,216 @@ const path_1 = __importDefault(require("path"));
14
15
  function isFQNNode(node) {
15
16
  return ts_morph_1.Node.isVariableDeclaration(node) || ts_morph_1.Node.isArrowFunction(node) || ts_morph_1.Node.isIdentifier(node) || ts_morph_1.Node.isMethodDeclaration(node) || ts_morph_1.Node.isClassDeclaration(node) || ts_morph_1.Node.isClassExpression(node) || ts_morph_1.Node.isDecorator(node) || ts_morph_1.Node.isModuleDeclaration(node) || ts_morph_1.Node.isCallExpression(node);
16
17
  }
18
+ /**
19
+ * Builds a map of method positions to their property keys in object literals.
20
+ * Scans all variable declarations in a source file, targeting object literals with any keys
21
+ * (e.g., `3: { method() {} }` or `add: { compute() {} }`), and maps each method's start position to its key.
22
+ * Logs each step for debugging.
23
+ *
24
+ * @param sourceFile The TypeScript source file to analyze
25
+ * @returns A Map where keys are method start positions and values are their property keys (e.g., "3", "add")
26
+ */
27
+ function buildStageMethodMap(sourceFile) {
28
+ const stageMap = new Map();
29
+ sourceFile.getVariableDeclarations().forEach(varDecl => {
30
+ // const varName = varDecl.getName();
31
+ const initializer = varDecl.getInitializer();
32
+ if (!initializer || !ts_morph_1.Node.isObjectLiteralExpression(initializer)) {
33
+ return;
34
+ }
35
+ initializer.getProperties().forEach(prop => {
36
+ let key;
37
+ if (ts_morph_1.Node.isPropertyAssignment(prop)) {
38
+ const nameNode = prop.getNameNode();
39
+ if (ts_morph_1.Node.isIdentifier(nameNode)) {
40
+ key = nameNode.getText();
41
+ }
42
+ else if (ts_morph_1.Node.isStringLiteral(nameNode)) {
43
+ key = nameNode.getText().replace(/^"(.+)"$/, '$1').replace(/^'(.+)'$/, '$1');
44
+ }
45
+ else if (ts_morph_1.Node.isNumericLiteral(nameNode)) {
46
+ key = nameNode.getText();
47
+ }
48
+ else if (ts_morph_1.Node.isComputedPropertyName(nameNode)) {
49
+ const expression = nameNode.getExpression();
50
+ if (ts_morph_1.Node.isIdentifier(expression)) {
51
+ // Resolve variable value if possible
52
+ const symbol = expression.getSymbol();
53
+ if (symbol) {
54
+ const decl = symbol.getDeclarations()[0];
55
+ if (ts_morph_1.Node.isVariableDeclaration(decl) && decl.getInitializer()) {
56
+ const init = decl.getInitializer();
57
+ if (ts_morph_1.Node.isStringLiteral(init) || ts_morph_1.Node.isNumericLiteral(init)) {
58
+ key = init.getText().replace(/^"(.+)"$/, '$1').replace(/^'(.+)'$/, '$1');
59
+ }
60
+ }
61
+ }
62
+ if (!key) {
63
+ key = expression.getText();
64
+ }
65
+ }
66
+ else if (ts_morph_1.Node.isBinaryExpression(expression) && expression.getOperatorToken().getText() === '+') {
67
+ // Handle simple string concatenation (e.g., "A" + "B")
68
+ const left = expression.getLeft();
69
+ const right = expression.getRight();
70
+ if (ts_morph_1.Node.isStringLiteral(left) && ts_morph_1.Node.isStringLiteral(right)) {
71
+ key = left.getLiteralText() + right.getLiteralText();
72
+ }
73
+ }
74
+ else if (ts_morph_1.Node.isTemplateExpression(expression)) {
75
+ // Handle template literals (e.g., `key-${1}`)
76
+ const head = expression.getHead().getLiteralText();
77
+ const spans = expression.getTemplateSpans();
78
+ if (spans.length === 1 && ts_morph_1.Node.isNumericLiteral(spans[0].getExpression())) {
79
+ const num = spans[0].getExpression().getText();
80
+ key = `${head}${num}`;
81
+ }
82
+ }
83
+ if (!key) {
84
+ key = expression.getText(); // Fallback
85
+ }
86
+ }
87
+ else {
88
+ return;
89
+ }
90
+ const propInitializer = prop.getInitializer();
91
+ if (propInitializer && ts_morph_1.Node.isObjectLiteralExpression(propInitializer)) {
92
+ propInitializer.getDescendantsOfKind(ts_morph_1.SyntaxKind.MethodDeclaration).forEach(method => {
93
+ // const methodName = method.getName();
94
+ const pos = method.getStart();
95
+ if (key) {
96
+ stageMap.set(pos, key);
97
+ }
98
+ });
99
+ }
100
+ }
101
+ });
102
+ });
103
+ return stageMap;
104
+ }
105
+ /**
106
+ * Builds a map of method positions to their index in class/interface/namespace declarations
107
+ * @param sourceFile The TypeScript source file to analyze
108
+ * @returns A Map where keys are method start positions and values are their positional index (1-based)
109
+ */
110
+ function buildMethodPositionMap(sourceFile) {
111
+ const positionMap = new Map();
112
+ // console.log(`[buildMethodPositionMap] Starting analysis for file: ${sourceFile.getFilePath()}`);
113
+ // Helper function to process modules recursively
114
+ function processModule(moduleNode, modulePath) {
115
+ // console.log(`[buildMethodPositionMap] Processing module: ${modulePath}`);
116
+ // Handle functions directly in the module
117
+ const functions = moduleNode.getFunctions();
118
+ const functionCounts = new Map();
119
+ functions.forEach(func => {
120
+ const funcName = func.getName() || `Unnamed_Function(${func.getStart()})`;
121
+ const count = (functionCounts.get(funcName) || 0) + 1;
122
+ functionCounts.set(funcName, count);
123
+ positionMap.set(func.getStart(), count);
124
+ // console.log(`[buildMethodPositionMap] Module function: ${funcName}, position: ${func.getStart()}, index: ${count}`);
125
+ });
126
+ // Handle classes within the module
127
+ const classes = moduleNode.getClasses();
128
+ classes.forEach(classNode => {
129
+ // console.log(`[buildMethodPositionMap] Processing class in module: ${classNode.getName() || 'Unnamed'}`);
130
+ const methods = classNode.getMethods();
131
+ const methodCounts = new Map();
132
+ methods.forEach(method => {
133
+ const methodName = method.getName();
134
+ const count = (methodCounts.get(methodName) || 0) + 1;
135
+ methodCounts.set(methodName, count);
136
+ positionMap.set(method.getStart(), count);
137
+ // console.log(`[buildMethodPositionMap] Module class method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
138
+ });
139
+ });
140
+ // Handle interfaces within the module
141
+ const interfaces = moduleNode.getInterfaces();
142
+ interfaces.forEach(interfaceNode => {
143
+ // console.log(`[buildMethodPositionMap] Processing interface in module: ${interfaceNode.getName() || 'Unnamed'}`);
144
+ const methods = interfaceNode.getMethods();
145
+ const methodCounts = new Map();
146
+ methods.forEach(method => {
147
+ const methodName = method.getName();
148
+ const count = (methodCounts.get(methodName) || 0) + 1;
149
+ methodCounts.set(methodName, count);
150
+ positionMap.set(method.getStart(), count);
151
+ // console.log(`[buildMethodPositionMap] Module interface method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
152
+ });
153
+ });
154
+ // Recursively process nested modules
155
+ const nestedModules = moduleNode.getModules();
156
+ nestedModules.forEach(nestedModule => {
157
+ if (ts_morph_1.Node.isModuleDeclaration(nestedModule)) {
158
+ const nestedModuleName = nestedModule.getName();
159
+ const newModulePath = `${modulePath}.${nestedModuleName}`;
160
+ processModule(nestedModule, newModulePath);
161
+ }
162
+ });
163
+ }
164
+ function trackArrowFunctions(container) {
165
+ const arrows = container.getDescendantsOfKind(ts_morph_1.SyntaxKind.ArrowFunction);
166
+ arrows.forEach(arrow => {
167
+ const parent = arrow.getParent();
168
+ if (ts_morph_1.Node.isBlock(parent) || ts_morph_1.Node.isSourceFile(parent)) {
169
+ // Use negative numbers for arrow functions to distinguish from methods
170
+ positionMap.set(arrow.getStart(), -1 * (positionMap.size + 1));
171
+ // console.log(`[buildMethodPositionMap] Arrow function at ${arrow.getStart()}`);
172
+ }
173
+ });
174
+ }
175
+ // Handle top-level classes
176
+ sourceFile.getClasses().forEach(classNode => {
177
+ // console.log(`[buildMethodPositionMap] Processing class: ${classNode.getName() || 'Unnamed'}`);
178
+ const methods = classNode.getMethods();
179
+ const methodCounts = new Map();
180
+ methods.forEach(method => {
181
+ const methodName = method.getName();
182
+ const count = (methodCounts.get(methodName) || 0) + 1;
183
+ methodCounts.set(methodName, count);
184
+ positionMap.set(method.getStart(), count);
185
+ // console.log(`[buildMethodPositionMap] Class method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
186
+ });
187
+ methods.forEach(method => trackArrowFunctions(method));
188
+ });
189
+ // Handle top-level interfaces
190
+ sourceFile.getInterfaces().forEach(interfaceNode => {
191
+ // console.log(`[buildMethodPositionMap] Processing interface: ${interfaceNode.getName() || 'Unnamed'}`);
192
+ const methods = interfaceNode.getMethods();
193
+ const methodCounts = new Map();
194
+ methods.forEach(method => {
195
+ const methodName = method.getName();
196
+ const count = (methodCounts.get(methodName) || 0) + 1;
197
+ methodCounts.set(methodName, count);
198
+ positionMap.set(method.getStart(), count);
199
+ // console.log(`[buildMethodPositionMap] Interface method: ${methodName}, position: ${method.getStart()}, index: ${count}`);
200
+ });
201
+ methods.forEach(method => trackArrowFunctions(method));
202
+ });
203
+ // Handle top-level namespaces/modules
204
+ sourceFile.getModules().forEach(moduleNode => {
205
+ if (ts_morph_1.Node.isModuleDeclaration(moduleNode)) {
206
+ const moduleName = moduleNode.getName();
207
+ processModule(moduleNode, moduleName);
208
+ }
209
+ });
210
+ // console.log(`[buildMethodPositionMap] Final positionMap:`, Array.from(positionMap.entries()));
211
+ return positionMap;
212
+ }
213
+ /**
214
+ * Generates a fully qualified name (FQN) for a given AST node.
215
+ * Constructs an FQN by traversing the node's ancestry, adding names and keys
216
+ * (numeric or string from object literals ...) as needed, prefixed with the file's relative path.
217
+ *
218
+ * @param node The AST node to generate an FQN for
219
+ * @returns A string representing the node's FQN (e.g., "{path}.operations.add.compute[MethodDeclaration]")
220
+ */
17
221
  function getFQN(node) {
18
- const absolutePathProject = analyze_1.entityDictionary.famixRep.getAbsolutePath();
19
222
  const sourceFile = node.getSourceFile();
223
+ const absolutePathProject = analyze_1.entityDictionary.famixRep.getAbsolutePath();
20
224
  const parts = [];
21
225
  let currentNode = node;
226
+ const stageMap = buildStageMethodMap(sourceFile);
227
+ const methodPositionMap = buildMethodPositionMap(sourceFile);
22
228
  while (currentNode && !ts_morph_1.Node.isSourceFile(currentNode)) {
23
229
  const { line, column } = sourceFile.getLineAndColumnAtPos(currentNode.getStart());
24
230
  const lc = `${line}:${column}`;
@@ -31,7 +237,6 @@ function getFQN(node) {
31
237
  ts_morph_1.Node.isVariableDeclaration(currentNode) ||
32
238
  ts_morph_1.Node.isGetAccessorDeclaration(currentNode) ||
33
239
  ts_morph_1.Node.isSetAccessorDeclaration(currentNode) ||
34
- ts_morph_1.Node.isTypeParameterDeclaration(currentNode) ||
35
240
  ts_morph_1.Node.isPropertyDeclaration(currentNode) ||
36
241
  ts_morph_1.Node.isParameterDeclaration(currentNode) ||
37
242
  ts_morph_1.Node.isDecorator(currentNode) ||
@@ -43,39 +248,113 @@ function getFQN(node) {
43
248
  ts_morph_1.Node.isArrayLiteralExpression(currentNode) ||
44
249
  ts_morph_1.Node.isImportSpecifier(currentNode) ||
45
250
  ts_morph_1.Node.isIdentifier(currentNode)) {
46
- const name = ts_morph_1.Node.isIdentifier(currentNode) ? currentNode.getText()
47
- : getNameOfNode(currentNode) /* currentNode.getName() */ || 'Unnamed_' + currentNode.getKindName() + `(${lc})`;
251
+ let name;
252
+ if (ts_morph_1.Node.isImportSpecifier(currentNode)) {
253
+ const alias = currentNode.getAliasNode()?.getText();
254
+ if (alias) {
255
+ let importDecl = currentNode;
256
+ while (importDecl && !ts_morph_1.Node.isImportDeclaration(importDecl)) {
257
+ importDecl = importDecl.getParent();
258
+ }
259
+ const moduleSpecifier = importDecl && ts_morph_1.Node.isImportDeclaration(importDecl)
260
+ ? importDecl.getModuleSpecifier().getLiteralText()
261
+ : "unknown";
262
+ name = currentNode.getName();
263
+ name = `${name} as ${alias}[ImportSpecifier<${moduleSpecifier}>]`;
264
+ }
265
+ else {
266
+ name = currentNode.getName();
267
+ }
268
+ }
269
+ else {
270
+ // if constructor, use "constructor" as name
271
+ if (ts_morph_1.Node.isConstructorDeclaration(currentNode)) {
272
+ name = "constructor";
273
+ }
274
+ else {
275
+ name = ts_morph_1.Node.isIdentifier(currentNode) ? currentNode.getText()
276
+ : 'getName' in currentNode && typeof currentNode['getName'] === 'function'
277
+ ? (currentNode.getName() +
278
+ ((ts_morph_1.Node.isClassDeclaration(currentNode) ||
279
+ ts_morph_1.Node.isInterfaceDeclaration(currentNode) ||
280
+ ts_morph_1.Node.isMethodDeclaration(currentNode) ||
281
+ ts_morph_1.Node.isFunctionDeclaration(currentNode)) &&
282
+ 'getTypeParameters' in currentNode &&
283
+ currentNode.getTypeParameters().length > 0
284
+ ? getParameters(currentNode)
285
+ : ''))
286
+ : `Unnamed_${currentNode.getKindName()}(${lc})`;
287
+ }
288
+ }
289
+ if (ts_morph_1.Node.isMethodSignature(currentNode)) {
290
+ const method = currentNode;
291
+ const params = method.getParameters().map(p => {
292
+ const typeText = p.getType().getText().replace(/\s+/g, "");
293
+ return typeText || "any"; // Fallback for untyped parameters
294
+ });
295
+ const returnType = method.getReturnType().getText().replace(/\s+/g, "") || "void";
296
+ name = `${name}(${params.join(",")}):${returnType}`;
297
+ }
48
298
  parts.unshift(name);
299
+ // Apply positional index for MethodDeclaration, MethodSignature, and FunctionDeclaration
300
+ if (ts_morph_1.Node.isMethodDeclaration(currentNode) ||
301
+ ts_morph_1.Node.isMethodSignature(currentNode) ||
302
+ ts_morph_1.Node.isFunctionDeclaration(currentNode)) {
303
+ const key = stageMap.get(currentNode.getStart());
304
+ if (key) {
305
+ parts.unshift(key);
306
+ // console.log(`[getFQN] Applied stageMap key: ${key} for ${currentNode.getKindName()} at position ${currentNode.getStart()}`);
307
+ }
308
+ else {
309
+ const positionIndex = methodPositionMap.get(currentNode.getStart());
310
+ if (positionIndex && positionIndex > 1) {
311
+ parts.unshift(positionIndex.toString());
312
+ // console.log(`[getFQN] Applied positionIndex: ${positionIndex} for ${currentNode.getKindName()} at position ${currentNode.getStart()}`);
313
+ }
314
+ else {
315
+ console.log(`[getFQN] No positionIndex applied for ${currentNode.getKindName()} at position ${currentNode.getStart()}, positionIndex: ${positionIndex || 'none'}`);
316
+ }
317
+ }
318
+ }
49
319
  }
50
- // unnamed nodes
51
320
  else if (ts_morph_1.Node.isArrowFunction(currentNode) ||
52
321
  ts_morph_1.Node.isBlock(currentNode) ||
53
322
  ts_morph_1.Node.isForInStatement(currentNode) ||
54
323
  ts_morph_1.Node.isForOfStatement(currentNode) ||
55
324
  ts_morph_1.Node.isForStatement(currentNode) ||
56
325
  ts_morph_1.Node.isCatchClause(currentNode)) {
57
- parts.unshift(`${currentNode.getKindName()}(${lc})`);
326
+ const name = `${currentNode.getKindName()}(${lc})`;
327
+ parts.unshift(name);
328
+ }
329
+ else if (ts_morph_1.Node.isTypeParameterDeclaration(currentNode)) {
330
+ const arrowParent = currentNode.getFirstAncestorByKind(ts_morph_1.SyntaxKind.ArrowFunction);
331
+ if (arrowParent) {
332
+ const arrowIndex = Math.abs(methodPositionMap.get(arrowParent.getStart()) || 0);
333
+ if (arrowIndex > 0) {
334
+ parts.unshift(arrowIndex.toString());
335
+ }
336
+ }
337
+ parts.unshift(currentNode.getName());
338
+ // Removed continue to allow ancestor processing
58
339
  }
59
340
  else if (ts_morph_1.Node.isConstructorDeclaration(currentNode)) {
60
- parts.unshift(`constructor`);
341
+ const name = "constructor";
342
+ parts.unshift(name);
61
343
  }
62
344
  else {
63
- // For other kinds, you might want to handle them specifically or ignore
64
- analyze_1.logger.debug(`Ignoring node kind: ${currentNode.getKindName()}`);
345
+ console.log(`[getFQN] Ignoring node kind: ${currentNode.getKindName()}`);
65
346
  }
66
347
  currentNode = currentNode.getParent();
67
348
  }
68
- // Prepend the relative path of the source file
69
- let relativePath = analyze_1.entityDictionary.convertToRelativePath(path_1.default.normalize(sourceFile.getFilePath()), absolutePathProject).replace(/\\/sg, "/");
70
- if (relativePath.includes("..")) {
71
- analyze_1.logger.error(`Relative path contains ../: ${relativePath}`);
72
- }
349
+ let relativePath = analyze_1.entityDictionary.convertToRelativePath(path_1.default.normalize(sourceFile.getFilePath()), absolutePathProject).replace(/\\/g, "/");
350
+ // if (relativePath.includes("..")) {
351
+ // }
73
352
  if (relativePath.startsWith("/")) {
74
- relativePath = relativePath.substring(1);
353
+ relativePath = relativePath.slice(1);
75
354
  }
76
355
  parts.unshift(`{${relativePath}}`);
77
- const fqn = parts.join(".") + `[${node.getKindName()}]`; // disambiguate
78
- analyze_1.logger.debug(`Generated FQN: ${fqn} for node: ${node.getKindName()}`);
356
+ const fqn = parts.join(".") + `[${node.getKindName()}]`;
357
+ // console.log(`[getFQN] Final FQN: ${fqn}`);
79
358
  return fqn;
80
359
  }
81
360
  function getUniqueFQN(node) {
@@ -216,4 +495,58 @@ function getParameters(a) {
216
495
  }
217
496
  return paramString;
218
497
  }
219
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnFuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Zxbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQVlBLHdCQXNFQztBQUdELG9DQTJCQztBQU9ELHNDQWlHQztBQU9ELHNDQW1CQztBQWxQRCx1Q0FBK2I7QUFDL2IsdUNBQXFEO0FBQ3JELGdEQUF3QjtBQUt4Qiw2REFBNkQ7QUFDN0QsU0FBUyxTQUFTLENBQUMsSUFBVTtJQUN6QixPQUFPLGVBQUksQ0FBQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLG1CQUFtQixDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLGdCQUFnQixDQUFDLElBQUksQ0FBQyxDQUFDO0FBQ25TLENBQUM7QUFFRCxTQUFnQixNQUFNLENBQUMsSUFBb0I7SUFDdkMsTUFBTSxtQkFBbUIsR0FBRywwQkFBZ0IsQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUM7SUFFeEUsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3hDLE1BQU0sS0FBSyxHQUFhLEVBQUUsQ0FBQztJQUMzQixJQUFJLFdBQVcsR0FBcUIsSUFBSSxDQUFDO0lBRXpDLE9BQU8sV0FBVyxJQUFJLENBQUMsZUFBSSxDQUFDLFlBQVksQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1FBQ3BELE1BQU0sRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLEdBQUcsVUFBVSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO1FBQ2xGLE1BQU0sRUFBRSxHQUFHLEdBQUcsSUFBSSxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQy9CLElBQUksZUFBSSxDQUFDLGtCQUFrQixDQUFDLFdBQVcsQ0FBQztZQUNwQyxlQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDO1lBQ25DLGVBQUksQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLENBQUM7WUFDeEMsZUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsQ0FBQztZQUN2QyxlQUFJLENBQUMsbUJBQW1CLENBQUMsV0FBVyxDQUFDO1lBQ3JDLGVBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQUM7WUFDckMsZUFBSSxDQUFDLHFCQUFxQixDQUFDLFdBQVcsQ0FBQztZQUN2QyxlQUFJLENBQUMsd0JBQXdCLENBQUMsV0FBVyxDQUFDO1lBQzFDLGVBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUM7WUFDMUMsZUFBSSxDQUFDLDBCQUEwQixDQUFDLFdBQVcsQ0FBQztZQUM1QyxlQUFJLENBQUMscUJBQXFCLENBQUMsV0FBVyxDQUFDO1lBQ3ZDLGVBQUksQ0FBQyxzQkFBc0IsQ0FBQyxXQUFXLENBQUM7WUFDeEMsZUFBSSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUM7WUFDN0IsZUFBSSxDQUFDLHNCQUFzQixDQUFDLFdBQVcsQ0FBQztZQUN4QyxlQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDO1lBQ25DLGVBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDO1lBQzlCLGVBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO1lBQy9CLGVBQUksQ0FBQyxtQkFBbUIsQ0FBQyxXQUFXLENBQUM7WUFDckMsZUFBSSxDQUFDLHdCQUF3QixDQUFDLFdBQVcsQ0FBQztZQUMxQyxlQUFJLENBQUMsaUJBQWlCLENBQUMsV0FBVyxDQUFDO1lBQ25DLGVBQUksQ0FBQyxZQUFZLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksR0FBRyxlQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxXQUFXLENBQUMsT0FBTyxFQUFFO2dCQUMvRCxDQUFDLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxDQUFDLDJCQUEyQixJQUFJLFVBQVUsR0FBRyxXQUFXLENBQUMsV0FBVyxFQUFFLEdBQUcsSUFBSSxFQUFFLEdBQUcsQ0FBQztZQUNuSCxLQUFLLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3hCLENBQUM7UUFDRCxnQkFBZ0I7YUFDWCxJQUFJLGVBQUksQ0FBQyxlQUFlLENBQUMsV0FBVyxDQUFDO1lBQy9CLGVBQUksQ0FBQyxPQUFPLENBQUMsV0FBVyxDQUFDO1lBQ3pCLGVBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxXQUFXLENBQUM7WUFDbEMsZUFBSSxDQUFDLGdCQUFnQixDQUFDLFdBQVcsQ0FBQztZQUNsQyxlQUFJLENBQUMsY0FBYyxDQUFDLFdBQVcsQ0FBQztZQUNoQyxlQUFJLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDekMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxHQUFHLFdBQVcsQ0FBQyxXQUFXLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3pELENBQUM7YUFBTSxJQUFJLGVBQUksQ0FBQyx3QkFBd0IsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDO1lBQ3BELEtBQUssQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDakMsQ0FBQzthQUFNLENBQUM7WUFDSix3RUFBd0U7WUFDeEUsZ0JBQU0sQ0FBQyxLQUFLLENBQUMsdUJBQXVCLFdBQVcsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDckUsQ0FBQztRQUNELFdBQVcsR0FBRyxXQUFXLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDMUMsQ0FBQztJQUlELCtDQUErQztJQUMvQyxJQUFJLFlBQVksR0FBRywwQkFBZ0IsQ0FBQyxxQkFBcUIsQ0FDckQsY0FBSSxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsV0FBVyxFQUFFLENBQUMsRUFDekIsbUJBQW1CLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBRTdELElBQUksWUFBWSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDO1FBQzlCLGdCQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixZQUFZLEVBQUUsQ0FBQyxDQUFDO0lBQ2hFLENBQUM7SUFDRCxJQUFJLFlBQVksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQztRQUMvQixZQUFZLEdBQUcsWUFBWSxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUM3QyxDQUFDO0lBQ0QsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLFlBQVksR0FBRyxDQUFDLENBQUM7SUFDbkMsTUFBTSxHQUFHLEdBQUcsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxXQUFXLEVBQUUsR0FBRyxDQUFDLENBQUUsZUFBZTtJQUV6RSxnQkFBTSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsR0FBRyxjQUFjLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDdEUsT0FBTyxHQUFHLENBQUM7QUFDZixDQUFDO0FBR0QsU0FBZ0IsWUFBWSxDQUFDLElBQVU7SUFDbkMsTUFBTSxtQkFBbUIsR0FBRywwQkFBZ0IsQ0FBQyxRQUFRLENBQUMsZUFBZSxFQUFFLENBQUM7SUFDeEUsTUFBTSxLQUFLLEdBQWEsRUFBRSxDQUFDO0lBRTNCLElBQUksSUFBSSxZQUFZLHFCQUFVLEVBQUUsQ0FBQztRQUM3QixPQUFPLDBCQUFnQixDQUFDLHFCQUFxQixDQUFDLGNBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDLEVBQUUsbUJBQW1CLENBQUMsQ0FBQyxPQUFPLENBQUMsS0FBSyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQy9ILENBQUM7SUFFRCxJQUFJLFdBQVcsR0FBcUIsSUFBSSxDQUFDO0lBQ3pDLE9BQU8sV0FBVyxFQUFFLENBQUM7UUFDakIsSUFBSSxlQUFJLENBQUMsWUFBWSxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDakMsTUFBTSxZQUFZLEdBQUcsMEJBQWdCLENBQUMscUJBQXFCLENBQUMsY0FBSSxDQUFDLFNBQVMsQ0FBQyxXQUFXLENBQUMsV0FBVyxFQUFFLENBQUMsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEosSUFBSSxZQUFZLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUM7Z0JBQzlCLGdCQUFNLENBQUMsS0FBSyxDQUFDLCtCQUErQixZQUFZLEVBQUUsQ0FBQyxDQUFDO1lBQ2hFLENBQUM7WUFDRCxLQUFLLENBQUMsT0FBTyxDQUFDLFlBQVksQ0FBQyxDQUFDLENBQUMsNkJBQTZCO1lBQzFELE1BQU07UUFDVixDQUFDO2FBQU0sSUFBSSxXQUFXLENBQUMsU0FBUyxFQUFFLEVBQUUsQ0FBQztZQUNqQyxNQUFNLElBQUksR0FBRyxXQUFXLENBQUMsU0FBUyxFQUFHLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDaEQsbUVBQW1FO1lBQ25FLE1BQU0sVUFBVSxHQUFHLElBQUksS0FBSyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxXQUFXLENBQUMsV0FBVyxFQUFFLElBQUksV0FBVyxDQUFDLGVBQWUsRUFBRSxFQUFFLENBQUM7WUFDbEgsS0FBSyxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztRQUM5QixDQUFDO1FBQ0QsV0FBVyxHQUFHLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQztJQUMxQyxDQUFDO0lBRUQsT0FBTyxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO0FBQzVCLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsU0FBZ0IsYUFBYSxDQUFDLENBQU87SUFDakMsSUFBSSxLQUFtQyxDQUFDO0lBQ3hDLElBQUksS0FBdUMsQ0FBQztJQUM1QyxJQUFJLEtBQW9DLENBQUM7SUFDekMsSUFBSSxLQUFzQyxDQUFDO0lBQzNDLElBQUksS0FBeUMsQ0FBQztJQUM5QyxRQUFRLENBQUMsQ0FBQyxPQUFPLEVBQUUsRUFBRSxDQUFDO1FBQ2xCLEtBQUsscUJBQVUsQ0FBQyxVQUFVO1lBQ3RCLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLFVBQVUsQ0FBRSxDQUFDLFdBQVcsRUFBRSxDQUFDO1FBRTFELEtBQUsscUJBQVUsQ0FBQyxpQkFBaUI7WUFDN0IsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLHFCQUFVLENBQUMsaUJBQWlCLENBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUU3RCxLQUFLLHFCQUFVLENBQUMsZ0JBQWdCO1lBQzVCLEtBQUssR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLHFCQUFVLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUM5QyxJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2hELE9BQU8sS0FBSyxDQUFDLE9BQU8sRUFBRSxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxDQUFDO2lCQUFNLENBQUM7Z0JBQ0osT0FBTyxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDO1lBQ2xDLENBQUM7UUFFTCxLQUFLLHFCQUFVLENBQUMsb0JBQW9CO1lBQ2hDLEtBQUssR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDLHFCQUFVLENBQUMsb0JBQW9CLENBQUMsQ0FBQztZQUNsRCxJQUFJLEtBQUssSUFBSSxLQUFLLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFLENBQUM7Z0JBQ2hELE9BQU8sS0FBSyxDQUFDLE9BQU8sRUFBRSxHQUFHLGFBQWEsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUM5QyxDQUFDO2lCQUFNLENBQUM7Z0JBQ0osT0FBTyxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDO1lBQ2xDLENBQUM7UUFFTCxLQUFLLHFCQUFVLENBQUMsbUJBQW1CO1lBQy9CLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLG1CQUFtQixDQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFL0QsS0FBSyxxQkFBVSxDQUFDLGlCQUFpQjtZQUM3QixPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMscUJBQVUsQ0FBQyxpQkFBaUIsQ0FBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRTdELEtBQUsscUJBQVUsQ0FBQyxpQkFBaUI7WUFDN0IsS0FBSyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMscUJBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO1lBQy9DLElBQUksS0FBSyxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDaEQsT0FBTyxLQUFLLENBQUMsT0FBTyxFQUFFLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlDLENBQUM7aUJBQU0sQ0FBQztnQkFDSixPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFDbEMsQ0FBQztRQUVMLEtBQUsscUJBQVUsQ0FBQyxlQUFlO1lBQzNCLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLGVBQWUsQ0FBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRTNELEtBQUsscUJBQVUsQ0FBQyxXQUFXO1lBQ3ZCLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLFdBQVcsQ0FBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRXZELEtBQUsscUJBQVUsQ0FBQyxXQUFXO1lBQ3ZCLE9BQU8sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLFdBQVcsQ0FBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRXZELEtBQUsscUJBQVUsQ0FBQyxtQkFBbUI7WUFDL0IsS0FBSyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMscUJBQVUsQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO1lBQ2pELElBQUksS0FBSyxJQUFJLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsQ0FBQztnQkFDaEQsT0FBTyxLQUFLLENBQUMsT0FBTyxFQUFFLEdBQUcsYUFBYSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzlDLENBQUM7aUJBQU0sQ0FBQztnQkFDSixPQUFPLEtBQUssRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7WUFDbEMsQ0FBQztRQUVMLEtBQUsscUJBQVUsQ0FBQyxrQkFBa0I7WUFDOUIsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLHFCQUFVLENBQUMsa0JBQWtCLENBQUMsRUFBRSxPQUFPLEVBQUUsSUFBSSxXQUFXLENBQUM7UUFFN0UsS0FBSyxxQkFBVSxDQUFDLFNBQVM7WUFDckIsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLHFCQUFVLENBQUMsU0FBUyxDQUFFLENBQUMsT0FBTyxFQUFFLENBQUM7UUFFckQsS0FBSyxxQkFBVSxDQUFDLG1CQUFtQjtZQUMvQixPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMscUJBQVUsQ0FBQyxtQkFBbUIsQ0FBRSxDQUFDLE9BQU8sRUFBRSxDQUFDO1FBRS9ELEtBQUsscUJBQVUsQ0FBQyxTQUFTO1lBQ3JCLE9BQU8sR0FBRyxHQUFHLENBQUMsQ0FBQyxNQUFNLENBQUMscUJBQVUsQ0FBQyxTQUFTLENBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUUzRCxLQUFLLHFCQUFVLENBQUMsYUFBYTtZQUN6QixPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMscUJBQVUsQ0FBQyxhQUFhLENBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUV6RCxLQUFLLHFCQUFVLENBQUMsZUFBZTtZQUMzQixPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMscUJBQVUsQ0FBQyxlQUFlLENBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUUzRCxLQUFLLHFCQUFVLENBQUMsVUFBVTtZQUN0QixPQUFPLENBQUMsQ0FBQyxNQUFNLENBQUMscUJBQVUsQ0FBQyxVQUFVLENBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUV0RCxLQUFLLHFCQUFVLENBQUMsb0JBQW9CO1lBQ2hDLHVDQUF1QztZQUN2QyxLQUFLLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLG9CQUFvQixDQUFDLENBQUM7WUFDbEQsSUFBSSxLQUFLLElBQUksS0FBSyxDQUFDLGlCQUFpQixFQUFFLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRSxDQUFDO2dCQUNoRCxPQUFPLEtBQUssQ0FBQyxPQUFPLEVBQUUsR0FBRyxHQUFHLEdBQUcsS0FBSyxDQUFDLGlCQUFpQixFQUFFLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQztZQUN0RyxDQUFDO1lBQ0QsT0FBTyxDQUFDLENBQUMsTUFBTSxDQUFDLHFCQUFVLENBQUMsb0JBQW9CLENBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUVoRSxLQUFLLHFCQUFVLENBQUMsV0FBVztZQUN2QixPQUFPLGFBQWEsQ0FBQztRQUV6QjtZQUNJLGtHQUFrRztZQUNsRyxvQ0FBb0M7WUFDcEMsT0FBTyxFQUFFLENBQUM7SUFDZCxDQUFDO0FBQ1QsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFnQixhQUFhLENBQUMsQ0FBTztJQUNqQyxJQUFJLFdBQVcsR0FBRyxFQUFFLENBQUM7SUFDckIsUUFBUSxDQUFDLENBQUMsT0FBTyxFQUFFLEVBQUUsQ0FBQztRQUNsQixLQUFLLHFCQUFVLENBQUMsZ0JBQWdCO1lBQzVCLFdBQVcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLGdCQUFnQixDQUFDLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQ3hILE1BQU07UUFDVixLQUFLLHFCQUFVLENBQUMsb0JBQW9CO1lBQ2hDLFdBQVcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLG9CQUFvQixDQUFDLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQzVILE1BQU07UUFDVixLQUFLLHFCQUFVLENBQUMsaUJBQWlCO1lBQzdCLFdBQVcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLGlCQUFpQixDQUFDLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQ3pILE1BQU07UUFDVixLQUFLLHFCQUFVLENBQUMsbUJBQW1CO1lBQy9CLFdBQVcsR0FBRyxHQUFHLEdBQUcsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxxQkFBVSxDQUFDLG1CQUFtQixDQUFDLEVBQUUsaUJBQWlCLEVBQUUsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsR0FBRyxDQUFDO1lBQzNILE1BQU07UUFDVjtZQUNJLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0VBQWdFLENBQUMsQ0FBQyxXQUFXLEVBQUUsRUFBRSxDQUFDLENBQUM7SUFDM0csQ0FBQztJQUNELE9BQU8sV0FBVyxDQUFDO0FBQ3ZCLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBBcnJvd0Z1bmN0aW9uLCBDYWxsRXhwcmVzc2lvbiwgQ2xhc3NEZWNsYXJhdGlvbiwgQ29uc3RydWN0b3JEZWNsYXJhdGlvbiwgRGVjb3JhdG9yLCBFbnVtRGVjbGFyYXRpb24sIEZ1bmN0aW9uRGVjbGFyYXRpb24sIEZ1bmN0aW9uRXhwcmVzc2lvbiwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiwgSWRlbnRpZmllciwgSW1wb3J0RGVjbGFyYXRpb24sIEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uLCBJbnRlcmZhY2VEZWNsYXJhdGlvbiwgTWV0aG9kRGVjbGFyYXRpb24sIE1ldGhvZFNpZ25hdHVyZSwgTW9kdWxlRGVjbGFyYXRpb24sIE5vZGUsIFByb3BlcnR5RGVjbGFyYXRpb24sIFNldEFjY2Vzc29yRGVjbGFyYXRpb24sIFNvdXJjZUZpbGUsIFN5bnRheEtpbmQsIFR5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbiwgVmFyaWFibGVEZWNsYXJhdGlvbiB9IGZyb20gXCJ0cy1tb3JwaFwiO1xyXG5pbXBvcnQgeyBlbnRpdHlEaWN0aW9uYXJ5LCBsb2dnZXIgfSBmcm9tIFwiLi9hbmFseXplXCI7XHJcbmltcG9ydCBwYXRoIGZyb20gXCJwYXRoXCI7XHJcbmltcG9ydCB7IFRTTW9ycGhUeXBlRGVjbGFyYXRpb24gfSBmcm9tIFwiLi9mYW1peF9mdW5jdGlvbnMvRW50aXR5RGljdGlvbmFyeVwiO1xyXG5cclxudHlwZSBGUU5Ob2RlID0gU291cmNlRmlsZSB8IFZhcmlhYmxlRGVjbGFyYXRpb24gfCBBcnJvd0Z1bmN0aW9uIHwgSWRlbnRpZmllciB8IE1ldGhvZERlY2xhcmF0aW9uIHwgTWV0aG9kU2lnbmF0dXJlIHwgRnVuY3Rpb25EZWNsYXJhdGlvbiB8IEZ1bmN0aW9uRXhwcmVzc2lvbiB8IFByb3BlcnR5RGVjbGFyYXRpb24gfCBUU01vcnBoVHlwZURlY2xhcmF0aW9uIHwgRW51bURlY2xhcmF0aW9uIHwgSW1wb3J0RGVjbGFyYXRpb24gfCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiB8IENhbGxFeHByZXNzaW9uIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uIHwgQ2xhc3NEZWNsYXJhdGlvbiB8IEludGVyZmFjZURlY2xhcmF0aW9uIHwgRGVjb3JhdG9yIHwgTW9kdWxlRGVjbGFyYXRpb247XHJcblxyXG4vLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25vLXVudXNlZC12YXJzXHJcbmZ1bmN0aW9uIGlzRlFOTm9kZShub2RlOiBOb2RlKTogbm9kZSBpcyBGUU5Ob2RlIHtcclxuICAgIHJldHVybiBOb2RlLmlzVmFyaWFibGVEZWNsYXJhdGlvbihub2RlKSB8fCBOb2RlLmlzQXJyb3dGdW5jdGlvbihub2RlKSB8fCBOb2RlLmlzSWRlbnRpZmllcihub2RlKSB8fCBOb2RlLmlzTWV0aG9kRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0NsYXNzRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0NsYXNzRXhwcmVzc2lvbihub2RlKSB8fCBOb2RlLmlzRGVjb3JhdG9yKG5vZGUpIHx8IE5vZGUuaXNNb2R1bGVEZWNsYXJhdGlvbihub2RlKSB8fCBOb2RlLmlzQ2FsbEV4cHJlc3Npb24obm9kZSk7XHJcbn1cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGUU4obm9kZTogRlFOTm9kZSB8IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgY29uc3QgYWJzb2x1dGVQYXRoUHJvamVjdCA9IGVudGl0eURpY3Rpb25hcnkuZmFtaXhSZXAuZ2V0QWJzb2x1dGVQYXRoKCk7XHJcblxyXG4gICAgY29uc3Qgc291cmNlRmlsZSA9IG5vZGUuZ2V0U291cmNlRmlsZSgpO1xyXG4gICAgY29uc3QgcGFydHM6IHN0cmluZ1tdID0gW107XHJcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCB1bmRlZmluZWQgPSBub2RlO1xyXG5cclxuICAgIHdoaWxlIChjdXJyZW50Tm9kZSAmJiAhTm9kZS5pc1NvdXJjZUZpbGUoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgY29uc3QgeyBsaW5lLCBjb2x1bW4gfSA9IHNvdXJjZUZpbGUuZ2V0TGluZUFuZENvbHVtbkF0UG9zKGN1cnJlbnROb2RlLmdldFN0YXJ0KCkpO1xyXG4gICAgICAgIGNvbnN0IGxjID0gYCR7bGluZX06JHtjb2x1bW59YDtcclxuICAgICAgICBpZiAoTm9kZS5pc0NsYXNzRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8IFxyXG4gICAgICAgICAgICBOb2RlLmlzQ2xhc3NFeHByZXNzaW9uKGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgTm9kZS5pc0ludGVyZmFjZURlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRnVuY3Rpb25EZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgIE5vZGUuaXNNZXRob2REZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgIE5vZGUuaXNNb2R1bGVEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgIE5vZGUuaXNWYXJpYWJsZURlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgTm9kZS5pc0dldEFjY2Vzc29yRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzUHJvcGVydHlEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1BhcmFtZXRlckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRGVjb3JhdG9yKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzVHlwZUFsaWFzRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNFbnVtRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNFbnVtTWVtYmVyKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzUGFyYW1ldGVyZWQoY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNQcm9wZXJ0eVNpZ25hdHVyZShjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc0FycmF5TGl0ZXJhbEV4cHJlc3Npb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNJbXBvcnRTcGVjaWZpZXIoY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNJZGVudGlmaWVyKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBjb25zdCBuYW1lID0gTm9kZS5pc0lkZW50aWZpZXIoY3VycmVudE5vZGUpID8gY3VycmVudE5vZGUuZ2V0VGV4dCgpIFxyXG4gICAgICAgICAgICAgICAgOiBnZXROYW1lT2ZOb2RlKGN1cnJlbnROb2RlKSAvKiBjdXJyZW50Tm9kZS5nZXROYW1lKCkgKi8gfHwgJ1VubmFtZWRfJyArIGN1cnJlbnROb2RlLmdldEtpbmROYW1lKCkgKyBgKCR7bGN9KWA7XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQobmFtZSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIC8vIHVubmFtZWQgbm9kZXNcclxuICAgICAgICBlbHNlIGlmIChOb2RlLmlzQXJyb3dGdW5jdGlvbihjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgICAgICAgICBOb2RlLmlzQmxvY2soY3VycmVudE5vZGUpIHx8IFxyXG4gICAgICAgICAgICAgICAgICAgTm9kZS5pc0ZvckluU3RhdGVtZW50KGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgICAgICAgIE5vZGUuaXNGb3JPZlN0YXRlbWVudChjdXJyZW50Tm9kZSkgfHwgXHJcbiAgICAgICAgICAgICAgICAgICBOb2RlLmlzRm9yU3RhdGVtZW50KGN1cnJlbnROb2RlKSB8fCBcclxuICAgICAgICAgICAgICAgICAgIE5vZGUuaXNDYXRjaENsYXVzZShjdXJyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgcGFydHMudW5zaGlmdChgJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfSgke2xjfSlgKTtcclxuICAgICAgICB9IGVsc2UgaWYgKE5vZGUuaXNDb25zdHJ1Y3RvckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBwYXJ0cy51bnNoaWZ0KGBjb25zdHJ1Y3RvcmApO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIC8vIEZvciBvdGhlciBraW5kcywgeW91IG1pZ2h0IHdhbnQgdG8gaGFuZGxlIHRoZW0gc3BlY2lmaWNhbGx5IG9yIGlnbm9yZVxyXG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYElnbm9yaW5nIG5vZGUga2luZDogJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfWApO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLmdldFBhcmVudCgpO1xyXG4gICAgfVxyXG5cclxuXHJcblxyXG4gICAgLy8gUHJlcGVuZCB0aGUgcmVsYXRpdmUgcGF0aCBvZiB0aGUgc291cmNlIGZpbGVcclxuICAgIGxldCByZWxhdGl2ZVBhdGggPSBlbnRpdHlEaWN0aW9uYXJ5LmNvbnZlcnRUb1JlbGF0aXZlUGF0aChcclxuICAgICAgICBwYXRoLm5vcm1hbGl6ZShzb3VyY2VGaWxlLmdldEZpbGVQYXRoKCkpLCBcclxuICAgICAgICAgICAgICAgICAgICAgICBhYnNvbHV0ZVBhdGhQcm9qZWN0KS5yZXBsYWNlKC9cXFxcL3NnLCBcIi9cIik7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgXHJcbiAgICBpZiAocmVsYXRpdmVQYXRoLmluY2x1ZGVzKFwiLi5cIikpIHtcclxuICAgICAgICBsb2dnZXIuZXJyb3IoYFJlbGF0aXZlIHBhdGggY29udGFpbnMgLi4vOiAke3JlbGF0aXZlUGF0aH1gKTtcclxuICAgIH1cclxuICAgIGlmIChyZWxhdGl2ZVBhdGguc3RhcnRzV2l0aChcIi9cIikpIHtcclxuICAgICAgICByZWxhdGl2ZVBhdGggPSByZWxhdGl2ZVBhdGguc3Vic3RyaW5nKDEpO1xyXG4gICAgfVxyXG4gICAgcGFydHMudW5zaGlmdChgeyR7cmVsYXRpdmVQYXRofX1gKTtcclxuICAgIGNvbnN0IGZxbiA9IHBhcnRzLmpvaW4oXCIuXCIpICsgYFske25vZGUuZ2V0S2luZE5hbWUoKX1dYDsgIC8vIGRpc2FtYmlndWF0ZVxyXG5cclxuICAgIGxvZ2dlci5kZWJ1ZyhgR2VuZXJhdGVkIEZRTjogJHtmcW59IGZvciBub2RlOiAke25vZGUuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgIHJldHVybiBmcW47XHJcbn1cclxuXHJcblxyXG5leHBvcnQgZnVuY3Rpb24gZ2V0VW5pcXVlRlFOKG5vZGU6IE5vZGUpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xyXG4gICAgY29uc3QgYWJzb2x1dGVQYXRoUHJvamVjdCA9IGVudGl0eURpY3Rpb25hcnkuZmFtaXhSZXAuZ2V0QWJzb2x1dGVQYXRoKCk7XHJcbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcclxuXHJcbiAgICBpZiAobm9kZSBpbnN0YW5jZW9mIFNvdXJjZUZpbGUpIHtcclxuICAgICAgICByZXR1cm4gZW50aXR5RGljdGlvbmFyeS5jb252ZXJ0VG9SZWxhdGl2ZVBhdGgocGF0aC5ub3JtYWxpemUobm9kZS5nZXRGaWxlUGF0aCgpKSwgYWJzb2x1dGVQYXRoUHJvamVjdCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IGN1cnJlbnROb2RlOiBOb2RlIHwgdW5kZWZpbmVkID0gbm9kZTtcclxuICAgIHdoaWxlIChjdXJyZW50Tm9kZSkge1xyXG4gICAgICAgIGlmIChOb2RlLmlzU291cmNlRmlsZShjdXJyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgY29uc3QgcmVsYXRpdmVQYXRoID0gZW50aXR5RGljdGlvbmFyeS5jb252ZXJ0VG9SZWxhdGl2ZVBhdGgocGF0aC5ub3JtYWxpemUoY3VycmVudE5vZGUuZ2V0RmlsZVBhdGgoKSksIGFic29sdXRlUGF0aFByb2plY3QpLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xyXG4gICAgICAgICAgICBpZiAocmVsYXRpdmVQYXRoLmluY2x1ZGVzKFwiLi5cIikpIHtcclxuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgUmVsYXRpdmUgcGF0aCBjb250YWlucyAuLi86ICR7cmVsYXRpdmVQYXRofWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQocmVsYXRpdmVQYXRoKTsgLy8gQWRkIGZpbGUgcGF0aCBhdCB0aGUgc3RhcnRcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50Tm9kZS5nZXRTeW1ib2woKSkge1xyXG4gICAgICAgICAgICBjb25zdCBuYW1lID0gY3VycmVudE5vZGUuZ2V0U3ltYm9sKCkhLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgLy8gRm9yIGFub255bW91cyBub2RlcywgdXNlIGtpbmQgYW5kIHBvc2l0aW9uIGFzIHVuaXF1ZSBpZGVudGlmaWVyc1xyXG4gICAgICAgICAgICBjb25zdCBpZGVudGlmaWVyID0gbmFtZSAhPT0gXCJfX2NvbXB1dGVkXCIgPyBuYW1lIDogYCR7Y3VycmVudE5vZGUuZ2V0S2luZE5hbWUoKX1fJHtjdXJyZW50Tm9kZS5nZXRTdGFydExpbmVQb3MoKX1gO1xyXG4gICAgICAgICAgICBwYXJ0cy51bnNoaWZ0KGlkZW50aWZpZXIpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLmdldFBhcmVudCgpO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBwYXJ0cy5qb2luKFwiOjpcIik7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZXRzIHRoZSBuYW1lIG9mIGEgbm9kZSwgaWYgaXQgaGFzIG9uZVxyXG4gKiBAcGFyYW0gYSBBIG5vZGVcclxuICogQHJldHVybnMgVGhlIG5hbWUgb2YgdGhlIG5vZGUsIG9yIGFuIGVtcHR5IHN0cmluZyBpZiBpdCBkb2Vzbid0IGhhdmUgb25lXHJcbiAqL1xyXG5leHBvcnQgZnVuY3Rpb24gZ2V0TmFtZU9mTm9kZShhOiBOb2RlKTogc3RyaW5nIHtcclxuICAgIGxldCBjS2luZDogQ2xhc3NEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZDtcclxuICAgIGxldCBpS2luZDogSW50ZXJmYWNlRGVjbGFyYXRpb24gfCB1bmRlZmluZWQ7XHJcbiAgICBsZXQgbUtpbmQ6IE1ldGhvZERlY2xhcmF0aW9uIHwgdW5kZWZpbmVkO1xyXG4gICAgbGV0IGZLaW5kOiBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgdW5kZWZpbmVkOyBcclxuICAgIGxldCBhbGlhczogVFNNb3JwaFR5cGVEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZDtcclxuICAgIHN3aXRjaCAoYS5nZXRLaW5kKCkpIHtcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuU291cmNlRmlsZTpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuU291cmNlRmlsZSkhLmdldEJhc2VOYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Nb2R1bGVEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuTW9kdWxlRGVjbGFyYXRpb24pIS5nZXROYW1lKCk7IFxyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgY0tpbmQgPSBhLmFzS2luZChTeW50YXhLaW5kLkNsYXNzRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoY0tpbmQgJiYgY0tpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY0tpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkludGVyZmFjZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBpS2luZCA9IGEuYXNLaW5kKFN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoaUtpbmQgJiYgaUtpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaUtpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Qcm9wZXJ0eURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5Qcm9wZXJ0eURlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpOyAgICBcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlByb3BlcnR5U2lnbmF0dXJlOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5Qcm9wZXJ0eVNpZ25hdHVyZSkhLmdldE5hbWUoKTsgICAgXHJcbiAgICBcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuTWV0aG9kRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIG1LaW5kID0gYS5hc0tpbmQoU3ludGF4S2luZC5NZXRob2REZWNsYXJhdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChtS2luZCAmJiBtS2luZC5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBtS2luZC5nZXROYW1lKCkgKyBnZXRQYXJhbWV0ZXJzKGEpO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG1LaW5kPy5nZXROYW1lKCkgfHwgXCJcIjtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuTWV0aG9kU2lnbmF0dXJlOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5NZXRob2RTaWduYXR1cmUpIS5nZXROYW1lKCk7ICAgXHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5HZXRBY2Nlc3NvcjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuR2V0QWNjZXNzb3IpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5TZXRBY2Nlc3NvcjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuU2V0QWNjZXNzb3IpIS5nZXROYW1lKCk7XHJcbiAgICBcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRnVuY3Rpb25EZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgZktpbmQgPSBhLmFzS2luZChTeW50YXhLaW5kLkZ1bmN0aW9uRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoZktpbmQgJiYgZktpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZktpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBmS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkZ1bmN0aW9uRXhwcmVzc2lvbjpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuRnVuY3Rpb25FeHByZXNzaW9uKT8uZ2V0TmFtZSgpIHx8IFwiYW5vbnltb3VzXCI7XHJcbiAgICAgICAgICAgIFxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5QYXJhbWV0ZXI6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlBhcmFtZXRlcikhLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgICAgIFxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRGVjb3JhdG9yOlxyXG4gICAgICAgICAgICByZXR1cm4gXCJAXCIgKyBhLmFzS2luZChTeW50YXhLaW5kLkRlY29yYXRvcikhLmdldE5hbWUoKTsgICAgXHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5UeXBlUGFyYW1ldGVyOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5UeXBlUGFyYW1ldGVyKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRW51bURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5FbnVtRGVjbGFyYXRpb24pIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5FbnVtTWVtYmVyOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5FbnVtTWVtYmVyKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuVHlwZUFsaWFzRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIC8vIHNwZWNpYWwgY2FzZSBmb3IgcGFyYW1ldGVyaXplZCB0eXBlc1xyXG4gICAgICAgICAgICBhbGlhcyA9IGEuYXNLaW5kKFN5bnRheEtpbmQuVHlwZUFsaWFzRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoYWxpYXMgJiYgYWxpYXMuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYWxpYXMuZ2V0TmFtZSgpICsgXCI8XCIgKyBhbGlhcy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCh0cCA9PiB0cC5nZXROYW1lKCkpLmpvaW4oXCIsIFwiKSArIFwiPlwiO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlR5cGVBbGlhc0RlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuQ29uc3RydWN0b3I6XHJcbiAgICAgICAgICAgIHJldHVybiBcImNvbnN0cnVjdG9yXCI7ICAgXHJcbiAgICAgICAgXHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKGBnZXROYW1lT2ZOb2RlIGNhbGxlZCBvbiBhIG5vZGUgdGhhdCBkb2Vzbid0IGhhdmUgYSBuYW1lOiAke2EuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgICAgICAgICAgLy8gYW5jZXN0b3IgaGFzbid0IGdvdCBhIHVzZWZ1bCBuYW1lXHJcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgICAgIH1cclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIG5hbWUgb2YgYSBub2RlLCBpZiBpdCBoYXMgb25lXHJcbiAqIEBwYXJhbSBhIEEgbm9kZVxyXG4gKiBAcmV0dXJucyBUaGUgbmFtZSBvZiB0aGUgbm9kZSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRQYXJhbWV0ZXJzKGE6IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgbGV0IHBhcmFtU3RyaW5nID0gXCJcIjtcclxuICAgIHN3aXRjaCAoYS5nZXRLaW5kKCkpIHtcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcGFyYW1TdHJpbmcgPSBcIjxcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbik/LmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCI7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5JbnRlcmZhY2VEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcGFyYW1TdHJpbmcgPSBcIjxcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24pPy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCh0cCA9PiB0cC5nZXROYW1lKCkpLmpvaW4oXCIsIFwiKSArIFwiPlwiO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuTWV0aG9kRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHBhcmFtU3RyaW5nID0gXCI8XCIgKyBhLmFzS2luZChTeW50YXhLaW5kLk1ldGhvZERlY2xhcmF0aW9uKT8uZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAodHAgPT4gdHAuZ2V0TmFtZSgpKS5qb2luKFwiLCBcIikgKyBcIj5cIjtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkZ1bmN0aW9uRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHBhcmFtU3RyaW5nID0gXCI8XCIgKyBhLmFzS2luZChTeW50YXhLaW5kLkZ1bmN0aW9uRGVjbGFyYXRpb24pPy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCh0cCA9PiB0cC5nZXROYW1lKCkpLmpvaW4oXCIsIFwiKSArIFwiPlwiO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBkZWZhdWx0OlxyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYGdldFBhcmFtZXRlcnMgY2FsbGVkIG9uIGEgbm9kZSB0aGF0IGRvZXNuJ3QgaGF2ZSBwYXJhbWV0ZXJzOiAke2EuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgIH1cclxuICAgIHJldHVybiBwYXJhbVN0cmluZztcclxufVxyXG4iXX0=
498
+ /**
499
+ * Gets the FQN of an unresolved interface that is being implemented or extended
500
+ * @param unresolvedInheritedClassOrInterface The expression with type arguments representing the interface
501
+ * @returns The FQN of the unresolved interface
502
+ */
503
+ function getFQNUnresolvedInheritedClassOrInterface(unresolvedInheritedClassOrInterface) {
504
+ // Check for either ClassDeclaration or InterfaceDeclaration ancestor
505
+ const classAncestor = unresolvedInheritedClassOrInterface.getFirstAncestorByKind(ts_morph_1.SyntaxKind.ClassDeclaration);
506
+ const interfaceAncestor = unresolvedInheritedClassOrInterface.getFirstAncestorByKind(ts_morph_1.SyntaxKind.InterfaceDeclaration);
507
+ // Validate the context
508
+ if (!classAncestor && !interfaceAncestor) {
509
+ throw new Error("getFQNUnresolvedClassOrInterface called on a node that is not in an implements or extends context");
510
+ }
511
+ // Check if it's a valid implements/extends context
512
+ let isValidContext = false;
513
+ let classExtendsClass = false;
514
+ if (classAncestor) {
515
+ // check if the class is extending or implementing an interface
516
+ const extendsClause = classAncestor.getExtends();
517
+ const implementsClause = classAncestor.getImplements();
518
+ isValidContext = (extendsClause !== undefined) || (implementsClause && implementsClause.length > 0);
519
+ classExtendsClass = extendsClause !== undefined;
520
+ }
521
+ else if (interfaceAncestor) {
522
+ // Check extends clause for interfaces
523
+ const extendsClause = interfaceAncestor.getExtends();
524
+ isValidContext = extendsClause && extendsClause.length > 0;
525
+ }
526
+ if (!isValidContext) {
527
+ throw new Error("getFQNUnresolvedInterface called on a node that is not in a valid implements or extends context");
528
+ }
529
+ // get the name of the interface
530
+ const name = unresolvedInheritedClassOrInterface.getExpression().getText();
531
+ // Find where it's imported - search the entire source file
532
+ const sourceFile = unresolvedInheritedClassOrInterface.getSourceFile();
533
+ const importDecls = sourceFile.getImportDeclarations();
534
+ for (const importDecl of importDecls) {
535
+ const moduleSpecifier = importDecl.getModuleSpecifierValue();
536
+ const importClause = importDecl.getImportClause();
537
+ if (importClause) {
538
+ const namedImports = importClause.getNamedImports();
539
+ // declarationName is ClassDeclaration if "class extends class"
540
+ const declarationName = classExtendsClass ? "ClassDeclaration" : "InterfaceDeclaration";
541
+ for (const namedImport of namedImports) {
542
+ if (namedImport.getName() === name) {
543
+ analyze_1.logger.debug(`Found import for ${name} in ${moduleSpecifier}`);
544
+ return `{module:${moduleSpecifier}}.${name}[${declarationName}]`;
545
+ }
546
+ }
547
+ }
548
+ }
549
+ // If not found, return a default FQN format
550
+ return `{unknown-module}.${name}[InterfaceDeclaration]`;
551
+ }
552
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnFuLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2Zxbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7OztBQTZPQSx3QkFpSkM7QUFHRCxvQ0EyQkM7QUFPRCxzQ0FpR0M7QUFPRCxzQ0FtQkM7QUFPRCw4RkEwREM7QUEvbEJELHVDQUE0ZDtBQUM1ZCx1Q0FBcUQ7QUFDckQsZ0RBQXdCO0FBS3hCLDZEQUE2RDtBQUM3RCxTQUFTLFNBQVMsQ0FBQyxJQUFVO0lBQ3pCLE9BQU8sZUFBSSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLElBQUksZUFBSSxDQUFDLGtCQUFrQixDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxpQkFBaUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLGVBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsSUFBSSxlQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLENBQUM7QUFDblMsQ0FBQztBQUVEOzs7Ozs7OztHQVFHO0FBQ0gsU0FBUyxtQkFBbUIsQ0FBQyxVQUFzQjtJQUMvQyxNQUFNLFFBQVEsR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztJQUUzQyxVQUFVLENBQUMsdUJBQXVCLEVBQUUsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUU7UUFDbkQscUNBQXFDO1FBQ3JDLE1BQU0sV0FBVyxHQUFHLE9BQU8sQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUU3QyxJQUFJLENBQUMsV0FBVyxJQUFJLENBQUMsZUFBSSxDQUFDLHlCQUF5QixDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUM7WUFDL0QsT0FBTztRQUNYLENBQUM7UUFFRCxXQUFXLENB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R0FBRyxVQUFVLENBQUMscUJBQXFCLEVBQUUsQ0FBQztJQUV2RCxLQUFLLE1BQU0sVUFBVSxJQUFJLFdBQVcsRUFBRSxDQUFDO1FBQ25DLE1BQU0sZUFBZSxHQUFHLFVBQVUsQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBQzdELE1BQU0sWUFBWSxHQUFHLFVBQVUsQ0FBQyxlQUFlLEVBQUUsQ0FBQztRQUVsRCxJQUFJLFlBQVksRUFBRSxDQUFDO1lBQ2YsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDLGVBQWUsRUFBRSxDQUFDO1lBQ3BELCtEQUErRDtZQUMvRCxNQUFNLGVBQWUsR0FBRyxpQkFBaUIsQ0FBQyxDQUFDLENBQUMsa0JBQWtCLENBQUMsQ0FBQyxDQUFDLHNCQUFzQixDQUFDO1lBRXhGLEtBQUssTUFBTSxXQUFXLElBQUksWUFBWSxFQUFFLENBQUM7Z0JBQ3JDLElBQUksV0FBVyxDQUFDLE9BQU8sRUFBRSxLQUFLLElBQUksRUFBRSxDQUFDO29CQUNqQyxnQkFBTSxDQUFDLEtBQUssQ0FBQyxvQkFBb0IsSUFBSSxPQUFPLGVBQWUsRUFBRSxDQUFDLENBQUM7b0JBQy9ELE9BQU8sV0FBVyxlQUFlLEtBQUssSUFBSSxJQUFJLGVBQWUsR0FBRyxDQUFDO2dCQUNyRSxDQUFDO1lBQ0wsQ0FBQztRQUNMLENBQUM7SUFDTCxDQUFDO0lBRUQsNENBQTRDO0lBQzVDLE9BQU8sb0JBQW9CLElBQUksd0JBQXdCLENBQUM7QUFDNUQsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFycm93RnVuY3Rpb24sIENhbGxFeHByZXNzaW9uLCBDbGFzc0RlY2xhcmF0aW9uLCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uLCBEZWNvcmF0b3IsIEVudW1EZWNsYXJhdGlvbiwgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzLCBGdW5jdGlvbkRlY2xhcmF0aW9uLCBGdW5jdGlvbkV4cHJlc3Npb24sIEdldEFjY2Vzc29yRGVjbGFyYXRpb24sIElkZW50aWZpZXIsIEltcG9ydERlY2xhcmF0aW9uLCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiwgSW50ZXJmYWNlRGVjbGFyYXRpb24sIE1ldGhvZERlY2xhcmF0aW9uLCBNZXRob2RTaWduYXR1cmUsIE1vZHVsZURlY2xhcmF0aW9uLCBOb2RlLCBQcm9wZXJ0eURlY2xhcmF0aW9uLCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uLCBTb3VyY2VGaWxlLCBTeW50YXhLaW5kLCBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24sIFZhcmlhYmxlRGVjbGFyYXRpb24gfSBmcm9tIFwidHMtbW9ycGhcIjtcclxuaW1wb3J0IHsgZW50aXR5RGljdGlvbmFyeSwgbG9nZ2VyIH0gZnJvbSBcIi4vYW5hbHl6ZVwiO1xyXG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xyXG5pbXBvcnQgeyBUU01vcnBoVHlwZURlY2xhcmF0aW9uIH0gZnJvbSBcIi4vZmFtaXhfZnVuY3Rpb25zL0VudGl0eURpY3Rpb25hcnlcIjtcclxuXHJcbnR5cGUgRlFOTm9kZSA9IFNvdXJjZUZpbGUgfCBWYXJpYWJsZURlY2xhcmF0aW9uIHwgQXJyb3dGdW5jdGlvbiB8IElkZW50aWZpZXIgfCBNZXRob2REZWNsYXJhdGlvbiB8IE1ldGhvZFNpZ25hdHVyZSB8IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uIHwgVFNNb3JwaFR5cGVEZWNsYXJhdGlvbiB8IEVudW1EZWNsYXJhdGlvbiB8IEltcG9ydERlY2xhcmF0aW9uIHwgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24gfCBDYWxsRXhwcmVzc2lvbiB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgQ29uc3RydWN0b3JEZWNsYXJhdGlvbiB8IFR5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IERlY29yYXRvciB8IE1vZHVsZURlY2xhcmF0aW9uO1xyXG5cclxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIEB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1xyXG5mdW5jdGlvbiBpc0ZRTk5vZGUobm9kZTogTm9kZSk6IG5vZGUgaXMgRlFOTm9kZSB7XHJcbiAgICByZXR1cm4gTm9kZS5pc1ZhcmlhYmxlRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0Fycm93RnVuY3Rpb24obm9kZSkgfHwgTm9kZS5pc0lkZW50aWZpZXIobm9kZSkgfHwgTm9kZS5pc01ldGhvZERlY2xhcmF0aW9uKG5vZGUpIHx8IE5vZGUuaXNDbGFzc0RlY2xhcmF0aW9uKG5vZGUpIHx8IE5vZGUuaXNDbGFzc0V4cHJlc3Npb24obm9kZSkgfHwgTm9kZS5pc0RlY29yYXRvcihub2RlKSB8fCBOb2RlLmlzTW9kdWxlRGVjbGFyYXRpb24obm9kZSkgfHwgTm9kZS5pc0NhbGxFeHByZXNzaW9uKG5vZGUpO1xyXG59XHJcblxyXG4vKipcclxuICogQnVpbGRzIGEgbWFwIG9mIG1ldGhvZCBwb3NpdGlvbnMgdG8gdGhlaXIgcHJvcGVydHkga2V5cyBpbiBvYmplY3QgbGl0ZXJhbHMuXHJcbiAqIFNjYW5zIGFsbCB2YXJpYWJsZSBkZWNsYXJhdGlvbnMgaW4gYSBzb3VyY2UgZmlsZSwgdGFyZ2V0aW5nIG9iamVjdCBsaXRlcmFscyB3aXRoIGFueSBrZXlzXHJcbiAqIChlLmcuLCBgMzogeyBtZXRob2QoKSB7fSB9YCBvciBgYWRkOiB7IGNvbXB1dGUoKSB7fSB9YCksIGFuZCBtYXBzIGVhY2ggbWV0aG9kJ3Mgc3RhcnQgcG9zaXRpb24gdG8gaXRzIGtleS5cclxuICogTG9ncyBlYWNoIHN0ZXAgZm9yIGRlYnVnZ2luZy5cclxuICogXHJcbiAqIEBwYXJhbSBzb3VyY2VGaWxlIFRoZSBUeXBlU2NyaXB0IHNvdXJjZSBmaWxlIHRvIGFuYWx5emVcclxuICogQHJldHVybnMgQSBNYXAgd2hlcmUga2V5cyBhcmUgbWV0aG9kIHN0YXJ0IHBvc2l0aW9ucyBhbmQgdmFsdWVzIGFyZSB0aGVpciBwcm9wZXJ0eSBrZXlzIChlLmcuLCBcIjNcIiwgXCJhZGRcIilcclxuICovXHJcbmZ1bmN0aW9uIGJ1aWxkU3RhZ2VNZXRob2RNYXAoc291cmNlRmlsZTogU291cmNlRmlsZSk6IE1hcDxudW1iZXIsIHN0cmluZz4ge1xyXG4gICAgY29uc3Qgc3RhZ2VNYXAgPSBuZXcgTWFwPG51bWJlciwgc3RyaW5nPigpO1xyXG5cclxuICAgIHNvdXJjZUZpbGUuZ2V0VmFyaWFibGVEZWNsYXJhdGlvbnMoKS5mb3JFYWNoKHZhckRlY2wgPT4ge1xyXG4gICAgICAgIC8vIGNvbnN0IHZhck5hbWUgPSB2YXJEZWNsLmdldE5hbWUoKTtcclxuICAgICAgICBjb25zdCBpbml0aWFsaXplciA9IHZhckRlY2wuZ2V0SW5pdGlhbGl6ZXIoKTtcclxuXHJcbiAgICAgICAgaWYgKCFpbml0aWFsaXplciB8fCAhTm9kZS5pc09iamVjdExpdGVyYWxFeHByZXNzaW9uKGluaXRpYWxpemVyKSkge1xyXG4gICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpbml0aWFsaXplci5nZXRQcm9wZXJ0aWVzKCkuZm9yRWFjaChwcm9wID0+IHtcclxuICAgICAgICAgICAgbGV0IGtleTogc3RyaW5nIHwgdW5kZWZpbmVkO1xyXG5cclxuICAgICAgICAgICAgaWYgKE5vZGUuaXNQcm9wZXJ0eUFzc2lnbm1lbnQocHJvcCkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5hbWVOb2RlID0gcHJvcC5nZXROYW1lTm9kZSgpO1xyXG5cclxuICAgICAgICAgICAgICAgIGlmIChOb2RlLmlzSWRlbnRpZmllcihuYW1lTm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBrZXkgPSBuYW1lTm9kZS5nZXRUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE5vZGUuaXNTdHJpbmdMaXRlcmFsKG5hbWVOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleSA9IG5hbWVOb2RlLmdldFRleHQoKS5yZXBsYWNlKC9eXCIoLispXCIkLywgJyQxJykucmVwbGFjZSgvXicoLispJyQvLCAnJDEnKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoTm9kZS5pc051bWVyaWNMaXRlcmFsKG5hbWVOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGtleSA9IG5hbWVOb2RlLmdldFRleHQoKTtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoTm9kZS5pc0NvbXB1dGVkUHJvcGVydHlOYW1lKG5hbWVOb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBuYW1lTm9kZS5nZXRFeHByZXNzaW9uKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKE5vZGUuaXNJZGVudGlmaWVyKGV4cHJlc3Npb24pKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIFJlc29sdmUgdmFyaWFibGUgdmFsdWUgaWYgcG9zc2libGVcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3ltYm9sID0gZXhwcmVzc2lvbi5nZXRTeW1ib2woKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHN5bWJvbCkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZGVjbCA9IHN5bWJvbC5nZXREZWNsYXJhdGlvbnMoKVswXTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChOb2RlLmlzVmFyaWFibGVEZWNsYXJhdGlvbihkZWNsKSAmJiBkZWNsLmdldEluaXRpYWxpemVyKCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbml0ID0gZGVjbC5nZXRJbml0aWFsaXplcigpITtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoTm9kZS5pc1N0cmluZ0xpdGVyYWwoaW5pdCkgfHwgTm9kZS5pc051bWVyaWNMaXRlcmFsKGluaXQpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGluaXQuZ2V0VGV4dCgpLnJlcGxhY2UoL15cIiguKylcIiQvLCAnJDEnKS5yZXBsYWNlKC9eJyguKyknJC8sICckMScpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5ID0gZXhwcmVzc2lvbi5nZXRUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE5vZGUuaXNCaW5hcnlFeHByZXNzaW9uKGV4cHJlc3Npb24pICYmIGV4cHJlc3Npb24uZ2V0T3BlcmF0b3JUb2tlbigpLmdldFRleHQoKSA9PT0gJysnKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIC8vIEhhbmRsZSBzaW1wbGUgc3RyaW5nIGNvbmNhdGVuYXRpb24gKGUuZy4sIFwiQVwiICsgXCJCXCIpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGxlZnQgPSBleHByZXNzaW9uLmdldExlZnQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcmlnaHQgPSBleHByZXNzaW9uLmdldFJpZ2h0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChOb2RlLmlzU3RyaW5nTGl0ZXJhbChsZWZ0KSAmJiBOb2RlLmlzU3RyaW5nTGl0ZXJhbChyaWdodCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGxlZnQuZ2V0TGl0ZXJhbFRleHQoKSArIHJpZ2h0LmdldExpdGVyYWxUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKE5vZGUuaXNUZW1wbGF0ZUV4cHJlc3Npb24oZXhwcmVzc2lvbikpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gSGFuZGxlIHRlbXBsYXRlIGxpdGVyYWxzIChlLmcuLCBga2V5LSR7MX1gKVxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBoZWFkID0gZXhwcmVzc2lvbi5nZXRIZWFkKCkuZ2V0TGl0ZXJhbFRleHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3Qgc3BhbnMgPSBleHByZXNzaW9uLmdldFRlbXBsYXRlU3BhbnMoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHNwYW5zLmxlbmd0aCA9PT0gMSAmJiBOb2RlLmlzTnVtZXJpY0xpdGVyYWwoc3BhbnNbMF0uZ2V0RXhwcmVzc2lvbigpKSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbnVtID0gc3BhbnNbMF0uZ2V0RXhwcmVzc2lvbigpLmdldFRleHQoKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGtleSA9IGAke2hlYWR9JHtudW19YDtcclxuICAgICAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgICAgICBpZiAoIWtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBrZXkgPSBleHByZXNzaW9uLmdldFRleHQoKTsgLy8gRmFsbGJhY2tcclxuICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICBjb25zdCBwcm9wSW5pdGlhbGl6ZXIgPSBwcm9wLmdldEluaXRpYWxpemVyKCk7XHJcbiAgICAgICAgICAgICAgICBpZiAocHJvcEluaXRpYWxpemVyICYmIE5vZGUuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihwcm9wSW5pdGlhbGl6ZXIpKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcHJvcEluaXRpYWxpemVyLmdldERlc2NlbmRhbnRzT2ZLaW5kKFN5bnRheEtpbmQuTWV0aG9kRGVjbGFyYXRpb24pLmZvckVhY2gobWV0aG9kID0+IHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29uc3QgbWV0aG9kTmFtZSA9IG1ldGhvZC5nZXROYW1lKCk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvcyA9IG1ldGhvZC5nZXRTdGFydCgpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoa2V5KSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdGFnZU1hcC5zZXQocG9zLCBrZXkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgICAgICAgICAgfSk7XHJcbiAgICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9KTtcclxuICAgIH0pO1xyXG5cclxuICAgIHJldHVybiBzdGFnZU1hcDtcclxufVxyXG5cclxuLyoqXHJcbiAqIEJ1aWxkcyBhIG1hcCBvZiBtZXRob2QgcG9zaXRpb25zIHRvIHRoZWlyIGluZGV4IGluIGNsYXNzL2ludGVyZmFjZS9uYW1lc3BhY2UgZGVjbGFyYXRpb25zXHJcbiAqIEBwYXJhbSBzb3VyY2VGaWxlIFRoZSBUeXBlU2NyaXB0IHNvdXJjZSBmaWxlIHRvIGFuYWx5emVcclxuICogQHJldHVybnMgQSBNYXAgd2hlcmUga2V5cyBhcmUgbWV0aG9kIHN0YXJ0IHBvc2l0aW9ucyBhbmQgdmFsdWVzIGFyZSB0aGVpciBwb3NpdGlvbmFsIGluZGV4ICgxLWJhc2VkKVxyXG4gKi9cclxuZnVuY3Rpb24gYnVpbGRNZXRob2RQb3NpdGlvbk1hcChzb3VyY2VGaWxlOiBTb3VyY2VGaWxlKTogTWFwPG51bWJlciwgbnVtYmVyPiB7XHJcbiAgICBjb25zdCBwb3NpdGlvbk1hcCA9IG5ldyBNYXA8bnVtYmVyLCBudW1iZXI+KCk7XHJcbiAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIFN0YXJ0aW5nIGFuYWx5c2lzIGZvciBmaWxlOiAke3NvdXJjZUZpbGUuZ2V0RmlsZVBhdGgoKX1gKTtcclxuXHJcbiAgICAvLyBIZWxwZXIgZnVuY3Rpb24gdG8gcHJvY2VzcyBtb2R1bGVzIHJlY3Vyc2l2ZWx5XHJcbiAgICBmdW5jdGlvbiBwcm9jZXNzTW9kdWxlKG1vZHVsZU5vZGU6IE1vZHVsZURlY2xhcmF0aW9uLCBtb2R1bGVQYXRoOiBzdHJpbmcpIHtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIFByb2Nlc3NpbmcgbW9kdWxlOiAke21vZHVsZVBhdGh9YCk7XHJcblxyXG4gICAgICAgIC8vIEhhbmRsZSBmdW5jdGlvbnMgZGlyZWN0bHkgaW4gdGhlIG1vZHVsZVxyXG4gICAgICAgIGNvbnN0IGZ1bmN0aW9ucyA9IG1vZHVsZU5vZGUuZ2V0RnVuY3Rpb25zKCk7XHJcbiAgICAgICAgY29uc3QgZnVuY3Rpb25Db3VudHMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xyXG5cclxuICAgICAgICBmdW5jdGlvbnMuZm9yRWFjaChmdW5jID0+IHtcclxuICAgICAgICAgICAgY29uc3QgZnVuY05hbWUgPSBmdW5jLmdldE5hbWUoKSB8fCBgVW5uYW1lZF9GdW5jdGlvbigke2Z1bmMuZ2V0U3RhcnQoKX0pYDtcclxuICAgICAgICAgICAgY29uc3QgY291bnQgPSAoZnVuY3Rpb25Db3VudHMuZ2V0KGZ1bmNOYW1lKSB8fCAwKSArIDE7XHJcbiAgICAgICAgICAgIGZ1bmN0aW9uQ291bnRzLnNldChmdW5jTmFtZSwgY291bnQpO1xyXG4gICAgICAgICAgICBwb3NpdGlvbk1hcC5zZXQoZnVuYy5nZXRTdGFydCgpLCBjb3VudCk7XHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBbYnVpbGRNZXRob2RQb3NpdGlvbk1hcF0gTW9kdWxlIGZ1bmN0aW9uOiAke2Z1bmNOYW1lfSwgcG9zaXRpb246ICR7ZnVuYy5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIC8vIEhhbmRsZSBjbGFzc2VzIHdpdGhpbiB0aGUgbW9kdWxlXHJcbiAgICAgICAgY29uc3QgY2xhc3NlcyA9IG1vZHVsZU5vZGUuZ2V0Q2xhc3NlcygpO1xyXG4gICAgICAgIGNsYXNzZXMuZm9yRWFjaChjbGFzc05vZGUgPT4ge1xyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIFByb2Nlc3NpbmcgY2xhc3MgaW4gbW9kdWxlOiAke2NsYXNzTm9kZS5nZXROYW1lKCkgfHwgJ1VubmFtZWQnfWApO1xyXG4gICAgICAgICAgICBjb25zdCBtZXRob2RzID0gY2xhc3NOb2RlLmdldE1ldGhvZHMoKTtcclxuICAgICAgICAgICAgY29uc3QgbWV0aG9kQ291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcclxuXHJcbiAgICAgICAgICAgIG1ldGhvZHMuZm9yRWFjaChtZXRob2QgPT4ge1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbWV0aG9kTmFtZSA9IG1ldGhvZC5nZXROYW1lKCk7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb3VudCA9IChtZXRob2RDb3VudHMuZ2V0KG1ldGhvZE5hbWUpIHx8IDApICsgMTtcclxuICAgICAgICAgICAgICAgIG1ldGhvZENvdW50cy5zZXQobWV0aG9kTmFtZSwgY291bnQpO1xyXG4gICAgICAgICAgICAgICAgcG9zaXRpb25NYXAuc2V0KG1ldGhvZC5nZXRTdGFydCgpLCBjb3VudCk7XHJcbiAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIE1vZHVsZSBjbGFzcyBtZXRob2Q6ICR7bWV0aG9kTmFtZX0sIHBvc2l0aW9uOiAke21ldGhvZC5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBIYW5kbGUgaW50ZXJmYWNlcyB3aXRoaW4gdGhlIG1vZHVsZVxyXG4gICAgICAgIGNvbnN0IGludGVyZmFjZXMgPSBtb2R1bGVOb2RlLmdldEludGVyZmFjZXMoKTtcclxuICAgICAgICBpbnRlcmZhY2VzLmZvckVhY2goaW50ZXJmYWNlTm9kZSA9PiB7XHJcbiAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBbYnVpbGRNZXRob2RQb3NpdGlvbk1hcF0gUHJvY2Vzc2luZyBpbnRlcmZhY2UgaW4gbW9kdWxlOiAke2ludGVyZmFjZU5vZGUuZ2V0TmFtZSgpIHx8ICdVbm5hbWVkJ31gKTtcclxuICAgICAgICAgICAgY29uc3QgbWV0aG9kcyA9IGludGVyZmFjZU5vZGUuZ2V0TWV0aG9kcygpO1xyXG4gICAgICAgICAgICBjb25zdCBtZXRob2RDb3VudHMgPSBuZXcgTWFwPHN0cmluZywgbnVtYmVyPigpO1xyXG5cclxuICAgICAgICAgICAgbWV0aG9kcy5mb3JFYWNoKG1ldGhvZCA9PiB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRob2ROYW1lID0gbWV0aG9kLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IGNvdW50ID0gKG1ldGhvZENvdW50cy5nZXQobWV0aG9kTmFtZSkgfHwgMCkgKyAxO1xyXG4gICAgICAgICAgICAgICAgbWV0aG9kQ291bnRzLnNldChtZXRob2ROYW1lLCBjb3VudCk7XHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbk1hcC5zZXQobWV0aG9kLmdldFN0YXJ0KCksIGNvdW50KTtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBbYnVpbGRNZXRob2RQb3NpdGlvbk1hcF0gTW9kdWxlIGludGVyZmFjZSBtZXRob2Q6ICR7bWV0aG9kTmFtZX0sIHBvc2l0aW9uOiAke21ldGhvZC5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBSZWN1cnNpdmVseSBwcm9jZXNzIG5lc3RlZCBtb2R1bGVzXHJcbiAgICAgICAgY29uc3QgbmVzdGVkTW9kdWxlcyA9IG1vZHVsZU5vZGUuZ2V0TW9kdWxlcygpO1xyXG4gICAgICAgIG5lc3RlZE1vZHVsZXMuZm9yRWFjaChuZXN0ZWRNb2R1bGUgPT4ge1xyXG4gICAgICAgICAgICBpZiAoTm9kZS5pc01vZHVsZURlY2xhcmF0aW9uKG5lc3RlZE1vZHVsZSkpIHtcclxuICAgICAgICAgICAgICAgIGNvbnN0IG5lc3RlZE1vZHVsZU5hbWUgPSBuZXN0ZWRNb2R1bGUuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICAgICAgY29uc3QgbmV3TW9kdWxlUGF0aCA9IGAke21vZHVsZVBhdGh9LiR7bmVzdGVkTW9kdWxlTmFtZX1gO1xyXG4gICAgICAgICAgICAgICAgcHJvY2Vzc01vZHVsZShuZXN0ZWRNb2R1bGUsIG5ld01vZHVsZVBhdGgpO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgfVxyXG5cclxuICAgIGZ1bmN0aW9uIHRyYWNrQXJyb3dGdW5jdGlvbnMoY29udGFpbmVyOiBOb2RlKSB7XHJcbiAgICAgICAgY29uc3QgYXJyb3dzID0gY29udGFpbmVyLmdldERlc2NlbmRhbnRzT2ZLaW5kKFN5bnRheEtpbmQuQXJyb3dGdW5jdGlvbik7XHJcbiAgICAgICAgYXJyb3dzLmZvckVhY2goYXJyb3cgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBwYXJlbnQgPSBhcnJvdy5nZXRQYXJlbnQoKTtcclxuICAgICAgICAgICAgaWYgKE5vZGUuaXNCbG9jayhwYXJlbnQpIHx8IE5vZGUuaXNTb3VyY2VGaWxlKHBhcmVudCkpIHtcclxuICAgICAgICAgICAgICAgIC8vIFVzZSBuZWdhdGl2ZSBudW1iZXJzIGZvciBhcnJvdyBmdW5jdGlvbnMgdG8gZGlzdGluZ3Vpc2ggZnJvbSBtZXRob2RzXHJcbiAgICAgICAgICAgICAgICBwb3NpdGlvbk1hcC5zZXQoYXJyb3cuZ2V0U3RhcnQoKSwgLTEgKiAocG9zaXRpb25NYXAuc2l6ZSArIDEpKTtcclxuICAgICAgICAgICAgICAgIC8vIGNvbnNvbGUubG9nKGBbYnVpbGRNZXRob2RQb3NpdGlvbk1hcF0gQXJyb3cgZnVuY3Rpb24gYXQgJHthcnJvdy5nZXRTdGFydCgpfWApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gSGFuZGxlIHRvcC1sZXZlbCBjbGFzc2VzXHJcbiAgICBzb3VyY2VGaWxlLmdldENsYXNzZXMoKS5mb3JFYWNoKGNsYXNzTm9kZSA9PiB7XHJcbiAgICAgICAgLy8gY29uc29sZS5sb2coYFtidWlsZE1ldGhvZFBvc2l0aW9uTWFwXSBQcm9jZXNzaW5nIGNsYXNzOiAke2NsYXNzTm9kZS5nZXROYW1lKCkgfHwgJ1VubmFtZWQnfWApO1xyXG4gICAgICAgIGNvbnN0IG1ldGhvZHMgPSBjbGFzc05vZGUuZ2V0TWV0aG9kcygpO1xyXG4gICAgICAgIGNvbnN0IG1ldGhvZENvdW50cyA9IG5ldyBNYXA8c3RyaW5nLCBudW1iZXI+KCk7XHJcblxyXG4gICAgICAgIG1ldGhvZHMuZm9yRWFjaChtZXRob2QgPT4ge1xyXG4gICAgICAgICAgICBjb25zdCBtZXRob2ROYW1lID0gbWV0aG9kLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgY29uc3QgY291bnQgPSAobWV0aG9kQ291bnRzLmdldChtZXRob2ROYW1lKSB8fCAwKSArIDE7XHJcbiAgICAgICAgICAgIG1ldGhvZENvdW50cy5zZXQobWV0aG9kTmFtZSwgY291bnQpO1xyXG4gICAgICAgICAgICBwb3NpdGlvbk1hcC5zZXQobWV0aG9kLmdldFN0YXJ0KCksIGNvdW50KTtcclxuICAgICAgICAgICAgLy8gY29uc29sZS5sb2coYFtidWlsZE1ldGhvZFBvc2l0aW9uTWFwXSBDbGFzcyBtZXRob2Q6ICR7bWV0aG9kTmFtZX0sIHBvc2l0aW9uOiAke21ldGhvZC5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIG1ldGhvZHMuZm9yRWFjaChtZXRob2QgPT4gdHJhY2tBcnJvd0Z1bmN0aW9ucyhtZXRob2QpKTtcclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEhhbmRsZSB0b3AtbGV2ZWwgaW50ZXJmYWNlc1xyXG4gICAgc291cmNlRmlsZS5nZXRJbnRlcmZhY2VzKCkuZm9yRWFjaChpbnRlcmZhY2VOb2RlID0+IHtcclxuICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIFByb2Nlc3NpbmcgaW50ZXJmYWNlOiAke2ludGVyZmFjZU5vZGUuZ2V0TmFtZSgpIHx8ICdVbm5hbWVkJ31gKTtcclxuICAgICAgICBjb25zdCBtZXRob2RzID0gaW50ZXJmYWNlTm9kZS5nZXRNZXRob2RzKCk7XHJcbiAgICAgICAgY29uc3QgbWV0aG9kQ291bnRzID0gbmV3IE1hcDxzdHJpbmcsIG51bWJlcj4oKTtcclxuXHJcbiAgICAgICAgbWV0aG9kcy5mb3JFYWNoKG1ldGhvZCA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IG1ldGhvZE5hbWUgPSBtZXRob2QuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICBjb25zdCBjb3VudCA9IChtZXRob2RDb3VudHMuZ2V0KG1ldGhvZE5hbWUpIHx8IDApICsgMTtcclxuICAgICAgICAgICAgbWV0aG9kQ291bnRzLnNldChtZXRob2ROYW1lLCBjb3VudCk7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uTWFwLnNldChtZXRob2QuZ2V0U3RhcnQoKSwgY291bnQpO1xyXG4gICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIEludGVyZmFjZSBtZXRob2Q6ICR7bWV0aG9kTmFtZX0sIHBvc2l0aW9uOiAke21ldGhvZC5nZXRTdGFydCgpfSwgaW5kZXg6ICR7Y291bnR9YCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgICAgbWV0aG9kcy5mb3JFYWNoKG1ldGhvZCA9PiB0cmFja0Fycm93RnVuY3Rpb25zKG1ldGhvZCkpO1xyXG5cclxuICAgIH0pO1xyXG5cclxuICAgIC8vIEhhbmRsZSB0b3AtbGV2ZWwgbmFtZXNwYWNlcy9tb2R1bGVzXHJcbiAgICBzb3VyY2VGaWxlLmdldE1vZHVsZXMoKS5mb3JFYWNoKG1vZHVsZU5vZGUgPT4ge1xyXG4gICAgICAgIGlmIChOb2RlLmlzTW9kdWxlRGVjbGFyYXRpb24obW9kdWxlTm9kZSkpIHtcclxuICAgICAgICAgICAgY29uc3QgbW9kdWxlTmFtZSA9IG1vZHVsZU5vZGUuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICBwcm9jZXNzTW9kdWxlKG1vZHVsZU5vZGUsIG1vZHVsZU5hbWUpO1xyXG4gICAgICAgIH1cclxuICAgIH0pO1xyXG5cclxuXHJcbiAgICAvLyBjb25zb2xlLmxvZyhgW2J1aWxkTWV0aG9kUG9zaXRpb25NYXBdIEZpbmFsIHBvc2l0aW9uTWFwOmAsIEFycmF5LmZyb20ocG9zaXRpb25NYXAuZW50cmllcygpKSk7XHJcbiAgICByZXR1cm4gcG9zaXRpb25NYXA7XHJcbn1cclxuXHJcbi8qKlxyXG4gKiBHZW5lcmF0ZXMgYSBmdWxseSBxdWFsaWZpZWQgbmFtZSAoRlFOKSBmb3IgYSBnaXZlbiBBU1Qgbm9kZS5cclxuICogQ29uc3RydWN0cyBhbiBGUU4gYnkgdHJhdmVyc2luZyB0aGUgbm9kZSdzIGFuY2VzdHJ5LCBhZGRpbmcgbmFtZXMgYW5kIGtleXNcclxuICogKG51bWVyaWMgb3Igc3RyaW5nIGZyb20gb2JqZWN0IGxpdGVyYWxzIC4uLikgYXMgbmVlZGVkLCBwcmVmaXhlZCB3aXRoIHRoZSBmaWxlJ3MgcmVsYXRpdmUgcGF0aC5cclxuICogXHJcbiAqIEBwYXJhbSBub2RlIFRoZSBBU1Qgbm9kZSB0byBnZW5lcmF0ZSBhbiBGUU4gZm9yXHJcbiAqIEByZXR1cm5zIEEgc3RyaW5nIHJlcHJlc2VudGluZyB0aGUgbm9kZSdzIEZRTiAoZS5nLiwgXCJ7cGF0aH0ub3BlcmF0aW9ucy5hZGQuY29tcHV0ZVtNZXRob2REZWNsYXJhdGlvbl1cIilcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGUU4obm9kZTogRlFOTm9kZSB8IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgY29uc3Qgc291cmNlRmlsZSA9IG5vZGUuZ2V0U291cmNlRmlsZSgpO1xyXG4gICAgY29uc3QgYWJzb2x1dGVQYXRoUHJvamVjdCA9IGVudGl0eURpY3Rpb25hcnkuZmFtaXhSZXAuZ2V0QWJzb2x1dGVQYXRoKCk7XHJcbiAgICBjb25zdCBwYXJ0czogc3RyaW5nW10gPSBbXTtcclxuICAgIGxldCBjdXJyZW50Tm9kZTogTm9kZSB8IHVuZGVmaW5lZCA9IG5vZGU7XHJcblxyXG4gICAgY29uc3Qgc3RhZ2VNYXAgPSBidWlsZFN0YWdlTWV0aG9kTWFwKHNvdXJjZUZpbGUpO1xyXG4gICAgY29uc3QgbWV0aG9kUG9zaXRpb25NYXAgPSBidWlsZE1ldGhvZFBvc2l0aW9uTWFwKHNvdXJjZUZpbGUpO1xyXG5cclxuICAgIHdoaWxlIChjdXJyZW50Tm9kZSAmJiAhTm9kZS5pc1NvdXJjZUZpbGUoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgY29uc3QgeyBsaW5lLCBjb2x1bW4gfSA9IHNvdXJjZUZpbGUuZ2V0TGluZUFuZENvbHVtbkF0UG9zKGN1cnJlbnROb2RlLmdldFN0YXJ0KCkpO1xyXG4gICAgICAgIGNvbnN0IGxjID0gYCR7bGluZX06JHtjb2x1bW59YDtcclxuXHJcbiAgICAgICAgaWYgKE5vZGUuaXNDbGFzc0RlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzQ2xhc3NFeHByZXNzaW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzSW50ZXJmYWNlRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNGdW5jdGlvbkRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzTWV0aG9kRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNNb2R1bGVEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1ZhcmlhYmxlRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNHZXRBY2Nlc3NvckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzU2V0QWNjZXNzb3JEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1Byb3BlcnR5RGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNQYXJhbWV0ZXJEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc0RlY29yYXRvcihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1R5cGVBbGlhc0RlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRW51bURlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRW51bU1lbWJlcihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc1BhcmFtZXRlcmVkKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzUHJvcGVydHlTaWduYXR1cmUoY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNBcnJheUxpdGVyYWxFeHByZXNzaW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzSW1wb3J0U3BlY2lmaWVyKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzSWRlbnRpZmllcihjdXJyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgbGV0IG5hbWU6IHN0cmluZztcclxuICAgICAgICAgICAgaWYgKE5vZGUuaXNJbXBvcnRTcGVjaWZpZXIoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhbGlhcyA9IGN1cnJlbnROb2RlLmdldEFsaWFzTm9kZSgpPy5nZXRUZXh0KCk7XHJcbiAgICAgICAgICAgICAgICBpZiAoYWxpYXMpIHtcclxuICAgICAgICAgICAgICAgICAgICBsZXQgaW1wb3J0RGVjbDogTm9kZSB8IHVuZGVmaW5lZCA9IGN1cnJlbnROb2RlO1xyXG4gICAgICAgICAgICAgICAgICAgIHdoaWxlIChpbXBvcnREZWNsICYmICFOb2RlLmlzSW1wb3J0RGVjbGFyYXRpb24oaW1wb3J0RGVjbCkpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgaW1wb3J0RGVjbCA9IGltcG9ydERlY2wuZ2V0UGFyZW50KCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG1vZHVsZVNwZWNpZmllciA9IGltcG9ydERlY2wgJiYgTm9kZS5pc0ltcG9ydERlY2xhcmF0aW9uKGltcG9ydERlY2wpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgID8gaW1wb3J0RGVjbC5nZXRNb2R1bGVTcGVjaWZpZXIoKS5nZXRMaXRlcmFsVGV4dCgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogXCJ1bmtub3duXCI7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGN1cnJlbnROb2RlLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gYCR7bmFtZX0gYXMgJHthbGlhc31bSW1wb3J0U3BlY2lmaWVyPCR7bW9kdWxlU3BlY2lmaWVyfT5dYDtcclxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICAgICAgbmFtZSA9IGN1cnJlbnROb2RlLmdldE5hbWUoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIC8vIGlmIGNvbnN0cnVjdG9yLCB1c2UgXCJjb25zdHJ1Y3RvclwiIGFzIG5hbWVcclxuICAgICAgICAgICAgICAgIGlmIChOb2RlLmlzQ29uc3RydWN0b3JEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkpIHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gXCJjb25zdHJ1Y3RvclwiO1xyXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgICAgICBuYW1lID0gTm9kZS5pc0lkZW50aWZpZXIoY3VycmVudE5vZGUpID8gY3VycmVudE5vZGUuZ2V0VGV4dCgpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgIDogJ2dldE5hbWUnIGluIGN1cnJlbnROb2RlICYmIHR5cGVvZiBjdXJyZW50Tm9kZVsnZ2V0TmFtZSddID09PSAnZnVuY3Rpb24nXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/ICgoY3VycmVudE5vZGUgYXMgeyBnZXROYW1lKCk6IHN0cmluZyB9KS5nZXROYW1lKCkgK1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICgoTm9kZS5pc0NsYXNzRGVjbGFyYXRpb24oY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIE5vZGUuaXNJbnRlcmZhY2VEZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgTm9kZS5pc01ldGhvZERlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBOb2RlLmlzRnVuY3Rpb25EZWNsYXJhdGlvbihjdXJyZW50Tm9kZSkpICYmXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICdnZXRUeXBlUGFyYW1ldGVycycgaW4gY3VycmVudE5vZGUgJiZcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudE5vZGUuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZ2V0UGFyYW1ldGVycyhjdXJyZW50Tm9kZSlcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnJykpXHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IGBVbm5hbWVkXyR7Y3VycmVudE5vZGUuZ2V0S2luZE5hbWUoKX0oJHtsY30pYDtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKE5vZGUuaXNNZXRob2RTaWduYXR1cmUoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBtZXRob2QgPSBjdXJyZW50Tm9kZSBhcyBNZXRob2RTaWduYXR1cmU7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJhbXMgPSBtZXRob2QuZ2V0UGFyYW1ldGVycygpLm1hcChwID0+IHtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlVGV4dCA9IHAuZ2V0VHlwZSgpLmdldFRleHQoKS5yZXBsYWNlKC9cXHMrL2csIFwiXCIpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJldHVybiB0eXBlVGV4dCB8fCBcImFueVwiOyAvLyBGYWxsYmFjayBmb3IgdW50eXBlZCBwYXJhbWV0ZXJzXHJcbiAgICAgICAgICAgICAgICB9KTtcclxuICAgICAgICAgICAgICAgIGNvbnN0IHJldHVyblR5cGUgPSBtZXRob2QuZ2V0UmV0dXJuVHlwZSgpLmdldFRleHQoKS5yZXBsYWNlKC9cXHMrL2csIFwiXCIpIHx8IFwidm9pZFwiO1xyXG4gICAgICAgICAgICAgICAgbmFtZSA9IGAke25hbWV9KCR7cGFyYW1zLmpvaW4oXCIsXCIpfSk6JHtyZXR1cm5UeXBlfWA7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQobmFtZSk7XHJcblxyXG4gICAgICAgICAgICAvLyBBcHBseSBwb3NpdGlvbmFsIGluZGV4IGZvciBNZXRob2REZWNsYXJhdGlvbiwgTWV0aG9kU2lnbmF0dXJlLCBhbmQgRnVuY3Rpb25EZWNsYXJhdGlvblxyXG4gICAgICAgICAgICBpZiAoTm9kZS5pc01ldGhvZERlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICAgICAgTm9kZS5pc01ldGhvZFNpZ25hdHVyZShjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgICAgIE5vZGUuaXNGdW5jdGlvbkRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICAgICAgY29uc3Qga2V5ID0gc3RhZ2VNYXAuZ2V0KGN1cnJlbnROb2RlLmdldFN0YXJ0KCkpO1xyXG4gICAgICAgICAgICAgICAgaWYgKGtleSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQoa2V5KTtcclxuICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2dldEZRTl0gQXBwbGllZCBzdGFnZU1hcCBrZXk6ICR7a2V5fSBmb3IgJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfSBhdCBwb3NpdGlvbiAke2N1cnJlbnROb2RlLmdldFN0YXJ0KCl9YCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHBvc2l0aW9uSW5kZXggPSBtZXRob2RQb3NpdGlvbk1hcC5nZXQoY3VycmVudE5vZGUuZ2V0U3RhcnQoKSk7XHJcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBvc2l0aW9uSW5kZXggJiYgcG9zaXRpb25JbmRleCA+IDEpIHtcclxuICAgICAgICAgICAgICAgICAgICAgICAgcGFydHMudW5zaGlmdChwb3NpdGlvbkluZGV4LnRvU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBjb25zb2xlLmxvZyhgW2dldEZRTl0gQXBwbGllZCBwb3NpdGlvbkluZGV4OiAke3Bvc2l0aW9uSW5kZXh9IGZvciAke2N1cnJlbnROb2RlLmdldEtpbmROYW1lKCl9IGF0IHBvc2l0aW9uICR7Y3VycmVudE5vZGUuZ2V0U3RhcnQoKX1gKTtcclxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zb2xlLmxvZyhgW2dldEZRTl0gTm8gcG9zaXRpb25JbmRleCBhcHBsaWVkIGZvciAke2N1cnJlbnROb2RlLmdldEtpbmROYW1lKCl9IGF0IHBvc2l0aW9uICR7Y3VycmVudE5vZGUuZ2V0U3RhcnQoKX0sIHBvc2l0aW9uSW5kZXg6ICR7cG9zaXRpb25JbmRleCB8fCAnbm9uZSd9YCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKE5vZGUuaXNBcnJvd0Z1bmN0aW9uKGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzQmxvY2soY3VycmVudE5vZGUpIHx8XHJcbiAgICAgICAgICAgIE5vZGUuaXNGb3JJblN0YXRlbWVudChjdXJyZW50Tm9kZSkgfHxcclxuICAgICAgICAgICAgTm9kZS5pc0Zvck9mU3RhdGVtZW50KGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzRm9yU3RhdGVtZW50KGN1cnJlbnROb2RlKSB8fFxyXG4gICAgICAgICAgICBOb2RlLmlzQ2F0Y2hDbGF1c2UoY3VycmVudE5vZGUpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBgJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfSgke2xjfSlgO1xyXG4gICAgICAgICAgICBwYXJ0cy51bnNoaWZ0KG5hbWUpO1xyXG4gICAgICAgIH1cclxuICAgICAgICBlbHNlIGlmIChOb2RlLmlzVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBjb25zdCBhcnJvd1BhcmVudCA9IGN1cnJlbnROb2RlLmdldEZpcnN0QW5jZXN0b3JCeUtpbmQoU3ludGF4S2luZC5BcnJvd0Z1bmN0aW9uKTtcclxuICAgICAgICAgICAgaWYgKGFycm93UGFyZW50KSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBhcnJvd0luZGV4ID0gTWF0aC5hYnMobWV0aG9kUG9zaXRpb25NYXAuZ2V0KGFycm93UGFyZW50LmdldFN0YXJ0KCkpIHx8IDApO1xyXG4gICAgICAgICAgICAgICAgaWYgKGFycm93SW5kZXggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgcGFydHMudW5zaGlmdChhcnJvd0luZGV4LnRvU3RyaW5nKCkpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQoY3VycmVudE5vZGUuZ2V0TmFtZSgpKTtcclxuICAgICAgICAgICAgLy8gUmVtb3ZlZCBjb250aW51ZSB0byBhbGxvdyBhbmNlc3RvciBwcm9jZXNzaW5nXHJcbiAgICAgICAgfVxyXG4gICAgICAgIGVsc2UgaWYgKE5vZGUuaXNDb25zdHJ1Y3RvckRlY2xhcmF0aW9uKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBjb25zdCBuYW1lID0gXCJjb25zdHJ1Y3RvclwiO1xyXG4gICAgICAgICAgICBwYXJ0cy51bnNoaWZ0KG5hbWUpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgIGNvbnNvbGUubG9nKGBbZ2V0RlFOXSBJZ25vcmluZyBub2RlIGtpbmQ6ICR7Y3VycmVudE5vZGUuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUuZ2V0UGFyZW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgbGV0IHJlbGF0aXZlUGF0aCA9IGVudGl0eURpY3Rpb25hcnkuY29udmVydFRvUmVsYXRpdmVQYXRoKFxyXG4gICAgICAgIHBhdGgubm9ybWFsaXplKHNvdXJjZUZpbGUuZ2V0RmlsZVBhdGgoKSksXHJcbiAgICAgICAgYWJzb2x1dGVQYXRoUHJvamVjdFxyXG4gICAgKS5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKTtcclxuXHJcbiAgICAvLyBpZiAocmVsYXRpdmVQYXRoLmluY2x1ZGVzKFwiLi5cIikpIHtcclxuICAgIC8vIH1cclxuICAgIGlmIChyZWxhdGl2ZVBhdGguc3RhcnRzV2l0aChcIi9cIikpIHtcclxuICAgICAgICByZWxhdGl2ZVBhdGggPSByZWxhdGl2ZVBhdGguc2xpY2UoMSk7XHJcbiAgICB9XHJcbiAgICBwYXJ0cy51bnNoaWZ0KGB7JHtyZWxhdGl2ZVBhdGh9fWApO1xyXG5cclxuICAgIGNvbnN0IGZxbiA9IHBhcnRzLmpvaW4oXCIuXCIpICsgYFske25vZGUuZ2V0S2luZE5hbWUoKX1dYDtcclxuICAgIC8vIGNvbnNvbGUubG9nKGBbZ2V0RlFOXSBGaW5hbCBGUU46ICR7ZnFufWApO1xyXG4gICAgcmV0dXJuIGZxbjtcclxufVxyXG5cclxuXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRVbmlxdWVGUU4obm9kZTogTm9kZSk6IHN0cmluZyB8IHVuZGVmaW5lZCB7XHJcbiAgICBjb25zdCBhYnNvbHV0ZVBhdGhQcm9qZWN0ID0gZW50aXR5RGljdGlvbmFyeS5mYW1peFJlcC5nZXRBYnNvbHV0ZVBhdGgoKTtcclxuICAgIGNvbnN0IHBhcnRzOiBzdHJpbmdbXSA9IFtdO1xyXG5cclxuICAgIGlmIChub2RlIGluc3RhbmNlb2YgU291cmNlRmlsZSkge1xyXG4gICAgICAgIHJldHVybiBlbnRpdHlEaWN0aW9uYXJ5LmNvbnZlcnRUb1JlbGF0aXZlUGF0aChwYXRoLm5vcm1hbGl6ZShub2RlLmdldEZpbGVQYXRoKCkpLCBhYnNvbHV0ZVBhdGhQcm9qZWN0KS5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKTtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCB1bmRlZmluZWQgPSBub2RlO1xyXG4gICAgd2hpbGUgKGN1cnJlbnROb2RlKSB7XHJcbiAgICAgICAgaWYgKE5vZGUuaXNTb3VyY2VGaWxlKGN1cnJlbnROb2RlKSkge1xyXG4gICAgICAgICAgICBjb25zdCByZWxhdGl2ZVBhdGggPSBlbnRpdHlEaWN0aW9uYXJ5LmNvbnZlcnRUb1JlbGF0aXZlUGF0aChwYXRoLm5vcm1hbGl6ZShjdXJyZW50Tm9kZS5nZXRGaWxlUGF0aCgpKSwgYWJzb2x1dGVQYXRoUHJvamVjdCkucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XHJcbiAgICAgICAgICAgIGlmIChyZWxhdGl2ZVBhdGguaW5jbHVkZXMoXCIuLlwiKSkge1xyXG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBSZWxhdGl2ZSBwYXRoIGNvbnRhaW5zIC4uLzogJHtyZWxhdGl2ZVBhdGh9YCk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcGFydHMudW5zaGlmdChyZWxhdGl2ZVBhdGgpOyAvLyBBZGQgZmlsZSBwYXRoIGF0IHRoZSBzdGFydFxyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnROb2RlLmdldFN5bWJvbCgpKSB7XHJcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBjdXJyZW50Tm9kZS5nZXRTeW1ib2woKSEuZ2V0TmFtZSgpO1xyXG4gICAgICAgICAgICAvLyBGb3IgYW5vbnltb3VzIG5vZGVzLCB1c2Uga2luZCBhbmQgcG9zaXRpb24gYXMgdW5pcXVlIGlkZW50aWZpZXJzXHJcbiAgICAgICAgICAgIGNvbnN0IGlkZW50aWZpZXIgPSBuYW1lICE9PSBcIl9fY29tcHV0ZWRcIiA/IG5hbWUgOiBgJHtjdXJyZW50Tm9kZS5nZXRLaW5kTmFtZSgpfV8ke2N1cnJlbnROb2RlLmdldFN0YXJ0TGluZVBvcygpfWA7XHJcbiAgICAgICAgICAgIHBhcnRzLnVuc2hpZnQoaWRlbnRpZmllcik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGN1cnJlbnROb2RlID0gY3VycmVudE5vZGUuZ2V0UGFyZW50KCk7XHJcbiAgICB9XHJcblxyXG4gICAgcmV0dXJuIHBhcnRzLmpvaW4oXCI6OlwiKTtcclxufVxyXG5cclxuLyoqXHJcbiAqIEdldHMgdGhlIG5hbWUgb2YgYSBub2RlLCBpZiBpdCBoYXMgb25lXHJcbiAqIEBwYXJhbSBhIEEgbm9kZVxyXG4gKiBAcmV0dXJucyBUaGUgbmFtZSBvZiB0aGUgbm9kZSwgb3IgYW4gZW1wdHkgc3RyaW5nIGlmIGl0IGRvZXNuJ3QgaGF2ZSBvbmVcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXROYW1lT2ZOb2RlKGE6IE5vZGUpOiBzdHJpbmcge1xyXG4gICAgbGV0IGNLaW5kOiBDbGFzc0RlY2xhcmF0aW9uIHwgdW5kZWZpbmVkO1xyXG4gICAgbGV0IGlLaW5kOiBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IHVuZGVmaW5lZDtcclxuICAgIGxldCBtS2luZDogTWV0aG9kRGVjbGFyYXRpb24gfCB1bmRlZmluZWQ7XHJcbiAgICBsZXQgZktpbmQ6IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCB1bmRlZmluZWQ7XHJcbiAgICBsZXQgYWxpYXM6IFRTTW9ycGhUeXBlRGVjbGFyYXRpb24gfCB1bmRlZmluZWQ7XHJcbiAgICBzd2l0Y2ggKGEuZ2V0S2luZCgpKSB7XHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlNvdXJjZUZpbGU6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlNvdXJjZUZpbGUpIS5nZXRCYXNlTmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuTW9kdWxlRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLk1vZHVsZURlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuQ2xhc3NEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgY0tpbmQgPSBhLmFzS2luZChTeW50YXhLaW5kLkNsYXNzRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoY0tpbmQgJiYgY0tpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gY0tpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBjS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkludGVyZmFjZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBpS2luZCA9IGEuYXNLaW5kKFN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24pO1xyXG4gICAgICAgICAgICBpZiAoaUtpbmQgJiYgaUtpbmQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gaUtpbmQuZ2V0TmFtZSgpICsgZ2V0UGFyYW1ldGVycyhhKTtcclxuICAgICAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBpS2luZD8uZ2V0TmFtZSgpIHx8IFwiXCI7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlByb3BlcnR5RGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlByb3BlcnR5RGVjbGFyYXRpb24pIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Qcm9wZXJ0eVNpZ25hdHVyZTpcclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuUHJvcGVydHlTaWduYXR1cmUpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5NZXRob2REZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgbUtpbmQgPSBhLmFzS2luZChTeW50YXhLaW5kLk1ldGhvZERlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgaWYgKG1LaW5kICYmIG1LaW5kLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIG1LaW5kLmdldE5hbWUoKSArIGdldFBhcmFtZXRlcnMoYSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gbUtpbmQ/LmdldE5hbWUoKSB8fCBcIlwiO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5NZXRob2RTaWduYXR1cmU6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLk1ldGhvZFNpZ25hdHVyZSkhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkdldEFjY2Vzc29yOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5HZXRBY2Nlc3NvcikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlNldEFjY2Vzc29yOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5TZXRBY2Nlc3NvcikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkZ1bmN0aW9uRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIGZLaW5kID0gYS5hc0tpbmQoU3ludGF4S2luZC5GdW5jdGlvbkRlY2xhcmF0aW9uKTtcclxuICAgICAgICAgICAgaWYgKGZLaW5kICYmIGZLaW5kLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMCkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZLaW5kLmdldE5hbWUoKSArIGdldFBhcmFtZXRlcnMoYSk7XHJcbiAgICAgICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gZktpbmQ/LmdldE5hbWUoKSB8fCBcIlwiO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5GdW5jdGlvbkV4cHJlc3Npb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLkZ1bmN0aW9uRXhwcmVzc2lvbik/LmdldE5hbWUoKSB8fCBcImFub255bW91c1wiO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuUGFyYW1ldGVyOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5QYXJhbWV0ZXIpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICByZXR1cm4gYS5hc0tpbmQoU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uKSEuZ2V0TmFtZSgpO1xyXG5cclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRGVjb3JhdG9yOlxyXG4gICAgICAgICAgICByZXR1cm4gXCJAXCIgKyBhLmFzS2luZChTeW50YXhLaW5kLkRlY29yYXRvcikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLlR5cGVQYXJhbWV0ZXI6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLlR5cGVQYXJhbWV0ZXIpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5FbnVtRGVjbGFyYXRpb246XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLkVudW1EZWNsYXJhdGlvbikhLmdldE5hbWUoKTtcclxuXHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkVudW1NZW1iZXI6XHJcbiAgICAgICAgICAgIHJldHVybiBhLmFzS2luZChTeW50YXhLaW5kLkVudW1NZW1iZXIpIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5UeXBlQWxpYXNEZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgLy8gc3BlY2lhbCBjYXNlIGZvciBwYXJhbWV0ZXJpemVkIHR5cGVzXHJcbiAgICAgICAgICAgIGFsaWFzID0gYS5hc0tpbmQoU3ludGF4S2luZC5UeXBlQWxpYXNEZWNsYXJhdGlvbik7XHJcbiAgICAgICAgICAgIGlmIChhbGlhcyAmJiBhbGlhcy5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgICAgIHJldHVybiBhbGlhcy5nZXROYW1lKCkgKyBcIjxcIiArIGFsaWFzLmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCI7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIGEuYXNLaW5kKFN5bnRheEtpbmQuVHlwZUFsaWFzRGVjbGFyYXRpb24pIS5nZXROYW1lKCk7XHJcblxyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5Db25zdHJ1Y3RvcjpcclxuICAgICAgICAgICAgcmV0dXJuIFwiY29uc3RydWN0b3JcIjtcclxuXHJcbiAgICAgICAgZGVmYXVsdDpcclxuICAgICAgICAgICAgLy8gdGhyb3cgbmV3IEVycm9yKGBnZXROYW1lT2ZOb2RlIGNhbGxlZCBvbiBhIG5vZGUgdGhhdCBkb2Vzbid0IGhhdmUgYSBuYW1lOiAke2EuZ2V0S2luZE5hbWUoKX1gKTtcclxuICAgICAgICAgICAgLy8gYW5jZXN0b3IgaGFzbid0IGdvdCBhIHVzZWZ1bCBuYW1lXHJcbiAgICAgICAgICAgIHJldHVybiBcIlwiO1xyXG4gICAgfVxyXG59XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgbmFtZSBvZiBhIG5vZGUsIGlmIGl0IGhhcyBvbmVcclxuICogQHBhcmFtIGEgQSBub2RlXHJcbiAqIEByZXR1cm5zIFRoZSBuYW1lIG9mIHRoZSBub2RlLCBvciBhbiBlbXB0eSBzdHJpbmcgaWYgaXQgZG9lc24ndCBoYXZlIG9uZVxyXG4gKi9cclxuZXhwb3J0IGZ1bmN0aW9uIGdldFBhcmFtZXRlcnMoYTogTm9kZSk6IHN0cmluZyB7XHJcbiAgICBsZXQgcGFyYW1TdHJpbmcgPSBcIlwiO1xyXG4gICAgc3dpdGNoIChhLmdldEtpbmQoKSkge1xyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBwYXJhbVN0cmluZyA9IFwiPFwiICsgYS5hc0tpbmQoU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uKT8uZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAodHAgPT4gdHAuZ2V0TmFtZSgpKS5qb2luKFwiLCBcIikgKyBcIj5cIjtcclxuICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgY2FzZSBTeW50YXhLaW5kLkludGVyZmFjZURlY2xhcmF0aW9uOlxyXG4gICAgICAgICAgICBwYXJhbVN0cmluZyA9IFwiPFwiICsgYS5hc0tpbmQoU3ludGF4S2luZC5JbnRlcmZhY2VEZWNsYXJhdGlvbik/LmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCI7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGNhc2UgU3ludGF4S2luZC5NZXRob2REZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcGFyYW1TdHJpbmcgPSBcIjxcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuTWV0aG9kRGVjbGFyYXRpb24pPy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCh0cCA9PiB0cC5nZXROYW1lKCkpLmpvaW4oXCIsIFwiKSArIFwiPlwiO1xyXG4gICAgICAgICAgICBicmVhaztcclxuICAgICAgICBjYXNlIFN5bnRheEtpbmQuRnVuY3Rpb25EZWNsYXJhdGlvbjpcclxuICAgICAgICAgICAgcGFyYW1TdHJpbmcgPSBcIjxcIiArIGEuYXNLaW5kKFN5bnRheEtpbmQuRnVuY3Rpb25EZWNsYXJhdGlvbik/LmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCI7XHJcbiAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZ2V0UGFyYW1ldGVycyBjYWxsZWQgb24gYSBub2RlIHRoYXQgZG9lc24ndCBoYXZlIHBhcmFtZXRlcnM6ICR7YS5nZXRLaW5kTmFtZSgpfWApO1xyXG4gICAgfVxyXG4gICAgcmV0dXJuIHBhcmFtU3RyaW5nO1xyXG59XHJcblxyXG4vKipcclxuICogR2V0cyB0aGUgRlFOIG9mIGFuIHVucmVzb2x2ZWQgaW50ZXJmYWNlIHRoYXQgaXMgYmVpbmcgaW1wbGVtZW50ZWQgb3IgZXh0ZW5kZWRcclxuICogQHBhcmFtIHVucmVzb2x2ZWRJbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlIFRoZSBleHByZXNzaW9uIHdpdGggdHlwZSBhcmd1bWVudHMgcmVwcmVzZW50aW5nIHRoZSBpbnRlcmZhY2VcclxuICogQHJldHVybnMgVGhlIEZRTiBvZiB0aGUgdW5yZXNvbHZlZCBpbnRlcmZhY2VcclxuICovXHJcbmV4cG9ydCBmdW5jdGlvbiBnZXRGUU5VbnJlc29sdmVkSW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZSh1bnJlc29sdmVkSW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZTogRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKTogc3RyaW5nIHtcclxuICAgIC8vIENoZWNrIGZvciBlaXRoZXIgQ2xhc3NEZWNsYXJhdGlvbiBvciBJbnRlcmZhY2VEZWNsYXJhdGlvbiBhbmNlc3RvclxyXG4gICAgY29uc3QgY2xhc3NBbmNlc3RvciA9IHVucmVzb2x2ZWRJbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlLmdldEZpcnN0QW5jZXN0b3JCeUtpbmQoU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uKTtcclxuICAgIGNvbnN0IGludGVyZmFjZUFuY2VzdG9yID0gdW5yZXNvbHZlZEluaGVyaXRlZENsYXNzT3JJbnRlcmZhY2UuZ2V0Rmlyc3RBbmNlc3RvckJ5S2luZChTeW50YXhLaW5kLkludGVyZmFjZURlY2xhcmF0aW9uKTtcclxuXHJcbiAgICAvLyBWYWxpZGF0ZSB0aGUgY29udGV4dFxyXG4gICAgaWYgKCFjbGFzc0FuY2VzdG9yICYmICFpbnRlcmZhY2VBbmNlc3Rvcikge1xyXG4gICAgICAgIHRocm93IG5ldyBFcnJvcihcImdldEZRTlVucmVzb2x2ZWRDbGFzc09ySW50ZXJmYWNlIGNhbGxlZCBvbiBhIG5vZGUgdGhhdCBpcyBub3QgaW4gYW4gaW1wbGVtZW50cyBvciBleHRlbmRzIGNvbnRleHRcIik7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gQ2hlY2sgaWYgaXQncyBhIHZhbGlkIGltcGxlbWVudHMvZXh0ZW5kcyBjb250ZXh0XHJcbiAgICBsZXQgaXNWYWxpZENvbnRleHQgPSBmYWxzZTtcclxuXHJcbiAgICBsZXQgY2xhc3NFeHRlbmRzQ2xhc3MgPSBmYWxzZTtcclxuXHJcbiAgICBpZiAoY2xhc3NBbmNlc3Rvcikge1xyXG4gICAgICAgIC8vIGNoZWNrIGlmIHRoZSBjbGFzcyBpcyBleHRlbmRpbmcgb3IgaW1wbGVtZW50aW5nIGFuIGludGVyZmFjZVxyXG4gICAgICAgIGNvbnN0IGV4dGVuZHNDbGF1c2UgPSBjbGFzc0FuY2VzdG9yLmdldEV4dGVuZHMoKTtcclxuICAgICAgICBjb25zdCBpbXBsZW1lbnRzQ2xhdXNlID0gY2xhc3NBbmNlc3Rvci5nZXRJbXBsZW1lbnRzKCk7XHJcbiAgICAgICAgaXNWYWxpZENvbnRleHQgPSAoZXh0ZW5kc0NsYXVzZSAhPT0gdW5kZWZpbmVkKSB8fCAoaW1wbGVtZW50c0NsYXVzZSAmJiBpbXBsZW1lbnRzQ2xhdXNlLmxlbmd0aCA+IDApO1xyXG4gICAgICAgIGNsYXNzRXh0ZW5kc0NsYXNzID0gZXh0ZW5kc0NsYXVzZSAhPT0gdW5kZWZpbmVkO1xyXG4gICAgfSBlbHNlIGlmIChpbnRlcmZhY2VBbmNlc3Rvcikge1xyXG4gICAgICAgIC8vIENoZWNrIGV4dGVuZHMgY2xhdXNlIGZvciBpbnRlcmZhY2VzXHJcbiAgICAgICAgY29uc3QgZXh0ZW5kc0NsYXVzZSA9IGludGVyZmFjZUFuY2VzdG9yLmdldEV4dGVuZHMoKTtcclxuICAgICAgICBpc1ZhbGlkQ29udGV4dCA9IGV4dGVuZHNDbGF1c2UgJiYgZXh0ZW5kc0NsYXVzZS5sZW5ndGggPiAwO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICghaXNWYWxpZENvbnRleHQpIHtcclxuICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJnZXRGUU5VbnJlc29sdmVkSW50ZXJmYWNlIGNhbGxlZCBvbiBhIG5vZGUgdGhhdCBpcyBub3QgaW4gYSB2YWxpZCBpbXBsZW1lbnRzIG9yIGV4dGVuZHMgY29udGV4dFwiKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBnZXQgdGhlIG5hbWUgb2YgdGhlIGludGVyZmFjZVxyXG4gICAgY29uc3QgbmFtZSA9IHVucmVzb2x2ZWRJbmhlcml0ZWRDbGFzc09ySW50ZXJmYWNlLmdldEV4cHJlc3Npb24oKS5nZXRUZXh0KCk7XHJcblxyXG4gICAgLy8gRmluZCB3aGVyZSBpdCdzIGltcG9ydGVkIC0gc2VhcmNoIHRoZSBlbnRpcmUgc291cmNlIGZpbGVcclxuICAgIGNvbnN0IHNvdXJjZUZpbGUgPSB1bnJlc29sdmVkSW5oZXJpdGVkQ2xhc3NPckludGVyZmFjZS5nZXRTb3VyY2VGaWxlKCk7XHJcbiAgICBjb25zdCBpbXBvcnREZWNscyA9IHNvdXJjZUZpbGUuZ2V0SW1wb3J0RGVjbGFyYXRpb25zKCk7XHJcblxyXG4gICAgZm9yIChjb25zdCBpbXBvcnREZWNsIG9mIGltcG9ydERlY2xzKSB7XHJcbiAgICAgICAgY29uc3QgbW9kdWxlU3BlY2lmaWVyID0gaW1wb3J0RGVjbC5nZXRNb2R1bGVTcGVjaWZpZXJWYWx1ZSgpO1xyXG4gICAgICAgIGNvbnN0IGltcG9ydENsYXVzZSA9IGltcG9ydERlY2wuZ2V0SW1wb3J0Q2xhdXNlKCk7XHJcblxyXG4gICAgICAgIGlmIChpbXBvcnRDbGF1c2UpIHtcclxuICAgICAgICAgICAgY29uc3QgbmFtZWRJbXBvcnRzID0gaW1wb3J0Q2xhdXNlLmdldE5hbWVkSW1wb3J0cygpO1xyXG4gICAgICAgICAgICAvLyBkZWNsYXJhdGlvbk5hbWUgaXMgQ2xhc3NEZWNsYXJhdGlvbiBpZiBcImNsYXNzIGV4dGVuZHMgY2xhc3NcIlxyXG4gICAgICAgICAgICBjb25zdCBkZWNsYXJhdGlvbk5hbWUgPSBjbGFzc0V4dGVuZHNDbGFzcyA/IFwiQ2xhc3NEZWNsYXJhdGlvblwiIDogXCJJbnRlcmZhY2VEZWNsYXJhdGlvblwiO1xyXG5cclxuICAgICAgICAgICAgZm9yIChjb25zdCBuYW1lZEltcG9ydCBvZiBuYW1lZEltcG9ydHMpIHtcclxuICAgICAgICAgICAgICAgIGlmIChuYW1lZEltcG9ydC5nZXROYW1lKCkgPT09IG5hbWUpIHtcclxuICAgICAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYEZvdW5kIGltcG9ydCBmb3IgJHtuYW1lfSBpbiAke21vZHVsZVNwZWNpZmllcn1gKTtcclxuICAgICAgICAgICAgICAgICAgICByZXR1cm4gYHttb2R1bGU6JHttb2R1bGVTcGVjaWZpZXJ9fS4ke25hbWV9WyR7ZGVjbGFyYXRpb25OYW1lfV1gO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIElmIG5vdCBmb3VuZCwgcmV0dXJuIGEgZGVmYXVsdCBGUU4gZm9ybWF0XHJcbiAgICByZXR1cm4gYHt1bmtub3duLW1vZHVsZX0uJHtuYW1lfVtJbnRlcmZhY2VEZWNsYXJhdGlvbl1gO1xyXG59XHJcblxyXG4iXX0=