@angular/compiler 16.2.0-next.2 → 16.2.0-next.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/src/compiler.mjs +3 -3
- package/esm2022/src/jit_compiler_facade.mjs +6 -2
- package/esm2022/src/ml_parser/lexer.mjs +14 -3
- package/esm2022/src/output/abstract_emitter.mjs +4 -1
- package/esm2022/src/output/output_ast.mjs +22 -1
- package/esm2022/src/render3/partial/class_metadata.mjs +1 -1
- package/esm2022/src/render3/partial/directive.mjs +1 -1
- package/esm2022/src/render3/partial/factory.mjs +1 -1
- package/esm2022/src/render3/partial/injectable.mjs +1 -1
- package/esm2022/src/render3/partial/injector.mjs +1 -1
- package/esm2022/src/render3/partial/ng_module.mjs +1 -1
- package/esm2022/src/render3/partial/pipe.mjs +1 -1
- package/esm2022/src/render3/r3_ast.mjs +109 -1
- package/esm2022/src/render3/r3_deferred_blocks.mjs +156 -0
- package/esm2022/src/render3/r3_deferred_triggers.mjs +275 -0
- package/esm2022/src/render3/r3_template_transform.mjs +40 -12
- package/esm2022/src/render3/view/t2_binder.mjs +61 -6
- package/esm2022/src/render3/view/template.mjs +17 -3
- package/esm2022/src/template/pipeline/ir/src/enums.mjs +21 -9
- package/esm2022/src/template/pipeline/ir/src/expression.mjs +4 -1
- package/esm2022/src/template/pipeline/ir/src/ops/update.mjs +42 -1
- package/esm2022/src/template/pipeline/src/emit.mjs +8 -6
- package/esm2022/src/template/pipeline/src/ingest.mjs +25 -3
- package/esm2022/src/template/pipeline/src/instruction.mjs +35 -8
- package/esm2022/src/template/pipeline/src/phases/attribute_extraction.mjs +2 -1
- package/esm2022/src/template/pipeline/src/phases/chaining.mjs +11 -1
- package/esm2022/src/template/pipeline/src/phases/naming.mjs +38 -9
- package/esm2022/src/template/pipeline/src/phases/property_ordering.mjs +82 -0
- package/esm2022/src/template/pipeline/src/phases/reify.mjs +10 -1
- package/esm2022/src/template/pipeline/src/phases/var_counting.mjs +13 -8
- package/esm2022/src/template_parser/binding_parser.mjs +4 -4
- package/esm2022/src/util.mjs +2 -8
- package/esm2022/src/version.mjs +1 -1
- package/fesm2022/compiler.mjs +1335 -456
- package/fesm2022/compiler.mjs.map +1 -1
- package/fesm2022/testing.mjs +1 -1
- package/index.d.ts +120 -2
- package/package.json +2 -2
- package/testing/index.d.ts +1 -1
|
@@ -0,0 +1,275 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* @license
|
|
3
|
+
* Copyright Google LLC All Rights Reserved.
|
|
4
|
+
*
|
|
5
|
+
* Use of this source code is governed by an MIT-style license that can be
|
|
6
|
+
* found in the LICENSE file at https://angular.io/license
|
|
7
|
+
*/
|
|
8
|
+
import * as chars from '../chars';
|
|
9
|
+
import { Lexer, TokenType } from '../expression_parser/lexer';
|
|
10
|
+
import { ParseError, ParseSourceSpan } from '../parse_util';
|
|
11
|
+
import * as t from './r3_ast';
|
|
12
|
+
/** Pattern for a timing value in a trigger. */
|
|
13
|
+
const TIME_PATTERN = /^\d+(ms|s)?$/;
|
|
14
|
+
/** Pattern for a separator between keywords in a trigger expression. */
|
|
15
|
+
const SEPARATOR_PATTERN = /^\s$/;
|
|
16
|
+
/** Pairs of characters that form syntax that is comma-delimited. */
|
|
17
|
+
const COMMA_DELIMITED_SYNTAX = new Map([
|
|
18
|
+
[chars.$LBRACE, chars.$RBRACE],
|
|
19
|
+
[chars.$LBRACKET, chars.$RBRACKET],
|
|
20
|
+
[chars.$LPAREN, chars.$RPAREN], // Function calls
|
|
21
|
+
]);
|
|
22
|
+
/** Possible types of `on` triggers. */
|
|
23
|
+
var OnTriggerType;
|
|
24
|
+
(function (OnTriggerType) {
|
|
25
|
+
OnTriggerType["IDLE"] = "idle";
|
|
26
|
+
OnTriggerType["TIMER"] = "timer";
|
|
27
|
+
OnTriggerType["INTERACTION"] = "interaction";
|
|
28
|
+
OnTriggerType["IMMEDIATE"] = "immediate";
|
|
29
|
+
OnTriggerType["HOVER"] = "hover";
|
|
30
|
+
OnTriggerType["VIEWPORT"] = "viewport";
|
|
31
|
+
})(OnTriggerType || (OnTriggerType = {}));
|
|
32
|
+
/** Parses a `when` deferred trigger. */
|
|
33
|
+
export function parseWhenTrigger({ expression, sourceSpan }, bindingParser, errors) {
|
|
34
|
+
const whenIndex = expression.indexOf('when');
|
|
35
|
+
// This is here just to be safe, we shouldn't enter this function
|
|
36
|
+
// in the first place if a block doesn't have the "when" keyword.
|
|
37
|
+
if (whenIndex === -1) {
|
|
38
|
+
errors.push(new ParseError(sourceSpan, `Could not find "when" keyword in expression`));
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
const start = getTriggerParametersStart(expression, whenIndex + 1);
|
|
42
|
+
const parsed = bindingParser.parseBinding(expression.slice(start), false, sourceSpan, sourceSpan.start.offset + start);
|
|
43
|
+
return new t.BoundDeferredTrigger(parsed, sourceSpan);
|
|
44
|
+
}
|
|
45
|
+
/** Parses an `on` trigger */
|
|
46
|
+
export function parseOnTrigger({ expression, sourceSpan }, errors) {
|
|
47
|
+
const onIndex = expression.indexOf('on');
|
|
48
|
+
// This is here just to be safe, we shouldn't enter this function
|
|
49
|
+
// in the first place if a block doesn't have the "on" keyword.
|
|
50
|
+
if (onIndex === -1) {
|
|
51
|
+
errors.push(new ParseError(sourceSpan, `Could not find "on" keyword in expression`));
|
|
52
|
+
return [];
|
|
53
|
+
}
|
|
54
|
+
const start = getTriggerParametersStart(expression, onIndex + 1);
|
|
55
|
+
return new OnTriggerParser(expression, start, sourceSpan, errors).parse();
|
|
56
|
+
}
|
|
57
|
+
class OnTriggerParser {
|
|
58
|
+
constructor(expression, start, span, errors) {
|
|
59
|
+
this.expression = expression;
|
|
60
|
+
this.start = start;
|
|
61
|
+
this.span = span;
|
|
62
|
+
this.errors = errors;
|
|
63
|
+
this.index = 0;
|
|
64
|
+
this.triggers = [];
|
|
65
|
+
this.tokens = new Lexer().tokenize(expression.slice(start));
|
|
66
|
+
}
|
|
67
|
+
parse() {
|
|
68
|
+
while (this.tokens.length > 0 && this.index < this.tokens.length) {
|
|
69
|
+
const token = this.token();
|
|
70
|
+
if (!token.isIdentifier()) {
|
|
71
|
+
this.unexpectedToken(token);
|
|
72
|
+
break;
|
|
73
|
+
}
|
|
74
|
+
// An identifier immediately followed by a comma or the end of
|
|
75
|
+
// the expression cannot have parameters so we can exit early.
|
|
76
|
+
if (this.isFollowedByOrLast(chars.$COMMA)) {
|
|
77
|
+
this.consumeTrigger(token, []);
|
|
78
|
+
this.advance();
|
|
79
|
+
}
|
|
80
|
+
else if (this.isFollowedByOrLast(chars.$LPAREN)) {
|
|
81
|
+
this.advance(); // Advance to the opening paren.
|
|
82
|
+
const prevErrors = this.errors.length;
|
|
83
|
+
const parameters = this.consumeParameters();
|
|
84
|
+
if (this.errors.length !== prevErrors) {
|
|
85
|
+
break;
|
|
86
|
+
}
|
|
87
|
+
this.consumeTrigger(token, parameters);
|
|
88
|
+
this.advance(); // Advance past the closing paren.
|
|
89
|
+
}
|
|
90
|
+
else if (this.index < this.tokens.length - 1) {
|
|
91
|
+
this.unexpectedToken(this.tokens[this.index + 1]);
|
|
92
|
+
}
|
|
93
|
+
this.advance();
|
|
94
|
+
}
|
|
95
|
+
return this.triggers;
|
|
96
|
+
}
|
|
97
|
+
advance() {
|
|
98
|
+
this.index++;
|
|
99
|
+
}
|
|
100
|
+
isFollowedByOrLast(char) {
|
|
101
|
+
if (this.index === this.tokens.length - 1) {
|
|
102
|
+
return true;
|
|
103
|
+
}
|
|
104
|
+
return this.tokens[this.index + 1].isCharacter(char);
|
|
105
|
+
}
|
|
106
|
+
token() {
|
|
107
|
+
return this.tokens[Math.min(this.index, this.tokens.length - 1)];
|
|
108
|
+
}
|
|
109
|
+
consumeTrigger(identifier, parameters) {
|
|
110
|
+
const startSpan = this.span.start.moveBy(this.start + identifier.index - this.tokens[0].index);
|
|
111
|
+
const endSpan = startSpan.moveBy(this.token().end - identifier.index);
|
|
112
|
+
const sourceSpan = new ParseSourceSpan(startSpan, endSpan);
|
|
113
|
+
try {
|
|
114
|
+
switch (identifier.toString()) {
|
|
115
|
+
case OnTriggerType.IDLE:
|
|
116
|
+
this.triggers.push(createIdleTrigger(parameters, sourceSpan));
|
|
117
|
+
break;
|
|
118
|
+
case OnTriggerType.TIMER:
|
|
119
|
+
this.triggers.push(createTimerTrigger(parameters, sourceSpan));
|
|
120
|
+
break;
|
|
121
|
+
case OnTriggerType.INTERACTION:
|
|
122
|
+
this.triggers.push(createInteractionTrigger(parameters, sourceSpan));
|
|
123
|
+
break;
|
|
124
|
+
case OnTriggerType.IMMEDIATE:
|
|
125
|
+
this.triggers.push(createImmediateTrigger(parameters, sourceSpan));
|
|
126
|
+
break;
|
|
127
|
+
case OnTriggerType.HOVER:
|
|
128
|
+
this.triggers.push(createHoverTrigger(parameters, sourceSpan));
|
|
129
|
+
break;
|
|
130
|
+
case OnTriggerType.VIEWPORT:
|
|
131
|
+
this.triggers.push(createViewportTrigger(parameters, sourceSpan));
|
|
132
|
+
break;
|
|
133
|
+
default:
|
|
134
|
+
throw new Error(`Unrecognized trigger type "${identifier}"`);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
137
|
+
catch (e) {
|
|
138
|
+
this.error(identifier, e.message);
|
|
139
|
+
}
|
|
140
|
+
}
|
|
141
|
+
consumeParameters() {
|
|
142
|
+
const parameters = [];
|
|
143
|
+
if (!this.token().isCharacter(chars.$LPAREN)) {
|
|
144
|
+
this.unexpectedToken(this.token());
|
|
145
|
+
return parameters;
|
|
146
|
+
}
|
|
147
|
+
this.advance();
|
|
148
|
+
const commaDelimStack = [];
|
|
149
|
+
let current = '';
|
|
150
|
+
while (this.index < this.tokens.length) {
|
|
151
|
+
const token = this.token();
|
|
152
|
+
// Stop parsing if we've hit the end character and we're outside of a comma-delimited syntax.
|
|
153
|
+
// Note that we don't need to account for strings here since the lexer already parsed them
|
|
154
|
+
// into string tokens.
|
|
155
|
+
if (token.isCharacter(chars.$RPAREN) && commaDelimStack.length === 0) {
|
|
156
|
+
if (current.length) {
|
|
157
|
+
parameters.push(current);
|
|
158
|
+
}
|
|
159
|
+
break;
|
|
160
|
+
}
|
|
161
|
+
// In the `on` microsyntax "top-level" commas (e.g. ones outside of an parameters) separate
|
|
162
|
+
// the different triggers (e.g. `on idle,timer(500)`). This is problematic, because the
|
|
163
|
+
// function-like syntax also implies that multiple parameters can be passed into the
|
|
164
|
+
// individual trigger (e.g. `on foo(a, b)`). To avoid tripping up the parser with commas that
|
|
165
|
+
// are part of other sorts of syntax (object literals, arrays), we treat anything inside
|
|
166
|
+
// a comma-delimited syntax block as plain text.
|
|
167
|
+
if (token.type === TokenType.Character && COMMA_DELIMITED_SYNTAX.has(token.numValue)) {
|
|
168
|
+
commaDelimStack.push(COMMA_DELIMITED_SYNTAX.get(token.numValue));
|
|
169
|
+
}
|
|
170
|
+
if (commaDelimStack.length > 0 &&
|
|
171
|
+
token.isCharacter(commaDelimStack[commaDelimStack.length - 1])) {
|
|
172
|
+
commaDelimStack.pop();
|
|
173
|
+
}
|
|
174
|
+
// If we hit a comma outside of a comma-delimited syntax, it means
|
|
175
|
+
// that we're at the top level and we're starting a new parameter.
|
|
176
|
+
if (commaDelimStack.length === 0 && token.isCharacter(chars.$COMMA) && current.length > 0) {
|
|
177
|
+
parameters.push(current);
|
|
178
|
+
current = '';
|
|
179
|
+
this.advance();
|
|
180
|
+
continue;
|
|
181
|
+
}
|
|
182
|
+
// Otherwise treat the token as a plain text character in the current parameter.
|
|
183
|
+
current += this.tokenText();
|
|
184
|
+
this.advance();
|
|
185
|
+
}
|
|
186
|
+
if (!this.token().isCharacter(chars.$RPAREN) || commaDelimStack.length > 0) {
|
|
187
|
+
this.error(this.token(), 'Unexpected end of expression');
|
|
188
|
+
}
|
|
189
|
+
if (this.index < this.tokens.length - 1 &&
|
|
190
|
+
!this.tokens[this.index + 1].isCharacter(chars.$COMMA)) {
|
|
191
|
+
this.unexpectedToken(this.tokens[this.index + 1]);
|
|
192
|
+
}
|
|
193
|
+
return parameters;
|
|
194
|
+
}
|
|
195
|
+
tokenText() {
|
|
196
|
+
// Tokens have a toString already which we could use, but for string tokens it omits the quotes.
|
|
197
|
+
// Eventually we could expose this information on the token directly.
|
|
198
|
+
return this.expression.slice(this.start + this.token().index, this.start + this.token().end);
|
|
199
|
+
}
|
|
200
|
+
error(token, message) {
|
|
201
|
+
const newStart = this.span.start.moveBy(this.start + token.index);
|
|
202
|
+
const newEnd = newStart.moveBy(token.end - token.index);
|
|
203
|
+
this.errors.push(new ParseError(new ParseSourceSpan(newStart, newEnd), message));
|
|
204
|
+
}
|
|
205
|
+
unexpectedToken(token) {
|
|
206
|
+
this.error(token, `Unexpected token "${token}"`);
|
|
207
|
+
}
|
|
208
|
+
}
|
|
209
|
+
function createIdleTrigger(parameters, sourceSpan) {
|
|
210
|
+
if (parameters.length > 0) {
|
|
211
|
+
throw new Error(`"${OnTriggerType.IDLE}" trigger cannot have parameters`);
|
|
212
|
+
}
|
|
213
|
+
return new t.IdleDeferredTrigger(sourceSpan);
|
|
214
|
+
}
|
|
215
|
+
function createTimerTrigger(parameters, sourceSpan) {
|
|
216
|
+
if (parameters.length !== 1) {
|
|
217
|
+
throw new Error(`"${OnTriggerType.TIMER}" trigger must have exactly one parameter`);
|
|
218
|
+
}
|
|
219
|
+
const delay = parseDeferredTime(parameters[0]);
|
|
220
|
+
if (delay === null) {
|
|
221
|
+
throw new Error(`Could not parse time value of trigger "${OnTriggerType.TIMER}"`);
|
|
222
|
+
}
|
|
223
|
+
return new t.TimerDeferredTrigger(delay, sourceSpan);
|
|
224
|
+
}
|
|
225
|
+
function createInteractionTrigger(parameters, sourceSpan) {
|
|
226
|
+
if (parameters.length > 1) {
|
|
227
|
+
throw new Error(`"${OnTriggerType.INTERACTION}" trigger can only have zero or one parameters`);
|
|
228
|
+
}
|
|
229
|
+
return new t.InteractionDeferredTrigger(parameters[0] ?? null, sourceSpan);
|
|
230
|
+
}
|
|
231
|
+
function createImmediateTrigger(parameters, sourceSpan) {
|
|
232
|
+
if (parameters.length > 0) {
|
|
233
|
+
throw new Error(`"${OnTriggerType.IMMEDIATE}" trigger cannot have parameters`);
|
|
234
|
+
}
|
|
235
|
+
return new t.ImmediateDeferredTrigger(sourceSpan);
|
|
236
|
+
}
|
|
237
|
+
function createHoverTrigger(parameters, sourceSpan) {
|
|
238
|
+
if (parameters.length > 0) {
|
|
239
|
+
throw new Error(`"${OnTriggerType.HOVER}" trigger cannot have parameters`);
|
|
240
|
+
}
|
|
241
|
+
return new t.HoverDeferredTrigger(sourceSpan);
|
|
242
|
+
}
|
|
243
|
+
function createViewportTrigger(parameters, sourceSpan) {
|
|
244
|
+
// TODO: the RFC has some more potential parameters for `viewport`.
|
|
245
|
+
if (parameters.length > 1) {
|
|
246
|
+
throw new Error(`"${OnTriggerType.VIEWPORT}" trigger can only have zero or one parameters`);
|
|
247
|
+
}
|
|
248
|
+
return new t.ViewportDeferredTrigger(parameters[0] ?? null, sourceSpan);
|
|
249
|
+
}
|
|
250
|
+
/** Gets the index within an expression at which the trigger parameters start. */
|
|
251
|
+
export function getTriggerParametersStart(value, startPosition = 0) {
|
|
252
|
+
let hasFoundSeparator = false;
|
|
253
|
+
for (let i = startPosition; i < value.length; i++) {
|
|
254
|
+
if (SEPARATOR_PATTERN.test(value[i])) {
|
|
255
|
+
hasFoundSeparator = true;
|
|
256
|
+
}
|
|
257
|
+
else if (hasFoundSeparator) {
|
|
258
|
+
return i;
|
|
259
|
+
}
|
|
260
|
+
}
|
|
261
|
+
return -1;
|
|
262
|
+
}
|
|
263
|
+
/**
|
|
264
|
+
* Parses a time expression from a deferred trigger to
|
|
265
|
+
* milliseconds. Returns null if it cannot be parsed.
|
|
266
|
+
*/
|
|
267
|
+
export function parseDeferredTime(value) {
|
|
268
|
+
const match = value.match(TIME_PATTERN);
|
|
269
|
+
if (!match) {
|
|
270
|
+
return null;
|
|
271
|
+
}
|
|
272
|
+
const [time, units] = match;
|
|
273
|
+
return parseInt(time) * (units === 's' ? 1000 : 1);
|
|
274
|
+
}
|
|
275
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicjNfZGVmZXJyZWRfdHJpZ2dlcnMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21waWxlci9zcmMvcmVuZGVyMy9yM19kZWZlcnJlZF90cmlnZ2Vycy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEtBQUssS0FBSyxNQUFNLFVBQVUsQ0FBQztBQUNsQyxPQUFPLEVBQUMsS0FBSyxFQUFTLFNBQVMsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBRW5FLE9BQU8sRUFBQyxVQUFVLEVBQUUsZUFBZSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRzFELE9BQU8sS0FBSyxDQUFDLE1BQU0sVUFBVSxDQUFDO0FBRTlCLCtDQUErQztBQUMvQyxNQUFNLFlBQVksR0FBRyxjQUFjLENBQUM7QUFFcEMsd0VBQXdFO0FBQ3hFLE1BQU0saUJBQWlCLEdBQUcsTUFBTSxDQUFDO0FBRWpDLG9FQUFvRTtBQUNwRSxNQUFNLHNCQUFzQixHQUFHLElBQUksR0FBRyxDQUFDO0lBQ3JDLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDO0lBQzlCLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxLQUFLLENBQUMsU0FBUyxDQUFDO0lBQ2xDLENBQUMsS0FBSyxDQUFDLE9BQU8sRUFBRSxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQU8saUJBQWlCO0NBQ3ZELENBQUMsQ0FBQztBQUVILHVDQUF1QztBQUN2QyxJQUFLLGFBT0o7QUFQRCxXQUFLLGFBQWE7SUFDaEIsOEJBQWEsQ0FBQTtJQUNiLGdDQUFlLENBQUE7SUFDZiw0Q0FBMkIsQ0FBQTtJQUMzQix3Q0FBdUIsQ0FBQTtJQUN2QixnQ0FBZSxDQUFBO0lBQ2Ysc0NBQXFCLENBQUE7QUFDdkIsQ0FBQyxFQVBJLGFBQWEsS0FBYixhQUFhLFFBT2pCO0FBRUQsd0NBQXdDO0FBQ3hDLE1BQU0sVUFBVSxnQkFB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QUFNLFVBQVUseUJBQXlCLENBQUMsS0FBYSxFQUFFLGFBQWEsR0FBRyxDQUFDO0lBQ3hFLElBQUksaUJBQWlCLEdBQUcsS0FBSyxDQUFDO0lBRTlCLEtBQUssSUFBSSxDQUFDLEdBQUcsYUFBYSxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1FBQ2pELElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFO1lBQ3BDLGlCQUFpQixHQUFHLElBQUksQ0FBQztTQUMxQjthQUFNLElBQUksaUJBQWlCLEVBQUU7WUFDNUIsT0FBTyxDQUFDLENBQUM7U0FDVjtLQUNGO0lBRUQsT0FBTyxDQUFDLENBQUMsQ0FBQztBQUNaLENBQUM7QUFFRDs7O0dBR0c7QUFDSCxNQUFNLFVBQVUsaUJBQWlCLENBQUMsS0FBYTtJQUM3QyxNQUFNLEtBQUssR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLFlBQVksQ0FBQyxDQUFDO0lBRXhDLElBQUksQ0FBQyxLQUFLLEVBQUU7UUFDVixPQUFPLElBQUksQ0FBQztLQUNiO0lBRUQsTUFBTSxDQUFDLElBQUksRUFBRSxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUM7SUFDNUIsT0FBTyxRQUFRLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEtBQUssR0FBRyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0FBQ3JELENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0ICogYXMgY2hhcnMgZnJvbSAnLi4vY2hhcnMnO1xuaW1wb3J0IHtMZXhlciwgVG9rZW4sIFRva2VuVHlwZX0gZnJvbSAnLi4vZXhwcmVzc2lvbl9wYXJzZXIvbGV4ZXInO1xuaW1wb3J0ICogYXMgaHRtbCBmcm9tICcuLi9tbF9wYXJzZXIvYXN0JztcbmltcG9ydCB7UGFyc2VFcnJvciwgUGFyc2VTb3VyY2VTcGFufSBmcm9tICcuLi9wYXJzZV91dGlsJztcbmltcG9ydCB7QmluZGluZ1BhcnNlcn0gZnJvbSAnLi4vdGVtcGxhdGVfcGFyc2VyL2JpbmRpbmdfcGFyc2VyJztcblxuaW1wb3J0ICogYXMgdCBmcm9tICcuL3IzX2FzdCc7XG5cbi8qKiBQYXR0ZXJuIGZvciBhIHRpbWluZyB2YWx1ZSBpbiBhIHRyaWdnZXIuICovXG5jb25zdCBUSU1FX1BBVFRFUk4gPSAvXlxcZCsobXN8cyk/JC87XG5cbi8qKiBQYXR0ZXJuIGZvciBhIHNlcGFyYXRvciBiZXR3ZWVuIGtleXdvcmRzIGluIGEgdHJpZ2dlciBleHByZXNzaW9uLiAqL1xuY29uc3QgU0VQQVJBVE9SX1BBVFRFUk4gPSAvXlxccyQvO1xuXG4vKiogUGFpcnMgb2YgY2hhcmFjdGVycyB0aGF0IGZvcm0gc3ludGF4IHRoYXQgaXMgY29tbWEtZGVsaW1pdGVkLiAqL1xuY29uc3QgQ09NTUFfREVMSU1JVEVEX1NZTlRBWCA9IG5ldyBNYXAoW1xuICBbY2hhcnMuJExCUkFDRSwgY2hhcnMuJFJCUkFDRV0sICAgICAgLy8gT2JqZWN0IGxpdGVyYWxzXG4gIFtjaGFycy4kTEJSQUNLRVQsIGNoYXJzLiRSQlJBQ0tFVF0sICAvLyBBcnJheSBsaXRlcmFsc1xuICBbY2hhcnMuJExQQVJFTiwgY2hhcnMuJFJQQVJFTl0sICAgICAgLy8gRnVuY3Rpb24gY2FsbHNcbl0pO1xuXG4vKiogUG9zc2libGUgdHlwZXMgb2YgYG9uYCB0cmlnZ2Vycy4gKi9cbmVudW0gT25UcmlnZ2VyVHlwZSB7XG4gIElETEUgPSAnaWRsZScsXG4gIFRJTUVSID0gJ3RpbWVyJyxcbiAgSU5URVJBQ1RJT04gPSAnaW50ZXJhY3Rpb24nLFxuICBJTU1FRElBVEUgPSAnaW1tZWRpYXRlJyxcbiAgSE9WRVIgPSAnaG92ZXInLFxuICBWSUVXUE9SVCA9ICd2aWV3cG9ydCcsXG59XG5cbi8qKiBQYXJzZXMgYSBgd2hlbmAgZGVmZXJyZWQgdHJpZ2dlci4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZVdoZW5UcmlnZ2VyKFxuICAgIHtleHByZXNzaW9uLCBzb3VyY2VTcGFufTogaHRtbC5CbG9ja1BhcmFtZXRlciwgYmluZGluZ1BhcnNlcjogQmluZGluZ1BhcnNlcixcbiAgICBlcnJvcnM6IFBhcnNlRXJyb3JbXSk6IHQuQm91bmREZWZlcnJlZFRyaWdnZXJ8bnVsbCB7XG4gIGNvbnN0IHdoZW5JbmRleCA9IGV4cHJlc3Npb24uaW5kZXhPZignd2hlbicpO1xuXG4gIC8vIFRoaXMgaXMgaGVyZSBqdXN0IHRvIGJlIHNhZmUsIHdlIHNob3VsZG4ndCBlbnRlciB0aGlzIGZ1bmN0aW9uXG4gIC8vIGluIHRoZSBmaXJzdCBwbGFjZSBpZiBhIGJsb2NrIGRvZXNuJ3QgaGF2ZSB0aGUgXCJ3aGVuXCIga2V5d29yZC5cbiAgaWYgKHdoZW5JbmRleCA9PT0gLTEpIHtcbiAgICBlcnJvcnMucHVzaChuZXcgUGFyc2VFcnJvcihzb3VyY2VTcGFuLCBgQ291bGQgbm90IGZpbmQgXCJ3aGVuXCIga2V5d29yZCBpbiBleHByZXNzaW9uYCkpO1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3Qgc3RhcnQgPSBnZXRUcmlnZ2VyUGFyYW1ldGVyc1N0YXJ0KGV4cHJlc3Npb24sIHdoZW5JbmRleCArIDEpO1xuICBjb25zdCBwYXJzZWQgPSBiaW5kaW5nUGFyc2VyLnBhcnNlQmluZGluZyhcbiAgICAgIGV4cHJlc3Npb24uc2xpY2Uoc3RhcnQpLCBmYWxzZSwgc291cmNlU3Bhbiwgc291cmNlU3Bhbi5zdGFydC5vZmZzZXQgKyBzdGFydCk7XG5cbiAgcmV0dXJuIG5ldyB0LkJvdW5kRGVmZXJyZWRUcmlnZ2VyKHBhcnNlZCwgc291cmNlU3Bhbik7XG59XG5cbi8qKiBQYXJzZXMgYW4gYG9uYCB0cmlnZ2VyICovXG5leHBvcnQgZnVuY3Rpb24gcGFyc2VPblRyaWdnZXIoXG4gICAge2V4cHJlc3Npb24sIHNvdXJjZVNwYW59OiBodG1sLkJsb2NrUGFyYW1ldGVyLCBlcnJvcnM6IFBhcnNlRXJyb3JbXSk6IHQuRGVmZXJyZWRUcmlnZ2VyW10ge1xuICBjb25zdCBvbkluZGV4ID0gZXhwcmVzc2lvbi5pbmRleE9mKCdvbicpO1xuXG4gIC8vIFRoaXMgaXMgaGVyZSBqdXN0IHRvIGJlIHNhZmUsIHdlIHNob3VsZG4ndCBlbnRlciB0aGlzIGZ1bmN0aW9uXG4gIC8vIGluIHRoZSBmaXJzdCBwbGFjZSBpZiBhIGJsb2NrIGRvZXNuJ3QgaGF2ZSB0aGUgXCJvblwiIGtleXdvcmQuXG4gIGlmIChvbkluZGV4ID09PSAtMSkge1xuICAgIGVycm9ycy5wdXNoKG5ldyBQYXJzZUVycm9yKHNvdXJjZVNwYW4sIGBDb3VsZCBub3QgZmluZCBcIm9uXCIga2V5d29yZCBpbiBleHByZXNzaW9uYCkpO1xuICAgIHJldHVybiBbXTtcbiAgfVxuXG4gIGNvbnN0IHN0YXJ0ID0gZ2V0VHJpZ2dlclBhcmFtZXRlcnNTdGFydChleHByZXNzaW9uLCBvbkluZGV4ICsgMSk7XG4gIHJldHVybiBuZXcgT25UcmlnZ2VyUGFyc2VyKGV4cHJlc3Npb24sIHN0YXJ0LCBzb3VyY2VTcGFuLCBlcnJvcnMpLnBhcnNlKCk7XG59XG5cbmNsYXNzIE9uVHJpZ2dlclBhcnNlciB7XG4gIHByaXZhdGUgaW5kZXggPSAwO1xuICBwcml2YXRlIHRva2VuczogVG9rZW5bXTtcbiAgcHJpdmF0ZSB0cmlnZ2VyczogdC5EZWZlcnJlZFRyaWdnZXJbXSA9IFtdO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgICAgcHJpdmF0ZSBleHByZXNzaW9uOiBzdHJpbmcsIHByaXZhdGUgc3RhcnQ6IG51bWJlciwgcHJpdmF0ZSBzcGFuOiBQYXJzZVNvdXJjZVNwYW4sXG4gICAgICBwcml2YXRlIGVycm9yczogUGFyc2VFcnJvcltdKSB7XG4gICAgdGhpcy50b2tlbnMgPSBuZXcgTGV4ZXIoKS50b2tlbml6ZShleHByZXNzaW9uLnNsaWNlKHN0YXJ0KSk7XG4gIH1cblxuICBwYXJzZSgpOiB0LkRlZmVycmVkVHJpZ2dlcltdIHtcbiAgICB3aGlsZSAodGhpcy50b2tlbnMubGVuZ3RoID4gMCAmJiB0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW4oKTtcblxuICAgICAgaWYgKCF0b2tlbi5pc0lkZW50aWZpZXIoKSkge1xuICAgICAgICB0aGlzLnVuZXhwZWN0ZWRUb2tlbih0b2tlbik7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuXG4gICAgICAvLyBBbiBpZGVudGlmaWVyIGltbWVkaWF0ZWx5IGZvbGxvd2VkIGJ5IGEgY29tbWEgb3IgdGhlIGVuZCBvZlxuICAgICAgLy8gdGhlIGV4cHJlc3Npb24gY2Fubm90IGhhdmUgcGFyYW1ldGVycyBzbyB3ZSBjYW4gZXhpdCBlYXJseS5cbiAgICAgIGlmICh0aGlzLmlzRm9sbG93ZWRCeU9yTGFzdChjaGFycy4kQ09NTUEpKSB7XG4gICAgICAgIHRoaXMuY29uc3VtZVRyaWdnZXIodG9rZW4sIFtdKTtcbiAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuaXNGb2xsb3dlZEJ5T3JMYXN0KGNoYXJzLiRMUEFSRU4pKSB7XG4gICAgICAgIHRoaXMuYWR2YW5jZSgpOyAgLy8gQWR2YW5jZSB0byB0aGUgb3BlbmluZyBwYXJlbi5cbiAgICAgICAgY29uc3QgcHJldkVycm9ycyA9IHRoaXMuZXJyb3JzLmxlbmd0aDtcbiAgICAgICAgY29uc3QgcGFyYW1ldGVycyA9IHRoaXMuY29uc3VtZVBhcmFtZXRlcnMoKTtcbiAgICAgICAgaWYgKHRoaXMuZXJyb3JzLmxlbmd0aCAhPT0gcHJldkVycm9ycykge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIHRoaXMuY29uc3VtZVRyaWdnZXIodG9rZW4sIHBhcmFtZXRlcnMpO1xuICAgICAgICB0aGlzLmFkdmFuY2UoKTsgIC8vIEFkdmFuY2UgcGFzdCB0aGUgY2xvc2luZyBwYXJlbi5cbiAgICAgIH0gZWxzZSBpZiAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCAtIDEpIHtcbiAgICAgICAgdGhpcy51bmV4cGVjdGVkVG9rZW4odGhpcy50b2tlbnNbdGhpcy5pbmRleCArIDFdKTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMudHJpZ2dlcnM7XG4gIH1cblxuICBwcml2YXRlIGFkdmFuY2UoKSB7XG4gICAgdGhpcy5pbmRleCsrO1xuICB9XG5cbiAgcHJpdmF0ZSBpc0ZvbGxvd2VkQnlPckxhc3QoY2hhcjogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMuaW5kZXggPT09IHRoaXMudG9rZW5zLmxlbmd0aCAtIDEpIHtcbiAgICAgIHJldHVybiB0cnVlO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLnRva2Vuc1t0aGlzLmluZGV4ICsgMV0uaXNDaGFyYWN0ZXIoY2hhcik7XG4gIH1cblxuICBwcml2YXRlIHRva2VuKCk6IFRva2VuIHtcbiAgICByZXR1cm4gdGhpcy50b2tlbnNbTWF0aC5taW4odGhpcy5pbmRleCwgdGhpcy50b2tlbnMubGVuZ3RoIC0gMSldO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdW1lVHJpZ2dlcihpZGVudGlmaWVyOiBUb2tlbiwgcGFyYW1ldGVyczogc3RyaW5nW10pIHtcbiAgICBjb25zdCBzdGFydFNwYW4gPSB0aGlzLnNwYW4uc3RhcnQubW92ZUJ5KHRoaXMuc3RhcnQgKyBpZGVudGlmaWVyLmluZGV4IC0gdGhpcy50b2tlbnNbMF0uaW5kZXgpO1xuICAgIGNvbnN0IGVuZFNwYW4gPSBzdGFydFNwYW4ubW92ZUJ5KHRoaXMudG9rZW4oKS5lbmQgLSBpZGVudGlmaWVyLmluZGV4KTtcbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IFBhcnNlU291cmNlU3BhbihzdGFydFNwYW4sIGVuZFNwYW4pO1xuXG4gICAgdHJ5IHtcbiAgICAgIHN3aXRjaCAoaWRlbnRpZmllci50b1N0cmluZygpKSB7XG4gICAgICAgIGNhc2UgT25UcmlnZ2VyVHlwZS5JRExFOlxuICAgICAgICAgIHRoaXMudHJpZ2dlcnMucHVzaChjcmVhdGVJZGxlVHJpZ2dlcihwYXJhbWV0ZXJzLCBzb3VyY2VTcGFuKSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBPblRyaWdnZXJUeXBlLlRJTUVSOlxuICAgICAgICAgIHRoaXMudHJpZ2dlcnMucHVzaChjcmVhdGVUaW1lclRyaWdnZXIocGFyYW1ldGVycywgc291cmNlU3BhbikpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGNhc2UgT25UcmlnZ2VyVHlwZS5JTlRFUkFDVElPTjpcbiAgICAgICAgICB0aGlzLnRyaWdnZXJzLnB1c2goY3JlYXRlSW50ZXJhY3Rpb25UcmlnZ2VyKHBhcmFtZXRlcnMsIHNvdXJjZVNwYW4pKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIE9uVHJpZ2dlclR5cGUuSU1NRURJQVRFOlxuICAgICAgICAgIHRoaXMudHJpZ2dlcnMucHVzaChjcmVhdGVJbW1lZGlhdGVUcmlnZ2VyKHBhcmFtZXRlcnMsIHNvdXJjZVNwYW4pKTtcbiAgICAgICAgICBicmVhaztcblxuICAgICAgICBjYXNlIE9uVHJpZ2dlclR5cGUuSE9WRVI6XG4gICAgICAgICAgdGhpcy50cmlnZ2Vycy5wdXNoKGNyZWF0ZUhvdmVyVHJpZ2dlcihwYXJhbWV0ZXJzLCBzb3VyY2VTcGFuKSk7XG4gICAgICAgICAgYnJlYWs7XG5cbiAgICAgICAgY2FzZSBPblRyaWdnZXJUeXBlLlZJRVdQT1JUOlxuICAgICAgICAgIHRoaXMudHJpZ2dlcnMucHVzaChjcmVhdGVWaWV3cG9ydFRyaWdnZXIocGFyYW1ldGVycywgc291cmNlU3BhbikpO1xuICAgICAgICAgIGJyZWFrO1xuXG4gICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnJlY29nbml6ZWQgdHJpZ2dlciB0eXBlIFwiJHtpZGVudGlmaWVyfVwiYCk7XG4gICAgICB9XG4gICAgfSBjYXRjaCAoZSkge1xuICAgICAgdGhpcy5lcnJvcihpZGVudGlmaWVyLCAoZSBhcyBFcnJvcikubWVzc2FnZSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjb25zdW1lUGFyYW1ldGVycygpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgcGFyYW1ldGVyczogc3RyaW5nW10gPSBbXTtcblxuICAgIGlmICghdGhpcy50b2tlbigpLmlzQ2hhcmFjdGVyKGNoYXJzLiRMUEFSRU4pKSB7XG4gICAgICB0aGlzLnVuZXhwZWN0ZWRUb2tlbih0aGlzLnRva2VuKCkpO1xuICAgICAgcmV0dXJuIHBhcmFtZXRlcnM7XG4gICAgfVxuXG4gICAgdGhpcy5hZHZhbmNlKCk7XG5cbiAgICBjb25zdCBjb21tYURlbGltU3RhY2s6IG51bWJlcltdID0gW107XG4gICAgbGV0IGN1cnJlbnQgPSAnJztcblxuICAgIHdoaWxlICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICBjb25zdCB0b2tlbiA9IHRoaXMudG9rZW4oKTtcblxuICAgICAgLy8gU3RvcCBwYXJzaW5nIGlmIHdlJ3ZlIGhpdCB0aGUgZW5kIGNoYXJhY3RlciBhbmQgd2UncmUgb3V0c2lkZSBvZiBhIGNvbW1hLWRlbGltaXRlZCBzeW50YXguXG4gICAgICAvLyBOb3RlIHRoYXQgd2UgZG9uJ3QgbmVlZCB0byBhY2NvdW50IGZvciBzdHJpbmdzIGhlcmUgc2luY2UgdGhlIGxleGVyIGFscmVhZHkgcGFyc2VkIHRoZW1cbiAgICAgIC8vIGludG8gc3RyaW5nIHRva2Vucy5cbiAgICAgIGlmICh0b2tlbi5pc0NoYXJhY3RlcihjaGFycy4kUlBBUkVOKSAmJiBjb21tYURlbGltU3RhY2subGVuZ3RoID09PSAwKSB7XG4gICAgICAgIGlmIChjdXJyZW50Lmxlbmd0aCkge1xuICAgICAgICAgIHBhcmFtZXRlcnMucHVzaChjdXJyZW50KTtcbiAgICAgICAgfVxuICAgICAgICBicmVhaztcbiAgICAgIH1cblxuICAgICAgLy8gSW4gdGhlIGBvbmAgbWljcm9zeW50YXggXCJ0b3AtbGV2ZWxcIiBjb21tYXMgKGUuZy4gb25lcyBvdXRzaWRlIG9mIGFuIHBhcmFtZXRlcnMpIHNlcGFyYXRlXG4gICAgICAvLyB0aGUgZGlmZmVyZW50IHRyaWdnZXJzIChlLmcuIGBvbiBpZGxlLHRpbWVyKDUwMClgKS4gVGhpcyBpcyBwcm9ibGVtYXRpYywgYmVjYXVzZSB0aGVcbiAgICAgIC8vIGZ1bmN0aW9uLWxpa2Ugc3ludGF4IGFsc28gaW1wbGllcyB0aGF0IG11bHRpcGxlIHBhcmFtZXRlcnMgY2FuIGJlIHBhc3NlZCBpbnRvIHRoZVxuICAgICAgLy8gaW5kaXZpZHVhbCB0cmlnZ2VyIChlLmcuIGBvbiBmb28oYSwgYilgKS4gVG8gYXZvaWQgdHJpcHBpbmcgdXAgdGhlIHBhcnNlciB3aXRoIGNvbW1hcyB0aGF0XG4gICAgICAvLyBhcmUgcGFydCBvZiBvdGhlciBzb3J0cyBvZiBzeW50YXggKG9iamVjdCBsaXRlcmFscywgYXJyYXlzKSwgd2UgdHJlYXQgYW55dGhpbmcgaW5zaWRlXG4gICAgICAvLyBhIGNvbW1hLWRlbGltaXRlZCBzeW50YXggYmxvY2sgYXMgcGxhaW4gdGV4dC5cbiAgICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlblR5cGUuQ2hhcmFjdGVyICYmIENPTU1BX0RFTElNSVRFRF9TWU5UQVguaGFzKHRva2VuLm51bVZhbHVlKSkge1xuICAgICAgICBjb21tYURlbGltU3RhY2sucHVzaChDT01NQV9ERUxJTUlURURfU1lOVEFYLmdldCh0b2tlbi5udW1WYWx1ZSkhKTtcbiAgICAgIH1cblxuICAgICAgaWYgKGNvbW1hRGVsaW1TdGFjay5sZW5ndGggPiAwICYmXG4gICAgICAgICAgdG9rZW4uaXNDaGFyYWN0ZXIoY29tbWFEZWxpbVN0YWNrW2NvbW1hRGVsaW1TdGFjay5sZW5ndGggLSAxXSkpIHtcbiAgICAgICAgY29tbWFEZWxpbVN0YWNrLnBvcCgpO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiB3ZSBoaXQgYSBjb21tYSBvdXRzaWRlIG9mIGEgY29tbWEtZGVsaW1pdGVkIHN5bnRheCwgaXQgbWVhbnNcbiAgICAgIC8vIHRoYXQgd2UncmUgYXQgdGhlIHRvcCBsZXZlbCBhbmQgd2UncmUgc3RhcnRpbmcgYSBuZXcgcGFyYW1ldGVyLlxuICAgICAgaWYgKGNvbW1hRGVsaW1TdGFjay5sZW5ndGggPT09IDAgJiYgdG9rZW4uaXNDaGFyYWN0ZXIoY2hhcnMuJENPTU1BKSAmJiBjdXJyZW50Lmxlbmd0aCA+IDApIHtcbiAgICAgICAgcGFyYW1ldGVycy5wdXNoKGN1cnJlbnQpO1xuICAgICAgICBjdXJyZW50ID0gJyc7XG4gICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gT3RoZXJ3aXNlIHRyZWF0IHRoZSB0b2tlbiBhcyBhIHBsYWluIHRleHQgY2hhcmFjdGVyIGluIHRoZSBjdXJyZW50IHBhcmFtZXRlci5cbiAgICAgIGN1cnJlbnQgKz0gdGhpcy50b2tlblRleHQoKTtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIH1cblxuICAgIGlmICghdGhpcy50b2tlbigpLmlzQ2hhcmFjdGVyKGNoYXJzLiRSUEFSRU4pIHx8IGNvbW1hRGVsaW1TdGFjay5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmVycm9yKHRoaXMudG9rZW4oKSwgJ1VuZXhwZWN0ZWQgZW5kIG9mIGV4cHJlc3Npb24nKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCAtIDEgJiZcbiAgICAgICAgIXRoaXMudG9rZW5zW3RoaXMuaW5kZXggKyAxXS5pc0NoYXJhY3RlcihjaGFycy4kQ09NTUEpKSB7XG4gICAgICB0aGlzLnVuZXhwZWN0ZWRUb2tlbih0aGlzLnRva2Vuc1t0aGlzLmluZGV4ICsgMV0pO1xuICAgIH1cblxuICAgIHJldHVybiBwYXJhbWV0ZXJzO1xuICB9XG5cbiAgcHJpdmF0ZSB0b2tlblRleHQoKTogc3RyaW5nIHtcbiAgICAvLyBUb2tlbnMgaGF2ZSBhIHRvU3RyaW5nIGFscmVhZHkgd2hpY2ggd2UgY291bGQgdXNlLCBidXQgZm9yIHN0cmluZyB0b2tlbnMgaXQgb21pdHMgdGhlIHF1b3Rlcy5cbiAgICAvLyBFdmVudHVhbGx5IHdlIGNvdWxkIGV4cG9zZSB0aGlzIGluZm9ybWF0aW9uIG9uIHRoZSB0b2tlbiBkaXJlY3RseS5cbiAgICByZXR1cm4gdGhpcy5leHByZXNzaW9uLnNsaWNlKHRoaXMuc3RhcnQgKyB0aGlzLnRva2VuKCkuaW5kZXgsIHRoaXMuc3RhcnQgKyB0aGlzLnRva2VuKCkuZW5kKTtcbiAgfVxuXG4gIHByaXZhdGUgZXJyb3IodG9rZW46IFRva2VuLCBtZXNzYWdlOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBuZXdTdGFydCA9IHRoaXMuc3Bhbi5zdGFydC5tb3ZlQnkodGhpcy5zdGFydCArIHRva2VuLmluZGV4KTtcbiAgICBjb25zdCBuZXdFbmQgPSBuZXdTdGFydC5tb3ZlQnkodG9rZW4uZW5kIC0gdG9rZW4uaW5kZXgpO1xuICAgIHRoaXMuZXJyb3JzLnB1c2gobmV3IFBhcnNlRXJyb3IobmV3IFBhcnNlU291cmNlU3BhbihuZXdTdGFydCwgbmV3RW5kKSwgbWVzc2FnZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSB1bmV4cGVjdGVkVG9rZW4odG9rZW46IFRva2VuKSB7XG4gICAgdGhpcy5lcnJvcih0b2tlbiwgYFVuZXhwZWN0ZWQgdG9rZW4gXCIke3Rva2VufVwiYCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlSWRsZVRyaWdnZXIoXG4gICAgcGFyYW1ldGVyczogc3RyaW5nW10sIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3Bhbik6IHQuSWRsZURlZmVycmVkVHJpZ2dlciB7XG4gIGlmIChwYXJhbWV0ZXJzLmxlbmd0aCA+IDApIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYFwiJHtPblRyaWdnZXJUeXBlLklETEV9XCIgdHJpZ2dlciBjYW5ub3QgaGF2ZSBwYXJhbWV0ZXJzYCk7XG4gIH1cblxuICByZXR1cm4gbmV3IHQuSWRsZURlZmVycmVkVHJpZ2dlcihzb3VyY2VTcGFuKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlVGltZXJUcmlnZ2VyKHBhcmFtZXRlcnM6IHN0cmluZ1tdLCBzb3VyY2VTcGFuOiBQYXJzZVNvdXJjZVNwYW4pIHtcbiAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoICE9PSAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBcIiR7T25UcmlnZ2VyVHlwZS5USU1FUn1cIiB0cmlnZ2VyIG11c3QgaGF2ZSBleGFjdGx5IG9uZSBwYXJhbWV0ZXJgKTtcbiAgfVxuXG4gIGNvbnN0IGRlbGF5ID0gcGFyc2VEZWZlcnJlZFRpbWUocGFyYW1ldGVyc1swXSk7XG5cbiAgaWYgKGRlbGF5ID09PSBudWxsKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBDb3VsZCBub3QgcGFyc2UgdGltZSB2YWx1ZSBvZiB0cmlnZ2VyIFwiJHtPblRyaWdnZXJUeXBlLlRJTUVSfVwiYCk7XG4gIH1cblxuICByZXR1cm4gbmV3IHQuVGltZXJEZWZlcnJlZFRyaWdnZXIoZGVsYXksIHNvdXJjZVNwYW4pO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVJbnRlcmFjdGlvblRyaWdnZXIoXG4gICAgcGFyYW1ldGVyczogc3RyaW5nW10sIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3Bhbik6IHQuSW50ZXJhY3Rpb25EZWZlcnJlZFRyaWdnZXIge1xuICBpZiAocGFyYW1ldGVycy5sZW5ndGggPiAxKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBcIiR7T25UcmlnZ2VyVHlwZS5JTlRFUkFDVElPTn1cIiB0cmlnZ2VyIGNhbiBvbmx5IGhhdmUgemVybyBvciBvbmUgcGFyYW1ldGVyc2ApO1xuICB9XG5cbiAgcmV0dXJuIG5ldyB0LkludGVyYWN0aW9uRGVmZXJyZWRUcmlnZ2VyKHBhcmFtZXRlcnNbMF0gPz8gbnVsbCwgc291cmNlU3Bhbik7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUltbWVkaWF0ZVRyaWdnZXIoXG4gICAgcGFyYW1ldGVyczogc3RyaW5nW10sIHNvdXJjZVNwYW46IFBhcnNlU291cmNlU3Bhbik6IHQuSW1tZWRpYXRlRGVmZXJyZWRUcmlnZ2VyIHtcbiAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgXCIke09uVHJpZ2dlclR5cGUuSU1NRURJQVRFfVwiIHRyaWdnZXIgY2Fubm90IGhhdmUgcGFyYW1ldGVyc2ApO1xuICB9XG5cbiAgcmV0dXJuIG5ldyB0LkltbWVkaWF0ZURlZmVycmVkVHJpZ2dlcihzb3VyY2VTcGFuKTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlSG92ZXJUcmlnZ2VyKFxuICAgIHBhcmFtZXRlcnM6IHN0cmluZ1tdLCBzb3VyY2VTcGFuOiBQYXJzZVNvdXJjZVNwYW4pOiB0LkhvdmVyRGVmZXJyZWRUcmlnZ2VyIHtcbiAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoID4gMCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgXCIke09uVHJpZ2dlclR5cGUuSE9WRVJ9XCIgdHJpZ2dlciBjYW5ub3QgaGF2ZSBwYXJhbWV0ZXJzYCk7XG4gIH1cblxuICByZXR1cm4gbmV3IHQuSG92ZXJEZWZlcnJlZFRyaWdnZXIoc291cmNlU3Bhbik7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVZpZXdwb3J0VHJpZ2dlcihcbiAgICBwYXJhbWV0ZXJzOiBzdHJpbmdbXSwgc291cmNlU3BhbjogUGFyc2VTb3VyY2VTcGFuKTogdC5WaWV3cG9ydERlZmVycmVkVHJpZ2dlciB7XG4gIC8vIFRPRE86IHRoZSBSRkMgaGFzIHNvbWUgbW9yZSBwb3RlbnRpYWwgcGFyYW1ldGVycyBmb3IgYHZpZXdwb3J0YC5cbiAgaWYgKHBhcmFtZXRlcnMubGVuZ3RoID4gMSkge1xuICAgIHRocm93IG5ldyBFcnJvcihgXCIke09uVHJpZ2dlclR5cGUuVklFV1BPUlR9XCIgdHJpZ2dlciBjYW4gb25seSBoYXZlIHplcm8gb3Igb25lIHBhcmFtZXRlcnNgKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgdC5WaWV3cG9ydERlZmVycmVkVHJpZ2dlcihwYXJhbWV0ZXJzWzBdID8/IG51bGwsIHNvdXJjZVNwYW4pO1xufVxuXG4vKiogR2V0cyB0aGUgaW5kZXggd2l0aGluIGFuIGV4cHJlc3Npb24gYXQgd2hpY2ggdGhlIHRyaWdnZXIgcGFyYW1ldGVycyBzdGFydC4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRUcmlnZ2VyUGFyYW1ldGVyc1N0YXJ0KHZhbHVlOiBzdHJpbmcsIHN0YXJ0UG9zaXRpb24gPSAwKTogbnVtYmVyIHtcbiAgbGV0IGhhc0ZvdW5kU2VwYXJhdG9yID0gZmFsc2U7XG5cbiAgZm9yIChsZXQgaSA9IHN0YXJ0UG9zaXRpb247IGkgPCB2YWx1ZS5sZW5ndGg7IGkrKykge1xuICAgIGlmIChTRVBBUkFUT1JfUEFUVEVSTi50ZXN0KHZhbHVlW2ldKSkge1xuICAgICAgaGFzRm91bmRTZXBhcmF0b3IgPSB0cnVlO1xuICAgIH0gZWxzZSBpZiAoaGFzRm91bmRTZXBhcmF0b3IpIHtcbiAgICAgIHJldHVybiBpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiAtMTtcbn1cblxuLyoqXG4gKiBQYXJzZXMgYSB0aW1lIGV4cHJlc3Npb24gZnJvbSBhIGRlZmVycmVkIHRyaWdnZXIgdG9cbiAqIG1pbGxpc2Vjb25kcy4gUmV0dXJucyBudWxsIGlmIGl0IGNhbm5vdCBiZSBwYXJzZWQuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZURlZmVycmVkVGltZSh2YWx1ZTogc3RyaW5nKTogbnVtYmVyfG51bGwge1xuICBjb25zdCBtYXRjaCA9IHZhbHVlLm1hdGNoKFRJTUVfUEFUVEVSTik7XG5cbiAgaWYgKCFtYXRjaCkge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgY29uc3QgW3RpbWUsIHVuaXRzXSA9IG1hdGNoO1xuICByZXR1cm4gcGFyc2VJbnQodGltZSkgKiAodW5pdHMgPT09ICdzJyA/IDEwMDAgOiAxKTtcbn1cbiJdfQ==
|