@angular/compiler 19.0.0-next.0 → 19.0.0-next.10

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 (187) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +1 -1
  3. package/fesm2022/compiler.mjs +5465 -4675
  4. package/fesm2022/compiler.mjs.map +1 -1
  5. package/index.d.ts +115 -15
  6. package/package.json +2 -4
  7. package/esm2022/compiler.mjs +0 -13
  8. package/esm2022/index.mjs +0 -13
  9. package/esm2022/public_api.mjs +0 -15
  10. package/esm2022/src/assertions.mjs +0 -31
  11. package/esm2022/src/chars.mjs +0 -90
  12. package/esm2022/src/compiler.mjs +0 -88
  13. package/esm2022/src/compiler_facade_interface.mjs +0 -29
  14. package/esm2022/src/config.mjs +0 -20
  15. package/esm2022/src/constant_pool.mjs +0 -285
  16. package/esm2022/src/core.mjs +0 -96
  17. package/esm2022/src/expression_parser/ast.mjs +0 -755
  18. package/esm2022/src/expression_parser/lexer.mjs +0 -421
  19. package/esm2022/src/expression_parser/parser.mjs +0 -1222
  20. package/esm2022/src/i18n/digest.mjs +0 -322
  21. package/esm2022/src/i18n/extractor_merger.mjs +0 -409
  22. package/esm2022/src/i18n/i18n_ast.mjs +0 -212
  23. package/esm2022/src/i18n/i18n_html_parser.mjs +0 -54
  24. package/esm2022/src/i18n/i18n_parser.mjs +0 -247
  25. package/esm2022/src/i18n/index.mjs +0 -16
  26. package/esm2022/src/i18n/message_bundle.mjs +0 -93
  27. package/esm2022/src/i18n/parse_util.mjs +0 -17
  28. package/esm2022/src/i18n/serializers/placeholder.mjs +0 -139
  29. package/esm2022/src/i18n/serializers/serializer.mjs +0 -77
  30. package/esm2022/src/i18n/serializers/xliff.mjs +0 -300
  31. package/esm2022/src/i18n/serializers/xliff2.mjs +0 -349
  32. package/esm2022/src/i18n/serializers/xmb.mjs +0 -188
  33. package/esm2022/src/i18n/serializers/xml_helper.mjs +0 -94
  34. package/esm2022/src/i18n/serializers/xtb.mjs +0 -186
  35. package/esm2022/src/i18n/translation_bundle.mjs +0 -164
  36. package/esm2022/src/injectable_compiler_2.mjs +0 -138
  37. package/esm2022/src/jit_compiler_facade.mjs +0 -681
  38. package/esm2022/src/ml_parser/ast.mjs +0 -167
  39. package/esm2022/src/ml_parser/defaults.mjs +0 -24
  40. package/esm2022/src/ml_parser/entities.mjs +0 -2144
  41. package/esm2022/src/ml_parser/html_parser.mjs +0 -18
  42. package/esm2022/src/ml_parser/html_tags.mjs +0 -156
  43. package/esm2022/src/ml_parser/html_whitespaces.mjs +0 -107
  44. package/esm2022/src/ml_parser/icu_ast_expander.mjs +0 -125
  45. package/esm2022/src/ml_parser/lexer.mjs +0 -1210
  46. package/esm2022/src/ml_parser/parser.mjs +0 -539
  47. package/esm2022/src/ml_parser/tags.mjs +0 -47
  48. package/esm2022/src/ml_parser/tokens.mjs +0 -9
  49. package/esm2022/src/ml_parser/xml_parser.mjs +0 -19
  50. package/esm2022/src/ml_parser/xml_tags.mjs +0 -32
  51. package/esm2022/src/output/abstract_emitter.mjs +0 -524
  52. package/esm2022/src/output/abstract_js_emitter.mjs +0 -130
  53. package/esm2022/src/output/map_util.mjs +0 -19
  54. package/esm2022/src/output/output_ast.mjs +0 -1301
  55. package/esm2022/src/output/output_jit.mjs +0 -138
  56. package/esm2022/src/output/output_jit_trusted_types.mjs +0 -100
  57. package/esm2022/src/output/source_map.mjs +0 -150
  58. package/esm2022/src/parse_util.mjs +0 -198
  59. package/esm2022/src/render3/partial/api.mjs +0 -9
  60. package/esm2022/src/render3/partial/class_metadata.mjs +0 -52
  61. package/esm2022/src/render3/partial/component.mjs +0 -197
  62. package/esm2022/src/render3/partial/directive.mjs +0 -264
  63. package/esm2022/src/render3/partial/factory.mjs +0 -35
  64. package/esm2022/src/render3/partial/injectable.mjs +0 -67
  65. package/esm2022/src/render3/partial/injector.mjs +0 -41
  66. package/esm2022/src/render3/partial/ng_module.mjs +0 -63
  67. package/esm2022/src/render3/partial/pipe.mjs +0 -50
  68. package/esm2022/src/render3/partial/util.mjs +0 -79
  69. package/esm2022/src/render3/r3_ast.mjs +0 -493
  70. package/esm2022/src/render3/r3_class_debug_info_compiler.mjs +0 -35
  71. package/esm2022/src/render3/r3_class_metadata_compiler.mjs +0 -92
  72. package/esm2022/src/render3/r3_control_flow.mjs +0 -421
  73. package/esm2022/src/render3/r3_deferred_blocks.mjs +0 -170
  74. package/esm2022/src/render3/r3_deferred_triggers.mjs +0 -316
  75. package/esm2022/src/render3/r3_factory.mjs +0 -200
  76. package/esm2022/src/render3/r3_identifiers.mjs +0 -480
  77. package/esm2022/src/render3/r3_injector_compiler.mjs +0 -28
  78. package/esm2022/src/render3/r3_jit.mjs +0 -29
  79. package/esm2022/src/render3/r3_module_compiler.mjs +0 -211
  80. package/esm2022/src/render3/r3_pipe_compiler.mjs +0 -35
  81. package/esm2022/src/render3/r3_template_transform.mjs +0 -560
  82. package/esm2022/src/render3/util.mjs +0 -90
  83. package/esm2022/src/render3/view/api.mjs +0 -14
  84. package/esm2022/src/render3/view/compiler.mjs +0 -546
  85. package/esm2022/src/render3/view/i18n/get_msg_utils.mjs +0 -113
  86. package/esm2022/src/render3/view/i18n/icu_serializer.mjs +0 -43
  87. package/esm2022/src/render3/view/i18n/localize_utils.mjs +0 -118
  88. package/esm2022/src/render3/view/i18n/meta.mjs +0 -259
  89. package/esm2022/src/render3/view/i18n/util.mjs +0 -70
  90. package/esm2022/src/render3/view/query_generation.mjs +0 -182
  91. package/esm2022/src/render3/view/t2_api.mjs +0 -9
  92. package/esm2022/src/render3/view/t2_binder.mjs +0 -823
  93. package/esm2022/src/render3/view/template.mjs +0 -113
  94. package/esm2022/src/render3/view/util.mjs +0 -192
  95. package/esm2022/src/resource_loader.mjs +0 -17
  96. package/esm2022/src/schema/dom_element_schema_registry.mjs +0 -471
  97. package/esm2022/src/schema/dom_security_schema.mjs +0 -96
  98. package/esm2022/src/schema/element_schema_registry.mjs +0 -10
  99. package/esm2022/src/schema/trusted_types_sinks.mjs +0 -41
  100. package/esm2022/src/selector.mjs +0 -400
  101. package/esm2022/src/shadow_css.mjs +0 -1053
  102. package/esm2022/src/style_url_resolver.mjs +0 -17
  103. package/esm2022/src/template/pipeline/ir/index.mjs +0 -18
  104. package/esm2022/src/template/pipeline/ir/src/enums.mjs +0 -503
  105. package/esm2022/src/template/pipeline/ir/src/expression.mjs +0 -997
  106. package/esm2022/src/template/pipeline/ir/src/handle.mjs +0 -13
  107. package/esm2022/src/template/pipeline/ir/src/operations.mjs +0 -261
  108. package/esm2022/src/template/pipeline/ir/src/ops/create.mjs +0 -405
  109. package/esm2022/src/template/pipeline/ir/src/ops/host.mjs +0 -25
  110. package/esm2022/src/template/pipeline/ir/src/ops/shared.mjs +0 -43
  111. package/esm2022/src/template/pipeline/ir/src/ops/update.mjs +0 -277
  112. package/esm2022/src/template/pipeline/ir/src/traits.mjs +0 -64
  113. package/esm2022/src/template/pipeline/ir/src/variable.mjs +0 -13
  114. package/esm2022/src/template/pipeline/src/compilation.mjs +0 -194
  115. package/esm2022/src/template/pipeline/src/conversion.mjs +0 -64
  116. package/esm2022/src/template/pipeline/src/emit.mjs +0 -238
  117. package/esm2022/src/template/pipeline/src/ingest.mjs +0 -1058
  118. package/esm2022/src/template/pipeline/src/instruction.mjs +0 -564
  119. package/esm2022/src/template/pipeline/src/phases/any_cast.mjs +0 -32
  120. package/esm2022/src/template/pipeline/src/phases/apply_i18n_expressions.mjs +0 -63
  121. package/esm2022/src/template/pipeline/src/phases/assign_i18n_slot_dependencies.mjs +0 -63
  122. package/esm2022/src/template/pipeline/src/phases/attribute_extraction.mjs +0 -138
  123. package/esm2022/src/template/pipeline/src/phases/binding_specialization.mjs +0 -75
  124. package/esm2022/src/template/pipeline/src/phases/chaining.mjs +0 -112
  125. package/esm2022/src/template/pipeline/src/phases/collapse_singleton_interpolations.mjs +0 -32
  126. package/esm2022/src/template/pipeline/src/phases/conditionals.mjs +0 -58
  127. package/esm2022/src/template/pipeline/src/phases/const_collection.mjs +0 -214
  128. package/esm2022/src/template/pipeline/src/phases/convert_i18n_bindings.mjs +0 -52
  129. package/esm2022/src/template/pipeline/src/phases/create_i18n_contexts.mjs +0 -105
  130. package/esm2022/src/template/pipeline/src/phases/deduplicate_text_bindings.mjs +0 -40
  131. package/esm2022/src/template/pipeline/src/phases/defer_configs.mjs +0 -29
  132. package/esm2022/src/template/pipeline/src/phases/defer_resolve_targets.mjs +0 -113
  133. package/esm2022/src/template/pipeline/src/phases/empty_elements.mjs +0 -47
  134. package/esm2022/src/template/pipeline/src/phases/expand_safe_reads.mjs +0 -192
  135. package/esm2022/src/template/pipeline/src/phases/extract_i18n_messages.mjs +0 -218
  136. package/esm2022/src/template/pipeline/src/phases/generate_advance.mjs +0 -66
  137. package/esm2022/src/template/pipeline/src/phases/generate_local_let_references.mjs +0 -29
  138. package/esm2022/src/template/pipeline/src/phases/generate_projection_def.mjs +0 -46
  139. package/esm2022/src/template/pipeline/src/phases/generate_variables.mjs +0 -170
  140. package/esm2022/src/template/pipeline/src/phases/has_const_expression_collection.mjs +0 -28
  141. package/esm2022/src/template/pipeline/src/phases/host_style_property_parsing.mjs +0 -81
  142. package/esm2022/src/template/pipeline/src/phases/i18n_const_collection.mjs +0 -309
  143. package/esm2022/src/template/pipeline/src/phases/i18n_text_extraction.mjs +0 -97
  144. package/esm2022/src/template/pipeline/src/phases/local_refs.mjs +0 -43
  145. package/esm2022/src/template/pipeline/src/phases/namespace.mjs +0 -26
  146. package/esm2022/src/template/pipeline/src/phases/naming.mjs +0 -179
  147. package/esm2022/src/template/pipeline/src/phases/next_context_merging.mjs +0 -75
  148. package/esm2022/src/template/pipeline/src/phases/ng_container.mjs +0 -29
  149. package/esm2022/src/template/pipeline/src/phases/nonbindable.mjs +0 -47
  150. package/esm2022/src/template/pipeline/src/phases/nullish_coalescing.mjs +0 -33
  151. package/esm2022/src/template/pipeline/src/phases/ordering.mjs +0 -140
  152. package/esm2022/src/template/pipeline/src/phases/parse_extracted_styles.mjs +0 -137
  153. package/esm2022/src/template/pipeline/src/phases/phase_remove_content_selectors.mjs +0 -42
  154. package/esm2022/src/template/pipeline/src/phases/pipe_creation.mjs +0 -74
  155. package/esm2022/src/template/pipeline/src/phases/pipe_variadic.mjs +0 -30
  156. package/esm2022/src/template/pipeline/src/phases/propagate_i18n_blocks.mjs +0 -81
  157. package/esm2022/src/template/pipeline/src/phases/pure_function_extraction.mjs +0 -55
  158. package/esm2022/src/template/pipeline/src/phases/pure_literal_structures.mjs +0 -58
  159. package/esm2022/src/template/pipeline/src/phases/reify.mjs +0 -433
  160. package/esm2022/src/template/pipeline/src/phases/remove_empty_bindings.mjs +0 -31
  161. package/esm2022/src/template/pipeline/src/phases/remove_i18n_contexts.mjs +0 -27
  162. package/esm2022/src/template/pipeline/src/phases/remove_illegal_let_references.mjs +0 -36
  163. package/esm2022/src/template/pipeline/src/phases/remove_unused_i18n_attrs.mjs +0 -33
  164. package/esm2022/src/template/pipeline/src/phases/resolve_contexts.mjs +0 -60
  165. package/esm2022/src/template/pipeline/src/phases/resolve_defer_deps_fns.mjs +0 -31
  166. package/esm2022/src/template/pipeline/src/phases/resolve_dollar_event.mjs +0 -36
  167. package/esm2022/src/template/pipeline/src/phases/resolve_i18n_element_placeholders.mjs +0 -266
  168. package/esm2022/src/template/pipeline/src/phases/resolve_i18n_expression_placeholders.mjs +0 -70
  169. package/esm2022/src/template/pipeline/src/phases/resolve_names.mjs +0 -124
  170. package/esm2022/src/template/pipeline/src/phases/resolve_sanitizers.mjs +0 -123
  171. package/esm2022/src/template/pipeline/src/phases/save_restore_view.mjs +0 -64
  172. package/esm2022/src/template/pipeline/src/phases/slot_allocation.mjs +0 -62
  173. package/esm2022/src/template/pipeline/src/phases/store_let_optimization.mjs +0 -35
  174. package/esm2022/src/template/pipeline/src/phases/style_binding_specialization.mjs +0 -42
  175. package/esm2022/src/template/pipeline/src/phases/temporary_variables.mjs +0 -87
  176. package/esm2022/src/template/pipeline/src/phases/track_fn_generation.mjs +0 -52
  177. package/esm2022/src/template/pipeline/src/phases/track_fn_optimization.mjs +0 -88
  178. package/esm2022/src/template/pipeline/src/phases/track_variables.mjs +0 -36
  179. package/esm2022/src/template/pipeline/src/phases/transform_two_way_binding_set.mjs +0 -43
  180. package/esm2022/src/template/pipeline/src/phases/var_counting.mjs +0 -155
  181. package/esm2022/src/template/pipeline/src/phases/variable_optimization.mjs +0 -423
  182. package/esm2022/src/template/pipeline/src/phases/wrap_icus.mjs +0 -41
  183. package/esm2022/src/template/pipeline/src/util/elements.mjs +0 -29
  184. package/esm2022/src/template_parser/binding_parser.mjs +0 -465
  185. package/esm2022/src/template_parser/template_preparser.mjs +0 -84
  186. package/esm2022/src/util.mjs +0 -124
  187. package/esm2022/src/version.mjs +0 -15
@@ -1,1222 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC All Rights Reserved.
4
- *
5
- * Use of this source code is governed by an MIT-style license that can be
6
- * found in the LICENSE file at https://angular.io/license
7
- */
8
- import * as chars from '../chars';
9
- import { DEFAULT_INTERPOLATION_CONFIG } from '../ml_parser/defaults';
10
- import { AbsoluteSourceSpan, ASTWithSource, Binary, BindingPipe, Call, Chain, Conditional, EmptyExpr, ExpressionBinding, ImplicitReceiver, Interpolation, KeyedRead, KeyedWrite, LiteralArray, LiteralMap, LiteralPrimitive, NonNullAssert, ParserError, ParseSpan, PrefixNot, PropertyRead, PropertyWrite, RecursiveAstVisitor, SafeCall, SafeKeyedRead, SafePropertyRead, ThisReceiver, Unary, VariableBinding, } from './ast';
11
- import { EOF, TokenType } from './lexer';
12
- export class SplitInterpolation {
13
- constructor(strings, expressions, offsets) {
14
- this.strings = strings;
15
- this.expressions = expressions;
16
- this.offsets = offsets;
17
- }
18
- }
19
- export class TemplateBindingParseResult {
20
- constructor(templateBindings, warnings, errors) {
21
- this.templateBindings = templateBindings;
22
- this.warnings = warnings;
23
- this.errors = errors;
24
- }
25
- }
26
- export class Parser {
27
- constructor(_lexer) {
28
- this._lexer = _lexer;
29
- this.errors = [];
30
- }
31
- parseAction(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
32
- this._checkNoInterpolation(input, location, interpolationConfig);
33
- const sourceToLex = this._stripComments(input);
34
- const tokens = this._lexer.tokenize(sourceToLex);
35
- const ast = new _ParseAST(input, location, absoluteOffset, tokens, 1 /* ParseFlags.Action */, this.errors, 0).parseChain();
36
- return new ASTWithSource(ast, input, location, absoluteOffset, this.errors);
37
- }
38
- parseBinding(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
39
- const ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig);
40
- return new ASTWithSource(ast, input, location, absoluteOffset, this.errors);
41
- }
42
- checkSimpleExpression(ast) {
43
- const checker = new SimpleExpressionChecker();
44
- ast.visit(checker);
45
- return checker.errors;
46
- }
47
- // Host bindings parsed here
48
- parseSimpleBinding(input, location, absoluteOffset, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
49
- const ast = this._parseBindingAst(input, location, absoluteOffset, interpolationConfig);
50
- const errors = this.checkSimpleExpression(ast);
51
- if (errors.length > 0) {
52
- this._reportError(`Host binding expression cannot contain ${errors.join(' ')}`, input, location);
53
- }
54
- return new ASTWithSource(ast, input, location, absoluteOffset, this.errors);
55
- }
56
- _reportError(message, input, errLocation, ctxLocation) {
57
- this.errors.push(new ParserError(message, input, errLocation, ctxLocation));
58
- }
59
- _parseBindingAst(input, location, absoluteOffset, interpolationConfig) {
60
- this._checkNoInterpolation(input, location, interpolationConfig);
61
- const sourceToLex = this._stripComments(input);
62
- const tokens = this._lexer.tokenize(sourceToLex);
63
- return new _ParseAST(input, location, absoluteOffset, tokens, 0 /* ParseFlags.None */, this.errors, 0).parseChain();
64
- }
65
- /**
66
- * Parse microsyntax template expression and return a list of bindings or
67
- * parsing errors in case the given expression is invalid.
68
- *
69
- * For example,
70
- * ```
71
- * <div *ngFor="let item of items">
72
- * ^ ^ absoluteValueOffset for `templateValue`
73
- * absoluteKeyOffset for `templateKey`
74
- * ```
75
- * contains three bindings:
76
- * 1. ngFor -> null
77
- * 2. item -> NgForOfContext.$implicit
78
- * 3. ngForOf -> items
79
- *
80
- * This is apparent from the de-sugared template:
81
- * ```
82
- * <ng-template ngFor let-item [ngForOf]="items">
83
- * ```
84
- *
85
- * @param templateKey name of directive, without the * prefix. For example: ngIf, ngFor
86
- * @param templateValue RHS of the microsyntax attribute
87
- * @param templateUrl template filename if it's external, component filename if it's inline
88
- * @param absoluteKeyOffset start of the `templateKey`
89
- * @param absoluteValueOffset start of the `templateValue`
90
- */
91
- parseTemplateBindings(templateKey, templateValue, templateUrl, absoluteKeyOffset, absoluteValueOffset) {
92
- const tokens = this._lexer.tokenize(templateValue);
93
- const parser = new _ParseAST(templateValue, templateUrl, absoluteValueOffset, tokens, 0 /* ParseFlags.None */, this.errors, 0 /* relative offset */);
94
- return parser.parseTemplateBindings({
95
- source: templateKey,
96
- span: new AbsoluteSourceSpan(absoluteKeyOffset, absoluteKeyOffset + templateKey.length),
97
- });
98
- }
99
- parseInterpolation(input, location, absoluteOffset, interpolatedTokens, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
100
- const { strings, expressions, offsets } = this.splitInterpolation(input, location, interpolatedTokens, interpolationConfig);
101
- if (expressions.length === 0)
102
- return null;
103
- const expressionNodes = [];
104
- for (let i = 0; i < expressions.length; ++i) {
105
- const expressionText = expressions[i].text;
106
- const sourceToLex = this._stripComments(expressionText);
107
- const tokens = this._lexer.tokenize(sourceToLex);
108
- const ast = new _ParseAST(input, location, absoluteOffset, tokens, 0 /* ParseFlags.None */, this.errors, offsets[i]).parseChain();
109
- expressionNodes.push(ast);
110
- }
111
- return this.createInterpolationAst(strings.map((s) => s.text), expressionNodes, input, location, absoluteOffset);
112
- }
113
- /**
114
- * Similar to `parseInterpolation`, but treats the provided string as a single expression
115
- * element that would normally appear within the interpolation prefix and suffix (`{{` and `}}`).
116
- * This is used for parsing the switch expression in ICUs.
117
- */
118
- parseInterpolationExpression(expression, location, absoluteOffset) {
119
- const sourceToLex = this._stripComments(expression);
120
- const tokens = this._lexer.tokenize(sourceToLex);
121
- const ast = new _ParseAST(expression, location, absoluteOffset, tokens, 0 /* ParseFlags.None */, this.errors, 0).parseChain();
122
- const strings = ['', '']; // The prefix and suffix strings are both empty
123
- return this.createInterpolationAst(strings, [ast], expression, location, absoluteOffset);
124
- }
125
- createInterpolationAst(strings, expressions, input, location, absoluteOffset) {
126
- const span = new ParseSpan(0, input.length);
127
- const interpolation = new Interpolation(span, span.toAbsolute(absoluteOffset), strings, expressions);
128
- return new ASTWithSource(interpolation, input, location, absoluteOffset, this.errors);
129
- }
130
- /**
131
- * Splits a string of text into "raw" text segments and expressions present in interpolations in
132
- * the string.
133
- * Returns `null` if there are no interpolations, otherwise a
134
- * `SplitInterpolation` with splits that look like
135
- * <raw text> <expression> <raw text> ... <raw text> <expression> <raw text>
136
- */
137
- splitInterpolation(input, location, interpolatedTokens, interpolationConfig = DEFAULT_INTERPOLATION_CONFIG) {
138
- const strings = [];
139
- const expressions = [];
140
- const offsets = [];
141
- const inputToTemplateIndexMap = interpolatedTokens
142
- ? getIndexMapForOriginalTemplate(interpolatedTokens)
143
- : null;
144
- let i = 0;
145
- let atInterpolation = false;
146
- let extendLastString = false;
147
- let { start: interpStart, end: interpEnd } = interpolationConfig;
148
- while (i < input.length) {
149
- if (!atInterpolation) {
150
- // parse until starting {{
151
- const start = i;
152
- i = input.indexOf(interpStart, i);
153
- if (i === -1) {
154
- i = input.length;
155
- }
156
- const text = input.substring(start, i);
157
- strings.push({ text, start, end: i });
158
- atInterpolation = true;
159
- }
160
- else {
161
- // parse from starting {{ to ending }} while ignoring content inside quotes.
162
- const fullStart = i;
163
- const exprStart = fullStart + interpStart.length;
164
- const exprEnd = this._getInterpolationEndIndex(input, interpEnd, exprStart);
165
- if (exprEnd === -1) {
166
- // Could not find the end of the interpolation; do not parse an expression.
167
- // Instead we should extend the content on the last raw string.
168
- atInterpolation = false;
169
- extendLastString = true;
170
- break;
171
- }
172
- const fullEnd = exprEnd + interpEnd.length;
173
- const text = input.substring(exprStart, exprEnd);
174
- if (text.trim().length === 0) {
175
- this._reportError('Blank expressions are not allowed in interpolated strings', input, `at column ${i} in`, location);
176
- }
177
- expressions.push({ text, start: fullStart, end: fullEnd });
178
- const startInOriginalTemplate = inputToTemplateIndexMap?.get(fullStart) ?? fullStart;
179
- const offset = startInOriginalTemplate + interpStart.length;
180
- offsets.push(offset);
181
- i = fullEnd;
182
- atInterpolation = false;
183
- }
184
- }
185
- if (!atInterpolation) {
186
- // If we are now at a text section, add the remaining content as a raw string.
187
- if (extendLastString) {
188
- const piece = strings[strings.length - 1];
189
- piece.text += input.substring(i);
190
- piece.end = input.length;
191
- }
192
- else {
193
- strings.push({ text: input.substring(i), start: i, end: input.length });
194
- }
195
- }
196
- return new SplitInterpolation(strings, expressions, offsets);
197
- }
198
- wrapLiteralPrimitive(input, location, absoluteOffset) {
199
- const span = new ParseSpan(0, input == null ? 0 : input.length);
200
- return new ASTWithSource(new LiteralPrimitive(span, span.toAbsolute(absoluteOffset), input), input, location, absoluteOffset, this.errors);
201
- }
202
- _stripComments(input) {
203
- const i = this._commentStart(input);
204
- return i != null ? input.substring(0, i) : input;
205
- }
206
- _commentStart(input) {
207
- let outerQuote = null;
208
- for (let i = 0; i < input.length - 1; i++) {
209
- const char = input.charCodeAt(i);
210
- const nextChar = input.charCodeAt(i + 1);
211
- if (char === chars.$SLASH && nextChar == chars.$SLASH && outerQuote == null)
212
- return i;
213
- if (outerQuote === char) {
214
- outerQuote = null;
215
- }
216
- else if (outerQuote == null && chars.isQuote(char)) {
217
- outerQuote = char;
218
- }
219
- }
220
- return null;
221
- }
222
- _checkNoInterpolation(input, location, { start, end }) {
223
- let startIndex = -1;
224
- let endIndex = -1;
225
- for (const charIndex of this._forEachUnquotedChar(input, 0)) {
226
- if (startIndex === -1) {
227
- if (input.startsWith(start)) {
228
- startIndex = charIndex;
229
- }
230
- }
231
- else {
232
- endIndex = this._getInterpolationEndIndex(input, end, charIndex);
233
- if (endIndex > -1) {
234
- break;
235
- }
236
- }
237
- }
238
- if (startIndex > -1 && endIndex > -1) {
239
- this._reportError(`Got interpolation (${start}${end}) where expression was expected`, input, `at column ${startIndex} in`, location);
240
- }
241
- }
242
- /**
243
- * Finds the index of the end of an interpolation expression
244
- * while ignoring comments and quoted content.
245
- */
246
- _getInterpolationEndIndex(input, expressionEnd, start) {
247
- for (const charIndex of this._forEachUnquotedChar(input, start)) {
248
- if (input.startsWith(expressionEnd, charIndex)) {
249
- return charIndex;
250
- }
251
- // Nothing else in the expression matters after we've
252
- // hit a comment so look directly for the end token.
253
- if (input.startsWith('//', charIndex)) {
254
- return input.indexOf(expressionEnd, charIndex);
255
- }
256
- }
257
- return -1;
258
- }
259
- /**
260
- * Generator used to iterate over the character indexes of a string that are outside of quotes.
261
- * @param input String to loop through.
262
- * @param start Index within the string at which to start.
263
- */
264
- *_forEachUnquotedChar(input, start) {
265
- let currentQuote = null;
266
- let escapeCount = 0;
267
- for (let i = start; i < input.length; i++) {
268
- const char = input[i];
269
- // Skip the characters inside quotes. Note that we only care about the outer-most
270
- // quotes matching up and we need to account for escape characters.
271
- if (chars.isQuote(input.charCodeAt(i)) &&
272
- (currentQuote === null || currentQuote === char) &&
273
- escapeCount % 2 === 0) {
274
- currentQuote = currentQuote === null ? char : null;
275
- }
276
- else if (currentQuote === null) {
277
- yield i;
278
- }
279
- escapeCount = char === '\\' ? escapeCount + 1 : 0;
280
- }
281
- }
282
- }
283
- /** Describes a stateful context an expression parser is in. */
284
- var ParseContextFlags;
285
- (function (ParseContextFlags) {
286
- ParseContextFlags[ParseContextFlags["None"] = 0] = "None";
287
- /**
288
- * A Writable context is one in which a value may be written to an lvalue.
289
- * For example, after we see a property access, we may expect a write to the
290
- * property via the "=" operator.
291
- * prop
292
- * ^ possible "=" after
293
- */
294
- ParseContextFlags[ParseContextFlags["Writable"] = 1] = "Writable";
295
- })(ParseContextFlags || (ParseContextFlags = {}));
296
- class _ParseAST {
297
- constructor(input, location, absoluteOffset, tokens, parseFlags, errors, offset) {
298
- this.input = input;
299
- this.location = location;
300
- this.absoluteOffset = absoluteOffset;
301
- this.tokens = tokens;
302
- this.parseFlags = parseFlags;
303
- this.errors = errors;
304
- this.offset = offset;
305
- this.rparensExpected = 0;
306
- this.rbracketsExpected = 0;
307
- this.rbracesExpected = 0;
308
- this.context = ParseContextFlags.None;
309
- // Cache of expression start and input indeces to the absolute source span they map to, used to
310
- // prevent creating superfluous source spans in `sourceSpan`.
311
- // A serial of the expression start and input index is used for mapping because both are stateful
312
- // and may change for subsequent expressions visited by the parser.
313
- this.sourceSpanCache = new Map();
314
- this.index = 0;
315
- }
316
- peek(offset) {
317
- const i = this.index + offset;
318
- return i < this.tokens.length ? this.tokens[i] : EOF;
319
- }
320
- get next() {
321
- return this.peek(0);
322
- }
323
- /** Whether all the parser input has been processed. */
324
- get atEOF() {
325
- return this.index >= this.tokens.length;
326
- }
327
- /**
328
- * Index of the next token to be processed, or the end of the last token if all have been
329
- * processed.
330
- */
331
- get inputIndex() {
332
- return this.atEOF ? this.currentEndIndex : this.next.index + this.offset;
333
- }
334
- /**
335
- * End index of the last processed token, or the start of the first token if none have been
336
- * processed.
337
- */
338
- get currentEndIndex() {
339
- if (this.index > 0) {
340
- const curToken = this.peek(-1);
341
- return curToken.end + this.offset;
342
- }
343
- // No tokens have been processed yet; return the next token's start or the length of the input
344
- // if there is no token.
345
- if (this.tokens.length === 0) {
346
- return this.input.length + this.offset;
347
- }
348
- return this.next.index + this.offset;
349
- }
350
- /**
351
- * Returns the absolute offset of the start of the current token.
352
- */
353
- get currentAbsoluteOffset() {
354
- return this.absoluteOffset + this.inputIndex;
355
- }
356
- /**
357
- * Retrieve a `ParseSpan` from `start` to the current position (or to `artificialEndIndex` if
358
- * provided).
359
- *
360
- * @param start Position from which the `ParseSpan` will start.
361
- * @param artificialEndIndex Optional ending index to be used if provided (and if greater than the
362
- * natural ending index)
363
- */
364
- span(start, artificialEndIndex) {
365
- let endIndex = this.currentEndIndex;
366
- if (artificialEndIndex !== undefined && artificialEndIndex > this.currentEndIndex) {
367
- endIndex = artificialEndIndex;
368
- }
369
- // In some unusual parsing scenarios (like when certain tokens are missing and an `EmptyExpr` is
370
- // being created), the current token may already be advanced beyond the `currentEndIndex`. This
371
- // appears to be a deep-seated parser bug.
372
- //
373
- // As a workaround for now, swap the start and end indices to ensure a valid `ParseSpan`.
374
- // TODO(alxhub): fix the bug upstream in the parser state, and remove this workaround.
375
- if (start > endIndex) {
376
- const tmp = endIndex;
377
- endIndex = start;
378
- start = tmp;
379
- }
380
- return new ParseSpan(start, endIndex);
381
- }
382
- sourceSpan(start, artificialEndIndex) {
383
- const serial = `${start}@${this.inputIndex}:${artificialEndIndex}`;
384
- if (!this.sourceSpanCache.has(serial)) {
385
- this.sourceSpanCache.set(serial, this.span(start, artificialEndIndex).toAbsolute(this.absoluteOffset));
386
- }
387
- return this.sourceSpanCache.get(serial);
388
- }
389
- advance() {
390
- this.index++;
391
- }
392
- /**
393
- * Executes a callback in the provided context.
394
- */
395
- withContext(context, cb) {
396
- this.context |= context;
397
- const ret = cb();
398
- this.context ^= context;
399
- return ret;
400
- }
401
- consumeOptionalCharacter(code) {
402
- if (this.next.isCharacter(code)) {
403
- this.advance();
404
- return true;
405
- }
406
- else {
407
- return false;
408
- }
409
- }
410
- peekKeywordLet() {
411
- return this.next.isKeywordLet();
412
- }
413
- peekKeywordAs() {
414
- return this.next.isKeywordAs();
415
- }
416
- /**
417
- * Consumes an expected character, otherwise emits an error about the missing expected character
418
- * and skips over the token stream until reaching a recoverable point.
419
- *
420
- * See `this.error` and `this.skip` for more details.
421
- */
422
- expectCharacter(code) {
423
- if (this.consumeOptionalCharacter(code))
424
- return;
425
- this.error(`Missing expected ${String.fromCharCode(code)}`);
426
- }
427
- consumeOptionalOperator(op) {
428
- if (this.next.isOperator(op)) {
429
- this.advance();
430
- return true;
431
- }
432
- else {
433
- return false;
434
- }
435
- }
436
- expectOperator(operator) {
437
- if (this.consumeOptionalOperator(operator))
438
- return;
439
- this.error(`Missing expected operator ${operator}`);
440
- }
441
- prettyPrintToken(tok) {
442
- return tok === EOF ? 'end of input' : `token ${tok}`;
443
- }
444
- expectIdentifierOrKeyword() {
445
- const n = this.next;
446
- if (!n.isIdentifier() && !n.isKeyword()) {
447
- if (n.isPrivateIdentifier()) {
448
- this._reportErrorForPrivateIdentifier(n, 'expected identifier or keyword');
449
- }
450
- else {
451
- this.error(`Unexpected ${this.prettyPrintToken(n)}, expected identifier or keyword`);
452
- }
453
- return null;
454
- }
455
- this.advance();
456
- return n.toString();
457
- }
458
- expectIdentifierOrKeywordOrString() {
459
- const n = this.next;
460
- if (!n.isIdentifier() && !n.isKeyword() && !n.isString()) {
461
- if (n.isPrivateIdentifier()) {
462
- this._reportErrorForPrivateIdentifier(n, 'expected identifier, keyword or string');
463
- }
464
- else {
465
- this.error(`Unexpected ${this.prettyPrintToken(n)}, expected identifier, keyword, or string`);
466
- }
467
- return '';
468
- }
469
- this.advance();
470
- return n.toString();
471
- }
472
- parseChain() {
473
- const exprs = [];
474
- const start = this.inputIndex;
475
- while (this.index < this.tokens.length) {
476
- const expr = this.parsePipe();
477
- exprs.push(expr);
478
- if (this.consumeOptionalCharacter(chars.$SEMICOLON)) {
479
- if (!(this.parseFlags & 1 /* ParseFlags.Action */)) {
480
- this.error('Binding expression cannot contain chained expression');
481
- }
482
- while (this.consumeOptionalCharacter(chars.$SEMICOLON)) { } // read all semicolons
483
- }
484
- else if (this.index < this.tokens.length) {
485
- const errorIndex = this.index;
486
- this.error(`Unexpected token '${this.next}'`);
487
- // The `error` call above will skip ahead to the next recovery point in an attempt to
488
- // recover part of the expression, but that might be the token we started from which will
489
- // lead to an infinite loop. If that's the case, break the loop assuming that we can't
490
- // parse further.
491
- if (this.index === errorIndex) {
492
- break;
493
- }
494
- }
495
- }
496
- if (exprs.length === 0) {
497
- // We have no expressions so create an empty expression that spans the entire input length
498
- const artificialStart = this.offset;
499
- const artificialEnd = this.offset + this.input.length;
500
- return new EmptyExpr(this.span(artificialStart, artificialEnd), this.sourceSpan(artificialStart, artificialEnd));
501
- }
502
- if (exprs.length == 1)
503
- return exprs[0];
504
- return new Chain(this.span(start), this.sourceSpan(start), exprs);
505
- }
506
- parsePipe() {
507
- const start = this.inputIndex;
508
- let result = this.parseExpression();
509
- if (this.consumeOptionalOperator('|')) {
510
- if (this.parseFlags & 1 /* ParseFlags.Action */) {
511
- this.error(`Cannot have a pipe in an action expression`);
512
- }
513
- do {
514
- const nameStart = this.inputIndex;
515
- let nameId = this.expectIdentifierOrKeyword();
516
- let nameSpan;
517
- let fullSpanEnd = undefined;
518
- if (nameId !== null) {
519
- nameSpan = this.sourceSpan(nameStart);
520
- }
521
- else {
522
- // No valid identifier was found, so we'll assume an empty pipe name ('').
523
- nameId = '';
524
- // However, there may have been whitespace present between the pipe character and the next
525
- // token in the sequence (or the end of input). We want to track this whitespace so that
526
- // the `BindingPipe` we produce covers not just the pipe character, but any trailing
527
- // whitespace beyond it. Another way of thinking about this is that the zero-length name
528
- // is assumed to be at the end of any whitespace beyond the pipe character.
529
- //
530
- // Therefore, we push the end of the `ParseSpan` for this pipe all the way up to the
531
- // beginning of the next token, or until the end of input if the next token is EOF.
532
- fullSpanEnd = this.next.index !== -1 ? this.next.index : this.input.length + this.offset;
533
- // The `nameSpan` for an empty pipe name is zero-length at the end of any whitespace
534
- // beyond the pipe character.
535
- nameSpan = new ParseSpan(fullSpanEnd, fullSpanEnd).toAbsolute(this.absoluteOffset);
536
- }
537
- const args = [];
538
- while (this.consumeOptionalCharacter(chars.$COLON)) {
539
- args.push(this.parseExpression());
540
- // If there are additional expressions beyond the name, then the artificial end for the
541
- // name is no longer relevant.
542
- }
543
- result = new BindingPipe(this.span(start), this.sourceSpan(start, fullSpanEnd), result, nameId, args, nameSpan);
544
- } while (this.consumeOptionalOperator('|'));
545
- }
546
- return result;
547
- }
548
- parseExpression() {
549
- return this.parseConditional();
550
- }
551
- parseConditional() {
552
- const start = this.inputIndex;
553
- const result = this.parseLogicalOr();
554
- if (this.consumeOptionalOperator('?')) {
555
- const yes = this.parsePipe();
556
- let no;
557
- if (!this.consumeOptionalCharacter(chars.$COLON)) {
558
- const end = this.inputIndex;
559
- const expression = this.input.substring(start, end);
560
- this.error(`Conditional expression ${expression} requires all 3 expressions`);
561
- no = new EmptyExpr(this.span(start), this.sourceSpan(start));
562
- }
563
- else {
564
- no = this.parsePipe();
565
- }
566
- return new Conditional(this.span(start), this.sourceSpan(start), result, yes, no);
567
- }
568
- else {
569
- return result;
570
- }
571
- }
572
- parseLogicalOr() {
573
- // '||'
574
- const start = this.inputIndex;
575
- let result = this.parseLogicalAnd();
576
- while (this.consumeOptionalOperator('||')) {
577
- const right = this.parseLogicalAnd();
578
- result = new Binary(this.span(start), this.sourceSpan(start), '||', result, right);
579
- }
580
- return result;
581
- }
582
- parseLogicalAnd() {
583
- // '&&'
584
- const start = this.inputIndex;
585
- let result = this.parseNullishCoalescing();
586
- while (this.consumeOptionalOperator('&&')) {
587
- const right = this.parseNullishCoalescing();
588
- result = new Binary(this.span(start), this.sourceSpan(start), '&&', result, right);
589
- }
590
- return result;
591
- }
592
- parseNullishCoalescing() {
593
- // '??'
594
- const start = this.inputIndex;
595
- let result = this.parseEquality();
596
- while (this.consumeOptionalOperator('??')) {
597
- const right = this.parseEquality();
598
- result = new Binary(this.span(start), this.sourceSpan(start), '??', result, right);
599
- }
600
- return result;
601
- }
602
- parseEquality() {
603
- // '==','!=','===','!=='
604
- const start = this.inputIndex;
605
- let result = this.parseRelational();
606
- while (this.next.type == TokenType.Operator) {
607
- const operator = this.next.strValue;
608
- switch (operator) {
609
- case '==':
610
- case '===':
611
- case '!=':
612
- case '!==':
613
- this.advance();
614
- const right = this.parseRelational();
615
- result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
616
- continue;
617
- }
618
- break;
619
- }
620
- return result;
621
- }
622
- parseRelational() {
623
- // '<', '>', '<=', '>='
624
- const start = this.inputIndex;
625
- let result = this.parseAdditive();
626
- while (this.next.type == TokenType.Operator) {
627
- const operator = this.next.strValue;
628
- switch (operator) {
629
- case '<':
630
- case '>':
631
- case '<=':
632
- case '>=':
633
- this.advance();
634
- const right = this.parseAdditive();
635
- result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
636
- continue;
637
- }
638
- break;
639
- }
640
- return result;
641
- }
642
- parseAdditive() {
643
- // '+', '-'
644
- const start = this.inputIndex;
645
- let result = this.parseMultiplicative();
646
- while (this.next.type == TokenType.Operator) {
647
- const operator = this.next.strValue;
648
- switch (operator) {
649
- case '+':
650
- case '-':
651
- this.advance();
652
- let right = this.parseMultiplicative();
653
- result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
654
- continue;
655
- }
656
- break;
657
- }
658
- return result;
659
- }
660
- parseMultiplicative() {
661
- // '*', '%', '/'
662
- const start = this.inputIndex;
663
- let result = this.parsePrefix();
664
- while (this.next.type == TokenType.Operator) {
665
- const operator = this.next.strValue;
666
- switch (operator) {
667
- case '*':
668
- case '%':
669
- case '/':
670
- this.advance();
671
- let right = this.parsePrefix();
672
- result = new Binary(this.span(start), this.sourceSpan(start), operator, result, right);
673
- continue;
674
- }
675
- break;
676
- }
677
- return result;
678
- }
679
- parsePrefix() {
680
- if (this.next.type == TokenType.Operator) {
681
- const start = this.inputIndex;
682
- const operator = this.next.strValue;
683
- let result;
684
- switch (operator) {
685
- case '+':
686
- this.advance();
687
- result = this.parsePrefix();
688
- return Unary.createPlus(this.span(start), this.sourceSpan(start), result);
689
- case '-':
690
- this.advance();
691
- result = this.parsePrefix();
692
- return Unary.createMinus(this.span(start), this.sourceSpan(start), result);
693
- case '!':
694
- this.advance();
695
- result = this.parsePrefix();
696
- return new PrefixNot(this.span(start), this.sourceSpan(start), result);
697
- }
698
- }
699
- return this.parseCallChain();
700
- }
701
- parseCallChain() {
702
- const start = this.inputIndex;
703
- let result = this.parsePrimary();
704
- while (true) {
705
- if (this.consumeOptionalCharacter(chars.$PERIOD)) {
706
- result = this.parseAccessMember(result, start, false);
707
- }
708
- else if (this.consumeOptionalOperator('?.')) {
709
- if (this.consumeOptionalCharacter(chars.$LPAREN)) {
710
- result = this.parseCall(result, start, true);
711
- }
712
- else {
713
- result = this.consumeOptionalCharacter(chars.$LBRACKET)
714
- ? this.parseKeyedReadOrWrite(result, start, true)
715
- : this.parseAccessMember(result, start, true);
716
- }
717
- }
718
- else if (this.consumeOptionalCharacter(chars.$LBRACKET)) {
719
- result = this.parseKeyedReadOrWrite(result, start, false);
720
- }
721
- else if (this.consumeOptionalCharacter(chars.$LPAREN)) {
722
- result = this.parseCall(result, start, false);
723
- }
724
- else if (this.consumeOptionalOperator('!')) {
725
- result = new NonNullAssert(this.span(start), this.sourceSpan(start), result);
726
- }
727
- else {
728
- return result;
729
- }
730
- }
731
- }
732
- parsePrimary() {
733
- const start = this.inputIndex;
734
- if (this.consumeOptionalCharacter(chars.$LPAREN)) {
735
- this.rparensExpected++;
736
- const result = this.parsePipe();
737
- this.rparensExpected--;
738
- this.expectCharacter(chars.$RPAREN);
739
- return result;
740
- }
741
- else if (this.next.isKeywordNull()) {
742
- this.advance();
743
- return new LiteralPrimitive(this.span(start), this.sourceSpan(start), null);
744
- }
745
- else if (this.next.isKeywordUndefined()) {
746
- this.advance();
747
- return new LiteralPrimitive(this.span(start), this.sourceSpan(start), void 0);
748
- }
749
- else if (this.next.isKeywordTrue()) {
750
- this.advance();
751
- return new LiteralPrimitive(this.span(start), this.sourceSpan(start), true);
752
- }
753
- else if (this.next.isKeywordFalse()) {
754
- this.advance();
755
- return new LiteralPrimitive(this.span(start), this.sourceSpan(start), false);
756
- }
757
- else if (this.next.isKeywordThis()) {
758
- this.advance();
759
- return new ThisReceiver(this.span(start), this.sourceSpan(start));
760
- }
761
- else if (this.consumeOptionalCharacter(chars.$LBRACKET)) {
762
- this.rbracketsExpected++;
763
- const elements = this.parseExpressionList(chars.$RBRACKET);
764
- this.rbracketsExpected--;
765
- this.expectCharacter(chars.$RBRACKET);
766
- return new LiteralArray(this.span(start), this.sourceSpan(start), elements);
767
- }
768
- else if (this.next.isCharacter(chars.$LBRACE)) {
769
- return this.parseLiteralMap();
770
- }
771
- else if (this.next.isIdentifier()) {
772
- return this.parseAccessMember(new ImplicitReceiver(this.span(start), this.sourceSpan(start)), start, false);
773
- }
774
- else if (this.next.isNumber()) {
775
- const value = this.next.toNumber();
776
- this.advance();
777
- return new LiteralPrimitive(this.span(start), this.sourceSpan(start), value);
778
- }
779
- else if (this.next.isString()) {
780
- const literalValue = this.next.toString();
781
- this.advance();
782
- return new LiteralPrimitive(this.span(start), this.sourceSpan(start), literalValue);
783
- }
784
- else if (this.next.isPrivateIdentifier()) {
785
- this._reportErrorForPrivateIdentifier(this.next, null);
786
- return new EmptyExpr(this.span(start), this.sourceSpan(start));
787
- }
788
- else if (this.index >= this.tokens.length) {
789
- this.error(`Unexpected end of expression: ${this.input}`);
790
- return new EmptyExpr(this.span(start), this.sourceSpan(start));
791
- }
792
- else {
793
- this.error(`Unexpected token ${this.next}`);
794
- return new EmptyExpr(this.span(start), this.sourceSpan(start));
795
- }
796
- }
797
- parseExpressionList(terminator) {
798
- const result = [];
799
- do {
800
- if (!this.next.isCharacter(terminator)) {
801
- result.push(this.parsePipe());
802
- }
803
- else {
804
- break;
805
- }
806
- } while (this.consumeOptionalCharacter(chars.$COMMA));
807
- return result;
808
- }
809
- parseLiteralMap() {
810
- const keys = [];
811
- const values = [];
812
- const start = this.inputIndex;
813
- this.expectCharacter(chars.$LBRACE);
814
- if (!this.consumeOptionalCharacter(chars.$RBRACE)) {
815
- this.rbracesExpected++;
816
- do {
817
- const keyStart = this.inputIndex;
818
- const quoted = this.next.isString();
819
- const key = this.expectIdentifierOrKeywordOrString();
820
- const literalMapKey = { key, quoted };
821
- keys.push(literalMapKey);
822
- // Properties with quoted keys can't use the shorthand syntax.
823
- if (quoted) {
824
- this.expectCharacter(chars.$COLON);
825
- values.push(this.parsePipe());
826
- }
827
- else if (this.consumeOptionalCharacter(chars.$COLON)) {
828
- values.push(this.parsePipe());
829
- }
830
- else {
831
- literalMapKey.isShorthandInitialized = true;
832
- const span = this.span(keyStart);
833
- const sourceSpan = this.sourceSpan(keyStart);
834
- values.push(new PropertyRead(span, sourceSpan, sourceSpan, new ImplicitReceiver(span, sourceSpan), key));
835
- }
836
- } while (this.consumeOptionalCharacter(chars.$COMMA) &&
837
- !this.next.isCharacter(chars.$RBRACE));
838
- this.rbracesExpected--;
839
- this.expectCharacter(chars.$RBRACE);
840
- }
841
- return new LiteralMap(this.span(start), this.sourceSpan(start), keys, values);
842
- }
843
- parseAccessMember(readReceiver, start, isSafe) {
844
- const nameStart = this.inputIndex;
845
- const id = this.withContext(ParseContextFlags.Writable, () => {
846
- const id = this.expectIdentifierOrKeyword() ?? '';
847
- if (id.length === 0) {
848
- this.error(`Expected identifier for property access`, readReceiver.span.end);
849
- }
850
- return id;
851
- });
852
- const nameSpan = this.sourceSpan(nameStart);
853
- let receiver;
854
- if (isSafe) {
855
- if (this.consumeOptionalOperator('=')) {
856
- this.error("The '?.' operator cannot be used in the assignment");
857
- receiver = new EmptyExpr(this.span(start), this.sourceSpan(start));
858
- }
859
- else {
860
- receiver = new SafePropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
861
- }
862
- }
863
- else {
864
- if (this.consumeOptionalOperator('=')) {
865
- if (!(this.parseFlags & 1 /* ParseFlags.Action */)) {
866
- this.error('Bindings cannot contain assignments');
867
- return new EmptyExpr(this.span(start), this.sourceSpan(start));
868
- }
869
- const value = this.parseConditional();
870
- receiver = new PropertyWrite(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id, value);
871
- }
872
- else {
873
- receiver = new PropertyRead(this.span(start), this.sourceSpan(start), nameSpan, readReceiver, id);
874
- }
875
- }
876
- return receiver;
877
- }
878
- parseCall(receiver, start, isSafe) {
879
- const argumentStart = this.inputIndex;
880
- this.rparensExpected++;
881
- const args = this.parseCallArguments();
882
- const argumentSpan = this.span(argumentStart, this.inputIndex).toAbsolute(this.absoluteOffset);
883
- this.expectCharacter(chars.$RPAREN);
884
- this.rparensExpected--;
885
- const span = this.span(start);
886
- const sourceSpan = this.sourceSpan(start);
887
- return isSafe
888
- ? new SafeCall(span, sourceSpan, receiver, args, argumentSpan)
889
- : new Call(span, sourceSpan, receiver, args, argumentSpan);
890
- }
891
- parseCallArguments() {
892
- if (this.next.isCharacter(chars.$RPAREN))
893
- return [];
894
- const positionals = [];
895
- do {
896
- positionals.push(this.parsePipe());
897
- } while (this.consumeOptionalCharacter(chars.$COMMA));
898
- return positionals;
899
- }
900
- /**
901
- * Parses an identifier, a keyword, a string with an optional `-` in between,
902
- * and returns the string along with its absolute source span.
903
- */
904
- expectTemplateBindingKey() {
905
- let result = '';
906
- let operatorFound = false;
907
- const start = this.currentAbsoluteOffset;
908
- do {
909
- result += this.expectIdentifierOrKeywordOrString();
910
- operatorFound = this.consumeOptionalOperator('-');
911
- if (operatorFound) {
912
- result += '-';
913
- }
914
- } while (operatorFound);
915
- return {
916
- source: result,
917
- span: new AbsoluteSourceSpan(start, start + result.length),
918
- };
919
- }
920
- /**
921
- * Parse microsyntax template expression and return a list of bindings or
922
- * parsing errors in case the given expression is invalid.
923
- *
924
- * For example,
925
- * ```
926
- * <div *ngFor="let item of items; index as i; trackBy: func">
927
- * ```
928
- * contains five bindings:
929
- * 1. ngFor -> null
930
- * 2. item -> NgForOfContext.$implicit
931
- * 3. ngForOf -> items
932
- * 4. i -> NgForOfContext.index
933
- * 5. ngForTrackBy -> func
934
- *
935
- * For a full description of the microsyntax grammar, see
936
- * https://gist.github.com/mhevery/d3530294cff2e4a1b3fe15ff75d08855
937
- *
938
- * @param templateKey name of the microsyntax directive, like ngIf, ngFor,
939
- * without the *, along with its absolute span.
940
- */
941
- parseTemplateBindings(templateKey) {
942
- const bindings = [];
943
- // The first binding is for the template key itself
944
- // In *ngFor="let item of items", key = "ngFor", value = null
945
- // In *ngIf="cond | pipe", key = "ngIf", value = "cond | pipe"
946
- bindings.push(...this.parseDirectiveKeywordBindings(templateKey));
947
- while (this.index < this.tokens.length) {
948
- // If it starts with 'let', then this must be variable declaration
949
- const letBinding = this.parseLetBinding();
950
- if (letBinding) {
951
- bindings.push(letBinding);
952
- }
953
- else {
954
- // Two possible cases here, either `value "as" key` or
955
- // "directive-keyword expression". We don't know which case, but both
956
- // "value" and "directive-keyword" are template binding key, so consume
957
- // the key first.
958
- const key = this.expectTemplateBindingKey();
959
- // Peek at the next token, if it is "as" then this must be variable
960
- // declaration.
961
- const binding = this.parseAsBinding(key);
962
- if (binding) {
963
- bindings.push(binding);
964
- }
965
- else {
966
- // Otherwise the key must be a directive keyword, like "of". Transform
967
- // the key to actual key. Eg. of -> ngForOf, trackBy -> ngForTrackBy
968
- key.source =
969
- templateKey.source + key.source.charAt(0).toUpperCase() + key.source.substring(1);
970
- bindings.push(...this.parseDirectiveKeywordBindings(key));
971
- }
972
- }
973
- this.consumeStatementTerminator();
974
- }
975
- return new TemplateBindingParseResult(bindings, [] /* warnings */, this.errors);
976
- }
977
- parseKeyedReadOrWrite(receiver, start, isSafe) {
978
- return this.withContext(ParseContextFlags.Writable, () => {
979
- this.rbracketsExpected++;
980
- const key = this.parsePipe();
981
- if (key instanceof EmptyExpr) {
982
- this.error(`Key access cannot be empty`);
983
- }
984
- this.rbracketsExpected--;
985
- this.expectCharacter(chars.$RBRACKET);
986
- if (this.consumeOptionalOperator('=')) {
987
- if (isSafe) {
988
- this.error("The '?.' operator cannot be used in the assignment");
989
- }
990
- else {
991
- const value = this.parseConditional();
992
- return new KeyedWrite(this.span(start), this.sourceSpan(start), receiver, key, value);
993
- }
994
- }
995
- else {
996
- return isSafe
997
- ? new SafeKeyedRead(this.span(start), this.sourceSpan(start), receiver, key)
998
- : new KeyedRead(this.span(start), this.sourceSpan(start), receiver, key);
999
- }
1000
- return new EmptyExpr(this.span(start), this.sourceSpan(start));
1001
- });
1002
- }
1003
- /**
1004
- * Parse a directive keyword, followed by a mandatory expression.
1005
- * For example, "of items", "trackBy: func".
1006
- * The bindings are: ngForOf -> items, ngForTrackBy -> func
1007
- * There could be an optional "as" binding that follows the expression.
1008
- * For example,
1009
- * ```
1010
- * *ngFor="let item of items | slice:0:1 as collection".
1011
- * ^^ ^^^^^^^^^^^^^^^^^ ^^^^^^^^^^^^^
1012
- * keyword bound target optional 'as' binding
1013
- * ```
1014
- *
1015
- * @param key binding key, for example, ngFor, ngIf, ngForOf, along with its
1016
- * absolute span.
1017
- */
1018
- parseDirectiveKeywordBindings(key) {
1019
- const bindings = [];
1020
- this.consumeOptionalCharacter(chars.$COLON); // trackBy: trackByFunction
1021
- const value = this.getDirectiveBoundTarget();
1022
- let spanEnd = this.currentAbsoluteOffset;
1023
- // The binding could optionally be followed by "as". For example,
1024
- // *ngIf="cond | pipe as x". In this case, the key in the "as" binding
1025
- // is "x" and the value is the template key itself ("ngIf"). Note that the
1026
- // 'key' in the current context now becomes the "value" in the next binding.
1027
- const asBinding = this.parseAsBinding(key);
1028
- if (!asBinding) {
1029
- this.consumeStatementTerminator();
1030
- spanEnd = this.currentAbsoluteOffset;
1031
- }
1032
- const sourceSpan = new AbsoluteSourceSpan(key.span.start, spanEnd);
1033
- bindings.push(new ExpressionBinding(sourceSpan, key, value));
1034
- if (asBinding) {
1035
- bindings.push(asBinding);
1036
- }
1037
- return bindings;
1038
- }
1039
- /**
1040
- * Return the expression AST for the bound target of a directive keyword
1041
- * binding. For example,
1042
- * ```
1043
- * *ngIf="condition | pipe"
1044
- * ^^^^^^^^^^^^^^^^ bound target for "ngIf"
1045
- * *ngFor="let item of items"
1046
- * ^^^^^ bound target for "ngForOf"
1047
- * ```
1048
- */
1049
- getDirectiveBoundTarget() {
1050
- if (this.next === EOF || this.peekKeywordAs() || this.peekKeywordLet()) {
1051
- return null;
1052
- }
1053
- const ast = this.parsePipe(); // example: "condition | async"
1054
- const { start, end } = ast.span;
1055
- const value = this.input.substring(start, end);
1056
- return new ASTWithSource(ast, value, this.location, this.absoluteOffset + start, this.errors);
1057
- }
1058
- /**
1059
- * Return the binding for a variable declared using `as`. Note that the order
1060
- * of the key-value pair in this declaration is reversed. For example,
1061
- * ```
1062
- * *ngFor="let item of items; index as i"
1063
- * ^^^^^ ^
1064
- * value key
1065
- * ```
1066
- *
1067
- * @param value name of the value in the declaration, "ngIf" in the example
1068
- * above, along with its absolute span.
1069
- */
1070
- parseAsBinding(value) {
1071
- if (!this.peekKeywordAs()) {
1072
- return null;
1073
- }
1074
- this.advance(); // consume the 'as' keyword
1075
- const key = this.expectTemplateBindingKey();
1076
- this.consumeStatementTerminator();
1077
- const sourceSpan = new AbsoluteSourceSpan(value.span.start, this.currentAbsoluteOffset);
1078
- return new VariableBinding(sourceSpan, key, value);
1079
- }
1080
- /**
1081
- * Return the binding for a variable declared using `let`. For example,
1082
- * ```
1083
- * *ngFor="let item of items; let i=index;"
1084
- * ^^^^^^^^ ^^^^^^^^^^^
1085
- * ```
1086
- * In the first binding, `item` is bound to `NgForOfContext.$implicit`.
1087
- * In the second binding, `i` is bound to `NgForOfContext.index`.
1088
- */
1089
- parseLetBinding() {
1090
- if (!this.peekKeywordLet()) {
1091
- return null;
1092
- }
1093
- const spanStart = this.currentAbsoluteOffset;
1094
- this.advance(); // consume the 'let' keyword
1095
- const key = this.expectTemplateBindingKey();
1096
- let value = null;
1097
- if (this.consumeOptionalOperator('=')) {
1098
- value = this.expectTemplateBindingKey();
1099
- }
1100
- this.consumeStatementTerminator();
1101
- const sourceSpan = new AbsoluteSourceSpan(spanStart, this.currentAbsoluteOffset);
1102
- return new VariableBinding(sourceSpan, key, value);
1103
- }
1104
- /**
1105
- * Consume the optional statement terminator: semicolon or comma.
1106
- */
1107
- consumeStatementTerminator() {
1108
- this.consumeOptionalCharacter(chars.$SEMICOLON) || this.consumeOptionalCharacter(chars.$COMMA);
1109
- }
1110
- /**
1111
- * Records an error and skips over the token stream until reaching a recoverable point. See
1112
- * `this.skip` for more details on token skipping.
1113
- */
1114
- error(message, index = null) {
1115
- this.errors.push(new ParserError(message, this.input, this.locationText(index), this.location));
1116
- this.skip();
1117
- }
1118
- locationText(index = null) {
1119
- if (index == null)
1120
- index = this.index;
1121
- return index < this.tokens.length
1122
- ? `at column ${this.tokens[index].index + 1} in`
1123
- : `at the end of the expression`;
1124
- }
1125
- /**
1126
- * Records an error for an unexpected private identifier being discovered.
1127
- * @param token Token representing a private identifier.
1128
- * @param extraMessage Optional additional message being appended to the error.
1129
- */
1130
- _reportErrorForPrivateIdentifier(token, extraMessage) {
1131
- let errorMessage = `Private identifiers are not supported. Unexpected private identifier: ${token}`;
1132
- if (extraMessage !== null) {
1133
- errorMessage += `, ${extraMessage}`;
1134
- }
1135
- this.error(errorMessage);
1136
- }
1137
- /**
1138
- * Error recovery should skip tokens until it encounters a recovery point.
1139
- *
1140
- * The following are treated as unconditional recovery points:
1141
- * - end of input
1142
- * - ';' (parseChain() is always the root production, and it expects a ';')
1143
- * - '|' (since pipes may be chained and each pipe expression may be treated independently)
1144
- *
1145
- * The following are conditional recovery points:
1146
- * - ')', '}', ']' if one of calling productions is expecting one of these symbols
1147
- * - This allows skip() to recover from errors such as '(a.) + 1' allowing more of the AST to
1148
- * be retained (it doesn't skip any tokens as the ')' is retained because of the '(' begins
1149
- * an '(' <expr> ')' production).
1150
- * The recovery points of grouping symbols must be conditional as they must be skipped if
1151
- * none of the calling productions are not expecting the closing token else we will never
1152
- * make progress in the case of an extraneous group closing symbol (such as a stray ')').
1153
- * That is, we skip a closing symbol if we are not in a grouping production.
1154
- * - '=' in a `Writable` context
1155
- * - In this context, we are able to recover after seeing the `=` operator, which
1156
- * signals the presence of an independent rvalue expression following the `=` operator.
1157
- *
1158
- * If a production expects one of these token it increments the corresponding nesting count,
1159
- * and then decrements it just prior to checking if the token is in the input.
1160
- */
1161
- skip() {
1162
- let n = this.next;
1163
- while (this.index < this.tokens.length &&
1164
- !n.isCharacter(chars.$SEMICOLON) &&
1165
- !n.isOperator('|') &&
1166
- (this.rparensExpected <= 0 || !n.isCharacter(chars.$RPAREN)) &&
1167
- (this.rbracesExpected <= 0 || !n.isCharacter(chars.$RBRACE)) &&
1168
- (this.rbracketsExpected <= 0 || !n.isCharacter(chars.$RBRACKET)) &&
1169
- (!(this.context & ParseContextFlags.Writable) || !n.isOperator('='))) {
1170
- if (this.next.isError()) {
1171
- this.errors.push(new ParserError(this.next.toString(), this.input, this.locationText(), this.location));
1172
- }
1173
- this.advance();
1174
- n = this.next;
1175
- }
1176
- }
1177
- }
1178
- class SimpleExpressionChecker extends RecursiveAstVisitor {
1179
- constructor() {
1180
- super(...arguments);
1181
- this.errors = [];
1182
- }
1183
- visitPipe() {
1184
- this.errors.push('pipes');
1185
- }
1186
- }
1187
- /**
1188
- * Computes the real offset in the original template for indexes in an interpolation.
1189
- *
1190
- * Because templates can have encoded HTML entities and the input passed to the parser at this stage
1191
- * of the compiler is the _decoded_ value, we need to compute the real offset using the original
1192
- * encoded values in the interpolated tokens. Note that this is only a special case handling for
1193
- * `MlParserTokenType.ENCODED_ENTITY` token types. All other interpolated tokens are expected to
1194
- * have parts which exactly match the input string for parsing the interpolation.
1195
- *
1196
- * @param interpolatedTokens The tokens for the interpolated value.
1197
- *
1198
- * @returns A map of index locations in the decoded template to indexes in the original template
1199
- */
1200
- function getIndexMapForOriginalTemplate(interpolatedTokens) {
1201
- let offsetMap = new Map();
1202
- let consumedInOriginalTemplate = 0;
1203
- let consumedInInput = 0;
1204
- let tokenIndex = 0;
1205
- while (tokenIndex < interpolatedTokens.length) {
1206
- const currentToken = interpolatedTokens[tokenIndex];
1207
- if (currentToken.type === 9 /* MlParserTokenType.ENCODED_ENTITY */) {
1208
- const [decoded, encoded] = currentToken.parts;
1209
- consumedInOriginalTemplate += encoded.length;
1210
- consumedInInput += decoded.length;
1211
- }
1212
- else {
1213
- const lengthOfParts = currentToken.parts.reduce((sum, current) => sum + current.length, 0);
1214
- consumedInInput += lengthOfParts;
1215
- consumedInOriginalTemplate += lengthOfParts;
1216
- }
1217
- offsetMap.set(consumedInInput, consumedInOriginalTemplate);
1218
- tokenIndex++;
1219
- }
1220
- return offsetMap;
1221
- }
1222
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicGFyc2VyLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29tcGlsZXIvc3JjL2V4cHJlc3Npb25fcGFyc2VyL3BhcnNlci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFFSCxPQUFPLEtBQUssS0FBSyxNQUFNLFVBQVUsQ0FBQztBQUNsQyxPQUFPLEVBQUMsNEJBQTRCLEVBQXNCLE1BQU0sdUJBQXVCLENBQUM7QUFPeEYsT0FBTyxFQUNMLGtCQUFrQixFQUVsQixhQUFhLEVBQ2IsTUFBTSxFQUNOLFdBQVcsRUFDWCxJQUFJLEVBQ0osS0FBSyxFQUNMLFdBQVcsRUFDWCxTQUFTLEVBQ1QsaUJBQWlCLEVBQ2pCLGdCQUFnQixFQUNoQixhQUFhLEVBQ2IsU0FBUyxFQUNULFVBQVUsRUFDVixZQUFZLEVBQ1osVUFBVSxFQUVWLGdCQUFnQixFQUNoQixhQUFhLEVBQ2IsV0FBVyxFQUNYLFNBQVMsRUFDVCxTQUFTLEVBQ1QsWUFBWSxFQUNaLGFBQWEsRUFDYixtQkFBbUIsRUFDbkIsUUFBUSxFQUNSLGFBQWEsRUFDYixnQkFBZ0IsRUFHaEIsWUFBWSxFQUNaLEtBQUssRUFDTCxlQUFlLEdBQ2hCLE1BQU0sT0FBTyxDQUFDO0FBQ2YsT0FBTyxFQUFDLEdBQUcsRUFBZ0IsU0FBUyxFQUFDLE1BQU0sU0FBUyxDQUFDO0FBT3JELE1BQU0sT0FBTyxrQkFBa0I7SUFDN0IsWUFDUyxPQUE2QixFQUM3QixXQUFpQyxFQUNqQyxPQUFpQjtRQUZqQixZQUFPLEdBQVAsT0FBTyxDQUFzQjtRQUM3QixnQkFBVyxHQUFYLFdBQVcsQ0FBc0I7UUFDakMsWUFBTyxHQUFQLE9BQU8sQ0FBVTtJQUN2QixDQUFDO0NBQ0w7QUFFRCxNQUFNLE9BQU8sMEJBQTBCO0lBQ3JDLFlBQ1MsZ0JBQW1DLEVBQ25DLFFBQWtCLEVBQ2xCLE1BQXFCO1FBRnJCLHFCQUFnQixHQUFoQixnQkFBZ0IsQ0FBbUI7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cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0ICogYXMgY2hhcnMgZnJvbSAnLi4vY2hhcnMnO1xuaW1wb3J0IHtERUZBVUxUX0lOVEVSUE9MQVRJT05fQ09ORklHLCBJbnRlcnBvbGF0aW9uQ29uZmlnfSBmcm9tICcuLi9tbF9wYXJzZXIvZGVmYXVsdHMnO1xuaW1wb3J0IHtcbiAgSW50ZXJwb2xhdGVkQXR0cmlidXRlVG9rZW4sXG4gIEludGVycG9sYXRlZFRleHRUb2tlbixcbiAgVG9rZW5UeXBlIGFzIE1sUGFyc2VyVG9rZW5UeXBlLFxufSBmcm9tICcuLi9tbF9wYXJzZXIvdG9rZW5zJztcblxuaW1wb3J0IHtcbiAgQWJzb2x1dGVTb3VyY2VTcGFuLFxuICBBU1QsXG4gIEFTVFdpdGhTb3VyY2UsXG4gIEJpbmFyeSxcbiAgQmluZGluZ1BpcGUsXG4gIENhbGwsXG4gIENoYWluLFxuICBDb25kaXRpb25hbCxcbiAgRW1wdHlFeHByLFxuICBFeHByZXNzaW9uQmluZGluZyxcbiAgSW1wbGljaXRSZWNlaXZlcixcbiAgSW50ZXJwb2xhdGlvbixcbiAgS2V5ZWRSZWFkLFxuICBLZXllZFdyaXRlLFxuICBMaXRlcmFsQXJyYXksXG4gIExpdGVyYWxNYXAsXG4gIExpdGVyYWxNYXBLZXksXG4gIExpdGVyYWxQcmltaXRpdmUsXG4gIE5vbk51bGxBc3NlcnQsXG4gIFBhcnNlckVycm9yLFxuICBQYXJzZVNwYW4sXG4gIFByZWZpeE5vdCxcbiAgUHJvcGVydHlSZWFkLFxuICBQcm9wZXJ0eVdyaXRlLFxuICBSZWN1cnNpdmVBc3RWaXNpdG9yLFxuICBTYWZlQ2FsbCxcbiAgU2FmZUtleWVkUmVhZCxcbiAgU2FmZVByb3BlcnR5UmVhZCxcbiAgVGVtcGxhdGVCaW5kaW5nLFxuICBUZW1wbGF0ZUJpbmRpbmdJZGVudGlmaWVyLFxuICBUaGlzUmVjZWl2ZXIsXG4gIFVuYXJ5LFxuICBWYXJpYWJsZUJpbmRpbmcsXG59IGZyb20gJy4vYXN0JztcbmltcG9ydCB7RU9GLCBMZXhlciwgVG9rZW4sIFRva2VuVHlwZX0gZnJvbSAnLi9sZXhlcic7XG5cbmV4cG9ydCBpbnRlcmZhY2UgSW50ZXJwb2xhdGlvblBpZWNlIHtcbiAgdGV4dDogc3RyaW5nO1xuICBzdGFydDogbnVtYmVyO1xuICBlbmQ6IG51bWJlcjtcbn1cbmV4cG9ydCBjbGFzcyBTcGxpdEludGVycG9sYXRpb24ge1xuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgc3RyaW5nczogSW50ZXJwb2xhdGlvblBpZWNlW10sXG4gICAgcHVibGljIGV4cHJlc3Npb25zOiBJbnRlcnBvbGF0aW9uUGllY2VbXSxcbiAgICBwdWJsaWMgb2Zmc2V0czogbnVtYmVyW10sXG4gICkge31cbn1cblxuZXhwb3J0IGNsYXNzIFRlbXBsYXRlQmluZGluZ1BhcnNlUmVzdWx0IHtcbiAgY29uc3RydWN0b3IoXG4gICAgcHVibGljIHRlbXBsYXRlQmluZGluZ3M6IFRlbXBsYXRlQmluZGluZ1tdLFxuICAgIHB1YmxpYyB3YXJuaW5nczogc3RyaW5nW10sXG4gICAgcHVibGljIGVycm9yczogUGFyc2VyRXJyb3JbXSxcbiAgKSB7fVxufVxuXG4vKipcbiAqIFJlcHJlc2VudHMgdGhlIHBvc3NpYmxlIHBhcnNlIG1vZGVzIHRvIGJlIHVzZWQgYXMgYSBiaXRtYXNrLlxuICovXG5leHBvcnQgY29uc3QgZW51bSBQYXJzZUZsYWdzIHtcbiAgTm9uZSA9IDAsXG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgYW4gb3V0cHV0IGJpbmRpbmcgaXMgYmVpbmcgcGFyc2VkLlxuICAgKi9cbiAgQWN0aW9uID0gMSA8PCAwLFxufVxuXG5leHBvcnQgY2xhc3MgUGFyc2VyIHtcbiAgcHJpdmF0ZSBlcnJvcnM6IFBhcnNlckVycm9yW10gPSBbXTtcblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIF9sZXhlcjogTGV4ZXIpIHt9XG5cbiAgcGFyc2VBY3Rpb24oXG4gICAgaW5wdXQ6IHN0cmluZyxcbiAgICBsb2NhdGlvbjogc3RyaW5nLFxuICAgIGFic29sdXRlT2Zmc2V0OiBudW1iZXIsXG4gICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyA9IERFRkFVTFRfSU5URVJQT0xBVElPTl9DT05GSUcsXG4gICk6IEFTVFdpdGhTb3VyY2Uge1xuICAgIHRoaXMuX2NoZWNrTm9JbnRlcnBvbGF0aW9uKGlucHV0LCBsb2NhdGlvbiwgaW50ZXJwb2xhdGlvbkNvbmZpZyk7XG4gICAgY29uc3Qgc291cmNlVG9MZXggPSB0aGlzLl9zdHJpcENvbW1lbnRzKGlucHV0KTtcbiAgICBjb25zdCB0b2tlbnMgPSB0aGlzLl9sZXhlci50b2tlbml6ZShzb3VyY2VUb0xleCk7XG4gICAgY29uc3QgYXN0ID0gbmV3IF9QYXJzZUFTVChcbiAgICAgIGlucHV0LFxuICAgICAgbG9jYXRpb24sXG4gICAgICBhYnNvbHV0ZU9mZnNldCxcbiAgICAgIHRva2VucyxcbiAgICAgIFBhcnNlRmxhZ3MuQWN0aW9uLFxuICAgICAgdGhpcy5lcnJvcnMsXG4gICAgICAwLFxuICAgICkucGFyc2VDaGFpbigpO1xuXG4gICAgcmV0dXJuIG5ldyBBU1RXaXRoU291cmNlKGFzdCwgaW5wdXQsIGxvY2F0aW9uLCBhYnNvbHV0ZU9mZnNldCwgdGhpcy5lcnJvcnMpO1xuICB9XG5cbiAgcGFyc2VCaW5kaW5nKFxuICAgIGlucHV0OiBzdHJpbmcsXG4gICAgbG9jYXRpb246IHN0cmluZyxcbiAgICBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICAgIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcgPSBERUZBVUxUX0lOVEVSUE9MQVRJT05fQ09ORklHLFxuICApOiBBU1RXaXRoU291cmNlIHtcbiAgICBjb25zdCBhc3QgPSB0aGlzLl9wYXJzZUJpbmRpbmdBc3QoaW5wdXQsIGxvY2F0aW9uLCBhYnNvbHV0ZU9mZnNldCwgaW50ZXJwb2xhdGlvbkNvbmZpZyk7XG4gICAgcmV0dXJuIG5ldyBBU1RXaXRoU291cmNlKGFzdCwgaW5wdXQsIGxvY2F0aW9uLCBhYnNvbHV0ZU9mZnNldCwgdGhpcy5lcnJvcnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBjaGVja1NpbXBsZUV4cHJlc3Npb24oYXN0OiBBU1QpOiBzdHJpbmdbXSB7XG4gICAgY29uc3QgY2hlY2tlciA9IG5ldyBTaW1wbGVFeHByZXNzaW9uQ2hlY2tlcigpO1xuICAgIGFzdC52aXNpdChjaGVja2VyKTtcbiAgICByZXR1cm4gY2hlY2tlci5lcnJvcnM7XG4gIH1cblxuICAvLyBIb3N0IGJpbmRpbmdzIHBhcnNlZCBoZXJlXG4gIHBhcnNlU2ltcGxlQmluZGluZyhcbiAgICBpbnB1dDogc3RyaW5nLFxuICAgIGxvY2F0aW9uOiBzdHJpbmcsXG4gICAgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcixcbiAgICBpbnRlcnBvbGF0aW9uQ29uZmlnOiBJbnRlcnBvbGF0aW9uQ29uZmlnID0gREVGQVVMVF9JTlRFUlBPTEFUSU9OX0NPTkZJRyxcbiAgKTogQVNUV2l0aFNvdXJjZSB7XG4gICAgY29uc3QgYXN0ID0gdGhpcy5fcGFyc2VCaW5kaW5nQXN0KGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIGludGVycG9sYXRpb25Db25maWcpO1xuICAgIGNvbnN0IGVycm9ycyA9IHRoaXMuY2hlY2tTaW1wbGVFeHByZXNzaW9uKGFzdCk7XG4gICAgaWYgKGVycm9ycy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLl9yZXBvcnRFcnJvcihcbiAgICAgICAgYEhvc3QgYmluZGluZyBleHByZXNzaW9uIGNhbm5vdCBjb250YWluICR7ZXJyb3JzLmpvaW4oJyAnKX1gLFxuICAgICAgICBpbnB1dCxcbiAgICAgICAgbG9jYXRpb24sXG4gICAgICApO1xuICAgIH1cbiAgICByZXR1cm4gbmV3IEFTVFdpdGhTb3VyY2UoYXN0LCBpbnB1dCwgbG9jYXRpb24sIGFic29sdXRlT2Zmc2V0LCB0aGlzLmVycm9ycyk7XG4gIH1cblxuICBwcml2YXRlIF9yZXBvcnRFcnJvcihtZXNzYWdlOiBzdHJpbmcsIGlucHV0OiBzdHJpbmcsIGVyckxvY2F0aW9uOiBzdHJpbmcsIGN0eExvY2F0aW9uPzogc3RyaW5nKSB7XG4gICAgdGhpcy5lcnJvcnMucHVzaChuZXcgUGFyc2VyRXJyb3IobWVzc2FnZSwgaW5wdXQsIGVyckxvY2F0aW9uLCBjdHhMb2NhdGlvbikpO1xuICB9XG5cbiAgcHJpdmF0ZSBfcGFyc2VCaW5kaW5nQXN0KFxuICAgIGlucHV0OiBzdHJpbmcsXG4gICAgbG9jYXRpb246IHN0cmluZyxcbiAgICBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICAgIGludGVycG9sYXRpb25Db25maWc6IEludGVycG9sYXRpb25Db25maWcsXG4gICk6IEFTVCB7XG4gICAgdGhpcy5fY2hlY2tOb0ludGVycG9sYXRpb24oaW5wdXQsIGxvY2F0aW9uLCBpbnRlcnBvbGF0aW9uQ29uZmlnKTtcbiAgICBjb25zdCBzb3VyY2VUb0xleCA9IHRoaXMuX3N0cmlwQ29tbWVudHMoaW5wdXQpO1xuICAgIGNvbnN0IHRva2VucyA9IHRoaXMuX2xleGVyLnRva2VuaXplKHNvdXJjZVRvTGV4KTtcbiAgICByZXR1cm4gbmV3IF9QYXJzZUFTVChcbiAgICAgIGlucHV0LFxuICAgICAgbG9jYXRpb24sXG4gICAgICBhYnNvbHV0ZU9mZnNldCxcbiAgICAgIHRva2VucyxcbiAgICAgIFBhcnNlRmxhZ3MuTm9uZSxcbiAgICAgIHRoaXMuZXJyb3JzLFxuICAgICAgMCxcbiAgICApLnBhcnNlQ2hhaW4oKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBtaWNyb3N5bnRheCB0ZW1wbGF0ZSBleHByZXNzaW9uIGFuZCByZXR1cm4gYSBsaXN0IG9mIGJpbmRpbmdzIG9yXG4gICAqIHBhcnNpbmcgZXJyb3JzIGluIGNhc2UgdGhlIGdpdmVuIGV4cHJlc3Npb24gaXMgaW52YWxpZC5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsXG4gICAqIGBgYFxuICAgKiAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXNcIj5cbiAgICogICAgICAgICBeICAgICAgXiBhYnNvbHV0ZVZhbHVlT2Zmc2V0IGZvciBgdGVtcGxhdGVWYWx1ZWBcbiAgICogICAgICAgICBhYnNvbHV0ZUtleU9mZnNldCBmb3IgYHRlbXBsYXRlS2V5YFxuICAgKiBgYGBcbiAgICogY29udGFpbnMgdGhyZWUgYmluZGluZ3M6XG4gICAqIDEuIG5nRm9yIC0+IG51bGxcbiAgICogMi4gaXRlbSAtPiBOZ0Zvck9mQ29udGV4dC4kaW1wbGljaXRcbiAgICogMy4gbmdGb3JPZiAtPiBpdGVtc1xuICAgKlxuICAgKiBUaGlzIGlzIGFwcGFyZW50IGZyb20gdGhlIGRlLXN1Z2FyZWQgdGVtcGxhdGU6XG4gICAqIGBgYFxuICAgKiAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtaXRlbSBbbmdGb3JPZl09XCJpdGVtc1wiPlxuICAgKiBgYGBcbiAgICpcbiAgICogQHBhcmFtIHRlbXBsYXRlS2V5IG5hbWUgb2YgZGlyZWN0aXZlLCB3aXRob3V0IHRoZSAqIHByZWZpeC4gRm9yIGV4YW1wbGU6IG5nSWYsIG5nRm9yXG4gICAqIEBwYXJhbSB0ZW1wbGF0ZVZhbHVlIFJIUyBvZiB0aGUgbWljcm9zeW50YXggYXR0cmlidXRlXG4gICAqIEBwYXJhbSB0ZW1wbGF0ZVVybCB0ZW1wbGF0ZSBmaWxlbmFtZSBpZiBpdCdzIGV4dGVybmFsLCBjb21wb25lbnQgZmlsZW5hbWUgaWYgaXQncyBpbmxpbmVcbiAgICogQHBhcmFtIGFic29sdXRlS2V5T2Zmc2V0IHN0YXJ0IG9mIHRoZSBgdGVtcGxhdGVLZXlgXG4gICAqIEBwYXJhbSBhYnNvbHV0ZVZhbHVlT2Zmc2V0IHN0YXJ0IG9mIHRoZSBgdGVtcGxhdGVWYWx1ZWBcbiAgICovXG4gIHBhcnNlVGVtcGxhdGVCaW5kaW5ncyhcbiAgICB0ZW1wbGF0ZUtleTogc3RyaW5nLFxuICAgIHRlbXBsYXRlVmFsdWU6IHN0cmluZyxcbiAgICB0ZW1wbGF0ZVVybDogc3RyaW5nLFxuICAgIGFic29sdXRlS2V5T2Zmc2V0OiBudW1iZXIsXG4gICAgYWJzb2x1dGVWYWx1ZU9mZnNldDogbnVtYmVyLFxuICApOiBUZW1wbGF0ZUJpbmRpbmdQYXJzZVJlc3VsdCB7XG4gICAgY29uc3QgdG9rZW5zID0gdGhpcy5fbGV4ZXIudG9rZW5pemUodGVtcGxhdGVWYWx1ZSk7XG4gICAgY29uc3QgcGFyc2VyID0gbmV3IF9QYXJzZUFTVChcbiAgICAgIHRlbXBsYXRlVmFsdWUsXG4gICAgICB0ZW1wbGF0ZVVybCxcbiAgICAgIGFic29sdXRlVmFsdWVPZmZzZXQsXG4gICAgICB0b2tlbnMsXG4gICAgICBQYXJzZUZsYWdzLk5vbmUsXG4gICAgICB0aGlzLmVycm9ycyxcbiAgICAgIDAgLyogcmVsYXRpdmUgb2Zmc2V0ICovLFxuICAgICk7XG4gICAgcmV0dXJuIHBhcnNlci5wYXJzZVRlbXBsYXRlQmluZGluZ3Moe1xuICAgICAgc291cmNlOiB0ZW1wbGF0ZUtleSxcbiAgICAgIHNwYW46IG5ldyBBYnNvbHV0ZVNvdXJjZVNwYW4oYWJzb2x1dGVLZXlPZmZzZXQsIGFic29sdXRlS2V5T2Zmc2V0ICsgdGVtcGxhdGVLZXkubGVuZ3RoKSxcbiAgICB9KTtcbiAgfVxuXG4gIHBhcnNlSW50ZXJwb2xhdGlvbihcbiAgICBpbnB1dDogc3RyaW5nLFxuICAgIGxvY2F0aW9uOiBzdHJpbmcsXG4gICAgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcixcbiAgICBpbnRlcnBvbGF0ZWRUb2tlbnM6IEludGVycG9sYXRlZEF0dHJpYnV0ZVRva2VuW10gfCBJbnRlcnBvbGF0ZWRUZXh0VG9rZW5bXSB8IG51bGwsXG4gICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyA9IERFRkFVTFRfSU5URVJQT0xBVElPTl9DT05GSUcsXG4gICk6IEFTVFdpdGhTb3VyY2UgfCBudWxsIHtcbiAgICBjb25zdCB7c3RyaW5ncywgZXhwcmVzc2lvbnMsIG9mZnNldHN9ID0gdGhpcy5zcGxpdEludGVycG9sYXRpb24oXG4gICAgICBpbnB1dCxcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgaW50ZXJwb2xhdGVkVG9rZW5zLFxuICAgICAgaW50ZXJwb2xhdGlvbkNvbmZpZyxcbiAgICApO1xuICAgIGlmIChleHByZXNzaW9ucy5sZW5ndGggPT09IDApIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgZXhwcmVzc2lvbk5vZGVzOiBBU1RbXSA9IFtdO1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBleHByZXNzaW9ucy5sZW5ndGg7ICsraSkge1xuICAgICAgY29uc3QgZXhwcmVzc2lvblRleHQgPSBleHByZXNzaW9uc1tpXS50ZXh0O1xuICAgICAgY29uc3Qgc291cmNlVG9MZXggPSB0aGlzLl9zdHJpcENvbW1lbnRzKGV4cHJlc3Npb25UZXh0KTtcbiAgICAgIGNvbnN0IHRva2VucyA9IHRoaXMuX2xleGVyLnRva2VuaXplKHNvdXJjZVRvTGV4KTtcbiAgICAgIGNvbnN0IGFzdCA9IG5ldyBfUGFyc2VBU1QoXG4gICAgICAgIGlucHV0LFxuICAgICAgICBsb2NhdGlvbixcbiAgICAgICAgYWJzb2x1dGVPZmZzZXQsXG4gICAgICAgIHRva2VucyxcbiAgICAgICAgUGFyc2VGbGFncy5Ob25lLFxuICAgICAgICB0aGlzLmVycm9ycyxcbiAgICAgICAgb2Zmc2V0c1tpXSxcbiAgICAgICkucGFyc2VDaGFpbigpO1xuICAgICAgZXhwcmVzc2lvbk5vZGVzLnB1c2goYXN0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5jcmVhdGVJbnRlcnBvbGF0aW9uQXN0KFxuICAgICAgc3RyaW5ncy5tYXAoKHMpID0+IHMudGV4dCksXG4gICAgICBleHByZXNzaW9uTm9kZXMsXG4gICAgICBpbnB1dCxcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgYWJzb2x1dGVPZmZzZXQsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTaW1pbGFyIHRvIGBwYXJzZUludGVycG9sYXRpb25gLCBidXQgdHJlYXRzIHRoZSBwcm92aWRlZCBzdHJpbmcgYXMgYSBzaW5nbGUgZXhwcmVzc2lvblxuICAgKiBlbGVtZW50IHRoYXQgd291bGQgbm9ybWFsbHkgYXBwZWFyIHdpdGhpbiB0aGUgaW50ZXJwb2xhdGlvbiBwcmVmaXggYW5kIHN1ZmZpeCAoYHt7YCBhbmQgYH19YCkuXG4gICAqIFRoaXMgaXMgdXNlZCBmb3IgcGFyc2luZyB0aGUgc3dpdGNoIGV4cHJlc3Npb24gaW4gSUNVcy5cbiAgICovXG4gIHBhcnNlSW50ZXJwb2xhdGlvbkV4cHJlc3Npb24oXG4gICAgZXhwcmVzc2lvbjogc3RyaW5nLFxuICAgIGxvY2F0aW9uOiBzdHJpbmcsXG4gICAgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcixcbiAgKTogQVNUV2l0aFNvdXJjZSB7XG4gICAgY29uc3Qgc291cmNlVG9MZXggPSB0aGlzLl9zdHJpcENvbW1lbnRzKGV4cHJlc3Npb24pO1xuICAgIGNvbnN0IHRva2VucyA9IHRoaXMuX2xleGVyLnRva2VuaXplKHNvdXJjZVRvTGV4KTtcbiAgICBjb25zdCBhc3QgPSBuZXcgX1BhcnNlQVNUKFxuICAgICAgZXhwcmVzc2lvbixcbiAgICAgIGxvY2F0aW9uLFxuICAgICAgYWJzb2x1dGVPZmZzZXQsXG4gICAgICB0b2tlbnMsXG4gICAgICBQYXJzZUZsYWdzLk5vbmUsXG4gICAgICB0aGlzLmVycm9ycyxcbiAgICAgIDAsXG4gICAgKS5wYXJzZUNoYWluKCk7XG4gICAgY29uc3Qgc3RyaW5ncyA9IFsnJywgJyddOyAvLyBUaGUgcHJlZml4IGFuZCBzdWZmaXggc3RyaW5ncyBhcmUgYm90aCBlbXB0eVxuICAgIHJldHVybiB0aGlzLmNyZWF0ZUludGVycG9sYXRpb25Bc3Qoc3RyaW5ncywgW2FzdF0sIGV4cHJlc3Npb24sIGxvY2F0aW9uLCBhYnNvbHV0ZU9mZnNldCk7XG4gIH1cblxuICBwcml2YXRlIGNyZWF0ZUludGVycG9sYXRpb25Bc3QoXG4gICAgc3RyaW5nczogc3RyaW5nW10sXG4gICAgZXhwcmVzc2lvbnM6IEFTVFtdLFxuICAgIGlucHV0OiBzdHJpbmcsXG4gICAgbG9jYXRpb246IHN0cmluZyxcbiAgICBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICApOiBBU1RXaXRoU291cmNlIHtcbiAgICBjb25zdCBzcGFuID0gbmV3IFBhcnNlU3BhbigwLCBpbnB1dC5sZW5ndGgpO1xuICAgIGNvbnN0IGludGVycG9sYXRpb24gPSBuZXcgSW50ZXJwb2xhdGlvbihcbiAgICAgIHNwYW4sXG4gICAgICBzcGFuLnRvQWJzb2x1dGUoYWJzb2x1dGVPZmZzZXQpLFxuICAgICAgc3RyaW5ncyxcbiAgICAgIGV4cHJlc3Npb25zLFxuICAgICk7XG4gICAgcmV0dXJuIG5ldyBBU1RXaXRoU291cmNlKGludGVycG9sYXRpb24sIGlucHV0LCBsb2NhdGlvbiwgYWJzb2x1dGVPZmZzZXQsIHRoaXMuZXJyb3JzKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTcGxpdHMgYSBzdHJpbmcgb2YgdGV4dCBpbnRvIFwicmF3XCIgdGV4dCBzZWdtZW50cyBhbmQgZXhwcmVzc2lvbnMgcHJlc2VudCBpbiBpbnRlcnBvbGF0aW9ucyBpblxuICAgKiB0aGUgc3RyaW5nLlxuICAgKiBSZXR1cm5zIGBudWxsYCBpZiB0aGVyZSBhcmUgbm8gaW50ZXJwb2xhdGlvbnMsIG90aGVyd2lzZSBhXG4gICAqIGBTcGxpdEludGVycG9sYXRpb25gIHdpdGggc3BsaXRzIHRoYXQgbG9vayBsaWtlXG4gICAqICAgPHJhdyB0ZXh0PiA8ZXhwcmVzc2lvbj4gPHJhdyB0ZXh0PiAuLi4gPHJhdyB0ZXh0PiA8ZXhwcmVzc2lvbj4gPHJhdyB0ZXh0PlxuICAgKi9cbiAgc3BsaXRJbnRlcnBvbGF0aW9uKFxuICAgIGlucHV0OiBzdHJpbmcsXG4gICAgbG9jYXRpb246IHN0cmluZyxcbiAgICBpbnRlcnBvbGF0ZWRUb2tlbnM6IEludGVycG9sYXRlZEF0dHJpYnV0ZVRva2VuW10gfCBJbnRlcnBvbGF0ZWRUZXh0VG9rZW5bXSB8IG51bGwsXG4gICAgaW50ZXJwb2xhdGlvbkNvbmZpZzogSW50ZXJwb2xhdGlvbkNvbmZpZyA9IERFRkFVTFRfSU5URVJQT0xBVElPTl9DT05GSUcsXG4gICk6IFNwbGl0SW50ZXJwb2xhdGlvbiB7XG4gICAgY29uc3Qgc3RyaW5nczogSW50ZXJwb2xhdGlvblBpZWNlW10gPSBbXTtcbiAgICBjb25zdCBleHByZXNzaW9uczogSW50ZXJwb2xhdGlvblBpZWNlW10gPSBbXTtcbiAgICBjb25zdCBvZmZzZXRzOiBudW1iZXJbXSA9IFtdO1xuICAgIGNvbnN0IGlucHV0VG9UZW1wbGF0ZUluZGV4TWFwID0gaW50ZXJwb2xhdGVkVG9rZW5zXG4gICAgICA/IGdldEluZGV4TWFwRm9yT3JpZ2luYWxUZW1wbGF0ZShpbnRlcnBvbGF0ZWRUb2tlbnMpXG4gICAgICA6IG51bGw7XG4gICAgbGV0IGkgPSAwO1xuICAgIGxldCBhdEludGVycG9sYXRpb24gPSBmYWxzZTtcbiAgICBsZXQgZXh0ZW5kTGFzdFN0cmluZyA9IGZhbHNlO1xuICAgIGxldCB7c3RhcnQ6IGludGVycFN0YXJ0LCBlbmQ6IGludGVycEVuZH0gPSBpbnRlcnBvbGF0aW9uQ29uZmlnO1xuICAgIHdoaWxlIChpIDwgaW5wdXQubGVuZ3RoKSB7XG4gICAgICBpZiAoIWF0SW50ZXJwb2xhdGlvbikge1xuICAgICAgICAvLyBwYXJzZSB1bnRpbCBzdGFydGluZyB7e1xuICAgICAgICBjb25zdCBzdGFydCA9IGk7XG4gICAgICAgIGkgPSBpbnB1dC5pbmRleE9mKGludGVycFN0YXJ0LCBpKTtcbiAgICAgICAgaWYgKGkgPT09IC0xKSB7XG4gICAgICAgICAgaSA9IGlucHV0Lmxlbmd0aDtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB0ZXh0ID0gaW5wdXQuc3Vic3RyaW5nKHN0YXJ0LCBpKTtcbiAgICAgICAgc3RyaW5ncy5wdXNoKHt0ZXh0LCBzdGFydCwgZW5kOiBpfSk7XG5cbiAgICAgICAgYXRJbnRlcnBvbGF0aW9uID0gdHJ1ZTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIC8vIHBhcnNlIGZyb20gc3RhcnRpbmcge3sgdG8gZW5kaW5nIH19IHdoaWxlIGlnbm9yaW5nIGNvbnRlbnQgaW5zaWRlIHF1b3Rlcy5cbiAgICAgICAgY29uc3QgZnVsbFN0YXJ0ID0gaTtcbiAgICAgICAgY29uc3QgZXhwclN0YXJ0ID0gZnVsbFN0YXJ0ICsgaW50ZXJwU3RhcnQubGVuZ3RoO1xuICAgICAgICBjb25zdCBleHByRW5kID0gdGhpcy5fZ2V0SW50ZXJwb2xhdGlvbkVuZEluZGV4KGlucHV0LCBpbnRlcnBFbmQsIGV4cHJTdGFydCk7XG4gICAgICAgIGlmIChleHByRW5kID09PSAtMSkge1xuICAgICAgICAgIC8vIENvdWxkIG5vdCBmaW5kIHRoZSBlbmQgb2YgdGhlIGludGVycG9sYXRpb247IGRvIG5vdCBwYXJzZSBhbiBleHByZXNzaW9uLlxuICAgICAgICAgIC8vIEluc3RlYWQgd2Ugc2hvdWxkIGV4dGVuZCB0aGUgY29udGVudCBvbiB0aGUgbGFzdCByYXcgc3RyaW5nLlxuICAgICAgICAgIGF0SW50ZXJwb2xhdGlvbiA9IGZhbHNlO1xuICAgICAgICAgIGV4dGVuZExhc3RTdHJpbmcgPSB0cnVlO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IGZ1bGxFbmQgPSBleHByRW5kICsgaW50ZXJwRW5kLmxlbmd0aDtcblxuICAgICAgICBjb25zdCB0ZXh0ID0gaW5wdXQuc3Vic3RyaW5nKGV4cHJTdGFydCwgZXhwckVuZCk7XG4gICAgICAgIGlmICh0ZXh0LnRyaW0oKS5sZW5ndGggPT09IDApIHtcbiAgICAgICAgICB0aGlzLl9yZXBvcnRFcnJvcihcbiAgICAgICAgICAgICdCbGFuayBleHByZXNzaW9ucyBhcmUgbm90IGFsbG93ZWQgaW4gaW50ZXJwb2xhdGVkIHN0cmluZ3MnLFxuICAgICAgICAgICAgaW5wdXQsXG4gICAgICAgICAgICBgYXQgY29sdW1uICR7aX0gaW5gLFxuICAgICAgICAgICAgbG9jYXRpb24sXG4gICAgICAgICAgKTtcbiAgICAgICAgfVxuICAgICAgICBleHByZXNzaW9ucy5wdXNoKHt0ZXh0LCBzdGFydDogZnVsbFN0YXJ0LCBlbmQ6IGZ1bGxFbmR9KTtcbiAgICAgICAgY29uc3Qgc3RhcnRJbk9yaWdpbmFsVGVtcGxhdGUgPSBpbnB1dFRvVGVtcGxhdGVJbmRleE1hcD8uZ2V0KGZ1bGxTdGFydCkgPz8gZnVsbFN0YXJ0O1xuICAgICAgICBjb25zdCBvZmZzZXQgPSBzdGFydEluT3JpZ2luYWxUZW1wbGF0ZSArIGludGVycFN0YXJ0Lmxlbmd0aDtcbiAgICAgICAgb2Zmc2V0cy5wdXNoKG9mZnNldCk7XG5cbiAgICAgICAgaSA9IGZ1bGxFbmQ7XG4gICAgICAgIGF0SW50ZXJwb2xhdGlvbiA9IGZhbHNlO1xuICAgICAgfVxuICAgIH1cbiAgICBpZiAoIWF0SW50ZXJwb2xhdGlvbikge1xuICAgICAgLy8gSWYgd2UgYXJlIG5vdyBhdCBhIHRleHQgc2VjdGlvbiwgYWRkIHRoZSByZW1haW5pbmcgY29udGVudCBhcyBhIHJhdyBzdHJpbmcuXG4gICAgICBpZiAoZXh0ZW5kTGFzdFN0cmluZykge1xuICAgICAgICBjb25zdCBwaWVjZSA9IHN0cmluZ3Nbc3RyaW5ncy5sZW5ndGggLSAxXTtcbiAgICAgICAgcGllY2UudGV4dCArPSBpbnB1dC5zdWJzdHJpbmcoaSk7XG4gICAgICAgIHBpZWNlLmVuZCA9IGlucHV0Lmxlbmd0aDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN0cmluZ3MucHVzaCh7dGV4dDogaW5wdXQuc3Vic3RyaW5nKGkpLCBzdGFydDogaSwgZW5kOiBpbnB1dC5sZW5ndGh9KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIG5ldyBTcGxpdEludGVycG9sYXRpb24oc3RyaW5ncywgZXhwcmVzc2lvbnMsIG9mZnNldHMpO1xuICB9XG5cbiAgd3JhcExpdGVyYWxQcmltaXRpdmUoXG4gICAgaW5wdXQ6IHN0cmluZyB8IG51bGwsXG4gICAgbG9jYXRpb246IHN0cmluZyxcbiAgICBhYnNvbHV0ZU9mZnNldDogbnVtYmVyLFxuICApOiBBU1RXaXRoU291cmNlIHtcbiAgICBjb25zdCBzcGFuID0gbmV3IFBhcnNlU3BhbigwLCBpbnB1dCA9PSBudWxsID8gMCA6IGlucHV0Lmxlbmd0aCk7XG4gICAgcmV0dXJuIG5ldyBBU1RXaXRoU291cmNlKFxuICAgICAgbmV3IExpdGVyYWxQcmltaXRpdmUoc3Bhbiwgc3Bhbi50b0Fic29sdXRlKGFic29sdXRlT2Zmc2V0KSwgaW5wdXQpLFxuICAgICAgaW5wdXQsXG4gICAgICBsb2NhdGlvbixcbiAgICAgIGFic29sdXRlT2Zmc2V0LFxuICAgICAgdGhpcy5lcnJvcnMsXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX3N0cmlwQ29tbWVudHMoaW5wdXQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgY29uc3QgaSA9IHRoaXMuX2NvbW1lbnRTdGFydChpbnB1dCk7XG4gICAgcmV0dXJuIGkgIT0gbnVsbCA/IGlucHV0LnN1YnN0cmluZygwLCBpKSA6IGlucHV0O1xuICB9XG5cbiAgcHJpdmF0ZSBfY29tbWVudFN0YXJ0KGlucHV0OiBzdHJpbmcpOiBudW1iZXIgfCBudWxsIHtcbiAgICBsZXQgb3V0ZXJRdW90ZTogbnVtYmVyIHwgbnVsbCA9IG51bGw7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpbnB1dC5sZW5ndGggLSAxOyBpKyspIHtcbiAgICAgIGNvbnN0IGNoYXIgPSBpbnB1dC5jaGFyQ29kZUF0KGkpO1xuICAgICAgY29uc3QgbmV4dENoYXIgPSBpbnB1dC5jaGFyQ29kZUF0KGkgKyAxKTtcblxuICAgICAgaWYgKGNoYXIgPT09IGNoYXJzLiRTTEFTSCAmJiBuZXh0Q2hhciA9PSBjaGFycy4kU0xBU0ggJiYgb3V0ZXJRdW90ZSA9PSBudWxsKSByZXR1cm4gaTtcblxuICAgICAgaWYgKG91dGVyUXVvdGUgPT09IGNoYXIpIHtcbiAgICAgICAgb3V0ZXJRdW90ZSA9IG51bGw7XG4gICAgICB9IGVsc2UgaWYgKG91dGVyUXVvdGUgPT0gbnVsbCAmJiBjaGFycy5pc1F1b3RlKGNoYXIpKSB7XG4gICAgICAgIG91dGVyUXVvdGUgPSBjaGFyO1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgX2NoZWNrTm9JbnRlcnBvbGF0aW9uKFxuICAgIGlucHV0OiBzdHJpbmcsXG4gICAgbG9jYXRpb246IHN0cmluZyxcbiAgICB7c3RhcnQsIGVuZH06IEludGVycG9sYXRpb25Db25maWcsXG4gICk6IHZvaWQge1xuICAgIGxldCBzdGFydEluZGV4ID0gLTE7XG4gICAgbGV0IGVuZEluZGV4ID0gLTE7XG5cbiAgICBmb3IgKGNvbnN0IGNoYXJJbmRleCBvZiB0aGlzLl9mb3JFYWNoVW5xdW90ZWRDaGFyKGlucHV0LCAwKSkge1xuICAgICAgaWYgKHN0YXJ0SW5kZXggPT09IC0xKSB7XG4gICAgICAgIGlmIChpbnB1dC5zdGFydHNXaXRoKHN0YXJ0KSkge1xuICAgICAgICAgIHN0YXJ0SW5kZXggPSBjaGFySW5kZXg7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVuZEluZGV4ID0gdGhpcy5fZ2V0SW50ZXJwb2xhdGlvbkVuZEluZGV4KGlucHV0LCBlbmQsIGNoYXJJbmRleCk7XG4gICAgICAgIGlmIChlbmRJbmRleCA+IC0xKSB7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3RhcnRJbmRleCA+IC0xICYmIGVuZEluZGV4ID4gLTEpIHtcbiAgICAgIHRoaXMuX3JlcG9ydEVycm9yKFxuICAgICAgICBgR290IGludGVycG9sYXRpb24gKCR7c3RhcnR9JHtlbmR9KSB3aGVyZSBleHByZXNzaW9uIHdhcyBleHBlY3RlZGAsXG4gICAgICAgIGlucHV0LFxuICAgICAgICBgYXQgY29sdW1uICR7c3RhcnRJbmRleH0gaW5gLFxuICAgICAgICBsb2NhdGlvbixcbiAgICAgICk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIHRoZSBpbmRleCBvZiB0aGUgZW5kIG9mIGFuIGludGVycG9sYXRpb24gZXhwcmVzc2lvblxuICAgKiB3aGlsZSBpZ25vcmluZyBjb21tZW50cyBhbmQgcXVvdGVkIGNvbnRlbnQuXG4gICAqL1xuICBwcml2YXRlIF9nZXRJbnRlcnBvbGF0aW9uRW5kSW5kZXgoaW5wdXQ6IHN0cmluZywgZXhwcmVzc2lvbkVuZDogc3RyaW5nLCBzdGFydDogbnVtYmVyKTogbnVtYmVyIHtcbiAgICBmb3IgKGNvbnN0IGNoYXJJbmRleCBvZiB0aGlzLl9mb3JFYWNoVW5xdW90ZWRDaGFyKGlucHV0LCBzdGFydCkpIHtcbiAgICAgIGlmIChpbnB1dC5zdGFydHNXaXRoKGV4cHJlc3Npb25FbmQsIGNoYXJJbmRleCkpIHtcbiAgICAgICAgcmV0dXJuIGNoYXJJbmRleDtcbiAgICAgIH1cblxuICAgICAgLy8gTm90aGluZyBlbHNlIGluIHRoZSBleHByZXNzaW9uIG1hdHRlcnMgYWZ0ZXIgd2UndmVcbiAgICAgIC8vIGhpdCBhIGNvbW1lbnQgc28gbG9vayBkaXJlY3RseSBmb3IgdGhlIGVuZCB0b2tlbi5cbiAgICAgIGlmIChpbnB1dC5zdGFydHNXaXRoKCcvLycsIGNoYXJJbmRleCkpIHtcbiAgICAgICAgcmV0dXJuIGlucHV0LmluZGV4T2YoZXhwcmVzc2lvbkVuZCwgY2hhckluZGV4KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gLTE7XG4gIH1cblxuICAvKipcbiAgICogR2VuZXJhdG9yIHVzZWQgdG8gaXRlcmF0ZSBvdmVyIHRoZSBjaGFyYWN0ZXIgaW5kZXhlcyBvZiBhIHN0cmluZyB0aGF0IGFyZSBvdXRzaWRlIG9mIHF1b3Rlcy5cbiAgICogQHBhcmFtIGlucHV0IFN0cmluZyB0byBsb29wIHRocm91Z2guXG4gICAqIEBwYXJhbSBzdGFydCBJbmRleCB3aXRoaW4gdGhlIHN0cmluZyBhdCB3aGljaCB0byBzdGFydC5cbiAgICovXG4gIHByaXZhdGUgKl9mb3JFYWNoVW5xdW90ZWRDaGFyKGlucHV0OiBzdHJpbmcsIHN0YXJ0OiBudW1iZXIpIHtcbiAgICBsZXQgY3VycmVudFF1b3RlOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICBsZXQgZXNjYXBlQ291bnQgPSAwO1xuICAgIGZvciAobGV0IGkgPSBzdGFydDsgaSA8IGlucHV0Lmxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBjaGFyID0gaW5wdXRbaV07XG4gICAgICAvLyBTa2lwIHRoZSBjaGFyYWN0ZXJzIGluc2lkZSBxdW90ZXMuIE5vdGUgdGhhdCB3ZSBvbmx5IGNhcmUgYWJvdXQgdGhlIG91dGVyLW1vc3RcbiAgICAgIC8vIHF1b3RlcyBtYXRjaGluZyB1cCBhbmQgd2UgbmVlZCB0byBhY2NvdW50IGZvciBlc2NhcGUgY2hhcmFjdGVycy5cbiAgICAgIGlmIChcbiAgICAgICAgY2hhcnMuaXNRdW90ZShpbnB1dC5jaGFyQ29kZUF0KGkpKSAmJlxuICAgICAgICAoY3VycmVudFF1b3RlID09PSBudWxsIHx8IGN1cnJlbnRRdW90ZSA9PT0gY2hhcikgJiZcbiAgICAgICAgZXNjYXBlQ291bnQgJSAyID09PSAwXG4gICAgICApIHtcbiAgICAgICAgY3VycmVudFF1b3RlID0gY3VycmVudFF1b3RlID09PSBudWxsID8gY2hhciA6IG51bGw7XG4gICAgICB9IGVsc2UgaWYgKGN1cnJlbnRRdW90ZSA9PT0gbnVsbCkge1xuICAgICAgICB5aWVsZCBpO1xuICAgICAgfVxuICAgICAgZXNjYXBlQ291bnQgPSBjaGFyID09PSAnXFxcXCcgPyBlc2NhcGVDb3VudCArIDEgOiAwO1xuICAgIH1cbiAgfVxufVxuXG4vKiogRGVzY3JpYmVzIGEgc3RhdGVmdWwgY29udGV4dCBhbiBleHByZXNzaW9uIHBhcnNlciBpcyBpbi4gKi9cbmVudW0gUGFyc2VDb250ZXh0RmxhZ3Mge1xuICBOb25lID0gMCxcbiAgLyoqXG4gICAqIEEgV3JpdGFibGUgY29udGV4dCBpcyBvbmUgaW4gd2hpY2ggYSB2YWx1ZSBtYXkgYmUgd3JpdHRlbiB0byBhbiBsdmFsdWUuXG4gICAqIEZvciBleGFtcGxlLCBhZnRlciB3ZSBzZWUgYSBwcm9wZXJ0eSBhY2Nlc3MsIHdlIG1heSBleHBlY3QgYSB3cml0ZSB0byB0aGVcbiAgICogcHJvcGVydHkgdmlhIHRoZSBcIj1cIiBvcGVyYXRvci5cbiAgICogICBwcm9wXG4gICAqICAgICAgICBeIHBvc3NpYmxlIFwiPVwiIGFmdGVyXG4gICAqL1xuICBXcml0YWJsZSA9IDEsXG59XG5cbmNsYXNzIF9QYXJzZUFTVCB7XG4gIHByaXZhdGUgcnBhcmVuc0V4cGVjdGVkID0gMDtcbiAgcHJpdmF0ZSByYnJhY2tldHNFeHBlY3RlZCA9IDA7XG4gIHByaXZhdGUgcmJyYWNlc0V4cGVjdGVkID0gMDtcbiAgcHJpdmF0ZSBjb250ZXh0ID0gUGFyc2VDb250ZXh0RmxhZ3MuTm9uZTtcblxuICAvLyBDYWNoZSBvZiBleHByZXNzaW9uIHN0YXJ0IGFuZCBpbnB1dCBpbmRlY2VzIHRvIHRoZSBhYnNvbHV0ZSBzb3VyY2Ugc3BhbiB0aGV5IG1hcCB0bywgdXNlZCB0b1xuICAvLyBwcmV2ZW50IGNyZWF0aW5nIHN1cGVyZmx1b3VzIHNvdXJjZSBzcGFucyBpbiBgc291cmNlU3BhbmAuXG4gIC8vIEEgc2VyaWFsIG9mIHRoZSBleHByZXNzaW9uIHN0YXJ0IGFuZCBpbnB1dCBpbmRleCBpcyB1c2VkIGZvciBtYXBwaW5nIGJlY2F1c2UgYm90aCBhcmUgc3RhdGVmdWxcbiAgLy8gYW5kIG1heSBjaGFuZ2UgZm9yIHN1YnNlcXVlbnQgZXhwcmVzc2lvbnMgdmlzaXRlZCBieSB0aGUgcGFyc2VyLlxuICBwcml2YXRlIHNvdXJjZVNwYW5DYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBBYnNvbHV0ZVNvdXJjZVNwYW4+KCk7XG5cbiAgcHJpdmF0ZSBpbmRleDogbnVtYmVyID0gMDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIGlucHV0OiBzdHJpbmcsXG4gICAgcHJpdmF0ZSBsb2NhdGlvbjogc3RyaW5nLFxuICAgIHByaXZhdGUgYWJzb2x1dGVPZmZzZXQ6IG51bWJlcixcbiAgICBwcml2YXRlIHRva2VuczogVG9rZW5bXSxcbiAgICBwcml2YXRlIHBhcnNlRmxhZ3M6IFBhcnNlRmxhZ3MsXG4gICAgcHJpdmF0ZSBlcnJvcnM6IFBhcnNlckVycm9yW10sXG4gICAgcHJpdmF0ZSBvZmZzZXQ6IG51bWJlcixcbiAgKSB7fVxuXG4gIHByaXZhdGUgcGVlayhvZmZzZXQ6IG51bWJlcik6IFRva2VuIHtcbiAgICBjb25zdCBpID0gdGhpcy5pbmRleCArIG9mZnNldDtcbiAgICByZXR1cm4gaSA8IHRoaXMudG9rZW5zLmxlbmd0aCA/IHRoaXMudG9rZW5zW2ldIDogRU9GO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXQgbmV4dCgpOiBUb2tlbiB7XG4gICAgcmV0dXJuIHRoaXMucGVlaygwKTtcbiAgfVxuXG4gIC8qKiBXaGV0aGVyIGFsbCB0aGUgcGFyc2VyIGlucHV0IGhhcyBiZWVuIHByb2Nlc3NlZC4gKi9cbiAgcHJpdmF0ZSBnZXQgYXRFT0YoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMuaW5kZXggPj0gdGhpcy50b2tlbnMubGVuZ3RoO1xuICB9XG5cbiAgLyoqXG4gICAqIEluZGV4IG9mIHRoZSBuZXh0IHRva2VuIHRvIGJlIHByb2Nlc3NlZCwgb3IgdGhlIGVuZCBvZiB0aGUgbGFzdCB0b2tlbiBpZiBhbGwgaGF2ZSBiZWVuXG4gICAqIHByb2Nlc3NlZC5cbiAgICovXG4gIHByaXZhdGUgZ2V0IGlucHV0SW5kZXgoKTogbnVtYmVyIHtcbiAgICByZXR1cm4gdGhpcy5hdEVPRiA/IHRoaXMuY3VycmVudEVuZEluZGV4IDogdGhpcy5uZXh0LmluZGV4ICsgdGhpcy5vZmZzZXQ7XG4gIH1cblxuICAvKipcbiAgICogRW5kIGluZGV4IG9mIHRoZSBsYXN0IHByb2Nlc3NlZCB0b2tlbiwgb3IgdGhlIHN0YXJ0IG9mIHRoZSBmaXJzdCB0b2tlbiBpZiBub25lIGhhdmUgYmVlblxuICAgKiBwcm9jZXNzZWQuXG4gICAqL1xuICBwcml2YXRlIGdldCBjdXJyZW50RW5kSW5kZXgoKTogbnVtYmVyIHtcbiAgICBpZiAodGhpcy5pbmRleCA+IDApIHtcbiAgICAgIGNvbnN0IGN1clRva2VuID0gdGhpcy5wZWVrKC0xKTtcbiAgICAgIHJldHVybiBjdXJUb2tlbi5lbmQgKyB0aGlzLm9mZnNldDtcbiAgICB9XG4gICAgLy8gTm8gdG9rZW5zIGhhdmUgYmVlbiBwcm9jZXNzZWQgeWV0OyByZXR1cm4gdGhlIG5leHQgdG9rZW4ncyBzdGFydCBvciB0aGUgbGVuZ3RoIG9mIHRoZSBpbnB1dFxuICAgIC8vIGlmIHRoZXJlIGlzIG5vIHRva2VuLlxuICAgIGlmICh0aGlzLnRva2Vucy5sZW5ndGggPT09IDApIHtcbiAgICAgIHJldHVybiB0aGlzLmlucHV0Lmxlbmd0aCArIHRoaXMub2Zmc2V0O1xuICAgIH1cbiAgICByZXR1cm4gdGhpcy5uZXh0LmluZGV4ICsgdGhpcy5vZmZzZXQ7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgYWJzb2x1dGUgb2Zmc2V0IG9mIHRoZSBzdGFydCBvZiB0aGUgY3VycmVudCB0b2tlbi5cbiAgICovXG4gIHByaXZhdGUgZ2V0IGN1cnJlbnRBYnNvbHV0ZU9mZnNldCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLmFic29sdXRlT2Zmc2V0ICsgdGhpcy5pbnB1dEluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIGEgYFBhcnNlU3BhbmAgZnJvbSBgc3RhcnRgIHRvIHRoZSBjdXJyZW50IHBvc2l0aW9uIChvciB0byBgYXJ0aWZpY2lhbEVuZEluZGV4YCBpZlxuICAgKiBwcm92aWRlZCkuXG4gICAqXG4gICAqIEBwYXJhbSBzdGFydCBQb3NpdGlvbiBmcm9tIHdoaWNoIHRoZSBgUGFyc2VTcGFuYCB3aWxsIHN0YXJ0LlxuICAgKiBAcGFyYW0gYXJ0aWZpY2lhbEVuZEluZGV4IE9wdGlvbmFsIGVuZGluZyBpbmRleCB0byBiZSB1c2VkIGlmIHByb3ZpZGVkIChhbmQgaWYgZ3JlYXRlciB0aGFuIHRoZVxuICAgKiAgICAgbmF0dXJhbCBlbmRpbmcgaW5kZXgpXG4gICAqL1xuICBwcml2YXRlIHNwYW4oc3RhcnQ6IG51bWJlciwgYXJ0aWZpY2lhbEVuZEluZGV4PzogbnVtYmVyKTogUGFyc2VTcGFuIHtcbiAgICBsZXQgZW5kSW5kZXggPSB0aGlzLmN1cnJlbnRFbmRJbmRleDtcbiAgICBpZiAoYXJ0aWZpY2lhbEVuZEluZGV4ICE9PSB1bmRlZmluZWQgJiYgYXJ0aWZpY2lhbEVuZEluZGV4ID4gdGhpcy5jdXJyZW50RW5kSW5kZXgpIHtcbiAgICAgIGVuZEluZGV4ID0gYXJ0aWZpY2lhbEVuZEluZGV4O1xuICAgIH1cblxuICAgIC8vIEluIHNvbWUgdW51c3VhbCBwYXJzaW5nIHNjZW5hcmlvcyAobGlrZSB3aGVuIGNlcnRhaW4gdG9rZW5zIGFyZSBtaXNzaW5nIGFuZCBhbiBgRW1wdHlFeHByYCBpc1xuICAgIC8vIGJlaW5nIGNyZWF0ZWQpLCB0aGUgY3VycmVudCB0b2tlbiBtYXkgYWxyZWFkeSBiZSBhZHZhbmNlZCBiZXlvbmQgdGhlIGBjdXJyZW50RW5kSW5kZXhgLiBUaGlzXG4gICAgLy8gYXBwZWFycyB0byBiZSBhIGRlZXAtc2VhdGVkIHBhcnNlciBidWcuXG4gICAgLy9cbiAgICAvLyBBcyBhIHdvcmthcm91bmQgZm9yIG5vdywgc3dhcCB0aGUgc3RhcnQgYW5kIGVuZCBpbmRpY2VzIHRvIGVuc3VyZSBhIHZhbGlkIGBQYXJzZVNwYW5gLlxuICAgIC8vIFRPRE8oYWx4aHViKTogZml4IHRoZSBidWcgdXBzdHJlYW0gaW4gdGhlIHBhcnNlciBzdGF0ZSwgYW5kIHJlbW92ZSB0aGlzIHdvcmthcm91bmQuXG4gICAgaWYgKHN0YXJ0ID4gZW5kSW5kZXgpIHtcbiAgICAgIGNvbnN0IHRtcCA9IGVuZEluZGV4O1xuICAgICAgZW5kSW5kZXggPSBzdGFydDtcbiAgICAgIHN0YXJ0ID0gdG1wO1xuICAgIH1cblxuICAgIHJldHVybiBuZXcgUGFyc2VTcGFuKHN0YXJ0LCBlbmRJbmRleCk7XG4gIH1cblxuICBwcml2YXRlIHNvdXJjZVNwYW4oc3RhcnQ6IG51bWJlciwgYXJ0aWZpY2lhbEVuZEluZGV4PzogbnVtYmVyKTogQWJzb2x1dGVTb3VyY2VTcGFuIHtcbiAgICBjb25zdCBzZXJpYWwgPSBgJHtzdGFydH1AJHt0aGlzLmlucHV0SW5kZXh9OiR7YXJ0aWZpY2lhbEVuZEluZGV4fWA7XG4gICAgaWYgKCF0aGlzLnNvdXJjZVNwYW5DYWNoZS5oYXMoc2VyaWFsKSkge1xuICAgICAgdGhpcy5zb3VyY2VTcGFuQ2FjaGUuc2V0KFxuICAgICAgICBzZXJpYWwsXG4gICAgICAgIHRoaXMuc3BhbihzdGFydCwgYXJ0aWZpY2lhbEVuZEluZGV4KS50b0Fic29sdXRlKHRoaXMuYWJzb2x1dGVPZmZzZXQpLFxuICAgICAgKTtcbiAgICB9XG4gICAgcmV0dXJuIHRoaXMuc291cmNlU3BhbkNhY2hlLmdldChzZXJpYWwpITtcbiAgfVxuXG4gIHByaXZhdGUgYWR2YW5jZSgpIHtcbiAgICB0aGlzLmluZGV4Kys7XG4gIH1cblxuICAvKipcbiAgICogRXhlY3V0ZXMgYSBjYWxsYmFjayBpbiB0aGUgcHJvdmlkZWQgY29udGV4dC5cbiAgICovXG4gIHByaXZhdGUgd2l0aENvbnRleHQ8VD4oY29udGV4dDogUGFyc2VDb250ZXh0RmxhZ3MsIGNiOiAoKSA9PiBUKTogVCB7XG4gICAgdGhpcy5jb250ZXh0IHw9IGNvbnRleHQ7XG4gICAgY29uc3QgcmV0ID0gY2IoKTtcbiAgICB0aGlzLmNvbnRleHQgXj0gY29udGV4dDtcbiAgICByZXR1cm4gcmV0O1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY29kZTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMubmV4dC5pc0NoYXJhY3Rlcihjb2RlKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgcGVla0tleXdvcmRMZXQoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubmV4dC5pc0tleXdvcmRMZXQoKTtcbiAgfVxuXG4gIHByaXZhdGUgcGVla0tleXdvcmRBcygpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uZXh0LmlzS2V5d29yZEFzKCk7XG4gIH1cblxuICAvKipcbiAgICogQ29uc3VtZXMgYW4gZXhwZWN0ZWQgY2hhcmFjdGVyLCBvdGhlcndpc2UgZW1pdHMgYW4gZXJyb3IgYWJvdXQgdGhlIG1pc3NpbmcgZXhwZWN0ZWQgY2hhcmFjdGVyXG4gICAqIGFuZCBza2lwcyBvdmVyIHRoZSB0b2tlbiBzdHJlYW0gdW50aWwgcmVhY2hpbmcgYSByZWNvdmVyYWJsZSBwb2ludC5cbiAgICpcbiAgICogU2VlIGB0aGlzLmVycm9yYCBhbmQgYHRoaXMuc2tpcGAgZm9yIG1vcmUgZGV0YWlscy5cbiAgICovXG4gIHByaXZhdGUgZXhwZWN0Q2hhcmFjdGVyKGNvZGU6IG51bWJlcikge1xuICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3Rlcihjb2RlKSkgcmV0dXJuO1xuICAgIHRoaXMuZXJyb3IoYE1pc3NpbmcgZXhwZWN0ZWQgJHtTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpfWApO1xuICB9XG5cbiAgcHJpdmF0ZSBjb25zdW1lT3B0aW9uYWxPcGVyYXRvcihvcDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgaWYgKHRoaXMubmV4dC5pc09wZXJhdG9yKG9wKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgZXhwZWN0T3BlcmF0b3Iob3BlcmF0b3I6IHN0cmluZykge1xuICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKG9wZXJhdG9yKSkgcmV0dXJuO1xuICAgIHRoaXMuZXJyb3IoYE1pc3NpbmcgZXhwZWN0ZWQgb3BlcmF0b3IgJHtvcGVyYXRvcn1gKTtcbiAgfVxuXG4gIHByaXZhdGUgcHJldHR5UHJpbnRUb2tlbih0b2s6IFRva2VuKTogc3RyaW5nIHtcbiAgICByZXR1cm4gdG9rID09PSBFT0YgPyAnZW5kIG9mIGlucHV0JyA6IGB0b2tlbiAke3Rva31gO1xuICB9XG5cbiAgcHJpdmF0ZSBleHBlY3RJZGVudGlmaWVyT3JLZXl3b3JkKCk6IHN0cmluZyB8IG51bGwge1xuICAgIGNvbnN0IG4gPSB0aGlzLm5leHQ7XG4gICAgaWYgKCFuLmlzSWRlbnRpZmllcigpICYmICFuLmlzS2V5d29yZCgpKSB7XG4gICAgICBpZiAobi5pc1ByaXZhdGVJZGVudGlmaWVyKCkpIHtcbiAgICAgICAgdGhpcy5fcmVwb3J0RXJyb3JGb3JQcml2YXRlSWRlbnRpZmllcihuLCAnZXhwZWN0ZWQgaWRlbnRpZmllciBvciBrZXl3b3JkJyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmVycm9yKGBVbmV4cGVjdGVkICR7dGhpcy5wcmV0dHlQcmludFRva2VuKG4pfSwgZXhwZWN0ZWQgaWRlbnRpZmllciBvciBrZXl3b3JkYCk7XG4gICAgICB9XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgcmV0dXJuIG4udG9TdHJpbmcoKSBhcyBzdHJpbmc7XG4gIH1cblxuICBwcml2YXRlIGV4cGVjdElkZW50aWZpZXJPcktleXdvcmRPclN0cmluZygpOiBzdHJpbmcge1xuICAgIGNvbnN0IG4gPSB0aGlzLm5leHQ7XG4gICAgaWYgKCFuLmlzSWRlbnRpZmllcigpICYmICFuLmlzS2V5d29yZCgpICYmICFuLmlzU3RyaW5nKCkpIHtcbiAgICAgIGlmIChuLmlzUHJpdmF0ZUlkZW50aWZpZXIoKSkge1xuICAgICAgICB0aGlzLl9yZXBvcnRFcnJvckZvclByaXZhdGVJZGVudGlmaWVyKG4sICdleHBlY3RlZCBpZGVudGlmaWVyLCBrZXl3b3JkIG9yIHN0cmluZycpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5lcnJvcihcbiAgICAgICAgICBgVW5leHBlY3RlZCAke3RoaXMucHJldHR5UHJpbnRUb2tlbihuKX0sIGV4cGVjdGVkIGlkZW50aWZpZXIsIGtleXdvcmQsIG9yIHN0cmluZ2AsXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICByZXR1cm4gJyc7XG4gICAgfVxuICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgIHJldHVybiBuLnRvU3RyaW5nKCkgYXMgc3RyaW5nO1xuICB9XG5cbiAgcGFyc2VDaGFpbigpOiBBU1Qge1xuICAgIGNvbnN0IGV4cHJzOiBBU1RbXSA9IFtdO1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIHdoaWxlICh0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBleHByID0gdGhpcy5wYXJzZVBpcGUoKTtcbiAgICAgIGV4cHJzLnB1c2goZXhwcik7XG5cbiAgICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSkge1xuICAgICAgICBpZiAoISh0aGlzLnBhcnNlRmxhZ3MgJiBQYXJzZUZsYWdzLkFjdGlvbikpIHtcbiAgICAgICAgICB0aGlzLmVycm9yKCdCaW5kaW5nIGV4cHJlc3Npb24gY2Fubm90IGNvbnRhaW4gY2hhaW5lZCBleHByZXNzaW9uJyk7XG4gICAgICAgIH1cbiAgICAgICAgd2hpbGUgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRTRU1JQ09MT04pKSB7fSAvLyByZWFkIGFsbCBzZW1pY29sb25zXG4gICAgICB9IGVsc2UgaWYgKHRoaXMuaW5kZXggPCB0aGlzLnRva2Vucy5sZW5ndGgpIHtcbiAgICAgICAgY29uc3QgZXJyb3JJbmRleCA9IHRoaXMuaW5kZXg7XG4gICAgICAgIHRoaXMuZXJyb3IoYFVuZXhwZWN0ZWQgdG9rZW4gJyR7dGhpcy5uZXh0fSdgKTtcbiAgICAgICAgLy8gVGhlIGBlcnJvcmAgY2FsbCBhYm92ZSB3aWxsIHNraXAgYWhlYWQgdG8gdGhlIG5leHQgcmVjb3ZlcnkgcG9pbnQgaW4gYW4gYXR0ZW1wdCB0b1xuICAgICAgICAvLyByZWNvdmVyIHBhcnQgb2YgdGhlIGV4cHJlc3Npb24sIGJ1dCB0aGF0IG1pZ2h0IGJlIHRoZSB0b2tlbiB3ZSBzdGFydGVkIGZyb20gd2hpY2ggd2lsbFxuICAgICAgICAvLyBsZWFkIHRvIGFuIGluZmluaXRlIGxvb3AuIElmIHRoYXQncyB0aGUgY2FzZSwgYnJlYWsgdGhlIGxvb3AgYXNzdW1pbmcgdGhhdCB3ZSBjYW4ndFxuICAgICAgICAvLyBwYXJzZSBmdXJ0aGVyLlxuICAgICAgICBpZiAodGhpcy5pbmRleCA9PT0gZXJyb3JJbmRleCkge1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIGlmIChleHBycy5sZW5ndGggPT09IDApIHtcbiAgICAgIC8vIFdlIGhhdmUgbm8gZXhwcmVzc2lvbnMgc28gY3JlYXRlIGFuIGVtcHR5IGV4cHJlc3Npb24gdGhhdCBzcGFucyB0aGUgZW50aXJlIGlucHV0IGxlbmd0aFxuICAgICAgY29uc3QgYXJ0aWZpY2lhbFN0YXJ0ID0gdGhpcy5vZmZzZXQ7XG4gICAgICBjb25zdCBhcnRpZmljaWFsRW5kID0gdGhpcy5vZmZzZXQgKyB0aGlzLmlucHV0Lmxlbmd0aDtcbiAgICAgIHJldHVybiBuZXcgRW1wdHlFeHByKFxuICAgICAgICB0aGlzLnNwYW4oYXJ0aWZpY2lhbFN0YXJ0LCBhcnRpZmljaWFsRW5kKSxcbiAgICAgICAgdGhpcy5zb3VyY2VTcGFuKGFydGlmaWNpYWxTdGFydCwgYXJ0aWZpY2lhbEVuZCksXG4gICAgICApO1xuICAgIH1cbiAgICBpZiAoZXhwcnMubGVuZ3RoID09IDEpIHJldHVybiBleHByc1swXTtcbiAgICByZXR1cm4gbmV3IENoYWluKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIGV4cHJzKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VQaXBlKCk6IEFTVCB7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VFeHByZXNzaW9uKCk7XG4gICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJ3wnKSkge1xuICAgICAgaWYgKHRoaXMucGFyc2VGbGFncyAmIFBhcnNlRmxhZ3MuQWN0aW9uKSB7XG4gICAgICAgIHRoaXMuZXJyb3IoYENhbm5vdCBoYXZlIGEgcGlwZSBpbiBhbiBhY3Rpb24gZXhwcmVzc2lvbmApO1xuICAgICAgfVxuXG4gICAgICBkbyB7XG4gICAgICAgIGNvbnN0IG5hbWVTdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICAgICAgbGV0IG5hbWVJZCA9IHRoaXMuZXhwZWN0SWRlbnRpZmllck9yS2V5d29yZCgpO1xuICAgICAgICBsZXQgbmFtZVNwYW46IEFic29sdXRlU291cmNlU3BhbjtcbiAgICAgICAgbGV0IGZ1bGxTcGFuRW5kOiBudW1iZXIgfCB1bmRlZmluZWQgPSB1bmRlZmluZWQ7XG4gICAgICAgIGlmIChuYW1lSWQgIT09IG51bGwpIHtcbiAgICAgICAgICBuYW1lU3BhbiA9IHRoaXMuc291cmNlU3BhbihuYW1lU3RhcnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIC8vIE5vIHZhbGlkIGlkZW50aWZpZXIgd2FzIGZvdW5kLCBzbyB3ZSdsbCBhc3N1bWUgYW4gZW1wdHkgcGlwZSBuYW1lICgnJykuXG4gICAgICAgICAgbmFtZUlkID0gJyc7XG5cbiAgICAgICAgICAvLyBIb3dldmVyLCB0aGVyZSBtYXkgaGF2ZSBiZWVuIHdoaXRlc3BhY2UgcHJlc2VudCBiZXR3ZWVuIHRoZSBwaXBlIGNoYXJhY3RlciBhbmQgdGhlIG5leHRcbiAgICAgICAgICAvLyB0b2tlbiBpbiB0aGUgc2VxdWVuY2UgKG9yIHRoZSBlbmQgb2YgaW5wdXQpLiBXZSB3YW50IHRvIHRyYWNrIHRoaXMgd2hpdGVzcGFjZSBzbyB0aGF0XG4gICAgICAgICAgLy8gdGhlIGBCaW5kaW5nUGlwZWAgd2UgcHJvZHVjZSBjb3ZlcnMgbm90IGp1c3QgdGhlIHBpcGUgY2hhcmFjdGVyLCBidXQgYW55IHRyYWlsaW5nXG4gICAgICAgICAgLy8gd2hpdGVzcGFjZSBiZXlvbmQgaXQuIEFub3RoZXIgd2F5IG9mIHRoaW5raW5nIGFib3V0IHRoaXMgaXMgdGhhdCB0aGUgemVyby1sZW5ndGggbmFtZVxuICAgICAgICAgIC8vIGlzIGFzc3VtZWQgdG8gYmUgYXQgdGhlIGVuZCBvZiBhbnkgd2hpdGVzcGFjZSBiZXlvbmQgdGhlIHBpcGUgY2hhcmFjdGVyLlxuICAgICAgICAgIC8vXG4gICAgICAgICAgLy8gVGhlcmVmb3JlLCB3ZSBwdXNoIHRoZSBlbmQgb2YgdGhlIGBQYXJzZVNwYW5gIGZvciB0aGlzIHBpcGUgYWxsIHRoZSB3YXkgdXAgdG8gdGhlXG4gICAgICAgICAgLy8gYmVnaW5uaW5nIG9mIHRoZSBuZXh0IHRva2VuLCBvciB1bnRpbCB0aGUgZW5kIG9mIGlucHV0IGlmIHRoZSBuZXh0IHRva2VuIGlzIEVPRi5cbiAgICAgICAgICBmdWxsU3BhbkVuZCA9IHRoaXMubmV4dC5pbmRleCAhPT0gLTEgPyB0aGlzLm5leHQuaW5kZXggOiB0aGlzLmlucHV0Lmxlbmd0aCArIHRoaXMub2Zmc2V0O1xuXG4gICAgICAgICAgLy8gVGhlIGBuYW1lU3BhbmAgZm9yIGFuIGVtcHR5IHBpcGUgbmFtZSBpcyB6ZXJvLWxlbmd0aCBhdCB0aGUgZW5kIG9mIGFueSB3aGl0ZXNwYWNlXG4gICAgICAgICAgLy8gYmV5b25kIHRoZSBwaXBlIGNoYXJhY3Rlci5cbiAgICAgICAgICBuYW1lU3BhbiA9IG5ldyBQYXJzZVNwYW4oZnVsbFNwYW5FbmQsIGZ1bGxTcGFuRW5kKS50b0Fic29sdXRlKHRoaXMuYWJzb2x1dGVPZmZzZXQpO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgYXJnczogQVNUW10gPSBbXTtcbiAgICAgICAgd2hpbGUgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRDT0xPTikpIHtcbiAgICAgICAgICBhcmdzLnB1c2godGhpcy5wYXJzZUV4cHJlc3Npb24oKSk7XG5cbiAgICAgICAgICAvLyBJZiB0aGVyZSBhcmUgYWRkaXRpb25hbCBleHByZXNzaW9ucyBiZXlvbmQgdGhlIG5hbWUsIHRoZW4gdGhlIGFydGlmaWNpYWwgZW5kIGZvciB0aGVcbiAgICAgICAgICAvLyBuYW1lIGlzIG5vIGxvbmdlciByZWxldmFudC5cbiAgICAgICAgfVxuICAgICAgICByZXN1bHQgPSBuZXcgQmluZGluZ1BpcGUoXG4gICAgICAgICAgdGhpcy5zcGFuKHN0YXJ0KSxcbiAgICAgICAgICB0aGlzLnNvdXJjZVNwYW4oc3RhcnQsIGZ1bGxTcGFuRW5kKSxcbiAgICAgICAgICByZXN1bHQsXG4gICAgICAgICAgbmFtZUlkLFxuICAgICAgICAgIGFyZ3MsXG4gICAgICAgICAgbmFtZVNwYW4sXG4gICAgICAgICk7XG4gICAgICB9IHdoaWxlICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCd8JykpO1xuICAgIH1cblxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRXhwcmVzc2lvbigpOiBBU1Qge1xuICAgIHJldHVybiB0aGlzLnBhcnNlQ29uZGl0aW9uYWwoKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VDb25kaXRpb25hbCgpOiBBU1Qge1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGNvbnN0IHJlc3VsdCA9IHRoaXMucGFyc2VMb2dpY2FsT3IoKTtcblxuICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCc/JykpIHtcbiAgICAgIGNvbnN0IHllcyA9IHRoaXMucGFyc2VQaXBlKCk7XG4gICAgICBsZXQgbm86IEFTVDtcbiAgICAgIGlmICghdGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKSkge1xuICAgICAgICBjb25zdCBlbmQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgICAgIGNvbnN0IGV4cHJlc3Npb24gPSB0aGlzLmlucHV0LnN1YnN0cmluZyhzdGFydCwgZW5kKTtcbiAgICAgICAgdGhpcy5lcnJvcihgQ29uZGl0aW9uYWwgZXhwcmVzc2lvbiAke2V4cHJlc3Npb259IHJlcXVpcmVzIGFsbCAzIGV4cHJlc3Npb25zYCk7XG4gICAgICAgIG5vID0gbmV3IEVtcHR5RXhwcih0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIG5vID0gdGhpcy5wYXJzZVBpcGUoKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBuZXcgQ29uZGl0aW9uYWwodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgcmVzdWx0LCB5ZXMsIG5vKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTG9naWNhbE9yKCk6IEFTVCB7XG4gICAgLy8gJ3x8J1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlTG9naWNhbEFuZCgpO1xuICAgIHdoaWxlICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCd8fCcpKSB7XG4gICAgICBjb25zdCByaWdodCA9IHRoaXMucGFyc2VMb2dpY2FsQW5kKCk7XG4gICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksICd8fCcsIHJlc3VsdCwgcmlnaHQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUxvZ2ljYWxBbmQoKTogQVNUIHtcbiAgICAvLyAnJiYnXG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VOdWxsaXNoQ29hbGVzY2luZygpO1xuICAgIHdoaWxlICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCcmJicpKSB7XG4gICAgICBjb25zdCByaWdodCA9IHRoaXMucGFyc2VOdWxsaXNoQ29hbGVzY2luZygpO1xuICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCAnJiYnLCByZXN1bHQsIHJpZ2h0KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VOdWxsaXNoQ29hbGVzY2luZygpOiBBU1Qge1xuICAgIC8vICc/PydcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZUVxdWFsaXR5KCk7XG4gICAgd2hpbGUgKHRoaXMuY29uc3VtZU9wdGlvbmFsT3BlcmF0b3IoJz8/JykpIHtcbiAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZUVxdWFsaXR5KCk7XG4gICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksICc/PycsIHJlc3VsdCwgcmlnaHQpO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUVxdWFsaXR5KCk6IEFTVCB7XG4gICAgLy8gJz09JywnIT0nLCc9PT0nLCchPT0nXG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VSZWxhdGlvbmFsKCk7XG4gICAgd2hpbGUgKHRoaXMubmV4dC50eXBlID09IFRva2VuVHlwZS5PcGVyYXRvcikge1xuICAgICAgY29uc3Qgb3BlcmF0b3IgPSB0aGlzLm5leHQuc3RyVmFsdWU7XG4gICAgICBzd2l0Y2ggKG9wZXJhdG9yKSB7XG4gICAgICAgIGNhc2UgJz09JzpcbiAgICAgICAgY2FzZSAnPT09JzpcbiAgICAgICAgY2FzZSAnIT0nOlxuICAgICAgICBjYXNlICchPT0nOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIGNvbnN0IHJpZ2h0ID0gdGhpcy5wYXJzZVJlbGF0aW9uYWwoKTtcbiAgICAgICAgICByZXN1bHQgPSBuZXcgQmluYXJ5KHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIG9wZXJhdG9yLCByZXN1bHQsIHJpZ2h0KTtcbiAgICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVJlbGF0aW9uYWwoKTogQVNUIHtcbiAgICAvLyAnPCcsICc+JywgJzw9JywgJz49J1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlQWRkaXRpdmUoKTtcbiAgICB3aGlsZSAodGhpcy5uZXh0LnR5cGUgPT0gVG9rZW5UeXBlLk9wZXJhdG9yKSB7XG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMubmV4dC5zdHJWYWx1ZTtcbiAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSAnPCc6XG4gICAgICAgIGNhc2UgJz4nOlxuICAgICAgICBjYXNlICc8PSc6XG4gICAgICAgIGNhc2UgJz49JzpcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICBjb25zdCByaWdodCA9IHRoaXMucGFyc2VBZGRpdGl2ZSgpO1xuICAgICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgb3BlcmF0b3IsIHJlc3VsdCwgcmlnaHQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQWRkaXRpdmUoKTogQVNUIHtcbiAgICAvLyAnKycsICctJ1xuICAgIGNvbnN0IHN0YXJ0ID0gdGhpcy5pbnB1dEluZGV4O1xuICAgIGxldCByZXN1bHQgPSB0aGlzLnBhcnNlTXVsdGlwbGljYXRpdmUoKTtcbiAgICB3aGlsZSAodGhpcy5uZXh0LnR5cGUgPT0gVG9rZW5UeXBlLk9wZXJhdG9yKSB7XG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMubmV4dC5zdHJWYWx1ZTtcbiAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSAnKyc6XG4gICAgICAgIGNhc2UgJy0nOlxuICAgICAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgICAgIGxldCByaWdodCA9IHRoaXMucGFyc2VNdWx0aXBsaWNhdGl2ZSgpO1xuICAgICAgICAgIHJlc3VsdCA9IG5ldyBCaW5hcnkodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgb3BlcmF0b3IsIHJlc3VsdCwgcmlnaHQpO1xuICAgICAgICAgIGNvbnRpbnVlO1xuICAgICAgfVxuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlTXVsdGlwbGljYXRpdmUoKTogQVNUIHtcbiAgICAvLyAnKicsICclJywgJy8nXG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgbGV0IHJlc3VsdCA9IHRoaXMucGFyc2VQcmVmaXgoKTtcbiAgICB3aGlsZSAodGhpcy5uZXh0LnR5cGUgPT0gVG9rZW5UeXBlLk9wZXJhdG9yKSB7XG4gICAgICBjb25zdCBvcGVyYXRvciA9IHRoaXMubmV4dC5zdHJWYWx1ZTtcbiAgICAgIHN3aXRjaCAob3BlcmF0b3IpIHtcbiAgICAgICAgY2FzZSAnKic6XG4gICAgICAgIGNhc2UgJyUnOlxuICAgICAgICBjYXNlICcvJzpcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICBsZXQgcmlnaHQgPSB0aGlzLnBhcnNlUHJlZml4KCk7XG4gICAgICAgICAgcmVzdWx0ID0gbmV3IEJpbmFyeSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBvcGVyYXRvciwgcmVzdWx0LCByaWdodCk7XG4gICAgICAgICAgY29udGludWU7XG4gICAgICB9XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VQcmVmaXgoKTogQVNUIHtcbiAgICBpZiAodGhpcy5uZXh0LnR5cGUgPT0gVG9rZW5UeXBlLk9wZXJhdG9yKSB7XG4gICAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICAgIGNvbnN0IG9wZXJhdG9yID0gdGhpcy5uZXh0LnN0clZhbHVlO1xuICAgICAgbGV0IHJlc3VsdDogQVNUO1xuICAgICAgc3dpdGNoIChvcGVyYXRvcikge1xuICAgICAgICBjYXNlICcrJzpcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICByZXN1bHQgPSB0aGlzLnBhcnNlUHJlZml4KCk7XG4gICAgICAgICAgcmV0dXJuIFVuYXJ5LmNyZWF0ZVBsdXModGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgcmVzdWx0KTtcbiAgICAgICAgY2FzZSAnLSc6XG4gICAgICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICAgICAgcmVzdWx0ID0gdGhpcy5wYXJzZVByZWZpeCgpO1xuICAgICAgICAgIHJldHVybiBVbmFyeS5jcmVhdGVNaW51cyh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCByZXN1bHQpO1xuICAgICAgICBjYXNlICchJzpcbiAgICAgICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgICAgICByZXN1bHQgPSB0aGlzLnBhcnNlUHJlZml4KCk7XG4gICAgICAgICAgcmV0dXJuIG5ldyBQcmVmaXhOb3QodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgcmVzdWx0KTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHRoaXMucGFyc2VDYWxsQ2hhaW4oKTtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VDYWxsQ2hhaW4oKTogQVNUIHtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBsZXQgcmVzdWx0ID0gdGhpcy5wYXJzZVByaW1hcnkoKTtcbiAgICB3aGlsZSAodHJ1ZSkge1xuICAgICAgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRQRVJJT0QpKSB7XG4gICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VBY2Nlc3NNZW1iZXIocmVzdWx0LCBzdGFydCwgZmFsc2UpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCc/LicpKSB7XG4gICAgICAgIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kTFBBUkVOKSkge1xuICAgICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VDYWxsKHJlc3VsdCwgc3RhcnQsIHRydWUpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHJlc3VsdCA9IHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRMQlJBQ0tFVClcbiAgICAgICAgICAgID8gdGhpcy5wYXJzZUtleWVkUmVhZE9yV3JpdGUocmVzdWx0LCBzdGFydCwgdHJ1ZSlcbiAgICAgICAgICAgIDogdGhpcy5wYXJzZUFjY2Vzc01lbWJlcihyZXN1bHQsIHN0YXJ0LCB0cnVlKTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kTEJSQUNLRVQpKSB7XG4gICAgICAgIHJlc3VsdCA9IHRoaXMucGFyc2VLZXllZFJlYWRPcldyaXRlKHJlc3VsdCwgc3RhcnQsIGZhbHNlKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJExQQVJFTikpIHtcbiAgICAgICAgcmVzdWx0ID0gdGhpcy5wYXJzZUNhbGwocmVzdWx0LCBzdGFydCwgZmFsc2UpO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCchJykpIHtcbiAgICAgICAgcmVzdWx0ID0gbmV3IE5vbk51bGxBc3NlcnQodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgcmVzdWx0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHJldHVybiByZXN1bHQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZVByaW1hcnkoKTogQVNUIHtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJExQQVJFTikpIHtcbiAgICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkKys7XG4gICAgICBjb25zdCByZXN1bHQgPSB0aGlzLnBhcnNlUGlwZSgpO1xuICAgICAgdGhpcy5ycGFyZW5zRXhwZWN0ZWQtLTtcbiAgICAgIHRoaXMuZXhwZWN0Q2hhcmFjdGVyKGNoYXJzLiRSUEFSRU4pO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0tleXdvcmROdWxsKCkpIHtcbiAgICAgIHRoaXMuYWR2YW5jZSgpO1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsUHJpbWl0aXZlKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCksIG51bGwpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5uZXh0LmlzS2V5d29yZFVuZGVmaW5lZCgpKSB7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiBuZXcgTGl0ZXJhbFByaW1pdGl2ZSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCB2b2lkIDApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5uZXh0LmlzS2V5d29yZFRydWUoKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbmV3IExpdGVyYWxQcmltaXRpdmUodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgdHJ1ZSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNLZXl3b3JkRmFsc2UoKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbmV3IExpdGVyYWxQcmltaXRpdmUodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgZmFsc2UpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5uZXh0LmlzS2V5d29yZFRoaXMoKSkge1xuICAgICAgdGhpcy5hZHZhbmNlKCk7XG4gICAgICByZXR1cm4gbmV3IFRoaXNSZWNlaXZlcih0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRMQlJBQ0tFVCkpIHtcbiAgICAgIHRoaXMucmJyYWNrZXRzRXhwZWN0ZWQrKztcbiAgICAgIGNvbnN0IGVsZW1lbnRzID0gdGhpcy5wYXJzZUV4cHJlc3Npb25MaXN0KGNoYXJzLiRSQlJBQ0tFVCk7XG4gICAgICB0aGlzLnJicmFja2V0c0V4cGVjdGVkLS07XG4gICAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kUkJSQUNLRVQpO1xuICAgICAgcmV0dXJuIG5ldyBMaXRlcmFsQXJyYXkodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgZWxlbWVudHMpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5uZXh0LmlzQ2hhcmFjdGVyKGNoYXJzLiRMQlJBQ0UpKSB7XG4gICAgICByZXR1cm4gdGhpcy5wYXJzZUxpdGVyYWxNYXAoKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubmV4dC5pc0lkZW50aWZpZXIoKSkge1xuICAgICAgcmV0dXJuIHRoaXMucGFyc2VBY2Nlc3NNZW1iZXIoXG4gICAgICAgIG5ldyBJbXBsaWNpdFJlY2VpdmVyKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpLFxuICAgICAgICBzdGFydCxcbiAgICAgICAgZmFsc2UsXG4gICAgICApO1xuICAgIH0gZWxzZSBpZiAodGhpcy5uZXh0LmlzTnVtYmVyKCkpIHtcbiAgICAgIGNvbnN0IHZhbHVlID0gdGhpcy5uZXh0LnRvTnVtYmVyKCk7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiBuZXcgTGl0ZXJhbFByaW1pdGl2ZSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCB2YWx1ZSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLm5leHQuaXNTdHJpbmcoKSkge1xuICAgICAgY29uc3QgbGl0ZXJhbFZhbHVlID0gdGhpcy5uZXh0LnRvU3RyaW5nKCk7XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIHJldHVybiBuZXcgTGl0ZXJhbFByaW1pdGl2ZSh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBsaXRlcmFsVmFsdWUpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5uZXh0LmlzUHJpdmF0ZUlkZW50aWZpZXIoKSkge1xuICAgICAgdGhpcy5fcmVwb3J0RXJyb3JGb3JQcml2YXRlSWRlbnRpZmllcih0aGlzLm5leHQsIG51bGwpO1xuICAgICAgcmV0dXJuIG5ldyBFbXB0eUV4cHIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmluZGV4ID49IHRoaXMudG9rZW5zLmxlbmd0aCkge1xuICAgICAgdGhpcy5lcnJvcihgVW5leHBlY3RlZCBlbmQgb2YgZXhwcmVzc2lvbjogJHt0aGlzLmlucHV0fWApO1xuICAgICAgcmV0dXJuIG5ldyBFbXB0eUV4cHIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZXJyb3IoYFVuZXhwZWN0ZWQgdG9rZW4gJHt0aGlzLm5leHR9YCk7XG4gICAgICByZXR1cm4gbmV3IEVtcHR5RXhwcih0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHBhcnNlRXhwcmVzc2lvbkxpc3QodGVybWluYXRvcjogbnVtYmVyKTogQVNUW10ge1xuICAgIGNvbnN0IHJlc3VsdDogQVNUW10gPSBbXTtcblxuICAgIGRvIHtcbiAgICAgIGlmICghdGhpcy5uZXh0LmlzQ2hhcmFjdGVyKHRlcm1pbmF0b3IpKSB7XG4gICAgICAgIHJlc3VsdC5wdXNoKHRoaXMucGFyc2VQaXBlKCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfSB3aGlsZSAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTU1BKSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHByaXZhdGUgcGFyc2VMaXRlcmFsTWFwKCk6IExpdGVyYWxNYXAge1xuICAgIGNvbnN0IGtleXM6IExpdGVyYWxNYXBLZXlbXSA9IFtdO1xuICAgIGNvbnN0IHZhbHVlczogQVNUW10gPSBbXTtcbiAgICBjb25zdCBzdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICB0aGlzLmV4cGVjdENoYXJhY3RlcihjaGFycy4kTEJSQUNFKTtcbiAgICBpZiAoIXRoaXMuY29uc3VtZU9wdGlvbmFsQ2hhcmFjdGVyKGNoYXJzLiRSQlJBQ0UpKSB7XG4gICAgICB0aGlzLnJicmFjZXNFeHBlY3RlZCsrO1xuICAgICAgZG8ge1xuICAgICAgICBjb25zdCBrZXlTdGFydCA9IHRoaXMuaW5wdXRJbmRleDtcbiAgICAgICAgY29uc3QgcXVvdGVkID0gdGhpcy5uZXh0LmlzU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGtleSA9IHRoaXMuZXhwZWN0SWRlbnRpZmllck9yS2V5d29yZE9yU3RyaW5nKCk7XG4gICAgICAgIGNvbnN0IGxpdGVyYWxNYXBLZXk6IExpdGVyYWxNYXBLZXkgPSB7a2V5LCBxdW90ZWR9O1xuICAgICAgICBrZXlzLnB1c2gobGl0ZXJhbE1hcEtleSk7XG5cbiAgICAgICAgLy8gUHJvcGVydGllcyB3aXRoIHF1b3RlZCBrZXlzIGNhbid0IHVzZSB0aGUgc2hvcnRoYW5kIHN5bnRheC5cbiAgICAgICAgaWYgKHF1b3RlZCkge1xuICAgICAgICAgIHRoaXMuZXhwZWN0Q2hhcmFjdGVyKGNoYXJzLiRDT0xPTik7XG4gICAgICAgICAgdmFsdWVzLnB1c2godGhpcy5wYXJzZVBpcGUoKSk7XG4gICAgICAgIH0gZWxzZSBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKSkge1xuICAgICAgICAgIHZhbHVlcy5wdXNoKHRoaXMucGFyc2VQaXBlKCkpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGxpdGVyYWxNYXBLZXkuaXNTaG9ydGhhbmRJbml0aWFsaXplZCA9IHRydWU7XG5cbiAgICAgICAgICBjb25zdCBzcGFuID0gdGhpcy5zcGFuKGtleVN0YXJ0KTtcbiAgICAgICAgICBjb25zdCBzb3VyY2VTcGFuID0gdGhpcy5zb3VyY2VTcGFuKGtleVN0YXJ0KTtcbiAgICAgICAgICB2YWx1ZXMucHVzaChcbiAgICAgICAgICAgIG5ldyBQcm9wZXJ0eVJlYWQoXG4gICAgICAgICAgICAgIHNwYW4sXG4gICAgICAgICAgICAgIHNvdXJjZVNwYW4sXG4gICAgICAgICAgICAgIHNvdXJjZVNwYW4sXG4gICAgICAgICAgICAgIG5ldyBJbXBsaWNpdFJlY2VpdmVyKHNwYW4sIHNvdXJjZVNwYW4pLFxuICAgICAgICAgICAgICBrZXksXG4gICAgICAgICAgICApLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH0gd2hpbGUgKFxuICAgICAgICB0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpICYmXG4gICAgICAgICF0aGlzLm5leHQuaXNDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDRSlcbiAgICAgICk7XG4gICAgICB0aGlzLnJicmFjZXNFeHBlY3RlZC0tO1xuICAgICAgdGhpcy5leHBlY3RDaGFyYWN0ZXIoY2hhcnMuJFJCUkFDRSk7XG4gICAgfVxuICAgIHJldHVybiBuZXcgTGl0ZXJhbE1hcCh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCBrZXlzLCB2YWx1ZXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUFjY2Vzc01lbWJlcihyZWFkUmVjZWl2ZXI6IEFTVCwgc3RhcnQ6IG51bWJlciwgaXNTYWZlOiBib29sZWFuKTogQVNUIHtcbiAgICBjb25zdCBuYW1lU3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgY29uc3QgaWQgPSB0aGlzLndpdGhDb250ZXh0KFBhcnNlQ29udGV4dEZsYWdzLldyaXRhYmxlLCAoKSA9PiB7XG4gICAgICBjb25zdCBpZCA9IHRoaXMuZXhwZWN0SWRlbnRpZmllck9yS2V5d29yZCgpID8/ICcnO1xuICAgICAgaWYgKGlkLmxlbmd0aCA9PT0gMCkge1xuICAgICAgICB0aGlzLmVycm9yKGBFeHBlY3RlZCBpZGVudGlmaWVyIGZvciBwcm9wZXJ0eSBhY2Nlc3NgLCByZWFkUmVjZWl2ZXIuc3Bhbi5lbmQpO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGlkO1xuICAgIH0pO1xuICAgIGNvbnN0IG5hbWVTcGFuID0gdGhpcy5zb3VyY2VTcGFuKG5hbWVTdGFydCk7XG4gICAgbGV0IHJlY2VpdmVyOiBBU1Q7XG5cbiAgICBpZiAoaXNTYWZlKSB7XG4gICAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignPScpKSB7XG4gICAgICAgIHRoaXMuZXJyb3IoXCJUaGUgJz8uJyBvcGVyYXRvciBjYW5ub3QgYmUgdXNlZCBpbiB0aGUgYXNzaWdubWVudFwiKTtcbiAgICAgICAgcmVjZWl2ZXIgPSBuZXcgRW1wdHlFeHByKHRoaXMuc3BhbihzdGFydCksIHRoaXMuc291cmNlU3BhbihzdGFydCkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVjZWl2ZXIgPSBuZXcgU2FmZVByb3BlcnR5UmVhZChcbiAgICAgICAgICB0aGlzLnNwYW4oc3RhcnQpLFxuICAgICAgICAgIHRoaXMuc291cmNlU3BhbihzdGFydCksXG4gICAgICAgICAgbmFtZVNwYW4sXG4gICAgICAgICAgcmVhZFJlY2VpdmVyLFxuICAgICAgICAgIGlkLFxuICAgICAgICApO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignPScpKSB7XG4gICAgICAgIGlmICghKHRoaXMucGFyc2VGbGFncyAmIFBhcnNlRmxhZ3MuQWN0aW9uKSkge1xuICAgICAgICAgIHRoaXMuZXJyb3IoJ0JpbmRpbmdzIGNhbm5vdCBjb250YWluIGFzc2lnbm1lbnRzJyk7XG4gICAgICAgICAgcmV0dXJuIG5ldyBFbXB0eUV4cHIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCB2YWx1ZSA9IHRoaXMucGFyc2VDb25kaXRpb25hbCgpO1xuICAgICAgICByZWNlaXZlciA9IG5ldyBQcm9wZXJ0eVdyaXRlKFxuICAgICAgICAgIHRoaXMuc3BhbihzdGFydCksXG4gICAgICAgICAgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSxcbiAgICAgICAgICBuYW1lU3BhbixcbiAgICAgICAgICByZWFkUmVjZWl2ZXIsXG4gICAgICAgICAgaWQsXG4gICAgICAgICAgdmFsdWUsXG4gICAgICAgICk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZWNlaXZlciA9IG5ldyBQcm9wZXJ0eVJlYWQoXG4gICAgICAgICAgdGhpcy5zcGFuKHN0YXJ0KSxcbiAgICAgICAgICB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLFxuICAgICAgICAgIG5hbWVTcGFuLFxuICAgICAgICAgIHJlYWRSZWNlaXZlcixcbiAgICAgICAgICBpZCxcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gcmVjZWl2ZXI7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQ2FsbChyZWNlaXZlcjogQVNULCBzdGFydDogbnVtYmVyLCBpc1NhZmU6IGJvb2xlYW4pOiBBU1Qge1xuICAgIGNvbnN0IGFyZ3VtZW50U3RhcnQgPSB0aGlzLmlucHV0SW5kZXg7XG4gICAgdGhpcy5ycGFyZW5zRXhwZWN0ZWQrKztcbiAgICBjb25zdCBhcmdzID0gdGhpcy5wYXJzZUNhbGxBcmd1bWVudHMoKTtcbiAgICBjb25zdCBhcmd1bWVudFNwYW4gPSB0aGlzLnNwYW4oYXJndW1lbnRTdGFydCwgdGhpcy5pbnB1dEluZGV4KS50b0Fic29sdXRlKHRoaXMuYWJzb2x1dGVPZmZzZXQpO1xuICAgIHRoaXMuZXhwZWN0Q2hhcmFjdGVyKGNoYXJzLiRSUEFSRU4pO1xuICAgIHRoaXMucnBhcmVuc0V4cGVjdGVkLS07XG4gICAgY29uc3Qgc3BhbiA9IHRoaXMuc3BhbihzdGFydCk7XG4gICAgY29uc3Qgc291cmNlU3BhbiA9IHRoaXMuc291cmNlU3BhbihzdGFydCk7XG4gICAgcmV0dXJuIGlzU2FmZVxuICAgICAgPyBuZXcgU2FmZUNhbGwoc3Bhbiwgc291cmNlU3BhbiwgcmVjZWl2ZXIsIGFyZ3MsIGFyZ3VtZW50U3BhbilcbiAgICAgIDogbmV3IENhbGwoc3Bhbiwgc291cmNlU3BhbiwgcmVjZWl2ZXIsIGFyZ3MsIGFyZ3VtZW50U3Bhbik7XG4gIH1cblxuICBwcml2YXRlIHBhcnNlQ2FsbEFyZ3VtZW50cygpOiBCaW5kaW5nUGlwZVtdIHtcbiAgICBpZiAodGhpcy5uZXh0LmlzQ2hhcmFjdGVyKGNoYXJzLiRSUEFSRU4pKSByZXR1cm4gW107XG4gICAgY29uc3QgcG9zaXRpb25hbHM6IEFTVFtdID0gW107XG4gICAgZG8ge1xuICAgICAgcG9zaXRpb25hbHMucHVzaCh0aGlzLnBhcnNlUGlwZSgpKTtcbiAgICB9IHdoaWxlICh0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpKTtcbiAgICByZXR1cm4gcG9zaXRpb25hbHMgYXMgQmluZGluZ1BpcGVbXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZXMgYW4gaWRlbnRpZmllciwgYSBrZXl3b3JkLCBhIHN0cmluZyB3aXRoIGFuIG9wdGlvbmFsIGAtYCBpbiBiZXR3ZWVuLFxuICAgKiBhbmQgcmV0dXJucyB0aGUgc3RyaW5nIGFsb25nIHdpdGggaXRzIGFic29sdXRlIHNvdXJjZSBzcGFuLlxuICAgKi9cbiAgcHJpdmF0ZSBleHBlY3RUZW1wbGF0ZUJpbmRpbmdLZXkoKTogVGVtcGxhdGVCaW5kaW5nSWRlbnRpZmllciB7XG4gICAgbGV0IHJlc3VsdCA9ICcnO1xuICAgIGxldCBvcGVyYXRvckZvdW5kID0gZmFsc2U7XG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLmN1cnJlbnRBYnNvbHV0ZU9mZnNldDtcbiAgICBkbyB7XG4gICAgICByZXN1bHQgKz0gdGhpcy5leHBlY3RJZGVudGlmaWVyT3JLZXl3b3JkT3JTdHJpbmcoKTtcbiAgICAgIG9wZXJhdG9yRm91bmQgPSB0aGlzLmNvbnN1bWVPcHRpb25hbE9wZXJhdG9yKCctJyk7XG4gICAgICBpZiAob3BlcmF0b3JGb3VuZCkge1xuICAgICAgICByZXN1bHQgKz0gJy0nO1xuICAgICAgfVxuICAgIH0gd2hpbGUgKG9wZXJhdG9yRm91bmQpO1xuICAgIHJldHVybiB7XG4gICAgICBzb3VyY2U6IHJlc3VsdCxcbiAgICAgIHNwYW46IG5ldyBBYnNvbHV0ZVNvdXJjZVNwYW4oc3RhcnQsIHN0YXJ0ICsgcmVzdWx0Lmxlbmd0aCksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBQYXJzZSBtaWNyb3N5bnRheCB0ZW1wbGF0ZSBleHByZXNzaW9uIGFuZCByZXR1cm4gYSBsaXN0IG9mIGJpbmRpbmdzIG9yXG4gICAqIHBhcnNpbmcgZXJyb3JzIGluIGNhc2UgdGhlIGdpdmVuIGV4cHJlc3Npb24gaXMgaW52YWxpZC5cbiAgICpcbiAgICogRm9yIGV4YW1wbGUsXG4gICAqIGBgYFxuICAgKiAgIDxkaXYgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXM7IGluZGV4IGFzIGk7IHRyYWNrQnk6IGZ1bmNcIj5cbiAgICogYGBgXG4gICAqIGNvbnRhaW5zIGZpdmUgYmluZGluZ3M6XG4gICAqIDEuIG5nRm9yIC0+IG51bGxcbiAgICogMi4gaXRlbSAtPiBOZ0Zvck9mQ29udGV4dC4kaW1wbGljaXRcbiAgICogMy4gbmdGb3JPZiAtPiBpdGVtc1xuICAgKiA0LiBpIC0+IE5nRm9yT2ZDb250ZXh0LmluZGV4XG4gICAqIDUuIG5nRm9yVHJhY2tCeSAtPiBmdW5jXG4gICAqXG4gICAqIEZvciBhIGZ1bGwgZGVzY3JpcHRpb24gb2YgdGhlIG1pY3Jvc3ludGF4IGdyYW1tYXIsIHNlZVxuICAgKiBodHRwczovL2dpc3QuZ2l0aHViLmNvbS9taGV2ZXJ5L2QzNTMwMjk0Y2ZmMmU0YTFiM2ZlMTVmZjc1ZDA4ODU1XG4gICAqXG4gICAqIEBwYXJhbSB0ZW1wbGF0ZUtleSBuYW1lIG9mIHRoZSBtaWNyb3N5bnRheCBkaXJlY3RpdmUsIGxpa2UgbmdJZiwgbmdGb3IsXG4gICAqIHdpdGhvdXQgdGhlICosIGFsb25nIHdpdGggaXRzIGFic29sdXRlIHNwYW4uXG4gICAqL1xuICBwYXJzZVRlbXBsYXRlQmluZGluZ3ModGVtcGxhdGVLZXk6IFRlbXBsYXRlQmluZGluZ0lkZW50aWZpZXIpOiBUZW1wbGF0ZUJpbmRpbmdQYXJzZVJlc3VsdCB7XG4gICAgY29uc3QgYmluZGluZ3M6IFRlbXBsYXRlQmluZGluZ1tdID0gW107XG5cbiAgICAvLyBUaGUgZmlyc3QgYmluZGluZyBpcyBmb3IgdGhlIHRlbXBsYXRlIGtleSBpdHNlbGZcbiAgICAvLyBJbiAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtc1wiLCBrZXkgPSBcIm5nRm9yXCIsIHZhbHVlID0gbnVsbFxuICAgIC8vIEluICpuZ0lmPVwiY29uZCB8IHBpcGVcIiwga2V5ID0gXCJuZ0lmXCIsIHZhbHVlID0gXCJjb25kIHwgcGlwZVwiXG4gICAgYmluZGluZ3MucHVzaCguLi50aGlzLnBhcnNlRGlyZWN0aXZlS2V5d29yZEJpbmRpbmdzKHRlbXBsYXRlS2V5KSk7XG5cbiAgICB3aGlsZSAodGhpcy5pbmRleCA8IHRoaXMudG9rZW5zLmxlbmd0aCkge1xuICAgICAgLy8gSWYgaXQgc3RhcnRzIHdpdGggJ2xldCcsIHRoZW4gdGhpcyBtdXN0IGJlIHZhcmlhYmxlIGRlY2xhcmF0aW9uXG4gICAgICBjb25zdCBsZXRCaW5kaW5nID0gdGhpcy5wYXJzZUxldEJpbmRpbmcoKTtcbiAgICAgIGlmIChsZXRCaW5kaW5nKSB7XG4gICAgICAgIGJpbmRpbmdzLnB1c2gobGV0QmluZGluZyk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBUd28gcG9zc2libGUgY2FzZXMgaGVyZSwgZWl0aGVyIGB2YWx1ZSBcImFzXCIga2V5YCBvclxuICAgICAgICAvLyBcImRpcmVjdGl2ZS1rZXl3b3JkIGV4cHJlc3Npb25cIi4gV2UgZG9uJ3Qga25vdyB3aGljaCBjYXNlLCBidXQgYm90aFxuICAgICAgICAvLyBcInZhbHVlXCIgYW5kIFwiZGlyZWN0aXZlLWtleXdvcmRcIiBhcmUgdGVtcGxhdGUgYmluZGluZyBrZXksIHNvIGNvbnN1bWVcbiAgICAgICAgLy8gdGhlIGtleSBmaXJzdC5cbiAgICAgICAgY29uc3Qga2V5ID0gdGhpcy5leHBlY3RUZW1wbGF0ZUJpbmRpbmdLZXkoKTtcbiAgICAgICAgLy8gUGVlayBhdCB0aGUgbmV4dCB0b2tlbiwgaWYgaXQgaXMgXCJhc1wiIHRoZW4gdGhpcyBtdXN0IGJlIHZhcmlhYmxlXG4gICAgICAgIC8vIGRlY2xhcmF0aW9uLlxuICAgICAgICBjb25zdCBiaW5kaW5nID0gdGhpcy5wYXJzZUFzQmluZGluZyhrZXkpO1xuICAgICAgICBpZiAoYmluZGluZykge1xuICAgICAgICAgIGJpbmRpbmdzLnB1c2goYmluZGluZyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgLy8gT3RoZXJ3aXNlIHRoZSBrZXkgbXVzdCBiZSBhIGRpcmVjdGl2ZSBrZXl3b3JkLCBsaWtlIFwib2ZcIi4gVHJhbnNmb3JtXG4gICAgICAgICAgLy8gdGhlIGtleSB0byBhY3R1YWwga2V5LiBFZy4gb2YgLT4gbmdGb3JPZiwgdHJhY2tCeSAtPiBuZ0ZvclRyYWNrQnlcbiAgICAgICAgICBrZXkuc291cmNlID1cbiAgICAgICAgICAgIHRlbXBsYXRlS2V5LnNvdXJjZSArIGtleS5zb3VyY2UuY2hhckF0KDApLnRvVXBwZXJDYXNlKCkgKyBrZXkuc291cmNlLnN1YnN0cmluZygxKTtcbiAgICAgICAgICBiaW5kaW5ncy5wdXNoKC4uLnRoaXMucGFyc2VEaXJlY3RpdmVLZXl3b3JkQmluZGluZ3Moa2V5KSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIHRoaXMuY29uc3VtZVN0YXRlbWVudFRlcm1pbmF0b3IoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gbmV3IFRlbXBsYXRlQmluZGluZ1BhcnNlUmVzdWx0KGJpbmRpbmdzLCBbXSAvKiB3YXJuaW5ncyAqLywgdGhpcy5lcnJvcnMpO1xuICB9XG5cbiAgcHJpdmF0ZSBwYXJzZUtleWVkUmVhZE9yV3JpdGUocmVjZWl2ZXI6IEFTVCwgc3RhcnQ6IG51bWJlciwgaXNTYWZlOiBib29sZWFuKTogQVNUIHtcbiAgICByZXR1cm4gdGhpcy53aXRoQ29udGV4dChQYXJzZUNvbnRleHRGbGFncy5Xcml0YWJsZSwgKCkgPT4ge1xuICAgICAgdGhpcy5yYnJhY2tldHNFeHBlY3RlZCsrO1xuICAgICAgY29uc3Qga2V5ID0gdGhpcy5wYXJzZVBpcGUoKTtcbiAgICAgIGlmIChrZXkgaW5zdGFuY2VvZiBFbXB0eUV4cHIpIHtcbiAgICAgICAgdGhpcy5lcnJvcihgS2V5IGFjY2VzcyBjYW5ub3QgYmUgZW1wdHlgKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucmJyYWNrZXRzRXhwZWN0ZWQtLTtcbiAgICAgIHRoaXMuZXhwZWN0Q2hhcmFjdGVyKGNoYXJzLiRSQlJBQ0tFVCk7XG4gICAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignPScpKSB7XG4gICAgICAgIGlmIChpc1NhZmUpIHtcbiAgICAgICAgICB0aGlzLmVycm9yKFwiVGhlICc/Licgb3BlcmF0b3IgY2Fubm90IGJlIHVzZWQgaW4gdGhlIGFzc2lnbm1lbnRcIik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgY29uc3QgdmFsdWUgPSB0aGlzLnBhcnNlQ29uZGl0aW9uYWwoKTtcbiAgICAgICAgICByZXR1cm4gbmV3IEtleWVkV3JpdGUodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSwgcmVjZWl2ZXIsIGtleSwgdmFsdWUpO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gaXNTYWZlXG4gICAgICAgICAgPyBuZXcgU2FmZUtleWVkUmVhZCh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCByZWNlaXZlciwga2V5KVxuICAgICAgICAgIDogbmV3IEtleWVkUmVhZCh0aGlzLnNwYW4oc3RhcnQpLCB0aGlzLnNvdXJjZVNwYW4oc3RhcnQpLCByZWNlaXZlciwga2V5KTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG5ldyBFbXB0eUV4cHIodGhpcy5zcGFuKHN0YXJ0KSwgdGhpcy5zb3VyY2VTcGFuKHN0YXJ0KSk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogUGFyc2UgYSBkaXJlY3RpdmUga2V5d29yZCwgZm9sbG93ZWQgYnkgYSBtYW5kYXRvcnkgZXhwcmVzc2lvbi5cbiAgICogRm9yIGV4YW1wbGUsIFwib2YgaXRlbXNcIiwgXCJ0cmFja0J5OiBmdW5jXCIuXG4gICAqIFRoZSBiaW5kaW5ncyBhcmU6IG5nRm9yT2YgLT4gaXRlbXMsIG5nRm9yVHJhY2tCeSAtPiBmdW5jXG4gICAqIFRoZXJlIGNvdWxkIGJlIGFuIG9wdGlvbmFsIFwiYXNcIiBiaW5kaW5nIHRoYXQgZm9sbG93cyB0aGUgZXhwcmVzc2lvbi5cbiAgICogRm9yIGV4YW1wbGUsXG4gICAqIGBgYFxuICAgKiAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zIHwgc2xpY2U6MDoxIGFzIGNvbGxlY3Rpb25cIi5cbiAgICogICAgICAgICAgICAgICAgICAgIF5eIF5eXl5eXl5eXl5eXl5eXl5eIF5eXl5eXl5eXl5eXl5cbiAgICogICAgICAgICAgICAgICBrZXl3b3JkICAgIGJvdW5kIHRhcmdldCAgIG9wdGlvbmFsICdhcycgYmluZGluZ1xuICAgKiBgYGBcbiAgICpcbiAgICogQHBhcmFtIGtleSBiaW5kaW5nIGtleSwgZm9yIGV4YW1wbGUsIG5nRm9yLCBuZ0lmLCBuZ0Zvck9mLCBhbG9uZyB3aXRoIGl0c1xuICAgKiBhYnNvbHV0ZSBzcGFuLlxuICAgKi9cbiAgcHJpdmF0ZSBwYXJzZURpcmVjdGl2ZUtleXdvcmRCaW5kaW5ncyhrZXk6IFRlbXBsYXRlQmluZGluZ0lkZW50aWZpZXIpOiBUZW1wbGF0ZUJpbmRpbmdbXSB7XG4gICAgY29uc3QgYmluZGluZ3M6IFRlbXBsYXRlQmluZGluZ1tdID0gW107XG4gICAgdGhpcy5jb25zdW1lT3B0aW9uYWxDaGFyYWN0ZXIoY2hhcnMuJENPTE9OKTsgLy8gdHJhY2tCeTogdHJhY2tCeUZ1bmN0aW9uXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmdldERpcmVjdGl2ZUJvdW5kVGFyZ2V0KCk7XG4gICAgbGV0IHNwYW5FbmQgPSB0aGlzLmN1cnJlbnRBYnNvbHV0ZU9mZnNldDtcbiAgICAvLyBUaGUgYmluZGluZyBjb3VsZCBvcHRpb25hbGx5IGJlIGZvbGxvd2VkIGJ5IFwiYXNcIi4gRm9yIGV4YW1wbGUsXG4gICAgLy8gKm5nSWY9XCJjb25kIHwgcGlwZSBhcyB4XCIuIEluIHRoaXMgY2FzZSwgdGhlIGtleSBpbiB0aGUgXCJhc1wiIGJpbmRpbmdcbiAgICAvLyBpcyBcInhcIiBhbmQgdGhlIHZhbHVlIGlzIHRoZSB0ZW1wbGF0ZSBrZXkgaXRzZWxmIChcIm5nSWZcIikuIE5vdGUgdGhhdCB0aGVcbiAgICAvLyAna2V5JyBpbiB0aGUgY3VycmVudCBjb250ZXh0IG5vdyBiZWNvbWVzIHRoZSBcInZhbHVlXCIgaW4gdGhlIG5leHQgYmluZGluZy5cbiAgICBjb25zdCBhc0JpbmRpbmcgPSB0aGlzLnBhcnNlQXNCaW5kaW5nKGtleSk7XG4gICAgaWYgKCFhc0JpbmRpbmcpIHtcbiAgICAgIHRoaXMuY29uc3VtZVN0YXRlbWVudFRlcm1pbmF0b3IoKTtcbiAgICAgIHNwYW5FbmQgPSB0aGlzLmN1cnJlbnRBYnNvbHV0ZU9mZnNldDtcbiAgICB9XG4gICAgY29uc3Qgc291cmNlU3BhbiA9IG5ldyBBYnNvbHV0ZVNvdXJjZVNwYW4oa2V5LnNwYW4uc3RhcnQsIHNwYW5FbmQpO1xuICAgIGJpbmRpbmdzLnB1c2gobmV3IEV4cHJlc3Npb25CaW5kaW5nKHNvdXJjZVNwYW4sIGtleSwgdmFsdWUpKTtcbiAgICBpZiAoYXNCaW5kaW5nKSB7XG4gICAgICBiaW5kaW5ncy5wdXNoKGFzQmluZGluZyk7XG4gICAgfVxuICAgIHJldHVybiBiaW5kaW5ncztcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm4gdGhlIGV4cHJlc3Npb24gQVNUIGZvciB0aGUgYm91bmQgdGFyZ2V0IG9mIGEgZGlyZWN0aXZlIGtleXdvcmRcbiAgICogYmluZGluZy4gRm9yIGV4YW1wbGUsXG4gICAqIGBgYFxuICAgKiAgICpuZ0lmPVwiY29uZGl0aW9uIHwgcGlwZVwiXG4gICAqICAgICAgICAgIF5eXl5eXl5eXl5eXl5eXl4gYm91bmQgdGFyZ2V0IGZvciBcIm5nSWZcIlxuICAgKiAgICpuZ0Zvcj1cImxldCBpdGVtIG9mIGl0ZW1zXCJcbiAgICogICAgICAgICAgICAgICAgICAgICAgIF5eXl5eIGJvdW5kIHRhcmdldCBmb3IgXCJuZ0Zvck9mXCJcbiAgICogYGBgXG4gICAqL1xuICBwcml2YXRlIGdldERpcmVjdGl2ZUJvdW5kVGFyZ2V0KCk6IEFTVFdpdGhTb3VyY2UgfCBudWxsIHtcbiAgICBpZiAodGhpcy5uZXh0ID09PSBFT0YgfHwgdGhpcy5wZWVrS2V5d29yZEFzKCkgfHwgdGhpcy5wZWVrS2V5d29yZExldCgpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgY29uc3QgYXN0ID0gdGhpcy5wYXJzZVBpcGUoKTsgLy8gZXhhbXBsZTogXCJjb25kaXRpb24gfCBhc3luY1wiXG4gICAgY29uc3Qge3N0YXJ0LCBlbmR9ID0gYXN0LnNwYW47XG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLmlucHV0LnN1YnN0cmluZyhzdGFydCwgZW5kKTtcbiAgICByZXR1cm4gbmV3IEFTVFdpdGhTb3VyY2UoYXN0LCB2YWx1ZSwgdGhpcy5sb2NhdGlvbiwgdGhpcy5hYnNvbHV0ZU9mZnNldCArIHN0YXJ0LCB0aGlzLmVycm9ycyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBiaW5kaW5nIGZvciBhIHZhcmlhYmxlIGRlY2xhcmVkIHVzaW5nIGBhc2AuIE5vdGUgdGhhdCB0aGUgb3JkZXJcbiAgICogb2YgdGhlIGtleS12YWx1ZSBwYWlyIGluIHRoaXMgZGVjbGFyYXRpb24gaXMgcmV2ZXJzZWQuIEZvciBleGFtcGxlLFxuICAgKiBgYGBcbiAgICogICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtczsgaW5kZXggYXMgaVwiXG4gICAqICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgXl5eXl4gICAgXlxuICAgKiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHZhbHVlICAgIGtleVxuICAgKiBgYGBcbiAgICpcbiAgICogQHBhcmFtIHZhbHVlIG5hbWUgb2YgdGhlIHZhbHVlIGluIHRoZSBkZWNsYXJhdGlvbiwgXCJuZ0lmXCIgaW4gdGhlIGV4YW1wbGVcbiAgICogYWJvdmUsIGFsb25nIHdpdGggaXRzIGFic29sdXRlIHNwYW4uXG4gICAqL1xuICBwcml2YXRlIHBhcnNlQXNCaW5kaW5nKHZhbHVlOiBUZW1wbGF0ZUJpbmRpbmdJZGVudGlmaWVyKTogVGVtcGxhdGVCaW5kaW5nIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLnBlZWtLZXl3b3JkQXMoKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIHRoaXMuYWR2YW5jZSgpOyAvLyBjb25zdW1lIHRoZSAnYXMnIGtleXdvcmRcbiAgICBjb25zdCBrZXkgPSB0aGlzLmV4cGVjdFRlbXBsYXRlQmluZGluZ0tleSgpO1xuICAgIHRoaXMuY29uc3VtZVN0YXRlbWVudFRlcm1pbmF0b3IoKTtcbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IEFic29sdXRlU291cmNlU3Bhbih2YWx1ZS5zcGFuLnN0YXJ0LCB0aGlzLmN1cnJlbnRBYnNvbHV0ZU9mZnNldCk7XG4gICAgcmV0dXJuIG5ldyBWYXJpYWJsZUJpbmRpbmcoc291cmNlU3Bhbiwga2V5LCB2YWx1ZSk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJuIHRoZSBiaW5kaW5nIGZvciBhIHZhcmlhYmxlIGRlY2xhcmVkIHVzaW5nIGBsZXRgLiBGb3IgZXhhbXBsZSxcbiAgICogYGBgXG4gICAqICAgKm5nRm9yPVwibGV0IGl0ZW0gb2YgaXRlbXM7IGxldCBpPWluZGV4O1wiXG4gICAqICAgICAgICAgICBeXl5eXl5eXiAgICAgICAgICAgXl5eXl5eXl5eXl5cbiAgICogYGBgXG4gICAqIEluIHRoZSBmaXJzdCBiaW5kaW5nLCBgaXRlbWAgaXMgYm91bmQgdG8gYE5nRm9yT2ZDb250ZXh0LiRpbXBsaWNpdGAuXG4gICAqIEluIHRoZSBzZWNvbmQgYmluZGluZywgYGlgIGlzIGJvdW5kIHRvIGBOZ0Zvck9mQ29udGV4dC5pbmRleGAuXG4gICAqL1xuICBwcml2YXRlIHBhcnNlTGV0QmluZGluZygpOiBUZW1wbGF0ZUJpbmRpbmcgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMucGVla0tleXdvcmRMZXQoKSkge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICAgIGNvbnN0IHNwYW5TdGFydCA9IHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0O1xuICAgIHRoaXMuYWR2YW5jZSgpOyAvLyBjb25zdW1lIHRoZSAnbGV0JyBrZXl3b3JkXG4gICAgY29uc3Qga2V5ID0gdGhpcy5leHBlY3RUZW1wbGF0ZUJpbmRpbmdLZXkoKTtcbiAgICBsZXQgdmFsdWU6IFRlbXBsYXRlQmluZGluZ0lkZW50aWZpZXIgfCBudWxsID0gbnVsbDtcbiAgICBpZiAodGhpcy5jb25zdW1lT3B0aW9uYWxPcGVyYXRvcignPScpKSB7XG4gICAgICB2YWx1ZSA9IHRoaXMuZXhwZWN0VGVtcGxhdGVCaW5kaW5nS2V5KCk7XG4gICAgfVxuICAgIHRoaXMuY29uc3VtZVN0YXRlbWVudFRlcm1pbmF0b3IoKTtcbiAgICBjb25zdCBzb3VyY2VTcGFuID0gbmV3IEFic29sdXRlU291cmNlU3BhbihzcGFuU3RhcnQsIHRoaXMuY3VycmVudEFic29sdXRlT2Zmc2V0KTtcbiAgICByZXR1cm4gbmV3IFZhcmlhYmxlQmluZGluZyhzb3VyY2VTcGFuLCBrZXksIHZhbHVlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25zdW1lIHRoZSBvcHRpb25hbCBzdGF0ZW1lbnQgdGVybWluYXRvcjogc2VtaWNvbG9uIG9yIGNvbW1hLlxuICAgKi9cbiAgcHJpdmF0ZSBjb25zdW1lU3RhdGVtZW50VGVybWluYXRvcigpIHtcbiAgICB0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSB8fCB0aGlzLmNvbnN1bWVPcHRpb25hbENoYXJhY3RlcihjaGFycy4kQ09NTUEpO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZHMgYW4gZXJyb3IgYW5kIHNraXBzIG92ZXIgdGhlIHRva2VuIHN0cmVhbSB1bnRpbCByZWFjaGluZyBhIHJlY292ZXJhYmxlIHBvaW50LiBTZWVcbiAgICogYHRoaXMuc2tpcGAgZm9yIG1vcmUgZGV0YWlscyBvbiB0b2tlbiBza2lwcGluZy5cbiAgICovXG4gIHByaXZhdGUgZXJyb3IobWVzc2FnZTogc3RyaW5nLCBpbmRleDogbnVtYmVyIHwgbnVsbCA9IG51bGwpIHtcbiAgICB0aGlzLmVycm9ycy5wdXNoKG5ldyBQYXJzZXJFcnJvcihtZXNzYWdlLCB0aGlzLmlucHV0LCB0aGlzLmxvY2F0aW9uVGV4dChpbmRleCksIHRoaXMubG9jYXRpb24pKTtcbiAgICB0aGlzLnNraXAoKTtcbiAgfVxuXG4gIHByaXZhdGUgbG9jYXRpb25UZXh0KGluZGV4OiBudW1iZXIgfCBudWxsID0gbnVsbCkge1xuICAgIGlmIChpbmRleCA9PSBudWxsKSBpbmRleCA9IHRoaXMuaW5kZXg7XG4gICAgcmV0dXJuIGluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoXG4gICAgICA/IGBhdCBjb2x1bW4gJHt0aGlzLnRva2Vuc1tpbmRleF0uaW5kZXggKyAxfSBpbmBcbiAgICAgIDogYGF0IHRoZSBlbmQgb2YgdGhlIGV4cHJlc3Npb25gO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlY29yZHMgYW4gZXJyb3IgZm9yIGFuIHVuZXhwZWN0ZWQgcHJpdmF0ZSBpZGVudGlmaWVyIGJlaW5nIGRpc2NvdmVyZWQuXG4gICAqIEBwYXJhbSB0b2tlbiBUb2tlbiByZXByZXNlbnRpbmcgYSBwcml2YXRlIGlkZW50aWZpZXIuXG4gICAqIEBwYXJhbSBleHRyYU1lc3NhZ2UgT3B0aW9uYWwgYWRkaXRpb25hbCBtZXNzYWdlIGJlaW5nIGFwcGVuZGVkIHRvIHRoZSBlcnJvci5cbiAgICovXG4gIHByaXZhdGUgX3JlcG9ydEVycm9yRm9yUHJpdmF0ZUlkZW50aWZpZXIodG9rZW46IFRva2VuLCBleHRyYU1lc3NhZ2U6IHN0cmluZyB8IG51bGwpIHtcbiAgICBsZXQgZXJyb3JNZXNzYWdlID0gYFByaXZhdGUgaWRlbnRpZmllcnMgYXJlIG5vdCBzdXBwb3J0ZWQuIFVuZXhwZWN0ZWQgcHJpdmF0ZSBpZGVudGlmaWVyOiAke3Rva2VufWA7XG4gICAgaWYgKGV4dHJhTWVzc2FnZSAhPT0gbnVsbCkge1xuICAgICAgZXJyb3JNZXNzYWdlICs9IGAsICR7ZXh0cmFNZXNzYWdlfWA7XG4gICAgfVxuICAgIHRoaXMuZXJyb3IoZXJyb3JNZXNzYWdlKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBFcnJvciByZWNvdmVyeSBzaG91bGQgc2tpcCB0b2tlbnMgdW50aWwgaXQgZW5jb3VudGVycyBhIHJlY292ZXJ5IHBvaW50LlxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGFyZSB0cmVhdGVkIGFzIHVuY29uZGl0aW9uYWwgcmVjb3ZlcnkgcG9pbnRzOlxuICAgKiAgIC0gZW5kIG9mIGlucHV0XG4gICAqICAgLSAnOycgKHBhcnNlQ2hhaW4oKSBpcyBhbHdheXMgdGhlIHJvb3QgcHJvZHVjdGlvbiwgYW5kIGl0IGV4cGVjdHMgYSAnOycpXG4gICAqICAgLSAnfCcgKHNpbmNlIHBpcGVzIG1heSBiZSBjaGFpbmVkIGFuZCBlYWNoIHBpcGUgZXhwcmVzc2lvbiBtYXkgYmUgdHJlYXRlZCBpbmRlcGVuZGVudGx5KVxuICAgKlxuICAgKiBUaGUgZm9sbG93aW5nIGFyZSBjb25kaXRpb25hbCByZWNvdmVyeSBwb2ludHM6XG4gICAqICAgLSAnKScsICd9JywgJ10nIGlmIG9uZSBvZiBjYWxsaW5nIHByb2R1Y3Rpb25zIGlzIGV4cGVjdGluZyBvbmUgb2YgdGhlc2Ugc3ltYm9sc1xuICAgKiAgICAgLSBUaGlzIGFsbG93cyBza2lwKCkgdG8gcmVjb3ZlciBmcm9tIGVycm9ycyBzdWNoIGFzICcoYS4pICsgMScgYWxsb3dpbmcgbW9yZSBvZiB0aGUgQVNUIHRvXG4gICAqICAgICAgIGJlIHJldGFpbmVkIChpdCBkb2Vzbid0IHNraXAgYW55IHRva2VucyBhcyB0aGUgJyknIGlzIHJldGFpbmVkIGJlY2F1c2Ugb2YgdGhlICcoJyBiZWdpbnNcbiAgICogICAgICAgYW4gJygnIDxleHByPiAnKScgcHJvZHVjdGlvbikuXG4gICAqICAgICAgIFRoZSByZWNvdmVyeSBwb2ludHMgb2YgZ3JvdXBpbmcgc3ltYm9scyBtdXN0IGJlIGNvbmRpdGlvbmFsIGFzIHRoZXkgbXVzdCBiZSBza2lwcGVkIGlmXG4gICAqICAgICAgIG5vbmUgb2YgdGhlIGNhbGxpbmcgcHJvZHVjdGlvbnMgYXJlIG5vdCBleHBlY3RpbmcgdGhlIGNsb3NpbmcgdG9rZW4gZWxzZSB3ZSB3aWxsIG5ldmVyXG4gICAqICAgICAgIG1ha2UgcHJvZ3Jlc3MgaW4gdGhlIGNhc2Ugb2YgYW4gZXh0cmFuZW91cyBncm91cCBjbG9zaW5nIHN5bWJvbCAoc3VjaCBhcyBhIHN0cmF5ICcpJykuXG4gICAqICAgICAgIFRoYXQgaXMsIHdlIHNraXAgYSBjbG9zaW5nIHN5bWJvbCBpZiB3ZSBhcmUgbm90IGluIGEgZ3JvdXBpbmcgcHJvZHVjdGlvbi5cbiAgICogICAtICc9JyBpbiBhIGBXcml0YWJsZWAgY29udGV4dFxuICAgKiAgICAgLSBJbiB0aGlzIGNvbnRleHQsIHdlIGFyZSBhYmxlIHRvIHJlY292ZXIgYWZ0ZXIgc2VlaW5nIHRoZSBgPWAgb3BlcmF0b3IsIHdoaWNoXG4gICAqICAgICAgIHNpZ25hbHMgdGhlIHByZXNlbmNlIG9mIGFuIGluZGVwZW5kZW50IHJ2YWx1ZSBleHByZXNzaW9uIGZvbGxvd2luZyB0aGUgYD1gIG9wZXJhdG9yLlxuICAgKlxuICAgKiBJZiBhIHByb2R1Y3Rpb24gZXhwZWN0cyBvbmUgb2YgdGhlc2UgdG9rZW4gaXQgaW5jcmVtZW50cyB0aGUgY29ycmVzcG9uZGluZyBuZXN0aW5nIGNvdW50LFxuICAgKiBhbmQgdGhlbiBkZWNyZW1lbnRzIGl0IGp1c3QgcHJpb3IgdG8gY2hlY2tpbmcgaWYgdGhlIHRva2VuIGlzIGluIHRoZSBpbnB1dC5cbiAgICovXG4gIHByaXZhdGUgc2tpcCgpIHtcbiAgICBsZXQgbiA9IHRoaXMubmV4dDtcbiAgICB3aGlsZSAoXG4gICAgICB0aGlzLmluZGV4IDwgdGhpcy50b2tlbnMubGVuZ3RoICYmXG4gICAgICAhbi5pc0NoYXJhY3RlcihjaGFycy4kU0VNSUNPTE9OKSAmJlxuICAgICAgIW4uaXNPcGVyYXRvcignfCcpICYmXG4gICAgICAodGhpcy5ycGFyZW5zRXhwZWN0ZWQgPD0gMCB8fCAhbi5pc0NoYXJhY3RlcihjaGFycy4kUlBBUkVOKSkgJiZcbiAgICAgICh0aGlzLnJicmFjZXNFeHBlY3RlZCA8PSAwIHx8ICFuLmlzQ2hhcmFjdGVyKGNoYXJzLiRSQlJBQ0UpKSAmJlxuICAgICAgKHRoaXMucmJyYWNrZXRzRXhwZWN0ZWQgPD0gMCB8fCAhbi5pc0NoYXJhY3RlcihjaGFycy4kUkJSQUNLRVQpKSAmJlxuICAgICAgKCEodGhpcy5jb250ZXh0ICYgUGFyc2VDb250ZXh0RmxhZ3MuV3JpdGFibGUpIHx8ICFuLmlzT3BlcmF0b3IoJz0nKSlcbiAgICApIHtcbiAgICAgIGlmICh0aGlzLm5leHQuaXNFcnJvcigpKSB7XG4gICAgICAgIHRoaXMuZXJyb3JzLnB1c2goXG4gICAgICAgICAgbmV3IFBhcnNlckVycm9yKHRoaXMubmV4dC50b1N0cmluZygpISwgdGhpcy5pbnB1dCwgdGhpcy5sb2NhdGlvblRleHQoKSwgdGhpcy5sb2NhdGlvbiksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgICB0aGlzLmFkdmFuY2UoKTtcbiAgICAgIG4gPSB0aGlzLm5leHQ7XG4gICAgfVxuICB9XG59XG5cbmNsYXNzIFNpbXBsZUV4cHJlc3Npb25DaGVja2VyIGV4dGVuZHMgUmVjdXJzaXZlQXN0VmlzaXRvciB7XG4gIGVycm9yczogc3RyaW5nW10gPSBbXTtcblxuICBvdmVycmlkZSB2aXNpdFBpcGUoKSB7XG4gICAgdGhpcy5lcnJvcnMucHVzaCgncGlwZXMnKTtcbiAgfVxufVxuLyoqXG4gKiBDb21wdXRlcyB0aGUgcmVhbCBvZmZzZXQgaW4gdGhlIG9yaWdpbmFsIHRlbXBsYXRlIGZvciBpbmRleGVzIGluIGFuIGludGVycG9sYXRpb24uXG4gKlxuICogQmVjYXVzZSB0ZW1wbGF0ZXMgY2FuIGhhdmUgZW5jb2RlZCBIVE1MIGVudGl0aWVzIGFuZCB0aGUgaW5wdXQgcGFzc2VkIHRvIHRoZSBwYXJzZXIgYXQgdGhpcyBzdGFnZVxuICogb2YgdGhlIGNvbXBpbGVyIGlzIHRoZSBfZGVjb2RlZF8gdmFsdWUsIHdlIG5lZWQgdG8gY29tcHV0ZSB0aGUgcmVhbCBvZmZzZXQgdXNpbmcgdGhlIG9yaWdpbmFsXG4gKiBlbmNvZGVkIHZhbHVlcyBpbiB0aGUgaW50ZXJwb2xhdGVkIHRva2Vucy4gTm90ZSB0aGF0IHRoaXMgaXMgb25seSBhIHNwZWNpYWwgY2FzZSBoYW5kbGluZyBmb3JcbiAqIGBNbFBhcnNlclRva2VuVHlwZS5FTkNPREVEX0VOVElUWWAgdG9rZW4gdHlwZXMuIEFsbCBvdGhlciBpbnRlcnBvbGF0ZWQgdG9rZW5zIGFyZSBleHBlY3RlZCB0b1xuICogaGF2ZSBwYXJ0cyB3aGljaCBleGFjdGx5IG1hdGNoIHRoZSBpbnB1dCBzdHJpbmcgZm9yIHBhcnNpbmcgdGhlIGludGVycG9sYXRpb24uXG4gKlxuICogQHBhcmFtIGludGVycG9sYXRlZFRva2VucyBUaGUgdG9rZW5zIGZvciB0aGUgaW50ZXJwb2xhdGVkIHZhbHVlLlxuICpcbiAqIEByZXR1cm5zIEEgbWFwIG9mIGluZGV4IGxvY2F0aW9ucyBpbiB0aGUgZGVjb2RlZCB0ZW1wbGF0ZSB0byBpbmRleGVzIGluIHRoZSBvcmlnaW5hbCB0ZW1wbGF0ZVxuICovXG5mdW5jdGlvbiBnZXRJbmRleE1hcEZvck9yaWdpbmFsVGVtcGxhdGUoXG4gIGludGVycG9sYXRlZFRva2VuczogSW50ZXJwb2xhdGVkQXR0cmlidXRlVG9rZW5bXSB8IEludGVycG9sYXRlZFRleHRUb2tlbltdLFxuKTogTWFwPG51bWJlciwgbnVtYmVyPiB7XG4gIGxldCBvZmZzZXRNYXAgPSBuZXcgTWFwPG51bWJlciwgbnVtYmVyPigpO1xuICBsZXQgY29uc3VtZWRJbk9yaWdpbmFsVGVtcGxhdGUgPSAwO1xuICBsZXQgY29uc3VtZWRJbklucHV0ID0gMDtcbiAgbGV0IHRva2VuSW5kZXggPSAwO1xuICB3aGlsZSAodG9rZW5JbmRleCA8IGludGVycG9sYXRlZFRva2Vucy5sZW5ndGgpIHtcbiAgICBjb25zdCBjdXJyZW50VG9rZW4gPSBpbnRlcnBvbGF0ZWRUb2tlbnNbdG9rZW5JbmRleF07XG4gICAgaWYgKGN1cnJlbnRUb2tlbi50eXBlID09PSBNbFBhcnNlclRva2VuVHlwZS5FTkNPREVEX0VOVElUWSkge1xuICAgICAgY29uc3QgW2RlY29kZWQsIGVuY29kZWRdID0gY3VycmVudFRva2VuLnBhcnRzO1xuICAgICAgY29uc3VtZWRJbk9yaWdpbmFsVGVtcGxhdGUgKz0gZW5jb2RlZC5sZW5ndGg7XG4gICAgICBjb25zdW1lZEluSW5wdXQgKz0gZGVjb2RlZC5sZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGxlbmd0aE9mUGFydHMgPSBjdXJyZW50VG9rZW4ucGFydHMucmVkdWNlKChzdW0sIGN1cnJlbnQpID0+IHN1bSArIGN1cnJlbnQubGVuZ3RoLCAwKTtcbiAgICAgIGNvbnN1bWVkSW5JbnB1dCArPSBsZW5ndGhPZlBhcnRzO1xuICAgICAgY29uc3VtZWRJbk9yaWdpbmFsVGVtcGxhdGUgKz0gbGVuZ3RoT2ZQYXJ0cztcbiAgICB9XG4gICAgb2Zmc2V0TWFwLnNldChjb25zdW1lZEluSW5wdXQsIGNvbnN1bWVkSW5PcmlnaW5hbFRlbXBsYXRlKTtcbiAgICB0b2tlbkluZGV4Kys7XG4gIH1cbiAgcmV0dXJuIG9mZnNldE1hcDtcbn1cbiJdfQ==