@energycap/components 0.41.0 → 0.41.1-ECAP-27592-angular-17.20241220-1140

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 (258) hide show
  1. package/{esm2020 → esm2022}/energycap-components.mjs +4 -4
  2. package/{esm2020 → esm2022}/lib/components.module.mjs +418 -418
  3. package/{esm2020 → esm2022}/lib/controls/banner/banner.component.mjs +109 -109
  4. package/{esm2020 → esm2022}/lib/controls/button/button.component.mjs +106 -106
  5. package/{esm2020 → esm2022}/lib/controls/button/copy-button-base.directive.mjs +67 -67
  6. package/{esm2020 → esm2022}/lib/controls/button/copy-button.directive.mjs +28 -28
  7. package/{esm2020 → esm2022}/lib/controls/button/copy-table-button.directive.mjs +43 -43
  8. package/{esm2020 → esm2022}/lib/controls/calendar/calendar-item.component.mjs +59 -59
  9. package/{esm2020 → esm2022}/lib/controls/calendar/calendar.component.mjs +200 -200
  10. package/{esm2020 → esm2022}/lib/controls/calendar/calendar.types.mjs +3 -3
  11. package/{esm2020 → esm2022}/lib/controls/checkbox/checkbox.component.mjs +140 -140
  12. package/{esm2020 → esm2022}/lib/controls/collapsible-toggle/collapsible-toggle.component.mjs +38 -38
  13. package/{esm2020 → esm2022}/lib/controls/combobox/combobox.component.mjs +879 -879
  14. package/{esm2020 → esm2022}/lib/controls/date-input/date-input.component.mjs +256 -256
  15. package/{esm2020 → esm2022}/lib/controls/dropdown/dropdown.component.mjs +243 -243
  16. package/{esm2020 → esm2022}/lib/controls/file-upload/file-upload.component.mjs +261 -261
  17. package/{esm2020 → esm2022}/lib/controls/form-control/form-control.component.mjs +104 -104
  18. package/{esm2020 → esm2022}/lib/controls/form-control-base.mjs +151 -151
  19. package/{esm2020 → esm2022}/lib/controls/form-control-label/form-control-label.component.mjs +136 -136
  20. package/{esm2020 → esm2022}/lib/controls/form-group/form-group.component.mjs +261 -261
  21. package/{esm2020 → esm2022}/lib/controls/help-popover/help-popover.component.mjs +31 -31
  22. package/{esm2020 → esm2022}/lib/controls/item-picker/item-picker.component.mjs +329 -329
  23. package/{esm2020 → esm2022}/lib/controls/link-button/link-button.component.mjs +11 -11
  24. package/{esm2020 → esm2022}/lib/controls/menu/menu.component.mjs +485 -485
  25. package/{esm2020 → esm2022}/lib/controls/navigation/link-item.mjs +1 -1
  26. package/{esm2020 → esm2022}/lib/controls/navigation/nav-group.mjs +38 -38
  27. package/{esm2020 → esm2022}/lib/controls/navigation/nav-item-active.directive.mjs +92 -92
  28. package/{esm2020 → esm2022}/lib/controls/navigation/nav-item.mjs +1 -1
  29. package/{esm2020 → esm2022}/lib/controls/numericbox/numericbox.component.mjs +372 -372
  30. package/{esm2020 → esm2022}/lib/controls/popover/popover.component.mjs +117 -117
  31. package/{esm2020 → esm2022}/lib/controls/radio-button/radio-button-option.mjs +2 -2
  32. package/{esm2020 → esm2022}/lib/controls/radio-button/radio-button.component.mjs +82 -82
  33. package/{esm2020 → esm2022}/lib/controls/select/select.component.mjs +88 -88
  34. package/{esm2020 → esm2022}/lib/controls/tabs/tabs.component.mjs +47 -47
  35. package/{esm2020 → esm2022}/lib/controls/textbox/textbox.component.mjs +155 -155
  36. package/{esm2020 → esm2022}/lib/core/cache.service.mjs +105 -105
  37. package/esm2022/lib/core/custom-validators.mjs +29 -0
  38. package/esm2022/lib/core/date-time-helper.mjs +220 -0
  39. package/{esm2020 → esm2022}/lib/core/error.service.mjs +61 -61
  40. package/{esm2020 → esm2022}/lib/core/router-helper.service.mjs +111 -111
  41. package/{esm2020 → esm2022}/lib/core/scroll.service.mjs +89 -89
  42. package/{esm2020 → esm2022}/lib/core/telemetry-tracker.service.mjs +16 -16
  43. package/{esm2020 → esm2022}/lib/core/telemetry.service.mjs +38 -38
  44. package/{esm2020 → esm2022}/lib/core/validation-message.service.mjs +185 -185
  45. package/{esm2020 → esm2022}/lib/core/validation-patterns.mjs +30 -30
  46. package/{esm2020 → esm2022}/lib/core/window.service.mjs +186 -186
  47. package/{esm2020 → esm2022}/lib/display/app-bar/app-bar.component.mjs +46 -46
  48. package/esm2022/lib/display/avatar/avatar.component.mjs +67 -0
  49. package/{esm2020 → esm2022}/lib/display/avatar/avatar.service.mjs +64 -64
  50. package/{esm2020 → esm2022}/lib/display/confirm/confirm.component.mjs +168 -168
  51. package/{esm2020 → esm2022}/lib/display/dialog/dialog-content.mjs +1 -1
  52. package/{esm2020 → esm2022}/lib/display/dialog/dialog-group/dialog-group.component.mjs +63 -63
  53. package/{esm2020 → esm2022}/lib/display/dialog/dialog-types.mjs +76 -76
  54. package/{esm2020 → esm2022}/lib/display/dialog/dialog.component.mjs +281 -281
  55. package/{esm2020 → esm2022}/lib/display/dialog/dialog.service.mjs +71 -71
  56. package/{esm2020 → esm2022}/lib/display/help/help-types.mjs +1 -1
  57. package/{esm2020 → esm2022}/lib/display/hierarchy/hierarchy-base.mjs +111 -111
  58. package/{esm2020 → esm2022}/lib/display/hierarchy/hierarchy-mocks.spec.mjs +53 -53
  59. package/{esm2020 → esm2022}/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.mjs +61 -61
  60. package/{esm2020 → esm2022}/lib/display/item-display/item-display.component.mjs +81 -81
  61. package/{esm2020 → esm2022}/lib/display/json-display/json-display.component.mjs +47 -47
  62. package/{esm2020 → esm2022}/lib/display/resizable/resizable-base.mjs +120 -120
  63. package/{esm2020 → esm2022}/lib/display/resizable/resizable.component.mjs +52 -52
  64. package/{esm2020 → esm2022}/lib/display/spinner/spinner.component.mjs +12 -12
  65. package/{esm2020 → esm2022}/lib/display/splash/splash.component.mjs +42 -42
  66. package/{esm2020 → esm2022}/lib/display/splash/splash.service.mjs +35 -35
  67. package/{esm2020 → esm2022}/lib/display/table/resizable-column.component.mjs +20 -20
  68. package/{esm2020 → esm2022}/lib/display/table/resizable-table.directive.mjs +227 -227
  69. package/{esm2020 → esm2022}/lib/display/table/searchable-table.component.mjs +342 -342
  70. package/{esm2020 → esm2022}/lib/display/table/table-detail-row.component.mjs +19 -19
  71. package/{esm2020 → esm2022}/lib/display/table/table-locked-column.component.mjs +58 -58
  72. package/{esm2020 → esm2022}/lib/display/table/table-master-header-row.component.mjs +14 -14
  73. package/{esm2020 → esm2022}/lib/display/table/table-master-row.component.mjs +163 -163
  74. package/{esm2020 → esm2022}/lib/display/table/table-pagination.component.mjs +155 -155
  75. package/{esm2020 → esm2022}/lib/display/table/table-selectable-row.component.mjs +235 -235
  76. package/{esm2020 → esm2022}/lib/display/table/table.component.mjs +249 -249
  77. package/{esm2020 → esm2022}/lib/display/tags/tag.mjs +17 -17
  78. package/{esm2020 → esm2022}/lib/display/tags/tags.component.mjs +77 -77
  79. package/{esm2020 → esm2022}/lib/display/toast/toast/toast.component.mjs +77 -77
  80. package/{esm2020 → esm2022}/lib/display/toast/toast-types.mjs +7 -7
  81. package/{esm2020 → esm2022}/lib/display/toast/toast.service.mjs +35 -35
  82. package/{esm2020 → esm2022}/lib/display/toast/toaster/toaster.component.mjs +114 -114
  83. package/{esm2020 → esm2022}/lib/display/tooltip/tooltip.component.mjs +28 -28
  84. package/{esm2020 → esm2022}/lib/display/tooltip/tooltip.service.mjs +78 -78
  85. package/{esm2020 → esm2022}/lib/display/tooltip-directive/tooltip.directive.mjs +173 -173
  86. package/{esm2020 → esm2022}/lib/display/tour/tour-types.mjs +33 -33
  87. package/{esm2020 → esm2022}/lib/display/tour/tour.component.mjs +398 -398
  88. package/{esm2020 → esm2022}/lib/display/tour/tour.service.mjs +75 -75
  89. package/{esm2020 → esm2022}/lib/display/tree/tree.component.mjs +135 -135
  90. package/{esm2020 → esm2022}/lib/display/view-overlay/view-overlay.component.mjs +58 -58
  91. package/{esm2020 → esm2022}/lib/shared/directives/click-area-for/click-area-for.directive.mjs +32 -32
  92. package/{esm2020 → esm2022}/lib/shared/directives/if-viewport-width/if-viewport-width.directive.mjs +111 -111
  93. package/esm2022/lib/shared/directives/popup/popup-container.directive.mjs +166 -0
  94. package/{esm2020 → esm2022}/lib/shared/display/pipes/date-display.pipe.mjs +50 -50
  95. package/{esm2020 → esm2022}/lib/shared/display/pipes/highlight-text.pipe.mjs +30 -30
  96. package/{esm2020 → esm2022}/lib/shared/display/pipes/relative-date.pipe.mjs +62 -62
  97. package/{esm2020 → esm2022}/lib/shared/display/pipes/row-count.pipe.mjs +48 -48
  98. package/{esm2020 → esm2022}/lib/shared/display/pipes/time-display.pipe.mjs +41 -41
  99. package/esm2022/lib/shared/display.mjs +6 -0
  100. package/esm2022/lib/shared/form-group.helper.mjs +67 -0
  101. package/{esm2020 → esm2022}/lib/shared/json-helper.mjs +18 -18
  102. package/esm2022/lib/shared/lodash-helper.mjs +52 -0
  103. package/{esm2020 → esm2022}/lib/shared/page/page-base/page-base.component.mjs +387 -387
  104. package/{esm2020 → esm2022}/lib/shared/page/page-statuses.mjs +22 -22
  105. package/{esm2020 → esm2022}/lib/shared/page/page-title/page-title.component.mjs +23 -23
  106. package/{esm2020 → esm2022}/lib/shared/page/page-view/page-view.component.mjs +147 -147
  107. package/{esm2020 → esm2022}/lib/shared/testing/copy-button-base-test-injector-factory.spec.mjs +16 -16
  108. package/{esm2020 → esm2022}/lib/shared/testing/hierarchy-base-test-injector-factory.spec.mjs +16 -16
  109. package/{esm2020 → esm2022}/lib/shared/testing/page-base-component-test-helper.spec.mjs +37 -37
  110. package/esm2022/lib/shared/testing/page-base-component-test-injector-factory.spec.mjs +98 -0
  111. package/{esm2020 → esm2022}/lib/shared/testing/public-mocks.spec.mjs +148 -148
  112. package/{esm2020 → esm2022}/lib/shared/testing/spy-factory.spec.mjs +39 -39
  113. package/{esm2020 → esm2022}/lib/shared/testing/translation-mocks.spec.mjs +56 -56
  114. package/{esm2020 → esm2022}/lib/shared/user-preference.service.mjs +17 -17
  115. package/{esm2020 → esm2022}/lib/shared/wizard/wizard-base/wizard-base.component.mjs +246 -246
  116. package/{esm2020 → esm2022}/lib/shared/wizard/wizard-buttons/wizard-buttons.component.mjs +68 -68
  117. package/{esm2020 → esm2022}/lib/shared/wizard/wizard-progress/wizard-progress.component.mjs +18 -18
  118. package/{esm2020 → esm2022}/public-api.mjs +114 -114
  119. package/{fesm2020 → fesm2022}/energycap-components.mjs +11797 -11793
  120. package/fesm2022/energycap-components.mjs.map +1 -0
  121. package/index.d.ts +5 -5
  122. package/lib/components.module.d.ts +91 -91
  123. package/lib/controls/banner/banner.component.d.ts +50 -50
  124. package/lib/controls/button/button.component.d.ts +78 -78
  125. package/lib/controls/button/copy-button-base.directive.d.ts +20 -20
  126. package/lib/controls/button/copy-button.directive.d.ts +14 -14
  127. package/lib/controls/button/copy-table-button.directive.d.ts +19 -19
  128. package/lib/controls/calendar/calendar-item.component.d.ts +17 -17
  129. package/lib/controls/calendar/calendar.component.d.ts +54 -54
  130. package/lib/controls/calendar/calendar.types.d.ts +7 -7
  131. package/lib/controls/checkbox/checkbox.component.d.ts +65 -65
  132. package/lib/controls/collapsible-toggle/collapsible-toggle.component.d.ts +25 -25
  133. package/lib/controls/combobox/combobox.component.d.ts +418 -418
  134. package/lib/controls/date-input/date-input.component.d.ts +80 -80
  135. package/lib/controls/dropdown/dropdown.component.d.ts +161 -161
  136. package/lib/controls/file-upload/file-upload.component.d.ts +124 -124
  137. package/lib/controls/form-control/form-control.component.d.ts +30 -30
  138. package/lib/controls/form-control-base.d.ts +110 -110
  139. package/lib/controls/form-control-label/form-control-label.component.d.ts +73 -73
  140. package/lib/controls/form-group/form-group.component.d.ts +105 -105
  141. package/lib/controls/help-popover/help-popover.component.d.ts +11 -11
  142. package/lib/controls/item-picker/item-picker.component.d.ts +164 -164
  143. package/lib/controls/link-button/link-button.component.d.ts +5 -5
  144. package/lib/controls/menu/menu.component.d.ts +255 -255
  145. package/lib/controls/navigation/link-item.d.ts +32 -32
  146. package/lib/controls/navigation/nav-group.d.ts +18 -18
  147. package/lib/controls/navigation/nav-item-active.directive.d.ts +42 -42
  148. package/lib/controls/navigation/nav-item.d.ts +31 -31
  149. package/lib/controls/numericbox/numericbox.component.d.ts +148 -148
  150. package/lib/controls/popover/popover.component.d.ts +51 -51
  151. package/lib/controls/radio-button/radio-button-option.d.ts +19 -19
  152. package/lib/controls/radio-button/radio-button.component.d.ts +53 -53
  153. package/lib/controls/select/select.component.d.ts +44 -44
  154. package/lib/controls/tabs/tabs.component.d.ts +30 -30
  155. package/lib/controls/textbox/textbox.component.d.ts +107 -107
  156. package/lib/core/cache.service.d.ts +33 -33
  157. package/lib/core/custom-validators.d.ts +20 -20
  158. package/lib/core/date-time-helper.d.ts +101 -101
  159. package/lib/core/error.service.d.ts +20 -20
  160. package/lib/core/router-helper.service.d.ts +48 -48
  161. package/lib/core/scroll.service.d.ts +36 -36
  162. package/lib/core/telemetry-tracker.service.d.ts +13 -13
  163. package/lib/core/telemetry.service.d.ts +31 -31
  164. package/lib/core/validation-message.service.d.ts +26 -26
  165. package/lib/core/validation-patterns.d.ts +22 -22
  166. package/lib/core/window.service.d.ts +116 -116
  167. package/lib/display/app-bar/app-bar.component.d.ts +20 -20
  168. package/lib/display/avatar/avatar.component.d.ts +35 -35
  169. package/lib/display/avatar/avatar.service.d.ts +24 -24
  170. package/lib/display/confirm/confirm.component.d.ts +123 -123
  171. package/lib/display/dialog/dialog-content.d.ts +19 -19
  172. package/lib/display/dialog/dialog-group/dialog-group.component.d.ts +32 -32
  173. package/lib/display/dialog/dialog-types.d.ts +130 -130
  174. package/lib/display/dialog/dialog.component.d.ts +120 -120
  175. package/lib/display/dialog/dialog.service.d.ts +48 -48
  176. package/lib/display/help/help-types.d.ts +33 -33
  177. package/lib/display/hierarchy/hierarchy-base.d.ts +97 -97
  178. package/lib/display/hierarchy/hierarchy-mocks.spec.d.ts +53 -53
  179. package/lib/display/hierarchy/hierarchy-tree/hierarchy-tree.component.d.ts +34 -34
  180. package/lib/display/item-display/item-display.component.d.ts +43 -43
  181. package/lib/display/json-display/json-display.component.d.ts +16 -16
  182. package/lib/display/resizable/resizable-base.d.ts +67 -67
  183. package/lib/display/resizable/resizable.component.d.ts +31 -31
  184. package/lib/display/spinner/spinner.component.d.ts +5 -5
  185. package/lib/display/splash/splash.component.d.ts +16 -16
  186. package/lib/display/splash/splash.service.d.ts +22 -22
  187. package/lib/display/table/resizable-column.component.d.ts +10 -10
  188. package/lib/display/table/resizable-table.directive.d.ts +93 -93
  189. package/lib/display/table/searchable-table.component.d.ts +206 -206
  190. package/lib/display/table/table-detail-row.component.d.ts +8 -8
  191. package/lib/display/table/table-locked-column.component.d.ts +20 -20
  192. package/lib/display/table/table-master-header-row.component.d.ts +9 -9
  193. package/lib/display/table/table-master-row.component.d.ts +113 -113
  194. package/lib/display/table/table-pagination.component.d.ts +91 -91
  195. package/lib/display/table/table-selectable-row.component.d.ts +102 -102
  196. package/lib/display/table/table.component.d.ts +121 -121
  197. package/lib/display/tags/tag.d.ts +18 -18
  198. package/lib/display/tags/tags.component.d.ts +48 -48
  199. package/lib/display/toast/toast/toast.component.d.ts +23 -23
  200. package/lib/display/toast/toast-types.d.ts +24 -24
  201. package/lib/display/toast/toast.service.d.ts +20 -20
  202. package/lib/display/toast/toaster/toaster.component.d.ts +35 -35
  203. package/lib/display/tooltip/tooltip.component.d.ts +70 -70
  204. package/lib/display/tooltip/tooltip.service.d.ts +16 -16
  205. package/lib/display/tooltip-directive/tooltip.directive.d.ts +44 -44
  206. package/lib/display/tour/tour-types.d.ts +70 -70
  207. package/lib/display/tour/tour.component.d.ts +147 -147
  208. package/lib/display/tour/tour.service.d.ts +38 -38
  209. package/lib/display/tree/tree.component.d.ts +75 -75
  210. package/lib/display/view-overlay/view-overlay.component.d.ts +38 -38
  211. package/lib/shared/directives/click-area-for/click-area-for.directive.d.ts +14 -14
  212. package/lib/shared/directives/if-viewport-width/if-viewport-width.directive.d.ts +60 -60
  213. package/lib/shared/directives/popup/popup-container.directive.d.ts +101 -101
  214. package/lib/shared/display/pipes/date-display.pipe.d.ts +21 -21
  215. package/lib/shared/display/pipes/highlight-text.pipe.d.ts +9 -9
  216. package/lib/shared/display/pipes/relative-date.pipe.d.ts +36 -36
  217. package/lib/shared/display/pipes/row-count.pipe.d.ts +23 -23
  218. package/lib/shared/display/pipes/time-display.pipe.d.ts +18 -18
  219. package/lib/shared/display.d.ts +42 -42
  220. package/lib/shared/form-group.helper.d.ts +31 -31
  221. package/lib/shared/json-helper.d.ts +7 -7
  222. package/lib/shared/lodash-helper.d.ts +18 -18
  223. package/lib/shared/page/page-base/page-base.component.d.ts +259 -259
  224. package/lib/shared/page/page-statuses.d.ts +13 -13
  225. package/lib/shared/page/page-title/page-title.component.d.ts +9 -9
  226. package/lib/shared/page/page-view/page-view.component.d.ts +102 -102
  227. package/lib/shared/testing/copy-button-base-test-injector-factory.spec.d.ts +4 -4
  228. package/lib/shared/testing/hierarchy-base-test-injector-factory.spec.d.ts +4 -4
  229. package/lib/shared/testing/page-base-component-test-helper.spec.d.ts +30 -30
  230. package/lib/shared/testing/page-base-component-test-injector-factory.spec.d.ts +28 -28
  231. package/lib/shared/testing/public-mocks.spec.d.ts +90 -90
  232. package/lib/shared/testing/spy-factory.spec.d.ts +27 -27
  233. package/lib/shared/testing/translation-mocks.spec.d.ts +30 -30
  234. package/lib/shared/user-preference.service.d.ts +13 -13
  235. package/lib/shared/wizard/wizard-base/wizard-base.component.d.ts +134 -134
  236. package/lib/shared/wizard/wizard-buttons/wizard-buttons.component.d.ts +27 -27
  237. package/lib/shared/wizard/wizard-progress/wizard-progress.component.d.ts +10 -10
  238. package/package.json +12 -18
  239. package/public-api.d.ts +111 -111
  240. package/schematics/rxjs-7-upgrade/index.d.ts +3 -3
  241. package/schematics/rxjs-7-upgrade/index.js +67 -67
  242. package/schematics/rxjs-7-upgrade/schema.d.ts +4 -4
  243. package/schematics/rxjs-7-upgrade/schema.js +2 -2
  244. package/schematics/utilities/typescript.d.ts +7 -7
  245. package/schematics/utilities/typescript.js +41 -41
  246. package/schematics/utilities/workspace.d.ts +8 -8
  247. package/schematics/utilities/workspace.js +71 -71
  248. package/esm2020/lib/core/custom-validators.mjs +0 -29
  249. package/esm2020/lib/core/date-time-helper.mjs +0 -220
  250. package/esm2020/lib/display/avatar/avatar.component.mjs +0 -67
  251. package/esm2020/lib/shared/directives/popup/popup-container.directive.mjs +0 -163
  252. package/esm2020/lib/shared/display.mjs +0 -6
  253. package/esm2020/lib/shared/form-group.helper.mjs +0 -67
  254. package/esm2020/lib/shared/lodash-helper.mjs +0 -51
  255. package/esm2020/lib/shared/testing/page-base-component-test-injector-factory.spec.mjs +0 -98
  256. package/fesm2015/energycap-components.mjs +0 -12211
  257. package/fesm2015/energycap-components.mjs.map +0 -1
  258. package/fesm2020/energycap-components.mjs.map +0 -1
@@ -1,256 +1,256 @@
1
- import { Component, HostBinding, Input, ViewChild } from '@angular/core';
2
- import { FormControl } 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 { isCalendarSelectionSingleDate } from '../calendar/calendar.types';
8
- import { FormControlBase } from '../form-control-base';
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 "../../shared/display/pipes/date-display.pipe";
14
- import * as i5 from "@angular/cdk/overlay";
15
- import * as i6 from "@angular/common";
16
- import * as i7 from "@angular/forms";
17
- import * as i8 from "../form-control/form-control.component";
18
- import * as i9 from "../help-popover/help-popover.component";
19
- import * as i10 from "../calendar/calendar.component";
20
- import * as i11 from "@ngx-translate/core";
21
- export class DateInputComponent extends FormControlBase {
22
- constructor(validationMessageService, formGroupHelper, userPreferenceService, dateDisplayPipe, el, overlayService) {
23
- super(validationMessageService, formGroupHelper);
24
- this.validationMessageService = validationMessageService;
25
- this.formGroupHelper = formGroupHelper;
26
- this.userPreferenceService = userPreferenceService;
27
- this.dateDisplayPipe = dateDisplayPipe;
28
- this.el = el;
29
- this.overlayService = overlayService;
30
- this.id = '';
31
- /** The form control provided by the hosting form. */
32
- this.formModel = new FormControl(null);
33
- this.minDate = DateTimeHelper.minDatePickerDate;
34
- this.maxDate = DateTimeHelper.maxDatePickerDate;
35
- /** The internal textbox's form control. */
36
- this.textboxControl = new FormControl(null);
37
- /**
38
- * The current calendar selection.
39
- * Updated when the user clicks on a calendar item or when the date entered into the textbox is parsed.
40
- */
41
- this.calendarSelection = null;
42
- /** Controls whether the calendar overlay is open or not. */
43
- this.isCalendarOpen = false;
44
- /** Placeholder for the textbox. Updated to reflect the user's date display preference. */
45
- this.placeholder = 'MM/DD/YYYY';
46
- /** Overlay scroll strategy for the calendar overlay. Closes the calendar on scroll. */
47
- this.overlayScrollStrategy = this.overlayService.scrollStrategies.close();
48
- /**
49
- * Date parsing formats for user-entered dates. Defaults to month-first formats, but is updated in onInit
50
- * to use the user's preferred date format.
51
- */
52
- this.parseFormats = DateTimeHelper.getParseFormats();
53
- /**
54
- * Validator that checks if the date is within the min and max date range.
55
- * If the date is outside of the range, the validator returns an error that
56
- * triggers the validation message service to show the error in the label.
57
- */
58
- this.dateValidator = (control) => {
59
- if (control.value) {
60
- if (control.value < this.minDate) {
61
- return { minDate: { minValue: this.minDate } };
62
- }
63
- else if (control.value > this.maxDate) {
64
- return { maxDate: { maxValue: this.maxDate } };
65
- }
66
- }
67
- return null;
68
- };
69
- }
70
- /** Focuses the input whenever the calendar is shift-tabbed out of. */
71
- onCalendarFocusOutStart(event) {
72
- event.preventDefault();
73
- this.focusInput();
74
- }
75
- /** Closes the calendar and focuses the input whenever the calendar is tabbed out of. */
76
- onCalendarFocusOutEnd(event) {
77
- event.preventDefault();
78
- this.isCalendarOpen = false;
79
- this.focusInput();
80
- }
81
- /** Close the calendar if the user clicks outside of the calendar and date input. */
82
- onOverlayOutsideClick(event) {
83
- // Do not close the calendar if the click was within the date input or action button
84
- const rect = this.el.nativeElement.getBoundingClientRect();
85
- const clickedOutsideControl = event.clientY < rect.top ||
86
- event.clientY > rect.bottom ||
87
- event.clientX < rect.left ||
88
- event.clientX > rect.right;
89
- // It's possible that the user hit enter on the action button instead of clicking with the mouse.
90
- // In this case the "click" event will be outside of the component because the clientx and y are 0,
91
- // but we don't want to close in this case because button clicks trigger calendar open/close separately.
92
- const isActionClick = event.target.id === `${this.id}_action`;
93
- if (!isActionClick && clickedOutsideControl) {
94
- this.isCalendarOpen = false;
95
- }
96
- }
97
- /** 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 */
98
- onActionKeydown(event) {
99
- if (event.key === 'Tab' && !event.shiftKey && this.isCalendarOpen) {
100
- // Prevent the default tab action so the focus doesn't move to the next element in the tab order after we manually focus the calendar button.
101
- event.preventDefault();
102
- // Focus the first button in the calendar overlay
103
- const firstButton = this.overlay?.overlayRef.hostElement.querySelector('button:not(:disabled)');
104
- firstButton?.focus();
105
- }
106
- }
107
- onTextboxKeydown(event) {
108
- if (event.key === 'Tab' && event.shiftKey) {
109
- // If the user is tabbing backwards from the textbox, close the calendar.
110
- this.isCalendarOpen = false;
111
- }
112
- }
113
- /** Whenever the user selects a date from the calendar, update the formModel with the selection */
114
- onSelectionChange(selection) {
115
- this.calendarSelection = selection;
116
- if (isCalendarSelectionSingleDate(selection)) {
117
- this.formModel.setValue(selection);
118
- this.isCalendarOpen = false;
119
- this.focusInput();
120
- }
121
- }
122
- onTextboxBlur() {
123
- // Parse the textbox value into a date and update the form model
124
- const value = this.textboxControl.value;
125
- if (value) {
126
- const parsedDate = moment(value, this.parseFormats);
127
- if (parsedDate.isValid()) {
128
- this.formModel.setValue(parsedDate.toDate());
129
- }
130
- else {
131
- this.formModel.setValue(null);
132
- }
133
- }
134
- else {
135
- this.formModel.setValue(null);
136
- }
137
- // Update the form model's touched and dirty status based on the textbox's status.
138
- // Since the user interacts with a control that is internal to this component, the
139
- // form model's status won't be updated automatically.
140
- if (this.textboxControl.touched && !this.formModel.touched) {
141
- this.formModel.markAsTouched();
142
- }
143
- if (this.textboxControl.dirty && !this.formModel.dirty) {
144
- this.formModel.markAsDirty();
145
- }
146
- }
147
- ngOnInit() {
148
- // Setup
149
- super.ngOnInit();
150
- this.setDateFormats();
151
- this.formModel.addValidators(this.dateValidator);
152
- // Subscriptions
153
- this.onFormModelStatusChanges();
154
- this.onFormModelValueChanges();
155
- this.onTextboxValueChanges();
156
- // Sync the initial disabled status and value of the textbox
157
- this.syncTextboxControlDisabledStatus(this.formModel.status);
158
- this.textboxControl.setValue(this.dateDisplayPipe.transform(this.formModel.value, true), { emitEvent: false });
159
- this.calendarSelection = this.formModel.value;
160
- }
161
- onFormModelStatusChanges() {
162
- // Keep the textboxControl disabled status in sync with the formModel
163
- this.formModel.statusChanges.pipe(distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(status => {
164
- this.syncTextboxControlDisabledStatus(status);
165
- if (this.isCalendarOpen) {
166
- // As validation messages appear/disappear, the date input may have shifted up or down on the page.
167
- // Update the overlay position to ensure it's still aligned with the textbox and not blocking it.
168
- // Settimeout is needed to ensure the overlay is being updated after the message is rendered.
169
- setTimeout(() => {
170
- this.overlay?.overlayRef?.updatePosition();
171
- });
172
- }
173
- });
174
- }
175
- onFormModelValueChanges() {
176
- // Update the calendar selection textbox value with a formatted date when the form model changes.
177
- // This is usually triggered by programmatic changes to the form model by a parent component.
178
- this.formModel.valueChanges.pipe(distinctUntilChanged((a, b) => moment(a).isSame(b, 'day')), takeUntil(this.componentDestroyed)).subscribe(value => {
179
- const displayValue = this.dateDisplayPipe.transform(value, true);
180
- // Don't emit an event when setting the textbox value to avoid circular updates between the textbox and form model.
181
- this.textboxControl.setValue(displayValue, { emitEvent: false });
182
- this.calendarSelection = value;
183
- });
184
- }
185
- onTextboxValueChanges() {
186
- // Update the calendar selection when the textbox value changes to update the calendar.
187
- // We don't patch the formModel here because we don't want to trigger the
188
- // date formatting logic and overwrite the user's input.
189
- // We'll do that when the user blurs out of the textbox. See onTextboxBlur()
190
- this.textboxControl.valueChanges.pipe(debounceTime(300), distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(value => {
191
- if (value) {
192
- const parsedDate = moment(value, this.parseFormats);
193
- if (parsedDate.isValid()) {
194
- // If the parsed date is before the minDate, set the year to the current year.
195
- // This prevents the calendar from showing unhelpful dates in the distant past as the user types
196
- if (parsedDate.year() < this.minDate.getFullYear()) {
197
- parsedDate.set('year', moment().year());
198
- }
199
- this.calendarSelection = parsedDate.toDate();
200
- }
201
- }
202
- else {
203
- this.calendarSelection = null;
204
- }
205
- });
206
- }
207
- syncTextboxControlDisabledStatus(status) {
208
- // The textbox should only be disabled if the form model is disabled.
209
- // All other statuses are considered enabled.
210
- if (status === 'DISABLED' && this.textboxControl.enabled) {
211
- this.textboxControl.disable();
212
- }
213
- else if (status !== 'DISABLED' && this.textboxControl.disabled) {
214
- this.textboxControl.enable();
215
- }
216
- }
217
- ;
218
- /**
219
- * Updates the date parsing formats and placeholder based on the user's display preference.
220
- * NOTE: This is async because we're retrieving the user's preferences. We're not awaiting the result
221
- * because the only logic that depends on this is the text box date parsing logic and placeholder.
222
- * Our forms should always be behind a pending overlay, so the user won't be able to interact with the
223
- * form until the user is loaded anyway.
224
- */
225
- async setDateFormats() {
226
- const { preference } = await lastValueFrom(this.userPreferenceService.getPreferences());
227
- const dateFormat = preference?.dateFormat;
228
- this.placeholder = dateFormat ?? this.placeholder;
229
- this.parseFormats = DateTimeHelper.getMomentParseFormats(dateFormat);
230
- }
231
- /** Focuses the date input. */
232
- focusInput() {
233
- this.el.nativeElement.querySelector('input')?.focus();
234
- }
235
- }
236
- DateInputComponentfac = 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: i4.DateDisplayPipe }, { token: i0.ElementRef }, { token: i5.Overlay }], target: i0.ɵɵFactoryTarget.Component });
237
- 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" }, host: { properties: { "attr.id": "this.id" } }, viewQueries: [{ propertyName: "overlay", first: true, predicate: ["overlay"], descendants: true }], usesInheritance: 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<ec-form-control id=\"{{id}}\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n [formModel]=\"formModel\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n (actionKeydown)=\"onActionKeydown($event)\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n cdkOverlayOrigin\r\n #overlayOrigin=\"cdkOverlayOrigin\">\r\n <input id=\"{{id}}_input\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxControl\"\r\n (blur)=\"onTextboxBlur()\"\r\n (keydown)=\"onTextboxKeydown($event)\">\r\n</ec-form-control>\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 <ec-calendar [id]=\"id + '_calendar'\"\r\n [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\"\r\n [selection]=\"calendarSelection\"\r\n (selectionChange)=\"onSelectionChange($event)\"\r\n class=\"card px-1 pt-1 pb-2\"\r\n (focusOutStart)=\"onCalendarFocusOutStart($event)\"\r\n (focusOutEnd)=\"onCalendarFocusOutEnd($event)\">\r\n </ec-calendar>\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}\n"], dependencies: [{ 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: i5.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: i5.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: i8.FormControlComponent, selector: "ec-form-control", inputs: ["id", "icon", "actionIcon", "showClear", "formModel", "autofocus", "pending", "required", "readonly"], outputs: ["actionClicked", "actionKeydown"] }, { kind: "component", type: i9.HelpPopoverComponent, selector: "ec-help-popover", inputs: ["id", "text", "contentPosition", "maxWidth"] }, { kind: "component", type: i10.CalendarComponent, selector: "ec-calendar", inputs: ["id", "selection", "minDate", "maxDate"], outputs: ["selectionChange", "focusOutStart", "focusOutEnd"] }, { kind: "pipe", type: i11.TranslatePipe, name: "translate" }] });
238
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "15.2.9", ngImport: i0, type: DateInputComponent, decorators: [{
239
- type: Component,
240
- args: [{ selector: 'ec-date-input', 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<ec-form-control id=\"{{id}}\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n [formModel]=\"formModel\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n (actionKeydown)=\"onActionKeydown($event)\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n cdkOverlayOrigin\r\n #overlayOrigin=\"cdkOverlayOrigin\">\r\n <input id=\"{{id}}_input\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxControl\"\r\n (blur)=\"onTextboxBlur()\"\r\n (keydown)=\"onTextboxKeydown($event)\">\r\n</ec-form-control>\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 <ec-calendar [id]=\"id + '_calendar'\"\r\n [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\"\r\n [selection]=\"calendarSelection\"\r\n (selectionChange)=\"onSelectionChange($event)\"\r\n class=\"card px-1 pt-1 pb-2\"\r\n (focusOutStart)=\"onCalendarFocusOutStart($event)\"\r\n (focusOutEnd)=\"onCalendarFocusOutEnd($event)\">\r\n </ec-calendar>\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}\n"] }]
241
- }], ctorParameters: function () { return [{ type: i1.ValidationMessageService }, { type: i2.FormGroupHelper }, { type: i3.UserPreferenceService }, { type: i4.DateDisplayPipe }, { type: i0.ElementRef }, { type: i5.Overlay }]; }, propDecorators: { id: [{
242
- type: HostBinding,
243
- args: ['attr.id']
244
- }, {
245
- type: Input
246
- }], formModel: [{
247
- type: Input
248
- }], minDate: [{
249
- type: Input
250
- }], maxDate: [{
251
- type: Input
252
- }], overlay: [{
253
- type: ViewChild,
254
- args: ['overlay']
255
- }] } });
256
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1pbnB1dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NyYy9saWIvY29udHJvbHMvZGF0ZS1pbnB1dC9kYXRlLWlucHV0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9kYXRlLWlucHV0L2RhdGUtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFNBQVMsRUFBYyxXQUFXLEVBQUUsS0FBSyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RixPQUFPLEVBQW1CLFdBQVcsRUFBa0MsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5RixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDNUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyQyxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUs3RCxPQUFPLEVBQXFCLDZCQUE2QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDOzs7Ozs7Ozs7Ozs7O0FBU3ZELE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxlQUFlO0lBc0NyRCxZQUNZLHdCQUFrRCxFQUNsRCxlQUFnQyxFQUNsQyxxQkFBNEMsRUFDNUMsZUFBZ0MsRUFDaEMsRUFBYyxFQUNkLGNBQXVCO1FBRS9CLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxlQUFlLENBQUMsQ0FBQztRQVB2Qyw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQ2xELG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUNsQyww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LGNBQWMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUMvQjthQUFNLElBQUksTUFBTSxLQUFLLFVBQVUsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRTtZQUNoRSxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQzlCO0lBQ0gsQ0FBQztJQUFBLENBQUM7SUFFRjs7Ozs7O09BTUc7SUFDSyxLQUFLLENBQUMsY0FBYztRQUMxQixNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsTUFBTSxhQUFhLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7UUFDeEYsTUFBTSxVQUFVLEdBQUcsVUFBVSxFQUFFLFVBQVUsQ0FBQztRQUMxQyxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ2xELElBQUksQ0FBQyxZQUFZLEdBQUcsY0FBYyxDQUFDLHFCQUFxQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFtQkQsOEJBQThCO0lBQ3RCLFVBQVU7UUFDaEIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQ3hELENBQUM7OytHQTlQVSxrQkFBa0I7bUdBQWxCLGtCQUFrQixzVENyQi9CLHd1RUFpREE7MkZENUJhLGtCQUFrQjtrQkFMOUIsU0FBUzsrQkFDRSxlQUFlOzhQQU9ULEVBQUU7c0JBRGpCLFdBQVc7dUJBQUMsU0FBUzs7c0JBQ3JCLEtBQUs7Z0JBR1UsU0FBUztzQkFBeEIsS0FBSztnQkFFVSxPQUFPO3NCQUF0QixLQUFLO2dCQUNVLE9BQU87c0JBQXRCLEtBQUs7Z0JBMkJnQixPQUFPO3NCQUE1QixTQUFTO3VCQUFDLFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZGtDb25uZWN0ZWRPdmVybGF5LCBPdmVybGF5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RCaW5kaW5nLCBJbnB1dCwgT25Jbml0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBGb3JtQ29udHJvbCwgRm9ybUNvbnRyb2xTdGF0dXMsIFZhbGlkYXRvckZuIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XHJcbmltcG9ydCB7IGxhc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBEYXRlVGltZUhlbHBlciB9IGZyb20gJy4uLy4uL2NvcmUvZGF0ZS10aW1lLWhlbHBlcic7XHJcbmltcG9ydCB7IFZhbGlkYXRpb25NZXNzYWdlU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvdmFsaWRhdGlvbi1tZXNzYWdlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBEYXRlRGlzcGxheVBpcGUgfSBmcm9tICcuLi8uLi9zaGFyZWQvZGlzcGxheS9waXBlcy9kYXRlLWRpc3BsYXkucGlwZSc7XHJcbmltcG9ydCB7IEZvcm1Hcm91cEhlbHBlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9mb3JtLWdyb3VwLmhlbHBlcic7XHJcbmltcG9ydCB7IFVzZXJQcmVmZXJlbmNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC91c2VyLXByZWZlcmVuY2Uuc2VydmljZSc7XHJcbmltcG9ydCB7IENhbGVuZGFyU2VsZWN0aW9uLCBpc0NhbGVuZGFyU2VsZWN0aW9uU2luZ2xlRGF0ZSB9IGZyb20gJy4uL2NhbGVuZGFyL2NhbGVuZGFyLnR5cGVzJztcclxuaW1wb3J0IHsgRm9ybUNvbnRyb2xCYXNlIH0gZnJvbSAnLi4vZm9ybS1jb250cm9sLWJhc2UnO1xyXG5cclxuZXhwb3J0IHR5cGUgRGF0ZUlucHV0Rm9ybUNvbnRyb2wgPSBGb3JtQ29udHJvbDxEYXRlIHwgbnVsbD47XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2VjLWRhdGUtaW5wdXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlLWlucHV0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9kYXRlLWlucHV0LmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIERhdGVJbnB1dENvbXBvbmVudCBleHRlbmRzIEZvcm1Db250cm9sQmFzZSBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIEBIb3N0QmluZGluZygnYXR0ci5pZCcpXHJcbiAgQElucHV0KCkgcHVibGljIGlkOiBzdHJpbmcgPSAnJztcclxuXHJcbiAgLyoqIFRoZSBmb3JtIGNvbnRyb2wgcHJvdmlkZWQgYnkgdGhlIGhvc3RpbmcgZm9ybS4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgZm9ybU1vZGVsOiBEYXRlSW5wdXRGb3JtQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbDxEYXRlIHwgbnVsbD4obnVsbCk7XHJcblxyXG4gIEBJbnB1dCgpIHB1YmxpYyBtaW5EYXRlOiBEYXRlID0gRGF0ZVRpbWVIZWxwZXIubWluRGF0ZVBpY2tlckRhdGU7XHJcbiAgQElucHV0KCkgcHVibGljIG1heERhdGU6IERhdGUgPSBEYXRlVGltZUhlbHBlci5tYXhEYXRlUGlja2VyRGF0ZTtcclxuXHJcbiAgLyoqIFRoZSBpbnRlcm5hbCB0ZXh0Ym94J3MgZm9ybSBjb250cm9sLiAqL1xyXG4gIHB1YmxpYyB0ZXh0Ym94Q29udHJvbCA9IG5ldyBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPihudWxsKTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGN1cnJlbnQgY2FsZW5kYXIgc2VsZWN0aW9uLlxyXG4gICAqIFVwZGF0ZWQgd2hlbiB0aGUgdXNlciBjbGlja3Mgb24gYSBjYWxlbmRhciBpdGVtIG9yIHdoZW4gdGhlIGRhdGUgZW50ZXJlZCBpbnRvIHRoZSB0ZXh0Ym94IGlzIHBhcnNlZC5cclxuICAgKi9cclxuICBwdWJsaWMgY2FsZW5kYXJTZWxlY3Rpb246IENhbGVuZGFyU2VsZWN0aW9uIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8qKiBDb250cm9scyB3aGV0aGVyIHRoZSBjYWxlbmRhciBvdmVybGF5IGlzIG9wZW4gb3Igbm90LiAqL1xyXG4gIHB1YmxpYyBpc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG5cclxuICAvKiogUGxhY2Vob2xkZXIgZm9yIHRoZSB0ZXh0Ym94LiBVcGRhdGVkIHRvIHJlZmxlY3QgdGhlIHVzZXIncyBkYXRlIGRpc3BsYXkgcHJlZmVyZW5jZS4gKi9cclxuICBwdWJsaWMgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdNTS9ERC9ZWVlZJztcclxuXHJcbiAgLyoqIE92ZXJsYXkgc2Nyb2xsIHN0cmF0ZWd5IGZvciB0aGUgY2FsZW5kYXIgb3ZlcmxheS4gQ2xvc2VzIHRoZSBjYWxlbmRhciBvbiBzY3JvbGwuICovXHJcbiAgcHVibGljIG92ZXJsYXlTY3JvbGxTdHJhdGVneSA9IHRoaXMub3ZlcmxheVNlcnZpY2Uuc2Nyb2xsU3RyYXRlZ2llcy5jbG9zZSgpO1xyXG5cclxuICAvKiogXHJcbiAgICogRGF0ZSBwYXJzaW5nIGZvcm1hdHMgZm9yIHVzZXItZW50ZXJlZCBkYXRlcy4gRGVmYXVsdHMgdG8gbW9udGgtZmlyc3QgZm9ybWF0cywgYnV0IGlzIHVwZGF0ZWQgaW4gb25Jbml0XHJcbiAgICogdG8gdXNlIHRoZSB1c2VyJ3MgcHJlZmVycmVkIGRhdGUgZm9ybWF0LlxyXG4gICAqL1xyXG4gIHByaXZhdGUgcGFyc2VGb3JtYXRzOiBzdHJpbmdbXSA9IERhdGVUaW1lSGVscGVyLmdldFBhcnNlRm9ybWF0cygpO1xyXG5cclxuICAvKiogUmVmZXJlbmNlIHRvIHRoZSBvdmVybGF5IGRpcmVjdGl2ZSAoc2VlIHRlbXBsYXRlKS4gVXNlZCB0byBhY2Nlc3MgdGhlIG92ZXJsYXkncyBob3N0IGVsZW1lbnQgdG8gY29udHJvbCBmb2N1cy4gKi9cclxuICBAVmlld0NoaWxkKCdvdmVybGF5Jykgb3ZlcmxheT86IENka0Nvbm5lY3RlZE92ZXJsYXk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJvdGVjdGVkIHZhbGlkYXRpb25NZXNzYWdlU2VydmljZTogVmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlLFxyXG4gICAgcHJvdGVjdGVkIGZvcm1Hcm91cEhlbHBlcjogRm9ybUdyb3VwSGVscGVyLFxyXG4gICAgcHJpdmF0ZSB1c2VyUHJlZmVyZW5jZVNlcnZpY2U6IFVzZXJQcmVmZXJlbmNlU2VydmljZSxcclxuICAgIHByaXZhdGUgZGF0ZURpc3BsYXlQaXBlOiBEYXRlRGlzcGxheVBpcGUsXHJcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxyXG4gICAgcHJpdmF0ZSBvdmVybGF5U2VydmljZTogT3ZlcmxheVxyXG4gICkge1xyXG4gICAgc3VwZXIodmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlLCBmb3JtR3JvdXBIZWxwZXIpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEZvY3VzZXMgdGhlIGlucHV0IHdoZW5ldmVyIHRoZSBjYWxlbmRhciBpcyBzaGlmdC10YWJiZWQgb3V0IG9mLiAqL1xyXG4gIHB1YmxpYyBvbkNhbGVuZGFyRm9jdXNPdXRTdGFydChldmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIHRoaXMuZm9jdXNJbnB1dCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqIENsb3NlcyB0aGUgY2FsZW5kYXIgYW5kIGZvY3VzZXMgdGhlIGlucHV0IHdoZW5ldmVyIHRoZSBjYWxlbmRhciBpcyB0YWJiZWQgb3V0IG9mLiAqL1xyXG4gIHB1YmxpYyBvbkNhbGVuZGFyRm9jdXNPdXRFbmQoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB0aGlzLmlzQ2FsZW5kYXJPcGVuID0gZmFsc2U7XHJcbiAgICB0aGlzLmZvY3VzSW5wdXQoKTtcclxuICB9XHJcblxyXG4gIC8qKiBDbG9zZSB0aGUgY2FsZW5kYXIgaWYgdGhlIHVzZXIgY2xpY2tzIG91dHNpZGUgb2YgdGhlIGNhbGVuZGFyIGFuZCBkYXRlIGlucHV0LiAqL1xyXG4gIHB1YmxpYyBvbk92ZXJsYXlPdXRzaWRlQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIC8vIERvIG5vdCBjbG9zZSB0aGUgY2FsZW5kYXIgaWYgdGhlIGNsaWNrIHdhcyB3aXRoaW4gdGhlIGRhdGUgaW5wdXQgb3IgYWN0aW9uIGJ1dHRvblxyXG4gICAgY29uc3QgcmVjdCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGNvbnN0IGNsaWNrZWRPdXRzaWRlQ29udHJvbCA9IGV2ZW50LmNsaWVudFkgPCByZWN0LnRvcCB8fFxyXG4gICAgICBldmVudC5jbGllbnRZID4gcmVjdC5ib3R0b20gfHxcclxuICAgICAgZXZlbnQuY2xpZW50WCA8IHJlY3QubGVmdCB8fFxyXG4gICAgICBldmVudC5jbGllbnRYID4gcmVjdC5yaWdodDtcclxuICAgIC8vIEl0J3MgcG9zc2libGUgdGhhdCB0aGUgdXNlciBoaXQgZW50ZXIgb24gdGhlIGFjdGlvbiBidXR0b24gaW5zdGVhZCBvZiBjbGlja2luZyB3aXRoIHRoZSBtb3VzZS5cclxuICAgIC8vIEluIHRoaXMgY2FzZSB0aGUgXCJjbGlja1wiIGV2ZW50IHdpbGwgYmUgb3V0c2lkZSBvZiB0aGUgY29tcG9uZW50IGJlY2F1c2UgdGhlIGNsaWVudHggYW5kIHkgYXJlIDAsXHJcbiAgICAvLyBidXQgd2UgZG9uJ3Qgd2FudCB0byBjbG9zZSBpbiB0aGlzIGNhc2UgYmVjYXVzZSBidXR0b24gY2xpY2tzIHRyaWdnZXIgY2FsZW5kYXIgb3Blbi9jbG9zZSBzZXBhcmF0ZWx5LlxyXG4gICAgY29uc3QgaXNBY3Rpb25DbGljayA9ICg8SFRNTEVsZW1lbnQ+ZXZlbnQudGFyZ2V0KS5pZCA9PT0gYCR7dGhpcy5pZH1fYWN0aW9uYDtcclxuXHJcbiAgICBpZiAoIWlzQWN0aW9uQ2xpY2sgJiYgY2xpY2tlZE91dHNpZGVDb250cm9sKSB7XHJcbiAgICAgIHRoaXMuaXNDYWxlbmRhck9wZW4gPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBJZiB0aGUgdXNlciB0YWJzIG91dCBvZiB0aGUgZm9ybSBjb250cm9sJ3MgYWN0aW9uIGJ1dHRvbiBhbmQgdGhlIGNhbGVuZGFyIGlzIG9wZW4sIGZvY3VzIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBjYWxlbmRhciBvdmVybGF5ICovXHJcbiAgcHVibGljIG9uQWN0aW9uS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ1RhYicgJiYgIWV2ZW50LnNoaWZ0S2V5ICYmIHRoaXMuaXNDYWxlbmRhck9wZW4pIHtcclxuICAgICAgLy8gUHJldmVudCB0aGUgZGVmYXVsdCB0YWIgYWN0aW9uIHNvIHRoZSBmb2N1cyBkb2Vzbid0IG1vdmUgdG8gdGhlIG5leHQgZWxlbWVudCBpbiB0aGUgdGFiIG9yZGVyIGFmdGVyIHdlIG1hbnVhbGx5IGZvY3VzIHRoZSBjYWxlbmRhciBidXR0b24uXHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIC8vIEZvY3VzIHRoZSBmaXJzdCBidXR0b24gaW4gdGhlIGNhbGVuZGFyIG92ZXJsYXlcclxuICAgICAgY29uc3QgZmlyc3RCdXR0b246IEhUTUxCdXR0b25FbGVtZW50IHwgbnVsbCB8IHVuZGVmaW5lZCA9IHRoaXMub3ZlcmxheT8ub3ZlcmxheVJlZi5ob3N0RWxlbWVudC5xdWVyeVNlbGVjdG9yKCdidXR0b246bm90KDpkaXNhYmxlZCknKTtcclxuICAgICAgZmlyc3RCdXR0b24/LmZvY3VzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25UZXh0Ym94S2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ1RhYicgJiYgZXZlbnQuc2hpZnRLZXkpIHtcclxuICAgICAgLy8gSWYgdGhlIHVzZXIgaXMgdGFiYmluZyBiYWNrd2FyZHMgZnJvbSB0aGUgdGV4dGJveCwgY2xvc2UgdGhlIGNhbGVuZGFyLlxyXG4gICAgICB0aGlzLmlzQ2FsZW5kYXJPcGVuID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogV2hlbmV2ZXIgdGhlIHVzZXIgc2VsZWN0cyBhIGRhdGUgZnJvbSB0aGUgY2FsZW5kYXIsIHVwZGF0ZSB0aGUgZm9ybU1vZGVsIHdpdGggdGhlIHNlbGVjdGlvbiAqL1xyXG4gIHB1YmxpYyBvblNlbGVjdGlvbkNoYW5nZShzZWxlY3Rpb246IENhbGVuZGFyU2VsZWN0aW9uIHwgbnVsbCkge1xyXG4gICAgdGhpcy5jYWxlbmRhclNlbGVjdGlvbiA9IHNlbGVjdGlvbjtcclxuICAgIGlmIChpc0NhbGVuZGFyU2VsZWN0aW9uU2luZ2xlRGF0ZShzZWxlY3Rpb24pKSB7XHJcbiAgICAgIHRoaXMuZm9ybU1vZGVsLnNldFZhbHVlKHNlbGVjdGlvbik7XHJcbiAgICAgIHRoaXMuaXNDYWxlbmRhck9wZW4gPSBmYWxzZTtcclxuICAgICAgdGhpcy5mb2N1c0lucHV0KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25UZXh0Ym94Qmx1cigpIHtcclxuICAgIC8vIFBhcnNlIHRoZSB0ZXh0Ym94IHZhbHVlIGludG8gYSBkYXRlIGFuZCB1cGRhdGUgdGhlIGZvcm0gbW9kZWxcclxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy50ZXh0Ym94Q29udHJvbC52YWx1ZTtcclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICBjb25zdCBwYXJzZWREYXRlID0gbW9tZW50KHZhbHVlLCB0aGlzLnBhcnNlRm9ybWF0cyk7XHJcbiAgICAgIGlmIChwYXJzZWREYXRlLmlzVmFsaWQoKSkge1xyXG4gICAgICAgIHRoaXMuZm9ybU1vZGVsLnNldFZhbHVlKHBhcnNlZERhdGUudG9EYXRlKCkpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZm9ybU1vZGVsLnNldFZhbHVlKG51bGwpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmZvcm1Nb2RlbC5zZXRWYWx1ZShudWxsKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBVcGRhdGUgdGhlIGZvcm0gbW9kZWwncyB0b3VjaGVkIGFuZCBkaXJ0eSBzdGF0dXMgYmFzZWQgb24gdGhlIHRleHRib3gncyBzdGF0dXMuXHJcbiAgICAvLyBTaW5jZSB0aGUgdXNlciBpbnRlcmFjdHMgd2l0aCBhIGNvbnRyb2wgdGhhdCBpcyBpbnRlcm5hbCB0byB0aGlzIGNvbXBvbmVudCwgdGhlXHJcbiAgICAvLyBmb3JtIG1vZGVsJ3Mgc3RhdHVzIHdvbid0IGJlIHVwZGF0ZWQgYXV0b21hdGljYWxseS5cclxuICAgIGlmICh0aGlzLnRleHRib3hDb250cm9sLnRvdWNoZWQgJiYgIXRoaXMuZm9ybU1vZGVsLnRvdWNoZWQpIHtcclxuICAgICAgdGhpcy5mb3JtTW9kZWwubWFya0FzVG91Y2hlZCgpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMudGV4dGJveENvbnRyb2wuZGlydHkgJiYgIXRoaXMuZm9ybU1vZGVsLmRpcnR5KSB7XHJcbiAgICAgIHRoaXMuZm9ybU1vZGVsLm1hcmtBc0RpcnR5KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIC8vIFNldHVwXHJcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xyXG4gICAgdGhpcy5zZXREYXRlRm9ybWF0cygpO1xyXG5cclxuICAgIHRoaXMuZm9ybU1vZGVsLmFkZFZhbGlkYXRvcnModGhpcy5kYXRlVmFsaWRhdG9yKTtcclxuXHJcbiAgICAvLyBTdWJzY3JpcHRpb25zXHJcbiAgICB0aGlzLm9uRm9ybU1vZGVsU3RhdHVzQ2hhbmdlcygpO1xyXG4gICAgdGhpcy5vbkZvcm1Nb2RlbFZhbHVlQ2hhbmdlcygpO1xyXG4gICAgdGhpcy5vblRleHRib3hWYWx1ZUNoYW5nZXMoKTtcclxuXHJcbiAgICAvLyBTeW5jIHRoZSBpbml0aWFsIGRpc2FibGVkIHN0YXR1cyBhbmQgdmFsdWUgb2YgdGhlIHRleHRib3hcclxuICAgIHRoaXMuc3luY1RleHRib3hDb250cm9sRGlzYWJsZWRTdGF0dXModGhpcy5mb3JtTW9kZWwuc3RhdHVzKTtcclxuICAgIHRoaXMudGV4dGJveENvbnRyb2wuc2V0VmFsdWUodGhpcy5kYXRlRGlzcGxheVBpcGUudHJhbnNmb3JtKHRoaXMuZm9ybU1vZGVsLnZhbHVlLCB0cnVlKSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgdGhpcy5jYWxlbmRhclNlbGVjdGlvbiA9IHRoaXMuZm9ybU1vZGVsLnZhbHVlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvbkZvcm1Nb2RlbFN0YXR1c0NoYW5nZXMoKSB7XHJcbiAgICAvLyBLZWVwIHRoZSB0ZXh0Ym94Q29udHJvbCBkaXNhYmxlZCBzdGF0dXMgaW4gc3luYyB3aXRoIHRoZSBmb3JtTW9kZWxcclxuICAgIHRoaXMuZm9ybU1vZGVsLnN0YXR1c0NoYW5nZXMucGlwZShcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgdGFrZVVudGlsKHRoaXMuY29tcG9uZW50RGVzdHJveWVkKVxyXG4gICAgKS5zdWJzY3JpYmUoc3RhdHVzID0+IHtcclxuICAgICAgdGhpcy5zeW5jVGV4dGJveENvbnRyb2xEaXNhYmxlZFN0YXR1cyhzdGF0dXMpO1xyXG5cclxuICAgICAgaWYgKHRoaXMuaXNDYWxlbmRhck9wZW4pIHtcclxuICAgICAgICAvLyBBcyB2YWxpZGF0aW9uIG1lc3NhZ2VzIGFwcGVhci9kaXNhcHBlYXIsIHRoZSBkYXRlIGlucHV0IG1heSBoYXZlIHNoaWZ0ZWQgdXAgb3IgZG93biBvbiB0aGUgcGFnZS5cclxuICAgICAgICAvLyBVcGRhdGUgdGhlIG92ZXJsYXkgcG9zaXRpb24gdG8gZW5zdXJlIGl0J3Mgc3RpbGwgYWxpZ25lZCB3aXRoIHRoZSB0ZXh0Ym94IGFuZCBub3QgYmxvY2tpbmcgaXQuXHJcbiAgICAgICAgLy8gU2V0dGltZW91dCBpcyBuZWVkZWQgdG8gZW5zdXJlIHRoZSBvdmVybGF5IGlzIGJlaW5nIHVwZGF0ZWQgYWZ0ZXIgdGhlIG1lc3NhZ2UgaXMgcmVuZGVyZWQuXHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLm92ZXJsYXk/Lm92ZXJsYXlSZWY/LnVwZGF0ZVBvc2l0aW9uKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvbkZvcm1Nb2RlbFZhbHVlQ2hhbmdlcygpIHtcclxuICAgIC8vIFVwZGF0ZSB0aGUgY2FsZW5kYXIgc2VsZWN0aW9uIHRleHRib3ggdmFsdWUgd2l0aCBhIGZvcm1hdHRlZCBkYXRlIHdoZW4gdGhlIGZvcm0gbW9kZWwgY2hhbmdlcy5cclxuICAgIC8vIFRoaXMgaXMgdXN1YWxseSB0cmlnZ2VyZWQgYnkgcHJvZ3JhbW1hdGljIGNoYW5nZXMgdG8gdGhlIGZvcm0gbW9kZWwgYnkgYSBwYXJlbnQgY29tcG9uZW50LlxyXG4gICAgdGhpcy5mb3JtTW9kZWwudmFsdWVDaGFuZ2VzLnBpcGUoXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKChhLCBiKSA9PiBtb21lbnQoYSkuaXNTYW1lKGIsICdkYXknKSksXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLmNvbXBvbmVudERlc3Ryb3llZClcclxuICAgICkuc3Vic2NyaWJlKHZhbHVlID0+IHtcclxuICAgICAgY29uc3QgZGlzcGxheVZhbHVlID0gdGhpcy5kYXRlRGlzcGxheVBpcGUudHJhbnNmb3JtKHZhbHVlLCB0cnVlKTtcclxuICAgICAgLy8gRG9uJ3QgZW1pdCBhbiBldmVudCB3aGVuIHNldHRpbmcgdGhlIHRleHRib3ggdmFsdWUgdG8gYXZvaWQgY2lyY3VsYXIgdXBkYXRlcyBiZXR3ZWVuIHRoZSB0ZXh0Ym94IGFuZCBmb3JtIG1vZGVsLlxyXG4gICAgICB0aGlzLnRleHRib3hDb250cm9sLnNldFZhbHVlKGRpc3BsYXlWYWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgICB0aGlzLmNhbGVuZGFyU2VsZWN0aW9uID0gdmFsdWU7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgb25UZXh0Ym94VmFsdWVDaGFuZ2VzKCkge1xyXG4gICAgLy8gVXBkYXRlIHRoZSBjYWxlbmRhciBzZWxlY3Rpb24gd2hlbiB0aGUgdGV4dGJveCB2YWx1ZSBjaGFuZ2VzIHRvIHVwZGF0ZSB0aGUgY2FsZW5kYXIuXHJcbiAgICAvLyBXZSBkb24ndCBwYXRjaCB0aGUgZm9ybU1vZGVsIGhlcmUgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIHRyaWdnZXIgdGhlXHJcbiAgICAvLyBkYXRlIGZvcm1hdHRpbmcgbG9naWMgYW5kIG92ZXJ3cml0ZSB0aGUgdXNlcidzIGlucHV0LlxyXG4gICAgLy8gV2UnbGwgZG8gdGhhdCB3aGVuIHRoZSB1c2VyIGJsdXJzIG91dCBvZiB0aGUgdGV4dGJveC4gU2VlIG9uVGV4dGJveEJsdXIoKVxyXG4gICAgdGhpcy50ZXh0Ym94Q29udHJvbC52YWx1ZUNoYW5nZXMucGlwZShcclxuICAgICAgZGVib3VuY2VUaW1lKDMwMCksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLmNvbXBvbmVudERlc3Ryb3llZClcclxuICAgICkuc3Vic2NyaWJlKHZhbHVlID0+IHtcclxuICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgY29uc3QgcGFyc2VkRGF0ZSA9IG1vbWVudCh2YWx1ZSwgdGhpcy5wYXJzZUZvcm1hdHMpO1xyXG4gICAgICAgIGlmIChwYXJzZWREYXRlLmlzVmFsaWQoKSkge1xyXG4gICAgICAgICAgLy8gSWYgdGhlIHBhcnNlZCBkYXRlIGlzIGJlZm9yZSB0aGUgbWluRGF0ZSwgc2V0IHRoZSB5ZWFyIHRvIHRoZSBjdXJyZW50IHllYXIuXHJcbiAgICAgICAgICAvLyBUaGlzIHByZXZlbnRzIHRoZSBjYWxlbmRhciBmcm9tIHNob3dpbmcgdW5oZWxwZnVsIGRhdGVzIGluIHRoZSBkaXN0YW50IHBhc3QgYXMgdGhlIHVzZXIgdHlwZXNcclxuICAgICAgICAgIGlmIChwYXJzZWREYXRlLnllYXIoKSA8IHRoaXMubWluRGF0ZS5nZXRGdWxsWWVhcigpKSB7XHJcbiAgICAgICAgICAgIHBhcnNlZERhdGUuc2V0KCd5ZWFyJywgbW9tZW50KCkueWVhcigpKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24gPSBwYXJzZWREYXRlLnRvRGF0ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmNhbGVuZGFyU2VsZWN0aW9uID0gbnVsbDtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN5bmNUZXh0Ym94Q29udHJvbERpc2FibGVkU3RhdHVzKHN0YXR1czogRm9ybUNvbnRyb2xTdGF0dXMpIHtcclxuICAgIC8vIFRoZSB0ZXh0Ym94IHNob3VsZCBvbmx5IGJlIGRpc2FibGVkIGlmIHRoZSBmb3JtIG1vZGVsIGlzIGRpc2FibGVkLlxyXG4gICAgLy8gQWxsIG90aGVyIHN0YXR1c2VzIGFyZSBjb25zaWRlcmVkIGVuYWJsZWQuXHJcbiAgICBpZiAoc3RhdHVzID09PSAnRElTQUJMRUQnICYmIHRoaXMudGV4dGJveENvbnRyb2wuZW5hYmxlZCkge1xyXG4gICAgICB0aGlzLnRleHRib3hDb250cm9sLmRpc2FibGUoKTtcclxuICAgIH0gZWxzZSBpZiAoc3RhdHVzICE9PSAnRElTQUJMRUQnICYmIHRoaXMudGV4dGJveENvbnRyb2wuZGlzYWJsZWQpIHtcclxuICAgICAgdGhpcy50ZXh0Ym94Q29udHJvbC5lbmFibGUoKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICAvKiogXHJcbiAgICogVXBkYXRlcyB0aGUgZGF0ZSBwYXJzaW5nIGZvcm1hdHMgYW5kIHBsYWNlaG9sZGVyIGJhc2VkIG9uIHRoZSB1c2VyJ3MgZGlzcGxheSBwcmVmZXJlbmNlLlxyXG4gICAqIE5PVEU6IFRoaXMgaXMgYXN5bmMgYmVjYXVzZSB3ZSdyZSByZXRyaWV2aW5nIHRoZSB1c2VyJ3MgcHJlZmVyZW5jZXMuIFdlJ3JlIG5vdCBhd2FpdGluZyB0aGUgcmVzdWx0XHJcbiAgICogYmVjYXVzZSB0aGUgb25seSBsb2dpYyB0aGF0IGRlcGVuZHMgb24gdGhpcyBpcyB0aGUgdGV4dCBib3ggZGF0ZSBwYXJzaW5nIGxvZ2ljIGFuZCBwbGFjZWhvbGRlci5cclxuICAgKiBPdXIgZm9ybXMgc2hvdWxkIGFsd2F5cyBiZSBiZWhpbmQgYSBwZW5kaW5nIG92ZXJsYXksIHNvIHRoZSB1c2VyIHdvbid0IGJlIGFibGUgdG8gaW50ZXJhY3Qgd2l0aCB0aGVcclxuICAgKiBmb3JtIHVudGlsIHRoZSB1c2VyIGlzIGxvYWRlZCBhbnl3YXkuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhc3luYyBzZXREYXRlRm9ybWF0cygpIHtcclxuICAgIGNvbnN0IHsgcHJlZmVyZW5jZSB9ID0gYXdhaXQgbGFzdFZhbHVlRnJvbSh0aGlzLnVzZXJQcmVmZXJlbmNlU2VydmljZS5nZXRQcmVmZXJlbmNlcygpKTtcclxuICAgIGNvbnN0IGRhdGVGb3JtYXQgPSBwcmVmZXJlbmNlPy5kYXRlRm9ybWF0O1xyXG4gICAgdGhpcy5wbGFjZWhvbGRlciA9IGRhdGVGb3JtYXQgPz8gdGhpcy5wbGFjZWhvbGRlcjtcclxuICAgIHRoaXMucGFyc2VGb3JtYXRzID0gRGF0ZVRpbWVIZWxwZXIuZ2V0TW9tZW50UGFyc2VGb3JtYXRzKGRhdGVGb3JtYXQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVmFsaWRhdG9yIHRoYXQgY2hlY2tzIGlmIHRoZSBkYXRlIGlzIHdpdGhpbiB0aGUgbWluIGFuZCBtYXggZGF0ZSByYW5nZS5cclxuICAgKiBJZiB0aGUgZGF0ZSBpcyBvdXRzaWRlIG9mIHRoZSByYW5nZSwgdGhlIHZhbGlkYXRvciByZXR1cm5zIGFuIGVycm9yIHRoYXRcclxuICAgKiB0cmlnZ2VycyB0aGUgdmFsaWRhdGlvbiBtZXNzYWdlIHNlcnZpY2UgdG8gc2hvdyB0aGUgZXJyb3IgaW4gdGhlIGxhYmVsLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgZGF0ZVZhbGlkYXRvcjogVmFsaWRhdG9yRm4gPSAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiB7XHJcbiAgICBpZiAoY29udHJvbC52YWx1ZSkge1xyXG4gICAgICBpZiAoY29udHJvbC52YWx1ZSA8IHRoaXMubWluRGF0ZSkge1xyXG4gICAgICAgIHJldHVybiB7IG1pbkRhdGU6IHsgbWluVmFsdWU6IHRoaXMubWluRGF0ZSB9IH07XHJcbiAgICAgIH0gZWxzZSBpZiAoY29udHJvbC52YWx1ZSA+IHRoaXMubWF4RGF0ZSkge1xyXG4gICAgICAgIHJldHVybiB7IG1heERhdGU6IHsgbWF4VmFsdWU6IHRoaXMubWF4RGF0ZSB9IH07XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9O1xyXG5cclxuICAvKiogRm9jdXNlcyB0aGUgZGF0ZSBpbnB1dC4gKi9cclxuICBwcml2YXRlIGZvY3VzSW5wdXQoKSB7XHJcbiAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXQnKT8uZm9jdXMoKTtcclxuICB9XHJcbn1cclxuIiwiPGxhYmVsICpuZ0lmPVwibGFiZWxcIj5cclxuICA8c3Bhbj57e2xhYmVsIHwgdHJhbnNsYXRlfX08L3NwYW4+XHJcbiAgPHNwYW4gKm5nSWY9XCJ2YWxpZGF0aW9uRXJyb3JzLmxlbmd0aCA+IDAgJiYgZm9ybU1vZGVsLnRvdWNoZWQgJiYgZm9ybU1vZGVsLmludmFsaWRcIj4mbmJzcDt7e3ZhbGlkYXRpb25FcnJvcnN9fTwvc3Bhbj5cclxuICA8ZWMtaGVscC1wb3BvdmVyIGlkPVwie3tpZH19X2hlbHBQb3BvdmVyXCJcclxuICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaGVscFBvcG92ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkLWlubGluZS1ibG9jayBteS1uMyBteC1uMVwiXHJcbiAgICAgICAgICAgICAgICAgICB0ZXh0PVwie3toZWxwUG9wb3ZlciB8IHRyYW5zbGF0ZX19XCJcclxuICAgICAgICAgICAgICAgICAgIGNvbnRlbnRQb3NpdGlvbj1cInt7aGVscFBvcG92ZXJQb3NpdGlvbn19XCI+XHJcbiAgPC9lYy1oZWxwLXBvcG92ZXI+XHJcbjwvbGFiZWw+XHJcblxyXG48ZWMtZm9ybS1jb250cm9sIGlkPVwie3tpZH19XCJcclxuICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgIFthdXRvZm9jdXNdPVwiYXV0b2ZvY3VzXCJcclxuICAgICAgICAgICAgICAgICBbcGVuZGluZ109XCJwZW5kaW5nXCJcclxuICAgICAgICAgICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgIFtmb3JtTW9kZWxdPVwiZm9ybU1vZGVsXCJcclxuICAgICAgICAgICAgICAgICAoYWN0aW9uQ2xpY2tlZCk9XCJpc0NhbGVuZGFyT3BlbiA9ICFpc0NhbGVuZGFyT3BlblwiXHJcbiAgICAgICAgICAgICAgICAgKGFjdGlvbktleWRvd24pPVwib25BY3Rpb25LZXlkb3duKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgIGFjdGlvbkljb249XCJpY29uLWRhdGVcIlxyXG4gICAgICAgICAgICAgICAgIGNka092ZXJsYXlPcmlnaW5cclxuICAgICAgICAgICAgICAgICAjb3ZlcmxheU9yaWdpbj1cImNka092ZXJsYXlPcmlnaW5cIj5cclxuICA8aW5wdXQgaWQ9XCJ7e2lkfX1faW5wdXRcIlxyXG4gICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgIHBsYWNlaG9sZGVyPVwie3twbGFjZWhvbGRlcn19XCJcclxuICAgICAgICAgW2Zvcm1Db250cm9sXT1cInRleHRib3hDb250cm9sXCJcclxuICAgICAgICAgKGJsdXIpPVwib25UZXh0Ym94Qmx1cigpXCJcclxuICAgICAgICAgKGtleWRvd24pPVwib25UZXh0Ym94S2V5ZG93bigkZXZlbnQpXCI+XHJcbjwvZWMtZm9ybS1jb250cm9sPlxyXG5cclxuPG5nLXRlbXBsYXRlIGNka0Nvbm5lY3RlZE92ZXJsYXlcclxuICAgICAgICAgICAgICNvdmVybGF5PVwiY2RrQ29ubmVjdGVkT3ZlcmxheVwiXHJcbiAgICAgICAgICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbl09XCJvdmVybGF5T3JpZ2luXCJcclxuICAgICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5T3Blbl09XCJpc0NhbGVuZGFyT3BlblwiXHJcbiAgICAgICAgICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheVNjcm9sbFN0cmF0ZWd5XT1cIm92ZXJsYXlTY3JvbGxTdHJhdGVneVwiXHJcbiAgICAgICAgICAgICBjZGtDb25uZWN0ZWRPdmVybGF5UGFuZWxDbGFzcz1cIm15LTFcIlxyXG4gICAgICAgICAgICAgKG92ZXJsYXlPdXRzaWRlQ2xpY2spPVwib25PdmVybGF5T3V0c2lkZUNsaWNrKCRldmVudClcIlxyXG4gICAgICAgICAgICAgKGRldGFjaCk9XCJpc0NhbGVuZGFyT3BlbiA9IGZhbHNlXCI+XHJcbiAgPGVjLWNhbGVuZGFyIFtpZF09XCJpZCArICdfY2FsZW5kYXInXCJcclxuICAgICAgICAgICAgICAgW21pbkRhdGVdPVwibWluRGF0ZVwiXHJcbiAgICAgICAgICAgICAgIFttYXhEYXRlXT1cIm1heERhdGVcIlxyXG4gICAgICAgICAgICAgICBbc2VsZWN0aW9uXT1cImNhbGVuZGFyU2VsZWN0aW9uXCJcclxuICAgICAgICAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCJvblNlbGVjdGlvbkNoYW5nZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgY2xhc3M9XCJjYXJkIHB4LTEgcHQtMSBwYi0yXCJcclxuICAgICAgICAgICAgICAgKGZvY3VzT3V0U3RhcnQpPVwib25DYWxlbmRhckZvY3VzT3V0U3RhcnQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgIChmb2N1c091dEVuZCk9XCJvbkNhbGVuZGFyRm9jdXNPdXRFbmQoJGV2ZW50KVwiPlxyXG4gIDwvZWMtY2FsZW5kYXI+XHJcbjwvbmctdGVtcGxhdGU+XHJcbiJdfQ==
1
+ import { Component, HostBinding, Input, ViewChild } from '@angular/core';
2
+ import { FormControl } 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 { isCalendarSelectionSingleDate } from '../calendar/calendar.types';
8
+ import { FormControlBase } from '../form-control-base';
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 "../../shared/display/pipes/date-display.pipe";
14
+ import * as i5 from "@angular/cdk/overlay";
15
+ import * as i6 from "@angular/common";
16
+ import * as i7 from "@angular/forms";
17
+ import * as i8 from "../form-control/form-control.component";
18
+ import * as i9 from "../help-popover/help-popover.component";
19
+ import * as i10 from "../calendar/calendar.component";
20
+ import * as i11 from "@ngx-translate/core";
21
+ export class DateInputComponent extends FormControlBase {
22
+ constructor(validationMessageService, formGroupHelper, userPreferenceService, dateDisplayPipe, el, overlayService) {
23
+ super(validationMessageService, formGroupHelper);
24
+ this.validationMessageService = validationMessageService;
25
+ this.formGroupHelper = formGroupHelper;
26
+ this.userPreferenceService = userPreferenceService;
27
+ this.dateDisplayPipe = dateDisplayPipe;
28
+ this.el = el;
29
+ this.overlayService = overlayService;
30
+ this.id = '';
31
+ /** The form control provided by the hosting form. */
32
+ this.formModel = new FormControl(null);
33
+ this.minDate = DateTimeHelper.minDatePickerDate;
34
+ this.maxDate = DateTimeHelper.maxDatePickerDate;
35
+ /** The internal textbox's form control. */
36
+ this.textboxControl = new FormControl(null);
37
+ /**
38
+ * The current calendar selection.
39
+ * Updated when the user clicks on a calendar item or when the date entered into the textbox is parsed.
40
+ */
41
+ this.calendarSelection = null;
42
+ /** Controls whether the calendar overlay is open or not. */
43
+ this.isCalendarOpen = false;
44
+ /** Placeholder for the textbox. Updated to reflect the user's date display preference. */
45
+ this.placeholder = 'MM/DD/YYYY';
46
+ /** Overlay scroll strategy for the calendar overlay. Closes the calendar on scroll. */
47
+ this.overlayScrollStrategy = this.overlayService.scrollStrategies.close();
48
+ /**
49
+ * Date parsing formats for user-entered dates. Defaults to month-first formats, but is updated in onInit
50
+ * to use the user's preferred date format.
51
+ */
52
+ this.parseFormats = DateTimeHelper.getParseFormats();
53
+ /**
54
+ * Validator that checks if the date is within the min and max date range.
55
+ * If the date is outside of the range, the validator returns an error that
56
+ * triggers the validation message service to show the error in the label.
57
+ */
58
+ this.dateValidator = (control) => {
59
+ if (control.value) {
60
+ if (control.value < this.minDate) {
61
+ return { minDate: { minValue: this.minDate } };
62
+ }
63
+ else if (control.value > this.maxDate) {
64
+ return { maxDate: { maxValue: this.maxDate } };
65
+ }
66
+ }
67
+ return null;
68
+ };
69
+ }
70
+ /** Focuses the input whenever the calendar is shift-tabbed out of. */
71
+ onCalendarFocusOutStart(event) {
72
+ event.preventDefault();
73
+ this.focusInput();
74
+ }
75
+ /** Closes the calendar and focuses the input whenever the calendar is tabbed out of. */
76
+ onCalendarFocusOutEnd(event) {
77
+ event.preventDefault();
78
+ this.isCalendarOpen = false;
79
+ this.focusInput();
80
+ }
81
+ /** Close the calendar if the user clicks outside of the calendar and date input. */
82
+ onOverlayOutsideClick(event) {
83
+ // Do not close the calendar if the click was within the date input or action button
84
+ const rect = this.el.nativeElement.getBoundingClientRect();
85
+ const clickedOutsideControl = event.clientY < rect.top ||
86
+ event.clientY > rect.bottom ||
87
+ event.clientX < rect.left ||
88
+ event.clientX > rect.right;
89
+ // It's possible that the user hit enter on the action button instead of clicking with the mouse.
90
+ // In this case the "click" event will be outside of the component because the clientx and y are 0,
91
+ // but we don't want to close in this case because button clicks trigger calendar open/close separately.
92
+ const isActionClick = event.target.id === `${this.id}_action`;
93
+ if (!isActionClick && clickedOutsideControl) {
94
+ this.isCalendarOpen = false;
95
+ }
96
+ }
97
+ /** 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 */
98
+ onActionKeydown(event) {
99
+ if (event.key === 'Tab' && !event.shiftKey && this.isCalendarOpen) {
100
+ // Prevent the default tab action so the focus doesn't move to the next element in the tab order after we manually focus the calendar button.
101
+ event.preventDefault();
102
+ // Focus the first button in the calendar overlay
103
+ const firstButton = this.overlay?.overlayRef.hostElement.querySelector('button:not(:disabled)');
104
+ firstButton?.focus();
105
+ }
106
+ }
107
+ onTextboxKeydown(event) {
108
+ if (event.key === 'Tab' && event.shiftKey) {
109
+ // If the user is tabbing backwards from the textbox, close the calendar.
110
+ this.isCalendarOpen = false;
111
+ }
112
+ }
113
+ /** Whenever the user selects a date from the calendar, update the formModel with the selection */
114
+ onSelectionChange(selection) {
115
+ this.calendarSelection = selection;
116
+ if (isCalendarSelectionSingleDate(selection)) {
117
+ this.formModel.setValue(selection);
118
+ this.isCalendarOpen = false;
119
+ this.focusInput();
120
+ }
121
+ }
122
+ onTextboxBlur() {
123
+ // Parse the textbox value into a date and update the form model
124
+ const value = this.textboxControl.value;
125
+ if (value) {
126
+ const parsedDate = moment(value, this.parseFormats);
127
+ if (parsedDate.isValid()) {
128
+ this.formModel.setValue(parsedDate.toDate());
129
+ }
130
+ else {
131
+ this.formModel.setValue(null);
132
+ }
133
+ }
134
+ else {
135
+ this.formModel.setValue(null);
136
+ }
137
+ // Update the form model's touched and dirty status based on the textbox's status.
138
+ // Since the user interacts with a control that is internal to this component, the
139
+ // form model's status won't be updated automatically.
140
+ if (this.textboxControl.touched && !this.formModel.touched) {
141
+ this.formModel.markAsTouched();
142
+ }
143
+ if (this.textboxControl.dirty && !this.formModel.dirty) {
144
+ this.formModel.markAsDirty();
145
+ }
146
+ }
147
+ ngOnInit() {
148
+ // Setup
149
+ super.ngOnInit();
150
+ this.setDateFormats();
151
+ this.formModel.addValidators(this.dateValidator);
152
+ // Subscriptions
153
+ this.onFormModelStatusChanges();
154
+ this.onFormModelValueChanges();
155
+ this.onTextboxValueChanges();
156
+ // Sync the initial disabled status and value of the textbox
157
+ this.syncTextboxControlDisabledStatus(this.formModel.status);
158
+ this.textboxControl.setValue(this.dateDisplayPipe.transform(this.formModel.value, true), { emitEvent: false });
159
+ this.calendarSelection = this.formModel.value;
160
+ }
161
+ onFormModelStatusChanges() {
162
+ // Keep the textboxControl disabled status in sync with the formModel
163
+ this.formModel.statusChanges.pipe(distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(status => {
164
+ this.syncTextboxControlDisabledStatus(status);
165
+ if (this.isCalendarOpen) {
166
+ // As validation messages appear/disappear, the date input may have shifted up or down on the page.
167
+ // Update the overlay position to ensure it's still aligned with the textbox and not blocking it.
168
+ // Settimeout is needed to ensure the overlay is being updated after the message is rendered.
169
+ setTimeout(() => {
170
+ this.overlay?.overlayRef?.updatePosition();
171
+ });
172
+ }
173
+ });
174
+ }
175
+ onFormModelValueChanges() {
176
+ // Update the calendar selection textbox value with a formatted date when the form model changes.
177
+ // This is usually triggered by programmatic changes to the form model by a parent component.
178
+ this.formModel.valueChanges.pipe(distinctUntilChanged((a, b) => moment(a).isSame(b, 'day')), takeUntil(this.componentDestroyed)).subscribe(value => {
179
+ const displayValue = this.dateDisplayPipe.transform(value, true);
180
+ // Don't emit an event when setting the textbox value to avoid circular updates between the textbox and form model.
181
+ this.textboxControl.setValue(displayValue, { emitEvent: false });
182
+ this.calendarSelection = value;
183
+ });
184
+ }
185
+ onTextboxValueChanges() {
186
+ // Update the calendar selection when the textbox value changes to update the calendar.
187
+ // We don't patch the formModel here because we don't want to trigger the
188
+ // date formatting logic and overwrite the user's input.
189
+ // We'll do that when the user blurs out of the textbox. See onTextboxBlur()
190
+ this.textboxControl.valueChanges.pipe(debounceTime(300), distinctUntilChanged(), takeUntil(this.componentDestroyed)).subscribe(value => {
191
+ if (value) {
192
+ const parsedDate = moment(value, this.parseFormats);
193
+ if (parsedDate.isValid()) {
194
+ // If the parsed date is before the minDate, set the year to the current year.
195
+ // This prevents the calendar from showing unhelpful dates in the distant past as the user types
196
+ if (parsedDate.year() < this.minDate.getFullYear()) {
197
+ parsedDate.set('year', moment().year());
198
+ }
199
+ this.calendarSelection = parsedDate.toDate();
200
+ }
201
+ }
202
+ else {
203
+ this.calendarSelection = null;
204
+ }
205
+ });
206
+ }
207
+ syncTextboxControlDisabledStatus(status) {
208
+ // The textbox should only be disabled if the form model is disabled.
209
+ // All other statuses are considered enabled.
210
+ if (status === 'DISABLED' && this.textboxControl.enabled) {
211
+ this.textboxControl.disable();
212
+ }
213
+ else if (status !== 'DISABLED' && this.textboxControl.disabled) {
214
+ this.textboxControl.enable();
215
+ }
216
+ }
217
+ ;
218
+ /**
219
+ * Updates the date parsing formats and placeholder based on the user's display preference.
220
+ * NOTE: This is async because we're retrieving the user's preferences. We're not awaiting the result
221
+ * because the only logic that depends on this is the text box date parsing logic and placeholder.
222
+ * Our forms should always be behind a pending overlay, so the user won't be able to interact with the
223
+ * form until the user is loaded anyway.
224
+ */
225
+ async setDateFormats() {
226
+ const { preference } = await lastValueFrom(this.userPreferenceService.getPreferences());
227
+ const dateFormat = preference?.dateFormat;
228
+ this.placeholder = dateFormat ?? this.placeholder;
229
+ this.parseFormats = DateTimeHelper.getMomentParseFormats(dateFormat);
230
+ }
231
+ /** Focuses the date input. */
232
+ focusInput() {
233
+ this.el.nativeElement.querySelector('input')?.focus();
234
+ }
235
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DateInputComponent, deps: [{ token: i1.ValidationMessageService }, { token: i2.FormGroupHelper }, { token: i3.UserPreferenceService }, { token: i4.DateDisplayPipe }, { token: i0.ElementRef }, { token: i5.Overlay }], target: i0.ɵɵFactoryTarget.Component }); }
236
+ static { thiscmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "16.2.12", type: DateInputComponent, selector: "ec-date-input", inputs: { id: "id", formModel: "formModel", minDate: "minDate", maxDate: "maxDate" }, host: { properties: { "attr.id": "this.id" } }, viewQueries: [{ propertyName: "overlay", first: true, predicate: ["overlay"], descendants: true }], usesInheritance: 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<ec-form-control id=\"{{id}}\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n [formModel]=\"formModel\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n (actionKeydown)=\"onActionKeydown($event)\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n cdkOverlayOrigin\r\n #overlayOrigin=\"cdkOverlayOrigin\">\r\n <input id=\"{{id}}_input\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxControl\"\r\n (blur)=\"onTextboxBlur()\"\r\n (keydown)=\"onTextboxKeydown($event)\">\r\n</ec-form-control>\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 <ec-calendar [id]=\"id + '_calendar'\"\r\n [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\"\r\n [selection]=\"calendarSelection\"\r\n (selectionChange)=\"onSelectionChange($event)\"\r\n class=\"card px-1 pt-1 pb-2\"\r\n (focusOutStart)=\"onCalendarFocusOutStart($event)\"\r\n (focusOutEnd)=\"onCalendarFocusOutEnd($event)\">\r\n </ec-calendar>\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}\n"], dependencies: [{ 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: i5.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: i5.CdkOverlayOrigin, selector: "[cdk-overlay-origin], [overlay-origin], [cdkOverlayOrigin]", exportAs: ["cdkOverlayOrigin"] }, { kind: "component", type: i8.FormControlComponent, selector: "ec-form-control", inputs: ["id", "icon", "actionIcon", "showClear", "formModel", "autofocus", "pending", "required", "readonly"], outputs: ["actionClicked", "actionKeydown"] }, { kind: "component", type: i9.HelpPopoverComponent, selector: "ec-help-popover", inputs: ["id", "text", "contentPosition", "maxWidth"] }, { kind: "component", type: i10.CalendarComponent, selector: "ec-calendar", inputs: ["id", "selection", "minDate", "maxDate"], outputs: ["selectionChange", "focusOutStart", "focusOutEnd"] }, { kind: "pipe", type: i11.TranslatePipe, name: "translate" }] }); }
237
+ }
238
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.2.12", ngImport: i0, type: DateInputComponent, decorators: [{
239
+ type: Component,
240
+ args: [{ selector: 'ec-date-input', 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<ec-form-control id=\"{{id}}\"\r\n [required]=\"required\"\r\n [autofocus]=\"autofocus\"\r\n [pending]=\"pending\"\r\n [readonly]=\"readonly\"\r\n [formModel]=\"formModel\"\r\n (actionClicked)=\"isCalendarOpen = !isCalendarOpen\"\r\n (actionKeydown)=\"onActionKeydown($event)\"\r\n [showClear]=\"false\"\r\n actionIcon=\"icon-date\"\r\n cdkOverlayOrigin\r\n #overlayOrigin=\"cdkOverlayOrigin\">\r\n <input id=\"{{id}}_input\"\r\n type=\"text\"\r\n placeholder=\"{{placeholder}}\"\r\n [formControl]=\"textboxControl\"\r\n (blur)=\"onTextboxBlur()\"\r\n (keydown)=\"onTextboxKeydown($event)\">\r\n</ec-form-control>\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 <ec-calendar [id]=\"id + '_calendar'\"\r\n [minDate]=\"minDate\"\r\n [maxDate]=\"maxDate\"\r\n [selection]=\"calendarSelection\"\r\n (selectionChange)=\"onSelectionChange($event)\"\r\n class=\"card px-1 pt-1 pb-2\"\r\n (focusOutStart)=\"onCalendarFocusOutStart($event)\"\r\n (focusOutEnd)=\"onCalendarFocusOutEnd($event)\">\r\n </ec-calendar>\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}\n"] }]
241
+ }], ctorParameters: function () { return [{ type: i1.ValidationMessageService }, { type: i2.FormGroupHelper }, { type: i3.UserPreferenceService }, { type: i4.DateDisplayPipe }, { type: i0.ElementRef }, { type: i5.Overlay }]; }, propDecorators: { id: [{
242
+ type: HostBinding,
243
+ args: ['attr.id']
244
+ }, {
245
+ type: Input
246
+ }], formModel: [{
247
+ type: Input
248
+ }], minDate: [{
249
+ type: Input
250
+ }], maxDate: [{
251
+ type: Input
252
+ }], overlay: [{
253
+ type: ViewChild,
254
+ args: ['overlay']
255
+ }] } });
256
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS1pbnB1dC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jb21wb25lbnRzL3NyYy9saWIvY29udHJvbHMvZGF0ZS1pbnB1dC9kYXRlLWlucHV0LmNvbXBvbmVudC50cyIsIi4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2NvbXBvbmVudHMvc3JjL2xpYi9jb250cm9scy9kYXRlLWlucHV0L2RhdGUtaW5wdXQuY29tcG9uZW50Lmh0bWwiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxFQUFFLFNBQVMsRUFBYyxXQUFXLEVBQUUsS0FBSyxFQUFVLFNBQVMsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3RixPQUFPLEVBQW1CLFdBQVcsRUFBa0MsTUFBTSxnQkFBZ0IsQ0FBQztBQUM5RixPQUFPLE1BQU0sTUFBTSxRQUFRLENBQUM7QUFDNUIsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNyQyxPQUFPLEVBQUUsWUFBWSxFQUFFLG9CQUFvQixFQUFFLFNBQVMsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQy9FLE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw2QkFBNkIsQ0FBQztBQUs3RCxPQUFPLEVBQXFCLDZCQUE2QixFQUFFLE1BQU0sNEJBQTRCLENBQUM7QUFDOUYsT0FBTyxFQUFFLGVBQWUsRUFBRSxNQUFNLHNCQUFzQixDQUFDOzs7Ozs7Ozs7Ozs7O0FBU3ZELE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxlQUFlO0lBc0NyRCxZQUNZLHdCQUFrRCxFQUNsRCxlQUFnQyxFQUNsQyxxQkFBNEMsRUFDNUMsZUFBZ0MsRUFDaEMsRUFBYyxFQUNkLGNBQXVCO1FBRS9CLEtBQUssQ0FBQyx3QkFBd0IsRUFBRSxlQUFlLENBQUMsQ0FBQztRQVB2Qyw2QkFBd0IsR0FBeEIsd0JBQXdCLENBQTBCO1FBQ2xELG9CQUFlLEdBQWYsZUFBZSxDQUFpQjtRQUNsQyww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LGNBQWMsQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUMvQjthQUFNLElBQUksTUFBTSxLQUFLLFVBQVUsSUFBSSxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsRUFBRTtZQUNoRSxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sRUFBRSxDQUFDO1NBQzlCO0lBQ0gsQ0FBQztJQUFBLENBQUM7SUFFRjs7Ozs7O09BTUc7SUFDSyxLQUFLLENBQUMsY0FBYztRQUMxQixNQUFNLEVBQUUsVUFBVSxFQUFFLEdBQUcsTUFBTSxhQUFhLENBQUMsSUFBSSxDQUFDLHFCQUFxQixDQUFDLGNBQWMsRUFBRSxDQUFDLENBQUM7UUFDeEYsTUFBTSxVQUFVLEdBQUcsVUFBVSxFQUFFLFVBQVUsQ0FBQztRQUMxQyxJQUFJLENBQUMsV0FBVyxHQUFHLFVBQVUsSUFBSSxJQUFJLENBQUMsV0FBVyxDQUFDO1FBQ2xELElBQUksQ0FBQyxZQUFZLEdBQUcsY0FBYyxDQUFDLHFCQUFxQixDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3ZFLENBQUM7SUFtQkQsOEJBQThCO0lBQ3RCLFVBQVU7UUFDaEIsSUFBSSxDQUFDLEVBQUUsQ0FBQyxhQUFhLENBQUMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxFQUFFLEtBQUssRUFBRSxDQUFDO0lBQ3hELENBQUM7K0dBOVBVLGtCQUFrQjttR0FBbEIsa0JBQWtCLHNUQ3JCL0Isd3VFQWlEQTs7NEZENUJhLGtCQUFrQjtrQkFMOUIsU0FBUzsrQkFDRSxlQUFlOzhQQU9ULEVBQUU7c0JBRGpCLFdBQVc7dUJBQUMsU0FBUzs7c0JBQ3JCLEtBQUs7Z0JBR1UsU0FBUztzQkFBeEIsS0FBSztnQkFFVSxPQUFPO3NCQUF0QixLQUFLO2dCQUNVLE9BQU87c0JBQXRCLEtBQUs7Z0JBMkJnQixPQUFPO3NCQUE1QixTQUFTO3VCQUFDLFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDZGtDb25uZWN0ZWRPdmVybGF5LCBPdmVybGF5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL292ZXJsYXknO1xyXG5pbXBvcnQgeyBDb21wb25lbnQsIEVsZW1lbnRSZWYsIEhvc3RCaW5kaW5nLCBJbnB1dCwgT25Jbml0LCBWaWV3Q2hpbGQgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgQWJzdHJhY3RDb250cm9sLCBGb3JtQ29udHJvbCwgRm9ybUNvbnRyb2xTdGF0dXMsIFZhbGlkYXRvckZuIH0gZnJvbSAnQGFuZ3VsYXIvZm9ybXMnO1xyXG5pbXBvcnQgbW9tZW50IGZyb20gJ21vbWVudCc7XHJcbmltcG9ydCB7IGxhc3RWYWx1ZUZyb20gfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBkaXN0aW5jdFVudGlsQ2hhbmdlZCwgdGFrZVVudGlsIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xyXG5pbXBvcnQgeyBEYXRlVGltZUhlbHBlciB9IGZyb20gJy4uLy4uL2NvcmUvZGF0ZS10aW1lLWhlbHBlcic7XHJcbmltcG9ydCB7IFZhbGlkYXRpb25NZXNzYWdlU2VydmljZSB9IGZyb20gJy4uLy4uL2NvcmUvdmFsaWRhdGlvbi1tZXNzYWdlLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBEYXRlRGlzcGxheVBpcGUgfSBmcm9tICcuLi8uLi9zaGFyZWQvZGlzcGxheS9waXBlcy9kYXRlLWRpc3BsYXkucGlwZSc7XHJcbmltcG9ydCB7IEZvcm1Hcm91cEhlbHBlciB9IGZyb20gJy4uLy4uL3NoYXJlZC9mb3JtLWdyb3VwLmhlbHBlcic7XHJcbmltcG9ydCB7IFVzZXJQcmVmZXJlbmNlU2VydmljZSB9IGZyb20gJy4uLy4uL3NoYXJlZC91c2VyLXByZWZlcmVuY2Uuc2VydmljZSc7XHJcbmltcG9ydCB7IENhbGVuZGFyU2VsZWN0aW9uLCBpc0NhbGVuZGFyU2VsZWN0aW9uU2luZ2xlRGF0ZSB9IGZyb20gJy4uL2NhbGVuZGFyL2NhbGVuZGFyLnR5cGVzJztcclxuaW1wb3J0IHsgRm9ybUNvbnRyb2xCYXNlIH0gZnJvbSAnLi4vZm9ybS1jb250cm9sLWJhc2UnO1xyXG5cclxuZXhwb3J0IHR5cGUgRGF0ZUlucHV0Rm9ybUNvbnRyb2wgPSBGb3JtQ29udHJvbDxEYXRlIHwgbnVsbD47XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2VjLWRhdGUtaW5wdXQnLFxyXG4gIHRlbXBsYXRlVXJsOiAnLi9kYXRlLWlucHV0LmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybHM6IFsnLi9kYXRlLWlucHV0LmNvbXBvbmVudC5zY3NzJ11cclxufSlcclxuZXhwb3J0IGNsYXNzIERhdGVJbnB1dENvbXBvbmVudCBleHRlbmRzIEZvcm1Db250cm9sQmFzZSBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIEBIb3N0QmluZGluZygnYXR0ci5pZCcpXHJcbiAgQElucHV0KCkgcHVibGljIGlkOiBzdHJpbmcgPSAnJztcclxuXHJcbiAgLyoqIFRoZSBmb3JtIGNvbnRyb2wgcHJvdmlkZWQgYnkgdGhlIGhvc3RpbmcgZm9ybS4gKi9cclxuICBASW5wdXQoKSBwdWJsaWMgZm9ybU1vZGVsOiBEYXRlSW5wdXRGb3JtQ29udHJvbCA9IG5ldyBGb3JtQ29udHJvbDxEYXRlIHwgbnVsbD4obnVsbCk7XHJcblxyXG4gIEBJbnB1dCgpIHB1YmxpYyBtaW5EYXRlOiBEYXRlID0gRGF0ZVRpbWVIZWxwZXIubWluRGF0ZVBpY2tlckRhdGU7XHJcbiAgQElucHV0KCkgcHVibGljIG1heERhdGU6IERhdGUgPSBEYXRlVGltZUhlbHBlci5tYXhEYXRlUGlja2VyRGF0ZTtcclxuXHJcbiAgLyoqIFRoZSBpbnRlcm5hbCB0ZXh0Ym94J3MgZm9ybSBjb250cm9sLiAqL1xyXG4gIHB1YmxpYyB0ZXh0Ym94Q29udHJvbCA9IG5ldyBGb3JtQ29udHJvbDxzdHJpbmcgfCBudWxsPihudWxsKTtcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIGN1cnJlbnQgY2FsZW5kYXIgc2VsZWN0aW9uLlxyXG4gICAqIFVwZGF0ZWQgd2hlbiB0aGUgdXNlciBjbGlja3Mgb24gYSBjYWxlbmRhciBpdGVtIG9yIHdoZW4gdGhlIGRhdGUgZW50ZXJlZCBpbnRvIHRoZSB0ZXh0Ym94IGlzIHBhcnNlZC5cclxuICAgKi9cclxuICBwdWJsaWMgY2FsZW5kYXJTZWxlY3Rpb246IENhbGVuZGFyU2VsZWN0aW9uIHwgbnVsbCA9IG51bGw7XHJcblxyXG4gIC8qKiBDb250cm9scyB3aGV0aGVyIHRoZSBjYWxlbmRhciBvdmVybGF5IGlzIG9wZW4gb3Igbm90LiAqL1xyXG4gIHB1YmxpYyBpc0NhbGVuZGFyT3BlbiA9IGZhbHNlO1xyXG5cclxuICAvKiogUGxhY2Vob2xkZXIgZm9yIHRoZSB0ZXh0Ym94LiBVcGRhdGVkIHRvIHJlZmxlY3QgdGhlIHVzZXIncyBkYXRlIGRpc3BsYXkgcHJlZmVyZW5jZS4gKi9cclxuICBwdWJsaWMgcGxhY2Vob2xkZXI6IHN0cmluZyA9ICdNTS9ERC9ZWVlZJztcclxuXHJcbiAgLyoqIE92ZXJsYXkgc2Nyb2xsIHN0cmF0ZWd5IGZvciB0aGUgY2FsZW5kYXIgb3ZlcmxheS4gQ2xvc2VzIHRoZSBjYWxlbmRhciBvbiBzY3JvbGwuICovXHJcbiAgcHVibGljIG92ZXJsYXlTY3JvbGxTdHJhdGVneSA9IHRoaXMub3ZlcmxheVNlcnZpY2Uuc2Nyb2xsU3RyYXRlZ2llcy5jbG9zZSgpO1xyXG5cclxuICAvKiogXHJcbiAgICogRGF0ZSBwYXJzaW5nIGZvcm1hdHMgZm9yIHVzZXItZW50ZXJlZCBkYXRlcy4gRGVmYXVsdHMgdG8gbW9udGgtZmlyc3QgZm9ybWF0cywgYnV0IGlzIHVwZGF0ZWQgaW4gb25Jbml0XHJcbiAgICogdG8gdXNlIHRoZSB1c2VyJ3MgcHJlZmVycmVkIGRhdGUgZm9ybWF0LlxyXG4gICAqL1xyXG4gIHByaXZhdGUgcGFyc2VGb3JtYXRzOiBzdHJpbmdbXSA9IERhdGVUaW1lSGVscGVyLmdldFBhcnNlRm9ybWF0cygpO1xyXG5cclxuICAvKiogUmVmZXJlbmNlIHRvIHRoZSBvdmVybGF5IGRpcmVjdGl2ZSAoc2VlIHRlbXBsYXRlKS4gVXNlZCB0byBhY2Nlc3MgdGhlIG92ZXJsYXkncyBob3N0IGVsZW1lbnQgdG8gY29udHJvbCBmb2N1cy4gKi9cclxuICBAVmlld0NoaWxkKCdvdmVybGF5Jykgb3ZlcmxheT86IENka0Nvbm5lY3RlZE92ZXJsYXk7XHJcblxyXG4gIGNvbnN0cnVjdG9yKFxyXG4gICAgcHJvdGVjdGVkIHZhbGlkYXRpb25NZXNzYWdlU2VydmljZTogVmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlLFxyXG4gICAgcHJvdGVjdGVkIGZvcm1Hcm91cEhlbHBlcjogRm9ybUdyb3VwSGVscGVyLFxyXG4gICAgcHJpdmF0ZSB1c2VyUHJlZmVyZW5jZVNlcnZpY2U6IFVzZXJQcmVmZXJlbmNlU2VydmljZSxcclxuICAgIHByaXZhdGUgZGF0ZURpc3BsYXlQaXBlOiBEYXRlRGlzcGxheVBpcGUsXHJcbiAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxyXG4gICAgcHJpdmF0ZSBvdmVybGF5U2VydmljZTogT3ZlcmxheVxyXG4gICkge1xyXG4gICAgc3VwZXIodmFsaWRhdGlvbk1lc3NhZ2VTZXJ2aWNlLCBmb3JtR3JvdXBIZWxwZXIpO1xyXG4gIH1cclxuXHJcbiAgLyoqIEZvY3VzZXMgdGhlIGlucHV0IHdoZW5ldmVyIHRoZSBjYWxlbmRhciBpcyBzaGlmdC10YWJiZWQgb3V0IG9mLiAqL1xyXG4gIHB1YmxpYyBvbkNhbGVuZGFyRm9jdXNPdXRTdGFydChldmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgIHRoaXMuZm9jdXNJbnB1dCgpO1xyXG4gIH1cclxuXHJcbiAgLyoqIENsb3NlcyB0aGUgY2FsZW5kYXIgYW5kIGZvY3VzZXMgdGhlIGlucHV0IHdoZW5ldmVyIHRoZSBjYWxlbmRhciBpcyB0YWJiZWQgb3V0IG9mLiAqL1xyXG4gIHB1YmxpYyBvbkNhbGVuZGFyRm9jdXNPdXRFbmQoZXZlbnQ6IEtleWJvYXJkRXZlbnQpIHtcclxuICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICB0aGlzLmlzQ2FsZW5kYXJPcGVuID0gZmFsc2U7XHJcbiAgICB0aGlzLmZvY3VzSW5wdXQoKTtcclxuICB9XHJcblxyXG4gIC8qKiBDbG9zZSB0aGUgY2FsZW5kYXIgaWYgdGhlIHVzZXIgY2xpY2tzIG91dHNpZGUgb2YgdGhlIGNhbGVuZGFyIGFuZCBkYXRlIGlucHV0LiAqL1xyXG4gIHB1YmxpYyBvbk92ZXJsYXlPdXRzaWRlQ2xpY2soZXZlbnQ6IE1vdXNlRXZlbnQpIHtcclxuICAgIC8vIERvIG5vdCBjbG9zZSB0aGUgY2FsZW5kYXIgaWYgdGhlIGNsaWNrIHdhcyB3aXRoaW4gdGhlIGRhdGUgaW5wdXQgb3IgYWN0aW9uIGJ1dHRvblxyXG4gICAgY29uc3QgcmVjdCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcclxuICAgIGNvbnN0IGNsaWNrZWRPdXRzaWRlQ29udHJvbCA9IGV2ZW50LmNsaWVudFkgPCByZWN0LnRvcCB8fFxyXG4gICAgICBldmVudC5jbGllbnRZID4gcmVjdC5ib3R0b20gfHxcclxuICAgICAgZXZlbnQuY2xpZW50WCA8IHJlY3QubGVmdCB8fFxyXG4gICAgICBldmVudC5jbGllbnRYID4gcmVjdC5yaWdodDtcclxuICAgIC8vIEl0J3MgcG9zc2libGUgdGhhdCB0aGUgdXNlciBoaXQgZW50ZXIgb24gdGhlIGFjdGlvbiBidXR0b24gaW5zdGVhZCBvZiBjbGlja2luZyB3aXRoIHRoZSBtb3VzZS5cclxuICAgIC8vIEluIHRoaXMgY2FzZSB0aGUgXCJjbGlja1wiIGV2ZW50IHdpbGwgYmUgb3V0c2lkZSBvZiB0aGUgY29tcG9uZW50IGJlY2F1c2UgdGhlIGNsaWVudHggYW5kIHkgYXJlIDAsXHJcbiAgICAvLyBidXQgd2UgZG9uJ3Qgd2FudCB0byBjbG9zZSBpbiB0aGlzIGNhc2UgYmVjYXVzZSBidXR0b24gY2xpY2tzIHRyaWdnZXIgY2FsZW5kYXIgb3Blbi9jbG9zZSBzZXBhcmF0ZWx5LlxyXG4gICAgY29uc3QgaXNBY3Rpb25DbGljayA9ICg8SFRNTEVsZW1lbnQ+ZXZlbnQudGFyZ2V0KS5pZCA9PT0gYCR7dGhpcy5pZH1fYWN0aW9uYDtcclxuXHJcbiAgICBpZiAoIWlzQWN0aW9uQ2xpY2sgJiYgY2xpY2tlZE91dHNpZGVDb250cm9sKSB7XHJcbiAgICAgIHRoaXMuaXNDYWxlbmRhck9wZW4gPSBmYWxzZTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8qKiBJZiB0aGUgdXNlciB0YWJzIG91dCBvZiB0aGUgZm9ybSBjb250cm9sJ3MgYWN0aW9uIGJ1dHRvbiBhbmQgdGhlIGNhbGVuZGFyIGlzIG9wZW4sIGZvY3VzIHRoZSBmaXJzdCBpdGVtIGluIHRoZSBjYWxlbmRhciBvdmVybGF5ICovXHJcbiAgcHVibGljIG9uQWN0aW9uS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ1RhYicgJiYgIWV2ZW50LnNoaWZ0S2V5ICYmIHRoaXMuaXNDYWxlbmRhck9wZW4pIHtcclxuICAgICAgLy8gUHJldmVudCB0aGUgZGVmYXVsdCB0YWIgYWN0aW9uIHNvIHRoZSBmb2N1cyBkb2Vzbid0IG1vdmUgdG8gdGhlIG5leHQgZWxlbWVudCBpbiB0aGUgdGFiIG9yZGVyIGFmdGVyIHdlIG1hbnVhbGx5IGZvY3VzIHRoZSBjYWxlbmRhciBidXR0b24uXHJcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XHJcbiAgICAgIC8vIEZvY3VzIHRoZSBmaXJzdCBidXR0b24gaW4gdGhlIGNhbGVuZGFyIG92ZXJsYXlcclxuICAgICAgY29uc3QgZmlyc3RCdXR0b246IEhUTUxCdXR0b25FbGVtZW50IHwgbnVsbCB8IHVuZGVmaW5lZCA9IHRoaXMub3ZlcmxheT8ub3ZlcmxheVJlZi5ob3N0RWxlbWVudC5xdWVyeVNlbGVjdG9yKCdidXR0b246bm90KDpkaXNhYmxlZCknKTtcclxuICAgICAgZmlyc3RCdXR0b24/LmZvY3VzKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25UZXh0Ym94S2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xyXG4gICAgaWYgKGV2ZW50LmtleSA9PT0gJ1RhYicgJiYgZXZlbnQuc2hpZnRLZXkpIHtcclxuICAgICAgLy8gSWYgdGhlIHVzZXIgaXMgdGFiYmluZyBiYWNrd2FyZHMgZnJvbSB0aGUgdGV4dGJveCwgY2xvc2UgdGhlIGNhbGVuZGFyLlxyXG4gICAgICB0aGlzLmlzQ2FsZW5kYXJPcGVuID0gZmFsc2U7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKiogV2hlbmV2ZXIgdGhlIHVzZXIgc2VsZWN0cyBhIGRhdGUgZnJvbSB0aGUgY2FsZW5kYXIsIHVwZGF0ZSB0aGUgZm9ybU1vZGVsIHdpdGggdGhlIHNlbGVjdGlvbiAqL1xyXG4gIHB1YmxpYyBvblNlbGVjdGlvbkNoYW5nZShzZWxlY3Rpb246IENhbGVuZGFyU2VsZWN0aW9uIHwgbnVsbCkge1xyXG4gICAgdGhpcy5jYWxlbmRhclNlbGVjdGlvbiA9IHNlbGVjdGlvbjtcclxuICAgIGlmIChpc0NhbGVuZGFyU2VsZWN0aW9uU2luZ2xlRGF0ZShzZWxlY3Rpb24pKSB7XHJcbiAgICAgIHRoaXMuZm9ybU1vZGVsLnNldFZhbHVlKHNlbGVjdGlvbik7XHJcbiAgICAgIHRoaXMuaXNDYWxlbmRhck9wZW4gPSBmYWxzZTtcclxuICAgICAgdGhpcy5mb2N1c0lucHV0KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgb25UZXh0Ym94Qmx1cigpIHtcclxuICAgIC8vIFBhcnNlIHRoZSB0ZXh0Ym94IHZhbHVlIGludG8gYSBkYXRlIGFuZCB1cGRhdGUgdGhlIGZvcm0gbW9kZWxcclxuICAgIGNvbnN0IHZhbHVlID0gdGhpcy50ZXh0Ym94Q29udHJvbC52YWx1ZTtcclxuICAgIGlmICh2YWx1ZSkge1xyXG4gICAgICBjb25zdCBwYXJzZWREYXRlID0gbW9tZW50KHZhbHVlLCB0aGlzLnBhcnNlRm9ybWF0cyk7XHJcbiAgICAgIGlmIChwYXJzZWREYXRlLmlzVmFsaWQoKSkge1xyXG4gICAgICAgIHRoaXMuZm9ybU1vZGVsLnNldFZhbHVlKHBhcnNlZERhdGUudG9EYXRlKCkpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHRoaXMuZm9ybU1vZGVsLnNldFZhbHVlKG51bGwpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmZvcm1Nb2RlbC5zZXRWYWx1ZShudWxsKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBVcGRhdGUgdGhlIGZvcm0gbW9kZWwncyB0b3VjaGVkIGFuZCBkaXJ0eSBzdGF0dXMgYmFzZWQgb24gdGhlIHRleHRib3gncyBzdGF0dXMuXHJcbiAgICAvLyBTaW5jZSB0aGUgdXNlciBpbnRlcmFjdHMgd2l0aCBhIGNvbnRyb2wgdGhhdCBpcyBpbnRlcm5hbCB0byB0aGlzIGNvbXBvbmVudCwgdGhlXHJcbiAgICAvLyBmb3JtIG1vZGVsJ3Mgc3RhdHVzIHdvbid0IGJlIHVwZGF0ZWQgYXV0b21hdGljYWxseS5cclxuICAgIGlmICh0aGlzLnRleHRib3hDb250cm9sLnRvdWNoZWQgJiYgIXRoaXMuZm9ybU1vZGVsLnRvdWNoZWQpIHtcclxuICAgICAgdGhpcy5mb3JtTW9kZWwubWFya0FzVG91Y2hlZCgpO1xyXG4gICAgfVxyXG4gICAgaWYgKHRoaXMudGV4dGJveENvbnRyb2wuZGlydHkgJiYgIXRoaXMuZm9ybU1vZGVsLmRpcnR5KSB7XHJcbiAgICAgIHRoaXMuZm9ybU1vZGVsLm1hcmtBc0RpcnR5KCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIC8vIFNldHVwXHJcbiAgICBzdXBlci5uZ09uSW5pdCgpO1xyXG4gICAgdGhpcy5zZXREYXRlRm9ybWF0cygpO1xyXG5cclxuICAgIHRoaXMuZm9ybU1vZGVsLmFkZFZhbGlkYXRvcnModGhpcy5kYXRlVmFsaWRhdG9yKTtcclxuXHJcbiAgICAvLyBTdWJzY3JpcHRpb25zXHJcbiAgICB0aGlzLm9uRm9ybU1vZGVsU3RhdHVzQ2hhbmdlcygpO1xyXG4gICAgdGhpcy5vbkZvcm1Nb2RlbFZhbHVlQ2hhbmdlcygpO1xyXG4gICAgdGhpcy5vblRleHRib3hWYWx1ZUNoYW5nZXMoKTtcclxuXHJcbiAgICAvLyBTeW5jIHRoZSBpbml0aWFsIGRpc2FibGVkIHN0YXR1cyBhbmQgdmFsdWUgb2YgdGhlIHRleHRib3hcclxuICAgIHRoaXMuc3luY1RleHRib3hDb250cm9sRGlzYWJsZWRTdGF0dXModGhpcy5mb3JtTW9kZWwuc3RhdHVzKTtcclxuICAgIHRoaXMudGV4dGJveENvbnRyb2wuc2V0VmFsdWUodGhpcy5kYXRlRGlzcGxheVBpcGUudHJhbnNmb3JtKHRoaXMuZm9ybU1vZGVsLnZhbHVlLCB0cnVlKSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgdGhpcy5jYWxlbmRhclNlbGVjdGlvbiA9IHRoaXMuZm9ybU1vZGVsLnZhbHVlO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvbkZvcm1Nb2RlbFN0YXR1c0NoYW5nZXMoKSB7XHJcbiAgICAvLyBLZWVwIHRoZSB0ZXh0Ym94Q29udHJvbCBkaXNhYmxlZCBzdGF0dXMgaW4gc3luYyB3aXRoIHRoZSBmb3JtTW9kZWxcclxuICAgIHRoaXMuZm9ybU1vZGVsLnN0YXR1c0NoYW5nZXMucGlwZShcclxuICAgICAgZGlzdGluY3RVbnRpbENoYW5nZWQoKSxcclxuICAgICAgdGFrZVVudGlsKHRoaXMuY29tcG9uZW50RGVzdHJveWVkKVxyXG4gICAgKS5zdWJzY3JpYmUoc3RhdHVzID0+IHtcclxuICAgICAgdGhpcy5zeW5jVGV4dGJveENvbnRyb2xEaXNhYmxlZFN0YXR1cyhzdGF0dXMpO1xyXG5cclxuICAgICAgaWYgKHRoaXMuaXNDYWxlbmRhck9wZW4pIHtcclxuICAgICAgICAvLyBBcyB2YWxpZGF0aW9uIG1lc3NhZ2VzIGFwcGVhci9kaXNhcHBlYXIsIHRoZSBkYXRlIGlucHV0IG1heSBoYXZlIHNoaWZ0ZWQgdXAgb3IgZG93biBvbiB0aGUgcGFnZS5cclxuICAgICAgICAvLyBVcGRhdGUgdGhlIG92ZXJsYXkgcG9zaXRpb24gdG8gZW5zdXJlIGl0J3Mgc3RpbGwgYWxpZ25lZCB3aXRoIHRoZSB0ZXh0Ym94IGFuZCBub3QgYmxvY2tpbmcgaXQuXHJcbiAgICAgICAgLy8gU2V0dGltZW91dCBpcyBuZWVkZWQgdG8gZW5zdXJlIHRoZSBvdmVybGF5IGlzIGJlaW5nIHVwZGF0ZWQgYWZ0ZXIgdGhlIG1lc3NhZ2UgaXMgcmVuZGVyZWQuXHJcbiAgICAgICAgc2V0VGltZW91dCgoKSA9PiB7XHJcbiAgICAgICAgICB0aGlzLm92ZXJsYXk/Lm92ZXJsYXlSZWY/LnVwZGF0ZVBvc2l0aW9uKCk7XHJcbiAgICAgICAgfSk7XHJcbiAgICAgIH1cclxuICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBvbkZvcm1Nb2RlbFZhbHVlQ2hhbmdlcygpIHtcclxuICAgIC8vIFVwZGF0ZSB0aGUgY2FsZW5kYXIgc2VsZWN0aW9uIHRleHRib3ggdmFsdWUgd2l0aCBhIGZvcm1hdHRlZCBkYXRlIHdoZW4gdGhlIGZvcm0gbW9kZWwgY2hhbmdlcy5cclxuICAgIC8vIFRoaXMgaXMgdXN1YWxseSB0cmlnZ2VyZWQgYnkgcHJvZ3JhbW1hdGljIGNoYW5nZXMgdG8gdGhlIGZvcm0gbW9kZWwgYnkgYSBwYXJlbnQgY29tcG9uZW50LlxyXG4gICAgdGhpcy5mb3JtTW9kZWwudmFsdWVDaGFuZ2VzLnBpcGUoXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKChhLCBiKSA9PiBtb21lbnQoYSkuaXNTYW1lKGIsICdkYXknKSksXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLmNvbXBvbmVudERlc3Ryb3llZClcclxuICAgICkuc3Vic2NyaWJlKHZhbHVlID0+IHtcclxuICAgICAgY29uc3QgZGlzcGxheVZhbHVlID0gdGhpcy5kYXRlRGlzcGxheVBpcGUudHJhbnNmb3JtKHZhbHVlLCB0cnVlKTtcclxuICAgICAgLy8gRG9uJ3QgZW1pdCBhbiBldmVudCB3aGVuIHNldHRpbmcgdGhlIHRleHRib3ggdmFsdWUgdG8gYXZvaWQgY2lyY3VsYXIgdXBkYXRlcyBiZXR3ZWVuIHRoZSB0ZXh0Ym94IGFuZCBmb3JtIG1vZGVsLlxyXG4gICAgICB0aGlzLnRleHRib3hDb250cm9sLnNldFZhbHVlKGRpc3BsYXlWYWx1ZSwgeyBlbWl0RXZlbnQ6IGZhbHNlIH0pO1xyXG4gICAgICB0aGlzLmNhbGVuZGFyU2VsZWN0aW9uID0gdmFsdWU7XHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgb25UZXh0Ym94VmFsdWVDaGFuZ2VzKCkge1xyXG4gICAgLy8gVXBkYXRlIHRoZSBjYWxlbmRhciBzZWxlY3Rpb24gd2hlbiB0aGUgdGV4dGJveCB2YWx1ZSBjaGFuZ2VzIHRvIHVwZGF0ZSB0aGUgY2FsZW5kYXIuXHJcbiAgICAvLyBXZSBkb24ndCBwYXRjaCB0aGUgZm9ybU1vZGVsIGhlcmUgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIHRyaWdnZXIgdGhlXHJcbiAgICAvLyBkYXRlIGZvcm1hdHRpbmcgbG9naWMgYW5kIG92ZXJ3cml0ZSB0aGUgdXNlcidzIGlucHV0LlxyXG4gICAgLy8gV2UnbGwgZG8gdGhhdCB3aGVuIHRoZSB1c2VyIGJsdXJzIG91dCBvZiB0aGUgdGV4dGJveC4gU2VlIG9uVGV4dGJveEJsdXIoKVxyXG4gICAgdGhpcy50ZXh0Ym94Q29udHJvbC52YWx1ZUNoYW5nZXMucGlwZShcclxuICAgICAgZGVib3VuY2VUaW1lKDMwMCksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksXHJcbiAgICAgIHRha2VVbnRpbCh0aGlzLmNvbXBvbmVudERlc3Ryb3llZClcclxuICAgICkuc3Vic2NyaWJlKHZhbHVlID0+IHtcclxuICAgICAgaWYgKHZhbHVlKSB7XHJcbiAgICAgICAgY29uc3QgcGFyc2VkRGF0ZSA9IG1vbWVudCh2YWx1ZSwgdGhpcy5wYXJzZUZvcm1hdHMpO1xyXG4gICAgICAgIGlmIChwYXJzZWREYXRlLmlzVmFsaWQoKSkge1xyXG4gICAgICAgICAgLy8gSWYgdGhlIHBhcnNlZCBkYXRlIGlzIGJlZm9yZSB0aGUgbWluRGF0ZSwgc2V0IHRoZSB5ZWFyIHRvIHRoZSBjdXJyZW50IHllYXIuXHJcbiAgICAgICAgICAvLyBUaGlzIHByZXZlbnRzIHRoZSBjYWxlbmRhciBmcm9tIHNob3dpbmcgdW5oZWxwZnVsIGRhdGVzIGluIHRoZSBkaXN0YW50IHBhc3QgYXMgdGhlIHVzZXIgdHlwZXNcclxuICAgICAgICAgIGlmIChwYXJzZWREYXRlLnllYXIoKSA8IHRoaXMubWluRGF0ZS5nZXRGdWxsWWVhcigpKSB7XHJcbiAgICAgICAgICAgIHBhcnNlZERhdGUuc2V0KCd5ZWFyJywgbW9tZW50KCkueWVhcigpKTtcclxuICAgICAgICAgIH1cclxuICAgICAgICAgIHRoaXMuY2FsZW5kYXJTZWxlY3Rpb24gPSBwYXJzZWREYXRlLnRvRGF0ZSgpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICB0aGlzLmNhbGVuZGFyU2VsZWN0aW9uID0gbnVsbDtcclxuICAgICAgfVxyXG4gICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIHN5bmNUZXh0Ym94Q29udHJvbERpc2FibGVkU3RhdHVzKHN0YXR1czogRm9ybUNvbnRyb2xTdGF0dXMpIHtcclxuICAgIC8vIFRoZSB0ZXh0Ym94IHNob3VsZCBvbmx5IGJlIGRpc2FibGVkIGlmIHRoZSBmb3JtIG1vZGVsIGlzIGRpc2FibGVkLlxyXG4gICAgLy8gQWxsIG90aGVyIHN0YXR1c2VzIGFyZSBjb25zaWRlcmVkIGVuYWJsZWQuXHJcbiAgICBpZiAoc3RhdHVzID09PSAnRElTQUJMRUQnICYmIHRoaXMudGV4dGJveENvbnRyb2wuZW5hYmxlZCkge1xyXG4gICAgICB0aGlzLnRleHRib3hDb250cm9sLmRpc2FibGUoKTtcclxuICAgIH0gZWxzZSBpZiAoc3RhdHVzICE9PSAnRElTQUJMRUQnICYmIHRoaXMudGV4dGJveENvbnRyb2wuZGlzYWJsZWQpIHtcclxuICAgICAgdGhpcy50ZXh0Ym94Q29udHJvbC5lbmFibGUoKTtcclxuICAgIH1cclxuICB9O1xyXG5cclxuICAvKiogXHJcbiAgICogVXBkYXRlcyB0aGUgZGF0ZSBwYXJzaW5nIGZvcm1hdHMgYW5kIHBsYWNlaG9sZGVyIGJhc2VkIG9uIHRoZSB1c2VyJ3MgZGlzcGxheSBwcmVmZXJlbmNlLlxyXG4gICAqIE5PVEU6IFRoaXMgaXMgYXN5bmMgYmVjYXVzZSB3ZSdyZSByZXRyaWV2aW5nIHRoZSB1c2VyJ3MgcHJlZmVyZW5jZXMuIFdlJ3JlIG5vdCBhd2FpdGluZyB0aGUgcmVzdWx0XHJcbiAgICogYmVjYXVzZSB0aGUgb25seSBsb2dpYyB0aGF0IGRlcGVuZHMgb24gdGhpcyBpcyB0aGUgdGV4dCBib3ggZGF0ZSBwYXJzaW5nIGxvZ2ljIGFuZCBwbGFjZWhvbGRlci5cclxuICAgKiBPdXIgZm9ybXMgc2hvdWxkIGFsd2F5cyBiZSBiZWhpbmQgYSBwZW5kaW5nIG92ZXJsYXksIHNvIHRoZSB1c2VyIHdvbid0IGJlIGFibGUgdG8gaW50ZXJhY3Qgd2l0aCB0aGVcclxuICAgKiBmb3JtIHVudGlsIHRoZSB1c2VyIGlzIGxvYWRlZCBhbnl3YXkuXHJcbiAgICovXHJcbiAgcHJpdmF0ZSBhc3luYyBzZXREYXRlRm9ybWF0cygpIHtcclxuICAgIGNvbnN0IHsgcHJlZmVyZW5jZSB9ID0gYXdhaXQgbGFzdFZhbHVlRnJvbSh0aGlzLnVzZXJQcmVmZXJlbmNlU2VydmljZS5nZXRQcmVmZXJlbmNlcygpKTtcclxuICAgIGNvbnN0IGRhdGVGb3JtYXQgPSBwcmVmZXJlbmNlPy5kYXRlRm9ybWF0O1xyXG4gICAgdGhpcy5wbGFjZWhvbGRlciA9IGRhdGVGb3JtYXQgPz8gdGhpcy5wbGFjZWhvbGRlcjtcclxuICAgIHRoaXMucGFyc2VGb3JtYXRzID0gRGF0ZVRpbWVIZWxwZXIuZ2V0TW9tZW50UGFyc2VGb3JtYXRzKGRhdGVGb3JtYXQpO1xyXG4gIH1cclxuXHJcbiAgLyoqXHJcbiAgICogVmFsaWRhdG9yIHRoYXQgY2hlY2tzIGlmIHRoZSBkYXRlIGlzIHdpdGhpbiB0aGUgbWluIGFuZCBtYXggZGF0ZSByYW5nZS5cclxuICAgKiBJZiB0aGUgZGF0ZSBpcyBvdXRzaWRlIG9mIHRoZSByYW5nZSwgdGhlIHZhbGlkYXRvciByZXR1cm5zIGFuIGVycm9yIHRoYXRcclxuICAgKiB0cmlnZ2VycyB0aGUgdmFsaWRhdGlvbiBtZXNzYWdlIHNlcnZpY2UgdG8gc2hvdyB0aGUgZXJyb3IgaW4gdGhlIGxhYmVsLlxyXG4gICAqL1xyXG4gIHByaXZhdGUgZGF0ZVZhbGlkYXRvcjogVmFsaWRhdG9yRm4gPSAoY29udHJvbDogQWJzdHJhY3RDb250cm9sKSA9PiB7XHJcbiAgICBpZiAoY29udHJvbC52YWx1ZSkge1xyXG4gICAgICBpZiAoY29udHJvbC52YWx1ZSA8IHRoaXMubWluRGF0ZSkge1xyXG4gICAgICAgIHJldHVybiB7IG1pbkRhdGU6IHsgbWluVmFsdWU6IHRoaXMubWluRGF0ZSB9IH07XHJcbiAgICAgIH0gZWxzZSBpZiAoY29udHJvbC52YWx1ZSA+IHRoaXMubWF4RGF0ZSkge1xyXG4gICAgICAgIHJldHVybiB7IG1heERhdGU6IHsgbWF4VmFsdWU6IHRoaXMubWF4RGF0ZSB9IH07XHJcbiAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZXR1cm4gbnVsbDtcclxuICB9O1xyXG5cclxuICAvKiogRm9jdXNlcyB0aGUgZGF0ZSBpbnB1dC4gKi9cclxuICBwcml2YXRlIGZvY3VzSW5wdXQoKSB7XHJcbiAgICB0aGlzLmVsLm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignaW5wdXQnKT8uZm9jdXMoKTtcclxuICB9XHJcbn1cclxuIiwiPGxhYmVsICpuZ0lmPVwibGFiZWxcIj5cclxuICA8c3Bhbj57e2xhYmVsIHwgdHJhbnNsYXRlfX08L3NwYW4+XHJcbiAgPHNwYW4gKm5nSWY9XCJ2YWxpZGF0aW9uRXJyb3JzLmxlbmd0aCA+IDAgJiYgZm9ybU1vZGVsLnRvdWNoZWQgJiYgZm9ybU1vZGVsLmludmFsaWRcIj4mbmJzcDt7e3ZhbGlkYXRpb25FcnJvcnN9fTwvc3Bhbj5cclxuICA8ZWMtaGVscC1wb3BvdmVyIGlkPVwie3tpZH19X2hlbHBQb3BvdmVyXCJcclxuICAgICAgICAgICAgICAgICAgICpuZ0lmPVwiaGVscFBvcG92ZXJcIlxyXG4gICAgICAgICAgICAgICAgICAgY2xhc3M9XCJkLWlubGluZS1ibG9jayBteS1uMyBteC1uMVwiXHJcbiAgICAgICAgICAgICAgICAgICB0ZXh0PVwie3toZWxwUG9wb3ZlciB8IHRyYW5zbGF0ZX19XCJcclxuICAgICAgICAgICAgICAgICAgIGNvbnRlbnRQb3NpdGlvbj1cInt7aGVscFBvcG92ZXJQb3NpdGlvbn19XCI+XHJcbiAgPC9lYy1oZWxwLXBvcG92ZXI+XHJcbjwvbGFiZWw+XHJcblxyXG48ZWMtZm9ybS1jb250cm9sIGlkPVwie3tpZH19XCJcclxuICAgICAgICAgICAgICAgICBbcmVxdWlyZWRdPVwicmVxdWlyZWRcIlxyXG4gICAgICAgICAgICAgICAgIFthdXRvZm9jdXNdPVwiYXV0b2ZvY3VzXCJcclxuICAgICAgICAgICAgICAgICBbcGVuZGluZ109XCJwZW5kaW5nXCJcclxuICAgICAgICAgICAgICAgICBbcmVhZG9ubHldPVwicmVhZG9ubHlcIlxyXG4gICAgICAgICAgICAgICAgIFtmb3JtTW9kZWxdPVwiZm9ybU1vZGVsXCJcclxuICAgICAgICAgICAgICAgICAoYWN0aW9uQ2xpY2tlZCk9XCJpc0NhbGVuZGFyT3BlbiA9ICFpc0NhbGVuZGFyT3BlblwiXHJcbiAgICAgICAgICAgICAgICAgKGFjdGlvbktleWRvd24pPVwib25BY3Rpb25LZXlkb3duKCRldmVudClcIlxyXG4gICAgICAgICAgICAgICAgIFtzaG93Q2xlYXJdPVwiZmFsc2VcIlxyXG4gICAgICAgICAgICAgICAgIGFjdGlvbkljb249XCJpY29uLWRhdGVcIlxyXG4gICAgICAgICAgICAgICAgIGNka092ZXJsYXlPcmlnaW5cclxuICAgICAgICAgICAgICAgICAjb3ZlcmxheU9yaWdpbj1cImNka092ZXJsYXlPcmlnaW5cIj5cclxuICA8aW5wdXQgaWQ9XCJ7e2lkfX1faW5wdXRcIlxyXG4gICAgICAgICB0eXBlPVwidGV4dFwiXHJcbiAgICAgICAgIHBsYWNlaG9sZGVyPVwie3twbGFjZWhvbGRlcn19XCJcclxuICAgICAgICAgW2Zvcm1Db250cm9sXT1cInRleHRib3hDb250cm9sXCJcclxuICAgICAgICAgKGJsdXIpPVwib25UZXh0Ym94Qmx1cigpXCJcclxuICAgICAgICAgKGtleWRvd24pPVwib25UZXh0Ym94S2V5ZG93bigkZXZlbnQpXCI+XHJcbjwvZWMtZm9ybS1jb250cm9sPlxyXG5cclxuPG5nLXRlbXBsYXRlIGNka0Nvbm5lY3RlZE92ZXJsYXlcclxuICAgICAgICAgICAgICNvdmVybGF5PVwiY2RrQ29ubmVjdGVkT3ZlcmxheVwiXHJcbiAgICAgICAgICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheU9yaWdpbl09XCJvdmVybGF5T3JpZ2luXCJcclxuICAgICAgICAgICAgIFtjZGtDb25uZWN0ZWRPdmVybGF5T3Blbl09XCJpc0NhbGVuZGFyT3BlblwiXHJcbiAgICAgICAgICAgICBbY2RrQ29ubmVjdGVkT3ZlcmxheVNjcm9sbFN0cmF0ZWd5XT1cIm92ZXJsYXlTY3JvbGxTdHJhdGVneVwiXHJcbiAgICAgICAgICAgICBjZGtDb25uZWN0ZWRPdmVybGF5UGFuZWxDbGFzcz1cIm15LTFcIlxyXG4gICAgICAgICAgICAgKG92ZXJsYXlPdXRzaWRlQ2xpY2spPVwib25PdmVybGF5T3V0c2lkZUNsaWNrKCRldmVudClcIlxyXG4gICAgICAgICAgICAgKGRldGFjaCk9XCJpc0NhbGVuZGFyT3BlbiA9IGZhbHNlXCI+XHJcbiAgPGVjLWNhbGVuZGFyIFtpZF09XCJpZCArICdfY2FsZW5kYXInXCJcclxuICAgICAgICAgICAgICAgW21pbkRhdGVdPVwibWluRGF0ZVwiXHJcbiAgICAgICAgICAgICAgIFttYXhEYXRlXT1cIm1heERhdGVcIlxyXG4gICAgICAgICAgICAgICBbc2VsZWN0aW9uXT1cImNhbGVuZGFyU2VsZWN0aW9uXCJcclxuICAgICAgICAgICAgICAgKHNlbGVjdGlvbkNoYW5nZSk9XCJvblNlbGVjdGlvbkNoYW5nZSgkZXZlbnQpXCJcclxuICAgICAgICAgICAgICAgY2xhc3M9XCJjYXJkIHB4LTEgcHQtMSBwYi0yXCJcclxuICAgICAgICAgICAgICAgKGZvY3VzT3V0U3RhcnQpPVwib25DYWxlbmRhckZvY3VzT3V0U3RhcnQoJGV2ZW50KVwiXHJcbiAgICAgICAgICAgICAgIChmb2N1c091dEVuZCk9XCJvbkNhbGVuZGFyRm9jdXNPdXRFbmQoJGV2ZW50KVwiPlxyXG4gIDwvZWMtY2FsZW5kYXI+XHJcbjwvbmctdGVtcGxhdGU+XHJcbiJdfQ==