ts2famix 2.0.0 → 2.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +1 -0
- package/README.md +29 -60
- package/dist/analyze.js +1 -1
- package/dist/analyze_functions/process_functions.js +49 -43
- package/dist/famix_functions/EntityDictionary.js +309 -182
- package/dist/famix_functions/helpers_creation.js +36 -5
- package/dist/fqn.js +76 -114
- package/dist/lib/famix/famix_JSON_exporter.js +55 -0
- package/dist/lib/famix/famix_base_element.js +18 -0
- package/dist/lib/famix/famix_repository.js +224 -0
- package/dist/lib/famix/{src/index.js → index.js} +1 -1
- package/dist/lib/famix/model/famix/access.js +40 -0
- package/dist/lib/famix/model/famix/accessor.js +17 -0
- package/dist/lib/famix/model/famix/alias.js +33 -0
- package/dist/lib/famix/model/famix/arrow_function.js +17 -0
- package/dist/lib/famix/model/famix/behavioral_entity.js +79 -0
- package/dist/lib/famix/model/famix/class.js +71 -0
- package/dist/lib/famix/model/famix/comment.js +39 -0
- package/dist/lib/famix/model/famix/concretisation.js +31 -0
- package/dist/lib/famix/model/famix/container_entity.js +126 -0
- package/dist/lib/famix/model/famix/decorator.js +32 -0
- package/dist/lib/famix/model/famix/entity.js +17 -0
- package/dist/lib/famix/model/famix/enum.js +31 -0
- package/dist/lib/famix/model/famix/enum_value.js +25 -0
- package/dist/lib/famix/model/famix/function.js +17 -0
- package/dist/lib/famix/model/famix/import_clause.js +41 -0
- package/dist/lib/famix/{src/model → model}/famix/index.js +6 -10
- package/dist/lib/famix/model/famix/indexed_file_anchor.js +38 -0
- package/dist/lib/famix/model/famix/inheritance.js +33 -0
- package/dist/lib/famix/model/famix/interface.js +64 -0
- package/dist/lib/famix/model/famix/invocation.js +54 -0
- package/dist/lib/famix/model/famix/method.js +67 -0
- package/dist/lib/famix/model/famix/module.js +60 -0
- package/dist/lib/famix/model/famix/named_entity.js +78 -0
- package/dist/lib/famix/model/famix/parameter.js +25 -0
- package/dist/lib/famix/model/famix/parameter_concretisation.js +44 -0
- package/dist/lib/famix/model/famix/parameter_type.js +45 -0
- package/dist/lib/famix/model/famix/parametric_arrow_function.js +31 -0
- package/dist/lib/famix/model/famix/parametric_class.js +44 -0
- package/dist/lib/famix/model/famix/parametric_function.js +31 -0
- package/dist/lib/famix/model/famix/parametric_interface.js +44 -0
- package/dist/lib/famix/model/famix/parametric_method.js +31 -0
- package/dist/lib/famix/model/famix/primitive_type.js +17 -0
- package/dist/lib/famix/model/famix/property.js +73 -0
- package/dist/lib/famix/model/famix/reference.js +33 -0
- package/dist/lib/famix/model/famix/scoping_entity.js +36 -0
- package/dist/lib/famix/model/famix/script_entity.js +29 -0
- package/dist/lib/famix/model/famix/source_anchor.js +27 -0
- package/dist/lib/famix/model/famix/source_language.js +35 -0
- package/dist/lib/famix/model/famix/sourced_entity.js +60 -0
- package/dist/lib/famix/model/famix/structural_entity.js +39 -0
- package/dist/lib/famix/model/famix/type.js +73 -0
- package/dist/lib/famix/model/famix/variable.js +24 -0
- package/dist/lib/ts-complex/cyclomatic-service.js +2 -2
- package/dist/refactorer/refactor-getter-setter.js +142 -0
- package/dist/ts2famix-cli-wrapper.js +29 -3
- package/dist/ts2famix-cli.js +1 -1
- package/doc-uml/famix-typescript-model.puml +390 -341
- package/doc-uml/famix-typescript-model.svg +1 -1
- package/package.json +26 -9
- package/src/analyze.ts +2 -2
- package/src/analyze_functions/process_functions.ts +49 -44
- package/src/famix_functions/EntityDictionary.ts +345 -216
- package/src/famix_functions/helpers_creation.ts +36 -4
- package/src/fqn.ts +76 -125
- package/src/lib/famix/famix_JSON_exporter.ts +56 -0
- package/src/lib/famix/famix_base_element.ts +22 -0
- package/src/lib/famix/famix_repository.ts +243 -0
- package/src/lib/famix/model/famix/access.ts +50 -0
- package/src/lib/famix/model/famix/alias.ts +39 -0
- package/src/lib/famix/model/famix/behavioral_entity.ts +97 -0
- package/src/lib/famix/model/famix/class.ts +85 -0
- package/src/lib/famix/model/famix/comment.ts +47 -0
- package/src/lib/famix/model/famix/concretisation.ts +40 -0
- package/src/lib/famix/model/famix/container_entity.ts +160 -0
- package/src/lib/famix/model/famix/decorator.ts +37 -0
- package/src/lib/famix/model/famix/enum.ts +30 -0
- package/src/lib/famix/model/famix/enum_value.ts +28 -0
- package/src/lib/famix/model/famix/import_clause.ts +51 -0
- package/src/lib/famix/{src/model → model}/famix/index.ts +2 -4
- package/src/lib/famix/model/famix/indexed_file_anchor.ts +46 -0
- package/src/lib/famix/model/famix/inheritance.ts +40 -0
- package/src/lib/famix/model/famix/interface.ts +75 -0
- package/src/lib/famix/model/famix/invocation.ts +65 -0
- package/src/lib/famix/model/famix/method.ts +89 -0
- package/src/lib/famix/model/famix/module.ts +71 -0
- package/src/lib/famix/model/famix/named_entity.ts +95 -0
- package/src/lib/famix/{src/model → model}/famix/parameter.ts +11 -12
- package/src/lib/famix/model/famix/parameter_concretisation.ts +51 -0
- package/src/lib/famix/model/famix/parameter_type.ts +58 -0
- package/src/lib/famix/model/famix/parametric_arrow_function.ts +32 -0
- package/src/lib/famix/model/famix/parametric_class.ts +49 -0
- package/src/lib/famix/model/famix/parametric_function.ts +32 -0
- package/src/lib/famix/model/famix/parametric_interface.ts +49 -0
- package/src/lib/famix/model/famix/parametric_method.ts +32 -0
- package/src/lib/famix/model/famix/primitive_type.ts +15 -0
- package/src/lib/famix/model/famix/property.ts +94 -0
- package/src/lib/famix/model/famix/reference.ts +40 -0
- package/src/lib/famix/model/famix/scoping_entity.ts +35 -0
- package/src/lib/famix/model/famix/script_entity.ts +34 -0
- package/src/lib/famix/model/famix/source_anchor.ts +30 -0
- package/src/lib/famix/model/famix/source_language.ts +35 -0
- package/src/lib/famix/model/famix/sourced_entity.ts +70 -0
- package/src/lib/famix/model/famix/structural_entity.ts +43 -0
- package/src/lib/famix/model/famix/type.ts +87 -0
- package/src/lib/famix/model/famix/variable.ts +27 -0
- package/src/lib/famix/package.json +1 -1
- package/src/lib/ts-complex/cyclomatic-service.ts +10 -10
- package/src/refactorer/refactor-getter-setter.ts +140 -0
- package/src/ts2famix-cli-wrapper.ts +6 -2
- package/src/ts2famix-cli.ts +1 -1
- package/tsconfig.check-tests.json +14 -0
- package/tsconfig.json +70 -68
- package/dist/famix2puml.js +0 -126
- package/dist/lib/famix/src/famix_JSON_exporter.js +0 -55
- package/dist/lib/famix/src/famix_base_element.js +0 -18
- package/dist/lib/famix/src/famix_repository.js +0 -223
- package/dist/lib/famix/src/model/famix/access.js +0 -40
- package/dist/lib/famix/src/model/famix/accessor.js +0 -17
- package/dist/lib/famix/src/model/famix/alias.js +0 -33
- package/dist/lib/famix/src/model/famix/arrowFunction.js +0 -17
- package/dist/lib/famix/src/model/famix/behavioral_entity.js +0 -79
- package/dist/lib/famix/src/model/famix/class.js +0 -71
- package/dist/lib/famix/src/model/famix/comment.js +0 -39
- package/dist/lib/famix/src/model/famix/concretisation.js +0 -31
- package/dist/lib/famix/src/model/famix/container_entity.js +0 -126
- package/dist/lib/famix/src/model/famix/decorator.js +0 -32
- package/dist/lib/famix/src/model/famix/entity.js +0 -17
- package/dist/lib/famix/src/model/famix/enum.js +0 -31
- package/dist/lib/famix/src/model/famix/enum_value.js +0 -25
- package/dist/lib/famix/src/model/famix/function.js +0 -17
- package/dist/lib/famix/src/model/famix/implicit_variable.js +0 -17
- package/dist/lib/famix/src/model/famix/import_clause.js +0 -41
- package/dist/lib/famix/src/model/famix/indexed_file_anchor.js +0 -52
- package/dist/lib/famix/src/model/famix/inheritance.js +0 -33
- package/dist/lib/famix/src/model/famix/interface.js +0 -64
- package/dist/lib/famix/src/model/famix/invocation.js +0 -54
- package/dist/lib/famix/src/model/famix/method.js +0 -67
- package/dist/lib/famix/src/model/famix/module.js +0 -84
- package/dist/lib/famix/src/model/famix/named_entity.js +0 -78
- package/dist/lib/famix/src/model/famix/parameter.js +0 -25
- package/dist/lib/famix/src/model/famix/parameterConcretisation.js +0 -44
- package/dist/lib/famix/src/model/famix/parameter_type.js +0 -45
- package/dist/lib/famix/src/model/famix/parametric_arrow_function.js +0 -31
- package/dist/lib/famix/src/model/famix/parametric_class.js +0 -44
- package/dist/lib/famix/src/model/famix/parametric_function.js +0 -31
- package/dist/lib/famix/src/model/famix/parametric_interface.js +0 -44
- package/dist/lib/famix/src/model/famix/parametric_method.js +0 -31
- package/dist/lib/famix/src/model/famix/primitive_type.js +0 -17
- package/dist/lib/famix/src/model/famix/property.js +0 -126
- package/dist/lib/famix/src/model/famix/reference.js +0 -33
- package/dist/lib/famix/src/model/famix/scoping_entity.js +0 -37
- package/dist/lib/famix/src/model/famix/script_entity.js +0 -29
- package/dist/lib/famix/src/model/famix/source_anchor.js +0 -27
- package/dist/lib/famix/src/model/famix/source_language.js +0 -35
- package/dist/lib/famix/src/model/famix/sourced_entity.js +0 -60
- package/dist/lib/famix/src/model/famix/structural_entity.js +0 -39
- package/dist/lib/famix/src/model/famix/text_anchor.js +0 -38
- package/dist/lib/famix/src/model/famix/type.js +0 -73
- package/dist/lib/famix/src/model/famix/variable.js +0 -24
- package/jest.config-old.ts +0 -199
- package/src/famix2puml.ts +0 -119
- package/src/lib/famix/package-lock.json +0 -301
- package/src/lib/famix/readme.md +0 -5
- package/src/lib/famix/src/famix_JSON_exporter.ts +0 -56
- package/src/lib/famix/src/famix_base_element.ts +0 -22
- package/src/lib/famix/src/famix_repository.ts +0 -243
- package/src/lib/famix/src/model/famix/access.ts +0 -53
- package/src/lib/famix/src/model/famix/alias.ts +0 -41
- package/src/lib/famix/src/model/famix/behavioral_entity.ts +0 -100
- package/src/lib/famix/src/model/famix/class.ts +0 -86
- package/src/lib/famix/src/model/famix/comment.ts +0 -50
- package/src/lib/famix/src/model/famix/concretisation.ts +0 -42
- package/src/lib/famix/src/model/famix/container_entity.ts +0 -165
- package/src/lib/famix/src/model/famix/decorator.ts +0 -39
- package/src/lib/famix/src/model/famix/enum.ts +0 -31
- package/src/lib/famix/src/model/famix/enum_value.ts +0 -29
- package/src/lib/famix/src/model/famix/implicit_variable.ts +0 -15
- package/src/lib/famix/src/model/famix/import_clause.ts +0 -54
- package/src/lib/famix/src/model/famix/indexed_file_anchor.ts +0 -71
- package/src/lib/famix/src/model/famix/inheritance.ts +0 -41
- package/src/lib/famix/src/model/famix/interface.ts +0 -75
- package/src/lib/famix/src/model/famix/invocation.ts +0 -68
- package/src/lib/famix/src/model/famix/method.ts +0 -96
- package/src/lib/famix/src/model/famix/module.ts +0 -97
- package/src/lib/famix/src/model/famix/named_entity.ts +0 -98
- package/src/lib/famix/src/model/famix/parameterConcretisation.ts +0 -54
- package/src/lib/famix/src/model/famix/parameter_type.ts +0 -60
- package/src/lib/famix/src/model/famix/parametric_arrow_function.ts +0 -32
- package/src/lib/famix/src/model/famix/parametric_class.ts +0 -49
- package/src/lib/famix/src/model/famix/parametric_function.ts +0 -32
- package/src/lib/famix/src/model/famix/parametric_interface.ts +0 -49
- package/src/lib/famix/src/model/famix/parametric_method.ts +0 -32
- package/src/lib/famix/src/model/famix/primitive_type.ts +0 -15
- package/src/lib/famix/src/model/famix/property.ts +0 -152
- package/src/lib/famix/src/model/famix/reference.ts +0 -42
- package/src/lib/famix/src/model/famix/scoping_entity.ts +0 -36
- package/src/lib/famix/src/model/famix/script_entity.ts +0 -36
- package/src/lib/famix/src/model/famix/source_anchor.ts +0 -31
- package/src/lib/famix/src/model/famix/source_language.ts +0 -36
- package/src/lib/famix/src/model/famix/sourced_entity.ts +0 -73
- package/src/lib/famix/src/model/famix/structural_entity.ts +0 -44
- package/src/lib/famix/src/model/famix/text_anchor.ts +0 -49
- package/src/lib/famix/src/model/famix/type.ts +0 -89
- package/src/lib/famix/src/model/famix/variable.ts +0 -28
- package/src/lib/famix/tsconfig.json +0 -27
- package/src/lib/famix/tslint.json +0 -15
- /package/src/lib/famix/{src/index.ts → index.ts} +0 -0
- /package/src/lib/famix/{src/model → model}/famix/accessor.ts +0 -0
- /package/src/lib/famix/{src/model/famix/arrowFunction.ts → model/famix/arrow_function.ts} +0 -0
- /package/src/lib/famix/{src/model → model}/famix/entity.ts +0 -0
- /package/src/lib/famix/{src/model → model}/famix/function.ts +0 -0
|
@@ -29,12 +29,12 @@ Object.defineProperty(exports, "__esModule", { value: true });
|
|
|
29
29
|
exports.EntityDictionary = void 0;
|
|
30
30
|
const ts_morph_1 = require("ts-morph");
|
|
31
31
|
const process_functions_1 = require("../analyze_functions/process_functions");
|
|
32
|
-
const Famix = __importStar(require("../lib/famix/
|
|
32
|
+
const Famix = __importStar(require("../lib/famix/model/famix"));
|
|
33
|
+
const famix_repository_1 = require("../lib/famix/famix_repository");
|
|
33
34
|
const analyze_1 = require("../analyze");
|
|
34
35
|
const grapheme_splitter_1 = __importDefault(require("grapheme-splitter"));
|
|
35
36
|
const Helpers = __importStar(require("./helpers_creation"));
|
|
36
37
|
const FQNFunctions = __importStar(require("../fqn"));
|
|
37
|
-
const famix_repository_1 = require("../lib/famix/src/famix_repository");
|
|
38
38
|
const path_1 = __importDefault(require("path"));
|
|
39
39
|
const lodash_1 = __importDefault(require("lodash"));
|
|
40
40
|
class EntityDictionary {
|
|
@@ -49,17 +49,76 @@ class EntityDictionary {
|
|
|
49
49
|
this.fmxFunctionAndMethodMap = new Map; // Maps the function names to their Famix model
|
|
50
50
|
this.UNKNOWN_VALUE = '(unknown due to parsing error)'; // The value to use when a name is not usable
|
|
51
51
|
this.fmxElementObjectMap = new Map();
|
|
52
|
+
this.tsMorphElementObjectMap = new Map();
|
|
52
53
|
this.famixRep.setFmxElementObjectMap(this.fmxElementObjectMap);
|
|
53
54
|
}
|
|
55
|
+
addSourceAnchor(fmx, node) {
|
|
56
|
+
const sourceAnchor = new Famix.IndexedFileAnchor();
|
|
57
|
+
let sourceStart, sourceEnd;
|
|
58
|
+
if (fmx && node) {
|
|
59
|
+
// find the start and end positions of the source element
|
|
60
|
+
if (!(node instanceof ts_morph_1.CommentRange)) {
|
|
61
|
+
sourceStart = node.getStart();
|
|
62
|
+
sourceEnd = node.getEnd();
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
sourceStart = node.getPos();
|
|
66
|
+
sourceEnd = node.getEnd();
|
|
67
|
+
}
|
|
68
|
+
if (analyze_1.config.expectGraphemes) {
|
|
69
|
+
/**
|
|
70
|
+
* The following logic handles the case of multi-code point characters (e.g. emoji) in the source text.
|
|
71
|
+
* This is needed because Pharo/Smalltalk treats multi-code point characters as a single character,
|
|
72
|
+
* but JavaScript treats them as multiple characters. This means that the start and end positions
|
|
73
|
+
* of a source element in Pharo/Smalltalk will be different than the start and end positions of the
|
|
74
|
+
* same source element in JavaScript. This logic finds the start and end positions of the source
|
|
75
|
+
* element in JavaScript and then uses those positions to set the start and end positions of the
|
|
76
|
+
* Famix index file anchor.
|
|
77
|
+
* It depends on code in the 'grapheme-splitter' package in npm.
|
|
78
|
+
*/
|
|
79
|
+
const splitter = new grapheme_splitter_1.default();
|
|
80
|
+
const sourceFileText = node.getSourceFile().getFullText();
|
|
81
|
+
const hasGraphemeClusters = splitter.countGraphemes(sourceFileText) > 1;
|
|
82
|
+
if (hasGraphemeClusters) {
|
|
83
|
+
const sourceElementText = sourceFileText.substring(sourceStart, sourceEnd);
|
|
84
|
+
const sourceElementTextGraphemes = splitter.splitGraphemes(sourceElementText);
|
|
85
|
+
const sourceFileTextGraphemes = splitter.splitGraphemes(sourceFileText);
|
|
86
|
+
const numberOfGraphemeClustersBeforeStart = splitter.countGraphemes(sourceFileText.substring(0, sourceStart));
|
|
87
|
+
// find the start of the sourceElementTextGraphemes array in the sourceFileTextGraphemes array
|
|
88
|
+
sourceStart = Helpers.indexOfSplitArray({ searchArray: sourceFileTextGraphemes,
|
|
89
|
+
targetArray: sourceElementTextGraphemes,
|
|
90
|
+
start: sourceStart - numberOfGraphemeClustersBeforeStart });
|
|
91
|
+
sourceEnd = sourceStart + sourceElementTextGraphemes.length;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
// The +1 is because the source anchor (Pharo) is 1-based, but ts-morph is 0-based
|
|
95
|
+
sourceAnchor.startPos = sourceStart + 1;
|
|
96
|
+
sourceAnchor.endPos = sourceEnd + 1;
|
|
97
|
+
const fileName = node.getSourceFile().getFilePath();
|
|
98
|
+
sourceAnchor.element = fmx;
|
|
99
|
+
sourceAnchor.fileName = fileName;
|
|
100
|
+
fmx.sourceAnchor = sourceAnchor;
|
|
101
|
+
this.famixRep.addElement(sourceAnchor);
|
|
102
|
+
}
|
|
103
|
+
return sourceAnchor;
|
|
104
|
+
}
|
|
54
105
|
/**
|
|
55
106
|
* Makes a Famix index file anchor
|
|
56
107
|
* @param sourceElement A source element
|
|
57
108
|
* @param famixElement The Famix model of the source element
|
|
58
109
|
*/
|
|
59
110
|
makeFamixIndexFileAnchor(sourceElement, famixElement) {
|
|
111
|
+
// check if famixElement doesn't have a valid fullyQualifiedName
|
|
112
|
+
if (typeof famixElement.getFullyQualifiedName === 'function') {
|
|
113
|
+
// The method exists
|
|
114
|
+
const fullyQualifiedName = famixElement.fullyQualifiedName;
|
|
115
|
+
if (!fullyQualifiedName || fullyQualifiedName === this.UNKNOWN_VALUE) {
|
|
116
|
+
throw new Error(`Famix element ${famixElement.constructor.name} has no valid fullyQualifiedName.`);
|
|
117
|
+
}
|
|
118
|
+
}
|
|
60
119
|
analyze_1.logger.debug("making index file anchor for '" + sourceElement?.getText() + "' with famixElement " + famixElement.getJSON());
|
|
61
120
|
const fmxIndexFileAnchor = new Famix.IndexedFileAnchor();
|
|
62
|
-
fmxIndexFileAnchor.
|
|
121
|
+
fmxIndexFileAnchor.element = famixElement;
|
|
63
122
|
this.fmxElementObjectMap.set(famixElement, sourceElement);
|
|
64
123
|
if (sourceElement !== null) {
|
|
65
124
|
const absolutePathProject = this.famixRep.getAbsolutePath();
|
|
@@ -75,7 +134,7 @@ class EntityDictionary {
|
|
|
75
134
|
}
|
|
76
135
|
// revert any backslashes to forward slashes (path.normalize on windows introduces them)
|
|
77
136
|
pathInProject = pathInProject.replace(/\\/g, "/");
|
|
78
|
-
fmxIndexFileAnchor.
|
|
137
|
+
fmxIndexFileAnchor.fileName = pathInProject;
|
|
79
138
|
let sourceStart, sourceEnd, sourceLineStart, sourceLineEnd;
|
|
80
139
|
if (!(sourceElement instanceof ts_morph_1.CommentRange)) {
|
|
81
140
|
sourceStart = sourceElement.getStart();
|
|
@@ -114,24 +173,18 @@ class EntityDictionary {
|
|
|
114
173
|
}
|
|
115
174
|
}
|
|
116
175
|
// note: the +1 is because the source anchor is 1-based, but ts-morph is 0-based
|
|
117
|
-
fmxIndexFileAnchor.
|
|
118
|
-
fmxIndexFileAnchor.
|
|
119
|
-
if (!(sourceElement instanceof
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
}
|
|
123
|
-
if (!(famixElement instanceof Famix.ImportClause || famixElement instanceof Famix.Access || famixElement instanceof Famix.Reference || famixElement instanceof Famix.Invocation || famixElement instanceof Famix.Inheritance) && !(famixElement instanceof Famix.Comment) && !(sourceElement instanceof ts_morph_1.CommentRange) && !(sourceElement instanceof ts_morph_1.Identifier) && !(sourceElement instanceof ts_morph_1.ImportSpecifier) && !(sourceElement instanceof ts_morph_1.ExpressionWithTypeArguments)) {
|
|
124
|
-
const fqn = FQNFunctions.getFQN(sourceElement);
|
|
125
|
-
analyze_1.logger.debug("Setting fully qualified name for " + famixElement.getJSON() + " to " + fqn);
|
|
126
|
-
famixElement.setFullyQualifiedName(fqn);
|
|
127
|
-
}
|
|
176
|
+
fmxIndexFileAnchor.startPos = sourceStart + 1;
|
|
177
|
+
fmxIndexFileAnchor.endPos = sourceEnd + 1;
|
|
178
|
+
// if (!(famixElement instanceof Famix.ImportClause || famixElement instanceof Famix.Access || famixElement instanceof Famix.Reference || famixElement instanceof Famix.Invocation || famixElement instanceof Famix.Inheritance) && !(famixElement instanceof Famix.Comment) && !(sourceElement instanceof CommentRange) && !(sourceElement instanceof Identifier) && !(sourceElement instanceof ImportSpecifier) && !(sourceElement instanceof ExpressionWithTypeArguments)) {
|
|
179
|
+
// initFQN(sourceElement, famixElement);
|
|
180
|
+
// }
|
|
128
181
|
}
|
|
129
182
|
else {
|
|
130
183
|
// sourceElement is null
|
|
131
184
|
analyze_1.logger.warn("sourceElement is null for famixElement " + famixElement.getJSON());
|
|
132
|
-
fmxIndexFileAnchor.
|
|
133
|
-
fmxIndexFileAnchor.
|
|
134
|
-
fmxIndexFileAnchor.
|
|
185
|
+
fmxIndexFileAnchor.fileName = "unknown";
|
|
186
|
+
fmxIndexFileAnchor.startPos = 0;
|
|
187
|
+
fmxIndexFileAnchor.endPos = 0;
|
|
135
188
|
}
|
|
136
189
|
this.famixRep.addElement(fmxIndexFileAnchor);
|
|
137
190
|
}
|
|
@@ -145,22 +198,24 @@ class EntityDictionary {
|
|
|
145
198
|
let fmxFile; // | Famix.Module;
|
|
146
199
|
const fileName = f.getBaseName();
|
|
147
200
|
const fullyQualifiedFilename = f.getFilePath();
|
|
148
|
-
|
|
201
|
+
const foundFileName = this.fmxFileMap.get(fullyQualifiedFilename);
|
|
202
|
+
if (!foundFileName) {
|
|
149
203
|
if (isModule) {
|
|
150
204
|
fmxFile = new Famix.Module();
|
|
151
205
|
}
|
|
152
206
|
else {
|
|
153
207
|
fmxFile = new Famix.ScriptEntity();
|
|
154
208
|
}
|
|
155
|
-
fmxFile.
|
|
156
|
-
fmxFile.
|
|
157
|
-
fmxFile.
|
|
209
|
+
fmxFile.name = fileName;
|
|
210
|
+
fmxFile.numberOfLinesOfText = f.getEndLineNumber() - f.getStartLineNumber();
|
|
211
|
+
fmxFile.numberOfCharacters = f.getFullText().length;
|
|
212
|
+
initFQN(f, fmxFile);
|
|
158
213
|
this.makeFamixIndexFileAnchor(f, fmxFile);
|
|
159
214
|
this.fmxFileMap.set(fullyQualifiedFilename, fmxFile);
|
|
160
215
|
this.famixRep.addElement(fmxFile);
|
|
161
216
|
}
|
|
162
217
|
else {
|
|
163
|
-
fmxFile =
|
|
218
|
+
fmxFile = foundFileName;
|
|
164
219
|
}
|
|
165
220
|
this.fmxElementObjectMap.set(fmxFile, f);
|
|
166
221
|
return fmxFile;
|
|
@@ -173,18 +228,20 @@ class EntityDictionary {
|
|
|
173
228
|
createOrGetFamixModule(m) {
|
|
174
229
|
let fmxModule;
|
|
175
230
|
const moduleName = m.getName();
|
|
176
|
-
|
|
231
|
+
const foundModuleName = this.fmxModuleMap.get(moduleName);
|
|
232
|
+
if (!foundModuleName) {
|
|
177
233
|
fmxModule = new Famix.Module();
|
|
178
|
-
fmxModule.
|
|
179
|
-
fmxModule
|
|
180
|
-
fmxModule
|
|
181
|
-
fmxModule
|
|
234
|
+
fmxModule.name = moduleName;
|
|
235
|
+
fmxModule.isAmbient = (0, process_functions_1.isAmbient)(m);
|
|
236
|
+
fmxModule.isNamespace = (0, process_functions_1.isNamespace)(m);
|
|
237
|
+
fmxModule.isModule = !fmxModule.isNamespace && !fmxModule.isAmbient;
|
|
238
|
+
initFQN(m, fmxModule);
|
|
182
239
|
this.makeFamixIndexFileAnchor(m, fmxModule);
|
|
183
240
|
this.fmxModuleMap.set(moduleName, fmxModule);
|
|
184
241
|
this.famixRep.addElement(fmxModule);
|
|
185
242
|
}
|
|
186
243
|
else {
|
|
187
|
-
fmxModule =
|
|
244
|
+
fmxModule = foundModuleName;
|
|
188
245
|
}
|
|
189
246
|
this.fmxElementObjectMap.set(fmxModule, m);
|
|
190
247
|
return fmxModule;
|
|
@@ -198,19 +255,21 @@ class EntityDictionary {
|
|
|
198
255
|
let fmxAlias;
|
|
199
256
|
const aliasName = a.getName();
|
|
200
257
|
const aliasFullyQualifiedName = a.getType().getText(); // FQNFunctions.getFQN(a);
|
|
201
|
-
|
|
258
|
+
const foundAlias = this.fmxAliasMap.get(aliasFullyQualifiedName);
|
|
259
|
+
if (!foundAlias) {
|
|
202
260
|
fmxAlias = new Famix.Alias();
|
|
203
|
-
fmxAlias.
|
|
261
|
+
fmxAlias.name = a.getName();
|
|
204
262
|
const aliasNameWithGenerics = aliasName + (a.getTypeParameters().length ? ("<" + a.getTypeParameters().map(tp => tp.getName()).join(", ") + ">") : "");
|
|
205
263
|
analyze_1.logger.debug(`> NOTE: alias ${aliasName} has fully qualified name ${aliasFullyQualifiedName} and name with generics ${aliasNameWithGenerics}.`);
|
|
206
264
|
const fmxType = this.createOrGetFamixType(aliasNameWithGenerics, a);
|
|
207
|
-
fmxAlias.
|
|
265
|
+
fmxAlias.aliasedEntity = fmxType;
|
|
266
|
+
initFQN(a, fmxAlias);
|
|
208
267
|
this.makeFamixIndexFileAnchor(a, fmxAlias);
|
|
209
268
|
this.fmxAliasMap.set(aliasFullyQualifiedName, fmxAlias);
|
|
210
269
|
this.famixRep.addElement(fmxAlias);
|
|
211
270
|
}
|
|
212
271
|
else {
|
|
213
|
-
fmxAlias =
|
|
272
|
+
fmxAlias = foundAlias;
|
|
214
273
|
}
|
|
215
274
|
this.fmxElementObjectMap.set(fmxAlias, a);
|
|
216
275
|
return fmxAlias;
|
|
@@ -224,25 +283,26 @@ class EntityDictionary {
|
|
|
224
283
|
let fmxClass;
|
|
225
284
|
const isAbstract = cls.isAbstract();
|
|
226
285
|
const classFullyQualifiedName = FQNFunctions.getFQN(cls);
|
|
227
|
-
const clsName = cls.getName();
|
|
286
|
+
const clsName = cls.getName() || this.UNKNOWN_VALUE;
|
|
228
287
|
const isGeneric = cls.getTypeParameters().length;
|
|
229
|
-
|
|
288
|
+
const foundClass = this.fmxClassMap.get(classFullyQualifiedName);
|
|
289
|
+
if (!foundClass) {
|
|
230
290
|
if (isGeneric) {
|
|
231
291
|
fmxClass = new Famix.ParametricClass();
|
|
232
292
|
}
|
|
233
293
|
else {
|
|
234
294
|
fmxClass = new Famix.Class();
|
|
235
295
|
}
|
|
236
|
-
fmxClass.
|
|
237
|
-
fmxClass.
|
|
238
|
-
fmxClass.
|
|
296
|
+
fmxClass.name = clsName;
|
|
297
|
+
fmxClass.fullyQualifiedName = classFullyQualifiedName;
|
|
298
|
+
fmxClass.isAbstract = isAbstract;
|
|
239
299
|
this.makeFamixIndexFileAnchor(cls, fmxClass);
|
|
240
300
|
this.fmxClassMap.set(classFullyQualifiedName, fmxClass);
|
|
241
301
|
this.famixRep.addElement(fmxClass);
|
|
242
302
|
this.fmxElementObjectMap.set(fmxClass, cls);
|
|
243
303
|
}
|
|
244
304
|
else {
|
|
245
|
-
fmxClass =
|
|
305
|
+
fmxClass = foundClass;
|
|
246
306
|
}
|
|
247
307
|
return fmxClass;
|
|
248
308
|
}
|
|
@@ -255,7 +315,8 @@ class EntityDictionary {
|
|
|
255
315
|
let fmxInterface;
|
|
256
316
|
const interName = inter.getName();
|
|
257
317
|
const interFullyQualifiedName = FQNFunctions.getFQN(inter);
|
|
258
|
-
|
|
318
|
+
const foundInterface = this.fmxInterfaceMap.get(interFullyQualifiedName);
|
|
319
|
+
if (!foundInterface) {
|
|
259
320
|
const isGeneric = inter.getTypeParameters().length;
|
|
260
321
|
if (isGeneric) {
|
|
261
322
|
fmxInterface = new Famix.ParametricInterface();
|
|
@@ -263,26 +324,27 @@ class EntityDictionary {
|
|
|
263
324
|
else {
|
|
264
325
|
fmxInterface = new Famix.Interface();
|
|
265
326
|
}
|
|
266
|
-
fmxInterface.
|
|
327
|
+
fmxInterface.name = interName;
|
|
328
|
+
initFQN(inter, fmxInterface);
|
|
267
329
|
this.makeFamixIndexFileAnchor(inter, fmxInterface);
|
|
268
330
|
this.fmxInterfaceMap.set(interFullyQualifiedName, fmxInterface);
|
|
269
331
|
this.famixRep.addElement(fmxInterface);
|
|
270
332
|
this.fmxElementObjectMap.set(fmxInterface, inter);
|
|
271
333
|
}
|
|
272
334
|
else {
|
|
273
|
-
fmxInterface =
|
|
335
|
+
fmxInterface = foundInterface;
|
|
274
336
|
}
|
|
275
337
|
return fmxInterface;
|
|
276
338
|
}
|
|
277
339
|
/**
|
|
278
340
|
* Creates or gets a Famix concrete element
|
|
279
|
-
* @param
|
|
280
|
-
* @param
|
|
341
|
+
* @param concreteElement A parametric Element
|
|
342
|
+
* @param concreteElementDeclaration the element declaration
|
|
281
343
|
* @param concreteArguments concrete arguments
|
|
282
344
|
* @returns A parametric Element
|
|
283
345
|
*/
|
|
284
|
-
createOrGetFamixConcreteElement(
|
|
285
|
-
let fullyQualifiedFilename =
|
|
346
|
+
createOrGetFamixConcreteElement(concreteElement, concreteElementDeclaration, concreteArguments) {
|
|
347
|
+
let fullyQualifiedFilename = concreteElement.fullyQualifiedName;
|
|
286
348
|
let params = "";
|
|
287
349
|
concreteArguments.map((param) => {
|
|
288
350
|
params = params + param.getText() + ',';
|
|
@@ -290,40 +352,42 @@ class EntityDictionary {
|
|
|
290
352
|
params = params.substring(0, params.length - 1);
|
|
291
353
|
fullyQualifiedFilename = Helpers.replaceLastBetweenTags(fullyQualifiedFilename, params);
|
|
292
354
|
let concElement;
|
|
293
|
-
if (!this.fmxInterfaceMap.has(fullyQualifiedFilename) &&
|
|
294
|
-
|
|
295
|
-
|
|
355
|
+
if (!this.fmxInterfaceMap.has(fullyQualifiedFilename) &&
|
|
356
|
+
!this.fmxClassMap.has(fullyQualifiedFilename) &&
|
|
357
|
+
!this.fmxFunctionAndMethodMap.has(fullyQualifiedFilename)) {
|
|
358
|
+
concElement = lodash_1.default.cloneDeep(concreteElement);
|
|
359
|
+
concElement.fullyQualifiedName = fullyQualifiedFilename;
|
|
296
360
|
concElement.clearGenericParameters();
|
|
297
361
|
concreteArguments.map((param) => {
|
|
298
362
|
const parameter = this.createOrGetFamixConcreteType(param);
|
|
299
363
|
concElement.addConcreteParameter(parameter);
|
|
300
364
|
});
|
|
301
|
-
if (
|
|
365
|
+
if (concreteElement instanceof Famix.ParametricClass) {
|
|
302
366
|
this.fmxClassMap.set(fullyQualifiedFilename, concElement);
|
|
303
367
|
}
|
|
304
|
-
else if (
|
|
368
|
+
else if (concreteElement instanceof Famix.ParametricInterface) {
|
|
305
369
|
this.fmxInterfaceMap.set(fullyQualifiedFilename, concElement);
|
|
306
370
|
}
|
|
307
|
-
else if (
|
|
371
|
+
else if (concreteElement instanceof Famix.ParametricFunction) {
|
|
308
372
|
this.fmxFunctionAndMethodMap.set(fullyQualifiedFilename, concElement);
|
|
309
373
|
}
|
|
310
|
-
else if (
|
|
374
|
+
else { // if (concreteElement instanceof Famix.ParametricMethod) {
|
|
311
375
|
this.fmxFunctionAndMethodMap.set(fullyQualifiedFilename, concElement);
|
|
312
376
|
}
|
|
313
377
|
this.famixRep.addElement(concElement);
|
|
314
|
-
this.fmxElementObjectMap.set(concElement,
|
|
378
|
+
this.fmxElementObjectMap.set(concElement, concreteElementDeclaration);
|
|
315
379
|
}
|
|
316
380
|
else {
|
|
317
|
-
if (
|
|
381
|
+
if (concreteElement instanceof Famix.ParametricClass) {
|
|
318
382
|
concElement = this.fmxClassMap.get(fullyQualifiedFilename);
|
|
319
383
|
}
|
|
320
|
-
else if (
|
|
384
|
+
else if (concreteElement instanceof Famix.ParametricInterface) {
|
|
321
385
|
concElement = this.fmxInterfaceMap.get(fullyQualifiedFilename);
|
|
322
386
|
}
|
|
323
|
-
else if (
|
|
387
|
+
else if (concreteElement instanceof Famix.ParametricFunction) {
|
|
324
388
|
concElement = this.fmxFunctionAndMethodMap.get(fullyQualifiedFilename);
|
|
325
389
|
}
|
|
326
|
-
else if (
|
|
390
|
+
else { // if (concreteElement instanceof Famix.ParametricMethod) {
|
|
327
391
|
concElement = this.fmxFunctionAndMethodMap.get(fullyQualifiedFilename);
|
|
328
392
|
}
|
|
329
393
|
}
|
|
@@ -337,7 +401,7 @@ class EntityDictionary {
|
|
|
337
401
|
createFamixProperty(property) {
|
|
338
402
|
const fmxProperty = new Famix.Property();
|
|
339
403
|
const isSignature = property instanceof ts_morph_1.PropertySignature;
|
|
340
|
-
fmxProperty.
|
|
404
|
+
fmxProperty.name = property.getName();
|
|
341
405
|
let propTypeName = this.UNKNOWN_VALUE;
|
|
342
406
|
try {
|
|
343
407
|
propTypeName = property.getType().getText().trim();
|
|
@@ -346,7 +410,7 @@ class EntityDictionary {
|
|
|
346
410
|
analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for property: ${property.getName()}. Continuing...`);
|
|
347
411
|
}
|
|
348
412
|
const fmxType = this.createOrGetFamixType(propTypeName, property);
|
|
349
|
-
fmxProperty.
|
|
413
|
+
fmxProperty.declaredType = fmxType;
|
|
350
414
|
// add the visibility (public, private, etc.) to the fmxProperty
|
|
351
415
|
fmxProperty.visibility = "";
|
|
352
416
|
property.getModifiers().forEach(m => {
|
|
@@ -361,7 +425,7 @@ class EntityDictionary {
|
|
|
361
425
|
fmxProperty.visibility = "private";
|
|
362
426
|
break;
|
|
363
427
|
case "static":
|
|
364
|
-
fmxProperty.
|
|
428
|
+
fmxProperty.isClassSide = true;
|
|
365
429
|
break;
|
|
366
430
|
case "readonly":
|
|
367
431
|
fmxProperty.readOnly = true;
|
|
@@ -379,6 +443,7 @@ class EntityDictionary {
|
|
|
379
443
|
if (property.getName().substring(0, 1) === "#") {
|
|
380
444
|
fmxProperty.isJavaScriptPrivate = true;
|
|
381
445
|
}
|
|
446
|
+
initFQN(property, fmxProperty);
|
|
382
447
|
this.makeFamixIndexFileAnchor(property, fmxProperty);
|
|
383
448
|
this.famixRep.addElement(fmxProperty);
|
|
384
449
|
this.fmxElementObjectMap.set(fmxProperty, property);
|
|
@@ -400,10 +465,10 @@ class EntityDictionary {
|
|
|
400
465
|
const isGetter = method instanceof ts_morph_1.GetAccessorDeclaration;
|
|
401
466
|
const isSetter = method instanceof ts_morph_1.SetAccessorDeclaration;
|
|
402
467
|
if (isGetter) {
|
|
403
|
-
fmxMethod.
|
|
468
|
+
fmxMethod.kind = "getter";
|
|
404
469
|
}
|
|
405
470
|
if (isSetter) {
|
|
406
|
-
fmxMethod.
|
|
471
|
+
fmxMethod.kind = "setter";
|
|
407
472
|
}
|
|
408
473
|
this.famixRep.addElement(fmxMethod);
|
|
409
474
|
}
|
|
@@ -425,13 +490,13 @@ class EntityDictionary {
|
|
|
425
490
|
isStatic = method.isStatic();
|
|
426
491
|
}
|
|
427
492
|
if (isConstructor) {
|
|
428
|
-
fmxMethod.
|
|
493
|
+
fmxMethod.kind = "constructor";
|
|
429
494
|
}
|
|
430
|
-
fmxMethod.
|
|
431
|
-
fmxMethod.
|
|
432
|
-
fmxMethod.
|
|
433
|
-
fmxMethod.
|
|
434
|
-
fmxMethod.
|
|
495
|
+
fmxMethod.isAbstract = isAbstract;
|
|
496
|
+
fmxMethod.isClassSide = isStatic;
|
|
497
|
+
fmxMethod.isPrivate = (method instanceof ts_morph_1.MethodDeclaration || method instanceof ts_morph_1.GetAccessorDeclaration || method instanceof ts_morph_1.SetAccessorDeclaration) ? (method.getModifiers().find(x => x.getText() === 'private')) !== undefined : false;
|
|
498
|
+
fmxMethod.isProtected = (method instanceof ts_morph_1.MethodDeclaration || method instanceof ts_morph_1.GetAccessorDeclaration || method instanceof ts_morph_1.SetAccessorDeclaration) ? (method.getModifiers().find(x => x.getText() === 'protected')) !== undefined : false;
|
|
499
|
+
fmxMethod.signature = Helpers.computeSignature(method.getText());
|
|
435
500
|
let methodName;
|
|
436
501
|
if (isConstructor) {
|
|
437
502
|
methodName = "constructor";
|
|
@@ -439,42 +504,43 @@ class EntityDictionary {
|
|
|
439
504
|
else {
|
|
440
505
|
methodName = method.getName();
|
|
441
506
|
}
|
|
442
|
-
fmxMethod.
|
|
507
|
+
fmxMethod.name = methodName;
|
|
443
508
|
if (!isConstructor) {
|
|
444
509
|
if (method.getName().substring(0, 1) === "#") {
|
|
445
|
-
fmxMethod.
|
|
510
|
+
fmxMethod.isPrivate = true;
|
|
446
511
|
}
|
|
447
512
|
}
|
|
448
|
-
if (!fmxMethod.
|
|
449
|
-
fmxMethod.
|
|
513
|
+
if (!fmxMethod.isPrivate && !fmxMethod.isProtected) {
|
|
514
|
+
fmxMethod.isPublic = true;
|
|
450
515
|
}
|
|
451
516
|
else {
|
|
452
|
-
fmxMethod.
|
|
517
|
+
fmxMethod.isPublic = false;
|
|
453
518
|
}
|
|
454
519
|
if (!isSignature) {
|
|
455
|
-
fmxMethod.
|
|
520
|
+
fmxMethod.cyclomaticComplexity = currentCC[fmxMethod.name];
|
|
456
521
|
}
|
|
457
522
|
else {
|
|
458
|
-
fmxMethod.
|
|
523
|
+
fmxMethod.cyclomaticComplexity = 0;
|
|
459
524
|
}
|
|
460
525
|
let methodTypeName = this.UNKNOWN_VALUE;
|
|
461
526
|
try {
|
|
462
527
|
methodTypeName = method.getReturnType().getText().trim();
|
|
463
528
|
}
|
|
464
529
|
catch (error) {
|
|
465
|
-
analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for return type of method: ${fmxMethod.
|
|
530
|
+
analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for return type of method: ${fmxMethod.name}. Continuing...`);
|
|
466
531
|
}
|
|
467
532
|
const fmxType = this.createOrGetFamixType(methodTypeName, method);
|
|
468
|
-
fmxMethod.
|
|
469
|
-
fmxMethod.
|
|
533
|
+
fmxMethod.declaredType = fmxType;
|
|
534
|
+
fmxMethod.numberOfLinesOfCode = method.getEndLineNumber() - method.getStartLineNumber();
|
|
470
535
|
const parameters = method.getParameters();
|
|
471
|
-
fmxMethod.
|
|
536
|
+
fmxMethod.numberOfParameters = parameters.length;
|
|
472
537
|
if (!isSignature) {
|
|
473
|
-
fmxMethod.
|
|
538
|
+
fmxMethod.numberOfStatements = method.getStatements().length;
|
|
474
539
|
}
|
|
475
540
|
else {
|
|
476
|
-
fmxMethod.
|
|
541
|
+
fmxMethod.numberOfStatements = 0;
|
|
477
542
|
}
|
|
543
|
+
initFQN(method, fmxMethod);
|
|
478
544
|
this.makeFamixIndexFileAnchor(method, fmxMethod);
|
|
479
545
|
this.fmxFunctionAndMethodMap.set(functionFullyQualifiedName, fmxMethod);
|
|
480
546
|
}
|
|
@@ -501,15 +567,16 @@ class EntityDictionary {
|
|
|
501
567
|
else {
|
|
502
568
|
fmxFunction = new Famix.Function();
|
|
503
569
|
}
|
|
504
|
-
|
|
505
|
-
|
|
570
|
+
const name = func.getName();
|
|
571
|
+
if (name) {
|
|
572
|
+
fmxFunction.name = name;
|
|
506
573
|
}
|
|
507
574
|
else {
|
|
508
|
-
fmxFunction.
|
|
575
|
+
fmxFunction.name = "anonymous";
|
|
509
576
|
}
|
|
510
|
-
fmxFunction.
|
|
511
|
-
fmxFunction.
|
|
512
|
-
fmxFunction.
|
|
577
|
+
fmxFunction.signature = Helpers.computeSignature(func.getText());
|
|
578
|
+
fmxFunction.cyclomaticComplexity = currentCC[fmxFunction.name];
|
|
579
|
+
fmxFunction.fullyQualifiedName = functionFullyQualifiedName;
|
|
513
580
|
let functionTypeName = this.UNKNOWN_VALUE;
|
|
514
581
|
try {
|
|
515
582
|
functionTypeName = func.getReturnType().getText().trim();
|
|
@@ -518,11 +585,11 @@ class EntityDictionary {
|
|
|
518
585
|
analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for return type of function: ${func.getName()}. Continuing...`);
|
|
519
586
|
}
|
|
520
587
|
const fmxType = this.createOrGetFamixType(functionTypeName, func);
|
|
521
|
-
fmxFunction.
|
|
522
|
-
fmxFunction.
|
|
588
|
+
fmxFunction.declaredType = fmxType;
|
|
589
|
+
fmxFunction.numberOfLinesOfCode = func.getEndLineNumber() - func.getStartLineNumber();
|
|
523
590
|
const parameters = func.getParameters();
|
|
524
|
-
fmxFunction.
|
|
525
|
-
fmxFunction.
|
|
591
|
+
fmxFunction.numberOfParameters = parameters.length;
|
|
592
|
+
fmxFunction.numberOfStatements = func.getStatements().length;
|
|
526
593
|
this.makeFamixIndexFileAnchor(func, fmxFunction);
|
|
527
594
|
this.famixRep.addElement(fmxFunction);
|
|
528
595
|
this.fmxElementObjectMap.set(fmxFunction, func);
|
|
@@ -548,8 +615,9 @@ class EntityDictionary {
|
|
|
548
615
|
analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for parameter: ${param.getName()}. Continuing...`);
|
|
549
616
|
}
|
|
550
617
|
const fmxType = this.createOrGetFamixType(paramTypeName, param);
|
|
551
|
-
fmxParam.
|
|
552
|
-
fmxParam.
|
|
618
|
+
fmxParam.declaredType = fmxType;
|
|
619
|
+
fmxParam.name = param.getName();
|
|
620
|
+
initFQN(param, fmxParam);
|
|
553
621
|
this.makeFamixIndexFileAnchor(param, fmxParam);
|
|
554
622
|
this.famixRep.addElement(fmxParam);
|
|
555
623
|
this.fmxElementObjectMap.set(fmxParam, param);
|
|
@@ -562,7 +630,8 @@ class EntityDictionary {
|
|
|
562
630
|
*/
|
|
563
631
|
createFamixParameterType(tp) {
|
|
564
632
|
const fmxParameterType = new Famix.ParameterType();
|
|
565
|
-
fmxParameterType.
|
|
633
|
+
fmxParameterType.name = tp.getName();
|
|
634
|
+
initFQN(tp, fmxParameterType);
|
|
566
635
|
this.makeFamixIndexFileAnchor(tp, fmxParameterType);
|
|
567
636
|
this.famixRep.addElement(fmxParameterType);
|
|
568
637
|
this.fmxElementObjectMap.set(fmxParameterType, tp);
|
|
@@ -576,12 +645,12 @@ class EntityDictionary {
|
|
|
576
645
|
createOrGetFamixConcreteType(param) {
|
|
577
646
|
const typeParameterDeclaration = param.getSymbol()?.getDeclarations()[0];
|
|
578
647
|
const parameterTypeName = param.getText();
|
|
579
|
-
let fmxParameterType;
|
|
648
|
+
let fmxParameterType = undefined;
|
|
580
649
|
let isClassOrInterface = false;
|
|
581
650
|
if (this.fmxClassMap.has(parameterTypeName)) {
|
|
582
651
|
this.fmxClassMap.forEach((obj, name) => {
|
|
583
652
|
if (obj instanceof Famix.ParametricClass) {
|
|
584
|
-
if (name === param.getText() && obj.
|
|
653
|
+
if (name === param.getText() && obj.genericParameters.size > 0) {
|
|
585
654
|
fmxParameterType = obj;
|
|
586
655
|
isClassOrInterface = true;
|
|
587
656
|
}
|
|
@@ -597,7 +666,7 @@ class EntityDictionary {
|
|
|
597
666
|
if (this.fmxInterfaceMap.has(parameterTypeName)) {
|
|
598
667
|
this.fmxInterfaceMap.forEach((obj, name) => {
|
|
599
668
|
if (obj instanceof Famix.ParametricInterface) {
|
|
600
|
-
if (name === param.getText() && obj.
|
|
669
|
+
if (name === param.getText() && obj.genericParameters.size > 0) {
|
|
601
670
|
fmxParameterType = obj;
|
|
602
671
|
isClassOrInterface = true;
|
|
603
672
|
}
|
|
@@ -614,20 +683,29 @@ class EntityDictionary {
|
|
|
614
683
|
if (!this.fmxTypeMap.has(parameterTypeName)) {
|
|
615
684
|
if (parameterTypeName === "number" || parameterTypeName === "string" || parameterTypeName === "boolean" || parameterTypeName === "bigint" || parameterTypeName === "symbol" || parameterTypeName === "undefined" || parameterTypeName === "null" || parameterTypeName === "any" || parameterTypeName === "unknown" || parameterTypeName === "never" || parameterTypeName === "void") {
|
|
616
685
|
fmxParameterType = new Famix.PrimitiveType();
|
|
617
|
-
fmxParameterType.
|
|
686
|
+
fmxParameterType.isStub = true;
|
|
618
687
|
}
|
|
619
688
|
else {
|
|
620
689
|
fmxParameterType = new Famix.ParameterType();
|
|
621
690
|
}
|
|
622
|
-
fmxParameterType.
|
|
691
|
+
fmxParameterType.name = parameterTypeName;
|
|
623
692
|
this.famixRep.addElement(fmxParameterType);
|
|
624
693
|
this.fmxTypeMap.set(parameterTypeName, fmxParameterType);
|
|
625
694
|
this.fmxElementObjectMap.set(fmxParameterType, typeParameterDeclaration);
|
|
626
695
|
}
|
|
627
696
|
else {
|
|
628
|
-
|
|
697
|
+
const result = this.fmxTypeMap.get(parameterTypeName);
|
|
698
|
+
if (result) {
|
|
699
|
+
fmxParameterType = result;
|
|
700
|
+
}
|
|
701
|
+
else {
|
|
702
|
+
throw new Error(`Famix type ${parameterTypeName} is not found in the Type map.`);
|
|
703
|
+
}
|
|
629
704
|
}
|
|
630
705
|
}
|
|
706
|
+
if (!fmxParameterType) {
|
|
707
|
+
throw new Error(`fmxParameterType was undefined for parameterTypeName ${parameterTypeName}`);
|
|
708
|
+
}
|
|
631
709
|
return fmxParameterType;
|
|
632
710
|
}
|
|
633
711
|
/**
|
|
@@ -645,8 +723,9 @@ class EntityDictionary {
|
|
|
645
723
|
analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for variable: ${variable.getName()}. Continuing...`);
|
|
646
724
|
}
|
|
647
725
|
const fmxType = this.createOrGetFamixType(variableTypeName, variable);
|
|
648
|
-
fmxVariable.
|
|
649
|
-
fmxVariable.
|
|
726
|
+
fmxVariable.declaredType = fmxType;
|
|
727
|
+
fmxVariable.name = variable.getName();
|
|
728
|
+
initFQN(variable, fmxVariable);
|
|
650
729
|
this.makeFamixIndexFileAnchor(variable, fmxVariable);
|
|
651
730
|
this.famixRep.addElement(fmxVariable);
|
|
652
731
|
this.fmxElementObjectMap.set(fmxVariable, variable);
|
|
@@ -659,7 +738,8 @@ class EntityDictionary {
|
|
|
659
738
|
*/
|
|
660
739
|
createFamixEnum(enumEntity) {
|
|
661
740
|
const fmxEnum = new Famix.Enum();
|
|
662
|
-
fmxEnum.
|
|
741
|
+
fmxEnum.name = enumEntity.getName();
|
|
742
|
+
initFQN(enumEntity, fmxEnum);
|
|
663
743
|
this.makeFamixIndexFileAnchor(enumEntity, fmxEnum);
|
|
664
744
|
this.famixRep.addElement(fmxEnum);
|
|
665
745
|
this.fmxElementObjectMap.set(fmxEnum, enumEntity);
|
|
@@ -680,8 +760,9 @@ class EntityDictionary {
|
|
|
680
760
|
analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for enum value: ${enumMember.getName()}. Continuing...`);
|
|
681
761
|
}
|
|
682
762
|
const fmxType = this.createOrGetFamixType(enumValueTypeName, enumMember);
|
|
683
|
-
fmxEnumValue.
|
|
684
|
-
fmxEnumValue.
|
|
763
|
+
fmxEnumValue.declaredType = fmxType;
|
|
764
|
+
fmxEnumValue.name = enumMember.getName();
|
|
765
|
+
initFQN(enumMember, fmxEnumValue);
|
|
685
766
|
this.makeFamixIndexFileAnchor(enumMember, fmxEnumValue);
|
|
686
767
|
this.famixRep.addElement(fmxEnumValue);
|
|
687
768
|
this.fmxElementObjectMap.set(fmxEnumValue, enumMember);
|
|
@@ -697,11 +778,12 @@ class EntityDictionary {
|
|
|
697
778
|
const fmxDecorator = new Famix.Decorator();
|
|
698
779
|
const decoratorName = "@" + decorator.getName();
|
|
699
780
|
const decoratorExpression = decorator.getText().substring(1);
|
|
700
|
-
fmxDecorator.
|
|
701
|
-
fmxDecorator.
|
|
781
|
+
fmxDecorator.name = decoratorName;
|
|
782
|
+
fmxDecorator.decoratorExpression = decoratorExpression;
|
|
702
783
|
const decoratedEntityFullyQualifiedName = FQNFunctions.getFQN(decoratedEntity);
|
|
703
784
|
const fmxDecoratedEntity = this.famixRep.getFamixEntityByFullyQualifiedName(decoratedEntityFullyQualifiedName);
|
|
704
|
-
fmxDecorator.
|
|
785
|
+
fmxDecorator.decoratedEntity = fmxDecoratedEntity;
|
|
786
|
+
initFQN(decorator, fmxDecorator);
|
|
705
787
|
this.makeFamixIndexFileAnchor(decorator, fmxDecorator);
|
|
706
788
|
this.famixRep.addElement(fmxDecorator);
|
|
707
789
|
this.fmxElementObjectMap.set(fmxDecorator, decorator);
|
|
@@ -715,10 +797,10 @@ class EntityDictionary {
|
|
|
715
797
|
* @returns The Famix model of the comment
|
|
716
798
|
*/
|
|
717
799
|
createFamixComment(comment, fmxScope, isJSDoc) {
|
|
718
|
-
analyze_1.logger.debug(`> NOTE: creating comment ${comment.getText()} in scope ${fmxScope.
|
|
800
|
+
analyze_1.logger.debug(`> NOTE: creating comment ${comment.getText()} in scope ${fmxScope.name}.`);
|
|
719
801
|
const fmxComment = new Famix.Comment();
|
|
720
|
-
fmxComment.
|
|
721
|
-
fmxComment.
|
|
802
|
+
fmxComment.container = fmxScope; // adds comment to the container's comments collection
|
|
803
|
+
fmxComment.isJSDoc = isJSDoc;
|
|
722
804
|
this.makeFamixIndexFileAnchor(comment, fmxComment);
|
|
723
805
|
this.famixRep.addElement(fmxComment);
|
|
724
806
|
this.fmxElementObjectMap.set(fmxComment, comment);
|
|
@@ -735,7 +817,7 @@ class EntityDictionary {
|
|
|
735
817
|
let isPrimitiveType = false;
|
|
736
818
|
let isParameterType = false;
|
|
737
819
|
analyze_1.logger.debug("Creating (or getting) type: '" + typeName + "' of element: " + element?.getText() + " of kind: " + element?.getKindName());
|
|
738
|
-
let ancestor;
|
|
820
|
+
let ancestor = undefined;
|
|
739
821
|
if (element !== undefined) {
|
|
740
822
|
const typeAncestor = Helpers.findTypeAncestor(element);
|
|
741
823
|
if (!typeAncestor) {
|
|
@@ -757,7 +839,7 @@ class EntityDictionary {
|
|
|
757
839
|
if (!this.fmxTypeMap.has(typeName)) {
|
|
758
840
|
if (isPrimitiveType) {
|
|
759
841
|
fmxType = new Famix.PrimitiveType();
|
|
760
|
-
fmxType.
|
|
842
|
+
fmxType.isStub = true;
|
|
761
843
|
}
|
|
762
844
|
else if (isParameterType) {
|
|
763
845
|
fmxType = new Famix.ParameterType();
|
|
@@ -768,19 +850,29 @@ class EntityDictionary {
|
|
|
768
850
|
fmxType.addArgument(fmxParameterType);
|
|
769
851
|
});
|
|
770
852
|
const fmxBaseType = this.createOrGetFamixType(baseTypeName, element);
|
|
771
|
-
fmxType.
|
|
853
|
+
fmxType.baseType = fmxBaseType;
|
|
772
854
|
}
|
|
773
855
|
else {
|
|
774
856
|
fmxType = new Famix.Type();
|
|
775
857
|
}
|
|
776
|
-
fmxType.
|
|
777
|
-
|
|
858
|
+
fmxType.name = typeName;
|
|
859
|
+
if (!ancestor) {
|
|
860
|
+
throw new Error(`Ancestor not found for type ${typeName}.`);
|
|
861
|
+
}
|
|
862
|
+
fmxType.container = ancestor;
|
|
863
|
+
initFQN(element, fmxType);
|
|
778
864
|
this.makeFamixIndexFileAnchor(element, fmxType);
|
|
779
865
|
this.famixRep.addElement(fmxType);
|
|
780
866
|
this.fmxTypeMap.set(typeName, fmxType);
|
|
781
867
|
}
|
|
782
868
|
else {
|
|
783
|
-
|
|
869
|
+
const result = this.fmxTypeMap.get(typeName);
|
|
870
|
+
if (result) {
|
|
871
|
+
fmxType = result;
|
|
872
|
+
}
|
|
873
|
+
else {
|
|
874
|
+
throw new Error(`Famix type ${typeName} is not found in the Type map.`);
|
|
875
|
+
}
|
|
784
876
|
}
|
|
785
877
|
this.fmxElementObjectMap.set(fmxType, element);
|
|
786
878
|
return fmxType;
|
|
@@ -795,7 +887,7 @@ class EntityDictionary {
|
|
|
795
887
|
if (!fmxVar) {
|
|
796
888
|
throw new Error(`Famix entity with id ${id} not found, for node ${node.getText()} in ${node.getSourceFile().getBaseName()} at line ${node.getStartLineNumber()}.`);
|
|
797
889
|
}
|
|
798
|
-
analyze_1.logger.debug(`Creating FamixAccess. Node: [${node.getKindName()}] '${node.getText()}' at line ${node.getStartLineNumber()} in ${node.getSourceFile().getBaseName()}, id: ${id} refers to fmxVar '${fmxVar.
|
|
890
|
+
analyze_1.logger.debug(`Creating FamixAccess. Node: [${node.getKindName()}] '${node.getText()}' at line ${node.getStartLineNumber()} in ${node.getSourceFile().getBaseName()}, id: ${id} refers to fmxVar '${fmxVar.fullyQualifiedName}'.`);
|
|
799
891
|
const nodeReferenceAncestor = Helpers.findAncestor(node);
|
|
800
892
|
const ancestorFullyQualifiedName = FQNFunctions.getFQN(nodeReferenceAncestor);
|
|
801
893
|
let accessor = this.famixRep.getFamixEntityByFullyQualifiedName(ancestorFullyQualifiedName);
|
|
@@ -804,8 +896,8 @@ class EntityDictionary {
|
|
|
804
896
|
// accessor = this.createOrGetFamixType(ancestorFullyQualifiedName, nodeReferenceAncestor as TypeDeclaration);
|
|
805
897
|
}
|
|
806
898
|
const fmxAccess = new Famix.Access();
|
|
807
|
-
fmxAccess.
|
|
808
|
-
fmxAccess.
|
|
899
|
+
fmxAccess.accessor = accessor;
|
|
900
|
+
fmxAccess.variable = fmxVar;
|
|
809
901
|
this.famixRep.addElement(fmxAccess);
|
|
810
902
|
this.fmxElementObjectMap.set(fmxAccess, node);
|
|
811
903
|
}
|
|
@@ -823,10 +915,10 @@ class EntityDictionary {
|
|
|
823
915
|
const receiverFullyQualifiedName = FQNFunctions.getFQN(m.getParent());
|
|
824
916
|
const receiver = this.famixRep.getFamixEntityByFullyQualifiedName(receiverFullyQualifiedName);
|
|
825
917
|
const fmxInvocation = new Famix.Invocation();
|
|
826
|
-
fmxInvocation.
|
|
827
|
-
fmxInvocation.
|
|
918
|
+
fmxInvocation.sender = sender;
|
|
919
|
+
fmxInvocation.receiver = receiver;
|
|
828
920
|
fmxInvocation.addCandidate(fmxMethodOrFunction);
|
|
829
|
-
fmxInvocation.
|
|
921
|
+
fmxInvocation.signature = fmxMethodOrFunction.signature;
|
|
830
922
|
this.famixRep.addElement(fmxInvocation);
|
|
831
923
|
this.fmxElementObjectMap.set(fmxInvocation, node);
|
|
832
924
|
}
|
|
@@ -847,11 +939,17 @@ class EntityDictionary {
|
|
|
847
939
|
else {
|
|
848
940
|
subClass = this.fmxInterfaceMap.get(classFullyQualifiedName);
|
|
849
941
|
}
|
|
942
|
+
if (!subClass) {
|
|
943
|
+
throw new Error(`Subclass ${classFullyQualifiedName} not found in Class or Interface maps.`);
|
|
944
|
+
}
|
|
850
945
|
let inhClassName;
|
|
851
946
|
let inhClassFullyQualifiedName;
|
|
852
947
|
let superClass;
|
|
853
948
|
if (inhClass instanceof ts_morph_1.ClassDeclaration || inhClass instanceof ts_morph_1.InterfaceDeclaration) {
|
|
854
949
|
inhClassName = inhClass.getName();
|
|
950
|
+
if (!inhClassName) {
|
|
951
|
+
throw new Error(`Inherited class or interface name not found for ${inhClass.getText()}.`);
|
|
952
|
+
}
|
|
855
953
|
inhClassFullyQualifiedName = FQNFunctions.getFQN(inhClass);
|
|
856
954
|
if (inhClass instanceof ts_morph_1.ClassDeclaration) {
|
|
857
955
|
superClass = this.fmxClassMap.get(inhClassFullyQualifiedName);
|
|
@@ -859,6 +957,9 @@ class EntityDictionary {
|
|
|
859
957
|
else {
|
|
860
958
|
superClass = this.fmxInterfaceMap.get(inhClassFullyQualifiedName);
|
|
861
959
|
}
|
|
960
|
+
if (!superClass) {
|
|
961
|
+
throw new Error(`Superclass ${classFullyQualifiedName} not found in Class or Interface maps.`);
|
|
962
|
+
}
|
|
862
963
|
}
|
|
863
964
|
else {
|
|
864
965
|
// inhClass is an ExpressionWithTypeArguments
|
|
@@ -876,21 +977,22 @@ class EntityDictionary {
|
|
|
876
977
|
this.fmxInterfaceMap.set(inhClassFullyQualifiedName, superClass);
|
|
877
978
|
}
|
|
878
979
|
this.fmxElementObjectMap.set(superClass, inhClass);
|
|
879
|
-
superClass.
|
|
880
|
-
superClass.
|
|
881
|
-
superClass.
|
|
980
|
+
superClass.name = inhClassName;
|
|
981
|
+
superClass.fullyQualifiedName = inhClassFullyQualifiedName;
|
|
982
|
+
superClass.isStub = true;
|
|
882
983
|
this.makeFamixIndexFileAnchor(inhClass, superClass);
|
|
883
984
|
this.famixRep.addElement(superClass);
|
|
884
985
|
}
|
|
885
|
-
fmxInheritance.
|
|
886
|
-
fmxInheritance.
|
|
986
|
+
fmxInheritance.subclass = subClass;
|
|
987
|
+
fmxInheritance.superclass = superClass;
|
|
887
988
|
this.famixRep.addElement(fmxInheritance);
|
|
888
|
-
|
|
989
|
+
// We don't map inheritance to the source code element because there are two elements (super, sub)
|
|
990
|
+
// this.fmxElementObjectMap.set(fmxInheritance, null);
|
|
889
991
|
}
|
|
890
992
|
createFamixImportClause(importedEntity, importingEntity) {
|
|
891
993
|
const fmxImportClause = new Famix.ImportClause();
|
|
892
|
-
fmxImportClause.
|
|
893
|
-
fmxImportClause.
|
|
994
|
+
fmxImportClause.importedEntity = importedEntity;
|
|
995
|
+
fmxImportClause.importingEntity = importingEntity;
|
|
894
996
|
importingEntity.addOutgoingImport(fmxImportClause);
|
|
895
997
|
this.famixRep.addElement(fmxImportClause);
|
|
896
998
|
}
|
|
@@ -908,7 +1010,7 @@ class EntityDictionary {
|
|
|
908
1010
|
const { importDeclaration, importerSourceFile: importer, moduleSpecifierFilePath, importElement, isInExports, isDefaultExport } = importClauseInfo;
|
|
909
1011
|
analyze_1.logger.debug(`createFamixImportClause: Creating import clause:`);
|
|
910
1012
|
const fmxImportClause = new Famix.ImportClause();
|
|
911
|
-
let importedEntity;
|
|
1013
|
+
let importedEntity = undefined;
|
|
912
1014
|
let importedEntityName;
|
|
913
1015
|
const absolutePathProject = this.famixRep.getAbsolutePath();
|
|
914
1016
|
const absolutePath = path_1.default.normalize(moduleSpecifierFilePath);
|
|
@@ -926,12 +1028,12 @@ class EntityDictionary {
|
|
|
926
1028
|
}
|
|
927
1029
|
if (importedEntity === undefined) {
|
|
928
1030
|
importedEntity = new Famix.NamedEntity();
|
|
929
|
-
importedEntity.
|
|
1031
|
+
importedEntity.name = importedEntityName;
|
|
930
1032
|
if (!isInExports) {
|
|
931
|
-
importedEntity.
|
|
1033
|
+
importedEntity.isStub = true;
|
|
932
1034
|
}
|
|
1035
|
+
importedEntity.fullyQualifiedName = pathName;
|
|
933
1036
|
this.makeFamixIndexFileAnchor(importElement, importedEntity);
|
|
934
|
-
importedEntity.setFullyQualifiedName(pathName);
|
|
935
1037
|
// must add entity to repository
|
|
936
1038
|
this.famixRep.addElement(importedEntity);
|
|
937
1039
|
}
|
|
@@ -942,37 +1044,39 @@ class EntityDictionary {
|
|
|
942
1044
|
importedEntityName = importDeclaration?.getName();
|
|
943
1045
|
pathName = pathName + importedEntityName;
|
|
944
1046
|
importedEntity = new Famix.StructuralEntity();
|
|
945
|
-
importedEntity.
|
|
1047
|
+
importedEntity.name = importedEntityName;
|
|
1048
|
+
initFQN(importDeclaration, importedEntity);
|
|
946
1049
|
this.makeFamixIndexFileAnchor(importElement, importedEntity);
|
|
947
|
-
importedEntity.
|
|
948
|
-
const anyType = this.createOrGetFamixType('any',
|
|
949
|
-
importedEntity.
|
|
1050
|
+
importedEntity.fullyQualifiedName = pathName;
|
|
1051
|
+
const anyType = this.createOrGetFamixType('any', importDeclaration);
|
|
1052
|
+
importedEntity.declaredType = anyType;
|
|
950
1053
|
}
|
|
951
1054
|
else { // default imports, e.g. import ClassW from "./complexExportModule";
|
|
952
1055
|
importedEntityName = importElement.getText();
|
|
953
1056
|
pathName = pathName + (isDefaultExport ? "defaultExport" : "namespaceExport");
|
|
954
1057
|
importedEntity = new Famix.NamedEntity();
|
|
955
|
-
importedEntity.
|
|
1058
|
+
importedEntity.name = importedEntityName;
|
|
1059
|
+
importedEntity.fullyQualifiedName = pathName;
|
|
956
1060
|
this.makeFamixIndexFileAnchor(importElement, importedEntity);
|
|
957
|
-
importedEntity.setFullyQualifiedName(pathName);
|
|
958
1061
|
}
|
|
959
1062
|
// I don't think it should be added to the repository if it exists already
|
|
960
1063
|
if (!isInExports)
|
|
961
1064
|
this.famixRep.addElement(importedEntity);
|
|
962
1065
|
const importerFullyQualifiedName = FQNFunctions.getFQN(importer);
|
|
963
1066
|
const fmxImporter = this.famixRep.getFamixEntityByFullyQualifiedName(importerFullyQualifiedName);
|
|
964
|
-
fmxImportClause.
|
|
965
|
-
fmxImportClause.
|
|
1067
|
+
fmxImportClause.importingEntity = fmxImporter;
|
|
1068
|
+
fmxImportClause.importedEntity = importedEntity;
|
|
966
1069
|
if (importDeclaration instanceof ts_morph_1.ImportEqualsDeclaration) {
|
|
967
|
-
fmxImportClause.
|
|
1070
|
+
fmxImportClause.moduleSpecifier = importDeclaration?.getModuleReference().getText();
|
|
968
1071
|
}
|
|
969
1072
|
else {
|
|
970
|
-
fmxImportClause.
|
|
1073
|
+
fmxImportClause.moduleSpecifier = importDeclaration?.getModuleSpecifierValue();
|
|
971
1074
|
}
|
|
972
|
-
analyze_1.logger.debug(`createFamixImportClause: ${fmxImportClause.
|
|
1075
|
+
analyze_1.logger.debug(`createFamixImportClause: ${fmxImportClause.importedEntity?.name} (of type ${Helpers.getSubTypeName(fmxImportClause.importedEntity)}) is imported by ${fmxImportClause.importingEntity?.name}`);
|
|
973
1076
|
fmxImporter.addOutgoingImport(fmxImportClause);
|
|
974
1077
|
this.famixRep.addElement(fmxImportClause);
|
|
975
|
-
|
|
1078
|
+
if (importDeclaration)
|
|
1079
|
+
this.fmxElementObjectMap.set(fmxImportClause, importDeclaration);
|
|
976
1080
|
}
|
|
977
1081
|
/**
|
|
978
1082
|
* Creates a Famix Arrow Function
|
|
@@ -997,16 +1101,16 @@ class EntityDictionary {
|
|
|
997
1101
|
functionName = parent.getName();
|
|
998
1102
|
}
|
|
999
1103
|
if (functionName) {
|
|
1000
|
-
fmxArrowFunction.
|
|
1104
|
+
fmxArrowFunction.name = functionName;
|
|
1001
1105
|
}
|
|
1002
1106
|
else {
|
|
1003
|
-
fmxArrowFunction.
|
|
1107
|
+
fmxArrowFunction.name = "anonymous";
|
|
1004
1108
|
}
|
|
1005
1109
|
// Signature of an arrow function is (parameters) => return_type
|
|
1006
1110
|
const parametersSignature = arrowFunction.getParameters().map(p => p.getText()).join(", ");
|
|
1007
1111
|
const returnTypeSignature = arrowFunction.getReturnType().getText();
|
|
1008
|
-
fmxArrowFunction.
|
|
1009
|
-
fmxArrowFunction.
|
|
1112
|
+
fmxArrowFunction.signature = `(${parametersSignature}) => ${returnTypeSignature}`;
|
|
1113
|
+
fmxArrowFunction.cyclomaticComplexity = currentCC[fmxArrowFunction.name];
|
|
1010
1114
|
let functionTypeName = this.UNKNOWN_VALUE;
|
|
1011
1115
|
try {
|
|
1012
1116
|
functionTypeName = arrowFunction.getReturnType().getText().trim();
|
|
@@ -1015,11 +1119,12 @@ class EntityDictionary {
|
|
|
1015
1119
|
analyze_1.logger.error(`> WARNING: got exception ${error}. Failed to get usable name for return type of function: ${functionName}. Continuing...`);
|
|
1016
1120
|
}
|
|
1017
1121
|
const fmxType = this.createOrGetFamixType(functionTypeName, arrowFunction);
|
|
1018
|
-
fmxArrowFunction.
|
|
1019
|
-
fmxArrowFunction.
|
|
1122
|
+
fmxArrowFunction.declaredType = fmxType;
|
|
1123
|
+
fmxArrowFunction.numberOfLinesOfCode = arrowFunction.getEndLineNumber() - arrowFunction.getStartLineNumber();
|
|
1020
1124
|
const parameters = arrowFunction.getParameters();
|
|
1021
|
-
fmxArrowFunction.
|
|
1022
|
-
fmxArrowFunction.
|
|
1125
|
+
fmxArrowFunction.numberOfParameters = parameters.length;
|
|
1126
|
+
fmxArrowFunction.numberOfStatements = arrowFunction.getStatements().length;
|
|
1127
|
+
initFQN(arrowExpression, fmxArrowFunction);
|
|
1023
1128
|
this.makeFamixIndexFileAnchor(arrowExpression, fmxArrowFunction);
|
|
1024
1129
|
this.famixRep.addElement(fmxArrowFunction);
|
|
1025
1130
|
this.fmxElementObjectMap.set(fmxArrowFunction, arrowFunction);
|
|
@@ -1032,11 +1137,11 @@ class EntityDictionary {
|
|
|
1032
1137
|
*/
|
|
1033
1138
|
createFamixConcretisation(conEntity, genEntity) {
|
|
1034
1139
|
const fmxConcretisation = new Famix.Concretisation();
|
|
1035
|
-
fmxConcretisation.
|
|
1036
|
-
fmxConcretisation.
|
|
1037
|
-
this.fmxElementObjectMap.set(fmxConcretisation,
|
|
1140
|
+
fmxConcretisation.concreteEntity = conEntity;
|
|
1141
|
+
fmxConcretisation.genericEntity = genEntity;
|
|
1142
|
+
// this.fmxElementObjectMap.set(fmxConcretisation,null);
|
|
1038
1143
|
this.famixRep.addElement(fmxConcretisation);
|
|
1039
|
-
const parameterConcretisation = this.
|
|
1144
|
+
const parameterConcretisation = this.createFamixParameterConcretisation(fmxConcretisation);
|
|
1040
1145
|
return fmxConcretisation;
|
|
1041
1146
|
}
|
|
1042
1147
|
/**
|
|
@@ -1044,39 +1149,46 @@ class EntityDictionary {
|
|
|
1044
1149
|
* @param concretisation A FamixConcretisation
|
|
1045
1150
|
* @returns The Famix model of the ParameterConcrestisation
|
|
1046
1151
|
*/
|
|
1047
|
-
|
|
1048
|
-
const conClass = concretisation.
|
|
1049
|
-
const genClass = concretisation.
|
|
1152
|
+
createFamixParameterConcretisation(concretisation) {
|
|
1153
|
+
const conClass = concretisation.concreteEntity;
|
|
1154
|
+
const genClass = concretisation.genericEntity;
|
|
1155
|
+
analyze_1.logger.debug(`Creating parameter concretisation between ${conClass.fullyQualifiedName} and ${genClass.fullyQualifiedName}`);
|
|
1050
1156
|
const parameterConcretisations = this.famixRep._getAllEntitiesWithType("ParameterConcretisation");
|
|
1051
|
-
const concreteParameters = conClass.
|
|
1052
|
-
const genericParameters = genClass.
|
|
1157
|
+
const concreteParameters = conClass.concreteParameters;
|
|
1158
|
+
const genericParameters = genClass.genericParameters;
|
|
1053
1159
|
let conClassTypeParametersIterator = concreteParameters.values();
|
|
1054
1160
|
let genClassTypeParametersIterator = genericParameters.values();
|
|
1055
|
-
let fmxParameterConcretisation;
|
|
1161
|
+
let fmxParameterConcretisation = undefined;
|
|
1056
1162
|
for (let i = 0; i < genericParameters.size; i++) {
|
|
1057
1163
|
const conClassTypeParameter = conClassTypeParametersIterator.next().value;
|
|
1058
1164
|
const genClassTypeParameter = genClassTypeParametersIterator.next().value;
|
|
1059
1165
|
let createParameterConcretisation = true;
|
|
1060
|
-
if (conClassTypeParameter && genClassTypeParameter && conClassTypeParameter.
|
|
1166
|
+
if (conClassTypeParameter && genClassTypeParameter && conClassTypeParameter.name != genClassTypeParameter.name) {
|
|
1061
1167
|
parameterConcretisations.forEach((param) => {
|
|
1062
|
-
if (conClassTypeParameter.
|
|
1168
|
+
if (conClassTypeParameter.name == param.concreteParameter.name && genClassTypeParameter.name == param.genericParameter.name) {
|
|
1063
1169
|
createParameterConcretisation = false;
|
|
1064
1170
|
fmxParameterConcretisation = param;
|
|
1065
1171
|
}
|
|
1066
1172
|
});
|
|
1067
1173
|
if (createParameterConcretisation) {
|
|
1068
1174
|
fmxParameterConcretisation = new Famix.ParameterConcretisation();
|
|
1069
|
-
fmxParameterConcretisation.
|
|
1070
|
-
fmxParameterConcretisation.
|
|
1175
|
+
fmxParameterConcretisation.genericParameter = genClassTypeParameter;
|
|
1176
|
+
fmxParameterConcretisation.concreteParameter = conClassTypeParameter;
|
|
1071
1177
|
fmxParameterConcretisation.addConcretisation(concretisation);
|
|
1072
|
-
this.fmxElementObjectMap.set(fmxParameterConcretisation,
|
|
1178
|
+
// this.fmxElementObjectMap.set(fmxParameterConcretisation,null);
|
|
1073
1179
|
}
|
|
1074
1180
|
else {
|
|
1181
|
+
if (!fmxParameterConcretisation) {
|
|
1182
|
+
throw new Error(`fmxParameterConcretisation was undefined for concretisation with generic parameter ${genClassTypeParameter.name} and concrete parameter ${conClassTypeParameter.name}`);
|
|
1183
|
+
}
|
|
1075
1184
|
fmxParameterConcretisation.addConcretisation(concretisation);
|
|
1076
1185
|
}
|
|
1077
1186
|
this.famixRep.addElement(fmxParameterConcretisation);
|
|
1078
1187
|
}
|
|
1079
1188
|
}
|
|
1189
|
+
if (!fmxParameterConcretisation) {
|
|
1190
|
+
analyze_1.logger.error(`fmxParameterConcretisation was undefined for concretisation with concrete entity ${conClass.fullyQualifiedName} and generic entity ${genClass.fullyQualifiedName}`);
|
|
1191
|
+
}
|
|
1080
1192
|
return fmxParameterConcretisation;
|
|
1081
1193
|
}
|
|
1082
1194
|
/**
|
|
@@ -1107,11 +1219,11 @@ class EntityDictionary {
|
|
|
1107
1219
|
let EntityDeclaration;
|
|
1108
1220
|
let genEntity;
|
|
1109
1221
|
if (superEntity instanceof ts_morph_1.ExpressionWithTypeArguments) {
|
|
1110
|
-
EntityDeclaration = entity.getExpression().getSymbol()
|
|
1222
|
+
EntityDeclaration = entity.getExpression().getSymbol()?.getDeclarations()[0];
|
|
1111
1223
|
genEntity = this.createOrGetFamixClass(EntityDeclaration);
|
|
1112
1224
|
}
|
|
1113
1225
|
else {
|
|
1114
|
-
EntityDeclaration = entity.getExpression().getSymbol()
|
|
1226
|
+
EntityDeclaration = entity.getExpression().getSymbol()?.getDeclarations()[0];
|
|
1115
1227
|
genEntity = this.createOrGetFamixInterface(EntityDeclaration);
|
|
1116
1228
|
}
|
|
1117
1229
|
const genParams = EntityDeclaration.getTypeParameters().map((param) => param.getText());
|
|
@@ -1123,7 +1235,7 @@ class EntityDictionary {
|
|
|
1123
1235
|
const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
|
|
1124
1236
|
let createConcretisation = true;
|
|
1125
1237
|
concretisations.forEach((conc) => {
|
|
1126
|
-
if (genEntity.
|
|
1238
|
+
if (genEntity.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == conEntity.fullyQualifiedName) {
|
|
1127
1239
|
createConcretisation = false;
|
|
1128
1240
|
}
|
|
1129
1241
|
});
|
|
@@ -1134,6 +1246,7 @@ class EntityDictionary {
|
|
|
1134
1246
|
}
|
|
1135
1247
|
});
|
|
1136
1248
|
}
|
|
1249
|
+
// TODO: This function seems unfinished
|
|
1137
1250
|
}
|
|
1138
1251
|
/**
|
|
1139
1252
|
* Creates a Famix concretisation between a class and its instanciations
|
|
@@ -1159,7 +1272,7 @@ class EntityDictionary {
|
|
|
1159
1272
|
const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
|
|
1160
1273
|
let createConcretisation = true;
|
|
1161
1274
|
concretisations.forEach((conc) => {
|
|
1162
|
-
if (genEntity.
|
|
1275
|
+
if (genEntity.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == conEntity.fullyQualifiedName) {
|
|
1163
1276
|
createConcretisation = false;
|
|
1164
1277
|
}
|
|
1165
1278
|
});
|
|
@@ -1170,6 +1283,7 @@ class EntityDictionary {
|
|
|
1170
1283
|
}
|
|
1171
1284
|
});
|
|
1172
1285
|
}
|
|
1286
|
+
// TODO: This function seems unfinished
|
|
1173
1287
|
}
|
|
1174
1288
|
/**
|
|
1175
1289
|
* Creates a Famix concretisation between a class and its instanciations
|
|
@@ -1185,6 +1299,9 @@ class EntityDictionary {
|
|
|
1185
1299
|
while (currentNode) {
|
|
1186
1300
|
if (currentNode.getKind() === ts_morph_1.SyntaxKind.CallExpression) {
|
|
1187
1301
|
const callExpression = currentNode.asKind(ts_morph_1.SyntaxKind.CallExpression);
|
|
1302
|
+
if (!callExpression) {
|
|
1303
|
+
throw new Error(`CallExpression not found for ${currentNode.getText()}`);
|
|
1304
|
+
}
|
|
1188
1305
|
const instanceIsGeneric = callExpression.getTypeArguments().length > 0;
|
|
1189
1306
|
if (instanceIsGeneric) {
|
|
1190
1307
|
const args = callExpression.getTypeArguments();
|
|
@@ -1192,17 +1309,17 @@ class EntityDictionary {
|
|
|
1192
1309
|
if (!Helpers.arraysAreEqual(conParams, genParams)) {
|
|
1193
1310
|
let genElement;
|
|
1194
1311
|
if (element instanceof ts_morph_1.FunctionDeclaration) {
|
|
1195
|
-
genElement = this.createOrGetFamixFunction(element,
|
|
1312
|
+
genElement = this.createOrGetFamixFunction(element, {});
|
|
1196
1313
|
}
|
|
1197
1314
|
else {
|
|
1198
|
-
genElement = this.createOrGetFamixMethod(element,
|
|
1315
|
+
genElement = this.createOrGetFamixMethod(element, {});
|
|
1199
1316
|
}
|
|
1200
1317
|
let concElement;
|
|
1201
1318
|
concElement = this.createOrGetFamixConcreteElement(genElement, element, args);
|
|
1202
1319
|
const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
|
|
1203
1320
|
let createConcretisation = true;
|
|
1204
1321
|
concretisations.forEach((conc) => {
|
|
1205
|
-
if (genElement.
|
|
1322
|
+
if (genElement.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == concElement.fullyQualifiedName) {
|
|
1206
1323
|
createConcretisation = false;
|
|
1207
1324
|
}
|
|
1208
1325
|
});
|
|
@@ -1228,7 +1345,7 @@ class EntityDictionary {
|
|
|
1228
1345
|
superInterfaces.forEach(interfaceType => {
|
|
1229
1346
|
const interfaceIsGeneric = interfaceType.getTypeArguments().length > 0;
|
|
1230
1347
|
if (interfaceIsGeneric) {
|
|
1231
|
-
const interfaceDeclaration = interfaceType.getExpression().getSymbol()
|
|
1348
|
+
const interfaceDeclaration = interfaceType.getExpression().getSymbol()?.getDeclarations()[0];
|
|
1232
1349
|
const genParams = interfaceDeclaration.getTypeParameters().map((param) => param.getText());
|
|
1233
1350
|
const conParams = cls.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments().map((param) => param.getText());
|
|
1234
1351
|
const args = cls.getHeritageClauses()[0].getTypeNodes()[0].getTypeArguments();
|
|
@@ -1238,7 +1355,7 @@ class EntityDictionary {
|
|
|
1238
1355
|
const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
|
|
1239
1356
|
let createConcretisation = true;
|
|
1240
1357
|
concretisations.forEach((conc) => {
|
|
1241
|
-
if (genInterface.
|
|
1358
|
+
if (genInterface.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == conInterface.fullyQualifiedName) {
|
|
1242
1359
|
createConcretisation = false;
|
|
1243
1360
|
}
|
|
1244
1361
|
});
|
|
@@ -1264,6 +1381,9 @@ class EntityDictionary {
|
|
|
1264
1381
|
while (parentNode) {
|
|
1265
1382
|
if (parentNode.getKind() === ts_morph_1.SyntaxKind.TypeReference) {
|
|
1266
1383
|
const typeReferenceNode = parentNode.asKind(ts_morph_1.SyntaxKind.TypeReference);
|
|
1384
|
+
if (!typeReferenceNode) {
|
|
1385
|
+
throw new Error(`TypeReferenceNode not found for ${parentNode.getText()}`);
|
|
1386
|
+
}
|
|
1267
1387
|
const typeReferenceNodeIsGeneric = typeReferenceNode.getTypeArguments().length > 0;
|
|
1268
1388
|
if (typeReferenceNodeIsGeneric) { }
|
|
1269
1389
|
const args = typeReferenceNode.getTypeArguments();
|
|
@@ -1281,7 +1401,7 @@ class EntityDictionary {
|
|
|
1281
1401
|
const concretisations = this.famixRep._getAllEntitiesWithType("Concretisation");
|
|
1282
1402
|
let createConcretisation = true;
|
|
1283
1403
|
concretisations.forEach((conc) => {
|
|
1284
|
-
if (genElement.
|
|
1404
|
+
if (genElement.fullyQualifiedName == conc.genericEntity.fullyQualifiedName && conc.concreteEntity.fullyQualifiedName == concElement.fullyQualifiedName) {
|
|
1285
1405
|
createConcretisation = false;
|
|
1286
1406
|
}
|
|
1287
1407
|
});
|
|
@@ -1301,4 +1421,11 @@ class EntityDictionary {
|
|
|
1301
1421
|
}
|
|
1302
1422
|
}
|
|
1303
1423
|
exports.EntityDictionary = EntityDictionary;
|
|
1304
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW50aXR5RGljdGlvbmFyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9mYW1peF9mdW5jdGlvbnMvRW50aXR5RGljdGlvbmFyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUE2bEI7QUFDN2xCLDhFQUFnRjtBQUNoRixvRUFBc0Q7QUFDdEQsd0NBQTRDO0FBQzVDLDBFQUFpRDtBQUNqRCw0REFBOEM7QUFDOUMscURBQXVDO0FBQ3ZDLHdFQUFvRTtBQUNwRSxnREFBd0I7QUFDeEIsb0RBQXVCO0FBTXZCLE1BQWEsZ0JBQWdCO0lBYXpCO1FBWE8sYUFBUSxHQUFHLElBQUksa0NBQWUsRUFBRSxDQUFDO1FBQ2hDLGdCQUFXLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUMsQ0FBQyw0Q0FBNEM7UUFDMUYsZ0JBQVcsR0FBRyxJQUFJLEdBQUcsRUFBK0MsQ0FBQyxDQUFDLDREQUE0RDtRQUNsSSxvQkFBZSxHQUFHLElBQUksR0FBRyxFQUF1RCxDQUFDLENBQUMsZ0RBQWdEO1FBQ2xJLGlCQUFZLEdBQUcsSUFBSSxHQUFHLEVBQXdCLENBQUMsQ0FBQyxnREFBZ0Q7UUFDaEcsZUFBVSxHQUFHLElBQUksR0FBRyxFQUE2QyxDQUFDLENBQUMsa0RBQWtEO1FBQ3JILGVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBa0UsQ0FBQyxDQUFDLDJDQUEyQztRQUNuSSw0QkFBdUIsR0FBRyxJQUFJLEdBQThGLENBQUEsQ0FBQywrQ0FBK0M7UUFDNUssa0JBQWEsR0FBRyxnQ0FBZ0MsQ0FBQyxDQUFDLDZDQUE2QztRQUNoRyx3QkFBbUIsR0FBRyxJQUFJLEdBQUcsRUFBa0MsQ0FBQztRQUduRSxJQUFJLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ25FLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ksd0JBQXdCLENBQUMsYUFBZ0MsRUFB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QXc2Q0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDbGFzc0RlY2xhcmF0aW9uLCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uLCBGdW5jdGlvbkRlY2xhcmF0aW9uLCBJZGVudGlmaWVyLCBJbnRlcmZhY2VEZWNsYXJhdGlvbiwgTWV0aG9kRGVjbGFyYXRpb24sIE1ldGhvZFNpZ25hdHVyZSwgTW9kdWxlRGVjbGFyYXRpb24sIFByb3BlcnR5RGVjbGFyYXRpb24sIFByb3BlcnR5U2lnbmF0dXJlLCBTb3VyY2VGaWxlLCBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24sIFZhcmlhYmxlRGVjbGFyYXRpb24sIFBhcmFtZXRlckRlY2xhcmF0aW9uLCBEZWNvcmF0b3IsIEdldEFjY2Vzc29yRGVjbGFyYXRpb24sIFNldEFjY2Vzc29yRGVjbGFyYXRpb24sIEltcG9ydFNwZWNpZmllciwgQ29tbWVudFJhbmdlLCBFbnVtRGVjbGFyYXRpb24sIEVudW1NZW1iZXIsIFR5cGVBbGlhc0RlY2xhcmF0aW9uLCBGdW5jdGlvbkV4cHJlc3Npb24sIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cywgSW1wb3J0RGVjbGFyYXRpb24sIEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uLCBTeW50YXhLaW5kLCBFeHByZXNzaW9uLCBUeXBlTm9kZSwgTm9kZSwgdHMsIFNjb3BlLCBUeXBlLCBBcnJvd0Z1bmN0aW9uIH0gZnJvbSBcInRzLW1vcnBoXCI7XG5pbXBvcnQgeyBpc0FtYmllbnQsIGlzTmFtZXNwYWNlIH0gZnJvbSBcIi4uL2FuYWx5emVfZnVuY3Rpb25zL3Byb2Nlc3NfZnVuY3Rpb25zXCI7XG5pbXBvcnQgKiBhcyBGYW1peCBmcm9tIFwiLi4vbGliL2ZhbWl4L3NyYy9tb2RlbC9mYW1peFwiO1xuaW1wb3J0IHsgbG9nZ2VyLCBjb25maWcgfSBmcm9tIFwiLi4vYW5hbHl6ZVwiO1xuaW1wb3J0IEdyYXBoZW1lU3BsaXR0ZXIgZnJvbSBcImdyYXBoZW1lLXNwbGl0dGVyXCI7XG5pbXBvcnQgKiBhcyBIZWxwZXJzIGZyb20gXCIuL2hlbHBlcnNfY3JlYXRpb25cIjtcbmltcG9ydCAqIGFzIEZRTkZ1bmN0aW9ucyBmcm9tIFwiLi4vZnFuXCI7XG5pbXBvcnQgeyBGYW1peFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vbGliL2ZhbWl4L3NyYy9mYW1peF9yZXBvc2l0b3J5XCI7XG5pbXBvcnQgcGF0aCBmcm9tIFwicGF0aFwiO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcblxuZXhwb3J0IHR5cGUgVFNNb3JwaE9iamVjdFR5cGUgPSBJbXBvcnREZWNsYXJhdGlvbiB8IEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uIHwgU291cmNlRmlsZSB8IE1vZHVsZURlY2xhcmF0aW9uIHwgQ2xhc3NEZWNsYXJhdGlvbiB8IEludGVyZmFjZURlY2xhcmF0aW9uIHwgTWV0aG9kRGVjbGFyYXRpb24gfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgTWV0aG9kU2lnbmF0dXJlIHwgRnVuY3Rpb25EZWNsYXJhdGlvbiB8IEZ1bmN0aW9uRXhwcmVzc2lvbiB8IFBhcmFtZXRlckRlY2xhcmF0aW9uIHwgVmFyaWFibGVEZWNsYXJhdGlvbiB8IFByb3BlcnR5RGVjbGFyYXRpb24gfCBQcm9wZXJ0eVNpZ25hdHVyZSB8IFR5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IElkZW50aWZpZXIgfCBEZWNvcmF0b3IgfCBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IEltcG9ydFNwZWNpZmllciB8IENvbW1lbnRSYW5nZSB8IEVudW1EZWNsYXJhdGlvbiB8IEVudW1NZW1iZXIgfCBUeXBlQWxpYXNEZWNsYXJhdGlvbiB8IEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cztcblxuZXhwb3J0IHR5cGUgVHlwZURlY2xhcmF0aW9uID0gVHlwZUFsaWFzRGVjbGFyYXRpb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uIHwgUHJvcGVydHlTaWduYXR1cmUgfCBNZXRob2REZWNsYXJhdGlvbiB8IENvbnN0cnVjdG9yRGVjbGFyYXRpb24gfCBNZXRob2RTaWduYXR1cmUgfCBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24gfCBQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IFZhcmlhYmxlRGVjbGFyYXRpb24gfCBFbnVtTWVtYmVyO1xuXG5leHBvcnQgY2xhc3MgRW50aXR5RGljdGlvbmFyeSB7XG4gICAgXG4gICAgcHVibGljIGZhbWl4UmVwID0gbmV3IEZhbWl4UmVwb3NpdG9yeSgpO1xuICAgIHByaXZhdGUgZm14QWxpYXNNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguQWxpYXM+KCk7IC8vIE1hcHMgdGhlIGFsaWFzIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXG4gICAgcHJpdmF0ZSBmbXhDbGFzc01hcCA9IG5ldyBNYXA8c3RyaW5nLCBGYW1peC5DbGFzcyB8IEZhbWl4LlBhcmFtZXRyaWNDbGFzcz4oKTsgLy8gTWFwcyB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXG4gICAgcHJpdmF0ZSBmbXhJbnRlcmZhY2VNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguSW50ZXJmYWNlIHwgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZT4oKTsgLy8gTWFwcyB0aGUgaW50ZXJmYWNlIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXG4gICAgcHJpdmF0ZSBmbXhNb2R1bGVNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguTW9kdWxlPigpOyAvLyBNYXBzIHRoZSBuYW1lc3BhY2UgbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIGZteEZpbGVNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguU2NyaXB0RW50aXR5IHwgRmFtaXguTW9kdWxlPigpOyAvLyBNYXBzIHRoZSBzb3VyY2UgZmlsZSBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxuICAgIHByaXZhdGUgZm14VHlwZU1hcCA9IG5ldyBNYXA8c3RyaW5nLCBGYW1peC5UeXBlIHwgRmFtaXguUHJpbWl0aXZlVHlwZSB8IEZhbWl4LlBhcmFtZXRlclR5cGU+KCk7IC8vIE1hcHMgdGhlIHR5cGUgbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIGZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwID0gbmV3IE1hcDxzdHJpbmcsIEZhbWl4LkZ1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uIHwgRmFtaXguTWV0aG9kIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZD4gLy8gTWFwcyB0aGUgZnVuY3Rpb24gbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIFVOS05PV05fVkFMVUUgPSAnKHVua25vd24gZHVlIHRvIHBhcnNpbmcgZXJyb3IpJzsgLy8gVGhlIHZhbHVlIHRvIHVzZSB3aGVuIGEgbmFtZSBpcyBub3QgdXNhYmxlXG4gICAgcHVibGljIGZteEVsZW1lbnRPYmplY3RNYXAgPSBuZXcgTWFwPEZhbWl4LkVudGl0eSxUU01vcnBoT2JqZWN0VHlwZT4oKTtcbiAgICAgICAgICAgIFxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmZhbWl4UmVwLnNldEZteEVsZW1lbnRPYmplY3RNYXAodGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwKTsgICAgICBcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBNYWtlcyBhIEZhbWl4IGluZGV4IGZpbGUgYW5jaG9yXG4gICAgICogQHBhcmFtIHNvdXJjZUVsZW1lbnQgQSBzb3VyY2UgZWxlbWVudFxuICAgICAqIEBwYXJhbSBmYW1peEVsZW1lbnQgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBzb3VyY2UgZWxlbWVudFxuICAgICAqL1xuICAgIHB1YmxpYyBtYWtlRmFtaXhJbmRleEZpbGVBbmNob3Ioc291cmNlRWxlbWVudDogVFNNb3JwaE9iamVjdFR5cGUsIGZhbWl4RWxlbWVudDogRmFtaXguU291cmNlZEVudGl0eSk6IHZvaWQge1xuICAgICAgICBsb2dnZXIuZGVidWcoXCJtYWtpbmcgaW5kZXggZmlsZSBhbmNob3IgZm9yICdcIiArIHNvdXJjZUVsZW1lbnQ/LmdldFRleHQoKSArIFwiJyB3aXRoIGZhbWl4RWxlbWVudCBcIiArIGZhbWl4RWxlbWVudC5nZXRKU09OKCkpO1xuICAgICAgICBjb25zdCBmbXhJbmRleEZpbGVBbmNob3IgPSBuZXcgRmFtaXguSW5kZXhlZEZpbGVBbmNob3IoKTtcbiAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLnNldEVsZW1lbnQoZmFtaXhFbGVtZW50KTtcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmYW1peEVsZW1lbnQsIHNvdXJjZUVsZW1lbnQpO1xuXG4gICAgICAgIGlmIChzb3VyY2VFbGVtZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCBhYnNvbHV0ZVBhdGhQcm9qZWN0ID0gdGhpcy5mYW1peFJlcC5nZXRBYnNvbHV0ZVBhdGgoKTtcbiAgICAgICAgXG4gICAgICAgICAgICBjb25zdCBhYnNvbHV0ZVBhdGggPSBwYXRoLm5vcm1hbGl6ZShzb3VyY2VFbGVtZW50LmdldFNvdXJjZUZpbGUoKS5nZXRGaWxlUGF0aCgpKTtcblxuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25Ob2RlTW9kdWxlcyA9IGFic29sdXRlUGF0aC5pbmRleE9mKCdub2RlX21vZHVsZXMnKTtcblxuICAgICAgICAgICAgbGV0IHBhdGhJblByb2plY3Q6IHN0cmluZyA9IFwiXCI7XG5cbiAgICAgICAgICAgIGlmIChwb3NpdGlvbk5vZGVNb2R1bGVzICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhdGhGcm9tTm9kZU1vZHVsZXMgPSBhYnNvbHV0ZVBhdGguc3Vic3RyaW5nKHBvc2l0aW9uTm9kZU1vZHVsZXMpO1xuICAgICAgICAgICAgICAgIHBhdGhJblByb2plY3QgPSBwYXRoRnJvbU5vZGVNb2R1bGVzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXRoSW5Qcm9qZWN0ID0gdGhpcy5jb252ZXJ0VG9SZWxhdGl2ZVBhdGgoYWJzb2x1dGVQYXRoLCBhYnNvbHV0ZVBhdGhQcm9qZWN0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gcmV2ZXJ0IGFueSBiYWNrc2xhc2hlcyB0byBmb3J3YXJkIHNsYXNoZXMgKHBhdGgubm9ybWFsaXplIG9uIHdpbmRvd3MgaW50cm9kdWNlcyB0aGVtKVxuICAgICAgICAgICAgcGF0aEluUHJvamVjdCA9IHBhdGhJblByb2plY3QucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG5cbiAgICAgICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5zZXRGaWxlTmFtZShwYXRoSW5Qcm9qZWN0KTtcbiAgICAgICAgICAgIGxldCBzb3VyY2VTdGFydCwgc291cmNlRW5kLCBzb3VyY2VMaW5lU3RhcnQsIHNvdXJjZUxpbmVFbmQ6IG51bWJlcjtcbiAgICAgICAgICAgIGlmICghKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBDb21tZW50UmFuZ2UpKSB7XG4gICAgICAgICAgICAgICAgc291cmNlU3RhcnQgPSBzb3VyY2VFbGVtZW50LmdldFN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgc291cmNlRW5kID0gc291cmNlRWxlbWVudC5nZXRFbmQoKTtcbiAgICAgICAgICAgICAgICBzb3VyY2VMaW5lU3RhcnQgPSBzb3VyY2VFbGVtZW50LmdldFN0YXJ0TGluZU51bWJlcigpO1xuICAgICAgICAgICAgICAgIHNvdXJjZUxpbmVFbmQgPSBzb3VyY2VFbGVtZW50LmdldEVuZExpbmVOdW1iZXIoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc291cmNlU3RhcnQgPSBzb3VyY2VFbGVtZW50LmdldFBvcygpO1xuICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IHNvdXJjZUVsZW1lbnQuZ2V0RW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoY29uZmlnLmV4cGVjdEdyYXBoZW1lcykge1xuICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAqIFRoZSBmb2xsb3dpbmcgbG9naWMgaGFuZGxlcyB0aGUgY2FzZSBvZiBtdWx0aS1jb2RlIHBvaW50IGNoYXJhY3RlcnMgKGUuZy4gZW1vamkpIGluIHRoZSBzb3VyY2UgdGV4dC5cbiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlIFBoYXJvL1NtYWxsdGFsayB0cmVhdHMgbXVsdGktY29kZSBwb2ludCBjaGFyYWN0ZXJzIGFzIGEgc2luZ2xlIGNoYXJhY3RlciwgXG4gICAgICAgICAgICAgICAgICogYnV0IEphdmFTY3JpcHQgdHJlYXRzIHRoZW0gYXMgbXVsdGlwbGUgY2hhcmFjdGVycy4gVGhpcyBtZWFucyB0aGF0IHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9uc1xuICAgICAgICAgICAgICAgICAqIG9mIGEgc291cmNlIGVsZW1lbnQgaW4gUGhhcm8vU21hbGx0YWxrIHdpbGwgYmUgZGlmZmVyZW50IHRoYW4gdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIHRoZVxuICAgICAgICAgICAgICAgICAqIHNhbWUgc291cmNlIGVsZW1lbnQgaW4gSmF2YVNjcmlwdC4gVGhpcyBsb2dpYyBmaW5kcyB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgb2YgdGhlIHNvdXJjZVxuICAgICAgICAgICAgICAgICAqIGVsZW1lbnQgaW4gSmF2YVNjcmlwdCBhbmQgdGhlbiB1c2VzIHRob3NlIHBvc2l0aW9ucyB0byBzZXQgdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIHRoZVxuICAgICAgICAgICAgICAgICAqIEZhbWl4IGluZGV4IGZpbGUgYW5jaG9yLlxuICAgICAgICAgICAgICAgICAqIEl0IGRlcGVuZHMgb24gY29kZSBpbiB0aGUgJ2dyYXBoZW1lLXNwbGl0dGVyJyBwYWNrYWdlIGluIG5wbS5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBzcGxpdHRlciA9IG5ldyBHcmFwaGVtZVNwbGl0dGVyKCk7XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlRmlsZVRleHQgPSBzb3VyY2VFbGVtZW50LmdldFNvdXJjZUZpbGUoKS5nZXRGdWxsVGV4dCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhc0dyYXBoZW1lQ2x1c3RlcnMgPSBzcGxpdHRlci5jb3VudEdyYXBoZW1lcyhzb3VyY2VGaWxlVGV4dCkgPiAxO1xuICAgICAgICAgICAgICAgIGlmIChoYXNHcmFwaGVtZUNsdXN0ZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUVsZW1lbnRUZXh0ID0gc291cmNlRmlsZVRleHQuc3Vic3RyaW5nKHNvdXJjZVN0YXJ0LCBzb3VyY2VFbmQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcyA9IHNwbGl0dGVyLnNwbGl0R3JhcGhlbWVzKHNvdXJjZUVsZW1lbnRUZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291cmNlRmlsZVRleHRHcmFwaGVtZXMgPSBzcGxpdHRlci5zcGxpdEdyYXBoZW1lcyhzb3VyY2VGaWxlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mR3JhcGhlbWVDbHVzdGVyc0JlZm9yZVN0YXJ0ID0gc3BsaXR0ZXIuY291bnRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQuc3Vic3RyaW5nKDAsIHNvdXJjZVN0YXJ0KSk7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAvLyBmaW5kIHRoZSBzdGFydCBvZiB0aGUgc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMgYXJyYXkgaW4gdGhlIHNvdXJjZUZpbGVUZXh0R3JhcGhlbWVzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gSGVscGVycy5pbmRleE9mU3BsaXRBcnJheSh7c2VhcmNoQXJyYXk6IHNvdXJjZUZpbGVUZXh0R3JhcGhlbWVzLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0QXJyYXk6IHNvdXJjZUVsZW1lbnRUZXh0R3JhcGhlbWVzLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IHNvdXJjZVN0YXJ0IC0gbnVtYmVyT2ZHcmFwaGVtZUNsdXN0ZXJzQmVmb3JlU3RhcnR9KTtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlRW5kID0gc291cmNlU3RhcnQgKyBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgfSBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIC8vIG5vdGU6IHRoZSArMSBpcyBiZWNhdXNlIHRoZSBzb3VyY2UgYW5jaG9yIGlzIDEtYmFzZWQsIGJ1dCB0cy1tb3JwaCBpcyAwLWJhc2VkXG4gICAgICAgICAgICBmbXhJbmRleEZpbGVBbmNob3Iuc2V0U3RhcnRQb3Moc291cmNlU3RhcnQgKyAxKTtcbiAgICAgICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5zZXRFbmRQb3Moc291cmNlRW5kICsgMSk7XG4gICAgICAgICAgICBpZiAoIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSkge1xuICAgICAgICAgICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5zZXRTdGFydExpbmUoc291cmNlTGluZVN0YXJ0KTtcbiAgICAgICAgICAgICAgICBmbXhJbmRleEZpbGVBbmNob3Iuc2V0RW5kTGluZShzb3VyY2VMaW5lRW5kKTsgICAgXG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghKGZhbWl4RWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LkltcG9ydENsYXVzZSB8fCBmYW1peEVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5BY2Nlc3MgfHwgZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUmVmZXJlbmNlIHx8IGZhbWl4RWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4Lkludm9jYXRpb24gfHwgZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguSW5oZXJpdGFuY2UpICYmICEoZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguQ29tbWVudCkgJiYgIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSAmJiAhKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBJZGVudGlmaWVyKSAmJiAhKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBJbXBvcnRTcGVjaWZpZXIpICYmICEoc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cykpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBmcW4gPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKHNvdXJjZUVsZW1lbnQpO1xuICAgICAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhcIlNldHRpbmcgZnVsbHkgcXVhbGlmaWVkIG5hbWUgZm9yIFwiICsgZmFtaXhFbGVtZW50LmdldEpTT04oKSArIFwiIHRvIFwiICsgZnFuKTtcbiAgICAgICAgICAgICAgICAoZmFtaXhFbGVtZW50IGFzIEZhbWl4Lk5hbWVkRW50aXR5KS5zZXRGdWxseVF1YWxpZmllZE5hbWUoZnFuKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHNvdXJjZUVsZW1lbnQgaXMgbnVsbFxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXCJzb3VyY2VFbGVtZW50IGlzIG51bGwgZm9yIGZhbWl4RWxlbWVudCBcIiArIGZhbWl4RWxlbWVudC5nZXRKU09OKCkpO1xuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLnNldEZpbGVOYW1lKFwidW5rbm93blwiKTtcbiAgICAgICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5zZXRTdGFydFBvcygwKTtcbiAgICAgICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5zZXRFbmRQb3MoMCk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW5kZXhGaWxlQW5jaG9yKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBzY3JpcHQgZW50aXR5IG9yIG1vZHVsZVxuICAgICAqIEBwYXJhbSBmIEEgc291cmNlIGZpbGVcbiAgICAgKiBAcGFyYW0gaXNNb2R1bGUgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIHNvdXJjZSBmaWxlIGlzIGEgbW9kdWxlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBzb3VyY2UgZmlsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4RmlsZShmOiBTb3VyY2VGaWxlLCBpc01vZHVsZTogYm9vbGVhbik6IEZhbWl4LlNjcmlwdEVudGl0eSB8IEZhbWl4Lk1vZHVsZSB7XG4gICAgICAgIGxldCBmbXhGaWxlOiBGYW1peC5TY3JpcHRFbnRpdHk7IC8vIHwgRmFtaXguTW9kdWxlO1xuXG4gICAgICAgIGNvbnN0IGZpbGVOYW1lID0gZi5nZXRCYXNlTmFtZSgpO1xuICAgICAgICBjb25zdCBmdWxseVF1YWxpZmllZEZpbGVuYW1lID0gZi5nZXRGaWxlUGF0aCgpO1xuICAgICAgICBpZiAoIXRoaXMuZm14RmlsZU1hcC5oYXMoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSkpIHtcbiAgICAgICAgICAgIGlmIChpc01vZHVsZSkge1xuICAgICAgICAgICAgICAgIGZteEZpbGUgPSBuZXcgRmFtaXguTW9kdWxlKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhGaWxlID0gbmV3IEZhbWl4LlNjcmlwdEVudGl0eSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm14RmlsZS5zZXROYW1lKGZpbGVOYW1lKTtcbiAgICAgICAgICAgIGZteEZpbGUuc2V0TnVtYmVyT2ZMaW5lc09mVGV4dChmLmdldEVuZExpbmVOdW1iZXIoKSAtIGYuZ2V0U3RhcnRMaW5lTnVtYmVyKCkpO1xuICAgICAgICAgICAgZm14RmlsZS5zZXROdW1iZXJPZkNoYXJhY3RlcnMoZi5nZXRGdWxsVGV4dCgpLmxlbmd0aCk7XG5cbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGYsIGZteEZpbGUpO1xuXG4gICAgICAgICAgICB0aGlzLmZteEZpbGVNYXAuc2V0KGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUsIGZteEZpbGUpO1xuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEZpbGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14RmlsZSA9IHRoaXMuZm14RmlsZU1hcC5nZXQoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSk7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEZpbGUsZik7XG4gICAgICAgIHJldHVybiBmbXhGaWxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgb3IgZ2V0cyBhIEZhbWl4IE1vZHVsZVxuICAgICAqIEBwYXJhbSBtIEEgbW9kdWxlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBtb2R1bGVcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlT3JHZXRGYW1peE1vZHVsZShtOiBNb2R1bGVEZWNsYXJhdGlvbik6IEZhbWl4Lk1vZHVsZSB7XG4gICAgICAgIGxldCBmbXhNb2R1bGU6IEZhbWl4Lk1vZHVsZTtcbiAgICAgICAgY29uc3QgbW9kdWxlTmFtZSA9IG0uZ2V0TmFtZSgpO1xuICAgICAgICBpZiAoIXRoaXMuZm14TW9kdWxlTWFwLmhhcyhtb2R1bGVOYW1lKSkge1xuICAgICAgICAgICAgZm14TW9kdWxlID0gbmV3IEZhbWl4Lk1vZHVsZSgpO1xuICAgICAgICAgICAgZm14TW9kdWxlLnNldE5hbWUobW9kdWxlTmFtZSk7XG4gICAgICAgICAgICBmbXhNb2R1bGUuJGlzQW1iaWVudCA9IGlzQW1iaWVudChtKTtcbiAgICAgICAgICAgIGZteE1vZHVsZS4kaXNOYW1lc3BhY2UgPSBpc05hbWVzcGFjZShtKTtcbiAgICAgICAgICAgIGZteE1vZHVsZS4kaXNNb2R1bGUgPSAhZm14TW9kdWxlLiRpc05hbWVzcGFjZSAmJiAhZm14TW9kdWxlLiRpc0FtYmllbnQ7XG5cbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKG0sIGZteE1vZHVsZSk7XG5cbiAgICAgICAgICAgIHRoaXMuZm14TW9kdWxlTWFwLnNldChtb2R1bGVOYW1lLCBmbXhNb2R1bGUpO1xuXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14TW9kdWxlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZteE1vZHVsZSA9IHRoaXMuZm14TW9kdWxlTWFwLmdldChtb2R1bGVOYW1lKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14TW9kdWxlLG0pO1xuICAgICAgICByZXR1cm4gZm14TW9kdWxlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBhbGlhc1xuICAgICAqIEBwYXJhbSBhIEFuIGFsaWFzXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBhbGlhc1xuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peEFsaWFzKGE6IFR5cGVBbGlhc0RlY2xhcmF0aW9uKTogRmFtaXguQWxpYXMge1xuICAgICAgICBsZXQgZm14QWxpYXM6IEZhbWl4LkFsaWFzO1xuICAgICAgICBjb25zdCBhbGlhc05hbWUgPSBhLmdldE5hbWUoKTtcbiAgICAgICAgY29uc3QgYWxpYXNGdWxseVF1YWxpZmllZE5hbWUgPSBhLmdldFR5cGUoKS5nZXRUZXh0KCk7IC8vIEZRTkZ1bmN0aW9ucy5nZXRGUU4oYSk7XG4gICAgICAgIGlmICghdGhpcy5mbXhBbGlhc01hcC5oYXMoYWxpYXNGdWxseVF1YWxpZmllZE5hbWUpKSB7XG4gICAgICAgICAgICBmbXhBbGlhcyA9IG5ldyBGYW1peC5BbGlhcygpO1xuICAgICAgICAgICAgZm14QWxpYXMuc2V0TmFtZShhLmdldE5hbWUoKSk7XG4gICAgICAgICAgICBjb25zdCBhbGlhc05hbWVXaXRoR2VuZXJpY3MgPSBhbGlhc05hbWUgKyAoYS5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA/IChcIjxcIiArIGEuZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAodHAgPT4gdHAuZ2V0TmFtZSgpKS5qb2luKFwiLCBcIikgKyBcIj5cIikgOiBcIlwiKTtcbiAgICAgICAgICAgIGxvZ2dlci5kZWJ1ZyhgPiBOT1RFOiBhbGlhcyAke2FsaWFzTmFtZX0gaGFzIGZ1bGx5IHF1YWxpZmllZCBuYW1lICR7YWxpYXNGdWxseVF1YWxpZmllZE5hbWV9IGFuZCBuYW1lIHdpdGggZ2VuZXJpY3MgJHthbGlhc05hbWVXaXRoR2VuZXJpY3N9LmApO1xuXG4gICAgICAgICAgICBjb25zdCBmbXhUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShhbGlhc05hbWVXaXRoR2VuZXJpY3MsIGEpO1xuICAgICAgICAgICAgZm14QWxpYXMuc2V0QWxpYXNlZEVudGl0eShmbXhUeXBlKTtcblxuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoYSwgZm14QWxpYXMpO1xuXG4gICAgICAgICAgICB0aGlzLmZteEFsaWFzTWFwLnNldChhbGlhc0Z1bGx5UXVhbGlmaWVkTmFtZSwgZm14QWxpYXMpO1xuXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14QWxpYXMpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14QWxpYXMgPSB0aGlzLmZteEFsaWFzTWFwLmdldChhbGlhc0Z1bGx5UXVhbGlmaWVkTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhBbGlhcyxhKTtcblxuICAgICAgICByZXR1cm4gZm14QWxpYXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggY2xhc3Mgb3IgcGFyYW1ldGVyaXphYmxlIGNsYXNzXG4gICAgICogQHBhcmFtIGNscyBBIGNsYXNzXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBjbGFzc1xuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4Q2xhc3MoY2xzOiBDbGFzc0RlY2xhcmF0aW9uKTogRmFtaXguQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljQ2xhc3Mge1xuICAgICAgICBsZXQgZm14Q2xhc3M6IEZhbWl4LkNsYXNzIHwgRmFtaXguUGFyYW1ldHJpY0NsYXNzO1xuICAgICAgICBjb25zdCBpc0Fic3RyYWN0ID0gY2xzLmlzQWJzdHJhY3QoKTtcbiAgICAgICAgY29uc3QgY2xhc3NGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGNscyk7XG4gICAgICAgIGNvbnN0IGNsc05hbWUgPSBjbHMuZ2V0TmFtZSgpO1xuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBjbHMuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGg7XG4gICAgICAgIGlmICghdGhpcy5mbXhDbGFzc01hcC5oYXMoY2xhc3NGdWxseVF1YWxpZmllZE5hbWUpKSB7XG4gICAgICAgICAgICBpZiAoaXNHZW5lcmljKSB7XG4gICAgICAgICAgICAgICAgZm14Q2xhc3MgPSBuZXcgRmFtaXguUGFyYW1ldHJpY0NsYXNzKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhDbGFzcyA9IG5ldyBGYW1peC5DbGFzcygpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmbXhDbGFzcy5zZXROYW1lKGNsc05hbWUpO1xuICAgICAgICAgICAgZm14Q2xhc3Muc2V0RnVsbHlRdWFsaWZpZWROYW1lKGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lKTtcbiAgICAgICAgICAgIGZteENsYXNzLnNldElzQWJzdHJhY3QoaXNBYnN0cmFjdCk7XG5cbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGNscywgZm14Q2xhc3MpO1xuXG4gICAgICAgICAgICB0aGlzLmZteENsYXNzTWFwLnNldChjbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZSwgZm14Q2xhc3MpO1xuXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14Q2xhc3MpO1xuXG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteENsYXNzLGNscyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmbXhDbGFzcyA9IHRoaXMuZm14Q2xhc3NNYXAuZ2V0KGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lKSBhcyAoRmFtaXguQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljQ2xhc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGZteENsYXNzO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgb3IgZ2V0cyBhIEZhbWl4IGludGVyZmFjZSBvciBwYXJhbWV0ZXJpemFibGUgaW50ZXJmYWNlXG4gICAgICogQHBhcmFtIGludGVyIEFuIGludGVyZmFjZVxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgaW50ZXJmYWNlXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoaW50ZXI6IEludGVyZmFjZURlY2xhcmF0aW9uKTogRmFtaXguSW50ZXJmYWNlIHwgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSB7XG4gICAgICAgIGxldCBmbXhJbnRlcmZhY2U6IEZhbWl4LkludGVyZmFjZSB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2U7XG4gICAgICAgIGNvbnN0IGludGVyTmFtZSA9IGludGVyLmdldE5hbWUoKTtcbiAgICAgICAgY29uc3QgaW50ZXJGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGludGVyKTtcbiAgICAgICAgaWYgKCF0aGlzLmZteEludGVyZmFjZU1hcC5oYXMoaW50ZXJGdWxseVF1YWxpZmllZE5hbWUpKSB7XG4gICAgICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBpbnRlci5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChpc0dlbmVyaWMpIHtcbiAgICAgICAgICAgICAgICBmbXhJbnRlcmZhY2UgPSBuZXcgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm14SW50ZXJmYWNlID0gbmV3IEZhbWl4LkludGVyZmFjZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmbXhJbnRlcmZhY2Uuc2V0TmFtZShpbnRlck5hbWUpO1xuXG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihpbnRlciwgZm14SW50ZXJmYWNlKTtcblxuICAgICAgICAgICAgdGhpcy5mbXhJbnRlcmZhY2VNYXAuc2V0KGludGVyRnVsbHlRdWFsaWZpZWROYW1lLCBmbXhJbnRlcmZhY2UpO1xuXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW50ZXJmYWNlKTtcblxuICAgICAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhJbnRlcmZhY2UsaW50ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14SW50ZXJmYWNlID0gdGhpcy5mbXhJbnRlcmZhY2VNYXAuZ2V0KGludGVyRnVsbHlRdWFsaWZpZWROYW1lKSBhcyAoRmFtaXguSW50ZXJmYWNlIHwgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZteEludGVyZmFjZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBjb25jcmV0ZSBlbGVtZW50XG4gICAgICogQHBhcmFtIGVsIEEgcGFyYW1ldHJpYyBFbGVtZW50ICAgXG4gICAgICogQHBhcmFtIGVsRGVjbGFyYXRpb24gdGhlIGVsZW1lbnQgZGVjbGFyYXRpb25cbiAgICAgKiBAcGFyYW0gY29uY3JldGVBcmd1bWVudHMgY29uY3JldGUgYXJndW1lbnRzXG4gICAgICogQHJldHVybnMgQSBwYXJhbWV0cmljIEVsZW1lbnQgIFxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGVsIDogRmFtaXguUGFyYW1ldHJpY0NsYXNzIHwgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSB8IEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbiB8IEZhbWl4LlBhcmFtZXRyaWNNZXRob2QsIGVsRGVjbGFyYXRpb24gOiBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgTWV0aG9kRGVjbGFyYXRpb24sIGNvbmNyZXRlQXJndW1lbnRzIDogYW55KTogRmFtaXguUGFyYW1ldHJpY0NsYXNzIHwgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSB8IEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbiB8IEZhbWl4LlBhcmFtZXRyaWNNZXRob2Qge1xuICAgICAgICBcbiAgICAgICAgbGV0IGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUgPSBlbC5nZXRGdWxseVF1YWxpZmllZE5hbWUoKTtcbiAgICAgICAgbGV0IHBhcmFtcyA9IFwiXCI7XG4gICAgICAgIFxuICAgICAgICBjb25jcmV0ZUFyZ3VtZW50cy5tYXAoKHBhcmFtKSA9PiB7XG4gICAgICAgICAgICBwYXJhbXMgPSBwYXJhbXMrcGFyYW0uZ2V0VGV4dCgpKycsJ1xuICAgICAgICB9KVxuICAgICAgICBcbiAgICAgICAgcGFyYW1zID0gcGFyYW1zLnN1YnN0cmluZygwLCBwYXJhbXMubGVuZ3RoIC0gMSlcbiAgICAgICAgICAgICAgICBcbiAgICAgICAgZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSA9IEhlbHBlcnMucmVwbGFjZUxhc3RCZXR3ZWVuVGFncyhmdWxseVF1YWxpZmllZEZpbGVuYW1lLHBhcmFtcyk7XG5cbiAgICAgICAgbGV0IGNvbmNFbGVtZW50O1xuXG4gICAgICAgIGlmICghdGhpcy5mbXhJbnRlcmZhY2VNYXAuaGFzKGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpICYmICF0aGlzLmZteENsYXNzTWFwLmhhcyhmdWxseVF1YWxpZmllZEZpbGVuYW1lKSAmJiAhdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5oYXMoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSkpe1xuICAgICAgICAgICAgY29uY0VsZW1lbnQgPSBfLmNsb25lRGVlcChlbCk7IFxuICAgICAgICAgICAgY29uY0VsZW1lbnQuc2V0RnVsbHlRdWFsaWZpZWROYW1lKGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpO1xuICAgICAgICAgICAgY29uY0VsZW1lbnQuY2xlYXJHZW5lcmljUGFyYW1ldGVycygpO1xuICAgICAgICAgICAgY29uY3JldGVBcmd1bWVudHMubWFwKChwYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlciA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENvbmNyZXRlVHlwZShwYXJhbSk7XG4gICAgICAgICAgICAgICAgY29uY0VsZW1lbnQuYWRkQ29uY3JldGVQYXJhbWV0ZXIocGFyYW1ldGVyKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIChlbCBpbnN0YW5jZW9mIEZhbWl4LlBhcmFtZXRyaWNDbGFzcykge1xuICAgICAgICAgICAgICAgIHRoaXMuZm14Q2xhc3NNYXAuc2V0KGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUsIGNvbmNFbGVtZW50IGFzIEZhbWl4LlBhcmFtZXRyaWNDbGFzcyk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVsIGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuZm14SW50ZXJmYWNlTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZWwgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChlbCBpbnN0YW5jZW9mIEZhbWl4LlBhcmFtZXRyaWNNZXRob2QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljTWV0aG9kKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChjb25jRWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGNvbmNFbGVtZW50LGVsRGVjbGFyYXRpb24pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgaWYgKGVsIGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0NsYXNzKSB7XG4gICAgICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmZteENsYXNzTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZWwgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlKSB7XG4gICAgICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmZteEludGVyZmFjZU1hcC5nZXQoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGVsIGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uKSB7XG4gICAgICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZWwgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljTWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29uY0VsZW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IHByb3BlcnR5XG4gICAgICogQHBhcmFtIHByb3BlcnR5IEEgcHJvcGVydHlcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHByb3BlcnR5XG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4UHJvcGVydHkocHJvcGVydHk6IFByb3BlcnR5RGVjbGFyYXRpb24gfCBQcm9wZXJ0eVNpZ25hdHVyZSk6IEZhbWl4LlByb3BlcnR5IHtcbiAgICAgICAgY29uc3QgZm14UHJvcGVydHkgPSBuZXcgRmFtaXguUHJvcGVydHkoKTtcbiAgICAgICAgY29uc3QgaXNTaWduYXR1cmUgPSBwcm9wZXJ0eSBpbnN0YW5jZW9mIFByb3BlcnR5U2lnbmF0dXJlO1xuICAgICAgICBmbXhQcm9wZXJ0eS5zZXROYW1lKHByb3BlcnR5LmdldE5hbWUoKSk7XG5cbiAgICAgICAgbGV0IHByb3BUeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHByb3BUeXBlTmFtZSA9IHByb3BlcnR5LmdldFR5cGUoKS5nZXRUZXh0KCkudHJpbSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGA+IFdBUk5JTkc6IGdvdCBleGNlcHRpb24gJHtlcnJvcn0uIEZhaWxlZCB0byBnZXQgdXNhYmxlIG5hbWUgZm9yIHByb3BlcnR5OiAke3Byb3BlcnR5LmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKHByb3BUeXBlTmFtZSwgcHJvcGVydHkpO1xuICAgICAgICBmbXhQcm9wZXJ0eS5zZXREZWNsYXJlZFR5cGUoZm14VHlwZSk7XG5cbiAgICAgICAgLy8gYWRkIHRoZSB2aXNpYmlsaXR5IChwdWJsaWMsIHByaXZhdGUsIGV0Yy4pIHRvIHRoZSBmbXhQcm9wZXJ0eVxuICAgICAgICBmbXhQcm9wZXJ0eS52aXNpYmlsaXR5ID0gXCJcIjtcblxuICAgICAgICBwcm9wZXJ0eS5nZXRNb2RpZmllcnMoKS5mb3JFYWNoKG0gPT4ge1xuICAgICAgICAgICAgc3dpdGNoIChtLmdldFRleHQoKSkge1xuICAgICAgICAgICAgICAgIGNhc2UgU2NvcGUuUHVibGljOlxuICAgICAgICAgICAgICAgICAgICBmbXhQcm9wZXJ0eS52aXNpYmlsaXR5ID0gXCJwdWJsaWNcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBTY29wZS5Qcm90ZWN0ZWQ6XG4gICAgICAgICAgICAgICAgICAgIGZteFByb3BlcnR5LnZpc2liaWxpdHkgPSBcInByb3RlY3RlZFwiO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFNjb3BlLlByaXZhdGU6XG4gICAgICAgICAgICAgICAgICAgIGZteFByb3BlcnR5LnZpc2liaWxpdHkgPSBcInByaXZhdGVcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInN0YXRpY1wiOlxuICAgICAgICAgICAgICAgICAgICBmbXhQcm9wZXJ0eS5zZXRJc0NsYXNzU2lkZSh0cnVlKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBcInJlYWRvbmx5XCI6XG4gICAgICAgICAgICAgICAgICAgIGZteFByb3BlcnR5LnJlYWRPbmx5ID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIGlmICghaXNTaWduYXR1cmUgJiYgcHJvcGVydHkuZ2V0RXhjbGFtYXRpb25Ub2tlbk5vZGUoKSkge1xuICAgICAgICAgICAgZm14UHJvcGVydHkuaXNEZWZpbml0ZWx5QXNzaWduZWQgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wZXJ0eS5nZXRRdWVzdGlvblRva2VuTm9kZSgpKSB7XG4gICAgICAgICAgICBmbXhQcm9wZXJ0eS5pc09wdGlvbmFsID0gdHJ1ZTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocHJvcGVydHkuZ2V0TmFtZSgpLnN1YnN0cmluZygwLCAxKSA9PT0gXCIjXCIpIHtcbiAgICAgICAgICAgIGZteFByb3BlcnR5LmlzSmF2YVNjcmlwdFByaXZhdGUgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IocHJvcGVydHksIGZteFByb3BlcnR5KTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14UHJvcGVydHkpO1xuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14UHJvcGVydHkscHJvcGVydHkpO1xuXG4gICAgICAgIHJldHVybiBmbXhQcm9wZXJ0eTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggbWV0aG9kIG9yIGFjY2Vzc29yXG4gICAgICogQHBhcmFtIG1ldGhvZCBBIG1ldGhvZCBvciBhbiBhY2Nlc3NvclxuICAgICAqIEBwYXJhbSBjdXJyZW50Q0MgVGhlIGN5Y2xvbWF0aWMgY29tcGxleGl0eSBtZXRyaWNzIG9mIHRoZSBjdXJyZW50IHNvdXJjZSBmaWxlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBtZXRob2Qgb3IgdGhlIGFjY2Vzc29yXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhNZXRob2QobWV0aG9kOiBNZXRob2REZWNsYXJhdGlvbiB8IENvbnN0cnVjdG9yRGVjbGFyYXRpb24gfCBNZXRob2RTaWduYXR1cmUgfCBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbiwgY3VycmVudENDOiB1bmtub3duKTogRmFtaXguTWV0aG9kIHwgRmFtaXguQWNjZXNzb3IgfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kIHtcbiAgICAgICAgbGV0IGZteE1ldGhvZDogRmFtaXguTWV0aG9kIHwgRmFtaXguQWNjZXNzb3IgfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kO1xuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBtZXRob2QuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwO1xuICAgICAgICBjb25zdCBmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4obWV0aG9kKTtcbiAgICAgICAgaWYgKCF0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmhhcyhmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSkpIHtcblxuICAgICAgICAgICAgaWYgKG1ldGhvZCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGZteE1ldGhvZCA9IG5ldyBGYW1peC5BY2Nlc3NvcigpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGlzR2V0dGVyID0gbWV0aG9kIGluc3RhbmNlb2YgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbjtcbiAgICAgICAgICAgICAgICBjb25zdCBpc1NldHRlciA9IG1ldGhvZCBpbnN0YW5jZW9mIFNldEFjY2Vzc29yRGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgaWYgKGlzR2V0dGVyKSB7KGZteE1ldGhvZCBhcyBGYW1peC5BY2Nlc3Nvcikuc2V0S2luZChcImdldHRlclwiKTt9XG4gICAgICAgICAgICAgICAgaWYgKGlzU2V0dGVyKSB7KGZteE1ldGhvZCBhcyBGYW1peC5BY2Nlc3Nvcikuc2V0S2luZChcInNldHRlclwiKTt9XG4gICAgICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteE1ldGhvZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNHZW5lcmljKSB7XG4gICAgICAgICAgICAgICAgICAgIGZteE1ldGhvZCA9IG5ldyBGYW1peC5QYXJhbWV0cmljTWV0aG9kKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmbXhNZXRob2QgPSBuZXcgRmFtaXguTWV0aG9kKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhNZXRob2QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaXNDb25zdHJ1Y3RvciA9IG1ldGhvZCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yRGVjbGFyYXRpb247XG4gICAgICAgICAgICBjb25zdCBpc1NpZ25hdHVyZSA9IG1ldGhvZCBpbnN0YW5jZW9mIE1ldGhvZFNpZ25hdHVyZTtcblxuICAgICAgICAgICAgbGV0IGlzQWJzdHJhY3QgPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBpc1N0YXRpYyA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKG1ldGhvZCBpbnN0YW5jZW9mIE1ldGhvZERlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGlzQWJzdHJhY3QgPSBtZXRob2QuaXNBYnN0cmFjdCgpO1xuICAgICAgICAgICAgICAgIGlzU3RhdGljID0gbWV0aG9kLmlzU3RhdGljKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0NvbnN0cnVjdG9yKSB7KGZteE1ldGhvZCBhcyBGYW1peC5BY2Nlc3Nvcikuc2V0S2luZChcImNvbnN0cnVjdG9yXCIpO31cbiAgICAgICAgICAgIGZteE1ldGhvZC5zZXRJc0Fic3RyYWN0KGlzQWJzdHJhY3QpO1xuICAgICAgICAgICAgZm14TWV0aG9kLnNldElzQ2xhc3NTaWRlKGlzU3RhdGljKTtcbiAgICAgICAgICAgIGZteE1ldGhvZC5zZXRJc1ByaXZhdGUoKG1ldGhvZCBpbnN0YW5jZW9mIE1ldGhvZERlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbikgPyAobWV0aG9kLmdldE1vZGlmaWVycygpLmZpbmQoeCA9PiB4LmdldFRleHQoKSA9PT0gJ3ByaXZhdGUnKSkgIT09IHVuZGVmaW5lZCA6IGZhbHNlKTtcbiAgICAgICAgICAgIGZteE1ldGhvZC5zZXRJc1Byb3RlY3RlZCgobWV0aG9kIGluc3RhbmNlb2YgTWV0aG9kRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8fCBtZXRob2QgaW5zdGFuY2VvZiBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKSA/IChtZXRob2QuZ2V0TW9kaWZpZXJzKCkuZmluZCh4ID0+IHguZ2V0VGV4dCgpID09PSAncHJvdGVjdGVkJykpICE9PSB1bmRlZmluZWQgOiBmYWxzZSk7XG4gICAgICAgICAgICBmbXhNZXRob2Quc2V0U2lnbmF0dXJlKEhlbHBlcnMuY29tcHV0ZVNpZ25hdHVyZShtZXRob2QuZ2V0VGV4dCgpKSk7XG5cbiAgICAgICAgICAgIGxldCBtZXRob2ROYW1lOiBzdHJpbmc7XG4gICAgICAgICAgICBpZiAoaXNDb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgIG1ldGhvZE5hbWUgPSBcImNvbnN0cnVjdG9yXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBtZXRob2ROYW1lID0gKG1ldGhvZCBhcyBNZXRob2REZWNsYXJhdGlvbiB8IE1ldGhvZFNpZ25hdHVyZSB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKS5nZXROYW1lKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmbXhNZXRob2Quc2V0TmFtZShtZXRob2ROYW1lKTtcblxuICAgICAgICAgICAgaWYgKCFpc0NvbnN0cnVjdG9yKSB7XG4gICAgICAgICAgICAgICAgaWYgKG1ldGhvZC5nZXROYW1lKCkuc3Vic3RyaW5nKDAsIDEpID09PSBcIiNcIikge1xuICAgICAgICAgICAgICAgICAgICBmbXhNZXRob2Quc2V0SXNQcml2YXRlKHRydWUpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFmbXhNZXRob2QuZ2V0SXNQcml2YXRlKCkgJiYgIWZteE1ldGhvZC5nZXRJc1Byb3RlY3RlZCgpKSB7XG4gICAgICAgICAgICAgICAgZm14TWV0aG9kLnNldElzUHVibGljKHRydWUpOyAgICBcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZteE1ldGhvZC5zZXRJc1B1YmxpYyhmYWxzZSk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmICghaXNTaWduYXR1cmUpIHtcbiAgICAgICAgICAgICAgICBmbXhNZXRob2Quc2V0Q3ljbG9tYXRpY0NvbXBsZXhpdHkoY3VycmVudENDW2ZteE1ldGhvZC5nZXROYW1lKCldKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZteE1ldGhvZC5zZXRDeWNsb21hdGljQ29tcGxleGl0eSgwKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgbGV0IG1ldGhvZFR5cGVOYW1lID0gdGhpcy5VTktOT1dOX1ZBTFVFOyBcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgbWV0aG9kVHlwZU5hbWUgPSBtZXRob2QuZ2V0UmV0dXJuVHlwZSgpLmdldFRleHQoKS50cmltKCk7ICAgICAgICAgICAgXG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciByZXR1cm4gdHlwZSBvZiBtZXRob2Q6ICR7Zm14TWV0aG9kLmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZm14VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUobWV0aG9kVHlwZU5hbWUsIG1ldGhvZCk7XG4gICAgICAgICAgICBmbXhNZXRob2Quc2V0RGVjbGFyZWRUeXBlKGZteFR5cGUpO1xuICAgICAgICAgICAgZm14TWV0aG9kLnNldE51bWJlck9mTGluZXNPZkNvZGUobWV0aG9kLmdldEVuZExpbmVOdW1iZXIoKSAtIG1ldGhvZC5nZXRTdGFydExpbmVOdW1iZXIoKSk7XG4gICAgICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gbWV0aG9kLmdldFBhcmFtZXRlcnMoKTtcbiAgICAgICAgICAgIGZteE1ldGhvZC5zZXROdW1iZXJPZlBhcmFtZXRlcnMocGFyYW1ldGVycy5sZW5ndGgpO1xuXG4gICAgICAgICAgICBpZiAoIWlzU2lnbmF0dXJlKSB7XG4gICAgICAgICAgICAgICAgZm14TWV0aG9kLnNldE51bWJlck9mU3RhdGVtZW50cyhtZXRob2QuZ2V0U3RhdGVtZW50cygpLmxlbmd0aCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhNZXRob2Quc2V0TnVtYmVyT2ZTdGF0ZW1lbnRzKDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgXG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihtZXRob2QsIGZteE1ldGhvZCk7XG5cbiAgICAgICAgICAgIHRoaXMuZm14RnVuY3Rpb25BbmRNZXRob2RNYXAuc2V0KGZ1bmN0aW9uRnVsbHlRdWFsaWZpZWROYW1lLCBmbXhNZXRob2QpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14TWV0aG9kID0gdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5nZXQoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpIGFzIChGYW1peC5NZXRob2QgfCBGYW1peC5BY2Nlc3NvciB8IEZhbWl4LlBhcmFtZXRyaWNNZXRob2QpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhNZXRob2QsbWV0aG9kKTtcbiAgICAgICAgXG4gICAgICAgIHJldHVybiBmbXhNZXRob2Q7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIGZ1bmMgQSBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBjdXJyZW50Q0MgVGhlIGN5Y2xvbWF0aWMgY29tcGxleGl0eSBtZXRyaWNzIG9mIHRoZSBjdXJyZW50IHNvdXJjZSBmaWxlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBmdW5jdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4RnVuY3Rpb24oZnVuYzogRnVuY3Rpb25EZWNsYXJhdGlvbiB8IEZ1bmN0aW9uRXhwcmVzc2lvbiwgY3VycmVudENDOiB1bmtub3duKTogRmFtaXguRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24ge1xuICAgICAgICBsZXQgZm14RnVuY3Rpb246IEZhbWl4LkZ1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uO1xuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBmdW5jLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDsgICAgICAgIFxuICAgICAgICBjb25zdCBmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oZnVuYyk7XG4gICAgICAgIGlmICghdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5oYXMoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpKSB7XG4gICAgICAgICAgICBpZiAoaXNHZW5lcmljKSB7XG4gICAgICAgICAgICAgICAgZm14RnVuY3Rpb24gPSBuZXcgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhGdW5jdGlvbiA9IG5ldyBGYW1peC5GdW5jdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgIFxuICAgICAgICAgICAgaWYgKGZ1bmMuZ2V0TmFtZSgpKSB7XG4gICAgICAgICAgICAgICAgZm14RnVuY3Rpb24uc2V0TmFtZShmdW5jLmdldE5hbWUoKSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhGdW5jdGlvbi5zZXROYW1lKFwiYW5vbnltb3VzXCIpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5zZXRTaWduYXR1cmUoSGVscGVycy5jb21wdXRlU2lnbmF0dXJlKGZ1bmMuZ2V0VGV4dCgpKSk7XG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5zZXRDeWNsb21hdGljQ29tcGxleGl0eShjdXJyZW50Q0NbZm14RnVuY3Rpb24uZ2V0TmFtZSgpXSk7XG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5zZXRGdWxseVF1YWxpZmllZE5hbWUoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpO1xuICAgIFxuICAgICAgICAgICAgbGV0IGZ1bmN0aW9uVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7XG4gICAgICAgICAgICB0cnkge1xuICAgICAgICAgICAgICAgIGZ1bmN0aW9uVHlwZU5hbWUgPSBmdW5jLmdldFJldHVyblR5cGUoKS5nZXRUZXh0KCkudHJpbSgpO1xuICAgICAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZXJyb3IoYD4gV0FSTklORzogZ290IGV4Y2VwdGlvbiAke2Vycm9yfS4gRmFpbGVkIHRvIGdldCB1c2FibGUgbmFtZSBmb3IgcmV0dXJuIHR5cGUgb2YgZnVuY3Rpb246ICR7ZnVuYy5nZXROYW1lKCl9LiBDb250aW51aW5nLi4uYCk7XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICBjb25zdCBmbXhUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShmdW5jdGlvblR5cGVOYW1lLCBmdW5jKTtcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLnNldERlY2xhcmVkVHlwZShmbXhUeXBlKTtcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLnNldE51bWJlck9mTGluZXNPZkNvZGUoZnVuYy5nZXRFbmRMaW5lTnVtYmVyKCkgLSBmdW5jLmdldFN0YXJ0TGluZU51bWJlcigpKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBmdW5jLmdldFBhcmFtZXRlcnMoKTtcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLnNldE51bWJlck9mUGFyYW1ldGVycyhwYXJhbWV0ZXJzLmxlbmd0aCk7XG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5zZXROdW1iZXJPZlN0YXRlbWVudHMoZnVuYy5nZXRTdGF0ZW1lbnRzKCkubGVuZ3RoKTtcbiAgICBcbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGZ1bmMsIGZteEZ1bmN0aW9uKTtcbiAgICBcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhGdW5jdGlvbik7XG4gICAgXG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEZ1bmN0aW9uLGZ1bmMpO1xuXG4gICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSwgZm14RnVuY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14RnVuY3Rpb24gPSB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmdldChmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgKEZhbWl4LkZ1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbXhGdW5jdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggcGFyYW1ldGVyXG4gICAgICogQHBhcmFtIHBhcmFtIEEgcGFyYW1ldGVyXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhQYXJhbWV0ZXIocGFyYW06IFBhcmFtZXRlckRlY2xhcmF0aW9uKTogRmFtaXguUGFyYW1ldGVyIHtcbiAgICAgICAgY29uc3QgZm14UGFyYW0gPSBuZXcgRmFtaXguUGFyYW1ldGVyKCk7XG5cbiAgICAgICAgbGV0IHBhcmFtVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwYXJhbVR5cGVOYW1lID0gcGFyYW0uZ2V0VHlwZSgpLmdldFRleHQoKS50cmltKCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYD4gV0FSTklORzogZ290IGV4Y2VwdGlvbiAke2Vycm9yfS4gRmFpbGVkIHRvIGdldCB1c2FibGUgbmFtZSBmb3IgcGFyYW1ldGVyOiAke3BhcmFtLmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKHBhcmFtVHlwZU5hbWUsIHBhcmFtKTtcbiAgICAgICAgZm14UGFyYW0uc2V0RGVjbGFyZWRUeXBlKGZteFR5cGUpO1xuICAgICAgICBmbXhQYXJhbS5zZXROYW1lKHBhcmFtLmdldE5hbWUoKSk7XG5cbiAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IocGFyYW0sIGZteFBhcmFtKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14UGFyYW0pO1xuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14UGFyYW0scGFyYW0pO1xuXG4gICAgICAgIHJldHVybiBmbXhQYXJhbTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggdHlwZSBwYXJhbWV0ZXJcbiAgICAgKiBAcGFyYW0gdHAgQSB0eXBlIHBhcmFtZXRlclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgdHlwZSBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhQYXJhbWV0ZXJUeXBlKHRwOiBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24pOiBGYW1peC5QYXJhbWV0ZXJUeXBlIHtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGZteFBhcmFtZXRlclR5cGUgPSBuZXcgRmFtaXguUGFyYW1ldGVyVHlwZSgpO1xuICAgXG4gICAgICAgIGZteFBhcmFtZXRlclR5cGUuc2V0TmFtZSh0cC5nZXROYW1lKCkpOyAgICAgIFxuXG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKHRwLCBmbXhQYXJhbWV0ZXJUeXBlKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14UGFyYW1ldGVyVHlwZSk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhQYXJhbWV0ZXJUeXBlLHRwKTtcblxuICAgICAgICByZXR1cm4gZm14UGFyYW1ldGVyVHlwZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggdHlwZSBwYXJhbWV0ZXJcbiAgICAgKiBAcGFyYW0gdHAgQSB0eXBlIHBhcmFtZXRlclxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgdHlwZSBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlT3JHZXRGYW1peENvbmNyZXRlVHlwZShwYXJhbTogVHlwZU5vZGUpOiBGYW1peC5QYXJhbWV0ZXJUeXBlIHwgRmFtaXguUHJpbWl0aXZlVHlwZSB8IEZhbWl4LkNsYXNzIHwgRmFtaXguSW50ZXJmYWNlIHtcbiAgICAgICAgY29uc3QgdHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uID0gcGFyYW0uZ2V0U3ltYm9sKCk/LmdldERlY2xhcmF0aW9ucygpWzBdIGFzIFR5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbjtcbiAgICAgICAgY29uc3QgcGFyYW1ldGVyVHlwZU5hbWUgOiBzdHJpbmcgPSBwYXJhbS5nZXRUZXh0KCk7XG4gICAgICAgIGxldCBmbXhQYXJhbWV0ZXJUeXBlOiBGYW1peC5UeXBlIHwgRmFtaXguQ2xhc3MgfCBGYW1peC5JbnRlcmZhY2U7XG5cbiAgICAgICAgbGV0IGlzQ2xhc3NPckludGVyZmFjZSA9IGZhbHNlO1xuICAgICAgICBpZiAodGhpcy5mbXhDbGFzc01hcC5oYXMocGFyYW1ldGVyVHlwZU5hbWUpKXtcbiAgICAgICAgICAgIHRoaXMuZm14Q2xhc3NNYXAuZm9yRWFjaCgob2JqLCBuYW1lKSA9PiB7XG4gICAgICAgICAgICAgICAgaWYob2JqIGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0NsYXNzKXtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IHBhcmFtLmdldFRleHQoKSAmJiBvYmouZ2V0R2VuZXJpY1BhcmFtZXRlcnMoKS5zaXplPjApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NsYXNzT3JJbnRlcmZhY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBwYXJhbS5nZXRUZXh0KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NsYXNzT3JJbnRlcmZhY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IFxuICAgICAgICAgICAgICAgIH0gICBcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZiAodGhpcy5mbXhJbnRlcmZhY2VNYXAuaGFzKHBhcmFtZXRlclR5cGVOYW1lKSl7XG4gICAgICAgICAgICB0aGlzLmZteEludGVyZmFjZU1hcC5mb3JFYWNoKChvYmosIG5hbWUpID0+IHtcbiAgICAgICAgICAgICAgICBpZihvYmogaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlKXtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IHBhcmFtLmdldFRleHQoKSAmJiBvYmouZ2V0R2VuZXJpY1BhcmFtZXRlcnMoKS5zaXplPjApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NsYXNzT3JJbnRlcmZhY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBwYXJhbS5nZXRUZXh0KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NsYXNzT3JJbnRlcmZhY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IFxuICAgICAgICAgICAgICAgIH0gICBcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZighaXNDbGFzc09ySW50ZXJmYWNlKXtcbiAgICAgICAgICAgIGlmICghdGhpcy5mbXhUeXBlTWFwLmhhcyhwYXJhbWV0ZXJUeXBlTmFtZSkpIHsgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIChwYXJhbWV0ZXJUeXBlTmFtZSA9PT0gXCJudW1iZXJcIiB8fCBwYXJhbWV0ZXJUeXBlTmFtZSA9PT0gXCJzdHJpbmdcIiB8fCBwYXJhbWV0ZXJUeXBlTmFtZSA9PT0gXCJib29sZWFuXCIgfHwgcGFyYW1ldGVyVHlwZU5hbWUgPT09IFwiYmlnaW50XCIgfHwgcGFyYW1ldGVyVHlwZU5hbWUgPT09IFwic3ltYm9sXCIgfHwgcGFyYW1ldGVyVHlwZU5hbWUgPT09IFwidW5kZWZpbmVkXCIgfHwgcGFyYW1ldGVyVHlwZU5hbWUgPT09IFwibnVsbFwiIHx8IHBhcmFtZXRlclR5cGVOYW1lID09PSBcImFueVwiIHx8IHBhcmFtZXRlclR5cGVOYW1lID09PSBcInVua25vd25cIiB8fCBwYXJhbWV0ZXJUeXBlTmFtZSA9PT0gXCJuZXZlclwiIHx8IHBhcmFtZXRlclR5cGVOYW1lID09PSBcInZvaWRcIikge1xuICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJUeXBlID0gbmV3IEZhbWl4LlByaW1pdGl2ZVR5cGUoKTtcbiAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZS5zZXRJc1N0dWIodHJ1ZSk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZSA9IG5ldyBGYW1peC5QYXJhbWV0ZXJUeXBlKCk7XG4gICAgICAgICAgICAgICAgfSBcbiAgICBcbiAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJUeXBlLnNldE5hbWUocGFyYW1ldGVyVHlwZU5hbWUpO1xuICAgICAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhQYXJhbWV0ZXJUeXBlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZteFR5cGVNYXAuc2V0KHBhcmFtZXRlclR5cGVOYW1lLCBmbXhQYXJhbWV0ZXJUeXBlKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteFBhcmFtZXRlclR5cGUsdHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSB0aGlzLmZteFR5cGVNYXAuZ2V0KHBhcmFtZXRlclR5cGVOYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbXhQYXJhbWV0ZXJUeXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCB2YXJpYWJsZVxuICAgICAqIEBwYXJhbSB2YXJpYWJsZSBBIHZhcmlhYmxlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSB2YXJpYWJsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peFZhcmlhYmxlKHZhcmlhYmxlOiBWYXJpYWJsZURlY2xhcmF0aW9uKTogRmFtaXguVmFyaWFibGUge1xuICAgICAgICBjb25zdCBmbXhWYXJpYWJsZSA9IG5ldyBGYW1peC5WYXJpYWJsZSgpO1xuICAgIFxuICAgICAgICBsZXQgdmFyaWFibGVUeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhcmlhYmxlVHlwZU5hbWUgPSB2YXJpYWJsZS5nZXRUeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciB2YXJpYWJsZTogJHt2YXJpYWJsZS5nZXROYW1lKCl9LiBDb250aW51aW5nLi4uYCk7XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgY29uc3QgZm14VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUodmFyaWFibGVUeXBlTmFtZSwgdmFyaWFibGUpO1xuICAgICAgICBmbXhWYXJpYWJsZS5zZXREZWNsYXJlZFR5cGUoZm14VHlwZSk7XG4gICAgICAgIGZteFZhcmlhYmxlLnNldE5hbWUodmFyaWFibGUuZ2V0TmFtZSgpKTtcbiAgICBcbiAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IodmFyaWFibGUsIGZteFZhcmlhYmxlKTtcbiAgICBcbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFZhcmlhYmxlKTtcbiAgICBcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhWYXJpYWJsZSx2YXJpYWJsZSk7XG4gICAgXG4gICAgICAgIHJldHVybiBmbXhWYXJpYWJsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggZW51bVxuICAgICAqIEBwYXJhbSBlbnVtRW50aXR5IEFuIGVudW1cbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGVudW1cbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhFbnVtKGVudW1FbnRpdHk6IEVudW1EZWNsYXJhdGlvbik6IEZhbWl4LkVudW0ge1xuICAgICAgICBjb25zdCBmbXhFbnVtID0gbmV3IEZhbWl4LkVudW0oKTtcbiAgICAgICAgZm14RW51bS5zZXROYW1lKGVudW1FbnRpdHkuZ2V0TmFtZSgpKTtcblxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihlbnVtRW50aXR5LCBmbXhFbnVtKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14RW51bSk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhFbnVtLGVudW1FbnRpdHkpO1xuXG4gICAgICAgIHJldHVybiBmbXhFbnVtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIGVudW1NZW1iZXIgQW4gZW51bSBtZW1iZXJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGVudW0gbWVtYmVyXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4RW51bVZhbHVlKGVudW1NZW1iZXI6IEVudW1NZW1iZXIpOiBGYW1peC5FbnVtVmFsdWUge1xuICAgICAgICBjb25zdCBmbXhFbnVtVmFsdWUgPSBuZXcgRmFtaXguRW51bVZhbHVlKCk7XG5cbiAgICAgICAgbGV0IGVudW1WYWx1ZVR5cGVOYW1lID0gdGhpcy5VTktOT1dOX1ZBTFVFO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZW51bVZhbHVlVHlwZU5hbWUgPSBlbnVtTWVtYmVyLmdldFR5cGUoKS5nZXRUZXh0KCkudHJpbSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGA+IFdBUk5JTkc6IGdvdCBleGNlcHRpb24gJHtlcnJvcn0uIEZhaWxlZCB0byBnZXQgdXNhYmxlIG5hbWUgZm9yIGVudW0gdmFsdWU6ICR7ZW51bU1lbWJlci5nZXROYW1lKCl9LiBDb250aW51aW5nLi4uYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmbXhUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShlbnVtVmFsdWVUeXBlTmFtZSwgZW51bU1lbWJlcik7XG4gICAgICAgIGZteEVudW1WYWx1ZS5zZXREZWNsYXJlZFR5cGUoZm14VHlwZSk7XG4gICAgICAgIGZteEVudW1WYWx1ZS5zZXROYW1lKGVudW1NZW1iZXIuZ2V0TmFtZSgpKTtcblxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihlbnVtTWVtYmVyLCBmbXhFbnVtVmFsdWUpO1xuXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhFbnVtVmFsdWUpO1xuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14RW51bVZhbHVlLGVudW1NZW1iZXIpO1xuXG4gICAgICAgIHJldHVybiBmbXhFbnVtVmFsdWU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggZGVjb3JhdG9yXG4gICAgICogQHBhcmFtIGRlY29yYXRvciBBIGRlY29yYXRvclxuICAgICAqIEBwYXJhbSBkZWNvcmF0ZWRFbnRpdHkgQSBjbGFzcywgYSBtZXRob2QsIGEgcGFyYW1ldGVyIG9yIGEgcHJvcGVydHlcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGRlY29yYXRvclxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4RGVjb3JhdG9yKGRlY29yYXRvcjogRGVjb3JhdG9yLCBkZWNvcmF0ZWRFbnRpdHk6IENsYXNzRGVjbGFyYXRpb24gfCBNZXRob2REZWNsYXJhdGlvbiB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgUGFyYW1ldGVyRGVjbGFyYXRpb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uKTogRmFtaXguRGVjb3JhdG9yIHtcbiAgICAgICAgY29uc3QgZm14RGVjb3JhdG9yID0gbmV3IEZhbWl4LkRlY29yYXRvcigpO1xuICAgICAgICBjb25zdCBkZWNvcmF0b3JOYW1lID0gXCJAXCIgKyBkZWNvcmF0b3IuZ2V0TmFtZSgpO1xuICAgICAgICBjb25zdCBkZWNvcmF0b3JFeHByZXNzaW9uID0gZGVjb3JhdG9yLmdldFRleHQoKS5zdWJzdHJpbmcoMSk7XG5cbiAgICAgICAgZm14RGVjb3JhdG9yLnNldE5hbWUoZGVjb3JhdG9yTmFtZSk7XG4gICAgICAgIGZteERlY29yYXRvci5zZXREZWNvcmF0b3JFeHByZXNzaW9uKGRlY29yYXRvckV4cHJlc3Npb24pO1xuICAgICAgICBjb25zdCBkZWNvcmF0ZWRFbnRpdHlGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGRlY29yYXRlZEVudGl0eSk7XG4gICAgICAgIGNvbnN0IGZteERlY29yYXRlZEVudGl0eSA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShkZWNvcmF0ZWRFbnRpdHlGdWxseVF1YWxpZmllZE5hbWUpIGFzIEZhbWl4Lk5hbWVkRW50aXR5O1xuICAgICAgICBmbXhEZWNvcmF0b3Iuc2V0RGVjb3JhdGVkRW50aXR5KGZteERlY29yYXRlZEVudGl0eSk7XG5cbiAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoZGVjb3JhdG9yLCBmbXhEZWNvcmF0b3IpO1xuXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhEZWNvcmF0b3IpO1xuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14RGVjb3JhdG9yLGRlY29yYXRvcik7XG5cbiAgICAgICAgcmV0dXJuIGZteERlY29yYXRvcjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggY29tbWVudFxuICAgICAqIEBwYXJhbSBjb21tZW50IEEgY29tbWVudFxuICAgICAqIEBwYXJhbSBmbXhTY29wZSBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGNvbW1lbnQncyBjb250YWluZXJcbiAgICAgKiBAcGFyYW0gaXNKU0RvYyBBIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgY29tbWVudCBpcyBhIEpTRG9jXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBjb21tZW50XG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4Q29tbWVudChjb21tZW50OiBDb21tZW50UmFuZ2UsIGZteFNjb3BlOiBGYW1peC5OYW1lZEVudGl0eSwgaXNKU0RvYzogYm9vbGVhbik6IEZhbWl4LkNvbW1lbnQge1xuICAgICAgICBsb2dnZXIuZGVidWcoYD4gTk9URTogY3JlYXRpbmcgY29tbWVudCAke2NvbW1lbnQuZ2V0VGV4dCgpfSBpbiBzY29wZSAke2ZteFNjb3BlLmdldE5hbWUoKX0uYCk7XG4gICAgICAgIGNvbnN0IGZteENvbW1lbnQgPSBuZXcgRmFtaXguQ29tbWVudCgpO1xuICAgICAgICBmbXhDb21tZW50LnNldENvbnRhaW5lcihmbXhTY29wZSk7ICAvLyBhZGRzIGNvbW1lbnQgdG8gdGhlIGNvbnRhaW5lcidzIGNvbW1lbnRzIGNvbGxlY3Rpb25cbiAgICAgICAgZm14Q29tbWVudC5zZXRJc0pTRG9jKGlzSlNEb2MpO1xuXG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGNvbW1lbnQsIGZteENvbW1lbnQpO1xuXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhDb21tZW50KTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteENvbW1lbnQsY29tbWVudCk7XG5cbiAgICAgICAgcmV0dXJuIGZteENvbW1lbnQ7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggdHlwZVxuICAgICAqIEBwYXJhbSB0eXBlTmFtZSBBIHR5cGUgbmFtZVxuICAgICAqIEBwYXJhbSBlbGVtZW50IEEgdHMtbW9ycGggZWxlbWVudFxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgdHlwZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4VHlwZSh0eXBlTmFtZTogc3RyaW5nLCBlbGVtZW50OiBUeXBlRGVjbGFyYXRpb24pOiBGYW1peC5UeXBlIHwgRmFtaXguUHJpbWl0aXZlVHlwZSB8IEZhbWl4LlBhcmFtZXRlclR5cGUge1xuICAgICAgICBsZXQgZm14VHlwZTogRmFtaXguVHlwZSB8IEZhbWl4LlByaW1pdGl2ZVR5cGUgfCBGYW1peC5QYXJhbWV0ZXJUeXBlO1xuICAgICAgICBsZXQgaXNQcmltaXRpdmVUeXBlID0gZmFsc2U7XG4gICAgICAgIGxldCBpc1BhcmFtZXRlclR5cGUgPSBmYWxzZTtcblxuICAgICAgICBsb2dnZXIuZGVidWcoXCJDcmVhdGluZyAob3IgZ2V0dGluZykgdHlwZTogJ1wiICsgdHlwZU5hbWUgKyBcIicgb2YgZWxlbWVudDogXCIgKyBlbGVtZW50Py5nZXRUZXh0KCkgKyBcIiBvZiBraW5kOiBcIiArIGVsZW1lbnQ/LmdldEtpbmROYW1lKCkpO1xuICAgICAgICBsZXQgYW5jZXN0b3I6IEZhbWl4LkNvbnRhaW5lckVudGl0eTtcbiAgICAgICAgaWYgKGVsZW1lbnQgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgY29uc3QgdHlwZUFuY2VzdG9yID0gSGVscGVycy5maW5kVHlwZUFuY2VzdG9yKGVsZW1lbnQpO1xuICAgICAgICAgICAgaWYgKCF0eXBlQW5jZXN0b3IpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEFuY2VzdG9yIG5vdCBmb3VuZCBmb3IgZWxlbWVudCAke2VsZW1lbnQuZ2V0VGV4dCgpfS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGNvbnN0IGFuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTih0eXBlQW5jZXN0b3IpO1xuICAgICAgICAgICAgYW5jZXN0b3IgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUoYW5jZXN0b3JGdWxseVF1YWxpZmllZE5hbWUpIGFzIEZhbWl4LkNvbnRhaW5lckVudGl0eTtcbiAgICAgICAgICAgIGlmICghYW5jZXN0b3IpIHtcbiAgICAgICAgICAgICAgICBsb2dnZXIuZGVidWcoYEFuY2VzdG9yICR7RlFORnVuY3Rpb25zLmdldEZRTih0eXBlQW5jZXN0b3IpfSBub3QgZm91bmQuIEFkZGluZyB0aGUgbmV3IHR5cGUuYCk7XG4gICAgICAgICAgICAgICAgYW5jZXN0b3IgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKHR5cGVBbmNlc3Rvci5nZXRUZXh0KCksIHR5cGVBbmNlc3RvciBhcyBUeXBlRGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHR5cGVOYW1lID09PSBcIm51bWJlclwiIHx8IHR5cGVOYW1lID09PSBcInN0cmluZ1wiIHx8IHR5cGVOYW1lID09PSBcImJvb2xlYW5cIiB8fCB0eXBlTmFtZSA9PT0gXCJiaWdpbnRcIiB8fCB0eXBlTmFtZSA9PT0gXCJzeW1ib2xcIiB8fCB0eXBlTmFtZSA9PT0gXCJ1bmRlZmluZWRcIiB8fCB0eXBlTmFtZSA9PT0gXCJudWxsXCIgfHwgdHlwZU5hbWUgPT09IFwiYW55XCIgfHwgdHlwZU5hbWUgPT09IFwidW5rbm93blwiIHx8IHR5cGVOYW1lID09PSBcIm5ldmVyXCIgfHwgdHlwZU5hbWUgPT09IFwidm9pZFwiKSB7XG4gICAgICAgICAgICBpc1ByaW1pdGl2ZVR5cGUgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYoIWlzUHJpbWl0aXZlVHlwZSAmJiB0eXBlTmFtZS5pbmNsdWRlcyhcIjxcIikgJiYgdHlwZU5hbWUuaW5jbHVkZXMoXCI+XCIpICYmICEodHlwZU5hbWUuaW5jbHVkZXMoXCI9PlwiKSkpIHtcbiAgICAgICAgICAgIGlzUGFyYW1ldGVyVHlwZSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpZiAoIXRoaXMuZm14VHlwZU1hcC5oYXModHlwZU5hbWUpKSB7XG4gICAgICAgICAgICBpZiAoaXNQcmltaXRpdmVUeXBlKSB7XG4gICAgICAgICAgICAgICAgZm14VHlwZSA9IG5ldyBGYW1peC5QcmltaXRpdmVUeXBlKCk7XG4gICAgICAgICAgICAgICAgZm14VHlwZS5zZXRJc1N0dWIodHJ1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIGlmIChpc1BhcmFtZXRlclR5cGUpIHtcbiAgICAgICAgICAgICAgICBmbXhUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRlclR5cGUoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBwYXJhbWV0ZXJUeXBlTmFtZXMgPSB0eXBlTmFtZS5zdWJzdHJpbmcodHlwZU5hbWUuaW5kZXhPZihcIjxcIikgKyAxLCB0eXBlTmFtZS5pbmRleE9mKFwiPlwiKSkuc3BsaXQoXCIsXCIpLm1hcChzID0+IHMudHJpbSgpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBiYXNlVHlwZU5hbWUgPSB0eXBlTmFtZS5zdWJzdHJpbmcoMCwgdHlwZU5hbWUuaW5kZXhPZihcIjxcIikpLnRyaW0oKTtcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJUeXBlTmFtZXMuZm9yRWFjaChwYXJhbWV0ZXJUeXBlTmFtZSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGZteFBhcmFtZXRlclR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKHBhcmFtZXRlclR5cGVOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgKGZteFR5cGUgYXMgRmFtaXguUGFyYW1ldGVyVHlwZSkuYWRkQXJndW1lbnQoZm14UGFyYW1ldGVyVHlwZSk7XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICAgICAgY29uc3QgZm14QmFzZVR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGJhc2VUeXBlTmFtZSwgZWxlbWVudCk7XG4gICAgICAgICAgICAgICAgKGZteFR5cGUgYXMgRmFtaXguUGFyYW1ldGVyVHlwZSkuc2V0QmFzZVR5cGUoZm14QmFzZVR5cGUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm14VHlwZSA9IG5ldyBGYW1peC5UeXBlKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZteFR5cGUuc2V0TmFtZSh0eXBlTmFtZSk7XG4gICAgICAgICAgICBmbXhUeXBlLnNldENvbnRhaW5lcihhbmNlc3Rvcik7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGVsZW1lbnQsIGZteFR5cGUpO1xuXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14VHlwZSk7XG5cbiAgICAgICAgICAgIHRoaXMuZm14VHlwZU1hcC5zZXQodHlwZU5hbWUsIGZteFR5cGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14VHlwZSA9IHRoaXMuZm14VHlwZU1hcC5nZXQodHlwZU5hbWUpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhUeXBlLGVsZW1lbnQpO1xuXG4gICAgICAgIHJldHVybiBmbXhUeXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBhY2Nlc3NcbiAgICAgKiBAcGFyYW0gbm9kZSBBIG5vZGVcbiAgICAgKiBAcGFyYW0gaWQgQW4gaWQgb2YgYSBwYXJhbWV0ZXIsIGEgdmFyaWFibGUsIGEgcHJvcGVydHkgb3IgYW4gZW51bSBtZW1iZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhBY2Nlc3Mobm9kZTogSWRlbnRpZmllciwgaWQ6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBmbXhWYXIgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlJZChpZCkgYXMgRmFtaXguU3RydWN0dXJhbEVudGl0eTtcbiAgICAgICAgaWYgKCFmbXhWYXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggZW50aXR5IHdpdGggaWQgJHtpZH0gbm90IGZvdW5kLCBmb3Igbm9kZSAke25vZGUuZ2V0VGV4dCgpfSBpbiAke25vZGUuZ2V0U291cmNlRmlsZSgpLmdldEJhc2VOYW1lKCl9IGF0IGxpbmUgJHtub2RlLmdldFN0YXJ0TGluZU51bWJlcigpfS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgQ3JlYXRpbmcgRmFtaXhBY2Nlc3MuIE5vZGU6IFske25vZGUuZ2V0S2luZE5hbWUoKX1dICcke25vZGUuZ2V0VGV4dCgpfScgYXQgbGluZSAke25vZGUuZ2V0U3RhcnRMaW5lTnVtYmVyKCl9IGluICR7bm9kZS5nZXRTb3VyY2VGaWxlKCkuZ2V0QmFzZU5hbWUoKX0sIGlkOiAke2lkfSByZWZlcnMgdG8gZm14VmFyICcke2ZteFZhci5nZXRGdWxseVF1YWxpZmllZE5hbWUoKX0nLmApO1xuXG4gICAgICAgIGNvbnN0IG5vZGVSZWZlcmVuY2VBbmNlc3RvciA9IEhlbHBlcnMuZmluZEFuY2VzdG9yKG5vZGUpO1xuICAgICAgICBjb25zdCBhbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4obm9kZVJlZmVyZW5jZUFuY2VzdG9yKTtcbiAgICAgICAgbGV0IGFjY2Vzc29yID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lKGFuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lKSBhcyBGYW1peC5Db250YWluZXJFbnRpdHk7XG4gICAgICAgIGlmICghYWNjZXNzb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgQW5jZXN0b3IgJHthbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZX0gb2Yga2luZCAke25vZGVSZWZlcmVuY2VBbmNlc3Rvci5nZXRLaW5kTmFtZSgpfSBub3QgZm91bmQuYCk7XG4gICAgICAgICAgICAvLyBhY2Nlc3NvciA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoYW5jZXN0b3JGdWxseVF1YWxpZmllZE5hbWUsIG5vZGVSZWZlcmVuY2VBbmNlc3RvciBhcyBUeXBlRGVjbGFyYXRpb24pO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgZm14QWNjZXNzID0gbmV3IEZhbWl4LkFjY2VzcygpO1xuICAgICAgICBmbXhBY2Nlc3Muc2V0QWNjZXNzb3IoYWNjZXNzb3IpO1xuICAgICAgICBmbXhBY2Nlc3Muc2V0VmFyaWFibGUoZm14VmFyKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14QWNjZXNzKTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEFjY2Vzcyxub2RlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggaW52b2NhdGlvblxuICAgICAqIEBwYXJhbSBub2RlIEEgbm9kZVxuICAgICAqIEBwYXJhbSBtIEEgbWV0aG9kIG9yIGEgZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBtZXRob2Qgb3IgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4SW52b2NhdGlvbihub2RlOiBJZGVudGlmaWVyLCBtOiBNZXRob2REZWNsYXJhdGlvbiB8IENvbnN0cnVjdG9yRGVjbGFyYXRpb24gfCBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24sIGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZm14TWV0aG9kT3JGdW5jdGlvbiA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUlkKGlkKSBhcyBGYW1peC5CZWhhdmlvcmFsRW50aXR5O1xuICAgICAgICBjb25zdCBub2RlUmVmZXJlbmNlQW5jZXN0b3IgPSBIZWxwZXJzLmZpbmRBbmNlc3Rvcihub2RlKTtcbiAgICAgICAgY29uc3QgYW5jZXN0b3JGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKG5vZGVSZWZlcmVuY2VBbmNlc3Rvcik7XG4gICAgICAgIGNvbnN0IHNlbmRlciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShhbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgRmFtaXguQ29udGFpbmVyRW50aXR5O1xuICAgICAgICBjb25zdCByZWNlaXZlckZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4obS5nZXRQYXJlbnQoKSk7XG4gICAgICAgIGNvbnN0IHJlY2VpdmVyID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lKHJlY2VpdmVyRnVsbHlRdWFsaWZpZWROYW1lKSBhcyBGYW1peC5OYW1lZEVudGl0eTtcblxuICAgICAgICBjb25zdCBmbXhJbnZvY2F0aW9uID0gbmV3IEZhbWl4Lkludm9jYXRpb24oKTtcbiAgICAgICAgZm14SW52b2NhdGlvbi5zZXRTZW5kZXIoc2VuZGVyKTtcbiAgICAgICAgZm14SW52b2NhdGlvbi5zZXRSZWNlaXZlcihyZWNlaXZlcik7XG4gICAgICAgIGZteEludm9jYXRpb24uYWRkQ2FuZGlkYXRlKGZteE1ldGhvZE9yRnVuY3Rpb24pO1xuICAgICAgICBmbXhJbnZvY2F0aW9uLnNldFNpZ25hdHVyZShmbXhNZXRob2RPckZ1bmN0aW9uLmdldFNpZ25hdHVyZSgpKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW52b2NhdGlvbik7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhJbnZvY2F0aW9uLG5vZGUpO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBpbmhlcml0YW5jZVxuICAgICAqIEBwYXJhbSBjbHMgQSBjbGFzcyBvciBhbiBpbnRlcmZhY2UgKHN1YmNsYXNzKVxuICAgICAqIEBwYXJhbSBpbmhDbGFzcyBUaGUgaW5oZXJpdGVkIGNsYXNzIG9yIGludGVyZmFjZSAoc3VwZXJjbGFzcylcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhJbmhlcml0YW5jZShjbHM6IENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbiwgaW5oQ2xhc3M6IENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cyk6IHZvaWQge1xuICAgICAgICBjb25zdCBmbXhJbmhlcml0YW5jZSA9IG5ldyBGYW1peC5Jbmhlcml0YW5jZSgpO1xuICAgICAgICAvLyBjb25zdCBjbHNOYW1lID0gY2xzLmdldE5hbWUoKTtcbiAgICAgICAgY29uc3QgY2xhc3NGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGNscyk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgY3JlYXRlRmFtaXhJbmhlcml0YW5jZTogY2xhc3NGdWxseVF1YWxpZmllZE5hbWU6IGNsYXNzIGZxbiA9ICR7Y2xhc3NGdWxseVF1YWxpZmllZE5hbWV9YCk7XG4gICAgICAgIGxldCBzdWJDbGFzczogRmFtaXguQ2xhc3MgfCBGYW1peC5JbnRlcmZhY2U7XG4gICAgICAgIGlmIChjbHMgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICBzdWJDbGFzcyA9IHRoaXMuZm14Q2xhc3NNYXAuZ2V0KGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIHN1YkNsYXNzID0gdGhpcy5mbXhJbnRlcmZhY2VNYXAuZ2V0KGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lKTtcbiAgICAgICAgfVxuICAgICAgICBcbiAgICAgICAgbGV0IGluaENsYXNzTmFtZTogc3RyaW5nO1xuICAgICAgICBsZXQgaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWU6IHN0cmluZztcbiAgICAgICAgbGV0IHN1cGVyQ2xhc3M6IEZhbWl4LkNsYXNzIHwgRmFtaXguSW50ZXJmYWNlO1xuICAgICAgICBpZiAoaW5oQ2xhc3MgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uIHx8IGluaENsYXNzIGluc3RhbmNlb2YgSW50ZXJmYWNlRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgIGluaENsYXNzTmFtZSA9IGluaENsYXNzLmdldE5hbWUoKTtcbiAgICAgICAgICAgIGluaENsYXNzRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihpbmhDbGFzcyk7XG4gICAgICAgICAgICBpZiAoaW5oQ2xhc3MgaW5zdGFuY2VvZiBDbGFzc0RlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICAgICAgc3VwZXJDbGFzcyA9IHRoaXMuZm14Q2xhc3NNYXAuZ2V0KGluaENsYXNzRnVsbHlRdWFsaWZpZWROYW1lKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIHN1cGVyQ2xhc3MgPSB0aGlzLmZteEludGVyZmFjZU1hcC5nZXQoaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gaW5oQ2xhc3MgaXMgYW4gRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzXG4gICAgICAgICAgICBpbmhDbGFzc05hbWUgPSBpbmhDbGFzcy5nZXRFeHByZXNzaW9uKCkuZ2V0VGV4dCgpO1xuICAgICAgICAgICAgLy8gd2hhdCBpcyBpbmhDbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZT8gVE9ET1xuICAgICAgICAgICAgaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUgPSAnVW5kZWZpbmVkX1Njb3BlX2Zyb21faW1wb3J0ZXIuJyArIGluaENsYXNzTmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdXBlckNsYXNzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChpbmhDbGFzcyBpbnN0YW5jZW9mIENsYXNzRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgICAgICBzdXBlckNsYXNzID0gbmV3IEZhbWl4LkNsYXNzKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5mbXhDbGFzc01hcC5zZXQoaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUsIHN1cGVyQ2xhc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3VwZXJDbGFzcyA9IG5ldyBGYW1peC5JbnRlcmZhY2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZteEludGVyZmFjZU1hcC5zZXQoaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUsIHN1cGVyQ2xhc3MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KHN1cGVyQ2xhc3MsaW5oQ2xhc3MpO1xuXG4gICAgICAgICAgICBzdXBlckNsYXNzLnNldE5hbWUoaW5oQ2xhc3NOYW1lKTtcbiAgICAgICAgICAgIHN1cGVyQ2xhc3Muc2V0RnVsbHlRdWFsaWZpZWROYW1lKGluaENsYXNzRnVsbHlRdWFsaWZpZWROYW1lKTtcbiAgICAgICAgICAgIHN1cGVyQ2xhc3Muc2V0SXNTdHViKHRydWUpO1xuXG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihpbmhDbGFzcywgc3VwZXJDbGFzcyk7XG4gICAgICAgIFxuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KHN1cGVyQ2xhc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm14SW5oZXJpdGFuY2Uuc2V0U3ViY2xhc3Moc3ViQ2xhc3MpO1xuICAgICAgICBmbXhJbmhlcml0YW5jZS5zZXRTdXBlcmNsYXNzKHN1cGVyQ2xhc3MpO1xuXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhJbmhlcml0YW5jZSk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhJbmhlcml0YW5jZSxudWxsKTtcblxuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVGYW1peEltcG9ydENsYXVzZShpbXBvcnRlZEVudGl0eTogRmFtaXguTmFtZWRFbnRpdHksIGltcG9ydGluZ0VudGl0eTogRmFtaXguTW9kdWxlKSB7XG4gICAgICAgIGNvbnN0IGZteEltcG9ydENsYXVzZSA9IG5ldyBGYW1peC5JbXBvcnRDbGF1c2UoKTtcbiAgICAgICAgZm14SW1wb3J0Q2xhdXNlLnNldEltcG9ydGVkRW50aXR5KGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgZm14SW1wb3J0Q2xhdXNlLnNldEltcG9ydGluZ0VudGl0eShpbXBvcnRpbmdFbnRpdHkpO1xuICAgICAgICBpbXBvcnRpbmdFbnRpdHkuYWRkT3V0Z29pbmdJbXBvcnQoZm14SW1wb3J0Q2xhdXNlKTtcbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEltcG9ydENsYXVzZSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGltcG9ydCBjbGF1c2VcbiAgICAgKiBAcGFyYW0gaW1wb3J0Q2xhdXNlSW5mbyBUaGUgaW5mb3JtYXRpb24gbmVlZGVkIHRvIGNyZWF0ZSBhIEZhbWl4IGltcG9ydCBjbGF1c2VcbiAgICAgKiBAcGFyYW0gaW1wb3J0RGVjbGFyYXRpb24gVGhlIGltcG9ydCBkZWNsYXJhdGlvblxuICAgICAqIEBwYXJhbSBpbXBvcnRlciBBIHNvdXJjZSBmaWxlIHdoaWNoIGlzIGEgbW9kdWxlXG4gICAgICogQHBhcmFtIG1vZHVsZVNwZWNpZmllckZpbGVQYXRoIFRoZSBwYXRoIG9mIHRoZSBtb2R1bGUgd2hlcmUgdGhlIGV4cG9ydCBkZWNsYXJhdGlvbiBpc1xuICAgICAqIEBwYXJhbSBpbXBvcnRFbGVtZW50IFRoZSBpbXBvcnRlZCBlbnRpdHlcbiAgICAgKiBAcGFyYW0gaXNJbkV4cG9ydHMgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIGltcG9ydGVkIGVudGl0eSBpcyBpbiB0aGUgZXhwb3J0c1xuICAgICAqIEBwYXJhbSBpc0RlZmF1bHRFeHBvcnQgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIGltcG9ydGVkIGVudGl0eSBpcyBhIGRlZmF1bHQgZXhwb3J0XG4gICAgICovXG4gICAgcHVibGljIG9sZENyZWF0ZUZhbWl4SW1wb3J0Q2xhdXNlKGltcG9ydENsYXVzZUluZm86IHtpbXBvcnREZWNsYXJhdGlvbj86IEltcG9ydERlY2xhcmF0aW9uIHwgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24sIGltcG9ydGVyU291cmNlRmlsZTogU291cmNlRmlsZSwgbW9kdWxlU3BlY2lmaWVyRmlsZVBhdGg6IHN0cmluZywgaW1wb3J0RWxlbWVudDogSW1wb3J0U3BlY2lmaWVyIHwgSWRlbnRpZmllciwgaXNJbkV4cG9ydHM6IGJvb2xlYW4sIGlzRGVmYXVsdEV4cG9ydDogYm9vbGVhbn0pOiB2b2lkIHtcbiAgICAgICAgY29uc3Qge2ltcG9ydERlY2xhcmF0aW9uLCBpbXBvcnRlclNvdXJjZUZpbGU6IGltcG9ydGVyLCBtb2R1bGVTcGVjaWZpZXJGaWxlUGF0aCwgaW1wb3J0RWxlbWVudCwgaXNJbkV4cG9ydHMsIGlzRGVmYXVsdEV4cG9ydH0gPSBpbXBvcnRDbGF1c2VJbmZvO1xuICAgICAgICBsb2dnZXIuZGVidWcoYGNyZWF0ZUZhbWl4SW1wb3J0Q2xhdXNlOiBDcmVhdGluZyBpbXBvcnQgY2xhdXNlOmApO1xuICAgICAgICBjb25zdCBmbXhJbXBvcnRDbGF1c2UgPSBuZXcgRmFtaXguSW1wb3J0Q2xhdXNlKCk7XG5cbiAgICAgICAgbGV0IGltcG9ydGVkRW50aXR5OiBGYW1peC5OYW1lZEVudGl0eSB8IEZhbWl4LlN0cnVjdHVyYWxFbnRpdHk7XG4gICAgICAgIGxldCBpbXBvcnRlZEVudGl0eU5hbWU6IHN0cmluZztcblxuICAgICAgICBjb25zdCBhYnNvbHV0ZVBhdGhQcm9qZWN0ID0gdGhpcy5mYW1peFJlcC5nZXRBYnNvbHV0ZVBhdGgoKTtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGFic29sdXRlUGF0aCA9IHBhdGgubm9ybWFsaXplKG1vZHVsZVNwZWNpZmllckZpbGVQYXRoKTtcbiAgICAgICAgLy8gY29udmVydCB0aGUgcGF0aCBhbmQgcmVtb3ZlIGFueSB3aW5kb3dzIGJhY2tzbGFzaGVzIGludHJvZHVjZWQgYnkgcGF0aC5ub3JtYWxpemVcbiAgICAgICAgY29uc3QgcGF0aEluUHJvamVjdDogc3RyaW5nID0gdGhpcy5jb252ZXJ0VG9SZWxhdGl2ZVBhdGgoYWJzb2x1dGVQYXRoLCBhYnNvbHV0ZVBhdGhQcm9qZWN0KS5yZXBsYWNlKC9cXFxcL2csIFwiL1wiKTtcbiAgICAgICAgbGV0IHBhdGhOYW1lID0gXCJ7XCIgKyBwYXRoSW5Qcm9qZWN0ICsgXCJ9LlwiO1xuXG4gICAgICAgIC8vIE5hbWVkIGltcG9ydHMsIGUuZy4gaW1wb3J0IHsgQ2xhc3NXIH0gZnJvbSBcIi4vY29tcGxleEV4cG9ydE1vZHVsZVwiO1xuXG4gICAgICAgIC8vIFN0YXJ0IHdpdGggc2ltcGxlIGltcG9ydCBjbGF1c2UgKHdpdGhvdXQgcmVmZXJyaW5nIHRvIHRoZSBhY3R1YWwgdmFyaWFibGUpXG5cbiAgICAgICAgaWYgKGltcG9ydERlY2xhcmF0aW9uIGluc3RhbmNlb2YgSW1wb3J0RGVjbGFyYXRpb24gXG4gICAgICAgICAgICAmJiBpbXBvcnRFbGVtZW50IGluc3RhbmNlb2YgSW1wb3J0U3BlY2lmaWVyKSB7IFxuICAgICAgICAgICAgICAgIGltcG9ydGVkRW50aXR5TmFtZSA9IGltcG9ydEVsZW1lbnQuZ2V0TmFtZSgpO1xuICAgICAgICAgICAgcGF0aE5hbWUgPSBwYXRoTmFtZSArIGltcG9ydGVkRW50aXR5TmFtZTtcbiAgICAgICAgICAgIGlmIChpc0luRXhwb3J0cykge1xuICAgICAgICAgICAgICAgIGltcG9ydGVkRW50aXR5ID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lKHBhdGhOYW1lKSBhcyBGYW1peC5OYW1lZEVudGl0eTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGlmIChpbXBvcnRlZEVudGl0eSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSBuZXcgRmFtaXguTmFtZWRFbnRpdHkoKTtcbiAgICAgICAgICAgICAgICBpbXBvcnRlZEVudGl0eS5zZXROYW1lKGltcG9ydGVkRW50aXR5TmFtZSk7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0luRXhwb3J0cykge1xuICAgICAgICAgICAgICAgICAgICBpbXBvcnRlZEVudGl0eS5zZXRJc1N0dWIodHJ1ZSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGltcG9ydEVsZW1lbnQsIGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgICAgICBpbXBvcnRlZEVudGl0eS5zZXRGdWxseVF1YWxpZmllZE5hbWUocGF0aE5hbWUpO1xuICAgICAgICAgICAgICAgIC8vIG11c3QgYWRkIGVudGl0eSB0byByZXBvc2l0b3J5XG4gICAgICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICAvLyBoYW5kbGUgaW1wb3J0IGVxdWFscyBkZWNsYXJhdGlvbnMsIGUuZy4gaW1wb3J0IG15TW9kdWxlID0gcmVxdWlyZShcIi4vY29tcGxleEV4cG9ydE1vZHVsZVwiKTtcbiAgICAgICAgLy8gVHlwZVNjcmlwdCBjYW4ndCBkZXRlcm1pbmUgdGhlIHR5cGUgb2YgdGhlIGltcG9ydGVkIG1vZHVsZSwgc28gd2UgY3JlYXRlIGEgTW9kdWxlIGVudGl0eVxuICAgICAgICBlbHNlIGlmIChpbXBvcnREZWNsYXJhdGlvbiBpbnN0YW5jZW9mIEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICBpbXBvcnRlZEVudGl0eU5hbWUgPSBpbXBvcnREZWNsYXJhdGlvbj8uZ2V0TmFtZSgpO1xuICAgICAgICAgICAgcGF0aE5hbWUgPSBwYXRoTmFtZSArIGltcG9ydGVkRW50aXR5TmFtZTtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5ID0gbmV3IEZhbWl4LlN0cnVjdHVyYWxFbnRpdHkoKTtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5LnNldE5hbWUoaW1wb3J0ZWRFbnRpdHlOYW1lKTtcbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGltcG9ydEVsZW1lbnQsIGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5LnNldEZ1bGx5UXVhbGlmaWVkTmFtZShwYXRoTmFtZSk7XG4gICAgICAgICAgICBjb25zdCBhbnlUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZSgnYW55JywgdW5kZWZpbmVkKTtcbiAgICAgICAgICAgIChpbXBvcnRlZEVudGl0eSBhcyBGYW1peC5TdHJ1Y3R1cmFsRW50aXR5KS5zZXREZWNsYXJlZFR5cGUoYW55VHlwZSk7XG4gICAgICAgIH0gZWxzZSB7ICAvLyBkZWZhdWx0IGltcG9ydHMsIGUuZy4gaW1wb3J0IENsYXNzVyBmcm9tIFwiLi9jb21wbGV4RXhwb3J0TW9kdWxlXCI7ICBcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5TmFtZSA9IGltcG9ydEVsZW1lbnQuZ2V0VGV4dCgpO1xuICAgICAgICAgICAgcGF0aE5hbWUgPSBwYXRoTmFtZSArIChpc0RlZmF1bHRFeHBvcnQgPyBcImRlZmF1bHRFeHBvcnRcIiA6IFwibmFtZXNwYWNlRXhwb3J0XCIpO1xuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSBuZXcgRmFtaXguTmFtZWRFbnRpdHkoKTtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5LnNldE5hbWUoaW1wb3J0ZWRFbnRpdHlOYW1lKTtcbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGltcG9ydEVsZW1lbnQsIGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5LnNldEZ1bGx5UXVhbGlmaWVkTmFtZShwYXRoTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSSBkb24ndCB0aGluayBpdCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIHJlcG9zaXRvcnkgaWYgaXQgZXhpc3RzIGFscmVhZHlcbiAgICAgICAgaWYgKCFpc0luRXhwb3J0cykgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgY29uc3QgaW1wb3J0ZXJGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGltcG9ydGVyKTtcbiAgICAgICAgY29uc3QgZm14SW1wb3J0ZXIgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUoaW1wb3J0ZXJGdWxseVF1YWxpZmllZE5hbWUpIGFzIEZhbWl4Lk1vZHVsZTtcbiAgICAgICAgZm14SW1wb3J0Q2xhdXNlLnNldEltcG9ydGluZ0VudGl0eShmbXhJbXBvcnRlcik7XG4gICAgICAgIGZteEltcG9ydENsYXVzZS5zZXRJbXBvcnRlZEVudGl0eShpbXBvcnRlZEVudGl0eSk7XG4gICAgICAgIGlmIChpbXBvcnREZWNsYXJhdGlvbiBpbnN0YW5jZW9mIEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICBmbXhJbXBvcnRDbGF1c2Uuc2V0TW9kdWxlU3BlY2lmaWVyKGltcG9ydERlY2xhcmF0aW9uPy5nZXRNb2R1bGVSZWZlcmVuY2UoKS5nZXRUZXh0KCkgYXMgc3RyaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZteEltcG9ydENsYXVzZS5zZXRNb2R1bGVTcGVjaWZpZXIoaW1wb3J0RGVjbGFyYXRpb24/LmdldE1vZHVsZVNwZWNpZmllclZhbHVlKCkgYXMgc3RyaW5nKTtcbiAgICAgICAgfVxuICAgIFxuICAgICAgICBsb2dnZXIuZGVidWcoYGNyZWF0ZUZhbWl4SW1wb3J0Q2xhdXNlOiAke2ZteEltcG9ydENsYXVzZS5nZXRJbXBvcnRlZEVudGl0eSgpPy5nZXROYW1lKCl9IChvZiB0eXBlICR7XG4gICAgICAgICAgICBIZWxwZXJzLmdldFN1YlR5cGVOYW1lKGZteEltcG9ydENsYXVzZS5nZXRJbXBvcnRlZEVudGl0eSgpKX0pIGlzIGltcG9ydGVkIGJ5ICR7Zm14SW1wb3J0Q2xhdXNlLmdldEltcG9ydGluZ0VudGl0eSgpPy5nZXROYW1lKCl9YCk7XG5cbiAgICAgICAgZm14SW1wb3J0ZXIuYWRkT3V0Z29pbmdJbXBvcnQoZm14SW1wb3J0Q2xhdXNlKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW1wb3J0Q2xhdXNlKTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEltcG9ydENsYXVzZSxpbXBvcnREZWNsYXJhdGlvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IEFycm93IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIGFycm93RXhwcmVzc2lvbiBBbiBFeHByZXNzaW9uXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSB2YXJpYWJsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peEFycm93RnVuY3Rpb24oYXJyb3dFeHByZXNzaW9uOiBFeHByZXNzaW9uICxjdXJyZW50Q0M6IHVua25vd24pOiBGYW1peC5BcnJvd0Z1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Fycm93RnVuY3Rpb24ge1xuICAgICAgICBcbiAgICAgICAgbGV0IGZteEFycm93RnVuY3Rpb246IEZhbWl4LkFycm93RnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljQXJyb3dGdW5jdGlvbjtcblxuICAgICAgICBjb25zdCBhcnJvd0Z1bmN0aW9uID0gYXJyb3dFeHByZXNzaW9uLmFzS2luZE9yVGhyb3coU3ludGF4S2luZC5BcnJvd0Z1bmN0aW9uKTtcblxuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBhcnJvd0Z1bmN0aW9uLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcblxuICAgICAgICBpZiAoaXNHZW5lcmljKSB7XG4gICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNBcnJvd0Z1bmN0aW9uKCk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uID0gbmV3IEZhbWl4LkFycm93RnVuY3Rpb24oKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEdldCB0aGUgcGFyZW50IG9mIHRoZSBhcnJvdyBmdW5jdGlvbiAodGhlIHZhcmlhYmxlIGRlY2xhcmF0aW9uKVxuICAgICAgICBjb25zdCBwYXJlbnQgPSBhcnJvd0Z1bmN0aW9uLmdldFBhcmVudElmS2luZChTeW50YXhLaW5kLlZhcmlhYmxlRGVjbGFyYXRpb24pO1xuICAgICAgICBsZXQgZnVuY3Rpb25OYW1lID0gJyhOT19OQU1FKSc7XG5cbiAgICAgICAgaWYgKHBhcmVudCAmJiBwYXJlbnQgaW5zdGFuY2VvZiBWYXJpYWJsZURlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICAvLyBHZXQgdGhlIG5hbWUgb2YgdGhlIHZhcmlhYmxlXG4gICAgICAgICAgICBmdW5jdGlvbk5hbWUgPSBwYXJlbnQuZ2V0TmFtZSgpO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKGZ1bmN0aW9uTmFtZSkge1xuICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5zZXROYW1lKGZ1bmN0aW9uTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLnNldE5hbWUoXCJhbm9ueW1vdXNcIik7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaWduYXR1cmUgb2YgYW4gYXJyb3cgZnVuY3Rpb24gaXMgKHBhcmFtZXRlcnMpID0+IHJldHVybl90eXBlXG4gICAgICAgIGNvbnN0IHBhcmFtZXRlcnNTaWduYXR1cmUgPSBhcnJvd0Z1bmN0aW9uLmdldFBhcmFtZXRlcnMoKS5tYXAocCA9PiBwLmdldFRleHQoKSkuam9pbihcIiwgXCIpO1xuICAgICAgICBjb25zdCByZXR1cm5UeXBlU2lnbmF0dXJlID0gYXJyb3dGdW5jdGlvbi5nZXRSZXR1cm5UeXBlKCkuZ2V0VGV4dCgpO1xuICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLnNldFNpZ25hdHVyZShgKCR7cGFyYW1ldGVyc1NpZ25hdHVyZX0pID0+ICR7cmV0dXJuVHlwZVNpZ25hdHVyZX1gKTtcbiAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5zZXRDeWNsb21hdGljQ29tcGxleGl0eShjdXJyZW50Q0NbZm14QXJyb3dGdW5jdGlvbi5nZXROYW1lKCldKTtcblxuICAgICAgICBsZXQgZnVuY3Rpb25UeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZ1bmN0aW9uVHlwZU5hbWUgPSBhcnJvd0Z1bmN0aW9uLmdldFJldHVyblR5cGUoKS5nZXRUZXh0KCkudHJpbSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGA+IFdBUk5JTkc6IGdvdCBleGNlcHRpb24gJHtlcnJvcn0uIEZhaWxlZCB0byBnZXQgdXNhYmxlIG5hbWUgZm9yIHJldHVybiB0eXBlIG9mIGZ1bmN0aW9uOiAke2Z1bmN0aW9uTmFtZX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGZ1bmN0aW9uVHlwZU5hbWUsIGFycm93RnVuY3Rpb24gYXMgdW5rbm93biBhcyBGdW5jdGlvbkRlY2xhcmF0aW9uKTtcbiAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5zZXREZWNsYXJlZFR5cGUoZm14VHlwZSk7XG4gICAgICAgIGZteEFycm93RnVuY3Rpb24uc2V0TnVtYmVyT2ZMaW5lc09mQ29kZShhcnJvd0Z1bmN0aW9uLmdldEVuZExpbmVOdW1iZXIoKSAtIGFycm93RnVuY3Rpb24uZ2V0U3RhcnRMaW5lTnVtYmVyKCkpO1xuICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gYXJyb3dGdW5jdGlvbi5nZXRQYXJhbWV0ZXJzKCk7XG4gICAgICAgIGZteEFycm93RnVuY3Rpb24uc2V0TnVtYmVyT2ZQYXJhbWV0ZXJzKHBhcmFtZXRlcnMubGVuZ3RoKTtcbiAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5zZXROdW1iZXJPZlN0YXRlbWVudHMoYXJyb3dGdW5jdGlvbi5nZXRTdGF0ZW1lbnRzKCkubGVuZ3RoKTtcblxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihhcnJvd0V4cHJlc3Npb24gYXMgdW5rbm93biBhcyBUU01vcnBoT2JqZWN0VHlwZSwgZm14QXJyb3dGdW5jdGlvbik7XG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhBcnJvd0Z1bmN0aW9uKTtcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhBcnJvd0Z1bmN0aW9uLGFycm93RnVuY3Rpb24gYXMgdW5rbm93biBhcyBUU01vcnBoT2JqZWN0VHlwZSk7XG5cbiAgICAgICAgcmV0dXJuIGZteEFycm93RnVuY3Rpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uXG4gICAgICogQHBhcmFtIGNscyBBIGNsYXNzXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBjb25jcmV0aXNhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbkVudGl0eSA6IEZhbWl4LlBhcmFtZXRyaWNDbGFzcyB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UgfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kICxnZW5FbnRpdHkgOiBGYW1peC5QYXJhbWV0cmljQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZCk6IEZhbWl4LkNvbmNyZXRpc2F0aW9uIHtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGZteENvbmNyZXRpc2F0aW9uIDogRmFtaXguQ29uY3JldGlzYXRpb24gPSBuZXcgRmFtaXguQ29uY3JldGlzYXRpb24oKTsgICAgICAgICAgICAgIFxuICAgICAgICBcbiAgICAgICAgZm14Q29uY3JldGlzYXRpb24uc2V0Q29uY3JldGVFbnRpdHkoY29uRW50aXR5KTtcbiAgICAgICAgZm14Q29uY3JldGlzYXRpb24uc2V0R2VuZXJpY0VudGl0eShnZW5FbnRpdHkpO1xuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteENvbmNyZXRpc2F0aW9uLG51bGwpO1xuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14Q29uY3JldGlzYXRpb24pOyAgICBcbiAgICAgICAgY29uc3QgcGFyYW1ldGVyQ29uY3JldGlzYXRpb24gPSB0aGlzLmNyZWF0ZUZhbWl4UGFyYW1ldGVyQ29uY3Jlc3Rpc2F0aW9uKGZteENvbmNyZXRpc2F0aW9uKTtcbiAgICAgICAgICAgIFxuICAgICAgICByZXR1cm4gZm14Q29uY3JldGlzYXRpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uXG4gICAgICogQHBhcmFtIGNvbmNyZXRpc2F0aW9uIEEgRmFtaXhDb25jcmV0aXNhdGlvblxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgUGFyYW1ldGVyQ29uY3Jlc3Rpc2F0aW9uXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4UGFyYW1ldGVyQ29uY3Jlc3Rpc2F0aW9uKGNvbmNyZXRpc2F0aW9uOiBGYW1peC5Db25jcmV0aXNhdGlvbik6IEZhbWl4LlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uIHtcbiAgICAgICAgY29uc3QgY29uQ2xhc3MgPSBjb25jcmV0aXNhdGlvbi5nZXRDb25jcmV0ZUVudGl0eSgpO1xuICAgICAgICBjb25zdCBnZW5DbGFzcyA9IGNvbmNyZXRpc2F0aW9uLmdldEdlbmVyaWNFbnRpdHkoKTtcbiAgICAgICAgY29uc3QgcGFyYW1ldGVyQ29uY3JldGlzYXRpb25zID0gdGhpcy5mYW1peFJlcC5fZ2V0QWxsRW50aXRpZXNXaXRoVHlwZShcIlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uXCIpO1xuICAgICAgICBjb25zdCBjb25jcmV0ZVBhcmFtZXRlcnMgPSBjb25DbGFzcy5nZXRDb25jcmV0ZVBhcmFtZXRlcnMoKTtcbiAgICAgICAgY29uc3QgZ2VuZXJpY1BhcmFtZXRlcnMgPSBnZW5DbGFzcy5nZXRHZW5lcmljUGFyYW1ldGVycygpO1xuICAgICAgICBcbiAgICAgICAgbGV0IGNvbkNsYXNzVHlwZVBhcmFtZXRlcnNJdGVyYXRvciA9IGNvbmNyZXRlUGFyYW1ldGVycy52YWx1ZXMoKTtcbiAgICAgICAgbGV0IGdlbkNsYXNzVHlwZVBhcmFtZXRlcnNJdGVyYXRvciA9IGdlbmVyaWNQYXJhbWV0ZXJzLnZhbHVlcygpO1xuICAgICAgICBsZXQgZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24gOiBGYW1peC5QYXJhbWV0ZXJDb25jcmV0aXNhdGlvbjtcblxuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGdlbmVyaWNQYXJhbWV0ZXJzLnNpemU7IGkrKykge1xuICAgICAgICAgICAgY29uc3QgY29uQ2xhc3NUeXBlUGFyYW1ldGVyID0gY29uQ2xhc3NUeXBlUGFyYW1ldGVyc0l0ZXJhdG9yLm5leHQoKS52YWx1ZTtcbiAgICAgICAgICAgIGNvbnN0IGdlbkNsYXNzVHlwZVBhcmFtZXRlciA9IGdlbkNsYXNzVHlwZVBhcmFtZXRlcnNJdGVyYXRvci5uZXh0KCkudmFsdWU7XG4gICAgICAgICAgICBsZXQgY3JlYXRlUGFyYW1ldGVyQ29uY3JldGlzYXRpb24gOiBib29sZWFuID0gdHJ1ZTtcbiAgICAgICAgICAgIGlmKGNvbkNsYXNzVHlwZVBhcmFtZXRlciAmJiBnZW5DbGFzc1R5cGVQYXJhbWV0ZXIgJiYgY29uQ2xhc3NUeXBlUGFyYW1ldGVyLmdldE5hbWUoKSAhPSBnZW5DbGFzc1R5cGVQYXJhbWV0ZXIuZ2V0TmFtZSgpKXtcbiAgICAgICAgICAgICAgICBwYXJhbWV0ZXJDb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgocGFyYW0gOiBGYW1peC5QYXJhbWV0ZXJDb25jcmV0aXNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY29uQ2xhc3NUeXBlUGFyYW1ldGVyLmdldE5hbWUoKSA9PSBwYXJhbS5nZXRDb25jcmV0ZVBhcmFtZXRlcigpLmdldE5hbWUoKSAmJiBnZW5DbGFzc1R5cGVQYXJhbWV0ZXIuZ2V0TmFtZSgpID09IHBhcmFtLmdldEdlbmVyaWNQYXJhbWV0ZXIoKS5nZXROYW1lKCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZVBhcmFtZXRlckNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiA9IHBhcmFtO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICBpZiAoY3JlYXRlUGFyYW1ldGVyQ29uY3JldGlzYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24gPSBuZXcgRmFtaXguUGFyYW1ldGVyQ29uY3JldGlzYXRpb24oKTtcbiAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24uc2V0R2VuZXJpY1BhcmFtZXRlcihnZW5DbGFzc1R5cGVQYXJhbWV0ZXIpO1xuICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbi5zZXRDb25jcmV0ZVBhcmFtZXRlcihjb25DbGFzc1R5cGVQYXJhbWV0ZXIpO1xuICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbi5hZGRDb25jcmV0aXNhdGlvbihjb25jcmV0aXNhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24sbnVsbCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24uYWRkQ29uY3JldGlzYXRpb24oY29uY3JldGlzYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgXG4gICAgICAgIHJldHVybiBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbjtcblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvbiBiZXR3ZWVuIHR3byBjbGFzc2VzIG9yIHR3byBpbnRlcmZhY2VzXG4gICAgICogQHBhcmFtIGVsZW1lbnQgQSBjbGFzcyBvciBhbiBJbnRlcmZhY2VcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkNsYXNzT3JJbnRlcmZhY2VTcGVjaWFsaXNhdGlvbihlbGVtZW50OiBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24pe1xuICAgICAgICBcbiAgICAgICAgY29uc3Qgc3VwZXJFbnRpdHkgPSBlbGVtZW50LmdldEV4dGVuZHMoKTtcbiAgICAgICAgbGV0IHN1cGVyRW50aXR5QXJyYXk7XG4gICAgICAgIGlmIChzdXBlckVudGl0eSl7XG4gICAgICAgICAgICBzdXBlckVudGl0eUFycmF5ID0gQXJyYXkuaXNBcnJheShzdXBlckVudGl0eSkgPyBzdXBlckVudGl0eSA6IFtzdXBlckVudGl0eV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN1cGVyRW50aXR5QXJyYXkgJiYgc3VwZXJFbnRpdHlBcnJheS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzdXBlckVudGl0eUFycmF5LmZvckVhY2goZW50aXR5ID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgZW50aXR5SXNHZW5lcmljO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN1cGVyRW50aXR5U3ltYm9sID0gZW50aXR5LmdldEV4cHJlc3Npb24oKS5nZXRTeW1ib2xPclRocm93KCk7XG4gICAgICAgICAgICAgICAgbGV0IHN1cGVyRW50aXR5RGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgaWYgKHN1cGVyRW50aXR5IGluc3RhbmNlb2YgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1cGVyRW50aXR5RGVjbGFyYXRpb24gPSBzdXBlckVudGl0eVN5bWJvbC5nZXREZWNsYXJhdGlvbnMoKVswXS5hc0tpbmQodHMuU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdXBlckVudGl0eURlY2xhcmF0aW9uID0gc3VwZXJFbnRpdHlTeW1ib2wuZ2V0RGVjbGFyYXRpb25zKClbMF0uYXNLaW5kKHRzLlN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3VwZXJFbnRpdHlEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBlbnRpdHlJc0dlbmVyaWMgPSBzdXBlckVudGl0eURlY2xhcmF0aW9uLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGVudGl0eUlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgRW50aXR5RGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgICAgIGxldCBnZW5FbnRpdHk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdXBlckVudGl0eSBpbnN0YW5jZW9mIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgRW50aXR5RGVjbGFyYXRpb24gPSBlbnRpdHkuZ2V0RXhwcmVzc2lvbigpLmdldFN5bWJvbCgpLmdldERlY2xhcmF0aW9ucygpWzBdIGFzIENsYXNzRGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBnZW5FbnRpdHkgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhDbGFzcyhFbnRpdHlEZWNsYXJhdGlvbikgYXMgRmFtaXguUGFyYW1ldHJpY0NsYXNzO1xuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgRW50aXR5RGVjbGFyYXRpb24gPSBlbnRpdHkuZ2V0RXhwcmVzc2lvbigpLmdldFN5bWJvbCgpLmdldERlY2xhcmF0aW9ucygpWzBdIGFzIEludGVyZmFjZURlY2xhcmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2VuRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlKEVudGl0eURlY2xhcmF0aW9uKSBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdlblBhcmFtcyA9IEVudGl0eURlY2xhcmF0aW9uLmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKChwYXJhbSkgPT4gcGFyYW0uZ2V0VGV4dCgpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJncyA9IGVsZW1lbnQuZ2V0SGVyaXRhZ2VDbGF1c2VzKClbMF0uZ2V0VHlwZU5vZGVzKClbMF0uZ2V0VHlwZUFyZ3VtZW50cygpXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvblBhcmFtcyA9IGVsZW1lbnQuZ2V0SGVyaXRhZ2VDbGF1c2VzKClbMF0uZ2V0VHlwZU5vZGVzKClbMF0uZ2V0VHlwZUFyZ3VtZW50cygpLm1hcCgocGFyYW0pID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSGVscGVycy5hcnJheXNBcmVFcXVhbChjb25QYXJhbXMsZ2VuUGFyYW1zKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbkVudGl0eTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbkVudGl0eSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENvbmNyZXRlRWxlbWVudChnZW5FbnRpdHksRW50aXR5RGVjbGFyYXRpb24sYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25jcmV0aXNhdGlvbnMgPSB0aGlzLmZhbWl4UmVwLl9nZXRBbGxFbnRpdGllc1dpdGhUeXBlKFwiQ29uY3JldGlzYXRpb25cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY3JlYXRlQ29uY3JldGlzYXRpb24gOiBib29sZWFuID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmNyZXRpc2F0aW9ucy5mb3JFYWNoKChjb25jIDogRmFtaXguQ29uY3JldGlzYXRpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2VuRW50aXR5LmdldEZ1bGx5UXVhbGlmaWVkTmFtZSgpID09IGNvbmMuZ2V0R2VuZXJpY0VudGl0eSgpLmdldEZ1bGx5UXVhbGlmaWVkTmFtZSgpICYmIGNvbmMuZ2V0Q29uY3JldGVFbnRpdHkoKS5nZXRGdWxseVF1YWxpZmllZE5hbWUoKSA9PSBjb25FbnRpdHkuZ2V0RnVsbHlRdWFsaWZpZWROYW1lKCkpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb25jcmV0aXNhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3JlYXRlQ29uY3JldGlzYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmbXhDb25jcmV0aXNhdGlvbiA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gdGhpcy5jcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbkVudGl0eSxnZW5FbnRpdHkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gICAgICAgICAgIFxuICAgIH0gICAgXG4gICAgXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggY29uY3JldGlzYXRpb24gYmV0d2VlbiBhIGNsYXNzIGFuZCBpdHMgaW5zdGFuY2lhdGlvbnNcbiAgICAgKiBAcGFyYW0gY2xzIEEgY2xhc3NcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkdlbmVyaWNJbnN0YW50aWF0aW9uKGNsczogQ2xhc3NEZWNsYXJhdGlvbil7XG4gICAgICAgXG4gICAgICAgIGNvbnN0IGlzR2VuZXJpYyA9IGNscy5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDA7XG4gICAgICAgIGlmIChpc0dlbmVyaWMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlcyA9IGNscy5nZXRTb3VyY2VGaWxlKCkuZ2V0RGVzY2VuZGFudHNPZktpbmQodHMuU3ludGF4S2luZC5OZXdFeHByZXNzaW9uKVxuICAgICAgICAgICAgICAgIC5maWx0ZXIobmV3RXhwciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBuZXdFeHByLmdldEV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4cHJlc3Npb24uZ2V0VGV4dCgpID09PSBjbHMuZ2V0TmFtZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGluc3RhbmNlcy5mb3JFYWNoKGluc3RhbmNlID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnN0YW5jZUlzR2VuZXJpYyA9IGluc3RhbmNlLmdldFR5cGVBcmd1bWVudHMoKS5sZW5ndGggPiAwO1xuICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZUlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25QYXJhbXMgPSBpbnN0YW5jZS5nZXRUeXBlQXJndW1lbnRzKCkubWFwKChwYXJhbSkgPT4gcGFyYW0uZ2V0VGV4dCgpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2VuRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoY2xzKSBhcyBGYW1peC5QYXJhbWV0cmljQ2xhc3M7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdlblBhcmFtcyA9IGNscy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCgocGFyYW0pID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSGVscGVycy5hcnJheXNBcmVFcXVhbChjb25QYXJhbXMsZ2VuUGFyYW1zKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbkVudGl0eTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbkVudGl0eSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENvbmNyZXRlRWxlbWVudChnZW5FbnRpdHksY2xzLGluc3RhbmNlLmdldFR5cGVBcmd1bWVudHMoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25jcmV0aXNhdGlvbnMgPSB0aGlzLmZhbWl4UmVwLl9nZXRBbGxFbnRpdGllc1dpdGhUeXBlKFwiQ29uY3JldGlzYXRpb25cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY3JlYXRlQ29uY3JldGlzYXRpb24gOiBib29sZWFuID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbmNyZXRpc2F0aW9ucy5mb3JFYWNoKChjb25jIDogRmFtaXguQ29uY3JldGlzYXRpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2VuRW50aXR5LmdldEZ1bGx5UXVhbGlmaWVkTmFtZSgpID09IGNvbmMuZ2V0R2VuZXJpY0VudGl0eSgpLmdldEZ1bGx5UXVhbGlmaWVkTmFtZSgpICYmIGNvbmMuZ2V0Q29uY3JldGVFbnRpdHkoKS5nZXRGdWxseVF1YWxpZmllZE5hbWUoKSA9PSBjb25FbnRpdHkuZ2V0RnVsbHlRdWFsaWZpZWROYW1lKCkpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb25jcmV0aXNhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3JlYXRlQ29uY3JldGlzYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmbXhDb25jcmV0aXNhdGlvbiA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gdGhpcy5jcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbkVudGl0eSxnZW5FbnRpdHkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvbiBiZXR3ZWVuIGEgY2xhc3MgYW5kIGl0cyBpbnN0YW5jaWF0aW9uc1xuICAgICAqIEBwYXJhbSBmdW5jIEEgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkZ1bmN0aW9uSW5zdGFudGlhdGlvbihlbGVtZW50OiBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgTWV0aG9kRGVjbGFyYXRpb24pe1xuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgaWYgKGlzR2VuZXJpYykge1xuICAgICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpLm1hcChwYXJhbSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgY29uc3QgdXNlcyA9IGVsZW1lbnQuZmluZFJlZmVyZW5jZXNBc05vZGVzKCk7ICAgIFxuICAgICAgICAgICAgdXNlcy5mb3JFYWNoKHVzYWdlID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgY3VycmVudE5vZGUgPSB1c2FnZTtcblxuICAgICAgICAgICAgICAgIHdoaWxlIChjdXJyZW50Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudE5vZGUuZ2V0S2luZCgpID09PSBTeW50YXhLaW5kLkNhbGxFeHByZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYWxsRXhwcmVzc2lvbiA9IGN1cnJlbnROb2RlLmFzS2luZChTeW50YXhLaW5kLkNhbGxFeHByZXNzaW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlSXNHZW5lcmljID0gY2FsbEV4cHJlc3Npb24uZ2V0VHlwZUFyZ3VtZW50cygpLmxlbmd0aCA+IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoaW5zdGFuY2VJc0dlbmVyaWMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhcmdzID0gY2FsbEV4cHJlc3Npb24uZ2V0VHlwZUFyZ3VtZW50cygpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvblBhcmFtcyA9IGNhbGxFeHByZXNzaW9uLmdldFR5cGVBcmd1bWVudHMoKS5tYXAocGFyYW0gPT4gcGFyYW0uZ2V0VGV4dCgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIUhlbHBlcnMuYXJyYXlzQXJlRXF1YWwoY29uUGFyYW1zLGdlblBhcmFtcykpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGdlbkVsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmKGVsZW1lbnQgaW5zdGFuY2VvZiBGdW5jdGlvbkRlY2xhcmF0aW9uKXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbkVsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhGdW5jdGlvbihlbGVtZW50LDApIGFzIEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbkVsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhNZXRob2QoZWxlbWVudCwwKSBhcyBGYW1peC5QYXJhbWV0cmljTWV0aG9kO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb25jRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhDb25jcmV0ZUVsZW1lbnQoZ2VuRWxlbWVudCxlbGVtZW50LGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25jcmV0aXNhdGlvbnMgPSB0aGlzLmZhbWl4UmVwLl9nZXRBbGxFbnRpdGllc1dpdGhUeXBlKFwiQ29uY3JldGlzYXRpb25cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjcmVhdGVDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2VuRWxlbWVudC5nZXRGdWxseVF1YWxpZmllZE5hbWUoKSA9PSBjb25jLmdldEdlbmVyaWNFbnRpdHkoKS5nZXRGdWxseVF1YWxpZmllZE5hbWUoKSAmJiBjb25jLmdldENvbmNyZXRlRW50aXR5KCkuZ2V0RnVsbHlRdWFsaWZpZWROYW1lKCkgPT0gY29uY0VsZW1lbnQuZ2V0RnVsbHlRdWFsaWZpZWROYW1lKCkpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWF0ZUNvbmNyZXRpc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmbXhDb25jcmV0aXNhdGlvbiA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gdGhpcy5jcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbmNFbGVtZW50LGdlbkVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgLy8gUmVtb250ZXIgw6AgbCfDqWzDqW1lbnQgcGFyZW50ICh1dGlsZSBzaSBsZSBuxZN1ZCBkZSByw6lmw6lyZW5jZSBlc3QgdW4gZW5mYW50KVxuICAgICAgICAgICAgICAgICAgICBjdXJyZW50Tm9kZSA9IGN1cnJlbnROb2RlLmdldFBhcmVudCgpO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uIGJldHdlZW4gYSBjbGFzcyBhbmQgYW4gaW50ZXJmYWNlXG4gICAgICogQHBhcmFtIGNscyBBIGNsYXNzXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb25JbnRlcmZhY2VDbGFzcyhjbHM6IENsYXNzRGVjbGFyYXRpb24pe1xuICAgIFxuICAgICAgICBjb25zdCBzdXBlckludGVyZmFjZXMgPSBjbHMuZ2V0SW1wbGVtZW50cygpO1xuICAgICAgICBzdXBlckludGVyZmFjZXMuZm9yRWFjaChpbnRlcmZhY2VUeXBlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGludGVyZmFjZUlzR2VuZXJpYyA9IGludGVyZmFjZVR5cGUuZ2V0VHlwZUFyZ3VtZW50cygpLmxlbmd0aD4wO1xuICAgICAgICAgICAgaWYgKGludGVyZmFjZUlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgIGNvbnN0IGludGVyZmFjZURlY2xhcmF0aW9uID0gaW50ZXJmYWNlVHlwZS5nZXRFeHByZXNzaW9uKCkuZ2V0U3ltYm9sKCkuZ2V0RGVjbGFyYXRpb25zKClbMF0gYXMgSW50ZXJmYWNlRGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gaW50ZXJmYWNlRGVjbGFyYXRpb24uZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAoKHBhcmFtKSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGNvblBhcmFtcyA9IGNscy5nZXRIZXJpdGFnZUNsYXVzZXMoKVswXS5nZXRUeXBlTm9kZXMoKVswXS5nZXRUeXBlQXJndW1lbnRzKCkubWFwKChwYXJhbSkgPT4gcGFyYW0uZ2V0VGV4dCgpKTtcbiAgICAgICAgICAgICAgICBjb25zdCBhcmdzID0gY2xzLmdldEhlcml0YWdlQ2xhdXNlcygpWzBdLmdldFR5cGVOb2RlcygpWzBdLmdldFR5cGVBcmd1bWVudHMoKTtcbiAgICAgICAgICAgICAgICBpZiAoIUhlbHBlcnMuYXJyYXlzQXJlRXF1YWwoY29uUGFyYW1zLGdlblBhcmFtcykpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2VuSW50ZXJmYWNlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlKGludGVyZmFjZURlY2xhcmF0aW9uKSBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25JbnRlcmZhY2UgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhDb25jcmV0ZUVsZW1lbnQoZ2VuSW50ZXJmYWNlLGludGVyZmFjZURlY2xhcmF0aW9uLGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25jcmV0aXNhdGlvbnMgPSB0aGlzLmZhbWl4UmVwLl9nZXRBbGxFbnRpdGllc1dpdGhUeXBlKFwiQ29uY3JldGlzYXRpb25cIik7XG4gICAgICAgICAgICAgICAgICAgIGxldCBjcmVhdGVDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2VuSW50ZXJmYWNlLmdldEZ1bGx5UXVhbGlmaWVkTmFtZSgpID09IGNvbmMuZ2V0R2VuZXJpY0VudGl0eSgpLmdldEZ1bGx5UXVhbGlmaWVkTmFtZSgpICYmIGNvbmMuZ2V0Q29uY3JldGVFbnRpdHkoKS5nZXRGdWxseVF1YWxpZmllZE5hbWUoKSA9PSBjb25JbnRlcmZhY2UuZ2V0RnVsbHlRdWFsaWZpZWROYW1lKCkpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgIGlmIChjcmVhdGVDb25jcmV0aXNhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb24gOiBGYW1peC5Db25jcmV0aXNhdGlvbiA9IHRoaXMuY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbihjb25JbnRlcmZhY2UsZ2VuSW50ZXJmYWNlKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uIGJldHdlZW4gYW4gaW50ZXJmYWNlIGFuZCBhIFR5cGVcbiAgICAgKiBAcGFyYW0gZWxlbWVudCBBIHZhcmlhYmxlIG9yIGEgZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gaW50ZXIgQW4gaW50ZXJmYWNlXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb25UeXBlSW5zdGFuY2lhdGlvbihlbGVtZW50OiBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IENsYXNzRGVjbGFyYXRpb24pe1xuXG4gICAgICAgIGNvbnN0IGlzR2VuZXJpYyA9IGVsZW1lbnQuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPiAwO1xuICAgICAgICBpZiAoaXNHZW5lcmljKSB7XG4gICAgICAgICAgICBjb25zdCBnZW5QYXJhbXMgPSBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHBhcmFtID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICBjb25zdCB1c2VzID0gZWxlbWVudC5maW5kUmVmZXJlbmNlc0FzTm9kZXMoKTtcbiAgICAgICAgICAgIHVzZXMuZm9yRWFjaCh1c2UgPT4geyAgICAgICAgXG4gICAgICAgICAgICAgICAgbGV0IHBhcmVudE5vZGUgPSB1c2UuZ2V0UGFyZW50KCk7XG4gICAgICAgICAgICAgICAgd2hpbGUgKHBhcmVudE5vZGUpIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHBhcmVudE5vZGUuZ2V0S2luZCgpID09PSBTeW50YXhLaW5kLlR5cGVSZWZlcmVuY2UpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVSZWZlcmVuY2VOb2RlID0gcGFyZW50Tm9kZS5hc0tpbmQoU3ludGF4S2luZC5UeXBlUmVmZXJlbmNlKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IHR5cGVSZWZlcmVuY2VOb2RlSXNHZW5lcmljID0gdHlwZVJlZmVyZW5jZU5vZGUuZ2V0VHlwZUFyZ3VtZW50cygpLmxlbmd0aCA+IDA7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAodHlwZVJlZmVyZW5jZU5vZGVJc0dlbmVyaWMpIHt9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJncyA9IHR5cGVSZWZlcmVuY2VOb2RlLmdldFR5cGVBcmd1bWVudHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25QYXJhbXMgPSB0eXBlUmVmZXJlbmNlTm9kZS5nZXRUeXBlQXJndW1lbnRzKCkubWFwKHBhcmFtID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFIZWxwZXJzLmFycmF5c0FyZUVxdWFsKGNvblBhcmFtcyxnZW5QYXJhbXMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBnZW5FbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihlbGVtZW50IGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbil7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5FbGVtZW50ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoZWxlbWVudCkgYXMgRmFtaXguUGFyYW1ldHJpY0NsYXNzO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuRWxlbWVudCA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peEludGVyZmFjZShlbGVtZW50KSBhcyBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjb25jRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhDb25jcmV0ZUVsZW1lbnQoZ2VuRWxlbWVudCxlbGVtZW50LGFyZ3MpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25jcmV0aXNhdGlvbnMgPSB0aGlzLmZhbWl4UmVwLl9nZXRBbGxFbnRpdGllc1dpdGhUeXBlKFwiQ29uY3JldGlzYXRpb25cIik7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjcmVhdGVDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2VuRWxlbWVudC5nZXRGdWxseVF1YWxpZmllZE5hbWUoKSA9PSBjb25jLmdldEdlbmVyaWNFbnRpdHkoKS5nZXRGdWxseVF1YWxpZmllZE5hbWUoKSAmJiBjb25jLmdldENvbmNyZXRlRW50aXR5KCkuZ2V0RnVsbHlRdWFsaWZpZWROYW1lKCkgPT0gY29uY0VsZW1lbnQuZ2V0RnVsbHlRdWFsaWZpZWROYW1lKCkpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWF0ZUNvbmNyZXRpc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmbXhDb25jcmV0aXNhdGlvbiA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gdGhpcy5jcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbmNFbGVtZW50LGdlbkVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IHBhcmVudE5vZGUuZ2V0UGFyZW50KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY29udmVydFRvUmVsYXRpdmVQYXRoKGFic29sdXRlUGF0aDogc3RyaW5nLCBhYnNvbHV0ZVBhdGhQcm9qZWN0OiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIGFic29sdXRlUGF0aC5yZXBsYWNlKGFic29sdXRlUGF0aFByb2plY3QsIFwiXCIpLnNsaWNlKDEpO1xuICAgIH1cbn1cbiJdfQ==
|
|
1424
|
+
function initFQN(sourceElement, famixElement) {
|
|
1425
|
+
if (!(sourceElement instanceof ts_morph_1.CommentRange)) {
|
|
1426
|
+
const fqn = FQNFunctions.getFQN(sourceElement);
|
|
1427
|
+
analyze_1.logger.debug("Setting fully qualified name for " + famixElement.getJSON() + " to " + fqn);
|
|
1428
|
+
famixElement.fullyQualifiedName = fqn;
|
|
1429
|
+
}
|
|
1430
|
+
}
|
|
1431
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRW50aXR5RGljdGlvbmFyeS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9mYW1peF9mdW5jdGlvbnMvRW50aXR5RGljdGlvbmFyeS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFBLHVDQUE2bEI7QUFDN2xCLDhFQUFnRjtBQUNoRixnRUFBa0Q7QUFDbEQsb0VBQWdFO0FBQ2hFLHdDQUE0QztBQUM1QywwRUFBaUQ7QUFDakQsNERBQThDO0FBQzlDLHFEQUF1QztBQUN2QyxnREFBd0I7QUFDeEIsb0RBQXVCO0FBVXZCLE1BQWEsZ0JBQWdCO0lBY3pCO1FBWk8sYUFBUSxHQUFHLElBQUksa0NBQWUsRUFBRSxDQUFDO1FBQ2hDLGdCQUFXLEdBQUcsSUFBSSxHQUFHLEVBQXVCLENBQUMsQ0FBQyw0Q0FBNEM7UUFDMUYsZ0JBQVcsR0FBRyxJQUFJLEdBQUcsRUFBK0MsQ0FBQyxDQUFDLDREQUE0RDtRQUNsSSxvQkFBZSxHQUFHLElBQUksR0FBRyxFQUF1RCxDQUFDLENBQUMsZ0RBQWdEO1FBQ2xJLGlCQUFZLEdBQUcsSUFBSSxHQUFHLEVBQXdCLENBQUMsQ0FBQyxnREFBZ0Q7UUFDaEcsZUFBVSxHQUFHLElBQUksR0FBRyxFQUE2QyxDQUFDLENBQUMsa0RBQWtEO1FBQ3JILGVBQVUsR0FBRyxJQUFJLEdBQUcsRUFBa0UsQ0FBQyxDQUFDLDJDQUEyQztRQUNuSSw0QkFBdUIsR0FBRyxJQUFJLEdBQThGLENBQUEsQ0FBQywrQ0FBK0M7UUFDNUssa0JBQWEsR0FBRyxnQ0FBZ0MsQ0FBQyxDQUFDLDZDQUE2QztRQUNoRyx3QkFBbUIsR0FBRyxJQUFJLEdBQUcsRUFBa0MsQ0FBQztRQUNoRSw0QkFBdUIsR0FBRyxJQUFJLEdBQUcsRUFBa0MsQ0FBQztRQUd2RSxJQUFJLENBQUMsUUFBUSxDQUFDLHNCQUFzQixDQUFDLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxDQUFDO0lBQ25FLENBQUM7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RyxLQUFLLENBQUM7Z0NBQ2pDLENBQUM7NEJBQ0wsQ0FBQyxDQUFDLENBQUM7NEJBRUgsSUFBSSxvQkFBb0IsRUFBRSxDQUFDO2dDQUN2QixNQUFNLGlCQUFpQixHQUEwQixJQUFJLENBQUMseUJBQXlCLENBQUMsV0FBVyxFQUFDLFVBQVUsQ0FBQyxDQUFDOzRCQUM1RyxDQUFDO3dCQUNMLENBQUM7d0JBQ0wsTUFBTTtvQkFDVixDQUFDO29CQUNELFVBQVUsR0FBRyxVQUFVLENBQUMsU0FBUyxFQUFFLENBQUM7Z0JBQ3hDLENBQUM7WUFDTCxDQUFDLENBQUMsQ0FBQztRQUNQLENBQUM7SUFDTCxDQUFDO0lBRU0scUJBQXFCLENBQUMsWUFBb0IsRUFBRSxtQkFBMkI7UUFDMUUsT0FBTyxZQUFZLENBQUMsT0FBTyxDQUFDLG1CQUFtQixFQUFFLEVBQUUsQ0FBQyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNsRSxDQUFDO0NBQ0o7QUE3aERELDRDQTZoREM7QUFDRCxTQUFTLE9BQU8sQ0FBQyxhQUFnQyxFQUFFLFlBQWlDO0lBQ2hGLElBQUksQ0FBQyxDQUFDLGFBQWEsWUFBWSx1QkFBWSxDQUFDLEVBQUUsQ0FBQztRQUMzQyxNQUFNLEdBQUcsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQy9DLGdCQUFNLENBQUMsS0FBSyxDQUFDLG1DQUFtQyxHQUFHLFlBQVksQ0FBQyxPQUFPLEVBQUUsR0FBRyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQUM7UUFDekYsWUFBa0MsQ0FBQyxrQkFBa0IsR0FBRyxHQUFHLENBQUM7SUFDakUsQ0FBQztBQUNMLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDbGFzc0RlY2xhcmF0aW9uLCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uLCBGdW5jdGlvbkRlY2xhcmF0aW9uLCBJZGVudGlmaWVyLCBJbnRlcmZhY2VEZWNsYXJhdGlvbiwgTWV0aG9kRGVjbGFyYXRpb24sIE1ldGhvZFNpZ25hdHVyZSwgTW9kdWxlRGVjbGFyYXRpb24sIFByb3BlcnR5RGVjbGFyYXRpb24sIFByb3BlcnR5U2lnbmF0dXJlLCBTb3VyY2VGaWxlLCBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24sIFZhcmlhYmxlRGVjbGFyYXRpb24sIFBhcmFtZXRlckRlY2xhcmF0aW9uLCBEZWNvcmF0b3IsIEdldEFjY2Vzc29yRGVjbGFyYXRpb24sIFNldEFjY2Vzc29yRGVjbGFyYXRpb24sIEltcG9ydFNwZWNpZmllciwgQ29tbWVudFJhbmdlLCBFbnVtRGVjbGFyYXRpb24sIEVudW1NZW1iZXIsIFR5cGVBbGlhc0RlY2xhcmF0aW9uLCBGdW5jdGlvbkV4cHJlc3Npb24sIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cywgSW1wb3J0RGVjbGFyYXRpb24sIEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uLCBTeW50YXhLaW5kLCBFeHByZXNzaW9uLCBUeXBlTm9kZSwgTm9kZSwgdHMsIFNjb3BlLCBUeXBlLCBBcnJvd0Z1bmN0aW9uIH0gZnJvbSBcInRzLW1vcnBoXCI7XG5pbXBvcnQgeyBpc0FtYmllbnQsIGlzTmFtZXNwYWNlIH0gZnJvbSBcIi4uL2FuYWx5emVfZnVuY3Rpb25zL3Byb2Nlc3NfZnVuY3Rpb25zXCI7XG5pbXBvcnQgKiBhcyBGYW1peCBmcm9tIFwiLi4vbGliL2ZhbWl4L21vZGVsL2ZhbWl4XCI7XG5pbXBvcnQgeyBGYW1peFJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vbGliL2ZhbWl4L2ZhbWl4X3JlcG9zaXRvcnlcIjtcbmltcG9ydCB7IGxvZ2dlciwgY29uZmlnIH0gZnJvbSBcIi4uL2FuYWx5emVcIjtcbmltcG9ydCBHcmFwaGVtZVNwbGl0dGVyIGZyb20gXCJncmFwaGVtZS1zcGxpdHRlclwiO1xuaW1wb3J0ICogYXMgSGVscGVycyBmcm9tIFwiLi9oZWxwZXJzX2NyZWF0aW9uXCI7XG5pbXBvcnQgKiBhcyBGUU5GdW5jdGlvbnMgZnJvbSBcIi4uL2ZxblwiO1xuaW1wb3J0IHBhdGggZnJvbSBcInBhdGhcIjtcbmltcG9ydCBfIGZyb20gJ2xvZGFzaCc7XG5cbmV4cG9ydCB0eXBlIFRTTW9ycGhPYmplY3RUeXBlID0gSW1wb3J0RGVjbGFyYXRpb24gfCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiB8IFNvdXJjZUZpbGUgfCBNb2R1bGVEZWNsYXJhdGlvbiB8IENsYXNzRGVjbGFyYXRpb24gfCBJbnRlcmZhY2VEZWNsYXJhdGlvbiB8IE1ldGhvZERlY2xhcmF0aW9uIHwgQ29uc3RydWN0b3JEZWNsYXJhdGlvbiB8IE1ldGhvZFNpZ25hdHVyZSB8IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24gfCBQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IFZhcmlhYmxlRGVjbGFyYXRpb24gfCBQcm9wZXJ0eURlY2xhcmF0aW9uIHwgUHJvcGVydHlTaWduYXR1cmUgfCBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb24gfCBJZGVudGlmaWVyIHwgRGVjb3JhdG9yIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBJbXBvcnRTcGVjaWZpZXIgfCBDb21tZW50UmFuZ2UgfCBFbnVtRGVjbGFyYXRpb24gfCBFbnVtTWVtYmVyIHwgVHlwZUFsaWFzRGVjbGFyYXRpb24gfCBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHM7XG5cbmV4cG9ydCB0eXBlIFR5cGVEZWNsYXJhdGlvbiA9IFR5cGVBbGlhc0RlY2xhcmF0aW9uIHwgUHJvcGVydHlEZWNsYXJhdGlvbiB8IFByb3BlcnR5U2lnbmF0dXJlIHwgTWV0aG9kRGVjbGFyYXRpb24gfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgTWV0aG9kU2lnbmF0dXJlIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgRnVuY3Rpb25FeHByZXNzaW9uIHwgUGFyYW1ldGVyRGVjbGFyYXRpb24gfCBWYXJpYWJsZURlY2xhcmF0aW9uIHwgRW51bU1lbWJlciB8IEltcG9ydEVxdWFsc0RlY2xhcmF0aW9uO1xuXG50eXBlIFBhcmFtZXRyaWNWYXJpYW50VHlwZSA9IEZhbWl4LlBhcmFtZXRyaWNDbGFzcyB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UgfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kO1xuXG50eXBlIENvbmNyZXRlRWxlbWVudFRTTW9ycGhUeXBlID0gQ2xhc3NEZWNsYXJhdGlvbiB8IEludGVyZmFjZURlY2xhcmF0aW9uIHwgRnVuY3Rpb25EZWNsYXJhdGlvbiB8IE1ldGhvZERlY2xhcmF0aW9uO1xuXG5leHBvcnQgY2xhc3MgRW50aXR5RGljdGlvbmFyeSB7XG4gICAgXG4gICAgcHVibGljIGZhbWl4UmVwID0gbmV3IEZhbWl4UmVwb3NpdG9yeSgpO1xuICAgIHByaXZhdGUgZm14QWxpYXNNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguQWxpYXM+KCk7IC8vIE1hcHMgdGhlIGFsaWFzIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXG4gICAgcHJpdmF0ZSBmbXhDbGFzc01hcCA9IG5ldyBNYXA8c3RyaW5nLCBGYW1peC5DbGFzcyB8IEZhbWl4LlBhcmFtZXRyaWNDbGFzcz4oKTsgLy8gTWFwcyB0aGUgZnVsbHkgcXVhbGlmaWVkIGNsYXNzIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXG4gICAgcHJpdmF0ZSBmbXhJbnRlcmZhY2VNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguSW50ZXJmYWNlIHwgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZT4oKTsgLy8gTWFwcyB0aGUgaW50ZXJmYWNlIG5hbWVzIHRvIHRoZWlyIEZhbWl4IG1vZGVsXG4gICAgcHJpdmF0ZSBmbXhNb2R1bGVNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguTW9kdWxlPigpOyAvLyBNYXBzIHRoZSBuYW1lc3BhY2UgbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIGZteEZpbGVNYXAgPSBuZXcgTWFwPHN0cmluZywgRmFtaXguU2NyaXB0RW50aXR5IHwgRmFtaXguTW9kdWxlPigpOyAvLyBNYXBzIHRoZSBzb3VyY2UgZmlsZSBuYW1lcyB0byB0aGVpciBGYW1peCBtb2RlbFxuICAgIHByaXZhdGUgZm14VHlwZU1hcCA9IG5ldyBNYXA8c3RyaW5nLCBGYW1peC5UeXBlIHwgRmFtaXguUHJpbWl0aXZlVHlwZSB8IEZhbWl4LlBhcmFtZXRlclR5cGU+KCk7IC8vIE1hcHMgdGhlIHR5cGUgbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIGZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwID0gbmV3IE1hcDxzdHJpbmcsIEZhbWl4LkZ1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uIHwgRmFtaXguTWV0aG9kIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZD4gLy8gTWFwcyB0aGUgZnVuY3Rpb24gbmFtZXMgdG8gdGhlaXIgRmFtaXggbW9kZWxcbiAgICBwcml2YXRlIFVOS05PV05fVkFMVUUgPSAnKHVua25vd24gZHVlIHRvIHBhcnNpbmcgZXJyb3IpJzsgLy8gVGhlIHZhbHVlIHRvIHVzZSB3aGVuIGEgbmFtZSBpcyBub3QgdXNhYmxlXG4gICAgcHVibGljIGZteEVsZW1lbnRPYmplY3RNYXAgPSBuZXcgTWFwPEZhbWl4LkVudGl0eSxUU01vcnBoT2JqZWN0VHlwZT4oKTtcbiAgICBwdWJsaWMgdHNNb3JwaEVsZW1lbnRPYmplY3RNYXAgPSBuZXcgTWFwPFRTTW9ycGhPYmplY3RUeXBlLEZhbWl4LkVudGl0eT4oKTtcbiAgICAgICAgICAgIFxuICAgIGNvbnN0cnVjdG9yKCkge1xuICAgICAgICB0aGlzLmZhbWl4UmVwLnNldEZteEVsZW1lbnRPYmplY3RNYXAodGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwKTsgICAgICBcbiAgICB9XG5cbiAgICBwdWJsaWMgYWRkU291cmNlQW5jaG9yKGZteDogRmFtaXguU291cmNlZEVudGl0eSwgbm9kZTogVFNNb3JwaE9iamVjdFR5cGUpOiBGYW1peC5JbmRleGVkRmlsZUFuY2hvciB7XG4gICAgICAgIGNvbnN0IHNvdXJjZUFuY2hvcjogRmFtaXguSW5kZXhlZEZpbGVBbmNob3IgPSBuZXcgRmFtaXguSW5kZXhlZEZpbGVBbmNob3IoKTtcbiAgICAgICAgbGV0IHNvdXJjZVN0YXJ0LCBzb3VyY2VFbmQ6IG51bWJlcjtcbiAgICAgICAgaWYgKGZteCAmJiBub2RlKSB7XG4gICAgICAgICAgICAvLyBmaW5kIHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiB0aGUgc291cmNlIGVsZW1lbnRcbiAgICAgICAgICAgIGlmICghKG5vZGUgaW5zdGFuY2VvZiBDb21tZW50UmFuZ2UpKSB7XG4gICAgICAgICAgICAgICAgc291cmNlU3RhcnQgPSBub2RlLmdldFN0YXJ0KCk7XG4gICAgICAgICAgICAgICAgc291cmNlRW5kID0gbm9kZS5nZXRFbmQoKTtcbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgc291cmNlU3RhcnQgPSBub2RlLmdldFBvcygpO1xuICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IG5vZGUuZ2V0RW5kKCk7XG4gICAgICAgICAgICB9XG4gICAgXG4gICAgICAgICAgICBpZiAoY29uZmlnLmV4cGVjdEdyYXBoZW1lcykge1xuICAgICAgICAgICAgICAgIC8qKlxuICAgICAgICAgICAgICAgICAqIFRoZSBmb2xsb3dpbmcgbG9naWMgaGFuZGxlcyB0aGUgY2FzZSBvZiBtdWx0aS1jb2RlIHBvaW50IGNoYXJhY3RlcnMgKGUuZy4gZW1vamkpIGluIHRoZSBzb3VyY2UgdGV4dC5cbiAgICAgICAgICAgICAgICAgKiBUaGlzIGlzIG5lZWRlZCBiZWNhdXNlIFBoYXJvL1NtYWxsdGFsayB0cmVhdHMgbXVsdGktY29kZSBwb2ludCBjaGFyYWN0ZXJzIGFzIGEgc2luZ2xlIGNoYXJhY3RlciwgXG4gICAgICAgICAgICAgICAgICogYnV0IEphdmFTY3JpcHQgdHJlYXRzIHRoZW0gYXMgbXVsdGlwbGUgY2hhcmFjdGVycy4gVGhpcyBtZWFucyB0aGF0IHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9uc1xuICAgICAgICAgICAgICAgICAqIG9mIGEgc291cmNlIGVsZW1lbnQgaW4gUGhhcm8vU21hbGx0YWxrIHdpbGwgYmUgZGlmZmVyZW50IHRoYW4gdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIHRoZVxuICAgICAgICAgICAgICAgICAqIHNhbWUgc291cmNlIGVsZW1lbnQgaW4gSmF2YVNjcmlwdC4gVGhpcyBsb2dpYyBmaW5kcyB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnMgb2YgdGhlIHNvdXJjZVxuICAgICAgICAgICAgICAgICAqIGVsZW1lbnQgaW4gSmF2YVNjcmlwdCBhbmQgdGhlbiB1c2VzIHRob3NlIHBvc2l0aW9ucyB0byBzZXQgdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIHRoZVxuICAgICAgICAgICAgICAgICAqIEZhbWl4IGluZGV4IGZpbGUgYW5jaG9yLlxuICAgICAgICAgICAgICAgICAqIEl0IGRlcGVuZHMgb24gY29kZSBpbiB0aGUgJ2dyYXBoZW1lLXNwbGl0dGVyJyBwYWNrYWdlIGluIG5wbS5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjb25zdCBzcGxpdHRlciA9IG5ldyBHcmFwaGVtZVNwbGl0dGVyKCk7XG4gICAgICAgICAgICAgICAgY29uc3Qgc291cmNlRmlsZVRleHQgPSBub2RlLmdldFNvdXJjZUZpbGUoKS5nZXRGdWxsVGV4dCgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGhhc0dyYXBoZW1lQ2x1c3RlcnMgPSBzcGxpdHRlci5jb3VudEdyYXBoZW1lcyhzb3VyY2VGaWxlVGV4dCkgPiAxO1xuICAgICAgICAgICAgICAgIGlmIChoYXNHcmFwaGVtZUNsdXN0ZXJzKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUVsZW1lbnRUZXh0ID0gc291cmNlRmlsZVRleHQuc3Vic3RyaW5nKHNvdXJjZVN0YXJ0LCBzb3VyY2VFbmQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcyA9IHNwbGl0dGVyLnNwbGl0R3JhcGhlbWVzKHNvdXJjZUVsZW1lbnRUZXh0KTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291cmNlRmlsZVRleHRHcmFwaGVtZXMgPSBzcGxpdHRlci5zcGxpdEdyYXBoZW1lcyhzb3VyY2VGaWxlVGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IG51bWJlck9mR3JhcGhlbWVDbHVzdGVyc0JlZm9yZVN0YXJ0ID0gc3BsaXR0ZXIuY291bnRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQuc3Vic3RyaW5nKDAsIHNvdXJjZVN0YXJ0KSk7XG4gICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAvLyBmaW5kIHRoZSBzdGFydCBvZiB0aGUgc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMgYXJyYXkgaW4gdGhlIHNvdXJjZUZpbGVUZXh0R3JhcGhlbWVzIGFycmF5XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gSGVscGVycy5pbmRleE9mU3BsaXRBcnJheSh7c2VhcmNoQXJyYXk6IHNvdXJjZUZpbGVUZXh0R3JhcGhlbWVzLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFyZ2V0QXJyYXk6IHNvdXJjZUVsZW1lbnRUZXh0R3JhcGhlbWVzLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3RhcnQ6IHNvdXJjZVN0YXJ0IC0gbnVtYmVyT2ZHcmFwaGVtZUNsdXN0ZXJzQmVmb3JlU3RhcnR9KTtcbiAgICAgICAgICAgICAgICAgICAgc291cmNlRW5kID0gc291cmNlU3RhcnQgKyBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcy5sZW5ndGg7XG4gICAgICAgICAgICAgICAgfSBcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVGhlICsxIGlzIGJlY2F1c2UgdGhlIHNvdXJjZSBhbmNob3IgKFBoYXJvKSBpcyAxLWJhc2VkLCBidXQgdHMtbW9ycGggaXMgMC1iYXNlZFxuICAgICAgICAgICAgc291cmNlQW5jaG9yLnN0YXJ0UG9zID0gc291cmNlU3RhcnQgKyAxO1xuICAgICAgICAgICAgc291cmNlQW5jaG9yLmVuZFBvcyA9IHNvdXJjZUVuZCArIDE7XG5cbiAgICAgICAgICAgIGNvbnN0IGZpbGVOYW1lID0gbm9kZS5nZXRTb3VyY2VGaWxlKCkuZ2V0RmlsZVBhdGgoKTtcblxuICAgICAgICAgICAgc291cmNlQW5jaG9yLmVsZW1lbnQgPSBmbXg7XG4gICAgICAgICAgICBzb3VyY2VBbmNob3IuZmlsZU5hbWUgPSBmaWxlTmFtZTtcbiAgICAgICAgICAgIGZteC5zb3VyY2VBbmNob3IgPSBzb3VyY2VBbmNob3I7XG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoc291cmNlQW5jaG9yKTtcblxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBzb3VyY2VBbmNob3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogTWFrZXMgYSBGYW1peCBpbmRleCBmaWxlIGFuY2hvclxuICAgICAqIEBwYXJhbSBzb3VyY2VFbGVtZW50IEEgc291cmNlIGVsZW1lbnRcbiAgICAgKiBAcGFyYW0gZmFtaXhFbGVtZW50IFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgc291cmNlIGVsZW1lbnRcbiAgICAgKi9cbiAgICBwdWJsaWMgbWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKHNvdXJjZUVsZW1lbnQ6IFRTTW9ycGhPYmplY3RUeXBlLCBmYW1peEVsZW1lbnQ6IEZhbWl4LlNvdXJjZWRFbnRpdHkpOiB2b2lkIHtcbiAgICAgICAgLy8gY2hlY2sgaWYgZmFtaXhFbGVtZW50IGRvZXNuJ3QgaGF2ZSBhIHZhbGlkIGZ1bGx5UXVhbGlmaWVkTmFtZVxuICAgICAgICBpZiAodHlwZW9mIChmYW1peEVsZW1lbnQgYXMgYW55KS5nZXRGdWxseVF1YWxpZmllZE5hbWUgPT09ICdmdW5jdGlvbicpIHtcbiAgICAgICAgICAgIC8vIFRoZSBtZXRob2QgZXhpc3RzXG4gICAgICAgICAgICBjb25zdCBmdWxseVF1YWxpZmllZE5hbWUgPSAoZmFtaXhFbGVtZW50IGFzIGFueSkuZnVsbHlRdWFsaWZpZWROYW1lO1xuICAgICAgICAgICAgaWYgKCFmdWxseVF1YWxpZmllZE5hbWUgfHwgZnVsbHlRdWFsaWZpZWROYW1lID09PSB0aGlzLlVOS05PV05fVkFMVUUpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEZhbWl4IGVsZW1lbnQgJHtmYW1peEVsZW1lbnQuY29uc3RydWN0b3IubmFtZX0gaGFzIG5vIHZhbGlkIGZ1bGx5UXVhbGlmaWVkTmFtZS5gKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhcIm1ha2luZyBpbmRleCBmaWxlIGFuY2hvciBmb3IgJ1wiICsgc291cmNlRWxlbWVudD8uZ2V0VGV4dCgpICsgXCInIHdpdGggZmFtaXhFbGVtZW50IFwiICsgZmFtaXhFbGVtZW50LmdldEpTT04oKSk7XG4gICAgICAgIGNvbnN0IGZteEluZGV4RmlsZUFuY2hvciA9IG5ldyBGYW1peC5JbmRleGVkRmlsZUFuY2hvcigpO1xuICAgICAgICBmbXhJbmRleEZpbGVBbmNob3IuZWxlbWVudCA9IGZhbWl4RWxlbWVudDtcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmYW1peEVsZW1lbnQsIHNvdXJjZUVsZW1lbnQpO1xuXG4gICAgICAgIGlmIChzb3VyY2VFbGVtZW50ICE9PSBudWxsKSB7XG4gICAgICAgICAgICBjb25zdCBhYnNvbHV0ZVBhdGhQcm9qZWN0ID0gdGhpcy5mYW1peFJlcC5nZXRBYnNvbHV0ZVBhdGgoKTtcbiAgICAgICAgXG4gICAgICAgICAgICBjb25zdCBhYnNvbHV0ZVBhdGggPSBwYXRoLm5vcm1hbGl6ZShzb3VyY2VFbGVtZW50LmdldFNvdXJjZUZpbGUoKS5nZXRGaWxlUGF0aCgpKTtcblxuICAgICAgICAgICAgY29uc3QgcG9zaXRpb25Ob2RlTW9kdWxlcyA9IGFic29sdXRlUGF0aC5pbmRleE9mKCdub2RlX21vZHVsZXMnKTtcblxuICAgICAgICAgICAgbGV0IHBhdGhJblByb2plY3Q6IHN0cmluZyA9IFwiXCI7XG5cbiAgICAgICAgICAgIGlmIChwb3NpdGlvbk5vZGVNb2R1bGVzICE9PSAtMSkge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhdGhGcm9tTm9kZU1vZHVsZXMgPSBhYnNvbHV0ZVBhdGguc3Vic3RyaW5nKHBvc2l0aW9uTm9kZU1vZHVsZXMpO1xuICAgICAgICAgICAgICAgIHBhdGhJblByb2plY3QgPSBwYXRoRnJvbU5vZGVNb2R1bGVzO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICBwYXRoSW5Qcm9qZWN0ID0gdGhpcy5jb252ZXJ0VG9SZWxhdGl2ZVBhdGgoYWJzb2x1dGVQYXRoLCBhYnNvbHV0ZVBhdGhQcm9qZWN0KTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gcmV2ZXJ0IGFueSBiYWNrc2xhc2hlcyB0byBmb3J3YXJkIHNsYXNoZXMgKHBhdGgubm9ybWFsaXplIG9uIHdpbmRvd3MgaW50cm9kdWNlcyB0aGVtKVxuICAgICAgICAgICAgcGF0aEluUHJvamVjdCA9IHBhdGhJblByb2plY3QucmVwbGFjZSgvXFxcXC9nLCBcIi9cIik7XG5cbiAgICAgICAgICAgIGZteEluZGV4RmlsZUFuY2hvci5maWxlTmFtZSA9IHBhdGhJblByb2plY3Q7XG4gICAgICAgICAgICBsZXQgc291cmNlU3RhcnQsIHNvdXJjZUVuZCwgc291cmNlTGluZVN0YXJ0LCBzb3VyY2VMaW5lRW5kOiBudW1iZXI7XG4gICAgICAgICAgICBpZiAoIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSkge1xuICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gc291cmNlRWxlbWVudC5nZXRTdGFydCgpO1xuICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IHNvdXJjZUVsZW1lbnQuZ2V0RW5kKCk7XG4gICAgICAgICAgICAgICAgc291cmNlTGluZVN0YXJ0ID0gc291cmNlRWxlbWVudC5nZXRTdGFydExpbmVOdW1iZXIoKTtcbiAgICAgICAgICAgICAgICBzb3VyY2VMaW5lRW5kID0gc291cmNlRWxlbWVudC5nZXRFbmRMaW5lTnVtYmVyKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHNvdXJjZVN0YXJ0ID0gc291cmNlRWxlbWVudC5nZXRQb3MoKTtcbiAgICAgICAgICAgICAgICBzb3VyY2VFbmQgPSBzb3VyY2VFbGVtZW50LmdldEVuZCgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGNvbmZpZy5leHBlY3RHcmFwaGVtZXMpIHtcbiAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgKiBUaGUgZm9sbG93aW5nIGxvZ2ljIGhhbmRsZXMgdGhlIGNhc2Ugb2YgbXVsdGktY29kZSBwb2ludCBjaGFyYWN0ZXJzIChlLmcuIGVtb2ppKSBpbiB0aGUgc291cmNlIHRleHQuXG4gICAgICAgICAgICAgICAgICogVGhpcyBpcyBuZWVkZWQgYmVjYXVzZSBQaGFyby9TbWFsbHRhbGsgdHJlYXRzIG11bHRpLWNvZGUgcG9pbnQgY2hhcmFjdGVycyBhcyBhIHNpbmdsZSBjaGFyYWN0ZXIsIFxuICAgICAgICAgICAgICAgICAqIGJ1dCBKYXZhU2NyaXB0IHRyZWF0cyB0aGVtIGFzIG11bHRpcGxlIGNoYXJhY3RlcnMuIFRoaXMgbWVhbnMgdGhhdCB0aGUgc3RhcnQgYW5kIGVuZCBwb3NpdGlvbnNcbiAgICAgICAgICAgICAgICAgKiBvZiBhIHNvdXJjZSBlbGVtZW50IGluIFBoYXJvL1NtYWxsdGFsayB3aWxsIGJlIGRpZmZlcmVudCB0aGFuIHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiB0aGVcbiAgICAgICAgICAgICAgICAgKiBzYW1lIHNvdXJjZSBlbGVtZW50IGluIEphdmFTY3JpcHQuIFRoaXMgbG9naWMgZmluZHMgdGhlIHN0YXJ0IGFuZCBlbmQgcG9zaXRpb25zIG9mIHRoZSBzb3VyY2VcbiAgICAgICAgICAgICAgICAgKiBlbGVtZW50IGluIEphdmFTY3JpcHQgYW5kIHRoZW4gdXNlcyB0aG9zZSBwb3NpdGlvbnMgdG8gc2V0IHRoZSBzdGFydCBhbmQgZW5kIHBvc2l0aW9ucyBvZiB0aGVcbiAgICAgICAgICAgICAgICAgKiBGYW1peCBpbmRleCBmaWxlIGFuY2hvci5cbiAgICAgICAgICAgICAgICAgKiBJdCBkZXBlbmRzIG9uIGNvZGUgaW4gdGhlICdncmFwaGVtZS1zcGxpdHRlcicgcGFja2FnZSBpbiBucG0uXG4gICAgICAgICAgICAgICAgICovXG4gICAgICAgICAgICAgICAgY29uc3Qgc3BsaXR0ZXIgPSBuZXcgR3JhcGhlbWVTcGxpdHRlcigpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUZpbGVUZXh0ID0gc291cmNlRWxlbWVudC5nZXRTb3VyY2VGaWxlKCkuZ2V0RnVsbFRleHQoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBoYXNHcmFwaGVtZUNsdXN0ZXJzID0gc3BsaXR0ZXIuY291bnRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQpID4gMTtcbiAgICAgICAgICAgICAgICBpZiAoaGFzR3JhcGhlbWVDbHVzdGVycykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VFbGVtZW50VGV4dCA9IHNvdXJjZUZpbGVUZXh0LnN1YnN0cmluZyhzb3VyY2VTdGFydCwgc291cmNlRW5kKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3Qgc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMgPSBzcGxpdHRlci5zcGxpdEdyYXBoZW1lcyhzb3VyY2VFbGVtZW50VGV4dCk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IHNvdXJjZUZpbGVUZXh0R3JhcGhlbWVzID0gc3BsaXR0ZXIuc3BsaXRHcmFwaGVtZXMoc291cmNlRmlsZVRleHQpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBudW1iZXJPZkdyYXBoZW1lQ2x1c3RlcnNCZWZvcmVTdGFydCA9IHNwbGl0dGVyLmNvdW50R3JhcGhlbWVzKHNvdXJjZUZpbGVUZXh0LnN1YnN0cmluZygwLCBzb3VyY2VTdGFydCkpO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgLy8gZmluZCB0aGUgc3RhcnQgb2YgdGhlIHNvdXJjZUVsZW1lbnRUZXh0R3JhcGhlbWVzIGFycmF5IGluIHRoZSBzb3VyY2VGaWxlVGV4dEdyYXBoZW1lcyBhcnJheVxuICAgICAgICAgICAgICAgICAgICBzb3VyY2VTdGFydCA9IEhlbHBlcnMuaW5kZXhPZlNwbGl0QXJyYXkoe3NlYXJjaEFycmF5OiBzb3VyY2VGaWxlVGV4dEdyYXBoZW1lcywgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRhcmdldEFycmF5OiBzb3VyY2VFbGVtZW50VGV4dEdyYXBoZW1lcywgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHN0YXJ0OiBzb3VyY2VTdGFydCAtIG51bWJlck9mR3JhcGhlbWVDbHVzdGVyc0JlZm9yZVN0YXJ0fSk7XG4gICAgICAgICAgICAgICAgICAgIHNvdXJjZUVuZCA9IHNvdXJjZVN0YXJ0ICsgc291cmNlRWxlbWVudFRleHRHcmFwaGVtZXMubGVuZ3RoO1xuICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAvLyBub3RlOiB0aGUgKzEgaXMgYmVjYXVzZSB0aGUgc291cmNlIGFuY2hvciBpcyAxLWJhc2VkLCBidXQgdHMtbW9ycGggaXMgMC1iYXNlZFxuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLnN0YXJ0UG9zID0gc291cmNlU3RhcnQgKyAxO1xuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLmVuZFBvcyA9IHNvdXJjZUVuZCArIDE7XG5cbiAgICAgICAgICAgIC8vIGlmICghKGZhbWl4RWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LkltcG9ydENsYXVzZSB8fCBmYW1peEVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5BY2Nlc3MgfHwgZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUmVmZXJlbmNlIHx8IGZhbWl4RWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4Lkludm9jYXRpb24gfHwgZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguSW5oZXJpdGFuY2UpICYmICEoZmFtaXhFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguQ29tbWVudCkgJiYgIShzb3VyY2VFbGVtZW50IGluc3RhbmNlb2YgQ29tbWVudFJhbmdlKSAmJiAhKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBJZGVudGlmaWVyKSAmJiAhKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBJbXBvcnRTcGVjaWZpZXIpICYmICEoc291cmNlRWxlbWVudCBpbnN0YW5jZW9mIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cykpIHtcbiAgICAgICAgICAgIC8vICAgIGluaXRGUU4oc291cmNlRWxlbWVudCwgZmFtaXhFbGVtZW50KTtcbiAgICAgICAgICAgIC8vIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIHNvdXJjZUVsZW1lbnQgaXMgbnVsbFxuICAgICAgICAgICAgbG9nZ2VyLndhcm4oXCJzb3VyY2VFbGVtZW50IGlzIG51bGwgZm9yIGZhbWl4RWxlbWVudCBcIiArIGZhbWl4RWxlbWVudC5nZXRKU09OKCkpO1xuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLmZpbGVOYW1lID0gXCJ1bmtub3duXCI7XG4gICAgICAgICAgICBmbXhJbmRleEZpbGVBbmNob3Iuc3RhcnRQb3MgPSAwO1xuICAgICAgICAgICAgZm14SW5kZXhGaWxlQW5jaG9yLmVuZFBvcyA9IDA7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW5kZXhGaWxlQW5jaG9yKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBzY3JpcHQgZW50aXR5IG9yIG1vZHVsZVxuICAgICAqIEBwYXJhbSBmIEEgc291cmNlIGZpbGVcbiAgICAgKiBAcGFyYW0gaXNNb2R1bGUgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIHNvdXJjZSBmaWxlIGlzIGEgbW9kdWxlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBzb3VyY2UgZmlsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4RmlsZShmOiBTb3VyY2VGaWxlLCBpc01vZHVsZTogYm9vbGVhbik6IEZhbWl4LlNjcmlwdEVudGl0eSB8IEZhbWl4Lk1vZHVsZSB7XG4gICAgICAgIGxldCBmbXhGaWxlOiBGYW1peC5TY3JpcHRFbnRpdHk7IC8vIHwgRmFtaXguTW9kdWxlO1xuXG4gICAgICAgIGNvbnN0IGZpbGVOYW1lID0gZi5nZXRCYXNlTmFtZSgpO1xuICAgICAgICBjb25zdCBmdWxseVF1YWxpZmllZEZpbGVuYW1lID0gZi5nZXRGaWxlUGF0aCgpO1xuICAgICAgICBjb25zdCBmb3VuZEZpbGVOYW1lID0gdGhpcy5mbXhGaWxlTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKTtcbiAgICAgICAgaWYgKCFmb3VuZEZpbGVOYW1lKSB7XG4gICAgICAgICAgICBpZiAoaXNNb2R1bGUpIHtcbiAgICAgICAgICAgICAgICBmbXhGaWxlID0gbmV3IEZhbWl4Lk1vZHVsZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm14RmlsZSA9IG5ldyBGYW1peC5TY3JpcHRFbnRpdHkoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGZteEZpbGUubmFtZSA9IGZpbGVOYW1lO1xuICAgICAgICAgICAgZm14RmlsZS5udW1iZXJPZkxpbmVzT2ZUZXh0ID0gZi5nZXRFbmRMaW5lTnVtYmVyKCkgLSBmLmdldFN0YXJ0TGluZU51bWJlcigpO1xuICAgICAgICAgICAgZm14RmlsZS5udW1iZXJPZkNoYXJhY3RlcnMgPSBmLmdldEZ1bGxUZXh0KCkubGVuZ3RoO1xuXG4gICAgICAgICAgICBpbml0RlFOKGYsIGZteEZpbGUpO1xuXG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihmLCBmbXhGaWxlKTtcblxuICAgICAgICAgICAgdGhpcy5mbXhGaWxlTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBmbXhGaWxlKTtcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhGaWxlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZteEZpbGUgPSBmb3VuZEZpbGVOYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhGaWxlLGYpO1xuICAgICAgICByZXR1cm4gZm14RmlsZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBNb2R1bGVcbiAgICAgKiBAcGFyYW0gbSBBIG1vZHVsZVxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgbW9kdWxlXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhNb2R1bGUobTogTW9kdWxlRGVjbGFyYXRpb24pOiBGYW1peC5Nb2R1bGUge1xuICAgICAgICBsZXQgZm14TW9kdWxlOiBGYW1peC5Nb2R1bGU7XG4gICAgICAgIGNvbnN0IG1vZHVsZU5hbWUgPSBtLmdldE5hbWUoKTtcbiAgICAgICAgY29uc3QgZm91bmRNb2R1bGVOYW1lID0gdGhpcy5mbXhNb2R1bGVNYXAuZ2V0KG1vZHVsZU5hbWUpO1xuICAgICAgICBpZiAoIWZvdW5kTW9kdWxlTmFtZSkge1xuICAgICAgICAgICAgZm14TW9kdWxlID0gbmV3IEZhbWl4Lk1vZHVsZSgpO1xuICAgICAgICAgICAgZm14TW9kdWxlLm5hbWUgPSBtb2R1bGVOYW1lO1xuICAgICAgICAgICAgZm14TW9kdWxlLmlzQW1iaWVudCA9IGlzQW1iaWVudChtKTtcbiAgICAgICAgICAgIGZteE1vZHVsZS5pc05hbWVzcGFjZSA9IGlzTmFtZXNwYWNlKG0pO1xuICAgICAgICAgICAgZm14TW9kdWxlLmlzTW9kdWxlID0gIWZteE1vZHVsZS5pc05hbWVzcGFjZSAmJiAhZm14TW9kdWxlLmlzQW1iaWVudDtcblxuICAgICAgICAgICAgaW5pdEZRTihtLCBmbXhNb2R1bGUpO1xuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IobSwgZm14TW9kdWxlKTtcblxuICAgICAgICAgICAgdGhpcy5mbXhNb2R1bGVNYXAuc2V0KG1vZHVsZU5hbWUsIGZteE1vZHVsZSk7XG5cbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhNb2R1bGUpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14TW9kdWxlID0gZm91bmRNb2R1bGVOYW1lO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhNb2R1bGUsbSk7XG4gICAgICAgIHJldHVybiBmbXhNb2R1bGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGFsaWFzXG4gICAgICogQHBhcmFtIGEgQW4gYWxpYXNcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGFsaWFzXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4QWxpYXMoYTogVHlwZUFsaWFzRGVjbGFyYXRpb24pOiBGYW1peC5BbGlhcyB7XG4gICAgICAgIGxldCBmbXhBbGlhczogRmFtaXguQWxpYXM7XG4gICAgICAgIGNvbnN0IGFsaWFzTmFtZSA9IGEuZ2V0TmFtZSgpO1xuICAgICAgICBjb25zdCBhbGlhc0Z1bGx5UXVhbGlmaWVkTmFtZSA9IGEuZ2V0VHlwZSgpLmdldFRleHQoKTsgLy8gRlFORnVuY3Rpb25zLmdldEZRTihhKTtcbiAgICAgICAgY29uc3QgZm91bmRBbGlhcyA9IHRoaXMuZm14QWxpYXNNYXAuZ2V0KGFsaWFzRnVsbHlRdWFsaWZpZWROYW1lKTtcbiAgICAgICAgaWYgKCFmb3VuZEFsaWFzKSB7XG4gICAgICAgICAgICBmbXhBbGlhcyA9IG5ldyBGYW1peC5BbGlhcygpO1xuICAgICAgICAgICAgZm14QWxpYXMubmFtZSA9IGEuZ2V0TmFtZSgpO1xuICAgICAgICAgICAgY29uc3QgYWxpYXNOYW1lV2l0aEdlbmVyaWNzID0gYWxpYXNOYW1lICsgKGEuZ2V0VHlwZVBhcmFtZXRlcnMoKS5sZW5ndGggPyAoXCI8XCIgKyBhLmdldFR5cGVQYXJhbWV0ZXJzKCkubWFwKHRwID0+IHRwLmdldE5hbWUoKSkuam9pbihcIiwgXCIpICsgXCI+XCIpIDogXCJcIik7XG4gICAgICAgICAgICBsb2dnZXIuZGVidWcoYD4gTk9URTogYWxpYXMgJHthbGlhc05hbWV9IGhhcyBmdWxseSBxdWFsaWZpZWQgbmFtZSAke2FsaWFzRnVsbHlRdWFsaWZpZWROYW1lfSBhbmQgbmFtZSB3aXRoIGdlbmVyaWNzICR7YWxpYXNOYW1lV2l0aEdlbmVyaWNzfS5gKTtcblxuICAgICAgICAgICAgY29uc3QgZm14VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoYWxpYXNOYW1lV2l0aEdlbmVyaWNzLCBhKTtcbiAgICAgICAgICAgIGZteEFsaWFzLmFsaWFzZWRFbnRpdHkgPSBmbXhUeXBlO1xuICAgICAgICAgICAgaW5pdEZRTihhLCBmbXhBbGlhcyk7XG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihhLCBmbXhBbGlhcyk7XG5cbiAgICAgICAgICAgIHRoaXMuZm14QWxpYXNNYXAuc2V0KGFsaWFzRnVsbHlRdWFsaWZpZWROYW1lLCBmbXhBbGlhcyk7XG5cbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhBbGlhcyk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBmbXhBbGlhcyA9IGZvdW5kQWxpYXM7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhBbGlhcyxhKTtcblxuICAgICAgICByZXR1cm4gZm14QWxpYXM7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBvciBnZXRzIGEgRmFtaXggY2xhc3Mgb3IgcGFyYW1ldGVyaXphYmxlIGNsYXNzXG4gICAgICogQHBhcmFtIGNscyBBIGNsYXNzXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBjbGFzc1xuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4Q2xhc3MoY2xzOiBDbGFzc0RlY2xhcmF0aW9uKTogRmFtaXguQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljQ2xhc3Mge1xuICAgICAgICBsZXQgZm14Q2xhc3M6IEZhbWl4LkNsYXNzIHwgRmFtaXguUGFyYW1ldHJpY0NsYXNzO1xuICAgICAgICBjb25zdCBpc0Fic3RyYWN0ID0gY2xzLmlzQWJzdHJhY3QoKTtcbiAgICAgICAgY29uc3QgY2xhc3NGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGNscyk7XG4gICAgICAgIGNvbnN0IGNsc05hbWUgPSBjbHMuZ2V0TmFtZSgpIHx8IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgY29uc3QgaXNHZW5lcmljID0gY2xzLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoO1xuICAgICAgICBjb25zdCBmb3VuZENsYXNzID0gdGhpcy5mbXhDbGFzc01hcC5nZXQoY2xhc3NGdWxseVF1YWxpZmllZE5hbWUpO1xuICAgICAgICBpZiAoIWZvdW5kQ2xhc3MpIHtcbiAgICAgICAgICAgIGlmIChpc0dlbmVyaWMpIHtcbiAgICAgICAgICAgICAgICBmbXhDbGFzcyA9IG5ldyBGYW1peC5QYXJhbWV0cmljQ2xhc3MoKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgIGZteENsYXNzID0gbmV3IEZhbWl4LkNsYXNzKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZteENsYXNzLm5hbWUgPSBjbHNOYW1lO1xuICAgICAgICAgICAgZm14Q2xhc3MuZnVsbHlRdWFsaWZpZWROYW1lID0gY2xhc3NGdWxseVF1YWxpZmllZE5hbWU7XG4gICAgICAgICAgICBmbXhDbGFzcy5pc0Fic3RyYWN0ID0gaXNBYnN0cmFjdDtcblxuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IoY2xzLCBmbXhDbGFzcyk7XG5cbiAgICAgICAgICAgIHRoaXMuZm14Q2xhc3NNYXAuc2V0KGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lLCBmbXhDbGFzcyk7XG5cbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhDbGFzcyk7XG5cbiAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14Q2xhc3MsY2xzKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZteENsYXNzID0gZm91bmRDbGFzcztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbXhDbGFzcztcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBpbnRlcmZhY2Ugb3IgcGFyYW1ldGVyaXphYmxlIGludGVyZmFjZVxuICAgICAqIEBwYXJhbSBpbnRlciBBbiBpbnRlcmZhY2VcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGludGVyZmFjZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4SW50ZXJmYWNlKGludGVyOiBJbnRlcmZhY2VEZWNsYXJhdGlvbik6IEZhbWl4LkludGVyZmFjZSB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2Uge1xuXG4gICAgICAgIGxldCBmbXhJbnRlcmZhY2U6IEZhbWl4LkludGVyZmFjZSB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2U7XG4gICAgICAgIGNvbnN0IGludGVyTmFtZSA9IGludGVyLmdldE5hbWUoKTtcbiAgICAgICAgY29uc3QgaW50ZXJGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGludGVyKTtcbiAgICAgICAgY29uc3QgZm91bmRJbnRlcmZhY2UgPSB0aGlzLmZteEludGVyZmFjZU1hcC5nZXQoaW50ZXJGdWxseVF1YWxpZmllZE5hbWUpO1xuICAgICAgICBpZiAoIWZvdW5kSW50ZXJmYWNlKSB7XG4gICAgICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBpbnRlci5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aDtcbiAgICAgICAgICAgIGlmIChpc0dlbmVyaWMpIHtcbiAgICAgICAgICAgICAgICBmbXhJbnRlcmZhY2UgPSBuZXcgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm14SW50ZXJmYWNlID0gbmV3IEZhbWl4LkludGVyZmFjZSgpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmbXhJbnRlcmZhY2UubmFtZSA9IGludGVyTmFtZTtcbiAgICAgICAgICAgIGluaXRGUU4oaW50ZXIsIGZteEludGVyZmFjZSk7XG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihpbnRlciwgZm14SW50ZXJmYWNlKTtcblxuICAgICAgICAgICAgdGhpcy5mbXhJbnRlcmZhY2VNYXAuc2V0KGludGVyRnVsbHlRdWFsaWZpZWROYW1lLCBmbXhJbnRlcmZhY2UpO1xuXG4gICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW50ZXJmYWNlKTtcblxuICAgICAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhJbnRlcmZhY2UsaW50ZXIpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14SW50ZXJmYWNlID0gZm91bmRJbnRlcmZhY2U7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGZteEludGVyZmFjZTtcbiAgICB9XG5cbiAgICBcbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBjb25jcmV0ZSBlbGVtZW50XG4gICAgICogQHBhcmFtIGNvbmNyZXRlRWxlbWVudCBBIHBhcmFtZXRyaWMgRWxlbWVudCAgIFxuICAgICAqIEBwYXJhbSBjb25jcmV0ZUVsZW1lbnREZWNsYXJhdGlvbiB0aGUgZWxlbWVudCBkZWNsYXJhdGlvblxuICAgICAqIEBwYXJhbSBjb25jcmV0ZUFyZ3VtZW50cyBjb25jcmV0ZSBhcmd1bWVudHNcbiAgICAgKiBAcmV0dXJucyBBIHBhcmFtZXRyaWMgRWxlbWVudCAgXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhDb25jcmV0ZUVsZW1lbnQoY29uY3JldGVFbGVtZW50IDogUGFyYW1ldHJpY1ZhcmlhbnRUeXBlLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0ZUVsZW1lbnREZWNsYXJhdGlvbiA6IENvbmNyZXRlRWxlbWVudFRTTW9ycGhUeXBlLCBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0ZUFyZ3VtZW50czogVHlwZU5vZGVbXSk6IFBhcmFtZXRyaWNWYXJpYW50VHlwZSB7XG4gICAgICAgIFxuICAgICAgICBsZXQgZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSA9IGNvbmNyZXRlRWxlbWVudC5mdWxseVF1YWxpZmllZE5hbWU7XG4gICAgICAgIGxldCBwYXJhbXMgPSBcIlwiO1xuICAgICAgICBcbiAgICAgICAgY29uY3JldGVBcmd1bWVudHMubWFwKChwYXJhbSkgPT4ge1xuICAgICAgICAgICAgcGFyYW1zID0gcGFyYW1zK3BhcmFtLmdldFRleHQoKSsnLCdcbiAgICAgICAgfSlcbiAgICAgICAgXG4gICAgICAgIHBhcmFtcyA9IHBhcmFtcy5zdWJzdHJpbmcoMCwgcGFyYW1zLmxlbmd0aCAtIDEpXG4gICAgICAgICAgICAgICAgXG4gICAgICAgIGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUgPSBIZWxwZXJzLnJlcGxhY2VMYXN0QmV0d2VlblRhZ3MoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSxwYXJhbXMpO1xuXG4gICAgICAgIGxldCBjb25jRWxlbWVudDogUGFyYW1ldHJpY1ZhcmlhbnRUeXBlO1xuXG4gICAgICAgIGlmICghdGhpcy5mbXhJbnRlcmZhY2VNYXAuaGFzKGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpICYmIFxuICAgICAgICAgICAgIXRoaXMuZm14Q2xhc3NNYXAuaGFzKGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpICYmIFxuICAgICAgICAgICAgIXRoaXMuZm14RnVuY3Rpb25BbmRNZXRob2RNYXAuaGFzKGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpKXtcbiAgICAgICAgICAgIGNvbmNFbGVtZW50ID0gXy5jbG9uZURlZXAoY29uY3JldGVFbGVtZW50KTsgXG4gICAgICAgICAgICBjb25jRWxlbWVudC5mdWxseVF1YWxpZmllZE5hbWUgPSBmdWxseVF1YWxpZmllZEZpbGVuYW1lO1xuICAgICAgICAgICAgY29uY0VsZW1lbnQuY2xlYXJHZW5lcmljUGFyYW1ldGVycygpO1xuICAgICAgICAgICAgY29uY3JldGVBcmd1bWVudHMubWFwKChwYXJhbSkgPT4ge1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlciA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENvbmNyZXRlVHlwZShwYXJhbSk7XG4gICAgICAgICAgICAgICAgY29uY0VsZW1lbnQuYWRkQ29uY3JldGVQYXJhbWV0ZXIocGFyYW1ldGVyKTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljQ2xhc3MpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZteENsYXNzTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljQ2xhc3MpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5mbXhJbnRlcmZhY2VNYXAuc2V0KGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUsIGNvbmNFbGVtZW50IGFzIEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UpO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24pIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24pO1xuICAgICAgICAgICAgfSBlbHNlIHsgLy8gaWYgKGNvbmNyZXRlRWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LlBhcmFtZXRyaWNNZXRob2QpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdWxseVF1YWxpZmllZEZpbGVuYW1lLCBjb25jRWxlbWVudCBhcyBGYW1peC5QYXJhbWV0cmljTWV0aG9kKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChjb25jRWxlbWVudCk7XG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGNvbmNFbGVtZW50LGNvbmNyZXRlRWxlbWVudERlY2xhcmF0aW9uKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljQ2xhc3MpIHtcbiAgICAgICAgICAgICAgICBjb25jRWxlbWVudCA9IHRoaXMuZm14Q2xhc3NNYXAuZ2V0KGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpIGFzIEZhbWl4LlBhcmFtZXRyaWNDbGFzcztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoY29uY3JldGVFbGVtZW50IGluc3RhbmNlb2YgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZSkge1xuICAgICAgICAgICAgICAgIGNvbmNFbGVtZW50ID0gdGhpcy5mbXhJbnRlcmZhY2VNYXAuZ2V0KGZ1bGx5UXVhbGlmaWVkRmlsZW5hbWUpIGFzIEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2U7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNvbmNyZXRlRWxlbWVudCBpbnN0YW5jZW9mIEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbikge1xuICAgICAgICAgICAgICAgIGNvbmNFbGVtZW50ID0gdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5nZXQoZnVsbHlRdWFsaWZpZWRGaWxlbmFtZSkgYXMgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uO1xuICAgICAgICAgICAgfSBlbHNlIHsgIC8vIGlmIChjb25jcmV0ZUVsZW1lbnQgaW5zdGFuY2VvZiBGYW1peC5QYXJhbWV0cmljTWV0aG9kKSB7XG4gICAgICAgICAgICAgICAgY29uY0VsZW1lbnQgPSB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmdldChmdWxseVF1YWxpZmllZEZpbGVuYW1lKSBhcyBGYW1peC5QYXJhbWV0cmljTWV0aG9kO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybiBjb25jRWxlbWVudDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggcHJvcGVydHlcbiAgICAgKiBAcGFyYW0gcHJvcGVydHkgQSBwcm9wZXJ0eVxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgcHJvcGVydHlcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhQcm9wZXJ0eShwcm9wZXJ0eTogUHJvcGVydHlEZWNsYXJhdGlvbiB8IFByb3BlcnR5U2lnbmF0dXJlKTogRmFtaXguUHJvcGVydHkge1xuICAgICAgICBjb25zdCBmbXhQcm9wZXJ0eSA9IG5ldyBGYW1peC5Qcm9wZXJ0eSgpO1xuICAgICAgICBjb25zdCBpc1NpZ25hdHVyZSA9IHByb3BlcnR5IGluc3RhbmNlb2YgUHJvcGVydHlTaWduYXR1cmU7XG4gICAgICAgIGZteFByb3BlcnR5Lm5hbWUgPSBwcm9wZXJ0eS5nZXROYW1lKCk7XG5cbiAgICAgICAgbGV0IHByb3BUeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHByb3BUeXBlTmFtZSA9IHByb3BlcnR5LmdldFR5cGUoKS5nZXRUZXh0KCkudHJpbSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGA+IFdBUk5JTkc6IGdvdCBleGNlcHRpb24gJHtlcnJvcn0uIEZhaWxlZCB0byBnZXQgdXNhYmxlIG5hbWUgZm9yIHByb3BlcnR5OiAke3Byb3BlcnR5LmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKHByb3BUeXBlTmFtZSwgcHJvcGVydHkpO1xuICAgICAgICBmbXhQcm9wZXJ0eS5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xuXG4gICAgICAgIC8vIGFkZCB0aGUgdmlzaWJpbGl0eSAocHVibGljLCBwcml2YXRlLCBldGMuKSB0byB0aGUgZm14UHJvcGVydHlcbiAgICAgICAgZm14UHJvcGVydHkudmlzaWJpbGl0eSA9IFwiXCI7XG5cbiAgICAgICAgcHJvcGVydHkuZ2V0TW9kaWZpZXJzKCkuZm9yRWFjaChtID0+IHtcbiAgICAgICAgICAgIHN3aXRjaCAobS5nZXRUZXh0KCkpIHtcbiAgICAgICAgICAgICAgICBjYXNlIFNjb3BlLlB1YmxpYzpcbiAgICAgICAgICAgICAgICAgICAgZm14UHJvcGVydHkudmlzaWJpbGl0eSA9IFwicHVibGljXCI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgU2NvcGUuUHJvdGVjdGVkOlxuICAgICAgICAgICAgICAgICAgICBmbXhQcm9wZXJ0eS52aXNpYmlsaXR5ID0gXCJwcm90ZWN0ZWRcIjtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgY2FzZSBTY29wZS5Qcml2YXRlOlxuICAgICAgICAgICAgICAgICAgICBmbXhQcm9wZXJ0eS52aXNpYmlsaXR5ID0gXCJwcml2YXRlXCI7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIGNhc2UgXCJzdGF0aWNcIjpcbiAgICAgICAgICAgICAgICAgICAgZm14UHJvcGVydHkuaXNDbGFzc1NpZGUgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBjYXNlIFwicmVhZG9ubHlcIjpcbiAgICAgICAgICAgICAgICAgICAgZm14UHJvcGVydHkucmVhZE9ubHkgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSk7XG5cbiAgICAgICAgaWYgKCFpc1NpZ25hdHVyZSAmJiBwcm9wZXJ0eS5nZXRFeGNsYW1hdGlvblRva2VuTm9kZSgpKSB7XG4gICAgICAgICAgICBmbXhQcm9wZXJ0eS5pc0RlZmluaXRlbHlBc3NpZ25lZCA9IHRydWU7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHByb3BlcnR5LmdldFF1ZXN0aW9uVG9rZW5Ob2RlKCkpIHtcbiAgICAgICAgICAgIGZteFByb3BlcnR5LmlzT3B0aW9uYWwgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICAgIGlmIChwcm9wZXJ0eS5nZXROYW1lKCkuc3Vic3RyaW5nKDAsIDEpID09PSBcIiNcIikge1xuICAgICAgICAgICAgZm14UHJvcGVydHkuaXNKYXZhU2NyaXB0UHJpdmF0ZSA9IHRydWU7XG4gICAgICAgIH1cblxuICAgICAgICBpbml0RlFOKHByb3BlcnR5LCBmbXhQcm9wZXJ0eSk7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKHByb3BlcnR5LCBmbXhQcm9wZXJ0eSk7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFByb3BlcnR5KTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteFByb3BlcnR5LHByb3BlcnR5KTtcblxuICAgICAgICByZXR1cm4gZm14UHJvcGVydHk7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IG1ldGhvZCBvciBhY2Nlc3NvclxuICAgICAqIEBwYXJhbSBtZXRob2QgQSBtZXRob2Qgb3IgYW4gYWNjZXNzb3JcbiAgICAgKiBAcGFyYW0gY3VycmVudENDIFRoZSBjeWNsb21hdGljIGNvbXBsZXhpdHkgbWV0cmljcyBvZiB0aGUgY3VycmVudCBzb3VyY2UgZmlsZVxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgbWV0aG9kIG9yIHRoZSBhY2Nlc3NvclxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVPckdldEZhbWl4TWV0aG9kKG1ldGhvZDogTWV0aG9kRGVjbGFyYXRpb24gfCBDb25zdHJ1Y3RvckRlY2xhcmF0aW9uIHwgTWV0aG9kU2lnbmF0dXJlIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24sIGN1cnJlbnRDQzogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSk6IEZhbWl4Lk1ldGhvZCB8IEZhbWl4LkFjY2Vzc29yIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZCB7XG4gICAgICAgIGxldCBmbXhNZXRob2Q6IEZhbWl4Lk1ldGhvZCB8IEZhbWl4LkFjY2Vzc29yIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZDtcbiAgICAgICAgY29uc3QgaXNHZW5lcmljID0gbWV0aG9kLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgY29uc3QgZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKG1ldGhvZCk7XG4gICAgICAgIGlmICghdGhpcy5mbXhGdW5jdGlvbkFuZE1ldGhvZE1hcC5oYXMoZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUpKSB7XG5cbiAgICAgICAgICAgIGlmIChtZXRob2QgaW5zdGFuY2VvZiBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIFNldEFjY2Vzc29yRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgICAgICBmbXhNZXRob2QgPSBuZXcgRmFtaXguQWNjZXNzb3IoKTtcbiAgICAgICAgICAgICAgICBjb25zdCBpc0dldHRlciA9IG1ldGhvZCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgY29uc3QgaXNTZXR0ZXIgPSBtZXRob2QgaW5zdGFuY2VvZiBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uO1xuICAgICAgICAgICAgICAgIGlmIChpc0dldHRlcikgeyhmbXhNZXRob2QgYXMgRmFtaXguQWNjZXNzb3IpLmtpbmQgPSBcImdldHRlclwiO31cbiAgICAgICAgICAgICAgICBpZiAoaXNTZXR0ZXIpIHsoZm14TWV0aG9kIGFzIEZhbWl4LkFjY2Vzc29yKS5raW5kID0gXCJzZXR0ZXJcIjt9XG4gICAgICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteE1ldGhvZCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBpZiAoaXNHZW5lcmljKSB7XG4gICAgICAgICAgICAgICAgICAgIGZteE1ldGhvZCA9IG5ldyBGYW1peC5QYXJhbWV0cmljTWV0aG9kKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBmbXhNZXRob2QgPSBuZXcgRmFtaXguTWV0aG9kKCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhNZXRob2QpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgaXNDb25zdHJ1Y3RvciA9IG1ldGhvZCBpbnN0YW5jZW9mIENvbnN0cnVjdG9yRGVjbGFyYXRpb247XG4gICAgICAgICAgICBjb25zdCBpc1NpZ25hdHVyZSA9IG1ldGhvZCBpbnN0YW5jZW9mIE1ldGhvZFNpZ25hdHVyZTtcblxuICAgICAgICAgICAgbGV0IGlzQWJzdHJhY3QgPSBmYWxzZTtcbiAgICAgICAgICAgIGxldCBpc1N0YXRpYyA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKG1ldGhvZCBpbnN0YW5jZW9mIE1ldGhvZERlY2xhcmF0aW9uIHx8IG1ldGhvZCBpbnN0YW5jZW9mIEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgICAgIGlzQWJzdHJhY3QgPSBtZXRob2QuaXNBYnN0cmFjdCgpO1xuICAgICAgICAgICAgICAgIGlzU3RhdGljID0gbWV0aG9kLmlzU3RhdGljKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChpc0NvbnN0cnVjdG9yKSB7KGZteE1ldGhvZCBhcyBGYW1peC5BY2Nlc3Nvcikua2luZCA9IFwiY29uc3RydWN0b3JcIjt9XG4gICAgICAgICAgICBmbXhNZXRob2QuaXNBYnN0cmFjdCA9IGlzQWJzdHJhY3Q7XG4gICAgICAgICAgICBmbXhNZXRob2QuaXNDbGFzc1NpZGUgPSBpc1N0YXRpYztcbiAgICAgICAgICAgIGZteE1ldGhvZC5pc1ByaXZhdGUgPSAobWV0aG9kIGluc3RhbmNlb2YgTWV0aG9kRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8fCBtZXRob2QgaW5zdGFuY2VvZiBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKSA/IChtZXRob2QuZ2V0TW9kaWZpZXJzKCkuZmluZCh4ID0+IHguZ2V0VGV4dCgpID09PSAncHJpdmF0ZScpKSAhPT0gdW5kZWZpbmVkIDogZmFsc2U7XG4gICAgICAgICAgICBmbXhNZXRob2QuaXNQcm90ZWN0ZWQgPSAobWV0aG9kIGluc3RhbmNlb2YgTWV0aG9kRGVjbGFyYXRpb24gfHwgbWV0aG9kIGluc3RhbmNlb2YgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8fCBtZXRob2QgaW5zdGFuY2VvZiBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKSA/IChtZXRob2QuZ2V0TW9kaWZpZXJzKCkuZmluZCh4ID0+IHguZ2V0VGV4dCgpID09PSAncHJvdGVjdGVkJykpICE9PSB1bmRlZmluZWQgOiBmYWxzZTtcbiAgICAgICAgICAgIGZteE1ldGhvZC5zaWduYXR1cmUgPSBIZWxwZXJzLmNvbXB1dGVTaWduYXR1cmUobWV0aG9kLmdldFRleHQoKSk7XG5cbiAgICAgICAgICAgIGxldCBtZXRob2ROYW1lOiBzdHJpbmc7XG4gICAgICAgICAgICBpZiAoaXNDb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgIG1ldGhvZE5hbWUgPSBcImNvbnN0cnVjdG9yXCI7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBtZXRob2ROYW1lID0gKG1ldGhvZCBhcyBNZXRob2REZWNsYXJhdGlvbiB8IE1ldGhvZFNpZ25hdHVyZSB8IEdldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBTZXRBY2Nlc3NvckRlY2xhcmF0aW9uKS5nZXROYW1lKCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmbXhNZXRob2QubmFtZSA9IG1ldGhvZE5hbWU7XG5cbiAgICAgICAgICAgIGlmICghaXNDb25zdHJ1Y3Rvcikge1xuICAgICAgICAgICAgICAgIGlmIChtZXRob2QuZ2V0TmFtZSgpLnN1YnN0cmluZygwLCAxKSA9PT0gXCIjXCIpIHtcbiAgICAgICAgICAgICAgICAgICAgZm14TWV0aG9kLmlzUHJpdmF0ZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBpZiAoIWZteE1ldGhvZC5pc1ByaXZhdGUgJiYgIWZteE1ldGhvZC5pc1Byb3RlY3RlZCkge1xuICAgICAgICAgICAgICAgIGZteE1ldGhvZC5pc1B1YmxpYyA9IHRydWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhNZXRob2QuaXNQdWJsaWMgPSBmYWxzZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgaWYgKCFpc1NpZ25hdHVyZSkge1xuICAgICAgICAgICAgICAgIGZteE1ldGhvZC5jeWNsb21hdGljQ29tcGxleGl0eSA9IGN1cnJlbnRDQ1tmbXhNZXRob2QubmFtZV07XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhNZXRob2QuY3ljbG9tYXRpY0NvbXBsZXhpdHkgPSAwO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBsZXQgbWV0aG9kVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7IFxuICAgICAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgICAgICBtZXRob2RUeXBlTmFtZSA9IG1ldGhvZC5nZXRSZXR1cm5UeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTsgICAgICAgICAgICBcbiAgICAgICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGA+IFdBUk5JTkc6IGdvdCBleGNlcHRpb24gJHtlcnJvcn0uIEZhaWxlZCB0byBnZXQgdXNhYmxlIG5hbWUgZm9yIHJldHVybiB0eXBlIG9mIG1ldGhvZDogJHtmbXhNZXRob2QubmFtZX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgY29uc3QgZm14VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUobWV0aG9kVHlwZU5hbWUsIG1ldGhvZCk7XG4gICAgICAgICAgICBmbXhNZXRob2QuZGVjbGFyZWRUeXBlID0gZm14VHlwZTtcbiAgICAgICAgICAgIGZteE1ldGhvZC5udW1iZXJPZkxpbmVzT2ZDb2RlID0gbWV0aG9kLmdldEVuZExpbmVOdW1iZXIoKSAtIG1ldGhvZC5nZXRTdGFydExpbmVOdW1iZXIoKTtcbiAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBtZXRob2QuZ2V0UGFyYW1ldGVycygpO1xuICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mUGFyYW1ldGVycyA9IHBhcmFtZXRlcnMubGVuZ3RoO1xuXG4gICAgICAgICAgICBpZiAoIWlzU2lnbmF0dXJlKSB7XG4gICAgICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mU3RhdGVtZW50cyA9IG1ldGhvZC5nZXRTdGF0ZW1lbnRzKCkubGVuZ3RoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm14TWV0aG9kLm51bWJlck9mU3RhdGVtZW50cyA9IDA7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBcbiAgICAgICAgICAgIGluaXRGUU4obWV0aG9kLCBmbXhNZXRob2QpO1xuICAgICAgICAgICAgdGhpcy5tYWtlRmFtaXhJbmRleEZpbGVBbmNob3IobWV0aG9kLCBmbXhNZXRob2QpO1xuXG4gICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSwgZm14TWV0aG9kKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZteE1ldGhvZCA9IHRoaXMuZm14RnVuY3Rpb25BbmRNZXRob2RNYXAuZ2V0KGZ1bmN0aW9uRnVsbHlRdWFsaWZpZWROYW1lKSBhcyAoRmFtaXguTWV0aG9kIHwgRmFtaXguQWNjZXNzb3IgfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14TWV0aG9kLG1ldGhvZCk7XG4gICAgICAgIFxuICAgICAgICByZXR1cm4gZm14TWV0aG9kO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBmdW5jdGlvblxuICAgICAqIEBwYXJhbSBmdW5jIEEgZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gY3VycmVudENDIFRoZSBjeWNsb21hdGljIGNvbXBsZXhpdHkgbWV0cmljcyBvZiB0aGUgY3VycmVudCBzb3VyY2UgZmlsZVxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlT3JHZXRGYW1peEZ1bmN0aW9uKGZ1bmM6IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24sIGN1cnJlbnRDQzogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSk6IEZhbWl4LkZ1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uIHtcbiAgICAgICAgbGV0IGZteEZ1bmN0aW9uOiBGYW1peC5GdW5jdGlvbiB8IEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbjtcbiAgICAgICAgY29uc3QgaXNHZW5lcmljID0gZnVuYy5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDA7ICAgICAgICBcbiAgICAgICAgY29uc3QgZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGZ1bmMpO1xuICAgICAgICBpZiAoIXRoaXMuZm14RnVuY3Rpb25BbmRNZXRob2RNYXAuaGFzKGZ1bmN0aW9uRnVsbHlRdWFsaWZpZWROYW1lKSkge1xuICAgICAgICAgICAgaWYgKGlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgIGZteEZ1bmN0aW9uID0gbmV3IEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbigpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm14RnVuY3Rpb24gPSBuZXcgRmFtaXguRnVuY3Rpb24oKTtcbiAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgIGNvbnN0IG5hbWUgPSBmdW5jLmdldE5hbWUoKTtcbiAgICAgICAgICAgIGlmIChuYW1lKSB7XG4gICAgICAgICAgICAgICAgZm14RnVuY3Rpb24ubmFtZSA9IG5hbWU7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgICAgICBmbXhGdW5jdGlvbi5uYW1lID0gXCJhbm9ueW1vdXNcIjtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgZm14RnVuY3Rpb24uc2lnbmF0dXJlID0gSGVscGVycy5jb21wdXRlU2lnbmF0dXJlKGZ1bmMuZ2V0VGV4dCgpKTtcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLmN5Y2xvbWF0aWNDb21wbGV4aXR5ID0gY3VycmVudENDW2ZteEZ1bmN0aW9uLm5hbWVdO1xuICAgICAgICAgICAgZm14RnVuY3Rpb24uZnVsbHlRdWFsaWZpZWROYW1lID0gZnVuY3Rpb25GdWxseVF1YWxpZmllZE5hbWU7XG4gICAgXG4gICAgICAgICAgICBsZXQgZnVuY3Rpb25UeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgICAgIHRyeSB7XG4gICAgICAgICAgICAgICAgZnVuY3Rpb25UeXBlTmFtZSA9IGZ1bmMuZ2V0UmV0dXJuVHlwZSgpLmdldFRleHQoKS50cmltKCk7XG4gICAgICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciByZXR1cm4gdHlwZSBvZiBmdW5jdGlvbjogJHtmdW5jLmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgICAgIH1cbiAgICBcbiAgICAgICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGZ1bmN0aW9uVHlwZU5hbWUsIGZ1bmMpO1xuICAgICAgICAgICAgZm14RnVuY3Rpb24uZGVjbGFyZWRUeXBlID0gZm14VHlwZTtcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLm51bWJlck9mTGluZXNPZkNvZGUgPSBmdW5jLmdldEVuZExpbmVOdW1iZXIoKSAtIGZ1bmMuZ2V0U3RhcnRMaW5lTnVtYmVyKCk7XG4gICAgICAgICAgICBjb25zdCBwYXJhbWV0ZXJzID0gZnVuYy5nZXRQYXJhbWV0ZXJzKCk7XG4gICAgICAgICAgICBmbXhGdW5jdGlvbi5udW1iZXJPZlBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzLmxlbmd0aDtcbiAgICAgICAgICAgIGZteEZ1bmN0aW9uLm51bWJlck9mU3RhdGVtZW50cyA9IGZ1bmMuZ2V0U3RhdGVtZW50cygpLmxlbmd0aDtcbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGZ1bmMsIGZteEZ1bmN0aW9uKTtcbiAgICBcbiAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhGdW5jdGlvbik7XG4gICAgXG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEZ1bmN0aW9uLGZ1bmMpO1xuXG4gICAgICAgICAgICB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLnNldChmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSwgZm14RnVuY3Rpb24pO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14RnVuY3Rpb24gPSB0aGlzLmZteEZ1bmN0aW9uQW5kTWV0aG9kTWFwLmdldChmdW5jdGlvbkZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgKEZhbWl4LkZ1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBmbXhGdW5jdGlvbjtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggcGFyYW1ldGVyXG4gICAgICogQHBhcmFtIHBhcmFtIEEgcGFyYW1ldGVyXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBwYXJhbWV0ZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhQYXJhbWV0ZXIocGFyYW06IFBhcmFtZXRlckRlY2xhcmF0aW9uKTogRmFtaXguUGFyYW1ldGVyIHtcbiAgICAgICAgY29uc3QgZm14UGFyYW0gPSBuZXcgRmFtaXguUGFyYW1ldGVyKCk7XG5cbiAgICAgICAgbGV0IHBhcmFtVHlwZU5hbWUgPSB0aGlzLlVOS05PV05fVkFMVUU7XG4gICAgICAgIHRyeSB7XG4gICAgICAgICAgICBwYXJhbVR5cGVOYW1lID0gcGFyYW0uZ2V0VHlwZSgpLmdldFRleHQoKS50cmltKCk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYD4gV0FSTklORzogZ290IGV4Y2VwdGlvbiAke2Vycm9yfS4gRmFpbGVkIHRvIGdldCB1c2FibGUgbmFtZSBmb3IgcGFyYW1ldGVyOiAke3BhcmFtLmdldE5hbWUoKX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKHBhcmFtVHlwZU5hbWUsIHBhcmFtKTtcbiAgICAgICAgZm14UGFyYW0uZGVjbGFyZWRUeXBlID0gZm14VHlwZTtcbiAgICAgICAgZm14UGFyYW0ubmFtZSA9IHBhcmFtLmdldE5hbWUoKTtcblxuICAgICAgICBpbml0RlFOKHBhcmFtLCBmbXhQYXJhbSk7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKHBhcmFtLCBmbXhQYXJhbSk7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFBhcmFtKTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteFBhcmFtLHBhcmFtKTtcblxuICAgICAgICByZXR1cm4gZm14UGFyYW07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IHR5cGUgcGFyYW1ldGVyXG4gICAgICogQHBhcmFtIHRwIEEgdHlwZSBwYXJhbWV0ZXJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHR5cGUgcGFyYW1ldGVyXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4UGFyYW1ldGVyVHlwZSh0cDogVHlwZVBhcmFtZXRlckRlY2xhcmF0aW9uKTogRmFtaXguUGFyYW1ldGVyVHlwZSB7XG4gICAgICAgIFxuICAgICAgICBjb25zdCBmbXhQYXJhbWV0ZXJUeXBlID0gbmV3IEZhbWl4LlBhcmFtZXRlclR5cGUoKTtcbiAgIFxuICAgICAgICBmbXhQYXJhbWV0ZXJUeXBlLm5hbWUgPSB0cC5nZXROYW1lKCk7ICAgICAgXG4gICAgICAgIGluaXRGUU4odHAsIGZteFBhcmFtZXRlclR5cGUpO1xuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcih0cCwgZm14UGFyYW1ldGVyVHlwZSk7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFBhcmFtZXRlclR5cGUpO1xuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14UGFyYW1ldGVyVHlwZSx0cCk7XG5cbiAgICAgICAgcmV0dXJuIGZteFBhcmFtZXRlclR5cGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IHR5cGUgcGFyYW1ldGVyXG4gICAgICogQHBhcmFtIHRwIEEgdHlwZSBwYXJhbWV0ZXJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHR5cGUgcGFyYW1ldGVyXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhDb25jcmV0ZVR5cGUocGFyYW06IFR5cGVOb2RlKTogRmFtaXguUGFyYW1ldGVyVHlwZSB8IEZhbWl4LlByaW1pdGl2ZVR5cGUgfCBGYW1peC5DbGFzcyB8IEZhbWl4LkludGVyZmFjZSB7XG4gICAgICAgIGNvbnN0IHR5cGVQYXJhbWV0ZXJEZWNsYXJhdGlvbiA9IHBhcmFtLmdldFN5bWJvbCgpPy5nZXREZWNsYXJhdGlvbnMoKVswXSBhcyBUeXBlUGFyYW1ldGVyRGVjbGFyYXRpb247XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlclR5cGVOYW1lIDogc3RyaW5nID0gcGFyYW0uZ2V0VGV4dCgpO1xuICAgICAgICBsZXQgZm14UGFyYW1ldGVyVHlwZTogRmFtaXguVHlwZSB8IEZhbWl4LkNsYXNzIHwgRmFtaXguSW50ZXJmYWNlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuXG4gICAgICAgIGxldCBpc0NsYXNzT3JJbnRlcmZhY2UgPSBmYWxzZTtcbiAgICAgICAgaWYgKHRoaXMuZm14Q2xhc3NNYXAuaGFzKHBhcmFtZXRlclR5cGVOYW1lKSl7XG4gICAgICAgICAgICB0aGlzLmZteENsYXNzTWFwLmZvckVhY2goKG9iaiwgbmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmKG9iaiBpbnN0YW5jZW9mIEZhbWl4LlBhcmFtZXRyaWNDbGFzcyl7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBwYXJhbS5nZXRUZXh0KCkgJiYgb2JqLmdlbmVyaWNQYXJhbWV0ZXJzLnNpemU+MCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZSA9IG9iajtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2xhc3NPckludGVyZmFjZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKG5hbWUgPT09IHBhcmFtLmdldFRleHQoKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZSA9IG9iajtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlzQ2xhc3NPckludGVyZmFjZSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIH0gXG4gICAgICAgICAgICAgICAgfSAgIFxuICAgICAgICAgICAgfSlcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmZteEludGVyZmFjZU1hcC5oYXMocGFyYW1ldGVyVHlwZU5hbWUpKXtcbiAgICAgICAgICAgIHRoaXMuZm14SW50ZXJmYWNlTWFwLmZvckVhY2goKG9iaiwgbmFtZSkgPT4ge1xuICAgICAgICAgICAgICAgIGlmKG9iaiBpbnN0YW5jZW9mIEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2Upe1xuICAgICAgICAgICAgICAgICAgICBpZiAobmFtZSA9PT0gcGFyYW0uZ2V0VGV4dCgpICYmIG9iai5nZW5lcmljUGFyYW1ldGVycy5zaXplPjApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NsYXNzT3JJbnRlcmZhY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IFxuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChuYW1lID09PSBwYXJhbS5nZXRUZXh0KCkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBvYmo7XG4gICAgICAgICAgICAgICAgICAgICAgICBpc0NsYXNzT3JJbnRlcmZhY2UgPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICB9IFxuICAgICAgICAgICAgICAgIH0gICBcbiAgICAgICAgICAgIH0pXG4gICAgICAgIH1cblxuICAgICAgICBpZighaXNDbGFzc09ySW50ZXJmYWNlKXtcbiAgICAgICAgICAgIGlmICghdGhpcy5mbXhUeXBlTWFwLmhhcyhwYXJhbWV0ZXJUeXBlTmFtZSkpIHsgICAgICAgICAgIFxuICAgICAgICAgICAgICAgIGlmIChwYXJhbWV0ZXJUeXBlTmFtZSA9PT0gXCJudW1iZXJcIiB8fCBwYXJhbWV0ZXJUeXBlTmFtZSA9PT0gXCJzdHJpbmdcIiB8fCBwYXJhbWV0ZXJUeXBlTmFtZSA9PT0gXCJib29sZWFuXCIgfHwgcGFyYW1ldGVyVHlwZU5hbWUgPT09IFwiYmlnaW50XCIgfHwgcGFyYW1ldGVyVHlwZU5hbWUgPT09IFwic3ltYm9sXCIgfHwgcGFyYW1ldGVyVHlwZU5hbWUgPT09IFwidW5kZWZpbmVkXCIgfHwgcGFyYW1ldGVyVHlwZU5hbWUgPT09IFwibnVsbFwiIHx8IHBhcmFtZXRlclR5cGVOYW1lID09PSBcImFueVwiIHx8IHBhcmFtZXRlclR5cGVOYW1lID09PSBcInVua25vd25cIiB8fCBwYXJhbWV0ZXJUeXBlTmFtZSA9PT0gXCJuZXZlclwiIHx8IHBhcmFtZXRlclR5cGVOYW1lID09PSBcInZvaWRcIikge1xuICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJUeXBlID0gbmV3IEZhbWl4LlByaW1pdGl2ZVR5cGUoKTtcbiAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZS5pc1N0dWIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlclR5cGUgPSBuZXcgRmFtaXguUGFyYW1ldGVyVHlwZSgpO1xuICAgICAgICAgICAgICAgIH0gXG4gICAgXG4gICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyVHlwZS5uYW1lID0gcGFyYW1ldGVyVHlwZU5hbWU7XG4gICAgICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFBhcmFtZXRlclR5cGUpO1xuICAgICAgICAgICAgICAgIHRoaXMuZm14VHlwZU1hcC5zZXQocGFyYW1ldGVyVHlwZU5hbWUsIGZteFBhcmFtZXRlclR5cGUpO1xuICAgICAgICAgICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14UGFyYW1ldGVyVHlwZSx0eXBlUGFyYW1ldGVyRGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5mbXhUeXBlTWFwLmdldChwYXJhbWV0ZXJUeXBlTmFtZSk7XG4gICAgICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJUeXBlID0gcmVzdWx0O1xuICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggdHlwZSAke3BhcmFtZXRlclR5cGVOYW1lfSBpcyBub3QgZm91bmQgaW4gdGhlIFR5cGUgbWFwLmApO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAoIWZteFBhcmFtZXRlclR5cGUpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgZm14UGFyYW1ldGVyVHlwZSB3YXMgdW5kZWZpbmVkIGZvciBwYXJhbWV0ZXJUeXBlTmFtZSAke3BhcmFtZXRlclR5cGVOYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmbXhQYXJhbWV0ZXJUeXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCB2YXJpYWJsZVxuICAgICAqIEBwYXJhbSB2YXJpYWJsZSBBIHZhcmlhYmxlXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSB2YXJpYWJsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peFZhcmlhYmxlKHZhcmlhYmxlOiBWYXJpYWJsZURlY2xhcmF0aW9uKTogRmFtaXguVmFyaWFibGUge1xuICAgICAgICBjb25zdCBmbXhWYXJpYWJsZSA9IG5ldyBGYW1peC5WYXJpYWJsZSgpO1xuICAgIFxuICAgICAgICBsZXQgdmFyaWFibGVUeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIHZhcmlhYmxlVHlwZU5hbWUgPSB2YXJpYWJsZS5nZXRUeXBlKCkuZ2V0VGV4dCgpLnRyaW0oKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICAgIGxvZ2dlci5lcnJvcihgPiBXQVJOSU5HOiBnb3QgZXhjZXB0aW9uICR7ZXJyb3J9LiBGYWlsZWQgdG8gZ2V0IHVzYWJsZSBuYW1lIGZvciB2YXJpYWJsZTogJHt2YXJpYWJsZS5nZXROYW1lKCl9LiBDb250aW51aW5nLi4uYCk7XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgY29uc3QgZm14VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUodmFyaWFibGVUeXBlTmFtZSwgdmFyaWFibGUpO1xuICAgICAgICBmbXhWYXJpYWJsZS5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xuICAgICAgICBmbXhWYXJpYWJsZS5uYW1lID0gdmFyaWFibGUuZ2V0TmFtZSgpO1xuICAgICAgICBpbml0RlFOKHZhcmlhYmxlLCBmbXhWYXJpYWJsZSk7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKHZhcmlhYmxlLCBmbXhWYXJpYWJsZSk7XG4gICAgXG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhWYXJpYWJsZSk7XG4gICAgXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14VmFyaWFibGUsdmFyaWFibGUpO1xuICAgIFxuICAgICAgICByZXR1cm4gZm14VmFyaWFibGU7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGVudW1cbiAgICAgKiBAcGFyYW0gZW51bUVudGl0eSBBbiBlbnVtXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBlbnVtXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4RW51bShlbnVtRW50aXR5OiBFbnVtRGVjbGFyYXRpb24pOiBGYW1peC5FbnVtIHtcbiAgICAgICAgY29uc3QgZm14RW51bSA9IG5ldyBGYW1peC5FbnVtKCk7XG4gICAgICAgIGZteEVudW0ubmFtZSA9IGVudW1FbnRpdHkuZ2V0TmFtZSgpO1xuICAgICAgICBpbml0RlFOKGVudW1FbnRpdHksIGZteEVudW0pO1xuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihlbnVtRW50aXR5LCBmbXhFbnVtKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14RW51bSk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhFbnVtLGVudW1FbnRpdHkpO1xuXG4gICAgICAgIHJldHVybiBmbXhFbnVtO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBlbnVtIHZhbHVlXG4gICAgICogQHBhcmFtIGVudW1NZW1iZXIgQW4gZW51bSBtZW1iZXJcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIGVudW0gbWVtYmVyXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4RW51bVZhbHVlKGVudW1NZW1iZXI6IEVudW1NZW1iZXIpOiBGYW1peC5FbnVtVmFsdWUge1xuICAgICAgICBjb25zdCBmbXhFbnVtVmFsdWUgPSBuZXcgRmFtaXguRW51bVZhbHVlKCk7XG5cbiAgICAgICAgbGV0IGVudW1WYWx1ZVR5cGVOYW1lID0gdGhpcy5VTktOT1dOX1ZBTFVFO1xuICAgICAgICB0cnkge1xuICAgICAgICAgICAgZW51bVZhbHVlVHlwZU5hbWUgPSBlbnVtTWVtYmVyLmdldFR5cGUoKS5nZXRUZXh0KCkudHJpbSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGA+IFdBUk5JTkc6IGdvdCBleGNlcHRpb24gJHtlcnJvcn0uIEZhaWxlZCB0byBnZXQgdXNhYmxlIG5hbWUgZm9yIGVudW0gdmFsdWU6ICR7ZW51bU1lbWJlci5nZXROYW1lKCl9LiBDb250aW51aW5nLi4uYCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmbXhUeXBlID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZShlbnVtVmFsdWVUeXBlTmFtZSwgZW51bU1lbWJlcik7XG4gICAgICAgIGZteEVudW1WYWx1ZS5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xuICAgICAgICBmbXhFbnVtVmFsdWUubmFtZSA9IGVudW1NZW1iZXIuZ2V0TmFtZSgpO1xuICAgICAgICBpbml0RlFOKGVudW1NZW1iZXIsIGZteEVudW1WYWx1ZSk7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGVudW1NZW1iZXIsIGZteEVudW1WYWx1ZSk7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEVudW1WYWx1ZSk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhFbnVtVmFsdWUsZW51bU1lbWJlcik7XG5cbiAgICAgICAgcmV0dXJuIGZteEVudW1WYWx1ZTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIG9yIGdldHMgYSBGYW1peCBkZWNvcmF0b3JcbiAgICAgKiBAcGFyYW0gZGVjb3JhdG9yIEEgZGVjb3JhdG9yXG4gICAgICogQHBhcmFtIGRlY29yYXRlZEVudGl0eSBBIGNsYXNzLCBhIG1ldGhvZCwgYSBwYXJhbWV0ZXIgb3IgYSBwcm9wZXJ0eVxuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgZGVjb3JhdG9yXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZU9yR2V0RmFtaXhEZWNvcmF0b3IoZGVjb3JhdG9yOiBEZWNvcmF0b3IsIGRlY29yYXRlZEVudGl0eTogQ2xhc3NEZWNsYXJhdGlvbiB8IE1ldGhvZERlY2xhcmF0aW9uIHwgR2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IFNldEFjY2Vzc29yRGVjbGFyYXRpb24gfCBQYXJhbWV0ZXJEZWNsYXJhdGlvbiB8IFByb3BlcnR5RGVjbGFyYXRpb24pOiBGYW1peC5EZWNvcmF0b3Ige1xuICAgICAgICBjb25zdCBmbXhEZWNvcmF0b3IgPSBuZXcgRmFtaXguRGVjb3JhdG9yKCk7XG4gICAgICAgIGNvbnN0IGRlY29yYXRvck5hbWUgPSBcIkBcIiArIGRlY29yYXRvci5nZXROYW1lKCk7XG4gICAgICAgIGNvbnN0IGRlY29yYXRvckV4cHJlc3Npb24gPSBkZWNvcmF0b3IuZ2V0VGV4dCgpLnN1YnN0cmluZygxKTtcblxuICAgICAgICBmbXhEZWNvcmF0b3IubmFtZSA9IGRlY29yYXRvck5hbWU7XG4gICAgICAgIGZteERlY29yYXRvci5kZWNvcmF0b3JFeHByZXNzaW9uID0gZGVjb3JhdG9yRXhwcmVzc2lvbjtcbiAgICAgICAgY29uc3QgZGVjb3JhdGVkRW50aXR5RnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihkZWNvcmF0ZWRFbnRpdHkpO1xuICAgICAgICBjb25zdCBmbXhEZWNvcmF0ZWRFbnRpdHkgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUoZGVjb3JhdGVkRW50aXR5RnVsbHlRdWFsaWZpZWROYW1lKSBhcyBGYW1peC5OYW1lZEVudGl0eTtcbiAgICAgICAgZm14RGVjb3JhdG9yLmRlY29yYXRlZEVudGl0eSA9IGZteERlY29yYXRlZEVudGl0eTtcbiAgICAgICAgaW5pdEZRTihkZWNvcmF0b3IsIGZteERlY29yYXRvcik7XG4gICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGRlY29yYXRvciwgZm14RGVjb3JhdG9yKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14RGVjb3JhdG9yKTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteERlY29yYXRvcixkZWNvcmF0b3IpO1xuXG4gICAgICAgIHJldHVybiBmbXhEZWNvcmF0b3I7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbW1lbnRcbiAgICAgKiBAcGFyYW0gY29tbWVudCBBIGNvbW1lbnRcbiAgICAgKiBAcGFyYW0gZm14U2NvcGUgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBjb21tZW50J3MgY29udGFpbmVyXG4gICAgICogQHBhcmFtIGlzSlNEb2MgQSBib29sZWFuIGluZGljYXRpbmcgaWYgdGhlIGNvbW1lbnQgaXMgYSBKU0RvY1xuICAgICAqIEByZXR1cm5zIFRoZSBGYW1peCBtb2RlbCBvZiB0aGUgY29tbWVudFxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peENvbW1lbnQoY29tbWVudDogQ29tbWVudFJhbmdlLCBmbXhTY29wZTogRmFtaXguTmFtZWRFbnRpdHksIGlzSlNEb2M6IGJvb2xlYW4pOiBGYW1peC5Db21tZW50IHtcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGA+IE5PVEU6IGNyZWF0aW5nIGNvbW1lbnQgJHtjb21tZW50LmdldFRleHQoKX0gaW4gc2NvcGUgJHtmbXhTY29wZS5uYW1lfS5gKTtcbiAgICAgICAgY29uc3QgZm14Q29tbWVudCA9IG5ldyBGYW1peC5Db21tZW50KCk7XG4gICAgICAgIGZteENvbW1lbnQuY29udGFpbmVyID0gZm14U2NvcGU7ICAvLyBhZGRzIGNvbW1lbnQgdG8gdGhlIGNvbnRhaW5lcidzIGNvbW1lbnRzIGNvbGxlY3Rpb25cbiAgICAgICAgZm14Q29tbWVudC5pc0pTRG9jID0gaXNKU0RvYztcblxuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihjb21tZW50LCBmbXhDb21tZW50KTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14Q29tbWVudCk7XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhDb21tZW50LGNvbW1lbnQpO1xuXG4gICAgICAgIHJldHVybiBmbXhDb21tZW50O1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgb3IgZ2V0cyBhIEZhbWl4IHR5cGVcbiAgICAgKiBAcGFyYW0gdHlwZU5hbWUgQSB0eXBlIG5hbWVcbiAgICAgKiBAcGFyYW0gZWxlbWVudCBBIHRzLW1vcnBoIGVsZW1lbnRcbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIHR5cGVcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlT3JHZXRGYW1peFR5cGUodHlwZU5hbWU6IHN0cmluZywgZWxlbWVudDogVHlwZURlY2xhcmF0aW9uKTogRmFtaXguVHlwZSB8IEZhbWl4LlByaW1pdGl2ZVR5cGUgfCBGYW1peC5QYXJhbWV0ZXJUeXBlIHtcbiAgICAgICAgbGV0IGZteFR5cGU6IEZhbWl4LlR5cGUgfCBGYW1peC5QcmltaXRpdmVUeXBlIHwgRmFtaXguUGFyYW1ldGVyVHlwZTtcbiAgICAgICAgbGV0IGlzUHJpbWl0aXZlVHlwZSA9IGZhbHNlO1xuICAgICAgICBsZXQgaXNQYXJhbWV0ZXJUeXBlID0gZmFsc2U7XG5cbiAgICAgICAgbG9nZ2VyLmRlYnVnKFwiQ3JlYXRpbmcgKG9yIGdldHRpbmcpIHR5cGU6ICdcIiArIHR5cGVOYW1lICsgXCInIG9mIGVsZW1lbnQ6IFwiICsgZWxlbWVudD8uZ2V0VGV4dCgpICsgXCIgb2Yga2luZDogXCIgKyBlbGVtZW50Py5nZXRLaW5kTmFtZSgpKTtcbiAgICAgICAgbGV0IGFuY2VzdG9yOiBGYW1peC5Db250YWluZXJFbnRpdHkgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChlbGVtZW50ICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGNvbnN0IHR5cGVBbmNlc3RvciA9IEhlbHBlcnMuZmluZFR5cGVBbmNlc3RvcihlbGVtZW50KTtcbiAgICAgICAgICAgIGlmICghdHlwZUFuY2VzdG9yKSB7XG4gICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBBbmNlc3RvciBub3QgZm91bmQgZm9yIGVsZW1lbnQgJHtlbGVtZW50LmdldFRleHQoKX0uYCk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBjb25zdCBhbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4odHlwZUFuY2VzdG9yKTtcbiAgICAgICAgICAgIGFuY2VzdG9yID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lKGFuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lKSBhcyBGYW1peC5Db250YWluZXJFbnRpdHk7XG4gICAgICAgICAgICBpZiAoIWFuY2VzdG9yKSB7XG4gICAgICAgICAgICAgICAgbG9nZ2VyLmRlYnVnKGBBbmNlc3RvciAke0ZRTkZ1bmN0aW9ucy5nZXRGUU4odHlwZUFuY2VzdG9yKX0gbm90IGZvdW5kLiBBZGRpbmcgdGhlIG5ldyB0eXBlLmApO1xuICAgICAgICAgICAgICAgIGFuY2VzdG9yID0gdGhpcy5jcmVhdGVPckdldEZhbWl4VHlwZSh0eXBlQW5jZXN0b3IuZ2V0VGV4dCgpLCB0eXBlQW5jZXN0b3IgYXMgVHlwZURlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlTmFtZSA9PT0gXCJudW1iZXJcIiB8fCB0eXBlTmFtZSA9PT0gXCJzdHJpbmdcIiB8fCB0eXBlTmFtZSA9PT0gXCJib29sZWFuXCIgfHwgdHlwZU5hbWUgPT09IFwiYmlnaW50XCIgfHwgdHlwZU5hbWUgPT09IFwic3ltYm9sXCIgfHwgdHlwZU5hbWUgPT09IFwidW5kZWZpbmVkXCIgfHwgdHlwZU5hbWUgPT09IFwibnVsbFwiIHx8IHR5cGVOYW1lID09PSBcImFueVwiIHx8IHR5cGVOYW1lID09PSBcInVua25vd25cIiB8fCB0eXBlTmFtZSA9PT0gXCJuZXZlclwiIHx8IHR5cGVOYW1lID09PSBcInZvaWRcIikge1xuICAgICAgICAgICAgaXNQcmltaXRpdmVUeXBlID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmKCFpc1ByaW1pdGl2ZVR5cGUgJiYgdHlwZU5hbWUuaW5jbHVkZXMoXCI8XCIpICYmIHR5cGVOYW1lLmluY2x1ZGVzKFwiPlwiKSAmJiAhKHR5cGVOYW1lLmluY2x1ZGVzKFwiPT5cIikpKSB7XG4gICAgICAgICAgICBpc1BhcmFtZXRlclR5cGUgPSB0cnVlO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCF0aGlzLmZteFR5cGVNYXAuaGFzKHR5cGVOYW1lKSkge1xuICAgICAgICAgICAgaWYgKGlzUHJpbWl0aXZlVHlwZSkge1xuICAgICAgICAgICAgICAgIGZteFR5cGUgPSBuZXcgRmFtaXguUHJpbWl0aXZlVHlwZSgpO1xuICAgICAgICAgICAgICAgIGZteFR5cGUuaXNTdHViID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIGVsc2UgaWYgKGlzUGFyYW1ldGVyVHlwZSkge1xuICAgICAgICAgICAgICAgIGZteFR5cGUgPSBuZXcgRmFtaXguUGFyYW1ldGVyVHlwZSgpO1xuICAgICAgICAgICAgICAgIGNvbnN0IHBhcmFtZXRlclR5cGVOYW1lcyA9IHR5cGVOYW1lLnN1YnN0cmluZyh0eXBlTmFtZS5pbmRleE9mKFwiPFwiKSArIDEsIHR5cGVOYW1lLmluZGV4T2YoXCI+XCIpKS5zcGxpdChcIixcIikubWFwKHMgPT4gcy50cmltKCkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGJhc2VUeXBlTmFtZSA9IHR5cGVOYW1lLnN1YnN0cmluZygwLCB0eXBlTmFtZS5pbmRleE9mKFwiPFwiKSkudHJpbSgpO1xuICAgICAgICAgICAgICAgIHBhcmFtZXRlclR5cGVOYW1lcy5mb3JFYWNoKHBhcmFtZXRlclR5cGVOYW1lID0+IHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14UGFyYW1ldGVyVHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUocGFyYW1ldGVyVHlwZU5hbWUsIGVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICAoZm14VHlwZSBhcyBGYW1peC5QYXJhbWV0ZXJUeXBlKS5hZGRBcmd1bWVudChmbXhQYXJhbWV0ZXJUeXBlKTtcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICBjb25zdCBmbXhCYXNlVHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoYmFzZVR5cGVOYW1lLCBlbGVtZW50KTtcbiAgICAgICAgICAgICAgICAoZm14VHlwZSBhcyBGYW1peC5QYXJhbWV0ZXJUeXBlKS5iYXNlVHlwZSA9IGZteEJhc2VUeXBlO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgZm14VHlwZSA9IG5ldyBGYW1peC5UeXBlKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGZteFR5cGUubmFtZSA9IHR5cGVOYW1lO1xuICAgICAgICAgICAgaWYgKCFhbmNlc3Rvcikge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQW5jZXN0b3Igbm90IGZvdW5kIGZvciB0eXBlICR7dHlwZU5hbWV9LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZm14VHlwZS5jb250YWluZXIgPSBhbmNlc3RvcjtcbiAgICAgICAgICAgIGluaXRGUU4oZWxlbWVudCwgZm14VHlwZSk7XG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihlbGVtZW50LCBmbXhUeXBlKTtcblxuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteFR5cGUpO1xuXG4gICAgICAgICAgICB0aGlzLmZteFR5cGVNYXAuc2V0KHR5cGVOYW1lLCBmbXhUeXBlKTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMuZm14VHlwZU1hcC5nZXQodHlwZU5hbWUpO1xuICAgICAgICAgICAgaWYgKHJlc3VsdCkge1xuICAgICAgICAgICAgICAgIGZteFR5cGUgPSByZXN1bHQ7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggdHlwZSAke3R5cGVOYW1lfSBpcyBub3QgZm91bmQgaW4gdGhlIFR5cGUgbWFwLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhUeXBlLGVsZW1lbnQpO1xuXG4gICAgICAgIHJldHVybiBmbXhUeXBlO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBhY2Nlc3NcbiAgICAgKiBAcGFyYW0gbm9kZSBBIG5vZGVcbiAgICAgKiBAcGFyYW0gaWQgQW4gaWQgb2YgYSBwYXJhbWV0ZXIsIGEgdmFyaWFibGUsIGEgcHJvcGVydHkgb3IgYW4gZW51bSBtZW1iZXJcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhBY2Nlc3Mobm9kZTogSWRlbnRpZmllciwgaWQ6IG51bWJlcik6IHZvaWQge1xuICAgICAgICBjb25zdCBmbXhWYXIgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlJZChpZCkgYXMgRmFtaXguU3RydWN0dXJhbEVudGl0eTtcbiAgICAgICAgaWYgKCFmbXhWYXIpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgRmFtaXggZW50aXR5IHdpdGggaWQgJHtpZH0gbm90IGZvdW5kLCBmb3Igbm9kZSAke25vZGUuZ2V0VGV4dCgpfSBpbiAke25vZGUuZ2V0U291cmNlRmlsZSgpLmdldEJhc2VOYW1lKCl9IGF0IGxpbmUgJHtub2RlLmdldFN0YXJ0TGluZU51bWJlcigpfS5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgQ3JlYXRpbmcgRmFtaXhBY2Nlc3MuIE5vZGU6IFske25vZGUuZ2V0S2luZE5hbWUoKX1dICcke25vZGUuZ2V0VGV4dCgpfScgYXQgbGluZSAke25vZGUuZ2V0U3RhcnRMaW5lTnVtYmVyKCl9IGluICR7bm9kZS5nZXRTb3VyY2VGaWxlKCkuZ2V0QmFzZU5hbWUoKX0sIGlkOiAke2lkfSByZWZlcnMgdG8gZm14VmFyICcke2ZteFZhci5mdWxseVF1YWxpZmllZE5hbWV9Jy5gKTtcblxuICAgICAgICBjb25zdCBub2RlUmVmZXJlbmNlQW5jZXN0b3IgPSBIZWxwZXJzLmZpbmRBbmNlc3Rvcihub2RlKTtcbiAgICAgICAgY29uc3QgYW5jZXN0b3JGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKG5vZGVSZWZlcmVuY2VBbmNlc3Rvcik7XG4gICAgICAgIGxldCBhY2Nlc3NvciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShhbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgRmFtaXguQ29udGFpbmVyRW50aXR5O1xuICAgICAgICBpZiAoIWFjY2Vzc29yKSB7XG4gICAgICAgICAgICBsb2dnZXIuZXJyb3IoYEFuY2VzdG9yICR7YW5jZXN0b3JGdWxseVF1YWxpZmllZE5hbWV9IG9mIGtpbmQgJHtub2RlUmVmZXJlbmNlQW5jZXN0b3IuZ2V0S2luZE5hbWUoKX0gbm90IGZvdW5kLmApO1xuICAgICAgICAgICAgLy8gYWNjZXNzb3IgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGFuY2VzdG9yRnVsbHlRdWFsaWZpZWROYW1lLCBub2RlUmVmZXJlbmNlQW5jZXN0b3IgYXMgVHlwZURlY2xhcmF0aW9uKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZteEFjY2VzcyA9IG5ldyBGYW1peC5BY2Nlc3MoKTtcbiAgICAgICAgZm14QWNjZXNzLmFjY2Vzc29yID0gYWNjZXNzb3I7XG4gICAgICAgIGZteEFjY2Vzcy52YXJpYWJsZSA9IGZteFZhcjtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14QWNjZXNzKTtcblxuICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEFjY2Vzcyxub2RlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggaW52b2NhdGlvblxuICAgICAqIEBwYXJhbSBub2RlIEEgbm9kZVxuICAgICAqIEBwYXJhbSBtIEEgbWV0aG9kIG9yIGEgZnVuY3Rpb25cbiAgICAgKiBAcGFyYW0gaWQgVGhlIGlkIG9mIHRoZSBtZXRob2Qgb3IgdGhlIGZ1bmN0aW9uXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4SW52b2NhdGlvbihub2RlOiBJZGVudGlmaWVyLCBtOiBNZXRob2REZWNsYXJhdGlvbiB8IENvbnN0cnVjdG9yRGVjbGFyYXRpb24gfCBHZXRBY2Nlc3NvckRlY2xhcmF0aW9uIHwgU2V0QWNjZXNzb3JEZWNsYXJhdGlvbiB8IEZ1bmN0aW9uRGVjbGFyYXRpb24gfCBGdW5jdGlvbkV4cHJlc3Npb24sIGlkOiBudW1iZXIpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZm14TWV0aG9kT3JGdW5jdGlvbiA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUlkKGlkKSBhcyBGYW1peC5CZWhhdmlvcmFsRW50aXR5O1xuICAgICAgICBjb25zdCBub2RlUmVmZXJlbmNlQW5jZXN0b3IgPSBIZWxwZXJzLmZpbmRBbmNlc3Rvcihub2RlKTtcbiAgICAgICAgY29uc3QgYW5jZXN0b3JGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKG5vZGVSZWZlcmVuY2VBbmNlc3Rvcik7XG4gICAgICAgIGNvbnN0IHNlbmRlciA9IHRoaXMuZmFtaXhSZXAuZ2V0RmFtaXhFbnRpdHlCeUZ1bGx5UXVhbGlmaWVkTmFtZShhbmNlc3RvckZ1bGx5UXVhbGlmaWVkTmFtZSkgYXMgRmFtaXguQ29udGFpbmVyRW50aXR5O1xuICAgICAgICBjb25zdCByZWNlaXZlckZ1bGx5UXVhbGlmaWVkTmFtZSA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4obS5nZXRQYXJlbnQoKSk7XG4gICAgICAgIGNvbnN0IHJlY2VpdmVyID0gdGhpcy5mYW1peFJlcC5nZXRGYW1peEVudGl0eUJ5RnVsbHlRdWFsaWZpZWROYW1lKHJlY2VpdmVyRnVsbHlRdWFsaWZpZWROYW1lKSBhcyBGYW1peC5OYW1lZEVudGl0eTtcblxuICAgICAgICBjb25zdCBmbXhJbnZvY2F0aW9uID0gbmV3IEZhbWl4Lkludm9jYXRpb24oKTtcbiAgICAgICAgZm14SW52b2NhdGlvbi5zZW5kZXIgPSBzZW5kZXI7XG4gICAgICAgIGZteEludm9jYXRpb24ucmVjZWl2ZXIgPSByZWNlaXZlcjtcbiAgICAgICAgZm14SW52b2NhdGlvbi5hZGRDYW5kaWRhdGUoZm14TWV0aG9kT3JGdW5jdGlvbik7XG4gICAgICAgIGZteEludm9jYXRpb24uc2lnbmF0dXJlID0gZm14TWV0aG9kT3JGdW5jdGlvbi5zaWduYXR1cmU7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEludm9jYXRpb24pO1xuXG4gICAgICAgIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14SW52b2NhdGlvbixub2RlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggaW5oZXJpdGFuY2VcbiAgICAgKiBAcGFyYW0gY2xzIEEgY2xhc3Mgb3IgYW4gaW50ZXJmYWNlIChzdWJjbGFzcylcbiAgICAgKiBAcGFyYW0gaW5oQ2xhc3MgVGhlIGluaGVyaXRlZCBjbGFzcyBvciBpbnRlcmZhY2UgKHN1cGVyY2xhc3MpXG4gICAgICovXG4gICAgcHVibGljIGNyZWF0ZUZhbWl4SW5oZXJpdGFuY2UoY2xzOiBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24sIGluaENsYXNzOiBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBFeHByZXNzaW9uV2l0aFR5cGVBcmd1bWVudHMpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgZm14SW5oZXJpdGFuY2UgPSBuZXcgRmFtaXguSW5oZXJpdGFuY2UoKTtcbiAgICAgICAgLy8gY29uc3QgY2xzTmFtZSA9IGNscy5nZXROYW1lKCk7XG4gICAgICAgIGNvbnN0IGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lID0gRlFORnVuY3Rpb25zLmdldEZRTihjbHMpO1xuICAgICAgICBsb2dnZXIuZGVidWcoYGNyZWF0ZUZhbWl4SW5oZXJpdGFuY2U6IGNsYXNzRnVsbHlRdWFsaWZpZWROYW1lOiBjbGFzcyBmcW4gPSAke2NsYXNzRnVsbHlRdWFsaWZpZWROYW1lfWApO1xuICAgICAgICBsZXQgc3ViQ2xhc3M6IEZhbWl4LkNsYXNzIHwgRmFtaXguSW50ZXJmYWNlIHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAoY2xzIGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgc3ViQ2xhc3MgPSB0aGlzLmZteENsYXNzTWFwLmdldChjbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICBzdWJDbGFzcyA9IHRoaXMuZm14SW50ZXJmYWNlTWFwLmdldChjbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZSk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFzdWJDbGFzcykge1xuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBTdWJjbGFzcyAke2NsYXNzRnVsbHlRdWFsaWZpZWROYW1lfSBub3QgZm91bmQgaW4gQ2xhc3Mgb3IgSW50ZXJmYWNlIG1hcHMuYCk7XG4gICAgICAgIH1cbiAgICAgICAgXG4gICAgICAgIGxldCBpbmhDbGFzc05hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGluaENsYXNzRnVsbHlRdWFsaWZpZWROYW1lOiBzdHJpbmc7XG4gICAgICAgIGxldCBzdXBlckNsYXNzOiBGYW1peC5DbGFzcyB8IEZhbWl4LkludGVyZmFjZSB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKGluaENsYXNzIGluc3RhbmNlb2YgQ2xhc3NEZWNsYXJhdGlvbiB8fCBpbmhDbGFzcyBpbnN0YW5jZW9mIEludGVyZmFjZURlY2xhcmF0aW9uKSB7XG4gICAgICAgICAgICBpbmhDbGFzc05hbWUgPSBpbmhDbGFzcy5nZXROYW1lKCk7XG4gICAgICAgICAgICBpZiAoIWluaENsYXNzTmFtZSkge1xuICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSW5oZXJpdGVkIGNsYXNzIG9yIGludGVyZmFjZSBuYW1lIG5vdCBmb3VuZCBmb3IgJHtpbmhDbGFzcy5nZXRUZXh0KCl9LmApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGluaENsYXNzKTtcbiAgICAgICAgICAgIGlmIChpbmhDbGFzcyBpbnN0YW5jZW9mIENsYXNzRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgICAgICBzdXBlckNsYXNzID0gdGhpcy5mbXhDbGFzc01hcC5nZXQoaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3VwZXJDbGFzcyA9IHRoaXMuZm14SW50ZXJmYWNlTWFwLmdldChpbmhDbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBpZiAoIXN1cGVyQ2xhc3MpIHtcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYFN1cGVyY2xhc3MgJHtjbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZX0gbm90IGZvdW5kIGluIENsYXNzIG9yIEludGVyZmFjZSBtYXBzLmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgLy8gaW5oQ2xhc3MgaXMgYW4gRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzXG4gICAgICAgICAgICBpbmhDbGFzc05hbWUgPSBpbmhDbGFzcy5nZXRFeHByZXNzaW9uKCkuZ2V0VGV4dCgpO1xuICAgICAgICAgICAgLy8gd2hhdCBpcyBpbmhDbGFzc0Z1bGx5UXVhbGlmaWVkTmFtZT8gVE9ET1xuICAgICAgICAgICAgaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUgPSAnVW5kZWZpbmVkX1Njb3BlX2Zyb21faW1wb3J0ZXIuJyArIGluaENsYXNzTmFtZTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChzdXBlckNsYXNzID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgIGlmIChpbmhDbGFzcyBpbnN0YW5jZW9mIENsYXNzRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgICAgICBzdXBlckNsYXNzID0gbmV3IEZhbWl4LkNsYXNzKCk7XG4gICAgICAgICAgICAgICAgdGhpcy5mbXhDbGFzc01hcC5zZXQoaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUsIHN1cGVyQ2xhc3MpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgZWxzZSB7XG4gICAgICAgICAgICAgICAgc3VwZXJDbGFzcyA9IG5ldyBGYW1peC5JbnRlcmZhY2UoKTtcbiAgICAgICAgICAgICAgICB0aGlzLmZteEludGVyZmFjZU1hcC5zZXQoaW5oQ2xhc3NGdWxseVF1YWxpZmllZE5hbWUsIHN1cGVyQ2xhc3MpO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KHN1cGVyQ2xhc3MsaW5oQ2xhc3MpO1xuXG4gICAgICAgICAgICBzdXBlckNsYXNzLm5hbWUgPSBpbmhDbGFzc05hbWU7XG4gICAgICAgICAgICBzdXBlckNsYXNzLmZ1bGx5UXVhbGlmaWVkTmFtZSA9IGluaENsYXNzRnVsbHlRdWFsaWZpZWROYW1lO1xuICAgICAgICAgICAgc3VwZXJDbGFzcy5pc1N0dWIgPSB0cnVlO1xuXG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihpbmhDbGFzcywgc3VwZXJDbGFzcyk7XG4gICAgICAgIFxuICAgICAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KHN1cGVyQ2xhc3MpO1xuICAgICAgICB9XG5cbiAgICAgICAgZm14SW5oZXJpdGFuY2Uuc3ViY2xhc3MgPSBzdWJDbGFzcztcbiAgICAgICAgZm14SW5oZXJpdGFuY2Uuc3VwZXJjbGFzcyA9IHN1cGVyQ2xhc3M7XG5cbiAgICAgICAgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGZteEluaGVyaXRhbmNlKTtcblxuICAgICAgICAvLyBXZSBkb24ndCBtYXAgaW5oZXJpdGFuY2UgdG8gdGhlIHNvdXJjZSBjb2RlIGVsZW1lbnQgYmVjYXVzZSB0aGVyZSBhcmUgdHdvIGVsZW1lbnRzIChzdXBlciwgc3ViKVxuICAgICAgICAvLyB0aGlzLmZteEVsZW1lbnRPYmplY3RNYXAuc2V0KGZteEluaGVyaXRhbmNlLCBudWxsKTtcblxuICAgIH1cblxuICAgIHB1YmxpYyBjcmVhdGVGYW1peEltcG9ydENsYXVzZShpbXBvcnRlZEVudGl0eTogRmFtaXguTmFtZWRFbnRpdHksIGltcG9ydGluZ0VudGl0eTogRmFtaXguTW9kdWxlKSB7XG4gICAgICAgIGNvbnN0IGZteEltcG9ydENsYXVzZSA9IG5ldyBGYW1peC5JbXBvcnRDbGF1c2UoKTtcbiAgICAgICAgZm14SW1wb3J0Q2xhdXNlLmltcG9ydGVkRW50aXR5ID0gaW1wb3J0ZWRFbnRpdHk7XG4gICAgICAgIGZteEltcG9ydENsYXVzZS5pbXBvcnRpbmdFbnRpdHkgPSBpbXBvcnRpbmdFbnRpdHk7XG4gICAgICAgIGltcG9ydGluZ0VudGl0eS5hZGRPdXRnb2luZ0ltcG9ydChmbXhJbXBvcnRDbGF1c2UpO1xuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW1wb3J0Q2xhdXNlKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggaW1wb3J0IGNsYXVzZVxuICAgICAqIEBwYXJhbSBpbXBvcnRDbGF1c2VJbmZvIFRoZSBpbmZvcm1hdGlvbiBuZWVkZWQgdG8gY3JlYXRlIGEgRmFtaXggaW1wb3J0IGNsYXVzZVxuICAgICAqIEBwYXJhbSBpbXBvcnREZWNsYXJhdGlvbiBUaGUgaW1wb3J0IGRlY2xhcmF0aW9uXG4gICAgICogQHBhcmFtIGltcG9ydGVyIEEgc291cmNlIGZpbGUgd2hpY2ggaXMgYSBtb2R1bGVcbiAgICAgKiBAcGFyYW0gbW9kdWxlU3BlY2lmaWVyRmlsZVBhdGggVGhlIHBhdGggb2YgdGhlIG1vZHVsZSB3aGVyZSB0aGUgZXhwb3J0IGRlY2xhcmF0aW9uIGlzXG4gICAgICogQHBhcmFtIGltcG9ydEVsZW1lbnQgVGhlIGltcG9ydGVkIGVudGl0eVxuICAgICAqIEBwYXJhbSBpc0luRXhwb3J0cyBBIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgaW1wb3J0ZWQgZW50aXR5IGlzIGluIHRoZSBleHBvcnRzXG4gICAgICogQHBhcmFtIGlzRGVmYXVsdEV4cG9ydCBBIGJvb2xlYW4gaW5kaWNhdGluZyBpZiB0aGUgaW1wb3J0ZWQgZW50aXR5IGlzIGEgZGVmYXVsdCBleHBvcnRcbiAgICAgKi9cbiAgICBwdWJsaWMgb2xkQ3JlYXRlRmFtaXhJbXBvcnRDbGF1c2UoaW1wb3J0Q2xhdXNlSW5mbzoge2ltcG9ydERlY2xhcmF0aW9uPzogSW1wb3J0RGVjbGFyYXRpb24gfCBJbXBvcnRFcXVhbHNEZWNsYXJhdGlvbiwgaW1wb3J0ZXJTb3VyY2VGaWxlOiBTb3VyY2VGaWxlLCBtb2R1bGVTcGVjaWZpZXJGaWxlUGF0aDogc3RyaW5nLCBpbXBvcnRFbGVtZW50OiBJbXBvcnRTcGVjaWZpZXIgfCBJZGVudGlmaWVyLCBpc0luRXhwb3J0czogYm9vbGVhbiwgaXNEZWZhdWx0RXhwb3J0OiBib29sZWFufSk6IHZvaWQge1xuICAgICAgICBjb25zdCB7aW1wb3J0RGVjbGFyYXRpb24sIGltcG9ydGVyU291cmNlRmlsZTogaW1wb3J0ZXIsIG1vZHVsZVNwZWNpZmllckZpbGVQYXRoLCBpbXBvcnRFbGVtZW50LCBpc0luRXhwb3J0cywgaXNEZWZhdWx0RXhwb3J0fSA9IGltcG9ydENsYXVzZUluZm87XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgY3JlYXRlRmFtaXhJbXBvcnRDbGF1c2U6IENyZWF0aW5nIGltcG9ydCBjbGF1c2U6YCk7XG4gICAgICAgIGNvbnN0IGZteEltcG9ydENsYXVzZSA9IG5ldyBGYW1peC5JbXBvcnRDbGF1c2UoKTtcblxuICAgICAgICBsZXQgaW1wb3J0ZWRFbnRpdHk6IEZhbWl4Lk5hbWVkRW50aXR5IHwgRmFtaXguU3RydWN0dXJhbEVudGl0eSB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgICAgICAgbGV0IGltcG9ydGVkRW50aXR5TmFtZTogc3RyaW5nO1xuXG4gICAgICAgIGNvbnN0IGFic29sdXRlUGF0aFByb2plY3QgPSB0aGlzLmZhbWl4UmVwLmdldEFic29sdXRlUGF0aCgpO1xuICAgICAgICBcbiAgICAgICAgY29uc3QgYWJzb2x1dGVQYXRoID0gcGF0aC5ub3JtYWxpemUobW9kdWxlU3BlY2lmaWVyRmlsZVBhdGgpO1xuICAgICAgICAvLyBjb252ZXJ0IHRoZSBwYXRoIGFuZCByZW1vdmUgYW55IHdpbmRvd3MgYmFja3NsYXNoZXMgaW50cm9kdWNlZCBieSBwYXRoLm5vcm1hbGl6ZVxuICAgICAgICBjb25zdCBwYXRoSW5Qcm9qZWN0OiBzdHJpbmcgPSB0aGlzLmNvbnZlcnRUb1JlbGF0aXZlUGF0aChhYnNvbHV0ZVBhdGgsIGFic29sdXRlUGF0aFByb2plY3QpLnJlcGxhY2UoL1xcXFwvZywgXCIvXCIpO1xuICAgICAgICBsZXQgcGF0aE5hbWUgPSBcIntcIiArIHBhdGhJblByb2plY3QgKyBcIn0uXCI7XG5cbiAgICAgICAgLy8gTmFtZWQgaW1wb3J0cywgZS5nLiBpbXBvcnQgeyBDbGFzc1cgfSBmcm9tIFwiLi9jb21wbGV4RXhwb3J0TW9kdWxlXCI7XG5cbiAgICAgICAgLy8gU3RhcnQgd2l0aCBzaW1wbGUgaW1wb3J0IGNsYXVzZSAod2l0aG91dCByZWZlcnJpbmcgdG8gdGhlIGFjdHVhbCB2YXJpYWJsZSlcblxuICAgICAgICBpZiAoaW1wb3J0RGVjbGFyYXRpb24gaW5zdGFuY2VvZiBJbXBvcnREZWNsYXJhdGlvbiBcbiAgICAgICAgICAgICYmIGltcG9ydEVsZW1lbnQgaW5zdGFuY2VvZiBJbXBvcnRTcGVjaWZpZXIpIHsgXG4gICAgICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHlOYW1lID0gaW1wb3J0RWxlbWVudC5nZXROYW1lKCk7XG4gICAgICAgICAgICBwYXRoTmFtZSA9IHBhdGhOYW1lICsgaW1wb3J0ZWRFbnRpdHlOYW1lO1xuICAgICAgICAgICAgaWYgKGlzSW5FeHBvcnRzKSB7XG4gICAgICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUocGF0aE5hbWUpIGFzIEZhbWl4Lk5hbWVkRW50aXR5O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKGltcG9ydGVkRW50aXR5ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICAgICAgICBpbXBvcnRlZEVudGl0eSA9IG5ldyBGYW1peC5OYW1lZEVudGl0eSgpO1xuICAgICAgICAgICAgICAgIGltcG9ydGVkRW50aXR5Lm5hbWUgPSBpbXBvcnRlZEVudGl0eU5hbWU7XG4gICAgICAgICAgICAgICAgaWYgKCFpc0luRXhwb3J0cykge1xuICAgICAgICAgICAgICAgICAgICBpbXBvcnRlZEVudGl0eS5pc1N0dWIgPSB0cnVlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpbXBvcnRlZEVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPSBwYXRoTmFtZTtcbiAgICAgICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihpbXBvcnRFbGVtZW50LCBpbXBvcnRlZEVudGl0eSk7XG4gICAgICAgICAgICAgICAgLy8gbXVzdCBhZGQgZW50aXR5IHRvIHJlcG9zaXRvcnlcbiAgICAgICAgICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoaW1wb3J0ZWRFbnRpdHkpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIC8vIGhhbmRsZSBpbXBvcnQgZXF1YWxzIGRlY2xhcmF0aW9ucywgZS5nLiBpbXBvcnQgbXlNb2R1bGUgPSByZXF1aXJlKFwiLi9jb21wbGV4RXhwb3J0TW9kdWxlXCIpO1xuICAgICAgICAvLyBUeXBlU2NyaXB0IGNhbid0IGRldGVybWluZSB0aGUgdHlwZSBvZiB0aGUgaW1wb3J0ZWQgbW9kdWxlLCBzbyB3ZSBjcmVhdGUgYSBNb2R1bGUgZW50aXR5XG4gICAgICAgIGVsc2UgaWYgKGltcG9ydERlY2xhcmF0aW9uIGluc3RhbmNlb2YgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5TmFtZSA9IGltcG9ydERlY2xhcmF0aW9uPy5nZXROYW1lKCk7XG4gICAgICAgICAgICBwYXRoTmFtZSA9IHBhdGhOYW1lICsgaW1wb3J0ZWRFbnRpdHlOYW1lO1xuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkgPSBuZXcgRmFtaXguU3RydWN0dXJhbEVudGl0eSgpO1xuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkubmFtZSA9IGltcG9ydGVkRW50aXR5TmFtZTtcbiAgICAgICAgICAgIGluaXRGUU4oaW1wb3J0RGVjbGFyYXRpb24sIGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgIHRoaXMubWFrZUZhbWl4SW5kZXhGaWxlQW5jaG9yKGltcG9ydEVsZW1lbnQsIGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9IHBhdGhOYW1lO1xuICAgICAgICAgICAgY29uc3QgYW55VHlwZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peFR5cGUoJ2FueScsIGltcG9ydERlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgIChpbXBvcnRlZEVudGl0eSBhcyBGYW1peC5TdHJ1Y3R1cmFsRW50aXR5KS5kZWNsYXJlZFR5cGUgPSBhbnlUeXBlO1xuICAgICAgICB9IGVsc2UgeyAgLy8gZGVmYXVsdCBpbXBvcnRzLCBlLmcuIGltcG9ydCBDbGFzc1cgZnJvbSBcIi4vY29tcGxleEV4cG9ydE1vZHVsZVwiOyAgXG4gICAgICAgICAgICBpbXBvcnRlZEVudGl0eU5hbWUgPSBpbXBvcnRFbGVtZW50LmdldFRleHQoKTtcbiAgICAgICAgICAgIHBhdGhOYW1lID0gcGF0aE5hbWUgKyAoaXNEZWZhdWx0RXhwb3J0ID8gXCJkZWZhdWx0RXhwb3J0XCIgOiBcIm5hbWVzcGFjZUV4cG9ydFwiKTtcbiAgICAgICAgICAgIGltcG9ydGVkRW50aXR5ID0gbmV3IEZhbWl4Lk5hbWVkRW50aXR5KCk7XG4gICAgICAgICAgICBpbXBvcnRlZEVudGl0eS5uYW1lID0gaW1wb3J0ZWRFbnRpdHlOYW1lO1xuICAgICAgICAgICAgaW1wb3J0ZWRFbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lID0gcGF0aE5hbWU7XG4gICAgICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihpbXBvcnRFbGVtZW50LCBpbXBvcnRlZEVudGl0eSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSSBkb24ndCB0aGluayBpdCBzaG91bGQgYmUgYWRkZWQgdG8gdGhlIHJlcG9zaXRvcnkgaWYgaXQgZXhpc3RzIGFscmVhZHlcbiAgICAgICAgaWYgKCFpc0luRXhwb3J0cykgdGhpcy5mYW1peFJlcC5hZGRFbGVtZW50KGltcG9ydGVkRW50aXR5KTtcbiAgICAgICAgY29uc3QgaW1wb3J0ZXJGdWxseVF1YWxpZmllZE5hbWUgPSBGUU5GdW5jdGlvbnMuZ2V0RlFOKGltcG9ydGVyKTtcbiAgICAgICAgY29uc3QgZm14SW1wb3J0ZXIgPSB0aGlzLmZhbWl4UmVwLmdldEZhbWl4RW50aXR5QnlGdWxseVF1YWxpZmllZE5hbWUoaW1wb3J0ZXJGdWxseVF1YWxpZmllZE5hbWUpIGFzIEZhbWl4Lk1vZHVsZTtcbiAgICAgICAgZm14SW1wb3J0Q2xhdXNlLmltcG9ydGluZ0VudGl0eSA9IGZteEltcG9ydGVyO1xuICAgICAgICBmbXhJbXBvcnRDbGF1c2UuaW1wb3J0ZWRFbnRpdHkgPSBpbXBvcnRlZEVudGl0eTtcbiAgICAgICAgaWYgKGltcG9ydERlY2xhcmF0aW9uIGluc3RhbmNlb2YgSW1wb3J0RXF1YWxzRGVjbGFyYXRpb24pIHtcbiAgICAgICAgICAgIGZteEltcG9ydENsYXVzZS5tb2R1bGVTcGVjaWZpZXIgPSBpbXBvcnREZWNsYXJhdGlvbj8uZ2V0TW9kdWxlUmVmZXJlbmNlKCkuZ2V0VGV4dCgpIGFzIHN0cmluZztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGZteEltcG9ydENsYXVzZS5tb2R1bGVTcGVjaWZpZXIgPSBpbXBvcnREZWNsYXJhdGlvbj8uZ2V0TW9kdWxlU3BlY2lmaWVyVmFsdWUoKSBhcyBzdHJpbmc7XG4gICAgICAgIH1cbiAgICBcbiAgICAgICAgbG9nZ2VyLmRlYnVnKGBjcmVhdGVGYW1peEltcG9ydENsYXVzZTogJHtmbXhJbXBvcnRDbGF1c2UuaW1wb3J0ZWRFbnRpdHk/Lm5hbWV9IChvZiB0eXBlICR7XG4gICAgICAgICAgICBIZWxwZXJzLmdldFN1YlR5cGVOYW1lKGZteEltcG9ydENsYXVzZS5pbXBvcnRlZEVudGl0eSl9KSBpcyBpbXBvcnRlZCBieSAke2ZteEltcG9ydENsYXVzZS5pbXBvcnRpbmdFbnRpdHk/Lm5hbWV9YCk7XG5cbiAgICAgICAgZm14SW1wb3J0ZXIuYWRkT3V0Z29pbmdJbXBvcnQoZm14SW1wb3J0Q2xhdXNlKTtcblxuICAgICAgICB0aGlzLmZhbWl4UmVwLmFkZEVsZW1lbnQoZm14SW1wb3J0Q2xhdXNlKTtcblxuICAgICAgICBpZiAoaW1wb3J0RGVjbGFyYXRpb24pIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14SW1wb3J0Q2xhdXNlLCBpbXBvcnREZWNsYXJhdGlvbik7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IEFycm93IEZ1bmN0aW9uXG4gICAgICogQHBhcmFtIGFycm93RXhwcmVzc2lvbiBBbiBFeHByZXNzaW9uXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSB2YXJpYWJsZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peEFycm93RnVuY3Rpb24oYXJyb3dFeHByZXNzaW9uOiBFeHByZXNzaW9uLCBjdXJyZW50Q0M6IHsgW2tleTogc3RyaW5nXTogbnVtYmVyIH0gKTogRmFtaXguQXJyb3dGdW5jdGlvbiB8IEZhbWl4LlBhcmFtZXRyaWNBcnJvd0Z1bmN0aW9uIHtcbiAgICAgICAgXG4gICAgICAgIGxldCBmbXhBcnJvd0Z1bmN0aW9uOiBGYW1peC5BcnJvd0Z1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY0Fycm93RnVuY3Rpb247XG5cbiAgICAgICAgY29uc3QgYXJyb3dGdW5jdGlvbiA9IGFycm93RXhwcmVzc2lvbi5hc0tpbmRPclRocm93KFN5bnRheEtpbmQuQXJyb3dGdW5jdGlvbik7XG5cbiAgICAgICAgY29uc3QgaXNHZW5lcmljID0gYXJyb3dGdW5jdGlvbi5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDA7XG5cbiAgICAgICAgaWYgKGlzR2VuZXJpYykge1xuICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbiA9IG5ldyBGYW1peC5QYXJhbWV0cmljQXJyb3dGdW5jdGlvbigpO1xuICAgICAgICB9XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgICAgZm14QXJyb3dGdW5jdGlvbiA9IG5ldyBGYW1peC5BcnJvd0Z1bmN0aW9uKCk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBHZXQgdGhlIHBhcmVudCBvZiB0aGUgYXJyb3cgZnVuY3Rpb24gKHRoZSB2YXJpYWJsZSBkZWNsYXJhdGlvbilcbiAgICAgICAgY29uc3QgcGFyZW50ID0gYXJyb3dGdW5jdGlvbi5nZXRQYXJlbnRJZktpbmQoU3ludGF4S2luZC5WYXJpYWJsZURlY2xhcmF0aW9uKTtcbiAgICAgICAgbGV0IGZ1bmN0aW9uTmFtZSA9ICcoTk9fTkFNRSknO1xuXG4gICAgICAgIGlmIChwYXJlbnQgJiYgcGFyZW50IGluc3RhbmNlb2YgVmFyaWFibGVEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgLy8gR2V0IHRoZSBuYW1lIG9mIHRoZSB2YXJpYWJsZVxuICAgICAgICAgICAgZnVuY3Rpb25OYW1lID0gcGFyZW50LmdldE5hbWUoKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmIChmdW5jdGlvbk5hbWUpIHtcbiAgICAgICAgICAgIGZteEFycm93RnVuY3Rpb24ubmFtZSA9IGZ1bmN0aW9uTmFtZTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICAgIGZteEFycm93RnVuY3Rpb24ubmFtZSA9IFwiYW5vbnltb3VzXCI7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBTaWduYXR1cmUgb2YgYW4gYXJyb3cgZnVuY3Rpb24gaXMgKHBhcmFtZXRlcnMpID0+IHJldHVybl90eXBlXG4gICAgICAgIGNvbnN0IHBhcmFtZXRlcnNTaWduYXR1cmUgPSBhcnJvd0Z1bmN0aW9uLmdldFBhcmFtZXRlcnMoKS5tYXAocCA9PiBwLmdldFRleHQoKSkuam9pbihcIiwgXCIpO1xuICAgICAgICBjb25zdCByZXR1cm5UeXBlU2lnbmF0dXJlID0gYXJyb3dGdW5jdGlvbi5nZXRSZXR1cm5UeXBlKCkuZ2V0VGV4dCgpO1xuICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLnNpZ25hdHVyZSA9IGAoJHtwYXJhbWV0ZXJzU2lnbmF0dXJlfSkgPT4gJHtyZXR1cm5UeXBlU2lnbmF0dXJlfWA7XG4gICAgICAgIGZteEFycm93RnVuY3Rpb24uY3ljbG9tYXRpY0NvbXBsZXhpdHkgPSBjdXJyZW50Q0NbZm14QXJyb3dGdW5jdGlvbi5uYW1lXTtcblxuICAgICAgICBsZXQgZnVuY3Rpb25UeXBlTmFtZSA9IHRoaXMuVU5LTk9XTl9WQUxVRTtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICAgIGZ1bmN0aW9uVHlwZU5hbWUgPSBhcnJvd0Z1bmN0aW9uLmdldFJldHVyblR5cGUoKS5nZXRUZXh0KCkudHJpbSgpO1xuICAgICAgICB9IGNhdGNoIChlcnJvcikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGA+IFdBUk5JTkc6IGdvdCBleGNlcHRpb24gJHtlcnJvcn0uIEZhaWxlZCB0byBnZXQgdXNhYmxlIG5hbWUgZm9yIHJldHVybiB0eXBlIG9mIGZ1bmN0aW9uOiAke2Z1bmN0aW9uTmFtZX0uIENvbnRpbnVpbmcuLi5gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IGZteFR5cGUgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhUeXBlKGZ1bmN0aW9uVHlwZU5hbWUsIGFycm93RnVuY3Rpb24gYXMgdW5rbm93biBhcyBGdW5jdGlvbkRlY2xhcmF0aW9uKTtcbiAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5kZWNsYXJlZFR5cGUgPSBmbXhUeXBlO1xuICAgICAgICBmbXhBcnJvd0Z1bmN0aW9uLm51bWJlck9mTGluZXNPZkNvZGUgPSBhcnJvd0Z1bmN0aW9uLmdldEVuZExpbmVOdW1iZXIoKSAtIGFycm93RnVuY3Rpb24uZ2V0U3RhcnRMaW5lTnVtYmVyKCk7XG4gICAgICAgIGNvbnN0IHBhcmFtZXRlcnMgPSBhcnJvd0Z1bmN0aW9uLmdldFBhcmFtZXRlcnMoKTtcbiAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5udW1iZXJPZlBhcmFtZXRlcnMgPSBwYXJhbWV0ZXJzLmxlbmd0aDtcbiAgICAgICAgZm14QXJyb3dGdW5jdGlvbi5udW1iZXJPZlN0YXRlbWVudHMgPSBhcnJvd0Z1bmN0aW9uLmdldFN0YXRlbWVudHMoKS5sZW5ndGg7XG4gICAgICAgIGluaXRGUU4oYXJyb3dFeHByZXNzaW9uIGFzIHVua25vd24gYXMgVFNNb3JwaE9iamVjdFR5cGUsIGZteEFycm93RnVuY3Rpb24pO1xuICAgICAgICB0aGlzLm1ha2VGYW1peEluZGV4RmlsZUFuY2hvcihhcnJvd0V4cHJlc3Npb24gYXMgdW5rbm93biBhcyBUU01vcnBoT2JqZWN0VHlwZSwgZm14QXJyb3dGdW5jdGlvbik7XG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhBcnJvd0Z1bmN0aW9uKTtcbiAgICAgICAgdGhpcy5mbXhFbGVtZW50T2JqZWN0TWFwLnNldChmbXhBcnJvd0Z1bmN0aW9uLGFycm93RnVuY3Rpb24gYXMgdW5rbm93biBhcyBUU01vcnBoT2JqZWN0VHlwZSk7XG5cbiAgICAgICAgcmV0dXJuIGZteEFycm93RnVuY3Rpb247XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ3JlYXRlcyBhIEZhbWl4IGNvbmNyZXRpc2F0aW9uXG4gICAgICogQHBhcmFtIGNscyBBIGNsYXNzXG4gICAgICogQHJldHVybnMgVGhlIEZhbWl4IG1vZGVsIG9mIHRoZSBjb25jcmV0aXNhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbkVudGl0eSA6IEZhbWl4LlBhcmFtZXRyaWNDbGFzcyB8IEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2UgfCBGYW1peC5QYXJhbWV0cmljRnVuY3Rpb24gfCBGYW1peC5QYXJhbWV0cmljTWV0aG9kICxnZW5FbnRpdHkgOiBGYW1peC5QYXJhbWV0cmljQ2xhc3MgfCBGYW1peC5QYXJhbWV0cmljSW50ZXJmYWNlIHwgRmFtaXguUGFyYW1ldHJpY0Z1bmN0aW9uIHwgRmFtaXguUGFyYW1ldHJpY01ldGhvZCk6IEZhbWl4LkNvbmNyZXRpc2F0aW9uIHtcbiAgICAgICAgXG4gICAgICAgIGNvbnN0IGZteENvbmNyZXRpc2F0aW9uIDogRmFtaXguQ29uY3JldGlzYXRpb24gPSBuZXcgRmFtaXguQ29uY3JldGlzYXRpb24oKTsgICAgICAgICAgICAgIFxuICAgICAgICBcbiAgICAgICAgZm14Q29uY3JldGlzYXRpb24uY29uY3JldGVFbnRpdHkgPSBjb25FbnRpdHk7XG4gICAgICAgIGZteENvbmNyZXRpc2F0aW9uLmdlbmVyaWNFbnRpdHkgPSBnZW5FbnRpdHk7XG4gICAgICAgIC8vIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14Q29uY3JldGlzYXRpb24sbnVsbCk7XG4gICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhDb25jcmV0aXNhdGlvbik7ICAgIFxuICAgICAgICBjb25zdCBwYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiA9IHRoaXMuY3JlYXRlRmFtaXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbihmbXhDb25jcmV0aXNhdGlvbik7XG4gICAgICAgICAgICBcbiAgICAgICAgcmV0dXJuIGZteENvbmNyZXRpc2F0aW9uO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvblxuICAgICAqIEBwYXJhbSBjb25jcmV0aXNhdGlvbiBBIEZhbWl4Q29uY3JldGlzYXRpb25cbiAgICAgKiBAcmV0dXJucyBUaGUgRmFtaXggbW9kZWwgb2YgdGhlIFBhcmFtZXRlckNvbmNyZXN0aXNhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uKGNvbmNyZXRpc2F0aW9uOiBGYW1peC5Db25jcmV0aXNhdGlvbik6IEZhbWl4LlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uIHwgdW5kZWZpbmVke1xuICAgICAgICBjb25zdCBjb25DbGFzcyA9IGNvbmNyZXRpc2F0aW9uLmNvbmNyZXRlRW50aXR5O1xuICAgICAgICBjb25zdCBnZW5DbGFzcyA9IGNvbmNyZXRpc2F0aW9uLmdlbmVyaWNFbnRpdHk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhgQ3JlYXRpbmcgcGFyYW1ldGVyIGNvbmNyZXRpc2F0aW9uIGJldHdlZW4gJHtjb25DbGFzcy5mdWxseVF1YWxpZmllZE5hbWV9IGFuZCAke2dlbkNsYXNzLmZ1bGx5UXVhbGlmaWVkTmFtZX1gKTtcbiAgICAgICAgY29uc3QgcGFyYW1ldGVyQ29uY3JldGlzYXRpb25zID0gdGhpcy5mYW1peFJlcC5fZ2V0QWxsRW50aXRpZXNXaXRoVHlwZShcIlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uXCIpIGFzIFNldDxGYW1peC5QYXJhbWV0ZXJDb25jcmV0aXNhdGlvbj47XG4gICAgICAgIGNvbnN0IGNvbmNyZXRlUGFyYW1ldGVycyA9IGNvbkNsYXNzLmNvbmNyZXRlUGFyYW1ldGVycztcbiAgICAgICAgY29uc3QgZ2VuZXJpY1BhcmFtZXRlcnMgPSBnZW5DbGFzcy5nZW5lcmljUGFyYW1ldGVycztcbiAgICAgICAgXG4gICAgICAgIGxldCBjb25DbGFzc1R5cGVQYXJhbWV0ZXJzSXRlcmF0b3IgPSBjb25jcmV0ZVBhcmFtZXRlcnMudmFsdWVzKCk7XG4gICAgICAgIGxldCBnZW5DbGFzc1R5cGVQYXJhbWV0ZXJzSXRlcmF0b3IgPSBnZW5lcmljUGFyYW1ldGVycy52YWx1ZXMoKTtcbiAgICAgICAgbGV0IGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uIDogRmFtaXguUGFyYW1ldGVyQ29uY3JldGlzYXRpb24gfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBnZW5lcmljUGFyYW1ldGVycy5zaXplOyBpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IGNvbkNsYXNzVHlwZVBhcmFtZXRlciA9IGNvbkNsYXNzVHlwZVBhcmFtZXRlcnNJdGVyYXRvci5uZXh0KCkudmFsdWUgYXMgRmFtaXguUGFyYW1ldGVyVHlwZTtcbiAgICAgICAgICAgIGNvbnN0IGdlbkNsYXNzVHlwZVBhcmFtZXRlciA9IGdlbkNsYXNzVHlwZVBhcmFtZXRlcnNJdGVyYXRvci5uZXh0KCkudmFsdWUgYXMgRmFtaXguUGFyYW1ldGVyVHlwZTtcbiAgICAgICAgICAgIGxldCBjcmVhdGVQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xuICAgICAgICAgICAgaWYoY29uQ2xhc3NUeXBlUGFyYW1ldGVyICYmIGdlbkNsYXNzVHlwZVBhcmFtZXRlciAmJiBjb25DbGFzc1R5cGVQYXJhbWV0ZXIubmFtZSAhPSBnZW5DbGFzc1R5cGVQYXJhbWV0ZXIubmFtZSl7XG4gICAgICAgICAgICAgICAgcGFyYW1ldGVyQ29uY3JldGlzYXRpb25zLmZvckVhY2goKHBhcmFtIDogRmFtaXguUGFyYW1ldGVyQ29uY3JldGlzYXRpb24pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKGNvbkNsYXNzVHlwZVBhcmFtZXRlci5uYW1lID09IHBhcmFtLmNvbmNyZXRlUGFyYW1ldGVyLm5hbWUgJiYgZ2VuQ2xhc3NUeXBlUGFyYW1ldGVyLm5hbWUgPT0gcGFyYW0uZ2VuZXJpY1BhcmFtZXRlci5uYW1lKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24gPSBwYXJhbTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgaWYgKGNyZWF0ZVBhcmFtZXRlckNvbmNyZXRpc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uID0gbmV3IEZhbWl4LlBhcmFtZXRlckNvbmNyZXRpc2F0aW9uKCk7XG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uLmdlbmVyaWNQYXJhbWV0ZXIgPSBnZW5DbGFzc1R5cGVQYXJhbWV0ZXI7XG4gICAgICAgICAgICAgICAgICAgIGZteFBhcmFtZXRlckNvbmNyZXRpc2F0aW9uLmNvbmNyZXRlUGFyYW1ldGVyID0gY29uQ2xhc3NUeXBlUGFyYW1ldGVyO1xuICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbi5hZGRDb25jcmV0aXNhdGlvbihjb25jcmV0aXNhdGlvbik7XG4gICAgICAgICAgICAgICAgICAgIC8vIHRoaXMuZm14RWxlbWVudE9iamVjdE1hcC5zZXQoZm14UGFyYW1ldGVyQ29uY3JldGlzYXRpb24sbnVsbCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiB3YXMgdW5kZWZpbmVkIGZvciBjb25jcmV0aXNhdGlvbiB3aXRoIGdlbmVyaWMgcGFyYW1ldGVyICR7Z2VuQ2xhc3NUeXBlUGFyYW1ldGVyLm5hbWV9IGFuZCBjb25jcmV0ZSBwYXJhbWV0ZXIgJHtjb25DbGFzc1R5cGVQYXJhbWV0ZXIubmFtZX1gKTtcbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbi5hZGRDb25jcmV0aXNhdGlvbihjb25jcmV0aXNhdGlvbik7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIHRoaXMuZmFtaXhSZXAuYWRkRWxlbWVudChmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbik7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgaWYgKCFmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbikge1xuICAgICAgICAgICAgbG9nZ2VyLmVycm9yKGBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbiB3YXMgdW5kZWZpbmVkIGZvciBjb25jcmV0aXNhdGlvbiB3aXRoIGNvbmNyZXRlIGVudGl0eSAke2NvbkNsYXNzLmZ1bGx5UXVhbGlmaWVkTmFtZX0gYW5kIGdlbmVyaWMgZW50aXR5ICR7Z2VuQ2xhc3MuZnVsbHlRdWFsaWZpZWROYW1lfWApO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiBmbXhQYXJhbWV0ZXJDb25jcmV0aXNhdGlvbjtcblxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvbiBiZXR3ZWVuIHR3byBjbGFzc2VzIG9yIHR3byBpbnRlcmZhY2VzXG4gICAgICogQHBhcmFtIGVsZW1lbnQgQSBjbGFzcyBvciBhbiBJbnRlcmZhY2VcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkNsYXNzT3JJbnRlcmZhY2VTcGVjaWFsaXNhdGlvbihlbGVtZW50OiBDbGFzc0RlY2xhcmF0aW9uIHwgSW50ZXJmYWNlRGVjbGFyYXRpb24pe1xuICAgICAgICBcbiAgICAgICAgY29uc3Qgc3VwZXJFbnRpdHkgPSBlbGVtZW50LmdldEV4dGVuZHMoKTtcbiAgICAgICAgbGV0IHN1cGVyRW50aXR5QXJyYXk7XG4gICAgICAgIGlmIChzdXBlckVudGl0eSl7XG4gICAgICAgICAgICBzdXBlckVudGl0eUFycmF5ID0gQXJyYXkuaXNBcnJheShzdXBlckVudGl0eSkgPyBzdXBlckVudGl0eSA6IFtzdXBlckVudGl0eV07XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHN1cGVyRW50aXR5QXJyYXkgJiYgc3VwZXJFbnRpdHlBcnJheS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBzdXBlckVudGl0eUFycmF5LmZvckVhY2goZW50aXR5ID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgZW50aXR5SXNHZW5lcmljO1xuICAgICAgICAgICAgICAgIGNvbnN0IHN1cGVyRW50aXR5U3ltYm9sID0gZW50aXR5LmdldEV4cHJlc3Npb24oKS5nZXRTeW1ib2xPclRocm93KCk7XG4gICAgICAgICAgICAgICAgbGV0IHN1cGVyRW50aXR5RGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgaWYgKHN1cGVyRW50aXR5IGluc3RhbmNlb2YgRXhwcmVzc2lvbldpdGhUeXBlQXJndW1lbnRzKSB7XG4gICAgICAgICAgICAgICAgICAgIHN1cGVyRW50aXR5RGVjbGFyYXRpb24gPSBzdXBlckVudGl0eVN5bWJvbC5nZXREZWNsYXJhdGlvbnMoKVswXS5hc0tpbmQodHMuU3ludGF4S2luZC5DbGFzc0RlY2xhcmF0aW9uKTtcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICBzdXBlckVudGl0eURlY2xhcmF0aW9uID0gc3VwZXJFbnRpdHlTeW1ib2wuZ2V0RGVjbGFyYXRpb25zKClbMF0uYXNLaW5kKHRzLlN5bnRheEtpbmQuSW50ZXJmYWNlRGVjbGFyYXRpb24pO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBpZiAoc3VwZXJFbnRpdHlEZWNsYXJhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICBlbnRpdHlJc0dlbmVyaWMgPSBzdXBlckVudGl0eURlY2xhcmF0aW9uLmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgaWYgKGVudGl0eUlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgICAgICBsZXQgRW50aXR5RGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgICAgIGxldCBnZW5FbnRpdHk7XG4gICAgICAgICAgICAgICAgICAgIGlmIChzdXBlckVudGl0eSBpbnN0YW5jZW9mIEV4cHJlc3Npb25XaXRoVHlwZUFyZ3VtZW50cykge1xuICAgICAgICAgICAgICAgICAgICAgICAgRW50aXR5RGVjbGFyYXRpb24gPSBlbnRpdHkuZ2V0RXhwcmVzc2lvbigpLmdldFN5bWJvbCgpPy5nZXREZWNsYXJhdGlvbnMoKVswXSBhcyBDbGFzc0RlY2xhcmF0aW9uO1xuICAgICAgICAgICAgICAgICAgICAgICAgZ2VuRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoRW50aXR5RGVjbGFyYXRpb24pIGFzIEZhbWl4LlBhcmFtZXRyaWNDbGFzcztcbiAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIEVudGl0eURlY2xhcmF0aW9uID0gZW50aXR5LmdldEV4cHJlc3Npb24oKS5nZXRTeW1ib2woKT8uZ2V0RGVjbGFyYXRpb25zKClbMF0gYXMgSW50ZXJmYWNlRGVjbGFyYXRpb247XG4gICAgICAgICAgICAgICAgICAgICAgICBnZW5FbnRpdHkgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoRW50aXR5RGVjbGFyYXRpb24pIGFzIEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2U7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gRW50aXR5RGVjbGFyYXRpb24uZ2V0VHlwZVBhcmFtZXRlcnMoKS5tYXAoKHBhcmFtKSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBhcmdzID0gZWxlbWVudC5nZXRIZXJpdGFnZUNsYXVzZXMoKVswXS5nZXRUeXBlTm9kZXMoKVswXS5nZXRUeXBlQXJndW1lbnRzKClcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uUGFyYW1zID0gZWxlbWVudC5nZXRIZXJpdGFnZUNsYXVzZXMoKVswXS5nZXRUeXBlTm9kZXMoKVswXS5nZXRUeXBlQXJndW1lbnRzKCkubWFwKChwYXJhbSkgPT4gcGFyYW0uZ2V0VGV4dCgpKTtcbiAgICAgICAgICAgICAgICAgICAgaWYgKCFIZWxwZXJzLmFycmF5c0FyZUVxdWFsKGNvblBhcmFtcyxnZW5QYXJhbXMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29uRW50aXR5O1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGdlbkVudGl0eSxFbnRpdHlEZWNsYXJhdGlvbixhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbmNyZXRpc2F0aW9ucyA9IHRoaXMuZmFtaXhSZXAuX2dldEFsbEVudGl0aWVzV2l0aFR5cGUoXCJDb25jcmV0aXNhdGlvblwiKSBhcyBTZXQ8RmFtaXguQ29uY3JldGlzYXRpb24+O1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNyZWF0ZUNvbmNyZXRpc2F0aW9uIDogYm9vbGVhbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdlbkVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uYy5nZW5lcmljRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSAmJiBjb25jLmNvbmNyZXRlRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25FbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lKXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3JlYXRlQ29uY3JldGlzYXRpb24gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWF0ZUNvbmNyZXRpc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb24gOiBGYW1peC5Db25jcmV0aXNhdGlvbiA9IHRoaXMuY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbihjb25FbnRpdHksZ2VuRW50aXR5KTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0pO1xuICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IFRoaXMgZnVuY3Rpb24gc2VlbXMgdW5maW5pc2hlZFxuICAgIH0gICAgXG4gICAgXG5cbiAgICAvKipcbiAgICAgKiBDcmVhdGVzIGEgRmFtaXggY29uY3JldGlzYXRpb24gYmV0d2VlbiBhIGNsYXNzIGFuZCBpdHMgaW5zdGFuY2lhdGlvbnNcbiAgICAgKiBAcGFyYW0gY2xzIEEgY2xhc3NcbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkdlbmVyaWNJbnN0YW50aWF0aW9uKGNsczogQ2xhc3NEZWNsYXJhdGlvbil7XG4gICAgICAgXG4gICAgICAgIGNvbnN0IGlzR2VuZXJpYyA9IGNscy5nZXRUeXBlUGFyYW1ldGVycygpLmxlbmd0aCA+IDA7XG4gICAgICAgIGlmIChpc0dlbmVyaWMpIHtcbiAgICAgICAgICAgIGNvbnN0IGluc3RhbmNlcyA9IGNscy5nZXRTb3VyY2VGaWxlKCkuZ2V0RGVzY2VuZGFudHNPZktpbmQodHMuU3ludGF4S2luZC5OZXdFeHByZXNzaW9uKVxuICAgICAgICAgICAgICAgIC5maWx0ZXIobmV3RXhwciA9PiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSBuZXdFeHByLmdldEV4cHJlc3Npb24oKTtcbiAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGV4cHJlc3Npb24uZ2V0VGV4dCgpID09PSBjbHMuZ2V0TmFtZSgpO1xuICAgICAgICAgICAgfSk7XG5cbiAgICAgICAgICAgIGluc3RhbmNlcy5mb3JFYWNoKGluc3RhbmNlID0+IHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnN0YW5jZUlzR2VuZXJpYyA9IGluc3RhbmNlLmdldFR5cGVBcmd1bWVudHMoKS5sZW5ndGggPiAwO1xuICAgICAgICAgICAgICAgIGlmIChpbnN0YW5jZUlzR2VuZXJpYykge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25QYXJhbXMgPSBpbnN0YW5jZS5nZXRUeXBlQXJndW1lbnRzKCkubWFwKChwYXJhbSkgPT4gcGFyYW0uZ2V0VGV4dCgpKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZ2VuRW50aXR5ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q2xhc3MoY2xzKSBhcyBGYW1peC5QYXJhbWV0cmljQ2xhc3M7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGdlblBhcmFtcyA9IGNscy5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCgocGFyYW0pID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICAgICAgICAgIGlmICghSGVscGVycy5hcnJheXNBcmVFcXVhbChjb25QYXJhbXMsZ2VuUGFyYW1zKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbkVudGl0eTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbkVudGl0eSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENvbmNyZXRlRWxlbWVudChnZW5FbnRpdHksY2xzLGluc3RhbmNlLmdldFR5cGVBcmd1bWVudHMoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25jcmV0aXNhdGlvbnMgPSB0aGlzLmZhbWl4UmVwLl9nZXRBbGxFbnRpdGllc1dpdGhUeXBlKFwiQ29uY3JldGlzYXRpb25cIikgYXMgU2V0PEZhbWl4LkNvbmNyZXRpc2F0aW9uPjtcbiAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjcmVhdGVDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uY3JldGlzYXRpb25zLmZvckVhY2goKGNvbmMgOiBGYW1peC5Db25jcmV0aXNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnZW5FbnRpdHkuZnVsbHlRdWFsaWZpZWROYW1lID09IGNvbmMuZ2VuZXJpY0VudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgJiYgY29uYy5jb25jcmV0ZUVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSl7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjcmVhdGVDb25jcmV0aXNhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZteENvbmNyZXRpc2F0aW9uIDogRmFtaXguQ29uY3JldGlzYXRpb24gPSB0aGlzLmNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb24oY29uRW50aXR5LGdlbkVudGl0eSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KVxuICAgICAgICB9XG4gICAgICAgIC8vIFRPRE86IFRoaXMgZnVuY3Rpb24gc2VlbXMgdW5maW5pc2hlZFxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvbiBiZXR3ZWVuIGEgY2xhc3MgYW5kIGl0cyBpbnN0YW5jaWF0aW9uc1xuICAgICAqIEBwYXJhbSBmdW5jIEEgZnVuY3Rpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbkZ1bmN0aW9uSW5zdGFudGlhdGlvbihlbGVtZW50OiBGdW5jdGlvbkRlY2xhcmF0aW9uIHwgTWV0aG9kRGVjbGFyYXRpb24pe1xuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgaWYgKGlzR2VuZXJpYykge1xuICAgICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpLm1hcChwYXJhbSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgY29uc3QgdXNlcyA9IGVsZW1lbnQuZmluZFJlZmVyZW5jZXNBc05vZGVzKCk7ICAgIFxuICAgICAgICAgICAgdXNlcy5mb3JFYWNoKHVzYWdlID0+IHtcbiAgICAgICAgICAgICAgICBsZXQgY3VycmVudE5vZGU6IE5vZGUgfCB1bmRlZmluZWQgPSB1c2FnZTtcblxuICAgICAgICAgICAgICAgIHdoaWxlIChjdXJyZW50Tm9kZSkge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudE5vZGUuZ2V0S2luZCgpID09PSBTeW50YXhLaW5kLkNhbGxFeHByZXNzaW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjYWxsRXhwcmVzc2lvbiA9IGN1cnJlbnROb2RlLmFzS2luZChTeW50YXhLaW5kLkNhbGxFeHByZXNzaW9uKTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmICghY2FsbEV4cHJlc3Npb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYENhbGxFeHByZXNzaW9uIG5vdCBmb3VuZCBmb3IgJHtjdXJyZW50Tm9kZS5nZXRUZXh0KCl9YCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBpbnN0YW5jZUlzR2VuZXJpYyA9IGNhbGxFeHByZXNzaW9uLmdldFR5cGVBcmd1bWVudHMoKS5sZW5ndGggPiAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGluc3RhbmNlSXNHZW5lcmljKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgYXJncyA9IGNhbGxFeHByZXNzaW9uLmdldFR5cGVBcmd1bWVudHMoKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBjb25QYXJhbXMgPSBjYWxsRXhwcmVzc2lvbi5nZXRUeXBlQXJndW1lbnRzKCkubWFwKHBhcmFtID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFIZWxwZXJzLmFycmF5c0FyZUVxdWFsKGNvblBhcmFtcyxnZW5QYXJhbXMpKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBnZW5FbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZihlbGVtZW50IGluc3RhbmNlb2YgRnVuY3Rpb25EZWNsYXJhdGlvbil7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZW5FbGVtZW50ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4RnVuY3Rpb24oZWxlbWVudCwge30pIGFzIEZhbWl4LlBhcmFtZXRyaWNGdW5jdGlvbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbkVsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhNZXRob2QoZWxlbWVudCwge30pIGFzIEZhbWl4LlBhcmFtZXRyaWNNZXRob2Q7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGV0IGNvbmNFbGVtZW50O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25jRWxlbWVudCA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENvbmNyZXRlRWxlbWVudChnZW5FbGVtZW50LGVsZW1lbnQsYXJncyk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbmNyZXRpc2F0aW9ucyA9IHRoaXMuZmFtaXhSZXAuX2dldEFsbEVudGl0aWVzV2l0aFR5cGUoXCJDb25jcmV0aXNhdGlvblwiKSBhcyBTZXQ8RmFtaXguQ29uY3JldGlzYXRpb24+O1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY3JlYXRlQ29uY3JldGlzYXRpb24gOiBib29sZWFuID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uY3JldGlzYXRpb25zLmZvckVhY2goKGNvbmMgOiBGYW1peC5Db25jcmV0aXNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdlbkVsZW1lbnQuZnVsbHlRdWFsaWZpZWROYW1lID09IGNvbmMuZ2VuZXJpY0VudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgJiYgY29uYy5jb25jcmV0ZUVudGl0eS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uY0VsZW1lbnQuZnVsbHlRdWFsaWZpZWROYW1lKXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb25jcmV0aXNhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChjcmVhdGVDb25jcmV0aXNhdGlvbikge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZm14Q29uY3JldGlzYXRpb24gOiBGYW1peC5Db25jcmV0aXNhdGlvbiA9IHRoaXMuY3JlYXRlRmFtaXhDb25jcmV0aXNhdGlvbihjb25jRWxlbWVudCxnZW5FbGVtZW50KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIC8vIFJlbW9udGVyIMOgIGwnw6lsw6ltZW50IHBhcmVudCAodXRpbGUgc2kgbGUgbsWTdWQgZGUgcsOpZsOpcmVuY2UgZXN0IHVuIGVuZmFudClcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudE5vZGUgPSBjdXJyZW50Tm9kZS5nZXRQYXJlbnQoKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvbiBiZXR3ZWVuIGEgY2xhc3MgYW5kIGFuIGludGVyZmFjZVxuICAgICAqIEBwYXJhbSBjbHMgQSBjbGFzc1xuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uSW50ZXJmYWNlQ2xhc3MoY2xzOiBDbGFzc0RlY2xhcmF0aW9uKXtcbiAgICBcbiAgICAgICAgY29uc3Qgc3VwZXJJbnRlcmZhY2VzID0gY2xzLmdldEltcGxlbWVudHMoKTtcbiAgICAgICAgc3VwZXJJbnRlcmZhY2VzLmZvckVhY2goaW50ZXJmYWNlVHlwZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBpbnRlcmZhY2VJc0dlbmVyaWMgPSBpbnRlcmZhY2VUeXBlLmdldFR5cGVBcmd1bWVudHMoKS5sZW5ndGg+MDtcbiAgICAgICAgICAgIGlmIChpbnRlcmZhY2VJc0dlbmVyaWMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBpbnRlcmZhY2VEZWNsYXJhdGlvbiA9IGludGVyZmFjZVR5cGUuZ2V0RXhwcmVzc2lvbigpLmdldFN5bWJvbCgpPy5nZXREZWNsYXJhdGlvbnMoKVswXSBhcyBJbnRlcmZhY2VEZWNsYXJhdGlvbjtcbiAgICAgICAgICAgICAgICBjb25zdCBnZW5QYXJhbXMgPSBpbnRlcmZhY2VEZWNsYXJhdGlvbi5nZXRUeXBlUGFyYW1ldGVycygpLm1hcCgocGFyYW0pID0+IHBhcmFtLmdldFRleHQoKSk7XG4gICAgICAgICAgICAgICAgY29uc3QgY29uUGFyYW1zID0gY2xzLmdldEhlcml0YWdlQ2xhdXNlcygpWzBdLmdldFR5cGVOb2RlcygpWzBdLmdldFR5cGVBcmd1bWVudHMoKS5tYXAoKHBhcmFtKSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSBjbHMuZ2V0SGVyaXRhZ2VDbGF1c2VzKClbMF0uZ2V0VHlwZU5vZGVzKClbMF0uZ2V0VHlwZUFyZ3VtZW50cygpO1xuICAgICAgICAgICAgICAgIGlmICghSGVscGVycy5hcnJheXNBcmVFcXVhbChjb25QYXJhbXMsZ2VuUGFyYW1zKSkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBnZW5JbnRlcmZhY2UgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoaW50ZXJmYWNlRGVjbGFyYXRpb24pIGFzIEZhbWl4LlBhcmFtZXRyaWNJbnRlcmZhY2U7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbkludGVyZmFjZSA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENvbmNyZXRlRWxlbWVudChnZW5JbnRlcmZhY2UsaW50ZXJmYWNlRGVjbGFyYXRpb24sYXJncyk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNvbmNyZXRpc2F0aW9ucyA9IHRoaXMuZmFtaXhSZXAuX2dldEFsbEVudGl0aWVzV2l0aFR5cGUoXCJDb25jcmV0aXNhdGlvblwiKSBhcyBTZXQ8RmFtaXguQ29uY3JldGlzYXRpb24+O1xuICAgICAgICAgICAgICAgICAgICBsZXQgY3JlYXRlQ29uY3JldGlzYXRpb24gOiBib29sZWFuID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgY29uY3JldGlzYXRpb25zLmZvckVhY2goKGNvbmMgOiBGYW1peC5Db25jcmV0aXNhdGlvbikgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGdlbkludGVyZmFjZS5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uYy5nZW5lcmljRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSAmJiBjb25jLmNvbmNyZXRlRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25JbnRlcmZhY2UuZnVsbHlRdWFsaWZpZWROYW1lKXtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjcmVhdGVDb25jcmV0aXNhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIFxuICAgICAgICAgICAgICAgICAgICBpZiAoY3JlYXRlQ29uY3JldGlzYXRpb24pIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGZteENvbmNyZXRpc2F0aW9uIDogRmFtaXguQ29uY3JldGlzYXRpb24gPSB0aGlzLmNyZWF0ZUZhbWl4Q29uY3JldGlzYXRpb24oY29uSW50ZXJmYWNlLGdlbkludGVyZmFjZSk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIENyZWF0ZXMgYSBGYW1peCBjb25jcmV0aXNhdGlvbiBiZXR3ZWVuIGFuIGludGVyZmFjZSBhbmQgYSBUeXBlXG4gICAgICogQHBhcmFtIGVsZW1lbnQgQSB2YXJpYWJsZSBvciBhIGZ1bmN0aW9uXG4gICAgICogQHBhcmFtIGludGVyIEFuIGludGVyZmFjZVxuICAgICAqL1xuICAgIHB1YmxpYyBjcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uVHlwZUluc3RhbmNpYXRpb24oZWxlbWVudDogSW50ZXJmYWNlRGVjbGFyYXRpb24gfCBDbGFzc0RlY2xhcmF0aW9uKXtcblxuICAgICAgICBjb25zdCBpc0dlbmVyaWMgPSBlbGVtZW50LmdldFR5cGVQYXJhbWV0ZXJzKCkubGVuZ3RoID4gMDtcbiAgICAgICAgaWYgKGlzR2VuZXJpYykge1xuICAgICAgICAgICAgY29uc3QgZ2VuUGFyYW1zID0gZWxlbWVudC5nZXRUeXBlUGFyYW1ldGVycygpLm1hcChwYXJhbSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgY29uc3QgdXNlcyA9IGVsZW1lbnQuZmluZFJlZmVyZW5jZXNBc05vZGVzKCk7XG4gICAgICAgICAgICB1c2VzLmZvckVhY2godXNlID0+IHsgICAgICAgIFxuICAgICAgICAgICAgICAgIGxldCBwYXJlbnROb2RlID0gdXNlLmdldFBhcmVudCgpO1xuICAgICAgICAgICAgICAgIHdoaWxlIChwYXJlbnROb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChwYXJlbnROb2RlLmdldEtpbmQoKSA9PT0gU3ludGF4S2luZC5UeXBlUmVmZXJlbmNlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlUmVmZXJlbmNlTm9kZSA9IHBhcmVudE5vZGUuYXNLaW5kKFN5bnRheEtpbmQuVHlwZVJlZmVyZW5jZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoIXR5cGVSZWZlcmVuY2VOb2RlKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBUeXBlUmVmZXJlbmNlTm9kZSBub3QgZm91bmQgZm9yICR7cGFyZW50Tm9kZS5nZXRUZXh0KCl9YCk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCB0eXBlUmVmZXJlbmNlTm9kZUlzR2VuZXJpYyA9IHR5cGVSZWZlcmVuY2VOb2RlLmdldFR5cGVBcmd1bWVudHMoKS5sZW5ndGggPiAwO1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKHR5cGVSZWZlcmVuY2VOb2RlSXNHZW5lcmljKSB7fVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IGFyZ3MgPSB0eXBlUmVmZXJlbmNlTm9kZS5nZXRUeXBlQXJndW1lbnRzKCk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uUGFyYW1zID0gdHlwZVJlZmVyZW5jZU5vZGUuZ2V0VHlwZUFyZ3VtZW50cygpLm1hcChwYXJhbSA9PiBwYXJhbS5nZXRUZXh0KCkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmICghSGVscGVycy5hcnJheXNBcmVFcXVhbChjb25QYXJhbXMsZ2VuUGFyYW1zKSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgZ2VuRWxlbWVudDtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYoZWxlbWVudCBpbnN0YW5jZW9mIENsYXNzRGVjbGFyYXRpb24pe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2VuRWxlbWVudCA9IHRoaXMuY3JlYXRlT3JHZXRGYW1peENsYXNzKGVsZW1lbnQpIGFzIEZhbWl4LlBhcmFtZXRyaWNDbGFzcztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdlbkVsZW1lbnQgPSB0aGlzLmNyZWF0ZU9yR2V0RmFtaXhJbnRlcmZhY2UoZWxlbWVudCkgYXMgRmFtaXguUGFyYW1ldHJpY0ludGVyZmFjZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29uY0VsZW1lbnQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmNFbGVtZW50ID0gdGhpcy5jcmVhdGVPckdldEZhbWl4Q29uY3JldGVFbGVtZW50KGdlbkVsZW1lbnQsZWxlbWVudCxhcmdzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29uY3JldGlzYXRpb25zID0gdGhpcy5mYW1peFJlcC5fZ2V0QWxsRW50aXRpZXNXaXRoVHlwZShcIkNvbmNyZXRpc2F0aW9uXCIpIGFzIFNldDxGYW1peC5Db25jcmV0aXNhdGlvbj47XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCBjcmVhdGVDb25jcmV0aXNhdGlvbiA6IGJvb2xlYW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25jcmV0aXNhdGlvbnMuZm9yRWFjaCgoY29uYyA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2VuRWxlbWVudC5mdWxseVF1YWxpZmllZE5hbWUgPT0gY29uYy5nZW5lcmljRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSAmJiBjb25jLmNvbmNyZXRlRW50aXR5LmZ1bGx5UXVhbGlmaWVkTmFtZSA9PSBjb25jRWxlbWVudC5mdWxseVF1YWxpZmllZE5hbWUpe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNyZWF0ZUNvbmNyZXRpc2F0aW9uID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKGNyZWF0ZUNvbmNyZXRpc2F0aW9uKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBmbXhDb25jcmV0aXNhdGlvbiA6IEZhbWl4LkNvbmNyZXRpc2F0aW9uID0gdGhpcy5jcmVhdGVGYW1peENvbmNyZXRpc2F0aW9uKGNvbmNFbGVtZW50LGdlbkVsZW1lbnQpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgcGFyZW50Tm9kZSA9IHBhcmVudE5vZGUuZ2V0UGFyZW50KCk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBwdWJsaWMgY29udmVydFRvUmVsYXRpdmVQYXRoKGFic29sdXRlUGF0aDogc3RyaW5nLCBhYnNvbHV0ZVBhdGhQcm9qZWN0OiBzdHJpbmcpIHtcbiAgICAgICAgcmV0dXJuIGFic29sdXRlUGF0aC5yZXBsYWNlKGFic29sdXRlUGF0aFByb2plY3QsIFwiXCIpLnNsaWNlKDEpO1xuICAgIH1cbn1cbmZ1bmN0aW9uIGluaXRGUU4oc291cmNlRWxlbWVudDogVFNNb3JwaE9iamVjdFR5cGUsIGZhbWl4RWxlbWVudDogRmFtaXguU291cmNlZEVudGl0eSkge1xuICAgIGlmICghKHNvdXJjZUVsZW1lbnQgaW5zdGFuY2VvZiBDb21tZW50UmFuZ2UpKSB7XG4gICAgICAgIGNvbnN0IGZxbiA9IEZRTkZ1bmN0aW9ucy5nZXRGUU4oc291cmNlRWxlbWVudCk7XG4gICAgICAgIGxvZ2dlci5kZWJ1ZyhcIlNldHRpbmcgZnVsbHkgcXVhbGlmaWVkIG5hbWUgZm9yIFwiICsgZmFtaXhFbGVtZW50LmdldEpTT04oKSArIFwiIHRvIFwiICsgZnFuKTtcbiAgICAgICAgKGZhbWl4RWxlbWVudCBhcyBGYW1peC5OYW1lZEVudGl0eSkuZnVsbHlRdWFsaWZpZWROYW1lID0gZnFuO1xuICAgIH1cbn1cblxuIl19
|