@energycap/components 0.41.1-ECAP-26841-date-input-features.20250108-1149 → 0.42.1

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 (357) hide show
  1. package/{esm2020 → esm2022}/energycap-components.mjs +4 -4
  2. package/{esm2020 → esm2022}/lib/components.module.mjs +423 -423
  3. package/esm2022/lib/controls/banner/banner.component.mjs +109 -0
  4. package/esm2022/lib/controls/button/button.component.mjs +106 -0
  5. package/esm2022/lib/controls/button/copy-button-base.directive.mjs +67 -0
  6. package/{esm2020 → esm2022}/lib/controls/button/copy-button.directive.mjs +28 -28
  7. package/esm2022/lib/controls/button/copy-table-button.directive.mjs +43 -0
  8. package/esm2022/lib/controls/calendar/calendar-item.component.mjs +91 -0
  9. package/esm2022/lib/controls/calendar/calendar.component.mjs +248 -0
  10. package/{esm2020 → esm2022}/lib/controls/calendar/calendar.types.mjs +1 -1
  11. package/esm2022/lib/controls/checkbox/checkbox.component.mjs +140 -0
  12. package/{esm2020 → esm2022}/lib/controls/collapsible-toggle/collapsible-toggle.component.mjs +38 -38
  13. package/esm2022/lib/controls/combobox/combobox.component.mjs +879 -0
  14. package/esm2022/lib/controls/date-input/date-input-selection-strategies/date-input-selection-strategy-base.mjs +57 -0
  15. package/esm2022/lib/controls/date-input/date-input-selection-strategies/day-selection-strategy.mjs +62 -0
  16. package/esm2022/lib/controls/date-input/date-input-selection-strategies/last-28-days-selection-strategy.mjs +100 -0
  17. package/esm2022/lib/controls/date-input/date-input-selection-strategies/last-7-days-selection-strategy.mjs +101 -0
  18. package/esm2022/lib/controls/date-input/date-input-selection-strategies/month-selection-strategy.mjs +76 -0
  19. package/esm2022/lib/controls/date-input/date-input-selection-strategies/quarter-selection-strategy.mjs +79 -0
  20. package/esm2022/lib/controls/date-input/date-input-selection-strategies/range-selection-strategy.mjs +210 -0
  21. package/esm2022/lib/controls/date-input/date-input-selection-strategies/year-selection-strategy.mjs +81 -0
  22. package/esm2022/lib/controls/date-input/date-input.component.mjs +465 -0
  23. package/{esm2020 → esm2022}/lib/controls/date-input/date-input.types.mjs +44 -44
  24. package/esm2022/lib/controls/dropdown/dropdown.component.mjs +243 -0
  25. package/esm2022/lib/controls/file-upload/file-upload.component.mjs +261 -0
  26. package/esm2022/lib/controls/form-control/form-control.component.mjs +98 -0
  27. package/esm2022/lib/controls/form-control-base.mjs +151 -0
  28. package/esm2022/lib/controls/form-control-label/form-control-label.component.mjs +136 -0
  29. package/esm2022/lib/controls/form-group/form-group.component.mjs +261 -0
  30. package/{esm2020 → esm2022}/lib/controls/help-popover/help-popover.component.mjs +31 -31
  31. package/esm2022/lib/controls/item-picker/item-picker.component.mjs +329 -0
  32. package/{esm2020 → esm2022}/lib/controls/link-button/link-button.component.mjs +11 -11
  33. package/esm2022/lib/controls/menu/menu.component.mjs +485 -0
  34. package/{esm2020 → esm2022}/lib/controls/navigation/link-item.mjs +1 -1
  35. package/esm2022/lib/controls/navigation/nav-group.mjs +39 -0
  36. package/esm2022/lib/controls/navigation/nav-item-active.directive.mjs +92 -0
  37. package/{esm2020 → esm2022}/lib/controls/navigation/nav-item.mjs +1 -1
  38. package/esm2022/lib/controls/numericbox/numericbox.component.mjs +372 -0
  39. package/esm2022/lib/controls/popover/popover.component.mjs +117 -0
  40. package/{esm2020 → esm2022}/lib/controls/radio-button/radio-button-option.mjs +2 -2
  41. package/esm2022/lib/controls/radio-button/radio-button.component.mjs +82 -0
  42. package/esm2022/lib/controls/select/select.component.mjs +88 -0
  43. package/esm2022/lib/controls/tabs/tabs.component.mjs +47 -0
  44. package/esm2022/lib/controls/textbox/textbox.component.mjs +155 -0
  45. package/esm2022/lib/core/cache.service.mjs +105 -0
  46. package/esm2022/lib/core/custom-validators.mjs +29 -0
  47. package/esm2022/lib/core/date-time-helper.mjs +228 -0
  48. package/esm2022/lib/core/error.service.mjs +61 -0
  49. package/esm2022/lib/core/router-helper.service.mjs +111 -0
  50. package/esm2022/lib/core/scroll.service.mjs +89 -0
  51. package/{esm2020 → esm2022}/lib/core/telemetry-tracker.service.mjs +16 -16
  52. package/{esm2020 → esm2022}/lib/core/telemetry.service.mjs +38 -38
  53. package/esm2022/lib/core/validation-message.service.mjs +185 -0
  54. package/{esm2020 → esm2022}/lib/core/validation-patterns.mjs +30 -30
  55. package/esm2022/lib/core/window.service.mjs +186 -0
  56. package/esm2022/lib/display/app-bar/app-bar.component.mjs +46 -0
  57. package/esm2022/lib/display/avatar/avatar.component.mjs +67 -0
  58. package/esm2022/lib/display/avatar/avatar.service.mjs +64 -0
  59. package/esm2022/lib/display/confirm/confirm.component.mjs +168 -0
  60. package/{esm2020 → esm2022}/lib/display/dialog/dialog-content.mjs +1 -1
  61. package/esm2022/lib/display/dialog/dialog-group/dialog-group.component.mjs +63 -0
  62. package/{esm2020 → esm2022}/lib/display/dialog/dialog-types.mjs +76 -76
  63. package/esm2022/lib/display/dialog/dialog.component.mjs +281 -0
  64. package/{esm2020 → esm2022}/lib/display/dialog/dialog.service.mjs +71 -71
  65. package/{esm2020 → esm2022}/lib/display/help/help-types.mjs +1 -1
  66. package/esm2022/lib/display/hierarchy/hierarchy-base.mjs +111 -0
  67. package/{esm2020 → esm2022}/lib/display/hierarchy/hierarchy-mocks.spec.mjs +53 -53
  68. package/esm2022/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.mjs +61 -0
  69. package/esm2022/lib/display/item-display/item-display.component.mjs +81 -0
  70. package/esm2022/lib/display/json-display/json-display.component.mjs +47 -0
  71. package/esm2022/lib/display/resizable/resizable-base.mjs +120 -0
  72. package/{esm2020 → esm2022}/lib/display/resizable/resizable.component.mjs +52 -52
  73. package/{esm2020 → esm2022}/lib/display/spinner/spinner.component.mjs +12 -12
  74. package/esm2022/lib/display/splash/splash.component.mjs +42 -0
  75. package/{esm2020 → esm2022}/lib/display/splash/splash.service.mjs +35 -35
  76. package/{esm2020 → esm2022}/lib/display/table/resizable-column.component.mjs +20 -20
  77. package/esm2022/lib/display/table/resizable-table.directive.mjs +227 -0
  78. package/esm2022/lib/display/table/searchable-table.component.mjs +342 -0
  79. package/{esm2020 → esm2022}/lib/display/table/table-detail-row.component.mjs +19 -19
  80. package/esm2022/lib/display/table/table-locked-column.component.mjs +58 -0
  81. package/{esm2020 → esm2022}/lib/display/table/table-master-header-row.component.mjs +14 -14
  82. package/esm2022/lib/display/table/table-master-row.component.mjs +163 -0
  83. package/esm2022/lib/display/table/table-pagination.component.mjs +155 -0
  84. package/esm2022/lib/display/table/table-selectable-row.component.mjs +235 -0
  85. package/esm2022/lib/display/table/table.component.mjs +249 -0
  86. package/esm2022/lib/display/tags/tag.mjs +18 -0
  87. package/esm2022/lib/display/tags/tags.component.mjs +77 -0
  88. package/esm2022/lib/display/toast/toast/toast.component.mjs +77 -0
  89. package/{esm2020 → esm2022}/lib/display/toast/toast-types.mjs +7 -7
  90. package/{esm2020 → esm2022}/lib/display/toast/toast.service.mjs +35 -35
  91. package/esm2022/lib/display/toast/toaster/toaster.component.mjs +114 -0
  92. package/{esm2020 → esm2022}/lib/display/tooltip/tooltip.component.mjs +28 -28
  93. package/{esm2020 → esm2022}/lib/display/tooltip/tooltip.service.mjs +78 -78
  94. package/esm2022/lib/display/tooltip-directive/tooltip.directive.mjs +173 -0
  95. package/{esm2020 → esm2022}/lib/display/tour/tour-types.mjs +33 -33
  96. package/esm2022/lib/display/tour/tour.component.mjs +398 -0
  97. package/esm2022/lib/display/tour/tour.service.mjs +75 -0
  98. package/esm2022/lib/display/tree/tree.component.mjs +135 -0
  99. package/esm2022/lib/display/view-overlay/view-overlay.component.mjs +58 -0
  100. package/esm2022/lib/shared/directives/click-area-for/click-area-for.directive.mjs +32 -0
  101. package/esm2022/lib/shared/directives/if-viewport-width/if-viewport-width.directive.mjs +111 -0
  102. package/{esm2020 → esm2022}/lib/shared/directives/keyboard-nav-container/keyboard-nav-container.directive.mjs +100 -100
  103. package/esm2022/lib/shared/directives/popup/popup-container.directive.mjs +166 -0
  104. package/esm2022/lib/shared/display/pipes/date-display.pipe.mjs +50 -0
  105. package/esm2022/lib/shared/display/pipes/highlight-text.pipe.mjs +30 -0
  106. package/esm2022/lib/shared/display/pipes/relative-date.pipe.mjs +62 -0
  107. package/esm2022/lib/shared/display/pipes/row-count.pipe.mjs +48 -0
  108. package/esm2022/lib/shared/display/pipes/time-display.pipe.mjs +41 -0
  109. package/esm2022/lib/shared/display.mjs +6 -0
  110. package/esm2022/lib/shared/form-group.helper.mjs +67 -0
  111. package/esm2022/lib/shared/json-helper.mjs +19 -0
  112. package/esm2022/lib/shared/lodash-helper.mjs +52 -0
  113. package/esm2022/lib/shared/page/page-base/page-base.component.mjs +387 -0
  114. package/{esm2020 → esm2022}/lib/shared/page/page-statuses.mjs +22 -22
  115. package/{esm2020 → esm2022}/lib/shared/page/page-title/page-title.component.mjs +23 -23
  116. package/esm2022/lib/shared/page/page-view/page-view.component.mjs +147 -0
  117. package/{esm2020 → esm2022}/lib/shared/testing/copy-button-base-test-injector-factory.spec.mjs +16 -16
  118. package/{esm2020 → esm2022}/lib/shared/testing/hierarchy-base-test-injector-factory.spec.mjs +16 -16
  119. package/{esm2020 → esm2022}/lib/shared/testing/page-base-component-test-helper.spec.mjs +37 -37
  120. package/esm2022/lib/shared/testing/page-base-component-test-injector-factory.spec.mjs +98 -0
  121. package/{esm2020 → esm2022}/lib/shared/testing/public-mocks.spec.mjs +148 -148
  122. package/{esm2020 → esm2022}/lib/shared/testing/spy-factory.spec.mjs +39 -39
  123. package/{esm2020 → esm2022}/lib/shared/testing/translation-mocks.spec.mjs +56 -56
  124. package/{esm2020 → esm2022}/lib/shared/user-preference.service.mjs +17 -17
  125. package/esm2022/lib/shared/wizard/wizard-base/wizard-base.component.mjs +246 -0
  126. package/{esm2020 → esm2022}/lib/shared/wizard/wizard-buttons/wizard-buttons.component.mjs +68 -68
  127. package/{esm2020 → esm2022}/lib/shared/wizard/wizard-progress/wizard-progress.component.mjs +18 -18
  128. package/{esm2020 → esm2022}/public-api.mjs +116 -116
  129. package/{fesm2020 → fesm2022}/energycap-components.mjs +12956 -12952
  130. package/fesm2022/energycap-components.mjs.map +1 -0
  131. package/index.d.ts +5 -5
  132. package/lib/components.module.d.ts +92 -92
  133. package/lib/controls/banner/banner.component.d.ts +50 -50
  134. package/lib/controls/button/button.component.d.ts +78 -78
  135. package/lib/controls/button/copy-button-base.directive.d.ts +20 -20
  136. package/lib/controls/button/copy-button.directive.d.ts +14 -14
  137. package/lib/controls/button/copy-table-button.directive.d.ts +19 -19
  138. package/lib/controls/calendar/calendar-item.component.d.ts +22 -22
  139. package/lib/controls/calendar/calendar.component.d.ts +52 -52
  140. package/lib/controls/calendar/calendar.types.d.ts +11 -11
  141. package/lib/controls/checkbox/checkbox.component.d.ts +65 -65
  142. package/lib/controls/collapsible-toggle/collapsible-toggle.component.d.ts +25 -25
  143. package/lib/controls/combobox/combobox.component.d.ts +418 -418
  144. package/lib/controls/date-input/date-input-selection-strategies/date-input-selection-strategy-base.d.ts +42 -42
  145. package/lib/controls/date-input/date-input-selection-strategies/day-selection-strategy.d.ts +21 -21
  146. package/lib/controls/date-input/date-input-selection-strategies/last-28-days-selection-strategy.d.ts +21 -21
  147. package/lib/controls/date-input/date-input-selection-strategies/last-7-days-selection-strategy.d.ts +21 -21
  148. package/lib/controls/date-input/date-input-selection-strategies/month-selection-strategy.d.ts +18 -18
  149. package/lib/controls/date-input/date-input-selection-strategies/quarter-selection-strategy.d.ts +18 -18
  150. package/lib/controls/date-input/date-input-selection-strategies/range-selection-strategy.d.ts +21 -21
  151. package/lib/controls/date-input/date-input-selection-strategies/year-selection-strategy.d.ts +20 -20
  152. package/lib/controls/date-input/date-input.component.d.ts +115 -115
  153. package/lib/controls/date-input/date-input.types.d.ts +62 -62
  154. package/lib/controls/dropdown/dropdown.component.d.ts +161 -161
  155. package/lib/controls/file-upload/file-upload.component.d.ts +124 -124
  156. package/lib/controls/form-control/form-control.component.d.ts +28 -28
  157. package/lib/controls/form-control-base.d.ts +110 -110
  158. package/lib/controls/form-control-label/form-control-label.component.d.ts +73 -73
  159. package/lib/controls/form-group/form-group.component.d.ts +105 -105
  160. package/lib/controls/help-popover/help-popover.component.d.ts +11 -11
  161. package/lib/controls/item-picker/item-picker.component.d.ts +164 -164
  162. package/lib/controls/link-button/link-button.component.d.ts +5 -5
  163. package/lib/controls/menu/menu.component.d.ts +255 -255
  164. package/lib/controls/navigation/link-item.d.ts +32 -32
  165. package/lib/controls/navigation/nav-group.d.ts +18 -18
  166. package/lib/controls/navigation/nav-item-active.directive.d.ts +42 -42
  167. package/lib/controls/navigation/nav-item.d.ts +31 -31
  168. package/lib/controls/numericbox/numericbox.component.d.ts +148 -148
  169. package/lib/controls/popover/popover.component.d.ts +51 -51
  170. package/lib/controls/radio-button/radio-button-option.d.ts +19 -19
  171. package/lib/controls/radio-button/radio-button.component.d.ts +53 -53
  172. package/lib/controls/select/select.component.d.ts +44 -44
  173. package/lib/controls/tabs/tabs.component.d.ts +30 -30
  174. package/lib/controls/textbox/textbox.component.d.ts +107 -107
  175. package/lib/core/cache.service.d.ts +33 -33
  176. package/lib/core/custom-validators.d.ts +20 -20
  177. package/lib/core/date-time-helper.d.ts +101 -101
  178. package/lib/core/error.service.d.ts +20 -20
  179. package/lib/core/router-helper.service.d.ts +48 -48
  180. package/lib/core/scroll.service.d.ts +36 -36
  181. package/lib/core/telemetry-tracker.service.d.ts +13 -13
  182. package/lib/core/telemetry.service.d.ts +31 -31
  183. package/lib/core/validation-message.service.d.ts +26 -26
  184. package/lib/core/validation-patterns.d.ts +22 -22
  185. package/lib/core/window.service.d.ts +116 -116
  186. package/lib/display/app-bar/app-bar.component.d.ts +20 -20
  187. package/lib/display/avatar/avatar.component.d.ts +35 -35
  188. package/lib/display/avatar/avatar.service.d.ts +24 -24
  189. package/lib/display/confirm/confirm.component.d.ts +123 -123
  190. package/lib/display/dialog/dialog-content.d.ts +19 -19
  191. package/lib/display/dialog/dialog-group/dialog-group.component.d.ts +32 -32
  192. package/lib/display/dialog/dialog-types.d.ts +130 -130
  193. package/lib/display/dialog/dialog.component.d.ts +120 -120
  194. package/lib/display/dialog/dialog.service.d.ts +48 -48
  195. package/lib/display/help/help-types.d.ts +33 -33
  196. package/lib/display/hierarchy/hierarchy-base.d.ts +97 -97
  197. package/lib/display/hierarchy/hierarchy-mocks.spec.d.ts +53 -53
  198. package/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.d.ts +34 -34
  199. package/lib/display/item-display/item-display.component.d.ts +43 -43
  200. package/lib/display/json-display/json-display.component.d.ts +16 -16
  201. package/lib/display/resizable/resizable-base.d.ts +67 -67
  202. package/lib/display/resizable/resizable.component.d.ts +31 -31
  203. package/lib/display/spinner/spinner.component.d.ts +5 -5
  204. package/lib/display/splash/splash.component.d.ts +16 -16
  205. package/lib/display/splash/splash.service.d.ts +22 -22
  206. package/lib/display/table/resizable-column.component.d.ts +10 -10
  207. package/lib/display/table/resizable-table.directive.d.ts +93 -93
  208. package/lib/display/table/searchable-table.component.d.ts +206 -206
  209. package/lib/display/table/table-detail-row.component.d.ts +8 -8
  210. package/lib/display/table/table-locked-column.component.d.ts +20 -20
  211. package/lib/display/table/table-master-header-row.component.d.ts +9 -9
  212. package/lib/display/table/table-master-row.component.d.ts +113 -113
  213. package/lib/display/table/table-pagination.component.d.ts +91 -91
  214. package/lib/display/table/table-selectable-row.component.d.ts +102 -102
  215. package/lib/display/table/table.component.d.ts +121 -121
  216. package/lib/display/tags/tag.d.ts +18 -18
  217. package/lib/display/tags/tags.component.d.ts +48 -48
  218. package/lib/display/toast/toast/toast.component.d.ts +23 -23
  219. package/lib/display/toast/toast-types.d.ts +24 -24
  220. package/lib/display/toast/toast.service.d.ts +20 -20
  221. package/lib/display/toast/toaster/toaster.component.d.ts +35 -35
  222. package/lib/display/tooltip/tooltip.component.d.ts +70 -70
  223. package/lib/display/tooltip/tooltip.service.d.ts +16 -16
  224. package/lib/display/tooltip-directive/tooltip.directive.d.ts +44 -44
  225. package/lib/display/tour/tour-types.d.ts +70 -70
  226. package/lib/display/tour/tour.component.d.ts +147 -147
  227. package/lib/display/tour/tour.service.d.ts +38 -38
  228. package/lib/display/tree/tree.component.d.ts +75 -75
  229. package/lib/display/view-overlay/view-overlay.component.d.ts +38 -38
  230. package/lib/shared/directives/click-area-for/click-area-for.directive.d.ts +14 -14
  231. package/lib/shared/directives/if-viewport-width/if-viewport-width.directive.d.ts +60 -60
  232. package/lib/shared/directives/keyboard-nav-container/keyboard-nav-container.directive.d.ts +23 -23
  233. package/lib/shared/directives/popup/popup-container.directive.d.ts +101 -101
  234. package/lib/shared/display/pipes/date-display.pipe.d.ts +21 -21
  235. package/lib/shared/display/pipes/highlight-text.pipe.d.ts +9 -9
  236. package/lib/shared/display/pipes/relative-date.pipe.d.ts +36 -36
  237. package/lib/shared/display/pipes/row-count.pipe.d.ts +23 -23
  238. package/lib/shared/display/pipes/time-display.pipe.d.ts +18 -18
  239. package/lib/shared/display.d.ts +42 -42
  240. package/lib/shared/form-group.helper.d.ts +31 -31
  241. package/lib/shared/json-helper.d.ts +7 -7
  242. package/lib/shared/lodash-helper.d.ts +18 -18
  243. package/lib/shared/page/page-base/page-base.component.d.ts +259 -259
  244. package/lib/shared/page/page-statuses.d.ts +13 -13
  245. package/lib/shared/page/page-title/page-title.component.d.ts +9 -9
  246. package/lib/shared/page/page-view/page-view.component.d.ts +102 -102
  247. package/lib/shared/testing/copy-button-base-test-injector-factory.spec.d.ts +4 -4
  248. package/lib/shared/testing/hierarchy-base-test-injector-factory.spec.d.ts +4 -4
  249. package/lib/shared/testing/page-base-component-test-helper.spec.d.ts +30 -30
  250. package/lib/shared/testing/page-base-component-test-injector-factory.spec.d.ts +28 -28
  251. package/lib/shared/testing/public-mocks.spec.d.ts +90 -90
  252. package/lib/shared/testing/spy-factory.spec.d.ts +27 -27
  253. package/lib/shared/testing/translation-mocks.spec.d.ts +30 -30
  254. package/lib/shared/user-preference.service.d.ts +13 -13
  255. package/lib/shared/wizard/wizard-base/wizard-base.component.d.ts +134 -134
  256. package/lib/shared/wizard/wizard-buttons/wizard-buttons.component.d.ts +27 -27
  257. package/lib/shared/wizard/wizard-progress/wizard-progress.component.d.ts +10 -10
  258. package/package.json +12 -18
  259. package/public-api.d.ts +113 -113
  260. package/schematics/rxjs-7-upgrade/index.d.ts +3 -3
  261. package/schematics/rxjs-7-upgrade/index.js +67 -67
  262. package/schematics/rxjs-7-upgrade/index.js.map +1 -1
  263. package/schematics/rxjs-7-upgrade/schema.d.ts +4 -4
  264. package/schematics/rxjs-7-upgrade/schema.js +2 -2
  265. package/schematics/utilities/typescript.d.ts +7 -7
  266. package/schematics/utilities/typescript.js +41 -41
  267. package/schematics/utilities/workspace.d.ts +8 -8
  268. package/schematics/utilities/workspace.js +71 -71
  269. package/schematics/utilities/workspace.js.map +1 -1
  270. package/esm2020/lib/controls/banner/banner.component.mjs +0 -109
  271. package/esm2020/lib/controls/button/button.component.mjs +0 -106
  272. package/esm2020/lib/controls/button/copy-button-base.directive.mjs +0 -67
  273. package/esm2020/lib/controls/button/copy-table-button.directive.mjs +0 -43
  274. package/esm2020/lib/controls/calendar/calendar-item.component.mjs +0 -91
  275. package/esm2020/lib/controls/calendar/calendar.component.mjs +0 -248
  276. package/esm2020/lib/controls/checkbox/checkbox.component.mjs +0 -140
  277. package/esm2020/lib/controls/combobox/combobox.component.mjs +0 -879
  278. package/esm2020/lib/controls/date-input/date-input-selection-strategies/date-input-selection-strategy-base.mjs +0 -57
  279. package/esm2020/lib/controls/date-input/date-input-selection-strategies/day-selection-strategy.mjs +0 -62
  280. package/esm2020/lib/controls/date-input/date-input-selection-strategies/last-28-days-selection-strategy.mjs +0 -100
  281. package/esm2020/lib/controls/date-input/date-input-selection-strategies/last-7-days-selection-strategy.mjs +0 -101
  282. package/esm2020/lib/controls/date-input/date-input-selection-strategies/month-selection-strategy.mjs +0 -76
  283. package/esm2020/lib/controls/date-input/date-input-selection-strategies/quarter-selection-strategy.mjs +0 -79
  284. package/esm2020/lib/controls/date-input/date-input-selection-strategies/range-selection-strategy.mjs +0 -210
  285. package/esm2020/lib/controls/date-input/date-input-selection-strategies/year-selection-strategy.mjs +0 -81
  286. package/esm2020/lib/controls/date-input/date-input.component.mjs +0 -465
  287. package/esm2020/lib/controls/dropdown/dropdown.component.mjs +0 -243
  288. package/esm2020/lib/controls/file-upload/file-upload.component.mjs +0 -261
  289. package/esm2020/lib/controls/form-control/form-control.component.mjs +0 -98
  290. package/esm2020/lib/controls/form-control-base.mjs +0 -151
  291. package/esm2020/lib/controls/form-control-label/form-control-label.component.mjs +0 -136
  292. package/esm2020/lib/controls/form-group/form-group.component.mjs +0 -261
  293. package/esm2020/lib/controls/item-picker/item-picker.component.mjs +0 -329
  294. package/esm2020/lib/controls/menu/menu.component.mjs +0 -485
  295. package/esm2020/lib/controls/navigation/nav-group.mjs +0 -39
  296. package/esm2020/lib/controls/navigation/nav-item-active.directive.mjs +0 -92
  297. package/esm2020/lib/controls/numericbox/numericbox.component.mjs +0 -372
  298. package/esm2020/lib/controls/popover/popover.component.mjs +0 -117
  299. package/esm2020/lib/controls/radio-button/radio-button.component.mjs +0 -82
  300. package/esm2020/lib/controls/select/select.component.mjs +0 -88
  301. package/esm2020/lib/controls/tabs/tabs.component.mjs +0 -47
  302. package/esm2020/lib/controls/textbox/textbox.component.mjs +0 -155
  303. package/esm2020/lib/core/cache.service.mjs +0 -105
  304. package/esm2020/lib/core/custom-validators.mjs +0 -29
  305. package/esm2020/lib/core/date-time-helper.mjs +0 -228
  306. package/esm2020/lib/core/error.service.mjs +0 -61
  307. package/esm2020/lib/core/router-helper.service.mjs +0 -111
  308. package/esm2020/lib/core/scroll.service.mjs +0 -89
  309. package/esm2020/lib/core/validation-message.service.mjs +0 -185
  310. package/esm2020/lib/core/window.service.mjs +0 -186
  311. package/esm2020/lib/display/app-bar/app-bar.component.mjs +0 -46
  312. package/esm2020/lib/display/avatar/avatar.component.mjs +0 -67
  313. package/esm2020/lib/display/avatar/avatar.service.mjs +0 -64
  314. package/esm2020/lib/display/confirm/confirm.component.mjs +0 -168
  315. package/esm2020/lib/display/dialog/dialog-group/dialog-group.component.mjs +0 -63
  316. package/esm2020/lib/display/dialog/dialog.component.mjs +0 -281
  317. package/esm2020/lib/display/hierarchy/hierarchy-base.mjs +0 -111
  318. package/esm2020/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.mjs +0 -61
  319. package/esm2020/lib/display/item-display/item-display.component.mjs +0 -81
  320. package/esm2020/lib/display/json-display/json-display.component.mjs +0 -47
  321. package/esm2020/lib/display/resizable/resizable-base.mjs +0 -120
  322. package/esm2020/lib/display/splash/splash.component.mjs +0 -42
  323. package/esm2020/lib/display/table/resizable-table.directive.mjs +0 -227
  324. package/esm2020/lib/display/table/searchable-table.component.mjs +0 -342
  325. package/esm2020/lib/display/table/table-locked-column.component.mjs +0 -58
  326. package/esm2020/lib/display/table/table-master-row.component.mjs +0 -163
  327. package/esm2020/lib/display/table/table-pagination.component.mjs +0 -155
  328. package/esm2020/lib/display/table/table-selectable-row.component.mjs +0 -235
  329. package/esm2020/lib/display/table/table.component.mjs +0 -249
  330. package/esm2020/lib/display/tags/tag.mjs +0 -18
  331. package/esm2020/lib/display/tags/tags.component.mjs +0 -77
  332. package/esm2020/lib/display/toast/toast/toast.component.mjs +0 -77
  333. package/esm2020/lib/display/toast/toaster/toaster.component.mjs +0 -114
  334. package/esm2020/lib/display/tooltip-directive/tooltip.directive.mjs +0 -173
  335. package/esm2020/lib/display/tour/tour.component.mjs +0 -398
  336. package/esm2020/lib/display/tour/tour.service.mjs +0 -75
  337. package/esm2020/lib/display/tree/tree.component.mjs +0 -135
  338. package/esm2020/lib/display/view-overlay/view-overlay.component.mjs +0 -58
  339. package/esm2020/lib/shared/directives/click-area-for/click-area-for.directive.mjs +0 -32
  340. package/esm2020/lib/shared/directives/if-viewport-width/if-viewport-width.directive.mjs +0 -111
  341. package/esm2020/lib/shared/directives/popup/popup-container.directive.mjs +0 -163
  342. package/esm2020/lib/shared/display/pipes/date-display.pipe.mjs +0 -50
  343. package/esm2020/lib/shared/display/pipes/highlight-text.pipe.mjs +0 -30
  344. package/esm2020/lib/shared/display/pipes/relative-date.pipe.mjs +0 -62
  345. package/esm2020/lib/shared/display/pipes/row-count.pipe.mjs +0 -48
  346. package/esm2020/lib/shared/display/pipes/time-display.pipe.mjs +0 -41
  347. package/esm2020/lib/shared/display.mjs +0 -6
  348. package/esm2020/lib/shared/form-group.helper.mjs +0 -67
  349. package/esm2020/lib/shared/json-helper.mjs +0 -19
  350. package/esm2020/lib/shared/lodash-helper.mjs +0 -51
  351. package/esm2020/lib/shared/page/page-base/page-base.component.mjs +0 -387
  352. package/esm2020/lib/shared/page/page-view/page-view.component.mjs +0 -147
  353. package/esm2020/lib/shared/testing/page-base-component-test-injector-factory.spec.mjs +0 -98
  354. package/esm2020/lib/shared/wizard/wizard-base/wizard-base.component.mjs +0 -246
  355. package/fesm2015/energycap-components.mjs +0 -13373
  356. package/fesm2015/energycap-components.mjs.map +0 -1
  357. package/fesm2020/energycap-components.mjs.map +0 -1
@@ -1,465 +0,0 @@
1
- import { Component, HostBinding, Input, ViewChild } from '@angular/core';
2
- import { FormControl, FormGroup } from '@angular/forms';
3
- import moment from 'moment';
4
- import { lastValueFrom } from 'rxjs';
5
- import { debounceTime, distinctUntilChanged, takeUntil } from 'rxjs/operators';
6
- import { DateTimeHelper } from '../../core/date-time-helper';
7
- import { FormControlBase } from '../form-control-base';
8
- import { DateInput } from './date-input.types';
9
- import * as i0 from "@angular/core";
10
- import * as i1 from "../../core/validation-message.service";
11
- import * as i2 from "../../shared/form-group.helper";
12
- import * as i3 from "../../shared/user-preference.service";
13
- import * as i4 from "@angular/cdk/overlay";
14
- import * as i5 from "./date-input.types";
15
- import * as i6 from "@angular/common";
16
- import * as i7 from "@angular/forms";
17
- import * as i8 from "../button/button.component";
18
- import * as i9 from "../form-control/form-control.component";
19
- import * as i10 from "../help-popover/help-popover.component";
20
- import * as i11 from "../link-button/link-button.component";
21
- import * as i12 from "../calendar/calendar.component";
22
- import * as i13 from "../../shared/directives/keyboard-nav-container/keyboard-nav-container.directive";
23
- import * as i14 from "@ngx-translate/core";
24
- export class DateInputComponent extends FormControlBase {
25
- constructor(validationMessageService, formGroupHelper, userPreferenceService, el, overlayService, selectionStrategies) {
26
- super(validationMessageService, formGroupHelper);
27
- this.validationMessageService = validationMessageService;
28
- this.formGroupHelper = formGroupHelper;
29
- this.userPreferenceService = userPreferenceService;
30
- this.el = el;
31
- this.overlayService = overlayService;
32
- this.selectionStrategies = selectionStrategies;
33
- this.id = '';
34
- /** The form control provided by the hosting form. */
35
- this.formModel = new FormControl(null);
36
- this.minDate = DateTimeHelper.minDatePickerDate;
37
- this.maxDate = DateTimeHelper.maxDatePickerDate;
38
- /** The initial selection mode for the calendar. Defaults to day if not provided */
39
- this.selectionMode = 'day';
40
- /** The available selection modes for the calendar. Defaults to only the initial selection mode if not provided. */
41
- this.selectionModeOptions = ['day'];
42
- /** Enables the next/previous selection buttons. */
43
- this.enableSteppers = false;
44
- /** The form group for the internal textboxes. Textbox2 is only used for ranges. */
45
- this.textboxGroup = new FormGroup({
46
- textbox: new FormControl(null),
47
- textbox2: new FormControl(null)
48
- });
49
- /**
50
- * The current calendar selection.
51
- * Updated when the user clicks on a calendar item or when the date entered into the textbox is parsed.
52
- */
53
- this.calendarSelection = null;
54
- /** Controls whether the calendar overlay is open or not. */
55
- this.isCalendarOpen = false;
56
- /** Placeholder for the textbox. Updated to reflect the user's date display preference. */
57
- this.placeholder = 'MM/DD/YYYY';
58
- /** Overlay scroll strategy for the calendar overlay. Closes the calendar on scroll. */
59
- this.overlayScrollStrategy = this.overlayService.scrollStrategies.close();
60
- this.primaryCalendarView = { mode: 'day', date: new Date() };
61
- this.secondaryCalendarView = { mode: 'day', date: new Date() };
62
- this.primaryCalendarMaxDate = DateTimeHelper.maxDatePickerDate;
63
- this.secondaryCalendarMinDate = DateTimeHelper.minDatePickerDate;
64
- this.disableSteppers = false;
65
- /**
66
- * Date parsing formats for user-entered dates. Defaults to month-first formats, but is updated in onInit
67
- * to use the user's preferred date format.
68
- */
69
- this.parseFormats = DateTimeHelper.getMomentParseFormats();
70
- }
71
- ngOnChanges(changes) {
72
- if (changes.selectionMode && !changes.selectionMode.isFirstChange()) {
73
- this.onSelectionModeChange(this.selectionMode);
74
- }
75
- }
76
- ngOnInit() {
77
- // Setup
78
- super.ngOnInit();
79
- this.setDateFormats();
80
- this.setSelectionMode(this.selectionMode);
81
- // Subscriptions
82
- this.onFormModelStatusChanges();
83
- this.onFormModelValueChanges();
84
- this.onTextboxValueChanges();
85
- // Sync the initial disabled status and value of the textbox
86
- this.syncTextboxControlDisabledStatus(this.formModel.status);
87
- const initialDisplayValue = this.selectionStrategy.formatSelection(this.formModel.value);
88
- this.textboxGroup.patchValue(initialDisplayValue, { emitEvent: false });
89
- // Update the calendar selection and view based on the initial form model value
90
- this.calendarSelection = this.formModel.value;
91
- this.updateCalendars(this.calendarSelection);
92
- this.updateSteppers(this.calendarSelection);
93
- console.log(this.calendarSelection);
94
- }
95
- /** Focuses the input whenever the calendar is shift-tabbed out of. */
96
- onCalendarFocusOutStart() {
97
- this.focusInput();
98
- }
99
- /** Closes the calendar and focuses the input whenever the calendar is tabbed out of. */
100
- onCalendarFocusOutEnd() {
101
- this.isCalendarOpen = false;
102
- this.focusInput();
103
- }
104
- /** Closes the calendar if the user clicks outside of the calendar and date input. */
105
- onOverlayOutsideClick(event) {
106
- // Do not close the calendar if the click was within the date input or action button
107
- const rect = this.el.nativeElement.getBoundingClientRect();
108
- const clickedOutsideControl = event.clientY < rect.top ||
109
- event.clientY > rect.bottom ||
110
- event.clientX < rect.left ||
111
- event.clientX > rect.right;
112
- // It's possible that the user hit enter on the action button instead of clicking with the mouse.
113
- // In this case the "click" event will be outside of the component because the clientx and y are 0,
114
- // but we don't want to close in this case because button clicks trigger calendar open/close separately.
115
- const targetId = event.target.id;
116
- const isActionClick = targetId === `${this.id}_action` || targetId === `${this.id}_control2_action`;
117
- if (!isActionClick && clickedOutsideControl) {
118
- this.isCalendarOpen = false;
119
- }
120
- }
121
- /** If the user tabs out of the form control's action button and the calendar is open, focus the first item in the calendar overlay */
122
- onControlsFocusOutEnd() {
123
- if (this.isCalendarOpen) {
124
- this.calendar?.focus();
125
- }
126
- }
127
- onTextboxBlur() {
128
- // We want to prevent the fixed date range modes from re-autocompleting the first textbox when it is explicitly cleared.
129
- const previousValue = DateInput.isSelectionRange(this.formModel.value) ? this.formModel.value.start : this.formModel.value;
130
- const currentValue = this.textboxGroup.value.textbox;
131
- const cleared = !!previousValue && !currentValue;
132
- const options = { preventAutoComplete: cleared };
133
- // Parse the textbox values into a selection and update the form model
134
- const parsedSelection = this.selectionStrategy.parseTextboxValues(this.textboxGroup.value, this.parseFormats, options);
135
- this.updateFormModel(parsedSelection);
136
- }
137
- onTextbox2Blur() {
138
- // We want to prevent the fixed date range modes from re-autocompleting the second textbox when it is explicitly cleared.
139
- const previousValue = DateInput.isSelectionRange(this.formModel.value) ? this.formModel.value.end : null;
140
- const currentValue = this.textboxGroup.value.textbox2;
141
- const cleared = !!previousValue && !currentValue;
142
- const options = { parseFromEnd: true, preventAutoComplete: cleared };
143
- // Parse the textbox values into a selection and update the form model,
144
- // For the second box we're keying the parse from the end date in the selection.
145
- const parsedSelection = this.selectionStrategy.parseTextboxValues(this.textboxGroup.value, this.parseFormats, options);
146
- this.updateFormModel(parsedSelection);
147
- }
148
- onSelectionModeChange(mode) {
149
- this.setSelectionMode(mode);
150
- const newSelection = this.selectionStrategy.getNewSelectionFromExisting(this.calendarSelection);
151
- this.updateFormModel(newSelection);
152
- // On selection mode change, we want to force the calendars to show the right view mode for the new selection.
153
- // This prevents the user from seeing a view mode that doesn't make sense for the new selection,
154
- // Like when swiching from year mode to last 7 days mode.
155
- this.primaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: this.primaryCalendarView.date };
156
- this.secondaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: this.secondaryCalendarView.date };
157
- this.updateCalendarMinMaxDates();
158
- }
159
- onCalendarDateSelected(date) {
160
- const newSelection = this.selectionStrategy.getSelectionFromDate(date, this.calendarSelection);
161
- const displayValue = this.selectionStrategy.formatSelection(newSelection);
162
- // Don't emit events when patching values here. We don't want to trigger the calendar updates since the calendar is already
163
- // showing the selected date. We also don't want to trigger the textbox parsing logic since the date was selected from the calendar.
164
- this.textboxGroup.patchValue(displayValue, { emitEvent: false });
165
- this.formModel.patchValue(newSelection, { emitEvent: false });
166
- this.calendarSelection = newSelection;
167
- this.updateSteppers(newSelection);
168
- // Close the calendar if the selection mode is not a range mode where either the start or the end date can be changed.
169
- if (!this.selectionStrategy.showSecondaryTextbox) {
170
- this.isCalendarOpen = false;
171
- this.focusInput();
172
- }
173
- }
174
- onPrimaryCalendarViewChange(view) {
175
- this.primaryCalendarView = view;
176
- this.updateCalendarMinMaxDates();
177
- }
178
- onSecondaryCalendarViewChange(view) {
179
- this.secondaryCalendarView = view;
180
- this.updateCalendarMinMaxDates();
181
- }
182
- /** Shifts the calendar views to display today. Does not update the calendar selection. */
183
- goToToday() {
184
- // If both calendars are visible, show today in the secondary calendar and the month before in the primary calendar.
185
- if (this.selectionStrategy.showSecondaryCalendar) {
186
- this.primaryCalendarView = { mode: 'day', date: moment().subtract(1, 'month').toDate() };
187
- this.secondaryCalendarView = { mode: 'day', date: new Date() };
188
- // If we're in a single date mode, show today in the primary calendar.
189
- }
190
- else {
191
- this.primaryCalendarView = { mode: 'day', date: new Date() };
192
- }
193
- this.updateCalendarMinMaxDates();
194
- }
195
- goToQuickSelectDate() {
196
- if (this.quickSelectDate) {
197
- const newSelection = this.selectionStrategy.getSelectionForQuickSelectDate(this.quickSelectDate, this.calendarSelection);
198
- this.updateFormModel(newSelection);
199
- }
200
- }
201
- nextSelection() {
202
- const newSelection = this.selectionStrategy.getNextSelection(this.calendarSelection);
203
- this.updateFormModel(newSelection);
204
- }
205
- previousSelection() {
206
- const newSelection = this.selectionStrategy.getPreviousSelection(this.calendarSelection);
207
- this.updateFormModel(newSelection);
208
- }
209
- updateFormModel(value) {
210
- this.formModel.patchValue(value);
211
- // Validate the textboxes and sync the form errors
212
- // We do this after patching the form model because the form model patch will trigger
213
- // the date formatting logic and overwrite any errors on the controls from before.
214
- this.validateTextboxes();
215
- this.syncFormErrors();
216
- }
217
- onFormModelStatusChanges() {
218
- // Keep the textboxControl disabled status in sync with the formModel
219
- this.formModel.statusChanges.pipe(distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(status => {
220
- this.syncTextboxControlDisabledStatus(status);
221
- if (this.isCalendarOpen) {
222
- // As validation messages appear/disappear, the date input may have shifted up or down on the page.
223
- // Update the overlay position to ensure it's still aligned with the textbox and not blocking it.
224
- // Settimeout is needed to ensure the overlay is being updated after the message is rendered.
225
- setTimeout(() => {
226
- this.overlay?.overlayRef?.updatePosition();
227
- });
228
- }
229
- });
230
- }
231
- onFormModelValueChanges() {
232
- // Update the calendar selection textbox value with a formatted date when the form model changes.
233
- // This is triggered by the user selecting a date from the calendar or when the textbox is blurred.
234
- this.formModel.valueChanges.pipe(takeUntil(this.componentDestroyed)).subscribe(value => {
235
- const displayValue = this.selectionStrategy.formatSelection(value);
236
- // Don't emit an event when setting the textbox value to avoid circular updates between the textbox and form model.
237
- this.textboxGroup.patchValue(displayValue, { emitEvent: false });
238
- this.updateCalendars(value);
239
- this.updateSteppers(value);
240
- });
241
- }
242
- onTextboxValueChanges() {
243
- // Update the calendar selection when the textbox value changes to update the calendar.
244
- // We don't patch the formModel here because we don't want to trigger the
245
- // date formatting logic and overwrite the user's input.
246
- // We'll do that when the user blurs out of the textbox. See onTextboxBlur()
247
- this.textboxGroup.controls.textbox.valueChanges.pipe(debounceTime(300), distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(() => {
248
- const options = { shiftToCurrentYearIfBelow: this.minDate };
249
- const newSelection = this.selectionStrategy.parseTextboxValues(this.textboxGroup.value, this.parseFormats, options);
250
- // Calendar selection will be null if the dates are invalid. Don't update the calendars in this case.
251
- if (newSelection) {
252
- this.calendarSelection = newSelection;
253
- this.updatePrimaryCalendar(this.calendarSelection, this.selectionStrategy.showSecondaryCalendar);
254
- this.updateCalendarMinMaxDates();
255
- }
256
- });
257
- // The second textbox is only used in last7Days, last28Days, and range modes.
258
- this.textboxGroup.controls.textbox2.valueChanges.pipe(debounceTime(300), distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(() => {
259
- const options = { shiftToCurrentYearIfBelow: this.minDate, parseFromEnd: true };
260
- const newSelection = this.selectionStrategy.parseTextboxValues(this.textboxGroup.value, this.parseFormats, options);
261
- // Calendar selection will be null if the dates are invalid. Don't update the calendars in this case.
262
- if (newSelection) {
263
- this.calendarSelection = newSelection;
264
- // The secondary calendar is only shown in range mode. Update the primary calendar if we're not in range mode.
265
- if (this.selectionStrategy.showSecondaryCalendar) {
266
- this.updateSecondaryCalendar(this.calendarSelection, true);
267
- }
268
- else {
269
- this.updatePrimaryCalendar(this.calendarSelection);
270
- }
271
- this.updateCalendarMinMaxDates();
272
- }
273
- });
274
- }
275
- syncTextboxControlDisabledStatus(status) {
276
- // The textbox should only be disabled if the form model is disabled.
277
- // All other statuses are considered enabled.
278
- if (status === 'DISABLED' && this.textboxGroup.enabled) {
279
- this.textboxGroup.disable();
280
- }
281
- else if (status !== 'DISABLED' && this.textboxGroup.disabled) {
282
- this.textboxGroup.enable();
283
- }
284
- }
285
- ;
286
- syncFormErrors() {
287
- // Start with the existing form model errors
288
- let errors = this.formModel.errors;
289
- // Add the errors from the textboxes if they exist
290
- if (this.textboxGroup.controls.textbox.errors) {
291
- errors = { ...errors, ...this.textboxGroup.controls.textbox.errors };
292
- }
293
- if (this.textboxGroup.controls.textbox2.errors) {
294
- errors = { ...errors, ...this.textboxGroup.controls.textbox2.errors };
295
- }
296
- // Update the form model's errors with the combined errors
297
- this.formModel.setErrors(errors);
298
- // Update the form model's touched and dirty status based on the textbox's status.
299
- // Since the user interacts with a control that is internal to this component, the
300
- // form model's status won't be updated automatically.
301
- if (this.textboxGroup.touched && !this.formModel.touched) {
302
- this.formModel.markAsTouched();
303
- }
304
- if (this.textboxGroup.dirty && !this.formModel.dirty) {
305
- this.formModel.markAsDirty();
306
- }
307
- }
308
- /**
309
- * Updates the date parsing formats and placeholder based on the user's display preference.
310
- * NOTE: This is async because we're retrieving the user's preferences. We're not awaiting the result
311
- * because the only logic that depends on this is the text box date parsing logic and placeholder.
312
- * Our forms should always be behind a pending overlay, so the user won't be able to interact with the
313
- * form until the user is loaded anyway.
314
- */
315
- async setDateFormats() {
316
- const { preference } = await lastValueFrom(this.userPreferenceService.getPreferences());
317
- const dateFormat = preference?.dateFormat;
318
- this.placeholder = dateFormat ?? this.placeholder;
319
- this.parseFormats = DateTimeHelper.getMomentParseFormats(dateFormat);
320
- }
321
- /** Focuses the date input. */
322
- focusInput() {
323
- this.controls?.focus();
324
- }
325
- setSelectionMode(mode) {
326
- this.selectionMode = mode;
327
- this.selectionStrategy = this.selectionStrategies[mode];
328
- }
329
- /**
330
- * Sets the max date for the primary calendar and the min date for the secondary calendar based
331
- * on the current views in each. This prevents the user from moving the calendars out of order.
332
- */
333
- updateCalendarMinMaxDates() {
334
- // Only update the min/max dates when the view mode is 'day'.
335
- // When a calendar is in a month or year view mode, the view dates at the beginning of the year.
336
- // This would cause the dates in the other calendar to be unselectable if we were to
337
- // update the min/max dates in these cases.
338
- if (this.primaryCalendarView?.mode === 'day') {
339
- this.secondaryCalendarMinDate = moment(this.primaryCalendarView?.date).add(1, 'month').startOf('month').toDate();
340
- }
341
- if (this.secondaryCalendarView?.mode === 'day') {
342
- this.primaryCalendarMaxDate = moment(this.secondaryCalendarView?.date).subtract(1, 'month').endOf('month').toDate();
343
- }
344
- }
345
- updateCalendars(selection) {
346
- this.calendarSelection = selection;
347
- this.updatePrimaryCalendar(selection);
348
- // Only shift the primary calendar if we're showing the secondary calendar
349
- this.updateSecondaryCalendar(selection, this.selectionStrategy.showSecondaryCalendar);
350
- this.updateCalendarMinMaxDates();
351
- }
352
- updatePrimaryCalendar(selection, shiftSecondary = false) {
353
- this.primaryCalendarView = this.selectionStrategy.getPrimaryCalendarView(selection, this.minDate, this.maxDate, this.primaryCalendarView);
354
- // When entering a date into the first textbox, we really only want to update the primary calendar.
355
- // However, it's possible that the new date is after the secondary calendar's date. In this case,
356
- // We want to shift the secondary calendar so the calendars stay in order.
357
- if (shiftSecondary && this.secondaryCalendarView) {
358
- if (moment(this.primaryCalendarView.date).isSameOrAfter(this.secondaryCalendarView.date, 'month')) {
359
- let newSecondaryDate = moment(this.primaryCalendarView.date).add(1, 'month').toDate();
360
- this.secondaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: newSecondaryDate };
361
- }
362
- }
363
- }
364
- updateSecondaryCalendar(selection, shiftPrimary = false) {
365
- this.secondaryCalendarView = this.selectionStrategy.getSecondaryCalendarView(selection, this.minDate, this.maxDate, this.secondaryCalendarView);
366
- // When entering a date into the second textbox, we really only want to update the secondary calendar.
367
- // However, it's possible that the new date is before the primary calendar's date. In this case,
368
- // We want to shift the primary calendar so the calendars stay in order.
369
- if (shiftPrimary && this.primaryCalendarView) {
370
- if (moment(this.primaryCalendarView.date).isSameOrAfter(this.secondaryCalendarView.date, 'month')) {
371
- let newPrimaryDate = moment(this.secondaryCalendarView.date).subtract(1, 'month').toDate();
372
- this.primaryCalendarView = { mode: this.selectionStrategy.selectionViewMode, date: newPrimaryDate };
373
- }
374
- }
375
- }
376
- updateSteppers(value) {
377
- // Disable the steppers if we either don't have a selection or only have one date in the selection.
378
- if (!value ||
379
- (DateInput.isSelectionSingleDate(value) && this.selectionMode !== 'day') ||
380
- (DateInput.isSelectionRange(value) && (!value.start || !value.end))) {
381
- this.disableSteppers = true;
382
- }
383
- else {
384
- this.disableSteppers = false;
385
- }
386
- }
387
- validateTextboxes() {
388
- const control = this.textboxGroup.controls.textbox;
389
- const control2 = this.textboxGroup.controls.textbox2;
390
- // The first textbox should only have the required error if it's empty and the date input is required,
391
- // or if the date input is not required and the second control is visible and has a value (meaning a partial range)
392
- if (!control.value &&
393
- (this.required || (control2.value && this.selectionStrategy.showSecondaryTextbox))) {
394
- control.setErrors({ required: true });
395
- }
396
- // The same idea applies to the second textbox, but only if it's visible
397
- if (this.selectionStrategy.showSecondaryTextbox &&
398
- !control2.value &&
399
- (this.required || control.value)) {
400
- control2.setErrors({ required: true });
401
- }
402
- if (control.value) {
403
- const errors = this.validateDateString(control.value);
404
- if (errors) {
405
- control.setErrors(errors);
406
- }
407
- }
408
- if (control2.value && this.selectionStrategy.showSecondaryTextbox) {
409
- const errors = this.validateDateString(control2.value);
410
- if (errors) {
411
- control2.setErrors(errors);
412
- }
413
- }
414
- }
415
- validateDateString(date) {
416
- const value = this.selectionStrategy.parseString(date, this.parseFormats);
417
- if (value) {
418
- // We're using the view mode as the granularity. We don't want to invalidate
419
- // the date in the case where you have a month/quarter/year selected and the min
420
- // or max date is somewhere within that month/quarter/year.
421
- if (moment(value).isBefore(this.minDate, this.selectionStrategy.selectionViewMode)) {
422
- return { minDate: { minValue: this.minDate } };
423
- }
424
- else if (moment(value).isAfter(this.maxDate, this.selectionStrategy.selectionViewMode)) {
425
- return { maxDate: { maxValue: this.maxDate } };
426
- }
427
- }
428
- return null;
429
- }
430
- }
431
- DateInputComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateInputComponent, deps: [{ token: i1.ValidationMessageService }, { token: i2.FormGroupHelper }, { token: i3.UserPreferenceService }, { token: i0.ElementRef }, { token: i4.Overlay }, { token: i5.DateInput.SelectionStrategies }], target: i0.ɵɵFactoryTarget.Component });
432
- DateInputComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "15.2.9", type: DateInputComponent, selector: "ec-date-input", inputs: { id: "id", formModel: "formModel", minDate: "minDate", maxDate: "maxDate", selectionMode: "selectionMode", selectionModeOptions: "selectionModeOptions", quickSelectDate: "quickSelectDate", enableSteppers: "enableSteppers" }, host: { properties: { "attr.id": "this.id" } }, providers: [DateInput.SelectionStrategies], viewQueries: [{ propertyName: "calendar", first: true, predicate: ["calendar"], descendants: true }, { propertyName: "controls", first: true, predicate: ["controls"], descendants: true }, { propertyName: "overlay", first: true, predicate: ["overlay"], descendants: true }], usesInheritance: true, usesOnChanges: true, ngImport: i0, template: "<label *ngIf=\"label\">\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\">&nbsp;{{validationErrors}}</span>\r\n <ec-help-popover id=\"{{id}}_helpPopover\"\r\n *ngIf=\"helpPopover\"\r\n class=\"d-inline-block my-n3 mx-n1\"\r\n text=\"{{helpPopover | translate}}\"\r\n contentPosition=\"{{helpPopoverPosition}}\">\r\n </ec-help-popover>\r\n</label>\r\n\r\n<div class=\"d-flex align-items-center\"\r\n [ecKeyboardNavContainer]=\"isCalendarOpen\"\r\n #controls=\"ecKeyboardNavContainer\"\r\n (focusOutEnd)=\"onControlsFocusOutEnd()\">\r\n <ec-form-control id=\"{{id}}\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n cdkOverlayOrigin\r\n #overlayOrigin=\"cdkOverlayOrigin\"\r\n class=\"flex-grow\"\r\n style=\"height: 2rem;\">\r\n <input id=\"{{id}}_input\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxGroup.get('textbox')\"\r\n (blur)=\"onTextboxBlur()\">\r\n </ec-form-control>\r\n\r\n <ng-container *ngIf=\"selectionStrategy.showSecondaryTextbox\">\r\n <span class=\"flex-shrink mx-1\">&ndash;</span>\r\n <ec-form-control id=\"{{id}}_control2\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n class=\"flex-grow\"\r\n style=\"height: 2rem;\">\r\n <input id=\"{{id}}_input2\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxGroup.get('textbox2')\"\r\n (blur)=\"onTextbox2Blur()\">\r\n </ec-form-control>\r\n </ng-container>\r\n\r\n <div *ngIf=\"enableSteppers\"\r\n class=\"control-group ml-2\">\r\n <ec-button id=\"{{id}}_previousSelection\"\r\n type=\"secondary\"\r\n icon=\"icon-angle-down rotate-90\"\r\n (clicked)=\"previousSelection()\"\r\n [disabled]=\"isCalendarOpen || disableSteppers || formModel?.disabled\">\r\n </ec-button>\r\n <ec-button id=\"{{id}}_nextSelection\"\r\n type=\"secondary\"\r\n icon=\"icon-angle-down rotate-270\"\r\n (clicked)=\"nextSelection()\"\r\n [disabled]=\"isCalendarOpen || disableSteppers || formModel?.disabled\">\r\n </ec-button>\r\n </div>\r\n\r\n <ec-button *ngIf=\"quickSelectDate\"\r\n id=\"{{id}}_quickSelect\"\r\n icon=\"icon-day\"\r\n type=\"secondary\"\r\n title=\"{{'DateInput_LatestDataAvailableTitle' | translate}}\"\r\n (clicked)=\"goToQuickSelectDate()\"\r\n class=\"ml-2\">\r\n </ec-button>\r\n</div>\r\n\r\n<ng-template cdkConnectedOverlay\r\n #overlay=\"cdkConnectedOverlay\"\r\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\r\n [cdkConnectedOverlayOpen]=\"isCalendarOpen\"\r\n [cdkConnectedOverlayScrollStrategy]=\"overlayScrollStrategy\"\r\n cdkConnectedOverlayPanelClass=\"my-1\"\r\n (overlayOutsideClick)=\"onOverlayOutsideClick($event)\"\r\n (detach)=\"isCalendarOpen = false\">\r\n <article id=\"{{id}}_datePicker\"\r\n class=\"card d-flex\"\r\n [ecKeyboardNavContainer]=\"isCalendarOpen\"\r\n #calendar=\"ecKeyboardNavContainer\"\r\n (focusOutStart)=\"onCalendarFocusOutStart()\"\r\n (focusOutEnd)=\"onCalendarFocusOutEnd()\">\r\n <ul *ngIf=\"selectionModeOptions.length > 1\"\r\n class=\"selection-mode-menu border-right p-1\">\r\n <li *ngFor=\"let option of selectionModeOptions\">\r\n <button id=\"{{id}}_selectionMode_{{option}}\"\r\n class=\"text-body-1\"\r\n [class.is-selected]=\"option === selectionMode\"\r\n (click)=\"onSelectionModeChange(option)\">\r\n {{'DateInputSelectionMode_' + option | translate}}\r\n </button>\r\n </li>\r\n </ul>\r\n\r\n <div>\r\n <div class=\"d-flex\">\r\n <ec-calendar id=\"{{id}}_calendar\"\r\n [view]=\"primaryCalendarView\"\r\n (viewChange)=\"onPrimaryCalendarViewChange($event)\"\r\n [selectionMode]=\"selectionMode\"\r\n [selection]=\"calendarSelection\"\r\n (dateSelected)=\"onCalendarDateSelected($event)\"\r\n [minDate]=\"minDate\"\r\n [maxDate]=\"selectionStrategy.showSecondaryCalendar ? primaryCalendarMaxDate : maxDate\">\r\n </ec-calendar>\r\n\r\n <ec-calendar *ngIf=\"selectionStrategy.showSecondaryCalendar\"\r\n id=\"{{id}}_secondaryCalendar\"\r\n [view]=\"secondaryCalendarView\"\r\n (viewChange)=\"onSecondaryCalendarViewChange($event)\"\r\n [selectionMode]=\"selectionMode\"\r\n [selection]=\"calendarSelection\"\r\n (dateSelected)=\"onCalendarDateSelected($event)\"\r\n [minDate]=\"secondaryCalendarMinDate\"\r\n [maxDate]=\"maxDate\">\r\n </ec-calendar>\r\n </div>\r\n\r\n <footer *ngIf=\"selectionStrategy.selectionViewMode === 'day'\"\r\n class=\"px-2 my-2 d-flex\">\r\n <button id=\"{{id}}_today_button\"\r\n ecLinkButton\r\n class=\"ml-auto d-inline-block\"\r\n (click)=\"goToToday()\"\r\n style=\"height: 1.75rem;\">\r\n {{'Today' | translate}}\r\n </button>\r\n </footer>\r\n </div>\r\n </article>\r\n</ng-template>\r\n", styles: [":host{display:block}label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}.date-picker{display:grid;grid-template-areas:\"menu calendar calendar\" \"menu footer footer\"}.date-picker footer{grid-area:footer}ul.selection-mode-menu{grid-area:menu;list-style:none;padding:0;margin:0;min-width:7rem}ul.selection-mode-menu li{margin-bottom:.25rem}ul.selection-mode-menu li button{font-size:var(--ec-font-size-action);height:2rem;line-height:1.25rem;padding:.3125rem .5rem;border:0;border-radius:var(--ec-border-radius);display:flex;align-items:center;justify-content:center;cursor:pointer;background-color:transparent;width:100%;height:1.75rem}ul.selection-mode-menu li button .label{display:flex;align-items:center;justify-content:center;white-space:nowrap;flex:auto}ul.selection-mode-menu li button .ec-icon{flex:none}ul.selection-mode-menu li button .ec-icon+.label{flex:none;margin-left:.25rem}ul.selection-mode-menu li button.has-badge{padding-right:.0625rem}ul.selection-mode-menu li button:focus{outline:none;position:relative;z-index:1}ul.selection-mode-menu li button:disabled{background-color:var(--ec-background-color-disabled);border:1px solid var(--ec-form-control-border-color-disabled);color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled);cursor:default}ul.selection-mode-menu li button:disabled{background-color:transparent;border-color:transparent;color:var(--ec-color-hint-dark);--ec-color-icon: var(--ec-color-hint-dark)}ul.selection-mode-menu li button:hover:not(:disabled){background-color:var(--ec-background-color-hover)}ul.selection-mode-menu li button:active:not(:disabled){background-color:var(--ec-background-color-selected);font-weight:700}ul.selection-mode-menu li button:focus:not(:disabled){box-shadow:var(--ec-button-box-shadow-active, 0 0 0 2px var(--ec-border-color-focus))}ul.selection-mode-menu li button.is-selected{background-color:var(--ec-background-color-selected);font-weight:700}ec-button{--ec-button-border-color-secondary: var(--ec-border-color-control)}.control-group ec-button:has(+ ec-button) ::ng-deep button{border-right:0}.control-group ec-button+ec-button ::ng-deep button{border-left:0}\n"], dependencies: [{ kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i7.DefaultValueAccessor, selector: "input:not([type=checkbox])[formControlName],textarea[formControlName],input:not([type=checkbox])[formControl],textarea[formControl],input:not([type=checkbox])[ngModel],textarea[ngModel],[ngDefaultControl]" }, { kind: "directive", type: i7.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i7.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.CdkConnectedOverlay, selector: "[cdk-connected-overlay], [connected-overlay], [cdkConnectedOverlay]", inputs: ["cdkConnectedOverlayOrigin", "cdkConnectedOverlayPositions", "cdkConnectedOverlayPositionStrategy", "cdkConnectedOverlayOffsetX", "cdkConnectedOverlayOffsetY", "cdkConnectedOverlayWidth", "cdkConnectedOverlayHeight", "cdkConnectedOverlayMinWidth", "cdkConnectedOverlayMinHeight", "cdkConnectedOverlayBackdropClass", "cdkConnectedOverlayPanelClass", "cdkConnectedOverlayViewportMargin", "cdkConnectedOverlayScrollStrategy", "cdkConnectedOverlayOpen", "cdkConnectedOverlayDisableClose", "cdkConnectedOverlayTransformOriginOn", "cdkConnectedOverlayHasBackdrop", "cdkConnectedOverlayLockPosition", "cdkConnectedOverlayFlexibleDimensions", "cdkConnectedOverlayGrowAfterOpen", "cdkConnectedOverlayPush"], outputs: ["backdropClick", "positionChange", "attach", "detach", "overlayKeydown", "overlayOutsideClick"], exportAs: ["cdkConnectedOverlay"] }, { kind: "directive", type: i4.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: i8.ButtonComponent, selector: "ec-button", inputs: ["id", "disabled", "icon", "label", "badge", "tabindex", "type", "pending", "pendingIcon", "customTemplate", "isSubmit", "autofocus"], outputs: ["clicked"] }, { kind: "component", type: i9.FormControlComponent, selector: "ec-form-control", inputs: ["id", "icon", "actionIcon", "showClear", "formModel", "autofocus", "pending", "required", "readonly"], outputs: ["actionClicked"] }, { kind: "component", type: i10.HelpPopoverComponent, selector: "ec-help-popover", inputs: ["id", "text", "contentPosition", "maxWidth"] }, { kind: "component", type: i11.LinkButtonComponent, selector: "button[ecLinkButton]" }, { kind: "component", type: i12.CalendarComponent, selector: "ec-calendar", inputs: ["id", "selection", "selectionMode", "minDate", "maxDate", "view"], outputs: ["dateSelected", "viewChange"] }, { kind: "directive", type: i13.KeyboardNavContainerDirective, selector: "[ecKeyboardNavContainer]", inputs: ["ecKeyboardNavContainer"], outputs: ["focusOutStart", "focusOutEnd"], exportAs: ["ecKeyboardNavContainer"] }, { kind: "pipe", type: i14.TranslatePipe, name: "translate" }] });
433
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateInputComponent, decorators: [{
434
- type: Component,
435
- args: [{ selector: 'ec-date-input', providers: [DateInput.SelectionStrategies], template: "<label *ngIf=\"label\">\r\n <span>{{label | translate}}</span>\r\n <span *ngIf=\"validationErrors.length > 0 && formModel.touched && formModel.invalid\">&nbsp;{{validationErrors}}</span>\r\n <ec-help-popover id=\"{{id}}_helpPopover\"\r\n *ngIf=\"helpPopover\"\r\n class=\"d-inline-block my-n3 mx-n1\"\r\n text=\"{{helpPopover | translate}}\"\r\n contentPosition=\"{{helpPopoverPosition}}\">\r\n </ec-help-popover>\r\n</label>\r\n\r\n<div class=\"d-flex align-items-center\"\r\n [ecKeyboardNavContainer]=\"isCalendarOpen\"\r\n #controls=\"ecKeyboardNavContainer\"\r\n (focusOutEnd)=\"onControlsFocusOutEnd()\">\r\n <ec-form-control id=\"{{id}}\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n cdkOverlayOrigin\r\n #overlayOrigin=\"cdkOverlayOrigin\"\r\n class=\"flex-grow\"\r\n style=\"height: 2rem;\">\r\n <input id=\"{{id}}_input\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxGroup.get('textbox')\"\r\n (blur)=\"onTextboxBlur()\">\r\n </ec-form-control>\r\n\r\n <ng-container *ngIf=\"selectionStrategy.showSecondaryTextbox\">\r\n <span class=\"flex-shrink mx-1\">&ndash;</span>\r\n <ec-form-control id=\"{{id}}_control2\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n class=\"flex-grow\"\r\n style=\"height: 2rem;\">\r\n <input id=\"{{id}}_input2\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxGroup.get('textbox2')\"\r\n (blur)=\"onTextbox2Blur()\">\r\n </ec-form-control>\r\n </ng-container>\r\n\r\n <div *ngIf=\"enableSteppers\"\r\n class=\"control-group ml-2\">\r\n <ec-button id=\"{{id}}_previousSelection\"\r\n type=\"secondary\"\r\n icon=\"icon-angle-down rotate-90\"\r\n (clicked)=\"previousSelection()\"\r\n [disabled]=\"isCalendarOpen || disableSteppers || formModel?.disabled\">\r\n </ec-button>\r\n <ec-button id=\"{{id}}_nextSelection\"\r\n type=\"secondary\"\r\n icon=\"icon-angle-down rotate-270\"\r\n (clicked)=\"nextSelection()\"\r\n [disabled]=\"isCalendarOpen || disableSteppers || formModel?.disabled\">\r\n </ec-button>\r\n </div>\r\n\r\n <ec-button *ngIf=\"quickSelectDate\"\r\n id=\"{{id}}_quickSelect\"\r\n icon=\"icon-day\"\r\n type=\"secondary\"\r\n title=\"{{'DateInput_LatestDataAvailableTitle' | translate}}\"\r\n (clicked)=\"goToQuickSelectDate()\"\r\n class=\"ml-2\">\r\n </ec-button>\r\n</div>\r\n\r\n<ng-template cdkConnectedOverlay\r\n #overlay=\"cdkConnectedOverlay\"\r\n [cdkConnectedOverlayOrigin]=\"overlayOrigin\"\r\n [cdkConnectedOverlayOpen]=\"isCalendarOpen\"\r\n [cdkConnectedOverlayScrollStrategy]=\"overlayScrollStrategy\"\r\n cdkConnectedOverlayPanelClass=\"my-1\"\r\n (overlayOutsideClick)=\"onOverlayOutsideClick($event)\"\r\n (detach)=\"isCalendarOpen = false\">\r\n <article id=\"{{id}}_datePicker\"\r\n class=\"card d-flex\"\r\n [ecKeyboardNavContainer]=\"isCalendarOpen\"\r\n #calendar=\"ecKeyboardNavContainer\"\r\n (focusOutStart)=\"onCalendarFocusOutStart()\"\r\n (focusOutEnd)=\"onCalendarFocusOutEnd()\">\r\n <ul *ngIf=\"selectionModeOptions.length > 1\"\r\n class=\"selection-mode-menu border-right p-1\">\r\n <li *ngFor=\"let option of selectionModeOptions\">\r\n <button id=\"{{id}}_selectionMode_{{option}}\"\r\n class=\"text-body-1\"\r\n [class.is-selected]=\"option === selectionMode\"\r\n (click)=\"onSelectionModeChange(option)\">\r\n {{'DateInputSelectionMode_' + option | translate}}\r\n </button>\r\n </li>\r\n </ul>\r\n\r\n <div>\r\n <div class=\"d-flex\">\r\n <ec-calendar id=\"{{id}}_calendar\"\r\n [view]=\"primaryCalendarView\"\r\n (viewChange)=\"onPrimaryCalendarViewChange($event)\"\r\n [selectionMode]=\"selectionMode\"\r\n [selection]=\"calendarSelection\"\r\n (dateSelected)=\"onCalendarDateSelected($event)\"\r\n [minDate]=\"minDate\"\r\n [maxDate]=\"selectionStrategy.showSecondaryCalendar ? primaryCalendarMaxDate : maxDate\">\r\n </ec-calendar>\r\n\r\n <ec-calendar *ngIf=\"selectionStrategy.showSecondaryCalendar\"\r\n id=\"{{id}}_secondaryCalendar\"\r\n [view]=\"secondaryCalendarView\"\r\n (viewChange)=\"onSecondaryCalendarViewChange($event)\"\r\n [selectionMode]=\"selectionMode\"\r\n [selection]=\"calendarSelection\"\r\n (dateSelected)=\"onCalendarDateSelected($event)\"\r\n [minDate]=\"secondaryCalendarMinDate\"\r\n [maxDate]=\"maxDate\">\r\n </ec-calendar>\r\n </div>\r\n\r\n <footer *ngIf=\"selectionStrategy.selectionViewMode === 'day'\"\r\n class=\"px-2 my-2 d-flex\">\r\n <button id=\"{{id}}_today_button\"\r\n ecLinkButton\r\n class=\"ml-auto d-inline-block\"\r\n (click)=\"goToToday()\"\r\n style=\"height: 1.75rem;\">\r\n {{'Today' | translate}}\r\n </button>\r\n </footer>\r\n </div>\r\n </article>\r\n</ng-template>\r\n", styles: [":host{display:block}label{color:var(--ec-form-control-label-color, var(--ec-color-secondary-dark));display:block;font-size:var(--ec-font-size-label);line-height:1;margin:calc(var(--ec-font-size-label) / 2) 0}.date-picker{display:grid;grid-template-areas:\"menu calendar calendar\" \"menu footer footer\"}.date-picker footer{grid-area:footer}ul.selection-mode-menu{grid-area:menu;list-style:none;padding:0;margin:0;min-width:7rem}ul.selection-mode-menu li{margin-bottom:.25rem}ul.selection-mode-menu li button{font-size:var(--ec-font-size-action);height:2rem;line-height:1.25rem;padding:.3125rem .5rem;border:0;border-radius:var(--ec-border-radius);display:flex;align-items:center;justify-content:center;cursor:pointer;background-color:transparent;width:100%;height:1.75rem}ul.selection-mode-menu li button .label{display:flex;align-items:center;justify-content:center;white-space:nowrap;flex:auto}ul.selection-mode-menu li button .ec-icon{flex:none}ul.selection-mode-menu li button .ec-icon+.label{flex:none;margin-left:.25rem}ul.selection-mode-menu li button.has-badge{padding-right:.0625rem}ul.selection-mode-menu li button:focus{outline:none;position:relative;z-index:1}ul.selection-mode-menu li button:disabled{background-color:var(--ec-background-color-disabled);border:1px solid var(--ec-form-control-border-color-disabled);color:var(--ec-color-disabled-dark);opacity:var(--ec-form-control-opacity-disabled);cursor:default}ul.selection-mode-menu li button:disabled{background-color:transparent;border-color:transparent;color:var(--ec-color-hint-dark);--ec-color-icon: var(--ec-color-hint-dark)}ul.selection-mode-menu li button:hover:not(:disabled){background-color:var(--ec-background-color-hover)}ul.selection-mode-menu li button:active:not(:disabled){background-color:var(--ec-background-color-selected);font-weight:700}ul.selection-mode-menu li button:focus:not(:disabled){box-shadow:var(--ec-button-box-shadow-active, 0 0 0 2px var(--ec-border-color-focus))}ul.selection-mode-menu li button.is-selected{background-color:var(--ec-background-color-selected);font-weight:700}ec-button{--ec-button-border-color-secondary: var(--ec-border-color-control)}.control-group ec-button:has(+ ec-button) ::ng-deep button{border-right:0}.control-group ec-button+ec-button ::ng-deep button{border-left:0}\n"] }]
436
- }], ctorParameters: function () { return [{ type: i1.ValidationMessageService }, { type: i2.FormGroupHelper }, { type: i3.UserPreferenceService }, { type: i0.ElementRef }, { type: i4.Overlay }, { type: i5.DateInput.SelectionStrategies }]; }, propDecorators: { id: [{
437
- type: HostBinding,
438
- args: ['attr.id']
439
- }, {
440
- type: Input
441
- }], formModel: [{
442
- type: Input
443
- }], minDate: [{
444
- type: Input
445
- }], maxDate: [{
446
- type: Input
447
- }], selectionMode: [{
448
- type: Input
449
- }], selectionModeOptions: [{
450
- type: Input
451
- }], quickSelectDate: [{
452
- type: Input
453
- }], enableSteppers: [{
454
- type: Input
455
- }], calendar: [{
456
- type: ViewChild,
457
- args: ['calendar']
458
- }], controls: [{
459
- type: ViewChild,
460
- args: ['controls']
461
- }], overlay: [{
462
- type: ViewChild,
463
- args: ['overlay']
464
- }] } });
465
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1pbnB1dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NyYy9saWIvY29udHJvbHMvZGF0ZS1pbnB1dC9kYXRlLWlucHV0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9kYXRlLWlucHV0L2RhdGUtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFNBQVMsRUFBYyxXQUFXLEVBQUUsS0FBSyxFQUFvQyxTQUFTLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDdkgsT0FBTyxFQUFFLFdBQVcsRUFBcUIsU0FBUyxFQUFvQixNQUFNLGdCQUFnQixDQUFDO0FBQzdGLE9BQU8sTUFBTSxNQUFNLFFBQVEsQ0FBQztBQUM1QixPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQ3JDLE9BQU8sRUFBRSxZQUFZLEVBQUUsb0JBQW9CLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFL0UsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBSzdELE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxzQkFBc0IsQ0FBQztBQUV2RCxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sb0JBQW9CLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7QUFRL0MsTUFBTSxPQUFPLGtCQUFtQixTQUFRLGVBQWU7SUFxRXJELFlBQ1ksd0JBQWtELEVBQ2xELGVBQWdDLEVBQ2xDLHFCQUE0QyxFQUM1QyxFQUFjLEVBQ2QsY0FBdUIsRUFDdkIsbUJBQWtEO1FBRTFELEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxlQUFlLENBQUMsQ0FBQztRQVB2Qyw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQ2xELG9CQUFlLEdBQWYsZUFBZSxD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dUNpQixRQUFRO3NCQUE5QixTQUFTO3VCQUFDLFVBQVU7Z0JBQ0UsUUFBUTtzQkFBOUIsU0FBUzt1QkFBQyxVQUFVO2dCQUdDLE9BQU87c0JBQTVCLFNBQVM7dUJBQUMsU0FBUyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENka0Nvbm5lY3RlZE92ZXJsYXksIE92ZXJsYXkgfSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XHJcbmltcG9ydCB7IENvbXBvbmVudCwgRWxlbWVudFJlZiwgSG9zdEJpbmRpbmcsIElucHV0LCBPbkNoYW5nZXMsIE9uSW5pdCwgU2ltcGxlQ2hhbmdlcywgVmlld0NoaWxkIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IEZvcm1Db250cm9sLCBGb3JtQ29udHJvbFN0YXR1cywgRm9ybUdyb3VwLCBWYWxpZGF0aW9uRXJyb3JzIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XHJcbmltcG9ydCB7IGxhc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBLZXlib2FyZE5hdkNvbnRhaW5lckRpcmVjdGl2ZSB9IGZyb20gJy4uLy4uLy4uL3B1YmxpYy1hcGknO1xyXG5pbXBvcnQgeyBEYXRlVGltZUhlbHBlciB9IGZyb20gJy4uLy4uL2NvcmUvZGF0ZS10aW1lLWhlbHBlcic7XHJcbmltcG9ydCB7IFZhbGlkYXRpb25NZXNzYWdlU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvdmFsaWRhdGlvbi1tZXNzYWdlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBGb3JtR3JvdXBIZWxwZXIgfSBmcm9tICcuLi8uLi9zaGFyZWQvZm9ybS1ncm91cC5oZWxwZXInO1xyXG5pbXBvcnQgeyBVc2VyUHJlZmVyZW5jZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zaGFyZWQvdXNlci1wcmVmZXJlbmNlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBDYWxlbmRhciB9IGZyb20gJy4uL2NhbGVuZGFyL2NhbGVuZGFyLnR5cGVzJztcclxuaW1wb3J0IHsgRm9ybUNvbnRyb2xCYXNlIH0gZnJvbSAnLi4vZm9ybS1jb250cm9sLWJhc2UnO1xyXG5pbXBvcnQgeyBEYXRlSW5wdXRTZWxlY3Rpb25TdHJhdGVneUJhc2UgfSBmcm9tICcuL2RhdGUtaW5wdXQtc2VsZWN0aW9uLXN0cmF0ZWdpZXMvZGF0ZS1pbnB1dC1zZWxlY3Rpb24tc3RyYXRlZ3ktYmFzZSc7XHJcbmltcG9ydCB7IERhdGVJbnB1dCB9IGZyb20gJy4vZGF0ZS1pbnB1dC50eXBlcyc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2VjLWRhdGUtaW5wdXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlLWlucHV0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9kYXRlLWlucHV0LmNvbXBvbmVudC5zY3NzJ10sXHJcbiAgcHJvdmlkZXJzOiBbRGF0ZUlucHV0LlNlbGVjdGlvblN0cmF0ZWdpZXNdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBEYXRlSW5wdXRDb21wb25lbnQgZXh0ZW5kcyBGb3JtQ29udHJvbEJhc2UgaW1wbGVtZW50cyBPbkluaXQsIE9uQ2hhbmdlcyB7XHJcblxyXG4gIEBIb3N0QmluZGluZygnYXR0ci5pZCcpXHJcbiAgQElucHV0KCkgcHVibGljIGlkOiBzdHJpbmcgPSAnJztcclxuXHJcbiAgLyoqIFRoZSBmb3JtIGNvbnRyb2wgcHJvdmlkZWQgYnkgdGhlIGhvc3RpbmcgZm9ybS4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgZm9ybU1vZGVsOiBEYXRlSW5wdXQuRm9ybU1vZGVsID0gbmV3IEZvcm1Db250cm9sKG51bGwpO1xyXG5cclxuICBASW5wdXQoKSBwdWJsaWMgbWluRGF0ZTogRGF0ZSA9IERhdGVUaW1lSGVscGVyLm1pbkRhdGVQaWNrZXJEYXRlO1xyXG4gIEBJbnB1dCgpIHB1YmxpYyBtYXhEYXRlOiBEYXRlID0gRGF0ZVRpbWVIZWxwZXIubWF4RGF0ZVBpY2tlckRhdGU7XHJcblxyXG4gIC8qKiBUaGUgaW5pdGlhbCBzZWxlY3Rpb24gbW9kZSBmb3IgdGhlIGNhbGVuZGFyLiBEZWZhdWx0cyB0byBkYXkgaWYgbm90IHByb3ZpZGVkICovXHJcbiAgQElucHV0KCkgc2VsZWN0aW9uTW9kZTogRGF0ZUlucHV0LlNlbGVjdGlvbk1vZGUgPSAnZGF5JztcclxuXHJcbiAgLyoqIFRoZSBhdmFpbGFibGUgc2VsZWN0aW9uIG1vZGVzIGZvciB0aGUgY2FsZW5kYXIuIERlZmF1bHRzIHRvIG9ubHkgdGhlIGluaXRpYWwgc2VsZWN0aW9uIG1vZGUgaWYgbm90IHByb3ZpZGVkLiAgKi9cclxuICBASW5wdXQoKSBzZWxlY3Rpb25Nb2RlT3B0aW9uczogRGF0ZUlucHV0LlNlbGVjdGlvbk1vZGVbXSA9IFsnZGF5J107XHJcblxyXG4gIC8qKiBcclxuICAgKiBXaGVuIGEgZGF0ZSBpcyBwcm92aWRlZCwgZW5hYmxlcyB0aGUgJ3F1aWNrIHNlbGVjdCcgYnV0dG9uLlxyXG4gICAqIENsaWNraW5nIHRoZSBidXR0b24gd2lsbCBzaGlmdCB0aGUgc2VsZWN0ZWQgZGF0ZSByYW5nZSB0byB0aGUgcHJvdmlkZWQgZGF0ZS5cclxuICAgKi9cclxuICBASW5wdXQoKSBxdWlja1NlbGVjdERhdGU/OiBEYXRlO1xyXG5cclxuICAvKiogRW5hYmxlcyB0aGUgbmV4dC9wcmV2aW91cyBzZWxlY3Rpb24gYnV0dG9ucy4gKi9cclxuICBASW5wdXQoKSBlbmFibGVTdGVwcGVyczogYm9vbGVhbiA9IGZhbHNlO1xyXG5cclxuICAvKiogVGhlIGZvcm0gZ3JvdXAgZm9yIHRoZSBpbnRlcm5hbCB0ZXh0Ym94ZXMuIFRleHRib3gyIGlzIG9ubHkgdXNlZCBmb3IgcmFuZ2VzLiAqL1xyXG4gIHB1YmxpYyB0ZXh0Ym94R3JvdXA6IERhdGVJbnB1dC5UZXh0Ym94R3JvdXAgPSBuZXcgRm9ybUdyb3VwKHtcclxuICAgIHRleHRib3g6IG5ldyBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPihudWxsKSxcclxuICAgIHRleHRib3gyOiBuZXcgRm9ybUNvbnRyb2w8c3RyaW5nIHwgbnVsbD4obnVsbClcclxuICB9KTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGN1cnJlbnQgY2FsZW5kYXIgc2VsZWN0aW9uLlxyXG4gICAqIFVwZGF0ZWQgd2hlbiB0aGUgdXNlciBjbGlja3Mgb24gYSBjYWxlbmRhciBpdGVtIG9yIHdoZW4gdGhlIGRhdGUgZW50ZXJlZCBpbnRvIHRoZSB0ZXh0Ym94IGlzIHBhcnNlZC5cclxuICAgKi9cclxuICBwdWJsaWMgY2FsZW5kYXJTZWxlY3Rpb246IERhdGVJbnB1dC5TZWxlY3Rpb24gfCBudWxsID0gbnVsbDtcclxuXHJcbiAgLyoqIENvbnRyb2xzIHdoZXRoZXIgdGhlIGNhbGVuZGFyIG92ZXJsYXkgaXMgb3BlbiBvciBub3QuICovXHJcbiAgcHVibGljIGlzQ2FsZW5kYXJPcGVuID0gZmFsc2U7XHJcblxyXG4gIC8qKiBQbGFjZWhvbGRlciBmb3IgdGhlIHRleHRib3guIFVwZGF0ZWQgdG8gcmVmbGVjdCB0aGUgdXNlcidzIGRhdGUgZGlzcGxheSBwcmVmZXJlbmNlLiAqL1xyXG4gIHB1YmxpYyBwbGFjZWhvbGRlcjogc3RyaW5nID0gJ01NL0REL1lZWVknO1xyXG5cclxuICAvKiogT3ZlcmxheSBzY3JvbGwgc3RyYXRlZ3kgZm9yIHRoZSBjYWxlbmRhciBvdmVybGF5LiBDbG9zZXMgdGhlIGNhbGVuZGFyIG9uIHNjcm9sbC4gKi9cclxuICBwdWJsaWMgb3ZlcmxheVNjcm9sbFN0cmF0ZWd5ID0gdGhpcy5vdmVybGF5U2VydmljZS5zY3JvbGxTdHJhdGVnaWVzLmNsb3NlKCk7XHJcblxyXG4gIHB1YmxpYyBwcmltYXJ5Q2FsZW5kYXJWaWV3OiBDYWxlbmRhci5WaWV3ID0geyBtb2RlOiAnZGF5JywgZGF0ZTogbmV3IERhdGUoKSB9O1xyXG4gIHB1YmxpYyBzZWNvbmRhcnlDYWxlbmRhclZpZXc6IENhbGVuZGFyLlZpZXcgPSB7IG1vZGU6ICdkYXknLCBkYXRlOiBuZXcgRGF0ZSgpIH07XHJcblxyXG4gIHB1YmxpYyBwcmltYXJ5Q2FsZW5kYXJNYXhEYXRlOiBEYXRlID0gRGF0ZVRpbWVIZWxwZXIubWF4RGF0ZVBpY2tlckRhdGU7XHJcbiAgcHVibGljIHNlY29uZGFyeUNhbGVuZGFyTWluRGF0ZTogRGF0ZSA9IERhdGVUaW1lSGVscGVyLm1pbkRhdGVQaWNrZXJEYXRlO1xyXG5cclxuICBwdWJsaWMgZGlzYWJsZVN0ZXBwZXJzOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIHB1YmxpYyBzZWxlY3Rpb25TdHJhdGVneSE6IERhdGVJbnB1dFNlbGVjdGlvblN0cmF0ZWd5QmFzZTtcclxuXHJcbiAgLyoqIFxyXG4gICAqIERhdGUgcGFyc2luZyBmb3JtYXRzIGZvciB1c2VyLWVudGVyZWQgZGF0ZXMuIERlZmF1bHRzIHRvIG1vbnRoLWZpcnN0IGZvcm1hdHMsIGJ1dCBpcyB1cGRhdGVkIGluIG9uSW5pdFxyXG4gICAqIHRvIHVzZSB0aGUgdXNlcidzIHByZWZlcnJlZCBkYXRlIGZvcm1hdC5cclxuICAgKi9cclxuICBwcml2YXRlIHBhcnNlRm9ybWF0czogc3RyaW5nW10gPSBEYXRlVGltZUhlbHBlci5nZXRNb21lbnRQYXJzZUZvcm1hdHMoKTtcclxuXHJcbiAgQFZpZXdDaGlsZCgnY2FsZW5kYXInKSBjYWxlbmRhcj86IEtleWJvYXJkTmF2Q29udGFpbmVyRGlyZWN0aXZlO1xyXG4gIEBWaWV3Q2hpbGQoJ2NvbnRyb2xzJykgY29udHJvbHM/OiBLZXlib2FyZE5hdkNvbnRhaW5lckRpcmVjdGl2ZTtcclxuXHJcbiAgLyoqIFJlZmVyZW5jZSB0byB0aGUgb3ZlcmxheSBkaXJlY3RpdmUgKHNlZSB0ZW1wbGF0ZSkuIFVzZWQgdG8gdXBkYXRlIHRoZSBvdmVybGF5IHBvc2l0aW9uIG9uIHZhbGlkYXRpb24gY2hhbmdlcy4gKi9cclxuICBAVmlld0NoaWxkKCdvdmVybGF5Jykgb3ZlcmxheT86IENka0Nvbm5lY3RlZE92ZXJsYXk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJvdGVjdGVkIHZhbGlkYXRpb25NZXNzYWdlU2VydmljZTogVmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlLFxyXG4gICAgcHJvdGVjdGVkIGZvcm1Hcm91cEhlbHBlcjogRm9ybUdyb3VwSGVscGVyLFxyXG4gICAgcHJpdmF0ZSB1c2VyUHJlZmVyZW5jZVNlcnZpY2U6IFVzZXJQcmVmZXJlbmNlU2VydmljZSxcclxuICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXHJcbiAgICBwcml2YXRlIG92ZXJsYXlTZXJ2aWNlOiBPdmVybGF5LFxyXG4gICAgcHJpdmF0ZSBzZWxlY3Rpb25TdHJhdGVnaWVzOiBEYXRlSW5wdXQuU2VsZWN0aW9uU3RyYXRlZ2llc1xyXG4gICkge1xyXG4gICAgc3VwZXIodmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlLCBmb3JtR3JvdXBIZWxwZXIpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcykge1xyXG4gICAgaWYgKGNoYW5nZXMuc2VsZWN0aW9uTW9kZSAmJiAhY2hhbmdlcy5zZWxlY3Rpb25Nb2RlLmlzRmlyc3RDaGFuZ2UoKSkge1xyXG4gICAgICB0aGlzLm9uU2VsZWN0aW9uTW9kZUNoYW5nZSh0aGlzLnNlbGVjdGlvbk1vZGUpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICAvLyBTZXR1cFxyXG4gICAgc3VwZXIubmdPbkluaXQoKTtcclxuICAgIHRoaXMuc2V0RGF0ZUZvcm1hdHMoKTtcclxuICAgIHRoaXMuc2V0U2VsZWN0aW9uTW9kZSh0aGlzLnNlbGVjdGlvbk1vZGUpO1xyXG5cclxuICAgIC8vIFN1YnNjcmlwdGlvbnNcclxuICAgIHRoaXMub25Gb3JtTW9kZWxTdGF0dXNDaGFuZ2VzKCk7XHJcbiAgICB0aGlzLm9uRm9ybU1vZGVsVmFsdWVDaGFuZ2VzKCk7XHJcbiAgICB0aGlzLm9uVGV4dGJveFZhbHVlQ2hhbmdlcygpO1xyXG5cclxuICAgIC8vIFN5bmMgdGhlIGluaXRpYWwgZGlzYWJsZWQgc3RhdHVzIGFuZCB2YWx1ZSBvZiB0aGUgdGV4dGJveFxyXG4gICAgdGhpcy5zeW5jVGV4dGJveENvbnRyb2xEaXNhYmxlZFN0YXR1cyh0aGlzLmZvcm1Nb2RlbC5zdGF0dXMpO1xyXG4gICAgY29uc3QgaW5pdGlhbERpc3BsYXlWYWx1ZSA9IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuZm9ybWF0U2VsZWN0aW9uKHRoaXMuZm9ybU1vZGVsLnZhbHVlKTtcclxuICAgIHRoaXMudGV4dGJveEdyb3VwLnBhdGNoVmFsdWUoaW5pdGlhbERpc3BsYXlWYWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG5cclxuICAgIC8vIFVwZGF0ZSB0aGUgY2FsZW5kYXIgc2VsZWN0aW9uIGFuZCB2aWV3IGJhc2VkIG9uIHRoZSBpbml0aWFsIGZvcm0gbW9kZWwgdmFsdWVcclxuICAgIHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24gPSB0aGlzLmZvcm1Nb2RlbC52YWx1ZTtcclxuICAgIHRoaXMudXBkYXRlQ2FsZW5kYXJzKHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24pO1xyXG4gICAgdGhpcy51cGRhdGVTdGVwcGVycyh0aGlzLmNhbGVuZGFyU2VsZWN0aW9uKTtcclxuICAgIGNvbnNvbGUubG9nKHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgLyoqIEZvY3VzZXMgdGhlIGlucHV0IHdoZW5ldmVyIHRoZSBjYWxlbmRhciBpcyBzaGlmdC10YWJiZWQgb3V0IG9mLiAqL1xyXG4gIHB1YmxpYyBvbkNhbGVuZGFyRm9jdXNPdXRTdGFydCgpIHtcclxuICAgIHRoaXMuZm9jdXNJbnB1dCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqIENsb3NlcyB0aGUgY2FsZW5kYXIgYW5kIGZvY3VzZXMgdGhlIGlucHV0IHdoZW5ldmVyIHRoZSBjYWxlbmRhciBpcyB0YWJiZWQgb3V0IG9mLiAqL1xyXG4gIHB1YmxpYyBvbkNhbGVuZGFyRm9jdXNPdXRFbmQoKSB7XHJcbiAgICB0aGlzLmlzQ2FsZW5kYXJPcGVuID0gZmFsc2U7XHJcbiAgICB0aGlzLmZvY3VzSW5wdXQoKTtcclxuICB9XHJcblxyXG4gIC8qKiBDbG9zZXMgdGhlIGNhbGVuZGFyIGlmIHRoZSB1c2VyIGNsaWNrcyBvdXRzaWRlIG9mIHRoZSBjYWxlbmRhciBhbmQgZGF0ZSBpbnB1dC4gKi9cclxuICBwdWJsaWMgb25PdmVybGF5T3V0c2lkZUNsaWNrKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICAvLyBEbyBub3QgY2xvc2UgdGhlIGNhbGVuZGFyIGlmIHRoZSBjbGljayB3YXMgd2l0aGluIHRoZSBkYXRlIGlucHV0IG9yIGFjdGlvbiBidXR0b25cclxuICAgIGNvbnN0IHJlY3QgPSB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XHJcbiAgICBjb25zdCBjbGlja2VkT3V0c2lkZUNvbnRyb2wgPSBldmVudC5jbGllbnRZIDwgcmVjdC50b3AgfHxcclxuICAgICAgZXZlbnQuY2xpZW50WSA+IHJlY3QuYm90dG9tIHx8XHJcbiAgICAgIGV2ZW50LmNsaWVudFggPCByZWN0LmxlZnQgfHxcclxuICAgICAgZXZlbnQuY2xpZW50WCA+IHJlY3QucmlnaHQ7XHJcbiAgICAvLyBJdCdzIHBvc3NpYmxlIHRoYXQgdGhlIHVzZXIgaGl0IGVudGVyIG9uIHRoZSBhY3Rpb24gYnV0dG9uIGluc3RlYWQgb2YgY2xpY2tpbmcgd2l0aCB0aGUgbW91c2UuXHJcbiAgICAvLyBJbiB0aGlzIGNhc2UgdGhlIFwiY2xpY2tcIiBldmVudCB3aWxsIGJlIG91dHNpZGUgb2YgdGhlIGNvbXBvbmVudCBiZWNhdXNlIHRoZSBjbGllbnR4IGFuZCB5IGFyZSAwLFxyXG4gICAgLy8gYnV0IHdlIGRvbid0IHdhbnQgdG8gY2xvc2UgaW4gdGhpcyBjYXNlIGJlY2F1c2UgYnV0dG9uIGNsaWNrcyB0cmlnZ2VyIGNhbGVuZGFyIG9wZW4vY2xvc2Ugc2VwYXJhdGVseS5cclxuICAgIGNvbnN0IHRhcmdldElkID0gKDxIVE1MRWxlbWVudD5ldmVudC50YXJnZXQpLmlkO1xyXG4gICAgY29uc3QgaXNBY3Rpb25DbGljayA9IHRhcmdldElkID09PSBgJHt0aGlzLmlkfV9hY3Rpb25gIHx8IHRhcmdldElkID09PSBgJHt0aGlzLmlkfV9jb250cm9sMl9hY3Rpb25gO1xyXG5cclxuICAgIGlmICghaXNBY3Rpb25DbGljayAmJiBjbGlja2VkT3V0c2lkZUNvbnRyb2wpIHtcclxuICAgICAgdGhpcy5pc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIElmIHRoZSB1c2VyIHRhYnMgb3V0IG9mIHRoZSBmb3JtIGNvbnRyb2wncyBhY3Rpb24gYnV0dG9uIGFuZCB0aGUgY2FsZW5kYXIgaXMgb3BlbiwgZm9jdXMgdGhlIGZpcnN0IGl0ZW0gaW4gdGhlIGNhbGVuZGFyIG92ZXJsYXkgKi9cclxuICBwdWJsaWMgb25Db250cm9sc0ZvY3VzT3V0RW5kKCkge1xyXG4gICAgaWYgKHRoaXMuaXNDYWxlbmRhck9wZW4pIHtcclxuICAgICAgdGhpcy5jYWxlbmRhcj8uZm9jdXMoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBvblRleHRib3hCbHVyKCkge1xyXG4gICAgLy8gV2Ugd2FudCB0byBwcmV2ZW50IHRoZSBmaXhlZCBkYXRlIHJhbmdlIG1vZGVzIGZyb20gcmUtYXV0b2NvbXBsZXRpbmcgdGhlIGZpcnN0IHRleHRib3ggd2hlbiBpdCBpcyBleHBsaWNpdGx5IGNsZWFyZWQuXHJcbiAgICBjb25zdCBwcmV2aW91c1ZhbHVlID0gRGF0ZUlucHV0LmlzU2VsZWN0aW9uUmFuZ2UodGhpcy5mb3JtTW9kZWwudmFsdWUpID8gdGhpcy5mb3JtTW9kZWwudmFsdWUuc3RhcnQgOiB0aGlzLmZvcm1Nb2RlbC52YWx1ZTtcclxuICAgIGNvbnN0IGN1cnJlbnRWYWx1ZSA9IHRoaXMudGV4dGJveEdyb3VwLnZhbHVlLnRleHRib3g7XHJcbiAgICBjb25zdCBjbGVhcmVkID0gISFwcmV2aW91c1ZhbHVlICYmICFjdXJyZW50VmFsdWU7XHJcbiAgICBjb25zdCBvcHRpb25zOiBEYXRlSW5wdXQuUGFyc2luZ09wdGlvbnMgPSB7IHByZXZlbnRBdXRvQ29tcGxldGU6IGNsZWFyZWQgfTtcclxuXHJcbiAgICAvLyBQYXJzZSB0aGUgdGV4dGJveCB2YWx1ZXMgaW50byBhIHNlbGVjdGlvbiBhbmQgdXBkYXRlIHRoZSBmb3JtIG1vZGVsXHJcbiAgICBjb25zdCBwYXJzZWRTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnBhcnNlVGV4dGJveFZhbHVlcyh0aGlzLnRleHRib3hHcm91cC52YWx1ZSwgdGhpcy5wYXJzZUZvcm1hdHMsIG9wdGlvbnMpO1xyXG4gICAgdGhpcy51cGRhdGVGb3JtTW9kZWwocGFyc2VkU2VsZWN0aW9uKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvblRleHRib3gyQmx1cigpIHtcclxuICAgIC8vIFdlIHdhbnQgdG8gcHJldmVudCB0aGUgZml4ZWQgZGF0ZSByYW5nZSBtb2RlcyBmcm9tIHJlLWF1dG9jb21wbGV0aW5nIHRoZSBzZWNvbmQgdGV4dGJveCB3aGVuIGl0IGlzIGV4cGxpY2l0bHkgY2xlYXJlZC5cclxuICAgIGNvbnN0IHByZXZpb3VzVmFsdWUgPSBEYXRlSW5wdXQuaXNTZWxlY3Rpb25SYW5nZSh0aGlzLmZvcm1Nb2RlbC52YWx1ZSkgPyB0aGlzLmZvcm1Nb2RlbC52YWx1ZS5lbmQgOiBudWxsO1xyXG4gICAgY29uc3QgY3VycmVudFZhbHVlID0gdGhpcy50ZXh0Ym94R3JvdXAudmFsdWUudGV4dGJveDI7XHJcbiAgICBjb25zdCBjbGVhcmVkID0gISFwcmV2aW91c1ZhbHVlICYmICFjdXJyZW50VmFsdWU7XHJcbiAgICBjb25zdCBvcHRpb25zOiBEYXRlSW5wdXQuUGFyc2luZ09wdGlvbnMgPSB7IHBhcnNlRnJvbUVuZDogdHJ1ZSwgcHJldmVudEF1dG9Db21wbGV0ZTogY2xlYXJlZCB9O1xyXG5cclxuICAgIC8vIFBhcnNlIHRoZSB0ZXh0Ym94IHZhbHVlcyBpbnRvIGEgc2VsZWN0aW9uIGFuZCB1cGRhdGUgdGhlIGZvcm0gbW9kZWwsXHJcbiAgICAvLyBGb3IgdGhlIHNlY29uZCBib3ggd2UncmUga2V5aW5nIHRoZSBwYXJzZSBmcm9tIHRoZSBlbmQgZGF0ZSBpbiB0aGUgc2VsZWN0aW9uLlxyXG4gICAgY29uc3QgcGFyc2VkU2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5wYXJzZVRleHRib3hWYWx1ZXModGhpcy50ZXh0Ym94R3JvdXAudmFsdWUsIHRoaXMucGFyc2VGb3JtYXRzLCBvcHRpb25zKTtcclxuICAgIHRoaXMudXBkYXRlRm9ybU1vZGVsKHBhcnNlZFNlbGVjdGlvbik7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25TZWxlY3Rpb25Nb2RlQ2hhbmdlKG1vZGU6IERhdGVJbnB1dC5TZWxlY3Rpb25Nb2RlKSB7XHJcbiAgICB0aGlzLnNldFNlbGVjdGlvbk1vZGUobW9kZSk7XHJcbiAgICBjb25zdCBuZXdTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LmdldE5ld1NlbGVjdGlvbkZyb21FeGlzdGluZyh0aGlzLmNhbGVuZGFyU2VsZWN0aW9uKTtcclxuICAgIHRoaXMudXBkYXRlRm9ybU1vZGVsKG5ld1NlbGVjdGlvbik7XHJcblxyXG4gICAgLy8gT24gc2VsZWN0aW9uIG1vZGUgY2hhbmdlLCB3ZSB3YW50IHRvIGZvcmNlIHRoZSBjYWxlbmRhcnMgdG8gc2hvdyB0aGUgcmlnaHQgdmlldyBtb2RlIGZvciB0aGUgbmV3IHNlbGVjdGlvbi5cclxuICAgIC8vIFRoaXMgcHJldmVudHMgdGhlIHVzZXIgZnJvbSBzZWVpbmcgYSB2aWV3IG1vZGUgdGhhdCBkb2Vzbid0IG1ha2Ugc2Vuc2UgZm9yIHRoZSBuZXcgc2VsZWN0aW9uLFxyXG4gICAgLy8gTGlrZSB3aGVuIHN3aWNoaW5nIGZyb20geWVhciBtb2RlIHRvIGxhc3QgNyBkYXlzIG1vZGUuXHJcbiAgICB0aGlzLnByaW1hcnlDYWxlbmRhclZpZXcgPSB7IG1vZGU6IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2VsZWN0aW9uVmlld01vZGUsIGRhdGU6IHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldy5kYXRlIH07XHJcbiAgICB0aGlzLnNlY29uZGFyeUNhbGVuZGFyVmlldyA9IHsgbW9kZTogdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zZWxlY3Rpb25WaWV3TW9kZSwgZGF0ZTogdGhpcy5zZWNvbmRhcnlDYWxlbmRhclZpZXcuZGF0ZSB9O1xyXG4gICAgdGhpcy51cGRhdGVDYWxlbmRhck1pbk1heERhdGVzKCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25DYWxlbmRhckRhdGVTZWxlY3RlZChkYXRlOiBEYXRlKSB7XHJcbiAgICBjb25zdCBuZXdTZWxlY3Rpb24gPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LmdldFNlbGVjdGlvbkZyb21EYXRlKGRhdGUsIHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24pO1xyXG4gICAgY29uc3QgZGlzcGxheVZhbHVlID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5mb3JtYXRTZWxlY3Rpb24obmV3U2VsZWN0aW9uKTtcclxuICAgIC8vIERvbid0IGVtaXQgZXZlbnRzIHdoZW4gcGF0Y2hpbmcgdmFsdWVzIGhlcmUuIFdlIGRvbid0IHdhbnQgdG8gdHJpZ2dlciB0aGUgY2FsZW5kYXIgdXBkYXRlcyBzaW5jZSB0aGUgY2FsZW5kYXIgaXMgYWxyZWFkeVxyXG4gICAgLy8gc2hvd2luZyB0aGUgc2VsZWN0ZWQgZGF0ZS4gV2UgYWxzbyBkb24ndCB3YW50IHRvIHRyaWdnZXIgdGhlIHRleHRib3ggcGFyc2luZyBsb2dpYyBzaW5jZSB0aGUgZGF0ZSB3YXMgc2VsZWN0ZWQgZnJvbSB0aGUgY2FsZW5kYXIuXHJcbiAgICB0aGlzLnRleHRib3hHcm91cC5wYXRjaFZhbHVlKGRpc3BsYXlWYWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgdGhpcy5mb3JtTW9kZWwucGF0Y2hWYWx1ZShuZXdTZWxlY3Rpb24sIHsgZW1pdEV2ZW50OiBmYWxzZSB9KTtcclxuICAgIHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24gPSBuZXdTZWxlY3Rpb247XHJcbiAgICB0aGlzLnVwZGF0ZVN0ZXBwZXJzKG5ld1NlbGVjdGlvbik7XHJcblxyXG4gICAgLy8gQ2xvc2UgdGhlIGNhbGVuZGFyIGlmIHRoZSBzZWxlY3Rpb24gbW9kZSBpcyBub3QgYSByYW5nZSBtb2RlIHdoZXJlIGVpdGhlciB0aGUgc3RhcnQgb3IgdGhlIGVuZCBkYXRlIGNhbiBiZSBjaGFuZ2VkLlxyXG4gICAgaWYgKCF0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnNob3dTZWNvbmRhcnlUZXh0Ym94KSB7XHJcbiAgICAgIHRoaXMuaXNDYWxlbmRhck9wZW4gPSBmYWxzZTtcclxuICAgICAgdGhpcy5mb2N1c0lucHV0KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25QcmltYXJ5Q2FsZW5kYXJWaWV3Q2hhbmdlKHZpZXc6IENhbGVuZGFyLlZpZXcpIHtcclxuICAgIHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldyA9IHZpZXc7XHJcbiAgICB0aGlzLnVwZGF0ZUNhbGVuZGFyTWluTWF4RGF0ZXMoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBvblNlY29uZGFyeUNhbGVuZGFyVmlld0NoYW5nZSh2aWV3OiBDYWxlbmRhci5WaWV3KSB7XHJcbiAgICB0aGlzLnNlY29uZGFyeUNhbGVuZGFyVmlldyA9IHZpZXc7XHJcbiAgICB0aGlzLnVwZGF0ZUNhbGVuZGFyTWluTWF4RGF0ZXMoKTtcclxuICB9XHJcblxyXG4gIC8qKiBTaGlmdHMgdGhlIGNhbGVuZGFyIHZpZXdzIHRvIGRpc3BsYXkgdG9kYXkuIERvZXMgbm90IHVwZGF0ZSB0aGUgY2FsZW5kYXIgc2VsZWN0aW9uLiAqL1xyXG4gIHB1YmxpYyBnb1RvVG9kYXkoKSB7XHJcbiAgICAvLyBJZiBib3RoIGNhbGVuZGFycyBhcmUgdmlzaWJsZSwgc2hvdyB0b2RheSBpbiB0aGUgc2Vjb25kYXJ5IGNhbGVuZGFyIGFuZCB0aGUgbW9udGggYmVmb3JlIGluIHRoZSBwcmltYXJ5IGNhbGVuZGFyLlxyXG4gICAgaWYgKHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2hvd1NlY29uZGFyeUNhbGVuZGFyKSB7XHJcbiAgICAgIHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldyA9IHsgbW9kZTogJ2RheScsIGRhdGU6IG1vbWVudCgpLnN1YnRyYWN0KDEsICdtb250aCcpLnRvRGF0ZSgpIH07XHJcbiAgICAgIHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3ID0geyBtb2RlOiAnZGF5JywgZGF0ZTogbmV3IERhdGUoKSB9O1xyXG4gICAgICAvLyBJZiB3ZSdyZSBpbiBhIHNpbmdsZSBkYXRlIG1vZGUsIHNob3cgdG9kYXkgaW4gdGhlIHByaW1hcnkgY2FsZW5kYXIuXHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnByaW1hcnlDYWxlbmRhclZpZXcgPSB7IG1vZGU6ICdkYXknLCBkYXRlOiBuZXcgRGF0ZSgpIH07XHJcbiAgICB9XHJcbiAgICB0aGlzLnVwZGF0ZUNhbGVuZGFyTWluTWF4RGF0ZXMoKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBnb1RvUXVpY2tTZWxlY3REYXRlKCkge1xyXG4gICAgaWYgKHRoaXMucXVpY2tTZWxlY3REYXRlKSB7XHJcbiAgICAgIGNvbnN0IG5ld1NlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuZ2V0U2VsZWN0aW9uRm9yUXVpY2tTZWxlY3REYXRlKHRoaXMucXVpY2tTZWxlY3REYXRlLCB0aGlzLmNhbGVuZGFyU2VsZWN0aW9uKTtcclxuICAgICAgdGhpcy51cGRhdGVGb3JtTW9kZWwobmV3U2VsZWN0aW9uKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHB1YmxpYyBuZXh0U2VsZWN0aW9uKCkge1xyXG4gICAgY29uc3QgbmV3U2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5nZXROZXh0U2VsZWN0aW9uKHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24pO1xyXG4gICAgdGhpcy51cGRhdGVGb3JtTW9kZWwobmV3U2VsZWN0aW9uKTtcclxuICB9XHJcblxyXG4gIHB1YmxpYyBwcmV2aW91c1NlbGVjdGlvbigpIHtcclxuICAgIGNvbnN0IG5ld1NlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuZ2V0UHJldmlvdXNTZWxlY3Rpb24odGhpcy5jYWxlbmRhclNlbGVjdGlvbik7XHJcbiAgICB0aGlzLnVwZGF0ZUZvcm1Nb2RlbChuZXdTZWxlY3Rpb24pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVGb3JtTW9kZWwodmFsdWU6IERhdGVJbnB1dC5TZWxlY3Rpb24gfCBudWxsKSB7XHJcbiAgICB0aGlzLmZvcm1Nb2RlbC5wYXRjaFZhbHVlKHZhbHVlKTtcclxuXHJcbiAgICAvLyBWYWxpZGF0ZSB0aGUgdGV4dGJveGVzIGFuZCBzeW5jIHRoZSBmb3JtIGVycm9yc1xyXG4gICAgLy8gV2UgZG8gdGhpcyBhZnRlciBwYXRjaGluZyB0aGUgZm9ybSBtb2RlbCBiZWNhdXNlIHRoZSBmb3JtIG1vZGVsIHBhdGNoIHdpbGwgdHJpZ2dlclxyXG4gICAgLy8gdGhlIGRhdGUgZm9ybWF0dGluZyBsb2dpYyBhbmQgb3ZlcndyaXRlIGFueSBlcnJvcnMgb24gdGhlIGNvbnRyb2xzIGZyb20gYmVmb3JlLlxyXG4gICAgdGhpcy52YWxpZGF0ZVRleHRib3hlcygpO1xyXG4gICAgdGhpcy5zeW5jRm9ybUVycm9ycygpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvbkZvcm1Nb2RlbFN0YXR1c0NoYW5nZXMoKSB7XHJcbiAgICAvLyBLZWVwIHRoZSB0ZXh0Ym94Q29udHJvbCBkaXNhYmxlZCBzdGF0dXMgaW4gc3luYyB3aXRoIHRoZSBmb3JtTW9kZWxcclxuICAgIHRoaXMuZm9ybU1vZGVsLnN0YXR1c0NoYW5nZXMucGlwZShcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgdGFrZVVudGlsKHRoaXMuY29tcG9uZW50RGVzdHJveWVkKVxyXG4gICAgKS5zdWJzY3JpYmUoc3RhdHVzID0+IHtcclxuICAgICAgdGhpcy5zeW5jVGV4dGJveENvbnRyb2xEaXNhYmxlZFN0YXR1cyhzdGF0dXMpO1xyXG5cclxuICAgICAgaWYgKHRoaXMuaXNDYWxlbmRhck9wZW4pIHtcclxuICAgICAgICAvLyBBcyB2YWxpZGF0aW9uIG1lc3NhZ2VzIGFwcGVhci9kaXNhcHBlYXIsIHRoZSBkYXRlIGlucHV0IG1heSBoYXZlIHNoaWZ0ZWQgdXAgb3IgZG93biBvbiB0aGUgcGFnZS5cclxuICAgICAgICAvLyBVcGRhdGUgdGhlIG92ZXJsYXkgcG9zaXRpb24gdG8gZW5zdXJlIGl0J3Mgc3RpbGwgYWxpZ25lZCB3aXRoIHRoZSB0ZXh0Ym94IGFuZCBub3QgYmxvY2tpbmcgaXQuXHJcbiAgICAgICAgLy8gU2V0dGltZW91dCBpcyBuZWVkZWQgdG8gZW5zdXJlIHRoZSBvdmVybGF5IGlzIGJlaW5nIHVwZGF0ZWQgYWZ0ZXIgdGhlIG1lc3NhZ2UgaXMgcmVuZGVyZWQuXHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLm92ZXJsYXk/Lm92ZXJsYXlSZWY/LnVwZGF0ZVBvc2l0aW9uKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvbkZvcm1Nb2RlbFZhbHVlQ2hhbmdlcygpIHtcclxuICAgIC8vIFVwZGF0ZSB0aGUgY2FsZW5kYXIgc2VsZWN0aW9uIHRleHRib3ggdmFsdWUgd2l0aCBhIGZvcm1hdHRlZCBkYXRlIHdoZW4gdGhlIGZvcm0gbW9kZWwgY2hhbmdlcy5cclxuICAgIC8vIFRoaXMgaXMgdHJpZ2dlcmVkIGJ5IHRoZSB1c2VyIHNlbGVjdGluZyBhIGRhdGUgZnJvbSB0aGUgY2FsZW5kYXIgb3Igd2hlbiB0aGUgdGV4dGJveCBpcyBibHVycmVkLlxyXG4gICAgdGhpcy5mb3JtTW9kZWwudmFsdWVDaGFuZ2VzLnBpcGUoXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLmNvbXBvbmVudERlc3Ryb3llZClcclxuICAgICkuc3Vic2NyaWJlKHZhbHVlID0+IHtcclxuICAgICAgY29uc3QgZGlzcGxheVZhbHVlID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5mb3JtYXRTZWxlY3Rpb24odmFsdWUpO1xyXG4gICAgICAvLyBEb24ndCBlbWl0IGFuIGV2ZW50IHdoZW4gc2V0dGluZyB0aGUgdGV4dGJveCB2YWx1ZSB0byBhdm9pZCBjaXJjdWxhciB1cGRhdGVzIGJldHdlZW4gdGhlIHRleHRib3ggYW5kIGZvcm0gbW9kZWwuXHJcbiAgICAgIHRoaXMudGV4dGJveEdyb3VwLnBhdGNoVmFsdWUoZGlzcGxheVZhbHVlLCB7IGVtaXRFdmVudDogZmFsc2UgfSk7XHJcbiAgICAgIHRoaXMudXBkYXRlQ2FsZW5kYXJzKHZhbHVlKTtcclxuICAgICAgdGhpcy51cGRhdGVTdGVwcGVycyh2YWx1ZSk7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgb25UZXh0Ym94VmFsdWVDaGFuZ2VzKCkge1xyXG4gICAgLy8gVXBkYXRlIHRoZSBjYWxlbmRhciBzZWxlY3Rpb24gd2hlbiB0aGUgdGV4dGJveCB2YWx1ZSBjaGFuZ2VzIHRvIHVwZGF0ZSB0aGUgY2FsZW5kYXIuXHJcbiAgICAvLyBXZSBkb24ndCBwYXRjaCB0aGUgZm9ybU1vZGVsIGhlcmUgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIHRyaWdnZXIgdGhlXHJcbiAgICAvLyBkYXRlIGZvcm1hdHRpbmcgbG9naWMgYW5kIG92ZXJ3cml0ZSB0aGUgdXNlcidzIGlucHV0LlxyXG4gICAgLy8gV2UnbGwgZG8gdGhhdCB3aGVuIHRoZSB1c2VyIGJsdXJzIG91dCBvZiB0aGUgdGV4dGJveC4gU2VlIG9uVGV4dGJveEJsdXIoKVxyXG4gICAgdGhpcy50ZXh0Ym94R3JvdXAuY29udHJvbHMudGV4dGJveC52YWx1ZUNoYW5nZXMucGlwZShcclxuICAgICAgZGVib3VuY2VUaW1lKDMwMCksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLmNvbXBvbmVudERlc3Ryb3llZClcclxuICAgICkuc3Vic2NyaWJlKCgpID0+IHtcclxuICAgICAgY29uc3Qgb3B0aW9uczogRGF0ZUlucHV0LlBhcnNpbmdPcHRpb25zID0geyBzaGlmdFRvQ3VycmVudFllYXJJZkJlbG93OiB0aGlzLm1pbkRhdGUgfTtcclxuICAgICAgY29uc3QgbmV3U2VsZWN0aW9uID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5wYXJzZVRleHRib3hWYWx1ZXModGhpcy50ZXh0Ym94R3JvdXAudmFsdWUsIHRoaXMucGFyc2VGb3JtYXRzLCBvcHRpb25zKTtcclxuXHJcbiAgICAgIC8vIENhbGVuZGFyIHNlbGVjdGlvbiB3aWxsIGJlIG51bGwgaWYgdGhlIGRhdGVzIGFyZSBpbnZhbGlkLiBEb24ndCB1cGRhdGUgdGhlIGNhbGVuZGFycyBpbiB0aGlzIGNhc2UuXHJcbiAgICAgIGlmIChuZXdTZWxlY3Rpb24pIHtcclxuICAgICAgICB0aGlzLmNhbGVuZGFyU2VsZWN0aW9uID0gbmV3U2VsZWN0aW9uO1xyXG4gICAgICAgIHRoaXMudXBkYXRlUHJpbWFyeUNhbGVuZGFyKHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24sIHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2hvd1NlY29uZGFyeUNhbGVuZGFyKTtcclxuICAgICAgICB0aGlzLnVwZGF0ZUNhbGVuZGFyTWluTWF4RGF0ZXMoKTtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgLy8gVGhlIHNlY29uZCB0ZXh0Ym94IGlzIG9ubHkgdXNlZCBpbiBsYXN0N0RheXMsIGxhc3QyOERheXMsIGFuZCByYW5nZSBtb2Rlcy5cclxuICAgIHRoaXMudGV4dGJveEdyb3VwLmNvbnRyb2xzLnRleHRib3gyLnZhbHVlQ2hhbmdlcy5waXBlKFxyXG4gICAgICBkZWJvdW5jZVRpbWUoMzAwKSxcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgdGFrZVVudGlsKHRoaXMuY29tcG9uZW50RGVzdHJveWVkKVxyXG4gICAgKS5zdWJzY3JpYmUoKCkgPT4ge1xyXG4gICAgICBjb25zdCBvcHRpb25zOiBEYXRlSW5wdXQuUGFyc2luZ09wdGlvbnMgPSB7IHNoaWZ0VG9DdXJyZW50WWVhcklmQmVsb3c6IHRoaXMubWluRGF0ZSwgcGFyc2VGcm9tRW5kOiB0cnVlIH07XHJcbiAgICAgIGNvbnN0IG5ld1NlbGVjdGlvbiA9IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kucGFyc2VUZXh0Ym94VmFsdWVzKHRoaXMudGV4dGJveEdyb3VwLnZhbHVlLCB0aGlzLnBhcnNlRm9ybWF0cywgb3B0aW9ucyk7XHJcblxyXG4gICAgICAvLyBDYWxlbmRhciBzZWxlY3Rpb24gd2lsbCBiZSBudWxsIGlmIHRoZSBkYXRlcyBhcmUgaW52YWxpZC4gRG9uJ3QgdXBkYXRlIHRoZSBjYWxlbmRhcnMgaW4gdGhpcyBjYXNlLlxyXG4gICAgICBpZiAobmV3U2VsZWN0aW9uKSB7XHJcbiAgICAgICAgdGhpcy5jYWxlbmRhclNlbGVjdGlvbiA9IG5ld1NlbGVjdGlvbjtcclxuICAgICAgICAvLyBUaGUgc2Vjb25kYXJ5IGNhbGVuZGFyIGlzIG9ubHkgc2hvd24gaW4gcmFuZ2UgbW9kZS4gVXBkYXRlIHRoZSBwcmltYXJ5IGNhbGVuZGFyIGlmIHdlJ3JlIG5vdCBpbiByYW5nZSBtb2RlLlxyXG4gICAgICAgIGlmICh0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnNob3dTZWNvbmRhcnlDYWxlbmRhcikge1xyXG4gICAgICAgICAgdGhpcy51cGRhdGVTZWNvbmRhcnlDYWxlbmRhcih0aGlzLmNhbGVuZGFyU2VsZWN0aW9uLCB0cnVlKTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgdGhpcy51cGRhdGVQcmltYXJ5Q2FsZW5kYXIodGhpcy5jYWxlbmRhclNlbGVjdGlvbik7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMudXBkYXRlQ2FsZW5kYXJNaW5NYXhEYXRlcygpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgc3luY1RleHRib3hDb250cm9sRGlzYWJsZWRTdGF0dXMoc3RhdHVzOiBGb3JtQ29udHJvbFN0YXR1cykge1xyXG4gICAgLy8gVGhlIHRleHRib3ggc2hvdWxkIG9ubHkgYmUgZGlzYWJsZWQgaWYgdGhlIGZvcm0gbW9kZWwgaXMgZGlzYWJsZWQuXHJcbiAgICAvLyBBbGwgb3RoZXIgc3RhdHVzZXMgYXJlIGNvbnNpZGVyZWQgZW5hYmxlZC5cclxuICAgIGlmIChzdGF0dXMgPT09ICdESVNBQkxFRCcgJiYgdGhpcy50ZXh0Ym94R3JvdXAuZW5hYmxlZCkge1xyXG4gICAgICB0aGlzLnRleHRib3hHcm91cC5kaXNhYmxlKCk7XHJcbiAgICB9IGVsc2UgaWYgKHN0YXR1cyAhPT0gJ0RJU0FCTEVEJyAmJiB0aGlzLnRleHRib3hHcm91cC5kaXNhYmxlZCkge1xyXG4gICAgICB0aGlzLnRleHRib3hHcm91cC5lbmFibGUoKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICBwcml2YXRlIHN5bmNGb3JtRXJyb3JzKCkge1xyXG4gICAgLy8gU3RhcnQgd2l0aCB0aGUgZXhpc3RpbmcgZm9ybSBtb2RlbCBlcnJvcnNcclxuICAgIGxldCBlcnJvcnMgPSB0aGlzLmZvcm1Nb2RlbC5lcnJvcnM7XHJcblxyXG4gICAgLy8gQWRkIHRoZSBlcnJvcnMgZnJvbSB0aGUgdGV4dGJveGVzIGlmIHRoZXkgZXhpc3RcclxuICAgIGlmICh0aGlzLnRleHRib3hHcm91cC5jb250cm9scy50ZXh0Ym94LmVycm9ycykge1xyXG4gICAgICBlcnJvcnMgPSB7IC4uLmVycm9ycywgLi4udGhpcy50ZXh0Ym94R3JvdXAuY29udHJvbHMudGV4dGJveC5lcnJvcnMgfTtcclxuICAgIH1cclxuICAgIGlmICh0aGlzLnRleHRib3hHcm91cC5jb250cm9scy50ZXh0Ym94Mi5lcnJvcnMpIHtcclxuICAgICAgZXJyb3JzID0geyAuLi5lcnJvcnMsIC4uLnRoaXMudGV4dGJveEdyb3VwLmNvbnRyb2xzLnRleHRib3gyLmVycm9ycyB9O1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFVwZGF0ZSB0aGUgZm9ybSBtb2RlbCdzIGVycm9ycyB3aXRoIHRoZSBjb21iaW5lZCBlcnJvcnNcclxuICAgIHRoaXMuZm9ybU1vZGVsLnNldEVycm9ycyhlcnJvcnMpO1xyXG5cclxuICAgIC8vIFVwZGF0ZSB0aGUgZm9ybSBtb2RlbCdzIHRvdWNoZWQgYW5kIGRpcnR5IHN0YXR1cyBiYXNlZCBvbiB0aGUgdGV4dGJveCdzIHN0YXR1cy5cclxuICAgIC8vIFNpbmNlIHRoZSB1c2VyIGludGVyYWN0cyB3aXRoIGEgY29udHJvbCB0aGF0IGlzIGludGVybmFsIHRvIHRoaXMgY29tcG9uZW50LCB0aGVcclxuICAgIC8vIGZvcm0gbW9kZWwncyBzdGF0dXMgd29uJ3QgYmUgdXBkYXRlZCBhdXRvbWF0aWNhbGx5LlxyXG4gICAgaWYgKHRoaXMudGV4dGJveEdyb3VwLnRvdWNoZWQgJiYgIXRoaXMuZm9ybU1vZGVsLnRvdWNoZWQpIHtcclxuICAgICAgdGhpcy5mb3JtTW9kZWwubWFya0FzVG91Y2hlZCgpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMudGV4dGJveEdyb3VwLmRpcnR5ICYmICF0aGlzLmZvcm1Nb2RlbC5kaXJ0eSkge1xyXG4gICAgICB0aGlzLmZvcm1Nb2RlbC5tYXJrQXNEaXJ0eSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLyoqIFxyXG4gICAqIFVwZGF0ZXMgdGhlIGRhdGUgcGFyc2luZyBmb3JtYXRzIGFuZCBwbGFjZWhvbGRlciBiYXNlZCBvbiB0aGUgdXNlcidzIGRpc3BsYXkgcHJlZmVyZW5jZS5cclxuICAgKiBOT1RFOiBUaGlzIGlzIGFzeW5jIGJlY2F1c2Ugd2UncmUgcmV0cmlldmluZyB0aGUgdXNlcidzIHByZWZlcmVuY2VzLiBXZSdyZSBub3QgYXdhaXRpbmcgdGhlIHJlc3VsdFxyXG4gICAqIGJlY2F1c2UgdGhlIG9ubHkgbG9naWMgdGhhdCBkZXBlbmRzIG9uIHRoaXMgaXMgdGhlIHRleHQgYm94IGRhdGUgcGFyc2luZyBsb2dpYyBhbmQgcGxhY2Vob2xkZXIuXHJcbiAgICogT3VyIGZvcm1zIHNob3VsZCBhbHdheXMgYmUgYmVoaW5kIGEgcGVuZGluZyBvdmVybGF5LCBzbyB0aGUgdXNlciB3b24ndCBiZSBhYmxlIHRvIGludGVyYWN0IHdpdGggdGhlXHJcbiAgICogZm9ybSB1bnRpbCB0aGUgdXNlciBpcyBsb2FkZWQgYW55d2F5LlxyXG4gICAqL1xyXG4gIHByaXZhdGUgYXN5bmMgc2V0RGF0ZUZvcm1hdHMoKSB7XHJcbiAgICBjb25zdCB7IHByZWZlcmVuY2UgfSA9IGF3YWl0IGxhc3RWYWx1ZUZyb20odGhpcy51c2VyUHJlZmVyZW5jZVNlcnZpY2UuZ2V0UHJlZmVyZW5jZXMoKSk7XHJcbiAgICBjb25zdCBkYXRlRm9ybWF0ID0gcHJlZmVyZW5jZT8uZGF0ZUZvcm1hdDtcclxuICAgIHRoaXMucGxhY2Vob2xkZXIgPSBkYXRlRm9ybWF0ID8/IHRoaXMucGxhY2Vob2xkZXI7XHJcbiAgICB0aGlzLnBhcnNlRm9ybWF0cyA9IERhdGVUaW1lSGVscGVyLmdldE1vbWVudFBhcnNlRm9ybWF0cyhkYXRlRm9ybWF0KTtcclxuICB9XHJcblxyXG4gIC8qKiBGb2N1c2VzIHRoZSBkYXRlIGlucHV0LiAqL1xyXG4gIHByaXZhdGUgZm9jdXNJbnB1dCgpIHtcclxuICAgIHRoaXMuY29udHJvbHM/LmZvY3VzKCk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHNldFNlbGVjdGlvbk1vZGUobW9kZTogRGF0ZUlucHV0LlNlbGVjdGlvbk1vZGUpIHtcclxuICAgIHRoaXMuc2VsZWN0aW9uTW9kZSA9IG1vZGU7XHJcbiAgICB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5ID0gdGhpcy5zZWxlY3Rpb25TdHJhdGVnaWVzW21vZGVdO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogU2V0cyB0aGUgbWF4IGRhdGUgZm9yIHRoZSBwcmltYXJ5IGNhbGVuZGFyIGFuZCB0aGUgbWluIGRhdGUgZm9yIHRoZSBzZWNvbmRhcnkgY2FsZW5kYXIgYmFzZWRcclxuICAgKiBvbiB0aGUgY3VycmVudCB2aWV3cyBpbiBlYWNoLiBUaGlzIHByZXZlbnRzIHRoZSB1c2VyIGZyb20gbW92aW5nIHRoZSBjYWxlbmRhcnMgb3V0IG9mIG9yZGVyLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgdXBkYXRlQ2FsZW5kYXJNaW5NYXhEYXRlcygpIHtcclxuICAgIC8vIE9ubHkgdXBkYXRlIHRoZSBtaW4vbWF4IGRhdGVzIHdoZW4gdGhlIHZpZXcgbW9kZSBpcyAnZGF5Jy5cclxuICAgIC8vIFdoZW4gYSBjYWxlbmRhciBpcyBpbiBhIG1vbnRoIG9yIHllYXIgdmlldyBtb2RlLCB0aGUgdmlldyBkYXRlcyBhdCB0aGUgYmVnaW5uaW5nIG9mIHRoZSB5ZWFyLlxyXG4gICAgLy8gVGhpcyB3b3VsZCBjYXVzZSB0aGUgZGF0ZXMgaW4gdGhlIG90aGVyIGNhbGVuZGFyIHRvIGJlIHVuc2VsZWN0YWJsZSBpZiB3ZSB3ZXJlIHRvXHJcbiAgICAvLyB1cGRhdGUgdGhlIG1pbi9tYXggZGF0ZXMgaW4gdGhlc2UgY2FzZXMuXHJcbiAgICBpZiAodGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3Py5tb2RlID09PSAnZGF5Jykge1xyXG4gICAgICB0aGlzLnNlY29uZGFyeUNhbGVuZGFyTWluRGF0ZSA9IG1vbWVudCh0aGlzLnByaW1hcnlDYWxlbmRhclZpZXc/LmRhdGUpLmFkZCgxLCAnbW9udGgnKS5zdGFydE9mKCdtb250aCcpLnRvRGF0ZSgpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3Py5tb2RlID09PSAnZGF5Jykge1xyXG4gICAgICB0aGlzLnByaW1hcnlDYWxlbmRhck1heERhdGUgPSBtb21lbnQodGhpcy5zZWNvbmRhcnlDYWxlbmRhclZpZXc/LmRhdGUpLnN1YnRyYWN0KDEsICdtb250aCcpLmVuZE9mKCdtb250aCcpLnRvRGF0ZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVDYWxlbmRhcnMoc2VsZWN0aW9uOiBEYXRlSW5wdXQuU2VsZWN0aW9uIHwgbnVsbCkge1xyXG4gICAgdGhpcy5jYWxlbmRhclNlbGVjdGlvbiA9IHNlbGVjdGlvbjtcclxuICAgIHRoaXMudXBkYXRlUHJpbWFyeUNhbGVuZGFyKHNlbGVjdGlvbik7XHJcbiAgICAvLyBPbmx5IHNoaWZ0IHRoZSBwcmltYXJ5IGNhbGVuZGFyIGlmIHdlJ3JlIHNob3dpbmcgdGhlIHNlY29uZGFyeSBjYWxlbmRhclxyXG4gICAgdGhpcy51cGRhdGVTZWNvbmRhcnlDYWxlbmRhcihzZWxlY3Rpb24sIHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2hvd1NlY29uZGFyeUNhbGVuZGFyKTtcclxuXHJcbiAgICB0aGlzLnVwZGF0ZUNhbGVuZGFyTWluTWF4RGF0ZXMoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgdXBkYXRlUHJpbWFyeUNhbGVuZGFyKHNlbGVjdGlvbjogRGF0ZUlucHV0LlNlbGVjdGlvbiB8IG51bGwsIHNoaWZ0U2Vjb25kYXJ5OiBib29sZWFuID0gZmFsc2UpIHtcclxuICAgIHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldyA9IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuZ2V0UHJpbWFyeUNhbGVuZGFyVmlldyhzZWxlY3Rpb24sIHRoaXMubWluRGF0ZSwgdGhpcy5tYXhEYXRlLCB0aGlzLnByaW1hcnlDYWxlbmRhclZpZXcpO1xyXG5cclxuICAgIC8vIFdoZW4gZW50ZXJpbmcgYSBkYXRlIGludG8gdGhlIGZpcnN0IHRleHRib3gsIHdlIHJlYWxseSBvbmx5IHdhbnQgdG8gdXBkYXRlIHRoZSBwcmltYXJ5IGNhbGVuZGFyLlxyXG4gICAgLy8gSG93ZXZlciwgaXQncyBwb3NzaWJsZSB0aGF0IHRoZSBuZXcgZGF0ZSBpcyBhZnRlciB0aGUgc2Vjb25kYXJ5IGNhbGVuZGFyJ3MgZGF0ZS4gSW4gdGhpcyBjYXNlLFxyXG4gICAgLy8gV2Ugd2FudCB0byBzaGlmdCB0aGUgc2Vjb25kYXJ5IGNhbGVuZGFyIHNvIHRoZSBjYWxlbmRhcnMgc3RheSBpbiBvcmRlci5cclxuICAgIGlmIChzaGlmdFNlY29uZGFyeSAmJiB0aGlzLnNlY29uZGFyeUNhbGVuZGFyVmlldykge1xyXG4gICAgICBpZiAobW9tZW50KHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldy5kYXRlKS5pc1NhbWVPckFmdGVyKHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3LmRhdGUsICdtb250aCcpKSB7XHJcbiAgICAgICAgbGV0IG5ld1NlY29uZGFyeURhdGUgPSBtb21lbnQodGhpcy5wcmltYXJ5Q2FsZW5kYXJWaWV3LmRhdGUpLmFkZCgxLCAnbW9udGgnKS50b0RhdGUoKTtcclxuICAgICAgICB0aGlzLnNlY29uZGFyeUNhbGVuZGFyVmlldyA9IHsgbW9kZTogdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zZWxlY3Rpb25WaWV3TW9kZSwgZGF0ZTogbmV3U2Vjb25kYXJ5RGF0ZSB9O1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHVwZGF0ZVNlY29uZGFyeUNhbGVuZGFyKHNlbGVjdGlvbjogRGF0ZUlucHV0LlNlbGVjdGlvbiB8IG51bGwsIHNoaWZ0UHJpbWFyeTogYm9vbGVhbiA9IGZhbHNlKSB7XHJcbiAgICB0aGlzLnNlY29uZGFyeUNhbGVuZGFyVmlldyA9IHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuZ2V0U2Vjb25kYXJ5Q2FsZW5kYXJWaWV3KHNlbGVjdGlvbiwgdGhpcy5taW5EYXRlLCB0aGlzLm1heERhdGUsIHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3KTtcclxuXHJcbiAgICAvLyBXaGVuIGVudGVyaW5nIGEgZGF0ZSBpbnRvIHRoZSBzZWNvbmQgdGV4dGJveCwgd2UgcmVhbGx5IG9ubHkgd2FudCB0byB1cGRhdGUgdGhlIHNlY29uZGFyeSBjYWxlbmRhci5cclxuICAgIC8vIEhvd2V2ZXIsIGl0J3MgcG9zc2libGUgdGhhdCB0aGUgbmV3IGRhdGUgaXMgYmVmb3JlIHRoZSBwcmltYXJ5IGNhbGVuZGFyJ3MgZGF0ZS4gSW4gdGhpcyBjYXNlLFxyXG4gICAgLy8gV2Ugd2FudCB0byBzaGlmdCB0aGUgcHJpbWFyeSBjYWxlbmRhciBzbyB0aGUgY2FsZW5kYXJzIHN0YXkgaW4gb3JkZXIuXHJcbiAgICBpZiAoc2hpZnRQcmltYXJ5ICYmIHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldykge1xyXG4gICAgICBpZiAobW9tZW50KHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldy5kYXRlKS5pc1NhbWVPckFmdGVyKHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3LmRhdGUsICdtb250aCcpKSB7XHJcbiAgICAgICAgbGV0IG5ld1ByaW1hcnlEYXRlID0gbW9tZW50KHRoaXMuc2Vjb25kYXJ5Q2FsZW5kYXJWaWV3LmRhdGUpLnN1YnRyYWN0KDEsICdtb250aCcpLnRvRGF0ZSgpO1xyXG4gICAgICAgIHRoaXMucHJpbWFyeUNhbGVuZGFyVmlldyA9IHsgbW9kZTogdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zZWxlY3Rpb25WaWV3TW9kZSwgZGF0ZTogbmV3UHJpbWFyeURhdGUgfTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB1cGRhdGVTdGVwcGVycyh2YWx1ZTogRGF0ZUlucHV0LlNlbGVjdGlvbiB8IG51bGwpIHtcclxuICAgIC8vIERpc2FibGUgdGhlIHN0ZXBwZXJzIGlmIHdlIGVpdGhlciBkb24ndCBoYXZlIGEgc2VsZWN0aW9uIG9yIG9ubHkgaGF2ZSBvbmUgZGF0ZSBpbiB0aGUgc2VsZWN0aW9uLlxyXG4gICAgaWYgKFxyXG4gICAgICAhdmFsdWUgfHxcclxuICAgICAgKERhdGVJbnB1dC5pc1NlbGVjdGlvblNpbmdsZURhdGUodmFsdWUpICYmIHRoaXMuc2VsZWN0aW9uTW9kZSAhPT0gJ2RheScpIHx8XHJcbiAgICAgIChEYXRlSW5wdXQuaXNTZWxlY3Rpb25SYW5nZSh2YWx1ZSkgJiYgKCF2YWx1ZS5zdGFydCB8fCAhdmFsdWUuZW5kKSlcclxuICAgICkge1xyXG4gICAgICB0aGlzLmRpc2FibGVTdGVwcGVycyA9IHRydWU7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmRpc2FibGVTdGVwcGVycyA9IGZhbHNlO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB2YWxpZGF0ZVRleHRib3hlcygpIHtcclxuICAgIGNvbnN0IGNvbnRyb2wgPSB0aGlzLnRleHRib3hHcm91cC5jb250cm9scy50ZXh0Ym94O1xyXG4gICAgY29uc3QgY29udHJvbDIgPSB0aGlzLnRleHRib3hHcm91cC5jb250cm9scy50ZXh0Ym94MjtcclxuXHJcbiAgICAvLyBUaGUgZmlyc3QgdGV4dGJveCBzaG91bGQgb25seSBoYXZlIHRoZSByZXF1aXJlZCBlcnJvciBpZiBpdCdzIGVtcHR5IGFuZCB0aGUgZGF0ZSBpbnB1dCBpcyByZXF1aXJlZCxcclxuICAgIC8vIG9yIGlmIHRoZSBkYXRlIGlucHV0IGlzIG5vdCByZXF1aXJlZCBhbmQgdGhlIHNlY29uZCBjb250cm9sIGlzIHZpc2libGUgYW5kIGhhcyBhIHZhbHVlIChtZWFuaW5nIGEgcGFydGlhbCByYW5nZSlcclxuICAgIGlmIChcclxuICAgICAgIWNvbnRyb2wudmFsdWUgJiZcclxuICAgICAgKHRoaXMucmVxdWlyZWQgfHwgKGNvbnRyb2wyLnZhbHVlICYmIHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2hvd1NlY29uZGFyeVRleHRib3gpKVxyXG4gICAgKSB7XHJcbiAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKHsgcmVxdWlyZWQ6IHRydWUgfSk7XHJcbiAgICB9XHJcbiAgICAvLyBUaGUgc2FtZSBpZGVhIGFwcGxpZXMgdG8gdGhlIHNlY29uZCB0ZXh0Ym94LCBidXQgb25seSBpZiBpdCdzIHZpc2libGVcclxuICAgIGlmIChcclxuICAgICAgdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zaG93U2Vjb25kYXJ5VGV4dGJveCAmJlxyXG4gICAgICAhY29udHJvbDIudmFsdWUgJiZcclxuICAgICAgKHRoaXMucmVxdWlyZWQgfHwgY29udHJvbC52YWx1ZSlcclxuICAgICkge1xyXG4gICAgICBjb250cm9sMi5zZXRFcnJvcnMoeyByZXF1aXJlZDogdHJ1ZSB9KTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29udHJvbC52YWx1ZSkge1xyXG4gICAgICBjb25zdCBlcnJvcnMgPSB0aGlzLnZhbGlkYXRlRGF0ZVN0cmluZyhjb250cm9sLnZhbHVlKTtcclxuICAgICAgaWYgKGVycm9ycykge1xyXG4gICAgICAgIGNvbnRyb2wuc2V0RXJyb3JzKGVycm9ycyk7XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBpZiAoY29udHJvbDIudmFsdWUgJiYgdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zaG93U2Vjb25kYXJ5VGV4dGJveCkge1xyXG4gICAgICBjb25zdCBlcnJvcnMgPSB0aGlzLnZhbGlkYXRlRGF0ZVN0cmluZyhjb250cm9sMi52YWx1ZSk7XHJcbiAgICAgIGlmIChlcnJvcnMpIHtcclxuICAgICAgICBjb250cm9sMi5zZXRFcnJvcnMoZXJyb3JzKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSB2YWxpZGF0ZURhdGVTdHJpbmcoZGF0ZTogc3RyaW5nKTogVmFsaWRhdGlvbkVycm9ycyB8IG51bGwge1xyXG4gICAgY29uc3QgdmFsdWUgPSB0aGlzLnNlbGVjdGlvblN0cmF0ZWd5LnBhcnNlU3RyaW5nKGRhdGUsIHRoaXMucGFyc2VGb3JtYXRzKTtcclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICAvLyBXZSdyZSB1c2luZyB0aGUgdmlldyBtb2RlIGFzIHRoZSBncmFudWxhcml0eS4gV2UgZG9uJ3Qgd2FudCB0byBpbnZhbGlkYXRlXHJcbiAgICAgIC8vIHRoZSBkYXRlIGluIHRoZSBjYXNlIHdoZXJlIHlvdSBoYXZlIGEgbW9udGgvcXVhcnRlci95ZWFyIHNlbGVjdGVkIGFuZCB0aGUgbWluXHJcbiAgICAgIC8vIG9yIG1heCBkYXRlIGlzIHNvbWV3aGVyZSB3aXRoaW4gdGhhdCBtb250aC9xdWFydGVyL3llYXIuXHJcbiAgICAgIGlmIChtb21lbnQodmFsdWUpLmlzQmVmb3JlKHRoaXMubWluRGF0ZSwgdGhpcy5zZWxlY3Rpb25TdHJhdGVneS5zZWxlY3Rpb25WaWV3TW9kZSkpIHtcclxuICAgICAgICByZXR1cm4geyBtaW5EYXRlOiB7IG1pblZhbHVlOiB0aGlzLm1pbkRhdGUgfSB9O1xyXG4gICAgICB9IGVsc2UgaWYgKG1vbWVudCh2YWx1ZSkuaXNBZnRlcih0aGlzLm1heERhdGUsIHRoaXMuc2VsZWN0aW9uU3RyYXRlZ3kuc2VsZWN0aW9uVmlld01vZGUpKSB7XHJcbiAgICAgICAgcmV0dXJuIHsgbWF4RGF0ZTogeyBtYXhWYWx1ZTogdGhpcy5tYXhEYXRlIH0gfTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBudWxsO1xyXG4gIH1cclxufVxyXG4iLCI8bGFiZWwgKm5nSWY9XCJsYWJlbFwiPlxyXG4gIDxzcGFuPnt7bGFiZWwgfCB0cmFuc2xhdGV9fTwvc3Bhbj5cclxuICA8c3BhbiAqbmdJZj1cInZhbGlkYXRpb25FcnJvcnMubGVuZ3RoID4gMCAmJiBmb3JtTW9kZWwudG91Y2hlZCAmJiBmb3JtTW9kZWwuaW52YWxpZFwiPiZuYnNwO3t7dmFsaWRhdGlvbkVycm9yc319PC9zcGFuPlxyXG4gIDxlYy1oZWxwLXBvcG92ZXIgaWQ9XCJ7e2lkfX1faGVscFBvcG92ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgKm5nSWY9XCJoZWxwUG9wb3ZlclwiXHJcbiAgICAgICAgICAgICAgICAgICBjbGFzcz1cImQtaW5saW5lLWJsb2NrIG15LW4zIG14LW4xXCJcclxuICAgICAgICAgICAgICAgICAgIHRleHQ9XCJ7e2hlbHBQb3BvdmVyIHwgdHJhbnNsYXRlfX1cIlxyXG4gICAgICAgICAgICAgICAgICAgY29udGVudFBvc2l0aW9uPVwie3toZWxwUG9wb3ZlclBvc2l0aW9ufX1cIj5cclxuICA8L2VjLWhlbHAtcG9wb3Zlcj5cclxuPC9sYWJlbD5cclxuXHJcbjxkaXYgY2xhc3M9XCJkLWZsZXggYWxpZ24taXRlbXMtY2VudGVyXCJcclxuICAgICBbZWNLZXlib2FyZE5hdkNvbnRhaW5lcl09XCJpc0NhbGVuZGFyT3BlblwiXHJcbiAgICAgI2NvbnRyb2xzPVwiZWNLZXlib2FyZE5hdkNvbnRhaW5lclwiXHJcbiAgICAgKGZvY3VzT3V0RW5kKT1cIm9uQ29udHJvbHNGb2N1c091dEVuZCgpXCI+XHJcbiAgPGVjLWZvcm0tY29udHJvbCBpZD1cInt7aWR9fVwiXHJcbiAgICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgICAgW2F1dG9mb2N1c109XCJhdXRvZm9jdXNcIlxyXG4gICAgICAgICAgICAgICAgICAgW3BlbmRpbmddPVwicGVuZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgICAgKGFjdGlvbkNsaWNrZWQpPVwiaXNDYWxlbmRhck9wZW4gPSAhaXNDYWxlbmRhck9wZW5cIlxyXG4gICAgICAgICAgICAgICAgICAgW3Nob3dDbGVhcl09XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICBhY3Rpb25JY29uPVwiaWNvbi1kYXRlXCJcclxuICAgICAgICAgICAgICAgICAgIGNka092ZXJsYXlPcmlnaW5cclxuICAgICAgICAgICAgICAgICAgICNvdmVybGF5T3JpZ2luPVwiY2RrT3ZlcmxheU9yaWdpblwiXHJcbiAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXgtZ3Jvd1wiXHJcbiAgICAgICAgICAgICAgICAgICBzdHlsZT1cImhlaWdodDogMnJlbTtcIj5cclxuICAgIDxpbnB1dCBpZD1cInt7aWR9fV9pbnB1dFwiXHJcbiAgICAgICAgICAgdHlwZT1cInRleHRcIlxyXG4gICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3twbGFjZWhvbGRlcn19XCJcclxuICAgICAgICAgICBbZm9ybUNvbnRyb2xdPVwidGV4dGJveEdyb3VwLmdldCgndGV4dGJveCcpXCJcclxuICAgICAgICAgICAoYmx1cik9XCJvblRleHRib3hCbHVyKClcIj5cclxuICA8L2VjLWZvcm0tY29udHJvbD5cclxuXHJcbiAgPG5nLWNvbnRhaW5lciAqbmdJZj1cInNlbGVjdGlvblN0cmF0ZWd5LnNob3dTZWNvbmRhcnlUZXh0Ym94XCI+XHJcbiAgICA8c3BhbiBjbGFzcz1cImZsZXgtc2hyaW5rIG14LTFcIj4mbmRhc2g7PC9zcGFuPlxyXG4gICAgPGVjLWZvcm0tY29udHJvbCBpZD1cInt7aWR9fV9jb250cm9sMlwiXHJcbiAgICAgICAgICAgICAgICAgICAgIFtyZXF1aXJlZF09XCJyZXF1aXJlZFwiXHJcbiAgICAgICAgICAgICAgICAgICAgIFthdXRvZm9jdXNdPVwiYXV0b2ZvY3VzXCJcclxuICAgICAgICAgICAgICAgICAgICAgW3BlbmRpbmddPVwicGVuZGluZ1wiXHJcbiAgICAgICAgICAgICAgICAgICAgIFtyZWFkb25seV09XCJyZWFkb25seVwiXHJcbiAgICAgICAgICAgICAgICAgICAgIChhY3Rpb25DbGlja2VkKT1cImlzQ2FsZW5kYXJPcGVuID0gIWlzQ2FsZW5kYXJPcGVuXCJcclxuICAgICAgICAgICAgICAgICAgICAgW3Nob3dDbGVhcl09XCJmYWxzZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgIGFjdGlvbkljb249XCJpY29uLWRhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImZsZXgtZ3Jvd1wiXHJcbiAgICAgICAgICAgICAgICAgICAgIHN0eWxlPVwiaGVpZ2h0OiAycmVtO1wiPlxyXG4gICAgICA8aW5wdXQgaWQ9XCJ7e2lkfX1faW5wdXQyXCJcclxuICAgICAgICAgICAgIHR5cGU9XCJ0ZXh0XCJcclxuICAgICAgICAgICAgIHBsYWNlaG9sZGVyPVwie3twbGFjZWhvbGRlcn19XCJcclxuICAgICAgICAgICAgIFtmb3JtQ29udHJvbF09XCJ0ZXh0Ym94R3JvdXAuZ2V0KCd0ZXh0Ym94MicpXCJcclxuICAgICAgICAgICAgIChibHVyKT1cIm9uVGV4dGJveDJCbHVyKClcIj5cclxuICAgIDwvZWMtZm9ybS1jb250cm9sPlxyXG4gIDwvbmctY29udGFpbmVyPlxyXG5cclxuICA8ZGl2ICpuZ0lmPVwiZW5hYmxlU3RlcHBlcnNcIlxyXG4gICAgICAgY2xhc3M9XCJjb250cm9sLWdyb3VwIG1sLTJcIj5cclxuICAgIDxlYy1idXR0b24gaWQ9XCJ7e2lkfX1fcHJldmlvdXNTZWxlY3Rpb25cIlxyXG4gICAgICAgICAgICAgICB0eXBlPVwic2Vjb25kYXJ5XCJcclxuICAgICAgICAgICAgICAgaWNvbj1cImljb24tYW5nbGUtZG93biByb3RhdGUtOTBcIlxyXG4gICAgICAgICAgICAgICAoY2xpY2tlZCk9XCJwcmV2aW91c1NlbGVjdGlvbigpXCJcclxuICAgICAgICAgICAgICAgW2Rpc2FibGVkXT1cImlzQ2FsZW5kYXJPcGVuIHx8IGRpc2FibGVTdGVwcGVycyB8fCBmb3JtTW9kZWw/LmRpc2FibGVkXCI+XHJcbiAgICA8L2VjLWJ1dHRvbj5cclxuICAgIDxlYy1idXR0b24gaWQ9XCJ7e2lkfX1fbmV4dFNlbGVjdGlvblwiXHJcbiAgICAgICAgICAgICAgIHR5cGU9XCJzZWNvbmRhcnlcIlxyXG4gICAgICAgICAgICAgICBpY29uPVwiaWNvbi1hbmdsZS1kb3duIHJvdGF0ZS0yNzBcIlxyXG4gICAgICAgICAgICAgICAoY2xpY2tlZCk9XCJuZXh0U2VsZWN0aW9uKClcIlxyXG4gICAgICAgICAgICAgICBbZGlzYWJsZWRdPVwiaXNDYWxlbmRhck9wZW4gfHwgZGlzYWJsZVN0ZXBwZXJzIHx8IGZvcm1Nb2RlbD8uZGlzYWJsZWRcIj5cclxuICAgIDwvZWMtYnV0dG9uPlxyXG4gIDwvZGl2PlxyXG5cclxuICA8ZWMtYnV0dG9uICpuZ0lmPVwicXVpY2tTZWxlY3REYXRlXCJcclxuICAgICAgICAgICAgIGlkPVwie3tpZH19X3F1aWNrU2VsZWN0XCJcclxuICAgICAgICAgICAgIGljb249XCJpY29uLWRheVwiXHJcbiAgICAgICAgICAgICB0eXBlPVwic2Vjb25kYXJ5XCJcclxuICAgICAgICAgICAgIHRpdGxlPVwie3snRGF0ZUlucHV0X0xhdGVzdERhdGFBdmFpbGFibGVUaXRsZScgfCB0cmFuc2xhdGV9fVwiXHJcbiAgICAgICAgICAgICAoY2xpY2tlZCk9XCJnb1RvUXVpY2tTZWxlY3REYXRlKClcIlxyXG4gICAgICAgICAgICAgY2xhc3M9XCJtbC0yXCI+XHJcbiAgPC9lYy1idXR0b24+XHJcbjwvZGl2PlxyXG5cclxuPG5nLXRlbXBsYXRlIGNka0Nvbm5lY3RlZE92ZXJsYXlcclxuICAgICAgICAgICAgICNvdmVybGF5PVwiY2RrQ29ubmVjdGVkT3ZlcmxheVwiXHJcbiAgICAgICAgICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbl09XCJvdmVybGF5T3JpZ2luXCJcclxuICAgICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5T3Blbl09XCJpc0NhbGVuZGFyT3BlblwiXHJcbiAgICAgICAgICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheVNjcm9sbFN0cmF0ZWd5XT1cIm92ZXJsYXlTY3JvbGxTdHJhdGVneVwiXHJcbiAgICAgICAgICAgICBjZGtDb25uZWN0ZWRPdmVybGF5UGFuZWxDbGFzcz1cIm15LTFcIlxyXG4gICAgICAgICAgICAgKG92ZXJsYXlPdXRzaWRlQ2xpY2spPVwib25PdmVybGF5T3V0c2lkZUNsaWNrKCRldmVudClcIlxyXG4gICAgICAgICAgICAgKGRldGFjaCk9XCJpc0NhbGVuZGFyT3BlbiA9IGZhbHNlXCI+XHJcbiAgPGFydGljbGUgaWQ9XCJ7e2lkfX1fZGF0ZVBpY2tlclwiXHJcbiAgICAgICAgICAgY2xhc3M9XCJjYXJkIGQtZmxleFwiXHJcbiAgICAgICAgICAgW2VjS2V5Ym9hcmROYXZDb250YWluZXJdPVwiaXNDYWxlbmRhck9wZW5cIlxyXG4gICAgICAgICAgICNjYWxlbmRhcj1cImVjS2V5Ym9hcmROYXZDb250YWluZXJcIlxyXG4gICAgICAgICAgIChmb2N1c091dFN0YXJ0KT1cIm9uQ2FsZW5kYXJGb2N1c091dFN0YXJ0KClcIlxyXG4gICAgICAgICAgIChmb2N1c091dEVuZCk9XCJvbkNhbGVuZGFyRm9jdXNPdXRFbmQoKVwiPlxyXG4gICAgPHVsICpuZ0lmPVwic2VsZWN0aW9uTW9kZU9wdGlvbnMubGVuZ3RoID4gMVwiXHJcbiAgICAgICAgY2xhc3M9XCJzZWxlY3Rpb24tbW9kZS1tZW51IGJvcmRlci1yaWdodCBwLTFcIj5cclxuICAgICAgPGxpICpuZ0Zvcj1cImxldCBvcHRpb24gb2Ygc2VsZWN0aW9uTW9kZU9wdGlvbnNcIj5cclxuICAgICAgICA8YnV0dG9uIGlkPVwie3tpZH19X3NlbGVjdGlvbk1vZGVfe3tvcHRpb259fVwiXHJcbiAgICAgICAgICAgICAgICBjbGFzcz1cInRleHQtYm9keS0xXCJcclxuICAgICAgICAgICAgICAgIFtjbGFzcy5pcy1zZWxlY3RlZF09XCJvcHRpb24gPT09IHNlbGVjdGlvbk1vZGVcIlxyXG4gICAgICAgICAgICAgICAgKGNsaWNrKT1cIm9uU2VsZWN0aW9uTW9kZUNoYW5nZShvcHRpb24pXCI+XHJcbiAgICAgICAgICB7eydEYXRlSW5wdXRTZWxlY3Rpb25Nb2RlXycgKyBvcHRpb24gfCB0cmFuc2xhdGV9fVxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8L2xpPlxyXG4gICAgPC91bD5cclxuXHJcbiAgICA8ZGl2PlxyXG4gICAgICA8ZGl2IGNsYXNzPVwiZC1mbGV4XCI+XHJcbiAgICAgICAgPGVjLWNhbGVuZGFyIGlkPVwie3tpZH19X2NhbGVuZGFyXCJcclxuICAgICAgICAgICAgICAgICAgICAgW3ZpZXddPVwicHJpbWFyeUNhbGVuZGFyVmlld1wiXHJcbiAgICAgICAgICAgICAgICAgICAgICh2aWV3Q2hhbmdlKT1cIm9uUHJpbWFyeUNhbGVuZGFyVmlld0NoYW5nZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgICAgICAgW3NlbGVjdGlvbk1vZGVdPVwic2VsZWN0aW9uTW9kZVwiXHJcbiAgICAgICAgICAgICAgICAgICAgIFtzZWxlY3Rpb25dPVwiY2FsZW5kYXJTZWxlY3Rpb25cIlxyXG4gICAgICAgICAgICAgICAgICAgICAoZGF0ZVNlbGVjdGVkKT1cIm9uQ2FsZW5kYXJEYXRlU2VsZWN0ZWQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgIFttaW5EYXRlXT1cIm1pbkRhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbbWF4RGF0ZV09XCJzZWxlY3Rpb25TdHJhdGVneS5zaG93U2Vjb25kYXJ5Q2FsZW5kYXIgPyBwcmltYXJ5Q2FsZW5kYXJNYXhEYXRlIDogbWF4RGF0ZVwiPlxyXG4gICAgICAgIDwvZWMtY2FsZW5kYXI+XHJcblxyXG4gICAgICAgIDxlYy1jYWxlbmRhciAqbmdJZj1cInNlbGVjdGlvblN0cmF0ZWd5LnNob3dTZWNvbmRhcnlDYWxlbmRhclwiXHJcbiAgICAgICAgICAgICAgICAgICAgIGlkPVwie3tpZH19X3NlY29uZGFyeUNhbGVuZGFyXCJcclxuICAgICAgICAgICAgICAgICAgICAgW3ZpZXddPVwic2Vjb25kYXJ5Q2FsZW5kYXJWaWV3XCJcclxuICAgICAgICAgICAgICAgICAgICAgKHZpZXdDaGFuZ2UpPVwib25TZWNvbmRhcnlDYWxlbmRhclZpZXdDaGFuZ2UoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgICAgICAgIFtzZWxlY3Rpb25Nb2RlXT1cInNlbGVjdGlvbk1vZGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbc2VsZWN0aW9uXT1cImNhbGVuZGFyU2VsZWN0aW9uXCJcclxuICAgICAgICAgICAgICAgICAgICAgKGRhdGVTZWxlY3RlZCk9XCJvbkNhbGVuZGFyRGF0ZVNlbGVjdGVkKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbbWluRGF0ZV09XCJzZWNvbmRhcnlDYWxlbmRhck1pbkRhdGVcIlxyXG4gICAgICAgICAgICAgICAgICAgICBbbWF4RGF0ZV09XCJtYXhEYXRlXCI+XHJcbiAgICAgICAgPC9lYy1jYWxlbmRhcj5cclxuICAgICAgPC9kaXY+XHJcblxyXG4gICAgICA8Zm9vdGVyICpuZ0lmPVwic2VsZWN0aW9uU3RyYXRlZ3kuc2VsZWN0aW9uVmlld01vZGUgPT09ICdkYXknXCJcclxuICAgICAgICAgICAgICBjbGFzcz1cInB4LTIgbXktMiBkLWZsZXhcIj5cclxuICAgICAgICA8YnV0dG9uIGlkPVwie3tpZH19X3RvZGF5X2J1dHRvblwiXHJcbiAgICAgICAgICAgICAgICBlY0xpbmtCdXR0b25cclxuICAgICAgICAgICAgICAgIGNsYXNzPVwibWwtYXV0byBkLWlubGluZS1ibG9ja1wiXHJcbiAgICAgICAgICAgICAgICAoY2xpY2spPVwiZ29Ub1RvZGF5KClcIlxyXG4gICAgICAgICAgICAgICAgc3R5bGU9XCJoZWlnaHQ6IDEuNzVyZW07XCI+XHJcbiAgICAgICAgICB7eydUb2RheScgfCB0cmFuc2xhdGV9fVxyXG4gICAgICAgIDwvYnV0dG9uPlxyXG4gICAgICA8L2Zvb3Rlcj5cclxuICAgIDwvZGl2PlxyXG4gIDwvYXJ0aWNsZT5cclxuPC9uZy10ZW1wbGF0ZT5cclxuIl19