@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,832 @@
1
+ import { __esDecorate, __runInitializers } from "tslib";
2
+ import { SbbLanguageController } from "@sbb-esta/lyne-elements/core/controllers.js";
3
+ import { boxSizingStyles } from "@sbb-esta/lyne-elements/core/styles.js";
4
+ import { css, html, nothing } from "lit";
5
+ import { customElement } from "lit/decorators.js";
6
+ import { classMap } from "lit/directives/class-map.js";
7
+ import { repeat } from "lit/directives/repeat.js";
8
+ import { styleMap } from "lit/directives/style-map.js";
9
+ import { getI18nSeatReservation } from "../common.js";
10
+ import { SeatReservationBaseElement } from "./seat-reservation-base-element.js";
11
+ import "@sbb-esta/lyne-elements/button.js";
12
+ import "@sbb-esta/lyne-elements/screen-reader-only.js";
13
+ import "@sbb-esta/lyne-elements/popover.js";
14
+ import "../seat-reservation-area.js";
15
+ import "../seat-reservation-graphic.js";
16
+ import "../seat-reservation-place-control.js";
17
+ import "../seat-reservation-navigation-coach.js";
18
+ import "../seat-reservation-scoped.js";
19
+ const style = css`:host {
20
+ --sbb-seat-reservation-grid-size: 16px;
21
+ --sbb-seat-reservation-height: 0;
22
+ --sbb-seat-reservation-decks: 1;
23
+ display: block;
24
+ height: inherit;
25
+ }
26
+ :host ::part(coach-floor) {
27
+ fill: var(--sbb-background-color-2);
28
+ }
29
+ @media (forced-colors: active) {
30
+ :host ::part(coach-floor) {
31
+ fill: transparent;
32
+ }
33
+ }
34
+
35
+ :host(:dir(rtl)) :not(.sbb-sr-place-ctrl--type-bicycle,
36
+ .sbb-sr-place-ctrl--orientation-90,
37
+ .sbb-sr-place-ctrl--orientation-270,
38
+ .sbb-sr-place-ctrl--state-selected) ::part(coach-floor) {
39
+ rotate: calc(180 * 1deg);
40
+ }
41
+
42
+ [popover]:where(sbb-popover) {
43
+ margin: 0;
44
+ padding: 0;
45
+ border: none;
46
+ width: auto;
47
+ height: auto;
48
+ background-color: transparent;
49
+ color: inherit;
50
+ pointer-events: none;
51
+ }
52
+ [popover]:where(sbb-popover) .sbb-sr-popover {
53
+ margin-block: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
54
+ }
55
+
56
+ :host([align-vertical]) .sbb-sr__component {
57
+ flex-direction: row-reverse;
58
+ justify-content: flex-end;
59
+ gap: calc(22 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
60
+ height: inherit;
61
+ }
62
+ @media (min-width: calc(37.5rem)) {
63
+ :host([align-vertical]) .sbb-sr__component {
64
+ gap: calc(54 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
65
+ }
66
+ }
67
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation,
68
+ :host([align-vertical]) .sbb-sr__component ul.sbb-sr-navigation__list-coaches {
69
+ flex-direction: column;
70
+ }
71
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation {
72
+ padding: calc(16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) 0;
73
+ }
74
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation .sbb-sr__navigation-control-button {
75
+ left: calc(1 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
76
+ top: 0;
77
+ rotate: 90deg;
78
+ }
79
+ @media (min-width: calc(64rem)) {
80
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation .sbb-sr__navigation-control-button {
81
+ left: calc(-1 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
82
+ }
83
+ }
84
+ :host([align-vertical]) .sbb-sr__component nav.sbb-sr-navigation ul.sbb-sr-navigation__list-coaches {
85
+ max-width: initial;
86
+ padding: calc(5 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
87
+ overflow: hidden scroll;
88
+ }
89
+ :host([align-vertical]) .sbb-sr__wrapper-coach-decks {
90
+ flex-direction: column;
91
+ }
92
+ :host([align-vertical]) .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels {
93
+ flex-direction: column-reverse;
94
+ width: calc((var(--sbb-seat-reservation-height) + 24) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
95
+ height: initial;
96
+ }
97
+ :host([align-vertical]) .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels b {
98
+ inline-size: calc(50% - 16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
99
+ block-size: calc(20 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
100
+ margin-bottom: calc(16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
101
+ rotate: initial;
102
+ writing-mode: initial;
103
+ }
104
+ :host([align-vertical]) .sbb-sr__wrapper-scrollarea {
105
+ width: calc((var(--sbb-seat-reservation-height) + 24) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
106
+ height: 100%;
107
+ overflow: hidden scroll;
108
+ }
109
+ :host([align-vertical]) .sbb-sr__wrapper-scrollarea .sbb-sr__parent {
110
+ flex-direction: row;
111
+ rotate: 90deg;
112
+ }
113
+
114
+ .sbb-sr-navigation {
115
+ gap: calc(3 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
116
+ }
117
+
118
+ .sbb-sr-navigation .sbb-sr__navigation-control-button {
119
+ position: relative;
120
+ top: calc(2 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
121
+ }
122
+ @media (min-width: calc(64rem)) {
123
+ .sbb-sr-navigation .sbb-sr__navigation-control-button {
124
+ top: 0;
125
+ }
126
+ }
127
+
128
+ .sbb-sr__component {
129
+ display: flex;
130
+ flex-direction: column;
131
+ gap: calc(64 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem) - 16px);
132
+ }
133
+
134
+ .sbb-sr-navigation-wrapper {
135
+ display: flex;
136
+ }
137
+
138
+ .sbb-sr-navigation {
139
+ display: flex;
140
+ justify-content: center;
141
+ width: 100%;
142
+ padding-inline: 16px;
143
+ }
144
+
145
+ .sbb-sr-navigation__list-coaches {
146
+ list-style: none;
147
+ margin: 0;
148
+ padding: 0;
149
+ font-size: inherit;
150
+ --sbb-scrollbar-thumb-width: 0.125rem;
151
+ --sbb-scrollbar-thumb-width-hover: 0.25rem;
152
+ --sbb-scrollbar-width-firefox: thin;
153
+ --sbb-scrollbar-color: color-mix(in srgb, var(--sbb-color-black) 30%, transparent);
154
+ --sbb-scrollbar-color: light-dark(
155
+ color-mix(in srgb, var(--sbb-color-black) 30%, transparent),
156
+ color-mix(in srgb, var(--sbb-color-white) 30%, transparent)
157
+ );
158
+ --sbb-scrollbar-color-hover: color-mix(in srgb, var(--sbb-color-black) 60%, transparent);
159
+ --sbb-scrollbar-color-hover: light-dark(
160
+ color-mix(in srgb, var(--sbb-color-black) 60%, transparent),
161
+ color-mix(in srgb, var(--sbb-color-white) 60%, transparent)
162
+ );
163
+ --sbb-scrollbar-track-color: transparent;
164
+ --sbb-scrollbar-width: var(--sbb-spacing-fixed-3x);
165
+ }
166
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar {
167
+ width: var(--sbb-scrollbar-width);
168
+ height: var(--sbb-scrollbar-width);
169
+ background-color: var(--sbb-scrollbar-track-color, transparent);
170
+ }
171
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar-corner {
172
+ background-color: var(--sbb-scrollbar-track-color, transparent);
173
+ }
174
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar-thumb {
175
+ background-color: var(--sbb-scrollbar-color, currentcolor);
176
+ border: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width))) solid transparent;
177
+ border-radius: var(--sbb-border-radius-4x);
178
+ background-clip: padding-box;
179
+ }
180
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar-thumb:hover {
181
+ background-color: var(--sbb-scrollbar-color-hover, currentcolor);
182
+ border-width: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width-hover)));
183
+ }
184
+ .sbb-sr-navigation__list-coaches::-webkit-scrollbar-button, .sbb-sr-navigation__list-coaches::-webkit-scrollbar-corner {
185
+ display: none;
186
+ }
187
+ @supports not selector(::-webkit-scrollbar) {
188
+ .sbb-sr-navigation__list-coaches {
189
+ scrollbar-width: var(--sbb-scrollbar-width-firefox);
190
+ scrollbar-color: var(--sbb-scrollbar-color, currentcolor) var(--sbb-scrollbar-track-color, transparent);
191
+ }
192
+ }
193
+ .sbb-sr-navigation__list-coaches {
194
+ display: flex;
195
+ flex-wrap: nowrap;
196
+ gap: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
197
+ padding: calc(6 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) calc(5 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) 0;
198
+ max-width: 856px;
199
+ --sbb-scrollbar-color: transparent;
200
+ overflow: scroll hidden;
201
+ position: relative;
202
+ }
203
+
204
+ .sbb-sr__wrapper-coach-decks {
205
+ display: flex;
206
+ overflow: hidden;
207
+ height: inherit;
208
+ }
209
+ .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels {
210
+ display: flex;
211
+ justify-content: space-between;
212
+ height: calc(var(--sbb-seat-reservation-height) * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
213
+ writing-mode: vertical-lr;
214
+ }
215
+ .sbb-sr__wrapper-coach-decks .sbb-sr__wrapper-deck-labels b {
216
+ height: calc(50% - 16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
217
+ width: calc(20 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
218
+ margin-block-end: 16px;
219
+ rotate: 180deg;
220
+ text-align: center;
221
+ line-height: calc(20 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
222
+ }
223
+
224
+ .sbb-sr__wrapper-scrollarea {
225
+ --sbb-scrollbar-thumb-width: 0.125rem;
226
+ --sbb-scrollbar-thumb-width-hover: 0.25rem;
227
+ --sbb-scrollbar-width-firefox: thin;
228
+ --sbb-scrollbar-color: color-mix(in srgb, var(--sbb-color-black) 30%, transparent);
229
+ --sbb-scrollbar-color: light-dark(
230
+ color-mix(in srgb, var(--sbb-color-black) 30%, transparent),
231
+ color-mix(in srgb, var(--sbb-color-white) 30%, transparent)
232
+ );
233
+ --sbb-scrollbar-color-hover: color-mix(in srgb, var(--sbb-color-black) 60%, transparent);
234
+ --sbb-scrollbar-color-hover: light-dark(
235
+ color-mix(in srgb, var(--sbb-color-black) 60%, transparent),
236
+ color-mix(in srgb, var(--sbb-color-white) 60%, transparent)
237
+ );
238
+ --sbb-scrollbar-track-color: transparent;
239
+ --sbb-scrollbar-width: var(--sbb-spacing-fixed-3x);
240
+ }
241
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar {
242
+ width: var(--sbb-scrollbar-width);
243
+ height: var(--sbb-scrollbar-width);
244
+ background-color: var(--sbb-scrollbar-track-color, transparent);
245
+ }
246
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-corner {
247
+ background-color: var(--sbb-scrollbar-track-color, transparent);
248
+ }
249
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-thumb {
250
+ background-color: var(--sbb-scrollbar-color, currentcolor);
251
+ border: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width))) solid transparent;
252
+ border-radius: var(--sbb-border-radius-4x);
253
+ background-clip: padding-box;
254
+ }
255
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-thumb:hover {
256
+ background-color: var(--sbb-scrollbar-color-hover, currentcolor);
257
+ border-width: calc(0.5 * (var(--sbb-scrollbar-width) - var(--sbb-scrollbar-thumb-width-hover)));
258
+ }
259
+ .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-button, .sbb-sr__wrapper-scrollarea::-webkit-scrollbar-corner {
260
+ display: none;
261
+ }
262
+ @supports not selector(::-webkit-scrollbar) {
263
+ .sbb-sr__wrapper-scrollarea {
264
+ scrollbar-width: var(--sbb-scrollbar-width-firefox);
265
+ scrollbar-color: var(--sbb-scrollbar-color, currentcolor) var(--sbb-scrollbar-track-color, transparent);
266
+ }
267
+ }
268
+ .sbb-sr__wrapper-scrollarea {
269
+ overflow: scroll hidden;
270
+ padding-block: calc(8 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem)) calc(16 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
271
+ }
272
+ .sbb-sr__wrapper-scrollarea .sbb-sr__parent {
273
+ display: flex;
274
+ flex-direction: column;
275
+ position: relative;
276
+ }
277
+
278
+ .sbb-sr__list-decks {
279
+ list-style: none;
280
+ margin: 0;
281
+ padding: 0;
282
+ font-size: inherit;
283
+ display: flex;
284
+ flex-direction: column;
285
+ }
286
+
287
+ .sbb-sr__list-decks--gap {
288
+ gap: calc(48 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
289
+ }
290
+
291
+ .sbb-sr__list-item-deck {
292
+ position: relative;
293
+ }
294
+
295
+ .sbb-sr__list-coaches {
296
+ list-style: none;
297
+ margin: 0;
298
+ padding: 0;
299
+ font-size: inherit;
300
+ display: flex;
301
+ gap: calc(4 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
302
+ }
303
+
304
+ .sbb-sr__list-decks:has(.sbb-sr-coach-has-overhanging-elements) .sbb-sr__list-coaches {
305
+ gap: calc(8 * var(--sbb-seat-reservation-one-px-rem, 0.0625rem));
306
+ }
307
+
308
+ .sbb-sr__item-coach {
309
+ position: relative;
310
+ }
311
+
312
+ .sbb-sr-coach-wrapper__table {
313
+ outline: 0;
314
+ }`;
315
+ let SbbSeatReservationElement = (() => {
316
+ var _a;
317
+ let _classDecorators = [customElement("sbb-seat-reservation")];
318
+ let _classDescriptor;
319
+ let _classExtraInitializers = [];
320
+ let _classThis;
321
+ let _classSuper = SeatReservationBaseElement;
322
+ _a = class extends _classSuper {
323
+ constructor() {
324
+ super(...arguments);
325
+ this._language = new SbbLanguageController(this);
326
+ this._notFixedRotatableAreaIcons = ["ENTRY_EXIT"];
327
+ }
328
+ willUpdate(changedProperties) {
329
+ super.willUpdate(changedProperties);
330
+ if (changedProperties.has("hasNavigation")) {
331
+ if (this.hasNavigation) {
332
+ this.shadowRoot?.querySelectorAll("table").forEach((table) => table.removeAttribute("tabindex"));
333
+ } else {
334
+ this.shadowRoot?.querySelectorAll("table").forEach((table) => table.setAttribute("tabindex", "0"));
335
+ }
336
+ }
337
+ }
338
+ firstUpdated(changedProperties) {
339
+ super.firstUpdated(changedProperties);
340
+ this.updateComplete.then(() => {
341
+ this.initNavigationSelectionByScrollEvent();
342
+ });
343
+ }
344
+ render() {
345
+ this._initVehicleSeatReservationConstruction();
346
+ return this._coachesHtmlTemplate || null;
347
+ }
348
+ _initVehicleSeatReservationConstruction() {
349
+ this._coachesHtmlTemplate = html`
350
+ <div class="sbb-sr__component">
351
+ ${this._renderNavigation()}
352
+ <div
353
+ class="sbb-sr__wrapper-coach-decks"
354
+ @keydown=${(evt) => this.keyboardSeatmapEventHandling(evt)}
355
+ >
356
+ <div class="sbb-sr__wrapper-deck-labels">${this._renderDeckLabels()}</div>
357
+ <div
358
+ @scroll=${() => this.coachAreaScrollend()}
359
+ id="sbb-sr__wrapper-scrollarea"
360
+ class="sbb-sr__wrapper-scrollarea"
361
+ tabindex="0"
362
+ >
363
+ <div id="sbb-sr__parent-area" class="sbb-sr__parent">
364
+ <ul
365
+ class="${classMap({
366
+ "sbb-sr__list-decks": true,
367
+ "sbb-sr__list-decks--gap": this.hasMultipleDecks
368
+ })}"
369
+ >
370
+ ${this.seatReservations?.map((seatReservation, coachDeckIndex) => {
371
+ return html`<li class="sbb-sr__list-item-deck">
372
+ <ul class="sbb-sr__list-coaches" role="presentation">
373
+ ${this._renderCoaches(seatReservation, coachDeckIndex)}
374
+ </ul>
375
+ </li>`;
376
+ })}
377
+ </ul>
378
+ </div>
379
+ </div>
380
+ </div>
381
+ </div>
382
+ `;
383
+ }
384
+ _renderDeckLabels() {
385
+ if (!this.hasMultipleDecks)
386
+ return null;
387
+ return this.seatReservations.map((seatReservation) => {
388
+ const deckDescription = getI18nSeatReservation(seatReservation.deckCoachLevel, this._language.current);
389
+ return html`<b aria-hidden="true">${deckDescription}</b>`;
390
+ });
391
+ }
392
+ _renderNavigationControlButton(btnDirection) {
393
+ if (!this.hasNavigation || !this.seatReservations)
394
+ return null;
395
+ const btnNavigationDirectionId = btnDirection == "DIRECTION_RIGHT" ? "sbb-sr-navigation__wrapper-button-direction--right" : "sbb-sr-navigation__wrapper-button-direction--left";
396
+ const btnIcon = btnDirection == "DIRECTION_RIGHT" ? "chevron-small-right-small" : "chevron-small-left-small";
397
+ const btnAriaDescription = btnDirection == "DIRECTION_RIGHT" ? getI18nSeatReservation("SEAT_RESERVATION_END", this._language.current) : getI18nSeatReservation("SEAT_RESERVATION_BEGIN", this._language.current);
398
+ let btnDisabled = true;
399
+ if (btnDirection == "DIRECTION_LEFT" && this.selectedCoachIndex > 0) {
400
+ btnDisabled = false;
401
+ } else if (btnDirection == "DIRECTION_RIGHT" && this.selectedCoachIndex < this.coachNavData.length - 1) {
402
+ btnDisabled = false;
403
+ }
404
+ return html`<div class="sbb-sr-navigation__wrapper-button-direction">
405
+ <sbb-secondary-button
406
+ @click="${() => this.navigateByDirectionBtn(btnDirection)}"
407
+ @focus="${() => this.onFocusNavDirectionButton()}"
408
+ id="${btnNavigationDirectionId}"
409
+ class="sbb-sr__navigation-control-button"
410
+ size="m"
411
+ icon-name="${btnIcon}"
412
+ type="button"
413
+ aria-label="${btnAriaDescription}"
414
+ role="button"
415
+ .disabledInteractive="${btnDisabled || nothing}"
416
+ .disabled="${btnDisabled || nothing}"
417
+ ></sbb-secondary-button>
418
+ </div>`;
419
+ }
420
+ _renderNavigation() {
421
+ if (!this.hasNavigation || !this.seatReservations)
422
+ return null;
423
+ return html`<div class="sbb-sr-navigation-wrapper">
424
+ <nav id="sbb-sr-navigation" class="sbb-sr-navigation">
425
+ ${this._renderNavigationControlButton("DIRECTION_LEFT")}
426
+ <ul
427
+ id="sbb-sr__navigation-list-coaches"
428
+ class="sbb-sr-navigation__list-coaches"
429
+ aria-label="${getI18nSeatReservation("SEAT_RESERVATION_NAVIGATION", this._language.current)}"
430
+ >
431
+ ${this.coachNavData.map((navigationCoach, index) => {
432
+ return html`<li>
433
+ <sbb-seat-reservation-navigation-coach
434
+ @selectcoach=${(event) => this._onSelectNavCoach(event)}
435
+ @focuscoach=${() => this._onFocusNavCoach()}
436
+ @keyup=${(evt) => this.onKeyNavigationNavCoachButton(evt, index)}
437
+ index="${index}"
438
+ coach-id="${navigationCoach.id}"
439
+ .freePlacesByType="${navigationCoach.freePlaces}"
440
+ .selected=${this.selectedCoachIndex === index}
441
+ .focused=${this.focusedCoachIndex === index}
442
+ .hovered=${this.hoveredCoachIndex === index}
443
+ .nativeFocusActive=${this.hasSeatReservationNativeFocus}
444
+ .propertyIds="${navigationCoach.propertyIds}"
445
+ .travelClass="${navigationCoach.travelClass}"
446
+ ?driver-area="${navigationCoach.isDriverArea}"
447
+ ?first="${navigationCoach?.driverAreaSide?.left}"
448
+ ?last="${navigationCoach?.driverAreaSide?.right}"
449
+ ?vertical="${this.alignVertical}"
450
+ >
451
+ </sbb-seat-reservation-navigation-coach>
452
+ </li>`;
453
+ })}
454
+ </ul>
455
+ ${this._renderNavigationControlButton("DIRECTION_RIGHT")}
456
+ </nav>
457
+ </div>`;
458
+ }
459
+ /**
460
+ *
461
+ * @returns
462
+ * @param seatReservation
463
+ * @param coachDeckIndex
464
+ */
465
+ _renderCoaches(seatReservation, coachDeckIndex) {
466
+ const coaches = JSON.parse(JSON.stringify(seatReservation?.coachItems));
467
+ if (!coaches) {
468
+ return null;
469
+ }
470
+ return coaches.map((coachItem, coachIndex) => {
471
+ return html`
472
+ <li class="sbb-sr__item-coach">
473
+ ${this._renderCoachElement(coachItem, coachIndex, coachDeckIndex, seatReservation.deckCoachIndex)}
474
+ </li>
475
+ `;
476
+ });
477
+ }
478
+ _renderCoachElement(coachItem, coachIndex, coachDeckIndex, placeCoachDeckIndex) {
479
+ const calculatedCoachDimension = this.getCalculatedDimension(coachItem.dimension);
480
+ const descriptionTableCoachWithServices = this._getDescriptionTableCoach(coachItem);
481
+ return html`<sbb-seat-reservation-scoped
482
+ style=${styleMap({
483
+ "--sbb-seat-reservation-scoped-width": calculatedCoachDimension.w,
484
+ "--sbb-seat-reservation-scoped-height": calculatedCoachDimension.h
485
+ })}
486
+ >
487
+ ${this._getRenderedCoachBorders(coachItem)}
488
+ ${this._getRenderedGraphicalElements(coachItem.graphicElements || [], coachItem.dimension, coachIndex, coachDeckIndex)}
489
+ ${this._getRenderedServiceElements(coachIndex, coachDeckIndex, coachItem.serviceElements)}
490
+
491
+ <table
492
+ @focus=${() => this.onFocusTableCoachAndPreselectPlace(coachIndex)}
493
+ id="sbb-sr-coach-${coachIndex}"
494
+ class="sbb-sr-coach-wrapper__table"
495
+ aria-describedby="sbb-sr-coach-caption-${coachIndex}"
496
+ tabindex="-1"
497
+ >
498
+ <caption id="sbb-sr-coach-caption-${coachIndex}" tabindex="-1">
499
+ <sbb-screen-reader-only>${descriptionTableCoachWithServices}</sbb-screen-reader-only>
500
+ </caption>
501
+ ${this._getRenderedRowPlaces(coachItem, coachIndex, coachDeckIndex, placeCoachDeckIndex)}
502
+ </table>
503
+ </sbb-seat-reservation-scoped>`;
504
+ }
505
+ /**
506
+ * @returns Returns the border graphic (COACH_BORDER_MIDDLE) of a coach with calculated border gap and coach width,
507
+ * depending on whether the coach is with a driver area or without.
508
+ */
509
+ _getRenderedCoachBorders(coachItem) {
510
+ if (!coachItem.graphicElements)
511
+ return null;
512
+ const COACH_PASSAGE_WIDTH = 1;
513
+ const allElements = coachItem.graphicElements;
514
+ const driverArea = allElements?.find((element) => element.icon === "DRIVER_AREA");
515
+ let borderWidth = driverArea ? coachItem.dimension.w - driverArea.dimension.w - COACH_PASSAGE_WIDTH : coachItem.dimension.w - COACH_PASSAGE_WIDTH * 2;
516
+ borderWidth *= this.baseGridSize;
517
+ const borderHeight = (coachItem.dimension.h + this.coachBorderOffset * 2) * this.baseGridSize;
518
+ let borderOffsetX = driverArea && driverArea.position.x === 0 ? driverArea?.dimension.w * this.baseGridSize : this.baseGridSize;
519
+ const currentCoachOverlappingInfo = this.overHangingElementInformation.find((el) => el.coachId == coachItem.id);
520
+ if (currentCoachOverlappingInfo?.overhangingPlaces || currentCoachOverlappingInfo?.overhangingGraphicAreas) {
521
+ borderWidth += 2 * this.baseGridSize;
522
+ borderOffsetX = 0;
523
+ }
524
+ return html`
525
+ <sbb-seat-reservation-graphic
526
+ class="${classMap({
527
+ "sbb-sr-coach-has-overhanging-elements": currentCoachOverlappingInfo?.overhangingPlaces || currentCoachOverlappingInfo?.overhangingGraphicAreas || false
528
+ })}"
529
+ style=${styleMap({
530
+ "--sbb-seat-reservation-graphic-width": borderWidth,
531
+ "--sbb-seat-reservation-graphic-height": borderHeight,
532
+ "--sbb-seat-reservation-graphic-top": this.coachBorderPadding * -1,
533
+ "--sbb-seat-reservation-graphic-left": borderOffsetX,
534
+ "--sbb-seat-reservation-graphic-position": "absolute"
535
+ })}
536
+ name="COACH_BORDER_MIDDLE"
537
+ ?stretch=${true}
538
+ role="presentation"
539
+ ></sbb-seat-reservation-graphic>
540
+ `;
541
+ }
542
+ _getRenderedRowPlaces(coach, coachIndex, coachDeckIndex, placeCoachDeckIndex) {
543
+ if (!coach.places) {
544
+ return null;
545
+ }
546
+ const tableRowPlaces = {};
547
+ for (const place of coach.places) {
548
+ if (!tableRowPlaces[place.position.y]) {
549
+ tableRowPlaces[place.position.y] = [place];
550
+ } else {
551
+ tableRowPlaces[place.position.y].push(place);
552
+ }
553
+ }
554
+ return Object.values(tableRowPlaces).map((rowPlaces, index) => {
555
+ return html`
556
+ <tr id="row-${coachIndex}-${rowPlaces[0].position.y}" data-row-index=${index}>
557
+ ${this._getRenderedColumnPlaces(rowPlaces, coachIndex, coachDeckIndex, placeCoachDeckIndex)}
558
+ </tr>
559
+ `;
560
+ }).flatMap((rowTemplate) => rowTemplate);
561
+ }
562
+ _getRenderedColumnPlaces(places, coachIndex, deckIndex, placeCoachDeckIndex) {
563
+ places.sort((placeA, placeB) => Number(placeA.position.x) - Number(placeB.position.x));
564
+ const trackPlaceId = coachIndex + "-" + placeCoachDeckIndex;
565
+ return html`${repeat(places, (place) => trackPlaceId + "-" + place.number, (place, index) => {
566
+ const calculatedDimension = this.getCalculatedDimension(place.dimension);
567
+ const calculatedPosition = this.getCalculatedPosition(place.position);
568
+ const rotation = place.rotation || 0;
569
+ const textRotation = this.alignVertical ? -90 : 0;
570
+ const placeId = this.getPlaceElementId(deckIndex, coachIndex, place.number);
571
+ return html`
572
+ <td
573
+ id="cell-${deckIndex}-${coachIndex}-${place.position.y}-${index}"
574
+ class="graphical-element"
575
+ >
576
+ <sbb-seat-reservation-place-control
577
+ style=${styleMap({
578
+ "--sbb-seat-reservation-place-control-text-scale-value": Math.min(calculatedDimension.w, calculatedDimension.h),
579
+ "--sbb-seat-reservation-place-control-width": calculatedDimension.w,
580
+ "--sbb-seat-reservation-place-control-height": calculatedDimension.h,
581
+ "--sbb-seat-reservation-place-control-top": calculatedPosition.y,
582
+ "--sbb-seat-reservation-place-control-left": calculatedPosition.x,
583
+ "--sbb-seat-reservation-place-control-rotation": rotation,
584
+ "--sbb-seat-reservation-place-control-text-rotation": textRotation
585
+ })}
586
+ @selectplace=${(selectPlaceEvent) => this._onSelectPlace(selectPlaceEvent)}
587
+ exportparts="sbb-sr-place-part"
588
+ id=${placeId}
589
+ class="seat-reservation-place-control"
590
+ text=${place.number}
591
+ type=${place.type}
592
+ state=${place.state}
593
+ coach-index=${coachIndex}
594
+ deck-index=${placeCoachDeckIndex}
595
+ data-deck-index=${deckIndex}
596
+ .propertyIds=${place.propertyIds}
597
+ .preventClick=${this.preventPlaceClick}
598
+ ></sbb-seat-reservation-place-control>
599
+ </td>
600
+ `;
601
+ })}`;
602
+ }
603
+ _getRenderedGraphicalElements(graphicalElements, coachDimension, coachIndex, coachDeckIndex) {
604
+ if (!graphicalElements)
605
+ return null;
606
+ return graphicalElements?.map((graphicalElement) => {
607
+ const icon = graphicalElement.icon ?? "";
608
+ const elementRotation = graphicalElement.rotation || 0;
609
+ const isNotFixedRotationGraphicalElement = this._notFixedRotatableAreaIcons.indexOf(graphicalElement.icon) === -1;
610
+ const elementFixedRotation = this.alignVertical && isNotFixedRotationGraphicalElement ? elementRotation - 90 : elementRotation;
611
+ if (this.notAreaElements.findIndex((notAreaElement) => notAreaElement === icon) > -1) {
612
+ return this._getRenderElementWithoutArea(graphicalElement, elementRotation, coachDimension);
613
+ }
614
+ return this._getRenderElementWithArea(graphicalElement, elementFixedRotation, coachDimension, coachIndex, coachDeckIndex);
615
+ });
616
+ }
617
+ /**
618
+ * creates a rendered element with an area component
619
+ * @param graphicalElement
620
+ * @param rotation
621
+ * @param coachDimension
622
+ * @param coachIndex used to generate a unique id for the popover trigger
623
+ * @param coachDeckIndex used to generate a unique id
624
+ * @private
625
+ */
626
+ _getRenderElementWithArea(graphicalElement, rotation, coachDimension, coachIndex, coachDeckIndex) {
627
+ const isNotTableGraphic = graphicalElement.icon?.indexOf("TABLE") === -1;
628
+ const areaProperty = graphicalElement.icon && isNotTableGraphic ? graphicalElement.icon : null;
629
+ const stretchHeight = this.isElementDirectlyOnBorder(graphicalElement, coachDimension) && areaProperty !== "ENTRY_EXIT";
630
+ const ariaLabelForArea = graphicalElement.icon ? getI18nSeatReservation(graphicalElement.icon, this._language.current) : nothing;
631
+ const calculatedDimension = this.getCalculatedDimension(graphicalElement.dimension, coachDimension, true, stretchHeight);
632
+ const calculatedPosition = this.getCalculatedPosition(graphicalElement.position, graphicalElement.dimension, coachDimension, true);
633
+ const triggerId = `popover-trigger-${coachDeckIndex}-${coachIndex}-${calculatedPosition.x}-${calculatedPosition.y}`;
634
+ let elementMounting = "free";
635
+ if (graphicalElement.position.y === this.coachBorderOffset * -1) {
636
+ elementMounting = "upper-border";
637
+ } else if (graphicalElement.position.y + graphicalElement.dimension.h === coachDimension.h + this.coachBorderOffset) {
638
+ elementMounting = "lower-border";
639
+ }
640
+ if (elementMounting !== "free") {
641
+ calculatedPosition.y += elementMounting === "upper-border" ? 2 : 1;
642
+ calculatedDimension.h -= 3;
643
+ }
644
+ return html`
645
+ <sbb-seat-reservation-area
646
+ id="${triggerId}"
647
+ class="${classMap({ "sbb-seat-reservation-area--cursor-pointer": areaProperty !== null })}"
648
+ style=${styleMap({
649
+ "--sbb-seat-reservation-area-width": calculatedDimension.w,
650
+ "--sbb-seat-reservation-area-height": calculatedDimension.h,
651
+ "--sbb-seat-reservation-area-top": calculatedPosition.y,
652
+ "--sbb-seat-reservation-area-left": calculatedPosition.x
653
+ })}
654
+ mounting=${elementMounting}
655
+ background="dark"
656
+ aria-hidden="true"
657
+ >
658
+ ${areaProperty ? html`
659
+ <sbb-seat-reservation-graphic
660
+ style=${styleMap({
661
+ "--sbb-seat-reservation-graphic-max-width": calculatedDimension.w,
662
+ "--sbb-seat-reservation-graphic-height": this.baseGridSize,
663
+ "--sbb-seat-reservation-graphic-rotation": rotation
664
+ })}
665
+ name=${areaProperty}
666
+ role="img"
667
+ aria-hidden="true"
668
+ class="auto-width"
669
+ ></sbb-seat-reservation-graphic>
670
+ ` : nothing}
671
+ </sbb-seat-reservation-area>
672
+ ${areaProperty ? this._popover(triggerId, ariaLabelForArea) : nothing}
673
+ `;
674
+ }
675
+ _getRenderElementWithoutArea(graphicalElement, rotation, coachDimension) {
676
+ const calculatedDimension = this.getCalculatedDimension(graphicalElement.dimension, coachDimension);
677
+ const calculatedPosition = this.getCalculatedPosition(graphicalElement.position, graphicalElement.dimension, coachDimension);
678
+ const icon = graphicalElement.icon && graphicalElement.icon.indexOf("DRIVER_AREA") === -1 ? graphicalElement.icon : graphicalElement.icon?.concat("_", this.seatReservations[this.currSelectedDeckIndex].vehicleType);
679
+ return html` <sbb-seat-reservation-graphic
680
+ style=${styleMap({
681
+ "--sbb-seat-reservation-graphic-width": calculatedDimension.w,
682
+ "--sbb-seat-reservation-graphic-height": calculatedDimension.h,
683
+ "--sbb-seat-reservation-graphic-top": calculatedPosition.y,
684
+ "--sbb-seat-reservation-graphic-left": calculatedPosition.x,
685
+ "--sbb-seat-reservation-graphic-position": "absolute",
686
+ "--sbb-seat-reservation-graphic-rotation": rotation
687
+ })}
688
+ name=${icon ?? nothing}
689
+ aria-hidden="true"
690
+ ?stretch=${true}
691
+ ></sbb-seat-reservation-graphic>`;
692
+ }
693
+ _getRenderedServiceElements(coachIndex, coachDeckIndex, serviceElements) {
694
+ if (!serviceElements)
695
+ return null;
696
+ return serviceElements?.map((serviceElement) => {
697
+ const titleDescription = serviceElement.icon ? getI18nSeatReservation(serviceElement.icon, this._language.current) : null;
698
+ const calculatedDimension = this.getCalculatedDimension(serviceElement.dimension);
699
+ const calculatedPosition = this.getCalculatedPosition(serviceElement.position);
700
+ const elementRotation = serviceElement.rotation || 0;
701
+ const elementFixedRotation = this.alignVertical ? elementRotation - 90 : elementRotation;
702
+ const triggerId = `popover-trigger-${coachDeckIndex}-${coachIndex}-${calculatedPosition.x}-${calculatedPosition.y}`;
703
+ return html`
704
+ <sbb-seat-reservation-graphic
705
+ id="${triggerId}"
706
+ style=${styleMap({
707
+ "--sbb-seat-reservation-graphic-width": calculatedDimension.w,
708
+ "--sbb-seat-reservation-graphic-height": calculatedDimension.h,
709
+ "--sbb-seat-reservation-graphic-top": calculatedPosition.y,
710
+ "--sbb-seat-reservation-graphic-left": calculatedPosition.x,
711
+ "--sbb-seat-reservation-graphic-position": "absolute",
712
+ "--sbb-seat-reservation-graphic-rotation": elementFixedRotation
713
+ })}
714
+ class="sbb-seat-reservation-graphic--cursor-pointer"
715
+ name=${serviceElement.icon ?? nothing}
716
+ role="img"
717
+ aria-hidden="true"
718
+ ></sbb-seat-reservation-graphic>
719
+ ${this._popover(triggerId, titleDescription)}
720
+ `;
721
+ });
722
+ }
723
+ /**
724
+ * Manages the selected place event triggered from the place
725
+ * Each selection emits an array of all selected places
726
+ * @param selectPlaceEvent
727
+ */
728
+ _onSelectPlace(selectPlaceEvent) {
729
+ const selectedPlace = selectPlaceEvent.detail;
730
+ this.preventCoachScrollByPlaceClick = true;
731
+ this.isCoachGridFocusable = false;
732
+ this.focusedCoachIndex = -1;
733
+ if (!this.hasSeatReservationNativeFocus) {
734
+ this.hasSeatReservationNativeFocus = true;
735
+ }
736
+ if (!this.preventPlaceClick) {
737
+ this.updateSelectedSeatReservationPlaces(selectedPlace);
738
+ this.updateCurrentSelectedPlaceInCoach(selectedPlace);
739
+ }
740
+ }
741
+ _onSelectNavCoach(event) {
742
+ const selectedNavCoachIndex = event.detail;
743
+ this.isKeyboardNavigation = false;
744
+ this.preventCoachScrollByPlaceClick = false;
745
+ this.hasSeatReservationNativeFocus = true;
746
+ if (selectedNavCoachIndex !== null && selectedNavCoachIndex !== this.currSelectedCoachIndex) {
747
+ this.unfocusPlaceElement();
748
+ this.scrollToSelectedNavCoach(selectedNavCoachIndex);
749
+ } else if (selectedNavCoachIndex === this.currSelectedCoachIndex) {
750
+ this.updateCurrentSelectedCoach();
751
+ this.preselectPlaceInCoach();
752
+ }
753
+ this._closePopover();
754
+ }
755
+ _onFocusNavCoach() {
756
+ if (!this.preventCoachScrollByPlaceClick) {
757
+ this.preselectPlaceInCoach();
758
+ } else {
759
+ this.focusPlaceElement(this.currSelectedPlace);
760
+ }
761
+ this.isAutoScrolling = false;
762
+ }
763
+ /**
764
+ * Creates a popover for extra service information
765
+ * @param triggerId
766
+ * @param popoverContent
767
+ * @private
768
+ */
769
+ _popover(triggerId, popoverContent) {
770
+ return html`
771
+ <sbb-popover trigger="${triggerId}" hover-trigger="">
772
+ <p class="sbb-text-s sbb-sr-popover">${popoverContent}</p>
773
+ </sbb-popover>
774
+ `;
775
+ }
776
+ /**
777
+ * trigger to close all opened popovers (normally only one is opened at a time)
778
+ * @private
779
+ */
780
+ _closePopover() {
781
+ this.shadowRoot?.querySelectorAll("sbb-popover:is(:state(state-opened),[state--state-opened])").forEach((popover) => popover.close());
782
+ }
783
+ _getDescriptionTableCoach(coachItem) {
784
+ if (!coachItem.places?.length) {
785
+ return getI18nSeatReservation("COACH_BLOCKED_TABLE_CAPTION", this._language.current, [
786
+ coachItem.id
787
+ ]);
788
+ }
789
+ let tableCoachDescription;
790
+ const areaDescriptions = this._getTitleDescriptionListString(coachItem.graphicElements);
791
+ const serviceDescriptions = this._getTitleDescriptionListString(coachItem.serviceElements);
792
+ tableCoachDescription = getI18nSeatReservation("COACH_TABLE_CAPTION", this._language.current, [
793
+ coachItem.id
794
+ ]);
795
+ if (!this.hasNavigation) {
796
+ const freePlaces = this.getAvailableFreePlacesNumFromCoach(coachItem.places);
797
+ const freePlacesTxt = getI18nSeatReservation("COACH_AVAILABLE_NUMBER_OF_PLACES", this._language.current, [freePlaces.seats, freePlaces.bicycles]);
798
+ tableCoachDescription = tableCoachDescription.concat(". ").concat(freePlacesTxt).concat(". ");
799
+ }
800
+ if (!!areaDescriptions || !!serviceDescriptions) {
801
+ tableCoachDescription += ". " + getI18nSeatReservation("COACH_AVAILABLE_SERVICES", this._language.current) + ": ";
802
+ tableCoachDescription += serviceDescriptions + ", " + areaDescriptions + ".";
803
+ }
804
+ return tableCoachDescription;
805
+ }
806
+ _getTitleDescriptionListString(descriptionsElements) {
807
+ const uniqueDescriptions = [];
808
+ return descriptionsElements?.map((descriptionElement) => {
809
+ const icon = descriptionElement.icon;
810
+ if (!icon)
811
+ return null;
812
+ const descriptionAlreadyExist = uniqueDescriptions.indexOf(icon) > -1;
813
+ const translation = getI18nSeatReservation(descriptionElement.icon, this._language.current);
814
+ const isValidDescription = this._notFixedRotatableAreaIcons.indexOf(icon) === -1 && this.notAreaElements.indexOf(icon) === -1;
815
+ if (!descriptionAlreadyExist) {
816
+ uniqueDescriptions.push(descriptionElement.icon);
817
+ }
818
+ return !!translation && !descriptionAlreadyExist && isValidDescription ? translation : null;
819
+ }).filter((description) => !!description).join(", ");
820
+ }
821
+ }, _classThis = _a, (() => {
822
+ const _metadata = typeof Symbol === "function" && Symbol.metadata ? Object.create(_classSuper[Symbol.metadata] ?? null) : void 0;
823
+ __esDecorate(null, _classDescriptor = { value: _classThis }, _classDecorators, { kind: "class", name: _classThis.name, metadata: _metadata }, null, _classExtraInitializers);
824
+ _classThis = _classDescriptor.value;
825
+ if (_metadata) Object.defineProperty(_classThis, Symbol.metadata, { enumerable: true, configurable: true, writable: true, value: _metadata });
826
+ })(), _a.styles = [boxSizingStyles, style], __runInitializers(_classThis, _classExtraInitializers), _a;
827
+ return _classThis;
828
+ })();
829
+ export {
830
+ SbbSeatReservationElement
831
+ };
832
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2VhdC1yZXNlcnZhdGlvbi5jb21wb25lbnQuanMiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9lbGVtZW50cy1leHBlcmltZW50YWwvc2VhdC1yZXNlcnZhdGlvbi9zZWF0LXJlc2VydmF0aW9uL3NlYXQtcmVzZXJ2YXRpb24uY29tcG9uZW50LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IFNiYkxhbmd1YWdlQ29udHJvbGxlciB9IGZyb20gJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL2NvcmUvY29udHJvbGxlcnMuanMnO1xuaW1wb3J0IHsgYm94U2l6aW5nU3R5bGVzIH0gZnJvbSAnQHNiYi1lc3RhL2x5bmUtZWxlbWVudHMvY29yZS9zdHlsZXMuanMnO1xuaW1wb3J0IHR5cGUgeyBTYmJQb3BvdmVyRWxlbWVudCB9IGZyb20gJ0BzYmItZXN0YS9seW5lLWVsZW1lbnRzL3BvcG92ZXIuanMnO1xuaW1wb3J0IHsgaHRtbCwgbm90aGluZyB9IGZyb20gJ2xpdCc7XG5pbXBvcnQgdHlwZSB7IENTU1Jlc3VsdEdyb3VwLCBQcm9wZXJ0eVZhbHVlcywgVGVtcGxhdGVSZXN1bHQgfSBmcm9tICdsaXQnO1xuaW1wb3J0IHsgY3VzdG9tRWxlbWVudCB9IGZyb20gJ2xpdC9kZWNvcmF0b3JzLmpzJztcbmltcG9ydCB7IGNsYXNzTWFwIH0gZnJvbSAnbGl0L2RpcmVjdGl2ZXMvY2xhc3MtbWFwLmpzJztcbmltcG9ydCB7IHJlcGVhdCB9IGZyb20gJ2xpdC9kaXJlY3RpdmVzL3JlcGVhdC5qcyc7XG5pbXBvcnQgeyBzdHlsZU1hcCB9IGZyb20gJ2xpdC9kaXJlY3RpdmVzL3N0eWxlLW1hcC5qcyc7XG5cbmltcG9ydCB7IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24gfSBmcm9tICcuLi9jb21tb24udHMnO1xuaW1wb3J0IHR5cGUge1xuICBDb2FjaEl0ZW0sXG4gIFBsYWNlLFxuICBFbGVtZW50RGltZW5zaW9uLFxuICBCYXNlRWxlbWVudCxcbiAgUGxhY2VTZWxlY3Rpb24sXG4gIFNlYXRSZXNlcnZhdGlvbixcbiAgTmF2aWdhdGlvbkNvYWNoSXRlbSxcbn0gZnJvbSAnLi4vY29tbW9uLnRzJztcblxuaW1wb3J0IHsgU2VhdFJlc2VydmF0aW9uQmFzZUVsZW1lbnQgfSBmcm9tICcuL3NlYXQtcmVzZXJ2YXRpb24tYmFzZS1lbGVtZW50LnRzJztcbmltcG9ydCBzdHlsZSBmcm9tICcuL3NlYXQtcmVzZXJ2YXRpb24uc2Nzcz9saXQmaW5saW5lJztcblxuaW1wb3J0ICdAc2JiLWVzdGEvbHluZS1lbGVtZW50cy9idXR0b24uanMnO1xuaW1wb3J0ICdAc2JiLWVzdGEvbHluZS1lbGVtZW50cy9zY3JlZW4tcmVhZGVyLW9ubHkuanMnO1xuaW1wb3J0ICdAc2JiLWVzdGEvbHluZS1lbGVtZW50cy9wb3BvdmVyLmpzJztcbmltcG9ydCAnLi4vc2VhdC1yZXNlcnZhdGlvbi1hcmVhLnRzJztcbmltcG9ydCAnLi4vc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLnRzJztcbmltcG9ydCAnLi4vc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sLnRzJztcbmltcG9ydCAnLi4vc2VhdC1yZXNlcnZhdGlvbi1uYXZpZ2F0aW9uLWNvYWNoLnRzJztcbmltcG9ydCAnLi4vc2VhdC1yZXNlcnZhdGlvbi1zY29wZWQudHMnO1xuXG4vKipcbiAqIE1haW4gY29tcG9uZW50IGZvciB0aGUgc2VhdCByZXNlcnZhdGlvbi5cbiAqXG4gKi9cbmV4cG9ydFxuQGN1c3RvbUVsZW1lbnQoJ3NiYi1zZWF0LXJlc2VydmF0aW9uJylcbmNsYXNzIFNiYlNlYXRSZXNlcnZhdGlvbkVsZW1lbnQgZXh0ZW5kcyBTZWF0UmVzZXJ2YXRpb25CYXNlRWxlbWVudCB7XG4gIHB1YmxpYyBzdGF0aWMgb3ZlcnJpZGUgc3R5bGVzOiBDU1NSZXN1bHRHcm91cCA9IFtib3hTaXppbmdTdHlsZXMsIHN0eWxlXTtcblxuICBwcml2YXRlIF9sYW5ndWFnZSA9IG5ldyBTYmJMYW5ndWFnZUNvbnRyb2xsZXIodGhpcyk7XG4gIHByaXZhdGUgX2NvYWNoZXNIdG1sVGVtcGxhdGU/OiBUZW1wbGF0ZVJlc3VsdDtcblxuICAvLyBBcmVhIGljb25zIHRoYXQgc2hvdWxkIG5vdCBiZSBmaXhlZCBkdXJpbmcgcm90YXRpb24gd2hlbiB2ZXJ0aWNhbCBtb2RlIGlzIHNlbGVjdGVkXG4gIHByaXZhdGUgX25vdEZpeGVkUm90YXRhYmxlQXJlYUljb25zID0gWydFTlRSWV9FWElUJ107XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIHdpbGxVcGRhdGUoY2hhbmdlZFByb3BlcnRpZXM6IFByb3BlcnR5VmFsdWVzPHRoaXM+KTogdm9pZCB7XG4gICAgc3VwZXIud2lsbFVwZGF0ZShjaGFuZ2VkUHJvcGVydGllcyk7XG5cbiAgICBpZiAoY2hhbmdlZFByb3BlcnRpZXMuaGFzKCdoYXNOYXZpZ2F0aW9uJykpIHtcbiAgICAgIGlmICh0aGlzLmhhc05hdmlnYXRpb24pIHtcbiAgICAgICAgdGhpcy5zaGFkb3dSb290XG4gICAgICAgICAgPy5xdWVyeVNlbGVjdG9yQWxsKCd0YWJsZScpXG4gICAgICAgICAgLmZvckVhY2goKHRhYmxlKSA9PiB0YWJsZS5yZW1vdmVBdHRyaWJ1dGUoJ3RhYmluZGV4JykpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdGhpcy5zaGFkb3dSb290XG4gICAgICAgICAgPy5xdWVyeVNlbGVjdG9yQWxsKCd0YWJsZScpXG4gICAgICAgICAgLmZvckVhY2goKHRhYmxlKSA9PiB0YWJsZS5zZXRBdHRyaWJ1dGUoJ3RhYmluZGV4JywgJzAnKSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcHJvdGVjdGVkIG92ZXJyaWRlIGZpcnN0VXBkYXRlZChjaGFuZ2VkUHJvcGVydGllczogUHJvcGVydHlWYWx1ZXM8dGhpcz4pOiB2b2lkIHtcbiAgICBzdXBlci5maXJzdFVwZGF0ZWQoY2hhbmdlZFByb3BlcnRpZXMpO1xuXG4gICAgLy8gV2UgbmVlZCB0byB3YWl0IHVudGlsIHRoZSBmaXJzdCB1cGRhdGUgaXMgY29tcGxldGUgdG8gaW5pdCBkaWZmZXJlbnQgSFRNTCBlbGVtZW50IGRpbWVuc2lvbnNcbiAgICB0aGlzLnVwZGF0ZUNvbXBsZXRlLnRoZW4oKCkgPT4ge1xuICAgICAgdGhpcy5pbml0TmF2aWdhdGlvblNlbGVjdGlvbkJ5U2Nyb2xsRXZlbnQoKTtcbiAgICB9KTtcbiAgfVxuXG4gIHByb3RlY3RlZCBvdmVycmlkZSByZW5kZXIoKTogVGVtcGxhdGVSZXN1bHQgfCBudWxsIHtcbiAgICB0aGlzLl9pbml0VmVoaWNsZVNlYXRSZXNlcnZhdGlvbkNvbnN0cnVjdGlvbigpO1xuICAgIHJldHVybiB0aGlzLl9jb2FjaGVzSHRtbFRlbXBsYXRlIHx8IG51bGw7XG4gIH1cblxuICBwcml2YXRlIF9pbml0VmVoaWNsZVNlYXRSZXNlcnZhdGlvbkNvbnN0cnVjdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLl9jb2FjaGVzSHRtbFRlbXBsYXRlID0gaHRtbGBcbiAgICAgIDxkaXYgY2xhc3M9XCJzYmItc3JfX2NvbXBvbmVudFwiPlxuICAgICAgICAke3RoaXMuX3JlbmRlck5hdmlnYXRpb24oKX1cbiAgICAgICAgPGRpdlxuICAgICAgICAgIGNsYXNzPVwic2JiLXNyX193cmFwcGVyLWNvYWNoLWRlY2tzXCJcbiAgICAgICAgICBAa2V5ZG93bj0keyhldnQ6IEtleWJvYXJkRXZlbnQpID0+IHRoaXMua2V5Ym9hcmRTZWF0bWFwRXZlbnRIYW5kbGluZyhldnQpfVxuICAgICAgICA+XG4gICAgICAgICAgPGRpdiBjbGFzcz1cInNiYi1zcl9fd3JhcHBlci1kZWNrLWxhYmVsc1wiPiR7dGhpcy5fcmVuZGVyRGVja0xhYmVscygpfTwvZGl2PlxuICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgIEBzY3JvbGw9JHsoKSA9PiB0aGlzLmNvYWNoQXJlYVNjcm9sbGVuZCgpfVxuICAgICAgICAgICAgaWQ9XCJzYmItc3JfX3dyYXBwZXItc2Nyb2xsYXJlYVwiXG4gICAgICAgICAgICBjbGFzcz1cInNiYi1zcl9fd3JhcHBlci1zY3JvbGxhcmVhXCJcbiAgICAgICAgICAgIHRhYmluZGV4PVwiMFwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAgPGRpdiBpZD1cInNiYi1zcl9fcGFyZW50LWFyZWFcIiBjbGFzcz1cInNiYi1zcl9fcGFyZW50XCI+XG4gICAgICAgICAgICAgIDx1bFxuICAgICAgICAgICAgICAgIGNsYXNzPVwiJHtjbGFzc01hcCh7XG4gICAgICAgICAgICAgICAgICAnc2JiLXNyX19saXN0LWRlY2tzJzogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICdzYmItc3JfX2xpc3QtZGVja3MtLWdhcCc6IHRoaXMuaGFzTXVsdGlwbGVEZWNrcyxcbiAgICAgICAgICAgICAgICB9KX1cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgJHt0aGlzLnNlYXRSZXNlcnZhdGlvbnM/Lm1hcChcbiAgICAgICAgICAgICAgICAgIChzZWF0UmVzZXJ2YXRpb246IFNlYXRSZXNlcnZhdGlvbiwgY29hY2hEZWNrSW5kZXg6IG51bWJlcikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gaHRtbGA8bGkgY2xhc3M9XCJzYmItc3JfX2xpc3QtaXRlbS1kZWNrXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPHVsIGNsYXNzPVwic2JiLXNyX19saXN0LWNvYWNoZXNcIiByb2xlPVwicHJlc2VudGF0aW9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAke3RoaXMuX3JlbmRlckNvYWNoZXMoc2VhdFJlc2VydmF0aW9uLCBjb2FjaERlY2tJbmRleCl9XG4gICAgICAgICAgICAgICAgICAgICAgPC91bD5cbiAgICAgICAgICAgICAgICAgICAgPC9saT5gO1xuICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICApfVxuICAgICAgICAgICAgICA8L3VsPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvZGl2PlxuICAgICAgPC9kaXY+XG4gICAgYDtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlckRlY2tMYWJlbHMoKTogVGVtcGxhdGVSZXN1bHRbXSB8IG51bGwge1xuICAgIGlmICghdGhpcy5oYXNNdWx0aXBsZURlY2tzKSByZXR1cm4gbnVsbDtcblxuICAgIHJldHVybiB0aGlzLnNlYXRSZXNlcnZhdGlvbnMubWFwKChzZWF0UmVzZXJ2YXRpb24pID0+IHtcbiAgICAgIGNvbnN0IGRlY2tEZXNjcmlwdGlvbiA9IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oXG4gICAgICAgIHNlYXRSZXNlcnZhdGlvbi5kZWNrQ29hY2hMZXZlbCxcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCxcbiAgICAgICk7XG4gICAgICByZXR1cm4gaHRtbGA8YiBhcmlhLWhpZGRlbj1cInRydWVcIj4ke2RlY2tEZXNjcmlwdGlvbn08L2I+YDtcbiAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgX3JlbmRlck5hdmlnYXRpb25Db250cm9sQnV0dG9uKGJ0bkRpcmVjdGlvbjogc3RyaW5nKTogVGVtcGxhdGVSZXN1bHQgfCBudWxsIHtcbiAgICBpZiAoIXRoaXMuaGFzTmF2aWdhdGlvbiB8fCAhdGhpcy5zZWF0UmVzZXJ2YXRpb25zKSByZXR1cm4gbnVsbDtcbiAgICBjb25zdCBidG5OYXZpZ2F0aW9uRGlyZWN0aW9uSWQgPVxuICAgICAgYnRuRGlyZWN0aW9uID09ICdESVJFQ1RJT05fUklHSFQnXG4gICAgICAgID8gJ3NiYi1zci1uYXZpZ2F0aW9uX193cmFwcGVyLWJ1dHRvbi1kaXJlY3Rpb24tLXJpZ2h0J1xuICAgICAgICA6ICdzYmItc3ItbmF2aWdhdGlvbl9fd3JhcHBlci1idXR0b24tZGlyZWN0aW9uLS1sZWZ0JztcbiAgICBjb25zdCBidG5JY29uID1cbiAgICAgIGJ0bkRpcmVjdGlvbiA9PSAnRElSRUNUSU9OX1JJR0hUJyA/ICdjaGV2cm9uLXNtYWxsLXJpZ2h0LXNtYWxsJyA6ICdjaGV2cm9uLXNtYWxsLWxlZnQtc21hbGwnO1xuICAgIGNvbnN0IGJ0bkFyaWFEZXNjcmlwdGlvbiA9XG4gICAgICBidG5EaXJlY3Rpb24gPT0gJ0RJUkVDVElPTl9SSUdIVCdcbiAgICAgICAgPyBnZXRJMThuU2VhdFJlc2VydmF0aW9uKCdTRUFUX1JFU0VSVkFUSU9OX0VORCcsIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQpXG4gICAgICAgIDogZ2V0STE4blNlYXRSZXNlcnZhdGlvbignU0VBVF9SRVNFUlZBVElPTl9CRUdJTicsIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQpO1xuICAgIGxldCBidG5EaXNhYmxlZCA9IHRydWU7XG5cbiAgICBpZiAoYnRuRGlyZWN0aW9uID09ICdESVJFQ1RJT05fTEVGVCcgJiYgdGhpcy5zZWxlY3RlZENvYWNoSW5kZXggPiAwKSB7XG4gICAgICBidG5EaXNhYmxlZCA9IGZhbHNlO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICBidG5EaXJlY3Rpb24gPT0gJ0RJUkVDVElPTl9SSUdIVCcgJiZcbiAgICAgIHRoaXMuc2VsZWN0ZWRDb2FjaEluZGV4IDwgdGhpcy5jb2FjaE5hdkRhdGEubGVuZ3RoIC0gMVxuICAgICkge1xuICAgICAgYnRuRGlzYWJsZWQgPSBmYWxzZTtcbiAgICB9XG5cbiAgICByZXR1cm4gaHRtbGA8ZGl2IGNsYXNzPVwic2JiLXNyLW5hdmlnYXRpb25fX3dyYXBwZXItYnV0dG9uLWRpcmVjdGlvblwiPlxuICAgICAgPHNiYi1zZWNvbmRhcnktYnV0dG9uXG4gICAgICAgIEBjbGljaz1cIiR7KCkgPT4gdGhpcy5uYXZpZ2F0ZUJ5RGlyZWN0aW9uQnRuKGJ0bkRpcmVjdGlvbil9XCJcbiAgICAgICAgQGZvY3VzPVwiJHsoKSA9PiB0aGlzLm9uRm9jdXNOYXZEaXJlY3Rpb25CdXR0b24oKX1cIlxuICAgICAgICBpZD1cIiR7YnRuTmF2aWdhdGlvbkRpcmVjdGlvbklkfVwiXG4gICAgICAgIGNsYXNzPVwic2JiLXNyX19uYXZpZ2F0aW9uLWNvbnRyb2wtYnV0dG9uXCJcbiAgICAgICAgc2l6ZT1cIm1cIlxuICAgICAgICBpY29uLW5hbWU9XCIke2J0bkljb259XCJcbiAgICAgICAgdHlwZT1cImJ1dHRvblwiXG4gICAgICAgIGFyaWEtbGFiZWw9XCIke2J0bkFyaWFEZXNjcmlwdGlvbn1cIlxuICAgICAgICByb2xlPVwiYnV0dG9uXCJcbiAgICAgICAgLmRpc2FibGVkSW50ZXJhY3RpdmU9XCIke2J0bkRpc2FibGVkIHx8IG5vdGhpbmd9XCJcbiAgICAgICAgLmRpc2FibGVkPVwiJHtidG5EaXNhYmxlZCB8fCBub3RoaW5nfVwiXG4gICAgICA+PC9zYmItc2Vjb25kYXJ5LWJ1dHRvbj5cbiAgICA8L2Rpdj5gO1xuICB9XG5cbiAgcHJpdmF0ZSBfcmVuZGVyTmF2aWdhdGlvbigpOiBUZW1wbGF0ZVJlc3VsdCB8IG51bGwge1xuICAgIGlmICghdGhpcy5oYXNOYXZpZ2F0aW9uIHx8ICF0aGlzLnNlYXRSZXNlcnZhdGlvbnMpIHJldHVybiBudWxsO1xuICAgIHJldHVybiBodG1sYDxkaXYgY2xhc3M9XCJzYmItc3ItbmF2aWdhdGlvbi13cmFwcGVyXCI+XG4gICAgICA8bmF2IGlkPVwic2JiLXNyLW5hdmlnYXRpb25cIiBjbGFzcz1cInNiYi1zci1uYXZpZ2F0aW9uXCI+XG4gICAgICAgICR7dGhpcy5fcmVuZGVyTmF2aWdhdGlvbkNvbnRyb2xCdXR0b24oJ0RJUkVDVElPTl9MRUZUJyl9XG4gICAgICAgIDx1bFxuICAgICAgICAgIGlkPVwic2JiLXNyX19uYXZpZ2F0aW9uLWxpc3QtY29hY2hlc1wiXG4gICAgICAgICAgY2xhc3M9XCJzYmItc3ItbmF2aWdhdGlvbl9fbGlzdC1jb2FjaGVzXCJcbiAgICAgICAgICBhcmlhLWxhYmVsPVwiJHtnZXRJMThuU2VhdFJlc2VydmF0aW9uKFxuICAgICAgICAgICAgJ1NFQVRfUkVTRVJWQVRJT05fTkFWSUdBVElPTicsXG4gICAgICAgICAgICB0aGlzLl9sYW5ndWFnZS5jdXJyZW50LFxuICAgICAgICAgICl9XCJcbiAgICAgICAgPlxuICAgICAgICAgICR7dGhpcy5jb2FjaE5hdkRhdGEubWFwKChuYXZpZ2F0aW9uQ29hY2g6IE5hdmlnYXRpb25Db2FjaEl0ZW0sIGluZGV4OiBudW1iZXIpID0+IHtcbiAgICAgICAgICAgIHJldHVybiBodG1sYDxsaT5cbiAgICAgICAgICAgICAgPHNiYi1zZWF0LXJlc2VydmF0aW9uLW5hdmlnYXRpb24tY29hY2hcbiAgICAgICAgICAgICAgICBAc2VsZWN0Y29hY2g9JHsoZXZlbnQ6IEN1c3RvbUV2ZW50PG51bWJlcj4pID0+IHRoaXMuX29uU2VsZWN0TmF2Q29hY2goZXZlbnQpfVxuICAgICAgICAgICAgICAgIEBmb2N1c2NvYWNoPSR7KCkgPT4gdGhpcy5fb25Gb2N1c05hdkNvYWNoKCl9XG4gICAgICAgICAgICAgICAgQGtleXVwPSR7KGV2dDogS2V5Ym9hcmRFdmVudCkgPT4gdGhpcy5vbktleU5hdmlnYXRpb25OYXZDb2FjaEJ1dHRvbihldnQsIGluZGV4KX1cbiAgICAgICAgICAgICAgICBpbmRleD1cIiR7aW5kZXh9XCJcbiAgICAgICAgICAgICAgICBjb2FjaC1pZD1cIiR7bmF2aWdhdGlvbkNvYWNoLmlkfVwiXG4gICAgICAgICAgICAgICAgLmZyZWVQbGFjZXNCeVR5cGU9XCIke25hdmlnYXRpb25Db2FjaC5mcmVlUGxhY2VzfVwiXG4gICAgICAgICAgICAgICAgLnNlbGVjdGVkPSR7dGhpcy5zZWxlY3RlZENvYWNoSW5kZXggPT09IGluZGV4fVxuICAgICAgICAgICAgICAgIC5mb2N1c2VkPSR7dGhpcy5mb2N1c2VkQ29hY2hJbmRleCA9PT0gaW5kZXh9XG4gICAgICAgICAgICAgICAgLmhvdmVyZWQ9JHt0aGlzLmhvdmVyZWRDb2FjaEluZGV4ID09PSBpbmRleH1cbiAgICAgICAgICAgICAgICAubmF0aXZlRm9jdXNBY3RpdmU9JHt0aGlzLmhhc1NlYXRSZXNlcnZhdGlvbk5hdGl2ZUZvY3VzfVxuICAgICAgICAgICAgICAgIC5wcm9wZXJ0eUlkcz1cIiR7bmF2aWdhdGlvbkNvYWNoLnByb3BlcnR5SWRzfVwiXG4gICAgICAgICAgICAgICAgLnRyYXZlbENsYXNzPVwiJHtuYXZpZ2F0aW9uQ29hY2gudHJhdmVsQ2xhc3N9XCJcbiAgICAgICAgICAgICAgICA/ZHJpdmVyLWFyZWE9XCIke25hdmlnYXRpb25Db2FjaC5pc0RyaXZlckFyZWF9XCJcbiAgICAgICAgICAgICAgICA/Zmlyc3Q9XCIke25hdmlnYXRpb25Db2FjaD8uZHJpdmVyQXJlYVNpZGU/LmxlZnR9XCJcbiAgICAgICAgICAgICAgICA/bGFzdD1cIiR7bmF2aWdhdGlvbkNvYWNoPy5kcml2ZXJBcmVhU2lkZT8ucmlnaHR9XCJcbiAgICAgICAgICAgICAgICA/dmVydGljYWw9XCIke3RoaXMuYWxpZ25WZXJ0aWNhbH1cIlxuICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgIDwvc2JiLXNlYXQtcmVzZXJ2YXRpb24tbmF2aWdhdGlvbi1jb2FjaD5cbiAgICAgICAgICAgIDwvbGk+YDtcbiAgICAgICAgICB9KX1cbiAgICAgICAgPC91bD5cbiAgICAgICAgJHt0aGlzLl9yZW5kZXJOYXZpZ2F0aW9uQ29udHJvbEJ1dHRvbignRElSRUNUSU9OX1JJR0hUJyl9XG4gICAgICA8L25hdj5cbiAgICA8L2Rpdj5gO1xuICB9XG4gIC8qKlxuICAgKlxuICAgKiBAcmV0dXJuc1xuICAgKiBAcGFyYW0gc2VhdFJlc2VydmF0aW9uXG4gICAqIEBwYXJhbSBjb2FjaERlY2tJbmRleFxuICAgKi9cbiAgcHJpdmF0ZSBfcmVuZGVyQ29hY2hlcyhcbiAgICBzZWF0UmVzZXJ2YXRpb246IFNlYXRSZXNlcnZhdGlvbixcbiAgICBjb2FjaERlY2tJbmRleDogbnVtYmVyLFxuICApOiBUZW1wbGF0ZVJlc3VsdFtdIHwgbnVsbCB7XG4gICAgY29uc3QgY29hY2hlczogQ29hY2hJdGVtW10gPSBKU09OLnBhcnNlKEpTT04uc3RyaW5naWZ5KHNlYXRSZXNlcnZhdGlvbj8uY29hY2hJdGVtcykpO1xuXG4gICAgaWYgKCFjb2FjaGVzKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGNvYWNoZXMubWFwKChjb2FjaEl0ZW06IENvYWNoSXRlbSwgY29hY2hJbmRleDogbnVtYmVyKSA9PiB7XG4gICAgICByZXR1cm4gaHRtbGBcbiAgICAgICAgPGxpIGNsYXNzPVwic2JiLXNyX19pdGVtLWNvYWNoXCI+XG4gICAgICAgICAgJHt0aGlzLl9yZW5kZXJDb2FjaEVsZW1lbnQoXG4gICAgICAgICAgICBjb2FjaEl0ZW0sXG4gICAgICAgICAgICBjb2FjaEluZGV4LFxuICAgICAgICAgICAgY29hY2hEZWNrSW5kZXgsXG4gICAgICAgICAgICBzZWF0UmVzZXJ2YXRpb24uZGVja0NvYWNoSW5kZXgsXG4gICAgICAgICAgKX1cbiAgICAgICAgPC9saT5cbiAgICAgIGA7XG4gICAgfSk7XG4gIH1cblxuICBwcml2YXRlIF9yZW5kZXJDb2FjaEVsZW1lbnQoXG4gICAgY29hY2hJdGVtOiBDb2FjaEl0ZW0sXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICAgcGxhY2VDb2FjaERlY2tJbmRleDogbnVtYmVyLFxuICApOiBUZW1wbGF0ZVJlc3VsdCB7XG4gICAgY29uc3QgY2FsY3VsYXRlZENvYWNoRGltZW5zaW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkRGltZW5zaW9uKGNvYWNoSXRlbS5kaW1lbnNpb24pO1xuICAgIGNvbnN0IGRlc2NyaXB0aW9uVGFibGVDb2FjaFdpdGhTZXJ2aWNlcyA9IHRoaXMuX2dldERlc2NyaXB0aW9uVGFibGVDb2FjaChjb2FjaEl0ZW0pO1xuXG4gICAgcmV0dXJuIGh0bWxgPHNiYi1zZWF0LXJlc2VydmF0aW9uLXNjb3BlZFxuICAgICAgc3R5bGU9JHtzdHlsZU1hcCh7XG4gICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLXNjb3BlZC13aWR0aCc6IGNhbGN1bGF0ZWRDb2FjaERpbWVuc2lvbi53LFxuICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1zY29wZWQtaGVpZ2h0JzogY2FsY3VsYXRlZENvYWNoRGltZW5zaW9uLmgsXG4gICAgICB9KX1cbiAgICA+XG4gICAgICAke3RoaXMuX2dldFJlbmRlcmVkQ29hY2hCb3JkZXJzKGNvYWNoSXRlbSl9XG4gICAgICAke3RoaXMuX2dldFJlbmRlcmVkR3JhcGhpY2FsRWxlbWVudHMoXG4gICAgICAgIGNvYWNoSXRlbS5ncmFwaGljRWxlbWVudHMgfHwgW10sXG4gICAgICAgIGNvYWNoSXRlbS5kaW1lbnNpb24sXG4gICAgICAgIGNvYWNoSW5kZXgsXG4gICAgICAgIGNvYWNoRGVja0luZGV4LFxuICAgICAgKX1cbiAgICAgICR7dGhpcy5fZ2V0UmVuZGVyZWRTZXJ2aWNlRWxlbWVudHMoY29hY2hJbmRleCwgY29hY2hEZWNrSW5kZXgsIGNvYWNoSXRlbS5zZXJ2aWNlRWxlbWVudHMpfVxuXG4gICAgICA8dGFibGVcbiAgICAgICAgQGZvY3VzPSR7KCkgPT4gdGhpcy5vbkZvY3VzVGFibGVDb2FjaEFuZFByZXNlbGVjdFBsYWNlKGNvYWNoSW5kZXgpfVxuICAgICAgICBpZD1cInNiYi1zci1jb2FjaC0ke2NvYWNoSW5kZXh9XCJcbiAgICAgICAgY2xhc3M9XCJzYmItc3ItY29hY2gtd3JhcHBlcl9fdGFibGVcIlxuICAgICAgICBhcmlhLWRlc2NyaWJlZGJ5PVwic2JiLXNyLWNvYWNoLWNhcHRpb24tJHtjb2FjaEluZGV4fVwiXG4gICAgICAgIHRhYmluZGV4PVwiLTFcIlxuICAgICAgPlxuICAgICAgICA8Y2FwdGlvbiBpZD1cInNiYi1zci1jb2FjaC1jYXB0aW9uLSR7Y29hY2hJbmRleH1cIiB0YWJpbmRleD1cIi0xXCI+XG4gICAgICAgICAgPHNiYi1zY3JlZW4tcmVhZGVyLW9ubHk+JHtkZXNjcmlwdGlvblRhYmxlQ29hY2hXaXRoU2VydmljZXN9PC9zYmItc2NyZWVuLXJlYWRlci1vbmx5PlxuICAgICAgICA8L2NhcHRpb24+XG4gICAgICAgICR7dGhpcy5fZ2V0UmVuZGVyZWRSb3dQbGFjZXMoY29hY2hJdGVtLCBjb2FjaEluZGV4LCBjb2FjaERlY2tJbmRleCwgcGxhY2VDb2FjaERlY2tJbmRleCl9XG4gICAgICA8L3RhYmxlPlxuICAgIDwvc2JiLXNlYXQtcmVzZXJ2YXRpb24tc2NvcGVkPmA7XG4gIH1cblxuICAvKipcbiAgICogQHJldHVybnMgUmV0dXJucyB0aGUgYm9yZGVyIGdyYXBoaWMgKENPQUNIX0JPUkRFUl9NSURETEUpIG9mIGEgY29hY2ggd2l0aCBjYWxjdWxhdGVkIGJvcmRlciBnYXAgYW5kIGNvYWNoIHdpZHRoLFxuICAgKiBkZXBlbmRpbmcgb24gd2hldGhlciB0aGUgY29hY2ggaXMgd2l0aCBhIGRyaXZlciBhcmVhIG9yIHdpdGhvdXQuXG4gICAqL1xuICBwcml2YXRlIF9nZXRSZW5kZXJlZENvYWNoQm9yZGVycyhjb2FjaEl0ZW06IENvYWNoSXRlbSk6IFRlbXBsYXRlUmVzdWx0IHwgbnVsbCB7XG4gICAgaWYgKCFjb2FjaEl0ZW0uZ3JhcGhpY0VsZW1lbnRzKSByZXR1cm4gbnVsbDtcblxuICAgIGNvbnN0IENPQUNIX1BBU1NBR0VfV0lEVEggPSAxO1xuICAgIGNvbnN0IGFsbEVsZW1lbnRzID0gY29hY2hJdGVtLmdyYXBoaWNFbGVtZW50cztcbiAgICBjb25zdCBkcml2ZXJBcmVhID0gYWxsRWxlbWVudHM/LmZpbmQoKGVsZW1lbnQ6IEJhc2VFbGVtZW50KSA9PiBlbGVtZW50Lmljb24gPT09ICdEUklWRVJfQVJFQScpO1xuICAgIGxldCBib3JkZXJXaWR0aCA9IGRyaXZlckFyZWFcbiAgICAgID8gY29hY2hJdGVtLmRpbWVuc2lvbi53IC0gZHJpdmVyQXJlYS5kaW1lbnNpb24udyAtIENPQUNIX1BBU1NBR0VfV0lEVEhcbiAgICAgIDogY29hY2hJdGVtLmRpbWVuc2lvbi53IC0gQ09BQ0hfUEFTU0FHRV9XSURUSCAqIDI7XG5cbiAgICAvL211bHRpcGx5IHdpdGggYmFzZSBncmlkIHNpemUgYWx3YXlzIGZvciBhbGwga2luZCBvZiBib3JkZXJXaWR0aFxuICAgIGJvcmRlcldpZHRoICo9IHRoaXMuYmFzZUdyaWRTaXplO1xuXG4gICAgY29uc3QgYm9yZGVySGVpZ2h0ID0gKGNvYWNoSXRlbS5kaW1lbnNpb24uaCArIHRoaXMuY29hY2hCb3JkZXJPZmZzZXQgKiAyKSAqIHRoaXMuYmFzZUdyaWRTaXplO1xuICAgIGxldCBib3JkZXJPZmZzZXRYID1cbiAgICAgIGRyaXZlckFyZWEgJiYgZHJpdmVyQXJlYS5wb3NpdGlvbi54ID09PSAwXG4gICAgICAgID8gZHJpdmVyQXJlYT8uZGltZW5zaW9uLncgKiB0aGlzLmJhc2VHcmlkU2l6ZVxuICAgICAgICA6IHRoaXMuYmFzZUdyaWRTaXplO1xuXG4gICAgY29uc3QgY3VycmVudENvYWNoT3ZlcmxhcHBpbmdJbmZvID0gdGhpcy5vdmVySGFuZ2luZ0VsZW1lbnRJbmZvcm1hdGlvbi5maW5kKFxuICAgICAgKGVsKSA9PiBlbC5jb2FjaElkID09IGNvYWNoSXRlbS5pZCxcbiAgICApO1xuXG4gICAgLy8gY2hlY2sgaWYgdGhlcmUgYXJlIG92ZXJoYW5naW5nIHBsYWNlcyBvciBncmFwaGljYWwgZWxlbWVudHMgdG8gYWRqdXN0IHRoZSBib3JkZXIgd2lkdGggYW5kIG9mZnNldCArIGdhcFxuICAgIC8vIFdlIGRvIG5vdCBkaWZmZXJlbnRpYXRlIHdoZXRoZXIgdGhlcmUgaXMgc29tZXRoaW5nIHRvIGJlIGRvbmUgb24gYm90aCBzaWRlcyBhcyB0aGlzIHdvdWxkIGxlYWQgdG8gdW5uZWNlc3NhcnlcbiAgICAvLyBjb21wbGV4aXR5LiBTbyBpZiB0aGVyZSBpcyBzb21ldGhpbmcgb24gb25lIHNpZGUsIHdlIGp1c3QgaW5jcmVhc2UgdGhlIGNvYWNoLWJvcmRlciBvbiBib3RoIHNpZGVzLlxuICAgIGlmIChcbiAgICAgIGN1cnJlbnRDb2FjaE92ZXJsYXBwaW5nSW5mbz8ub3ZlcmhhbmdpbmdQbGFjZXMgfHxcbiAgICAgIGN1cnJlbnRDb2FjaE92ZXJsYXBwaW5nSW5mbz8ub3ZlcmhhbmdpbmdHcmFwaGljQXJlYXNcbiAgICApIHtcbiAgICAgIGJvcmRlcldpZHRoICs9IDIgKiB0aGlzLmJhc2VHcmlkU2l6ZTsgLy8gd2UgaW5jcmVhc2UgdGhlIHdpZHRoIGJ5IDIgZ3JpZCBzaXplcyB0byBoYXZlIGVub3VnaCBzcGFjZSBmb3IgcHJvdHJ1ZGVkIHBsYWNlcyBvbiBib3RoIHNpZGVzXG4gICAgICBib3JkZXJPZmZzZXRYID0gMDsgLy8gd2Ugc3RhcnQgYXQgMCB0byBoYXZlIGVub3VnaCBzcGFjZSBvbiB0aGUgbGVmdCBzaWRlIGFzIHdlbGxcbiAgICB9XG5cbiAgICByZXR1cm4gaHRtbGBcbiAgICAgIDxzYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljXG4gICAgICAgIGNsYXNzPVwiJHtjbGFzc01hcCh7XG4gICAgICAgICAgJ3NiYi1zci1jb2FjaC1oYXMtb3ZlcmhhbmdpbmctZWxlbWVudHMnOlxuICAgICAgICAgICAgY3VycmVudENvYWNoT3ZlcmxhcHBpbmdJbmZvPy5vdmVyaGFuZ2luZ1BsYWNlcyB8fFxuICAgICAgICAgICAgY3VycmVudENvYWNoT3ZlcmxhcHBpbmdJbmZvPy5vdmVyaGFuZ2luZ0dyYXBoaWNBcmVhcyB8fFxuICAgICAgICAgICAgZmFsc2UsXG4gICAgICAgIH0pfVwiXG4gICAgICAgIHN0eWxlPSR7c3R5bGVNYXAoe1xuICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtd2lkdGgnOiBib3JkZXJXaWR0aCxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLWhlaWdodCc6IGJvcmRlckhlaWdodCxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXRvcCc6IHRoaXMuY29hY2hCb3JkZXJQYWRkaW5nICogLTEsXG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1sZWZ0JzogYm9yZGVyT2Zmc2V0WCxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXBvc2l0aW9uJzogJ2Fic29sdXRlJyxcbiAgICAgICAgfSl9XG4gICAgICAgIG5hbWU9XCJDT0FDSF9CT1JERVJfTUlERExFXCJcbiAgICAgICAgP3N0cmV0Y2g9JHt0cnVlfVxuICAgICAgICByb2xlPVwicHJlc2VudGF0aW9uXCJcbiAgICAgID48L3NiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWM+XG4gICAgYDtcbiAgfVxuXG4gIHByaXZhdGUgX2dldFJlbmRlcmVkUm93UGxhY2VzKFxuICAgIGNvYWNoOiBDb2FjaEl0ZW0sXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGNvYWNoRGVja0luZGV4OiBudW1iZXIsXG4gICAgcGxhY2VDb2FjaERlY2tJbmRleDogbnVtYmVyLFxuICApOiBUZW1wbGF0ZVJlc3VsdFtdIHwgbnVsbCB7XG4gICAgaWYgKCFjb2FjaC5wbGFjZXMpIHtcbiAgICAgIHJldHVybiBudWxsO1xuICAgIH1cblxuICAgIC8vIFByZXBhcmUgcm93cyB3aXRoIHRoZSBwbGFjZXMgdG8gcmVuZGVyIGEgdGFibGVcbiAgICBjb25zdCB0YWJsZVJvd1BsYWNlczogUmVjb3JkPG51bWJlciwgUGxhY2VbXT4gPSB7fTtcbiAgICBmb3IgKGNvbnN0IHBsYWNlIG9mIGNvYWNoLnBsYWNlcykge1xuICAgICAgaWYgKCF0YWJsZVJvd1BsYWNlc1twbGFjZS5wb3NpdGlvbi55XSkge1xuICAgICAgICB0YWJsZVJvd1BsYWNlc1twbGFjZS5wb3NpdGlvbi55XSA9IFtwbGFjZV07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0YWJsZVJvd1BsYWNlc1twbGFjZS5wb3NpdGlvbi55XS5wdXNoKHBsYWNlKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gT2JqZWN0LnZhbHVlcyh0YWJsZVJvd1BsYWNlcylcbiAgICAgIC5tYXAoKHJvd1BsYWNlczogUGxhY2VbXSwgaW5kZXgpID0+IHtcbiAgICAgICAgcmV0dXJuIGh0bWxgXG4gICAgICAgICAgPHRyIGlkPVwicm93LSR7Y29hY2hJbmRleH0tJHtyb3dQbGFjZXNbMF0ucG9zaXRpb24ueX1cIiBkYXRhLXJvdy1pbmRleD0ke2luZGV4fT5cbiAgICAgICAgICAgICR7dGhpcy5fZ2V0UmVuZGVyZWRDb2x1bW5QbGFjZXMoXG4gICAgICAgICAgICAgIHJvd1BsYWNlcyxcbiAgICAgICAgICAgICAgY29hY2hJbmRleCxcbiAgICAgICAgICAgICAgY29hY2hEZWNrSW5kZXgsXG4gICAgICAgICAgICAgIHBsYWNlQ29hY2hEZWNrSW5kZXgsXG4gICAgICAgICAgICApfVxuICAgICAgICAgIDwvdHI+XG4gICAgICAgIGA7XG4gICAgICB9KVxuICAgICAgLmZsYXRNYXAoKHJvd1RlbXBsYXRlKSA9PiByb3dUZW1wbGF0ZSk7XG4gIH1cblxuICBwcml2YXRlIF9nZXRSZW5kZXJlZENvbHVtblBsYWNlcyhcbiAgICBwbGFjZXM6IFBsYWNlW10sXG4gICAgY29hY2hJbmRleDogbnVtYmVyLFxuICAgIGRlY2tJbmRleDogbnVtYmVyLFxuICAgIHBsYWNlQ29hY2hEZWNrSW5kZXg6IG51bWJlcixcbiAgKTogVGVtcGxhdGVSZXN1bHQgfCBudWxsIHtcbiAgICAvL1NvcnRzIGVhY2ggcGxhY2UgYnkgaXRzIGFzY2VuZGluZyB4IGNvb3JkaW5hdGVcbiAgICBwbGFjZXMuc29ydChcbiAgICAgIChwbGFjZUE6IFBsYWNlLCBwbGFjZUI6IFBsYWNlKSA9PiBOdW1iZXIocGxhY2VBLnBvc2l0aW9uLngpIC0gTnVtYmVyKHBsYWNlQi5wb3NpdGlvbi54KSxcbiAgICApO1xuXG4gICAgLy8gRm9yIHJlbmRlcmluZyB0aGUgcGxhY2VzIHdpdGhpbiBhIHRkIGVsZW1lbnQsIGhlcmUgd2UgdXNlIHJlcGVhdCBkaXJlY3RpdmUgZm9yIGJldHRlciBwZXJmb3JtYW5jZSBmb3IgcmV1c2luZyBlbGVtZW50cyAodHJhY2sgYnkgaWQpLlxuICAgIGNvbnN0IHRyYWNrUGxhY2VJZCA9IGNvYWNoSW5kZXggKyAnLScgKyBwbGFjZUNvYWNoRGVja0luZGV4O1xuICAgIHJldHVybiBodG1sYCR7cmVwZWF0KFxuICAgICAgcGxhY2VzLFxuICAgICAgKHBsYWNlKSA9PiB0cmFja1BsYWNlSWQgKyAnLScgKyBwbGFjZS5udW1iZXIsXG4gICAgICAocGxhY2UsIGluZGV4KSA9PiB7XG4gICAgICAgIGNvbnN0IGNhbGN1bGF0ZWREaW1lbnNpb24gPSB0aGlzLmdldENhbGN1bGF0ZWREaW1lbnNpb24ocGxhY2UuZGltZW5zaW9uKTtcbiAgICAgICAgY29uc3QgY2FsY3VsYXRlZFBvc2l0aW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkUG9zaXRpb24ocGxhY2UucG9zaXRpb24pO1xuICAgICAgICBjb25zdCByb3RhdGlvbiA9IHBsYWNlLnJvdGF0aW9uIHx8IDA7XG4gICAgICAgIGNvbnN0IHRleHRSb3RhdGlvbiA9IHRoaXMuYWxpZ25WZXJ0aWNhbCA/IC05MCA6IDA7XG4gICAgICAgIGNvbnN0IHBsYWNlSWQgPSB0aGlzLmdldFBsYWNlRWxlbWVudElkKGRlY2tJbmRleCwgY29hY2hJbmRleCwgcGxhY2UubnVtYmVyKTtcbiAgICAgICAgcmV0dXJuIGh0bWxgXG4gICAgICAgICAgPHRkXG4gICAgICAgICAgICBpZD1cImNlbGwtJHtkZWNrSW5kZXh9LSR7Y29hY2hJbmRleH0tJHtwbGFjZS5wb3NpdGlvbi55fS0ke2luZGV4fVwiXG4gICAgICAgICAgICBjbGFzcz1cImdyYXBoaWNhbC1lbGVtZW50XCJcbiAgICAgICAgICA+XG4gICAgICAgICAgICA8c2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbFxuICAgICAgICAgICAgICBzdHlsZT0ke3N0eWxlTWFwKHtcbiAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sLXRleHQtc2NhbGUtdmFsdWUnOiBNYXRoLm1pbihcbiAgICAgICAgICAgICAgICAgIGNhbGN1bGF0ZWREaW1lbnNpb24udyxcbiAgICAgICAgICAgICAgICAgIGNhbGN1bGF0ZWREaW1lbnNpb24uaCxcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2wtd2lkdGgnOiBjYWxjdWxhdGVkRGltZW5zaW9uLncsXG4gICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC1oZWlnaHQnOiBjYWxjdWxhdGVkRGltZW5zaW9uLmgsXG4gICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC10b3AnOiBjYWxjdWxhdGVkUG9zaXRpb24ueSxcbiAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sLWxlZnQnOiBjYWxjdWxhdGVkUG9zaXRpb24ueCxcbiAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1wbGFjZS1jb250cm9sLXJvdGF0aW9uJzogcm90YXRpb24sXG4gICAgICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbC10ZXh0LXJvdGF0aW9uJzogdGV4dFJvdGF0aW9uLFxuICAgICAgICAgICAgICB9KX1cbiAgICAgICAgICAgICAgQHNlbGVjdHBsYWNlPSR7KHNlbGVjdFBsYWNlRXZlbnQ6IEN1c3RvbUV2ZW50PFBsYWNlU2VsZWN0aW9uPikgPT5cbiAgICAgICAgICAgICAgICB0aGlzLl9vblNlbGVjdFBsYWNlKHNlbGVjdFBsYWNlRXZlbnQpfVxuICAgICAgICAgICAgICBleHBvcnRwYXJ0cz1cInNiYi1zci1wbGFjZS1wYXJ0XCJcbiAgICAgICAgICAgICAgaWQ9JHtwbGFjZUlkfVxuICAgICAgICAgICAgICBjbGFzcz1cInNlYXQtcmVzZXJ2YXRpb24tcGxhY2UtY29udHJvbFwiXG4gICAgICAgICAgICAgIHRleHQ9JHtwbGFjZS5udW1iZXJ9XG4gICAgICAgICAgICAgIHR5cGU9JHtwbGFjZS50eXBlfVxuICAgICAgICAgICAgICBzdGF0ZT0ke3BsYWNlLnN0YXRlfVxuICAgICAgICAgICAgICBjb2FjaC1pbmRleD0ke2NvYWNoSW5kZXh9XG4gICAgICAgICAgICAgIGRlY2staW5kZXg9JHtwbGFjZUNvYWNoRGVja0luZGV4fVxuICAgICAgICAgICAgICBkYXRhLWRlY2staW5kZXg9JHtkZWNrSW5kZXh9XG4gICAgICAgICAgICAgIC5wcm9wZXJ0eUlkcz0ke3BsYWNlLnByb3BlcnR5SWRzfVxuICAgICAgICAgICAgICAucHJldmVudENsaWNrPSR7dGhpcy5wcmV2ZW50UGxhY2VDbGlja31cbiAgICAgICAgICAgID48L3NiYi1zZWF0LXJlc2VydmF0aW9uLXBsYWNlLWNvbnRyb2w+XG4gICAgICAgICAgPC90ZD5cbiAgICAgICAgYDtcbiAgICAgIH0sXG4gICAgKX1gO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0UmVuZGVyZWRHcmFwaGljYWxFbGVtZW50cyhcbiAgICBncmFwaGljYWxFbGVtZW50czogQmFzZUVsZW1lbnRbXSxcbiAgICBjb2FjaERpbWVuc2lvbjogRWxlbWVudERpbWVuc2lvbixcbiAgICBjb2FjaEluZGV4OiBudW1iZXIsXG4gICAgY29hY2hEZWNrSW5kZXg6IG51bWJlcixcbiAgKTogVGVtcGxhdGVSZXN1bHRbXSB8IG51bGwge1xuICAgIGlmICghZ3JhcGhpY2FsRWxlbWVudHMpIHJldHVybiBudWxsO1xuXG4gICAgcmV0dXJuIGdyYXBoaWNhbEVsZW1lbnRzPy5tYXAoKGdyYXBoaWNhbEVsZW1lbnQ6IEJhc2VFbGVtZW50KSA9PiB7XG4gICAgICBjb25zdCBpY29uID0gZ3JhcGhpY2FsRWxlbWVudC5pY29uID8/ICcnO1xuICAgICAgY29uc3QgZWxlbWVudFJvdGF0aW9uID0gZ3JhcGhpY2FsRWxlbWVudC5yb3RhdGlvbiB8fCAwO1xuICAgICAgY29uc3QgaXNOb3RGaXhlZFJvdGF0aW9uR3JhcGhpY2FsRWxlbWVudCA9XG4gICAgICAgIHRoaXMuX25vdEZpeGVkUm90YXRhYmxlQXJlYUljb25zLmluZGV4T2YoZ3JhcGhpY2FsRWxlbWVudC5pY29uISkgPT09IC0xO1xuICAgICAgY29uc3QgZWxlbWVudEZpeGVkUm90YXRpb24gPVxuICAgICAgICB0aGlzLmFsaWduVmVydGljYWwgJiYgaXNOb3RGaXhlZFJvdGF0aW9uR3JhcGhpY2FsRWxlbWVudFxuICAgICAgICAgID8gZWxlbWVudFJvdGF0aW9uIC0gOTBcbiAgICAgICAgICA6IGVsZW1lbnRSb3RhdGlvbjtcblxuICAgICAgLy9jaGVjayBpZiB0aGUgY3VycmVudCBlbGVtZW50IGlzIG5vdCBhbiBhcmVhIGVsZW1lbnQsIHNpbmNlIHRoaXMgZWxlbWVudCBpcyBkcmF3biB3aXRob3V0IGFuIGFyZWEgY29tcG9uZW50XG4gICAgICBpZiAodGhpcy5ub3RBcmVhRWxlbWVudHMuZmluZEluZGV4KChub3RBcmVhRWxlbWVudCkgPT4gbm90QXJlYUVsZW1lbnQgPT09IGljb24pID4gLTEpIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX2dldFJlbmRlckVsZW1lbnRXaXRob3V0QXJlYShncmFwaGljYWxFbGVtZW50LCBlbGVtZW50Um90YXRpb24sIGNvYWNoRGltZW5zaW9uKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0aGlzLl9nZXRSZW5kZXJFbGVtZW50V2l0aEFyZWEoXG4gICAgICAgIGdyYXBoaWNhbEVsZW1lbnQsXG4gICAgICAgIGVsZW1lbnRGaXhlZFJvdGF0aW9uLFxuICAgICAgICBjb2FjaERpbWVuc2lvbixcbiAgICAgICAgY29hY2hJbmRleCxcbiAgICAgICAgY29hY2hEZWNrSW5kZXgsXG4gICAgICApO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqXG4gICAqIGNyZWF0ZXMgYSByZW5kZXJlZCBlbGVtZW50IHdpdGggYW4gYXJlYSBjb21wb25lbnRcbiAgICogQHBhcmFtIGdyYXBoaWNhbEVsZW1lbnRcbiAgICogQHBhcmFtIHJvdGF0aW9uXG4gICAqIEBwYXJhbSBjb2FjaERpbWVuc2lvblxuICAgKiBAcGFyYW0gY29hY2hJbmRleCB1c2VkIHRvIGdlbmVyYXRlIGEgdW5pcXVlIGlkIGZvciB0aGUgcG9wb3ZlciB0cmlnZ2VyXG4gICAqIEBwYXJhbSBjb2FjaERlY2tJbmRleCB1c2VkIHRvIGdlbmVyYXRlIGEgdW5pcXVlIGlkXG4gICAqIEBwcml2YXRlXG4gICAqL1xuICBwcml2YXRlIF9nZXRSZW5kZXJFbGVtZW50V2l0aEFyZWEoXG4gICAgZ3JhcGhpY2FsRWxlbWVudDogQmFzZUVsZW1lbnQsXG4gICAgcm90YXRpb246IG51bWJlcixcbiAgICBjb2FjaERpbWVuc2lvbjogRWxlbWVudERpbWVuc2lvbixcbiAgICBjb2FjaEluZGV4OiBudW1iZXIsXG4gICAgY29hY2hEZWNrSW5kZXg6IG51bWJlcixcbiAgKTogVGVtcGxhdGVSZXN1bHQge1xuICAgIC8vIGZvciBUQUJMRSwgd2UgdXNlIHRoZSBhcmVhIGNvbXBvbmVudCBpdHNlbGYgdG8gZGlzcGxheSB0aGUgdGFibGUgaW5zdGVhZCBvZiB0aGUgU1ZHIGdyYXBoaWMuXG4gICAgLy8gRHVlIHRvIGRpZmZlcmVudCBoZWlnaHRzIGFuZCB3aWR0aHMsIGl0IHdvdWxkbid0IHNob3cgY29ycmVjdGx5LiBUbyBjb3JyZWN0IHRoaXMsIHdlIHdvdWxkXG4gICAgLy8gbmVlZCBkaWZmaWN1bHQgY2FsY3VsYXRpb25zIGZvciBwb3NpdGlvbiwgcm90YXRpb24gYW5kIGRpbWVuc2lvbi5cbiAgICBjb25zdCBpc05vdFRhYmxlR3JhcGhpYyA9IGdyYXBoaWNhbEVsZW1lbnQuaWNvbj8uaW5kZXhPZignVEFCTEUnKSA9PT0gLTE7XG4gICAgY29uc3QgYXJlYVByb3BlcnR5ID0gZ3JhcGhpY2FsRWxlbWVudC5pY29uICYmIGlzTm90VGFibGVHcmFwaGljID8gZ3JhcGhpY2FsRWxlbWVudC5pY29uIDogbnVsbDtcbiAgICBjb25zdCBzdHJldGNoSGVpZ2h0ID1cbiAgICAgIHRoaXMuaXNFbGVtZW50RGlyZWN0bHlPbkJvcmRlcihncmFwaGljYWxFbGVtZW50LCBjb2FjaERpbWVuc2lvbikgJiZcbiAgICAgIGFyZWFQcm9wZXJ0eSAhPT0gJ0VOVFJZX0VYSVQnO1xuICAgIGNvbnN0IGFyaWFMYWJlbEZvckFyZWEgPSBncmFwaGljYWxFbGVtZW50Lmljb25cbiAgICAgID8gZ2V0STE4blNlYXRSZXNlcnZhdGlvbihncmFwaGljYWxFbGVtZW50Lmljb24sIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQpXG4gICAgICA6IG5vdGhpbmc7XG5cbiAgICBjb25zdCBjYWxjdWxhdGVkRGltZW5zaW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkRGltZW5zaW9uKFxuICAgICAgZ3JhcGhpY2FsRWxlbWVudC5kaW1lbnNpb24sXG4gICAgICBjb2FjaERpbWVuc2lvbixcbiAgICAgIHRydWUsXG4gICAgICBzdHJldGNoSGVpZ2h0LFxuICAgICk7XG5cbiAgICBjb25zdCBjYWxjdWxhdGVkUG9zaXRpb24gPSB0aGlzLmdldENhbGN1bGF0ZWRQb3NpdGlvbihcbiAgICAgIGdyYXBoaWNhbEVsZW1lbnQucG9zaXRpb24sXG4gICAgICBncmFwaGljYWxFbGVtZW50LmRpbWVuc2lvbixcbiAgICAgIGNvYWNoRGltZW5zaW9uLFxuICAgICAgdHJ1ZSxcbiAgICApO1xuXG4gICAgLy9nZW5lcmF0ZSB1bmlxdWUgaW5kZXggbnVtYmVyIGZvciB0aGUgdHJpZ2dlciBlbGVtZW50XG4gICAgY29uc3QgdHJpZ2dlcklkID0gYHBvcG92ZXItdHJpZ2dlci0ke2NvYWNoRGVja0luZGV4fS0ke2NvYWNoSW5kZXh9LSR7Y2FsY3VsYXRlZFBvc2l0aW9uLnh9LSR7Y2FsY3VsYXRlZFBvc2l0aW9uLnl9YDtcbiAgICBsZXQgZWxlbWVudE1vdW50aW5nID0gJ2ZyZWUnO1xuXG4gICAgaWYgKGdyYXBoaWNhbEVsZW1lbnQucG9zaXRpb24ueSA9PT0gdGhpcy5jb2FjaEJvcmRlck9mZnNldCAqIC0xKSB7XG4gICAgICBlbGVtZW50TW91bnRpbmcgPSAndXBwZXItYm9yZGVyJztcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgZ3JhcGhpY2FsRWxlbWVudC5wb3NpdGlvbi55ICsgZ3JhcGhpY2FsRWxlbWVudC5kaW1lbnNpb24uaCA9PT1cbiAgICAgIGNvYWNoRGltZW5zaW9uLmggKyB0aGlzLmNvYWNoQm9yZGVyT2Zmc2V0XG4gICAgKSB7XG4gICAgICBlbGVtZW50TW91bnRpbmcgPSAnbG93ZXItYm9yZGVyJztcbiAgICB9XG5cbiAgICAvLyBUSU1PLTQ1ODMwXG4gICAgLy8gSWYgYXJlYSBlbGVtZW50cyBhcmUgbG9jYXRlZCBhdCB0aGUgYm9yZGVyIG9mIGNvYWNoLFxuICAgIC8vIHdlIGhhdmUgdG8gbWFudWFsbHkgbW9kaWZ5IHRoZSBwb3NpdGlvbiBhbmQgaGVpZ2h0IG9mIHRoZSBhcmVhIGVsZW1lbnQsXG4gICAgLy8gc28gdGhhdCB3ZSBnZXQgYSBnYXAgZnJvbSB0aGUgdmlzdWVsIGNvYWNoIGJvcmRlclxuICAgIGlmIChlbGVtZW50TW91bnRpbmcgIT09ICdmcmVlJykge1xuICAgICAgY2FsY3VsYXRlZFBvc2l0aW9uLnkgKz0gZWxlbWVudE1vdW50aW5nID09PSAndXBwZXItYm9yZGVyJyA/IDIgOiAxO1xuICAgICAgY2FsY3VsYXRlZERpbWVuc2lvbi5oIC09IDM7XG4gICAgfVxuICAgIHJldHVybiBodG1sYFxuICAgICAgPHNiYi1zZWF0LXJlc2VydmF0aW9uLWFyZWFcbiAgICAgICAgaWQ9XCIke3RyaWdnZXJJZH1cIlxuICAgICAgICBjbGFzcz1cIiR7Y2xhc3NNYXAoeyAnc2JiLXNlYXQtcmVzZXJ2YXRpb24tYXJlYS0tY3Vyc29yLXBvaW50ZXInOiBhcmVhUHJvcGVydHkgIT09IG51bGwgfSl9XCJcbiAgICAgICAgc3R5bGU9JHtzdHlsZU1hcCh7XG4gICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tYXJlYS13aWR0aCc6IGNhbGN1bGF0ZWREaW1lbnNpb24udyxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1hcmVhLWhlaWdodCc6IGNhbGN1bGF0ZWREaW1lbnNpb24uaCxcbiAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1hcmVhLXRvcCc6IGNhbGN1bGF0ZWRQb3NpdGlvbi55LFxuICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWFyZWEtbGVmdCc6IGNhbGN1bGF0ZWRQb3NpdGlvbi54LFxuICAgICAgICB9KX1cbiAgICAgICAgbW91bnRpbmc9JHtlbGVtZW50TW91bnRpbmd9XG4gICAgICAgIGJhY2tncm91bmQ9XCJkYXJrXCJcbiAgICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgID5cbiAgICAgICAgJHthcmVhUHJvcGVydHlcbiAgICAgICAgICA/IGh0bWxgXG4gICAgICAgICAgICAgIDxzYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljXG4gICAgICAgICAgICAgICAgc3R5bGU9JHtzdHlsZU1hcCh7XG4gICAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLW1heC13aWR0aCc6IGNhbGN1bGF0ZWREaW1lbnNpb24udyxcbiAgICAgICAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtaGVpZ2h0JzogdGhpcy5iYXNlR3JpZFNpemUsXG4gICAgICAgICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXJvdGF0aW9uJzogcm90YXRpb24sXG4gICAgICAgICAgICAgICAgfSl9XG4gICAgICAgICAgICAgICAgbmFtZT0ke2FyZWFQcm9wZXJ0eX1cbiAgICAgICAgICAgICAgICByb2xlPVwiaW1nXCJcbiAgICAgICAgICAgICAgICBhcmlhLWhpZGRlbj1cInRydWVcIlxuICAgICAgICAgICAgICAgIGNsYXNzPVwiYXV0by13aWR0aFwiXG4gICAgICAgICAgICAgID48L3NiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWM+XG4gICAgICAgICAgICBgXG4gICAgICAgICAgOiBub3RoaW5nfVxuICAgICAgPC9zYmItc2VhdC1yZXNlcnZhdGlvbi1hcmVhPlxuICAgICAgJHthcmVhUHJvcGVydHkgPyB0aGlzLl9wb3BvdmVyKHRyaWdnZXJJZCwgYXJpYUxhYmVsRm9yQXJlYSkgOiBub3RoaW5nfVxuICAgIGA7XG4gIH1cblxuICBwcml2YXRlIF9nZXRSZW5kZXJFbGVtZW50V2l0aG91dEFyZWEoXG4gICAgZ3JhcGhpY2FsRWxlbWVudDogQmFzZUVsZW1lbnQsXG4gICAgcm90YXRpb246IG51bWJlcixcbiAgICBjb2FjaERpbWVuc2lvbjogRWxlbWVudERpbWVuc2lvbixcbiAgKTogVGVtcGxhdGVSZXN1bHQge1xuICAgIGNvbnN0IGNhbGN1bGF0ZWREaW1lbnNpb24gPSB0aGlzLmdldENhbGN1bGF0ZWREaW1lbnNpb24oXG4gICAgICBncmFwaGljYWxFbGVtZW50LmRpbWVuc2lvbixcbiAgICAgIGNvYWNoRGltZW5zaW9uLFxuICAgICk7XG4gICAgY29uc3QgY2FsY3VsYXRlZFBvc2l0aW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkUG9zaXRpb24oXG4gICAgICBncmFwaGljYWxFbGVtZW50LnBvc2l0aW9uLFxuICAgICAgZ3JhcGhpY2FsRWxlbWVudC5kaW1lbnNpb24sXG4gICAgICBjb2FjaERpbWVuc2lvbixcbiAgICApO1xuXG4gICAgLy8gSWYgdGhlIGljb24gaXMgdGhlIGRyaXZlciBhcmVhLCB0aGVuIGhlcmUgY29uY2F0IHRoZSB2ZWhpY2xlIHR5cGUgdG8gZ2V0IHRoZSByaWdodCB2ZWhpY2xlIGNoYXNzaXMgaWNvblxuICAgIGNvbnN0IGljb24gPVxuICAgICAgZ3JhcGhpY2FsRWxlbWVudC5pY29uICYmIGdyYXBoaWNhbEVsZW1lbnQuaWNvbi5pbmRleE9mKCdEUklWRVJfQVJFQScpID09PSAtMVxuICAgICAgICA/IGdyYXBoaWNhbEVsZW1lbnQuaWNvblxuICAgICAgICA6IGdyYXBoaWNhbEVsZW1lbnQuaWNvbj8uY29uY2F0KFxuICAgICAgICAgICAgJ18nLFxuICAgICAgICAgICAgdGhpcy5zZWF0UmVzZXJ2YXRpb25zW3RoaXMuY3VyclNlbGVjdGVkRGVja0luZGV4XS52ZWhpY2xlVHlwZSxcbiAgICAgICAgICApO1xuXG4gICAgcmV0dXJuIGh0bWxgIDxzYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljXG4gICAgICBzdHlsZT0ke3N0eWxlTWFwKHtcbiAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy13aWR0aCc6IGNhbGN1bGF0ZWREaW1lbnNpb24udyxcbiAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1oZWlnaHQnOiBjYWxjdWxhdGVkRGltZW5zaW9uLmgsXG4gICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtdG9wJzogY2FsY3VsYXRlZFBvc2l0aW9uLnksXG4gICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtbGVmdCc6IGNhbGN1bGF0ZWRQb3NpdGlvbi54LFxuICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXBvc2l0aW9uJzogJ2Fic29sdXRlJyxcbiAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1yb3RhdGlvbic6IHJvdGF0aW9uLFxuICAgICAgfSl9XG4gICAgICBuYW1lPSR7aWNvbiA/PyBub3RoaW5nfVxuICAgICAgYXJpYS1oaWRkZW49XCJ0cnVlXCJcbiAgICAgID9zdHJldGNoPSR7dHJ1ZX1cbiAgICA+PC9zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljPmA7XG4gIH1cblxuICBwcml2YXRlIF9nZXRSZW5kZXJlZFNlcnZpY2VFbGVtZW50cyhcbiAgICBjb2FjaEluZGV4OiBudW1iZXIsXG4gICAgY29hY2hEZWNrSW5kZXg6IG51bWJlcixcbiAgICBzZXJ2aWNlRWxlbWVudHM/OiBCYXNlRWxlbWVudFtdLFxuICApOiBUZW1wbGF0ZVJlc3VsdFtdIHwgbnVsbCB7XG4gICAgaWYgKCFzZXJ2aWNlRWxlbWVudHMpIHJldHVybiBudWxsO1xuXG4gICAgcmV0dXJuIHNlcnZpY2VFbGVtZW50cz8ubWFwKChzZXJ2aWNlRWxlbWVudDogQmFzZUVsZW1lbnQpID0+IHtcbiAgICAgIGNvbnN0IHRpdGxlRGVzY3JpcHRpb24gPSBzZXJ2aWNlRWxlbWVudC5pY29uXG4gICAgICAgID8gZ2V0STE4blNlYXRSZXNlcnZhdGlvbihzZXJ2aWNlRWxlbWVudC5pY29uLCB0aGlzLl9sYW5ndWFnZS5jdXJyZW50KVxuICAgICAgICA6IG51bGw7XG4gICAgICBjb25zdCBjYWxjdWxhdGVkRGltZW5zaW9uID0gdGhpcy5nZXRDYWxjdWxhdGVkRGltZW5zaW9uKHNlcnZpY2VFbGVtZW50LmRpbWVuc2lvbik7XG4gICAgICBjb25zdCBjYWxjdWxhdGVkUG9zaXRpb24gPSB0aGlzLmdldENhbGN1bGF0ZWRQb3NpdGlvbihzZXJ2aWNlRWxlbWVudC5wb3NpdGlvbik7XG4gICAgICBjb25zdCBlbGVtZW50Um90YXRpb24gPSBzZXJ2aWNlRWxlbWVudC5yb3RhdGlvbiB8fCAwO1xuICAgICAgY29uc3QgZWxlbWVudEZpeGVkUm90YXRpb24gPSB0aGlzLmFsaWduVmVydGljYWwgPyBlbGVtZW50Um90YXRpb24gLSA5MCA6IGVsZW1lbnRSb3RhdGlvbjtcblxuICAgICAgLy9nZW5lcmF0ZSB1bmlxdWUgaW5kZXggbnVtYmVyIGZvciB0aGUgdHJpZ2dlciBlbGVtZW50XG4gICAgICBjb25zdCB0cmlnZ2VySWQgPSBgcG9wb3Zlci10cmlnZ2VyLSR7Y29hY2hEZWNrSW5kZXh9LSR7Y29hY2hJbmRleH0tJHtjYWxjdWxhdGVkUG9zaXRpb24ueH0tJHtjYWxjdWxhdGVkUG9zaXRpb24ueX1gO1xuXG4gICAgICByZXR1cm4gaHRtbGBcbiAgICAgICAgPHNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWNcbiAgICAgICAgICBpZD1cIiR7dHJpZ2dlcklkfVwiXG4gICAgICAgICAgc3R5bGU9JHtzdHlsZU1hcCh7XG4gICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXdpZHRoJzogY2FsY3VsYXRlZERpbWVuc2lvbi53LFxuICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1oZWlnaHQnOiBjYWxjdWxhdGVkRGltZW5zaW9uLmgsXG4gICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXRvcCc6IGNhbGN1bGF0ZWRQb3NpdGlvbi55LFxuICAgICAgICAgICAgJy0tc2JiLXNlYXQtcmVzZXJ2YXRpb24tZ3JhcGhpYy1sZWZ0JzogY2FsY3VsYXRlZFBvc2l0aW9uLngsXG4gICAgICAgICAgICAnLS1zYmItc2VhdC1yZXNlcnZhdGlvbi1ncmFwaGljLXBvc2l0aW9uJzogJ2Fic29sdXRlJyxcbiAgICAgICAgICAgICctLXNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtcm90YXRpb24nOiBlbGVtZW50Rml4ZWRSb3RhdGlvbixcbiAgICAgICAgICB9KX1cbiAgICAgICAgICBjbGFzcz1cInNiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWMtLWN1cnNvci1wb2ludGVyXCJcbiAgICAgICAgICBuYW1lPSR7c2VydmljZUVsZW1lbnQuaWNvbiA/PyBub3RoaW5nfVxuICAgICAgICAgIHJvbGU9XCJpbWdcIlxuICAgICAgICAgIGFyaWEtaGlkZGVuPVwidHJ1ZVwiXG4gICAgICAgID48L3NiYi1zZWF0LXJlc2VydmF0aW9uLWdyYXBoaWM+XG4gICAgICAgICR7dGhpcy5fcG9wb3Zlcih0cmlnZ2VySWQsIHRpdGxlRGVzY3JpcHRpb24pfVxuICAgICAgYDtcbiAgICB9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBNYW5hZ2VzIHRoZSBzZWxlY3RlZCBwbGFjZSBldmVudCB0cmlnZ2VyZWQgZnJvbSB0aGUgcGxhY2VcbiAgICogRWFjaCBzZWxlY3Rpb24gZW1pdHMgYW4gYXJyYXkgb2YgYWxsIHNlbGVjdGVkIHBsYWNlc1xuICAgKiBAcGFyYW0gc2VsZWN0UGxhY2VFdmVudFxuICAgKi9cbiAgcHJpdmF0ZSBfb25TZWxlY3RQbGFjZShzZWxlY3RQbGFjZUV2ZW50OiBDdXN0b21FdmVudDxQbGFjZVNlbGVjdGlvbj4pOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3RlZFBsYWNlID0gc2VsZWN0UGxhY2VFdmVudC5kZXRhaWw7XG4gICAgLy8gV2UgaGF2ZSB0byBzZXQgcHJldmVudENvYWNoU2Nyb2xsQnlQbGFjZUNsaWNrIHRvIHRydWUsIHRvIHByZXZlbnQgYXV0b21hdGljIHNjcm9sbGluZyB0byB0aGUgbmV3IGZvY3VzZWQgcGxhY2VcbiAgICB0aGlzLnByZXZlbnRDb2FjaFNjcm9sbEJ5UGxhY2VDbGljayA9IHRydWU7XG4gICAgdGhpcy5pc0NvYWNoR3JpZEZvY3VzYWJsZSA9IGZhbHNlO1xuICAgIHRoaXMuZm9jdXNlZENvYWNoSW5kZXggPSAtMTtcbiAgICAvLyBDaGVjayBhbnkga2V5Ym9hcmQgZXZlbnQgd2FzIHRyaWdnZXJlZCBpbnNpZGUgdGhlIHNlYXQgcmVzZXJ2YXRpb24gY29tcG9uZW50LFxuICAgIC8vIHNvIHdlIGNhbiBzYXkgdGhlIG5hdGl2ZSBicm93c2VyIGZvY3VzIGxpZXMgb24gdGhlIGNvbXBvbmVudFxuICAgIGlmICghdGhpcy5oYXNTZWF0UmVzZXJ2YXRpb25OYXRpdmVGb2N1cykge1xuICAgICAgdGhpcy5oYXNTZWF0UmVzZXJ2YXRpb25OYXRpdmVGb2N1cyA9IHRydWU7XG4gICAgfVxuXG4gICAgaWYgKCF0aGlzLnByZXZlbnRQbGFjZUNsaWNrKSB7XG4gICAgICAvLyBBZGQgcGxhY2UgdG8gcGxhY2UgY29sbGVjdGlvblxuICAgICAgdGhpcy51cGRhdGVTZWxlY3RlZFNlYXRSZXNlcnZhdGlvblBsYWNlcyhzZWxlY3RlZFBsYWNlKTtcbiAgICAgIHRoaXMudXBkYXRlQ3VycmVudFNlbGVjdGVkUGxhY2VJbkNvYWNoKHNlbGVjdGVkUGxhY2UpO1xuICAgIH1cbiAgfVxuXG4gIHByaXZhdGUgX29uU2VsZWN0TmF2Q29hY2goZXZlbnQ6IEN1c3RvbUV2ZW50PG51bWJlcj4pOiB2b2lkIHtcbiAgICBjb25zdCBzZWxlY3RlZE5hdkNvYWNoSW5kZXggPSBldmVudC5kZXRhaWw7XG5cbiAgICB0aGlzLmlzS2V5Ym9hcmROYXZpZ2F0aW9uID0gZmFsc2U7XG4gICAgdGhpcy5wcmV2ZW50Q29hY2hTY3JvbGxCeVBsYWNlQ2xpY2sgPSBmYWxzZTtcbiAgICB0aGlzLmhhc1NlYXRSZXNlcnZhdGlvbk5hdGl2ZUZvY3VzID0gdHJ1ZTtcblxuICAgIGlmIChzZWxlY3RlZE5hdkNvYWNoSW5kZXggIT09IG51bGwgJiYgc2VsZWN0ZWROYXZDb2FjaEluZGV4ICE9PSB0aGlzLmN1cnJTZWxlY3RlZENvYWNoSW5kZXgpIHtcbiAgICAgIHRoaXMudW5mb2N1c1BsYWNlRWxlbWVudCgpO1xuICAgICAgdGhpcy5zY3JvbGxUb1NlbGVjdGVkTmF2Q29hY2goc2VsZWN0ZWROYXZDb2FjaEluZGV4KTtcbiAgICB9IGVsc2UgaWYgKHNlbGVjdGVkTmF2Q29hY2hJbmRleCA9PT0gdGhpcy5jdXJyU2VsZWN0ZWRDb2FjaEluZGV4KSB7XG4gICAgICB0aGlzLnVwZGF0ZUN1cnJlbnRTZWxlY3RlZENvYWNoKCk7XG4gICAgICB0aGlzLnByZXNlbGVjdFBsYWNlSW5Db2FjaCgpO1xuICAgIH1cblxuICAgIC8vY2xvc2UgYWxsIG9wZW5lZCBwb3BvdmVyc1xuICAgIHRoaXMuX2Nsb3NlUG9wb3ZlcigpO1xuICB9XG5cbiAgcHJpdmF0ZSBfb25Gb2N1c05hdkNvYWNoKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5wcmV2ZW50Q29hY2hTY3JvbGxCeVBsYWNlQ2xpY2spIHtcbiAgICAgIHRoaXMucHJlc2VsZWN0UGxhY2VJbkNvYWNoKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuZm9jdXNQbGFjZUVsZW1lbnQodGhpcy5jdXJyU2VsZWN0ZWRQbGFjZSk7XG4gICAgfVxuXG4gICAgdGhpcy5pc0F1dG9TY3JvbGxpbmcgPSBmYWxzZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIGEgcG9wb3ZlciBmb3IgZXh0cmEgc2VydmljZSBpbmZvcm1hdGlvblxuICAgKiBAcGFyYW0gdHJpZ2dlcklkXG4gICAqIEBwYXJhbSBwb3BvdmVyQ29udGVudFxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfcG9wb3ZlcihcbiAgICB0cmlnZ2VySWQ6IHN0cmluZyxcbiAgICBwb3BvdmVyQ29udGVudDogc3RyaW5nIHwgbnVsbCB8IHR5cGVvZiBub3RoaW5nLFxuICApOiBUZW1wbGF0ZVJlc3VsdCB7XG4gICAgcmV0dXJuIGh0bWxgXG4gICAgICA8c2JiLXBvcG92ZXIgdHJpZ2dlcj1cIiR7dHJpZ2dlcklkfVwiIGhvdmVyLXRyaWdnZXI9XCJcIj5cbiAgICAgICAgPHAgY2xhc3M9XCJzYmItdGV4dC1zIHNiYi1zci1wb3BvdmVyXCI+JHtwb3BvdmVyQ29udGVudH08L3A+XG4gICAgICA8L3NiYi1wb3BvdmVyPlxuICAgIGA7XG4gIH1cblxuICAvKipcbiAgICogdHJpZ2dlciB0byBjbG9zZSBhbGwgb3BlbmVkIHBvcG92ZXJzIChub3JtYWxseSBvbmx5IG9uZSBpcyBvcGVuZWQgYXQgYSB0aW1lKVxuICAgKiBAcHJpdmF0ZVxuICAgKi9cbiAgcHJpdmF0ZSBfY2xvc2VQb3BvdmVyKCk6IHZvaWQge1xuICAgIHRoaXMuc2hhZG93Um9vdFxuICAgICAgPy5xdWVyeVNlbGVjdG9yQWxsPFNiYlBvcG92ZXJFbGVtZW50Pignc2JiLXBvcG92ZXI6c3RhdGUoc3RhdGUtb3BlbmVkKScpXG4gICAgICAuZm9yRWFjaCgocG9wb3ZlcikgPT4gcG9wb3Zlci5jbG9zZSgpKTtcbiAgfVxuXG4gIHByaXZhdGUgX2dldERlc2NyaXB0aW9uVGFibGVDb2FjaChjb2FjaEl0ZW06IENvYWNoSXRlbSk6IHN0cmluZyB7XG4gICAgaWYgKCFjb2FjaEl0ZW0ucGxhY2VzPy5sZW5ndGgpIHtcbiAgICAgIHJldHVybiBnZXRJMThuU2VhdFJlc2VydmF0aW9uKCdDT0FDSF9CTE9DS0VEX1RBQkxFX0NBUFRJT04nLCB0aGlzLl9sYW5ndWFnZS5jdXJyZW50LCBbXG4gICAgICAgIGNvYWNoSXRlbS5pZCxcbiAgICAgIF0pO1xuICAgIH1cblxuICAgIGxldCB0YWJsZUNvYWNoRGVzY3JpcHRpb246IHN0cmluZztcbiAgICBjb25zdCBhcmVhRGVzY3JpcHRpb25zID0gdGhpcy5fZ2V0VGl0bGVEZXNjcmlwdGlvbkxpc3RTdHJpbmcoY29hY2hJdGVtLmdyYXBoaWNFbGVtZW50cyEpO1xuICAgIGNvbnN0IHNlcnZpY2VEZXNjcmlwdGlvbnMgPSB0aGlzLl9nZXRUaXRsZURlc2NyaXB0aW9uTGlzdFN0cmluZyhjb2FjaEl0ZW0uc2VydmljZUVsZW1lbnRzISk7XG5cbiAgICB0YWJsZUNvYWNoRGVzY3JpcHRpb24gPSBnZXRJMThuU2VhdFJlc2VydmF0aW9uKCdDT0FDSF9UQUJMRV9DQVBUSU9OJywgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCwgW1xuICAgICAgY29hY2hJdGVtLmlkLFxuICAgIF0pO1xuXG4gICAgaWYgKCF0aGlzLmhhc05hdmlnYXRpb24pIHtcbiAgICAgIC8vIEV4cGFuZHMgdGhlIG51bWJlciBvZiBhdmFpbGFibGUgc2VhdHMgYW5kIGJpY3ljbGUgc3BhY2VzIGFzIGluZm9cbiAgICAgIGNvbnN0IGZyZWVQbGFjZXMgPSB0aGlzLmdldEF2YWlsYWJsZUZyZWVQbGFjZXNOdW1Gcm9tQ29hY2goY29hY2hJdGVtLnBsYWNlcyk7XG4gICAgICBjb25zdCBmcmVlUGxhY2VzVHh0ID0gZ2V0STE4blNlYXRSZXNlcnZhdGlvbihcbiAgICAgICAgJ0NPQUNIX0FWQUlMQUJMRV9OVU1CRVJfT0ZfUExBQ0VTJyxcbiAgICAgICAgdGhpcy5fbGFuZ3VhZ2UuY3VycmVudCxcbiAgICAgICAgW2ZyZWVQbGFjZXMuc2VhdHMsIGZyZWVQbGFjZXMuYmljeWNsZXNdLFxuICAgICAgKTtcbiAgICAgIHRhYmxlQ29hY2hEZXNjcmlwdGlvbiA9IHRhYmxlQ29hY2hEZXNjcmlwdGlvbi5jb25jYXQoJy4gJykuY29uY2F0KGZyZWVQbGFjZXNUeHQpLmNvbmNhdCgnLiAnKTtcbiAgICB9XG5cbiAgICBpZiAoISFhcmVhRGVzY3JpcHRpb25zIHx8ICEhc2VydmljZURlc2NyaXB0aW9ucykge1xuICAgICAgdGFibGVDb2FjaERlc2NyaXB0aW9uICs9XG4gICAgICAgICcuICcgKyBnZXRJMThuU2VhdFJlc2VydmF0aW9uKCdDT0FDSF9BVkFJTEFCTEVfU0VSVklDRVMnLCB0aGlzLl9sYW5ndWFnZS5jdXJyZW50KSArICc6ICc7XG4gICAgICB0YWJsZUNvYWNoRGVzY3JpcHRpb24gKz0gc2VydmljZURlc2NyaXB0aW9ucyArICcsICcgKyBhcmVhRGVzY3JpcHRpb25zICsgJy4nO1xuICAgIH1cbiAgICByZXR1cm4gdGFibGVDb2FjaERlc2NyaXB0aW9uO1xuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0VGl0bGVEZXNjcmlwdGlvbkxpc3RTdHJpbmcoZGVzY3JpcHRpb25zRWxlbWVudHM6IEJhc2VFbGVtZW50W10pOiBzdHJpbmcge1xuICAgIGNvbnN0IHVuaXF1ZURlc2NyaXB0aW9uczogc3RyaW5nW10gPSBbXTtcblxuICAgIHJldHVybiBkZXNjcmlwdGlvbnNFbGVtZW50c1xuICAgICAgPy5tYXAoKGRlc2NyaXB0aW9uRWxlbWVudCkgPT4ge1xuICAgICAgICBjb25zdCBpY29uID0gZGVzY3JpcHRpb25FbGVtZW50Lmljb247XG4gICAgICAgIGlmICghaWNvbikgcmV0dXJuIG51bGw7XG5cbiAgICAgICAgY29uc3QgZGVzY3JpcHRpb25BbHJlYWR5RXhpc3QgPSB1bmlxdWVEZXNjcmlwdGlvbnMuaW5kZXhPZihpY29uKSA+IC0xO1xuICAgICAgICBjb25zdCB0cmFuc2xhdGlvbiA9IGdldEkxOG5TZWF0UmVzZXJ2YXRpb24oXG4gICAgICAgICAgZGVzY3JpcHRpb25FbGVtZW50Lmljb24hLFxuICAgICAgICAgIHRoaXMuX2xhbmd1YWdlLmN1cnJlbnQsXG4gICAgICAgICk7XG4gICAgICAgIGNvbnN0IGlzVmFsaWREZXNjcmlwdGlvbiA9XG4gICAgICAgICAgdGhpcy5fbm90Rml4ZWRSb3RhdGFibGVBcmVhSWNvbnMuaW5kZXhPZihpY29uKSA9PT0gLTEgJiZcbiAgICAgICAgICB0aGlzLm5vdEFyZWFFbGVtZW50cy5pbmRleE9mKGljb24pID09PSAtMTtcblxuICAgICAgICBpZiAoIWRlc2NyaXB0aW9uQWxyZWFkeUV4aXN0KSB7XG4gICAgICAgICAgdW5pcXVlRGVzY3JpcHRpb25zLnB1c2goZGVzY3JpcHRpb25FbGVtZW50Lmljb24hKTtcbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gISF0cmFuc2xhdGlvbiAmJiAhZGVzY3JpcHRpb25BbHJlYWR5RXhpc3QgJiYgaXNWYWxpZERlc2NyaXB0aW9uID8gdHJhbnNsYXRpb24gOiBudWxsO1xuICAgICAgfSlcbiAgICAgIC5maWx0ZXIoKGRlc2NyaXB0aW9uKSA9PiAhIWRlc2NyaXB0aW9uKVxuICAgICAgLmpvaW4oJywgJyk7XG4gIH1cbn1cblxuZGVjbGFyZSBnbG9iYWwge1xuICBpbnRlcmZhY2UgSFRNTEVsZW1lbnRUYWdOYW1lTWFwIHtcbiAgICAvLyBlc2xpbnQtZGlzYWJsZS1uZXh0LWxpbmUgQHR5cGVzY3JpcHQtZXNsaW50L25hbWluZy1jb252ZW50aW9uXG4gICAgJ3NiYi1zZWF0LXJlc2VydmF0aW9uJzogU2JiU2VhdFJlc2VydmF0aW9uRWxlbWVudDtcbiAgfVxufVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0lBdUNNLDZCQUF5QixNQUFBOzswQkFEOUIsY0FBYyxzQkFBc0IsQ0FBQzs7OztvQkFDRTtBQUFSLEVBQUEsbUJBQVEsWUFBMEI7QUFBQTs7QUFHeEQsV0FBQSxZQUFZLElBQUksc0JBQXNCLElBQUk7QUFJMUMsV0FBQSw4QkFBOEIsQ0FBQyxZQUFZO0FBQUEsSUErdEJyRDtBQUFBLElBN3RCcUIsV0FBVyxtQkFBdUM7QUFDbkUsWUFBTSxXQUFXLGlCQUFpQjtBQUVsQyxVQUFJLGtCQUFrQixJQUFJLGVBQWUsR0FBRztBQUMxQyxZQUFJLEtBQUssZUFBZTtBQUN0QixlQUFLLFlBQ0QsaUJBQWlCLE9BQU8sRUFDekIsUUFBUSxDQUFDLFVBQVUsTUFBTSxnQkFBZ0IsVUFBVSxDQUFDO0FBQUEsUUFDekQsT0FBTztBQUNMLGVBQUssWUFDRCxpQkFBaUIsT0FBTyxFQUN6QixRQUFRLENBQUMsVUFBVSxNQUFNLGFBQWEsWUFBWSxHQUFHLENBQUM7QUFBQSxRQUMzRDtBQUFBLE1BQ0Y7QUFBQSxJQUNGO0FBQUEsSUFFbUIsYUFBYSxtQkFBdUM7QUFDckUsWUFBTSxhQUFhLGlCQUFpQjtBQUdwQyxXQUFLLGVBQWUsS0FBSyxNQUFLO0FBQzVCLGFBQUsscUNBQUE7QUFBQSxNQUNQLENBQUM7QUFBQSxJQUNIO0FBQUEsSUFFbUIsU0FBTTtBQUN2QixXQUFLLHdDQUFBO0FBQ0wsYUFBTyxLQUFLLHdCQUF3QjtBQUFBLElBQ3RDO0FBQUEsSUFFUSwwQ0FBdUM7QUFDN0MsV0FBSyx1QkFBdUI7QUFBQTtBQUFBLFVBRXRCLEtBQUssbUJBQW1CO0FBQUE7QUFBQTtBQUFBLHFCQUdiLENBQUMsUUFBdUIsS0FBSyw2QkFBNkIsR0FBRyxDQUFDO0FBQUE7QUFBQSxxREFFOUIsS0FBSyxtQkFBbUI7QUFBQTtBQUFBLHNCQUV2RCxNQUFNLEtBQUssbUJBQUEsQ0FBb0I7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSx5QkFPNUIsU0FBUztBQUFBLFFBQ2hCLHNCQUFzQjtBQUFBLFFBQ3RCLDJCQUEyQixLQUFLO0FBQUEsTUFBQSxDQUNqQyxDQUFDO0FBQUE7QUFBQSxrQkFFQSxLQUFLLGtCQUFrQixJQUN2QixDQUFDLGlCQUFrQyxtQkFBMEI7QUFDM0QsZUFBTztBQUFBO0FBQUEsMEJBRUQsS0FBSyxlQUFlLGlCQUFpQixjQUFjLENBQUM7QUFBQTtBQUFBO0FBQUEsTUFHNUQsQ0FBQyxDQUNGO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsSUFPZjtBQUFBLElBRVEsb0JBQWlCO0FBQ3ZCLFVBQUksQ0FBQyxLQUFLO0FBQWtCLGVBQU87QUFFbkMsYUFBTyxLQUFLLGlCQUFpQixJQUFJLENBQUMsb0JBQW1CO0FBQ25ELGNBQU0sa0JBQWtCLHVCQUN0QixnQkFBZ0IsZ0JBQ2hCLEtBQUssVUFBVSxPQUFPO0FBRXhCLGVBQU8sNkJBQTZCLGVBQWU7QUFBQSxNQUNyRCxDQUFDO0FBQUEsSUFDSDtBQUFBLElBRVEsK0JBQStCLGNBQW9CO0FBQ3pELFVBQUksQ0FBQyxLQUFLLGlCQUFpQixDQUFDLEtBQUs7QUFBa0IsZUFBTztBQUMxRCxZQUFNLDJCQUNKLGdCQUFnQixvQkFDWix1REFDQTtBQUNOLFlBQU0sVUFDSixnQkFBZ0Isb0JBQW9CLDhCQUE4QjtBQUNwRSxZQUFNLHFCQUNKLGdCQUFnQixvQkFDWix1QkFBdUIsd0JBQXdCLEtBQUssVUFBVSxPQUFPLElBQ3JFLHVCQUF1QiwwQkFBMEIsS0FBSyxVQUFVLE9BQU87QUFDN0UsVUFBSSxjQUFjO0FBRWxCLFVBQUksZ0JBQWdCLG9CQUFvQixLQUFLLHFCQUFxQixHQUFHO0FBQ25FLHNCQUFjO0FBQUEsTUFDaEIsV0FDRSxnQkFBZ0IscUJBQ2hCLEtBQUsscUJBQXFCLEtBQUssYUFBYSxTQUFTLEdBQ3JEO0FBQ0Esc0JBQWM7QUFBQSxNQUNoQjtBQUVBLGFBQU87QUFBQTtBQUFBLGtCQUVPLE1BQU0sS0FBSyx1QkFBdUIsWUFBWSxDQUFDO0FBQUEsa0JBQy9DLE1BQU0sS0FBSywyQkFBMkI7QUFBQSxjQUMxQyx3QkFBd0I7QUFBQTtBQUFBO0FBQUEscUJBR2pCLE9BQU87QUFBQTtBQUFBLHNCQUVOLGtCQUFrQjtBQUFBO0FBQUEsZ0NBRVIsZUFBZSxPQUFPO0FBQUEscUJBQ2pDLGVBQWUsT0FBTztBQUFBO0FBQUE7QUFBQSxJQUd6QztBQUFBLElBRVEsb0JBQWlCO0FBQ3ZCLFVBQUksQ0FBQyxLQUFLLGlCQUFpQixDQUFDLEtBQUs7QUFBa0IsZUFBTztBQUMxRCxhQUFPO0FBQUE7QUFBQSxVQUVELEtBQUssK0JBQStCLGdCQUFnQixDQUFDO0FBQUE7QUFBQTtBQUFBO0FBQUEsd0JBSXZDLHVCQUNaLCtCQUNBLEtBQUssVUFBVSxPQUFPLENBQ3ZCO0FBQUE7QUFBQSxZQUVDLEtBQUssYUFBYSxJQUFJLENBQUMsaUJBQXNDLFVBQWlCO0FBQzlFLGVBQU87QUFBQTtBQUFBLCtCQUVZLENBQUMsVUFBK0IsS0FBSyxrQkFBa0IsS0FBSyxDQUFDO0FBQUEsOEJBQzlELE1BQU0sS0FBSyxpQkFBQSxDQUFrQjtBQUFBLHlCQUNsQyxDQUFDLFFBQXVCLEtBQUssOEJBQThCLEtBQUssS0FBSyxDQUFDO0FBQUEseUJBQ3RFLEtBQUs7QUFBQSw0QkFDRixnQkFBZ0IsRUFBRTtBQUFBLHFDQUNULGdCQUFnQixVQUFVO0FBQUEsNEJBQ25DLEtBQUssdUJBQXVCLEtBQUs7QUFBQSwyQkFDbEMsS0FBSyxzQkFBc0IsS0FBSztBQUFBLDJCQUNoQyxLQUFLLHNCQUFzQixLQUFLO0FBQUEscUNBQ3RCLEtBQUssNkJBQTZCO0FBQUEsZ0NBQ3ZDLGdCQUFnQixXQUFXO0FBQUEsZ0NBQzNCLGdCQUFnQixXQUFXO0FBQUEsZ0NBQzNCLGdCQUFnQixZQUFZO0FBQUEsMEJBQ2xDLGlCQUFpQixnQkFBZ0IsSUFBSTtBQUFBLHlCQUN0QyxpQkFBaUIsZ0JBQWdCLEtBQUs7QUFBQSw2QkFDbEMsS0FBSyxhQUFhO0FBQUE7QUFBQTtBQUFBO0FBQUEsTUFJckMsQ0FBQyxDQUFDO0FBQUE7QUFBQSxVQUVGLEtBQUssK0JBQStCLGlCQUFpQixDQUFDO0FBQUE7QUFBQTtBQUFBLElBRzlEO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsSUFPUSxlQUNOLGlCQUNBLGdCQUFzQjtBQUV0QixZQUFNLFVBQXVCLEtBQUssTUFBTSxLQUFLLFVBQVUsaUJBQWlCLFVBQVUsQ0FBQztBQUVuRixVQUFJLENBQUMsU0FBUztBQUNaLGVBQU87QUFBQSxNQUNUO0FBQ0EsYUFBTyxRQUFRLElBQUksQ0FBQyxXQUFzQixlQUFzQjtBQUM5RCxlQUFPO0FBQUE7QUFBQSxZQUVELEtBQUssb0JBQ0wsV0FDQSxZQUNBLGdCQUNBLGdCQUFnQixjQUFjLENBQy9CO0FBQUE7QUFBQTtBQUFBLE1BR1AsQ0FBQztBQUFBLElBQ0g7QUFBQSxJQUVRLG9CQUNOLFdBQ0EsWUFDQSxnQkFDQSxxQkFBMkI7QUFFM0IsWUFBTSwyQkFBMkIsS0FBSyx1QkFBdUIsVUFBVSxTQUFTO0FBQ2hGLFlBQU0sb0NBQW9DLEtBQUssMEJBQTBCLFNBQVM7QUFFbEYsYUFBTztBQUFBLGNBQ0csU0FBUztBQUFBLFFBQ2YsdUNBQXVDLHlCQUF5QjtBQUFBLFFBQ2hFLHdDQUF3Qyx5QkFBeUI7QUFBQSxNQUFBLENBQ2xFLENBQUM7QUFBQTtBQUFBLFFBRUEsS0FBSyx5QkFBeUIsU0FBUyxDQUFDO0FBQUEsUUFDeEMsS0FBSyw4QkFDTCxVQUFVLG1CQUFtQixDQUFBLEdBQzdCLFVBQVUsV0FDVixZQUNBLGNBQWMsQ0FDZjtBQUFBLFFBQ0MsS0FBSyw0QkFBNEIsWUFBWSxnQkFBZ0IsVUFBVSxlQUFlLENBQUM7QUFBQTtBQUFBO0FBQUEsaUJBRzlFLE1BQU0sS0FBSyxtQ0FBbUMsVUFBVSxDQUFDO0FBQUEsMkJBQy9DLFVBQVU7QUFBQTtBQUFBLGlEQUVZLFVBQVU7QUFBQTtBQUFBO0FBQUEsNENBR2YsVUFBVTtBQUFBLG9DQUNsQixpQ0FBaUM7QUFBQTtBQUFBLFVBRTNELEtBQUssc0JBQXNCLFdBQVcsWUFBWSxnQkFBZ0IsbUJBQW1CLENBQUM7QUFBQTtBQUFBO0FBQUEsSUFHOUY7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLElBTVEseUJBQXlCLFdBQW9CO0FBQ25ELFVBQUksQ0FBQyxVQUFVO0FBQWlCLGVBQU87QUFFdkMsWUFBTSxzQkFBc0I7QUFDNUIsWUFBTSxjQUFjLFVBQVU7QUFDOUIsWUFBTSxhQUFhLGFBQWEsS0FBSyxDQUFDLFlBQXlCLFFBQVEsU0FBUyxhQUFhO0FBQzdGLFVBQUksY0FBYyxhQUNkLFVBQVUsVUFBVSxJQUFJLFdBQVcsVUFBVSxJQUFJLHNCQUNqRCxVQUFVLFVBQVUsSUFBSSxzQkFBc0I7QUFHbEQscUJBQWUsS0FBSztBQUVwQixZQUFNLGdCQUFnQixVQUFVLFVBQVUsSUFBSSxLQUFLLG9CQUFvQixLQUFLLEtBQUs7QUFDakYsVUFBSSxnQkFDRixjQUFjLFdBQVcsU0FBUyxNQUFNLElBQ3BDLFlBQVksVUFBVSxJQUFJLEtBQUssZUFDL0IsS0FBSztBQUVYLFlBQU0sOEJBQThCLEtBQUssOEJBQThCLEtBQ3JFLENBQUMsT0FBTyxHQUFHLFdBQVcsVUFBVSxFQUFFO0FBTXBDLFVBQ0UsNkJBQTZCLHFCQUM3Qiw2QkFBNkIseUJBQzdCO0FBQ0EsdUJBQWUsSUFBSSxLQUFLO0FBQ3hCLHdCQUFnQjtBQUFBLE1BQ2xCO0FBRUEsYUFBTztBQUFBO0FBQUEsaUJBRU0sU0FBUztBQUFBLFFBQ2hCLHlDQUNFLDZCQUE2QixxQkFDN0IsNkJBQTZCLDJCQUM3QjtBQUFBLE1BQUEsQ0FDSCxDQUFDO0FBQUEsZ0JBQ00sU0FBUztBQUFBLFFBQ2Ysd0NBQXdDO0FBQUEsUUFDeEMseUNBQXlDO0FBQUEsUUFDekMsc0NBQXNDLEtBQUsscUJBQXFCO0FBQUEsUUFDaEUsdUNBQXVDO0FBQUEsUUFDdkMsMkNBQTJDO0FBQUEsTUFBQSxDQUM1QyxDQUFDO0FBQUE7QUFBQSxtQkFFUyxJQUFJO0FBQUE7QUFBQTtBQUFBO0FBQUEsSUFJckI7QUFBQSxJQUVRLHNCQUNOLE9BQ0EsWUFDQSxnQkFDQSxxQkFBMkI7QUFFM0IsVUFBSSxDQUFDLE1BQU0sUUFBUTtBQUNqQixlQUFPO0FBQUEsTUFDVDtBQUdBLFlBQU0saUJBQTBDLENBQUE7QUFDaEQsaUJBQVcsU0FBUyxNQUFNLFFBQVE7QUFDaEMsWUFBSSxDQUFDLGVBQWUsTUFBTSxTQUFTLENBQUMsR0FBRztBQUNyQyx5QkFBZSxNQUFNLFNBQVMsQ0FBQyxJQUFJLENBQUMsS0FBSztBQUFBLFFBQzNDLE9BQU87QUFDTCx5QkFBZSxNQUFNLFNBQVMsQ0FBQyxFQUFFLEtBQUssS0FBSztBQUFBLFFBQzdDO0FBQUEsTUFDRjtBQUVBLGFBQU8sT0FBTyxPQUFPLGNBQWMsRUFDaEMsSUFBSSxDQUFDLFdBQW9CLFVBQVM7QUFDakMsZUFBTztBQUFBLHdCQUNTLFVBQVUsSUFBSSxVQUFVLENBQUMsRUFBRSxTQUFTLENBQUMsb0JBQW9CLEtBQUs7QUFBQSxjQUN4RSxLQUFLLHlCQUNMLFdBQ0EsWUFDQSxnQkFDQSxtQkFBbUIsQ0FDcEI7QUFBQTtBQUFBO0FBQUEsTUFHUCxDQUFDLEVBQ0EsUUFBUSxDQUFDLGdCQUFnQixXQUFXO0FBQUEsSUFDekM7QUFBQSxJQUVRLHlCQUNOLFFBQ0EsWUFDQSxXQUNBLHFCQUEyQjtBQUczQixhQUFPLEtBQ0wsQ0FBQyxRQUFlLFdBQWtCLE9BQU8sT0FBTyxTQUFTLENBQUMsSUFBSSxPQUFPLE9BQU8sU0FBUyxDQUFDLENBQUM7QUFJekYsWUFBTSxlQUFlLGFBQWEsTUFBTTtBQUN4QyxhQUFPLE9BQU8sT0FDWixRQUNBLENBQUMsVUFBVSxlQUFlLE1BQU0sTUFBTSxRQUN0QyxDQUFDLE9BQU8sVUFBUztBQUNmLGNBQU0sc0JBQXNCLEtBQUssdUJBQXVCLE1BQU0sU0FBUztBQUN2RSxjQUFNLHFCQUFxQixLQUFLLHNCQUFzQixNQUFNLFFBQVE7QUFDcEUsY0FBTSxXQUFXLE1BQU0sWUFBWTtBQUNuQyxjQUFNLGVBQWUsS0FBSyxnQkFBZ0IsTUFBTTtBQUNoRCxjQUFNLFVBQVUsS0FBSyxrQkFBa0IsV0FBVyxZQUFZLE1BQU0sTUFBTTtBQUMxRSxlQUFPO0FBQUE7QUFBQSx1QkFFUSxTQUFTLElBQUksVUFBVSxJQUFJLE1BQU0sU0FBUyxDQUFDLElBQUksS0FBSztBQUFBO0FBQUE7QUFBQTtBQUFBLHNCQUlyRCxTQUFTO0FBQUEsVUFDZix5REFBeUQsS0FBSyxJQUM1RCxvQkFBb0IsR0FDcEIsb0JBQW9CLENBQUM7QUFBQSxVQUV2Qiw4Q0FBOEMsb0JBQW9CO0FBQUEsVUFDbEUsK0NBQStDLG9CQUFvQjtBQUFBLFVBQ25FLDRDQUE0QyxtQkFBbUI7QUFBQSxVQUMvRCw2Q0FBNkMsbUJBQW1CO0FBQUEsVUFDaEUsaURBQWlEO0FBQUEsVUFDakQsc0RBQXNEO0FBQUEsUUFBQSxDQUN2RCxDQUFDO0FBQUEsNkJBQ2EsQ0FBQyxxQkFDZCxLQUFLLGVBQWUsZ0JBQWdCLENBQUM7QUFBQTtBQUFBLG1CQUVsQyxPQUFPO0FBQUE7QUFBQSxxQkFFTCxNQUFNLE1BQU07QUFBQSxxQkFDWixNQUFNLElBQUk7QUFBQSxzQkFDVCxNQUFNLEtBQUs7QUFBQSw0QkFDTCxVQUFVO0FBQUEsMkJBQ1gsbUJBQW1CO0FBQUEsZ0NBQ2QsU0FBUztBQUFBLDZCQUNaLE1BQU0sV0FBVztBQUFBLDhCQUNoQixLQUFLLGlCQUFpQjtBQUFBO0FBQUE7QUFBQTtBQUFBLE1BSTlDLENBQUMsQ0FDRjtBQUFBLElBQ0g7QUFBQSxJQUVRLDhCQUNOLG1CQUNBLGdCQUNBLFlBQ0EsZ0JBQXNCO0FBRXRCLFVBQUksQ0FBQztBQUFtQixlQUFPO0FBRS9CLGFBQU8sbUJBQW1CLElBQUksQ0FBQyxxQkFBaUM7QUFDOUQsY0FBTSxPQUFPLGlCQUFpQixRQUFRO0FBQ3RDLGNBQU0sa0JBQWtCLGlCQUFpQixZQUFZO0FBQ3JELGNBQU0scUNBQ0osS0FBSyw0QkFBNEIsUUFBUSxpQkFBaUIsSUFBSyxNQUFNO0FBQ3ZFLGNBQU0sdUJBQ0osS0FBSyxpQkFBaUIscUNBQ2xCLGtCQUFrQixLQUNsQjtBQUdOLFlBQUksS0FBSyxnQkFBZ0IsVUFBVSxDQUFDLG1CQUFtQixtQkFBbUIsSUFBSSxJQUFJLElBQUk7QUFDcEYsaUJBQU8sS0FBSyw2QkFBNkIsa0JBQWtCLGlCQUFpQixjQUFjO0FBQUEsUUFDNUY7QUFDQSxlQUFPLEtBQUssMEJBQ1Ysa0JBQ0Esc0JBQ0EsZ0JBQ0EsWUFDQSxjQUFjO0FBQUEsTUFFbEIsQ0FBQztBQUFBLElBQ0g7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQSxJQVdRLDBCQUNOLGtCQUNBLFVBQ0EsZ0JBQ0EsWUFDQSxnQkFBc0I7QUFLdEIsWUFBTSxvQkFBb0IsaUJBQWlCLE1BQU0sUUFBUSxPQUFPLE1BQU07QUFDdEUsWUFBTSxlQUFlLGlCQUFpQixRQUFRLG9CQUFvQixpQkFBaUIsT0FBTztBQUMxRixZQUFNLGdCQUNKLEtBQUssMEJBQTBCLGtCQUFrQixjQUFjLEtBQy9ELGlCQUFpQjtBQUNuQixZQUFNLG1CQUFtQixpQkFBaUIsT0FDdEMsdUJBQXVCLGlCQUFpQixNQUFNLEtBQUssVUFBVSxPQUFPLElBQ3BFO0FBRUosWUFBTSxzQkFBc0IsS0FBSyx1QkFDL0IsaUJBQWlCLFdBQ2pCLGdCQUNBLE1BQ0EsYUFBYTtBQUdmLFlBQU0scUJBQXFCLEtBQUssc0JBQzlCLGlCQUFpQixVQUNqQixpQkFBaUIsV0FDakIsZ0JBQ0EsSUFBSTtBQUlOLFlBQU0sWUFBWSxtQkFBbUIsY0FBYyxJQUFJLFVBQVUsSUFBSSxtQkFBbUIsQ0FBQyxJQUFJLG1CQUFtQixDQUFDO0FBQ2pILFVBQUksa0JBQWtCO0FBRXRCLFVBQUksaUJBQWlCLFNBQVMsTUFBTSxLQUFLLG9CQUFvQixJQUFJO0FBQy9ELDBCQUFrQjtBQUFBLE1BQ3BCLFdBQ0UsaUJBQWlCLFNBQVMsSUFBSSxpQkFBaUIsVUFBVSxNQUN6RCxlQUFlLElBQUksS0FBSyxtQkFDeEI7QUFDQSwwQkFBa0I7QUFBQSxNQUNwQjtBQU1BLFVBQUksb0JBQW9CLFFBQVE7QUFDOUIsMkJBQW1CLEtBQUssb0JBQW9CLGlCQUFpQixJQUFJO0FBQ2pFLDRCQUFvQixLQUFLO0FBQUEsTUFDM0I7QUFDQSxhQUFPO0FBQUE7QUFBQSxjQUVHLFNBQVM7QUFBQSxpQkFDTixTQUFTLEVBQUUsNkNBQTZDLGlCQUFpQixLQUFBLENBQU0sQ0FBQztBQUFBLGdCQUNqRixTQUFTO0FBQUEsUUFDZixxQ0FBcUMsb0JBQW9CO0FBQUEsUUFDekQsc0NBQXNDLG9CQUFvQjtBQUFBLFFBQzFELG1DQUFtQyxtQkFBbUI7QUFBQSxRQUN0RCxvQ0FBb0MsbUJBQW1CO0FBQUEsTUFBQSxDQUN4RCxDQUFDO0FBQUEsbUJBQ1MsZUFBZTtBQUFBO0FBQUE7QUFBQTtBQUFBLFVBSXhCLGVBQ0U7QUFBQTtBQUFBLHdCQUVZLFNBQVM7QUFBQSxRQUNmLDRDQUE0QyxvQkFBb0I7QUFBQSxRQUNoRSx5Q0FBeUMsS0FBSztBQUFBLFFBQzlDLDJDQUEyQztBQUFBLE1BQUEsQ0FDNUMsQ0FBQztBQUFBLHVCQUNLLFlBQVk7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLGdCQU12QixPQUFPO0FBQUE7QUFBQSxRQUVYLGVBQWUsS0FBSyxTQUFTLFdBQVcsZ0JBQWdCLElBQUksT0FBTztBQUFBO0FBQUEsSUFFekU7QUFBQSxJQUVRLDZCQUNOLGtCQUNBLFVBQ0EsZ0JBQWdDO0FBRWhDLFlBQU0sc0JBQXNCLEtBQUssdUJBQy9CLGlCQUFpQixXQUNqQixjQUFjO0FBRWhCLFlBQU0scUJBQXFCLEtBQUssc0JBQzlCLGlCQUFpQixVQUNqQixpQkFBaUIsV0FDakIsY0FBYztBQUloQixZQUFNLE9BQ0osaUJBQWlCLFFBQVEsaUJBQWlCLEtBQUssUUFBUSxhQUFhLE1BQU0sS0FDdEUsaUJBQWlCLE9BQ2pCLGlCQUFpQixNQUFNLE9BQ3JCLEtBQ0EsS0FBSyxpQkFBaUIsS0FBSyxxQkFBcUIsRUFBRSxXQUFXO0FBR3JFLGFBQU87QUFBQSxjQUNHLFNBQVM7QUFBQSxRQUNmLHdDQUF3QyxvQkFBb0I7QUFBQSxRQUM1RCx5Q0FBeUMsb0JBQW9CO0FBQUEsUUFDN0Qsc0NBQXNDLG1CQUFtQjtBQUFBLFFBQ3pELHVDQUF1QyxtQkFBbUI7QUFBQSxRQUMxRCwyQ0FBMkM7QUFBQSxRQUMzQywyQ0FBMkM7QUFBQSxNQUFBLENBQzVDLENBQUM7QUFBQSxhQUNLLFFBQVEsT0FBTztBQUFBO0FBQUEsaUJBRVgsSUFBSTtBQUFBO0FBQUEsSUFFbkI7QUFBQSxJQUVRLDRCQUNOLFlBQ0EsZ0JBQ0EsaUJBQStCO0FBRS9CLFVBQUksQ0FBQztBQUFpQixlQUFPO0FBRTdCLGFBQU8saUJBQWlCLElBQUksQ0FBQyxtQkFBK0I7QUFDMUQsY0FBTSxtQkFBbUIsZUFBZSxPQUNwQyx1QkFBdUIsZUFBZSxNQUFNLEtBQUssVUFBVSxPQUFPLElBQ2xFO0FBQ0osY0FBTSxzQkFBc0IsS0FBSyx1QkFBdUIsZUFBZSxTQUFTO0FBQ2hGLGNBQU0scUJBQXFCLEtBQUssc0JBQXNCLGVBQWUsUUFBUTtBQUM3RSxjQUFNLGtCQUFrQixlQUFlLFlBQVk7QUFDbkQsY0FBTSx1QkFBdUIsS0FBSyxnQkFBZ0Isa0JBQWtCLEtBQUs7QUFHekUsY0FBTSxZQUFZLG1CQUFtQixjQUFjLElBQUksVUFBVSxJQUFJLG1CQUFtQixDQUFDLElBQUksbUJBQW1CLENBQUM7QUFFakgsZUFBTztBQUFBO0FBQUEsZ0JBRUcsU0FBUztBQUFBLGtCQUNQLFNBQVM7QUFBQSxVQUNmLHdDQUF3QyxvQkFBb0I7QUFBQSxVQUM1RCx5Q0FBeUMsb0JBQW9CO0FBQUEsVUFDN0Qsc0NBQXNDLG1CQUFtQjtBQUFBLFVBQ3pELHVDQUF1QyxtQkFBbUI7QUFBQSxVQUMxRCwyQ0FBMkM7QUFBQSxVQUMzQywyQ0FBMkM7QUFBQSxRQUFBLENBQzVDLENBQUM7QUFBQTtBQUFBLGlCQUVLLGVBQWUsUUFBUSxPQUFPO0FBQUE7QUFBQTtBQUFBO0FBQUEsVUFJckMsS0FBSyxTQUFTLFdBQVcsZ0JBQWdCLENBQUM7QUFBQTtBQUFBLE1BRWhELENBQUM7QUFBQSxJQUNIO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLElBT1EsZUFBZSxrQkFBNkM7QUFDbEUsWUFBTSxnQkFBZ0IsaUJBQWlCO0FBRXZDLFdBQUssaUNBQWlDO0FBQ3RDLFdBQUssdUJBQXVCO0FBQzVCLFdBQUssb0JBQW9CO0FBR3pCLFVBQUksQ0FBQyxLQUFLLCtCQUErQjtBQUN2QyxhQUFLLGdDQUFnQztBQUFBLE1BQ3ZDO0FBRUEsVUFBSSxDQUFDLEtBQUssbUJBQW1CO0FBRTNCLGFBQUssb0NBQW9DLGFBQWE7QUFDdEQsYUFBSyxrQ0FBa0MsYUFBYTtBQUFBLE1BQ3REO0FBQUEsSUFDRjtBQUFBLElBRVEsa0JBQWtCLE9BQTBCO0FBQ2xELFlBQU0sd0JBQXdCLE1BQU07QUFFcEMsV0FBSyx1QkFBdUI7QUFDNUIsV0FBSyxpQ0FBaUM7QUFDdEMsV0FBSyxnQ0FBZ0M7QUFFckMsVUFBSSwwQkFBMEIsUUFBUSwwQkFBMEIsS0FBSyx3QkFBd0I7QUFDM0YsYUFBSyxvQkFBQTtBQUNMLGFBQUsseUJBQXlCLHFCQUFxQjtBQUFBLE1BQ3JELFdBQVcsMEJBQTBCLEtBQUssd0JBQXdCO0FBQ2hFLGFBQUssMkJBQUE7QUFDTCxhQUFLLHNCQUFBO0FBQUEsTUFDUDtBQUdBLFdBQUssY0FBQTtBQUFBLElBQ1A7QUFBQSxJQUVRLG1CQUFnQjtBQUN0QixVQUFJLENBQUMsS0FBSyxnQ0FBZ0M7QUFDeEMsYUFBSyxzQkFBQTtBQUFBLE1BQ1AsT0FBTztBQUNMLGFBQUssa0JBQWtCLEtBQUssaUJBQWlCO0FBQUEsTUFDL0M7QUFFQSxXQUFLLGtCQUFrQjtBQUFBLElBQ3pCO0FBQUE7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBO0FBQUEsSUFRUSxTQUNOLFdBQ0EsZ0JBQThDO0FBRTlDLGFBQU87QUFBQSw4QkFDbUIsU0FBUztBQUFBLCtDQUNRLGNBQWM7QUFBQTtBQUFBO0FBQUEsSUFHM0Q7QUFBQTtBQUFBO0FBQUE7QUFBQTtBQUFBLElBTVEsZ0JBQWE7QUFDbkIsV0FBSyxZQUNELGlCQUFvQyw0REFBaUMsRUFDdEUsUUFBUSxDQUFDLFlBQVksUUFBUSxPQUFPO0FBQUEsSUFDekM7QUFBQSxJQUVRLDBCQUEwQixXQUFvQjtBQUNwRCxVQUFJLENBQUMsVUFBVSxRQUFRLFFBQVE7QUFDN0IsZUFBTyx1QkFBdUIsK0JBQStCLEtBQUssVUFBVSxTQUFTO0FBQUEsVUFDbkYsVUFBVTtBQUFBLFFBQUEsQ0FDWDtBQUFBLE1BQ0g7QUFFQSxVQUFJO0FBQ0osWUFBTSxtQkFBbUIsS0FBSywrQkFBK0IsVUFBVSxlQUFnQjtBQUN2RixZQUFNLHNCQUFzQixLQUFLLCtCQUErQixVQUFVLGVBQWdCO0FBRTFGLDhCQUF3Qix1QkFBdUIsdUJBQXVCLEtBQUssVUFBVSxTQUFTO0FBQUEsUUFDNUYsVUFBVTtBQUFBLE1BQUEsQ0FDWDtBQUVELFVBQUksQ0FBQyxLQUFLLGVBQWU7QUFFdkIsY0FBTSxhQUFhLEtBQUssbUNBQW1DLFVBQVUsTUFBTTtBQUMzRSxjQUFNLGdCQUFnQix1QkFDcEIsb0NBQ0EsS0FBSyxVQUFVLFNBQ2YsQ0FBQyxXQUFXLE9BQU8sV0FBVyxRQUFRLENBQUM7QUFFekMsZ0NBQXdCLHNCQUFzQixPQUFPLElBQUksRUFBRSxPQUFPLGFBQWEsRUFBRSxPQUFPLElBQUk7QUFBQSxNQUM5RjtBQUVBLFVBQUksQ0FBQyxDQUFDLG9CQUFvQixDQUFDLENBQUMscUJBQXFCO0FBQy9DLGlDQUNFLE9BQU8sdUJBQXVCLDRCQUE0QixLQUFLLFVBQVUsT0FBTyxJQUFJO0FBQ3RGLGlDQUF5QixzQkFBc0IsT0FBTyxtQkFBbUI7QUFBQSxNQUMzRTtBQUNBLGFBQU87QUFBQSxJQUNUO0FBQUEsSUFFUSwrQkFBK0Isc0JBQW1DO0FBQ3hFLFlBQU0scUJBQStCLENBQUE7QUFFckMsYUFBTyxzQkFDSCxJQUFJLENBQUMsdUJBQXNCO0FBQzNCLGNBQU0sT0FBTyxtQkFBbUI7QUFDaEMsWUFBSSxDQUFDO0FBQU0saUJBQU87QUFFbEIsY0FBTSwwQkFBMEIsbUJBQW1CLFFBQVEsSUFBSSxJQUFJO0FBQ25FLGNBQU0sY0FBYyx1QkFDbEIsbUJBQW1CLE1BQ25CLEtBQUssVUFBVSxPQUFPO0FBRXhCLGNBQU0scUJBQ0osS0FBSyw0QkFBNEIsUUFBUSxJQUFJLE1BQU0sTUFDbkQsS0FBSyxnQkFBZ0IsUUFBUSxJQUFJLE1BQU07QUFFekMsWUFBSSxDQUFDLHlCQUF5QjtBQUM1Qiw2QkFBbUIsS0FBSyxtQkFBbUIsSUFBSztBQUFBLFFBQ2xEO0FBQ0EsZUFBTyxDQUFDLENBQUMsZUFBZSxDQUFDLDJCQUEyQixxQkFBcUIsY0FBYztBQUFBLE1BQ3pGLENBQUMsRUFDQSxPQUFPLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxXQUFXLEVBQ3JDLEtBQUssSUFBSTtBQUFBLElBQ2Q7QUFBQTs7QUFydUJGLGlCQUFBLE1BQUEsbUJBQUEsRUFBQSxPQUFBLFdBQUEsR0FBQSxrQkFBQSxFQUFBLE1BQUEsU0FBQSxNQUFBLFdBQUEsTUFBQSxVQUFBLFVBQUEsR0FBQSxNQUFBLHVCQUFBOzs7UUFDeUIsR0FBQSxTQUF5QixDQUFDLGlCQUFpQixLQUFLLEdBRG5FLGtCQUFBLFlBQUEsdUJBQUEsR0FBMEI7OzsifQ==