@angular/core 9.0.0-rc.9 → 9.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (196) hide show
  1. package/bundles/core-testing.umd.js +10 -9
  2. package/bundles/core-testing.umd.js.map +1 -1
  3. package/bundles/core-testing.umd.min.js +6 -6
  4. package/bundles/core-testing.umd.min.js.map +1 -1
  5. package/bundles/core.umd.js +3619 -3914
  6. package/bundles/core.umd.js.map +1 -1
  7. package/bundles/core.umd.min.js +182 -175
  8. package/bundles/core.umd.min.js.map +1 -1
  9. package/core.d.ts +483 -651
  10. package/core.metadata.json +1 -1
  11. package/esm2015/core.js +17 -17
  12. package/esm2015/index.js +2 -2
  13. package/esm2015/public_api.js +2 -2
  14. package/esm2015/src/application_ref.js +7 -7
  15. package/esm2015/src/core.js +3 -3
  16. package/esm2015/src/core_private_export.js +7 -7
  17. package/esm2015/src/core_render3_private_export.js +2 -2
  18. package/esm2015/src/debug/debug_node.js +44 -12
  19. package/esm2015/src/i18n/locale_data_api.js +1 -2
  20. package/esm2015/src/interface/type.js +1 -1
  21. package/esm2015/src/metadata/ng_module.js +1 -1
  22. package/esm2015/src/render/api.js +4 -1
  23. package/esm2015/src/render3/assert.js +9 -1
  24. package/esm2015/src/render3/bindings.js +16 -5
  25. package/esm2015/src/render3/component.js +54 -25
  26. package/esm2015/src/render3/component_ref.js +11 -15
  27. package/esm2015/src/render3/definition.js +3 -1
  28. package/esm2015/src/render3/di.js +3 -4
  29. package/esm2015/src/render3/di_setup.js +5 -7
  30. package/esm2015/src/render3/errors.js +3 -1
  31. package/esm2015/src/render3/features/inherit_definition_feature.js +41 -13
  32. package/esm2015/src/render3/features/ng_onchanges_feature.js +2 -2
  33. package/esm2015/src/render3/global_utils_api.js +3 -3
  34. package/esm2015/src/render3/i18n.js +60 -56
  35. package/esm2015/src/render3/index.js +2 -2
  36. package/esm2015/src/render3/instructions/advance.js +10 -11
  37. package/esm2015/src/render3/instructions/all.js +4 -5
  38. package/esm2015/src/render3/instructions/attribute.js +6 -6
  39. package/esm2015/src/render3/instructions/attribute_interpolation.js +40 -21
  40. package/esm2015/src/render3/instructions/change_detection.js +8 -23
  41. package/esm2015/src/render3/instructions/class_map_interpolation.js +13 -12
  42. package/esm2015/src/render3/instructions/container.js +15 -12
  43. package/esm2015/src/render3/instructions/element.js +40 -127
  44. package/esm2015/src/render3/instructions/element_container.js +8 -10
  45. package/esm2015/src/render3/instructions/embedded_view.js +7 -7
  46. package/esm2015/src/render3/instructions/host_property.js +10 -7
  47. package/esm2015/src/render3/instructions/listener.js +18 -16
  48. package/esm2015/src/render3/instructions/lview_debug.js +160 -23
  49. package/esm2015/src/render3/instructions/projection.js +7 -5
  50. package/esm2015/src/render3/instructions/property.js +27 -6
  51. package/esm2015/src/render3/instructions/property_interpolation.js +40 -22
  52. package/esm2015/src/render3/instructions/shared.js +267 -240
  53. package/esm2015/src/render3/instructions/storage.js +6 -8
  54. package/esm2015/src/render3/instructions/style_prop_interpolation.js +12 -12
  55. package/esm2015/src/render3/instructions/styling.js +731 -475
  56. package/esm2015/src/render3/instructions/text.js +5 -5
  57. package/esm2015/src/render3/interfaces/definition.js +41 -1
  58. package/esm2015/src/render3/interfaces/node.js +160 -115
  59. package/esm2015/src/render3/interfaces/styling.js +183 -375
  60. package/esm2015/src/render3/interfaces/view.js +10 -2
  61. package/esm2015/src/render3/jit/environment.js +1 -3
  62. package/esm2015/src/render3/node_manipulation.js +177 -57
  63. package/esm2015/src/render3/node_selector_matcher.js +39 -24
  64. package/esm2015/src/render3/node_util.js +12 -7
  65. package/esm2015/src/render3/pipe.js +4 -6
  66. package/esm2015/src/render3/query.js +32 -26
  67. package/esm2015/src/render3/state.js +54 -183
  68. package/esm2015/src/render3/styling/class_differ.js +47 -0
  69. package/esm2015/src/render3/styling/static_styling.js +54 -0
  70. package/esm2015/src/render3/styling/style_binding_list.js +437 -0
  71. package/esm2015/src/render3/styling/styling_parser.js +336 -0
  72. package/esm2015/src/render3/tokens.js +2 -2
  73. package/esm2015/src/render3/util/attrs_utils.js +125 -2
  74. package/esm2015/src/render3/util/change_detection_utils.js +33 -0
  75. package/esm2015/src/render3/util/discovery_utils.js +146 -119
  76. package/esm2015/src/render3/util/global_utils.js +5 -5
  77. package/esm2015/src/render3/util/view_utils.js +6 -6
  78. package/esm2015/src/render3/view_engine_compatibility.js +16 -17
  79. package/esm2015/src/render3/view_ref.js +16 -13
  80. package/esm2015/src/sanitization/bypass.js +1 -1
  81. package/esm2015/src/sanitization/sanitization.js +20 -5
  82. package/esm2015/src/util/array_utils.js +240 -1
  83. package/esm2015/src/util/assert.js +37 -21
  84. package/esm2015/src/util/char_code.js +8 -0
  85. package/esm2015/src/util/iterable.js +4 -1
  86. package/esm2015/src/util/ng_dev_mode.js +1 -12
  87. package/esm2015/src/util/stringify.js +14 -1
  88. package/esm2015/src/version.js +1 -1
  89. package/esm2015/testing/src/r3_test_bed.js +5 -1
  90. package/esm2015/testing/src/r3_test_bed_compiler.js +2 -12
  91. package/esm2015/testing/src/styling.js +103 -0
  92. package/esm5/core.js +17 -17
  93. package/esm5/src/application_ref.js +6 -6
  94. package/esm5/src/core_private_export.js +7 -7
  95. package/esm5/src/core_render3_private_export.js +2 -2
  96. package/esm5/src/debug/debug_node.js +29 -11
  97. package/esm5/src/i18n/locale_data_api.js +1 -2
  98. package/esm5/src/interface/type.js +1 -1
  99. package/esm5/src/metadata/ng_module.js +1 -1
  100. package/esm5/src/render/api.js +4 -1
  101. package/esm5/src/render3/assert.js +4 -1
  102. package/esm5/src/render3/bindings.js +19 -2
  103. package/esm5/src/render3/component.js +47 -22
  104. package/esm5/src/render3/component_ref.js +9 -14
  105. package/esm5/src/render3/definition.js +3 -1
  106. package/esm5/src/render3/di.js +3 -4
  107. package/esm5/src/render3/di_setup.js +4 -5
  108. package/esm5/src/render3/errors.js +3 -1
  109. package/esm5/src/render3/features/inherit_definition_feature.js +36 -12
  110. package/esm5/src/render3/features/ng_onchanges_feature.js +1 -1
  111. package/esm5/src/render3/global_utils_api.js +3 -3
  112. package/esm5/src/render3/i18n.js +51 -51
  113. package/esm5/src/render3/index.js +2 -2
  114. package/esm5/src/render3/instructions/advance.js +9 -11
  115. package/esm5/src/render3/instructions/all.js +1 -2
  116. package/esm5/src/render3/instructions/attribute.js +5 -6
  117. package/esm5/src/render3/instructions/attribute_interpolation.js +31 -21
  118. package/esm5/src/render3/instructions/change_detection.js +8 -21
  119. package/esm5/src/render3/instructions/class_map_interpolation.js +13 -12
  120. package/esm5/src/render3/instructions/container.js +13 -12
  121. package/esm5/src/render3/instructions/element.js +36 -108
  122. package/esm5/src/render3/instructions/element_container.js +8 -9
  123. package/esm5/src/render3/instructions/embedded_view.js +7 -7
  124. package/esm5/src/render3/instructions/host_property.js +8 -7
  125. package/esm5/src/render3/instructions/listener.js +13 -13
  126. package/esm5/src/render3/instructions/lview_debug.js +56 -15
  127. package/esm5/src/render3/instructions/projection.js +6 -5
  128. package/esm5/src/render3/instructions/property.js +17 -6
  129. package/esm5/src/render3/instructions/property_interpolation.js +31 -23
  130. package/esm5/src/render3/instructions/shared.js +247 -207
  131. package/esm5/src/render3/instructions/storage.js +4 -6
  132. package/esm5/src/render3/instructions/style_prop_interpolation.js +12 -12
  133. package/esm5/src/render3/instructions/styling.js +685 -367
  134. package/esm5/src/render3/instructions/text.js +5 -5
  135. package/esm5/src/render3/interfaces/definition.js +1 -1
  136. package/esm5/src/render3/interfaces/node.js +49 -1
  137. package/esm5/src/render3/interfaces/styling.js +57 -1
  138. package/esm5/src/render3/interfaces/view.js +1 -1
  139. package/esm5/src/render3/jit/environment.js +1 -3
  140. package/esm5/src/render3/node_manipulation.js +167 -54
  141. package/esm5/src/render3/node_selector_matcher.js +40 -20
  142. package/esm5/src/render3/node_util.js +12 -7
  143. package/esm5/src/render3/pipe.js +4 -6
  144. package/esm5/src/render3/query.js +25 -24
  145. package/esm5/src/render3/state.js +34 -131
  146. package/esm5/src/render3/styling/class_differ.js +39 -0
  147. package/esm5/src/render3/styling/static_styling.js +42 -0
  148. package/esm5/src/render3/styling/style_binding_list.js +411 -0
  149. package/esm5/src/render3/styling/styling_parser.js +265 -0
  150. package/esm5/src/render3/tokens.js +2 -2
  151. package/esm5/src/render3/util/attrs_utils.js +117 -2
  152. package/esm5/src/render3/util/change_detection_utils.js +23 -0
  153. package/esm5/src/render3/util/discovery_utils.js +115 -99
  154. package/esm5/src/render3/util/global_utils.js +5 -5
  155. package/esm5/src/render3/util/view_utils.js +5 -5
  156. package/esm5/src/render3/view_engine_compatibility.js +37 -39
  157. package/esm5/src/render3/view_ref.js +14 -13
  158. package/esm5/src/sanitization/bypass.js +1 -1
  159. package/esm5/src/sanitization/sanitization.js +16 -5
  160. package/esm5/src/util/array_utils.js +240 -1
  161. package/esm5/src/util/assert.js +37 -21
  162. package/esm5/src/util/char_code.js +8 -0
  163. package/esm5/src/util/iterable.js +4 -1
  164. package/esm5/src/util/ng_dev_mode.js +1 -12
  165. package/esm5/src/util/stringify.js +14 -1
  166. package/esm5/src/version.js +1 -1
  167. package/esm5/testing/src/r3_test_bed.js +9 -1
  168. package/esm5/testing/src/r3_test_bed_compiler.js +2 -9
  169. package/esm5/testing/src/styling.js +82 -0
  170. package/fesm2015/core.js +5917 -6880
  171. package/fesm2015/core.js.map +1 -1
  172. package/fesm2015/testing.js +6 -12
  173. package/fesm2015/testing.js.map +1 -1
  174. package/fesm5/core.js +3588 -3884
  175. package/fesm5/core.js.map +1 -1
  176. package/fesm5/testing.js +10 -9
  177. package/fesm5/testing.js.map +1 -1
  178. package/package.json +1 -1
  179. package/src/r3_symbols.d.ts +1 -1
  180. package/testing/testing.d.ts +1 -3
  181. package/testing/testing.metadata.json +1 -1
  182. package/testing.d.ts +1 -1
  183. package/esm2015/global.js +0 -7
  184. package/esm2015/src/render3/instructions/alloc_host_vars.js +0 -80
  185. package/esm2015/src/render3/styling/bindings.js +0 -1248
  186. package/esm2015/src/render3/styling/map_based_bindings.js +0 -384
  187. package/esm2015/src/render3/styling/state.js +0 -135
  188. package/esm2015/src/render3/styling/styling_debug.js +0 -655
  189. package/esm2015/src/render3/util/styling_utils.js +0 -625
  190. package/esm5/global.js +0 -9
  191. package/esm5/src/render3/instructions/alloc_host_vars.js +0 -62
  192. package/esm5/src/render3/styling/bindings.js +0 -949
  193. package/esm5/src/render3/styling/map_based_bindings.js +0 -310
  194. package/esm5/src/render3/styling/state.js +0 -56
  195. package/esm5/src/render3/styling/styling_debug.js +0 -315
  196. package/esm5/src/render3/util/styling_utils.js +0 -378
@@ -0,0 +1,54 @@
1
+ /**
2
+ * @fileoverview added by tsickle
3
+ * Generated from: packages/core/src/render3/styling/static_styling.ts
4
+ * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
+ */
6
+ /**
7
+ * @license
8
+ * Copyright Google Inc. All Rights Reserved.
9
+ *
10
+ * Use of this source code is governed by an MIT-style license that can be
11
+ * found in the LICENSE file at https://angular.io/license
12
+ */
13
+ import { concatStringsWithSpace } from '../../util/stringify';
14
+ import { assertFirstCreatePass } from '../assert';
15
+ import { getTView } from '../state';
16
+ /**
17
+ * Compute the static styling (class/style) from `TAttributes`.
18
+ *
19
+ * This function should be called during `firstCreatePass` only.
20
+ *
21
+ * @param {?} tNode The `TNode` into which the styling information should be loaded.
22
+ * @param {?} attrs `TAttributes` containing the styling information.
23
+ * @return {?}
24
+ */
25
+ export function computeStaticStyling(tNode, attrs) {
26
+ ngDevMode &&
27
+ assertFirstCreatePass(getTView(), 'Expecting to be called in first template pass only');
28
+ /** @type {?} */
29
+ let styles = tNode.styles;
30
+ /** @type {?} */
31
+ let classes = tNode.classes;
32
+ /** @type {?} */
33
+ let mode = 0;
34
+ for (let i = 0; i < attrs.length; i++) {
35
+ /** @type {?} */
36
+ const value = attrs[i];
37
+ if (typeof value === 'number') {
38
+ mode = value;
39
+ }
40
+ else if (mode == 1 /* Classes */) {
41
+ classes = concatStringsWithSpace(classes, (/** @type {?} */ (value)));
42
+ }
43
+ else if (mode == 2 /* Styles */) {
44
+ /** @type {?} */
45
+ const style = (/** @type {?} */ (value));
46
+ /** @type {?} */
47
+ const styleValue = (/** @type {?} */ (attrs[++i]));
48
+ styles = concatStringsWithSpace(styles, style + ': ' + styleValue + ';');
49
+ }
50
+ }
51
+ styles !== null && (tNode.styles = styles);
52
+ classes !== null && (tNode.classes = classes);
53
+ }
54
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3RhdGljX3N0eWxpbmcuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi8uLi8uLi9wYWNrYWdlcy9jb3JlL3NyYy9yZW5kZXIzL3N0eWxpbmcvc3RhdGljX3N0eWxpbmcudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7O0FBUUEsT0FBTyxFQUFDLHNCQUFzQixFQUFDLE1BQU0sc0JBQXNCLENBQUM7QUFDNUQsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sV0FBVyxDQUFDO0FBRWhELE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxVQUFVLENBQUM7Ozs7Ozs7Ozs7QUFVbEMsTUFBTSxVQUFVLG9CQUFvQixDQUFDLEtBQVksRUFBRSxLQUFrQjtJQUNuRSxTQUFTO1FBQ0wscUJBQXFCLENBQUMsUUFBUSxFQUFFLEVBQUUsb0RBQW9ELENBQUMsQ0FBQzs7UUFDeEYsTUFBTSxHQUFnQixLQUFLLENBQUMsTUFBTTs7UUFDbEMsT0FBTyxHQUFnQixLQUFLLENBQUMsT0FBTzs7UUFDcEMsSUFBSSxHQUFzQixDQUFDO0lBQy9CLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFOztjQUMvQixLQUFLLEdBQUcsS0FBSyxDQUFDLENBQUMsQ0FBQztRQUN0QixJQUFJLE9BQU8sS0FBSyxLQUFLLFFBQVEsRUFBRTtZQUM3QixJQUFJLEdBQUcsS0FBSyxDQUFDO1NBQ2Q7YUFBTSxJQUFJLElBQUksbUJBQTJCLEVBQUU7WUFDMUMsT0FBTyxHQUFHLHNCQUFzQixDQUFDLE9BQU8sRUFBRSxtQkFBQSxLQUFLLEVBQVUsQ0FBQyxDQUFDO1NBQzVEO2FBQU0sSUFBSSxJQUFJLGtCQUEwQixFQUFFOztrQkFDbkMsS0FBSyxHQUFHLG1CQUFBLEtBQUssRUFBVTs7a0JBQ3ZCLFVBQVUsR0FBRyxtQkFBQSxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBVTtZQUN2QyxNQUFNLEdBQUcsc0JBQXNCLENBQUMsTUFBTSxFQUFFLEtBQUssR0FBRyxJQUFJLEdBQUcsVUFBVSxHQUFHLEdBQUcsQ0FBQyxDQUFDO1NBQzFFO0tBQ0Y7SUFDRCxNQUFNLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQztJQUMzQyxPQUFPLEtBQUssSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sR0FBRyxPQUFPLENBQUMsQ0FBQztBQUNoRCxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4qIEBsaWNlbnNlXG4qIENvcHlyaWdodCBHb29nbGUgSW5jLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxuKlxuKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4qL1xuXG5pbXBvcnQge2NvbmNhdFN0cmluZ3NXaXRoU3BhY2V9IGZyb20gJy4uLy4uL3V0aWwvc3RyaW5naWZ5JztcbmltcG9ydCB7YXNzZXJ0Rmlyc3RDcmVhdGVQYXNzfSBmcm9tICcuLi9hc3NlcnQnO1xuaW1wb3J0IHtBdHRyaWJ1dGVNYXJrZXIsIFRBdHRyaWJ1dGVzLCBUTm9kZX0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ub2RlJztcbmltcG9ydCB7Z2V0VFZpZXd9IGZyb20gJy4uL3N0YXRlJztcblxuLyoqXG4gKiBDb21wdXRlIHRoZSBzdGF0aWMgc3R5bGluZyAoY2xhc3Mvc3R5bGUpIGZyb20gYFRBdHRyaWJ1dGVzYC5cbiAqXG4gKiBUaGlzIGZ1bmN0aW9uIHNob3VsZCBiZSBjYWxsZWQgZHVyaW5nIGBmaXJzdENyZWF0ZVBhc3NgIG9ubHkuXG4gKlxuICogQHBhcmFtIHROb2RlIFRoZSBgVE5vZGVgIGludG8gd2hpY2ggdGhlIHN0eWxpbmcgaW5mb3JtYXRpb24gc2hvdWxkIGJlIGxvYWRlZC5cbiAqIEBwYXJhbSBhdHRycyBgVEF0dHJpYnV0ZXNgIGNvbnRhaW5pbmcgdGhlIHN0eWxpbmcgaW5mb3JtYXRpb24uXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlU3RhdGljU3R5bGluZyh0Tm9kZTogVE5vZGUsIGF0dHJzOiBUQXR0cmlidXRlcyk6IHZvaWQge1xuICBuZ0Rldk1vZGUgJiZcbiAgICAgIGFzc2VydEZpcnN0Q3JlYXRlUGFzcyhnZXRUVmlldygpLCAnRXhwZWN0aW5nIHRvIGJlIGNhbGxlZCBpbiBmaXJzdCB0ZW1wbGF0ZSBwYXNzIG9ubHknKTtcbiAgbGV0IHN0eWxlczogc3RyaW5nfG51bGwgPSB0Tm9kZS5zdHlsZXM7XG4gIGxldCBjbGFzc2VzOiBzdHJpbmd8bnVsbCA9IHROb2RlLmNsYXNzZXM7XG4gIGxldCBtb2RlOiBBdHRyaWJ1dGVNYXJrZXJ8MCA9IDA7XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXR0cnMubGVuZ3RoOyBpKyspIHtcbiAgICBjb25zdCB2YWx1ZSA9IGF0dHJzW2ldO1xuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICBtb2RlID0gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChtb2RlID09IEF0dHJpYnV0ZU1hcmtlci5DbGFzc2VzKSB7XG4gICAgICBjbGFzc2VzID0gY29uY2F0U3RyaW5nc1dpdGhTcGFjZShjbGFzc2VzLCB2YWx1ZSBhcyBzdHJpbmcpO1xuICAgIH0gZWxzZSBpZiAobW9kZSA9PSBBdHRyaWJ1dGVNYXJrZXIuU3R5bGVzKSB7XG4gICAgICBjb25zdCBzdHlsZSA9IHZhbHVlIGFzIHN0cmluZztcbiAgICAgIGNvbnN0IHN0eWxlVmFsdWUgPSBhdHRyc1srK2ldIGFzIHN0cmluZztcbiAgICAgIHN0eWxlcyA9IGNvbmNhdFN0cmluZ3NXaXRoU3BhY2Uoc3R5bGVzLCBzdHlsZSArICc6ICcgKyBzdHlsZVZhbHVlICsgJzsnKTtcbiAgICB9XG4gIH1cbiAgc3R5bGVzICE9PSBudWxsICYmICh0Tm9kZS5zdHlsZXMgPSBzdHlsZXMpO1xuICBjbGFzc2VzICE9PSBudWxsICYmICh0Tm9kZS5jbGFzc2VzID0gY2xhc3Nlcyk7XG59Il19
@@ -0,0 +1,437 @@
1
+ /**
2
+ * @fileoverview added by tsickle
3
+ * Generated from: packages/core/src/render3/styling/style_binding_list.ts
4
+ * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
5
+ */
6
+ /**
7
+ * @license
8
+ * Copyright Google Inc. All Rights Reserved.
9
+ *
10
+ * Use of this source code is governed by an MIT-style license that can be
11
+ * found in the LICENSE file at https://angular.io/license
12
+ */
13
+ import { keyValueArrayIndexOf } from '../../util/array_utils';
14
+ import { assertDataInRange, assertEqual, assertNotEqual } from '../../util/assert';
15
+ import { assertFirstUpdatePass } from '../assert';
16
+ import { getTStylingRangeNext, getTStylingRangePrev, setTStylingRangeNext, setTStylingRangeNextDuplicate, setTStylingRangePrev, setTStylingRangePrevDuplicate, toTStylingRange } from '../interfaces/styling';
17
+ import { getTView } from '../state';
18
+ /**
19
+ * NOTE: The word `styling` is used interchangeably as style or class styling.
20
+ *
21
+ * This file contains code to link styling instructions together so that they can be replayed in
22
+ * priority order. The file exists because Ivy styling instruction execution order does not match
23
+ * that of the priority order. The purpose of this code is to create a linked list so that the
24
+ * instructions can be traversed in priority order when computing the styles.
25
+ *
26
+ * Assume we are dealing with the following code:
27
+ * ```
28
+ * \@Component({
29
+ * template: `
30
+ * <my-cmp [style]=" {color: '#001'} "
31
+ * [style.color]=" #002 "
32
+ * dir-style-color-1
33
+ * dir-style-color-2> `
34
+ * })
35
+ * class ExampleComponent {
36
+ * static ngComp = ... {
37
+ * ...
38
+ * // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
39
+ * ɵɵstyleMap({color: '#001'});
40
+ * ɵɵstyleProp('color', '#002');
41
+ * ...
42
+ * }
43
+ * }
44
+ *
45
+ * \@Directive({
46
+ * selector: `[dir-style-color-1]',
47
+ * })
48
+ * class Style1Directive {
49
+ * \@HostBinding('style') style = {color: '#005'};
50
+ * \@HostBinding('style.color') color = '#006';
51
+ *
52
+ * static ngDir = ... {
53
+ * ...
54
+ * // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
55
+ * ɵɵstyleMap({color: '#005'});
56
+ * ɵɵstyleProp('color', '#006');
57
+ * ...
58
+ * }
59
+ * }
60
+ *
61
+ * \@Directive({
62
+ * selector: `[dir-style-color-2]',
63
+ * })
64
+ * class Style2Directive {
65
+ * \@HostBinding('style') style = {color: '#007'};
66
+ * \@HostBinding('style.color') color = '#008';
67
+ *
68
+ * static ngDir = ... {
69
+ * ...
70
+ * // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
71
+ * ɵɵstyleMap({color: '#007'});
72
+ * ɵɵstyleProp('color', '#008');
73
+ * ...
74
+ * }
75
+ * }
76
+ *
77
+ * \@Directive({
78
+ * selector: `my-cmp',
79
+ * })
80
+ * class MyComponent {
81
+ * \@HostBinding('style') style = {color: '#003'};
82
+ * \@HostBinding('style.color') color = '#004';
83
+ *
84
+ * static ngComp = ... {
85
+ * ...
86
+ * // Compiler ensures that `ɵɵstyleProp` is after `ɵɵstyleMap`
87
+ * ɵɵstyleMap({color: '#003'});
88
+ * ɵɵstyleProp('color', '#004');
89
+ * ...
90
+ * }
91
+ * }
92
+ * ```
93
+ *
94
+ * The Order of instruction execution is:
95
+ *
96
+ * NOTE: the comment binding location is for illustrative purposes only.
97
+ *
98
+ * ```
99
+ * // Template: (ExampleComponent)
100
+ * ɵɵstyleMap({color: '#001'}); // Binding index: 10
101
+ * ɵɵstyleProp('color', '#002'); // Binding index: 12
102
+ * // MyComponent
103
+ * ɵɵstyleMap({color: '#003'}); // Binding index: 20
104
+ * ɵɵstyleProp('color', '#004'); // Binding index: 22
105
+ * // Style1Directive
106
+ * ɵɵstyleMap({color: '#005'}); // Binding index: 24
107
+ * ɵɵstyleProp('color', '#006'); // Binding index: 26
108
+ * // Style2Directive
109
+ * ɵɵstyleMap({color: '#007'}); // Binding index: 28
110
+ * ɵɵstyleProp('color', '#008'); // Binding index: 30
111
+ * ```
112
+ *
113
+ * The correct priority order of concatenation is:
114
+ *
115
+ * ```
116
+ * // MyComponent
117
+ * ɵɵstyleMap({color: '#003'}); // Binding index: 20
118
+ * ɵɵstyleProp('color', '#004'); // Binding index: 22
119
+ * // Style1Directive
120
+ * ɵɵstyleMap({color: '#005'}); // Binding index: 24
121
+ * ɵɵstyleProp('color', '#006'); // Binding index: 26
122
+ * // Style2Directive
123
+ * ɵɵstyleMap({color: '#007'}); // Binding index: 28
124
+ * ɵɵstyleProp('color', '#008'); // Binding index: 30
125
+ * // Template: (ExampleComponent)
126
+ * ɵɵstyleMap({color: '#001'}); // Binding index: 10
127
+ * ɵɵstyleProp('color', '#002'); // Binding index: 12
128
+ * ```
129
+ *
130
+ * What color should be rendered?
131
+ *
132
+ * Once the items are correctly sorted in the list, the answer is simply the last item in the
133
+ * concatenation list which is `#002`.
134
+ *
135
+ * To do so we keep a linked list of all of the bindings which pertain to this element.
136
+ * Notice that the bindings are inserted in the order of execution, but the `TView.data` allows
137
+ * us to traverse them in the order of priority.
138
+ *
139
+ * |Idx|`TView.data`|`LView` | Notes
140
+ * |---|------------|-----------------|--------------
141
+ * |...| | |
142
+ * |10 |`null` |`{color: '#001'}`| `ɵɵstyleMap('color', {color: '#001'})`
143
+ * |11 |`30 | 12` | ... |
144
+ * |12 |`color` |`'#002'` | `ɵɵstyleProp('color', '#002')`
145
+ * |13 |`10 | 0` | ... |
146
+ * |...| | |
147
+ * |20 |`null` |`{color: '#003'}`| `ɵɵstyleMap('color', {color: '#003'})`
148
+ * |21 |`0 | 22` | ... |
149
+ * |22 |`color` |`'#004'` | `ɵɵstyleProp('color', '#004')`
150
+ * |23 |`20 | 24` | ... |
151
+ * |24 |`null` |`{color: '#005'}`| `ɵɵstyleMap('color', {color: '#005'})`
152
+ * |25 |`22 | 26` | ... |
153
+ * |26 |`color` |`'#006'` | `ɵɵstyleProp('color', '#006')`
154
+ * |27 |`24 | 28` | ... |
155
+ * |28 |`null` |`{color: '#007'}`| `ɵɵstyleMap('color', {color: '#007'})`
156
+ * |29 |`26 | 30` | ... |
157
+ * |30 |`color` |`'#008'` | `ɵɵstyleProp('color', '#008')`
158
+ * |31 |`28 | 10` | ... |
159
+ *
160
+ * The above data structure allows us to re-concatenate the styling no matter which data binding
161
+ * changes.
162
+ *
163
+ * NOTE: in addition to keeping track of next/previous index the `TView.data` also stores prev/next
164
+ * duplicate bit. The duplicate bit if true says there either is a binding with the same name or
165
+ * there is a map (which may contain the name). This information is useful in knowing if other
166
+ * styles with higher priority need to be searched for overwrites.
167
+ *
168
+ * NOTE: See `should support example in 'tnode_linked_list.ts' documentation` in
169
+ * `tnode_linked_list_spec.ts` for working example.
170
+ * @type {?}
171
+ */
172
+ let __unused_const_as_closure_does_not_like_standalone_comment_blocks__;
173
+ /**
174
+ * Insert new `tStyleValue` at `TData` and link existing style bindings such that we maintain linked
175
+ * list of styles and compute the duplicate flag.
176
+ *
177
+ * Note: this function is executed during `firstUpdatePass` only to populate the `TView.data`.
178
+ *
179
+ * The function works by keeping track of `tStylingRange` which contains two pointers pointing to
180
+ * the head/tail of the template portion of the styles.
181
+ * - if `isHost === false` (we are template) then insertion is at tail of `TStylingRange`
182
+ * - if `isHost === true` (we are host binding) then insertion is at head of `TStylingRange`
183
+ *
184
+ * @param {?} tData The `TData` to insert into.
185
+ * @param {?} tNode `TNode` associated with the styling element.
186
+ * @param {?} tStylingKeyWithStatic
187
+ * @param {?} index location of where `tStyleValue` should be stored (and linked into list.)
188
+ * @param {?} isHostBinding `true` if the insertion is for a `hostBinding`. (insertion is in front of
189
+ * template.)
190
+ * @param {?} isClassBinding True if the associated `tStylingKey` as a `class` styling.
191
+ * `tNode.classBindings` should be used (or `tNode.styleBindings` otherwise.)
192
+ * @return {?}
193
+ */
194
+ export function insertTStylingBinding(tData, tNode, tStylingKeyWithStatic, index, isHostBinding, isClassBinding) {
195
+ ngDevMode && assertFirstUpdatePass(getTView());
196
+ /** @type {?} */
197
+ let tBindings = isClassBinding ? tNode.classBindings : tNode.styleBindings;
198
+ /** @type {?} */
199
+ let tmplHead = getTStylingRangePrev(tBindings);
200
+ /** @type {?} */
201
+ let tmplTail = getTStylingRangeNext(tBindings);
202
+ tData[index] = tStylingKeyWithStatic;
203
+ /** @type {?} */
204
+ let isKeyDuplicateOfStatic = false;
205
+ /** @type {?} */
206
+ let tStylingKey;
207
+ if (Array.isArray(tStylingKeyWithStatic)) {
208
+ // We are case when the `TStylingKey` contains static fields as well.
209
+ /** @type {?} */
210
+ const staticKeyValueArray = (/** @type {?} */ (tStylingKeyWithStatic));
211
+ tStylingKey = staticKeyValueArray[1]; // unwrap.
212
+ // We need to check if our key is present in the static so that we can mark it as duplicate.
213
+ if (tStylingKey === null ||
214
+ keyValueArrayIndexOf(staticKeyValueArray, (/** @type {?} */ (tStylingKey))) > 0) {
215
+ // tStylingKey is present in the statics, need to mark it as duplicate.
216
+ isKeyDuplicateOfStatic = true;
217
+ }
218
+ }
219
+ else {
220
+ tStylingKey = tStylingKeyWithStatic;
221
+ }
222
+ if (isHostBinding) {
223
+ // We are inserting host bindings
224
+ // If we don't have template bindings then `tail` is 0.
225
+ /** @type {?} */
226
+ const hasTemplateBindings = tmplTail !== 0;
227
+ // This is important to know because that means that the `head` can't point to the first
228
+ // template bindings (there are none.) Instead the head points to the tail of the template.
229
+ if (hasTemplateBindings) {
230
+ // template head's "prev" will point to last host binding or to 0 if no host bindings yet
231
+ /** @type {?} */
232
+ const previousNode = getTStylingRangePrev((/** @type {?} */ (tData[tmplHead + 1])));
233
+ tData[index + 1] = toTStylingRange(previousNode, tmplHead);
234
+ // if a host binding has already been registered, we need to update the next of that host
235
+ // binding to point to this one
236
+ if (previousNode !== 0) {
237
+ // We need to update the template-tail value to point to us.
238
+ tData[previousNode + 1] =
239
+ setTStylingRangeNext((/** @type {?} */ (tData[previousNode + 1])), index);
240
+ }
241
+ // The "previous" of the template binding head should point to this host binding
242
+ tData[tmplHead + 1] = setTStylingRangePrev((/** @type {?} */ (tData[tmplHead + 1])), index);
243
+ }
244
+ else {
245
+ tData[index + 1] = toTStylingRange(tmplHead, 0);
246
+ // if a host binding has already been registered, we need to update the next of that host
247
+ // binding to point to this one
248
+ if (tmplHead !== 0) {
249
+ // We need to update the template-tail value to point to us.
250
+ tData[tmplHead + 1] = setTStylingRangeNext((/** @type {?} */ (tData[tmplHead + 1])), index);
251
+ }
252
+ // if we don't have template, the head points to template-tail, and needs to be advanced.
253
+ tmplHead = index;
254
+ }
255
+ }
256
+ else {
257
+ // We are inserting in template section.
258
+ // We need to set this binding's "previous" to the current template tail
259
+ tData[index + 1] = toTStylingRange(tmplTail, 0);
260
+ ngDevMode && assertEqual(tmplHead !== 0 && tmplTail === 0, false, 'Adding template bindings after hostBindings is not allowed.');
261
+ if (tmplHead === 0) {
262
+ tmplHead = index;
263
+ }
264
+ else {
265
+ // We need to update the previous value "next" to point to this binding
266
+ tData[tmplTail + 1] = setTStylingRangeNext((/** @type {?} */ (tData[tmplTail + 1])), index);
267
+ }
268
+ tmplTail = index;
269
+ }
270
+ // Now we need to update / compute the duplicates.
271
+ // Starting with our location search towards head (least priority)
272
+ if (isKeyDuplicateOfStatic) {
273
+ tData[index + 1] = setTStylingRangePrevDuplicate((/** @type {?} */ (tData[index + 1])));
274
+ }
275
+ markDuplicates(tData, tStylingKey, index, true, isClassBinding);
276
+ markDuplicates(tData, tStylingKey, index, false, isClassBinding);
277
+ markDuplicateOfResidualStyling(tNode, tStylingKey, tData, index, isClassBinding);
278
+ tBindings = toTStylingRange(tmplHead, tmplTail);
279
+ if (isClassBinding) {
280
+ tNode.classBindings = tBindings;
281
+ }
282
+ else {
283
+ tNode.styleBindings = tBindings;
284
+ }
285
+ }
286
+ /**
287
+ * Look into the residual styling to see if the current `tStylingKey` is duplicate of residual.
288
+ *
289
+ * @param {?} tNode `TNode` where the residual is stored.
290
+ * @param {?} tStylingKey `TStylingKey` to store.
291
+ * @param {?} tData `TData` associated with the current `LView`.
292
+ * @param {?} index location of where `tStyleValue` should be stored (and linked into list.)
293
+ * @param {?} isClassBinding True if the associated `tStylingKey` as a `class` styling.
294
+ * `tNode.classBindings` should be used (or `tNode.styleBindings` otherwise.)
295
+ * @return {?}
296
+ */
297
+ function markDuplicateOfResidualStyling(tNode, tStylingKey, tData, index, isClassBinding) {
298
+ /** @type {?} */
299
+ const residual = isClassBinding ? tNode.residualClasses : tNode.residualStyles;
300
+ if (residual != null /* or undefined */ && typeof tStylingKey == 'string' &&
301
+ keyValueArrayIndexOf(residual, tStylingKey) >= 0) {
302
+ // We have duplicate in the residual so mark ourselves as duplicate.
303
+ tData[index + 1] = setTStylingRangeNextDuplicate((/** @type {?} */ (tData[index + 1])));
304
+ }
305
+ }
306
+ /**
307
+ * Marks `TStyleValue`s as duplicates if another style binding in the list has the same
308
+ * `TStyleValue`.
309
+ *
310
+ * NOTE: this function is intended to be called twice once with `isPrevDir` set to `true` and once
311
+ * with it set to `false` to search both the previous as well as next items in the list.
312
+ *
313
+ * No duplicate case
314
+ * ```
315
+ * [style.color]
316
+ * [style.width.px] <<- index
317
+ * [style.height.px]
318
+ * ```
319
+ *
320
+ * In the above case adding `[style.width.px]` to the existing `[style.color]` produces no
321
+ * duplicates because `width` is not found in any other part of the linked list.
322
+ *
323
+ * Duplicate case
324
+ * ```
325
+ * [style.color]
326
+ * [style.width.em]
327
+ * [style.width.px] <<- index
328
+ * ```
329
+ * In the above case adding `[style.width.px]` will produce a duplicate with `[style.width.em]`
330
+ * because `width` is found in the chain.
331
+ *
332
+ * Map case 1
333
+ * ```
334
+ * [style.width.px]
335
+ * [style.color]
336
+ * [style] <<- index
337
+ * ```
338
+ * In the above case adding `[style]` will produce a duplicate with any other bindings because
339
+ * `[style]` is a Map and as such is fully dynamic and could produce `color` or `width`.
340
+ *
341
+ * Map case 2
342
+ * ```
343
+ * [style]
344
+ * [style.width.px]
345
+ * [style.color] <<- index
346
+ * ```
347
+ * In the above case adding `[style.color]` will produce a duplicate because there is already a
348
+ * `[style]` binding which is a Map and as such is fully dynamic and could produce `color` or
349
+ * `width`.
350
+ *
351
+ * NOTE: Once `[style]` (Map) is added into the system all things are mapped as duplicates.
352
+ * NOTE: We use `style` as example, but same logic is applied to `class`es as well.
353
+ *
354
+ * @param {?} tData `TData` where the linked list is stored.
355
+ * @param {?} tStylingKey `TStylingKeyPrimitive` which contains the value to compare to other keys in
356
+ * the linked list.
357
+ * @param {?} index Starting location in the linked list to search from
358
+ * @param {?} isPrevDir Direction.
359
+ * - `true` for previous (lower priority);
360
+ * - `false` for next (higher priority).
361
+ * @param {?} isClassBinding
362
+ * @return {?}
363
+ */
364
+ function markDuplicates(tData, tStylingKey, index, isPrevDir, isClassBinding) {
365
+ /** @type {?} */
366
+ const tStylingAtIndex = (/** @type {?} */ (tData[index + 1]));
367
+ /** @type {?} */
368
+ const isMap = tStylingKey === null;
369
+ /** @type {?} */
370
+ let cursor = isPrevDir ? getTStylingRangePrev(tStylingAtIndex) : getTStylingRangeNext(tStylingAtIndex);
371
+ /** @type {?} */
372
+ let foundDuplicate = false;
373
+ // We keep iterating as long as we have a cursor
374
+ // AND either:
375
+ // - we found what we are looking for, OR
376
+ // - we are a map in which case we have to continue searching even after we find what we were
377
+ // looking for since we are a wild card and everything needs to be flipped to duplicate.
378
+ while (cursor !== 0 && (foundDuplicate === false || isMap)) {
379
+ ngDevMode && assertDataInRange(tData, cursor);
380
+ /** @type {?} */
381
+ const tStylingValueAtCursor = (/** @type {?} */ (tData[cursor]));
382
+ /** @type {?} */
383
+ const tStyleRangeAtCursor = (/** @type {?} */ (tData[cursor + 1]));
384
+ if (isStylingMatch(tStylingValueAtCursor, tStylingKey)) {
385
+ foundDuplicate = true;
386
+ tData[cursor + 1] = isPrevDir ? setTStylingRangeNextDuplicate(tStyleRangeAtCursor) :
387
+ setTStylingRangePrevDuplicate(tStyleRangeAtCursor);
388
+ }
389
+ cursor = isPrevDir ? getTStylingRangePrev(tStyleRangeAtCursor) :
390
+ getTStylingRangeNext(tStyleRangeAtCursor);
391
+ }
392
+ if (foundDuplicate) {
393
+ // if we found a duplicate, than mark ourselves.
394
+ tData[index + 1] = isPrevDir ? setTStylingRangePrevDuplicate(tStylingAtIndex) :
395
+ setTStylingRangeNextDuplicate(tStylingAtIndex);
396
+ }
397
+ }
398
+ /**
399
+ * Determines if two `TStylingKey`s are a match.
400
+ *
401
+ * When computing weather a binding contains a duplicate, we need to compare if the instruction
402
+ * `TStylingKey` has a match.
403
+ *
404
+ * Here are examples of `TStylingKey`s which match given `tStylingKeyCursor` is:
405
+ * - `color`
406
+ * - `color` // Match another color
407
+ * - `null` // That means that `tStylingKey` is a `classMap`/`styleMap` instruction
408
+ * - `['', 'color', 'other', true]` // wrapped `color` so match
409
+ * - `['', null, 'other', true]` // wrapped `null` so match
410
+ * - `['', 'width', 'color', 'value']` // wrapped static value contains a match on `'color'`
411
+ * - `null` // `tStylingKeyCursor` always match as it is `classMap`/`styleMap` instruction
412
+ *
413
+ * @param {?} tStylingKeyCursor
414
+ * @param {?} tStylingKey
415
+ * @return {?}
416
+ */
417
+ function isStylingMatch(tStylingKeyCursor, tStylingKey) {
418
+ ngDevMode &&
419
+ assertNotEqual(Array.isArray(tStylingKey), true, 'Expected that \'tStylingKey\' has been unwrapped');
420
+ if (tStylingKeyCursor === null || // If the cursor is `null` it means that we have map at that
421
+ // location so we must assume that we have a match.
422
+ tStylingKey == null || // If `tStylingKey` is `null` then it is a map therefor assume that it
423
+ // contains a match.
424
+ (Array.isArray(tStylingKeyCursor) ? tStylingKeyCursor[1] : tStylingKeyCursor) ===
425
+ tStylingKey // If the keys match explicitly than we are a match.
426
+ ) {
427
+ return true;
428
+ }
429
+ else if (Array.isArray(tStylingKeyCursor) && typeof tStylingKey === 'string') {
430
+ // if we did not find a match, but `tStylingKeyCursor` is `KeyValueArray` that means cursor has
431
+ // statics and we need to check those as well.
432
+ return keyValueArrayIndexOf(tStylingKeyCursor, tStylingKey) >=
433
+ 0; // see if we are matching the key
434
+ }
435
+ return false;
436
+ }
437
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic3R5bGVfYmluZGluZ19saXN0LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvY29yZS9zcmMvcmVuZGVyMy9zdHlsaW5nL3N0eWxlX2JpbmRpbmdfbGlzdC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFRQSxPQUFPLEVBQWdCLG9CQUFvQixFQUFDLE1BQU0sd0JBQXdCLENBQUM7QUFDM0UsT0FBTyxFQUFDLGlCQUFpQixFQUFFLFdBQVcsRUFBRSxjQUFjLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUNqRixPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSxXQUFXLENBQUM7QUFFaEQsT0FBTyxFQUFtRCxvQkFBb0IsRUFBRSxvQkFBb0IsRUFBRSxvQkFBb0IsRUFBRSw2QkFBNkIsRUFBRSxvQkFBb0IsRUFBRSw2QkFBNkIsRUFBRSxlQUFlLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUU5UCxPQUFPLEVBQUMsUUFBUSxFQUFDLE1BQU0sVUFBVSxDQUFDOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztJQTRKOUIsbUVBQThFOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBc0JsRixNQUFNLFVBQVUscUJBQXFCLENBQ2pDLEtBQVksRUFBRSxLQUFZLEVBQUUscUJBQWtDLEVBQUUsS0FBYSxFQUM3RSxhQUFzQixFQUFFLGNBQXVCO0lBQ2pELFNBQVMsSUFBSSxxQkFBcUIsQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDOztRQUMzQyxTQUFTLEdBQUcsY0FBYyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQyxLQUFLLENB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QUFpQztLQUMxQztJQUNELE9BQU8sS0FBSyxDQUFDO0FBQ2YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuKiBAbGljZW5zZVxuKiBDb3B5cmlnaHQgR29vZ2xlIEluYy4gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbipcbiogVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbiogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuKi9cblxuaW1wb3J0IHtLZXlWYWx1ZUFycmF5LCBrZXlWYWx1ZUFycmF5SW5kZXhPZn0gZnJvbSAnLi4vLi4vdXRpbC9hcnJheV91dGlscyc7XG5pbXBvcnQge2Fzc2VydERhdGFJblJhbmdlLCBhc3NlcnRFcXVhbCwgYXNzZXJ0Tm90RXF1YWx9IGZyb20gJy4uLy4uL3V0aWwvYXNzZXJ0JztcbmltcG9ydCB7YXNzZXJ0Rmlyc3RVcGRhdGVQYXNzfSBmcm9tICcuLi9hc3NlcnQnO1xuaW1wb3J0IHtUTm9kZX0gZnJvbSAnLi4vaW50ZXJmYWNlcy9ub2RlJztcbmltcG9ydCB7VFN0eWxpbmdLZXksIFRTdHlsaW5nS2V5UHJpbWl0aXZlLCBUU3R5bGluZ1JhbmdlLCBnZXRUU3R5bGluZ1JhbmdlTmV4dCwgZ2V0VFN0eWxpbmdSYW5nZVByZXYsIHNldFRTdHlsaW5nUmFuZ2VOZXh0LCBzZXRUU3R5bGluZ1JhbmdlTmV4dER1cGxpY2F0ZSwgc2V0VFN0eWxpbmdSYW5nZVByZXYsIHNldFRTdHlsaW5nUmFuZ2VQcmV2RHVwbGljYXRlLCB0b1RTdHlsaW5nUmFuZ2V9IGZyb20gJy4uL2ludGVyZmFjZXMvc3R5bGluZyc7XG5pbXBvcnQge1REYXRhfSBmcm9tICcuLi9pbnRlcmZhY2VzL3ZpZXcnO1xuaW1wb3J0IHtnZXRUVmlld30gZnJvbSAnLi4vc3RhdGUnO1xuXG5cbi8qKlxuICogTk9URTogVGhlIHdvcmQgYHN0eWxpbmdgIGlzIHVzZWQgaW50ZXJjaGFuZ2VhYmx5IGFzIHN0eWxlIG9yIGNsYXNzIHN0eWxpbmcuXG4gKlxuICogVGhpcyBmaWxlIGNvbnRhaW5zIGNvZGUgdG8gbGluayBzdHlsaW5nIGluc3RydWN0aW9ucyB0b2dldGhlciBzbyB0aGF0IHRoZXkgY2FuIGJlIHJlcGxheWVkIGluXG4gKiBwcmlvcml0eSBvcmRlci4gVGhlIGZpbGUgZXhpc3RzIGJlY2F1c2UgSXZ5IHN0eWxpbmcgaW5zdHJ1Y3Rpb24gZXhlY3V0aW9uIG9yZGVyIGRvZXMgbm90IG1hdGNoXG4gKiB0aGF0IG9mIHRoZSBwcmlvcml0eSBvcmRlci4gVGhlIHB1cnBvc2Ugb2YgdGhpcyBjb2RlIGlzIHRvIGNyZWF0ZSBhIGxpbmtlZCBsaXN0IHNvIHRoYXQgdGhlXG4gKiBpbnN0cnVjdGlvbnMgY2FuIGJlIHRyYXZlcnNlZCBpbiBwcmlvcml0eSBvcmRlciB3aGVuIGNvbXB1dGluZyB0aGUgc3R5bGVzLlxuICpcbiAqIEFzc3VtZSB3ZSBhcmUgZGVhbGluZyB3aXRoIHRoZSBmb2xsb3dpbmcgY29kZTpcbiAqIGBgYFxuICogQENvbXBvbmVudCh7XG4gKiAgIHRlbXBsYXRlOiBgXG4gKiAgICAgPG15LWNtcCBbc3R5bGVdPVwiIHtjb2xvcjogJyMwMDEnfSBcIlxuICogICAgICAgICAgICAgW3N0eWxlLmNvbG9yXT1cIiAjMDAyIFwiXG4gKiAgICAgICAgICAgICBkaXItc3R5bGUtY29sb3ItMVxuICogICAgICAgICAgICAgZGlyLXN0eWxlLWNvbG9yLTI+IGBcbiAqIH0pXG4gKiBjbGFzcyBFeGFtcGxlQ29tcG9uZW50IHtcbiAqICAgc3RhdGljIG5nQ29tcCA9IC4uLiB7XG4gKiAgICAgLi4uXG4gKiAgICAgLy8gQ29tcGlsZXIgZW5zdXJlcyB0aGF0IGDJtcm1c3R5bGVQcm9wYCBpcyBhZnRlciBgybXJtXN0eWxlTWFwYFxuICogICAgIMm1ybVzdHlsZU1hcCh7Y29sb3I6ICcjMDAxJ30pO1xuICogICAgIMm1ybVzdHlsZVByb3AoJ2NvbG9yJywgJyMwMDInKTtcbiAqICAgICAuLi5cbiAqICAgfVxuICogfVxuICpcbiAqIEBEaXJlY3RpdmUoe1xuICogICBzZWxlY3RvcjogYFtkaXItc3R5bGUtY29sb3ItMV0nLFxuICogfSlcbiAqIGNsYXNzIFN0eWxlMURpcmVjdGl2ZSB7XG4gKiAgIEBIb3N0QmluZGluZygnc3R5bGUnKSBzdHlsZSA9IHtjb2xvcjogJyMwMDUnfTtcbiAqICAgQEhvc3RCaW5kaW5nKCdzdHlsZS5jb2xvcicpIGNvbG9yID0gJyMwMDYnO1xuICpcbiAqICAgc3RhdGljIG5nRGlyID0gLi4uIHtcbiAqICAgICAuLi5cbiAqICAgICAvLyBDb21waWxlciBlbnN1cmVzIHRoYXQgYMm1ybVzdHlsZVByb3BgIGlzIGFmdGVyIGDJtcm1c3R5bGVNYXBgXG4gKiAgICAgybXJtXN0eWxlTWFwKHtjb2xvcjogJyMwMDUnfSk7XG4gKiAgICAgybXJtXN0eWxlUHJvcCgnY29sb3InLCAnIzAwNicpO1xuICogICAgIC4uLlxuICogICB9XG4gKiB9XG4gKlxuICogQERpcmVjdGl2ZSh7XG4gKiAgIHNlbGVjdG9yOiBgW2Rpci1zdHlsZS1jb2xvci0yXScsXG4gKiB9KVxuICogY2xhc3MgU3R5bGUyRGlyZWN0aXZlIHtcbiAqICAgQEhvc3RCaW5kaW5nKCdzdHlsZScpIHN0eWxlID0ge2NvbG9yOiAnIzAwNyd9O1xuICogICBASG9zdEJpbmRpbmcoJ3N0eWxlLmNvbG9yJykgY29sb3IgPSAnIzAwOCc7XG4gKlxuICogICBzdGF0aWMgbmdEaXIgPSAuLi4ge1xuICogICAgIC4uLlxuICogICAgIC8vIENvbXBpbGVyIGVuc3VyZXMgdGhhdCBgybXJtXN0eWxlUHJvcGAgaXMgYWZ0ZXIgYMm1ybVzdHlsZU1hcGBcbiAqICAgICDJtcm1c3R5bGVNYXAoe2NvbG9yOiAnIzAwNyd9KTtcbiAqICAgICDJtcm1c3R5bGVQcm9wKCdjb2xvcicsICcjMDA4Jyk7XG4gKiAgICAgLi4uXG4gKiAgIH1cbiAqIH1cbiAqXG4gKiBARGlyZWN0aXZlKHtcbiAqICAgc2VsZWN0b3I6IGBteS1jbXAnLFxuICogfSlcbiAqIGNsYXNzIE15Q29tcG9uZW50IHtcbiAqICAgQEhvc3RCaW5kaW5nKCdzdHlsZScpIHN0eWxlID0ge2NvbG9yOiAnIzAwMyd9O1xuICogICBASG9zdEJpbmRpbmcoJ3N0eWxlLmNvbG9yJykgY29sb3IgPSAnIzAwNCc7XG4gKlxuICogICBzdGF0aWMgbmdDb21wID0gLi4uIHtcbiAqICAgICAuLi5cbiAqICAgICAvLyBDb21waWxlciBlbnN1cmVzIHRoYXQgYMm1ybVzdHlsZVByb3BgIGlzIGFmdGVyIGDJtcm1c3R5bGVNYXBgXG4gKiAgICAgybXJtXN0eWxlTWFwKHtjb2xvcjogJyMwMDMnfSk7XG4gKiAgICAgybXJtXN0eWxlUHJvcCgnY29sb3InLCAnIzAwNCcpO1xuICogICAgIC4uLlxuICogICB9XG4gKiB9XG4gKiBgYGBcbiAqXG4gKiBUaGUgT3JkZXIgb2YgaW5zdHJ1Y3Rpb24gZXhlY3V0aW9uIGlzOlxuICpcbiAqIE5PVEU6IHRoZSBjb21tZW50IGJpbmRpbmcgbG9jYXRpb24gaXMgZm9yIGlsbHVzdHJhdGl2ZSBwdXJwb3NlcyBvbmx5LlxuICpcbiAqIGBgYFxuICogLy8gVGVtcGxhdGU6IChFeGFtcGxlQ29tcG9uZW50KVxuICogICAgIMm1ybVzdHlsZU1hcCh7Y29sb3I6ICcjMDAxJ30pOyAgIC8vIEJpbmRpbmcgaW5kZXg6IDEwXG4gKiAgICAgybXJtXN0eWxlUHJvcCgnY29sb3InLCAnIzAwMicpOyAgLy8gQmluZGluZyBpbmRleDogMTJcbiAqIC8vIE15Q29tcG9uZW50XG4gKiAgICAgybXJtXN0eWxlTWFwKHtjb2xvcjogJyMwMDMnfSk7ICAgLy8gQmluZGluZyBpbmRleDogMjBcbiAqICAgICDJtcm1c3R5bGVQcm9wKCdjb2xvcicsICcjMDA0Jyk7ICAvLyBCaW5kaW5nIGluZGV4OiAyMlxuICogLy8gU3R5bGUxRGlyZWN0aXZlXG4gKiAgICAgybXJtXN0eWxlTWFwKHtjb2xvcjogJyMwMDUnfSk7ICAgLy8gQmluZGluZyBpbmRleDogMjRcbiAqICAgICDJtcm1c3R5bGVQcm9wKCdjb2xvcicsICcjMDA2Jyk7ICAvLyBCaW5kaW5nIGluZGV4OiAyNlxuICogLy8gU3R5bGUyRGlyZWN0aXZlXG4gKiAgICAgybXJtXN0eWxlTWFwKHtjb2xvcjogJyMwMDcnfSk7ICAgLy8gQmluZGluZyBpbmRleDogMjhcbiAqICAgICDJtcm1c3R5bGVQcm9wKCdjb2xvcicsICcjMDA4Jyk7ICAvLyBCaW5kaW5nIGluZGV4OiAzMFxuICogYGBgXG4gKlxuICogVGhlIGNvcnJlY3QgcHJpb3JpdHkgb3JkZXIgb2YgY29uY2F0ZW5hdGlvbiBpczpcbiAqXG4gKiBgYGBcbiAqIC8vIE15Q29tcG9uZW50XG4gKiAgICAgybXJtXN0eWxlTWFwKHtjb2xvcjogJyMwMDMnfSk7ICAgLy8gQmluZGluZyBpbmRleDogMjBcbiAqICAgICDJtcm1c3R5bGVQcm9wKCdjb2xvcicsICcjMDA0Jyk7ICAvLyBCaW5kaW5nIGluZGV4OiAyMlxuICogLy8gU3R5bGUxRGlyZWN0aXZlXG4gKiAgICAgybXJtXN0eWxlTWFwKHtjb2xvcjogJyMwMDUnfSk7ICAgLy8gQmluZGluZyBpbmRleDogMjRcbiAqICAgICDJtcm1c3R5bGVQcm9wKCdjb2xvcicsICcjMDA2Jyk7ICAvLyBCaW5kaW5nIGluZGV4OiAyNlxuICogLy8gU3R5bGUyRGlyZWN0aXZlXG4gKiAgICAgybXJtXN0eWxlTWFwKHtjb2xvcjogJyMwMDcnfSk7ICAgLy8gQmluZGluZyBpbmRleDogMjhcbiAqICAgICDJtcm1c3R5bGVQcm9wKCdjb2xvcicsICcjMDA4Jyk7ICAvLyBCaW5kaW5nIGluZGV4OiAzMFxuICogLy8gVGVtcGxhdGU6IChFeGFtcGxlQ29tcG9uZW50KVxuICogICAgIMm1ybVzdHlsZU1hcCh7Y29sb3I6ICcjMDAxJ30pOyAgIC8vIEJpbmRpbmcgaW5kZXg6IDEwXG4gKiAgICAgybXJtXN0eWxlUHJvcCgnY29sb3InLCAnIzAwMicpOyAgLy8gQmluZGluZyBpbmRleDogMTJcbiAqIGBgYFxuICpcbiAqIFdoYXQgY29sb3Igc2hvdWxkIGJlIHJlbmRlcmVkP1xuICpcbiAqIE9uY2UgdGhlIGl0ZW1zIGFyZSBjb3JyZWN0bHkgc29ydGVkIGluIHRoZSBsaXN0LCB0aGUgYW5zd2VyIGlzIHNpbXBseSB0aGUgbGFzdCBpdGVtIGluIHRoZVxuICogY29uY2F0ZW5hdGlvbiBsaXN0IHdoaWNoIGlzIGAjMDAyYC5cbiAqXG4gKiBUbyBkbyBzbyB3ZSBrZWVwIGEgbGlua2VkIGxpc3Qgb2YgYWxsIG9mIHRoZSBiaW5kaW5ncyB3aGljaCBwZXJ0YWluIHRvIHRoaXMgZWxlbWVudC5cbiAqIE5vdGljZSB0aGF0IHRoZSBiaW5kaW5ncyBhcmUgaW5zZXJ0ZWQgaW4gdGhlIG9yZGVyIG9mIGV4ZWN1dGlvbiwgYnV0IHRoZSBgVFZpZXcuZGF0YWAgYWxsb3dzXG4gKiB1cyB0byB0cmF2ZXJzZSB0aGVtIGluIHRoZSBvcmRlciBvZiBwcmlvcml0eS5cbiAqXG4gKiB8SWR4fGBUVmlldy5kYXRhYHxgTFZpZXdgICAgICAgICAgIHwgTm90ZXNcbiAqIHwtLS18LS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tLS0tfC0tLS0tLS0tLS0tLS0tXG4gKiB8Li4ufCAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgIHxcbiAqIHwxMCB8YG51bGxgICAgICAgfGB7Y29sb3I6ICcjMDAxJ31gfCBgybXJtXN0eWxlTWFwKCdjb2xvcicsIHtjb2xvcjogJyMwMDEnfSlgXG4gKiB8MTEgfGAzMCB8IDEyYCAgIHwgLi4uICAgICAgICAgICAgIHxcbiAqIHwxMiB8YGNvbG9yYCAgICAgfGAnIzAwMidgICAgICAgICAgfCBgybXJtXN0eWxlUHJvcCgnY29sb3InLCAnIzAwMicpYFxuICogfDEzIHxgMTAgfCAwYCAgICB8IC4uLiAgICAgICAgICAgICB8XG4gKiB8Li4ufCAgICAgICAgICAgIHwgICAgICAgICAgICAgICAgIHxcbiAqIHwyMCB8YG51bGxgICAgICAgfGB7Y29sb3I6ICcjMDAzJ31gfCBgybXJtXN0eWxlTWFwKCdjb2xvcicsIHtjb2xvcjogJyMwMDMnfSlgXG4gKiB8MjEgfGAwIHwgMjJgICAgIHwgLi4uICAgICAgICAgICAgIHxcbiAqIHwyMiB8YGNvbG9yYCAgICAgfGAnIzAwNCdgICAgICAgICAgfCBgybXJtXN0eWxlUHJvcCgnY29sb3InLCAnIzAwNCcpYFxuICogfDIzIHxgMjAgfCAyNGAgICB8IC4uLiAgICAgICAgICAgICB8XG4gKiB8MjQgfGBudWxsYCAgICAgIHxge2NvbG9yOiAnIzAwNSd9YHwgYMm1ybVzdHlsZU1hcCgnY29sb3InLCB7Y29sb3I6ICcjMDA1J30pYFxuICogfDI1IHxgMjIgfCAyNmAgICB8IC4uLiAgICAgICAgICAgICB8XG4gKiB8MjYgfGBjb2xvcmAgICAgIHxgJyMwMDYnYCAgICAgICAgIHwgYMm1ybVzdHlsZVByb3AoJ2NvbG9yJywgJyMwMDYnKWBcbiAqIHwyNyB8YDI0IHwgMjhgICAgfCAuLi4gICAgICAgICAgICAgfFxuICogfDI4IHxgbnVsbGAgICAgICB8YHtjb2xvcjogJyMwMDcnfWB8IGDJtcm1c3R5bGVNYXAoJ2NvbG9yJywge2NvbG9yOiAnIzAwNyd9KWBcbiAqIHwyOSB8YDI2IHwgMzBgICAgfCAuLi4gICAgICAgICAgICAgfFxuICogfDMwIHxgY29sb3JgICAgICB8YCcjMDA4J2AgICAgICAgICB8IGDJtcm1c3R5bGVQcm9wKCdjb2xvcicsICcjMDA4JylgXG4gKiB8MzEgfGAyOCB8IDEwYCAgIHwgLi4uICAgICAgICAgICAgIHxcbiAqXG4gKiBUaGUgYWJvdmUgZGF0YSBzdHJ1Y3R1cmUgYWxsb3dzIHVzIHRvIHJlLWNvbmNhdGVuYXRlIHRoZSBzdHlsaW5nIG5vIG1hdHRlciB3aGljaCBkYXRhIGJpbmRpbmdcbiAqIGNoYW5nZXMuXG4gKlxuICogTk9URTogaW4gYWRkaXRpb24gdG8ga2VlcGluZyB0cmFjayBvZiBuZXh0L3ByZXZpb3VzIGluZGV4IHRoZSBgVFZpZXcuZGF0YWAgYWxzbyBzdG9yZXMgcHJldi9uZXh0XG4gKiBkdXBsaWNhdGUgYml0LiBUaGUgZHVwbGljYXRlIGJpdCBpZiB0cnVlIHNheXMgdGhlcmUgZWl0aGVyIGlzIGEgYmluZGluZyB3aXRoIHRoZSBzYW1lIG5hbWUgb3JcbiAqIHRoZXJlIGlzIGEgbWFwICh3aGljaCBtYXkgY29udGFpbiB0aGUgbmFtZSkuIFRoaXMgaW5mb3JtYXRpb24gaXMgdXNlZnVsIGluIGtub3dpbmcgaWYgb3RoZXJcbiAqIHN0eWxlcyB3aXRoIGhpZ2hlciBwcmlvcml0eSBuZWVkIHRvIGJlIHNlYXJjaGVkIGZvciBvdmVyd3JpdGVzLlxuICpcbiAqIE5PVEU6IFNlZSBgc2hvdWxkIHN1cHBvcnQgZXhhbXBsZSBpbiAndG5vZGVfbGlua2VkX2xpc3QudHMnIGRvY3VtZW50YXRpb25gIGluXG4gKiBgdG5vZGVfbGlua2VkX2xpc3Rfc3BlYy50c2AgZm9yIHdvcmtpbmcgZXhhbXBsZS5cbiAqL1xubGV0IF9fdW51c2VkX2NvbnN0X2FzX2Nsb3N1cmVfZG9lc19ub3RfbGlrZV9zdGFuZGFsb25lX2NvbW1lbnRfYmxvY2tzX186IHVuZGVmaW5lZDtcblxuLyoqXG4gKiBJbnNlcnQgbmV3IGB0U3R5bGVWYWx1ZWAgYXQgYFREYXRhYCBhbmQgbGluayBleGlzdGluZyBzdHlsZSBiaW5kaW5ncyBzdWNoIHRoYXQgd2UgbWFpbnRhaW4gbGlua2VkXG4gKiBsaXN0IG9mIHN0eWxlcyBhbmQgY29tcHV0ZSB0aGUgZHVwbGljYXRlIGZsYWcuXG4gKlxuICogTm90ZTogdGhpcyBmdW5jdGlvbiBpcyBleGVjdXRlZCBkdXJpbmcgYGZpcnN0VXBkYXRlUGFzc2Agb25seSB0byBwb3B1bGF0ZSB0aGUgYFRWaWV3LmRhdGFgLlxuICpcbiAqIFRoZSBmdW5jdGlvbiB3b3JrcyBieSBrZWVwaW5nIHRyYWNrIG9mIGB0U3R5bGluZ1JhbmdlYCB3aGljaCBjb250YWlucyB0d28gcG9pbnRlcnMgcG9pbnRpbmcgdG9cbiAqIHRoZSBoZWFkL3RhaWwgb2YgdGhlIHRlbXBsYXRlIHBvcnRpb24gb2YgdGhlIHN0eWxlcy5cbiAqICAtIGlmIGBpc0hvc3QgPT09IGZhbHNlYCAod2UgYXJlIHRlbXBsYXRlKSB0aGVuIGluc2VydGlvbiBpcyBhdCB0YWlsIG9mIGBUU3R5bGluZ1JhbmdlYFxuICogIC0gaWYgYGlzSG9zdCA9PT0gdHJ1ZWAgKHdlIGFyZSBob3N0IGJpbmRpbmcpIHRoZW4gaW5zZXJ0aW9uIGlzIGF0IGhlYWQgb2YgYFRTdHlsaW5nUmFuZ2VgXG4gKlxuICogQHBhcmFtIHREYXRhIFRoZSBgVERhdGFgIHRvIGluc2VydCBpbnRvLlxuICogQHBhcmFtIHROb2RlIGBUTm9kZWAgYXNzb2NpYXRlZCB3aXRoIHRoZSBzdHlsaW5nIGVsZW1lbnQuXG4gKiBAcGFyYW0gdFN0eWxpbmdLZXkgU2VlIGBUU3R5bGluZ0tleWAuXG4gKiBAcGFyYW0gaW5kZXggbG9jYXRpb24gb2Ygd2hlcmUgYHRTdHlsZVZhbHVlYCBzaG91bGQgYmUgc3RvcmVkIChhbmQgbGlua2VkIGludG8gbGlzdC4pXG4gKiBAcGFyYW0gaXNIb3N0QmluZGluZyBgdHJ1ZWAgaWYgdGhlIGluc2VydGlvbiBpcyBmb3IgYSBgaG9zdEJpbmRpbmdgLiAoaW5zZXJ0aW9uIGlzIGluIGZyb250IG9mXG4gKiAgICAgICAgICAgICAgIHRlbXBsYXRlLilcbiAqIEBwYXJhbSBpc0NsYXNzQmluZGluZyBUcnVlIGlmIHRoZSBhc3NvY2lhdGVkIGB0U3R5bGluZ0tleWAgYXMgYSBgY2xhc3NgIHN0eWxpbmcuXG4gKiAgICAgICAgICAgICAgICAgICAgICAgYHROb2RlLmNsYXNzQmluZGluZ3NgIHNob3VsZCBiZSB1c2VkIChvciBgdE5vZGUuc3R5bGVCaW5kaW5nc2Agb3RoZXJ3aXNlLilcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGluc2VydFRTdHlsaW5nQmluZGluZyhcbiAgICB0RGF0YTogVERhdGEsIHROb2RlOiBUTm9kZSwgdFN0eWxpbmdLZXlXaXRoU3RhdGljOiBUU3R5bGluZ0tleSwgaW5kZXg6IG51bWJlcixcbiAgICBpc0hvc3RCaW5kaW5nOiBib29sZWFuLCBpc0NsYXNzQmluZGluZzogYm9vbGVhbik6IHZvaWQge1xuICBuZ0Rldk1vZGUgJiYgYXNzZXJ0Rmlyc3RVcGRhdGVQYXNzKGdldFRWaWV3KCkpO1xuICBsZXQgdEJpbmRpbmdzID0gaXNDbGFzc0JpbmRpbmcgPyB0Tm9kZS5jbGFzc0JpbmRpbmdzIDogdE5vZGUuc3R5bGVCaW5kaW5ncztcbiAgbGV0IHRtcGxIZWFkID0gZ2V0VFN0eWxpbmdSYW5nZVByZXYodEJpbmRpbmdzKTtcbiAgbGV0IHRtcGxUYWlsID0gZ2V0VFN0eWxpbmdSYW5nZU5leHQodEJpbmRpbmdzKTtcblxuICB0RGF0YVtpbmRleF0gPSB0U3R5bGluZ0tleVdpdGhTdGF0aWM7XG4gIGxldCBpc0tleUR1cGxpY2F0ZU9mU3RhdGljID0gZmFsc2U7XG4gIGxldCB0U3R5bGluZ0tleTogVFN0eWxpbmdLZXlQcmltaXRpdmU7XG4gIGlmIChBcnJheS5pc0FycmF5KHRTdHlsaW5nS2V5V2l0aFN0YXRpYykpIHtcbiAgICAvLyBXZSBhcmUgY2FzZSB3aGVuIHRoZSBgVFN0eWxpbmdLZXlgIGNvbnRhaW5zIHN0YXRpYyBmaWVsZHMgYXMgd2VsbC5cbiAgICBjb25zdCBzdGF0aWNLZXlWYWx1ZUFycmF5ID0gdFN0eWxpbmdLZXlXaXRoU3RhdGljIGFzIEtleVZhbHVlQXJyYXk8YW55PjtcbiAgICB0U3R5bGluZ0tleSA9IHN0YXRpY0tleVZhbHVlQXJyYXlbMV07ICAvLyB1bndyYXAuXG4gICAgLy8gV2UgbmVlZCB0byBjaGVjayBpZiBvdXIga2V5IGlzIHByZXNlbnQgaW4gdGhlIHN0YXRpYyBzbyB0aGF0IHdlIGNhbiBtYXJrIGl0IGFzIGR1cGxpY2F0ZS5cbiAgICBpZiAodFN0eWxpbmdLZXkgPT09IG51bGwgfHxcbiAgICAgICAga2V5VmFsdWVBcnJheUluZGV4T2Yoc3RhdGljS2V5VmFsdWVBcnJheSwgdFN0eWxpbmdLZXkgYXMgc3RyaW5nKSA+IDApIHtcbiAgICAgIC8vIHRTdHlsaW5nS2V5IGlzIHByZXNlbnQgaW4gdGhlIHN0YXRpY3MsIG5lZWQgdG8gbWFyayBpdCBhcyBkdXBsaWNhdGUuXG4gICAgICBpc0tleUR1cGxpY2F0ZU9mU3RhdGljID0gdHJ1ZTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgdFN0eWxpbmdLZXkgPSB0U3R5bGluZ0tleVdpdGhTdGF0aWM7XG4gIH1cbiAgaWYgKGlzSG9zdEJpbmRpbmcpIHtcbiAgICAvLyBXZSBhcmUgaW5zZXJ0aW5nIGhvc3QgYmluZGluZ3NcblxuICAgIC8vIElmIHdlIGRvbid0IGhhdmUgdGVtcGxhdGUgYmluZGluZ3MgdGhlbiBgdGFpbGAgaXMgMC5cbiAgICBjb25zdCBoYXNUZW1wbGF0ZUJpbmRpbmdzID0gdG1wbFRhaWwgIT09IDA7XG4gICAgLy8gVGhpcyBpcyBpbXBvcnRhbnQgdG8ga25vdyBiZWNhdXNlIHRoYXQgbWVhbnMgdGhhdCB0aGUgYGhlYWRgIGNhbid0IHBvaW50IHRvIHRoZSBmaXJzdFxuICAgIC8vIHRlbXBsYXRlIGJpbmRpbmdzICh0aGVyZSBhcmUgbm9uZS4pIEluc3RlYWQgdGhlIGhlYWQgcG9pbnRzIHRvIHRoZSB0YWlsIG9mIHRoZSB0ZW1wbGF0ZS5cbiAgICBpZiAoaGFzVGVtcGxhdGVCaW5kaW5ncykge1xuICAgICAgLy8gdGVtcGxhdGUgaGVhZCdzIFwicHJldlwiIHdpbGwgcG9pbnQgdG8gbGFzdCBob3N0IGJpbmRpbmcgb3IgdG8gMCBpZiBubyBob3N0IGJpbmRpbmdzIHlldFxuICAgICAgY29uc3QgcHJldmlvdXNOb2RlID0gZ2V0VFN0eWxpbmdSYW5nZVByZXYodERhdGFbdG1wbEhlYWQgKyAxXSBhcyBUU3R5bGluZ1JhbmdlKTtcbiAgICAgIHREYXRhW2luZGV4ICsgMV0gPSB0b1RTdHlsaW5nUmFuZ2UocHJldmlvdXNOb2RlLCB0bXBsSGVhZCk7XG4gICAgICAvLyBpZiBhIGhvc3QgYmluZGluZyBoYXMgYWxyZWFkeSBiZWVuIHJlZ2lzdGVyZWQsIHdlIG5lZWQgdG8gdXBkYXRlIHRoZSBuZXh0IG9mIHRoYXQgaG9zdFxuICAgICAgLy8gYmluZGluZyB0byBwb2ludCB0byB0aGlzIG9uZVxuICAgICAgaWYgKHByZXZpb3VzTm9kZSAhPT0gMCkge1xuICAgICAgICAvLyBXZSBuZWVkIHRvIHVwZGF0ZSB0aGUgdGVtcGxhdGUtdGFpbCB2YWx1ZSB0byBwb2ludCB0byB1cy5cbiAgICAgICAgdERhdGFbcHJldmlvdXNOb2RlICsgMV0gPVxuICAgICAgICAgICAgc2V0VFN0eWxpbmdSYW5nZU5leHQodERhdGFbcHJldmlvdXNOb2RlICsgMV0gYXMgVFN0eWxpbmdSYW5nZSwgaW5kZXgpO1xuICAgICAgfVxuICAgICAgLy8gVGhlIFwicHJldmlvdXNcIiBvZiB0aGUgdGVtcGxhdGUgYmluZGluZyBoZWFkIHNob3VsZCBwb2ludCB0byB0aGlzIGhvc3QgYmluZGluZ1xuICAgICAgdERhdGFbdG1wbEhlYWQgKyAxXSA9IHNldFRTdHlsaW5nUmFuZ2VQcmV2KHREYXRhW3RtcGxIZWFkICsgMV0gYXMgVFN0eWxpbmdSYW5nZSwgaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0RGF0YVtpbmRleCArIDFdID0gdG9UU3R5bGluZ1JhbmdlKHRtcGxIZWFkLCAwKTtcbiAgICAgIC8vIGlmIGEgaG9zdCBiaW5kaW5nIGhhcyBhbHJlYWR5IGJlZW4gcmVnaXN0ZXJlZCwgd2UgbmVlZCB0byB1cGRhdGUgdGhlIG5leHQgb2YgdGhhdCBob3N0XG4gICAgICAvLyBiaW5kaW5nIHRvIHBvaW50IHRvIHRoaXMgb25lXG4gICAgICBpZiAodG1wbEhlYWQgIT09IDApIHtcbiAgICAgICAgLy8gV2UgbmVlZCB0byB1cGRhdGUgdGhlIHRlbXBsYXRlLXRhaWwgdmFsdWUgdG8gcG9pbnQgdG8gdXMuXG4gICAgICAgIHREYXRhW3RtcGxIZWFkICsgMV0gPSBzZXRUU3R5bGluZ1JhbmdlTmV4dCh0RGF0YVt0bXBsSGVhZCArIDFdIGFzIFRTdHlsaW5nUmFuZ2UsIGluZGV4KTtcbiAgICAgIH1cbiAgICAgIC8vIGlmIHdlIGRvbid0IGhhdmUgdGVtcGxhdGUsIHRoZSBoZWFkIHBvaW50cyB0byB0ZW1wbGF0ZS10YWlsLCBhbmQgbmVlZHMgdG8gYmUgYWR2YW5jZWQuXG4gICAgICB0bXBsSGVhZCA9IGluZGV4O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICAvLyBXZSBhcmUgaW5zZXJ0aW5nIGluIHRlbXBsYXRlIHNlY3Rpb24uXG4gICAgLy8gV2UgbmVlZCB0byBzZXQgdGhpcyBiaW5kaW5nJ3MgXCJwcmV2aW91c1wiIHRvIHRoZSBjdXJyZW50IHRlbXBsYXRlIHRhaWxcbiAgICB0RGF0YVtpbmRleCArIDFdID0gdG9UU3R5bGluZ1JhbmdlKHRtcGxUYWlsLCAwKTtcbiAgICBuZ0Rldk1vZGUgJiYgYXNzZXJ0RXF1YWwoXG4gICAgICAgICAgICAgICAgICAgICB0bXBsSGVhZCAhPT0gMCAmJiB0bXBsVGFpbCA9PT0gMCwgZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAnQWRkaW5nIHRlbXBsYXRlIGJpbmRpbmdzIGFmdGVyIGhvc3RCaW5kaW5ncyBpcyBub3QgYWxsb3dlZC4nKTtcbiAgICBpZiAodG1wbEhlYWQgPT09IDApIHtcbiAgICAgIHRtcGxIZWFkID0gaW5kZXg7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIFdlIG5lZWQgdG8gdXBkYXRlIHRoZSBwcmV2aW91cyB2YWx1ZSBcIm5leHRcIiB0byBwb2ludCB0byB0aGlzIGJpbmRpbmdcbiAgICAgIHREYXRhW3RtcGxUYWlsICsgMV0gPSBzZXRUU3R5bGluZ1JhbmdlTmV4dCh0RGF0YVt0bXBsVGFpbCArIDFdIGFzIFRTdHlsaW5nUmFuZ2UsIGluZGV4KTtcbiAgICB9XG4gICAgdG1wbFRhaWwgPSBpbmRleDtcbiAgfVxuXG4gIC8vIE5vdyB3ZSBuZWVkIHRvIHVwZGF0ZSAvIGNvbXB1dGUgdGhlIGR1cGxpY2F0ZXMuXG4gIC8vIFN0YXJ0aW5nIHdpdGggb3VyIGxvY2F0aW9uIHNlYXJjaCB0b3dhcmRzIGhlYWQgKGxlYXN0IHByaW9yaXR5KVxuICBpZiAoaXNLZXlEdXBsaWNhdGVPZlN0YXRpYykge1xuICAgIHREYXRhW2luZGV4ICsgMV0gPSBzZXRUU3R5bGluZ1JhbmdlUHJldkR1cGxpY2F0ZSh0RGF0YVtpbmRleCArIDFdIGFzIFRTdHlsaW5nUmFuZ2UpO1xuICB9XG4gIG1hcmtEdXBsaWNhdGVzKHREYXRhLCB0U3R5bGluZ0tleSwgaW5kZXgsIHRydWUsIGlzQ2xhc3NCaW5kaW5nKTtcbiAgbWFya0R1cGxpY2F0ZXModERhdGEsIHRTdHlsaW5nS2V5LCBpbmRleCwgZmFsc2UsIGlzQ2xhc3NCaW5kaW5nKTtcbiAgbWFya0R1cGxpY2F0ZU9mUmVzaWR1YWxTdHlsaW5nKHROb2RlLCB0U3R5bGluZ0tleSwgdERhdGEsIGluZGV4LCBpc0NsYXNzQmluZGluZyk7XG5cbiAgdEJpbmRpbmdzID0gdG9UU3R5bGluZ1JhbmdlKHRtcGxIZWFkLCB0bXBsVGFpbCk7XG4gIGlmIChpc0NsYXNzQmluZGluZykge1xuICAgIHROb2RlLmNsYXNzQmluZGluZ3MgPSB0QmluZGluZ3M7XG4gIH0gZWxzZSB7XG4gICAgdE5vZGUuc3R5bGVCaW5kaW5ncyA9IHRCaW5kaW5ncztcbiAgfVxufVxuXG4vKipcbiAqIExvb2sgaW50byB0aGUgcmVzaWR1YWwgc3R5bGluZyB0byBzZWUgaWYgdGhlIGN1cnJlbnQgYHRTdHlsaW5nS2V5YCBpcyBkdXBsaWNhdGUgb2YgcmVzaWR1YWwuXG4gKlxuICogQHBhcmFtIHROb2RlIGBUTm9kZWAgd2hlcmUgdGhlIHJlc2lkdWFsIGlzIHN0b3JlZC5cbiAqIEBwYXJhbSB0U3R5bGluZ0tleSBgVFN0eWxpbmdLZXlgIHRvIHN0b3JlLlxuICogQHBhcmFtIHREYXRhIGBURGF0YWAgYXNzb2NpYXRlZCB3aXRoIHRoZSBjdXJyZW50IGBMVmlld2AuXG4gKiBAcGFyYW0gaW5kZXggbG9jYXRpb24gb2Ygd2hlcmUgYHRTdHlsZVZhbHVlYCBzaG91bGQgYmUgc3RvcmVkIChhbmQgbGlua2VkIGludG8gbGlzdC4pXG4gKiBAcGFyYW0gaXNDbGFzc0JpbmRpbmcgVHJ1ZSBpZiB0aGUgYXNzb2NpYXRlZCBgdFN0eWxpbmdLZXlgIGFzIGEgYGNsYXNzYCBzdHlsaW5nLlxuICogICAgICAgICAgICAgICAgICAgICAgIGB0Tm9kZS5jbGFzc0JpbmRpbmdzYCBzaG91bGQgYmUgdXNlZCAob3IgYHROb2RlLnN0eWxlQmluZGluZ3NgIG90aGVyd2lzZS4pXG4gKi9cbmZ1bmN0aW9uIG1hcmtEdXBsaWNhdGVPZlJlc2lkdWFsU3R5bGluZyhcbiAgICB0Tm9kZTogVE5vZGUsIHRTdHlsaW5nS2V5OiBUU3R5bGluZ0tleSwgdERhdGE6IFREYXRhLCBpbmRleDogbnVtYmVyLCBpc0NsYXNzQmluZGluZzogYm9vbGVhbikge1xuICBjb25zdCByZXNpZHVhbCA9IGlzQ2xhc3NCaW5kaW5nID8gdE5vZGUucmVzaWR1YWxDbGFzc2VzIDogdE5vZGUucmVzaWR1YWxTdHlsZXM7XG4gIGlmIChyZXNpZHVhbCAhPSBudWxsIC8qIG9yIHVuZGVmaW5lZCAqLyAmJiB0eXBlb2YgdFN0eWxpbmdLZXkgPT0gJ3N0cmluZycgJiZcbiAgICAgIGtleVZhbHVlQXJyYXlJbmRleE9mKHJlc2lkdWFsLCB0U3R5bGluZ0tleSkgPj0gMCkge1xuICAgIC8vIFdlIGhhdmUgZHVwbGljYXRlIGluIHRoZSByZXNpZHVhbCBzbyBtYXJrIG91cnNlbHZlcyBhcyBkdXBsaWNhdGUuXG4gICAgdERhdGFbaW5kZXggKyAxXSA9IHNldFRTdHlsaW5nUmFuZ2VOZXh0RHVwbGljYXRlKHREYXRhW2luZGV4ICsgMV0gYXMgVFN0eWxpbmdSYW5nZSk7XG4gIH1cbn1cblxuXG4vKipcbiAqIE1hcmtzIGBUU3R5bGVWYWx1ZWBzIGFzIGR1cGxpY2F0ZXMgaWYgYW5vdGhlciBzdHlsZSBiaW5kaW5nIGluIHRoZSBsaXN0IGhhcyB0aGUgc2FtZVxuICogYFRTdHlsZVZhbHVlYC5cbiAqXG4gKiBOT1RFOiB0aGlzIGZ1bmN0aW9uIGlzIGludGVuZGVkIHRvIGJlIGNhbGxlZCB0d2ljZSBvbmNlIHdpdGggYGlzUHJldkRpcmAgc2V0IHRvIGB0cnVlYCBhbmQgb25jZVxuICogd2l0aCBpdCBzZXQgdG8gYGZhbHNlYCB0byBzZWFyY2ggYm90aCB0aGUgcHJldmlvdXMgYXMgd2VsbCBhcyBuZXh0IGl0ZW1zIGluIHRoZSBsaXN0LlxuICpcbiAqIE5vIGR1cGxpY2F0ZSBjYXNlXG4gKiBgYGBcbiAqICAgW3N0eWxlLmNvbG9yXVxuICogICBbc3R5bGUud2lkdGgucHhdIDw8LSBpbmRleFxuICogICBbc3R5bGUuaGVpZ2h0LnB4XVxuICogYGBgXG4gKlxuICogSW4gdGhlIGFib3ZlIGNhc2UgYWRkaW5nIGBbc3R5bGUud2lkdGgucHhdYCB0byB0aGUgZXhpc3RpbmcgYFtzdHlsZS5jb2xvcl1gIHByb2R1Y2VzIG5vXG4gKiBkdXBsaWNhdGVzIGJlY2F1c2UgYHdpZHRoYCBpcyBub3QgZm91bmQgaW4gYW55IG90aGVyIHBhcnQgb2YgdGhlIGxpbmtlZCBsaXN0LlxuICpcbiAqIER1cGxpY2F0ZSBjYXNlXG4gKiBgYGBcbiAqICAgW3N0eWxlLmNvbG9yXVxuICogICBbc3R5bGUud2lkdGguZW1dXG4gKiAgIFtzdHlsZS53aWR0aC5weF0gPDwtIGluZGV4XG4gKiBgYGBcbiAqIEluIHRoZSBhYm92ZSBjYXNlIGFkZGluZyBgW3N0eWxlLndpZHRoLnB4XWAgd2lsbCBwcm9kdWNlIGEgZHVwbGljYXRlIHdpdGggYFtzdHlsZS53aWR0aC5lbV1gXG4gKiBiZWNhdXNlIGB3aWR0aGAgaXMgZm91bmQgaW4gdGhlIGNoYWluLlxuICpcbiAqIE1hcCBjYXNlIDFcbiAqIGBgYFxuICogICBbc3R5bGUud2lkdGgucHhdXG4gKiAgIFtzdHlsZS5jb2xvcl1cbiAqICAgW3N0eWxlXSAgPDwtIGluZGV4XG4gKiBgYGBcbiAqIEluIHRoZSBhYm92ZSBjYXNlIGFkZGluZyBgW3N0eWxlXWAgd2lsbCBwcm9kdWNlIGEgZHVwbGljYXRlIHdpdGggYW55IG90aGVyIGJpbmRpbmdzIGJlY2F1c2VcbiAqIGBbc3R5bGVdYCBpcyBhIE1hcCBhbmQgYXMgc3VjaCBpcyBmdWxseSBkeW5hbWljIGFuZCBjb3VsZCBwcm9kdWNlIGBjb2xvcmAgb3IgYHdpZHRoYC5cbiAqXG4gKiBNYXAgY2FzZSAyXG4gKiBgYGBcbiAqICAgW3N0eWxlXVxuICogICBbc3R5bGUud2lkdGgucHhdXG4gKiAgIFtzdHlsZS5jb2xvcl0gIDw8LSBpbmRleFxuICogYGBgXG4gKiBJbiB0aGUgYWJvdmUgY2FzZSBhZGRpbmcgYFtzdHlsZS5jb2xvcl1gIHdpbGwgcHJvZHVjZSBhIGR1cGxpY2F0ZSBiZWNhdXNlIHRoZXJlIGlzIGFscmVhZHkgYVxuICogYFtzdHlsZV1gIGJpbmRpbmcgd2hpY2ggaXMgYSBNYXAgYW5kIGFzIHN1Y2ggaXMgZnVsbHkgZHluYW1pYyBhbmQgY291bGQgcHJvZHVjZSBgY29sb3JgIG9yXG4gKiBgd2lkdGhgLlxuICpcbiAqIE5PVEU6IE9uY2UgYFtzdHlsZV1gIChNYXApIGlzIGFkZGVkIGludG8gdGhlIHN5c3RlbSBhbGwgdGhpbmdzIGFyZSBtYXBwZWQgYXMgZHVwbGljYXRlcy5cbiAqIE5PVEU6IFdlIHVzZSBgc3R5bGVgIGFzIGV4YW1wbGUsIGJ1dCBzYW1lIGxvZ2ljIGlzIGFwcGxpZWQgdG8gYGNsYXNzYGVzIGFzIHdlbGwuXG4gKlxuICogQHBhcmFtIHREYXRhIGBURGF0YWAgd2hlcmUgdGhlIGxpbmtlZCBsaXN0IGlzIHN0b3JlZC5cbiAqIEBwYXJhbSB0U3R5bGluZ0tleSBgVFN0eWxpbmdLZXlQcmltaXRpdmVgIHdoaWNoIGNvbnRhaW5zIHRoZSB2YWx1ZSB0byBjb21wYXJlIHRvIG90aGVyIGtleXMgaW5cbiAqICAgICAgICB0aGUgbGlua2VkIGxpc3QuXG4gKiBAcGFyYW0gaW5kZXggU3RhcnRpbmcgbG9jYXRpb24gaW4gdGhlIGxpbmtlZCBsaXN0IHRvIHNlYXJjaCBmcm9tXG4gKiBAcGFyYW0gaXNQcmV2RGlyIERpcmVjdGlvbi5cbiAqICAgICAgICAtIGB0cnVlYCBmb3IgcHJldmlvdXMgKGxvd2VyIHByaW9yaXR5KTtcbiAqICAgICAgICAtIGBmYWxzZWAgZm9yIG5leHQgKGhpZ2hlciBwcmlvcml0eSkuXG4gKi9cbmZ1bmN0aW9uIG1hcmtEdXBsaWNhdGVzKFxuICAgIHREYXRhOiBURGF0YSwgdFN0eWxpbmdLZXk6IFRTdHlsaW5nS2V5UHJpbWl0aXZlLCBpbmRleDogbnVtYmVyLCBpc1ByZXZEaXI6IGJvb2xlYW4sXG4gICAgaXNDbGFzc0JpbmRpbmc6IGJvb2xlYW4pIHtcbiAgY29uc3QgdFN0eWxpbmdBdEluZGV4ID0gdERhdGFbaW5kZXggKyAxXSBhcyBUU3R5bGluZ1JhbmdlO1xuICBjb25zdCBpc01hcCA9IHRTdHlsaW5nS2V5ID09PSBudWxsO1xuICBsZXQgY3Vyc29yID1cbiAgICAgIGlzUHJldkRpciA/IGdldFRTdHlsaW5nUmFuZ2VQcmV2KHRTdHlsaW5nQXRJbmRleCkgOiBnZXRUU3R5bGluZ1JhbmdlTmV4dCh0U3R5bGluZ0F0SW5kZXgpO1xuICBsZXQgZm91bmREdXBsaWNhdGUgPSBmYWxzZTtcbiAgLy8gV2Uga2VlcCBpdGVyYXRpbmcgYXMgbG9uZyBhcyB3ZSBoYXZlIGEgY3Vyc29yXG4gIC8vIEFORCBlaXRoZXI6XG4gIC8vIC0gd2UgZm91bmQgd2hhdCB3ZSBhcmUgbG9va2luZyBmb3IsIE9SXG4gIC8vIC0gd2UgYXJlIGEgbWFwIGluIHdoaWNoIGNhc2Ugd2UgaGF2ZSB0byBjb250aW51ZSBzZWFyY2hpbmcgZXZlbiBhZnRlciB3ZSBmaW5kIHdoYXQgd2Ugd2VyZVxuICAvLyAgIGxvb2tpbmcgZm9yIHNpbmNlIHdlIGFyZSBhIHdpbGQgY2FyZCBhbmQgZXZlcnl0aGluZyBuZWVkcyB0byBiZSBmbGlwcGVkIHRvIGR1cGxpY2F0ZS5cbiAgd2hpbGUgKGN1cnNvciAhPT0gMCAmJiAoZm91bmREdXBsaWNhdGUgPT09IGZhbHNlIHx8IGlzTWFwKSkge1xuICAgIG5nRGV2TW9kZSAmJiBhc3NlcnREYXRhSW5SYW5nZSh0RGF0YSwgY3Vyc29yKTtcbiAgICBjb25zdCB0U3R5bGluZ1ZhbHVlQXRDdXJzb3IgPSB0RGF0YVtjdXJzb3JdIGFzIFRTdHlsaW5nS2V5O1xuICAgIGNvbnN0IHRTdHlsZVJhbmdlQXRDdXJzb3IgPSB0RGF0YVtjdXJzb3IgKyAxXSBhcyBUU3R5bGluZ1JhbmdlO1xuICAgIGlmIChpc1N0eWxpbmdNYXRjaCh0U3R5bGluZ1ZhbHVlQXRDdXJzb3IsIHRTdHlsaW5nS2V5KSkge1xuICAgICAgZm91bmREdXBsaWNhdGUgPSB0cnVlO1xuICAgICAgdERhdGFbY3Vyc29yICsgMV0gPSBpc1ByZXZEaXIgPyBzZXRUU3R5bGluZ1JhbmdlTmV4dER1cGxpY2F0ZSh0U3R5bGVSYW5nZUF0Q3Vyc29yKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNldFRTdHlsaW5nUmFuZ2VQcmV2RHVwbGljYXRlKHRTdHlsZVJhbmdlQXRDdXJzb3IpO1xuICAgIH1cbiAgICBjdXJzb3IgPSBpc1ByZXZEaXIgPyBnZXRUU3R5bGluZ1JhbmdlUHJldih0U3R5bGVSYW5nZUF0Q3Vyc29yKSA6XG4gICAgICAgICAgICAgICAgICAgICAgICAgZ2V0VFN0eWxpbmdSYW5nZU5leHQodFN0eWxlUmFuZ2VBdEN1cnNvcik7XG4gIH1cbiAgaWYgKGZvdW5kRHVwbGljYXRlKSB7XG4gICAgLy8gaWYgd2UgZm91bmQgYSBkdXBsaWNhdGUsIHRoYW4gbWFyayBvdXJzZWx2ZXMuXG4gICAgdERhdGFbaW5kZXggKyAxXSA9IGlzUHJldkRpciA/IHNldFRTdHlsaW5nUmFuZ2VQcmV2RHVwbGljYXRlKHRTdHlsaW5nQXRJbmRleCkgOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBzZXRUU3R5bGluZ1JhbmdlTmV4dER1cGxpY2F0ZSh0U3R5bGluZ0F0SW5kZXgpO1xuICB9XG59XG5cbi8qKlxuICogRGV0ZXJtaW5lcyBpZiB0d28gYFRTdHlsaW5nS2V5YHMgYXJlIGEgbWF0Y2guXG4gKlxuICogV2hlbiBjb21wdXRpbmcgd2VhdGhlciBhIGJpbmRpbmcgY29udGFpbnMgYSBkdXBsaWNhdGUsIHdlIG5lZWQgdG8gY29tcGFyZSBpZiB0aGUgaW5zdHJ1Y3Rpb25cbiAqIGBUU3R5bGluZ0tleWAgaGFzIGEgbWF0Y2guXG4gKlxuICogSGVyZSBhcmUgZXhhbXBsZXMgb2YgYFRTdHlsaW5nS2V5YHMgd2hpY2ggbWF0Y2ggZ2l2ZW4gYHRTdHlsaW5nS2V5Q3Vyc29yYCBpczpcbiAqIC0gYGNvbG9yYFxuICogICAgLSBgY29sb3JgICAgIC8vIE1hdGNoIGFub3RoZXIgY29sb3JcbiAqICAgIC0gYG51bGxgICAgICAvLyBUaGF0IG1lYW5zIHRoYXQgYHRTdHlsaW5nS2V5YCBpcyBhIGBjbGFzc01hcGAvYHN0eWxlTWFwYCBpbnN0cnVjdGlvblxuICogICAgLSBgWycnLCAnY29sb3InLCAnb3RoZXInLCB0cnVlXWAgLy8gd3JhcHBlZCBgY29sb3JgIHNvIG1hdGNoXG4gKiAgICAtIGBbJycsIG51bGwsICdvdGhlcicsIHRydWVdYCAgICAgICAvLyB3cmFwcGVkIGBudWxsYCBzbyBtYXRjaFxuICogICAgLSBgWycnLCAnd2lkdGgnLCAnY29sb3InLCAndmFsdWUnXWAgLy8gd3JhcHBlZCBzdGF0aWMgdmFsdWUgY29udGFpbnMgYSBtYXRjaCBvbiBgJ2NvbG9yJ2BcbiAqIC0gYG51bGxgICAgICAgIC8vIGB0U3R5bGluZ0tleUN1cnNvcmAgYWx3YXlzIG1hdGNoIGFzIGl0IGlzIGBjbGFzc01hcGAvYHN0eWxlTWFwYCBpbnN0cnVjdGlvblxuICpcbiAqIEBwYXJhbSB0U3R5bGluZ0tleUN1cnNvclxuICogQHBhcmFtIHRTdHlsaW5nS2V5XG4gKi9cbmZ1bmN0aW9uIGlzU3R5bGluZ01hdGNoKHRTdHlsaW5nS2V5Q3Vyc29yOiBUU3R5bGluZ0tleSwgdFN0eWxpbmdLZXk6IFRTdHlsaW5nS2V5UHJpbWl0aXZlKSB7XG4gIG5nRGV2TW9kZSAmJlxuICAgICAgYXNzZXJ0Tm90RXF1YWwoXG4gICAgICAgICAgQXJyYXkuaXNBcnJheSh0U3R5bGluZ0tleSksIHRydWUsICdFeHBlY3RlZCB0aGF0IFxcJ3RTdHlsaW5nS2V5XFwnIGhhcyBiZWVuIHVud3JhcHBlZCcpO1xuICBpZiAodFN0eWxpbmdLZXlDdXJzb3IgPT09IG51bGwgfHwgIC8vIElmIHRoZSBjdXJzb3IgaXMgYG51bGxgIGl0IG1lYW5zIHRoYXQgd2UgaGF2ZSBtYXAgYXQgdGhhdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGxvY2F0aW9uIHNvIHdlIG11c3QgYXNzdW1lIHRoYXQgd2UgaGF2ZSBhIG1hdGNoLlxuICAgICAgdFN0eWxpbmdLZXkgPT0gbnVsbCB8fCAgLy8gSWYgYHRTdHlsaW5nS2V5YCBpcyBgbnVsbGAgdGhlbiBpdCBpcyBhIG1hcCB0aGVyZWZvciBhc3N1bWUgdGhhdCBpdFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gY29udGFpbnMgYSBtYXRjaC5cbiAgICAgIChBcnJheS5pc0FycmF5KHRTdHlsaW5nS2V5Q3Vyc29yKSA/IHRTdHlsaW5nS2V5Q3Vyc29yWzFdIDogdFN0eWxpbmdLZXlDdXJzb3IpID09PVxuICAgICAgICAgIHRTdHlsaW5nS2V5ICAvLyBJZiB0aGUga2V5cyBtYXRjaCBleHBsaWNpdGx5IHRoYW4gd2UgYXJlIGEgbWF0Y2guXG4gICAgICApIHtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIGlmIChBcnJheS5pc0FycmF5KHRTdHlsaW5nS2V5Q3Vyc29yKSAmJiB0eXBlb2YgdFN0eWxpbmdLZXkgPT09ICdzdHJpbmcnKSB7XG4gICAgLy8gaWYgd2UgZGlkIG5vdCBmaW5kIGEgbWF0Y2gsIGJ1dCBgdFN0eWxpbmdLZXlDdXJzb3JgIGlzIGBLZXlWYWx1ZUFycmF5YCB0aGF0IG1lYW5zIGN1cnNvciBoYXNcbiAgICAvLyBzdGF0aWNzIGFuZCB3ZSBuZWVkIHRvIGNoZWNrIHRob3NlIGFzIHdlbGwuXG4gICAgcmV0dXJuIGtleVZhbHVlQXJyYXlJbmRleE9mKHRTdHlsaW5nS2V5Q3Vyc29yLCB0U3R5bGluZ0tleSkgPj1cbiAgICAgICAgMDsgIC8vIHNlZSBpZiB3ZSBhcmUgbWF0Y2hpbmcgdGhlIGtleVxuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cbiJdfQ==