@ngx-formly/core 7.0.1 → 7.1.0
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/json-schema/formly-json-schema.service.mjs +101 -1
- package/esm2022/lib/core.config.mjs +19 -3
- package/esm2022/lib/core.mjs +2 -2
- package/esm2022/lib/extensions/field-expression/field-expression.mjs +6 -244
- package/esm2022/lib/extensions/field-expression/utils.mjs +453 -11
- package/esm2022/lib/extensions/field-expression-legacy/field-expression.mjs +249 -0
- package/esm2022/lib/extensions/field-expression-legacy/utils.mjs +20 -0
- package/esm2022/lib/utils.mjs +2 -1
- package/fesm2022/ngx-formly-core-json-schema.mjs +100 -0
- package/fesm2022/ngx-formly-core-json-schema.mjs.map +1 -1
- package/fesm2022/ngx-formly-core.mjs +492 -5
- package/fesm2022/ngx-formly-core.mjs.map +1 -1
- package/json-schema/formly-json-schema.service.d.ts +3 -0
- package/lib/core.config.d.ts +1 -0
- package/lib/core.d.ts +2 -2
- package/lib/extensions/field-expression/field-expression.d.ts +3 -12
- package/lib/extensions/field-expression/utils.d.ts +4 -2
- package/lib/extensions/field-expression-legacy/field-expression.d.ts +16 -0
- package/lib/extensions/field-expression-legacy/utils.d.ts +5 -0
- package/package.json +1 -1
- package/esm2022/lib/extensions/index.mjs +0 -2
- package/lib/extensions/index.d.ts +0 -1
|
@@ -1,17 +1,459 @@
|
|
|
1
|
-
|
|
2
|
-
|
|
3
|
-
|
|
1
|
+
// CSP-compliant expression parser for Formly expressions
|
|
2
|
+
// Supports: model.path, formState.path, field.path, comparisons, logical operators, and negation
|
|
3
|
+
// Tokenizer
|
|
4
|
+
var TokenType;
|
|
5
|
+
(function (TokenType) {
|
|
6
|
+
TokenType["IDENTIFIER"] = "IDENTIFIER";
|
|
7
|
+
TokenType["DOT"] = "DOT";
|
|
8
|
+
TokenType["BRACKET_OPEN"] = "BRACKET_OPEN";
|
|
9
|
+
TokenType["BRACKET_CLOSE"] = "BRACKET_CLOSE";
|
|
10
|
+
TokenType["STRING"] = "STRING";
|
|
11
|
+
TokenType["NUMBER"] = "NUMBER";
|
|
12
|
+
TokenType["BOOLEAN"] = "BOOLEAN";
|
|
13
|
+
TokenType["NULL"] = "NULL";
|
|
14
|
+
TokenType["UNDEFINED"] = "UNDEFINED";
|
|
15
|
+
TokenType["OPERATOR"] = "OPERATOR";
|
|
16
|
+
TokenType["LOGICAL"] = "LOGICAL";
|
|
17
|
+
TokenType["NOT"] = "NOT";
|
|
18
|
+
TokenType["ARITHMETIC"] = "ARITHMETIC";
|
|
19
|
+
TokenType["PAREN_OPEN"] = "PAREN_OPEN";
|
|
20
|
+
TokenType["PAREN_CLOSE"] = "PAREN_CLOSE";
|
|
21
|
+
TokenType["TERNARY_QUESTION"] = "TERNARY_QUESTION";
|
|
22
|
+
TokenType["TERNARY_COLON"] = "TERNARY_COLON";
|
|
23
|
+
TokenType["EOF"] = "EOF";
|
|
24
|
+
})(TokenType || (TokenType = {}));
|
|
25
|
+
class Tokenizer {
|
|
26
|
+
constructor(input) {
|
|
27
|
+
this.pos = 0;
|
|
28
|
+
this.input = input.trim();
|
|
4
29
|
}
|
|
5
|
-
|
|
6
|
-
|
|
30
|
+
tokenize() {
|
|
31
|
+
const tokens = [];
|
|
32
|
+
while (this.pos < this.input.length) {
|
|
33
|
+
this.skipWhitespace();
|
|
34
|
+
if (this.pos >= this.input.length)
|
|
35
|
+
break;
|
|
36
|
+
const char = this.input[this.pos];
|
|
37
|
+
// String literals
|
|
38
|
+
if (char === '"' || char === "'") {
|
|
39
|
+
tokens.push(this.readString());
|
|
40
|
+
}
|
|
41
|
+
// Numbers
|
|
42
|
+
else if (/\d/.test(char)) {
|
|
43
|
+
tokens.push(this.readNumber());
|
|
44
|
+
}
|
|
45
|
+
// Identifiers and keywords
|
|
46
|
+
else if (/[a-zA-Z_$]/.test(char)) {
|
|
47
|
+
tokens.push(this.readIdentifier());
|
|
48
|
+
}
|
|
49
|
+
// Operators and symbols
|
|
50
|
+
else if (char === '.') {
|
|
51
|
+
tokens.push({ type: TokenType.DOT, value: '.' });
|
|
52
|
+
this.pos++;
|
|
53
|
+
}
|
|
54
|
+
else if (char === '[') {
|
|
55
|
+
tokens.push({ type: TokenType.BRACKET_OPEN, value: '[' });
|
|
56
|
+
this.pos++;
|
|
57
|
+
}
|
|
58
|
+
else if (char === ']') {
|
|
59
|
+
tokens.push({ type: TokenType.BRACKET_CLOSE, value: ']' });
|
|
60
|
+
this.pos++;
|
|
61
|
+
}
|
|
62
|
+
else if (char === '(') {
|
|
63
|
+
tokens.push({ type: TokenType.PAREN_OPEN, value: '(' });
|
|
64
|
+
this.pos++;
|
|
65
|
+
}
|
|
66
|
+
else if (char === ')') {
|
|
67
|
+
tokens.push({ type: TokenType.PAREN_CLOSE, value: ')' });
|
|
68
|
+
this.pos++;
|
|
69
|
+
}
|
|
70
|
+
else if (char === '?') {
|
|
71
|
+
tokens.push({ type: TokenType.TERNARY_QUESTION, value: '?' });
|
|
72
|
+
this.pos++;
|
|
73
|
+
}
|
|
74
|
+
else if (char === ':') {
|
|
75
|
+
tokens.push({ type: TokenType.TERNARY_COLON, value: ':' });
|
|
76
|
+
this.pos++;
|
|
77
|
+
}
|
|
78
|
+
else if (char === '!') {
|
|
79
|
+
if (this.peek() === '=') {
|
|
80
|
+
if (this.input[this.pos + 2] === '=') {
|
|
81
|
+
tokens.push({ type: TokenType.OPERATOR, value: '!==' });
|
|
82
|
+
this.pos += 3;
|
|
83
|
+
}
|
|
84
|
+
else {
|
|
85
|
+
tokens.push({ type: TokenType.OPERATOR, value: '!=' });
|
|
86
|
+
this.pos += 2;
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
else {
|
|
90
|
+
tokens.push({ type: TokenType.NOT, value: '!' });
|
|
91
|
+
this.pos++;
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
else if (char === '=' || char === '<' || char === '>') {
|
|
95
|
+
tokens.push(this.readOperator());
|
|
96
|
+
}
|
|
97
|
+
else if (char === '+' || char === '*' || char === '/' || char === '%') {
|
|
98
|
+
tokens.push({ type: TokenType.ARITHMETIC, value: char });
|
|
99
|
+
this.pos++;
|
|
100
|
+
}
|
|
101
|
+
else if (char === '-') {
|
|
102
|
+
// Check if this is a negative number or subtraction
|
|
103
|
+
// It's a negative number if preceded by an operator, opening paren, or at the start
|
|
104
|
+
const lastToken = tokens[tokens.length - 1];
|
|
105
|
+
const isNegativeNumber = tokens.length === 0 ||
|
|
106
|
+
lastToken?.type === TokenType.OPERATOR ||
|
|
107
|
+
lastToken?.type === TokenType.LOGICAL ||
|
|
108
|
+
lastToken?.type === TokenType.ARITHMETIC ||
|
|
109
|
+
lastToken?.type === TokenType.PAREN_OPEN ||
|
|
110
|
+
lastToken?.type === TokenType.TERNARY_QUESTION ||
|
|
111
|
+
lastToken?.type === TokenType.TERNARY_COLON;
|
|
112
|
+
if (isNegativeNumber && this.peek() && /\d/.test(this.peek())) {
|
|
113
|
+
tokens.push(this.readNumber());
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
tokens.push({ type: TokenType.ARITHMETIC, value: '-' });
|
|
117
|
+
this.pos++;
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
else if (char === '&' && this.peek() === '&') {
|
|
121
|
+
tokens.push({ type: TokenType.LOGICAL, value: '&&' });
|
|
122
|
+
this.pos += 2;
|
|
123
|
+
}
|
|
124
|
+
else if (char === '|' && this.peek() === '|') {
|
|
125
|
+
tokens.push({ type: TokenType.LOGICAL, value: '||' });
|
|
126
|
+
this.pos += 2;
|
|
127
|
+
}
|
|
128
|
+
else {
|
|
129
|
+
throw new Error(`Unexpected character: ${char} at position ${this.pos}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
tokens.push({ type: TokenType.EOF, value: null });
|
|
133
|
+
return tokens;
|
|
134
|
+
}
|
|
135
|
+
skipWhitespace() {
|
|
136
|
+
while (this.pos < this.input.length && /\s/.test(this.input[this.pos])) {
|
|
137
|
+
this.pos++;
|
|
138
|
+
}
|
|
139
|
+
}
|
|
140
|
+
peek(offset = 1) {
|
|
141
|
+
return this.input[this.pos + offset] || '';
|
|
142
|
+
}
|
|
143
|
+
readString() {
|
|
144
|
+
const quote = this.input[this.pos];
|
|
145
|
+
this.pos++;
|
|
146
|
+
let value = '';
|
|
147
|
+
while (this.pos < this.input.length && this.input[this.pos] !== quote) {
|
|
148
|
+
if (this.input[this.pos] === '\\') {
|
|
149
|
+
this.pos++;
|
|
150
|
+
if (this.pos < this.input.length) {
|
|
151
|
+
const escaped = this.input[this.pos];
|
|
152
|
+
switch (escaped) {
|
|
153
|
+
case 'n':
|
|
154
|
+
value += '\n';
|
|
155
|
+
break;
|
|
156
|
+
case 't':
|
|
157
|
+
value += '\t';
|
|
158
|
+
break;
|
|
159
|
+
case 'r':
|
|
160
|
+
value += '\r';
|
|
161
|
+
break;
|
|
162
|
+
default:
|
|
163
|
+
value += escaped;
|
|
164
|
+
}
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
else {
|
|
168
|
+
value += this.input[this.pos];
|
|
169
|
+
}
|
|
170
|
+
this.pos++;
|
|
171
|
+
}
|
|
172
|
+
this.pos++; // skip closing quote
|
|
173
|
+
return { type: TokenType.STRING, value };
|
|
174
|
+
}
|
|
175
|
+
readNumber() {
|
|
176
|
+
let value = '';
|
|
177
|
+
// Handle negatives
|
|
178
|
+
if (this.input[this.pos] === '-') {
|
|
179
|
+
value += '-';
|
|
180
|
+
this.pos++;
|
|
181
|
+
}
|
|
182
|
+
let hasDecimal = false;
|
|
183
|
+
while (this.pos < this.input.length && /[\d.]/.test(this.input[this.pos])) {
|
|
184
|
+
if (this.input[this.pos] === '.') {
|
|
185
|
+
if (hasDecimal) {
|
|
186
|
+
throw new Error(`Invalid number format: multiple decimal points at position ${this.pos}`);
|
|
187
|
+
}
|
|
188
|
+
hasDecimal = true;
|
|
189
|
+
}
|
|
190
|
+
value += this.input[this.pos];
|
|
191
|
+
this.pos++;
|
|
192
|
+
}
|
|
193
|
+
const parsed = parseFloat(value);
|
|
194
|
+
if (isNaN(parsed)) {
|
|
195
|
+
throw new Error(`Invalid number format: ${value}`);
|
|
196
|
+
}
|
|
197
|
+
return { type: TokenType.NUMBER, value: parsed };
|
|
198
|
+
}
|
|
199
|
+
readIdentifier() {
|
|
200
|
+
let value = '';
|
|
201
|
+
while (this.pos < this.input.length && /[a-zA-Z0-9_$]/.test(this.input[this.pos])) {
|
|
202
|
+
value += this.input[this.pos];
|
|
203
|
+
this.pos++;
|
|
204
|
+
}
|
|
205
|
+
// Check for keywords
|
|
206
|
+
if (value === 'true' || value === 'false') {
|
|
207
|
+
return { type: TokenType.BOOLEAN, value: value === 'true' };
|
|
208
|
+
}
|
|
209
|
+
if (value === 'null') {
|
|
210
|
+
return { type: TokenType.NULL, value: null };
|
|
211
|
+
}
|
|
212
|
+
if (value === 'undefined') {
|
|
213
|
+
return { type: TokenType.UNDEFINED, value: undefined };
|
|
214
|
+
}
|
|
215
|
+
return { type: TokenType.IDENTIFIER, value };
|
|
216
|
+
}
|
|
217
|
+
readOperator() {
|
|
218
|
+
let op = this.input[this.pos];
|
|
219
|
+
this.pos++;
|
|
220
|
+
if (this.pos < this.input.length) {
|
|
221
|
+
const next = this.input[this.pos];
|
|
222
|
+
if ((op === '=' && next === '=') ||
|
|
223
|
+
(op === '!' && next === '=') ||
|
|
224
|
+
(op === '<' && next === '=') ||
|
|
225
|
+
(op === '>' && next === '=')) {
|
|
226
|
+
op += next;
|
|
227
|
+
this.pos++;
|
|
228
|
+
// Check for === or !==
|
|
229
|
+
if (this.pos < this.input.length && this.input[this.pos] === '=') {
|
|
230
|
+
op += '=';
|
|
231
|
+
this.pos++;
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
}
|
|
235
|
+
return { type: TokenType.OPERATOR, value: op };
|
|
236
|
+
}
|
|
237
|
+
}
|
|
238
|
+
// Parser and Evaluator
|
|
239
|
+
class ExpressionParser {
|
|
240
|
+
constructor(tokens) {
|
|
241
|
+
this.pos = 0;
|
|
242
|
+
this.tokens = tokens;
|
|
243
|
+
}
|
|
244
|
+
parse() {
|
|
245
|
+
const expr = this.parseTernary();
|
|
246
|
+
return (context) => expr(context);
|
|
247
|
+
}
|
|
248
|
+
parseTernary() {
|
|
249
|
+
const expr = this.parseLogicalOr();
|
|
250
|
+
if (this.current().type === TokenType.TERNARY_QUESTION) {
|
|
251
|
+
this.consume(TokenType.TERNARY_QUESTION);
|
|
252
|
+
const trueExpr = this.parseLogicalOr();
|
|
253
|
+
this.consume(TokenType.TERNARY_COLON);
|
|
254
|
+
const falseExpr = this.parseTernary();
|
|
255
|
+
return (context) => {
|
|
256
|
+
return expr(context) ? trueExpr(context) : falseExpr(context);
|
|
257
|
+
};
|
|
258
|
+
}
|
|
259
|
+
return expr;
|
|
260
|
+
}
|
|
261
|
+
parseLogicalOr() {
|
|
262
|
+
let left = this.parseLogicalAnd();
|
|
263
|
+
while (this.current().type === TokenType.LOGICAL && this.current().value === '||') {
|
|
264
|
+
this.consume(TokenType.LOGICAL);
|
|
265
|
+
const right = this.parseLogicalAnd();
|
|
266
|
+
const prevLeft = left;
|
|
267
|
+
left = (context) => prevLeft(context) || right(context);
|
|
268
|
+
}
|
|
269
|
+
return left;
|
|
270
|
+
}
|
|
271
|
+
parseLogicalAnd() {
|
|
272
|
+
let left = this.parseComparison();
|
|
273
|
+
while (this.current().type === TokenType.LOGICAL && this.current().value === '&&') {
|
|
274
|
+
this.consume(TokenType.LOGICAL);
|
|
275
|
+
const right = this.parseComparison();
|
|
276
|
+
const prevLeft = left;
|
|
277
|
+
left = (context) => prevLeft(context) && right(context);
|
|
278
|
+
}
|
|
279
|
+
return left;
|
|
280
|
+
}
|
|
281
|
+
parseComparison() {
|
|
282
|
+
const left = this.parseAdditive();
|
|
283
|
+
if (this.current().type === TokenType.OPERATOR) {
|
|
284
|
+
const op = this.consume(TokenType.OPERATOR).value;
|
|
285
|
+
const right = this.parseAdditive();
|
|
286
|
+
return (context) => {
|
|
287
|
+
const leftVal = left(context);
|
|
288
|
+
const rightVal = right(context);
|
|
289
|
+
switch (op) {
|
|
290
|
+
case '===':
|
|
291
|
+
return leftVal === rightVal;
|
|
292
|
+
case '!==':
|
|
293
|
+
return leftVal !== rightVal;
|
|
294
|
+
case '==':
|
|
295
|
+
return leftVal == rightVal;
|
|
296
|
+
case '!=':
|
|
297
|
+
return leftVal != rightVal;
|
|
298
|
+
case '<':
|
|
299
|
+
return leftVal < rightVal;
|
|
300
|
+
case '<=':
|
|
301
|
+
return leftVal <= rightVal;
|
|
302
|
+
case '>':
|
|
303
|
+
return leftVal > rightVal;
|
|
304
|
+
case '>=':
|
|
305
|
+
return leftVal >= rightVal;
|
|
306
|
+
default:
|
|
307
|
+
throw new Error(`Unknown operator: ${op}`);
|
|
308
|
+
}
|
|
309
|
+
};
|
|
310
|
+
}
|
|
311
|
+
return left;
|
|
312
|
+
}
|
|
313
|
+
parseAdditive() {
|
|
314
|
+
let left = this.parseMultiplicative();
|
|
315
|
+
while (this.current().type === TokenType.ARITHMETIC &&
|
|
316
|
+
(this.current().value === '+' || this.current().value === '-')) {
|
|
317
|
+
const op = this.consume(TokenType.ARITHMETIC).value;
|
|
318
|
+
const right = this.parseMultiplicative();
|
|
319
|
+
const prevLeft = left;
|
|
320
|
+
if (op === '+') {
|
|
321
|
+
left = (context) => prevLeft(context) + right(context);
|
|
322
|
+
}
|
|
323
|
+
else {
|
|
324
|
+
left = (context) => prevLeft(context) - right(context);
|
|
325
|
+
}
|
|
326
|
+
}
|
|
327
|
+
return left;
|
|
328
|
+
}
|
|
329
|
+
parseMultiplicative() {
|
|
330
|
+
let left = this.parseUnary();
|
|
331
|
+
while (this.current().type === TokenType.ARITHMETIC &&
|
|
332
|
+
(this.current().value === '*' || this.current().value === '/' || this.current().value === '%')) {
|
|
333
|
+
const op = this.consume(TokenType.ARITHMETIC).value;
|
|
334
|
+
const right = this.parseUnary();
|
|
335
|
+
const prevLeft = left;
|
|
336
|
+
if (op === '*') {
|
|
337
|
+
left = (context) => prevLeft(context) * right(context);
|
|
338
|
+
}
|
|
339
|
+
else if (op === '/') {
|
|
340
|
+
left = (context) => prevLeft(context) / right(context);
|
|
341
|
+
}
|
|
342
|
+
else {
|
|
343
|
+
left = (context) => prevLeft(context) % right(context);
|
|
344
|
+
}
|
|
345
|
+
}
|
|
346
|
+
return left;
|
|
347
|
+
}
|
|
348
|
+
parseUnary() {
|
|
349
|
+
if (this.current().type === TokenType.NOT) {
|
|
350
|
+
this.consume(TokenType.NOT);
|
|
351
|
+
const expr = this.parseUnary();
|
|
352
|
+
return (context) => !expr(context);
|
|
353
|
+
}
|
|
354
|
+
return this.parsePrimary();
|
|
355
|
+
}
|
|
356
|
+
parsePrimary() {
|
|
357
|
+
const token = this.current();
|
|
358
|
+
// Parentheses
|
|
359
|
+
if (token.type === TokenType.PAREN_OPEN) {
|
|
360
|
+
this.consume(TokenType.PAREN_OPEN);
|
|
361
|
+
const expr = this.parseTernary();
|
|
362
|
+
this.consume(TokenType.PAREN_CLOSE);
|
|
363
|
+
return expr;
|
|
364
|
+
}
|
|
365
|
+
// Literals
|
|
366
|
+
if (token.type === TokenType.STRING ||
|
|
367
|
+
token.type === TokenType.NUMBER ||
|
|
368
|
+
token.type === TokenType.BOOLEAN ||
|
|
369
|
+
token.type === TokenType.NULL ||
|
|
370
|
+
token.type === TokenType.UNDEFINED) {
|
|
371
|
+
const value = token.value;
|
|
372
|
+
this.pos++;
|
|
373
|
+
return () => value;
|
|
374
|
+
}
|
|
375
|
+
// Property access (model.field, formState.prop, etc)
|
|
376
|
+
if (token.type === TokenType.IDENTIFIER) {
|
|
377
|
+
return this.parsePropertyAccess();
|
|
378
|
+
}
|
|
379
|
+
throw new Error(`Unexpected token: ${JSON.stringify(token)}`);
|
|
380
|
+
}
|
|
381
|
+
parsePropertyAccess() {
|
|
382
|
+
const path = [];
|
|
383
|
+
// Read first identifier
|
|
384
|
+
path.push(this.consume(TokenType.IDENTIFIER).value);
|
|
385
|
+
// Read rest of path (dots and brackets)
|
|
386
|
+
while (this.current().type === TokenType.DOT || this.current().type === TokenType.BRACKET_OPEN) {
|
|
387
|
+
if (this.current().type === TokenType.DOT) {
|
|
388
|
+
this.consume(TokenType.DOT);
|
|
389
|
+
path.push(this.consume(TokenType.IDENTIFIER).value);
|
|
390
|
+
}
|
|
391
|
+
else {
|
|
392
|
+
this.consume(TokenType.BRACKET_OPEN);
|
|
393
|
+
// bracket notation can contain expressions
|
|
394
|
+
if (this.current().type === TokenType.STRING) {
|
|
395
|
+
path.push(this.consume(TokenType.STRING).value);
|
|
396
|
+
}
|
|
397
|
+
else if (this.current().type === TokenType.NUMBER) {
|
|
398
|
+
path.push(String(this.consume(TokenType.NUMBER).value));
|
|
399
|
+
}
|
|
400
|
+
else {
|
|
401
|
+
// dynamic property access
|
|
402
|
+
const expr = this.parseTernary();
|
|
403
|
+
path.push(expr);
|
|
404
|
+
}
|
|
405
|
+
this.consume(TokenType.BRACKET_CLOSE);
|
|
406
|
+
}
|
|
407
|
+
}
|
|
408
|
+
return (context) => {
|
|
409
|
+
let value = context;
|
|
410
|
+
for (const segment of path) {
|
|
411
|
+
if (value === null || value === undefined) {
|
|
412
|
+
return undefined;
|
|
413
|
+
}
|
|
414
|
+
if (typeof segment === 'function') {
|
|
415
|
+
value = value[segment(context)];
|
|
416
|
+
}
|
|
417
|
+
else {
|
|
418
|
+
value = value[segment];
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
return value;
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
current() {
|
|
425
|
+
return this.tokens[this.pos];
|
|
426
|
+
}
|
|
427
|
+
consume(expectedType) {
|
|
428
|
+
const token = this.current();
|
|
429
|
+
if (token.type !== expectedType) {
|
|
430
|
+
throw new Error(`Expected ${expectedType}, got ${token.type}`);
|
|
431
|
+
}
|
|
432
|
+
this.pos++;
|
|
433
|
+
return token;
|
|
7
434
|
}
|
|
8
435
|
}
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
436
|
+
/**
|
|
437
|
+
* Uses CSP-safe implementation
|
|
438
|
+
*/
|
|
439
|
+
export function parseExpression(expression, argNames) {
|
|
440
|
+
try {
|
|
441
|
+
const tokenizer = new Tokenizer(expression);
|
|
442
|
+
const tokens = tokenizer.tokenize();
|
|
443
|
+
const parser = new ExpressionParser(tokens);
|
|
444
|
+
const evaluator = parser.parse();
|
|
445
|
+
// Return a function that maps the args to the context
|
|
446
|
+
return (...args) => {
|
|
447
|
+
const context = {};
|
|
448
|
+
argNames.forEach((name, i) => {
|
|
449
|
+
context[name] = args[i];
|
|
450
|
+
});
|
|
451
|
+
return evaluator(context);
|
|
452
|
+
};
|
|
12
453
|
}
|
|
13
|
-
|
|
14
|
-
|
|
454
|
+
catch (error) {
|
|
455
|
+
console.error('Expression parse error:', error);
|
|
456
|
+
return undefined;
|
|
15
457
|
}
|
|
16
458
|
}
|
|
17
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvY29yZS9zcmMvbGliL2V4dGVuc2lvbnMvZmllbGQtZXhwcmVzc2lvbi91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxNQUFNLFVBQVUsb0JBQW9CLENBQUMsVUFBa0IsRUFBRSxRQUFrQjtJQUN6RSxJQUFJLENBQUM7UUFDSCxPQUFPLFFBQVEsQ0FBQyxHQUFHLFFBQVEsRUFBRSxVQUFVLFVBQVUsR0FBRyxDQUFRLENBQUM7SUFDL0QsQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ3ZCLENBQUM7QUFDSCxDQUFDO0FBRUQsTUFBTSxVQUFVLGNBQWMsQ0FDNUIsVUFBeUQsRUFDekQsT0FBWSxFQUNaLE1BQWE7SUFFYixJQUFJLE9BQU8sVUFBVSxLQUFLLFVBQVUsRUFBRSxDQUFDO1FBQ3JDLE9BQU8sVUFBVSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDM0MsQ0FBQztTQUFNLENBQUM7UUFDTixPQUFPLFVBQVUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7SUFDbkMsQ0FBQztBQUNILENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyJleHBvcnQgZnVuY3Rpb24gZXZhbFN0cmluZ0V4cHJlc3Npb24oZXhwcmVzc2lvbjogc3RyaW5nLCBhcmdOYW1lczogc3RyaW5nW10pIHtcbiAgdHJ5IHtcbiAgICByZXR1cm4gRnVuY3Rpb24oLi4uYXJnTmFtZXMsIGByZXR1cm4gJHtleHByZXNzaW9ufTtgKSBhcyBhbnk7XG4gIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgY29uc29sZS5lcnJvcihlcnJvcik7XG4gIH1cbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGV2YWxFeHByZXNzaW9uKFxuICBleHByZXNzaW9uOiBzdHJpbmcgfCAoKC4uLnZhbHVlOiBhbnlbXSkgPT4gYW55KSB8IGJvb2xlYW4sXG4gIHRoaXNBcmc6IGFueSxcbiAgYXJnVmFsOiBhbnlbXSxcbik6IGFueSB7XG4gIGlmICh0eXBlb2YgZXhwcmVzc2lvbiA9PT0gJ2Z1bmN0aW9uJykge1xuICAgIHJldHVybiBleHByZXNzaW9uLmFwcGx5KHRoaXNBcmcsIGFyZ1ZhbCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGV4cHJlc3Npb24gPyB0cnVlIDogZmFsc2U7XG4gIH1cbn1cbiJdfQ==
|
|
459
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidXRpbHMuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9zcmMvY29yZS9zcmMvbGliL2V4dGVuc2lvbnMvZmllbGQtZXhwcmVzc2lvbi91dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSx5REFBeUQ7QUFDekQsaUdBQWlHO0FBUWpHLFlBQVk7QUFDWixJQUFLLFNBbUJKO0FBbkJELFdBQUssU0FBUztJQUNaLHNDQUF5QixDQUFBO0lBQ3pCLHdCQUFXLENBQUE7SUFDWCwwQ0FBNkIsQ0FBQTtJQUM3Qiw0Q0FBK0IsQ0FBQTtJQUMvQiw4QkFBaUIsQ0FBQTtJQUNqQiw4QkFBaUIsQ0FBQTtJQUNqQixnQ0FBbUIsQ0FBQTtJQUNuQiwwQkFBYSxDQUFBO0lBQ2Isb0NBQXVCLENBQUE7SUFDdkIsa0NBQXFCLENBQUE7SUFDckIsZ0NBQW1CLENBQUE7SUFDbkIsd0JBQVcsQ0FBQTtJQUNYLHNDQUF5QixDQUFBO0lBQ3pCLHNDQUF5QixDQUFBO0lBQ3pCLHdDQUEyQixDQUFBO0lBQzNCLGtEQUFxQyxDQUFBO0lBQ3JDLDRDQUErQixDQUFBO0lBQy9CLHdCQUFXLENBQUE7QUFDYixDQUFDLEVBbkJJLFNBQVMsS0FBVCxTQUFTLFFBbUJiO0FBT0QsTUFBTSxTQUFTO0lBSWIsWUFBWSxLQUFhO1FBSGpCLFFBQUcsR0FBRyxDQUFDLENBQUM7UUFJZCxJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBRUQsUUFBUTtRQUNOLE1BQU0sTUFBTSxHQUFZLEVBQUUsQ0FBQztRQUUzQixPQUFPLElBQUksQ0FBQyxHQUFHLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFFdEIsSUFBSSxJQUFJLENBQUMsR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsTUFBTTtnQkFBRSxNQUFN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Q3hCLE1BQU0sT0FBTyxHQUFRLEVBQUUsQ0FBQztZQUN4QixRQUFRLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUMzQixPQUFPLENBQUMsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFCLENBQUMsQ0FBQyxDQUFDO1lBQ0gsT0FBTyxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDNUIsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUFDLE9BQU8sS0FBSyxFQUFFLENBQUM7UUFDZixPQUFPLENBQUMsS0FBSyxDQUFDLHlCQUF5QixFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ2hELE9BQU8sU0FBUyxDQUFDO0lBQ25CLENBQUM7QUFDSCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQ1NQLWNvbXBsaWFudCBleHByZXNzaW9uIHBhcnNlciBmb3IgRm9ybWx5IGV4cHJlc3Npb25zXG4vLyBTdXBwb3J0czogbW9kZWwucGF0aCwgZm9ybVN0YXRlLnBhdGgsIGZpZWxkLnBhdGgsIGNvbXBhcmlzb25zLCBsb2dpY2FsIG9wZXJhdG9ycywgYW5kIG5lZ2F0aW9uXG5cbnR5cGUgRXhwcmVzc2lvbkNvbnRleHQgPSB7XG4gIG1vZGVsOiBhbnk7XG4gIGZvcm1TdGF0ZTogYW55O1xuICBmaWVsZDogYW55O1xufTtcblxuLy8gVG9rZW5pemVyXG5lbnVtIFRva2VuVHlwZSB7XG4gIElERU5USUZJRVIgPSAnSURFTlRJRklFUicsXG4gIERPVCA9ICdET1QnLFxuICBCUkFDS0VUX09QRU4gPSAnQlJBQ0tFVF9PUEVOJyxcbiAgQlJBQ0tFVF9DTE9TRSA9ICdCUkFDS0VUX0NMT1NFJyxcbiAgU1RSSU5HID0gJ1NUUklORycsXG4gIE5VTUJFUiA9ICdOVU1CRVInLFxuICBCT09MRUFOID0gJ0JPT0xFQU4nLFxuICBOVUxMID0gJ05VTEwnLFxuICBVTkRFRklORUQgPSAnVU5ERUZJTkVEJyxcbiAgT1BFUkFUT1IgPSAnT1BFUkFUT1InLFxuICBMT0dJQ0FMID0gJ0xPR0lDQUwnLFxuICBOT1QgPSAnTk9UJyxcbiAgQVJJVEhNRVRJQyA9ICdBUklUSE1FVElDJyxcbiAgUEFSRU5fT1BFTiA9ICdQQVJFTl9PUEVOJyxcbiAgUEFSRU5fQ0xPU0UgPSAnUEFSRU5fQ0xPU0UnLFxuICBURVJOQVJZX1FVRVNUSU9OID0gJ1RFUk5BUllfUVVFU1RJT04nLFxuICBURVJOQVJZX0NPTE9OID0gJ1RFUk5BUllfQ09MT04nLFxuICBFT0YgPSAnRU9GJyxcbn1cblxuaW50ZXJmYWNlIFRva2VuIHtcbiAgdHlwZTogVG9rZW5UeXBlO1xuICB2YWx1ZTogYW55O1xufVxuXG5jbGFzcyBUb2tlbml6ZXIge1xuICBwcml2YXRlIHBvcyA9IDA7XG4gIHByaXZhdGUgaW5wdXQ6IHN0cmluZztcblxuICBjb25zdHJ1Y3RvcihpbnB1dDogc3RyaW5nKSB7XG4gICAgdGhpcy5pbnB1dCA9IGlucHV0LnRyaW0oKTtcbiAgfVxuXG4gIHRva2VuaXplKCk6IFRva2VuW10ge1xuICAgIGNvbnN0IHRva2VuczogVG9rZW5bXSA9IFtdO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgdGhpcy5pbnB1dC5sZW5ndGgpIHtcbiAgICAgIHRoaXMuc2tpcFdoaXRlc3BhY2UoKTtcblxuICAgICAgaWYgKHRoaXMucG9zID49IHRoaXMuaW5wdXQubGVuZ3RoKSBicmVhaztcblxuICAgICAgY29uc3QgY2hhciA9IHRoaXMuaW5wdXRbdGhpcy5wb3NdO1xuXG4gICAgICAvLyBTdHJpbmcgbGl0ZXJhbHNcbiAgICAgIGlmIChjaGFyID09PSAnXCInIHx8IGNoYXIgPT09IFwiJ1wiKSB7XG4gICAgICAgIHRva2Vucy5wdXNoKHRoaXMucmVhZFN0cmluZygpKTtcbiAgICAgIH1cbiAgICAgIC8vIE51bWJlcnNcbiAgICAgIGVsc2UgaWYgKC9cXGQvLnRlc3QoY2hhcikpIHtcbiAgICAgICAgdG9rZW5zLnB1c2godGhpcy5yZWFkTnVtYmVyKCkpO1xuICAgICAgfVxuICAgICAgLy8gSWRlbnRpZmllcnMgYW5kIGtleXdvcmRzXG4gICAgICBlbHNlIGlmICgvW2EtekEtWl8kXS8udGVzdChjaGFyKSkge1xuICAgICAgICB0b2tlbnMucHVzaCh0aGlzLnJlYWRJZGVudGlmaWVyKCkpO1xuICAgICAgfVxuICAgICAgLy8gT3BlcmF0b3JzIGFuZCBzeW1ib2xzXG4gICAgICBlbHNlIGlmIChjaGFyID09PSAnLicpIHtcbiAgICAgICAgdG9rZW5zLnB1c2goeyB0eXBlOiBUb2tlblR5cGUuRE9ULCB2YWx1ZTogJy4nIH0pO1xuICAgICAgICB0aGlzLnBvcysrO1xuICAgICAgfSBlbHNlIGlmIChjaGFyID09PSAnWycpIHtcbiAgICAgICAgdG9rZW5zLnB1c2goeyB0eXBlOiBUb2tlblR5cGUuQlJBQ0tFVF9PUEVOLCB2YWx1ZTogJ1snIH0pO1xuICAgICAgICB0aGlzLnBvcysrO1xuICAgICAgfSBlbHNlIGlmIChjaGFyID09PSAnXScpIHtcbiAgICAgICAgdG9rZW5zLnB1c2goeyB0eXBlOiBUb2tlblR5cGUuQlJBQ0tFVF9DTE9TRSwgdmFsdWU6ICddJyB9KTtcbiAgICAgICAgdGhpcy5wb3MrKztcbiAgICAgIH0gZWxzZSBpZiAoY2hhciA9PT0gJygnKSB7XG4gICAgICAgIHRva2Vucy5wdXNoKHsgdHlwZTogVG9rZW5UeXBlLlBBUkVOX09QRU4sIHZhbHVlOiAnKCcgfSk7XG4gICAgICAgIHRoaXMucG9zKys7XG4gICAgICB9IGVsc2UgaWYgKGNoYXIgPT09ICcpJykge1xuICAgICAgICB0b2tlbnMucHVzaCh7IHR5cGU6IFRva2VuVHlwZS5QQVJFTl9DTE9TRSwgdmFsdWU6ICcpJyB9KTtcbiAgICAgICAgdGhpcy5wb3MrKztcbiAgICAgIH0gZWxzZSBpZiAoY2hhciA9PT0gJz8nKSB7XG4gICAgICAgIHRva2Vucy5wdXNoKHsgdHlwZTogVG9rZW5UeXBlLlRFUk5BUllfUVVFU1RJT04sIHZhbHVlOiAnPycgfSk7XG4gICAgICAgIHRoaXMucG9zKys7XG4gICAgICB9IGVsc2UgaWYgKGNoYXIgPT09ICc6Jykge1xuICAgICAgICB0b2tlbnMucHVzaCh7IHR5cGU6IFRva2VuVHlwZS5URVJOQVJZX0NPTE9OLCB2YWx1ZTogJzonIH0pO1xuICAgICAgICB0aGlzLnBvcysrO1xuICAgICAgfSBlbHNlIGlmIChjaGFyID09PSAnIScpIHtcbiAgICAgICAgaWYgKHRoaXMucGVlaygpID09PSAnPScpIHtcbiAgICAgICAgICBpZiAodGhpcy5pbnB1dFt0aGlzLnBvcyArIDJdID09PSAnPScpIHtcbiAgICAgICAgICAgIHRva2Vucy5wdXNoKHsgdHlwZTogVG9rZW5UeXBlLk9QRVJBVE9SLCB2YWx1ZTogJyE9PScgfSk7XG4gICAgICAgICAgICB0aGlzLnBvcyArPSAzO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICB0b2tlbnMucHVzaCh7IHR5cGU6IFRva2VuVHlwZS5PUEVSQVRPUiwgdmFsdWU6ICchPScgfSk7XG4gICAgICAgICAgICB0aGlzLnBvcyArPSAyO1xuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0b2tlbnMucHVzaCh7IHR5cGU6IFRva2VuVHlwZS5OT1QsIHZhbHVlOiAnIScgfSk7XG4gICAgICAgICAgdGhpcy5wb3MrKztcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmIChjaGFyID09PSAnPScgfHwgY2hhciA9PT0gJzwnIHx8IGNoYXIgPT09ICc+Jykge1xuICAgICAgICB0b2tlbnMucHVzaCh0aGlzLnJlYWRPcGVyYXRvcigpKTtcbiAgICAgIH0gZWxzZSBpZiAoY2hhciA9PT0gJysnIHx8IGNoYXIgPT09ICcqJyB8fCBjaGFyID09PSAnLycgfHwgY2hhciA9PT0gJyUnKSB7XG4gICAgICAgIHRva2Vucy5wdXNoKHsgdHlwZTogVG9rZW5UeXBlLkFSSVRITUVUSUMsIHZhbHVlOiBjaGFyIH0pO1xuICAgICAgICB0aGlzLnBvcysrO1xuICAgICAgfSBlbHNlIGlmIChjaGFyID09PSAnLScpIHtcbiAgICAgICAgLy8gQ2hlY2sgaWYgdGhpcyBpcyBhIG5lZ2F0aXZlIG51bWJlciBvciBzdWJ0cmFjdGlvblxuICAgICAgICAvLyBJdCdzIGEgbmVnYXRpdmUgbnVtYmVyIGlmIHByZWNlZGVkIGJ5IGFuIG9wZXJhdG9yLCBvcGVuaW5nIHBhcmVuLCBvciBhdCB0aGUgc3RhcnRcbiAgICAgICAgY29uc3QgbGFzdFRva2VuID0gdG9rZW5zW3Rva2Vucy5sZW5ndGggLSAxXTtcbiAgICAgICAgY29uc3QgaXNOZWdhdGl2ZU51bWJlciA9XG4gICAgICAgICAgdG9rZW5zLmxlbmd0aCA9PT0gMCB8fFxuICAgICAgICAgIGxhc3RUb2tlbj8udHlwZSA9PT0gVG9rZW5UeXBlLk9QRVJBVE9SIHx8XG4gICAgICAgICAgbGFzdFRva2VuPy50eXBlID09PSBUb2tlblR5cGUuTE9HSUNBTCB8fFxuICAgICAgICAgIGxhc3RUb2tlbj8udHlwZSA9PT0gVG9rZW5UeXBlLkFSSVRITUVUSUMgfHxcbiAgICAgICAgICBsYXN0VG9rZW4/LnR5cGUgPT09IFRva2VuVHlwZS5QQVJFTl9PUEVOIHx8XG4gICAgICAgICAgbGFzdFRva2VuPy50eXBlID09PSBUb2tlblR5cGUuVEVSTkFSWV9RVUVTVElPTiB8fFxuICAgICAgICAgIGxhc3RUb2tlbj8udHlwZSA9PT0gVG9rZW5UeXBlLlRFUk5BUllfQ09MT047XG5cbiAgICAgICAgaWYgKGlzTmVnYXRpdmVOdW1iZXIgJiYgdGhpcy5wZWVrKCkgJiYgL1xcZC8udGVzdCh0aGlzLnBlZWsoKSkpIHtcbiAgICAgICAgICB0b2tlbnMucHVzaCh0aGlzLnJlYWROdW1iZXIoKSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdG9rZW5zLnB1c2goeyB0eXBlOiBUb2tlblR5cGUuQVJJVEhNRVRJQywgdmFsdWU6ICctJyB9KTtcbiAgICAgICAgICB0aGlzLnBvcysrO1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKGNoYXIgPT09ICcmJyAmJiB0aGlzLnBlZWsoKSA9PT0gJyYnKSB7XG4gICAgICAgIHRva2Vucy5wdXNoKHsgdHlwZTogVG9rZW5UeXBlLkxPR0lDQUwsIHZhbHVlOiAnJiYnIH0pO1xuICAgICAgICB0aGlzLnBvcyArPSAyO1xuICAgICAgfSBlbHNlIGlmIChjaGFyID09PSAnfCcgJiYgdGhpcy5wZWVrKCkgPT09ICd8Jykge1xuICAgICAgICB0b2tlbnMucHVzaCh7IHR5cGU6IFRva2VuVHlwZS5MT0dJQ0FMLCB2YWx1ZTogJ3x8JyB9KTtcbiAgICAgICAgdGhpcy5wb3MgKz0gMjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCBjaGFyYWN0ZXI6ICR7Y2hhcn0gYXQgcG9zaXRpb24gJHt0aGlzLnBvc31gKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0b2tlbnMucHVzaCh7IHR5cGU6IFRva2VuVHlwZS5FT0YsIHZhbHVlOiBudWxsIH0pO1xuICAgIHJldHVybiB0b2tlbnM7XG4gIH1cblxuICBwcml2YXRlIHNraXBXaGl0ZXNwYWNlKCk6IHZvaWQge1xuICAgIHdoaWxlICh0aGlzLnBvcyA8IHRoaXMuaW5wdXQubGVuZ3RoICYmIC9cXHMvLnRlc3QodGhpcy5pbnB1dFt0aGlzLnBvc10pKSB7XG4gICAgICB0aGlzLnBvcysrO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcGVlayhvZmZzZXQgPSAxKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdGhpcy5pbnB1dFt0aGlzLnBvcyArIG9mZnNldF0gfHwgJyc7XG4gIH1cblxuICBwcml2YXRlIHJlYWRTdHJpbmcoKTogVG9rZW4ge1xuICAgIGNvbnN0IHF1b3RlID0gdGhpcy5pbnB1dFt0aGlzLnBvc107XG4gICAgdGhpcy5wb3MrKztcbiAgICBsZXQgdmFsdWUgPSAnJztcblxuICAgIHdoaWxlICh0aGlzLnBvcyA8IHRoaXMuaW5wdXQubGVuZ3RoICYmIHRoaXMuaW5wdXRbdGhpcy5wb3NdICE9PSBxdW90ZSkge1xuICAgICAgaWYgKHRoaXMuaW5wdXRbdGhpcy5wb3NdID09PSAnXFxcXCcpIHtcbiAgICAgICAgdGhpcy5wb3MrKztcbiAgICAgICAgaWYgKHRoaXMucG9zIDwgdGhpcy5pbnB1dC5sZW5ndGgpIHtcbiAgICAgICAgICBjb25zdCBlc2NhcGVkID0gdGhpcy5pbnB1dFt0aGlzLnBvc107XG4gICAgICAgICAgc3dpdGNoIChlc2NhcGVkKSB7XG4gICAgICAgICAgICBjYXNlICduJzpcbiAgICAgICAgICAgICAgdmFsdWUgKz0gJ1xcbic7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgY2FzZSAndCc6XG4gICAgICAgICAgICAgIHZhbHVlICs9ICdcXHQnO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIGNhc2UgJ3InOlxuICAgICAgICAgICAgICB2YWx1ZSArPSAnXFxyJztcbiAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgICB2YWx1ZSArPSBlc2NhcGVkO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgKz0gdGhpcy5pbnB1dFt0aGlzLnBvc107XG4gICAgICB9XG4gICAgICB0aGlzLnBvcysrO1xuICAgIH1cblxuICAgIHRoaXMucG9zKys7IC8vIHNraXAgY2xvc2luZyBxdW90ZVxuICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5TVFJJTkcsIHZhbHVlIH07XG4gIH1cblxuICBwcml2YXRlIHJlYWROdW1iZXIoKTogVG9rZW4ge1xuICAgIGxldCB2YWx1ZSA9ICcnO1xuXG4gICAgLy8gSGFuZGxlIG5lZ2F0aXZlc1xuICAgIGlmICh0aGlzLmlucHV0W3RoaXMucG9zXSA9PT0gJy0nKSB7XG4gICAgICB2YWx1ZSArPSAnLSc7XG4gICAgICB0aGlzLnBvcysrO1xuICAgIH1cblxuICAgIGxldCBoYXNEZWNpbWFsID0gZmFsc2U7XG4gICAgd2hpbGUgKHRoaXMucG9zIDwgdGhpcy5pbnB1dC5sZW5ndGggJiYgL1tcXGQuXS8udGVzdCh0aGlzLmlucHV0W3RoaXMucG9zXSkpIHtcbiAgICAgIGlmICh0aGlzLmlucHV0W3RoaXMucG9zXSA9PT0gJy4nKSB7XG4gICAgICAgIGlmIChoYXNEZWNpbWFsKSB7XG4gICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBJbnZhbGlkIG51bWJlciBmb3JtYXQ6IG11bHRpcGxlIGRlY2ltYWwgcG9pbnRzIGF0IHBvc2l0aW9uICR7dGhpcy5wb3N9YCk7XG4gICAgICAgIH1cbiAgICAgICAgaGFzRGVjaW1hbCA9IHRydWU7XG4gICAgICB9XG4gICAgICB2YWx1ZSArPSB0aGlzLmlucHV0W3RoaXMucG9zXTtcbiAgICAgIHRoaXMucG9zKys7XG4gICAgfVxuXG4gICAgY29uc3QgcGFyc2VkID0gcGFyc2VGbG9hdCh2YWx1ZSk7XG4gICAgaWYgKGlzTmFOKHBhcnNlZCkpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBudW1iZXIgZm9ybWF0OiAke3ZhbHVlfWApO1xuICAgIH1cblxuICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5OVU1CRVIsIHZhbHVlOiBwYXJzZWQgfTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZElkZW50aWZpZXIoKTogVG9rZW4ge1xuICAgIGxldCB2YWx1ZSA9ICcnO1xuXG4gICAgd2hpbGUgKHRoaXMucG9zIDwgdGhpcy5pbnB1dC5sZW5ndGggJiYgL1thLXpBLVowLTlfJF0vLnRlc3QodGhpcy5pbnB1dFt0aGlzLnBvc10pKSB7XG4gICAgICB2YWx1ZSArPSB0aGlzLmlucHV0W3RoaXMucG9zXTtcbiAgICAgIHRoaXMucG9zKys7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIGtleXdvcmRzXG4gICAgaWYgKHZhbHVlID09PSAndHJ1ZScgfHwgdmFsdWUgPT09ICdmYWxzZScpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5CT09MRUFOLCB2YWx1ZTogdmFsdWUgPT09ICd0cnVlJyB9O1xuICAgIH1cbiAgICBpZiAodmFsdWUgPT09ICdudWxsJykge1xuICAgICAgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLk5VTEwsIHZhbHVlOiBudWxsIH07XG4gICAgfVxuICAgIGlmICh2YWx1ZSA9PT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHJldHVybiB7IHR5cGU6IFRva2VuVHlwZS5VTkRFRklORUQsIHZhbHVlOiB1bmRlZmluZWQgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyB0eXBlOiBUb2tlblR5cGUuSURFTlRJRklFUiwgdmFsdWUgfTtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZE9wZXJhdG9yKCk6IFRva2VuIHtcbiAgICBsZXQgb3AgPSB0aGlzLmlucHV0W3RoaXMucG9zXTtcbiAgICB0aGlzLnBvcysrO1xuXG4gICAgaWYgKHRoaXMucG9zIDwgdGhpcy5pbnB1dC5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IG5leHQgPSB0aGlzLmlucHV0W3RoaXMucG9zXTtcbiAgICAgIGlmIChcbiAgICAgICAgKG9wID09PSAnPScgJiYgbmV4dCA9PT0gJz0nKSB8fFxuICAgICAgICAob3AgPT09ICchJyAmJiBuZXh0ID09PSAnPScpIHx8XG4gICAgICAgIChvcCA9PT0gJzwnICYmIG5leHQgPT09ICc9JykgfHxcbiAgICAgICAgKG9wID09PSAnPicgJiYgbmV4dCA9PT0gJz0nKVxuICAgICAgKSB7XG4gICAgICAgIG9wICs9IG5leHQ7XG4gICAgICAgIHRoaXMucG9zKys7XG5cbiAgICAgICAgLy8gQ2hlY2sgZm9yID09PSBvciAhPT1cbiAgICAgICAgaWYgKHRoaXMucG9zIDwgdGhpcy5pbnB1dC5sZW5ndGggJiYgdGhpcy5pbnB1dFt0aGlzLnBvc10gPT09ICc9Jykge1xuICAgICAgICAgIG9wICs9ICc9JztcbiAgICAgICAgICB0aGlzLnBvcysrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHsgdHlwZTogVG9rZW5UeXBlLk9QRVJBVE9SLCB2YWx1ZTogb3AgfTtcbiAgfVxufVxuXG4vLyBQYXJzZXIgYW5kIEV2YWx1YXRvclxuY2xhc3MgRXhwcmVzc2lvblBhcnNlciB7XG4gIHByaXZhdGUgdG9rZW5zOiBUb2tlbltdO1xuICBwcml2YXRlIHBvcyA9IDA7XG5cbiAgY29uc3RydWN0b3IodG9rZW5zOiBUb2tlbltdKSB7XG4gICAgdGhpcy50b2tlbnMgPSB0b2tlbnM7XG4gIH1cblxuICBwYXJzZSgpOiAoY29udGV4dDogRXhwcmVzc2lvbkNvbnRleHQpID0+IGFueSB7XG4gICAgY29uc3QgZXhwciA9IHRoaXMucGFyc2VUZXJuYXJ5KCk7XG4gICAgcmV0dXJuIChjb250ZXh0OiBFeHByZXNzaW9uQ29udGV4dCkgPT4gZXhwcihjb250ZXh0KTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VUZXJuYXJ5KCk6IChjb250ZXh0OiBFeHByZXNzaW9uQ29udGV4dCkgPT4gYW55IHtcbiAgICBjb25zdCBleHByID0gdGhpcy5wYXJzZUxvZ2ljYWxPcigpO1xuXG4gICAgaWYgKHRoaXMuY3VycmVudCgpLnR5cGUgPT09IFRva2VuVHlwZS5URVJOQVJZX1FVRVNUSU9OKSB7XG4gICAgICB0aGlzLmNvbnN1bWUoVG9rZW5UeXBlLlRFUk5BUllfUVVFU1RJT04pO1xuICAgICAgY29uc3QgdHJ1ZUV4cHIgPSB0aGlzLnBhcnNlTG9naWNhbE9yKCk7XG4gICAgICB0aGlzLmNvbnN1bWUoVG9rZW5UeXBlLlRFUk5BUllfQ09MT04pO1xuICAgICAgY29uc3QgZmFsc2VFeHByID0gdGhpcy5wYXJzZVRlcm5hcnkoKTtcblxuICAgICAgcmV0dXJuIChjb250ZXh0OiBFeHByZXNzaW9uQ29udGV4dCkgPT4ge1xuICAgICAgICByZXR1cm4gZXhwcihjb250ZXh0KSA/IHRydWVFeHByKGNvbnRleHQpIDogZmFsc2VFeHByKGNvbnRleHQpO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICByZXR1cm4gZXhwcjtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VMb2dpY2FsT3IoKTogKGNvbnRleHQ6IEV4cHJlc3Npb25Db250ZXh0KSA9PiBhbnkge1xuICAgIGxldCBsZWZ0ID0gdGhpcy5wYXJzZUxvZ2ljYWxBbmQoKTtcblxuICAgIHdoaWxlICh0aGlzLmN1cnJlbnQoKS50eXBlID09PSBUb2tlblR5cGUuTE9HSUNBTCAmJiB0aGlzLmN1cnJlbnQoKS52YWx1ZSA9PT0gJ3x8Jykge1xuICAgICAgdGhpcy5jb25zdW1lKFRva2VuVHlwZS5MT0dJQ0FMKTtcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZUxvZ2ljYWxBbmQoKTtcbiAgICAgIGNvbnN0IHByZXZMZWZ0ID0gbGVmdDtcbiAgICAgIGxlZnQgPSAoY29udGV4dDogRXhwcmVzc2lvbkNvbnRleHQpID0+IHByZXZMZWZ0KGNvbnRleHQpIHx8IHJpZ2h0KGNvbnRleHQpO1xuICAgIH1cblxuICAgIHJldHVybiBsZWZ0O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUxvZ2ljYWxBbmQoKTogKGNvbnRleHQ6IEV4cHJlc3Npb25Db250ZXh0KSA9PiBhbnkge1xuICAgIGxldCBsZWZ0ID0gdGhpcy5wYXJzZUNvbXBhcmlzb24oKTtcblxuICAgIHdoaWxlICh0aGlzLmN1cnJlbnQoKS50eXBlID09PSBUb2tlblR5cGUuTE9HSUNBTCAmJiB0aGlzLmN1cnJlbnQoKS52YWx1ZSA9PT0gJyYmJykge1xuICAgICAgdGhpcy5jb25zdW1lKFRva2VuVHlwZS5MT0dJQ0FMKTtcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZUNvbXBhcmlzb24oKTtcbiAgICAgIGNvbnN0IHByZXZMZWZ0ID0gbGVmdDtcbiAgICAgIGxlZnQgPSAoY29udGV4dDogRXhwcmVzc2lvbkNvbnRleHQpID0+IHByZXZMZWZ0KGNvbnRleHQpICYmIHJpZ2h0KGNvbnRleHQpO1xuICAgIH1cblxuICAgIHJldHVybiBsZWZ0O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUNvbXBhcmlzb24oKTogKGNvbnRleHQ6IEV4cHJlc3Npb25Db250ZXh0KSA9PiBhbnkge1xuICAgIGNvbnN0IGxlZnQgPSB0aGlzLnBhcnNlQWRkaXRpdmUoKTtcblxuICAgIGlmICh0aGlzLmN1cnJlbnQoKS50eXBlID09PSBUb2tlblR5cGUuT1BFUkFUT1IpIHtcbiAgICAgIGNvbnN0IG9wID0gdGhpcy5jb25zdW1lKFRva2VuVHlwZS5PUEVSQVRPUikudmFsdWU7XG4gICAgICBjb25zdCByaWdodCA9IHRoaXMucGFyc2VBZGRpdGl2ZSgpO1xuXG4gICAgICByZXR1cm4gKGNvbnRleHQ6IEV4cHJlc3Npb25Db250ZXh0KSA9PiB7XG4gICAgICAgIGNvbnN0IGxlZnRWYWwgPSBsZWZ0KGNvbnRleHQpO1xuICAgICAgICBjb25zdCByaWdodFZhbCA9IHJpZ2h0KGNvbnRleHQpO1xuXG4gICAgICAgIHN3aXRjaCAob3ApIHtcbiAgICAgICAgICBjYXNlICc9PT0nOlxuICAgICAgICAgICAgcmV0dXJuIGxlZnRWYWwgPT09IHJpZ2h0VmFsO1xuICAgICAgICAgIGNhc2UgJyE9PSc6XG4gICAgICAgICAgICByZXR1cm4gbGVmdFZhbCAhPT0gcmlnaHRWYWw7XG4gICAgICAgICAgY2FzZSAnPT0nOlxuICAgICAgICAgICAgcmV0dXJuIGxlZnRWYWwgPT0gcmlnaHRWYWw7XG4gICAgICAgICAgY2FzZSAnIT0nOlxuICAgICAgICAgICAgcmV0dXJuIGxlZnRWYWwgIT0gcmlnaHRWYWw7XG4gICAgICAgICAgY2FzZSAnPCc6XG4gICAgICAgICAgICByZXR1cm4gbGVmdFZhbCA8IHJpZ2h0VmFsO1xuICAgICAgICAgIGNhc2UgJzw9JzpcbiAgICAgICAgICAgIHJldHVybiBsZWZ0VmFsIDw9IHJpZ2h0VmFsO1xuICAgICAgICAgIGNhc2UgJz4nOlxuICAgICAgICAgICAgcmV0dXJuIGxlZnRWYWwgPiByaWdodFZhbDtcbiAgICAgICAgICBjYXNlICc+PSc6XG4gICAgICAgICAgICByZXR1cm4gbGVmdFZhbCA+PSByaWdodFZhbDtcbiAgICAgICAgICBkZWZhdWx0OlxuICAgICAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbmtub3duIG9wZXJhdG9yOiAke29wfWApO1xuICAgICAgICB9XG4gICAgICB9O1xuICAgIH1cblxuICAgIHJldHVybiBsZWZ0O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUFkZGl0aXZlKCk6IChjb250ZXh0OiBFeHByZXNzaW9uQ29udGV4dCkgPT4gYW55IHtcbiAgICBsZXQgbGVmdCA9IHRoaXMucGFyc2VNdWx0aXBsaWNhdGl2ZSgpO1xuXG4gICAgd2hpbGUgKFxuICAgICAgdGhpcy5jdXJyZW50KCkudHlwZSA9PT0gVG9rZW5UeXBlLkFSSVRITUVUSUMgJiZcbiAgICAgICh0aGlzLmN1cnJlbnQoKS52YWx1ZSA9PT0gJysnIHx8IHRoaXMuY3VycmVudCgpLnZhbHVlID09PSAnLScpXG4gICAgKSB7XG4gICAgICBjb25zdCBvcCA9IHRoaXMuY29uc3VtZShUb2tlblR5cGUuQVJJVEhNRVRJQykudmFsdWU7XG4gICAgICBjb25zdCByaWdodCA9IHRoaXMucGFyc2VNdWx0aXBsaWNhdGl2ZSgpO1xuICAgICAgY29uc3QgcHJldkxlZnQgPSBsZWZ0O1xuXG4gICAgICBpZiAob3AgPT09ICcrJykge1xuICAgICAgICBsZWZ0ID0gKGNvbnRleHQ6IEV4cHJlc3Npb25Db250ZXh0KSA9PiBwcmV2TGVmdChjb250ZXh0KSArIHJpZ2h0KGNvbnRleHQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbGVmdCA9IChjb250ZXh0OiBFeHByZXNzaW9uQ29udGV4dCkgPT4gcHJldkxlZnQoY29udGV4dCkgLSByaWdodChjb250ZXh0KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gbGVmdDtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VNdWx0aXBsaWNhdGl2ZSgpOiAoY29udGV4dDogRXhwcmVzc2lvbkNvbnRleHQpID0+IGFueSB7XG4gICAgbGV0IGxlZnQgPSB0aGlzLnBhcnNlVW5hcnkoKTtcblxuICAgIHdoaWxlIChcbiAgICAgIHRoaXMuY3VycmVudCgpLnR5cGUgPT09IFRva2VuVHlwZS5BUklUSE1FVElDICYmXG4gICAgICAodGhpcy5jdXJyZW50KCkudmFsdWUgPT09ICcqJyB8fCB0aGlzLmN1cnJlbnQoKS52YWx1ZSA9PT0gJy8nIHx8IHRoaXMuY3VycmVudCgpLnZhbHVlID09PSAnJScpXG4gICAgKSB7XG4gICAgICBjb25zdCBvcCA9IHRoaXMuY29uc3VtZShUb2tlblR5cGUuQVJJVEhNRVRJQykudmFsdWU7XG4gICAgICBjb25zdCByaWdodCA9IHRoaXMucGFyc2VVbmFyeSgpO1xuICAgICAgY29uc3QgcHJldkxlZnQgPSBsZWZ0O1xuXG4gICAgICBpZiAob3AgPT09ICcqJykge1xuICAgICAgICBsZWZ0ID0gKGNvbnRleHQ6IEV4cHJlc3Npb25Db250ZXh0KSA9PiBwcmV2TGVmdChjb250ZXh0KSAqIHJpZ2h0KGNvbnRleHQpO1xuICAgICAgfSBlbHNlIGlmIChvcCA9PT0gJy8nKSB7XG4gICAgICAgIGxlZnQgPSAoY29udGV4dDogRXhwcmVzc2lvbkNvbnRleHQpID0+IHByZXZMZWZ0KGNvbnRleHQpIC8gcmlnaHQoY29udGV4dCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBsZWZ0ID0gKGNvbnRleHQ6IEV4cHJlc3Npb25Db250ZXh0KSA9PiBwcmV2TGVmdChjb250ZXh0KSAlIHJpZ2h0KGNvbnRleHQpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBsZWZ0O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVVuYXJ5KCk6IChjb250ZXh0OiBFeHByZXNzaW9uQ29udGV4dCkgPT4gYW55IHtcbiAgICBpZiAodGhpcy5jdXJyZW50KCkudHlwZSA9PT0gVG9rZW5UeXBlLk5PVCkge1xuICAgICAgdGhpcy5jb25zdW1lKFRva2VuVHlwZS5OT1QpO1xuICAgICAgY29uc3QgZXhwciA9IHRoaXMucGFyc2VVbmFyeSgpO1xuICAgICAgcmV0dXJuIChjb250ZXh0OiBFeHByZXNzaW9uQ29udGV4dCkgPT4gIWV4cHIoY29udGV4dCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMucGFyc2VQcmltYXJ5KCk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlUHJpbWFyeSgpOiAoY29udGV4dDogRXhwcmVzc2lvbkNvbnRleHQpID0+IGFueSB7XG4gICAgY29uc3QgdG9rZW4gPSB0aGlzLmN1cnJlbnQoKTtcblxuICAgIC8vIFBhcmVudGhlc2VzXG4gICAgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuVHlwZS5QQVJFTl9PUEVOKSB7XG4gICAgICB0aGlzLmNvbnN1bWUoVG9rZW5UeXBlLlBBUkVOX09QRU4pO1xuICAgICAgY29uc3QgZXhwciA9IHRoaXMucGFyc2VUZXJuYXJ5KCk7XG4gICAgICB0aGlzLmNvbnN1bWUoVG9rZW5UeXBlLlBBUkVOX0NMT1NFKTtcbiAgICAgIHJldHVybiBleHByO1xuICAgIH1cblxuICAgIC8vIExpdGVyYWxzXG4gICAgaWYgKFxuICAgICAgdG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLlNUUklORyB8fFxuICAgICAgdG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLk5VTUJFUiB8fFxuICAgICAgdG9rZW4udHlwZSA9PT0gVG9rZW5UeXBlLkJPT0xFQU4gfHxcbiAgICAgIHRva2VuLnR5cGUgPT09IFRva2VuVHlwZS5OVUxMIHx8XG4gICAgICB0b2tlbi50eXBlID09PSBUb2tlblR5cGUuVU5ERUZJTkVEXG4gICAgKSB7XG4gICAgICBjb25zdCB2YWx1ZSA9IHRva2VuLnZhbHVlO1xuICAgICAgdGhpcy5wb3MrKztcbiAgICAgIHJldHVybiAoKSA9PiB2YWx1ZTtcbiAgICB9XG5cbiAgICAvLyBQcm9wZXJ0eSBhY2Nlc3MgKG1vZGVsLmZpZWxkLCBmb3JtU3RhdGUucHJvcCwgZXRjKVxuICAgIGlmICh0b2tlbi50eXBlID09PSBUb2tlblR5cGUuSURFTlRJRklFUikge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VQcm9wZXJ0eUFjY2VzcygpO1xuICAgIH1cblxuICAgIHRocm93IG5ldyBFcnJvcihgVW5leHBlY3RlZCB0b2tlbjogJHtKU09OLnN0cmluZ2lmeSh0b2tlbil9YCk7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlUHJvcGVydHlBY2Nlc3MoKTogKGNvbnRleHQ6IEV4cHJlc3Npb25Db250ZXh0KSA9PiBhbnkge1xuICAgIGNvbnN0IHBhdGg6IEFycmF5PHN0cmluZyB8ICgoY29udGV4dDogRXhwcmVzc2lvbkNvbnRleHQpID0+IGFueSk+ID0gW107XG5cbiAgICAvLyBSZWFkIGZpcnN0IGlkZW50aWZpZXJcbiAgICBwYXRoLnB1c2godGhpcy5jb25zdW1lKFRva2VuVHlwZS5JREVOVElGSUVSKS52YWx1ZSk7XG5cbiAgICAvLyBSZWFkIHJlc3Qgb2YgcGF0aCAoZG90cyBhbmQgYnJhY2tldHMpXG4gICAgd2hpbGUgKHRoaXMuY3VycmVudCgpLnR5cGUgPT09IFRva2VuVHlwZS5ET1QgfHwgdGhpcy5jdXJyZW50KCkudHlwZSA9PT0gVG9rZW5UeXBlLkJSQUNLRVRfT1BFTikge1xuICAgICAgaWYgKHRoaXMuY3VycmVudCgpLnR5cGUgPT09IFRva2VuVHlwZS5ET1QpIHtcbiAgICAgICAgdGhpcy5jb25zdW1lKFRva2VuVHlwZS5ET1QpO1xuICAgICAgICBwYXRoLnB1c2godGhpcy5jb25zdW1lKFRva2VuVHlwZS5JREVOVElGSUVSKS52YWx1ZSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmNvbnN1bWUoVG9rZW5UeXBlLkJSQUNLRVRfT1BFTik7XG5cbiAgICAgICAgLy8gYnJhY2tldCBub3RhdGlvbiBjYW4gY29udGFpbiBleHByZXNzaW9uc1xuICAgICAgICBpZiAodGhpcy5jdXJyZW50KCkudHlwZSA9PT0gVG9rZW5UeXBlLlNUUklORykge1xuICAgICAgICAgIHBhdGgucHVzaCh0aGlzLmNvbnN1bWUoVG9rZW5UeXBlLlNUUklORykudmFsdWUpO1xuICAgICAgICB9IGVsc2UgaWYgKHRoaXMuY3VycmVudCgpLnR5cGUgPT09IFRva2VuVHlwZS5OVU1CRVIpIHtcbiAgICAgICAgICBwYXRoLnB1c2goU3RyaW5nKHRoaXMuY29uc3VtZShUb2tlblR5cGUuTlVNQkVSKS52YWx1ZSkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIGR5bmFtaWMgcHJvcGVydHkgYWNjZXNzXG4gICAgICAgICAgY29uc3QgZXhwciA9IHRoaXMucGFyc2VUZXJuYXJ5KCk7XG4gICAgICAgICAgcGF0aC5wdXNoKGV4cHIpO1xuICAgICAgICB9XG5cbiAgICAgICAgdGhpcy5jb25zdW1lKFRva2VuVHlwZS5CUkFDS0VUX0NMT1NFKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gKGNvbnRleHQ6IEV4cHJlc3Npb25Db250ZXh0KSA9PiB7XG4gICAgICBsZXQgdmFsdWU6IGFueSA9IGNvbnRleHQ7XG5cbiAgICAgIGZvciAoY29uc3Qgc2VnbWVudCBvZiBwYXRoKSB7XG4gICAgICAgIGlmICh2YWx1ZSA9PT0gbnVsbCB8fCB2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0eXBlb2Ygc2VnbWVudCA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgICAgIHZhbHVlID0gdmFsdWVbc2VnbWVudChjb250ZXh0KV07XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWUgPSB2YWx1ZVtzZWdtZW50XTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfTtcbiAgfVxuXG4gIHByaXZhdGUgY3VycmVudCgpOiBUb2tlbiB7XG4gICAgcmV0dXJuIHRoaXMudG9rZW5zW3RoaXMucG9zXTtcbiAgfVxuXG4gIHByaXZhdGUgY29uc3VtZShleHBlY3RlZFR5cGU6IFRva2VuVHlwZSk6IFRva2VuIHtcbiAgICBjb25zdCB0b2tlbiA9IHRoaXMuY3VycmVudCgpO1xuXG4gICAgaWYgKHRva2VuLnR5cGUgIT09IGV4cGVjdGVkVHlwZSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCAke2V4cGVjdGVkVHlwZX0sIGdvdCAke3Rva2VuLnR5cGV9YCk7XG4gICAgfVxuXG4gICAgdGhpcy5wb3MrKztcbiAgICByZXR1cm4gdG9rZW47XG4gIH1cbn1cblxuLyoqXG4gKiBVc2VzIENTUC1zYWZlIGltcGxlbWVudGF0aW9uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBwYXJzZUV4cHJlc3Npb24oZXhwcmVzc2lvbjogc3RyaW5nLCBhcmdOYW1lczogc3RyaW5nW10pOiBhbnkge1xuICB0cnkge1xuICAgIGNvbnN0IHRva2VuaXplciA9IG5ldyBUb2tlbml6ZXIoZXhwcmVzc2lvbik7XG4gICAgY29uc3QgdG9rZW5zID0gdG9rZW5pemVyLnRva2VuaXplKCk7XG4gICAgY29uc3QgcGFyc2VyID0gbmV3IEV4cHJlc3Npb25QYXJzZXIodG9rZW5zKTtcbiAgICBjb25zdCBldmFsdWF0b3IgPSBwYXJzZXIucGFyc2UoKTtcblxuICAgIC8vIFJldHVybiBhIGZ1bmN0aW9uIHRoYXQgbWFwcyB0aGUgYXJncyB0byB0aGUgY29udGV4dFxuICAgIHJldHVybiAoLi4uYXJnczogYW55W10pID0+IHtcbiAgICAgIGNvbnN0IGNvbnRleHQ6IGFueSA9IHt9O1xuICAgICAgYXJnTmFtZXMuZm9yRWFjaCgobmFtZSwgaSkgPT4ge1xuICAgICAgICBjb250ZXh0W25hbWVdID0gYXJnc1tpXTtcbiAgICAgIH0pO1xuICAgICAgcmV0dXJuIGV2YWx1YXRvcihjb250ZXh0KTtcbiAgICB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIGNvbnNvbGUuZXJyb3IoJ0V4cHJlc3Npb24gcGFyc2UgZXJyb3I6JywgZXJyb3IpO1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cbn1cbiJdfQ==
|