@ohioepa/oepa-ui-lib 1.1.0

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 (299) hide show
  1. package/README.md +24 -0
  2. package/esm2022/lib/account-search-input/account-search-input.component.mjs +147 -0
  3. package/esm2022/lib/account-search-modal/account-search-modal.component.mjs +151 -0
  4. package/esm2022/lib/action-btn/action-btn.component.mjs +70 -0
  5. package/esm2022/lib/action-btn/oepa-action-event.mjs +2 -0
  6. package/esm2022/lib/action-btn/oepa-action.mjs +2 -0
  7. package/esm2022/lib/action-btn-modal/action-btn-modal.component.mjs +21 -0
  8. package/esm2022/lib/address/address.component.mjs +174 -0
  9. package/esm2022/lib/address/oepa-address.service.mjs +64 -0
  10. package/esm2022/lib/address/oepa-form-address.mjs +2 -0
  11. package/esm2022/lib/blank/blank.component.mjs +14 -0
  12. package/esm2022/lib/checkbox/checkbox.component.mjs +33 -0
  13. package/esm2022/lib/checkbox-input/checkbox-input.component.mjs +41 -0
  14. package/esm2022/lib/comment-modal/comment-modal.component.mjs +56 -0
  15. package/esm2022/lib/common-forms.module.mjs +291 -0
  16. package/esm2022/lib/confirmation-modal/confirmation-modal.component.mjs +120 -0
  17. package/esm2022/lib/contact/contact.component.mjs +102 -0
  18. package/esm2022/lib/contact/oepa-form-contact.mjs +2 -0
  19. package/esm2022/lib/date-input/date-input.component.mjs +52 -0
  20. package/esm2022/lib/date-input-modal/date-input-modal.component.mjs +68 -0
  21. package/esm2022/lib/datepicker/datepicker.component.mjs +131 -0
  22. package/esm2022/lib/daterangepicker/daterangepicker.component.mjs +70 -0
  23. package/esm2022/lib/document/document-editor/document-editor.component.mjs +225 -0
  24. package/esm2022/lib/document/document-event-entity-type.mjs +7 -0
  25. package/esm2022/lib/document/document-event-type.mjs +7 -0
  26. package/esm2022/lib/document/document-event.mjs +2 -0
  27. package/esm2022/lib/document/document-group/document-group.component.mjs +210 -0
  28. package/esm2022/lib/document/document-part/document-part.component.mjs +19 -0
  29. package/esm2022/lib/document/document-part-editor/document-part-editor.component.mjs +296 -0
  30. package/esm2022/lib/document/document-placeholder-modal/document-placeholder-modal.component.mjs +49 -0
  31. package/esm2022/lib/document/document-section/document-section.component.mjs +226 -0
  32. package/esm2022/lib/document/document.service.mjs +325 -0
  33. package/esm2022/lib/document/group-modal/group-modal.component.mjs +46 -0
  34. package/esm2022/lib/document/part-modal/part-modal.component.mjs +48 -0
  35. package/esm2022/lib/document/portal-document-class.mjs +2 -0
  36. package/esm2022/lib/document/portal-document-group.mjs +2 -0
  37. package/esm2022/lib/document/portal-document-part.mjs +2 -0
  38. package/esm2022/lib/document/portal-document-placeholder.mjs +2 -0
  39. package/esm2022/lib/document/portal-document-section.mjs +2 -0
  40. package/esm2022/lib/document/portal-document-text.mjs +2 -0
  41. package/esm2022/lib/document/portal-document-type.mjs +2 -0
  42. package/esm2022/lib/document/portal-document.mjs +2 -0
  43. package/esm2022/lib/document/portal-email-attachment-type.mjs +2 -0
  44. package/esm2022/lib/document/portal-email-attachment.mjs +2 -0
  45. package/esm2022/lib/document/portal-email-filter.mjs +2 -0
  46. package/esm2022/lib/document/portal-email.mjs +2 -0
  47. package/esm2022/lib/document/section-modal/section-modal.component.mjs +46 -0
  48. package/esm2022/lib/dual-list-box/array.pipes.mjs +71 -0
  49. package/esm2022/lib/dual-list-box/dual-list-box.component.mjs +339 -0
  50. package/esm2022/lib/dual-list-box/items-moved-event.mjs +2 -0
  51. package/esm2022/lib/dual-list-box/list-box-item.mjs +2 -0
  52. package/esm2022/lib/ebiz-address/ebiz-address.component.mjs +62 -0
  53. package/esm2022/lib/edoc-attachment/edoc-attachment.component.mjs +216 -0
  54. package/esm2022/lib/edoc-attachment/edoc-attachment.service.mjs +38 -0
  55. package/esm2022/lib/edoc-attachment/edocument-attachment-metadata.mjs +2 -0
  56. package/esm2022/lib/edoc-attachment/edocument-attachment.mjs +2 -0
  57. package/esm2022/lib/edoc-attachment/edocument-reference.mjs +2 -0
  58. package/esm2022/lib/entity/entity.service.mjs +104 -0
  59. package/esm2022/lib/entity/organization-create-modal/organization-create-modal.component.mjs +307 -0
  60. package/esm2022/lib/entity/organization-search-input/organization-search-input.component.mjs +127 -0
  61. package/esm2022/lib/entity/organization-search-modal/organization-search-modal.component.mjs +304 -0
  62. package/esm2022/lib/entity/person-create-modal/person-create-modal.component.mjs +316 -0
  63. package/esm2022/lib/entity/person-search-input/person-search-input.component.mjs +129 -0
  64. package/esm2022/lib/entity/person-search-modal/person-search-modal.component.mjs +311 -0
  65. package/esm2022/lib/entity/place-create-modal/place-create-modal.component.mjs +14 -0
  66. package/esm2022/lib/entity/place-search-input/place-search-input.component.mjs +126 -0
  67. package/esm2022/lib/entity/place-search-modal/place-search-modal.component.mjs +216 -0
  68. package/esm2022/lib/esri-map/esri-map.component.mjs +416 -0
  69. package/esm2022/lib/file-upload/file-upload.component.mjs +148 -0
  70. package/esm2022/lib/lynx-image-upload/lynx-image-upload.component.mjs +143 -0
  71. package/esm2022/lib/lynx-image-upload/lynx.service.mjs +47 -0
  72. package/esm2022/lib/masks/oepa-create-integer-mask.mjs +39 -0
  73. package/esm2022/lib/masks/oepa-integer-mask-args.mjs +2 -0
  74. package/esm2022/lib/message/message.component.mjs +19 -0
  75. package/esm2022/lib/message/oepa-message-type.mjs +7 -0
  76. package/esm2022/lib/message/oepa-message.mjs +31 -0
  77. package/esm2022/lib/message-list/message-list.component.mjs +24 -0
  78. package/esm2022/lib/multi-file-upload/multi-file-upload.component.mjs +137 -0
  79. package/esm2022/lib/notes-modal/notes-modal.component.mjs +177 -0
  80. package/esm2022/lib/notes-modal/oepa-note-result.mjs +2 -0
  81. package/esm2022/lib/notes-modal/oepa-note.mjs +2 -0
  82. package/esm2022/lib/numeric-input/numeric-input.component.mjs +50 -0
  83. package/esm2022/lib/numeric-input.directive.mjs +76 -0
  84. package/esm2022/lib/oepa-error-message/oepa-error-message.component.mjs +39 -0
  85. package/esm2022/lib/oepa-forms.service.mjs +199 -0
  86. package/esm2022/lib/oepa-images.mjs +59 -0
  87. package/esm2022/lib/oepa-wait-message/oepa-wait-message.component.mjs +29 -0
  88. package/esm2022/lib/ohio-lat-long/ohio-lat-long.component.mjs +176 -0
  89. package/esm2022/lib/parameter/parameter.mjs +2 -0
  90. package/esm2022/lib/parameter/parameter.service.mjs +47 -0
  91. package/esm2022/lib/params-help-button/params-help-button.component.mjs +42 -0
  92. package/esm2022/lib/phone-number/phone-number.component.mjs +44 -0
  93. package/esm2022/lib/pin-modal/oepa-attestation.mjs +2 -0
  94. package/esm2022/lib/pin-modal/oepa-pin.mjs +2 -0
  95. package/esm2022/lib/pin-modal/oepa-pin.service.mjs +54 -0
  96. package/esm2022/lib/pin-modal/oepa-security-question.mjs +2 -0
  97. package/esm2022/lib/pin-modal/pin-modal.component.mjs +186 -0
  98. package/esm2022/lib/progress-indicator/progress-info.mjs +2 -0
  99. package/esm2022/lib/select-input/select-input.component.mjs +96 -0
  100. package/esm2022/lib/server-timeout-modal/server-timeout-modal.component.mjs +63 -0
  101. package/esm2022/lib/shopping-cart/shopping-cart-summary/shopping-cart-summary.component.mjs +54 -0
  102. package/esm2022/lib/shopping-cart/shopping-cart-view/shopping-cart-view-parameters.mjs +2 -0
  103. package/esm2022/lib/shopping-cart/shopping-cart-view/shopping-cart-view.component.mjs +190 -0
  104. package/esm2022/lib/shopping-cart/shopping-cart.service.mjs +89 -0
  105. package/esm2022/lib/start-end-timepicker/start-end-timepicker.component.mjs +126 -0
  106. package/esm2022/lib/table/oepa-p-column.mjs +2 -0
  107. package/esm2022/lib/table/oepa-table-cell-classname.pipe.mjs +22 -0
  108. package/esm2022/lib/table/oepa-table-cell-click-event.mjs +2 -0
  109. package/esm2022/lib/table/oepa-table-cell-colspan.pipe.mjs +22 -0
  110. package/esm2022/lib/table/oepa-table-cell-hidden.pipe.mjs +22 -0
  111. package/esm2022/lib/table/oepa-table-cell-icon-classname.pipe.mjs +22 -0
  112. package/esm2022/lib/table/oepa-table-cell-img-src.pipe.mjs +22 -0
  113. package/esm2022/lib/table/oepa-table-cell-inner-html.pipe.mjs +22 -0
  114. package/esm2022/lib/table/oepa-table-cell-input-component.pipe.mjs +22 -0
  115. package/esm2022/lib/table/oepa-table-cell-not-selectable.pipe.mjs +22 -0
  116. package/esm2022/lib/table/oepa-table-cell-value.pipe.mjs +22 -0
  117. package/esm2022/lib/table/oepa-table-cell.mjs +2 -0
  118. package/esm2022/lib/table/oepa-table-column.mjs +2 -0
  119. package/esm2022/lib/table/oepa-table-config.mjs +2 -0
  120. package/esm2022/lib/table/oepa-table-filter.mjs +2 -0
  121. package/esm2022/lib/table/oepa-table-filtering.directive.mjs +57 -0
  122. package/esm2022/lib/table/oepa-table-header.mjs +2 -0
  123. package/esm2022/lib/table/oepa-table-page-info.mjs +2 -0
  124. package/esm2022/lib/table/oepa-table-popover.mjs +2 -0
  125. package/esm2022/lib/table/oepa-table-row.mjs +2 -0
  126. package/esm2022/lib/table/oepa-table-sort-criterion.mjs +2 -0
  127. package/esm2022/lib/table/oepa-table-sorting.directive.mjs +57 -0
  128. package/esm2022/lib/table/oepa-table.mjs +2 -0
  129. package/esm2022/lib/table/p-table/p-table.component.mjs +826 -0
  130. package/esm2022/lib/table/table-data-cell/table-data-cell-click-event.mjs +2 -0
  131. package/esm2022/lib/table/table-data-cell/table-data-cell.component.mjs +60 -0
  132. package/esm2022/lib/table/table-export.service.mjs +57 -0
  133. package/esm2022/lib/table/table-header-cell/table-header-cell.component.mjs +61 -0
  134. package/esm2022/lib/table/table.component.mjs +793 -0
  135. package/esm2022/lib/table/table.service.mjs +112 -0
  136. package/esm2022/lib/template-confirmation-modal/template-confirmation-modal.component.mjs +46 -0
  137. package/esm2022/lib/text-area-input/text-area-input.component.mjs +48 -0
  138. package/esm2022/lib/text-input/text-input.component.mjs +48 -0
  139. package/esm2022/lib/timeout-modal/timeout-modal.component.mjs +31 -0
  140. package/esm2022/lib/timepicker/timepicker.component.mjs +48 -0
  141. package/esm2022/lib/validation/form-validator.mjs +2 -0
  142. package/esm2022/lib/validation/validation.service.mjs +134 -0
  143. package/esm2022/lib/yes-no/yes-no.component.mjs +44 -0
  144. package/esm2022/lib/yes-no-boolean/yes-no.component.mjs +44 -0
  145. package/esm2022/lib/yes-no-other-input/yes-no-other-input.component.mjs +41 -0
  146. package/esm2022/lib/zip-code/zip-code.component.mjs +42 -0
  147. package/esm2022/ohioepa-oepa-ui-lib.mjs +5 -0
  148. package/esm2022/public-api.mjs +142 -0
  149. package/fesm2022/ohioepa-oepa-ui-lib.mjs +10720 -0
  150. package/fesm2022/ohioepa-oepa-ui-lib.mjs.map +1 -0
  151. package/index.d.ts +5 -0
  152. package/lib/account-search-input/account-search-input.component.d.ts +36 -0
  153. package/lib/account-search-modal/account-search-modal.component.d.ts +40 -0
  154. package/lib/action-btn/action-btn.component.d.ts +34 -0
  155. package/lib/action-btn/oepa-action-event.d.ts +19 -0
  156. package/lib/action-btn/oepa-action.d.ts +13 -0
  157. package/lib/action-btn-modal/action-btn-modal.component.d.ts +12 -0
  158. package/lib/address/address.component.d.ts +43 -0
  159. package/lib/address/oepa-address.service.d.ts +28 -0
  160. package/lib/address/oepa-form-address.d.ts +19 -0
  161. package/lib/blank/blank.component.d.ts +8 -0
  162. package/lib/checkbox/checkbox.component.d.ts +15 -0
  163. package/lib/checkbox-input/checkbox-input.component.d.ts +17 -0
  164. package/lib/comment-modal/comment-modal.component.d.ts +22 -0
  165. package/lib/common-forms.module.d.ts +104 -0
  166. package/lib/confirmation-modal/confirmation-modal.component.d.ts +49 -0
  167. package/lib/contact/contact.component.d.ts +33 -0
  168. package/lib/contact/oepa-form-contact.d.ts +58 -0
  169. package/lib/date-input/date-input.component.d.ts +18 -0
  170. package/lib/date-input-modal/date-input-modal.component.d.ts +25 -0
  171. package/lib/datepicker/datepicker.component.d.ts +28 -0
  172. package/lib/daterangepicker/daterangepicker.component.d.ts +22 -0
  173. package/lib/document/document-editor/document-editor.component.d.ts +34 -0
  174. package/lib/document/document-event-entity-type.d.ts +5 -0
  175. package/lib/document/document-event-type.d.ts +5 -0
  176. package/lib/document/document-event.d.ts +9 -0
  177. package/lib/document/document-group/document-group.component.d.ts +38 -0
  178. package/lib/document/document-part/document-part.component.d.ts +10 -0
  179. package/lib/document/document-part-editor/document-part-editor.component.d.ts +46 -0
  180. package/lib/document/document-placeholder-modal/document-placeholder-modal.component.d.ts +19 -0
  181. package/lib/document/document-section/document-section.component.d.ts +37 -0
  182. package/lib/document/document.service.d.ts +90 -0
  183. package/lib/document/group-modal/group-modal.component.d.ts +20 -0
  184. package/lib/document/part-modal/part-modal.component.d.ts +20 -0
  185. package/lib/document/portal-document-class.d.ts +10 -0
  186. package/lib/document/portal-document-group.d.ts +15 -0
  187. package/lib/document/portal-document-part.d.ts +22 -0
  188. package/lib/document/portal-document-placeholder.d.ts +12 -0
  189. package/lib/document/portal-document-section.d.ts +13 -0
  190. package/lib/document/portal-document-text.d.ts +7 -0
  191. package/lib/document/portal-document-type.d.ts +15 -0
  192. package/lib/document/portal-document.d.ts +27 -0
  193. package/lib/document/portal-email-attachment-type.d.ts +6 -0
  194. package/lib/document/portal-email-attachment.d.ts +12 -0
  195. package/lib/document/portal-email-filter.d.ts +12 -0
  196. package/lib/document/portal-email.d.ts +18 -0
  197. package/lib/document/section-modal/section-modal.component.d.ts +20 -0
  198. package/lib/dual-list-box/array.pipes.d.ts +36 -0
  199. package/lib/dual-list-box/dual-list-box.component.d.ts +91 -0
  200. package/lib/dual-list-box/items-moved-event.d.ts +11 -0
  201. package/lib/dual-list-box/list-box-item.d.ts +7 -0
  202. package/lib/ebiz-address/ebiz-address.component.d.ts +23 -0
  203. package/lib/edoc-attachment/edoc-attachment.component.d.ts +44 -0
  204. package/lib/edoc-attachment/edoc-attachment.service.d.ts +16 -0
  205. package/lib/edoc-attachment/edocument-attachment-metadata.d.ts +16 -0
  206. package/lib/edoc-attachment/edocument-attachment.d.ts +12 -0
  207. package/lib/edoc-attachment/edocument-reference.d.ts +5 -0
  208. package/lib/entity/entity.service.d.ts +31 -0
  209. package/lib/entity/organization-create-modal/organization-create-modal.component.d.ts +53 -0
  210. package/lib/entity/organization-search-input/organization-search-input.component.d.ts +34 -0
  211. package/lib/entity/organization-search-modal/organization-search-modal.component.d.ts +56 -0
  212. package/lib/entity/person-create-modal/person-create-modal.component.d.ts +53 -0
  213. package/lib/entity/person-search-input/person-search-input.component.d.ts +34 -0
  214. package/lib/entity/person-search-modal/person-search-modal.component.d.ts +56 -0
  215. package/lib/entity/place-create-modal/place-create-modal.component.d.ts +8 -0
  216. package/lib/entity/place-search-input/place-search-input.component.d.ts +34 -0
  217. package/lib/entity/place-search-modal/place-search-modal.component.d.ts +41 -0
  218. package/lib/esri-map/esri-map.component.d.ts +41 -0
  219. package/lib/file-upload/file-upload.component.d.ts +37 -0
  220. package/lib/lynx-image-upload/lynx-image-upload.component.d.ts +36 -0
  221. package/lib/lynx-image-upload/lynx.service.d.ts +16 -0
  222. package/lib/masks/oepa-create-integer-mask.d.ts +8 -0
  223. package/lib/masks/oepa-integer-mask-args.d.ts +5 -0
  224. package/lib/message/message.component.d.ts +10 -0
  225. package/lib/message/oepa-message-type.d.ts +5 -0
  226. package/lib/message/oepa-message.d.ts +7 -0
  227. package/lib/message-list/message-list.component.d.ts +11 -0
  228. package/lib/multi-file-upload/multi-file-upload.component.d.ts +36 -0
  229. package/lib/notes-modal/notes-modal.component.d.ts +50 -0
  230. package/lib/notes-modal/oepa-note-result.d.ts +10 -0
  231. package/lib/notes-modal/oepa-note.d.ts +13 -0
  232. package/lib/numeric-input/numeric-input.component.d.ts +20 -0
  233. package/lib/numeric-input.directive.d.ts +19 -0
  234. package/lib/oepa-error-message/oepa-error-message.component.d.ts +9 -0
  235. package/lib/oepa-forms.service.d.ts +28 -0
  236. package/lib/oepa-images.d.ts +53 -0
  237. package/lib/oepa-wait-message/oepa-wait-message.component.d.ts +9 -0
  238. package/lib/ohio-lat-long/ohio-lat-long.component.d.ts +63 -0
  239. package/lib/parameter/parameter.d.ts +7 -0
  240. package/lib/parameter/parameter.service.d.ts +18 -0
  241. package/lib/params-help-button/params-help-button.component.d.ts +15 -0
  242. package/lib/phone-number/phone-number.component.d.ts +19 -0
  243. package/lib/pin-modal/oepa-attestation.d.ts +10 -0
  244. package/lib/pin-modal/oepa-pin.d.ts +26 -0
  245. package/lib/pin-modal/oepa-pin.service.d.ts +38 -0
  246. package/lib/pin-modal/oepa-security-question.d.ts +8 -0
  247. package/lib/pin-modal/pin-modal.component.d.ts +46 -0
  248. package/lib/progress-indicator/progress-info.d.ts +4 -0
  249. package/lib/select-input/select-input.component.d.ts +27 -0
  250. package/lib/server-timeout-modal/server-timeout-modal.component.d.ts +23 -0
  251. package/lib/shopping-cart/shopping-cart-summary/shopping-cart-summary.component.d.ts +18 -0
  252. package/lib/shopping-cart/shopping-cart-view/shopping-cart-view-parameters.d.ts +10 -0
  253. package/lib/shopping-cart/shopping-cart-view/shopping-cart-view.component.d.ts +51 -0
  254. package/lib/shopping-cart/shopping-cart.service.d.ts +44 -0
  255. package/lib/start-end-timepicker/start-end-timepicker.component.d.ts +29 -0
  256. package/lib/table/oepa-p-column.d.ts +4 -0
  257. package/lib/table/oepa-table-cell-classname.pipe.d.ts +9 -0
  258. package/lib/table/oepa-table-cell-click-event.d.ts +15 -0
  259. package/lib/table/oepa-table-cell-colspan.pipe.d.ts +9 -0
  260. package/lib/table/oepa-table-cell-hidden.pipe.d.ts +9 -0
  261. package/lib/table/oepa-table-cell-icon-classname.pipe.d.ts +9 -0
  262. package/lib/table/oepa-table-cell-img-src.pipe.d.ts +9 -0
  263. package/lib/table/oepa-table-cell-inner-html.pipe.d.ts +9 -0
  264. package/lib/table/oepa-table-cell-input-component.pipe.d.ts +9 -0
  265. package/lib/table/oepa-table-cell-not-selectable.pipe.d.ts +9 -0
  266. package/lib/table/oepa-table-cell-value.pipe.d.ts +9 -0
  267. package/lib/table/oepa-table-cell.d.ts +66 -0
  268. package/lib/table/oepa-table-column.d.ts +71 -0
  269. package/lib/table/oepa-table-config.d.ts +72 -0
  270. package/lib/table/oepa-table-filter.d.ts +10 -0
  271. package/lib/table/oepa-table-filtering.directive.d.ts +17 -0
  272. package/lib/table/oepa-table-header.d.ts +9 -0
  273. package/lib/table/oepa-table-page-info.d.ts +22 -0
  274. package/lib/table/oepa-table-popover.d.ts +28 -0
  275. package/lib/table/oepa-table-row.d.ts +84 -0
  276. package/lib/table/oepa-table-sort-criterion.d.ts +4 -0
  277. package/lib/table/oepa-table-sorting.directive.d.ts +16 -0
  278. package/lib/table/oepa-table.d.ts +42 -0
  279. package/lib/table/p-table/p-table.component.d.ts +155 -0
  280. package/lib/table/table-data-cell/table-data-cell-click-event.d.ts +5 -0
  281. package/lib/table/table-data-cell/table-data-cell.component.d.ts +23 -0
  282. package/lib/table/table-export.service.d.ts +33 -0
  283. package/lib/table/table-header-cell/table-header-cell.component.d.ts +24 -0
  284. package/lib/table/table.component.d.ts +144 -0
  285. package/lib/table/table.service.d.ts +28 -0
  286. package/lib/template-confirmation-modal/template-confirmation-modal.component.d.ts +19 -0
  287. package/lib/text-area-input/text-area-input.component.d.ts +19 -0
  288. package/lib/text-input/text-input.component.d.ts +19 -0
  289. package/lib/timeout-modal/timeout-modal.component.d.ts +13 -0
  290. package/lib/timepicker/timepicker.component.d.ts +17 -0
  291. package/lib/validation/form-validator.d.ts +10 -0
  292. package/lib/validation/validation.service.d.ts +16 -0
  293. package/lib/yes-no/yes-no.component.d.ts +19 -0
  294. package/lib/yes-no-boolean/yes-no.component.d.ts +19 -0
  295. package/lib/yes-no-other-input/yes-no-other-input.component.d.ts +18 -0
  296. package/lib/zip-code/zip-code.component.d.ts +19 -0
  297. package/ohioepa-oepa-ui-lib-1.1.0.tgz +0 -0
  298. package/package.json +25 -0
  299. package/public-api.d.ts +138 -0
@@ -0,0 +1,793 @@
1
+ import { Component, EventEmitter, Input, Output } from '@angular/core';
2
+ import * as i0 from "@angular/core";
3
+ import * as i1 from "@angular/platform-browser";
4
+ import * as i2 from "./table.service";
5
+ import * as i3 from "./table-export.service";
6
+ import * as i4 from "@ohioepa/oepa-common-lib";
7
+ import * as i5 from "@angular/common";
8
+ import * as i6 from "@angular/forms";
9
+ import * as i7 from "ngx-bootstrap/pagination";
10
+ import * as i8 from "ngx-bootstrap/popover";
11
+ import * as i9 from "ngx-bootstrap/tooltip";
12
+ import * as i10 from "../action-btn/action-btn.component";
13
+ import * as i11 from "./oepa-table-sorting.directive";
14
+ import * as i12 from "./oepa-table-filtering.directive";
15
+ import * as i13 from "./oepa-table-cell-inner-html.pipe";
16
+ import * as i14 from "./oepa-table-cell-colspan.pipe";
17
+ import * as i15 from "./oepa-table-cell-value.pipe";
18
+ import * as i16 from "./oepa-table-cell-classname.pipe";
19
+ import * as i17 from "./oepa-table-cell-icon-classname.pipe";
20
+ import * as i18 from "./oepa-table-cell-img-src.pipe";
21
+ export class TableComponent {
22
+ sanitizer;
23
+ tableService;
24
+ tableExportService;
25
+ fileUtilService;
26
+ showFilterRow = false;
27
+ headerRows = [];
28
+ rows = [];
29
+ visibleColumnCount = 0;
30
+ allColumnCount = 0;
31
+ exportVisibleOnly = false;
32
+ dataColumns = [];
33
+ hiddenColumns = [];
34
+ columnHeaders = [];
35
+ _data = [];
36
+ _config = {};
37
+ currentFilters = [{
38
+ filterString: '',
39
+ columnId: undefined
40
+ }];
41
+ dataHasDetails = false;
42
+ showAllDetails = false;
43
+ allRowsSelected = false;
44
+ pageInfo = {
45
+ page: 1,
46
+ itemsPerPage: 10,
47
+ maxSize: 5,
48
+ numPages: 1,
49
+ length: 0
50
+ };
51
+ currentPage = 1;
52
+ paginationOn = true;
53
+ tableId = '';
54
+ set config(conf) {
55
+ if (!conf.className) {
56
+ conf.className = 'table-striped table-bordered';
57
+ }
58
+ if (conf.classNames) {
59
+ conf.className = conf.classNames.join(' ');
60
+ }
61
+ if (conf.rowsPerPage) {
62
+ this.pageInfo.itemsPerPage = conf.rowsPerPage;
63
+ }
64
+ this.exportVisibleOnly = conf.exportVisibleOnly;
65
+ this._config = conf;
66
+ }
67
+ get config() {
68
+ return this._config;
69
+ }
70
+ set complexHeader(hdrs) {
71
+ this.resetHeaders();
72
+ if (hdrs && hdrs.length) {
73
+ hdrs.forEach((hdr) => {
74
+ this.headerRows.push(this.extractInnerColumns(hdr.columns));
75
+ });
76
+ this.columnHeaders = this.extractColumnHeaders(this.headerRows);
77
+ this.dataColumns = this.extractDataColumns(this.headerRows);
78
+ this.initializeHiddenColumns(true);
79
+ }
80
+ }
81
+ set header(hdr) {
82
+ this.resetHeaders();
83
+ if (hdr.columns && hdr.columns.length > 0) {
84
+ this.headerRows.push(this.extractInnerColumns(hdr.columns));
85
+ }
86
+ this.columnHeaders = this.extractColumnHeaders(this.headerRows);
87
+ this.dataColumns = this.extractDataColumns(this.headerRows);
88
+ this.initializeHiddenColumns(false);
89
+ }
90
+ customBtnLabel = undefined;
91
+ customBtnVisible = false;
92
+ customBtnEnabled = false;
93
+ // Outputs (Events)
94
+ cellClicked = new EventEmitter();
95
+ actionClicked = new EventEmitter();
96
+ rowSelected = new EventEmitter();
97
+ customBtnClicked = new EventEmitter();
98
+ resetHeaders() {
99
+ this.headerRows = [];
100
+ this.columnHeaders = [];
101
+ this.dataColumns = [];
102
+ this.hiddenColumns = [];
103
+ }
104
+ initializeHiddenColumns(complexHeader) {
105
+ this.visibleColumnCount = 0;
106
+ this.allColumnCount = 0;
107
+ this.dataColumns.forEach((column) => {
108
+ if (complexHeader && (column?.hidden === true || column?.hidden === false)) {
109
+ console.error('disabling hidden attribute for column: ' + column.id +
110
+ '. Hidden columns are not supported for complex headers (yet).');
111
+ column.hidden = undefined;
112
+ this.visibleColumnCount++;
113
+ }
114
+ else if (column?.hidden === true) {
115
+ this.hiddenColumns.push(column);
116
+ }
117
+ else {
118
+ this.visibleColumnCount++;
119
+ }
120
+ this.allColumnCount++;
121
+ });
122
+ // console.log('visibleColumnCount = ' + this.visibleColumnCount);
123
+ }
124
+ set data(values) {
125
+ if (!this._data || this._data.length === 0) {
126
+ this._data = this.tableService.getData(this.tableId) || [];
127
+ }
128
+ if (values) {
129
+ for (let i = 0; i < values.length; i++) {
130
+ values[i].privateId = i;
131
+ }
132
+ if (this._data && this._data.length !== values.length) {
133
+ this.tableService.clearPageInfo(this.tableId);
134
+ }
135
+ }
136
+ this._data = values;
137
+ this.tableService.setData(this.tableId, this._data);
138
+ this.updateTable();
139
+ }
140
+ get data() {
141
+ return this._data.map(x => Object.assign({}, x));
142
+ }
143
+ totalRow;
144
+ constructor(sanitizer, tableService, tableExportService, fileUtilService) {
145
+ this.sanitizer = sanitizer;
146
+ this.tableService = tableService;
147
+ this.tableExportService = tableExportService;
148
+ this.fileUtilService = fileUtilService;
149
+ }
150
+ ngOnInit() {
151
+ this.paginationOn = !this._config.disablePagination;
152
+ }
153
+ extractInnerColumns(inner) {
154
+ const header = { columns: [] };
155
+ inner.forEach((value) => {
156
+ const column = header.columns.find((col) => col.id === value.id);
157
+ if (column) {
158
+ // overwrite repeated column
159
+ Object.assign(column, value);
160
+ }
161
+ if (!column) {
162
+ header.columns.push(value);
163
+ }
164
+ });
165
+ return header;
166
+ }
167
+ extractColumnHeaders(headerRows) {
168
+ const headers = [];
169
+ let rowIndex = 0;
170
+ const childColumns = {};
171
+ headerRows.forEach((hdr) => {
172
+ let colIndex = 0;
173
+ hdr.columns.forEach((column) => {
174
+ // console.log('rowIndex=' + rowIndex + ', colIndex=' + colIndex + ', column=' + JSON.stringify(column));
175
+ if (rowIndex === 0) {
176
+ headers.push(column.title);
177
+ if (column.colspan) {
178
+ for (let count = 1; count < column.colspan; count++) {
179
+ headers.push('');
180
+ }
181
+ }
182
+ if (column.rowspan) {
183
+ childColumns[colIndex] = column.rowspan - 1;
184
+ }
185
+ }
186
+ else {
187
+ while (childColumns[colIndex] && childColumns[colIndex] > 0) {
188
+ childColumns[colIndex]--;
189
+ colIndex++;
190
+ }
191
+ headers[colIndex] += ' ' + column.title;
192
+ if (column.colspan) {
193
+ for (let count = 1; count < column.colspan; count++) {
194
+ colIndex++;
195
+ }
196
+ }
197
+ }
198
+ colIndex++;
199
+ });
200
+ rowIndex++;
201
+ });
202
+ // console.log('headers = ' + JSON.stringify(headers));
203
+ return headers;
204
+ }
205
+ extractDataColumns(headerRows) {
206
+ const dataColumns = [];
207
+ let rowIndex = 0;
208
+ const childColumns = {};
209
+ headerRows.forEach((hdr) => {
210
+ let colIndex = 0;
211
+ hdr.columns.forEach((column) => {
212
+ if (rowIndex === 0) {
213
+ if (column.colspan && column.colspan > 1) {
214
+ for (let count = 0; count < column.colspan; count++) {
215
+ dataColumns.push({
216
+ id: '',
217
+ title: ''
218
+ });
219
+ }
220
+ colIndex += (column.colspan - 1);
221
+ }
222
+ else {
223
+ dataColumns.push(column);
224
+ if (column.rowspan) {
225
+ childColumns[colIndex] = column.rowspan - 1;
226
+ }
227
+ }
228
+ }
229
+ else {
230
+ while (childColumns[colIndex] && childColumns[colIndex] > 0) {
231
+ childColumns[colIndex]--;
232
+ colIndex++;
233
+ }
234
+ if (column.colspan && column.colspan > 1) {
235
+ colIndex += (column.colspan - 1);
236
+ }
237
+ else {
238
+ dataColumns[colIndex] = column;
239
+ }
240
+ }
241
+ colIndex++;
242
+ });
243
+ rowIndex++;
244
+ });
245
+ // console.log('dataColumns = ' + JSON.stringify(dataColumns));
246
+ return dataColumns;
247
+ }
248
+ sanitize(html) {
249
+ return this.sanitizer.bypassSecurityTrustHtml(html);
250
+ }
251
+ /**
252
+ * Check to see if any filters are set
253
+ */
254
+ noFilters() {
255
+ let noFilters = true;
256
+ this.currentFilters.forEach(filter => {
257
+ if (filter.filterString && filter.filterString.length > 0) {
258
+ noFilters = false;
259
+ }
260
+ });
261
+ return noFilters;
262
+ }
263
+ /**
264
+ * Retrieve the global filter string (if any) as a RegExp
265
+ */
266
+ getGlobalFilter() {
267
+ let regExp;
268
+ this.currentFilters.forEach(filter => {
269
+ if (!filter.columnId && filter.filterString && filter.filterString.length > 0) {
270
+ regExp = new RegExp(filter.filterString, 'i');
271
+ }
272
+ });
273
+ return regExp;
274
+ }
275
+ /**
276
+ * Retrieve the filter for the specified column (if any) as a RegExp.
277
+ * @param columnId
278
+ */
279
+ getFilterForColumn(columnId) {
280
+ let regExp;
281
+ this.currentFilters.forEach(filter => {
282
+ if (filter.columnId === columnId && filter.filterString && filter.filterString.length > 0) {
283
+ regExp = new RegExp(filter.filterString, 'i');
284
+ }
285
+ });
286
+ return regExp;
287
+ }
288
+ /**
289
+ * Filter the table data provided by the global or column-specific
290
+ * filters set in the UI.
291
+ * @param data
292
+ */
293
+ filterData(data) {
294
+ // don't attempt filtering if there are no filters set
295
+ if (this.noFilters()) {
296
+ return data;
297
+ }
298
+ let filteredData = data;
299
+ const tempArray = [];
300
+ filteredData.forEach((row) => {
301
+ let flag = this.filterByColumnFilters(row);
302
+ if (flag) {
303
+ flag = this.filterByGlobalFilter(row);
304
+ }
305
+ if (flag || row.isDivider) {
306
+ tempArray.push(row);
307
+ }
308
+ });
309
+ filteredData = tempArray;
310
+ return filteredData;
311
+ }
312
+ /**
313
+ * Test if row matches any of the columnn filters that may be set.
314
+ * @param row
315
+ */
316
+ filterByColumnFilters(row) {
317
+ let flag = true;
318
+ row.cells.forEach((cell) => {
319
+ const regExp = this.getFilterForColumn(cell.id);
320
+ const filterValue = cell.filterValue || cell.value || '';
321
+ if (regExp && filterValue !== undefined && filterValue !== null) {
322
+ const result = filterValue.toString().match(regExp);
323
+ flag = flag && (result !== null);
324
+ }
325
+ });
326
+ return flag;
327
+ }
328
+ /**
329
+ * Test if row matches the global filter
330
+ * @param row
331
+ */
332
+ filterByGlobalFilter(row) {
333
+ let flag = true;
334
+ const regExp = this.getGlobalFilter();
335
+ if (regExp) {
336
+ flag = false;
337
+ row.cells.forEach((cell) => {
338
+ const filterValue = cell.filterValue || cell.value;
339
+ if (filterValue !== undefined && filterValue !== null) {
340
+ const result = filterValue.toString().match(regExp);
341
+ flag = flag || (result !== null);
342
+ }
343
+ });
344
+ }
345
+ return flag;
346
+ }
347
+ hideColumn(column) {
348
+ this.hiddenColumns.push(column);
349
+ column.hidden = true;
350
+ this.visibleColumnCount--;
351
+ }
352
+ unhideColumn(columnId) {
353
+ const hiddenCols = [];
354
+ this.hiddenColumns.forEach((col) => {
355
+ if (col.id !== columnId) {
356
+ hiddenCols.push(col);
357
+ }
358
+ else {
359
+ col.hidden = false;
360
+ }
361
+ });
362
+ this.hiddenColumns = hiddenCols;
363
+ this.visibleColumnCount++;
364
+ }
365
+ sortData(data) {
366
+ let sortCriteria = this.tableService.getSortCriteria(this.tableId) || [];
367
+ if (sortCriteria.length == 0) {
368
+ return data;
369
+ }
370
+ this.resetColumnSortIndexes(sortCriteria);
371
+ return data.sort((previous, current) => {
372
+ let sortIndex = 0;
373
+ let sortResult = 0;
374
+ while (sortIndex < sortCriteria.length && sortResult === 0) {
375
+ let prev = this.getRowSortValue(previous, sortCriteria[sortIndex].columnId);
376
+ let curr = this.getRowSortValue(current, sortCriteria[sortIndex].columnId);
377
+ if (prev > curr) {
378
+ sortResult = (sortCriteria[sortIndex].sort === 'desc' ? -1 : 1);
379
+ }
380
+ else if (prev < curr) {
381
+ sortResult = (sortCriteria[sortIndex].sort === 'asc' ? -1 : 1);
382
+ }
383
+ else {
384
+ sortResult = 0;
385
+ }
386
+ sortIndex++;
387
+ }
388
+ return sortResult;
389
+ });
390
+ }
391
+ resetColumnSortIndexes(sortCriteria) {
392
+ if (sortCriteria && sortCriteria.length > 0) {
393
+ for (let i = 0; i < sortCriteria.length; i++) {
394
+ this.dataColumns.forEach(column => {
395
+ if (column?.id === sortCriteria[i].columnId) {
396
+ if (column) {
397
+ column.sortIndex = i + 1;
398
+ }
399
+ }
400
+ });
401
+ }
402
+ ;
403
+ }
404
+ }
405
+ /**
406
+ * Retrieve the display value of the specified cell.
407
+ * @param row
408
+ * @param columnId
409
+ */
410
+ getRowValue(row, columnId) {
411
+ let value;
412
+ row.cells.forEach((cell) => {
413
+ if (cell.id === columnId) {
414
+ value = cell.value;
415
+ }
416
+ });
417
+ return value;
418
+ }
419
+ /**
420
+ *
421
+ * @param row Retrieve the sort value of the specified cell (will default to display value if sort
422
+ * value is not specified).
423
+ * @param columnId
424
+ */
425
+ getRowSortValue(row, columnId) {
426
+ let value;
427
+ row.cells.forEach((cell) => {
428
+ if (cell.id === columnId) {
429
+ if (cell.sortValue !== undefined && cell.sortValue !== null) {
430
+ value = cell.sortValue;
431
+ }
432
+ else {
433
+ value = cell.value;
434
+ }
435
+ }
436
+ });
437
+ if (typeof value === 'string') {
438
+ value = value.toUpperCase();
439
+ }
440
+ return value;
441
+ }
442
+ changePage(data = this.data) {
443
+ if (!this.paginationOn) {
444
+ return data;
445
+ }
446
+ this.updatePage();
447
+ const start = (this.pageInfo.page - 1) * this.pageInfo.itemsPerPage;
448
+ const end = this.pageInfo.itemsPerPage > -1 ? (start + this.pageInfo.itemsPerPage) : data.length;
449
+ // not sure why, but maxSize was getting lost. Reset it here to prevent weirdness.
450
+ this.pageInfo.maxSize = 5;
451
+ return data.slice(start, end);
452
+ }
453
+ togglePagingation() {
454
+ this.paginationOn = !this.paginationOn;
455
+ this.updateTable();
456
+ }
457
+ onFilterChanged(filter) {
458
+ const matchFilter = this.currentFilters.find((f) => {
459
+ return f.columnId === filter.columnId;
460
+ });
461
+ if (!matchFilter) {
462
+ this.currentFilters.push(filter);
463
+ }
464
+ else {
465
+ matchFilter.filterString = filter.filterString;
466
+ }
467
+ this.updateTable();
468
+ }
469
+ onSortChanged(column) {
470
+ this.tableService.setSort(this.tableId, column);
471
+ this.updateTable();
472
+ }
473
+ onPageChanged(pageEvent) {
474
+ this.pageInfo = {
475
+ page: pageEvent.page,
476
+ itemsPerPage: pageEvent.itemsPerPage,
477
+ maxSize: this.pageInfo.maxSize,
478
+ length: this.pageInfo.length,
479
+ numPages: this.pageInfo.numPages
480
+ };
481
+ this.tableService.setPage(this.tableId, pageEvent.page);
482
+ this.updateTable();
483
+ }
484
+ updateTable() {
485
+ const filteredData = this.filterData(this.data);
486
+ const sortedData = this.sortData(filteredData);
487
+ this.rows = this.changePage(sortedData);
488
+ this.pageInfo.length = sortedData.length;
489
+ this.dataHasDetails = this.checkForDetails(this.rows);
490
+ }
491
+ updatePage() {
492
+ const savedPageNumber = this.tableService.getPage(this.tableId);
493
+ if (savedPageNumber && this.pageInfo.page !== savedPageNumber) {
494
+ this.pageInfo.page = savedPageNumber;
495
+ this.currentPage = this.pageInfo.page;
496
+ }
497
+ }
498
+ checkForDetails(data) {
499
+ let hasDetails = false;
500
+ if (data && data.length) {
501
+ data.forEach((row) => {
502
+ if (row.showDetail === true || row.showDetail === false) {
503
+ hasDetails = true;
504
+ }
505
+ });
506
+ }
507
+ return hasDetails;
508
+ }
509
+ toggleAllDetails() {
510
+ // console.log('toggleAllDetails...');
511
+ this.showAllDetails = !this.showAllDetails;
512
+ // console.log('showAllDetails = ' + this.showAllDetails);
513
+ if (this._data && this._data.length) {
514
+ this._data.forEach((row) => {
515
+ if (row.showDetail !== undefined) {
516
+ row.showDetail = this.showAllDetails;
517
+ // console.log('setting details for row to ' + this.showAllDetails);
518
+ }
519
+ });
520
+ }
521
+ this.updateTable();
522
+ }
523
+ toggleRowDetail(toggleRow) {
524
+ if (toggleRow && this._data && this._data.length) {
525
+ this._data.forEach((row) => {
526
+ // console.log('TEST: ' + JSON.stringify(row.dataSource) + ' === ' + JSON.stringify(toggleRow.dataSource));
527
+ if (row.dataSource === toggleRow.dataSource) {
528
+ // console.log('!!! MATCH !!!');
529
+ row.showDetail = !toggleRow.showDetail;
530
+ toggleRow.showDetail = row.showDetail;
531
+ // console.log('show detail = ' + row.showDetail + ' for row: ' + JSON.stringify(row.dataSource));
532
+ }
533
+ });
534
+ // this._data = this._data.splice(0);
535
+ }
536
+ // console.log('toggleRowDetail...');
537
+ // this.dumpDetailRows();
538
+ }
539
+ isActionColumn(columnId) {
540
+ // console.log('isActionColumn ' + columnId);
541
+ let actionColumn = false;
542
+ this.headerRows.forEach((hdr) => {
543
+ hdr.columns.forEach((column) => {
544
+ if (column.id === columnId) {
545
+ // console.log('test action column: ' + column.id + ' - ' + column.actionColumn);
546
+ actionColumn = column.actionColumn || false;
547
+ }
548
+ });
549
+ });
550
+ return actionColumn;
551
+ }
552
+ isColumnHidden(columnId) {
553
+ // console.log('isColumnHidden ' + columnId);
554
+ let hidden = false;
555
+ this.headerRows.forEach((hdr) => {
556
+ hdr.columns.forEach((column) => {
557
+ if (column.id === columnId) {
558
+ // console.log('test hidden column: ' + column.id + ' - ' + column.hidden);
559
+ hidden = column.hidden || false;
560
+ }
561
+ });
562
+ });
563
+ return hidden;
564
+ }
565
+ getHiddenColumns() {
566
+ const columns = [];
567
+ this.headerRows.forEach((hdr) => {
568
+ hdr.columns.forEach((column) => {
569
+ if (column.hidden) {
570
+ columns.push(column);
571
+ }
572
+ });
573
+ });
574
+ return columns;
575
+ }
576
+ getCellClassName(row, columnId) {
577
+ let result = '';
578
+ row.cells.forEach((cell) => {
579
+ if (cell.id === columnId) {
580
+ result = cell.className;
581
+ }
582
+ });
583
+ return result;
584
+ }
585
+ getCellColSpan(row, columnId) {
586
+ let result = 1;
587
+ row.cells.forEach((cell) => {
588
+ if (cell.id === columnId) {
589
+ result = cell.colSpan || 0 >= 0 ? cell.colSpan : 1;
590
+ }
591
+ });
592
+ return result;
593
+ }
594
+ getCellIconClassName(row, columnId) {
595
+ let result = '';
596
+ row.cells.forEach((cell) => {
597
+ if (cell.id === columnId) {
598
+ result = cell.iconClassName;
599
+ }
600
+ });
601
+ return result;
602
+ }
603
+ getCellImgSrc(row, columnId) {
604
+ let result = '';
605
+ row.cells.forEach((cell) => {
606
+ if (cell.id === columnId) {
607
+ result = cell.imgSrc;
608
+ }
609
+ });
610
+ return result;
611
+ }
612
+ getCellInnerHTML(row, columnId) {
613
+ let result = '';
614
+ row.cells.forEach((cell) => {
615
+ if (cell.id === columnId) {
616
+ result = cell.innerHTML;
617
+ }
618
+ });
619
+ return result;
620
+ }
621
+ cellClick(row, columnId) {
622
+ const value = this.getRowValue(row, columnId);
623
+ this.cellClicked.emit({ row, columnId, value });
624
+ }
625
+ onActionClick(event) {
626
+ this.actionClicked.emit(event);
627
+ }
628
+ toggleAllRowsSelection() {
629
+ const selectedRows = [];
630
+ this.allRowsSelected = !this.allRowsSelected;
631
+ this._data.forEach((r) => {
632
+ if (r.selectable) {
633
+ r.selected = this.allRowsSelected;
634
+ }
635
+ if (r.selected) {
636
+ selectedRows.push(r);
637
+ }
638
+ });
639
+ this.updateTable();
640
+ this.rowSelected.emit(selectedRows);
641
+ }
642
+ toggleRowSelection(row) {
643
+ const selectedRows = [];
644
+ row.selected = !row.selected;
645
+ this._data.forEach((dr) => {
646
+ if (row.privateId === dr.privateId) {
647
+ dr.selected = row.selected;
648
+ }
649
+ if (dr.selected) {
650
+ selectedRows.push(dr);
651
+ }
652
+ else {
653
+ this.allRowsSelected = false;
654
+ }
655
+ });
656
+ this.updateTable();
657
+ this.rowSelected.emit(selectedRows);
658
+ }
659
+ singleRowSelection(row) {
660
+ const selectedRows = [];
661
+ row.selected = !row.selected;
662
+ // add row to selected rows if it is selected
663
+ if (row.selected) {
664
+ selectedRows.push(row);
665
+ }
666
+ // unselect any other row that may be selected
667
+ this._data.forEach((dr) => {
668
+ if (row.privateId === dr.privateId) {
669
+ dr.selected = row.selected;
670
+ }
671
+ else {
672
+ dr.selected = false;
673
+ }
674
+ });
675
+ this.updateTable();
676
+ this.rowSelected.emit(selectedRows);
677
+ }
678
+ prepareRowsForExport(rows) {
679
+ const result = [];
680
+ // console.log('prepareRowsForExport...');
681
+ // this.dumpDetailRows();
682
+ if (rows && rows.length) {
683
+ rows.forEach((row) => {
684
+ // console.log('showDetail = ' + row.showDetail + ' ' + JSON.stringify(row.cells));
685
+ result.push({
686
+ cells: row.cells,
687
+ actions: row.actions,
688
+ showDetail: row.showDetail,
689
+ subTable: row.detail ? this.convertToTable(row.detail) : undefined,
690
+ isDivider: row.isDivider,
691
+ dividerClassName: row.dividerClassName
692
+ });
693
+ });
694
+ }
695
+ return result;
696
+ }
697
+ gatherTableData(rows) {
698
+ // console.log('gatherTableData...');
699
+ // this.dumpDetailRows();
700
+ const oepaTable = {};
701
+ oepaTable.headerRows = this.headerRows;
702
+ oepaTable.allDataRows = this.prepareRowsForExport(rows);
703
+ oepaTable.showAllDetails = this.showAllDetails;
704
+ oepaTable.className = this._config.className;
705
+ oepaTable.visibleColumnCount = this.visibleColumnCount;
706
+ oepaTable.allColumnCount = this.allColumnCount;
707
+ return oepaTable;
708
+ }
709
+ dumpDetailRows() {
710
+ console.log('dumpDetailRows - Total rows: ' + this._data.length);
711
+ this._data.forEach((row) => {
712
+ if (row.showDetail) {
713
+ console.log('SHOW DETAIL: ' + JSON.stringify(row.dataSource));
714
+ }
715
+ });
716
+ }
717
+ convertToTable(template) {
718
+ let oepaTable = undefined;
719
+ if (template.component === TableComponent) {
720
+ const table = new TableComponent(this.sanitizer, this.tableService, this.tableExportService, this.fileUtilService);
721
+ if (template.inputs && template.inputs.length > 0) {
722
+ template.inputs.forEach((input) => {
723
+ if (input.name === 'config') {
724
+ table.config = input.value;
725
+ }
726
+ else if (input.name === 'complexHeader') {
727
+ table.complexHeader = input.value;
728
+ }
729
+ else if (input.name === 'header') {
730
+ table.header = input.value;
731
+ }
732
+ else if (input.name === 'data') {
733
+ table.data = input.value;
734
+ }
735
+ });
736
+ oepaTable = table.gatherTableData(table.data);
737
+ }
738
+ }
739
+ return oepaTable;
740
+ }
741
+ toggleExportVisibleOnly() {
742
+ this.exportVisibleOnly = !this.exportVisibleOnly;
743
+ }
744
+ exportToExcel() {
745
+ const exportTable = this.gatherTableData(this.exportVisibleOnly ? this.rows : this._data);
746
+ this.tableExportService.downloadExcel(exportTable, this._config).subscribe(data => {
747
+ this.fileUtilService.downloadFile(data, 'application/vnd.ms-excel');
748
+ }, error => console.log(error));
749
+ }
750
+ exportToHTML() {
751
+ const exportTable = this.gatherTableData(this.exportVisibleOnly ? this.rows : this._data);
752
+ // for now, always embed sub-tables in HTML view.
753
+ this.tableExportService.downloadHTML(exportTable, this._config).subscribe(data => {
754
+ this.fileUtilService.downloadFile(data, 'text/html');
755
+ }, error => console.log(error));
756
+ }
757
+ onCustomBtnClick() {
758
+ this.customBtnClicked.emit();
759
+ }
760
+ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableComponent, deps: [{ token: i1.DomSanitizer }, { token: i2.TableService }, { token: i3.TableExportService }, { token: i4.OepaFileUtilService }], target: i0.ɵɵFactoryTarget.Component });
761
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: TableComponent, selector: "oepa-table", inputs: { tableId: "tableId", config: "config", complexHeader: "complexHeader", header: "header", customBtnLabel: "customBtnLabel", customBtnVisible: "customBtnVisible", customBtnEnabled: "customBtnEnabled", data: "data", totalRow: "totalRow" }, outputs: { cellClicked: "cellClicked", actionClicked: "actionClicked", rowSelected: "rowSelected", customBtnClicked: "customBtnClicked" }, ngImport: i0, template: "<!-- Unhide select input - only visible if one or more columns are hidden -->\n\n<form *ngIf=\"hiddenColumns.length > 0\">\n <div class=\"row mb-2\">\n <label class=\"col-sm-2 col-form-label\">Show Hidden Columns:</label>\n <div class=\"col-sm-4\">\n <select class=\"form-select\" (change)=\"unhideColumn($any($event).target.value)\" [id]=\"tableId+'_UnhideColumnSelect'\">\n <option value=\"\">Choose a column</option>\n <option *ngFor=\"let col of hiddenColumns\" [value]=\"col.id\">{{col.title}}</option>\n </select>\n </div>\n </div>\n</form>\n<!-- This is the table -->\n<div ngClass=\"{{config.divClassName || ''}}\" >\n<table *ngIf=\"!config.hideTable\" class=\"table dataTable\" ngClass=\"{{config.className || ''}}\" role=\"grid\" style=\"width: 100%;\">\n\n<!-- This is the table header -->\n<thead>\n <!-- There may be multiple header rows -->\n <tr *ngFor=\"let hdr of headerRows; let hr=index;\" role=\"row\">\n <!-- Details indicator column (if data has details) -->\n <th *ngIf=\"dataHasDetails && hr === 0\" [rowSpan]=\"headerRows.length\" class=\"detail-indicator-col\">\n <span>\n <i (click)=\"toggleAllDetails()\" [id]=\"tableId+'_ShowAllDetailsLink'\" class=\"bi\" [ngClass]=\"{'bi-chevron-down': showAllDetails, 'bi-chevron-right': !showAllDetails}\"\n [tooltip]=\"(showAllDetails ? 'Hide' : 'Show') + ' details for all rows'\" placement=\"right\">\n </i>\n </span>\n </th>\n <ng-template ngFor let-column [ngForOf]=\"hdr.columns\" let-c=\"index\">\n <!-- Header cell -->\n <th *ngIf=\"!column.hidden\" ngClass=\"{{column.className || ''}}\" [colSpan]=\"column.colspan || 1\" [rowSpan]=\"column.rowspan || 1\">\n <!-- Select all Rows Checkbox -->\n <div class=\"text-center\">\n <input *ngIf=\"column.selectColumn\" type=\"checkbox\" [checked]=\"allRowsSelected\" (change)=\"toggleAllRowsSelection()\">\n\n <!-- Header cell text with sort capability (if specified) -->\n <span [oepaTableSorting]=\"true\" [column]=\"column\" [tableId]=\"tableId\" (sortChanged)=\"onSortChanged($event)\" [id]=\"tableId+'_SortColumnLink_'+column.id\">\n <span *ngIf=\"column.sort\"><i class=\"pull-left bi\" [ngClass]=\"{'bi-chevron-down': column.sort === 'desc', 'bi-chevron-up': column.sort === 'asc'}\"></i>\n <sup *ngIf=\"column?.sortIndex || 0 > 1\">{{column.sortIndex}}</sup></span>\n {{column.title}}\n </span>\n <!-- button to allow column to be hidden (if specified) -->\n <button *ngIf=\"column.hidden === false\" type=\"button\" class=\"btn-close float-end\" aria-label=\"Hide\" (click)=\"hideColumn(column)\"\n [id]=\"tableId+'_HideColumnLink'+'_'+column.id\">\n </button>\n\n </div>\n <!-- column filter (if specified) -->\n <div *ngIf=\"((rows && rows.length > 0) || !noFilters()) && column.filterable\" >\n <input [oepaTableFiltering]=\"{ filterString: '', columnId: column.id }\" [tableId]=\"tableId\" class=\"form-control input-sm\" (tableChanged)=\"onFilterChanged($event)\"\n [id]=\"tableId+'_FilterColumn_'+column.id\" />\n </div>\n </th>\n </ng-template>\n </tr>\n</thead>\n\n<!-- This is the table body -->\n<tbody>\n <ng-template ngFor let-row [ngForOf]=\"rows\" let-r=\"index\">\n <!-- Data Row -->\n <tr>\n <td *ngIf=\"dataHasDetails\">\n <!-- Detail icon (if specified) -->\n <span *ngIf=\"row.showDetail === true || row.showDetail === false\">\n <i *ngIf=\"row.detailIconClassName\" [ngClass]=\"row.detailIconClassName\"></i>\n <i (click)=\"toggleRowDetail(row)\" [id]=\"tableId+'_ShowDetailLink_'+r\" class=\"bi\" [ngClass]=\"{'bi-chevron-down': row.showDetail, 'bi-chevron-right': !row.showDetail}\"\n [tooltip]=\"(row.showDetail ? 'Hide' : 'Show') + ' details for this row'\" placement=\"right\">\n </i>\n </span>\n </td>\n <!-- If row is a divider, it spans the whole table -->\n <!-- <td *ngIf=\"row.isDivider\" [colSpan]=\"visibleColumnCount + (dataHasDetails ? 1 : 0)\" [ngClass]=\"row.dividerClassName || 'oepa-table-gray'\">&nbsp;</td> -->\n <!-- Data Rows -->\n <ng-template *ngIf=\"!row.isDivider\" ngFor let-col [ngForOf]=\"dataColumns\" let-i=\"index\">\n <td *ngIf=\"!col.hidden && (row|cellColspan:col) > 0\" ngClass=\"{{row|cellClassname:col || ''}}\" [colSpan]=\"row|cellColspan:col\">\n <!-- Data Cell -->\n <div *ngIf=\"!col.actionColumn && !col.selectColumn && !col.singleSelectColumn\">\n <!-- Template for popover 1 -->\n <ng-template #popoverTemplate>\n <div *ngIf=\"row.popover\">\n <cml-template [templateInfo]=\"row.popover.content\"></cml-template>\n </div>\n </ng-template>\n <!-- Popover 1 icon (if specified) -->\n <span *ngIf=\"row.popover && i === (row.popoverColumnIndex || 0) && row.popover\" tabindex=\"0\" [popoverTitle]=\"row.popover.title\" [popover]=\"popoverTemplate\"\n [containerClass]=\"row.popover.containerClass\" placement=\"right\" [triggers]=\"row.popover.trigger || 'mouseenter:mouseleave'\">\n <i [ngClass]=\"row.popover.className\" [id]=\"tableId+'_PopoverLink_'+r\"></i>\n </span>\n\n <!-- Template for popover 2 -->\n <ng-template #popover2Template>\n <div *ngIf=\"row.popover2\">\n <cml-template [templateInfo]=\"row.popover2.content\"></cml-template>\n </div>\n </ng-template>\n <!-- Popover 2 icon (if specified) -->\n <span *ngIf=\"i === (row.popover2ColumnIndex || 0) && row.popover2\" tabindex=\"0\" [popoverTitle]=\"row.popover2.title\" [popover]=\"popover2Template\"\n [containerClass]=\"row.popover2.containerClass\" placement=\"right\" [triggers]=\"row.popover2.trigger || 'mouseenter:mouseleave'\">\n <i [ngClass]=\"row.popover2.className\" [id]=\"tableId+'_Popover2Link_'+r\"></i>\n </span>\n\n <!-- Template for popover 3 -->\n <ng-template #popover3Template>\n <div *ngIf=\"row.popover3\">\n <cml-template [templateInfo]=\"row.popover3.content\"></cml-template>\n </div>\n </ng-template>\n <!-- Popover 3 icon (if specified) -->\n <span *ngIf=\"i === (row.popover3ColumnIndex || 0) && row.popover3\" tabindex=\"0\" [popoverTitle]=\"row.popover3.title\" [popover]=\"popover3Template\"\n [containerClass]=\"row.popover3.containerClass\" placement=\"right\" [triggers]=\"row.popover3.trigger || 'mouseenter:mouseleave'\">\n <i [ngClass]=\"row.popover3.className\" [id]=\"tableId+'_Popover3Link_'+r\"></i>\n </span>\n\n \n <!-- <div *ngIf=\"row|cellInnerHTML:col\" [innerHTML]=\"row|cellInnerHTML:col\"></div>\n <span *ngIf=\"!(row|cellInnerHTML:col)\">{{row|cellValue:col}}</span> -->\n\n <!-- If col is hyperlink, display data as a hyperlink -->\n <button *ngIf=\"col.hyperlink\" type=\"button\" class=\"btn btn-link\" (click)=\"cellClick(row, col.id)\" [id]=\"tableId+'_CellClick_'+r+'_'+i\">\n <span *ngIf=\"!(row|cellInnerHTML:col)\">\n <i [ngClass]=\"row|cellIconClassname:col\"></i>\n <span *ngIf=\"row|cellImgSrc:col\"><img [src]=\"row|cellImgSrc:col\"/></span>\n {{row|cellValue:col}}\n </span>\n <div *ngIf=\"row|cellInnerHTML:col\" [innerHTML]=\"row|cellInnerHTML:col\"></div>\n </button>\n <!-- If col is NOT hyperlink, just display data -->\n <span *ngIf=\"!col.hyperlink\">\n <span *ngIf=\"!(row|cellInnerHTML:col)\">\n <i ngClass=\"{{row|cellIconClassname:col || ''}}\"></i>\n <span *ngIf=\"row|cellImgSrc:col\"><img [src]=\"row|cellImgSrc:col\"/></span>\n {{row|cellValue:col}}\n </span>\n <div *ngIf=\"row|cellInnerHTML:col\" [innerHTML]=\"row|cellInnerHTML:col\"></div>\n </span>\n </div>\n <!-- Select Cell -->\n <div *ngIf=\"col.selectColumn\" class=\"text-center\">\n <input [id]=\"tableId+'_'+r\" type=\"checkbox\" [disabled]=\"!row.selectable\" [checked]=\"row.selected\" (change)=\"toggleRowSelection(row)\">\n </div>\n <!-- Single Select Cell -->\n <div *ngIf=\"col.singleSelectColumn\" class=\"text-center\">\n <input [id]=\"tableId+'_singleSelect_'+r\" type=\"radio\" [disabled]=\"!row.selectable\" [checked]=\"row.selected\" (change)=\"singleRowSelection(row)\">\n </div>\n <!-- Action Button Cell -->\n <div *ngIf=\"col.actionColumn && row.actions\">\n <oepa-action-btn [actions]=\"row.actions\" [data]=\"row.dataSource\" (actionClicked)=\"onActionClick($event)\" [btnId]=\"tableId+'_'+r\"></oepa-action-btn>\n </div>\n </td>\n </ng-template>\n </tr>\n\n <!-- Detail Row -->\n <tr *ngIf=\"row.showDetail\" class=\"table-info\">\n <td [colSpan]=\"visibleColumnCount + (dataHasDetails ? 1 : 0)\">\n <cml-template [templateInfo]=\"row.detail\"></cml-template>\n </td>\n </tr>\n </ng-template>\n <tr *ngIf=\"totalRow\">\n <td *ngIf=\"dataHasDetails\">\n </td>\n <ng-template ngFor let-totalCol [ngForOf]=\"dataColumns\">\n <td *ngIf=\"!totalCol.hidden\" ngClass=\"{{totalRow|cellClassname:totalCol || ''}}\">\n <div>\n <span><i ngClass=\"{{totalRow|cellIconClassname:totalCol || ''}}\"></i>{{totalRow|cellValue:totalCol}}</span>\n </div>\n </td>\n </ng-template>\n </tr>\n</tbody>\n</table>\n</div>\n<!-- Table footer -->\n<form *ngIf=\"!config.hideFooter || (data && pageInfo.itemsPerPage < data.length)\" class=\"form-horizontal\">\n<div class=\"form-group row text-right\">\n <!-- Table-wide filter -->\n <div class=\"col-sm-4\">\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <input *ngIf=\"!config.hideGlobalFilter\" placeholder=\"Filter all columns\" [oepaTableFiltering]=\"{ filterString: '' }\" [tableId]=\"tableId\" class=\"form-control input-sm\" (tableChanged)=\"onFilterChanged($event)\"\n [id]=\"tableId+'_FilterAllColumnsInput'\" />\n </div>\n <div class=\"col-sm-6\">\n <span *ngIf=\"config.showRowCountInFooter && _data && _data.length > 0\">\n <span class=\"badge badge-secondary\" style=\"color: #999\">{{_data.length}}</span>&nbsp;total rows\n </span>\n </div>\n </div>\n </div>\n <!-- Export Buttons -->\n <div class=\"col-sm-4 d-flex justify-content-center\">\n <div class=\"row\">\n <div class=\"col-sm-12 text-center\">\n <button type=\"button\" *ngIf=\"config.exportToExcel\" class=\"btn btn-primary mr-1\" (click)=\"exportToExcel()\" [id]=\"tableId+'_ExportToExcelBtn'\">Export to Excel</button>\n <button type=\"button\" *ngIf=\"config.exportToHTML\" class=\"btn btn-primary mr-1\" (click)=\"exportToHTML()\" [id]=\"tableId+'_ExportToHTMLBtn'\">Export to HTML</button>\n <button *ngIf=\"customBtnVisible\" type=\"button\" class=\"btn btn-primary mr-1\" (click)=\"onCustomBtnClick()\" [id]=\"tableId+'_CustomBtn'\" [disabled]=\"!customBtnEnabled\">{{customBtnLabel}}</button>\n </div>\n <div *ngIf=\"config.exportToExcel || config.exportToHTML\" class=\"col-sm-12 text-center\">\n <span>Export only visible data:&nbsp;\n <input type=\"checkbox\" [checked]=\"exportVisibleOnly\" (click)=\"toggleExportVisibleOnly()\" id=\"exportVisibleOnlyCheckbox\"/>\n </span>\n </div>\n </div>\n </div>\n <!-- Pagination -->\n <div *ngIf=\"!config.disablePagination\" class=\"col-sm-4 d-flex justify-content-end\">\n <pagination *ngIf=\"paginationOn\" class=\"pagination-sm\" [totalItems]=\"pageInfo.length\" [itemsPerPage]=\"pageInfo.itemsPerPage\" [maxSize]=\"pageInfo.maxSize\"\n [(ngModel)]=\"currentPage\" name=\"currentTablePage\"\n [boundaryLinks]=\"true\" [rotate]=\"false\" (pageChanged)=\"onPageChanged($event)\" (numPages)=\"pageInfo.numPages = $event\">\n </pagination>\n &nbsp;\n <button (click)=\"togglePagingation()\" type=\"button\" class=\"btn btn-default btn-sm mr-1\">{{ paginationOn ? 'Show All Rows' : 'Restore Pagination'}}</button>\n </div>\n</div>\n</form>", styles: [".pagination{margin:0}th.oepa-table-header-center{text-align:center}.oepa-table-bold{font-weight:700}.oepa-table-italic{font-style:italic}.oepa-table-line-through{text-decoration:line-through}.oepa-table-gray{background-color:#ddd}td.oepa-undeline-cell{border-bottom:1pt solid black}.detail-indicator-col{width:30px}.action-btn-col{width:90px}.select-col{width:20px}\n"], dependencies: [{ kind: "directive", type: i5.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "directive", type: i5.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i5.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i6.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i6.NgSelectOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.ɵNgSelectMultipleOption, selector: "option", inputs: ["ngValue", "value"] }, { kind: "directive", type: i6.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i6.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i6.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "directive", type: i6.NgForm, selector: "form:not([ngNoForm]):not([formGroup]),ng-form,[ngForm]", inputs: ["ngFormOptions"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "component", type: i7.PaginationComponent, selector: "pagination", inputs: ["align", "maxSize", "boundaryLinks", "directionLinks", "firstText", "previousText", "nextText", "lastText", "rotate", "pageBtnClass", "disabled", "customPageTemplate", "customNextTemplate", "customPreviousTemplate", "customFirstTemplate", "customLastTemplate", "itemsPerPage", "totalItems"], outputs: ["numPages", "pageChanged"] }, { kind: "directive", type: i8.PopoverDirective, selector: "[popover]", inputs: ["adaptivePosition", "boundariesElement", "popover", "popoverContext", "popoverTitle", "placement", "outsideClick", "triggers", "container", "containerClass", "isOpen", "delay"], outputs: ["onShown", "onHidden"], exportAs: ["bs-popover"] }, { kind: "directive", type: i9.TooltipDirective, selector: "[tooltip], [tooltipHtml]", inputs: ["adaptivePosition", "tooltip", "placement", "triggers", "container", "containerClass", "boundariesElement", "isOpen", "isDisabled", "delay", "tooltipHtml", "tooltipPlacement", "tooltipIsOpen", "tooltipEnable", "tooltipAppendToBody", "tooltipAnimation", "tooltipClass", "tooltipContext", "tooltipPopupDelay", "tooltipFadeDuration", "tooltipTrigger"], outputs: ["tooltipChange", "onShown", "onHidden", "tooltipStateChanged"], exportAs: ["bs-tooltip"] }, { kind: "component", type: i4.OepaTemplateComponent, selector: "cml-template", inputs: ["templateInfo"] }, { kind: "component", type: i10.ActionBtnComponent, selector: "oepa-action-btn", inputs: ["label", "btnId", "data", "actions", "normalSize", "dropup"], outputs: ["actionClicked"] }, { kind: "directive", type: i11.OepaTableSortingDirective, selector: "[oepaTableSorting]", inputs: ["tableId", "oepaTableSorting", "column"], outputs: ["sortChanged"] }, { kind: "directive", type: i12.OepaTableFilteringDirective, selector: "[oepaTableFiltering]", inputs: ["oepaTableFiltering", "tableId"], outputs: ["tableChanged"] }, { kind: "pipe", type: i13.OepaTableCellInnerHtmlPipe, name: "cellInnerHTML" }, { kind: "pipe", type: i14.OepaTableCellColSpanPipe, name: "cellColspan" }, { kind: "pipe", type: i15.OepaTableCellValuePipe, name: "cellValue" }, { kind: "pipe", type: i16.OepaTableCellClassnamePipe, name: "cellClassname" }, { kind: "pipe", type: i17.OepaTableCellIconClassnamePipe, name: "cellIconClassname" }, { kind: "pipe", type: i18.OepaTableCellImgSrcPipe, name: "cellImgSrc" }] });
762
+ }
763
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: TableComponent, decorators: [{
764
+ type: Component,
765
+ args: [{ selector: 'oepa-table', template: "<!-- Unhide select input - only visible if one or more columns are hidden -->\n\n<form *ngIf=\"hiddenColumns.length > 0\">\n <div class=\"row mb-2\">\n <label class=\"col-sm-2 col-form-label\">Show Hidden Columns:</label>\n <div class=\"col-sm-4\">\n <select class=\"form-select\" (change)=\"unhideColumn($any($event).target.value)\" [id]=\"tableId+'_UnhideColumnSelect'\">\n <option value=\"\">Choose a column</option>\n <option *ngFor=\"let col of hiddenColumns\" [value]=\"col.id\">{{col.title}}</option>\n </select>\n </div>\n </div>\n</form>\n<!-- This is the table -->\n<div ngClass=\"{{config.divClassName || ''}}\" >\n<table *ngIf=\"!config.hideTable\" class=\"table dataTable\" ngClass=\"{{config.className || ''}}\" role=\"grid\" style=\"width: 100%;\">\n\n<!-- This is the table header -->\n<thead>\n <!-- There may be multiple header rows -->\n <tr *ngFor=\"let hdr of headerRows; let hr=index;\" role=\"row\">\n <!-- Details indicator column (if data has details) -->\n <th *ngIf=\"dataHasDetails && hr === 0\" [rowSpan]=\"headerRows.length\" class=\"detail-indicator-col\">\n <span>\n <i (click)=\"toggleAllDetails()\" [id]=\"tableId+'_ShowAllDetailsLink'\" class=\"bi\" [ngClass]=\"{'bi-chevron-down': showAllDetails, 'bi-chevron-right': !showAllDetails}\"\n [tooltip]=\"(showAllDetails ? 'Hide' : 'Show') + ' details for all rows'\" placement=\"right\">\n </i>\n </span>\n </th>\n <ng-template ngFor let-column [ngForOf]=\"hdr.columns\" let-c=\"index\">\n <!-- Header cell -->\n <th *ngIf=\"!column.hidden\" ngClass=\"{{column.className || ''}}\" [colSpan]=\"column.colspan || 1\" [rowSpan]=\"column.rowspan || 1\">\n <!-- Select all Rows Checkbox -->\n <div class=\"text-center\">\n <input *ngIf=\"column.selectColumn\" type=\"checkbox\" [checked]=\"allRowsSelected\" (change)=\"toggleAllRowsSelection()\">\n\n <!-- Header cell text with sort capability (if specified) -->\n <span [oepaTableSorting]=\"true\" [column]=\"column\" [tableId]=\"tableId\" (sortChanged)=\"onSortChanged($event)\" [id]=\"tableId+'_SortColumnLink_'+column.id\">\n <span *ngIf=\"column.sort\"><i class=\"pull-left bi\" [ngClass]=\"{'bi-chevron-down': column.sort === 'desc', 'bi-chevron-up': column.sort === 'asc'}\"></i>\n <sup *ngIf=\"column?.sortIndex || 0 > 1\">{{column.sortIndex}}</sup></span>\n {{column.title}}\n </span>\n <!-- button to allow column to be hidden (if specified) -->\n <button *ngIf=\"column.hidden === false\" type=\"button\" class=\"btn-close float-end\" aria-label=\"Hide\" (click)=\"hideColumn(column)\"\n [id]=\"tableId+'_HideColumnLink'+'_'+column.id\">\n </button>\n\n </div>\n <!-- column filter (if specified) -->\n <div *ngIf=\"((rows && rows.length > 0) || !noFilters()) && column.filterable\" >\n <input [oepaTableFiltering]=\"{ filterString: '', columnId: column.id }\" [tableId]=\"tableId\" class=\"form-control input-sm\" (tableChanged)=\"onFilterChanged($event)\"\n [id]=\"tableId+'_FilterColumn_'+column.id\" />\n </div>\n </th>\n </ng-template>\n </tr>\n</thead>\n\n<!-- This is the table body -->\n<tbody>\n <ng-template ngFor let-row [ngForOf]=\"rows\" let-r=\"index\">\n <!-- Data Row -->\n <tr>\n <td *ngIf=\"dataHasDetails\">\n <!-- Detail icon (if specified) -->\n <span *ngIf=\"row.showDetail === true || row.showDetail === false\">\n <i *ngIf=\"row.detailIconClassName\" [ngClass]=\"row.detailIconClassName\"></i>\n <i (click)=\"toggleRowDetail(row)\" [id]=\"tableId+'_ShowDetailLink_'+r\" class=\"bi\" [ngClass]=\"{'bi-chevron-down': row.showDetail, 'bi-chevron-right': !row.showDetail}\"\n [tooltip]=\"(row.showDetail ? 'Hide' : 'Show') + ' details for this row'\" placement=\"right\">\n </i>\n </span>\n </td>\n <!-- If row is a divider, it spans the whole table -->\n <!-- <td *ngIf=\"row.isDivider\" [colSpan]=\"visibleColumnCount + (dataHasDetails ? 1 : 0)\" [ngClass]=\"row.dividerClassName || 'oepa-table-gray'\">&nbsp;</td> -->\n <!-- Data Rows -->\n <ng-template *ngIf=\"!row.isDivider\" ngFor let-col [ngForOf]=\"dataColumns\" let-i=\"index\">\n <td *ngIf=\"!col.hidden && (row|cellColspan:col) > 0\" ngClass=\"{{row|cellClassname:col || ''}}\" [colSpan]=\"row|cellColspan:col\">\n <!-- Data Cell -->\n <div *ngIf=\"!col.actionColumn && !col.selectColumn && !col.singleSelectColumn\">\n <!-- Template for popover 1 -->\n <ng-template #popoverTemplate>\n <div *ngIf=\"row.popover\">\n <cml-template [templateInfo]=\"row.popover.content\"></cml-template>\n </div>\n </ng-template>\n <!-- Popover 1 icon (if specified) -->\n <span *ngIf=\"row.popover && i === (row.popoverColumnIndex || 0) && row.popover\" tabindex=\"0\" [popoverTitle]=\"row.popover.title\" [popover]=\"popoverTemplate\"\n [containerClass]=\"row.popover.containerClass\" placement=\"right\" [triggers]=\"row.popover.trigger || 'mouseenter:mouseleave'\">\n <i [ngClass]=\"row.popover.className\" [id]=\"tableId+'_PopoverLink_'+r\"></i>\n </span>\n\n <!-- Template for popover 2 -->\n <ng-template #popover2Template>\n <div *ngIf=\"row.popover2\">\n <cml-template [templateInfo]=\"row.popover2.content\"></cml-template>\n </div>\n </ng-template>\n <!-- Popover 2 icon (if specified) -->\n <span *ngIf=\"i === (row.popover2ColumnIndex || 0) && row.popover2\" tabindex=\"0\" [popoverTitle]=\"row.popover2.title\" [popover]=\"popover2Template\"\n [containerClass]=\"row.popover2.containerClass\" placement=\"right\" [triggers]=\"row.popover2.trigger || 'mouseenter:mouseleave'\">\n <i [ngClass]=\"row.popover2.className\" [id]=\"tableId+'_Popover2Link_'+r\"></i>\n </span>\n\n <!-- Template for popover 3 -->\n <ng-template #popover3Template>\n <div *ngIf=\"row.popover3\">\n <cml-template [templateInfo]=\"row.popover3.content\"></cml-template>\n </div>\n </ng-template>\n <!-- Popover 3 icon (if specified) -->\n <span *ngIf=\"i === (row.popover3ColumnIndex || 0) && row.popover3\" tabindex=\"0\" [popoverTitle]=\"row.popover3.title\" [popover]=\"popover3Template\"\n [containerClass]=\"row.popover3.containerClass\" placement=\"right\" [triggers]=\"row.popover3.trigger || 'mouseenter:mouseleave'\">\n <i [ngClass]=\"row.popover3.className\" [id]=\"tableId+'_Popover3Link_'+r\"></i>\n </span>\n\n \n <!-- <div *ngIf=\"row|cellInnerHTML:col\" [innerHTML]=\"row|cellInnerHTML:col\"></div>\n <span *ngIf=\"!(row|cellInnerHTML:col)\">{{row|cellValue:col}}</span> -->\n\n <!-- If col is hyperlink, display data as a hyperlink -->\n <button *ngIf=\"col.hyperlink\" type=\"button\" class=\"btn btn-link\" (click)=\"cellClick(row, col.id)\" [id]=\"tableId+'_CellClick_'+r+'_'+i\">\n <span *ngIf=\"!(row|cellInnerHTML:col)\">\n <i [ngClass]=\"row|cellIconClassname:col\"></i>\n <span *ngIf=\"row|cellImgSrc:col\"><img [src]=\"row|cellImgSrc:col\"/></span>\n {{row|cellValue:col}}\n </span>\n <div *ngIf=\"row|cellInnerHTML:col\" [innerHTML]=\"row|cellInnerHTML:col\"></div>\n </button>\n <!-- If col is NOT hyperlink, just display data -->\n <span *ngIf=\"!col.hyperlink\">\n <span *ngIf=\"!(row|cellInnerHTML:col)\">\n <i ngClass=\"{{row|cellIconClassname:col || ''}}\"></i>\n <span *ngIf=\"row|cellImgSrc:col\"><img [src]=\"row|cellImgSrc:col\"/></span>\n {{row|cellValue:col}}\n </span>\n <div *ngIf=\"row|cellInnerHTML:col\" [innerHTML]=\"row|cellInnerHTML:col\"></div>\n </span>\n </div>\n <!-- Select Cell -->\n <div *ngIf=\"col.selectColumn\" class=\"text-center\">\n <input [id]=\"tableId+'_'+r\" type=\"checkbox\" [disabled]=\"!row.selectable\" [checked]=\"row.selected\" (change)=\"toggleRowSelection(row)\">\n </div>\n <!-- Single Select Cell -->\n <div *ngIf=\"col.singleSelectColumn\" class=\"text-center\">\n <input [id]=\"tableId+'_singleSelect_'+r\" type=\"radio\" [disabled]=\"!row.selectable\" [checked]=\"row.selected\" (change)=\"singleRowSelection(row)\">\n </div>\n <!-- Action Button Cell -->\n <div *ngIf=\"col.actionColumn && row.actions\">\n <oepa-action-btn [actions]=\"row.actions\" [data]=\"row.dataSource\" (actionClicked)=\"onActionClick($event)\" [btnId]=\"tableId+'_'+r\"></oepa-action-btn>\n </div>\n </td>\n </ng-template>\n </tr>\n\n <!-- Detail Row -->\n <tr *ngIf=\"row.showDetail\" class=\"table-info\">\n <td [colSpan]=\"visibleColumnCount + (dataHasDetails ? 1 : 0)\">\n <cml-template [templateInfo]=\"row.detail\"></cml-template>\n </td>\n </tr>\n </ng-template>\n <tr *ngIf=\"totalRow\">\n <td *ngIf=\"dataHasDetails\">\n </td>\n <ng-template ngFor let-totalCol [ngForOf]=\"dataColumns\">\n <td *ngIf=\"!totalCol.hidden\" ngClass=\"{{totalRow|cellClassname:totalCol || ''}}\">\n <div>\n <span><i ngClass=\"{{totalRow|cellIconClassname:totalCol || ''}}\"></i>{{totalRow|cellValue:totalCol}}</span>\n </div>\n </td>\n </ng-template>\n </tr>\n</tbody>\n</table>\n</div>\n<!-- Table footer -->\n<form *ngIf=\"!config.hideFooter || (data && pageInfo.itemsPerPage < data.length)\" class=\"form-horizontal\">\n<div class=\"form-group row text-right\">\n <!-- Table-wide filter -->\n <div class=\"col-sm-4\">\n <div class=\"row\">\n <div class=\"col-sm-6\">\n <input *ngIf=\"!config.hideGlobalFilter\" placeholder=\"Filter all columns\" [oepaTableFiltering]=\"{ filterString: '' }\" [tableId]=\"tableId\" class=\"form-control input-sm\" (tableChanged)=\"onFilterChanged($event)\"\n [id]=\"tableId+'_FilterAllColumnsInput'\" />\n </div>\n <div class=\"col-sm-6\">\n <span *ngIf=\"config.showRowCountInFooter && _data && _data.length > 0\">\n <span class=\"badge badge-secondary\" style=\"color: #999\">{{_data.length}}</span>&nbsp;total rows\n </span>\n </div>\n </div>\n </div>\n <!-- Export Buttons -->\n <div class=\"col-sm-4 d-flex justify-content-center\">\n <div class=\"row\">\n <div class=\"col-sm-12 text-center\">\n <button type=\"button\" *ngIf=\"config.exportToExcel\" class=\"btn btn-primary mr-1\" (click)=\"exportToExcel()\" [id]=\"tableId+'_ExportToExcelBtn'\">Export to Excel</button>\n <button type=\"button\" *ngIf=\"config.exportToHTML\" class=\"btn btn-primary mr-1\" (click)=\"exportToHTML()\" [id]=\"tableId+'_ExportToHTMLBtn'\">Export to HTML</button>\n <button *ngIf=\"customBtnVisible\" type=\"button\" class=\"btn btn-primary mr-1\" (click)=\"onCustomBtnClick()\" [id]=\"tableId+'_CustomBtn'\" [disabled]=\"!customBtnEnabled\">{{customBtnLabel}}</button>\n </div>\n <div *ngIf=\"config.exportToExcel || config.exportToHTML\" class=\"col-sm-12 text-center\">\n <span>Export only visible data:&nbsp;\n <input type=\"checkbox\" [checked]=\"exportVisibleOnly\" (click)=\"toggleExportVisibleOnly()\" id=\"exportVisibleOnlyCheckbox\"/>\n </span>\n </div>\n </div>\n </div>\n <!-- Pagination -->\n <div *ngIf=\"!config.disablePagination\" class=\"col-sm-4 d-flex justify-content-end\">\n <pagination *ngIf=\"paginationOn\" class=\"pagination-sm\" [totalItems]=\"pageInfo.length\" [itemsPerPage]=\"pageInfo.itemsPerPage\" [maxSize]=\"pageInfo.maxSize\"\n [(ngModel)]=\"currentPage\" name=\"currentTablePage\"\n [boundaryLinks]=\"true\" [rotate]=\"false\" (pageChanged)=\"onPageChanged($event)\" (numPages)=\"pageInfo.numPages = $event\">\n </pagination>\n &nbsp;\n <button (click)=\"togglePagingation()\" type=\"button\" class=\"btn btn-default btn-sm mr-1\">{{ paginationOn ? 'Show All Rows' : 'Restore Pagination'}}</button>\n </div>\n</div>\n</form>", styles: [".pagination{margin:0}th.oepa-table-header-center{text-align:center}.oepa-table-bold{font-weight:700}.oepa-table-italic{font-style:italic}.oepa-table-line-through{text-decoration:line-through}.oepa-table-gray{background-color:#ddd}td.oepa-undeline-cell{border-bottom:1pt solid black}.detail-indicator-col{width:30px}.action-btn-col{width:90px}.select-col{width:20px}\n"] }]
766
+ }], ctorParameters: () => [{ type: i1.DomSanitizer }, { type: i2.TableService }, { type: i3.TableExportService }, { type: i4.OepaFileUtilService }], propDecorators: { tableId: [{
767
+ type: Input
768
+ }], config: [{
769
+ type: Input
770
+ }], complexHeader: [{
771
+ type: Input
772
+ }], header: [{
773
+ type: Input
774
+ }], customBtnLabel: [{
775
+ type: Input
776
+ }], customBtnVisible: [{
777
+ type: Input
778
+ }], customBtnEnabled: [{
779
+ type: Input
780
+ }], cellClicked: [{
781
+ type: Output
782
+ }], actionClicked: [{
783
+ type: Output
784
+ }], rowSelected: [{
785
+ type: Output
786
+ }], customBtnClicked: [{
787
+ type: Output
788
+ }], data: [{
789
+ type: Input
790
+ }], totalRow: [{
791
+ type: Input
792
+ }] } });
793
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvb2VwYS11aS1saWIvc3JjL2xpYi90YWJsZS90YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9vZXBhLXVpLWxpYi9zcmMvbGliL3RhYmxlL3RhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQVUsTUFBTSxlQUFlLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBMkIvRSxNQUFNLE9BQU8sY0FBYztJQTJJRTtJQUNqQjtJQUNBO0lBQ0E7SUE3SUgsYUFBYSxHQUFZLEtBQUssQ0FBQztJQUMvQixVQUFVLEdBQTJCLEVBQUUsQ0FBQztJQUN4QyxJQUFJLEdBQXdCLEVBQUUsQ0FBQztJQUMvQixrQkFBa0IsR0FBRyxDQUFDLENBQUM7SUFDdkIsY0FBYyxHQUFHLENBQUMsQ0FBQztJQUNuQixpQkFBaUIsR0FBd0IsS0FBSyxDQUFDO0lBRS9DLFdBQVcsR0FBMkIsRUFBRSxDQUFDO0lBQ3pDLGFBQWEsR0FBMkIsRUFBRSxDQUFDO0lBQzNDLGFBQWEsR0FBa0IsRUFBRSxDQUFDO0lBQ2xDLEtBQUssR0FBd0IsRUFBRSxDQUFDO0lBQy9CLE9BQU8sR0FBb0IsRUFBRSxDQUFDO0lBQzlCLGNBQWMsR0FBMkIsQ0FBQztZQUNoRCxZQUFZLEVBQUUsRUFBRTtZQUNoQixRQUFRLEVBQUUsU0FBUztTQUNwQixDQUFDLENBQUM7SUFFSSxjQUFjLEdBQUcsS0FBSyxDQUFDO0lBQ3ZCLGNBQWMsR0FBRyxLQUFLLENBQUM7SUFFdkIsZUFBZSxHQUFHLEtBQUssQ0FBQztJQUV4QixRQUFRLEdBQXNCO1FBQ25DLElBQUksRUFBRSxDQUFDO1FBQ1AsWUFBWSxFQUFFLEVBQUU7UUFDaEIsT0FBTyxFQUFFLENB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QUFDLENBQUMsU0FBUyxDQUN2RSxJQUFJLENBQUMsRUFBRTtZQUNMLElBQUksQ0FBQyxlQUFlLENBQUMsWUFBWSxDQUFDLElBQUksRUFBRSxXQUFXLENBQUMsQ0FBQztRQUN2RCxDQUFDLEVBQ0QsS0FBSyxDQUFDLEVBQUUsQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUM1QixDQUFDO0lBQ0osQ0FBQztJQUVNLGdCQUFnQjtRQUNyQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDL0IsQ0FBQzt3R0E3eEJVLGNBQWM7NEZBQWQsY0FBYyxtYkMzQjNCLCt4WUF5Tk87OzRGRDlMTSxjQUFjO2tCQUwxQixTQUFTOytCQUNFLFlBQVk7K0tBcUNiLE9BQU87c0JBQWYsS0FBSztnQkFHSyxNQUFNO3NCQURoQixLQUFLO2dCQW9CSyxhQUFhO3NCQUR2QixLQUFLO2dCQWNLLE1BQU07c0JBRGhCLEtBQUs7Z0JBV0csY0FBYztzQkFBdEIsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0csZ0JBQWdCO3NCQUF4QixLQUFLO2dCQUdXLFdBQVc7c0JBQTNCLE1BQU07Z0JBQ1UsYUFBYTtzQkFBN0IsTUFBTTtnQkFDVSxXQUFXO3NCQUEzQixNQUFNO2dCQUNVLGdCQUFnQjtzQkFBaEMsTUFBTTtnQkE2QkksSUFBSTtzQkFEZCxLQUFLO2dCQXVCRyxRQUFRO3NCQUFoQixLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQ29tcG9uZW50LCBFdmVudEVtaXR0ZXIsIElucHV0LCBPdXRwdXQsIE9uSW5pdCB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRG9tU2FuaXRpemVyLCBTYWZlSHRtbCB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xuXG5pbXBvcnQgeyBPZXBhVGFibGUgfSBmcm9tICcuL29lcGEtdGFibGUnO1xuaW1wb3J0IHsgT2VwYVRhYmxlQ29uZmlnIH0gZnJvbSAnLi9vZXBhLXRhYmxlLWNvbmZpZyc7XG5pbXBvcnQgeyBPZXBhVGFibGVIZWFkZXIgfSBmcm9tICcuL29lcGEtdGFibGUtaGVhZGVyJztcbmltcG9ydCB7IE9lcGFUYWJsZUNvbHVtbiB9IGZyb20gJy4vb2VwYS10YWJsZS1jb2x1bW4nO1xuaW1wb3J0IHsgT2VwYVRhYmxlUm93IH0gZnJvbSAnLi9vZXBhLXRhYmxlLXJvdyc7XG5pbXBvcnQgeyBPZXBhVGFibGVDZWxsIH0gZnJvbSAnLi9vZXBhLXRhYmxlLWNlbGwnO1xuaW1wb3J0IHsgT2VwYVRhYmxlRmlsdGVyIH0gZnJvbSAnLi9vZXBhLXRhYmxlLWZpbHRlcic7XG5pbXBvcnQgeyBPZXBhVGFibGVQYWdlSW5mbyB9IGZyb20gJy4vb2VwYS10YWJsZS1wYWdlLWluZm8nO1xuaW1wb3J0IHsgT2VwYVRhYmxlQ2VsbENsaWNrRXZlbnQgfSBmcm9tICcuL29lcGEtdGFibGUtY2VsbC1jbGljay1ldmVudCc7XG5cbmltcG9ydCB7IE9lcGFBY3Rpb25FdmVudCB9IGZyb20gJy4uL2FjdGlvbi1idG4vb2VwYS1hY3Rpb24tZXZlbnQnO1xuXG5pbXBvcnQgeyBUYWJsZUV4cG9ydFNlcnZpY2UgfSBmcm9tICcuL3RhYmxlLWV4cG9ydC5zZXJ2aWNlJztcbmltcG9ydCB7IE9lcGFGaWxlVXRpbFNlcnZpY2UgfSBmcm9tICdAb2hpb2VwYS9vZXBhLWNvbW1vbi1saWInO1xuaW1wb3J0IHsgT2VwYVRlbXBsYXRlSW5mbyB9IGZyb20gJ0BvaGlvZXBhL29lcGEtY29tbW9uLWxpYic7XG5pbXBvcnQgeyBUYWJsZVNlcnZpY2UgfSBmcm9tICcuL3RhYmxlLnNlcnZpY2UnO1xuaW1wb3J0IHsgT2VwYVRhYmxlU29ydENyaXRlcmlvbiB9IGZyb20gJy4vb2VwYS10YWJsZS1zb3J0LWNyaXRlcmlvbic7XG5pbXBvcnQgeyBQYWdlQ2hhbmdlZEV2ZW50IH0gZnJvbSAnbmd4LWJvb3RzdHJhcC9wYWdpbmF0aW9uJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnb2VwYS10YWJsZScsXG4gIHRlbXBsYXRlVXJsOiAnLi90YWJsZS5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3RhYmxlLmNvbXBvbmVudC5jc3MnXVxufSlcbmV4cG9ydCBjbGFzcyBUYWJsZUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCB7XG4gIHB1YmxpYyBzaG93RmlsdGVyUm93OiBCb29sZWFuID0gZmFsc2U7XG4gIHB1YmxpYyBoZWFkZXJSb3dzOiBBcnJheTxPZXBhVGFibGVIZWFkZXI+ID0gW107XG4gIHB1YmxpYyByb3dzOiBBcnJheTxPZXBhVGFibGVSb3c+ID0gW107XG4gIHB1YmxpYyB2aXNpYmxlQ29sdW1uQ291bnQgPSAwO1xuICBwdWJsaWMgYWxsQ29sdW1uQ291bnQgPSAwO1xuICBwdWJsaWMgZXhwb3J0VmlzaWJsZU9ubHk6IGJvb2xlYW4gfCB1bmRlZmluZWQgPSBmYWxzZTtcblxuICBwdWJsaWMgZGF0YUNvbHVtbnM6IEFycmF5PE9lcGFUYWJsZUNvbHVtbj4gPSBbXTtcbiAgcHVibGljIGhpZGRlbkNvbHVtbnM6IEFycmF5PE9lcGFUYWJsZUNvbHVtbj4gPSBbXTtcbiAgcHVibGljIGNvbHVtbkhlYWRlcnM6IEFycmF5PHN0cmluZz4gPSBbXTtcbiAgcHVibGljIF9kYXRhOiBBcnJheTxPZXBhVGFibGVSb3c+ID0gW107XG4gIHByaXZhdGUgX2NvbmZpZzogT2VwYVRhYmxlQ29uZmlnID0ge307XG4gIHByaXZhdGUgY3VycmVudEZpbHRlcnM6IEFycmF5PE9lcGFUYWJsZUZpbHRlcj4gPSBbe1xuICAgIGZpbHRlclN0cmluZzogJycsXG4gICAgY29sdW1uSWQ6IHVuZGVmaW5lZFxuICB9XTtcblxuICBwdWJsaWMgZGF0YUhhc0RldGFpbHMgPSBmYWxzZTtcbiAgcHVibGljIHNob3dBbGxEZXRhaWxzID0gZmFsc2U7XG5cbiAgcHVibGljIGFsbFJvd3NTZWxlY3RlZCA9IGZhbHNlO1xuXG4gIHB1YmxpYyBwYWdlSW5mbzogT2VwYVRhYmxlUGFnZUluZm8gPSB7XG4gICAgcGFnZTogMSxcbiAgICBpdGVtc1BlclBhZ2U6IDEwLFxuICAgIG1heFNpemU6IDUsXG4gICAgbnVtUGFnZXM6IDEsXG4gICAgbGVuZ3RoOiAwXG4gIH07XG4gIHB1YmxpYyBjdXJyZW50UGFnZSA9IDE7XG4gIHB1YmxpYyBwYWdpbmF0aW9uT24gPSB0cnVlO1xuXG4gIEBJbnB1dCgpIHRhYmxlSWQgPSAnJztcblxuICBASW5wdXQoKVxuICBwdWJsaWMgc2V0IGNvbmZpZyhjb25mOiBPZXBhVGFibGVDb25maWcpIHtcbiAgICBpZiAoIWNvbmYuY2xhc3NOYW1lKSB7XG4gICAgICBjb25mLmNsYXNzTmFtZSA9ICd0YWJsZS1zdHJpcGVkIHRhYmxlLWJvcmRlcmVkJztcbiAgICB9XG4gICAgaWYgKGNvbmYuY2xhc3NOYW1lcykge1xuICAgICAgY29uZi5jbGFzc05hbWUgPSBjb25mLmNsYXNzTmFtZXMuam9pbignICcpO1xuICAgIH1cbiAgICBpZiAoY29uZi5yb3dzUGVyUGFnZSkge1xuICAgICAgdGhpcy5wYWdlSW5mby5pdGVtc1BlclBhZ2UgPSBjb25mLnJvd3NQZXJQYWdlO1xuICAgIH1cbiAgICB0aGlzLmV4cG9ydFZpc2libGVPbmx5ID0gY29uZi5leHBvcnRWaXNpYmxlT25seTtcbiAgICB0aGlzLl9jb25maWcgPSBjb25mO1xuICB9XG5cbiAgcHVibGljIGdldCBjb25maWcoKTogT2VwYVRhYmxlQ29uZmlnIHtcbiAgICByZXR1cm4gdGhpcy5fY29uZmlnO1xuICB9XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNldCBjb21wbGV4SGVhZGVyKGhkcnM6IEFycmF5PE9lcGFUYWJsZUhlYWRlcj4pIHtcbiAgICB0aGlzLnJlc2V0SGVhZGVycygpO1xuICAgIGlmIChoZHJzICYmIGhkcnMubGVuZ3RoKSB7XG4gICAgICBoZHJzLmZvckVhY2goKGhkcjogT2VwYVRhYmxlSGVhZGVyKSA9PiB7XG4gICAgICAgIHRoaXMuaGVhZGVyUm93cy5wdXNoKHRoaXMuZXh0cmFjdElubmVyQ29sdW1ucyhoZHIuY29sdW1ucykpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLmNvbHVtbkhlYWRlcnMgPSB0aGlzLmV4dHJhY3RDb2x1bW5IZWFkZXJzKHRoaXMuaGVhZGVyUm93cyk7XG4gICAgICB0aGlzLmRhdGFDb2x1bW5zID0gdGhpcy5leHRyYWN0RGF0YUNvbHVtbnModGhpcy5oZWFkZXJSb3dzKTtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZUhpZGRlbkNvbHVtbnModHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgQElucHV0KClcbiAgcHVibGljIHNldCBoZWFkZXIoaGRyOiBPZXBhVGFibGVIZWFkZXIpIHtcbiAgICB0aGlzLnJlc2V0SGVhZGVycygpO1xuICAgIGlmIChoZHIuY29sdW1ucyAmJiBoZHIuY29sdW1ucy5sZW5ndGggPiAwKSB7XG4gICAgICB0aGlzLmhlYWRlclJvd3MucHVzaCh0aGlzLmV4dHJhY3RJbm5lckNvbHVtbnMoaGRyLmNvbHVtbnMpKTtcbiAgICB9XG4gICAgdGhpcy5jb2x1bW5IZWFkZXJzID0gdGhpcy5leHRyYWN0Q29sdW1uSGVhZGVycyh0aGlzLmhlYWRlclJvd3MpO1xuICAgIHRoaXMuZGF0YUNvbHVtbnMgPSB0aGlzLmV4dHJhY3REYXRhQ29sdW1ucyh0aGlzLmhlYWRlclJvd3MpO1xuICAgIHRoaXMuaW5pdGlhbGl6ZUhpZGRlbkNvbHVtbnMoZmFsc2UpO1xuICB9XG5cbiAgQElucHV0KCkgY3VzdG9tQnRuTGFiZWw6IHN0cmluZyB8IHVuZGVmaW5lZCA9IHVuZGVmaW5lZDtcbiAgQElucHV0KCkgY3VzdG9tQnRuVmlzaWJsZSA9IGZhbHNlO1xuICBASW5wdXQoKSBjdXN0b21CdG5FbmFibGVkID0gZmFsc2U7XG5cbiAgLy8gT3V0cHV0cyAoRXZlbnRzKVxuICBAT3V0cHV0KCkgcHVibGljIGNlbGxDbGlja2VkOiBFdmVudEVtaXR0ZXI8T2VwYVRhYmxlQ2VsbENsaWNrRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcHVibGljIGFjdGlvbkNsaWNrZWQ6IEV2ZW50RW1pdHRlcjxPZXBhQWN0aW9uRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICBAT3V0cHV0KCkgcHVibGljIHJvd1NlbGVjdGVkOiBFdmVudEVtaXR0ZXI8QXJyYXk8T2VwYVRhYmxlUm93Pj4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gIEBPdXRwdXQoKSBwdWJsaWMgY3VzdG9tQnRuQ2xpY2tlZDogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuXG4gIHByaXZhdGUgcmVzZXRIZWFkZXJzKCkge1xuICAgIHRoaXMuaGVhZGVyUm93cyA9IFtdO1xuICAgIHRoaXMuY29sdW1uSGVhZGVycyA9IFtdO1xuICAgIHRoaXMuZGF0YUNvbHVtbnMgPSBbXTtcbiAgICB0aGlzLmhpZGRlbkNvbHVtbnMgPSBbXTtcbiAgfVxuXG4gIHByaXZhdGUgaW5pdGlhbGl6ZUhpZGRlbkNvbHVtbnMoY29tcGxleEhlYWRlcjogYm9vbGVhbikge1xuICAgIHRoaXMudmlzaWJsZUNvbHVtbkNvdW50ID0gMDtcbiAgICB0aGlzLmFsbENvbHVtbkNvdW50ID0gMDtcbiAgICB0aGlzLmRhdGFDb2x1bW5zLmZvckVhY2goKGNvbHVtbikgPT4ge1xuICAgICAgaWYgKGNvbXBsZXhIZWFkZXIgJiYgKGNvbHVtbj8uaGlkZGVuID09PSB0cnVlIHx8IGNvbHVtbj8uaGlkZGVuID09PSBmYWxzZSkpIHtcbiAgICAgICAgY29uc29sZS5lcnJvcignZGlzYWJsaW5nIGhpZGRlbiBhdHRyaWJ1dGUgZm9yIGNvbHVtbjogJyArIGNvbHVtbi5pZCArXG4gICAgICAgICAgJy4gSGlkZGVuIGNvbHVtbnMgYXJlIG5vdCBzdXBwb3J0ZWQgZm9yIGNvbXBsZXggaGVhZGVycyAoeWV0KS4nKTtcbiAgICAgICAgY29sdW1uLmhpZGRlbiA9IHVuZGVmaW5lZDtcbiAgICAgICAgdGhpcy52aXNpYmxlQ29sdW1uQ291bnQrKztcbiAgICAgIH0gZWxzZSBpZiAoY29sdW1uPy5oaWRkZW4gPT09IHRydWUpIHtcbiAgICAgICAgdGhpcy5oaWRkZW5Db2x1bW5zLnB1c2goY29sdW1uKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMudmlzaWJsZUNvbHVtbkNvdW50Kys7XG4gICAgICB9XG4gICAgICB0aGlzLmFsbENvbHVtbkNvdW50Kys7XG4gICAgfSk7XG4gICAgLy8gY29uc29sZS5sb2coJ3Zpc2libGVDb2x1bW5Db3VudCA9ICcgKyB0aGlzLnZpc2libGVDb2x1bW5Db3VudCk7XG4gIH1cblxuICBASW5wdXQoKVxuICBwdWJsaWMgc2V0IGRhdGEodmFsdWVzOiBBcnJheTxPZXBhVGFibGVSb3c+KSB7XG4gICAgaWYgKCF0aGlzLl9kYXRhIHx8IHRoaXMuX2RhdGEubGVuZ3RoID09PSAwKSB7XG4gICAgICB0aGlzLl9kYXRhID0gdGhpcy50YWJsZVNlcnZpY2UuZ2V0RGF0YSh0aGlzLnRhYmxlSWQpIHx8IFtdO1xuICAgIH1cbiAgICBpZiAodmFsdWVzKSB7XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHZhbHVlcy5sZW5ndGg7IGkrKykge1xuICAgICAgICB2YWx1ZXNbaV0ucHJpdmF0ZUlkID0gaTtcbiAgICAgIH1cbiAgICAgIGlmICh0aGlzLl9kYXRhICYmIHRoaXMuX2RhdGEubGVuZ3RoICE9PSB2YWx1ZXMubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMudGFibGVTZXJ2aWNlLmNsZWFyUGFnZUluZm8odGhpcy50YWJsZUlkKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl9kYXRhID0gdmFsdWVzO1xuICAgIHRoaXMudGFibGVTZXJ2aWNlLnNldERhdGEodGhpcy50YWJsZUlkLCB0aGlzLl9kYXRhKTtcbiAgICB0aGlzLnVwZGF0ZVRhYmxlKCk7XG4gIH1cblxuICBwdWJsaWMgZ2V0IGRhdGEoKTogQXJyYXk8T2VwYVRhYmxlUm93PiB7XG4gICAgcmV0dXJuIHRoaXMuX2RhdGEubWFwKHggPT4gT2JqZWN0LmFzc2lnbih7fSwgeCkpO1xuICB9XG5cbiAgQElucHV0KCkgdG90YWxSb3c6IE9lcGFUYWJsZVJvdyB8IHVuZGVmaW5lZDtcblxuICBwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSBzYW5pdGl6ZXI6IERvbVNhbml0aXplcixcbiAgICBwcml2YXRlIHRhYmxlU2VydmljZTogVGFibGVTZXJ2aWNlLFxuICAgIHByaXZhdGUgdGFibGVFeHBvcnRTZXJ2aWNlOiBUYWJsZUV4cG9ydFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBmaWxlVXRpbFNlcnZpY2U6IE9lcGFGaWxlVXRpbFNlcnZpY2UpIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMucGFnaW5hdGlvbk9uID0gIXRoaXMuX2NvbmZpZy5kaXNhYmxlUGFnaW5hdGlvbjtcbiAgfVxuXG4gIHByaXZhdGUgZXh0cmFjdElubmVyQ29sdW1ucyhpbm5lcjogQXJyYXk8T2VwYVRhYmxlQ29sdW1uPik6IE9lcGFUYWJsZUhlYWRlciB7XG4gICAgY29uc3QgaGVhZGVyOiBPZXBhVGFibGVIZWFkZXIgPSB7IGNvbHVtbnM6IFtdIH07XG4gICAgaW5uZXIuZm9yRWFjaCgodmFsdWU6IE9lcGFUYWJsZUNvbHVtbikgPT4ge1xuICAgICAgY29uc3QgY29sdW1uID0gaGVhZGVyLmNvbHVtbnMuZmluZCgoY29sOiBPZXBhVGFibGVDb2x1bW4pID0+IGNvbC5pZCA9PT0gdmFsdWUuaWQpO1xuICAgICAgaWYgKGNvbHVtbikge1xuICAgICAgICAvLyBvdmVyd3JpdGUgcmVwZWF0ZWQgY29sdW1uXG4gICAgICAgIE9iamVjdC5hc3NpZ24oY29sdW1uLCB2YWx1ZSk7XG4gICAgICB9XG4gICAgICBpZiAoIWNvbHVtbikge1xuICAgICAgICBoZWFkZXIuY29sdW1ucy5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gaGVhZGVyO1xuICB9XG5cbiAgcHJpdmF0ZSBleHRyYWN0Q29sdW1uSGVhZGVycyhoZWFkZXJSb3dzOiBBcnJheTxPZXBhVGFibGVIZWFkZXI+KTogQXJyYXk8c3RyaW5nPiB7XG4gICAgY29uc3QgaGVhZGVyczogQXJyYXk8c3RyaW5nPiA9IFtdO1xuICAgIGxldCByb3dJbmRleCA9IDA7XG4gICAgY29uc3QgY2hpbGRDb2x1bW5zOiBhbnkgPSB7fTtcbiAgICBoZWFkZXJSb3dzLmZvckVhY2goKGhkcjogT2VwYVRhYmxlSGVhZGVyKSA9PiB7XG4gICAgICBsZXQgY29sSW5kZXggPSAwO1xuICAgICAgaGRyLmNvbHVtbnMuZm9yRWFjaCgoY29sdW1uOiBPZXBhVGFibGVDb2x1bW4pID0+IHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ3Jvd0luZGV4PScgKyByb3dJbmRleCArICcsIGNvbEluZGV4PScgKyBjb2xJbmRleCArICcsIGNvbHVtbj0nICsgSlNPTi5zdHJpbmdpZnkoY29sdW1uKSk7XG4gICAgICAgIGlmIChyb3dJbmRleCA9PT0gMCkge1xuICAgICAgICAgIGhlYWRlcnMucHVzaChjb2x1bW4udGl0bGUpO1xuICAgICAgICAgIGlmIChjb2x1bW4uY29sc3Bhbikge1xuICAgICAgICAgICAgZm9yIChsZXQgY291bnQgPSAxOyBjb3VudCA8IGNvbHVtbi5jb2xzcGFuOyBjb3VudCsrKSB7XG4gICAgICAgICAgICAgIGhlYWRlcnMucHVzaCgnJyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICAgIGlmIChjb2x1bW4ucm93c3Bhbikge1xuICAgICAgICAgICAgY2hpbGRDb2x1bW5zW2NvbEluZGV4XSA9IGNvbHVtbi5yb3dzcGFuIC0gMTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgd2hpbGUgKGNoaWxkQ29sdW1uc1tjb2xJbmRleF0gJiYgY2hpbGRDb2x1bW5zW2NvbEluZGV4XSA+IDApIHtcbiAgICAgICAgICAgIGNoaWxkQ29sdW1uc1tjb2xJbmRleF0tLTtcbiAgICAgICAgICAgIGNvbEluZGV4Kys7XG4gICAgICAgICAgfVxuICAgICAgICAgIGhlYWRlcnNbY29sSW5kZXhdICs9ICcgJyArIGNvbHVtbi50aXRsZTtcbiAgICAgICAgICBpZiAoY29sdW1uLmNvbHNwYW4pIHtcbiAgICAgICAgICAgIGZvciAobGV0IGNvdW50ID0gMTsgY291bnQgPCBjb2x1bW4uY29sc3BhbjsgY291bnQrKykge1xuICAgICAgICAgICAgICBjb2xJbmRleCsrO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBjb2xJbmRleCsrO1xuICAgICAgfSk7XG4gICAgICByb3dJbmRleCsrO1xuICAgIH0pO1xuICAgIC8vIGNvbnNvbGUubG9nKCdoZWFkZXJzID0gJyArIEpTT04uc3RyaW5naWZ5KGhlYWRlcnMpKTtcbiAgICByZXR1cm4gaGVhZGVycztcbiAgfVxuXG5cbiAgcHJpdmF0ZSBleHRyYWN0RGF0YUNvbHVtbnMoaGVhZGVyUm93czogQXJyYXk8T2VwYVRhYmxlSGVhZGVyPik6IEFycmF5PE9lcGFUYWJsZUNvbHVtbj4ge1xuICAgIGNvbnN0IGRhdGFDb2x1bW5zOiBBcnJheTxPZXBhVGFibGVDb2x1bW4+ID0gW107XG4gICAgbGV0IHJvd0luZGV4ID0gMDtcbiAgICBjb25zdCBjaGlsZENvbHVtbnM6YW55ID0ge307XG4gICAgaGVhZGVyUm93cy5mb3JFYWNoKChoZHI6IE9lcGFUYWJsZUhlYWRlcikgPT4ge1xuICAgICAgbGV0IGNvbEluZGV4ID0gMDtcbiAgICAgIGhkci5jb2x1bW5zLmZvckVhY2goKGNvbHVtbjogT2VwYVRhYmxlQ29sdW1uKSA9PiB7XG4gICAgICAgIGlmIChyb3dJbmRleCA9PT0gMCkge1xuICAgICAgICAgIGlmIChjb2x1bW4uY29sc3BhbiAmJiBjb2x1bW4uY29sc3BhbiA+IDEpIHtcbiAgICAgICAgICAgIGZvciAobGV0IGNvdW50ID0gMDsgY291bnQgPCBjb2x1bW4uY29sc3BhbjsgY291bnQrKykge1xuICAgICAgICAgICAgICBkYXRhQ29sdW1ucy5wdXNoKHtcbiAgICAgICAgICAgICAgICBpZDogJycsXG4gICAgICAgICAgICAgICAgdGl0bGU6ICcnXG4gICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29sSW5kZXggKz0gKGNvbHVtbi5jb2xzcGFuIC0gMSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRhdGFDb2x1bW5zLnB1c2goY29sdW1uKTtcbiAgICAgICAgICAgIGlmIChjb2x1bW4ucm93c3Bhbikge1xuICAgICAgICAgICAgICBjaGlsZENvbHVtbnNbY29sSW5kZXhdID0gY29sdW1uLnJvd3NwYW4gLSAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB3aGlsZSAoY2hpbGRDb2x1bW5zW2NvbEluZGV4XSAmJiBjaGlsZENvbHVtbnNbY29sSW5kZXhdID4gMCkge1xuICAgICAgICAgICAgY2hpbGRDb2x1bW5zW2NvbEluZGV4XS0tO1xuICAgICAgICAgICAgY29sSW5kZXgrKztcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKGNvbHVtbi5jb2xzcGFuICYmIGNvbHVtbi5jb2xzcGFuID4gMSkge1xuICAgICAgICAgICAgY29sSW5kZXggKz0gKGNvbHVtbi5jb2xzcGFuIC0gMSk7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIGRhdGFDb2x1bW5zW2NvbEluZGV4XSA9IGNvbHVtbjtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgY29sSW5kZXgrKztcbiAgICAgIH0pO1xuICAgICAgcm93SW5kZXgrKztcbiAgICB9KTtcbiAgICAvLyBjb25zb2xlLmxvZygnZGF0YUNvbHVtbnMgPSAnICsgSlNPTi5zdHJpbmdpZnkoZGF0YUNvbHVtbnMpKTtcbiAgICByZXR1cm4gZGF0YUNvbHVtbnM7XG4gIH1cblxuICBwdWJsaWMgc2FuaXRpemUoaHRtbDogc3RyaW5nKTogU2FmZUh0bWwge1xuICAgIHJldHVybiB0aGlzLnNhbml0aXplci5ieXBhc3NTZWN1cml0eVRydXN0SHRtbChodG1sKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBDaGVjayB0byBzZWUgaWYgYW55IGZpbHRlcnMgYXJlIHNldFxuICAgKi9cbiAgcHVibGljIG5vRmlsdGVycygpOiBib29sZWFuIHtcbiAgICBsZXQgbm9GaWx0ZXJzID0gdHJ1ZTtcbiAgICB0aGlzLmN1cnJlbnRGaWx0ZXJzLmZvckVhY2goZmlsdGVyID0+IHtcbiAgICAgIGlmIChmaWx0ZXIuZmlsdGVyU3RyaW5nICYmIGZpbHRlci5maWx0ZXJTdHJpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICBub0ZpbHRlcnMgPSBmYWxzZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gbm9GaWx0ZXJzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJldHJpZXZlIHRoZSBnbG9iYWwgZmlsdGVyIHN0cmluZyAoaWYgYW55KSBhcyBhIFJlZ0V4cFxuICAgKi9cbiAgcHJpdmF0ZSBnZXRHbG9iYWxGaWx0ZXIoKTogUmVnRXhwIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgcmVnRXhwOiBSZWdFeHAgfCB1bmRlZmluZWQ7XG4gICAgdGhpcy5jdXJyZW50RmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgICBpZiAoIWZpbHRlci5jb2x1bW5JZCAmJiBmaWx0ZXIuZmlsdGVyU3RyaW5nICYmIGZpbHRlci5maWx0ZXJTdHJpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICByZWdFeHAgPSBuZXcgUmVnRXhwKGZpbHRlci5maWx0ZXJTdHJpbmcsICdpJyk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlZ0V4cDtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgZmlsdGVyIGZvciB0aGUgc3BlY2lmaWVkIGNvbHVtbiAoaWYgYW55KSBhcyBhIFJlZ0V4cC5cbiAgICogQHBhcmFtIGNvbHVtbklkXG4gICAqL1xuICBwcml2YXRlIGdldEZpbHRlckZvckNvbHVtbihjb2x1bW5JZDogc3RyaW5nKTogUmVnRXhwIHwgdW5kZWZpbmVkIHtcbiAgICBsZXQgcmVnRXhwOiBSZWdFeHAgfCB1bmRlZmluZWQ7XG4gICAgdGhpcy5jdXJyZW50RmlsdGVycy5mb3JFYWNoKGZpbHRlciA9PiB7XG4gICAgICBpZiAoZmlsdGVyLmNvbHVtbklkID09PSBjb2x1bW5JZCAmJiBmaWx0ZXIuZmlsdGVyU3RyaW5nICYmIGZpbHRlci5maWx0ZXJTdHJpbmcubGVuZ3RoID4gMCkge1xuICAgICAgICByZWdFeHAgPSBuZXcgUmVnRXhwKGZpbHRlci5maWx0ZXJTdHJpbmcsICdpJyk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlZ0V4cDtcbiAgfVxuXG4gIC8qKlxuICAgKiBGaWx0ZXIgdGhlIHRhYmxlIGRhdGEgcHJvdmlkZWQgYnkgdGhlIGdsb2JhbCBvciBjb2x1bW4tc3BlY2lmaWNcbiAgICogZmlsdGVycyBzZXQgaW4gdGhlIFVJLlxuICAgKiBAcGFyYW0gZGF0YVxuICAgKi9cbiAgcHJpdmF0ZSBmaWx0ZXJEYXRhKGRhdGE6IEFycmF5PE9lcGFUYWJsZVJvdz4pOiBBcnJheTxPZXBhVGFibGVSb3c+IHtcbiAgICAvLyBkb24ndCBhdHRlbXB0IGZpbHRlcmluZyBpZiB0aGVyZSBhcmUgbm8gZmlsdGVycyBzZXRcbiAgICBpZiAodGhpcy5ub0ZpbHRlcnMoKSkge1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIGxldCBmaWx0ZXJlZERhdGE6IEFycmF5PE9lcGFUYWJsZVJvdz4gPSBkYXRhO1xuICAgIGNvbnN0IHRlbXBBcnJheTogQXJyYXk8T2VwYVRhYmxlUm93PiA9IFtdO1xuICAgIGZpbHRlcmVkRGF0YS5mb3JFYWNoKChyb3c6IE9lcGFUYWJsZVJvdykgPT4ge1xuICAgICAgbGV0IGZsYWcgPSB0aGlzLmZpbHRlckJ5Q29sdW1uRmlsdGVycyhyb3cpO1xuICAgICAgaWYgKGZsYWcpIHtcbiAgICAgICAgZmxhZyA9IHRoaXMuZmlsdGVyQnlHbG9iYWxGaWx0ZXIocm93KTtcbiAgICAgIH1cbiAgICAgIGlmIChmbGFnIHx8IHJvdy5pc0RpdmlkZXIpIHtcbiAgICAgICAgdGVtcEFycmF5LnB1c2gocm93KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBmaWx0ZXJlZERhdGEgPSB0ZW1wQXJyYXk7XG4gICAgcmV0dXJuIGZpbHRlcmVkRGF0YTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUZXN0IGlmIHJvdyBtYXRjaGVzIGFueSBvZiB0aGUgY29sdW1ubiBmaWx0ZXJzIHRoYXQgbWF5IGJlIHNldC5cbiAgICogQHBhcmFtIHJvd1xuICAgKi9cbiAgcHJpdmF0ZSBmaWx0ZXJCeUNvbHVtbkZpbHRlcnMocm93OiBPZXBhVGFibGVSb3cpOiBib29sZWFuIHtcbiAgICBsZXQgZmxhZyA9IHRydWU7XG4gICAgcm93LmNlbGxzLmZvckVhY2goKGNlbGw6IE9lcGFUYWJsZUNlbGwpID0+IHtcbiAgICAgIGNvbnN0IHJlZ0V4cCA9IHRoaXMuZ2V0RmlsdGVyRm9yQ29sdW1uKGNlbGwuaWQpO1xuICAgICAgY29uc3QgZmlsdGVyVmFsdWUgPSBjZWxsLmZpbHRlclZhbHVlIHx8IGNlbGwudmFsdWUgfHwgJyc7XG4gICAgICBpZiAocmVnRXhwICYmIGZpbHRlclZhbHVlICE9PSB1bmRlZmluZWQgJiYgZmlsdGVyVmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gZmlsdGVyVmFsdWUudG9TdHJpbmcoKS5tYXRjaChyZWdFeHApO1xuICAgICAgICBmbGFnID0gZmxhZyAmJiAocmVzdWx0ICE9PSBudWxsKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZmxhZztcbiAgfVxuXG4gIC8qKlxuICAgKiBUZXN0IGlmIHJvdyBtYXRjaGVzIHRoZSBnbG9iYWwgZmlsdGVyXG4gICAqIEBwYXJhbSByb3dcbiAgICovXG4gIHByaXZhdGUgZmlsdGVyQnlHbG9iYWxGaWx0ZXIocm93OiBPZXBhVGFibGVSb3cpOiBib29sZWFuIHtcbiAgICBsZXQgZmxhZyA9IHRydWU7XG4gICAgY29uc3QgcmVnRXhwID0gdGhpcy5nZXRHbG9iYWxGaWx0ZXIoKTtcbiAgICBpZiAocmVnRXhwKSB7XG4gICAgICBmbGFnID0gZmFsc2U7XG4gICAgICByb3cuY2VsbHMuZm9yRWFjaCgoY2VsbDogT2VwYVRhYmxlQ2VsbCkgPT4ge1xuICAgICAgICBjb25zdCBmaWx0ZXJWYWx1ZSA9IGNlbGwuZmlsdGVyVmFsdWUgfHwgY2VsbC52YWx1ZTtcbiAgICAgICAgaWYgKGZpbHRlclZhbHVlICE9PSB1bmRlZmluZWQgJiYgZmlsdGVyVmFsdWUgIT09IG51bGwpIHtcbiAgICAgICAgICBjb25zdCByZXN1bHQgPSBmaWx0ZXJWYWx1ZS50b1N0cmluZygpLm1hdGNoKHJlZ0V4cCk7XG4gICAgICAgICAgZmxhZyA9IGZsYWcgfHwgKHJlc3VsdCAhPT0gbnVsbCk7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gZmxhZztcbiAgfVxuXG4gIHB1YmxpYyBoaWRlQ29sdW1uKGNvbHVtbjogT2VwYVRhYmxlQ29sdW1uKSB7XG4gICAgdGhpcy5oaWRkZW5Db2x1bW5zLnB1c2goY29sdW1uKTtcbiAgICBjb2x1bW4uaGlkZGVuID0gdHJ1ZTtcbiAgICB0aGlzLnZpc2libGVDb2x1bW5Db3VudC0tO1xuICB9XG5cbiAgcHVibGljIHVuaGlkZUNvbHVtbihjb2x1bW5JZDogc3RyaW5nKSB7XG4gICAgY29uc3QgaGlkZGVuQ29sczogQXJyYXk8T2VwYVRhYmxlQ29sdW1uPiA9IFtdO1xuICAgIHRoaXMuaGlkZGVuQ29sdW1ucy5mb3JFYWNoKChjb2wpID0+IHtcbiAgICAgIGlmIChjb2wuaWQgIT09IGNvbHVtbklkKSB7XG4gICAgICAgIGhpZGRlbkNvbHMucHVzaChjb2wpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29sLmhpZGRlbiA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHRoaXMuaGlkZGVuQ29sdW1ucyA9IGhpZGRlbkNvbHM7XG4gICAgdGhpcy52aXNpYmxlQ29sdW1uQ291bnQrKztcbiAgfVxuXG4gIHByaXZhdGUgc29ydERhdGEoZGF0YTogQXJyYXk8T2VwYVRhYmxlUm93Pik6IEFycmF5PE9lcGFUYWJsZVJvdz4ge1xuICAgIGxldCBzb3J0Q3JpdGVyaWE6IGFueSA9IHRoaXMudGFibGVTZXJ2aWNlLmdldFNvcnRDcml0ZXJpYSh0aGlzLnRhYmxlSWQpIHx8IFtdO1xuICAgIGlmIChzb3J0Q3JpdGVyaWEubGVuZ3RoID09IDApIHtcbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cblxuICAgIHRoaXMucmVzZXRDb2x1bW5Tb3J0SW5kZXhlcyhzb3J0Q3JpdGVyaWEpO1xuXG4gICAgcmV0dXJuIGRhdGEuc29ydCgocHJldmlvdXM6IE9lcGFUYWJsZVJvdywgY3VycmVudDogT2VwYVRhYmxlUm93KSA9PiB7XG4gICAgICBsZXQgc29ydEluZGV4ID0gMDtcbiAgICAgIGxldCBzb3J0UmVzdWx0ID0gMDtcbiAgICAgIHdoaWxlIChzb3J0SW5kZXggPCBzb3J0Q3JpdGVyaWEubGVuZ3RoICYmIHNvcnRSZXN1bHQgPT09IDApIHtcbiAgICAgICAgbGV0IHByZXYgPSB0aGlzLmdldFJvd1NvcnRWYWx1ZShwcmV2aW91cywgc29ydENyaXRlcmlhW3NvcnRJbmRleF0uY29sdW1uSWQpO1xuICAgICAgICBsZXQgY3VyciA9IHRoaXMuZ2V0Um93U29ydFZhbHVlKGN1cnJlbnQsIHNvcnRDcml0ZXJpYVtzb3J0SW5kZXhdLmNvbHVtbklkKTtcbiAgICAgICAgaWYgKHByZXYgPiBjdXJyKSB7XG4gICAgICAgICAgc29ydFJlc3VsdCA9ICAoc29ydENyaXRlcmlhW3NvcnRJbmRleF0uc29ydCA9PT0gJ2Rlc2MnID8gLTEgOiAxKTtcbiAgICAgICAgfSBlbHNlIGlmIChwcmV2IDwgY3Vycikge1xuICAgICAgICAgIHNvcnRSZXN1bHQgPSAgKHNvcnRDcml0ZXJpYVtzb3J0SW5kZXhdLnNvcnQgPT09ICdhc2MnID8gLTEgOiAxKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBzb3J0UmVzdWx0ID0gMDtcbiAgICAgICAgfVxuICAgICAgICBzb3J0SW5kZXgrKztcbiAgICAgIH1cbiAgICAgIHJldHVybiBzb3J0UmVzdWx0O1xuICAgIH0pO1xuICB9XG5cbiAgcHVibGljIHJlc2V0Q29sdW1uU29ydEluZGV4ZXMoc29ydENyaXRlcmlhOiBPZXBhVGFibGVTb3J0Q3JpdGVyaW9uW10pIHtcbiAgICBpZiAoc29ydENyaXRlcmlhICYmIHNvcnRDcml0ZXJpYS5sZW5ndGggPiAwKSB7XG4gICAgICBmb3IgKGxldCBpPTA7IGk8c29ydENyaXRlcmlhLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgIHRoaXMuZGF0YUNvbHVtbnMuZm9yRWFjaChjb2x1bW4gPT4ge1xuICAgICAgICAgIGlmIChjb2x1bW4/LmlkID09PSBzb3J0Q3JpdGVyaWFbaV0uY29sdW1uSWQpIHtcbiAgICAgICAgICAgIGlmIChjb2x1bW4pIHtcbiAgICAgICAgICAgICAgY29sdW1uLnNvcnRJbmRleCA9IGkgKyAxO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgICB9O1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBSZXRyaWV2ZSB0aGUgZGlzcGxheSB2YWx1ZSBvZiB0aGUgc3BlY2lmaWVkIGNlbGwuXG4gICAqIEBwYXJhbSByb3dcbiAgICogQHBhcmFtIGNvbHVtbklkXG4gICAqL1xuICBwdWJsaWMgZ2V0Um93VmFsdWUocm93OiBPZXBhVGFibGVSb3csIGNvbHVtbklkOiBzdHJpbmcpOiBhbnkge1xuICAgIGxldCB2YWx1ZTogYW55O1xuICAgIHJvdy5jZWxscy5mb3JFYWNoKChjZWxsOiBPZXBhVGFibGVDZWxsKSA9PiB7XG4gICAgICBpZiAoY2VsbC5pZCA9PT0gY29sdW1uSWQpIHtcbiAgICAgICAgdmFsdWUgPSBjZWxsLnZhbHVlO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiB2YWx1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKlxuICAgKiBAcGFyYW0gcm93IFJldHJpZXZlIHRoZSBzb3J0IHZhbHVlIG9mIHRoZSBzcGVjaWZpZWQgY2VsbCAod2lsbCBkZWZhdWx0IHRvIGRpc3BsYXkgdmFsdWUgaWYgc29ydFxuICAgKiB2YWx1ZSBpcyBub3Qgc3BlY2lmaWVkKS5cbiAgICogQHBhcmFtIGNvbHVtbklkXG4gICAqL1xuICBwdWJsaWMgZ2V0Um93U29ydFZhbHVlKHJvdzogT2VwYVRhYmxlUm93LCBjb2x1bW5JZDogc3RyaW5nKTogYW55IHtcbiAgICBsZXQgdmFsdWU6IGFueTtcbiAgICByb3cuY2VsbHMuZm9yRWFjaCgoY2VsbDogT2VwYVRhYmxlQ2VsbCkgPT4ge1xuICAgICAgaWYgKGNlbGwuaWQgPT09IGNvbHVtbklkKSB7XG4gICAgICAgIGlmIChjZWxsLnNvcnRWYWx1ZSAhPT0gdW5kZWZpbmVkICYmIGNlbGwuc29ydFZhbHVlICE9PSBudWxsKSB7XG4gICAgICAgICAgdmFsdWUgPSBjZWxsLnNvcnRWYWx1ZTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB2YWx1ZSA9IGNlbGwudmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcbiAgICBpZiAodHlwZW9mIHZhbHVlID09PSAnc3RyaW5nJykge1xuICAgICAgdmFsdWUgPSB2YWx1ZS50b1VwcGVyQ2FzZSgpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWU7XG4gIH1cblxuICBwdWJsaWMgY2hhbmdlUGFnZShkYXRhOiBBcnJheTxPZXBhVGFibGVSb3c+ID0gdGhpcy5kYXRhKTogQXJyYXk8T2VwYVRhYmxlUm93PiB7XG4gICAgaWYgKCF0aGlzLnBhZ2luYXRpb25Pbikge1xuICAgICAgcmV0dXJuIGRhdGE7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlUGFnZSgpO1xuICAgIGNvbnN0IHN0YXJ0ID0gKHRoaXMucGFnZUluZm8ucGFnZSAtIDEpICogdGhpcy5wYWdlSW5mby5pdGVtc1BlclBhZ2U7XG4gICAgY29uc3QgZW5kID0gdGhpcy5wYWdlSW5mby5pdGVtc1BlclBhZ2UgPiAtMSA/IChzdGFydCArIHRoaXMucGFnZUluZm8uaXRlbXNQZXJQYWdlKSA6IGRhdGEubGVuZ3RoO1xuICAgIC8vIG5vdCBzdXJlIHdoeSwgYnV0IG1heFNpemUgd2FzIGdldHRpbmcgbG9zdC4gUmVzZXQgaXQgaGVyZSB0byBwcmV2ZW50IHdlaXJkbmVzcy5cbiAgICB0aGlzLnBhZ2VJbmZvLm1heFNpemUgPSA1O1xuICAgIHJldHVybiBkYXRhLnNsaWNlKHN0YXJ0LCBlbmQpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZVBhZ2luZ2F0aW9uKCkge1xuICAgIHRoaXMucGFnaW5hdGlvbk9uID0gIXRoaXMucGFnaW5hdGlvbk9uO1xuICAgIHRoaXMudXBkYXRlVGFibGUoKTtcbiAgfVxuXG4gIHB1YmxpYyBvbkZpbHRlckNoYW5nZWQoZmlsdGVyOiBPZXBhVGFibGVGaWx0ZXIpIHtcbiAgICBjb25zdCBtYXRjaEZpbHRlciA9IHRoaXMuY3VycmVudEZpbHRlcnMuZmluZCgoZikgPT4ge1xuICAgICAgcmV0dXJuIGYuY29sdW1uSWQgPT09IGZpbHRlci5jb2x1bW5JZDtcbiAgICB9KTtcbiAgICBpZiAoIW1hdGNoRmlsdGVyKSB7XG4gICAgICB0aGlzLmN1cnJlbnRGaWx0ZXJzLnB1c2goZmlsdGVyKTtcbiAgICB9IGVsc2Uge1xuICAgICAgbWF0Y2hGaWx0ZXIuZmlsdGVyU3RyaW5nID0gZmlsdGVyLmZpbHRlclN0cmluZztcbiAgICB9XG4gICAgdGhpcy51cGRhdGVUYWJsZSgpO1xuICB9XG5cbiAgcHVibGljIG9uU29ydENoYW5nZWQoY29sdW1uOiBPZXBhVGFibGVDb2x1bW4pIHtcbiAgICB0aGlzLnRhYmxlU2VydmljZS5zZXRTb3J0KHRoaXMudGFibGVJZCwgY29sdW1uKTtcbiAgICB0aGlzLnVwZGF0ZVRhYmxlKCk7XG4gIH1cblxuICBwdWJsaWMgb25QYWdlQ2hhbmdlZChwYWdlRXZlbnQ6IFBhZ2VDaGFuZ2VkRXZlbnQpIHtcbiAgICB0aGlzLnBhZ2VJbmZvID0ge1xuICAgICAgcGFnZTogcGFnZUV2ZW50LnBhZ2UsXG4gICAgICBpdGVtc1BlclBhZ2U6IHBhZ2VFdmVudC5pdGVtc1BlclBhZ2UsXG4gICAgICBtYXhTaXplOiB0aGlzLnBhZ2VJbmZvLm1heFNpemUsXG4gICAgICBsZW5ndGg6IHRoaXMucGFnZUluZm8ubGVuZ3RoLFxuICAgICAgbnVtUGFnZXM6IHRoaXMucGFnZUluZm8ubnVtUGFnZXNcbiAgICB9XG4gICAgdGhpcy50YWJsZVNlcnZpY2Uuc2V0UGFnZSh0aGlzLnRhYmxlSWQsIHBhZ2VFdmVudC5wYWdlKTtcbiAgICB0aGlzLnVwZGF0ZVRhYmxlKCk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVRhYmxlKCkge1xuICAgIGNvbnN0IGZpbHRlcmVkRGF0YSA9IHRoaXMuZmlsdGVyRGF0YSh0aGlzLmRhdGEpO1xuICAgIGNvbnN0IHNvcnRlZERhdGEgPSB0aGlzLnNvcnREYXRhKGZpbHRlcmVkRGF0YSk7XG4gICAgdGhpcy5yb3dzID0gdGhpcy5jaGFuZ2VQYWdlKHNvcnRlZERhdGEpO1xuICAgIHRoaXMucGFnZUluZm8ubGVuZ3RoID0gc29ydGVkRGF0YS5sZW5ndGg7XG4gICAgdGhpcy5kYXRhSGFzRGV0YWlscyA9IHRoaXMuY2hlY2tGb3JEZXRhaWxzKHRoaXMucm93cyk7XG4gIH1cblxuICBwcml2YXRlIHVwZGF0ZVBhZ2UoKSB7XG4gICAgY29uc3Qgc2F2ZWRQYWdlTnVtYmVyID0gdGhpcy50YWJsZVNlcnZpY2UuZ2V0UGFnZSh0aGlzLnRhYmxlSWQpO1xuICAgIGlmIChzYXZlZFBhZ2VOdW1iZXIgJiYgdGhpcy5wYWdlSW5mby5wYWdlICE9PSBzYXZlZFBhZ2VOdW1iZXIpIHtcbiAgICAgIHRoaXMucGFnZUluZm8ucGFnZSA9IHNhdmVkUGFnZU51bWJlcjtcbiAgICAgIHRoaXMuY3VycmVudFBhZ2UgPSB0aGlzLnBhZ2VJbmZvLnBhZ2U7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBjaGVja0ZvckRldGFpbHMoZGF0YTogQXJyYXk8T2VwYVRhYmxlUm93Pik6IGJvb2xlYW4ge1xuICAgIGxldCBoYXNEZXRhaWxzID0gZmFsc2U7XG4gICAgaWYgKGRhdGEgJiYgZGF0YS5sZW5ndGgpIHtcbiAgICAgIGRhdGEuZm9yRWFjaCgocm93OiBPZXBhVGFibGVSb3cpID0+IHtcbiAgICAgICAgaWYgKHJvdy5zaG93RGV0YWlsID09PSB0cnVlIHx8IHJvdy5zaG93RGV0YWlsID09PSBmYWxzZSkge1xuICAgICAgICAgIGhhc0RldGFpbHMgPSB0cnVlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIGhhc0RldGFpbHM7XG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlQWxsRGV0YWlscygpIHtcbiAgICAvLyBjb25zb2xlLmxvZygndG9nZ2xlQWxsRGV0YWlscy4uLicpO1xuICAgIHRoaXMuc2hvd0FsbERldGFpbHMgPSAhdGhpcy5zaG93QWxsRGV0YWlscztcbiAgICAvLyBjb25zb2xlLmxvZygnc2hvd0FsbERldGFpbHMgPSAnICsgdGhpcy5zaG93QWxsRGV0YWlscyk7XG4gICAgaWYgKHRoaXMuX2RhdGEgJiYgdGhpcy5fZGF0YS5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX2RhdGEuZm9yRWFjaCgocm93OiBPZXBhVGFibGVSb3cpID0+IHtcbiAgICAgICAgaWYgKHJvdy5zaG93RGV0YWlsICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByb3cuc2hvd0RldGFpbCA9IHRoaXMuc2hvd0FsbERldGFpbHM7XG4gICAgICAgICAgLy8gY29uc29sZS5sb2coJ3NldHRpbmcgZGV0YWlscyBmb3Igcm93IHRvICcgKyB0aGlzLnNob3dBbGxEZXRhaWxzKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICAgIHRoaXMudXBkYXRlVGFibGUoKTtcbiAgfVxuXG4gIHB1YmxpYyB0b2dnbGVSb3dEZXRhaWwodG9nZ2xlUm93OiBPZXBhVGFibGVSb3cpIHtcbiAgICBpZiAodG9nZ2xlUm93ICYmIHRoaXMuX2RhdGEgJiYgdGhpcy5fZGF0YS5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX2RhdGEuZm9yRWFjaCgocm93OiBPZXBhVGFibGVSb3cpID0+IHtcbiAgICAgICAgLy8gY29uc29sZS5sb2coJ1RFU1Q6ICcgKyBKU09OLnN0cmluZ2lmeShyb3cuZGF0YVNvdXJjZSkgKyAnID09PSAnICsgSlNPTi5zdHJpbmdpZnkodG9nZ2xlUm93LmRhdGFTb3VyY2UpKTtcbiAgICAgICAgaWYgKHJvdy5kYXRhU291cmNlID09PSB0b2dnbGVSb3cuZGF0YVNvdXJjZSkge1xuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCchISEgTUFUQ0ggISEhJyk7XG4gICAgICAgICAgcm93LnNob3dEZXRhaWwgPSAhdG9nZ2xlUm93LnNob3dEZXRhaWw7XG4gICAgICAgICAgdG9nZ2xlUm93LnNob3dEZXRhaWwgPSByb3cuc2hvd0RldGFpbDtcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZygnc2hvdyBkZXRhaWwgPSAnICsgcm93LnNob3dEZXRhaWwgKyAnIGZvciByb3c6ICcgKyBKU09OLnN0cmluZ2lmeShyb3cuZGF0YVNvdXJjZSkpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIC8vIHRoaXMuX2RhdGEgPSB0aGlzLl9kYXRhLnNwbGljZSgwKTtcbiAgICB9XG4gICAgLy8gY29uc29sZS5sb2coJ3RvZ2dsZVJvd0RldGFpbC4uLicpO1xuICAgIC8vIHRoaXMuZHVtcERldGFpbFJvd3MoKTtcbiAgfVxuXG4gIHB1YmxpYyBpc0FjdGlvbkNvbHVtbihjb2x1bW5JZDogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgLy8gY29uc29sZS5sb2coJ2lzQWN0aW9uQ29sdW1uICcgKyBjb2x1bW5JZCk7XG4gICAgbGV0IGFjdGlvbkNvbHVtbiA9IGZhbHNlO1xuICAgIHRoaXMuaGVhZGVyUm93cy5mb3JFYWNoKChoZHI6IE9lcGFUYWJsZUhlYWRlcikgPT4ge1xuICAgICAgaGRyLmNvbHVtbnMuZm9yRWFjaCgoY29sdW1uOiBPZXBhVGFibGVDb2x1bW4pID0+IHtcbiAgICAgICAgaWYgKGNvbHVtbi5pZCA9PT0gY29sdW1uSWQpIHtcbiAgICAgICAgICAvLyBjb25zb2xlLmxvZygndGVzdCBhY3Rpb24gY29sdW1uOiAnICsgY29sdW1uLmlkICsgJyAtICcgKyBjb2x1bW4uYWN0aW9uQ29sdW1uKTtcbiAgICAgICAgICBhY3Rpb25Db2x1bW4gPSBjb2x1bW4uYWN0aW9uQ29sdW1uIHx8IGZhbHNlO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gYWN0aW9uQ29sdW1uO1xuICB9XG5cbiAgcHVibGljIGlzQ29sdW1uSGlkZGVuKGNvbHVtbklkOiBzdHJpbmcpOiBib29sZWFuIHtcbiAgICAvLyBjb25zb2xlLmxvZygnaXNDb2x1bW5IaWRkZW4gJyArIGNvbHVtbklkKTtcbiAgICBsZXQgaGlkZGVuID0gZmFsc2U7XG4gICAgdGhpcy5oZWFkZXJSb3dzLmZvckVhY2goKGhkcjogT2VwYVRhYmxlSGVhZGVyKSA9PiB7XG4gICAgICBoZHIuY29sdW1ucy5mb3JFYWNoKChjb2x1bW46IE9lcGFUYWJsZUNvbHVtbikgPT4ge1xuICAgICAgICBpZiAoY29sdW1uLmlkID09PSBjb2x1bW5JZCkge1xuICAgICAgICAgIC8vIGNvbnNvbGUubG9nKCd0ZXN0IGhpZGRlbiBjb2x1bW46ICcgKyBjb2x1bW4uaWQgKyAnIC0gJyArIGNvbHVtbi5oaWRkZW4pO1xuICAgICAgICAgIGhpZGRlbiA9IGNvbHVtbi5oaWRkZW4gfHwgZmFsc2U7XG4gICAgICAgIH1cbiAgICAgIH0pO1xuICAgIH0pO1xuICAgIHJldHVybiBoaWRkZW47XG4gIH1cblxuICBwdWJsaWMgZ2V0SGlkZGVuQ29sdW1ucygpOiBBcnJheTxPZXBhVGFibGVDb2x1bW4+IHtcbiAgICBjb25zdCBjb2x1bW5zOiBBcnJheTxPZXBhVGFibGVDb2x1bW4+ID0gW107XG4gICAgdGhpcy5oZWFkZXJSb3dzLmZvckVhY2goKGhkcjogT2VwYVRhYmxlSGVhZGVyKSA9PiB7XG4gICAgICBoZHIuY29sdW1ucy5mb3JFYWNoKChjb2x1bW46IE9lcGFUYWJsZUNvbHVtbikgPT4ge1xuICAgICAgICBpZiAoY29sdW1uLmhpZGRlbikge1xuICAgICAgICAgIGNvbHVtbnMucHVzaChjb2x1bW4pO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgICByZXR1cm4gY29sdW1ucztcbiAgfVxuXG4gIHB1YmxpYyBnZXRDZWxsQ2xhc3NOYW1lKHJvdzogT2VwYVRhYmxlUm93LCBjb2x1bW5JZDogc3RyaW5nKTogc3RyaW5nIHtcbiAgICBsZXQgcmVzdWx0OiBzdHJpbmcgfCB1bmRlZmluZWQgPSAnJztcbiAgICByb3cuY2VsbHMuZm9yRWFjaCgoY2VsbDogT2VwYVRhYmxlQ2VsbCkgPT4ge1xuICAgICAgaWYgKGNlbGwuaWQgPT09IGNvbHVtbklkKSB7XG4gICAgICAgIHJlc3VsdCA9IGNlbGwuY2xhc3NOYW1lO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2VsbENvbFNwYW4ocm93OiBPZXBhVGFibGVSb3csIGNvbHVtbklkOiBzdHJpbmcpOiBudW1iZXIge1xuICAgIGxldCByZXN1bHQ6IG51bWJlciB8IHVuZGVmaW5lZCA9IDE7XG4gICAgcm93LmNlbGxzLmZvckVhY2goKGNlbGw6IE9lcGFUYWJsZUNlbGwpID0+IHtcbiAgICAgIGlmIChjZWxsLmlkID09PSBjb2x1bW5JZCkge1xuICAgICAgICByZXN1bHQgPSBjZWxsLmNvbFNwYW4gfHwgMCA+PTAgPyBjZWxsLmNvbFNwYW4gOiAxO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2VsbEljb25DbGFzc05hbWUocm93OiBPZXBhVGFibGVSb3csIGNvbHVtbklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCByZXN1bHQ6IHN0cmluZyB8IHVuZGVmaW5lZCA9ICcnO1xuICAgIHJvdy5jZWxscy5mb3JFYWNoKChjZWxsOiBPZXBhVGFibGVDZWxsKSA9PiB7XG4gICAgICBpZiAoY2VsbC5pZCA9PT0gY29sdW1uSWQpIHtcbiAgICAgICAgcmVzdWx0ID0gY2VsbC5pY29uQ2xhc3NOYW1lO1xuICAgICAgfVxuICAgIH0pO1xuICAgIHJldHVybiByZXN1bHQ7XG4gIH1cblxuICBwdWJsaWMgZ2V0Q2VsbEltZ1NyYyhyb3c6IE9lcGFUYWJsZVJvdywgY29sdW1uSWQ6IHN0cmluZyk6IHN0cmluZyB7XG4gICAgbGV0IHJlc3VsdDogc3RyaW5nIHwgdW5kZWZpbmVkID0gJyc7XG4gICAgcm93LmNlbGxzLmZvckVhY2goKGNlbGw6IE9lcGFUYWJsZUNlbGwpID0+IHtcbiAgICAgIGlmIChjZWxsLmlkID09PSBjb2x1bW5JZCkge1xuICAgICAgICByZXN1bHQgPSBjZWxsLmltZ1NyYztcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHVibGljIGdldENlbGxJbm5lckhUTUwocm93OiBPZXBhVGFibGVSb3csIGNvbHVtbklkOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIGxldCByZXN1bHQ6IHN0cmluZyB8IHVuZGVmaW5lZCA9ICcnO1xuICAgIHJvdy5jZWxscy5mb3JFYWNoKChjZWxsOiBPZXBhVGFibGVDZWxsKSA9PiB7XG4gICAgICBpZiAoY2VsbC5pZCA9PT0gY29sdW1uSWQpIHtcbiAgICAgICAgcmVzdWx0ID0gY2VsbC5pbm5lckhUTUw7XG4gICAgICB9XG4gICAgfSk7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHB1YmxpYyBjZWxsQ2xpY2socm93OiBPZXBhVGFibGVSb3csIGNvbHVtbklkOiBzdHJpbmcpOiB2b2lkIHtcbiAgICBjb25zdCB2YWx1ZSA9IHRoaXMuZ2V0Um93VmFsdWUocm93LCBjb2x1bW5JZCk7XG4gICAgdGhpcy5jZWxsQ2xpY2tlZC5lbWl0KHsgcm93LCBjb2x1bW5JZCwgdmFsdWUgfSk7XG4gIH1cblxuICBwdWJsaWMgb25BY3Rpb25DbGljayhldmVudDogT2VwYUFjdGlvbkV2ZW50KTogdm9pZCB7XG4gICAgdGhpcy5hY3Rpb25DbGlja2VkLmVtaXQoZXZlbnQpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZUFsbFJvd3NTZWxlY3Rpb24oKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsZWN0ZWRSb3dzOiBBcnJheTxPZXBhVGFibGVSb3c+ID0gW107XG4gICAgdGhpcy5hbGxSb3dzU2VsZWN0ZWQgPSAhdGhpcy5hbGxSb3dzU2VsZWN0ZWQ7XG4gICAgdGhpcy5fZGF0YS5mb3JFYWNoKChyOiBPZXBhVGFibGVSb3cpID0+IHtcbiAgICAgIGlmIChyLnNlbGVjdGFibGUpIHtcbiAgICAgICAgci5zZWxlY3RlZCA9IHRoaXMuYWxsUm93c1NlbGVjdGVkO1xuICAgICAgfVxuICAgICAgaWYgKHIuc2VsZWN0ZWQpIHtcbiAgICAgICAgc2VsZWN0ZWRSb3dzLnB1c2gocik7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy51cGRhdGVUYWJsZSgpO1xuICAgIHRoaXMucm93U2VsZWN0ZWQuZW1pdChzZWxlY3RlZFJvd3MpO1xuICB9XG5cbiAgcHVibGljIHRvZ2dsZVJvd1NlbGVjdGlvbihyb3c6IE9lcGFUYWJsZVJvdyk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGVkUm93czogQXJyYXk8T2VwYVRhYmxlUm93PiA9IFtdO1xuICAgIHJvdy5zZWxlY3RlZCA9ICFyb3cuc2VsZWN0ZWQ7XG4gICAgdGhpcy5fZGF0YS5mb3JFYWNoKChkcjogT2VwYVRhYmxlUm93KSA9PiB7XG4gICAgICBpZiAocm93LnByaXZhdGVJZCA9PT0gZHIucHJpdmF0ZUlkKSB7XG4gICAgICAgIGRyLnNlbGVjdGVkID0gcm93LnNlbGVjdGVkO1xuICAgICAgfVxuICAgICAgaWYgKGRyLnNlbGVjdGVkKSB7XG4gICAgICAgIHNlbGVjdGVkUm93cy5wdXNoKGRyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHRoaXMuYWxsUm93c1NlbGVjdGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy51cGRhdGVUYWJsZSgpO1xuICAgIHRoaXMucm93U2VsZWN0ZWQuZW1pdChzZWxlY3RlZFJvd3MpO1xuICB9XG5cbiAgcHVibGljIHNpbmdsZVJvd1NlbGVjdGlvbihyb3c6IE9lcGFUYWJsZVJvdyk6IHZvaWQge1xuICAgIGNvbnN0IHNlbGVjdGVkUm93czogQXJyYXk8T2VwYVRhYmxlUm93PiA9IFtdO1xuICAgIHJvdy5zZWxlY3RlZCA9ICFyb3cuc2VsZWN0ZWQ7XG4gICAgLy8gYWRkIHJvdyB0byBzZWxlY3RlZCByb3dzIGlmIGl0IGlzIHNlbGVjdGVkXG4gICAgaWYgKHJvdy5zZWxlY3RlZCkge1xuICAgICAgc2VsZWN0ZWRSb3dzLnB1c2gocm93KTtcbiAgICB9XG4gICAgLy8gdW5zZWxlY3QgYW55IG90aGVyIHJvdyB0aGF0IG1heSBiZSBzZWxlY3RlZFxuICAgIHRoaXMuX2RhdGEuZm9yRWFjaCgoZHI6IE9lcGFUYWJsZVJvdykgPT4ge1xuICAgICAgaWYgKHJvdy5wcml2YXRlSWQgPT09IGRyLnByaXZhdGVJZCkge1xuICAgICAgICBkci5zZWxlY3RlZCA9IHJvdy5zZWxlY3RlZDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRyLnNlbGVjdGVkID0gZmFsc2U7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy51cGRhdGVUYWJsZSgpO1xuICAgIHRoaXMucm93U2VsZWN0ZWQuZW1pdChzZWxlY3RlZFJvd3MpO1xuICB9XG5cbiAgcHJpdmF0ZSBwcmVwYXJlUm93c0ZvckV4cG9ydChyb3dzOiBBcnJheTxPZXBhVGFibGVSb3c+KTogQXJyYXk8T2VwYVRhYmxlUm93PiB7XG4gICAgY29uc3QgcmVzdWx0OiBBcnJheTxPZXBhVGFibGVSb3c+ID0gW107XG4gICAgLy8gY29uc29sZS5sb2coJ3ByZXBhcmVSb3dzRm9yRXhwb3J0Li4uJyk7XG4gICAgLy8gdGhpcy5kdW1wRGV0YWlsUm93cygpO1xuICAgIGlmIChyb3dzICYmIHJvd3MubGVuZ3RoKSB7XG4gICAgICByb3dzLmZvckVhY2goKHJvdzogT2VwYVRhYmxlUm93KSA9PiB7XG4gICAgICAgIC8vIGNvbnNvbGUubG9nKCdzaG93RGV0YWlsID0gJyArIHJvdy5zaG93RGV0YWlsICsgJyAnICsgSlNPTi5zdHJpbmdpZnkocm93LmNlbGxzKSk7XG4gICAgICAgIHJlc3VsdC5wdXNoKHtcbiAgICAgICAgICBjZWxsczogcm93LmNlbGxzLFxuICAgICAgICAgIGFjdGlvbnM6IHJvdy5hY3Rpb25zLFxuICAgICAgICAgIHNob3dEZXRhaWw6IHJvdy5zaG93RGV0YWlsLFxuICAgICAgICAgIHN1YlRhYmxlOiByb3cuZGV0YWlsID8gdGhpcy5jb252ZXJ0VG9UYWJsZShyb3cuZGV0YWlsKSA6IHVuZGVmaW5lZCxcbiAgICAgICAgICBpc0RpdmlkZXI6IHJvdy5pc0RpdmlkZXIsXG4gICAgICAgICAgZGl2aWRlckNsYXNzTmFtZTogcm93LmRpdmlkZXJDbGFzc05hbWVcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIHB1YmxpYyBnYXRoZXJUYWJsZURhdGEocm93czogT2VwYVRhYmxlUm93W10pOiBPZXBhVGFibGUge1xuICAgIC8vIGNvbnNvbGUubG9nKCdnYXRoZXJUYWJsZURhdGEuLi4nKTtcbiAgICAvLyB0aGlzLmR1bXBEZXRhaWxSb3dzKCk7XG4gICAgY29uc3Qgb2VwYVRhYmxlOiBPZXBhVGFibGUgPSB7fTtcbiAgICBvZXBhVGFibGUuaGVhZGVyUm93cyA9IHRoaXMuaGVhZGVyUm93cztcbiAgICBvZXBhVGFibGUuYWxsRGF0YVJvd3MgPSB0aGlzLnByZXBhcmVSb3dzRm9yRXhwb3J0KHJvd3MpO1xuICAgIG9lcGFUYWJsZS5zaG93QWxsRGV0YWlscyA9IHRoaXMuc2hvd0FsbERldGFpbHM7XG4gICAgb2VwYVRhYmxlLmNsYXNzTmFtZSA9IHRoaXMuX2NvbmZpZy5jbGFzc05hbWU7XG4gICAgb2VwYVRhYmxlLnZpc2libGVDb2x1bW5Db3VudCA9IHRoaXMudmlzaWJsZUNvbHVtbkNvdW50O1xuICAgIG9lcGFUYWJsZS5hbGxDb2x1bW5Db3VudCA9IHRoaXMuYWxsQ29sdW1uQ291bnQ7XG4gICAgcmV0dXJuIG9lcGFUYWJsZTtcbiAgfVxuXG4gIHByaXZhdGUgZHVtcERldGFpbFJvd3MoKSB7XG4gICAgY29uc29sZS5sb2coJ2R1bXBEZXRhaWxSb3dzIC0gVG90YWwgcm93czogJyArIHRoaXMuX2RhdGEubGVuZ3RoKTtcbiAgICB0aGlzLl9kYXRhLmZvckVhY2goKHJvdzogT2VwYVRhYmxlUm93KSA9PiB7XG4gICAgICBpZiAocm93LnNob3dEZXRhaWwpIHtcbiAgICAgICAgY29uc29sZS5sb2coJ1NIT1cgREVUQUlMOiAnICsgSlNPTi5zdHJpbmdpZnkocm93LmRhdGFTb3VyY2UpKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBjb252ZXJ0VG9UYWJsZSh0ZW1wbGF0ZTogT2VwYVRlbXBsYXRlSW5mbyk6IE9lcGFUYWJsZSB8IHVuZGVmaW5lZCB7XG4gICAgbGV0IG9lcGFUYWJsZTogT2VwYVRhYmxlIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGlmICh0ZW1wbGF0ZS5jb21wb25lbnQgPT09IFRhYmxlQ29tcG9uZW50KSB7XG4gICAgICBjb25zdCB0YWJsZTogVGFibGVDb21wb25lbnQgPSBuZXcgVGFibGVDb21wb25lbnQodGhpcy5zYW5pdGl6ZXIsIHRoaXMudGFibGVTZXJ2aWNlLCB0aGlzLnRhYmxlRXhwb3J0U2VydmljZSwgdGhpcy5maWxlVXRpbFNlcnZpY2UpO1xuICAgICAgaWYgKHRlbXBsYXRlLmlucHV0cyAmJiB0ZW1wbGF0ZS5pbnB1dHMubGVuZ3RoID4gMCkge1xuICAgICAgICB0ZW1wbGF0ZS5pbnB1dHMuZm9yRWFjaCgoaW5wdXQpID0+IHtcbiAgICAgICAgICBpZiAoaW5wdXQubmFtZSA9PT0gJ2NvbmZpZycpIHtcbiAgICAgICAgICAgIHRhYmxlLmNvbmZpZyA9IGlucHV0LnZhbHVlO1xuICAgICAgICAgIH0gZWxzZSBpZiAoaW5wdXQubmFtZSA9PT0gJ2NvbXBsZXhIZWFkZXInKSB7XG4gICAgICAgICAgICB0YWJsZS5jb21wbGV4SGVhZGVyID0gaW5wdXQudmFsdWU7XG4gICAgICAgICAgfSBlbHNlIGlmIChpbnB1dC5uYW1lID09PSAnaGVhZGVyJykge1xuICAgICAgICAgICAgdGFibGUuaGVhZGVyID0gaW5wdXQudmFsdWU7XG4gICAgICAgICAgfSBlbHNlIGlmIChpbnB1dC5uYW1lID09PSAnZGF0YScpIHtcbiAgICAgICAgICAgIHRhYmxlLmRhdGEgPSBpbnB1dC52YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuICAgICAgICBvZXBhVGFibGUgPSB0YWJsZS5nYXRoZXJUYWJsZURhdGEodGFibGUuZGF0YSk7XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBvZXBhVGFibGU7XG4gIH1cblxuICBwdWJsaWMgdG9nZ2xlRXhwb3J0VmlzaWJsZU9ubHkoKSB7XG4gICAgdGhpcy5leHBvcnRWaXNpYmxlT25seSA9ICF0aGlzLmV4cG9ydFZpc2libGVPbmx5O1xuICB9XG5cbiAgcHVibGljIGV4cG9ydFRvRXhjZWwoKSB7XG4gICAgY29uc3QgZXhwb3J0VGFibGU6IE9lcGFUYWJsZSA9IHRoaXMuZ2F0aGVyVGFibGVEYXRhKHRoaXMuZXhwb3J0VmlzaWJsZU9ubHkgPyB0aGlzLnJvd3MgOiB0aGlzLl9kYXRhKTtcblxuICAgIHRoaXMudGFibGVFeHBvcnRTZXJ2aWNlLmRvd25sb2FkRXhjZWwoZXhwb3J0VGFibGUsIHRoaXMuX2NvbmZpZykuc3Vic2NyaWJlKFxuICAgICAgZGF0YSA9PiB7XG4gICAgICAgIHRoaXMuZmlsZVV0aWxTZXJ2aWNlLmRvd25sb2FkRmlsZShkYXRhLCAnYXBwbGljYXRpb24vdm5kLm1zLWV4Y2VsJyk7XG4gICAgICB9LFxuICAgICAgZXJyb3IgPT4gY29uc29sZS5sb2coZXJyb3IpXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBleHBvcnRUb0hUTUwoKSB7XG4gICAgY29uc3QgZXhwb3J0VGFibGU6IE9lcGFUYWJsZSA9IHRoaXMuZ2F0aGVyVGFibGVEYXRhKHRoaXMuZXhwb3J0VmlzaWJsZU9ubHkgPyB0aGlzLnJvd3MgOiB0aGlzLl9kYXRhKTtcblxuICAgIC8vIGZvciBub3csIGFsd2F5cyBlbWJlZCBzdWItdGFibGVzICBpbiBIVE1MIHZpZXcuXG4gICAgdGhpcy50YWJsZUV4cG9ydFNlcnZpY2UuZG93bmxvYWRIVE1MKGV4cG9ydFRhYmxlLCB0aGlzLl9jb25maWcpLnN1YnNjcmliZShcbiAgICAgIGRhdGEgPT4ge1xuICAgICAgICB0aGlzLmZpbGVVdGlsU2VydmljZS5kb3dubG9hZEZpbGUoZGF0YSwgJ3RleHQvaHRtbCcpO1xuICAgICAgfSxcbiAgICAgIGVycm9yID0+IGNvbnNvbGUubG9nKGVycm9yKVxuICAgICk7XG4gIH1cblxuICBwdWJsaWMgb25DdXN0b21CdG5DbGljaygpIHtcbiAgICB0aGlzLmN1c3RvbUJ0bkNsaWNrZWQuZW1pdCgpO1xuICB9XG5cbn1cbiIsIjwhLS0gVW5oaWRlIHNlbGVjdCBpbnB1dCAtIG9ubHkgdmlzaWJsZSBpZiBvbmUgb3IgbW9yZSBjb2x1bW5zIGFyZSBoaWRkZW4gLS0+XG5cbjxmb3JtICpuZ0lmPVwiaGlkZGVuQ29sdW1ucy5sZW5ndGggPiAwXCI+XG4gIDxkaXYgY2xhc3M9XCJyb3cgbWItMlwiPlxuICAgIDxsYWJlbCBjbGFzcz1cImNvbC1zbS0yIGNvbC1mb3JtLWxhYmVsXCI+U2hvdyBIaWRkZW4gQ29sdW1uczo8L2xhYmVsPlxuICAgIDxkaXYgY2xhc3M9XCJjb2wtc20tNFwiPlxuICAgICAgPHNlbGVjdCBjbGFzcz1cImZvcm0tc2VsZWN0XCIgKGNoYW5nZSk9XCJ1bmhpZGVDb2x1bW4oJGFueSgkZXZlbnQpLnRhcmdldC52YWx1ZSlcIiBbaWRdPVwidGFibGVJZCsnX1VuaGlkZUNvbHVtblNlbGVjdCdcIj5cbiAgICAgICAgPG9wdGlvbiB2YWx1ZT1cIlwiPkNob29zZSBhIGNvbHVtbjwvb3B0aW9uPlxuICAgICAgICA8b3B0aW9uICpuZ0Zvcj1cImxldCBjb2wgb2YgaGlkZGVuQ29sdW1uc1wiIFt2YWx1ZV09XCJjb2wuaWRcIj57e2NvbC50aXRsZX19PC9vcHRpb24+XG4gICAgICA8L3NlbGVjdD5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Zvcm0+XG48IS0tIFRoaXMgaXMgdGhlIHRhYmxlIC0tPlxuPGRpdiBuZ0NsYXNzPVwie3tjb25maWcuZGl2Q2xhc3NOYW1lIHx8ICcnfX1cIiA+XG48dGFibGUgKm5nSWY9XCIhY29uZmlnLmhpZGVUYWJsZVwiIGNsYXNzPVwidGFibGUgZGF0YVRhYmxlXCIgbmdDbGFzcz1cInt7Y29uZmlnLmNsYXNzTmFtZSB8fCAnJ319XCIgcm9sZT1cImdyaWRcIiBzdHlsZT1cIndpZHRoOiAxMDAlO1wiPlxuXG48IS0tIFRoaXMgaXMgdGhlIHRhYmxlIGhlYWRlciAtLT5cbjx0aGVhZD5cbiAgPCEtLSBUaGVyZSBtYXkgYmUgbXVsdGlwbGUgaGVhZGVyIHJvd3MgLS0+XG4gIDx0ciAqbmdGb3I9XCJsZXQgaGRyIG9mIGhlYWRlclJvd3M7IGxldCBocj1pbmRleDtcIiByb2xlPVwicm93XCI+XG4gICAgPCEtLSBEZXRhaWxzIGluZGljYXRvciBjb2x1bW4gKGlmIGRhdGEgaGFzIGRldGFpbHMpIC0tPlxuICAgIDx0aCAqbmdJZj1cImRhdGFIYXNEZXRhaWxzICYmIGhyID09PSAwXCIgW3Jvd1NwYW5dPVwiaGVhZGVyUm93cy5sZW5ndGhcIiBjbGFzcz1cImRldGFpbC1pbmRpY2F0b3ItY29sXCI+XG4gICAgICA8c3Bhbj5cbiAgICAgICAgPGkgKGNsaWNrKT1cInRvZ2dsZUFsbERldGFpbHMoKVwiIFtpZF09XCJ0YWJsZUlkKydfU2hvd0FsbERldGFpbHNMaW5rJ1wiIGNsYXNzPVwiYmlcIiBbbmdDbGFzc109XCJ7J2JpLWNoZXZyb24tZG93bic6IHNob3dBbGxEZXRhaWxzLCAnYmktY2hldnJvbi1yaWdodCc6ICFzaG93QWxsRGV0YWlsc31cIlxuICAgICAgICAgIFt0b29sdGlwXT1cIihzaG93QWxsRGV0YWlscyA/ICdIaWRlJyA6ICdTaG93JykgKyAnIGRldGFpbHMgZm9yIGFsbCByb3dzJ1wiIHBsYWNlbWVudD1cInJpZ2h0XCI+XG4gICAgICAgIDwvaT5cbiAgICAgIDwvc3Bhbj5cbiAgICA8L3RoPlxuICAgIDxuZy10ZW1wbGF0ZSBuZ0ZvciBsZXQtY29sdW1uIFtuZ0Zvck9mXT1cImhkci5jb2x1bW5zXCIgbGV0LWM9XCJpbmRleFwiPlxuICAgICAgPCEtLSBIZWFkZXIgY2VsbCAtLT5cbiAgICAgIDx0aCAqbmdJZj1cIiFjb2x1bW4uaGlkZGVuXCIgbmdDbGFzcz1cInt7Y29sdW1uLmNsYXNzTmFtZSB8fCAnJ319XCIgW2NvbFNwYW5dPVwiY29sdW1uLmNvbHNwYW4gfHwgMVwiIFtyb3dTcGFuXT1cImNvbHVtbi5yb3dzcGFuIHx8IDFcIj5cbiAgICAgICAgPCEtLSBTZWxlY3QgYWxsIFJvd3MgQ2hlY2tib3ggLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxuICAgICAgICAgIDxpbnB1dCAqbmdJZj1cImNvbHVtbi5zZWxlY3RDb2x1bW5cIiB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJhbGxSb3dzU2VsZWN0ZWRcIiAoY2hhbmdlKT1cInRvZ2dsZUFsbFJvd3NTZWxlY3Rpb24oKVwiPlxuXG4gICAgICAgICAgPCEtLSBIZWFkZXIgY2VsbCB0ZXh0IHdpdGggc29ydCBjYXBhYmlsaXR5IChpZiBzcGVjaWZpZWQpIC0tPlxuICAgICAgICAgIDxzcGFuIFtvZXBhVGFibGVTb3J0aW5nXT1cInRydWVcIiBbY29sdW1uXT1cImNvbHVtblwiIFt0YWJsZUlkXT1cInRhYmxlSWRcIiAoc29ydENoYW5nZWQpPVwib25Tb3J0Q2hhbmdlZCgkZXZlbnQpXCIgW2lkXT1cInRhYmxlSWQrJ19Tb3J0Q29sdW1uTGlua18nK2NvbHVtbi5pZFwiPlxuICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCJjb2x1bW4uc29ydFwiPjxpIGNsYXNzPVwicHVsbC1sZWZ0IGJpXCIgW25nQ2xhc3NdPVwieydiaS1jaGV2cm9uLWRvd24nOiBjb2x1bW4uc29ydCA9PT0gJ2Rlc2MnLCAnYmktY2hldnJvbi11cCc6IGNvbHVtbi5zb3J0ID09PSAnYXNjJ31cIj48L2k+XG4gICAgICAgICAgICA8c3VwICpuZ0lmPVwiY29sdW1uPy5zb3J0SW5kZXggfHwgMCA+IDFcIj57e2NvbHVtbi5zb3J0SW5kZXh9fTwvc3VwPjwvc3Bhbj5cbiAgICAgICAgICAgIHt7Y29sdW1uLnRpdGxlfX1cbiAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgPCEtLSBidXR0b24gdG8gYWxsb3cgY29sdW1uIHRvIGJlIGhpZGRlbiAoaWYgc3BlY2lmaWVkKSAtLT5cbiAgICAgICAgICA8YnV0dG9uICpuZ0lmPVwiY29sdW1uLmhpZGRlbiA9PT0gZmFsc2VcIiB0eXBlPVwiYnV0dG9uXCIgY2xhc3M9XCJidG4tY2xvc2UgZmxvYXQtZW5kXCIgYXJpYS1sYWJlbD1cIkhpZGVcIiAoY2xpY2spPVwiaGlkZUNvbHVtbihjb2x1bW4pXCJcbiAgICAgICAgICAgIFtpZF09XCJ0YWJsZUlkKydfSGlkZUNvbHVtbkxpbmsnKydfJytjb2x1bW4uaWRcIj5cbiAgICAgICAgICA8L2J1dHRvbj5cblxuICAgICAgICA8L2Rpdj5cbiAgICAgICAgPCEtLSBjb2x1bW4gZmlsdGVyIChpZiBzcGVjaWZpZWQpIC0tPlxuICAgICAgICA8ZGl2ICpuZ0lmPVwiKChyb3dzICYmIHJvd3MubGVuZ3RoID4gMCkgfHwgIW5vRmlsdGVycygpKSAmJiBjb2x1bW4uZmlsdGVyYWJsZVwiID5cbiAgICAgICAgICA8aW5wdXQgW29lcGFUYWJsZUZpbHRlcmluZ109XCJ7IGZpbHRlclN0cmluZzogJycsIGNvbHVtbklkOiBjb2x1bW4uaWQgfVwiIFt0YWJsZUlkXT1cInRhYmxlSWRcIiBjbGFzcz1cImZvcm0tY29udHJvbCBpbnB1dC1zbVwiICh0YWJsZUNoYW5nZWQpPVwib25GaWx0ZXJDaGFuZ2VkKCRldmVudClcIlxuICAgICAgICAgICAgW2lkXT1cInRhYmxlSWQrJ19GaWx0ZXJDb2x1bW5fJytjb2x1bW4uaWRcIiAvPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvdGg+XG4gICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC90cj5cbjwvdGhlYWQ+XG5cbjwhLS0gVGhpcyBpcyB0aGUgdGFibGUgYm9keSAtLT5cbjx0Ym9keT5cbiAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC1yb3cgW25nRm9yT2ZdPVwicm93c1wiIGxldC1yPVwiaW5kZXhcIj5cbiAgICA8IS0tIERhdGEgUm93IC0tPlxuICAgIDx0cj5cbiAgICAgIDx0ZCAqbmdJZj1cImRhdGFIYXNEZXRhaWxzXCI+XG4gICAgICAgIDwhLS0gRGV0YWlsIGljb24gKGlmIHNwZWNpZmllZCkgLS0+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwicm93LnNob3dEZXRhaWwgPT09IHRydWUgfHwgcm93LnNob3dEZXRhaWwgPT09IGZhbHNlXCI+XG4gICAgICAgICAgPGkgKm5nSWY9XCJyb3cuZGV0YWlsSWNvbkNsYXNzTmFtZVwiIFtuZ0NsYXNzXT1cInJvdy5kZXRhaWxJY29uQ2xhc3NOYW1lXCI+PC9pPlxuICAgICAgICAgIDxpIChjbGljayk9XCJ0b2dnbGVSb3dEZXRhaWwocm93KVwiIFtpZF09XCJ0YWJsZUlkKydfU2hvd0RldGFpbExpbmtfJytyXCIgY2xhc3M9XCJiaVwiIFtuZ0NsYXNzXT1cInsnYmktY2hldnJvbi1kb3duJzogcm93LnNob3dEZXRhaWwsICdiaS1jaGV2cm9uLXJpZ2h0JzogIXJvdy5zaG93RGV0YWlsfVwiXG4gICAgICAgICAgICBbdG9vbHRpcF09XCIocm93LnNob3dEZXRhaWwgPyAnSGlkZScgOiAnU2hvdycpICsgJyBkZXRhaWxzIGZvciB0aGlzIHJvdydcIiBwbGFjZW1lbnQ9XCJyaWdodFwiPlxuICAgICAgICAgIDwvaT5cbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC90ZD5cbiAgICAgIDwhLS0gSWYgcm93IGlzIGEgZGl2aWRlciwgaXQgc3BhbnMgdGhlIHdob2xlIHRhYmxlIC0tPlxuICAgICAgPCEtLSA8dGQgKm5nSWY9XCJyb3cuaXNEaXZpZGVyXCIgW2NvbFNwYW5dPVwidmlzaWJsZUNvbHVtbkNvdW50ICsgKGRhdGFIYXNEZXRhaWxzID8gMSA6IDApXCIgW25nQ2xhc3NdPVwicm93LmRpdmlkZXJDbGFzc05hbWUgfHwgJ29lcGEtdGFibGUtZ3JheSdcIj4mbmJzcDs8L3RkPiAtLT5cbiAgICAgIDwhLS0gRGF0YSBSb3dzIC0tPlxuICAgICAgPG5nLXRlbXBsYXRlICpuZ0lmPVwiIXJvdy5pc0RpdmlkZXJcIiBuZ0ZvciBsZXQtY29sIFtuZ0Zvck9mXT1cImRhdGFDb2x1bW5zXCIgbGV0LWk9XCJpbmRleFwiPlxuICAgICAgICA8dGQgKm5nSWY9XCIhY29sLmhpZGRlbiAmJiAocm93fGNlbGxDb2xzcGFuOmNvbCkgPiAwXCIgbmdDbGFzcz1cInt7cm93fGNlbGxDbGFzc25hbWU6Y29sIHx8ICcnfX1cIiBbY29sU3Bhbl09XCJyb3d8Y2VsbENvbHNwYW46Y29sXCI+XG4gICAgICAgICAgPCEtLSBEYXRhIENlbGwgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cIiFjb2wuYWN0aW9uQ29sdW1uICYmICFjb2wuc2VsZWN0Q29sdW1uICYmICFjb2wuc2luZ2xlU2VsZWN0Q29sdW1uXCI+XG4gICAgICAgICAgICA8IS0tIFRlbXBsYXRlIGZvciBwb3BvdmVyIDEgLS0+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgI3BvcG92ZXJUZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInJvdy5wb3BvdmVyXCI+XG4gICAgICAgICAgICAgICAgPGNtbC10ZW1wbGF0ZSBbdGVtcGxhdGVJbmZvXT1cInJvdy5wb3BvdmVyLmNvbnRlbnRcIj48L2NtbC10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgPCEtLSBQb3BvdmVyIDEgaWNvbiAoaWYgc3BlY2lmaWVkKSAtLT5cbiAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwicm93LnBvcG92ZXIgJiYgaSA9PT0gKHJvdy5wb3BvdmVyQ29sdW1uSW5kZXggfHwgMCkgJiYgcm93LnBvcG92ZXJcIiB0YWJpbmRleD1cIjBcIiBbcG9wb3ZlclRpdGxlXT1cInJvdy5wb3BvdmVyLnRpdGxlXCIgW3BvcG92ZXJdPVwicG9wb3ZlclRlbXBsYXRlXCJcbiAgICAgICAgICAgICAgW2NvbnRhaW5lckNsYXNzXT1cInJvdy5wb3BvdmVyLmNvbnRhaW5lckNsYXNzXCIgcGxhY2VtZW50PVwicmlnaHRcIiBbdHJpZ2dlcnNdPVwicm93LnBvcG92ZXIudHJpZ2dlciB8fCAnbW91c2VlbnRlcjptb3VzZWxlYXZlJ1wiPlxuICAgICAgICAgICAgICA8aSBbbmdDbGFzc109XCJyb3cucG9wb3Zlci5jbGFzc05hbWVcIiBbaWRdPVwidGFibGVJZCsnX1BvcG92ZXJMaW5rXycrclwiPjwvaT5cbiAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgPCEtLSBUZW1wbGF0ZSBmb3IgcG9wb3ZlciAyIC0tPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNwb3BvdmVyMlRlbXBsYXRlPlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicm93LnBvcG92ZXIyXCI+XG4gICAgICAgICAgICAgICAgPGNtbC10ZW1wbGF0ZSBbdGVtcGxhdGVJbmZvXT1cInJvdy5wb3BvdmVyMi5jb250ZW50XCI+PC9jbWwtdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwhLS0gUG9wb3ZlciAyIGljb24gKGlmIHNwZWNpZmllZCkgLS0+XG4gICAgICAgICAgICA8c3BhbiAqbmdJZj1cImkgPT09IChyb3cucG9wb3ZlcjJDb2x1bW5JbmRleCB8fCAwKSAmJiByb3cucG9wb3ZlcjJcIiB0YWJpbmRleD1cIjBcIiBbcG9wb3ZlclRpdGxlXT1cInJvdy5wb3BvdmVyMi50aXRsZVwiIFtwb3BvdmVyXT1cInBvcG92ZXIyVGVtcGxhdGVcIlxuICAgICAgICAgICAgICBbY29udGFpbmVyQ2xhc3NdPVwicm93LnBvcG92ZXIyLmNvbnRhaW5lckNsYXNzXCIgcGxhY2VtZW50PVwicmlnaHRcIiBbdHJpZ2dlcnNdPVwicm93LnBvcG92ZXIyLnRyaWdnZXIgfHwgJ21vdXNlZW50ZXI6bW91c2VsZWF2ZSdcIj5cbiAgICAgICAgICAgICAgPGkgW25nQ2xhc3NdPVwicm93LnBvcG92ZXIyLmNsYXNzTmFtZVwiIFtpZF09XCJ0YWJsZUlkKydfUG9wb3ZlcjJMaW5rXycrclwiPjwvaT5cbiAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgPCEtLSBUZW1wbGF0ZSBmb3IgcG9wb3ZlciAzIC0tPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICNwb3BvdmVyM1RlbXBsYXRlPlxuICAgICAgICAgICAgICA8ZGl2ICpuZ0lmPVwicm93LnBvcG92ZXIzXCI+XG4gICAgICAgICAgICAgICAgPGNtbC10ZW1wbGF0ZSBbdGVtcGxhdGVJbmZvXT1cInJvdy5wb3BvdmVyMy5jb250ZW50XCI+PC9jbWwtdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgIDwhLS0gUG9wb3ZlciAzIGljb24gKGlmIHNwZWNpZmllZCkgLS0+XG4gICAgICAgICAgICA8c3BhbiAqbmdJZj1cImkgPT09IChyb3cucG9wb3ZlcjNDb2x1bW5JbmRleCB8fCAwKSAmJiByb3cucG9wb3ZlcjNcIiB0YWJpbmRleD1cIjBcIiBbcG9wb3ZlclRpdGxlXT1cInJvdy5wb3BvdmVyMy50aXRsZVwiIFtwb3BvdmVyXT1cInBvcG92ZXIzVGVtcGxhdGVcIlxuICAgICAgICAgICAgICBbY29udGFpbmVyQ2xhc3NdPVwicm93LnBvcG92ZXIzLmNvbnRhaW5lckNsYXNzXCIgcGxhY2VtZW50PVwicmlnaHRcIiBbdHJpZ2dlcnNdPVwicm93LnBvcG92ZXIzLnRyaWdnZXIgfHwgJ21vdXNlZW50ZXI6bW91c2VsZWF2ZSdcIj5cbiAgICAgICAgICAgICAgPGkgW25nQ2xhc3NdPVwicm93LnBvcG92ZXIzLmNsYXNzTmFtZVwiIFtpZF09XCJ0YWJsZUlkKydfUG9wb3ZlcjNMaW5rXycrclwiPjwvaT5cbiAgICAgICAgICAgIDwvc3Bhbj5cblxuICAgICAgICAgICAgXG4gICAgICAgICAgICA8IS0tIDxkaXYgKm5nSWY9XCJyb3d8Y2VsbElubmVySFRNTDpjb2xcIiBbaW5uZXJIVE1MXT1cInJvd3xjZWxsSW5uZXJIVE1MOmNvbFwiPjwvZGl2PlxuICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhKHJvd3xjZWxsSW5uZXJIVE1MOmNvbClcIj57e3Jvd3xjZWxsVmFsdWU6Y29sfX08L3NwYW4+IC0tPlxuXG4gICAgICAgICAgICA8IS0tIElmIGNvbCBpcyBoeXBlcmxpbmssIGRpc3BsYXkgZGF0YSBhcyBhIGh5cGVybGluayAtLT5cbiAgICAgICAgICAgIDxidXR0b24gKm5nSWY9XCJjb2wuaHlwZXJsaW5rXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1saW5rXCIgKGNsaWNrKT1cImNlbGxDbGljayhyb3csIGNvbC5pZClcIiBbaWRdPVwidGFibGVJZCsnX0NlbGxDbGlja18nK3IrJ18nK2lcIj5cbiAgICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhKHJvd3xjZWxsSW5uZXJIVE1MOmNvbClcIj5cbiAgICAgICAgICAgICAgICA8aSBbbmdDbGFzc109XCJyb3d8Y2VsbEljb25DbGFzc25hbWU6Y29sXCI+PC9pPlxuICAgICAgICAgICAgICAgIDxzcGFuICpuZ0lmPVwicm93fGNlbGxJbWdTcmM6Y29sXCI+PGltZyBbc3JjXT1cInJvd3xjZWxsSW1nU3JjOmNvbFwiLz48L3NwYW4+XG4gICAgICAgICAgICAgICAge3tyb3d8Y2VsbFZhbHVlOmNvbH19XG4gICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgPGRpdiAqbmdJZj1cInJvd3xjZWxsSW5uZXJIVE1MOmNvbFwiIFtpbm5lckhUTUxdPVwicm93fGNlbGxJbm5lckhUTUw6Y29sXCI+PC9kaXY+XG4gICAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICAgIDwhLS0gSWYgY29sIGlzIE5PVCBoeXBlcmxpbmssIGp1c3QgZGlzcGxheSBkYXRhIC0tPlxuICAgICAgICAgICAgPHNwYW4gKm5nSWY9XCIhY29sLmh5cGVybGlua1wiPlxuICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cIiEocm93fGNlbGxJbm5lckhUTUw6Y29sKVwiPlxuICAgICAgICAgICAgICAgIDxpIG5nQ2xhc3M9XCJ7e3Jvd3xjZWxsSWNvbkNsYXNzbmFtZTpjb2wgfHwgJyd9fVwiPjwvaT5cbiAgICAgICAgICAgICAgICA8c3BhbiAqbmdJZj1cInJvd3xjZWxsSW1nU3JjOmNvbFwiPjxpbWcgW3NyY109XCJyb3d8Y2VsbEltZ1NyYzpjb2xcIi8+PC9zcGFuPlxuICAgICAgICAgICAgICAgIHt7cm93fGNlbGxWYWx1ZTpjb2x9fVxuICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgIDxkaXYgKm5nSWY9XCJyb3d8Y2VsbElubmVySFRNTDpjb2xcIiBbaW5uZXJIVE1MXT1cInJvd3xjZWxsSW5uZXJIVE1MOmNvbFwiPjwvZGl2PlxuICAgICAgICAgICAgPC9zcGFuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwhLS0gU2VsZWN0IENlbGwgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImNvbC5zZWxlY3RDb2x1bW5cIiBjbGFzcz1cInRleHQtY2VudGVyXCI+XG4gICAgICAgICAgICA8aW5wdXQgW2lkXT1cInRhYmxlSWQrJ18nK3JcIiB0eXBlPVwiY2hlY2tib3hcIiBbZGlzYWJsZWRdPVwiIXJvdy5zZWxlY3RhYmxlXCIgW2NoZWNrZWRdPVwicm93LnNlbGVjdGVkXCIgKGNoYW5nZSk9XCJ0b2dnbGVSb3dTZWxlY3Rpb24ocm93KVwiPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwhLS0gU2luZ2xlIFNlbGVjdCBDZWxsIC0tPlxuICAgICAgICAgIDxkaXYgKm5nSWY9XCJjb2wuc2luZ2xlU2VsZWN0Q29sdW1uXCIgY2xhc3M9XCJ0ZXh0LWNlbnRlclwiPlxuICAgICAgICAgICAgPGlucHV0IFtpZF09XCJ0YWJsZUlkKydfc2luZ2xlU2VsZWN0XycrclwiIHR5cGU9XCJyYWRpb1wiIFtkaXNhYmxlZF09XCIhcm93LnNlbGVjdGFibGVcIiBbY2hlY2tlZF09XCJyb3cuc2VsZWN0ZWRcIiAoY2hhbmdlKT1cInNpbmdsZVJvd1NlbGVjdGlvbihyb3cpXCI+XG4gICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgPCEtLSBBY3Rpb24gQnV0dG9uIENlbGwgLS0+XG4gICAgICAgICAgPGRpdiAqbmdJZj1cImNvbC5hY3Rpb25Db2x1bW4gJiYgcm93LmFjdGlvbnNcIj5cbiAgICAgICAgICAgIDxvZXBhLWFjdGlvbi1idG4gW2FjdGlvbnNdPVwicm93LmFjdGlvbnNcIiBbZGF0YV09XCJyb3cuZGF0YVNvdXJjZVwiICAoYWN0aW9uQ2xpY2tlZCk9XCJvbkFjdGlvbkNsaWNrKCRldmVudClcIiBbYnRuSWRdPVwidGFibGVJZCsnXycrclwiPjwvb2VwYS1hY3Rpb24tYnRuPlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICA8L3RkPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICA8L3RyPlxuXG4gICAgPCEtLSBEZXRhaWwgUm93IC0tPlxuICAgIDx0ciAqbmdJZj1cInJvdy5zaG93RGV0YWlsXCIgY2xhc3M9XCJ0YWJsZS1pbmZvXCI+XG4gICAgICA8dGQgW2NvbFNwYW5dPVwidmlzaWJsZUNvbHVtbkNvdW50ICsgKGRhdGFIYXNEZXRhaWxzID8gMSA6IDApXCI+XG4gICAgICAgIDxjbWwtdGVtcGxhdGUgW3RlbXBsYXRlSW5mb109XCJyb3cuZGV0YWlsXCI+PC9jbWwtdGVtcGxhdGU+XG4gICAgICA8L3RkPlxuICAgIDwvdHI+XG4gIDwvbmctdGVtcGxhdGU+XG4gIDx0ciAqbmdJZj1cInRvdGFsUm93XCI+XG4gICAgPHRkICpuZ0lmPVwiZGF0YUhhc0RldGFpbHNcIj5cbiAgICA8L3RkPlxuICAgICAgPG5nLXRlbXBsYXRlIG5nRm9yIGxldC10b3RhbENvbCBbbmdGb3JPZl09XCJkYXRhQ29sdW1uc1wiPlxuICAgICAgICAgIDx0ZCAqbmdJZj1cIiF0b3RhbENvbC5oaWRkZW5cIiBuZ0NsYXNzPVwie3t0b3RhbFJvd3xjZWxsQ2xhc3NuYW1lOnRvdGFsQ29sIHx8ICcnfX1cIj5cbiAgICAgICAgICAgIDxkaXY+XG4gICAgICAgICAgICAgICA8c3Bhbj48aSBuZ0NsYXNzPVwie3t0b3RhbFJvd3xjZWxsSWNvbkNsYXNzbmFtZTp0b3RhbENvbCB8fCAnJ319XCI+PC9pPnt7dG90YWxSb3d8Y2VsbFZhbHVlOnRvdGFsQ29sfX08L3NwYW4+XG4gICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICA8L3RkPlxuICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgPC90cj5cbjwvdGJvZHk+XG48L3RhYmxlPlxuPC9kaXY+XG48IS0tIFRhYmxlIGZvb3RlciAtLT5cbjxmb3JtICpuZ0lmPVwiIWNvbmZpZy5oaWRlRm9vdGVyIHx8IChkYXRhICYmIHBhZ2VJbmZvLml0ZW1zUGVyUGFnZSA8IGRhdGEubGVuZ3RoKVwiIGNsYXNzPVwiZm9ybS1ob3Jpem9udGFsXCI+XG48ZGl2IGNsYXNzPVwiZm9ybS1ncm91cCByb3cgdGV4dC1yaWdodFwiPlxuICA8IS0tIFRhYmxlLXdpZGUgZmlsdGVyIC0tPlxuICA8ZGl2IGNsYXNzPVwiY29sLXNtLTRcIj5cbiAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTZcIj5cbiAgICAgICAgPGlucHV0ICpuZ0lmPVwiIWNvbmZpZy5oaWRlR2xvYmFsRmlsdGVyXCIgcGxhY2Vob2xkZXI9XCJGaWx0ZXIgYWxsIGNvbHVtbnNcIiBbb2VwYVRhYmxlRmlsdGVyaW5nXT1cInsgZmlsdGVyU3RyaW5nOiAnJyB9XCIgW3RhYmxlSWRdPVwidGFibGVJZFwiIGNsYXNzPVwiZm9ybS1jb250cm9sIGlucHV0LXNtXCIgKHRhYmxlQ2hhbmdlZCk9XCJvbkZpbHRlckNoYW5nZWQoJGV2ZW50KVwiXG4gICAgICAgICAgW2lkXT1cInRhYmxlSWQrJ19GaWx0ZXJBbGxDb2x1bW5zSW5wdXQnXCIgLz5cbiAgICAgIDwvZGl2PlxuICAgICAgPGRpdiBjbGFzcz1cImNvbC1zbS02XCI+XG4gICAgICAgIDxzcGFuICpuZ0lmPVwiY29uZmlnLnNob3dSb3dDb3VudEluRm9vdGVyICYmIF9kYXRhICYmIF9kYXRhLmxlbmd0aCA+IDBcIj5cbiAgICAgICAgICA8c3BhbiBjbGFzcz1cImJhZGdlIGJhZGdlLXNlY29uZGFyeVwiIHN0eWxlPVwiY29sb3I6ICM5OTlcIj57e19kYXRhLmxlbmd0aH19PC9zcGFuPiZuYnNwO3RvdGFsIHJvd3NcbiAgICAgICAgPC9zcGFuPlxuICAgICAgPC9kaXY+XG4gICAgPC9kaXY+XG4gIDwvZGl2PlxuICA8IS0tIEV4cG9ydCBCdXR0b25zIC0tPlxuICA8ZGl2IGNsYXNzPVwiY29sLXNtLTQgZC1mbGV4IGp1c3RpZnktY29udGVudC1jZW50ZXJcIj5cbiAgICA8ZGl2IGNsYXNzPVwicm93XCI+XG4gICAgICA8ZGl2IGNsYXNzPVwiY29sLXNtLTEyIHRleHQtY2VudGVyXCI+XG4gICAgICAgIDxidXR0b24gdHlwZT1cImJ1dHRvblwiICpuZ0lmPVwiY29uZmlnLmV4cG9ydFRvRXhjZWxcIiBjbGFzcz1cImJ0biBidG4tcHJpbWFyeSBtci0xXCIgKGNsaWNrKT1cImV4cG9ydFRvRXhjZWwoKVwiIFtpZF09XCJ0YWJsZUlkKydfRXhwb3J0VG9FeGNlbEJ0bidcIj5FeHBvcnQgdG8gRXhjZWw8L2J1dHRvbj5cbiAgICAgICAgPGJ1dHRvbiB0eXBlPVwiYnV0dG9uXCIgKm5nSWY9XCJjb25maWcuZXhwb3J0VG9IVE1MXCIgY2xhc3M9XCJidG4gYnRuLXByaW1hcnkgbXItMVwiIChjbGljayk9XCJleHBvcnRUb0hUTUwoKVwiIFtpZF09XCJ0YWJsZUlkKydfRXhwb3J0VG9IVE1MQnRuJ1wiPkV4cG9ydCB0byBIVE1MPC9idXR0b24+XG4gICAgICAgIDxidXR0b24gKm5nSWY9XCJjdXN0b21CdG5WaXNpYmxlXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1wcmltYXJ5IG1yLTFcIiAoY2xpY2spPVwib25DdXN0b21CdG5DbGljaygpXCIgW2lkXT1cInRhYmxlSWQrJ19DdXN0b21CdG4nXCIgW2Rpc2FibGVkXT1cIiFjdXN0b21CdG5FbmFibGVkXCI+e3tjdXN0b21CdG5MYWJlbH19PC9idXR0b24+XG4gICAgICA8L2Rpdj5cbiAgICAgIDxkaXYgKm5nSWY9XCJjb25maWcuZXhwb3J0VG9FeGNlbCB8fCBjb25maWcuZXhwb3J0VG9IVE1MXCIgY2xhc3M9XCJjb2wtc20tMTIgdGV4dC1jZW50ZXJcIj5cbiAgICAgICAgPHNwYW4+RXhwb3J0IG9ubHkgdmlzaWJsZSBkYXRhOiZuYnNwO1xuICAgICAgICAgIDxpbnB1dCB0eXBlPVwiY2hlY2tib3hcIiBbY2hlY2tlZF09XCJleHBvcnRWaXNpYmxlT25seVwiIChjbGljayk9XCJ0b2dnbGVFeHBvcnRWaXNpYmxlT25seSgpXCIgaWQ9XCJleHBvcnRWaXNpYmxlT25seUNoZWNrYm94XCIvPlxuICAgICAgICA8L3NwYW4+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG4gIDwhLS0gUGFnaW5hdGlvbiAtLT5cbiAgPGRpdiAqbmdJZj1cIiFjb25maWcuZGlzYWJsZVBhZ2luYXRpb25cIiBjbGFzcz1cImNvbC1zbS00IGQtZmxleCBqdXN0aWZ5LWNvbnRlbnQtZW5kXCI+XG4gICAgPHBhZ2luYXRpb24gKm5nSWY9XCJwYWdpbmF0aW9uT25cIiBjbGFzcz1cInBhZ2luYXRpb24tc21cIiBbdG90YWxJdGVtc109XCJwYWdlSW5mby5sZW5ndGhcIiBbaXRlbXNQZXJQYWdlXT1cInBhZ2VJbmZvLml0ZW1zUGVyUGFnZVwiIFttYXhTaXplXT1cInBhZ2VJbmZvLm1heFNpemVcIlxuICAgICAgWyhuZ01vZGVsKV09XCJjdXJyZW50UGFnZVwiIG5hbWU9XCJjdXJyZW50VGFibGVQYWdlXCJcbiAgICAgIFtib3VuZGFyeUxpbmtzXT1cInRydWVcIiBbcm90YXRlXT1cImZhbHNlXCIgKHBhZ2VDaGFuZ2VkKT1cIm9uUGFnZUNoYW5nZWQoJGV2ZW50KVwiIChudW1QYWdlcyk9XCJwYWdlSW5mby5udW1QYWdlcyA9ICRldmVudFwiPlxuICAgIDwvcGFnaW5hdGlvbj5cbiAgICAmbmJzcDtcbiAgICA8YnV0dG9uIChjbGljayk9XCJ0b2dnbGVQYWdpbmdhdGlvbigpXCIgdHlwZT1cImJ1dHRvblwiIGNsYXNzPVwiYnRuIGJ0bi1kZWZhdWx0IGJ0bi1zbSBtci0xXCI+e3sgcGFnaW5hdGlvbk9uID8gJ1Nob3cgQWxsIFJvd3MnIDogJ1Jlc3RvcmUgUGFnaW5hdGlvbid9fTwvYnV0dG9uPlxuICA8L2Rpdj5cbjwvZGl2PlxuPC9mb3JtPiJdfQ==