UNPKG

28.1 kBJavaScriptView Raw
1/**
2 * @license
3 * Copyright Google LLC All Rights Reserved.
4 *
5 * Use of this source code is governed by an MIT-style license that can be
6 * found in the LICENSE file at https://angular.io/license
7 */
8(function (factory) {
9 if (typeof module === "object" && typeof module.exports === "object") {
10 var v = factory(require, exports);
11 if (v !== undefined) module.exports = v;
12 }
13 else if (typeof define === "function" && define.amd) {
14 define("@angular/language-service/src/diagnostics", ["require", "exports", "tslib", "path", "typescript", "@angular/language-service/src/diagnostic_messages", "@angular/language-service/src/expression_diagnostics", "@angular/language-service/src/ts_utils", "@angular/language-service/src/utils"], factory);
15 }
16})(function (require, exports) {
17 "use strict";
18 Object.defineProperty(exports, "__esModule", { value: true });
19 exports.ngDiagnosticToTsDiagnostic = exports.getDeclarationDiagnostics = exports.getTemplateDiagnostics = void 0;
20 var tslib_1 = require("tslib");
21 var path = require("path");
22 var ts = require("typescript");
23 var diagnostic_messages_1 = require("@angular/language-service/src/diagnostic_messages");
24 var expression_diagnostics_1 = require("@angular/language-service/src/expression_diagnostics");
25 var ts_utils_1 = require("@angular/language-service/src/ts_utils");
26 var utils_1 = require("@angular/language-service/src/utils");
27 /**
28 * Return diagnostic information for the parsed AST of the template.
29 * @param ast contains HTML and template AST
30 */
31 function getTemplateDiagnostics(ast) {
32 var parseErrors = ast.parseErrors, templateAst = ast.templateAst, htmlAst = ast.htmlAst, template = ast.template;
33 if (parseErrors && parseErrors.length) {
34 return parseErrors.map(function (e) {
35 return {
36 kind: ts.DiagnosticCategory.Error,
37 span: utils_1.offsetSpan(utils_1.spanOf(e.span), template.span.start),
38 message: e.msg,
39 };
40 });
41 }
42 return expression_diagnostics_1.getTemplateExpressionDiagnostics({
43 templateAst: templateAst,
44 htmlAst: htmlAst,
45 offset: template.span.start,
46 query: template.query,
47 members: template.members,
48 source: ast.template.source,
49 });
50 }
51 exports.getTemplateDiagnostics = getTemplateDiagnostics;
52 /**
53 * Performs a variety diagnostics on directive declarations.
54 *
55 * @param declarations Angular directive declarations
56 * @param modules NgModules in the project
57 * @param host TypeScript service host used to perform TypeScript queries
58 * @return diagnosed errors, if any
59 */
60 function getDeclarationDiagnostics(declarations, modules, host) {
61 var e_1, _a, e_2, _b, e_3, _c, e_4, _d;
62 var directives = new Set();
63 try {
64 for (var _e = tslib_1.__values(modules.ngModules), _f = _e.next(); !_f.done; _f = _e.next()) {
65 var ngModule = _f.value;
66 try {
67 for (var _g = (e_2 = void 0, tslib_1.__values(ngModule.declaredDirectives)), _h = _g.next(); !_h.done; _h = _g.next()) {
68 var directive = _h.value;
69 directives.add(directive.reference);
70 }
71 }
72 catch (e_2_1) { e_2 = { error: e_2_1 }; }
73 finally {
74 try {
75 if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
76 }
77 finally { if (e_2) throw e_2.error; }
78 }
79 }
80 }
81 catch (e_1_1) { e_1 = { error: e_1_1 }; }
82 finally {
83 try {
84 if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
85 }
86 finally { if (e_1) throw e_1.error; }
87 }
88 var results = [];
89 try {
90 for (var declarations_1 = tslib_1.__values(declarations), declarations_1_1 = declarations_1.next(); !declarations_1_1.done; declarations_1_1 = declarations_1.next()) {
91 var declaration = declarations_1_1.value;
92 var errors = declaration.errors, metadata = declaration.metadata, type = declaration.type, declarationSpan = declaration.declarationSpan;
93 var sf = host.getSourceFile(type.filePath);
94 if (!sf) {
95 host.error("directive " + type.name + " exists but has no source file");
96 return [];
97 }
98 // TypeScript identifier of the directive declaration annotation (e.g. "Component" or
99 // "Directive") on a directive class.
100 var directiveIdentifier = ts_utils_1.findTightestNode(sf, declarationSpan.start);
101 if (!directiveIdentifier) {
102 host.error("directive " + type.name + " exists but has no identifier");
103 return [];
104 }
105 try {
106 for (var errors_1 = (e_4 = void 0, tslib_1.__values(errors)), errors_1_1 = errors_1.next(); !errors_1_1.done; errors_1_1 = errors_1.next()) {
107 var error = errors_1_1.value;
108 results.push({
109 kind: ts.DiagnosticCategory.Error,
110 message: error.message,
111 span: error.span,
112 });
113 }
114 }
115 catch (e_4_1) { e_4 = { error: e_4_1 }; }
116 finally {
117 try {
118 if (errors_1_1 && !errors_1_1.done && (_d = errors_1.return)) _d.call(errors_1);
119 }
120 finally { if (e_4) throw e_4.error; }
121 }
122 if (!modules.ngModuleByPipeOrDirective.has(declaration.type)) {
123 results.push(diagnostic_messages_1.createDiagnostic(declarationSpan, diagnostic_messages_1.Diagnostic.directive_not_in_module, metadata.isComponent ? 'Component' : 'Directive', type.name));
124 }
125 if (metadata.isComponent) {
126 var _j = metadata.template, template = _j.template, templateUrl = _j.templateUrl, styleUrls = _j.styleUrls;
127 if (template === null && !templateUrl) {
128 results.push(diagnostic_messages_1.createDiagnostic(declarationSpan, diagnostic_messages_1.Diagnostic.missing_template_and_templateurl, type.name));
129 }
130 else if (templateUrl) {
131 if (template) {
132 results.push(diagnostic_messages_1.createDiagnostic(declarationSpan, diagnostic_messages_1.Diagnostic.both_template_and_templateurl, type.name));
133 }
134 // Find templateUrl value from the directive call expression, which is the parent of the
135 // directive identifier.
136 //
137 // TODO: We should create an enum of the various properties a directive can have to use
138 // instead of string literals. We can then perform a mass migration of all literal usages.
139 var templateUrlNode = ts_utils_1.findPropertyValueOfType(directiveIdentifier.parent, 'templateUrl', ts.isLiteralExpression);
140 if (!templateUrlNode) {
141 host.error("templateUrl " + templateUrl + " exists but its TypeScript node doesn't");
142 return [];
143 }
144 results.push.apply(results, tslib_1.__spread(validateUrls([templateUrlNode], host.tsLsHost)));
145 }
146 if (styleUrls.length > 0) {
147 // Find styleUrls value from the directive call expression, which is the parent of the
148 // directive identifier.
149 var styleUrlsNode = ts_utils_1.findPropertyValueOfType(directiveIdentifier.parent, 'styleUrls', ts.isArrayLiteralExpression);
150 if (!styleUrlsNode) {
151 host.error("styleUrls property exists but its TypeScript node doesn't'");
152 return [];
153 }
154 results.push.apply(results, tslib_1.__spread(validateUrls(styleUrlsNode.elements, host.tsLsHost)));
155 }
156 }
157 }
158 }
159 catch (e_3_1) { e_3 = { error: e_3_1 }; }
160 finally {
161 try {
162 if (declarations_1_1 && !declarations_1_1.done && (_c = declarations_1.return)) _c.call(declarations_1);
163 }
164 finally { if (e_3) throw e_3.error; }
165 }
166 return results;
167 }
168 exports.getDeclarationDiagnostics = getDeclarationDiagnostics;
169 /**
170 * Checks that URLs on a directive point to a valid file.
171 * Note that this diagnostic check may require a filesystem hit, and thus may be slower than other
172 * checks.
173 *
174 * @param urls urls to check for validity
175 * @param tsLsHost TS LS host used for querying filesystem information
176 * @return diagnosed url errors, if any
177 */
178 function validateUrls(urls, tsLsHost) {
179 if (!tsLsHost.fileExists) {
180 return [];
181 }
182 var allErrors = [];
183 // TODO(ayazhafiz): most of this logic can be unified with the logic in
184 // definitions.ts#getUrlFromProperty. Create a utility function to be used by both.
185 for (var i = 0; i < urls.length; ++i) {
186 var urlNode = urls[i];
187 if (!ts.isStringLiteralLike(urlNode)) {
188 // If a non-string value is assigned to a URL node (like `templateUrl`), a type error will be
189 // picked up by the TS Language Server.
190 continue;
191 }
192 var curPath = urlNode.getSourceFile().fileName;
193 var url = path.join(path.dirname(curPath), urlNode.text);
194 if (tsLsHost.fileExists(url))
195 continue;
196 // Exclude opening and closing quotes in the url span.
197 var urlSpan = { start: urlNode.getStart() + 1, end: urlNode.end - 1 };
198 allErrors.push(diagnostic_messages_1.createDiagnostic(urlSpan, diagnostic_messages_1.Diagnostic.invalid_templateurl));
199 }
200 return allErrors;
201 }
202 /**
203 * Return a recursive data structure that chains diagnostic messages.
204 * @param chain
205 */
206 function chainDiagnostics(chain) {
207 return {
208 messageText: chain.message,
209 category: ts.DiagnosticCategory.Error,
210 code: 0,
211 next: chain.next ? chain.next.map(chainDiagnostics) : undefined
212 };
213 }
214 /**
215 * Convert ng.Diagnostic to ts.Diagnostic.
216 * @param d diagnostic
217 * @param file
218 */
219 function ngDiagnosticToTsDiagnostic(d, file) {
220 return {
221 file: file,
222 start: d.span.start,
223 length: d.span.end - d.span.start,
224 messageText: typeof d.message === 'string' ? d.message : chainDiagnostics(d.message),
225 category: d.kind,
226 code: 0,
227 source: 'ng',
228 };
229 }
230 exports.ngDiagnosticToTsDiagnostic = ngDiagnosticToTsDiagnostic;
231});
232//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhZ25vc3RpY3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9sYW5ndWFnZS1zZXJ2aWNlL3NyYy9kaWFnbm9zdGljcy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7Ozs7O0lBR0gsMkJBQTZCO0lBQzdCLCtCQUFpQztJQUVqQyx5RkFBbUU7SUFDbkUsK0ZBQTBFO0lBQzFFLG1FQUFxRTtJQUdyRSw2REFBMkM7SUFFM0M7OztPQUdHO0lBQ0gsU0FBZ0Isc0JBQXNCLENBQUMsR0FBaUI7UUFDL0MsSUFBQSxXQUFXLEdBQW9DLEdBQUcsWUFBdkMsRUFBRSxXQUFXLEdBQXVCLEdBQUcsWUFBMUIsRUFBRSxPQUFPLEdBQWMsR0FBRyxRQUFqQixFQUFFLFFBQVEsR0FBSSxHQUFHLFNBQVAsQ0FBUTtRQUMxRCxJQUFJLFdBQVcsSUFBSSxXQUFXLENBQUMsTUFBTSxFQUFFO1lBQ3JDLE9BQU8sV0FBVyxDQUFDLEdBQUcsQ0FBQyxVQUFBLENBQUM7Z0JBQ3RCLE9BQU87b0JBQ0wsSUFBSSxFQUFFLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLO29CQUNqQyxJQUFJLEVBQUUsa0JBQVUsQ0FBQyxjQUFNLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO29CQUNyRCxPQUFPLEVBQUUsQ0FBQyxDQUFDLEdBQUc7aUJBQ2YsQ0FBQztZQUNKLENBQUMsQ0FBQyxDQUFDO1NBQ0o7UUFDRCxPQUFPLHlEQUFnQyxDQUFDO1lBQ3RDLFdBQVcsRUFBRSxXQUFXO1lBQ3hCLE9BQU8sRUFBRSxPQUFPO1lBQ2hCLE1BQU0sRUFBRSxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUs7WUFDM0IsS0FBSyxFQUFFLFFBQVEsQ0FBQyxLQUFLO1lBQ3JCLE9BQU8sRUFBRSxRQUFRLENBQUMsT0FBTztZQUN6QixNQUFNLEVBQUUsR0FB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UyxDQUFDO0lBQ25CLENBQUM7SUFFRDs7O09BR0c7SUFDSCxTQUFTLGdCQUFnQixDQUFDLEtBQWdDO1FBQ3hELE9BQU87WUFDTCxXQUFXLEVBQUUsS0FBSyxDQUFDLE9BQU87WUFDMUIsUUFBUSxFQUFFLEVBQUUsQ0FBQyxrQkFBa0IsQ0FBQyxLQUFLO1lBQ3JDLElBQUksRUFBRSxDQUFDO1lBQ1AsSUFBSSxFQUFFLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVM7U0FDaEUsQ0FBQztJQUNKLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsU0FBZ0IsMEJBQTBCLENBQ3RDLENBQWdCLEVBQUUsSUFBNkI7UUFDakQsT0FBTztZQUNMLElBQUksTUFBQTtZQUNKLEtBQUssRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUs7WUFDbkIsTUFBTSxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSztZQUNqQyxXQUFXLEVBQUUsT0FBTyxDQUFDLENBQUMsT0FBTyxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUNwRixRQUFRLEVBQUUsQ0FBQyxDQUFDLElBQUk7WUFDaEIsSUFBSSxFQUFFLENBQUM7WUFDUCxNQUFNLEVBQUUsSUFBSTtTQUNiLENBQUM7SUFDSixDQUFDO0lBWEQsZ0VBV0MiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtOZ0FuYWx5emVkTW9kdWxlc30gZnJvbSAnQGFuZ3VsYXIvY29tcGlsZXInO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCAqIGFzIHRzIGZyb20gJ3R5cGVzY3JpcHQnO1xuXG5pbXBvcnQge2NyZWF0ZURpYWdub3N0aWMsIERpYWdub3N0aWN9IGZyb20gJy4vZGlhZ25vc3RpY19tZXNzYWdlcyc7XG5pbXBvcnQge2dldFRlbXBsYXRlRXhwcmVzc2lvbkRpYWdub3N0aWNzfSBmcm9tICcuL2V4cHJlc3Npb25fZGlhZ25vc3RpY3MnO1xuaW1wb3J0IHtmaW5kUHJvcGVydHlWYWx1ZU9mVHlwZSwgZmluZFRpZ2h0ZXN0Tm9kZX0gZnJvbSAnLi90c191dGlscyc7XG5pbXBvcnQgKiBhcyBuZyBmcm9tICcuL3R5cGVzJztcbmltcG9ydCB7VHlwZVNjcmlwdFNlcnZpY2VIb3N0fSBmcm9tICcuL3R5cGVzY3JpcHRfaG9zdCc7XG5pbXBvcnQge29mZnNldFNwYW4sIHNwYW5PZn0gZnJvbSAnLi91dGlscyc7XG5cbi8qKlxuICogUmV0dXJuIGRpYWdub3N0aWMgaW5mb3JtYXRpb24gZm9yIHRoZSBwYXJzZWQgQVNUIG9mIHRoZSB0ZW1wbGF0ZS5cbiAqIEBwYXJhbSBhc3QgY29udGFpbnMgSFRNTCBhbmQgdGVtcGxhdGUgQVNUXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUZW1wbGF0ZURpYWdub3N0aWNzKGFzdDogbmcuQXN0UmVzdWx0KTogbmcuRGlhZ25vc3RpY1tdIHtcbiAgY29uc3Qge3BhcnNlRXJyb3JzLCB0ZW1wbGF0ZUFzdCwgaHRtbEFzdCwgdGVtcGxhdGV9ID0gYXN0O1xuICBpZiAocGFyc2VFcnJvcnMgJiYgcGFyc2VFcnJvcnMubGVuZ3RoKSB7XG4gICAgcmV0dXJuIHBhcnNlRXJyb3JzLm1hcChlID0+IHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIGtpbmQ6IHRzLkRpYWdub3N0aWNDYXRlZ29yeS5FcnJvcixcbiAgICAgICAgc3Bhbjogb2Zmc2V0U3BhbihzcGFuT2YoZS5zcGFuKSwgdGVtcGxhdGUuc3Bhbi5zdGFydCksXG4gICAgICAgIG1lc3NhZ2U6IGUubXNnLFxuICAgICAgfTtcbiAgICB9KTtcbiAgfVxuICByZXR1cm4gZ2V0VGVtcGxhdGVFeHByZXNzaW9uRGlhZ25vc3RpY3Moe1xuICAgIHRlbXBsYXRlQXN0OiB0ZW1wbGF0ZUFzdCxcbiAgICBodG1sQXN0OiBodG1sQXN0LFxuICAgIG9mZnNldDogdGVtcGxhdGUuc3Bhbi5zdGFydCxcbiAgICBxdWVyeTogdGVtcGxhdGUucXVlcnksXG4gICAgbWVtYmVyczogdGVtcGxhdGUubWVtYmVycyxcbiAgICBzb3VyY2U6IGFzdC50ZW1wbGF0ZS5zb3VyY2UsXG4gIH0pO1xufVxuXG4vKipcbiAqIFBlcmZvcm1zIGEgdmFyaWV0eSBkaWFnbm9zdGljcyBvbiBkaXJlY3RpdmUgZGVjbGFyYXRpb25zLlxuICpcbiAqIEBwYXJhbSBkZWNsYXJhdGlvbnMgQW5ndWxhciBkaXJlY3RpdmUgZGVjbGFyYXRpb25zXG4gKiBAcGFyYW0gbW9kdWxlcyBOZ01vZHVsZXMgaW4gdGhlIHByb2plY3RcbiAqIEBwYXJhbSBob3N0IFR5cGVTY3JpcHQgc2VydmljZSBob3N0IHVzZWQgdG8gcGVyZm9ybSBUeXBlU2NyaXB0IHF1ZXJpZXNcbiAqIEByZXR1cm4gZGlhZ25vc2VkIGVycm9ycywgaWYgYW55XG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXREZWNsYXJhdGlvbkRpYWdub3N0aWNzKFxuICAgIGRlY2xhcmF0aW9uczogbmcuRGVjbGFyYXRpb25bXSwgbW9kdWxlczogTmdBbmFseXplZE1vZHVsZXMsXG4gICAgaG9zdDogUmVhZG9ubHk8VHlwZVNjcmlwdFNlcnZpY2VIb3N0Pik6IG5nLkRpYWdub3N0aWNbXSB7XG4gIGNvbnN0IGRpcmVjdGl2ZXMgPSBuZXcgU2V0PG5nLlN0YXRpY1N5bWJvbD4oKTtcbiAgZm9yIChjb25zdCBuZ01vZHVsZSBvZiBtb2R1bGVzLm5nTW9kdWxlcykge1xuICAgIGZvciAoY29uc3QgZGlyZWN0aXZlIG9mIG5nTW9kdWxlLmRlY2xhcmVkRGlyZWN0aXZlcykge1xuICAgICAgZGlyZWN0aXZlcy5hZGQoZGlyZWN0aXZlLnJlZmVyZW5jZSk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcmVzdWx0czogbmcuRGlhZ25vc3RpY1tdID0gW107XG5cbiAgZm9yIChjb25zdCBkZWNsYXJhdGlvbiBvZiBkZWNsYXJhdGlvbnMpIHtcbiAgICBjb25zdCB7ZXJyb3JzLCBtZXRhZGF0YSwgdHlwZSwgZGVjbGFyYXRpb25TcGFufSA9IGRlY2xhcmF0aW9uO1xuXG4gICAgY29uc3Qgc2YgPSBob3N0LmdldFNvdXJjZUZpbGUodHlwZS5maWxlUGF0aCk7XG4gICAgaWYgKCFzZikge1xuICAgICAgaG9zdC5lcnJvcihgZGlyZWN0aXZlICR7dHlwZS5uYW1lfSBleGlzdHMgYnV0IGhhcyBubyBzb3VyY2UgZmlsZWApO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICAvLyBUeXBlU2NyaXB0IGlkZW50aWZpZXIgb2YgdGhlIGRpcmVjdGl2ZSBkZWNsYXJhdGlvbiBhbm5vdGF0aW9uIChlLmcuIFwiQ29tcG9uZW50XCIgb3JcbiAgICAvLyBcIkRpcmVjdGl2ZVwiKSBvbiBhIGRpcmVjdGl2ZSBjbGFzcy5cbiAgICBjb25zdCBkaXJlY3RpdmVJZGVudGlmaWVyID0gZmluZFRpZ2h0ZXN0Tm9kZShzZiwgZGVjbGFyYXRpb25TcGFuLnN0YXJ0KTtcbiAgICBpZiAoIWRpcmVjdGl2ZUlkZW50aWZpZXIpIHtcbiAgICAgIGhvc3QuZXJyb3IoYGRpcmVjdGl2ZSAke3R5cGUubmFtZX0gZXhpc3RzIGJ1dCBoYXMgbm8gaWRlbnRpZmllcmApO1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cblxuICAgIGZvciAoY29uc3QgZXJyb3Igb2YgZXJyb3JzKSB7XG4gICAgICByZXN1bHRzLnB1c2goe1xuICAgICAgICBraW5kOiB0cy5EaWFnbm9zdGljQ2F0ZWdvcnkuRXJyb3IsXG4gICAgICAgIG1lc3NhZ2U6IGVycm9yLm1lc3NhZ2UsXG4gICAgICAgIHNwYW46IGVycm9yLnNwYW4sXG4gICAgICB9KTtcbiAgICB9XG5cbiAgICBpZiAoIW1vZHVsZXMubmdNb2R1bGVCeVBpcGVPckRpcmVjdGl2ZS5oYXMoZGVjbGFyYXRpb24udHlwZSkpIHtcbiAgICAgIHJlc3VsdHMucHVzaChjcmVhdGVEaWFnbm9zdGljKFxuICAgICAgICAgIGRlY2xhcmF0aW9uU3BhbiwgRGlhZ25vc3RpYy5kaXJlY3RpdmVfbm90X2luX21vZHVsZSxcbiAgICAgICAgICBtZXRhZGF0YS5pc0NvbXBvbmVudCA/ICdDb21wb25lbnQnIDogJ0RpcmVjdGl2ZScsIHR5cGUubmFtZSkpO1xuICAgIH1cblxuICAgIGlmIChtZXRhZGF0YS5pc0NvbXBvbmVudCkge1xuICAgICAgY29uc3Qge3RlbXBsYXRlLCB0ZW1wbGF0ZVVybCwgc3R5bGVVcmxzfSA9IG1ldGFkYXRhLnRlbXBsYXRlICE7XG4gICAgICBpZiAodGVtcGxhdGUgPT09IG51bGwgJiYgIXRlbXBsYXRlVXJsKSB7XG4gICAgICAgIHJlc3VsdHMucHVzaChjcmVhdGVEaWFnbm9zdGljKFxuICAgICAgICAgICAgZGVjbGFyYXRpb25TcGFuLCBEaWFnbm9zdGljLm1pc3NpbmdfdGVtcGxhdGVfYW5kX3RlbXBsYXRldXJsLCB0eXBlLm5hbWUpKTtcbiAgICAgIH0gZWxzZSBpZiAodGVtcGxhdGVVcmwpIHtcbiAgICAgICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKGNyZWF0ZURpYWdub3N0aWMoXG4gICAgICAgICAgICAgIGRlY2xhcmF0aW9uU3BhbiwgRGlhZ25vc3RpYy5ib3RoX3RlbXBsYXRlX2FuZF90ZW1wbGF0ZXVybCwgdHlwZS5uYW1lKSk7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBGaW5kIHRlbXBsYXRlVXJsIHZhbHVlIGZyb20gdGhlIGRpcmVjdGl2ZSBjYWxsIGV4cHJlc3Npb24sIHdoaWNoIGlzIHRoZSBwYXJlbnQgb2YgdGhlXG4gICAgICAgIC8vIGRpcmVjdGl2ZSBpZGVudGlmaWVyLlxuICAgICAgICAvL1xuICAgICAgICAvLyBUT0RPOiBXZSBzaG91bGQgY3JlYXRlIGFuIGVudW0gb2YgdGhlIHZhcmlvdXMgcHJvcGVydGllcyBhIGRpcmVjdGl2ZSBjYW4gaGF2ZSB0byB1c2VcbiAgICAgICAgLy8gaW5zdGVhZCBvZiBzdHJpbmcgbGl0ZXJhbHMuIFdlIGNhbiB0aGVuIHBlcmZvcm0gYSBtYXNzIG1pZ3JhdGlvbiBvZiBhbGwgbGl0ZXJhbCB1c2FnZXMuXG4gICAgICAgIGNvbnN0IHRlbXBsYXRlVXJsTm9kZSA9IGZpbmRQcm9wZXJ0eVZhbHVlT2ZUeXBlKFxuICAgICAgICAgICAgZGlyZWN0aXZlSWRlbnRpZmllci5wYXJlbnQsICd0ZW1wbGF0ZVVybCcsIHRzLmlzTGl0ZXJhbEV4cHJlc3Npb24pO1xuICAgICAgICBpZiAoIXRlbXBsYXRlVXJsTm9kZSkge1xuICAgICAgICAgIGhvc3QuZXJyb3IoYHRlbXBsYXRlVXJsICR7dGVtcGxhdGVVcmx9IGV4aXN0cyBidXQgaXRzIFR5cGVTY3JpcHQgbm9kZSBkb2Vzbid0YCk7XG4gICAgICAgICAgcmV0dXJuIFtdO1xuICAgICAgICB9XG5cbiAgICAgICAgcmVzdWx0cy5wdXNoKC4uLnZhbGlkYXRlVXJscyhbdGVtcGxhdGVVcmxOb2RlXSwgaG9zdC50c0xzSG9zdCkpO1xuICAgICAgfVxuXG4gICAgICBpZiAoc3R5bGVVcmxzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgLy8gRmluZCBzdHlsZVVybHMgdmFsdWUgZnJvbSB0aGUgZGlyZWN0aXZlIGNhbGwgZXhwcmVzc2lvbiwgd2hpY2ggaXMgdGhlIHBhcmVudCBvZiB0aGVcbiAgICAgICAgLy8gZGlyZWN0aXZlIGlkZW50aWZpZXIuXG4gICAgICAgIGNvbnN0IHN0eWxlVXJsc05vZGUgPSBmaW5kUHJvcGVydHlWYWx1ZU9mVHlwZShcbiAgICAgICAgICAgIGRpcmVjdGl2ZUlkZW50aWZpZXIucGFyZW50LCAnc3R5bGVVcmxzJywgdHMuaXNBcnJheUxpdGVyYWxFeHByZXNzaW9uKTtcbiAgICAgICAgaWYgKCFzdHlsZVVybHNOb2RlKSB7XG4gICAgICAgICAgaG9zdC5lcnJvcihgc3R5bGVVcmxzIHByb3BlcnR5IGV4aXN0cyBidXQgaXRzIFR5cGVTY3JpcHQgbm9kZSBkb2Vzbid0J2ApO1xuICAgICAgICAgIHJldHVybiBbXTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3VsdHMucHVzaCguLi52YWxpZGF0ZVVybHMoc3R5bGVVcmxzTm9kZS5lbGVtZW50cywgaG9zdC50c0xzSG9zdCkpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiByZXN1bHRzO1xufVxuXG4vKipcbiAqIENoZWNrcyB0aGF0IFVSTHMgb24gYSBkaXJlY3RpdmUgcG9pbnQgdG8gYSB2YWxpZCBmaWxlLlxuICogTm90ZSB0aGF0IHRoaXMgZGlhZ25vc3RpYyBjaGVjayBtYXkgcmVxdWlyZSBhIGZpbGVzeXN0ZW0gaGl0LCBhbmQgdGh1cyBtYXkgYmUgc2xvd2VyIHRoYW4gb3RoZXJcbiAqIGNoZWNrcy5cbiAqXG4gKiBAcGFyYW0gdXJscyB1cmxzIHRvIGNoZWNrIGZvciB2YWxpZGl0eVxuICogQHBhcmFtIHRzTHNIb3N0IFRTIExTIGhvc3QgdXNlZCBmb3IgcXVlcnlpbmcgZmlsZXN5c3RlbSBpbmZvcm1hdGlvblxuICogQHJldHVybiBkaWFnbm9zZWQgdXJsIGVycm9ycywgaWYgYW55XG4gKi9cbmZ1bmN0aW9uIHZhbGlkYXRlVXJscyhcbiAgICB1cmxzOiBBcnJheUxpa2U8dHMuRXhwcmVzc2lvbj4sIHRzTHNIb3N0OiBSZWFkb25seTx0cy5MYW5ndWFnZVNlcnZpY2VIb3N0Pik6IG5nLkRpYWdub3N0aWNbXSB7XG4gIGlmICghdHNMc0hvc3QuZmlsZUV4aXN0cykge1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IGFsbEVycm9yczogbmcuRGlhZ25vc3RpY1tdID0gW107XG4gIC8vIFRPRE8oYXlhemhhZml6KTogbW9zdCBvZiB0aGlzIGxvZ2ljIGNhbiBiZSB1bmlmaWVkIHdpdGggdGhlIGxvZ2ljIGluXG4gIC8vIGRlZmluaXRpb25zLnRzI2dldFVybEZyb21Qcm9wZXJ0eS4gQ3JlYXRlIGEgdXRpbGl0eSBmdW5jdGlvbiB0byBiZSB1c2VkIGJ5IGJvdGguXG4gIGZvciAobGV0IGkgPSAwOyBpIDwgdXJscy5sZW5ndGg7ICsraSkge1xuICAgIGNvbnN0IHVybE5vZGUgPSB1cmxzW2ldO1xuICAgIGlmICghdHMuaXNTdHJpbmdMaXRlcmFsTGlrZSh1cmxOb2RlKSkge1xuICAgICAgLy8gSWYgYSBub24tc3RyaW5nIHZhbHVlIGlzIGFzc2lnbmVkIHRvIGEgVVJMIG5vZGUgKGxpa2UgYHRlbXBsYXRlVXJsYCksIGEgdHlwZSBlcnJvciB3aWxsIGJlXG4gICAgICAvLyBwaWNrZWQgdXAgYnkgdGhlIFRTIExhbmd1YWdlIFNlcnZlci5cbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBjb25zdCBjdXJQYXRoID0gdXJsTm9kZS5nZXRTb3VyY2VGaWxlKCkuZmlsZU5hbWU7XG4gICAgY29uc3QgdXJsID0gcGF0aC5qb2luKHBhdGguZGlybmFtZShjdXJQYXRoKSwgdXJsTm9kZS50ZXh0KTtcbiAgICBpZiAodHNMc0hvc3QuZmlsZUV4aXN0cyh1cmwpKSBjb250aW51ZTtcblxuICAgIC8vIEV4Y2x1ZGUgb3BlbmluZyBhbmQgY2xvc2luZyBxdW90ZXMgaW4gdGhlIHVybCBzcGFuLlxuICAgIGNvbnN0IHVybFNwYW4gPSB7c3RhcnQ6IHVybE5vZGUuZ2V0U3RhcnQoKSArIDEsIGVuZDogdXJsTm9kZS5lbmQgLSAxfTtcbiAgICBhbGxFcnJvcnMucHVzaChjcmVhdGVEaWFnbm9zdGljKHVybFNwYW4sIERpYWdub3N0aWMuaW52YWxpZF90ZW1wbGF0ZXVybCkpO1xuICB9XG4gIHJldHVybiBhbGxFcnJvcnM7XG59XG5cbi8qKlxuICogUmV0dXJuIGEgcmVjdXJzaXZlIGRhdGEgc3RydWN0dXJlIHRoYXQgY2hhaW5zIGRpYWdub3N0aWMgbWVzc2FnZXMuXG4gKiBAcGFyYW0gY2hhaW5cbiAqL1xuZnVuY3Rpb24gY2hhaW5EaWFnbm9zdGljcyhjaGFpbjogbmcuRGlhZ25vc3RpY01lc3NhZ2VDaGFpbik6IHRzLkRpYWdub3N0aWNNZXNzYWdlQ2hhaW4ge1xuICByZXR1cm4ge1xuICAgIG1lc3NhZ2VUZXh0OiBjaGFpbi5tZXNzYWdlLFxuICAgIGNhdGVnb3J5OiB0cy5EaWFnbm9zdGljQ2F0ZWdvcnkuRXJyb3IsXG4gICAgY29kZTogMCxcbiAgICBuZXh0OiBjaGFpbi5uZXh0ID8gY2hhaW4ubmV4dC5tYXAoY2hhaW5EaWFnbm9zdGljcykgOiB1bmRlZmluZWRcbiAgfTtcbn1cblxuLyoqXG4gKiBDb252ZXJ0IG5nLkRpYWdub3N0aWMgdG8gdHMuRGlhZ25vc3RpYy5cbiAqIEBwYXJhbSBkIGRpYWdub3N0aWNcbiAqIEBwYXJhbSBmaWxlXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBuZ0RpYWdub3N0aWNUb1RzRGlhZ25vc3RpYyhcbiAgICBkOiBuZy5EaWFnbm9zdGljLCBmaWxlOiB0cy5Tb3VyY2VGaWxlfHVuZGVmaW5lZCk6IHRzLkRpYWdub3N0aWMge1xuICByZXR1cm4ge1xuICAgIGZpbGUsXG4gICAgc3RhcnQ6IGQuc3Bhbi5zdGFydCxcbiAgICBsZW5ndGg6IGQuc3Bhbi5lbmQgLSBkLnNwYW4uc3RhcnQsXG4gICAgbWVzc2FnZVRleHQ6IHR5cGVvZiBkLm1lc3NhZ2UgPT09ICdzdHJpbmcnID8gZC5tZXNzYWdlIDogY2hhaW5EaWFnbm9zdGljcyhkLm1lc3NhZ2UpLFxuICAgIGNhdGVnb3J5OiBkLmtpbmQsXG4gICAgY29kZTogMCxcbiAgICBzb3VyY2U6ICduZycsXG4gIH07XG59XG4iXX0=
\No newline at end of file