@sbb-esta/lyne-elements-experimental-dev 0.0.0 → 4.5.1-dev.1771849274

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 (249) hide show
  1. package/README.md +55 -0
  2. package/autocomplete-grid/autocomplete-grid/autocomplete-grid.component.js +86 -0
  3. package/autocomplete-grid/autocomplete-grid-button/autocomplete-grid-button.component.js +54 -0
  4. package/autocomplete-grid/autocomplete-grid-button.js +4 -0
  5. package/autocomplete-grid/autocomplete-grid-cell/autocomplete-grid-cell.component.js +25 -0
  6. package/autocomplete-grid/autocomplete-grid-cell.js +4 -0
  7. package/autocomplete-grid/autocomplete-grid-optgroup/autocomplete-grid-optgroup.component.js +29 -0
  8. package/autocomplete-grid/autocomplete-grid-optgroup.js +4 -0
  9. package/autocomplete-grid/autocomplete-grid-option/autocomplete-grid-option.component.js +41 -0
  10. package/autocomplete-grid/autocomplete-grid-option.js +5 -0
  11. package/autocomplete-grid/autocomplete-grid-row/autocomplete-grid-row.component.js +28 -0
  12. package/autocomplete-grid/autocomplete-grid-row.js +4 -0
  13. package/autocomplete-grid/autocomplete-grid.js +4 -0
  14. package/autocomplete-grid.js +15 -0
  15. package/core/datetime/date-helper.js +191 -0
  16. package/core/datetime.js +5 -0
  17. package/core/timetable/access-leg-helper.js +91 -0
  18. package/core/timetable/timetable-helper.js +12 -0
  19. package/core/timetable/timetable-properties.js +1 -0
  20. package/core/timetable.js +8 -0
  21. package/custom-elements.json +8211 -0
  22. package/development/autocomplete-grid/autocomplete-grid/autocomplete-grid.component.d.ts +39 -0
  23. package/development/autocomplete-grid/autocomplete-grid/autocomplete-grid.component.d.ts.map +1 -0
  24. package/development/autocomplete-grid/autocomplete-grid/autocomplete-grid.component.js +141 -0
  25. package/development/autocomplete-grid/autocomplete-grid-button/autocomplete-grid-button.component.d.ts +31 -0
  26. package/development/autocomplete-grid/autocomplete-grid-button/autocomplete-grid-button.component.d.ts.map +1 -0
  27. package/development/autocomplete-grid/autocomplete-grid-button/autocomplete-grid-button.component.js +82 -0
  28. package/development/autocomplete-grid/autocomplete-grid-button.d.ts +5 -0
  29. package/development/autocomplete-grid/autocomplete-grid-button.d.ts.map +1 -0
  30. package/development/autocomplete-grid/autocomplete-grid-button.js +5 -0
  31. package/development/autocomplete-grid/autocomplete-grid-cell/autocomplete-grid-cell.component.d.ts +19 -0
  32. package/development/autocomplete-grid/autocomplete-grid-cell/autocomplete-grid-cell.component.d.ts.map +1 -0
  33. package/development/autocomplete-grid/autocomplete-grid-cell/autocomplete-grid-cell.component.js +40 -0
  34. package/development/autocomplete-grid/autocomplete-grid-cell.d.ts +5 -0
  35. package/development/autocomplete-grid/autocomplete-grid-cell.d.ts.map +1 -0
  36. package/development/autocomplete-grid/autocomplete-grid-cell.js +5 -0
  37. package/development/autocomplete-grid/autocomplete-grid-optgroup/autocomplete-grid-optgroup.component.d.ts +19 -0
  38. package/development/autocomplete-grid/autocomplete-grid-optgroup/autocomplete-grid-optgroup.component.d.ts.map +1 -0
  39. package/development/autocomplete-grid/autocomplete-grid-optgroup/autocomplete-grid-optgroup.component.js +40 -0
  40. package/development/autocomplete-grid/autocomplete-grid-optgroup.d.ts +5 -0
  41. package/development/autocomplete-grid/autocomplete-grid-optgroup.d.ts.map +1 -0
  42. package/development/autocomplete-grid/autocomplete-grid-optgroup.js +5 -0
  43. package/development/autocomplete-grid/autocomplete-grid-option/autocomplete-grid-option.component.d.ts +26 -0
  44. package/development/autocomplete-grid/autocomplete-grid-option/autocomplete-grid-option.component.d.ts.map +1 -0
  45. package/development/autocomplete-grid/autocomplete-grid-option/autocomplete-grid-option.component.js +134 -0
  46. package/development/autocomplete-grid/autocomplete-grid-option.d.ts +5 -0
  47. package/development/autocomplete-grid/autocomplete-grid-option.d.ts.map +1 -0
  48. package/development/autocomplete-grid/autocomplete-grid-option.js +6 -0
  49. package/development/autocomplete-grid/autocomplete-grid-row/autocomplete-grid-row.component.d.ts +20 -0
  50. package/development/autocomplete-grid/autocomplete-grid-row/autocomplete-grid-row.component.d.ts.map +1 -0
  51. package/development/autocomplete-grid/autocomplete-grid-row/autocomplete-grid-row.component.js +115 -0
  52. package/development/autocomplete-grid/autocomplete-grid-row.d.ts +5 -0
  53. package/development/autocomplete-grid/autocomplete-grid-row.d.ts.map +1 -0
  54. package/development/autocomplete-grid/autocomplete-grid-row.js +5 -0
  55. package/development/autocomplete-grid/autocomplete-grid.d.ts +5 -0
  56. package/development/autocomplete-grid/autocomplete-grid.d.ts.map +1 -0
  57. package/development/autocomplete-grid/autocomplete-grid.js +5 -0
  58. package/development/autocomplete-grid.d.ts +10 -0
  59. package/development/autocomplete-grid.d.ts.map +1 -0
  60. package/development/autocomplete-grid.js +16 -0
  61. package/development/core/datetime/date-helper.d.ts +27 -0
  62. package/development/core/datetime/date-helper.d.ts.map +1 -0
  63. package/development/core/datetime/date-helper.js +285 -0
  64. package/development/core/datetime.d.ts +5 -0
  65. package/development/core/datetime.d.ts.map +1 -0
  66. package/development/core/datetime.js +6 -0
  67. package/development/core/timetable/access-leg-helper.d.ts +26 -0
  68. package/development/core/timetable/access-leg-helper.d.ts.map +1 -0
  69. package/development/core/timetable/access-leg-helper.js +125 -0
  70. package/development/core/timetable/timetable-helper.d.ts +12 -0
  71. package/development/core/timetable/timetable-helper.d.ts.map +1 -0
  72. package/development/core/timetable/timetable-helper.js +20 -0
  73. package/development/core/timetable/timetable-properties.d.ts +308 -0
  74. package/development/core/timetable/timetable-properties.d.ts.map +1 -0
  75. package/development/core/timetable/timetable-properties.js +2 -0
  76. package/development/core/timetable.d.ts +7 -0
  77. package/development/core/timetable.d.ts.map +1 -0
  78. package/development/core/timetable.js +9 -0
  79. package/development/differenceInMinutes-B0dawX-5.js +26 -0
  80. package/development/format-BMkeaqaF.js +1433 -0
  81. package/development/isValid-BYRch7pV.js +53 -0
  82. package/development/journey-summary/journey-summary.component.d.ts +65 -0
  83. package/development/journey-summary/journey-summary.component.d.ts.map +1 -0
  84. package/development/journey-summary/journey-summary.component.js +294 -0
  85. package/development/journey-summary.d.ts +5 -0
  86. package/development/journey-summary.d.ts.map +1 -0
  87. package/development/journey-summary.js +5 -0
  88. package/development/pearl-chain/pearl-chain.component.d.ts +42 -0
  89. package/development/pearl-chain/pearl-chain.component.d.ts.map +1 -0
  90. package/development/pearl-chain/pearl-chain.component.js +639 -0
  91. package/development/pearl-chain-time/pearl-chain-time.component.d.ts +47 -0
  92. package/development/pearl-chain-time/pearl-chain-time.component.d.ts.map +1 -0
  93. package/development/pearl-chain-time/pearl-chain-time.component.js +312 -0
  94. package/development/pearl-chain-time.d.ts +5 -0
  95. package/development/pearl-chain-time.d.ts.map +1 -0
  96. package/development/pearl-chain-time.js +5 -0
  97. package/development/pearl-chain-vertical/pearl-chain-vertical.component.d.ts +16 -0
  98. package/development/pearl-chain-vertical/pearl-chain-vertical.component.d.ts.map +1 -0
  99. package/development/pearl-chain-vertical/pearl-chain-vertical.component.js +40 -0
  100. package/development/pearl-chain-vertical-item/pearl-chain-vertical-item.component.d.ts +34 -0
  101. package/development/pearl-chain-vertical-item/pearl-chain-vertical-item.component.d.ts.map +1 -0
  102. package/development/pearl-chain-vertical-item/pearl-chain-vertical-item.component.js +398 -0
  103. package/development/pearl-chain-vertical-item.d.ts +5 -0
  104. package/development/pearl-chain-vertical-item.d.ts.map +1 -0
  105. package/development/pearl-chain-vertical-item.js +5 -0
  106. package/development/pearl-chain-vertical.d.ts +5 -0
  107. package/development/pearl-chain-vertical.d.ts.map +1 -0
  108. package/development/pearl-chain-vertical.js +5 -0
  109. package/development/pearl-chain.d.ts +5 -0
  110. package/development/pearl-chain.d.ts.map +1 -0
  111. package/development/pearl-chain.js +5 -0
  112. package/development/seat-reservation/common/mapper/icon-mapper.d.ts +106 -0
  113. package/development/seat-reservation/common/mapper/icon-mapper.d.ts.map +1 -0
  114. package/development/seat-reservation/common/mapper/icon-mapper.js +72 -0
  115. package/development/seat-reservation/common/mapper/mapper.d.ts +34 -0
  116. package/development/seat-reservation/common/mapper/mapper.d.ts.map +1 -0
  117. package/development/seat-reservation/common/mapper/mapper.js +129 -0
  118. package/development/seat-reservation/common/mapper/seat-reservation-sample-data.d.ts +372 -0
  119. package/development/seat-reservation/common/mapper/seat-reservation-sample-data.d.ts.map +1 -0
  120. package/development/seat-reservation/common/mapper/seat-reservation-sample-data.js +31673 -0
  121. package/development/seat-reservation/common/mapper.d.ts +3 -0
  122. package/development/seat-reservation/common/mapper.d.ts.map +1 -0
  123. package/development/seat-reservation/common/mapper.js +10 -0
  124. package/development/seat-reservation/common/svgs.d.ts +24 -0
  125. package/development/seat-reservation/common/svgs.d.ts.map +1 -0
  126. package/development/seat-reservation/common/svgs.js +46 -0
  127. package/development/seat-reservation/common/translations/i18n.d.ts +28 -0
  128. package/development/seat-reservation/common/translations/i18n.d.ts.map +1 -0
  129. package/development/seat-reservation/common/translations/i18n.js +871 -0
  130. package/development/seat-reservation/common/translations.d.ts +2 -0
  131. package/development/seat-reservation/common/translations.d.ts.map +1 -0
  132. package/development/seat-reservation/common/translations.js +5 -0
  133. package/development/seat-reservation/common/types.d.ts +97 -0
  134. package/development/seat-reservation/common/types.d.ts.map +1 -0
  135. package/development/seat-reservation/common/types.js +2 -0
  136. package/development/seat-reservation/common.d.ts +8 -0
  137. package/development/seat-reservation/common.d.ts.map +1 -0
  138. package/development/seat-reservation/common.js +14 -0
  139. package/development/seat-reservation/seat-reservation/seat-reservation-base-element.d.ts +273 -0
  140. package/development/seat-reservation/seat-reservation/seat-reservation-base-element.d.ts.map +1 -0
  141. package/development/seat-reservation/seat-reservation/seat-reservation-base-element.js +1171 -0
  142. package/development/seat-reservation/seat-reservation/seat-reservation.component.d.ts +75 -0
  143. package/development/seat-reservation/seat-reservation/seat-reservation.component.d.ts.map +1 -0
  144. package/development/seat-reservation/seat-reservation/seat-reservation.component.js +832 -0
  145. package/development/seat-reservation/seat-reservation-area/seat-reservation-area.component.d.ts +18 -0
  146. package/development/seat-reservation/seat-reservation-area/seat-reservation-area.component.d.ts.map +1 -0
  147. package/development/seat-reservation/seat-reservation-area/seat-reservation-area.component.js +112 -0
  148. package/development/seat-reservation/seat-reservation-area.d.ts +5 -0
  149. package/development/seat-reservation/seat-reservation-area.d.ts.map +1 -0
  150. package/development/seat-reservation/seat-reservation-area.js +5 -0
  151. package/development/seat-reservation/seat-reservation-graphic/seat-reservation-assets.d.ts +9 -0
  152. package/development/seat-reservation/seat-reservation-graphic/seat-reservation-assets.d.ts.map +1 -0
  153. package/development/seat-reservation/seat-reservation-graphic/seat-reservation-assets.js +303 -0
  154. package/development/seat-reservation/seat-reservation-graphic/seat-reservation-graphic.component.d.ts +20 -0
  155. package/development/seat-reservation/seat-reservation-graphic/seat-reservation-graphic.component.d.ts.map +1 -0
  156. package/development/seat-reservation/seat-reservation-graphic/seat-reservation-graphic.component.js +167 -0
  157. package/development/seat-reservation/seat-reservation-graphic.d.ts +5 -0
  158. package/development/seat-reservation/seat-reservation-graphic.d.ts.map +1 -0
  159. package/development/seat-reservation/seat-reservation-graphic.js +5 -0
  160. package/development/seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.d.ts +65 -0
  161. package/development/seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.d.ts.map +1 -0
  162. package/development/seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.js +798 -0
  163. package/development/seat-reservation/seat-reservation-navigation-coach.d.ts +5 -0
  164. package/development/seat-reservation/seat-reservation-navigation-coach.d.ts.map +1 -0
  165. package/development/seat-reservation/seat-reservation-navigation-coach.js +5 -0
  166. package/development/seat-reservation/seat-reservation-navigation-services/seat-reservation-navigation-services.component.d.ts +21 -0
  167. package/development/seat-reservation/seat-reservation-navigation-services/seat-reservation-navigation-services.component.d.ts.map +1 -0
  168. package/development/seat-reservation/seat-reservation-navigation-services/seat-reservation-navigation-services.component.js +120 -0
  169. package/development/seat-reservation/seat-reservation-navigation-services.d.ts +5 -0
  170. package/development/seat-reservation/seat-reservation-navigation-services.d.ts.map +1 -0
  171. package/development/seat-reservation/seat-reservation-navigation-services.js +5 -0
  172. package/development/seat-reservation/seat-reservation-place-control/seat-reservation-place-control.component.d.ts +42 -0
  173. package/development/seat-reservation/seat-reservation-place-control/seat-reservation-place-control.component.d.ts.map +1 -0
  174. package/development/seat-reservation/seat-reservation-place-control/seat-reservation-place-control.component.js +462 -0
  175. package/development/seat-reservation/seat-reservation-place-control.d.ts +5 -0
  176. package/development/seat-reservation/seat-reservation-place-control.d.ts.map +1 -0
  177. package/development/seat-reservation/seat-reservation-place-control.js +5 -0
  178. package/development/seat-reservation/seat-reservation-scoped/seat-reservation-scoped.component.d.ts +14 -0
  179. package/development/seat-reservation/seat-reservation-scoped/seat-reservation-scoped.component.d.ts.map +1 -0
  180. package/development/seat-reservation/seat-reservation-scoped/seat-reservation-scoped.component.js +34 -0
  181. package/development/seat-reservation/seat-reservation-scoped.d.ts +5 -0
  182. package/development/seat-reservation/seat-reservation-scoped.d.ts.map +1 -0
  183. package/development/seat-reservation/seat-reservation-scoped.js +5 -0
  184. package/development/seat-reservation/seat-reservation.d.ts +6 -0
  185. package/development/seat-reservation/seat-reservation.d.ts.map +1 -0
  186. package/development/seat-reservation/seat-reservation.js +7 -0
  187. package/development/seat-reservation.d.ts +12 -0
  188. package/development/seat-reservation.d.ts.map +1 -0
  189. package/development/seat-reservation.js +30 -0
  190. package/development/timetable-duration/timetable-duration.component.d.ts +22 -0
  191. package/development/timetable-duration/timetable-duration.component.d.ts.map +1 -0
  192. package/development/timetable-duration/timetable-duration.component.js +114 -0
  193. package/development/timetable-duration.d.ts +5 -0
  194. package/development/timetable-duration.d.ts.map +1 -0
  195. package/development/timetable-duration.js +5 -0
  196. package/development/timetable-row/timetable-row.component.d.ts +87 -0
  197. package/development/timetable-row/timetable-row.component.d.ts.map +1 -0
  198. package/development/timetable-row/timetable-row.component.js +787 -0
  199. package/development/timetable-row.d.ts +5 -0
  200. package/development/timetable-row.d.ts.map +1 -0
  201. package/development/timetable-row.js +12 -0
  202. package/development/toDate-BWb6Z1JD.js +24 -0
  203. package/differenceInMinutes-COvvdYsJ.js +23 -0
  204. package/format-CmKROkbc.js +1186 -0
  205. package/index.d.ts +44 -0
  206. package/index.js +43 -0
  207. package/isValid-m3_OsPaB.js +45 -0
  208. package/journey-summary/journey-summary.component.js +193 -0
  209. package/journey-summary.js +4 -0
  210. package/package.json +161 -1
  211. package/pearl-chain/pearl-chain.component.js +164 -0
  212. package/pearl-chain-time/pearl-chain-time.component.js +156 -0
  213. package/pearl-chain-time.js +4 -0
  214. package/pearl-chain-vertical/pearl-chain-vertical.component.js +24 -0
  215. package/pearl-chain-vertical-item/pearl-chain-vertical-item.component.js +76 -0
  216. package/pearl-chain-vertical-item.js +4 -0
  217. package/pearl-chain-vertical.js +4 -0
  218. package/pearl-chain.js +4 -0
  219. package/seat-reservation/common/mapper/icon-mapper.js +71 -0
  220. package/seat-reservation/common/mapper/mapper.js +89 -0
  221. package/seat-reservation/common/mapper/seat-reservation-sample-data.js +31668 -0
  222. package/seat-reservation/common/mapper.js +9 -0
  223. package/seat-reservation/common/svgs.js +243 -0
  224. package/seat-reservation/common/translations/i18n.js +861 -0
  225. package/seat-reservation/common/translations.js +4 -0
  226. package/seat-reservation/common/types.js +1 -0
  227. package/seat-reservation/common.js +13 -0
  228. package/seat-reservation/seat-reservation/seat-reservation-base-element.js +756 -0
  229. package/seat-reservation/seat-reservation/seat-reservation.component.js +410 -0
  230. package/seat-reservation/seat-reservation-area/seat-reservation-area.component.js +50 -0
  231. package/seat-reservation/seat-reservation-area.js +4 -0
  232. package/seat-reservation/seat-reservation-graphic/seat-reservation-assets.js +292 -0
  233. package/seat-reservation/seat-reservation-graphic/seat-reservation-graphic.component.js +73 -0
  234. package/seat-reservation/seat-reservation-graphic.js +4 -0
  235. package/seat-reservation/seat-reservation-navigation-coach/seat-reservation-navigation-coach.component.js +277 -0
  236. package/seat-reservation/seat-reservation-navigation-coach.js +4 -0
  237. package/seat-reservation/seat-reservation-navigation-services/seat-reservation-navigation-services.component.js +73 -0
  238. package/seat-reservation/seat-reservation-navigation-services.js +4 -0
  239. package/seat-reservation/seat-reservation-place-control/seat-reservation-place-control.component.js +167 -0
  240. package/seat-reservation/seat-reservation-place-control.js +4 -0
  241. package/seat-reservation/seat-reservation-scoped/seat-reservation-scoped.component.js +20 -0
  242. package/seat-reservation/seat-reservation-scoped.js +4 -0
  243. package/seat-reservation/seat-reservation.js +6 -0
  244. package/seat-reservation.js +29 -0
  245. package/timetable-duration/timetable-duration.component.js +56 -0
  246. package/timetable-duration.js +4 -0
  247. package/timetable-row/timetable-row.component.js +426 -0
  248. package/timetable-row.js +11 -0
  249. package/toDate-Bw2KTWeq.js +15 -0
@@ -0,0 +1,1171 @@
1
+ var __typeError = (msg) => {
2
+ throw TypeError(msg);
3
+ };
4
+ var __accessCheck = (obj, member, msg) => member.has(obj) || __typeError("Cannot " + msg);
5
+ var __privateGet = (obj, member, getter) => (__accessCheck(obj, member, "read from private field"), getter ? getter.call(obj) : member.get(obj));
6
+ var __privateAdd = (obj, member, value) => member.has(obj) ? __typeError("Cannot add the same private member more than once") : member instanceof WeakSet ? member.add(obj) : member.set(obj, value);
7
+ var __privateSet = (obj, member, value, setter) => (__accessCheck(obj, member, "write to private field"), setter ? setter.call(obj, value) : member.set(obj, value), value);
8
+ import { __runInitializers, __esDecorate } from "tslib";
9
+ import { isArrowKeyOrPageKeysPressed } from "@sbb-esta/lyne-elements/core/a11y.js";
10
+ import { forceType } from "@sbb-esta/lyne-elements/core/decorators.js";
11
+ import { LitElement, isServer } from "lit";
12
+ import { property, state, eventOptions } from "lit/decorators.js";
13
+ import { mapIconToSvg, mapPlaceInfosToPlaceSelection, mapPlaceAndCoachToSeatReservationPlaceSelection, mapCoachInfosToCoachSelection } from "../common/mapper.js";
14
+ var ScrollDirection;
15
+ (function(ScrollDirection2) {
16
+ ScrollDirection2["right"] = "right";
17
+ ScrollDirection2["left"] = "left";
18
+ })(ScrollDirection || (ScrollDirection = {}));
19
+ const MAX_SERVICE_PROPERTIES = 3;
20
+ const ALLOWED_SERVICE_ICONS = [
21
+ "sa-vo",
22
+ "sa-rs",
23
+ "sa-abteilkinderwagen",
24
+ "sa-wr",
25
+ "sa-fa",
26
+ "sa-bz",
27
+ "sa-rz"
28
+ ];
29
+ let SeatReservationBaseElement = (() => {
30
+ var _seatReservations_accessor_storage, _hasNavigation_accessor_storage, _alignVertical_accessor_storage, _baseGridSize_accessor_storage, _height_accessor_storage, _maxSeatReservations_accessor_storage, _maxBicycleReservations_accessor_storage, _preventPlaceClick_accessor_storage, _preselectCoachIndex_accessor_storage, _selectedCoachIndex_accessor_storage, _focusedCoachIndex_accessor_storage, _hoveredCoachIndex_accessor_storage, _a;
31
+ let _classSuper = LitElement;
32
+ let _instanceExtraInitializers = [];
33
+ let _seatReservations_decorators;
34
+ let _seatReservations_initializers = [];
35
+ let _seatReservations_extraInitializers = [];
36
+ let _hasNavigation_decorators;
37
+ let _hasNavigation_initializers = [];
38
+ let _hasNavigation_extraInitializers = [];
39
+ let _alignVertical_decorators;
40
+ let _alignVertical_initializers = [];
41
+ let _alignVertical_extraInitializers = [];
42
+ let _baseGridSize_decorators;
43
+ let _baseGridSize_initializers = [];
44
+ let _baseGridSize_extraInitializers = [];
45
+ let _height_decorators;
46
+ let _height_initializers = [];
47
+ let _height_extraInitializers = [];
48
+ let _maxSeatReservations_decorators;
49
+ let _maxSeatReservations_initializers = [];
50
+ let _maxSeatReservations_extraInitializers = [];
51
+ let _maxBicycleReservations_decorators;
52
+ let _maxBicycleReservations_initializers = [];
53
+ let _maxBicycleReservations_extraInitializers = [];
54
+ let _preventPlaceClick_decorators;
55
+ let _preventPlaceClick_initializers = [];
56
+ let _preventPlaceClick_extraInitializers = [];
57
+ let _preselectCoachIndex_decorators;
58
+ let _preselectCoachIndex_initializers = [];
59
+ let _preselectCoachIndex_extraInitializers = [];
60
+ let _selectedCoachIndex_decorators;
61
+ let _selectedCoachIndex_initializers = [];
62
+ let _selectedCoachIndex_extraInitializers = [];
63
+ let _focusedCoachIndex_decorators;
64
+ let _focusedCoachIndex_initializers = [];
65
+ let _focusedCoachIndex_extraInitializers = [];
66
+ let _hoveredCoachIndex_decorators;
67
+ let _hoveredCoachIndex_initializers = [];
68
+ let _hoveredCoachIndex_extraInitializers = [];
69
+ let _coachAreaScrollend_decorators;
70
+ return _a = class extends _classSuper {
71
+ constructor() {
72
+ super(...arguments);
73
+ __privateAdd(this, _seatReservations_accessor_storage);
74
+ __privateAdd(this, _hasNavigation_accessor_storage);
75
+ __privateAdd(this, _alignVertical_accessor_storage);
76
+ __privateAdd(this, _baseGridSize_accessor_storage);
77
+ __privateAdd(this, _height_accessor_storage);
78
+ __privateAdd(this, _maxSeatReservations_accessor_storage);
79
+ __privateAdd(this, _maxBicycleReservations_accessor_storage);
80
+ __privateAdd(this, _preventPlaceClick_accessor_storage);
81
+ __privateAdd(this, _preselectCoachIndex_accessor_storage);
82
+ __privateAdd(this, _selectedCoachIndex_accessor_storage);
83
+ __privateAdd(this, _focusedCoachIndex_accessor_storage);
84
+ __privateAdd(this, _hoveredCoachIndex_accessor_storage);
85
+ __privateSet(this, _seatReservations_accessor_storage, (__runInitializers(this, _instanceExtraInitializers), __runInitializers(this, _seatReservations_initializers, null)));
86
+ __privateSet(this, _hasNavigation_accessor_storage, (__runInitializers(this, _seatReservations_extraInitializers), __runInitializers(this, _hasNavigation_initializers, true)));
87
+ __privateSet(this, _alignVertical_accessor_storage, (__runInitializers(this, _hasNavigation_extraInitializers), __runInitializers(this, _alignVertical_initializers, false)));
88
+ __privateSet(this, _baseGridSize_accessor_storage, (__runInitializers(this, _alignVertical_extraInitializers), __runInitializers(this, _baseGridSize_initializers, 16)));
89
+ __privateSet(this, _height_accessor_storage, (__runInitializers(this, _baseGridSize_extraInitializers), __runInitializers(this, _height_initializers, null)));
90
+ __privateSet(this, _maxSeatReservations_accessor_storage, (__runInitializers(this, _height_extraInitializers), __runInitializers(this, _maxSeatReservations_initializers, -1)));
91
+ __privateSet(this, _maxBicycleReservations_accessor_storage, (__runInitializers(this, _maxSeatReservations_extraInitializers), __runInitializers(this, _maxBicycleReservations_initializers, -1)));
92
+ __privateSet(this, _preventPlaceClick_accessor_storage, (__runInitializers(this, _maxBicycleReservations_extraInitializers), __runInitializers(this, _preventPlaceClick_initializers, false)));
93
+ __privateSet(this, _preselectCoachIndex_accessor_storage, (__runInitializers(this, _preventPlaceClick_extraInitializers), __runInitializers(this, _preselectCoachIndex_initializers, -1)));
94
+ __privateSet(this, _selectedCoachIndex_accessor_storage, (__runInitializers(this, _preselectCoachIndex_extraInitializers), __runInitializers(this, _selectedCoachIndex_initializers, -1)));
95
+ __privateSet(this, _focusedCoachIndex_accessor_storage, (__runInitializers(this, _selectedCoachIndex_extraInitializers), __runInitializers(this, _focusedCoachIndex_initializers, -1)));
96
+ __privateSet(this, _hoveredCoachIndex_accessor_storage, (__runInitializers(this, _focusedCoachIndex_extraInitializers), __runInitializers(this, _hoveredCoachIndex_initializers, -1)));
97
+ this.coachBorderPadding = (__runInitializers(this, _hoveredCoachIndex_extraInitializers), 6);
98
+ this.gapBetweenCoaches = 4;
99
+ this.coachBorderOffset = this.coachBorderPadding / this.baseGridSize;
100
+ this.gapBetweenCoachDecks = 48;
101
+ this.coachNavButtonDim = 0;
102
+ this.coachNavData = [];
103
+ this.currScrollDirection = ScrollDirection.right;
104
+ this.maxCalcCoachesWidth = 0;
105
+ this.scrollCoachesAreaWidth = 0;
106
+ this.scrollNavigationAreaDim = 0;
107
+ this.triggerCoachPositionsCollection = [];
108
+ this.navigationScrollArea = null;
109
+ this.coachScrollArea = null;
110
+ this.currSelectedPlace = null;
111
+ this.currSelectedPlaceElementId = null;
112
+ this.currSelectedCoachIndex = -1;
113
+ this.currSelectedDeckIndex = 0;
114
+ this.preventCoachScrollByPlaceClick = false;
115
+ this.selectedSeatReservationPlaces = {
116
+ seats: [],
117
+ bicycles: []
118
+ };
119
+ this.seatReservationWithoutNavigationHasFocus = false;
120
+ this.isCoachGridFocusable = false;
121
+ this.isAutoScrolling = false;
122
+ this.isKeyboardNavigation = false;
123
+ this.hasMultipleDecks = false;
124
+ this.hasSeatReservationNativeFocus = false;
125
+ this.keyboardNavigationEvents = {
126
+ ArrowLeft: "ArrowLeft",
127
+ ArrowRight: "ArrowRight",
128
+ ArrowUp: "ArrowUp",
129
+ ArrowDown: "ArrowDown",
130
+ Tab: "Tab",
131
+ Enter: "Enter"
132
+ };
133
+ this.notAreaElements = [
134
+ "DRIVER_AREA",
135
+ "COACH_PASSAGE",
136
+ "COACH_WALL_NO_PASSAGE",
137
+ "COMPARTMENT_PASSAGE",
138
+ "COMPARTMENT_PASSAGE_HIGH",
139
+ "COMPARTMENT_PASSAGE_MIDDLE",
140
+ "COMPARTMENT_PASSAGE_LOW"
141
+ ];
142
+ this.overHangingElementInformation = [];
143
+ this._isRunningInitPreselectCoachIndex = false;
144
+ this._lastStartScrollPos = -1;
145
+ this._prepareServiceIconsNavigation = (propertyIds) => {
146
+ if (!propertyIds) {
147
+ return [];
148
+ }
149
+ const shrunkPropertyIds = propertyIds?.map(function(propertyId) {
150
+ return {
151
+ pId: propertyId,
152
+ svgName: mapIconToSvg[propertyId]?.svgName ? mapIconToSvg[propertyId]?.svgName : ""
153
+ };
154
+ }).filter((propertyToSvg) => ALLOWED_SERVICE_ICONS.indexOf(propertyToSvg.svgName) !== -1).filter((value, index, self) => self.map((propSvg) => propSvg.svgName).indexOf(value.svgName) === index).map((propertyToSvg) => propertyToSvg.pId).slice(0, MAX_SERVICE_PROPERTIES);
155
+ return shrunkPropertyIds ? shrunkPropertyIds : [];
156
+ };
157
+ }
158
+ /** The seat reservations array contains all coaches and places */
159
+ get seatReservations() {
160
+ return __privateGet(this, _seatReservations_accessor_storage);
161
+ }
162
+ set seatReservations(value) {
163
+ __privateSet(this, _seatReservations_accessor_storage, value);
164
+ }
165
+ /** The seat reservation navigation can be toggled by this property */
166
+ get hasNavigation() {
167
+ return __privateGet(this, _hasNavigation_accessor_storage);
168
+ }
169
+ set hasNavigation(value) {
170
+ __privateSet(this, _hasNavigation_accessor_storage, value);
171
+ }
172
+ /** The seat reservation area is aligned vertically */
173
+ get alignVertical() {
174
+ return __privateGet(this, _alignVertical_accessor_storage);
175
+ }
176
+ set alignVertical(value) {
177
+ __privateSet(this, _alignVertical_accessor_storage, value);
178
+ }
179
+ /** The seat reservation area's base grid size */
180
+ get baseGridSize() {
181
+ return __privateGet(this, _baseGridSize_accessor_storage);
182
+ }
183
+ set baseGridSize(value) {
184
+ __privateSet(this, _baseGridSize_accessor_storage, value);
185
+ }
186
+ /** The seat reservation area's width */
187
+ get height() {
188
+ return __privateGet(this, _height_accessor_storage);
189
+ }
190
+ set height(value) {
191
+ __privateSet(this, _height_accessor_storage, value);
192
+ }
193
+ /** Maximal number of possible clickable seats */
194
+ get maxSeatReservations() {
195
+ return __privateGet(this, _maxSeatReservations_accessor_storage);
196
+ }
197
+ set maxSeatReservations(value) {
198
+ __privateSet(this, _maxSeatReservations_accessor_storage, value);
199
+ }
200
+ /** Maximal number of possible clickable bicycle places */
201
+ get maxBicycleReservations() {
202
+ return __privateGet(this, _maxBicycleReservations_accessor_storage);
203
+ }
204
+ set maxBicycleReservations(value) {
205
+ __privateSet(this, _maxBicycleReservations_accessor_storage, value);
206
+ }
207
+ /** Any click functionality is prevented */
208
+ get preventPlaceClick() {
209
+ return __privateGet(this, _preventPlaceClick_accessor_storage);
210
+ }
211
+ set preventPlaceClick(value) {
212
+ __privateSet(this, _preventPlaceClick_accessor_storage, value);
213
+ }
214
+ get preselectCoachIndex() {
215
+ return __privateGet(this, _preselectCoachIndex_accessor_storage);
216
+ }
217
+ set preselectCoachIndex(value) {
218
+ __privateSet(this, _preselectCoachIndex_accessor_storage, value);
219
+ }
220
+ get selectedCoachIndex() {
221
+ return __privateGet(this, _selectedCoachIndex_accessor_storage);
222
+ }
223
+ set selectedCoachIndex(value) {
224
+ __privateSet(this, _selectedCoachIndex_accessor_storage, value);
225
+ }
226
+ get focusedCoachIndex() {
227
+ return __privateGet(this, _focusedCoachIndex_accessor_storage);
228
+ }
229
+ set focusedCoachIndex(value) {
230
+ __privateSet(this, _focusedCoachIndex_accessor_storage, value);
231
+ }
232
+ get hoveredCoachIndex() {
233
+ return __privateGet(this, _hoveredCoachIndex_accessor_storage);
234
+ }
235
+ set hoveredCoachIndex(value) {
236
+ __privateSet(this, _hoveredCoachIndex_accessor_storage, value);
237
+ }
238
+ willUpdate(changedProperties) {
239
+ super.willUpdate(changedProperties);
240
+ if (changedProperties.has("seatReservations")) {
241
+ this.hasMultipleDecks = this.seatReservations?.length > 1;
242
+ this._initPrepareSeatReservationData();
243
+ this._prepareCoachWidthAndGapCalculations();
244
+ this._initSeatReservationPlaceSelection();
245
+ this.initNavigationSelectionByScrollEvent();
246
+ }
247
+ if (changedProperties.has("baseGridSize")) {
248
+ this.coachBorderOffset = this.coachBorderPadding / this.baseGridSize;
249
+ this.style?.setProperty("--sbb-seat-reservation-grid-size", `${this.baseGridSize}px`);
250
+ this.initNavigationSelectionByScrollEvent();
251
+ }
252
+ if (changedProperties.has("height") && !!this.height) {
253
+ const seatReservationLayer = this.seatReservations[this.currSelectedDeckIndex] || null;
254
+ if (seatReservationLayer?.coachItems.length) {
255
+ this.baseGridSize = this.height / seatReservationLayer.coachItems[0].dimension.h;
256
+ this.coachBorderOffset = this.coachBorderPadding / this.baseGridSize;
257
+ this.style?.setProperty("--sbb-seat-reservation-grid-size", `${this.baseGridSize}px`);
258
+ this.initNavigationSelectionByScrollEvent();
259
+ }
260
+ }
261
+ if (changedProperties.has("alignVertical") && this.alignVertical) {
262
+ this.initNavigationSelectionByScrollEvent();
263
+ }
264
+ if (changedProperties.has("preselectCoachIndex")) {
265
+ this._isRunningInitPreselectCoachIndex = true;
266
+ setTimeout(() => this.scrollToSelectedNavCoach(this.preselectCoachIndex), 1);
267
+ }
268
+ }
269
+ navigateByDirectionBtn(btnDirection) {
270
+ this.unfocusPlaceElement();
271
+ let navigateToCoachIndex = this.currSelectedCoachIndex;
272
+ if (btnDirection == "DIRECTION_LEFT" && navigateToCoachIndex > 0) {
273
+ navigateToCoachIndex = this.currSelectedCoachIndex != -1 ? this.currSelectedCoachIndex - 1 : 0;
274
+ } else if (btnDirection == "DIRECTION_RIGHT" && navigateToCoachIndex < this.seatReservations[this.currSelectedDeckIndex]?.coachItems.length - 1) {
275
+ navigateToCoachIndex = this.currSelectedCoachIndex != -1 ? this.currSelectedCoachIndex + 1 : 0;
276
+ }
277
+ this.scrollToSelectedNavCoach(navigateToCoachIndex);
278
+ }
279
+ /**
280
+ * Data can be prepared once for the entire component
281
+ * in order to avoid recurring iteration processes in rendering.
282
+ */
283
+ _initPrepareSeatReservationData() {
284
+ this._determineBaseFontSize();
285
+ if (this.hasMultipleDecks) {
286
+ this._initEmptyCoachDeckOffsets();
287
+ }
288
+ this._prepareNavigationCoachData();
289
+ }
290
+ /** Init scroll event handling for coach navigation */
291
+ initNavigationSelectionByScrollEvent() {
292
+ this.coachScrollArea = this.shadowRoot?.querySelector("#sbb-sr__wrapper-scrollarea");
293
+ this.navigationScrollArea = this.shadowRoot?.querySelector("#sbb-sr__navigation-list-coaches");
294
+ const seatReservationDeck = this.seatReservations ? this.seatReservations[this.currSelectedDeckIndex] : null;
295
+ if (seatReservationDeck && seatReservationDeck.coachItems.length > 0) {
296
+ const coachHeightWithBorderPadding = seatReservationDeck.coachItems[0].dimension.h * this.baseGridSize + this.coachBorderPadding;
297
+ const gapBetweenCoachDecks = (this.seatReservations.length - 1) * this.gapBetweenCoachDecks;
298
+ this.style?.setProperty("--sbb-seat-reservation-height", `${coachHeightWithBorderPadding * this.seatReservations.length + gapBetweenCoachDecks}`);
299
+ this.style?.setProperty("--sbb-seat-reservation-decks", `${this.seatReservations.length}`);
300
+ }
301
+ if (this.navigationScrollArea) {
302
+ this.scrollNavigationAreaDim = this.alignVertical ? this.navigationScrollArea.getBoundingClientRect().height : this.navigationScrollArea.getBoundingClientRect().width;
303
+ const navCoachesList = this.navigationScrollArea.querySelector("ul > li");
304
+ if (navCoachesList) {
305
+ const firstLiEleDimension = navCoachesList?.getBoundingClientRect();
306
+ this.coachNavButtonDim = this.alignVertical ? firstLiEleDimension.height : firstLiEleDimension.width;
307
+ }
308
+ }
309
+ if (this.coachScrollArea && seatReservationDeck) {
310
+ let currCalcTriggerPos = 0;
311
+ this.scrollCoachesAreaWidth = this.alignVertical ? this.coachScrollArea.getBoundingClientRect().height : this.coachScrollArea.getBoundingClientRect().width;
312
+ this.triggerCoachPositionsCollection = seatReservationDeck.coachItems.map((coach) => {
313
+ const startPosX = currCalcTriggerPos;
314
+ const coachWidth = this.getCalculatedDimension(coach.dimension).w;
315
+ const currentCoachOverhangingInfo = this.overHangingElementInformation.find((e) => e.coachId === coach.id);
316
+ const overhangingElementsPresent = currentCoachOverhangingInfo?.overhangingPlaces || currentCoachOverhangingInfo?.overhangingGraphicAreas;
317
+ currCalcTriggerPos += coachWidth + (!overhangingElementsPresent ? this.gapBetweenCoaches : 2 * this.gapBetweenCoaches);
318
+ return {
319
+ start: startPosX,
320
+ end: currCalcTriggerPos,
321
+ width: coachWidth
322
+ };
323
+ });
324
+ this.maxCalcCoachesWidth = currCalcTriggerPos;
325
+ }
326
+ }
327
+ /**
328
+ * Scroll event handler managed the end of scrolling inside the coach scroll area.
329
+ * Timeout event handling to check if the scrolling has been completed.
330
+ * It is required because the Safari browser does not handle scrollend event,
331
+ * and we therefore imitate this event -> scrollend.
332
+ */
333
+ coachAreaScrollend() {
334
+ if (this._scrollTimeout) {
335
+ clearTimeout(this._scrollTimeout);
336
+ }
337
+ this._scrollTimeout = setTimeout(() => this._handleCoachAreaScrollendEvent(), 150);
338
+ }
339
+ /**
340
+ * If no navigation exists (property setting -> hasNavigation) and a table coach gets the focus,
341
+ * the first place in the coach must be automatically preselected to control the place navigation via keyboard
342
+ *
343
+ * @param focusCoachIndex
344
+ */
345
+ onFocusTableCoachAndPreselectPlace(focusCoachIndex) {
346
+ if (!this.seatReservationWithoutNavigationHasFocus && !this.hasNavigation) {
347
+ this.seatReservationWithoutNavigationHasFocus = true;
348
+ this.currSelectedCoachIndex = focusCoachIndex === 0 ? this.getNextAvailableCoachIndex(-1) : this.getPrevAvailableCoachIndex(focusCoachIndex);
349
+ this.preselectPlaceInCoach();
350
+ }
351
+ }
352
+ /** Will be triggered by focus navigation direction */
353
+ onFocusNavDirectionButton() {
354
+ this.focusedCoachIndex = -1;
355
+ }
356
+ /** TAB Key Event handling for Coach Navigation */
357
+ onKeyNavigationNavCoachButton(event, currNavCoachButtonIndex) {
358
+ const pressedKey = event.key;
359
+ if (pressedKey === this.keyboardNavigationEvents.Tab) {
360
+ this._handleTabKeyNavigation(event, "navigation", currNavCoachButtonIndex);
361
+ return;
362
+ }
363
+ if (isArrowKeyOrPageKeysPressed(event)) {
364
+ this.keyboardSeatmapEventHandling(event);
365
+ }
366
+ }
367
+ /** General TAB Key Event handling for tab navigation inside the coach navigation area and the seatmap area */
368
+ _handleTabKeyNavigation(event, eventArea, currTabIndex) {
369
+ const pressedKey = event.key;
370
+ const pressedShiftTab = event.shiftKey;
371
+ if (pressedKey === this.keyboardNavigationEvents.Tab) {
372
+ if (eventArea == "navigation") {
373
+ if (currTabIndex == this.currSelectedCoachIndex) {
374
+ if (!this.currSelectedPlace || !pressedShiftTab || this.coachNavData[currTabIndex].isDriverArea || this.focusedCoachIndex == -1) {
375
+ this.focusedCoachIndex = currTabIndex;
376
+ } else if (pressedShiftTab && this.currSelectedPlace) {
377
+ this.focusedCoachIndex = -1;
378
+ this.focusPlaceElement(this.currSelectedPlace);
379
+ }
380
+ } else {
381
+ this.focusedCoachIndex = currTabIndex;
382
+ }
383
+ this._scrollToSelectedNavigationButton(currTabIndex);
384
+ } else if (eventArea == "seatmap") {
385
+ event.preventDefault();
386
+ if (pressedShiftTab) {
387
+ this._navigateCoachNavigationByKeyboard("PREV_TAB");
388
+ } else {
389
+ this._navigateCoachNavigationByKeyboard("NEXT_TAB");
390
+ }
391
+ }
392
+ }
393
+ }
394
+ /**
395
+ * Initialisation of Keyboard Seatmap event handling to navigation between each places inside a selected coach by using [arrow] keys.
396
+ * With the [TAB] key the user navigation goes to the next coach navigation element and the currently selected place is automatically reset.
397
+ */
398
+ keyboardSeatmapEventHandling(event) {
399
+ const pressedKey = event.key;
400
+ this.preventCoachScrollByPlaceClick = false;
401
+ if (!this.hasSeatReservationNativeFocus && (event.shiftKey && pressedKey === this.keyboardNavigationEvents.Tab || pressedKey === this.keyboardNavigationEvents.Tab)) {
402
+ this.hasSeatReservationNativeFocus = true;
403
+ }
404
+ if (pressedKey == this.keyboardNavigationEvents.Tab) {
405
+ this._handleTabKeyNavigation(event, "seatmap");
406
+ return;
407
+ }
408
+ if (this.currSelectedCoachIndex !== -1 && isArrowKeyOrPageKeysPressed(event)) {
409
+ event.preventDefault();
410
+ switch (pressedKey) {
411
+ case this.keyboardNavigationEvents.ArrowLeft:
412
+ {
413
+ const pressedLeftKeyMapping = this.alignVertical ? this.keyboardNavigationEvents.ArrowDown : pressedKey;
414
+ this._navigateToPlaceByKeyboard(pressedLeftKeyMapping);
415
+ }
416
+ break;
417
+ case this.keyboardNavigationEvents.ArrowRight:
418
+ {
419
+ const pressedRightKeyMapping = this.alignVertical ? this.keyboardNavigationEvents.ArrowUp : pressedKey;
420
+ this._navigateToPlaceByKeyboard(pressedRightKeyMapping);
421
+ }
422
+ break;
423
+ case this.keyboardNavigationEvents.ArrowUp:
424
+ {
425
+ const pressedUpKeyMapping = this.alignVertical ? this.keyboardNavigationEvents.ArrowLeft : pressedKey;
426
+ this._navigateToPlaceByKeyboard(pressedUpKeyMapping);
427
+ }
428
+ break;
429
+ case this.keyboardNavigationEvents.ArrowDown:
430
+ {
431
+ const pressedDownKeyMapping = this.alignVertical ? this.keyboardNavigationEvents.ArrowRight : pressedKey;
432
+ this._navigateToPlaceByKeyboard(pressedDownKeyMapping);
433
+ }
434
+ break;
435
+ }
436
+ }
437
+ }
438
+ /**
439
+ * Selects a place inside the coach if navigated via keyboard,
440
+ * otherwise the coach grid is selected (necessary for ScreenReader)
441
+ */
442
+ preselectPlaceInCoach() {
443
+ if (!this.isAutoScrolling)
444
+ return;
445
+ if (this._isRunningInitPreselectCoachIndex) {
446
+ this._isRunningInitPreselectCoachIndex = false;
447
+ return;
448
+ }
449
+ if (this.coachNavData[this.currSelectedCoachIndex] && this.coachNavData[this.currSelectedCoachIndex].isDriverArea) {
450
+ this._setFocusToSelectedCoachGrid();
451
+ return;
452
+ }
453
+ if (this.isKeyboardNavigation && this.isAutoScrolling) {
454
+ const closestPlace = this._getClosestPlaceByKeyDirection();
455
+ if (closestPlace) {
456
+ this.unfocusPlaceElement();
457
+ this.focusPlaceElement(closestPlace);
458
+ this.focusedCoachIndex = -1;
459
+ } else {
460
+ this._setFocusToSelectedCoachGrid();
461
+ }
462
+ } else {
463
+ this.unfocusPlaceElement();
464
+ this.isCoachGridFocusable = true;
465
+ this._setFocusToSelectedCoachGrid();
466
+ }
467
+ }
468
+ scrollToSelectedNavCoach(selectedNavCoachIndex) {
469
+ if (this._isValidCoachIndex(selectedNavCoachIndex) && selectedNavCoachIndex !== this.currSelectedCoachIndex) {
470
+ this.hoveredCoachIndex = selectedNavCoachIndex;
471
+ this.isAutoScrolling = true;
472
+ this.isCoachGridFocusable = true;
473
+ this.currSelectedCoachIndex = selectedNavCoachIndex;
474
+ this.currSelectedDeckIndex = this._getExistingCoachDeckIndex();
475
+ this._setScrollDirectionByCoachIndex();
476
+ const scrollToCoachPosX = this._getCoachScrollPositionX();
477
+ const isSelectedCoachIndexScrollable = this.selectedCoachIndex !== -1 || this.currSelectedCoachIndex > 0;
478
+ if (isSelectedCoachIndexScrollable && this._isScrollableToSelectedCoach()) {
479
+ this._lastStartScrollPos = this.coachScrollArea.scrollLeft;
480
+ this.coachScrollArea.scrollTo({
481
+ top: this.alignVertical ? scrollToCoachPosX : 0,
482
+ left: this.alignVertical ? 0 : scrollToCoachPosX,
483
+ behavior: "smooth"
484
+ });
485
+ } else {
486
+ this.updateCurrentSelectedCoach();
487
+ }
488
+ this._scrollToSelectedNavigationButton(selectedNavCoachIndex);
489
+ }
490
+ }
491
+ focusPlaceElement(place) {
492
+ this.unfocusPlaceElement();
493
+ if (place) {
494
+ this.currSelectedPlace = place;
495
+ this._setCurrSelectedPlaceElementId(place);
496
+ const selectedPlaceElement = this._getPlaceHtmlElement();
497
+ if (selectedPlaceElement) {
498
+ selectedPlaceElement.setAttribute("keyfocus", "focus");
499
+ const delayScrollInViewport = setTimeout(() => {
500
+ const placeId = this.getPlaceElementId(this.currSelectedDeckIndex, this.currSelectedCoachIndex, place.number);
501
+ this._scrollPlaceIntoNearestViewport(placeId);
502
+ clearTimeout(delayScrollInViewport);
503
+ }, 0);
504
+ }
505
+ }
506
+ }
507
+ unfocusPlaceElement() {
508
+ const selectedPlaceElement = this._getPlaceHtmlElement();
509
+ if (selectedPlaceElement) {
510
+ selectedPlaceElement.setAttribute("keyfocus", "unfocus");
511
+ this._setCurrSelectedPlaceElementId(null);
512
+ this.currSelectedPlace = null;
513
+ }
514
+ }
515
+ getCalculatedDimension(elementDimension, coachDimension, isOriginHeight, isStretchHeight) {
516
+ if (coachDimension && !isOriginHeight) {
517
+ elementDimension.h += this.coachBorderOffset * 2;
518
+ }
519
+ if (isStretchHeight) {
520
+ elementDimension.h += this.coachBorderOffset;
521
+ }
522
+ return {
523
+ w: this.baseGridSize * elementDimension.w,
524
+ h: this.baseGridSize * elementDimension.h
525
+ };
526
+ }
527
+ getCalculatedPosition(elementPosition, elementDimension, coachDimension, isOriginHeight) {
528
+ if (coachDimension && elementDimension) {
529
+ const endPosHeight = isOriginHeight ? coachDimension.h : coachDimension.h + this.coachBorderOffset;
530
+ if (elementPosition.y === 0) {
531
+ elementPosition.y -= this.coachBorderOffset;
532
+ } else if (elementPosition.y + elementDimension.h === endPosHeight) {
533
+ elementPosition.y += this.coachBorderOffset;
534
+ }
535
+ }
536
+ return {
537
+ x: this.baseGridSize * elementPosition.x,
538
+ y: this.baseGridSize * elementPosition.y,
539
+ z: elementPosition.z
540
+ };
541
+ }
542
+ /**
543
+ * detects if a (graphical) element is on the border with its position (upper or lower border).
544
+ * @param baseElement
545
+ * @param coachDimension
546
+ * @protected
547
+ */
548
+ isElementDirectlyOnBorder(baseElement, coachDimension) {
549
+ return baseElement.position.y === 0 || baseElement.position.y + baseElement.dimension.h === coachDimension.h;
550
+ }
551
+ /**
552
+ * Counts all available seats together depending on the seat type
553
+ *
554
+ * @param places
555
+ * @returns An Object with count of free seats and free bicycle places
556
+ */
557
+ getAvailableFreePlacesNumFromCoach(places) {
558
+ const accumulator = { seats: 0, bicycles: 0 };
559
+ const freePlaces = places?.reduce((accumulator2, currPlace) => {
560
+ if (currPlace.state !== "FREE") {
561
+ return accumulator2;
562
+ }
563
+ if (currPlace.type === "SEAT") {
564
+ accumulator2.seats++;
565
+ } else {
566
+ accumulator2.bicycles++;
567
+ }
568
+ return accumulator2;
569
+ }, accumulator);
570
+ return freePlaces ? freePlaces : accumulator;
571
+ }
572
+ /**
573
+ * At the end of a scroll Event from the coach scrollable area,
574
+ * the reached coach is marked as selected
575
+ */
576
+ _handleCoachAreaScrollendEvent() {
577
+ const findScrollCoachIndex = this.isAutoScrolling ? this.currSelectedCoachIndex : this._getCoachIndexByScrollTriggerPosition();
578
+ if (this.preventCoachScrollByPlaceClick) {
579
+ const isCoachScrolling = Math.abs(this._lastStartScrollPos - this.coachScrollArea.scrollLeft) > this.baseGridSize * 2;
580
+ if (isCoachScrolling) {
581
+ this.selectedCoachIndex = findScrollCoachIndex;
582
+ }
583
+ this.preventCoachScrollByPlaceClick = false;
584
+ return;
585
+ }
586
+ this._lastStartScrollPos = this.coachScrollArea.scrollLeft;
587
+ this.hoveredCoachIndex = -1;
588
+ if (this.currSelectedCoachIndex === -1) {
589
+ this.currSelectedCoachIndex = findScrollCoachIndex;
590
+ }
591
+ if (this._isScrollableToSelectedCoach()) {
592
+ this.currSelectedCoachIndex = findScrollCoachIndex;
593
+ } else {
594
+ this.currSelectedCoachIndex = findScrollCoachIndex < this.currSelectedCoachIndex ? this.currSelectedCoachIndex : findScrollCoachIndex;
595
+ }
596
+ if (!this.isAutoScrolling) {
597
+ this._scrollToSelectedNavigationButton(findScrollCoachIndex);
598
+ }
599
+ this.preventCoachScrollByPlaceClick = false;
600
+ this.updateCurrentSelectedCoach();
601
+ if (!this.hasNavigation) {
602
+ this.preselectPlaceInCoach();
603
+ this.isAutoScrolling = false;
604
+ }
605
+ }
606
+ /**
607
+ * Performs an automatic main navigation scroll to the specified selectedNavCoachIndex.
608
+ * Calculates the central scroll offset of the nav coach to be selected.
609
+ * @param selectedNavCoachIndex
610
+ */
611
+ _scrollToSelectedNavigationButton(selectedNavCoachIndex) {
612
+ setTimeout(() => {
613
+ if (this.hasNavigation && this.navigationScrollArea) {
614
+ const navigationAreaCenteredPosX = this.scrollNavigationAreaDim / 2;
615
+ const scrollButtonOffsetX = selectedNavCoachIndex * this.coachNavButtonDim;
616
+ const scrollOffsetX = scrollButtonOffsetX - navigationAreaCenteredPosX + this.coachNavButtonDim;
617
+ this.navigationScrollArea.scrollTo({
618
+ top: this.alignVertical ? scrollOffsetX : 0,
619
+ left: this.alignVertical ? 0 : scrollOffsetX,
620
+ behavior: "smooth"
621
+ });
622
+ }
623
+ }, 10);
624
+ }
625
+ /**
626
+ * Sets the new ScrollDirection by the new given target coach index.
627
+ */
628
+ _setScrollDirectionByCoachIndex() {
629
+ this.currScrollDirection = this.currSelectedCoachIndex > this.selectedCoachIndex ? ScrollDirection.right : ScrollDirection.left;
630
+ }
631
+ /**
632
+ * Returns the scroll start or end position X from the selected coach.
633
+ * In case the user is currently navigating through places by keyboard and goes to previous coach,
634
+ * then we return the end position of the coach to get the closest scroll position of the next focus place.
635
+ * @returns number
636
+ */
637
+ _getCoachScrollPositionX() {
638
+ const coachTriggerPoint = this.triggerCoachPositionsCollection[this.currSelectedCoachIndex];
639
+ const isFocusPlaceFromPreviousCoachPosition = this.isKeyboardNavigation && this.currScrollDirection === ScrollDirection.left && coachTriggerPoint.width > this.scrollCoachesAreaWidth;
640
+ return isFocusPlaceFromPreviousCoachPosition ? coachTriggerPoint.end - this.scrollCoachesAreaWidth : coachTriggerPoint.start;
641
+ }
642
+ /**
643
+ * Sets the focus on the HTML table (grid) caption element so that the heading is read out when using a ScreenReader.
644
+ */
645
+ _setFocusToSelectedCoachGrid() {
646
+ if (this.isCoachGridFocusable && this.hasSeatReservationNativeFocus) {
647
+ this.isCoachGridFocusable = false;
648
+ const coachTableCaptionElement = this.shadowRoot?.querySelector("#sbb-sr-coach-caption-" + this.currSelectedCoachIndex);
649
+ if (coachTableCaptionElement) {
650
+ coachTableCaptionElement.focus();
651
+ }
652
+ }
653
+ }
654
+ /**
655
+ * Returns whether the current scrolled position can be used to scroll to the selected wagon
656
+ * @returns boolean
657
+ */
658
+ _isScrollableToSelectedCoach() {
659
+ const currScrollPosX = this.alignVertical ? this.coachScrollArea.scrollTop : this.coachScrollArea.scrollLeft;
660
+ const coachScrollWindowWidth = this.alignVertical ? this.coachScrollArea.getBoundingClientRect().height : this.coachScrollArea.getBoundingClientRect().width;
661
+ const maxScrollWidthArea = this.maxCalcCoachesWidth - coachScrollWindowWidth;
662
+ const currCoachTrigger = this.triggerCoachPositionsCollection[this.currSelectedCoachIndex];
663
+ const isScrollPosSameToCurrCoachPos = currScrollPosX === this.triggerCoachPositionsCollection[this.currSelectedCoachIndex].start;
664
+ return (currScrollPosX < maxScrollWidthArea || currScrollPosX > currCoachTrigger.start) && !isScrollPosSameToCurrCoachPos;
665
+ }
666
+ /**
667
+ * Returns the coach index which is currently visible in the scroll area
668
+ * @returns number
669
+ */
670
+ _getCoachIndexByScrollTriggerPosition() {
671
+ const scrollPos = this.alignVertical ? this.coachScrollArea.scrollTop : this.coachScrollArea.scrollLeft;
672
+ const scrollOffsetX = scrollPos + this.scrollCoachesAreaWidth / 2;
673
+ return this.triggerCoachPositionsCollection.findIndex((coachTrigger) => scrollOffsetX >= coachTrigger.start && scrollOffsetX <= coachTrigger.end);
674
+ }
675
+ /**
676
+ * Get the first place of current selected coach by table cell coordinate 0-0 id.
677
+ * @returns Place or null
678
+ */
679
+ _getFirstPlaceInSelectedCoach() {
680
+ let firstPlace = null;
681
+ const coach = this.seatReservations[this.currSelectedDeckIndex].coachItems[this.currSelectedCoachIndex];
682
+ const firstCellId = "cell-" + this.currSelectedDeckIndex + "-" + this.currSelectedCoachIndex + "-0-0";
683
+ const placeNumber = this.shadowRoot?.querySelector("#" + firstCellId)?.querySelector("sbb-seat-reservation-place-control")?.getAttribute("text") || null;
684
+ if (coach && placeNumber) {
685
+ firstPlace = coach.places?.find((place) => place.number === placeNumber) || null;
686
+ }
687
+ return firstPlace;
688
+ }
689
+ _getSwitchedCoachDeckIndexByKeyNavigation(pressedKey, coach) {
690
+ if (!this.currSelectedPlace || pressedKey === this.keyboardNavigationEvents.ArrowRight || pressedKey === this.keyboardNavigationEvents.ArrowLeft)
691
+ return null;
692
+ if (pressedKey === this.keyboardNavigationEvents.ArrowDown && this.currSelectedPlace.position.y + 2 === coach.dimension.h && !!this.seatReservations[this.currSelectedDeckIndex + 1]) {
693
+ return this.currSelectedDeckIndex + 1;
694
+ } else if (pressedKey === this.keyboardNavigationEvents.ArrowUp && this.currSelectedPlace.position.y === 0 && !!this.seatReservations[this.currSelectedDeckIndex - 1]) {
695
+ return this.currSelectedDeckIndex - 1;
696
+ }
697
+ return null;
698
+ }
699
+ /**
700
+ * To get the correct closest place of current pressed key and the current selected place,
701
+ * we have to investigate the coordinates of each place to find the closest place of the currSelectedPlaceElementId.
702
+ * @param pressedKey
703
+ * @returns Place or null
704
+ */
705
+ _getClosestPlaceByKeyDirection(pressedKey) {
706
+ const coach = this.seatReservations[this.currSelectedDeckIndex].coachItems[this.currSelectedCoachIndex];
707
+ let closestPlace = null;
708
+ let coachPlaces = coach.places;
709
+ let switchedCoachDeckIndex = null;
710
+ if (coachPlaces) {
711
+ if (!this.currSelectedPlaceElementId) {
712
+ return this._getFirstPlaceInSelectedCoach();
713
+ } else {
714
+ if (this.currSelectedPlace) {
715
+ const currSelectedPlacePosition = { ...this.currSelectedPlace.position };
716
+ if (pressedKey) {
717
+ switchedCoachDeckIndex = this._getSwitchedCoachDeckIndexByKeyNavigation(pressedKey, coach);
718
+ if (switchedCoachDeckIndex !== null) {
719
+ coachPlaces = this.seatReservations[switchedCoachDeckIndex].coachItems[this.currSelectedCoachIndex].places || [];
720
+ currSelectedPlacePosition.y = switchedCoachDeckIndex < this.currSelectedDeckIndex ? coach.dimension.h : -1;
721
+ }
722
+ }
723
+ for (const place of coachPlaces) {
724
+ if (!pressedKey) {
725
+ if (this.currScrollDirection === ScrollDirection.right && place.position.y === currSelectedPlacePosition.y && (!closestPlace || place.position.x < closestPlace.position.x)) {
726
+ closestPlace = place;
727
+ } else if (this.currScrollDirection === ScrollDirection.left && place.position.y === currSelectedPlacePosition.y && (!closestPlace || place.position.x > closestPlace.position.x)) {
728
+ closestPlace = place;
729
+ }
730
+ } else {
731
+ if (place.number !== this.currSelectedPlace?.number) {
732
+ if (pressedKey === this.keyboardNavigationEvents.ArrowRight && (place.position.y === currSelectedPlacePosition.y || place.position.y === currSelectedPlacePosition.y - 1) && place.position.x > currSelectedPlacePosition.x && (!closestPlace || place.position.x < closestPlace.position.x)) {
733
+ closestPlace = place;
734
+ } else if (pressedKey === this.keyboardNavigationEvents.ArrowDown && (place.position.x === currSelectedPlacePosition.x || place.position.x === currSelectedPlacePosition.x + 1) && place.position.y > currSelectedPlacePosition.y && (!closestPlace || place.position.y < closestPlace.position.y)) {
735
+ closestPlace = place;
736
+ } else if (pressedKey === this.keyboardNavigationEvents.ArrowLeft && (place.position.y === currSelectedPlacePosition.y || place.position.y === currSelectedPlacePosition.y + 1) && place.position.x < currSelectedPlacePosition.x && (!closestPlace || place.position.x > closestPlace.position.x)) {
737
+ closestPlace = place;
738
+ } else if (pressedKey === this.keyboardNavigationEvents.ArrowUp && (place.position.x === currSelectedPlacePosition.x || place.position.x === currSelectedPlacePosition.x - 1) && place.position.y < currSelectedPlacePosition.y && (!closestPlace || place.position.y > closestPlace.position.y)) {
739
+ closestPlace = place;
740
+ }
741
+ }
742
+ }
743
+ }
744
+ if (switchedCoachDeckIndex !== null && closestPlace) {
745
+ this.currSelectedDeckIndex = switchedCoachDeckIndex;
746
+ }
747
+ }
748
+ }
749
+ }
750
+ return closestPlace;
751
+ }
752
+ // Handling for Tab navigation if a place is selected inside the coach.
753
+ // This controls the focused coach from the current selected coach.
754
+ _navigateCoachNavigationByKeyboard(tabDirection) {
755
+ const currFocusIndex = this.focusedCoachIndex === -1 ? this.currSelectedCoachIndex === -1 ? 0 : this.currSelectedCoachIndex : this.focusedCoachIndex;
756
+ const newFocusableIndex = tabDirection === "NEXT_TAB" ? this.getNextAvailableCoachIndex(currFocusIndex) : this.getPrevAvailableCoachIndex(currFocusIndex);
757
+ if (this.hasNavigation) {
758
+ const selectedPlaceElement = this._getPlaceHtmlElement();
759
+ const placeInCoachHasFocus = selectedPlaceElement ? selectedPlaceElement.getAttribute("keyfocus") === "focus" : false;
760
+ if (tabDirection === "PREV_TAB" && this.selectedCoachIndex === currFocusIndex) {
761
+ if (placeInCoachHasFocus || this.currSelectedPlace !== null) {
762
+ this.focusedCoachIndex = currFocusIndex;
763
+ this.unfocusPlaceElement();
764
+ return;
765
+ } else if (currFocusIndex == 0) {
766
+ this.unfocusPlaceElement();
767
+ this.currSelectedPlace = null;
768
+ this.focusedCoachIndex = -1;
769
+ const btnLeftDirection = this.shadowRoot?.getElementById("sbb-sr-navigation__wrapper-button-direction--left");
770
+ btnLeftDirection.focus();
771
+ } else {
772
+ this.focusedCoachIndex = newFocusableIndex;
773
+ }
774
+ } else if (newFocusableIndex !== this.currSelectedCoachIndex) {
775
+ this.focusedCoachIndex = newFocusableIndex;
776
+ } else if (tabDirection === "NEXT_TAB" && newFocusableIndex === this.coachNavData.length - 1) {
777
+ this.unfocusPlaceElement();
778
+ this.focusedCoachIndex = -1;
779
+ const btnRightDirection = this.shadowRoot?.getElementById("sbb-sr-navigation__wrapper-button-direction--right");
780
+ btnRightDirection.focus();
781
+ } else {
782
+ this.focusedCoachIndex = -1;
783
+ this.selectedCoachIndex = newFocusableIndex;
784
+ if (placeInCoachHasFocus) {
785
+ this.focusPlaceElement(this.currSelectedPlace);
786
+ } else {
787
+ this.isCoachGridFocusable = true;
788
+ this._setFocusToSelectedCoachGrid();
789
+ }
790
+ }
791
+ this._scrollToSelectedNavigationButton(newFocusableIndex);
792
+ } else {
793
+ this.scrollToSelectedNavCoach(newFocusableIndex);
794
+ }
795
+ }
796
+ _navigateToPlaceByKeyboard(pressedKey) {
797
+ this.isKeyboardNavigation = true;
798
+ if (this.focusedCoachIndex !== -1) {
799
+ this.focusedCoachIndex = -1;
800
+ }
801
+ if (!this.preventPlaceClick) {
802
+ const findClosestPlace = this._getClosestPlaceByKeyDirection(pressedKey);
803
+ if (findClosestPlace) {
804
+ this.focusPlaceElement(findClosestPlace);
805
+ } else {
806
+ if (pressedKey === this.keyboardNavigationEvents.ArrowRight || pressedKey === this.keyboardNavigationEvents.ArrowLeft || this.alignVertical && (pressedKey === this.keyboardNavigationEvents.ArrowUp || pressedKey === this.keyboardNavigationEvents.ArrowDown)) {
807
+ const newSelectedCoachIndex = pressedKey === this.keyboardNavigationEvents.ArrowRight ? this.getNextAvailableCoachIndex() : this.getPrevAvailableCoachIndex();
808
+ this.scrollToSelectedNavCoach(newSelectedCoachIndex);
809
+ }
810
+ }
811
+ }
812
+ }
813
+ getNextAvailableCoachIndex(currentIndex) {
814
+ const startIndex = currentIndex ?? this.currSelectedCoachIndex;
815
+ return startIndex < this.seatReservations[this.currSelectedDeckIndex].coachItems.length - 1 ? startIndex + 1 : startIndex;
816
+ }
817
+ getPrevAvailableCoachIndex(currentIndex) {
818
+ const startIndex = currentIndex ?? this.currSelectedCoachIndex;
819
+ return startIndex > 0 ? startIndex - 1 : startIndex;
820
+ }
821
+ updateSelectedSeatReservationPlaces(placeSelection) {
822
+ const placeTypeProp = placeSelection.placeType === "SEAT" ? "seats" : "bicycles";
823
+ const maxReservations = placeSelection.placeType === "SEAT" ? this.maxSeatReservations : this.maxBicycleReservations;
824
+ const currSelectedPlaces = this.selectedSeatReservationPlaces[placeTypeProp];
825
+ this.selectedSeatReservationPlaces[placeTypeProp] = this._updateSelectedSeatReservationPlaces(currSelectedPlaces, maxReservations, placeSelection);
826
+ this.dispatchEvent(new CustomEvent("selectedplaces", {
827
+ bubbles: true,
828
+ composed: true,
829
+ detail: this.selectedSeatReservationPlaces
830
+ }));
831
+ }
832
+ _updateSelectedSeatReservationPlaces(selectedSeatReservationPlaces, maxReservations, placeSelection) {
833
+ if (placeSelection.state === "SELECTED") {
834
+ const selectedPlaceDeckIndex = this._getDeckIndexByPlaceId(placeSelection.id);
835
+ const seatReservationSelection = this._getSeatReservationPlaceSelection(placeSelection, selectedPlaceDeckIndex);
836
+ if (seatReservationSelection) {
837
+ selectedSeatReservationPlaces.push(seatReservationSelection);
838
+ }
839
+ } else {
840
+ selectedSeatReservationPlaces = selectedSeatReservationPlaces.filter((_selectedPlace) => _selectedPlace.id !== placeSelection.id);
841
+ }
842
+ if (maxReservations > -1 && selectedSeatReservationPlaces.length > maxReservations) {
843
+ const resetWithPlaceSelection = maxReservations > 0 ? placeSelection : void 0;
844
+ selectedSeatReservationPlaces = this._resetAllPlaceSelections(selectedSeatReservationPlaces, resetWithPlaceSelection);
845
+ }
846
+ return selectedSeatReservationPlaces;
847
+ }
848
+ updateCurrentSelectedPlaceInCoach(placeSelection) {
849
+ const placeDeckIndex = this._getDeckIndexByPlaceId(placeSelection.id);
850
+ const coachIndex = placeSelection.coachIndex;
851
+ if (placeDeckIndex === null)
852
+ return;
853
+ const place = this.seatReservations[placeDeckIndex].coachItems[coachIndex].places?.find((place2) => place2.number == placeSelection.number);
854
+ if (!place)
855
+ return;
856
+ this.currSelectedDeckIndex = placeDeckIndex;
857
+ this.currSelectedCoachIndex = coachIndex;
858
+ this.currSelectedPlace = place;
859
+ if (this.currSelectedCoachIndex !== this.selectedCoachIndex) {
860
+ this.updateCurrentSelectedCoach();
861
+ }
862
+ this._setCurrSelectedPlaceElementId(place);
863
+ const delayScrollInViewport = setTimeout(() => {
864
+ this._scrollPlaceIntoNearestViewport(placeSelection.id);
865
+ clearTimeout(delayScrollInViewport);
866
+ }, 0);
867
+ }
868
+ updateCurrentSelectedCoach() {
869
+ if (this.currSelectedCoachIndex == this.selectedCoachIndex)
870
+ return;
871
+ if (this.focusedCoachIndex != -1) {
872
+ this.focusedCoachIndex = this.currSelectedCoachIndex;
873
+ }
874
+ this.selectedCoachIndex = this.currSelectedCoachIndex;
875
+ const coachSelection = this._getSeatReservationSelectedCoach(this.selectedCoachIndex);
876
+ if (coachSelection) {
877
+ this.dispatchEvent(new CustomEvent("selectedcoach", {
878
+ bubbles: true,
879
+ composed: true,
880
+ detail: coachSelection
881
+ }));
882
+ }
883
+ }
884
+ getPlaceElementId(coachDeckIndex, coachIndex, placeNumber) {
885
+ return "seat-reservation__place-button-" + coachDeckIndex + "-" + coachIndex + "-" + placeNumber;
886
+ }
887
+ /**
888
+ * In the case of coach layouts with different decks,
889
+ * it is necessary to extend the offset with empty coaches
890
+ * in order to create a stable vehicle layout.
891
+ *
892
+ * [ooo]-[ooo]-[ooo]
893
+ * [ooo]-[ooo]-[ooo]-[ooo]-[ooo]
894
+ */
895
+ _initEmptyCoachDeckOffsets() {
896
+ const coachOffsetIndexCounter = Array(this.seatReservations.length - 1).fill(0);
897
+ const lowerDeck = this.seatReservations[this.seatReservations.length - 1];
898
+ lowerDeck.coachItems.forEach((lowerCoachItem) => {
899
+ for (let i = 0; i < this.seatReservations.length - 1; i++) {
900
+ const deckCoachItem = this.seatReservations[i].coachItems[coachOffsetIndexCounter[i]];
901
+ if (lowerCoachItem.id != deckCoachItem?.id) {
902
+ const emptyOffsetCoach = {
903
+ ...lowerCoachItem,
904
+ places: void 0,
905
+ propertyIds: void 0,
906
+ graphicElements: void 0,
907
+ serviceElements: void 0,
908
+ travelClass: []
909
+ };
910
+ this.seatReservations[i].coachItems.splice(coachOffsetIndexCounter[i], 0, emptyOffsetCoach);
911
+ }
912
+ coachOffsetIndexCounter[i]++;
913
+ }
914
+ });
915
+ }
916
+ /**
917
+ * Initialization of SeatReservationPlaceSelection Array based on the transferred places
918
+ * that have the state SELECTED within the seatReservation object
919
+ */
920
+ _initSeatReservationPlaceSelection() {
921
+ this.selectedSeatReservationPlaces.seats = [];
922
+ this.selectedSeatReservationPlaces.bicycles = [];
923
+ this.seatReservations?.forEach((seatReservation, coachDeckIndex) => seatReservation.coachItems.map((coach, coachIndex) => {
924
+ coach.places?.filter((place) => place.state === "SELECTED")?.forEach((place) => {
925
+ const placeId = this.getPlaceElementId(coachDeckIndex, coachIndex, place.number);
926
+ const preselectedPlaceSelection = mapPlaceInfosToPlaceSelection(place, placeId, seatReservation.deckCoachIndex, coachIndex);
927
+ const seatReservationPlaceSelection = this._getSeatReservationPlaceSelection(preselectedPlaceSelection, coachDeckIndex);
928
+ if (seatReservationPlaceSelection) {
929
+ if (seatReservationPlaceSelection.placeType === "SEAT") {
930
+ this.selectedSeatReservationPlaces.seats.push(seatReservationPlaceSelection);
931
+ } else {
932
+ this.selectedSeatReservationPlaces.bicycles.push(seatReservationPlaceSelection);
933
+ }
934
+ }
935
+ });
936
+ }));
937
+ }
938
+ /**
939
+ * All selected places will be reset or the currentSelectedPlace was given, then we reset all except currentSelectedPlace
940
+ * @param reservationPlaceSelections
941
+ * @param currSelectedPlace
942
+ */
943
+ _resetAllPlaceSelections(reservationPlaceSelections, currSelectedPlace) {
944
+ for (const placeSelection of reservationPlaceSelections) {
945
+ if (!currSelectedPlace || currSelectedPlace.id !== placeSelection.id) {
946
+ const placeElement = this.shadowRoot?.getElementById(placeSelection.id);
947
+ if (placeElement) {
948
+ placeElement.setAttribute("state", "FREE");
949
+ }
950
+ }
951
+ }
952
+ if (currSelectedPlace) {
953
+ reservationPlaceSelections = reservationPlaceSelections.filter((_selectedPlace) => _selectedPlace.id === currSelectedPlace.id);
954
+ } else {
955
+ reservationPlaceSelections = [];
956
+ }
957
+ return reservationPlaceSelections;
958
+ }
959
+ _getSeatReservationPlaceSelection(currSelectedPlace, coachDeckIndex) {
960
+ if (coachDeckIndex === null)
961
+ return null;
962
+ const coach = this.seatReservations[coachDeckIndex].coachItems[currSelectedPlace.coachIndex];
963
+ const place = coach.places?.find((place2) => place2.number === currSelectedPlace.number);
964
+ return place ? mapPlaceAndCoachToSeatReservationPlaceSelection(place, coach, currSelectedPlace.id, currSelectedPlace.deckIndex, currSelectedPlace.coachIndex) : null;
965
+ }
966
+ _getSeatReservationSelectedCoach(coachIndex) {
967
+ if (!this.seatReservations[this.currSelectedDeckIndex].coachItems[coachIndex])
968
+ return null;
969
+ const coach = this.seatReservations[this.currSelectedDeckIndex].coachItems[coachIndex];
970
+ const coachNumberOfFreePlaces = this.getAvailableFreePlacesNumFromCoach(coach.places);
971
+ return mapCoachInfosToCoachSelection(coachIndex, coach, coachNumberOfFreePlaces);
972
+ }
973
+ _setCurrSelectedPlaceElementId(place) {
974
+ this.currSelectedPlaceElementId = place ? this.getPlaceElementId(this.currSelectedDeckIndex, this.currSelectedCoachIndex, place.number) : null;
975
+ }
976
+ /**
977
+ * Preparation of the used documents font-size which needs
978
+ * to be determined in order to correctly calculate CSS values with rem
979
+ * */
980
+ _determineBaseFontSize() {
981
+ if (!isServer) {
982
+ const baseFontSize = parseInt(window.getComputedStyle(document.body).fontSize, 10);
983
+ const onePixelInRem = 1 / baseFontSize;
984
+ this.style?.setProperty("--sbb-seat-reservation-one-px-rem", `${onePixelInRem + "rem"}`);
985
+ }
986
+ }
987
+ /**
988
+ * Prepares data for displaying navigation area.
989
+ * Calculates the values which are not going to change during use of a component:
990
+ * - coach id
991
+ * - list of service icons
992
+ * - class (first, second, any)
993
+ * - whether there is a driver area left or right
994
+ * */
995
+ _prepareNavigationCoachData() {
996
+ if (this.seatReservations) {
997
+ const lowerDeck = this.seatReservations[this.seatReservations.length - 1].coachItems;
998
+ this.coachNavData = [];
999
+ lowerDeck.forEach((coach, index) => {
1000
+ const travelClasses = [];
1001
+ const propertyIds = [];
1002
+ const places = [];
1003
+ this.seatReservations.map((sr) => {
1004
+ return sr.coachItems[index];
1005
+ }).forEach((coach2) => {
1006
+ travelClasses.push(...coach2.travelClass);
1007
+ propertyIds.push(...coach2.propertyIds ? coach2.propertyIds : []);
1008
+ places.push(...coach2.places ? coach2.places : []);
1009
+ });
1010
+ this.coachNavData.push({
1011
+ id: coach.id,
1012
+ travelClass: this._prepareTravelClassNavigation(travelClasses),
1013
+ propertyIds: this._prepareServiceIconsNavigation(propertyIds),
1014
+ isDriverArea: coach.places ? coach.places.length === 0 : true,
1015
+ driverAreaSide: this._prepareDriverAreaSideNavigation(coach),
1016
+ freePlaces: this.getAvailableFreePlacesNumFromCoach(places)
1017
+ });
1018
+ });
1019
+ }
1020
+ }
1021
+ _prepareTravelClassNavigation(travelClasses) {
1022
+ if (travelClasses.indexOf("FIRST") !== -1)
1023
+ return "FIRST";
1024
+ if (travelClasses.indexOf("SECOND") !== -1)
1025
+ return "SECOND";
1026
+ return "ANY_CLASS";
1027
+ }
1028
+ _prepareDriverAreaSideNavigation(coachItem) {
1029
+ const coachDriverAreas = coachItem.graphicElements?.filter((graphicalElements) => graphicalElements.icon === "DRIVER_AREA");
1030
+ if (coachDriverAreas && coachDriverAreas.length > 0) {
1031
+ const hasLeftDriverArea = coachDriverAreas.find((driverAreaElement) => driverAreaElement.position.x === 0) || false;
1032
+ const hasRightDriverArea = coachDriverAreas.find((driverAreaElement) => driverAreaElement.position.x > 0) || false;
1033
+ return {
1034
+ left: !!hasLeftDriverArea,
1035
+ right: !!hasRightDriverArea
1036
+ };
1037
+ }
1038
+ return void 0;
1039
+ }
1040
+ _prepareCoachWidthAndGapCalculations() {
1041
+ if (this.seatReservations) {
1042
+ const coachItems = this.seatReservations[this.seatReservations.length - 1]?.coachItems;
1043
+ coachItems?.forEach((coachItem) => {
1044
+ const hasOverhangingPlaces = this._isOverhangingElementsPresent(coachItem.dimension.w, coachItem.places);
1045
+ const filteredElements = coachItem.graphicElements?.filter((e) => e.icon && !this.notAreaElements.includes(e.icon));
1046
+ const hasOverhangingGraphicAreas = this._isOverhangingElementsPresent(coachItem.dimension.w, filteredElements);
1047
+ this.overHangingElementInformation.push({
1048
+ coachId: coachItem.id,
1049
+ overhangingPlaces: hasOverhangingPlaces,
1050
+ overhangingGraphicAreas: hasOverhangingGraphicAreas
1051
+ });
1052
+ });
1053
+ }
1054
+ }
1055
+ /**
1056
+ * Returns the current selected place HTML element by currSelectedPlaceElementId.
1057
+ * @returns HTMLElement or null
1058
+ */
1059
+ _getPlaceHtmlElement() {
1060
+ return this.currSelectedPlaceElementId ? this.shadowRoot?.getElementById(this.currSelectedPlaceElementId) || null : null;
1061
+ }
1062
+ /**
1063
+ * Returns the extracted coach deck index from place id
1064
+ * @returns number
1065
+ */
1066
+ _getDeckIndexByPlaceId(placeId) {
1067
+ const deckIndex = this.shadowRoot?.querySelector("#" + placeId)?.getAttribute("data-deck-index");
1068
+ if (deckIndex && !isNaN(+deckIndex)) {
1069
+ return +deckIndex;
1070
+ }
1071
+ return null;
1072
+ }
1073
+ _isValidCoachIndex(coachIndex) {
1074
+ return coachIndex >= 0 && coachIndex <= this.seatReservations[this.seatReservations.length - 1].coachItems.length;
1075
+ }
1076
+ /**
1077
+ * Returns existing coach deck index depending on the selected coach.
1078
+ * This method is necessary to get an available coach deck index during keyboard navigation, which can vary between coaches with different decks.
1079
+ * For example, when navigating from a coach with two decks to a coach with one deck.
1080
+ *
1081
+ * [ooo]-[ooo]-[ooo]
1082
+ * [ooo]-[ooo]-[ooo]-[ooo]-[ooo]
1083
+ *
1084
+ * @returns number
1085
+ */
1086
+ _getExistingCoachDeckIndex() {
1087
+ if (this.seatReservations[this.currSelectedDeckIndex].coachItems[this.currSelectedCoachIndex].places !== void 0) {
1088
+ return this.currSelectedDeckIndex;
1089
+ }
1090
+ const nextAvailableDeckCoachIndex = this.seatReservations.findIndex((seatReservation) => seatReservation.coachItems[this.currSelectedCoachIndex].places !== void 0);
1091
+ return this.currSelectedDeckIndex >= nextAvailableDeckCoachIndex ? this.currSelectedDeckIndex : nextAvailableDeckCoachIndex;
1092
+ }
1093
+ /**
1094
+ * If a selected place is slightly hidden by the overflow scroll content and is still clicked,
1095
+ * the method tries to scroll the selected place into the nearest viewport, so that it is completely visible.
1096
+ *
1097
+ * @param placeId
1098
+ */
1099
+ _scrollPlaceIntoNearestViewport(placeId) {
1100
+ this.shadowRoot?.getElementById(placeId)?.scrollIntoView({ behavior: "smooth", block: "nearest", inline: "nearest" });
1101
+ }
1102
+ /**
1103
+ * checks if any places or graphical elements (e.g. toilet area, etc.) are overhanging the coach borders
1104
+ * @param coachItemWidth
1105
+ * @param elements
1106
+ */
1107
+ _isOverhangingElementsPresent(coachItemWidth, elements) {
1108
+ return elements?.some((element) => element.position.x === 0 || element.position.x + element.dimension.w >= coachItemWidth) ?? false;
1109
+ }
1110
+ }, _seatReservations_accessor_storage = new WeakMap(), _hasNavigation_accessor_storage = new WeakMap(), _alignVertical_accessor_storage = new WeakMap(), _baseGridSize_accessor_storage = new WeakMap(), _height_accessor_storage = new WeakMap(), _maxSeatReservations_accessor_storage = new WeakMap(), _maxBicycleReservations_accessor_storage = new WeakMap(), _preventPlaceClick_accessor_storage = new WeakMap(), _preselectCoachIndex_accessor_storage = new WeakMap(), _selectedCoachIndex_accessor_storage = new WeakMap(), _focusedCoachIndex_accessor_storage = new WeakMap(), _hoveredCoachIndex_accessor_storage = new WeakMap(), (() => {
1111
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
1112
+ _seatReservations_decorators = [property({ attribute: "seat-reservations", type: Array })];
1113
+ _hasNavigation_decorators = [forceType(), property({ attribute: "has-navigation", type: Boolean })];
1114
+ _alignVertical_decorators = [forceType(), property({ attribute: "align-vertical", type: Boolean, reflect: true, useDefault: true })];
1115
+ _baseGridSize_decorators = [forceType(), property({ attribute: "base-grid-size", type: Number })];
1116
+ _height_decorators = [forceType(), property({ attribute: "height", type: Number })];
1117
+ _maxSeatReservations_decorators = [forceType(), property({ attribute: "max-seat-reservations", type: Number })];
1118
+ _maxBicycleReservations_decorators = [forceType(), property({ attribute: "max-bicycle-reservations", type: Number })];
1119
+ _preventPlaceClick_decorators = [forceType(), property({ attribute: "prevent-place-click", type: Boolean })];
1120
+ _preselectCoachIndex_decorators = [forceType(), property({ attribute: "preselect-coach-index", type: Number })];
1121
+ _selectedCoachIndex_decorators = [state()];
1122
+ _focusedCoachIndex_decorators = [state()];
1123
+ _hoveredCoachIndex_decorators = [state()];
1124
+ _coachAreaScrollend_decorators = [eventOptions({ passive: true })];
1125
+ __esDecorate(_a, null, _seatReservations_decorators, { kind: "accessor", name: "seatReservations", static: false, private: false, access: { has: (obj) => "seatReservations" in obj, get: (obj) => obj.seatReservations, set: (obj, value) => {
1126
+ obj.seatReservations = value;
1127
+ } }, metadata: _metadata }, _seatReservations_initializers, _seatReservations_extraInitializers);
1128
+ __esDecorate(_a, null, _hasNavigation_decorators, { kind: "accessor", name: "hasNavigation", static: false, private: false, access: { has: (obj) => "hasNavigation" in obj, get: (obj) => obj.hasNavigation, set: (obj, value) => {
1129
+ obj.hasNavigation = value;
1130
+ } }, metadata: _metadata }, _hasNavigation_initializers, _hasNavigation_extraInitializers);
1131
+ __esDecorate(_a, null, _alignVertical_decorators, { kind: "accessor", name: "alignVertical", static: false, private: false, access: { has: (obj) => "alignVertical" in obj, get: (obj) => obj.alignVertical, set: (obj, value) => {
1132
+ obj.alignVertical = value;
1133
+ } }, metadata: _metadata }, _alignVertical_initializers, _alignVertical_extraInitializers);
1134
+ __esDecorate(_a, null, _baseGridSize_decorators, { kind: "accessor", name: "baseGridSize", static: false, private: false, access: { has: (obj) => "baseGridSize" in obj, get: (obj) => obj.baseGridSize, set: (obj, value) => {
1135
+ obj.baseGridSize = value;
1136
+ } }, metadata: _metadata }, _baseGridSize_initializers, _baseGridSize_extraInitializers);
1137
+ __esDecorate(_a, null, _height_decorators, { kind: "accessor", name: "height", static: false, private: false, access: { has: (obj) => "height" in obj, get: (obj) => obj.height, set: (obj, value) => {
1138
+ obj.height = value;
1139
+ } }, metadata: _metadata }, _height_initializers, _height_extraInitializers);
1140
+ __esDecorate(_a, null, _maxSeatReservations_decorators, { kind: "accessor", name: "maxSeatReservations", static: false, private: false, access: { has: (obj) => "maxSeatReservations" in obj, get: (obj) => obj.maxSeatReservations, set: (obj, value) => {
1141
+ obj.maxSeatReservations = value;
1142
+ } }, metadata: _metadata }, _maxSeatReservations_initializers, _maxSeatReservations_extraInitializers);
1143
+ __esDecorate(_a, null, _maxBicycleReservations_decorators, { kind: "accessor", name: "maxBicycleReservations", static: false, private: false, access: { has: (obj) => "maxBicycleReservations" in obj, get: (obj) => obj.maxBicycleReservations, set: (obj, value) => {
1144
+ obj.maxBicycleReservations = value;
1145
+ } }, metadata: _metadata }, _maxBicycleReservations_initializers, _maxBicycleReservations_extraInitializers);
1146
+ __esDecorate(_a, null, _preventPlaceClick_decorators, { kind: "accessor", name: "preventPlaceClick", static: false, private: false, access: { has: (obj) => "preventPlaceClick" in obj, get: (obj) => obj.preventPlaceClick, set: (obj, value) => {
1147
+ obj.preventPlaceClick = value;
1148
+ } }, metadata: _metadata }, _preventPlaceClick_initializers, _preventPlaceClick_extraInitializers);
1149
+ __esDecorate(_a, null, _preselectCoachIndex_decorators, { kind: "accessor", name: "preselectCoachIndex", static: false, private: false, access: { has: (obj) => "preselectCoachIndex" in obj, get: (obj) => obj.preselectCoachIndex, set: (obj, value) => {
1150
+ obj.preselectCoachIndex = value;
1151
+ } }, metadata: _metadata }, _preselectCoachIndex_initializers, _preselectCoachIndex_extraInitializers);
1152
+ __esDecorate(_a, null, _selectedCoachIndex_decorators, { kind: "accessor", name: "selectedCoachIndex", static: false, private: false, access: { has: (obj) => "selectedCoachIndex" in obj, get: (obj) => obj.selectedCoachIndex, set: (obj, value) => {
1153
+ obj.selectedCoachIndex = value;
1154
+ } }, metadata: _metadata }, _selectedCoachIndex_initializers, _selectedCoachIndex_extraInitializers);
1155
+ __esDecorate(_a, null, _focusedCoachIndex_decorators, { kind: "accessor", name: "focusedCoachIndex", static: false, private: false, access: { has: (obj) => "focusedCoachIndex" in obj, get: (obj) => obj.focusedCoachIndex, set: (obj, value) => {
1156
+ obj.focusedCoachIndex = value;
1157
+ } }, metadata: _metadata }, _focusedCoachIndex_initializers, _focusedCoachIndex_extraInitializers);
1158
+ __esDecorate(_a, null, _hoveredCoachIndex_decorators, { kind: "accessor", name: "hoveredCoachIndex", static: false, private: false, access: { has: (obj) => "hoveredCoachIndex" in obj, get: (obj) => obj.hoveredCoachIndex, set: (obj, value) => {
1159
+ obj.hoveredCoachIndex = value;
1160
+ } }, metadata: _metadata }, _hoveredCoachIndex_initializers, _hoveredCoachIndex_extraInitializers);
1161
+ __esDecorate(_a, null, _coachAreaScrollend_decorators, { kind: "method", name: "coachAreaScrollend", static: false, private: false, access: { has: (obj) => "coachAreaScrollend" in obj, get: (obj) => obj.coachAreaScrollend }, metadata: _metadata }, null, _instanceExtraInitializers);
1162
+ if (_metadata) Object.defineProperty(_a, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
1163
+ })(), _a.events = {
1164
+ selectedplaces: "selectedplaces",
1165
+ selectedcoach: "selectedcoach"
1166
+ }, _a;
1167
+ })();
1168
+ export {
1169
+ SeatReservationBaseElement
1170
+ };
1171
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhdC1yZXNlcnZhdGlvbi1iYXNlLWVsZW1lbnQuanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lbGVtZW50cy1leHBlcmltZW50YWwvc2VhdC1yZXNlcnZhdGlvbi9zZWF0LXJlc2VydmF0aW9uL3NlYXQtcmVzZXJ2YXRpb24tYmFzZS1lbGVtZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IGlzQXJyb3dLZXlPclBhZ2VLZXlzUHJlc3NlZCB9IGZyb20gJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL2NvcmUvYTExeS5qcyc7XG5pbXBvcnQgeyBmb3JjZVR5cGUgfSBmcm9tICdAc2JiLWVzdGEvbHluZS1lbGVtZW50cy9jb3JlL2RlY29yYXRvcnMuanMnO1xuaW1wb3J0IHsgaXNTZXJ2ZXIsIExpdEVsZW1lbnQsIHR5cGUgUHJvcGVydHlWYWx1ZXMgfSBmcm9tICdsaXQnO1xuaW1wb3J0IHsgZXZlbnRPcHRpb25zLCBwcm9wZXJ0eSwgc3RhdGUgfSBmcm9tICdsaXQvZGVjb3JhdG9ycy5qcyc7XG5cbmltcG9ydCB7XG4gIG1hcENvYWNoSW5mb3NUb0NvYWNoU2VsZWN0aW9uLFxuICBtYXBJY29uVG9TdmcsXG4gIG1hcFBsYWNlQW5kQ29hY2hUb1NlYXRSZXNlcnZhdGlvblBsYWNlU2VsZWN0aW9uLFxuICBtYXBQbGFjZUluZm9zVG9QbGFjZVNlbGVjdGlvbixcbn0gZnJvbSAnLi4vY29tbW9uL21hcHBlci50cyc7XG5pbXBvcnQgdHlwZSB7XG4gIEJhc2VFbGVtZW50LFxuICBDb2FjaEl0ZW0sXG4gIENvYWNoTnVtYmVyT2ZGcmVlUGxhY2VzLFxuICBFbGVtZW50RGltZW5zaW9uLFxuICBFbGVtZW50UG9zaXRpb24sXG4gIE5hdmlnYXRpb25Db2FjaEl0ZW0sXG4gIFBsYWNlLFxuICBQbGFjZVNlbGVjdGlvbixcbiAgUGxhY2VUcmF2ZWxDbGFzcyxcbiAgU2VhdFJlc2VydmF0aW9uLFxuICBTZWF0UmVzZXJ2YXRpb25QbGFjZVNlbGVjdGlvbixcbiAgU2VhdFJlc2VydmF0aW9uU2VsZWN0ZWRDb2FjaCxcbiAgU2VhdFJlc2VydmF0aW9uU2VsZWN0ZWRQbGFjZXMsXG59IGZyb20gJy4uL2NvbW1vbi50cyc7XG5pbXBvcnQgdHlwZSB7IFNiYlNlYXRSZXNlcnZhdGlvblBsYWNlQ29udHJvbEVsZW1lbnQgfSBmcm9tICcuLi9zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2wvc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sLmNvbXBvbmVudC50cyc7XG5cbmVudW0gU2Nyb2xsRGlyZWN0aW9uIHtcbiAgcmlnaHQgPSAncmlnaHQnLFxuICBsZWZ0ID0gJ2xlZnQnLFxufVxuXG5pbnRlcmZhY2UgQ29hY2hTY3JvbGxUcmlnZ2VyUG9pbnQge1xuICBzdGFydDogbnVtYmVyO1xuICBlbmQ6IG51bWJlcjtcbiAgd2lkdGg6IG51bWJlcjtcbn1cblxuY29uc3QgTUFYX1NFUlZJQ0VfUFJPUEVSVElFUyA9IDM7XG5jb25zdCBBTExPV0VEX1NFUlZJQ0VfSUNPTlM6IHN0cmluZ1tdID0gW1xuICAnc2Etdm8nLFxuICAnc2EtcnMnLFxuICAnc2EtYWJ0ZWlsa2luZGVyd2FnZW4nLFxuICAnc2Etd3InLFxuICAnc2EtZmEnLFxuICAnc2EtYnonLFxuICAnc2EtcnonLFxuXTtcblxuZXhwb3J0IGNsYXNzIFNlYXRSZXNlcnZhdGlvbkJhc2VFbGVtZW50IGV4dGVuZHMgTGl0RWxlbWVudCB7XG4gIHB1YmxpYyBzdGF0aWMgcmVhZG9ubHkgZXZlbnRzID0ge1xuICAgIHNlbGVjdGVkcGxhY2VzOiAnc2VsZWN0ZWRwbGFjZXMnLFxuICAgIHNlbGVjdGVkY29hY2g6ICdzZWxlY3RlZGNvYWNoJyxcbiAgfSBhcyBjb25zdDtcblxuICAvKiogVGhlIHNlYXQgcmVzZXJ2YXRpb25zIGFycmF5IGNvbnRhaW5zIGFsbCBjb2FjaGVzIGFuZCBwbGFjZXMgKi9cbiAgQHByb3BlcnR5KHsgYXR0cmlidXRlOiAnc2VhdC1yZXNlcnZhdGlvbnMnLCB0eXBlOiBBcnJheSB9KVxuICBwdWJsaWMgYWNjZXNzb3Igc2VhdFJlc2VydmF0aW9uczogU2VhdFJlc2VydmF0aW9uW10gPSBudWxsITtcblxuICAvKiogVGhlIHNlYXQgcmVzZXJ2YXRpb24gbmF2aWdhdGlvbiBjYW4gYmUgdG9nZ2xlZCBieSB0aGlzIHByb3BlcnR5ICovXG4gIEBmb3JjZVR5cGUoKVxuICBAcHJvcGVydHkoeyBhdHRyaWJ1dGU6ICdoYXMtbmF2aWdhdGlvbicsIHR5cGU6IEJvb2xlYW4gfSlcbiAgcHVibGljIGFjY2Vzc29yIGhhc05hdmlnYXRpb246IGJvb2xlYW4gPSB0cnVlO1xuXG4gIC8qKiBUaGUgc2VhdCByZXNlcnZhdGlvbiBhcmVhIGlzIGFsaWduZWQgdmVydGljYWxseSAqL1xuICBAZm9yY2VUeXBlKClcbiAgQHByb3BlcnR5KHsgYXR0cmlidXRlOiAnYWxpZ24tdmVydGljYWwnLCB0eXBlOiBCb29sZWFuLCByZWZsZWN0OiB0cnVlLCB1c2VEZWZhdWx0OiB0cnVlIH0pXG4gIHB1YmxpYyBhY2Nlc3NvciBhbGlnblZlcnRpY2FsOiBib29sZWFuID0gZmFsc2U7XG5cbiAgLyoqIFRoZSBzZWF0IHJlc2VydmF0aW9uIGFyZWEncyBiYXNlIGdyaWQgc2l6ZSAqL1xuICBAZm9yY2VUeXBlKClcbiAgQHByb3BlcnR5KHsgYXR0cmlidXRlOiAnYmFzZS1ncmlkLXNpemUnLCB0eXBlOiBOdW1iZXIgfSlcbiAgcHVibGljIGFjY2Vzc29yIGJhc2VHcmlkU2l6ZTogbnVtYmVyID0gMTY7XG5cbiAgLyoqIFRoZSBzZWF0IHJlc2VydmF0aW9uIGFyZWEncyB3aWR0aCAqL1xuICBAZm9yY2VUeXBlKClcbiAgQHByb3BlcnR5KHsgYXR0cmlidXRlOiAnaGVpZ2h0JywgdHlwZTogTnVtYmVyIH0pXG4gIHB1YmxpYyBhY2Nlc3NvciBoZWlnaHQ6IG51bWJlciA9IG51bGwhO1xuXG4gIC8qKiBNYXhpbWFsIG51bWJlciBvZiBwb3NzaWJsZSBjbGlja2FibGUgc2VhdHMgKi9cbiAgQGZvcmNlVHlwZSgpXG4gIEBwcm9wZXJ0eSh7IGF0dHJpYnV0ZTogJ21heC1zZWF0LXJlc2VydmF0aW9ucycsIHR5cGU6IE51bWJlciB9KVxuICBwdWJsaWMgYWNjZXNzb3IgbWF4U2VhdFJlc2VydmF0aW9uczogbnVtYmVyID0gLTE7XG5cbiAgLyoqIE1heGltYWwgbnVtYmVyIG9mIHBvc3NpYmxlIGNsaWNrYWJsZSBiaWN5Y2xlIHBsYWNlcyAqL1xuICBAZm9yY2VUeXBlKClcbiAgQHByb3BlcnR5KHsgYXR0cmlidXRlOiAnbWF4LWJpY3ljbGUtcmVzZXJ2YXRpb25zJywgdHlwZTogTnVtYmVyIH0pXG4gIHB1YmxpYyBhY2Nlc3NvciBtYXhCaWN5Y2xlUmVzZXJ2YXRpb25zOiBudW1iZXIgPSAtMTtcblxuICAvKiogQW55IGNsaWNrIGZ1bmN0aW9uYWxpdHkgaXMgcHJldmVudGVkICovXG4gIEBmb3JjZVR5cGUoKVxuICBAcHJvcGVydHkoeyBhdHRyaWJ1dGU6ICdwcmV2ZW50LXBsYWNlLWNsaWNrJywgdHlwZTogQm9vbGVhbiB9KVxuICBwdWJsaWMgYWNjZXNzb3IgcHJldmVudFBsYWNlQ2xpY2s6IGJvb2xlYW4gPSBmYWxzZTtcblxuICBAZm9yY2VUeXBlKClcbiAgQHByb3BlcnR5KHsgYXR0cmlidXRlOiAncHJlc2VsZWN0LWNvYWNoLWluZGV4JywgdHlwZTogTnVtYmVyIH0pXG4gIHB1YmxpYyBhY2Nlc3NvciBwcmVzZWxlY3RDb2FjaEluZGV4OiBudW1iZXIgPSAtMTtcblxuICBAc3RhdGUoKSBwcm90ZWN0ZWQgYWNjZXNzb3Igc2VsZWN0ZWRDb2FjaEluZGV4OiBudW1iZXIgPSAtMTtcbiAgQHN0YXRlKCkgcHJvdGVjdGVkIGFjY2Vzc29yIGZvY3VzZWRDb2FjaEluZGV4OiBudW1iZXIgPSAtMTtcbiAgQHN0YXRlKCkgcHJvdGVjdGVkIGFjY2Vzc29yIGhvdmVyZWRDb2FjaEluZGV4OiBudW1iZXIgPSAtMTtcblxuICAvLyBEZXNjcmliZXMgdGhlIGRpc3RhbmNlIGJldHdlZW4gdGhlIGJvcmRlciBvZiB0aGUgY29hY2ggYW5kIHRoZSBwbGFjZXMgaW4gcGl4ZWxzXG4gIHByb3RlY3RlZCBjb2FjaEJvcmRlclBhZGRpbmcgPSA2O1xuICAvLyBEZXNjcmliZXMgdGhlIGdhcCBiZXR3ZWVuIHRoZSBjb2FjaGVzIGluIHBpeGVsc1xuICBwcm90ZWN0ZWQgZ2FwQmV0d2VlbkNvYWNoZXMgPSA0O1xuICAvLyBUaGUgY2FsY3VsYXRlZCBjb2FjaEJvcmRlck9mZnNldCBpcyB1c2VkIHRvIGNhbGN1bGF0ZSB0aGUgd2lkdGggYW5kIGhlaWdodCBvZiBjb2FjaCBib3JkZXIgZ3JhcGhpYyxcbiAgLy8gYnV0IGFsc28gdG8gcG9zaXRpb24gb3RoZXIgZ3JhcGhpY3MgdGhhdCBhcmUgYWxpZ25lZCBkaXJlY3RseSB0byB0aGUgY29hY2ggYm9yZGVyLlxuICBwcm90ZWN0ZWQgY29hY2hCb3JkZXJPZmZzZXQgPSB0aGlzLmNvYWNoQm9yZGVyUGFkZGluZyAvIHRoaXMuYmFzZUdyaWRTaXplO1xuICAvLyBEZXNjcmliZXMgdGhlIGdhcCBiZXR3ZWVuIHRoZSBjb2FjaGVzIGRlY2tzIGJ5IG11bHRpcGxlIGRlY2sgdmlzdWFsaXphdGlvblxuICBwcm90ZWN0ZWQgZ2FwQmV0d2VlbkNvYWNoRGVja3MgPSA0ODtcbiAgLy8gRGVzY3JpYmVzIHRoZSBmaXggd2lkdGggb2YgY29hY2ggbmF2aWdhdGlvbiBidXR0b25cbiAgcHJvdGVjdGVkIGNvYWNoTmF2QnV0dG9uRGltOiBudW1iZXIgPSAwO1xuICBwcm90ZWN0ZWQgY29hY2hOYXZEYXRhOiBOYXZpZ2F0aW9uQ29hY2hJdGVtW10gPSBbXTtcbiAgcHJvdGVjdGVkIGN1cnJTY3JvbGxEaXJlY3Rpb246IFNjcm9sbERpcmVjdGlvbiA9IFNjcm9sbERpcmVjdGlvbi5yaWdodDtcbiAgcHJvdGVjdGVkIG1heENhbGNDb2FjaGVzV2lkdGg6IG51bWJlciA9IDA7XG4gIHByb3RlY3RlZCBzY3JvbGxDb2FjaGVzQXJlYVdpZHRoOiBudW1iZXIgPSAwO1xuICBwcm90ZWN0ZWQgc2Nyb2xsTmF2aWdhdGlvbkFyZWFEaW06IG51bWJlciA9IDA7XG4gIHByb3RlY3RlZCB0cmlnZ2VyQ29hY2hQb3NpdGlvbnNDb2xsZWN0aW9uOiBDb2FjaFNjcm9sbFRyaWdnZXJQb2ludFtdID0gW107XG4gIHByb3RlY3RlZCBuYXZpZ2F0aW9uU2Nyb2xsQXJlYTogSFRNTEVsZW1lbnQgPSBudWxsITtcbiAgcHJvdGVjdGVkIGNvYWNoU2Nyb2xsQXJlYTogSFRNTEVsZW1lbnQgPSBudWxsITtcbiAgcHJvdGVjdGVkIGN1cnJTZWxlY3RlZFBsYWNlOiBQbGFjZSB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgY3VyclNlbGVjdGVkUGxhY2VFbGVtZW50SWQ6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICBwcm90ZWN0ZWQgY3VyclNlbGVjdGVkQ29hY2hJbmRleDogbnVtYmVyID0gLTE7XG4gIHByb3RlY3RlZCBjdXJyU2VsZWN0ZWREZWNrSW5kZXg6IG51bWJlciA9IDA7XG4gIHByb3RlY3RlZCBwcmV2ZW50Q29hY2hTY3JvbGxCeVBsYWNlQ2xpY2s6IGJvb2xlYW4gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIHNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzOiBTZWF0UmVzZXJ2YXRpb25TZWxlY3RlZFBsYWNlcyA9IHtcbiAgICBzZWF0czogW10sXG4gICAgYmljeWNsZXM6IFtdLFxuICB9O1xuICBwcm90ZWN0ZWQgc2VhdFJlc2VydmF0aW9uV2l0aG91dE5hdmlnYXRpb25IYXNGb2N1cyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgaXNDb2FjaEdyaWRGb2N1c2FibGUgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGlzQXV0b1Njcm9sbGluZyA9IGZhbHNlO1xuICBwcm90ZWN0ZWQgaXNLZXlib2FyZE5hdmlnYXRpb24gPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGhhc011bHRpcGxlRGVja3MgPSBmYWxzZTtcbiAgcHJvdGVjdGVkIGhhc1NlYXRSZXNlcnZhdGlvbk5hdGl2ZUZvY3VzID0gZmFsc2U7XG4gIHByb3RlY3RlZCBrZXlib2FyZE5hdmlnYXRpb25FdmVudHMgPSB7XG4gICAgQXJyb3dMZWZ0OiAnQXJyb3dMZWZ0JyxcbiAgICBBcnJvd1JpZ2h0OiAnQXJyb3dSaWdodCcsXG4gICAgQXJyb3dVcDogJ0Fycm93VXAnLFxuICAgIEFycm93RG93bjogJ0Fycm93RG93bicsXG4gICAgVGFiOiAnVGFiJyxcbiAgICBFbnRlcjogJ0VudGVyJyxcbiAgfSBhcyBjb25zdDtcblxuICAvLyBHcmFwaGljcyB0aGF0IHNob3VsZCBub3QgYmUgcmVuZGVyZWQgd2l0aCBhbiBhcmVhXG4gIHByb3RlY3RlZCBub3RBcmVhRWxlbWVudHMgPSBbXG4gICAgJ0RSSVZFUl9BUkVBJyxcbiAgICAnQ09BQ0hfUEFTU0FHRScsXG4gICAgJ0NPQUNIX1dBTExfTk9fUEFTU0FHRScsXG4gICAgJ0NPTVBBUlRNRU5UX1BBU1NBR0UnLFxuICAgICdDT01QQVJUTUVOVF9QQVNTQUdFX0hJR0gnLFxuICAgICdDT01QQVJUTUVOVF9QQVNTQUdFX01JRERMRScsXG4gICAgJ0NPTVBBUlRNRU5UX1BBU1NBR0VfTE9XJyxcbiAgXTtcblxuICBwcm90ZWN0ZWQgb3ZlckhhbmdpbmdFbGVtZW50SW5mb3JtYXRpb246IHtcbiAgICBjb2FjaElkOiBzdHJpbmc7XG4gICAgb3ZlcmhhbmdpbmdQbGFjZXM6IGJvb2xlYW47XG4gICAgb3ZlcmhhbmdpbmdHcmFwaGljQXJlYXM6IGJvb2xlYW47XG4gIH1bXSA9IFtdO1xuXG4gIHByaXZhdGUgX2lzUnVubmluZ0luaXRQcmVzZWxlY3RDb2FjaEluZGV4ID0gZmFsc2U7XG4gIHByaXZhdGUgX3Njcm9sbFRpbWVvdXQ6IFJldHVyblR5cGU8dHlwZW9mIHNldFRpbWVvdXQ+IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIF9sYXN0U3RhcnRTY3JvbGxQb3MgPSAtMTtcblxuICBwcm90ZWN0ZWQgb3ZlcnJpZGUgd2lsbFVwZGF0ZShjaGFuZ2VkUHJvcGVydGllczogUHJvcGVydHlWYWx1ZXM8dGhpcz4pOiB2b2lkIHtcbiAgICBzdXBlci53aWxsVXBkYXRlKGNoYW5nZWRQcm9wZXJ0aWVzKTtcblxuICAgIGlmIChjaGFuZ2VkUHJvcGVydGllcy5oYXMoJ3NlYXRSZXNlcnZhdGlvbnMnKSkge1xuICAgICAgdGhpcy5oYXNNdWx0aXBsZURlY2tzID0gdGhpcy5zZWF0UmVzZXJ2YXRpb25zPy5sZW5ndGggPiAxO1xuXG4gICAgICB0aGlzLl9pbml0UHJlcGFyZVNlYXRSZXNlcnZhdGlvbkRhdGEoKTtcbiAgICAgIHRoaXMuX3ByZXBhcmVDb2FjaFdpZHRoQW5kR2FwQ2FsY3VsYXRpb25zKCk7XG4gICAgICB0aGlzLl9pbml0U2VhdFJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb24oKTtcbiAgICAgIHRoaXMuaW5pdE5hdmlnYXRpb25TZWxlY3Rpb25CeVNjcm9sbEV2ZW50KCk7XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzLmhhcygnYmFzZUdyaWRTaXplJykpIHtcbiAgICAgIHRoaXMuY29hY2hCb3JkZXJPZmZzZXQgPSB0aGlzLmNvYWNoQm9yZGVyUGFkZGluZyAvIHRoaXMuYmFzZUdyaWRTaXplO1xuICAgICAgdGhpcy5zdHlsZT8uc2V0UHJvcGVydHkoJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JpZC1zaXplJywgYCR7dGhpcy5iYXNlR3JpZFNpemV9cHhgKTtcblxuICAgICAgdGhpcy5pbml0TmF2aWdhdGlvblNlbGVjdGlvbkJ5U2Nyb2xsRXZlbnQoKTtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgaGVpZ2h0IGlzIHVzZWQsIHRoZSBiYXNlR3JpZFNpemUgbXVzdCBiZSByZWNhbGN1bGF0ZWRcbiAgICBpZiAoY2hhbmdlZFByb3BlcnRpZXMuaGFzKCdoZWlnaHQnKSAmJiAhIXRoaXMuaGVpZ2h0KSB7XG4gICAgICBjb25zdCBzZWF0UmVzZXJ2YXRpb25MYXllciA9IHRoaXMuc2VhdFJlc2VydmF0aW9uc1t0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleF0gfHwgbnVsbDtcbiAgICAgIGlmIChzZWF0UmVzZXJ2YXRpb25MYXllcj8uY29hY2hJdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgdGhpcy5iYXNlR3JpZFNpemUgPSB0aGlzLmhlaWdodCAvIHNlYXRSZXNlcnZhdGlvbkxheWVyLmNvYWNoSXRlbXNbMF0uZGltZW5zaW9uLmg7XG4gICAgICAgIHRoaXMuY29hY2hCb3JkZXJPZmZzZXQgPSB0aGlzLmNvYWNoQm9yZGVyUGFkZGluZyAvIHRoaXMuYmFzZUdyaWRTaXplO1xuICAgICAgICB0aGlzLnN0eWxlPy5zZXRQcm9wZXJ0eSgnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmlkLXNpemUnLCBgJHt0aGlzLmJhc2VHcmlkU2l6ZX1weGApO1xuXG4gICAgICAgIHRoaXMuaW5pdE5hdmlnYXRpb25TZWxlY3Rpb25CeVNjcm9sbEV2ZW50KCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNoYW5nZWRQcm9wZXJ0aWVzLmhhcygnYWxpZ25WZXJ0aWNhbCcpICYmIHRoaXMuYWxpZ25WZXJ0aWNhbCkge1xuICAgICAgdGhpcy5pbml0TmF2aWdhdGlvblNlbGVjdGlvbkJ5U2Nyb2xsRXZlbnQoKTtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlZFByb3BlcnRpZXMuaGFzKCdwcmVzZWxlY3RDb2FjaEluZGV4JykpIHtcbiAgICAgIC8vIHNldFRpbWVvdXQgaXMgbmVjZXNzYXJ5IGJlY2F1c2Ugd2l0aG91dCwgX2dldENvYWNoU2Nyb2xsUG9zaXRpb25YKCkgd291bGQgZmFpbCB3aXRoIE5QRSBiZWNhdXNlXG4gICAgICAvLyB0aGUgY29hY2hTY3JvbGxBcmVhIGlzIG5vdCB5ZXQgaW5pdGlhbGl6ZWRcbiAgICAgIHRoaXMuX2lzUnVubmluZ0luaXRQcmVzZWxlY3RDb2FjaEluZGV4ID0gdHJ1ZTtcbiAgICAgIHNldFRpbWVvdXQoKCkgPT4gdGhpcy5zY3JvbGxUb1NlbGVjdGVkTmF2Q29hY2godGhpcy5wcmVzZWxlY3RDb2FjaEluZGV4KSwgMSk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIG5hdmlnYXRlQnlEaXJlY3Rpb25CdG4oYnRuRGlyZWN0aW9uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLnVuZm9jdXNQbGFjZUVsZW1lbnQoKTtcbiAgICBsZXQgbmF2aWdhdGVUb0NvYWNoSW5kZXggPSB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXg7XG4gICAgaWYgKGJ0bkRpcmVjdGlvbiA9PSAnRElSRUNUSU9OX0xFRlQnICYmIG5hdmlnYXRlVG9Db2FjaEluZGV4ID4gMCkge1xuICAgICAgbmF2aWdhdGVUb0NvYWNoSW5kZXggPVxuICAgICAgICB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXggIT0gLTEgPyB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXggLSAxIDogMDtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgYnRuRGlyZWN0aW9uID09ICdESVJFQ1RJT05fUklHSFQnICYmXG4gICAgICBuYXZpZ2F0ZVRvQ29hY2hJbmRleCA8XG4gICAgICAgIHRoaXMuc2VhdFJlc2VydmF0aW9uc1t0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleF0/LmNvYWNoSXRlbXMubGVuZ3RoIC0gMVxuICAgICkge1xuICAgICAgbmF2aWdhdGVUb0NvYWNoSW5kZXggPVxuICAgICAgICB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXggIT0gLTEgPyB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXggKyAxIDogMDtcbiAgICB9XG5cbiAgICB0aGlzLnNjcm9sbFRvU2VsZWN0ZWROYXZDb2FjaChuYXZpZ2F0ZVRvQ29hY2hJbmRleCk7XG4gIH1cblxuICAvKipcbiAgICogRGF0YSBjYW4gYmUgcHJlcGFyZWQgb25jZSBmb3IgdGhlIGVudGlyZSBjb21wb25lbnRcbiAgICogaW4gb3JkZXIgdG8gYXZvaWQgcmVjdXJyaW5nIGl0ZXJhdGlvbiBwcm9jZXNzZXMgaW4gcmVuZGVyaW5nLlxuICAgKi9cbiAgcHJpdmF0ZSBfaW5pdFByZXBhcmVTZWF0UmVzZXJ2YXRpb25EYXRhKCk6IHZvaWQge1xuICAgIHRoaXMuX2RldGVybWluZUJhc2VGb250U2l6ZSgpO1xuXG4gICAgaWYgKHRoaXMuaGFzTXVsdGlwbGVEZWNrcykge1xuICAgICAgLy8gSWYgdGhlcmUgYXJlIG11bHRpcGxlIGRlY2tzLCB3ZSBuZWVkIHRvIGNoZWNrXG4gICAgICAvLyB3aGV0aGVyIGVtcHR5IGNvYWNoZXMgbmVlZCB0byBiZSBhZGRlZCBvbiBkaWZmZXJlbnQgZGVjayBsZXZlbHNcbiAgICAgIHRoaXMuX2luaXRFbXB0eUNvYWNoRGVja09mZnNldHMoKTtcbiAgICB9XG5cbiAgICB0aGlzLl9wcmVwYXJlTmF2aWdhdGlvbkNvYWNoRGF0YSgpO1xuICB9XG5cbiAgLyoqIEluaXQgc2Nyb2xsIGV2ZW50IGhhbmRsaW5nIGZvciBjb2FjaCBuYXZpZ2F0aW9uICovXG4gIHByb3RlY3RlZCBpbml0TmF2aWdhdGlvblNlbGVjdGlvbkJ5U2Nyb2xsRXZlbnQoKTogdm9pZCB7XG4gICAgdGhpcy5jb2FjaFNjcm9sbEFyZWEgPSB0aGlzLnNoYWRvd1Jvb3Q/LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAnI3NiYi1zcl9fd3JhcHBlci1zY3JvbGxhcmVhJyxcbiAgICApIGFzIEhUTUxFbGVtZW50O1xuICAgIHRoaXMubmF2aWdhdGlvblNjcm9sbEFyZWEgPSB0aGlzLnNoYWRvd1Jvb3Q/LnF1ZXJ5U2VsZWN0b3IoXG4gICAgICAnI3NiYi1zcl9fbmF2aWdhdGlvbi1saXN0LWNvYWNoZXMnLFxuICAgICkgYXMgSFRNTEVsZW1lbnQ7XG5cbiAgICBjb25zdCBzZWF0UmVzZXJ2YXRpb25EZWNrID0gdGhpcy5zZWF0UmVzZXJ2YXRpb25zXG4gICAgICA/IHRoaXMuc2VhdFJlc2VydmF0aW9uc1t0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleF1cbiAgICAgIDogbnVsbDtcbiAgICBpZiAoc2VhdFJlc2VydmF0aW9uRGVjayAmJiBzZWF0UmVzZXJ2YXRpb25EZWNrLmNvYWNoSXRlbXMubGVuZ3RoID4gMCkge1xuICAgICAgLy8gQ2FsY3VsYXRlcyB0aGUgYWJzb2x1dGUgaGVpZ2h0IG9mIG9uZSBjb2FjaCBpbmNsdWRpbmcgYm9yZGVyIHBhZGRpbmdcbiAgICAgIGNvbnN0IGNvYWNoSGVpZ2h0V2l0aEJvcmRlclBhZGRpbmcgPVxuICAgICAgICBzZWF0UmVzZXJ2YXRpb25EZWNrLmNvYWNoSXRlbXNbMF0uZGltZW5zaW9uLmggKiB0aGlzLmJhc2VHcmlkU2l6ZSArIHRoaXMuY29hY2hCb3JkZXJQYWRkaW5nO1xuXG4gICAgICAvLyBDYWxjdWxhdGUgZWFjaCBnYXAgYmV0d2VlbiBtdWx0aXBsZSBjb2FjaCB0aGUgZGVja3MuXG4gICAgICAvLyBObyBnYXAgZXhpc3QgaWYganVzdCBvbmUgY29hY2ggZGVjayBleGlzdC5cbiAgICAgIGNvbnN0IGdhcEJldHdlZW5Db2FjaERlY2tzID0gKHRoaXMuc2VhdFJlc2VydmF0aW9ucy5sZW5ndGggLSAxKSAqIHRoaXMuZ2FwQmV0d2VlbkNvYWNoRGVja3M7XG5cbiAgICAgIHRoaXMuc3R5bGU/LnNldFByb3BlcnR5KFxuICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1oZWlnaHQnLFxuICAgICAgICBgJHtjb2FjaEhlaWdodFdpdGhCb3JkZXJQYWRkaW5nICogdGhpcy5zZWF0UmVzZXJ2YXRpb25zLmxlbmd0aCArIGdhcEJldHdlZW5Db2FjaERlY2tzfWAsXG4gICAgICApO1xuICAgICAgdGhpcy5zdHlsZT8uc2V0UHJvcGVydHkoJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZGVja3MnLCBgJHt0aGlzLnNlYXRSZXNlcnZhdGlvbnMubGVuZ3RofWApO1xuICAgIH1cblxuICAgIGlmICh0aGlzLm5hdmlnYXRpb25TY3JvbGxBcmVhKSB7XG4gICAgICB0aGlzLnNjcm9sbE5hdmlnYXRpb25BcmVhRGltID0gdGhpcy5hbGlnblZlcnRpY2FsXG4gICAgICAgID8gdGhpcy5uYXZpZ2F0aW9uU2Nyb2xsQXJlYS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHRcbiAgICAgICAgOiB0aGlzLm5hdmlnYXRpb25TY3JvbGxBcmVhLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoO1xuXG4gICAgICAvLyBJbml0IHRoZSBjb2FjaE5hdkJ1dHRvbkRpbSBkaW1lbnNpb24sIHdoaWNoIGlzIG5lZWRlZCB0byBjYWxjdWxhdGUgdGhlIGNvcnJlY3Qgc2Nyb2xsIG5hdmlnYXRpb24gbGF0ZXJcbiAgICAgIGNvbnN0IG5hdkNvYWNoZXNMaXN0ID0gdGhpcy5uYXZpZ2F0aW9uU2Nyb2xsQXJlYS5xdWVyeVNlbGVjdG9yKCd1bCA+IGxpJykgYXMgSFRNTFVMaXN0RWxlbWVudDtcbiAgICAgIGlmIChuYXZDb2FjaGVzTGlzdCkge1xuICAgICAgICBjb25zdCBmaXJzdExpRWxlRGltZW5zaW9uID0gbmF2Q29hY2hlc0xpc3Q/LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgICAgICB0aGlzLmNvYWNoTmF2QnV0dG9uRGltID0gdGhpcy5hbGlnblZlcnRpY2FsXG4gICAgICAgICAgPyBmaXJzdExpRWxlRGltZW5zaW9uLmhlaWdodFxuICAgICAgICAgIDogZmlyc3RMaUVsZURpbWVuc2lvbi53aWR0aDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5jb2FjaFNjcm9sbEFyZWEgJiYgc2VhdFJlc2VydmF0aW9uRGVjaykge1xuICAgICAgLy8gSW5pdCB0aGUgc3RhcnQgb2Zmc2V0IGZvciB0aGUgY2FsY3VsYXRpb24gb2YgdGhlIGNvYWNoIHNjcm9sbCB0cmlnZ2VyIHBvc2l0aW9uc1xuICAgICAgbGV0IGN1cnJDYWxjVHJpZ2dlclBvcyA9IDA7XG4gICAgICB0aGlzLnNjcm9sbENvYWNoZXNBcmVhV2lkdGggPSB0aGlzLmFsaWduVmVydGljYWxcbiAgICAgICAgPyB0aGlzLmNvYWNoU2Nyb2xsQXJlYS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS5oZWlnaHRcbiAgICAgICAgOiB0aGlzLmNvYWNoU2Nyb2xsQXJlYS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKS53aWR0aDtcblxuICAgICAgLy8gUHJlY2FsY3VsYXRlIHRyaWdnZXIgc2Nyb2xsIHBvc2l0aW9uIGFycmF5IGRlcGVuZHMgb24gY29hY2ggd2lkdGhcbiAgICAgIHRoaXMudHJpZ2dlckNvYWNoUG9zaXRpb25zQ29sbGVjdGlvbiA9IHNlYXRSZXNlcnZhdGlvbkRlY2suY29hY2hJdGVtcy5tYXAoKGNvYWNoKSA9PiB7XG4gICAgICAgIGNvbnN0IHN0YXJ0UG9zWCA9IGN1cnJDYWxjVHJpZ2dlclBvcztcbiAgICAgICAgY29uc3QgY29hY2hXaWR0aCA9IHRoaXMuZ2V0Q2FsY3VsYXRlZERpbWVuc2lvbihjb2FjaC5kaW1lbnNpb24pLnc7XG5cbiAgICAgICAgLy8gQ2FsY3VsYXRpb24gb2YgdGhlIGVuZCBzY3JvbGwgdHJpZ2dlciBwb3NpdGlvbiBvZiBhIGNvYWNoLCBpbmNsdWRpbmcgdGhlIGdhcCBiZXR3ZWVuIHRoZSBjb2FjaGVzXG4gICAgICAgIC8vIFRoZSBnYXAgaXMgbWF5YmUgYWRqdXN0ZWQgaWYgb3ZlcmhhbmdpbmcgcGxhY2VzIG9yIGdyYXBoaWNzIGV4aXN0XG4gICAgICAgIGNvbnN0IGN1cnJlbnRDb2FjaE92ZXJoYW5naW5nSW5mbyA9IHRoaXMub3ZlckhhbmdpbmdFbGVtZW50SW5mb3JtYXRpb24uZmluZChcbiAgICAgICAgICAoZSkgPT4gZS5jb2FjaElkID09PSBjb2FjaC5pZCxcbiAgICAgICAgKTtcbiAgICAgICAgY29uc3Qgb3ZlcmhhbmdpbmdFbGVtZW50c1ByZXNlbnQgPVxuICAgICAgICAgIGN1cnJlbnRDb2FjaE92ZXJoYW5naW5nSW5mbz8ub3ZlcmhhbmdpbmdQbGFjZXMgfHxcbiAgICAgICAgICBjdXJyZW50Q29hY2hPdmVyaGFuZ2luZ0luZm8/Lm92ZXJoYW5naW5nR3JhcGhpY0FyZWFzO1xuICAgICAgICBjdXJyQ2FsY1RyaWdnZXJQb3MgKz1cbiAgICAgICAgICBjb2FjaFdpZHRoICtcbiAgICAgICAgICAoIW92ZXJoYW5naW5nRWxlbWVudHNQcmVzZW50ID8gdGhpcy5nYXBCZXR3ZWVuQ29hY2hlcyA6IDIgKiB0aGlzLmdhcEJldHdlZW5Db2FjaGVzKTtcblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgIHN0YXJ0OiBzdGFydFBvc1gsXG4gICAgICAgICAgZW5kOiBjdXJyQ2FsY1RyaWdnZXJQb3MsXG4gICAgICAgICAgd2lkdGg6IGNvYWNoV2lkdGgsXG4gICAgICAgIH0gYXMgQ29hY2hTY3JvbGxUcmlnZ2VyUG9pbnQ7XG4gICAgICB9KTtcblxuICAgICAgLy8gU2V0IG1heGltdW0gY2FsY3VsYXRlZCBjb2FjaCB3aWR0aFxuICAgICAgdGhpcy5tYXhDYWxjQ29hY2hlc1dpZHRoID0gY3VyckNhbGNUcmlnZ2VyUG9zO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBTY3JvbGwgZXZlbnQgaGFuZGxlciBtYW5hZ2VkIHRoZSBlbmQgb2Ygc2Nyb2xsaW5nIGluc2lkZSB0aGUgY29hY2ggc2Nyb2xsIGFyZWEuXG4gICAqIFRpbWVvdXQgZXZlbnQgaGFuZGxpbmcgdG8gY2hlY2sgaWYgdGhlIHNjcm9sbGluZyBoYXMgYmVlbiBjb21wbGV0ZWQuXG4gICAqIEl0IGlzIHJlcXVpcmVkIGJlY2F1c2UgdGhlIFNhZmFyaSBicm93c2VyIGRvZXMgbm90IGhhbmRsZSBzY3JvbGxlbmQgZXZlbnQsXG4gICAqIGFuZCB3ZSB0aGVyZWZvcmUgaW1pdGF0ZSB0aGlzIGV2ZW50IC0+IHNjcm9sbGVuZC5cbiAgICovXG4gIEBldmVudE9wdGlvbnMoeyBwYXNzaXZlOiB0cnVlIH0pXG4gIHByb3RlY3RlZCBjb2FjaEFyZWFTY3JvbGxlbmQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuX3Njcm9sbFRpbWVvdXQpIHtcbiAgICAgIC8vIEZpcnN0LCB3ZSBjbGVhcmVkIHRoZSByZWdpc3RlcmVkIHRpbWVvdXQsIGFzIHRoZSBzY3JvbGxpbmcgaXMgc3RpbGwgcnVubmluZ1xuICAgICAgLy8gYW5kIHRodXMgd2UgcHJldmVudCB0aGUgZXhlY3V0aW9uIG9mIHRoZSBfaGFuZGxlQ29hY2hBcmVhU2Nyb2xsZW5kRXZlbnQgZnVuY3Rpb25cbiAgICAgIGNsZWFyVGltZW91dCh0aGlzLl9zY3JvbGxUaW1lb3V0KTtcbiAgICB9XG4gICAgLy8gSWYgbm8gZnVydGhlciBzY3JvbGwgZXZlbnQgaXMgZmlyZWQsIHRoZSBuZXh0IHRpbWVvdXQgY2FuIGV4ZWN1dGUgdGhlIGlubmVyIGZ1bmN0aW9uIF9oYW5kbGVDb2FjaEFyZWFTY3JvbGxlbmRFdmVudCB3aXRob3V0IGNsZWFyaW5nXG4gICAgdGhpcy5fc2Nyb2xsVGltZW91dCA9IHNldFRpbWVvdXQoKCkgPT4gdGhpcy5faGFuZGxlQ29hY2hBcmVhU2Nyb2xsZW5kRXZlbnQoKSwgMTUwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBJZiBubyBuYXZpZ2F0aW9uIGV4aXN0cyAocHJvcGVydHkgc2V0dGluZyAtPiBoYXNOYXZpZ2F0aW9uKSBhbmQgYSB0YWJsZSBjb2FjaCBnZXRzIHRoZSBmb2N1cyxcbiAgICogdGhlIGZpcnN0IHBsYWNlIGluIHRoZSBjb2FjaCBtdXN0IGJlIGF1dG9tYXRpY2FsbHkgcHJlc2VsZWN0ZWQgdG8gY29udHJvbCB0aGUgcGxhY2UgbmF2aWdhdGlvbiB2aWEga2V5Ym9hcmRcbiAgICpcbiAgICogQHBhcmFtIGZvY3VzQ29hY2hJbmRleFxuICAgKi9cbiAgcHJvdGVjdGVkIG9uRm9jdXNUYWJsZUNvYWNoQW5kUHJlc2VsZWN0UGxhY2UoZm9jdXNDb2FjaEluZGV4OiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuc2VhdFJlc2VydmF0aW9uV2l0aG91dE5hdmlnYXRpb25IYXNGb2N1cyAmJiAhdGhpcy5oYXNOYXZpZ2F0aW9uKSB7XG4gICAgICB0aGlzLnNlYXRSZXNlcnZhdGlvbldpdGhvdXROYXZpZ2F0aW9uSGFzRm9jdXMgPSB0cnVlO1xuICAgICAgdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4ID1cbiAgICAgICAgZm9jdXNDb2FjaEluZGV4ID09PSAwXG4gICAgICAgICAgPyB0aGlzLmdldE5leHRBdmFpbGFibGVDb2FjaEluZGV4KC0xKVxuICAgICAgICAgIDogdGhpcy5nZXRQcmV2QXZhaWxhYmxlQ29hY2hJbmRleChmb2N1c0NvYWNoSW5kZXgpO1xuICAgICAgdGhpcy5wcmVzZWxlY3RQbGFjZUluQ29hY2goKTtcbiAgICB9XG4gIH1cblxuICAvKiogV2lsbCBiZSB0cmlnZ2VyZWQgYnkgZm9jdXMgbmF2aWdhdGlvbiBkaXJlY3Rpb24gKi9cbiAgcHJvdGVjdGVkIG9uRm9jdXNOYXZEaXJlY3Rpb25CdXR0b24oKTogdm9pZCB7XG4gICAgLy8gSWYgYW55IG5hdmlnYXRpb24gZGlyZWN0aW9uIGJ1dHRvbiAocmlnaHR8bGVmdCkgZ2V0IHRoZSBmb2N1cywgc28gd2UgaGF2ZSBtYW51YWwgcmVzZXQgdGhlIHByZXZpb3VzIGZvY3VzQ29hY2hJbmRleC5cbiAgICB0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID0gLTE7XG4gIH1cblxuICAvKiogVEFCIEtleSBFdmVudCBoYW5kbGluZyBmb3IgQ29hY2ggTmF2aWdhdGlvbiAqL1xuICBwcm90ZWN0ZWQgb25LZXlOYXZpZ2F0aW9uTmF2Q29hY2hCdXR0b24oXG4gICAgZXZlbnQ6IEtleWJvYXJkRXZlbnQsXG4gICAgY3Vyck5hdkNvYWNoQnV0dG9uSW5kZXg6IG51bWJlcixcbiAgKTogdm9pZCB7XG4gICAgY29uc3QgcHJlc3NlZEtleSA9IGV2ZW50LmtleTtcblxuICAgIGlmIChwcmVzc2VkS2V5ID09PSB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5UYWIpIHtcbiAgICAgIHRoaXMuX2hhbmRsZVRhYktleU5hdmlnYXRpb24oZXZlbnQsICduYXZpZ2F0aW9uJywgY3Vyck5hdkNvYWNoQnV0dG9uSW5kZXgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEJ5IHVzaW5nIGFueSBvdGhlciBrZXkgKG5vIFRBQikgaW5zaWRlIHRoZSBOYXZpZ2F0aW9uIGFyZWEsIHNvIHdlIGNhbiBoYW5kbGUgdGhpcyBieSB1c2luZyB0aGUgbG9naWMgZnJvbSBrZXlib2FyZFNlYXRtYXBFdmVudEhhbmRsaW5nXG4gICAgaWYgKGlzQXJyb3dLZXlPclBhZ2VLZXlzUHJlc3NlZChldmVudCkpIHtcbiAgICAgIHRoaXMua2V5Ym9hcmRTZWF0bWFwRXZlbnRIYW5kbGluZyhldmVudCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEdlbmVyYWwgVEFCIEtleSBFdmVudCBoYW5kbGluZyBmb3IgdGFiIG5hdmlnYXRpb24gaW5zaWRlIHRoZSBjb2FjaCBuYXZpZ2F0aW9uIGFyZWEgYW5kIHRoZSBzZWF0bWFwIGFyZWEgKi9cbiAgcHJpdmF0ZSBfaGFuZGxlVGFiS2V5TmF2aWdhdGlvbihcbiAgICBldmVudDogS2V5Ym9hcmRFdmVudCxcbiAgICBldmVudEFyZWE6IHN0cmluZyxcbiAgICBjdXJyVGFiSW5kZXg/OiBudW1iZXIsXG4gICk6IHZvaWQge1xuICAgIGNvbnN0IHByZXNzZWRLZXkgPSBldmVudC5rZXk7XG4gICAgY29uc3QgcHJlc3NlZFNoaWZ0VGFiID0gZXZlbnQuc2hpZnRLZXk7XG5cbiAgICBpZiAocHJlc3NlZEtleSA9PT0gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuVGFiKSB7XG4gICAgICAvLyBIYW5kbGUgVEFCIGtleSBldmVudCBuYXZpZ2F0aW9uIGZvciBjb2FjaCBuYXZpZ2F0aW9uIGFyZWEuXG4gICAgICAvLyBGcHIgY29hY2ggbmF2aWdhdGlvbiB3ZSBqdXN0IGNvbnRyb2wgdGhlIGZvY3VzIGluZGV4IHRvIHZpc3VhbGl6ZSBmb2N1cyBzdHlsZSBmb3IgbmF2IGNvYWNoIGJ1dHRvblxuICAgICAgaWYgKGV2ZW50QXJlYSA9PSAnbmF2aWdhdGlvbicpIHtcbiAgICAgICAgaWYgKGN1cnJUYWJJbmRleCA9PSB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXgpIHtcbiAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAhdGhpcy5jdXJyU2VsZWN0ZWRQbGFjZSB8fFxuICAgICAgICAgICAgIXByZXNzZWRTaGlmdFRhYiB8fFxuICAgICAgICAgICAgdGhpcy5jb2FjaE5hdkRhdGFbY3VyclRhYkluZGV4XS5pc0RyaXZlckFyZWEgfHxcbiAgICAgICAgICAgIHRoaXMuZm9jdXNlZENvYWNoSW5kZXggPT0gLTFcbiAgICAgICAgICApIHtcbiAgICAgICAgICAgIHRoaXMuZm9jdXNlZENvYWNoSW5kZXggPSBjdXJyVGFiSW5kZXg7XG4gICAgICAgICAgfSBlbHNlIGlmIChwcmVzc2VkU2hpZnRUYWIgJiYgdGhpcy5jdXJyU2VsZWN0ZWRQbGFjZSkge1xuICAgICAgICAgICAgLy9JZiB0aGUgRm9yIGJhY2sgdGFiYmluZywgd2UganVtcFxuICAgICAgICAgICAgdGhpcy5mb2N1c2VkQ29hY2hJbmRleCA9IC0xO1xuICAgICAgICAgICAgdGhpcy5mb2N1c1BsYWNlRWxlbWVudCh0aGlzLmN1cnJTZWxlY3RlZFBsYWNlKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5mb2N1c2VkQ29hY2hJbmRleCA9IGN1cnJUYWJJbmRleCE7XG4gICAgICAgIH1cblxuICAgICAgICB0aGlzLl9zY3JvbGxUb1NlbGVjdGVkTmF2aWdhdGlvbkJ1dHRvbihjdXJyVGFiSW5kZXghKTtcbiAgICAgIH1cbiAgICAgIC8vIEhhbmRsZSBUQUIga2V5IGV2ZW50IG5hdmlnYXRpb24gZm9yIHNlYXRtYXAgYXJlYVxuICAgICAgZWxzZSBpZiAoZXZlbnRBcmVhID09ICdzZWF0bWFwJykge1xuICAgICAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICBpZiAocHJlc3NlZFNoaWZ0VGFiKSB7XG4gICAgICAgICAgdGhpcy5fbmF2aWdhdGVDb2FjaE5hdmlnYXRpb25CeUtleWJvYXJkKCdQUkVWX1RBQicpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoaXMuX25hdmlnYXRlQ29hY2hOYXZpZ2F0aW9uQnlLZXlib2FyZCgnTkVYVF9UQUInKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBJbml0aWFsaXNhdGlvbiBvZiBLZXlib2FyZCBTZWF0bWFwIGV2ZW50IGhhbmRsaW5nIHRvIG5hdmlnYXRpb24gYmV0d2VlbiBlYWNoIHBsYWNlcyBpbnNpZGUgYSBzZWxlY3RlZCBjb2FjaCBieSB1c2luZyBbYXJyb3ddIGtleXMuXG4gICAqIFdpdGggdGhlIFtUQUJdIGtleSB0aGUgdXNlciBuYXZpZ2F0aW9uIGdvZXMgdG8gdGhlIG5leHQgY29hY2ggbmF2aWdhdGlvbiBlbGVtZW50IGFuZCB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHBsYWNlIGlzIGF1dG9tYXRpY2FsbHkgcmVzZXQuXG4gICAqL1xuICBwcm90ZWN0ZWQga2V5Ym9hcmRTZWF0bWFwRXZlbnRIYW5kbGluZyhldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQge1xuICAgIGNvbnN0IHByZXNzZWRLZXkgPSBldmVudC5rZXk7XG4gICAgdGhpcy5wcmV2ZW50Q29hY2hTY3JvbGxCeVBsYWNlQ2xpY2sgPSBmYWxzZTtcblxuICAgIC8vIENoZWNrIGFueSBrZXlib2FyZCBldmVudCB3YXMgdHJpZ2dlcmVkIGluc2lkZSB0aGUgc2VhdCByZXNlcnZhdGlvbiBjb21wb25lbnQsXG4gICAgLy8gc28gd2UgY2FuIHNheSB0aGUgbmF0aXZlIGJyb3dzZXIgZm9jdXMgbGllcyBvbiB0aGUgY29tcG9uZW50XG4gICAgaWYgKFxuICAgICAgIXRoaXMuaGFzU2VhdFJlc2VydmF0aW9uTmF0aXZlRm9jdXMgJiZcbiAgICAgICgoZXZlbnQuc2hpZnRLZXkgJiYgcHJlc3NlZEtleSA9PT0gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuVGFiKSB8fFxuICAgICAgICBwcmVzc2VkS2V5ID09PSB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5UYWIpXG4gICAgKSB7XG4gICAgICB0aGlzLmhhc1NlYXRSZXNlcnZhdGlvbk5hdGl2ZUZvY3VzID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBJZiBhbnkgcGxhY2UgaXMgc2VsZWN0ZWQgYW5kIFRBQiBLZXkgY29tYmluYXRpb24gaXN0IHByZXNzZWQsXG4gICAgLy8gdGhlbiB3ZSBoYW5kbGUgdGhlIG5leHQgb3IgcHJldmlvdXMgY29hY2ggc2VsZWN0aW9uXG4gICAgaWYgKHByZXNzZWRLZXkgPT0gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuVGFiKSB7XG4gICAgICB0aGlzLl9oYW5kbGVUYWJLZXlOYXZpZ2F0aW9uKGV2ZW50LCAnc2VhdG1hcCcpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEFycm93IEtleWJvYXJkIG5hdmlnYXRpb24gdG8gY29udHJvbCBwbGFjZXMgaW5zaWRlIHRoZSBzZWF0bWFwXG4gICAgaWYgKHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCAhPT0gLTEgJiYgaXNBcnJvd0tleU9yUGFnZUtleXNQcmVzc2VkKGV2ZW50KSkge1xuICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcblxuICAgICAgc3dpdGNoIChwcmVzc2VkS2V5KSB7XG4gICAgICAgIGNhc2UgdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuQXJyb3dMZWZ0OlxuICAgICAgICAgIHtcbiAgICAgICAgICAgIGNvbnN0IHByZXNzZWRMZWZ0S2V5TWFwcGluZzogc3RyaW5nID0gdGhpcy5hbGlnblZlcnRpY2FsXG4gICAgICAgICAgICAgID8gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuQXJyb3dEb3duXG4gICAgICAgICAgICAgIDogcHJlc3NlZEtleTtcbiAgICAgICAgICAgIHRoaXMuX25hdmlnYXRlVG9QbGFjZUJ5S2V5Ym9hcmQocHJlc3NlZExlZnRLZXlNYXBwaW5nKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIGNhc2UgdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuQXJyb3dSaWdodDpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb25zdCBwcmVzc2VkUmlnaHRLZXlNYXBwaW5nOiBzdHJpbmcgPSB0aGlzLmFsaWduVmVydGljYWxcbiAgICAgICAgICAgICAgPyB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5BcnJvd1VwXG4gICAgICAgICAgICAgIDogcHJlc3NlZEtleTtcbiAgICAgICAgICAgIHRoaXMuX25hdmlnYXRlVG9QbGFjZUJ5S2V5Ym9hcmQocHJlc3NlZFJpZ2h0S2V5TWFwcGluZyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIHRoaXMua2V5Ym9hcmROYXZpZ2F0aW9uRXZlbnRzLkFycm93VXA6XG4gICAgICAgICAge1xuICAgICAgICAgICAgY29uc3QgcHJlc3NlZFVwS2V5TWFwcGluZzogc3RyaW5nID0gdGhpcy5hbGlnblZlcnRpY2FsXG4gICAgICAgICAgICAgID8gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuQXJyb3dMZWZ0XG4gICAgICAgICAgICAgIDogcHJlc3NlZEtleTtcbiAgICAgICAgICAgIHRoaXMuX25hdmlnYXRlVG9QbGFjZUJ5S2V5Ym9hcmQocHJlc3NlZFVwS2V5TWFwcGluZyk7XG4gICAgICAgICAgfVxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIHRoaXMua2V5Ym9hcmROYXZpZ2F0aW9uRXZlbnRzLkFycm93RG93bjpcbiAgICAgICAgICB7XG4gICAgICAgICAgICBjb25zdCBwcmVzc2VkRG93bktleU1hcHBpbmc6IHN0cmluZyA9IHRoaXMuYWxpZ25WZXJ0aWNhbFxuICAgICAgICAgICAgICA/IHRoaXMua2V5Ym9hcmROYXZpZ2F0aW9uRXZlbnRzLkFycm93UmlnaHRcbiAgICAgICAgICAgICAgOiBwcmVzc2VkS2V5O1xuICAgICAgICAgICAgdGhpcy5fbmF2aWdhdGVUb1BsYWNlQnlLZXlib2FyZChwcmVzc2VkRG93bktleU1hcHBpbmcpO1xuICAgICAgICAgIH1cbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogU2VsZWN0cyBhIHBsYWNlIGluc2lkZSB0aGUgY29hY2ggaWYgbmF2aWdhdGVkIHZpYSBrZXlib2FyZCxcbiAgICogb3RoZXJ3aXNlIHRoZSBjb2FjaCBncmlkIGlzIHNlbGVjdGVkIChuZWNlc3NhcnkgZm9yIFNjcmVlblJlYWRlcilcbiAgICovXG4gIHByb3RlY3RlZCBwcmVzZWxlY3RQbGFjZUluQ29hY2goKTogdm9pZCB7XG4gICAgLy8gTm8gcHJlc2VsZWN0IHBsYWNlIGJ5IG1hbnVhbCBzZWF0bWFwIHNjcm9sbGluZ1xuICAgIGlmICghdGhpcy5pc0F1dG9TY3JvbGxpbmcpIHJldHVybjtcblxuICAgIC8vIE5vIGF1dG8gcGxhY2UgcHJlc2VsZWN0aW9uIGJ5IHJ1bm5pbmcgdGhlIHByZXNlbGVjdCBjb2FjaCBpbmRleFxuICAgIGlmICh0aGlzLl9pc1J1bm5pbmdJbml0UHJlc2VsZWN0Q29hY2hJbmRleCkge1xuICAgICAgdGhpcy5faXNSdW5uaW5nSW5pdFByZXNlbGVjdENvYWNoSW5kZXggPSBmYWxzZTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBGb3IgRHJpdmVyQXJlYSBvciBFbXB0eSBjb2FjaCAobm8gcGxhY2VzKSwgbm8gcGxhY2UgaXMgc2VsZWN0YWJsZSwgc28gd2UgcmV0dXJuIGRpcmVjdGx5XG4gICAgaWYgKFxuICAgICAgdGhpcy5jb2FjaE5hdkRhdGFbdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4XSAmJlxuICAgICAgdGhpcy5jb2FjaE5hdkRhdGFbdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4XS5pc0RyaXZlckFyZWFcbiAgICApIHtcbiAgICAgIHRoaXMuX3NldEZvY3VzVG9TZWxlY3RlZENvYWNoR3JpZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIE9ubHkgd2hlbiBrZXlib2FyZCBuYXZpZ2F0aW9uIGlzIHVzZWQgYW5kIGNvYWNoZXMgYXJlIHNjcm9sbGVkIGJ5IGF1dG8gc2Nyb2xsaW5nLFxuICAgIC8vIHRoZW4gd2UgY2FuIHNldCB0aGUgZm9jdXMgb24gdGhlIGZpcnN0IHBsYWNlIGluIHRoZSBjb2FjaC5cbiAgICBpZiAodGhpcy5pc0tleWJvYXJkTmF2aWdhdGlvbiAmJiB0aGlzLmlzQXV0b1Njcm9sbGluZykge1xuICAgICAgY29uc3QgY2xvc2VzdFBsYWNlID0gdGhpcy5fZ2V0Q2xvc2VzdFBsYWNlQnlLZXlEaXJlY3Rpb24oKTtcbiAgICAgIC8vSWYgY2xvc2VzdFBsYWNlIGV4aXN0LCB3ZSBoYXZlIHRvIHVuZm9jdXMgcHJldmlvdXMgZm9jdXNlZCBwbGFjZVxuICAgICAgaWYgKGNsb3Nlc3RQbGFjZSkge1xuICAgICAgICB0aGlzLnVuZm9jdXNQbGFjZUVsZW1lbnQoKTtcbiAgICAgICAgdGhpcy5mb2N1c1BsYWNlRWxlbWVudChjbG9zZXN0UGxhY2UpO1xuICAgICAgICB0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID0gLTE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBJZiBhIGNvYWNoIHdhcyBzZWxlY3RlZCB3aXRoIG5vIHBsYWNlcywgdGhlbiB3ZSBoYXZlIHRvIGZvY3VzIHRoZSBjb2FjaEdyaWRcbiAgICAgICAgdGhpcy5fc2V0Rm9jdXNUb1NlbGVjdGVkQ29hY2hHcmlkKCk7XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEluIGNhc2VzIHdoZXJlIHRoZSBwcmVzZWxlY3Rpb24gZnVuY3Rpb24gaXMgdHJpZ2dlcmVkIGJ5IG5vcm1hbCBjbGlja2luZyBvciB2aWEgc2NyZWVuIHJlYWRlciB2aWEgdGFiLFxuICAgIC8vIHdlIG9ubHkgZm9jdXMgdGhlIHRhYmxlIHdpdGhvdXQgZGlyZWN0bHkgZm9jdXNpbmcgdGhlIHBsYWNlLlxuICAgIGVsc2Uge1xuICAgICAgdGhpcy51bmZvY3VzUGxhY2VFbGVtZW50KCk7XG5cbiAgICAgIHRoaXMuaXNDb2FjaEdyaWRGb2N1c2FibGUgPSB0cnVlO1xuICAgICAgdGhpcy5fc2V0Rm9jdXNUb1NlbGVjdGVkQ29hY2hHcmlkKCk7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHNjcm9sbFRvU2VsZWN0ZWROYXZDb2FjaChzZWxlY3RlZE5hdkNvYWNoSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIGlmIChcbiAgICAgIHRoaXMuX2lzVmFsaWRDb2FjaEluZGV4KHNlbGVjdGVkTmF2Q29hY2hJbmRleCkgJiZcbiAgICAgIHNlbGVjdGVkTmF2Q29hY2hJbmRleCAhPT0gdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4XG4gICAgKSB7XG4gICAgICB0aGlzLmhvdmVyZWRDb2FjaEluZGV4ID0gc2VsZWN0ZWROYXZDb2FjaEluZGV4O1xuICAgICAgdGhpcy5pc0F1dG9TY3JvbGxpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5pc0NvYWNoR3JpZEZvY3VzYWJsZSA9IHRydWU7XG4gICAgICB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXggPSBzZWxlY3RlZE5hdkNvYWNoSW5kZXg7XG4gICAgICB0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleCA9IHRoaXMuX2dldEV4aXN0aW5nQ29hY2hEZWNrSW5kZXgoKTtcbiAgICAgIHRoaXMuX3NldFNjcm9sbERpcmVjdGlvbkJ5Q29hY2hJbmRleCgpO1xuXG4gICAgICBjb25zdCBzY3JvbGxUb0NvYWNoUG9zWCA9IHRoaXMuX2dldENvYWNoU2Nyb2xsUG9zaXRpb25YKCk7XG4gICAgICBjb25zdCBpc1NlbGVjdGVkQ29hY2hJbmRleFNjcm9sbGFibGUgPVxuICAgICAgICB0aGlzLnNlbGVjdGVkQ29hY2hJbmRleCAhPT0gLTEgfHwgdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4ID4gMDtcblxuICAgICAgLy8gQ2hlY2tzIHdoZXRoZXIgdGhlIGN1cnJlbnQgc2Nyb2xsIHBvc2l0aW9uIGFsbG93cyBzY3JvbGxpbmcgdG8gdGhlIG5leHQgd2Fnb24gb3Igbm90XG4gICAgICBpZiAoaXNTZWxlY3RlZENvYWNoSW5kZXhTY3JvbGxhYmxlICYmIHRoaXMuX2lzU2Nyb2xsYWJsZVRvU2VsZWN0ZWRDb2FjaCgpKSB7XG4gICAgICAgIHRoaXMuX2xhc3RTdGFydFNjcm9sbFBvcyA9IHRoaXMuY29hY2hTY3JvbGxBcmVhLnNjcm9sbExlZnQ7XG4gICAgICAgIHRoaXMuY29hY2hTY3JvbGxBcmVhLnNjcm9sbFRvKHtcbiAgICAgICAgICB0b3A6IHRoaXMuYWxpZ25WZXJ0aWNhbCA/IHNjcm9sbFRvQ29hY2hQb3NYIDogMCxcbiAgICAgICAgICBsZWZ0OiB0aGlzLmFsaWduVmVydGljYWwgPyAwIDogc2Nyb2xsVG9Db2FjaFBvc1gsXG4gICAgICAgICAgYmVoYXZpb3I6ICdzbW9vdGgnLFxuICAgICAgICB9KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudXBkYXRlQ3VycmVudFNlbGVjdGVkQ29hY2goKTtcbiAgICAgIH1cblxuICAgICAgLy8gQXV0b21hdGljIHNjcm9sbGluZyB0byB0aGUgc2VsZWN0ZWQgY29hY2ggaW4gdGhlIG1haW4gbmF2aWdhdGlvblxuICAgICAgdGhpcy5fc2Nyb2xsVG9TZWxlY3RlZE5hdmlnYXRpb25CdXR0b24oc2VsZWN0ZWROYXZDb2FjaEluZGV4KTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgZm9jdXNQbGFjZUVsZW1lbnQocGxhY2U6IFBsYWNlIHwgbnVsbCk6IHZvaWQge1xuICAgIHRoaXMudW5mb2N1c1BsYWNlRWxlbWVudCgpO1xuICAgIGlmIChwbGFjZSkge1xuICAgICAgdGhpcy5jdXJyU2VsZWN0ZWRQbGFjZSA9IHBsYWNlO1xuICAgICAgdGhpcy5fc2V0Q3VyclNlbGVjdGVkUGxhY2VFbGVtZW50SWQocGxhY2UpO1xuXG4gICAgICBjb25zdCBzZWxlY3RlZFBsYWNlRWxlbWVudCA9IHRoaXMuX2dldFBsYWNlSHRtbEVsZW1lbnQoKTtcbiAgICAgIGlmIChzZWxlY3RlZFBsYWNlRWxlbWVudCkge1xuICAgICAgICBzZWxlY3RlZFBsYWNlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2tleWZvY3VzJywgJ2ZvY3VzJyk7XG5cbiAgICAgICAgLy9UcnkgdG8gc2Nyb2xsIGZvY3VzZWQgcGxhY2UgaW50byB0aGUgdmlld3BvcnRcbiAgICAgICAgY29uc3QgZGVsYXlTY3JvbGxJblZpZXdwb3J0ID0gc2V0VGltZW91dCgoKSA9PiB7XG4gICAgICAgICAgY29uc3QgcGxhY2VJZCA9IHRoaXMuZ2V0UGxhY2VFbGVtZW50SWQoXG4gICAgICAgICAgICB0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleCxcbiAgICAgICAgICAgIHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCxcbiAgICAgICAgICAgIHBsYWNlLm51bWJlcixcbiAgICAgICAgICApO1xuICAgICAgICAgIHRoaXMuX3Njcm9sbFBsYWNlSW50b05lYXJlc3RWaWV3cG9ydChwbGFjZUlkKTtcbiAgICAgICAgICBjbGVhclRpbWVvdXQoZGVsYXlTY3JvbGxJblZpZXdwb3J0KTtcbiAgICAgICAgfSwgMCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIHVuZm9jdXNQbGFjZUVsZW1lbnQoKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRQbGFjZUVsZW1lbnQgPSB0aGlzLl9nZXRQbGFjZUh0bWxFbGVtZW50KCk7XG4gICAgaWYgKHNlbGVjdGVkUGxhY2VFbGVtZW50KSB7XG4gICAgICBzZWxlY3RlZFBsYWNlRWxlbWVudC5zZXRBdHRyaWJ1dGUoJ2tleWZvY3VzJywgJ3VuZm9jdXMnKTtcbiAgICAgIHRoaXMuX3NldEN1cnJTZWxlY3RlZFBsYWNlRWxlbWVudElkKG51bGwpO1xuICAgICAgdGhpcy5jdXJyU2VsZWN0ZWRQbGFjZSA9IG51bGw7XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIGdldENhbGN1bGF0ZWREaW1lbnNpb24oXG4gICAgZWxlbWVudERpbWVuc2lvbjogRWxlbWVudERpbWVuc2lvbixcbiAgICBjb2FjaERpbWVuc2lvbj86IEVsZW1lbnREaW1lbnNpb24sXG4gICAgaXNPcmlnaW5IZWlnaHQ/OiBib29sZWFuLFxuICAgIGlzU3RyZXRjaEhlaWdodD86IGJvb2xlYW4sXG4gICk6IEVsZW1lbnREaW1lbnNpb24ge1xuICAgIGlmIChjb2FjaERpbWVuc2lvbiAmJiAhaXNPcmlnaW5IZWlnaHQpIHtcbiAgICAgIC8vIFNpbmNlIHRoZSBoZWlnaHQgb2YgdGhlIGNvYWNoIGhhcyBiZWVuIHZpc3VhbGx5IGV4cGFuZGVkIHRvIG1haW50YWluIGEgZGlzdGFuY2UgYmV0d2VlbiB0aGUgYm9yZGVyIG9mIHRoZSBjb2FjaCBhbmQgdGhlIHBsYWNlcyxcbiAgICAgIC8vIHNvbWUgZ3JhcGhpY3MgbXVzdCBhbHNvIGJlIGFkYXB0ZWQgdG8gdGhlIGhlaWdodCwgd2hpY2ggZW5kIHdpdGggdGhlIGJvcmRlcnMgb2YgdGhlIGNvYWNoXG4gICAgICBlbGVtZW50RGltZW5zaW9uLmggKz0gdGhpcy5jb2FjaEJvcmRlck9mZnNldCAqIDI7XG4gICAgfVxuXG4gICAgaWYgKGlzU3RyZXRjaEhlaWdodCkge1xuICAgICAgLy8gSW4gdGhlIGNhc2Ugb2YgZ3JhcGhpY3MgYXJlIGFzc2lnbmVkIGRpcmVjdGx5IGF0IHRoZSBib3JkZXIgb2YgdGhlIGNvYWNoLFxuICAgICAgLy8gdGhlc2UgZ3JhcGhpY3MgbXVzdCBiZSBleHBhbmRlZCBpbiBoZWlnaHQgYnkgYSBjb2FjaEJvcmRlck9mZnNldCBpbiBvcmRlciB0byByZWFjaCB0aGVpciBvcmlnaW5hbCB2aXN1YWwgcG9zaXRpb25cbiAgICAgIGVsZW1lbnREaW1lbnNpb24uaCArPSB0aGlzLmNvYWNoQm9yZGVyT2Zmc2V0O1xuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB3OiB0aGlzLmJhc2VHcmlkU2l6ZSAqIGVsZW1lbnREaW1lbnNpb24udyxcbiAgICAgIGg6IHRoaXMuYmFzZUdyaWRTaXplICogZWxlbWVudERpbWVuc2lvbi5oLFxuICAgIH07XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0Q2FsY3VsYXRlZFBvc2l0aW9uKFxuICAgIGVsZW1lbnRQb3NpdGlvbjogRWxlbWVudFBvc2l0aW9uLFxuICAgIGVsZW1lbnREaW1lbnNpb24/OiBFbGVtZW50RGltZW5zaW9uLFxuICAgIGNvYWNoRGltZW5zaW9uPzogRWxlbWVudERpbWVuc2lvbixcbiAgICBpc09yaWdpbkhlaWdodD86IGJvb2xlYW4sXG4gICk6IEVsZW1lbnRQb3NpdGlvbiB7XG4gICAgaWYgKGNvYWNoRGltZW5zaW9uICYmIGVsZW1lbnREaW1lbnNpb24pIHtcbiAgICAgIGNvbnN0IGVuZFBvc0hlaWdodCA9IGlzT3JpZ2luSGVpZ2h0XG4gICAgICAgID8gY29hY2hEaW1lbnNpb24uaFxuICAgICAgICA6IGNvYWNoRGltZW5zaW9uLmggKyB0aGlzLmNvYWNoQm9yZGVyT2Zmc2V0O1xuICAgICAgLy8gSWYgdGhlIG9yaWdpbmFsIGVsZW1lbnQgaXMgcG9zaXRpb25lZCBhdCB0aGUgdG9wIG9yIGJvdHRvbSBvZiB0aGUgY29hY2gsIHdlIG5lZWQgdG8gcmVjYWxjdWxhdGUgdGhlIFkgY29vcmRpbmF0ZSB3aXRoIHRoZSBhZGRpdGlvbmFsIGJvcmRlciBwYWRkaW5nXG4gICAgICBpZiAoZWxlbWVudFBvc2l0aW9uLnkgPT09IDApIHtcbiAgICAgICAgZWxlbWVudFBvc2l0aW9uLnkgLT0gdGhpcy5jb2FjaEJvcmRlck9mZnNldDtcbiAgICAgIH0gZWxzZSBpZiAoZWxlbWVudFBvc2l0aW9uLnkgKyBlbGVtZW50RGltZW5zaW9uLmggPT09IGVuZFBvc0hlaWdodCkge1xuICAgICAgICBlbGVtZW50UG9zaXRpb24ueSArPSB0aGlzLmNvYWNoQm9yZGVyT2Zmc2V0O1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiB7XG4gICAgICB4OiB0aGlzLmJhc2VHcmlkU2l6ZSAqIGVsZW1lbnRQb3NpdGlvbi54LFxuICAgICAgeTogdGhpcy5iYXNlR3JpZFNpemUgKiBlbGVtZW50UG9zaXRpb24ueSxcbiAgICAgIHo6IGVsZW1lbnRQb3NpdGlvbi56LFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogZGV0ZWN0cyBpZiBhIChncmFwaGljYWwpIGVsZW1lbnQgaXMgb24gdGhlIGJvcmRlciB3aXRoIGl0cyBwb3NpdGlvbiAodXBwZXIgb3IgbG93ZXIgYm9yZGVyKS5cbiAgICogQHBhcmFtIGJhc2VFbGVtZW50XG4gICAqIEBwYXJhbSBjb2FjaERpbWVuc2lvblxuICAgKiBAcHJvdGVjdGVkXG4gICAqL1xuICBwcm90ZWN0ZWQgaXNFbGVtZW50RGlyZWN0bHlPbkJvcmRlcihcbiAgICBiYXNlRWxlbWVudDogQmFzZUVsZW1lbnQsXG4gICAgY29hY2hEaW1lbnNpb246IEVsZW1lbnREaW1lbnNpb24sXG4gICk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBiYXNlRWxlbWVudC5wb3NpdGlvbi55ID09PSAwIHx8XG4gICAgICBiYXNlRWxlbWVudC5wb3NpdGlvbi55ICsgYmFzZUVsZW1lbnQuZGltZW5zaW9uLmggPT09IGNvYWNoRGltZW5zaW9uLmhcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIENvdW50cyBhbGwgYXZhaWxhYmxlIHNlYXRzIHRvZ2V0aGVyIGRlcGVuZGluZyBvbiB0aGUgc2VhdCB0eXBlXG4gICAqXG4gICAqIEBwYXJhbSBwbGFjZXNcbiAgICogQHJldHVybnMgQW4gT2JqZWN0IHdpdGggY291bnQgb2YgZnJlZSBzZWF0cyBhbmQgZnJlZSBiaWN5Y2xlIHBsYWNlc1xuICAgKi9cbiAgcHJvdGVjdGVkIGdldEF2YWlsYWJsZUZyZWVQbGFjZXNOdW1Gcm9tQ29hY2goXG4gICAgcGxhY2VzOiBQbGFjZVtdIHwgdW5kZWZpbmVkLFxuICApOiBDb2FjaE51bWJlck9mRnJlZVBsYWNlcyB7XG4gICAgY29uc3QgYWNjdW11bGF0b3I6IENvYWNoTnVtYmVyT2ZGcmVlUGxhY2VzID0geyBzZWF0czogMCwgYmljeWNsZXM6IDAgfTtcbiAgICBjb25zdCBmcmVlUGxhY2VzID0gcGxhY2VzPy5yZWR1Y2UoKGFjY3VtdWxhdG9yLCBjdXJyUGxhY2U6IFBsYWNlKSA9PiB7XG4gICAgICBpZiAoY3VyclBsYWNlLnN0YXRlICE9PSAnRlJFRScpIHtcbiAgICAgICAgcmV0dXJuIGFjY3VtdWxhdG9yO1xuICAgICAgfVxuICAgICAgLy8gQ291bnQgdXAgZGVwZW5kaW5nIG9uIHNlYXQgdHlwZVxuICAgICAgaWYgKGN1cnJQbGFjZS50eXBlID09PSAnU0VBVCcpIHtcbiAgICAgICAgYWNjdW11bGF0b3Iuc2VhdHMrKztcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGFjY3VtdWxhdG9yLmJpY3ljbGVzKys7XG4gICAgICB9XG4gICAgICByZXR1cm4gYWNjdW11bGF0b3I7XG4gICAgfSwgYWNjdW11bGF0b3IpO1xuICAgIHJldHVybiBmcmVlUGxhY2VzID8gZnJlZVBsYWNlcyA6IGFjY3VtdWxhdG9yO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0IHRoZSBlbmQgb2YgYSBzY3JvbGwgRXZlbnQgZnJvbSB0aGUgY29hY2ggc2Nyb2xsYWJsZSBhcmVhLFxuICAgKiB0aGUgcmVhY2hlZCBjb2FjaCBpcyBtYXJrZWQgYXMgc2VsZWN0ZWRcbiAgICovXG4gIHByaXZhdGUgX2hhbmRsZUNvYWNoQXJlYVNjcm9sbGVuZEV2ZW50KCk6IHZvaWQge1xuICAgIGNvbnN0IGZpbmRTY3JvbGxDb2FjaEluZGV4ID0gdGhpcy5pc0F1dG9TY3JvbGxpbmdcbiAgICAgID8gdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4XG4gICAgICA6IHRoaXMuX2dldENvYWNoSW5kZXhCeVNjcm9sbFRyaWdnZXJQb3NpdGlvbigpO1xuXG4gICAgLy8gVElNTy00MzcwNVxuICAgIC8vIElmIGEgcGxhY2Ugd2FzIHNlbGVjdGVkIGJ5IG1vdXNlIGNsaWNrIChwcmV2ZW50Q29hY2hTY3JvbGxCeVBsYWNlQ2xpY2spIGJlZm9yZSB0cmlnZ2VyaW5nIHRoaXMgc2Nyb2xsZW5kIG1ldGhvZCxcbiAgICAvLyB0aGVuIHRoaXMgc2Nyb2xsaW5nIHdhcyB0cmlnZ2VyZWQgYnkgdGhlIG1ldGhvZCBfc2Nyb2xsUGxhY2VJbnRvTmVhcmVzdFZpZXdwb3J0LCBhbmQgaXQgaXMgb25seSBhIHBsYWNlIGFkanVzdG1lbnQgc2Nyb2xsIChzY3JvbGxJbnRvVmlldyksXG4gICAgLy8gd2hlcmUgYSBsZXNzIHZpc2libGUgcGxhY2UgaGFzIGJlZW4gc2Nyb2xsZWQgaW50byB0aGUgdmlld3BvcnQuIEluIGNhc2Ugb2YgYSBwbGFjZSBhZGp1c3RtZW50IGJ5IGNsaWNrLCB3ZSBjYW4gcmV0dXJuIGhlcmUuXG4gICAgaWYgKHRoaXMucHJldmVudENvYWNoU2Nyb2xsQnlQbGFjZUNsaWNrKSB7XG4gICAgICAvLyBDaGVjayB3aGV0aGVyIHRoZSBlbmRzY3JvbGxpbmcgaXMganVzdCBhIHBsYWNlIGFkanVzdG1lbnQgc2Nyb2xsaW5nIChwbGFjZSBoYXMgMiBncmlkIHNpemUgdW5pdHMpXG4gICAgICBjb25zdCBpc0NvYWNoU2Nyb2xsaW5nID1cbiAgICAgICAgTWF0aC5hYnModGhpcy5fbGFzdFN0YXJ0U2Nyb2xsUG9zIC0gdGhpcy5jb2FjaFNjcm9sbEFyZWEuc2Nyb2xsTGVmdCkgPlxuICAgICAgICB0aGlzLmJhc2VHcmlkU2l6ZSAqIDI7XG4gICAgICBpZiAoaXNDb2FjaFNjcm9sbGluZykge1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ29hY2hJbmRleCA9IGZpbmRTY3JvbGxDb2FjaEluZGV4O1xuICAgICAgfVxuXG4gICAgICB0aGlzLnByZXZlbnRDb2FjaFNjcm9sbEJ5UGxhY2VDbGljayA9IGZhbHNlO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX2xhc3RTdGFydFNjcm9sbFBvcyA9IHRoaXMuY29hY2hTY3JvbGxBcmVhLnNjcm9sbExlZnQ7XG5cbiAgICAvLyBBZnRlciBjb2FjaCBzY3JvbGxlbmQgZXZlbnQgd2UgY2FuIHJlc2V0IHRoZSBob3ZlcmVkIGNvYWNoIGluZGV4XG4gICAgdGhpcy5ob3ZlcmVkQ29hY2hJbmRleCA9IC0xO1xuXG4gICAgLy8gSW4gY2FzZSB0aGUgdXNlciB1c2VzIHRoZSBzY3JvbGxiYXIgd2l0aG91dCBpbnRlcmFjdGluZyB3aXRoIHRoZSBzZWF0IHJlc2VydmF0aW9uLFxuICAgIC8vIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgaW5kZXggaXMgLTEsIGFuZCB3ZSBoYXZlIHRvIHNldCB0aGlzIHZhbHVlIHdpdGggZmluZFNjcm9sbENvYWNoSW5kZXguXG4gICAgaWYgKHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCA9PT0gLTEpIHtcbiAgICAgIHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCA9IGZpbmRTY3JvbGxDb2FjaEluZGV4O1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9pc1Njcm9sbGFibGVUb1NlbGVjdGVkQ29hY2goKSkge1xuICAgICAgdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4ID0gZmluZFNjcm9sbENvYWNoSW5kZXg7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCA9XG4gICAgICAgIGZpbmRTY3JvbGxDb2FjaEluZGV4IDwgdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4XG4gICAgICAgICAgPyB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXhcbiAgICAgICAgICA6IGZpbmRTY3JvbGxDb2FjaEluZGV4O1xuICAgIH1cblxuICAgIGlmICghdGhpcy5pc0F1dG9TY3JvbGxpbmcpIHtcbiAgICAgIC8vV2hlbiB1c2VyIGlzIHNjcm9sbGluZyB2aWEgc2Nyb2xsYmFyLCBpdCBhdXRvbWF0aWNhbGx5IHNjcm9sbHMgdG8gdGhlIGZvY3VzZWQgY29hY2ggaW4gdGhlIG1haW4gbmF2aWdhdGlvblxuICAgICAgdGhpcy5fc2Nyb2xsVG9TZWxlY3RlZE5hdmlnYXRpb25CdXR0b24oZmluZFNjcm9sbENvYWNoSW5kZXgpO1xuICAgIH1cbiAgICB0aGlzLnByZXZlbnRDb2FjaFNjcm9sbEJ5UGxhY2VDbGljayA9IGZhbHNlO1xuICAgIHRoaXMudXBkYXRlQ3VycmVudFNlbGVjdGVkQ29hY2goKTtcblxuICAgIGlmICghdGhpcy5oYXNOYXZpZ2F0aW9uKSB7XG4gICAgICB0aGlzLnByZXNlbGVjdFBsYWNlSW5Db2FjaCgpO1xuICAgICAgdGhpcy5pc0F1dG9TY3JvbGxpbmcgPSBmYWxzZTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUGVyZm9ybXMgYW4gYXV0b21hdGljIG1haW4gbmF2aWdhdGlvbiBzY3JvbGwgdG8gdGhlIHNwZWNpZmllZCBzZWxlY3RlZE5hdkNvYWNoSW5kZXguXG4gICAqIENhbGN1bGF0ZXMgdGhlIGNlbnRyYWwgc2Nyb2xsIG9mZnNldCBvZiB0aGUgbmF2IGNvYWNoIHRvIGJlIHNlbGVjdGVkLlxuICAgKiBAcGFyYW0gc2VsZWN0ZWROYXZDb2FjaEluZGV4XG4gICAqL1xuICBwcml2YXRlIF9zY3JvbGxUb1NlbGVjdGVkTmF2aWdhdGlvbkJ1dHRvbihzZWxlY3RlZE5hdkNvYWNoSW5kZXg6IG51bWJlcik6IHZvaWQge1xuICAgIC8vVGltZSBkZWxheSB0byBub3QgaW50ZXJmZXJlIHdpdGggb3RoZXIgZXhlY3V0aW5nIGNhbGxpbmcgc2Nyb2xsVG8gZnVuY3Rpb25zIChjb2FjaGVzIHNjcm9sbGluZylcbiAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIGlmICh0aGlzLmhhc05hdmlnYXRpb24gJiYgdGhpcy5uYXZpZ2F0aW9uU2Nyb2xsQXJlYSkge1xuICAgICAgICBjb25zdCBuYXZpZ2F0aW9uQXJlYUNlbnRlcmVkUG9zWCA9IHRoaXMuc2Nyb2xsTmF2aWdhdGlvbkFyZWFEaW0gLyAyO1xuICAgICAgICBjb25zdCBzY3JvbGxCdXR0b25PZmZzZXRYID0gc2VsZWN0ZWROYXZDb2FjaEluZGV4ICogdGhpcy5jb2FjaE5hdkJ1dHRvbkRpbTtcbiAgICAgICAgY29uc3Qgc2Nyb2xsT2Zmc2V0WCA9XG4gICAgICAgICAgc2Nyb2xsQnV0dG9uT2Zmc2V0WCAtIG5hdmlnYXRpb25BcmVhQ2VudGVyZWRQb3NYICsgdGhpcy5jb2FjaE5hdkJ1dHRvbkRpbTtcbiAgICAgICAgdGhpcy5uYXZpZ2F0aW9uU2Nyb2xsQXJlYS5zY3JvbGxUbyh7XG4gICAgICAgICAgdG9wOiB0aGlzLmFsaWduVmVydGljYWwgPyBzY3JvbGxPZmZzZXRYIDogMCxcbiAgICAgICAgICBsZWZ0OiB0aGlzLmFsaWduVmVydGljYWwgPyAwIDogc2Nyb2xsT2Zmc2V0WCxcbiAgICAgICAgICBiZWhhdmlvcjogJ3Ntb290aCcsXG4gICAgICAgIH0pO1xuICAgICAgfVxuICAgIH0sIDEwKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBuZXcgU2Nyb2xsRGlyZWN0aW9uIGJ5IHRoZSBuZXcgZ2l2ZW4gdGFyZ2V0IGNvYWNoIGluZGV4LlxuICAgKi9cbiAgcHJpdmF0ZSBfc2V0U2Nyb2xsRGlyZWN0aW9uQnlDb2FjaEluZGV4KCk6IHZvaWQge1xuICAgIHRoaXMuY3VyclNjcm9sbERpcmVjdGlvbiA9XG4gICAgICB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXggPiB0aGlzLnNlbGVjdGVkQ29hY2hJbmRleFxuICAgICAgICA/IFNjcm9sbERpcmVjdGlvbi5yaWdodFxuICAgICAgICA6IFNjcm9sbERpcmVjdGlvbi5sZWZ0O1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHVybnMgdGhlIHNjcm9sbCBzdGFydCBvciBlbmQgcG9zaXRpb24gWCBmcm9tIHRoZSBzZWxlY3RlZCBjb2FjaC5cbiAgICogSW4gY2FzZSB0aGUgdXNlciBpcyBjdXJyZW50bHkgbmF2aWdhdGluZyB0aHJvdWdoIHBsYWNlcyBieSBrZXlib2FyZCBhbmQgZ29lcyB0byBwcmV2aW91cyBjb2FjaCxcbiAgICogdGhlbiB3ZSByZXR1cm4gdGhlIGVuZCBwb3NpdGlvbiBvZiB0aGUgY29hY2ggdG8gZ2V0IHRoZSBjbG9zZXN0IHNjcm9sbCBwb3NpdGlvbiBvZiB0aGUgbmV4dCBmb2N1cyBwbGFjZS5cbiAgICogQHJldHVybnMgbnVtYmVyXG4gICAqL1xuICBwcml2YXRlIF9nZXRDb2FjaFNjcm9sbFBvc2l0aW9uWCgpOiBudW1iZXIge1xuICAgIGNvbnN0IGNvYWNoVHJpZ2dlclBvaW50ID0gdGhpcy50cmlnZ2VyQ29hY2hQb3NpdGlvbnNDb2xsZWN0aW9uW3RoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleF07XG4gICAgY29uc3QgaXNGb2N1c1BsYWNlRnJvbVByZXZpb3VzQ29hY2hQb3NpdGlvbiA9XG4gICAgICB0aGlzLmlzS2V5Ym9hcmROYXZpZ2F0aW9uICYmXG4gICAgICB0aGlzLmN1cnJTY3JvbGxEaXJlY3Rpb24gPT09IFNjcm9sbERpcmVjdGlvbi5sZWZ0ICYmXG4gICAgICBjb2FjaFRyaWdnZXJQb2ludC53aWR0aCA+IHRoaXMuc2Nyb2xsQ29hY2hlc0FyZWFXaWR0aDtcblxuICAgIHJldHVybiBpc0ZvY3VzUGxhY2VGcm9tUHJldmlvdXNDb2FjaFBvc2l0aW9uXG4gICAgICA/IGNvYWNoVHJpZ2dlclBvaW50LmVuZCAtIHRoaXMuc2Nyb2xsQ29hY2hlc0FyZWFXaWR0aFxuICAgICAgOiBjb2FjaFRyaWdnZXJQb2ludC5zdGFydDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBmb2N1cyBvbiB0aGUgSFRNTCB0YWJsZSAoZ3JpZCkgY2FwdGlvbiBlbGVtZW50IHNvIHRoYXQgdGhlIGhlYWRpbmcgaXMgcmVhZCBvdXQgd2hlbiB1c2luZyBhIFNjcmVlblJlYWRlci5cbiAgICovXG4gIHByaXZhdGUgX3NldEZvY3VzVG9TZWxlY3RlZENvYWNoR3JpZCgpOiB2b2lkIHtcbiAgICAvLyBXaGVuIHRoZSB1c2VyIHBlcmZvcm1zIGFuIGFjdGlvbiB0aGF0IGFmZmVjdHMgdGhlIGNvYWNoIG5hdmlnYXRpb24sIHRoZW4gdGhlIG5hdmlnYXRlZCB0YWJsZSBpcyBmb2N1c2FibGUuXG4gICAgaWYgKHRoaXMuaXNDb2FjaEdyaWRGb2N1c2FibGUgJiYgdGhpcy5oYXNTZWF0UmVzZXJ2YXRpb25OYXRpdmVGb2N1cykge1xuICAgICAgdGhpcy5pc0NvYWNoR3JpZEZvY3VzYWJsZSA9IGZhbHNlO1xuICAgICAgY29uc3QgY29hY2hUYWJsZUNhcHRpb25FbGVtZW50ID0gdGhpcy5zaGFkb3dSb290Py5xdWVyeVNlbGVjdG9yKFxuICAgICAgICAnI3NiYi1zci1jb2FjaC1jYXB0aW9uLScgKyB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXgsXG4gICAgICApIGFzIEhUTUxUYWJsZUNhcHRpb25FbGVtZW50O1xuICAgICAgaWYgKGNvYWNoVGFibGVDYXB0aW9uRWxlbWVudCkge1xuICAgICAgICBjb2FjaFRhYmxlQ2FwdGlvbkVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB3aGV0aGVyIHRoZSBjdXJyZW50IHNjcm9sbGVkIHBvc2l0aW9uIGNhbiBiZSB1c2VkIHRvIHNjcm9sbCB0byB0aGUgc2VsZWN0ZWQgd2Fnb25cbiAgICogQHJldHVybnMgYm9vbGVhblxuICAgKi9cbiAgcHJpdmF0ZSBfaXNTY3JvbGxhYmxlVG9TZWxlY3RlZENvYWNoKCk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IGN1cnJTY3JvbGxQb3NYID0gdGhpcy5hbGlnblZlcnRpY2FsXG4gICAgICA/IHRoaXMuY29hY2hTY3JvbGxBcmVhLnNjcm9sbFRvcFxuICAgICAgOiB0aGlzLmNvYWNoU2Nyb2xsQXJlYS5zY3JvbGxMZWZ0O1xuICAgIGNvbnN0IGNvYWNoU2Nyb2xsV2luZG93V2lkdGggPSB0aGlzLmFsaWduVmVydGljYWxcbiAgICAgID8gdGhpcy5jb2FjaFNjcm9sbEFyZWEuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCkuaGVpZ2h0XG4gICAgICA6IHRoaXMuY29hY2hTY3JvbGxBcmVhLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLndpZHRoO1xuICAgIGNvbnN0IG1heFNjcm9sbFdpZHRoQXJlYSA9IHRoaXMubWF4Q2FsY0NvYWNoZXNXaWR0aCAtIGNvYWNoU2Nyb2xsV2luZG93V2lkdGg7XG4gICAgY29uc3QgY3VyckNvYWNoVHJpZ2dlciA9IHRoaXMudHJpZ2dlckNvYWNoUG9zaXRpb25zQ29sbGVjdGlvblt0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXhdO1xuICAgIGNvbnN0IGlzU2Nyb2xsUG9zU2FtZVRvQ3VyckNvYWNoUG9zID1cbiAgICAgIGN1cnJTY3JvbGxQb3NYID09PSB0aGlzLnRyaWdnZXJDb2FjaFBvc2l0aW9uc0NvbGxlY3Rpb25bdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4XS5zdGFydDtcblxuICAgIHJldHVybiAoXG4gICAgICAoY3VyclNjcm9sbFBvc1ggPCBtYXhTY3JvbGxXaWR0aEFyZWEgfHwgY3VyclNjcm9sbFBvc1ggPiBjdXJyQ29hY2hUcmlnZ2VyLnN0YXJ0KSAmJlxuICAgICAgIWlzU2Nyb2xsUG9zU2FtZVRvQ3VyckNvYWNoUG9zXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBjb2FjaCBpbmRleCB3aGljaCBpcyBjdXJyZW50bHkgdmlzaWJsZSBpbiB0aGUgc2Nyb2xsIGFyZWFcbiAgICogQHJldHVybnMgbnVtYmVyXG4gICAqL1xuICBwcml2YXRlIF9nZXRDb2FjaEluZGV4QnlTY3JvbGxUcmlnZ2VyUG9zaXRpb24oKTogbnVtYmVyIHtcbiAgICBjb25zdCBzY3JvbGxQb3MgPSB0aGlzLmFsaWduVmVydGljYWxcbiAgICAgID8gdGhpcy5jb2FjaFNjcm9sbEFyZWEuc2Nyb2xsVG9wXG4gICAgICA6IHRoaXMuY29hY2hTY3JvbGxBcmVhLnNjcm9sbExlZnQ7XG4gICAgY29uc3Qgc2Nyb2xsT2Zmc2V0WCA9IHNjcm9sbFBvcyArIHRoaXMuc2Nyb2xsQ29hY2hlc0FyZWFXaWR0aCAvIDI7XG4gICAgcmV0dXJuIHRoaXMudHJpZ2dlckNvYWNoUG9zaXRpb25zQ29sbGVjdGlvbi5maW5kSW5kZXgoXG4gICAgICAoY29hY2hUcmlnZ2VyKSA9PiBzY3JvbGxPZmZzZXRYID49IGNvYWNoVHJpZ2dlci5zdGFydCAmJiBzY3JvbGxPZmZzZXRYIDw9IGNvYWNoVHJpZ2dlci5lbmQsXG4gICAgKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXQgdGhlIGZpcnN0IHBsYWNlIG9mIGN1cnJlbnQgc2VsZWN0ZWQgY29hY2ggYnkgdGFibGUgY2VsbCBjb29yZGluYXRlIDAtMCBpZC5cbiAgICogQHJldHVybnMgUGxhY2Ugb3IgbnVsbFxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0Rmlyc3RQbGFjZUluU2VsZWN0ZWRDb2FjaCgpOiBQbGFjZSB8IG51bGwge1xuICAgIGxldCBmaXJzdFBsYWNlOiBQbGFjZSB8IG51bGwgPSBudWxsO1xuICAgIGNvbnN0IGNvYWNoID1cbiAgICAgIHRoaXMuc2VhdFJlc2VydmF0aW9uc1t0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleF0uY29hY2hJdGVtc1t0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXhdO1xuICAgIGNvbnN0IGZpcnN0Q2VsbElkID1cbiAgICAgICdjZWxsLScgKyB0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleCArICctJyArIHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCArICctMC0wJztcbiAgICBjb25zdCBwbGFjZU51bWJlciA9XG4gICAgICB0aGlzLnNoYWRvd1Jvb3RcbiAgICAgICAgPy5xdWVyeVNlbGVjdG9yPEhUTUxUYWJsZUNlbGxFbGVtZW50PignIycgKyBmaXJzdENlbGxJZClcbiAgICAgICAgPy5xdWVyeVNlbGVjdG9yPFNiYlNlYXRSZXNlcnZhdGlvblBsYWNlQ29udHJvbEVsZW1lbnQ+KCdzYmItc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sJylcbiAgICAgICAgPy5nZXRBdHRyaWJ1dGUoJ3RleHQnKSB8fCBudWxsO1xuXG4gICAgaWYgKGNvYWNoICYmIHBsYWNlTnVtYmVyKSB7XG4gICAgICBmaXJzdFBsYWNlID0gY29hY2gucGxhY2VzPy5maW5kKChwbGFjZSkgPT4gcGxhY2UubnVtYmVyID09PSBwbGFjZU51bWJlcikgfHwgbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGZpcnN0UGxhY2U7XG4gIH1cblxuICBwcml2YXRlIF9nZXRTd2l0Y2hlZENvYWNoRGVja0luZGV4QnlLZXlOYXZpZ2F0aW9uKFxuICAgIHByZXNzZWRLZXk6IHN0cmluZyxcbiAgICBjb2FjaDogQ29hY2hJdGVtLFxuICApOiBudW1iZXIgfCBudWxsIHtcbiAgICBpZiAoXG4gICAgICAhdGhpcy5jdXJyU2VsZWN0ZWRQbGFjZSB8fFxuICAgICAgcHJlc3NlZEtleSA9PT0gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuQXJyb3dSaWdodCB8fFxuICAgICAgcHJlc3NlZEtleSA9PT0gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuQXJyb3dMZWZ0XG4gICAgKVxuICAgICAgcmV0dXJuIG51bGw7XG5cbiAgICAvL0NIRUNLIERFQ0sgU1dJVENIIERPV05cbiAgICBpZiAoXG4gICAgICBwcmVzc2VkS2V5ID09PSB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5BcnJvd0Rvd24gJiZcbiAgICAgIHRoaXMuY3VyclNlbGVjdGVkUGxhY2UucG9zaXRpb24ueSArIDIgPT09IGNvYWNoLmRpbWVuc2lvbi5oICYmXG4gICAgICAhIXRoaXMuc2VhdFJlc2VydmF0aW9uc1t0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleCArIDFdXG4gICAgKSB7XG4gICAgICByZXR1cm4gdGhpcy5jdXJyU2VsZWN0ZWREZWNrSW5kZXggKyAxO1xuICAgIH1cbiAgICAvL0NIRUNLIERFQ0sgU1dJVENIIFVQXG4gICAgZWxzZSBpZiAoXG4gICAgICBwcmVzc2VkS2V5ID09PSB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5BcnJvd1VwICYmXG4gICAgICB0aGlzLmN1cnJTZWxlY3RlZFBsYWNlLnBvc2l0aW9uLnkgPT09IDAgJiZcbiAgICAgICEhdGhpcy5zZWF0UmVzZXJ2YXRpb25zW3RoaXMuY3VyclNlbGVjdGVkRGVja0luZGV4IC0gMV1cbiAgICApIHtcbiAgICAgIHJldHVybiB0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleCAtIDE7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG4gIC8qKlxuICAgKiBUbyBnZXQgdGhlIGNvcnJlY3QgY2xvc2VzdCBwbGFjZSBvZiBjdXJyZW50IHByZXNzZWQga2V5IGFuZCB0aGUgY3VycmVudCBzZWxlY3RlZCBwbGFjZSxcbiAgICogd2UgaGF2ZSB0byBpbnZlc3RpZ2F0ZSB0aGUgY29vcmRpbmF0ZXMgb2YgZWFjaCBwbGFjZSB0byBmaW5kIHRoZSBjbG9zZXN0IHBsYWNlIG9mIHRoZSBjdXJyU2VsZWN0ZWRQbGFjZUVsZW1lbnRJZC5cbiAgICogQHBhcmFtIHByZXNzZWRLZXlcbiAgICogQHJldHVybnMgUGxhY2Ugb3IgbnVsbFxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0Q2xvc2VzdFBsYWNlQnlLZXlEaXJlY3Rpb24ocHJlc3NlZEtleT86IHN0cmluZyk6IFBsYWNlIHwgbnVsbCB7XG4gICAgY29uc3QgY29hY2ggPVxuICAgICAgdGhpcy5zZWF0UmVzZXJ2YXRpb25zW3RoaXMuY3VyclNlbGVjdGVkRGVja0luZGV4XS5jb2FjaEl0ZW1zW3RoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleF07XG4gICAgbGV0IGNsb3Nlc3RQbGFjZSA9IG51bGw7XG4gICAgbGV0IGNvYWNoUGxhY2VzID0gY29hY2gucGxhY2VzO1xuICAgIGxldCBzd2l0Y2hlZENvYWNoRGVja0luZGV4ID0gbnVsbDtcblxuICAgIGlmIChjb2FjaFBsYWNlcykge1xuICAgICAgLy8gSWYgbm8gcGxhY2Ugc2V0LCB0aGVuIHdlIHVzZSBpbml0aWFsIHRoZSBsZWZ0LXRvcCBwbGFjZSBvbiB0aGUgY29hY2hcbiAgICAgIGlmICghdGhpcy5jdXJyU2VsZWN0ZWRQbGFjZUVsZW1lbnRJZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5fZ2V0Rmlyc3RQbGFjZUluU2VsZWN0ZWRDb2FjaCgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKHRoaXMuY3VyclNlbGVjdGVkUGxhY2UpIHtcbiAgICAgICAgICBjb25zdCBjdXJyU2VsZWN0ZWRQbGFjZVBvc2l0aW9uID0geyAuLi50aGlzLmN1cnJTZWxlY3RlZFBsYWNlLnBvc2l0aW9uIH07XG5cbiAgICAgICAgICBpZiAocHJlc3NlZEtleSkge1xuICAgICAgICAgICAgLy8gQ2hlY2sgd2hldGhlciB0aGUga2V5Ym9hcmQgbmF2aWdhdGlvbiBpcyB1c2VkIHRvIHN3aXRjaCB0byBhbm90aGVyIGNvYWNoIGRlY2sgKFVwIC0+IERvd24gfCBEb3duIC0+IFVwKS5cbiAgICAgICAgICAgIC8vIEluIHRoaXMgY2FzZSwgd2UgdGFrZSB0aGUgY29hY2ggcGxhY2VzIHdlIGhhdmUgdG8gY2hlY2tlZCBmcm9tIHRoZSB0YXJnZXQgZGVjayBub3cuXG4gICAgICAgICAgICBzd2l0Y2hlZENvYWNoRGVja0luZGV4ID0gdGhpcy5fZ2V0U3dpdGNoZWRDb2FjaERlY2tJbmRleEJ5S2V5TmF2aWdhdGlvbihcbiAgICAgICAgICAgICAgcHJlc3NlZEtleSxcbiAgICAgICAgICAgICAgY29hY2gsXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgaWYgKHN3aXRjaGVkQ29hY2hEZWNrSW5kZXggIT09IG51bGwpIHtcbiAgICAgICAgICAgICAgLy8gQXNzaWduIGNoZWNrIHBsYWNlcyBmcm9tIHRoZSB0YXJnZXQgc3dpdGNoIGRlY2tcbiAgICAgICAgICAgICAgY29hY2hQbGFjZXMgPVxuICAgICAgICAgICAgICAgIHRoaXMuc2VhdFJlc2VydmF0aW9uc1tzd2l0Y2hlZENvYWNoRGVja0luZGV4XS5jb2FjaEl0ZW1zW1xuICAgICAgICAgICAgICAgICAgdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4XG4gICAgICAgICAgICAgICAgXS5wbGFjZXMgfHwgW107XG4gICAgICAgICAgICAgIC8vIFdlIGhhdmUgdG8gdXBkYXRlIHkgY29vcmRpbmF0ZVxuICAgICAgICAgICAgICBjdXJyU2VsZWN0ZWRQbGFjZVBvc2l0aW9uLnkgPVxuICAgICAgICAgICAgICAgIHN3aXRjaGVkQ29hY2hEZWNrSW5kZXggPCB0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleCA/IGNvYWNoLmRpbWVuc2lvbi5oIDogLTE7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgZm9yIChjb25zdCBwbGFjZSBvZiBjb2FjaFBsYWNlcykge1xuICAgICAgICAgICAgLy8gSWYgbm8ga2V5IHByZXNzZWQsIHRoZW4gd2UgdHJ5IHRvIGZpbmQgdGhlIHBsYWNlIG9mIHRoZSBjdXJyZW50IGN1cnJTY3JvbGxEaXJlY3Rpb25cbiAgICAgICAgICAgIGlmICghcHJlc3NlZEtleSkge1xuICAgICAgICAgICAgICAvLyBGaW5kIHBsYWNlIGZyb20gdGhlIGxlZnQgc2lkZSBvZiBjb2FjaCBieSB5IGNvb3JkaW5hdGUuIEN1cnJlbnQgY3VyclNjcm9sbERpcmVjdGlvbiBpcyBSSUdIVFxuICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyU2Nyb2xsRGlyZWN0aW9uID09PSBTY3JvbGxEaXJlY3Rpb24ucmlnaHQgJiZcbiAgICAgICAgICAgICAgICBwbGFjZS5wb3NpdGlvbi55ID09PSBjdXJyU2VsZWN0ZWRQbGFjZVBvc2l0aW9uLnkgJiZcbiAgICAgICAgICAgICAgICAoIWNsb3Nlc3RQbGFjZSB8fCBwbGFjZS5wb3NpdGlvbi54IDwgY2xvc2VzdFBsYWNlLnBvc2l0aW9uLngpXG4gICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGNsb3Nlc3RQbGFjZSA9IHBsYWNlO1xuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIC8vRmluZCBwbGFjZSBmcm9tIHRoZSByaWdodCBzaWRlIG9mIGNvYWNoIGJ5IHkgY29vcmRpbmF0ZS4gQ3VycmVudCBjdXJyU2Nyb2xsRGlyZWN0aW9uIGlzIExFRlRcbiAgICAgICAgICAgICAgZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgdGhpcy5jdXJyU2Nyb2xsRGlyZWN0aW9uID09PSBTY3JvbGxEaXJlY3Rpb24ubGVmdCAmJlxuICAgICAgICAgICAgICAgIHBsYWNlLnBvc2l0aW9uLnkgPT09IGN1cnJTZWxlY3RlZFBsYWNlUG9zaXRpb24ueSAmJlxuICAgICAgICAgICAgICAgICghY2xvc2VzdFBsYWNlIHx8IHBsYWNlLnBvc2l0aW9uLnggPiBjbG9zZXN0UGxhY2UucG9zaXRpb24ueClcbiAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgY2xvc2VzdFBsYWNlID0gcGxhY2U7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgIGlmIChwbGFjZS5udW1iZXIgIT09IHRoaXMuY3VyclNlbGVjdGVkUGxhY2U/Lm51bWJlcikge1xuICAgICAgICAgICAgICAgIC8vS2V5IFtSaWdodF0gbmF2aWdhdGlvbiwgd2UgY2hlY2sgdGhlIHBsYWNlIGNvb3JkaW5hdGVzIG9mIHRoZSB4LWF4aXMgdG8gZ2V0IHRoZSBzbWFsbGVzdCBsYXJnZXIgeCBwbGFjZSBjb29yZGluYXRlIG9mIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcGxhY2VcbiAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICBwcmVzc2VkS2V5ID09PSB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5BcnJvd1JpZ2h0ICYmXG4gICAgICAgICAgICAgICAgICAocGxhY2UucG9zaXRpb24ueSA9PT0gY3VyclNlbGVjdGVkUGxhY2VQb3NpdGlvbi55IHx8XG4gICAgICAgICAgICAgICAgICAgIHBsYWNlLnBvc2l0aW9uLnkgPT09IGN1cnJTZWxlY3RlZFBsYWNlUG9zaXRpb24ueSAtIDEpICYmXG4gICAgICAgICAgICAgICAgICBwbGFjZS5wb3NpdGlvbi54ID4gY3VyclNlbGVjdGVkUGxhY2VQb3NpdGlvbi54ICYmXG4gICAgICAgICAgICAgICAgICAoIWNsb3Nlc3RQbGFjZSB8fCBwbGFjZS5wb3NpdGlvbi54IDwgY2xvc2VzdFBsYWNlLnBvc2l0aW9uLngpXG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICBjbG9zZXN0UGxhY2UgPSBwbGFjZTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgLy9LZXkgW0Rvd25dIG5hdmlnYXRpb24sIHdlIGNoZWNrIHRoZSBwbGFjZSBjb29yZGluYXRlcyBvZiB0aGUgeS1heGlzIHRvIGdldCB0aGUgc21hbGxlc3QgbGFyZ2VyIHkgcGxhY2UgY29vcmRpbmF0ZSBvZiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHBsYWNlXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgICBwcmVzc2VkS2V5ID09PSB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5BcnJvd0Rvd24gJiZcbiAgICAgICAgICAgICAgICAgIChwbGFjZS5wb3NpdGlvbi54ID09PSBjdXJyU2VsZWN0ZWRQbGFjZVBvc2l0aW9uLnggfHxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2UucG9zaXRpb24ueCA9PT0gY3VyclNlbGVjdGVkUGxhY2VQb3NpdGlvbi54ICsgMSkgJiZcbiAgICAgICAgICAgICAgICAgIHBsYWNlLnBvc2l0aW9uLnkgPiBjdXJyU2VsZWN0ZWRQbGFjZVBvc2l0aW9uLnkgJiZcbiAgICAgICAgICAgICAgICAgICghY2xvc2VzdFBsYWNlIHx8IHBsYWNlLnBvc2l0aW9uLnkgPCBjbG9zZXN0UGxhY2UucG9zaXRpb24ueSlcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIGNsb3Nlc3RQbGFjZSA9IHBsYWNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvL0tleSBbTGVmdF0gbmF2aWdhdGlvbiwgd2UgY2hlY2sgdGhlIHBsYWNlIGNvb3JkaW5hdGVzIG9mIHRoZSB4LWF4aXMgdG8gZ2V0IHRoZSBncmVhdGVzdCBzbWFsbGVyIHggcGxhY2UgY29vcmRpbmF0ZSBvZiB0aGUgY3VycmVudGx5IHNlbGVjdGVkIHBsYWNlXG4gICAgICAgICAgICAgICAgZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgICBwcmVzc2VkS2V5ID09PSB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5BcnJvd0xlZnQgJiZcbiAgICAgICAgICAgICAgICAgIChwbGFjZS5wb3NpdGlvbi55ID09PSBjdXJyU2VsZWN0ZWRQbGFjZVBvc2l0aW9uLnkgfHxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2UucG9zaXRpb24ueSA9PT0gY3VyclNlbGVjdGVkUGxhY2VQb3NpdGlvbi55ICsgMSkgJiZcbiAgICAgICAgICAgICAgICAgIHBsYWNlLnBvc2l0aW9uLnggPCBjdXJyU2VsZWN0ZWRQbGFjZVBvc2l0aW9uLnggJiZcbiAgICAgICAgICAgICAgICAgICghY2xvc2VzdFBsYWNlIHx8IHBsYWNlLnBvc2l0aW9uLnggPiBjbG9zZXN0UGxhY2UucG9zaXRpb24ueClcbiAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgIGNsb3Nlc3RQbGFjZSA9IHBsYWNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvL0tleSBbVXBdIG5hdmlnYXRpb24sIHdlIGNoZWNrIHRoZSBwbGFjZSBjb29yZGluYXRlcyBvZiB0aGUgeS1heGlzIHRvIGdldCB0aGUgZ3JlYXRlc3Qgc21hbGxlciB5IHBsYWNlIGNvb3JkaW5hdGUgb2YgdGhlIGN1cnJlbnRseSBzZWxlY3RlZCBwbGFjZVxuICAgICAgICAgICAgICAgIGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgICAgcHJlc3NlZEtleSA9PT0gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuQXJyb3dVcCAmJlxuICAgICAgICAgICAgICAgICAgKHBsYWNlLnBvc2l0aW9uLnggPT09IGN1cnJTZWxlY3RlZFBsYWNlUG9zaXRpb24ueCB8fFxuICAgICAgICAgICAgICAgICAgICBwbGFjZS5wb3NpdGlvbi54ID09PSBjdXJyU2VsZWN0ZWRQbGFjZVBvc2l0aW9uLnggLSAxKSAmJlxuICAgICAgICAgICAgICAgICAgcGxhY2UucG9zaXRpb24ueSA8IGN1cnJTZWxlY3RlZFBsYWNlUG9zaXRpb24ueSAmJlxuICAgICAgICAgICAgICAgICAgKCFjbG9zZXN0UGxhY2UgfHwgcGxhY2UucG9zaXRpb24ueSA+IGNsb3Nlc3RQbGFjZS5wb3NpdGlvbi55KVxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgY2xvc2VzdFBsYWNlID0gcGxhY2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgLy8gSWYgYSBwbGFjZSBoYXMgYmVlbiBmb3VuZCBpbiB0aGUgY2hhbmdpbmcgc3dpdGNoIGNvYWNoLFxuICAgICAgICAgIC8vIHdlIGNhbiB1cGRhdGUgdGhlIGN1cnJTZWxlY3RlZERlY2tJbmRleFxuICAgICAgICAgIGlmIChzd2l0Y2hlZENvYWNoRGVja0luZGV4ICE9PSBudWxsICYmIGNsb3Nlc3RQbGFjZSkge1xuICAgICAgICAgICAgdGhpcy5jdXJyU2VsZWN0ZWREZWNrSW5kZXggPSBzd2l0Y2hlZENvYWNoRGVja0luZGV4O1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gY2xvc2VzdFBsYWNlO1xuICB9XG5cbiAgLy8gSGFuZGxpbmcgZm9yIFRhYiBuYXZpZ2F0aW9uIGlmIGEgcGxhY2UgaXMgc2VsZWN0ZWQgaW5zaWRlIHRoZSBjb2FjaC5cbiAgLy8gVGhpcyBjb250cm9scyB0aGUgZm9jdXNlZCBjb2FjaCBmcm9tIHRoZSBjdXJyZW50IHNlbGVjdGVkIGNvYWNoLlxuICBwcml2YXRlIF9uYXZpZ2F0ZUNvYWNoTmF2aWdhdGlvbkJ5S2V5Ym9hcmQodGFiRGlyZWN0aW9uOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCBjdXJyRm9jdXNJbmRleCA9XG4gICAgICB0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID09PSAtMVxuICAgICAgICA/IHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCA9PT0gLTFcbiAgICAgICAgICA/IDBcbiAgICAgICAgICA6IHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleFxuICAgICAgICA6IHRoaXMuZm9jdXNlZENvYWNoSW5kZXg7XG5cbiAgICAvLyBDaGVjayBuZXh0IG9yIHByZXYgdGFiIGlzIHByZXNzZWQsIHRoZW4gd2UgbmVlZCB0byBmaW5kIHRoZSBuZXh0IGF2YWlsYWJsZSBjb2FjaCBpbmRleCB0aGF0IHNob3VsZCByZWNlaXZlIHRoZSBmb2N1c1xuICAgIGNvbnN0IG5ld0ZvY3VzYWJsZUluZGV4OiBudW1iZXIgPVxuICAgICAgdGFiRGlyZWN0aW9uID09PSAnTkVYVF9UQUInXG4gICAgICAgID8gdGhpcy5nZXROZXh0QXZhaWxhYmxlQ29hY2hJbmRleChjdXJyRm9jdXNJbmRleClcbiAgICAgICAgOiB0aGlzLmdldFByZXZBdmFpbGFibGVDb2FjaEluZGV4KGN1cnJGb2N1c0luZGV4KTtcblxuICAgIGlmICh0aGlzLmhhc05hdmlnYXRpb24pIHtcbiAgICAgIGNvbnN0IHNlbGVjdGVkUGxhY2VFbGVtZW50ID0gdGhpcy5fZ2V0UGxhY2VIdG1sRWxlbWVudCgpO1xuICAgICAgY29uc3QgcGxhY2VJbkNvYWNoSGFzRm9jdXMgPSBzZWxlY3RlZFBsYWNlRWxlbWVudFxuICAgICAgICA/IHNlbGVjdGVkUGxhY2VFbGVtZW50LmdldEF0dHJpYnV0ZSgna2V5Zm9jdXMnKSA9PT0gJ2ZvY3VzJ1xuICAgICAgICA6IGZhbHNlO1xuXG4gICAgICAvLyBJZiB3ZSB0YWIgYmFjayAoUFJFVl9UQUIpIGFuZCB0aGUgZm9jdXMgaXMgY3VycmVudGx5IG9uIHBsYWNlLFxuICAgICAgLy8gd2UgcmVtb3ZlIHRoZSBzZWxlY3RlZCBzdGF0ZSBmcm9tIHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgbmF2aWdhdGlvbiBjb2FjaCBhbmQgb25seSBzZXQgdGhlIGZvY3VzIHN0YXR1cyB0byBpdFxuICAgICAgaWYgKHRhYkRpcmVjdGlvbiA9PT0gJ1BSRVZfVEFCJyAmJiB0aGlzLnNlbGVjdGVkQ29hY2hJbmRleCA9PT0gY3VyckZvY3VzSW5kZXgpIHtcbiAgICAgICAgLy8gSWYgd2UgVEFCIGJhY2sgYW5kIGhhdmUgYSBzZWxlY3RlZCBwbGFjZXMgaW5zaWRlIHRoZSBjdXJyZW50IGNvYWNoLCB0aGVuIHdlIG1vdmUgb3V0IGZyb20gdGhlIHNlYXRtYXAgYW5kIHNldCB0aGUgZm9jdXMgdG8gdGhlIGN1cnJlbnQgc2VsZWN0ZWQgY29hY2hcbiAgICAgICAgaWYgKHBsYWNlSW5Db2FjaEhhc0ZvY3VzIHx8IHRoaXMuY3VyclNlbGVjdGVkUGxhY2UgIT09IG51bGwpIHtcbiAgICAgICAgICB0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID0gY3VyckZvY3VzSW5kZXg7XG4gICAgICAgICAgdGhpcy51bmZvY3VzUGxhY2VFbGVtZW50KCk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICAgIC8vIElmIHdlIHRhYiBiYWNrIGFuZCB0aGUgY3VycmVudCBzZWxlY3RlZCBuYXYgY29hY2ggaXMgdGhlIGZpcnN0IGVsZW1lbnQsIHNvIHdlIGhhdmUgdG8gZm9jdXMgKGp1bXApIGRpcmVjdGx5IHRvIHRoZSBsZWZ0IG5hdiBkaXJlY3Rpb24gYnV0dG9uXG4gICAgICAgIGVsc2UgaWYgKGN1cnJGb2N1c0luZGV4ID09IDApIHtcbiAgICAgICAgICB0aGlzLnVuZm9jdXNQbGFjZUVsZW1lbnQoKTtcbiAgICAgICAgICB0aGlzLmN1cnJTZWxlY3RlZFBsYWNlID0gbnVsbDtcbiAgICAgICAgICB0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID0gLTE7XG4gICAgICAgICAgY29uc3QgYnRuTGVmdERpcmVjdGlvbiA9IHRoaXMuc2hhZG93Um9vdD8uZ2V0RWxlbWVudEJ5SWQoXG4gICAgICAgICAgICAnc2JiLXNyLW5hdmlnYXRpb25fX3dyYXBwZXItYnV0dG9uLWRpcmVjdGlvbi0tbGVmdCcsXG4gICAgICAgICAgKSBhcyBIVE1MRWxlbWVudDtcbiAgICAgICAgICBidG5MZWZ0RGlyZWN0aW9uLmZvY3VzKCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdGhpcy5mb2N1c2VkQ29hY2hJbmRleCA9IG5ld0ZvY3VzYWJsZUluZGV4O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICAvLyBPbmx5IHNldHMgdGhlIGZvY3VzIG9uIHRoZSBuZXcgbmF2aWdhdGlvbiBjb2FjaFxuICAgICAgZWxzZSBpZiAobmV3Rm9jdXNhYmxlSW5kZXggIT09IHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCkge1xuICAgICAgICB0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID0gbmV3Rm9jdXNhYmxlSW5kZXg7XG4gICAgICB9XG4gICAgICAvLyBJZiB3ZSB0YWIgbmV4dCBhbmQgdGhlIGN1cnJlbnQgc2VsZWN0ZWQgbmF2IGNvYWNoIGlzIHRoZSBsYXN0IGVsZW1lbnQsIHNvIHdlIGhhdmUgdG8gZm9jdXMgKGp1bXApIGRpcmVjdGx5IHRvIHRoZSByaWdodCBuYXYgZGlyZWN0aW9uIGJ1dHRvblxuICAgICAgZWxzZSBpZiAodGFiRGlyZWN0aW9uID09PSAnTkVYVF9UQUInICYmIG5ld0ZvY3VzYWJsZUluZGV4ID09PSB0aGlzLmNvYWNoTmF2RGF0YS5sZW5ndGggLSAxKSB7XG4gICAgICAgIHRoaXMudW5mb2N1c1BsYWNlRWxlbWVudCgpO1xuICAgICAgICB0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID0gLTE7XG4gICAgICAgIGNvbnN0IGJ0blJpZ2h0RGlyZWN0aW9uID0gdGhpcy5zaGFkb3dSb290Py5nZXRFbGVtZW50QnlJZChcbiAgICAgICAgICAnc2JiLXNyLW5hdmlnYXRpb25fX3dyYXBwZXItYnV0dG9uLWRpcmVjdGlvbi0tcmlnaHQnLFxuICAgICAgICApIGFzIEhUTUxFbGVtZW50O1xuICAgICAgICBidG5SaWdodERpcmVjdGlvbi5mb2N1cygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5mb2N1c2VkQ29hY2hJbmRleCA9IC0xO1xuICAgICAgICB0aGlzLnNlbGVjdGVkQ29hY2hJbmRleCA9IG5ld0ZvY3VzYWJsZUluZGV4O1xuICAgICAgICAvLyBJZiBhbnkgcGxhY2Ugd2FzIGZvY3VzZWQgaW4gY29hY2gsIHNvIHdlIHNldCBmb2N1c2VkIGFnYWluXG4gICAgICAgIGlmIChwbGFjZUluQ29hY2hIYXNGb2N1cykge1xuICAgICAgICAgIHRoaXMuZm9jdXNQbGFjZUVsZW1lbnQodGhpcy5jdXJyU2VsZWN0ZWRQbGFjZSk7XG4gICAgICAgIH1cbiAgICAgICAgLy8gSWYgbm8gcGxhY2Ugd2FzIHNlbGVjdGVkLCB0aGVuIHdlIHNlbGVjdCB0aGUgY29hY2ggZ3JpZFxuICAgICAgICBlbHNlIHtcbiAgICAgICAgICB0aGlzLmlzQ29hY2hHcmlkRm9jdXNhYmxlID0gdHJ1ZTtcbiAgICAgICAgICB0aGlzLl9zZXRGb2N1c1RvU2VsZWN0ZWRDb2FjaEdyaWQoKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICAvLyBCeSBUYWIgTmF2aWdhdGlvbiwgcGVyZm9ybSBhdXRvbWF0aWMgc2Nyb2xsaW5nIHRvIHRoZSBmb2N1c2VkIHdhZ29uXG4gICAgICB0aGlzLl9zY3JvbGxUb1NlbGVjdGVkTmF2aWdhdGlvbkJ1dHRvbihuZXdGb2N1c2FibGVJbmRleCk7XG4gICAgfVxuICAgIC8vIElmIG5vIG5hdmlnYXRpb24gZXhpc3QsIHdlIHNjcm9sbCBkaXJlY3RseSB0byB0aGUgbmV4dCB0YWJhYmxlIGNvYWNoXG4gICAgZWxzZSB7XG4gICAgICB0aGlzLnNjcm9sbFRvU2VsZWN0ZWROYXZDb2FjaChuZXdGb2N1c2FibGVJbmRleCk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfbmF2aWdhdGVUb1BsYWNlQnlLZXlib2FyZChwcmVzc2VkS2V5OiBzdHJpbmcpOiB2b2lkIHtcbiAgICB0aGlzLmlzS2V5Ym9hcmROYXZpZ2F0aW9uID0gdHJ1ZTtcblxuICAgIGlmICh0aGlzLmZvY3VzZWRDb2FjaEluZGV4ICE9PSAtMSkge1xuICAgICAgdGhpcy5mb2N1c2VkQ29hY2hJbmRleCA9IC0xO1xuICAgIH1cblxuICAgIGlmICghdGhpcy5wcmV2ZW50UGxhY2VDbGljaykge1xuICAgICAgY29uc3QgZmluZENsb3Nlc3RQbGFjZSA9IHRoaXMuX2dldENsb3Nlc3RQbGFjZUJ5S2V5RGlyZWN0aW9uKHByZXNzZWRLZXkpO1xuXG4gICAgICBpZiAoZmluZENsb3Nlc3RQbGFjZSkge1xuICAgICAgICB0aGlzLmZvY3VzUGxhY2VFbGVtZW50KGZpbmRDbG9zZXN0UGxhY2UpO1xuICAgICAgfVxuICAgICAgLy8gTm8gY2xvc2VzdCBwbGFjZSBmb3VuZCBieSBrZXkgbmF2aWdhdGlvblxuICAgICAgZWxzZSB7XG4gICAgICAgIGlmIChcbiAgICAgICAgICBwcmVzc2VkS2V5ID09PSB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5BcnJvd1JpZ2h0IHx8XG4gICAgICAgICAgcHJlc3NlZEtleSA9PT0gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuQXJyb3dMZWZ0IHx8XG4gICAgICAgICAgKHRoaXMuYWxpZ25WZXJ0aWNhbCAmJlxuICAgICAgICAgICAgKHByZXNzZWRLZXkgPT09IHRoaXMua2V5Ym9hcmROYXZpZ2F0aW9uRXZlbnRzLkFycm93VXAgfHxcbiAgICAgICAgICAgICAgcHJlc3NlZEtleSA9PT0gdGhpcy5rZXlib2FyZE5hdmlnYXRpb25FdmVudHMuQXJyb3dEb3duKSlcbiAgICAgICAgKSB7XG4gICAgICAgICAgLy8gQ2hlY2sgdGhlIGN1cnJlbnQgcHJlc3NlZCBrZXkgdG8gZ2V0IHRoZSBuZXh0IGF2YWlsYWJsZSBjb2FjaCBpbmRleFxuICAgICAgICAgIGNvbnN0IG5ld1NlbGVjdGVkQ29hY2hJbmRleCA9XG4gICAgICAgICAgICBwcmVzc2VkS2V5ID09PSB0aGlzLmtleWJvYXJkTmF2aWdhdGlvbkV2ZW50cy5BcnJvd1JpZ2h0XG4gICAgICAgICAgICAgID8gdGhpcy5nZXROZXh0QXZhaWxhYmxlQ29hY2hJbmRleCgpXG4gICAgICAgICAgICAgIDogdGhpcy5nZXRQcmV2QXZhaWxhYmxlQ29hY2hJbmRleCgpO1xuXG4gICAgICAgICAgdGhpcy5zY3JvbGxUb1NlbGVjdGVkTmF2Q29hY2gobmV3U2VsZWN0ZWRDb2FjaEluZGV4KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHByb3RlY3RlZCBnZXROZXh0QXZhaWxhYmxlQ29hY2hJbmRleChjdXJyZW50SW5kZXg/OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IHN0YXJ0SW5kZXggPSBjdXJyZW50SW5kZXggPz8gdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4O1xuICAgIHJldHVybiBzdGFydEluZGV4IDwgdGhpcy5zZWF0UmVzZXJ2YXRpb25zW3RoaXMuY3VyclNlbGVjdGVkRGVja0luZGV4XS5jb2FjaEl0ZW1zLmxlbmd0aCAtIDFcbiAgICAgID8gc3RhcnRJbmRleCArIDFcbiAgICAgIDogc3RhcnRJbmRleDtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRQcmV2QXZhaWxhYmxlQ29hY2hJbmRleChjdXJyZW50SW5kZXg/OiBudW1iZXIpOiBudW1iZXIge1xuICAgIGNvbnN0IHN0YXJ0SW5kZXggPSBjdXJyZW50SW5kZXggPz8gdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4O1xuICAgIHJldHVybiBzdGFydEluZGV4ID4gMCA/IHN0YXJ0SW5kZXggLSAxIDogc3RhcnRJbmRleDtcbiAgfVxuXG4gIHByb3RlY3RlZCB1cGRhdGVTZWxlY3RlZFNlYXRSZXNlcnZhdGlvblBsYWNlcyhwbGFjZVNlbGVjdGlvbjogUGxhY2VTZWxlY3Rpb24pOiB2b2lkIHtcbiAgICBjb25zdCBwbGFjZVR5cGVQcm9wID0gcGxhY2VTZWxlY3Rpb24ucGxhY2VUeXBlID09PSAnU0VBVCcgPyAnc2VhdHMnIDogJ2JpY3ljbGVzJztcbiAgICBjb25zdCBtYXhSZXNlcnZhdGlvbnMgPVxuICAgICAgcGxhY2VTZWxlY3Rpb24ucGxhY2VUeXBlID09PSAnU0VBVCcgPyB0aGlzLm1heFNlYXRSZXNlcnZhdGlvbnMgOiB0aGlzLm1heEJpY3ljbGVSZXNlcnZhdGlvbnM7XG4gICAgY29uc3QgY3VyclNlbGVjdGVkUGxhY2VzID0gdGhpcy5zZWxlY3RlZFNlYXRSZXNlcnZhdGlvblBsYWNlc1twbGFjZVR5cGVQcm9wXTtcblxuICAgIHRoaXMuc2VsZWN0ZWRTZWF0UmVzZXJ2YXRpb25QbGFjZXNbcGxhY2VUeXBlUHJvcF0gPSB0aGlzLl91cGRhdGVTZWxlY3RlZFNlYXRSZXNlcnZhdGlvblBsYWNlcyhcbiAgICAgIGN1cnJTZWxlY3RlZFBsYWNlcyxcbiAgICAgIG1heFJlc2VydmF0aW9ucyxcbiAgICAgIHBsYWNlU2VsZWN0aW9uLFxuICAgICk7XG4gICAgLyoqXG4gICAgICogQHR5cGUge0N1c3RvbUV2ZW50PFNlYXRSZXNlcnZhdGlvblNlbGVjdGVkUGxhY2VzPn1cbiAgICAgKiBFbWl0cyB3aGVuIGEgcGxhY2Ugd2FzIHNlbGVjdGVkIGFuZCByZXR1cm5zIGEgUGxhY2UgYXJyYXkgd2l0aCBhbGwgc2VsZWN0ZWQgcGxhY2VzLlxuICAgICAqL1xuICAgIHRoaXMuZGlzcGF0Y2hFdmVudChcbiAgICAgIG5ldyBDdXN0b21FdmVudDxTZWF0UmVzZXJ2YXRpb25TZWxlY3RlZFBsYWNlcz4oJ3NlbGVjdGVkcGxhY2VzJywge1xuICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICBjb21wb3NlZDogdHJ1ZSxcbiAgICAgICAgZGV0YWlsOiB0aGlzLnNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIHByaXZhdGUgX3VwZGF0ZVNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzKFxuICAgIHNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzOiBTZWF0UmVzZXJ2YXRpb25QbGFjZVNlbGVjdGlvbltdLFxuICAgIG1heFJlc2VydmF0aW9uczogbnVtYmVyLFxuICAgIHBsYWNlU2VsZWN0aW9uOiBQbGFjZVNlbGVjdGlvbixcbiAgKTogU2VhdFJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb25bXSB7XG4gICAgLy8gQWRkIHNlbGVjdGVkIHBsYWNlIHRvIHNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzXG4gICAgaWYgKHBsYWNlU2VsZWN0aW9uLnN0YXRlID09PSAnU0VMRUNURUQnKSB7XG4gICAgICBjb25zdCBzZWxlY3RlZFBsYWNlRGVja0luZGV4ID0gdGhpcy5fZ2V0RGVja0luZGV4QnlQbGFjZUlkKHBsYWNlU2VsZWN0aW9uLmlkKTtcbiAgICAgIGNvbnN0IHNlYXRSZXNlcnZhdGlvblNlbGVjdGlvbiA9IHRoaXMuX2dldFNlYXRSZXNlcnZhdGlvblBsYWNlU2VsZWN0aW9uKFxuICAgICAgICBwbGFjZVNlbGVjdGlvbixcbiAgICAgICAgc2VsZWN0ZWRQbGFjZURlY2tJbmRleCxcbiAgICAgICk7XG4gICAgICBpZiAoc2VhdFJlc2VydmF0aW9uU2VsZWN0aW9uKSB7XG4gICAgICAgIHNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzLnB1c2goc2VhdFJlc2VydmF0aW9uU2VsZWN0aW9uKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gUmVtb3ZlIHNlbGVjdGVkIHBsYWNlIGZyb20gc2VsZWN0ZWRTZWF0UmVzZXJ2YXRpb25QbGFjZXNcbiAgICBlbHNlIHtcbiAgICAgIHNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzID0gc2VsZWN0ZWRTZWF0UmVzZXJ2YXRpb25QbGFjZXMuZmlsdGVyKFxuICAgICAgICAoX3NlbGVjdGVkUGxhY2UpID0+IF9zZWxlY3RlZFBsYWNlLmlkICE9PSBwbGFjZVNlbGVjdGlvbi5pZCxcbiAgICAgICk7XG4gICAgfVxuICAgIC8vIENoZWNrcyB3aGV0aGVyIG1heFJlc2VydmF0aW9uIGlzIGFjdGl2YXRlZCBhbmQgdGhlIG1heGltdW0gbnVtYmVyIG9mIHNlbGVjdGVkIHBsYWNlcyBpcyByZWFjaGVkXG4gICAgaWYgKG1heFJlc2VydmF0aW9ucyA+IC0xICYmIHNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzLmxlbmd0aCA+IG1heFJlc2VydmF0aW9ucykge1xuICAgICAgY29uc3QgcmVzZXRXaXRoUGxhY2VTZWxlY3Rpb24gPSBtYXhSZXNlcnZhdGlvbnMgPiAwID8gcGxhY2VTZWxlY3Rpb24gOiB1bmRlZmluZWQ7XG5cbiAgICAgIHNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzID0gdGhpcy5fcmVzZXRBbGxQbGFjZVNlbGVjdGlvbnMoXG4gICAgICAgIHNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzLFxuICAgICAgICByZXNldFdpdGhQbGFjZVNlbGVjdGlvbixcbiAgICAgICk7XG4gICAgfVxuICAgIHJldHVybiBzZWxlY3RlZFNlYXRSZXNlcnZhdGlvblBsYWNlcztcbiAgfVxuXG4gIHByb3RlY3RlZCB1cGRhdGVDdXJyZW50U2VsZWN0ZWRQbGFjZUluQ29hY2gocGxhY2VTZWxlY3Rpb246IFBsYWNlU2VsZWN0aW9uKTogdm9pZCB7XG4gICAgY29uc3QgcGxhY2VEZWNrSW5kZXggPSB0aGlzLl9nZXREZWNrSW5kZXhCeVBsYWNlSWQocGxhY2VTZWxlY3Rpb24uaWQpO1xuICAgIGNvbnN0IGNvYWNoSW5kZXggPSBwbGFjZVNlbGVjdGlvbi5jb2FjaEluZGV4O1xuXG4gICAgaWYgKHBsYWNlRGVja0luZGV4ID09PSBudWxsKSByZXR1cm47XG5cbiAgICBjb25zdCBwbGFjZSA9IHRoaXMuc2VhdFJlc2VydmF0aW9uc1twbGFjZURlY2tJbmRleF0uY29hY2hJdGVtc1tjb2FjaEluZGV4XS5wbGFjZXM/LmZpbmQoXG4gICAgICAocGxhY2UpID0+IHBsYWNlLm51bWJlciA9PSBwbGFjZVNlbGVjdGlvbi5udW1iZXIsXG4gICAgKTtcblxuICAgIGlmICghcGxhY2UpIHJldHVybjtcblxuICAgIHRoaXMuY3VyclNlbGVjdGVkRGVja0luZGV4ID0gcGxhY2VEZWNrSW5kZXg7XG4gICAgdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4ID0gY29hY2hJbmRleDtcbiAgICB0aGlzLmN1cnJTZWxlY3RlZFBsYWNlID0gcGxhY2U7XG5cbiAgICBpZiAodGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4ICE9PSB0aGlzLnNlbGVjdGVkQ29hY2hJbmRleCkge1xuICAgICAgdGhpcy51cGRhdGVDdXJyZW50U2VsZWN0ZWRDb2FjaCgpO1xuICAgIH1cblxuICAgIHRoaXMuX3NldEN1cnJTZWxlY3RlZFBsYWNlRWxlbWVudElkKHBsYWNlKTtcblxuICAgIC8vIFRpbWUgZGVsYXkgdG8gd2FpdCBmb3Igc3RhdHVzIHVwZGF0ZSBwcm9jZXNzIGF0IGNsaWNrZWQgcGxhY2VcbiAgICBjb25zdCBkZWxheVNjcm9sbEluVmlld3BvcnQgPSBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgIHRoaXMuX3Njcm9sbFBsYWNlSW50b05lYXJlc3RWaWV3cG9ydChwbGFjZVNlbGVjdGlvbi5pZCk7XG4gICAgICBjbGVhclRpbWVvdXQoZGVsYXlTY3JvbGxJblZpZXdwb3J0KTtcbiAgICB9LCAwKTtcbiAgfVxuXG4gIHByb3RlY3RlZCB1cGRhdGVDdXJyZW50U2VsZWN0ZWRDb2FjaCgpOiB2b2lkIHtcbiAgICAvL09ubHkgaWYgdGhlIHNlbGVjdGVkQ29hY2hJbmRleCBoYXMgY2hhbmdlZCwgYW4gdXBkYXRlIG5lZWRzIHRvIGJlIGNhcnJpZWQgb3V0XG4gICAgaWYgKHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleCA9PSB0aGlzLnNlbGVjdGVkQ29hY2hJbmRleCkgcmV0dXJuO1xuXG4gICAgLy8gSWYgYSBmb2N1c2luZGV4IGhhcyBiZWVuIHNldCAoIT0gLTEpLCBpdCBjYW4gYmUgdXBkYXRlZCB3aXRoIHRoZSBjdXJyZW50IHNlbGVjdGVkQ29hY2hJbmRleFxuICAgIGlmICh0aGlzLmZvY3VzZWRDb2FjaEluZGV4ICE9IC0xKSB7XG4gICAgICB0aGlzLmZvY3VzZWRDb2FjaEluZGV4ID0gdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4O1xuICAgIH1cbiAgICB0aGlzLnNlbGVjdGVkQ29hY2hJbmRleCA9IHRoaXMuY3VyclNlbGVjdGVkQ29hY2hJbmRleDtcblxuICAgIGNvbnN0IGNvYWNoU2VsZWN0aW9uID0gdGhpcy5fZ2V0U2VhdFJlc2VydmF0aW9uU2VsZWN0ZWRDb2FjaCh0aGlzLnNlbGVjdGVkQ29hY2hJbmRleCk7XG4gICAgaWYgKGNvYWNoU2VsZWN0aW9uKSB7XG4gICAgICAvKipcbiAgICAgICAqIEB0eXBlIHtDdXN0b21FdmVudDxTZWF0UmVzZXJ2YXRpb25TZWxlY3RlZENvYWNoPn1cbiAgICAgICAqIEVtaXRzIHdoZW4gYSBjb2FjaCB3YXMgc2VsZWN0ZWQgYW5kIHJldHVybnMgYSBDb2FjaFNlbGVjdGlvblxuICAgICAgICovXG4gICAgICB0aGlzLmRpc3BhdGNoRXZlbnQoXG4gICAgICAgIG5ldyBDdXN0b21FdmVudDxTZWF0UmVzZXJ2YXRpb25TZWxlY3RlZENvYWNoPignc2VsZWN0ZWRjb2FjaCcsIHtcbiAgICAgICAgICBidWJibGVzOiB0cnVlLFxuICAgICAgICAgIGNvbXBvc2VkOiB0cnVlLFxuICAgICAgICAgIGRldGFpbDogY29hY2hTZWxlY3Rpb24sXG4gICAgICAgIH0pLFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0UGxhY2VFbGVtZW50SWQoXG4gICAgY29hY2hEZWNrSW5kZXg6IG51bWJlcixcbiAgICBjb2FjaEluZGV4OiBudW1iZXIsXG4gICAgcGxhY2VOdW1iZXI6IHN0cmluZyxcbiAgKTogc3RyaW5nIHtcbiAgICByZXR1cm4gKFxuICAgICAgJ3NlYXQtcmVzZXJ2YXRpb25fX3BsYWNlLWJ1dHRvbi0nICsgY29hY2hEZWNrSW5kZXggKyAnLScgKyBjb2FjaEluZGV4ICsgJy0nICsgcGxhY2VOdW1iZXJcbiAgICApO1xuICB9XG5cbiAgLyoqXG4gICAqIEluIHRoZSBjYXNlIG9mIGNvYWNoIGxheW91dHMgd2l0aCBkaWZmZXJlbnQgZGVja3MsXG4gICAqIGl0IGlzIG5lY2Vzc2FyeSB0byBleHRlbmQgdGhlIG9mZnNldCB3aXRoIGVtcHR5IGNvYWNoZXNcbiAgICogaW4gb3JkZXIgdG8gY3JlYXRlIGEgc3RhYmxlIHZlaGljbGUgbGF5b3V0LlxuICAgKlxuICAgKiAgICAgICAgICAgICBbb29vXS1bb29vXS1bb29vXVxuICAgKiBbb29vXS1bb29vXS1bb29vXS1bb29vXS1bb29vXVxuICAgKi9cbiAgcHJpdmF0ZSBfaW5pdEVtcHR5Q29hY2hEZWNrT2Zmc2V0cygpOiB2b2lkIHtcbiAgICAvLyBQcmVmaWxsIG9mZnNldCBjb3VudGVycyB3aXRoIDAgc3RhcnQgaW5kZXhcbiAgICBjb25zdCBjb2FjaE9mZnNldEluZGV4Q291bnRlciA9IEFycmF5KHRoaXMuc2VhdFJlc2VydmF0aW9ucy5sZW5ndGggLSAxKS5maWxsKDApO1xuICAgIC8vIFRha2VzIHRoZSBsb3dlciBkZWNrIHdoaWNoIGNvbnRhaW5zIHRoZSBtYXggbnVtYmVycyBvZiBjb2FjaGVzXG4gICAgY29uc3QgbG93ZXJEZWNrID0gdGhpcy5zZWF0UmVzZXJ2YXRpb25zW3RoaXMuc2VhdFJlc2VydmF0aW9ucy5sZW5ndGggLSAxXTtcblxuICAgIGxvd2VyRGVjay5jb2FjaEl0ZW1zLmZvckVhY2goKGxvd2VyQ29hY2hJdGVtOiBDb2FjaEl0ZW0pID0+IHtcbiAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5zZWF0UmVzZXJ2YXRpb25zLmxlbmd0aCAtIDE7IGkrKykge1xuICAgICAgICBjb25zdCBkZWNrQ29hY2hJdGVtID0gdGhpcy5zZWF0UmVzZXJ2YXRpb25zW2ldLmNvYWNoSXRlbXNbY29hY2hPZmZzZXRJbmRleENvdW50ZXJbaV1dO1xuICAgICAgICBpZiAobG93ZXJDb2FjaEl0ZW0uaWQgIT0gZGVja0NvYWNoSXRlbT8uaWQpIHtcbiAgICAgICAgICAvLyBBZGQgRW1wdHkgb2Zmc2V0IGNvYWNoIHRvIHNwZWNpZmllZCBpbmRleCBwb3NpdGlvblxuICAgICAgICAgIGNvbnN0IGVtcHR5T2Zmc2V0Q29hY2ggPSB7XG4gICAgICAgICAgICAuLi5sb3dlckNvYWNoSXRlbSxcbiAgICAgICAgICAgIHBsYWNlczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgcHJvcGVydHlJZHM6IHVuZGVmaW5lZCxcbiAgICAgICAgICAgIGdyYXBoaWNFbGVtZW50czogdW5kZWZpbmVkLFxuICAgICAgICAgICAgc2VydmljZUVsZW1lbnRzOiB1bmRlZmluZWQsXG4gICAgICAgICAgICB0cmF2ZWxDbGFzczogW10sXG4gICAgICAgICAgfTtcbiAgICAgICAgICB0aGlzLnNlYXRSZXNlcnZhdGlvbnNbaV0uY29hY2hJdGVtcy5zcGxpY2UoXG4gICAgICAgICAgICBjb2FjaE9mZnNldEluZGV4Q291bnRlcltpXSxcbiAgICAgICAgICAgIDAsXG4gICAgICAgICAgICBlbXB0eU9mZnNldENvYWNoLFxuICAgICAgICAgICk7XG4gICAgICAgIH1cblxuICAgICAgICBjb2FjaE9mZnNldEluZGV4Q291bnRlcltpXSsrO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIEluaXRpYWxpemF0aW9uIG9mIFNlYXRSZXNlcnZhdGlvblBsYWNlU2VsZWN0aW9uIEFycmF5IGJhc2VkIG9uIHRoZSB0cmFuc2ZlcnJlZCBwbGFjZXNcbiAgICogdGhhdCBoYXZlIHRoZSBzdGF0ZSBTRUxFQ1RFRCB3aXRoaW4gdGhlIHNlYXRSZXNlcnZhdGlvbiBvYmplY3RcbiAgICovXG4gIHByaXZhdGUgX2luaXRTZWF0UmVzZXJ2YXRpb25QbGFjZVNlbGVjdGlvbigpOiB2b2lkIHtcbiAgICAvLyBSZXNldCBwbGFjZSBzZWxlY3Rpb25zXG4gICAgdGhpcy5zZWxlY3RlZFNlYXRSZXNlcnZhdGlvblBsYWNlcy5zZWF0cyA9IFtdO1xuICAgIHRoaXMuc2VsZWN0ZWRTZWF0UmVzZXJ2YXRpb25QbGFjZXMuYmljeWNsZXMgPSBbXTtcblxuICAgIHRoaXMuc2VhdFJlc2VydmF0aW9ucz8uZm9yRWFjaCgoc2VhdFJlc2VydmF0aW9uOiBTZWF0UmVzZXJ2YXRpb24sIGNvYWNoRGVja0luZGV4OiBudW1iZXIpID0+XG4gICAgICBzZWF0UmVzZXJ2YXRpb24uY29hY2hJdGVtcy5tYXAoKGNvYWNoOiBDb2FjaEl0ZW0sIGNvYWNoSW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICBjb2FjaC5wbGFjZXNcbiAgICAgICAgICA/LmZpbHRlcigocGxhY2UpID0+IHBsYWNlLnN0YXRlID09PSAnU0VMRUNURUQnKVxuICAgICAgICAgID8uZm9yRWFjaCgocGxhY2UpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHBsYWNlSWQgPSB0aGlzLmdldFBsYWNlRWxlbWVudElkKGNvYWNoRGVja0luZGV4LCBjb2FjaEluZGV4LCBwbGFjZS5udW1iZXIpO1xuICAgICAgICAgICAgY29uc3QgcHJlc2VsZWN0ZWRQbGFjZVNlbGVjdGlvbjogUGxhY2VTZWxlY3Rpb24gPSBtYXBQbGFjZUluZm9zVG9QbGFjZVNlbGVjdGlvbihcbiAgICAgICAgICAgICAgcGxhY2UsXG4gICAgICAgICAgICAgIHBsYWNlSWQsXG4gICAgICAgICAgICAgIHNlYXRSZXNlcnZhdGlvbi5kZWNrQ29hY2hJbmRleCxcbiAgICAgICAgICAgICAgY29hY2hJbmRleCxcbiAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgIGNvbnN0IHNlYXRSZXNlcnZhdGlvblBsYWNlU2VsZWN0aW9uOiBTZWF0UmVzZXJ2YXRpb25QbGFjZVNlbGVjdGlvbiB8IG51bGwgPVxuICAgICAgICAgICAgICB0aGlzLl9nZXRTZWF0UmVzZXJ2YXRpb25QbGFjZVNlbGVjdGlvbihwcmVzZWxlY3RlZFBsYWNlU2VsZWN0aW9uLCBjb2FjaERlY2tJbmRleCk7XG5cbiAgICAgICAgICAgIGlmIChzZWF0UmVzZXJ2YXRpb25QbGFjZVNlbGVjdGlvbikge1xuICAgICAgICAgICAgICBpZiAoc2VhdFJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb24ucGxhY2VUeXBlID09PSAnU0VBVCcpIHtcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkU2VhdFJlc2VydmF0aW9uUGxhY2VzLnNlYXRzLnB1c2goc2VhdFJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb24pO1xuICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRTZWF0UmVzZXJ2YXRpb25QbGFjZXMuYmljeWNsZXMucHVzaChzZWF0UmVzZXJ2YXRpb25QbGFjZVNlbGVjdGlvbik7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9KTtcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cbiAgLyoqXG4gICAqIEFsbCBzZWxlY3RlZCBwbGFjZXMgd2lsbCBiZSByZXNldCBvciB0aGUgY3VycmVudFNlbGVjdGVkUGxhY2Ugd2FzIGdpdmVuLCB0aGVuIHdlIHJlc2V0IGFsbCBleGNlcHQgY3VycmVudFNlbGVjdGVkUGxhY2VcbiAgICogQHBhcmFtIHJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb25zXG4gICAqIEBwYXJhbSBjdXJyU2VsZWN0ZWRQbGFjZVxuICAgKi9cbiAgcHJpdmF0ZSBfcmVzZXRBbGxQbGFjZVNlbGVjdGlvbnMoXG4gICAgcmVzZXJ2YXRpb25QbGFjZVNlbGVjdGlvbnM6IFNlYXRSZXNlcnZhdGlvblBsYWNlU2VsZWN0aW9uW10sXG4gICAgY3VyclNlbGVjdGVkUGxhY2U/OiBQbGFjZVNlbGVjdGlvbixcbiAgKTogU2VhdFJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb25bXSB7XG4gICAgLy9GaW5kIGFsbCBwbGFjZXMgdG8gYmUgbmVlZGVkIHVuc2VsZWN0XG4gICAgZm9yIChjb25zdCBwbGFjZVNlbGVjdGlvbiBvZiByZXNlcnZhdGlvblBsYWNlU2VsZWN0aW9ucykge1xuICAgICAgaWYgKCFjdXJyU2VsZWN0ZWRQbGFjZSB8fCBjdXJyU2VsZWN0ZWRQbGFjZS5pZCAhPT0gcGxhY2VTZWxlY3Rpb24uaWQpIHtcbiAgICAgICAgY29uc3QgcGxhY2VFbGVtZW50ID0gdGhpcy5zaGFkb3dSb290Py5nZXRFbGVtZW50QnlJZChwbGFjZVNlbGVjdGlvbi5pZCkgYXMgSFRNTEVsZW1lbnQ7XG4gICAgICAgIGlmIChwbGFjZUVsZW1lbnQpIHtcbiAgICAgICAgICBwbGFjZUVsZW1lbnQuc2V0QXR0cmlidXRlKCdzdGF0ZScsICdGUkVFJyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgLy9SZW1vdmVzIGFsbCBzZWxlY3RlZCBwbGFjZXMgZXhjZXB0IHRoZSBjdXJyZW50bHkgc2VsZWN0ZWQgcGxhY2VcbiAgICBpZiAoY3VyclNlbGVjdGVkUGxhY2UpIHtcbiAgICAgIHJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb25zID0gcmVzZXJ2YXRpb25QbGFjZVNlbGVjdGlvbnMuZmlsdGVyKFxuICAgICAgICAoX3NlbGVjdGVkUGxhY2UpID0+IF9zZWxlY3RlZFBsYWNlLmlkID09PSBjdXJyU2VsZWN0ZWRQbGFjZS5pZCxcbiAgICAgICk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb25zID0gW107XG4gICAgfVxuICAgIHJldHVybiByZXNlcnZhdGlvblBsYWNlU2VsZWN0aW9ucztcbiAgfVxuXG4gIHByaXZhdGUgX2dldFNlYXRSZXNlcnZhdGlvblBsYWNlU2VsZWN0aW9uKFxuICAgIGN1cnJTZWxlY3RlZFBsYWNlOiBQbGFjZVNlbGVjdGlvbixcbiAgICBjb2FjaERlY2tJbmRleDogbnVtYmVyIHwgbnVsbCxcbiAgKTogU2VhdFJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb24gfCBudWxsIHtcbiAgICBpZiAoY29hY2hEZWNrSW5kZXggPT09IG51bGwpIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgY29hY2ggPSB0aGlzLnNlYXRSZXNlcnZhdGlvbnNbY29hY2hEZWNrSW5kZXhdLmNvYWNoSXRlbXNbY3VyclNlbGVjdGVkUGxhY2UuY29hY2hJbmRleF07XG4gICAgY29uc3QgcGxhY2UgPSBjb2FjaC5wbGFjZXM/LmZpbmQoKHBsYWNlKSA9PiBwbGFjZS5udW1iZXIgPT09IGN1cnJTZWxlY3RlZFBsYWNlLm51bWJlcik7XG5cbiAgICByZXR1cm4gcGxhY2VcbiAgICAgID8gbWFwUGxhY2VBbmRDb2FjaFRvU2VhdFJlc2VydmF0aW9uUGxhY2VTZWxlY3Rpb24oXG4gICAgICAgICAgcGxhY2UsXG4gICAgICAgICAgY29hY2gsXG4gICAgICAgICAgY3VyclNlbGVjdGVkUGxhY2UuaWQsXG4gICAgICAgICAgY3VyclNlbGVjdGVkUGxhY2UuZGVja0luZGV4LFxuICAgICAgICAgIGN1cnJTZWxlY3RlZFBsYWNlLmNvYWNoSW5kZXgsXG4gICAgICAgIClcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgX2dldFNlYXRSZXNlcnZhdGlvblNlbGVjdGVkQ29hY2goXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICApOiBTZWF0UmVzZXJ2YXRpb25TZWxlY3RlZENvYWNoIHwgbnVsbCB7XG4gICAgaWYgKCF0aGlzLnNlYXRSZXNlcnZhdGlvbnNbdGhpcy5jdXJyU2VsZWN0ZWREZWNrSW5kZXhdLmNvYWNoSXRlbXNbY29hY2hJbmRleF0pIHJldHVybiBudWxsO1xuXG4gICAgY29uc3QgY29hY2ggPSB0aGlzLnNlYXRSZXNlcnZhdGlvbnNbdGhpcy5jdXJyU2VsZWN0ZWREZWNrSW5kZXhdLmNvYWNoSXRlbXNbY29hY2hJbmRleF07XG4gICAgY29uc3QgY29hY2hOdW1iZXJPZkZyZWVQbGFjZXMgPSB0aGlzLmdldEF2YWlsYWJsZUZyZWVQbGFjZXNOdW1Gcm9tQ29hY2goY29hY2gucGxhY2VzKTtcbiAgICByZXR1cm4gbWFwQ29hY2hJbmZvc1RvQ29hY2hTZWxlY3Rpb24oY29hY2hJbmRleCwgY29hY2gsIGNvYWNoTnVtYmVyT2ZGcmVlUGxhY2VzKTtcbiAgfVxuXG4gIHByaXZhdGUgX3NldEN1cnJTZWxlY3RlZFBsYWNlRWxlbWVudElkKHBsYWNlOiBQbGFjZSB8IG51bGwpOiB2b2lkIHtcbiAgICB0aGlzLmN1cnJTZWxlY3RlZFBsYWNlRWxlbWVudElkID0gcGxhY2VcbiAgICAgID8gdGhpcy5nZXRQbGFjZUVsZW1lbnRJZChcbiAgICAgICAgICB0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleCxcbiAgICAgICAgICB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXgsXG4gICAgICAgICAgcGxhY2UubnVtYmVyLFxuICAgICAgICApXG4gICAgICA6IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUHJlcGFyYXRpb24gb2YgdGhlIHVzZWQgZG9jdW1lbnRzIGZvbnQtc2l6ZSB3aGljaCBuZWVkc1xuICAgKiB0byBiZSBkZXRlcm1pbmVkIGluIG9yZGVyIHRvIGNvcnJlY3RseSBjYWxjdWxhdGUgQ1NTIHZhbHVlcyB3aXRoIHJlbVxuICAgKiAqL1xuICBwcml2YXRlIF9kZXRlcm1pbmVCYXNlRm9udFNpemUoKTogdm9pZCB7XG4gICAgaWYgKCFpc1NlcnZlcikge1xuICAgICAgY29uc3QgYmFzZUZvbnRTaXplID0gcGFyc2VJbnQod2luZG93LmdldENvbXB1dGVkU3R5bGUoZG9jdW1lbnQuYm9keSkuZm9udFNpemUsIDEwKTtcbiAgICAgIC8vY2FsY3VsYXRlIHJlbSBvZiAxcHhcbiAgICAgIGNvbnN0IG9uZVBpeGVsSW5SZW0gPSAxIC8gYmFzZUZvbnRTaXplO1xuICAgICAgdGhpcy5zdHlsZT8uc2V0UHJvcGVydHkoJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tb25lLXB4LXJlbScsIGAke29uZVBpeGVsSW5SZW0gKyAncmVtJ31gKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUHJlcGFyZXMgZGF0YSBmb3IgZGlzcGxheWluZyBuYXZpZ2F0aW9uIGFyZWEuXG4gICAqIENhbGN1bGF0ZXMgdGhlIHZhbHVlcyB3aGljaCBhcmUgbm90IGdvaW5nIHRvIGNoYW5nZSBkdXJpbmcgdXNlIG9mIGEgY29tcG9uZW50OlxuICAgKiAgICAtIGNvYWNoIGlkXG4gICAqICAgIC0gbGlzdCBvZiBzZXJ2aWNlIGljb25zXG4gICAqICAgIC0gY2xhc3MgKGZpcnN0LCBzZWNvbmQsIGFueSlcbiAgICogICAgLSB3aGV0aGVyIHRoZXJlIGlzIGEgZHJpdmVyIGFyZWEgbGVmdCBvciByaWdodFxuICAgKiAqL1xuICBwcml2YXRlIF9wcmVwYXJlTmF2aWdhdGlvbkNvYWNoRGF0YSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5zZWF0UmVzZXJ2YXRpb25zKSB7XG4gICAgICBjb25zdCBsb3dlckRlY2s6IENvYWNoSXRlbVtdID1cbiAgICAgICAgdGhpcy5zZWF0UmVzZXJ2YXRpb25zW3RoaXMuc2VhdFJlc2VydmF0aW9ucy5sZW5ndGggLSAxXS5jb2FjaEl0ZW1zO1xuXG4gICAgICB0aGlzLmNvYWNoTmF2RGF0YSA9IFtdO1xuXG4gICAgICBsb3dlckRlY2suZm9yRWFjaCgoY29hY2gsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IHRyYXZlbENsYXNzZXM6IFBsYWNlVHJhdmVsQ2xhc3NbXSA9IFtdO1xuICAgICAgICBjb25zdCBwcm9wZXJ0eUlkczogc3RyaW5nW10gPSBbXTtcbiAgICAgICAgY29uc3QgcGxhY2VzOiBQbGFjZVtdID0gW107XG5cbiAgICAgICAgLy8gQ29sbGVjdCBhbGwgaW1wb3J0YW50IG5hdmlnYXRpb24gZGF0YSB0byBiZSByZW5kZXJlZFxuICAgICAgICB0aGlzLnNlYXRSZXNlcnZhdGlvbnNcbiAgICAgICAgICAubWFwKChzcikgPT4ge1xuICAgICAgICAgICAgcmV0dXJuIHNyLmNvYWNoSXRlbXNbaW5kZXhdO1xuICAgICAgICAgIH0pXG4gICAgICAgICAgLmZvckVhY2goKGNvYWNoOiBDb2FjaEl0ZW0pID0+IHtcbiAgICAgICAgICAgIHRyYXZlbENsYXNzZXMucHVzaCguLi5jb2FjaC50cmF2ZWxDbGFzcyk7XG4gICAgICAgICAgICBwcm9wZXJ0eUlkcy5wdXNoKC4uLihjb2FjaC5wcm9wZXJ0eUlkcyA/IGNvYWNoLnByb3BlcnR5SWRzIDogW10pKTtcbiAgICAgICAgICAgIHBsYWNlcy5wdXNoKC4uLihjb2FjaC5wbGFjZXMgPyBjb2FjaC5wbGFjZXMgOiBbXSkpO1xuICAgICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuY29hY2hOYXZEYXRhLnB1c2goe1xuICAgICAgICAgIGlkOiBjb2FjaC5pZCxcbiAgICAgICAgICB0cmF2ZWxDbGFzczogdGhpcy5fcHJlcGFyZVRyYXZlbENsYXNzTmF2aWdhdGlvbih0cmF2ZWxDbGFzc2VzKSxcbiAgICAgICAgICBwcm9wZXJ0eUlkczogdGhpcy5fcHJlcGFyZVNlcnZpY2VJY29uc05hdmlnYXRpb24ocHJvcGVydHlJZHMpLFxuICAgICAgICAgIGlzRHJpdmVyQXJlYTogY29hY2gucGxhY2VzID8gY29hY2gucGxhY2VzLmxlbmd0aCA9PT0gMCA6IHRydWUsXG4gICAgICAgICAgZHJpdmVyQXJlYVNpZGU6IHRoaXMuX3ByZXBhcmVEcml2ZXJBcmVhU2lkZU5hdmlnYXRpb24oY29hY2gpLFxuICAgICAgICAgIGZyZWVQbGFjZXM6IHRoaXMuZ2V0QXZhaWxhYmxlRnJlZVBsYWNlc051bUZyb21Db2FjaChwbGFjZXMpLFxuICAgICAgICB9KTtcbiAgICAgIH0pO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX3ByZXBhcmVUcmF2ZWxDbGFzc05hdmlnYXRpb24odHJhdmVsQ2xhc3NlczogUGxhY2VUcmF2ZWxDbGFzc1tdKTogUGxhY2VUcmF2ZWxDbGFzcyB7XG4gICAgaWYgKHRyYXZlbENsYXNzZXMuaW5kZXhPZignRklSU1QnKSAhPT0gLTEpIHJldHVybiAnRklSU1QnO1xuICAgIGlmICh0cmF2ZWxDbGFzc2VzLmluZGV4T2YoJ1NFQ09ORCcpICE9PSAtMSkgcmV0dXJuICdTRUNPTkQnO1xuICAgIHJldHVybiAnQU5ZX0NMQVNTJztcbiAgfVxuXG4gIHByaXZhdGUgX3ByZXBhcmVEcml2ZXJBcmVhU2lkZU5hdmlnYXRpb24oXG4gICAgY29hY2hJdGVtOiBDb2FjaEl0ZW0sXG4gICk6IFJlY29yZDxzdHJpbmcsIGJvb2xlYW4+IHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBjb2FjaERyaXZlckFyZWFzID0gY29hY2hJdGVtLmdyYXBoaWNFbGVtZW50cz8uZmlsdGVyKFxuICAgICAgKGdyYXBoaWNhbEVsZW1lbnRzKSA9PiBncmFwaGljYWxFbGVtZW50cy5pY29uID09PSAnRFJJVkVSX0FSRUEnLFxuICAgICk7XG5cbiAgICBpZiAoY29hY2hEcml2ZXJBcmVhcyAmJiBjb2FjaERyaXZlckFyZWFzLmxlbmd0aCA+IDApIHtcbiAgICAgIC8vIENoZWNraW5nIHRoZSBkcml2ZXIgYXJlYSBwb3NpdGlvbiB3aGV0aGVyIGl0IGlzIHByZXNlbnQgb24gdGhlIGxlZnQgb3IgcmlnaHQgc2lkZSBpbiBhIGNvYWNoXG4gICAgICBjb25zdCBoYXNMZWZ0RHJpdmVyQXJlYSA9XG4gICAgICAgIGNvYWNoRHJpdmVyQXJlYXMuZmluZCgoZHJpdmVyQXJlYUVsZW1lbnQpID0+IGRyaXZlckFyZWFFbGVtZW50LnBvc2l0aW9uLnggPT09IDApIHx8IGZhbHNlO1xuICAgICAgY29uc3QgaGFzUmlnaHREcml2ZXJBcmVhID1cbiAgICAgICAgY29hY2hEcml2ZXJBcmVhcy5maW5kKChkcml2ZXJBcmVhRWxlbWVudCkgPT4gZHJpdmVyQXJlYUVsZW1lbnQucG9zaXRpb24ueCA+IDApIHx8IGZhbHNlO1xuXG4gICAgICByZXR1cm4ge1xuICAgICAgICBsZWZ0OiAhIWhhc0xlZnREcml2ZXJBcmVhLFxuICAgICAgICByaWdodDogISFoYXNSaWdodERyaXZlckFyZWEsXG4gICAgICB9O1xuICAgIH1cbiAgICByZXR1cm4gdW5kZWZpbmVkO1xuICB9XG5cbiAgcHJpdmF0ZSBfcHJlcGFyZVNlcnZpY2VJY29uc05hdmlnYXRpb24gPSAocHJvcGVydHlJZHM6IHN0cmluZ1tdKTogc3RyaW5nW10gPT4ge1xuICAgIGlmICghcHJvcGVydHlJZHMpIHtcbiAgICAgIHJldHVybiBbXTtcbiAgICB9XG5cbiAgICBjb25zdCBzaHJ1bmtQcm9wZXJ0eUlkcyA9IHByb3BlcnR5SWRzXG4gICAgICA/Lm1hcChmdW5jdGlvbiAocHJvcGVydHlJZDogc3RyaW5nKToge1xuICAgICAgICBwSWQ6IHN0cmluZztcbiAgICAgICAgc3ZnTmFtZTogc3RyaW5nO1xuICAgICAgfSB7XG4gICAgICAgIC8vIHByZXBhcmUgdGVtcG9yYXJ5IG9iamVjdCBtYXBwaW5nIHByb3BlcnR5IGlkIHRvIGl0J3Mgc3ZnTmFtZSBzbyB0aGF0IHdlIGNhbiBjb21wYXJlIGl0IHRvIHRoZSBsaXN0IG9mIGFsbG93ZWQgaWNvbnNcbiAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICBwSWQ6IHByb3BlcnR5SWQsXG4gICAgICAgICAgc3ZnTmFtZTogbWFwSWNvblRvU3ZnW3Byb3BlcnR5SWRdPy5zdmdOYW1lID8gbWFwSWNvblRvU3ZnW3Byb3BlcnR5SWRdPy5zdmdOYW1lIDogJycsXG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLy9maWx0ZXIgb3V0IG9iamVjdHMgc2VydmljZSBpY29ucyB3aGljaCBhcmUgbm90IGluIEFMTE9XRURfU0VSVklDRV9JQ09OU1xuICAgICAgLmZpbHRlcigocHJvcGVydHlUb1N2ZykgPT4gQUxMT1dFRF9TRVJWSUNFX0lDT05TLmluZGV4T2YocHJvcGVydHlUb1N2Zy5zdmdOYW1lKSAhPT0gLTEpXG4gICAgICAvL21ha2UgaXQgZGlzdGluY3QgYnkgc3ZnTmFtZVxuICAgICAgLmZpbHRlcihcbiAgICAgICAgKHZhbHVlLCBpbmRleCwgc2VsZikgPT5cbiAgICAgICAgICBzZWxmLm1hcCgocHJvcFN2ZykgPT4gcHJvcFN2Zy5zdmdOYW1lKS5pbmRleE9mKHZhbHVlLnN2Z05hbWUpID09PSBpbmRleCxcbiAgICAgIClcbiAgICAgIC8vIGdvIGJhY2sgdG8gcHJvcGVydHlJZCBzdHJpbmcgZnJvbSB0ZW1wb3Jhcnkgb2JqZWN0XG4gICAgICAubWFwKChwcm9wZXJ0eVRvU3ZnKSA9PiBwcm9wZXJ0eVRvU3ZnLnBJZClcbiAgICAgIC8vIHRha2UgZmlyc3QgTUFYX1NFUlZJQ0VfUFJPUEVSVElFUyByZWdhcmRsZXNzIG9mIHRoZSBpbnB1dCBmcm9tIEJhY2tlbmQsIG90aGVyd2lzZSB0aGUgbGF5b3V0IGNvdWxkIGJlIGRlc3Ryb3llZFxuICAgICAgLnNsaWNlKDAsIE1BWF9TRVJWSUNFX1BST1BFUlRJRVMpO1xuICAgIHJldHVybiBzaHJ1bmtQcm9wZXJ0eUlkcyA/IHNocnVua1Byb3BlcnR5SWRzIDogW107XG4gIH07XG5cbiAgcHJpdmF0ZSBfcHJlcGFyZUNvYWNoV2lkdGhBbmRHYXBDYWxjdWxhdGlvbnMoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuc2VhdFJlc2VydmF0aW9ucykge1xuICAgICAgY29uc3QgY29hY2hJdGVtczogQ29hY2hJdGVtW10gPVxuICAgICAgICB0aGlzLnNlYXRSZXNlcnZhdGlvbnNbdGhpcy5zZWF0UmVzZXJ2YXRpb25zLmxlbmd0aCAtIDFdPy5jb2FjaEl0ZW1zO1xuXG4gICAgICBjb2FjaEl0ZW1zPy5mb3JFYWNoKChjb2FjaEl0ZW06IENvYWNoSXRlbSkgPT4ge1xuICAgICAgICBjb25zdCBoYXNPdmVyaGFuZ2luZ1BsYWNlcyA9IHRoaXMuX2lzT3ZlcmhhbmdpbmdFbGVtZW50c1ByZXNlbnQoXG4gICAgICAgICAgY29hY2hJdGVtLmRpbWVuc2lvbi53LFxuICAgICAgICAgIGNvYWNoSXRlbS5wbGFjZXMsXG4gICAgICAgICk7XG5cbiAgICAgICAgLy9NdXN0ICBiZSBkb25lIGFsc28gZm9yIGdyYXBoaWNhbCBlbGVtZW50cywgYXMgdGhleSBjYW4gYWxzbyBwcm90cnVkZSB0aGUgY29hY2ggYm9yZGVyXG4gICAgICAgIC8vIENoZWNrIG9ubHkgZ3JhcGhpY2FsIGVsZW1lbnRzIHRoYXQgYXJlIG5vdCBhcmVhIGVsZW1lbnRzXG4gICAgICAgIGNvbnN0IGZpbHRlcmVkRWxlbWVudHMgPSBjb2FjaEl0ZW0uZ3JhcGhpY0VsZW1lbnRzPy5maWx0ZXIoXG4gICAgICAgICAgKGUpID0+IGUuaWNvbiAmJiAhdGhpcy5ub3RBcmVhRWxlbWVudHMuaW5jbHVkZXMoZS5pY29uKSxcbiAgICAgICAgKTtcblxuICAgICAgICBjb25zdCBoYXNPdmVyaGFuZ2luZ0dyYXBoaWNBcmVhcyA9IHRoaXMuX2lzT3ZlcmhhbmdpbmdFbGVtZW50c1ByZXNlbnQoXG4gICAgICAgICAgY29hY2hJdGVtLmRpbWVuc2lvbi53LFxuICAgICAgICAgIGZpbHRlcmVkRWxlbWVudHMsXG4gICAgICAgICk7XG5cbiAgICAgICAgdGhpcy5vdmVySGFuZ2luZ0VsZW1lbnRJbmZvcm1hdGlvbi5wdXNoKHtcbiAgICAgICAgICBjb2FjaElkOiBjb2FjaEl0ZW0uaWQsXG4gICAgICAgICAgb3ZlcmhhbmdpbmdQbGFjZXM6IGhhc092ZXJoYW5naW5nUGxhY2VzLFxuICAgICAgICAgIG92ZXJoYW5naW5nR3JhcGhpY0FyZWFzOiBoYXNPdmVyaGFuZ2luZ0dyYXBoaWNBcmVhcyxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgY3VycmVudCBzZWxlY3RlZCBwbGFjZSBIVE1MIGVsZW1lbnQgYnkgY3VyclNlbGVjdGVkUGxhY2VFbGVtZW50SWQuXG4gICAqIEByZXR1cm5zIEhUTUxFbGVtZW50IG9yIG51bGxcbiAgICovXG4gIHByaXZhdGUgX2dldFBsYWNlSHRtbEVsZW1lbnQoKTogSFRNTEVsZW1lbnQgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5jdXJyU2VsZWN0ZWRQbGFjZUVsZW1lbnRJZFxuICAgICAgPyB0aGlzLnNoYWRvd1Jvb3Q/LmdldEVsZW1lbnRCeUlkKHRoaXMuY3VyclNlbGVjdGVkUGxhY2VFbGVtZW50SWQpIHx8IG51bGxcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXR1cm5zIHRoZSBleHRyYWN0ZWQgY29hY2ggZGVjayBpbmRleCBmcm9tIHBsYWNlIGlkXG4gICAqIEByZXR1cm5zIG51bWJlclxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0RGVja0luZGV4QnlQbGFjZUlkKHBsYWNlSWQ6IHN0cmluZyk6IG51bWJlciB8IG51bGwge1xuICAgIGNvbnN0IGRlY2tJbmRleCA9IHRoaXMuc2hhZG93Um9vdFxuICAgICAgPy5xdWVyeVNlbGVjdG9yKCcjJyArIHBsYWNlSWQpXG4gICAgICA/LmdldEF0dHJpYnV0ZSgnZGF0YS1kZWNrLWluZGV4Jyk7XG4gICAgaWYgKGRlY2tJbmRleCAmJiAhaXNOYU4oK2RlY2tJbmRleCkpIHtcbiAgICAgIHJldHVybiArZGVja0luZGV4O1xuICAgIH1cbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuXG4gIHByaXZhdGUgX2lzVmFsaWRDb2FjaEluZGV4KGNvYWNoSW5kZXg6IG51bWJlcik6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICBjb2FjaEluZGV4ID49IDAgJiZcbiAgICAgIGNvYWNoSW5kZXggPD0gdGhpcy5zZWF0UmVzZXJ2YXRpb25zW3RoaXMuc2VhdFJlc2VydmF0aW9ucy5sZW5ndGggLSAxXS5jb2FjaEl0ZW1zLmxlbmd0aFxuICAgICk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyBleGlzdGluZyBjb2FjaCBkZWNrIGluZGV4IGRlcGVuZGluZyBvbiB0aGUgc2VsZWN0ZWQgY29hY2guXG4gICAqIFRoaXMgbWV0aG9kIGlzIG5lY2Vzc2FyeSB0byBnZXQgYW4gYXZhaWxhYmxlIGNvYWNoIGRlY2sgaW5kZXggZHVyaW5nIGtleWJvYXJkIG5hdmlnYXRpb24sIHdoaWNoIGNhbiB2YXJ5IGJldHdlZW4gY29hY2hlcyB3aXRoIGRpZmZlcmVudCBkZWNrcy5cbiAgICogRm9yIGV4YW1wbGUsIHdoZW4gbmF2aWdhdGluZyBmcm9tIGEgY29hY2ggd2l0aCB0d28gZGVja3MgdG8gYSBjb2FjaCB3aXRoIG9uZSBkZWNrLlxuICAgKlxuICAgKiAgICAgICBbb29vXS1bb29vXS1bb29vXVxuICAgKiBbb29vXS1bb29vXS1bb29vXS1bb29vXS1bb29vXVxuICAgKlxuICAgKiBAcmV0dXJucyBudW1iZXJcbiAgICovXG4gIHByaXZhdGUgX2dldEV4aXN0aW5nQ29hY2hEZWNrSW5kZXgoKTogbnVtYmVyIHtcbiAgICBpZiAoXG4gICAgICB0aGlzLnNlYXRSZXNlcnZhdGlvbnNbdGhpcy5jdXJyU2VsZWN0ZWREZWNrSW5kZXhdLmNvYWNoSXRlbXNbdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4XVxuICAgICAgICAucGxhY2VzICE9PSB1bmRlZmluZWRcbiAgICApIHtcbiAgICAgIHJldHVybiB0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleDtcbiAgICB9XG5cbiAgICAvLyBGaW5kIG5leHQgcG9zc2libGUgY29hY2ggZGVjayBpbmRleCB3aGVyZSBwbGFjZXMgZXhpc3RcbiAgICBjb25zdCBuZXh0QXZhaWxhYmxlRGVja0NvYWNoSW5kZXggPSB0aGlzLnNlYXRSZXNlcnZhdGlvbnMuZmluZEluZGV4KFxuICAgICAgKHNlYXRSZXNlcnZhdGlvbikgPT5cbiAgICAgICAgc2VhdFJlc2VydmF0aW9uLmNvYWNoSXRlbXNbdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4XS5wbGFjZXMgIT09IHVuZGVmaW5lZCxcbiAgICApO1xuICAgIHJldHVybiB0aGlzLmN1cnJTZWxlY3RlZERlY2tJbmRleCA+PSBuZXh0QXZhaWxhYmxlRGVja0NvYWNoSW5kZXhcbiAgICAgID8gdGhpcy5jdXJyU2VsZWN0ZWREZWNrSW5kZXhcbiAgICAgIDogbmV4dEF2YWlsYWJsZURlY2tDb2FjaEluZGV4O1xuICB9XG5cbiAgLyoqXG4gICAqIElmIGEgc2VsZWN0ZWQgcGxhY2UgaXMgc2xpZ2h0bHkgaGlkZGVuIGJ5IHRoZSBvdmVyZmxvdyBzY3JvbGwgY29udGVudCBhbmQgaXMgc3RpbGwgY2xpY2tlZCxcbiAgICogdGhlIG1ldGhvZCB0cmllcyB0byBzY3JvbGwgdGhlIHNlbGVjdGVkIHBsYWNlIGludG8gdGhlIG5lYXJlc3Qgdmlld3BvcnQsIHNvIHRoYXQgaXQgaXMgY29tcGxldGVseSB2aXNpYmxlLlxuICAgKlxuICAgKiBAcGFyYW0gcGxhY2VJZFxuICAgKi9cbiAgcHJpdmF0ZSBfc2Nyb2xsUGxhY2VJbnRvTmVhcmVzdFZpZXdwb3J0KHBsYWNlSWQ6IHN0cmluZyk6IHZvaWQge1xuICAgIHRoaXMuc2hhZG93Um9vdFxuICAgICAgPy5nZXRFbGVtZW50QnlJZChwbGFjZUlkKVxuICAgICAgPy5zY3JvbGxJbnRvVmlldyh7IGJlaGF2aW9yOiAnc21vb3RoJywgYmxvY2s6ICduZWFyZXN0JywgaW5saW5lOiAnbmVhcmVzdCcgfSk7XG4gIH1cblxuICAvKipcbiAgICogY2hlY2tzIGlmIGFueSBwbGFjZXMgb3IgZ3JhcGhpY2FsIGVsZW1lbnRzIChlLmcuIHRvaWxldCBhcmVhLCBldGMuKSBhcmUgb3ZlcmhhbmdpbmcgdGhlIGNvYWNoIGJvcmRlcnNcbiAgICogQHBhcmFtIGNvYWNoSXRlbVdpZHRoXG4gICAqIEBwYXJhbSBlbGVtZW50c1xuICAgKi9cbiAgcHJpdmF0ZSBfaXNPdmVyaGFuZ2luZ0VsZW1lbnRzUHJlc2VudChcbiAgICBjb2FjaEl0ZW1XaWR0aDogbnVtYmVyLFxuICAgIGVsZW1lbnRzOiAoUGxhY2UgfCBCYXNlRWxlbWVudClbXSB8IHVuZGVmaW5lZCxcbiAgKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIChcbiAgICAgIGVsZW1lbnRzPy5zb21lKFxuICAgICAgICAoZWxlbWVudCkgPT5cbiAgICAgICAgICBlbGVtZW50LnBvc2l0aW9uLnggPT09IDAgfHwgZWxlbWVudC5wb3NpdGlvbi54ICsgZWxlbWVudC5kaW1lbnNpb24udyA+PSBjb2FjaEl0ZW1XaWR0aCxcbiAgICAgICkgPz8gZmFsc2VcbiAgICApO1xuICB9XG59XG4iXSwibmFtZXMiOlsiU2Nyb2xsRGlyZWN0aW9uIiwiYWNjdW11bGF0b3IiLCJwbGFjZSIsImNvYWNoIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBNEJBLElBQUs7QUFBQSxDQUFMLFNBQUtBLGtCQUFlO0FBQ2xCQSxtQkFBQSxPQUFBLElBQUE7QUFDQUEsbUJBQUEsTUFBQSxJQUFBO0FBQ0YsR0FISyxvQkFBQSxrQkFBZSxDQUFBLEVBQUE7QUFXcEIsTUFBTSx5QkFBeUI7QUFDL0IsTUFBTSx3QkFBa0M7QUFBQSxFQUN0QztBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTtBQUFBLEVBQ0E7QUFBQSxFQUNBO0FBQUEsRUFDQTs7SUFHVyw4QkFBMEIsTUFBQTs7b0JBQVM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUFuQyxTQUFBLG1CQUFtQyxZQUFVO0FBQUE7O0FBUXhEO0FBS0E7QUFLQTtBQUtBO0FBS0E7QUFLQTtBQUtBO0FBS0E7QUFJQTtBQUVTO0FBQ0E7QUFDQTtBQTND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