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/src/expression_parser/parser", ["require", "exports", "tslib", "@angular/compiler/src/chars", "@angular/compiler/src/ml_parser/interpolation_config", "@angular/compiler/src/expression_parser/ast", "@angular/compiler/src/expression_parser/lexer"], factory);
|
---|
15 | }
|
---|
16 | })(function (require, exports) {
|
---|
17 | "use strict";
|
---|
18 | Object.defineProperty(exports, "__esModule", { value: true });
|
---|
19 | exports._ParseAST = exports.IvyParser = exports.Parser = exports.TemplateBindingParseResult = exports.SplitInterpolation = void 0;
|
---|
20 | var tslib_1 = require("tslib");
|
---|
21 | var chars = require("@angular/compiler/src/chars");
|
---|
22 | var interpolation_config_1 = require("@angular/compiler/src/ml_parser/interpolation_config");
|
---|
23 | var ast_1 = require("@angular/compiler/src/expression_parser/ast");
|
---|
24 | var lexer_1 = require("@angular/compiler/src/expression_parser/lexer");
|
---|
25 | var SplitInterpolation = /** @class */ (function () {
|
---|
26 | function SplitInterpolation(strings, expressions, offsets) {
|
---|
27 | this.strings = strings;
|
---|
28 | this.expressions = expressions;
|
---|
29 | this.offsets = offsets;
|
---|
30 | }
|
---|
31 | return SplitInterpolation;
|
---|
32 | }());
|
---|
33 | exports.SplitInterpolation = SplitInterpolation;
|
---|
34 | var TemplateBindingParseResult = /** @class */ (function () {
|
---|
35 | function TemplateBindingParseResult(templateBindings, warnings, errors) {
|
---|
36 | this.templateBindings = templateBindings;
|
---|
37 | this.warnings = warnings;
|
---|
38 | this.errors = errors;
|
---|
39 | }
|
---|
40 | return TemplateBindingParseResult;
|
---|
41 | }());
|
---|
42 | exports.TemplateBindingParseResult = TemplateBindingParseResult;
|
---|
43 | var Parser = /** @class */ (function () {
|
---|
44 | function Parser(_lexer) {
|
---|
45 | this._lexer = _lexer;
|
---|
46 | this.errors = [];
|
---|
47 | this.simpleExpressionChecker = SimpleExpressionChecker;
|
---|
48 | }
|
---|
49 | Parser.prototype.parseAction = function (input, location, absoluteOffset, interpolationConfig) {
|
---|
50 | if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; }
|
---|
51 | this._checkNoInterpolation(input, location, interpolationConfig);
|
---|
52 | var sourceToLex = this._stripComments(input);
|
---|
53 | var tokens = this._lexer.tokenize(this._stripComments(input));
|
---|
54 | var ast = new _ParseAST(input, location, absoluteOffset, tokens, sourceToLex.length, true, this.errors, input.length - sourceToLex.length)
|
---|
55 | .parseChain();
|
---|
56 | return new ast_1.ASTWithSource(ast, input, location, absoluteOffset, this.errors);
|
---|
57 | };
|
---|
58 | Parser.prototype.parseBinding = function (input, location, absoluteOffset, interpolationConfig) {
|
---|
59 | if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; }
|
---|
60 | var ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig);
|
---|
61 | return new ast_1.ASTWithSource(ast, input, location, absoluteOffset, this.errors);
|
---|
62 | };
|
---|
63 | Parser.prototype.checkSimpleExpression = function (ast) {
|
---|
64 | var checker = new this.simpleExpressionChecker();
|
---|
65 | ast.visit(checker);
|
---|
66 | return checker.errors;
|
---|
67 | };
|
---|
68 | Parser.prototype.parseSimpleBinding = function (input, location, absoluteOffset, interpolationConfig) {
|
---|
69 | if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; }
|
---|
70 | var ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig);
|
---|
71 | var errors = this.checkSimpleExpression(ast);
|
---|
72 | if (errors.length > 0) {
|
---|
73 | this._reportError("Host binding expression cannot contain " + errors.join(' '), input, location);
|
---|
74 | }
|
---|
75 | return new ast_1.ASTWithSource(ast, input, location, absoluteOffset, this.errors);
|
---|
76 | };
|
---|
77 | Parser.prototype._reportError = function (message, input, errLocation, ctxLocation) {
|
---|
78 | this.errors.push(new ast_1.ParserError(message, input, errLocation, ctxLocation));
|
---|
79 | };
|
---|
80 | Parser.prototype._parseBindingAst = function (input, location, absoluteOffset, interpolationConfig) {
|
---|
81 | // Quotes expressions use 3rd-party expression language. We don't want to use
|
---|
82 | // our lexer or parser for that, so we check for that ahead of time.
|
---|
83 | var quote = this._parseQuote(input, location, absoluteOffset);
|
---|
84 | if (quote != null) {
|
---|
85 | return quote;
|
---|
86 | }
|
---|
87 | this._checkNoInterpolation(input, location, interpolationConfig);
|
---|
88 | var sourceToLex = this._stripComments(input);
|
---|
89 | var tokens = this._lexer.tokenize(sourceToLex);
|
---|
90 | return new _ParseAST(input, location, absoluteOffset, tokens, sourceToLex.length, false, this.errors, input.length - sourceToLex.length)
|
---|
91 | .parseChain();
|
---|
92 | };
|
---|
93 | Parser.prototype._parseQuote = function (input, location, absoluteOffset) {
|
---|
94 | if (input == null)
|
---|
95 | return null;
|
---|
96 | var prefixSeparatorIndex = input.indexOf(':');
|
---|
97 | if (prefixSeparatorIndex == -1)
|
---|
98 | return null;
|
---|
99 | var prefix = input.substring(0, prefixSeparatorIndex).trim();
|
---|
100 | if (!lexer_1.isIdentifier(prefix))
|
---|
101 | return null;
|
---|
102 | var uninterpretedExpression = input.substring(prefixSeparatorIndex + 1);
|
---|
103 | var span = new ast_1.ParseSpan(0, input.length);
|
---|
104 | return new ast_1.Quote(span, span.toAbsolute(absoluteOffset), prefix, uninterpretedExpression, location);
|
---|
105 | };
|
---|
106 | /**
|
---|
107 | * Parse microsyntax template expression and return a list of bindings or
|
---|
108 | * parsing errors in case the given expression is invalid.
|
---|
109 | *
|
---|
110 | * For example,
|
---|
111 | * ```
|
---|
112 | * <div *ngFor="let item of items">
|
---|
113 | * ^ ^ absoluteValueOffset for `templateValue`
|
---|
114 | * absoluteKeyOffset for `templateKey`
|
---|
115 | * ```
|
---|
116 | * contains three bindings:
|
---|
117 | * 1. ngFor -> null
|
---|
118 | * 2. item -> NgForOfContext.$implicit
|
---|
119 | * 3. ngForOf -> items
|
---|
120 | *
|
---|
121 | * This is apparent from the de-sugared template:
|
---|
122 | * ```
|
---|
123 | * <ng-template ngFor let-item [ngForOf]="items">
|
---|
124 | * ```
|
---|
125 | *
|
---|
126 | * @param templateKey name of directive, without the * prefix. For example: ngIf, ngFor
|
---|
127 | * @param templateValue RHS of the microsyntax attribute
|
---|
128 | * @param templateUrl template filename if it's external, component filename if it's inline
|
---|
129 | * @param absoluteKeyOffset start of the `templateKey`
|
---|
130 | * @param absoluteValueOffset start of the `templateValue`
|
---|
131 | */
|
---|
132 | Parser.prototype.parseTemplateBindings = function (templateKey, templateValue, templateUrl, absoluteKeyOffset, absoluteValueOffset) {
|
---|
133 | var tokens = this._lexer.tokenize(templateValue);
|
---|
134 | var parser = new _ParseAST(templateValue, templateUrl, absoluteValueOffset, tokens, templateValue.length, false /* parseAction */, this.errors, 0 /* relative offset */);
|
---|
135 | return parser.parseTemplateBindings({
|
---|
136 | source: templateKey,
|
---|
137 | span: new ast_1.AbsoluteSourceSpan(absoluteKeyOffset, absoluteKeyOffset + templateKey.length),
|
---|
138 | });
|
---|
139 | };
|
---|
140 | Parser.prototype.parseInterpolation = function (input, location, absoluteOffset, interpolationConfig) {
|
---|
141 | if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; }
|
---|
142 | var _a = this.splitInterpolation(input, location, interpolationConfig), strings = _a.strings, expressions = _a.expressions, offsets = _a.offsets;
|
---|
143 | if (expressions.length === 0)
|
---|
144 | return null;
|
---|
145 | var expressionNodes = [];
|
---|
146 | for (var i = 0; i < expressions.length; ++i) {
|
---|
147 | var expressionText = expressions[i].text;
|
---|
148 | var sourceToLex = this._stripComments(expressionText);
|
---|
149 | var tokens = this._lexer.tokenize(sourceToLex);
|
---|
150 | var ast = new _ParseAST(input, location, absoluteOffset, tokens, sourceToLex.length, false, this.errors, offsets[i] + (expressionText.length - sourceToLex.length))
|
---|
151 | .parseChain();
|
---|
152 | expressionNodes.push(ast);
|
---|
153 | }
|
---|
154 | return this.createInterpolationAst(strings.map(function (s) { return s.text; }), expressionNodes, input, location, absoluteOffset);
|
---|
155 | };
|
---|
156 | /**
|
---|
157 | * Similar to `parseInterpolation`, but treats the provided string as a single expression
|
---|
158 | * element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`).
|
---|
159 | * This is used for parsing the switch expression in ICUs.
|
---|
160 | */
|
---|
161 | Parser.prototype.parseInterpolationExpression = function (expression, location, absoluteOffset) {
|
---|
162 | var sourceToLex = this._stripComments(expression);
|
---|
163 | var tokens = this._lexer.tokenize(sourceToLex);
|
---|
164 | var ast = new _ParseAST(expression, location, absoluteOffset, tokens, sourceToLex.length,
|
---|
165 | /* parseAction */ false, this.errors, 0)
|
---|
166 | .parseChain();
|
---|
167 | var strings = ['', '']; // The prefix and suffix strings are both empty
|
---|
168 | return this.createInterpolationAst(strings, [ast], expression, location, absoluteOffset);
|
---|
169 | };
|
---|
170 | Parser.prototype.createInterpolationAst = function (strings, expressions, input, location, absoluteOffset) {
|
---|
171 | var span = new ast_1.ParseSpan(0, input.length);
|
---|
172 | var interpolation = new ast_1.Interpolation(span, span.toAbsolute(absoluteOffset), strings, expressions);
|
---|
173 | return new ast_1.ASTWithSource(interpolation, input, location, absoluteOffset, this.errors);
|
---|
174 | };
|
---|
175 | /**
|
---|
176 | * Splits a string of text into "raw" text segments and expressions present in interpolations in
|
---|
177 | * the string.
|
---|
178 | * Returns `null` if there are no interpolations, otherwise a
|
---|
179 | * `SplitInterpolation` with splits that look like
|
---|
180 | * <raw text> <expression> <raw text> ... <raw text> <expression> <raw text>
|
---|
181 | */
|
---|
182 | Parser.prototype.splitInterpolation = function (input, location, interpolationConfig) {
|
---|
183 | if (interpolationConfig === void 0) { interpolationConfig = interpolation_config_1.DEFAULT_INTERPOLATION_CONFIG; }
|
---|
184 | var strings = [];
|
---|
185 | var expressions = [];
|
---|
186 | var offsets = [];
|
---|
187 | var i = 0;
|
---|
188 | var atInterpolation = false;
|
---|
189 | var extendLastString = false;
|
---|
190 | var interpStart = interpolationConfig.start, interpEnd = interpolationConfig.end;
|
---|
191 | while (i < input.length) {
|
---|
192 | if (!atInterpolation) {
|
---|
193 | // parse until starting {{
|
---|
194 | var start = i;
|
---|
195 | i = input.indexOf(interpStart, i);
|
---|
196 | if (i === -1) {
|
---|
197 | i = input.length;
|
---|
198 | }
|
---|
199 | var text = input.substring(start, i);
|
---|
200 | strings.push({ text: text, start: start, end: i });
|
---|
201 | atInterpolation = true;
|
---|
202 | }
|
---|
203 | else {
|
---|
204 | // parse from starting {{ to ending }} while ignoring content inside quotes.
|
---|
205 | var fullStart = i;
|
---|
206 | var exprStart = fullStart + interpStart.length;
|
---|
207 | var exprEnd = this._getInterpolationEndIndex(input, interpEnd, exprStart);
|
---|
208 | if (exprEnd === -1) {
|
---|
209 | // Could not find the end of the interpolation; do not parse an expression.
|
---|
210 | // Instead we should extend the content on the last raw string.
|
---|
211 | atInterpolation = false;
|
---|
212 | extendLastString = true;
|
---|
213 | break;
|
---|
214 | }
|
---|
215 | var fullEnd = exprEnd + interpEnd.length;
|
---|
216 | var text = input.substring(exprStart, exprEnd);
|
---|
217 | if (text.trim().length === 0) {
|
---|
218 | this._reportError('Blank expressions are not allowed in interpolated strings', input, "at column " + i + " in", location);
|
---|
219 | }
|
---|
220 | expressions.push({ text: text, start: fullStart, end: fullEnd });
|
---|
221 | offsets.push(exprStart);
|
---|
222 | i = fullEnd;
|
---|
223 | atInterpolation = false;
|
---|
224 | }
|
---|
225 | }
|
---|
226 | if (!atInterpolation) {
|
---|
227 | // If we are now at a text section, add the remaining content as a raw string.
|
---|
228 | if (extendLastString) {
|
---|
229 | var piece = strings[strings.length - 1];
|
---|
230 | piece.text += input.substring(i);
|
---|
231 | piece.end = input.length;
|
---|
232 | }
|
---|
233 | else {
|
---|
234 | strings.push({ text: input.substring(i), start: i, end: input.length });
|
---|
235 | }
|
---|
236 | }
|
---|
237 | return new SplitInterpolation(strings, expressions, offsets);
|
---|
238 | };
|
---|
239 | Parser.prototype.wrapLiteralPrimitive = function (input, location, absoluteOffset) {
|
---|
240 | var span = new ast_1.ParseSpan(0, input == null ? 0 : input.length);
|
---|
241 | return new ast_1.ASTWithSource(new ast_1.LiteralPrimitive(span, span.toAbsolute(absoluteOffset), input), input, location, absoluteOffset, this.errors);
|
---|
242 | };
|
---|
243 | Parser.prototype._stripComments = function (input) {
|
---|
244 | var i = this._commentStart(input);
|
---|
245 | return i != null ? input.substring(0, i).trim() : input;
|
---|
246 | };
|
---|
247 | Parser.prototype._commentStart = function (input) {
|
---|
248 | var outerQuote = null;
|
---|
249 | for (var i = 0; i < input.length - 1; i++) {
|
---|
250 | var char = input.charCodeAt(i);
|
---|
251 | var nextChar = input.charCodeAt(i + 1);
|
---|
252 | if (char === chars.$SLASH && nextChar == chars.$SLASH && outerQuote == null)
|
---|
253 | return i;
|
---|
254 | if (outerQuote === char) {
|
---|
255 | outerQuote = null;
|
---|
256 | }
|
---|
257 | else if (outerQuote == null && chars.isQuote(char)) {
|
---|
258 | outerQuote = char;
|
---|
259 | }
|
---|
260 | }
|
---|
261 | return null;
|
---|
262 | };
|
---|
263 | Parser.prototype._checkNoInterpolation = function (input, location, _a) {
|
---|
264 | var e_1, _b;
|
---|
265 | var start = _a.start, end = _a.end;
|
---|
266 | var startIndex = -1;
|
---|
267 | var endIndex = -1;
|
---|
268 | try {
|
---|
269 | for (var _c = tslib_1.__values(this._forEachUnquotedChar(input, 0)), _d = _c.next(); !_d.done; _d = _c.next()) {
|
---|
270 | var charIndex = _d.value;
|
---|
271 | if (startIndex === -1) {
|
---|
272 | if (input.startsWith(start)) {
|
---|
273 | startIndex = charIndex;
|
---|
274 | }
|
---|
275 | }
|
---|
276 | else {
|
---|
277 | endIndex = this._getInterpolationEndIndex(input, end, charIndex);
|
---|
278 | if (endIndex > -1) {
|
---|
279 | break;
|
---|
280 | }
|
---|
281 | }
|
---|
282 | }
|
---|
283 | }
|
---|
284 | catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
---|
285 | finally {
|
---|
286 | try {
|
---|
287 | if (_d && !_d.done && (_b = _c.return)) _b.call(_c);
|
---|
288 | }
|
---|
289 | finally { if (e_1) throw e_1.error; }
|
---|
290 | }
|
---|
291 | if (startIndex > -1 && endIndex > -1) {
|
---|
292 | this._reportError("Got interpolation (" + start + end + ") where expression was expected", input, "at column " + startIndex + " in", location);
|
---|
293 | }
|
---|
294 | };
|
---|
295 | /**
|
---|
296 | * Finds the index of the end of an interpolation expression
|
---|
297 | * while ignoring comments and quoted content.
|
---|
298 | */
|
---|
299 | Parser.prototype._getInterpolationEndIndex = function (input, expressionEnd, start) {
|
---|
300 | var e_2, _a;
|
---|
301 | try {
|
---|
302 | for (var _b = tslib_1.__values(this._forEachUnquotedChar(input, start)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
---|
303 | var charIndex = _c.value;
|
---|
304 | if (input.startsWith(expressionEnd, charIndex)) {
|
---|
305 | return charIndex;
|
---|
306 | }
|
---|
307 | // Nothing else in the expression matters after we've
|
---|
308 | // hit a comment so look directly for the end token.
|
---|
309 | if (input.startsWith('//', charIndex)) {
|
---|
310 | return input.indexOf(expressionEnd, charIndex);
|
---|
311 | }
|
---|
312 | }
|
---|
313 | }
|
---|
314 | catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
---|
315 | finally {
|
---|
316 | try {
|
---|
317 | if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
---|
318 | }
|
---|
319 | finally { if (e_2) throw e_2.error; }
|
---|
320 | }
|
---|
321 | return -1;
|
---|
322 | };
|
---|
323 | /**
|
---|
324 | * Generator used to iterate over the character indexes of a string that are outside of quotes.
|
---|
325 | * @param input String to loop through.
|
---|
326 | * @param start Index within the string at which to start.
|
---|
327 | */
|
---|
328 | Parser.prototype._forEachUnquotedChar = function (input, start) {
|
---|
329 | var currentQuote, escapeCount, i, char;
|
---|
330 | return tslib_1.__generator(this, function (_a) {
|
---|
331 | switch (_a.label) {
|
---|
332 | case 0:
|
---|
333 | currentQuote = null;
|
---|
334 | escapeCount = 0;
|
---|
335 | i = start;
|
---|
336 | _a.label = 1;
|
---|
337 | case 1:
|
---|
338 | if (!(i < input.length)) return [3 /*break*/, 6];
|
---|
339 | char = input[i];
|
---|
340 | if (!(chars.isQuote(input.charCodeAt(i)) && (currentQuote === null || currentQuote === char) &&
|
---|
341 | escapeCount % 2 === 0)) return [3 /*break*/, 2];
|
---|
342 | currentQuote = currentQuote === null ? char : null;
|
---|
343 | return [3 /*break*/, 4];
|
---|
344 | case 2:
|
---|
345 | if (!(currentQuote === null)) return [3 /*break*/, 4];
|
---|
346 | return [4 /*yield*/, i];
|
---|
347 | case 3:
|
---|
348 | _a.sent();
|
---|
349 | _a.label = 4;
|
---|
350 | case 4:
|
---|
351 | escapeCount = char === '\\' ? escapeCount + 1 : 0;
|
---|
352 | _a.label = 5;
|
---|
353 | case 5:
|
---|
354 | i++;
|
---|
355 | return [3 /*break*/, 1];
|
---|
356 | case 6: return [2 /*return*/];
|
---|
357 | }
|
---|
358 | });
|
---|
359 | };
|
---|
360 | return Parser;
|
---|
361 | }());
|
---|
362 | exports.Parser = Parser;
|
---|
363 | var IvyParser = /** @class */ (function (_super) {
|
---|
364 | tslib_1.__extends(IvyParser, _super);
|
---|
365 | function IvyParser() {
|
---|
366 | var _this = _super !== null && _super.apply(this, arguments) || this;
|
---|
367 | _this.simpleExpressionChecker = IvySimpleExpressionChecker;
|
---|
368 | return _this;
|
---|
369 | }
|
---|
370 | return IvyParser;
|
---|
371 | }(Parser));
|
---|
372 | exports.IvyParser = IvyParser;
|
---|
373 | /** Describes a stateful context an expression parser is in. */
|
---|
374 | var ParseContextFlags;
|
---|
375 | (function (ParseContextFlags) {
|
---|
376 | ParseContextFlags[ParseContextFlags["None"] = 0] = "None";
|
---|
377 | /**
|
---|
378 | * A Writable context is one in which a value may be written to an lvalue.
|
---|
379 | * For example, after we see a property access, we may expect a write to the
|
---|
380 | * property via the "=" operator.
|
---|
381 | * prop
|
---|
382 | * ^ possible "=" after
|
---|
383 | */
|
---|
384 | ParseContextFlags[ParseContextFlags["Writable"] = 1] = "Writable";
|
---|
385 | })(ParseContextFlags || (ParseContextFlags = {}));
|
---|
386 | var _ParseAST = /** @class */ (function () {
|
---|
387 | function _ParseAST(input, location, absoluteOffset, tokens, inputLength, parseAction, errors, offset) {
|
---|
388 | this.input = input;
|
---|
389 | this.location = location;
|
---|
390 | this.absoluteOffset = absoluteOffset;
|
---|
391 | this.tokens = tokens;
|
---|
392 | this.inputLength = inputLength;
|
---|
393 | this.parseAction = parseAction;
|
---|
394 | this.errors = errors;
|
---|
395 | this.offset = offset;
|
---|
396 | this.rparensExpected = 0;
|
---|
397 | this.rbracketsExpected = 0;
|
---|
398 | this.rbracesExpected = 0;
|
---|
399 | this.context = ParseContextFlags.None;
|
---|
400 | // Cache of expression start and input indeces to the absolute source span they map to, used to
|
---|
401 | // prevent creating superfluous source spans in `sourceSpan`.
|
---|
402 | // A serial of the expression start and input index is used for mapping because both are stateful
|
---|
403 | // and may change for subsequent expressions visited by the parser.
|
---|
404 | this.sourceSpanCache = new Map();
|
---|
405 | this.index = 0;
|
---|
406 | }
|
---|
407 | _ParseAST.prototype.peek = function (offset) {
|
---|
408 | var i = this.index + offset;
|
---|
409 | return i < this.tokens.length ? this.tokens[i] : lexer_1.EOF;
|
---|
410 | };
|
---|
411 | Object.defineProperty(_ParseAST.prototype, "next", {
|
---|
412 | get: function () {
|
---|
413 | return this.peek(0);
|
---|
414 | },
|
---|
415 | enumerable: false,
|
---|
416 | configurable: true
|
---|
417 | });
|
---|
418 | Object.defineProperty(_ParseAST.prototype, "atEOF", {
|
---|
419 | /** Whether all the parser input has been processed. */
|
---|
420 | get: function () {
|
---|
421 | return this.index >= this.tokens.length;
|
---|
422 | },
|
---|
423 | enumerable: false,
|
---|
424 | configurable: true
|
---|
425 | });
|
---|
426 | Object.defineProperty(_ParseAST.prototype, "inputIndex", {
|
---|
427 | /**
|
---|
428 | * Index of the next token to be processed, or the end of the last token if all have been
|
---|
429 | * processed.
|
---|
430 | */
|
---|
431 | get: function () {
|
---|
432 | return this.atEOF ? this.currentEndIndex : this.next.index + this.offset;
|
---|
433 | },
|
---|
434 | enumerable: false,
|
---|
435 | configurable: true
|
---|
436 | });
|
---|
437 | Object.defineProperty(_ParseAST.prototype, "currentEndIndex", {
|
---|
438 | /**
|
---|
439 | * End index of the last processed token, or the start of the first token if none have been
|
---|
440 | * processed.
|
---|
441 | */
|
---|
442 | get: function () {
|
---|
443 | if (this.index > 0) {
|
---|
444 | var curToken = this.peek(-1);
|
---|
445 | return curToken.end + this.offset;
|
---|
446 | }
|
---|
447 | // No tokens have been processed yet; return the next token's start or the length of the input
|
---|
448 | // if there is no token.
|
---|
449 | if (this.tokens.length === 0) {
|
---|
450 | return this.inputLength + this.offset;
|
---|
451 | }
|
---|
452 | return this.next.index + this.offset;
|
---|
453 | },
|
---|
454 | enumerable: false,
|
---|
455 | configurable: true
|
---|
456 | });
|
---|
457 | Object.defineProperty(_ParseAST.prototype, "currentAbsoluteOffset", {
|
---|
458 | /**
|
---|
459 | * Returns the absolute offset of the start of the current token.
|
---|
460 | */
|
---|
461 | get: function () {
|
---|
462 | return this.absoluteOffset + this.inputIndex;
|
---|
463 | },
|
---|
464 | enumerable: false,
|
---|
465 | configurable: true
|
---|
466 | });
|
---|
467 | /**
|
---|
468 | * Retrieve a `ParseSpan` from `start` to the current position (or to `artificialEndIndex` if
|
---|
469 | * provided).
|
---|
470 | *
|
---|
471 | * @param start Position from which the `ParseSpan` will start.
|
---|
472 | * @param artificialEndIndex Optional ending index to be used if provided (and if greater than the
|
---|
473 | * natural ending index)
|
---|
474 | */
|
---|
475 | _ParseAST.prototype.span = function (start, artificialEndIndex) {
|
---|
476 | var endIndex = this.currentEndIndex;
|
---|
477 | if (artificialEndIndex !== undefined && artificialEndIndex > this.currentEndIndex) {
|
---|
478 | endIndex = artificialEndIndex;
|
---|
479 | }
|
---|
480 | // In some unusual parsing scenarios (like when certain tokens are missing and an `EmptyExpr` is
|
---|
481 | // being created), the current token may already be advanced beyond the `currentEndIndex`. This
|
---|
482 | // appears to be a deep-seated parser bug.
|
---|
483 | //
|
---|
484 | // As a workaround for now, swap the start and end indices to ensure a valid `ParseSpan`.
|
---|
485 | // TODO(alxhub): fix the bug upstream in the parser state, and remove this workaround.
|
---|
486 | if (start > endIndex) {
|
---|
487 | var tmp = endIndex;
|
---|
488 | endIndex = start;
|
---|
489 | start = tmp;
|
---|
490 | }
|
---|
491 | return new ast_1.ParseSpan(start, endIndex);
|
---|
492 | };
|
---|
493 | _ParseAST.prototype.sourceSpan = function (start, artificialEndIndex) {
|
---|
494 | var serial = start + "@" + this.inputIndex + ":" + artificialEndIndex;
|
---|
495 | if (!this.sourceSpanCache.has(serial)) {
|
---|
496 | this.sourceSpanCache.set(serial, this.span(start, artificialEndIndex).toAbsolute(this.absoluteOffset));
|
---|
497 | }
|
---|
498 | return this.sourceSpanCache.get(serial);
|
---|
499 | };
|
---|
500 | _ParseAST.prototype.advance = function () {
|
---|
501 | this.index++;
|
---|
502 | };
|
---|
503 | /**
|
---|
504 | * Executes a callback in the provided context.
|
---|
505 | */
|
---|
506 | _ParseAST.prototype.withContext = function (context, cb) {
|
---|
507 | this.context |= context;
|
---|
508 | var ret = cb();
|
---|
509 | this.context ^= context;
|
---|
510 | return ret;
|
---|
511 | };
|
---|
512 | _ParseAST.prototype.consumeOptionalCharacter = function (code) {
|
---|
513 | if (this.next.isCharacter(code)) {
|
---|
514 | this.advance();
|
---|
515 | return true;
|
---|
516 | }
|
---|
517 | else {
|
---|
518 | return false;
|
---|
519 | }
|
---|
520 | };
|
---|
521 | _ParseAST.prototype.peekKeywordLet = function () {
|
---|
522 | return this.next.isKeywordLet();
|
---|
523 | };
|
---|
524 | _ParseAST.prototype.peekKeywordAs = function () {
|
---|
525 | return this.next.isKeywordAs();
|
---|
526 | };
|
---|
527 | /**
|
---|
528 | * Consumes an expected character, otherwise emits an error about the missing expected character
|
---|
529 | * and skips over the token stream until reaching a recoverable point.
|
---|
530 | *
|
---|
531 | * See `this.error` and `this.skip` for more details.
|
---|
532 | */
|
---|
533 | _ParseAST.prototype.expectCharacter = function (code) {
|
---|
534 | if (this.consumeOptionalCharacter(code))
|
---|
535 | return;
|
---|
536 | this.error("Missing expected " + String.fromCharCode(code));
|
---|
537 | };
|
---|
538 | _ParseAST.prototype.consumeOptionalOperator = function (op) {
|
---|
539 | if (this.next.isOperator(op)) {
|
---|
540 | this.advance();
|
---|
541 | return true;
|
---|
542 | }
|
---|
543 | else {
|
---|
544 | return false;
|
---|
545 | }
|
---|
546 | };
|
---|
547 | _ParseAST.prototype.expectOperator = function (operator) {
|
---|
548 | if (this.consumeOptionalOperator(operator))
|
---|
549 | return;
|
---|
550 | this.error("Missing expected operator " + operator);
|
---|
551 | };
|
---|
552 | _ParseAST.prototype.prettyPrintToken = function (tok) {
|
---|
553 | return tok === lexer_1.EOF ? 'end of input' : "token " + tok;
|
---|
554 | };
|
---|
555 | _ParseAST.prototype.expectIdentifierOrKeyword = function () {
|
---|
556 | var n = this.next;
|
---|
557 | if (!n.isIdentifier() && !n.isKeyword()) {
|
---|
558 | if (n.isPrivateIdentifier()) {
|
---|
559 | this._reportErrorForPrivateIdentifier(n, 'expected identifier or keyword');
|
---|
560 | }
|
---|
561 | else {
|
---|
562 | this.error("Unexpected " + this.prettyPrintToken(n) + ", expected identifier or keyword");
|
---|
563 | }
|
---|
564 | return null;
|
---|
565 | }
|
---|
566 | this.advance();
|
---|
567 | return n.toString();
|
---|
568 | };
|
---|
569 | _ParseAST.prototype.expectIdentifierOrKeywordOrString = function () {
|
---|
570 | var n = this.next;
|
---|
571 | if (!n.isIdentifier() && !n.isKeyword() && !n.isString()) {
|
---|
572 | if (n.isPrivateIdentifier()) {
|
---|
573 | this._reportErrorForPrivateIdentifier(n, 'expected identifier, keyword or string');
|
---|
574 | }
|
---|
575 | else {
|
---|
576 | this.error("Unexpected " + this.prettyPrintToken(n) + ", expected identifier, keyword, or string");
|
---|
577 | }
|
---|
578 | return '';
|
---|
579 | }
|
---|
580 | this.advance();
|
---|
581 | return n.toString();
|
---|
582 | };
|
---|
583 | _ParseAST.prototype.parseChain = function () {
|
---|
584 | var exprs = [];
|
---|
585 | var start = this.inputIndex;
|
---|
586 | while (this.index < this.tokens.length) {
|
---|
587 | var expr = this.parsePipe();
|
---|
588 | exprs.push(expr);
|
---|
589 | if (this.consumeOptionalCharacter(chars.$SEMICOLON)) {
|
---|
590 | if (!this.parseAction) {
|
---|
591 | this.error('Binding expression cannot contain chained expression');
|
---|
592 | }
|
---|
593 | while (this.consumeOptionalCharacter(chars.$SEMICOLON)) {
|
---|
594 | } // read all semicolons
|
---|
595 | }
|
---|
596 | else if (this.index < this.tokens.length) {
|
---|
597 | this.error("Unexpected token '" + this.next + "'");
|
---|
598 | }
|
---|
599 | }
|
---|
600 | if (exprs.length == 0) {
|
---|
601 | // We have no expressions so create an empty expression that spans the entire input length
|
---|
602 | var artificialStart = this.offset;
|
---|
603 | var artificialEnd = this.offset + this.inputLength;
|
---|
604 | return new ast_1.EmptyExpr(this.span(artificialStart, artificialEnd), this.sourceSpan(artificialStart, artificialEnd));
|
---|
605 | }
|
---|
606 | if (exprs.length == 1)
|
---|
607 | return exprs[0];
|
---|
608 | return new ast_1.Chain(this.span(start), this.sourceSpan(start), exprs);
|
---|
609 | };
|
---|
610 | _ParseAST.prototype.parsePipe = function () {
|
---|
611 | var start = this.inputIndex;
|
---|
612 | var result = this.parseExpression();
|
---|
613 | if (this.consumeOptionalOperator('|')) {
|
---|
614 | if (this.parseAction) {
|
---|
615 | this.error('Cannot have a pipe in an action expression');
|
---|
616 | }
|
---|
617 | do {
|
---|
618 | var nameStart = this.inputIndex;
|
---|
619 | var nameId = this.expectIdentifierOrKeyword();
|
---|
620 | var nameSpan = void 0;
|
---|
621 | var fullSpanEnd = undefined;
|
---|
622 | if (nameId !== null) {
|
---|
623 | nameSpan = this.sourceSpan(nameStart);
|
---|
624 | }
|
---|
625 | else {
|
---|
626 | // No valid identifier was found, so we'll assume an empty pipe name ('').
|
---|
627 | nameId = '';
|
---|
628 | // However, there may have been whitespace present between the pipe character and the next
|
---|
629 | // token in the sequence (or the end of input). We want to track this whitespace so that
|
---|
630 | // the `BindingPipe` we produce covers not just the pipe character, but any trailing
|
---|
631 | // whitespace beyond it. Another way of thinking about this is that the zero-length name
|
---|
632 | // is assumed to be at the end of any whitespace beyond the pipe character.
|
---|
633 | //
|
---|
634 | // Therefore, we push the end of the `ParseSpan` for this pipe all the way up to the
|
---|
635 | // beginning of the next token, or until the end of input if the next token is EOF.
|
---|
636 | fullSpanEnd = this.next.index !== -1 ? this.next.index : this.inputLength + this.offset;
|
---|
637 | // The `nameSpan` for an empty pipe name is zero-length at the end of any whitespace
|
---|
638 | // beyond the pipe character.
|
---|
639 | nameSpan = new ast_1.ParseSpan(fullSpanEnd, fullSpanEnd).toAbsolute(this.absoluteOffset);
|
---|
640 | }
|
---|
641 | var args = [];
|
---|
642 | while (this.consumeOptionalCharacter(chars.$COLON)) {
|
---|
643 | args.push(this.parseExpression());
|
---|
644 | // If there are additional expressions beyond the name, then the artificial end for the
|
---|
645 | // name is no longer relevant.
|
---|
646 | }
|
---|
647 | result = new ast_1.BindingPipe(this.span(start), this.sourceSpan(start, fullSpanEnd), result, nameId, args, nameSpan);
|
---|
648 | } while (this.consumeOptionalOperator('|'));
|
---|
649 | }
|
---|
650 | return result;
|
---|
651 | };
|
---|
652 | _ParseAST.prototype.parseExpression = function () {
|
---|
653 | return this.parseConditional();
|
---|
654 | };
|
---|
655 | _ParseAST.prototype.parseConditional = function () {
|
---|
656 | var start = this.inputIndex;
|
---|
657 | var result = this.parseLogicalOr();
|
---|
658 | if (this.consumeOptionalOperator('?')) {
|
---|
659 | var yes = this.parsePipe();
|
---|
660 | var no = void 0;
|
---|
661 | if (!this.consumeOptionalCharacter(chars.$COLON)) {
|
---|
662 | var end = this.inputIndex;
|
---|
663 | var expression = this.input.substring(start, end);
|
---|
664 | this.error("Conditional expression " + expression + " requires all 3 expressions");
|
---|
665 | no = new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start));
|
---|
666 | }
|
---|
667 | else {
|
---|
668 | no = this.parsePipe();
|
---|
669 | }
|
---|
670 | return new ast_1.Conditional(this.span(start), this.sourceSpan(start), result, yes, no);
|
---|
671 | }
|
---|
672 | else {
|
---|
673 | return result;
|
---|
674 | }
|
---|
675 | };
|
---|
676 | _ParseAST.prototype.parseLogicalOr = function () {
|
---|
677 | // '||'
|
---|
678 | var start = this.inputIndex;
|
---|
679 | var result = this.parseLogicalAnd();
|
---|
680 | while (this.consumeOptionalOperator('||')) {
|
---|
681 | var right = this.parseLogicalAnd();
|
---|
682 | result = new ast_1.Binary(this.span(start), this.sourceSpan(start), '||', result, right);
|
---|
683 | }
|
---|
684 | return result;
|
---|
685 | };
|
---|
686 | _ParseAST.prototype.parseLogicalAnd = function () {
|
---|
687 | // '&&'
|
---|
688 | var start = this.inputIndex;
|
---|
689 | var result = this.parseNullishCoalescing();
|
---|
690 | while (this.consumeOptionalOperator('&&')) {
|
---|
691 | var right = this.parseNullishCoalescing();
|
---|
692 | result = new ast_1.Binary(this.span(start), this.sourceSpan(start), '&&', result, right);
|
---|
693 | }
|
---|
694 | return result;
|
---|
695 | };
|
---|
696 | _ParseAST.prototype.parseNullishCoalescing = function () {
|
---|
697 | // '??'
|
---|
698 | var start = this.inputIndex;
|
---|
699 | var result = this.parseEquality();
|
---|
700 | while (this.consumeOptionalOperator('??')) {
|
---|
701 | var right = this.parseEquality();
|
---|
702 | result = new ast_1.Binary(this.span(start), this.sourceSpan(start), '??', result, right);
|
---|
703 | }
|
---|
704 | return result;
|
---|
705 | };
|
---|
706 | _ParseAST.prototype.parseEquality = function () {
|
---|
707 | // '==','!=','===','!=='
|
---|
708 | var start = this.inputIndex;
|
---|
709 | var result = this.parseRelational();
|
---|
710 | while (this.next.type == lexer_1.TokenType.Operator) {
|
---|
711 | var operator = this.next.strValue;
|
---|
712 | switch (operator) {
|
---|
713 | case '==':
|
---|
714 | case '===':
|
---|
715 | case '!=':
|
---|
716 | case '!==':
|
---|
717 | this.advance();
|
---|
718 | var right = this.parseRelational();
|
---|
719 | result = new ast_1.Binary(this.span(start), this.sourceSpan(start), operator, result, right);
|
---|
720 | continue;
|
---|
721 | }
|
---|
722 | break;
|
---|
723 | }
|
---|
724 | return result;
|
---|
725 | };
|
---|
726 | _ParseAST.prototype.parseRelational = function () {
|
---|
727 | // '<', '>', '<=', '>='
|
---|
728 | var start = this.inputIndex;
|
---|
729 | var result = this.parseAdditive();
|
---|
730 | while (this.next.type == lexer_1.TokenType.Operator) {
|
---|
731 | var operator = this.next.strValue;
|
---|
732 | switch (operator) {
|
---|
733 | case '<':
|
---|
734 | case '>':
|
---|
735 | case '<=':
|
---|
736 | case '>=':
|
---|
737 | this.advance();
|
---|
738 | var right = this.parseAdditive();
|
---|
739 | result = new ast_1.Binary(this.span(start), this.sourceSpan(start), operator, result, right);
|
---|
740 | continue;
|
---|
741 | }
|
---|
742 | break;
|
---|
743 | }
|
---|
744 | return result;
|
---|
745 | };
|
---|
746 | _ParseAST.prototype.parseAdditive = function () {
|
---|
747 | // '+', '-'
|
---|
748 | var start = this.inputIndex;
|
---|
749 | var result = this.parseMultiplicative();
|
---|
750 | while (this.next.type == lexer_1.TokenType.Operator) {
|
---|
751 | var operator = this.next.strValue;
|
---|
752 | switch (operator) {
|
---|
753 | case '+':
|
---|
754 | case '-':
|
---|
755 | this.advance();
|
---|
756 | var right = this.parseMultiplicative();
|
---|
757 | result = new ast_1.Binary(this.span(start), this.sourceSpan(start), operator, result, right);
|
---|
758 | continue;
|
---|
759 | }
|
---|
760 | break;
|
---|
761 | }
|
---|
762 | return result;
|
---|
763 | };
|
---|
764 | _ParseAST.prototype.parseMultiplicative = function () {
|
---|
765 | // '*', '%', '/'
|
---|
766 | var start = this.inputIndex;
|
---|
767 | var result = this.parsePrefix();
|
---|
768 | while (this.next.type == lexer_1.TokenType.Operator) {
|
---|
769 | var operator = this.next.strValue;
|
---|
770 | switch (operator) {
|
---|
771 | case '*':
|
---|
772 | case '%':
|
---|
773 | case '/':
|
---|
774 | this.advance();
|
---|
775 | var right = this.parsePrefix();
|
---|
776 | result = new ast_1.Binary(this.span(start), this.sourceSpan(start), operator, result, right);
|
---|
777 | continue;
|
---|
778 | }
|
---|
779 | break;
|
---|
780 | }
|
---|
781 | return result;
|
---|
782 | };
|
---|
783 | _ParseAST.prototype.parsePrefix = function () {
|
---|
784 | if (this.next.type == lexer_1.TokenType.Operator) {
|
---|
785 | var start = this.inputIndex;
|
---|
786 | var operator = this.next.strValue;
|
---|
787 | var result = void 0;
|
---|
788 | switch (operator) {
|
---|
789 | case '+':
|
---|
790 | this.advance();
|
---|
791 | result = this.parsePrefix();
|
---|
792 | return ast_1.Unary.createPlus(this.span(start), this.sourceSpan(start), result);
|
---|
793 | case '-':
|
---|
794 | this.advance();
|
---|
795 | result = this.parsePrefix();
|
---|
796 | return ast_1.Unary.createMinus(this.span(start), this.sourceSpan(start), result);
|
---|
797 | case '!':
|
---|
798 | this.advance();
|
---|
799 | result = this.parsePrefix();
|
---|
800 | return new ast_1.PrefixNot(this.span(start), this.sourceSpan(start), result);
|
---|
801 | }
|
---|
802 | }
|
---|
803 | return this.parseCallChain();
|
---|
804 | };
|
---|
805 | _ParseAST.prototype.parseCallChain = function () {
|
---|
806 | var start = this.inputIndex;
|
---|
807 | var result = this.parsePrimary();
|
---|
808 | while (true) {
|
---|
809 | if (this.consumeOptionalCharacter(chars.$PERIOD)) {
|
---|
810 | result = this.parseAccessMemberOrMethodCall(result, start, false);
|
---|
811 | }
|
---|
812 | else if (this.consumeOptionalOperator('?.')) {
|
---|
813 | result = this.consumeOptionalCharacter(chars.$LBRACKET) ?
|
---|
814 | this.parseKeyedReadOrWrite(result, start, true) :
|
---|
815 | this.parseAccessMemberOrMethodCall(result, start, true);
|
---|
816 | }
|
---|
817 | else if (this.consumeOptionalCharacter(chars.$LBRACKET)) {
|
---|
818 | result = this.parseKeyedReadOrWrite(result, start, false);
|
---|
819 | }
|
---|
820 | else if (this.consumeOptionalCharacter(chars.$LPAREN)) {
|
---|
821 | this.rparensExpected++;
|
---|
822 | var args = this.parseCallArguments();
|
---|
823 | this.rparensExpected--;
|
---|
824 | this.expectCharacter(chars.$RPAREN);
|
---|
825 | result = new ast_1.FunctionCall(this.span(start), this.sourceSpan(start), result, args);
|
---|
826 | }
|
---|
827 | else if (this.consumeOptionalOperator('!')) {
|
---|
828 | result = new ast_1.NonNullAssert(this.span(start), this.sourceSpan(start), result);
|
---|
829 | }
|
---|
830 | else {
|
---|
831 | return result;
|
---|
832 | }
|
---|
833 | }
|
---|
834 | };
|
---|
835 | _ParseAST.prototype.parsePrimary = function () {
|
---|
836 | var start = this.inputIndex;
|
---|
837 | if (this.consumeOptionalCharacter(chars.$LPAREN)) {
|
---|
838 | this.rparensExpected++;
|
---|
839 | var result = this.parsePipe();
|
---|
840 | this.rparensExpected--;
|
---|
841 | this.expectCharacter(chars.$RPAREN);
|
---|
842 | return result;
|
---|
843 | }
|
---|
844 | else if (this.next.isKeywordNull()) {
|
---|
845 | this.advance();
|
---|
846 | return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), null);
|
---|
847 | }
|
---|
848 | else if (this.next.isKeywordUndefined()) {
|
---|
849 | this.advance();
|
---|
850 | return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), void 0);
|
---|
851 | }
|
---|
852 | else if (this.next.isKeywordTrue()) {
|
---|
853 | this.advance();
|
---|
854 | return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), true);
|
---|
855 | }
|
---|
856 | else if (this.next.isKeywordFalse()) {
|
---|
857 | this.advance();
|
---|
858 | return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), false);
|
---|
859 | }
|
---|
860 | else if (this.next.isKeywordThis()) {
|
---|
861 | this.advance();
|
---|
862 | return new ast_1.ThisReceiver(this.span(start), this.sourceSpan(start));
|
---|
863 | }
|
---|
864 | else if (this.consumeOptionalCharacter(chars.$LBRACKET)) {
|
---|
865 | this.rbracketsExpected++;
|
---|
866 | var elements = this.parseExpressionList(chars.$RBRACKET);
|
---|
867 | this.rbracketsExpected--;
|
---|
868 | this.expectCharacter(chars.$RBRACKET);
|
---|
869 | return new ast_1.LiteralArray(this.span(start), this.sourceSpan(start), elements);
|
---|
870 | }
|
---|
871 | else if (this.next.isCharacter(chars.$LBRACE)) {
|
---|
872 | return this.parseLiteralMap();
|
---|
873 | }
|
---|
874 | else if (this.next.isIdentifier()) {
|
---|
875 | return this.parseAccessMemberOrMethodCall(new ast_1.ImplicitReceiver(this.span(start), this.sourceSpan(start)), start, false);
|
---|
876 | }
|
---|
877 | else if (this.next.isNumber()) {
|
---|
878 | var value = this.next.toNumber();
|
---|
879 | this.advance();
|
---|
880 | return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), value);
|
---|
881 | }
|
---|
882 | else if (this.next.isString()) {
|
---|
883 | var literalValue = this.next.toString();
|
---|
884 | this.advance();
|
---|
885 | return new ast_1.LiteralPrimitive(this.span(start), this.sourceSpan(start), literalValue);
|
---|
886 | }
|
---|
887 | else if (this.next.isPrivateIdentifier()) {
|
---|
888 | this._reportErrorForPrivateIdentifier(this.next, null);
|
---|
889 | return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start));
|
---|
890 | }
|
---|
891 | else if (this.index >= this.tokens.length) {
|
---|
892 | this.error("Unexpected end of expression: " + this.input);
|
---|
893 | return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start));
|
---|
894 | }
|
---|
895 | else {
|
---|
896 | this.error("Unexpected token " + this.next);
|
---|
897 | return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start));
|
---|
898 | }
|
---|
899 | };
|
---|
900 | _ParseAST.prototype.parseExpressionList = function (terminator) {
|
---|
901 | var result = [];
|
---|
902 | do {
|
---|
903 | if (!this.next.isCharacter(terminator)) {
|
---|
904 | result.push(this.parsePipe());
|
---|
905 | }
|
---|
906 | else {
|
---|
907 | break;
|
---|
908 | }
|
---|
909 | } while (this.consumeOptionalCharacter(chars.$COMMA));
|
---|
910 | return result;
|
---|
911 | };
|
---|
912 | _ParseAST.prototype.parseLiteralMap = function () {
|
---|
913 | var keys = [];
|
---|
914 | var values = [];
|
---|
915 | var start = this.inputIndex;
|
---|
916 | this.expectCharacter(chars.$LBRACE);
|
---|
917 | if (!this.consumeOptionalCharacter(chars.$RBRACE)) {
|
---|
918 | this.rbracesExpected++;
|
---|
919 | do {
|
---|
920 | var keyStart = this.inputIndex;
|
---|
921 | var quoted = this.next.isString();
|
---|
922 | var key = this.expectIdentifierOrKeywordOrString();
|
---|
923 | keys.push({ key: key, quoted: quoted });
|
---|
924 | // Properties with quoted keys can't use the shorthand syntax.
|
---|
925 | if (quoted) {
|
---|
926 | this.expectCharacter(chars.$COLON);
|
---|
927 | values.push(this.parsePipe());
|
---|
928 | }
|
---|
929 | else if (this.consumeOptionalCharacter(chars.$COLON)) {
|
---|
930 | values.push(this.parsePipe());
|
---|
931 | }
|
---|
932 | else {
|
---|
933 | var span = this.span(keyStart);
|
---|
934 | var sourceSpan = this.sourceSpan(keyStart);
|
---|
935 | values.push(new ast_1.PropertyRead(span, sourceSpan, sourceSpan, new ast_1.ImplicitReceiver(span, sourceSpan), key));
|
---|
936 | }
|
---|
937 | } while (this.consumeOptionalCharacter(chars.$COMMA));
|
---|
938 | this.rbracesExpected--;
|
---|
939 | this.expectCharacter(chars.$RBRACE);
|
---|
940 | }
|
---|
941 | return new ast_1.LiteralMap(this.span(start), this.sourceSpan(start), keys, values);
|
---|
942 | };
|
---|
943 | _ParseAST.prototype.parseAccessMemberOrMethodCall = function (receiver, start, isSafe) {
|
---|
944 | var _this = this;
|
---|
945 | var nameStart = this.inputIndex;
|
---|
946 | var id = this.withContext(ParseContextFlags.Writable, function () {
|
---|
947 | var _a;
|
---|
948 | var id = (_a = _this.expectIdentifierOrKeyword()) !== null && _a !== void 0 ? _a : '';
|
---|
949 | if (id.length === 0) {
|
---|
950 | _this.error("Expected identifier for property access", receiver.span.end);
|
---|
951 | }
|
---|
952 | return id;
|
---|
953 | });
|
---|
954 | var nameSpan = this.sourceSpan(nameStart);
|
---|
955 | if (this.consumeOptionalCharacter(chars.$LPAREN)) {
|
---|
956 | var argumentStart = this.inputIndex;
|
---|
957 | this.rparensExpected++;
|
---|
958 | var args = this.parseCallArguments();
|
---|
959 | var argumentSpan = this.span(argumentStart, this.inputIndex).toAbsolute(this.absoluteOffset);
|
---|
960 | this.expectCharacter(chars.$RPAREN);
|
---|
961 | this.rparensExpected--;
|
---|
962 | var span = this.span(start);
|
---|
963 | var sourceSpan = this.sourceSpan(start);
|
---|
964 | return isSafe ?
|
---|
965 | new ast_1.SafeMethodCall(span, sourceSpan, nameSpan, receiver, id, args, argumentSpan) :
|
---|
966 | new ast_1.MethodCall(span, sourceSpan, nameSpan, receiver, id, args, argumentSpan);
|
---|
967 | }
|
---|
968 | else {
|
---|
969 | if (isSafe) {
|
---|
970 | if (this.consumeOptionalOperator('=')) {
|
---|
971 | this.error('The \'?.\' operator cannot be used in the assignment');
|
---|
972 | return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start));
|
---|
973 | }
|
---|
974 | else {
|
---|
975 | return new ast_1.SafePropertyRead(this.span(start), this.sourceSpan(start), nameSpan, receiver, id);
|
---|
976 | }
|
---|
977 | }
|
---|
978 | else {
|
---|
979 | if (this.consumeOptionalOperator('=')) {
|
---|
980 | if (!this.parseAction) {
|
---|
981 | this.error('Bindings cannot contain assignments');
|
---|
982 | return new ast_1.EmptyExpr(this.span(start), this.sourceSpan(start));
|
---|
983 | }
|
---|
984 | var value = this.parseConditional();
|
---|
985 | return new ast_1.PropertyWrite(this.span(start), this.sourceSpan(start), nameSpan, receiver, id, value);
|
---|
986 | }
|
---|
987 | else {
|
---|
988 | return new ast_1.PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, receiver, id);
|
---|
989 | }
|
---|
990 | }
|
---|
991 | }
|
---|
992 | };
|
---|
993 | _ParseAST.prototype.parseCallArguments = function () {
|
---|
994 | if (this.next.isCharacter(chars.$RPAREN))
|
---|
995 | return [];
|
---|
996 | var positionals = [];
|
---|
997 | do {
|
---|
998 | positionals.push(this.parsePipe());
|
---|
999 | } while (this.consumeOptionalCharacter(chars.$COMMA));
|
---|
1000 | return positionals;
|
---|
1001 | };
|
---|
1002 | /**
|
---|
1003 | * Parses an identifier, a keyword, a string with an optional `-` in between,
|
---|
1004 | * and returns the string along with its absolute source span.
|
---|
1005 | */
|
---|
1006 | _ParseAST.prototype.expectTemplateBindingKey = function () {
|
---|
1007 | var result = '';
|
---|
1008 | var operatorFound = false;
|
---|
1009 | var start = this.currentAbsoluteOffset;
|
---|
1010 | do {
|
---|
1011 | result += this.expectIdentifierOrKeywordOrString();
|
---|
1012 | operatorFound = this.consumeOptionalOperator('-');
|
---|
1013 | if (operatorFound) {
|
---|
1014 | result += '-';
|
---|
1015 | }
|
---|
1016 | } while (operatorFound);
|
---|
1017 | return {
|
---|
1018 | source: result,
|
---|
1019 | span: new ast_1.AbsoluteSourceSpan(start, start + result.length),
|
---|
1020 | };
|
---|
1021 | };
|
---|
1022 | /**
|
---|
1023 | * Parse microsyntax template expression and return a list of bindings or
|
---|
1024 | * parsing errors in case the given expression is invalid.
|
---|
1025 | *
|
---|
1026 | * For example,
|
---|
1027 | * ```
|
---|
1028 | * <div *ngFor="let item of items; index as i; trackBy: func">
|
---|
1029 | * ```
|
---|
1030 | * contains five bindings:
|
---|
1031 | * 1. ngFor -> null
|
---|
1032 | * 2. item -> NgForOfContext.$implicit
|
---|
1033 | * 3. ngForOf -> items
|
---|
1034 | * 4. i -> NgForOfContext.index
|
---|
1035 | * 5. ngForTrackBy -> func
|
---|
1036 | *
|
---|
1037 | * For a full description of the microsyntax grammar, see
|
---|
1038 | * https://gist.github.com/mhevery/d3530294cff2e4a1b3fe15ff75d08855
|
---|
1039 | *
|
---|
1040 | * @param templateKey name of the microsyntax directive, like ngIf, ngFor,
|
---|
1041 | * without the *, along with its absolute span.
|
---|
1042 | */
|
---|
1043 | _ParseAST.prototype.parseTemplateBindings = function (templateKey) {
|
---|
1044 | var bindings = [];
|
---|
1045 | // The first binding is for the template key itself
|
---|
1046 | // In *ngFor="let item of items", key = "ngFor", value = null
|
---|
1047 | // In *ngIf="cond | pipe", key = "ngIf", value = "cond | pipe"
|
---|
1048 | bindings.push.apply(bindings, tslib_1.__spreadArray([], tslib_1.__read(this.parseDirectiveKeywordBindings(templateKey))));
|
---|
1049 | while (this.index < this.tokens.length) {
|
---|
1050 | // If it starts with 'let', then this must be variable declaration
|
---|
1051 | var letBinding = this.parseLetBinding();
|
---|
1052 | if (letBinding) {
|
---|
1053 | bindings.push(letBinding);
|
---|
1054 | }
|
---|
1055 | else {
|
---|
1056 | // Two possible cases here, either `value "as" key` or
|
---|
1057 | // "directive-keyword expression". We don't know which case, but both
|
---|
1058 | // "value" and "directive-keyword" are template binding key, so consume
|
---|
1059 | // the key first.
|
---|
1060 | var key = this.expectTemplateBindingKey();
|
---|
1061 | // Peek at the next token, if it is "as" then this must be variable
|
---|
1062 | // declaration.
|
---|
1063 | var binding = this.parseAsBinding(key);
|
---|
1064 | if (binding) {
|
---|
1065 | bindings.push(binding);
|
---|
1066 | }
|
---|
1067 | else {
|
---|
1068 | // Otherwise the key must be a directive keyword, like "of". Transform
|
---|
1069 | // the key to actual key. Eg. of -> ngForOf, trackBy -> ngForTrackBy
|
---|
1070 | key.source =
|
---|
1071 | templateKey.source + key.source.charAt(0).toUpperCase() + key.source.substring(1);
|
---|
1072 | bindings.push.apply(bindings, tslib_1.__spreadArray([], tslib_1.__read(this.parseDirectiveKeywordBindings(key))));
|
---|
1073 | }
|
---|
1074 | }
|
---|
1075 | this.consumeStatementTerminator();
|
---|
1076 | }
|
---|
1077 | return new TemplateBindingParseResult(bindings, [] /* warnings */, this.errors);
|
---|
1078 | };
|
---|
1079 | _ParseAST.prototype.parseKeyedReadOrWrite = function (receiver, start, isSafe) {
|
---|
1080 | var _this = this;
|
---|
1081 | return this.withContext(ParseContextFlags.Writable, function () {
|
---|
1082 | _this.rbracketsExpected++;
|
---|
1083 | var key = _this.parsePipe();
|
---|
1084 | if (key instanceof ast_1.EmptyExpr) {
|
---|
1085 | _this.error("Key access cannot be empty");
|
---|
1086 | }
|
---|
1087 | _this.rbracketsExpected--;
|
---|
1088 | _this.expectCharacter(chars.$RBRACKET);
|
---|
1089 | if (_this.consumeOptionalOperator('=')) {
|
---|
1090 | if (isSafe) {
|
---|
1091 | _this.error('The \'?.\' operator cannot be used in the assignment');
|
---|
1092 | }
|
---|
1093 | else {
|
---|
1094 | var value = _this.parseConditional();
|
---|
1095 | return new ast_1.KeyedWrite(_this.span(start), _this.sourceSpan(start), receiver, key, value);
|
---|
1096 | }
|
---|
1097 | }
|
---|
1098 | else {
|
---|
1099 | return isSafe ? new ast_1.SafeKeyedRead(_this.span(start), _this.sourceSpan(start), receiver, key) :
|
---|
1100 | new ast_1.KeyedRead(_this.span(start), _this.sourceSpan(start), receiver, key);
|
---|
1101 | }
|
---|
1102 | return new ast_1.EmptyExpr(_this.span(start), _this.sourceSpan(start));
|
---|
1103 | });
|
---|
1104 | };
|
---|
1105 | /**
|
---|
1106 | * Parse a directive keyword, followed by a mandatory expression.
|
---|
1107 | * For example, "of items", "trackBy: func".
|
---|
1108 | * The bindings are: ngForOf -> items, ngForTrackBy -> func
|
---|
1109 | * There could be an optional "as" binding that follows the expression.
|
---|
1110 | * For example,
|
---|
1111 | * ```
|
---|
1112 | * *ngFor="let item of items | slice:0:1 as collection".
|
---|
1113 | * ^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
|
---|
1114 | * keyword bound target optional 'as' binding
|
---|
1115 | * ```
|
---|
1116 | *
|
---|
1117 | * @param key binding key, for example, ngFor, ngIf, ngForOf, along with its
|
---|
1118 | * absolute span.
|
---|
1119 | */
|
---|
1120 | _ParseAST.prototype.parseDirectiveKeywordBindings = function (key) {
|
---|
1121 | var bindings = [];
|
---|
1122 | this.consumeOptionalCharacter(chars.$COLON); // trackBy: trackByFunction
|
---|
1123 | var value = this.getDirectiveBoundTarget();
|
---|
1124 | var spanEnd = this.currentAbsoluteOffset;
|
---|
1125 | // The binding could optionally be followed by "as". For example,
|
---|
1126 | // *ngIf="cond | pipe as x". In this case, the key in the "as" binding
|
---|
1127 | // is "x" and the value is the template key itself ("ngIf"). Note that the
|
---|
1128 | // 'key' in the current context now becomes the "value" in the next binding.
|
---|
1129 | var asBinding = this.parseAsBinding(key);
|
---|
1130 | if (!asBinding) {
|
---|
1131 | this.consumeStatementTerminator();
|
---|
1132 | spanEnd = this.currentAbsoluteOffset;
|
---|
1133 | }
|
---|
1134 | var sourceSpan = new ast_1.AbsoluteSourceSpan(key.span.start, spanEnd);
|
---|
1135 | bindings.push(new ast_1.ExpressionBinding(sourceSpan, key, value));
|
---|
1136 | if (asBinding) {
|
---|
1137 | bindings.push(asBinding);
|
---|
1138 | }
|
---|
1139 | return bindings;
|
---|
1140 | };
|
---|
1141 | /**
|
---|
1142 | * Return the expression AST for the bound target of a directive keyword
|
---|
1143 | * binding. For example,
|
---|
1144 | * ```
|
---|
1145 | * *ngIf="condition | pipe"
|
---|
1146 | * ^^^^^^^^^^^^^^^^ bound target for "ngIf"
|
---|
1147 | * *ngFor="let item of items"
|
---|
1148 | * ^^^^^ bound target for "ngForOf"
|
---|
1149 | * ```
|
---|
1150 | */
|
---|
1151 | _ParseAST.prototype.getDirectiveBoundTarget = function () {
|
---|
1152 | if (this.next === lexer_1.EOF || this.peekKeywordAs() || this.peekKeywordLet()) {
|
---|
1153 | return null;
|
---|
1154 | }
|
---|
1155 | var ast = this.parsePipe(); // example: "condition | async"
|
---|
1156 | var _a = ast.span, start = _a.start, end = _a.end;
|
---|
1157 | var value = this.input.substring(start, end);
|
---|
1158 | return new ast_1.ASTWithSource(ast, value, this.location, this.absoluteOffset + start, this.errors);
|
---|
1159 | };
|
---|
1160 | /**
|
---|
1161 | * Return the binding for a variable declared using `as`. Note that the order
|
---|
1162 | * of the key-value pair in this declaration is reversed. For example,
|
---|
1163 | * ```
|
---|
1164 | * *ngFor="let item of items; index as i"
|
---|
1165 | * ^^^^^ ^
|
---|
1166 | * value key
|
---|
1167 | * ```
|
---|
1168 | *
|
---|
1169 | * @param value name of the value in the declaration, "ngIf" in the example
|
---|
1170 | * above, along with its absolute span.
|
---|
1171 | */
|
---|
1172 | _ParseAST.prototype.parseAsBinding = function (value) {
|
---|
1173 | if (!this.peekKeywordAs()) {
|
---|
1174 | return null;
|
---|
1175 | }
|
---|
1176 | this.advance(); // consume the 'as' keyword
|
---|
1177 | var key = this.expectTemplateBindingKey();
|
---|
1178 | this.consumeStatementTerminator();
|
---|
1179 | var sourceSpan = new ast_1.AbsoluteSourceSpan(value.span.start, this.currentAbsoluteOffset);
|
---|
1180 | return new ast_1.VariableBinding(sourceSpan, key, value);
|
---|
1181 | };
|
---|
1182 | /**
|
---|
1183 | * Return the binding for a variable declared using `let`. For example,
|
---|
1184 | * ```
|
---|
1185 | * *ngFor="let item of items; let i=index;"
|
---|
1186 | * ^^^^^^^^ ^^^^^^^^^^^
|
---|
1187 | * ```
|
---|
1188 | * In the first binding, `item` is bound to `NgForOfContext.$implicit`.
|
---|
1189 | * In the second binding, `i` is bound to `NgForOfContext.index`.
|
---|
1190 | */
|
---|
1191 | _ParseAST.prototype.parseLetBinding = function () {
|
---|
1192 | if (!this.peekKeywordLet()) {
|
---|
1193 | return null;
|
---|
1194 | }
|
---|
1195 | var spanStart = this.currentAbsoluteOffset;
|
---|
1196 | this.advance(); // consume the 'let' keyword
|
---|
1197 | var key = this.expectTemplateBindingKey();
|
---|
1198 | var value = null;
|
---|
1199 | if (this.consumeOptionalOperator('=')) {
|
---|
1200 | value = this.expectTemplateBindingKey();
|
---|
1201 | }
|
---|
1202 | this.consumeStatementTerminator();
|
---|
1203 | var sourceSpan = new ast_1.AbsoluteSourceSpan(spanStart, this.currentAbsoluteOffset);
|
---|
1204 | return new ast_1.VariableBinding(sourceSpan, key, value);
|
---|
1205 | };
|
---|
1206 | /**
|
---|
1207 | * Consume the optional statement terminator: semicolon or comma.
|
---|
1208 | */
|
---|
1209 | _ParseAST.prototype.consumeStatementTerminator = function () {
|
---|
1210 | this.consumeOptionalCharacter(chars.$SEMICOLON) || this.consumeOptionalCharacter(chars.$COMMA);
|
---|
1211 | };
|
---|
1212 | /**
|
---|
1213 | * Records an error and skips over the token stream until reaching a recoverable point. See
|
---|
1214 | * `this.skip` for more details on token skipping.
|
---|
1215 | */
|
---|
1216 | _ParseAST.prototype.error = function (message, index) {
|
---|
1217 | if (index === void 0) { index = null; }
|
---|
1218 | this.errors.push(new ast_1.ParserError(message, this.input, this.locationText(index), this.location));
|
---|
1219 | this.skip();
|
---|
1220 | };
|
---|
1221 | _ParseAST.prototype.locationText = function (index) {
|
---|
1222 | if (index === void 0) { index = null; }
|
---|
1223 | if (index == null)
|
---|
1224 | index = this.index;
|
---|
1225 | return (index < this.tokens.length) ? "at column " + (this.tokens[index].index + 1) + " in" :
|
---|
1226 | "at the end of the expression";
|
---|
1227 | };
|
---|
1228 | /**
|
---|
1229 | * Records an error for an unexpected private identifier being discovered.
|
---|
1230 | * @param token Token representing a private identifier.
|
---|
1231 | * @param extraMessage Optional additional message being appended to the error.
|
---|
1232 | */
|
---|
1233 | _ParseAST.prototype._reportErrorForPrivateIdentifier = function (token, extraMessage) {
|
---|
1234 | var errorMessage = "Private identifiers are not supported. Unexpected private identifier: " + token;
|
---|
1235 | if (extraMessage !== null) {
|
---|
1236 | errorMessage += ", " + extraMessage;
|
---|
1237 | }
|
---|
1238 | this.error(errorMessage);
|
---|
1239 | };
|
---|
1240 | /**
|
---|
1241 | * Error recovery should skip tokens until it encounters a recovery point.
|
---|
1242 | *
|
---|
1243 | * The following are treated as unconditional recovery points:
|
---|
1244 | * - end of input
|
---|
1245 | * - ';' (parseChain() is always the root production, and it expects a ';')
|
---|
1246 | * - '|' (since pipes may be chained and each pipe expression may be treated independently)
|
---|
1247 | *
|
---|
1248 | * The following are conditional recovery points:
|
---|
1249 | * - ')', '}', ']' if one of calling productions is expecting one of these symbols
|
---|
1250 | * - This allows skip() to recover from errors such as '(a.) + 1' allowing more of the AST to
|
---|
1251 | * be retained (it doesn't skip any tokens as the ')' is retained because of the '(' begins
|
---|
1252 | * an '(' <expr> ')' production).
|
---|
1253 | * The recovery points of grouping symbols must be conditional as they must be skipped if
|
---|
1254 | * none of the calling productions are not expecting the closing token else we will never
|
---|
1255 | * make progress in the case of an extraneous group closing symbol (such as a stray ')').
|
---|
1256 | * That is, we skip a closing symbol if we are not in a grouping production.
|
---|
1257 | * - '=' in a `Writable` context
|
---|
1258 | * - In this context, we are able to recover after seeing the `=` operator, which
|
---|
1259 | * signals the presence of an independent rvalue expression following the `=` operator.
|
---|
1260 | *
|
---|
1261 | * If a production expects one of these token it increments the corresponding nesting count,
|
---|
1262 | * and then decrements it just prior to checking if the token is in the input.
|
---|
1263 | */
|
---|
1264 | _ParseAST.prototype.skip = function () {
|
---|
1265 | var n = this.next;
|
---|
1266 | while (this.index < this.tokens.length && !n.isCharacter(chars.$SEMICOLON) &&
|
---|
1267 | !n.isOperator('|') && (this.rparensExpected <= 0 || !n.isCharacter(chars.$RPAREN)) &&
|
---|
1268 | (this.rbracesExpected <= 0 || !n.isCharacter(chars.$RBRACE)) &&
|
---|
1269 | (this.rbracketsExpected <= 0 || !n.isCharacter(chars.$RBRACKET)) &&
|
---|
1270 | (!(this.context & ParseContextFlags.Writable) || !n.isOperator('='))) {
|
---|
1271 | if (this.next.isError()) {
|
---|
1272 | this.errors.push(new ast_1.ParserError(this.next.toString(), this.input, this.locationText(), this.location));
|
---|
1273 | }
|
---|
1274 | this.advance();
|
---|
1275 | n = this.next;
|
---|
1276 | }
|
---|
1277 | };
|
---|
1278 | return _ParseAST;
|
---|
1279 | }());
|
---|
1280 | exports._ParseAST = _ParseAST;
|
---|
1281 | var SimpleExpressionChecker = /** @class */ (function () {
|
---|
1282 | function SimpleExpressionChecker() {
|
---|
1283 | this.errors = [];
|
---|
1284 | }
|
---|
1285 | SimpleExpressionChecker.prototype.visitImplicitReceiver = function (ast, context) { };
|
---|
1286 | SimpleExpressionChecker.prototype.visitThisReceiver = function (ast, context) { };
|
---|
1287 | SimpleExpressionChecker.prototype.visitInterpolation = function (ast, context) { };
|
---|
1288 | SimpleExpressionChecker.prototype.visitLiteralPrimitive = function (ast, context) { };
|
---|
1289 | SimpleExpressionChecker.prototype.visitPropertyRead = function (ast, context) { };
|
---|
1290 | SimpleExpressionChecker.prototype.visitPropertyWrite = function (ast, context) { };
|
---|
1291 | SimpleExpressionChecker.prototype.visitSafePropertyRead = function (ast, context) { };
|
---|
1292 | SimpleExpressionChecker.prototype.visitMethodCall = function (ast, context) { };
|
---|
1293 | SimpleExpressionChecker.prototype.visitSafeMethodCall = function (ast, context) { };
|
---|
1294 | SimpleExpressionChecker.prototype.visitFunctionCall = function (ast, context) { };
|
---|
1295 | SimpleExpressionChecker.prototype.visitLiteralArray = function (ast, context) {
|
---|
1296 | this.visitAll(ast.expressions, context);
|
---|
1297 | };
|
---|
1298 | SimpleExpressionChecker.prototype.visitLiteralMap = function (ast, context) {
|
---|
1299 | this.visitAll(ast.values, context);
|
---|
1300 | };
|
---|
1301 | SimpleExpressionChecker.prototype.visitUnary = function (ast, context) { };
|
---|
1302 | SimpleExpressionChecker.prototype.visitBinary = function (ast, context) { };
|
---|
1303 | SimpleExpressionChecker.prototype.visitPrefixNot = function (ast, context) { };
|
---|
1304 | SimpleExpressionChecker.prototype.visitNonNullAssert = function (ast, context) { };
|
---|
1305 | SimpleExpressionChecker.prototype.visitConditional = function (ast, context) { };
|
---|
1306 | SimpleExpressionChecker.prototype.visitPipe = function (ast, context) {
|
---|
1307 | this.errors.push('pipes');
|
---|
1308 | };
|
---|
1309 | SimpleExpressionChecker.prototype.visitKeyedRead = function (ast, context) { };
|
---|
1310 | SimpleExpressionChecker.prototype.visitKeyedWrite = function (ast, context) { };
|
---|
1311 | SimpleExpressionChecker.prototype.visitAll = function (asts, context) {
|
---|
1312 | var _this = this;
|
---|
1313 | return asts.map(function (node) { return node.visit(_this, context); });
|
---|
1314 | };
|
---|
1315 | SimpleExpressionChecker.prototype.visitChain = function (ast, context) { };
|
---|
1316 | SimpleExpressionChecker.prototype.visitQuote = function (ast, context) { };
|
---|
1317 | SimpleExpressionChecker.prototype.visitSafeKeyedRead = function (ast, context) { };
|
---|
1318 | return SimpleExpressionChecker;
|
---|
1319 | }());
|
---|
1320 | /**
|
---|
1321 | * This class implements SimpleExpressionChecker used in View Engine and performs more strict checks
|
---|
1322 | * to make sure host bindings do not contain pipes. In View Engine, having pipes in host bindings is
|
---|
1323 | * not supported as well, but in some cases (like `!(value | async)`) the error is not triggered at
|
---|
1324 | * compile time. In order to preserve View Engine behavior, more strict checks are introduced for
|
---|
1325 | * Ivy mode only.
|
---|
1326 | */
|
---|
1327 | var IvySimpleExpressionChecker = /** @class */ (function (_super) {
|
---|
1328 | tslib_1.__extends(IvySimpleExpressionChecker, _super);
|
---|
1329 | function IvySimpleExpressionChecker() {
|
---|
1330 | var _this = _super !== null && _super.apply(this, arguments) || this;
|
---|
1331 | _this.errors = [];
|
---|
1332 | return _this;
|
---|
1333 | }
|
---|
1334 | IvySimpleExpressionChecker.prototype.visitPipe = function () {
|
---|
1335 | this.errors.push('pipes');
|
---|
1336 | };
|
---|
1337 | return IvySimpleExpressionChecker;
|
---|
1338 | }(ast_1.RecursiveAstVisitor));
|
---|
1339 | });
|
---|
1340 | //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL2V4cHJlc3Npb25fcGFyc2VyL3BhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7Ozs7Ozs7Ozs7Ozs7O0lBRUgsbURBQWtDO0lBQ2xDLDZGQUFvRztJQUVwRyxtRUFBMmdCO0lBQzNnQix1RUFBbUU7SUFPbkU7UUFDRSw0QkFDVyxPQUE2QixFQUFTLFdBQWlDLEVBQ3ZFLE9BQWlCO1lBRGpCLFlBQU8sR0FBUCxPQUFPLENBQXNCO1lBQVMsZ0JBQVcsR0FBWCxXQUFXLENBQXNCO1lBQ3ZFLFlBQU8sR0FBUCxPQUFPLENBQVU7UUFBRyxDQUFDO1FBQ2xDLHlCQUFDO0lBQUQsQ0FBQyxBQUpELElBSUM7SUFKWSxnREFBa0I7SUFNL0I7UUFDRSxvQ0FDVyxnQkFBbUMsRUFBUyxRQUFrQixFQUM5RCxNQUFxQjtZQURyQixxQkFBZ0IsR0FBaEIsZ0JBQWdCLENBQW1CO1lBQVMsYUFBUSxHQUFSLFFBQVEsQ0FBVTtZQUM5RCxXQUFNLEdBQU4sTUFBTSxDQUFlO1FBQUcsQ0FBQztRQUN0QyxpQ0FBQztJQUFELENBQUMsQUFKRCxJQUlDO0lBSlksZ0VBQTBCO0lBTXZDO1FBR0UsZ0JBQW9CLE1BQWE7WUFBYixXQUFNLEdBQU4sTUFBTSxDQUFPO1lBRnpCLFdBQU0sR0FBa0IsRUFBRSxDQUFDO1lBSW5DLDRCQUF1QixHQUFHLHVCQUF1QixDQUFDO1FBRmQsQ0FBQztRQUlyQyw0QkFBVyxHQUFYLFVBQ0ksS0FBYSxFQUFFLFFBQWdCLEVBQUUsY0FBc0IsRUFDdkQsbUJBQXVFO1lBQXZFLG9DQUFBLEVBQUEsc0JBQTJDLG1EQUE0QjtZQUN6RSxJQUFJLENBQUMscUJBQXFCLENBQUMsS0FBSyxFQUFFLFFBQVEsRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO1lBQ2pFLElBQU0sV0FBVyxHQUFHLElBQUks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cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCAqIGFzIGNoYXJzIGZyb20gJy4uL2NoYXJzJztcbmltcG9ydCB7REVGQVVMVF9JTlRFUlBPTEFUSU9OX0NPTkZJRywgSW50ZXJwb2xhdGlvbkNvbmZpZ30gZnJvbSAnLi4vbWxfcGFyc2VyL2ludGVycG9sYXRpb25fY29uZmlnJztcblxuaW1wb3J0IHtBYnNvbHV0ZVNvdXJjZVNwYW4sIEFTVCwgQXN0VmlzaXRvciwgQVNUV2l0aFNvdXJjZSwgQmluYXJ5LCBCaW5kaW5nUGlwZSwgQ2hhaW4sIENvbmRpdGlvbmFsLCBFbXB0eUV4cHIsIEV4cHJlc3Npb25CaW5kaW5nLCBGdW5jdGlvbkNhbGwsIEltcGxpY2l0UmVjZWl2ZXIsIEludGVycG9sYXRpb24sIEtleWVkUmVhZCwgS2V5ZWRXcml0ZSwgTGl0ZXJhbEFycmF5LCBMaXRlcmFsTWFwLCBMaXRlcmFsTWFwS2V5LCBMaXRlcmFsUHJpbWl0aXZlLCBNZXRob2RDYWxsLCBOb25OdWxsQXNzZXJ0LCBQYXJzZXJFcnJvciwgUGFyc2VTcGFuLCBQcmVmaXhOb3QsIFByb3BlcnR5UmVhZCwgUHJvcGVydHlXcml0ZSwgUXVvdGUsIFJlY3Vyc2l2ZUFzdFZpc2l0b3IsIFNhZmVLZXllZFJlYWQsIFNhZmVNZXRob2RDYWxsLCBTYWZlUHJvcGVydHlSZWFkLCBUZW1wbGF0ZUJpbmRpbmcsIFRlbXBsYXRlQmluZGluZ0lkZW50aWZpZXIsIFRoaXNSZWNlaXZlciwgVW5hcnksIFZhcmlhYmxlQmluZGluZ30gZnJvbSAnLi9hc3QnO1xuaW1wb3J0IHtFT0YsIGlzSWRlbnRpZmllciwgTGV4ZXIsIFRva2VuLCBUb2tlblR5cGV9IGZyb20gJy4vbGV4ZXInO1xuXG5leHBvcnQgaW50ZXJmYWNlIEludGVycG9sYXRpb25QaWVjZSB7XG4gIHRleHQ6IHN0cmluZztcbiAgc3RhcnQ6IG51bWJlcjtcbiAgZW5kOiBudW1iZXI7XG59XG5leHBvcnQgY2xhc3MgU3BsaXRJbnRlcnBvbGF0aW9uIHtcbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgc3RyaW5nczogSW50ZXJwb2xhdGlvblBpZWNlW10sIHB1YmxpYyBleHByZXNzaW9uczogSW50ZXJwb2xhdGlvblBpZWNlW10sXG4gICAgICBwdWJsaWMgb2Zmc2V0czogbnVtYmVyW10pIHt9XG59XG5cbmV4cG9ydCBjbGFzcyBUZW1wbGF0ZUJpbmRpbmdQYXJzZVJlc3VsdCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHVibGljIHRlbXBsYXRlQmluZGluZ3M6IFRlbXBsYXRlQmluZGluZ1tdLCBwdWJsaWMgd2FybmluZ3M6IHN0cmluZ1tdLFxuICAgICAgcHVibGljIGVycm9yczogUGFyc2VyRXJyb3JbXSkge31cbn1cblxuZXhwb3J0IGNsYXNzIFBhcnNlciB7XG4gIHByaXZhdGUgZXJyb3JzOiBQYXJzZXJFcnJvcltdID0gW107XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBfbGV4ZXI6IExleGVyKSB7fVxuXG4gIHNpbXBsZUV4cHJlc3Npb25DaGVja2VyID0gU2ltcGxlRXhwcmVzc2lvbkNoZWNrZXI7XG5cbiAgcGFyc2VBY3Rpb24oXG4gICAgICBpbnB1dDogc3RyaW5nLCBsb2NhdGlvbjogc3RyaW5nLCBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICAgICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyA9IERFRkFVTFRfSU5URVJQT0xBVElPTl9DT05GSUcpOiBBU1RXaXRoU291cmNlIHtcbiAgICB0aGlzLl9jaGVja05vSW50ZXJwb2xhdGlvbihpbnB1dCwgbG9jYXRpb24sIGludGVycG9sYXRpb25Db25maWcpO1xuICAgIGNvbnN0IHNvdXJjZVRvTGV4ID0gdGhpcy5fc3RyaXBDb21tZW50cyhpbnB1dCk7XG4gICAgY29uc3QgdG9rZW5zID0gdGhpcy5fbGV4ZXIudG9rZW5pemUodGhpcy5fc3RyaXBDb21tZW50cyhpbnB1dCkpO1xuICAgIGNvbnN0IGFzdCA9IG5ldyBfUGFyc2VBU1QoXG4gICAgICAgICAgICAgICAgICAgIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRva2Vucywgc291cmNlVG9MZXgubGVuZ3RoLCB0cnVlLCB0aGlzLmVycm9ycyxcbiAgICAgICAgICAgICAgICAgICAgaW5wdXQubGVuZ3RoIC0gc291cmNlVG9MZXgubGVuZ3RoKVxuICAgICAgICAgICAgICAgICAgICAucGFyc2VDaGFpbigpO1xuICAgIHJldHVybiBuZXcgQVNUV2l0aFNvdXJjZShhc3QsIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRoaXMuZXJyb3JzKTtcbiAgfVxuXG4gIHBhcnNlQmluZGluZyhcbiAgICAgIGlucHV0OiBzdHJpbmcsIGxvY2F0aW9uOiBzdHJpbmcsIGFic29sdXRlT2Zmc2V0OiBudW1iZXIsXG4gICAgICBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnID0gREVGQVVMVF9JTlRFUlBPTEFUSU9OX0NPTkZJRyk6IEFTVFdpdGhTb3VyY2Uge1xuICAgIGNvbnN0IGFzdCA9IHRoaXMuX3BhcnNlQmluZGluZ0FzdChpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0LCBpbnRlcnBvbGF0aW9uQ29uZmlnKTtcbiAgICByZXR1cm4gbmV3IEFTVFdpdGhTb3VyY2UoYXN0LCBpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0LCB0aGlzLmVycm9ycyk7XG4gIH1cblxuICBwcml2YXRlIGNoZWNrU2ltcGxlRXhwcmVzc2lvbihhc3Q6IEFTVCk6IHN0cmluZ1tdIHtcbiAgICBjb25zdCBjaGVja2VyID0gbmV3IHRoaXMuc2ltcGxlRXhwcmVzc2lvbkNoZWNrZXIoKTtcbiAgICBhc3QudmlzaXQoY2hlY2tlcik7XG4gICAgcmV0dXJuIGNoZWNrZXIuZXJyb3JzO1xuICB9XG5cbiAgcGFyc2VTaW1wbGVCaW5kaW5nKFxuICAgICAgaW5wdXQ6IHN0cmluZywgbG9jYXRpb246IHN0cmluZywgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcixcbiAgICAgIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcgPSBERUZBVUxUX0lOVEVSUE9MQVRJT05fQ09ORklHKTogQVNUV2l0aFNvdXJjZSB7XG4gICAgY29uc3QgYXN0ID0gdGhpcy5fcGFyc2VCaW5kaW5nQXN0KGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIGludGVycG9sYXRpb25Db25maWcpO1xuICAgIGNvbnN0IGVycm9ycyA9IHRoaXMuY2hlY2tTaW1wbGVFeHByZXNzaW9uKGFzdCk7XG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLl9yZXBvcnRFcnJvcihcbiAgICAgICAgICBgSG9zdCBiaW5kaW5nIGV4cHJlc3Npb24gY2Fubm90IGNvbnRhaW4gJHtlcnJvcnMuam9pbignICcpfWAsIGlucHV0LCBsb2NhdGlvbik7XG4gICAgfVxuICAgIHJldHVybiBuZXcgQVNUV2l0aFNvdXJjZShhc3QsIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRoaXMuZXJyb3JzKTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlcG9ydEVycm9yKG1lc3NhZ2U6IHN0cmluZywgaW5wdXQ6IHN0cmluZywgZXJyTG9jYXRpb246IHN0cmluZywgY3R4TG9jYXRpb24/OiBzdHJpbmcpIHtcbiAgICB0aGlzLmVycm9ycy5wdXNoKG5ldyBQYXJzZXJFcnJvcihtZXNzYWdlLCBpbnB1dCwgZXJyTG9jYXRpb24sIGN0eExvY2F0aW9uKSk7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZUJpbmRpbmdBc3QoXG4gICAgICBpbnB1dDogc3RyaW5nLCBsb2NhdGlvbjogc3RyaW5nLCBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICAgICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyk6IEFTVCB7XG4gICAgLy8gUXVvdGVzIGV4cHJlc3Npb25zIHVzZSAzcmQtcGFydHkgZXhwcmVzc2lvbiBsYW5ndWFnZS4gV2UgZG9uJ3Qgd2FudCB0byB1c2VcbiAgICAvLyBvdXIgbGV4ZXIgb3IgcGFyc2VyIGZvciB0aGF0LCBzbyB3ZSBjaGVjayBmb3IgdGhhdCBhaGVhZCBvZiB0aW1lLlxuICAgIGNvbnN0IHF1b3RlID0gdGhpcy5fcGFyc2VRdW90ZShpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0KTtcblxuICAgIGlmIChxdW90ZSAhPSBudWxsKSB7XG4gICAgICByZXR1cm4gcXVvdGU7XG4gICAgfVxuXG4gICAgdGhpcy5fY2hlY2tOb0ludGVycG9sYXRpb24oaW5wdXQsIGxvY2F0aW9uLCBpbnRlcnBvbGF0aW9uQ29uZmlnKTtcbiAgICBjb25zdCBzb3VyY2VUb0xleCA9IHRoaXMuX3N0cmlwQ29tbWVudHMoaW5wdXQpO1xuICAgIGNvbnN0IHRva2VucyA9IHRoaXMuX2xleGVyLnRva2VuaXplKHNvdXJjZVRvTGV4KTtcbiAgICByZXR1cm4gbmV3IF9QYXJzZUFTVChcbiAgICAgICAgICAgICAgIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRva2Vucywgc291cmNlVG9MZXgubGVuZ3RoLCBmYWxzZSwgdGhpcy5lcnJvcnMsXG4gICAgICAgICAgICAgICBpbnB1dC5sZW5ndGggLSBzb3VyY2VUb0xleC5sZW5ndGgpXG4gICAgICAgIC5wYXJzZUNoYWluKCk7XG4gIH1cblxuICBwcml2YXRlIF9wYXJzZVF1b3RlKGlucHV0OiBzdHJpbmd8bnVsbCwgbG9jYXRpb246IHN0cmluZywgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcik6IEFTVHxudWxsIHtcbiAgICBpZiAoaW5wdXQgPT0gbnVsbCkgcmV0dXJuIG51bGw7XG4gICAgY29uc3QgcHJlZml4U2VwYXJhdG9ySW5kZXggPSBpbnB1dC5pbmRleE9mKCc6Jyk7XG4gICAgaWYgKHByZWZpeFNlcGFyYXRvckluZGV4ID09IC0xKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBwcmVmaXggPSBpbnB1dC5zdWJzdHJpbmcoMCwgcHJlZml4U2VwYXJhdG9ySW5kZXgpLnRyaW0oKTtcbiAgICBpZiAoIWlzSWRlbnRpZmllcihwcmVmaXgpKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCB1bmludGVycHJldGVkRXhwcmVzc2lvbiA9IGlucHV0LnN1YnN0cmluZyhwcmVmaXhTZXBhcmF0b3JJbmRleCArIDEpO1xuICAgIGNvbnN0IHNwYW4gPSBuZXcgUGFyc2VTcGFuKDAsIGlucHV0Lmxlbmd0aCk7XG4gICAgcmV0dXJuIG5ldyBRdW90ZShcbiAgICAgICAgc3Bhbiwgc3Bhbi50b0Fic29sdXRlKGFic29sdXRlT2Zmc2V0KSwgcHJlZml4LCB1bmludGVycHJldGVkRXhwcmVzc2lvbiwgbG9jYXRpb24pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIG1pY3Jvc3ludGF4IHRlbXBsYXRlIGV4cHJlc3Npb24gYW5kIHJldHVybiBhIGxpc3Qgb2YgYmluZGluZ3Mgb3JcbiAgICogcGFyc2luZyBlcnJvcnMgaW4gY2FzZSB0aGUgZ2l2ZW4gZXhwcmVzc2lvbiBpcyBpbnZhbGlkLlxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtc1wiPlxuICAgKiAgICAgICAgIF4gICAgICBeIGFic29sdXRlVmFsdWVPZmZzZXQgZm9yIGB0ZW1wbGF0ZVZhbHVlYFxuICAgKiAgICAgICAgIGFic29sdXRlS2V5T2Zmc2V0IGZvciBgdGVtcGxhdGVLZXlgXG4gICAqIGBgYFxuICAgKiBjb250YWlucyB0aHJlZSBiaW5kaW5nczpcbiAgICogMS4gbmdGb3IgLT4gbnVsbFxuICAgKiAyLiBpdGVtIC0+IE5nRm9yT2ZDb250ZXh0LiRpbXBsaWNpdFxuICAgKiAzLiBuZ0Zvck9mIC0+IGl0ZW1zXG4gICAqXG4gICAqIFRoaXMgaXMgYXBwYXJlbnQgZnJvbSB0aGUgZGUtc3VnYXJlZCB0ZW1wbGF0ZTpcbiAgICogYGBgXG4gICAqICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1pdGVtIFtuZ0Zvck9mXT1cIml0ZW1zXCI+XG4gICAqIGBgYFxuICAgKlxuICAgKiBAcGFyYW0gdGVtcGxhdGVLZXkgbmFtZSBvZiBkaXJlY3RpdmUsIHdpdGhvdXQgdGhlICogcHJlZml4LiBGb3IgZXhhbXBsZTogbmdJZiwgbmdGb3JcbiAgICogQHBhcmFtIHRlbXBsYXRlVmFsdWUgUkhTIG9mIHRoZSBtaWNyb3N5bnRheCBhdHRyaWJ1dGVcbiAgICogQHBhcmFtIHRlbXBsYXRlVXJsIHRlbXBsYXRlIGZpbGVuYW1lIGlmIGl0J3MgZXh0ZXJuYWwsIGNvbXBvbmVudCBmaWxlbmFtZSBpZiBpdCdzIGlubGluZVxuICAgKiBAcGFyYW0gYWJzb2x1dGVLZXlPZmZzZXQgc3RhcnQgb2YgdGhlIGB0ZW1wbGF0ZUtleWBcbiAgICogQHBhcmFtIGFic29sdXRlVmFsdWVPZmZzZXQgc3RhcnQgb2YgdGhlIGB0ZW1wbGF0ZVZhbHVlYFxuICAgKi9cbiAgcGFyc2VUZW1wbGF0ZUJpbmRpbmdzKFxuICAgICAgdGVtcGxhdGVLZXk6IHN0cmluZywgdGVtcGxhdGVWYWx1ZTogc3RyaW5nLCB0ZW1wbGF0ZVVybDogc3RyaW5nLCBhYnNvbHV0ZUtleU9mZnNldDogbnVtYmVyLFxuICAgICAgYWJzb2x1dGVWYWx1ZU9mZnNldDogbnVtYmVyKTogVGVtcGxhdGVCaW5kaW5nUGFyc2VSZXN1bHQge1xuICAgIGNvbnN0IHRva2VucyA9IHRoaXMuX2xleGVyLnRva2VuaXplKHRlbXBsYXRlVmFsdWUpO1xuICAgIGNvbnN0IHBhcnNlciA9IG5ldyBfUGFyc2VBU1QoXG4gICAgICAgIHRlbXBsYXRlVmFsdWUsIHRlbXBsYXRlVXJsLCBhYnNvbHV0ZVZhbHVlT2Zmc2V0LCB0b2tlbnMsIHRlbXBsYXRlVmFsdWUubGVuZ3RoLFxuICAgICAgICBmYWxzZSAvKiBwYXJzZUFjdGlvbiAqLywgdGhpcy5lcnJvcnMsIDAgLyogcmVsYXRpdmUgb2Zmc2V0ICovKTtcbiAgICByZXR1cm4gcGFyc2VyLnBhcnNlVGVtcGxhdGVCaW5kaW5ncyh7XG4gICAgICBzb3VyY2U6IHRlbXBsYXRlS2V5LFxuICAgICAgc3BhbjogbmV3IEFic29sdXRlU291cmNlU3BhbihhYnNvbHV0ZUtleU9mZnNldCwgYWJzb2x1dGVLZXlPZmZzZXQgKyB0ZW1wbGF0ZUtleS5sZW5ndGgpLFxuICAgIH0pO1xuICB9XG5cbiAgcGFyc2VJbnRlcnBvbGF0aW9uKFxuICAgICAgaW5wdXQ6IHN0cmluZywgbG9jYXRpb246IHN0cmluZywgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcixcbiAgICAgIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcgPSBERUZBVUxUX0lOVEVSUE9MQVRJT05fQ09ORklHKTogQVNUV2l0aFNvdXJjZXxudWxsIHtcbiAgICBjb25zdCB7c3RyaW5ncywgZXhwcmVzc2lvbnMsIG9mZnNldHN9ID1cbiAgICAgICAgdGhpcy5zcGxpdEludGVycG9sYXRpb24oaW5wdXQsIGxvY2F0aW9uLCBpbnRlcnBvbGF0aW9uQ29uZmlnKTtcbiAgICBpZiAoZXhwcmVzc2lvbnMubGVuZ3RoID09PSAwKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IGV4cHJlc3Npb25Ob2RlczogQVNUW10gPSBbXTtcblxuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgZXhwcmVzc2lvbnMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGNvbnN0IGV4cHJlc3Npb25UZXh0ID0gZXhwcmVzc2lvbnNbaV0udGV4dDtcbiAgICAgIGNvbnN0IHNvdXJjZVRvTGV4ID0gdGhpcy5fc3RyaXBDb21tZW50cyhleHByZXNzaW9uVGV4dCk7XG4gICAgICBjb25zdCB0b2tlbnMgPSB0aGlzLl9sZXhlci50b2tlbml6ZShzb3VyY2VUb0xleCk7XG4gICAgICBjb25zdCBhc3QgPSBuZXcgX1BhcnNlQVNUKFxuICAgICAgICAgICAgICAgICAgICAgIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRva2Vucywgc291cmNlVG9MZXgubGVuZ3RoLCBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmVycm9ycywgb2Zmc2V0c1tpXSArIChleHByZXNzaW9uVGV4dC5sZW5ndGggLSBzb3VyY2VUb0xleC5sZW5ndGgpKVxuICAgICAgICAgICAgICAgICAgICAgIC5wYXJzZUNoYWluKCk7XG4gICAgICBleHByZXNzaW9uTm9kZXMucHVzaChhc3QpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLmNyZWF0ZUludGVycG9sYXRpb25Bc3QoXG4gICAgICAgIHN0cmluZ3MubWFwKHMgPT4gcy50ZXh0KSwgZXhwcmVzc2lvbk5vZGVzLCBpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaW1pbGFyIHRvIGBwYXJzZUludGVycG9sYXRpb25gLCBidXQgdHJlYXRzIHRoZSBwcm92aWRlZCBzdHJpbmcgYXMgYSBzaW5nbGUgZXhwcmVzc2lvblxuICAgKiBlbGVtZW50IHRoYXQgd291bGQgbm9ybWFsbHkgYXBwZWFyIHdpdGhpbiB0aGUgaW50ZXJwb2xhdGlvbiBwcmVmaXggYW5kIHN1ZmZpeCAoYHt7YCBhbmQgYH19YCkuXG4gICAqIFRoaXMgaXMgdXNlZCBmb3IgcGFyc2luZyB0aGUgc3dpdGNoIGV4cHJlc3Npb24gaW4gSUNVcy5cbiAgICovXG4gIHBhcnNlSW50ZXJwb2xhdGlvbkV4cHJlc3Npb24oZXhwcmVzc2lvbjogc3RyaW5nLCBsb2NhdGlvbjogc3RyaW5nLCBhYnNvbHV0ZU9mZnNldDogbnVtYmVyKTpcbiAgICAgIEFTVFdpdGhTb3VyY2Uge1xuICAgIGNvbnN0IHNvdXJjZVRvTGV4ID0gdGhpcy5fc3RyaXBDb21tZW50cyhleHByZXNzaW9uKTtcbiAgICBjb25zdCB0b2tlbnMgPSB0aGlzLl9sZXhlci50b2tlbml6ZShzb3VyY2VUb0xleCk7XG4gICAgY29uc3QgYXN0ID0gbmV3IF9QYXJzZUFTVChcbiAgICAgICAgICAgICAgICAgICAgZXhwcmVzc2lvbiwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0LCB0b2tlbnMsIHNvdXJjZVRvTGV4Lmxlbmd0aCxcbiAgICAgICAgICAgICAgICAgICAgLyogcGFyc2VBY3Rpb24gKi8gZmFsc2UsIHRoaXMuZXJyb3JzLCAwKVxuICAgICAgICAgICAgICAgICAgICAucGFyc2VDaGFpbigpO1xuICAgIGNvbnN0IHN0cmluZ3MgPSBbJycsICcnXTsgIC8vIFRoZSBwcmVmaXggYW5kIHN1ZmZpeCBzdHJpbmdzIGFyZSBib3RoIGVtcHR5XG4gICAgcmV0dXJuIHRoaXMuY3JlYXRlSW50ZXJwb2xhdGlvbkFzdChzdHJpbmdzLCBbYXN0XSwgZXhwcmVzc2lvbiwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0KTtcbiAgfVxuXG4gIHByaXZhdGUgY3JlYXRlSW50ZXJwb2xhdGlvbkFzdChcbiAgICAgIHN0cmluZ3M6IHN0cmluZ1tdLCBleHByZXNzaW9uczogQVNUW10sIGlucHV0OiBzdHJpbmcsIGxvY2F0aW9uOiBzdHJpbmcsXG4gICAgICBhYnNvbHV0ZU9mZnNldDogbnVtYmVyKTogQVNUV2l0aFNvdXJjZSB7XG4gICAgY29uc3Qgc3BhbiA9IG5ldyBQYXJzZVNwYW4oMCwgaW5wdXQubGVuZ3RoKTtcbiAgICBjb25zdCBpbnRlcnBvbGF0aW9uID1cbiAgICAgICAgbmV3IEludGVycG9sYXRpb24oc3Bhbiwgc3Bhbi50b0Fic29sdXRlKGFic29sdXRlT2Zmc2V0KSwgc3RyaW5ncywgZXhwcmVzc2lvbnMpO1xuICAgIHJldHVybiBuZXcgQVNUV2l0aFNvdXJjZShpbnRlcnBvbGF0aW9uLCBpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0LCB0aGlzLmVycm9ycyk7XG4gIH1cblxuICAvKipcbiAgICogU3BsaXRzIGEgc3RyaW5nIG9mIHRleHQgaW50byBcInJhd1wiIHRleHQgc2VnbWVudHMgYW5kIGV4cHJlc3Npb25zIHByZXNlbnQgaW4gaW50ZXJwb2xhdGlvbnMgaW5cbiAgICogdGhlIHN0cmluZy5cbiAgICogUmV0dXJucyBgbnVsbGAgaWYgdGhlcmUgYXJlIG5vIGludGVycG9sYXRpb25zLCBvdGhlcndpc2UgYVxuICAgKiBgU3BsaXRJbnRlcnBvbGF0aW9uYCB3aXRoIHNwbGl0cyB0aGF0IGxvb2sgbGlrZVxuICAgKiAgIDxyYXcgdGV4dD4gPGV4cHJlc3Npb24+IDxyYXcgdGV4dD4gLi4uIDxyYXcgdGV4dD4gPGV4cHJlc3Npb24+IDxyYXcgdGV4dD5cbiAgICovXG4gIHNwbGl0SW50ZXJwb2xhdGlvbihcbiAgICAgIGlucHV0OiBzdHJpbmcsIGxvY2F0aW9uOiBzdHJpbmcsXG4gICAgICBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnID0gREVGQVVMVF9JTlRFUlBPTEFUSU9OX0NPTkZJRyk6IFNwbGl0SW50ZXJwb2xhdGlvbiB7XG4gICAgY29uc3Qgc3RyaW5nczogSW50ZXJwb2xhdGlvblBpZWNlW10gPSBbXTtcbiAgICBjb25zdCBleHByZXNzaW9uczogSW50ZXJwb2xhdGlvblBpZWNlW10gPSBbXTtcbiAgICBjb25zdCBvZmZzZXRzOiBudW1iZXJbXSA9IFtdO1xuICAgIGxldCBpID0gMDtcbiAgICBsZXQgYXRJbnRlcnBvbGF0aW9uID0gZmFsc2U7XG4gICAgbGV0IGV4dGVuZExhc3RTdHJpbmcgPSBmYWxzZTtcbiAgICBsZXQge3N0YXJ0OiBpbnRlcnBTdGFydCwgZW5kOiBpbnRlcnBFbmR9ID0gaW50ZXJwb2xhdGlvbkNvbmZpZztcbiAgICB3aGlsZSAoaSA8IGlucHV0Lmxlbmd0aCkge1xuICAgICAgaWYgKCFhdEludGVycG9sYXRpb24pIHtcbiAgICAgICAgLy8gcGFyc2UgdW50aWwgc3RhcnRpbmcge3tcbiAgICAgICAgY29uc3Qgc3RhcnQgPSBpO1xuICAgICAgICBpID0gaW5wdXQuaW5kZXhPZihpbnRlcnBTdGFydCwgaSk7XG4gICAgICAgIGlmIChpID09PSAtMSkge1xuICAgICAgICAgIGkgPSBpbnB1dC5sZW5ndGg7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGV4dCA9IGlucHV0LnN1YnN0cmluZyhzdGFydCwgaSk7XG4gICAgICAgIHN0cmluZ3MucHVzaCh7dGV4dCwgc3RhcnQsIGVuZDogaX0pO1xuXG4gICAgICAgIGF0SW50ZXJwb2xhdGlvbiA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBwYXJzZSBmcm9tIHN0YXJ0aW5nIHt7IHRvIGVuZGluZyB9fSB3aGlsZSBpZ25vcmluZyBjb250ZW50IGluc2lkZSBxdW90ZXMuXG4gICAgICAgIGNvbnN0IGZ1bGxTdGFydCA9IGk7XG4gICAgICAgIGNvbnN0IGV4cHJTdGFydCA9IGZ1bGxTdGFydCArIGludGVycFN0YXJ0Lmxlbmd0aDtcbiAgICAgICAgY29uc3QgZXhwckVuZCA9IHRoaXMuX2dldEludGVycG9sYXRpb25FbmRJbmRleChpbnB1dCwgaW50ZXJwRW5kLCBleHByU3RhcnQpO1xuICAgICAgICBpZiAoZXhwckVuZCA9PT0gLTEpIHtcbiAgICAgICAgICAvLyBDb3VsZCBub3QgZmluZCB0aGUgZW5kIG9mIHRoZSBpbnRlcnBvbGF0aW9uOyBkbyBub3QgcGFyc2UgYW4gZXhwcmVzc2lvbi5cbiAgICAgICAgICAvLyBJbnN0ZWFkIHdlIHNob3VsZCBleHRlbmQgdGhlIGNvbnRlbnQgb24gdGhlIGxhc3QgcmF3IHN0cmluZy5cbiAgICAgICAgICBhdEludGVycG9sYXRpb24gPSBmYWxzZTtcbiAgICAgICAgICBleHRlbmRMYXN0U3RyaW5nID0gdHJ1ZTtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBmdWxsRW5kID0gZXhwckVuZCArIGludGVycEVuZC5sZW5ndGg7XG5cbiAgICAgICAgY29uc3QgdGV4dCA9IGlucHV0LnN1YnN0cmluZyhleHByU3RhcnQsIGV4cHJFbmQpO1xuICAgICAgICBpZiAodGV4dC50cmltKCkubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgdGhpcy5fcmVwb3J0RXJyb3IoXG4gICAgICAgICAgICAgICdCbGFuayBleHByZXNzaW9ucyBhcmUgbm90IGFsbG93ZWQgaW4gaW50ZXJwb2xhdGVkIHN0cmluZ3MnLCBpbnB1dCxcbiAgICAgICAgICAgICAgYGF0IGNvbHVtbiAke2l9IGluYCwgbG9jYXRpb24pO1xuICAgICAgICB9XG4gICAgICAgIGV4cHJlc3Npb25zLnB1c2goe3RleHQsIHN0YXJ0OiBmdWxsU3RhcnQsIGVuZDogZnVsbEVuZH0pO1xuICAgICAgICBvZmZzZXRzLnB1c2goZXhwclN0YXJ0KTtcblxuICAgICAgICBpID0gZnVsbEVuZDtcbiAgICAgICAgYXRJbnRlcnBvbGF0aW9uID0gZmFsc2U7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghYXRJbnRlcnBvbGF0aW9uKSB7XG4gICAgICAvLyBJZiB3ZSBhcmUgbm93IGF0IGEgdGV4dCBzZWN0aW9uLCBhZGQgdGhlIHJlbWFpbmluZyBjb250ZW50IGFzIGEgcmF3IHN0cmluZy5cbiAgICAgIGlmIChleHRlbmRMYXN0U3RyaW5nKSB7XG4gICAgICAgIGNvbnN0IHBpZWNlID0gc3RyaW5nc1tzdHJpbmdzLmxlbmd0aCAtIDFdO1xuICAgICAgICBwaWVjZS50ZXh0ICs9IGlucHV0LnN1YnN0cmluZyhpKTtcbiAgICAgICAgcGllY2UuZW5kID0gaW5wdXQubGVuZ3RoO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RyaW5ncy5wdXNoKHt0ZXh0OiBpbnB1dC5zdWJzdHJpbmcoaSksIHN0YXJ0OiBpLCBlbmQ6IGlucHV0Lmxlbmd0aH0pO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbmV3IFNwbGl0SW50ZXJwb2xhdGlvbihzdHJpbmdzLCBleHByZXNzaW9ucywgb2Zmc2V0cyk7XG4gIH1cblxuICB3cmFwTGl0ZXJhbFByaW1pdGl2ZShpbnB1dDogc3RyaW5nfG51bGwsIGxvY2F0aW9uOiBzdHJpbmcsIGFic29sdXRlT2Zmc2V0OiBudW1iZXIpOlxuICAgICAgQVNUV2l0aFNvdXJjZSB7XG4gICAgY29uc3Qgc3BhbiA9IG5ldyBQYXJzZVNwYW4oMCwgaW5wdXQgPT0gbnVsbCA/IDAgOiBpbnB1dC5sZW5ndGgpO1xuICAgIHJldHVybiBuZXcgQVNUV2l0aFNvdXJjZShcbiAgICAgICAgbmV3IExpdGVyYWxQcmltaXRpdmUoc3Bhbiwgc3Bhbi50b0Fic29sdXRlKGFic29sdXRlT2Zmc2V0KSwgaW5wdXQpLCBpbnB1dCwgbG9jYXRpb24sXG4gICAgICAgIGFic29sdXRlT2Zmc2V0LCB0aGlzLmVycm9ycyk7XG4gIH1cblxuICBwcml2YXRlIF9zdHJpcENvbW1lbnRzKGlucHV0OiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGNvbnN0IGkgPSB0aGlzLl9jb21tZW50U3RhcnQoaW5wdXQpO1xuICAgIHJldHVybiBpICE9IG51bGwgPyBpbnB1dC5zdWJzdHJpbmcoMCwgaSkudHJpbSgpIDogaW5wdXQ7XG4gIH1cblxuICBwcml2YXRlIF9jb21tZW50U3RhcnQoaW5wdXQ6IHN0cmluZyk6IG51bWJlcnxudWxsIHtcbiAgICBsZXQgb3V0ZXJRdW90ZTogbnVtYmVyfG51bGwgPSBudWxsO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgaW5wdXQubGVuZ3RoIC0gMTsgaSsrKSB7XG4gICAgICBjb25zdCBjaGFyID0gaW5wdXQuY2hhckNvZGVBdChpKTtcbiAgICAgIGNvbnN0IG5leHRDaGFyID0gaW5wdXQuY2hhckNvZGVBdChpICsgMSk7XG5cbiAgICAgIGlmIChjaGFyID09PSBjaGFycy4kU0xBU0ggJiYgbmV4dENoYXIgPT0gY2hhcnMuJFNMQVNIICYmIG91dGVyUXVvdGUgPT0gbnVsbCkgcmV0dXJuIGk7XG5cbiAgICAgIGlmIChvdXRlclF1b3RlID09PSBjaGFyKSB7XG4gICAgICAgIG91dGVyUXVvdGUgPSBudWxsO1xuICAgICAgfSBlbHNlIGlmIChvdXRlclF1b3RlID09IG51bGwgJiYgY2hhcnMuaXNRdW90ZShjaGFyKSkge1xuICAgICAgICBvdXRlclF1b3RlID0gY2hhcjtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9jaGVja05vSW50ZXJwb2xhdGlvbihpbnB1dDogc3RyaW5nLCBsb2NhdGlvbjogc3RyaW5nLCB7c3RhcnQsIGVuZH06IEludGVycG9sYXRpb25Db25maWcpOlxuICAgICAgdm9pZCB7XG4gICAgbGV0IHN0YXJ0SW5kZXggPSAtMTtcbiAgICBsZXQgZW5kSW5kZXggPSAtMTtcblxuICAgIGZvciAoY29uc3QgY2hhckluZGV4IG9mIHRoaXMuX2ZvckVhY2hVbnF1b3RlZENoYXIoaW5wdXQsIDApKSB7XG4gICAgICBpZiAoc3RhcnRJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgaWYgKGlucHV0LnN0YXJ0c1dpdGgoc3RhcnQpKSB7XG4gICAgICAgICAgc3RhcnRJbmRleCA9IGNoYXJJbmRleDtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW5kSW5kZXggPSB0aGlzLl9nZXRJbnRlcnBvbGF0aW9uRW5kSW5kZXgoaW5wdXQsIGVuZCwgY2hhckluZGV4KTtcbiAgICAgICAgaWYgKGVuZEluZGV4ID4gLTEpIHtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzdGFydEluZGV4ID4gLTEgJiYgZW5kSW5kZXggPiAtMSkge1xuICAgICAgdGhpcy5fcmVwb3J0RXJyb3IoXG4gICAgICAgICAgYEdvdCBpbnRlcnBvbGF0aW9uICgke3N0YXJ0fSR7ZW5kfSkgd2hlcmUgZXhwcmVzc2lvbiB3YXMgZXhwZWN0ZWRgLCBpbnB1dCxcbiAgICAgICAgICBgYXQgY29sdW1uICR7c3RhcnRJbmRleH0gaW5gLCBsb2NhdGlvbik7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgZW5kIG9mIGFuIGludGVycG9sYXRpb24gZXhwcmVzc2lvblxuICAgKiB3aGlsZSBpZ25vcmluZyBjb21tZW50cyBhbmQgcXVvdGVkIGNvbnRlbnQuXG4gICAqL1xuICBwcml2YXRlIF9nZXRJbnRlcnBvbGF0aW9uRW5kSW5kZXgoaW5wdXQ6IHN0cmluZywgZXhwcmVzc2lvbkVuZDogc3RyaW5nLCBzdGFydDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBmb3IgKGNvbnN0IGNoYXJJbmRleCBvZiB0aGlzLl9mb3JFYWNoVW5xdW90ZWRDaGFyKGlucHV0LCBzdGFydCkpIHtcbiAgICAgIGlmIChpbnB1dC5zdGFydHNXaXRoKGV4cHJlc3Npb25FbmQsIGNoYXJJbmRleCkpIHtcbiAgICAgICAgcmV0dXJuIGNoYXJJbmRleDtcbiAgICAgIH1cblxuICAgICAgLy8gTm90aGluZyBlbHNlIGluIHRoZSBleHByZXNzaW9uIG1hdHRlcnMgYWZ0ZXIgd2UndmVcbiAgICAgIC8vIGhpdCBhIGNvbW1lbnQgc28gbG9vayBkaXJlY3RseSBmb3IgdGhlIGVuZCB0b2tlbi5cbiAgICAgIGlmIChpbnB1dC5zdGFydHNXaXRoKCcvLycsIGNoYXJJbmRleCkpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0LmluZGV4T2YoZXhwcmVzc2lvbkVuZCwgY2hhckluZGV4KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdG9yIHVzZWQgdG8gaXRlcmF0ZSBvdmVyIHRoZSBjaGFyYWN0ZXIgaW5kZXhlcyBvZiBhIHN0cmluZyB0aGF0IGFyZSBvdXRzaWRlIG9mIHF1b3Rlcy5cbiAgICogQHBhcmFtIGlucHV0IFN0cmluZyB0byBsb29wIHRocm91Z2guXG4gICAqIEBwYXJhbSBzdGFydCBJbmRleCB3aXRoaW4gdGhlIHN0cmluZyBhdCB3aGljaCB0byBzdGFydC5cbiAgICovXG4gIHByaXZhdGUgKiBfZm9yRWFjaFVucXVvdGVkQ2hhcihpbnB1dDogc3RyaW5nLCBzdGFydDogbnVtYmVyKSB7XG4gICAgbGV0IGN1cnJlbnRRdW90ZTogc3RyaW5nfG51bGwgPSBudWxsO1xuICAgIGxldCBlc2NhcGVDb3VudCA9IDA7XG4gICAgZm9yIChsZXQgaSA9IHN0YXJ0OyBpIDwgaW5wdXQubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IGNoYXIgPSBpbnB1dFtpXTtcbiAgICAgIC8vIFNraXAgdGhlIGNoYXJhY3RlcnMgaW5zaWRlIHF1b3Rlcy4gTm90ZSB0aGF0IHdlIG9ubHkgY2FyZSBhYm91dCB0aGUgb3V0ZXItbW9zdFxuICAgICAgLy8gcXVvdGVzIG1hdGNoaW5nIHVwIGFuZCB3ZSBuZWVkIHRvIGFjY291bnQgZm9yIGVzY2FwZSBjaGFyYWN0ZXJzLlxuICAgICAgaWYgKGNoYXJzLmlzUXVvdGUoaW5wdXQuY2hhckNvZGVBdChpKSkgJiYgKGN1cnJlbnRRdW90ZSA9PT0gbnVsbCB8fCBjdXJyZW50UXVvdGUgPT09IGNoYXIpICYmXG4gICAgICAgICAgZXNjYXBlQ291bnQgJSAyID09PSAwKSB7XG4gICAgICAgIGN1cnJlbnRRdW90ZSA9IGN1cnJlbnRRdW90ZSA9PT0gbnVsbCA/IGNoYXIgOiBudWxsO1xuICAgICAgfSBlbHNlIGlmIChjdXJyZW50UXVvdGUgPT09IG51bGwpIHtcbiAgICAgICAgeWllbGQgaTtcbiAgICAgIH1cbiAgICAgIGVzY2FwZUNvdW50ID0gY2hhciA9PT0gJ1xcXFwnID8gZXNjYXBlQ291bnQgKyAxIDogMDtcbiAgICB9XG4gIH1cbn1cblxuZXhwb3J0IGNsYXNzIEl2eVBhcnNlciBleHRlbmRzIFBhcnNlciB7XG4gIG92ZXJyaWRlIHNpbXBsZUV4cHJlc3Npb25DaGVja2VyID0gSXZ5U2ltcGxlRXhwcmVzc2lvbkNoZWNrZXI7XG59XG5cbi8qKiBEZXNjcmliZXMgYSBzdGF0ZWZ1bCBjb250ZXh0IGFuIGV4cHJlc3Npb24gcGFyc2VyIGlzIGluLiAqL1xuZW51bSBQYXJzZUNvbnRleHRGbGFncyB7XG4gIE5vbmUgPSAwLFxuICAvKipcbiAgICogQSBXcml0YWJsZSBjb250ZXh0IGlzIG9uZSBpbiB3aGljaCBhIHZhbHVlIG1heSBiZSB3cml0dGVuIHRvIGFuIGx2YWx1ZS5cbiAgICogRm9yIGV4YW1wbGUsIGFmdGVyIHdlIHNlZSBhIHByb3BlcnR5IGFjY2Vzcywgd2UgbWF5IGV4cGVjdCBhIHdyaXRlIHRvIHRoZVxuICAgKiBwcm9wZXJ0eSB2aWEgdGhlIFwiPVwiIG9wZXJhdG9yLlxuICAgKiAgIHByb3BcbiAgICogICAgICAgIF4gcG9zc2libGUgXCI9XCIgYWZ0ZXJcbiAgICovXG4gIFdyaXRhYmxlID0gMSxcbn1cblxuZXhwb3J0IGNsYXNzIF9QYXJzZUFTVCB7XG4gIHByaXZhdGUgcnBhcmVuc0V4cGVjdGVkID0gMDtcbiAgcHJpdmF0ZSByYnJhY2tldHNFeHBlY3RlZCA9IDA7XG4gIHByaXZhdGUgcmJyYWNlc0V4cGVjdGVkID0gMDtcbiAgcHJpdmF0ZSBjb250ZXh0ID0gUGFyc2VDb250ZXh0RmxhZ3MuTm9uZTtcblxuICAvLyBDYWNoZSBvZiBleHByZXNzaW9uIHN0YXJ0IGFuZCBpbnB1dCBpbmRlY2VzIHRvIHRoZSBhYnNvbHV0ZSBzb3VyY2Ugc3BhbiB0aGV5IG1hcCB0bywgdXNlZCB0b1xuICAvLyBwcmV2ZW50IGNyZWF0aW5nIHN1cGVyZmx1b3VzIHNvdXJjZSBzcGFucyBpbiBgc291cmNlU3BhbmAuXG4gIC8vIEEgc2VyaWFsIG9mIHRoZSBleHByZXNzaW9uIHN0YXJ0IGFuZCBpbnB1dCBpbmRleCBpcyB1c2VkIGZvciBtYXBwaW5nIGJlY2F1c2UgYm90aCBhcmUgc3RhdGVmdWxcbiAgLy8gYW5kIG1heSBjaGFuZ2UgZm9yIHN1YnNlcXVlbnQgZXhwcmVzc2lvbnMgdmlzaXRlZCBieSB0aGUgcGFyc2VyLlxuICBwcml2YXRlIHNvdXJjZVNwYW5DYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBBYnNvbHV0ZVNvdXJjZVNwYW4+KCk7XG5cbiAgaW5kZXg6IG51bWJlciA9IDA7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwdWJsaWMgaW5wdXQ6IHN0cmluZywgcHVibGljIGxvY2F0aW9uOiBzdHJpbmcsIHB1YmxpYyBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICAgICAgcHVibGljIHRva2VuczogVG9rZW5bXSwgcHVibGljIGlucHV0TGVuZ3RoOiBudW1iZXIsIHB1YmxpYyBwYXJzZUFjdGlvbjogYm9vbGVhbixcbiAgICAgIHByaXZhdGUgZXJyb3JzOiBQYXJzZXJFcnJvcltdLCBwcml2YXRlIG9mZnNldDogbnVtYmVyKSB7fVxuXG4gIHBlZWsob2Zmc2V0OiBudW1iZXIpOiBUb2tlbiB7XG4gICAgY29uc3QgaSA9IHRoaXMuaW5kZXggKyBvZmZzZXQ7XG4gICAgcmV0dXJuIGkgPCB0aGlzLnRva2Vucy5sZW5ndGggPyB0aGlzLnRva2Vuc1tpXSA6IEVPRjtcbiAgfVxuXG4gIGdldCBuZXh0KCk6IFRva2VuIHtcbiAgICByZXR1cm4gdGhpcy5wZWVrKDApO1xuICB9XG5cbiAgLyoqIFdoZXRoZXIgYWxsIHRoZSBwYXJzZXIgaW5wdXQgaGFzIGJlZW4gcHJvY2Vzc2VkLiAqL1xuICBnZXQgYXRFT0YoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXggPj0gdGhpcy50b2tlbnMubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIEluZGV4IG9mIHRoZSBuZXh0IHRva2VuIHRvIGJlIHByb2Nlc3NlZCwgb3IgdGhlIGVuZCBvZiB0aGUgbGFzdCB0b2tlbiBpZiBhbGwgaGF2ZSBiZWVuXG4gICAqIHByb2Nlc3NlZC5cbiAgICovXG4gIGdldCBpbnB1dEluZGV4KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYXRFT0YgPyB0aGlzLmN1cnJlbnRFbmRJbmRleCA6IHRoaXMubmV4dC5pbmRleCArIHRoaXMub2Zmc2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIEVuZCBpbmRleCBvZiB0aGUgbGFzdCBwcm9jZXNzZWQgdG9rZW4sIG9yIHRoZSBzdGFydCBvZiB0aGUgZmlyc3QgdG9rZW4gaWYgbm9uZSBoYXZlIGJlZW5cbiAgICogcHJvY2Vzc2VkLlxuICAgKi9cbiAgZ2V0IGN1cnJlbnRFbmRJbmRleCgpOiBudW1iZXIge1xuICAgIGlmICh0aGlzLmluZGV4ID4gMCkge1xuICAgICAgY29uc3QgY3VyVG9rZW4gPSB0aGlzLnBlZWsoLTEpO1xuICAgICAgcmV0dXJuIGN1clRva2VuLmVuZCArIHRoaXMub2Zmc2V0O1xuICAgIH1cbiAgICAvLyBObyB0b2tlbnMgaGF2ZSBiZWVuIHByb2Nlc3NlZCB5ZXQ7IHJldHVybiB0aGUgbmV4dCB0b2tlbidzIHN0YXJ0IG9yIHRoZSBsZW5ndGggb2YgdGhlIGlucHV0XG4gICAgLy8gaWYgdGhlcmUgaXMgbm8gdG9rZW4uXG4gICAgaWYgKHRoaXMudG9rZW5zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIHRoaXMuaW5wdXRMZW5ndGggKyB0aGlzLm9mZnNldDtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMubmV4dC5pbmRleCArIHRoaXMub2Zmc2V0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIGFic29sdXRlIG9mZnNldCBvZiB0aGUgc3RhcnQgb2YgdGhlIGN1cnJlbnQgdG9rZW4uXG4gICAqL1xuICBnZXQgY3VycmVudEFic29sdXRlT2Zmc2V0KCk6IG51bWJlciB7XG4gICAgcmV0dXJuIHRoaXMuYWJzb2x1dGVPZmZzZXQgKyB0aGlzLmlucHV0SW5kZXg7XG4gIH1cblxuICAvKipcbiAgICogUmV0cmlldmUgYSBgUGFyc2VTcGFuYCBmcm9tIGBzdGFydGAgdG8gdGhlIGN1cnJlbnQgcG9zaXRpb24gKG9yIHRvIGBhcnRpZmljaWFsRW5kSW5kZXhgIGlmXG4gICAqIHByb3ZpZGVkKS5cbiAgICpcbiAgICogQHBhcmFtIHN0YXJ0IFBvc2l0aW9uIGZyb20gd2hpY2ggdGhlIGBQYXJzZVNwYW5gIHdpbGwgc3RhcnQuXG4gICAqIEBwYXJhbSBhcnRpZmljaWFsRW5kSW5kZXggT3B0aW9uYWwgZW5kaW5nIGluZGV4IHRvIGJlIHVzZWQgaWYgcHJvdmlkZWQgKGFuZCBpZiBncmVhdGVyIHRoYW4gdGhlXG4gICAqICAgICBuYXR1cmFsIGVuZGluZyBpbmRleClcbiAgICovXG4gIHNwYW4oc3RhcnQ6IG51bWJlciwgYXJ0aWZpY2lhbEVuZEluZGV4PzogbnVtYmVyKTogUGFyc2VTcGFuIHtcbiAgICBsZXQgZW5kSW5kZXggPSB0aGlzLmN1cnJlbnRFbmRJbmRleDtcbiAgICBpZiAoYXJ0aWZpY2lhbEVuZEluZGV4ICE9PSB1bmRlZmluZWQgJiYgYXJ0aWZpY2lhbEVuZEluZGV4ID4gdGhpcy5jdXJyZW50RW5kSW5kZXgpIHtcbiAgICAgIGVuZEluZGV4ID0gYXJ0aWZpY2lhbEVuZEluZGV4O1xuICAgIH1cblxuICAgIC8vIEluIHNvbWUgdW51c3VhbCBwYXJzaW5nIHNjZW5hcmlvcyAobGlrZSB3aGVuIGNlcnRhaW4gdG9rZW5zIGFyZSBtaXNzaW5nIGFuZCBhbiBgRW1wdHlFeHByYCBpc1xuICAgIC8vIGJlaW5nIGNyZWF0ZWQpLCB0aGUgY3VycmVudCB0b2tlbiBtYXkgYWxyZWFkeSBiZSBhZHZhbmNlZCBiZXlvbmQgdGhlIGBjdXJyZW50RW5kSW5kZXhgLiBUaGlzXG4gICAgLy8gYXBwZWFycyB0byBiZSBhIGRlZXAtc2VhdGVkIHBhcnNlciBidWcuXG4gICAgLy9cbiAgICAvLyBBcyBhIHdvcmthcm91bmQgZm9yIG5vdywgc3dhcCB0aGUgc3RhcnQgYW5kIGVuZCBpbmRpY2VzIHRvIGVuc3VyZSBhIHZhbGlkIGBQYXJzZVNwYW5gLlxuICAgIC8vIFRPRE8oYWx4aHViKTogZml4IHRoZSBidWcgdXBzdHJlYW0gaW4gdGhlIHBhcnNlciBzdGF0ZSwgYW5kIHJlbW92ZSB0aGlzIHdvcmthcm91bmQuXG4gICAgaWYgKHN0YXJ0ID4gZW5kSW5kZXgpIHtcbiAgICAgIGNvbnN0IHRtcCA9IGVuZEluZGV4O1xuICAgICAgZW5kSW5kZXggPSBzdGFydDtcbiAgICAgIHN0YXJ0ID0gdG1wO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUGFyc2VTcGFuKHN0YXJ0LCBlbmRJbmRleCk7XG4gIH1cblxuICBzb3VyY2VTcGFuKHN0YXJ0OiBudW1iZXIsIGFydGlmaWNpYWxFbmRJbmRleD86IG51bWJlcik6IEFic29sdXRlU291cmNlU3BhbiB7XG4gICAgY29uc3Qgc2VyaWFsID0gYCR7c3RhcnR9QCR7dGhpcy5pbnB1dEluZGV4fToke2FydGlmaWNpYWxFbmRJbmRleH1gO1xuICAgIGlmICghdGhpcy5zb3VyY2VTcGFuQ2FjaGUuaGFzKHNlcmlhbCkpIHtcbiAgICAgIHRoaXMuc291cmNlU3BhbkNhY2hlLnNldChcbiAgICAgICAgICBzZXJpYWwsIHRoaXMuc3BhbihzdGFydCwgYXJ0aWZpY2lhbEVuZEluZGV4KS50b0Fic29sdXRlKHRoaXMuYWJzb2x1dGVPZmZzZXQpKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc291cmNlU3BhbkNhY2hlLmdldChzZXJpYWwpITtcbiAgfVxuXG4gIGFkdmFuY2UoKSB7XG4gICAgdGhpcy5pbmRleCsrO1xuICB9XG5cbiAgLyoqXG4gICAqIEV4ZWN1dGVzIGEgY2FsbGJhY2sgaW4gdGhlIHByb3ZpZGVkIGNvbnRleHQuXG4gICAqL1xuICBwcml2YXRlIHdpdGhDb250ZXh0PFQ+KGNvbnRleHQ6IFBhcnNlQ29udGV4dEZsYWdzLCBjYjogKCkgPT4gVCk6IFQge1xuICAgIHRoaXMuY29udGV4dCB8PSBjb250ZXh0O1xuICAgIGNvbnN0IHJldCA9IGNiKCk7XG4gICAgdGhpcy5jb250ZXh0IF49IGNvbnRleHQ7XG4gICAgcmV0dXJuIHJldDtcbiAgfVxuXG4gIGNvbnN1bWVPcHRpb25hbENoYXJhY3Rlcihjb2RlOiBudW1iZXIpOiBib29sZWFuIHtcbiAgICBpZiAodGhpcy5uZXh0LmlzQ2hhcmFjdGVyKGNvZGUpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG5cbiAgcGVla0tleXdvcmRMZXQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubmV4dC5pc0tleXdvcmRMZXQoKTtcbiAgfVxuICBwZWVrS2V5d29yZEFzKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm5leHQuaXNLZXl3b3JkQXMoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdW1lcyBhbiBleHBlY3RlZCBjaGFyYWN0ZXIsIG90aGVyd2lzZSBlbWl0cyBhbiBlcnJvciBhYm91dCB0aGUgbWlzc2luZyBleHBlY3RlZCBjaGFyYWN0ZXJcbiAgICogYW5kIHNraXBzIG92ZXIgdGhlIHRva2VuIHN0cmVhbSB1bnRpbCByZWFjaGluZyBhIHJlY292ZXJhYmxlIHBvaW50LlxuICAgKlxuICAgKiBTZWUgYHRoaXMuZXJyb3JgIGFuZCBgdGhpcy5za2lwYCBmb3IgbW9yZSBkZXRhaWxzLlxuICAgKi9cbiAgZXhwZWN0Q2hhcmFjdGVyKGNvZGU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3Rlcihjb2RlKSkgcmV0dXJuO1xuICAgIHRoaXMuZXJyb3IoYE1pc3NpbmcgZXhwZWN0ZWQgJHtTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpfWApO1xuICB9XG5cbiAgY29uc3VtZU9wdGlvbmFsT3BlcmF0b3Iob3A6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIGlmICh0aGlzLm5leHQuaXNPcGVyYXRvcihvcCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIHRydWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICBleHBlY3RPcGVyYXRvcihvcGVyYXRvcjogc3RyaW5nKSB7XG4gICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3Iob3BlcmF0b3IpKSByZXR1cm47XG4gICAgdGhpcy5lcnJvcihgTWlzc2luZyBleHBlY3RlZCBvcGVyYXRvciAke29wZXJhdG9yfWApO1xuICB9XG5cbiAgcHJldHR5UHJpbnRUb2tlbih0b2s6IFRva2VuKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdG9rID09PSBFT0YgPyAnZW5kIG9mIGlucHV0JyA6IGB0b2tlbiAke3Rva31gO1xuICB9XG5cbiAgZXhwZWN0SWRlbnRpZmllck9yS2V5d29yZCgpOiBzdHJpbmd8bnVsbCB7XG4gICAgY29uc3QgbiA9IHRoaXMubmV4dDtcbiAgICBpZiAoIW4uaXNJZGVudGlmaWVyKCkgJiYgIW4uaXNLZXl3b3JkKCkpIHtcbiAgICAgIGlmIChuLmlzUHJpdmF0ZUlkZW50aWZpZXIoKSkge1xuICAgICAgICB0aGlzLl9yZXBvcnRFcnJvckZvclByaXZhdGVJZGVudGlmaWVyKG4sICdleHBlY3RlZCBpZGVudGlmaWVyIG9yIGtleXdvcmQnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuZXJyb3IoYFVuZXhwZWN0ZWQgJHt0aGlzLnByZXR0eVByaW50VG9rZW4obil9LCBleHBlY3RlZCBpZGVudGlmaWVyIG9yIGtleXdvcmRgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICByZXR1cm4gbi50b1N0cmluZygpIGFzIHN0cmluZztcbiAgfVxuXG4gIGV4cGVjdElkZW50aWZpZXJPcktleXdvcmRPclN0cmluZygpOiBzdHJpbmcge1xuICAgIGNvbnN0IG4gPSB0aGlzLm5leHQ7XG4gICAgaWYgKCFuLmlzSWRlbnRpZmllcigpICYmICFuLmlzS2V5d29yZCgpICYmICFuLmlzU3RyaW5nKCkpIHtcbiAgICAgIGlmIChuLmlzUHJpdmF0ZUlkZW50aWZpZXIoKSkge1xuICAgICAgICB0aGlzLl9yZXBvcnRFcnJvckZvclByaXZhdGVJZGVudGlmaWVyKG4sICdleHBlY3RlZCBpZGVudGlmaWVyLCBrZXl3b3JkIG9yIHN0cmluZycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lcnJvcihcbiAgICAgICAgICAgIGBVbmV4cGVjdGVkICR7dGhpcy5wcmV0dHlQcmludFRva2VuKG4pfSwgZXhwZWN0ZWQgaWRlbnRpZmllciwga2V5d29yZCwgb3Igc3RyaW5nYCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIHJldHVybiBuLnRvU3RyaW5nKCkgYXMgc3RyaW5nO1xuICB9XG5cbiAgcGFyc2VDaGFpbigpOiBBU1Qge1xuICAgIGNvbnN0IGV4cHJzOiBBU1RbXSA9IFtdO1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIHdoaWxlICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBleHByID0gdGhpcy5wYXJzZVBpcGUoKTtcbiAgICAgIGV4cHJzLnB1c2goZXhwcik7XG5cbiAgICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSkge1xuICAgICAgICBpZiAoIXRoaXMucGFyc2VBY3Rpb24pIHtcbiAgICAgICAgICB0aGlzLmVycm9yKCdCaW5kaW5nIGV4cHJlc3Npb24gY2Fubm90IGNvbnRhaW4gY2hhaW5lZCBleHByZXNzaW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRTRU1JQ09MT04pKSB7XG4gICAgICAgIH0gIC8vIHJlYWQgYWxsIHNlbWljb2xvbnNcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCkge1xuICAgICAgICB0aGlzLmVycm9yKGBVbmV4cGVjdGVkIHRva2VuICcke3RoaXMubmV4dH0nYCk7XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChleHBycy5sZW5ndGggPT0gMCkge1xuICAgICAgLy8gV2UgaGF2ZSBubyBleHByZXNzaW9ucyBzbyBjcmVhdGUgYW4gZW1wdHkgZXhwcmVzc2lvbiB0aGF0IHNwYW5zIHRoZSBlbnRpcmUgaW5wdXQgbGVuZ3RoXG4gICAgICBjb25zdCBhcnRpZmljaWFsU3RhcnQgPSB0aGlzLm9mZnNldDtcbiAgICAgIGNvbnN0IGFydGlmaWNpYWxFbmQgPSB0aGlzLm9mZnNldCArIHRoaXMuaW5wdXRMZW5ndGg7XG4gICAgICByZXR1cm4gbmV3IEVtcHR5RXhwcihcbiAgICAgICAgICB0aGlzLnNwYW4oYXJ0aWZpY2lhbFN0YXJ0LCBhcnRpZmljaWFsRW5kKSxcbiAgICAgICAgICB0aGlzLnNvdXJjZVNwYW4oYXJ0aWZpY2lhbFN0YXJ0LCBhcnRpZmljaWFsRW5kKSk7XG4gICAgfVxuICAgIGlmIChleHBycy5sZW5ndGggPT0gMSkgcmV0dXJuIGV4cHJzWzBdO1xuICAgIHJldHVybiBuZXcgQ2hhaW4odGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgZXhwcnMpO1xuICB9XG5cbiAgcGFyc2VQaXBlKCk6IEFTVCB7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VFeHByZXNzaW9uKCk7XG4gICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJ3wnKSkge1xuICAgICAgaWYgKHRoaXMucGFyc2VBY3Rpb24pIHtcbiAgICAgICAgdGhpcy5lcnJvcignQ2Fubm90IGhhdmUgYSBwaXBlIGluIGFuIGFjdGlvbiBleHByZXNzaW9uJyk7XG4gICAgICB9XG5cbiAgICAgIGRvIHtcbiAgICAgICAgY29uc3QgbmFtZVN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgICAgICBsZXQgbmFtZUlkID0gdGhpcy5leHBlY3RJZGVudGlmaWVyT3JLZXl3b3JkKCk7XG4gICAgICAgIGxldCBuYW1lU3BhbjogQWJzb2x1dGVTb3VyY2VTcGFuO1xuICAgICAgICBsZXQgZnVsbFNwYW5FbmQ6IG51bWJlcnx1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChuYW1lSWQgIT09IG51bGwpIHtcbiAgICAgICAgICBuYW1lU3BhbiA9IHRoaXMuc291cmNlU3BhbihuYW1lU3RhcnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHZhbGlkIGlkZW50aWZpZXIgd2FzIGZvdW5kLCBzbyB3ZSdsbCBhc3N1bWUgYW4gZW1wdHkgcGlwZSBuYW1lICgnJykuXG4gICAgICAgICAgbmFtZUlkID0gJyc7XG5cbiAgICAgICAgICAvLyBIb3dldmVyLCB0aGVyZSBtYXkgaGF2ZSBiZWVuIHdoaXRlc3BhY2UgcHJlc2VudCBiZXR3ZWVuIHRoZSBwaXBlIGNoYXJhY3RlciBhbmQgdGhlIG5leHRcbiAgICAgICAgICAvLyB0b2tlbiBpbiB0aGUgc2VxdWVuY2UgKG9yIHRoZSBlbmQgb2YgaW5wdXQpLiBXZSB3YW50IHRvIHRyYWNrIHRoaXMgd2hpdGVzcGFjZSBzbyB0aGF0XG4gICAgICAgICAgLy8gdGhlIGBCaW5kaW5nUGlwZWAgd2UgcHJvZHVjZSBjb3ZlcnMgbm90IGp1c3QgdGhlIHBpcGUgY2hhcmFjdGVyLCBidXQgYW55IHRyYWlsaW5nXG4gICAgICAgICAgLy8gd2hpdGVzcGFjZSBiZXlvbmQgaXQuIEFub3RoZXIgd2F5IG9mIHRoaW5raW5nIGFib3V0IHRoaXMgaXMgdGhhdCB0aGUgemVyby1sZW5ndGggbmFtZVxuICAgICAgICAgIC8vIGlzIGFzc3VtZWQgdG8gYmUgYXQgdGhlIGVuZCBvZiBhbnkgd2hpdGVzcGFjZSBiZXlvbmQgdGhlIHBpcGUgY2hhcmFjdGVyLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gVGhlcmVmb3JlLCB3ZSBwdXNoIHRoZSBlbmQgb2YgdGhlIGBQYXJzZVNwYW5gIGZvciB0aGlzIHBpcGUgYWxsIHRoZSB3YXkgdXAgdG8gdGhlXG4gICAgICAgICAgLy8gYmVnaW5uaW5nIG9mIHRoZSBuZXh0IHRva2VuLCBvciB1bnRpbCB0aGUgZW5kIG9mIGlucHV0IGlmIHRoZSBuZXh0IHRva2VuIGlzIEVPRi5cbiAgICAgICAgICBmdWxsU3BhbkVuZCA9IHRoaXMubmV4dC5pbmRleCAhPT0gLTEgPyB0aGlzLm5leHQuaW5kZXggOiB0aGlzLmlucHV0TGVuZ3RoICsgdGhpcy5vZmZzZXQ7XG5cbiAgICAgICAgICAvLyBUaGUgYG5hbWVTcGFuYCBmb3IgYW4gZW1wdHkgcGlwZSBuYW1lIGlzIHplcm8tbGVuZ3RoIGF0IHRoZSBlbmQgb2YgYW55IHdoaXRlc3BhY2VcbiAgICAgICAgICAvLyBiZXlvbmQgdGhlIHBpcGUgY2hhcmFjdGVyLlxuICAgICAgICAgIG5hbWVTcGFuID0gbmV3IFBhcnNlU3BhbihmdWxsU3BhbkVuZCwgZnVsbFNwYW5FbmQpLnRvQWJzb2x1dGUodGhpcy5hYnNvbHV0ZU9mZnNldCk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBhcmdzOiBBU1RbXSA9IFtdO1xuICAgICAgICB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKSkge1xuICAgICAgICAgIGFyZ3MucHVzaCh0aGlzLnBhcnNlRXhwcmVzc2lvbigpKTtcblxuICAgICAgICAgIC8vIElmIHRoZXJlIGFyZSBhZGRpdGlvbmFsIGV4cHJlc3Npb25zIGJleW9uZCB0aGUgbmFtZSwgdGhlbiB0aGUgYXJ0aWZpY2lhbCBlbmQgZm9yIHRoZVxuICAgICAgICAgIC8vIG5hbWUgaXMgbm8gbG9uZ2VyIHJlbGV2YW50LlxuICAgICAgICB9XG4gICAgICAgIHJlc3VsdCA9IG5ldyBCaW5kaW5nUGlwZShcbiAgICAgICAgICAgIHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCwgZnVsbFNwYW5FbmQpLCByZXN1bHQsIG5hbWVJZCwgYXJncywgbmFtZVNwYW4pO1xuICAgICAgfSB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignfCcpKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VFeHByZXNzaW9uKCk6IEFTVCB7XG4gICAgcmV0dXJuIHRoaXMucGFyc2VDb25kaXRpb25hbCgpO1xuICB9XG5cbiAgcGFyc2VDb25kaXRpb25hbCgpOiBBU1Qge1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMucGFyc2VMb2dpY2FsT3IoKTtcblxuICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCc/JykpIHtcbiAgICAgIGNvbnN0IHllcyA9IHRoaXMucGFyc2VQaXBlKCk7XG4gICAgICBsZXQgbm86IEFTVDtcbiAgICAgIGlmICghdGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKSkge1xuICAgICAgICBjb25zdCBlbmQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSB0aGlzLmlucHV0LnN1YnN0cmluZyhzdGFydCwgZW5kKTtcbiAgICAgICAgdGhpcy5lcnJvcihgQ29uZGl0aW9uYWwgZXhwcmVzc2lvbiAke2V4cHJlc3Npb259IHJlcXVpcmVzIGFsbCAzIGV4cHJlc3Npb25zYCk7XG4gICAgICAgIG5vID0gbmV3IEVtcHR5RXhwcih0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vID0gdGhpcy5wYXJzZVBpcGUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgQ29uZGl0aW9uYWwodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgcmVzdWx0LCB5ZXMsIG5vKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cblxuICBwYXJzZUxvZ2ljYWxPcigpOiBBU1Qge1xuICAgIC8vICd8fCdcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZUxvZ2ljYWxBbmQoKTtcbiAgICB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignfHwnKSkge1xuICAgICAgY29uc3QgcmlnaHQgPSB0aGlzLnBhcnNlTG9naWNhbEFuZCgpO1xuICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCAnfHwnLCByZXN1bHQsIHJpZ2h0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHBhcnNlTG9naWNhbEFuZCgpOiBBU1Qge1xuICAgIC8vICcmJidcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZU51bGxpc2hDb2FsZXNjaW5nKCk7XG4gICAgd2hpbGUgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJyYmJykpIHtcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZU51bGxpc2hDb2FsZXNjaW5nKCk7XG4gICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksICcmJicsIHJlc3VsdCwgcmlnaHQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VOdWxsaXNoQ29hbGVzY2luZygpOiBBU1Qge1xuICAgIC8vICc/PydcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZUVxdWFsaXR5KCk7XG4gICAgd2hpbGUgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJz8/JykpIHtcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZUVxdWFsaXR5KCk7XG4gICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksICc/PycsIHJlc3VsdCwgcmlnaHQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VFcXVhbGl0eSgpOiBBU1Qge1xuICAgIC8vICc9PScsJyE9JywnPT09JywnIT09J1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlUmVsYXRpb25hbCgpO1xuICAgIHdoaWxlICh0aGlzLm5leHQudHlwZSA9PSBUb2tlblR5cGUuT3BlcmF0b3IpIHtcbiAgICAgIGNvbnN0IG9wZXJhdG9yID0gdGhpcy5uZXh0LnN0clZhbHVlO1xuICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgICBjYXNlICc9PSc6XG4gICAgICAgIGNhc2UgJz09PSc6XG4gICAgICAgIGNhc2UgJyE9JzpcbiAgICAgICAgY2FzZSAnIT09JzpcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICBjb25zdCByaWdodCA9IHRoaXMucGFyc2VSZWxhdGlvbmFsKCk7XG4gICAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBvcGVyYXRvciwgcmVzdWx0LCByaWdodCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHBhcnNlUmVsYXRpb25hbCgpOiBBU1Qge1xuICAgIC8vICc8JywgJz4nLCAnPD0nLCAnPj0nXG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VBZGRpdGl2ZSgpO1xuICAgIHdoaWxlICh0aGlzLm5leHQudHlwZSA9PSBUb2tlblR5cGUuT3BlcmF0b3IpIHtcbiAgICAgIGNvbnN0IG9wZXJhdG9yID0gdGhpcy5uZXh0LnN0clZhbHVlO1xuICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgICBjYXNlICc8JzpcbiAgICAgICAgY2FzZSAnPic6XG4gICAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgY2FzZSAnPj0nOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZUFkZGl0aXZlKCk7XG4gICAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBvcGVyYXRvciwgcmVzdWx0LCByaWdodCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHBhcnNlQWRkaXRpdmUoKTogQVNUIHtcbiAgICAvLyAnKycsICctJ1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlTXVsdGlwbGljYXRpdmUoKTtcbiAgICB3aGlsZSAodGhpcy5uZXh0LnR5cGUgPT0gVG9rZW5UeXBlLk9wZXJhdG9yKSB7XG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMubmV4dC5zdHJWYWx1ZTtcbiAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSAnKyc6XG4gICAgICAgIGNhc2UgJy0nOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIGxldCByaWdodCA9IHRoaXMucGFyc2VNdWx0aXBsaWNhdGl2ZSgpO1xuICAgICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgb3BlcmF0b3IsIHJlc3VsdCwgcmlnaHQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwYXJzZU11bHRpcGxpY2F0aXZlKCk6IEFTVCB7XG4gICAgLy8gJyonLCAnJScsICcvJ1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlUHJlZml4KCk7XG4gICAgd2hpbGUgKHRoaXMubmV4dC50eXBlID09IFRva2VuVHlwZS5PcGVyYXRvcikge1xuICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLm5leHQuc3RyVmFsdWU7XG4gICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgJyonOlxuICAgICAgICBjYXNlICclJzpcbiAgICAgICAgY2FzZSAnLyc6XG4gICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICAgICAgbGV0IHJpZ2h0ID0gdGhpcy5wYXJzZVByZWZpeCgpO1xuICAgICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgb3BlcmF0b3IsIHJlc3VsdCwgcmlnaHQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwYXJzZVByZWZpeCgpOiBBU1Qge1xuICAgIGlmICh0aGlzLm5leHQudHlwZSA9PSBUb2tlblR5cGUuT3BlcmF0b3IpIHtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLm5leHQuc3RyVmFsdWU7XG4gICAgICBsZXQgcmVzdWx0OiBBU1Q7XG4gICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgJysnOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VQcmVmaXgoKTtcbiAgICAgICAgICByZXR1cm4gVW5hcnkuY3JlYXRlUGx1cyh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCByZXN1bHQpO1xuICAgICAgICBjYXNlICctJzpcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICByZXN1bHQgPSB0aGlzLnBhcnNlUHJlZml4KCk7XG4gICAgICAgICAgcmV0dXJuIFVuYXJ5LmNyZWF0ZU1pbnVzKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlc3VsdCk7XG4gICAgICAgIGNhc2UgJyEnOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VQcmVmaXgoKTtcbiAgICAgICAgICByZXR1cm4gbmV3IFByZWZpeE5vdCh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCByZXN1bHQpO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gdGhpcy5wYXJzZUNhbGxDaGFpbigpO1xuICB9XG5cbiAgcGFyc2VDYWxsQ2hhaW4oKTogQVNUIHtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZVByaW1hcnkoKTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRQRVJJT0QpKSB7XG4gICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VBY2Nlc3NNZW1iZXJPck1ldGhvZENhbGwocmVzdWx0LCBzdGFydCwgZmFsc2UpO1xuXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJz8uJykpIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJExCUkFDS0VUKSA/XG4gICAgICAgICAgICB0aGlzLnBhcnNlS2V5ZWRSZWFkT3JXcml0ZShyZXN1bHQsIHN0YXJ0LCB0cnVlKSA6XG4gICAgICAgICAgICB0aGlzLnBhcnNlQWNjZXNzTWVtYmVyT3JNZXRob2RDYWxsKHJlc3VsdCwgc3RhcnQsIHRydWUpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kTEJSQUNLRVQpKSB7XG4gICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VLZXllZFJlYWRPcldyaXRlKHJlc3VsdCwgc3RhcnQsIGZhbHNlKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJExQQVJFTikpIHtcbiAgICAgICAgdGhpcy5ycGFyZW5zRXhwZWN0ZWQrKztcbiAgICAgICAgY29uc3QgYXJncyA9IHRoaXMucGFyc2VDYWxsQXJndW1lbnRzKCk7XG4gICAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XG4gICAgICAgIHRoaXMuZXhwZWN0Q2hhcmFjdGVyKGNoYXJzLiRSUEFSRU4pO1xuICAgICAgICByZXN1bHQgPSBuZXcgRnVuY3Rpb25DYWxsKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlc3VsdCwgYXJncyk7XG5cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignIScpKSB7XG4gICAgICAgIHJlc3VsdCA9IG5ldyBOb25OdWxsQXNzZXJ0KHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlc3VsdCk7XG5cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcGFyc2VQcmltYXJ5KCk6IEFTVCB7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRMUEFSRU4pKSB7XG4gICAgICB0aGlzLnJwYXJlbnNFeHBlY3RlZCsrO1xuICAgICAgY29uc3QgcmVzdWx0ID0gdGhpcy5wYXJzZVBpcGUoKTtcbiAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XG4gICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUlBBUkVOKTtcbiAgICAgIHJldHVybiByZXN1bHQ7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0tleXdvcmROdWxsKCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIG51bGwpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkVW5kZWZpbmVkKCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHZvaWQgMCk7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0tleXdvcmRUcnVlKCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHRydWUpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkRmFsc2UoKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbmV3IExpdGVyYWxQcmltaXRpdmUodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgZmFsc2UpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkVGhpcygpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiBuZXcgVGhpc1JlY2VpdmVyKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJExCUkFDS0VUKSkge1xuICAgICAgdGhpcy5yYnJhY2tldHNFeHBlY3RlZCsrO1xuICAgICAgY29uc3QgZWxlbWVudHMgPSB0aGlzLnBhcnNlRXhwcmVzc2lvbkxpc3QoY2hhcnMuJFJCUkFDS0VUKTtcbiAgICAgIHRoaXMucmJyYWNrZXRzRXhwZWN0ZWQtLTtcbiAgICAgIHRoaXMuZXhwZWN0Q2hhcmFjdGVyKGNoYXJzLiRSQlJBQ0tFVCk7XG4gICAgICByZXR1cm4gbmV3IExpdGVyYWxBcnJheSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBlbGVtZW50cyk7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0NoYXJhY3RlcihjaGFycy4kTEJSQUNFKSkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VMaXRlcmFsTWFwKCk7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0lkZW50aWZpZXIoKSkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VBY2Nlc3NNZW1iZXJPck1ldGhvZENhbGwoXG4gICAgICAgICAgbmV3IEltcGxpY2l0UmVjZWl2ZXIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSksIHN0YXJ0LCBmYWxzZSk7XG5cbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc051bWJlcigpKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRoaXMubmV4dC50b051bWJlcigpO1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbmV3IExpdGVyYWxQcmltaXRpdmUodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgdmFsdWUpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNTdHJpbmcoKSkge1xuICAgICAgY29uc3QgbGl0ZXJhbFZhbHVlID0gdGhpcy5uZXh0LnRvU3RyaW5nKCk7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiBuZXcgTGl0ZXJhbFByaW1pdGl2ZSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBsaXRlcmFsVmFsdWUpO1xuXG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNQcml2YXRlSWRlbnRpZmllcigpKSB7XG4gICAgICB0aGlzLl9yZXBvcnRFcnJvckZvclByaXZhdGVJZGVudGlmaWVyKHRoaXMubmV4dCwgbnVsbCk7XG4gICAgICByZXR1cm4gbmV3IEVtcHR5RXhwcih0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpKTtcblxuICAgIH0gZWxzZSBpZiAodGhpcy5pbmRleCA+PSB0aGlzLnRva2Vucy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuZXJyb3IoYFVuZXhwZWN0ZWQgZW5kIG9mIGV4cHJlc3Npb246ICR7dGhpcy5pbnB1dH1gKTtcbiAgICAgIHJldHVybiBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmVycm9yKGBVbmV4cGVjdGVkIHRva2VuICR7dGhpcy5uZXh0fWApO1xuICAgICAgcmV0dXJuIG5ldyBFbXB0eUV4cHIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSk7XG4gICAgfVxuICB9XG5cbiAgcGFyc2VFeHByZXNzaW9uTGlzdCh0ZXJtaW5hdG9yOiBudW1iZXIpOiBBU1RbXSB7XG4gICAgY29uc3QgcmVzdWx0OiBBU1RbXSA9IFtdO1xuXG4gICAgZG8ge1xuICAgICAgaWYgKCF0aGlzLm5leHQuaXNDaGFyYWN0ZXIodGVybWluYXRvcikpIHtcbiAgICAgICAgcmVzdWx0LnB1c2godGhpcy5wYXJzZVBpcGUoKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9IHdoaWxlICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpKTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcGFyc2VMaXRlcmFsTWFwKCk6IExpdGVyYWxNYXAge1xuICAgIGNvbnN0IGtleXM6IExpdGVyYWxNYXBLZXlbXSA9IFtdO1xuICAgIGNvbnN0IHZhbHVlczogQVNUW10gPSBbXTtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kTEJSQUNFKTtcbiAgICBpZiAoIXRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRSQlJBQ0UpKSB7XG4gICAgICB0aGlzLnJicmFjZXNFeHBlY3RlZCsrO1xuICAgICAgZG8ge1xuICAgICAgICBjb25zdCBrZXlTdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICAgICAgY29uc3QgcXVvdGVkID0gdGhpcy5uZXh0LmlzU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZXhwZWN0SWRlbnRpZmllck9yS2V5d29yZE9yU3RyaW5nKCk7XG4gICAgICAgIGtleXMucHVzaCh7a2V5LCBxdW90ZWR9KTtcblxuICAgICAgICAvLyBQcm9wZXJ0aWVzIHdpdGggcXVvdGVkIGtleXMgY2FuJ3QgdXNlIHRoZSBzaG9ydGhhbmQgc3ludGF4LlxuICAgICAgICBpZiAocXVvdGVkKSB7XG4gICAgICAgICAgdGhpcy5leHBlY3RDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKTtcbiAgICAgICAgICB2YWx1ZXMucHVzaCh0aGlzLnBhcnNlUGlwZSgpKTtcbiAgICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09MT04pKSB7XG4gICAgICAgICAgdmFsdWVzLnB1c2godGhpcy5wYXJzZVBpcGUoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3Qgc3BhbiA9IHRoaXMuc3BhbihrZXlTdGFydCk7XG4gICAgICAgICAgY29uc3Qgc291cmNlU3BhbiA9IHRoaXMuc291cmNlU3BhbihrZXlTdGFydCk7XG4gICAgICAgICAgdmFsdWVzLnB1c2gobmV3IFByb3BlcnR5UmVhZChcbiAgICAgICAgICAgICAgc3Bhbiwgc291cmNlU3Bhbiwgc291cmNlU3BhbiwgbmV3IEltcGxpY2l0UmVjZWl2ZXIoc3Bhbiwgc291cmNlU3BhbiksIGtleSkpO1xuICAgICAgICB9XG4gICAgICB9IHdoaWxlICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpKTtcbiAgICAgIHRoaXMucmJyYWNlc0V4cGVjdGVkLS07XG4gICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUkJSQUNFKTtcbiAgICB9XG4gICAgcmV0dXJuIG5ldyBMaXRlcmFsTWFwKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIGtleXMsIHZhbHVlcyk7XG4gIH1cblxuICBwYXJzZUFjY2Vzc01lbWJlck9yTWV0aG9kQ2FsbChyZWNlaXZlcjogQVNULCBzdGFydDogbnVtYmVyLCBpc1NhZmU6IGJvb2xlYW4pOiBBU1Qge1xuICAgIGNvbnN0IG5hbWVTdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBjb25zdCBpZCA9IHRoaXMud2l0aENvbnRleHQoUGFyc2VDb250ZXh0RmxhZ3MuV3JpdGFibGUsICgpID0+IHtcbiAgICAgIGNvbnN0IGlkID0gdGhpcy5leHBlY3RJZGVudGlmaWVyT3JLZXl3b3JkKCkgPz8gJyc7XG4gICAgICBpZiAoaWQubGVuZ3RoID09PSAwKSB7XG4gICAgICAgIHRoaXMuZXJyb3IoYEV4cGVjdGVkIGlkZW50aWZpZXIgZm9yIHByb3BlcnR5IGFjY2Vzc2AsIHJlY2VpdmVyLnNwYW4uZW5kKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBpZDtcbiAgICB9KTtcbiAgICBjb25zdCBuYW1lU3BhbiA9IHRoaXMuc291cmNlU3BhbihuYW1lU3RhcnQpO1xuXG4gICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRMUEFSRU4pKSB7XG4gICAgICBjb25zdCBhcmd1bWVudFN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgICAgdGhpcy5ycGFyZW5zRXhwZWN0ZWQrKztcbiAgICAgIGNvbnN0IGFyZ3MgPSB0aGlzLnBhcnNlQ2FsbEFyZ3VtZW50cygpO1xuICAgICAgY29uc3QgYXJndW1lbnRTcGFuID1cbiAgICAgICAgICB0aGlzLnNwYW4oYXJndW1lbnRTdGFydCwgdGhpcy5pbnB1dEluZGV4KS50b0Fic29sdXRlKHRoaXMuYWJzb2x1dGVPZmZzZXQpO1xuXG4gICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUlBBUkVOKTtcbiAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XG4gICAgICBjb25zdCBzcGFuID0gdGhpcy5zcGFuKHN0YXJ0KTtcbiAgICAgIGNvbnN0IHNvdXJjZVNwYW4gPSB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpO1xuICAgICAgcmV0dXJuIGlzU2FmZSA/XG4gICAgICAgICAgbmV3IFNhZmVNZXRob2RDYWxsKHNwYW4sIHNvdXJjZVNwYW4sIG5hbWVTcGFuLCByZWNlaXZlciwgaWQsIGFyZ3MsIGFyZ3VtZW50U3BhbikgOlxuICAgICAgICAgIG5ldyBNZXRob2RDYWxsKHNwYW4sIHNvdXJjZVNwYW4sIG5hbWVTcGFuLCByZWNlaXZlciwgaWQsIGFyZ3MsIGFyZ3VtZW50U3Bhbik7XG5cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGlzU2FmZSkge1xuICAgICAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignPScpKSB7XG4gICAgICAgICAgdGhpcy5lcnJvcignVGhlIFxcJz8uXFwnIG9wZXJhdG9yIGNhbm5vdCBiZSB1c2VkIGluIHRoZSBhc3NpZ25tZW50Jyk7XG4gICAgICAgICAgcmV0dXJuIG5ldyBFbXB0eUV4cHIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBTYWZlUHJvcGVydHlSZWFkKFxuICAgICAgICAgICAgICB0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBuYW1lU3BhbiwgcmVjZWl2ZXIsIGlkKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJz0nKSkge1xuICAgICAgICAgIGlmICghdGhpcy5wYXJzZUFjdGlvbikge1xuICAgICAgICAgICAgdGhpcy5lcnJvcignQmluZGluZ3MgY2Fubm90IGNvbnRhaW4gYXNzaWdubWVudHMnKTtcbiAgICAgICAgICAgIHJldHVybiBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5wYXJzZUNvbmRpdGlvbmFsKCk7XG4gICAgICAgICAgcmV0dXJuIG5ldyBQcm9wZXJ0eVdyaXRlKFxuICAgICAgICAgICAgICB0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBuYW1lU3BhbiwgcmVjZWl2ZXIsIGlkLCB2YWx1ZSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmV0dXJuIG5ldyBQcm9wZXJ0eVJlYWQodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgbmFtZVNwYW4sIHJlY2VpdmVyLCBpZCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBwYXJzZUNhbGxBcmd1bWVudHMoKTogQmluZGluZ1BpcGVbXSB7XG4gICAgaWYgKHRoaXMubmV4dC5pc0NoYXJhY3RlcihjaGFycy4kUlBBUkVOKSkgcmV0dXJuIFtdO1xuICAgIGNvbnN0IHBvc2l0aW9uYWxzOiBBU1RbXSA9IFtdO1xuICAgIGRvIHtcbiAgICAgIHBvc2l0aW9uYWxzLnB1c2godGhpcy5wYXJzZVBpcGUoKSk7XG4gICAgfSB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTU1BKSk7XG4gICAgcmV0dXJuIHBvc2l0aW9uYWxzIGFzIEJpbmRpbmdQaXBlW107XG4gIH1cblxuICAvKipcbiAgICogUGFyc2VzIGFuIGlkZW50aWZpZXIsIGEga2V5d29yZCwgYSBzdHJpbmcgd2l0aCBhbiBvcHRpb25hbCBgLWAgaW4gYmV0d2VlbixcbiAgICogYW5kIHJldHVybnMgdGhlIHN0cmluZyBhbG9uZyB3aXRoIGl0cyBhYnNvbHV0ZSBzb3VyY2Ugc3Bhbi5cbiAgICovXG4gIGV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpOiBUZW1wbGF0ZUJpbmRpbmdJZGVudGlmaWVyIHtcbiAgICBsZXQgcmVzdWx0ID0gJyc7XG4gICAgbGV0IG9wZXJhdG9yRm91bmQgPSBmYWxzZTtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0O1xuICAgIGRvIHtcbiAgICAgIHJlc3VsdCArPSB0aGlzLmV4cGVjdElkZW50aWZpZXJPcktleXdvcmRPclN0cmluZygpO1xuICAgICAgb3BlcmF0b3JGb3VuZCA9IHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJy0nKTtcbiAgICAgIGlmIChvcGVyYXRvckZvdW5kKSB7XG4gICAgICAgIHJlc3VsdCArPSAnLSc7XG4gICAgICB9XG4gICAgfSB3aGlsZSAob3BlcmF0b3JGb3VuZCk7XG4gICAgcmV0dXJuIHtcbiAgICAgIHNvdXJjZTogcmVzdWx0LFxuICAgICAgc3BhbjogbmV3IEFic29sdXRlU291cmNlU3BhbihzdGFydCwgc3RhcnQgKyByZXN1bHQubGVuZ3RoKSxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIG1pY3Jvc3ludGF4IHRlbXBsYXRlIGV4cHJlc3Npb24gYW5kIHJldHVybiBhIGxpc3Qgb2YgYmluZGluZ3Mgb3JcbiAgICogcGFyc2luZyBlcnJvcnMgaW4gY2FzZSB0aGUgZ2l2ZW4gZXhwcmVzc2lvbiBpcyBpbnZhbGlkLlxuICAgKlxuICAgKiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgPGRpdiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtczsgaW5kZXggYXMgaTsgdHJhY2tCeTogZnVuY1wiPlxuICAgKiBgYGBcbiAgICogY29udGFpbnMgZml2ZSBiaW5kaW5nczpcbiAgICogMS4gbmdGb3IgLT4gbnVsbFxuICAgKiAyLiBpdGVtIC0+IE5nRm9yT2ZDb250ZXh0LiRpbXBsaWNpdFxuICAgKiAzLiBuZ0Zvck9mIC0+IGl0ZW1zXG4gICAqIDQuIGkgLT4gTmdGb3JPZkNvbnRleHQuaW5kZXhcbiAgICogNS4gbmdGb3JUcmFja0J5IC0+IGZ1bmNcbiAgICpcbiAgICogRm9yIGEgZnVsbCBkZXNjcmlwdGlvbiBvZiB0aGUgbWljcm9zeW50YXggZ3JhbW1hciwgc2VlXG4gICAqIGh0dHBzOi8vZ2lzdC5naXRodWIuY29tL21oZXZlcnkvZDM1MzAyOTRjZmYyZTRhMWIzZmUxNWZmNzVkMDg4NTVcbiAgICpcbiAgICogQHBhcmFtIHRlbXBsYXRlS2V5IG5hbWUgb2YgdGhlIG1pY3Jvc3ludGF4IGRpcmVjdGl2ZSwgbGlrZSBuZ0lmLCBuZ0ZvcixcbiAgICogd2l0aG91dCB0aGUgKiwgYWxvbmcgd2l0aCBpdHMgYWJzb2x1dGUgc3Bhbi5cbiAgICovXG4gIHBhcnNlVGVtcGxhdGVCaW5kaW5ncyh0ZW1wbGF0ZUtleTogVGVtcGxhdGVCaW5kaW5nSWRlbnRpZmllcik6IFRlbXBsYXRlQmluZGluZ1BhcnNlUmVzdWx0IHtcbiAgICBjb25zdCBiaW5kaW5nczogVGVtcGxhdGVCaW5kaW5nW10gPSBbXTtcblxuICAgIC8vIFRoZSBmaXJzdCBiaW5kaW5nIGlzIGZvciB0aGUgdGVtcGxhdGUga2V5IGl0c2VsZlxuICAgIC8vIEluICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zXCIsIGtleSA9IFwibmdGb3JcIiwgdmFsdWUgPSBudWxsXG4gICAgLy8gSW4gKm5nSWY9XCJjb25kIHwgcGlwZVwiLCBrZXkgPSBcIm5nSWZcIiwgdmFsdWUgPSBcImNvbmQgfCBwaXBlXCJcbiAgICBiaW5kaW5ncy5wdXNoKC4uLnRoaXMucGFyc2VEaXJlY3RpdmVLZXl3b3JkQmluZGluZ3ModGVtcGxhdGVLZXkpKTtcblxuICAgIHdoaWxlICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICAvLyBJZiBpdCBzdGFydHMgd2l0aCAnbGV0JywgdGhlbiB0aGlzIG11c3QgYmUgdmFyaWFibGUgZGVjbGFyYXRpb25cbiAgICAgIGNvbnN0IGxldEJpbmRpbmcgPSB0aGlzLnBhcnNlTGV0QmluZGluZygpO1xuICAgICAgaWYgKGxldEJpbmRpbmcpIHtcbiAgICAgICAgYmluZGluZ3MucHVzaChsZXRCaW5kaW5nKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIFR3byBwb3NzaWJsZSBjYXNlcyBoZXJlLCBlaXRoZXIgYHZhbHVlIFwiYXNcIiBrZXlgIG9yXG4gICAgICAgIC8vIFwiZGlyZWN0aXZlLWtleXdvcmQgZXhwcmVzc2lvblwiLiBXZSBkb24ndCBrbm93IHdoaWNoIGNhc2UsIGJ1dCBib3RoXG4gICAgICAgIC8vIFwidmFsdWVcIiBhbmQgXCJkaXJlY3RpdmUta2V5d29yZFwiIGFyZSB0ZW1wbGF0ZSBiaW5kaW5nIGtleSwgc28gY29uc3VtZVxuICAgICAgICAvLyB0aGUga2V5IGZpcnN0LlxuICAgICAgICBjb25zdCBrZXkgPSB0aGlzLmV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpO1xuICAgICAgICAvLyBQZWVrIGF0IHRoZSBuZXh0IHRva2VuLCBpZiBpdCBpcyBcImFzXCIgdGhlbiB0aGlzIG11c3QgYmUgdmFyaWFibGVcbiAgICAgICAgLy8gZGVjbGFyYXRpb24uXG4gICAgICAgIGNvbnN0IGJpbmRpbmcgPSB0aGlzLnBhcnNlQXNCaW5kaW5nKGtleSk7XG4gICAgICAgIGlmIChiaW5kaW5nKSB7XG4gICAgICAgICAgYmluZGluZ3MucHVzaChiaW5kaW5nKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAvLyBPdGhlcndpc2UgdGhlIGtleSBtdXN0IGJlIGEgZGlyZWN0aXZlIGtleXdvcmQsIGxpa2UgXCJvZlwiLiBUcmFuc2Zvcm1cbiAgICAgICAgICAvLyB0aGUga2V5IHRvIGFjdHVhbCBrZXkuIEVnLiBvZiAtPiBuZ0Zvck9mLCB0cmFja0J5IC0+IG5nRm9yVHJhY2tCeVxuICAgICAgICAgIGtleS5zb3VyY2UgPVxuICAgICAgICAgICAgICB0ZW1wbGF0ZUtleS5zb3VyY2UgKyBrZXkuc291cmNlLmNoYXJBdCgwKS50b1VwcGVyQ2FzZSgpICsga2V5LnNvdXJjZS5zdWJzdHJpbmcoMSk7XG4gICAgICAgICAgYmluZGluZ3MucHVzaCguLi50aGlzLnBhcnNlRGlyZWN0aXZlS2V5d29yZEJpbmRpbmdzKGtleSkpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICB0aGlzLmNvbnN1bWVTdGF0ZW1lbnRUZXJtaW5hdG9yKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBUZW1wbGF0ZUJpbmRpbmdQYXJzZVJlc3VsdChiaW5kaW5ncywgW10gLyogd2FybmluZ3MgKi8sIHRoaXMuZXJyb3JzKTtcbiAgfVxuXG4gIHBhcnNlS2V5ZWRSZWFkT3JXcml0ZShyZWNlaXZlcjogQVNULCBzdGFydDogbnVtYmVyLCBpc1NhZmU6IGJvb2xlYW4pOiBBU1Qge1xuICAgIHJldHVybiB0aGlzLndpdGhDb250ZXh0KFBhcnNlQ29udGV4dEZsYWdzLldyaXRhYmxlLCAoKSA9PiB7XG4gICAgICB0aGlzLnJicmFja2V0c0V4cGVjdGVkKys7XG4gICAgICBjb25zdCBrZXkgPSB0aGlzLnBhcnNlUGlwZSgpO1xuICAgICAgaWYgKGtleSBpbnN0YW5jZW9mIEVtcHR5RXhwcikge1xuICAgICAgICB0aGlzLmVycm9yKGBLZXkgYWNjZXNzIGNhbm5vdCBiZSBlbXB0eWApO1xuICAgICAgfVxuICAgICAgdGhpcy5yYnJhY2tldHNFeHBlY3RlZC0tO1xuICAgICAgdGhpcy5leHBlY3RDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDS0VUKTtcbiAgICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCc9JykpIHtcbiAgICAgICAgaWYgKGlzU2FmZSkge1xuICAgICAgICAgIHRoaXMuZXJyb3IoJ1RoZSBcXCc/LlxcJyBvcGVyYXRvciBjYW5ub3QgYmUgdXNlZCBpbiB0aGUgYXNzaWdubWVudCcpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5wYXJzZUNvbmRpdGlvbmFsKCk7XG4gICAgICAgICAgcmV0dXJuIG5ldyBLZXllZFdyaXRlKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlY2VpdmVyLCBrZXksIHZhbHVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGlzU2FmZSA/IG5ldyBTYWZlS2V5ZWRSZWFkKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIHJlY2VpdmVyLCBrZXkpIDpcbiAgICAgICAgICAgICAgICAgICAgICAgIG5ldyBLZXllZFJlYWQodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgcmVjZWl2ZXIsIGtleSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIFBhcnNlIGEgZGlyZWN0aXZlIGtleXdvcmQsIGZvbGxvd2VkIGJ5IGEgbWFuZGF0b3J5IGV4cHJlc3Npb24uXG4gICAqIEZvciBleGFtcGxlLCBcIm9mIGl0ZW1zXCIsIFwidHJhY2tCeTogZnVuY1wiLlxuICAgKiBUaGUgYmluZGluZ3MgYXJlOiBuZ0Zvck9mIC0+IGl0ZW1zLCBuZ0ZvclRyYWNrQnkgLT4gZnVuY1xuICAgKiBUaGVyZSBjb3VsZCBiZSBhbiBvcHRpb25hbCBcImFzXCIgYmluZGluZyB0aGF0IGZvbGxvd3MgdGhlIGV4cHJlc3Npb24uXG4gICAqIEZvciBleGFtcGxlLFxuICAgKiBgYGBcbiAgICogICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtcyB8IHNsaWNlOjA6MSBhcyBjb2xsZWN0aW9uXCIuXG4gICAqICAgICAgICAgICAgICAgICAgICBeXiBeXl5eXl5eXl5eXl5eXl5eXiBeXl5eXl5eXl5eXl5eXG4gICAqICAgICAgICAgICAgICAga2V5d29yZCAgICBib3VuZCB0YXJnZXQgICBvcHRpb25hbCAnYXMnIGJpbmRpbmdcbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSBrZXkgYmluZGluZyBrZXksIGZvciBleGFtcGxlLCBuZ0ZvciwgbmdJZiwgbmdGb3JPZiwgYWxvbmcgd2l0aCBpdHNcbiAgICogYWJzb2x1dGUgc3Bhbi5cbiAgICovXG4gIHByaXZhdGUgcGFyc2VEaXJlY3RpdmVLZXl3b3JkQmluZGluZ3Moa2V5OiBUZW1wbGF0ZUJpbmRpbmdJZGVudGlmaWVyKTogVGVtcGxhdGVCaW5kaW5nW10ge1xuICAgIGNvbnN0IGJpbmRpbmdzOiBUZW1wbGF0ZUJpbmRpbmdbXSA9IFtdO1xuICAgIHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRDT0xPTik7ICAvLyB0cmFja0J5OiB0cmFja0J5RnVuY3Rpb25cbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0RGlyZWN0aXZlQm91bmRUYXJnZXQoKTtcbiAgICBsZXQgc3BhbkVuZCA9IHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0O1xuICAgIC8vIFRoZSBiaW5kaW5nIGNvdWxkIG9wdGlvbmFsbHkgYmUgZm9sbG93ZWQgYnkgXCJhc1wiLiBGb3IgZXhhbXBsZSxcbiAgICAvLyAqbmdJZj1cImNvbmQgfCBwaXBlIGFzIHhcIi4gSW4gdGhpcyBjYXNlLCB0aGUga2V5IGluIHRoZSBcImFzXCIgYmluZGluZ1xuICAgIC8vIGlzIFwieFwiIGFuZCB0aGUgdmFsdWUgaXMgdGhlIHRlbXBsYXRlIGtleSBpdHNlbGYgKFwibmdJZlwiKS4gTm90ZSB0aGF0IHRoZVxuICAgIC8vICdrZXknIGluIHRoZSBjdXJyZW50IGNvbnRleHQgbm93IGJlY29tZXMgdGhlIFwidmFsdWVcIiBpbiB0aGUgbmV4dCBiaW5kaW5nLlxuICAgIGNvbnN0IGFzQmluZGluZyA9IHRoaXMucGFyc2VBc0JpbmRpbmcoa2V5KTtcbiAgICBpZiAoIWFzQmluZGluZykge1xuICAgICAgdGhpcy5jb25zdW1lU3RhdGVtZW50VGVybWluYXRvcigpO1xuICAgICAgc3BhbkVuZCA9IHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0O1xuICAgIH1cbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IEFic29sdXRlU291cmNlU3BhbihrZXkuc3Bhbi5zdGFydCwgc3BhbkVuZCk7XG4gICAgYmluZGluZ3MucHVzaChuZXcgRXhwcmVzc2lvbkJpbmRpbmcoc291cmNlU3Bhbiwga2V5LCB2YWx1ZSkpO1xuICAgIGlmIChhc0JpbmRpbmcpIHtcbiAgICAgIGJpbmRpbmdzLnB1c2goYXNCaW5kaW5nKTtcbiAgICB9XG4gICAgcmV0dXJuIGJpbmRpbmdzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgZXhwcmVzc2lvbiBBU1QgZm9yIHRoZSBib3VuZCB0YXJnZXQgb2YgYSBkaXJlY3RpdmUga2V5d29yZFxuICAgKiBiaW5kaW5nLiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgKm5nSWY9XCJjb25kaXRpb24gfCBwaXBlXCJcbiAgICogICAgICAgICAgXl5eXl5eXl5eXl5eXl5eXiBib3VuZCB0YXJnZXQgZm9yIFwibmdJZlwiXG4gICAqICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXNcIlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgXl5eXl4gYm91bmQgdGFyZ2V0IGZvciBcIm5nRm9yT2ZcIlxuICAgKiBgYGBcbiAgICovXG4gIHByaXZhdGUgZ2V0RGlyZWN0aXZlQm91bmRUYXJnZXQoKTogQVNUV2l0aFNvdXJjZXxudWxsIHtcbiAgICBpZiAodGhpcy5uZXh0ID09PSBFT0YgfHwgdGhpcy5wZWVrS2V5d29yZEFzKCkgfHwgdGhpcy5wZWVrS2V5d29yZExldCgpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgYXN0ID0gdGhpcy5wYXJzZVBpcGUoKTsgIC8vIGV4YW1wbGU6IFwiY29uZGl0aW9uIHwgYXN5bmNcIlxuICAgIGNvbnN0IHtzdGFydCwgZW5kfSA9IGFzdC5zcGFuO1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5pbnB1dC5zdWJzdHJpbmcoc3RhcnQsIGVuZCk7XG4gICAgcmV0dXJuIG5ldyBBU1RXaXRoU291cmNlKGFzdCwgdmFsdWUsIHRoaXMubG9jYXRpb24sIHRoaXMuYWJzb2x1dGVPZmZzZXQgKyBzdGFydCwgdGhpcy5lcnJvcnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybiB0aGUgYmluZGluZyBmb3IgYSB2YXJpYWJsZSBkZWNsYXJlZCB1c2luZyBgYXNgLiBOb3RlIHRoYXQgdGhlIG9yZGVyXG4gICAqIG9mIHRoZSBrZXktdmFsdWUgcGFpciBpbiB0aGlzIGRlY2xhcmF0aW9uIGlzIHJldmVyc2VkLiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXM7IGluZGV4IGFzIGlcIlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF5eXl5eICAgIF5cbiAgICogICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZSAgICBrZXlcbiAgICogYGBgXG4gICAqXG4gICAqIEBwYXJhbSB2YWx1ZSBuYW1lIG9mIHRoZSB2YWx1ZSBpbiB0aGUgZGVjbGFyYXRpb24sIFwibmdJZlwiIGluIHRoZSBleGFtcGxlXG4gICAqIGFib3ZlLCBhbG9uZyB3aXRoIGl0cyBhYnNvbHV0ZSBzcGFuLlxuICAgKi9cbiAgcHJpdmF0ZSBwYXJzZUFzQmluZGluZyh2YWx1ZTogVGVtcGxhdGVCaW5kaW5nSWRlbnRpZmllcik6IFRlbXBsYXRlQmluZGluZ3xudWxsIHtcbiAgICBpZiAoIXRoaXMucGVla0tleXdvcmRBcygpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5hZHZhbmNlKCk7ICAvLyBjb25zdW1lIHRoZSAnYXMnIGtleXdvcmRcbiAgICBjb25zdCBrZXkgPSB0aGlzLmV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpO1xuICAgIHRoaXMuY29uc3VtZVN0YXRlbWVudFRlcm1pbmF0b3IoKTtcbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IEFic29sdXRlU291cmNlU3Bhbih2YWx1ZS5zcGFuLnN0YXJ0LCB0aGlzLmN1cnJlbnRBYnNvbHV0ZU9mZnNldCk7XG4gICAgcmV0dXJuIG5ldyBWYXJpYWJsZUJpbmRpbmcoc291cmNlU3Bhbiwga2V5LCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBiaW5kaW5nIGZvciBhIHZhcmlhYmxlIGRlY2xhcmVkIHVzaW5nIGBsZXRgLiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXM7IGxldCBpPWluZGV4O1wiXG4gICAqICAgICAgICAgICBeXl5eXl5eXiAgICAgICAgICAgXl5eXl5eXl5eXl5cbiAgICogYGBgXG4gICAqIEluIHRoZSBmaXJzdCBiaW5kaW5nLCBgaXRlbWAgaXMgYm91bmQgdG8gYE5nRm9yT2ZDb250ZXh0LiRpbXBsaWNpdGAuXG4gICAqIEluIHRoZSBzZWNvbmQgYmluZGluZywgYGlgIGlzIGJvdW5kIHRvIGBOZ0Zvck9mQ29udGV4dC5pbmRleGAuXG4gICAqL1xuICBwcml2YXRlIHBhcnNlTGV0QmluZGluZygpOiBUZW1wbGF0ZUJpbmRpbmd8bnVsbCB7XG4gICAgaWYgKCF0aGlzLnBlZWtLZXl3b3JkTGV0KCkpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cbiAgICBjb25zdCBzcGFuU3RhcnQgPSB0aGlzLmN1cnJlbnRBYnNvbHV0ZU9mZnNldDtcbiAgICB0aGlzLmFkdmFuY2UoKTsgIC8vIGNvbnN1bWUgdGhlICdsZXQnIGtleXdvcmRcbiAgICBjb25zdCBrZXkgPSB0aGlzLmV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpO1xuICAgIGxldCB2YWx1ZTogVGVtcGxhdGVCaW5kaW5nSWRlbnRpZmllcnxudWxsID0gbnVsbDtcbiAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignPScpKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMuZXhwZWN0VGVtcGxhdGVCaW5kaW5nS2V5KCk7XG4gICAgfVxuICAgIHRoaXMuY29uc3VtZVN0YXRlbWVudFRlcm1pbmF0b3IoKTtcbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IEFic29sdXRlU291cmNlU3BhbihzcGFuU3RhcnQsIHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0KTtcbiAgICByZXR1cm4gbmV3IFZhcmlhYmxlQmluZGluZyhzb3VyY2VTcGFuLCBrZXksIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdW1lIHRoZSBvcHRpb25hbCBzdGF0ZW1lbnQgdGVybWluYXRvcjogc2VtaWNvbG9uIG9yIGNvbW1hLlxuICAgKi9cbiAgcHJpdmF0ZSBjb25zdW1lU3RhdGVtZW50VGVybWluYXRvcigpIHtcbiAgICB0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSB8fCB0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZHMgYW4gZXJyb3IgYW5kIHNraXBzIG92ZXIgdGhlIHRva2VuIHN0cmVhbSB1bnRpbCByZWFjaGluZyBhIHJlY292ZXJhYmxlIHBvaW50LiBTZWVcbiAgICogYHRoaXMuc2tpcGAgZm9yIG1vcmUgZGV0YWlscyBvbiB0b2tlbiBza2lwcGluZy5cbiAgICovXG4gIGVycm9yKG1lc3NhZ2U6IHN0cmluZywgaW5kZXg6IG51bWJlcnxudWxsID0gbnVsbCkge1xuICAgIHRoaXMuZXJyb3JzLnB1c2gobmV3IFBhcnNlckVycm9yKG1lc3NhZ2UsIHRoaXMuaW5wdXQsIHRoaXMubG9jYXRpb25UZXh0KGluZGV4KSwgdGhpcy5sb2NhdGlvbikpO1xuICAgIHRoaXMuc2tpcCgpO1xuICB9XG5cbiAgcHJpdmF0ZSBsb2NhdGlvblRleHQoaW5kZXg6IG51bWJlcnxudWxsID0gbnVsbCkge1xuICAgIGlmIChpbmRleCA9PSBudWxsKSBpbmRleCA9IHRoaXMuaW5kZXg7XG4gICAgcmV0dXJuIChpbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCkgPyBgYXQgY29sdW1uICR7dGhpcy50b2tlbnNbaW5kZXhdLmluZGV4ICsgMX0gaW5gIDpcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGBhdCB0aGUgZW5kIG9mIHRoZSBleHByZXNzaW9uYDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWNvcmRzIGFuIGVycm9yIGZvciBhbiB1bmV4cGVjdGVkIHByaXZhdGUgaWRlbnRpZmllciBiZWluZyBkaXNjb3ZlcmVkLlxuICAgKiBAcGFyYW0gdG9rZW4gVG9rZW4gcmVwcmVzZW50aW5nIGEgcHJpdmF0ZSBpZGVudGlmaWVyLlxuICAgKiBAcGFyYW0gZXh0cmFNZXNzYWdlIE9wdGlvbmFsIGFkZGl0aW9uYWwgbWVzc2FnZSBiZWluZyBhcHBlbmRlZCB0byB0aGUgZXJyb3IuXG4gICAqL1xuICBwcml2YXRlIF9yZXBvcnRFcnJvckZvclByaXZhdGVJZGVudGlmaWVyKHRva2VuOiBUb2tlbiwgZXh0cmFNZXNzYWdlOiBzdHJpbmd8bnVsbCkge1xuICAgIGxldCBlcnJvck1lc3NhZ2UgPVxuICAgICAgICBgUHJpdmF0ZSBpZGVudGlmaWVycyBhcmUgbm90IHN1cHBvcnRlZC4gVW5leHBlY3RlZCBwcml2YXRlIGlkZW50aWZpZXI6ICR7dG9rZW59YDtcbiAgICBpZiAoZXh0cmFNZXNzYWdlICE9PSBudWxsKSB7XG4gICAgICBlcnJvck1lc3NhZ2UgKz0gYCwgJHtleHRyYU1lc3NhZ2V9YDtcbiAgICB9XG4gICAgdGhpcy5lcnJvcihlcnJvck1lc3NhZ2UpO1xuICB9XG5cbiAgLyoqXG4gICAqIEVycm9yIHJlY292ZXJ5IHNob3VsZCBza2lwIHRva2VucyB1bnRpbCBpdCBlbmNvdW50ZXJzIGEgcmVjb3ZlcnkgcG9pbnQuXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgYXJlIHRyZWF0ZWQgYXMgdW5jb25kaXRpb25hbCByZWNvdmVyeSBwb2ludHM6XG4gICAqICAgLSBlbmQgb2YgaW5wdXRcbiAgICogICAtICc7JyAocGFyc2VDaGFpbigpIGlzIGFsd2F5cyB0aGUgcm9vdCBwcm9kdWN0aW9uLCBhbmQgaXQgZXhwZWN0cyBhICc7JylcbiAgICogICAtICd8JyAoc2luY2UgcGlwZXMgbWF5IGJlIGNoYWluZWQgYW5kIGVhY2ggcGlwZSBleHByZXNzaW9uIG1heSBiZSB0cmVhdGVkIGluZGVwZW5kZW50bHkpXG4gICAqXG4gICAqIFRoZSBmb2xsb3dpbmcgYXJlIGNvbmRpdGlvbmFsIHJlY292ZXJ5IHBvaW50czpcbiAgICogICAtICcpJywgJ30nLCAnXScgaWYgb25lIG9mIGNhbGxpbmcgcHJvZHVjdGlvbnMgaXMgZXhwZWN0aW5nIG9uZSBvZiB0aGVzZSBzeW1ib2xzXG4gICAqICAgICAtIFRoaXMgYWxsb3dzIHNraXAoKSB0byByZWNvdmVyIGZyb20gZXJyb3JzIHN1Y2ggYXMgJyhhLikgKyAxJyBhbGxvd2luZyBtb3JlIG9mIHRoZSBBU1QgdG9cbiAgICogICAgICAgYmUgcmV0YWluZWQgKGl0IGRvZXNuJ3Qgc2tpcCBhbnkgdG9rZW5zIGFzIHRoZSAnKScgaXMgcmV0YWluZWQgYmVjYXVzZSBvZiB0aGUgJygnIGJlZ2luc1xuICAgKiAgICAgICBhbiAnKCcgPGV4cHI+ICcpJyBwcm9kdWN0aW9uKS5cbiAgICogICAgICAgVGhlIHJlY292ZXJ5IHBvaW50cyBvZiBncm91cGluZyBzeW1ib2xzIG11c3QgYmUgY29uZGl0aW9uYWwgYXMgdGhleSBtdXN0IGJlIHNraXBwZWQgaWZcbiAgICogICAgICAgbm9uZSBvZiB0aGUgY2FsbGluZyBwcm9kdWN0aW9ucyBhcmUgbm90IGV4cGVjdGluZyB0aGUgY2xvc2luZyB0b2tlbiBlbHNlIHdlIHdpbGwgbmV2ZXJcbiAgICogICAgICAgbWFrZSBwcm9ncmVzcyBpbiB0aGUgY2FzZSBvZiBhbiBleHRyYW5lb3VzIGdyb3VwIGNsb3Npbmcgc3ltYm9sIChzdWNoIGFzIGEgc3RyYXkgJyknKS5cbiAgICogICAgICAgVGhhdCBpcywgd2Ugc2tpcCBhIGNsb3Npbmcgc3ltYm9sIGlmIHdlIGFyZSBub3QgaW4gYSBncm91cGluZyBwcm9kdWN0aW9uLlxuICAgKiAgIC0gJz0nIGluIGEgYFdyaXRhYmxlYCBjb250ZXh0XG4gICAqICAgICAtIEluIHRoaXMgY29udGV4dCwgd2UgYXJlIGFibGUgdG8gcmVjb3ZlciBhZnRlciBzZWVpbmcgdGhlIGA9YCBvcGVyYXRvciwgd2hpY2hcbiAgICogICAgICAgc2lnbmFscyB0aGUgcHJlc2VuY2Ugb2YgYW4gaW5kZXBlbmRlbnQgcnZhbHVlIGV4cHJlc3Npb24gZm9sbG93aW5nIHRoZSBgPWAgb3BlcmF0b3IuXG4gICAqXG4gICAqIElmIGEgcHJvZHVjdGlvbiBleHBlY3RzIG9uZSBvZiB0aGVzZSB0b2tlbiBpdCBpbmNyZW1lbnRzIHRoZSBjb3JyZXNwb25kaW5nIG5lc3RpbmcgY291bnQsXG4gICAqIGFuZCB0aGVuIGRlY3JlbWVudHMgaXQganVzdCBwcmlvciB0byBjaGVja2luZyBpZiB0aGUgdG9rZW4gaXMgaW4gdGhlIGlucHV0LlxuICAgKi9cbiAgcHJpdmF0ZSBza2lwKCkge1xuICAgIGxldCBuID0gdGhpcy5uZXh0O1xuICAgIHdoaWxlICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoICYmICFuLmlzQ2hhcmFjdGVyKGNoYXJzLiRTRU1JQ09MT04pICYmXG4gICAgICAgICAgICFuLmlzT3BlcmF0b3IoJ3wnKSAmJiAodGhpcy5ycGFyZW5zRXhwZWN0ZWQgPD0gMCB8fCAhbi5pc0NoYXJhY3RlcihjaGFycy4kUlBBUkVOKSkgJiZcbiAgICAgICAgICAgKHRoaXMucmJyYWNlc0V4cGVjdGVkIDw9IDAgfHwgIW4uaXNDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDRSkpICYmXG4gICAgICAgICAgICh0aGlzLnJicmFja2V0c0V4cGVjdGVkIDw9IDAgfHwgIW4uaXNDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDS0VUKSkgJiZcbiAgICAgICAgICAgKCEodGhpcy5jb250ZXh0ICYgUGFyc2VDb250ZXh0RmxhZ3MuV3JpdGFibGUpIHx8ICFuLmlzT3BlcmF0b3IoJz0nKSkpIHtcbiAgICAgIGlmICh0aGlzLm5leHQuaXNFcnJvcigpKSB7XG4gICAgICAgIHRoaXMuZXJyb3JzLnB1c2goXG4gICAgICAgICAgICBuZXcgUGFyc2VyRXJyb3IodGhpcy5uZXh0LnRvU3RyaW5nKCkhLCB0aGlzLmlucHV0LCB0aGlzLmxvY2F0aW9uVGV4dCgpLCB0aGlzLmxvY2F0aW9uKSk7XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIG4gPSB0aGlzLm5leHQ7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIFNpbXBsZUV4cHJlc3Npb25DaGVja2VyIGltcGxlbWVudHMgQXN0VmlzaXRvciB7XG4gIGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICB2aXNpdEltcGxpY2l0UmVjZWl2ZXIoYXN0OiBJbXBsaWNpdFJlY2VpdmVyLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRUaGlzUmVjZWl2ZXIoYXN0OiBUaGlzUmVjZWl2ZXIsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdEludGVycG9sYXRpb24oYXN0OiBJbnRlcnBvbGF0aW9uLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRMaXRlcmFsUHJpbWl0aXZlKGFzdDogTGl0ZXJhbFByaW1pdGl2ZSwgY29udGV4dDogYW55KSB7fVxuXG4gIHZpc2l0UHJvcGVydHlSZWFkKGFzdDogUHJvcGVydHlSZWFkLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRQcm9wZXJ0eVdyaXRlKGFzdDogUHJvcGVydHlXcml0ZSwgY29udGV4dDogYW55KSB7fVxuXG4gIHZpc2l0U2FmZVByb3BlcnR5UmVhZChhc3Q6IFNhZmVQcm9wZXJ0eVJlYWQsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdE1ldGhvZENhbGwoYXN0OiBNZXRob2RDYWxsLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRTYWZlTWV0aG9kQ2FsbChhc3Q6IFNhZmVNZXRob2RDYWxsLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRGdW5jdGlvbkNhbGwoYXN0OiBGdW5jdGlvbkNhbGwsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdExpdGVyYWxBcnJheShhc3Q6IExpdGVyYWxBcnJheSwgY29udGV4dDogYW55KSB7XG4gICAgdGhpcy52aXNpdEFsbChhc3QuZXhwcmVzc2lvbnMsIGNvbnRleHQpO1xuICB9XG5cbiAgdmlzaXRMaXRlcmFsTWFwKGFzdDogTGl0ZXJhbE1hcCwgY29udGV4dDogYW55KSB7XG4gICAgdGhpcy52aXNpdEFsbChhc3QudmFsdWVzLCBjb250ZXh0KTtcbiAgfVxuXG4gIHZpc2l0VW5hcnkoYXN0OiBVbmFyeSwgY29udGV4dDogYW55KSB7fVxuXG4gIHZpc2l0QmluYXJ5KGFzdDogQmluYXJ5LCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRQcmVmaXhOb3QoYXN0OiBQcmVmaXhOb3QsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdE5vbk51bGxBc3NlcnQoYXN0OiBOb25OdWxsQXNzZXJ0LCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRDb25kaXRpb25hbChhc3Q6IENvbmRpdGlvbmFsLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRQaXBlKGFzdDogQmluZGluZ1BpcGUsIGNvbnRleHQ6IGFueSkge1xuICAgIHRoaXMuZXJyb3JzLnB1c2goJ3BpcGVzJyk7XG4gIH1cblxuICB2aXNpdEtleWVkUmVhZChhc3Q6IEtleWVkUmVhZCwgY29udGV4dDogYW55KSB7fVxuXG4gIHZpc2l0S2V5ZWRXcml0ZShhc3Q6IEtleWVkV3JpdGUsIGNvbnRleHQ6IGFueSkge31cblxuICB2aXNpdEFsbChhc3RzOiBhbnlbXSwgY29udGV4dDogYW55KTogYW55W10ge1xuICAgIHJldHVybiBhc3RzLm1hcChub2RlID0+IG5vZGUudmlzaXQodGhpcywgY29udGV4dCkpO1xuICB9XG5cbiAgdmlzaXRDaGFpbihhc3Q6IENoYWluLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRRdW90ZShhc3Q6IFF1b3RlLCBjb250ZXh0OiBhbnkpIHt9XG5cbiAgdmlzaXRTYWZlS2V5ZWRSZWFkKGFzdDogU2FmZUtleWVkUmVhZCwgY29udGV4dDogYW55KSB7fVxufVxuXG4vKipcbiAqIFRoaXMgY2xhc3MgaW1wbGVtZW50cyBTaW1wbGVFeHByZXNzaW9uQ2hlY2tlciB1c2VkIGluIFZpZXcgRW5naW5lIGFuZCBwZXJmb3JtcyBtb3JlIHN0cmljdCBjaGVja3NcbiAqIHRvIG1ha2Ugc3VyZSBob3N0IGJpbmRpbmdzIGRvIG5vdCBjb250YWluIHBpcGVzLiBJbiBWaWV3IEVuZ2luZSwgaGF2aW5nIHBpcGVzIGluIGhvc3QgYmluZGluZ3MgaXNcbiAqIG5vdCBzdXBwb3J0ZWQgYXMgd2VsbCwgYnV0IGluIHNvbWUgY2FzZXMgKGxpa2UgYCEodmFsdWUgfCBhc3luYylgKSB0aGUgZXJyb3IgaXMgbm90IHRyaWdnZXJlZCBhdFxuICogY29tcGlsZSB0aW1lLiBJbiBvcmRlciB0byBwcmVzZXJ2ZSBWaWV3IEVuZ2luZSBiZWhhdmlvciwgbW9yZSBzdHJpY3QgY2hlY2tzIGFyZSBpbnRyb2R1Y2VkIGZvclxuICogSXZ5IG1vZGUgb25seS5cbiAqL1xuY2xhc3MgSXZ5U2ltcGxlRXhwcmVzc2lvbkNoZWNrZXIgZXh0ZW5kcyBSZWN1cnNpdmVBc3RWaXNpdG9yIGltcGxlbWVudHMgU2ltcGxlRXhwcmVzc2lvbkNoZWNrZXIge1xuICBlcnJvcnM6IHN0cmluZ1tdID0gW107XG5cbiAgb3ZlcnJpZGUgdmlzaXRQaXBlKCkge1xuICAgIHRoaXMuZXJyb3JzLnB1c2goJ3BpcGVzJyk7XG4gIH1cbn1cbiJdfQ== |
---|