@spartan-ng/brain 0.0.1-alpha.373 → 0.0.1-alpha.379

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 (398) hide show
  1. package/accordion/README.md +3 -0
  2. package/accordion/index.d.ts +13 -0
  3. package/accordion/lib/brn-accordion-content.component.d.ts +15 -0
  4. package/accordion/lib/brn-accordion.directive.d.ts +47 -0
  5. package/alert-dialog/README.md +3 -0
  6. package/alert-dialog/index.d.ts +25 -0
  7. package/alert-dialog/lib/brn-alert-dialog-content.directive.d.ts +6 -0
  8. package/alert-dialog/lib/brn-alert-dialog-description.directive.d.ts +6 -0
  9. package/alert-dialog/lib/brn-alert-dialog-overlay.component.d.ts +6 -0
  10. package/alert-dialog/lib/brn-alert-dialog-title.directive.d.ts +6 -0
  11. package/alert-dialog/lib/brn-alert-dialog-trigger.directive.d.ts +8 -0
  12. package/alert-dialog/lib/brn-alert-dialog.component.d.ts +7 -0
  13. package/avatar/README.md +3 -0
  14. package/avatar/index.d.ts +17 -0
  15. package/avatar/lib/brn-avatar.component.d.ts +7 -0
  16. package/avatar/lib/fallback/brn-avatar-fallback.directive.d.ts +11 -0
  17. package/avatar/lib/fallback/index.d.ts +1 -0
  18. package/avatar/lib/image/brn-avatar-image.directive.d.ts +9 -0
  19. package/avatar/lib/image/index.d.ts +1 -0
  20. package/avatar/lib/util/hex-color-for.d.ts +1 -0
  21. package/avatar/lib/util/index.d.ts +3 -0
  22. package/avatar/lib/util/initials.pipe.d.ts +7 -0
  23. package/avatar/lib/util/is-bright.d.ts +1 -0
  24. package/calendar/README.md +3 -0
  25. package/calendar/index.d.ts +36 -0
  26. package/calendar/lib/brn-calendar-cell-button.directive.d.ts +59 -0
  27. package/calendar/lib/brn-calendar-cell.directive.d.ts +5 -0
  28. package/calendar/lib/brn-calendar-grid.directive.d.ts +7 -0
  29. package/calendar/lib/brn-calendar-header.directive.d.ts +7 -0
  30. package/calendar/lib/brn-calendar-next-button.directive.d.ts +13 -0
  31. package/calendar/lib/brn-calendar-previous-button.directive.d.ts +13 -0
  32. package/calendar/lib/brn-calendar-week.directive.d.ts +25 -0
  33. package/calendar/lib/brn-calendar-weekday.directive.d.ts +25 -0
  34. package/calendar/lib/brn-calendar.directive.d.ts +55 -0
  35. package/calendar/lib/brn-calendar.token.d.ts +8 -0
  36. package/calendar/lib/i18n/calendar-i18n.d.ts +17 -0
  37. package/checkbox/lib/brn-checkbox.component.d.ts +1 -1
  38. package/collapsible/README.md +3 -0
  39. package/collapsible/index.d.ts +16 -0
  40. package/collapsible/lib/brn-collapsible-content.component.d.ts +19 -0
  41. package/collapsible/lib/brn-collapsible-trigger.directive.d.ts +12 -0
  42. package/collapsible/lib/brn-collapsible.component.d.ts +11 -0
  43. package/command/README.md +3 -0
  44. package/command/index.d.ts +33 -0
  45. package/command/lib/brn-command-empty.directive.d.ts +6 -0
  46. package/command/lib/brn-command-group.component.d.ts +6 -0
  47. package/command/lib/brn-command-input.directive.d.ts +6 -0
  48. package/command/lib/brn-command-item.directive.d.ts +6 -0
  49. package/command/lib/brn-command-list.component.d.ts +6 -0
  50. package/command/lib/brn-command-loader.directive.d.ts +6 -0
  51. package/command/lib/brn-command-separator.component.d.ts +6 -0
  52. package/command/lib/brn-command.component.d.ts +6 -0
  53. package/date-time/README.md +3 -0
  54. package/date-time/index.d.ts +2 -0
  55. package/date-time/lib/date-adapter.d.ts +176 -0
  56. package/date-time/lib/native-date-adapter.d.ts +103 -0
  57. package/date-time-luxon/README.md +3 -0
  58. package/date-time-luxon/index.d.ts +1 -0
  59. package/date-time-luxon/lib/date-adapter.d.ts +29 -0
  60. package/dialog/README.md +3 -0
  61. package/dialog/index.d.ts +33 -0
  62. package/dialog/lib/brn-dialog-close.directive.d.ts +10 -0
  63. package/dialog/lib/brn-dialog-content.directive.d.ts +12 -0
  64. package/dialog/lib/brn-dialog-description.directive.d.ts +8 -0
  65. package/dialog/lib/brn-dialog-options.d.ts +26 -0
  66. package/dialog/lib/brn-dialog-overlay.component.d.ts +8 -0
  67. package/dialog/lib/brn-dialog-ref.d.ts +24 -0
  68. package/dialog/lib/brn-dialog-state.d.ts +1 -0
  69. package/dialog/lib/brn-dialog-title.directive.d.ts +8 -0
  70. package/dialog/lib/brn-dialog-trigger.directive.d.ts +16 -0
  71. package/dialog/lib/brn-dialog-utils.d.ts +1 -0
  72. package/dialog/lib/brn-dialog.component.d.ts +56 -0
  73. package/dialog/lib/brn-dialog.service.d.ts +22 -0
  74. package/esm2022/accordion/index.mjs +31 -0
  75. package/esm2022/accordion/lib/brn-accordion-content.component.mjs +50 -0
  76. package/esm2022/accordion/lib/brn-accordion.directive.mjs +180 -0
  77. package/esm2022/accordion/spartan-ng-brain-accordion.mjs +5 -0
  78. package/esm2022/alert-dialog/index.mjs +45 -0
  79. package/esm2022/alert-dialog/lib/brn-alert-dialog-content.directive.mjs +17 -0
  80. package/esm2022/alert-dialog/lib/brn-alert-dialog-description.directive.mjs +18 -0
  81. package/esm2022/alert-dialog/lib/brn-alert-dialog-overlay.component.mjs +20 -0
  82. package/esm2022/alert-dialog/lib/brn-alert-dialog-title.directive.mjs +18 -0
  83. package/esm2022/alert-dialog/lib/brn-alert-dialog-trigger.directive.mjs +27 -0
  84. package/esm2022/alert-dialog/lib/brn-alert-dialog.component.mjs +40 -0
  85. package/esm2022/alert-dialog/spartan-ng-brain-alert-dialog.mjs +5 -0
  86. package/esm2022/avatar/index.mjs +23 -0
  87. package/esm2022/avatar/lib/brn-avatar.component.mjs +31 -0
  88. package/esm2022/avatar/lib/fallback/brn-avatar-fallback.directive.mjs +21 -0
  89. package/esm2022/avatar/lib/fallback/index.mjs +2 -0
  90. package/esm2022/avatar/lib/image/brn-avatar-image.directive.mjs +29 -0
  91. package/esm2022/avatar/lib/image/index.mjs +2 -0
  92. package/esm2022/avatar/lib/util/hex-color-for.mjs +22 -0
  93. package/esm2022/avatar/lib/util/index.mjs +4 -0
  94. package/esm2022/avatar/lib/util/initials.pipe.mjs +27 -0
  95. package/esm2022/avatar/lib/util/is-bright.mjs +12 -0
  96. package/esm2022/avatar/spartan-ng-brain-avatar.mjs +5 -0
  97. package/esm2022/calendar/index.mjs +62 -0
  98. package/esm2022/calendar/lib/brn-calendar-cell-button.directive.mjs +160 -0
  99. package/esm2022/calendar/lib/brn-calendar-cell.directive.mjs +17 -0
  100. package/esm2022/calendar/lib/brn-calendar-grid.directive.mjs +21 -0
  101. package/esm2022/calendar/lib/brn-calendar-header.directive.mjs +22 -0
  102. package/esm2022/calendar/lib/brn-calendar-next-button.directive.mjs +42 -0
  103. package/esm2022/calendar/lib/brn-calendar-previous-button.directive.mjs +42 -0
  104. package/esm2022/calendar/lib/brn-calendar-week.directive.mjs +64 -0
  105. package/esm2022/calendar/lib/brn-calendar-weekday.directive.mjs +48 -0
  106. package/esm2022/calendar/lib/brn-calendar.directive.mjs +154 -0
  107. package/esm2022/calendar/lib/brn-calendar.token.mjs +12 -0
  108. package/esm2022/calendar/lib/i18n/calendar-i18n.mjs +33 -0
  109. package/esm2022/calendar/spartan-ng-brain-calendar.mjs +5 -0
  110. package/esm2022/checkbox/lib/brn-checkbox.component.mjs +1 -1
  111. package/esm2022/collapsible/index.mjs +30 -0
  112. package/esm2022/collapsible/lib/brn-collapsible-content.component.mjs +61 -0
  113. package/esm2022/collapsible/lib/brn-collapsible-trigger.directive.mjs +35 -0
  114. package/esm2022/collapsible/lib/brn-collapsible.component.mjs +33 -0
  115. package/esm2022/collapsible/spartan-ng-brain-collapsible.mjs +5 -0
  116. package/esm2022/command/index.mjs +64 -0
  117. package/esm2022/command/lib/brn-command-empty.directive.mjs +29 -0
  118. package/esm2022/command/lib/brn-command-group.component.mjs +45 -0
  119. package/esm2022/command/lib/brn-command-input.directive.mjs +29 -0
  120. package/esm2022/command/lib/brn-command-item.directive.mjs +36 -0
  121. package/esm2022/command/lib/brn-command-list.component.mjs +35 -0
  122. package/esm2022/command/lib/brn-command-loader.directive.mjs +29 -0
  123. package/esm2022/command/lib/brn-command-separator.component.mjs +30 -0
  124. package/esm2022/command/lib/brn-command.component.mjs +21 -0
  125. package/esm2022/command/spartan-ng-brain-command.mjs +5 -0
  126. package/esm2022/date-time/index.mjs +3 -0
  127. package/esm2022/date-time/lib/date-adapter.mjs +16 -0
  128. package/esm2022/date-time/lib/native-date-adapter.mjs +155 -0
  129. package/esm2022/date-time/spartan-ng-brain-date-time.mjs +5 -0
  130. package/esm2022/date-time-luxon/index.mjs +2 -0
  131. package/esm2022/date-time-luxon/lib/date-adapter.mjs +85 -0
  132. package/esm2022/date-time-luxon/spartan-ng-brain-date-time-luxon.mjs +5 -0
  133. package/esm2022/dialog/index.mjs +55 -0
  134. package/esm2022/dialog/lib/brn-dialog-close.directive.mjs +29 -0
  135. package/esm2022/dialog/lib/brn-dialog-content.directive.mjs +41 -0
  136. package/esm2022/dialog/lib/brn-dialog-description.directive.mjs +25 -0
  137. package/esm2022/dialog/lib/brn-dialog-options.mjs +19 -0
  138. package/esm2022/dialog/lib/brn-dialog-overlay.component.mjs +29 -0
  139. package/esm2022/dialog/lib/brn-dialog-ref.mjs +53 -0
  140. package/esm2022/dialog/lib/brn-dialog-state.mjs +2 -0
  141. package/esm2022/dialog/lib/brn-dialog-title.directive.mjs +25 -0
  142. package/esm2022/dialog/lib/brn-dialog-trigger.directive.mjs +39 -0
  143. package/esm2022/dialog/lib/brn-dialog-utils.mjs +12 -0
  144. package/esm2022/dialog/lib/brn-dialog.component.mjs +208 -0
  145. package/esm2022/dialog/lib/brn-dialog.service.mjs +127 -0
  146. package/esm2022/dialog/spartan-ng-brain-dialog.mjs +5 -0
  147. package/esm2022/form-field/index.mjs +2 -0
  148. package/esm2022/form-field/lib/brn-form-field-control.mjs +14 -0
  149. package/esm2022/form-field/spartan-ng-brain-form-field.mjs +5 -0
  150. package/esm2022/forms/index.mjs +4 -0
  151. package/esm2022/forms/lib/control-value-accessor.mjs +2 -0
  152. package/esm2022/forms/lib/error-options.mjs +26 -0
  153. package/esm2022/forms/lib/error-state-tracker.mjs +29 -0
  154. package/esm2022/forms/spartan-ng-brain-forms.mjs +5 -0
  155. package/esm2022/hover-card/index.mjs +29 -0
  156. package/esm2022/hover-card/lib/brn-hover-card-content.service.mjs +205 -0
  157. package/esm2022/hover-card/lib/brn-hover-card.component.mjs +34 -0
  158. package/esm2022/hover-card/lib/createHoverObservable.mjs +19 -0
  159. package/esm2022/hover-card/spartan-ng-brain-hover-card.mjs +5 -0
  160. package/esm2022/label/index.mjs +17 -0
  161. package/esm2022/label/lib/brn-label.directive.mjs +49 -0
  162. package/esm2022/label/spartan-ng-brain-label.mjs +5 -0
  163. package/esm2022/menu/index.mjs +100 -0
  164. package/esm2022/menu/lib/brn-context-menu-trigger.directive.mjs +40 -0
  165. package/esm2022/menu/lib/brn-menu-align.mjs +15 -0
  166. package/esm2022/menu/lib/brn-menu-bar.directive.mjs +17 -0
  167. package/esm2022/menu/lib/brn-menu-group.directive.mjs +17 -0
  168. package/esm2022/menu/lib/brn-menu-item-checkbox.directive.mjs +30 -0
  169. package/esm2022/menu/lib/brn-menu-item-radio.directive.mjs +30 -0
  170. package/esm2022/menu/lib/brn-menu-item.directive.mjs +27 -0
  171. package/esm2022/menu/lib/brn-menu-trigger.directive.mjs +36 -0
  172. package/esm2022/menu/lib/brn-menu.directive.mjs +50 -0
  173. package/esm2022/menu/spartan-ng-brain-menu.mjs +5 -0
  174. package/esm2022/popover/index.mjs +35 -0
  175. package/esm2022/popover/lib/brn-popover-close.directive.mjs +15 -0
  176. package/esm2022/popover/lib/brn-popover-content.directive.mjs +17 -0
  177. package/esm2022/popover/lib/brn-popover-trigger.directive.mjs +37 -0
  178. package/esm2022/popover/lib/brn-popover.component.mjs +81 -0
  179. package/esm2022/popover/spartan-ng-brain-popover.mjs +5 -0
  180. package/esm2022/progress/index.mjs +21 -0
  181. package/esm2022/progress/lib/brn-progress-indicator.component.mjs +22 -0
  182. package/esm2022/progress/lib/brn-progress.component.mjs +61 -0
  183. package/esm2022/progress/lib/brn-progress.token.mjs +9 -0
  184. package/esm2022/progress/spartan-ng-brain-progress.mjs +5 -0
  185. package/esm2022/radio-group/index.mjs +20 -0
  186. package/esm2022/radio-group/lib/brn-radio-group.component.mjs +90 -0
  187. package/esm2022/radio-group/lib/brn-radio-group.token.mjs +9 -0
  188. package/esm2022/radio-group/lib/brn-radio.component.mjs +185 -0
  189. package/esm2022/radio-group/spartan-ng-brain-radio-group.mjs +5 -0
  190. package/esm2022/select/index.mjs +56 -0
  191. package/esm2022/select/lib/brn-select-content.component.mjs +204 -0
  192. package/esm2022/select/lib/brn-select-group.directive.mjs +19 -0
  193. package/esm2022/select/lib/brn-select-label.directive.mjs +23 -0
  194. package/esm2022/select/lib/brn-select-option.directive.mjs +65 -0
  195. package/esm2022/select/lib/brn-select-value.component.mjs +46 -0
  196. package/esm2022/select/lib/brn-select.component.mjs +358 -0
  197. package/esm2022/select/lib/brn-select.service.mjs +197 -0
  198. package/esm2022/select/spartan-ng-brain-select.mjs +5 -0
  199. package/esm2022/separator/index.mjs +17 -0
  200. package/esm2022/separator/lib/brn-separator.component.mjs +24 -0
  201. package/esm2022/separator/spartan-ng-brain-separator.mjs +5 -0
  202. package/esm2022/sheet/index.mjs +50 -0
  203. package/esm2022/sheet/lib/brn-sheet-close.directive.mjs +15 -0
  204. package/esm2022/sheet/lib/brn-sheet-content.directive.mjs +25 -0
  205. package/esm2022/sheet/lib/brn-sheet-description.directive.mjs +18 -0
  206. package/esm2022/sheet/lib/brn-sheet-overlay.component.mjs +20 -0
  207. package/esm2022/sheet/lib/brn-sheet-title.directive.mjs +18 -0
  208. package/esm2022/sheet/lib/brn-sheet-trigger.directive.mjs +26 -0
  209. package/esm2022/sheet/lib/brn-sheet.component.mjs +55 -0
  210. package/esm2022/sheet/spartan-ng-brain-sheet.mjs +5 -0
  211. package/esm2022/slider/index.mjs +13 -0
  212. package/esm2022/slider/lib/brn-slider-thumb.directive.mjs +41 -0
  213. package/esm2022/slider/lib/brn-slider-tick-mark.directive.mjs +37 -0
  214. package/esm2022/slider/lib/brn-slider-track-active-fill.directive.mjs +29 -0
  215. package/esm2022/slider/lib/brn-slider-track.directive.mjs +290 -0
  216. package/esm2022/slider/spartan-ng-brain-slider.mjs +5 -0
  217. package/esm2022/switch/index.mjs +20 -0
  218. package/esm2022/switch/lib/brn-switch-thumb.component.mjs +16 -0
  219. package/esm2022/switch/lib/brn-switch.component.mjs +236 -0
  220. package/esm2022/switch/spartan-ng-brain-switch.mjs +5 -0
  221. package/esm2022/table/index.mjs +47 -0
  222. package/esm2022/table/lib/brn-cell-def.directive.mjs +22 -0
  223. package/esm2022/table/lib/brn-column-def.component.mjs +82 -0
  224. package/esm2022/table/lib/brn-column-manager.mjs +61 -0
  225. package/esm2022/table/lib/brn-footer-def.directive.mjs +22 -0
  226. package/esm2022/table/lib/brn-header-def.directive.mjs +22 -0
  227. package/esm2022/table/lib/brn-paginator.directive.mjs +109 -0
  228. package/esm2022/table/lib/brn-table.component.mjs +169 -0
  229. package/esm2022/table/spartan-ng-brain-table.mjs +5 -0
  230. package/esm2022/tabs/index.mjs +32 -0
  231. package/esm2022/tabs/lib/brn-tabs-list.directive.mjs +65 -0
  232. package/esm2022/tabs/lib/brn-tabs-paginated-list.directive.mjs +525 -0
  233. package/esm2022/tabs/lib/brn-tabs-trigger.directive.mjs +134 -0
  234. package/esm2022/tabs/spartan-ng-brain-tabs.mjs +5 -0
  235. package/esm2022/toggle/index.mjs +31 -0
  236. package/esm2022/toggle/lib/brn-toggle-group.component.mjs +159 -0
  237. package/esm2022/toggle/lib/brn-toggle-group.token.mjs +9 -0
  238. package/esm2022/toggle/lib/brn-toggle.directive.mjs +65 -0
  239. package/esm2022/toggle/spartan-ng-brain-toggle.mjs +5 -0
  240. package/esm2022/tooltip/index.mjs +35 -0
  241. package/esm2022/tooltip/lib/brn-tooltip-content.component.mjs +228 -0
  242. package/esm2022/tooltip/lib/brn-tooltip-content.directive.mjs +22 -0
  243. package/esm2022/tooltip/lib/brn-tooltip-trigger.directive.mjs +689 -0
  244. package/esm2022/tooltip/lib/brn-tooltip.directive.mjs +15 -0
  245. package/esm2022/tooltip/spartan-ng-brain-tooltip.mjs +5 -0
  246. package/fesm2022/spartan-ng-brain-accordion.mjs +259 -0
  247. package/fesm2022/spartan-ng-brain-accordion.mjs.map +1 -0
  248. package/fesm2022/spartan-ng-brain-alert-dialog.mjs +162 -0
  249. package/fesm2022/spartan-ng-brain-alert-dialog.mjs.map +1 -0
  250. package/fesm2022/spartan-ng-brain-avatar.mjs +156 -0
  251. package/fesm2022/spartan-ng-brain-avatar.mjs.map +1 -0
  252. package/fesm2022/spartan-ng-brain-calendar.mjs +629 -0
  253. package/fesm2022/spartan-ng-brain-calendar.mjs.map +1 -0
  254. package/fesm2022/spartan-ng-brain-checkbox.mjs.map +1 -1
  255. package/fesm2022/spartan-ng-brain-collapsible.mjs +152 -0
  256. package/fesm2022/spartan-ng-brain-collapsible.mjs.map +1 -0
  257. package/fesm2022/spartan-ng-brain-command.mjs +284 -0
  258. package/fesm2022/spartan-ng-brain-command.mjs.map +1 -0
  259. package/fesm2022/spartan-ng-brain-date-time-luxon.mjs +92 -0
  260. package/fesm2022/spartan-ng-brain-date-time-luxon.mjs.map +1 -0
  261. package/fesm2022/spartan-ng-brain-date-time.mjs +177 -0
  262. package/fesm2022/spartan-ng-brain-date-time.mjs.map +1 -0
  263. package/fesm2022/spartan-ng-brain-dialog.mjs +617 -0
  264. package/fesm2022/spartan-ng-brain-dialog.mjs.map +1 -0
  265. package/fesm2022/spartan-ng-brain-form-field.mjs +21 -0
  266. package/fesm2022/spartan-ng-brain-form-field.mjs.map +1 -0
  267. package/fesm2022/spartan-ng-brain-forms.mjs +61 -0
  268. package/fesm2022/spartan-ng-brain-forms.mjs.map +1 -0
  269. package/fesm2022/spartan-ng-brain-hover-card.mjs +274 -0
  270. package/fesm2022/spartan-ng-brain-hover-card.mjs.map +1 -0
  271. package/fesm2022/spartan-ng-brain-label.mjs +69 -0
  272. package/fesm2022/spartan-ng-brain-label.mjs.map +1 -0
  273. package/fesm2022/spartan-ng-brain-menu.mjs +316 -0
  274. package/fesm2022/spartan-ng-brain-menu.mjs.map +1 -0
  275. package/fesm2022/spartan-ng-brain-popover.mjs +173 -0
  276. package/fesm2022/spartan-ng-brain-popover.mjs.map +1 -0
  277. package/fesm2022/spartan-ng-brain-progress.mjs +108 -0
  278. package/fesm2022/spartan-ng-brain-progress.mjs.map +1 -0
  279. package/fesm2022/spartan-ng-brain-radio-group.mjs +299 -0
  280. package/fesm2022/spartan-ng-brain-radio-group.mjs.map +1 -0
  281. package/fesm2022/spartan-ng-brain-select.mjs +928 -0
  282. package/fesm2022/spartan-ng-brain-select.mjs.map +1 -0
  283. package/fesm2022/spartan-ng-brain-separator.mjs +44 -0
  284. package/fesm2022/spartan-ng-brain-separator.mjs.map +1 -0
  285. package/fesm2022/spartan-ng-brain-sheet.mjs +197 -0
  286. package/fesm2022/spartan-ng-brain-sheet.mjs.map +1 -0
  287. package/fesm2022/spartan-ng-brain-slider.mjs +399 -0
  288. package/fesm2022/spartan-ng-brain-slider.mjs.map +1 -0
  289. package/fesm2022/spartan-ng-brain-switch.mjs +271 -0
  290. package/fesm2022/spartan-ng-brain-switch.mjs.map +1 -0
  291. package/fesm2022/spartan-ng-brain-table.mjs +506 -0
  292. package/fesm2022/spartan-ng-brain-table.mjs.map +1 -0
  293. package/fesm2022/spartan-ng-brain-tabs.mjs +748 -0
  294. package/fesm2022/spartan-ng-brain-tabs.mjs.map +1 -0
  295. package/fesm2022/spartan-ng-brain-toggle.mjs +260 -0
  296. package/fesm2022/spartan-ng-brain-toggle.mjs.map +1 -0
  297. package/fesm2022/spartan-ng-brain-tooltip.mjs +975 -0
  298. package/fesm2022/spartan-ng-brain-tooltip.mjs.map +1 -0
  299. package/form-field/README.md +3 -0
  300. package/form-field/index.d.ts +1 -0
  301. package/form-field/lib/brn-form-field-control.d.ts +11 -0
  302. package/forms/README.md +3 -0
  303. package/forms/index.d.ts +3 -0
  304. package/forms/lib/control-value-accessor.d.ts +2 -0
  305. package/forms/lib/error-options.d.ts +14 -0
  306. package/forms/lib/error-state-tracker.d.ts +15 -0
  307. package/hover-card/README.md +3 -0
  308. package/hover-card/index.d.ts +14 -0
  309. package/hover-card/lib/brn-hover-card-content.service.d.ts +65 -0
  310. package/hover-card/lib/brn-hover-card.component.d.ts +9 -0
  311. package/hover-card/lib/createHoverObservable.d.ts +4 -0
  312. package/label/README.md +3 -0
  313. package/label/index.d.ts +8 -0
  314. package/label/lib/brn-label.directive.d.ts +15 -0
  315. package/menu/README.md +3 -0
  316. package/menu/index.d.ts +49 -0
  317. package/menu/lib/brn-context-menu-trigger.directive.d.ts +13 -0
  318. package/menu/lib/brn-menu-align.d.ts +3 -0
  319. package/menu/lib/brn-menu-bar.directive.d.ts +6 -0
  320. package/menu/lib/brn-menu-group.directive.d.ts +6 -0
  321. package/menu/lib/brn-menu-item-checkbox.directive.d.ts +11 -0
  322. package/menu/lib/brn-menu-item-radio.directive.d.ts +11 -0
  323. package/menu/lib/brn-menu-item.directive.d.ts +10 -0
  324. package/menu/lib/brn-menu-trigger.directive.d.ts +10 -0
  325. package/menu/lib/brn-menu.directive.d.ts +11 -0
  326. package/package.json +182 -9
  327. package/popover/README.md +3 -0
  328. package/popover/index.d.ts +19 -0
  329. package/popover/lib/brn-popover-close.directive.d.ts +6 -0
  330. package/popover/lib/brn-popover-content.directive.d.ts +6 -0
  331. package/popover/lib/brn-popover-trigger.directive.d.ts +10 -0
  332. package/popover/lib/brn-popover.component.d.ts +14 -0
  333. package/progress/README.md +3 -0
  334. package/progress/index.d.ts +14 -0
  335. package/progress/lib/brn-progress-indicator.component.d.ts +6 -0
  336. package/progress/lib/brn-progress.component.d.ts +15 -0
  337. package/progress/lib/brn-progress.token.d.ts +4 -0
  338. package/radio-group/README.md +3 -0
  339. package/radio-group/index.d.ts +13 -0
  340. package/radio-group/lib/brn-radio-group.component.d.ts +57 -0
  341. package/radio-group/lib/brn-radio-group.token.d.ts +4 -0
  342. package/radio-group/lib/brn-radio.component.d.ts +58 -0
  343. package/select/README.md +3 -0
  344. package/select/index.d.ts +28 -0
  345. package/select/lib/brn-select-content.component.d.ts +50 -0
  346. package/select/lib/brn-select-group.directive.d.ts +6 -0
  347. package/select/lib/brn-select-label.directive.d.ts +9 -0
  348. package/select/lib/brn-select-option.directive.d.ts +25 -0
  349. package/select/lib/brn-select-value.component.d.ts +11 -0
  350. package/select/lib/brn-select.component.d.ts +82 -0
  351. package/select/lib/brn-select.service.d.ts +67 -0
  352. package/separator/README.md +3 -0
  353. package/separator/index.d.ts +8 -0
  354. package/separator/lib/brn-separator.component.d.ts +11 -0
  355. package/sheet/README.md +3 -0
  356. package/sheet/index.d.ts +28 -0
  357. package/sheet/lib/brn-sheet-close.directive.d.ts +6 -0
  358. package/sheet/lib/brn-sheet-content.directive.d.ts +8 -0
  359. package/sheet/lib/brn-sheet-description.directive.d.ts +6 -0
  360. package/sheet/lib/brn-sheet-overlay.component.d.ts +6 -0
  361. package/sheet/lib/brn-sheet-title.directive.d.ts +6 -0
  362. package/sheet/lib/brn-sheet-trigger.directive.d.ts +9 -0
  363. package/sheet/lib/brn-sheet.component.d.ts +9 -0
  364. package/slider/README.md +3 -0
  365. package/slider/index.d.ts +7 -0
  366. package/slider/lib/brn-slider-thumb.directive.d.ts +17 -0
  367. package/slider/lib/brn-slider-tick-mark.directive.d.ts +15 -0
  368. package/slider/lib/brn-slider-track-active-fill.directive.d.ts +10 -0
  369. package/slider/lib/brn-slider-track.directive.d.ts +139 -0
  370. package/switch/README.md +3 -0
  371. package/switch/index.d.ts +13 -0
  372. package/switch/lib/brn-switch-thumb.component.d.ts +5 -0
  373. package/switch/lib/brn-switch.component.d.ts +58 -0
  374. package/table/README.md +3 -0
  375. package/table/index.d.ts +26 -0
  376. package/table/lib/brn-cell-def.directive.d.ts +9 -0
  377. package/table/lib/brn-column-def.component.d.ts +18 -0
  378. package/table/lib/brn-column-manager.d.ts +26 -0
  379. package/table/lib/brn-footer-def.directive.d.ts +9 -0
  380. package/table/lib/brn-header-def.directive.d.ts +9 -0
  381. package/table/lib/brn-paginator.directive.d.ts +41 -0
  382. package/table/lib/brn-table.component.d.ts +37 -0
  383. package/tabs/README.md +3 -0
  384. package/tabs/index.d.ts +14 -0
  385. package/tabs/lib/brn-tabs-list.directive.d.ts +17 -0
  386. package/tabs/lib/brn-tabs-paginated-list.directive.d.ts +196 -0
  387. package/tabs/lib/brn-tabs-trigger.directive.d.ts +61 -0
  388. package/toggle/README.md +3 -0
  389. package/toggle/index.d.ts +15 -0
  390. package/toggle/lib/brn-toggle-group.component.d.ts +68 -0
  391. package/toggle/lib/brn-toggle-group.token.d.ts +4 -0
  392. package/toggle/lib/brn-toggle.directive.d.ts +25 -0
  393. package/tooltip/README.md +3 -0
  394. package/tooltip/index.d.ts +19 -0
  395. package/tooltip/lib/brn-tooltip-content.component.d.ts +73 -0
  396. package/tooltip/lib/brn-tooltip-content.directive.d.ts +8 -0
  397. package/tooltip/lib/brn-tooltip-trigger.directive.d.ts +177 -0
  398. package/tooltip/lib/brn-tooltip.directive.d.ts +7 -0
@@ -0,0 +1,525 @@
1
+ /**
2
+ * We are building on shoulders of giants here and adapt the implementation provided by the incredible Angular
3
+ * team: https://github.com/angular/components/blob/main/src/material/tabs/paginated-tab-header.ts
4
+ * Check them out! Give them a try! Leave a star! Their work is incredible!
5
+ */
6
+ /**
7
+ * @license
8
+ * Copyright Google LLC All Rights Reserved.
9
+ *
10
+ * Use of this source code is governed by an MIT-style license that can be
11
+ * found in the LICENSE file at https://angular.io/license
12
+ */
13
+ import { FocusKeyManager } from '@angular/cdk/a11y';
14
+ import { Directionality } from '@angular/cdk/bidi';
15
+ import { ENTER, SPACE, hasModifierKey } from '@angular/cdk/keycodes';
16
+ import { SharedResizeObserver } from '@angular/cdk/observers/private';
17
+ import { Platform, normalizePassiveListenerOptions } from '@angular/cdk/platform';
18
+ import { ViewportRuler } from '@angular/cdk/scrolling';
19
+ import { ANIMATION_MODULE_TYPE, ChangeDetectorRef, Directive, ElementRef, Injector, NgZone, afterNextRender, booleanAttribute, computed, effect, inject, input, output, signal, } from '@angular/core';
20
+ import { EMPTY, Observable, Subject, fromEvent, merge, of as observableOf, timer } from 'rxjs';
21
+ import { debounceTime, filter, skip, startWith, switchMap, takeUntil } from 'rxjs/operators';
22
+ import { BrnTabsDirective } from './brn-tabs-trigger.directive';
23
+ import * as i0 from "@angular/core";
24
+ /** Config used to bind passive event listeners */
25
+ const passiveEventListenerOptions = normalizePassiveListenerOptions({
26
+ passive: true,
27
+ });
28
+ /**
29
+ * Amount of milliseconds to wait before starting to scroll the header automatically.
30
+ * Set a little conservatively in order to handle fake events dispatched on touch devices.
31
+ */
32
+ const HEADER_SCROLL_DELAY = 650;
33
+ /**
34
+ * Interval in milliseconds at which to scroll the header
35
+ * while the user is holding their pointer.
36
+ */
37
+ const HEADER_SCROLL_INTERVAL = 100;
38
+ /**
39
+ * Base class for a tab header that supported pagination.
40
+ * @docs-private
41
+ */
42
+ export class BrnTabsPaginatedListDirective {
43
+ /** The distance in pixels that the tab labels should be translated to the left. */
44
+ _scrollDistance = 0;
45
+ /** Whether the header should scroll to the selected index after the view has been checked. */
46
+ _selectedIndexChanged = false;
47
+ _root = inject(BrnTabsDirective);
48
+ _activeTab = this._root.$activeTab;
49
+ _tabs = this._root.$tabs;
50
+ /** Emits when the component is destroyed. */
51
+ _destroyed = new Subject();
52
+ /** Whether the controls for pagination should be displayed */
53
+ _showPaginationControls = signal(false);
54
+ /** Whether the tab list can be scrolled more towards the end of the tab label list. */
55
+ _disableScrollAfter = true;
56
+ /** Whether the tab list can be scrolled more towards the beginning of the tab label list. */
57
+ _disableScrollBefore = true;
58
+ /**
59
+ * The number of tab labels that are displayed on the header. When this changes, the header
60
+ * should re-evaluate the scroll position.
61
+ */
62
+ _tabLabelCount;
63
+ /** Whether the scroll distance has changed and should be applied after the view is checked. */
64
+ _scrollDistanceChanged;
65
+ /** Used to manage focus between the tabs. */
66
+ _keyManager;
67
+ /** Cached text content of the header. */
68
+ _currentTextContent;
69
+ /** Stream that will stop the automated scrolling. */
70
+ _stopScrolling = new Subject();
71
+ /**
72
+ * Whether pagination should be disabled. This can be used to avoid unnecessary
73
+ * layout recalculations if it's known that pagination won't be required.
74
+ */
75
+ disablePagination = input(false, { transform: booleanAttribute });
76
+ /** The index of the active tab. */
77
+ _selectedIndex = computed(() => {
78
+ const currentTabKey = this._activeTab();
79
+ const tabs = this._tabs();
80
+ let activeIndex = 0;
81
+ if (currentTabKey && this._items()) {
82
+ const currentTab = tabs[currentTabKey];
83
+ if (currentTab) {
84
+ activeIndex = this._items().indexOf(currentTab.trigger);
85
+ }
86
+ }
87
+ return activeIndex;
88
+ });
89
+ /** Event emitted when the option is selected. */
90
+ selectFocusedIndex = output();
91
+ /** Event emitted when a label is focused. */
92
+ indexFocused = output();
93
+ _sharedResizeObserver = inject(SharedResizeObserver);
94
+ _injector = inject(Injector);
95
+ _elementRef = inject(ElementRef);
96
+ _changeDetectorRef = inject(ChangeDetectorRef);
97
+ _viewportRuler = inject(ViewportRuler);
98
+ _dir = inject(Directionality, { optional: true });
99
+ _ngZone = inject(NgZone);
100
+ _platform = inject(Platform);
101
+ _animationMode = inject(ANIMATION_MODULE_TYPE, { optional: true });
102
+ constructor() {
103
+ // Bind the `mouseleave` event on the outside since it doesn't change anything in the view.
104
+ this._ngZone.runOutsideAngular(() => {
105
+ fromEvent(this._elementRef.nativeElement, 'mouseleave')
106
+ .pipe(takeUntil(this._destroyed))
107
+ .subscribe(() => {
108
+ this._stopInterval();
109
+ });
110
+ });
111
+ effect(() => {
112
+ const selectedIndex = this._selectedIndex();
113
+ if (selectedIndex !== 0) {
114
+ this._selectedIndexChanged = true;
115
+ if (this._keyManager) {
116
+ this._keyManager.updateActiveItem(selectedIndex);
117
+ }
118
+ }
119
+ });
120
+ }
121
+ ngAfterViewInit() {
122
+ // We need to handle these events manually, because we want to bind passive event listeners.
123
+ fromEvent(this._previousPaginator().nativeElement, 'touchstart', passiveEventListenerOptions)
124
+ .pipe(takeUntil(this._destroyed))
125
+ .subscribe(() => {
126
+ this._handlePaginatorPress('before');
127
+ });
128
+ fromEvent(this._nextPaginator().nativeElement, 'touchstart', passiveEventListenerOptions)
129
+ .pipe(takeUntil(this._destroyed))
130
+ .subscribe(() => {
131
+ this._handlePaginatorPress('after');
132
+ });
133
+ }
134
+ ngAfterContentInit() {
135
+ const dirChange = this._dir ? this._dir.change : observableOf('ltr');
136
+ // We need to debounce resize events because the alignment logic is expensive.
137
+ // If someone animates the width of tabs, we don't want to realign on every animation frame.
138
+ // Once we haven't seen any more resize events in the last 32ms (~2 animaion frames) we can
139
+ // re-align.
140
+ const resize = this._sharedResizeObserver
141
+ .observe(this._elementRef.nativeElement)
142
+ .pipe(debounceTime(32), takeUntil(this._destroyed));
143
+ // Note: We do not actually need to watch these events for proper functioning of the tabs,
144
+ // the resize events above should capture any viewport resize that we care about. However,
145
+ // removing this is fairly breaking for screenshot tests, so we're leaving it here for now.
146
+ const viewportResize = this._viewportRuler.change(150).pipe(takeUntil(this._destroyed));
147
+ const realign = () => {
148
+ this.updatePagination();
149
+ };
150
+ this._keyManager = new FocusKeyManager(this._items())
151
+ .withHorizontalOrientation(this._getLayoutDirection())
152
+ .withHomeAndEnd()
153
+ .withWrap()
154
+ // Allow focus to land on disabled tabs, as per https://w3c.github.io/aria-practices/#kbd_disabled_controls
155
+ .skipPredicate(() => false);
156
+ this._keyManager.updateActiveItem(this._selectedIndex());
157
+ // Note: We do not need to realign after the first render for proper functioning of the tabs
158
+ // the resize events above should fire when we first start observing the element. However,
159
+ // removing this is fairly breaking for screenshot tests, so we're leaving it here for now.
160
+ afterNextRender(realign, { injector: this._injector });
161
+ // On dir change or resize, realign the ink bar and update the orientation of
162
+ // the key manager if the direction has changed.
163
+ merge(dirChange, viewportResize, resize, this._itemsChanges, this._itemsResized())
164
+ .pipe(takeUntil(this._destroyed))
165
+ .subscribe(() => {
166
+ // We need to defer this to give the browser some time to recalculate
167
+ // the element dimensions. The call has to be wrapped in `NgZone.run`,
168
+ // because the viewport change handler runs outside of Angular.
169
+ this._ngZone.run(() => {
170
+ Promise.resolve().then(() => {
171
+ // Clamp the scroll distance, because it can change with the number of tabs.
172
+ this._scrollDistance = Math.max(0, Math.min(this._getMaxScrollDistance(), this._scrollDistance));
173
+ realign();
174
+ });
175
+ });
176
+ this._keyManager.withHorizontalOrientation(this._getLayoutDirection());
177
+ });
178
+ // If there is a change in the focus key manager we need to emit the `indexFocused`
179
+ // event in order to provide a public event that notifies about focus changes. Also we realign
180
+ // the tabs container by scrolling the new focused tab into the visible section.
181
+ this._keyManager.change.subscribe((newFocusIndex) => {
182
+ this.indexFocused.emit(newFocusIndex);
183
+ this._setTabFocus(newFocusIndex);
184
+ });
185
+ }
186
+ /** Sends any changes that could affect the layout of the items. */
187
+ _itemsResized() {
188
+ if (typeof ResizeObserver !== 'function') {
189
+ return EMPTY;
190
+ }
191
+ return this._itemsChanges.pipe(startWith(this._items()), switchMap((tabItems) => new Observable((observer) => this._ngZone.runOutsideAngular(() => {
192
+ const resizeObserver = new ResizeObserver((entries) => observer.next(entries));
193
+ for (const tabItem of tabItems) {
194
+ resizeObserver.observe(tabItem.elementRef.nativeElement);
195
+ }
196
+ return () => {
197
+ resizeObserver.disconnect();
198
+ };
199
+ }))),
200
+ // Skip the first emit since the resize observer emits when an item
201
+ // is observed for new items when the tab is already inserted
202
+ skip(1),
203
+ // Skip emissions where all the elements are invisible since we don't want
204
+ // the header to try and re-render with invalid measurements. See #25574.
205
+ filter((entries) => entries.some((e) => e.contentRect.width > 0 && e.contentRect.height > 0)));
206
+ }
207
+ ngAfterContentChecked() {
208
+ // If the number of tab labels have changed, check if scrolling should be enabled
209
+ if (this._tabLabelCount !== this._items().length) {
210
+ this.updatePagination();
211
+ this._tabLabelCount = this._items().length;
212
+ this._changeDetectorRef.markForCheck();
213
+ }
214
+ // If the selected index has changed, scroll to the label and check if the scrolling controls
215
+ // should be disabled.
216
+ if (this._selectedIndexChanged) {
217
+ this._scrollToLabel(this._selectedIndex());
218
+ this._checkScrollingControls();
219
+ this._selectedIndexChanged = false;
220
+ this._changeDetectorRef.markForCheck();
221
+ }
222
+ // If the scroll distance has been changed (tab selected, focused, scroll controls activated),
223
+ // then translate the header to reflect this.
224
+ if (this._scrollDistanceChanged) {
225
+ this._updateTabScrollPosition();
226
+ this._scrollDistanceChanged = false;
227
+ this._changeDetectorRef.markForCheck();
228
+ }
229
+ }
230
+ ngOnDestroy() {
231
+ this._keyManager?.destroy();
232
+ this._destroyed.next();
233
+ this._destroyed.complete();
234
+ this._stopScrolling.complete();
235
+ }
236
+ /** Handles keyboard events on the header. */
237
+ _handleKeydown(event) {
238
+ // We don't handle any key bindings with a modifier key.
239
+ if (hasModifierKey(event)) {
240
+ return;
241
+ }
242
+ switch (event.keyCode) {
243
+ case ENTER:
244
+ case SPACE:
245
+ if (this.focusIndex !== this._selectedIndex()) {
246
+ const item = this._items()[this.focusIndex];
247
+ if (item && !item.disabled) {
248
+ this.selectFocusedIndex.emit(this.focusIndex);
249
+ this._itemSelected(event);
250
+ }
251
+ }
252
+ break;
253
+ default:
254
+ this._keyManager.onKeydown(event);
255
+ }
256
+ }
257
+ /**
258
+ * Callback for when the MutationObserver detects that the content has changed.
259
+ */
260
+ _onContentChanges() {
261
+ const textContent = this._elementRef.nativeElement.textContent;
262
+ // We need to diff the text content of the header, because the MutationObserver callback
263
+ // will fire even if the text content didn't change which is inefficient and is prone
264
+ // to infinite loops if a poorly constructed expression is passed in (see #14249).
265
+ if (textContent !== this._currentTextContent) {
266
+ this._currentTextContent = textContent || '';
267
+ // The content observer runs outside the `NgZone` by default, which
268
+ // means that we need to bring the callback back in ourselves.
269
+ this._ngZone.run(() => {
270
+ this.updatePagination();
271
+ this._changeDetectorRef.markForCheck();
272
+ });
273
+ }
274
+ }
275
+ /**
276
+ * Updates the view whether pagination should be enabled or not.
277
+ *
278
+ * WARNING: Calling this method can be very costly in terms of performance. It should be called
279
+ * as infrequently as possible from outside of the Tabs component as it causes a reflow of the
280
+ * page.
281
+ */
282
+ updatePagination() {
283
+ this._checkPaginationEnabled();
284
+ this._checkScrollingControls();
285
+ this._updateTabScrollPosition();
286
+ }
287
+ /** Tracks which element has focus; used for keyboard navigation */
288
+ get focusIndex() {
289
+ return this._keyManager ? (this._keyManager.activeItemIndex ?? 0) : 0;
290
+ }
291
+ /** When the focus index is set, we must manually send focus to the correct label */
292
+ set focusIndex(value) {
293
+ if (!this._isValidIndex(value) || this.focusIndex === value || !this._keyManager) {
294
+ return;
295
+ }
296
+ this._keyManager.setActiveItem(value);
297
+ }
298
+ /**
299
+ * Determines if an index is valid. If the tabs are not ready yet, we assume that the user is
300
+ * providing a valid index and return true.
301
+ */
302
+ _isValidIndex(index) {
303
+ return this._items() ? !!this._items()[index] : true;
304
+ }
305
+ /**
306
+ * Sets focus on the HTML element for the label wrapper and scrolls it into the view if
307
+ * scrolling is enabled.
308
+ */
309
+ _setTabFocus(tabIndex) {
310
+ if (this._showPaginationControls()) {
311
+ this._scrollToLabel(tabIndex);
312
+ }
313
+ if (this._items()?.length) {
314
+ this._items()[tabIndex].focus();
315
+ // Do not let the browser manage scrolling to focus the element, this will be handled
316
+ // by using translation. In LTR, the scroll left should be 0. In RTL, the scroll width
317
+ // should be the full width minus the offset width.
318
+ const containerEl = this._tabListContainer().nativeElement;
319
+ const dir = this._getLayoutDirection();
320
+ if (dir === 'ltr') {
321
+ containerEl.scrollLeft = 0;
322
+ }
323
+ else {
324
+ containerEl.scrollLeft = containerEl.scrollWidth - containerEl.offsetWidth;
325
+ }
326
+ }
327
+ }
328
+ /** The layout direction of the containing app. */
329
+ _getLayoutDirection() {
330
+ return this._dir && this._dir.value === 'rtl' ? 'rtl' : 'ltr';
331
+ }
332
+ /** Performs the CSS transformation on the tab list that will cause the list to scroll. */
333
+ _updateTabScrollPosition() {
334
+ if (this.disablePagination()) {
335
+ return;
336
+ }
337
+ const scrollDistance = this.scrollDistance;
338
+ const translateX = this._getLayoutDirection() === 'ltr' ? -scrollDistance : scrollDistance;
339
+ // Don't use `translate3d` here because we don't want to create a new layer. A new layer
340
+ // seems to cause flickering and overflow in Internet Explorer. For example, the ink bar
341
+ // and ripples will exceed the boundaries of the visible tab bar.
342
+ // See: https://github.com/angular/components/issues/10276
343
+ // We round the `transform` here, because transforms with sub-pixel precision cause some
344
+ // browsers to blur the content of the element.
345
+ this._tabList().nativeElement.style.transform = `translateX(${Math.round(translateX)}px)`;
346
+ // Setting the `transform` on IE will change the scroll offset of the parent, causing the
347
+ // position to be thrown off in some cases. We have to reset it ourselves to ensure that
348
+ // it doesn't get thrown off. Note that we scope it only to IE and Edge, because messing
349
+ // with the scroll position throws off Chrome 71+ in RTL mode (see #14689).
350
+ if (this._platform.TRIDENT || this._platform.EDGE) {
351
+ this._tabListContainer().nativeElement.scrollLeft = 0;
352
+ }
353
+ }
354
+ /** Sets the distance in pixels that the tab header should be transformed in the X-axis. */
355
+ get scrollDistance() {
356
+ return this._scrollDistance;
357
+ }
358
+ set scrollDistance(value) {
359
+ this._scrollTo(value);
360
+ }
361
+ /**
362
+ * Moves the tab list in the 'before' or 'after' direction (towards the beginning of the list or
363
+ * the end of the list, respectively). The distance to scroll is computed to be a third of the
364
+ * length of the tab list view window.
365
+ *
366
+ * This is an expensive call that forces a layout reflow to compute box and scroll metrics and
367
+ * should be called sparingly.
368
+ */
369
+ _scrollHeader(direction) {
370
+ const viewLength = this._tabListContainer().nativeElement.offsetWidth;
371
+ // Move the scroll distance one-third the length of the tab list's viewport.
372
+ const scrollAmount = ((direction === 'before' ? -1 : 1) * viewLength) / 3;
373
+ return this._scrollTo(this._scrollDistance + scrollAmount);
374
+ }
375
+ /** Handles click events on the pagination arrows. */
376
+ _handlePaginatorClick(direction) {
377
+ this._stopInterval();
378
+ this._scrollHeader(direction);
379
+ }
380
+ /**
381
+ * Moves the tab list such that the desired tab label (marked by index) is moved into view.
382
+ *
383
+ * This is an expensive call that forces a layout reflow to compute box and scroll metrics and
384
+ * should be called sparingly.
385
+ */
386
+ _scrollToLabel(labelIndex) {
387
+ if (this.disablePagination()) {
388
+ return;
389
+ }
390
+ const selectedLabel = this._items() ? this._items()[labelIndex] : null;
391
+ if (!selectedLabel) {
392
+ return;
393
+ }
394
+ // The view length is the visible width of the tab labels.
395
+ const viewLength = this._tabListContainer().nativeElement.offsetWidth;
396
+ const { offsetLeft, offsetWidth } = selectedLabel.elementRef.nativeElement;
397
+ let labelBeforePos;
398
+ let labelAfterPos;
399
+ if (this._getLayoutDirection() === 'ltr') {
400
+ labelBeforePos = offsetLeft;
401
+ labelAfterPos = labelBeforePos + offsetWidth;
402
+ }
403
+ else {
404
+ labelAfterPos = this._tabListInner().nativeElement.offsetWidth - offsetLeft;
405
+ labelBeforePos = labelAfterPos - offsetWidth;
406
+ }
407
+ const beforeVisiblePos = this.scrollDistance;
408
+ const afterVisiblePos = this.scrollDistance + viewLength;
409
+ if (labelBeforePos < beforeVisiblePos) {
410
+ // Scroll header to move label to the before direction
411
+ this.scrollDistance -= beforeVisiblePos - labelBeforePos;
412
+ }
413
+ else if (labelAfterPos > afterVisiblePos) {
414
+ // Scroll header to move label to the after direction
415
+ this.scrollDistance += Math.min(labelAfterPos - afterVisiblePos, labelBeforePos - beforeVisiblePos);
416
+ }
417
+ }
418
+ /**
419
+ * Evaluate whether the pagination controls should be displayed. If the scroll width of the
420
+ * tab list is wider than the size of the header container, then the pagination controls should
421
+ * be shown.
422
+ *
423
+ * This is an expensive call that forces a layout reflow to compute box and scroll metrics and
424
+ * should be called sparingly.
425
+ */
426
+ _checkPaginationEnabled() {
427
+ if (this.disablePagination()) {
428
+ this._showPaginationControls.set(false);
429
+ }
430
+ else {
431
+ const isEnabled = this._tabListInner().nativeElement.scrollWidth > this._elementRef.nativeElement.offsetWidth;
432
+ if (!isEnabled) {
433
+ this.scrollDistance = 0;
434
+ }
435
+ if (isEnabled !== this._showPaginationControls()) {
436
+ this._changeDetectorRef.markForCheck();
437
+ }
438
+ this._showPaginationControls.set(isEnabled);
439
+ }
440
+ }
441
+ /**
442
+ * Evaluate whether the before and after controls should be enabled or disabled.
443
+ * If the header is at the beginning of the list (scroll distance is equal to 0) then disable the
444
+ * before button. If the header is at the end of the list (scroll distance is equal to the
445
+ * maximum distance we can scroll), then disable the after button.
446
+ *
447
+ * This is an expensive call that forces a layout reflow to compute box and scroll metrics and
448
+ * should be called sparingly.
449
+ */
450
+ _checkScrollingControls() {
451
+ if (this.disablePagination()) {
452
+ this._disableScrollAfter = this._disableScrollBefore = true;
453
+ }
454
+ else {
455
+ // Check if the pagination arrows should be activated.
456
+ this._disableScrollBefore = this.scrollDistance === 0;
457
+ this._disableScrollAfter = this.scrollDistance === this._getMaxScrollDistance();
458
+ this._changeDetectorRef.markForCheck();
459
+ }
460
+ }
461
+ /**
462
+ * Determines what is the maximum length in pixels that can be set for the scroll distance. This
463
+ * is equal to the difference in width between the tab list container and tab header container.
464
+ *
465
+ * This is an expensive call that forces a layout reflow to compute box and scroll metrics and
466
+ * should be called sparingly.
467
+ */
468
+ _getMaxScrollDistance() {
469
+ const lengthOfTabList = this._tabListInner().nativeElement.scrollWidth;
470
+ const viewLength = this._tabListContainer().nativeElement.offsetWidth;
471
+ return lengthOfTabList - viewLength || 0;
472
+ }
473
+ /** Stops the currently-running paginator interval. */
474
+ _stopInterval() {
475
+ this._stopScrolling.next();
476
+ }
477
+ /**
478
+ * Handles the user pressing down on one of the paginators.
479
+ * Starts scrolling the header after a certain amount of time.
480
+ * @param direction In which direction the paginator should be scrolled.
481
+ */
482
+ _handlePaginatorPress(direction, mouseEvent) {
483
+ // Don't start auto scrolling for right mouse button clicks. Note that we shouldn't have to
484
+ // null check the `button`, but we do it so we don't break tests that use fake events.
485
+ if (mouseEvent && mouseEvent.button !== null && mouseEvent.button !== 0) {
486
+ return;
487
+ }
488
+ // Avoid overlapping timers.
489
+ this._stopInterval();
490
+ // Start a timer after the delay and keep firing based on the interval.
491
+ timer(HEADER_SCROLL_DELAY, HEADER_SCROLL_INTERVAL)
492
+ // Keep the timer going until something tells it to stop or the component is destroyed.
493
+ .pipe(takeUntil(merge(this._stopScrolling, this._destroyed)))
494
+ .subscribe(() => {
495
+ const { maxScrollDistance, distance } = this._scrollHeader(direction);
496
+ // Stop the timer if we've reached the start or the end.
497
+ if (distance === 0 || distance >= maxScrollDistance) {
498
+ this._stopInterval();
499
+ }
500
+ });
501
+ }
502
+ /**
503
+ * Scrolls the header to a given position.
504
+ * @param position Position to which to scroll.
505
+ * @returns Information on the current scroll distance and the maximum.
506
+ */
507
+ _scrollTo(position) {
508
+ if (this.disablePagination()) {
509
+ return { maxScrollDistance: 0, distance: 0 };
510
+ }
511
+ const maxScrollDistance = this._getMaxScrollDistance();
512
+ this._scrollDistance = Math.max(0, Math.min(maxScrollDistance, position));
513
+ // Mark that the scroll distance has changed so that after the view is checked, the CSS
514
+ // transformation can move the header.
515
+ this._scrollDistanceChanged = true;
516
+ this._checkScrollingControls();
517
+ return { maxScrollDistance, distance: this._scrollDistance };
518
+ }
519
+ /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: BrnTabsPaginatedListDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive });
520
+ /** @nocollapse */ static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.5", type: BrnTabsPaginatedListDirective, inputs: { disablePagination: { classPropertyName: "disablePagination", publicName: "disablePagination", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { selectFocusedIndex: "selectFocusedIndex", indexFocused: "indexFocused" }, ngImport: i0 });
521
+ }
522
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.5", ngImport: i0, type: BrnTabsPaginatedListDirective, decorators: [{
523
+ type: Directive
524
+ }], ctorParameters: () => [] });
525
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYnJuLXRhYnMtcGFnaW5hdGVkLWxpc3QuZGlyZWN0aXZlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vbGlicy9icmFpbi90YWJzL3NyYy9saWIvYnJuLXRhYnMtcGFnaW5hdGVkLWxpc3QuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7O0dBSUc7QUFFSDs7Ozs7O0dBTUc7QUFFSCxPQUFPLEVBQUUsZUFBZSxFQUF3QixNQUFNLG1CQUFtQixDQUFDO0FBQzFFLE9BQU8sRUFBa0IsY0FBYyxFQUFFLE1BQU0sbUJBQW1CLENBQUM7QUFDbkUsT0FBTyxFQUFFLEtBQUssRUFBRSxLQUFLLEVBQUUsY0FBYyxFQUFFLE1BQU0sdUJBQXVCLENBQUM7QUFDckUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sZ0NBQWdDLENBQUM7QUFDdEUsT0FBTyxFQUFFLFFBQVEsRUFBRSwrQkFBK0IsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ2xGLE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN2RCxPQUFPLEVBQ04scUJBQXFCLEVBSXJCLGlCQUFpQixFQUNqQixTQUFTLEVBQ1QsVUFBVSxFQUNWLFFBQVEsRUFDUixNQUFNLEVBR04sZUFBZSxFQUNmLGdCQUFnQixFQUNoQixRQUFRLEVBQ1IsTUFBTSxFQUNOLE1BQU0sRUFDTixLQUFLLEVBQ0wsTUFBTSxFQUNOLE1BQU0sR0FDTixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsS0FBSyxFQUFFLFVBQVUsRUFBaUIsT0FBTyxFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQUUsRUFBRSxJQUFJLFlBQVksRUFBRSxLQUFLLEVBQUUsTUFBTSxNQUFNLENBQUM7QUFDOUcsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDN0YsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0sOEJBQThCLENBQUM7O0FBRWhFLGtEQUFrRDtBQUNsRCxNQUFNLDJCQUEyQixHQUFHLCtCQUErQixDQUFDO0lBQ25FLE9BQU8sRUFBRSxJQUFJO0NBQ2IsQ0FBeUIsQ0FBQztBQVMzQjs7O0dBR0c7QUFDSCxNQUFNLG1CQUFtQixHQUFHLEdBQUcsQ0FBQztBQUVoQzs7O0dBR0c7QUFDSCxNQUFNLHNCQUFzQixHQUFHLEdBQUcsQ0FBQztBQUtuQzs7O0dBR0c7QUFFSCxNQUFNLE9BQWdCLDZCQUE2QjtJQVdsRCxtRkFBbUY7SUFDM0UsZUFBZSxHQUFHLENBQUMsQ0FBQztJQUU1Qiw4RkFBOEY7SUFDdEYscUJBQXFCLEdBQUcsS0FBSyxDQUFDO0lBRXJCLEtBQUssR0FBRyxNQUFNLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztJQUNqQyxVQUFVLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUM7SUFDbkMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsS0FBSyxDQUFDO0lBRTFDLDZDQUE2QztJQUMxQixVQUFVLEdBQUcsSUFBSSxPQUFPLEVBQVEsQ0FBQztJQUVwRCw4REFBOEQ7SUFDdkQsdUJBQXVCLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBRS9DLHVGQUF1RjtJQUNoRixtQkFBbUIsR0FBRyxJQUFJLENBQUM7SUFFbEMsNkZBQTZGO0lBQ3RGLG9CQUFvQixHQUFHLElBQUksQ0FBQztJQUVuQzs7O09BR0c7SUFDSyxjQUFjLENBQVU7SUFFaEMsK0ZBQStGO0lBQ3ZGLHNCQUFzQixDQUFXO0lBRXpDLDZDQUE2QztJQUNyQyxXQUFXLENBQThDO0lBRWpFLHlDQUF5QztJQUNqQyxtQkFBbUIsQ0FBVTtJQUVyQyxxREFBcUQ7SUFDcEMsY0FBYyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFFdEQ7OztPQUdHO0lBQ0ksaUJBQWlCLEdBQUcsS0FBSyxDQUFDLEtBQUssRUFBRSxFQUFFLFNBQVMsRUFBRSxnQkFBZ0IsRUFBRSxDQUFDLENBQUM7SUFFekUsbUNBQW1DO0lBQ2xCLGNBQWMsR0FBRyxRQUFRLENBQUMsR0FBRyxFQUFFO1FBQy9DLE1BQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUN4QyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFFMUIsSUFBSSxXQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ3BCLElBQUksYUFBYSxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDO1lBQ3BDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUN2QyxJQUFJLFVBQVUsRUFBRSxDQUFDO2dCQUNoQixXQUFXLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDekQsQ0FBQztRQUNGLENBQUM7UUFFRCxPQUFPLFdBQVcsQ0FBQztJQUNwQixDQUFDLENBQUMsQ0FBQztJQUVILGlEQUFpRDtJQUNqQyxrQkFBa0IsR0FBRyxNQUFNLEVBQVUsQ0FBQztJQUV0RCw2Q0FBNkM7SUFDN0IsWUFBWSxHQUFHLE1BQU0sRUFBVSxDQUFDO0lBRS9CLHFCQUFxQixHQUFHLE1BQU0sQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBRXJELFNBQVMsR0FBRyxNQUFNLENBQUMsUUFBUSxDQUFDLENBQUM7SUFFcEMsV0FBVyxHQUE0QixNQUFNLENBQUMsVUFBVSxDQUFDLENBQUM7SUFDMUQsa0JBQWtCLEdBQXNCLE1BQU0sQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO0lBQzNELGNBQWMsR0FBa0IsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDO0lBQ3RELElBQUksR0FBRyxNQUFNLENBQUMsY0FBYyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7SUFDbEQsT0FBTyxHQUFXLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUNqQyxTQUFTLEdBQWEsTUFBTSxDQUFDLFFBQVEsQ0FBQyxDQUFDO0lBQ2pELGNBQWMsR0FBRyxNQUFNLENBQUMscUJBQXFCLEVBQUUsRUFBRSxRQUFRLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztJQUUxRTtRQUNDLDJGQUEyRjtRQUMzRixJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUNuQyxTQUFTLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLEVBQUUsWUFBWSxDQUFDO2lCQUNyRCxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztpQkFDaEMsU0FBUyxDQUFDLEdBQUcsRUFBRTtnQkFDZixJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDdEIsQ0FBQyxDQUFDLENBQUM7UUFDTCxDQUFDLENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxHQUFHLEVBQUU7WUFDWCxNQUFNLGFBQWEsR0FBRyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUM7WUFFNUMsSUFBSSxhQUFhLEtBQUssQ0FBQyxFQUFFLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxJQUFJLENBQUM7Z0JBQ2xDLElBQUksSUFBSSxDQUFDLFdBQVcsRUFBRSxDQUFDO29CQUN0QixJQUFJLENBQUMsV0FBVyxDQUFDLGdCQUFnQixDQUFDLGFBQWEsQ0FBQyxDQUFDO2dCQUNsRCxDQUFDO1lBQ0YsQ0FBQztRQUNGLENBQUMsQ0FBQyxDQUFDO0lBQ0osQ0FBQztJQUtELGVBQWU7UUFDZCw0RkFBNEY7UUFDNUYsU0FBUyxDQUFDLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDLGFBQWEsRUFBRSxZQUFZLEVBQUUsMkJBQTJCLENBQUM7YUFDM0YsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDaEMsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNmLElBQUksQ0FBQyxxQkFBcUIsQ0FBQyxRQUFRLENBQUMsQ0FBQztRQUN0QyxDQUFDLENBQUMsQ0FBQztRQUVKLFNBQVMsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsYUFBYSxFQUFFLFlBQVksRUFBRSwyQkFBMkIsQ0FBQzthQUN2RixJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUNoQyxTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2YsSUFBSSxDQUFDLHFCQUFxQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ3JDLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELGtCQUFrQjtRQUNqQixNQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3JFLDhFQUE4RTtRQUM5RSw0RkFBNEY7UUFDNUYsMkZBQTJGO1FBQzNGLFlBQVk7UUFDWixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMscUJBQXFCO2FBQ3ZDLE9BQU8sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQzthQUN2QyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsQ0FBQyxFQUFFLFNBQVMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQztRQUNyRCwwRkFBMEY7UUFDMUYsMEZBQTBGO1FBQzFGLDJGQUEyRjtRQUMzRixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDO1FBRXhGLE1BQU0sT0FBTyxHQUFHLEdBQUcsRUFBRTtZQUNwQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztRQUN6QixDQUFDLENBQUM7UUFFRixJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksZUFBZSxDQUE0QixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7YUFDOUUseUJBQXlCLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUM7YUFDckQsY0FBYyxFQUFFO2FBQ2hCLFFBQVEsRUFBRTtZQUNYLDJHQUEyRzthQUMxRyxhQUFhLENBQUMsR0FBRyxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFN0IsSUFBSSxDQUFDLFdBQVcsQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQztRQUV6RCw0RkFBNEY7UUFDNUYsMEZBQTBGO1FBQzFGLDJGQUEyRjtRQUMzRixlQUFlLENBQUMsT0FBTyxFQUFFLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQyxDQUFDO1FBRXZELDZFQUE2RTtRQUM3RSxnREFBZ0Q7UUFDaEQsS0FBSyxDQUFDLFNBQVMsRUFBRSxjQUFjLEVBQUUsTUFBTSxFQUFFLElBQUksQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO2FBQ2hGLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO2FBQ2hDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDZixxRUFBcUU7WUFDckUsc0VBQXNFO1lBQ3RFLCtEQUErRDtZQUMvRCxJQUFJLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxHQUFHLEVBQUU7Z0JBQ3JCLE9BQU8sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFO29CQUMzQiw0RUFBNEU7b0JBQzVFLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMscUJBQXFCLEVBQUUsRUFBRSxJQUFJLENBQUMsZUFBZSxDQUFDLENBQUMsQ0FBQztvQkFDakcsT0FBTyxFQUFFLENBQUM7Z0JBQ1gsQ0FBQyxDQUFDLENBQUM7WUFDSixDQUFDLENBQUMsQ0FBQztZQUNILElBQUksQ0FBQyxXQUFXLENBQUMseUJBQXlCLENBQUMsSUFBSSxDQUFDLG1CQUFtQixFQUFFLENBQUMsQ0FBQztRQUN4RSxDQUFDLENBQUMsQ0FBQztRQUVKLG1GQUFtRjtRQUNuRiw4RkFBOEY7UUFDOUYsZ0ZBQWdGO1FBQ2hGLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQyxDQUFDLGFBQWEsRUFBRSxFQUFFO1lBQ25ELElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1lBQ3RDLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxDQUFDLENBQUM7UUFDbEMsQ0FBQyxDQUFDLENBQUM7SUFDSixDQUFDO0lBRUQsbUVBQW1FO0lBQzNELGFBQWE7UUFDcEIsSUFBSSxPQUFPLGNBQWMsS0FBSyxVQUFVLEVBQUUsQ0FBQztZQUMxQyxPQUFPLEtBQUssQ0FBQztRQUNkLENBQUM7UUFFRCxPQUFPLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUM3QixTQUFTLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQ3hCLFNBQVMsQ0FDUixDQUFDLFFBQWtELEVBQUUsRUFBRSxDQUN0RCxJQUFJLFVBQVUsQ0FBQyxDQUFDLFFBQXlDLEVBQUUsRUFBRSxDQUM1RCxJQUFJLENBQUMsT0FBTyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsRUFBRTtZQUNuQyxNQUFNLGNBQWMsR0FBRyxJQUFJLGNBQWMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQy9FLEtBQUssTUFBTSxPQUFPLElBQUksUUFBUSxFQUFFLENBQUM7Z0JBQ2hDLGNBQWMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUMxRCxDQUFDO1lBQ0QsT0FBTyxHQUFHLEVBQUU7Z0JBQ1gsY0FBYyxDQUFDLFVBQVUsRUFBRSxDQUFDO1lBQzdCLENBQUMsQ0FBQztRQUNILENBQUMsQ0FBQyxDQUNGLENBQ0Y7UUFDRCxtRUFBbUU7UUFDbkUsNkRBQTZEO1FBQzdELElBQUksQ0FBQyxDQUFDLENBQUM7UUFDUCwwRUFBMEU7UUFDMUUseUVBQXlFO1FBQ3pFLE1BQU0sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxLQUFLLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQzdGLENBQUM7SUFDSCxDQUFDO0lBRUQscUJBQXFCO1FBQ3BCLGlGQUFpRjtRQUNqRixJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sRUFBRSxDQUFDO1lBQ2xELElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1lBQ3hCLElBQUksQ0FBQyxjQUFjLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLE1BQU0sQ0FBQztZQUMzQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEMsQ0FBQztRQUVELDZGQUE2RjtRQUM3RixzQkFBc0I7UUFDdEIsSUFBSSxJQUFJLENBQUMscUJBQXFCLEVBQUUsQ0FBQztZQUNoQyxJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQyxDQUFDO1lBQzNDLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1lBQy9CLElBQUksQ0FBQyxxQkFBcUIsR0FBRyxLQUFLLENBQUM7WUFDbkMsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3hDLENBQUM7UUFFRCw4RkFBOEY7UUFDOUYsNkNBQTZDO1FBQzdDLElBQUksSUFBSSxDQUFDLHNCQUFzQixFQUFFLENBQUM7WUFDakMsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7WUFDaEMsSUFBSSxDQUFDLHNCQUFzQixHQUFHLEtBQUssQ0FBQztZQUNwQyxJQUFJLENBQUMsa0JBQWtCLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDeEMsQ0FBQztJQUNGLENBQUM7SUFFRCxXQUFXO1FBQ1YsSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUM1QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxVQUFVLENBQUMsUUFBUSxFQUFFLENBQUM7UUFDM0IsSUFBSSxDQUFDLGNBQWMsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUNoQyxDQUFDO0lBRUQsNkNBQTZDO0lBQzdDLGNBQWMsQ0FBQyxLQUFvQjtRQUNsQyx3REFBd0Q7UUFDeEQsSUFBSSxjQUFjLENBQUMsS0FBSyxDQUFDLEVBQUUsQ0FBQztZQUMzQixPQUFPO1FBQ1IsQ0FBQztRQUVELFFBQVEsS0FBSyxDQUFDLE9BQU8sRUFBRSxDQUFDO1lBQ3ZCLEtBQUssS0FBSyxDQUFDO1lBQ1gsS0FBSyxLQUFLO2dCQUNULElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsY0FBYyxFQUFFLEVBQUUsQ0FBQztvQkFDL0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFFNUMsSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7d0JBQzVCLElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO3dCQUM5QyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxDQUFDO29CQUMzQixDQUFDO2dCQUNGLENBQUM7Z0JBQ0QsTUFBTTtZQUNQO2dCQUNDLElBQUksQ0FBQyxXQUFXLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3BDLENBQUM7SUFDRixDQUFDO0lBRUQ7O09BRUc7SUFDSCxpQkFBaUI7UUFDaEIsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO1FBRS9ELHdGQUF3RjtRQUN4RixxRkFBcUY7UUFDckYsa0ZBQWtGO1FBQ2xGLElBQUksV0FBVyxLQUFLLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBQzlDLElBQUksQ0FBQyxtQkFBbUIsR0FBRyxXQUFXLElBQUksRUFBRSxDQUFDO1lBRTdDLG1FQUFtRTtZQUNuRSw4REFBOEQ7WUFDOUQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFO2dCQUNyQixJQUFJLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztnQkFDeEIsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO1lBQ3hDLENBQUMsQ0FBQyxDQUFDO1FBQ0osQ0FBQztJQUNGLENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSCxnQkFBZ0I7UUFDZixJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsdUJBQXVCLEVBQUUsQ0FBQztRQUMvQixJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQztJQUNqQyxDQUFDO0lBRUQsbUVBQW1FO0lBQ25FLElBQVcsVUFBVTtRQUNwQixPQUFPLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxlQUFlLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUN2RSxDQUFDO0lBRUQsb0ZBQW9GO0lBQ3BGLElBQVcsVUFBVSxDQUFDLEtBQWE7UUFDbEMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxDQUFDLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbEYsT0FBTztRQUNSLENBQUM7UUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLGFBQWEsQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsYUFBYSxDQUFDLEtBQWE7UUFDMUIsT0FBTyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUN0RCxDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsWUFBWSxDQUFDLFFBQWdCO1FBQzVCLElBQUksSUFBSSxDQUFDLHVCQUF1QixFQUFFLEVBQUUsQ0FBQztZQUNwQyxJQUFJLENBQUMsY0FBYyxDQUFDLFFBQVEsQ0FBQyxDQUFDO1FBQy9CLENBQUM7UUFFRCxJQUFJLElBQUksQ0FBQyxNQUFNLEVBQUUsRUFBRSxNQUFNLEVBQUUsQ0FBQztZQUMzQixJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxFQUFFLENBQUM7WUFFaEMscUZBQXFGO1lBQ3JGLHNGQUFzRjtZQUN0RixtREFBbUQ7WUFDbkQsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsYUFBYSxDQUFDO1lBQzNELE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxDQUFDO1lBRXZDLElBQUksR0FBRyxLQUFLLEtBQUssRUFBRSxDQUFDO2dCQUNuQixXQUFXLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztZQUM1QixDQUFDO2lCQUFNLENBQUM7Z0JBQ1AsV0FBVyxDQUFDLFVBQVUsR0FBRyxXQUFXLENBQUMsV0FBVyxHQUFHLFdBQVcsQ0FBQyxXQUFXLENBQUM7WUFDNUUsQ0FBQztRQUNGLENBQUM7SUFDRixDQUFDO0lBRUQsa0RBQWtEO0lBQ2xELG1CQUFtQjtRQUNsQixPQUFPLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztJQUMvRCxDQUFDO0lBRUQsMEZBQTBGO0lBQzFGLHdCQUF3QjtRQUN2QixJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLENBQUM7WUFDOUIsT0FBTztRQUNSLENBQUM7UUFFRCxNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQzNDLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxtQkFBbUIsRUFBRSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLGNBQWMsQ0FBQztRQUUzRix3RkFBd0Y7UUFDeEYsd0ZBQXdGO1FBQ3hGLGlFQUFpRTtRQUNqRSwwREFBMEQ7UUFDMUQsd0ZBQXdGO1FBQ3hGLCtDQUErQztRQUMvQyxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsY0FBYyxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUM7UUFFMUYseUZBQXlGO1FBQ3pGLHdGQUF3RjtRQUN4Rix3RkFBd0Y7UUFDeEYsMkVBQTJFO1FBQzNFLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLElBQUksSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNuRCxJQUFJLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxhQUFhLENBQUMsVUFBVSxHQUFHLENBQUMsQ0FBQztRQUN2RCxDQUFDO0lBQ0YsQ0FBQztJQUVELDJGQUEyRjtJQUMzRixJQUFXLGNBQWM7UUFDeEIsT0FBTyxJQUFJLENBQUMsZUFBZSxDQUFDO0lBQzdCLENBQUM7SUFDRCxJQUFXLGNBQWMsQ0FBQyxLQUFhO1FBQ3RDLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDdkIsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSCxhQUFhLENBQUMsU0FBMEI7UUFDdkMsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQztRQUV0RSw0RUFBNEU7UUFDNUUsTUFBTSxZQUFZLEdBQUcsQ0FBQyxDQUFDLFNBQVMsS0FBSyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsR0FBRyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFMUUsT0FBTyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxlQUFlLEdBQUcsWUFBWSxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVELHFEQUFxRDtJQUNyRCxxQkFBcUIsQ0FBQyxTQUEwQjtRQUMvQyxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxjQUFjLENBQUMsVUFBa0I7UUFDaEMsSUFBSSxJQUFJLENBQUMsaUJBQWlCLEVBQUUsRUFBRSxDQUFDO1lBQzlCLE9BQU87UUFDUixDQUFDO1FBRUQsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUMsVUFBVSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUV2RSxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7WUFDcEIsT0FBTztRQUNSLENBQUM7UUFFRCwwREFBMEQ7UUFDMUQsTUFBTSxVQUFVLEdBQUcsSUFBSSxDQUFDLGlCQUFpQixFQUFFLENBQUMsYUFBYSxDQUFDLFdBQVcsQ0FBQztRQUN0RSxNQUFNLEVBQUUsVUFBVSxFQUFFLFdBQVcsRUFBRSxHQUFHLGFBQWEsQ0FBQyxVQUFVLENBQUMsYUFBYSxDQUFDO1FBRTNFLElBQUksY0FBc0IsQ0FBQztRQUMzQixJQUFJLGFBQXFCLENBQUM7UUFDMUIsSUFBSSxJQUFJLENBQUMsbUJBQW1CLEVBQUUsS0FBSyxLQUFLLEVBQUUsQ0FBQztZQUMxQyxjQUFjLEdBQUcsVUFBVSxDQUFDO1lBQzVCLGFBQWEsR0FBRyxjQUFjLEdBQUcsV0FBVyxDQUFDO1FBQzlDLENBQUM7YUFBTSxDQUFDO1lBQ1AsYUFBYSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxhQUFhLENBQUMsV0FBVyxHQUFHLFVBQVUsQ0FBQztZQUM1RSxjQUFjLEdBQUcsYUFBYSxHQUFHLFdBQVcsQ0FBQztRQUM5QyxDQUFDO1FBRUQsTUFBTSxnQkFBZ0IsR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDO1FBQzdDLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxjQUFjLEdBQUcsVUFBVSxDQUFDO1FBRXpELElBQUksY0FBYyxHQUFHLGdCQUFnQixFQUFFLENBQUM7WUFDdkMsc0RBQXNEO1lBQ3RELElBQUksQ0FBQyxjQUFjLElBQUksZ0JBQWdCLEdBQUcsY0FBYyxDQUFDO1FBQzFELENBQUM7YUFBTSxJQUFJLGFBQWEsR0FBRyxlQUFlLEVBQUUsQ0FBQztZQUM1QyxxREFBcUQ7WUFDckQsSUFBSSxDQUFDLGNBQWMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLGFBQWEsR0FBRyxlQUFlLEVBQUUsY0FBYyxHQUFHLGdCQUFnQixDQUFDLENBQUM7UUFDckcsQ0FBQztJQUNGLENBQUM7SUFFRDs7Ozs7OztPQU9HO0lBQ0gsdUJBQXVCO1FBQ3RCLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsdUJBQXVCLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3pDLENBQUM7YUFBTSxDQUFDO1lBQ1AsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDLGFBQWEsQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO1lBRTlHLElBQUksQ0FBQyxTQUFTLEVBQUUsQ0FBQztnQkFDaEIsSUFBSSxDQUFDLGNBQWMsR0FBRyxDQUFDLENBQUM7WUFDekIsQ0FBQztZQUVELElBQUksU0FBUyxLQUFLLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxFQUFFLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxrQkFBa0IsQ0FBQyxZQUFZLEVBQUUsQ0FBQztZQUN4QyxDQUFDO1lBRUQsSUFBSSxDQUFDLHVCQUF1QixDQUFDLEdBQUcsQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUM3QyxDQUFDO0lBQ0YsQ0FBQztJQUVEOzs7Ozs7OztPQVFHO0lBQ0gsdUJBQXVCO1FBQ3RCLElBQUksSUFBSSxDQUFDLGlCQUFpQixFQUFFLEVBQUUsQ0FBQztZQUM5QixJQUFJLENBQUMsbUJBQW1CLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixHQUFHLElBQUksQ0FBQztRQUM3RCxDQUFDO2FBQU0sQ0FBQztZQUNQLHNEQUFzRDtZQUN0RCxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLGNBQWMsS0FBSyxDQUFDLENBQUM7WUFDdEQsSUFBSSxDQUFDLG1CQUFtQixHQUFHLElBQUksQ0FBQyxjQUFjLEtBQUssSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7WUFDaEYsSUFBSSxDQUFDLGtCQUFrQixDQUFDLFlBQVksRUFBRSxDQUFDO1FBQ3hDLENBQUM7SUFDRixDQUFDO0lBRUQ7Ozs7OztPQU1HO0lBQ0gscUJBQXFCO1FBQ3BCLE1BQU0sZUFBZSxHQUFHLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQyxhQUFhLENBQUMsV0FBVyxDQUFDO1FBQ3ZFLE1BQU0sVUFBVSxHQUFHLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxDQUFDLGFBQWEsQ0FBQyxXQUFXLENBQUM7UUFDdEUsT0FBTyxlQUFlLEdBQUcsVUFBVSxJQUFJLENBQUMsQ0FBQztJQUMxQyxDQUFDO0lBRUQsdURBQXVEO0lBQ3ZELGFBQWE7UUFDWixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0gscUJBQXFCLENBQUMsU0FBMEIsRUFBRSxVQUF1QjtRQUN4RSwyRkFBMkY7UUFDM0Ysc0ZBQXNGO1FBQ3RGLElBQUksVUFBVSxJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssSUFBSSxJQUFJLFVBQVUsQ0FBQyxNQUFNLEtBQUssQ0FBQyxFQUFFLENBQUM7WUFDekUsT0FBTztRQUNSLENBQUM7UUFFRCw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1FBRXJCLHVFQUF1RTtRQUN2RSxLQUFLLENBQUMsbUJBQW1CLEVBQUUsc0JBQXNCLENBQUM7WUFDakQsdUZBQXVGO2FBQ3RGLElBQUksQ0FBQyxTQUFTLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxjQUFjLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7YUFDNUQsU0FBUyxDQUFDLEdBQUcsRUFBRTtZQUNmLE1BQU0sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxDQUFDO1lBRXRFLHdEQUF3RDtZQUN4RCxJQUFJLFFBQVEsS0FBSyxDQUFDLElBQUksUUFBUSxJQUFJLGlCQUFpQixFQUFFLENBQUM7Z0JBQ3JELElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUN0QixDQUFDO1FBQ0YsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0lBRUQ7Ozs7T0FJRztJQUNLLFNBQVMsQ0FBQyxRQUFnQjtRQUNqQyxJQUFJLElBQUksQ0FBQyxpQkFBaUIsRUFBRSxFQUFFLENBQUM7WUFDOUIsT0FBTyxFQUFFLGlCQUFpQixFQUFFLENBQUMsRUFBRSxRQUFRLEVBQUUsQ0FBQyxFQUFFLENBQUM7UUFDOUMsQ0FBQztRQUVELE1BQU0saUJBQWlCLEdBQUcsSUFBSSxDQUFDLHFCQUFxQixFQUFFLENBQUM7UUFDdkQsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLGlCQUFpQixFQUFFLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFFMUUsdUZBQXVGO1FBQ3ZGLHNDQUFzQztRQUN0QyxJQUFJLENBQUMsc0JBQXNCLEdBQUcsSUFBSSxDQUFDO1FBQ25DLElBQUksQ0FBQyx1QkFBdUIsRUFBRSxDQUFDO1FBRS9CLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDO0lBQzlELENBQUM7MEhBamtCb0IsNkJBQTZCOzhHQUE3Qiw2QkFBNkI7OzJGQUE3Qiw2QkFBNkI7a0JBRGxELFNBQVMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIFdlIGFyZSBidWlsZGluZyBvbiBzaG91bGRlcnMgb2YgZ2lhbnRzIGhlcmUgYW5kIGFkYXB0IHRoZSBpbXBsZW1lbnRhdGlvbiBwcm92aWRlZCBieSB0aGUgaW5jcmVkaWJsZSBBbmd1bGFyXG4gKiB0ZWFtOiBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9jb21wb25lbnRzL2Jsb2IvbWFpbi9zcmMvbWF0ZXJpYWwvdGFicy9wYWdpbmF0ZWQtdGFiLWhlYWRlci50c1xuICogQ2hlY2sgdGhlbSBvdXQhIEdpdmUgdGhlbSBhIHRyeSEgTGVhdmUgYSBzdGFyISBUaGVpciB3b3JrIGlzIGluY3JlZGlibGUhXG4gKi9cblxuLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IEZvY3VzS2V5TWFuYWdlciwgdHlwZSBGb2N1c2FibGVPcHRpb24gfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQgeyB0eXBlIERpcmVjdGlvbiwgRGlyZWN0aW9uYWxpdHkgfSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQgeyBFTlRFUiwgU1BBQ0UsIGhhc01vZGlmaWVyS2V5IH0gZnJvbSAnQGFuZ3VsYXIvY2RrL2tleWNvZGVzJztcbmltcG9ydCB7IFNoYXJlZFJlc2l6ZU9ic2VydmVyIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL29ic2VydmVycy9wcml2YXRlJztcbmltcG9ydCB7IFBsYXRmb3JtLCBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zIH0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BsYXRmb3JtJztcbmltcG9ydCB7IFZpZXdwb3J0UnVsZXIgfSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7XG5cdEFOSU1BVElPTl9NT0RVTEVfVFlQRSxcblx0dHlwZSBBZnRlckNvbnRlbnRDaGVja2VkLFxuXHR0eXBlIEFmdGVyQ29udGVudEluaXQsXG5cdHR5cGUgQWZ0ZXJWaWV3SW5pdCxcblx0Q2hhbmdlRGV0ZWN0b3JSZWYsXG5cdERpcmVjdGl2ZSxcblx0RWxlbWVudFJlZixcblx0SW5qZWN0b3IsXG5cdE5nWm9uZSxcblx0dHlwZSBPbkRlc3Ryb3ksXG5cdFNpZ25hbCxcblx0YWZ0ZXJOZXh0UmVuZGVyLFxuXHRib29sZWFuQXR0cmlidXRlLFxuXHRjb21wdXRlZCxcblx0ZWZmZWN0LFxuXHRpbmplY3QsXG5cdGlucHV0LFxuXHRvdXRwdXQsXG5cdHNpZ25hbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFTVBUWSwgT2JzZXJ2YWJsZSwgdHlwZSBPYnNlcnZlciwgU3ViamVjdCwgZnJvbUV2ZW50LCBtZXJnZSwgb2YgYXMgb2JzZXJ2YWJsZU9mLCB0aW1lciB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGVib3VuY2VUaW1lLCBmaWx0ZXIsIHNraXAsIHN0YXJ0V2l0aCwgc3dpdGNoTWFwLCB0YWtlVW50aWwgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBCcm5UYWJzRGlyZWN0aXZlIH0gZnJvbSAnLi9icm4tdGFicy10cmlnZ2VyLmRpcmVjdGl2ZSc7XG5cbi8qKiBDb25maWcgdXNlZCB0byBiaW5kIHBhc3NpdmUgZXZlbnQgbGlzdGVuZXJzICovXG5jb25zdCBwYXNzaXZlRXZlbnRMaXN0ZW5lck9wdGlvbnMgPSBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zKHtcblx0cGFzc2l2ZTogdHJ1ZSxcbn0pIGFzIEV2ZW50TGlzdGVuZXJPcHRpb25zO1xuXG4vKipcbiAqIFRoZSBkaXJlY3Rpb25zIHRoYXQgc2Nyb2xsaW5nIGNhbiBnbyBpbiB3aGVuIHRoZSBoZWFkZXIncyB0YWJzIGV4Y2VlZCB0aGUgaGVhZGVyIHdpZHRoLiAnQWZ0ZXInXG4gKiB3aWxsIHNjcm9sbCB0aGUgaGVhZGVyIHRvd2FyZHMgdGhlIGVuZCBvZiB0aGUgdGFicyBsaXN0IGFuZCAnYmVmb3JlJyB3aWxsIHNjcm9sbCB0b3dhcmRzIHRoZVxuICogYmVnaW5uaW5nIG9mIHRoZSBsaXN0LlxuICovXG5leHBvcnQgdHlwZSBTY3JvbGxEaXJlY3Rpb24gPSAnYWZ0ZXInIHwgJ2JlZm9yZSc7XG5cbi8qKlxuICogQW1vdW50IG9mIG1pbGxpc2Vjb25kcyB0byB3YWl0IGJlZm9yZSBzdGFydGluZyB0byBzY3JvbGwgdGhlIGhlYWRlciBhdXRvbWF0aWNhbGx5LlxuICogU2V0IGEgbGl0dGxlIGNvbnNlcnZhdGl2ZWx5IGluIG9yZGVyIHRvIGhhbmRsZSBmYWtlIGV2ZW50cyBkaXNwYXRjaGVkIG9uIHRvdWNoIGRldmljZXMuXG4gKi9cbmNvbnN0IEhFQURFUl9TQ1JPTExfREVMQVkgPSA2NTA7XG5cbi8qKlxuICogSW50ZXJ2YWwgaW4gbWlsbGlzZWNvbmRzIGF0IHdoaWNoIHRvIHNjcm9sbCB0aGUgaGVhZGVyXG4gKiB3aGlsZSB0aGUgdXNlciBpcyBob2xkaW5nIHRoZWlyIHBvaW50ZXIuXG4gKi9cbmNvbnN0IEhFQURFUl9TQ1JPTExfSU5URVJWQUwgPSAxMDA7XG5cbi8qKiBJdGVtIGluc2lkZSBhIHBhZ2luYXRlZCB0YWIgaGVhZGVyLiAqL1xuZXhwb3J0IHR5cGUgQnJuUGFnaW5hdGVkVGFiSGVhZGVySXRlbSA9IEZvY3VzYWJsZU9wdGlvbiAmIHsgZWxlbWVudFJlZjogRWxlbWVudFJlZiB9O1xuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGEgdGFiIGhlYWRlciB0aGF0IHN1cHBvcnRlZCBwYWdpbmF0aW9uLlxuICogQGRvY3MtcHJpdmF0ZVxuICovXG5ARGlyZWN0aXZlKClcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBCcm5UYWJzUGFnaW5hdGVkTGlzdERpcmVjdGl2ZVxuXHRpbXBsZW1lbnRzIEFmdGVyQ29udGVudENoZWNrZWQsIEFmdGVyQ29udGVudEluaXQsIEFmdGVyVmlld0luaXQsIE9uRGVzdHJveVxue1xuXHRwdWJsaWMgYWJzdHJhY3QgX2l0ZW1zOiBTaWduYWw8UmVhZG9ubHlBcnJheTxCcm5QYWdpbmF0ZWRUYWJIZWFkZXJJdGVtPj47XG5cdHB1YmxpYyBhYnN0cmFjdCBfaXRlbXNDaGFuZ2VzOiBPYnNlcnZhYmxlPFJlYWRvbmx5QXJyYXk8QnJuUGFnaW5hdGVkVGFiSGVhZGVySXRlbT4+O1xuXHRwdWJsaWMgYWJzdHJhY3QgX3RhYkxpc3RDb250YWluZXI6IFNpZ25hbDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj47XG5cdHB1YmxpYyBhYnN0cmFjdCBfdGFiTGlzdDogU2lnbmFsPEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+Pjtcblx0cHVibGljIGFic3RyYWN0IF90YWJMaXN0SW5uZXI6IFNpZ25hbDxFbGVtZW50UmVmPEhUTUxFbGVtZW50Pj47XG5cdHB1YmxpYyBhYnN0cmFjdCBfbmV4dFBhZ2luYXRvcjogU2lnbmFsPEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+Pjtcblx0cHVibGljIGFic3RyYWN0IF9wcmV2aW91c1BhZ2luYXRvcjogU2lnbmFsPEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+PjtcblxuXHQvKiogVGhlIGRpc3RhbmNlIGluIHBpeGVscyB0aGF0IHRoZSB0YWIgbGFiZWxzIHNob3VsZCBiZSB0cmFuc2xhdGVkIHRvIHRoZSBsZWZ0LiAqL1xuXHRwcml2YXRlIF9zY3JvbGxEaXN0YW5jZSA9IDA7XG5cblx0LyoqIFdoZXRoZXIgdGhlIGhlYWRlciBzaG91bGQgc2Nyb2xsIHRvIHRoZSBzZWxlY3RlZCBpbmRleCBhZnRlciB0aGUgdmlldyBoYXMgYmVlbiBjaGVja2VkLiAqL1xuXHRwcml2YXRlIF9zZWxlY3RlZEluZGV4Q2hhbmdlZCA9IGZhbHNlO1xuXG5cdHByaXZhdGUgcmVhZG9ubHkgX3Jvb3QgPSBpbmplY3QoQnJuVGFic0RpcmVjdGl2ZSk7XG5cdHByaXZhdGUgcmVhZG9ubHkgX2FjdGl2ZVRhYiA9IHRoaXMuX3Jvb3QuJGFjdGl2ZVRhYjtcblx0cHJpdmF0ZSByZWFkb25seSBfdGFicyA9IHRoaXMuX3Jvb3QuJHRhYnM7XG5cblx0LyoqIEVtaXRzIHdoZW4gdGhlIGNvbXBvbmVudCBpcyBkZXN0cm95ZWQuICovXG5cdHByb3RlY3RlZCByZWFkb25seSBfZGVzdHJveWVkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuXHQvKiogV2hldGhlciB0aGUgY29udHJvbHMgZm9yIHBhZ2luYXRpb24gc2hvdWxkIGJlIGRpc3BsYXllZCAqL1xuXHRwdWJsaWMgX3Nob3dQYWdpbmF0aW9uQ29udHJvbHMgPSBzaWduYWwoZmFsc2UpO1xuXG5cdC8qKiBXaGV0aGVyIHRoZSB0YWIgbGlzdCBjYW4gYmUgc2Nyb2xsZWQgbW9yZSB0b3dhcmRzIHRoZSBlbmQgb2YgdGhlIHRhYiBsYWJlbCBsaXN0LiAqL1xuXHRwdWJsaWMgX2Rpc2FibGVTY3JvbGxBZnRlciA9IHRydWU7XG5cblx0LyoqIFdoZXRoZXIgdGhlIHRhYiBsaXN0IGNhbiBiZSBzY3JvbGxlZCBtb3JlIHRvd2FyZHMgdGhlIGJlZ2lubmluZyBvZiB0aGUgdGFiIGxhYmVsIGxpc3QuICovXG5cdHB1YmxpYyBfZGlzYWJsZVNjcm9sbEJlZm9yZSA9IHRydWU7XG5cblx0LyoqXG5cdCAqIFRoZSBudW1iZXIgb2YgdGFiIGxhYmVscyB0aGF0IGFyZSBkaXNwbGF5ZWQgb24gdGhlIGhlYWRlci4gV2hlbiB0aGlzIGNoYW5nZXMsIHRoZSBoZWFkZXJcblx0ICogc2hvdWxkIHJlLWV2YWx1YXRlIHRoZSBzY3JvbGwgcG9zaXRpb24uXG5cdCAqL1xuXHRwcml2YXRlIF90YWJMYWJlbENvdW50ITogbnVtYmVyO1xuXG5cdC8qKiBXaGV0aGVyIHRoZSBzY3JvbGwgZGlzdGFuY2UgaGFzIGNoYW5nZWQgYW5kIHNob3VsZCBiZSBhcHBsaWVkIGFmdGVyIHRoZSB2aWV3IGlzIGNoZWNrZWQuICovXG5cdHByaXZhdGUgX3Njcm9sbERpc3RhbmNlQ2hhbmdlZCE6IGJvb2xlYW47XG5cblx0LyoqIFVzZWQgdG8gbWFuYWdlIGZvY3VzIGJldHdlZW4gdGhlIHRhYnMuICovXG5cdHByaXZhdGUgX2tleU1hbmFnZXIhOiBGb2N1c0tleU1hbmFnZXI8QnJuUGFnaW5hdGVkVGFiSGVhZGVySXRlbT47XG5cblx0LyoqIENhY2hlZCB0ZXh0IGNvbnRlbnQgb2YgdGhlIGhlYWRlci4gKi9cblx0cHJpdmF0ZSBfY3VycmVudFRleHRDb250ZW50ITogc3RyaW5nO1xuXG5cdC8qKiBTdHJlYW0gdGhhdCB3aWxsIHN0b3AgdGhlIGF1dG9tYXRlZCBzY3JvbGxpbmcuICovXG5cdHByaXZhdGUgcmVhZG9ubHkgX3N0b3BTY3JvbGxpbmcgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuXG5cdC8qKlxuXHQgKiBXaGV0aGVyIHBhZ2luYXRpb24gc2hvdWxkIGJlIGRpc2FibGVkLiBUaGlzIGNhbiBiZSB1c2VkIHRvIGF2b2lkIHVubmVjZXNzYXJ5XG5cdCAqIGxheW91dCByZWNhbGN1bGF0aW9ucyBpZiBpdCdzIGtub3duIHRoYXQgcGFnaW5hdGlvbiB3b24ndCBiZSByZXF1aXJlZC5cblx0ICovXG5cdHB1YmxpYyBkaXNhYmxlUGFnaW5hdGlvbiA9IGlucHV0KGZhbHNlLCB7IHRyYW5zZm9ybTogYm9vbGVhbkF0dHJpYnV0ZSB9KTtcblxuXHQvKiogVGhlIGluZGV4IG9mIHRoZSBhY3RpdmUgdGFiLiAqL1xuXHRwcml2YXRlIHJlYWRvbmx5IF9zZWxlY3RlZEluZGV4ID0gY29tcHV0ZWQoKCkgPT4ge1xuXHRcdGNvbnN0IGN1cnJlbnRUYWJLZXkgPSB0aGlzLl9hY3RpdmVUYWIoKTtcblx0XHRjb25zdCB0YWJzID0gdGhpcy5fdGFicygpO1xuXG5cdFx0bGV0IGFjdGl2ZUluZGV4ID0gMDtcblx0XHRpZiAoY3VycmVudFRhYktleSAmJiB0aGlzLl9pdGVtcygpKSB7XG5cdFx0XHRjb25zdCBjdXJyZW50VGFiID0gdGFic1tjdXJyZW50VGFiS2V5XTtcblx0XHRcdGlmIChjdXJyZW50VGFiKSB7XG5cdFx0XHRcdGFjdGl2ZUluZGV4ID0gdGhpcy5faXRlbXMoKS5pbmRleE9mKGN1cnJlbnRUYWIudHJpZ2dlcik7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIGFjdGl2ZUluZGV4O1xuXHR9KTtcblxuXHQvKiogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBvcHRpb24gaXMgc2VsZWN0ZWQuICovXG5cdHB1YmxpYyByZWFkb25seSBzZWxlY3RGb2N1c2VkSW5kZXggPSBvdXRwdXQ8bnVtYmVyPigpO1xuXG5cdC8qKiBFdmVudCBlbWl0dGVkIHdoZW4gYSBsYWJlbCBpcyBmb2N1c2VkLiAqL1xuXHRwdWJsaWMgcmVhZG9ubHkgaW5kZXhGb2N1c2VkID0gb3V0cHV0PG51bWJlcj4oKTtcblxuXHRwcml2YXRlIHJlYWRvbmx5IF9zaGFyZWRSZXNpemVPYnNlcnZlciA9IGluamVjdChTaGFyZWRSZXNpemVPYnNlcnZlcik7XG5cblx0cHJpdmF0ZSByZWFkb25seSBfaW5qZWN0b3IgPSBpbmplY3QoSW5qZWN0b3IpO1xuXG5cdHByb3RlY3RlZCBfZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4gPSBpbmplY3QoRWxlbWVudFJlZik7XG5cdHByb3RlY3RlZCBfY2hhbmdlRGV0ZWN0b3JSZWY6IENoYW5nZURldGVjdG9yUmVmID0gaW5qZWN0KENoYW5nZURldGVjdG9yUmVmKTtcblx0cHJpdmF0ZSByZWFkb25seSBfdmlld3BvcnRSdWxlcjogVmlld3BvcnRSdWxlciA9IGluamVjdChWaWV3cG9ydFJ1bGVyKTtcblx0cHJpdmF0ZSByZWFkb25seSBfZGlyID0gaW5qZWN0KERpcmVjdGlvbmFsaXR5LCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9uZ1pvbmU6IE5nWm9uZSA9IGluamVjdChOZ1pvbmUpO1xuXHRwcml2YXRlIHJlYWRvbmx5IF9wbGF0Zm9ybTogUGxhdGZvcm0gPSBpbmplY3QoUGxhdGZvcm0pO1xuXHRwdWJsaWMgX2FuaW1hdGlvbk1vZGUgPSBpbmplY3QoQU5JTUFUSU9OX01PRFVMRV9UWVBFLCB7IG9wdGlvbmFsOiB0cnVlIH0pO1xuXG5cdGNvbnN0cnVjdG9yKCkge1xuXHRcdC8vIEJpbmQgdGhlIGBtb3VzZWxlYXZlYCBldmVudCBvbiB0aGUgb3V0c2lkZSBzaW5jZSBpdCBkb2Vzbid0IGNoYW5nZSBhbnl0aGluZyBpbiB0aGUgdmlldy5cblx0XHR0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuXHRcdFx0ZnJvbUV2ZW50KHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudCwgJ21vdXNlbGVhdmUnKVxuXHRcdFx0XHQucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSlcblx0XHRcdFx0LnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHRcdFx0dGhpcy5fc3RvcEludGVydmFsKCk7XG5cdFx0XHRcdH0pO1xuXHRcdH0pO1xuXG5cdFx0ZWZmZWN0KCgpID0+IHtcblx0XHRcdGNvbnN0IHNlbGVjdGVkSW5kZXggPSB0aGlzLl9zZWxlY3RlZEluZGV4KCk7XG5cblx0XHRcdGlmIChzZWxlY3RlZEluZGV4ICE9PSAwKSB7XG5cdFx0XHRcdHRoaXMuX3NlbGVjdGVkSW5kZXhDaGFuZ2VkID0gdHJ1ZTtcblx0XHRcdFx0aWYgKHRoaXMuX2tleU1hbmFnZXIpIHtcblx0XHRcdFx0XHR0aGlzLl9rZXlNYW5hZ2VyLnVwZGF0ZUFjdGl2ZUl0ZW0oc2VsZWN0ZWRJbmRleCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KTtcblx0fVxuXG5cdC8qKiBDYWxsZWQgd2hlbiB0aGUgdXNlciBoYXMgc2VsZWN0ZWQgYW4gaXRlbSB2aWEgdGhlIGtleWJvYXJkLiAqL1xuXHRwcm90ZWN0ZWQgYWJzdHJhY3QgX2l0ZW1TZWxlY3RlZChldmVudDogS2V5Ym9hcmRFdmVudCk6IHZvaWQ7XG5cblx0bmdBZnRlclZpZXdJbml0KCkge1xuXHRcdC8vIFdlIG5lZWQgdG8gaGFuZGxlIHRoZXNlIGV2ZW50cyBtYW51YWxseSwgYmVjYXVzZSB3ZSB3YW50IHRvIGJpbmQgcGFzc2l2ZSBldmVudCBsaXN0ZW5lcnMuXG5cdFx0ZnJvbUV2ZW50KHRoaXMuX3ByZXZpb3VzUGFnaW5hdG9yKCkubmF0aXZlRWxlbWVudCwgJ3RvdWNoc3RhcnQnLCBwYXNzaXZlRXZlbnRMaXN0ZW5lck9wdGlvbnMpXG5cdFx0XHQucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSlcblx0XHRcdC5zdWJzY3JpYmUoKCkgPT4ge1xuXHRcdFx0XHR0aGlzLl9oYW5kbGVQYWdpbmF0b3JQcmVzcygnYmVmb3JlJyk7XG5cdFx0XHR9KTtcblxuXHRcdGZyb21FdmVudCh0aGlzLl9uZXh0UGFnaW5hdG9yKCkubmF0aXZlRWxlbWVudCwgJ3RvdWNoc3RhcnQnLCBwYXNzaXZlRXZlbnRMaXN0ZW5lck9wdGlvbnMpXG5cdFx0XHQucGlwZSh0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSlcblx0XHRcdC5zdWJzY3JpYmUoKCkgPT4ge1xuXHRcdFx0XHR0aGlzLl9oYW5kbGVQYWdpbmF0b3JQcmVzcygnYWZ0ZXInKTtcblx0XHRcdH0pO1xuXHR9XG5cblx0bmdBZnRlckNvbnRlbnRJbml0KCkge1xuXHRcdGNvbnN0IGRpckNoYW5nZSA9IHRoaXMuX2RpciA/IHRoaXMuX2Rpci5jaGFuZ2UgOiBvYnNlcnZhYmxlT2YoJ2x0cicpO1xuXHRcdC8vIFdlIG5lZWQgdG8gZGVib3VuY2UgcmVzaXplIGV2ZW50cyBiZWNhdXNlIHRoZSBhbGlnbm1lbnQgbG9naWMgaXMgZXhwZW5zaXZlLlxuXHRcdC8vIElmIHNvbWVvbmUgYW5pbWF0ZXMgdGhlIHdpZHRoIG9mIHRhYnMsIHdlIGRvbid0IHdhbnQgdG8gcmVhbGlnbiBvbiBldmVyeSBhbmltYXRpb24gZnJhbWUuXG5cdFx0Ly8gT25jZSB3ZSBoYXZlbid0IHNlZW4gYW55IG1vcmUgcmVzaXplIGV2ZW50cyBpbiB0aGUgbGFzdCAzMm1zICh+MiBhbmltYWlvbiBmcmFtZXMpIHdlIGNhblxuXHRcdC8vIHJlLWFsaWduLlxuXHRcdGNvbnN0IHJlc2l6ZSA9IHRoaXMuX3NoYXJlZFJlc2l6ZU9ic2VydmVyXG5cdFx0XHQub2JzZXJ2ZSh0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpXG5cdFx0XHQucGlwZShkZWJvdW5jZVRpbWUoMzIpLCB0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSk7XG5cdFx0Ly8gTm90ZTogV2UgZG8gbm90IGFjdHVhbGx5IG5lZWQgdG8gd2F0Y2ggdGhlc2UgZXZlbnRzIGZvciBwcm9wZXIgZnVuY3Rpb25pbmcgb2YgdGhlIHRhYnMsXG5cdFx0Ly8gdGhlIHJlc2l6ZSBldmVudHMgYWJvdmUgc2hvdWxkIGNhcHR1cmUgYW55IHZpZXdwb3J0IHJlc2l6ZSB0aGF0IHdlIGNhcmUgYWJvdXQuIEhvd2V2ZXIsXG5cdFx0Ly8gcmVtb3ZpbmcgdGhpcyBpcyBmYWlybHkgYnJlYWtpbmcgZm9yIHNjcmVlbnNob3QgdGVzdHMsIHNvIHdlJ3JlIGxlYXZpbmcgaXQgaGVyZSBmb3Igbm93LlxuXHRcdGNvbnN0IHZpZXdwb3J0UmVzaXplID0gdGhpcy5fdmlld3BvcnRSdWxlci5jaGFuZ2UoMTUwKS5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKTtcblxuXHRcdGNvbnN0IHJlYWxpZ24gPSAoKSA9PiB7XG5cdFx0XHR0aGlzLnVwZGF0ZVBhZ2luYXRpb24oKTtcblx0XHR9O1xuXG5cdFx0dGhpcy5fa2V5TWFuYWdlciA9IG5ldyBGb2N1c0tleU1hbmFnZXI8QnJuUGFnaW5hdGVkVGFiSGVhZGVySXRlbT4odGhpcy5faXRlbXMoKSlcblx0XHRcdC53aXRoSG9yaXpvbnRhbE9yaWVudGF0aW9uKHRoaXMuX2dldExheW91dERpcmVjdGlvbigpKVxuXHRcdFx0LndpdGhIb21lQW5kRW5kKClcblx0XHRcdC53aXRoV3JhcCgpXG5cdFx0XHQvLyBBbGxvdyBmb2N1cyB0byBsYW5kIG9uIGRpc2FibGVkIHRhYnMsIGFzIHBlciBodHRwczovL3czYy5naXRodWIuaW8vYXJpYS1wcmFjdGljZXMvI2tiZF9kaXNhYmxlZF9jb250cm9sc1xuXHRcdFx0LnNraXBQcmVkaWNhdGUoKCkgPT4gZmFsc2UpO1xuXG5cdFx0dGhpcy5fa2V5TWFuYWdlci51cGRhdGVBY3RpdmVJdGVtKHRoaXMuX3NlbGVjdGVkSW5kZXgoKSk7XG5cblx0XHQvLyBOb3RlOiBXZSBkbyBub3QgbmVlZCB0byByZWFsaWduIGFmdGVyIHRoZSBmaXJzdCByZW5kZXIgZm9yIHByb3BlciBmdW5jdGlvbmluZyBvZiB0aGUgdGFic1xuXHRcdC8vIHRoZSByZXNpemUgZXZlbnRzIGFib3ZlIHNob3VsZCBmaXJlIHdoZW4gd2UgZmlyc3Qgc3RhcnQgb2JzZXJ2aW5nIHRoZSBlbGVtZW50LiBIb3dldmVyLFxuXHRcdC8vIHJlbW92aW5nIHRoaXMgaXMgZmFpcmx5IGJyZWFraW5nIGZvciBzY3JlZW5zaG90IHRlc3RzLCBzbyB3ZSdyZSBsZWF2aW5nIGl0IGhlcmUgZm9yIG5vdy5cblx0XHRhZnRlck5leHRSZW5kZXIocmVhbGlnbiwgeyBpbmplY3RvcjogdGhpcy5faW5qZWN0b3IgfSk7XG5cblx0XHQvLyBPbiBkaXIgY2hhbmdlIG9yIHJlc2l6ZSwgcmVhbGlnbiB0aGUgaW5rIGJhciBhbmQgdXBkYXRlIHRoZSBvcmllbnRhdGlvbiBvZlxuXHRcdC8vIHRoZSBrZXkgbWFuYWdlciBpZiB0aGUgZGlyZWN0aW9uIGhhcyBjaGFuZ2VkLlxuXHRcdG1lcmdlKGRpckNoYW5nZSwgdmlld3BvcnRSZXNpemUsIHJlc2l6ZSwgdGhpcy5faXRlbXNDaGFuZ2VzLCB0aGlzLl9pdGVtc1Jlc2l6ZWQoKSlcblx0XHRcdC5waXBlKHRha2VVbnRpbCh0aGlzLl9kZXN0cm95ZWQpKVxuXHRcdFx0LnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHRcdC8vIFdlIG5lZWQgdG8gZGVmZXIgdGhpcyB0byBnaXZlIHRoZSBicm93c2VyIHNvbWUgdGltZSB0byByZWNhbGN1bGF0ZVxuXHRcdFx0XHQvLyB0aGUgZWxlbWVudCBkaW1lbnNpb25zLiBUaGUgY2FsbCBoYXMgdG8gYmUgd3JhcHBlZCBpbiBgTmdab25lLnJ1bmAsXG5cdFx0XHRcdC8vIGJlY2F1c2UgdGhlIHZpZXdwb3J0IGNoYW5nZSBoYW5kbGVyIHJ1bnMgb3V0c2lkZSBvZiBBbmd1bGFyLlxuXHRcdFx0XHR0aGlzLl9uZ1pvbmUucnVuKCgpID0+IHtcblx0XHRcdFx0XHRQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcblx0XHRcdFx0XHRcdC8vIENsYW1wIHRoZSBzY3JvbGwgZGlzdGFuY2UsIGJlY2F1c2UgaXQgY2FuIGNoYW5nZSB3aXRoIHRoZSBudW1iZXIgb2YgdGFicy5cblx0XHRcdFx0XHRcdHRoaXMuX3Njcm9sbERpc3RhbmNlID0gTWF0aC5tYXgoMCwgTWF0aC5taW4odGhpcy5fZ2V0TWF4U2Nyb2xsRGlzdGFuY2UoKSwgdGhpcy5fc2Nyb2xsRGlzdGFuY2UpKTtcblx0XHRcdFx0XHRcdHJlYWxpZ24oKTtcblx0XHRcdFx0XHR9KTtcblx0XHRcdFx0fSk7XG5cdFx0XHRcdHRoaXMuX2tleU1hbmFnZXIud2l0aEhvcml6b250YWxPcmllbnRhdGlvbih0aGlzLl9nZXRMYXlvdXREaXJlY3Rpb24oKSk7XG5cdFx0XHR9KTtcblxuXHRcdC8vIElmIHRoZXJlIGlzIGEgY2hhbmdlIGluIHRoZSBmb2N1cyBrZXkgbWFuYWdlciB3ZSBuZWVkIHRvIGVtaXQgdGhlIGBpbmRleEZvY3VzZWRgXG5cdFx0Ly8gZXZlbnQgaW4gb3JkZXIgdG8gcHJvdmlkZSBhIHB1YmxpYyBldmVudCB0aGF0IG5vdGlmaWVzIGFib3V0IGZvY3VzIGNoYW5nZXMuIEFsc28gd2UgcmVhbGlnblxuXHRcdC8vIHRoZSB0YWJzIGNvbnRhaW5lciBieSBzY3JvbGxpbmcgdGhlIG5ldyBmb2N1c2VkIHRhYiBpbnRvIHRoZSB2aXNpYmxlIHNlY3Rpb24uXG5cdFx0dGhpcy5fa2V5TWFuYWdlci5jaGFuZ2Uuc3Vic2NyaWJlKChuZXdGb2N1c0luZGV4KSA9PiB7XG5cdFx0XHR0aGlzLmluZGV4Rm9jdXNlZC5lbWl0KG5ld0ZvY3VzSW5kZXgpO1xuXHRcdFx0dGhpcy5fc2V0VGFiRm9jdXMobmV3Rm9jdXNJbmRleCk7XG5cdFx0fSk7XG5cdH1cblxuXHQvKiogU2VuZHMgYW55IGNoYW5nZXMgdGhhdCBjb3VsZCBhZmZlY3QgdGhlIGxheW91dCBvZiB0aGUgaXRlbXMuICovXG5cdHByaXZhdGUgX2l0ZW1zUmVzaXplZCgpOiBPYnNlcnZhYmxlPFJlc2l6ZU9ic2VydmVyRW50cnlbXT4ge1xuXHRcdGlmICh0eXBlb2YgUmVzaXplT2JzZXJ2ZXIgIT09ICdmdW5jdGlvbicpIHtcblx0XHRcdHJldHVybiBFTVBUWTtcblx0XHR9XG5cblx0XHRyZXR1cm4gdGhpcy5faXRlbXNDaGFuZ2VzLnBpcGUoXG5cdFx0XHRzdGFydFdpdGgodGhpcy5faXRlbXMoKSksXG5cdFx0XHRzd2l0Y2hNYXAoXG5cdFx0XHRcdCh0YWJJdGVtczogUmVhZG9ubHlBcnJheTxCcm5QYWdpbmF0ZWRUYWJIZWFkZXJJdGVtPikgPT5cblx0XHRcdFx0XHRuZXcgT2JzZXJ2YWJsZSgob2JzZXJ2ZXI6IE9ic2VydmVyPFJlc2l6ZU9ic2VydmVyRW50cnlbXT4pID0+XG5cdFx0XHRcdFx0XHR0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuXHRcdFx0XHRcdFx0XHRjb25zdCByZXNpemVPYnNlcnZlciA9IG5ldyBSZXNpemVPYnNlcnZlcigoZW50cmllcykgPT4gb2JzZXJ2ZXIubmV4dChlbnRyaWVzKSk7XG5cdFx0XHRcdFx0XHRcdGZvciAoY29uc3QgdGFiSXRlbSBvZiB0YWJJdGVtcykge1xuXHRcdFx0XHRcdFx0XHRcdHJlc2l6ZU9ic2VydmVyLm9ic2VydmUodGFiSXRlbS5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0XHRcdHJldHVybiAoKSA9PiB7XG5cdFx0XHRcdFx0XHRcdFx0cmVzaXplT2JzZXJ2ZXIuZGlzY29ubmVjdCgpO1xuXHRcdFx0XHRcdFx0XHR9O1xuXHRcdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0KSxcblx0XHRcdCksXG5cdFx0XHQvLyBTa2lwIHRoZSBmaXJzdCBlbWl0IHNpbmNlIHRoZSByZXNpemUgb2JzZXJ2ZXIgZW1pdHMgd2hlbiBhbiBpdGVtXG5cdFx0XHQvLyBpcyBvYnNlcnZlZCBmb3IgbmV3IGl0ZW1zIHdoZW4gdGhlIHRhYiBpcyBhbHJlYWR5IGluc2VydGVkXG5cdFx0XHRza2lwKDEpLFxuXHRcdFx0Ly8gU2tpcCBlbWlzc2lvbnMgd2hlcmUgYWxsIHRoZSBlbGVtZW50cyBhcmUgaW52aXNpYmxlIHNpbmNlIHdlIGRvbid0IHdhbnRcblx0XHRcdC8vIHRoZSBoZWFkZXIgdG8gdHJ5IGFuZCByZS1yZW5kZXIgd2l0aCBpbnZhbGlkIG1lYXN1cmVtZW50cy4gU2VlICMyNTU3NC5cblx0XHRcdGZpbHRlcigoZW50cmllcykgPT4gZW50cmllcy5zb21lKChlKSA9PiBlLmNvbnRlbnRSZWN0LndpZHRoID4gMCAmJiBlLmNvbnRlbnRSZWN0LmhlaWdodCA+IDApKSxcblx0XHQpO1xuXHR9XG5cblx0bmdBZnRlckNvbnRlbnRDaGVja2VkKCk6IHZvaWQge1xuXHRcdC8vIElmIHRoZSBudW1iZXIgb2YgdGFiIGxhYmVscyBoYXZlIGNoYW5nZWQsIGNoZWNrIGlmIHNjcm9sbGluZyBzaG91bGQgYmUgZW5hYmxlZFxuXHRcdGlmICh0aGlzLl90YWJMYWJlbENvdW50ICE9PSB0aGlzLl9pdGVtcygpLmxlbmd0aCkge1xuXHRcdFx0dGhpcy51cGRhdGVQYWdpbmF0aW9uKCk7XG5cdFx0XHR0aGlzLl90YWJMYWJlbENvdW50ID0gdGhpcy5faXRlbXMoKS5sZW5ndGg7XG5cdFx0XHR0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblx0XHR9XG5cblx0XHQvLyBJZiB0aGUgc2VsZWN0ZWQgaW5kZXggaGFzIGNoYW5nZWQsIHNjcm9sbCB0byB0aGUgbGFiZWwgYW5kIGNoZWNrIGlmIHRoZSBzY3JvbGxpbmcgY29udHJvbHNcblx0XHQvLyBzaG91bGQgYmUgZGlzYWJsZWQuXG5cdFx0aWYgKHRoaXMuX3NlbGVjdGVkSW5kZXhDaGFuZ2VkKSB7XG5cdFx0XHR0aGlzLl9zY3JvbGxUb0xhYmVsKHRoaXMuX3NlbGVjdGVkSW5kZXgoKSk7XG5cdFx0XHR0aGlzLl9jaGVja1Njcm9sbGluZ0NvbnRyb2xzKCk7XG5cdFx0XHR0aGlzLl9zZWxlY3RlZEluZGV4Q2hhbmdlZCA9IGZhbHNlO1xuXHRcdFx0dGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG5cdFx0fVxuXG5cdFx0Ly8gSWYgdGhlIHNjcm9sbCBkaXN0YW5jZSBoYXMgYmVlbiBjaGFuZ2VkICh0YWIgc2VsZWN0ZWQsIGZvY3VzZWQsIHNjcm9sbCBjb250cm9scyBhY3RpdmF0ZWQpLFxuXHRcdC8vIHRoZW4gdHJhbnNsYXRlIHRoZSBoZWFkZXIgdG8gcmVmbGVjdCB0aGlzLlxuXHRcdGlmICh0aGlzLl9zY3JvbGxEaXN0YW5jZUNoYW5nZWQpIHtcblx0XHRcdHRoaXMuX3VwZGF0ZVRhYlNjcm9sbFBvc2l0aW9uKCk7XG5cdFx0XHR0aGlzLl9zY3JvbGxEaXN0YW5jZUNoYW5nZWQgPSBmYWxzZTtcblx0XHRcdHRoaXMuX2NoYW5nZURldGVjdG9yUmVmLm1hcmtGb3JDaGVjaygpO1xuXHRcdH1cblx0fVxuXG5cdG5nT25EZXN0cm95KCkge1xuXHRcdHRoaXMuX2tleU1hbmFnZXI/LmRlc3Ryb3koKTtcblx0XHR0aGlzLl9kZXN0cm95ZWQubmV4dCgpO1xuXHRcdHRoaXMuX2Rlc3Ryb3llZC5jb21wbGV0ZSgpO1xuXHRcdHRoaXMuX3N0b3BTY3JvbGxpbmcuY29tcGxldGUoKTtcblx0fVxuXG5cdC8qKiBIYW5kbGVzIGtleWJvYXJkIGV2ZW50cyBvbiB0aGUgaGVhZGVyLiAqL1xuXHRfaGFuZGxlS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuXHRcdC8vIFdlIGRvbid0IGhhbmRsZSBhbnkga2V5IGJpbmRpbmdzIHdpdGggYSBtb2RpZmllciBrZXkuXG5cdFx0aWYgKGhhc01vZGlmaWVyS2V5KGV2ZW50KSkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHN3aXRjaCAoZXZlbnQua2V5Q29kZSkge1xuXHRcdFx0Y2FzZSBFTlRFUjpcblx0XHRcdGNhc2UgU1BBQ0U6XG5cdFx0XHRcdGlmICh0aGlzLmZvY3VzSW5kZXggIT09IHRoaXMuX3NlbGVjdGVkSW5kZXgoKSkge1xuXHRcdFx0XHRcdGNvbnN0IGl0ZW0gPSB0aGlzLl9pdGVtcygpW3RoaXMuZm9jdXNJbmRleF07XG5cblx0XHRcdFx0XHRpZiAoaXRlbSAmJiAhaXRlbS5kaXNhYmxlZCkge1xuXHRcdFx0XHRcdFx0dGhpcy5zZWxlY3RGb2N1c2VkSW5kZXguZW1pdCh0aGlzLmZvY3VzSW5kZXgpO1xuXHRcdFx0XHRcdFx0dGhpcy5faXRlbVNlbGVjdGVkKGV2ZW50KTtcblx0XHRcdFx0XHR9XG5cdFx0XHRcdH1cblx0XHRcdFx0YnJlYWs7XG5cdFx0XHRkZWZhdWx0OlxuXHRcdFx0XHR0aGlzLl9rZXlNYW5hZ2VyLm9uS2V5ZG93bihldmVudCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIENhbGxiYWNrIGZvciB3aGVuIHRoZSBNdXRhdGlvbk9ic2VydmVyIGRldGVjdHMgdGhhdCB0aGUgY29udGVudCBoYXMgY2hhbmdlZC5cblx0ICovXG5cdF9vbkNvbnRlbnRDaGFuZ2VzKCkge1xuXHRcdGNvbnN0IHRleHRDb250ZW50ID0gdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LnRleHRDb250ZW50O1xuXG5cdFx0Ly8gV2UgbmVlZCB0byBkaWZmIHRoZSB0ZXh0IGNvbnRlbnQgb2YgdGhlIGhlYWRlciwgYmVjYXVzZSB0aGUgTXV0YXRpb25PYnNlcnZlciBjYWxsYmFja1xuXHRcdC8vIHdpbGwgZmlyZSBldmVuIGlmIHRoZSB0ZXh0IGNvbnRlbnQgZGlkbid0IGNoYW5nZSB3aGljaCBpcyBpbmVmZmljaWVudCBhbmQgaXMgcHJvbmVcblx0XHQvLyB0byBpbmZpbml0ZSBsb29wcyBpZiBhIHBvb3JseSBjb25zdHJ1Y3RlZCBleHByZXNzaW9uIGlzIHBhc3NlZCBpbiAoc2VlICMxNDI0OSkuXG5cdFx0aWYgKHRleHRDb250ZW50ICE9PSB0aGlzLl9jdXJyZW50VGV4dENvbnRlbnQpIHtcblx0XHRcdHRoaXMuX2N1cnJlbnRUZXh0Q29udGVudCA9IHRleHRDb250ZW50IHx8ICcnO1xuXG5cdFx0XHQvLyBUaGUgY29udGVudCBvYnNlcnZlciBydW5zIG91dHNpZGUgdGhlIGBOZ1pvbmVgIGJ5IGRlZmF1bHQsIHdoaWNoXG5cdFx0XHQvLyBtZWFucyB0aGF0IHdlIG5lZWQgdG8gYnJpbmcgdGhlIGNhbGxiYWNrIGJhY2sgaW4gb3Vyc2VsdmVzLlxuXHRcdFx0dGhpcy5fbmdab25lLnJ1bigoKSA9PiB7XG5cdFx0XHRcdHRoaXMudXBkYXRlUGFnaW5hdGlvbigpO1xuXHRcdFx0XHR0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdC8qKlxuXHQgKiBVcGRhdGVzIHRoZSB2aWV3IHdoZXRoZXIgcGFnaW5hdGlvbiBzaG91bGQgYmUgZW5hYmxlZCBvciBub3QuXG5cdCAqXG5cdCAqIFdBUk5JTkc6IENhbGxpbmcgdGhpcyBtZXRob2QgY2FuIGJlIHZlcnkgY29zdGx5IGluIHRlcm1zIG9mIHBlcmZvcm1hbmNlLiBJdCBzaG91bGQgYmUgY2FsbGVkXG5cdCAqIGFzIGluZnJlcXVlbnRseSBhcyBwb3NzaWJsZSBmcm9tIG91dHNpZGUgb2YgdGhlIFRhYnMgY29tcG9uZW50IGFzIGl0IGNhdXNlcyBhIHJlZmxvdyBvZiB0aGVcblx0ICogcGFnZS5cblx0ICovXG5cdHVwZGF0ZVBhZ2luYXRpb24oKSB7XG5cdFx0dGhpcy5fY2hlY2tQYWdpbmF0aW9uRW5hYmxlZCgpO1xuXHRcdHRoaXMuX2NoZWNrU2Nyb2xsaW5nQ29udHJvbHMoKTtcblx0XHR0aGlzLl91cGRhdGVUYWJTY3JvbGxQb3NpdGlvbigpO1xuXHR9XG5cblx0LyoqIFRyYWNrcyB3aGljaCBlbGVtZW50IGhhcyBmb2N1czsgdXNlZCBmb3Iga2V5Ym9hcmQgbmF2aWdhdGlvbiAqL1xuXHRwdWJsaWMgZ2V0IGZvY3VzSW5kZXgoKTogbnVtYmVyIHtcblx0XHRyZXR1cm4gdGhpcy5fa2V5TWFuYWdlciA/ICh0aGlzLl9rZXlNYW5hZ2VyLmFjdGl2ZUl0ZW1JbmRleCA/PyAwKSA6IDA7XG5cdH1cblxuXHQvKiogV2hlbiB0aGUgZm9jdXMgaW5kZXggaXMgc2V0LCB3ZSBtdXN0IG1hbnVhbGx5IHNlbmQgZm9jdXMgdG8gdGhlIGNvcnJlY3QgbGFiZWwgKi9cblx0cHVibGljIHNldCBmb2N1c0luZGV4KHZhbHVlOiBudW1iZXIpIHtcblx0XHRpZiAoIXRoaXMuX2lzVmFsaWRJbmRleCh2YWx1ZSkgfHwgdGhpcy5mb2N1c0luZGV4ID09PSB2YWx1ZSB8fCAhdGhpcy5fa2V5TWFuYWdlcikge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdHRoaXMuX2tleU1hbmFnZXIuc2V0QWN0aXZlSXRlbSh2YWx1ZSk7XG5cdH1cblxuXHQvKipcblx0ICogRGV0ZXJtaW5lcyBpZiBhbiBpbmRleCBpcyB2YWxpZC4gIElmIHRoZSB0YWJzIGFyZSBub3QgcmVhZHkgeWV0LCB3ZSBhc3N1bWUgdGhhdCB0aGUgdXNlciBpc1xuXHQgKiBwcm92aWRpbmcgYSB2YWxpZCBpbmRleCBhbmQgcmV0dXJuIHRydWUuXG5cdCAqL1xuXHRfaXNWYWxpZEluZGV4KGluZGV4OiBudW1iZXIpOiBib29sZWFuIHtcblx0XHRyZXR1cm4gdGhpcy5faXRlbXMoKSA/ICEhdGhpcy5faXRlbXMoKVtpbmRleF0gOiB0cnVlO1xuXHR9XG5cblx0LyoqXG5cdCAqIFNldHMgZm9jdXMgb24gdGhlIEhUTUwgZWxlbWVudCBmb3IgdGhlIGxhYmVsIHdyYXBwZXIgYW5kIHNjcm9sbHMgaXQgaW50byB0aGUgdmlldyBpZlxuXHQgKiBzY3JvbGxpbmcgaXMgZW5hYmxlZC5cblx0ICovXG5cdF9zZXRUYWJGb2N1cyh0YWJJbmRleDogbnVtYmVyKSB7XG5cdFx0aWYgKHRoaXMuX3Nob3dQYWdpbmF0aW9uQ29udHJvbHMoKSkge1xuXHRcdFx0dGhpcy5fc2Nyb2xsVG9MYWJlbCh0YWJJbmRleCk7XG5cdFx0fVxuXG5cdFx0aWYgKHRoaXMuX2l0ZW1zKCk/Lmxlbmd0aCkge1xuXHRcdFx0dGhpcy5faXRlbXMoKVt0YWJJbmRleF0uZm9jdXMoKTtcblxuXHRcdFx0Ly8gRG8gbm90IGxldCB0aGUgYnJvd3NlciBtYW5hZ2Ugc2Nyb2xsaW5nIHRvIGZvY3VzIHRoZSBlbGVtZW50LCB0aGlzIHdpbGwgYmUgaGFuZGxlZFxuXHRcdFx0Ly8gYnkgdXNpbmcgdHJhbnNsYXRpb24uIEluIExUUiwgdGhlIHNjcm9sbCBsZWZ0IHNob3VsZCBiZSAwLiBJbiBSVEwsIHRoZSBzY3JvbGwgd2lkdGhcblx0XHRcdC8vIHNob3VsZCBiZSB0aGUgZnVsbCB3aWR0aCBtaW51cyB0aGUgb2Zmc2V0IHdpZHRoLlxuXHRcdFx0Y29uc3QgY29udGFpbmVyRWwgPSB0aGlzLl90YWJMaXN0Q29udGFpbmVyKCkubmF0aXZlRWxlbWVudDtcblx0XHRcdGNvbnN0IGRpciA9IHRoaXMuX2dldExheW91dERpcmVjdGlvbigpO1xuXG5cdFx0XHRpZiAoZGlyID09PSAnbHRyJykge1xuXHRcdFx0XHRjb250YWluZXJFbC5zY3JvbGxMZWZ0ID0gMDtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdGNvbnRhaW5lckVsLnNjcm9sbExlZnQgPSBjb250YWluZXJFbC5zY3JvbGxXaWR0aCAtIGNvbnRhaW5lckVsLm9mZnNldFdpZHRoO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdC8qKiBUaGUgbGF5b3V0IGRpcmVjdGlvbiBvZiB0aGUgY29udGFpbmluZyBhcHAuICovXG5cdF9nZXRMYXlvdXREaXJlY3Rpb24oKTogRGlyZWN0aW9uIHtcblx0XHRyZXR1cm4gdGhpcy5fZGlyICYmIHRoaXMuX2Rpci52YWx1ZSA9PT0gJ3J0bCcgPyAncnRsJyA6ICdsdHInO1xuXHR9XG5cblx0LyoqIFBlcmZvcm1zIHRoZSBDU1MgdHJhbnNmb3JtYXRpb24gb24gdGhlIHRhYiBsaXN0IHRoYXQgd2lsbCBjYXVzZSB0aGUgbGlzdCB0byBzY3JvbGwuICovXG5cdF91cGRhdGVUYWJTY3JvbGxQb3NpdGlvbigpIHtcblx0XHRpZiAodGhpcy5kaXNhYmxlUGFnaW5hdGlvbigpKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Y29uc3Qgc2Nyb2xsRGlzdGFuY2UgPSB0aGlzLnNjcm9sbERpc3RhbmNlO1xuXHRcdGNvbnN0IHRyYW5zbGF0ZVggPSB0aGlzLl9nZXRMYXlvdXREaXJlY3Rpb24oKSA9PT0gJ2x0cicgPyAtc2Nyb2xsRGlzdGFuY2UgOiBzY3JvbGxEaXN0YW5jZTtcblxuXHRcdC8vIERvbid0IHVzZSBgdHJhbnNsYXRlM2RgIGhlcmUgYmVjYXVzZSB3ZSBkb24ndCB3YW50IHRvIGNyZWF0ZSBhIG5ldyBsYXllci4gQSBuZXcgbGF5ZXJcblx0XHQvLyBzZWVtcyB0byBjYXVzZSBmbGlja2VyaW5nIGFuZCBvdmVyZmxvdyBpbiBJbnRlcm5ldCBFeHBsb3Jlci4gRm9yIGV4YW1wbGUsIHRoZSBpbmsgYmFyXG5cdFx0Ly8gYW5kIHJpcHBsZXMgd2lsbCBleGNlZWQgdGhlIGJvdW5kYXJpZXMgb2YgdGhlIHZpc2libGUgdGFiIGJhci5cblx0XHQvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2NvbXBvbmVudHMvaXNzdWVzLzEwMjc2XG5cdFx0Ly8gV2Ugcm91bmQgdGhlIGB0cmFuc2Zvcm1gIGhlcmUsIGJlY2F1c2UgdHJhbnNmb3JtcyB3aXRoIHN1Yi1waXhlbCBwcmVjaXNpb24gY2F1c2Ugc29tZVxuXHRcdC8vIGJyb3dzZXJzIHRvIGJsdXIgdGhlIGNvbnRlbnQgb2YgdGhlIGVsZW1lbnQuXG5cdFx0dGhpcy5fdGFiTGlzdCgpLm5hdGl2ZUVsZW1lbnQuc3R5bGUudHJhbnNmb3JtID0gYHRyYW5zbGF0ZVgoJHtNYXRoLnJvdW5kKHRyYW5zbGF0ZVgpfXB4KWA7XG5cblx0XHQvLyBTZXR0aW5nIHRoZSBgdHJhbnNmb3JtYCBvbiBJRSB3aWxsIGNoYW5nZSB0aGUgc2Nyb2xsIG9mZnNldCBvZiB0aGUgcGFyZW50LCBjYXVzaW5nIHRoZVxuXHRcdC8vIHBvc2l0aW9uIHRvIGJlIHRocm93biBvZmYgaW4gc29tZSBjYXNlcy4gV2UgaGF2ZSB0byByZXNldCBpdCBvdXJzZWx2ZXMgdG8gZW5zdXJlIHRoYXRcblx0XHQvLyBpdCBkb2Vzbid0IGdldCB0aHJvd24gb2ZmLiBOb3RlIHRoYXQgd2Ugc2NvcGUgaXQgb25seSB0byBJRSBhbmQgRWRnZSwgYmVjYXVzZSBtZXNzaW5nXG5cdFx0Ly8gd2l0aCB0aGUgc2Nyb2xsIHBvc2l0aW9uIHRocm93cyBvZmYgQ2hyb21lIDcxKyBpbiBSVEwgbW9kZSAoc2VlICMxNDY4OSkuXG5cdFx0aWYgKHRoaXMuX3BsYXRmb3JtLlRSSURFTlQgfHwgdGhpcy5fcGxhdGZvcm0uRURHRSkge1xuXHRcdFx0dGhpcy5fdGFiTGlzdENvbnRhaW5lcigpLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsTGVmdCA9IDA7XG5cdFx0fVxuXHR9XG5cblx0LyoqIFNldHMgdGhlIGRpc3RhbmNlIGluIHBpeGVscyB0aGF0IHRoZSB0YWIgaGVhZGVyIHNob3VsZCBiZSB0cmFuc2Zvcm1lZCBpbiB0aGUgWC1heGlzLiAqL1xuXHRwdWJsaWMgZ2V0IHNjcm9sbERpc3RhbmNlKCk6IG51bWJlciB7XG5cdFx0cmV0dXJuIHRoaXMuX3Njcm9sbERpc3RhbmNlO1xuXHR9XG5cdHB1YmxpYyBzZXQgc2Nyb2xsRGlzdGFuY2UodmFsdWU6IG51bWJlcikge1xuXHRcdHRoaXMuX3Njcm9sbFRvKHZhbHVlKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBNb3ZlcyB0aGUgdGFiIGxpc3QgaW4gdGhlICdiZWZvcmUnIG9yICdhZnRlcicgZGlyZWN0aW9uICh0b3dhcmRzIHRoZSBiZWdpbm5pbmcgb2YgdGhlIGxpc3Qgb3Jcblx0ICogdGhlIGVuZCBvZiB0aGUgbGlzdCwgcmVzcGVjdGl2ZWx5KS4gVGhlIGRpc3RhbmNlIHRvIHNjcm9sbCBpcyBjb21wdXRlZCB0byBiZSBhIHRoaXJkIG9mIHRoZVxuXHQgKiBsZW5ndGggb2YgdGhlIHRhYiBsaXN0IHZpZXcgd2luZG93LlxuXHQgKlxuXHQgKiBUaGlzIGlzIGFuIGV4cGVuc2l2ZSBjYWxsIHRoYXQgZm9yY2VzIGEgbGF5b3V0IHJlZmxvdyB0byBjb21wdXRlIGJveCBhbmQgc2Nyb2xsIG1ldHJpY3MgYW5kXG5cdCAqIHNob3VsZCBiZSBjYWxsZWQgc3BhcmluZ2x5LlxuXHQgKi9cblx0X3Njcm9sbEhlYWRlcihkaXJlY3Rpb246IFNjcm9sbERpcmVjdGlvbikge1xuXHRcdGNvbnN0IHZpZXdMZW5ndGggPSB0aGlzLl90YWJMaXN0Q29udGFpbmVyKCkubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aDtcblxuXHRcdC8vIE1vdmUgdGhlIHNjcm9sbCBkaXN0YW5jZSBvbmUtdGhpcmQgdGhlIGxlbmd0aCBvZiB0aGUgdGFiIGxpc3QncyB2aWV3cG9ydC5cblx0XHRjb25zdCBzY3JvbGxBbW91bnQgPSAoKGRpcmVjdGlvbiA9PT0gJ2JlZm9yZScgPyAtMSA6IDEpICogdmlld0xlbmd0aCkgLyAzO1xuXG5cdFx0cmV0dXJuIHRoaXMuX3Njcm9sbFRvKHRoaXMuX3Njcm9sbERpc3RhbmNlICsgc2Nyb2xsQW1vdW50KTtcblx0fVxuXG5cdC8qKiBIYW5kbGVzIGNsaWNrIGV2ZW50cyBvbiB0aGUgcGFnaW5hdGlvbiBhcnJvd3MuICovXG5cdF9oYW5kbGVQYWdpbmF0b3JDbGljayhkaXJlY3Rpb246IFNjcm9sbERpcmVjdGlvbikge1xuXHRcdHRoaXMuX3N0b3BJbnRlcnZhbCgpO1xuXHRcdHRoaXMuX3Njcm9sbEhlYWRlcihkaXJlY3Rpb24pO1xuXHR9XG5cblx0LyoqXG5cdCAqIE1vdmVzIHRoZSB0YWIgbGlzdCBzdWNoIHRoYXQgdGhlIGRlc2lyZWQgdGFiIGxhYmVsIChtYXJrZWQgYnkgaW5kZXgpIGlzIG1vdmVkIGludG8gdmlldy5cblx0ICpcblx0ICogVGhpcyBpcyBhbiBleHBlbnNpdmUgY2FsbCB0aGF0IGZvcmNlcyBhIGxheW91dCByZWZsb3cgdG8gY29tcHV0ZSBib3ggYW5kIHNjcm9sbCBtZXRyaWNzIGFuZFxuXHQgKiBzaG91bGQgYmUgY2FsbGVkIHNwYXJpbmdseS5cblx0ICovXG5cdF9zY3JvbGxUb0xhYmVsKGxhYmVsSW5kZXg6IG51bWJlcikge1xuXHRcdGlmICh0aGlzLmRpc2FibGVQYWdpbmF0aW9uKCkpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHRjb25zdCBzZWxlY3RlZExhYmVsID0gdGhpcy5faXRlbXMoKSA/IHRoaXMuX2l0ZW1zKClbbGFiZWxJbmRleF0gOiBudWxsO1xuXG5cdFx0aWYgKCFzZWxlY3RlZExhYmVsKSB7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0Ly8gVGhlIHZpZXcgbGVuZ3RoIGlzIHRoZSB2aXNpYmxlIHdpZHRoIG9mIHRoZSB0YWIgbGFiZWxzLlxuXHRcdGNvbnN0IHZpZXdMZW5ndGggPSB0aGlzLl90YWJMaXN0Q29udGFpbmVyKCkubmF0aXZlRWxlbWVudC5vZmZzZXRXaWR0aDtcblx0XHRjb25zdCB7IG9mZnNldExlZnQsIG9mZnNldFdpZHRoIH0gPSBzZWxlY3RlZExhYmVsLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcblxuXHRcdGxldCBsYWJlbEJlZm9yZVBvczogbnVtYmVyO1xuXHRcdGxldCBsYWJlbEFmdGVyUG9zOiBudW1iZXI7XG5cdFx0aWYgKHRoaXMuX2dldExheW91dERpcmVjdGlvbigpID09PSAnbHRyJykge1xuXHRcdFx0bGFiZWxCZWZvcmVQb3MgPSBvZmZzZXRMZWZ0O1xuXHRcdFx0bGFiZWxBZnRlclBvcyA9IGxhYmVsQmVmb3JlUG9zICsgb2Zmc2V0V2lkdGg7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGxhYmVsQWZ0ZXJQb3MgPSB0aGlzLl90YWJMaXN0SW5uZXIoKS5uYXRpdmVFbGVtZW50Lm9mZnNldFdpZHRoIC0gb2Zmc2V0TGVmdDtcblx0XHRcdGxhYmVsQmVmb3JlUG9zID0gbGFiZWxBZnRlclBvcyAtIG9mZnNldFdpZHRoO1xuXHRcdH1cblxuXHRcdGNvbnN0IGJlZm9yZVZpc2libGVQb3MgPSB0aGlzLnNjcm9sbERpc3RhbmNlO1xuXHRcdGNvbnN0IGFmdGVyVmlzaWJsZVBvcyA9IHRoaXMuc2Nyb2xsRGlzdGFuY2UgKyB2aWV3TGVuZ3RoO1xuXG5cdFx0aWYgKGxhYmVsQmVmb3JlUG9zIDwgYmVmb3JlVmlzaWJsZVBvcykge1xuXHRcdFx0Ly8gU2Nyb2xsIGhlYWRlciB0byBtb3ZlIGxhYmVsIHRvIHRoZSBiZWZvcmUgZGlyZWN0aW9uXG5cdFx0XHR0aGlzLnNjcm9sbERpc3RhbmNlIC09IGJlZm9yZVZpc2libGVQb3MgLSBsYWJlbEJlZm9yZVBvcztcblx0XHR9IGVsc2UgaWYgKGxhYmVsQWZ0ZXJQb3MgPiBhZnRlclZpc2libGVQb3MpIHtcblx0XHRcdC8vIFNjcm9sbCBoZWFkZXIgdG8gbW92ZSBsYWJlbCB0byB0aGUgYWZ0ZXIgZGlyZWN0aW9uXG5cdFx0XHR0aGlzLnNjcm9sbERpc3RhbmNlICs9IE1hdGgubWluKGxhYmVsQWZ0ZXJQb3MgLSBhZnRlclZpc2libGVQb3MsIGxhYmVsQmVmb3JlUG9zIC0gYmVmb3JlVmlzaWJsZVBvcyk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlIHdoZXRoZXIgdGhlIHBhZ2luYXRpb24gY29udHJvbHMgc2hvdWxkIGJlIGRpc3BsYXllZC4gSWYgdGhlIHNjcm9sbCB3aWR0aCBvZiB0aGVcblx0ICogdGFiIGxpc3QgaXMgd2lkZXIgdGhhbiB0aGUgc2l6ZSBvZiB0aGUgaGVhZGVyIGNvbnRhaW5lciwgdGhlbiB0aGUgcGFnaW5hdGlvbiBjb250cm9scyBzaG91bGRcblx0ICogYmUgc2hvd24uXG5cdCAqXG5cdCAqIFRoaXMgaXMgYW4gZXhwZW5zaXZlIGNhbGwgdGhhdCBmb3JjZXMgYSBsYXlvdXQgcmVmbG93IHRvIGNvbXB1dGUgYm94IGFuZCBzY3JvbGwgbWV0cmljcyBhbmRcblx0ICogc2hvdWxkIGJlIGNhbGxlZCBzcGFyaW5nbHkuXG5cdCAqL1xuXHRfY2hlY2tQYWdpbmF0aW9uRW5hYmxlZCgpIHtcblx0XHRpZiAodGhpcy5kaXNhYmxlUGFnaW5hdGlvbigpKSB7XG5cdFx0XHR0aGlzLl9zaG93UGFnaW5hdGlvbkNvbnRyb2xzLnNldChmYWxzZSk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGNvbnN0IGlzRW5hYmxlZCA9IHRoaXMuX3RhYkxpc3RJbm5lcigpLm5hdGl2ZUVsZW1lbnQuc2Nyb2xsV2lkdGggPiB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XG5cblx0XHRcdGlmICghaXNFbmFibGVkKSB7XG5cdFx0XHRcdHRoaXMuc2Nyb2xsRGlzdGFuY2UgPSAwO1xuXHRcdFx0fVxuXG5cdFx0XHRpZiAoaXNFbmFibGVkICE9PSB0aGlzLl9zaG93UGFnaW5hdGlvbkNvbnRyb2xzKCkpIHtcblx0XHRcdFx0dGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG5cdFx0XHR9XG5cblx0XHRcdHRoaXMuX3Nob3dQYWdpbmF0aW9uQ29udHJvbHMuc2V0KGlzRW5hYmxlZCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIEV2YWx1YXRlIHdoZXRoZXIgdGhlIGJlZm9yZSBhbmQgYWZ0ZXIgY29udHJvbHMgc2hvdWxkIGJlIGVuYWJsZWQgb3IgZGlzYWJsZWQuXG5cdCAqIElmIHRoZSBoZWFkZXIgaXMgYXQgdGhlIGJlZ2lubmluZyBvZiB0aGUgbGlzdCAoc2Nyb2xsIGRpc3RhbmNlIGlzIGVxdWFsIHRvIDApIHRoZW4gZGlzYWJsZSB0aGVcblx0ICogYmVmb3JlIGJ1dHRvbi4gSWYgdGhlIGhlYWRlciBpcyBhdCB0aGUgZW5kIG9mIHRoZSBsaXN0IChzY3JvbGwgZGlzdGFuY2UgaXMgZXF1YWwgdG8gdGhlXG5cdCAqIG1heGltdW0gZGlzdGFuY2Ugd2UgY2FuIHNjcm9sbCksIHRoZW4gZGlzYWJsZSB0aGUgYWZ0ZXIgYnV0dG9uLlxuXHQgKlxuXHQgKiBUaGlzIGlzIGFuIGV4cGVuc2l2ZSBjYWxsIHRoYXQgZm9yY2VzIGEgbGF5b3V0IHJlZmxvdyB0byBjb21wdXRlIGJveCBhbmQgc2Nyb2xsIG1ldHJpY3MgYW5kXG5cdCAqIHNob3VsZCBiZSBjYWxsZWQgc3BhcmluZ2x5LlxuXHQgKi9cblx0X2NoZWNrU2Nyb2xsaW5nQ29udHJvbHMoKSB7XG5cdFx0aWYgKHRoaXMuZGlzYWJsZVBhZ2luYXRpb24oKSkge1xuXHRcdFx0dGhpcy5fZGlzYWJsZVNjcm9sbEFmdGVyID0gdGhpcy5fZGlzYWJsZVNjcm9sbEJlZm9yZSA9IHRydWU7XG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIENoZWNrIGlmIHRoZSBwYWdpbmF0aW9uIGFycm93cyBzaG91bGQgYmUgYWN0aXZhdGVkLlxuXHRcdFx0dGhpcy5fZGlzYWJsZVNjcm9sbEJlZm9yZSA9IHRoaXMuc2Nyb2xsRGlzdGFuY2UgPT09IDA7XG5cdFx0XHR0aGlzLl9kaXNhYmxlU2Nyb2xsQWZ0ZXIgPSB0aGlzLnNjcm9sbERpc3RhbmNlID09PSB0aGlzLl9nZXRNYXhTY3JvbGxEaXN0YW5jZSgpO1xuXHRcdFx0dGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG5cdFx0fVxuXHR9XG5cblx0LyoqXG5cdCAqIERldGVybWluZXMgd2hhdCBpcyB0aGUgbWF4aW11bSBsZW5ndGggaW4gcGl4ZWxzIHRoYXQgY2FuIGJlIHNldCBmb3IgdGhlIHNjcm9sbCBkaXN0YW5jZS4gVGhpc1xuXHQgKiBpcyBlcXVhbCB0byB0aGUgZGlmZmVyZW5jZSBpbiB3aWR0aCBiZXR3ZWVuIHRoZSB0YWIgbGlzdCBjb250YWluZXIgYW5kIHRhYiBoZWFkZXIgY29udGFpbmVyLlxuXHQgKlxuXHQgKiBUaGlzIGlzIGFuIGV4cGVuc2l2ZSBjYWxsIHRoYXQgZm9yY2VzIGEgbGF5b3V0IHJlZmxvdyB0byBjb21wdXRlIGJveCBhbmQgc2Nyb2xsIG1ldHJpY3MgYW5kXG5cdCAqIHNob3VsZCBiZSBjYWxsZWQgc3BhcmluZ2x5LlxuXHQgKi9cblx0X2dldE1heFNjcm9sbERpc3RhbmNlKCk6IG51bWJlciB7XG5cdFx0Y29uc3QgbGVuZ3RoT2ZUYWJMaXN0ID0gdGhpcy5fdGFiTGlzdElubmVyKCkubmF0aXZlRWxlbWVudC5zY3JvbGxXaWR0aDtcblx0XHRjb25zdCB2aWV3TGVuZ3RoID0gdGhpcy5fdGFiTGlzdENvbnRhaW5lcigpLm5hdGl2ZUVsZW1lbnQub2Zmc2V0V2lkdGg7XG5cdFx0cmV0dXJuIGxlbmd0aE9mVGFiTGlzdCAtIHZpZXdMZW5ndGggfHwgMDtcblx0fVxuXG5cdC8qKiBTdG9wcyB0aGUgY3VycmVudGx5LXJ1bm5pbmcgcGFnaW5hdG9yIGludGVydmFsLiAgKi9cblx0X3N0b3BJbnRlcnZhbCgpIHtcblx0XHR0aGlzLl9zdG9wU2Nyb2xsaW5nLm5leHQoKTtcblx0fVxuXG5cdC8qKlxuXHQgKiBIYW5kbGVzIHRoZSB1c2VyIHByZXNzaW5nIGRvd24gb24gb25lIG9mIHRoZSBwYWdpbmF0b3JzLlxuXHQgKiBTdGFydHMgc2Nyb2xsaW5nIHRoZSBoZWFkZXIgYWZ0ZXIgYSBjZXJ0YWluIGFtb3VudCBvZiB0aW1lLlxuXHQgKiBAcGFyYW0gZGlyZWN0aW9uIEluIHdoaWNoIGRpcmVjdGlvbiB0aGUgcGFnaW5hdG9yIHNob3VsZCBiZSBzY3JvbGxlZC5cblx0ICovXG5cdF9oYW5kbGVQYWdpbmF0b3JQcmVzcyhkaXJlY3Rpb246IFNjcm9sbERpcmVjdGlvbiwgbW91c2VFdmVudD86IE1vdXNlRXZlbnQpIHtcblx0XHQvLyBEb24ndCBzdGFydCBhdXRvIHNjcm9sbGluZyBmb3IgcmlnaHQgbW91c2UgYnV0dG9uIGNsaWNrcy4gTm90ZSB0aGF0IHdlIHNob3VsZG4ndCBoYXZlIHRvXG5cdFx0Ly8gbnVsbCBjaGVjayB0aGUgYGJ1dHRvbmAsIGJ1dCB3ZSBkbyBpdCBzbyB3ZSBkb24ndCBicmVhayB0ZXN0cyB0aGF0IHVzZSBmYWtlIGV2ZW50cy5cblx0XHRpZiAobW91c2VFdmVudCAmJiBtb3VzZUV2ZW50LmJ1dHRvbiAhPT0gbnVsbCAmJiBtb3VzZUV2ZW50LmJ1dHRvbiAhPT0gMCkge1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdC8vIEF2b2lkIG92ZXJsYXBwaW5nIHRpbWVycy5cblx0XHR0aGlzLl9zdG9wSW50ZXJ2YWwoKTtcblxuXHRcdC8vIFN0YXJ0IGEgdGltZXIgYWZ0ZXIgdGhlIGRlbGF5IGFuZCBrZWVwIGZpcmluZyBiYXNlZCBvbiB0aGUgaW50ZXJ2YWwuXG5cdFx0dGltZXIoSEVBREVSX1NDUk9MTF9ERUxBWSwgSEVBREVSX1NDUk9MTF9JTlRFUlZBTClcblx0XHRcdC8vIEtlZXAgdGhlIHRpbWVyIGdvaW5nIHVudGlsIHNvbWV0aGluZyB0ZWxscyBpdCB0byBzdG9wIG9yIHRoZSBjb21wb25lbnQgaXMgZGVzdHJveWVkLlxuXHRcdFx0LnBpcGUodGFrZVVudGlsKG1lcmdlKHRoaXMuX3N0b3BTY3JvbGxpbmcsIHRoaXMuX2Rlc3Ryb3llZCkpKVxuXHRcdFx0LnN1YnNjcmliZSgoKSA9PiB7XG5cdFx0XHRcdGNvbnN0IHsgbWF4U2Nyb2xsRGlzdGFuY2UsIGRpc3RhbmNlIH0gPSB0aGlzLl9zY3JvbGxIZWFkZXIoZGlyZWN0aW9uKTtcblxuXHRcdFx0XHQvLyBTdG9wIHRoZSB0aW1lciBpZiB3ZSd2ZSByZWFjaGVkIHRoZSBzdGFydCBvciB0aGUgZW5kLlxuXHRcdFx0XHRpZiAoZGlzdGFuY2UgPT09IDAgfHwgZGlzdGFuY2UgPj0gbWF4U2Nyb2xsRGlzdGFuY2UpIHtcblx0XHRcdFx0XHR0aGlzLl9zdG9wSW50ZXJ2YWwoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdH1cblxuXHQvKipcblx0ICogU2Nyb2xscyB0aGUgaGVhZGVyIHRvIGEgZ2l2ZW4gcG9zaXRpb24uXG5cdCAqIEBwYXJhbSBwb3NpdGlvbiBQb3NpdGlvbiB0byB3aGljaCB0byBzY3JvbGwuXG5cdCAqIEByZXR1cm5zIEluZm9ybWF0aW9uIG9uIHRoZSBjdXJyZW50IHNjcm9sbCBkaXN0YW5jZSBhbmQgdGhlIG1heGltdW0uXG5cdCAqL1xuXHRwcml2YXRlIF9zY3JvbGxUbyhwb3NpdGlvbjogbnVtYmVyKSB7XG5cdFx0aWYgKHRoaXMuZGlzYWJsZVBhZ2luYXRpb24oKSkge1xuXHRcdFx0cmV0dXJuIHsgbWF4U2Nyb2xsRGlzdGFuY2U6IDAsIGRpc3RhbmNlOiAwIH07XG5cdFx0fVxuXG5cdFx0Y29uc3QgbWF4U2Nyb2xsRGlzdGFuY2UgPSB0aGlzLl9nZXRNYXhTY3JvbGxEaXN0YW5jZSgpO1xuXHRcdHRoaXMuX3Njcm9sbERpc3RhbmNlID0gTWF0aC5tYXgoMCwgTWF0aC5taW4obWF4U2Nyb2xsRGlzdGFuY2UsIHBvc2l0aW9uKSk7XG5cblx0XHQvLyBNYXJrIHRoYXQgdGhlIHNjcm9sbCBkaXN0YW5jZSBoYXMgY2hhbmdlZCBzbyB0aGF0IGFmdGVyIHRoZSB2aWV3IGlzIGNoZWNrZWQsIHRoZSBDU1Ncblx0XHQvLyB0cmFuc2Zvcm1hdGlvbiBjYW4gbW92ZSB0aGUgaGVhZGVyLlxuXHRcdHRoaXMuX3Njcm9sbERpc3RhbmNlQ2hhbmdlZCA9IHRydWU7XG5cdFx0dGhpcy5fY2hlY2tTY3JvbGxpbmdDb250cm9scygpO1xuXG5cdFx0cmV0dXJuIHsgbWF4U2Nyb2xsRGlzdGFuY2UsIGRpc3RhbmNlOiB0aGlzLl9zY3JvbGxEaXN0YW5jZSB9O1xuXHR9XG59XG4iXX0=