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/compiler-cli/src/transformers/inline_resources", ["require", "exports", "tslib", "typescript", "@angular/compiler-cli/src/metadata/index"], factory);
|
---|
15 | }
|
---|
16 | })(function (require, exports) {
|
---|
17 | "use strict";
|
---|
18 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
19 | exports.getInlineResourcesTransformFactory = exports.InlineResourcesMetadataTransformer = void 0;
|
---|
20 | var tslib_1 = require("tslib");
|
---|
21 | var ts = require("typescript");
|
---|
22 | var index_1 = require("@angular/compiler-cli/src/metadata/index");
|
---|
23 | var PRECONDITIONS_TEXT = 'angularCompilerOptions.enableResourceInlining requires all resources to be statically resolvable.';
|
---|
24 | function getResourceLoader(host, containingFileName) {
|
---|
25 | return {
|
---|
26 | get: function (url) {
|
---|
27 | if (typeof url !== 'string') {
|
---|
28 | throw new Error('templateUrl and stylesUrl must be string literals. ' + PRECONDITIONS_TEXT);
|
---|
29 | }
|
---|
30 | var fileName = host.resourceNameToFileName(url, containingFileName);
|
---|
31 | if (fileName) {
|
---|
32 | var content = host.loadResource(fileName);
|
---|
33 | if (typeof content !== 'string') {
|
---|
34 | throw new Error('Cannot handle async resource. ' + PRECONDITIONS_TEXT);
|
---|
35 | }
|
---|
36 | return content;
|
---|
37 | }
|
---|
38 | throw new Error("Failed to resolve " + url + " from " + containingFileName + ". " + PRECONDITIONS_TEXT);
|
---|
39 | }
|
---|
40 | };
|
---|
41 | }
|
---|
42 | var InlineResourcesMetadataTransformer = /** @class */ (function () {
|
---|
43 | function InlineResourcesMetadataTransformer(host) {
|
---|
44 | this.host = host;
|
---|
45 | }
|
---|
46 | InlineResourcesMetadataTransformer.prototype.start = function (sourceFile) {
|
---|
47 | var _this = this;
|
---|
48 | var loader = getResourceLoader(this.host, sourceFile.fileName);
|
---|
49 | return function (value, node) {
|
---|
50 | if (index_1.isClassMetadata(value) && ts.isClassDeclaration(node) && value.decorators) {
|
---|
51 | value.decorators.forEach(function (d) {
|
---|
52 | if (index_1.isMetadataSymbolicCallExpression(d) &&
|
---|
53 | index_1.isMetadataImportedSymbolReferenceExpression(d.expression) &&
|
---|
54 | d.expression.module === '@angular/core' && d.expression.name === 'Component' &&
|
---|
55 | d.arguments) {
|
---|
56 | // Arguments to an @Component that was compiled successfully are always
|
---|
57 | // MetadataObject(s).
|
---|
58 | d.arguments = d.arguments
|
---|
59 | .map(_this.updateDecoratorMetadata.bind(_this, loader));
|
---|
60 | }
|
---|
61 | });
|
---|
62 | }
|
---|
63 | return value;
|
---|
64 | };
|
---|
65 | };
|
---|
66 | InlineResourcesMetadataTransformer.prototype.updateDecoratorMetadata = function (loader, arg) {
|
---|
67 | if (arg['templateUrl']) {
|
---|
68 | arg['template'] = loader.get(arg['templateUrl']);
|
---|
69 | delete arg['templateUrl'];
|
---|
70 | }
|
---|
71 | var styles = arg['styles'] || [];
|
---|
72 | var styleUrls = arg['styleUrls'] || [];
|
---|
73 | if (!Array.isArray(styles))
|
---|
74 | throw new Error('styles should be an array');
|
---|
75 | if (!Array.isArray(styleUrls))
|
---|
76 | throw new Error('styleUrls should be an array');
|
---|
77 | styles.push.apply(styles, tslib_1.__spreadArray([], tslib_1.__read(styleUrls.map(function (styleUrl) { return loader.get(styleUrl); }))));
|
---|
78 | if (styles.length > 0) {
|
---|
79 | arg['styles'] = styles;
|
---|
80 | delete arg['styleUrls'];
|
---|
81 | }
|
---|
82 | return arg;
|
---|
83 | };
|
---|
84 | return InlineResourcesMetadataTransformer;
|
---|
85 | }());
|
---|
86 | exports.InlineResourcesMetadataTransformer = InlineResourcesMetadataTransformer;
|
---|
87 | function getInlineResourcesTransformFactory(program, host) {
|
---|
88 | return function (context) { return function (sourceFile) {
|
---|
89 | var loader = getResourceLoader(host, sourceFile.fileName);
|
---|
90 | var visitor = function (node) {
|
---|
91 | // Components are always classes; skip any other node
|
---|
92 | if (!ts.isClassDeclaration(node)) {
|
---|
93 | return node;
|
---|
94 | }
|
---|
95 | // Decorator case - before or without decorator downleveling
|
---|
96 | // @Component()
|
---|
97 | var newDecorators = ts.visitNodes(node.decorators, function (node) {
|
---|
98 | if (ts.isDecorator(node) && isComponentDecorator(node, program.getTypeChecker())) {
|
---|
99 | return updateDecorator(node, loader);
|
---|
100 | }
|
---|
101 | return node;
|
---|
102 | });
|
---|
103 | // Annotation case - after decorator downleveling
|
---|
104 | // static decorators: {type: Function, args?: any[]}[]
|
---|
105 | var newMembers = ts.visitNodes(node.members, function (node) {
|
---|
106 | if (ts.isClassElement(node)) {
|
---|
107 | return updateAnnotations(node, loader, program.getTypeChecker());
|
---|
108 | }
|
---|
109 | else {
|
---|
110 | return node;
|
---|
111 | }
|
---|
112 | });
|
---|
113 | // Create a new AST subtree with our modifications
|
---|
114 | return ts.updateClassDeclaration(node, newDecorators, node.modifiers, node.name, node.typeParameters, node.heritageClauses || [], newMembers);
|
---|
115 | };
|
---|
116 | return ts.visitEachChild(sourceFile, visitor, context);
|
---|
117 | }; };
|
---|
118 | }
|
---|
119 | exports.getInlineResourcesTransformFactory = getInlineResourcesTransformFactory;
|
---|
120 | /**
|
---|
121 | * Update a Decorator AST node to inline the resources
|
---|
122 | * @param node the @Component decorator
|
---|
123 | * @param loader provides access to load resources
|
---|
124 | */
|
---|
125 | function updateDecorator(node, loader) {
|
---|
126 | if (!ts.isCallExpression(node.expression)) {
|
---|
127 | // User will get an error somewhere else with bare @Component
|
---|
128 | return node;
|
---|
129 | }
|
---|
130 | var expr = node.expression;
|
---|
131 | var newArguments = updateComponentProperties(expr.arguments, loader);
|
---|
132 | return ts.updateDecorator(node, ts.updateCall(expr, expr.expression, expr.typeArguments, newArguments));
|
---|
133 | }
|
---|
134 | /**
|
---|
135 | * Update an Annotations AST node to inline the resources
|
---|
136 | * @param node the static decorators property
|
---|
137 | * @param loader provides access to load resources
|
---|
138 | * @param typeChecker provides access to symbol table
|
---|
139 | */
|
---|
140 | function updateAnnotations(node, loader, typeChecker) {
|
---|
141 | // Looking for a member of this shape:
|
---|
142 | // PropertyDeclaration called decorators, with static modifier
|
---|
143 | // Initializer is ArrayLiteralExpression
|
---|
144 | // One element is the Component type, its initializer is the @angular/core Component symbol
|
---|
145 | // One element is the component args, its initializer is the Component arguments to change
|
---|
146 | // e.g.
|
---|
147 | // static decorators: {type: Function, args?: any[]}[] =
|
---|
148 | // [{
|
---|
149 | // type: Component,
|
---|
150 | // args: [{
|
---|
151 | // templateUrl: './my.component.html',
|
---|
152 | // styleUrls: ['./my.component.css'],
|
---|
153 | // }],
|
---|
154 | // }];
|
---|
155 | if (!ts.isPropertyDeclaration(node) || // ts.ModifierFlags.Static &&
|
---|
156 | !ts.isIdentifier(node.name) || node.name.text !== 'decorators' || !node.initializer ||
|
---|
157 | !ts.isArrayLiteralExpression(node.initializer)) {
|
---|
158 | return node;
|
---|
159 | }
|
---|
160 | var newAnnotations = node.initializer.elements.map(function (annotation) {
|
---|
161 | // No-op if there's a non-object-literal mixed in the decorators values
|
---|
162 | if (!ts.isObjectLiteralExpression(annotation))
|
---|
163 | return annotation;
|
---|
164 | var decoratorType = annotation.properties.find(function (p) { return isIdentifierNamed(p, 'type'); });
|
---|
165 | // No-op if there's no 'type' property, or if it's not initialized to the Component symbol
|
---|
166 | if (!decoratorType || !ts.isPropertyAssignment(decoratorType) ||
|
---|
167 | !ts.isIdentifier(decoratorType.initializer) ||
|
---|
168 | !isComponentSymbol(decoratorType.initializer, typeChecker)) {
|
---|
169 | return annotation;
|
---|
170 | }
|
---|
171 | var newAnnotation = annotation.properties.map(function (prop) {
|
---|
172 | // No-op if this isn't the 'args' property or if it's not initialized to an array
|
---|
173 | if (!isIdentifierNamed(prop, 'args') || !ts.isPropertyAssignment(prop) ||
|
---|
174 | !ts.isArrayLiteralExpression(prop.initializer))
|
---|
175 | return prop;
|
---|
176 | var newDecoratorArgs = ts.updatePropertyAssignment(prop, prop.name, ts.createArrayLiteral(updateComponentProperties(prop.initializer.elements, loader)));
|
---|
177 | return newDecoratorArgs;
|
---|
178 | });
|
---|
179 | return ts.updateObjectLiteral(annotation, newAnnotation);
|
---|
180 | });
|
---|
181 | return ts.updateProperty(node, node.decorators, node.modifiers, node.name, node.questionToken, node.type, ts.updateArrayLiteral(node.initializer, newAnnotations));
|
---|
182 | }
|
---|
183 | function isIdentifierNamed(p, name) {
|
---|
184 | return !!p.name && ts.isIdentifier(p.name) && p.name.text === name;
|
---|
185 | }
|
---|
186 | /**
|
---|
187 | * Check that the node we are visiting is the actual Component decorator defined in @angular/core.
|
---|
188 | */
|
---|
189 | function isComponentDecorator(node, typeChecker) {
|
---|
190 | if (!ts.isCallExpression(node.expression)) {
|
---|
191 | return false;
|
---|
192 | }
|
---|
193 | var callExpr = node.expression;
|
---|
194 | var identifier;
|
---|
195 | if (ts.isIdentifier(callExpr.expression)) {
|
---|
196 | identifier = callExpr.expression;
|
---|
197 | }
|
---|
198 | else {
|
---|
199 | return false;
|
---|
200 | }
|
---|
201 | return isComponentSymbol(identifier, typeChecker);
|
---|
202 | }
|
---|
203 | function isComponentSymbol(identifier, typeChecker) {
|
---|
204 | // Only handle identifiers, not expressions
|
---|
205 | if (!ts.isIdentifier(identifier))
|
---|
206 | return false;
|
---|
207 | // NOTE: resolver.getReferencedImportDeclaration would work as well but is internal
|
---|
208 | var symbol = typeChecker.getSymbolAtLocation(identifier);
|
---|
209 | if (!symbol || !symbol.declarations || !symbol.declarations.length) {
|
---|
210 | console.error("Unable to resolve symbol '" + identifier.text + "' in the program, does it type-check?");
|
---|
211 | return false;
|
---|
212 | }
|
---|
213 | var declaration = symbol.declarations[0];
|
---|
214 | if (!declaration || !ts.isImportSpecifier(declaration)) {
|
---|
215 | return false;
|
---|
216 | }
|
---|
217 | var name = (declaration.propertyName || declaration.name).text;
|
---|
218 | // We know that parent pointers are set because we created the SourceFile ourselves.
|
---|
219 | // The number of parent references here match the recursion depth at this point.
|
---|
220 | var moduleId = declaration.parent.parent.parent.moduleSpecifier.text;
|
---|
221 | return moduleId === '@angular/core' && name === 'Component';
|
---|
222 | }
|
---|
223 | /**
|
---|
224 | * For each property in the object literal, if it's templateUrl or styleUrls, replace it
|
---|
225 | * with content.
|
---|
226 | * @param node the arguments to @Component() or args property of decorators: [{type:Component}]
|
---|
227 | * @param loader provides access to the loadResource method of the host
|
---|
228 | * @returns updated arguments
|
---|
229 | */
|
---|
230 | function updateComponentProperties(args, loader) {
|
---|
231 | if (args.length !== 1) {
|
---|
232 | // User should have gotten a type-check error because @Component takes one argument
|
---|
233 | return args;
|
---|
234 | }
|
---|
235 | var componentArg = args[0];
|
---|
236 | if (!ts.isObjectLiteralExpression(componentArg)) {
|
---|
237 | // User should have gotten a type-check error because @Component takes an object literal
|
---|
238 | // argument
|
---|
239 | return args;
|
---|
240 | }
|
---|
241 | var newProperties = [];
|
---|
242 | var newStyleExprs = [];
|
---|
243 | componentArg.properties.forEach(function (prop) {
|
---|
244 | if (!ts.isPropertyAssignment(prop) || ts.isComputedPropertyName(prop.name)) {
|
---|
245 | newProperties.push(prop);
|
---|
246 | return;
|
---|
247 | }
|
---|
248 | switch (prop.name.text) {
|
---|
249 | case 'styles':
|
---|
250 | if (!ts.isArrayLiteralExpression(prop.initializer)) {
|
---|
251 | throw new Error('styles takes an array argument');
|
---|
252 | }
|
---|
253 | newStyleExprs.push.apply(newStyleExprs, tslib_1.__spreadArray([], tslib_1.__read(prop.initializer.elements)));
|
---|
254 | break;
|
---|
255 | case 'styleUrls':
|
---|
256 | if (!ts.isArrayLiteralExpression(prop.initializer)) {
|
---|
257 | throw new Error('styleUrls takes an array argument');
|
---|
258 | }
|
---|
259 | newStyleExprs.push.apply(newStyleExprs, tslib_1.__spreadArray([], tslib_1.__read(prop.initializer.elements.map(function (expr) {
|
---|
260 | if (!ts.isStringLiteral(expr) && !ts.isNoSubstitutionTemplateLiteral(expr)) {
|
---|
261 | throw new Error('Can only accept string literal arguments to styleUrls. ' + PRECONDITIONS_TEXT);
|
---|
262 | }
|
---|
263 | var styles = loader.get(expr.text);
|
---|
264 | return ts.createLiteral(styles);
|
---|
265 | }))));
|
---|
266 | break;
|
---|
267 | case 'templateUrl':
|
---|
268 | if (!ts.isStringLiteral(prop.initializer) &&
|
---|
269 | !ts.isNoSubstitutionTemplateLiteral(prop.initializer)) {
|
---|
270 | throw new Error('Can only accept a string literal argument to templateUrl. ' + PRECONDITIONS_TEXT);
|
---|
271 | }
|
---|
272 | var template = loader.get(prop.initializer.text);
|
---|
273 | newProperties.push(ts.updatePropertyAssignment(prop, ts.createIdentifier('template'), ts.createLiteral(template)));
|
---|
274 | break;
|
---|
275 | default:
|
---|
276 | newProperties.push(prop);
|
---|
277 | }
|
---|
278 | });
|
---|
279 | // Add the non-inline styles
|
---|
280 | if (newStyleExprs.length > 0) {
|
---|
281 | var newStyles = ts.createPropertyAssignment(ts.createIdentifier('styles'), ts.createArrayLiteral(newStyleExprs));
|
---|
282 | newProperties.push(newStyles);
|
---|
283 | }
|
---|
284 | return ts.createNodeArray([ts.updateObjectLiteral(componentArg, newProperties)]);
|
---|
285 | }
|
---|
286 | });
|
---|
287 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5saW5lX3Jlc291cmNlcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2NvbXBpbGVyLWNsaS9zcmMvdHJhbnNmb3JtZXJzL2lubGluZV9yZXNvdXJjZXMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7OztHQU1HOzs7Ozs7Ozs7Ozs7OztJQUVILCtCQUFpQztJQUVqQyxrRUFBZ0s7SUFJaEssSUFBTSxrQkFBa0IsR0FDcEIsbUdBQW1HLENBQUM7SUFZeEcsU0FBUyxpQkFBaUIsQ0FBQyxJQUFtQixFQUFFLGtCQUEwQjtRQUN4RSxPQUFPO1lBQ0wsR0FBRyxFQUFILFVBQUksR0FBeUI7Z0JBQzNCLElBQUksT0FBTyxHQUFHLEtBQUssUUFBUSxFQUFFO29CQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLHFEQUFxRCxHQUFHLGtCQUFrQixDQUFDLENBQUM7aUJBQzdGO2dCQUNELElBQU0sUUFBUSxHQUFHLElBQUksQ0FBQyxzQkFBc0IsQ0FBQyxHQUFHLEVBQUUsa0JBQWtCLENBQUMsQ0FBQztnQkFDdEUsSUFBSSxRQUFRLEVBQUU7b0JBQ1osSUFBTSxPQUFPLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDNUMsSUFBSSxPQUFPLE9BQU8sS0FBSyxRQUFRLEVBQUU7d0JBQy9CLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0NBQWdDLEdBQUcsa0JBQWtCLENBQUMsQ0FBQztxQkFDeEU7b0JBQ0QsT0FBTyxPQUFPLENBQUM7aUJBQ2hCO2dCQUNELE1BQU0sSUFBSSxLQUFLLENBQUMsdUJBQXFCLEdBQUcsY0FBUyxrQkFBa0IsVUFBSyxrQkFBb0IsQ0FBQyxDQUFDO1lBQ2hHLENBQUM7U0FDRixDQUFDO0lBQ0osQ0FBQztJQUVEO1FBQ0UsNENBQW9CLElBQW1CO1lBQW5CLFNBQUksR0FBSixJQUFJLENBQWU7UUFBRyxDQUFDO1FBRTNDLGtEQUFLLEdBQUwsVUFB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QUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUN6RSxhQUFhLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1NBQy9CO1FBRUQsT0FBTyxFQUFFLENBQUMsZUFBZSxDQUFDLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLFlBQVksRUFBRSxhQUFhLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDbkYsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGxpY2Vuc2VcbiAqIENvcHlyaWdodCBHb29nbGUgTExDIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXG4gKlxuICogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiAqIGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGUgYXQgaHR0cHM6Ly9hbmd1bGFyLmlvL2xpY2Vuc2VcbiAqL1xuXG5pbXBvcnQgKiBhcyB0cyBmcm9tICd0eXBlc2NyaXB0JztcblxuaW1wb3J0IHtpc0NsYXNzTWV0YWRhdGEsIGlzTWV0YWRhdGFJbXBvcnRlZFN5bWJvbFJlZmVyZW5jZUV4cHJlc3Npb24sIGlzTWV0YWRhdGFTeW1ib2xpY0NhbGxFeHByZXNzaW9uLCBNZXRhZGF0YU9iamVjdCwgTWV0YWRhdGFWYWx1ZX0gZnJvbSAnLi4vbWV0YWRhdGEvaW5kZXgnO1xuXG5pbXBvcnQge01ldGFkYXRhVHJhbnNmb3JtZXIsIFZhbHVlVHJhbnNmb3JtfSBmcm9tICcuL21ldGFkYXRhX2NhY2hlJztcblxuY29uc3QgUFJFQ09ORElUSU9OU19URVhUID1cbiAgICAnYW5ndWxhckNvbXBpbGVyT3B0aW9ucy5lbmFibGVSZXNvdXJjZUlubGluaW5nIHJlcXVpcmVzIGFsbCByZXNvdXJjZXMgdG8gYmUgc3RhdGljYWxseSByZXNvbHZhYmxlLic7XG5cbi8qKiBBIHN1YnNldCBvZiBtZW1iZXJzIGZyb20gQW90Q29tcGlsZXJIb3N0ICovXG5leHBvcnQgdHlwZSBSZXNvdXJjZXNIb3N0ID0ge1xuICByZXNvdXJjZU5hbWVUb0ZpbGVOYW1lKHJlc291cmNlTmFtZTogc3RyaW5nLCBjb250YWluaW5nRmlsZU5hbWU6IHN0cmluZyk6IHN0cmluZ3xudWxsO1xuICBsb2FkUmVzb3VyY2UocGF0aDogc3RyaW5nKTogUHJvbWlzZTxzdHJpbmc+fCBzdHJpbmc7XG59O1xuXG5leHBvcnQgdHlwZSBTdGF0aWNSZXNvdXJjZUxvYWRlciA9IHtcbiAgZ2V0KHVybDogc3RyaW5nfE1ldGFkYXRhVmFsdWUpOiBzdHJpbmc7XG59O1xuXG5mdW5jdGlvbiBnZXRSZXNvdXJjZUxvYWRlcihob3N0OiBSZXNvdXJjZXNIb3N0LCBjb250YWluaW5nRmlsZU5hbWU6IHN0cmluZyk6IFN0YXRpY1Jlc291cmNlTG9hZGVyIHtcbiAgcmV0dXJuIHtcbiAgICBnZXQodXJsOiBzdHJpbmd8TWV0YWRhdGFWYWx1ZSk6IHN0cmluZyB7XG4gICAgICBpZiAodHlwZW9mIHVybCAhPT0gJ3N0cmluZycpIHtcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKCd0ZW1wbGF0ZVVybCBhbmQgc3R5bGVzVXJsIG11c3QgYmUgc3RyaW5nIGxpdGVyYWxzLiAnICsgUFJFQ09ORElUSU9OU19URVhUKTtcbiAgICAgIH1cbiAgICAgIGNvbnN0IGZpbGVOYW1lID0gaG9zdC5yZXNvdXJjZU5hbWVUb0ZpbGVOYW1lKHVybCwgY29udGFpbmluZ0ZpbGVOYW1lKTtcbiAgICAgIGlmIChmaWxlTmFtZSkge1xuICAgICAgICBjb25zdCBjb250ZW50ID0gaG9zdC5sb2FkUmVzb3VyY2UoZmlsZU5hbWUpO1xuICAgICAgICBpZiAodHlwZW9mIGNvbnRlbnQgIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdDYW5ub3QgaGFuZGxlIGFzeW5jIHJlc291cmNlLiAnICsgUFJFQ09ORElUSU9OU19URVhUKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gY29udGVudDtcbiAgICAgIH1cbiAgICAgIHRocm93IG5ldyBFcnJvcihgRmFpbGVkIHRvIHJlc29sdmUgJHt1cmx9IGZyb20gJHtjb250YWluaW5nRmlsZU5hbWV9LiAke1BSRUNPTkRJVElPTlNfVEVYVH1gKTtcbiAgICB9XG4gIH07XG59XG5cbmV4cG9ydCBjbGFzcyBJbmxpbmVSZXNvdXJjZXNNZXRhZGF0YVRyYW5zZm9ybWVyIGltcGxlbWVudHMgTWV0YWRhdGFUcmFuc2Zvcm1lciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgaG9zdDogUmVzb3VyY2VzSG9zdCkge31cblxuICBzdGFydChzb3VyY2VGaWxlOiB0cy5Tb3VyY2VGaWxlKTogVmFsdWVUcmFuc2Zvcm18dW5kZWZpbmVkIHtcbiAgICBjb25zdCBsb2FkZXIgPSBnZXRSZXNvdXJjZUxvYWRlcih0aGlzLmhvc3QsIHNvdXJjZUZpbGUuZmlsZU5hbWUpO1xuICAgIHJldHVybiAodmFsdWU6IE1ldGFkYXRhVmFsdWUsIG5vZGU6IHRzLk5vZGUpOiBNZXRhZGF0YVZhbHVlID0+IHtcbiAgICAgIGlmIChpc0NsYXNzTWV0YWRhdGEodmFsdWUpICYmIHRzLmlzQ2xhc3NEZWNsYXJhdGlvbihub2RlKSAmJiB2YWx1ZS5kZWNvcmF0b3JzKSB7XG4gICAgICAgIHZhbHVlLmRlY29yYXRvcnMuZm9yRWFjaChkID0+IHtcbiAgICAgICAgICBpZiAoaXNNZXRhZGF0YVN5bWJvbGljQ2FsbEV4cHJlc3Npb24oZCkgJiZcbiAgICAgICAgICAgICAgaXNNZXRhZGF0YUltcG9ydGVkU3ltYm9sUmVmZXJlbmNlRXhwcmVzc2lvbihkLmV4cHJlc3Npb24pICYmXG4gICAgICAgICAgICAgIGQuZXhwcmVzc2lvbi5tb2R1bGUgPT09ICdAYW5ndWxhci9jb3JlJyAmJiBkLmV4cHJlc3Npb24ubmFtZSA9PT0gJ0NvbXBvbmVudCcgJiZcbiAgICAgICAgICAgICAgZC5hcmd1bWVudHMpIHtcbiAgICAgICAgICAgIC8vIEFyZ3VtZW50cyB0byBhbiBAQ29tcG9uZW50IHRoYXQgd2FzIGNvbXBpbGVkIHN1Y2Nlc3NmdWxseSBhcmUgYWx3YXlzXG4gICAgICAgICAgICAvLyBNZXRhZGF0YU9iamVjdChzKS5cbiAgICAgICAgICAgIGQuYXJndW1lbnRzID0gKGQuYXJndW1lbnRzIGFzIE1ldGFkYXRhT2JqZWN0W10pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAubWFwKHRoaXMudXBkYXRlRGVjb3JhdG9yTWV0YWRhdGEuYmluZCh0aGlzLCBsb2FkZXIpKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgICAgcmV0dXJuIHZhbHVlO1xuICAgIH07XG4gIH1cblxuICB1cGRhdGVEZWNvcmF0b3JNZXRhZGF0YShsb2FkZXI6IFN0YXRpY1Jlc291cmNlTG9hZGVyLCBhcmc6IE1ldGFkYXRhT2JqZWN0KTogTWV0YWRhdGFPYmplY3Qge1xuICAgIGlmIChhcmdbJ3RlbXBsYXRlVXJsJ10pIHtcbiAgICAgIGFyZ1sndGVtcGxhdGUnXSA9IGxvYWRlci5nZXQoYXJnWyd0ZW1wbGF0ZVVybCddKTtcbiAgICAgIGRlbGV0ZSBhcmdbJ3RlbXBsYXRlVXJsJ107XG4gICAgfVxuXG4gICAgY29uc3Qgc3R5bGVzID0gYXJnWydzdHlsZXMnXSB8fCBbXTtcbiAgICBjb25zdCBzdHlsZVVybHMgPSBhcmdbJ3N0eWxlVXJscyddIHx8IFtdO1xuICAgIGlmICghQXJyYXkuaXNBcnJheShzdHlsZXMpKSB0aHJvdyBuZXcgRXJyb3IoJ3N0eWxlcyBzaG91bGQgYmUgYW4gYXJyYXknKTtcbiAgICBpZiAoIUFycmF5LmlzQXJyYXkoc3R5bGVVcmxzKSkgdGhyb3cgbmV3IEVycm9yKCdzdHlsZVVybHMgc2hvdWxkIGJlIGFuIGFycmF5Jyk7XG5cbiAgICBzdHlsZXMucHVzaCguLi5zdHlsZVVybHMubWFwKHN0eWxlVXJsID0+IGxvYWRlci5nZXQoc3R5bGVVcmwpKSk7XG4gICAgaWYgKHN0eWxlcy5sZW5ndGggPiAwKSB7XG4gICAgICBhcmdbJ3N0eWxlcyddID0gc3R5bGVzO1xuICAgICAgZGVsZXRlIGFyZ1snc3R5bGVVcmxzJ107XG4gICAgfVxuXG4gICAgcmV0dXJuIGFyZztcbiAgfVxufVxuXG5leHBvcnQgZnVuY3Rpb24gZ2V0SW5saW5lUmVzb3VyY2VzVHJhbnNmb3JtRmFjdG9yeShcbiAgICBwcm9ncmFtOiB0cy5Qcm9ncmFtLCBob3N0OiBSZXNvdXJjZXNIb3N0KTogdHMuVHJhbnNmb3JtZXJGYWN0b3J5PHRzLlNvdXJjZUZpbGU+IHtcbiAgcmV0dXJuIChjb250ZXh0OiB0cy5UcmFuc2Zvcm1hdGlvbkNvbnRleHQpID0+IChzb3VyY2VGaWxlOiB0cy5Tb3VyY2VGaWxlKSA9PiB7XG4gICAgY29uc3QgbG9hZGVyID0gZ2V0UmVzb3VyY2VMb2FkZXIoaG9zdCwgc291cmNlRmlsZS5maWxlTmFtZSk7XG4gICAgY29uc3QgdmlzaXRvcjogdHMuVmlzaXRvciA9IG5vZGUgPT4ge1xuICAgICAgLy8gQ29tcG9uZW50cyBhcmUgYWx3YXlzIGNsYXNzZXM7IHNraXAgYW55IG90aGVyIG5vZGVcbiAgICAgIGlmICghdHMuaXNDbGFzc0RlY2xhcmF0aW9uKG5vZGUpKSB7XG4gICAgICAgIHJldHVybiBub2RlO1xuICAgICAgfVxuXG4gICAgICAvLyBEZWNvcmF0b3IgY2FzZSAtIGJlZm9yZSBvciB3aXRob3V0IGRlY29yYXRvciBkb3dubGV2ZWxpbmdcbiAgICAgIC8vIEBDb21wb25lbnQoKVxuICAgICAgY29uc3QgbmV3RGVjb3JhdG9ycyA9IHRzLnZpc2l0Tm9kZXMobm9kZS5kZWNvcmF0b3JzLCAobm9kZTogdHMuTm9kZSkgPT4ge1xuICAgICAgICBpZiAodHMuaXNEZWNvcmF0b3Iobm9kZSkgJiYgaXNDb21wb25lbnREZWNvcmF0b3Iobm9kZSwgcHJvZ3JhbS5nZXRUeXBlQ2hlY2tlcigpKSkge1xuICAgICAgICAgIHJldHVybiB1cGRhdGVEZWNvcmF0b3Iobm9kZSwgbG9hZGVyKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgIH0pO1xuXG4gICAgICAvLyBBbm5vdGF0aW9uIGNhc2UgLSBhZnRlciBkZWNvcmF0b3IgZG93bmxldmVsaW5nXG4gICAgICAvLyBzdGF0aWMgZGVjb3JhdG9yczoge3R5cGU6IEZ1bmN0aW9uLCBhcmdzPzogYW55W119W11cbiAgICAgIGNvbnN0IG5ld01lbWJlcnMgPSB0cy52aXNpdE5vZGVzKG5vZGUubWVtYmVycywgKG5vZGU6IHRzLk5vZGUpID0+IHtcbiAgICAgICAgaWYgKHRzLmlzQ2xhc3NFbGVtZW50KG5vZGUpKSB7XG4gICAgICAgICAgcmV0dXJuIHVwZGF0ZUFubm90YXRpb25zKG5vZGUsIGxvYWRlciwgcHJvZ3JhbS5nZXRUeXBlQ2hlY2tlcigpKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICByZXR1cm4gbm9kZTtcbiAgICAgICAgfVxuICAgICAgfSk7XG5cbiAgICAgIC8vIENyZWF0ZSBhIG5ldyBBU1Qgc3VidHJlZSB3aXRoIG91ciBtb2RpZmljYXRpb25zXG4gICAgICByZXR1cm4gdHMudXBkYXRlQ2xhc3NEZWNsYXJhdGlvbihcbiAgICAgICAgICBub2RlLCBuZXdEZWNvcmF0b3JzLCBub2RlLm1vZGlmaWVycywgbm9kZS5uYW1lLCBub2RlLnR5cGVQYXJhbWV0ZXJzLFxuICAgICAgICAgIG5vZGUuaGVyaXRhZ2VDbGF1c2VzIHx8IFtdLCBuZXdNZW1iZXJzKTtcbiAgICB9O1xuXG4gICAgcmV0dXJuIHRzLnZpc2l0RWFjaENoaWxkKHNvdXJjZUZpbGUsIHZpc2l0b3IsIGNvbnRleHQpO1xuICB9O1xufVxuXG4vKipcbiAqIFVwZGF0ZSBhIERlY29yYXRvciBBU1Qgbm9kZSB0byBpbmxpbmUgdGhlIHJlc291cmNlc1xuICogQHBhcmFtIG5vZGUgdGhlIEBDb21wb25lbnQgZGVjb3JhdG9yXG4gKiBAcGFyYW0gbG9hZGVyIHByb3ZpZGVzIGFjY2VzcyB0byBsb2FkIHJlc291cmNlc1xuICovXG5mdW5jdGlvbiB1cGRhdGVEZWNvcmF0b3Iobm9kZTogdHMuRGVjb3JhdG9yLCBsb2FkZXI6IFN0YXRpY1Jlc291cmNlTG9hZGVyKTogdHMuRGVjb3JhdG9yIHtcbiAgaWYgKCF0cy5pc0NhbGxFeHByZXNzaW9uKG5vZGUuZXhwcmVzc2lvbikpIHtcbiAgICAvLyBVc2VyIHdpbGwgZ2V0IGFuIGVycm9yIHNvbWV3aGVyZSBlbHNlIHdpdGggYmFyZSBAQ29tcG9uZW50XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cbiAgY29uc3QgZXhwciA9IG5vZGUuZXhwcmVzc2lvbjtcbiAgY29uc3QgbmV3QXJndW1lbnRzID0gdXBkYXRlQ29tcG9uZW50UHJvcGVydGllcyhleHByLmFyZ3VtZW50cywgbG9hZGVyKTtcbiAgcmV0dXJuIHRzLnVwZGF0ZURlY29yYXRvcihcbiAgICAgIG5vZGUsIHRzLnVwZGF0ZUNhbGwoZXhwciwgZXhwci5leHByZXNzaW9uLCBleHByLnR5cGVBcmd1bWVudHMsIG5ld0FyZ3VtZW50cykpO1xufVxuXG4vKipcbiAqIFVwZGF0ZSBhbiBBbm5vdGF0aW9ucyBBU1Qgbm9kZSB0byBpbmxpbmUgdGhlIHJlc291cmNlc1xuICogQHBhcmFtIG5vZGUgdGhlIHN0YXRpYyBkZWNvcmF0b3JzIHByb3BlcnR5XG4gKiBAcGFyYW0gbG9hZGVyIHByb3ZpZGVzIGFjY2VzcyB0byBsb2FkIHJlc291cmNlc1xuICogQHBhcmFtIHR5cGVDaGVja2VyIHByb3ZpZGVzIGFjY2VzcyB0byBzeW1ib2wgdGFibGVcbiAqL1xuZnVuY3Rpb24gdXBkYXRlQW5ub3RhdGlvbnMoXG4gICAgbm9kZTogdHMuQ2xhc3NFbGVtZW50LCBsb2FkZXI6IFN0YXRpY1Jlc291cmNlTG9hZGVyLFxuICAgIHR5cGVDaGVja2VyOiB0cy5UeXBlQ2hlY2tlcik6IHRzLkNsYXNzRWxlbWVudCB7XG4gIC8vIExvb2tpbmcgZm9yIGEgbWVtYmVyIG9mIHRoaXMgc2hhcGU6XG4gIC8vIFByb3BlcnR5RGVjbGFyYXRpb24gY2FsbGVkIGRlY29yYXRvcnMsIHdpdGggc3RhdGljIG1vZGlmaWVyXG4gIC8vIEluaXRpYWxpemVyIGlzIEFycmF5TGl0ZXJhbEV4cHJlc3Npb25cbiAgLy8gT25lIGVsZW1lbnQgaXMgdGhlIENvbXBvbmVudCB0eXBlLCBpdHMgaW5pdGlhbGl6ZXIgaXMgdGhlIEBhbmd1bGFyL2NvcmUgQ29tcG9uZW50IHN5bWJvbFxuICAvLyBPbmUgZWxlbWVudCBpcyB0aGUgY29tcG9uZW50IGFyZ3MsIGl0cyBpbml0aWFsaXplciBpcyB0aGUgQ29tcG9uZW50IGFyZ3VtZW50cyB0byBjaGFuZ2VcbiAgLy8gZS5nLlxuICAvLyAgIHN0YXRpYyBkZWNvcmF0b3JzOiB7dHlwZTogRnVuY3Rpb24sIGFyZ3M/OiBhbnlbXX1bXSA9XG4gIC8vICAgW3tcbiAgLy8gICAgIHR5cGU6IENvbXBvbmVudCxcbiAgLy8gICAgIGFyZ3M6IFt7XG4gIC8vICAgICAgIHRlbXBsYXRlVXJsOiAnLi9teS5jb21wb25lbnQuaHRtbCcsXG4gIC8vICAgICAgIHN0eWxlVXJsczogWycuL215LmNvbXBvbmVudC5jc3MnXSxcbiAgLy8gICAgIH1dLFxuICAvLyAgIH1dO1xuICBpZiAoIXRzLmlzUHJvcGVydHlEZWNsYXJhdGlvbihub2RlKSB8fCAgLy8gdHMuTW9kaWZpZXJGbGFncy5TdGF0aWMgJiZcbiAgICAgICF0cy5pc0lkZW50aWZpZXIobm9kZS5uYW1lKSB8fCBub2RlLm5hbWUudGV4dCAhPT0gJ2RlY29yYXRvcnMnIHx8ICFub2RlLmluaXRpYWxpemVyIHx8XG4gICAgICAhdHMuaXNBcnJheUxpdGVyYWxFeHByZXNzaW9uKG5vZGUuaW5pdGlhbGl6ZXIpKSB7XG4gICAgcmV0dXJuIG5vZGU7XG4gIH1cblxuICBjb25zdCBuZXdBbm5vdGF0aW9ucyA9IG5vZGUuaW5pdGlhbGl6ZXIuZWxlbWVudHMubWFwKGFubm90YXRpb24gPT4ge1xuICAgIC8vIE5vLW9wIGlmIHRoZXJlJ3MgYSBub24tb2JqZWN0LWxpdGVyYWwgbWl4ZWQgaW4gdGhlIGRlY29yYXRvcnMgdmFsdWVzXG4gICAgaWYgKCF0cy5pc09iamVjdExpdGVyYWxFeHByZXNzaW9uKGFubm90YXRpb24pKSByZXR1cm4gYW5ub3RhdGlvbjtcblxuICAgIGNvbnN0IGRlY29yYXRvclR5cGUgPSBhbm5vdGF0aW9uLnByb3BlcnRpZXMuZmluZChwID0+IGlzSWRlbnRpZmllck5hbWVkKHAsICd0eXBlJykpO1xuXG4gICAgLy8gTm8tb3AgaWYgdGhlcmUncyBubyAndHlwZScgcHJvcGVydHksIG9yIGlmIGl0J3Mgbm90IGluaXRpYWxpemVkIHRvIHRoZSBDb21wb25lbnQgc3ltYm9sXG4gICAgaWYgKCFkZWNvcmF0b3JUeXBlIHx8ICF0cy5pc1Byb3BlcnR5QXNzaWdubWVudChkZWNvcmF0b3JUeXBlKSB8fFxuICAgICAgICAhdHMuaXNJZGVudGlmaWVyKGRlY29yYXRvclR5cGUuaW5pdGlhbGl6ZXIpIHx8XG4gICAgICAgICFpc0NvbXBvbmVudFN5bWJvbChkZWNvcmF0b3JUeXBlLmluaXRpYWxpemVyLCB0eXBlQ2hlY2tlcikpIHtcbiAgICAgIHJldHVybiBhbm5vdGF0aW9uO1xuICAgIH1cblxuICAgIGNvbnN0IG5ld0Fubm90YXRpb24gPSBhbm5vdGF0aW9uLnByb3BlcnRpZXMubWFwKHByb3AgPT4ge1xuICAgICAgLy8gTm8tb3AgaWYgdGhpcyBpc24ndCB0aGUgJ2FyZ3MnIHByb3BlcnR5IG9yIGlmIGl0J3Mgbm90IGluaXRpYWxpemVkIHRvIGFuIGFycmF5XG4gICAgICBpZiAoIWlzSWRlbnRpZmllck5hbWVkKHByb3AsICdhcmdzJykgfHwgIXRzLmlzUHJvcGVydHlBc3NpZ25tZW50KHByb3ApIHx8XG4gICAgICAgICAgIXRzLmlzQXJyYXlMaXRlcmFsRXhwcmVzc2lvbihwcm9wLmluaXRpYWxpemVyKSlcbiAgICAgICAgcmV0dXJuIHByb3A7XG5cbiAgICAgIGNvbnN0IG5ld0RlY29yYXRvckFyZ3MgPSB0cy51cGRhdGVQcm9wZXJ0eUFzc2lnbm1lbnQoXG4gICAgICAgICAgcHJvcCwgcHJvcC5uYW1lLFxuICAgICAgICAgIHRzLmNyZWF0ZUFycmF5TGl0ZXJhbCh1cGRhdGVDb21wb25lbnRQcm9wZXJ0aWVzKHByb3AuaW5pdGlhbGl6ZXIuZWxlbWVudHMsIGxvYWRlcikpKTtcblxuICAgICAgcmV0dXJuIG5ld0RlY29yYXRvckFyZ3M7XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdHMudXBkYXRlT2JqZWN0TGl0ZXJhbChhbm5vdGF0aW9uLCBuZXdBbm5vdGF0aW9uKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHRzLnVwZGF0ZVByb3BlcnR5KFxuICAgICAgbm9kZSwgbm9kZS5kZWNvcmF0b3JzLCBub2RlLm1vZGlmaWVycywgbm9kZS5uYW1lLCBub2RlLnF1ZXN0aW9uVG9rZW4sIG5vZGUudHlwZSxcbiAgICAgIHRzLnVwZGF0ZUFycmF5TGl0ZXJhbChub2RlLmluaXRpYWxpemVyLCBuZXdBbm5vdGF0aW9ucykpO1xufVxuXG5mdW5jdGlvbiBpc0lkZW50aWZpZXJOYW1lZChwOiB0cy5PYmplY3RMaXRlcmFsRWxlbWVudExpa2UsIG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICByZXR1cm4gISFwLm5hbWUgJiYgdHMuaXNJZGVudGlmaWVyKHAubmFtZSkgJiYgcC5uYW1lLnRleHQgPT09IG5hbWU7XG59XG5cbi8qKlxuICogQ2hlY2sgdGhhdCB0aGUgbm9kZSB3ZSBhcmUgdmlzaXRpbmcgaXMgdGhlIGFjdHVhbCBDb21wb25lbnQgZGVjb3JhdG9yIGRlZmluZWQgaW4gQGFuZ3VsYXIvY29yZS5cbiAqL1xuZnVuY3Rpb24gaXNDb21wb25lbnREZWNvcmF0b3Iobm9kZTogdHMuRGVjb3JhdG9yLCB0eXBlQ2hlY2tlcjogdHMuVHlwZUNoZWNrZXIpOiBib29sZWFuIHtcbiAgaWYgKCF0cy5pc0NhbGxFeHByZXNzaW9uKG5vZGUuZXhwcmVzc2lvbikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgY29uc3QgY2FsbEV4cHIgPSBub2RlLmV4cHJlc3Npb247XG5cbiAgbGV0IGlkZW50aWZpZXI6IHRzLk5vZGU7XG5cbiAgaWYgKHRzLmlzSWRlbnRpZmllcihjYWxsRXhwci5leHByZXNzaW9uKSkge1xuICAgIGlkZW50aWZpZXIgPSBjYWxsRXhwci5leHByZXNzaW9uO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gaXNDb21wb25lbnRTeW1ib2woaWRlbnRpZmllciwgdHlwZUNoZWNrZXIpO1xufVxuXG5mdW5jdGlvbiBpc0NvbXBvbmVudFN5bWJvbChpZGVudGlmaWVyOiB0cy5Ob2RlLCB0eXBlQ2hlY2tlcjogdHMuVHlwZUNoZWNrZXIpIHtcbiAgLy8gT25seSBoYW5kbGUgaWRlbnRpZmllcnMsIG5vdCBleHByZXNzaW9uc1xuICBpZiAoIXRzLmlzSWRlbnRpZmllcihpZGVudGlmaWVyKSkgcmV0dXJuIGZhbHNlO1xuXG4gIC8vIE5PVEU6IHJlc29sdmVyLmdldFJlZmVyZW5jZWRJbXBvcnREZWNsYXJhdGlvbiB3b3VsZCB3b3JrIGFzIHdlbGwgYnV0IGlzIGludGVybmFsXG4gIGNvbnN0IHN5bWJvbCA9IHR5cGVDaGVja2VyLmdldFN5bWJvbEF0TG9jYXRpb24oaWRlbnRpZmllcik7XG5cbiAgaWYgKCFzeW1ib2wgfHwgIXN5bWJvbC5kZWNsYXJhdGlvbnMgfHwgIXN5bWJvbC5kZWNsYXJhdGlvbnMubGVuZ3RoKSB7XG4gICAgY29uc29sZS5lcnJvcihcbiAgICAgICAgYFVuYWJsZSB0byByZXNvbHZlIHN5bWJvbCAnJHtpZGVudGlmaWVyLnRleHR9JyBpbiB0aGUgcHJvZ3JhbSwgZG9lcyBpdCB0eXBlLWNoZWNrP2ApO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGNvbnN0IGRlY2xhcmF0aW9uID0gc3ltYm9sLmRlY2xhcmF0aW9uc1swXTtcblxuICBpZiAoIWRlY2xhcmF0aW9uIHx8ICF0cy5pc0ltcG9ydFNwZWNpZmllcihkZWNsYXJhdGlvbikpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICBjb25zdCBuYW1lID0gKGRlY2xhcmF0aW9uLnByb3BlcnR5TmFtZSB8fCBkZWNsYXJhdGlvbi5uYW1lKS50ZXh0O1xuICAvLyBXZSBrbm93IHRoYXQgcGFyZW50IHBvaW50ZXJzIGFyZSBzZXQgYmVjYXVzZSB3ZSBjcmVhdGVkIHRoZSBTb3VyY2VGaWxlIG91cnNlbHZlcy5cbiAgLy8gVGhlIG51bWJlciBvZiBwYXJlbnQgcmVmZXJlbmNlcyBoZXJlIG1hdGNoIHRoZSByZWN1cnNpb24gZGVwdGggYXQgdGhpcyBwb2ludC5cbiAgY29uc3QgbW9kdWxlSWQgPSAoZGVjbGFyYXRpb24ucGFyZW50IS5wYXJlbnQhLnBhcmVudCEubW9kdWxlU3BlY2lmaWVyIGFzIHRzLlN0cmluZ0xpdGVyYWwpLnRleHQ7XG4gIHJldHVybiBtb2R1bGVJZCA9PT0gJ0Bhbmd1bGFyL2NvcmUnICYmIG5hbWUgPT09ICdDb21wb25lbnQnO1xufVxuXG4vKipcbiAqIEZvciBlYWNoIHByb3BlcnR5IGluIHRoZSBvYmplY3QgbGl0ZXJhbCwgaWYgaXQncyB0ZW1wbGF0ZVVybCBvciBzdHlsZVVybHMsIHJlcGxhY2UgaXRcbiAqIHdpdGggY29udGVudC5cbiAqIEBwYXJhbSBub2RlIHRoZSBhcmd1bWVudHMgdG8gQENvbXBvbmVudCgpIG9yIGFyZ3MgcHJvcGVydHkgb2YgZGVjb3JhdG9yczogW3t0eXBlOkNvbXBvbmVudH1dXG4gKiBAcGFyYW0gbG9hZGVyIHByb3ZpZGVzIGFjY2VzcyB0byB0aGUgbG9hZFJlc291cmNlIG1ldGhvZCBvZiB0aGUgaG9zdFxuICogQHJldHVybnMgdXBkYXRlZCBhcmd1bWVudHNcbiAqL1xuZnVuY3Rpb24gdXBkYXRlQ29tcG9uZW50UHJvcGVydGllcyhcbiAgICBhcmdzOiB0cy5Ob2RlQXJyYXk8dHMuRXhwcmVzc2lvbj4sIGxvYWRlcjogU3RhdGljUmVzb3VyY2VMb2FkZXIpOiB0cy5Ob2RlQXJyYXk8dHMuRXhwcmVzc2lvbj4ge1xuICBpZiAoYXJncy5sZW5ndGggIT09IDEpIHtcbiAgICAvLyBVc2VyIHNob3VsZCBoYXZlIGdvdHRlbiBhIHR5cGUtY2hlY2sgZXJyb3IgYmVjYXVzZSBAQ29tcG9uZW50IHRha2VzIG9uZSBhcmd1bWVudFxuICAgIHJldHVybiBhcmdzO1xuICB9XG4gIGNvbnN0IGNvbXBvbmVudEFyZyA9IGFyZ3NbMF07XG4gIGlmICghdHMuaXNPYmplY3RMaXRlcmFsRXhwcmVzc2lvbihjb21wb25lbnRBcmcpKSB7XG4gICAgLy8gVXNlciBzaG91bGQgaGF2ZSBnb3R0ZW4gYSB0eXBlLWNoZWNrIGVycm9yIGJlY2F1c2UgQENvbXBvbmVudCB0YWtlcyBhbiBvYmplY3QgbGl0ZXJhbFxuICAgIC8vIGFyZ3VtZW50XG4gICAgcmV0dXJuIGFyZ3M7XG4gIH1cblxuICBjb25zdCBuZXdQcm9wZXJ0aWVzOiB0cy5PYmplY3RMaXRlcmFsRWxlbWVudExpa2VbXSA9IFtdO1xuICBjb25zdCBuZXdTdHlsZUV4cHJzOiB0cy5FeHByZXNzaW9uW10gPSBbXTtcbiAgY29tcG9uZW50QXJnLnByb3BlcnRpZXMuZm9yRWFjaChwcm9wID0+IHtcbiAgICBpZiAoIXRzLmlzUHJvcGVydHlBc3NpZ25tZW50KHByb3ApIHx8IHRzLmlzQ29tcHV0ZWRQcm9wZXJ0eU5hbWUocHJvcC5uYW1lKSkge1xuICAgICAgbmV3UHJvcGVydGllcy5wdXNoKHByb3ApO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN3aXRjaCAocHJvcC5uYW1lLnRleHQpIHtcbiAgICAgIGNhc2UgJ3N0eWxlcyc6XG4gICAgICAgIGlmICghdHMuaXNBcnJheUxpdGVyYWxFeHByZXNzaW9uKHByb3AuaW5pdGlhbGl6ZXIpKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKCdzdHlsZXMgdGFrZXMgYW4gYXJyYXkgYXJndW1lbnQnKTtcbiAgICAgICAgfVxuICAgICAgICBuZXdTdHlsZUV4cHJzLnB1c2goLi4ucHJvcC5pbml0aWFsaXplci5lbGVtZW50cyk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdzdHlsZVVybHMnOlxuICAgICAgICBpZiAoIXRzLmlzQXJyYXlMaXRlcmFsRXhwcmVzc2lvbihwcm9wLmluaXRpYWxpemVyKSkge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcignc3R5bGVVcmxzIHRha2VzIGFuIGFycmF5IGFyZ3VtZW50Jyk7XG4gICAgICAgIH1cbiAgICAgICAgbmV3U3R5bGVFeHBycy5wdXNoKC4uLnByb3AuaW5pdGlhbGl6ZXIuZWxlbWVudHMubWFwKChleHByOiB0cy5FeHByZXNzaW9uKSA9PiB7XG4gICAgICAgICAgaWYgKCF0cy5pc1N0cmluZ0xpdGVyYWwoZXhwcikgJiYgIXRzLmlzTm9TdWJzdGl0dXRpb25UZW1wbGF0ZUxpdGVyYWwoZXhwcikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgICAgICAgICAnQ2FuIG9ubHkgYWNjZXB0IHN0cmluZyBsaXRlcmFsIGFyZ3VtZW50cyB0byBzdHlsZVVybHMuICcgKyBQUkVDT05ESVRJT05TX1RFWFQpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBjb25zdCBzdHlsZXMgPSBsb2FkZXIuZ2V0KGV4cHIudGV4dCk7XG4gICAgICAgICAgcmV0dXJuIHRzLmNyZWF0ZUxpdGVyYWwoc3R5bGVzKTtcbiAgICAgICAgfSkpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAndGVtcGxhdGVVcmwnOlxuICAgICAgICBpZiAoIXRzLmlzU3RyaW5nTGl0ZXJhbChwcm9wLmluaXRpYWxpemVyKSAmJlxuICAgICAgICAgICAgIXRzLmlzTm9TdWJzdGl0dXRpb25UZW1wbGF0ZUxpdGVyYWwocHJvcC5pbml0aWFsaXplcikpIHtcbiAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgICAgICAgICdDYW4gb25seSBhY2NlcHQgYSBzdHJpbmcgbGl0ZXJhbCBhcmd1bWVudCB0byB0ZW1wbGF0ZVVybC4gJyArIFBSRUNPTkRJVElPTlNfVEVYVCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGVtcGxhdGUgPSBsb2FkZXIuZ2V0KHByb3AuaW5pdGlhbGl6ZXIudGV4dCk7XG4gICAgICAgIG5ld1Byb3BlcnRpZXMucHVzaCh0cy51cGRhdGVQcm9wZXJ0eUFzc2lnbm1lbnQoXG4gICAgICAgICAgICBwcm9wLCB0cy5jcmVhdGVJZGVudGlmaWVyKCd0ZW1wbGF0ZScpLCB0cy5jcmVhdGVMaXRlcmFsKHRlbXBsYXRlKSkpO1xuICAgICAgICBicmVhaztcblxuICAgICAgZGVmYXVsdDpcbiAgICAgICAgbmV3UHJvcGVydGllcy5wdXNoKHByb3ApO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gQWRkIHRoZSBub24taW5saW5lIHN0eWxlc1xuICBpZiAobmV3U3R5bGVFeHBycy5sZW5ndGggPiAwKSB7XG4gICAgY29uc3QgbmV3U3R5bGVzID0gdHMuY3JlYXRlUHJvcGVydHlBc3NpZ25tZW50KFxuICAgICAgICB0cy5jcmVhdGVJZGVudGlmaWVyKCdzdHlsZXMnKSwgdHMuY3JlYXRlQXJyYXlMaXRlcmFsKG5ld1N0eWxlRXhwcnMpKTtcbiAgICBuZXdQcm9wZXJ0aWVzLnB1c2gobmV3U3R5bGVzKTtcbiAgfVxuXG4gIHJldHVybiB0cy5jcmVhdGVOb2RlQXJyYXkoW3RzLnVwZGF0ZU9iamVjdExpdGVyYWwoY29tcG9uZW50QXJnLCBuZXdQcm9wZXJ0aWVzKV0pO1xufVxuIl19 |
---|