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 | import { CompileStylesheetMetadata, CompileTemplateMetadata, templateSourceUrl } from './compile_metadata';
|
---|
9 | import { preserveWhitespacesDefault } from './config';
|
---|
10 | import { ViewEncapsulation } from './core';
|
---|
11 | import * as html from './ml_parser/ast';
|
---|
12 | import { InterpolationConfig } from './ml_parser/interpolation_config';
|
---|
13 | import { syntaxError } from './parse_util';
|
---|
14 | import { extractStyleUrls, isStyleUrlResolvable } from './style_url_resolver';
|
---|
15 | import { PreparsedElementType, preparseElement } from './template_parser/template_preparser';
|
---|
16 | import { isDefined, stringify, SyncAsync } from './util';
|
---|
17 | export class DirectiveNormalizer {
|
---|
18 | constructor(_resourceLoader, _urlResolver, _htmlParser, _config) {
|
---|
19 | this._resourceLoader = _resourceLoader;
|
---|
20 | this._urlResolver = _urlResolver;
|
---|
21 | this._htmlParser = _htmlParser;
|
---|
22 | this._config = _config;
|
---|
23 | this._resourceLoaderCache = new Map();
|
---|
24 | }
|
---|
25 | clearCache() {
|
---|
26 | this._resourceLoaderCache.clear();
|
---|
27 | }
|
---|
28 | clearCacheFor(normalizedDirective) {
|
---|
29 | if (!normalizedDirective.isComponent) {
|
---|
30 | return;
|
---|
31 | }
|
---|
32 | const template = normalizedDirective.template;
|
---|
33 | this._resourceLoaderCache.delete(template.templateUrl);
|
---|
34 | template.externalStylesheets.forEach((stylesheet) => {
|
---|
35 | this._resourceLoaderCache.delete(stylesheet.moduleUrl);
|
---|
36 | });
|
---|
37 | }
|
---|
38 | _fetch(url) {
|
---|
39 | let result = this._resourceLoaderCache.get(url);
|
---|
40 | if (!result) {
|
---|
41 | result = this._resourceLoader.get(url);
|
---|
42 | this._resourceLoaderCache.set(url, result);
|
---|
43 | }
|
---|
44 | return result;
|
---|
45 | }
|
---|
46 | normalizeTemplate(prenormData) {
|
---|
47 | if (isDefined(prenormData.template)) {
|
---|
48 | if (isDefined(prenormData.templateUrl)) {
|
---|
49 | throw syntaxError(`'${stringify(prenormData
|
---|
50 | .componentType)}' component cannot define both template and templateUrl`);
|
---|
51 | }
|
---|
52 | if (typeof prenormData.template !== 'string') {
|
---|
53 | throw syntaxError(`The template specified for component ${stringify(prenormData.componentType)} is not a string`);
|
---|
54 | }
|
---|
55 | }
|
---|
56 | else if (isDefined(prenormData.templateUrl)) {
|
---|
57 | if (typeof prenormData.templateUrl !== 'string') {
|
---|
58 | throw syntaxError(`The templateUrl specified for component ${stringify(prenormData.componentType)} is not a string`);
|
---|
59 | }
|
---|
60 | }
|
---|
61 | else {
|
---|
62 | throw syntaxError(`No template specified for component ${stringify(prenormData.componentType)}`);
|
---|
63 | }
|
---|
64 | if (isDefined(prenormData.preserveWhitespaces) &&
|
---|
65 | typeof prenormData.preserveWhitespaces !== 'boolean') {
|
---|
66 | throw syntaxError(`The preserveWhitespaces option for component ${stringify(prenormData.componentType)} must be a boolean`);
|
---|
67 | }
|
---|
68 | return SyncAsync.then(this._preParseTemplate(prenormData), (preparsedTemplate) => this._normalizeTemplateMetadata(prenormData, preparsedTemplate));
|
---|
69 | }
|
---|
70 | _preParseTemplate(prenomData) {
|
---|
71 | let template;
|
---|
72 | let templateUrl;
|
---|
73 | if (prenomData.template != null) {
|
---|
74 | template = prenomData.template;
|
---|
75 | templateUrl = prenomData.moduleUrl;
|
---|
76 | }
|
---|
77 | else {
|
---|
78 | templateUrl = this._urlResolver.resolve(prenomData.moduleUrl, prenomData.templateUrl);
|
---|
79 | template = this._fetch(templateUrl);
|
---|
80 | }
|
---|
81 | return SyncAsync.then(template, (template) => this._preparseLoadedTemplate(prenomData, template, templateUrl));
|
---|
82 | }
|
---|
83 | _preparseLoadedTemplate(prenormData, template, templateAbsUrl) {
|
---|
84 | const isInline = !!prenormData.template;
|
---|
85 | const interpolationConfig = InterpolationConfig.fromArray(prenormData.interpolation);
|
---|
86 | const templateUrl = templateSourceUrl({ reference: prenormData.ngModuleType }, { type: { reference: prenormData.componentType } }, { isInline, templateUrl: templateAbsUrl });
|
---|
87 | const rootNodesAndErrors = this._htmlParser.parse(template, templateUrl, { tokenizeExpansionForms: true, interpolationConfig });
|
---|
88 | if (rootNodesAndErrors.errors.length > 0) {
|
---|
89 | const errorString = rootNodesAndErrors.errors.join('\n');
|
---|
90 | throw syntaxError(`Template parse errors:\n${errorString}`);
|
---|
91 | }
|
---|
92 | const templateMetadataStyles = this._normalizeStylesheet(new CompileStylesheetMetadata({ styles: prenormData.styles, moduleUrl: prenormData.moduleUrl }));
|
---|
93 | const visitor = new TemplatePreparseVisitor();
|
---|
94 | html.visitAll(visitor, rootNodesAndErrors.rootNodes);
|
---|
95 | const templateStyles = this._normalizeStylesheet(new CompileStylesheetMetadata({ styles: visitor.styles, styleUrls: visitor.styleUrls, moduleUrl: templateAbsUrl }));
|
---|
96 | const styles = templateMetadataStyles.styles.concat(templateStyles.styles);
|
---|
97 | const inlineStyleUrls = templateMetadataStyles.styleUrls.concat(templateStyles.styleUrls);
|
---|
98 | const styleUrls = this
|
---|
99 | ._normalizeStylesheet(new CompileStylesheetMetadata({ styleUrls: prenormData.styleUrls, moduleUrl: prenormData.moduleUrl }))
|
---|
100 | .styleUrls;
|
---|
101 | return {
|
---|
102 | template,
|
---|
103 | templateUrl: templateAbsUrl,
|
---|
104 | isInline,
|
---|
105 | htmlAst: rootNodesAndErrors,
|
---|
106 | styles,
|
---|
107 | inlineStyleUrls,
|
---|
108 | styleUrls,
|
---|
109 | ngContentSelectors: visitor.ngContentSelectors,
|
---|
110 | };
|
---|
111 | }
|
---|
112 | _normalizeTemplateMetadata(prenormData, preparsedTemplate) {
|
---|
113 | return SyncAsync.then(this._loadMissingExternalStylesheets(preparsedTemplate.styleUrls.concat(preparsedTemplate.inlineStyleUrls)), (externalStylesheets) => this._normalizeLoadedTemplateMetadata(prenormData, preparsedTemplate, externalStylesheets));
|
---|
114 | }
|
---|
115 | _normalizeLoadedTemplateMetadata(prenormData, preparsedTemplate, stylesheets) {
|
---|
116 | // Algorithm:
|
---|
117 | // - produce exactly 1 entry per original styleUrl in
|
---|
118 | // CompileTemplateMetadata.externalStylesheets with all styles inlined
|
---|
119 | // - inline all styles that are referenced by the template into CompileTemplateMetadata.styles.
|
---|
120 | // Reason: be able to determine how many stylesheets there are even without loading
|
---|
121 | // the template nor the stylesheets, so we can create a stub for TypeScript always synchronously
|
---|
122 | // (as resource loading may be async)
|
---|
123 | const styles = [...preparsedTemplate.styles];
|
---|
124 | this._inlineStyles(preparsedTemplate.inlineStyleUrls, stylesheets, styles);
|
---|
125 | const styleUrls = preparsedTemplate.styleUrls;
|
---|
126 | const externalStylesheets = styleUrls.map(styleUrl => {
|
---|
127 | const stylesheet = stylesheets.get(styleUrl);
|
---|
128 | const styles = [...stylesheet.styles];
|
---|
129 | this._inlineStyles(stylesheet.styleUrls, stylesheets, styles);
|
---|
130 | return new CompileStylesheetMetadata({ moduleUrl: styleUrl, styles: styles });
|
---|
131 | });
|
---|
132 | let encapsulation = prenormData.encapsulation;
|
---|
133 | if (encapsulation == null) {
|
---|
134 | encapsulation = this._config.defaultEncapsulation;
|
---|
135 | }
|
---|
136 | if (encapsulation === ViewEncapsulation.Emulated && styles.length === 0 &&
|
---|
137 | styleUrls.length === 0) {
|
---|
138 | encapsulation = ViewEncapsulation.None;
|
---|
139 | }
|
---|
140 | return new CompileTemplateMetadata({
|
---|
141 | encapsulation,
|
---|
142 | template: preparsedTemplate.template,
|
---|
143 | templateUrl: preparsedTemplate.templateUrl,
|
---|
144 | htmlAst: preparsedTemplate.htmlAst,
|
---|
145 | styles,
|
---|
146 | styleUrls,
|
---|
147 | ngContentSelectors: preparsedTemplate.ngContentSelectors,
|
---|
148 | animations: prenormData.animations,
|
---|
149 | interpolation: prenormData.interpolation,
|
---|
150 | isInline: preparsedTemplate.isInline,
|
---|
151 | externalStylesheets,
|
---|
152 | preserveWhitespaces: preserveWhitespacesDefault(prenormData.preserveWhitespaces, this._config.preserveWhitespaces),
|
---|
153 | });
|
---|
154 | }
|
---|
155 | _inlineStyles(styleUrls, stylesheets, targetStyles) {
|
---|
156 | styleUrls.forEach(styleUrl => {
|
---|
157 | const stylesheet = stylesheets.get(styleUrl);
|
---|
158 | stylesheet.styles.forEach(style => targetStyles.push(style));
|
---|
159 | this._inlineStyles(stylesheet.styleUrls, stylesheets, targetStyles);
|
---|
160 | });
|
---|
161 | }
|
---|
162 | _loadMissingExternalStylesheets(styleUrls, loadedStylesheets = new Map()) {
|
---|
163 | return SyncAsync.then(SyncAsync.all(styleUrls.filter((styleUrl) => !loadedStylesheets.has(styleUrl))
|
---|
164 | .map(styleUrl => SyncAsync.then(this._fetch(styleUrl), (loadedStyle) => {
|
---|
165 | const stylesheet = this._normalizeStylesheet(new CompileStylesheetMetadata({ styles: [loadedStyle], moduleUrl: styleUrl }));
|
---|
166 | loadedStylesheets.set(styleUrl, stylesheet);
|
---|
167 | return this._loadMissingExternalStylesheets(stylesheet.styleUrls, loadedStylesheets);
|
---|
168 | }))), (_) => loadedStylesheets);
|
---|
169 | }
|
---|
170 | _normalizeStylesheet(stylesheet) {
|
---|
171 | const moduleUrl = stylesheet.moduleUrl;
|
---|
172 | const allStyleUrls = stylesheet.styleUrls.filter(isStyleUrlResolvable)
|
---|
173 | .map(url => this._urlResolver.resolve(moduleUrl, url));
|
---|
174 | const allStyles = stylesheet.styles.map(style => {
|
---|
175 | const styleWithImports = extractStyleUrls(this._urlResolver, moduleUrl, style);
|
---|
176 | allStyleUrls.push(...styleWithImports.styleUrls);
|
---|
177 | return styleWithImports.style;
|
---|
178 | });
|
---|
179 | return new CompileStylesheetMetadata({ styles: allStyles, styleUrls: allStyleUrls, moduleUrl: moduleUrl });
|
---|
180 | }
|
---|
181 | }
|
---|
182 | class TemplatePreparseVisitor {
|
---|
183 | constructor() {
|
---|
184 | this.ngContentSelectors = [];
|
---|
185 | this.styles = [];
|
---|
186 | this.styleUrls = [];
|
---|
187 | this.ngNonBindableStackCount = 0;
|
---|
188 | }
|
---|
189 | visitElement(ast, context) {
|
---|
190 | const preparsedElement = preparseElement(ast);
|
---|
191 | switch (preparsedElement.type) {
|
---|
192 | case PreparsedElementType.NG_CONTENT:
|
---|
193 | if (this.ngNonBindableStackCount === 0) {
|
---|
194 | this.ngContentSelectors.push(preparsedElement.selectAttr);
|
---|
195 | }
|
---|
196 | break;
|
---|
197 | case PreparsedElementType.STYLE:
|
---|
198 | let textContent = '';
|
---|
199 | ast.children.forEach(child => {
|
---|
200 | if (child instanceof html.Text) {
|
---|
201 | textContent += child.value;
|
---|
202 | }
|
---|
203 | });
|
---|
204 | this.styles.push(textContent);
|
---|
205 | break;
|
---|
206 | case PreparsedElementType.STYLESHEET:
|
---|
207 | this.styleUrls.push(preparsedElement.hrefAttr);
|
---|
208 | break;
|
---|
209 | default:
|
---|
210 | break;
|
---|
211 | }
|
---|
212 | if (preparsedElement.nonBindable) {
|
---|
213 | this.ngNonBindableStackCount++;
|
---|
214 | }
|
---|
215 | html.visitAll(this, ast.children);
|
---|
216 | if (preparsedElement.nonBindable) {
|
---|
217 | this.ngNonBindableStackCount--;
|
---|
218 | }
|
---|
219 | return null;
|
---|
220 | }
|
---|
221 | visitExpansion(ast, context) {
|
---|
222 | html.visitAll(this, ast.cases);
|
---|
223 | }
|
---|
224 | visitExpansionCase(ast, context) {
|
---|
225 | html.visitAll(this, ast.expression);
|
---|
226 | }
|
---|
227 | visitComment(ast, context) {
|
---|
228 | return null;
|
---|
229 | }
|
---|
230 | visitAttribute(ast, context) {
|
---|
231 | return null;
|
---|
232 | }
|
---|
233 | visitText(ast, context) {
|
---|
234 | return null;
|
---|
235 | }
|
---|
236 | }
|
---|
237 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlyZWN0aXZlX25vcm1hbGl6ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21waWxlci9zcmMvZGlyZWN0aXZlX25vcm1hbGl6ZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HO0FBRUgsT0FBTyxFQUEyQix5QkFBeUIsRUFBRSx1QkFBdUIsRUFBRSxpQkFBaUIsRUFBQyxNQUFNLG9CQUFvQixDQUFDO0FBQ25JLE9BQU8sRUFBaUIsMEJBQTBCLEVBQUMsTUFBTSxVQUFVLENBQUM7QUFDcEUsT0FBTyxFQUFDLGlCQUFpQixFQUFDLE1BQU0sUUFBUSxDQUFDO0FBQ3pDLE9BQU8sS0FBSyxJQUFJLE1BQU0saUJBQWlCLENBQUM7QUFFeEMsT0FBTyxFQUFDLG1CQUFtQixFQUFDLE1BQU0sa0NBQWtDLENBQUM7QUFFckUsT0FBTyxFQUFDLFdBQVcsRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUV6QyxPQUFPLEVBQUMsZ0JBQWdCLEVBQUUsb0JBQW9CLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUM1RSxPQUFPLEVBQUMsb0JBQW9CLEVBQUUsZUFBZSxFQUFDLE1BQU0sc0NBQXNDLENBQUM7QUFFM0YsT0FBTyxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFDLE1BQU0sUUFBUSxDQUFDO0FBZ0J2RCxNQUFNLE9BQU8sbUJBQW1CO0lBRzlCLFlBQ1ksZUFBK0IsRUFBVSxZQUF5QixFQUNsRSxXQUF1QixFQUFVLE9BQXVCO1FBRHhELG9CQUFlLEdBQWYsZUFBZSxDQUFnQjtRQUFVLGlCQUFZLEdBQVosWUFBWSxDQUFhO1FBQ2xFLGdCQUFXLEdBQVgsV0FBVyxDQUFZO1FBQVUsWUFBTyxHQUFQLE9BQU8sQ0FBZ0I7UUFKNUQseUJBQW9CLEdBQUcsSUFBSSxHQUFHLEVBQTZCLENBQUM7SUFJRyxDQUFDO0lBRXhFLFVBQVU7UUFDUixJQUFJLENBQUMsb0JBQW9CLENBQUMs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QztJQUNkLENBQUM7SUFDRCxTQUFTLENBQUMsR0FBYyxFQUFFLE9BQVk7UUFDcEMsT0FBTyxJQUFJLENBQUM7SUFDZCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtDb21waWxlRGlyZWN0aXZlTWV0YWRhdGEsIENvbXBpbGVTdHlsZXNoZWV0TWV0YWRhdGEsIENvbXBpbGVUZW1wbGF0ZU1ldGFkYXRhLCB0ZW1wbGF0ZVNvdXJjZVVybH0gZnJvbSAnLi9jb21waWxlX21ldGFkYXRhJztcbmltcG9ydCB7Q29tcGlsZXJDb25maWcsIHByZXNlcnZlV2hpdGVzcGFjZXNEZWZhdWx0fSBmcm9tICcuL2NvbmZpZyc7XG5pbXBvcnQge1ZpZXdFbmNhcHN1bGF0aW9ufSBmcm9tICcuL2NvcmUnO1xuaW1wb3J0ICogYXMgaHRtbCBmcm9tICcuL21sX3BhcnNlci9hc3QnO1xuaW1wb3J0IHtIdG1sUGFyc2VyfSBmcm9tICcuL21sX3BhcnNlci9odG1sX3BhcnNlcic7XG5pbXBvcnQge0ludGVycG9sYXRpb25Db25maWd9IGZyb20gJy4vbWxfcGFyc2VyL2ludGVycG9sYXRpb25fY29uZmlnJztcbmltcG9ydCB7UGFyc2VUcmVlUmVzdWx0IGFzIEh0bWxQYXJzZVRyZWVSZXN1bHR9IGZyb20gJy4vbWxfcGFyc2VyL3BhcnNlcic7XG5pbXBvcnQge3N5bnRheEVycm9yfSBmcm9tICcuL3BhcnNlX3V0aWwnO1xuaW1wb3J0IHtSZXNvdXJjZUxvYWRlcn0gZnJvbSAnLi9yZXNvdXJjZV9sb2FkZXInO1xuaW1wb3J0IHtleHRyYWN0U3R5bGVVcmxzLCBpc1N0eWxlVXJsUmVzb2x2YWJsZX0gZnJvbSAnLi9zdHlsZV91cmxfcmVzb2x2ZXInO1xuaW1wb3J0IHtQcmVwYXJzZWRFbGVtZW50VHlwZSwgcHJlcGFyc2VFbGVtZW50fSBmcm9tICcuL3RlbXBsYXRlX3BhcnNlci90ZW1wbGF0ZV9wcmVwYXJzZXInO1xuaW1wb3J0IHtVcmxSZXNvbHZlcn0gZnJvbSAnLi91cmxfcmVzb2x2ZXInO1xuaW1wb3J0IHtpc0RlZmluZWQsIHN0cmluZ2lmeSwgU3luY0FzeW5jfSBmcm9tICcuL3V0aWwnO1xuXG5leHBvcnQgaW50ZXJmYWNlIFByZW5vcm1hbGl6ZWRUZW1wbGF0ZU1ldGFkYXRhIHtcbiAgbmdNb2R1bGVUeXBlOiBhbnk7XG4gIGNvbXBvbmVudFR5cGU6IGFueTtcbiAgbW9kdWxlVXJsOiBzdHJpbmc7XG4gIHRlbXBsYXRlOiBzdHJpbmd8bnVsbDtcbiAgdGVtcGxhdGVVcmw6IHN0cmluZ3xudWxsO1xuICBzdHlsZXM6IHN0cmluZ1tdO1xuICBzdHlsZVVybHM6IHN0cmluZ1tdO1xuICBpbnRlcnBvbGF0aW9uOiBbc3RyaW5nLCBzdHJpbmddfG51bGw7XG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9ufG51bGw7XG4gIGFuaW1hdGlvbnM6IGFueVtdO1xuICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBib29sZWFufG51bGw7XG59XG5cbmV4cG9ydCBjbGFzcyBEaXJlY3RpdmVOb3JtYWxpemVyIHtcbiAgcHJpdmF0ZSBfcmVzb3VyY2VMb2FkZXJDYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBTeW5jQXN5bmM8c3RyaW5nPj4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgX3Jlc291cmNlTG9hZGVyOiBSZXNvdXJjZUxvYWRlciwgcHJpdmF0ZSBfdXJsUmVzb2x2ZXI6IFVybFJlc29sdmVyLFxuICAgICAgcHJpdmF0ZSBfaHRtbFBhcnNlcjogSHRtbFBhcnNlciwgcHJpdmF0ZSBfY29uZmlnOiBDb21waWxlckNvbmZpZykge31cblxuICBjbGVhckNhY2hlKCk6IHZvaWQge1xuICAgIHRoaXMuX3Jlc291cmNlTG9hZGVyQ2FjaGUuY2xlYXIoKTtcbiAgfVxuXG4gIGNsZWFyQ2FjaGVGb3Iobm9ybWFsaXplZERpcmVjdGl2ZTogQ29tcGlsZURpcmVjdGl2ZU1ldGFkYXRhKTogdm9pZCB7XG4gICAgaWYgKCFub3JtYWxpemVkRGlyZWN0aXZlLmlzQ29tcG9uZW50KSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHRlbXBsYXRlID0gbm9ybWFsaXplZERpcmVjdGl2ZS50ZW1wbGF0ZSAhO1xuICAgIHRoaXMuX3Jlc291cmNlTG9hZGVyQ2FjaGUuZGVsZXRlKHRlbXBsYXRlLnRlbXBsYXRlVXJsISk7XG4gICAgdGVtcGxhdGUuZXh0ZXJuYWxTdHlsZXNoZWV0cy5mb3JFYWNoKChzdHlsZXNoZWV0KSA9PiB7XG4gICAgICB0aGlzLl9yZXNvdXJjZUxvYWRlckNhY2hlLmRlbGV0ZShzdHlsZXNoZWV0Lm1vZHVsZVVybCEpO1xuICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBfZmV0Y2godXJsOiBzdHJpbmcpOiBTeW5jQXN5bmM8c3RyaW5nPiB7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMuX3Jlc291cmNlTG9hZGVyQ2FjaGUuZ2V0KHVybCk7XG4gICAgaWYgKCFyZXN1bHQpIHtcbiAgICAgIHJlc3VsdCA9IHRoaXMuX3Jlc291cmNlTG9hZGVyLmdldCh1cmwpO1xuICAgICAgdGhpcy5fcmVzb3VyY2VMb2FkZXJDYWNoZS5zZXQodXJsLCByZXN1bHQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgbm9ybWFsaXplVGVtcGxhdGUocHJlbm9ybURhdGE6IFByZW5vcm1hbGl6ZWRUZW1wbGF0ZU1ldGFkYXRhKTpcbiAgICAgIFN5bmNBc3luYzxDb21waWxlVGVtcGxhdGVNZXRhZGF0YT4ge1xuICAgIGlmIChpc0RlZmluZWQocHJlbm9ybURhdGEudGVtcGxhdGUpKSB7XG4gICAgICBpZiAoaXNEZWZpbmVkKHByZW5vcm1EYXRhLnRlbXBsYXRlVXJsKSkge1xuICAgICAgICB0aHJvdyBzeW50YXhFcnJvcihgJyR7XG4gICAgICAgICAgICBzdHJpbmdpZnkocHJlbm9ybURhdGFcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLmNvbXBvbmVudFR5cGUpfScgY29tcG9uZW50IGNhbm5vdCBkZWZpbmUgYm90aCB0ZW1wbGF0ZSBhbmQgdGVtcGxhdGVVcmxgKTtcbiAgICAgIH1cbiAgICAgIGlmICh0eXBlb2YgcHJlbm9ybURhdGEudGVtcGxhdGUgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgIHRocm93IHN5bnRheEVycm9yKGBUaGUgdGVtcGxhdGUgc3BlY2lmaWVkIGZvciBjb21wb25lbnQgJHtcbiAgICAgICAgICAgIHN0cmluZ2lmeShwcmVub3JtRGF0YS5jb21wb25lbnRUeXBlKX0gaXMgbm90IGEgc3RyaW5nYCk7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc0RlZmluZWQocHJlbm9ybURhdGEudGVtcGxhdGVVcmwpKSB7XG4gICAgICBpZiAodHlwZW9mIHByZW5vcm1EYXRhLnRlbXBsYXRlVXJsICE9PSAnc3RyaW5nJykge1xuICAgICAgICB0aHJvdyBzeW50YXhFcnJvcihgVGhlIHRlbXBsYXRlVXJsIHNwZWNpZmllZCBmb3IgY29tcG9uZW50ICR7XG4gICAgICAgICAgICBzdHJpbmdpZnkocHJlbm9ybURhdGEuY29tcG9uZW50VHlwZSl9IGlzIG5vdCBhIHN0cmluZ2ApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB0aHJvdyBzeW50YXhFcnJvcihcbiAgICAgICAgICBgTm8gdGVtcGxhdGUgc3BlY2lmaWVkIGZvciBjb21wb25lbnQgJHtzdHJpbmdpZnkocHJlbm9ybURhdGEuY29tcG9uZW50VHlwZSl9YCk7XG4gICAgfVxuXG4gICAgaWYgKGlzRGVmaW5lZChwcmVub3JtRGF0YS5wcmVzZXJ2ZVdoaXRlc3BhY2VzKSAmJlxuICAgICAgICB0eXBlb2YgcHJlbm9ybURhdGEucHJlc2VydmVXaGl0ZXNwYWNlcyAhPT0gJ2Jvb2xlYW4nKSB7XG4gICAgICB0aHJvdyBzeW50YXhFcnJvcihgVGhlIHByZXNlcnZlV2hpdGVzcGFjZXMgb3B0aW9uIGZvciBjb21wb25lbnQgJHtcbiAgICAgICAgICBzdHJpbmdpZnkocHJlbm9ybURhdGEuY29tcG9uZW50VHlwZSl9IG11c3QgYmUgYSBib29sZWFuYCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIFN5bmNBc3luYy50aGVuKFxuICAgICAgICB0aGlzLl9wcmVQYXJzZVRlbXBsYXRlKHByZW5vcm1EYXRhKSxcbiAgICAgICAgKHByZXBhcnNlZFRlbXBsYXRlKSA9PiB0aGlzLl9ub3JtYWxpemVUZW1wbGF0ZU1ldGFkYXRhKHByZW5vcm1EYXRhLCBwcmVwYXJzZWRUZW1wbGF0ZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcHJlUGFyc2VUZW1wbGF0ZShwcmVub21EYXRhOiBQcmVub3JtYWxpemVkVGVtcGxhdGVNZXRhZGF0YSk6XG4gICAgICBTeW5jQXN5bmM8UHJlcGFyc2VkVGVtcGxhdGU+IHtcbiAgICBsZXQgdGVtcGxhdGU6IFN5bmNBc3luYzxzdHJpbmc+O1xuICAgIGxldCB0ZW1wbGF0ZVVybDogc3RyaW5nO1xuICAgIGlmIChwcmVub21EYXRhLnRlbXBsYXRlICE9IG51bGwpIHtcbiAgICAgIHRlbXBsYXRlID0gcHJlbm9tRGF0YS50ZW1wbGF0ZTtcbiAgICAgIHRlbXBsYXRlVXJsID0gcHJlbm9tRGF0YS5tb2R1bGVVcmw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRlbXBsYXRlVXJsID0gdGhpcy5fdXJsUmVzb2x2ZXIucmVzb2x2ZShwcmVub21EYXRhLm1vZHVsZVVybCwgcHJlbm9tRGF0YS50ZW1wbGF0ZVVybCEpO1xuICAgICAgdGVtcGxhdGUgPSB0aGlzLl9mZXRjaCh0ZW1wbGF0ZVVybCk7XG4gICAgfVxuICAgIHJldHVybiBTeW5jQXN5bmMudGhlbihcbiAgICAgICAgdGVtcGxhdGUsICh0ZW1wbGF0ZSkgPT4gdGhpcy5fcHJlcGFyc2VMb2FkZWRUZW1wbGF0ZShwcmVub21EYXRhLCB0ZW1wbGF0ZSwgdGVtcGxhdGVVcmwpKTtcbiAgfVxuXG4gIHByaXZhdGUgX3ByZXBhcnNlTG9hZGVkVGVtcGxhdGUoXG4gICAgICBwcmVub3JtRGF0YTogUHJlbm9ybWFsaXplZFRlbXBsYXRlTWV0YWRhdGEsIHRlbXBsYXRlOiBzdHJpbmcsXG4gICAgICB0ZW1wbGF0ZUFic1VybDogc3RyaW5nKTogUHJlcGFyc2VkVGVtcGxhdGUge1xuICAgIGNvbnN0IGlzSW5saW5lID0gISFwcmVub3JtRGF0YS50ZW1wbGF0ZTtcbiAgICBjb25zdCBpbnRlcnBvbGF0aW9uQ29uZmlnID0gSW50ZXJwb2xhdGlvbkNvbmZpZy5mcm9tQXJyYXkocHJlbm9ybURhdGEuaW50ZXJwb2xhdGlvbiEpO1xuICAgIGNvbnN0IHRlbXBsYXRlVXJsID0gdGVtcGxhdGVTb3VyY2VVcmwoXG4gICAgICAgIHtyZWZlcmVuY2U6IHByZW5vcm1EYXRhLm5nTW9kdWxlVHlwZX0sIHt0eXBlOiB7cmVmZXJlbmNlOiBwcmVub3JtRGF0YS5jb21wb25lbnRUeXBlfX0sXG4gICAgICAgIHtpc0lubGluZSwgdGVtcGxhdGVVcmw6IHRlbXBsYXRlQWJzVXJsfSk7XG4gICAgY29uc3Qgcm9vdE5vZGVzQW5kRXJyb3JzID0gdGhpcy5faHRtbFBhcnNlci5wYXJzZShcbiAgICAgICAgdGVtcGxhdGUsIHRlbXBsYXRlVXJsLCB7dG9rZW5pemVFeHBhbnNpb25Gb3JtczogdHJ1ZSwgaW50ZXJwb2xhdGlvbkNvbmZpZ30pO1xuICAgIGlmIChyb290Tm9kZXNBbmRFcnJvcnMuZXJyb3JzLmxlbmd0aCA+IDApIHtcbiAgICAgIGNvbnN0IGVycm9yU3RyaW5nID0gcm9vdE5vZGVzQW5kRXJyb3JzLmVycm9ycy5qb2luKCdcXG4nKTtcbiAgICAgIHRocm93IHN5bnRheEVycm9yKGBUZW1wbGF0ZSBwYXJzZSBlcnJvcnM6XFxuJHtlcnJvclN0cmluZ31gKTtcbiAgICB9XG5cbiAgICBjb25zdCB0ZW1wbGF0ZU1ldGFkYXRhU3R5bGVzID0gdGhpcy5fbm9ybWFsaXplU3R5bGVzaGVldChuZXcgQ29tcGlsZVN0eWxlc2hlZXRNZXRhZGF0YShcbiAgICAgICAge3N0eWxlczogcHJlbm9ybURhdGEuc3R5bGVzLCBtb2R1bGVVcmw6IHByZW5vcm1EYXRhLm1vZHVsZVVybH0pKTtcblxuICAgIGNvbnN0IHZpc2l0b3IgPSBuZXcgVGVtcGxhdGVQcmVwYXJzZVZpc2l0b3IoKTtcbiAgICBodG1sLnZpc2l0QWxsKHZpc2l0b3IsIHJvb3ROb2Rlc0FuZEVycm9ycy5yb290Tm9kZXMpO1xuICAgIGNvbnN0IHRlbXBsYXRlU3R5bGVzID0gdGhpcy5fbm9ybWFsaXplU3R5bGVzaGVldChuZXcgQ29tcGlsZVN0eWxlc2hlZXRNZXRhZGF0YShcbiAgICAgICAge3N0eWxlczogdmlzaXRvci5zdHlsZXMsIHN0eWxlVXJsczogdmlzaXRvci5zdHlsZVVybHMsIG1vZHVsZVVybDogdGVtcGxhdGVBYnNVcmx9KSk7XG5cbiAgICBjb25zdCBzdHlsZXMgPSB0ZW1wbGF0ZU1ldGFkYXRhU3R5bGVzLnN0eWxlcy5jb25jYXQodGVtcGxhdGVTdHlsZXMuc3R5bGVzKTtcblxuICAgIGNvbnN0IGlubGluZVN0eWxlVXJscyA9IHRlbXBsYXRlTWV0YWRhdGFTdHlsZXMuc3R5bGVVcmxzLmNvbmNhdCh0ZW1wbGF0ZVN0eWxlcy5zdHlsZVVybHMpO1xuICAgIGNvbnN0IHN0eWxlVXJscyA9IHRoaXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLl9ub3JtYWxpemVTdHlsZXNoZWV0KG5ldyBDb21waWxlU3R5bGVzaGVldE1ldGFkYXRhKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAge3N0eWxlVXJsczogcHJlbm9ybURhdGEuc3R5bGVVcmxzLCBtb2R1bGVVcmw6IHByZW5vcm1EYXRhLm1vZHVsZVVybH0pKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAuc3R5bGVVcmxzO1xuICAgIHJldHVybiB7XG4gICAgICB0ZW1wbGF0ZSxcbiAgICAgIHRlbXBsYXRlVXJsOiB0ZW1wbGF0ZUFic1VybCxcbiAgICAgIGlzSW5saW5lLFxuICAgICAgaHRtbEFzdDogcm9vdE5vZGVzQW5kRXJyb3JzLFxuICAgICAgc3R5bGVzLFxuICAgICAgaW5saW5lU3R5bGVVcmxzLFxuICAgICAgc3R5bGVVcmxzLFxuICAgICAgbmdDb250ZW50U2VsZWN0b3JzOiB2aXNpdG9yLm5nQ29udGVudFNlbGVjdG9ycyxcbiAgICB9O1xuICB9XG5cbiAgcHJpdmF0ZSBfbm9ybWFsaXplVGVtcGxhdGVNZXRhZGF0YShcbiAgICAgIHByZW5vcm1EYXRhOiBQcmVub3JtYWxpemVkVGVtcGxhdGVNZXRhZGF0YSxcbiAgICAgIHByZXBhcnNlZFRlbXBsYXRlOiBQcmVwYXJzZWRUZW1wbGF0ZSk6IFN5bmNBc3luYzxDb21waWxlVGVtcGxhdGVNZXRhZGF0YT4ge1xuICAgIHJldHVybiBTeW5jQXN5bmMudGhlbihcbiAgICAgICAgdGhpcy5fbG9hZE1pc3NpbmdFeHRlcm5hbFN0eWxlc2hlZXRzKFxuICAgICAgICAgICAgcHJlcGFyc2VkVGVtcGxhdGUuc3R5bGVVcmxzLmNvbmNhdChwcmVwYXJzZWRUZW1wbGF0ZS5pbmxpbmVTdHlsZVVybHMpKSxcbiAgICAgICAgKGV4dGVybmFsU3R5bGVzaGVldHMpID0+IHRoaXMuX25vcm1hbGl6ZUxvYWRlZFRlbXBsYXRlTWV0YWRhdGEoXG4gICAgICAgICAgICBwcmVub3JtRGF0YSwgcHJlcGFyc2VkVGVtcGxhdGUsIGV4dGVybmFsU3R5bGVzaGVldHMpKTtcbiAgfVxuXG4gIHByaXZhdGUgX25vcm1hbGl6ZUxvYWRlZFRlbXBsYXRlTWV0YWRhdGEoXG4gICAgICBwcmVub3JtRGF0YTogUHJlbm9ybWFsaXplZFRlbXBsYXRlTWV0YWRhdGEsIHByZXBhcnNlZFRlbXBsYXRlOiBQcmVwYXJzZWRUZW1wbGF0ZSxcbiAgICAgIHN0eWxlc2hlZXRzOiBNYXA8c3RyaW5nLCBDb21waWxlU3R5bGVzaGVldE1ldGFkYXRhPik6IENvbXBpbGVUZW1wbGF0ZU1ldGFkYXRhIHtcbiAgICAvLyBBbGdvcml0aG06XG4gICAgLy8gLSBwcm9kdWNlIGV4YWN0bHkgMSBlbnRyeSBwZXIgb3JpZ2luYWwgc3R5bGVVcmwgaW5cbiAgICAvLyBDb21waWxlVGVtcGxhdGVNZXRhZGF0YS5leHRlcm5hbFN0eWxlc2hlZXRzIHdpdGggYWxsIHN0eWxlcyBpbmxpbmVkXG4gICAgLy8gLSBpbmxpbmUgYWxsIHN0eWxlcyB0aGF0IGFyZSByZWZlcmVuY2VkIGJ5IHRoZSB0ZW1wbGF0ZSBpbnRvIENvbXBpbGVUZW1wbGF0ZU1ldGFkYXRhLnN0eWxlcy5cbiAgICAvLyBSZWFzb246IGJlIGFibGUgdG8gZGV0ZXJtaW5lIGhvdyBtYW55IHN0eWxlc2hlZXRzIHRoZXJlIGFyZSBldmVuIHdpdGhvdXQgbG9hZGluZ1xuICAgIC8vIHRoZSB0ZW1wbGF0ZSBub3IgdGhlIHN0eWxlc2hlZXRzLCBzbyB3ZSBjYW4gY3JlYXRlIGEgc3R1YiBmb3IgVHlwZVNjcmlwdCBhbHdheXMgc3luY2hyb25vdXNseVxuICAgIC8vIChhcyByZXNvdXJjZSBsb2FkaW5nIG1heSBiZSBhc3luYylcblxuICAgIGNvbnN0IHN0eWxlcyA9IFsuLi5wcmVwYXJzZWRUZW1wbGF0ZS5zdHlsZXNdO1xuICAgIHRoaXMuX2lubGluZVN0eWxlcyhwcmVwYXJzZWRUZW1wbGF0ZS5pbmxpbmVTdHlsZVVybHMsIHN0eWxlc2hlZXRzLCBzdHlsZXMpO1xuICAgIGNvbnN0IHN0eWxlVXJscyA9IHByZXBhcnNlZFRlbXBsYXRlLnN0eWxlVXJscztcblxuICAgIGNvbnN0IGV4dGVybmFsU3R5bGVzaGVldHMgPSBzdHlsZVVybHMubWFwKHN0eWxlVXJsID0+IHtcbiAgICAgIGNvbnN0IHN0eWxlc2hlZXQgPSBzdHlsZXNoZWV0cy5nZXQoc3R5bGVVcmwpITtcbiAgICAgIGNvbnN0IHN0eWxlcyA9IFsuLi5zdHlsZXNoZWV0LnN0eWxlc107XG4gICAgICB0aGlzLl9pbmxpbmVTdHlsZXMoc3R5bGVzaGVldC5zdHlsZVVybHMsIHN0eWxlc2hlZXRzLCBzdHlsZXMpO1xuICAgICAgcmV0dXJuIG5ldyBDb21waWxlU3R5bGVzaGVldE1ldGFkYXRhKHttb2R1bGVVcmw6IHN0eWxlVXJsLCBzdHlsZXM6IHN0eWxlc30pO1xuICAgIH0pO1xuXG4gICAgbGV0IGVuY2Fwc3VsYXRpb24gPSBwcmVub3JtRGF0YS5lbmNhcHN1bGF0aW9uO1xuICAgIGlmIChlbmNhcHN1bGF0aW9uID09IG51bGwpIHtcbiAgICAgIGVuY2Fwc3VsYXRpb24gPSB0aGlzLl9jb25maWcuZGVmYXVsdEVuY2Fwc3VsYXRpb247XG4gICAgfVxuICAgIGlmIChlbmNhcHN1bGF0aW9uID09PSBWaWV3RW5jYXBzdWxhdGlvbi5FbXVsYXRlZCAmJiBzdHlsZXMubGVuZ3RoID09PSAwICYmXG4gICAgICAgIHN0eWxlVXJscy5sZW5ndGggPT09IDApIHtcbiAgICAgIGVuY2Fwc3VsYXRpb24gPSBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IENvbXBpbGVUZW1wbGF0ZU1ldGFkYXRhKHtcbiAgICAgIGVuY2Fwc3VsYXRpb24sXG4gICAgICB0ZW1wbGF0ZTogcHJlcGFyc2VkVGVtcGxhdGUudGVtcGxhdGUsXG4gICAgICB0ZW1wbGF0ZVVybDogcHJlcGFyc2VkVGVtcGxhdGUudGVtcGxhdGVVcmwsXG4gICAgICBodG1sQXN0OiBwcmVwYXJzZWRUZW1wbGF0ZS5odG1sQXN0LFxuICAgICAgc3R5bGVzLFxuICAgICAgc3R5bGVVcmxzLFxuICAgICAgbmdDb250ZW50U2VsZWN0b3JzOiBwcmVwYXJzZWRUZW1wbGF0ZS5uZ0NvbnRlbnRTZWxlY3RvcnMsXG4gICAgICBhbmltYXRpb25zOiBwcmVub3JtRGF0YS5hbmltYXRpb25zLFxuICAgICAgaW50ZXJwb2xhdGlvbjogcHJlbm9ybURhdGEuaW50ZXJwb2xhdGlvbixcbiAgICAgIGlzSW5saW5lOiBwcmVwYXJzZWRUZW1wbGF0ZS5pc0lubGluZSxcbiAgICAgIGV4dGVybmFsU3R5bGVzaGVldHMsXG4gICAgICBwcmVzZXJ2ZVdoaXRlc3BhY2VzOiBwcmVzZXJ2ZVdoaXRlc3BhY2VzRGVmYXVsdChcbiAgICAgICAgICBwcmVub3JtRGF0YS5wcmVzZXJ2ZVdoaXRlc3BhY2VzLCB0aGlzLl9jb25maWcucHJlc2VydmVXaGl0ZXNwYWNlcyksXG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9pbmxpbmVTdHlsZXMoXG4gICAgICBzdHlsZVVybHM6IHN0cmluZ1tdLCBzdHlsZXNoZWV0czogTWFwPHN0cmluZywgQ29tcGlsZVN0eWxlc2hlZXRNZXRhZGF0YT4sXG4gICAgICB0YXJnZXRTdHlsZXM6IHN0cmluZ1tdKSB7XG4gICAgc3R5bGVVcmxzLmZvckVhY2goc3R5bGVVcmwgPT4ge1xuICAgICAgY29uc3Qgc3R5bGVzaGVldCA9IHN0eWxlc2hlZXRzLmdldChzdHlsZVVybCkhO1xuICAgICAgc3R5bGVzaGVldC5zdHlsZXMuZm9yRWFjaChzdHlsZSA9PiB0YXJnZXRTdHlsZXMucHVzaChzdHlsZSkpO1xuICAgICAgdGhpcy5faW5saW5lU3R5bGVzKHN0eWxlc2hlZXQuc3R5bGVVcmxzLCBzdHlsZXNoZWV0cywgdGFyZ2V0U3R5bGVzKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX2xvYWRNaXNzaW5nRXh0ZXJuYWxTdHlsZXNoZWV0cyhcbiAgICAgIHN0eWxlVXJsczogc3RyaW5nW10sXG4gICAgICBsb2FkZWRTdHlsZXNoZWV0czpcbiAgICAgICAgICBNYXA8c3RyaW5nLCBDb21waWxlU3R5bGVzaGVldE1ldGFkYXRhPiA9IG5ldyBNYXA8c3RyaW5nLCBDb21waWxlU3R5bGVzaGVldE1ldGFkYXRhPigpKTpcbiAgICAgIFN5bmNBc3luYzxNYXA8c3RyaW5nLCBDb21waWxlU3R5bGVzaGVldE1ldGFkYXRhPj4ge1xuICAgIHJldHVybiBTeW5jQXN5bmMudGhlbihcbiAgICAgICAgU3luY0FzeW5jLmFsbChzdHlsZVVybHMuZmlsdGVyKChzdHlsZVVybCkgPT4gIWxvYWRlZFN0eWxlc2hlZXRzLmhhcyhzdHlsZVVybCkpXG4gICAgICAgICAgICAgICAgICAgICAgICAgIC5tYXAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzdHlsZVVybCA9PiBTeW5jQXN5bmMudGhlbihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9mZXRjaChzdHlsZVVybCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGxvYWRlZFN0eWxlKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBzdHlsZXNoZWV0ID1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLl9ub3JtYWxpemVTdHlsZXNoZWV0KG5ldyBDb21waWxlU3R5bGVzaGVldE1ldGFkYXRhKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7c3R5bGVzOiBbbG9hZGVkU3R5bGVdLCBtb2R1bGVVcmw6IHN0eWxlVXJsfSkpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbG9hZGVkU3R5bGVzaGVldHMuc2V0KHN0eWxlVXJsLCBzdHlsZXNoZWV0KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiB0aGlzLl9sb2FkTWlzc2luZ0V4dGVybmFsU3R5bGVzaGVldHMoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgc3R5bGVzaGVldC5zdHlsZVVybHMsIGxvYWRlZFN0eWxlc2hlZXRzKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KSkpLFxuICAgICAgICAoXykgPT4gbG9hZGVkU3R5bGVzaGVldHMpO1xuICB9XG5cbiAgcHJpdmF0ZSBfbm9ybWFsaXplU3R5bGVzaGVldChzdHlsZXNoZWV0OiBDb21waWxlU3R5bGVzaGVldE1ldGFkYXRhKTogQ29tcGlsZVN0eWxlc2hlZXRNZXRhZGF0YSB7XG4gICAgY29uc3QgbW9kdWxlVXJsID0gc3R5bGVzaGVldC5tb2R1bGVVcmwhO1xuICAgIGNvbnN0IGFsbFN0eWxlVXJscyA9IHN0eWxlc2hlZXQuc3R5bGVVcmxzLmZpbHRlcihpc1N0eWxlVXJsUmVzb2x2YWJsZSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLm1hcCh1cmwgPT4gdGhpcy5fdXJsUmVzb2x2ZXIucmVzb2x2ZShtb2R1bGVVcmwsIHVybCkpO1xuXG4gICAgY29uc3QgYWxsU3R5bGVzID0gc3R5bGVzaGVldC5zdHlsZXMubWFwKHN0eWxlID0+IHtcbiAgICAgIGNvbnN0IHN0eWxlV2l0aEltcG9ydHMgPSBleHRyYWN0U3R5bGVVcmxzKHRoaXMuX3VybFJlc29sdmVyLCBtb2R1bGVVcmwsIHN0eWxlKTtcbiAgICAgIGFsbFN0eWxlVXJscy5wdXNoKC4uLnN0eWxlV2l0aEltcG9ydHMuc3R5bGVVcmxzKTtcbiAgICAgIHJldHVybiBzdHlsZVdpdGhJbXBvcnRzLnN0eWxlO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIG5ldyBDb21waWxlU3R5bGVzaGVldE1ldGFkYXRhKFxuICAgICAgICB7c3R5bGVzOiBhbGxTdHlsZXMsIHN0eWxlVXJsczogYWxsU3R5bGVVcmxzLCBtb2R1bGVVcmw6IG1vZHVsZVVybH0pO1xuICB9XG59XG5cbmludGVyZmFjZSBQcmVwYXJzZWRUZW1wbGF0ZSB7XG4gIHRlbXBsYXRlOiBzdHJpbmc7XG4gIHRlbXBsYXRlVXJsOiBzdHJpbmc7XG4gIGlzSW5saW5lOiBib29sZWFuO1xuICBodG1sQXN0OiBIdG1sUGFyc2VUcmVlUmVzdWx0O1xuICBzdHlsZXM6IHN0cmluZ1tdO1xuICBpbmxpbmVTdHlsZVVybHM6IHN0cmluZ1tdO1xuICBzdHlsZVVybHM6IHN0cmluZ1tdO1xuICBuZ0NvbnRlbnRTZWxlY3RvcnM6IHN0cmluZ1tdO1xufVxuXG5jbGFzcyBUZW1wbGF0ZVByZXBhcnNlVmlzaXRvciBpbXBsZW1lbnRzIGh0bWwuVmlzaXRvciB7XG4gIG5nQ29udGVudFNlbGVjdG9yczogc3RyaW5nW10gPSBbXTtcbiAgc3R5bGVzOiBzdHJpbmdbXSA9IFtdO1xuICBzdHlsZVVybHM6IHN0cmluZ1tdID0gW107XG4gIG5nTm9uQmluZGFibGVTdGFja0NvdW50OiBudW1iZXIgPSAwO1xuXG4gIHZpc2l0RWxlbWVudChhc3Q6IGh0bWwuRWxlbWVudCwgY29udGV4dDogYW55KTogYW55IHtcbiAgICBjb25zdCBwcmVwYXJzZWRFbGVtZW50ID0gcHJlcGFyc2VFbGVtZW50KGFzdCk7XG4gICAgc3dpdGNoIChwcmVwYXJzZWRFbGVtZW50LnR5cGUpIHtcbiAgICAgIGNhc2UgUHJlcGFyc2VkRWxlbWVudFR5cGUuTkdfQ09OVEVOVDpcbiAgICAgICAgaWYgKHRoaXMubmdOb25CaW5kYWJsZVN0YWNrQ291bnQgPT09IDApIHtcbiAgICAgICAgICB0aGlzLm5nQ29udGVudFNlbGVjdG9ycy5wdXNoKHByZXBhcnNlZEVsZW1lbnQuc2VsZWN0QXR0cik7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFByZXBhcnNlZEVsZW1lbnRUeXBlLlNUWUxFOlxuICAgICAgICBsZXQgdGV4dENvbnRlbnQgPSAnJztcbiAgICAgICAgYXN0LmNoaWxkcmVuLmZvckVhY2goY2hpbGQgPT4ge1xuICAgICAgICAgIGlmIChjaGlsZCBpbnN0YW5jZW9mIGh0bWwuVGV4dCkge1xuICAgICAgICAgICAgdGV4dENvbnRlbnQgKz0gY2hpbGQudmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICAgICAgdGhpcy5zdHlsZXMucHVzaCh0ZXh0Q29udGVudCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSBQcmVwYXJzZWRFbGVtZW50VHlwZS5TVFlMRVNIRUVUOlxuICAgICAgICB0aGlzLnN0eWxlVXJscy5wdXNoKHByZXBhcnNlZEVsZW1lbnQuaHJlZkF0dHIpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBpZiAocHJlcGFyc2VkRWxlbWVudC5ub25CaW5kYWJsZSkge1xuICAgICAgdGhpcy5uZ05vbkJpbmRhYmxlU3RhY2tDb3VudCsrO1xuICAgIH1cbiAgICBodG1sLnZpc2l0QWxsKHRoaXMsIGFzdC5jaGlsZHJlbik7XG4gICAgaWYgKHByZXBhcnNlZEVsZW1lbnQubm9uQmluZGFibGUpIHtcbiAgICAgIHRoaXMubmdOb25CaW5kYWJsZVN0YWNrQ291bnQtLTtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICB2aXNpdEV4cGFuc2lvbihhc3Q6IGh0bWwuRXhwYW5zaW9uLCBjb250ZXh0OiBhbnkpOiBhbnkge1xuICAgIGh0bWwudmlzaXRBbGwodGhpcywgYXN0LmNhc2VzKTtcbiAgfVxuXG4gIHZpc2l0RXhwYW5zaW9uQ2FzZShhc3Q6IGh0bWwuRXhwYW5zaW9uQ2FzZSwgY29udGV4dDogYW55KTogYW55IHtcbiAgICBodG1sLnZpc2l0QWxsKHRoaXMsIGFzdC5leHByZXNzaW9uKTtcbiAgfVxuXG4gIHZpc2l0Q29tbWVudChhc3Q6IGh0bWwuQ29tbWVudCwgY29udGV4dDogYW55KTogYW55IHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICB2aXNpdEF0dHJpYnV0ZShhc3Q6IGh0bWwuQXR0cmlidXRlLCBjb250ZXh0OiBhbnkpOiBhbnkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIHZpc2l0VGV4dChhc3Q6IGh0bWwuVGV4dCwgY29udGV4dDogYW55KTogYW55IHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuIl19 |
---|