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/typescript_host", ["require", "exports", "tslib", "@angular/compiler", "@angular/core", "path", "typescript/lib/tsserverlibrary", "@angular/language-service/src/language_service", "@angular/language-service/src/reflector_host", "@angular/language-service/src/template", "@angular/language-service/src/ts_utils"], factory);
|
15 | }
|
16 | })(function (require, exports) {
|
17 | ;
|
18 | Object.defineProperty(exports, "__esModule", { value: true });
|
19 | exports.TypeScriptServiceHost = exports.DummyResourceLoader = exports.DummyHtmlParser = exports.createLanguageServiceFromTypescript = void 0;
|
20 | var tslib_1 = require("tslib");
|
21 | var compiler_1 = require("@angular/compiler");
|
22 | var core_1 = require("@angular/core");
|
23 | var path = require("path");
|
24 | var tss = require("typescript/lib/tsserverlibrary");
|
25 | var language_service_1 = require("@angular/language-service/src/language_service");
|
26 | var reflector_host_1 = require("@angular/language-service/src/reflector_host");
|
27 | var template_1 = require("@angular/language-service/src/template");
|
28 | var ts_utils_1 = require("@angular/language-service/src/ts_utils");
|
29 | /**
|
30 | * Create a `LanguageServiceHost`
|
31 | */
|
32 | function createLanguageServiceFromTypescript(host, service) {
|
33 | var ngHost = new TypeScriptServiceHost(host, service);
|
34 | var ngServer = language_service_1.createLanguageService(ngHost);
|
35 | return ngServer;
|
36 | }
|
37 | exports.createLanguageServiceFromTypescript = createLanguageServiceFromTypescript;
|
38 | /**
|
39 | * The language service never needs the normalized versions of the metadata. To avoid parsing
|
40 | * the content and resolving references, return an empty file. This also allows normalizing
|
41 | * template that are syntatically incorrect which is required to provide completions in
|
42 | * syntactically incorrect templates.
|
43 | */
|
44 | var DummyHtmlParser = /** @class */ (function (_super) {
|
45 | tslib_1.__extends(DummyHtmlParser, _super);
|
46 | function DummyHtmlParser() {
|
47 | return _super !== null && _super.apply(this, arguments) || this;
|
48 | }
|
49 | DummyHtmlParser.prototype.parse = function () {
|
50 | return new compiler_1.ParseTreeResult([], []);
|
51 | };
|
52 | return DummyHtmlParser;
|
53 | }(compiler_1.HtmlParser));
|
54 | exports.DummyHtmlParser = DummyHtmlParser;
|
55 | /**
|
56 | * Avoid loading resources in the language servcie by using a dummy loader.
|
57 | */
|
58 | var DummyResourceLoader = /** @class */ (function (_super) {
|
59 | tslib_1.__extends(DummyResourceLoader, _super);
|
60 | function DummyResourceLoader() {
|
61 | return _super !== null && _super.apply(this, arguments) || this;
|
62 | }
|
63 | DummyResourceLoader.prototype.get = function (_url) {
|
64 | return Promise.resolve('');
|
65 | };
|
66 | return DummyResourceLoader;
|
67 | }(compiler_1.ResourceLoader));
|
68 | exports.DummyResourceLoader = DummyResourceLoader;
|
69 | /**
|
70 | * An implementation of a `LanguageServiceHost` for a TypeScript project.
|
71 | *
|
72 | * The `TypeScriptServiceHost` implements the Angular `LanguageServiceHost` using
|
73 | * the TypeScript language services.
|
74 | *
|
75 | * @publicApi
|
76 | */
|
77 | var TypeScriptServiceHost = /** @class */ (function () {
|
78 | function TypeScriptServiceHost(tsLsHost, tsLS) {
|
79 | var _this = this;
|
80 | this.tsLsHost = tsLsHost;
|
81 | this.tsLS = tsLS;
|
82 | this.staticSymbolCache = new compiler_1.StaticSymbolCache();
|
83 | this.fileToComponent = new Map();
|
84 | this.collectedErrors = new Map();
|
85 | this.fileVersions = new Map();
|
86 | this.lastProgram = undefined;
|
87 | this.analyzedModules = {
|
88 | files: [],
|
89 | ngModuleByPipeOrDirective: new Map(),
|
90 | ngModules: [],
|
91 | };
|
92 | this.summaryResolver = new compiler_1.AotSummaryResolver({
|
93 | loadSummary: function (_filePath) {
|
94 | return null;
|
95 | },
|
96 | isSourceFile: function (_sourceFilePath) {
|
97 | return true;
|
98 | },
|
99 | toSummaryFileName: function (sourceFilePath) {
|
100 | return sourceFilePath;
|
101 | },
|
102 | fromSummaryFileName: function (filePath) {
|
103 | return filePath;
|
104 | },
|
105 | }, this.staticSymbolCache);
|
106 | this.reflectorHost = new reflector_host_1.ReflectorHost(function () { return _this.program; }, tsLsHost);
|
107 | this.staticSymbolResolver = new compiler_1.StaticSymbolResolver(this.reflectorHost, this.staticSymbolCache, this.summaryResolver, function (e, filePath) { return _this.collectError(e, filePath); });
|
108 | this.urlResolver = {
|
109 | resolve: function (baseUrl, url) {
|
110 | // In practice, `directoryExists` is always defined.
|
111 | // https://github.com/microsoft/TypeScript/blob/0b6c9254a850dd07056259d4eefca7721745af75/src/server/project.ts#L1608-L1614
|
112 | if (tsLsHost.directoryExists(baseUrl)) {
|
113 | return path.resolve(baseUrl, url);
|
114 | }
|
115 | return path.resolve(path.dirname(baseUrl), url);
|
116 | }
|
117 | };
|
118 | }
|
119 | Object.defineProperty(TypeScriptServiceHost.prototype, "resolver", {
|
120 | /**
|
121 | * Return the singleton instance of the MetadataResolver.
|
122 | */
|
123 | get: function () {
|
124 | var _this = this;
|
125 | if (this._resolver) {
|
126 | return this._resolver;
|
127 | }
|
128 | // StaticReflector keeps its own private caches that are not clearable.
|
129 | // We have no choice but to create a new instance to invalidate the caches.
|
130 | // TODO: Revisit this when language service gets rewritten for Ivy.
|
131 | var staticReflector = new compiler_1.StaticReflector(this.summaryResolver, this.staticSymbolResolver, [], // knownMetadataClasses
|
132 | [], // knownMetadataFunctions
|
133 | function (e, filePath) { return _this.collectError(e, filePath); });
|
134 | // Because static reflector above is changed, we need to create a new
|
135 | // resolver.
|
136 | var moduleResolver = new compiler_1.NgModuleResolver(staticReflector);
|
137 | var directiveResolver = new compiler_1.DirectiveResolver(staticReflector);
|
138 | var pipeResolver = new compiler_1.PipeResolver(staticReflector);
|
139 | var elementSchemaRegistry = new compiler_1.DomElementSchemaRegistry();
|
140 | var resourceLoader = new DummyResourceLoader();
|
141 | var htmlParser = new DummyHtmlParser();
|
142 | // This tracks the CompileConfig in codegen.ts. Currently these options
|
143 | // are hard-coded.
|
144 | var config = new compiler_1.CompilerConfig({
|
145 | defaultEncapsulation: core_1.ViewEncapsulation.Emulated,
|
146 | useJit: false,
|
147 | });
|
148 | var directiveNormalizer = new compiler_1.DirectiveNormalizer(resourceLoader, this.urlResolver, htmlParser, config);
|
149 | this._resolver = new compiler_1.CompileMetadataResolver(config, htmlParser, moduleResolver, directiveResolver, pipeResolver, new compiler_1.JitSummaryResolver(), elementSchemaRegistry, directiveNormalizer, new core_1.ɵConsole(), this.staticSymbolCache, staticReflector, function (error, type) { return _this.collectError(error, type && type.filePath); });
|
150 | return this._resolver;
|
151 | },
|
152 | enumerable: false,
|
153 | configurable: true
|
154 | });
|
155 | Object.defineProperty(TypeScriptServiceHost.prototype, "reflector", {
|
156 | /**
|
157 | * Return the singleton instance of the StaticReflector hosted in the
|
158 | * MetadataResolver.
|
159 | */
|
160 | get: function () {
|
161 | return this.resolver.getReflector();
|
162 | },
|
163 | enumerable: false,
|
164 | configurable: true
|
165 | });
|
166 | /**
|
167 | * Return all known external templates.
|
168 | */
|
169 | TypeScriptServiceHost.prototype.getExternalTemplates = function () {
|
170 | return tslib_1.__spread(this.fileToComponent.keys());
|
171 | };
|
172 | /**
|
173 | * Checks whether the program has changed and returns all analyzed modules.
|
174 | * If program has changed, invalidate all caches and update fileToComponent
|
175 | * and templateReferences.
|
176 | * In addition to returning information about NgModules, this method plays the
|
177 | * same role as 'synchronizeHostData' in tsserver.
|
178 | */
|
179 | TypeScriptServiceHost.prototype.getAnalyzedModules = function () {
|
180 | var e_1, _a, e_2, _b;
|
181 | if (this.upToDate()) {
|
182 | return this.analyzedModules;
|
183 | }
|
184 | // Invalidate caches
|
185 | this.fileToComponent.clear();
|
186 | this.collectedErrors.clear();
|
187 | this.resolver.clearCache();
|
188 | var analyzeHost = {
|
189 | isSourceFile: function (_filePath) {
|
190 | return true;
|
191 | }
|
192 | };
|
193 | var programFiles = this.program.getSourceFiles().map(function (sf) { return sf.fileName; });
|
194 | try {
|
195 | this.analyzedModules =
|
196 | compiler_1.analyzeNgModules(programFiles, analyzeHost, this.staticSymbolResolver, this.resolver);
|
197 | }
|
198 | catch (e) {
|
199 | // Analyzing modules may throw; in that case, reuse the old modules.
|
200 | this.error("Analyzing NgModules failed. " + e);
|
201 | return this.analyzedModules;
|
202 | }
|
203 | try {
|
204 | // update template references and fileToComponent
|
205 | for (var _c = tslib_1.__values(this.analyzedModules.ngModules), _d = _c.next(); !_d.done; _d = _c.next()) {
|
206 | var ngModule = _d.value;
|
207 | try {
|
208 | for (var _e = (e_2 = void 0, tslib_1.__values(ngModule.declaredDirectives)), _f = _e.next(); !_f.done; _f = _e.next()) {
|
209 | var directive = _f.value;
|
210 | var metadata = this.resolver.getNonNormalizedDirectiveMetadata(directive.reference).metadata;
|
211 | if (metadata.isComponent && metadata.template && metadata.template.templateUrl) {
|
212 | var templateName = this.urlResolver.resolve(this.reflector.componentModuleUrl(directive.reference), metadata.template.templateUrl);
|
213 | this.fileToComponent.set(templateName, directive.reference);
|
214 | }
|
215 | }
|
216 | }
|
217 | catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
218 | finally {
|
219 | try {
|
220 | if (_f && !_f.done && (_b = _e.return)) _b.call(_e);
|
221 | }
|
222 | finally { if (e_2) throw e_2.error; }
|
223 | }
|
224 | }
|
225 | }
|
226 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
227 | finally {
|
228 | try {
|
229 | if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
230 | }
|
231 | finally { if (e_1) throw e_1.error; }
|
232 | }
|
233 | return this.analyzedModules;
|
234 | };
|
235 | /**
|
236 | * Checks whether the program has changed, and invalidate static symbols in
|
237 | * the source files that have changed.
|
238 | * Returns true if modules are up-to-date, false otherwise.
|
239 | * This should only be called by getAnalyzedModules().
|
240 | */
|
241 | TypeScriptServiceHost.prototype.upToDate = function () {
|
242 | var e_3, _a, e_4, _b, e_5, _c;
|
243 | var _d = this, lastProgram = _d.lastProgram, program = _d.program;
|
244 | if (lastProgram === program) {
|
245 | return true;
|
246 | }
|
247 | this.lastProgram = program;
|
248 | // Even though the program has changed, it could be the case that none of
|
249 | // the source files have changed. If all source files remain the same, then
|
250 | // program is still up-to-date, and we should not invalidate caches.
|
251 | var filesAdded = 0;
|
252 | var filesChangedOrRemoved = [];
|
253 | // Check if any source files have been added / changed since last computation.
|
254 | var seen = new Set();
|
255 | var ANGULAR_CORE = '@angular/core';
|
256 | var corePath = this.reflectorHost.moduleNameToFileName(ANGULAR_CORE);
|
257 | try {
|
258 | for (var _e = tslib_1.__values(program.getSourceFiles()), _f = _e.next(); !_f.done; _f = _e.next()) {
|
259 | var fileName = _f.value.fileName;
|
260 | // If `@angular/core` is edited, the language service would have to be
|
261 | // restarted, so ignore changes to `@angular/core`.
|
262 | // When the StaticReflector is initialized at startup, it loads core
|
263 | // symbols from @angular/core by calling initializeConversionMap(). This
|
264 | // is only done once. If the file is invalidated, some of the core symbols
|
265 | // will be lost permanently.
|
266 | if (fileName === corePath) {
|
267 | continue;
|
268 | }
|
269 | seen.add(fileName);
|
270 | var version = this.tsLsHost.getScriptVersion(fileName);
|
271 | var lastVersion = this.fileVersions.get(fileName);
|
272 | if (lastVersion === undefined) {
|
273 | filesAdded++;
|
274 | this.fileVersions.set(fileName, version);
|
275 | }
|
276 | else if (version !== lastVersion) {
|
277 | filesChangedOrRemoved.push(fileName); // changed
|
278 | this.fileVersions.set(fileName, version);
|
279 | }
|
280 | }
|
281 | }
|
282 | catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
283 | finally {
|
284 | try {
|
285 | if (_f && !_f.done && (_a = _e.return)) _a.call(_e);
|
286 | }
|
287 | finally { if (e_3) throw e_3.error; }
|
288 | }
|
289 | try {
|
290 | // Check if any source files have been removed since last computation.
|
291 | for (var _g = tslib_1.__values(this.fileVersions), _h = _g.next(); !_h.done; _h = _g.next()) {
|
292 | var _j = tslib_1.__read(_h.value, 1), fileName = _j[0];
|
293 | if (!seen.has(fileName)) {
|
294 | filesChangedOrRemoved.push(fileName); // removed
|
295 | // Because Maps are iterated in insertion order, it is safe to delete
|
296 | // entries from the same map while iterating.
|
297 | // See https://stackoverflow.com/questions/35940216 and
|
298 | // https://www.ecma-international.org/ecma-262/10.0/index.html#sec-map.prototype.foreach
|
299 | this.fileVersions.delete(fileName);
|
300 | }
|
301 | }
|
302 | }
|
303 | catch (e_4_1) { e_4 = { error: e_4_1 }; }
|
304 | finally {
|
305 | try {
|
306 | if (_h && !_h.done && (_b = _g.return)) _b.call(_g);
|
307 | }
|
308 | finally { if (e_4) throw e_4.error; }
|
309 | }
|
310 | try {
|
311 | for (var filesChangedOrRemoved_1 = tslib_1.__values(filesChangedOrRemoved), filesChangedOrRemoved_1_1 = filesChangedOrRemoved_1.next(); !filesChangedOrRemoved_1_1.done; filesChangedOrRemoved_1_1 = filesChangedOrRemoved_1.next()) {
|
312 | var fileName = filesChangedOrRemoved_1_1.value;
|
313 | var symbols = this.staticSymbolResolver.invalidateFile(fileName);
|
314 | this.reflector.invalidateSymbols(symbols);
|
315 | }
|
316 | }
|
317 | catch (e_5_1) { e_5 = { error: e_5_1 }; }
|
318 | finally {
|
319 | try {
|
320 | if (filesChangedOrRemoved_1_1 && !filesChangedOrRemoved_1_1.done && (_c = filesChangedOrRemoved_1.return)) _c.call(filesChangedOrRemoved_1);
|
321 | }
|
322 | finally { if (e_5) throw e_5.error; }
|
323 | }
|
324 | // Program is up-to-date iff no files are added, changed, or removed.
|
325 | return filesAdded === 0 && filesChangedOrRemoved.length === 0;
|
326 | };
|
327 | /**
|
328 | * Find all templates in the specified `file`.
|
329 | * @param fileName TS or HTML file
|
330 | */
|
331 | TypeScriptServiceHost.prototype.getTemplates = function (fileName) {
|
332 | var _this = this;
|
333 | var results = [];
|
334 | if (fileName.endsWith('.ts')) {
|
335 | // Find every template string in the file
|
336 | var visit_1 = function (child) {
|
337 | var template = _this.getInternalTemplate(child);
|
338 | if (template) {
|
339 | results.push(template);
|
340 | }
|
341 | else {
|
342 | tss.forEachChild(child, visit_1);
|
343 | }
|
344 | };
|
345 | var sourceFile = this.getSourceFile(fileName);
|
346 | if (sourceFile) {
|
347 | tss.forEachChild(sourceFile, visit_1);
|
348 | }
|
349 | }
|
350 | else {
|
351 | var template = this.getExternalTemplate(fileName);
|
352 | if (template) {
|
353 | results.push(template);
|
354 | }
|
355 | }
|
356 | return results;
|
357 | };
|
358 | /**
|
359 | * Return metadata about all class declarations in the file that are Angular
|
360 | * directives. Potential matches are `@NgModule`, `@Component`, `@Directive`,
|
361 | * `@Pipes`, etc. class declarations.
|
362 | *
|
363 | * @param fileName TS file
|
364 | */
|
365 | TypeScriptServiceHost.prototype.getDeclarations = function (fileName) {
|
366 | var _this = this;
|
367 | if (!fileName.endsWith('.ts')) {
|
368 | return [];
|
369 | }
|
370 | var sourceFile = this.getSourceFile(fileName);
|
371 | if (!sourceFile) {
|
372 | return [];
|
373 | }
|
374 | var results = [];
|
375 | var visit = function (child) {
|
376 | var candidate = ts_utils_1.getDirectiveClassLike(child);
|
377 | if (candidate) {
|
378 | var classId = candidate.classId;
|
379 | var declarationSpan = spanOf(classId);
|
380 | var className = classId.getText();
|
381 | var classSymbol = _this.reflector.getStaticSymbol(sourceFile.fileName, className);
|
382 | // Ask the resolver to check if candidate is actually Angular directive
|
383 | if (!_this.resolver.isDirective(classSymbol)) {
|
384 | return;
|
385 | }
|
386 | var data = _this.resolver.getNonNormalizedDirectiveMetadata(classSymbol);
|
387 | if (!data) {
|
388 | return;
|
389 | }
|
390 | results.push({
|
391 | type: classSymbol,
|
392 | declarationSpan: declarationSpan,
|
393 | metadata: data.metadata,
|
394 | errors: _this.getCollectedErrors(declarationSpan, sourceFile),
|
395 | });
|
396 | }
|
397 | else {
|
398 | child.forEachChild(visit);
|
399 | }
|
400 | };
|
401 | tss.forEachChild(sourceFile, visit);
|
402 | return results;
|
403 | };
|
404 | TypeScriptServiceHost.prototype.getSourceFile = function (fileName) {
|
405 | if (!fileName.endsWith('.ts')) {
|
406 | throw new Error("Non-TS source file requested: " + fileName);
|
407 | }
|
408 | return this.program.getSourceFile(fileName);
|
409 | };
|
410 | Object.defineProperty(TypeScriptServiceHost.prototype, "program", {
|
411 | get: function () {
|
412 | var program = this.tsLS.getProgram();
|
413 | if (!program) {
|
414 | // Program is very very unlikely to be undefined.
|
415 | throw new Error('No program in language service!');
|
416 | }
|
417 | return program;
|
418 | },
|
419 | enumerable: false,
|
420 | configurable: true
|
421 | });
|
422 | /**
|
423 | * Return the TemplateSource if `node` is a template node.
|
424 | *
|
425 | * For example,
|
426 | *
|
427 | * @Component({
|
428 | * template: '<div></div>' <-- template node
|
429 | * })
|
430 | * class AppComponent {}
|
431 | * ^---- class declaration node
|
432 | *
|
433 | * @param node Potential template node
|
434 | */
|
435 | TypeScriptServiceHost.prototype.getInternalTemplate = function (node) {
|
436 | if (!tss.isStringLiteralLike(node)) {
|
437 | return;
|
438 | }
|
439 | var tmplAsgn = ts_utils_1.getPropertyAssignmentFromValue(node, 'template');
|
440 | if (!tmplAsgn) {
|
441 | return;
|
442 | }
|
443 | var classDecl = ts_utils_1.getClassDeclFromDecoratorProp(tmplAsgn);
|
444 | if (!classDecl || !classDecl.name) { // Does not handle anonymous class
|
445 | return;
|
446 | }
|
447 | var fileName = node.getSourceFile().fileName;
|
448 | var classSymbol = this.reflector.getStaticSymbol(fileName, classDecl.name.text);
|
449 | return new template_1.InlineTemplate(node, classDecl, classSymbol, this);
|
450 | };
|
451 | /**
|
452 | * Return the external template for `fileName`.
|
453 | * @param fileName HTML file
|
454 | */
|
455 | TypeScriptServiceHost.prototype.getExternalTemplate = function (fileName) {
|
456 | // First get the text for the template
|
457 | var snapshot = this.tsLsHost.getScriptSnapshot(fileName);
|
458 | if (!snapshot) {
|
459 | return;
|
460 | }
|
461 | var source = snapshot.getText(0, snapshot.getLength());
|
462 | // Next find the component class symbol
|
463 | var classSymbol = this.fileToComponent.get(fileName);
|
464 | if (!classSymbol) {
|
465 | return;
|
466 | }
|
467 | // Then use the class symbol to find the actual ts.ClassDeclaration node
|
468 | var sourceFile = this.getSourceFile(classSymbol.filePath);
|
469 | if (!sourceFile) {
|
470 | return;
|
471 | }
|
472 | // TODO: This only considers top-level class declarations in a source file.
|
473 | // This would not find a class declaration in a namespace, for example.
|
474 | var classDecl = sourceFile.forEachChild(function (child) {
|
475 | if (tss.isClassDeclaration(child) && child.name && child.name.text === classSymbol.name) {
|
476 | return child;
|
477 | }
|
478 | });
|
479 | if (!classDecl) {
|
480 | return;
|
481 | }
|
482 | return new template_1.ExternalTemplate(source, fileName, classDecl, classSymbol, this);
|
483 | };
|
484 | TypeScriptServiceHost.prototype.collectError = function (error, filePath) {
|
485 | if (filePath) {
|
486 | var errors = this.collectedErrors.get(filePath);
|
487 | if (!errors) {
|
488 | errors = [];
|
489 | this.collectedErrors.set(filePath, errors);
|
490 | }
|
491 | errors.push(error);
|
492 | }
|
493 | };
|
494 | TypeScriptServiceHost.prototype.getCollectedErrors = function (defaultSpan, sourceFile) {
|
495 | var errors = this.collectedErrors.get(sourceFile.fileName);
|
496 | if (!errors) {
|
497 | return [];
|
498 | }
|
499 | // TODO: Add better typings for the errors
|
500 | return errors.map(function (e) {
|
501 | var line = e.line || (e.position && e.position.line);
|
502 | var column = e.column || (e.position && e.position.column);
|
503 | var span = spanAt(sourceFile, line, column) || defaultSpan;
|
504 | if (compiler_1.isFormattedError(e)) {
|
505 | return errorToDiagnosticWithChain(e, span);
|
506 | }
|
507 | return { message: e.message, span: span };
|
508 | });
|
509 | };
|
510 | /**
|
511 | * Return the parsed template for the template at the specified `position`.
|
512 | * @param fileName TS or HTML file
|
513 | * @param position Position of the template in the TS file, otherwise ignored.
|
514 | */
|
515 | TypeScriptServiceHost.prototype.getTemplateAstAtPosition = function (fileName, position) {
|
516 | var template;
|
517 | if (fileName.endsWith('.ts')) {
|
518 | var sourceFile = this.getSourceFile(fileName);
|
519 | if (!sourceFile) {
|
520 | return;
|
521 | }
|
522 | // Find the node that most closely matches the position
|
523 | var node = ts_utils_1.findTightestNode(sourceFile, position);
|
524 | if (!node) {
|
525 | return;
|
526 | }
|
527 | template = this.getInternalTemplate(node);
|
528 | }
|
529 | else {
|
530 | template = this.getExternalTemplate(fileName);
|
531 | }
|
532 | if (!template) {
|
533 | return;
|
534 | }
|
535 | return this.getTemplateAst(template);
|
536 | };
|
537 | /**
|
538 | * Find the NgModule which the directive associated with the `classSymbol`
|
539 | * belongs to, then return its schema and transitive directives and pipes.
|
540 | * @param classSymbol Angular Symbol that defines a directive
|
541 | */
|
542 | TypeScriptServiceHost.prototype.getModuleMetadataForDirective = function (classSymbol) {
|
543 | var e_6, _a, e_7, _b, _c;
|
544 | var result = {
|
545 | directives: [],
|
546 | pipes: [],
|
547 | schemas: [],
|
548 | };
|
549 | // First find which NgModule the directive belongs to.
|
550 | var ngModule = this.analyzedModules.ngModuleByPipeOrDirective.get(classSymbol) ||
|
551 | findSuitableDefaultModule(this.analyzedModules);
|
552 | if (!ngModule) {
|
553 | return result;
|
554 | }
|
555 | // Then gather all transitive directives and pipes.
|
556 | var _d = ngModule.transitiveModule, directives = _d.directives, pipes = _d.pipes;
|
557 | try {
|
558 | for (var directives_1 = tslib_1.__values(directives), directives_1_1 = directives_1.next(); !directives_1_1.done; directives_1_1 = directives_1.next()) {
|
559 | var directive = directives_1_1.value;
|
560 | var data = this.resolver.getNonNormalizedDirectiveMetadata(directive.reference);
|
561 | if (data) {
|
562 | result.directives.push(data.metadata.toSummary());
|
563 | }
|
564 | }
|
565 | }
|
566 | catch (e_6_1) { e_6 = { error: e_6_1 }; }
|
567 | finally {
|
568 | try {
|
569 | if (directives_1_1 && !directives_1_1.done && (_a = directives_1.return)) _a.call(directives_1);
|
570 | }
|
571 | finally { if (e_6) throw e_6.error; }
|
572 | }
|
573 | try {
|
574 | for (var pipes_1 = tslib_1.__values(pipes), pipes_1_1 = pipes_1.next(); !pipes_1_1.done; pipes_1_1 = pipes_1.next()) {
|
575 | var pipe = pipes_1_1.value;
|
576 | var metadata = this.resolver.getOrLoadPipeMetadata(pipe.reference);
|
577 | result.pipes.push(metadata.toSummary());
|
578 | }
|
579 | }
|
580 | catch (e_7_1) { e_7 = { error: e_7_1 }; }
|
581 | finally {
|
582 | try {
|
583 | if (pipes_1_1 && !pipes_1_1.done && (_b = pipes_1.return)) _b.call(pipes_1);
|
584 | }
|
585 | finally { if (e_7) throw e_7.error; }
|
586 | }
|
587 | (_c = result.schemas).push.apply(_c, tslib_1.__spread(ngModule.schemas));
|
588 | return result;
|
589 | };
|
590 | /**
|
591 | * Parse the `template` and return its AST, if any.
|
592 | * @param template template to be parsed
|
593 | */
|
594 | TypeScriptServiceHost.prototype.getTemplateAst = function (template) {
|
595 | var classSymbol = template.type, fileName = template.fileName;
|
596 | var data = this.resolver.getNonNormalizedDirectiveMetadata(classSymbol);
|
597 | if (!data) {
|
598 | return;
|
599 | }
|
600 | var htmlParser = new compiler_1.HtmlParser();
|
601 | var expressionParser = new compiler_1.Parser(new compiler_1.Lexer());
|
602 | var parser = new compiler_1.TemplateParser(new compiler_1.CompilerConfig(), this.reflector, expressionParser, new compiler_1.DomElementSchemaRegistry(), htmlParser, null, // console
|
603 | [] // tranforms
|
604 | );
|
605 | var htmlResult = htmlParser.parse(template.source, fileName, {
|
606 | tokenizeExpansionForms: true,
|
607 | preserveLineEndings: true,
|
608 | });
|
609 | var _a = this.getModuleMetadataForDirective(classSymbol), directives = _a.directives, pipes = _a.pipes, schemas = _a.schemas;
|
610 | var parseResult = parser.tryParseHtml(htmlResult, data.metadata, directives, pipes, schemas);
|
611 | if (!parseResult.templateAst) {
|
612 | return;
|
613 | }
|
614 | return {
|
615 | htmlAst: htmlResult.rootNodes,
|
616 | templateAst: parseResult.templateAst,
|
617 | directive: data.metadata,
|
618 | directives: directives,
|
619 | pipes: pipes,
|
620 | parseErrors: parseResult.errors,
|
621 | expressionParser: expressionParser,
|
622 | template: template,
|
623 | };
|
624 | };
|
625 | /**
|
626 | * Log the specified `msg` to file at INFO level. If logging is not enabled
|
627 | * this method is a no-op.
|
628 | * @param msg Log message
|
629 | */
|
630 | TypeScriptServiceHost.prototype.log = function (msg) {
|
631 | if (this.tsLsHost.log) {
|
632 | this.tsLsHost.log(msg);
|
633 | }
|
634 | };
|
635 | /**
|
636 | * Log the specified `msg` to file at ERROR level. If logging is not enabled
|
637 | * this method is a no-op.
|
638 | * @param msg error message
|
639 | */
|
640 | TypeScriptServiceHost.prototype.error = function (msg) {
|
641 | if (this.tsLsHost.error) {
|
642 | this.tsLsHost.error(msg);
|
643 | }
|
644 | };
|
645 | /**
|
646 | * Log debugging info to file at INFO level, only if verbose setting is turned
|
647 | * on. Otherwise, this method is a no-op.
|
648 | * @param msg debugging message
|
649 | */
|
650 | TypeScriptServiceHost.prototype.debug = function (msg) {
|
651 | var project = this.tsLsHost;
|
652 | if (!project.projectService) {
|
653 | // tsLsHost is not a Project
|
654 | return;
|
655 | }
|
656 | var logger = project.projectService.logger;
|
657 | if (logger.hasLevel(tss.server.LogLevel.verbose)) {
|
658 | logger.info(msg);
|
659 | }
|
660 | };
|
661 | return TypeScriptServiceHost;
|
662 | }());
|
663 | exports.TypeScriptServiceHost = TypeScriptServiceHost;
|
664 | function findSuitableDefaultModule(modules) {
|
665 | var e_8, _a;
|
666 | var result = undefined;
|
667 | var resultSize = 0;
|
668 | try {
|
669 | for (var _b = tslib_1.__values(modules.ngModules), _c = _b.next(); !_c.done; _c = _b.next()) {
|
670 | var module_1 = _c.value;
|
671 | var moduleSize = module_1.transitiveModule.directives.length;
|
672 | if (moduleSize > resultSize) {
|
673 | result = module_1;
|
674 | resultSize = moduleSize;
|
675 | }
|
676 | }
|
677 | }
|
678 | catch (e_8_1) { e_8 = { error: e_8_1 }; }
|
679 | finally {
|
680 | try {
|
681 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
682 | }
|
683 | finally { if (e_8) throw e_8.error; }
|
684 | }
|
685 | return result;
|
686 | }
|
687 | function spanOf(node) {
|
688 | return { start: node.getStart(), end: node.getEnd() };
|
689 | }
|
690 | function spanAt(sourceFile, line, column) {
|
691 | if (line != null && column != null) {
|
692 | var position_1 = tss.getPositionOfLineAndCharacter(sourceFile, line, column);
|
693 | var findChild = function findChild(node) {
|
694 | if (node.kind > tss.SyntaxKind.LastToken && node.pos <= position_1 && node.end > position_1) {
|
695 | var betterNode = tss.forEachChild(node, findChild);
|
696 | return betterNode || node;
|
697 | }
|
698 | };
|
699 | var node = tss.forEachChild(sourceFile, findChild);
|
700 | if (node) {
|
701 | return { start: node.getStart(), end: node.getEnd() };
|
702 | }
|
703 | }
|
704 | }
|
705 | function convertChain(chain) {
|
706 | return { message: chain.message, next: chain.next ? chain.next.map(convertChain) : undefined };
|
707 | }
|
708 | function errorToDiagnosticWithChain(error, span) {
|
709 | return { message: error.chain ? convertChain(error.chain) : error.message, span: span };
|
710 | }
|
711 | });
|
712 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHlwZXNjcmlwdF9ob3N0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvbGFuZ3VhZ2Utc2VydmljZS9zcmMvdHlwZXNjcmlwdF9ob3N0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7R0FNRzs7Ozs7Ozs7Ozs7Ozs7SUFFSCw4Q0FBeWhCO0lBQ3poQixzQ0FBcUY7SUFDckYsMkJBQTZCO0lBQzdCLG9EQUFzRDtJQUV0RCxtRkFBeUQ7SUFDekQsK0VBQStDO0lBQy9DLG1FQUE0RDtJQUM1RCxtRUFBa0k7SUFHbEk7O09BRUc7SUFDSCxTQUFnQixtQ0FBbUMsQ0FDL0MsSUFBNkIsRUFBRSxPQUE0QjtRQUM3RCxJQUFNLE1BQU0sR0FBRyxJQUFJLHFCQUFxQixDQUFDLElBQUksRUFBRSxPQUFPLENBQUMsQ0FBQztRQUN4RCxJQUFNLFFBQVEsR0FBRyx3Q0FBcUIsQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMvQyxPQUFPLFFBQVEsQ0FBQztJQUNsQixDQUFDO0lBTEQsa0ZBS0M7SUFFRDs7Ozs7T0FLRztJQUNIO1FBQXFDLDJDQUFVO1FBQS9DOztRQUlBLENBQUM7UUFIQywrQkFBSyxHQUFMO1lBQ0UsT0FBTyxJQUFJLDBCQUFlLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFDSCxzQkFBQztJQUFELENBQUMsQUFKRCxDQUFxQyxxQkFBVSxHQUk5QztJQUpZLDBDQUFlO0lBTTVCOztPQUVHO0lBQ0g7UUFBeUMsK0NBQWM7UUFBdkQ7O1FBSUEsQ0FBQztRQUhDLGlDQUFHLEdBQUgsVUFBSSxJQUFZO1lBQ2QsT0FBTyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQzdCLENBQUM7UUFDSCwwQkFBQztJQUFELENBQUMsQUFKRCxDQUF5Qyx5QkFBYyxHQUl0RDtJQUpZLGtEQUFtQjtJQU1oQzs7Ozs7OztPQU9HO0lBQ0g7UUFrQkUsK0JBQXFCLFFBQWlDLEVBQVcsSUFBeUI7WUFBMUYsaUJBK0JDO1lBL0JvQixhQUFRLEdBQVIsUUFBUSxDQUF5QjtZQUFXLFNBQUksR0FBSixJQUFJLENBQXFCO1lBYnpFLHNCQUFpQixHQUFHLElBQUksNEJBQWlCLEVBQUUsQ0FBQztZQUM1QyxvQkFBZSxHQUFHLElBQUksR0FBRyxFQUF3QixDQUFDO1lBQ2xELG9CQUFlLEdBQUcsSUFBSSxHQUFHLEVBQWlCLENBQUM7WUFDM0MsaUJBQVksR0FBRyxJQUFJLEdBQUcsRUFBa0IsQ0FBQztZQUdsRCxnQkFBVyxHQUEwQixTQUFTLENBQUM7WUFDL0Msb0JBQWUsR0FBc0I7Z0JBQzNDLEtBQUssRUFBRSxFQUFFO2dCQUNULHlCQUF5QixFQUFFLElBQUksR0FBRyxFQUFFO2dCQUNwQyxTQUFTLEVBQUUsRUFBRTthQUNkLENBQUM7WUFHQSxJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksNkJBQWtCLENBQ3pDO2dCQUNFLFdBQVcsRUFBWCxVQUFZLFNBQWlCO29CQUMzQixPQUFPLElBQUksQ0FBQztnQkFDZCxDQUFDO2dCQUNELFlBQVksRUFBWixVQUFhLGVBQXVCO29CQUNsQyxPQUFPLElBQUksQ0FBQztnQkFDZCxDQUFDO2dCQUNELGlCQUFpQixFQUFqQixVQUFrQixjQUFzQjtvQkFDdEMsT0FBTyxjQUFjLENBQUM7Z0JBQ3hCLENBQUM7Z0JBQ0QsbUJBQW1CLEVBQW5CLFVBQW9CLFFBQWdCO29CQUNsQyxPQUFPLFFBQVEsQ0FBQztnQkFDbEIsQ0FBQzthQUNGLEVBQ0QsSUFBSSxDQUFDLGlCQUFpQixDQUFDLENBQUM7WUFDNUIsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLDhCQUFhLENBQUMsY0FBTSxPQUFBLEtBQUksQ0FBQyxPQUFPLEVBQVosQ0FBWSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQ3JFLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxJQUFJLCtCQUFvQixDQUNoRCxJQUFJLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLENBQUMsZUFBZSxFQUNoRSxVQUFDLENBQUMsRUFBRSxRQUFRLElBQUssT0FBQSxLQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsRUFBOUIsQ0FBOEIsQ0FBQyxDQUFDO1lBQ3JELElBQUksQ0FBQyxXQUFXLEdBQUc7Z0JBQ2pCLE9BQU8sRUFBRSxVQUFDLE9BQWUsRUFBRSxHQUFXO29CQUNwQyxvREFBb0Q7b0JBQ3BELDBIQUEwSDtvQkFDMUgsSUFBSSxRQUFRLENBQUMsZUFBZ0IsQ0FBQyxPQUFPLENBQUMsRUFBRTt3QkFDdEMsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sRUFBRSxHQUFHLENBQUMsQ0FBQztxQkFDbkM7b0JBQ0QsT0FBTyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQ2xELENBQUM7YUFDRixDQUFDO1FBQ0osQ0FBQztRQWFELHNCQUFZLDJDQUFRO1lBSHBCOztlQUVHO2lCQUNIO2dCQUFBLGlCQWtDQztnQkFqQ0MsSUFBSSxJQUFJLENBQUMsU0FBUyxFQUFFO29CQUNsQixPQUFPLElBQUksQ0FBQyxTQUFTLENBQUM7aUJBQ3ZCO2dCQUNELHVFQUF1RTtnQkFDdkUsMkVBQTJFO2dCQUMzRSxtRUFBbUU7Z0JBQ25FLElBQU0sZUFBZSxHQUFHLElBQUksMEJBQWUsQ0FDdkMsSUFBSSxDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsb0JBQW9CLEVBQy9DLEVBQUUsRUFBRyx1QkFBdUI7Z0JBQzVCLEVBQUUsRUFBRyx5QkFBeUI7Z0JBQzlCLFVBQUMsQ0FBQyxFQUFFLFFBQVEsSUFBSyxPQUFBLEtBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxFQUE5QixDQUE4QixDQUFDLENBQUM7Z0JBQ3JELHFFQUFxRTtnQkFDckUsWUFBWTtnQkFDWixJQUFNLGNBQWMsR0FBRyxJQUFJLDJCQUFnQixDQUFDLGVBQWUsQ0FBQyxDQUFDO2dCQUM3RCxJQUFNLGlCQUFpQixHQUFHLElBQUksNEJBQWlCLENBQUMsZUFBZSxDQUFDLENBQUM7Z0JBQ2pFLElBQU0sWUFBWSxHQUFHLElBQUksdUJBQVksQ0FBQyxlQUFlLENBQUMsQ0FBQztnQkFDdkQsSUFBTSxxQkFBcUIsR0FBRyxJQUFJLG1DQUF3QixFQUFFLENBQUM7Z0JBQzdELElBQU0sY0FBYyxHQUFHLElBQUksbUJBQW1CLEVBQUUsQ0FBQztnQkFDakQsSUFBTSxVQUFVLEdBQUcsSUFBSSxlQUFlLEVBQUUsQ0FBQztnQkFDekMsdUVBQXVFO2dCQUN2RSxrQkFBa0I7Z0JBQ2xCLElBQU0sTUFBTSxHQUFHLElBQUkseUJBQWMsQ0FBQztvQkFDaEMsb0JBQW9CLEVBQUUsd0JBQWlCLENBQUMsUUFBUTtvQkFDaEQsTUFBTSxFQUFFLEtBQUs7aUJBQ2QsQ0FBQyxDQUFDO2dCQUNILElBQU0sbUJBQW1CLEdBQ3JCLElBQUksOEJBQW1CLENBQUMsY0FBYyxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsVUFBVSxFQUFFLE1BQU0sQ0FBQyxDQUFDO2dCQUNsRixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksa0NBQXVCLENBQ3hDLE1BQU0sRUFBRSxVQUFVLEVBQUUsY0FBYyxFQUFFLGlCQUFpQixFQUFFLFlBQVksRUFDbkUsSUFBSSw2QkFBa0IsRUFBRSxFQUFFLHFCQUFxQixFQUFFLG1CQUFtQixFQUFFLElBQUksZUFBTyxFQUFFLEVBQ25GLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxlQUFlLEVBQ3ZDLFVBQUMsS0FBSyxFQUFFLElBQUksSUFBSyxPQUFBLEtBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLElBQUksSUFBSSxJQUFJLENBQUMsUUFBUSxDQUFDLEVBQS9DLENBQStDLENBQUMsQ0FBQztnQkFDdEUsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQ3hCLENBQUM7OztXQUFBO1FBTUQsc0JBQVksNENBQVM7WUFKckI7OztlQUdHO2lCQUNIO2dCQUNFLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQXFCLENBQUM7WUFDekQsQ0FBQzs7O1dBQUE7UUFFRDs7V0FFRztRQUNILG9EQUFvQixHQUFwQjtZQUNFLHdCQUFXLElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxFQUFFLEVBQUU7UUFDMUMsQ0FBQztRQUVEOzs7Ozs7V0FNRztRQUNILGtEQUFrQixHQUFsQjs7WUFDRSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRTtnQkFDbkIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDO2FBQzdCO1lBRUQsb0JBQW9CO1lBQ3BCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLENBQUM7WUFDN0IsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUM3QixJQUFJLENBQUMsUUFBUSxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBRTNCLElBQU0sV0FBVyxHQUFHO2dCQUNsQixZQUFZLEVBQVosVUFBYSxTQUFpQjtvQkFDNUIsT0FBTyxJQUFJLENBQUM7Z0JBQ2QsQ0FBQzthQUNGLENBQUM7WUFDRixJQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxVQUFBLEVBQUUsSUFBSSxPQUFBLEVBQUUsQ0FBQyxRQUFRLEVBQVgsQ0FBVyxDQUFDLENBQUM7WUFFMUUsSUFBSTtnQkFDRixJQUFJLENBQUMsZUFBZTtvQkFDaEIsMkJBQWdCLENBQUMsWUFBWSxFQUFFLFdBQVcsRUFBRSxJQUFJLENBQUMsb0JBQW9CLEVBQUUsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQzNGO1lBQUMsT0FBTyxDQUFDLEVBQUU7Z0JBQ1Ysb0VBQW9FO2dCQUNwRSxJQUFJLENBQUMsS0FBSyxDQUFDLGlDQUErQixDQUFHLENBQUMsQ0FBQztnQkFDL0MsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDO2FBQzdCOztnQkFFRCxpREFBaUQ7Z0JBQ2pELEtBQXVCLElBQUEsS0FBQSxpQkFBQSxJQUFJLENBQUMsZUFBZSxDQUFDLFNBQVMsQ0FBQSxnQkFBQSw0QkFBRTtvQkFBbEQsSUFBTSxRQUFRLFdBQUE7O3dCQUNqQixLQUF3QixJQUFBLG9CQUFBLGlCQUFBLFFBQVEsQ0FBQyxrQkFBa0IsQ0FBQSxDQUFBLGdCQUFBLDRCQUFFOzRCQUFoRCxJQUFNLFNBQVMsV0FBQTs0QkFDWCxJQUFBLFFBQVEsR0FBSSxJQUFJLENBQUMsUUFBUSxDQUFDLGlDQUFpQyxDQUFDLFNBQVMsQ0FBQyxTQUFTLENBQUUsU0FBekUsQ0FBMEU7NEJBQ3pGLElBQUksUUFBUSxDQUFDLFdBQVcsSUFBSSxRQUFRLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsV0FBVyxFQUFFO2dDQUM5RSxJQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FDekMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxrQkFBa0IsQ0FBQyxTQUFTLENBQUMsU0FBUyxDQUFDLEVBQ3RELFFBQVEsQ0FBQyxRQUFRLENBQUMsV0FBVyxDQUFDLENBQUM7Z0NBQ25DLElBQUksQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLFlBQVksRUFBRSxTQUFTLENBQUMsU0FBUyxDQUFDLENBQUM7NkJBQzdEO3lCQUNGOzs7Ozs7Ozs7aUJBQ0Y7Ozs7Ozs7OztZQUVELE9BQU8sSUFBSSxDQUFDLGVBQWUsQ0FBQztRQUM5QixDQUFDO1FBRUQ7Ozs7O1dBS0c7UUFDSyx3Q0FBUSxHQUFoQjs7WUFDUSxJQUFBLEtBQXlCLElBQUksRUFBNUIsV0FBVyxpQkFBQSxFQUFFLE9BQU8sYUFBUSxDQUFDO1lBQ3BDLElBQUksV0FBVyxLQUFLLE9BQU8sRUFBRTtnQkFDM0IsT0FBTyxJQUFJLENBQUM7YUFDYjtZQUNELElBQUksQ0FBQyxXQUFXLEdBQUcsT0FBTyxDQUFDO1lBRTNCLHlFQUF5RTtZQUN6RSwyRUFBMkU7WUFDM0Usb0VBQW9FO1lBQ3BFLElBQUksVUFBVSxHQUFHLENBQUMsQ0FBQztZQUNuQixJQUFNLHFCQUFxQixHQUFhLEVBQUUsQ0FBQztZQUUzQyw4RUFBOEU7WUFDOUUsSUFBTSxJQUFJLEdBQUcsSUFBSSxHQUFHLEVBQVUsQ0FBQztZQUMvQixJQUFNLFlBQVksR0FBRyxlQUFlLENBQUM7WUFDckMsSUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxvQkFBb0IsQ0FBQyxZQUFZLENBQUMsQ0FBQzs7Z0JBQ3ZFLEtBQXlCLElBQUEsS0FBQSxpQkFBQSxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUEsZ0JBQUEsNEJBQUU7b0JBQXZDLElBQUEsUUFBUSxvQkFBQTtvQkFDbEIsc0VBQXNFO29CQUN0RSxtREFBbUQ7b0JBQ25ELG9FQUFvRTtvQkFDcEUsd0VBQXdFO29CQUN4RSwwRUFBMEU7b0JBQzFFLDRCQUE0QjtvQkFDNUIsSUFBSSxRQUFRLEtBQUssUUFBUSxFQUFFO3dCQUN6QixTQUFTO3FCQUNWO29CQUNELElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ25CLElBQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsZ0JBQWdCLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ3pELElBQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUNwRCxJQUFJLFdBQVcsS0FBSyxTQUFTLEVBQUU7d0JBQzdCLFVBQVUsRUFBRSxDQUFDO3dCQUNiLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRSxPQUFPLENBQUMsQ0FBQztxQkFDMUM7eUJBQU0sSUFBSSxPQUFPLEtBQUssV0FBVyxFQUFFO3dCQUNsQyxxQkFBcUIsQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBRSxVQUFVO3dCQUNqRCxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsT0FBTyxDQUFDLENBQUM7cUJBQzFDO2lCQUNGOzs7Ozs7Ozs7O2dCQUVELHNFQUFzRTtnQkFDdEUsS0FBeUIsSUFBQSxLQUFBLGlCQUFBLElBQUksQ0FBQyxZQUFZLENBQUEsZ0JBQUEsNEJBQUU7b0JBQWpDLElBQUEsS0FBQSwyQkFBVSxFQUFULFFBQVEsUUFBQTtvQkFDbEIsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLEVBQUU7d0JBQ3ZCLHFCQUFxQixDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFFLFVBQVU7d0JBQ2pELHFFQUFxRTt3QkFDckUsNkNBQTZDO3dCQUM3Qyx1REFBdUQ7d0JBQ3ZELHdGQUF3Rjt3QkFDeEYsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7cUJBQ3BDO2lCQUNGOzs7Ozs7Ozs7O2dCQUVELEtBQXVCLElBQUEsMEJBQUEsaUJBQUEscUJBQXFCLENBQUEsNERBQUEsK0ZBQUU7b0JBQXpDLElBQU0sUUFBUSxrQ0FBQTtvQkFDakIsSUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDbkUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztpQkFDM0M7Ozs7Ozs7OztZQUVELHFFQUFxRTtZQUNyRSxPQUFPLFVBQVUsS0FBSyxDQUFDLElBQUkscUJBQXFCLENBQUMsTUFBTSxLQUFLLENBQUMsQ0FBQztRQUNoRSxDQUFDO1FBRUQ7OztXQUdHO1FBQ0gsNENBQVksR0FBWixVQUFhLFFBQWdCO1lBQTdCLGlCQXVCQztZQXRCQyxJQUFNLE9BQU8sR0FBcUIsRUFBRSxDQUFDO1lBQ3JDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDNUIseUNBQXlDO2dCQUN6QyxJQUFNLE9BQUssR0FBRyxVQUFDLEtBQWU7b0JBQzVCLElBQU0sUUFBUSxHQUFHLEtBQUksQ0FBQyxtQkFBbUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDakQsSUFBSSxRQUFRLEVBQUU7d0JBQ1osT0FBTyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQztxQkFDeEI7eUJBQU07d0JBQ0wsR0FBRyxDQUFDLFlBQVksQ0FBQyxLQUFLLEVBQUUsT0FBSyxDQUFDLENBQUM7cUJBQ2hDO2dCQUNILENBQUMsQ0FBQztnQkFDRixJQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO2dCQUNoRCxJQUFJLFVBQVUsRUFBRTtvQkFDZCxHQUFHLENBQUMsWUFBWSxDQUFDLFVBQVUsRUFBRSxPQUFLLENBQUMsQ0FBQztpQkFDckM7YUFDRjtpQkFBTTtnQkFDTCxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsbUJBQW1CLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ3BELElBQUksUUFBUSxFQUFFO29CQUNaLE9BQU8sQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7aUJBQ3hCO2FBQ0Y7WUFDRCxPQUFPLE9BQU8sQ0FBQztRQUNqQixDQUFDO1FBRUQ7Ozs7OztXQU1HO1FBQ0gsK0NBQWUsR0FBZixVQUFnQixRQUFnQjtZQUFoQyxpQkFxQ0M7WUFwQ0MsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEVBQUU7Z0JBQzdCLE9BQU8sRUFBRSxDQUFDO2FBQ1g7WUFDRCxJQUFNLFVBQVUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQ2hELElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ2YsT0FBTyxFQUFFLENBQUM7YUFDWDtZQUNELElBQU0sT0FBTyxHQUFrQixFQUFFLENBQUM7WUFDbEMsSUFBTSxLQUFLLEdBQUcsVUFBQyxLQUFlO2dCQUM1QixJQUFNLFNBQVMsR0FBRyxnQ0FBcUIsQ0FBQyxLQUFLLENBQUMsQ0FBQztnQkFDL0MsSUFBSSxTQUFTLEVBQUU7b0JBQ04sSUFBQSxPQUFPLEdBQUksU0FBUyxRQUFiLENBQWM7b0JBQzVCLElBQU0sZUFBZSxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDeEMsSUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNwQyxJQUFNLFdBQVcsR0FBRyxLQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQyxDQUFDO29CQUNuRix1RUFBdUU7b0JBQ3ZFLElBQUksQ0FBQyxLQUFJLENBQUMsUUFBUSxDQUFDLFdBQVcsQ0FBQyxXQUFXLENBQUMsRUFBRTt3QkFDM0MsT0FBTztxQkFDUjtvQkFDRCxJQUFNLElBQUksR0FBRyxLQUFJLENBQUMsUUFBUSxDQUFDLGlDQUFpQyxDQUFDLFdBQVcsQ0FBQyxDQUFDO29CQUMxRSxJQUFJLENBQUMsSUFBSSxFQUFFO3dCQUNULE9BQU87cUJBQ1I7b0JBQ0QsT0FBTyxDQUFDLElBQUksQ0FBQzt3QkFDWCxJQUFJLEVBQUUsV0FBVzt3QkFDakIsZUFBZSxpQkFBQTt3QkFDZixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7d0JBQ3ZCLE1BQU0sRUFBRSxLQUFJLENBQUMsa0JBQWtCLENBQUMsZUFBZSxFQUFFLFVBQVUsQ0FBQztxQkFDN0QsQ0FBQyxDQUFDO2lCQUNKO3FCQUFNO29CQUNMLEtBQUssQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7aUJBQzNCO1lBQ0gsQ0FBQyxDQUFDO1lBQ0YsR0FBRyxDQUFDLFlBQVksQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFFcEMsT0FBTyxPQUFPLENBQUM7UUFDakIsQ0FBQztRQUVELDZDQUFhLEdBQWIsVUFBYyxRQUFnQjtZQUM1QixJQUFJLENBQUMsUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDN0IsTUFBTSxJQUFJLEtBQUssQ0FBQyxtQ0FBaUMsUUFBVSxDQUFDLENBQUM7YUFDOUQ7WUFDRCxPQUFPLElBQUksQ0FBQyxPQUFPLENBQUMsYUFBYSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQzlDLENBQUM7UUFFRCxzQkFBSSwwQ0FBTztpQkFBWDtnQkFDRSxJQUFNLE9BQU8sR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO2dCQUN2QyxJQUFJLENBQUMsT0FBTyxFQUFFO29CQUNaLGlEQUFpRDtvQkFDakQsTUFBTSxJQUFJLEtBQUssQ0FBQyxpQ0FBaUMsQ0FBQyxDQUFDO2lCQUNwRDtnQkFDRCxPQUFPLE9BQU8sQ0FBQztZQUNqQixDQUFDOzs7V0FBQTtRQUVEOzs7Ozs7Ozs7Ozs7V0FZRztRQUNLLG1EQUFtQixHQUEzQixVQUE0QixJQUFjO1lBQ3hDLElBQUksQ0FBQyxHQUFHLENBQUMsbUJBQW1CLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ2xDLE9BQU87YUFDUjtZQUNELElBQU0sUUFBUSxHQUFHLHlDQUE4QixDQUFDLElBQUksRUFBRSxVQUFVLENBQUMsQ0FBQztZQUNsRSxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNiLE9BQU87YUFDUjtZQUNELElBQU0sU0FBUyxHQUFHLHdDQUE2QixDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzFELElBQUksQ0FBQyxTQUFTLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLEVBQUcsa0NBQWtDO2dCQUN0RSxPQUFPO2FBQ1I7WUFDRCxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUMsUUFBUSxDQUFDO1lBQy9DLElBQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxTQUFTLENBQUMsZUFBZSxDQUFDLFFBQVEsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDO1lBQ2xGLE9BQU8sSUFBSSx5QkFBYyxDQUFDLElBQUksRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ2hFLENBQUM7UUFFRDs7O1dBR0c7UUFDSyxtREFBbUIsR0FBM0IsVUFBNEIsUUFBZ0I7WUFDMUMsc0NBQXNDO1lBQ3RDLElBQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsaUJBQWlCLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDM0QsSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDYixPQUFPO2FBQ1I7WUFDRCxJQUFNLE1BQU0sR0FBRyxRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsRUFBRSxRQUFRLENBQUMsU0FBUyxFQUFFLENBQUMsQ0FBQztZQUN6RCx1Q0FBdUM7WUFDdkMsSUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7WUFDdkQsSUFBSSxDQUFDLFdBQVcsRUFBRTtnQkFDaEIsT0FBTzthQUNSO1lBQ0Qsd0VBQXdFO1lBQ3hFLElBQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzVELElBQUksQ0FBQyxVQUFVLEVBQUU7Z0JBQ2YsT0FBTzthQUNSO1lBQ0QsMkVBQTJFO1lBQzNFLHVFQUF1RTtZQUN2RSxJQUFNLFNBQVMsR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDLFVBQUMsS0FBSztnQkFDOUMsSUFBSSxHQUFHLENBQUMsa0JBQWtCLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxDQUFDLElBQUksSUFBSSxLQUFLLENBQUMsSUFBSSxDQUFDLElBQUksS0FBSyxXQUFXLENBQUMsSUFBSSxFQUFFO29CQUN2RixPQUFPLEtBQUssQ0FBQztpQkFDZDtZQUNILENBQUMsQ0FBQyxDQUFDO1lBQ0gsSUFBSSxDQUFDLFNBQVMsRUFBRTtnQkFDZCxPQUFPO2FBQ1I7WUFDRCxPQUFPLElBQUksMkJBQWdCLENBQUMsTUFBTSxFQUFFLFFBQVEsRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQzlFLENBQUM7UUFFTyw0Q0FBWSxHQUFwQixVQUFxQixLQUFVLEVBQUUsUUFBaUI7WUFDaEQsSUFBSSxRQUFRLEVBQUU7Z0JBQ1osSUFBSSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLENBQUM7Z0JBQ2hELElBQUksQ0FBQyxNQUFNLEVBQUU7b0JBQ1gsTUFBTSxHQUFHLEVBQUUsQ0FBQztvQkFDWixJQUFJLENBQUMsZUFBZSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUUsTUFBTSxDQUFDLENBQUM7aUJBQzVDO2dCQUNELE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7YUFDcEI7UUFDSCxDQUFDO1FBRU8sa0RBQWtCLEdBQTFCLFVBQTJCLFdBQWlCLEVBQUUsVUFBMEI7WUFDdEUsSUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO1lBQzdELElBQUksQ0FBQyxNQUFNLEVBQUU7Z0JBQ1gsT0FBTyxFQUFFLENBQUM7YUFDWDtZQUNELDBDQUEwQztZQUMxQyxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsVUFBQyxDQUFNO2dCQUN2QixJQUFNLElBQUksR0FBRyxDQUFDLENBQUMsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUN2RCxJQUFNLE1BQU0sR0FBRyxDQUFDLENBQUMsTUFBTSxJQUFJLENBQUMsQ0FBQyxDQUFDLFFBQVEsSUFBSSxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUM3RCxJQUFNLElBQUksR0FBRyxNQUFNLENBQUMsVUFBVSxFQUFFLElBQUksRUFBRSxNQUFNLENBQUMsSUFBSSxXQUFXLENBQUM7Z0JBQzdELElBQUksMkJBQWdCLENBQUMsQ0FBQyxDQUFDLEVBQUU7b0JBQ3ZCLE9BQU8sMEJBQTBCLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxDQUFDO2lCQUM1QztnQkFDRCxPQUFPLEVBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQyxPQUFPLEVBQUUsSUFBSSxNQUFBLEVBQUMsQ0FBQztZQUNwQyxDQUFDLENBQUMsQ0FBQztRQUNMLENBQUM7UUFFRDs7OztXQUlHO1FBQ0gsd0RBQXdCLEdBQXhCLFVBQXlCLFFBQWdCLEVBQUUsUUFBZ0I7WUFDekQsSUFBSSxRQUFrQyxDQUFDO1lBQ3ZDLElBQUksUUFBUSxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsRUFBRTtnQkFDNUIsSUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztnQkFDaEQsSUFBSSxDQUFDLFVBQVUsRUFBRTtvQkFDZixPQUFPO2lCQUNSO2dCQUNELHVEQUF1RDtnQkFDdkQsSUFBTSxJQUFJLEdBQUcsMkJBQWdCLENBQUMsVUFBVSxFQUFFLFFBQVEsQ0FBQyxDQUFDO2dCQUNwRCxJQUFJLENBQUMsSUFBSSxFQUFFO29CQUNULE9BQU87aUJBQ1I7Z0JBQ0QsUUFBUSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUMzQztpQkFBTTtnQkFDTCxRQUFRLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLFFBQVEsQ0FBQyxDQUFDO2FBQy9DO1lBQ0QsSUFBSSxDQUFDLFFBQVEsRUFBRTtnQkFDYixPQUFPO2FBQ1I7WUFDRCxPQUFPLElBQUksQ0FBQyxjQUFjLENBQUMsUUFBUSxDQUFDLENBQUM7UUFDdkMsQ0FBQztRQUVEOzs7O1dBSUc7UUFDSyw2REFBNkIsR0FBckMsVUFBc0MsV0FBeUI7O1lBQzdELElBQU0sTUFBTSxHQUFHO2dCQUNiLFVBQVUsRUFBRSxFQUErQjtnQkFDM0MsS0FBSyxFQUFFLEVBQTBCO2dCQUNqQyxPQUFPLEVBQUUsRUFBc0I7YUFDaEMsQ0FBQztZQUNGLHNEQUFzRDtZQUN0RCxJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLHlCQUF5QixDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUM7Z0JBQzVFLHlCQUF5QixDQUFDLElBQUksQ0FBQyxlQUFlLENBQUMsQ0FBQztZQUNwRCxJQUFJLENBQUMsUUFBUSxFQUFFO2dCQUNiLE9BQU8sTUFBTSxDQUFDO2FBQ2Y7WUFDRCxtREFBbUQ7WUFDN0MsSUFBQSxLQUFzQixRQUFRLENBQUMsZ0JBQWdCLEVBQTlDLFVBQVUsZ0JBQUEsRUFBRSxLQUFLLFdBQTZCLENBQUM7O2dCQUN0RCxLQUF3QixJQUFBLGVBQUEsaUJBQUEsVUFBVSxDQUFBLHNDQUFBLDhEQUFFO29CQUEvQixJQUFNLFNBQVMsdUJBQUE7b0JBQ2xCLElBQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxRQUFRLENBQUMsaUNBQWlDLENBQUMsU0FBUyxDQUFDLFNBQVMsQ0FBQyxDQUFDO29CQUNsRixJQUFJLElBQUksRUFBRTt3QkFDUixNQUFNLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7cUJBQ25EO2lCQUNGOzs7Ozs7Ozs7O2dCQUNELEtBQW1CLElBQUEsVUFBQSxpQkFBQSxLQUFLLENBQUEsNEJBQUEsK0NBQUU7b0JBQXJCLElBQU0sSUFBSSxrQkFBQTtvQkFDYixJQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLHFCQUFxQixDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDckUsTUFBTSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7aUJBQ3pDOzs7Ozs7Ozs7WUFDRCxDQUFBLEtBQUEsTUFBTSxDQUFDLE9BQU8sQ0FBQSxDQUFDLElBQUksNEJBQUksUUFBUSxDQUFDLE9BQU8sR0FBRTtZQUN6QyxPQUFPLE1BQU0sQ0FBQztRQUNoQixDQUFDO1FBRUQ7OztXQUdHO1FBQ0gsOENBQWMsR0FBZCxVQUFlLFFBQXdCO1lBQzlCLElBQU0sV0FBVyxHQUFjLFFBQVEsS0FBdEIsRUFBRSxRQUFRLEdBQUksUUFBUSxTQUFaLENBQWE7WUFDL0MsSUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxpQ0FBaUMsQ0FBQyxXQUFXLENBQUMsQ0FBQztZQUMxRSxJQUFJLENBQUMsSUFBSSxFQUFFO2dCQUNULE9BQU87YUFDUjtZQUNELElBQU0sVUFBVSxHQUFHLElBQUkscUJBQVUsRUFBRSxDQUFDO1lBQ3BDLElBQU0sZ0JBQWdCLEdBQUcsSUFBSSxpQkFBTSxDQUFDLElBQUksZ0JBQUssRUFBRSxDQUFDLENBQUM7WUFDakQsSUFBTSxNQUFNLEdBQUcsSUFBSSx5QkFBYyxDQUM3QixJQUFJLHlCQUFjLEVBQUUsRUFBRSxJQUFJLENBQUMsU0FBUyxFQUFFLGdCQUFnQixFQUFFLElBQUksbUNBQXdCLEVBQUUsRUFDdEYsVUFBVSxFQUNWLElBQUksRUFBRyxVQUFVO1lBQ2pCLEVBQUUsQ0FBSyxZQUFZO2FBQ3RCLENBQUM7WUFDRixJQUFNLFVBQVUsR0FBRyxVQUFVLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxNQUFNLEVBQUUsUUFBUSxFQUFFO2dCQUM3RCxzQkFBc0IsRUFBRSxJQUFJO2dCQUM1QixtQkFBbUIsRUFBRSxJQUFJO2FBQzFCLENBQUMsQ0FBQztZQUNHLElBQUEsS0FBK0IsSUFBSSxDQUFDLDZCQUE2QixDQUFDLFdBQVcsQ0FBQyxFQUE3RSxVQUFVLGdCQUFBLEVBQUUsS0FBSyxXQUFBLEVBQUUsT0FBTyxhQUFtRCxDQUFDO1lBQ3JGLElBQU0sV0FBVyxHQUFHLE1BQU0sQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsVUFBVSxFQUFFLEtBQUssRUFBRSxPQUFPLENBQUMsQ0FBQztZQUMvRixJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRTtnQkFDNUIsT0FBTzthQUNSO1lBQ0QsT0FBTztnQkFDTCxPQUFPLEVBQUUsVUFBVSxDQUFDLFNBQVM7Z0JBQzdCLFdBQVcsRUFBRSxXQUFXLENBQUMsV0FBVztnQkFDcEMsU0FBUyxFQUFFLElBQUksQ0FBQyxRQUFRO2dCQUN4QixVQUFVLFlBQUE7Z0JBQ1YsS0FBSyxPQUFBO2dCQUNMLFdBQVcsRUFBRSxXQUFXLENBQUMsTUFBTTtnQkFDL0IsZ0JBQWdCLGtCQUFBO2dCQUNoQixRQUFRLFVBQUE7YUFDVCxDQUFDO1FBQ0osQ0FBQztRQUVEOzs7O1dBSUc7UUFDSCxtQ0FBRyxHQUFILFVBQUksR0FBVztZQUNiLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3JCLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ3hCO1FBQ0gsQ0FBQztRQUVEOzs7O1dBSUc7UUFDSCxxQ0FBSyxHQUFMLFVBQU0sR0FBVztZQUNmLElBQUksSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUU7Z0JBQ3ZCLElBQUksQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQzFCO1FBQ0gsQ0FBQztRQUVEOzs7O1dBSUc7UUFDSCxxQ0FBSyxHQUFMLFVBQU0sR0FBVztZQUNmLElBQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxRQUE4QixDQUFDO1lBQ3BELElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxFQUFFO2dCQUMzQiw0QkFBNEI7Z0JBQzVCLE9BQU87YUFDUjtZQUNNLElBQUEsTUFBTSxHQUFJLE9BQU8sQ0FBQyxjQUFjLE9BQTFCLENBQTJCO1lBQ3hDLElBQUksTUFBTSxDQUFDLFFBQVEsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLFFBQVEsQ0FBQyxPQUFPLENBQUMsRUFBRTtnQkFDaEQsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQzthQUNsQjtRQUNILENBQUM7UUFDSCw0QkFBQztJQUFELENBQUMsQUFwaUJELElBb2lCQztJQXBpQlksc0RBQXFCO0lBc2lCbEMsU0FBUyx5QkFBeUIsQ0FBQyxPQUEwQjs7UUFDM0QsSUFBSSxNQUFNLEdBQXNDLFNBQVMsQ0FBQztRQUMxRCxJQUFJLFVBQVUsR0FBRyxDQUFDLENBQUM7O1lBQ25CLEtBQXFCLElBQUEsS0FBQSxpQkFBQSxPQUFPLENBQUMsU0FBUyxDQUFBLGdCQUFBLDRCQUFFO2dCQUFuQyxJQUFNLFFBQU0sV0FBQTtnQkFDZixJQUFNLFVBQVUsR0FBRyxRQUFNLENBQUMsZ0JBQWdCLENBQUMsVUFBVSxDQUFDLE1BQU0sQ0FBQztnQkFDN0QsSUFBSSxVQUFVLEdBQUcsVUFBVSxFQUFFO29CQUMzQixNQUFNLEdBQUcsUUFBTSxDQUFDO29CQUNoQixVQUFVLEdBQUcsVUFBVSxDQUFDO2lCQUN6QjthQUNGOzs7Ozs7Ozs7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRUQsU0FBUyxNQUFNLENBQUMsSUFBYztRQUM1QixPQUFPLEVBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsRUFBRSxHQUFHLEVBQUUsSUFBSSxDQUFDLE1BQU0sRUFBRSxFQUFDLENBQUM7SUFDdEQsQ0FBQztJQUVELFNBQVMsTUFBTSxDQUFDLFVBQTBCLEVBQUUsSUFBWSxFQUFFLE1BQWM7UUFDdEUsSUFBSSxJQUFJLElBQUksSUFBSSxJQUFJLE1BQU0sSUFBSSxJQUFJLEVBQUU7WUFDbEMsSUFBTSxVQUFRLEdBQUcsR0FBRyxDQUFDLDZCQUE2QixDQUFDLFVBQVUsRUFBRSxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7WUFDN0UsSUFBTSxTQUFTLEdBQUcsU0FBUyxTQUFTLENBQUMsSUFBYztnQkFDakQsSUFBSSxJQUFJLENBQUMsSUFBSSxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxHQUFHLElBQUksVUFBUSxJQUFJLElBQUksQ0FBQyxHQUFHLEdBQUcsVUFBUSxFQUFFO29CQUN2RixJQUFNLFVBQVUsR0FBRyxHQUFHLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxTQUFTLENBQUMsQ0FBQztvQkFDckQsT0FBTyxVQUFVLElBQUksSUFBSSxDQUFDO2lCQUMzQjtZQUNILENBQUMsQ0FBQztZQUVGLElBQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxZQUFZLENBQUMsVUFBVSxFQUFFLFNBQVMsQ0FBQyxDQUFDO1lBQ3JELElBQUksSUFBSSxFQUFFO2dCQUNSLE9BQU8sRUFBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLFFBQVEsRUFBRSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLEVBQUMsQ0FBQzthQUNyRDtTQUNGO0lBQ0gsQ0FBQztJQUVELFNBQVMsWUFBWSxDQUFDLEtBQTRCO1FBQ2hELE9BQU8sRUFBQyxPQUFPLEVBQUUsS0FBSyxDQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUUsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsRUFBQyxDQUFDO0lBQy9GLENBQUM7SUFFRCxTQUFTLDBCQUEwQixDQUFDLEtBQXFCLEVBQUUsSUFBVTtRQUNuRSxPQUFPLEVBQUMsT0FBTyxFQUFFLEtBQUssQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFlBQVksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsSUFBSSxNQUFBLEVBQUMsQ0FBQztJQUNsRixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7YW5hbHl6ZU5nTW9kdWxlcywgQW90U3VtbWFyeVJlc29sdmVyLCBDb21waWxlRGlyZWN0aXZlU3VtbWFyeSwgQ29tcGlsZU1ldGFkYXRhUmVzb2x2ZXIsIENvbXBpbGVOZ01vZHVsZU1ldGFkYXRhLCBDb21waWxlUGlwZVN1bW1hcnksIENvbXBpbGVyQ29uZmlnLCBEaXJlY3RpdmVOb3JtYWxpemVyLCBEaXJlY3RpdmVSZXNvbHZlciwgRG9tRWxlbWVudFNjaGVtYVJlZ2lzdHJ5LCBGb3JtYXR0ZWRFcnJvciwgRm9ybWF0dGVkTWVzc2FnZUNoYWluLCBIdG1sUGFyc2VyLCBpc0Zvcm1hdHRlZEVycm9yLCBKaXRTdW1tYXJ5UmVzb2x2ZXIsIExleGVyLCBOZ0FuYWx5emVkTW9kdWxlcywgTmdNb2R1bGVSZXNvbHZlciwgUGFyc2VyLCBQYXJzZVRyZWVSZXN1bHQsIFBpcGVSZXNvbHZlciwgUmVzb3VyY2VMb2FkZXIsIFN0YXRpY1JlZmxlY3RvciwgU3RhdGljU3ltYm9sLCBTdGF0aWNTeW1ib2xDYWNoZSwgU3RhdGljU3ltYm9sUmVzb2x2ZXIsIFRlbXBsYXRlUGFyc2VyLCBVcmxSZXNvbHZlcn0gZnJvbSAnQGFuZ3VsYXIvY29tcGlsZXInO1xuaW1wb3J0IHtTY2hlbWFNZXRhZGF0YSwgVmlld0VuY2Fwc3VsYXRpb24sIMm1Q29uc29sZSBhcyBDb25zb2xlfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIHBhdGggZnJvbSAncGF0aCc7XG5pbXBvcnQgKiBhcyB0c3MgZnJvbSAndHlwZXNjcmlwdC9saWIvdHNzZXJ2ZXJsaWJyYXJ5JztcblxuaW1wb3J0IHtjcmVhdGVMYW5ndWFnZVNlcnZpY2V9IGZyb20gJy4vbGFuZ3VhZ2Vfc2VydmljZSc7XG5pbXBvcnQge1JlZmxlY3Rvckhvc3R9IGZyb20gJy4vcmVmbGVjdG9yX2hvc3QnO1xuaW1wb3J0IHtFeHRlcm5hbFRlbXBsYXRlLCBJbmxpbmVUZW1wbGF0ZX0gZnJvbSAnLi90ZW1wbGF0ZSc7XG5pbXBvcnQge2ZpbmRUaWdodGVzdE5vZGUsIGdldENsYXNzRGVjbEZyb21EZWNvcmF0b3JQcm9wLCBnZXREaXJlY3RpdmVDbGFzc0xpa2UsIGdldFByb3BlcnR5QXNzaWdubWVudEZyb21WYWx1ZX0gZnJvbSAnLi90c191dGlscyc7XG5pbXBvcnQge0FzdFJlc3VsdCwgRGVjbGFyYXRpb24sIERlY2xhcmF0aW9uRXJyb3IsIERpYWdub3N0aWNNZXNzYWdlQ2hhaW4sIExhbmd1YWdlU2VydmljZSwgTGFuZ3VhZ2VTZXJ2aWNlSG9zdCwgU3BhbiwgVGVtcGxhdGVTb3VyY2V9IGZyb20gJy4vdHlwZXMnO1xuXG4vKipcbiAqIENyZWF0ZSBhIGBMYW5ndWFnZVNlcnZpY2VIb3N0YFxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlTGFuZ3VhZ2VTZXJ2aWNlRnJvbVR5cGVzY3JpcHQoXG4gICAgaG9zdDogdHNzLkxhbmd1YWdlU2VydmljZUhvc3QsIHNlcnZpY2U6IHRzcy5MYW5ndWFnZVNlcnZpY2UpOiBMYW5ndWFnZVNlcnZpY2Uge1xuICBjb25zdCBuZ0hvc3QgPSBuZXcgVHlwZVNjcmlwdFNlcnZpY2VIb3N0KGhvc3QsIHNlcnZpY2UpO1xuICBjb25zdCBuZ1NlcnZlciA9IGNyZWF0ZUxhbmd1YWdlU2VydmljZShuZ0hvc3QpO1xuICByZXR1cm4gbmdTZXJ2ZXI7XG59XG5cbi8qKlxuICogVGhlIGxhbmd1YWdlIHNlcnZpY2UgbmV2ZXIgbmVlZHMgdGhlIG5vcm1hbGl6ZWQgdmVyc2lvbnMgb2YgdGhlIG1ldGFkYXRhLiBUbyBhdm9pZCBwYXJzaW5nXG4gKiB0aGUgY29udGVudCBhbmQgcmVzb2x2aW5nIHJlZmVyZW5jZXMsIHJldHVybiBhbiBlbXB0eSBmaWxlLiBUaGlzIGFsc28gYWxsb3dzIG5vcm1hbGl6aW5nXG4gKiB0ZW1wbGF0ZSB0aGF0IGFyZSBzeW50YXRpY2FsbHkgaW5jb3JyZWN0IHdoaWNoIGlzIHJlcXVpcmVkIHRvIHByb3ZpZGUgY29tcGxldGlvbnMgaW5cbiAqIHN5bnRhY3RpY2FsbHkgaW5jb3JyZWN0IHRlbXBsYXRlcy5cbiAqL1xuZXhwb3J0IGNsYXNzIER1bW15SHRtbFBhcnNlciBleHRlbmRzIEh0bWxQYXJzZXIge1xuICBwYXJzZSgpOiBQYXJzZVRyZWVSZXN1bHQge1xuICAgIHJldHVybiBuZXcgUGFyc2VUcmVlUmVzdWx0KFtdLCBbXSk7XG4gIH1cbn1cblxuLyoqXG4gKiBBdm9pZCBsb2FkaW5nIHJlc291cmNlcyBpbiB0aGUgbGFuZ3VhZ2Ugc2VydmNpZSBieSB1c2luZyBhIGR1bW15IGxvYWRlci5cbiAqL1xuZXhwb3J0IGNsYXNzIER1bW15UmVzb3VyY2VMb2FkZXIgZXh0ZW5kcyBSZXNvdXJjZUxvYWRlciB7XG4gIGdldChfdXJsOiBzdHJpbmcpOiBQcm9taXNlPHN0cmluZz4ge1xuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoJycpO1xuICB9XG59XG5cbi8qKlxuICogQW4gaW1wbGVtZW50YXRpb24gb2YgYSBgTGFuZ3VhZ2VTZXJ2aWNlSG9zdGAgZm9yIGEgVHlwZVNjcmlwdCBwcm9qZWN0LlxuICpcbiAqIFRoZSBgVHlwZVNjcmlwdFNlcnZpY2VIb3N0YCBpbXBsZW1lbnRzIHRoZSBBbmd1bGFyIGBMYW5ndWFnZVNlcnZpY2VIb3N0YCB1c2luZ1xuICogdGhlIFR5cGVTY3JpcHQgbGFuZ3VhZ2Ugc2VydmljZXMuXG4gKlxuICogQHB1YmxpY0FwaVxuICovXG5leHBvcnQgY2xhc3MgVHlwZVNjcmlwdFNlcnZpY2VIb3N0IGltcGxlbWVudHMgTGFuZ3VhZ2VTZXJ2aWNlSG9zdCB7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3VtbWFyeVJlc29sdmVyOiBBb3RTdW1tYXJ5UmVzb2x2ZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVmbGVjdG9ySG9zdDogUmVmbGVjdG9ySG9zdDtcbiAgcHJpdmF0ZSByZWFkb25seSBzdGF0aWNTeW1ib2xSZXNvbHZlcjogU3RhdGljU3ltYm9sUmVzb2x2ZXI7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBzdGF0aWNTeW1ib2xDYWNoZSA9IG5ldyBTdGF0aWNTeW1ib2xDYWNoZSgpO1xuICBwcml2YXRlIHJlYWRvbmx5IGZpbGVUb0NvbXBvbmVudCA9IG5ldyBNYXA8c3RyaW5nLCBTdGF0aWNTeW1ib2w+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgY29sbGVjdGVkRXJyb3JzID0gbmV3IE1hcDxzdHJpbmcsIGFueVtdPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGZpbGVWZXJzaW9ucyA9IG5ldyBNYXA8c3RyaW5nLCBzdHJpbmc+KCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgdXJsUmVzb2x2ZXI6IFVybFJlc29sdmVyO1xuXG4gIHByaXZhdGUgbGFzdFByb2dyYW06IHRzcy5Qcm9ncmFtfHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgcHJpdmF0ZSBhbmFseXplZE1vZHVsZXM6IE5nQW5hbHl6ZWRNb2R1bGVzID0ge1xuICAgIGZpbGVzOiBbXSxcbiAgICBuZ01vZHVsZUJ5UGlwZU9yRGlyZWN0aXZlOiBuZXcgTWFwKCksXG4gICAgbmdNb2R1bGVzOiBbXSxcbiAgfTtcblxuICBjb25zdHJ1Y3RvcihyZWFkb25seSB0c0xzSG9zdDogdHNzLkxhbmd1YWdlU2VydmljZUhvc3QsIHJlYWRvbmx5IHRzTFM6IHRzcy5MYW5ndWFnZVNlcnZpY2UpIHtcbiAgICB0aGlzLnN1bW1hcnlSZXNvbHZlciA9IG5ldyBBb3RTdW1tYXJ5UmVzb2x2ZXIoXG4gICAgICAgIHtcbiAgICAgICAgICBsb2FkU3VtbWFyeShfZmlsZVBhdGg6IHN0cmluZykge1xuICAgICAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICAgICAgfSxcbiAgICAgICAgICBpc1NvdXJjZUZpbGUoX3NvdXJjZUZpbGVQYXRoOiBzdHJpbmcpIHtcbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgdG9TdW1tYXJ5RmlsZU5hbWUoc291cmNlRmlsZVBhdGg6IHN0cmluZykge1xuICAgICAgICAgICAgcmV0dXJuIHNvdXJjZUZpbGVQYXRoO1xuICAgICAgICAgIH0sXG4gICAgICAgICAgZnJvbVN1bW1hcnlGaWxlTmFtZShmaWxlUGF0aDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICAgICAgICAgIHJldHVybiBmaWxlUGF0aDtcbiAgICAgICAgICB9LFxuICAgICAgICB9LFxuICAgICAgICB0aGlzLnN0YXRpY1N5bWJvbENhY2hlKTtcbiAgICB0aGlzLnJlZmxlY3Rvckhvc3QgPSBuZXcgUmVmbGVjdG9ySG9zdCgoKSA9PiB0aGlzLnByb2dyYW0sIHRzTHNIb3N0KTtcbiAgICB0aGlzLnN0YXRpY1N5bWJvbFJlc29sdmVyID0gbmV3IFN0YXRpY1N5bWJvbFJlc29sdmVyKFxuICAgICAgICB0aGlzLnJlZmxlY3Rvckhvc3QsIHRoaXMuc3RhdGljU3ltYm9sQ2FjaGUsIHRoaXMuc3VtbWFyeVJlc29sdmVyLFxuICAgICAgICAoZSwgZmlsZVBhdGgpID0+IHRoaXMuY29sbGVjdEVycm9yKGUsIGZpbGVQYXRoKSk7XG4gICAgdGhpcy51cmxSZXNvbHZlciA9IHtcbiAgICAgIHJlc29sdmU6IChiYXNlVXJsOiBzdHJpbmcsIHVybDogc3RyaW5nKSA9PiB7XG4gICAgICAgIC8vIEluIHByYWN0aWNlLCBgZGlyZWN0b3J5RXhpc3RzYCBpcyBhbHdheXMgZGVmaW5lZC5cbiAgICAgICAgLy8gaHR0cHM6Ly9naXRodWIuY29tL21pY3Jvc29mdC9UeXBlU2NyaXB0L2Jsb2IvMGI2YzkyNTRhODUwZGQwNzA1NjI1OWQ0ZWVmY2E3NzIxNzQ1YWY3NS9zcmMvc2VydmVyL3Byb2plY3QudHMjTDE2MDgtTDE2MTRcbiAgICAgICAgaWYgKHRzTHNIb3N0LmRpcmVjdG9yeUV4aXN0cyEoYmFzZVVybCkpIHtcbiAgICAgICAgICByZXR1cm4gcGF0aC5yZXNvbHZlKGJhc2VVcmwsIHVybCk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIHBhdGgucmVzb2x2ZShwYXRoLmRpcm5hbWUoYmFzZVVybCksIHVybCk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8vIFRoZSByZXNvbHZlciBpcyBpbnN0YW50aWF0ZWQgbGF6aWx5IGFuZCBzaG91bGQgbm90IGJlIGFjY2Vzc2VkIGRpcmVjdGx5LlxuICAvLyBJbnN0ZWFkLCBjYWxsIHRoZSByZXNvbHZlciBnZXR0ZXIuIFRoZSBpbnN0YW50aWF0aW9uIG9mIHRoZSByZXNvbHZlciBhbHNvXG4gIC8vIHJlcXVpcmVzIGluc3RhbnRpYXRpb24gb2YgdGhlIFN0YXRpY1JlZmxlY3RvciwgYW5kIHRoZSBsYXR0ZXIgcmVxdWlyZXNcbiAgLy8gcmVzb2x1dGlvbiBvZiBjb3JlIEFuZ3VsYXIgc3ltYm9scy4gTW9kdWxlIHJlc29sdXRpb24gc2hvdWxkIG5vdCBiZSBkb25lXG4gIC8vIGR1cmluZyBpbnN0YW50aWF0aW9uIHRvIGF2b2lkIGN5Y2xpYyBkZXBlbmRlbmN5IGJldHdlZW4gdGhlIHBsdWdpbiBhbmQgdGhlXG4gIC8vIGNvbnRhaW5pbmcgUHJvamVjdCwgc28gdGhlIFNpbmdsZXRvbiBwYXR0ZXJuIGlzIHVzZWQgaGVyZS5cbiAgcHJpdmF0ZSBfcmVzb2x2ZXI6IENvbXBpbGVNZXRhZGF0YVJlc29sdmVyfHVuZGVmaW5lZDtcblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBzaW5nbGV0b24gaW5zdGFuY2Ugb2YgdGhlIE1ldGFkYXRhUmVzb2x2ZXIuXG4gICAqL1xuICBwcml2YXRlIGdldCByZXNvbHZlcigpOiBDb21waWxlTWV0YWRhdGFSZXNvbHZlciB7XG4gICAgaWYgKHRoaXMuX3Jlc29sdmVyKSB7XG4gICAgICByZXR1cm4gdGhpcy5fcmVzb2x2ZXI7XG4gICAgfVxuICAgIC8vIFN0YXRpY1JlZmxlY3RvciBrZWVwcyBpdHMgb3duIHByaXZhdGUgY2FjaGVzIHRoYXQgYXJlIG5vdCBjbGVhcmFibGUuXG4gICAgLy8gV2UgaGF2ZSBubyBjaG9pY2UgYnV0IHRvIGNyZWF0ZSBhIG5ldyBpbnN0YW5jZSB0byBpbnZhbGlkYXRlIHRoZSBjYWNoZXMuXG4gICAgLy8gVE9ETzogUmV2aXNpdCB0aGlzIHdoZW4gbGFuZ3VhZ2Ugc2VydmljZSBnZXRzIHJld3JpdHRlbiBmb3IgSXZ5LlxuICAgIGNvbnN0IHN0YXRpY1JlZmxlY3RvciA9IG5ldyBTdGF0aWNSZWZsZWN0b3IoXG4gICAgICAgIHRoaXMuc3VtbWFyeVJlc29sdmVyLCB0aGlzLnN0YXRpY1N5bWJvbFJlc29sdmVyLFxuICAgICAgICBbXSwgIC8vIGtub3duTWV0YWRhdGFDbGFzc2VzXG4gICAgICAgIFtdLCAgLy8ga25vd25NZXRhZGF0YUZ1bmN0aW9uc1xuICAgICAgICAoZSwgZmlsZVBhdGgpID0+IHRoaXMuY29sbGVjdEVycm9yKGUsIGZpbGVQYXRoKSk7XG4gICAgLy8gQmVjYXVzZSBzdGF0aWMgcmVmbGVjdG9yIGFib3ZlIGlzIGNoYW5nZWQsIHdlIG5lZWQgdG8gY3JlYXRlIGEgbmV3XG4gICAgLy8gcmVzb2x2ZXIuXG4gICAgY29uc3QgbW9kdWxlUmVzb2x2ZXIgPSBuZXcgTmdNb2R1bGVSZXNvbHZlcihzdGF0aWNSZWZsZWN0b3IpO1xuICAgIGNvbnN0IGRpcmVjdGl2ZVJlc29sdmVyID0gbmV3IERpcmVjdGl2ZVJlc29sdmVyKHN0YXRpY1JlZmxlY3Rvcik7XG4gICAgY29uc3QgcGlwZVJlc29sdmVyID0gbmV3IFBpcGVSZXNvbHZlcihzdGF0aWNSZWZsZWN0b3IpO1xuICAgIGNvbnN0IGVsZW1lbnRTY2hlbWFSZWdpc3RyeSA9IG5ldyBEb21FbGVtZW50U2NoZW1hUmVnaXN0cnkoKTtcbiAgICBjb25zdCByZXNvdXJjZUxvYWRlciA9IG5ldyBEdW1teVJlc291cmNlTG9hZGVyKCk7XG4gICAgY29uc3QgaHRtbFBhcnNlciA9IG5ldyBEdW1teUh0bWxQYXJzZXIoKTtcbiAgICAvLyBUaGlzIHRyYWNrcyB0aGUgQ29tcGlsZUNvbmZpZyBpbiBjb2RlZ2VuLnRzLiBDdXJyZW50bHkgdGhlc2Ugb3B0aW9uc1xuICAgIC8vIGFyZSBoYXJkLWNvZGVkLlxuICAgIGNvbnN0IGNvbmZpZyA9IG5ldyBDb21waWxlckNvbmZpZyh7XG4gICAgICBkZWZhdWx0RW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uRW11bGF0ZWQsXG4gICAgICB1c2VKaXQ6IGZhbHNlLFxuICAgIH0pO1xuICAgIGNvbnN0IGRpcmVjdGl2ZU5vcm1hbGl6ZXIgPVxuICAgICAgICBuZXcgRGlyZWN0aXZlTm9ybWFsaXplcihyZXNvdXJjZUxvYWRlciwgdGhpcy51cmxSZXNvbHZlciwgaHRtbFBhcnNlciwgY29uZmlnKTtcbiAgICB0aGlzLl9yZXNvbHZlciA9IG5ldyBDb21waWxlTWV0YWRhdGFSZXNvbHZlcihcbiAgICAgICAgY29uZmlnLCBodG1sUGFyc2VyLCBtb2R1bGVSZXNvbHZlciwgZGlyZWN0aXZlUmVzb2x2ZXIsIHBpcGVSZXNvbHZlcixcbiAgICAgICAgbmV3IEppdFN1bW1hcnlSZXNvbHZlcigpLCBlbGVtZW50U2NoZW1hUmVnaXN0cnksIGRpcmVjdGl2ZU5vcm1hbGl6ZXIsIG5ldyBDb25zb2xlKCksXG4gICAgICAgIHRoaXMuc3RhdGljU3ltYm9sQ2FjaGUsIHN0YXRpY1JlZmxlY3RvcixcbiAgICAgICAgKGVycm9yLCB0eXBlKSA9PiB0aGlzLmNvbGxlY3RFcnJvcihlcnJvciwgdHlwZSAmJiB0eXBlLmZpbGVQYXRoKSk7XG4gICAgcmV0dXJuIHRoaXMuX3Jlc29sdmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgc2luZ2xldG9uIGluc3RhbmNlIG9mIHRoZSBTdGF0aWNSZWZsZWN0b3IgaG9zdGVkIGluIHRoZVxuICAgKiBNZXRhZGF0YVJlc29sdmVyLlxuICAgKi9cbiAgcHJpdmF0ZSBnZXQgcmVmbGVjdG9yKCk6IFN0YXRpY1JlZmxlY3RvciB7XG4gICAgcmV0dXJuIHRoaXMucmVzb2x2ZXIuZ2V0UmVmbGVjdG9yKCkgYXMgU3RhdGljUmVmbGVjdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiBhbGwga25vd24gZXh0ZXJuYWwgdGVtcGxhdGVzLlxuICAgKi9cbiAgZ2V0RXh0ZXJuYWxUZW1wbGF0ZXMoKTogc3RyaW5nW10ge1xuICAgIHJldHVybiBbLi4udGhpcy5maWxlVG9Db21wb25lbnQua2V5cygpXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3Mgd2hldGhlciB0aGUgcHJvZ3JhbSBoYXMgY2hhbmdlZCBhbmQgcmV0dXJucyBhbGwgYW5hbHl6ZWQgbW9kdWxlcy5cbiAgICogSWYgcHJvZ3JhbSBoYXMgY2hhbmdlZCwgaW52YWxpZGF0ZSBhbGwgY2FjaGVzIGFuZCB1cGRhdGUgZmlsZVRvQ29tcG9uZW50XG4gICAqIGFuZCB0ZW1wbGF0ZVJlZmVyZW5jZXMuXG4gICAqIEluIGFkZGl0aW9uIHRvIHJldHVybmluZyBpbmZvcm1hdGlvbiBhYm91dCBOZ01vZHVsZXMsIHRoaXMgbWV0aG9kIHBsYXlzIHRoZVxuICAgKiBzYW1lIHJvbGUgYXMgJ3N5bmNocm9uaXplSG9zdERhdGEnIGluIHRzc2VydmVyLlxuICAgKi9cbiAgZ2V0QW5hbHl6ZWRNb2R1bGVzKCk6IE5nQW5hbHl6ZWRNb2R1bGVzIHtcbiAgICBpZiAodGhpcy51cFRvRGF0ZSgpKSB7XG4gICAgICByZXR1cm4gdGhpcy5hbmFseXplZE1vZHVsZXM7XG4gICAgfVxuXG4gICAgLy8gSW52YWxpZGF0ZSBjYWNoZXNcbiAgICB0aGlzLmZpbGVUb0NvbXBvbmVudC5jbGVhcigpO1xuICAgIHRoaXMuY29sbGVjdGVkRXJyb3JzLmNsZWFyKCk7XG4gICAgdGhpcy5yZXNvbHZlci5jbGVhckNhY2hlKCk7XG5cbiAgICBjb25zdCBhbmFseXplSG9zdCA9IHtcbiAgICAgIGlzU291cmNlRmlsZShfZmlsZVBhdGg6IHN0cmluZykge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGNvbnN0IHByb2dyYW1GaWxlcyA9IHRoaXMucHJvZ3JhbS5nZXRTb3VyY2VGaWxlcygpLm1hcChzZiA9PiBzZi5maWxlTmFtZSk7XG5cbiAgICB0cnkge1xuICAgICAgdGhpcy5hbmFseXplZE1vZHVsZXMgPVxuICAgICAgICAgIGFuYWx5emVOZ01vZHVsZXMocHJvZ3JhbUZpbGVzLCBhbmFseXplSG9zdCwgdGhpcy5zdGF0aWNTeW1ib2xSZXNvbHZlciwgdGhpcy5yZXNvbHZlcik7XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgLy8gQW5hbHl6aW5nIG1vZHVsZXMgbWF5IHRocm93OyBpbiB0aGF0IGNhc2UsIHJldXNlIHRoZSBvbGQgbW9kdWxlcy5cbiAgICAgIHRoaXMuZXJyb3IoYEFuYWx5emluZyBOZ01vZHVsZXMgZmFpbGVkLiAke2V9YCk7XG4gICAgICByZXR1cm4gdGhpcy5hbmFseXplZE1vZHVsZXM7XG4gICAgfVxuXG4gICAgLy8gdXBkYXRlIHRlbXBsYXRlIHJlZmVyZW5jZXMgYW5kIGZpbGVUb0NvbXBvbmVudFxuICAgIGZvciAoY29uc3QgbmdNb2R1bGUgb2YgdGhpcy5hbmFseXplZE1vZHVsZXMubmdNb2R1bGVzKSB7XG4gICAgICBmb3IgKGNvbnN0IGRpcmVjdGl2ZSBvZiBuZ01vZHVsZS5kZWNsYXJlZERpcmVjdGl2ZXMpIHtcbiAgICAgICAgY29uc3Qge21ldGFkYXRhfSA9IHRoaXMucmVzb2x2ZXIuZ2V0Tm9uTm9ybWFsaXplZERpcmVjdGl2ZU1ldGFkYXRhKGRpcmVjdGl2ZS5yZWZlcmVuY2UpITtcbiAgICAgICAgaWYgKG1ldGFkYXRhLmlzQ29tcG9uZW50ICYmIG1ldGFkYXRhLnRlbXBsYXRlICYmIG1ldGFkYXRhLnRlbXBsYXRlLnRlbXBsYXRlVXJsKSB7XG4gICAgICAgICAgY29uc3QgdGVtcGxhdGVOYW1lID0gdGhpcy51cmxSZXNvbHZlci5yZXNvbHZlKFxuICAgICAgICAgICAgICB0aGlzLnJlZmxlY3Rvci5jb21wb25lbnRNb2R1bGVVcmwoZGlyZWN0aXZlLnJlZmVyZW5jZSksXG4gICAgICAgICAgICAgIG1ldGFkYXRhLnRlbXBsYXRlLnRlbXBsYXRlVXJsKTtcbiAgICAgICAgICB0aGlzLmZpbGVUb0NvbXBvbmVudC5zZXQodGVtcGxhdGVOYW1lLCBkaXJlY3RpdmUucmVmZXJlbmNlKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmFuYWx5emVkTW9kdWxlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVja3Mgd2hldGhlciB0aGUgcHJvZ3JhbSBoYXMgY2hhbmdlZCwgYW5kIGludmFsaWRhdGUgc3RhdGljIHN5bWJvbHMgaW5cbiAgICogdGhlIHNvdXJjZSBmaWxlcyB0aGF0IGhhdmUgY2hhbmdlZC5cbiAgICogUmV0dXJucyB0cnVlIGlmIG1vZHVsZXMgYXJlIHVwLXRvLWRhdGUsIGZhbHNlIG90aGVyd2lzZS5cbiAgICogVGhpcyBzaG91bGQgb25seSBiZSBjYWxsZWQgYnkgZ2V0QW5hbHl6ZWRNb2R1bGVzKCkuXG4gICAqL1xuICBwcml2YXRlIHVwVG9EYXRlKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHtsYXN0UHJvZ3JhbSwgcHJvZ3JhbX0gPSB0aGlzO1xuICAgIGlmIChsYXN0UHJvZ3JhbSA9PT0gcHJvZ3JhbSkge1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHRoaXMubGFzdFByb2dyYW0gPSBwcm9ncmFtO1xuXG4gICAgLy8gRXZlbiB0aG91Z2ggdGhlIHByb2dyYW0gaGFzIGNoYW5nZWQsIGl0IGNvdWxkIGJlIHRoZSBjYXNlIHRoYXQgbm9uZSBvZlxuICAgIC8vIHRoZSBzb3VyY2UgZmlsZXMgaGF2ZSBjaGFuZ2VkLiBJZiBhbGwgc291cmNlIGZpbGVzIHJlbWFpbiB0aGUgc2FtZSwgdGhlblxuICAgIC8vIHByb2dyYW0gaXMgc3RpbGwgdXAtdG8tZGF0ZSwgYW5kIHdlIHNob3VsZCBub3QgaW52YWxpZGF0ZSBjYWNoZXMuXG4gICAgbGV0IGZpbGVzQWRkZWQgPSAwO1xuICAgIGNvbnN0IGZpbGVzQ2hhbmdlZE9yUmVtb3ZlZDogc3RyaW5nW10gPSBbXTtcblxuICAgIC8vIENoZWNrIGlmIGFueSBzb3VyY2UgZmlsZXMgaGF2ZSBiZWVuIGFkZGVkIC8gY2hhbmdlZCBzaW5jZSBsYXN0IGNvbXB1dGF0aW9uLlxuICAgIGNvbnN0IHNlZW4gPSBuZXcgU2V0PHN0cmluZz4oKTtcbiAgICBjb25zdCBBTkdVTEFSX0NPUkUgPSAnQGFuZ3VsYXIvY29yZSc7XG4gICAgY29uc3QgY29yZVBhdGggPSB0aGlzLnJlZmxlY3Rvckhvc3QubW9kdWxlTmFtZVRvRmlsZU5hbWUoQU5HVUxBUl9DT1JFKTtcbiAgICBmb3IgKGNvbnN0IHtmaWxlTmFtZX0gb2YgcHJvZ3JhbS5nZXRTb3VyY2VGaWxlcygpKSB7XG4gICAgICAvLyBJZiBgQGFuZ3VsYXIvY29yZWAgaXMgZWRpdGVkLCB0aGUgbGFuZ3VhZ2Ugc2VydmljZSB3b3VsZCBoYXZlIHRvIGJlXG4gICAgICAvLyByZXN0YXJ0ZWQsIHNvIGlnbm9yZSBjaGFuZ2VzIHRvIGBAYW5ndWxhci9jb3JlYC5cbiAgICAgIC8vIFdoZW4gdGhlIFN0YXRpY1JlZmxlY3RvciBpcyBpbml0aWFsaXplZCBhdCBzdGFydHVwLCBpdCBsb2FkcyBjb3JlXG4gICAgICAvLyBzeW1ib2xzIGZyb20gQGFuZ3VsYXIvY29yZSBieSBjYWxsaW5nIGluaXRpYWxpemVDb252ZXJzaW9uTWFwKCkuIFRoaXNcbiAgICAgIC8vIGlzIG9ubHkgZG9uZSBvbmNlLiBJZiB0aGUgZmlsZSBpcyBpbnZhbGlkYXRlZCwgc29tZSBvZiB0aGUgY29yZSBzeW1ib2xzXG4gICAgICAvLyB3aWxsIGJlIGxvc3QgcGVybWFuZW50bHkuXG4gICAgICBpZiAoZmlsZU5hbWUgPT09IGNvcmVQYXRoKSB7XG4gICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgc2Vlbi5hZGQoZmlsZU5hbWUpO1xuICAgICAgY29uc3QgdmVyc2lvbiA9IHRoaXMudHNMc0hvc3QuZ2V0U2NyaXB0VmVyc2lvbihmaWxlTmFtZSk7XG4gICAgICBjb25zdCBsYXN0VmVyc2lvbiA9IHRoaXMuZmlsZVZlcnNpb25zLmdldChmaWxlTmFtZSk7XG4gICAgICBpZiAobGFzdFZlcnNpb24gPT09IHVuZGVmaW5lZCkge1xuICAgICAgICBmaWxlc0FkZGVkKys7XG4gICAgICAgIHRoaXMuZmlsZVZlcnNpb25zLnNldChmaWxlTmFtZSwgdmVyc2lvbik7XG4gICAgICB9IGVsc2UgaWYgKHZlcnNpb24gIT09IGxhc3RWZXJzaW9uKSB7XG4gICAgICAgIGZpbGVzQ2hhbmdlZE9yUmVtb3ZlZC5wdXNoKGZpbGVOYW1lKTsgIC8vIGNoYW5nZWRcbiAgICAgICAgdGhpcy5maWxlVmVyc2lvbnMuc2V0KGZpbGVOYW1lLCB2ZXJzaW9uKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBDaGVjayBpZiBhbnkgc291cmNlIGZpbGVzIGhhdmUgYmVlbiByZW1vdmVkIHNpbmNlIGxhc3QgY29tcHV0YXRpb24uXG4gICAgZm9yIChjb25zdCBbZmlsZU5hbWVdIG9mIHRoaXMuZmlsZVZlcnNpb25zKSB7XG4gICAgICBpZiAoIXNlZW4uaGFzKGZpbGVOYW1lKSkge1xuICAgICAgICBmaWxlc0NoYW5nZWRPclJlbW92ZWQucHVzaChmaWxlTmFtZSk7ICAvLyByZW1vdmVkXG4gICAgICAgIC8vIEJlY2F1c2UgTWFwcyBhcmUgaXRlcmF0ZWQgaW4gaW5zZXJ0aW9uIG9yZGVyLCBpdCBpcyBzYWZlIHRvIGRlbGV0ZVxuICAgICAgICAvLyBlbnRyaWVzIGZyb20gdGhlIHNhbWUgbWFwIHdoaWxlIGl0ZXJhdGluZy5cbiAgICAgICAgLy8gU2VlIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vcXVlc3Rpb25zLzM1OTQwMjE2IGFuZFxuICAgICAgICAvLyBodHRwczovL3d3dy5lY21hLWludGVybmF0aW9uYWwub3JnL2VjbWEtMjYyLzEwLjAvaW5kZXguaHRtbCNzZWMtbWFwLnByb3RvdHlwZS5mb3JlYWNoXG4gICAgICAgIHRoaXMuZmlsZVZlcnNpb25zLmRlbGV0ZShmaWxlTmFtZSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZm9yIChjb25zdCBmaWxlTmFtZSBvZiBmaWxlc0NoYW5nZWRPclJlbW92ZWQpIHtcbiAgICAgIGNvbnN0IHN5bWJvbHMgPSB0aGlzLnN0YXRpY1N5bWJvbFJlc29sdmVyLmludmFsaWRhdGVGaWxlKGZpbGVOYW1lKTtcbiAgICAgIHRoaXMucmVmbGVjdG9yLmludmFsaWRhdGVTeW1ib2xzKHN5bWJvbHMpO1xuICAgIH1cblxuICAgIC8vIFByb2dyYW0gaXMgdXAtdG8tZGF0ZSBpZmYgbm8gZmlsZXMgYXJlIGFkZGVkLCBjaGFuZ2VkLCBvciByZW1vdmVkLlxuICAgIHJldHVybiBmaWxlc0FkZGVkID09PSAwICYmIGZpbGVzQ2hhbmdlZE9yUmVtb3ZlZC5sZW5ndGggPT09IDA7XG4gIH1cblxuICAvKipcbiAgICogRmluZCBhbGwgdGVtcGxhdGVzIGluIHRoZSBzcGVjaWZpZWQgYGZpbGVgLlxuICAgKiBAcGFyYW0gZmlsZU5hbWUgVFMgb3IgSFRNTCBmaWxlXG4gICAqL1xuICBnZXRUZW1wbGF0ZXMoZmlsZU5hbWU6IHN0cmluZyk6IFRlbXBsYXRlU291cmNlW10ge1xuICAgIGNvbnN0IHJlc3VsdHM6IFRlbXBsYXRlU291cmNlW10gPSBbXTtcbiAgICBpZiAoZmlsZU5hbWUuZW5kc1dpdGgoJy50cycpKSB7XG4gICAgICAvLyBGaW5kIGV2ZXJ5IHRlbXBsYXRlIHN0cmluZyBpbiB0aGUgZmlsZVxuICAgICAgY29uc3QgdmlzaXQgPSAoY2hpbGQ6IHRzcy5Ob2RlKSA9PiB7XG4gICAgICAgIGNvbnN0IHRlbXBsYXRlID0gdGhpcy5nZXRJbnRlcm5hbFRlbXBsYXRlKGNoaWxkKTtcbiAgICAgICAgaWYgKHRlbXBsYXRlKSB7XG4gICAgICAgICAgcmVzdWx0cy5wdXNoKHRlbXBsYXRlKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0c3MuZm9yRWFjaENoaWxkKGNoaWxkLCB2aXNpdCk7XG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgICBjb25zdCBzb3VyY2VGaWxlID0gdGhpcy5nZXRTb3VyY2VGaWxlKGZpbGVOYW1lKTtcbiAgICAgIGlmIChzb3VyY2VGaWxlKSB7XG4gICAgICAgIHRzcy5mb3JFYWNoQ2hpbGQoc291cmNlRmlsZSwgdmlzaXQpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCB0ZW1wbGF0ZSA9IHRoaXMuZ2V0RXh0ZXJuYWxUZW1wbGF0ZShmaWxlTmFtZSk7XG4gICAgICBpZiAodGVtcGxhdGUpIHtcbiAgICAgICAgcmVzdWx0cy5wdXNoKHRlbXBsYXRlKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdHM7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIG1ldGFkYXRhIGFib3V0IGFsbCBjbGFzcyBkZWNsYXJhdGlvbnMgaW4gdGhlIGZpbGUgdGhhdCBhcmUgQW5ndWxhclxuICAgKiBkaXJlY3RpdmVzLiBQb3RlbnRpYWwgbWF0Y2hlcyBhcmUgYEBOZ01vZHVsZWAsIGBAQ29tcG9uZW50YCwgYEBEaXJlY3RpdmVgLFxuICAgKiBgQFBpcGVzYCwgZXRjLiBjbGFzcyBkZWNsYXJhdGlvbnMuXG4gICAqXG4gICAqIEBwYXJhbSBmaWxlTmFtZSBUUyBmaWxlXG4gICAqL1xuICBnZXREZWNsYXJhdGlvbnMoZmlsZU5hbWU6IHN0cmluZyk6IERlY2xhcmF0aW9uW10ge1xuICAgIGlmICghZmlsZU5hbWUuZW5kc1dpdGgoJy50cycpKSB7XG4gICAgICByZXR1cm4gW107XG4gICAgfVxuICAgIGNvbnN0IHNvdXJjZUZpbGUgPSB0aGlzLmdldFNvdXJjZUZpbGUoZmlsZU5hbWUpO1xuICAgIGlmICghc291cmNlRmlsZSkge1xuICAgICAgcmV0dXJuIFtdO1xuICAgIH1cbiAgICBjb25zdCByZXN1bHRzOiBEZWNsYXJhdGlvbltdID0gW107XG4gICAgY29uc3QgdmlzaXQgPSAoY2hpbGQ6IHRzcy5Ob2RlKSA9PiB7XG4gICAgICBjb25zdCBjYW5kaWRhdGUgPSBnZXREaXJlY3RpdmVDbGFzc0xpa2UoY2hpbGQpO1xuICAgICAgaWYgKGNhbmRpZGF0ZSkge1xuICAgICAgICBjb25zdCB7Y2xhc3NJZH0gPSBjYW5kaWRhdGU7XG4gICAgICAgIGNvbnN0IGRlY2xhcmF0aW9uU3BhbiA9IHNwYW5PZihjbGFzc0lkKTtcbiAgICAgICAgY29uc3QgY2xhc3NOYW1lID0gY2xhc3NJZC5nZXRUZXh0KCk7XG4gICAgICAgIGNvbnN0IGNsYXNzU3ltYm9sID0gdGhpcy5yZWZsZWN0b3IuZ2V0U3RhdGljU3ltYm9sKHNvdXJjZUZpbGUuZmlsZU5hbWUsIGNsYXNzTmFtZSk7XG4gICAgICAgIC8vIEFzayB0aGUgcmVzb2x2ZXIgdG8gY2hlY2sgaWYgY2FuZGlkYXRlIGlzIGFjdHVhbGx5IEFuZ3VsYXIgZGlyZWN0aXZlXG4gICAgICAgIGlmICghdGhpcy5yZXNvbHZlci5pc0RpcmVjdGl2ZShjbGFzc1N5bWJvbCkpIHtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgZGF0YSA9IHRoaXMucmVzb2x2ZXIuZ2V0Tm9uTm9ybWFsaXplZERpcmVjdGl2ZU1ldGFkYXRhKGNsYXNzU3ltYm9sKTtcbiAgICAgICAgaWYgKCFkYXRhKSB7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIHJlc3VsdHMucHVzaCh7XG4gICAgICAgICAgdHlwZTogY2xhc3NTeW1ib2wsXG4gICAgICAgICAgZGVjbGFyYXRpb25TcGFuLFxuICAgICAgICAgIG1ldGFkYXRhOiBkYXRhLm1ldGFkYXRhLFxuICAgICAgICAgIGVycm9yczogdGhpcy5nZXRDb2xsZWN0ZWRFcnJvcnMoZGVjbGFyYXRpb25TcGFuLCBzb3VyY2VGaWxlKSxcbiAgICAgICAgfSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjaGlsZC5mb3JFYWNoQ2hpbGQodmlzaXQpO1xuICAgICAgfVxuICAgIH07XG4gICAgdHNzLmZvckVhY2hDaGlsZChzb3VyY2VGaWxlLCB2aXNpdCk7XG5cbiAgICByZXR1cm4gcmVzdWx0cztcbiAgfVxuXG4gIGdldFNvdXJjZUZpbGUoZmlsZU5hbWU6IHN0cmluZyk6IHRzcy5Tb3VyY2VGaWxlfHVuZGVmaW5lZCB7XG4gICAgaWYgKCFmaWxlTmFtZS5lbmRzV2l0aCgnLnRzJykpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgTm9uLVRTIHNvdXJjZSBmaWxlIHJlcXVlc3RlZDogJHtmaWxlTmFtZX1gKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucHJvZ3JhbS5nZXRTb3VyY2VGaWxlKGZpbGVOYW1lKTtcbiAgfVxuXG4gIGdldCBwcm9ncmFtKCk6IHRzcy5Qcm9ncmFtIHtcbiAgICBjb25zdCBwcm9ncmFtID0gdGhpcy50c0xTLmdldFByb2dyYW0oKTtcbiAgICBpZiAoIXByb2dyYW0pIHtcbiAgICAgIC8vIFByb2dyYW0gaXMgdmVyeSB2ZXJ5IHVubGlrZWx5IHRvIGJlIHVuZGVmaW5lZC5cbiAgICAgIHRocm93IG5ldyBFcnJvcignTm8gcHJvZ3JhbSBpbiBsYW5ndWFnZSBzZXJ2aWNlIScpO1xuICAgIH1cbiAgICByZXR1cm4gcHJvZ3JhbTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIFRlbXBsYXRlU291cmNlIGlmIGBub2RlYCBpcyBhIHRlbXBsYXRlIG5vZGUuXG4gICAqXG4gICAqIEZvciBleGFtcGxlLFxuICAgKlxuICAgKiBAQ29tcG9uZW50KHtcbiAgICogICB0ZW1wbGF0ZTogJzxkaXY+PC9kaXY+JyA8LS0gdGVtcGxhdGUgbm9kZVxuICAgKiB9KVxuICAgKiBjbGFzcyBBcHBDb21wb25lbnQge31cbiAgICogICAgICAgICAgIF4tLS0tIGNsYXNzIGRlY2xhcmF0aW9uIG5vZGVcbiAgICpcbiAgICogQHBhcmFtIG5vZGUgUG90ZW50aWFsIHRlbXBsYXRlIG5vZGVcbiAgICovXG4gIHByaXZhdGUgZ2V0SW50ZXJuYWxUZW1wbGF0ZShub2RlOiB0c3MuTm9kZSk6IFRlbXBsYXRlU291cmNlfHVuZGVmaW5lZCB7XG4gICAgaWYgKCF0c3MuaXNTdHJpbmdMaXRlcmFsTGlrZShub2RlKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCB0bXBsQXNnbiA9IGdldFByb3BlcnR5QXNzaWdubWVudEZyb21WYWx1ZShub2RlLCAndGVtcGxhdGUnKTtcbiAgICBpZiAoIXRtcGxBc2duKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IGNsYXNzRGVjbCA9IGdldENsYXNzRGVjbEZyb21EZWNvcmF0b3JQcm9wKHRtcGxBc2duKTtcbiAgICBpZiAoIWNsYXNzRGVjbCB8fCAhY2xhc3NEZWNsLm5hbWUpIHsgIC8vIERvZXMgbm90IGhhbmRsZSBhbm9ueW1vdXMgY2xhc3NcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgZmlsZU5hbWUgPSBub2RlLmdldFNvdXJjZUZpbGUoKS5maWxlTmFtZTtcbiAgICBjb25zdCBjbGFzc1N5bWJvbCA9IHRoaXMucmVmbGVjdG9yLmdldFN0YXRpY1N5bWJvbChmaWxlTmFtZSwgY2xhc3NEZWNsLm5hbWUudGV4dCk7XG4gICAgcmV0dXJuIG5ldyBJbmxpbmVUZW1wbGF0ZShub2RlLCBjbGFzc0RlY2wsIGNsYXNzU3ltYm9sLCB0aGlzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGV4dGVybmFsIHRlbXBsYXRlIGZvciBgZmlsZU5hbWVgLlxuICAgKiBAcGFyYW0gZmlsZU5hbWUgSFRNTCBmaWxlXG4gICAqL1xuICBwcml2YXRlIGdldEV4dGVybmFsVGVtcGxhdGUoZmlsZU5hbWU6IHN0cmluZyk6IFRlbXBsYXRlU291cmNlfHVuZGVmaW5lZCB7XG4gICAgLy8gRmlyc3QgZ2V0IHRoZSB0ZXh0IGZvciB0aGUgdGVtcGxhdGVcbiAgICBjb25zdCBzbmFwc2hvdCA9IHRoaXMudHNMc0hvc3QuZ2V0U2NyaXB0U25hcHNob3QoZmlsZU5hbWUpO1xuICAgIGlmICghc25hcHNob3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgc291cmNlID0gc25hcHNob3QuZ2V0VGV4dCgwLCBzbmFwc2hvdC5nZXRMZW5ndGgoKSk7XG4gICAgLy8gTmV4dCBmaW5kIHRoZSBjb21wb25lbnQgY2xhc3Mgc3ltYm9sXG4gICAgY29uc3QgY2xhc3NTeW1ib2wgPSB0aGlzLmZpbGVUb0NvbXBvbmVudC5nZXQoZmlsZU5hbWUpO1xuICAgIGlmICghY2xhc3NTeW1ib2wpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgLy8gVGhlbiB1c2UgdGhlIGNsYXNzIHN5bWJvbCB0byBmaW5kIHRoZSBhY3R1YWwgdHMuQ2xhc3NEZWNsYXJhdGlvbiBub2RlXG4gICAgY29uc3Qgc291cmNlRmlsZSA9IHRoaXMuZ2V0U291cmNlRmlsZShjbGFzc1N5bWJvbC5maWxlUGF0aCk7XG4gICAgaWYgKCFzb3VyY2VGaWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIC8vIFRPRE86IFRoaXMgb25seSBjb25zaWRlcnMgdG9wLWxldmVsIGNsYXNzIGRlY2xhcmF0aW9ucyBpbiBhIHNvdXJjZSBmaWxlLlxuICAgIC8vIFRoaXMgd291bGQgbm90IGZpbmQgYSBjbGFzcyBkZWNsYXJhdGlvbiBpbiBhIG5hbWVzcGFjZSwgZm9yIGV4YW1wbGUuXG4gICAgY29uc3QgY2xhc3NEZWNsID0gc291cmNlRmlsZS5mb3JFYWNoQ2hpbGQoKGNoaWxkKSA9PiB7XG4gICAgICBpZiAodHNzLmlzQ2xhc3NEZWNsYXJhdGlvbihjaGlsZCkgJiYgY2hpbGQubmFtZSAmJiBjaGlsZC5uYW1lLnRleHQgPT09IGNsYXNzU3ltYm9sLm5hbWUpIHtcbiAgICAgICAgcmV0dXJuIGNoaWxkO1xuICAgICAgfVxuICAgIH0pO1xuICAgIGlmICghY2xhc3NEZWNsKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHJldHVybiBuZXcgRXh0ZXJuYWxUZW1wbGF0ZShzb3VyY2UsIGZpbGVOYW1lLCBjbGFzc0RlY2wsIGNsYXNzU3ltYm9sLCB0aGlzKTtcbiAgfVxuXG4gIHByaXZhdGUgY29sbGVjdEVycm9yKGVycm9yOiBhbnksIGZpbGVQYXRoPzogc3RyaW5nKSB7XG4gICAgaWYgKGZpbGVQYXRoKSB7XG4gICAgICBsZXQgZXJyb3JzID0gdGhpcy5jb2xsZWN0ZWRFcnJvcnMuZ2V0KGZpbGVQYXRoKTtcbiAgICAgIGlmICghZXJyb3JzKSB7XG4gICAgICAgIGVycm9ycyA9IFtdO1xuICAgICAgICB0aGlzLmNvbGxlY3RlZEVycm9ycy5zZXQoZmlsZVBhdGgsIGVycm9ycyk7XG4gICAgICB9XG4gICAgICBlcnJvcnMucHVzaChlcnJvcik7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb2xsZWN0ZWRFcnJvcnMoZGVmYXVsdFNwYW46IFNwYW4sIHNvdXJjZUZpbGU6IHRzcy5Tb3VyY2VGaWxlKTogRGVjbGFyYXRpb25FcnJvcltdIHtcbiAgICBjb25zdCBlcnJvcnMgPSB0aGlzLmNvbGxlY3RlZEVycm9ycy5nZXQoc291cmNlRmlsZS5maWxlTmFtZSk7XG4gICAgaWYgKCFlcnJvcnMpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG4gICAgLy8gVE9ETzogQWRkIGJldHRlciB0eXBpbmdzIGZvciB0aGUgZXJyb3JzXG4gICAgcmV0dXJuIGVycm9ycy5tYXAoKGU6IGFueSkgPT4ge1xuICAgICAgY29uc3QgbGluZSA9IGUubGluZSB8fCAoZS5wb3NpdGlvbiAmJiBlLnBvc2l0aW9uLmxpbmUpO1xuICAgICAgY29uc3QgY29sdW1uID0gZS5jb2x1bW4gfHwgKGUucG9zaXRpb24gJiYgZS5wb3NpdGlvbi5jb2x1bW4pO1xuICAgICAgY29uc3Qgc3BhbiA9IHNwYW5BdChzb3VyY2VGaWxlLCBsaW5lLCBjb2x1bW4pIHx8IGRlZmF1bHRTcGFuO1xuICAgICAgaWYgKGlzRm9ybWF0dGVkRXJyb3IoZSkpIHtcbiAgICAgICAgcmV0dXJuIGVycm9yVG9EaWFnbm9zdGljV2l0aENoYWluKGUsIHNwYW4pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHttZXNzYWdlOiBlLm1lc3NhZ2UsIHNwYW59O1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgcGFyc2VkIHRlbXBsYXRlIGZvciB0aGUgdGVtcGxhdGUgYXQgdGhlIHNwZWNpZmllZCBgcG9zaXRpb25gLlxuICAgKiBAcGFyYW0gZmlsZU5hbWUgVFMgb3IgSFRNTCBmaWxlXG4gICAqIEBwYXJhbSBwb3NpdGlvbiBQb3NpdGlvbiBvZiB0aGUgdGVtcGxhdGUgaW4gdGhlIFRTIGZpbGUsIG90aGVyd2lzZSBpZ25vcmVkLlxuICAgKi9cbiAgZ2V0VGVtcGxhdGVBc3RBdFBvc2l0aW9uKGZpbGVOYW1lOiBzdHJpbmcsIHBvc2l0aW9uOiBudW1iZXIpOiBBc3RSZXN1bHR8dW5kZWZpbmVkIHtcbiAgICBsZXQgdGVtcGxhdGU6IFRlbXBsYXRlU291cmNlfHVuZGVmaW5lZDtcbiAgICBpZiAoZmlsZU5hbWUuZW5kc1dpdGgoJy50cycpKSB7XG4gICAgICBjb25zdCBzb3VyY2VGaWxlID0gdGhpcy5nZXRTb3VyY2VGaWxlKGZpbGVOYW1lKTtcbiAgICAgIGlmICghc291cmNlRmlsZSkge1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgICAvLyBGaW5kIHRoZSBub2RlIHRoYXQgbW9zdCBjbG9zZWx5IG1hdGNoZXMgdGhlIHBvc2l0aW9uXG4gICAgICBjb25zdCBub2RlID0gZmluZFRpZ2h0ZXN0Tm9kZShzb3VyY2VGaWxlLCBwb3NpdGlvbik7XG4gICAgICBpZiAoIW5vZGUpIHtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgICAgdGVtcGxhdGUgPSB0aGlzLmdldEludGVybmFsVGVtcGxhdGUobm9kZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRlbXBsYXRlID0gdGhpcy5nZXRFeHRlcm5hbFRlbXBsYXRlKGZpbGVOYW1lKTtcbiAgICB9XG4gICAgaWYgKCF0ZW1wbGF0ZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5nZXRUZW1wbGF0ZUFzdCh0ZW1wbGF0ZSk7XG4gIH1cblxuICAvKipcbiAgICogRmluZCB0aGUgTmdNb2R1bGUgd2hpY2ggdGhlIGRpcmVjdGl2ZSBhc3NvY2lhdGVkIHdpdGggdGhlIGBjbGFzc1N5bWJvbGBcbiAgICogYmVsb25ncyB0bywgdGhlbiByZXR1cm4gaXRzIHNjaGVtYSBhbmQgdHJhbnNpdGl2ZSBkaXJlY3RpdmVzIGFuZCBwaXBlcy5cbiAgICogQHBhcmFtIGNsYXNzU3ltYm9sIEFuZ3VsYXIgU3ltYm9sIHRoYXQgZGVmaW5lcyBhIGRpcmVjdGl2ZVxuICAgKi9cbiAgcHJpdmF0ZSBnZXRNb2R1bGVNZXRhZGF0YUZvckRpcmVjdGl2ZShjbGFzc1N5bWJvbDogU3RhdGljU3ltYm9sKSB7XG4gICAgY29uc3QgcmVzdWx0ID0ge1xuICAgICAgZGlyZWN0aXZlczogW10gYXMgQ29tcGlsZURpcmVjdGl2ZVN1bW1hcnlbXSxcbiAgICAgIHBpcGVzOiBbXSBhcyBDb21waWxlUGlwZVN1bW1hcnlbXSxcbiAgICAgIHNjaGVtYXM6IFtdIGFzIFNjaGVtYU1ldGFkYXRhW10sXG4gICAgfTtcbiAgICAvLyBGaXJzdCBmaW5kIHdoaWNoIE5nTW9kdWxlIHRoZSBkaXJlY3RpdmUgYmVsb25ncyB0by5cbiAgICBjb25zdCBuZ01vZHVsZSA9IHRoaXMuYW5hbHl6ZWRNb2R1bGVzLm5nTW9kdWxlQnlQaXBlT3JEaXJlY3RpdmUuZ2V0KGNsYXNzU3ltYm9sKSB8fFxuICAgICAgICBmaW5kU3VpdGFibGVEZWZhdWx0TW9kdWxlKHRoaXMuYW5hbHl6ZWRNb2R1bGVzKTtcbiAgICBpZiAoIW5nTW9kdWxlKSB7XG4gICAgICByZXR1cm4gcmVzdWx0O1xuICAgIH1cbiAgICAvLyBUaGVuIGdhdGhlciBhbGwgdHJhbnNpdGl2ZSBkaXJlY3RpdmVzIGFuZCBwaXBlcy5cbiAgICBjb25zdCB7ZGlyZWN0aXZlcywgcGlwZXN9ID0gbmdNb2R1bGUudHJhbnNpdGl2ZU1vZHVsZTtcbiAgICBmb3IgKGNvbnN0IGRpcmVjdGl2ZSBvZiBkaXJlY3RpdmVzKSB7XG4gICAgICBjb25zdCBkYXRhID0gdGhpcy5yZXNvbHZlci5nZXROb25Ob3JtYWxpemVkRGlyZWN0aXZlTWV0YWRhdGEoZGlyZWN0aXZlLnJlZmVyZW5jZSk7XG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICByZXN1bHQuZGlyZWN0aXZlcy5wdXNoKGRhdGEubWV0YWRhdGEudG9TdW1tYXJ5KCkpO1xuICAgICAgfVxuICAgIH1cbiAgICBmb3IgKGNvbnN0IHBpcGUgb2YgcGlwZXMpIHtcbiAgICAgIGNvbnN0IG1ldGFkYXRhID0gdGhpcy5yZXNvbHZlci5nZXRPckxvYWRQaXBlTWV0YWRhdGEocGlwZS5yZWZlcmVuY2UpO1xuICAgICAgcmVzdWx0LnBpcGVzLnB1c2gobWV0YWRhdGEudG9TdW1tYXJ5KCkpO1xuICAgIH1cbiAgICByZXN1bHQuc2NoZW1hcy5wdXNoKC4uLm5nTW9kdWxlLnNjaGVtYXMpO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgdGhlIGB0ZW1wbGF0ZWAgYW5kIHJldHVybiBpdHMgQVNULCBpZiBhbnkuXG4gICAqIEBwYXJhbSB0ZW1wbGF0ZSB0ZW1wbGF0ZSB0byBiZSBwYXJzZWRcbiAgICovXG4gIGdldFRlbXBsYXRlQXN0KHRlbXBsYXRlOiBUZW1wbGF0ZVNvdXJjZSk6IEFzdFJlc3VsdHx1bmRlZmluZWQge1xuICAgIGNvbnN0IHt0eXBlOiBjbGFzc1N5bWJvbCwgZmlsZU5hbWV9ID0gdGVtcGxhdGU7XG4gICAgY29uc3QgZGF0YSA9IHRoaXMucmVzb2x2ZXIuZ2V0Tm9uTm9ybWFsaXplZERpcmVjdGl2ZU1ldGFkYXRhKGNsYXNzU3ltYm9sKTtcbiAgICBpZiAoIWRhdGEpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgaHRtbFBhcnNlciA9IG5ldyBIdG1sUGFyc2VyKCk7XG4gICAgY29uc3QgZXhwcmVzc2lvblBhcnNlciA9IG5ldyBQYXJzZXIobmV3IExleGVyKCkpO1xuICAgIGNvbnN0IHBhcnNlciA9IG5ldyBUZW1wbGF0ZVBhcnNlcihcbiAgICAgICAgbmV3IENvbXBpbGVyQ29uZmlnKCksIHRoaXMucmVmbGVjdG9yLCBleHByZXNzaW9uUGFyc2VyLCBuZXcgRG9tRWxlbWVudFNjaGVtYVJlZ2lzdHJ5KCksXG4gICAgICAgIGh0bWxQYXJzZXIsXG4gICAgICAgIG51bGwsICAvLyBjb25zb2xlXG4gICAgICAgIFtdICAgICAvLyB0cmFuZm9ybXNcbiAgICApO1xuICAgIGNvbnN0IGh0bWxSZXN1bHQgPSBodG1sUGFyc2VyLnBhcnNlKHRlbXBsYXRlLnNvdXJjZSwgZmlsZU5hbWUsIHtcbiAgICAgIHRva2VuaXplRXhwYW5zaW9uRm9ybXM6IHRydWUsXG4gICAgICBwcmVzZXJ2ZUxpbmVFbmRpbmdzOiB0cnVlLCAgLy8gZG8gbm90IGNvbnZlcnQgQ1JMRiB0byBMRlxuICAgIH0pO1xuICAgIGNvbnN0IHtkaXJlY3RpdmVzLCBwaXBlcywgc2NoZW1hc30gPSB0aGlzLmdldE1vZHVsZU1ldGFkYXRhRm9yRGlyZWN0aXZlKGNsYXNzU3ltYm9sKTtcbiAgICBjb25zdCBwYXJzZVJlc3VsdCA9IHBhcnNlci50cnlQYXJzZUh0bWwoaHRtbFJlc3VsdCwgZGF0YS5tZXRhZGF0YSwgZGlyZWN0aXZlcywgcGlwZXMsIHNjaGVtYXMpO1xuICAgIGlmICghcGFyc2VSZXN1bHQudGVtcGxhdGVBc3QpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgcmV0dXJuIHtcbiAgICAgIGh0bWxBc3Q6IGh0bWxSZXN1bHQucm9vdE5vZGVzLFxuICAgICAgdGVtcGxhdGVBc3Q6IHBhcnNlUmVzdWx0LnRlbXBsYXRlQXN0LFxuICAgICAgZGlyZWN0aXZlOiBkYXRhLm1ldGFkYXRhLFxuICAgICAgZGlyZWN0aXZlcyxcbiAgICAgIHBpcGVzLFxuICAgICAgcGFyc2VFcnJvcnM6IHBhcnNlUmVzdWx0LmVycm9ycyxcbiAgICAgIGV4cHJlc3Npb25QYXJzZXIsXG4gICAgICB0ZW1wbGF0ZSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIExvZyB0aGUgc3BlY2lmaWVkIGBtc2dgIHRvIGZpbGUgYXQgSU5GTyBsZXZlbC4gSWYgbG9nZ2luZyBpcyBub3QgZW5hYmxlZFxuICAgKiB0aGlzIG1ldGhvZCBpcyBhIG5vLW9wLlxuICAgKiBAcGFyYW0gbXNnIExvZyBtZXNzYWdlXG4gICAqL1xuICBsb2cobXNnOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy50c0xzSG9zdC5sb2cpIHtcbiAgICAgIHRoaXMudHNMc0hvc3QubG9nKG1zZyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExvZyB0aGUgc3BlY2lmaWVkIGBtc2dgIHRvIGZpbGUgYXQgRVJST1IgbGV2ZWwuIElmIGxvZ2dpbmcgaXMgbm90IGVuYWJsZWRcbiAgICogdGhpcyBtZXRob2QgaXMgYSBuby1vcC5cbiAgICogQHBhcmFtIG1zZyBlcnJvciBtZXNzYWdlXG4gICAqL1xuICBlcnJvcihtc2c6IHN0cmluZykge1xuICAgIGlmICh0aGlzLnRzTHNIb3N0LmVycm9yKSB7XG4gICAgICB0aGlzLnRzTHNIb3N0LmVycm9yKG1zZyk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIExvZyBkZWJ1Z2dpbmcgaW5mbyB0byBmaWxlIGF0IElORk8gbGV2ZWwsIG9ubHkgaWYgdmVyYm9zZSBzZXR0aW5nIGlzIHR1cm5lZFxuICAgKiBvbi4gT3RoZXJ3aXNlLCB0aGlzIG1ldGhvZCBpcyBhIG5vLW9wLlxuICAgKiBAcGFyYW0gbXNnIGRlYnVnZ2luZyBtZXNzYWdlXG4gICAqL1xuICBkZWJ1Zyhtc2c6IHN0cmluZykge1xuICAgIGNvbnN0IHByb2plY3QgPSB0aGlzLnRzTHNIb3N0IGFzIHRzcy5zZXJ2ZXIuUHJvamVjdDtcbiAgICBpZiAoIXByb2plY3QucHJvamVjdFNlcnZpY2UpIHtcbiAgICAgIC8vIHRzTHNIb3N0IGlzIG5vdCBhIFByb2plY3RcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qge2xvZ2dlcn0gPSBwcm9qZWN0LnByb2plY3RTZXJ2aWNlO1xuICAgIGlmIChsb2dnZXIuaGFzTGV2ZWwodHNzLnNlcnZlci5Mb2dMZXZlbC52ZXJib3NlKSkge1xuICAgICAgbG9nZ2VyLmluZm8obXNnKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmluZFN1aXRhYmxlRGVmYXVsdE1vZHVsZShtb2R1bGVzOiBOZ0FuYWx5emVkTW9kdWxlcyk6IENvbXBpbGVOZ01vZHVsZU1ldGFkYXRhfHVuZGVmaW5lZCB7XG4gIGxldCByZXN1bHQ6IENvbXBpbGVOZ01vZHVsZU1ldGFkYXRhfHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgbGV0IHJlc3VsdFNpemUgPSAwO1xuICBmb3IgKGNvbnN0IG1vZHVsZSBvZiBtb2R1bGVzLm5nTW9kdWxlcykge1xuICAgIGNvbnN0IG1vZHVsZVNpemUgPSBtb2R1bGUudHJhbnNpdGl2ZU1vZHVsZS5kaXJlY3RpdmVzLmxlbmd0aDtcbiAgICBpZiAobW9kdWxlU2l6ZSA+IHJlc3VsdFNpemUpIHtcbiAgICAgIHJlc3VsdCA9IG1vZHVsZTtcbiAgICAgIHJlc3VsdFNpemUgPSBtb2R1bGVTaXplO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcmVzdWx0O1xufVxuXG5mdW5jdGlvbiBzcGFuT2Yobm9kZTogdHNzLk5vZGUpOiBTcGFuIHtcbiAgcmV0dXJuIHtzdGFydDogbm9kZS5nZXRTdGFydCgpLCBlbmQ6IG5vZGUuZ2V0RW5kKCl9O1xufVxuXG5mdW5jdGlvbiBzcGFuQXQoc291cmNlRmlsZTogdHNzLlNvdXJjZUZpbGUsIGxpbmU6IG51bWJlciwgY29sdW1uOiBudW1iZXIpOiBTcGFufHVuZGVmaW5lZCB7XG4gIGlmIChsaW5lICE9IG51bGwgJiYgY29sdW1uICE9IG51bGwpIHtcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRzcy5nZXRQb3NpdGlvbk9mTGluZUFuZENoYXJhY3Rlcihzb3VyY2VGaWxlLCBsaW5lLCBjb2x1bW4pO1xuICAgIGNvbnN0IGZpbmRDaGlsZCA9IGZ1bmN0aW9uIGZpbmRDaGlsZChub2RlOiB0c3MuTm9kZSk6IHRzcy5Ob2RlfHVuZGVmaW5lZCB7XG4gICAgICBpZiAobm9kZS5raW5kID4gdHNzLlN5bnRheEtpbmQuTGFzdFRva2VuICYmIG5vZGUucG9zIDw9IHBvc2l0aW9uICYmIG5vZGUuZW5kID4gcG9zaXRpb24pIHtcbiAgICAgICAgY29uc3QgYmV0dGVyTm9kZSA9IHRzcy5mb3JFYWNoQ2hpbGQobm9kZSwgZmluZENoaWxkKTtcbiAgICAgICAgcmV0dXJuIGJldHRlck5vZGUgfHwgbm9kZTtcbiAgICAgIH1cbiAgICB9O1xuXG4gICAgY29uc3Qgbm9kZSA9IHRzcy5mb3JFYWNoQ2hpbGQoc291cmNlRmlsZSwgZmluZENoaWxkKTtcbiAgICBpZiAobm9kZSkge1xuICAgICAgcmV0dXJuIHtzdGFydDogbm9kZS5nZXRTdGFydCgpLCBlbmQ6IG5vZGUuZ2V0RW5kKCl9O1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBjb252ZXJ0Q2hhaW4oY2hhaW46IEZvcm1hdHRlZE1lc3NhZ2VDaGFpbik6IERpYWdub3N0aWNNZXNzYWdlQ2hhaW4ge1xuICByZXR1cm4ge21lc3NhZ2U6IGNoYWluLm1lc3NhZ2UsIG5leHQ6IGNoYWluLm5leHQgPyBjaGFpbi5uZXh0Lm1hcChjb252ZXJ0Q2hhaW4pIDogdW5kZWZpbmVkfTtcbn1cblxuZnVuY3Rpb24gZXJyb3JUb0RpYWdub3N0aWNXaXRoQ2hhaW4oZXJyb3I6IEZvcm1hdHRlZEVycm9yLCBzcGFuOiBTcGFuKTogRGVjbGFyYXRpb25FcnJvciB7XG4gIHJldHVybiB7bWVzc2FnZTogZXJyb3IuY2hhaW4gPyBjb252ZXJ0Q2hhaW4oZXJyb3IuY2hhaW4pIDogZXJyb3IubWVzc2FnZSwgc3Bhbn07XG59XG4iXX0= |
\ | No newline at end of file |