@angular/compiler 16.0.0-next.4 → 16.0.0-next.5

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.
Files changed (122) hide show
  1. package/esm2022/src/compiler_util/expression_converter.mjs +759 -0
  2. package/{esm2020 → esm2022}/src/expression_parser/parser.mjs +3 -2
  3. package/esm2022/src/i18n/digest.mjs +357 -0
  4. package/esm2022/src/i18n/i18n_ast.mjs +184 -0
  5. package/{esm2020 → esm2022}/src/render3/partial/class_metadata.mjs +1 -1
  6. package/{esm2020 → esm2022}/src/render3/partial/directive.mjs +1 -1
  7. package/{esm2020 → esm2022}/src/render3/partial/factory.mjs +1 -1
  8. package/{esm2020 → esm2022}/src/render3/partial/injectable.mjs +1 -1
  9. package/{esm2020 → esm2022}/src/render3/partial/injector.mjs +1 -1
  10. package/{esm2020 → esm2022}/src/render3/partial/ng_module.mjs +1 -1
  11. package/{esm2020 → esm2022}/src/render3/partial/pipe.mjs +1 -1
  12. package/esm2022/src/render3/r3_identifiers.mjs +214 -0
  13. package/esm2022/src/render3/view/i18n/meta.mjs +243 -0
  14. package/esm2022/src/render3/view/style_parser.mjs +86 -0
  15. package/{esm2020 → esm2022}/src/version.mjs +1 -1
  16. package/{fesm2020 → fesm2022}/compiler.mjs +221 -238
  17. package/fesm2022/compiler.mjs.map +1 -0
  18. package/{fesm2015 → fesm2022}/testing.mjs +1 -1
  19. package/index.d.ts +1 -1
  20. package/package.json +9 -17
  21. package/testing/index.d.ts +1 -1
  22. package/esm2020/src/compiler_util/expression_converter.mjs +0 -759
  23. package/esm2020/src/i18n/digest.mjs +0 -357
  24. package/esm2020/src/i18n/i18n_ast.mjs +0 -184
  25. package/esm2020/src/render3/r3_identifiers.mjs +0 -214
  26. package/esm2020/src/render3/view/i18n/meta.mjs +0 -244
  27. package/esm2020/src/render3/view/style_parser.mjs +0 -103
  28. package/fesm2015/compiler.mjs +0 -22352
  29. package/fesm2015/compiler.mjs.map +0 -1
  30. package/fesm2020/compiler.mjs.map +0 -1
  31. package/fesm2020/testing.mjs +0 -39
  32. package/fesm2020/testing.mjs.map +0 -1
  33. /package/{esm2020 → esm2022}/compiler.mjs +0 -0
  34. /package/{esm2020 → esm2022}/index.mjs +0 -0
  35. /package/{esm2020 → esm2022}/public_api.mjs +0 -0
  36. /package/{esm2020 → esm2022}/src/assertions.mjs +0 -0
  37. /package/{esm2020 → esm2022}/src/chars.mjs +0 -0
  38. /package/{esm2020 → esm2022}/src/compiler.mjs +0 -0
  39. /package/{esm2020 → esm2022}/src/compiler_facade_interface.mjs +0 -0
  40. /package/{esm2020 → esm2022}/src/config.mjs +0 -0
  41. /package/{esm2020 → esm2022}/src/constant_pool.mjs +0 -0
  42. /package/{esm2020 → esm2022}/src/core.mjs +0 -0
  43. /package/{esm2020 → esm2022}/src/expression_parser/ast.mjs +0 -0
  44. /package/{esm2020 → esm2022}/src/expression_parser/lexer.mjs +0 -0
  45. /package/{esm2020 → esm2022}/src/i18n/big_integer.mjs +0 -0
  46. /package/{esm2020 → esm2022}/src/i18n/extractor_merger.mjs +0 -0
  47. /package/{esm2020 → esm2022}/src/i18n/i18n_html_parser.mjs +0 -0
  48. /package/{esm2020 → esm2022}/src/i18n/i18n_parser.mjs +0 -0
  49. /package/{esm2020 → esm2022}/src/i18n/index.mjs +0 -0
  50. /package/{esm2020 → esm2022}/src/i18n/message_bundle.mjs +0 -0
  51. /package/{esm2020 → esm2022}/src/i18n/parse_util.mjs +0 -0
  52. /package/{esm2020 → esm2022}/src/i18n/serializers/placeholder.mjs +0 -0
  53. /package/{esm2020 → esm2022}/src/i18n/serializers/serializer.mjs +0 -0
  54. /package/{esm2020 → esm2022}/src/i18n/serializers/xliff.mjs +0 -0
  55. /package/{esm2020 → esm2022}/src/i18n/serializers/xliff2.mjs +0 -0
  56. /package/{esm2020 → esm2022}/src/i18n/serializers/xmb.mjs +0 -0
  57. /package/{esm2020 → esm2022}/src/i18n/serializers/xml_helper.mjs +0 -0
  58. /package/{esm2020 → esm2022}/src/i18n/serializers/xtb.mjs +0 -0
  59. /package/{esm2020 → esm2022}/src/i18n/translation_bundle.mjs +0 -0
  60. /package/{esm2020 → esm2022}/src/injectable_compiler_2.mjs +0 -0
  61. /package/{esm2020 → esm2022}/src/jit_compiler_facade.mjs +0 -0
  62. /package/{esm2020 → esm2022}/src/ml_parser/ast.mjs +0 -0
  63. /package/{esm2020 → esm2022}/src/ml_parser/entities.mjs +0 -0
  64. /package/{esm2020 → esm2022}/src/ml_parser/html_parser.mjs +0 -0
  65. /package/{esm2020 → esm2022}/src/ml_parser/html_tags.mjs +0 -0
  66. /package/{esm2020 → esm2022}/src/ml_parser/html_whitespaces.mjs +0 -0
  67. /package/{esm2020 → esm2022}/src/ml_parser/icu_ast_expander.mjs +0 -0
  68. /package/{esm2020 → esm2022}/src/ml_parser/interpolation_config.mjs +0 -0
  69. /package/{esm2020 → esm2022}/src/ml_parser/lexer.mjs +0 -0
  70. /package/{esm2020 → esm2022}/src/ml_parser/parser.mjs +0 -0
  71. /package/{esm2020 → esm2022}/src/ml_parser/tags.mjs +0 -0
  72. /package/{esm2020 → esm2022}/src/ml_parser/tokens.mjs +0 -0
  73. /package/{esm2020 → esm2022}/src/ml_parser/xml_parser.mjs +0 -0
  74. /package/{esm2020 → esm2022}/src/ml_parser/xml_tags.mjs +0 -0
  75. /package/{esm2020 → esm2022}/src/output/abstract_emitter.mjs +0 -0
  76. /package/{esm2020 → esm2022}/src/output/abstract_js_emitter.mjs +0 -0
  77. /package/{esm2020 → esm2022}/src/output/map_util.mjs +0 -0
  78. /package/{esm2020 → esm2022}/src/output/output_ast.mjs +0 -0
  79. /package/{esm2020 → esm2022}/src/output/output_jit.mjs +0 -0
  80. /package/{esm2020 → esm2022}/src/output/output_jit_trusted_types.mjs +0 -0
  81. /package/{esm2020 → esm2022}/src/output/source_map.mjs +0 -0
  82. /package/{esm2020 → esm2022}/src/parse_util.mjs +0 -0
  83. /package/{esm2020 → esm2022}/src/render3/partial/api.mjs +0 -0
  84. /package/{esm2020 → esm2022}/src/render3/partial/component.mjs +0 -0
  85. /package/{esm2020 → esm2022}/src/render3/partial/util.mjs +0 -0
  86. /package/{esm2020 → esm2022}/src/render3/r3_ast.mjs +0 -0
  87. /package/{esm2020 → esm2022}/src/render3/r3_class_metadata_compiler.mjs +0 -0
  88. /package/{esm2020 → esm2022}/src/render3/r3_factory.mjs +0 -0
  89. /package/{esm2020 → esm2022}/src/render3/r3_injector_compiler.mjs +0 -0
  90. /package/{esm2020 → esm2022}/src/render3/r3_jit.mjs +0 -0
  91. /package/{esm2020 → esm2022}/src/render3/r3_module_compiler.mjs +0 -0
  92. /package/{esm2020 → esm2022}/src/render3/r3_pipe_compiler.mjs +0 -0
  93. /package/{esm2020 → esm2022}/src/render3/r3_template_transform.mjs +0 -0
  94. /package/{esm2020 → esm2022}/src/render3/util.mjs +0 -0
  95. /package/{esm2020 → esm2022}/src/render3/view/api.mjs +0 -0
  96. /package/{esm2020 → esm2022}/src/render3/view/compiler.mjs +0 -0
  97. /package/{esm2020 → esm2022}/src/render3/view/i18n/context.mjs +0 -0
  98. /package/{esm2020 → esm2022}/src/render3/view/i18n/get_msg_utils.mjs +0 -0
  99. /package/{esm2020 → esm2022}/src/render3/view/i18n/icu_serializer.mjs +0 -0
  100. /package/{esm2020 → esm2022}/src/render3/view/i18n/localize_utils.mjs +0 -0
  101. /package/{esm2020 → esm2022}/src/render3/view/i18n/util.mjs +0 -0
  102. /package/{esm2020 → esm2022}/src/render3/view/styling_builder.mjs +0 -0
  103. /package/{esm2020 → esm2022}/src/render3/view/t2_api.mjs +0 -0
  104. /package/{esm2020 → esm2022}/src/render3/view/t2_binder.mjs +0 -0
  105. /package/{esm2020 → esm2022}/src/render3/view/template.mjs +0 -0
  106. /package/{esm2020 → esm2022}/src/render3/view/util.mjs +0 -0
  107. /package/{esm2020 → esm2022}/src/resource_loader.mjs +0 -0
  108. /package/{esm2020 → esm2022}/src/schema/dom_element_schema_registry.mjs +0 -0
  109. /package/{esm2020 → esm2022}/src/schema/dom_security_schema.mjs +0 -0
  110. /package/{esm2020 → esm2022}/src/schema/element_schema_registry.mjs +0 -0
  111. /package/{esm2020 → esm2022}/src/schema/trusted_types_sinks.mjs +0 -0
  112. /package/{esm2020 → esm2022}/src/selector.mjs +0 -0
  113. /package/{esm2020 → esm2022}/src/shadow_css.mjs +0 -0
  114. /package/{esm2020 → esm2022}/src/style_url_resolver.mjs +0 -0
  115. /package/{esm2020 → esm2022}/src/template_parser/binding_parser.mjs +0 -0
  116. /package/{esm2020 → esm2022}/src/template_parser/template_preparser.mjs +0 -0
  117. /package/{esm2020 → esm2022}/src/util.mjs +0 -0
  118. /package/{esm2020 → esm2022}/testing/index.mjs +0 -0
  119. /package/{esm2020 → esm2022}/testing/public_api.mjs +0 -0
  120. /package/{esm2020 → esm2022}/testing/src/testing.mjs +0 -0
  121. /package/{esm2020 → esm2022}/testing/testing.mjs +0 -0
  122. /package/{fesm2015 → fesm2022}/testing.mjs.map +0 -0
@@ -0,0 +1,759 @@
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 cdAst from '../expression_parser/ast';
9
+ import * as o from '../output/output_ast';
10
+ import { ParseSourceSpan } from '../parse_util';
11
+ class EventHandlerVars {
12
+ static { this.event = o.variable('$event'); }
13
+ }
14
+ export { EventHandlerVars };
15
+ /**
16
+ * Converts the given expression AST into an executable output AST, assuming the expression is
17
+ * used in an action binding (e.g. an event handler).
18
+ */
19
+ export function convertActionBinding(localResolver, implicitReceiver, action, bindingId, baseSourceSpan, implicitReceiverAccesses, globals) {
20
+ if (!localResolver) {
21
+ localResolver = new DefaultLocalResolver(globals);
22
+ }
23
+ const actionWithoutBuiltins = convertPropertyBindingBuiltins({
24
+ createLiteralArrayConverter: (argCount) => {
25
+ // Note: no caching for literal arrays in actions.
26
+ return (args) => o.literalArr(args);
27
+ },
28
+ createLiteralMapConverter: (keys) => {
29
+ // Note: no caching for literal maps in actions.
30
+ return (values) => {
31
+ const entries = keys.map((k, i) => ({
32
+ key: k.key,
33
+ value: values[i],
34
+ quoted: k.quoted,
35
+ }));
36
+ return o.literalMap(entries);
37
+ };
38
+ },
39
+ createPipeConverter: (name) => {
40
+ throw new Error(`Illegal State: Actions are not allowed to contain pipes. Pipe: ${name}`);
41
+ }
42
+ }, action);
43
+ const visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId, /* supportsInterpolation */ false, baseSourceSpan, implicitReceiverAccesses);
44
+ const actionStmts = [];
45
+ flattenStatements(actionWithoutBuiltins.visit(visitor, _Mode.Statement), actionStmts);
46
+ prependTemporaryDecls(visitor.temporaryCount, bindingId, actionStmts);
47
+ if (visitor.usesImplicitReceiver) {
48
+ localResolver.notifyImplicitReceiverUse();
49
+ }
50
+ const lastIndex = actionStmts.length - 1;
51
+ if (lastIndex >= 0) {
52
+ const lastStatement = actionStmts[lastIndex];
53
+ // Ensure that the value of the last expression statement is returned
54
+ if (lastStatement instanceof o.ExpressionStatement) {
55
+ actionStmts[lastIndex] = new o.ReturnStatement(lastStatement.expr);
56
+ }
57
+ }
58
+ return actionStmts;
59
+ }
60
+ export function convertPropertyBindingBuiltins(converterFactory, ast) {
61
+ return convertBuiltins(converterFactory, ast);
62
+ }
63
+ export class ConvertPropertyBindingResult {
64
+ constructor(stmts, currValExpr) {
65
+ this.stmts = stmts;
66
+ this.currValExpr = currValExpr;
67
+ }
68
+ }
69
+ /**
70
+ * Converts the given expression AST into an executable output AST, assuming the expression
71
+ * is used in property binding. The expression has to be preprocessed via
72
+ * `convertPropertyBindingBuiltins`.
73
+ */
74
+ export function convertPropertyBinding(localResolver, implicitReceiver, expressionWithoutBuiltins, bindingId) {
75
+ if (!localResolver) {
76
+ localResolver = new DefaultLocalResolver();
77
+ }
78
+ const visitor = new _AstToIrVisitor(localResolver, implicitReceiver, bindingId, /* supportsInterpolation */ false);
79
+ const outputExpr = expressionWithoutBuiltins.visit(visitor, _Mode.Expression);
80
+ const stmts = getStatementsFromVisitor(visitor, bindingId);
81
+ if (visitor.usesImplicitReceiver) {
82
+ localResolver.notifyImplicitReceiverUse();
83
+ }
84
+ return new ConvertPropertyBindingResult(stmts, outputExpr);
85
+ }
86
+ /**
87
+ * Given some expression, such as a binding or interpolation expression, and a context expression to
88
+ * look values up on, visit each facet of the given expression resolving values from the context
89
+ * expression such that a list of arguments can be derived from the found values that can be used as
90
+ * arguments to an external update instruction.
91
+ *
92
+ * @param localResolver The resolver to use to look up expressions by name appropriately
93
+ * @param contextVariableExpression The expression representing the context variable used to create
94
+ * the final argument expressions
95
+ * @param expressionWithArgumentsToExtract The expression to visit to figure out what values need to
96
+ * be resolved and what arguments list to build.
97
+ * @param bindingId A name prefix used to create temporary variable names if they're needed for the
98
+ * arguments generated
99
+ * @returns An array of expressions that can be passed as arguments to instruction expressions like
100
+ * `o.importExpr(R3.propertyInterpolate).callFn(result)`
101
+ */
102
+ export function convertUpdateArguments(localResolver, contextVariableExpression, expressionWithArgumentsToExtract, bindingId) {
103
+ const visitor = new _AstToIrVisitor(localResolver, contextVariableExpression, bindingId, /* supportsInterpolation */ true);
104
+ const outputExpr = visitor.visitInterpolation(expressionWithArgumentsToExtract, _Mode.Expression);
105
+ if (visitor.usesImplicitReceiver) {
106
+ localResolver.notifyImplicitReceiverUse();
107
+ }
108
+ const stmts = getStatementsFromVisitor(visitor, bindingId);
109
+ const args = outputExpr.args;
110
+ return { stmts, args };
111
+ }
112
+ function getStatementsFromVisitor(visitor, bindingId) {
113
+ const stmts = [];
114
+ for (let i = 0; i < visitor.temporaryCount; i++) {
115
+ stmts.push(temporaryDeclaration(bindingId, i));
116
+ }
117
+ return stmts;
118
+ }
119
+ function convertBuiltins(converterFactory, ast) {
120
+ const visitor = new _BuiltinAstConverter(converterFactory);
121
+ return ast.visit(visitor);
122
+ }
123
+ function temporaryName(bindingId, temporaryNumber) {
124
+ return `tmp_${bindingId}_${temporaryNumber}`;
125
+ }
126
+ function temporaryDeclaration(bindingId, temporaryNumber) {
127
+ return new o.DeclareVarStmt(temporaryName(bindingId, temporaryNumber));
128
+ }
129
+ function prependTemporaryDecls(temporaryCount, bindingId, statements) {
130
+ for (let i = temporaryCount - 1; i >= 0; i--) {
131
+ statements.unshift(temporaryDeclaration(bindingId, i));
132
+ }
133
+ }
134
+ var _Mode;
135
+ (function (_Mode) {
136
+ _Mode[_Mode["Statement"] = 0] = "Statement";
137
+ _Mode[_Mode["Expression"] = 1] = "Expression";
138
+ })(_Mode || (_Mode = {}));
139
+ function ensureStatementMode(mode, ast) {
140
+ if (mode !== _Mode.Statement) {
141
+ throw new Error(`Expected a statement, but saw ${ast}`);
142
+ }
143
+ }
144
+ function ensureExpressionMode(mode, ast) {
145
+ if (mode !== _Mode.Expression) {
146
+ throw new Error(`Expected an expression, but saw ${ast}`);
147
+ }
148
+ }
149
+ function convertToStatementIfNeeded(mode, expr) {
150
+ if (mode === _Mode.Statement) {
151
+ return expr.toStmt();
152
+ }
153
+ else {
154
+ return expr;
155
+ }
156
+ }
157
+ class _BuiltinAstConverter extends cdAst.AstTransformer {
158
+ constructor(_converterFactory) {
159
+ super();
160
+ this._converterFactory = _converterFactory;
161
+ }
162
+ visitPipe(ast, context) {
163
+ const args = [ast.exp, ...ast.args].map(ast => ast.visit(this, context));
164
+ return new BuiltinFunctionCall(ast.span, ast.sourceSpan, args, this._converterFactory.createPipeConverter(ast.name, args.length));
165
+ }
166
+ visitLiteralArray(ast, context) {
167
+ const args = ast.expressions.map(ast => ast.visit(this, context));
168
+ return new BuiltinFunctionCall(ast.span, ast.sourceSpan, args, this._converterFactory.createLiteralArrayConverter(ast.expressions.length));
169
+ }
170
+ visitLiteralMap(ast, context) {
171
+ const args = ast.values.map(ast => ast.visit(this, context));
172
+ return new BuiltinFunctionCall(ast.span, ast.sourceSpan, args, this._converterFactory.createLiteralMapConverter(ast.keys));
173
+ }
174
+ }
175
+ class _AstToIrVisitor {
176
+ constructor(_localResolver, _implicitReceiver, bindingId, supportsInterpolation, baseSourceSpan, implicitReceiverAccesses) {
177
+ this._localResolver = _localResolver;
178
+ this._implicitReceiver = _implicitReceiver;
179
+ this.bindingId = bindingId;
180
+ this.supportsInterpolation = supportsInterpolation;
181
+ this.baseSourceSpan = baseSourceSpan;
182
+ this.implicitReceiverAccesses = implicitReceiverAccesses;
183
+ this._nodeMap = new Map();
184
+ this._resultMap = new Map();
185
+ this._currentTemporary = 0;
186
+ this.temporaryCount = 0;
187
+ this.usesImplicitReceiver = false;
188
+ }
189
+ visitUnary(ast, mode) {
190
+ let op;
191
+ switch (ast.operator) {
192
+ case '+':
193
+ op = o.UnaryOperator.Plus;
194
+ break;
195
+ case '-':
196
+ op = o.UnaryOperator.Minus;
197
+ break;
198
+ default:
199
+ throw new Error(`Unsupported operator ${ast.operator}`);
200
+ }
201
+ return convertToStatementIfNeeded(mode, new o.UnaryOperatorExpr(op, this._visit(ast.expr, _Mode.Expression), undefined, this.convertSourceSpan(ast.span)));
202
+ }
203
+ visitBinary(ast, mode) {
204
+ let op;
205
+ switch (ast.operation) {
206
+ case '+':
207
+ op = o.BinaryOperator.Plus;
208
+ break;
209
+ case '-':
210
+ op = o.BinaryOperator.Minus;
211
+ break;
212
+ case '*':
213
+ op = o.BinaryOperator.Multiply;
214
+ break;
215
+ case '/':
216
+ op = o.BinaryOperator.Divide;
217
+ break;
218
+ case '%':
219
+ op = o.BinaryOperator.Modulo;
220
+ break;
221
+ case '&&':
222
+ op = o.BinaryOperator.And;
223
+ break;
224
+ case '||':
225
+ op = o.BinaryOperator.Or;
226
+ break;
227
+ case '==':
228
+ op = o.BinaryOperator.Equals;
229
+ break;
230
+ case '!=':
231
+ op = o.BinaryOperator.NotEquals;
232
+ break;
233
+ case '===':
234
+ op = o.BinaryOperator.Identical;
235
+ break;
236
+ case '!==':
237
+ op = o.BinaryOperator.NotIdentical;
238
+ break;
239
+ case '<':
240
+ op = o.BinaryOperator.Lower;
241
+ break;
242
+ case '>':
243
+ op = o.BinaryOperator.Bigger;
244
+ break;
245
+ case '<=':
246
+ op = o.BinaryOperator.LowerEquals;
247
+ break;
248
+ case '>=':
249
+ op = o.BinaryOperator.BiggerEquals;
250
+ break;
251
+ case '??':
252
+ return this.convertNullishCoalesce(ast, mode);
253
+ default:
254
+ throw new Error(`Unsupported operation ${ast.operation}`);
255
+ }
256
+ return convertToStatementIfNeeded(mode, new o.BinaryOperatorExpr(op, this._visit(ast.left, _Mode.Expression), this._visit(ast.right, _Mode.Expression), undefined, this.convertSourceSpan(ast.span)));
257
+ }
258
+ visitChain(ast, mode) {
259
+ ensureStatementMode(mode, ast);
260
+ return this.visitAll(ast.expressions, mode);
261
+ }
262
+ visitConditional(ast, mode) {
263
+ const value = this._visit(ast.condition, _Mode.Expression);
264
+ return convertToStatementIfNeeded(mode, value.conditional(this._visit(ast.trueExp, _Mode.Expression), this._visit(ast.falseExp, _Mode.Expression), this.convertSourceSpan(ast.span)));
265
+ }
266
+ visitPipe(ast, mode) {
267
+ throw new Error(`Illegal state: Pipes should have been converted into functions. Pipe: ${ast.name}`);
268
+ }
269
+ visitImplicitReceiver(ast, mode) {
270
+ ensureExpressionMode(mode, ast);
271
+ this.usesImplicitReceiver = true;
272
+ return this._implicitReceiver;
273
+ }
274
+ visitThisReceiver(ast, mode) {
275
+ return this.visitImplicitReceiver(ast, mode);
276
+ }
277
+ visitInterpolation(ast, mode) {
278
+ if (!this.supportsInterpolation) {
279
+ throw new Error('Unexpected interpolation');
280
+ }
281
+ ensureExpressionMode(mode, ast);
282
+ let args = [];
283
+ for (let i = 0; i < ast.strings.length - 1; i++) {
284
+ args.push(o.literal(ast.strings[i]));
285
+ args.push(this._visit(ast.expressions[i], _Mode.Expression));
286
+ }
287
+ args.push(o.literal(ast.strings[ast.strings.length - 1]));
288
+ // If we're dealing with an interpolation of 1 value with an empty prefix and suffix, reduce the
289
+ // args returned to just the value, because we're going to pass it to a special instruction.
290
+ const strings = ast.strings;
291
+ if (strings.length === 2 && strings[0] === '' && strings[1] === '') {
292
+ // Single argument interpolate instructions.
293
+ args = [args[1]];
294
+ }
295
+ else if (ast.expressions.length >= 9) {
296
+ // 9 or more arguments must be passed to the `interpolateV`-style instructions, which accept
297
+ // an array of arguments
298
+ args = [o.literalArr(args)];
299
+ }
300
+ return new InterpolationExpression(args);
301
+ }
302
+ visitKeyedRead(ast, mode) {
303
+ const leftMostSafe = this.leftMostSafeNode(ast);
304
+ if (leftMostSafe) {
305
+ return this.convertSafeAccess(ast, leftMostSafe, mode);
306
+ }
307
+ else {
308
+ return convertToStatementIfNeeded(mode, this._visit(ast.receiver, _Mode.Expression).key(this._visit(ast.key, _Mode.Expression)));
309
+ }
310
+ }
311
+ visitKeyedWrite(ast, mode) {
312
+ const obj = this._visit(ast.receiver, _Mode.Expression);
313
+ const key = this._visit(ast.key, _Mode.Expression);
314
+ const value = this._visit(ast.value, _Mode.Expression);
315
+ if (obj === this._implicitReceiver) {
316
+ this._localResolver.maybeRestoreView();
317
+ }
318
+ return convertToStatementIfNeeded(mode, obj.key(key).set(value));
319
+ }
320
+ visitLiteralArray(ast, mode) {
321
+ throw new Error(`Illegal State: literal arrays should have been converted into functions`);
322
+ }
323
+ visitLiteralMap(ast, mode) {
324
+ throw new Error(`Illegal State: literal maps should have been converted into functions`);
325
+ }
326
+ visitLiteralPrimitive(ast, mode) {
327
+ // For literal values of null, undefined, true, or false allow type interference
328
+ // to infer the type.
329
+ const type = ast.value === null || ast.value === undefined || ast.value === true || ast.value === true ?
330
+ o.INFERRED_TYPE :
331
+ undefined;
332
+ return convertToStatementIfNeeded(mode, o.literal(ast.value, type, this.convertSourceSpan(ast.span)));
333
+ }
334
+ _getLocal(name, receiver) {
335
+ if (this._localResolver.globals?.has(name) && receiver instanceof cdAst.ThisReceiver) {
336
+ return null;
337
+ }
338
+ return this._localResolver.getLocal(name);
339
+ }
340
+ visitPrefixNot(ast, mode) {
341
+ return convertToStatementIfNeeded(mode, o.not(this._visit(ast.expression, _Mode.Expression)));
342
+ }
343
+ visitNonNullAssert(ast, mode) {
344
+ return convertToStatementIfNeeded(mode, this._visit(ast.expression, _Mode.Expression));
345
+ }
346
+ visitPropertyRead(ast, mode) {
347
+ const leftMostSafe = this.leftMostSafeNode(ast);
348
+ if (leftMostSafe) {
349
+ return this.convertSafeAccess(ast, leftMostSafe, mode);
350
+ }
351
+ else {
352
+ let result = null;
353
+ const prevUsesImplicitReceiver = this.usesImplicitReceiver;
354
+ const receiver = this._visit(ast.receiver, _Mode.Expression);
355
+ if (receiver === this._implicitReceiver) {
356
+ result = this._getLocal(ast.name, ast.receiver);
357
+ if (result) {
358
+ // Restore the previous "usesImplicitReceiver" state since the implicit
359
+ // receiver has been replaced with a resolved local expression.
360
+ this.usesImplicitReceiver = prevUsesImplicitReceiver;
361
+ this.addImplicitReceiverAccess(ast.name);
362
+ }
363
+ }
364
+ if (result == null) {
365
+ result = receiver.prop(ast.name, this.convertSourceSpan(ast.span));
366
+ }
367
+ return convertToStatementIfNeeded(mode, result);
368
+ }
369
+ }
370
+ visitPropertyWrite(ast, mode) {
371
+ const receiver = this._visit(ast.receiver, _Mode.Expression);
372
+ const prevUsesImplicitReceiver = this.usesImplicitReceiver;
373
+ let varExpr = null;
374
+ if (receiver === this._implicitReceiver) {
375
+ const localExpr = this._getLocal(ast.name, ast.receiver);
376
+ if (localExpr) {
377
+ if (localExpr instanceof o.ReadPropExpr) {
378
+ // If the local variable is a property read expression, it's a reference
379
+ // to a 'context.property' value and will be used as the target of the
380
+ // write expression.
381
+ varExpr = localExpr;
382
+ // Restore the previous "usesImplicitReceiver" state since the implicit
383
+ // receiver has been replaced with a resolved local expression.
384
+ this.usesImplicitReceiver = prevUsesImplicitReceiver;
385
+ this.addImplicitReceiverAccess(ast.name);
386
+ }
387
+ else {
388
+ // Otherwise it's an error.
389
+ const receiver = ast.name;
390
+ const value = (ast.value instanceof cdAst.PropertyRead) ? ast.value.name : undefined;
391
+ throw new Error(`Cannot assign value "${value}" to template variable "${receiver}". Template variables are read-only.`);
392
+ }
393
+ }
394
+ }
395
+ // If no local expression could be produced, use the original receiver's
396
+ // property as the target.
397
+ if (varExpr === null) {
398
+ varExpr = receiver.prop(ast.name, this.convertSourceSpan(ast.span));
399
+ }
400
+ return convertToStatementIfNeeded(mode, varExpr.set(this._visit(ast.value, _Mode.Expression)));
401
+ }
402
+ visitSafePropertyRead(ast, mode) {
403
+ return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode);
404
+ }
405
+ visitSafeKeyedRead(ast, mode) {
406
+ return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode);
407
+ }
408
+ visitAll(asts, mode) {
409
+ return asts.map(ast => this._visit(ast, mode));
410
+ }
411
+ visitCall(ast, mode) {
412
+ const leftMostSafe = this.leftMostSafeNode(ast);
413
+ if (leftMostSafe) {
414
+ return this.convertSafeAccess(ast, leftMostSafe, mode);
415
+ }
416
+ const convertedArgs = this.visitAll(ast.args, _Mode.Expression);
417
+ if (ast instanceof BuiltinFunctionCall) {
418
+ return convertToStatementIfNeeded(mode, ast.converter(convertedArgs));
419
+ }
420
+ const receiver = ast.receiver;
421
+ if (receiver instanceof cdAst.PropertyRead &&
422
+ receiver.receiver instanceof cdAst.ImplicitReceiver &&
423
+ !(receiver.receiver instanceof cdAst.ThisReceiver) && receiver.name === '$any') {
424
+ if (convertedArgs.length !== 1) {
425
+ throw new Error(`Invalid call to $any, expected 1 argument but received ${convertedArgs.length || 'none'}`);
426
+ }
427
+ return convertToStatementIfNeeded(mode, convertedArgs[0]);
428
+ }
429
+ const call = this._visit(receiver, _Mode.Expression)
430
+ .callFn(convertedArgs, this.convertSourceSpan(ast.span));
431
+ return convertToStatementIfNeeded(mode, call);
432
+ }
433
+ visitSafeCall(ast, mode) {
434
+ return this.convertSafeAccess(ast, this.leftMostSafeNode(ast), mode);
435
+ }
436
+ _visit(ast, mode) {
437
+ const result = this._resultMap.get(ast);
438
+ if (result)
439
+ return result;
440
+ return (this._nodeMap.get(ast) || ast).visit(this, mode);
441
+ }
442
+ convertSafeAccess(ast, leftMostSafe, mode) {
443
+ // If the expression contains a safe access node on the left it needs to be converted to
444
+ // an expression that guards the access to the member by checking the receiver for blank. As
445
+ // execution proceeds from left to right, the left most part of the expression must be guarded
446
+ // first but, because member access is left associative, the right side of the expression is at
447
+ // the top of the AST. The desired result requires lifting a copy of the left part of the
448
+ // expression up to test it for blank before generating the unguarded version.
449
+ // Consider, for example the following expression: a?.b.c?.d.e
450
+ // This results in the ast:
451
+ // .
452
+ // / \
453
+ // ?. e
454
+ // / \
455
+ // . d
456
+ // / \
457
+ // ?. c
458
+ // / \
459
+ // a b
460
+ // The following tree should be generated:
461
+ //
462
+ // /---- ? ----\
463
+ // / | \
464
+ // a /--- ? ---\ null
465
+ // / | \
466
+ // . . null
467
+ // / \ / \
468
+ // . c . e
469
+ // / \ / \
470
+ // a b . d
471
+ // / \
472
+ // . c
473
+ // / \
474
+ // a b
475
+ //
476
+ // Notice that the first guard condition is the left hand of the left most safe access node
477
+ // which comes in as leftMostSafe to this routine.
478
+ let guardedExpression = this._visit(leftMostSafe.receiver, _Mode.Expression);
479
+ let temporary = undefined;
480
+ if (this.needsTemporaryInSafeAccess(leftMostSafe.receiver)) {
481
+ // If the expression has method calls or pipes then we need to save the result into a
482
+ // temporary variable to avoid calling stateful or impure code more than once.
483
+ temporary = this.allocateTemporary();
484
+ // Preserve the result in the temporary variable
485
+ guardedExpression = temporary.set(guardedExpression);
486
+ // Ensure all further references to the guarded expression refer to the temporary instead.
487
+ this._resultMap.set(leftMostSafe.receiver, temporary);
488
+ }
489
+ const condition = guardedExpression.isBlank();
490
+ // Convert the ast to an unguarded access to the receiver's member. The map will substitute
491
+ // leftMostNode with its unguarded version in the call to `this.visit()`.
492
+ if (leftMostSafe instanceof cdAst.SafeCall) {
493
+ this._nodeMap.set(leftMostSafe, new cdAst.Call(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.receiver, leftMostSafe.args, leftMostSafe.argumentSpan));
494
+ }
495
+ else if (leftMostSafe instanceof cdAst.SafeKeyedRead) {
496
+ this._nodeMap.set(leftMostSafe, new cdAst.KeyedRead(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.receiver, leftMostSafe.key));
497
+ }
498
+ else {
499
+ this._nodeMap.set(leftMostSafe, new cdAst.PropertyRead(leftMostSafe.span, leftMostSafe.sourceSpan, leftMostSafe.nameSpan, leftMostSafe.receiver, leftMostSafe.name));
500
+ }
501
+ // Recursively convert the node now without the guarded member access.
502
+ const access = this._visit(ast, _Mode.Expression);
503
+ // Remove the mapping. This is not strictly required as the converter only traverses each node
504
+ // once but is safer if the conversion is changed to traverse the nodes more than once.
505
+ this._nodeMap.delete(leftMostSafe);
506
+ // If we allocated a temporary, release it.
507
+ if (temporary) {
508
+ this.releaseTemporary(temporary);
509
+ }
510
+ // Produce the conditional
511
+ return convertToStatementIfNeeded(mode, condition.conditional(o.NULL_EXPR, access));
512
+ }
513
+ convertNullishCoalesce(ast, mode) {
514
+ const left = this._visit(ast.left, _Mode.Expression);
515
+ const right = this._visit(ast.right, _Mode.Expression);
516
+ const temporary = this.allocateTemporary();
517
+ this.releaseTemporary(temporary);
518
+ // Generate the following expression. It is identical to how TS
519
+ // transpiles binary expressions with a nullish coalescing operator.
520
+ // let temp;
521
+ // (temp = a) !== null && temp !== undefined ? temp : b;
522
+ return convertToStatementIfNeeded(mode, temporary.set(left)
523
+ .notIdentical(o.NULL_EXPR)
524
+ .and(temporary.notIdentical(o.literal(undefined)))
525
+ .conditional(temporary, right));
526
+ }
527
+ // Given an expression of the form a?.b.c?.d.e then the left most safe node is
528
+ // the (a?.b). The . and ?. are left associative thus can be rewritten as:
529
+ // ((((a?.c).b).c)?.d).e. This returns the most deeply nested safe read or
530
+ // safe method call as this needs to be transformed initially to:
531
+ // a == null ? null : a.c.b.c?.d.e
532
+ // then to:
533
+ // a == null ? null : a.b.c == null ? null : a.b.c.d.e
534
+ leftMostSafeNode(ast) {
535
+ const visit = (visitor, ast) => {
536
+ return (this._nodeMap.get(ast) || ast).visit(visitor);
537
+ };
538
+ return ast.visit({
539
+ visitUnary(ast) {
540
+ return null;
541
+ },
542
+ visitBinary(ast) {
543
+ return null;
544
+ },
545
+ visitChain(ast) {
546
+ return null;
547
+ },
548
+ visitConditional(ast) {
549
+ return null;
550
+ },
551
+ visitCall(ast) {
552
+ return visit(this, ast.receiver);
553
+ },
554
+ visitSafeCall(ast) {
555
+ return visit(this, ast.receiver) || ast;
556
+ },
557
+ visitImplicitReceiver(ast) {
558
+ return null;
559
+ },
560
+ visitThisReceiver(ast) {
561
+ return null;
562
+ },
563
+ visitInterpolation(ast) {
564
+ return null;
565
+ },
566
+ visitKeyedRead(ast) {
567
+ return visit(this, ast.receiver);
568
+ },
569
+ visitKeyedWrite(ast) {
570
+ return null;
571
+ },
572
+ visitLiteralArray(ast) {
573
+ return null;
574
+ },
575
+ visitLiteralMap(ast) {
576
+ return null;
577
+ },
578
+ visitLiteralPrimitive(ast) {
579
+ return null;
580
+ },
581
+ visitPipe(ast) {
582
+ return null;
583
+ },
584
+ visitPrefixNot(ast) {
585
+ return null;
586
+ },
587
+ visitNonNullAssert(ast) {
588
+ return visit(this, ast.expression);
589
+ },
590
+ visitPropertyRead(ast) {
591
+ return visit(this, ast.receiver);
592
+ },
593
+ visitPropertyWrite(ast) {
594
+ return null;
595
+ },
596
+ visitSafePropertyRead(ast) {
597
+ return visit(this, ast.receiver) || ast;
598
+ },
599
+ visitSafeKeyedRead(ast) {
600
+ return visit(this, ast.receiver) || ast;
601
+ }
602
+ });
603
+ }
604
+ // Returns true of the AST includes a method or a pipe indicating that, if the
605
+ // expression is used as the target of a safe property or method access then
606
+ // the expression should be stored into a temporary variable.
607
+ needsTemporaryInSafeAccess(ast) {
608
+ const visit = (visitor, ast) => {
609
+ return ast && (this._nodeMap.get(ast) || ast).visit(visitor);
610
+ };
611
+ const visitSome = (visitor, ast) => {
612
+ return ast.some(ast => visit(visitor, ast));
613
+ };
614
+ return ast.visit({
615
+ visitUnary(ast) {
616
+ return visit(this, ast.expr);
617
+ },
618
+ visitBinary(ast) {
619
+ return visit(this, ast.left) || visit(this, ast.right);
620
+ },
621
+ visitChain(ast) {
622
+ return false;
623
+ },
624
+ visitConditional(ast) {
625
+ return visit(this, ast.condition) || visit(this, ast.trueExp) || visit(this, ast.falseExp);
626
+ },
627
+ visitCall(ast) {
628
+ return true;
629
+ },
630
+ visitSafeCall(ast) {
631
+ return true;
632
+ },
633
+ visitImplicitReceiver(ast) {
634
+ return false;
635
+ },
636
+ visitThisReceiver(ast) {
637
+ return false;
638
+ },
639
+ visitInterpolation(ast) {
640
+ return visitSome(this, ast.expressions);
641
+ },
642
+ visitKeyedRead(ast) {
643
+ return false;
644
+ },
645
+ visitKeyedWrite(ast) {
646
+ return false;
647
+ },
648
+ visitLiteralArray(ast) {
649
+ return true;
650
+ },
651
+ visitLiteralMap(ast) {
652
+ return true;
653
+ },
654
+ visitLiteralPrimitive(ast) {
655
+ return false;
656
+ },
657
+ visitPipe(ast) {
658
+ return true;
659
+ },
660
+ visitPrefixNot(ast) {
661
+ return visit(this, ast.expression);
662
+ },
663
+ visitNonNullAssert(ast) {
664
+ return visit(this, ast.expression);
665
+ },
666
+ visitPropertyRead(ast) {
667
+ return false;
668
+ },
669
+ visitPropertyWrite(ast) {
670
+ return false;
671
+ },
672
+ visitSafePropertyRead(ast) {
673
+ return false;
674
+ },
675
+ visitSafeKeyedRead(ast) {
676
+ return false;
677
+ }
678
+ });
679
+ }
680
+ allocateTemporary() {
681
+ const tempNumber = this._currentTemporary++;
682
+ this.temporaryCount = Math.max(this._currentTemporary, this.temporaryCount);
683
+ return new o.ReadVarExpr(temporaryName(this.bindingId, tempNumber));
684
+ }
685
+ releaseTemporary(temporary) {
686
+ this._currentTemporary--;
687
+ if (temporary.name != temporaryName(this.bindingId, this._currentTemporary)) {
688
+ throw new Error(`Temporary ${temporary.name} released out of order`);
689
+ }
690
+ }
691
+ /**
692
+ * Creates an absolute `ParseSourceSpan` from the relative `ParseSpan`.
693
+ *
694
+ * `ParseSpan` objects are relative to the start of the expression.
695
+ * This method converts these to full `ParseSourceSpan` objects that
696
+ * show where the span is within the overall source file.
697
+ *
698
+ * @param span the relative span to convert.
699
+ * @returns a `ParseSourceSpan` for the given span or null if no
700
+ * `baseSourceSpan` was provided to this class.
701
+ */
702
+ convertSourceSpan(span) {
703
+ if (this.baseSourceSpan) {
704
+ const start = this.baseSourceSpan.start.moveBy(span.start);
705
+ const end = this.baseSourceSpan.start.moveBy(span.end);
706
+ const fullStart = this.baseSourceSpan.fullStart.moveBy(span.start);
707
+ return new ParseSourceSpan(start, end, fullStart);
708
+ }
709
+ else {
710
+ return null;
711
+ }
712
+ }
713
+ /** Adds the name of an AST to the list of implicit receiver accesses. */
714
+ addImplicitReceiverAccess(name) {
715
+ if (this.implicitReceiverAccesses) {
716
+ this.implicitReceiverAccesses.add(name);
717
+ }
718
+ }
719
+ }
720
+ function flattenStatements(arg, output) {
721
+ if (Array.isArray(arg)) {
722
+ arg.forEach((entry) => flattenStatements(entry, output));
723
+ }
724
+ else {
725
+ output.push(arg);
726
+ }
727
+ }
728
+ function unsupported() {
729
+ throw new Error('Unsupported operation');
730
+ }
731
+ class InterpolationExpression extends o.Expression {
732
+ constructor(args) {
733
+ super(null, null);
734
+ this.args = args;
735
+ this.isConstant = unsupported;
736
+ this.isEquivalent = unsupported;
737
+ this.visitExpression = unsupported;
738
+ }
739
+ }
740
+ class DefaultLocalResolver {
741
+ constructor(globals) {
742
+ this.globals = globals;
743
+ }
744
+ notifyImplicitReceiverUse() { }
745
+ maybeRestoreView() { }
746
+ getLocal(name) {
747
+ if (name === EventHandlerVars.event.name) {
748
+ return EventHandlerVars.event;
749
+ }
750
+ return null;
751
+ }
752
+ }
753
+ export class BuiltinFunctionCall extends cdAst.Call {
754
+ constructor(span, sourceSpan, args, converter) {
755
+ super(span, sourceSpan, new cdAst.EmptyExpr(span, sourceSpan), args, null);
756
+ this.converter = converter;
757
+ }
758
+ }
759
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXhwcmVzc2lvbl9jb252ZXJ0ZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb21waWxlci9zcmMvY29tcGlsZXJfdXRpbC9leHByZXNzaW9uX2NvbnZlcnRlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEtBQUssS0FBSyxNQUFNLDBCQUEwQixDQUFDO0FBQ2xELE9BQU8sS0FBSyxDQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDMUMsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUU5QyxNQUFhLGdCQUFnQjthQUNwQixVQUFLLEdBQUcsQ0FBQyxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQzs7U0FEekIsZ0JBQWdCO0FBVzdCOzs7R0FHRztBQUNILE1BQU0sVUFBVSxvQkFBb0IsQ0FDaEMsYUFBaUMsRUFBRSxnQkFBOEIsRUFBRSxNQUFpQixFQUNwRixTQUFpQixFQUFFLGNBQWdDLEVBQUUsd0JBQXNDLEVBQzNGLE9BQXFCO0lBQ3ZCLElBQUksQ0FBQyxhQUFhLEVBQUU7UUFDbEIsYUFBYSxHQUFHLElBQUksb0JBQW9CLENBQUMsT0FBTyxDQUFDLENBQUM7S0FDbkQ7SUFDRCxNQUFNLHFCQUFxQixHQUFHLDhCQUE4QixDQUN4RDtRQUNFLDJCQUEyQixFQUFFLENBQUMsUUFBZ0IsRUFBRSxFQUFFO1lBQ2hELGtEQUFrRDtZQUNsRCxPQUFPLENBQUMsSUFBb0IsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN0RCxDQUFDO1FBQ0QseUJBQXlCLEVBQUUsQ0FBQyxJQUFzQyxFQUFFLEVBQUU7WUFDcEUsZ0RBQWdEO1lBQ2hELE9BQU8sQ0FBQyxNQUFzQixFQUFFLEVBQUU7Z0JBQ2hDLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUs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bnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0ICogYXMgY2RBc3QgZnJvbSAnLi4vZXhwcmVzc2lvbl9wYXJzZXIvYXN0JztcbmltcG9ydCAqIGFzIG8gZnJvbSAnLi4vb3V0cHV0L291dHB1dF9hc3QnO1xuaW1wb3J0IHtQYXJzZVNvdXJjZVNwYW59IGZyb20gJy4uL3BhcnNlX3V0aWwnO1xuXG5leHBvcnQgY2xhc3MgRXZlbnRIYW5kbGVyVmFycyB7XG4gIHN0YXRpYyBldmVudCA9IG8udmFyaWFibGUoJyRldmVudCcpO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIExvY2FsUmVzb2x2ZXIge1xuICBnZXRMb2NhbChuYW1lOiBzdHJpbmcpOiBvLkV4cHJlc3Npb258bnVsbDtcbiAgbm90aWZ5SW1wbGljaXRSZWNlaXZlclVzZSgpOiB2b2lkO1xuICBnbG9iYWxzPzogU2V0PHN0cmluZz47XG4gIG1heWJlUmVzdG9yZVZpZXcoKTogdm9pZDtcbn1cblxuLyoqXG4gKiBDb252ZXJ0cyB0aGUgZ2l2ZW4gZXhwcmVzc2lvbiBBU1QgaW50byBhbiBleGVjdXRhYmxlIG91dHB1dCBBU1QsIGFzc3VtaW5nIHRoZSBleHByZXNzaW9uIGlzXG4gKiB1c2VkIGluIGFuIGFjdGlvbiBiaW5kaW5nIChlLmcuIGFuIGV2ZW50IGhhbmRsZXIpLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY29udmVydEFjdGlvbkJpbmRpbmcoXG4gICAgbG9jYWxSZXNvbHZlcjogTG9jYWxSZXNvbHZlcnxudWxsLCBpbXBsaWNpdFJlY2VpdmVyOiBvLkV4cHJlc3Npb24sIGFjdGlvbjogY2RBc3QuQVNULFxuICAgIGJpbmRpbmdJZDogc3RyaW5nLCBiYXNlU291cmNlU3Bhbj86IFBhcnNlU291cmNlU3BhbiwgaW1wbGljaXRSZWNlaXZlckFjY2Vzc2VzPzogU2V0PHN0cmluZz4sXG4gICAgZ2xvYmFscz86IFNldDxzdHJpbmc+KTogby5TdGF0ZW1lbnRbXSB7XG4gIGlmICghbG9jYWxSZXNvbHZlcikge1xuICAgIGxvY2FsUmVzb2x2ZXIgPSBuZXcgRGVmYXVsdExvY2FsUmVzb2x2ZXIoZ2xvYmFscyk7XG4gIH1cbiAgY29uc3QgYWN0aW9uV2l0aG91dEJ1aWx0aW5zID0gY29udmVydFByb3BlcnR5QmluZGluZ0J1aWx0aW5zKFxuICAgICAge1xuICAgICAgICBjcmVhdGVMaXRlcmFsQXJyYXlDb252ZXJ0ZXI6IChhcmdDb3VudDogbnVtYmVyKSA9PiB7XG4gICAgICAgICAgLy8gTm90ZTogbm8gY2FjaGluZyBmb3IgbGl0ZXJhbCBhcnJheXMgaW4gYWN0aW9ucy5cbiAgICAgICAgICByZXR1cm4gKGFyZ3M6IG8uRXhwcmVzc2lvbltdKSA9PiBvLmxpdGVyYWxBcnIoYXJncyk7XG4gICAgICAgIH0sXG4gICAgICAgIGNyZWF0ZUxpdGVyYWxNYXBDb252ZXJ0ZXI6IChrZXlzOiB7a2V5OiBzdHJpbmcsIHF1b3RlZDogYm9vbGVhbn1bXSkgPT4ge1xuICAgICAgICAgIC8vIE5vdGU6IG5vIGNhY2hpbmcgZm9yIGxpdGVyYWwgbWFwcyBpbiBhY3Rpb25zLlxuICAgICAgICAgIHJldHVybiAodmFsdWVzOiBvLkV4cHJlc3Npb25bXSkgPT4ge1xuICAgICAgICAgICAgY29uc3QgZW50cmllcyA9IGtleXMubWFwKChrLCBpKSA9PiAoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAga2V5OiBrLmtleSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZXNbaV0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBxdW90ZWQ6IGsucXVvdGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pKTtcbiAgICAgICAgICAgIHJldHVybiBvLmxpdGVyYWxNYXAoZW50cmllcyk7XG4gICAgICAgICAgfTtcbiAgICAgICAgfSxcbiAgICAgICAgY3JlYXRlUGlwZUNvbnZlcnRlcjogKG5hbWU6IHN0cmluZykgPT4ge1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgSWxsZWdhbCBTdGF0ZTogQWN0aW9ucyBhcmUgbm90IGFsbG93ZWQgdG8gY29udGFpbiBwaXBlcy4gUGlwZTogJHtuYW1lfWApO1xuICAgICAgICB9XG4gICAgICB9LFxuICAgICAgYWN0aW9uKTtcblxuICBjb25zdCB2aXNpdG9yID0gbmV3IF9Bc3RUb0lyVmlzaXRvcihcbiAgICAgIGxvY2FsUmVzb2x2ZXIsIGltcGxpY2l0UmVjZWl2ZXIsIGJpbmRpbmdJZCwgLyogc3VwcG9ydHNJbnRlcnBvbGF0aW9uICovIGZhbHNlLCBiYXNlU291cmNlU3BhbixcbiAgICAgIGltcGxpY2l0UmVjZWl2ZXJBY2Nlc3Nlcyk7XG4gIGNvbnN0IGFjdGlvblN0bXRzOiBvLlN0YXRlbWVudFtdID0gW107XG4gIGZsYXR0ZW5TdGF0ZW1lbnRzKGFjdGlvbldpdGhvdXRCdWlsdGlucy52aXNpdCh2aXNpdG9yLCBfTW9kZS5TdGF0ZW1lbnQpLCBhY3Rpb25TdG10cyk7XG4gIHByZXBlbmRUZW1wb3JhcnlEZWNscyh2aXNpdG9yLnRlbXBvcmFyeUNvdW50LCBiaW5kaW5nSWQsIGFjdGlvblN0bXRzKTtcblxuICBpZiAodmlzaXRvci51c2VzSW1wbGljaXRSZWNlaXZlcikge1xuICAgIGxvY2FsUmVzb2x2ZXIubm90aWZ5SW1wbGljaXRSZWNlaXZlclVzZSgpO1xuICB9XG5cbiAgY29uc3QgbGFzdEluZGV4ID0gYWN0aW9uU3RtdHMubGVuZ3RoIC0gMTtcbiAgaWYgKGxhc3RJbmRleCA+PSAwKSB7XG4gICAgY29uc3QgbGFzdFN0YXRlbWVudCA9IGFjdGlvblN0bXRzW2xhc3RJbmRleF07XG4gICAgLy8gRW5zdXJlIHRoYXQgdGhlIHZhbHVlIG9mIHRoZSBsYXN0IGV4cHJlc3Npb24gc3RhdGVtZW50IGlzIHJldHVybmVkXG4gICAgaWYgKGxhc3RTdGF0ZW1lbnQgaW5zdGFuY2VvZiBvLkV4cHJlc3Npb25TdGF0ZW1lbnQpIHtcbiAgICAgIGFjdGlvblN0bXRzW2xhc3RJbmRleF0gPSBuZXcgby5SZXR1cm5TdGF0ZW1lbnQobGFzdFN0YXRlbWVudC5leHByKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGFjdGlvblN0bXRzO1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIEJ1aWx0aW5Db252ZXJ0ZXIge1xuICAoYXJnczogby5FeHByZXNzaW9uW10pOiBvLkV4cHJlc3Npb247XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgQnVpbHRpbkNvbnZlcnRlckZhY3Rvcnkge1xuICBjcmVhdGVMaXRlcmFsQXJyYXlDb252ZXJ0ZXIoYXJnQ291bnQ6IG51bWJlcik6IEJ1aWx0aW5Db252ZXJ0ZXI7XG4gIGNyZWF0ZUxpdGVyYWxNYXBDb252ZXJ0ZXIoa2V5czoge2tleTogc3RyaW5nLCBxdW90ZWQ6IGJvb2xlYW59W10pOiBCdWlsdGluQ29udmVydGVyO1xuICBjcmVhdGVQaXBlQ29udmVydGVyKG5hbWU6IHN0cmluZywgYXJnQ291bnQ6IG51bWJlcik6IEJ1aWx0aW5Db252ZXJ0ZXI7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0UHJvcGVydHlCaW5kaW5nQnVpbHRpbnMoXG4gICAgY29udmVydGVyRmFjdG9yeTogQnVpbHRpbkNvbnZlcnRlckZhY3RvcnksIGFzdDogY2RBc3QuQVNUKTogY2RBc3QuQVNUIHtcbiAgcmV0dXJuIGNvbnZlcnRCdWlsdGlucyhjb252ZXJ0ZXJGYWN0b3J5LCBhc3QpO1xufVxuXG5leHBvcnQgY2xhc3MgQ29udmVydFByb3BlcnR5QmluZGluZ1Jlc3VsdCB7XG4gIGNvbnN0cnVjdG9yKHB1YmxpYyBzdG10czogby5TdGF0ZW1lbnRbXSwgcHVibGljIGN1cnJWYWxFeHByOiBvLkV4cHJlc3Npb24pIHt9XG59XG5cbi8qKlxuICogQ29udmVydHMgdGhlIGdpdmVuIGV4cHJlc3Npb24gQVNUIGludG8gYW4gZXhlY3V0YWJsZSBvdXRwdXQgQVNULCBhc3N1bWluZyB0aGUgZXhwcmVzc2lvblxuICogaXMgdXNlZCBpbiBwcm9wZXJ0eSBiaW5kaW5nLiBUaGUgZXhwcmVzc2lvbiBoYXMgdG8gYmUgcHJlcHJvY2Vzc2VkIHZpYVxuICogYGNvbnZlcnRQcm9wZXJ0eUJpbmRpbmdCdWlsdGluc2AuXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb252ZXJ0UHJvcGVydHlCaW5kaW5nKFxuICAgIGxvY2FsUmVzb2x2ZXI6IExvY2FsUmVzb2x2ZXJ8bnVsbCwgaW1wbGljaXRSZWNlaXZlcjogby5FeHByZXNzaW9uLFxuICAgIGV4cHJlc3Npb25XaXRob3V0QnVpbHRpbnM6IGNkQXN0LkFTVCwgYmluZGluZ0lkOiBzdHJpbmcpOiBDb252ZXJ0UHJvcGVydHlCaW5kaW5nUmVzdWx0IHtcbiAgaWYgKCFsb2NhbFJlc29sdmVyKSB7XG4gICAgbG9jYWxSZXNvbHZlciA9IG5ldyBEZWZhdWx0TG9jYWxSZXNvbHZlcigpO1xuICB9XG4gIGNvbnN0IHZpc2l0b3IgPSBuZXcgX0FzdFRvSXJWaXNpdG9yKFxuICAgICAgbG9jYWxSZXNvbHZlciwgaW1wbGljaXRSZWNlaXZlciwgYmluZGluZ0lkLCAvKiBzdXBwb3J0c0ludGVycG9sYXRpb24gKi8gZmFsc2UpO1xuICBjb25zdCBvdXRwdXRFeHByOiBvLkV4cHJlc3Npb24gPSBleHByZXNzaW9uV2l0aG91dEJ1aWx0aW5zLnZpc2l0KHZpc2l0b3IsIF9Nb2RlLkV4cHJlc3Npb24pO1xuICBjb25zdCBzdG10czogby5TdGF0ZW1lbnRbXSA9IGdldFN0YXRlbWVudHNGcm9tVmlzaXRvcih2aXNpdG9yLCBiaW5kaW5nSWQpO1xuXG4gIGlmICh2aXNpdG9yLnVzZXNJbXBsaWNpdFJlY2VpdmVyKSB7XG4gICAgbG9jYWxSZXNvbHZlci5ub3RpZnlJbXBsaWNpdFJlY2VpdmVyVXNlKCk7XG4gIH1cblxuICByZXR1cm4gbmV3IENvbnZlcnRQcm9wZXJ0eUJpbmRpbmdSZXN1bHQoc3RtdHMsIG91dHB1dEV4cHIpO1xufVxuXG4vKipcbiAqIEdpdmVuIHNvbWUgZXhwcmVzc2lvbiwgc3VjaCBhcyBhIGJpbmRpbmcgb3IgaW50ZXJwb2xhdGlvbiBleHByZXNzaW9uLCBhbmQgYSBjb250ZXh0IGV4cHJlc3Npb24gdG9cbiAqIGxvb2sgdmFsdWVzIHVwIG9uLCB2aXNpdCBlYWNoIGZhY2V0IG9mIHRoZSBnaXZlbiBleHByZXNzaW9uIHJlc29sdmluZyB2YWx1ZXMgZnJvbSB0aGUgY29udGV4dFxuICogZXhwcmVzc2lvbiBzdWNoIHRoYXQgYSBsaXN0IG9mIGFyZ3VtZW50cyBjYW4gYmUgZGVyaXZlZCBmcm9tIHRoZSBmb3VuZCB2YWx1ZXMgdGhhdCBjYW4gYmUgdXNlZCBhc1xuICogYXJndW1lbnRzIHRvIGFuIGV4dGVybmFsIHVwZGF0ZSBpbnN0cnVjdGlvbi5cbiAqXG4gKiBAcGFyYW0gbG9jYWxSZXNvbHZlciBUaGUgcmVzb2x2ZXIgdG8gdXNlIHRvIGxvb2sgdXAgZXhwcmVzc2lvbnMgYnkgbmFtZSBhcHByb3ByaWF0ZWx5XG4gKiBAcGFyYW0gY29udGV4dFZhcmlhYmxlRXhwcmVzc2lvbiBUaGUgZXhwcmVzc2lvbiByZXByZXNlbnRpbmcgdGhlIGNvbnRleHQgdmFyaWFibGUgdXNlZCB0byBjcmVhdGVcbiAqIHRoZSBmaW5hbCBhcmd1bWVudCBleHByZXNzaW9uc1xuICogQHBhcmFtIGV4cHJlc3Npb25XaXRoQXJndW1lbnRzVG9FeHRyYWN0IFRoZSBleHByZXNzaW9uIHRvIHZpc2l0IHRvIGZpZ3VyZSBvdXQgd2hhdCB2YWx1ZXMgbmVlZCB0b1xuICogYmUgcmVzb2x2ZWQgYW5kIHdoYXQgYXJndW1lbnRzIGxpc3QgdG8gYnVpbGQuXG4gKiBAcGFyYW0gYmluZGluZ0lkIEEgbmFtZSBwcmVmaXggdXNlZCB0byBjcmVhdGUgdGVtcG9yYXJ5IHZhcmlhYmxlIG5hbWVzIGlmIHRoZXkncmUgbmVlZGVkIGZvciB0aGVcbiAqIGFyZ3VtZW50cyBnZW5lcmF0ZWRcbiAqIEByZXR1cm5zIEFuIGFycmF5IG9mIGV4cHJlc3Npb25zIHRoYXQgY2FuIGJlIHBhc3NlZCBhcyBhcmd1bWVudHMgdG8gaW5zdHJ1Y3Rpb24gZXhwcmVzc2lvbnMgbGlrZVxuICogYG8uaW1wb3J0RXhwcihSMy5wcm9wZXJ0eUludGVycG9sYXRlKS5jYWxsRm4ocmVzdWx0KWBcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGNvbnZlcnRVcGRhdGVBcmd1bWVudHMoXG4gICAgbG9jYWxSZXNvbHZlcjogTG9jYWxSZXNvbHZlciwgY29udGV4dFZhcmlhYmxlRXhwcmVzc2lvbjogby5FeHByZXNzaW9uLFxuICAgIGV4cHJlc3Npb25XaXRoQXJndW1lbnRzVG9FeHRyYWN0OiBjZEFzdC5JbnRlcnBvbGF0aW9uLCBiaW5kaW5nSWQ6IHN0cmluZykge1xuICBjb25zdCB2aXNpdG9yID0gbmV3IF9Bc3RUb0lyVmlzaXRvcihcbiAgICAgIGxvY2FsUmVzb2x2ZXIsIGNvbnRleHRWYXJpYWJsZUV4cHJlc3Npb24sIGJpbmRpbmdJZCwgLyogc3VwcG9ydHNJbnRlcnBvbGF0aW9uICovIHRydWUpO1xuICBjb25zdCBvdXRwdXRFeHByID0gdmlzaXRvci52aXNpdEludGVycG9sYXRpb24oZXhwcmVzc2lvbldpdGhBcmd1bWVudHNUb0V4dHJhY3QsIF9Nb2RlLkV4cHJlc3Npb24pO1xuXG4gIGlmICh2aXNpdG9yLnVzZXNJbXBsaWNpdFJlY2VpdmVyKSB7XG4gICAgbG9jYWxSZXNvbHZlci5ub3RpZnlJbXBsaWNpdFJlY2VpdmVyVXNlKCk7XG4gIH1cblxuICBjb25zdCBzdG10cyA9IGdldFN0YXRlbWVudHNGcm9tVmlzaXRvcih2aXNpdG9yLCBiaW5kaW5nSWQpO1xuICBjb25zdCBhcmdzID0gb3V0cHV0RXhwci5hcmdzO1xuICByZXR1cm4ge3N0bXRzLCBhcmdzfTtcbn1cblxuZnVuY3Rpb24gZ2V0U3RhdGVtZW50c0Zyb21WaXNpdG9yKHZpc2l0b3I6IF9Bc3RUb0lyVmlzaXRvciwgYmluZGluZ0lkOiBzdHJpbmcpIHtcbiAgY29uc3Qgc3RtdHM6IG8uU3RhdGVtZW50W10gPSBbXTtcbiAgZm9yIChsZXQgaSA9IDA7IGkgPCB2aXNpdG9yLnRlbXBvcmFyeUNvdW50OyBpKyspIHtcbiAgICBzdG10cy5wdXNoKHRlbXBvcmFyeURlY2xhcmF0aW9uKGJpbmRpbmdJZCwgaSkpO1xuICB9XG4gIHJldHVybiBzdG10cztcbn1cblxuZnVuY3Rpb24gY29udmVydEJ1aWx0aW5zKGNvbnZlcnRlckZhY3Rvcnk6IEJ1aWx0aW5Db252ZXJ0ZXJGYWN0b3J5LCBhc3Q6IGNkQXN0LkFTVCk6IGNkQXN0LkFTVCB7XG4gIGNvbnN0IHZpc2l0b3IgPSBuZXcgX0J1aWx0aW5Bc3RDb252ZXJ0ZXIoY29udmVydGVyRmFjdG9yeSk7XG4gIHJldHVybiBhc3QudmlzaXQodmlzaXRvcik7XG59XG5cbmZ1bmN0aW9uIHRlbXBvcmFyeU5hbWUoYmluZGluZ0lkOiBzdHJpbmcsIHRlbXBvcmFyeU51bWJlcjogbnVtYmVyKTogc3RyaW5nIHtcbiAgcmV0dXJuIGB0bXBfJHtiaW5kaW5nSWR9XyR7dGVtcG9yYXJ5TnVtYmVyfWA7XG59XG5cbmZ1bmN0aW9uIHRlbXBvcmFyeURlY2xhcmF0aW9uKGJpbmRpbmdJZDogc3RyaW5nLCB0ZW1wb3JhcnlOdW1iZXI6IG51bWJlcik6IG8uU3RhdGVtZW50IHtcbiAgcmV0dXJuIG5ldyBvLkRlY2xhcmVWYXJTdG10KHRlbXBvcmFyeU5hbWUoYmluZGluZ0lkLCB0ZW1wb3JhcnlOdW1iZXIpKTtcbn1cblxuZnVuY3Rpb24gcHJlcGVuZFRlbXBvcmFyeURlY2xzKFxuICAgIHRlbXBvcmFyeUNvdW50OiBudW1iZXIsIGJpbmRpbmdJZDogc3RyaW5nLCBzdGF0ZW1lbnRzOiBvLlN0YXRlbWVudFtdKSB7XG4gIGZvciAobGV0IGkgPSB0ZW1wb3JhcnlDb3VudCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgc3RhdGVtZW50cy51bnNoaWZ0KHRlbXBvcmFyeURlY2xhcmF0aW9uKGJpbmRpbmdJZCwgaSkpO1xuICB9XG59XG5cbmVudW0gX01vZGUge1xuICBTdGF0ZW1lbnQsXG4gIEV4cHJlc3Npb25cbn1cblxuZnVuY3Rpb24gZW5zdXJlU3RhdGVtZW50TW9kZShtb2RlOiBfTW9kZSwgYXN0OiBjZEFzdC5BU1QpIHtcbiAgaWYgKG1vZGUgIT09IF9Nb2RlLlN0YXRlbWVudCkge1xuICAgIHRocm93IG5ldyBFcnJvcihgRXhwZWN0ZWQgYSBzdGF0ZW1lbnQsIGJ1dCBzYXcgJHthc3R9YCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5zdXJlRXhwcmVzc2lvbk1vZGUobW9kZTogX01vZGUsIGFzdDogY2RBc3QuQVNUKSB7XG4gIGlmIChtb2RlICE9PSBfTW9kZS5FeHByZXNzaW9uKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKGBFeHBlY3RlZCBhbiBleHByZXNzaW9uLCBidXQgc2F3ICR7YXN0fWApO1xuICB9XG59XG5cbmZ1bmN0aW9uIGNvbnZlcnRUb1N0YXRlbWVudElmTmVlZGVkKG1vZGU6IF9Nb2RlLCBleHByOiBvLkV4cHJlc3Npb24pOiBvLkV4cHJlc3Npb258by5TdGF0ZW1lbnQge1xuICBpZiAobW9kZSA9PT0gX01vZGUuU3RhdGVtZW50KSB7XG4gICAgcmV0dXJuIGV4cHIudG9TdG10KCk7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIGV4cHI7XG4gIH1cbn1cblxuY2xhc3MgX0J1aWx0aW5Bc3RDb252ZXJ0ZXIgZXh0ZW5kcyBjZEFzdC5Bc3RUcmFuc2Zvcm1lciB7XG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgX2NvbnZlcnRlckZhY3Rvcnk6IEJ1aWx0aW5Db252ZXJ0ZXJGYWN0b3J5KSB7XG4gICAgc3VwZXIoKTtcbiAgfVxuICBvdmVycmlkZSB2aXNpdFBpcGUoYXN0OiBjZEFzdC5CaW5kaW5nUGlwZSwgY29udGV4dDogYW55KTogYW55IHtcbiAgICBjb25zdCBhcmdzID0gW2FzdC5leHAsIC4uLmFzdC5hcmdzXS5tYXAoYXN0ID0+IGFzdC52aXNpdCh0aGlzLCBjb250ZXh0KSk7XG4gICAgcmV0dXJuIG5ldyBCdWlsdGluRnVuY3Rpb25DYWxsKFxuICAgICAgICBhc3Quc3BhbiwgYXN0LnNvdXJjZVNwYW4sIGFyZ3MsXG4gICAgICAgIHRoaXMuX2NvbnZlcnRlckZhY3RvcnkuY3JlYXRlUGlwZUNvbnZlcnRlcihhc3QubmFtZSwgYXJncy5sZW5ndGgpKTtcbiAgfVxuICBvdmVycmlkZSB2aXNpdExpdGVyYWxBcnJheShhc3Q6IGNkQXN0LkxpdGVyYWxBcnJheSwgY29udGV4dDogYW55KTogYW55IHtcbiAgICBjb25zdCBhcmdzID0gYXN0LmV4cHJlc3Npb25zLm1hcChhc3QgPT4gYXN0LnZpc2l0KHRoaXMsIGNvbnRleHQpKTtcbiAgICByZXR1cm4gbmV3IEJ1aWx0aW5GdW5jdGlvbkNhbGwoXG4gICAgICAgIGFzdC5zcGFuLCBhc3Quc291cmNlU3BhbiwgYXJncyxcbiAgICAgICAgdGhpcy5fY29udmVydGVyRmFjdG9yeS5jcmVhdGVMaXRlcmFsQXJyYXlDb252ZXJ0ZXIoYXN0LmV4cHJlc3Npb25zLmxlbmd0aCkpO1xuICB9XG4gIG92ZXJyaWRlIHZpc2l0TGl0ZXJhbE1hcChhc3Q6IGNkQXN0LkxpdGVyYWxNYXAsIGNvbnRleHQ6IGFueSk6IGFueSB7XG4gICAgY29uc3QgYXJncyA9IGFzdC52YWx1ZXMubWFwKGFzdCA9PiBhc3QudmlzaXQodGhpcywgY29udGV4dCkpO1xuXG4gICAgcmV0dXJuIG5ldyBCdWlsdGluRnVuY3Rpb25DYWxsKFxuICAgICAgICBhc3Quc3BhbiwgYXN0LnNvdXJjZVNwYW4sIGFyZ3MsIHRoaXMuX2NvbnZlcnRlckZhY3RvcnkuY3JlYXRlTGl0ZXJhbE1hcENvbnZlcnRlcihhc3Qua2V5cykpO1xuICB9XG59XG5cbmNsYXNzIF9Bc3RUb0lyVmlzaXRvciBpbXBsZW1lbnRzIGNkQXN0LkFzdFZpc2l0b3Ige1xuICBwcml2YXRlIF9ub2RlTWFwID0gbmV3IE1hcDxjZEFzdC5BU1QsIGNkQXN0LkFTVD4oKTtcbiAgcHJpdmF0ZSBfcmVzdWx0TWFwID0gbmV3IE1hcDxjZEFzdC5BU1QsIG8uRXhwcmVzc2lvbj4oKTtcbiAgcHJpdmF0ZSBfY3VycmVudFRlbXBvcmFyeTogbnVtYmVyID0gMDtcbiAgcHVibGljIHRlbXBvcmFyeUNvdW50OiBudW1iZXIgPSAwO1xuICBwdWJsaWMgdXNlc0ltcGxpY2l0UmVjZWl2ZXI6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICAgIHByaXZhdGUgX2xvY2FsUmVzb2x2ZXI6IExvY2FsUmVzb2x2ZXIsIHByaXZhdGUgX2ltcGxpY2l0UmVjZWl2ZXI6IG8uRXhwcmVzc2lvbixcbiAgICAgIHByaXZhdGUgYmluZGluZ0lkOiBzdHJpbmcsIHByaXZhdGUgc3VwcG9ydHNJbnRlcnBvbGF0aW9uOiBib29sZWFuLFxuICAgICAgcHJpdmF0ZSBiYXNlU291cmNlU3Bhbj86IFBhcnNlU291cmNlU3BhbiwgcHJpdmF0ZSBpbXBsaWNpdFJlY2VpdmVyQWNjZXNzZXM/OiBTZXQ8c3RyaW5nPikge31cblxuICB2aXNpdFVuYXJ5KGFzdDogY2RBc3QuVW5hcnksIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICBsZXQgb3A6IG8uVW5hcnlPcGVyYXRvcjtcbiAgICBzd2l0Y2ggKGFzdC5vcGVyYXRvcikge1xuICAgICAgY2FzZSAnKyc6XG4gICAgICAgIG9wID0gby5VbmFyeU9wZXJhdG9yLlBsdXM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnLSc6XG4gICAgICAgIG9wID0gby5VbmFyeU9wZXJhdG9yLk1pbnVzO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgVW5zdXBwb3J0ZWQgb3BlcmF0b3IgJHthc3Qub3BlcmF0b3J9YCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvbnZlcnRUb1N0YXRlbWVudElmTmVlZGVkKFxuICAgICAgICBtb2RlLFxuICAgICAgICBuZXcgby5VbmFyeU9wZXJhdG9yRXhwcihcbiAgICAgICAgICAgIG9wLCB0aGlzLl92aXNpdChhc3QuZXhwciwgX01vZGUuRXhwcmVzc2lvbiksIHVuZGVmaW5lZCxcbiAgICAgICAgICAgIHRoaXMuY29udmVydFNvdXJjZVNwYW4oYXN0LnNwYW4pKSk7XG4gIH1cblxuICB2aXNpdEJpbmFyeShhc3Q6IGNkQXN0LkJpbmFyeSwgbW9kZTogX01vZGUpOiBhbnkge1xuICAgIGxldCBvcDogby5CaW5hcnlPcGVyYXRvcjtcbiAgICBzd2l0Y2ggKGFzdC5vcGVyYXRpb24pIHtcbiAgICAgIGNhc2UgJysnOlxuICAgICAgICBvcCA9IG8uQmluYXJ5T3BlcmF0b3IuUGx1cztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICctJzpcbiAgICAgICAgb3AgPSBvLkJpbmFyeU9wZXJhdG9yLk1pbnVzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJyonOlxuICAgICAgICBvcCA9IG8uQmluYXJ5T3BlcmF0b3IuTXVsdGlwbHk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnLyc6XG4gICAgICAgIG9wID0gby5CaW5hcnlPcGVyYXRvci5EaXZpZGU7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJSc6XG4gICAgICAgIG9wID0gby5CaW5hcnlPcGVyYXRvci5Nb2R1bG87XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnJiYnOlxuICAgICAgICBvcCA9IG8uQmluYXJ5T3BlcmF0b3IuQW5kO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ3x8JzpcbiAgICAgICAgb3AgPSBvLkJpbmFyeU9wZXJhdG9yLk9yO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgb3AgPSBvLkJpbmFyeU9wZXJhdG9yLkVxdWFscztcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICchPSc6XG4gICAgICAgIG9wID0gby5CaW5hcnlPcGVyYXRvci5Ob3RFcXVhbHM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnPT09JzpcbiAgICAgICAgb3AgPSBvLkJpbmFyeU9wZXJhdG9yLklkZW50aWNhbDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICchPT0nOlxuICAgICAgICBvcCA9IG8uQmluYXJ5T3BlcmF0b3IuTm90SWRlbnRpY2FsO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJzwnOlxuICAgICAgICBvcCA9IG8uQmluYXJ5T3BlcmF0b3IuTG93ZXI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnPic6XG4gICAgICAgIG9wID0gby5CaW5hcnlPcGVyYXRvci5CaWdnZXI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnPD0nOlxuICAgICAgICBvcCA9IG8uQmluYXJ5T3BlcmF0b3IuTG93ZXJFcXVhbHM7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAnPj0nOlxuICAgICAgICBvcCA9IG8uQmluYXJ5T3BlcmF0b3IuQmlnZ2VyRXF1YWxzO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJz8/JzpcbiAgICAgICAgcmV0dXJuIHRoaXMuY29udmVydE51bGxpc2hDb2FsZXNjZShhc3QsIG1vZGUpO1xuICAgICAgZGVmYXVsdDpcbiAgICAgICAgdGhyb3cgbmV3IEVycm9yKGBVbnN1cHBvcnRlZCBvcGVyYXRpb24gJHthc3Qub3BlcmF0aW9ufWApO1xuICAgIH1cblxuICAgIHJldHVybiBjb252ZXJ0VG9TdGF0ZW1lbnRJZk5lZWRlZChcbiAgICAgICAgbW9kZSxcbiAgICAgICAgbmV3IG8uQmluYXJ5T3BlcmF0b3JFeHByKFxuICAgICAgICAgICAgb3AsIHRoaXMuX3Zpc2l0KGFzdC5sZWZ0LCBfTW9kZS5FeHByZXNzaW9uKSwgdGhpcy5fdmlzaXQoYXN0LnJpZ2h0LCBfTW9kZS5FeHByZXNzaW9uKSxcbiAgICAgICAgICAgIHVuZGVmaW5lZCwgdGhpcy5jb252ZXJ0U291cmNlU3Bhbihhc3Quc3BhbikpKTtcbiAgfVxuXG4gIHZpc2l0Q2hhaW4oYXN0OiBjZEFzdC5DaGFpbiwgbW9kZTogX01vZGUpOiBhbnkge1xuICAgIGVuc3VyZVN0YXRlbWVudE1vZGUobW9kZSwgYXN0KTtcbiAgICByZXR1cm4gdGhpcy52aXNpdEFsbChhc3QuZXhwcmVzc2lvbnMsIG1vZGUpO1xuICB9XG5cbiAgdmlzaXRDb25kaXRpb25hbChhc3Q6IGNkQXN0LkNvbmRpdGlvbmFsLCBtb2RlOiBfTW9kZSk6IGFueSB7XG4gICAgY29uc3QgdmFsdWU6IG8uRXhwcmVzc2lvbiA9IHRoaXMuX3Zpc2l0KGFzdC5jb25kaXRpb24sIF9Nb2RlLkV4cHJlc3Npb24pO1xuICAgIHJldHVybiBjb252ZXJ0VG9TdGF0ZW1lbnRJZk5lZWRlZChcbiAgICAgICAgbW9kZSxcbiAgICAgICAgdmFsdWUuY29uZGl0aW9uYWwoXG4gICAgICAgICAgICB0aGlzLl92aXNpdChhc3QudHJ1ZUV4cCwgX01vZGUuRXhwcmVzc2lvbiksIHRoaXMuX3Zpc2l0KGFzdC5mYWxzZUV4cCwgX01vZGUuRXhwcmVzc2lvbiksXG4gICAgICAgICAgICB0aGlzLmNvbnZlcnRTb3VyY2VTcGFuKGFzdC5zcGFuKSkpO1xuICB9XG5cbiAgdmlzaXRQaXBlKGFzdDogY2RBc3QuQmluZGluZ1BpcGUsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXG4gICAgICAgIGBJbGxlZ2FsIHN0YXRlOiBQaXBlcyBzaG91bGQgaGF2ZSBiZWVuIGNvbnZlcnRlZCBpbnRvIGZ1bmN0aW9ucy4gUGlwZTogJHthc3QubmFtZX1gKTtcbiAgfVxuXG4gIHZpc2l0SW1wbGljaXRSZWNlaXZlcihhc3Q6IGNkQXN0LkltcGxpY2l0UmVjZWl2ZXIsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICBlbnN1cmVFeHByZXNzaW9uTW9kZShtb2RlLCBhc3QpO1xuICAgIHRoaXMudXNlc0ltcGxpY2l0UmVjZWl2ZXIgPSB0cnVlO1xuICAgIHJldHVybiB0aGlzLl9pbXBsaWNpdFJlY2VpdmVyO1xuICB9XG5cbiAgdmlzaXRUaGlzUmVjZWl2ZXIoYXN0OiBjZEFzdC5UaGlzUmVjZWl2ZXIsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy52aXNpdEltcGxpY2l0UmVjZWl2ZXIoYXN0LCBtb2RlKTtcbiAgfVxuXG4gIHZpc2l0SW50ZXJwb2xhdGlvbihhc3Q6IGNkQXN0LkludGVycG9sYXRpb24sIG1vZGU6IF9Nb2RlKTogSW50ZXJwb2xhdGlvbkV4cHJlc3Npb24ge1xuICAgIGlmICghdGhpcy5zdXBwb3J0c0ludGVycG9sYXRpb24pIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcignVW5leHBlY3RlZCBpbnRlcnBvbGF0aW9uJyk7XG4gICAgfVxuXG4gICAgZW5zdXJlRXhwcmVzc2lvbk1vZGUobW9kZSwgYXN0KTtcbiAgICBsZXQgYXJnczogby5FeHByZXNzaW9uW10gPSBbXTtcbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGFzdC5zdHJpbmdzLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgYXJncy5wdXNoKG8ubGl0ZXJhbChhc3Quc3RyaW5nc1tpXSkpO1xuICAgICAgYXJncy5wdXNoKHRoaXMuX3Zpc2l0KGFzdC5leHByZXNzaW9uc1tpXSwgX01vZGUuRXhwcmVzc2lvbikpO1xuICAgIH1cbiAgICBhcmdzLnB1c2goby5saXRlcmFsKGFzdC5zdHJpbmdzW2FzdC5zdHJpbmdzLmxlbmd0aCAtIDFdKSk7XG5cbiAgICAvLyBJZiB3ZSdyZSBkZWFsaW5nIHdpdGggYW4gaW50ZXJwb2xhdGlvbiBvZiAxIHZhbHVlIHdpdGggYW4gZW1wdHkgcHJlZml4IGFuZCBzdWZmaXgsIHJlZHVjZSB0aGVcbiAgICAvLyBhcmdzIHJldHVybmVkIHRvIGp1c3QgdGhlIHZhbHVlLCBiZWNhdXNlIHdlJ3JlIGdvaW5nIHRvIHBhc3MgaXQgdG8gYSBzcGVjaWFsIGluc3RydWN0aW9uLlxuICAgIGNvbnN0IHN0cmluZ3MgPSBhc3Quc3RyaW5ncztcbiAgICBpZiAoc3RyaW5ncy5sZW5ndGggPT09IDIgJiYgc3RyaW5nc1swXSA9PT0gJycgJiYgc3RyaW5nc1sxXSA9PT0gJycpIHtcbiAgICAgIC8vIFNpbmdsZSBhcmd1bWVudCBpbnRlcnBvbGF0ZSBpbnN0cnVjdGlvbnMuXG4gICAgICBhcmdzID0gW2FyZ3NbMV1dO1xuICAgIH0gZWxzZSBpZiAoYXN0LmV4cHJlc3Npb25zLmxlbmd0aCA+PSA5KSB7XG4gICAgICAvLyA5IG9yIG1vcmUgYXJndW1lbnRzIG11c3QgYmUgcGFzc2VkIHRvIHRoZSBgaW50ZXJwb2xhdGVWYC1zdHlsZSBpbnN0cnVjdGlvbnMsIHdoaWNoIGFjY2VwdFxuICAgICAgLy8gYW4gYXJyYXkgb2YgYXJndW1lbnRzXG4gICAgICBhcmdzID0gW28ubGl0ZXJhbEFycihhcmdzKV07XG4gICAgfVxuXG4gICAgcmV0dXJuIG5ldyBJbnRlcnBvbGF0aW9uRXhwcmVzc2lvbihhcmdzKTtcbiAgfVxuXG4gIHZpc2l0S2V5ZWRSZWFkKGFzdDogY2RBc3QuS2V5ZWRSZWFkLCBtb2RlOiBfTW9kZSk6IGFueSB7XG4gICAgY29uc3QgbGVmdE1vc3RTYWZlID0gdGhpcy5sZWZ0TW9zdFNhZmVOb2RlKGFzdCk7XG4gICAgaWYgKGxlZnRNb3N0U2FmZSkge1xuICAgICAgcmV0dXJuIHRoaXMuY29udmVydFNhZmVBY2Nlc3MoYXN0LCBsZWZ0TW9zdFNhZmUsIG1vZGUpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY29udmVydFRvU3RhdGVtZW50SWZOZWVkZWQoXG4gICAgICAgICAgbW9kZSxcbiAgICAgICAgICB0aGlzLl92aXNpdChhc3QucmVjZWl2ZXIsIF9Nb2RlLkV4cHJlc3Npb24pLmtleSh0aGlzLl92aXNpdChhc3Qua2V5LCBfTW9kZS5FeHByZXNzaW9uKSkpO1xuICAgIH1cbiAgfVxuXG4gIHZpc2l0S2V5ZWRXcml0ZShhc3Q6IGNkQXN0LktleWVkV3JpdGUsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICBjb25zdCBvYmo6IG8uRXhwcmVzc2lvbiA9IHRoaXMuX3Zpc2l0KGFzdC5yZWNlaXZlciwgX01vZGUuRXhwcmVzc2lvbik7XG4gICAgY29uc3Qga2V5OiBvLkV4cHJlc3Npb24gPSB0aGlzLl92aXNpdChhc3Qua2V5LCBfTW9kZS5FeHByZXNzaW9uKTtcbiAgICBjb25zdCB2YWx1ZTogby5FeHByZXNzaW9uID0gdGhpcy5fdmlzaXQoYXN0LnZhbHVlLCBfTW9kZS5FeHByZXNzaW9uKTtcblxuICAgIGlmIChvYmogPT09IHRoaXMuX2ltcGxpY2l0UmVjZWl2ZXIpIHtcbiAgICAgIHRoaXMuX2xvY2FsUmVzb2x2ZXIubWF5YmVSZXN0b3JlVmlldygpO1xuICAgIH1cblxuICAgIHJldHVybiBjb252ZXJ0VG9TdGF0ZW1lbnRJZk5lZWRlZChtb2RlLCBvYmoua2V5KGtleSkuc2V0KHZhbHVlKSk7XG4gIH1cblxuICB2aXNpdExpdGVyYWxBcnJheShhc3Q6IGNkQXN0LkxpdGVyYWxBcnJheSwgbW9kZTogX01vZGUpOiBhbnkge1xuICAgIHRocm93IG5ldyBFcnJvcihgSWxsZWdhbCBTdGF0ZTogbGl0ZXJhbCBhcnJheXMgc2hvdWxkIGhhdmUgYmVlbiBjb252ZXJ0ZWQgaW50byBmdW5jdGlvbnNgKTtcbiAgfVxuXG4gIHZpc2l0TGl0ZXJhbE1hcChhc3Q6IGNkQXN0LkxpdGVyYWxNYXAsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoYElsbGVnYWwgU3RhdGU6IGxpdGVyYWwgbWFwcyBzaG91bGQgaGF2ZSBiZWVuIGNvbnZlcnRlZCBpbnRvIGZ1bmN0aW9uc2ApO1xuICB9XG5cbiAgdmlzaXRMaXRlcmFsUHJpbWl0aXZlKGFzdDogY2RBc3QuTGl0ZXJhbFByaW1pdGl2ZSwgbW9kZTogX01vZGUpOiBhbnkge1xuICAgIC8vIEZvciBsaXRlcmFsIHZhbHVlcyBvZiBudWxsLCB1bmRlZmluZWQsIHRydWUsIG9yIGZhbHNlIGFsbG93IHR5cGUgaW50ZXJmZXJlbmNlXG4gICAgLy8gdG8gaW5mZXIgdGhlIHR5cGUuXG4gICAgY29uc3QgdHlwZSA9XG4gICAgICAgIGFzdC52YWx1ZSA9PT0gbnVsbCB8fCBhc3QudmFsdWUgPT09IHVuZGVmaW5lZCB8fCBhc3QudmFsdWUgPT09IHRydWUgfHwgYXN0LnZhbHVlID09PSB0cnVlID9cbiAgICAgICAgby5JTkZFUlJFRF9UWVBFIDpcbiAgICAgICAgdW5kZWZpbmVkO1xuICAgIHJldHVybiBjb252ZXJ0VG9TdGF0ZW1lbnRJZk5lZWRlZChcbiAgICAgICAgbW9kZSwgby5saXRlcmFsKGFzdC52YWx1ZSwgdHlwZSwgdGhpcy5jb252ZXJ0U291cmNlU3Bhbihhc3Quc3BhbikpKTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldExvY2FsKG5hbWU6IHN0cmluZywgcmVjZWl2ZXI6IGNkQXN0LkFTVCk6IG8uRXhwcmVzc2lvbnxudWxsIHtcbiAgICBpZiAodGhpcy5fbG9jYWxSZXNvbHZlci5nbG9iYWxzPy5oYXMobmFtZSkgJiYgcmVjZWl2ZXIgaW5zdGFuY2VvZiBjZEFzdC5UaGlzUmVjZWl2ZXIpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9sb2NhbFJlc29sdmVyLmdldExvY2FsKG5hbWUpO1xuICB9XG5cbiAgdmlzaXRQcmVmaXhOb3QoYXN0OiBjZEFzdC5QcmVmaXhOb3QsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICByZXR1cm4gY29udmVydFRvU3RhdGVtZW50SWZOZWVkZWQobW9kZSwgby5ub3QodGhpcy5fdmlzaXQoYXN0LmV4cHJlc3Npb24sIF9Nb2RlLkV4cHJlc3Npb24pKSk7XG4gIH1cblxuICB2aXNpdE5vbk51bGxBc3NlcnQoYXN0OiBjZEFzdC5Ob25OdWxsQXNzZXJ0LCBtb2RlOiBfTW9kZSk6IGFueSB7XG4gICAgcmV0dXJuIGNvbnZlcnRUb1N0YXRlbWVudElmTmVlZGVkKG1vZGUsIHRoaXMuX3Zpc2l0KGFzdC5leHByZXNzaW9uLCBfTW9kZS5FeHByZXNzaW9uKSk7XG4gIH1cblxuICB2aXNpdFByb3BlcnR5UmVhZChhc3Q6IGNkQXN0LlByb3BlcnR5UmVhZCwgbW9kZTogX01vZGUpOiBhbnkge1xuICAgIGNvbnN0IGxlZnRNb3N0U2FmZSA9IHRoaXMubGVmdE1vc3RTYWZlTm9kZShhc3QpO1xuICAgIGlmIChsZWZ0TW9zdFNhZmUpIHtcbiAgICAgIHJldHVybiB0aGlzLmNvbnZlcnRTYWZlQWNjZXNzKGFzdCwgbGVmdE1vc3RTYWZlLCBtb2RlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbGV0IHJlc3VsdDogYW55ID0gbnVsbDtcbiAgICAgIGNvbnN0IHByZXZVc2VzSW1wbGljaXRSZWNlaXZlciA9IHRoaXMudXNlc0ltcGxpY2l0UmVjZWl2ZXI7XG4gICAgICBjb25zdCByZWNlaXZlciA9IHRoaXMuX3Zpc2l0KGFzdC5yZWNlaXZlciwgX01vZGUuRXhwcmVzc2lvbik7XG4gICAgICBpZiAocmVjZWl2ZXIgPT09IHRoaXMuX2ltcGxpY2l0UmVjZWl2ZXIpIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5fZ2V0TG9jYWwoYXN0Lm5hbWUsIGFzdC5yZWNlaXZlcik7XG4gICAgICAgIGlmIChyZXN1bHQpIHtcbiAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBwcmV2aW91cyBcInVzZXNJbXBsaWNpdFJlY2VpdmVyXCIgc3RhdGUgc2luY2UgdGhlIGltcGxpY2l0XG4gICAgICAgICAgLy8gcmVjZWl2ZXIgaGFzIGJlZW4gcmVwbGFjZWQgd2l0aCBhIHJlc29sdmVkIGxvY2FsIGV4cHJlc3Npb24uXG4gICAgICAgICAgdGhpcy51c2VzSW1wbGljaXRSZWNlaXZlciA9IHByZXZVc2VzSW1wbGljaXRSZWNlaXZlcjtcbiAgICAgICAgICB0aGlzLmFkZEltcGxpY2l0UmVjZWl2ZXJBY2Nlc3MoYXN0Lm5hbWUpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAocmVzdWx0ID09IG51bGwpIHtcbiAgICAgICAgcmVzdWx0ID0gcmVjZWl2ZXIucHJvcChhc3QubmFtZSwgdGhpcy5jb252ZXJ0U291cmNlU3Bhbihhc3Quc3BhbikpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGNvbnZlcnRUb1N0YXRlbWVudElmTmVlZGVkKG1vZGUsIHJlc3VsdCk7XG4gICAgfVxuICB9XG5cbiAgdmlzaXRQcm9wZXJ0eVdyaXRlKGFzdDogY2RBc3QuUHJvcGVydHlXcml0ZSwgbW9kZTogX01vZGUpOiBhbnkge1xuICAgIGNvbnN0IHJlY2VpdmVyOiBvLkV4cHJlc3Npb24gPSB0aGlzLl92aXNpdChhc3QucmVjZWl2ZXIsIF9Nb2RlLkV4cHJlc3Npb24pO1xuICAgIGNvbnN0IHByZXZVc2VzSW1wbGljaXRSZWNlaXZlciA9IHRoaXMudXNlc0ltcGxpY2l0UmVjZWl2ZXI7XG5cbiAgICBsZXQgdmFyRXhwcjogby5SZWFkUHJvcEV4cHJ8bnVsbCA9IG51bGw7XG4gICAgaWYgKHJlY2VpdmVyID09PSB0aGlzLl9pbXBsaWNpdFJlY2VpdmVyKSB7XG4gICAgICBjb25zdCBsb2NhbEV4cHIgPSB0aGlzLl9nZXRMb2NhbChhc3QubmFtZSwgYXN0LnJlY2VpdmVyKTtcbiAgICAgIGlmIChsb2NhbEV4cHIpIHtcbiAgICAgICAgaWYgKGxvY2FsRXhwciBpbnN0YW5jZW9mIG8uUmVhZFByb3BFeHByKSB7XG4gICAgICAgICAgLy8gSWYgdGhlIGxvY2FsIHZhcmlhYmxlIGlzIGEgcHJvcGVydHkgcmVhZCBleHByZXNzaW9uLCBpdCdzIGEgcmVmZXJlbmNlXG4gICAgICAgICAgLy8gdG8gYSAnY29udGV4dC5wcm9wZXJ0eScgdmFsdWUgYW5kIHdpbGwgYmUgdXNlZCBhcyB0aGUgdGFyZ2V0IG9mIHRoZVxuICAgICAgICAgIC8vIHdyaXRlIGV4cHJlc3Npb24uXG4gICAgICAgICAgdmFyRXhwciA9IGxvY2FsRXhwcjtcbiAgICAgICAgICAvLyBSZXN0b3JlIHRoZSBwcmV2aW91cyBcInVzZXNJbXBsaWNpdFJlY2VpdmVyXCIgc3RhdGUgc2luY2UgdGhlIGltcGxpY2l0XG4gICAgICAgICAgLy8gcmVjZWl2ZXIgaGFzIGJlZW4gcmVwbGFjZWQgd2l0aCBhIHJlc29sdmVkIGxvY2FsIGV4cHJlc3Npb24uXG4gICAgICAgICAgdGhpcy51c2VzSW1wbGljaXRSZWNlaXZlciA9IHByZXZVc2VzSW1wbGljaXRSZWNlaXZlcjtcbiAgICAgICAgICB0aGlzLmFkZEltcGxpY2l0UmVjZWl2ZXJBY2Nlc3MoYXN0Lm5hbWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE90aGVyd2lzZSBpdCdzIGFuIGVycm9yLlxuICAgICAgICAgIGNvbnN0IHJlY2VpdmVyID0gYXN0Lm5hbWU7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSAoYXN0LnZhbHVlIGluc3RhbmNlb2YgY2RBc3QuUHJvcGVydHlSZWFkKSA/IGFzdC52YWx1ZS5uYW1lIDogdW5kZWZpbmVkO1xuICAgICAgICAgIHRocm93IG5ldyBFcnJvcihgQ2Fubm90IGFzc2lnbiB2YWx1ZSBcIiR7dmFsdWV9XCIgdG8gdGVtcGxhdGUgdmFyaWFibGUgXCIke1xuICAgICAgICAgICAgICByZWNlaXZlcn1cIi4gVGVtcGxhdGUgdmFyaWFibGVzIGFyZSByZWFkLW9ubHkuYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy8gSWYgbm8gbG9jYWwgZXhwcmVzc2lvbiBjb3VsZCBiZSBwcm9kdWNlZCwgdXNlIHRoZSBvcmlnaW5hbCByZWNlaXZlcidzXG4gICAgLy8gcHJvcGVydHkgYXMgdGhlIHRhcmdldC5cbiAgICBpZiAodmFyRXhwciA9PT0gbnVsbCkge1xuICAgICAgdmFyRXhwciA9IHJlY2VpdmVyLnByb3AoYXN0Lm5hbWUsIHRoaXMuY29udmVydFNvdXJjZVNwYW4oYXN0LnNwYW4pKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnZlcnRUb1N0YXRlbWVudElmTmVlZGVkKG1vZGUsIHZhckV4cHIuc2V0KHRoaXMuX3Zpc2l0KGFzdC52YWx1ZSwgX01vZGUuRXhwcmVzc2lvbikpKTtcbiAgfVxuXG4gIHZpc2l0U2FmZVByb3BlcnR5UmVhZChhc3Q6IGNkQXN0LlNhZmVQcm9wZXJ0eVJlYWQsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5jb252ZXJ0U2FmZUFjY2Vzcyhhc3QsIHRoaXMubGVmdE1vc3RTYWZlTm9kZShhc3QpLCBtb2RlKTtcbiAgfVxuXG4gIHZpc2l0U2FmZUtleWVkUmVhZChhc3Q6IGNkQXN0LlNhZmVLZXllZFJlYWQsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICByZXR1cm4gdGhpcy5jb252ZXJ0U2FmZUFjY2Vzcyhhc3QsIHRoaXMubGVmdE1vc3RTYWZlTm9kZShhc3QpLCBtb2RlKTtcbiAgfVxuXG4gIHZpc2l0QWxsKGFzdHM6IGNkQXN0LkFTVFtdLCBtb2RlOiBfTW9kZSk6IGFueSB7XG4gICAgcmV0dXJuIGFzdHMubWFwKGFzdCA9PiB0aGlzLl92aXNpdChhc3QsIG1vZGUpKTtcbiAgfVxuXG4gIHZpc2l0Q2FsbChhc3Q6IGNkQXN0LkNhbGwsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICBjb25zdCBsZWZ0TW9zdFNhZmUgPSB0aGlzLmxlZnRNb3N0U2FmZU5vZGUoYXN0KTtcbiAgICBpZiAobGVmdE1vc3RTYWZlKSB7XG4gICAgICByZXR1cm4gdGhpcy5jb252ZXJ0U2FmZUFjY2Vzcyhhc3QsIGxlZnRNb3N0U2FmZSwgbW9kZSk7XG4gICAgfVxuXG4gICAgY29uc3QgY29udmVydGVkQXJncyA9IHRoaXMudmlzaXRBbGwoYXN0LmFyZ3MsIF9Nb2RlLkV4cHJlc3Npb24pO1xuXG4gICAgaWYgKGFzdCBpbnN0YW5jZW9mIEJ1aWx0aW5GdW5jdGlvbkNhbGwpIHtcbiAgICAgIHJldHVybiBjb252ZXJ0VG9TdGF0ZW1lbnRJZk5lZWRlZChtb2RlLCBhc3QuY29udmVydGVyKGNvbnZlcnRlZEFyZ3MpKTtcbiAgICB9XG5cbiAgICBjb25zdCByZWNlaXZlciA9IGFzdC5yZWNlaXZlcjtcbiAgICBpZiAocmVjZWl2ZXIgaW5zdGFuY2VvZiBjZEFzdC5Qcm9wZXJ0eVJlYWQgJiZcbiAgICAgICAgcmVjZWl2ZXIucmVjZWl2ZXIgaW5zdGFuY2VvZiBjZEFzdC5JbXBsaWNpdFJlY2VpdmVyICYmXG4gICAgICAgICEocmVjZWl2ZXIucmVjZWl2ZXIgaW5zdGFuY2VvZiBjZEFzdC5UaGlzUmVjZWl2ZXIpICYmIHJlY2VpdmVyLm5hbWUgPT09ICckYW55Jykge1xuICAgICAgaWYgKGNvbnZlcnRlZEFyZ3MubGVuZ3RoICE9PSAxKSB7XG4gICAgICAgIHRocm93IG5ldyBFcnJvcihgSW52YWxpZCBjYWxsIHRvICRhbnksIGV4cGVjdGVkIDEgYXJndW1lbnQgYnV0IHJlY2VpdmVkICR7XG4gICAgICAgICAgICBjb252ZXJ0ZWRBcmdzLmxlbmd0aCB8fCAnbm9uZSd9YCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gY29udmVydFRvU3RhdGVtZW50SWZOZWVkZWQobW9kZSwgY29udmVydGVkQXJnc1swXSBhcyBvLkV4cHJlc3Npb24pO1xuICAgIH1cblxuICAgIGNvbnN0IGNhbGwgPSB0aGlzLl92aXNpdChyZWNlaXZlciwgX01vZGUuRXhwcmVzc2lvbilcbiAgICAgICAgICAgICAgICAgICAgIC5jYWxsRm4oY29udmVydGVkQXJncywgdGhpcy5jb252ZXJ0U291cmNlU3Bhbihhc3Quc3BhbikpO1xuICAgIHJldHVybiBjb252ZXJ0VG9TdGF0ZW1lbnRJZk5lZWRlZChtb2RlLCBjYWxsKTtcbiAgfVxuXG4gIHZpc2l0U2FmZUNhbGwoYXN0OiBjZEFzdC5TYWZlQ2FsbCwgbW9kZTogX01vZGUpOiBhbnkge1xuICAgIHJldHVybiB0aGlzLmNvbnZlcnRTYWZlQWNjZXNzKGFzdCwgdGhpcy5sZWZ0TW9zdFNhZmVOb2RlKGFzdCksIG1vZGUpO1xuICB9XG5cbiAgcHJpdmF0ZSBfdmlzaXQoYXN0OiBjZEFzdC5BU1QsIG1vZGU6IF9Nb2RlKTogYW55IHtcbiAgICBjb25zdCByZXN1bHQgPSB0aGlzLl9yZXN1bHRNYXAuZ2V0KGFzdCk7XG4gICAgaWYgKHJlc3VsdCkgcmV0dXJuIHJlc3VsdDtcbiAgICByZXR1cm4gKHRoaXMuX25vZGVNYXAuZ2V0KGFzdCkgfHwgYXN0KS52aXNpdCh0aGlzLCBtb2RlKTtcbiAgfVxuXG4gIHByaXZhdGUgY29udmVydFNhZmVBY2Nlc3MoXG4gICAgICBhc3Q6IGNkQXN0LkFTVCwgbGVmdE1vc3RTYWZlOiBjZEFzdC5TYWZlUHJvcGVydHlSZWFkfGNkQXN0LlNhZmVLZXllZFJlYWR8Y2RBc3QuU2FmZUNhbGwsXG4gICAgICBtb2RlOiBfTW9kZSk6IGFueSB7XG4gICAgLy8gSWYgdGhlIGV4cHJlc3Npb24gY29udGFpbnMgYSBzYWZlIGFjY2VzcyBub2RlIG9uIHRoZSBsZWZ0IGl0IG5lZWRzIHRvIGJlIGNvbnZlcnRlZCB0b1xuICAgIC8vIGFuIGV4cHJlc3Npb24gdGhhdCBndWFyZHMgdGhlIGFjY2VzcyB0byB0aGUgbWVtYmVyIGJ5IGNoZWNraW5nIHRoZSByZWNlaXZlciBmb3IgYmxhbmsuIEFzXG4gICAgLy8gZXhlY3V0aW9uIHByb2NlZWRzIGZyb20gbGVmdCB0byByaWdodCwgdGhlIGxlZnQgbW9zdCBwYXJ0IG9mIHRoZSBleHByZXNzaW9uIG11c3QgYmUgZ3VhcmRlZFxuICAgIC8vIGZpcnN0IGJ1dCwgYmVjYXVzZSBtZW1iZXIgYWNjZXNzIGlzIGxlZnQgYXNzb2NpYXRpdmUsIHRoZSByaWdodCBzaWRlIG9mIHRoZSBleHByZXNzaW9uIGlzIGF0XG4gICAgLy8gdGhlIHRvcCBvZiB0aGUgQVNULiBUaGUgZGVzaXJlZCByZXN1bHQgcmVxdWlyZXMgbGlmdGluZyBhIGNvcHkgb2YgdGhlIGxlZnQgcGFydCBvZiB0aGVcbiAgICAvLyBleHByZXNzaW9uIHVwIHRvIHRlc3QgaXQgZm9yIGJsYW5rIGJlZm9yZSBnZW5lcmF0aW5nIHRoZSB1bmd1YXJkZWQgdmVyc2lvbi5cblxuICAgIC8vIENvbnNpZGVyLCBmb3IgZXhhbXBsZSB0aGUgZm9sbG93aW5nIGV4cHJlc3Npb246IGE/LmIuYz8uZC5lXG5cbiAgICAvLyBUaGlzIHJlc3VsdHMgaW4gdGhlIGFzdDpcbiAgICAvLyAgICAgICAgIC5cbiAgICAvLyAgICAgICAgLyBcXFxuICAgIC8vICAgICAgID8uICAgZVxuICAgIC8vICAgICAgLyAgXFxcbiAgICAvLyAgICAgLiAgICBkXG4gICAgLy8gICAgLyBcXFxuICAgIC8vICAgPy4gIGNcbiAgICAvLyAgLyAgXFxcbiAgICAvLyBhICAgIGJcblxuICAgIC8vIFRoZSBmb2xsb3dpbmcgdHJlZSBzaG91bGQgYmUgZ2VuZXJhdGVkOlxuICAgIC8vXG4gICAgLy8gICAgICAgIC8tLS0tID8gLS0tLVxcXG4gICAgLy8gICAgICAgLyAgICAgIHwgICAgICBcXFxuICAgIC8vICAgICBhICAgLy0tLSA/IC0tLVxcICBudWxsXG4gICAgLy8gICAgICAgIC8gICAgIHwgICAgIFxcXG4gICAgLy8gICAgICAgLiAgICAgIC4gICAgIG51bGxcbiAgICAvLyAgICAgIC8gXFwgICAgLyBcXFxuICAgIC8vICAgICAuICBjICAgLiAgIGVcbiAgICAvLyAgICAvIFxcICAgIC8gXFxcbiAgICAvLyAgIGEgICBiICAuICAgZFxuICAgIC8vICAgICAgICAgLyBcXFxuICAgIC8vICAgICAgICAuICAgY1xuICAgIC8vICAgICAgIC8gXFxcbiAgICAvLyAgICAgIGEgICBiXG4gICAgLy9cbiAgICAvLyBOb3RpY2UgdGhhdCB0aGUgZmlyc3QgZ3VhcmQgY29uZGl0aW9uIGlzIHRoZSBsZWZ0IGhhbmQgb2YgdGhlIGxlZnQgbW9zdCBzYWZlIGFjY2VzcyBub2RlXG4gICAgLy8gd2hpY2ggY29tZXMgaW4gYXMgbGVmdE1vc3RTYWZlIHRvIHRoaXMgcm91dGluZS5cblxuICAgIGxldCBndWFyZGVkRXhwcmVzc2lvbiA9IHRoaXMuX3Zpc2l0KGxlZnRNb3N0U2FmZS5yZWNlaXZlciwgX01vZGUuRXhwcmVzc2lvbik7XG4gICAgbGV0IHRlbXBvcmFyeTogby5SZWFkVmFyRXhwcnx1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgaWYgKHRoaXMubmVlZHNUZW1wb3JhcnlJblNhZmVBY2Nlc3MobGVmdE1vc3RTYWZlLnJlY2VpdmVyKSkge1xuICAgICAgLy8gSWYgdGhlIGV4cHJlc3Npb24gaGFzIG1ldGhvZCBjYWxscyBvciBwaXBlcyB0aGVuIHdlIG5lZWQgdG8gc2F2ZSB0aGUgcmVzdWx0IGludG8gYVxuICAgICAgLy8gdGVtcG9yYXJ5IHZhcmlhYmxlIHRvIGF2b2lkIGNhbGxpbmcgc3RhdGVmdWwgb3IgaW1wdXJlIGNvZGUgbW9yZSB0aGFuIG9uY2UuXG4gICAgICB0ZW1wb3JhcnkgPSB0aGlzLmFsbG9jYXRlVGVtcG9yYXJ5KCk7XG5cbiAgICAgIC8vIFByZXNlcnZlIHRoZSByZXN1bHQgaW4gdGhlIHRlbXBvcmFyeSB2YXJpYWJsZVxuICAgICAgZ3VhcmRlZEV4cHJlc3Npb24gPSB0ZW1wb3Jhcnkuc2V0KGd1YXJkZWRFeHByZXNzaW9uKTtcblxuICAgICAgLy8gRW5zdXJlIGFsbCBmdXJ0aGVyIHJlZmVyZW5jZXMgdG8gdGhlIGd1YXJkZWQgZXhwcmVzc2lvbiByZWZlciB0byB0aGUgdGVtcG9yYXJ5IGluc3RlYWQuXG4gICAgICB0aGlzLl9yZXN1bHRNYXAuc2V0KGxlZnRNb3N0U2FmZS5yZWNlaXZlciwgdGVtcG9yYXJ5KTtcbiAgICB9XG4gICAgY29uc3QgY29uZGl0aW9uID0gZ3VhcmRlZEV4cHJlc3Npb24uaXNCbGFuaygpO1xuXG4gICAgLy8gQ29udmVydCB0aGUgYXN0IHRvIGFuIHVuZ3VhcmRlZCBhY2Nlc3MgdG8gdGhlIHJlY2VpdmVyJ3MgbWVtYmVyLiBUaGUgbWFwIHdpbGwgc3Vic3RpdHV0ZVxuICAgIC8vIGxlZnRNb3N0Tm9kZSB3aXRoIGl0cyB1bmd1YXJkZWQgdmVyc2lvbiBpbiB0aGUgY2FsbCB0byBgdGhpcy52aXNpdCgpYC5cbiAgICBpZiAobGVmdE1vc3RTYWZlIGluc3RhbmNlb2YgY2RBc3QuU2FmZUNhbGwpIHtcbiAgICAgIHRoaXMuX25vZGVNYXAuc2V0KFxuICAgICAgICAgIGxlZnRNb3N0U2FmZSxcbiAgICAgICAgICBuZXcgY2RBc3QuQ2FsbChcbiAgICAgICAgICAgICAgbGVmdE1vc3RTYWZlLnNwYW4sIGxlZnRNb3N0U2FmZS5zb3VyY2VTcGFuLCBsZWZ0TW9zdFNhZmUucmVjZWl2ZXIsIGxlZnRNb3N0U2FmZS5hcmdzLFxuICAgICAgICAgICAgICBsZWZ0TW9zdFNhZmUuYXJndW1lbnRTcGFuKSk7XG4gICAgfSBlbHNlIGlmIChsZWZ0TW9zdFNhZmUgaW5zdGFuY2VvZiBjZEFzdC5TYWZlS2V5ZWRSZWFkKSB7XG4gICAgICB0aGlzLl9ub2RlTWFwLnNldChcbiAgICAgICAgICBsZWZ0TW9zdFNhZmUsXG4gICAgICAgICAgbmV3IGNkQXN0LktleWVkUmVhZChcbiAgICAgICAgICAgICAgbGVmdE1vc3RTYWZlLnNwYW4sIGxlZnRNb3N0U2FmZS5zb3VyY2VTcGFuLCBsZWZ0TW9zdFNhZmUucmVjZWl2ZXIsIGxlZnRNb3N0U2FmZS5rZXkpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fbm9kZU1hcC5zZXQoXG4gICAgICAgICAgbGVmdE1vc3RTYWZlLFxuICAgICAgICAgIG5ldyBjZEFzdC5Qcm9wZXJ0eVJlYWQoXG4gICAgICAgICAgICAgIGxlZnRNb3N0U2FmZS5zcGFuLCBsZWZ0TW9zdFNhZmUuc291cmNlU3BhbiwgbGVmdE1vc3RTYWZlLm5hbWVTcGFuLFxuICAgICAgICAgICAgICBsZWZ0TW9zdFNhZmUucmVjZWl2ZXIsIGxlZnRNb3N0U2FmZS5uYW1lKSk7XG4gICAgfVxuXG4gICAgLy8gUmVjdXJzaXZlbHkgY29udmVydCB0aGUgbm9kZSBub3cgd2l0aG91dCB0aGUgZ3VhcmRlZCBtZW1iZXIgYWNjZXNzLlxuICAgIGNvbnN0IGFjY2VzcyA9IHRoaXMuX3Zpc2l0KGFzdCwgX01vZGUuRXhwcmVzc2lvbik7XG5cbiAgICAvLyBSZW1vdmUgdGhlIG1hcHBpbmcuIFRoaXMgaXMgbm90IHN0cmljdGx5IHJlcXVpcmVkIGFzIHRoZSBjb252ZXJ0ZXIgb25seSB0cmF2ZXJzZXMgZWFjaCBub2RlXG4gICAgLy8gb25jZSBidXQgaXMgc2FmZXIgaWYgdGhlIGNvbnZlcnNpb24gaXMgY2hhbmdlZCB0byB0cmF2ZXJzZSB0aGUgbm9kZXMgbW9yZSB0aGFuIG9uY2UuXG4gICAgdGhpcy5fbm9kZU1hcC5kZWxldGUobGVmdE1vc3RTYWZlKTtcblxuICAgIC8vIElmIHdlIGFsbG9jYXRlZCBhIHRlbXBvcmFyeSwgcmVsZWFzZSBpdC5cbiAgICBpZiAodGVtcG9yYXJ5KSB7XG4gICAgICB0aGlzLnJlbGVhc2VUZW1wb3JhcnkodGVtcG9yYXJ5KTtcbiAgICB9XG5cbiAgICAvLyBQcm9kdWNlIHRoZSBjb25kaXRpb25hbFxuICAgIHJldHVybiBjb252ZXJ0VG9TdGF0ZW1lbnRJZk5lZWRlZChtb2RlLCBjb25kaXRpb24uY29uZGl0aW9uYWwoby5OVUxMX0VYUFIsIGFjY2VzcykpO1xuICB9XG5cbiAgcHJpdmF0ZSBjb252ZXJ0TnVsbGlzaENvYWxlc2NlKGFzdDogY2RBc3QuQmluYXJ5LCBtb2RlOiBfTW9kZSk6IGFueSB7XG4gICAgY29uc3QgbGVmdDogby5FeHByZXNzaW9uID0gdGhpcy5fdmlzaXQoYXN0LmxlZnQsIF9Nb2RlLkV4cHJlc3Npb24pO1xuICAgIGNvbnN0IHJpZ2h0OiBvLkV4cHJlc3Npb24gPSB0aGlzLl92aXNpdChhc3QucmlnaHQsIF9Nb2RlLkV4cHJlc3Npb24pO1xuICAgIGNvbnN0IHRlbXBvcmFyeSA9IHRoaXMuYWxsb2NhdGVUZW1wb3JhcnkoKTtcbiAgICB0aGlzLnJlbGVhc2VUZW1wb3JhcnkodGVtcG9yYXJ5KTtcblxuICAgIC8vIEdlbmVyYXRlIHRoZSBmb2xsb3dpbmcgZXhwcmVzc2lvbi4gSXQgaXMgaWRlbnRpY2FsIHRvIGhvdyBUU1xuICAgIC8vIHRyYW5zcGlsZXMgYmluYXJ5IGV4cHJlc3Npb25zIHdpdGggYSBudWxsaXNoIGNvYWxlc2Npbmcgb3BlcmF0b3IuXG4gICAgLy8gbGV0IHRlbXA7XG4gICAgLy8gKHRlbXAgPSBhKSAhPT0gbnVsbCAmJiB0ZW1wICE9PSB1bmRlZmluZWQgPyB0ZW1wIDogYjtcbiAgICByZXR1cm4gY29udmVydFRvU3RhdGVtZW50SWZOZWVkZWQoXG4gICAgICAgIG1vZGUsXG4gICAgICAgIHRlbXBvcmFyeS5zZXQobGVmdClcbiAgICAgICAgICAgIC5ub3RJZGVudGljYWwoby5OVUxMX0VYUFIpXG4gICAgICAgICAgICAuYW5kKHRlbXBvcmFyeS5ub3RJZGVudGljYWwoby5saXRlcmFsKHVuZGVmaW5lZCkpKVxuICAgICAgICAgICAgLmNvbmRpdGlvbmFsKHRlbXBvcmFyeSwgcmlnaHQpKTtcbiAgfVxuXG4gIC8vIEdpdmVuIGFuIGV4cHJlc3Npb24gb2YgdGhlIGZvcm0gYT8uYi5jPy5kLmUgdGhlbiB0aGUgbGVmdCBtb3N0IHNhZmUgbm9kZSBpc1xuICAvLyB0aGUgKGE/LmIpLiBUaGUgLiBhbmQgPy4gYXJlIGxlZnQgYXNzb2NpYXRpdmUgdGh1cyBjYW4gYmUgcmV3cml0dGVuIGFzOlxuICAvLyAoKCgoYT8uYykuYikuYyk/LmQpLmUuIFRoaXMgcmV0dXJucyB0aGUgbW9zdCBkZWVwbHkgbmVzdGVkIHNhZmUgcmVhZCBvclxuICAvLyBzYWZlIG1ldGhvZCBjYWxsIGFzIHRoaXMgbmVlZHMgdG8gYmUgdHJhbnNmb3JtZWQgaW5pdGlhbGx5IHRvOlxuICAvLyAgIGEgPT0gbnVsbCA/IG51bGwgOiBhLmMuYi5jPy5kLmVcbiAgLy8gdGhlbiB0bzpcbiAgLy8gICBhID09IG51bGwgPyBudWxsIDogYS5iLmMgPT0gbnVsbCA/IG51bGwgOiBhLmIuYy5kLmVcbiAgcHJpdmF0ZSBsZWZ0TW9zdFNhZmVOb2RlKGFzdDogY2RBc3QuQVNUKTogY2RBc3QuU2FmZVByb3BlcnR5UmVhZHxjZEFzdC5TYWZlS2V5ZWRSZWFkIHtcbiAgICBjb25zdCB2aXNpdCA9ICh2aXNpdG9yOiBjZEFzdC5Bc3RWaXNpdG9yLCBhc3Q6IGNkQXN0LkFTVCk6IGFueSA9PiB7XG4gICAgICByZXR1cm4gKHRoaXMuX25vZGVNYXAuZ2V0KGFzdCkgfHwgYXN0KS52aXNpdCh2aXNpdG9yKTtcbiAgICB9O1xuICAgIHJldHVybiBhc3QudmlzaXQoe1xuICAgICAgdmlzaXRVbmFyeShhc3Q6IGNkQXN0LlVuYXJ5KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSxcbiAgICAgIHZpc2l0QmluYXJ5KGFzdDogY2RBc3QuQmluYXJ5KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSxcbiAgICAgIHZpc2l0Q2hhaW4oYXN0OiBjZEFzdC5DaGFpbikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0sXG4gICAgICB2aXNpdENvbmRpdGlvbmFsKGFzdDogY2RBc3QuQ29uZGl0aW9uYWwpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9LFxuICAgICAgdmlzaXRDYWxsKGFzdDogY2RBc3QuQ2FsbCkge1xuICAgICAgICByZXR1cm4gdmlzaXQodGhpcywgYXN0LnJlY2VpdmVyKTtcbiAgICAgIH0sXG4gICAgICB2aXNpdFNhZmVDYWxsKGFzdDogY2RBc3QuU2FmZUNhbGwpIHtcbiAgICAgICAgcmV0dXJuIHZpc2l0KHRoaXMsIGFzdC5yZWNlaXZlcikgfHwgYXN0O1xuICAgICAgfSxcbiAgICAgIHZpc2l0SW1wbGljaXRSZWNlaXZlcihhc3Q6IGNkQXN0LkltcGxpY2l0UmVjZWl2ZXIpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9LFxuICAgICAgdmlzaXRUaGlzUmVjZWl2ZXIoYXN0OiBjZEFzdC5UaGlzUmVjZWl2ZXIpIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9LFxuICAgICAgdmlzaXRJbnRlcnBvbGF0aW9uKGFzdDogY2RBc3QuSW50ZXJwb2xhdGlvbikge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0sXG4gICAgICB2aXNpdEtleWVkUmVhZChhc3Q6IGNkQXN0LktleWVkUmVhZCkge1xuICAgICAgICByZXR1cm4gdmlzaXQodGhpcywgYXN0LnJlY2VpdmVyKTtcbiAgICAgIH0sXG4gICAgICB2aXNpdEtleWVkV3JpdGUoYXN0OiBjZEFzdC5LZXllZFdyaXRlKSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSxcbiAgICAgIHZpc2l0TGl0ZXJhbEFycmF5KGFzdDogY2RBc3QuTGl0ZXJhbEFycmF5KSB7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfSxcbiAgICAgIHZpc2l0TGl0ZXJhbE1hcChhc3Q6IGNkQXN0LkxpdGVyYWxNYXApIHtcbiAgICAgICAgcmV0dXJuIG51bGw7XG4gICAgICB9LFxuICAgICAgdmlzaXRMaXRlcmFsUHJpbWl0aXZlKGFzdDogY2RBc3QuTGl0ZXJhbFByaW1pdGl2ZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0sXG4gICAgICB2aXNpdFBpcGUoYXN0OiBjZEFzdC5CaW5kaW5nUGlwZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0sXG4gICAgICB2aXNpdFByZWZpeE5vdChhc3Q6IGNkQXN0LlByZWZpeE5vdCkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0sXG4gICAgICB2aXNpdE5vbk51bGxBc3NlcnQoYXN0OiBjZEFzdC5Ob25OdWxsQXNzZXJ0KSB7XG4gICAgICAgIHJldHVybiB2aXNpdCh0aGlzLCBhc3QuZXhwcmVzc2lvbik7XG4gICAgICB9LFxuICAgICAgdmlzaXRQcm9wZXJ0eVJlYWQoYXN0OiBjZEFzdC5Qcm9wZXJ0eVJlYWQpIHtcbiAgICAgICAgcmV0dXJuIHZpc2l0KHRoaXMsIGFzdC5yZWNlaXZlcik7XG4gICAgICB9LFxuICAgICAgdmlzaXRQcm9wZXJ0eVdyaXRlKGFzdDogY2RBc3QuUHJvcGVydHlXcml0ZSkge1xuICAgICAgICByZXR1cm4gbnVsbDtcbiAgICAgIH0sXG4gICAgICB2aXNpdFNhZmVQcm9wZXJ0eVJlYWQoYXN0OiBjZEFzdC5TYWZlUHJvcGVydHlSZWFkKSB7XG4gICAgICAgIHJldHVybiB2aXNpdCh0aGlzLCBhc3QucmVjZWl2ZXIpIHx8IGFzdDtcbiAgICAgIH0sXG4gICAgICB2aXNpdFNhZmVLZXllZFJlYWQoYXN0OiBjZEFzdC5TYWZlS2V5ZWRSZWFkKSB7XG4gICAgICAgIHJldHVybiB2aXNpdCh0aGlzLCBhc3QucmVjZWl2ZXIpIHx8IGFzdDtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIC8vIFJldHVybnMgdHJ1ZSBvZiB0aGUgQVNUIGluY2x1ZGVzIGEgbWV0aG9kIG9yIGEgcGlwZSBpbmRpY2F0aW5nIHRoYXQsIGlmIHRoZVxuICAvLyBleHByZXNzaW9uIGlzIHVzZWQgYXMgdGhlIHRhcmdldCBvZiBhIHNhZmUgcHJvcGVydHkgb3IgbWV0aG9kIGFjY2VzcyB0aGVuXG4gIC8vIHRoZSBleHByZXNzaW9uIHNob3VsZCBiZSBzdG9yZWQgaW50byBhIHRlbXBvcmFyeSB2YXJpYWJsZS5cbiAgcHJpdmF0ZSBuZWVkc1RlbXBvcmFyeUluU2FmZUFjY2Vzcyhhc3Q6IGNkQXN0LkFTVCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHZpc2l0ID0gKHZpc2l0b3I6IGNkQXN0LkFzdFZpc2l0b3IsIGFzdDogY2RBc3QuQVNUKTogYm9vbGVhbiA9PiB7XG4gICAgICByZXR1cm4gYXN0ICYmICh0aGlzLl9ub2RlTWFwLmdldChhc3QpIHx8IGFzdCkudmlzaXQodmlzaXRvcik7XG4gICAgfTtcbiAgICBjb25zdCB2aXNpdFNvbWUgPSAodmlzaXRvcjogY2RBc3QuQXN0VmlzaXRvciwgYXN0OiBjZEFzdC5BU1RbXSk6IGJvb2xlYW4gPT4ge1xuICAgICAgcmV0dXJuIGFzdC5zb21lKGFzdCA9PiB2aXNpdCh2aXNpdG9yLCBhc3QpKTtcbiAgICB9O1xuICAgIHJldHVybiBhc3QudmlzaXQoe1xuICAgICAgdmlzaXRVbmFyeShhc3Q6IGNkQXN0LlVuYXJ5KTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB2aXNpdCh0aGlzLCBhc3QuZXhwcik7XG4gICAgICB9LFxuICAgICAgdmlzaXRCaW5hcnkoYXN0OiBjZEFzdC5CaW5hcnkpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHZpc2l0KHRoaXMsIGFzdC5sZWZ0KSB8fCB2aXNpdCh0aGlzLCBhc3QucmlnaHQpO1xuICAgICAgfSxcbiAgICAgIHZpc2l0Q2hhaW4oYXN0OiBjZEFzdC5DaGFpbikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9LFxuICAgICAgdmlzaXRDb25kaXRpb25hbChhc3Q6IGNkQXN0LkNvbmRpdGlvbmFsKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB2aXNpdCh0aGlzLCBhc3QuY29uZGl0aW9uKSB8fCB2aXNpdCh0aGlzLCBhc3QudHJ1ZUV4cCkgfHwgdmlzaXQodGhpcywgYXN0LmZhbHNlRXhwKTtcbiAgICAgIH0sXG4gICAgICB2aXNpdENhbGwoYXN0OiBjZEFzdC5DYWxsKSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSxcbiAgICAgIHZpc2l0U2FmZUNhbGwoYXN0OiBjZEFzdC5TYWZlQ2FsbCkge1xuICAgICAgICByZXR1cm4gdHJ1ZTtcbiAgICAgIH0sXG4gICAgICB2aXNpdEltcGxpY2l0UmVjZWl2ZXIoYXN0OiBjZEFzdC5JbXBsaWNpdFJlY2VpdmVyKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH0sXG4gICAgICB2aXNpdFRoaXNSZWNlaXZlcihhc3Q6IGNkQXN0LlRoaXNSZWNlaXZlcikge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9LFxuICAgICAgdmlzaXRJbnRlcnBvbGF0aW9uKGFzdDogY2RBc3QuSW50ZXJwb2xhdGlvbikge1xuICAgICAgICByZXR1cm4gdmlzaXRTb21lKHRoaXMsIGFzdC5leHByZXNzaW9ucyk7XG4gICAgICB9LFxuICAgICAgdmlzaXRLZXllZFJlYWQoYXN0OiBjZEFzdC5LZXllZFJlYWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSxcbiAgICAgIHZpc2l0S2V5ZWRXcml0ZShhc3Q6IGNkQXN0LktleWVkV3JpdGUpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfSxcbiAgICAgIHZpc2l0TGl0ZXJhbEFycmF5KGFzdDogY2RBc3QuTGl0ZXJhbEFycmF5KSB7XG4gICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgfSxcbiAgICAgIHZpc2l0TGl0ZXJhbE1hcChhc3Q6IGNkQXN0LkxpdGVyYWxNYXApIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9LFxuICAgICAgdmlzaXRMaXRlcmFsUHJpbWl0aXZlKGFzdDogY2RBc3QuTGl0ZXJhbFByaW1pdGl2ZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9LFxuICAgICAgdmlzaXRQaXBlKGFzdDogY2RBc3QuQmluZGluZ1BpcGUpIHtcbiAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICB9LFxuICAgICAgdmlzaXRQcmVmaXhOb3QoYXN0OiBjZEFzdC5QcmVmaXhOb3QpIHtcbiAgICAgICAgcmV0dXJuIHZpc2l0KHRoaXMsIGFzdC5leHByZXNzaW9uKTtcbiAgICAgIH0sXG4gICAgICB2aXNpdE5vbk51bGxBc3NlcnQoYXN0OiBjZEFzdC5QcmVmaXhOb3QpIHtcbiAgICAgICAgcmV0dXJuIHZpc2l0KHRoaXMsIGFzdC5leHByZXNzaW9uKTtcbiAgICAgIH0sXG4gICAgICB2aXNpdFByb3BlcnR5UmVhZChhc3Q6IGNkQXN0LlByb3BlcnR5UmVhZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9LFxuICAgICAgdmlzaXRQcm9wZXJ0eVdyaXRlKGFzdDogY2RBc3QuUHJvcGVydHlXcml0ZSkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9LFxuICAgICAgdmlzaXRTYWZlUHJvcGVydHlSZWFkKGFzdDogY2RBc3QuU2FmZVByb3BlcnR5UmVhZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9LFxuICAgICAgdmlzaXRTYWZlS2V5ZWRSZWFkKGFzdDogY2RBc3QuU2FmZUtleWVkUmVhZCkge1xuICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIGFsbG9jYXRlVGVtcG9yYXJ5KCk6IG8uUmVhZFZhckV4cHIge1xuICAgIGNvbnN0IHRlbXBOdW1iZXIgPSB0aGlzLl9jdXJyZW50VGVtcG9yYXJ5Kys7XG4gICAgdGhpcy50ZW1wb3JhcnlDb3VudCA9IE1hdGgubWF4KHRoaXMuX2N1cnJlbnRUZW1wb3JhcnksIHRoaXMudGVtcG9yYXJ5Q291bnQpO1xuICAgIHJldHVybiBuZXcgby5SZWFkVmFyRXhwcih0ZW1wb3JhcnlOYW1lKHRoaXMuYmluZGluZ0lkLCB0ZW1wTnVtYmVyKSk7XG4gIH1cblxuICBwcml2YXRlIHJlbGVhc2VUZW1wb3JhcnkodGVtcG9yYXJ5OiBvLlJlYWRWYXJFeHByKSB7XG4gICAgdGhpcy5fY3VycmVudFRlbXBvcmFyeS0tO1xuICAgIGlmICh0ZW1wb3JhcnkubmFtZSAhPSB0ZW1wb3JhcnlOYW1lKHRoaXMuYmluZGluZ0lkLCB0aGlzLl9jdXJyZW50VGVtcG9yYXJ5KSkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKGBUZW1wb3JhcnkgJHt0ZW1wb3JhcnkubmFtZX0gcmVsZWFzZWQgb3V0IG9mIG9yZGVyYCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gYWJzb2x1dGUgYFBhcnNlU291cmNlU3BhbmAgZnJvbSB0aGUgcmVsYXRpdmUgYFBhcnNlU3BhbmAuXG4gICAqXG4gICAqIGBQYXJzZVNwYW5gIG9iamVjdHMgYXJlIHJlbGF0aXZlIHRvIHRoZSBzdGFydCBvZiB0aGUgZXhwcmVzc2lvbi5cbiAgICogVGhpcyBtZXRob2QgY29udmVydHMgdGhlc2UgdG8gZnVsbCBgUGFyc2VTb3VyY2VTcGFuYCBvYmplY3RzIHRoYXRcbiAgICogc2hvdyB3aGVyZSB0aGUgc3BhbiBpcyB3aXRoaW4gdGhlIG92ZXJhbGwgc291cmNlIGZpbGUuXG4gICAqXG4gICAqIEBwYXJhbSBzcGFuIHRoZSByZWxhdGl2ZSBzcGFuIHRvIGNvbnZlcnQuXG4gICAqIEByZXR1cm5zIGEgYFBhcnNlU291cmNlU3BhbmAgZm9yIHRoZSBnaXZlbiBzcGFuIG9yIG51bGwgaWYgbm9cbiAgICogYGJhc2VTb3VyY2VTcGFuYCB3YXMgcHJvdmlkZWQgdG8gdGhpcyBjbGFzcy5cbiAgICovXG4gIHByaXZhdGUgY29udmVydFNvdXJjZVNwYW4oc3BhbjogY2RBc3QuUGFyc2VTcGFuKSB7XG4gICAgaWYgKHRoaXMuYmFzZVNvdXJjZVNwYW4pIHtcbiAgICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5iYXNlU291cmNlU3Bhbi5zdGFydC5tb3ZlQnkoc3Bhbi5zdGFydCk7XG4gICAgICBjb25zdCBlbmQgPSB0aGlzLmJhc2VTb3VyY2VTcGFuLnN0YXJ0Lm1vdmVCeShzcGFuLmVuZCk7XG4gICAgICBjb25zdCBmdWxsU3RhcnQgPSB0aGlzLmJhc2VTb3VyY2VTcGFuLmZ1bGxTdGFydC5tb3ZlQnkoc3Bhbi5zdGFydCk7XG4gICAgICByZXR1cm4gbmV3IFBhcnNlU291cmNlU3BhbihzdGFydCwgZW5kLCBmdWxsU3RhcnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gIH1cblxuICAvKiogQWRkcyB0aGUgbmFtZSBvZiBhbiBBU1QgdG8gdGhlIGxpc3Qgb2YgaW1wbGljaXQgcmVjZWl2ZXIgYWNjZXNzZXMuICovXG4gIHByaXZhdGUgYWRkSW1wbGljaXRSZWNlaXZlckFjY2VzcyhuYW1lOiBzdHJpbmcpIHtcbiAgICBpZiAodGhpcy5pbXBsaWNpdFJlY2VpdmVyQWNjZXNzZXMpIHtcbiAgICAgIHRoaXMuaW1wbGljaXRSZWNlaXZlckFjY2Vzc2VzLmFkZChuYW1lKTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gZmxhdHRlblN0YXRlbWVudHMoYXJnOiBhbnksIG91dHB1dDogby5TdGF0ZW1lbnRbXSkge1xuICBpZiAoQXJyYXkuaXNBcnJheShhcmcpKSB7XG4gICAgKDxhbnlbXT5hcmcpLmZvckVhY2goKGVudHJ5KSA9PiBmbGF0dGVuU3RhdGVtZW50cyhlbnRyeSwgb3V0cHV0KSk7XG4gIH0gZWxzZSB7XG4gICAgb3V0cHV0LnB1c2goYXJnKTtcbiAgfVxufVxuXG5mdW5jdGlvbiB1bnN1cHBvcnRlZCgpOiBuZXZlciB7XG4gIHRocm93IG5ldyBFcnJvcignVW5zdXBwb3J0ZWQgb3BlcmF0aW9uJyk7XG59XG5cbmNsYXNzIEludGVycG9sYXRpb25FeHByZXNzaW9uIGV4dGVuZHMgby5FeHByZXNzaW9uIHtcbiAgY29uc3RydWN0b3IocHVibGljIGFyZ3M6IG8uRXhwcmVzc2lvbltdKSB7XG4gICAgc3VwZXIobnVsbCwgbnVsbCk7XG4gIH1cblxuICBvdmVycmlkZSBpc0NvbnN0YW50ID0gdW5zdXBwb3J0ZWQ7XG4gIG92ZXJyaWRlIGlzRXF1aXZhbGVudCA9IHVuc3VwcG9ydGVkO1xuICBvdmVycmlkZSB2aXNpdEV4cHJlc3Npb24gPSB1bnN1cHBvcnRlZDtcbn1cblxuY2xhc3MgRGVmYXVsdExvY2FsUmVzb2x2ZXIgaW1wbGVtZW50cyBMb2NhbFJlc29sdmVyIHtcbiAgY29uc3RydWN0b3IocHVibGljIGdsb2JhbHM/OiBTZXQ8c3RyaW5nPikge31cbiAgbm90aWZ5SW1wbGljaXRSZWNlaXZlclVzZSgpOiB2b2lkIHt9XG4gIG1heWJlUmVzdG9yZVZpZXcoKTogdm9pZCB7fVxuICBnZXRMb2NhbChuYW1lOiBzdHJpbmcpOiBvLkV4cHJlc3Npb258bnVsbCB7XG4gICAgaWYgKG5hbWUgPT09IEV2ZW50SGFuZGxlclZhcnMuZXZlbnQubmFtZSkge1xuICAgICAgcmV0dXJuIEV2ZW50SGFuZGxlclZhcnMuZXZlbnQ7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG59XG5cbmV4cG9ydCBjbGFzcyBCdWlsdGluRnVuY3Rpb25DYWxsIGV4dGVuZHMgY2RBc3QuQ2FsbCB7XG4gIGNvbnN0cnVjdG9yKFxuICAgICAgc3BhbjogY2RBc3QuUGFyc2VTcGFuLCBzb3VyY2VTcGFuOiBjZEFzdC5BYnNvbHV0ZVNvdXJjZVNwYW4sIGFyZ3M6IGNkQXN0LkFTVFtdLFxuICAgICAgcHVibGljIGNvbnZlcnRlcjogQnVpbHRpbkNvbnZlcnRlcikge1xuICAgIHN1cGVyKHNwYW4sIHNvdXJjZVNwYW4sIG5ldyBjZEFzdC5FbXB0eUV4cHIoc3Bhbiwgc291cmNlU3BhbiksIGFyZ3MsIG51bGwhKTtcbiAgfVxufVxuIl19