@colijnit/corecomponents_v12 12.2.26 → 12.2.27

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 (438) hide show
  1. package/bundles/colijnit-corecomponents_v12.umd.js +13684 -13680
  2. package/bundles/colijnit-corecomponents_v12.umd.js.map +1 -1
  3. package/colijnit-corecomponents_v12.d.ts +43 -43
  4. package/colijnit-corecomponents_v12.metadata.json +1 -1
  5. package/esm2015/colijnit-corecomponents_v12.js +43 -43
  6. package/esm2015/lib/components/article-tile/article-tile.component.js +49 -49
  7. package/esm2015/lib/components/article-tile/article-tile.module.js +34 -34
  8. package/esm2015/lib/components/base/base-input.component.js +833 -833
  9. package/esm2015/lib/components/base/base.module.js +21 -21
  10. package/esm2015/lib/components/base/commit-buttons/commit-buttons.component.js +85 -85
  11. package/esm2015/lib/components/base/commit-buttons/commit-buttons.module.js +20 -20
  12. package/esm2015/lib/components/base/dialog-base.component.js +5 -5
  13. package/esm2015/lib/components/base-input-date-picker/base-input-date-picker.directive.js +24 -24
  14. package/esm2015/lib/components/button/button.component.js +73 -73
  15. package/esm2015/lib/components/button/button.module.js +18 -18
  16. package/esm2015/lib/components/calendar/calendar-template.component.js +281 -281
  17. package/esm2015/lib/components/calendar/calendar.component.js +32 -32
  18. package/esm2015/lib/components/calendar/calendar.module.js +27 -27
  19. package/esm2015/lib/components/card/card.component.js +50 -50
  20. package/esm2015/lib/components/card/card.module.js +34 -34
  21. package/esm2015/lib/components/carousel/carousel.component.js +109 -109
  22. package/esm2015/lib/components/carousel/carousel.module.js +31 -31
  23. package/esm2015/lib/components/carousel-3d/carousel-3d.component.js +293 -293
  24. package/esm2015/lib/components/carousel-3d/carousel-3d.module.js +18 -18
  25. package/esm2015/lib/components/carousel-3d/carouselItem.js +53 -53
  26. package/esm2015/lib/components/checkmark-overlay/checkmark-overlay.component.js +72 -72
  27. package/esm2015/lib/components/checkmark-overlay/checkmark-overlay.module.js +18 -18
  28. package/esm2015/lib/components/co-dialog/co-dialog.component.js +91 -91
  29. package/esm2015/lib/components/co-dialog/co-dialog.module.js +18 -18
  30. package/esm2015/lib/components/co-dialog-wizard/co-dialog-wizard.component.js +35 -35
  31. package/esm2015/lib/components/co-dialog-wizard/co-dialog-wizard.module.js +16 -16
  32. package/esm2015/lib/components/collapsible/collapsible.component.js +67 -67
  33. package/esm2015/lib/components/collapsible/collapsible.module.js +18 -18
  34. package/esm2015/lib/components/color-picker/color-picker.component.js +33 -33
  35. package/esm2015/lib/components/color-picker/color-picker.module.js +20 -20
  36. package/esm2015/lib/components/core-dialog/confirmation-dialog/confirmation-dialog.component.js +46 -46
  37. package/esm2015/lib/components/core-dialog/core-dialog.module.js +38 -38
  38. package/esm2015/lib/components/core-dialog/core-dialog.service.js +66 -66
  39. package/esm2015/lib/components/core-dialog/core-dynamic-component.service.js +92 -92
  40. package/esm2015/lib/components/double-calendar/double-calendar.component.js +62 -62
  41. package/esm2015/lib/components/double-calendar/double-calendar.module.js +24 -24
  42. package/esm2015/lib/components/filter-item/filter-item-viewmodel.js +12 -12
  43. package/esm2015/lib/components/filter-item/filter-item.component.js +496 -496
  44. package/esm2015/lib/components/filter-item/filter-item.module.js +42 -42
  45. package/esm2015/lib/components/filter-item/filter-viewmodel.js +10 -10
  46. package/esm2015/lib/components/form/form.component.js +181 -181
  47. package/esm2015/lib/components/form/form.module.js +22 -22
  48. package/esm2015/lib/components/grid-toolbar/grid-toolbar.component.js +48 -48
  49. package/esm2015/lib/components/grid-toolbar/grid-toolbar.module.js +22 -22
  50. package/esm2015/lib/components/grid-toolbar-button/grid-toolbar-button.component.js +23 -23
  51. package/esm2015/lib/components/grid-toolbar-button/grid-toolbar-button.module.js +18 -18
  52. package/esm2015/lib/components/icon/icon-cache.service.js +51 -51
  53. package/esm2015/lib/components/icon/icon.component.js +47 -47
  54. package/esm2015/lib/components/icon/icon.module.js +24 -24
  55. package/esm2015/lib/components/icon-collapse-handle/icon-collapse-handle.component.js +56 -56
  56. package/esm2015/lib/components/icon-collapse-handle/icon-collapse-handle.module.js +22 -22
  57. package/esm2015/lib/components/image/image.component.js +31 -31
  58. package/esm2015/lib/components/image/image.module.js +13 -13
  59. package/esm2015/lib/components/input-checkbox/input-checkbox.component.js +71 -71
  60. package/esm2015/lib/components/input-checkbox/input-checkbox.module.js +18 -18
  61. package/esm2015/lib/components/input-date-picker/input-date-picker.component.js +74 -74
  62. package/esm2015/lib/components/input-date-picker/input-date-picker.module.js +25 -25
  63. package/esm2015/lib/components/input-date-range-picker/input-date-range-picker.component.js +107 -107
  64. package/esm2015/lib/components/input-date-range-picker/input-date-range-picker.module.js +26 -26
  65. package/esm2015/lib/components/input-number-picker/input-number-picker.component.js +285 -285
  66. package/esm2015/lib/components/input-number-picker/input-number-picker.module.js +22 -22
  67. package/esm2015/lib/components/input-radio-button/input-radio-button.component.js +77 -77
  68. package/esm2015/lib/components/input-radio-button/input-radio-button.module.js +18 -18
  69. package/esm2015/lib/components/input-scanner/bar-code-scanner.js +22 -22
  70. package/esm2015/lib/components/input-scanner/input-scanner.component.js +56 -56
  71. package/esm2015/lib/components/input-scanner/input-scanner.module.js +20 -20
  72. package/esm2015/lib/components/input-scanner/scanner.service.js +27 -27
  73. package/esm2015/lib/components/input-search/input-search.component.js +67 -63
  74. package/esm2015/lib/components/input-search/input-search.module.js +20 -20
  75. package/esm2015/lib/components/input-text/input-text.component.js +192 -192
  76. package/esm2015/lib/components/input-text/input-text.module.js +32 -32
  77. package/esm2015/lib/components/input-textarea/input-textarea.component.js +55 -55
  78. package/esm2015/lib/components/input-textarea/input-textarea.module.js +26 -26
  79. package/esm2015/lib/components/level-indicator/level-indicator-level.enum.js +6 -6
  80. package/esm2015/lib/components/level-indicator/level-indicator.component.js +29 -29
  81. package/esm2015/lib/components/level-indicator/level-indicator.module.js +14 -14
  82. package/esm2015/lib/components/list-of-values/list-of-values-multiselect-popup.component.js +87 -87
  83. package/esm2015/lib/components/list-of-values/list-of-values-popup.component.js +218 -218
  84. package/esm2015/lib/components/list-of-values/list-of-values.component.js +199 -199
  85. package/esm2015/lib/components/list-of-values/list-of-values.module.js +37 -37
  86. package/esm2015/lib/components/loader/loader.component.js +16 -16
  87. package/esm2015/lib/components/loader/loader.module.js +18 -18
  88. package/esm2015/lib/components/pagination/paginate.pipe.js +98 -98
  89. package/esm2015/lib/components/pagination/pagination-instance.js +1 -1
  90. package/esm2015/lib/components/pagination/pagination.component.js +107 -107
  91. package/esm2015/lib/components/pagination/pagination.module.js +27 -27
  92. package/esm2015/lib/components/pagination/pagination.service.js +87 -87
  93. package/esm2015/lib/components/pagination-bar/pagination-bar.component.js +136 -136
  94. package/esm2015/lib/components/pagination-bar/pagination-bar.module.js +18 -18
  95. package/esm2015/lib/components/popup/const/popup-window-token.js +2 -2
  96. package/esm2015/lib/components/popup/interface/popup-button.js +7 -7
  97. package/esm2015/lib/components/popup/interface/popup-close-event.js +1 -1
  98. package/esm2015/lib/components/popup/interface/popup-settings.js +41 -41
  99. package/esm2015/lib/components/popup/interface/popup.js +1 -1
  100. package/esm2015/lib/components/popup/model/popup-button-globals.js +10 -10
  101. package/esm2015/lib/components/popup/model/popup-window.js +37 -37
  102. package/esm2015/lib/components/popup/popup-buttons.component.js +42 -42
  103. package/esm2015/lib/components/popup/popup-message-display.component.js +37 -37
  104. package/esm2015/lib/components/popup/popup-window-shell.component.js +141 -141
  105. package/esm2015/lib/components/popup/popup.module.js +48 -48
  106. package/esm2015/lib/components/popup/service/popup-shower.service.js +89 -89
  107. package/esm2015/lib/components/popup/service/prompt.service.js +126 -126
  108. package/esm2015/lib/components/popup/text-input-popup.component.js +33 -33
  109. package/esm2015/lib/components/responsive-text/responsive-text.component.js +17 -17
  110. package/esm2015/lib/components/responsive-text/responsive-text.module.js +18 -18
  111. package/esm2015/lib/components/simple-grid/base-simple-grid.component.js +163 -163
  112. package/esm2015/lib/components/simple-grid/simple-grid-cell.component.js +141 -141
  113. package/esm2015/lib/components/simple-grid/simple-grid-column.directive.js +110 -110
  114. package/esm2015/lib/components/simple-grid/simple-grid.component.js +378 -378
  115. package/esm2015/lib/components/simple-grid/simple-grid.module.js +40 -40
  116. package/esm2015/lib/components/tile/tile.component.js +44 -44
  117. package/esm2015/lib/components/tile/tile.module.js +22 -22
  118. package/esm2015/lib/components/tile-select/tile-select.component.js +26 -26
  119. package/esm2015/lib/components/tile-select/tile-select.module.js +20 -20
  120. package/esm2015/lib/components/tooltip/tooltip.component.js +74 -74
  121. package/esm2015/lib/components/tooltip/tooltip.module.js +18 -18
  122. package/esm2015/lib/components/validation-error/validation-error.component.js +30 -30
  123. package/esm2015/lib/components/validation-error/validation-error.module.js +24 -24
  124. package/esm2015/lib/components/view-mode-buttons/content-view-mode.enum.js +10 -10
  125. package/esm2015/lib/components/view-mode-buttons/view-mode-buttons.component.js +41 -41
  126. package/esm2015/lib/components/view-mode-buttons/view-mode-buttons.module.js +20 -20
  127. package/esm2015/lib/core/constant/default-upper-bound-for-range-components.js +3 -3
  128. package/esm2015/lib/core/constant/java-max-int.js +1 -1
  129. package/esm2015/lib/core/constant/number-inputs-key-down-white-list.js +44 -44
  130. package/esm2015/lib/core/decorator/input-boolean.decorator.js +33 -33
  131. package/esm2015/lib/core/enum/co-direction.js +8 -8
  132. package/esm2015/lib/core/enum/co-document-image-display-kind.enum.js +6 -6
  133. package/esm2015/lib/core/enum/co-document-type.enum.js +10 -10
  134. package/esm2015/lib/core/enum/co-orientation.js +16 -16
  135. package/esm2015/lib/core/enum/core-components-icon.enum.js +299 -299
  136. package/esm2015/lib/core/enum/file-type-internal.enum.js +16 -16
  137. package/esm2015/lib/core/enum/file-type.enum.js +10 -10
  138. package/esm2015/lib/core/enum/filterItem-mode.enum.js +42 -42
  139. package/esm2015/lib/core/enum/input-number-picker-show-mode.enum.js +7 -7
  140. package/esm2015/lib/core/enum/keyboard-code.enum.js +73 -73
  141. package/esm2015/lib/core/enum/keyboard-key.enum.js +75 -75
  142. package/esm2015/lib/core/enum/object-right-type.enum.js +6 -6
  143. package/esm2015/lib/core/enum/popup-button-type.enum.js +11 -11
  144. package/esm2015/lib/core/enum/popup-type.enum.js +10 -10
  145. package/esm2015/lib/core/enum/table-name.enum.js +80 -80
  146. package/esm2015/lib/core/function/any-nill.function.js +5 -5
  147. package/esm2015/lib/core/function/is-nill.function.js +4 -4
  148. package/esm2015/lib/core/function/none-nill.function.js +16 -16
  149. package/esm2015/lib/core/function/not-nill.function.js +4 -4
  150. package/esm2015/lib/core/model/bounds-constrained-number-value.js +170 -170
  151. package/esm2015/lib/core/model/check-precision-and-scale-result.js +1 -1
  152. package/esm2015/lib/core/model/check-within-stepped-bounds-result.js +1 -1
  153. package/esm2015/lib/core/model/co-document-right.bo.js +2 -2
  154. package/esm2015/lib/core/model/co-document.bo.js +120 -120
  155. package/esm2015/lib/core/model/core-components-icon-svg.js +298 -298
  156. package/esm2015/lib/core/model/element-position.js +9 -9
  157. package/esm2015/lib/core/model/event/string-prompt-result-event.js +7 -7
  158. package/esm2015/lib/core/service/form-input-user-change-listener.service.js +24 -24
  159. package/esm2015/lib/core/service/form-master.service.js +101 -101
  160. package/esm2015/lib/core/service/ng-zone-wrapper.service.js +19 -19
  161. package/esm2015/lib/core/utils/array-utils.js +263 -263
  162. package/esm2015/lib/core/utils/browser-utils.js +99 -99
  163. package/esm2015/lib/core/utils/direction-enum-utils.js +13 -13
  164. package/esm2015/lib/core/utils/event-utils.js +52 -52
  165. package/esm2015/lib/core/utils/file-utils.js +266 -266
  166. package/esm2015/lib/core/utils/number-utils.js +308 -308
  167. package/esm2015/lib/core/utils/object-utils.js +185 -185
  168. package/esm2015/lib/core/utils/string-utils.js +93 -93
  169. package/esm2015/lib/core/validator/email.validator.js +5 -5
  170. package/esm2015/lib/core/validator/equal.validator.js +10 -10
  171. package/esm2015/lib/core/validator/max-string-length.validator.js +9 -9
  172. package/esm2015/lib/core/validator/password.validator.js +30 -30
  173. package/esm2015/lib/core/validator/precision-scale.validator.js +10 -10
  174. package/esm2015/lib/core/validator/required.validator.js +4 -4
  175. package/esm2015/lib/directives/clickoutside/click-outside-master.service.js +56 -56
  176. package/esm2015/lib/directives/clickoutside/click-outside.directive.js +70 -70
  177. package/esm2015/lib/directives/clickoutside/clickoutside.module.js +18 -18
  178. package/esm2015/lib/directives/observe-visibility/observe-visibility.directive.js +52 -52
  179. package/esm2015/lib/directives/observe-visibility/observe-visibility.module.js +14 -14
  180. package/esm2015/lib/directives/overlay/overlay-parent.directive.js +18 -18
  181. package/esm2015/lib/directives/overlay/overlay.directive.js +160 -160
  182. package/esm2015/lib/directives/overlay/overlay.module.js +17 -17
  183. package/esm2015/lib/directives/ripple/ripple-ref.js +25 -25
  184. package/esm2015/lib/directives/ripple/ripple-renderer.js +159 -159
  185. package/esm2015/lib/directives/ripple/ripple.directive.js +79 -79
  186. package/esm2015/lib/directives/ripple/ripple.module.js +23 -23
  187. package/esm2015/lib/directives/ripple/scroll-dispatcher.service.js +107 -107
  188. package/esm2015/lib/directives/ripple/scrollable.directive.js +39 -39
  189. package/esm2015/lib/directives/ripple/viewport-ruler.service.js +72 -72
  190. package/esm2015/lib/directives/screen-configuration/screen-configuration.directive.js +157 -157
  191. package/esm2015/lib/directives/screen-configuration/screen-configuration.module.js +18 -18
  192. package/esm2015/lib/directives/stopclick/stop-click.directive.js +37 -37
  193. package/esm2015/lib/directives/stopclick/stop-click.module.js +14 -14
  194. package/esm2015/lib/directives/template-wrapper/template-wrapper.directive.js +67 -67
  195. package/esm2015/lib/directives/template-wrapper/template-wrapper.module.js +14 -14
  196. package/esm2015/lib/directives/tooltip/tooltip-directive.module.js +18 -18
  197. package/esm2015/lib/directives/tooltip/tooltip.directive.js +77 -77
  198. package/esm2015/lib/interfaces/dialog-response.interface.js +1 -1
  199. package/esm2015/lib/interfaces/scanner-input.interface.js +1 -1
  200. package/esm2015/lib/interfaces/screen-config-adapter-component-interface-name.js +3 -3
  201. package/esm2015/lib/interfaces/screen-config-adapter.component.interface.js +1 -1
  202. package/esm2015/lib/model/enum/app-button-type.enum.js +10 -10
  203. package/esm2015/lib/model/enum/app-popup-type.enum.js +7 -7
  204. package/esm2015/lib/pipes/append.pipe.js +16 -16
  205. package/esm2015/lib/pipes/append.pipe.module.js +14 -14
  206. package/esm2015/lib/pipes/filter.pipe.js +15 -15
  207. package/esm2015/lib/pipes/filter.pipe.module.js +14 -14
  208. package/esm2015/lib/pipes/prepend.pipe.js +16 -16
  209. package/esm2015/lib/pipes/prepend.pipe.module.js +14 -14
  210. package/esm2015/lib/pipes/price-display-pipe.module.js +14 -14
  211. package/esm2015/lib/pipes/price-display.pipe.js +19 -19
  212. package/esm2015/lib/service/base-module-screen-config.service.js +204 -204
  213. package/esm2015/lib/service/base-module.service.js +41 -41
  214. package/esm2015/lib/service/color-sequence.service.js +22 -22
  215. package/esm2015/lib/service/overlay.service.js +72 -72
  216. package/esm2015/lib/translation/core-components-translation.module.js +28 -28
  217. package/esm2015/lib/translation/core-components-translation.service.js +16 -16
  218. package/esm2015/lib/translation/core-dictionary.service.js +28 -28
  219. package/esm2015/lib/translation/core-localize.pipe.js +25 -25
  220. package/esm2015/public-api.js +129 -129
  221. package/fesm2015/colijnit-corecomponents_v12.js +12090 -12086
  222. package/fesm2015/colijnit-corecomponents_v12.js.map +1 -1
  223. package/lib/components/article-tile/article-tile.component.d.ts +22 -22
  224. package/lib/components/article-tile/article-tile.module.d.ts +2 -2
  225. package/lib/components/base/base-input.component.d.ts +182 -182
  226. package/lib/components/base/base.module.d.ts +2 -2
  227. package/lib/components/base/commit-buttons/commit-buttons.component.d.ts +21 -21
  228. package/lib/components/base/commit-buttons/commit-buttons.module.d.ts +2 -2
  229. package/lib/components/base/dialog-base.component.d.ts +4 -4
  230. package/lib/components/base-input-date-picker/base-input-date-picker.directive.d.ts +15 -15
  231. package/lib/components/button/button.component.d.ts +29 -29
  232. package/lib/components/button/button.module.d.ts +2 -2
  233. package/lib/components/calendar/calendar-template.component.d.ts +60 -60
  234. package/lib/components/calendar/calendar.component.d.ts +13 -13
  235. package/lib/components/calendar/calendar.module.d.ts +2 -2
  236. package/lib/components/card/card.component.d.ts +23 -23
  237. package/lib/components/card/card.module.d.ts +2 -2
  238. package/lib/components/carousel/carousel.component.d.ts +23 -23
  239. package/lib/components/carousel/carousel.module.d.ts +6 -6
  240. package/lib/components/carousel-3d/carousel-3d.component.d.ts +55 -55
  241. package/lib/components/carousel-3d/carousel-3d.module.d.ts +2 -2
  242. package/lib/components/carousel-3d/carouselItem.d.ts +13 -13
  243. package/lib/components/checkmark-overlay/checkmark-overlay.component.d.ts +17 -17
  244. package/lib/components/checkmark-overlay/checkmark-overlay.module.d.ts +2 -2
  245. package/lib/components/co-dialog/co-dialog.component.d.ts +23 -23
  246. package/lib/components/co-dialog/co-dialog.module.d.ts +2 -2
  247. package/lib/components/co-dialog-wizard/co-dialog-wizard.component.d.ts +9 -9
  248. package/lib/components/co-dialog-wizard/co-dialog-wizard.module.d.ts +2 -2
  249. package/lib/components/collapsible/collapsible.component.d.ts +22 -22
  250. package/lib/components/collapsible/collapsible.module.d.ts +2 -2
  251. package/lib/components/color-picker/color-picker.component.d.ts +6 -6
  252. package/lib/components/color-picker/color-picker.module.d.ts +2 -2
  253. package/lib/components/core-dialog/confirmation-dialog/confirmation-dialog.component.d.ts +20 -20
  254. package/lib/components/core-dialog/core-dialog.module.d.ts +4 -4
  255. package/lib/components/core-dialog/core-dialog.service.d.ts +15 -15
  256. package/lib/components/core-dialog/core-dynamic-component.service.d.ts +12 -12
  257. package/lib/components/double-calendar/double-calendar.component.d.ts +18 -18
  258. package/lib/components/double-calendar/double-calendar.module.d.ts +2 -2
  259. package/lib/components/filter-item/filter-item-viewmodel.d.ts +9 -9
  260. package/lib/components/filter-item/filter-item.component.d.ts +80 -80
  261. package/lib/components/filter-item/filter-item.module.d.ts +2 -2
  262. package/lib/components/filter-item/filter-viewmodel.d.ts +8 -8
  263. package/lib/components/form/form.component.d.ts +39 -39
  264. package/lib/components/form/form.module.d.ts +2 -2
  265. package/lib/components/grid-toolbar/grid-toolbar.component.d.ts +19 -19
  266. package/lib/components/grid-toolbar/grid-toolbar.module.d.ts +2 -2
  267. package/lib/components/grid-toolbar-button/grid-toolbar-button.component.d.ts +8 -8
  268. package/lib/components/grid-toolbar-button/grid-toolbar-button.module.d.ts +2 -2
  269. package/lib/components/icon/icon-cache.service.d.ts +20 -20
  270. package/lib/components/icon/icon.component.d.ts +17 -17
  271. package/lib/components/icon/icon.module.d.ts +2 -2
  272. package/lib/components/icon-collapse-handle/icon-collapse-handle.component.d.ts +21 -21
  273. package/lib/components/icon-collapse-handle/icon-collapse-handle.module.d.ts +2 -2
  274. package/lib/components/image/image.component.d.ts +20 -20
  275. package/lib/components/image/image.module.d.ts +2 -2
  276. package/lib/components/input-checkbox/input-checkbox.component.d.ts +24 -24
  277. package/lib/components/input-checkbox/input-checkbox.module.d.ts +2 -2
  278. package/lib/components/input-date-picker/input-date-picker.component.d.ts +12 -12
  279. package/lib/components/input-date-picker/input-date-picker.module.d.ts +2 -2
  280. package/lib/components/input-date-range-picker/input-date-range-picker.component.d.ts +20 -20
  281. package/lib/components/input-date-range-picker/input-date-range-picker.module.d.ts +2 -2
  282. package/lib/components/input-number-picker/input-number-picker.component.d.ts +73 -73
  283. package/lib/components/input-number-picker/input-number-picker.module.d.ts +2 -2
  284. package/lib/components/input-radio-button/input-radio-button.component.d.ts +19 -19
  285. package/lib/components/input-radio-button/input-radio-button.module.d.ts +2 -2
  286. package/lib/components/input-scanner/bar-code-scanner.d.ts +7 -7
  287. package/lib/components/input-scanner/input-scanner.component.d.ts +24 -24
  288. package/lib/components/input-scanner/input-scanner.module.d.ts +2 -2
  289. package/lib/components/input-scanner/scanner.service.d.ts +11 -11
  290. package/lib/components/input-search/input-search.component.d.ts +20 -19
  291. package/lib/components/input-search/input-search.module.d.ts +2 -2
  292. package/lib/components/input-text/input-text.component.d.ts +65 -65
  293. package/lib/components/input-text/input-text.module.d.ts +2 -2
  294. package/lib/components/input-textarea/input-textarea.component.d.ts +19 -19
  295. package/lib/components/input-textarea/input-textarea.module.d.ts +2 -2
  296. package/lib/components/level-indicator/level-indicator-level.enum.d.ts +5 -5
  297. package/lib/components/level-indicator/level-indicator.component.d.ts +10 -10
  298. package/lib/components/level-indicator/level-indicator.module.d.ts +2 -2
  299. package/lib/components/list-of-values/list-of-values-multiselect-popup.component.d.ts +25 -25
  300. package/lib/components/list-of-values/list-of-values-popup.component.d.ts +47 -47
  301. package/lib/components/list-of-values/list-of-values.component.d.ts +37 -37
  302. package/lib/components/list-of-values/list-of-values.module.d.ts +2 -2
  303. package/lib/components/loader/loader.component.d.ts +3 -3
  304. package/lib/components/loader/loader.module.d.ts +2 -2
  305. package/lib/components/pagination/paginate.pipe.d.ts +15 -15
  306. package/lib/components/pagination/pagination-instance.d.ts +14 -14
  307. package/lib/components/pagination/pagination.component.d.ts +38 -38
  308. package/lib/components/pagination/pagination.module.d.ts +2 -2
  309. package/lib/components/pagination/pagination.service.d.ts +24 -24
  310. package/lib/components/pagination-bar/pagination-bar.component.d.ts +33 -33
  311. package/lib/components/pagination-bar/pagination-bar.module.d.ts +2 -2
  312. package/lib/components/popup/const/popup-window-token.d.ts +3 -3
  313. package/lib/components/popup/interface/popup-button.d.ts +8 -8
  314. package/lib/components/popup/interface/popup-close-event.d.ts +5 -5
  315. package/lib/components/popup/interface/popup-settings.d.ts +21 -21
  316. package/lib/components/popup/interface/popup.d.ts +9 -9
  317. package/lib/components/popup/model/popup-button-globals.d.ts +9 -9
  318. package/lib/components/popup/model/popup-window.d.ts +21 -21
  319. package/lib/components/popup/popup-buttons.component.d.ts +13 -13
  320. package/lib/components/popup/popup-message-display.component.d.ts +12 -12
  321. package/lib/components/popup/popup-window-shell.component.d.ts +42 -42
  322. package/lib/components/popup/popup.module.d.ts +4 -4
  323. package/lib/components/popup/service/popup-shower.service.d.ts +17 -17
  324. package/lib/components/popup/service/prompt.service.d.ts +17 -17
  325. package/lib/components/popup/text-input-popup.component.d.ts +12 -12
  326. package/lib/components/responsive-text/responsive-text.component.d.ts +4 -4
  327. package/lib/components/responsive-text/responsive-text.module.d.ts +2 -2
  328. package/lib/components/simple-grid/base-simple-grid.component.d.ts +52 -52
  329. package/lib/components/simple-grid/simple-grid-cell.component.d.ts +30 -30
  330. package/lib/components/simple-grid/simple-grid-column.directive.d.ts +42 -42
  331. package/lib/components/simple-grid/simple-grid.component.d.ts +64 -64
  332. package/lib/components/simple-grid/simple-grid.module.d.ts +2 -2
  333. package/lib/components/tile/tile.component.d.ts +16 -16
  334. package/lib/components/tile/tile.module.d.ts +2 -2
  335. package/lib/components/tile-select/tile-select.component.d.ts +8 -8
  336. package/lib/components/tile-select/tile-select.module.d.ts +2 -2
  337. package/lib/components/tooltip/tooltip.component.d.ts +18 -18
  338. package/lib/components/tooltip/tooltip.module.d.ts +2 -2
  339. package/lib/components/validation-error/validation-error.component.d.ts +12 -12
  340. package/lib/components/validation-error/validation-error.module.d.ts +2 -2
  341. package/lib/components/view-mode-buttons/content-view-mode.enum.d.ts +8 -8
  342. package/lib/components/view-mode-buttons/view-mode-buttons.component.d.ts +17 -17
  343. package/lib/components/view-mode-buttons/view-mode-buttons.module.d.ts +2 -2
  344. package/lib/core/constant/default-upper-bound-for-range-components.d.ts +2 -2
  345. package/lib/core/constant/java-max-int.d.ts +1 -1
  346. package/lib/core/constant/number-inputs-key-down-white-list.d.ts +2 -2
  347. package/lib/core/decorator/input-boolean.decorator.d.ts +8 -8
  348. package/lib/core/enum/co-direction.d.ts +6 -6
  349. package/lib/core/enum/co-document-image-display-kind.enum.d.ts +5 -5
  350. package/lib/core/enum/co-document-type.enum.d.ts +5 -5
  351. package/lib/core/enum/co-orientation.d.ts +6 -6
  352. package/lib/core/enum/core-components-icon.enum.d.ts +298 -298
  353. package/lib/core/enum/file-type-internal.enum.d.ts +15 -15
  354. package/lib/core/enum/file-type.enum.d.ts +5 -5
  355. package/lib/core/enum/filterItem-mode.enum.d.ts +15 -15
  356. package/lib/core/enum/input-number-picker-show-mode.enum.d.ts +5 -5
  357. package/lib/core/enum/keyboard-code.enum.d.ts +71 -71
  358. package/lib/core/enum/keyboard-key.enum.d.ts +70 -70
  359. package/lib/core/enum/object-right-type.enum.d.ts +5 -5
  360. package/lib/core/enum/popup-button-type.enum.d.ts +9 -9
  361. package/lib/core/enum/popup-type.enum.d.ts +9 -9
  362. package/lib/core/enum/table-name.enum.d.ts +79 -79
  363. package/lib/core/function/any-nill.function.d.ts +1 -1
  364. package/lib/core/function/is-nill.function.d.ts +1 -1
  365. package/lib/core/function/none-nill.function.d.ts +1 -1
  366. package/lib/core/function/not-nill.function.d.ts +1 -1
  367. package/lib/core/model/bounds-constrained-number-value.d.ts +46 -46
  368. package/lib/core/model/check-precision-and-scale-result.d.ts +4 -4
  369. package/lib/core/model/check-within-stepped-bounds-result.d.ts +8 -8
  370. package/lib/core/model/co-document-right.bo.d.ts +6 -6
  371. package/lib/core/model/co-document.bo.d.ts +61 -61
  372. package/lib/core/model/core-components-icon-svg.d.ts +4 -4
  373. package/lib/core/model/element-position.d.ts +7 -7
  374. package/lib/core/model/event/string-prompt-result-event.d.ts +6 -6
  375. package/lib/core/service/form-input-user-change-listener.service.d.ts +10 -10
  376. package/lib/core/service/form-master.service.d.ts +26 -26
  377. package/lib/core/service/ng-zone-wrapper.service.d.ts +6 -6
  378. package/lib/core/utils/array-utils.d.ts +85 -85
  379. package/lib/core/utils/browser-utils.d.ts +15 -15
  380. package/lib/core/utils/direction-enum-utils.d.ts +5 -5
  381. package/lib/core/utils/event-utils.d.ts +12 -12
  382. package/lib/core/utils/file-utils.d.ts +29 -29
  383. package/lib/core/utils/number-utils.d.ts +89 -89
  384. package/lib/core/utils/object-utils.d.ts +31 -31
  385. package/lib/core/utils/string-utils.d.ts +25 -25
  386. package/lib/core/validator/email.validator.d.ts +2 -2
  387. package/lib/core/validator/equal.validator.d.ts +2 -2
  388. package/lib/core/validator/max-string-length.validator.d.ts +2 -2
  389. package/lib/core/validator/password.validator.d.ts +3 -3
  390. package/lib/core/validator/precision-scale.validator.d.ts +2 -2
  391. package/lib/core/validator/required.validator.d.ts +2 -2
  392. package/lib/directives/clickoutside/click-outside-master.service.d.ts +15 -15
  393. package/lib/directives/clickoutside/click-outside.directive.d.ts +18 -18
  394. package/lib/directives/clickoutside/clickoutside.module.d.ts +2 -2
  395. package/lib/directives/observe-visibility/observe-visibility.directive.d.ts +14 -14
  396. package/lib/directives/observe-visibility/observe-visibility.module.d.ts +2 -2
  397. package/lib/directives/overlay/overlay-parent.directive.d.ts +6 -6
  398. package/lib/directives/overlay/overlay.directive.d.ts +25 -25
  399. package/lib/directives/overlay/overlay.module.d.ts +2 -2
  400. package/lib/directives/ripple/ripple-ref.d.ts +21 -21
  401. package/lib/directives/ripple/ripple-renderer.d.ts +56 -56
  402. package/lib/directives/ripple/ripple.directive.d.ts +56 -56
  403. package/lib/directives/ripple/ripple.module.d.ts +2 -2
  404. package/lib/directives/ripple/scroll-dispatcher.service.d.ts +51 -51
  405. package/lib/directives/ripple/scrollable.directive.d.ts +20 -20
  406. package/lib/directives/ripple/viewport-ruler.service.d.ts +29 -29
  407. package/lib/directives/screen-configuration/screen-configuration.directive.d.ts +32 -32
  408. package/lib/directives/screen-configuration/screen-configuration.module.d.ts +2 -2
  409. package/lib/directives/stopclick/stop-click.directive.d.ts +10 -10
  410. package/lib/directives/stopclick/stop-click.module.d.ts +2 -2
  411. package/lib/directives/template-wrapper/template-wrapper.directive.d.ts +13 -13
  412. package/lib/directives/template-wrapper/template-wrapper.module.d.ts +2 -2
  413. package/lib/directives/tooltip/tooltip-directive.module.d.ts +2 -2
  414. package/lib/directives/tooltip/tooltip.directive.d.ts +20 -20
  415. package/lib/interfaces/dialog-response.interface.d.ts +6 -6
  416. package/lib/interfaces/scanner-input.interface.d.ts +3 -3
  417. package/lib/interfaces/screen-config-adapter-component-interface-name.d.ts +3 -3
  418. package/lib/interfaces/screen-config-adapter.component.interface.d.ts +10 -10
  419. package/lib/model/enum/app-button-type.enum.d.ts +9 -9
  420. package/lib/model/enum/app-popup-type.enum.d.ts +6 -6
  421. package/lib/pipes/append.pipe.d.ts +4 -4
  422. package/lib/pipes/append.pipe.module.d.ts +2 -2
  423. package/lib/pipes/filter.pipe.d.ts +4 -4
  424. package/lib/pipes/filter.pipe.module.d.ts +2 -2
  425. package/lib/pipes/prepend.pipe.d.ts +4 -4
  426. package/lib/pipes/prepend.pipe.module.d.ts +2 -2
  427. package/lib/pipes/price-display-pipe.module.d.ts +2 -2
  428. package/lib/pipes/price-display.pipe.d.ts +4 -4
  429. package/lib/service/base-module-screen-config.service.d.ts +47 -47
  430. package/lib/service/base-module.service.d.ts +22 -22
  431. package/lib/service/color-sequence.service.d.ts +4 -4
  432. package/lib/service/overlay.service.d.ts +13 -13
  433. package/lib/translation/core-components-translation.module.d.ts +4 -4
  434. package/lib/translation/core-components-translation.service.d.ts +6 -6
  435. package/lib/translation/core-dictionary.service.d.ts +12 -12
  436. package/lib/translation/core-localize.pipe.d.ts +7 -7
  437. package/package.json +1 -1
  438. package/public-api.d.ts +126 -126
@@ -1,309 +1,309 @@
1
- import { anyNill } from "../function/any-nill.function";
2
- import { ArrayUtils } from "./array-utils";
3
- import { isNill } from "../function/is-nill.function";
4
- import { ObjectUtils } from './object-utils';
5
- // @dynamic
6
- export class NumberUtils {
7
- // @returns The inclusive max value
8
- static PrecisionScaleToMaxValue(precision, scale) {
9
- const oneStep = this.DecimalsToStepIncrement(scale);
10
- const maxExclusive = Math.pow(10, precision - scale);
11
- return maxExclusive - oneStep;
12
- }
13
- // Parses given argument to an integer, using a native parseInt() function with a radix of 10. Returns NaN if parsing was not possible.
14
- static ParseInt(arg) {
15
- if (isNill(arg) || Array.isArray(arg)) {
16
- return undefined;
17
- }
18
- return parseInt(arg, 10);
19
- }
20
- static DecimalsToStepIncrement(numberOfDecimals) {
21
- return Math.pow(10, -1 * numberOfDecimals);
22
- }
23
- // Returns the given argument as a number. Returns given defaultValue if conversion of argument was impossible.
24
- static ParseNumberOrDefault(arg, defaultValue = 0) {
25
- if (Array.isArray(arg)) {
26
- return defaultValue;
27
- }
28
- if (!NumberUtils.IsNumber(arg)) {
29
- arg = parseFloat(arg);
30
- arg = isNaN(arg) ? defaultValue : arg;
31
- }
32
- return arg;
33
- }
34
- // Parses given numberInput to a number, or returns given defaultValue if parse not possible. Allows ',' char as decimal delimiter.
35
- static ParseNumberInputOrDefault(numberInput, defaultValue = 0) {
36
- return NumberUtils.ParseNumberOrDefault(NumberUtils._NumberInputToNumberStr(numberInput), defaultValue);
37
- }
38
- static IsParsableNumberInput(numberInput) {
39
- return NumberUtils.IsParsableNumber(NumberUtils._NumberInputToNumberStr(numberInput));
40
- }
41
- // Returns whether the type of given argument is 'number'.
42
- static IsNumber(arg) {
43
- return typeof arg === 'number';
44
- }
45
- // Returns whether the value is parasable as a number.
46
- static IsParsableNumber(arg) {
47
- if (Array.isArray(arg)) {
48
- return false;
49
- }
50
- return !isNaN(parseFloat(arg));
51
- }
52
- /**
53
- * Returns given arg as a float number with given decimal precision, if possible. Returns NaN if parse conversion failed.
54
- *
55
- * @param The argument to parse to a float
56
- * @param The number of decimals, or the precision, the parsed return float should have
57
- * @returns NaN if not possible, else the parsed float value
58
- */
59
- static ParseFloat(arg, decimalPrecision = 2) {
60
- if (anyNill(arg, decimalPrecision) || Array.isArray(arg)) {
61
- return NaN;
62
- }
63
- if (!NumberUtils.IsInteger(decimalPrecision) || decimalPrecision < 0) {
64
- decimalPrecision = 2;
65
- // toFixed() can only handle up until 20
66
- }
67
- else if (decimalPrecision > 20) {
68
- decimalPrecision = 20;
69
- }
70
- return parseFloat(parseFloat(arg).toFixed(decimalPrecision));
71
- }
72
- /**
73
- * Returns given arg as a float number with given decimal precision, if possible. Returns NaN if parse conversion failed.
74
- *
75
- * @param The argument to parse to a float
76
- * @returns The argument as a float with its original decimal precision intact
77
- */
78
- static ParseFloatKeepPrecision(arg) {
79
- let decimalPrecision = this.GetDecimalPlaces(arg);
80
- return this.ParseFloat(arg, decimalPrecision);
81
- }
82
- static ParseFloatNumberInputKeepPrecision(arg) {
83
- let correctedInputStr = NumberUtils._NumberInputToNumberStr(arg);
84
- let decimalPrecision = this.GetDecimalPlaces(correctedInputStr);
85
- return NumberUtils.ParseFloat(correctedInputStr, decimalPrecision);
86
- }
87
- /**
88
- * Finds the number closest to the originalNumber, that adheres to the given bounds. That is, for which it holds that
89
- * nr = min + N * step with N integer or 0.
90
- * @param originalNr Find closest answer to this number
91
- * @param min Inclusive
92
- * @param max Inclusive
93
- * @param stepSize
94
- * @returns The closest OK number for bounds.
95
- */
96
- static GetNearestNumberWithinSteppedBounds(originalNr, min, max, stepSize = 1) {
97
- if (originalNr < min) {
98
- return min;
99
- }
100
- else if (originalNr > max) {
101
- return NumberUtils.GetTrueSteppedBoundsMax(min, max, stepSize);
102
- }
103
- let boundsCheck = NumberUtils.CheckWithinSteppedBounds(originalNr, min, max, stepSize);
104
- if (boundsCheck.isOk) {
105
- return originalNr;
106
- }
107
- let answer = undefined;
108
- let remainder = boundsCheck.remainder;
109
- if (remainder) {
110
- // round up or down?
111
- if ((remainder / stepSize) < 0.5) {
112
- // round down, but not below min
113
- answer = (originalNr - remainder >= min ? originalNr - remainder : min);
114
- }
115
- else {
116
- // round up, but not above max
117
- answer = (originalNr + stepSize - remainder <= max ? originalNr + stepSize - remainder :
118
- NumberUtils.GetTrueSteppedBoundsMax(min, max, stepSize));
119
- }
120
- }
121
- else {
122
- // is this real life, why wasn't our stepped bounds check OK?
123
- answer = originalNr;
124
- }
125
- // 'correct' float errors
126
- answer = NumberUtils.ParseFloat(answer, NumberUtils._GetLargestDecimalPrecisionOf(originalNr, min, max, stepSize));
127
- return answer;
128
- }
129
- // Returns the number of decimal places of the given number. Returns 0 if no decimals whatsoever could be found on given arg.
130
- static GetDecimalPlaces(arg, maxAnswer = 1000) {
131
- let match = ('' + arg).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
132
- if (!match) {
133
- return 0;
134
- }
135
- let answer = Math.max(0,
136
- // number of digits right of decimal point.
137
- (match[1] ? match[1].length : 0)
138
- // adjust for scientific notation
139
- - (match[2] ? +match[2] : 0));
140
- if (answer > maxAnswer) {
141
- answer = maxAnswer;
142
- }
143
- return answer;
144
- }
145
- // Returns true iff given argument is an integer number. Returns false on non-numbers or numbers with significant decimals.
146
- static IsInteger(arg) {
147
- if (isNaN(arg) || Array.isArray(arg)) {
148
- return false;
149
- }
150
- let argAsFloat = parseFloat(arg);
151
- return ((argAsFloat | 0) === argAsFloat); // returns whether 'arg converted to an integer equals arg'
152
- }
153
- /**
154
- * Returns whether given arg is parseable as a number, and whether the lengts of its number parse result is equal to its original length.
155
- * I.e. this function returns FALSE with given number-parsable strings, but that have non-numeric appendices, eg '2233ff'. That arg
156
- * IS number-parseable, but not a strict 'string number', the latter being what this method actually checks for.
157
- */
158
- static IsStringNumber(arg) {
159
- if (!NumberUtils.IsParsableNumber(arg)) {
160
- return false;
161
- }
162
- else {
163
- return arg.toString().length === parseFloat(arg).toString().length;
164
- }
165
- }
166
- /**
167
- * Returns a random integer in range [lowerBound .. upperBound], an inclusive range. Returns NaN if not possible.
168
- * Given bounds are truncated first, before serving as the true lower- and upper bounds for the random int.
169
- */
170
- static RandomInt(lowerBoundInt, upperBoundInt) {
171
- if (!NumberUtils.IsNumber(lowerBoundInt) || !NumberUtils.IsNumber(upperBoundInt) || lowerBoundInt > upperBoundInt) {
172
- return NaN;
173
- }
174
- lowerBoundInt = Math.trunc(lowerBoundInt);
175
- upperBoundInt = Math.trunc(upperBoundInt);
176
- if (lowerBoundInt === upperBoundInt) {
177
- return lowerBoundInt;
178
- }
179
- const delta = upperBoundInt - lowerBoundInt;
180
- return (Math.round(Math.random() * delta) + lowerBoundInt);
181
- }
182
- /**
183
- * Returns the true maximum allowed value for the given "stepped bounds": min, stepSize and max, for which it holds that each allowed
184
- * value Y = min + stepSize * N, for any INTEGER or 0 N where it also holds, of course, that Y <= max.
185
- * @param min
186
- * @param max
187
- * @param stepSize
188
- */
189
- static GetTrueSteppedBoundsMax(min, max, stepSize = 1) {
190
- // solve max integer X in formula min + X * step <= max, and return min + X * stepSize for that X
191
- let maxSteps = Math.floor((max - min) / stepSize);
192
- // 'correct' float errors
193
- return NumberUtils.ParseFloat(min + maxSteps * stepSize, NumberUtils._GetLargestDecimalPrecisionOf(min, min, max));
194
- }
195
- // Returns the string representation of given number. If it's not a number, returns the empty string.
196
- static ToString(nr) {
197
- if (!NumberUtils.IsNaN(nr)) {
198
- return "" + nr;
199
- }
200
- else {
201
- return "";
202
- }
203
- }
204
- // Returns whether given arg is indeed not a number (it's NaN or it has another type than 'number').
205
- static IsNaN(arg) {
206
- return isNaN(arg) || !NumberUtils.IsNumber(arg);
207
- }
208
- /**
209
- * Returns whether given x is OK within the given min, max and step boundaries, where it should hold that nrToCheck = min + N * step,
210
- * with N integer or 0.
211
- * @param nrToCheck Number to check whether it's within the given bounds
212
- * @param min Inclusive
213
- * @param max Inclusive
214
- * @param stepSize
215
- * @returns Returns remainder of undefined when nrToCheck was OUTSIDE [min, max], else full result object.
216
- */
217
- static CheckWithinSteppedBounds(nrToCheck, min, max, stepSize = 1) {
218
- if (nrToCheck < min || nrToCheck > max) {
219
- return { isOk: false, remainder: undefined };
220
- }
221
- // we're in [min, max], but still check if nrToCheck = min + N * step holds (for N integer or 0)
222
- let remainder = (nrToCheck - min) % stepSize;
223
- // correct float for largest precision amongst input numbers
224
- remainder = NumberUtils.ParseFloat(remainder, NumberUtils._GetLargestDecimalPrecisionOf(nrToCheck, min, stepSize));
225
- return { isOk: (remainder === 0), remainder: remainder };
226
- }
227
- // Adds thousands comma's to given value, E.g. '1000' to '1,000'. Returns empty string if value was undefined.
228
- static AddThousandsCommasTo(value) {
229
- if (isNill(value)) {
230
- return "";
231
- }
232
- return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
233
- }
234
- // Returns the nearest number, relative to the given originalNr, that is within the given [min, max] inclusive bounds.
235
- static GetNearestNumberWithinBounds(originalNr, min, max) {
236
- let answer = originalNr;
237
- if (originalNr < min) {
238
- answer = min;
239
- }
240
- else if (originalNr > max) {
241
- answer = max;
242
- }
243
- return answer;
244
- }
245
- /**
246
- * Returns whether given nrToCheck is within the given precision and scale limits. Precision and scale, here, are Oracle DB terms.
247
- * This function can thus be used to check whether the given number is safe to send to the 'database' beforehand, if we know the
248
- * precision and scale of the number in the db declaration.
249
- *
250
- * I.e. A number declared in the Oracle DB as number(5, 2) has a precision of 5 and a scale of 2.
251
- *
252
- * @param nrToCheck
253
- * @param precision The number of significant digits, including possibly negative scale. E.g. 3 in '123' and 5 in '51.123'
254
- * @param [scale = 0] The number of significant digits AFTER the decimal point. E.g. 1 in 5432.1 and 3 in 54000.003
255
- * @returns Whether given nrToCheck is ok for given precision and scale, and if not, the
256
- * nearest number that IS ok for those constraints.
257
- */
258
- static CheckPrecisionAndScale(nrToCheck, precision, scale = 0) {
259
- // let's say any undefined number is checked OK, and all numbers are checked OK for an undefined precision
260
- if (!ObjectUtils.AllExist(nrToCheck, precision, scale)) {
261
- return { isOk: true, nearestOkNr: NaN };
262
- }
263
- // no number can have 0 or less than 0 significant digits, in our universe
264
- if (precision < 1 || precision - scale < 1) {
265
- return { isOk: false, nearestOkNr: NaN };
266
- }
267
- // begin check
268
- const isNegative = (nrToCheck < 0);
269
- const nrParts = nrToCheck.toString().split(".");
270
- // remove minus sign if negative
271
- if (isNegative) {
272
- nrParts[0] = nrParts[0].slice(1);
273
- }
274
- const numCountBeforeDot = nrParts[0].length;
275
- const allowedNumCountBeforeDot = precision - scale;
276
- if (numCountBeforeDot <= allowedNumCountBeforeDot) {
277
- return { isOk: true, nearestOkNr: nrToCheck };
278
- }
279
- else {
280
- // cut a part from the "before decimal number" so that the number is not too big anymore
281
- const numCountToRemove = numCountBeforeDot - allowedNumCountBeforeDot;
282
- // remove the right-most numbers before the decimal dot
283
- nrParts[0] = nrParts[0].slice(0, -1 * numCountToRemove);
284
- // add minus sign again if it was negative
285
- if (isNegative) {
286
- nrParts[0] = "-" + nrParts[0];
287
- }
288
- // build and return composite number again
289
- let nearestOkNr;
290
- if (nrParts[1]) {
291
- nearestOkNr = Number(nrParts[0] + "." + nrParts[1]);
292
- }
293
- else {
294
- nearestOkNr = Number(nrParts[0]);
295
- }
296
- return { isOk: false, nearestOkNr: nearestOkNr };
297
- }
298
- }
299
- static _GetLargestDecimalPrecisionOf(...args) {
300
- return ArrayUtils.GetMaxCalculatedValue(args, (arg) => {
301
- return NumberUtils.GetDecimalPlaces(arg);
302
- });
303
- }
304
- // Returns given number input as a number that's useable by Javascript. Allows for incoming ',' decimal delimiter.
305
- static _NumberInputToNumberStr(numberInput) {
306
- return (numberInput + '').replace(',', '.');
307
- }
308
- }
1
+ import { anyNill } from "../function/any-nill.function";
2
+ import { ArrayUtils } from "./array-utils";
3
+ import { isNill } from "../function/is-nill.function";
4
+ import { ObjectUtils } from './object-utils';
5
+ // @dynamic
6
+ export class NumberUtils {
7
+ // @returns The inclusive max value
8
+ static PrecisionScaleToMaxValue(precision, scale) {
9
+ const oneStep = this.DecimalsToStepIncrement(scale);
10
+ const maxExclusive = Math.pow(10, precision - scale);
11
+ return maxExclusive - oneStep;
12
+ }
13
+ // Parses given argument to an integer, using a native parseInt() function with a radix of 10. Returns NaN if parsing was not possible.
14
+ static ParseInt(arg) {
15
+ if (isNill(arg) || Array.isArray(arg)) {
16
+ return undefined;
17
+ }
18
+ return parseInt(arg, 10);
19
+ }
20
+ static DecimalsToStepIncrement(numberOfDecimals) {
21
+ return Math.pow(10, -1 * numberOfDecimals);
22
+ }
23
+ // Returns the given argument as a number. Returns given defaultValue if conversion of argument was impossible.
24
+ static ParseNumberOrDefault(arg, defaultValue = 0) {
25
+ if (Array.isArray(arg)) {
26
+ return defaultValue;
27
+ }
28
+ if (!NumberUtils.IsNumber(arg)) {
29
+ arg = parseFloat(arg);
30
+ arg = isNaN(arg) ? defaultValue : arg;
31
+ }
32
+ return arg;
33
+ }
34
+ // Parses given numberInput to a number, or returns given defaultValue if parse not possible. Allows ',' char as decimal delimiter.
35
+ static ParseNumberInputOrDefault(numberInput, defaultValue = 0) {
36
+ return NumberUtils.ParseNumberOrDefault(NumberUtils._NumberInputToNumberStr(numberInput), defaultValue);
37
+ }
38
+ static IsParsableNumberInput(numberInput) {
39
+ return NumberUtils.IsParsableNumber(NumberUtils._NumberInputToNumberStr(numberInput));
40
+ }
41
+ // Returns whether the type of given argument is 'number'.
42
+ static IsNumber(arg) {
43
+ return typeof arg === 'number';
44
+ }
45
+ // Returns whether the value is parasable as a number.
46
+ static IsParsableNumber(arg) {
47
+ if (Array.isArray(arg)) {
48
+ return false;
49
+ }
50
+ return !isNaN(parseFloat(arg));
51
+ }
52
+ /**
53
+ * Returns given arg as a float number with given decimal precision, if possible. Returns NaN if parse conversion failed.
54
+ *
55
+ * @param The argument to parse to a float
56
+ * @param The number of decimals, or the precision, the parsed return float should have
57
+ * @returns NaN if not possible, else the parsed float value
58
+ */
59
+ static ParseFloat(arg, decimalPrecision = 2) {
60
+ if (anyNill(arg, decimalPrecision) || Array.isArray(arg)) {
61
+ return NaN;
62
+ }
63
+ if (!NumberUtils.IsInteger(decimalPrecision) || decimalPrecision < 0) {
64
+ decimalPrecision = 2;
65
+ // toFixed() can only handle up until 20
66
+ }
67
+ else if (decimalPrecision > 20) {
68
+ decimalPrecision = 20;
69
+ }
70
+ return parseFloat(parseFloat(arg).toFixed(decimalPrecision));
71
+ }
72
+ /**
73
+ * Returns given arg as a float number with given decimal precision, if possible. Returns NaN if parse conversion failed.
74
+ *
75
+ * @param The argument to parse to a float
76
+ * @returns The argument as a float with its original decimal precision intact
77
+ */
78
+ static ParseFloatKeepPrecision(arg) {
79
+ let decimalPrecision = this.GetDecimalPlaces(arg);
80
+ return this.ParseFloat(arg, decimalPrecision);
81
+ }
82
+ static ParseFloatNumberInputKeepPrecision(arg) {
83
+ let correctedInputStr = NumberUtils._NumberInputToNumberStr(arg);
84
+ let decimalPrecision = this.GetDecimalPlaces(correctedInputStr);
85
+ return NumberUtils.ParseFloat(correctedInputStr, decimalPrecision);
86
+ }
87
+ /**
88
+ * Finds the number closest to the originalNumber, that adheres to the given bounds. That is, for which it holds that
89
+ * nr = min + N * step with N integer or 0.
90
+ * @param originalNr Find closest answer to this number
91
+ * @param min Inclusive
92
+ * @param max Inclusive
93
+ * @param stepSize
94
+ * @returns The closest OK number for bounds.
95
+ */
96
+ static GetNearestNumberWithinSteppedBounds(originalNr, min, max, stepSize = 1) {
97
+ if (originalNr < min) {
98
+ return min;
99
+ }
100
+ else if (originalNr > max) {
101
+ return NumberUtils.GetTrueSteppedBoundsMax(min, max, stepSize);
102
+ }
103
+ let boundsCheck = NumberUtils.CheckWithinSteppedBounds(originalNr, min, max, stepSize);
104
+ if (boundsCheck.isOk) {
105
+ return originalNr;
106
+ }
107
+ let answer = undefined;
108
+ let remainder = boundsCheck.remainder;
109
+ if (remainder) {
110
+ // round up or down?
111
+ if ((remainder / stepSize) < 0.5) {
112
+ // round down, but not below min
113
+ answer = (originalNr - remainder >= min ? originalNr - remainder : min);
114
+ }
115
+ else {
116
+ // round up, but not above max
117
+ answer = (originalNr + stepSize - remainder <= max ? originalNr + stepSize - remainder :
118
+ NumberUtils.GetTrueSteppedBoundsMax(min, max, stepSize));
119
+ }
120
+ }
121
+ else {
122
+ // is this real life, why wasn't our stepped bounds check OK?
123
+ answer = originalNr;
124
+ }
125
+ // 'correct' float errors
126
+ answer = NumberUtils.ParseFloat(answer, NumberUtils._GetLargestDecimalPrecisionOf(originalNr, min, max, stepSize));
127
+ return answer;
128
+ }
129
+ // Returns the number of decimal places of the given number. Returns 0 if no decimals whatsoever could be found on given arg.
130
+ static GetDecimalPlaces(arg, maxAnswer = 1000) {
131
+ let match = ('' + arg).match(/(?:\.(\d+))?(?:[eE]([+-]?\d+))?$/);
132
+ if (!match) {
133
+ return 0;
134
+ }
135
+ let answer = Math.max(0,
136
+ // number of digits right of decimal point.
137
+ (match[1] ? match[1].length : 0)
138
+ // adjust for scientific notation
139
+ - (match[2] ? +match[2] : 0));
140
+ if (answer > maxAnswer) {
141
+ answer = maxAnswer;
142
+ }
143
+ return answer;
144
+ }
145
+ // Returns true iff given argument is an integer number. Returns false on non-numbers or numbers with significant decimals.
146
+ static IsInteger(arg) {
147
+ if (isNaN(arg) || Array.isArray(arg)) {
148
+ return false;
149
+ }
150
+ let argAsFloat = parseFloat(arg);
151
+ return ((argAsFloat | 0) === argAsFloat); // returns whether 'arg converted to an integer equals arg'
152
+ }
153
+ /**
154
+ * Returns whether given arg is parseable as a number, and whether the lengts of its number parse result is equal to its original length.
155
+ * I.e. this function returns FALSE with given number-parsable strings, but that have non-numeric appendices, eg '2233ff'. That arg
156
+ * IS number-parseable, but not a strict 'string number', the latter being what this method actually checks for.
157
+ */
158
+ static IsStringNumber(arg) {
159
+ if (!NumberUtils.IsParsableNumber(arg)) {
160
+ return false;
161
+ }
162
+ else {
163
+ return arg.toString().length === parseFloat(arg).toString().length;
164
+ }
165
+ }
166
+ /**
167
+ * Returns a random integer in range [lowerBound .. upperBound], an inclusive range. Returns NaN if not possible.
168
+ * Given bounds are truncated first, before serving as the true lower- and upper bounds for the random int.
169
+ */
170
+ static RandomInt(lowerBoundInt, upperBoundInt) {
171
+ if (!NumberUtils.IsNumber(lowerBoundInt) || !NumberUtils.IsNumber(upperBoundInt) || lowerBoundInt > upperBoundInt) {
172
+ return NaN;
173
+ }
174
+ lowerBoundInt = Math.trunc(lowerBoundInt);
175
+ upperBoundInt = Math.trunc(upperBoundInt);
176
+ if (lowerBoundInt === upperBoundInt) {
177
+ return lowerBoundInt;
178
+ }
179
+ const delta = upperBoundInt - lowerBoundInt;
180
+ return (Math.round(Math.random() * delta) + lowerBoundInt);
181
+ }
182
+ /**
183
+ * Returns the true maximum allowed value for the given "stepped bounds": min, stepSize and max, for which it holds that each allowed
184
+ * value Y = min + stepSize * N, for any INTEGER or 0 N where it also holds, of course, that Y <= max.
185
+ * @param min
186
+ * @param max
187
+ * @param stepSize
188
+ */
189
+ static GetTrueSteppedBoundsMax(min, max, stepSize = 1) {
190
+ // solve max integer X in formula min + X * step <= max, and return min + X * stepSize for that X
191
+ let maxSteps = Math.floor((max - min) / stepSize);
192
+ // 'correct' float errors
193
+ return NumberUtils.ParseFloat(min + maxSteps * stepSize, NumberUtils._GetLargestDecimalPrecisionOf(min, min, max));
194
+ }
195
+ // Returns the string representation of given number. If it's not a number, returns the empty string.
196
+ static ToString(nr) {
197
+ if (!NumberUtils.IsNaN(nr)) {
198
+ return "" + nr;
199
+ }
200
+ else {
201
+ return "";
202
+ }
203
+ }
204
+ // Returns whether given arg is indeed not a number (it's NaN or it has another type than 'number').
205
+ static IsNaN(arg) {
206
+ return isNaN(arg) || !NumberUtils.IsNumber(arg);
207
+ }
208
+ /**
209
+ * Returns whether given x is OK within the given min, max and step boundaries, where it should hold that nrToCheck = min + N * step,
210
+ * with N integer or 0.
211
+ * @param nrToCheck Number to check whether it's within the given bounds
212
+ * @param min Inclusive
213
+ * @param max Inclusive
214
+ * @param stepSize
215
+ * @returns Returns remainder of undefined when nrToCheck was OUTSIDE [min, max], else full result object.
216
+ */
217
+ static CheckWithinSteppedBounds(nrToCheck, min, max, stepSize = 1) {
218
+ if (nrToCheck < min || nrToCheck > max) {
219
+ return { isOk: false, remainder: undefined };
220
+ }
221
+ // we're in [min, max], but still check if nrToCheck = min + N * step holds (for N integer or 0)
222
+ let remainder = (nrToCheck - min) % stepSize;
223
+ // correct float for largest precision amongst input numbers
224
+ remainder = NumberUtils.ParseFloat(remainder, NumberUtils._GetLargestDecimalPrecisionOf(nrToCheck, min, stepSize));
225
+ return { isOk: (remainder === 0), remainder: remainder };
226
+ }
227
+ // Adds thousands comma's to given value, E.g. '1000' to '1,000'. Returns empty string if value was undefined.
228
+ static AddThousandsCommasTo(value) {
229
+ if (isNill(value)) {
230
+ return "";
231
+ }
232
+ return value.toString().replace(/\B(?=(\d{3})+(?!\d))/g, ",");
233
+ }
234
+ // Returns the nearest number, relative to the given originalNr, that is within the given [min, max] inclusive bounds.
235
+ static GetNearestNumberWithinBounds(originalNr, min, max) {
236
+ let answer = originalNr;
237
+ if (originalNr < min) {
238
+ answer = min;
239
+ }
240
+ else if (originalNr > max) {
241
+ answer = max;
242
+ }
243
+ return answer;
244
+ }
245
+ /**
246
+ * Returns whether given nrToCheck is within the given precision and scale limits. Precision and scale, here, are Oracle DB terms.
247
+ * This function can thus be used to check whether the given number is safe to send to the 'database' beforehand, if we know the
248
+ * precision and scale of the number in the db declaration.
249
+ *
250
+ * I.e. A number declared in the Oracle DB as number(5, 2) has a precision of 5 and a scale of 2.
251
+ *
252
+ * @param nrToCheck
253
+ * @param precision The number of significant digits, including possibly negative scale. E.g. 3 in '123' and 5 in '51.123'
254
+ * @param [scale = 0] The number of significant digits AFTER the decimal point. E.g. 1 in 5432.1 and 3 in 54000.003
255
+ * @returns Whether given nrToCheck is ok for given precision and scale, and if not, the
256
+ * nearest number that IS ok for those constraints.
257
+ */
258
+ static CheckPrecisionAndScale(nrToCheck, precision, scale = 0) {
259
+ // let's say any undefined number is checked OK, and all numbers are checked OK for an undefined precision
260
+ if (!ObjectUtils.AllExist(nrToCheck, precision, scale)) {
261
+ return { isOk: true, nearestOkNr: NaN };
262
+ }
263
+ // no number can have 0 or less than 0 significant digits, in our universe
264
+ if (precision < 1 || precision - scale < 1) {
265
+ return { isOk: false, nearestOkNr: NaN };
266
+ }
267
+ // begin check
268
+ const isNegative = (nrToCheck < 0);
269
+ const nrParts = nrToCheck.toString().split(".");
270
+ // remove minus sign if negative
271
+ if (isNegative) {
272
+ nrParts[0] = nrParts[0].slice(1);
273
+ }
274
+ const numCountBeforeDot = nrParts[0].length;
275
+ const allowedNumCountBeforeDot = precision - scale;
276
+ if (numCountBeforeDot <= allowedNumCountBeforeDot) {
277
+ return { isOk: true, nearestOkNr: nrToCheck };
278
+ }
279
+ else {
280
+ // cut a part from the "before decimal number" so that the number is not too big anymore
281
+ const numCountToRemove = numCountBeforeDot - allowedNumCountBeforeDot;
282
+ // remove the right-most numbers before the decimal dot
283
+ nrParts[0] = nrParts[0].slice(0, -1 * numCountToRemove);
284
+ // add minus sign again if it was negative
285
+ if (isNegative) {
286
+ nrParts[0] = "-" + nrParts[0];
287
+ }
288
+ // build and return composite number again
289
+ let nearestOkNr;
290
+ if (nrParts[1]) {
291
+ nearestOkNr = Number(nrParts[0] + "." + nrParts[1]);
292
+ }
293
+ else {
294
+ nearestOkNr = Number(nrParts[0]);
295
+ }
296
+ return { isOk: false, nearestOkNr: nearestOkNr };
297
+ }
298
+ }
299
+ static _GetLargestDecimalPrecisionOf(...args) {
300
+ return ArrayUtils.GetMaxCalculatedValue(args, (arg) => {
301
+ return NumberUtils.GetDecimalPlaces(arg);
302
+ });
303
+ }
304
+ // Returns given number input as a number that's useable by Javascript. Allows for incoming ',' decimal delimiter.
305
+ static _NumberInputToNumberStr(numberInput) {
306
+ return (numberInput + '').replace(',', '.');
307
+ }
308
+ }
309
309
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibnVtYmVyLXV0aWxzLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY29yZWNvbXBvbmVudHMvc3JjL2xpYi9jb3JlL3V0aWxzL251bWJlci11dGlscy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sK0JBQStCLENBQUM7QUFDdEQsT0FBTyxFQUFDLFVBQVUsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUV6QyxPQUFPLEVBQUMsTUFBTSxFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFDcEQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRzdDLFdBQVc7QUFDWCxNQUFNLE9BQU8sV0FBVztJQUNwQixtQ0FBbUM7SUFDNUIsTUFBTSxDQUFDLHdCQUF3QixDQUFDLFNBQWlCLEVBQUUsS0FBYTtRQUNuRSxNQUFNLE9BQU8sR0FBVyxJQUFJLENBQUMsdUJBQXVCLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUQsTUFBTSxZQUFZLEdBQVcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsU0FBUyxHQUFHLEtBQUssQ0FBQyxDQUFDO1FBQzdELE9BQU8sWUFBWSxHQUFHLE9BQU8sQ0FBQztJQUNsQyxDQUFDO0lBRUQsdUlBQXVJO0lBQ2hJLE1BQU0sQ0FBQyxRQUFRLENBQUMsR0FBUTtRQUMzQixJQUFJLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ25DLE9BQU8sU0FBUyxDQUFDO1NBQ3BCO1FBRUQsT0FBTyxRQUFRLENBQUMsR0FBRyxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQzdCLENBQUM7SUFFTSxNQUFNLENBQUMsdUJBQXVCLENBQUMsZ0JBQXdCO1FBQzFELE9BQU8sSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsZ0JBQWdCLENBQUMs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RyxHQUFHLEdBQUcsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDdkQ7aUJBQU07Z0JBQ0gsV0FBVyxHQUFHLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQzthQUNwQztZQUNELE9BQU8sRUFBQyxJQUFJLEVBQUUsS0FBSyxFQUFFLFdBQVcsRUFBRSxXQUFXLEVBQUMsQ0FBQztTQUNsRDtJQUNMLENBQUM7SUFFTyxNQUFNLENBQUMsNkJBQTZCLENBQUMsR0FBRyxJQUFjO1FBQzFELE9BQU8sVUFBVSxDQUFDLHFCQUFxQixDQUFDLElBQUksRUFBRSxDQUFDLEdBQVcsRUFBRSxFQUFFO1lBQzFELE9BQU8sV0FBVyxDQUFDLGdCQUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQzdDLENBQUMsQ0FBQyxDQUFDO0lBQ1AsQ0FBQztJQUVELGtIQUFrSDtJQUMxRyxNQUFNLENBQUMsdUJBQXVCLENBQUMsV0FBbUI7UUFDdEQsT0FBTyxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsR0FBRyxFQUFFLEdBQUcsQ0FBQyxDQUFDO0lBQ2hELENBQUM7Q0FDSiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7YW55TmlsbH0gZnJvbSBcIi4uL2Z1bmN0aW9uL2FueS1uaWxsLmZ1bmN0aW9uXCI7XHJcbmltcG9ydCB7QXJyYXlVdGlsc30gZnJvbSBcIi4vYXJyYXktdXRpbHNcIjtcclxuaW1wb3J0IHtDaGVja1dpdGhpblN0ZXBwZWRCb3VuZHNSZXN1bHR9IGZyb20gXCIuLi9tb2RlbC9jaGVjay13aXRoaW4tc3RlcHBlZC1ib3VuZHMtcmVzdWx0XCI7XHJcbmltcG9ydCB7aXNOaWxsfSBmcm9tIFwiLi4vZnVuY3Rpb24vaXMtbmlsbC5mdW5jdGlvblwiO1xyXG5pbXBvcnQgeyBPYmplY3RVdGlscyB9IGZyb20gJy4vb2JqZWN0LXV0aWxzJztcclxuaW1wb3J0IHsgQ2hlY2tQcmVjaXNpb25BbmRTY2FsZVJlc3VsdCB9IGZyb20gJy4uL21vZGVsL2NoZWNrLXByZWNpc2lvbi1hbmQtc2NhbGUtcmVzdWx0JztcclxuXHJcbi8vIEBkeW5hbWljXHJcbmV4cG9ydCBjbGFzcyBOdW1iZXJVdGlscyB7XHJcbiAgICAvLyBAcmV0dXJucyBUaGUgaW5jbHVzaXZlIG1heCB2YWx1ZVxyXG4gICAgcHVibGljIHN0YXRpYyBQcmVjaXNpb25TY2FsZVRvTWF4VmFsdWUocHJlY2lzaW9uOiBudW1iZXIsIHNjYWxlOiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIGNvbnN0IG9uZVN0ZXA6IG51bWJlciA9IHRoaXMuRGVjaW1hbHNUb1N0ZXBJbmNyZW1lbnQoc2NhbGUpO1xyXG4gICAgICAgIGNvbnN0IG1heEV4Y2x1c2l2ZTogbnVtYmVyID0gTWF0aC5wb3coMTAsIHByZWNpc2lvbiAtIHNjYWxlKTtcclxuICAgICAgICByZXR1cm4gbWF4RXhjbHVzaXZlIC0gb25lU3RlcDtcclxuICAgIH1cclxuXHJcbiAgICAvLyBQYXJzZXMgZ2l2ZW4gYXJndW1lbnQgdG8gYW4gaW50ZWdlciwgdXNpbmcgYSBuYXRpdmUgcGFyc2VJbnQoKSBmdW5jdGlvbiB3aXRoIGEgcmFkaXggb2YgMTAuIFJldHVybnMgTmFOIGlmIHBhcnNpbmcgd2FzIG5vdCBwb3NzaWJsZS5cclxuICAgIHB1YmxpYyBzdGF0aWMgUGFyc2VJbnQoYXJnOiBhbnkpOiBudW1iZXIge1xyXG4gICAgICAgIGlmIChpc05pbGwoYXJnKSB8fCBBcnJheS5pc0FycmF5KGFyZykpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiBwYXJzZUludChhcmcsIDEwKTtcclxuICAgIH1cclxuXHJcbiAgICBwdWJsaWMgc3RhdGljIERlY2ltYWxzVG9TdGVwSW5jcmVtZW50KG51bWJlck9mRGVjaW1hbHM6IG51bWJlcik6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIE1hdGgucG93KDEwLCAtMSAqIG51bWJlck9mRGVjaW1hbHMpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJldHVybnMgdGhlIGdpdmVuIGFyZ3VtZW50IGFzIGEgbnVtYmVyLiBSZXR1cm5zIGdpdmVuIGRlZmF1bHRWYWx1ZSBpZiBjb252ZXJzaW9uIG9mIGFyZ3VtZW50IHdhcyBpbXBvc3NpYmxlLlxyXG4gICAgcHVibGljIHN0YXRpYyBQYXJzZU51bWJlck9yRGVmYXVsdChhcmc6IGFueSwgZGVmYXVsdFZhbHVlOiBudW1iZXIgPSAwKTogbnVtYmVyIHtcclxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBkZWZhdWx0VmFsdWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBpZiAoIU51bWJlclV0aWxzLklzTnVtYmVyKGFyZykpIHtcclxuICAgICAgICAgICAgYXJnID0gcGFyc2VGbG9hdChhcmcpO1xyXG4gICAgICAgICAgICBhcmcgPSBpc05hTihhcmcpID8gZGVmYXVsdFZhbHVlIDogYXJnO1xyXG4gICAgICAgIH1cclxuICAgICAgICByZXR1cm4gYXJnO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFBhcnNlcyBnaXZlbiBudW1iZXJJbnB1dCB0byBhIG51bWJlciwgb3IgcmV0dXJucyBnaXZlbiBkZWZhdWx0VmFsdWUgaWYgcGFyc2Ugbm90IHBvc3NpYmxlLiBBbGxvd3MgJywnIGNoYXIgYXMgZGVjaW1hbCBkZWxpbWl0ZXIuXHJcbiAgICBwdWJsaWMgc3RhdGljIFBhcnNlTnVtYmVySW5wdXRPckRlZmF1bHQobnVtYmVySW5wdXQ6IGFueSwgZGVmYXVsdFZhbHVlOiBudW1iZXIgPSAwKTogbnVtYmVyIHtcclxuICAgICAgICByZXR1cm4gTnVtYmVyVXRpbHMuUGFyc2VOdW1iZXJPckRlZmF1bHQoTnVtYmVyVXRpbHMuX051bWJlcklucHV0VG9OdW1iZXJTdHIobnVtYmVySW5wdXQpLCBkZWZhdWx0VmFsdWUpO1xyXG4gICAgfVxyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgSXNQYXJzYWJsZU51bWJlcklucHV0KG51bWJlcklucHV0OiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gTnVtYmVyVXRpbHMuSXNQYXJzYWJsZU51bWJlcihOdW1iZXJVdGlscy5fTnVtYmVySW5wdXRUb051bWJlclN0cihudW1iZXJJbnB1dCkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJldHVybnMgd2hldGhlciB0aGUgdHlwZSBvZiBnaXZlbiBhcmd1bWVudCBpcyAnbnVtYmVyJy5cclxuICAgIHB1YmxpYyBzdGF0aWMgSXNOdW1iZXIoYXJnOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gdHlwZW9mIGFyZyA9PT0gJ251bWJlcic7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmV0dXJucyB3aGV0aGVyIHRoZSB2YWx1ZSBpcyBwYXJhc2FibGUgYXMgYSBudW1iZXIuXHJcbiAgICBwdWJsaWMgc3RhdGljIElzUGFyc2FibGVOdW1iZXIoYXJnOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoQXJyYXkuaXNBcnJheShhcmcpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiAhaXNOYU4ocGFyc2VGbG9hdChhcmcpKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgZ2l2ZW4gYXJnIGFzIGEgZmxvYXQgbnVtYmVyIHdpdGggZ2l2ZW4gZGVjaW1hbCBwcmVjaXNpb24sIGlmIHBvc3NpYmxlLiBSZXR1cm5zIE5hTiBpZiBwYXJzZSBjb252ZXJzaW9uIGZhaWxlZC5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gVGhlIGFyZ3VtZW50IHRvIHBhcnNlIHRvIGEgZmxvYXRcclxuICAgICAqIEBwYXJhbSBUaGUgbnVtYmVyIG9mIGRlY2ltYWxzLCBvciB0aGUgcHJlY2lzaW9uLCB0aGUgcGFyc2VkIHJldHVybiBmbG9hdCBzaG91bGQgaGF2ZVxyXG4gICAgICogQHJldHVybnMgTmFOIGlmIG5vdCBwb3NzaWJsZSwgZWxzZSB0aGUgcGFyc2VkIGZsb2F0IHZhbHVlXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgUGFyc2VGbG9hdChhcmc6IGFueSwgZGVjaW1hbFByZWNpc2lvbjogbnVtYmVyID0gMik6IG51bWJlciB7XHJcbiAgICAgICAgaWYgKGFueU5pbGwoYXJnLCBkZWNpbWFsUHJlY2lzaW9uKSB8fCBBcnJheS5pc0FycmF5KGFyZykpIHtcclxuICAgICAgICAgICAgcmV0dXJuIE5hTjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGlmICghTnVtYmVyVXRpbHMuSXNJbnRlZ2VyKGRlY2ltYWxQcmVjaXNpb24pIHx8IGRlY2ltYWxQcmVjaXNpb24gPCAwKSB7XHJcbiAgICAgICAgICAgIGRlY2ltYWxQcmVjaXNpb24gPSAyO1xyXG4gICAgICAgICAgICAvLyB0b0ZpeGVkKCkgY2FuIG9ubHkgaGFuZGxlIHVwIHVudGlsIDIwXHJcbiAgICAgICAgfSBlbHNlIGlmIChkZWNpbWFsUHJlY2lzaW9uID4gMjApIHtcclxuICAgICAgICAgICAgZGVjaW1hbFByZWNpc2lvbiA9IDIwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIHBhcnNlRmxvYXQocGFyc2VGbG9hdChhcmcpLnRvRml4ZWQoZGVjaW1hbFByZWNpc2lvbikpO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBnaXZlbiBhcmcgYXMgYSBmbG9hdCBudW1iZXIgd2l0aCBnaXZlbiBkZWNpbWFsIHByZWNpc2lvbiwgaWYgcG9zc2libGUuIFJldHVybnMgTmFOIGlmIHBhcnNlIGNvbnZlcnNpb24gZmFpbGVkLlxyXG4gICAgICpcclxuICAgICAqIEBwYXJhbSBUaGUgYXJndW1lbnQgdG8gcGFyc2UgdG8gYSBmbG9hdFxyXG4gICAgICogQHJldHVybnMgVGhlIGFyZ3VtZW50IGFzIGEgZmxvYXQgd2l0aCBpdHMgb3JpZ2luYWwgZGVjaW1hbCBwcmVjaXNpb24gaW50YWN0XHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgUGFyc2VGbG9hdEtlZXBQcmVjaXNpb24oYXJnOiBhbnkpOiBudW1iZXIge1xyXG4gICAgICAgIGxldCBkZWNpbWFsUHJlY2lzaW9uOiBudW1iZXIgPSB0aGlzLkdldERlY2ltYWxQbGFjZXMoYXJnKTtcclxuICAgICAgICByZXR1cm4gdGhpcy5QYXJzZUZsb2F0KGFyZywgZGVjaW1hbFByZWNpc2lvbik7XHJcbiAgICB9XHJcblxyXG4gICAgcHVibGljIHN0YXRpYyBQYXJzZUZsb2F0TnVtYmVySW5wdXRLZWVwUHJlY2lzaW9uKGFyZzogYW55KTogbnVtYmVyIHtcclxuICAgICAgICBsZXQgY29ycmVjdGVkSW5wdXRTdHI6IHN0cmluZyA9IE51bWJlclV0aWxzLl9OdW1iZXJJbnB1dFRvTnVtYmVyU3RyKGFyZyk7XHJcbiAgICAgICAgbGV0IGRlY2ltYWxQcmVjaXNpb246IG51bWJlciA9IHRoaXMuR2V0RGVjaW1hbFBsYWNlcyhjb3JyZWN0ZWRJbnB1dFN0cik7XHJcbiAgICAgICAgcmV0dXJuIE51bWJlclV0aWxzLlBhcnNlRmxvYXQoY29ycmVjdGVkSW5wdXRTdHIsIGRlY2ltYWxQcmVjaXNpb24pO1xyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogRmluZHMgdGhlIG51bWJlciBjbG9zZXN0IHRvIHRoZSBvcmlnaW5hbE51bWJlciwgdGhhdCBhZGhlcmVzIHRvIHRoZSBnaXZlbiBib3VuZHMuIFRoYXQgaXMsIGZvciB3aGljaCBpdCBob2xkcyB0aGF0XHJcbiAgICAgKiBuciA9IG1pbiArIE4gKiBzdGVwIHdpdGggTiBpbnRlZ2VyIG9yIDAuXHJcbiAgICAgKiBAcGFyYW0gb3JpZ2luYWxOciBGaW5kIGNsb3Nlc3QgYW5zd2VyIHRvIHRoaXMgbnVtYmVyXHJcbiAgICAgKiBAcGFyYW0gbWluIEluY2x1c2l2ZVxyXG4gICAgICogQHBhcmFtIG1heCBJbmNsdXNpdmVcclxuICAgICAqIEBwYXJhbSBzdGVwU2l6ZVxyXG4gICAgICogQHJldHVybnMgVGhlIGNsb3Nlc3QgT0sgbnVtYmVyIGZvciBib3VuZHMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0TmVhcmVzdE51bWJlcldpdGhpblN0ZXBwZWRCb3VuZHMob3JpZ2luYWxOcjogbnVtYmVyLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIsIHN0ZXBTaXplOiBudW1iZXIgPSAxKTogbnVtYmVyIHtcclxuICAgICAgICBpZiAob3JpZ2luYWxOciA8IG1pbikge1xyXG4gICAgICAgICAgICByZXR1cm4gbWluO1xyXG4gICAgICAgIH0gZWxzZSBpZiAob3JpZ2luYWxOciA+IG1heCkge1xyXG4gICAgICAgICAgICByZXR1cm4gTnVtYmVyVXRpbHMuR2V0VHJ1ZVN0ZXBwZWRCb3VuZHNNYXgobWluLCBtYXgsIHN0ZXBTaXplKTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIGxldCBib3VuZHNDaGVjazogQ2hlY2tXaXRoaW5TdGVwcGVkQm91bmRzUmVzdWx0ID0gTnVtYmVyVXRpbHMuQ2hlY2tXaXRoaW5TdGVwcGVkQm91bmRzKG9yaWdpbmFsTnIsIG1pbiwgbWF4LCBzdGVwU2l6ZSk7XHJcbiAgICAgICAgaWYgKGJvdW5kc0NoZWNrLmlzT2spIHtcclxuICAgICAgICAgICAgcmV0dXJuIG9yaWdpbmFsTnI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgYW5zd2VyOiBudW1iZXIgPSB1bmRlZmluZWQ7XHJcblxyXG4gICAgICAgIGxldCByZW1haW5kZXI6IG51bWJlciA9IGJvdW5kc0NoZWNrLnJlbWFpbmRlcjtcclxuICAgICAgICBpZiAocmVtYWluZGVyKSB7XHJcbiAgICAgICAgICAgIC8vIHJvdW5kIHVwIG9yIGRvd24/XHJcbiAgICAgICAgICAgIGlmICgocmVtYWluZGVyIC8gc3RlcFNpemUpIDwgMC41KSB7XHJcbiAgICAgICAgICAgICAgICAvLyAgcm91bmQgZG93biwgYnV0IG5vdCBiZWxvdyBtaW5cclxuICAgICAgICAgICAgICAgIGFuc3dlciA9IChvcmlnaW5hbE5yIC0gcmVtYWluZGVyID49IG1pbiA/IG9yaWdpbmFsTnIgLSByZW1haW5kZXIgOiBtaW4pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgLy8gcm91bmQgdXAsIGJ1dCBub3QgYWJvdmUgbWF4XHJcbiAgICAgICAgICAgICAgICBhbnN3ZXIgPSAob3JpZ2luYWxOciArIHN0ZXBTaXplIC0gcmVtYWluZGVyIDw9IG1heCA/IG9yaWdpbmFsTnIgKyBzdGVwU2l6ZSAtIHJlbWFpbmRlciA6XHJcbiAgICAgICAgICAgICAgICAgICAgTnVtYmVyVXRpbHMuR2V0VHJ1ZVN0ZXBwZWRCb3VuZHNNYXgobWluLCBtYXgsIHN0ZXBTaXplKSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBpcyB0aGlzIHJlYWwgbGlmZSwgd2h5IHdhc24ndCBvdXIgc3RlcHBlZCBib3VuZHMgY2hlY2sgT0s/XHJcbiAgICAgICAgICAgIGFuc3dlciA9IG9yaWdpbmFsTnI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyAnY29ycmVjdCcgZmxvYXQgZXJyb3JzXHJcbiAgICAgICAgYW5zd2VyID0gTnVtYmVyVXRpbHMuUGFyc2VGbG9hdChhbnN3ZXIsIE51bWJlclV0aWxzLl9HZXRMYXJnZXN0RGVjaW1hbFByZWNpc2lvbk9mKG9yaWdpbmFsTnIsIG1pbiwgbWF4LCBzdGVwU2l6ZSkpO1xyXG4gICAgICAgIHJldHVybiBhbnN3ZXI7XHJcbiAgICB9XHJcblxyXG4gICAgLy8gUmV0dXJucyB0aGUgbnVtYmVyIG9mIGRlY2ltYWwgcGxhY2VzIG9mIHRoZSBnaXZlbiBudW1iZXIuIFJldHVybnMgMCBpZiBubyBkZWNpbWFscyB3aGF0c29ldmVyIGNvdWxkIGJlIGZvdW5kIG9uIGdpdmVuIGFyZy5cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0RGVjaW1hbFBsYWNlcyhhcmc6IGFueSwgbWF4QW5zd2VyOiBudW1iZXIgPSAxMDAwKTogbnVtYmVyIHtcclxuICAgICAgICBsZXQgbWF0Y2g6IFJlZ0V4cE1hdGNoQXJyYXkgPSAoJycgKyBhcmcpLm1hdGNoKC8oPzpcXC4oXFxkKykpPyg/OltlRV0oWystXT9cXGQrKSk/JC8pO1xyXG4gICAgICAgIGlmICghbWF0Y2gpIHtcclxuICAgICAgICAgICAgcmV0dXJuIDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBsZXQgYW5zd2VyOiBudW1iZXIgPSBNYXRoLm1heCgwLFxyXG4gICAgICAgICAgICAvLyBudW1iZXIgb2YgZGlnaXRzIHJpZ2h0IG9mIGRlY2ltYWwgcG9pbnQuXHJcbiAgICAgICAgICAgIChtYXRjaFsxXSA/IG1hdGNoWzFdLmxlbmd0aCA6IDApXHJcbiAgICAgICAgICAgIC8vIGFkanVzdCBmb3Igc2NpZW50aWZpYyBub3RhdGlvblxyXG4gICAgICAgICAgICAtIChtYXRjaFsyXSA/ICttYXRjaFsyXSA6IDApKTtcclxuXHJcbiAgICAgICAgaWYgKGFuc3dlciA+IG1heEFuc3dlcikge1xyXG4gICAgICAgICAgICBhbnN3ZXIgPSBtYXhBbnN3ZXI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gYW5zd2VyO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJldHVybnMgdHJ1ZSBpZmYgZ2l2ZW4gYXJndW1lbnQgaXMgYW4gaW50ZWdlciBudW1iZXIuIFJldHVybnMgZmFsc2Ugb24gbm9uLW51bWJlcnMgb3IgbnVtYmVycyB3aXRoIHNpZ25pZmljYW50IGRlY2ltYWxzLlxyXG4gICAgcHVibGljIHN0YXRpYyBJc0ludGVnZXIoYXJnOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICBpZiAoaXNOYU4oYXJnKSB8fCBBcnJheS5pc0FycmF5KGFyZykpIHtcclxuICAgICAgICAgICAgcmV0dXJuIGZhbHNlO1xyXG4gICAgICAgIH1cclxuICAgICAgICBsZXQgYXJnQXNGbG9hdDogbnVtYmVyID0gcGFyc2VGbG9hdChhcmcpO1xyXG4gICAgICAgIHJldHVybiAoKGFyZ0FzRmxvYXQgfCAwKSA9PT0gYXJnQXNGbG9hdCk7IC8vIHJldHVybnMgd2hldGhlciAnYXJnIGNvbnZlcnRlZCB0byBhbiBpbnRlZ2VyIGVxdWFscyBhcmcnXHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHdoZXRoZXIgZ2l2ZW4gYXJnIGlzIHBhcnNlYWJsZSBhcyBhIG51bWJlciwgYW5kIHdoZXRoZXIgdGhlIGxlbmd0cyBvZiBpdHMgbnVtYmVyIHBhcnNlIHJlc3VsdCBpcyBlcXVhbCB0byBpdHMgb3JpZ2luYWwgbGVuZ3RoLlxyXG4gICAgICogSS5lLiB0aGlzIGZ1bmN0aW9uIHJldHVybnMgRkFMU0Ugd2l0aCBnaXZlbiBudW1iZXItcGFyc2FibGUgc3RyaW5ncywgYnV0IHRoYXQgaGF2ZSBub24tbnVtZXJpYyBhcHBlbmRpY2VzLCBlZyAnMjIzM2ZmJy4gVGhhdCBhcmdcclxuICAgICAqIElTIG51bWJlci1wYXJzZWFibGUsIGJ1dCBub3QgYSBzdHJpY3QgJ3N0cmluZyBudW1iZXInLCB0aGUgbGF0dGVyIGJlaW5nIHdoYXQgdGhpcyBtZXRob2QgYWN0dWFsbHkgY2hlY2tzIGZvci5cclxuICAgICAqL1xyXG4gICAgcHVibGljIHN0YXRpYyBJc1N0cmluZ051bWJlcihhcmc6IHN0cmluZyk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGlmICghTnVtYmVyVXRpbHMuSXNQYXJzYWJsZU51bWJlcihhcmcpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBmYWxzZTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICByZXR1cm4gYXJnLnRvU3RyaW5nKCkubGVuZ3RoID09PSBwYXJzZUZsb2F0KGFyZykudG9TdHJpbmcoKS5sZW5ndGg7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8qKlxyXG4gICAgICogUmV0dXJucyBhIHJhbmRvbSBpbnRlZ2VyIGluIHJhbmdlIFtsb3dlckJvdW5kIC4uIHVwcGVyQm91bmRdLCBhbiBpbmNsdXNpdmUgcmFuZ2UuIFJldHVybnMgTmFOIGlmIG5vdCBwb3NzaWJsZS5cclxuICAgICAqIEdpdmVuIGJvdW5kcyBhcmUgdHJ1bmNhdGVkIGZpcnN0LCBiZWZvcmUgc2VydmluZyBhcyB0aGUgdHJ1ZSBsb3dlci0gYW5kIHVwcGVyIGJvdW5kcyBmb3IgdGhlIHJhbmRvbSBpbnQuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgUmFuZG9tSW50KGxvd2VyQm91bmRJbnQ6IG51bWJlciwgdXBwZXJCb3VuZEludDogbnVtYmVyKTogbnVtYmVyIHtcclxuICAgICAgICBpZiAoIU51bWJlclV0aWxzLklzTnVtYmVyKGxvd2VyQm91bmRJbnQpIHx8ICFOdW1iZXJVdGlscy5Jc051bWJlcih1cHBlckJvdW5kSW50KSB8fCBsb3dlckJvdW5kSW50ID4gdXBwZXJCb3VuZEludCkge1xyXG4gICAgICAgICAgICByZXR1cm4gTmFOO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgbG93ZXJCb3VuZEludCA9IE1hdGgudHJ1bmMobG93ZXJCb3VuZEludCk7XHJcbiAgICAgICAgdXBwZXJCb3VuZEludCA9IE1hdGgudHJ1bmModXBwZXJCb3VuZEludCk7XHJcblxyXG4gICAgICAgIGlmIChsb3dlckJvdW5kSW50ID09PSB1cHBlckJvdW5kSW50KSB7XHJcbiAgICAgICAgICAgIHJldHVybiBsb3dlckJvdW5kSW50O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgZGVsdGE6IG51bWJlciA9IHVwcGVyQm91bmRJbnQgLSBsb3dlckJvdW5kSW50O1xyXG4gICAgICAgIHJldHVybiAoTWF0aC5yb3VuZChNYXRoLnJhbmRvbSgpICogZGVsdGEpICsgbG93ZXJCb3VuZEludCk7XHJcbiAgICB9XHJcblxyXG4gICAgLyoqXHJcbiAgICAgKiBSZXR1cm5zIHRoZSB0cnVlIG1heGltdW0gYWxsb3dlZCB2YWx1ZSBmb3IgdGhlIGdpdmVuIFwic3RlcHBlZCBib3VuZHNcIjogbWluLCBzdGVwU2l6ZSBhbmQgbWF4LCBmb3Igd2hpY2ggaXQgaG9sZHMgdGhhdCBlYWNoIGFsbG93ZWRcclxuICAgICAqIHZhbHVlIFkgPSBtaW4gKyBzdGVwU2l6ZSAqIE4sIGZvciBhbnkgSU5URUdFUiBvciAwIE4gd2hlcmUgaXQgYWxzbyBob2xkcywgb2YgY291cnNlLCB0aGF0IFkgPD0gbWF4LlxyXG4gICAgICogQHBhcmFtIG1pblxyXG4gICAgICogQHBhcmFtIG1heFxyXG4gICAgICogQHBhcmFtIHN0ZXBTaXplXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgR2V0VHJ1ZVN0ZXBwZWRCb3VuZHNNYXgobWluOiBudW1iZXIsIG1heDogbnVtYmVyLCBzdGVwU2l6ZTogbnVtYmVyID0gMSk6IG51bWJlciB7XHJcbiAgICAgICAgLy8gc29sdmUgbWF4IGludGVnZXIgWCBpbiBmb3JtdWxhIG1pbiArIFggKiBzdGVwIDw9IG1heCwgYW5kIHJldHVybiBtaW4gKyBYICogc3RlcFNpemUgZm9yIHRoYXQgWFxyXG4gICAgICAgIGxldCBtYXhTdGVwczogbnVtYmVyID0gTWF0aC5mbG9vcigobWF4IC0gbWluKSAvIHN0ZXBTaXplKTtcclxuICAgICAgICAvLyAnY29ycmVjdCcgZmxvYXQgZXJyb3JzXHJcbiAgICAgICAgcmV0dXJuIE51bWJlclV0aWxzLlBhcnNlRmxvYXQobWluICsgbWF4U3RlcHMgKiBzdGVwU2l6ZSwgTnVtYmVyVXRpbHMuX0dldExhcmdlc3REZWNpbWFsUHJlY2lzaW9uT2YobWluLCBtaW4sIG1heCkpO1xyXG4gICAgfVxyXG5cclxuICAgIC8vIFJldHVybnMgdGhlIHN0cmluZyByZXByZXNlbnRhdGlvbiBvZiBnaXZlbiBudW1iZXIuIElmIGl0J3Mgbm90IGEgbnVtYmVyLCByZXR1cm5zIHRoZSBlbXB0eSBzdHJpbmcuXHJcbiAgICBwdWJsaWMgc3RhdGljIFRvU3RyaW5nKG5yOiBudW1iZXIpOiBzdHJpbmcge1xyXG4gICAgICAgIGlmICghTnVtYmVyVXRpbHMuSXNOYU4obnIpKSB7XHJcbiAgICAgICAgICAgIHJldHVybiBcIlwiICsgbnI7XHJcbiAgICAgICAgfSBlbHNlIHtcclxuICAgICAgICAgICAgcmV0dXJuIFwiXCI7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIC8vIFJldHVybnMgd2hldGhlciBnaXZlbiBhcmcgaXMgaW5kZWVkIG5vdCBhIG51bWJlciAoaXQncyBOYU4gb3IgaXQgaGFzIGFub3RoZXIgdHlwZSB0aGFuICdudW1iZXInKS5cclxuICAgIHB1YmxpYyBzdGF0aWMgSXNOYU4oYXJnOiBhbnkpOiBib29sZWFuIHtcclxuICAgICAgICByZXR1cm4gaXNOYU4oYXJnKSB8fCAhTnVtYmVyVXRpbHMuSXNOdW1iZXIoYXJnKTtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgd2hldGhlciBnaXZlbiB4IGlzIE9LIHdpdGhpbiB0aGUgZ2l2ZW4gbWluLCBtYXggYW5kIHN0ZXAgYm91bmRhcmllcywgd2hlcmUgaXQgc2hvdWxkIGhvbGQgdGhhdCBuclRvQ2hlY2sgPSBtaW4gKyBOICogc3RlcCxcclxuICAgICAqIHdpdGggTiBpbnRlZ2VyIG9yIDAuXHJcbiAgICAgKiBAcGFyYW0gbnJUb0NoZWNrIE51bWJlciB0byBjaGVjayB3aGV0aGVyIGl0J3Mgd2l0aGluIHRoZSBnaXZlbiBib3VuZHNcclxuICAgICAqIEBwYXJhbSBtaW4gSW5jbHVzaXZlXHJcbiAgICAgKiBAcGFyYW0gbWF4IEluY2x1c2l2ZVxyXG4gICAgICogQHBhcmFtIHN0ZXBTaXplXHJcbiAgICAgKiBAcmV0dXJucyBSZXR1cm5zIHJlbWFpbmRlciBvZiB1bmRlZmluZWQgd2hlbiBuclRvQ2hlY2sgd2FzIE9VVFNJREUgW21pbiwgbWF4XSwgZWxzZSBmdWxsIHJlc3VsdCBvYmplY3QuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgQ2hlY2tXaXRoaW5TdGVwcGVkQm91bmRzKFxyXG4gICAgICAgIG5yVG9DaGVjazogbnVtYmVyLFxyXG4gICAgICAgIG1pbjogbnVtYmVyLFxyXG4gICAgICAgIG1heDogbnVtYmVyLFxyXG4gICAgICAgIHN0ZXBTaXplOiBudW1iZXIgPSAxXHJcbiAgICApOiBDaGVja1dpdGhpblN0ZXBwZWRCb3VuZHNSZXN1bHQge1xyXG4gICAgICAgIGlmIChuclRvQ2hlY2sgPCBtaW4gfHwgbnJUb0NoZWNrID4gbWF4KSB7XHJcbiAgICAgICAgICAgIHJldHVybiB7aXNPazogZmFsc2UsIHJlbWFpbmRlcjogdW5kZWZpbmVkfTtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIC8vIHdlJ3JlIGluIFttaW4sIG1heF0sIGJ1dCBzdGlsbCBjaGVjayBpZiBuclRvQ2hlY2sgPSBtaW4gKyBOICogc3RlcCBob2xkcyAoZm9yIE4gaW50ZWdlciBvciAwKVxyXG4gICAgICAgIGxldCByZW1haW5kZXI6IG51bWJlciA9IChuclRvQ2hlY2sgLSBtaW4pICUgc3RlcFNpemU7XHJcbiAgICAgICAgLy8gY29ycmVjdCBmbG9hdCBmb3IgbGFyZ2VzdCBwcmVjaXNpb24gYW1vbmdzdCBpbnB1dCBudW1iZXJzXHJcbiAgICAgICAgcmVtYWluZGVyID0gTnVtYmVyVXRpbHMuUGFyc2VGbG9hdChyZW1haW5kZXIsIE51bWJlclV0aWxzLl9HZXRMYXJnZXN0RGVjaW1hbFByZWNpc2lvbk9mKG5yVG9DaGVjaywgbWluLCBzdGVwU2l6ZSkpO1xyXG4gICAgICAgIHJldHVybiB7aXNPazogKHJlbWFpbmRlciA9PT0gMCksIHJlbWFpbmRlcjogcmVtYWluZGVyfTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBBZGRzIHRob3VzYW5kcyBjb21tYSdzIHRvIGdpdmVuIHZhbHVlLCBFLmcuICcxMDAwJyB0byAnMSwwMDAnLiBSZXR1cm5zIGVtcHR5IHN0cmluZyBpZiB2YWx1ZSB3YXMgdW5kZWZpbmVkLlxyXG4gICAgcHVibGljIHN0YXRpYyBBZGRUaG91c2FuZHNDb21tYXNUbyh2YWx1ZTogYW55KTogc3RyaW5nIHtcclxuICAgICAgICBpZiAoaXNOaWxsKHZhbHVlKSkge1xyXG4gICAgICAgICAgICByZXR1cm4gXCJcIjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIHJldHVybiB2YWx1ZS50b1N0cmluZygpLnJlcGxhY2UoL1xcQig/PShcXGR7M30pKyg/IVxcZCkpL2csIFwiLFwiKTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZXR1cm5zIHRoZSBuZWFyZXN0IG51bWJlciwgcmVsYXRpdmUgdG8gdGhlIGdpdmVuIG9yaWdpbmFsTnIsIHRoYXQgaXMgd2l0aGluIHRoZSBnaXZlbiBbbWluLCBtYXhdIGluY2x1c2l2ZSBib3VuZHMuXHJcbiAgICBwdWJsaWMgc3RhdGljIEdldE5lYXJlc3ROdW1iZXJXaXRoaW5Cb3VuZHMob3JpZ2luYWxOcjogbnVtYmVyLCBtaW46IG51bWJlciwgbWF4OiBudW1iZXIpOiBudW1iZXIge1xyXG4gICAgICAgIGxldCBhbnN3ZXI6IG51bWJlciA9IG9yaWdpbmFsTnI7XHJcblxyXG4gICAgICAgIGlmIChvcmlnaW5hbE5yIDwgbWluKSB7XHJcbiAgICAgICAgICAgIGFuc3dlciA9IG1pbjtcclxuICAgICAgICB9IGVsc2UgaWYgKG9yaWdpbmFsTnIgPiBtYXgpIHtcclxuICAgICAgICAgICAgYW5zd2VyID0gbWF4O1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgcmV0dXJuIGFuc3dlcjtcclxuICAgIH1cclxuXHJcbiAgICAvKipcclxuICAgICAqIFJldHVybnMgd2hldGhlciBnaXZlbiBuclRvQ2hlY2sgaXMgd2l0aGluIHRoZSBnaXZlbiBwcmVjaXNpb24gYW5kIHNjYWxlIGxpbWl0cy4gUHJlY2lzaW9uIGFuZCBzY2FsZSwgaGVyZSwgYXJlIE9yYWNsZSBEQiB0ZXJtcy5cclxuICAgICAqIFRoaXMgZnVuY3Rpb24gY2FuIHRodXMgYmUgdXNlZCB0byBjaGVjayB3aGV0aGVyIHRoZSBnaXZlbiBudW1iZXIgaXMgc2FmZSB0byBzZW5kIHRvIHRoZSAnZGF0YWJhc2UnIGJlZm9yZWhhbmQsIGlmIHdlIGtub3cgdGhlXHJcbiAgICAgKiBwcmVjaXNpb24gYW5kIHNjYWxlIG9mIHRoZSBudW1iZXIgaW4gdGhlIGRiIGRlY2xhcmF0aW9uLlxyXG4gICAgICpcclxuICAgICAqIEkuZS4gQSBudW1iZXIgZGVjbGFyZWQgaW4gdGhlIE9yYWNsZSBEQiBhcyBudW1iZXIoNSwgMikgaGFzIGEgcHJlY2lzaW9uIG9mIDUgYW5kIGEgc2NhbGUgb2YgMi5cclxuICAgICAqXHJcbiAgICAgKiBAcGFyYW0gbnJUb0NoZWNrXHJcbiAgICAgKiBAcGFyYW0gcHJlY2lzaW9uIFRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgZGlnaXRzLCBpbmNsdWRpbmcgcG9zc2libHkgbmVnYXRpdmUgc2NhbGUuIEUuZy4gMyBpbiAnMTIzJyBhbmQgNSBpbiAnNTEuMTIzJ1xyXG4gICAgICogQHBhcmFtIFtzY2FsZSA9IDBdIFRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgZGlnaXRzIEFGVEVSIHRoZSBkZWNpbWFsIHBvaW50LiBFLmcuIDEgaW4gNTQzMi4xIGFuZCAzIGluIDU0MDAwLjAwM1xyXG4gICAgICogQHJldHVybnMgV2hldGhlciBnaXZlbiBuclRvQ2hlY2sgaXMgb2sgZm9yIGdpdmVuIHByZWNpc2lvbiBhbmQgc2NhbGUsIGFuZCBpZiBub3QsIHRoZVxyXG4gICAgICogbmVhcmVzdCBudW1iZXIgdGhhdCBJUyBvayBmb3IgdGhvc2UgY29uc3RyYWludHMuXHJcbiAgICAgKi9cclxuICAgIHB1YmxpYyBzdGF0aWMgQ2hlY2tQcmVjaXNpb25BbmRTY2FsZShuclRvQ2hlY2s6IG51bWJlciwgcHJlY2lzaW9uOiBudW1iZXIsIHNjYWxlOiBudW1iZXIgPSAwKTogQ2hlY2tQcmVjaXNpb25BbmRTY2FsZVJlc3VsdCB7XHJcbiAgICAgICAgLy8gbGV0J3Mgc2F5IGFueSB1bmRlZmluZWQgbnVtYmVyIGlzIGNoZWNrZWQgT0ssIGFuZCBhbGwgbnVtYmVycyBhcmUgY2hlY2tlZCBPSyBmb3IgYW4gdW5kZWZpbmVkIHByZWNpc2lvblxyXG4gICAgICAgIGlmICghT2JqZWN0VXRpbHMuQWxsRXhpc3QobnJUb0NoZWNrLCBwcmVjaXNpb24sIHNjYWxlKSkge1xyXG4gICAgICAgICAgICByZXR1cm4ge2lzT2s6IHRydWUsIG5lYXJlc3RPa05yOiBOYU59O1xyXG4gICAgICAgIH1cclxuICAgICAgICAvLyBubyBudW1iZXIgY2FuIGhhdmUgMCBvciBsZXNzIHRoYW4gMCBzaWduaWZpY2FudCBkaWdpdHMsIGluIG91ciB1bml2ZXJzZVxyXG4gICAgICAgIGlmIChwcmVjaXNpb24gPCAxIHx8IHByZWNpc2lvbiAtIHNjYWxlIDwgMSkge1xyXG4gICAgICAgICAgICByZXR1cm4ge2lzT2s6IGZhbHNlLCBuZWFyZXN0T2tOcjogTmFOfTtcclxuICAgICAgICB9XHJcbiAgICAgICAgLy8gYmVnaW4gY2hlY2tcclxuICAgICAgICBjb25zdCBpc05lZ2F0aXZlOiBib29sZWFuID0gKG5yVG9DaGVjayA8IDApO1xyXG4gICAgICAgIGNvbnN0IG5yUGFydHM6IHN0cmluZ1tdID0gbnJUb0NoZWNrLnRvU3RyaW5nKCkuc3BsaXQoXCIuXCIpO1xyXG4gICAgICAgIC8vIHJlbW92ZSBtaW51cyBzaWduIGlmIG5lZ2F0aXZlXHJcbiAgICAgICAgaWYgKGlzTmVnYXRpdmUpIHtcclxuICAgICAgICAgICAgbnJQYXJ0c1swXSA9IG5yUGFydHNbMF0uc2xpY2UoMSk7XHJcbiAgICAgICAgfVxyXG4gICAgICAgIGNvbnN0IG51bUNvdW50QmVmb3JlRG90OiBudW1iZXIgPSBuclBhcnRzWzBdLmxlbmd0aDtcclxuICAgICAgICBjb25zdCBhbGxvd2VkTnVtQ291bnRCZWZvcmVEb3Q6IG51bWJlciA9IHByZWNpc2lvbiAtIHNjYWxlO1xyXG4gICAgICAgIGlmIChudW1Db3VudEJlZm9yZURvdCA8PSBhbGxvd2VkTnVtQ291bnRCZWZvcmVEb3QpIHtcclxuICAgICAgICAgICAgcmV0dXJuIHtpc09rOiB0cnVlLCBuZWFyZXN0T2tOcjogbnJUb0NoZWNrfTtcclxuICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAvLyBjdXQgYSBwYXJ0IGZyb20gdGhlIFwiYmVmb3JlIGRlY2ltYWwgbnVtYmVyXCIgc28gdGhhdCB0aGUgbnVtYmVyIGlzIG5vdCB0b28gYmlnIGFueW1vcmVcclxuICAgICAgICAgICAgY29uc3QgbnVtQ291bnRUb1JlbW92ZTogbnVtYmVyID0gbnVtQ291bnRCZWZvcmVEb3QgLSBhbGxvd2VkTnVtQ291bnRCZWZvcmVEb3Q7XHJcbiAgICAgICAgICAgIC8vIHJlbW92ZSB0aGUgcmlnaHQtbW9zdCBudW1iZXJzIGJlZm9yZSB0aGUgZGVjaW1hbCBkb3RcclxuICAgICAgICAgICAgbnJQYXJ0c1swXSA9IG5yUGFydHNbMF0uc2xpY2UoMCwgLTEgKiBudW1Db3VudFRvUmVtb3ZlKTtcclxuICAgICAgICAgICAgLy8gYWRkIG1pbnVzIHNpZ24gYWdhaW4gaWYgaXQgd2FzIG5lZ2F0aXZlXHJcbiAgICAgICAgICAgIGlmIChpc05lZ2F0aXZlKSB7XHJcbiAgICAgICAgICAgICAgICBuclBhcnRzWzBdID0gXCItXCIgKyBuclBhcnRzWzBdO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIC8vIGJ1aWxkIGFuZCByZXR1cm4gY29tcG9zaXRlIG51bWJlciBhZ2FpblxyXG4gICAgICAgICAgICBsZXQgbmVhcmVzdE9rTnI6IG51bWJlcjtcclxuICAgICAgICAgICAgaWYgKG5yUGFydHNbMV0pIHtcclxuICAgICAgICAgICAgICAgIG5lYXJlc3RPa05yID0gTnVtYmVyKG5yUGFydHNbMF0gKyBcIi5cIiArIG5yUGFydHNbMV0pO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgbmVhcmVzdE9rTnIgPSBOdW1iZXIobnJQYXJ0c1swXSk7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgcmV0dXJuIHtpc09rOiBmYWxzZSwgbmVhcmVzdE9rTnI6IG5lYXJlc3RPa05yfTtcclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgX0dldExhcmdlc3REZWNpbWFsUHJlY2lzaW9uT2YoLi4uYXJnczogbnVtYmVyW10pOiBudW1iZXIge1xyXG4gICAgICAgIHJldHVybiBBcnJheVV0aWxzLkdldE1heENhbGN1bGF0ZWRWYWx1ZShhcmdzLCAoYXJnOiBudW1iZXIpID0+IHtcclxuICAgICAgICAgICAgcmV0dXJuIE51bWJlclV0aWxzLkdldERlY2ltYWxQbGFjZXMoYXJnKTtcclxuICAgICAgICB9KTtcclxuICAgIH1cclxuXHJcbiAgICAvLyBSZXR1cm5zIGdpdmVuIG51bWJlciBpbnB1dCBhcyBhIG51bWJlciB0aGF0J3MgdXNlYWJsZSBieSBKYXZhc2NyaXB0LiBBbGxvd3MgZm9yIGluY29taW5nICcsJyBkZWNpbWFsIGRlbGltaXRlci5cclxuICAgIHByaXZhdGUgc3RhdGljIF9OdW1iZXJJbnB1dFRvTnVtYmVyU3RyKG51bWJlcklucHV0OiBzdHJpbmcpOiBzdHJpbmcge1xyXG4gICAgICAgIHJldHVybiAobnVtYmVySW5wdXQgKyAnJykucmVwbGFjZSgnLCcsICcuJyk7XHJcbiAgICB9XHJcbn1cclxuIl19