@pepperi-addons/ngx-lib 0.3.15-beta.60 → 0.3.15-beta.61

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 (690) hide show
  1. package/address/address.component.d.ts +27 -27
  2. package/address/address.module.d.ts +2 -2
  3. package/address/pepperi-addons-ngx-lib-address.d.ts +4 -4
  4. package/address/public-api.d.ts +2 -2
  5. package/attachment/attachment.component.d.ts +82 -82
  6. package/attachment/attachment.module.d.ts +2 -2
  7. package/attachment/pepperi-addons-ngx-lib-attachment.d.ts +4 -4
  8. package/attachment/public-api.d.ts +2 -2
  9. package/bread-crumbs/bread-crumbs.component.d.ts +23 -23
  10. package/bread-crumbs/bread-crumbs.model.d.ts +11 -11
  11. package/bread-crumbs/bread-crumbs.module.d.ts +5 -5
  12. package/bread-crumbs/pepperi-addons-ngx-lib-bread-crumbs.d.ts +4 -4
  13. package/bread-crumbs/public-api.d.ts +3 -3
  14. package/bundles/pepperi-addons-ngx-lib-address.umd.js +124 -124
  15. package/bundles/pepperi-addons-ngx-lib-attachment.umd.js +247 -247
  16. package/bundles/pepperi-addons-ngx-lib-bread-crumbs.umd.js +121 -121
  17. package/bundles/pepperi-addons-ngx-lib-button.umd.js +158 -158
  18. package/bundles/pepperi-addons-ngx-lib-carousel.umd.js +788 -788
  19. package/bundles/pepperi-addons-ngx-lib-checkbox.umd.js +192 -192
  20. package/bundles/pepperi-addons-ngx-lib-color.umd.js +302 -302
  21. package/bundles/pepperi-addons-ngx-lib-date.umd.js +667 -667
  22. package/bundles/pepperi-addons-ngx-lib-dialog.umd.js +519 -519
  23. package/bundles/pepperi-addons-ngx-lib-draggable-items.umd.js +151 -151
  24. package/bundles/pepperi-addons-ngx-lib-field-title.umd.js +57 -57
  25. package/bundles/pepperi-addons-ngx-lib-files-uploader.umd.js +260 -260
  26. package/bundles/pepperi-addons-ngx-lib-form.umd.js +3253 -3253
  27. package/bundles/pepperi-addons-ngx-lib-group-buttons.umd.js +87 -87
  28. package/bundles/pepperi-addons-ngx-lib-icon.umd.js +681 -681
  29. package/bundles/pepperi-addons-ngx-lib-image.umd.js +324 -324
  30. package/bundles/pepperi-addons-ngx-lib-images-filmstrip.umd.js +360 -360
  31. package/bundles/pepperi-addons-ngx-lib-link.umd.js +388 -388
  32. package/bundles/pepperi-addons-ngx-lib-list.umd.js +3191 -3191
  33. package/bundles/pepperi-addons-ngx-lib-menu.umd.js +646 -646
  34. package/bundles/pepperi-addons-ngx-lib-page-layout.umd.js +60 -60
  35. package/bundles/pepperi-addons-ngx-lib-profile-data-views-list.umd.js +543 -543
  36. package/bundles/pepperi-addons-ngx-lib-quantity-selector.umd.js +930 -930
  37. package/bundles/pepperi-addons-ngx-lib-query-builder.umd.js +1181 -1181
  38. package/bundles/pepperi-addons-ngx-lib-remote-loader.umd.js +683 -683
  39. package/bundles/pepperi-addons-ngx-lib-rich-html-textarea.umd.js +275 -275
  40. package/bundles/pepperi-addons-ngx-lib-search.umd.js +326 -326
  41. package/bundles/pepperi-addons-ngx-lib-select.umd.js +587 -587
  42. package/bundles/pepperi-addons-ngx-lib-separator.umd.js +79 -79
  43. package/bundles/pepperi-addons-ngx-lib-side-bar.umd.js +165 -165
  44. package/bundles/pepperi-addons-ngx-lib-signature.umd.js +286 -286
  45. package/bundles/pepperi-addons-ngx-lib-size-detector.umd.js +113 -113
  46. package/bundles/pepperi-addons-ngx-lib-slider.umd.js +124 -124
  47. package/bundles/pepperi-addons-ngx-lib-smart-filters.umd.js +1974 -1974
  48. package/bundles/pepperi-addons-ngx-lib-snack-bar.umd.js +148 -148
  49. package/bundles/pepperi-addons-ngx-lib-textarea.umd.js +211 -211
  50. package/bundles/pepperi-addons-ngx-lib-textbox-icon.umd.js +80 -80
  51. package/bundles/pepperi-addons-ngx-lib-textbox.umd.js +553 -553
  52. package/bundles/pepperi-addons-ngx-lib-top-bar.umd.js +129 -129
  53. package/bundles/pepperi-addons-ngx-lib.umd.js +4963 -4962
  54. package/bundles/pepperi-addons-ngx-lib.umd.js.map +1 -1
  55. package/button/button.component.d.ts +99 -99
  56. package/button/button.model.d.ts +14 -14
  57. package/button/button.module.d.ts +2 -2
  58. package/button/pepperi-addons-ngx-lib-button.d.ts +4 -4
  59. package/button/public-api.d.ts +3 -3
  60. package/carousel/carousel-item.directive.d.ts +9 -9
  61. package/carousel/carousel.component.d.ts +145 -145
  62. package/carousel/carousel.module.d.ts +2 -2
  63. package/carousel/pepperi-addons-ngx-lib-carousel.d.ts +4 -4
  64. package/carousel/public-api.d.ts +3 -3
  65. package/checkbox/checkbox.component.d.ts +47 -47
  66. package/checkbox/checkbox.module.d.ts +5 -5
  67. package/checkbox/pepperi-addons-ngx-lib-checkbox.d.ts +4 -4
  68. package/checkbox/public-api.d.ts +2 -2
  69. package/color/color-picker.component.d.ts +54 -54
  70. package/color/color.component.d.ts +27 -27
  71. package/color/color.model.d.ts +1 -1
  72. package/color/color.module.d.ts +5 -5
  73. package/color/pepperi-addons-ngx-lib-color.d.ts +5 -5
  74. package/color/public-api.d.ts +3 -3
  75. package/core/clipboard/clipboard.directive.d.ts +2 -2
  76. package/core/clipboard/clipboard.service.d.ts +2 -2
  77. package/core/clipboard/index.d.ts +1 -1
  78. package/core/clipboard/public-api.d.ts +2 -2
  79. package/core/common/directives/auto-width.directive.d.ts +16 -16
  80. package/core/common/directives/button-blur.directive.d.ts +6 -6
  81. package/core/common/directives/button-loader.directive.d.ts +23 -23
  82. package/core/common/directives/data-qa.directive.d.ts +8 -8
  83. package/core/common/directives/index.d.ts +1 -1
  84. package/core/common/directives/menu-blur.directive.d.ts +7 -7
  85. package/core/common/directives/prevent-multi-click.directive.d.ts +4 -4
  86. package/core/common/directives/print.directive.d.ts +72 -72
  87. package/core/common/directives/public-api.d.ts +7 -7
  88. package/core/common/index.d.ts +1 -1
  89. package/core/common/model/index.d.ts +1 -1
  90. package/core/common/model/papi.model.d.ts +2 -2
  91. package/core/common/model/public-api.d.ts +3 -3
  92. package/core/common/model/utilities.model.d.ts +5 -5
  93. package/core/common/model/wapi.model.d.ts +200 -200
  94. package/core/common/pipes/common-pipes.d.ts +36 -36
  95. package/core/common/pipes/date-ago.pipe.d.ts +8 -8
  96. package/core/common/pipes/index.d.ts +1 -1
  97. package/core/common/pipes/public-api.d.ts +2 -2
  98. package/core/common/public-api.d.ts +4 -4
  99. package/core/common/services/addon.service.d.ts +38 -38
  100. package/core/common/services/color.service.d.ts +48 -48
  101. package/core/common/services/cookie.service.d.ts +50 -50
  102. package/core/common/services/data-convertor.service.d.ts +41 -41
  103. package/core/common/services/file.service.d.ts +24 -24
  104. package/core/common/services/index.d.ts +1 -1
  105. package/core/common/services/jwt-helper.service.d.ts +10 -10
  106. package/core/common/services/public-api.d.ts +11 -11
  107. package/core/common/services/session.service.d.ts +15 -15
  108. package/core/common/services/translate.service.d.ts +9 -9
  109. package/core/common/services/utilities.service.d.ts +34 -34
  110. package/core/common/services/validator.service.d.ts +28 -28
  111. package/core/common/services/window-scrolling.service.d.ts +7 -7
  112. package/core/customization/customization.model.d.ts +266 -266
  113. package/core/customization/customization.service.d.ts +156 -156
  114. package/core/customization/index.d.ts +1 -1
  115. package/core/customization/public-api.d.ts +2 -2
  116. package/core/http/index.d.ts +1 -1
  117. package/core/http/interceptors/error.interceptor.d.ts +5 -5
  118. package/core/http/interceptors/index.d.ts +11 -11
  119. package/core/http/interceptors/loader.interceptor.d.ts +8 -8
  120. package/core/http/interceptors/profiler.interceptor.d.ts +5 -5
  121. package/core/http/public-api.d.ts +2 -2
  122. package/core/http/services/http.service.d.ts +25 -25
  123. package/core/http/services/loader.service.d.ts +10 -10
  124. package/core/index.d.ts +1 -1
  125. package/core/layout/index.d.ts +1 -1
  126. package/core/layout/layout.service.d.ts +33 -33
  127. package/core/layout/public-api.d.ts +2 -2
  128. package/core/layout/rtl.directive.d.ts +16 -16
  129. package/core/portal/attach.directive.d.ts +10 -10
  130. package/core/portal/index.d.ts +1 -1
  131. package/core/portal/portal.service.d.ts +9 -9
  132. package/core/portal/public-api.d.ts +3 -3
  133. package/core/portal/target.directive.d.ts +9 -9
  134. package/core/public-api.d.ts +7 -7
  135. package/core/scroll-to/index.d.ts +1 -1
  136. package/core/scroll-to/public-api.d.ts +1 -1
  137. package/core/scroll-to/scroll-to.service.d.ts +8 -8
  138. package/date/date.component.d.ts +66 -66
  139. package/date/date.model.d.ts +26 -26
  140. package/date/date.module.d.ts +5 -5
  141. package/date/pepperi-addons-ngx-lib-date.d.ts +5 -5
  142. package/date/public-api.d.ts +2 -2
  143. package/dialog/default-dialog.component.d.ts +9 -9
  144. package/dialog/dialog.component.d.ts +10 -10
  145. package/dialog/dialog.model.d.ts +31 -31
  146. package/dialog/dialog.module.d.ts +5 -5
  147. package/dialog/dialog.service.d.ts +24 -24
  148. package/dialog/pepperi-addons-ngx-lib-dialog.d.ts +5 -5
  149. package/dialog/public-api.d.ts +4 -4
  150. package/draggable-items/draggable-item/draggable-item.component.d.ts +8 -8
  151. package/draggable-items/draggable-items.component.d.ts +33 -33
  152. package/draggable-items/draggable-items.model.d.ts +11 -11
  153. package/draggable-items/draggable-items.module.d.ts +5 -5
  154. package/draggable-items/pepperi-addons-ngx-lib-draggable-items.d.ts +4 -4
  155. package/draggable-items/public-api.d.ts +4 -4
  156. package/esm2015/address/address.component.js +96 -96
  157. package/esm2015/address/address.module.js +30 -30
  158. package/esm2015/address/pepperi-addons-ngx-lib-address.js +4 -4
  159. package/esm2015/address/public-api.js +5 -5
  160. package/esm2015/attachment/attachment.component.js +208 -208
  161. package/esm2015/attachment/attachment.module.js +28 -28
  162. package/esm2015/attachment/pepperi-addons-ngx-lib-attachment.js +4 -4
  163. package/esm2015/attachment/public-api.js +5 -5
  164. package/esm2015/bread-crumbs/bread-crumbs.component.js +78 -78
  165. package/esm2015/bread-crumbs/bread-crumbs.model.js +6 -6
  166. package/esm2015/bread-crumbs/bread-crumbs.module.js +34 -34
  167. package/esm2015/bread-crumbs/pepperi-addons-ngx-lib-bread-crumbs.js +4 -4
  168. package/esm2015/bread-crumbs/public-api.js +6 -6
  169. package/esm2015/button/button.component.js +127 -127
  170. package/esm2015/button/button.model.js +5 -5
  171. package/esm2015/button/button.module.js +26 -26
  172. package/esm2015/button/pepperi-addons-ngx-lib-button.js +4 -4
  173. package/esm2015/button/public-api.js +6 -6
  174. package/esm2015/carousel/carousel-item.directive.js +26 -26
  175. package/esm2015/carousel/carousel.component.js +699 -699
  176. package/esm2015/carousel/carousel.module.js +11 -11
  177. package/esm2015/carousel/pepperi-addons-ngx-lib-carousel.js +4 -4
  178. package/esm2015/carousel/public-api.js +7 -7
  179. package/esm2015/checkbox/checkbox.component.js +151 -151
  180. package/esm2015/checkbox/checkbox.module.js +39 -39
  181. package/esm2015/checkbox/pepperi-addons-ngx-lib-checkbox.js +4 -4
  182. package/esm2015/checkbox/public-api.js +5 -5
  183. package/esm2015/color/color-picker.component.js +197 -197
  184. package/esm2015/color/color.component.js +77 -77
  185. package/esm2015/color/color.model.js +1 -1
  186. package/esm2015/color/color.module.js +57 -57
  187. package/esm2015/color/pepperi-addons-ngx-lib-color.js +5 -5
  188. package/esm2015/color/public-api.js +6 -6
  189. package/esm2015/core/clipboard/clipboard.directive.js +19 -19
  190. package/esm2015/core/clipboard/clipboard.service.js +11 -11
  191. package/esm2015/core/clipboard/index.js +4 -4
  192. package/esm2015/core/clipboard/public-api.js +5 -5
  193. package/esm2015/core/common/directives/auto-width.directive.js +77 -77
  194. package/esm2015/core/common/directives/button-blur.directive.js +22 -22
  195. package/esm2015/core/common/directives/button-loader.directive.js +102 -102
  196. package/esm2015/core/common/directives/data-qa.directive.js +22 -22
  197. package/esm2015/core/common/directives/index.js +4 -4
  198. package/esm2015/core/common/directives/menu-blur.directive.js +28 -28
  199. package/esm2015/core/common/directives/prevent-multi-click.directive.js +21 -21
  200. package/esm2015/core/common/directives/print.directive.js +134 -134
  201. package/esm2015/core/common/directives/public-api.js +11 -11
  202. package/esm2015/core/common/index.js +4 -4
  203. package/esm2015/core/common/model/index.js +4 -4
  204. package/esm2015/core/common/model/papi.model.js +2 -2
  205. package/esm2015/core/common/model/public-api.js +6 -6
  206. package/esm2015/core/common/model/utilities.model.js +56 -56
  207. package/esm2015/core/common/model/wapi.model.js +155 -155
  208. package/esm2015/core/common/pipes/common-pipes.js +141 -141
  209. package/esm2015/core/common/pipes/date-ago.pipe.js +44 -44
  210. package/esm2015/core/common/pipes/index.js +4 -4
  211. package/esm2015/core/common/pipes/public-api.js +5 -5
  212. package/esm2015/core/common/public-api.js +7 -7
  213. package/esm2015/core/common/services/addon.service.js +160 -160
  214. package/esm2015/core/common/services/color.service.js +356 -356
  215. package/esm2015/core/common/services/cookie.service.js +147 -147
  216. package/esm2015/core/common/services/data-convertor.service.js +117 -117
  217. package/esm2015/core/common/services/file.service.js +211 -211
  218. package/esm2015/core/common/services/index.js +4 -4
  219. package/esm2015/core/common/services/jwt-helper.service.js +103 -103
  220. package/esm2015/core/common/services/public-api.js +14 -14
  221. package/esm2015/core/common/services/session.service.js +72 -72
  222. package/esm2015/core/common/services/translate.service.js +47 -47
  223. package/esm2015/core/common/services/utilities.service.js +253 -253
  224. package/esm2015/core/common/services/validator.service.js +272 -272
  225. package/esm2015/core/common/services/window-scrolling.service.js +30 -30
  226. package/esm2015/core/customization/customization.model.js +290 -290
  227. package/esm2015/core/customization/customization.service.js +777 -777
  228. package/esm2015/core/customization/index.js +4 -4
  229. package/esm2015/core/customization/public-api.js +5 -5
  230. package/esm2015/core/http/index.js +4 -4
  231. package/esm2015/core/http/interceptors/error.interceptor.js +23 -23
  232. package/esm2015/core/http/interceptors/index.js +23 -23
  233. package/esm2015/core/http/interceptors/loader.interceptor.js +31 -31
  234. package/esm2015/core/http/interceptors/profiler.interceptor.js +28 -28
  235. package/esm2015/core/http/public-api.js +5 -5
  236. package/esm2015/core/http/services/http.service.js +160 -160
  237. package/esm2015/core/http/services/loader.service.js +48 -48
  238. package/esm2015/core/index.js +4 -4
  239. package/esm2015/core/layout/index.js +4 -4
  240. package/esm2015/core/layout/layout.service.js +168 -168
  241. package/esm2015/core/layout/public-api.js +5 -5
  242. package/esm2015/core/layout/rtl.directive.js +46 -46
  243. package/esm2015/core/portal/attach.directive.js +26 -26
  244. package/esm2015/core/portal/index.js +4 -4
  245. package/esm2015/core/portal/portal.service.js +34 -34
  246. package/esm2015/core/portal/public-api.js +6 -6
  247. package/esm2015/core/portal/target.directive.js +23 -23
  248. package/esm2015/core/public-api.js +10 -10
  249. package/esm2015/core/scroll-to/index.js +4 -4
  250. package/esm2015/core/scroll-to/public-api.js +5 -5
  251. package/esm2015/core/scroll-to/scroll-to.service.js +81 -81
  252. package/esm2015/date/date.component.js +251 -251
  253. package/esm2015/date/date.model.js +44 -44
  254. package/esm2015/date/date.module.js +50 -50
  255. package/esm2015/date/pepperi-addons-ngx-lib-date.js +5 -5
  256. package/esm2015/date/public-api.js +5 -5
  257. package/esm2015/dialog/default-dialog.component.js +31 -31
  258. package/esm2015/dialog/dialog.component.js +28 -28
  259. package/esm2015/dialog/dialog.model.js +34 -34
  260. package/esm2015/dialog/dialog.module.js +39 -39
  261. package/esm2015/dialog/dialog.service.js +87 -87
  262. package/esm2015/dialog/pepperi-addons-ngx-lib-dialog.js +5 -5
  263. package/esm2015/dialog/public-api.js +7 -7
  264. package/esm2015/draggable-items/draggable-item/draggable-item.component.js +24 -24
  265. package/esm2015/draggable-items/draggable-items.component.js +91 -91
  266. package/esm2015/draggable-items/draggable-items.model.js +1 -1
  267. package/esm2015/draggable-items/draggable-items.module.js +42 -42
  268. package/esm2015/draggable-items/pepperi-addons-ngx-lib-draggable-items.js +4 -4
  269. package/esm2015/draggable-items/public-api.js +7 -7
  270. package/esm2015/field-title/field-title.component.js +31 -31
  271. package/esm2015/field-title/field-title.module.js +31 -31
  272. package/esm2015/field-title/pepperi-addons-ngx-lib-field-title.js +4 -4
  273. package/esm2015/field-title/public-api.js +5 -5
  274. package/esm2015/files-uploader/files-uploader.component.js +220 -220
  275. package/esm2015/files-uploader/files-uploader.module.js +49 -49
  276. package/esm2015/files-uploader/pepperi-addons-ngx-lib-files-uploader.js +4 -4
  277. package/esm2015/files-uploader/public-api.js +5 -5
  278. package/esm2015/form/field-generator.component.js +121 -121
  279. package/esm2015/form/form.component.js +1200 -1200
  280. package/esm2015/form/form.model.js +1 -1
  281. package/esm2015/form/form.module.js +107 -107
  282. package/esm2015/form/indicators.component.js +20 -20
  283. package/esm2015/form/internal-button.component.js +165 -165
  284. package/esm2015/form/internal-carusel.component.js +115 -115
  285. package/esm2015/form/internal-carusel.service.js +31 -31
  286. package/esm2015/form/internal-list.component.js +494 -494
  287. package/esm2015/form/internal-menu.component.js +54 -54
  288. package/esm2015/form/internal-page.component.js +350 -350
  289. package/esm2015/form/internal-page.service.js +120 -120
  290. package/esm2015/form/pepperi-addons-ngx-lib-form.js +13 -13
  291. package/esm2015/form/public-api.js +6 -6
  292. package/esm2015/group-buttons/group-buttons.component.js +57 -57
  293. package/esm2015/group-buttons/group-buttons.module.js +37 -37
  294. package/esm2015/group-buttons/pepperi-addons-ngx-lib-group-buttons.js +4 -4
  295. package/esm2015/group-buttons/public-api.js +5 -5
  296. package/esm2015/icon/icon-generated-all.model.js +100 -100
  297. package/esm2015/icon/icon-generated.model.js +389 -389
  298. package/esm2015/icon/icon-registry.service.js +22 -22
  299. package/esm2015/icon/icon.component.js +124 -124
  300. package/esm2015/icon/icon.module.js +14 -14
  301. package/esm2015/icon/icon.service.js +31 -31
  302. package/esm2015/icon/pepperi-addons-ngx-lib-icon.js +4 -4
  303. package/esm2015/icon/public-api.js +10 -10
  304. package/esm2015/image/image.component.js +228 -228
  305. package/esm2015/image/image.module.js +48 -48
  306. package/esm2015/image/image.service.js +56 -56
  307. package/esm2015/image/pepperi-addons-ngx-lib-image.js +4 -4
  308. package/esm2015/image/public-api.js +6 -6
  309. package/esm2015/images-filmstrip/images-filmstrip.component.js +316 -316
  310. package/esm2015/images-filmstrip/images-filmstrip.module.js +51 -51
  311. package/esm2015/images-filmstrip/pepperi-addons-ngx-lib-images-filmstrip.js +4 -4
  312. package/esm2015/images-filmstrip/public-api.js +5 -5
  313. package/esm2015/link/link.component.js +315 -315
  314. package/esm2015/link/link.module.js +50 -50
  315. package/esm2015/link/link.pipes.js +13 -13
  316. package/esm2015/link/pepperi-addons-ngx-lib-link.js +5 -5
  317. package/esm2015/link/public-api.js +5 -5
  318. package/esm2015/list/list-actions.component.js +35 -35
  319. package/esm2015/list/list-carousel.component.js +94 -94
  320. package/esm2015/list/list-chooser.component.js +57 -57
  321. package/esm2015/list/list-pager.component.js +112 -112
  322. package/esm2015/list/list-sorting.component.js +54 -54
  323. package/esm2015/list/list-total.component.js +23 -23
  324. package/esm2015/list/list-views.component.js +71 -71
  325. package/esm2015/list/list.component.js +1127 -1127
  326. package/esm2015/list/list.model.js +3 -3
  327. package/esm2015/list/list.module.js +87 -87
  328. package/esm2015/list/list.pipes.js +39 -39
  329. package/esm2015/list/pepperi-addons-ngx-lib-list.js +6 -6
  330. package/esm2015/list/public-api.js +14 -14
  331. package/esm2015/list/virtual-scroller.js +1018 -1018
  332. package/esm2015/menu/menu-item.component.js +102 -102
  333. package/esm2015/menu/menu.component.js +173 -173
  334. package/esm2015/menu/menu.model.js +18 -18
  335. package/esm2015/menu/menu.module.js +39 -39
  336. package/esm2015/menu/pepperi-addons-ngx-lib-menu.js +5 -5
  337. package/esm2015/menu/public-api.js +6 -6
  338. package/esm2015/ngx-lib.module.js +96 -94
  339. package/esm2015/page-layout/page-layout.component.js +41 -41
  340. package/esm2015/page-layout/page-layout.module.js +20 -20
  341. package/esm2015/page-layout/pepperi-addons-ngx-lib-page-layout.js +4 -4
  342. package/esm2015/page-layout/public-api.js +5 -5
  343. package/esm2015/pepperi-addons-ngx-lib.js +8 -8
  344. package/esm2015/profile-data-views-list/pepperi-addons-ngx-lib-profile-data-views-list.js +4 -4
  345. package/esm2015/profile-data-views-list/profile-data-view/profile-data-view.component.js +38 -38
  346. package/esm2015/profile-data-views-list/profile-data-views-card/profile-data-views-card.component.js +59 -59
  347. package/esm2015/profile-data-views-list/profile-data-views-list.component.js +86 -86
  348. package/esm2015/profile-data-views-list/profile-data-views-list.model.js +1 -1
  349. package/esm2015/profile-data-views-list/profile-data-views-list.module.js +56 -56
  350. package/esm2015/profile-data-views-list/public-api.js +8 -8
  351. package/esm2015/public-api.js +5 -5
  352. package/esm2015/quantity-selector/pepperi-addons-ngx-lib-quantity-selector.js +6 -6
  353. package/esm2015/quantity-selector/public-api.js +5 -5
  354. package/esm2015/quantity-selector/quantity-selector-validation.directive.js +43 -43
  355. package/esm2015/quantity-selector/quantity-selector.component.js +472 -472
  356. package/esm2015/quantity-selector/quantity-selector.module.js +52 -52
  357. package/esm2015/quantity-selector/quantity-selector.pipes.js +18 -18
  358. package/esm2015/query-builder/common/model/field.js +1 -1
  359. package/esm2015/query-builder/common/model/filter.js +1 -1
  360. package/esm2015/query-builder/common/model/legacy.js +1 -1
  361. package/esm2015/query-builder/common/model/operator-unit.js +41 -41
  362. package/esm2015/query-builder/common/model/operator.js +265 -265
  363. package/esm2015/query-builder/common/model/structure.js +1 -1
  364. package/esm2015/query-builder/common/model/type-map.js +26 -26
  365. package/esm2015/query-builder/common/model/type.js +5 -5
  366. package/esm2015/query-builder/common/services/output-query.service.js +112 -112
  367. package/esm2015/query-builder/common/services/query-structure.service.js +228 -228
  368. package/esm2015/query-builder/common/services/type-convertor.service.js +39 -39
  369. package/esm2015/query-builder/pepperi-addons-ngx-lib-query-builder.js +9 -9
  370. package/esm2015/query-builder/public-api.js +8 -8
  371. package/esm2015/query-builder/query-builder-item/query-builder-item.component.js +117 -117
  372. package/esm2015/query-builder/query-builder-section/query-builder-section.component.js +63 -63
  373. package/esm2015/query-builder/query-builder.component.js +107 -107
  374. package/esm2015/query-builder/query-builder.module.js +34 -34
  375. package/esm2015/query-builder/query-builder.service.js +102 -102
  376. package/esm2015/remote-loader/addon-block-loader.component.js +77 -77
  377. package/esm2015/remote-loader/addon-block-loader.service.js +63 -63
  378. package/esm2015/remote-loader/pepperi-addons-ngx-lib-remote-loader.js +4 -4
  379. package/esm2015/remote-loader/public-api.js +9 -9
  380. package/esm2015/remote-loader/remote-loader.component.js +114 -114
  381. package/esm2015/remote-loader/remote-loader.model.js +1 -1
  382. package/esm2015/remote-loader/remote-loader.module.js +37 -37
  383. package/esm2015/remote-loader/remote-loader.service.js +65 -65
  384. package/esm2015/rich-html-textarea/pepperi-addons-ngx-lib-rich-html-textarea.js +4 -4
  385. package/esm2015/rich-html-textarea/public-api.js +5 -5
  386. package/esm2015/rich-html-textarea/rich-html-textarea.component.js +219 -219
  387. package/esm2015/rich-html-textarea/rich-html-textarea.module.js +56 -56
  388. package/esm2015/search/pepperi-addons-ngx-lib-search.js +4 -4
  389. package/esm2015/search/public-api.js +6 -6
  390. package/esm2015/search/search.component.js +273 -273
  391. package/esm2015/search/search.model.js +1 -1
  392. package/esm2015/search/search.module.js +44 -44
  393. package/esm2015/select/pepperi-addons-ngx-lib-select.js +4 -4
  394. package/esm2015/select/public-api.js +5 -5
  395. package/esm2015/select/select.component.js +219 -219
  396. package/esm2015/select/select.module.js +42 -42
  397. package/esm2015/separator/pepperi-addons-ngx-lib-separator.js +4 -4
  398. package/esm2015/separator/public-api.js +5 -5
  399. package/esm2015/separator/separator.component.js +62 -62
  400. package/esm2015/separator/separator.module.js +12 -12
  401. package/esm2015/side-bar/pepperi-addons-ngx-lib-side-bar.js +4 -4
  402. package/esm2015/side-bar/public-api.js +6 -6
  403. package/esm2015/side-bar/side-bar.component.js +132 -132
  404. package/esm2015/side-bar/side-bar.model.js +1 -1
  405. package/esm2015/side-bar/side-bar.module.js +33 -33
  406. package/esm2015/signature/pepperi-addons-ngx-lib-signature.js +4 -4
  407. package/esm2015/signature/public-api.js +5 -5
  408. package/esm2015/signature/signature.component.js +233 -233
  409. package/esm2015/signature/signature.module.js +54 -54
  410. package/esm2015/size-detector/pepperi-addons-ngx-lib-size-detector.js +4 -4
  411. package/esm2015/size-detector/public-api.js +5 -5
  412. package/esm2015/size-detector/size-detector.component.js +88 -88
  413. package/esm2015/size-detector/size-detector.module.js +21 -21
  414. package/esm2015/slider/pepperi-addons-ngx-lib-slider.js +4 -4
  415. package/esm2015/slider/public-api.js +5 -5
  416. package/esm2015/slider/slider.component.js +95 -95
  417. package/esm2015/slider/slider.module.js +24 -24
  418. package/esm2015/smart-filters/boolean-filter/boolean-filter.component.js +70 -70
  419. package/esm2015/smart-filters/common/filter-actions.component.js +25 -25
  420. package/esm2015/smart-filters/common/model/base-filter-component.js +291 -291
  421. package/esm2015/smart-filters/common/model/creator.js +75 -75
  422. package/esm2015/smart-filters/common/model/field.js +116 -116
  423. package/esm2015/smart-filters/common/model/filter.js +1 -1
  424. package/esm2015/smart-filters/common/model/operator.js +270 -270
  425. package/esm2015/smart-filters/common/model/type.js +1 -1
  426. package/esm2015/smart-filters/date-filter/date-filter.component.js +163 -163
  427. package/esm2015/smart-filters/multi-select-filter/multi-select-filter.component.js +190 -190
  428. package/esm2015/smart-filters/number-filter/number-filter.component.js +109 -109
  429. package/esm2015/smart-filters/pepperi-addons-ngx-lib-smart-filters.js +4 -4
  430. package/esm2015/smart-filters/public-api.js +18 -18
  431. package/esm2015/smart-filters/smart-filters.component.js +129 -129
  432. package/esm2015/smart-filters/smart-filters.module.js +90 -90
  433. package/esm2015/smart-filters/text-filter/text-filter.component.js +85 -85
  434. package/esm2015/snack-bar/default-snack-bar.component.js +27 -27
  435. package/esm2015/snack-bar/pepperi-addons-ngx-lib-snack-bar.js +5 -5
  436. package/esm2015/snack-bar/public-api.js +7 -7
  437. package/esm2015/snack-bar/snack-bar.component.js +25 -25
  438. package/esm2015/snack-bar/snack-bar.model.js +6 -6
  439. package/esm2015/snack-bar/snack-bar.module.js +41 -41
  440. package/esm2015/snack-bar/snack-bar.service.js +62 -62
  441. package/esm2015/textarea/pepperi-addons-ngx-lib-textarea.js +4 -4
  442. package/esm2015/textarea/public-api.js +5 -5
  443. package/esm2015/textarea/textarea.component.js +160 -160
  444. package/esm2015/textarea/textarea.module.js +50 -50
  445. package/esm2015/textbox/pepperi-addons-ngx-lib-textbox.js +5 -5
  446. package/esm2015/textbox/public-api.js +5 -5
  447. package/esm2015/textbox/textbox-validation.directive.js +85 -85
  448. package/esm2015/textbox/textbox.component.js +411 -411
  449. package/esm2015/textbox/textbox.module.js +44 -44
  450. package/esm2015/textbox-icon/pepperi-addons-ngx-lib-textbox-icon.js +4 -4
  451. package/esm2015/textbox-icon/public-api.js +5 -5
  452. package/esm2015/textbox-icon/textbox-icon.component.js +40 -40
  453. package/esm2015/textbox-icon/textbox-icon.module.js +46 -46
  454. package/esm2015/top-bar/pepperi-addons-ngx-lib-top-bar.js +4 -4
  455. package/esm2015/top-bar/public-api.js +6 -6
  456. package/esm2015/top-bar/top-bar.component.js +98 -98
  457. package/esm2015/top-bar/top-bar.model.js +1 -1
  458. package/esm2015/top-bar/top-bar.module.js +40 -40
  459. package/fesm2015/pepperi-addons-ngx-lib-address.js +116 -116
  460. package/fesm2015/pepperi-addons-ngx-lib-attachment.js +227 -227
  461. package/fesm2015/pepperi-addons-ngx-lib-bread-crumbs.js +109 -109
  462. package/fesm2015/pepperi-addons-ngx-lib-button.js +149 -149
  463. package/fesm2015/pepperi-addons-ngx-lib-carousel.js +731 -731
  464. package/fesm2015/pepperi-addons-ngx-lib-checkbox.js +178 -178
  465. package/fesm2015/pepperi-addons-ngx-lib-color.js +298 -298
  466. package/fesm2015/pepperi-addons-ngx-lib-date.js +320 -320
  467. package/fesm2015/pepperi-addons-ngx-lib-dialog.js +192 -192
  468. package/fesm2015/pepperi-addons-ngx-lib-draggable-items.js +143 -143
  469. package/fesm2015/pepperi-addons-ngx-lib-field-title.js +55 -55
  470. package/fesm2015/pepperi-addons-ngx-lib-files-uploader.js +252 -252
  471. package/fesm2015/pepperi-addons-ngx-lib-form.js +2697 -2697
  472. package/fesm2015/pepperi-addons-ngx-lib-group-buttons.js +84 -84
  473. package/fesm2015/pepperi-addons-ngx-lib-icon.js +662 -662
  474. package/fesm2015/pepperi-addons-ngx-lib-image.js +308 -308
  475. package/fesm2015/pepperi-addons-ngx-lib-images-filmstrip.js +347 -347
  476. package/fesm2015/pepperi-addons-ngx-lib-link.js +358 -358
  477. package/fesm2015/pepperi-addons-ngx-lib-list.js +2661 -2661
  478. package/fesm2015/pepperi-addons-ngx-lib-menu.js +314 -314
  479. package/fesm2015/pepperi-addons-ngx-lib-page-layout.js +55 -55
  480. package/fesm2015/pepperi-addons-ngx-lib-profile-data-views-list.js +219 -219
  481. package/fesm2015/pepperi-addons-ngx-lib-quantity-selector.js +561 -561
  482. package/fesm2015/pepperi-addons-ngx-lib-query-builder.js +1087 -1087
  483. package/fesm2015/pepperi-addons-ngx-lib-remote-loader.js +327 -327
  484. package/fesm2015/pepperi-addons-ngx-lib-rich-html-textarea.js +256 -256
  485. package/fesm2015/pepperi-addons-ngx-lib-search.js +301 -301
  486. package/fesm2015/pepperi-addons-ngx-lib-select.js +249 -249
  487. package/fesm2015/pepperi-addons-ngx-lib-separator.js +71 -71
  488. package/fesm2015/pepperi-addons-ngx-lib-side-bar.js +156 -156
  489. package/fesm2015/pepperi-addons-ngx-lib-signature.js +270 -270
  490. package/fesm2015/pepperi-addons-ngx-lib-size-detector.js +103 -103
  491. package/fesm2015/pepperi-addons-ngx-lib-slider.js +112 -112
  492. package/fesm2015/pepperi-addons-ngx-lib-smart-filters.js +1539 -1539
  493. package/fesm2015/pepperi-addons-ngx-lib-snack-bar.js +137 -137
  494. package/fesm2015/pepperi-addons-ngx-lib-textarea.js +194 -194
  495. package/fesm2015/pepperi-addons-ngx-lib-textbox-icon.js +78 -78
  496. package/fesm2015/pepperi-addons-ngx-lib-textbox.js +521 -521
  497. package/fesm2015/pepperi-addons-ngx-lib-top-bar.js +125 -125
  498. package/fesm2015/pepperi-addons-ngx-lib.js +4320 -4319
  499. package/fesm2015/pepperi-addons-ngx-lib.js.map +1 -1
  500. package/field-title/field-title.component.d.ts +11 -11
  501. package/field-title/field-title.module.d.ts +5 -5
  502. package/field-title/pepperi-addons-ngx-lib-field-title.d.ts +4 -4
  503. package/field-title/public-api.d.ts +2 -2
  504. package/files-uploader/files-uploader.component.d.ts +53 -53
  505. package/files-uploader/files-uploader.module.d.ts +5 -5
  506. package/files-uploader/pepperi-addons-ngx-lib-files-uploader.d.ts +4 -4
  507. package/files-uploader/public-api.d.ts +2 -2
  508. package/form/field-generator.component.d.ts +36 -36
  509. package/form/form.component.d.ts +90 -90
  510. package/form/form.model.d.ts +20 -20
  511. package/form/form.module.d.ts +5 -5
  512. package/form/indicators.component.d.ts +7 -7
  513. package/form/internal-button.component.d.ts +39 -39
  514. package/form/internal-carusel.component.d.ts +38 -38
  515. package/form/internal-carusel.service.d.ts +7 -7
  516. package/form/internal-list.component.d.ts +92 -92
  517. package/form/internal-menu.component.d.ts +16 -16
  518. package/form/internal-page.component.d.ts +72 -72
  519. package/form/internal-page.service.d.ts +19 -19
  520. package/form/pepperi-addons-ngx-lib-form.d.ts +13 -13
  521. package/form/public-api.d.ts +3 -3
  522. package/group-buttons/group-buttons.component.d.ts +20 -20
  523. package/group-buttons/group-buttons.module.d.ts +5 -5
  524. package/group-buttons/pepperi-addons-ngx-lib-group-buttons.d.ts +4 -4
  525. package/group-buttons/public-api.d.ts +2 -2
  526. package/icon/icon-generated-all.model.d.ts +99 -99
  527. package/icon/icon-generated.model.d.ts +394 -394
  528. package/icon/icon-registry.service.d.ts +6 -6
  529. package/icon/icon.component.d.ts +46 -46
  530. package/icon/icon.module.d.ts +2 -2
  531. package/icon/icon.service.d.ts +10 -10
  532. package/icon/pepperi-addons-ngx-lib-icon.d.ts +4 -4
  533. package/icon/public-api.d.ts +6 -6
  534. package/image/image.component.d.ts +63 -63
  535. package/image/image.module.d.ts +5 -5
  536. package/image/image.service.d.ts +11 -11
  537. package/image/pepperi-addons-ngx-lib-image.d.ts +4 -4
  538. package/image/public-api.d.ts +3 -3
  539. package/images-filmstrip/images-filmstrip.component.d.ts +84 -84
  540. package/images-filmstrip/images-filmstrip.module.d.ts +5 -5
  541. package/images-filmstrip/pepperi-addons-ngx-lib-images-filmstrip.d.ts +4 -4
  542. package/images-filmstrip/public-api.d.ts +2 -2
  543. package/link/link.component.d.ts +131 -131
  544. package/link/link.module.d.ts +5 -5
  545. package/link/link.pipes.d.ts +4 -4
  546. package/link/pepperi-addons-ngx-lib-link.d.ts +5 -5
  547. package/link/public-api.d.ts +2 -2
  548. package/list/list-actions.component.d.ts +14 -14
  549. package/list/list-carousel.component.d.ts +36 -36
  550. package/list/list-chooser.component.d.ts +25 -25
  551. package/list/list-pager.component.d.ts +35 -35
  552. package/list/list-sorting.component.d.ts +26 -26
  553. package/list/list-total.component.d.ts +7 -7
  554. package/list/list-views.component.d.ts +31 -31
  555. package/list/list.component.d.ts +161 -161
  556. package/list/list.model.d.ts +31 -31
  557. package/list/list.module.d.ts +5 -5
  558. package/list/list.pipes.d.ts +11 -11
  559. package/list/pepperi-addons-ngx-lib-list.d.ts +6 -6
  560. package/list/public-api.d.ts +10 -10
  561. package/list/virtual-scroller.d.ts +176 -176
  562. package/menu/menu-item.component.d.ts +25 -25
  563. package/menu/menu.component.d.ts +43 -43
  564. package/menu/menu.model.d.ts +25 -25
  565. package/menu/menu.module.d.ts +5 -5
  566. package/menu/pepperi-addons-ngx-lib-menu.d.ts +5 -5
  567. package/menu/public-api.d.ts +3 -3
  568. package/ngx-lib.module.d.ts +2 -2
  569. package/package.json +1 -1
  570. package/page-layout/page-layout.component.d.ts +16 -16
  571. package/page-layout/page-layout.module.d.ts +2 -2
  572. package/page-layout/pepperi-addons-ngx-lib-page-layout.d.ts +4 -4
  573. package/page-layout/public-api.d.ts +2 -2
  574. package/pepperi-addons-ngx-lib.d.ts +8 -8
  575. package/pepperi-addons-ngx-lib.metadata.json +1 -1
  576. package/profile-data-views-list/pepperi-addons-ngx-lib-profile-data-views-list.d.ts +4 -4
  577. package/profile-data-views-list/profile-data-view/profile-data-view.component.d.ts +15 -15
  578. package/profile-data-views-list/profile-data-views-card/profile-data-views-card.component.d.ts +21 -21
  579. package/profile-data-views-list/profile-data-views-list.component.d.ts +32 -32
  580. package/profile-data-views-list/profile-data-views-list.model.d.ts +18 -18
  581. package/profile-data-views-list/profile-data-views-list.module.d.ts +5 -5
  582. package/profile-data-views-list/public-api.d.ts +5 -5
  583. package/public-api.d.ts +2 -2
  584. package/quantity-selector/pepperi-addons-ngx-lib-quantity-selector.d.ts +6 -6
  585. package/quantity-selector/public-api.d.ts +2 -2
  586. package/quantity-selector/quantity-selector-validation.directive.d.ts +13 -13
  587. package/quantity-selector/quantity-selector.component.d.ts +98 -98
  588. package/quantity-selector/quantity-selector.module.d.ts +5 -5
  589. package/quantity-selector/quantity-selector.pipes.d.ts +4 -4
  590. package/query-builder/common/model/field.d.ts +8 -8
  591. package/query-builder/common/model/filter.d.ts +6 -6
  592. package/query-builder/common/model/legacy.d.ts +29 -29
  593. package/query-builder/common/model/operator-unit.d.ts +13 -13
  594. package/query-builder/common/model/operator.d.ts +21 -21
  595. package/query-builder/common/model/structure.d.ts +4 -4
  596. package/query-builder/common/model/type-map.d.ts +12 -12
  597. package/query-builder/common/model/type.d.ts +4 -4
  598. package/query-builder/common/services/output-query.service.d.ts +44 -44
  599. package/query-builder/common/services/query-structure.service.d.ts +78 -78
  600. package/query-builder/common/services/type-convertor.service.d.ts +10 -10
  601. package/query-builder/pepperi-addons-ngx-lib-query-builder.d.ts +9 -9
  602. package/query-builder/public-api.d.ts +5 -5
  603. package/query-builder/query-builder-item/query-builder-item.component.d.ts +38 -38
  604. package/query-builder/query-builder-section/query-builder-section.component.d.ts +27 -27
  605. package/query-builder/query-builder.component.d.ts +36 -36
  606. package/query-builder/query-builder.module.d.ts +2 -2
  607. package/query-builder/query-builder.service.d.ts +27 -27
  608. package/remote-loader/addon-block-loader.component.d.ts +29 -29
  609. package/remote-loader/addon-block-loader.service.d.ts +13 -13
  610. package/remote-loader/pepperi-addons-ngx-lib-remote-loader.d.ts +4 -4
  611. package/remote-loader/public-api.d.ts +6 -6
  612. package/remote-loader/remote-loader.component.d.ts +24 -24
  613. package/remote-loader/remote-loader.model.d.ts +36 -36
  614. package/remote-loader/remote-loader.module.d.ts +2 -2
  615. package/remote-loader/remote-loader.service.d.ts +14 -14
  616. package/rich-html-textarea/pepperi-addons-ngx-lib-rich-html-textarea.d.ts +4 -4
  617. package/rich-html-textarea/public-api.d.ts +2 -2
  618. package/rich-html-textarea/rich-html-textarea.component.d.ts +75 -75
  619. package/rich-html-textarea/rich-html-textarea.module.d.ts +5 -5
  620. package/search/pepperi-addons-ngx-lib-search.d.ts +4 -4
  621. package/search/public-api.d.ts +3 -3
  622. package/search/search.component.d.ts +61 -61
  623. package/search/search.model.d.ts +14 -14
  624. package/search/search.module.d.ts +5 -5
  625. package/select/pepperi-addons-ngx-lib-select.d.ts +4 -4
  626. package/select/public-api.d.ts +2 -2
  627. package/select/select.component.d.ts +52 -52
  628. package/select/select.module.d.ts +5 -5
  629. package/separator/pepperi-addons-ngx-lib-separator.d.ts +4 -4
  630. package/separator/public-api.d.ts +2 -2
  631. package/separator/separator.component.d.ts +19 -19
  632. package/separator/separator.module.d.ts +2 -2
  633. package/side-bar/pepperi-addons-ngx-lib-side-bar.d.ts +4 -4
  634. package/side-bar/public-api.d.ts +3 -3
  635. package/side-bar/side-bar.component.d.ts +39 -39
  636. package/side-bar/side-bar.model.d.ts +4 -4
  637. package/side-bar/side-bar.module.d.ts +5 -5
  638. package/signature/pepperi-addons-ngx-lib-signature.d.ts +4 -4
  639. package/signature/public-api.d.ts +2 -2
  640. package/signature/signature.component.d.ts +65 -65
  641. package/signature/signature.module.d.ts +5 -5
  642. package/size-detector/pepperi-addons-ngx-lib-size-detector.d.ts +4 -4
  643. package/size-detector/public-api.d.ts +2 -2
  644. package/size-detector/size-detector.component.d.ts +26 -26
  645. package/size-detector/size-detector.module.d.ts +2 -2
  646. package/slider/pepperi-addons-ngx-lib-slider.d.ts +4 -4
  647. package/slider/public-api.d.ts +2 -2
  648. package/slider/slider.component.d.ts +36 -36
  649. package/slider/slider.module.d.ts +2 -2
  650. package/smart-filters/boolean-filter/boolean-filter.component.d.ts +25 -25
  651. package/smart-filters/common/filter-actions.component.d.ts +9 -9
  652. package/smart-filters/common/model/base-filter-component.d.ts +70 -70
  653. package/smart-filters/common/model/creator.d.ts +6 -6
  654. package/smart-filters/common/model/field.d.ts +69 -69
  655. package/smart-filters/common/model/filter.d.ts +11 -11
  656. package/smart-filters/common/model/operator.d.ts +51 -51
  657. package/smart-filters/common/model/type.d.ts +4 -4
  658. package/smart-filters/date-filter/date-filter.component.d.ts +56 -56
  659. package/smart-filters/multi-select-filter/multi-select-filter.component.d.ts +53 -53
  660. package/smart-filters/number-filter/number-filter.component.d.ts +48 -48
  661. package/smart-filters/pepperi-addons-ngx-lib-smart-filters.d.ts +4 -4
  662. package/smart-filters/public-api.d.ts +14 -14
  663. package/smart-filters/smart-filters.component.d.ts +32 -32
  664. package/smart-filters/smart-filters.module.d.ts +5 -5
  665. package/smart-filters/text-filter/text-filter.component.d.ts +25 -25
  666. package/snack-bar/default-snack-bar.component.d.ts +10 -10
  667. package/snack-bar/pepperi-addons-ngx-lib-snack-bar.d.ts +5 -5
  668. package/snack-bar/public-api.d.ts +4 -4
  669. package/snack-bar/snack-bar.component.d.ts +9 -9
  670. package/snack-bar/snack-bar.model.d.ts +8 -8
  671. package/snack-bar/snack-bar.module.d.ts +5 -5
  672. package/snack-bar/snack-bar.service.d.ts +21 -21
  673. package/textarea/pepperi-addons-ngx-lib-textarea.d.ts +4 -4
  674. package/textarea/public-api.d.ts +2 -2
  675. package/textarea/textarea.component.d.ts +51 -51
  676. package/textarea/textarea.module.d.ts +5 -5
  677. package/textbox/pepperi-addons-ngx-lib-textbox.d.ts +5 -5
  678. package/textbox/public-api.d.ts +2 -2
  679. package/textbox/textbox-validation.directive.d.ts +18 -18
  680. package/textbox/textbox.component.d.ts +141 -141
  681. package/textbox/textbox.module.d.ts +5 -5
  682. package/textbox-icon/pepperi-addons-ngx-lib-textbox-icon.d.ts +4 -4
  683. package/textbox-icon/public-api.d.ts +2 -2
  684. package/textbox-icon/textbox-icon.component.d.ts +10 -10
  685. package/textbox-icon/textbox-icon.module.d.ts +5 -5
  686. package/top-bar/pepperi-addons-ngx-lib-top-bar.d.ts +4 -4
  687. package/top-bar/public-api.d.ts +3 -3
  688. package/top-bar/top-bar.component.d.ts +36 -36
  689. package/top-bar/top-bar.model.d.ts +4 -4
  690. package/top-bar/top-bar.module.d.ts +5 -5
@@ -1,1201 +1,1201 @@
1
- import { Component, ChangeDetectionStrategy, Input, KeyValueDiffers, Output, EventEmitter, } from '@angular/core';
2
- import { FormBuilder, Validators, } from '@angular/forms';
3
- import { TranslateService } from '@ngx-translate/core';
4
- import { PepDialogService, PepDialogData, } from '@pepperi-addons/ngx-lib/dialog';
5
- import { FIELD_TYPE, PepCustomizationService, PepLayoutService, PepTextboxField, PepSelectField, PepInternalMenuField, PepQuantitySelectorField, PepAddressField, PepIndicatorsField, PepInternalPageField, PepInternalCaruselField, PepInternalButtonField, PepAttachmentField, PepSignatureField, PepImageField, PepImagesField, PepLinkField, PepTextareaField, PepRichHtmlTextareaField, PepDateField, PepCheckboxField, PepSeparatorField, PepPlaceholderField, X_ALIGNMENT_TYPE, Y_ALIGNMENT_TYPE, DEFAULT_VERTICAL_ALIGNMENT, DEFAULT_HORIZONTAL_ALIGNMENT, } from '@pepperi-addons/ngx-lib';
6
- import { BehaviorSubject } from 'rxjs';
7
- export class PepFormComponent {
8
- // eventServiceSub: Subscription;
9
- // public jsonLib = JSON;
10
- constructor(dialogService, customizationService, layoutService, fb, differs, translate) {
11
- this.dialogService = dialogService;
12
- this.customizationService = customizationService;
13
- this.layoutService = layoutService;
14
- this.fb = fb;
15
- this.translate = translate;
16
- this.isInternal = true;
17
- this.isReport = false;
18
- this.lockEvents = false;
19
- this.canEditObject = true;
20
- this._data = null;
21
- this.isActive = false;
22
- this.layoutType = 'card';
23
- // @Input() listType = '';
24
- this.objectId = '0';
25
- this.parentId = '0';
26
- this.searchCode = '0';
27
- this.showTitle = true;
28
- this.firstFieldAsLink = false;
29
- this.checkForChanges = null;
30
- this.valueChange = new EventEmitter();
31
- this.formValidationChange = new EventEmitter();
32
- this.fieldClick = new EventEmitter();
33
- this.internalFormFieldClick = new EventEmitter();
34
- this.internalFormFieldChange = new EventEmitter();
35
- this.isLocked = false;
36
- // payLoad = '';
37
- this.rows = [];
38
- this.fields = [];
39
- this._fieldsSubject = new BehaviorSubject([]);
40
- this.columns = 1;
41
- this.hasMenuFloatingOnOtherField = false;
42
- this.indicatorsDataField = null;
43
- this._shouldReloadForm = false;
44
- // store the initial value to compare with
45
- this.differ = differs.find({}).create();
46
- }
47
- set data(value) {
48
- const shouldReload = this.shouldReloadForm || !this._data;
49
- this._data = value;
50
- if (shouldReload) {
51
- this._shouldReloadForm = false;
52
- this.initForm();
53
- }
54
- else {
55
- this.updateForm();
56
- }
57
- }
58
- get data() {
59
- return this._data;
60
- }
61
- set lockFields(value) {
62
- this.isLocked = value;
63
- }
64
- get fields$() {
65
- return this._fieldsSubject.asObservable();
66
- }
67
- get shouldReloadForm() {
68
- return this._shouldReloadForm;
69
- }
70
- convertXAlignToHorizontalAlign(xAlign) {
71
- let res = DEFAULT_HORIZONTAL_ALIGNMENT;
72
- if (xAlign === X_ALIGNMENT_TYPE.None ||
73
- xAlign === X_ALIGNMENT_TYPE.Left) {
74
- res = 'left';
75
- }
76
- else if (xAlign === X_ALIGNMENT_TYPE.Right) {
77
- res = 'right';
78
- }
79
- else {
80
- res = 'center';
81
- }
82
- return res;
83
- }
84
- convertYAlignToVerticalAlign(yAlign) {
85
- let res = DEFAULT_VERTICAL_ALIGNMENT;
86
- if (yAlign === Y_ALIGNMENT_TYPE.None ||
87
- yAlign === Y_ALIGNMENT_TYPE.Top) {
88
- res = 'top';
89
- }
90
- else if (yAlign === Y_ALIGNMENT_TYPE.Bottom) {
91
- res = 'bottom';
92
- }
93
- else {
94
- res = 'middle';
95
- }
96
- return res;
97
- }
98
- convertOptionalValues(optionalValues) {
99
- if (optionalValues && optionalValues.length > 0) {
100
- return optionalValues.map((ov) => {
101
- return { key: ov.Key, value: ov.Value };
102
- });
103
- }
104
- else {
105
- return [];
106
- }
107
- }
108
- convertAddressFields(controlField, addressFields, canEditObject) {
109
- const fields = [];
110
- addressFields.forEach((field) => {
111
- let customField;
112
- const placeholder = field.ApiName;
113
- if (field.ApiName.toLowerCase().indexOf('street') >= 0) {
114
- customField = new PepTextboxField({
115
- key: field.ApiName,
116
- label: field.ApiName,
117
- type: 'text',
118
- placeholder,
119
- readonly: !canEditObject,
120
- disabled: !field.Enabled || !canEditObject,
121
- hidden: false,
122
- mandatory: false,
123
- value: field.Value,
124
- formattedValue: field.FormattedValue,
125
- row: 0,
126
- rowSpan: 1,
127
- col: 0,
128
- colSpan: 2,
129
- xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
130
- yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
131
- order: 0,
132
- });
133
- }
134
- else if (field.ApiName.toLowerCase().indexOf('city') >= 0) {
135
- customField = new PepTextboxField({
136
- key: field.ApiName,
137
- label: field.ApiName,
138
- type: 'text',
139
- placeholder,
140
- readonly: !canEditObject,
141
- disabled: !field.Enabled || !canEditObject,
142
- hidden: false,
143
- mandatory: false,
144
- value: field.Value,
145
- formattedValue: field.FormattedValue,
146
- row: 0,
147
- rowSpan: 1,
148
- col: 2,
149
- colSpan: 1,
150
- xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
151
- yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
152
- order: 1,
153
- });
154
- }
155
- else if (field.ApiName.toLowerCase().indexOf('state') >= 0) {
156
- customField = new PepSelectField({
157
- key: field.ApiName,
158
- label: field.ApiName,
159
- placeholder,
160
- options: this.convertOptionalValues(field.OptionalValues),
161
- readonly: !canEditObject,
162
- disabled: !field.Enabled || !canEditObject,
163
- hidden: false,
164
- mandatory: false,
165
- value: field.Value,
166
- formattedValue: field.FormattedValue,
167
- row: 1,
168
- rowSpan: 1,
169
- col: 0,
170
- colSpan: 1,
171
- xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
172
- yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
173
- order: 2,
174
- });
175
- }
176
- else if (field.ApiName.toLowerCase().indexOf('zipcode') >= 0) {
177
- customField = new PepTextboxField({
178
- key: field.ApiName,
179
- label: field.ApiName,
180
- type: 'text',
181
- placeholder,
182
- readonly: !canEditObject,
183
- disabled: !field.Enabled || !canEditObject,
184
- hidden: false,
185
- mandatory: false,
186
- value: field.Value,
187
- formattedValue: field.FormattedValue,
188
- row: 1,
189
- rowSpan: 1,
190
- col: 1,
191
- colSpan: 1,
192
- xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
193
- yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
194
- order: 3,
195
- });
196
- }
197
- else if (field.ApiName.toLowerCase().indexOf('country') >= 0) {
198
- customField = new PepSelectField({
199
- key: field.ApiName,
200
- label: field.ApiName,
201
- placeholder,
202
- options: this.convertOptionalValues(field.OptionalValues),
203
- readonly: !canEditObject,
204
- disabled: !field.Enabled || !canEditObject,
205
- hidden: false,
206
- mandatory: false,
207
- value: field.Value,
208
- formattedValue: field.FormattedValue,
209
- row: 2,
210
- rowSpan: 1,
211
- col: 2,
212
- colSpan: 1,
213
- xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
214
- yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
215
- order: 4,
216
- });
217
- }
218
- fields.push(customField);
219
- });
220
- return fields.sort((n1, n2) => n1.order > n2.order ? 1 : n1.order < n2.order ? -1 : 0);
221
- }
222
- isMatrixField(apiNameToCheck) {
223
- return apiNameToCheck.indexOf('Matrix') >= 0;
224
- }
225
- doesFieldHavaFloatingField(controlField, floatingField) {
226
- let hasFloatingField = false;
227
- if (floatingField.Layout.Y >= controlField.Layout.Y &&
228
- floatingField.Layout.Y <
229
- controlField.Layout.Y + controlField.Layout.Height &&
230
- floatingField.Layout.X >= controlField.Layout.X &&
231
- floatingField.Layout.X <
232
- controlField.Layout.X + controlField.Layout.Width) {
233
- hasFloatingField = true;
234
- }
235
- return hasFloatingField;
236
- }
237
- getOptionsForCustomField(controlField, dataField, canEditObject) {
238
- if (!controlField || !dataField) {
239
- return;
240
- }
241
- const placeholder = controlField.ReadOnly || !canEditObject ? '' : controlField.Title;
242
- let fieldProperties = {
243
- key: controlField.ApiName,
244
- label: controlField.Title,
245
- accessory: dataField.Accessory,
246
- placeholder,
247
- readonly: controlField.ReadOnly || !canEditObject,
248
- disabled: !dataField.Enabled || !canEditObject,
249
- hidden: controlField.Hidden,
250
- mandatory: controlField.Mandatory,
251
- value: dataField.Value,
252
- formattedValue: dataField.FormattedValue,
253
- additionalValue: dataField.AdditionalValue,
254
- row: controlField.Layout.Y,
255
- rowSpan: controlField.Layout.Height,
256
- col: controlField.Layout.X,
257
- colSpan: controlField.Layout.Width,
258
- xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
259
- yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
260
- options: this.convertOptionalValues(dataField.OptionalValues),
261
- groupFields: undefined,
262
- maxFieldCharacters: controlField.MaxFieldCharacters,
263
- minValue: controlField.MinValue,
264
- maxValue: controlField.MaxValue,
265
- // hasMenu: hasMenu,
266
- // hasCampaign: hasCampaign,
267
- // hasIndicators: hasIndicators,
268
- textColor: dataField.TextColor,
269
- visible: dataField.Visible,
270
- };
271
- if (dataField.AdditionalProps) {
272
- fieldProperties = Object.assign(Object.assign({}, fieldProperties), dataField.AdditionalProps);
273
- }
274
- return fieldProperties;
275
- }
276
- convertToCustomField(controlField, dataField, canEditObject, menuField, hasCampaignField, indicatorsField, objectId, parentId, searchCode) {
277
- let customField;
278
- const options = this.getOptionsForCustomField(controlField, dataField, canEditObject);
279
- if (controlField.ApiName === 'ObjectMenu') {
280
- options.type = 'menu';
281
- customField = new PepInternalMenuField(options);
282
- }
283
- else if (controlField.FieldType === FIELD_TYPE.NumberRealQuantitySelector ||
284
- controlField.FieldType ===
285
- FIELD_TYPE.NumberIntegerQuantitySelector ||
286
- controlField.ApiName === 'QuantitySelector' ||
287
- controlField.ApiName === 'UnitsQuantity' ||
288
- controlField.ApiName.indexOf('size_') === 0) {
289
- if (dataField.FieldType === FIELD_TYPE.InternalLink) {
290
- options.type = 'button';
291
- }
292
- else if (dataField.FieldType === FIELD_TYPE.Package) {
293
- options.type = 'packageButton';
294
- }
295
- else if (dataField.FieldType === FIELD_TYPE.NumberRealQuantitySelector ||
296
- dataField.FieldType === FIELD_TYPE.NumberReal) {
297
- options.type = 'qs';
298
- options.allowDecimal = true;
299
- }
300
- else if (dataField.FieldType ===
301
- FIELD_TYPE.NumberIntegerQuantitySelector ||
302
- dataField.FieldType === FIELD_TYPE.NumberInteger) {
303
- options.type = 'qs';
304
- options.allowDecimal = false;
305
- }
306
- else if (dataField.FieldType === FIELD_TYPE.NumberIntegerForMatrix) {
307
- options.type = 'qsForMatrix';
308
- options.allowDecimal = false;
309
- }
310
- else if (dataField.FieldType === FIELD_TYPE.NumberRealForMatrix) {
311
- options.type = 'qsForMatrix';
312
- options.allowDecimal = true;
313
- }
314
- options.notificationInfo = dataField.NotificationInfo;
315
- customField = new PepQuantitySelectorField(options);
316
- }
317
- else {
318
- // HACK: need to remove this..
319
- if (dataField.FieldType === FIELD_TYPE.Indicators &&
320
- this.isMatrixField(dataField.ApiName)) {
321
- dataField.FieldType = FIELD_TYPE.InternalPage;
322
- }
323
- switch (dataField.FieldType) {
324
- case FIELD_TYPE.Address: {
325
- const canEditGroupObject = controlField.ReadOnly
326
- ? false
327
- : canEditObject;
328
- options.groupFields = this.convertAddressFields(controlField, dataField.GroupFields, canEditGroupObject);
329
- customField = new PepAddressField(options);
330
- break;
331
- }
332
- case FIELD_TYPE.Indicators: {
333
- // options['type'] = 'indicators'; // Not needed this is PepIndicatorsField.
334
- customField = new PepIndicatorsField(options);
335
- break;
336
- }
337
- case FIELD_TYPE.InternalPage: {
338
- if (this.isMatrixField(controlField.ApiName)) {
339
- options.rowSpan = controlField.Layout.Height;
340
- options.objectId = objectId;
341
- options.parentId = parentId;
342
- options.searchCode = searchCode;
343
- customField = new PepInternalPageField(options);
344
- }
345
- else {
346
- // Not supported
347
- }
348
- break;
349
- }
350
- case FIELD_TYPE.RelatedObjectsCards: {
351
- options.rowSpan = controlField.Layout.Height;
352
- options.searchCode = searchCode;
353
- options.pageInfo = dataField.UIPageInfo;
354
- customField = new PepInternalCaruselField(options);
355
- break;
356
- }
357
- case FIELD_TYPE.Link: {
358
- options.type = 'link';
359
- customField = new PepLinkField(options);
360
- break;
361
- }
362
- case FIELD_TYPE.InternalLink:
363
- case FIELD_TYPE.Button: {
364
- options.type = 'button';
365
- customField = new PepInternalButtonField(options);
366
- break;
367
- }
368
- case FIELD_TYPE.Attachment: {
369
- // options.type = 'attachment';
370
- customField = new PepAttachmentField(options);
371
- break;
372
- }
373
- case FIELD_TYPE.Signature: {
374
- // options.type = 'signature';
375
- customField = new PepSignatureField(options);
376
- break;
377
- }
378
- case FIELD_TYPE.Image:
379
- case FIELD_TYPE.ImageURL: {
380
- // options.type = 'image';
381
- options.menuField =
382
- menuField &&
383
- this.doesFieldHavaFloatingField(controlField, menuField)
384
- ? menuField
385
- : null;
386
- options.hasCampaignField =
387
- hasCampaignField &&
388
- this.doesFieldHavaFloatingField(controlField, hasCampaignField)
389
- ? hasCampaignField
390
- : null;
391
- options.indicatorsField =
392
- indicatorsField &&
393
- this.doesFieldHavaFloatingField(controlField, indicatorsField)
394
- ? indicatorsField
395
- : null;
396
- customField = new PepImageField(options);
397
- break;
398
- }
399
- case FIELD_TYPE.Images: {
400
- // options.type = 'images';
401
- customField = new PepImagesField(options);
402
- break;
403
- }
404
- case FIELD_TYPE.Email: {
405
- options.type = 'email';
406
- customField = new PepLinkField(options);
407
- break;
408
- }
409
- case FIELD_TYPE.Phone: {
410
- options.type = 'phone';
411
- customField = new PepLinkField(options);
412
- break;
413
- }
414
- case FIELD_TYPE.Duration: {
415
- options.type = 'duration';
416
- customField = new PepTextboxField(options);
417
- break;
418
- }
419
- case FIELD_TYPE.Default:
420
- case FIELD_TYPE.TextBox:
421
- case FIELD_TYPE.LimitedLengthTextBox:
422
- case FIELD_TYPE.TextHeader:
423
- case FIELD_TYPE.CalculatedString:
424
- case FIELD_TYPE.MapDataString: {
425
- customField = new PepTextboxField(options);
426
- break;
427
- }
428
- case FIELD_TYPE.TextArea: {
429
- customField = new PepTextareaField(options);
430
- break;
431
- }
432
- case FIELD_TYPE.RichTextHTML: {
433
- customField = new PepRichHtmlTextareaField(options);
434
- break;
435
- }
436
- case FIELD_TYPE.Date:
437
- case FIELD_TYPE.LimitedDate:
438
- case FIELD_TYPE.CalculatedDate:
439
- case FIELD_TYPE.DateAndTime: {
440
- options.type =
441
- dataField.FieldType === FIELD_TYPE.DateAndTime
442
- ? 'datetime'
443
- : 'date';
444
- customField = new PepDateField(options);
445
- break;
446
- }
447
- case FIELD_TYPE.NumberInteger:
448
- case FIELD_TYPE.CalculatedInt:
449
- case FIELD_TYPE.MapDataInt: {
450
- options.type = 'int';
451
- customField = new PepTextboxField(options);
452
- break;
453
- }
454
- case FIELD_TYPE.Percentage: {
455
- options.type = 'percentage';
456
- customField = new PepTextboxField(options);
457
- break;
458
- }
459
- case FIELD_TYPE.Currency: {
460
- options.type = 'currency';
461
- customField = new PepTextboxField(options);
462
- break;
463
- }
464
- case FIELD_TYPE.NumberReal:
465
- case FIELD_TYPE.CalculatedReal:
466
- case FIELD_TYPE.MapDataReal:
467
- case FIELD_TYPE.Sum:
468
- case FIELD_TYPE.Totals: {
469
- options.type = 'real';
470
- customField = new PepTextboxField(options);
471
- break;
472
- }
473
- case FIELD_TYPE.Boolean:
474
- case FIELD_TYPE.CalculatedBool: {
475
- customField = new PepCheckboxField(options);
476
- break;
477
- }
478
- case FIELD_TYPE.BooleanText: {
479
- options.type = 'booleanText';
480
- customField = new PepCheckboxField(options);
481
- break;
482
- }
483
- case FIELD_TYPE.ComboBox:
484
- case FIELD_TYPE.EmptyComboBox:
485
- case FIELD_TYPE.MapDataDropDown: {
486
- // options.type = 'select';
487
- customField = new PepSelectField(options);
488
- break;
489
- }
490
- case FIELD_TYPE.MultiTickBox:
491
- case FIELD_TYPE.MultiTickBoxToComboBox:
492
- case FIELD_TYPE.EmptyMultiTickBox: {
493
- options.type = 'multi';
494
- customField = new PepSelectField(options);
495
- break;
496
- }
497
- case FIELD_TYPE.GuidReferenceType: {
498
- options.type = 'reference';
499
- options.referenceObjectType = dataField.ReferenceObjectType;
500
- options.referenceObjectSubType =
501
- dataField.ReferenceObjectSubType;
502
- options.referenceObjectInternalType =
503
- dataField.ReferenceObjectInternalType;
504
- customField = new PepInternalButtonField(options);
505
- break;
506
- }
507
- case FIELD_TYPE.ListOfObjects: {
508
- options.type = 'listofobjects';
509
- customField = new PepInternalButtonField(options);
510
- break;
511
- }
512
- case FIELD_TYPE.Separator: {
513
- customField = new PepSeparatorField(options);
514
- break;
515
- }
516
- /*
517
- case FIELD_TYPE.Images: return that.field(value);
518
- */
519
- case FIELD_TYPE.NumberRealQuantitySelector:
520
- case FIELD_TYPE.NumberIntegerQuantitySelector: {
521
- options.type = 'qs';
522
- options.allowDecimal =
523
- dataField.FieldType ===
524
- FIELD_TYPE.NumberRealQuantitySelector;
525
- options.notificationInfo = dataField.NotificationInfo;
526
- customField = new PepQuantitySelectorField(options);
527
- break;
528
- }
529
- case FIELD_TYPE.Package: {
530
- options.type = 'packageButton';
531
- options.notificationInfo = dataField.NotificationInfo;
532
- customField = new PepQuantitySelectorField(options);
533
- break;
534
- }
535
- }
536
- }
537
- if (!customField) {
538
- options.label = controlField.ApiName + ' is not supported!!!';
539
- customField = new PepSeparatorField(options);
540
- }
541
- return customField;
542
- }
543
- getFieldFormattedValue(field) {
544
- let fieldFormattedValue = field.formattedValue;
545
- // Fix for the custom check box component.
546
- if (field.controlType === 'checkbox') {
547
- fieldFormattedValue = fieldFormattedValue === 'true';
548
- }
549
- // Fix for the custom button component.
550
- if (field.controlType === 'button') {
551
- fieldFormattedValue =
552
- fieldFormattedValue === '0' ? '' : fieldFormattedValue;
553
- }
554
- return fieldFormattedValue;
555
- }
556
- toControlGroup(fields) {
557
- const group = {};
558
- if (fields && fields.length > 0) {
559
- fields.forEach((field) => {
560
- if (field.groupFields && field.groupFields.length > 0) {
561
- const subGroup = {};
562
- field.groupFields.forEach((groupField) => {
563
- if (groupField.mandatory &&
564
- !field.readonly &&
565
- !field.disabled) {
566
- subGroup[groupField.key] = [
567
- {
568
- value: groupField.formattedValue || '',
569
- disabled: field.readonly ||
570
- field.disabled ||
571
- groupField.disabled,
572
- },
573
- [Validators.required],
574
- ];
575
- }
576
- else {
577
- subGroup[groupField.key] = [
578
- {
579
- value: groupField.formattedValue || '',
580
- disabled: field.readonly ||
581
- field.disabled ||
582
- groupField.disabled,
583
- },
584
- [Validators.nullValidator],
585
- ];
586
- }
587
- });
588
- group[field.key] = this.fb.group(subGroup);
589
- }
590
- else {
591
- const validators = field.getValidators();
592
- const fieldFormattedValue = this.getFieldFormattedValue(field);
593
- group[field.key] = [
594
- {
595
- value: fieldFormattedValue || '',
596
- disabled: field.disabled,
597
- },
598
- validators,
599
- ];
600
- }
601
- });
602
- }
603
- return this.fb.group(group);
604
- }
605
- createBaseField(uiControlField, dataField) {
606
- const customField = this.convertToCustomField(uiControlField, dataField, this.canEditObject, this.menuDataField, this.hasCampaignDataField, this.indicatorsDataField, this.objectId, this.parentId, this.searchCode);
607
- return customField;
608
- }
609
- showFormValidationMessage() {
610
- const fields = this.fields;
611
- let emptyMandatoryFieldsMsg = '';
612
- let notValidFieldsMsg = '';
613
- // for (let i: number = 0; i < fields.length; i++) {
614
- // let field = fields[i];
615
- for (const field of fields) {
616
- const formControl = this.form && this.form.get(field.key);
617
- if (formControl) {
618
- // Mandatory is empty.
619
- if (field.mandatory &&
620
- formControl.value.toString().trim().length === 0) {
621
- emptyMandatoryFieldsMsg +=
622
- '<li><small>' + field.label + '</small></li>';
623
- }
624
- else if (!field.disabled && !formControl.valid) {
625
- notValidFieldsMsg +=
626
- '<li><small>' + field.label + '</small></li>';
627
- }
628
- }
629
- }
630
- // Add the header message of the empty mandatory fields
631
- if (emptyMandatoryFieldsMsg.length > 0) {
632
- emptyMandatoryFieldsMsg =
633
- '<div>' +
634
- this.translate.instant('MESSAGES.ERROR_MANDATORY_FIELDS') +
635
- "</div><ul style='padding: 0 20px;'>" +
636
- emptyMandatoryFieldsMsg +
637
- '</ul><br/>';
638
- }
639
- // Add the header message of the empty mandatory fields
640
- if (notValidFieldsMsg.length > 0) {
641
- notValidFieldsMsg =
642
- '<div>' +
643
- this.translate.instant('MESSAGES.ERROR_INVALID_FIELDS') +
644
- "</div><ul style='padding: 0 20px;'>" +
645
- notValidFieldsMsg +
646
- '</ul>';
647
- }
648
- const title = this.translate.instant('MESSAGES.TITLE_NOTICE');
649
- const data = new PepDialogData({
650
- title,
651
- content: emptyMandatoryFieldsMsg + notValidFieldsMsg,
652
- });
653
- this.dialogService.openDefaultDialog(data);
654
- }
655
- ngOnInit() {
656
- const themeVars = this.customizationService.getThemeVariables();
657
- // convert rem to pixel
658
- const RemToPixel = 16;
659
- this.formGutterSize =
660
- this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.FORM_SPACEING_KEY) * RemToPixel;
661
- this.cardGutterSize =
662
- this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.CARD_SPACEING_KEY) * RemToPixel;
663
- }
664
- ngDoCheck() {
665
- const changes = this.differ.diff(this.data); // check for changes
666
- if (changes) {
667
- this.updateForm();
668
- this.checkForChanges = new Date();
669
- }
670
- }
671
- ngOnChanges(changes) {
672
- // if (changes.data && changes.data.currentValue) {
673
- // // Load changes
674
- // if (!this.shouldReloadForm && changes.data.previousValue) {
675
- // this.data = changes.data.currentValue;
676
- // this.updateForm();
677
- // } else {
678
- // this._shouldReloadForm = false;
679
- // this.initForm();
680
- // }
681
- // }
682
- // if (this.shouldReloadForm || !changes?.data?.previousValue) {
683
- // this._shouldReloadForm = false;
684
- // this.initForm();
685
- // this.checkForChanges = new Date();
686
- // }
687
- }
688
- ngOnDestroy() {
689
- //
690
- }
691
- getUiControlFields() {
692
- return this.layout ? this.layout.ControlFields : [];
693
- }
694
- initFieldsStructure(fields, maxRow) {
695
- const themeVars = this.customizationService.getThemeVariables();
696
- // Set form row height.
697
- if (this.layoutType === 'card') {
698
- const cardFieldHeight = this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.CARD_FIELD_HEIGHT_KEY);
699
- this.rowHeight = cardFieldHeight;
700
- }
701
- else {
702
- const rowFieldHeight = this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.FORM_FIELD_HEIGHT_KEY);
703
- const rowFieldTitleHeight = this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.FORM_FIELD_TITLE_HEIGHT_KEY);
704
- this.rowHeight = rowFieldHeight + rowFieldTitleHeight;
705
- }
706
- // Create the fields structure (the fields must be sorted!!!).
707
- if (fields.length > 0) {
708
- // Init the layout.
709
- if (
710
- // this.layoutType === 'form' ||
711
- this.layoutType === 'table') {
712
- this.fields = fields;
713
- this._fieldsSubject.next(fields);
714
- this.rows = [];
715
- for (let i = 0; i <= maxRow; i++) {
716
- this.rows[i] = [];
717
- }
718
- // for (let i = 0; i < fields.length; i++) {
719
- // const field = fields[i]
720
- for (const field of fields) {
721
- this.rows[field.row].push(field);
722
- }
723
- }
724
- else {
725
- const doesfieldExistIn = new Array(maxRow);
726
- for (let i = 0; i < doesfieldExistIn.length; i++) {
727
- doesfieldExistIn[i] = new Array(this.columns);
728
- for (let j = 0; j < doesfieldExistIn[i].length; j++) {
729
- doesfieldExistIn[i][j] = false;
730
- }
731
- }
732
- // Run in squere (row - colspan, col - rowspan) and put true where it should.
733
- // for (let index = 0; index < fields.length; index++) {
734
- // const currentField = fields[index];
735
- for (const currentField of fields) {
736
- if (currentField.rowSpan > 1) {
737
- for (let row = currentField.row; row < currentField.row + currentField.rowSpan; row++) {
738
- if (currentField.colSpan > 1) {
739
- for (let col = currentField.col; col <
740
- currentField.col + currentField.colSpan; col++) {
741
- if (doesfieldExistIn.length > row &&
742
- doesfieldExistIn[0].length > col) {
743
- doesfieldExistIn[row][col] = true;
744
- }
745
- }
746
- }
747
- else {
748
- if (doesfieldExistIn.length > row &&
749
- doesfieldExistIn[0].length >
750
- currentField.col) {
751
- doesfieldExistIn[row][currentField.col] = true;
752
- }
753
- }
754
- }
755
- }
756
- else if (currentField.colSpan > 1) {
757
- for (let col = currentField.col; col < currentField.col + currentField.colSpan; col++) {
758
- if (doesfieldExistIn.length > currentField.row &&
759
- doesfieldExistIn[0].length > col) {
760
- doesfieldExistIn[currentField.row][col] = true;
761
- }
762
- }
763
- }
764
- else {
765
- if (doesfieldExistIn.length > currentField.row &&
766
- doesfieldExistIn[0].length > currentField.col) {
767
- doesfieldExistIn[currentField.row][currentField.col] = true;
768
- }
769
- }
770
- }
771
- // Create empty fields where doesfieldExistIn is false (For the md-grid-list UI Component).
772
- for (let i = 0; i < doesfieldExistIn.length; i++) {
773
- for (let j = 0; j < doesfieldExistIn[i].length; j++) {
774
- if (!doesfieldExistIn[i][j]) {
775
- // Create empty field and add it to the fields list.
776
- fields.push(new PepPlaceholderField({
777
- key: i + '_' + j,
778
- label: '',
779
- placeholder: '',
780
- readonly: false,
781
- disabled: false,
782
- hidden: false,
783
- mandatory: false,
784
- value: '',
785
- formattedValue: '',
786
- row: i,
787
- rowSpan: 1,
788
- col: j,
789
- colSpan: 1,
790
- order: 1,
791
- }));
792
- }
793
- }
794
- }
795
- // Sort the fields again.
796
- this.fields = fields.sort((f1, f2) => f1.row > f2.row
797
- ? 1
798
- : f1.row < f2.row
799
- ? -1
800
- : f1.col > f2.col
801
- ? 1
802
- : f1.col < f2.col
803
- ? -1
804
- : 0);
805
- this._fieldsSubject.next(fields);
806
- }
807
- }
808
- }
809
- setForm(isForUpdate = false) {
810
- var _a;
811
- let allFieldsAreReadOnly = true;
812
- if (!isForUpdate) {
813
- const fields = [];
814
- for (const currentField of this.fields) {
815
- // Add all fields except 'internalPage' (for children).
816
- if (currentField.controlType !== 'internalPage') {
817
- fields.push(currentField);
818
- }
819
- if (!currentField.readonly) {
820
- allFieldsAreReadOnly = false;
821
- }
822
- }
823
- this.form = this.toControlGroup(fields);
824
- }
825
- else {
826
- // Update form values if changed by calculated fields.
827
- for (let i = 0; i < this.fields.length; i++) {
828
- let currentField = this.fields[i];
829
- if (currentField.controlType === 'internalCarusel') {
830
- // Hack to override (update) the field.
831
- const uiControlField = this.getUiControlFields().find(cf => cf.ApiName === currentField.key);
832
- const dataField = this.data.Fields.find(df => df.ApiName === currentField.key);
833
- currentField = this.createBaseField(uiControlField, dataField);
834
- this._fieldsSubject.value[i] = currentField;
835
- }
836
- else if (currentField.controlType !== 'internalPage') {
837
- if (currentField.groupFields &&
838
- currentField.groupFields.length > 0) {
839
- // for (let j = 0; j < currentField.groupFields.length; j++) {
840
- // let currentGroupField = currentField.groupFields[j];
841
- for (const currentGroupField of currentField.groupFields) {
842
- const fieldFormattedValue = this.getFieldFormattedValue(currentGroupField);
843
- this.customizationService.updateFormField(this.form, currentGroupField, fieldFormattedValue, currentField);
844
- }
845
- }
846
- else {
847
- const fieldFormattedValue = this.getFieldFormattedValue(currentField);
848
- // this.form.controls[currentField.key].setValue(fieldFormattedValue);
849
- this.customizationService.updateFormField(this.form, currentField, fieldFormattedValue);
850
- }
851
- }
852
- if (!currentField.readonly) {
853
- allFieldsAreReadOnly = false;
854
- }
855
- }
856
- }
857
- let isFormValid = (_a = this.form) === null || _a === void 0 ? void 0 : _a.valid;
858
- // Change validation to true if all fields are read only.
859
- if (!isFormValid && allFieldsAreReadOnly) {
860
- isFormValid = true;
861
- }
862
- this.onFormValidationChanged(isFormValid);
863
- // Set it to false to enable all fields.
864
- if (this.isInternal && this.isLocked) {
865
- this.isLocked = false;
866
- }
867
- }
868
- initForm() {
869
- if (this.data && this.data.Fields) {
870
- const fields = this.convertCustomFields(this.getUiControlFields(), this.data.Fields);
871
- const maxRow = Math.max(...fields.map((f) => {
872
- return f.row + f.rowSpan;
873
- }));
874
- this.columns = Math.max(...fields.map((f) => {
875
- return f.col + f.colSpan;
876
- }));
877
- this.initFieldsStructure(fields, maxRow);
878
- this.setForm();
879
- }
880
- }
881
- updateField(customField, updatedField) {
882
- const options = {
883
- disabled: !updatedField.Enabled || !this.canEditObject,
884
- readonly: !updatedField.Enabled || !this.canEditObject,
885
- visible: updatedField.Visible,
886
- value: updatedField.Value,
887
- additionalValue: updatedField.AdditionalValue,
888
- formattedValue: updatedField.FormattedValue,
889
- textColor: updatedField.TextColor,
890
- };
891
- if (customField instanceof PepQuantitySelectorField) {
892
- const notificationInfo = updatedField.NotificationInfo;
893
- options.notificationInfo = notificationInfo;
894
- // Change type if it's change (only for allowDecimal).
895
- let allowDecimal = false;
896
- if (updatedField.FieldType === FIELD_TYPE.NumberRealQuantitySelector ||
897
- updatedField.FieldType === FIELD_TYPE.NumberReal ||
898
- updatedField.FieldType === FIELD_TYPE.NumberRealForMatrix) {
899
- allowDecimal = true;
900
- }
901
- options.allowDecimal = allowDecimal;
902
- }
903
- else if (customField instanceof PepSelectField) {
904
- options.options = this.convertOptionalValues(updatedField.OptionalValues);
905
- if (!options.options || options.options.length === 0) {
906
- options.options.push({
907
- key: options.value,
908
- value: options.formattedValue,
909
- });
910
- }
911
- }
912
- else if (customField instanceof PepInternalCaruselField) {
913
- options.pageInfo = updatedField.UIPageInfo;
914
- }
915
- customField.update(options);
916
- }
917
- updateForm() {
918
- if (this.data && this.data.Fields) {
919
- for (const currentField of this.data.Fields) {
920
- const customField = this.fields.filter((f) => f.key === currentField.ApiName)[0];
921
- // Update all fields except 'internalPage' type (for children).
922
- if (customField && customField.controlType !== 'internalPage') {
923
- this.updateField(customField, currentField);
924
- // Update the group fields.
925
- if (customField.controlType === 'address' &&
926
- currentField.GroupFields) {
927
- // for (let j = 0; j < currentField.GroupFields.length; j++) {
928
- // let currentGroupField = currentField.GroupFields[j];
929
- for (const currentGroupField of currentField.GroupFields) {
930
- currentGroupField.Enabled = !currentField.Enabled
931
- ? false
932
- : currentGroupField.Enabled;
933
- const customGroupField = customField.groupFields.filter((f) => f.key === currentGroupField.ApiName)[0];
934
- this.updateField(customGroupField, currentGroupField);
935
- }
936
- }
937
- }
938
- }
939
- this.setForm(true);
940
- }
941
- }
942
- ReloadForm() {
943
- this._shouldReloadForm = true;
944
- }
945
- // onSubmit() {
946
- // if (this.form.valid) {
947
- // this.payLoad = JSON.stringify(this.form.value);
948
- // //this.submitted.emit(this.form.value);
949
- // }
950
- // }
951
- getFormControlById(key) {
952
- let formControl = null;
953
- this.fields.forEach((field) => {
954
- if (field.key === key) {
955
- formControl = this.form.get(field.key);
956
- return;
957
- }
958
- else if (field.groupFields && field.groupFields.length > 0) {
959
- field.groupFields.forEach((groupField) => {
960
- if (groupField.key === key) {
961
- formControl = this.form.get(field.key + '.' + groupField.key);
962
- return;
963
- }
964
- });
965
- }
966
- });
967
- return formControl;
968
- }
969
- setSpecialFields(controlFields, dataFields) {
970
- // let cf;
971
- // for (let index = 0; index < controlFields.length; index++) {
972
- // cf = controlFields[index];
973
- for (const cf of controlFields) {
974
- if (cf.ApiName === 'ObjectMenu') {
975
- this.menuField = cf;
976
- }
977
- else if (cf.ApiName === 'ItemHasActiveCampaign') {
978
- this.hasCampaignField = cf;
979
- }
980
- else if (cf.ApiName === 'ItemIndicatorsWithoutCampaign') {
981
- this.indicatorsField = cf;
982
- }
983
- }
984
- // let df;
985
- // for (let index = 0; index < dataFields.length; index++) {
986
- // df = dataFields[index];
987
- for (const df of dataFields) {
988
- if (df.ApiName === 'ObjectMenu') {
989
- this.menuDataField = df;
990
- }
991
- else if (df.ApiName === 'ItemHasActiveCampaign') {
992
- this.hasCampaignDataField = df;
993
- }
994
- else if (df.ApiName === 'ItemIndicatorsWithoutCampaign') {
995
- this.indicatorsDataField = df;
996
- }
997
- }
998
- if (this.menuField && this.menuDataField) {
999
- this.menuDataField.Layout = this.menuField.Layout;
1000
- }
1001
- if (this.hasCampaignField && this.hasCampaignDataField) {
1002
- this.hasCampaignDataField.Layout = this.hasCampaignField.Layout;
1003
- }
1004
- if (this.indicatorsField && this.indicatorsDataField) {
1005
- this.indicatorsDataField.Layout = this.indicatorsField.Layout;
1006
- }
1007
- // Check if menu is floating on other field.
1008
- // for (let index = 0; index < controlFields.length; index++) {
1009
- // cf = controlFields[index];
1010
- for (const cf of controlFields) {
1011
- if (this.menuField && cf.ApiName !== 'ObjectMenu') {
1012
- this.hasMenuFloatingOnOtherField = this.doesFieldHavaFloatingField(cf, this.menuField);
1013
- if (this.hasMenuFloatingOnOtherField) {
1014
- break;
1015
- }
1016
- }
1017
- }
1018
- }
1019
- convertCustomFields(controlFields, dataFields) {
1020
- if (this.layoutType !== 'table') {
1021
- this.setSpecialFields(controlFields, dataFields);
1022
- }
1023
- else {
1024
- // HACK: convert to center alignment if table view & special fields)
1025
- controlFields.forEach((field, index) => {
1026
- if (field.ApiName === 'UnitsQuantity' ||
1027
- field.ApiName === 'QuantitySelector' ||
1028
- field.ApiName === 'ObjectMenu' ||
1029
- field.FieldType === FIELD_TYPE.Image ||
1030
- field.FieldType === FIELD_TYPE.ImageURL ||
1031
- field.FieldType === FIELD_TYPE.Indicators ||
1032
- field.FieldType === FIELD_TYPE.Boolean ||
1033
- field.FieldType === FIELD_TYPE.CalculatedBool ||
1034
- field.FieldType === FIELD_TYPE.Signature ||
1035
- field.FieldType ===
1036
- FIELD_TYPE.NumberIntegerQuantitySelector ||
1037
- field.FieldType === FIELD_TYPE.NumberRealQuantitySelector ||
1038
- field.FieldType === FIELD_TYPE.Package ||
1039
- field.FieldType === FIELD_TYPE.NumberIntegerForMatrix ||
1040
- field.FieldType === FIELD_TYPE.NumberRealForMatrix) {
1041
- field.Layout.XAlignment = X_ALIGNMENT_TYPE.Center;
1042
- }
1043
- else {
1044
- // HACK: align the rest of the fields by the culture.
1045
- // field.Layout.XAlignment = this.layoutService.isRtl() ? X_ALIGNMENT_TYPE.Right : X_ALIGNMENT_TYPE.Left;
1046
- }
1047
- });
1048
- }
1049
- const fields = [];
1050
- controlFields.forEach((field, index) => {
1051
- const dataField = dataFields.filter((df) => df.ApiName === field.ApiName)[0];
1052
- if (!dataField) {
1053
- return;
1054
- }
1055
- // If current view is not table view and those fields are special.
1056
- if (this.layoutType !== 'table' &&
1057
- ((this.hasMenuFloatingOnOtherField &&
1058
- this.menuField &&
1059
- this.menuField.ApiName === field.ApiName) ||
1060
- (this.indicatorsField &&
1061
- this.indicatorsField.ApiName === field.ApiName) ||
1062
- (this.hasCampaignField &&
1063
- this.hasCampaignField.ApiName === field.ApiName))) {
1064
- return;
1065
- }
1066
- // Set type to link
1067
- if (index === 0 && this.firstFieldAsLink) {
1068
- dataField.FieldType = FIELD_TYPE.InternalLink;
1069
- // dataField.Value = this.getInternalLinkHref();
1070
- }
1071
- if (field.ApiName === 'ObjectMenu') {
1072
- dataField.Enabled = true;
1073
- // HACK : Until "Enabled" returns from the server, we set PepMenu to be
1074
- // Disabled in cart on regular items and not campign items.
1075
- }
1076
- const customField = this.createBaseField(field, dataField);
1077
- fields.push(customField);
1078
- });
1079
- return fields.sort((f1, f2) => f1.row > f2.row
1080
- ? 1
1081
- : f1.row < f2.row
1082
- ? -1
1083
- : f1.col > f2.col
1084
- ? 1
1085
- : f1.col < f2.col
1086
- ? -1
1087
- : 0);
1088
- }
1089
- onFormValidationChanged(formValidationChange) {
1090
- this.formValidationChange.emit(formValidationChange);
1091
- }
1092
- onValueChanged(event) {
1093
- this.onFormValidationChanged(this.form.valid);
1094
- const formControl = this.getFormControlById(event.key);
1095
- const isValid = formControl ? formControl.valid : true;
1096
- // const isValid = true;
1097
- if (isValid) {
1098
- // Set it to false to disable all fields.
1099
- if (this.isInternal && this.layoutType === 'form') {
1100
- this.isLocked = true;
1101
- }
1102
- // Update the current field value.
1103
- const currentField = this.fields.find((f) => f.key === event.key);
1104
- if (currentField) {
1105
- currentField.formattedValue = currentField.value = event.value;
1106
- }
1107
- this.valueChange.emit({
1108
- id: this.data.UID.toString(),
1109
- uiObjectKey: this.data.Key,
1110
- key: event.key,
1111
- value: event.value,
1112
- controlType: event.controlType,
1113
- });
1114
- }
1115
- }
1116
- onClick(fieldClickEvent) {
1117
- const clickedUiControlField = this.data.Fields.filter((f) => f.ApiName === fieldClickEvent.key)[0];
1118
- const idType = this.data.Type ? this.data.Type.toString() : '';
1119
- if (clickedUiControlField) {
1120
- this.fieldClick.emit({
1121
- id: this.data.UID.toString(),
1122
- uiObjectKey: this.data.Key,
1123
- key: fieldClickEvent.key,
1124
- idType,
1125
- which: fieldClickEvent.eventWhich,
1126
- value: fieldClickEvent.value,
1127
- controlType: fieldClickEvent.controlType,
1128
- fieldType: clickedUiControlField.FieldType,
1129
- otherData: fieldClickEvent.otherData,
1130
- });
1131
- }
1132
- else {
1133
- // For other api names (like enter children etc).
1134
- this.fieldClick.emit({
1135
- id: this.data.UID.toString(),
1136
- uiObjectKey: this.data.Key,
1137
- key: fieldClickEvent.key,
1138
- idType,
1139
- which: fieldClickEvent.eventWhich,
1140
- value: fieldClickEvent.value,
1141
- controlType: fieldClickEvent.controlType,
1142
- otherData: fieldClickEvent.otherData,
1143
- });
1144
- }
1145
- }
1146
- // This event is for handle the internal page events.
1147
- onInternalFormFieldClicked(internalFormFieldClick) {
1148
- this.internalFormFieldClick.emit(internalFormFieldClick);
1149
- }
1150
- // This event is for handle the internal page events.
1151
- onInternalFormFieldChanged(internalFormFieldChange) {
1152
- this.internalFormFieldChange.emit(internalFormFieldChange);
1153
- }
1154
- // This event is for handle the related items change events.
1155
- onFormValueChanged(event) {
1156
- // this.valueChange.emit(event);
1157
- }
1158
- // This event is for handle the related items change events.
1159
- onFormFieldClick(event) {
1160
- this.fieldClick.emit(event);
1161
- }
1162
- }
1163
- PepFormComponent.decorators = [
1164
- { type: Component, args: [{
1165
- selector: 'pep-form',
1166
- template: "<fieldset *ngIf=\"form\" [formGroup]=\"form\" [disabled]=\"isLocked\" class=\"pep-form\"\n [ngStyle]=\"{ 'background-color': layoutType == 'card' && data?.BackgroundColor }\">\n <!-- New Form -->\n <mat-grid-list *ngIf=\"layoutType == 'form'\" [cols]=\"columns\" [rowHeight]=\"rowHeight + 'rem'\"\n [gutterSize]=\"formGutterSize\">\n <mat-grid-tile *ngFor=\"let field of fields$ | async\" [rowspan]=\"field.rowSpan\" [colspan]=\"field.colSpan\">\n <pep-field-generator *ngIf=\"field.controlType != 'placeholder'\" [form]=\"form\" [layoutType]=\"layoutType\"\n [checkForChanges]=\"checkForChanges\" [uid]=\"data?.UID\" [field]=\"field\" [showTitle]=\"showTitle\"\n (valueChange)=\"onValueChanged($event)\" (elementClick)=\"onClick($event)\"\n (internalFormFieldClick)=\"onInternalFormFieldClicked($event)\"\n (internalFormFieldChange)=\"onInternalFormFieldChanged($event)\"\n (formValueChange)=\"onFormValueChanged($event)\" (formFieldClick)=\"onFormFieldClick($event)\"\n (formValidationChange)=\"onFormValidationChanged($event)\">\n </pep-field-generator>\n </mat-grid-tile>\n </mat-grid-list>\n\n <!-- Thumbnails -->\n <mat-grid-list *ngIf=\"layoutType == 'card'\" [cols]=\"columns\" [rowHeight]=\"rowHeight + 'rem'\"\n [gutterSize]=\"cardGutterSize\" class=\"card-spacing\">\n <mat-grid-tile *ngFor=\"let field of fields$ | async\" [rowspan]=\"field.rowSpan\" [colspan]=\"field.colSpan\"\n [ngStyle]=\"{ overflow: field.type == 'qs' ? 'unset' : 'hidden' }\">\n <pep-field-generator *ngIf=\"field.controlType != 'placeholder'\" [form]=\"form\" [layoutType]=\"layoutType\"\n [ngClass]=\"{ 'lock-events': lockEvents }\" [isActive]=\"isActive\" [checkForChanges]=\"checkForChanges\"\n [uid]=\"data?.UID\" [field]=\"field\" [showTitle]=\"showTitle\" (valueChange)=\"onValueChanged($event)\"\n (elementClick)=\"onClick($event)\" (internalFormFieldClick)=\"onInternalFormFieldClicked($event)\"\n (internalFormFieldChange)=\"onInternalFormFieldChanged($event)\"\n (formValueChange)=\"onFormValueChanged($event)\" (formFieldClick)=\"onFormFieldClick($event)\">\n </pep-field-generator>\n </mat-grid-tile>\n </mat-grid-list>\n\n <ng-container *ngIf=\"layoutType == 'table'\">\n <ng-container *ngIf=\"isReport; then reportBlock; else notReportBlock\"></ng-container>\n <ng-template #reportBlock>\n <ng-container *ngTemplateOutlet=\"report\"></ng-container>\n </ng-template>\n <ng-template #notReportBlock>\n <div *ngFor=\"let field of fields$ | async; let j = index\" class=\"pull-left flip table-cell \"\n [ngClass]=\"['text-align-' + field.xAlignment]\" style=\"height: 100%\"\n [ngStyle]=\"{ width: (layout?.ControlFields)[j]?.calcColumnWidthString}\">\n <pep-field-generator *ngIf=\"field.controlType != 'placeholder'\" [checkForChanges]=\"checkForChanges\"\n [uid]=\"data?.UID\" [field]=\"field\" [form]=\"form\" [layoutType]=\"layoutType\" [showTitle]=\"false\"\n (elementClick)=\"onClick($event)\" (valueChange)=\"onValueChanged($event)\"\n (formValueChange)=\"onFormValueChanged($event)\" (formFieldClick)=\"onFormFieldClick($event)\"\n [isActive]=\"isActive\">\n </pep-field-generator>\n </div>\n </ng-template>\n </ng-container>\n\n <!------- For testing ------------\n {{ form.value | json }}\n {{ form.valid }}\n ---------------------------------->\n</fieldset>\n\n<ng-template #report>\n <div *ngFor=\"let field of fields$ | async; let j = index\" class=\"pull-left flip pep-report-fields\"\n [ngStyle]=\"{ width: (layout?.ControlFields)[j]?.calcColumnWidthString }\"\n [ngClass]=\"['text-align-' + field.xAlignment]\">\n <ng-container [ngSwitch]=\"field.controlType\">\n <pep-image *ngSwitchCase=\"'image'\" [uid]=\"data?.UID\" [form]=\"form\" [key]=\"field.key\"\n [src]=\"field.formattedValue\" [srcLarge]=\"field.value\" [options]=\"field.options\" [label]=\"field.label\"\n [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\" [readonly]=\"field.readonly\"\n [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\" [layoutType]=\"layoutType\"\n (elementClick)=\"onClick($event)\">\n </pep-image>\n\n <pep-signature *ngSwitchCase=\"'signature'\" [form]=\"form\" [key]=\"field.key\" [src]=\"field.value\"\n [label]=\"field.label\" [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\"\n [readonly]=\"field.readonly\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [layoutType]=\"layoutType\">\n </pep-signature>\n\n <pep-checkbox *ngSwitchCase=\"'checkbox'\" [form]=\"form\" [key]=\"field.key\"\n [value]=\"(field.value | lowercase) == 'true' || field.value == '1' ? true : false\" [label]=\"field.label\"\n [type]=\"field.type\" [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\"\n [readonly]=\"field.readonly\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [additionalValue]=\"field.additionalValue\" [layoutType]=\"layoutType\">\n </pep-checkbox>\n\n <pep-date *ngSwitchCase=\"'date'\" [form]=\"form\" [key]=\"field.key\" [value]=\"field.value\"\n [formattedValue]=\"field.formattedValue\" [label]=\"field.label\" [type]=\"field.type\"\n [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\" [readonly]=\"field.readonly\"\n [textColor]=\"field.textColor\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [minValue]=\"field.minValue\" [maxValue]=\"field.maxValue\" [layoutType]=\"layoutType\">\n </pep-date>\n\n <pep-internal-button *ngSwitchCase=\"'button'\" [form]=\"form\" [key]=\"field.key\" [value]=\"field.value\"\n [formattedValue]=\"field.formattedValue\" [label]=\"field.label\" [type]=\"field.type\"\n [disabled]=\"field.disabled\" [readonly]=\"field.readonly\" [xAlignment]=\"field.xAlignment\"\n [layoutType]=\"layoutType\" (elementClick)=\"onClick($event)\">\n </pep-internal-button>\n\n <pep-textarea *ngSwitchCase=\"'textarea'\" [form]=\"form\" [key]=\"field.key\" [value]=\"field.value\"\n [label]=\"field.label\" [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\"\n [readonly]=\"field.readonly\" [maxFieldCharacters]=\"field.maxFieldCharacters\"\n [textColor]=\"field.textColor\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [layoutType]=\"layoutType\">\n </pep-textarea>\n\n <pep-quantity-selector *ngSwitchCase=\"'qs'\" [id]=\"field.key\" [form]=\"form\" [key]=\"field.key\"\n [value]=\"field.value\" [formattedValue]=\"field.formattedValue\" [label]=\"field.label\" [type]=\"field.type\"\n [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\" [readonly]=\"field.readonly\"\n [textColor]=\"field.textColor\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [layoutType]=\"layoutType\" (valueChange)=\"onValueChanged($event)\" (elementClick)=\"onClick($event)\">\n </pep-quantity-selector>\n\n <ng-container *ngSwitchDefault>\n <ng-container *ngIf=\"field.formattedValue?.length > 0; then notEmptyBlock; else emptyBlock\">\n </ng-container>\n <ng-template #notEmptyBlock>\n <ng-container\n *ngIf=\"field.controlType === 'attachment' || field.type === 'link'; then linkBlock; else notLinkBlock\">\n </ng-container>\n <ng-template #linkBlock>\n <a [id]=\"field.key\" class=\"color-link body-sm pep-report-input readonly\"\n *ngIf=\"field.formattedValue != null\" title=\"{{ field.formattedValue }}\" target=\"_blank\"\n href=\"{{ field.value }}\">{{ field.formattedValue }}</a>\n </ng-template>\n <ng-template #notLinkBlock>\n <span [id]=\"field.key\" class=\"body-sm pep-report-input readonly\"\n title=\"{{ field.formattedValue }}\" [ngStyle]=\"{ color: field.textColor }\">{{\n field.formattedValue }}</span>\n </ng-template>\n </ng-template>\n <ng-template #emptyBlock>\n <span>&nbsp;</span>\n </ng-template>\n </ng-container>\n </ng-container>\n </div>\n</ng-template>",
1167
- changeDetection: ChangeDetectionStrategy.OnPush,
1168
- styles: [":host{display:grid}"]
1169
- },] }
1170
- ];
1171
- PepFormComponent.ctorParameters = () => [
1172
- { type: PepDialogService },
1173
- { type: PepCustomizationService },
1174
- { type: PepLayoutService },
1175
- { type: FormBuilder },
1176
- { type: KeyValueDiffers },
1177
- { type: TranslateService }
1178
- ];
1179
- PepFormComponent.propDecorators = {
1180
- isInternal: [{ type: Input }],
1181
- isReport: [{ type: Input }],
1182
- layout: [{ type: Input }],
1183
- lockEvents: [{ type: Input }],
1184
- canEditObject: [{ type: Input }],
1185
- data: [{ type: Input }],
1186
- lockFields: [{ type: Input }],
1187
- isActive: [{ type: Input }],
1188
- layoutType: [{ type: Input }],
1189
- objectId: [{ type: Input }],
1190
- parentId: [{ type: Input }],
1191
- searchCode: [{ type: Input }],
1192
- showTitle: [{ type: Input }],
1193
- firstFieldAsLink: [{ type: Input }],
1194
- checkForChanges: [{ type: Input }],
1195
- valueChange: [{ type: Output }],
1196
- formValidationChange: [{ type: Output }],
1197
- fieldClick: [{ type: Output }],
1198
- internalFormFieldClick: [{ type: Output }],
1199
- internalFormFieldChange: [{ type: Output }]
1200
- };
1
+ import { Component, ChangeDetectionStrategy, Input, KeyValueDiffers, Output, EventEmitter, } from '@angular/core';
2
+ import { FormBuilder, Validators, } from '@angular/forms';
3
+ import { TranslateService } from '@ngx-translate/core';
4
+ import { PepDialogService, PepDialogData, } from '@pepperi-addons/ngx-lib/dialog';
5
+ import { FIELD_TYPE, PepCustomizationService, PepLayoutService, PepTextboxField, PepSelectField, PepInternalMenuField, PepQuantitySelectorField, PepAddressField, PepIndicatorsField, PepInternalPageField, PepInternalCaruselField, PepInternalButtonField, PepAttachmentField, PepSignatureField, PepImageField, PepImagesField, PepLinkField, PepTextareaField, PepRichHtmlTextareaField, PepDateField, PepCheckboxField, PepSeparatorField, PepPlaceholderField, X_ALIGNMENT_TYPE, Y_ALIGNMENT_TYPE, DEFAULT_VERTICAL_ALIGNMENT, DEFAULT_HORIZONTAL_ALIGNMENT, } from '@pepperi-addons/ngx-lib';
6
+ import { BehaviorSubject } from 'rxjs';
7
+ export class PepFormComponent {
8
+ // eventServiceSub: Subscription;
9
+ // public jsonLib = JSON;
10
+ constructor(dialogService, customizationService, layoutService, fb, differs, translate) {
11
+ this.dialogService = dialogService;
12
+ this.customizationService = customizationService;
13
+ this.layoutService = layoutService;
14
+ this.fb = fb;
15
+ this.translate = translate;
16
+ this.isInternal = true;
17
+ this.isReport = false;
18
+ this.lockEvents = false;
19
+ this.canEditObject = true;
20
+ this._data = null;
21
+ this.isActive = false;
22
+ this.layoutType = 'card';
23
+ // @Input() listType = '';
24
+ this.objectId = '0';
25
+ this.parentId = '0';
26
+ this.searchCode = '0';
27
+ this.showTitle = true;
28
+ this.firstFieldAsLink = false;
29
+ this.checkForChanges = null;
30
+ this.valueChange = new EventEmitter();
31
+ this.formValidationChange = new EventEmitter();
32
+ this.fieldClick = new EventEmitter();
33
+ this.internalFormFieldClick = new EventEmitter();
34
+ this.internalFormFieldChange = new EventEmitter();
35
+ this.isLocked = false;
36
+ // payLoad = '';
37
+ this.rows = [];
38
+ this.fields = [];
39
+ this._fieldsSubject = new BehaviorSubject([]);
40
+ this.columns = 1;
41
+ this.hasMenuFloatingOnOtherField = false;
42
+ this.indicatorsDataField = null;
43
+ this._shouldReloadForm = false;
44
+ // store the initial value to compare with
45
+ this.differ = differs.find({}).create();
46
+ }
47
+ set data(value) {
48
+ const shouldReload = this.shouldReloadForm || !this._data;
49
+ this._data = value;
50
+ if (shouldReload) {
51
+ this._shouldReloadForm = false;
52
+ this.initForm();
53
+ }
54
+ else {
55
+ this.updateForm();
56
+ }
57
+ }
58
+ get data() {
59
+ return this._data;
60
+ }
61
+ set lockFields(value) {
62
+ this.isLocked = value;
63
+ }
64
+ get fields$() {
65
+ return this._fieldsSubject.asObservable();
66
+ }
67
+ get shouldReloadForm() {
68
+ return this._shouldReloadForm;
69
+ }
70
+ convertXAlignToHorizontalAlign(xAlign) {
71
+ let res = DEFAULT_HORIZONTAL_ALIGNMENT;
72
+ if (xAlign === X_ALIGNMENT_TYPE.None ||
73
+ xAlign === X_ALIGNMENT_TYPE.Left) {
74
+ res = 'left';
75
+ }
76
+ else if (xAlign === X_ALIGNMENT_TYPE.Right) {
77
+ res = 'right';
78
+ }
79
+ else {
80
+ res = 'center';
81
+ }
82
+ return res;
83
+ }
84
+ convertYAlignToVerticalAlign(yAlign) {
85
+ let res = DEFAULT_VERTICAL_ALIGNMENT;
86
+ if (yAlign === Y_ALIGNMENT_TYPE.None ||
87
+ yAlign === Y_ALIGNMENT_TYPE.Top) {
88
+ res = 'top';
89
+ }
90
+ else if (yAlign === Y_ALIGNMENT_TYPE.Bottom) {
91
+ res = 'bottom';
92
+ }
93
+ else {
94
+ res = 'middle';
95
+ }
96
+ return res;
97
+ }
98
+ convertOptionalValues(optionalValues) {
99
+ if (optionalValues && optionalValues.length > 0) {
100
+ return optionalValues.map((ov) => {
101
+ return { key: ov.Key, value: ov.Value };
102
+ });
103
+ }
104
+ else {
105
+ return [];
106
+ }
107
+ }
108
+ convertAddressFields(controlField, addressFields, canEditObject) {
109
+ const fields = [];
110
+ addressFields.forEach((field) => {
111
+ let customField;
112
+ const placeholder = field.ApiName;
113
+ if (field.ApiName.toLowerCase().indexOf('street') >= 0) {
114
+ customField = new PepTextboxField({
115
+ key: field.ApiName,
116
+ label: field.ApiName,
117
+ type: 'text',
118
+ placeholder,
119
+ readonly: !canEditObject,
120
+ disabled: !field.Enabled || !canEditObject,
121
+ hidden: false,
122
+ mandatory: false,
123
+ value: field.Value,
124
+ formattedValue: field.FormattedValue,
125
+ row: 0,
126
+ rowSpan: 1,
127
+ col: 0,
128
+ colSpan: 2,
129
+ xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
130
+ yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
131
+ order: 0,
132
+ });
133
+ }
134
+ else if (field.ApiName.toLowerCase().indexOf('city') >= 0) {
135
+ customField = new PepTextboxField({
136
+ key: field.ApiName,
137
+ label: field.ApiName,
138
+ type: 'text',
139
+ placeholder,
140
+ readonly: !canEditObject,
141
+ disabled: !field.Enabled || !canEditObject,
142
+ hidden: false,
143
+ mandatory: false,
144
+ value: field.Value,
145
+ formattedValue: field.FormattedValue,
146
+ row: 0,
147
+ rowSpan: 1,
148
+ col: 2,
149
+ colSpan: 1,
150
+ xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
151
+ yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
152
+ order: 1,
153
+ });
154
+ }
155
+ else if (field.ApiName.toLowerCase().indexOf('state') >= 0) {
156
+ customField = new PepSelectField({
157
+ key: field.ApiName,
158
+ label: field.ApiName,
159
+ placeholder,
160
+ options: this.convertOptionalValues(field.OptionalValues),
161
+ readonly: !canEditObject,
162
+ disabled: !field.Enabled || !canEditObject,
163
+ hidden: false,
164
+ mandatory: false,
165
+ value: field.Value,
166
+ formattedValue: field.FormattedValue,
167
+ row: 1,
168
+ rowSpan: 1,
169
+ col: 0,
170
+ colSpan: 1,
171
+ xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
172
+ yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
173
+ order: 2,
174
+ });
175
+ }
176
+ else if (field.ApiName.toLowerCase().indexOf('zipcode') >= 0) {
177
+ customField = new PepTextboxField({
178
+ key: field.ApiName,
179
+ label: field.ApiName,
180
+ type: 'text',
181
+ placeholder,
182
+ readonly: !canEditObject,
183
+ disabled: !field.Enabled || !canEditObject,
184
+ hidden: false,
185
+ mandatory: false,
186
+ value: field.Value,
187
+ formattedValue: field.FormattedValue,
188
+ row: 1,
189
+ rowSpan: 1,
190
+ col: 1,
191
+ colSpan: 1,
192
+ xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
193
+ yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
194
+ order: 3,
195
+ });
196
+ }
197
+ else if (field.ApiName.toLowerCase().indexOf('country') >= 0) {
198
+ customField = new PepSelectField({
199
+ key: field.ApiName,
200
+ label: field.ApiName,
201
+ placeholder,
202
+ options: this.convertOptionalValues(field.OptionalValues),
203
+ readonly: !canEditObject,
204
+ disabled: !field.Enabled || !canEditObject,
205
+ hidden: false,
206
+ mandatory: false,
207
+ value: field.Value,
208
+ formattedValue: field.FormattedValue,
209
+ row: 2,
210
+ rowSpan: 1,
211
+ col: 2,
212
+ colSpan: 1,
213
+ xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
214
+ yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
215
+ order: 4,
216
+ });
217
+ }
218
+ fields.push(customField);
219
+ });
220
+ return fields.sort((n1, n2) => n1.order > n2.order ? 1 : n1.order < n2.order ? -1 : 0);
221
+ }
222
+ isMatrixField(apiNameToCheck) {
223
+ return apiNameToCheck.indexOf('Matrix') >= 0;
224
+ }
225
+ doesFieldHavaFloatingField(controlField, floatingField) {
226
+ let hasFloatingField = false;
227
+ if (floatingField.Layout.Y >= controlField.Layout.Y &&
228
+ floatingField.Layout.Y <
229
+ controlField.Layout.Y + controlField.Layout.Height &&
230
+ floatingField.Layout.X >= controlField.Layout.X &&
231
+ floatingField.Layout.X <
232
+ controlField.Layout.X + controlField.Layout.Width) {
233
+ hasFloatingField = true;
234
+ }
235
+ return hasFloatingField;
236
+ }
237
+ getOptionsForCustomField(controlField, dataField, canEditObject) {
238
+ if (!controlField || !dataField) {
239
+ return;
240
+ }
241
+ const placeholder = controlField.ReadOnly || !canEditObject ? '' : controlField.Title;
242
+ let fieldProperties = {
243
+ key: controlField.ApiName,
244
+ label: controlField.Title,
245
+ accessory: dataField.Accessory,
246
+ placeholder,
247
+ readonly: controlField.ReadOnly || !canEditObject,
248
+ disabled: !dataField.Enabled || !canEditObject,
249
+ hidden: controlField.Hidden,
250
+ mandatory: controlField.Mandatory,
251
+ value: dataField.Value,
252
+ formattedValue: dataField.FormattedValue,
253
+ additionalValue: dataField.AdditionalValue,
254
+ row: controlField.Layout.Y,
255
+ rowSpan: controlField.Layout.Height,
256
+ col: controlField.Layout.X,
257
+ colSpan: controlField.Layout.Width,
258
+ xAlignment: this.convertXAlignToHorizontalAlign(controlField.Layout.XAlignment),
259
+ yAlignment: this.convertYAlignToVerticalAlign(controlField.Layout.YAlignment),
260
+ options: this.convertOptionalValues(dataField.OptionalValues),
261
+ groupFields: undefined,
262
+ maxFieldCharacters: controlField.MaxFieldCharacters,
263
+ minValue: controlField.MinValue,
264
+ maxValue: controlField.MaxValue,
265
+ // hasMenu: hasMenu,
266
+ // hasCampaign: hasCampaign,
267
+ // hasIndicators: hasIndicators,
268
+ textColor: dataField.TextColor,
269
+ visible: dataField.Visible,
270
+ };
271
+ if (dataField.AdditionalProps) {
272
+ fieldProperties = Object.assign(Object.assign({}, fieldProperties), dataField.AdditionalProps);
273
+ }
274
+ return fieldProperties;
275
+ }
276
+ convertToCustomField(controlField, dataField, canEditObject, menuField, hasCampaignField, indicatorsField, objectId, parentId, searchCode) {
277
+ let customField;
278
+ const options = this.getOptionsForCustomField(controlField, dataField, canEditObject);
279
+ if (controlField.ApiName === 'ObjectMenu') {
280
+ options.type = 'menu';
281
+ customField = new PepInternalMenuField(options);
282
+ }
283
+ else if (controlField.FieldType === FIELD_TYPE.NumberRealQuantitySelector ||
284
+ controlField.FieldType ===
285
+ FIELD_TYPE.NumberIntegerQuantitySelector ||
286
+ controlField.ApiName === 'QuantitySelector' ||
287
+ controlField.ApiName === 'UnitsQuantity' ||
288
+ controlField.ApiName.indexOf('size_') === 0) {
289
+ if (dataField.FieldType === FIELD_TYPE.InternalLink) {
290
+ options.type = 'button';
291
+ }
292
+ else if (dataField.FieldType === FIELD_TYPE.Package) {
293
+ options.type = 'packageButton';
294
+ }
295
+ else if (dataField.FieldType === FIELD_TYPE.NumberRealQuantitySelector ||
296
+ dataField.FieldType === FIELD_TYPE.NumberReal) {
297
+ options.type = 'qs';
298
+ options.allowDecimal = true;
299
+ }
300
+ else if (dataField.FieldType ===
301
+ FIELD_TYPE.NumberIntegerQuantitySelector ||
302
+ dataField.FieldType === FIELD_TYPE.NumberInteger) {
303
+ options.type = 'qs';
304
+ options.allowDecimal = false;
305
+ }
306
+ else if (dataField.FieldType === FIELD_TYPE.NumberIntegerForMatrix) {
307
+ options.type = 'qsForMatrix';
308
+ options.allowDecimal = false;
309
+ }
310
+ else if (dataField.FieldType === FIELD_TYPE.NumberRealForMatrix) {
311
+ options.type = 'qsForMatrix';
312
+ options.allowDecimal = true;
313
+ }
314
+ options.notificationInfo = dataField.NotificationInfo;
315
+ customField = new PepQuantitySelectorField(options);
316
+ }
317
+ else {
318
+ // HACK: need to remove this..
319
+ if (dataField.FieldType === FIELD_TYPE.Indicators &&
320
+ this.isMatrixField(dataField.ApiName)) {
321
+ dataField.FieldType = FIELD_TYPE.InternalPage;
322
+ }
323
+ switch (dataField.FieldType) {
324
+ case FIELD_TYPE.Address: {
325
+ const canEditGroupObject = controlField.ReadOnly
326
+ ? false
327
+ : canEditObject;
328
+ options.groupFields = this.convertAddressFields(controlField, dataField.GroupFields, canEditGroupObject);
329
+ customField = new PepAddressField(options);
330
+ break;
331
+ }
332
+ case FIELD_TYPE.Indicators: {
333
+ // options['type'] = 'indicators'; // Not needed this is PepIndicatorsField.
334
+ customField = new PepIndicatorsField(options);
335
+ break;
336
+ }
337
+ case FIELD_TYPE.InternalPage: {
338
+ if (this.isMatrixField(controlField.ApiName)) {
339
+ options.rowSpan = controlField.Layout.Height;
340
+ options.objectId = objectId;
341
+ options.parentId = parentId;
342
+ options.searchCode = searchCode;
343
+ customField = new PepInternalPageField(options);
344
+ }
345
+ else {
346
+ // Not supported
347
+ }
348
+ break;
349
+ }
350
+ case FIELD_TYPE.RelatedObjectsCards: {
351
+ options.rowSpan = controlField.Layout.Height;
352
+ options.searchCode = searchCode;
353
+ options.pageInfo = dataField.UIPageInfo;
354
+ customField = new PepInternalCaruselField(options);
355
+ break;
356
+ }
357
+ case FIELD_TYPE.Link: {
358
+ options.type = 'link';
359
+ customField = new PepLinkField(options);
360
+ break;
361
+ }
362
+ case FIELD_TYPE.InternalLink:
363
+ case FIELD_TYPE.Button: {
364
+ options.type = 'button';
365
+ customField = new PepInternalButtonField(options);
366
+ break;
367
+ }
368
+ case FIELD_TYPE.Attachment: {
369
+ // options.type = 'attachment';
370
+ customField = new PepAttachmentField(options);
371
+ break;
372
+ }
373
+ case FIELD_TYPE.Signature: {
374
+ // options.type = 'signature';
375
+ customField = new PepSignatureField(options);
376
+ break;
377
+ }
378
+ case FIELD_TYPE.Image:
379
+ case FIELD_TYPE.ImageURL: {
380
+ // options.type = 'image';
381
+ options.menuField =
382
+ menuField &&
383
+ this.doesFieldHavaFloatingField(controlField, menuField)
384
+ ? menuField
385
+ : null;
386
+ options.hasCampaignField =
387
+ hasCampaignField &&
388
+ this.doesFieldHavaFloatingField(controlField, hasCampaignField)
389
+ ? hasCampaignField
390
+ : null;
391
+ options.indicatorsField =
392
+ indicatorsField &&
393
+ this.doesFieldHavaFloatingField(controlField, indicatorsField)
394
+ ? indicatorsField
395
+ : null;
396
+ customField = new PepImageField(options);
397
+ break;
398
+ }
399
+ case FIELD_TYPE.Images: {
400
+ // options.type = 'images';
401
+ customField = new PepImagesField(options);
402
+ break;
403
+ }
404
+ case FIELD_TYPE.Email: {
405
+ options.type = 'email';
406
+ customField = new PepLinkField(options);
407
+ break;
408
+ }
409
+ case FIELD_TYPE.Phone: {
410
+ options.type = 'phone';
411
+ customField = new PepLinkField(options);
412
+ break;
413
+ }
414
+ case FIELD_TYPE.Duration: {
415
+ options.type = 'duration';
416
+ customField = new PepTextboxField(options);
417
+ break;
418
+ }
419
+ case FIELD_TYPE.Default:
420
+ case FIELD_TYPE.TextBox:
421
+ case FIELD_TYPE.LimitedLengthTextBox:
422
+ case FIELD_TYPE.TextHeader:
423
+ case FIELD_TYPE.CalculatedString:
424
+ case FIELD_TYPE.MapDataString: {
425
+ customField = new PepTextboxField(options);
426
+ break;
427
+ }
428
+ case FIELD_TYPE.TextArea: {
429
+ customField = new PepTextareaField(options);
430
+ break;
431
+ }
432
+ case FIELD_TYPE.RichTextHTML: {
433
+ customField = new PepRichHtmlTextareaField(options);
434
+ break;
435
+ }
436
+ case FIELD_TYPE.Date:
437
+ case FIELD_TYPE.LimitedDate:
438
+ case FIELD_TYPE.CalculatedDate:
439
+ case FIELD_TYPE.DateAndTime: {
440
+ options.type =
441
+ dataField.FieldType === FIELD_TYPE.DateAndTime
442
+ ? 'datetime'
443
+ : 'date';
444
+ customField = new PepDateField(options);
445
+ break;
446
+ }
447
+ case FIELD_TYPE.NumberInteger:
448
+ case FIELD_TYPE.CalculatedInt:
449
+ case FIELD_TYPE.MapDataInt: {
450
+ options.type = 'int';
451
+ customField = new PepTextboxField(options);
452
+ break;
453
+ }
454
+ case FIELD_TYPE.Percentage: {
455
+ options.type = 'percentage';
456
+ customField = new PepTextboxField(options);
457
+ break;
458
+ }
459
+ case FIELD_TYPE.Currency: {
460
+ options.type = 'currency';
461
+ customField = new PepTextboxField(options);
462
+ break;
463
+ }
464
+ case FIELD_TYPE.NumberReal:
465
+ case FIELD_TYPE.CalculatedReal:
466
+ case FIELD_TYPE.MapDataReal:
467
+ case FIELD_TYPE.Sum:
468
+ case FIELD_TYPE.Totals: {
469
+ options.type = 'real';
470
+ customField = new PepTextboxField(options);
471
+ break;
472
+ }
473
+ case FIELD_TYPE.Boolean:
474
+ case FIELD_TYPE.CalculatedBool: {
475
+ customField = new PepCheckboxField(options);
476
+ break;
477
+ }
478
+ case FIELD_TYPE.BooleanText: {
479
+ options.type = 'booleanText';
480
+ customField = new PepCheckboxField(options);
481
+ break;
482
+ }
483
+ case FIELD_TYPE.ComboBox:
484
+ case FIELD_TYPE.EmptyComboBox:
485
+ case FIELD_TYPE.MapDataDropDown: {
486
+ // options.type = 'select';
487
+ customField = new PepSelectField(options);
488
+ break;
489
+ }
490
+ case FIELD_TYPE.MultiTickBox:
491
+ case FIELD_TYPE.MultiTickBoxToComboBox:
492
+ case FIELD_TYPE.EmptyMultiTickBox: {
493
+ options.type = 'multi';
494
+ customField = new PepSelectField(options);
495
+ break;
496
+ }
497
+ case FIELD_TYPE.GuidReferenceType: {
498
+ options.type = 'reference';
499
+ options.referenceObjectType = dataField.ReferenceObjectType;
500
+ options.referenceObjectSubType =
501
+ dataField.ReferenceObjectSubType;
502
+ options.referenceObjectInternalType =
503
+ dataField.ReferenceObjectInternalType;
504
+ customField = new PepInternalButtonField(options);
505
+ break;
506
+ }
507
+ case FIELD_TYPE.ListOfObjects: {
508
+ options.type = 'listofobjects';
509
+ customField = new PepInternalButtonField(options);
510
+ break;
511
+ }
512
+ case FIELD_TYPE.Separator: {
513
+ customField = new PepSeparatorField(options);
514
+ break;
515
+ }
516
+ /*
517
+ case FIELD_TYPE.Images: return that.field(value);
518
+ */
519
+ case FIELD_TYPE.NumberRealQuantitySelector:
520
+ case FIELD_TYPE.NumberIntegerQuantitySelector: {
521
+ options.type = 'qs';
522
+ options.allowDecimal =
523
+ dataField.FieldType ===
524
+ FIELD_TYPE.NumberRealQuantitySelector;
525
+ options.notificationInfo = dataField.NotificationInfo;
526
+ customField = new PepQuantitySelectorField(options);
527
+ break;
528
+ }
529
+ case FIELD_TYPE.Package: {
530
+ options.type = 'packageButton';
531
+ options.notificationInfo = dataField.NotificationInfo;
532
+ customField = new PepQuantitySelectorField(options);
533
+ break;
534
+ }
535
+ }
536
+ }
537
+ if (!customField) {
538
+ options.label = controlField.ApiName + ' is not supported!!!';
539
+ customField = new PepSeparatorField(options);
540
+ }
541
+ return customField;
542
+ }
543
+ getFieldFormattedValue(field) {
544
+ let fieldFormattedValue = field.formattedValue;
545
+ // Fix for the custom check box component.
546
+ if (field.controlType === 'checkbox') {
547
+ fieldFormattedValue = fieldFormattedValue === 'true';
548
+ }
549
+ // Fix for the custom button component.
550
+ if (field.controlType === 'button') {
551
+ fieldFormattedValue =
552
+ fieldFormattedValue === '0' ? '' : fieldFormattedValue;
553
+ }
554
+ return fieldFormattedValue;
555
+ }
556
+ toControlGroup(fields) {
557
+ const group = {};
558
+ if (fields && fields.length > 0) {
559
+ fields.forEach((field) => {
560
+ if (field.groupFields && field.groupFields.length > 0) {
561
+ const subGroup = {};
562
+ field.groupFields.forEach((groupField) => {
563
+ if (groupField.mandatory &&
564
+ !field.readonly &&
565
+ !field.disabled) {
566
+ subGroup[groupField.key] = [
567
+ {
568
+ value: groupField.formattedValue || '',
569
+ disabled: field.readonly ||
570
+ field.disabled ||
571
+ groupField.disabled,
572
+ },
573
+ [Validators.required],
574
+ ];
575
+ }
576
+ else {
577
+ subGroup[groupField.key] = [
578
+ {
579
+ value: groupField.formattedValue || '',
580
+ disabled: field.readonly ||
581
+ field.disabled ||
582
+ groupField.disabled,
583
+ },
584
+ [Validators.nullValidator],
585
+ ];
586
+ }
587
+ });
588
+ group[field.key] = this.fb.group(subGroup);
589
+ }
590
+ else {
591
+ const validators = field.getValidators();
592
+ const fieldFormattedValue = this.getFieldFormattedValue(field);
593
+ group[field.key] = [
594
+ {
595
+ value: fieldFormattedValue || '',
596
+ disabled: field.disabled,
597
+ },
598
+ validators,
599
+ ];
600
+ }
601
+ });
602
+ }
603
+ return this.fb.group(group);
604
+ }
605
+ createBaseField(uiControlField, dataField) {
606
+ const customField = this.convertToCustomField(uiControlField, dataField, this.canEditObject, this.menuDataField, this.hasCampaignDataField, this.indicatorsDataField, this.objectId, this.parentId, this.searchCode);
607
+ return customField;
608
+ }
609
+ showFormValidationMessage() {
610
+ const fields = this.fields;
611
+ let emptyMandatoryFieldsMsg = '';
612
+ let notValidFieldsMsg = '';
613
+ // for (let i: number = 0; i < fields.length; i++) {
614
+ // let field = fields[i];
615
+ for (const field of fields) {
616
+ const formControl = this.form && this.form.get(field.key);
617
+ if (formControl) {
618
+ // Mandatory is empty.
619
+ if (field.mandatory &&
620
+ formControl.value.toString().trim().length === 0) {
621
+ emptyMandatoryFieldsMsg +=
622
+ '<li><small>' + field.label + '</small></li>';
623
+ }
624
+ else if (!field.disabled && !formControl.valid) {
625
+ notValidFieldsMsg +=
626
+ '<li><small>' + field.label + '</small></li>';
627
+ }
628
+ }
629
+ }
630
+ // Add the header message of the empty mandatory fields
631
+ if (emptyMandatoryFieldsMsg.length > 0) {
632
+ emptyMandatoryFieldsMsg =
633
+ '<div>' +
634
+ this.translate.instant('MESSAGES.ERROR_MANDATORY_FIELDS') +
635
+ "</div><ul style='padding: 0 20px;'>" +
636
+ emptyMandatoryFieldsMsg +
637
+ '</ul><br/>';
638
+ }
639
+ // Add the header message of the empty mandatory fields
640
+ if (notValidFieldsMsg.length > 0) {
641
+ notValidFieldsMsg =
642
+ '<div>' +
643
+ this.translate.instant('MESSAGES.ERROR_INVALID_FIELDS') +
644
+ "</div><ul style='padding: 0 20px;'>" +
645
+ notValidFieldsMsg +
646
+ '</ul>';
647
+ }
648
+ const title = this.translate.instant('MESSAGES.TITLE_NOTICE');
649
+ const data = new PepDialogData({
650
+ title,
651
+ content: emptyMandatoryFieldsMsg + notValidFieldsMsg,
652
+ });
653
+ this.dialogService.openDefaultDialog(data);
654
+ }
655
+ ngOnInit() {
656
+ const themeVars = this.customizationService.getThemeVariables();
657
+ // convert rem to pixel
658
+ const RemToPixel = 16;
659
+ this.formGutterSize =
660
+ this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.FORM_SPACEING_KEY) * RemToPixel;
661
+ this.cardGutterSize =
662
+ this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.CARD_SPACEING_KEY) * RemToPixel;
663
+ }
664
+ ngDoCheck() {
665
+ const changes = this.differ.diff(this.data); // check for changes
666
+ if (changes) {
667
+ this.updateForm();
668
+ this.checkForChanges = new Date();
669
+ }
670
+ }
671
+ ngOnChanges(changes) {
672
+ // if (changes.data && changes.data.currentValue) {
673
+ // // Load changes
674
+ // if (!this.shouldReloadForm && changes.data.previousValue) {
675
+ // this.data = changes.data.currentValue;
676
+ // this.updateForm();
677
+ // } else {
678
+ // this._shouldReloadForm = false;
679
+ // this.initForm();
680
+ // }
681
+ // }
682
+ // if (this.shouldReloadForm || !changes?.data?.previousValue) {
683
+ // this._shouldReloadForm = false;
684
+ // this.initForm();
685
+ // this.checkForChanges = new Date();
686
+ // }
687
+ }
688
+ ngOnDestroy() {
689
+ //
690
+ }
691
+ getUiControlFields() {
692
+ return this.layout ? this.layout.ControlFields : [];
693
+ }
694
+ initFieldsStructure(fields, maxRow) {
695
+ const themeVars = this.customizationService.getThemeVariables();
696
+ // Set form row height.
697
+ if (this.layoutType === 'card') {
698
+ const cardFieldHeight = this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.CARD_FIELD_HEIGHT_KEY);
699
+ this.rowHeight = cardFieldHeight;
700
+ }
701
+ else {
702
+ const rowFieldHeight = this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.FORM_FIELD_HEIGHT_KEY);
703
+ const rowFieldTitleHeight = this.customizationService.getNumberThemeVariable(themeVars, PepCustomizationService.FORM_FIELD_TITLE_HEIGHT_KEY);
704
+ this.rowHeight = rowFieldHeight + rowFieldTitleHeight;
705
+ }
706
+ // Create the fields structure (the fields must be sorted!!!).
707
+ if (fields.length > 0) {
708
+ // Init the layout.
709
+ if (
710
+ // this.layoutType === 'form' ||
711
+ this.layoutType === 'table') {
712
+ this.fields = fields;
713
+ this._fieldsSubject.next(fields);
714
+ this.rows = [];
715
+ for (let i = 0; i <= maxRow; i++) {
716
+ this.rows[i] = [];
717
+ }
718
+ // for (let i = 0; i < fields.length; i++) {
719
+ // const field = fields[i]
720
+ for (const field of fields) {
721
+ this.rows[field.row].push(field);
722
+ }
723
+ }
724
+ else {
725
+ const doesfieldExistIn = new Array(maxRow);
726
+ for (let i = 0; i < doesfieldExistIn.length; i++) {
727
+ doesfieldExistIn[i] = new Array(this.columns);
728
+ for (let j = 0; j < doesfieldExistIn[i].length; j++) {
729
+ doesfieldExistIn[i][j] = false;
730
+ }
731
+ }
732
+ // Run in squere (row - colspan, col - rowspan) and put true where it should.
733
+ // for (let index = 0; index < fields.length; index++) {
734
+ // const currentField = fields[index];
735
+ for (const currentField of fields) {
736
+ if (currentField.rowSpan > 1) {
737
+ for (let row = currentField.row; row < currentField.row + currentField.rowSpan; row++) {
738
+ if (currentField.colSpan > 1) {
739
+ for (let col = currentField.col; col <
740
+ currentField.col + currentField.colSpan; col++) {
741
+ if (doesfieldExistIn.length > row &&
742
+ doesfieldExistIn[0].length > col) {
743
+ doesfieldExistIn[row][col] = true;
744
+ }
745
+ }
746
+ }
747
+ else {
748
+ if (doesfieldExistIn.length > row &&
749
+ doesfieldExistIn[0].length >
750
+ currentField.col) {
751
+ doesfieldExistIn[row][currentField.col] = true;
752
+ }
753
+ }
754
+ }
755
+ }
756
+ else if (currentField.colSpan > 1) {
757
+ for (let col = currentField.col; col < currentField.col + currentField.colSpan; col++) {
758
+ if (doesfieldExistIn.length > currentField.row &&
759
+ doesfieldExistIn[0].length > col) {
760
+ doesfieldExistIn[currentField.row][col] = true;
761
+ }
762
+ }
763
+ }
764
+ else {
765
+ if (doesfieldExistIn.length > currentField.row &&
766
+ doesfieldExistIn[0].length > currentField.col) {
767
+ doesfieldExistIn[currentField.row][currentField.col] = true;
768
+ }
769
+ }
770
+ }
771
+ // Create empty fields where doesfieldExistIn is false (For the md-grid-list UI Component).
772
+ for (let i = 0; i < doesfieldExistIn.length; i++) {
773
+ for (let j = 0; j < doesfieldExistIn[i].length; j++) {
774
+ if (!doesfieldExistIn[i][j]) {
775
+ // Create empty field and add it to the fields list.
776
+ fields.push(new PepPlaceholderField({
777
+ key: i + '_' + j,
778
+ label: '',
779
+ placeholder: '',
780
+ readonly: false,
781
+ disabled: false,
782
+ hidden: false,
783
+ mandatory: false,
784
+ value: '',
785
+ formattedValue: '',
786
+ row: i,
787
+ rowSpan: 1,
788
+ col: j,
789
+ colSpan: 1,
790
+ order: 1,
791
+ }));
792
+ }
793
+ }
794
+ }
795
+ // Sort the fields again.
796
+ this.fields = fields.sort((f1, f2) => f1.row > f2.row
797
+ ? 1
798
+ : f1.row < f2.row
799
+ ? -1
800
+ : f1.col > f2.col
801
+ ? 1
802
+ : f1.col < f2.col
803
+ ? -1
804
+ : 0);
805
+ this._fieldsSubject.next(fields);
806
+ }
807
+ }
808
+ }
809
+ setForm(isForUpdate = false) {
810
+ var _a;
811
+ let allFieldsAreReadOnly = true;
812
+ if (!isForUpdate) {
813
+ const fields = [];
814
+ for (const currentField of this.fields) {
815
+ // Add all fields except 'internalPage' (for children).
816
+ if (currentField.controlType !== 'internalPage') {
817
+ fields.push(currentField);
818
+ }
819
+ if (!currentField.readonly) {
820
+ allFieldsAreReadOnly = false;
821
+ }
822
+ }
823
+ this.form = this.toControlGroup(fields);
824
+ }
825
+ else {
826
+ // Update form values if changed by calculated fields.
827
+ for (let i = 0; i < this.fields.length; i++) {
828
+ let currentField = this.fields[i];
829
+ if (currentField.controlType === 'internalCarusel') {
830
+ // Hack to override (update) the field.
831
+ const uiControlField = this.getUiControlFields().find(cf => cf.ApiName === currentField.key);
832
+ const dataField = this.data.Fields.find(df => df.ApiName === currentField.key);
833
+ currentField = this.createBaseField(uiControlField, dataField);
834
+ this._fieldsSubject.value[i] = currentField;
835
+ }
836
+ else if (currentField.controlType !== 'internalPage') {
837
+ if (currentField.groupFields &&
838
+ currentField.groupFields.length > 0) {
839
+ // for (let j = 0; j < currentField.groupFields.length; j++) {
840
+ // let currentGroupField = currentField.groupFields[j];
841
+ for (const currentGroupField of currentField.groupFields) {
842
+ const fieldFormattedValue = this.getFieldFormattedValue(currentGroupField);
843
+ this.customizationService.updateFormField(this.form, currentGroupField, fieldFormattedValue, currentField);
844
+ }
845
+ }
846
+ else {
847
+ const fieldFormattedValue = this.getFieldFormattedValue(currentField);
848
+ // this.form.controls[currentField.key].setValue(fieldFormattedValue);
849
+ this.customizationService.updateFormField(this.form, currentField, fieldFormattedValue);
850
+ }
851
+ }
852
+ if (!currentField.readonly) {
853
+ allFieldsAreReadOnly = false;
854
+ }
855
+ }
856
+ }
857
+ let isFormValid = (_a = this.form) === null || _a === void 0 ? void 0 : _a.valid;
858
+ // Change validation to true if all fields are read only.
859
+ if (!isFormValid && allFieldsAreReadOnly) {
860
+ isFormValid = true;
861
+ }
862
+ this.onFormValidationChanged(isFormValid);
863
+ // Set it to false to enable all fields.
864
+ if (this.isInternal && this.isLocked) {
865
+ this.isLocked = false;
866
+ }
867
+ }
868
+ initForm() {
869
+ if (this.data && this.data.Fields) {
870
+ const fields = this.convertCustomFields(this.getUiControlFields(), this.data.Fields);
871
+ const maxRow = Math.max(...fields.map((f) => {
872
+ return f.row + f.rowSpan;
873
+ }));
874
+ this.columns = Math.max(...fields.map((f) => {
875
+ return f.col + f.colSpan;
876
+ }));
877
+ this.initFieldsStructure(fields, maxRow);
878
+ this.setForm();
879
+ }
880
+ }
881
+ updateField(customField, updatedField) {
882
+ const options = {
883
+ disabled: !updatedField.Enabled || !this.canEditObject,
884
+ readonly: !updatedField.Enabled || !this.canEditObject,
885
+ visible: updatedField.Visible,
886
+ value: updatedField.Value,
887
+ additionalValue: updatedField.AdditionalValue,
888
+ formattedValue: updatedField.FormattedValue,
889
+ textColor: updatedField.TextColor,
890
+ };
891
+ if (customField instanceof PepQuantitySelectorField) {
892
+ const notificationInfo = updatedField.NotificationInfo;
893
+ options.notificationInfo = notificationInfo;
894
+ // Change type if it's change (only for allowDecimal).
895
+ let allowDecimal = false;
896
+ if (updatedField.FieldType === FIELD_TYPE.NumberRealQuantitySelector ||
897
+ updatedField.FieldType === FIELD_TYPE.NumberReal ||
898
+ updatedField.FieldType === FIELD_TYPE.NumberRealForMatrix) {
899
+ allowDecimal = true;
900
+ }
901
+ options.allowDecimal = allowDecimal;
902
+ }
903
+ else if (customField instanceof PepSelectField) {
904
+ options.options = this.convertOptionalValues(updatedField.OptionalValues);
905
+ if (!options.options || options.options.length === 0) {
906
+ options.options.push({
907
+ key: options.value,
908
+ value: options.formattedValue,
909
+ });
910
+ }
911
+ }
912
+ else if (customField instanceof PepInternalCaruselField) {
913
+ options.pageInfo = updatedField.UIPageInfo;
914
+ }
915
+ customField.update(options);
916
+ }
917
+ updateForm() {
918
+ if (this.data && this.data.Fields) {
919
+ for (const currentField of this.data.Fields) {
920
+ const customField = this.fields.filter((f) => f.key === currentField.ApiName)[0];
921
+ // Update all fields except 'internalPage' type (for children).
922
+ if (customField && customField.controlType !== 'internalPage') {
923
+ this.updateField(customField, currentField);
924
+ // Update the group fields.
925
+ if (customField.controlType === 'address' &&
926
+ currentField.GroupFields) {
927
+ // for (let j = 0; j < currentField.GroupFields.length; j++) {
928
+ // let currentGroupField = currentField.GroupFields[j];
929
+ for (const currentGroupField of currentField.GroupFields) {
930
+ currentGroupField.Enabled = !currentField.Enabled
931
+ ? false
932
+ : currentGroupField.Enabled;
933
+ const customGroupField = customField.groupFields.filter((f) => f.key === currentGroupField.ApiName)[0];
934
+ this.updateField(customGroupField, currentGroupField);
935
+ }
936
+ }
937
+ }
938
+ }
939
+ this.setForm(true);
940
+ }
941
+ }
942
+ ReloadForm() {
943
+ this._shouldReloadForm = true;
944
+ }
945
+ // onSubmit() {
946
+ // if (this.form.valid) {
947
+ // this.payLoad = JSON.stringify(this.form.value);
948
+ // //this.submitted.emit(this.form.value);
949
+ // }
950
+ // }
951
+ getFormControlById(key) {
952
+ let formControl = null;
953
+ this.fields.forEach((field) => {
954
+ if (field.key === key) {
955
+ formControl = this.form.get(field.key);
956
+ return;
957
+ }
958
+ else if (field.groupFields && field.groupFields.length > 0) {
959
+ field.groupFields.forEach((groupField) => {
960
+ if (groupField.key === key) {
961
+ formControl = this.form.get(field.key + '.' + groupField.key);
962
+ return;
963
+ }
964
+ });
965
+ }
966
+ });
967
+ return formControl;
968
+ }
969
+ setSpecialFields(controlFields, dataFields) {
970
+ // let cf;
971
+ // for (let index = 0; index < controlFields.length; index++) {
972
+ // cf = controlFields[index];
973
+ for (const cf of controlFields) {
974
+ if (cf.ApiName === 'ObjectMenu') {
975
+ this.menuField = cf;
976
+ }
977
+ else if (cf.ApiName === 'ItemHasActiveCampaign') {
978
+ this.hasCampaignField = cf;
979
+ }
980
+ else if (cf.ApiName === 'ItemIndicatorsWithoutCampaign') {
981
+ this.indicatorsField = cf;
982
+ }
983
+ }
984
+ // let df;
985
+ // for (let index = 0; index < dataFields.length; index++) {
986
+ // df = dataFields[index];
987
+ for (const df of dataFields) {
988
+ if (df.ApiName === 'ObjectMenu') {
989
+ this.menuDataField = df;
990
+ }
991
+ else if (df.ApiName === 'ItemHasActiveCampaign') {
992
+ this.hasCampaignDataField = df;
993
+ }
994
+ else if (df.ApiName === 'ItemIndicatorsWithoutCampaign') {
995
+ this.indicatorsDataField = df;
996
+ }
997
+ }
998
+ if (this.menuField && this.menuDataField) {
999
+ this.menuDataField.Layout = this.menuField.Layout;
1000
+ }
1001
+ if (this.hasCampaignField && this.hasCampaignDataField) {
1002
+ this.hasCampaignDataField.Layout = this.hasCampaignField.Layout;
1003
+ }
1004
+ if (this.indicatorsField && this.indicatorsDataField) {
1005
+ this.indicatorsDataField.Layout = this.indicatorsField.Layout;
1006
+ }
1007
+ // Check if menu is floating on other field.
1008
+ // for (let index = 0; index < controlFields.length; index++) {
1009
+ // cf = controlFields[index];
1010
+ for (const cf of controlFields) {
1011
+ if (this.menuField && cf.ApiName !== 'ObjectMenu') {
1012
+ this.hasMenuFloatingOnOtherField = this.doesFieldHavaFloatingField(cf, this.menuField);
1013
+ if (this.hasMenuFloatingOnOtherField) {
1014
+ break;
1015
+ }
1016
+ }
1017
+ }
1018
+ }
1019
+ convertCustomFields(controlFields, dataFields) {
1020
+ if (this.layoutType !== 'table') {
1021
+ this.setSpecialFields(controlFields, dataFields);
1022
+ }
1023
+ else {
1024
+ // HACK: convert to center alignment if table view & special fields)
1025
+ controlFields.forEach((field, index) => {
1026
+ if (field.ApiName === 'UnitsQuantity' ||
1027
+ field.ApiName === 'QuantitySelector' ||
1028
+ field.ApiName === 'ObjectMenu' ||
1029
+ field.FieldType === FIELD_TYPE.Image ||
1030
+ field.FieldType === FIELD_TYPE.ImageURL ||
1031
+ field.FieldType === FIELD_TYPE.Indicators ||
1032
+ field.FieldType === FIELD_TYPE.Boolean ||
1033
+ field.FieldType === FIELD_TYPE.CalculatedBool ||
1034
+ field.FieldType === FIELD_TYPE.Signature ||
1035
+ field.FieldType ===
1036
+ FIELD_TYPE.NumberIntegerQuantitySelector ||
1037
+ field.FieldType === FIELD_TYPE.NumberRealQuantitySelector ||
1038
+ field.FieldType === FIELD_TYPE.Package ||
1039
+ field.FieldType === FIELD_TYPE.NumberIntegerForMatrix ||
1040
+ field.FieldType === FIELD_TYPE.NumberRealForMatrix) {
1041
+ field.Layout.XAlignment = X_ALIGNMENT_TYPE.Center;
1042
+ }
1043
+ else {
1044
+ // HACK: align the rest of the fields by the culture.
1045
+ // field.Layout.XAlignment = this.layoutService.isRtl() ? X_ALIGNMENT_TYPE.Right : X_ALIGNMENT_TYPE.Left;
1046
+ }
1047
+ });
1048
+ }
1049
+ const fields = [];
1050
+ controlFields.forEach((field, index) => {
1051
+ const dataField = dataFields.filter((df) => df.ApiName === field.ApiName)[0];
1052
+ if (!dataField) {
1053
+ return;
1054
+ }
1055
+ // If current view is not table view and those fields are special.
1056
+ if (this.layoutType !== 'table' &&
1057
+ ((this.hasMenuFloatingOnOtherField &&
1058
+ this.menuField &&
1059
+ this.menuField.ApiName === field.ApiName) ||
1060
+ (this.indicatorsField &&
1061
+ this.indicatorsField.ApiName === field.ApiName) ||
1062
+ (this.hasCampaignField &&
1063
+ this.hasCampaignField.ApiName === field.ApiName))) {
1064
+ return;
1065
+ }
1066
+ // Set type to link
1067
+ if (index === 0 && this.firstFieldAsLink) {
1068
+ dataField.FieldType = FIELD_TYPE.InternalLink;
1069
+ // dataField.Value = this.getInternalLinkHref();
1070
+ }
1071
+ if (field.ApiName === 'ObjectMenu') {
1072
+ dataField.Enabled = true;
1073
+ // HACK : Until "Enabled" returns from the server, we set PepMenu to be
1074
+ // Disabled in cart on regular items and not campign items.
1075
+ }
1076
+ const customField = this.createBaseField(field, dataField);
1077
+ fields.push(customField);
1078
+ });
1079
+ return fields.sort((f1, f2) => f1.row > f2.row
1080
+ ? 1
1081
+ : f1.row < f2.row
1082
+ ? -1
1083
+ : f1.col > f2.col
1084
+ ? 1
1085
+ : f1.col < f2.col
1086
+ ? -1
1087
+ : 0);
1088
+ }
1089
+ onFormValidationChanged(formValidationChange) {
1090
+ this.formValidationChange.emit(formValidationChange);
1091
+ }
1092
+ onValueChanged(event) {
1093
+ this.onFormValidationChanged(this.form.valid);
1094
+ const formControl = this.getFormControlById(event.key);
1095
+ const isValid = formControl ? formControl.valid : true;
1096
+ // const isValid = true;
1097
+ if (isValid) {
1098
+ // Set it to false to disable all fields.
1099
+ if (this.isInternal && this.layoutType === 'form') {
1100
+ this.isLocked = true;
1101
+ }
1102
+ // Update the current field value.
1103
+ const currentField = this.fields.find((f) => f.key === event.key);
1104
+ if (currentField) {
1105
+ currentField.formattedValue = currentField.value = event.value;
1106
+ }
1107
+ this.valueChange.emit({
1108
+ id: this.data.UID.toString(),
1109
+ uiObjectKey: this.data.Key,
1110
+ key: event.key,
1111
+ value: event.value,
1112
+ controlType: event.controlType,
1113
+ });
1114
+ }
1115
+ }
1116
+ onClick(fieldClickEvent) {
1117
+ const clickedUiControlField = this.data.Fields.filter((f) => f.ApiName === fieldClickEvent.key)[0];
1118
+ const idType = this.data.Type ? this.data.Type.toString() : '';
1119
+ if (clickedUiControlField) {
1120
+ this.fieldClick.emit({
1121
+ id: this.data.UID.toString(),
1122
+ uiObjectKey: this.data.Key,
1123
+ key: fieldClickEvent.key,
1124
+ idType,
1125
+ which: fieldClickEvent.eventWhich,
1126
+ value: fieldClickEvent.value,
1127
+ controlType: fieldClickEvent.controlType,
1128
+ fieldType: clickedUiControlField.FieldType,
1129
+ otherData: fieldClickEvent.otherData,
1130
+ });
1131
+ }
1132
+ else {
1133
+ // For other api names (like enter children etc).
1134
+ this.fieldClick.emit({
1135
+ id: this.data.UID.toString(),
1136
+ uiObjectKey: this.data.Key,
1137
+ key: fieldClickEvent.key,
1138
+ idType,
1139
+ which: fieldClickEvent.eventWhich,
1140
+ value: fieldClickEvent.value,
1141
+ controlType: fieldClickEvent.controlType,
1142
+ otherData: fieldClickEvent.otherData,
1143
+ });
1144
+ }
1145
+ }
1146
+ // This event is for handle the internal page events.
1147
+ onInternalFormFieldClicked(internalFormFieldClick) {
1148
+ this.internalFormFieldClick.emit(internalFormFieldClick);
1149
+ }
1150
+ // This event is for handle the internal page events.
1151
+ onInternalFormFieldChanged(internalFormFieldChange) {
1152
+ this.internalFormFieldChange.emit(internalFormFieldChange);
1153
+ }
1154
+ // This event is for handle the related items change events.
1155
+ onFormValueChanged(event) {
1156
+ // this.valueChange.emit(event);
1157
+ }
1158
+ // This event is for handle the related items change events.
1159
+ onFormFieldClick(event) {
1160
+ this.fieldClick.emit(event);
1161
+ }
1162
+ }
1163
+ PepFormComponent.decorators = [
1164
+ { type: Component, args: [{
1165
+ selector: 'pep-form',
1166
+ template: "<fieldset *ngIf=\"form\" [formGroup]=\"form\" [disabled]=\"isLocked\" class=\"pep-form\"\n [ngStyle]=\"{ 'background-color': layoutType == 'card' && data?.BackgroundColor }\">\n <!-- New Form -->\n <mat-grid-list *ngIf=\"layoutType == 'form'\" [cols]=\"columns\" [rowHeight]=\"rowHeight + 'rem'\"\n [gutterSize]=\"formGutterSize\">\n <mat-grid-tile *ngFor=\"let field of fields$ | async\" [rowspan]=\"field.rowSpan\" [colspan]=\"field.colSpan\">\n <pep-field-generator *ngIf=\"field.controlType != 'placeholder'\" [form]=\"form\" [layoutType]=\"layoutType\"\n [checkForChanges]=\"checkForChanges\" [uid]=\"data?.UID\" [field]=\"field\" [showTitle]=\"showTitle\"\n (valueChange)=\"onValueChanged($event)\" (elementClick)=\"onClick($event)\"\n (internalFormFieldClick)=\"onInternalFormFieldClicked($event)\"\n (internalFormFieldChange)=\"onInternalFormFieldChanged($event)\"\n (formValueChange)=\"onFormValueChanged($event)\" (formFieldClick)=\"onFormFieldClick($event)\"\n (formValidationChange)=\"onFormValidationChanged($event)\">\n </pep-field-generator>\n </mat-grid-tile>\n </mat-grid-list>\n\n <!-- Thumbnails -->\n <mat-grid-list *ngIf=\"layoutType == 'card'\" [cols]=\"columns\" [rowHeight]=\"rowHeight + 'rem'\"\n [gutterSize]=\"cardGutterSize\" class=\"card-spacing\">\n <mat-grid-tile *ngFor=\"let field of fields$ | async\" [rowspan]=\"field.rowSpan\" [colspan]=\"field.colSpan\"\n [ngStyle]=\"{ overflow: field.type == 'qs' ? 'unset' : 'hidden' }\">\n <pep-field-generator *ngIf=\"field.controlType != 'placeholder'\" [form]=\"form\" [layoutType]=\"layoutType\"\n [ngClass]=\"{ 'lock-events': lockEvents }\" [isActive]=\"isActive\" [checkForChanges]=\"checkForChanges\"\n [uid]=\"data?.UID\" [field]=\"field\" [showTitle]=\"showTitle\" (valueChange)=\"onValueChanged($event)\"\n (elementClick)=\"onClick($event)\" (internalFormFieldClick)=\"onInternalFormFieldClicked($event)\"\n (internalFormFieldChange)=\"onInternalFormFieldChanged($event)\"\n (formValueChange)=\"onFormValueChanged($event)\" (formFieldClick)=\"onFormFieldClick($event)\">\n </pep-field-generator>\n </mat-grid-tile>\n </mat-grid-list>\n\n <ng-container *ngIf=\"layoutType == 'table'\">\n <ng-container *ngIf=\"isReport; then reportBlock; else notReportBlock\"></ng-container>\n <ng-template #reportBlock>\n <ng-container *ngTemplateOutlet=\"report\"></ng-container>\n </ng-template>\n <ng-template #notReportBlock>\n <div *ngFor=\"let field of fields$ | async; let j = index\" class=\"pull-left flip table-cell \"\n [ngClass]=\"['text-align-' + field.xAlignment]\" style=\"height: 100%\"\n [ngStyle]=\"{ width: (layout?.ControlFields)[j]?.calcColumnWidthString}\">\n <pep-field-generator *ngIf=\"field.controlType != 'placeholder'\" [checkForChanges]=\"checkForChanges\"\n [uid]=\"data?.UID\" [field]=\"field\" [form]=\"form\" [layoutType]=\"layoutType\" [showTitle]=\"false\"\n (elementClick)=\"onClick($event)\" (valueChange)=\"onValueChanged($event)\"\n (formValueChange)=\"onFormValueChanged($event)\" (formFieldClick)=\"onFormFieldClick($event)\"\n [isActive]=\"isActive\">\n </pep-field-generator>\n </div>\n </ng-template>\n </ng-container>\n\n <!------- For testing ------------\n {{ form.value | json }}\n {{ form.valid }}\n ---------------------------------->\n</fieldset>\n\n<ng-template #report>\n <div *ngFor=\"let field of fields$ | async; let j = index\" class=\"pull-left flip pep-report-fields\"\n [ngStyle]=\"{ width: (layout?.ControlFields)[j]?.calcColumnWidthString }\"\n [ngClass]=\"['text-align-' + field.xAlignment]\">\n <ng-container [ngSwitch]=\"field.controlType\">\n <pep-image *ngSwitchCase=\"'image'\" [uid]=\"data?.UID\" [form]=\"form\" [key]=\"field.key\"\n [src]=\"field.formattedValue\" [srcLarge]=\"field.value\" [options]=\"field.options\" [label]=\"field.label\"\n [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\" [readonly]=\"field.readonly\"\n [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\" [layoutType]=\"layoutType\"\n (elementClick)=\"onClick($event)\">\n </pep-image>\n\n <pep-signature *ngSwitchCase=\"'signature'\" [form]=\"form\" [key]=\"field.key\" [src]=\"field.value\"\n [label]=\"field.label\" [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\"\n [readonly]=\"field.readonly\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [layoutType]=\"layoutType\">\n </pep-signature>\n\n <pep-checkbox *ngSwitchCase=\"'checkbox'\" [form]=\"form\" [key]=\"field.key\"\n [value]=\"(field.value | lowercase) == 'true' || field.value == '1' ? true : false\" [label]=\"field.label\"\n [type]=\"field.type\" [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\"\n [readonly]=\"field.readonly\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [additionalValue]=\"field.additionalValue\" [layoutType]=\"layoutType\">\n </pep-checkbox>\n\n <pep-date *ngSwitchCase=\"'date'\" [form]=\"form\" [key]=\"field.key\" [value]=\"field.value\"\n [formattedValue]=\"field.formattedValue\" [label]=\"field.label\" [type]=\"field.type\"\n [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\" [readonly]=\"field.readonly\"\n [textColor]=\"field.textColor\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [minValue]=\"field.minValue\" [maxValue]=\"field.maxValue\" [layoutType]=\"layoutType\">\n </pep-date>\n\n <pep-internal-button *ngSwitchCase=\"'button'\" [form]=\"form\" [key]=\"field.key\" [value]=\"field.value\"\n [formattedValue]=\"field.formattedValue\" [label]=\"field.label\" [type]=\"field.type\"\n [disabled]=\"field.disabled\" [readonly]=\"field.readonly\" [xAlignment]=\"field.xAlignment\"\n [layoutType]=\"layoutType\" (elementClick)=\"onClick($event)\">\n </pep-internal-button>\n\n <pep-textarea *ngSwitchCase=\"'textarea'\" [form]=\"form\" [key]=\"field.key\" [value]=\"field.value\"\n [label]=\"field.label\" [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\"\n [readonly]=\"field.readonly\" [maxFieldCharacters]=\"field.maxFieldCharacters\"\n [textColor]=\"field.textColor\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [layoutType]=\"layoutType\">\n </pep-textarea>\n\n <pep-quantity-selector *ngSwitchCase=\"'qs'\" [id]=\"field.key\" [form]=\"form\" [key]=\"field.key\"\n [value]=\"field.value\" [formattedValue]=\"field.formattedValue\" [label]=\"field.label\" [type]=\"field.type\"\n [mandatory]=\"field.mandatory\" [disabled]=\"field.disabled\" [readonly]=\"field.readonly\"\n [textColor]=\"field.textColor\" [xAlignment]=\"field.xAlignment\" [rowSpan]=\"field.rowSpan\"\n [layoutType]=\"layoutType\" (valueChange)=\"onValueChanged($event)\" (elementClick)=\"onClick($event)\">\n </pep-quantity-selector>\n\n <ng-container *ngSwitchDefault>\n <ng-container *ngIf=\"field.formattedValue?.length > 0; then notEmptyBlock; else emptyBlock\">\n </ng-container>\n <ng-template #notEmptyBlock>\n <ng-container\n *ngIf=\"field.controlType === 'attachment' || field.type === 'link'; then linkBlock; else notLinkBlock\">\n </ng-container>\n <ng-template #linkBlock>\n <a [id]=\"field.key\" class=\"color-link body-sm pep-report-input readonly\"\n *ngIf=\"field.formattedValue != null\" title=\"{{ field.formattedValue }}\" target=\"_blank\"\n href=\"{{ field.value }}\">{{ field.formattedValue }}</a>\n </ng-template>\n <ng-template #notLinkBlock>\n <span [id]=\"field.key\" class=\"body-sm pep-report-input readonly\"\n title=\"{{ field.formattedValue }}\" [ngStyle]=\"{ color: field.textColor }\">{{\n field.formattedValue }}</span>\n </ng-template>\n </ng-template>\n <ng-template #emptyBlock>\n <span>&nbsp;</span>\n </ng-template>\n </ng-container>\n </ng-container>\n </div>\n</ng-template>",
1167
+ changeDetection: ChangeDetectionStrategy.OnPush,
1168
+ styles: [":host{display:grid}"]
1169
+ },] }
1170
+ ];
1171
+ PepFormComponent.ctorParameters = () => [
1172
+ { type: PepDialogService },
1173
+ { type: PepCustomizationService },
1174
+ { type: PepLayoutService },
1175
+ { type: FormBuilder },
1176
+ { type: KeyValueDiffers },
1177
+ { type: TranslateService }
1178
+ ];
1179
+ PepFormComponent.propDecorators = {
1180
+ isInternal: [{ type: Input }],
1181
+ isReport: [{ type: Input }],
1182
+ layout: [{ type: Input }],
1183
+ lockEvents: [{ type: Input }],
1184
+ canEditObject: [{ type: Input }],
1185
+ data: [{ type: Input }],
1186
+ lockFields: [{ type: Input }],
1187
+ isActive: [{ type: Input }],
1188
+ layoutType: [{ type: Input }],
1189
+ objectId: [{ type: Input }],
1190
+ parentId: [{ type: Input }],
1191
+ searchCode: [{ type: Input }],
1192
+ showTitle: [{ type: Input }],
1193
+ firstFieldAsLink: [{ type: Input }],
1194
+ checkForChanges: [{ type: Input }],
1195
+ valueChange: [{ type: Output }],
1196
+ formValidationChange: [{ type: Output }],
1197
+ fieldClick: [{ type: Output }],
1198
+ internalFormFieldClick: [{ type: Output }],
1199
+ internalFormFieldChange: [{ type: Output }]
1200
+ };
1201
1201
  //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZm9ybS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9wcm9qZWN0cy9uZ3gtbGliL2Zvcm0vZm9ybS5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNILFNBQVMsRUFDVCx1QkFBdUIsRUFHdkIsS0FBSyxFQUNMLGVBQWUsRUFDZixNQUFNLEVBQ04sWUFBWSxHQUdmLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFFSCxXQUFXLEVBQ1gsVUFBVSxHQUViLE1BQU0sZ0JBQWdCLENBQUM7QUFDeEIsT0FBTyxFQUFFLGdCQUFnQixFQUFFLE1BQU0scUJBQXFCLENBQUM7QUFDdkQsT0FBTyxFQUNILGdCQUFnQixFQUNoQixhQUFhLEdBQ2hCLE1BQU0sZ0NBQWdDLENBQUM7QUFDeEMsT0FBTyxFQUlILFVBQVUsRUFDVix1QkFBdUIsRUFDdkIsZ0JBQWdCLEVBTWhCLGVBQWUsRUFDZixjQUFjLEVBQ2Qsb0JBQW9CLEVBQ3BCLHdCQUF3QixFQUN4QixlQUFlLEVBQ2Ysa0JBQWtCLEVBQ2xCLG9CQUFvQixFQUNwQix1QkFBdUIsRUFDdkIsc0JBQXNCLEVBQ3RCLGtCQUFrQixFQUNsQixpQkFBaUIsRUFDakIsYUFBYSxFQUNiLGNBQWMsRUFDZCxZQUFZLEVBQ1osZ0JBQWdCLEVBQ2hCLHdCQUF3QixFQUN4QixZQUFZLEVBQ1osZ0JBQWdCLEVBQ2hCLGlCQUFpQixFQUNqQixtQkFBbUIsRUFHbkIsZ0JBQWdCLEVBQ2hCLGdCQUFnQixFQUNoQiwwQkFBMEIsRUFDMUIsNEJBQTRCLEdBRy9CLE1BQU0seUJBQXlCLENBQUM7QUFDakMsT0FBTyxFQUFFLGVBQWUsRUFBYyxNQUFNLE1BQU0sQ0FBQztBQVNuRCxNQUFNLE9BQU8sZ0JBQWdCO0lBbUZ6QixpQ0FBaUM7SUFDakMseUJBQXlCO0lBRXpCLFlBQ1ksYUFBK0IsRUFDL0Isb0JBQTZDLEVBQzdDLGFBQStCLEVBQy9CLEVBQWUsRUFDdkIsT0FBd0IsRUFDaEIsU0FBMkI7UUFMM0Isa0JBQWEsR0FBYixhQUFhLENBQWtCO1FBQy9CLHlCQUFvQixHQUFwQixvQkFBb0IsQ0FBeUI7UUFDN0Msa0JBQWEsR0FBYixhQUFhLENBQWtCO1FBQy9CLE9BQUUsR0FBRixFQUFFLENBQWE7UUFFZixjQUFTLEdBQVQsU0FBUyxDQUFrQjtRQTNGOUIsZUFBVSxHQUFHLElBQUksQ0FBQztRQUNsQixhQUFRLEdBQUcsS0FBSyxDQUFDO1FBRWpCLGVBQVUsR0FBRyxLQUFLLENBQUM7UUFDbkIsa0JBQWEsR0FBRyxJQUFJLENBQUM7UUFFdEIsVUFBSyxHQUFtQixJQUFJLENBQUM7UUFzQjVCLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakIsZUFBVSxHQUFrQixNQUFNLENBQUM7UUFDNUMsMEJBQTBCO1FBQ2pCLGFBQVEsR0FBRyxHQUFHLENBQUM7UUFDZixhQUFRLEdBQUcsR0FBRyxDQUFDO1FBQ2YsZUFBVSxHQUFHLEdBQUcsQ0FBQztRQUNqQixjQUFTLEdBQUcsSUFBSSxDQUFDO1FBQ2pCLHFCQUFnQixHQUFHLEtBQUssQ0FBQztRQUN6QixvQkFBZSxHQUFRLElBQUksQ0FBQztRQUdyQyxnQkFBVyxHQUFnRCxJQUFJLFlBQVksRUFBaUMsQ0FBQztRQUU3Ryx5QkFBb0IsR0FBMEIsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUcxRSxlQUFVLEdBQTBDLElBQUksWUFBWSxFQUEyQixDQUFDO1FBRXRGLDJCQUFzQixHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ3BFLDRCQUF1QixHQUFzQixJQUFJLFlBQVksRUFBTyxDQUFDO1FBRS9FLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFTakIsZ0JBQWdCO1FBQ1IsU0FBSSxHQUEwQixFQUFFLENBQUM7UUFDekMsV0FBTSxHQUFtQixFQUFFLENBQUM7UUFFcEIsbUJBQWMsR0FBb0MsSUFBSSxlQUFlLENBQWlCLEVBQUUsQ0FBQyxDQUFDO1FBS2xHLFlBQU8sR0FBRyxDQUFDLENBQUM7UUFFSixnQ0FBMkIsR0FBRyxLQUFLLENBQUM7UUFNcEMsd0JBQW1CLEdBQVEsSUFBSSxDQUFDO1FBRWhDLHNCQUFpQixHQUFHLEtBQUssQ0FBQztRQWdCOUIsMENBQTBDO1FBQzFDLElBQUksQ0FBQyxNQUFNLEdBQUcsT0FBTyxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUM1QyxDQUFDO0lBeEZELElBQ0ksSUFBSSxDQUFDLEtBQXFCO1FBQzFCLE1BQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7UUFDMUQsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFFbkIsSUFBSSxZQUFZLEVBQUU7WUFDZCxJQUFJLENBQUMsaUJBQWlCLEdBQUcsS0FBSyxDQUFDO1lBQy9CLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQztTQUNuQjthQUFNO1lBQ0gsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1NBQ3JCO0lBQ0wsQ0FBQztJQUNELElBQUksSUFBSTtRQUNKLE9BQU8sSUFBSSxDQUFDLEtBQUssQ0FBQztJQUN0QixDQUFDO0lBRUQsSUFDSSxVQUFVLENBQUMsS0FBYztRQUN6QixJQUFJLENBQUMsUUFBUSxHQUFHLEtBQUssQ0FBQztJQUMxQixDQUFDO0lBcUNELElBQUksT0FBTztRQUNQLE9BQU8sSUFBSSxDQUFDLGNBQWMsQ0FBQyxZQUFZLEVBQUUsQ0FBQztJQUM5QyxDQUFDO0lBYUQsSUFBSSxnQkFBZ0I7UUFDaEIsT0FBTyxJQUFJLENBQUMsaUJBQWlCLENBQUM7SUFDbEMsQ0FBQztJQWlCRCw4QkFBOEIsQ0FDMUIsTUFBd0I7UUFFeEIsSUFBSSxHQUFHLEdBQUcsNEJBQTRCLENBQUM7UUFFdkMsSUFDSSxNQUFNLEtBQUssZ0JBQWdCLENBQUMsSUFBSTtZQUNoQyxNQUFNLEtBQUssZ0JBQWdCLENBQUMsSUFBSSxFQUNsQztZQUNFLEdBQUcsR0FBRyxNQUFNLENBQUM7U0FDaEI7YUFBTSxJQUFJLE1BQU0sS0FBSyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUU7WUFDMUMsR0FBRyxHQUFHLE9BQU8sQ0FBQztTQUNqQjthQUFNO1lBQ0gsR0FBRyxHQUFHLFFBQVEsQ0FBQztTQUNsQjtRQUVELE9BQU8sR0FBRyxDQUFDO0lBQ2YsQ0FBQztJQUVELDRCQUE0QixDQUN4QixNQUF3QjtRQUV4QixJQUFJLEdBQUcsR0FBRywwQkFBMEIsQ0FBQztRQUVyQyxJQUNJLE1BQU0sS0FBSyxnQkFBZ0IsQ0FBQyxJQUFJO1lBQ2hDLE1BQU0sS0FBSyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQ2pDO1lBQ0UsR0FBRyxHQUFHLEtBQUssQ0FBQztTQUNmO2FBQU0sSUFBSSxNQUFNLEtBQUssZ0JBQWdCLENBQUMsTUFBTSxFQUFFO1lBQzNDLEdBQUcsR0FBRyxRQUFRLENBQUM7U0FDbEI7YUFBTTtZQUNILEdBQUcsR0FBRyxRQUFRLENBQUM7U0FDbEI7UUFFRCxPQUFPLEdBQUcsQ0FBQztJQUNmLENBQUM7SUFFRCxxQkFBcUIsQ0FDakIsY0FBMkM7UUFFM0MsSUFBSSxjQUFjLElBQUksY0FBYyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDN0MsT0FBTyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUU7Z0JBQzdCLE9BQU8sRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsRUFBRSxLQUFLLEVBQUUsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDO1lBQzVDLENBQUMsQ0FBQyxDQUFDO1NBQ047YUFBTTtZQUNILE9BQU8sRUFBRSxDQUFDO1NBQ2I7SUFDTCxDQUFDO0lBRUQsb0JBQW9CLENBQ2hCLFlBQTRCLEVBQzVCLGFBQXdDLEVBQ3hDLGFBQXNCO1FBRXRCLE1BQU0sTUFBTSxHQUFtQixFQUFFLENBQUM7UUFFbEMsYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQzVCLElBQUksV0FBeUIsQ0FBQztZQUM5QixNQUFNLFdBQVcsR0FBRyxLQUFLLENBQUMsT0FBTyxDQUFDO1lBRWxDLElBQUksS0FBSyxDQUFDLE9BQU8sQ0FBQyxXQUFXLEVBQUUsQ0FBQyxPQUFPLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxFQUFFO2dCQUNwRCxXQUFXLEdBQUcsSUFBSSxlQUFlLENBQUM7b0JBQzlCLEdBQUcsRUFBRSxLQUFLLENBQUMsT0FBTztvQkFDbEIsS0FBSyxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUNwQixJQUFJLEVBQUUsTUFBTTtvQkFDWixXQUFXO29CQUNYLFFBQVEsRUFBRSxDQUFDLGFBQWE7b0JBQ3hCLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksQ0FBQyxhQUFhO29CQUMxQyxNQUFNLEVBQUUsS0FBSztvQkFDYixTQUFTLEVBQUUsS0FBSztvQkFDaEIsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO29CQUNsQixjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWM7b0JBQ3BDLEdBQUcsRUFBRSxDQUFDO29CQUNOLE9BQU8sRUFBRSxDQUFDO29CQUNWLEdBQUcsRUFBRSxDQUFDO29CQUNOLE9BQU8sRUFBRSxDQUFDO29CQUNWLFVBQVUsRUFBRSxJQUFJLENBQUMsOEJBQThCLENBQzNDLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUNqQztvQkFDRCxVQUFVLEVBQUUsSUFBSSxDQUFDLDRCQUE0QixDQUN6QyxZQUFZLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FDakM7b0JBQ0QsS0FBSyxFQUFFLENBQUM7aUJBQ1gsQ0FBQyxDQUFDO2FBQ047aUJBQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQ3pELFdBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBQztvQkFDOUIsR0FBRyxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUNsQixLQUFLLEVBQUUsS0FBSyxDQUFDLE9BQU87b0JBQ3BCLElBQUksRUFBRSxNQUFNO29CQUNaLFdBQVc7b0JBQ1gsUUFBUSxFQUFFLENBQUMsYUFBYTtvQkFDeEIsUUFBUSxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxDQUFDLGFBQWE7b0JBQzFDLE1BQU0sRUFBRSxLQUFLO29CQUNiLFNBQVMsRUFBRSxLQUFLO29CQUNoQixLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUs7b0JBQ2xCLGNBQWMsRUFBRSxLQUFLLENBQUMsY0FBYztvQkFDcEMsR0FBRyxFQUFFLENBQUM7b0JBQ04sT0FBTyxFQUFFLENBQUM7b0JBQ1YsR0FBRyxFQUFFLENBQUM7b0JBQ04sT0FBTyxFQUFFLENBQUM7b0JBQ1YsVUFBVSxFQUFFLElBQUksQ0FBQyw4QkFBOEIsQ0FDM0MsWUFBWSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQ2pDO29CQUNELFVBQVUsRUFBRSxJQUFJLENBQUMsNEJBQTRCLENBQ3pDLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUNqQztvQkFDRCxLQUFLLEVBQUUsQ0FBQztpQkFDWCxDQUFDLENBQUM7YUFDTjtpQkFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDMUQsV0FBVyxHQUFHLElBQUksY0FBYyxDQUFDO29CQUM3QixHQUFHLEVBQUUsS0FBSyxDQUFDLE9BQU87b0JBQ2xCLEtBQUssRUFBRSxLQUFLLENBQUMsT0FBTztvQkFDcEIsV0FBVztvQkFDWCxPQUFPLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7b0JBQ3pELFFBQVEsRUFBRSxDQUFDLGFBQWE7b0JBQ3hCLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksQ0FBQyxhQUFhO29CQUMxQyxNQUFNLEVBQUUsS0FBSztvQkFDYixTQUFTLEVBQUUsS0FBSztvQkFDaEIsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO29CQUNsQixjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWM7b0JBQ3BDLEdBQUcsRUFBRSxDQUFDO29CQUNOLE9BQU8sRUFBRSxDQUFDO29CQUNWLEdBQUcsRUFBRSxDQUFDO29CQUNOLE9BQU8sRUFBRSxDQUFDO29CQUNWLFVBQVUsRUFBRSxJQUFJLENBQUMsOEJBQThCLENBQzNDLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUNqQztvQkFDRCxVQUFVLEVBQUUsSUFBSSxDQUFDLDRCQUE0QixDQUN6QyxZQUFZLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FDakM7b0JBQ0QsS0FBSyxFQUFFLENBQUM7aUJBQ1gsQ0FBQyxDQUFDO2FBQ047aUJBQU0sSUFBSSxLQUFLLENBQUMsT0FBTyxDQUFDLFdBQVcsRUFBRSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLEVBQUU7Z0JBQzVELFdBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBQztvQkFDOUIsR0FBRyxFQUFFLEtBQUssQ0FBQyxPQUFPO29CQUNsQixLQUFLLEVBQUUsS0FBSyxDQUFDLE9BQU87b0JBQ3BCLElBQUksRUFBRSxNQUFNO29CQUNaLFdBQVc7b0JBQ1gsUUFBUSxFQUFFLENBQUMsYUFBYTtvQkFDeEIsUUFBUSxFQUFFLENBQUMsS0FBSyxDQUFDLE9BQU8sSUFBSSxDQUFDLGFBQWE7b0JBQzFDLE1BQU0sRUFBRSxLQUFLO29CQUNiLFNBQVMsRUFBRSxLQUFLO29CQUNoQixLQUFLLEVBQUUsS0FBSyxDQUFDLEtBQUs7b0JBQ2xCLGNBQWMsRUFBRSxLQUFLLENBQUMsY0FBYztvQkFDcEMsR0FBRyxFQUFFLENBQUM7b0JBQ04sT0FBTyxFQUFFLENBQUM7b0JBQ1YsR0FBRyxFQUFFLENBQUM7b0JBQ04sT0FBTyxFQUFFLENBQUM7b0JBQ1YsVUFBVSxFQUFFLElBQUksQ0FBQyw4QkFBOEIsQ0FDM0MsWUFBWSxDQUFDLE1BQU0sQ0FBQyxVQUFVLENBQ2pDO29CQUNELFVBQVUsRUFBRSxJQUFJLENBQUMsNEJBQTRCLENBQ3pDLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUNqQztvQkFDRCxLQUFLLEVBQUUsQ0FBQztpQkFDWCxDQUFDLENBQUM7YUFDTjtpQkFBTSxJQUFJLEtBQUssQ0FBQyxPQUFPLENBQUMsV0FBVyxFQUFFLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsRUFBRTtnQkFDNUQsV0FBVyxHQUFHLElBQUksY0FBYyxDQUFDO29CQUM3QixHQUFHLEVBQUUsS0FBSyxDQUFDLE9BQU87b0JBQ2xCLEtBQUssRUFBRSxLQUFLLENBQUMsT0FBTztvQkFDcEIsV0FBVztvQkFDWCxPQUFPLEVBQUUsSUFBSSxDQUFDLHFCQUFxQixDQUFDLEtBQUssQ0FBQyxjQUFjLENBQUM7b0JBQ3pELFFBQVEsRUFBRSxDQUFDLGFBQWE7b0JBQ3hCLFFBQVEsRUFBRSxDQUFDLEtBQUssQ0FBQyxPQUFPLElBQUksQ0FBQyxhQUFhO29CQUMxQyxNQUFNLEVBQUUsS0FBSztvQkFDYixTQUFTLEVBQUUsS0FBSztvQkFDaEIsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLO29CQUNsQixjQUFjLEVBQUUsS0FBSyxDQUFDLGNBQWM7b0JBQ3BDLEdBQUcsRUFBRSxDQUFDO29CQUNOLE9BQU8sRUFBRSxDQUFDO29CQUNWLEdBQUcsRUFBRSxDQUFDO29CQUNOLE9BQU8sRUFBRSxDQUFDO29CQUNWLFVBQVUsRUFBRSxJQUFJLENBQUMsOEJBQThCLENBQzNDLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUNqQztvQkFDRCxVQUFVLEVBQUUsSUFBSSxDQUFDLDRCQUE0QixDQUN6QyxZQUFZLENBQUMsTUFBTSxDQUFDLFVBQVUsQ0FDakM7b0JBQ0QsS0FBSyxFQUFFLENBQUM7aUJBQ1gsQ0FBQyxDQUFDO2FBQ047WUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzdCLENBQUMsQ0FBQyxDQUFDO1FBRUgsT0FBTyxNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQzFCLEVBQUUsQ0FBQyxLQUFLLEdBQUcsRUFBRSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsS0FBSyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQ3pELENBQUM7SUFDTixDQUFDO0lBRUQsYUFBYSxDQUFDLGNBQXNCO1FBQ2hDLE9BQU8sY0FBYyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVELDBCQUEwQixDQUN0QixZQUE0QixFQUM1QixhQUFrQjtRQUVsQixJQUFJLGdCQUFnQixHQUFHLEtBQUssQ0FBQztRQUM3QixJQUNJLGFBQWEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxJQUFJLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMvQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7Z0JBQ3RCLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsTUFBTTtZQUNsRCxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxZQUFZLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDL0MsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUN0QixZQUFZLENBQUMsTUFBTSxDQUFDLENBQUMsR0FBRyxZQUFZLENBQUMsTUFBTSxDQUFDLEtBQUssRUFDbkQ7WUFDRSxnQkFBZ0IsR0FBRyxJQUFJLENBQUM7U0FDM0I7UUFFRCxPQUFPLGdCQUFnQixDQUFDO0lBQzVCLENBQUM7SUFFRCx3QkFBd0IsQ0FDcEIsWUFBNEIsRUFDNUIsU0FBYyxFQUNkLGFBQXNCO1FBRXRCLElBQUksQ0FBQyxZQUFZLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDN0IsT0FBTztTQUNWO1FBRUQsTUFBTSxXQUFXLEdBQ2IsWUFBWSxDQUFDLFFBQVEsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDO1FBRXRFLElBQUksZUFBZSxHQUFHO1lBQ2xCLEdBQUcsRUFBRSxZQUFZLENBQUMsT0FBTztZQUN6QixLQUFLLEVBQUUsWUFBWSxDQUFDLEtBQUs7WUFDekIsU0FBUyxFQUFFLFNBQVMsQ0FBQyxTQUFTO1lBQzlCLFdBQVc7WUFDWCxRQUFRLEVBQUUsWUFBWSxDQUFDLFFBQVEsSUFBSSxDQUFDLGFBQWE7WUFDakQsUUFBUSxFQUFFLENBQUMsU0FBUyxDQUFDLE9BQU8sSUFBSSxDQUFDLGFBQWE7WUFDOUMsTUFBTSxFQUFFLFlBQVksQ0FBQyxNQUFNO1lBQzNCLFNBQVMsRUFBRSxZQUFZLENBQUMsU0FBUztZQUNqQyxLQUFLLEVBQUUsU0FBUyxDQUFDLEtBQUs7WUFDdEIsY0FBYyxFQUFFLFNBQVMsQ0FBQyxjQUFjO1lBQ3hDLGVBQWUsRUFBRSxTQUFTLENBQUMsZUFBZTtZQUMxQyxHQUFHLEVBQUUsWUFBWSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzFCLE9BQU8sRUFBRSxZQUFZLENBQUMsTUFBTSxDQUFDLE1BQU07WUFDbkMsR0FBRyxFQUFFLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMxQixPQUFPLEVBQUUsWUFBWSxDQUFDLE1BQU0sQ0FBQyxLQUFLO1lBQ2xDLFVBQVUsRUFBRSxJQUFJLENBQUMsOEJBQThCLENBQzNDLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUNqQztZQUNELFVBQVUsRUFBRSxJQUFJLENBQUMsNEJBQTRCLENBQ3pDLFlBQVksQ0FBQyxNQUFNLENBQUMsVUFBVSxDQUNqQztZQUNELE9BQU8sRUFBRSxJQUFJLENBQUMscUJBQXFCLENBQUMsU0FBUyxDQUFDLGNBQWMsQ0FBQztZQUM3RCxXQUFXLEVBQUUsU0FBUztZQUN0QixrQkFBa0IsRUFBRSxZQUFZLENBQUMsa0JBQWtCO1lBQ25ELFFBQVEsRUFBRSxZQUFZLENBQUMsUUFBUTtZQUMvQixRQUFRLEVBQUUsWUFBWSxDQUFDLFFBQVE7WUFDL0Isb0JBQW9CO1lBQ3BCLDRCQUE0QjtZQUM1QixnQ0FBZ0M7WUFDaEMsU0FBUyxFQUFFLFNBQVMsQ0FBQyxTQUFTO1lBQzlCLE9BQU8sRUFBRSxTQUFTLENBQUMsT0FBTztTQUM3QixDQUFDO1FBRUYsSUFBSSxTQUFTLENBQUMsZUFBZSxFQUFFO1lBQzNCLGVBQWUsbUNBQ1IsZUFBZSxHQUNmLFNBQVMsQ0FBQyxlQUFlLENBQy9CLENBQUE7U0FDSjtRQUNELE9BQU8sZUFBZSxDQUFDO0lBQzNCLENBQUM7SUFFRCxvQkFBb0IsQ0FDaEIsWUFBNEIsRUFDNUIsU0FBYyxFQUNkLGFBQXNCLEVBQ3RCLFNBQWMsRUFDZCxnQkFBcUIsRUFDckIsZUFBb0IsRUFDcEIsUUFBYSxFQUNiLFFBQWEsRUFDYixVQUFlO1FBRWYsSUFBSSxXQUF5QixDQUFDO1FBQzlCLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyx3QkFBd0IsQ0FDekMsWUFBWSxFQUNaLFNBQVMsRUFDVCxhQUFhLENBQ2hCLENBQUM7UUFFRixJQUFJLFlBQVksQ0FBQyxPQUFPLEtBQUssWUFBWSxFQUFFO1lBQ3ZDLE9BQU8sQ0FBQyxJQUFJLEdBQUcsTUFBTSxDQUFDO1lBQ3RCLFdBQVcsR0FBRyxJQUFJLG9CQUFvQixDQUFDLE9BQU8sQ0FBQyxDQUFDO1NBQ25EO2FBQU0sSUFDSCxZQUFZLENBQUMsU0FBUyxLQUFLLFVBQVUsQ0FBQywwQkFBMEI7WUFDaEUsWUFBWSxDQUFDLFNBQVM7Z0JBQ3RCLFVBQVUsQ0FBQyw2QkFBNkI7WUFDeEMsWUFBWSxDQUFDLE9BQU8sS0FBSyxrQkFBa0I7WUFDM0MsWUFBWSxDQUFDLE9BQU8sS0FBSyxlQUFlO1lBQ3hDLFlBQVksQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsRUFDN0M7WUFDRSxJQUFJLFNBQVMsQ0FBQyxTQUFTLEtBQUssVUFBVSxDQUFDLFlBQVksRUFBRTtnQkFDakQsT0FBTyxDQUFDLElBQUksR0FBRyxRQUFRLENBQUM7YUFDM0I7aUJBQU0sSUFBSSxTQUFTLENBQUMsU0FBUyxLQUFLLFVBQVUsQ0FBQyxPQUFPLEVBQUU7Z0JBQ25ELE9BQU8sQ0FBQyxJQUFJLEdBQUcsZUFBZSxDQUFDO2FBQ2xDO2lCQUFNLElBQ0gsU0FBUyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsMEJBQTBCO2dCQUM3RCxTQUFTLENBQUMsU0FBUyxLQUFLLFVBQVUsQ0FBQyxVQUFVLEVBQy9DO2dCQUNFLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO2dCQUNwQixPQUFPLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQzthQUMvQjtpQkFBTSxJQUNILFNBQVMsQ0FBQyxTQUFTO2dCQUNuQixVQUFVLENBQUMsNkJBQTZCO2dCQUN4QyxTQUFTLENBQUMsU0FBUyxLQUFLLFVBQVUsQ0FBQyxhQUFhLEVBQ2xEO2dCQUNFLE9BQU8sQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO2dCQUNwQixPQUFPLENBQUMsWUFBWSxHQUFHLEtBQUssQ0FBQzthQUNoQztpQkFBTSxJQUNILFNBQVMsQ0FBQyxTQUFTLEtBQUssVUFBVSxDQUFDLHNCQUFzQixFQUMzRDtnQkFDRSxPQUFPLENBQUMsSUFBSSxHQUFHLGFBQWEsQ0FBQztnQkFDN0IsT0FBTyxDQUFDLFlBQVksR0FBRyxLQUFLLENBQUM7YUFDaEM7aUJBQU0sSUFBSSxTQUFTLENBQUMsU0FBUyxLQUFLLFVBQVUsQ0FBQyxtQkFBbUIsRUFBRTtnQkFDL0QsT0FBTyxDQUFDLElBQUksR0FBRyxhQUFhLENBQUM7Z0JBQzdCLE9BQU8sQ0FBQyxZQUFZLEdBQUcsSUFBSSxDQUFDO2FBQy9CO1lBRUQsT0FBTyxDQUFDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQztZQUN0RCxXQUFXLEdBQUcsSUFBSSx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUN2RDthQUFNO1lBQ0gsOEJBQThCO1lBQzlCLElBQ0ksU0FBUyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsVUFBVTtnQkFDN0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLEVBQ3ZDO2dCQUNFLFNBQVMsQ0FBQyxTQUFTLEdBQUcsVUFBVSxDQUFDLFlBQVksQ0FBQzthQUNqRDtZQUVELFFBQVEsU0FBUyxDQUFDLFNBQVMsRUFBRTtnQkFDekIsS0FBSyxVQUFVLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3JCLE1BQU0sa0JBQWtCLEdBQUcsWUFBWSxDQUFDLFFBQVE7d0JBQzVDLENBQUMsQ0FBQyxLQUFLO3dCQUNQLENBQUMsQ0FBQyxhQUFhLENBQUM7b0JBQ3BCLE9BQU8sQ0FBQyxXQUFXLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUMzQyxZQUFZLEVBQ1osU0FBUyxDQUFDLFdBQVcsRUFDckIsa0JBQWtCLENBQ3JCLENBQUM7b0JBQ0YsV0FBVyxHQUFHLElBQUksZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUMzQyxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLFVBQVUsQ0FBQyxDQUFDO29CQUN4Qiw0RUFBNEU7b0JBQzVFLFdBQVcsR0FBRyxJQUFJLGtCQUFrQixDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUM5QyxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUMxQixJQUFJLElBQUksQ0FBQyxhQUFhLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxFQUFFO3dCQUMxQyxPQUFPLENBQUMsT0FBTyxHQUFHLFlBQVksQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDO3dCQUM3QyxPQUFPLENBQUMsUUFBUSxHQUFHLFFBQVEsQ0FBQzt3QkFDNUIsT0FBTyxDQUFDLFFBQVEsR0FBRyxRQUFRLENBQUM7d0JBQzVCLE9BQU8sQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO3dCQUVoQyxXQUFXLEdBQUcsSUFBSSxvQkFBb0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztxQkFDbkQ7eUJBQU07d0JBQ0gsZ0JBQWdCO3FCQUNuQjtvQkFDRCxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLG1CQUFtQixDQUFDLENBQUM7b0JBQ2pDLE9BQU8sQ0FBQyxPQUFPLEdBQUcsWUFBWSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUM7b0JBQzdDLE9BQU8sQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFDO29CQUNoQyxPQUFPLENBQUMsUUFBUSxHQUFHLFNBQVMsQ0FBQyxVQUFVLENBQUM7b0JBRXhDLFdBQVcsR0FBRyxJQUFJLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUNuRCxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLElBQUksQ0FBQyxDQUFDO29CQUNsQixPQUFPLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQztvQkFDdEIsV0FBVyxHQUFHLElBQUksWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUN4QyxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLFlBQVksQ0FBQztnQkFDN0IsS0FBSyxVQUFVLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBQ3BCLE9BQU8sQ0FBQyxJQUFJLEdBQUcsUUFBUSxDQUFDO29CQUN4QixXQUFXLEdBQUcsSUFBSSxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDbEQsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDeEIsK0JBQStCO29CQUMvQixXQUFXLEdBQUcsSUFBSSxrQkFBa0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDOUMsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDdkIsOEJBQThCO29CQUM5QixXQUFXLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDN0MsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxLQUFLLENBQUM7Z0JBQ3RCLEtBQUssVUFBVSxDQUFDLFFBQVEsQ0FBQyxDQUFDO29CQUN0QiwwQkFBMEI7b0JBQzFCLE9BQU8sQ0FBQyxTQUFTO3dCQUNiLFNBQVM7NEJBQ0wsSUFBSSxDQUFDLDBCQUEwQixDQUFDLFlBQVksRUFBRSxTQUFTLENBQUM7NEJBQ3hELENBQUMsQ0FBQyxTQUFTOzRCQUNYLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBQ2YsT0FBTyxDQUFDLGdCQUFnQjt3QkFDcEIsZ0JBQWdCOzRCQUNaLElBQUksQ0FBQywwQkFBMEIsQ0FDM0IsWUFBWSxFQUNaLGdCQUFnQixDQUNuQjs0QkFDRCxDQUFDLENBQUMsZ0JBQWdCOzRCQUNsQixDQUFDLENBQUMsSUFBSSxDQUFDO29CQUNmLE9BQU8sQ0FBQyxlQUFlO3dCQUNuQixlQUFlOzRCQUNYLElBQUksQ0FBQywwQkFBMEIsQ0FDM0IsWUFBWSxFQUNaLGVBQWUsQ0FDbEI7NEJBQ0QsQ0FBQyxDQUFDLGVBQWU7NEJBQ2pCLENBQUMsQ0FBQyxJQUFJLENBQUM7b0JBRWYsV0FBVyxHQUFHLElBQUksYUFBYSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUN6QyxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUNwQiwyQkFBMkI7b0JBQzNCLFdBQVcsR0FBRyxJQUFJLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDMUMsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDbkIsT0FBTyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7b0JBQ3ZCLFdBQVcsR0FBRyxJQUFJLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDeEMsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQztvQkFDbkIsT0FBTyxDQUFDLElBQUksR0FBRyxPQUFPLENBQUM7b0JBQ3ZCLFdBQVcsR0FBRyxJQUFJLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDeEMsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDdEIsT0FBTyxDQUFDLElBQUksR0FBRyxVQUFVLENBQUM7b0JBQzFCLFdBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDM0MsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxPQUFPLENBQUM7Z0JBQ3hCLEtBQUssVUFBVSxDQUFDLE9BQU8sQ0FBQztnQkFDeEIsS0FBSyxVQUFVLENBQUMsb0JBQW9CLENBQUM7Z0JBQ3JDLEtBQUssVUFBVSxDQUFDLFVBQVUsQ0FBQztnQkFDM0IsS0FBSyxVQUFVLENBQUMsZ0JBQWdCLENBQUM7Z0JBQ2pDLEtBQUssVUFBVSxDQUFDLGFBQWEsQ0FBQyxDQUFDO29CQUMzQixXQUFXLEdBQUcsSUFBSSxlQUFlLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQzNDLE1BQU07aUJBQ1Q7Z0JBQ0QsS0FBSyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUM7b0JBQ3RCLFdBQVcsR0FBRyxJQUFJLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUM1QyxNQUFNO2lCQUNUO2dCQUVELEtBQUssVUFBVSxDQUFDLFlBQVksQ0FBQyxDQUFDO29CQUMxQixXQUFXLEdBQUcsSUFBSSx3QkFBd0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDcEQsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxJQUFJLENBQUM7Z0JBQ3JCLEtBQUssVUFBVSxDQUFDLFdBQVcsQ0FBQztnQkFDNUIsS0FBSyxVQUFVLENBQUMsY0FBYyxDQUFDO2dCQUMvQixLQUFLLFVBQVUsQ0FBQyxXQUFXLENBQUMsQ0FBQztvQkFDekIsT0FBTyxDQUFDLElBQUk7d0JBQ1IsU0FBUyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsV0FBVzs0QkFDMUMsQ0FBQyxDQUFDLFVBQVU7NEJBQ1osQ0FBQyxDQUFDLE1BQU0sQ0FBQztvQkFDakIsV0FBVyxHQUFHLElBQUksWUFBWSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUN4QyxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLGFBQWEsQ0FBQztnQkFDOUIsS0FBSyxVQUFVLENBQUMsYUFBYSxDQUFDO2dCQUM5QixLQUFLLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDeEIsT0FBTyxDQUFDLElBQUksR0FBRyxLQUFLLENBQUM7b0JBQ3JCLFdBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDM0MsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxVQUFVLENBQUMsQ0FBQztvQkFDeEIsT0FBTyxDQUFDLElBQUksR0FBRyxZQUFZLENBQUM7b0JBQzVCLFdBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDM0MsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxRQUFRLENBQUMsQ0FBQztvQkFDdEIsT0FBTyxDQUFDLElBQUksR0FBRyxVQUFVLENBQUM7b0JBQzFCLFdBQVcsR0FBRyxJQUFJLGVBQWUsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDM0MsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxVQUFVLENBQUM7Z0JBQzNCLEtBQUssVUFBVSxDQUFDLGNBQWMsQ0FBQztnQkFDL0IsS0FBSyxVQUFVLENBQUMsV0FBVyxDQUFDO2dCQUM1QixLQUFLLFVBQVUsQ0FBQyxHQUFHLENBQUM7Z0JBQ3BCLEtBQUssVUFBVSxDQUFDLE1BQU0sQ0FBQyxDQUFDO29CQUNwQixPQUFPLENBQUMsSUFBSSxHQUFHLE1BQU0sQ0FBQztvQkFDdEIsV0FBVyxHQUFHLElBQUksZUFBZSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUMzQyxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLE9BQU8sQ0FBQztnQkFDeEIsS0FBSyxVQUFVLENBQUMsY0FBYyxDQUFDLENBQUM7b0JBQzVCLFdBQVcsR0FBRyxJQUFJLGdCQUFnQixDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUM1QyxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLFdBQVcsQ0FBQyxDQUFDO29CQUN6QixPQUFPLENBQUMsSUFBSSxHQUFHLGFBQWEsQ0FBQztvQkFDN0IsV0FBVyxHQUFHLElBQUksZ0JBQWdCLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQzVDLE1BQU07aUJBQ1Q7Z0JBQ0QsS0FBSyxVQUFVLENBQUMsUUFBUSxDQUFDO2dCQUN6QixLQUFLLFVBQVUsQ0FBQyxhQUFhLENBQUM7Z0JBQzlCLEtBQUssVUFBVSxDQUFDLGVBQWUsQ0FBQyxDQUFDO29CQUM3QiwyQkFBMkI7b0JBQzNCLFdBQVcsR0FBRyxJQUFJLGNBQWMsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDMUMsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxZQUFZLENBQUM7Z0JBQzdCLEtBQUssVUFBVSxDQUFDLHNCQUFzQixDQUFDO2dCQUN2QyxLQUFLLFVBQVUsQ0FBQyxpQkFBaUIsQ0FBQyxDQUFDO29CQUMvQixPQUFPLENBQUMsSUFBSSxHQUFHLE9BQU8sQ0FBQztvQkFDdkIsV0FBVyxHQUFHLElBQUksY0FBYyxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUMxQyxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLGlCQUFpQixDQUFDLENBQUM7b0JBQy9CLE9BQU8sQ0FBQyxJQUFJLEdBQUcsV0FBVyxDQUFDO29CQUMzQixPQUFPLENBQUMsbUJBQW1CLEdBQUcsU0FBUyxDQUFDLG1CQUFtQixDQUFDO29CQUM1RCxPQUFPLENBQUMsc0JBQXNCO3dCQUMxQixTQUFTLENBQUMsc0JBQXNCLENBQUM7b0JBQ3JDLE9BQU8sQ0FBQywyQkFBMkI7d0JBQy9CLFNBQVMsQ0FBQywyQkFBMkIsQ0FBQztvQkFDMUMsV0FBVyxHQUFHLElBQUksc0JBQXNCLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ2xELE1BQU07aUJBQ1Q7Z0JBQ0QsS0FBSyxVQUFVLENBQUMsYUFBYSxDQUFDLENBQUM7b0JBQzNCLE9BQU8sQ0FBQyxJQUFJLEdBQUcsZUFBZSxDQUFDO29CQUMvQixXQUFXLEdBQUcsSUFBSSxzQkFBc0IsQ0FBQyxPQUFPLENBQUMsQ0FBQztvQkFDbEQsTUFBTTtpQkFDVDtnQkFDRCxLQUFLLFVBQVUsQ0FBQyxTQUFTLENBQUMsQ0FBQztvQkFDdkIsV0FBVyxHQUFHLElBQUksaUJBQWlCLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQzdDLE1BQU07aUJBQ1Q7Z0JBQ0Q7O2tCQUVFO2dCQUNGLEtBQUssVUFBVSxDQUFDLDBCQUEwQixDQUFDO2dCQUMzQyxLQUFLLFVBQVUsQ0FBQyw2QkFBNkIsQ0FBQyxDQUFDO29CQUMzQyxPQUFPLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztvQkFDcEIsT0FBTyxDQUFDLFlBQVk7d0JBQ2hCLFNBQVMsQ0FBQyxTQUFTOzRCQUNuQixVQUFVLENBQUMsMEJBQTBCLENBQUM7b0JBQzFDLE9BQU8sQ0FBQyxnQkFBZ0IsR0FBRyxTQUFTLENBQUMsZ0JBQWdCLENBQUM7b0JBRXRELFdBQVcsR0FBRyxJQUFJLHdCQUF3QixDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUNwRCxNQUFNO2lCQUNUO2dCQUNELEtBQUssVUFBVSxDQUFDLE9BQU8sQ0FBQyxDQUFDO29CQUNyQixPQUFPLENBQUMsSUFBSSxHQUFHLGVBQWUsQ0FBQztvQkFDL0IsT0FBTyxDQUFDLGdCQUFnQixHQUFHLFNBQVMsQ0FBQyxnQkFBZ0IsQ0FBQztvQkFFdEQsV0FBVyxHQUFHLElBQUksd0JBQXdCLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBQ3BELE1BQU07aUJBQ1Q7YUFDSjtTQUNKO1FBRUQsSUFBSSxDQUFDLFdBQVcsRUFBRTtZQUNkLE9BQU8sQ0FBQyxLQUFLLEdBQUcsWUFBWSxDQUFDLE9BQU8sR0FBRyxzQkFBc0IsQ0FBQztZQUM5RCxXQUFXLEdBQUcsSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztTQUNoRDtRQUVELE9BQU8sV0FBVyxDQUFDO0lBQ3ZCLENBQUM7SUFFRCxzQkFBc0IsQ0FBQyxLQUFtQjtRQUN0QyxJQUFJLG1CQUFtQixHQUFHLEtBQUssQ0FBQyxjQUFjLENBQUM7UUFFL0MsMENBQTBDO1FBQzFDLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxVQUFVLEVBQUU7WUFDbEMsbUJBQW1CLEdBQUcsbUJBQW1CLEtBQUssTUFBTSxDQUFDO1NBQ3hEO1FBRUQsdUNBQXVDO1FBQ3ZDLElBQUksS0FBSyxDQUFDLFdBQVcsS0FBSyxRQUFRLEVBQUU7WUFDaEMsbUJBQW1CO2dCQUNmLG1CQUFtQixLQUFLLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxtQkFBbUIsQ0FBQztTQUM5RDtRQUVELE9BQU8sbUJBQW1CLENBQUM7SUFDL0IsQ0FBQztJQUVPLGNBQWMsQ0FBQyxNQUFzQjtRQUN6QyxNQUFNLEtBQUssR0FBRyxFQUFFLENBQUM7UUFDakIsSUFBSSxNQUFNLElBQUksTUFBTSxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDN0IsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO2dCQUNyQixJQUFJLEtBQUssQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO29CQUNuRCxNQUFNLFFBQVEsR0FBRyxFQUFFLENBQUM7b0JBRXBCLEtBQUssQ0FBQyxXQUFXLENBQUMsT0FBTyxDQUFDLENBQUMsVUFBVSxFQUFFLEVBQUU7d0JBQ3JDLElBQ0ksVUFBVSxDQUFDLFNBQVM7NEJBQ3BCLENBQUMsS0FBSyxDQUFDLFFBQVE7NEJBQ2YsQ0FBQyxLQUFLLENBQUMsUUFBUSxFQUNqQjs0QkFDRSxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHO2dDQUN2QjtvQ0FDSSxLQUFLLEVBQUUsVUFBVSxDQUFDLGNBQWMsSUFBSSxFQUFFO29DQUN0QyxRQUFRLEVBQ0osS0FBSyxDQUFDLFFBQVE7d0NBQ2QsS0FBSyxDQUFDLFFBQVE7d0NBQ2QsVUFBVSxDQUFDLFFBQVE7aUNBQzFCO2dDQUNELENBQUMsVUFBVSxDQUFDLFFBQVEsQ0FBQzs2QkFDeEIsQ0FBQzt5QkFDTDs2QkFBTTs0QkFDSCxRQUFRLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHO2dDQUN2QjtvQ0FDSSxLQUFLLEVBQUUsVUFBVSxDQUFDLGNBQWMsSUFBSSxFQUFFO29DQUN0QyxRQUFRLEVBQ0osS0FBSyxDQUFDLFFBQVE7d0NBQ2QsS0FBSyxDQUFDLFFBQVE7d0NBQ2QsVUFBVSxDQUFDLFFBQVE7aUNBQzFCO2dDQUNELENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQzs2QkFDN0IsQ0FBQzt5QkFDTDtvQkFDTCxDQUFDLENBQUMsQ0FBQztvQkFFSCxLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDO2lCQUM5QztxQkFBTTtvQkFDSCxNQUFNLFVBQVUsR0FBRyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7b0JBQ3pDLE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUNuRCxLQUFLLENBQ1IsQ0FBQztvQkFFRixLQUFLLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxHQUFHO3dCQUNmOzRCQUNJLEtBQUssRUFBRSxtQkFBbUIsSUFBSSxFQUFFOzRCQUNoQyxRQUFRLEVBQUUsS0FBSyxDQUFDLFFBQVE7eUJBQzNCO3dCQUNELFVBQVU7cUJBQ2IsQ0FBQztpQkFDTDtZQUNMLENBQUMsQ0FBQyxDQUFDO1NBQ047UUFFRCxPQUFPLElBQUksQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQ2hDLENBQUM7SUFFTyxlQUFlLENBQUMsY0FBOEIsRUFBRSxTQUFjO1FBQ2xFLE1BQU0sV0FBVyxHQUFpQixJQUFJLENBQUMsb0JBQW9CLENBQ3ZELGNBQWMsRUFDZCxTQUFTLEVBQ1QsSUFBSSxDQUFDLGFBQWEsRUFDbEIsSUFBSSxDQUFDLGFBQWEsRUFDbEIsSUFBSSxDQUFDLG9CQUFvQixFQUN6QixJQUFJLENBQUMsbUJBQW1CLEVBQ3hCLElBQUksQ0FBQyxRQUFRLEVBQ2IsSUFBSSxDQUFDLFFBQVEsRUFDYixJQUFJLENBQUMsVUFBVSxDQUNsQixDQUFDO1FBRUYsT0FBTyxXQUFXLENBQUM7SUFDdkIsQ0FBQztJQUVNLHlCQUF5QjtRQUM1QixNQUFNLE1BQU0sR0FBbUIsSUFBSSxDQUFDLE1BQU0sQ0FBQztRQUMzQyxJQUFJLHVCQUF1QixHQUFHLEVBQUUsQ0FBQztRQUNqQyxJQUFJLGlCQUFpQixHQUFHLEVBQUUsQ0FBQztRQUUzQixvREFBb0Q7UUFDcEQsNkJBQTZCO1FBQzdCLEtBQUssTUFBTSxLQUFLLElBQUksTUFBTSxFQUFFO1lBQ3hCLE1BQU0sV0FBVyxHQUFHLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBRTFELElBQUksV0FBVyxFQUFFO2dCQUNiLHNCQUFzQjtnQkFDdEIsSUFDSSxLQUFLLENBQUMsU0FBUztvQkFDZixXQUFXLENBQUMsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDLElBQUksRUFBRSxDQUFDLE1BQU0sS0FBSyxDQUFDLEVBQ2xEO29CQUNFLHVCQUF1Qjt3QkFDbkIsYUFBYSxHQUFHLEtBQUssQ0FBQyxLQUFLLEdBQUcsZUFBZSxDQUFDO2lCQUNyRDtxQkFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLFFBQVEsSUFBSSxDQUFDLFdBQVcsQ0FBQyxLQUFLLEVBQUU7b0JBQzlDLGlCQUFpQjt3QkFDYixhQUFhLEdBQUcsS0FBSyxDQUFDLEtBQUssR0FBRyxlQUFlLENBQUM7aUJBQ3JEO2FBQ0o7U0FDSjtRQUVELHVEQUF1RDtRQUN2RCxJQUFJLHVCQUF1QixDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUU7WUFDcEMsdUJBQXVCO2dCQUNuQixPQUFPO29CQUNQLElBQUksQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDLGlDQUFpQyxDQUFDO29CQUN6RCxxQ0FBcUM7b0JBQ3JDLHVCQUF1QjtvQkFDdkIsWUFBWSxDQUFDO1NBQ3BCO1FBRUQsdURBQXVEO1FBQ3ZELElBQUksaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUM5QixpQkFBaUI7Z0JBQ2IsT0FBTztvQkFDUCxJQUFJLENBQUMsU0FBUyxDQUFDLE9BQU8sQ0FBQywrQkFBK0IsQ0FBQztvQkFDdkQscUNBQXFDO29CQUNyQyxpQkFBaUI7b0JBQ2pCLE9BQU8sQ0FBQztTQUNmO1FBRUQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLENBQUMsdUJBQXVCLENBQUMsQ0FBQztRQUM5RCxNQUFNLElBQUksR0FBRyxJQUFJLGFBQWEsQ0FBQztZQUMzQixLQUFLO1lBQ0wsT0FBTyxFQUFFLHVCQUF1QixHQUFHLGlCQUFpQjtTQUN2RCxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsYUFBYSxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxDQUFDO0lBQy9DLENBQUM7SUFFRCxRQUFRO1FBQ0osTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFDaEUsdUJBQXVCO1FBQ3ZCLE1BQU0sVUFBVSxHQUFHLEVBQUUsQ0FBQztRQUN0QixJQUFJLENBQUMsY0FBYztZQUNmLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxzQkFBc0IsQ0FDNUMsU0FBUyxFQUNULHVCQUF1QixDQUFDLGlCQUFpQixDQUM1QyxHQUFHLFVBQVUsQ0FBQztRQUNuQixJQUFJLENBQUMsY0FBYztZQUNmLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxzQkFBc0IsQ0FDNUMsU0FBUyxFQUNULHVCQUF1QixDQUFDLGlCQUFpQixDQUM1QyxHQUFHLFVBQVUsQ0FBQztJQUN2QixDQUFDO0lBRUQsU0FBUztRQUNMLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLG9CQUFvQjtRQUNqRSxJQUFJLE9BQU8sRUFBRTtZQUNULElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNsQixJQUFJLENBQUMsZUFBZSxHQUFHLElBQUksSUFBSSxFQUFFLENBQUM7U0FDckM7SUFDTCxDQUFDO0lBRUQsV0FBVyxDQUFDLE9BQU87UUFDZixtREFBbUQ7UUFDbkQsc0JBQXNCO1FBQ3RCLGtFQUFrRTtRQUNsRSxpREFBaUQ7UUFDakQsNkJBQTZCO1FBQzdCLGVBQWU7UUFDZiwwQ0FBMEM7UUFDMUMsMkJBQTJCO1FBQzNCLFFBQVE7UUFDUixJQUFJO1FBQ0osZ0VBQWdFO1FBQ2hFLHNDQUFzQztRQUN0Qyx1QkFBdUI7UUFDdkIseUNBQXlDO1FBQ3pDLElBQUk7SUFDUixDQUFDO0lBRUQsV0FBVztRQUNQLEVBQUU7SUFDTixDQUFDO0lBRUQsa0JBQWtCO1FBQ2QsT0FBTyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0lBQ3hELENBQUM7SUFFRCxtQkFBbUIsQ0FBQyxNQUFzQixFQUFFLE1BQWM7UUFDdEQsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGlCQUFpQixFQUFFLENBQUM7UUFFaEUsdUJBQXVCO1FBQ3ZCLElBQUksSUFBSSxDQUFDLFVBQVUsS0FBSyxNQUFNLEVBQUU7WUFDNUIsTUFBTSxlQUFlLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLHNCQUFzQixDQUNwRSxTQUFTLEVBQ1QsdUJBQXVCLENBQUMscUJBQXFCLENBQ2hELENBQUM7WUFDRixJQUFJLENBQUMsU0FBUyxHQUFHLGVBQWUsQ0FBQztTQUNwQzthQUFNO1lBQ0gsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLHNCQUFzQixDQUNuRSxTQUFTLEVBQ1QsdUJBQXVCLENBQUMscUJBQXFCLENBQ2hELENBQUM7WUFDRixNQUFNLG1CQUFtQixHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxzQkFBc0IsQ0FDeEUsU0FBUyxFQUNULHVCQUF1QixDQUFDLDJCQUEyQixDQUN0RCxDQUFDO1lBQ0YsSUFBSSxDQUFDLFNBQVMsR0FBRyxjQUFjLEdBQUcsbUJBQW1CLENBQUM7U0FDekQ7UUFFRCw4REFBOEQ7UUFDOUQsSUFBSSxNQUFNLENBQUMsTUFBTSxHQUFHLENBQUMsRUFBRTtZQUNuQixtQkFBbUI7WUFDbkI7WUFDSSxnQ0FBZ0M7WUFDaEMsSUFBSSxDQUFDLFVBQVUsS0FBSyxPQUFPLEVBQzdCO2dCQUNFLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDO2dCQUNyQixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFFakMsSUFBSSxDQUFDLElBQUksR0FBRyxFQUFFLENBQUM7Z0JBRWYsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxJQUFJLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDOUIsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxFQUFFLENBQUM7aUJBQ3JCO2dCQUVELDRDQUE0QztnQkFDNUMsMEJBQTBCO2dCQUMxQixLQUFLLE1BQU0sS0FBSyxJQUFJLE1BQU0sRUFBRTtvQkFDeEIsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO2lCQUNwQzthQUNKO2lCQUFNO2dCQUNILE1BQU0sZ0JBQWdCLEdBQWdCLElBQUksS0FBSyxDQUFDLE1BQU0sQ0FBQyxDQUFDO2dCQUV4RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsZ0JBQWdCLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUM5QyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsR0FBRyxJQUFJLEtBQUssQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUM7b0JBRTlDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUU7d0JBQ2pELGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssQ0FBQztxQkFDbEM7aUJBQ0o7Z0JBRUQsNkVBQTZFO2dCQUM3RSx3REFBd0Q7Z0JBQ3hELDBDQUEwQztnQkFDMUMsS0FBSyxNQUFNLFlBQVksSUFBSSxNQUFNLEVBQUU7b0JBQy9CLElBQUksWUFBWSxDQUFDLE9BQU8sR0FBRyxDQUFDLEVBQUU7d0JBQzFCLEtBQ0ksSUFBSSxHQUFHLEdBQVcsWUFBWSxDQUFDLEdBQUcsRUFDbEMsR0FBRyxHQUFHLFlBQVksQ0FBQyxHQUFHLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFDN0MsR0FBRyxFQUFFLEVBQ1A7NEJBQ0UsSUFBSSxZQUFZLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRTtnQ0FDMUIsS0FDSSxJQUFJLEdBQUcsR0FBVyxZQUFZLENBQUMsR0FBRyxFQUNsQyxHQUFHO29DQUNILFlBQVksQ0FBQyxHQUFHLEdBQUcsWUFBWSxDQUFDLE9BQU8sRUFDdkMsR0FBRyxFQUFFLEVBQ1A7b0NBQ0UsSUFDSSxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsR0FBRzt3Q0FDN0IsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFDbEM7d0NBQ0UsZ0JBQWdCLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLEdBQUcsSUFBSSxDQUFDO3FDQUNyQztpQ0FDSjs2QkFDSjtpQ0FBTTtnQ0FDSCxJQUNJLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxHQUFHO29DQUM3QixnQkFBZ0IsQ0FBQyxDQUFDLENBQUMsQ0FBQyxNQUFNO3dDQUMxQixZQUFZLENBQUMsR0FBRyxFQUNsQjtvQ0FDRSxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsQ0FDakIsWUFBWSxDQUFDLEdBQUcsQ0FDbkIsR0FBRyxJQUFJLENBQUM7aUNBQ1o7NkJBQ0o7eUJBQ0o7cUJBQ0o7eUJBQU0sSUFBSSxZQUFZLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRTt3QkFDakMsS0FDSSxJQUFJLEdBQUcsR0FBVyxZQUFZLENBQUMsR0FBRyxFQUNsQyxHQUFHLEdBQUcsWUFBWSxDQUFDLEdBQUcsR0FBRyxZQUFZLENBQUMsT0FBTyxFQUM3QyxHQUFHLEVBQUUsRUFDUDs0QkFDRSxJQUNJLGdCQUFnQixDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUMsR0FBRztnQ0FDMUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsTUFBTSxHQUFHLEdBQUcsRUFDbEM7Z0NBQ0UsZ0JBQWdCLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQzs2QkFDbEQ7eUJBQ0o7cUJBQ0o7eUJBQU07d0JBQ0gsSUFDSSxnQkFBZ0IsQ0FBQyxNQUFNLEdBQUcsWUFBWSxDQUFDLEdBQUc7NEJBQzFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxZQUFZLENBQUMsR0FBRyxFQUMvQzs0QkFDRSxnQkFBZ0IsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQzlCLFlBQVksQ0FBQyxHQUFHLENBQ25CLEdBQUcsSUFBSSxDQUFDO3lCQUNaO3FCQUNKO2lCQUNKO2dCQUVELDJGQUEyRjtnQkFDM0YsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtvQkFDOUMsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTt3QkFDakQsSUFBSSxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFOzRCQUN6QixvREFBb0Q7NEJBQ3BELE1BQU0sQ0FBQyxJQUFJLENBQ1AsSUFBSSxtQkFBbUIsQ0FBQztnQ0FDcEIsR0FBRyxFQUFFLENBQUMsR0FBRyxHQUFHLEdBQUcsQ0FBQztnQ0FDaEIsS0FBSyxFQUFFLEVBQUU7Z0NBQ1QsV0FBVyxFQUFFLEVBQUU7Z0NBQ2YsUUFBUSxFQUFFLEtBQUs7Z0NBQ2YsUUFBUSxFQUFFLEtBQUs7Z0NBQ2YsTUFBTSxFQUFFLEtBQUs7Z0NBQ2IsU0FBUyxFQUFFLEtBQUs7Z0NBQ2hCLEtBQUssRUFBRSxFQUFFO2dDQUNULGNBQWMsRUFBRSxFQUFFO2dDQUNsQixHQUFHLEVBQUUsQ0FBQztnQ0FDTixPQUFPLEVBQUUsQ0FBQztnQ0FDVixHQUFHLEVBQUUsQ0FBQztnQ0FDTixPQUFPLEVBQUUsQ0FBQztnQ0FDVixLQUFLLEVBQUUsQ0FBQzs2QkFDWCxDQUFDLENBQ0wsQ0FBQzt5QkFDTDtxQkFDSjtpQkFDSjtnQkFFRCx5QkFBeUI7Z0JBQ3pCLElBQUksQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUNqQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHO29CQUNYLENBQUMsQ0FBQyxDQUFDO29CQUNILENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHO3dCQUNiLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ0osQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUc7NEJBQ2IsQ0FBQyxDQUFDLENBQUM7NEJBQ0gsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUc7Z0NBQ2IsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQ0FDSixDQUFDLENBQUMsQ0FBQyxDQUN0QixDQUFDO2dCQUNGLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDO2FBQ3BDO1NBQ0o7SUFDTCxDQUFDO0lBRUQsT0FBTyxDQUFDLFdBQVcsR0FBRyxLQUFLOztRQUN2QixJQUFJLG9CQUFvQixHQUFHLElBQUksQ0FBQztRQUVoQyxJQUFJLENBQUMsV0FBVyxFQUFFO1lBQ2QsTUFBTSxNQUFNLEdBQUcsRUFBRSxDQUFDO1lBQ2xCLEtBQUssTUFBTSxZQUFZLElBQUksSUFBSSxDQUFDLE1BQU0sRUFBRTtnQkFDcEMsdURBQXVEO2dCQUN2RCxJQUFJLFlBQVksQ0FBQyxXQUFXLEtBQUssY0FBYyxFQUFFO29CQUM3QyxNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxDQUFDO2lCQUM3QjtnQkFFRCxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRTtvQkFDeEIsb0JBQW9CLEdBQUcsS0FBSyxDQUFDO2lCQUNoQzthQUNKO1lBRUQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1NBQzNDO2FBQU07WUFDSCxzREFBc0Q7WUFDdEQsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxNQUFNLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO2dCQUN6QyxJQUFJLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUVsQyxJQUFJLFlBQVksQ0FBQyxXQUFXLEtBQUssaUJBQWlCLEVBQUU7b0JBQ2hELHVDQUF1QztvQkFDdkMsTUFBTSxjQUFjLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixFQUFFLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLE9BQU8sS0FBSyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQzdGLE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxFQUFFLENBQUMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssWUFBWSxDQUFDLEdBQUcsQ0FBQyxDQUFDO29CQUMvRSxZQUFZLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxjQUFjLEVBQUUsU0FBUyxDQUFDLENBQUM7b0JBQy9ELElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxHQUFHLFlBQVksQ0FBQztpQkFDL0M7cUJBQU0sSUFBSSxZQUFZLENBQUMsV0FBVyxLQUFLLGNBQWMsRUFBRTtvQkFDcEQsSUFDSSxZQUFZLENBQUMsV0FBVzt3QkFDeEIsWUFBWSxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUNyQzt3QkFDRSw4REFBOEQ7d0JBQzlELDJEQUEyRDt3QkFDM0QsS0FBSyxNQUFNLGlCQUFpQixJQUFJLFlBQVksQ0FBQyxXQUFXLEVBQUU7NEJBQ3RELE1BQU0sbUJBQW1CLEdBQUcsSUFBSSxDQUFDLHNCQUFzQixDQUNuRCxpQkFBaUIsQ0FDcEIsQ0FBQzs0QkFDRixJQUFJLENBQUMsb0JBQW9CLENBQUMsZUFBZSxDQUNyQyxJQUFJLENBQUMsSUFBSSxFQUNULGlCQUFpQixFQUNqQixtQkFBbUIsRUFDbkIsWUFBWSxDQUNmLENBQUM7eUJBQ0w7cUJBQ0o7eUJBQU07d0JBQ0gsTUFBTSxtQkFBbUIsR0FBRyxJQUFJLENBQUMsc0JBQXNCLENBQ25ELFlBQVksQ0FDZixDQUFDO3dCQUNGLHNFQUFzRTt3QkFDdEUsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGVBQWUsQ0FDckMsSUFBSSxDQUFDLElBQUksRUFDVCxZQUFZLEVBQ1osbUJBQW1CLENBQ3RCLENBQUM7cUJBQ0w7aUJBQ0o7Z0JBRUQsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUU7b0JBQ3hCLG9CQUFvQixHQUFHLEtBQUssQ0FBQztpQkFDaEM7YUFDSjtTQUNKO1FBRUQsSUFBSSxXQUFXLEdBQUcsTUFBQSxJQUFJLENBQUMsSUFBSSwwQ0FBRSxLQUFLLENBQUM7UUFFbkMseURBQXlEO1FBQ3pELElBQUksQ0FBQyxXQUFXLElBQUksb0JBQW9CLEVBQUU7WUFDdEMsV0FBVyxHQUFHLElBQUksQ0FBQztTQUN0QjtRQUVELElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUUxQyx3Q0FBd0M7UUFDeEMsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxRQUFRLEVBQUU7WUFDbEMsSUFBSSxDQUFDLFFBQVEsR0FBRyxLQUFLLENBQUM7U0FDekI7SUFDTCxDQUFDO0lBRUQsUUFBUTtRQUNKLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUMvQixNQUFNLE1BQU0sR0FBbUIsSUFBSSxDQUFDLG1CQUFtQixDQUNuRCxJQUFJLENBQUMsa0JBQWtCLEVBQUUsRUFDekIsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQ25CLENBQUM7WUFFRixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsR0FBRyxDQUNuQixHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRTtnQkFDaEIsT0FBTyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDN0IsQ0FBQyxDQUFDLENBQ0wsQ0FBQztZQUNGLElBQUksQ0FBQyxPQUFPLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FDbkIsR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUU7Z0JBQ2hCLE9BQU8sQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDO1lBQzdCLENBQUMsQ0FBQyxDQUNMLENBQUM7WUFFRixJQUFJLENBQUMsbUJBQW1CLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3pDLElBQUksQ0FBQyxPQUFPLEVBQUUsQ0FBQztTQUNsQjtJQUNMLENBQUM7SUFFTyxXQUFXLENBQ2YsV0FBeUIsRUFDekIsWUFBZ0M7UUFFaEMsTUFBTSxPQUFPLEdBQVE7WUFDakIsUUFBUSxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhO1lBQ3RELFFBQVEsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYTtZQUN0RCxPQUFPLEVBQUUsWUFBWSxDQUFDLE9BQU87WUFDN0IsS0FBSyxFQUFFLFlBQVksQ0FBQyxLQUFLO1lBQ3pCLGVBQWUsRUFBRSxZQUFZLENBQUMsZUFBZTtZQUM3QyxjQUFjLEVBQUUsWUFBWSxDQUFDLGNBQWM7WUFDM0MsU0FBUyxFQUFFLFlBQVksQ0FBQyxTQUFTO1NBQ3BDLENBQUM7UUFFRixJQUFJLFdBQVcsWUFBWSx3QkFBd0IsRUFBRTtZQUNqRCxNQUFNLGdCQUFnQixHQUFHLFlBQVksQ0FBQyxnQkFBZ0IsQ0FBQztZQUN2RCxPQUFPLENBQUMsZ0JBQWdCLEdBQUcsZ0JBQWdCLENBQUM7WUFFNUMsc0RBQXNEO1lBQ3RELElBQUksWUFBWSxHQUFHLEtBQUssQ0FBQztZQUN6QixJQUFJLFlBQVksQ0FBQyxTQUFTLEtBQUssVUFBVSxDQUFDLDBCQUEwQjtnQkFDaEUsWUFBWSxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsVUFBVTtnQkFDaEQsWUFBWSxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsbUJBQW1CLEVBQzNEO2dCQUNFLFlBQVksR0FBRyxJQUFJLENBQUM7YUFDdkI7WUFFRCxPQUFPLENBQUMsWUFBWSxHQUFHLFlBQVksQ0FBQztTQUV2QzthQUFNLElBQUksV0FBVyxZQUFZLGNBQWMsRUFBRTtZQUM5QyxPQUFPLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQyxxQkFBcUIsQ0FDeEMsWUFBWSxDQUFDLGNBQWMsQ0FDOUIsQ0FBQztZQUVGLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxJQUFJLE9BQU8sQ0FBQyxPQUFPLENBQUMsTUFBTSxLQUFLLENBQUMsRUFBRTtnQkFDbEQsT0FBTyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUM7b0JBQ2pCLEdBQUcsRUFBRSxPQUFPLENBQUMsS0FBSztvQkFDbEIsS0FBSyxFQUFFLE9BQU8sQ0FBQyxjQUFjO2lCQUNoQyxDQUFDLENBQUM7YUFDTjtTQUNKO2FBQU0sSUFBSSxXQUFXLFlBQVksdUJBQXVCLEVBQUU7WUFDdkQsT0FBTyxDQUFDLFFBQVEsR0FBRyxZQUFZLENBQUMsVUFBVSxDQUFDO1NBQzlDO1FBRUQsV0FBVyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztJQUNoQyxDQUFDO0lBRUQsVUFBVTtRQUNOLElBQUksSUFBSSxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRTtZQUMvQixLQUFLLE1BQU0sWUFBWSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFO2dCQUN6QyxNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FDbEMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssWUFBWSxDQUFDLE9BQU8sQ0FDeEMsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDTCwrREFBK0Q7Z0JBQy9ELElBQUksV0FBVyxJQUFJLFdBQVcsQ0FBQyxXQUFXLEtBQUssY0FBYyxFQUFFO29CQUMzRCxJQUFJLENBQUMsV0FBVyxDQUFDLFdBQVcsRUFBRSxZQUFZLENBQUMsQ0FBQztvQkFFNUMsMkJBQTJCO29CQUMzQixJQUNJLFdBQVcsQ0FBQyxXQUFXLEtBQUssU0FBUzt3QkFDckMsWUFBWSxDQUFDLFdBQVcsRUFDMUI7d0JBQ0UsOERBQThEO3dCQUM5RCx1REFBdUQ7d0JBQ3ZELEtBQUssTUFBTSxpQkFBaUIsSUFBSSxZQUFZLENBQUMsV0FBVyxFQUFFOzRCQUN0RCxpQkFBaUIsQ0FBQyxPQUFPLEdBQUcsQ0FBQyxZQUFZLENBQUMsT0FBTztnQ0FDN0MsQ0FBQyxDQUFDLEtBQUs7Z0NBQ1AsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLE9BQU8sQ0FBQzs0QkFFaEMsTUFBTSxnQkFBZ0IsR0FBRyxXQUFXLENBQUMsV0FBVyxDQUFDLE1BQU0sQ0FDbkQsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEtBQUssaUJBQWlCLENBQUMsT0FBTyxDQUM3QyxDQUFDLENBQUMsQ0FBQyxDQUFDOzRCQUNMLElBQUksQ0FBQyxXQUFXLENBQ1osZ0JBQWdCLEVBQ2hCLGlCQUFpQixDQUNwQixDQUFDO3lCQUNMO3FCQUNKO2lCQUNKO2FBQ0o7WUFFRCxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksQ0FBQyxDQUFDO1NBQ3RCO0lBQ0wsQ0FBQztJQUVNLFVBQVU7UUFDYixJQUFJLENBQUMsaUJBQWlCLEdBQUcsSUFBSSxDQUFDO0lBQ2xDLENBQUM7SUFFRCxlQUFlO0lBQ2YsNkJBQTZCO0lBQzdCLDBEQUEwRDtJQUMxRCxrREFBa0Q7SUFDbEQsUUFBUTtJQUNSLElBQUk7SUFFSSxrQkFBa0IsQ0FBQyxHQUFXO1FBQ2xDLElBQUksV0FBVyxHQUFHLElBQUksQ0FBQztRQUV2QixJQUFJLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEtBQUssRUFBRSxFQUFFO1lBQzFCLElBQUksS0FBSyxDQUFDLEdBQUcsS0FBSyxHQUFHLEVBQUU7Z0JBQ25CLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQ3ZDLE9BQU87YUFDVjtpQkFBTSxJQUFJLEtBQUssQ0FBQyxXQUFXLElBQUksS0FBSyxDQUFDLFdBQVcsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO2dCQUMxRCxLQUFLLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxDQUFDLFVBQVUsRUFBRSxFQUFFO29CQUNyQyxJQUFJLFVBQVUsQ0FBQyxHQUFHLEtBQUssR0FBRyxFQUFFO3dCQUN4QixXQUFXLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQ3ZCLEtBQUssQ0FBQyxHQUFHLEdBQUcsR0FBRyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQ25DLENBQUM7d0JBQ0YsT0FBTztxQkFDVjtnQkFDTCxDQUFDLENBQUMsQ0FBQzthQUNOO1FBQ0wsQ0FBQyxDQUFDLENBQUM7UUFFSCxPQUFPLFdBQVcsQ0FBQztJQUN2QixDQUFDO0lBRU8sZ0JBQWdCLENBQ3BCLGFBQXlCLEVBQ3pCLFVBQXNCO1FBRXRCLFVBQVU7UUFDViwrREFBK0Q7UUFDL0QsaUNBQWlDO1FBQ2pDLEtBQUssTUFBTSxFQUFFLElBQUksYUFBYSxFQUFFO1lBQzVCLElBQUksRUFBRSxDQUFDLE9BQU8sS0FBSyxZQUFZLEVBQUU7Z0JBQzdCLElBQUksQ0FBQyxTQUFTLEdBQUcsRUFBRSxDQUFDO2FBQ3ZCO2lCQUFNLElBQUksRUFBRSxDQUFDLE9BQU8sS0FBSyx1QkFBdUIsRUFBRTtnQkFDL0MsSUFBSSxDQUFDLGdCQUFnQixHQUFHLEVBQUUsQ0FBQzthQUM5QjtpQkFBTSxJQUFJLEVBQUUsQ0FBQyxPQUFPLEtBQUssK0JBQStCLEVBQUU7Z0JBQ3ZELElBQUksQ0FBQyxlQUFlLEdBQUcsRUFBRSxDQUFDO2FBQzdCO1NBQ0o7UUFFRCxVQUFVO1FBQ1YsNERBQTREO1FBQzVELDhCQUE4QjtRQUM5QixLQUFLLE1BQU0sRUFBRSxJQUFJLFVBQVUsRUFBRTtZQUN6QixJQUFJLEVBQUUsQ0FBQyxPQUFPLEtBQUssWUFBWSxFQUFFO2dCQUM3QixJQUFJLENBQUMsYUFBYSxHQUFHLEVBQUUsQ0FBQzthQUMzQjtpQkFBTSxJQUFJLEVBQUUsQ0FBQyxPQUFPLEtBQUssdUJBQXVCLEVBQUU7Z0JBQy9DLElBQUksQ0FBQyxvQkFBb0IsR0FBRyxFQUFFLENBQUM7YUFDbEM7aUJBQU0sSUFBSSxFQUFFLENBQUMsT0FBTyxLQUFLLCtCQUErQixFQUFFO2dCQUN2RCxJQUFJLENBQUMsbUJBQW1CLEdBQUcsRUFBRSxDQUFDO2FBQ2pDO1NBQ0o7UUFFRCxJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLGFBQWEsRUFBRTtZQUN0QyxJQUFJLENBQUMsYUFBYSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQztTQUNyRDtRQUVELElBQUksSUFBSSxDQUFDLGdCQUFnQixJQUFJLElBQUksQ0FBQyxvQkFBb0IsRUFBRTtZQUNwRCxJQUFJLENBQUMsb0JBQW9CLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7U0FDbkU7UUFFRCxJQUFJLElBQUksQ0FBQyxlQUFlLElBQUksSUFBSSxDQUFDLG1CQUFtQixFQUFFO1lBQ2xELElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxNQUFNLENBQUM7U0FDakU7UUFFRCw0Q0FBNEM7UUFDNUMsK0RBQStEO1FBQy9ELGlDQUFpQztRQUNqQyxLQUFLLE1BQU0sRUFBRSxJQUFJLGFBQWEsRUFBRTtZQUM1QixJQUFJLElBQUksQ0FBQyxTQUFTLElBQUksRUFBRSxDQUFDLE9BQU8sS0FBSyxZQUFZLEVBQUU7Z0JBQy9DLElBQUksQ0FBQywyQkFBMkIsR0FBRyxJQUFJLENBQUMsMEJBQTBCLENBQzlELEVBQUUsRUFDRixJQUFJLENBQUMsU0FBUyxDQUNqQixDQUFDO2dCQUVGLElBQUksSUFBSSxDQUFDLDJCQUEyQixFQUFFO29CQUNsQyxNQUFNO2lCQUNUO2FBQ0o7U0FDSjtJQUNMLENBQUM7SUFFRCxtQkFBbUIsQ0FDZixhQUF5QixFQUN6QixVQUFzQjtRQUV0QixJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssT0FBTyxFQUFFO1lBQzdCLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxhQUFhLEVBQUUsVUFBVSxDQUFDLENBQUM7U0FDcEQ7YUFBTTtZQUNILG9FQUFvRTtZQUNwRSxhQUFhLENBQUMsT0FBTyxDQUFDLENBQUMsS0FBSyxFQUFFLEtBQUssRUFBRSxFQUFFO2dCQUNuQyxJQUNJLEtBQUssQ0FBQyxPQUFPLEtBQUssZUFBZTtvQkFDakMsS0FBSyxDQUFDLE9BQU8sS0FBSyxrQkFBa0I7b0JBQ3BDLEtBQUssQ0FBQyxPQUFPLEtBQUssWUFBWTtvQkFDOUIsS0FBSyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsS0FBSztvQkFDcEMsS0FBSyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsUUFBUTtvQkFDdkMsS0FBSyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsVUFBVTtvQkFDekMsS0FBSyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsT0FBTztvQkFDdEMsS0FBSyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsY0FBYztvQkFDN0MsS0FBSyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsU0FBUztvQkFDeEMsS0FBSyxDQUFDLFNBQVM7d0JBQ2YsVUFBVSxDQUFDLDZCQUE2QjtvQkFDeEMsS0FBSyxDQUFDLFNBQVMsS0FBSyxVQUFVLENBQUMsMEJBQTBCO29CQUN6RCxLQUFLLENBQUMsU0FBUyxLQUFLLFVBQVUsQ0FBQyxPQUFPO29CQUN0QyxLQUFLLENBQUMsU0FBUyxLQUFLLFVBQVUsQ0FBQyxzQkFBc0I7b0JBQ3JELEtBQUssQ0FBQyxTQUFTLEtBQUssVUFBVSxDQUFDLG1CQUFtQixFQUNwRDtvQkFDRSxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQVUsR0FBRyxnQkFBZ0IsQ0FBQyxNQUFNLENBQUM7aUJBQ3JEO3FCQUFNO29CQUNILHFEQUFxRDtvQkFDckQseUdBQXlHO2lCQUM1RztZQUNMLENBQUMsQ0FBQyxDQUFDO1NBQ047UUFFRCxNQUFNLE1BQU0sR0FBbUIsRUFBRSxDQUFDO1FBRWxDLGFBQWEsQ0FBQyxPQUFPLENBQUMsQ0FBQyxLQUFLLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDbkMsTUFBTSxTQUFTLEdBQUcsVUFBVSxDQUFDLE1BQU0sQ0FDL0IsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLE9BQU8sQ0FDdkMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUVMLElBQUksQ0FBQyxTQUFTLEVBQUU7Z0JBQ1osT0FBTzthQUNWO1lBRUQsa0VBQWtFO1lBQ2xFLElBQ0ksSUFBSSxDQUFDLFVBQVUsS0FBSyxPQUFPO2dCQUMzQixDQUFDLENBQUMsSUFBSSxDQUFDLDJCQUEyQjtvQkFDOUIsSUFBSSxDQUFDLFNBQVM7b0JBQ2QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLE9BQU8sQ0FBQztvQkFDekMsQ0FBQyxJQUFJLENBQUMsZUFBZTt3QkFDakIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLE9BQU8sQ0FBQztvQkFDbkQsQ0FBQyxJQUFJLENBQUMsZ0JBQWdCO3dCQUNsQixJQUFJLENBQUMsZ0JBQWdCLENBQUMsT0FBTyxLQUFLLEtBQUssQ0FBQyxPQUFPLENBQUMsQ0FBQyxFQUMzRDtnQkFDRSxPQUFPO2FBQ1Y7WUFFRCxtQkFBbUI7WUFDbkIsSUFBSSxLQUFLLEtBQUssQ0FBQyxJQUFJLElBQUksQ0FBQyxnQkFBZ0IsRUFBRTtnQkFDdEMsU0FBUyxDQUFDLFNBQVMsR0FBRyxVQUFVLENBQUMsWUFBWSxDQUFDO2dCQUM5QyxnREFBZ0Q7YUFDbkQ7WUFFRCxJQUFJLEtBQUssQ0FBQyxPQUFPLEtBQUssWUFBWSxFQUFFO2dCQUNoQyxTQUFTLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztnQkFDekIsdUVBQXVFO2dCQUN2RSxrRUFBa0U7YUFDckU7WUFDRCxNQUFNLFdBQVcsR0FBaUIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsU0FBUyxDQUFDLENBQUM7WUFDekUsTUFBTSxDQUFDLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztRQUVILE9BQU8sTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUMxQixFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHO1lBQ1gsQ0FBQyxDQUFDLENBQUM7WUFDSCxDQUFDLENBQUMsRUFBRSxDQUFDLEdBQUcsR0FBRyxFQUFFLENBQUMsR0FBRztnQkFDYixDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNKLENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHO29CQUNiLENBQUMsQ0FBQyxDQUFDO29CQUNILENBQUMsQ0FBQyxFQUFFLENBQUMsR0FBRyxHQUFHLEVBQUUsQ0FBQyxHQUFHO3dCQUNiLENBQUMsQ0FBQyxDQUFDLENBQUM7d0JBQ0osQ0FBQyxDQUFDLENBQUMsQ0FDdEIsQ0FBQztJQUNOLENBQUM7SUFFRCx1QkFBdUIsQ0FBQyxvQkFBeUI7UUFDN0MsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCxjQUFjLENBQUMsS0FBZ0M7UUFDM0MsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFFOUMsTUFBTSxXQUFXLEdBQUcsSUFBSSxDQUFDLGtCQUFrQixDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUV2RCxNQUFNLE9BQU8sR0FBRyxXQUFXLENBQUMsQ0FBQyxDQUFDLFdBQVcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUN2RCx3QkFBd0I7UUFFeEIsSUFBSSxPQUFPLEVBQUU7WUFDVCx5Q0FBeUM7WUFDekMsSUFBSSxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxVQUFVLEtBQUssTUFBTSxFQUFFO2dCQUMvQyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQzthQUN4QjtZQUVELGtDQUFrQztZQUNsQyxNQUFNLFlBQVksR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsS0FBSyxLQUFLLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDbEUsSUFBSSxZQUFZLEVBQUU7Z0JBQ2QsWUFBWSxDQUFDLGNBQWMsR0FBRyxZQUFZLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQyxLQUFLLENBQUM7YUFDbEU7WUFFRCxJQUFJLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQztnQkFDbEIsRUFBRSxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFFBQVEsRUFBRTtnQkFDNUIsV0FBVyxFQUFFLElBQUksQ0FBQyxJQUFJLENBQUMsR0FBRztnQkFDMUIsR0FBRyxFQUFFLEtBQUssQ0FBQyxHQUFHO2dCQUNkLEtBQUssRUFBRSxLQUFLLENBQUMsS0FBSztnQkFDbEIsV0FBVyxFQUFFLEtBQUssQ0FBQyxXQUFXO2FBQ2pDLENBQUMsQ0FBQztTQUNOO0lBQ0wsQ0FBQztJQUVELE9BQU8sQ0FBQyxlQUFvQztRQUN4QyxNQUFNLHFCQUFxQixHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FDakQsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxPQUFPLEtBQUssZUFBZSxDQUFDLEdBQUcsQ0FDM0MsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNMLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRS9ELElBQUkscUJBQXFCLEVBQUU7WUFDdkIsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7Z0JBQ2pCLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUU7Z0JBQzVCLFdBQVcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUc7Z0JBQzFCLEdBQUcsRUFBRSxlQUFlLENBQUMsR0FBRztnQkFDeEIsTUFBTTtnQkFDTixLQUFLLEVBQUUsZUFBZSxDQUFDLFVBQVU7Z0JBQ2pDLEtBQUssRUFBRSxlQUFlLENBQUMsS0FBSztnQkFDNUIsV0FBVyxFQUFFLGVBQWUsQ0FBQyxXQUFXO2dCQUN4QyxTQUFTLEVBQUUscUJBQXFCLENBQUMsU0FBUztnQkFDMUMsU0FBUyxFQUFFLGVBQWUsQ0FBQyxTQUFTO2FBQ3ZDLENBQUMsQ0FBQztTQUNOO2FBQU07WUFDSCxpREFBaUQ7WUFDakQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7Z0JBQ2pCLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxRQUFRLEVBQUU7Z0JBQzVCLFdBQVcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUc7Z0JBQzFCLEdBQUcsRUFBRSxlQUFlLENBQUMsR0FBRztnQkFDeEIsTUFBTTtnQkFDTixLQUFLLEVBQUUsZUFBZSxDQUFDLFVBQVU7Z0JBQ2pDLEtBQUssRUFBRSxlQUFlLENBQUMsS0FBSztnQkFDNUIsV0FBVyxFQUFFLGVBQWUsQ0FBQyxXQUFXO2dCQUN4QyxTQUFTLEVBQUUsZUFBZSxDQUFDLFNBQVM7YUFDdkMsQ0FBQyxDQUFDO1NBQ047SUFDTCxDQUFDO0lBRUQscURBQXFEO0lBQ3JELDBCQUEwQixDQUFDLHNCQUEyQjtRQUNsRCxJQUFJLENBQUMsc0JBQXNCLENBQUMsSUFBSSxDQUFDLHNCQUFzQixDQUFDLENBQUM7SUFDN0QsQ0FBQztJQUVELHFEQUFxRDtJQUNyRCwwQkFBMEIsQ0FBQyx1QkFBNEI7UUFDbkQsSUFBSSxDQUFDLHVCQUF1QixDQUFDLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxDQUFDO0lBQy9ELENBQUM7SUFFRCw0REFBNEQ7SUFDNUQsa0JBQWtCLENBQUMsS0FBb0M7UUFDbkQsZ0NBQWdDO0lBQ3BDLENBQUM7SUFFRCw0REFBNEQ7SUFDNUQsZ0JBQWdCLENBQUMsS0FBOEI7UUFDM0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDaEMsQ0FBQzs7O1lBMzhDSixTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLFVBQVU7Z0JBQ3BCLDI4UkFBb0M7Z0JBRXBDLGVBQWUsRUFBRSx1QkFBdUIsQ0FBQyxNQUFNOzthQUNsRDs7O1lBcERHLGdCQUFnQjtZQVFoQix1QkFBdUI7WUFDdkIsZ0JBQWdCO1lBZmhCLFdBQVc7WUFSWCxlQUFlO1lBWVYsZ0JBQWdCOzs7eUJBd0RwQixLQUFLO3VCQUNMLEtBQUs7cUJBQ0wsS0FBSzt5QkFDTCxLQUFLOzRCQUNMLEtBQUs7bUJBR0wsS0FBSzt5QkFnQkwsS0FBSzt1QkFLTCxLQUFLO3lCQUNMLEtBQUs7dUJBRUwsS0FBSzt1QkFDTCxLQUFLO3lCQUNMLEtBQUs7d0JBQ0wsS0FBSzsrQkFDTCxLQUFLOzhCQUNMLEtBQUs7MEJBRUwsTUFBTTttQ0FFTixNQUFNO3lCQUdOLE1BQU07cUNBR04sTUFBTTtzQ0FDTixNQUFNIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcbiAgICBDb21wb25lbnQsXG4gICAgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksXG4gICAgT25Jbml0LFxuICAgIE9uRGVzdHJveSxcbiAgICBJbnB1dCxcbiAgICBLZXlWYWx1ZURpZmZlcnMsXG4gICAgT3V0cHV0LFxuICAgIEV2ZW50RW1pdHRlcixcbiAgICBPbkNoYW5nZXMsXG4gICAgRG9DaGVjaywgICAgXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtcbiAgICBGb3JtR3JvdXAsXG4gICAgRm9ybUJ1aWxkZXIsXG4gICAgVmFsaWRhdG9ycyxcbiAgICBBYnN0cmFjdENvbnRyb2wsXG59IGZyb20gJ0Bhbmd1bGFyL2Zvcm1zJztcbmltcG9ydCB7IFRyYW5zbGF0ZVNlcnZpY2UgfSBmcm9tICdAbmd4LXRyYW5zbGF0ZS9jb3JlJztcbmltcG9ydCB7XG4gICAgUGVwRGlhbG9nU2VydmljZSxcbiAgICBQZXBEaWFsb2dEYXRhLFxufSBmcm9tICdAcGVwcGVyaS1hZGRvbnMvbmd4LWxpYi9kaWFsb2cnO1xuaW1wb3J0IHtcbiAgICBJUGVwRmllbGRWYWx1ZUNoYW5nZUV2ZW50LFxuICAgIElQZXBGaWVsZENsaWNrRXZlbnQsXG4gICAgUGVwTGF5b3V0VHlwZSxcbiAgICBGSUVMRF9UWVBFLFxuICAgIFBlcEN1c3RvbWl6YXRpb25TZXJ2aWNlLFxuICAgIFBlcExheW91dFNlcnZpY2UsXG4gICAgVUlDb250cm9sLFxuICAgIFVJQ29udHJvbEZpZWxkLFxuICAgIE9iamVjdHNEYXRhUm93LFxuICAgIE9iamVjdHNEYXRhUm93Q2VsbCxcbiAgICBQZXBGaWVsZEJhc2UsXG4gICAgUGVwVGV4dGJveEZpZWxkLFxuICAgIFBlcFNlbGVjdEZpZWxkLFxuICAgIFBlcEludGVybmFsTWVudUZpZWxkLFxuICAgIFBlcFF1YW50aXR5U2VsZWN0b3JGaWVsZCxcbiAgICBQZXBBZGRyZXNzRmllbGQsXG4gICAgUGVwSW5kaWNhdG9yc0ZpZWxkLFxuICAgIFBlcEludGVybmFsUGFnZUZpZWxkLFxuICAgIFBlcEludGVybmFsQ2FydXNlbEZpZWxkLFxuICAgIFBlcEludGVybmFsQnV0dG9uRmllbGQsXG4gICAgUGVwQXR0YWNobWVudEZpZWxkLFxuICAgIFBlcFNpZ25hdHVyZUZpZWxkLFxuICAgIFBlcEltYWdlRmllbGQsXG4gICAgUGVwSW1hZ2VzRmllbGQsXG4gICAgUGVwTGlua0ZpZWxkLFxuICAgIFBlcFRleHRhcmVhRmllbGQsXG4gICAgUGVwUmljaEh0bWxUZXh0YXJlYUZpZWxkLFxuICAgIFBlcERhdGVGaWVsZCxcbiAgICBQZXBDaGVja2JveEZpZWxkLFxuICAgIFBlcFNlcGFyYXRvckZpZWxkLFxuICAgIFBlcFBsYWNlaG9sZGVyRmllbGQsXG4gICAgUGVwSG9yaXpvbnRhbEFsaWdubWVudCxcbiAgICBQZXBWZXJ0aWNhbEFsaWdubWVudCxcbiAgICBYX0FMSUdOTUVOVF9UWVBFLFxuICAgIFlfQUxJR05NRU5UX1RZUEUsXG4gICAgREVGQVVMVF9WRVJUSUNBTF9BTElHTk1FTlQsXG4gICAgREVGQVVMVF9IT1JJWk9OVEFMX0FMSUdOTUVOVCxcbiAgICBLZXlWYWx1ZVBhaXIsXG4gICAgSVBlcE9wdGlvbixcbn0gZnJvbSAnQHBlcHBlcmktYWRkb25zL25neC1saWInO1xuaW1wb3J0IHsgQmVoYXZpb3JTdWJqZWN0LCBPYnNlcnZhYmxlIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBJUGVwRm9ybUZpZWxkVmFsdWVDaGFuZ2VFdmVudCwgSVBlcEZvcm1GaWVsZENsaWNrRXZlbnQgfSBmcm9tICcuL2Zvcm0ubW9kZWwnO1xuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvcjogJ3BlcC1mb3JtJyxcbiAgICB0ZW1wbGF0ZVVybDogJy4vZm9ybS5jb21wb25lbnQuaHRtbCcsXG4gICAgc3R5bGVVcmxzOiBbJy4vZm9ybS5jb21wb25lbnQuc2NzcyddLFxuICAgIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBQZXBGb3JtQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBEb0NoZWNrLCBPbkNoYW5nZXMsIE9uRGVzdHJveSB7XG4gICAgQElucHV0KCkgaXNJbnRlcm5hbCA9IHRydWU7XG4gICAgQElucHV0KCkgaXNSZXBvcnQgPSBmYWxzZTtcbiAgICBASW5wdXQoKSBsYXlvdXQ6IFVJQ29udHJvbDtcbiAgICBASW5wdXQoKSBsb2NrRXZlbnRzID0gZmFsc2U7XG4gICAgQElucHV0KCkgY2FuRWRpdE9iamVjdCA9IHRydWU7XG5cbiAgICBwcml2YXRlIF9kYXRhOiBPYmplY3RzRGF0YVJvdyA9IG51bGw7XG4gICAgQElucHV0KClcbiAgICBzZXQgZGF0YSh2YWx1ZTogT2JqZWN0c0RhdGFSb3cpIHtcbiAgICAgICAgY29uc3Qgc2hvdWxkUmVsb2FkID0gdGhpcy5zaG91bGRSZWxvYWRGb3JtIHx8ICF0aGlzLl9kYXRhO1xuICAgICAgICB0aGlzLl9kYXRhID0gdmFsdWU7XG5cbiAgICAgICAgaWYgKHNob3VsZFJlbG9hZCkge1xuICAgICAgICAgICAgdGhpcy5fc2hvdWxkUmVsb2FkRm9ybSA9IGZhbHNlO1xuICAgICAgICAgICAgdGhpcy5pbml0Rm9ybSgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVGb3JtKCk7XG4gICAgICAgIH1cbiAgICB9XG4gICAgZ2V0IGRhdGEoKTogT2JqZWN0c0RhdGFSb3cge1xuICAgICAgICByZXR1cm4gdGhpcy5fZGF0YTtcbiAgICB9XG5cbiAgICBASW5wdXQoKVxuICAgIHNldCBsb2NrRmllbGRzKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIHRoaXMuaXNMb2NrZWQgPSB2YWx1ZTtcbiAgICB9XG5cbiAgICBASW5wdXQoKSBpc0FjdGl2ZSA9IGZhbHNlOyAgICBcbiAgICBASW5wdXQoKSBsYXlvdXRUeXBlOiBQZXBMYXlvdXRUeXBlID0gJ2NhcmQnO1xuICAgIC8vIEBJbnB1dCgpIGxpc3RUeXBlID0gJyc7XG4gICAgQElucHV0KCkgb2JqZWN0SWQgPSAnMCc7XG4gICAgQElucHV0KCkgcGFyZW50SWQgPSAnMCc7XG4gICAgQElucHV0KCkgc2VhcmNoQ29kZSA9ICcwJztcbiAgICBASW5wdXQoKSBzaG93VGl0bGUgPSB0cnVlO1xuICAgIEBJbnB1dCgpIGZpcnN0RmllbGRBc0xpbmsgPSBmYWxzZTtcbiAgICBASW5wdXQoKSBjaGVja0ZvckNoYW5nZXM6IGFueSA9IG51bGw7XG5cbiAgICBAT3V0cHV0KClcbiAgICB2YWx1ZUNoYW5nZTogRXZlbnRFbWl0dGVyPElQZXBGb3JtRmllbGRWYWx1ZUNoYW5nZUV2ZW50PiA9IG5ldyBFdmVudEVtaXR0ZXI8SVBlcEZvcm1GaWVsZFZhbHVlQ2hhbmdlRXZlbnQ+KCk7XG4gICAgQE91dHB1dCgpXG4gICAgZm9ybVZhbGlkYXRpb25DaGFuZ2U6IEV2ZW50RW1pdHRlcjxib29sZWFuPiA9IG5ldyBFdmVudEVtaXR0ZXI8Ym9vbGVhbj4oKTtcblxuICAgIEBPdXRwdXQoKVxuICAgIGZpZWxkQ2xpY2s6IEV2ZW50RW1pdHRlcjxJUGVwRm9ybUZpZWxkQ2xpY2tFdmVudD4gPSBuZXcgRXZlbnRFbWl0dGVyPElQZXBGb3JtRmllbGRDbGlja0V2ZW50PigpO1xuXG4gICAgQE91dHB1dCgpIGludGVybmFsRm9ybUZpZWxkQ2xpY2s6IEV2ZW50RW1pdHRlcjxhbnk+ID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XG4gICAgQE91dHB1dCgpIGludGVybmFsRm9ybUZpZWxkQ2hhbmdlOiBFdmVudEVtaXR0ZXI8YW55PiA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xuXG4gICAgaXNMb2NrZWQgPSBmYWxzZTtcbiAgICBmb3JtR3V0dGVyU2l6ZTtcbiAgICBjYXJkR3V0dGVyU2l6ZTtcbiAgICByb3dIZWlnaHQ7XG4gICAgLy8gcHJpdmF0ZSBtYXRyaXhJc0xhc3QgPSBmYWxzZTtcbiAgICAvLyBsYXN0VXBkYXRlZEZpZWxkQXBpTmFtZTogc3RyaW5nID0gJyc7XG4gICAgZm9ybTogRm9ybUdyb3VwO1xuICAgIGRpZmZlcjogYW55O1xuXG4gICAgLy8gcGF5TG9hZCA9ICcnO1xuICAgIHByaXZhdGUgcm93czogQXJyYXk8UGVwRmllbGRCYXNlW10+ID0gW107XG4gICAgZmllbGRzOiBQZXBGaWVsZEJhc2VbXSA9IFtdO1xuXG4gICAgcHJpdmF0ZSBfZmllbGRzU3ViamVjdDogQmVoYXZpb3JTdWJqZWN0PFBlcEZpZWxkQmFzZVtdPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8UGVwRmllbGRCYXNlW10+KFtdKTtcbiAgICBnZXQgZmllbGRzJCgpOiBPYnNlcnZhYmxlPFBlcEZpZWxkQmFzZVtdPiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9maWVsZHNTdWJqZWN0LmFzT2JzZXJ2YWJsZSgpO1xuICAgIH1cblxuICAgIGNvbHVtbnMgPSAxO1xuXG4gICAgcHJpdmF0ZSBoYXNNZW51RmxvYXRpbmdPbk90aGVyRmllbGQgPSBmYWxzZTtcbiAgICBwcml2YXRlIG1lbnVGaWVsZDogYW55O1xuICAgIHByaXZhdGUgbWVudURhdGFGaWVsZDogYW55O1xuICAgIHByaXZhdGUgaGFzQ2FtcGFpZ25GaWVsZDogYW55O1xuICAgIHByaXZhdGUgaGFzQ2FtcGFpZ25EYXRhRmllbGQ6IGFueTtcbiAgICBwcml2YXRlIGluZGljYXRvcnNGaWVsZDogYW55O1xuICAgIHByaXZhdGUgaW5kaWNhdG9yc0RhdGFGaWVsZDogYW55ID0gbnVsbDtcblxuICAgIHByaXZhdGUgX3Nob3VsZFJlbG9hZEZvcm0gPSBmYWxzZTtcbiAgICBnZXQgc2hvdWxkUmVsb2FkRm9ybSgpOiBib29sZWFuIHtcbiAgICAgICAgcmV0dXJuIHRoaXMuX3Nob3VsZFJlbG9hZEZvcm07XG4gICAgfVxuXG4gICAgLy8gZXZlbnRTZXJ2aWNlU3ViOiBTdWJzY3JpcHRpb247XG4gICAgLy8gcHVibGljIGpzb25MaWIgPSBKU09OO1xuXG4gICAgY29uc3RydWN0b3IoXG4gICAgICAgIHByaXZhdGUgZGlhbG9nU2VydmljZTogUGVwRGlhbG9nU2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBjdXN0b21pemF0aW9uU2VydmljZTogUGVwQ3VzdG9taXphdGlvblNlcnZpY2UsXG4gICAgICAgIHByaXZhdGUgbGF5b3V0U2VydmljZTogUGVwTGF5b3V0U2VydmljZSxcbiAgICAgICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXIsXG4gICAgICAgIGRpZmZlcnM6IEtleVZhbHVlRGlmZmVycyxcbiAgICAgICAgcHJpdmF0ZSB0cmFuc2xhdGU6IFRyYW5zbGF0ZVNlcnZpY2VcbiAgICApIHtcbiAgICAgICAgLy8gc3RvcmUgdGhlIGluaXRpYWwgdmFsdWUgdG8gY29tcGFyZSB3aXRoXG4gICAgICAgIHRoaXMuZGlmZmVyID0gZGlmZmVycy5maW5kKHt9KS5jcmVhdGUoKTtcbiAgICB9XG5cbiAgICBjb252ZXJ0WEFsaWduVG9Ib3Jpem9udGFsQWxpZ24oXG4gICAgICAgIHhBbGlnbjogWF9BTElHTk1FTlRfVFlQRVxuICAgICk6IFBlcEhvcml6b250YWxBbGlnbm1lbnQge1xuICAgICAgICBsZXQgcmVzID0gREVGQVVMVF9IT1JJWk9OVEFMX0FMSUdOTUVOVDtcblxuICAgICAgICBpZiAoXG4gICAgICAgICAgICB4QWxpZ24gPT09IFhfQUxJR05NRU5UX1RZUEUuTm9uZSB8fFxuICAgICAgICAgICAgeEFsaWduID09PSBYX0FMSUdOTUVOVF9UWVBFLkxlZnRcbiAgICAgICAgKSB7XG4gICAgICAgICAgICByZXMgPSAnbGVmdCc7XG4gICAgICAgIH0gZWxzZSBpZiAoeEFsaWduID09PSBYX0FMSUdOTUVOVF9UWVBFLlJpZ2h0KSB7XG4gICAgICAgICAgICByZXMgPSAncmlnaHQnO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgcmVzID0gJ2NlbnRlcic7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gcmVzO1xuICAgIH1cblxuICAgIGNvbnZlcnRZQWxpZ25Ub1ZlcnRpY2FsQWxpZ24oXG4gICAgICAgIHlBbGlnbjogWV9BTElHTk1FTlRfVFlQRVxuICAgICk6IFBlcFZlcnRpY2FsQWxpZ25tZW50IHtcbiAgICAgICAgbGV0IHJlcyA9IERFRkFVTFRfVkVSVElDQUxfQUxJR05NRU5UO1xuXG4gICAgICAgIGlmIChcbiAgICAgICAgICAgIHlBbGlnbiA9PT0gWV9BTElHTk1FTlRfVFlQRS5Ob25lIHx8XG4gICAgICAgICAgICB5QWxpZ24gPT09IFlfQUxJR05NRU5UX1RZUEUuVG9wXG4gICAgICAgICkge1xuICAgICAgICAgICAgcmVzID0gJ3RvcCc7XG4gICAgICAgIH0gZWxzZSBpZiAoeUFsaWduID09PSBZX0FMSUdOTUVOVF9UWVBFLkJvdHRvbSkge1xuICAgICAgICAgICAgcmVzID0gJ2JvdHRvbSc7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXMgPSAnbWlkZGxlJztcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiByZXM7XG4gICAgfVxuXG4gICAgY29udmVydE9wdGlvbmFsVmFsdWVzKFxuICAgICAgICBvcHRpb25hbFZhbHVlczogQXJyYXk8S2V5VmFsdWVQYWlyPHN0cmluZz4+XG4gICAgKTogSVBlcE9wdGlvbltdIHtcbiAgICAgICAgaWYgKG9wdGlvbmFsVmFsdWVzICYmIG9wdGlvbmFsVmFsdWVzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIHJldHVybiBvcHRpb25hbFZhbHVlcy5tYXAoKG92KSA9PiB7XG4gICAgICAgICAgICAgICAgcmV0dXJuIHsga2V5OiBvdi5LZXksIHZhbHVlOiBvdi5WYWx1ZSB9O1xuICAgICAgICAgICAgfSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICByZXR1cm4gW107XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBjb252ZXJ0QWRkcmVzc0ZpZWxkcyhcbiAgICAgICAgY29udHJvbEZpZWxkOiBVSUNvbnRyb2xGaWVsZCxcbiAgICAgICAgYWRkcmVzc0ZpZWxkczogQXJyYXk8T2JqZWN0c0RhdGFSb3dDZWxsPixcbiAgICAgICAgY2FuRWRpdE9iamVjdDogYm9vbGVhblxuICAgICk6IFBlcEZpZWxkQmFzZVtdIHtcbiAgICAgICAgY29uc3QgZmllbGRzOiBQZXBGaWVsZEJhc2VbXSA9IFtdO1xuXG4gICAgICAgIGFkZHJlc3NGaWVsZHMuZm9yRWFjaCgoZmllbGQpID0+IHtcbiAgICAgICAgICAgIGxldCBjdXN0b21GaWVsZDogUGVwRmllbGRCYXNlO1xuICAgICAgICAgICAgY29uc3QgcGxhY2Vob2xkZXIgPSBmaWVsZC5BcGlOYW1lO1xuXG4gICAgICAgICAgICBpZiAoZmllbGQuQXBpTmFtZS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ3N0cmVldCcpID49IDApIHtcbiAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBUZXh0Ym94RmllbGQoe1xuICAgICAgICAgICAgICAgICAgICBrZXk6IGZpZWxkLkFwaU5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBmaWVsZC5BcGlOYW1lLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyLFxuICAgICAgICAgICAgICAgICAgICByZWFkb25seTogIWNhbkVkaXRPYmplY3QsXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkOiAhZmllbGQuRW5hYmxlZCB8fCAhY2FuRWRpdE9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgaGlkZGVuOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZpZWxkLlZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZWRWYWx1ZTogZmllbGQuRm9ybWF0dGVkVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHJvdzogMCxcbiAgICAgICAgICAgICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICAgICAgICAgICAgY29sOiAwLFxuICAgICAgICAgICAgICAgICAgICBjb2xTcGFuOiAyLFxuICAgICAgICAgICAgICAgICAgICB4QWxpZ25tZW50OiB0aGlzLmNvbnZlcnRYQWxpZ25Ub0hvcml6b250YWxBbGlnbihcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xGaWVsZC5MYXlvdXQuWEFsaWdubWVudFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICB5QWxpZ25tZW50OiB0aGlzLmNvbnZlcnRZQWxpZ25Ub1ZlcnRpY2FsQWxpZ24oXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sRmllbGQuTGF5b3V0LllBbGlnbm1lbnRcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgb3JkZXI6IDAsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGZpZWxkLkFwaU5hbWUudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdjaXR5JykgPj0gMCkge1xuICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcFRleHRib3hGaWVsZCh7XG4gICAgICAgICAgICAgICAgICAgIGtleTogZmllbGQuQXBpTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgbGFiZWw6IGZpZWxkLkFwaU5hbWUsXG4gICAgICAgICAgICAgICAgICAgIHR5cGU6ICd0ZXh0JyxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXIsXG4gICAgICAgICAgICAgICAgICAgIHJlYWRvbmx5OiAhY2FuRWRpdE9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6ICFmaWVsZC5FbmFibGVkIHx8ICFjYW5FZGl0T2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICBoaWRkZW46IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICBtYW5kYXRvcnk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZmllbGQuVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIGZvcm1hdHRlZFZhbHVlOiBmaWVsZC5Gb3JtYXR0ZWRWYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgcm93OiAwLFxuICAgICAgICAgICAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgICAgICAgICAgICBjb2w6IDIsXG4gICAgICAgICAgICAgICAgICAgIGNvbFNwYW46IDEsXG4gICAgICAgICAgICAgICAgICAgIHhBbGlnbm1lbnQ6IHRoaXMuY29udmVydFhBbGlnblRvSG9yaXpvbnRhbEFsaWduKFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbEZpZWxkLkxheW91dC5YQWxpZ25tZW50XG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIHlBbGlnbm1lbnQ6IHRoaXMuY29udmVydFlBbGlnblRvVmVydGljYWxBbGlnbihcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xGaWVsZC5MYXlvdXQuWUFsaWdubWVudFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICBvcmRlcjogMSxcbiAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZmllbGQuQXBpTmFtZS50b0xvd2VyQ2FzZSgpLmluZGV4T2YoJ3N0YXRlJykgPj0gMCkge1xuICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcFNlbGVjdEZpZWxkKHtcbiAgICAgICAgICAgICAgICAgICAga2V5OiBmaWVsZC5BcGlOYW1lLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogZmllbGQuQXBpTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXIsXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IHRoaXMuY29udmVydE9wdGlvbmFsVmFsdWVzKGZpZWxkLk9wdGlvbmFsVmFsdWVzKSxcbiAgICAgICAgICAgICAgICAgICAgcmVhZG9ubHk6ICFjYW5FZGl0T2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogIWZpZWxkLkVuYWJsZWQgfHwgIWNhbkVkaXRPYmplY3QsXG4gICAgICAgICAgICAgICAgICAgIGhpZGRlbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1hbmRhdG9yeTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmaWVsZC5WYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVkVmFsdWU6IGZpZWxkLkZvcm1hdHRlZFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICByb3c6IDEsXG4gICAgICAgICAgICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgICAgICAgICAgIGNvbDogMCxcbiAgICAgICAgICAgICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICAgICAgICAgICAgeEFsaWdubWVudDogdGhpcy5jb252ZXJ0WEFsaWduVG9Ib3Jpem9udGFsQWxpZ24oXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sRmllbGQuTGF5b3V0LlhBbGlnbm1lbnRcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgeUFsaWdubWVudDogdGhpcy5jb252ZXJ0WUFsaWduVG9WZXJ0aWNhbEFsaWduKFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbEZpZWxkLkxheW91dC5ZQWxpZ25tZW50XG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyOiAyLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChmaWVsZC5BcGlOYW1lLnRvTG93ZXJDYXNlKCkuaW5kZXhPZignemlwY29kZScpID49IDApIHtcbiAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBUZXh0Ym94RmllbGQoe1xuICAgICAgICAgICAgICAgICAgICBrZXk6IGZpZWxkLkFwaU5hbWUsXG4gICAgICAgICAgICAgICAgICAgIGxhYmVsOiBmaWVsZC5BcGlOYW1lLFxuICAgICAgICAgICAgICAgICAgICB0eXBlOiAndGV4dCcsXG4gICAgICAgICAgICAgICAgICAgIHBsYWNlaG9sZGVyLFxuICAgICAgICAgICAgICAgICAgICByZWFkb25seTogIWNhbkVkaXRPYmplY3QsXG4gICAgICAgICAgICAgICAgICAgIGRpc2FibGVkOiAhZmllbGQuRW5hYmxlZCB8fCAhY2FuRWRpdE9iamVjdCxcbiAgICAgICAgICAgICAgICAgICAgaGlkZGVuOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgbWFuZGF0b3J5OiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgdmFsdWU6IGZpZWxkLlZhbHVlLFxuICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZWRWYWx1ZTogZmllbGQuRm9ybWF0dGVkVmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHJvdzogMSxcbiAgICAgICAgICAgICAgICAgICAgcm93U3BhbjogMSxcbiAgICAgICAgICAgICAgICAgICAgY29sOiAxLFxuICAgICAgICAgICAgICAgICAgICBjb2xTcGFuOiAxLFxuICAgICAgICAgICAgICAgICAgICB4QWxpZ25tZW50OiB0aGlzLmNvbnZlcnRYQWxpZ25Ub0hvcml6b250YWxBbGlnbihcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xGaWVsZC5MYXlvdXQuWEFsaWdubWVudFxuICAgICAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgICAgICB5QWxpZ25tZW50OiB0aGlzLmNvbnZlcnRZQWxpZ25Ub1ZlcnRpY2FsQWxpZ24oXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sRmllbGQuTGF5b3V0LllBbGlnbm1lbnRcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgb3JkZXI6IDMsXG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGZpZWxkLkFwaU5hbWUudG9Mb3dlckNhc2UoKS5pbmRleE9mKCdjb3VudHJ5JykgPj0gMCkge1xuICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcFNlbGVjdEZpZWxkKHtcbiAgICAgICAgICAgICAgICAgICAga2V5OiBmaWVsZC5BcGlOYW1lLFxuICAgICAgICAgICAgICAgICAgICBsYWJlbDogZmllbGQuQXBpTmFtZSxcbiAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXIsXG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IHRoaXMuY29udmVydE9wdGlvbmFsVmFsdWVzKGZpZWxkLk9wdGlvbmFsVmFsdWVzKSxcbiAgICAgICAgICAgICAgICAgICAgcmVhZG9ubHk6ICFjYW5FZGl0T2JqZWN0LFxuICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogIWZpZWxkLkVuYWJsZWQgfHwgIWNhbkVkaXRPYmplY3QsXG4gICAgICAgICAgICAgICAgICAgIGhpZGRlbjogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIG1hbmRhdG9yeTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBmaWVsZC5WYWx1ZSxcbiAgICAgICAgICAgICAgICAgICAgZm9ybWF0dGVkVmFsdWU6IGZpZWxkLkZvcm1hdHRlZFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICByb3c6IDIsXG4gICAgICAgICAgICAgICAgICAgIHJvd1NwYW46IDEsXG4gICAgICAgICAgICAgICAgICAgIGNvbDogMixcbiAgICAgICAgICAgICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICAgICAgICAgICAgeEFsaWdubWVudDogdGhpcy5jb252ZXJ0WEFsaWduVG9Ib3Jpem9udGFsQWxpZ24oXG4gICAgICAgICAgICAgICAgICAgICAgICBjb250cm9sRmllbGQuTGF5b3V0LlhBbGlnbm1lbnRcbiAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgeUFsaWdubWVudDogdGhpcy5jb252ZXJ0WUFsaWduVG9WZXJ0aWNhbEFsaWduKFxuICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbEZpZWxkLkxheW91dC5ZQWxpZ25tZW50XG4gICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgIG9yZGVyOiA0LFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICBmaWVsZHMucHVzaChjdXN0b21GaWVsZCk7XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBmaWVsZHMuc29ydCgobjEsIG4yKSA9PlxuICAgICAgICAgICAgbjEub3JkZXIgPiBuMi5vcmRlciA/IDEgOiBuMS5vcmRlciA8IG4yLm9yZGVyID8gLTEgOiAwXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgaXNNYXRyaXhGaWVsZChhcGlOYW1lVG9DaGVjazogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiBhcGlOYW1lVG9DaGVjay5pbmRleE9mKCdNYXRyaXgnKSA+PSAwO1xuICAgIH1cblxuICAgIGRvZXNGaWVsZEhhdmFGbG9hdGluZ0ZpZWxkKFxuICAgICAgICBjb250cm9sRmllbGQ6IFVJQ29udHJvbEZpZWxkLFxuICAgICAgICBmbG9hdGluZ0ZpZWxkOiBhbnlcbiAgICApOiBib29sZWFuIHtcbiAgICAgICAgbGV0IGhhc0Zsb2F0aW5nRmllbGQgPSBmYWxzZTtcbiAgICAgICAgaWYgKFxuICAgICAgICAgICAgZmxvYXRpbmdGaWVsZC5MYXlvdXQuWSA+PSBjb250cm9sRmllbGQuTGF5b3V0LlkgJiZcbiAgICAgICAgICAgIGZsb2F0aW5nRmllbGQuTGF5b3V0LlkgPFxuICAgICAgICAgICAgY29udHJvbEZpZWxkLkxheW91dC5ZICsgY29udHJvbEZpZWxkLkxheW91dC5IZWlnaHQgJiZcbiAgICAgICAgICAgIGZsb2F0aW5nRmllbGQuTGF5b3V0LlggPj0gY29udHJvbEZpZWxkLkxheW91dC5YICYmXG4gICAgICAgICAgICBmbG9hdGluZ0ZpZWxkLkxheW91dC5YIDxcbiAgICAgICAgICAgIGNvbnRyb2xGaWVsZC5MYXlvdXQuWCArIGNvbnRyb2xGaWVsZC5MYXlvdXQuV2lkdGhcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBoYXNGbG9hdGluZ0ZpZWxkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiBoYXNGbG9hdGluZ0ZpZWxkO1xuICAgIH1cblxuICAgIGdldE9wdGlvbnNGb3JDdXN0b21GaWVsZChcbiAgICAgICAgY29udHJvbEZpZWxkOiBVSUNvbnRyb2xGaWVsZCxcbiAgICAgICAgZGF0YUZpZWxkOiBhbnksXG4gICAgICAgIGNhbkVkaXRPYmplY3Q6IGJvb2xlYW5cbiAgICApOiBhbnkge1xuICAgICAgICBpZiAoIWNvbnRyb2xGaWVsZCB8fCAhZGF0YUZpZWxkKSB7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBwbGFjZWhvbGRlciA9XG4gICAgICAgICAgICBjb250cm9sRmllbGQuUmVhZE9ubHkgfHwgIWNhbkVkaXRPYmplY3QgPyAnJyA6IGNvbnRyb2xGaWVsZC5UaXRsZTtcblxuICAgICAgICBsZXQgZmllbGRQcm9wZXJ0aWVzID0ge1xuICAgICAgICAgICAga2V5OiBjb250cm9sRmllbGQuQXBpTmFtZSxcbiAgICAgICAgICAgIGxhYmVsOiBjb250cm9sRmllbGQuVGl0bGUsXG4gICAgICAgICAgICBhY2Nlc3Nvcnk6IGRhdGFGaWVsZC5BY2Nlc3NvcnksXG4gICAgICAgICAgICBwbGFjZWhvbGRlcixcbiAgICAgICAgICAgIHJlYWRvbmx5OiBjb250cm9sRmllbGQuUmVhZE9ubHkgfHwgIWNhbkVkaXRPYmplY3QsXG4gICAgICAgICAgICBkaXNhYmxlZDogIWRhdGFGaWVsZC5FbmFibGVkIHx8ICFjYW5FZGl0T2JqZWN0LFxuICAgICAgICAgICAgaGlkZGVuOiBjb250cm9sRmllbGQuSGlkZGVuLFxuICAgICAgICAgICAgbWFuZGF0b3J5OiBjb250cm9sRmllbGQuTWFuZGF0b3J5LFxuICAgICAgICAgICAgdmFsdWU6IGRhdGFGaWVsZC5WYWx1ZSxcbiAgICAgICAgICAgIGZvcm1hdHRlZFZhbHVlOiBkYXRhRmllbGQuRm9ybWF0dGVkVmFsdWUsXG4gICAgICAgICAgICBhZGRpdGlvbmFsVmFsdWU6IGRhdGFGaWVsZC5BZGRpdGlvbmFsVmFsdWUsXG4gICAgICAgICAgICByb3c6IGNvbnRyb2xGaWVsZC5MYXlvdXQuWSxcbiAgICAgICAgICAgIHJvd1NwYW46IGNvbnRyb2xGaWVsZC5MYXlvdXQuSGVpZ2h0LFxuICAgICAgICAgICAgY29sOiBjb250cm9sRmllbGQuTGF5b3V0LlgsXG4gICAgICAgICAgICBjb2xTcGFuOiBjb250cm9sRmllbGQuTGF5b3V0LldpZHRoLFxuICAgICAgICAgICAgeEFsaWdubWVudDogdGhpcy5jb252ZXJ0WEFsaWduVG9Ib3Jpem9udGFsQWxpZ24oXG4gICAgICAgICAgICAgICAgY29udHJvbEZpZWxkLkxheW91dC5YQWxpZ25tZW50XG4gICAgICAgICAgICApLFxuICAgICAgICAgICAgeUFsaWdubWVudDogdGhpcy5jb252ZXJ0WUFsaWduVG9WZXJ0aWNhbEFsaWduKFxuICAgICAgICAgICAgICAgIGNvbnRyb2xGaWVsZC5MYXlvdXQuWUFsaWdubWVudFxuICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIG9wdGlvbnM6IHRoaXMuY29udmVydE9wdGlvbmFsVmFsdWVzKGRhdGFGaWVsZC5PcHRpb25hbFZhbHVlcyksXG4gICAgICAgICAgICBncm91cEZpZWxkczogdW5kZWZpbmVkLFxuICAgICAgICAgICAgbWF4RmllbGRDaGFyYWN0ZXJzOiBjb250cm9sRmllbGQuTWF4RmllbGRDaGFyYWN0ZXJzLFxuICAgICAgICAgICAgbWluVmFsdWU6IGNvbnRyb2xGaWVsZC5NaW5WYWx1ZSxcbiAgICAgICAgICAgIG1heFZhbHVlOiBjb250cm9sRmllbGQuTWF4VmFsdWUsXG4gICAgICAgICAgICAvLyBoYXNNZW51OiBoYXNNZW51LFxuICAgICAgICAgICAgLy8gaGFzQ2FtcGFpZ246IGhhc0NhbXBhaWduLFxuICAgICAgICAgICAgLy8gaGFzSW5kaWNhdG9yczogaGFzSW5kaWNhdG9ycyxcbiAgICAgICAgICAgIHRleHRDb2xvcjogZGF0YUZpZWxkLlRleHRDb2xvcixcbiAgICAgICAgICAgIHZpc2libGU6IGRhdGFGaWVsZC5WaXNpYmxlLFxuICAgICAgICB9O1xuXG4gICAgICAgIGlmIChkYXRhRmllbGQuQWRkaXRpb25hbFByb3BzKSB7XG4gICAgICAgICAgICBmaWVsZFByb3BlcnRpZXMgPSB7XG4gICAgICAgICAgICAgICAgLi4uZmllbGRQcm9wZXJ0aWVzLFxuICAgICAgICAgICAgICAgIC4uLmRhdGFGaWVsZC5BZGRpdGlvbmFsUHJvcHNcbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICByZXR1cm4gZmllbGRQcm9wZXJ0aWVzO1xuICAgIH1cblxuICAgIGNvbnZlcnRUb0N1c3RvbUZpZWxkKFxuICAgICAgICBjb250cm9sRmllbGQ6IFVJQ29udHJvbEZpZWxkLFxuICAgICAgICBkYXRhRmllbGQ6IGFueSxcbiAgICAgICAgY2FuRWRpdE9iamVjdDogYm9vbGVhbixcbiAgICAgICAgbWVudUZpZWxkOiBhbnksXG4gICAgICAgIGhhc0NhbXBhaWduRmllbGQ6IGFueSxcbiAgICAgICAgaW5kaWNhdG9yc0ZpZWxkOiBhbnksXG4gICAgICAgIG9iamVjdElkOiBhbnksXG4gICAgICAgIHBhcmVudElkOiBhbnksXG4gICAgICAgIHNlYXJjaENvZGU6IGFueVxuICAgICk6IFBlcEZpZWxkQmFzZSB7XG4gICAgICAgIGxldCBjdXN0b21GaWVsZDogUGVwRmllbGRCYXNlO1xuICAgICAgICBjb25zdCBvcHRpb25zID0gdGhpcy5nZXRPcHRpb25zRm9yQ3VzdG9tRmllbGQoXG4gICAgICAgICAgICBjb250cm9sRmllbGQsXG4gICAgICAgICAgICBkYXRhRmllbGQsXG4gICAgICAgICAgICBjYW5FZGl0T2JqZWN0XG4gICAgICAgICk7XG5cbiAgICAgICAgaWYgKGNvbnRyb2xGaWVsZC5BcGlOYW1lID09PSAnT2JqZWN0TWVudScpIHtcbiAgICAgICAgICAgIG9wdGlvbnMudHlwZSA9ICdtZW51JztcbiAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcEludGVybmFsTWVudUZpZWxkKG9wdGlvbnMpO1xuICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgY29udHJvbEZpZWxkLkZpZWxkVHlwZSA9PT0gRklFTERfVFlQRS5OdW1iZXJSZWFsUXVhbnRpdHlTZWxlY3RvciB8fFxuICAgICAgICAgICAgY29udHJvbEZpZWxkLkZpZWxkVHlwZSA9PT1cbiAgICAgICAgICAgIEZJRUxEX1RZUEUuTnVtYmVySW50ZWdlclF1YW50aXR5U2VsZWN0b3IgfHxcbiAgICAgICAgICAgIGNvbnRyb2xGaWVsZC5BcGlOYW1lID09PSAnUXVhbnRpdHlTZWxlY3RvcicgfHxcbiAgICAgICAgICAgIGNvbnRyb2xGaWVsZC5BcGlOYW1lID09PSAnVW5pdHNRdWFudGl0eScgfHxcbiAgICAgICAgICAgIGNvbnRyb2xGaWVsZC5BcGlOYW1lLmluZGV4T2YoJ3NpemVfJykgPT09IDBcbiAgICAgICAgKSB7XG4gICAgICAgICAgICBpZiAoZGF0YUZpZWxkLkZpZWxkVHlwZSA9PT0gRklFTERfVFlQRS5JbnRlcm5hbExpbmspIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAnYnV0dG9uJztcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZGF0YUZpZWxkLkZpZWxkVHlwZSA9PT0gRklFTERfVFlQRS5QYWNrYWdlKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy50eXBlID0gJ3BhY2thZ2VCdXR0b24nO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChcbiAgICAgICAgICAgICAgICBkYXRhRmllbGQuRmllbGRUeXBlID09PSBGSUVMRF9UWVBFLk51bWJlclJlYWxRdWFudGl0eVNlbGVjdG9yIHx8XG4gICAgICAgICAgICAgICAgZGF0YUZpZWxkLkZpZWxkVHlwZSA9PT0gRklFTERfVFlQRS5OdW1iZXJSZWFsXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAncXMnO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuYWxsb3dEZWNpbWFsID0gdHJ1ZTtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoXG4gICAgICAgICAgICAgICAgZGF0YUZpZWxkLkZpZWxkVHlwZSA9PT1cbiAgICAgICAgICAgICAgICBGSUVMRF9UWVBFLk51bWJlckludGVnZXJRdWFudGl0eVNlbGVjdG9yIHx8XG4gICAgICAgICAgICAgICAgZGF0YUZpZWxkLkZpZWxkVHlwZSA9PT0gRklFTERfVFlQRS5OdW1iZXJJbnRlZ2VyXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAncXMnO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuYWxsb3dEZWNpbWFsID0gZmFsc2U7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKFxuICAgICAgICAgICAgICAgIGRhdGFGaWVsZC5GaWVsZFR5cGUgPT09IEZJRUxEX1RZUEUuTnVtYmVySW50ZWdlckZvck1hdHJpeFxuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy50eXBlID0gJ3FzRm9yTWF0cml4JztcbiAgICAgICAgICAgICAgICBvcHRpb25zLmFsbG93RGVjaW1hbCA9IGZhbHNlO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkYXRhRmllbGQuRmllbGRUeXBlID09PSBGSUVMRF9UWVBFLk51bWJlclJlYWxGb3JNYXRyaXgpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAncXNGb3JNYXRyaXgnO1xuICAgICAgICAgICAgICAgIG9wdGlvbnMuYWxsb3dEZWNpbWFsID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgb3B0aW9ucy5ub3RpZmljYXRpb25JbmZvID0gZGF0YUZpZWxkLk5vdGlmaWNhdGlvbkluZm87XG4gICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBRdWFudGl0eVNlbGVjdG9yRmllbGQob3B0aW9ucyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBIQUNLOiBuZWVkIHRvIHJlbW92ZSB0aGlzLi5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICBkYXRhRmllbGQuRmllbGRUeXBlID09PSBGSUVMRF9UWVBFLkluZGljYXRvcnMgJiZcbiAgICAgICAgICAgICAgICB0aGlzLmlzTWF0cml4RmllbGQoZGF0YUZpZWxkLkFwaU5hbWUpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICBkYXRhRmllbGQuRmllbGRUeXBlID0gRklFTERfVFlQRS5JbnRlcm5hbFBhZ2U7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHN3aXRjaCAoZGF0YUZpZWxkLkZpZWxkVHlwZSkge1xuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5BZGRyZXNzOiB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGNhbkVkaXRHcm91cE9iamVjdCA9IGNvbnRyb2xGaWVsZC5SZWFkT25seVxuICAgICAgICAgICAgICAgICAgICAgICAgPyBmYWxzZVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBjYW5FZGl0T2JqZWN0O1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLmdyb3VwRmllbGRzID0gdGhpcy5jb252ZXJ0QWRkcmVzc0ZpZWxkcyhcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnRyb2xGaWVsZCxcbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWVsZC5Hcm91cEZpZWxkcyxcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhbkVkaXRHcm91cE9iamVjdFxuICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBBZGRyZXNzRmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuSW5kaWNhdG9yczoge1xuICAgICAgICAgICAgICAgICAgICAvLyBvcHRpb25zWyd0eXBlJ10gPSAnaW5kaWNhdG9ycyc7IC8vIE5vdCBuZWVkZWQgdGhpcyBpcyBQZXBJbmRpY2F0b3JzRmllbGQuXG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcEluZGljYXRvcnNGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5JbnRlcm5hbFBhZ2U6IHtcbiAgICAgICAgICAgICAgICAgICAgaWYgKHRoaXMuaXNNYXRyaXhGaWVsZChjb250cm9sRmllbGQuQXBpTmFtZSkpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnMucm93U3BhbiA9IGNvbnRyb2xGaWVsZC5MYXlvdXQuSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5vYmplY3RJZCA9IG9iamVjdElkO1xuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5wYXJlbnRJZCA9IHBhcmVudElkO1xuICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5zZWFyY2hDb2RlID0gc2VhcmNoQ29kZTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwSW50ZXJuYWxQYWdlRmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBOb3Qgc3VwcG9ydGVkXG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5SZWxhdGVkT2JqZWN0c0NhcmRzOiB7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMucm93U3BhbiA9IGNvbnRyb2xGaWVsZC5MYXlvdXQuSGVpZ2h0O1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnNlYXJjaENvZGUgPSBzZWFyY2hDb2RlO1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnBhZ2VJbmZvID0gZGF0YUZpZWxkLlVJUGFnZUluZm87XG5cbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwSW50ZXJuYWxDYXJ1c2VsRmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuTGluazoge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAnbGluayc7XG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcExpbmtGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5JbnRlcm5hbExpbms6XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLkJ1dHRvbjoge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAnYnV0dG9uJztcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwSW50ZXJuYWxCdXR0b25GaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5BdHRhY2htZW50OiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIG9wdGlvbnMudHlwZSA9ICdhdHRhY2htZW50JztcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwQXR0YWNobWVudEZpZWxkKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLlNpZ25hdHVyZToge1xuICAgICAgICAgICAgICAgICAgICAvLyBvcHRpb25zLnR5cGUgPSAnc2lnbmF0dXJlJztcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwU2lnbmF0dXJlRmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuSW1hZ2U6XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLkltYWdlVVJMOiB7XG4gICAgICAgICAgICAgICAgICAgIC8vIG9wdGlvbnMudHlwZSA9ICdpbWFnZSc7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMubWVudUZpZWxkID1cbiAgICAgICAgICAgICAgICAgICAgICAgIG1lbnVGaWVsZCAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuZG9lc0ZpZWxkSGF2YUZsb2F0aW5nRmllbGQoY29udHJvbEZpZWxkLCBtZW51RmllbGQpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBtZW51RmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuaGFzQ2FtcGFpZ25GaWVsZCA9XG4gICAgICAgICAgICAgICAgICAgICAgICBoYXNDYW1wYWlnbkZpZWxkICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2VzRmllbGRIYXZhRmxvYXRpbmdGaWVsZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbEZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBoYXNDYW1wYWlnbkZpZWxkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gaGFzQ2FtcGFpZ25GaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogbnVsbDtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5pbmRpY2F0b3JzRmllbGQgPVxuICAgICAgICAgICAgICAgICAgICAgICAgaW5kaWNhdG9yc0ZpZWxkICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy5kb2VzRmllbGRIYXZhRmxvYXRpbmdGaWVsZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJvbEZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBpbmRpY2F0b3JzRmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyBpbmRpY2F0b3JzRmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IG51bGw7XG5cbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwSW1hZ2VGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5JbWFnZXM6IHtcbiAgICAgICAgICAgICAgICAgICAgLy8gb3B0aW9ucy50eXBlID0gJ2ltYWdlcyc7XG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcEltYWdlc0ZpZWxkKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLkVtYWlsOiB7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudHlwZSA9ICdlbWFpbCc7XG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcExpbmtGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5QaG9uZToge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAncGhvbmUnO1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBMaW5rRmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuRHVyYXRpb246IHtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy50eXBlID0gJ2R1cmF0aW9uJztcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwVGV4dGJveEZpZWxkKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLkRlZmF1bHQ6XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLlRleHRCb3g6XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLkxpbWl0ZWRMZW5ndGhUZXh0Qm94OlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5UZXh0SGVhZGVyOlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5DYWxjdWxhdGVkU3RyaW5nOlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5NYXBEYXRhU3RyaW5nOiB7XG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcFRleHRib3hGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5UZXh0QXJlYToge1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBUZXh0YXJlYUZpZWxkKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuUmljaFRleHRIVE1MOiB7XG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcFJpY2hIdG1sVGV4dGFyZWFGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5EYXRlOlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5MaW1pdGVkRGF0ZTpcbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuQ2FsY3VsYXRlZERhdGU6XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLkRhdGVBbmRUaW1lOiB7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudHlwZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmllbGQuRmllbGRUeXBlID09PSBGSUVMRF9UWVBFLkRhdGVBbmRUaW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAnZGF0ZXRpbWUnXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAnZGF0ZSc7XG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcERhdGVGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5OdW1iZXJJbnRlZ2VyOlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5DYWxjdWxhdGVkSW50OlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5NYXBEYXRhSW50OiB7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudHlwZSA9ICdpbnQnO1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBUZXh0Ym94RmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuUGVyY2VudGFnZToge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAncGVyY2VudGFnZSc7XG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcFRleHRib3hGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5DdXJyZW5jeToge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAnY3VycmVuY3knO1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBUZXh0Ym94RmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuTnVtYmVyUmVhbDpcbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuQ2FsY3VsYXRlZFJlYWw6XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLk1hcERhdGFSZWFsOlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5TdW06XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLlRvdGFsczoge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAncmVhbCc7XG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcFRleHRib3hGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5Cb29sZWFuOlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5DYWxjdWxhdGVkQm9vbDoge1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBDaGVja2JveEZpZWxkKG9wdGlvbnMpO1xuICAgICAgICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLkJvb2xlYW5UZXh0OiB7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudHlwZSA9ICdib29sZWFuVGV4dCc7XG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcENoZWNrYm94RmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuQ29tYm9Cb3g6XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLkVtcHR5Q29tYm9Cb3g6XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLk1hcERhdGFEcm9wRG93bjoge1xuICAgICAgICAgICAgICAgICAgICAvLyBvcHRpb25zLnR5cGUgPSAnc2VsZWN0JztcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwU2VsZWN0RmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuTXVsdGlUaWNrQm94OlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5NdWx0aVRpY2tCb3hUb0NvbWJvQm94OlxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5FbXB0eU11bHRpVGlja0JveDoge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAnbXVsdGknO1xuICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBTZWxlY3RGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5HdWlkUmVmZXJlbmNlVHlwZToge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAncmVmZXJlbmNlJztcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5yZWZlcmVuY2VPYmplY3RUeXBlID0gZGF0YUZpZWxkLlJlZmVyZW5jZU9iamVjdFR5cGU7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMucmVmZXJlbmNlT2JqZWN0U3ViVHlwZSA9XG4gICAgICAgICAgICAgICAgICAgICAgICBkYXRhRmllbGQuUmVmZXJlbmNlT2JqZWN0U3ViVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgb3B0aW9ucy5yZWZlcmVuY2VPYmplY3RJbnRlcm5hbFR5cGUgPVxuICAgICAgICAgICAgICAgICAgICAgICAgZGF0YUZpZWxkLlJlZmVyZW5jZU9iamVjdEludGVybmFsVHlwZTtcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwSW50ZXJuYWxCdXR0b25GaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5MaXN0T2ZPYmplY3RzOiB7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudHlwZSA9ICdsaXN0b2ZvYmplY3RzJztcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwSW50ZXJuYWxCdXR0b25GaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIGNhc2UgRklFTERfVFlQRS5TZXBhcmF0b3I6IHtcbiAgICAgICAgICAgICAgICAgICAgY3VzdG9tRmllbGQgPSBuZXcgUGVwU2VwYXJhdG9yRmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAvKlxuICAgICAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuSW1hZ2VzOiByZXR1cm4gdGhhdC5maWVsZCh2YWx1ZSk7XG4gICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuTnVtYmVyUmVhbFF1YW50aXR5U2VsZWN0b3I6XG4gICAgICAgICAgICAgICAgY2FzZSBGSUVMRF9UWVBFLk51bWJlckludGVnZXJRdWFudGl0eVNlbGVjdG9yOiB7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMudHlwZSA9ICdxcyc7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMuYWxsb3dEZWNpbWFsID1cbiAgICAgICAgICAgICAgICAgICAgICAgIGRhdGFGaWVsZC5GaWVsZFR5cGUgPT09XG4gICAgICAgICAgICAgICAgICAgICAgICBGSUVMRF9UWVBFLk51bWJlclJlYWxRdWFudGl0eVNlbGVjdG9yO1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLm5vdGlmaWNhdGlvbkluZm8gPSBkYXRhRmllbGQuTm90aWZpY2F0aW9uSW5mbztcblxuICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWVsZCA9IG5ldyBQZXBRdWFudGl0eVNlbGVjdG9yRmllbGQob3B0aW9ucyk7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBjYXNlIEZJRUxEX1RZUEUuUGFja2FnZToge1xuICAgICAgICAgICAgICAgICAgICBvcHRpb25zLnR5cGUgPSAncGFja2FnZUJ1dHRvbic7XG4gICAgICAgICAgICAgICAgICAgIG9wdGlvbnMubm90aWZpY2F0aW9uSW5mbyA9IGRhdGFGaWVsZC5Ob3RpZmljYXRpb25JbmZvO1xuXG4gICAgICAgICAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcFF1YW50aXR5U2VsZWN0b3JGaWVsZChvcHRpb25zKTtcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKCFjdXN0b21GaWVsZCkge1xuICAgICAgICAgICAgb3B0aW9ucy5sYWJlbCA9IGNvbnRyb2xGaWVsZC5BcGlOYW1lICsgJyBpcyBub3Qgc3VwcG9ydGVkISEhJztcbiAgICAgICAgICAgIGN1c3RvbUZpZWxkID0gbmV3IFBlcFNlcGFyYXRvckZpZWxkKG9wdGlvbnMpO1xuICAgICAgICB9XG5cbiAgICAgICAgcmV0dXJuIGN1c3RvbUZpZWxkO1xuICAgIH1cblxuICAgIGdldEZpZWxkRm9ybWF0dGVkVmFsdWUoZmllbGQ6IFBlcEZpZWxkQmFzZSk6IHN0cmluZyB7XG4gICAgICAgIGxldCBmaWVsZEZvcm1hdHRlZFZhbHVlID0gZmllbGQuZm9ybWF0dGVkVmFsdWU7XG5cbiAgICAgICAgLy8gRml4IGZvciB0aGUgY3VzdG9tIGNoZWNrIGJveCBjb21wb25lbnQuXG4gICAgICAgIGlmIChmaWVsZC5jb250cm9sVHlwZSA9PT0gJ2NoZWNrYm94Jykge1xuICAgICAgICAgICAgZmllbGRGb3JtYXR0ZWRWYWx1ZSA9IGZpZWxkRm9ybWF0dGVkVmFsdWUgPT09ICd0cnVlJztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEZpeCBmb3IgdGhlIGN1c3RvbSBidXR0b24gY29tcG9uZW50LlxuICAgICAgICBpZiAoZmllbGQuY29udHJvbFR5cGUgPT09ICdidXR0b24nKSB7XG4gICAgICAgICAgICBmaWVsZEZvcm1hdHRlZFZhbHVlID1cbiAgICAgICAgICAgICAgICBmaWVsZEZvcm1hdHRlZFZhbHVlID09PSAnMCcgPyAnJyA6IGZpZWxkRm9ybWF0dGVkVmFsdWU7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gZmllbGRGb3JtYXR0ZWRWYWx1ZTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHRvQ29udHJvbEdyb3VwKGZpZWxkczogUGVwRmllbGRCYXNlW10pOiBGb3JtR3JvdXAge1xuICAgICAgICBjb25zdCBncm91cCA9IHt9O1xuICAgICAgICBpZiAoZmllbGRzICYmIGZpZWxkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICBmaWVsZHMuZm9yRWFjaCgoZmllbGQpID0+IHtcbiAgICAgICAgICAgICAgICBpZiAoZmllbGQuZ3JvdXBGaWVsZHMgJiYgZmllbGQuZ3JvdXBGaWVsZHMubGVuZ3RoID4gMCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBzdWJHcm91cCA9IHt9O1xuXG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLmdyb3VwRmllbGRzLmZvckVhY2goKGdyb3VwRmllbGQpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cEZpZWxkLm1hbmRhdG9yeSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICFmaWVsZC5yZWFkb25seSAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICFmaWVsZC5kaXNhYmxlZFxuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViR3JvdXBbZ3JvdXBGaWVsZC5rZXldID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZ3JvdXBGaWVsZC5mb3JtYXR0ZWRWYWx1ZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLnJlYWRvbmx5IHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQuZGlzYWJsZWQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cEZpZWxkLmRpc2FibGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbVmFsaWRhdG9ycy5yZXF1aXJlZF0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgc3ViR3JvdXBbZ3JvdXBGaWVsZC5rZXldID0gW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZ3JvdXBGaWVsZC5mb3JtYXR0ZWRWYWx1ZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpc2FibGVkOlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLnJlYWRvbmx5IHx8XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmllbGQuZGlzYWJsZWQgfHxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBncm91cEZpZWxkLmRpc2FibGVkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBbVmFsaWRhdG9ycy5udWxsVmFsaWRhdG9yXSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBdO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICAgICAgICBncm91cFtmaWVsZC5rZXldID0gdGhpcy5mYi5ncm91cChzdWJHcm91cCk7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdmFsaWRhdG9ycyA9IGZpZWxkLmdldFZhbGlkYXRvcnMoKTtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZmllbGRGb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuZ2V0RmllbGRGb3JtYXR0ZWRWYWx1ZShcbiAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkXG4gICAgICAgICAgICAgICAgICAgICk7XG5cbiAgICAgICAgICAgICAgICAgICAgZ3JvdXBbZmllbGQua2V5XSA9IFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogZmllbGRGb3JtYXR0ZWRWYWx1ZSB8fCAnJyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkaXNhYmxlZDogZmllbGQuZGlzYWJsZWQsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdmFsaWRhdG9ycyxcbiAgICAgICAgICAgICAgICAgICAgXTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB0aGlzLmZiLmdyb3VwKGdyb3VwKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIGNyZWF0ZUJhc2VGaWVsZCh1aUNvbnRyb2xGaWVsZDogVUlDb250cm9sRmllbGQsIGRhdGFGaWVsZDogYW55KSB7XG4gICAgICAgIGNvbnN0IGN1c3RvbUZpZWxkOiBQZXBGaWVsZEJhc2UgPSB0aGlzLmNvbnZlcnRUb0N1c3RvbUZpZWxkKFxuICAgICAgICAgICAgdWlDb250cm9sRmllbGQsXG4gICAgICAgICAgICBkYXRhRmllbGQsXG4gICAgICAgICAgICB0aGlzLmNhbkVkaXRPYmplY3QsXG4gICAgICAgICAgICB0aGlzLm1lbnVEYXRhRmllbGQsXG4gICAgICAgICAgICB0aGlzLmhhc0NhbXBhaWduRGF0YUZpZWxkLFxuICAgICAgICAgICAgdGhpcy5pbmRpY2F0b3JzRGF0YUZpZWxkLFxuICAgICAgICAgICAgdGhpcy5vYmplY3RJZCxcbiAgICAgICAgICAgIHRoaXMucGFyZW50SWQsXG4gICAgICAgICAgICB0aGlzLnNlYXJjaENvZGVcbiAgICAgICAgKTtcblxuICAgICAgICByZXR1cm4gY3VzdG9tRmllbGQ7XG4gICAgfVxuXG4gICAgcHVibGljIHNob3dGb3JtVmFsaWRhdGlvbk1lc3NhZ2UoKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IGZpZWxkczogUGVwRmllbGRCYXNlW10gPSB0aGlzLmZpZWxkcztcbiAgICAgICAgbGV0IGVtcHR5TWFuZGF0b3J5RmllbGRzTXNnID0gJyc7XG4gICAgICAgIGxldCBub3RWYWxpZEZpZWxkc01zZyA9ICcnO1xuXG4gICAgICAgIC8vIGZvciAobGV0IGk6IG51bWJlciA9IDA7IGkgPCBmaWVsZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgLy8gICAgIGxldCBmaWVsZCA9IGZpZWxkc1tpXTtcbiAgICAgICAgZm9yIChjb25zdCBmaWVsZCBvZiBmaWVsZHMpIHtcbiAgICAgICAgICAgIGNvbnN0IGZvcm1Db250cm9sID0gdGhpcy5mb3JtICYmIHRoaXMuZm9ybS5nZXQoZmllbGQua2V5KTtcblxuICAgICAgICAgICAgaWYgKGZvcm1Db250cm9sKSB7XG4gICAgICAgICAgICAgICAgLy8gTWFuZGF0b3J5IGlzIGVtcHR5LlxuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgZmllbGQubWFuZGF0b3J5ICYmXG4gICAgICAgICAgICAgICAgICAgIGZvcm1Db250cm9sLnZhbHVlLnRvU3RyaW5nKCkudHJpbSgpLmxlbmd0aCA9PT0gMFxuICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICBlbXB0eU1hbmRhdG9yeUZpZWxkc01zZyArPVxuICAgICAgICAgICAgICAgICAgICAgICAgJzxsaT48c21hbGw+JyArIGZpZWxkLmxhYmVsICsgJzwvc21hbGw+PC9saT4nO1xuICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAoIWZpZWxkLmRpc2FibGVkICYmICFmb3JtQ29udHJvbC52YWxpZCkge1xuICAgICAgICAgICAgICAgICAgICBub3RWYWxpZEZpZWxkc01zZyArPVxuICAgICAgICAgICAgICAgICAgICAgICAgJzxsaT48c21hbGw+JyArIGZpZWxkLmxhYmVsICsgJzwvc21hbGw+PC9saT4nO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCB0aGUgaGVhZGVyIG1lc3NhZ2Ugb2YgdGhlIGVtcHR5IG1hbmRhdG9yeSBmaWVsZHNcbiAgICAgICAgaWYgKGVtcHR5TWFuZGF0b3J5RmllbGRzTXNnLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIGVtcHR5TWFuZGF0b3J5RmllbGRzTXNnID1cbiAgICAgICAgICAgICAgICAnPGRpdj4nICtcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdNRVNTQUdFUy5FUlJPUl9NQU5EQVRPUllfRklFTERTJykgK1xuICAgICAgICAgICAgICAgIFwiPC9kaXY+PHVsIHN0eWxlPSdwYWRkaW5nOiAwIDIwcHg7Jz5cIiArXG4gICAgICAgICAgICAgICAgZW1wdHlNYW5kYXRvcnlGaWVsZHNNc2cgK1xuICAgICAgICAgICAgICAgICc8L3VsPjxici8+JztcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIEFkZCB0aGUgaGVhZGVyIG1lc3NhZ2Ugb2YgdGhlIGVtcHR5IG1hbmRhdG9yeSBmaWVsZHNcbiAgICAgICAgaWYgKG5vdFZhbGlkRmllbGRzTXNnLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIG5vdFZhbGlkRmllbGRzTXNnID1cbiAgICAgICAgICAgICAgICAnPGRpdj4nICtcbiAgICAgICAgICAgICAgICB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdNRVNTQUdFUy5FUlJPUl9JTlZBTElEX0ZJRUxEUycpICtcbiAgICAgICAgICAgICAgICBcIjwvZGl2Pjx1bCBzdHlsZT0ncGFkZGluZzogMCAyMHB4Oyc+XCIgK1xuICAgICAgICAgICAgICAgIG5vdFZhbGlkRmllbGRzTXNnICtcbiAgICAgICAgICAgICAgICAnPC91bD4nO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgdGl0bGUgPSB0aGlzLnRyYW5zbGF0ZS5pbnN0YW50KCdNRVNTQUdFUy5USVRMRV9OT1RJQ0UnKTtcbiAgICAgICAgY29uc3QgZGF0YSA9IG5ldyBQZXBEaWFsb2dEYXRhKHtcbiAgICAgICAgICAgIHRpdGxlLFxuICAgICAgICAgICAgY29udGVudDogZW1wdHlNYW5kYXRvcnlGaWVsZHNNc2cgKyBub3RWYWxpZEZpZWxkc01zZyxcbiAgICAgICAgfSk7XG4gICAgICAgIHRoaXMuZGlhbG9nU2VydmljZS5vcGVuRGVmYXVsdERpYWxvZyhkYXRhKTtcbiAgICB9XG5cbiAgICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICAgICAgY29uc3QgdGhlbWVWYXJzID0gdGhpcy5jdXN0b21pemF0aW9uU2VydmljZS5nZXRUaGVtZVZhcmlhYmxlcygpO1xuICAgICAgICAvLyBjb252ZXJ0IHJlbSB0byBwaXhlbFxuICAgICAgICBjb25zdCBSZW1Ub1BpeGVsID0gMTY7XG4gICAgICAgIHRoaXMuZm9ybUd1dHRlclNpemUgPVxuICAgICAgICAgICAgdGhpcy5jdXN0b21pemF0aW9uU2VydmljZS5nZXROdW1iZXJUaGVtZVZhcmlhYmxlKFxuICAgICAgICAgICAgICAgIHRoZW1lVmFycyxcbiAgICAgICAgICAgICAgICBQZXBDdXN0b21pemF0aW9uU2VydmljZS5GT1JNX1NQQUNFSU5HX0tFWVxuICAgICAgICAgICAgKSAqIFJlbVRvUGl4ZWw7XG4gICAgICAgIHRoaXMuY2FyZEd1dHRlclNpemUgPVxuICAgICAgICAgICAgdGhpcy5jdXN0b21pemF0aW9uU2VydmljZS5nZXROdW1iZXJUaGVtZVZhcmlhYmxlKFxuICAgICAgICAgICAgICAgIHRoZW1lVmFycyxcbiAgICAgICAgICAgICAgICBQZXBDdXN0b21pemF0aW9uU2VydmljZS5DQVJEX1NQQUNFSU5HX0tFWVxuICAgICAgICAgICAgKSAqIFJlbVRvUGl4ZWw7XG4gICAgfVxuXG4gICAgbmdEb0NoZWNrKCk6IHZvaWQge1xuICAgICAgICBjb25zdCBjaGFuZ2VzID0gdGhpcy5kaWZmZXIuZGlmZih0aGlzLmRhdGEpOyAvLyBjaGVjayBmb3IgY2hhbmdlc1xuICAgICAgICBpZiAoY2hhbmdlcykge1xuICAgICAgICAgICAgdGhpcy51cGRhdGVGb3JtKCk7XG4gICAgICAgICAgICB0aGlzLmNoZWNrRm9yQ2hhbmdlcyA9IG5ldyBEYXRlKCk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBuZ09uQ2hhbmdlcyhjaGFuZ2VzKTogdm9pZCB7XG4gICAgICAgIC8vIGlmIChjaGFuZ2VzLmRhdGEgJiYgY2hhbmdlcy5kYXRhLmN1cnJlbnRWYWx1ZSkge1xuICAgICAgICAvLyAgICAgLy8gTG9hZCBjaGFuZ2VzXG4gICAgICAgIC8vICAgICBpZiAoIXRoaXMuc2hvdWxkUmVsb2FkRm9ybSAmJiBjaGFuZ2VzLmRhdGEucHJldmlvdXNWYWx1ZSkge1xuICAgICAgICAvLyAgICAgICAgIHRoaXMuZGF0YSA9IGNoYW5nZXMuZGF0YS5jdXJyZW50VmFsdWU7XG4gICAgICAgIC8vICAgICAgICAgdGhpcy51cGRhdGVGb3JtKCk7XG4gICAgICAgIC8vICAgICB9IGVsc2Uge1xuICAgICAgICAvLyAgICAgICAgIHRoaXMuX3Nob3VsZFJlbG9hZEZvcm0gPSBmYWxzZTtcbiAgICAgICAgLy8gICAgICAgICB0aGlzLmluaXRGb3JtKCk7XG4gICAgICAgIC8vICAgICB9XG4gICAgICAgIC8vIH1cbiAgICAgICAgLy8gaWYgKHRoaXMuc2hvdWxkUmVsb2FkRm9ybSB8fCAhY2hhbmdlcz8uZGF0YT8ucHJldmlvdXNWYWx1ZSkge1xuICAgICAgICAvLyAgICAgdGhpcy5fc2hvdWxkUmVsb2FkRm9ybSA9IGZhbHNlO1xuICAgICAgICAvLyAgICAgdGhpcy5pbml0Rm9ybSgpO1xuICAgICAgICAvLyAgICAgdGhpcy5jaGVja0ZvckNoYW5nZXMgPSBuZXcgRGF0ZSgpO1xuICAgICAgICAvLyB9XG4gICAgfVxuXG4gICAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgICAgIC8vXG4gICAgfVxuXG4gICAgZ2V0VWlDb250cm9sRmllbGRzKCk6IEFycmF5PFVJQ29udHJvbEZpZWxkPiB7XG4gICAgICAgIHJldHVybiB0aGlzLmxheW91dCA/IHRoaXMubGF5b3V0LkNvbnRyb2xGaWVsZHMgOiBbXTtcbiAgICB9XG5cbiAgICBpbml0RmllbGRzU3RydWN0dXJlKGZpZWxkczogUGVwRmllbGRCYXNlW10sIG1heFJvdzogbnVtYmVyKTogdm9pZCB7XG4gICAgICAgIGNvbnN0IHRoZW1lVmFycyA9IHRoaXMuY3VzdG9taXphdGlvblNlcnZpY2UuZ2V0VGhlbWVWYXJpYWJsZXMoKTtcblxuICAgICAgICAvLyBTZXQgZm9ybSByb3cgaGVpZ2h0LlxuICAgICAgICBpZiAodGhpcy5sYXlvdXRUeXBlID09PSAnY2FyZCcpIHtcbiAgICAgICAgICAgIGNvbnN0IGNhcmRGaWVsZEhlaWdodCA9IHRoaXMuY3VzdG9taXphdGlvblNlcnZpY2UuZ2V0TnVtYmVyVGhlbWVWYXJpYWJsZShcbiAgICAgICAgICAgICAgICB0aGVtZVZhcnMsXG4gICAgICAgICAgICAgICAgUGVwQ3VzdG9taXphdGlvblNlcnZpY2UuQ0FSRF9GSUVMRF9IRUlHSFRfS0VZXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5yb3dIZWlnaHQgPSBjYXJkRmllbGRIZWlnaHQ7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBjb25zdCByb3dGaWVsZEhlaWdodCA9IHRoaXMuY3VzdG9taXphdGlvblNlcnZpY2UuZ2V0TnVtYmVyVGhlbWVWYXJpYWJsZShcbiAgICAgICAgICAgICAgICB0aGVtZVZhcnMsXG4gICAgICAgICAgICAgICAgUGVwQ3VzdG9taXphdGlvblNlcnZpY2UuRk9STV9GSUVMRF9IRUlHSFRfS0VZXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgY29uc3Qgcm93RmllbGRUaXRsZUhlaWdodCA9IHRoaXMuY3VzdG9taXphdGlvblNlcnZpY2UuZ2V0TnVtYmVyVGhlbWVWYXJpYWJsZShcbiAgICAgICAgICAgICAgICB0aGVtZVZhcnMsXG4gICAgICAgICAgICAgICAgUGVwQ3VzdG9taXphdGlvblNlcnZpY2UuRk9STV9GSUVMRF9USVRMRV9IRUlHSFRfS0VZXG4gICAgICAgICAgICApO1xuICAgICAgICAgICAgdGhpcy5yb3dIZWlnaHQgPSByb3dGaWVsZEhlaWdodCArIHJvd0ZpZWxkVGl0bGVIZWlnaHQ7XG4gICAgICAgIH1cblxuICAgICAgICAvLyBDcmVhdGUgdGhlIGZpZWxkcyBzdHJ1Y3R1cmUgKHRoZSBmaWVsZHMgbXVzdCBiZSBzb3J0ZWQhISEpLlxuICAgICAgICBpZiAoZmllbGRzLmxlbmd0aCA+IDApIHtcbiAgICAgICAgICAgIC8vIEluaXQgdGhlIGxheW91dC5cbiAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAvLyB0aGlzLmxheW91dFR5cGUgPT09ICdmb3JtJyB8fFxuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VHlwZSA9PT0gJ3RhYmxlJ1xuICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5maWVsZHMgPSBmaWVsZHM7XG4gICAgICAgICAgICAgICAgdGhpcy5fZmllbGRzU3ViamVjdC5uZXh0KGZpZWxkcyk7XG5cbiAgICAgICAgICAgICAgICB0aGlzLnJvd3MgPSBbXTtcblxuICAgICAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDw9IG1heFJvdzsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMucm93c1tpXSA9IFtdO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIC8vIGZvciAobGV0IGkgPSAwOyBpIDwgZmllbGRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgLy8gY29uc3QgZmllbGQgPSBmaWVsZHNbaV1cbiAgICAgICAgICAgICAgICBmb3IgKGNvbnN0IGZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd3NbZmllbGQucm93XS5wdXNoKGZpZWxkKTtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIGNvbnN0IGRvZXNmaWVsZEV4aXN0SW46IGJvb2xlYW5bXVtdID0gbmV3IEFycmF5KG1heFJvdyk7XG5cbiAgICAgICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGRvZXNmaWVsZEV4aXN0SW4ubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICAgICAgZG9lc2ZpZWxkRXhpc3RJbltpXSA9IG5ldyBBcnJheSh0aGlzLmNvbHVtbnMpO1xuXG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZG9lc2ZpZWxkRXhpc3RJbltpXS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgZG9lc2ZpZWxkRXhpc3RJbltpXVtqXSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgLy8gUnVuIGluIHNxdWVyZSAocm93IC0gY29sc3BhbiwgY29sIC0gcm93c3BhbikgYW5kIHB1dCB0cnVlIHdoZXJlIGl0IHNob3VsZC5cbiAgICAgICAgICAgICAgICAvLyBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgZmllbGRzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAgICAgICAgIC8vICAgICBjb25zdCBjdXJyZW50RmllbGQgPSBmaWVsZHNbaW5kZXhdO1xuICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY3VycmVudEZpZWxkIG9mIGZpZWxkcykge1xuICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudEZpZWxkLnJvd1NwYW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBmb3IgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGxldCByb3c6IG51bWJlciA9IGN1cnJlbnRGaWVsZC5yb3c7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcm93IDwgY3VycmVudEZpZWxkLnJvdyArIGN1cnJlbnRGaWVsZC5yb3dTcGFuO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJvdysrXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoY3VycmVudEZpZWxkLmNvbFNwYW4gPiAxKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29sOiBudW1iZXIgPSBjdXJyZW50RmllbGQuY29sO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sIDxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGaWVsZC5jb2wgKyBjdXJyZW50RmllbGQuY29sU3BhbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbCsrXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvZXNmaWVsZEV4aXN0SW4ubGVuZ3RoID4gcm93ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9lc2ZpZWxkRXhpc3RJblswXS5sZW5ndGggPiBjb2xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvZXNmaWVsZEV4aXN0SW5bcm93XVtjb2xdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRvZXNmaWVsZEV4aXN0SW4ubGVuZ3RoID4gcm93ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2VzZmllbGRFeGlzdEluWzBdLmxlbmd0aCA+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50RmllbGQuY29sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9lc2ZpZWxkRXhpc3RJbltyb3ddW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGaWVsZC5jb2xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIF0gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2UgaWYgKGN1cnJlbnRGaWVsZC5jb2xTcGFuID4gMSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBsZXQgY29sOiBudW1iZXIgPSBjdXJyZW50RmllbGQuY29sO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbCA8IGN1cnJlbnRGaWVsZC5jb2wgKyBjdXJyZW50RmllbGQuY29sU3BhbjtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb2wrK1xuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2VzZmllbGRFeGlzdEluLmxlbmd0aCA+IGN1cnJlbnRGaWVsZC5yb3cgJiZcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9lc2ZpZWxkRXhpc3RJblswXS5sZW5ndGggPiBjb2xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9lc2ZpZWxkRXhpc3RJbltjdXJyZW50RmllbGQucm93XVtjb2xdID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9lc2ZpZWxkRXhpc3RJbi5sZW5ndGggPiBjdXJyZW50RmllbGQucm93ICYmXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZG9lc2ZpZWxkRXhpc3RJblswXS5sZW5ndGggPiBjdXJyZW50RmllbGQuY29sXG4gICAgICAgICAgICAgICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBkb2VzZmllbGRFeGlzdEluW2N1cnJlbnRGaWVsZC5yb3ddW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50RmllbGQuY29sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgXSA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBDcmVhdGUgZW1wdHkgZmllbGRzIHdoZXJlIGRvZXNmaWVsZEV4aXN0SW4gaXMgZmFsc2UgKEZvciB0aGUgbWQtZ3JpZC1saXN0IFVJIENvbXBvbmVudCkuXG4gICAgICAgICAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBkb2VzZmllbGRFeGlzdEluLmxlbmd0aDsgaSsrKSB7XG4gICAgICAgICAgICAgICAgICAgIGZvciAobGV0IGogPSAwOyBqIDwgZG9lc2ZpZWxkRXhpc3RJbltpXS5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgaWYgKCFkb2VzZmllbGRFeGlzdEluW2ldW2pdKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gQ3JlYXRlIGVtcHR5IGZpZWxkIGFuZCBhZGQgaXQgdG8gdGhlIGZpZWxkcyBsaXN0LlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkcy5wdXNoKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgUGVwUGxhY2Vob2xkZXJGaWVsZCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBrZXk6IGkgKyAnXycgKyBqLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbGFiZWw6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGxhY2Vob2xkZXI6ICcnLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcmVhZG9ubHk6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZGlzYWJsZWQ6IGZhbHNlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgaGlkZGVuOiBmYWxzZSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG1hbmRhdG9yeTogZmFsc2UsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB2YWx1ZTogJycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3JtYXR0ZWRWYWx1ZTogJycsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3c6IGksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICByb3dTcGFuOiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sOiBqLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY29sU3BhbjogMSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yZGVyOiAxLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAvLyBTb3J0IHRoZSBmaWVsZHMgYWdhaW4uXG4gICAgICAgICAgICAgICAgdGhpcy5maWVsZHMgPSBmaWVsZHMuc29ydCgoZjEsIGYyKSA9PlxuICAgICAgICAgICAgICAgICAgICBmMS5yb3cgPiBmMi5yb3dcbiAgICAgICAgICAgICAgICAgICAgICAgID8gMVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBmMS5yb3cgPCBmMi5yb3dcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IC0xXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBmMS5jb2wgPiBmMi5jb2xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgPyAxXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIDogZjEuY29sIDwgZjIuY29sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IC0xXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICA6IDBcbiAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgIHRoaXMuX2ZpZWxkc1N1YmplY3QubmV4dChmaWVsZHMpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxuXG4gICAgc2V0Rm9ybShpc0ZvclVwZGF0ZSA9IGZhbHNlKTogdm9pZCB7XG4gICAgICAgIGxldCBhbGxGaWVsZHNBcmVSZWFkT25seSA9IHRydWU7XG5cbiAgICAgICAgaWYgKCFpc0ZvclVwZGF0ZSkge1xuICAgICAgICAgICAgY29uc3QgZmllbGRzID0gW107XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGN1cnJlbnRGaWVsZCBvZiB0aGlzLmZpZWxkcykge1xuICAgICAgICAgICAgICAgIC8vIEFkZCBhbGwgZmllbGRzIGV4Y2VwdCAnaW50ZXJuYWxQYWdlJyAoZm9yIGNoaWxkcmVuKS5cbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudEZpZWxkLmNvbnRyb2xUeXBlICE9PSAnaW50ZXJuYWxQYWdlJykge1xuICAgICAgICAgICAgICAgICAgICBmaWVsZHMucHVzaChjdXJyZW50RmllbGQpO1xuICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgIGlmICghY3VycmVudEZpZWxkLnJlYWRvbmx5KSB7XG4gICAgICAgICAgICAgICAgICAgIGFsbEZpZWxkc0FyZVJlYWRPbmx5ID0gZmFsc2U7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICB0aGlzLmZvcm0gPSB0aGlzLnRvQ29udHJvbEdyb3VwKGZpZWxkcyk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBVcGRhdGUgZm9ybSB2YWx1ZXMgaWYgY2hhbmdlZCBieSBjYWxjdWxhdGVkIGZpZWxkcy5cbiAgICAgICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgdGhpcy5maWVsZHMubGVuZ3RoOyBpKyspIHtcbiAgICAgICAgICAgICAgICBsZXQgY3VycmVudEZpZWxkID0gdGhpcy5maWVsZHNbaV07XG5cbiAgICAgICAgICAgICAgICBpZiAoY3VycmVudEZpZWxkLmNvbnRyb2xUeXBlID09PSAnaW50ZXJuYWxDYXJ1c2VsJykge1xuICAgICAgICAgICAgICAgICAgICAvLyBIYWNrIHRvIG92ZXJyaWRlICh1cGRhdGUpIHRoZSBmaWVsZC5cbiAgICAgICAgICAgICAgICAgICAgY29uc3QgdWlDb250cm9sRmllbGQgPSB0aGlzLmdldFVpQ29udHJvbEZpZWxkcygpLmZpbmQoY2YgPT4gY2YuQXBpTmFtZSA9PT0gY3VycmVudEZpZWxkLmtleSk7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGRhdGFGaWVsZCA9IHRoaXMuZGF0YS5GaWVsZHMuZmluZChkZiA9PiBkZi5BcGlOYW1lID09PSBjdXJyZW50RmllbGQua2V5KTtcbiAgICAgICAgICAgICAgICAgICAgY3VycmVudEZpZWxkID0gdGhpcy5jcmVhdGVCYXNlRmllbGQodWlDb250cm9sRmllbGQsIGRhdGFGaWVsZCk7XG4gICAgICAgICAgICAgICAgICAgIHRoaXMuX2ZpZWxkc1N1YmplY3QudmFsdWVbaV0gPSBjdXJyZW50RmllbGQ7XG4gICAgICAgICAgICAgICAgfSBlbHNlIGlmIChjdXJyZW50RmllbGQuY29udHJvbFR5cGUgIT09ICdpbnRlcm5hbFBhZ2UnKSB7XG4gICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRGaWVsZC5ncm91cEZpZWxkcyAmJlxuICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEZpZWxkLmdyb3VwRmllbGRzLmxlbmd0aCA+IDBcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgKGxldCBqID0gMDsgaiA8IGN1cnJlbnRGaWVsZC5ncm91cEZpZWxkcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gICAgIGxldCBjdXJyZW50R3JvdXBGaWVsZCA9IGN1cnJlbnRGaWVsZC5ncm91cEZpZWxkc1tqXTtcbiAgICAgICAgICAgICAgICAgICAgICAgIGZvciAoY29uc3QgY3VycmVudEdyb3VwRmllbGQgb2YgY3VycmVudEZpZWxkLmdyb3VwRmllbGRzKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmllbGRGb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuZ2V0RmllbGRGb3JtYXR0ZWRWYWx1ZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEdyb3VwRmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMuY3VzdG9taXphdGlvblNlcnZpY2UudXBkYXRlRm9ybUZpZWxkKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGN1cnJlbnRHcm91cEZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBmaWVsZEZvcm1hdHRlZFZhbHVlLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50RmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgZmllbGRGb3JtYXR0ZWRWYWx1ZSA9IHRoaXMuZ2V0RmllbGRGb3JtYXR0ZWRWYWx1ZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50RmllbGRcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0aGlzLmZvcm0uY29udHJvbHNbY3VycmVudEZpZWxkLmtleV0uc2V0VmFsdWUoZmllbGRGb3JtYXR0ZWRWYWx1ZSk7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmN1c3RvbWl6YXRpb25TZXJ2aWNlLnVwZGF0ZUZvcm1GaWVsZChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmZvcm0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY3VycmVudEZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkRm9ybWF0dGVkVmFsdWVcbiAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICBpZiAoIWN1cnJlbnRGaWVsZC5yZWFkb25seSkge1xuICAgICAgICAgICAgICAgICAgICBhbGxGaWVsZHNBcmVSZWFkT25seSA9IGZhbHNlO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuXG4gICAgICAgIGxldCBpc0Zvcm1WYWxpZCA9IHRoaXMuZm9ybT8udmFsaWQ7XG5cbiAgICAgICAgLy8gQ2hhbmdlIHZhbGlkYXRpb24gdG8gdHJ1ZSBpZiBhbGwgZmllbGRzIGFyZSByZWFkIG9ubHkuXG4gICAgICAgIGlmICghaXNGb3JtVmFsaWQgJiYgYWxsRmllbGRzQXJlUmVhZE9ubHkpIHtcbiAgICAgICAgICAgIGlzRm9ybVZhbGlkID0gdHJ1ZTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMub25Gb3JtVmFsaWRhdGlvbkNoYW5nZWQoaXNGb3JtVmFsaWQpO1xuXG4gICAgICAgIC8vIFNldCBpdCB0byBmYWxzZSB0byBlbmFibGUgYWxsIGZpZWxkcy5cbiAgICAgICAgaWYgKHRoaXMuaXNJbnRlcm5hbCAmJiB0aGlzLmlzTG9ja2VkKSB7XG4gICAgICAgICAgICB0aGlzLmlzTG9ja2VkID0gZmFsc2U7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBpbml0Rm9ybSgpOiB2b2lkIHtcbiAgICAgICAgaWYgKHRoaXMuZGF0YSAmJiB0aGlzLmRhdGEuRmllbGRzKSB7XG4gICAgICAgICAgICBjb25zdCBmaWVsZHM6IFBlcEZpZWxkQmFzZVtdID0gdGhpcy5jb252ZXJ0Q3VzdG9tRmllbGRzKFxuICAgICAgICAgICAgICAgIHRoaXMuZ2V0VWlDb250cm9sRmllbGRzKCksXG4gICAgICAgICAgICAgICAgdGhpcy5kYXRhLkZpZWxkc1xuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgY29uc3QgbWF4Um93ID0gTWF0aC5tYXgoXG4gICAgICAgICAgICAgICAgLi4uZmllbGRzLm1hcCgoZikgPT4ge1xuICAgICAgICAgICAgICAgICAgICByZXR1cm4gZi5yb3cgKyBmLnJvd1NwYW47XG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgICB0aGlzLmNvbHVtbnMgPSBNYXRoLm1heChcbiAgICAgICAgICAgICAgICAuLi5maWVsZHMubWFwKChmKSA9PiB7XG4gICAgICAgICAgICAgICAgICAgIHJldHVybiBmLmNvbCArIGYuY29sU3BhbjtcbiAgICAgICAgICAgICAgICB9KVxuICAgICAgICAgICAgKTtcblxuICAgICAgICAgICAgdGhpcy5pbml0RmllbGRzU3RydWN0dXJlKGZpZWxkcywgbWF4Um93KTtcbiAgICAgICAgICAgIHRoaXMuc2V0Rm9ybSgpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1cGRhdGVGaWVsZChcbiAgICAgICAgY3VzdG9tRmllbGQ6IFBlcEZpZWxkQmFzZSxcbiAgICAgICAgdXBkYXRlZEZpZWxkOiBPYmplY3RzRGF0YVJvd0NlbGxcbiAgICApOiB2b2lkIHtcbiAgICAgICAgY29uc3Qgb3B0aW9uczogYW55ID0ge1xuICAgICAgICAgICAgZGlzYWJsZWQ6ICF1cGRhdGVkRmllbGQuRW5hYmxlZCB8fCAhdGhpcy5jYW5FZGl0T2JqZWN0LFxuICAgICAgICAgICAgcmVhZG9ubHk6ICF1cGRhdGVkRmllbGQuRW5hYmxlZCB8fCAhdGhpcy5jYW5FZGl0T2JqZWN0LFxuICAgICAgICAgICAgdmlzaWJsZTogdXBkYXRlZEZpZWxkLlZpc2libGUsXG4gICAgICAgICAgICB2YWx1ZTogdXBkYXRlZEZpZWxkLlZhbHVlLFxuICAgICAgICAgICAgYWRkaXRpb25hbFZhbHVlOiB1cGRhdGVkRmllbGQuQWRkaXRpb25hbFZhbHVlLFxuICAgICAgICAgICAgZm9ybWF0dGVkVmFsdWU6IHVwZGF0ZWRGaWVsZC5Gb3JtYXR0ZWRWYWx1ZSxcbiAgICAgICAgICAgIHRleHRDb2xvcjogdXBkYXRlZEZpZWxkLlRleHRDb2xvcixcbiAgICAgICAgfTtcblxuICAgICAgICBpZiAoY3VzdG9tRmllbGQgaW5zdGFuY2VvZiBQZXBRdWFudGl0eVNlbGVjdG9yRmllbGQpIHtcbiAgICAgICAgICAgIGNvbnN0IG5vdGlmaWNhdGlvbkluZm8gPSB1cGRhdGVkRmllbGQuTm90aWZpY2F0aW9uSW5mbztcbiAgICAgICAgICAgIG9wdGlvbnMubm90aWZpY2F0aW9uSW5mbyA9IG5vdGlmaWNhdGlvbkluZm87XG5cbiAgICAgICAgICAgIC8vIENoYW5nZSB0eXBlIGlmIGl0J3MgY2hhbmdlIChvbmx5IGZvciBhbGxvd0RlY2ltYWwpLlxuICAgICAgICAgICAgbGV0IGFsbG93RGVjaW1hbCA9IGZhbHNlO1xuICAgICAgICAgICAgaWYgKHVwZGF0ZWRGaWVsZC5GaWVsZFR5cGUgPT09IEZJRUxEX1RZUEUuTnVtYmVyUmVhbFF1YW50aXR5U2VsZWN0b3IgfHxcbiAgICAgICAgICAgICAgICB1cGRhdGVkRmllbGQuRmllbGRUeXBlID09PSBGSUVMRF9UWVBFLk51bWJlclJlYWwgfHxcbiAgICAgICAgICAgICAgICB1cGRhdGVkRmllbGQuRmllbGRUeXBlID09PSBGSUVMRF9UWVBFLk51bWJlclJlYWxGb3JNYXRyaXhcbiAgICAgICAgICAgICkge1xuICAgICAgICAgICAgICAgIGFsbG93RGVjaW1hbCA9IHRydWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIG9wdGlvbnMuYWxsb3dEZWNpbWFsID0gYWxsb3dEZWNpbWFsO1xuXG4gICAgICAgIH0gZWxzZSBpZiAoY3VzdG9tRmllbGQgaW5zdGFuY2VvZiBQZXBTZWxlY3RGaWVsZCkge1xuICAgICAgICAgICAgb3B0aW9ucy5vcHRpb25zID0gdGhpcy5jb252ZXJ0T3B0aW9uYWxWYWx1ZXMoXG4gICAgICAgICAgICAgICAgdXBkYXRlZEZpZWxkLk9wdGlvbmFsVmFsdWVzXG4gICAgICAgICAgICApO1xuXG4gICAgICAgICAgICBpZiAoIW9wdGlvbnMub3B0aW9ucyB8fCBvcHRpb25zLm9wdGlvbnMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICAgICAgb3B0aW9ucy5vcHRpb25zLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICBrZXk6IG9wdGlvbnMudmFsdWUsXG4gICAgICAgICAgICAgICAgICAgIHZhbHVlOiBvcHRpb25zLmZvcm1hdHRlZFZhbHVlLFxuICAgICAgICAgICAgICAgIH0pO1xuICAgICAgICAgICAgfVxuICAgICAgICB9IGVsc2UgaWYgKGN1c3RvbUZpZWxkIGluc3RhbmNlb2YgUGVwSW50ZXJuYWxDYXJ1c2VsRmllbGQpIHtcbiAgICAgICAgICAgIG9wdGlvbnMucGFnZUluZm8gPSB1cGRhdGVkRmllbGQuVUlQYWdlSW5mbztcbiAgICAgICAgfVxuXG4gICAgICAgIGN1c3RvbUZpZWxkLnVwZGF0ZShvcHRpb25zKTtcbiAgICB9XG5cbiAgICB1cGRhdGVGb3JtKCk6IHZvaWQge1xuICAgICAgICBpZiAodGhpcy5kYXRhICYmIHRoaXMuZGF0YS5GaWVsZHMpIHtcbiAgICAgICAgICAgIGZvciAoY29uc3QgY3VycmVudEZpZWxkIG9mIHRoaXMuZGF0YS5GaWVsZHMpIHtcbiAgICAgICAgICAgICAgICBjb25zdCBjdXN0b21GaWVsZCA9IHRoaXMuZmllbGRzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAgICAgKGYpID0+IGYua2V5ID09PSBjdXJyZW50RmllbGQuQXBpTmFtZVxuICAgICAgICAgICAgICAgIClbMF07XG4gICAgICAgICAgICAgICAgLy8gVXBkYXRlIGFsbCBmaWVsZHMgZXhjZXB0ICdpbnRlcm5hbFBhZ2UnIHR5cGUgKGZvciBjaGlsZHJlbikuXG4gICAgICAgICAgICAgICAgaWYgKGN1c3RvbUZpZWxkICYmIGN1c3RvbUZpZWxkLmNvbnRyb2xUeXBlICE9PSAnaW50ZXJuYWxQYWdlJykge1xuICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUZpZWxkKGN1c3RvbUZpZWxkLCBjdXJyZW50RmllbGQpO1xuXG4gICAgICAgICAgICAgICAgICAgIC8vIFVwZGF0ZSB0aGUgZ3JvdXAgZmllbGRzLlxuICAgICAgICAgICAgICAgICAgICBpZiAoXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXN0b21GaWVsZC5jb250cm9sVHlwZSA9PT0gJ2FkZHJlc3MnICYmXG4gICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50RmllbGQuR3JvdXBGaWVsZHNcbiAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAvLyBmb3IgKGxldCBqID0gMDsgaiA8IGN1cnJlbnRGaWVsZC5Hcm91cEZpZWxkcy5sZW5ndGg7IGorKykge1xuICAgICAgICAgICAgICAgICAgICAgICAgLy8gbGV0IGN1cnJlbnRHcm91cEZpZWxkID0gY3VycmVudEZpZWxkLkdyb3VwRmllbGRzW2pdO1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChjb25zdCBjdXJyZW50R3JvdXBGaWVsZCBvZiBjdXJyZW50RmllbGQuR3JvdXBGaWVsZHMpIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50R3JvdXBGaWVsZC5FbmFibGVkID0gIWN1cnJlbnRGaWVsZC5FbmFibGVkXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgID8gZmFsc2VcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgOiBjdXJyZW50R3JvdXBGaWVsZC5FbmFibGVkO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY3VzdG9tR3JvdXBGaWVsZCA9IGN1c3RvbUZpZWxkLmdyb3VwRmllbGRzLmZpbHRlcihcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKGYpID0+IGYua2V5ID09PSBjdXJyZW50R3JvdXBGaWVsZC5BcGlOYW1lXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgKVswXTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZUZpZWxkKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXN0b21Hcm91cEZpZWxkLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjdXJyZW50R3JvdXBGaWVsZFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMuc2V0Rm9ybSh0cnVlKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHB1YmxpYyBSZWxvYWRGb3JtKCk6IHZvaWQge1xuICAgICAgICB0aGlzLl9zaG91bGRSZWxvYWRGb3JtID0gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBvblN1Ym1pdCgpIHtcbiAgICAvLyAgICAgaWYgKHRoaXMuZm9ybS52YWxpZCkge1xuICAgIC8vICAgICAgICAgdGhpcy5wYXlMb2FkID0gSlNPTi5zdHJpbmdpZnkodGhpcy5mb3JtLnZhbHVlKTtcbiAgICAvLyAgICAgICAgIC8vdGhpcy5zdWJtaXR0ZWQuZW1pdCh0aGlzLmZvcm0udmFsdWUpO1xuICAgIC8vICAgICB9XG4gICAgLy8gfVxuXG4gICAgcHJpdmF0ZSBnZXRGb3JtQ29udHJvbEJ5SWQoa2V5OiBzdHJpbmcpOiBBYnN0cmFjdENvbnRyb2wgfCBudWxsIHtcbiAgICAgICAgbGV0IGZvcm1Db250cm9sID0gbnVsbDtcblxuICAgICAgICB0aGlzLmZpZWxkcy5mb3JFYWNoKChmaWVsZCkgPT4ge1xuICAgICAgICAgICAgaWYgKGZpZWxkLmtleSA9PT0ga2V5KSB7XG4gICAgICAgICAgICAgICAgZm9ybUNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KGZpZWxkLmtleSk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChmaWVsZC5ncm91cEZpZWxkcyAmJiBmaWVsZC5ncm91cEZpZWxkcy5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgICAgICAgZmllbGQuZ3JvdXBGaWVsZHMuZm9yRWFjaCgoZ3JvdXBGaWVsZCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICBpZiAoZ3JvdXBGaWVsZC5rZXkgPT09IGtleSkge1xuICAgICAgICAgICAgICAgICAgICAgICAgZm9ybUNvbnRyb2wgPSB0aGlzLmZvcm0uZ2V0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpZWxkLmtleSArICcuJyArIGdyb3VwRmllbGQua2V5XG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHJldHVybiBmb3JtQ29udHJvbDtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldFNwZWNpYWxGaWVsZHMoXG4gICAgICAgIGNvbnRyb2xGaWVsZHM6IEFycmF5PGFueT4sXG4gICAgICAgIGRhdGFGaWVsZHM6IEFycmF5PGFueT5cbiAgICApOiB2b2lkIHtcbiAgICAgICAgLy8gbGV0IGNmO1xuICAgICAgICAvLyBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgY29udHJvbEZpZWxkcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgLy8gICAgIGNmID0gY29udHJvbEZpZWxkc1tpbmRleF07XG4gICAgICAgIGZvciAoY29uc3QgY2Ygb2YgY29udHJvbEZpZWxkcykge1xuICAgICAgICAgICAgaWYgKGNmLkFwaU5hbWUgPT09ICdPYmplY3RNZW51Jykge1xuICAgICAgICAgICAgICAgIHRoaXMubWVudUZpZWxkID0gY2Y7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNmLkFwaU5hbWUgPT09ICdJdGVtSGFzQWN0aXZlQ2FtcGFpZ24nKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYXNDYW1wYWlnbkZpZWxkID0gY2Y7XG4gICAgICAgICAgICB9IGVsc2UgaWYgKGNmLkFwaU5hbWUgPT09ICdJdGVtSW5kaWNhdG9yc1dpdGhvdXRDYW1wYWlnbicpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmluZGljYXRvcnNGaWVsZCA9IGNmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gbGV0IGRmO1xuICAgICAgICAvLyBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgZGF0YUZpZWxkcy5sZW5ndGg7IGluZGV4KyspIHtcbiAgICAgICAgLy8gICAgIGRmID0gZGF0YUZpZWxkc1tpbmRleF07XG4gICAgICAgIGZvciAoY29uc3QgZGYgb2YgZGF0YUZpZWxkcykge1xuICAgICAgICAgICAgaWYgKGRmLkFwaU5hbWUgPT09ICdPYmplY3RNZW51Jykge1xuICAgICAgICAgICAgICAgIHRoaXMubWVudURhdGFGaWVsZCA9IGRmO1xuICAgICAgICAgICAgfSBlbHNlIGlmIChkZi5BcGlOYW1lID09PSAnSXRlbUhhc0FjdGl2ZUNhbXBhaWduJykge1xuICAgICAgICAgICAgICAgIHRoaXMuaGFzQ2FtcGFpZ25EYXRhRmllbGQgPSBkZjtcbiAgICAgICAgICAgIH0gZWxzZSBpZiAoZGYuQXBpTmFtZSA9PT0gJ0l0ZW1JbmRpY2F0b3JzV2l0aG91dENhbXBhaWduJykge1xuICAgICAgICAgICAgICAgIHRoaXMuaW5kaWNhdG9yc0RhdGFGaWVsZCA9IGRmO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMubWVudUZpZWxkICYmIHRoaXMubWVudURhdGFGaWVsZCkge1xuICAgICAgICAgICAgdGhpcy5tZW51RGF0YUZpZWxkLkxheW91dCA9IHRoaXMubWVudUZpZWxkLkxheW91dDtcbiAgICAgICAgfVxuXG4gICAgICAgIGlmICh0aGlzLmhhc0NhbXBhaWduRmllbGQgJiYgdGhpcy5oYXNDYW1wYWlnbkRhdGFGaWVsZCkge1xuICAgICAgICAgICAgdGhpcy5oYXNDYW1wYWlnbkRhdGFGaWVsZC5MYXlvdXQgPSB0aGlzLmhhc0NhbXBhaWduRmllbGQuTGF5b3V0O1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKHRoaXMuaW5kaWNhdG9yc0ZpZWxkICYmIHRoaXMuaW5kaWNhdG9yc0RhdGFGaWVsZCkge1xuICAgICAgICAgICAgdGhpcy5pbmRpY2F0b3JzRGF0YUZpZWxkLkxheW91dCA9IHRoaXMuaW5kaWNhdG9yc0ZpZWxkLkxheW91dDtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIENoZWNrIGlmIG1lbnUgaXMgZmxvYXRpbmcgb24gb3RoZXIgZmllbGQuXG4gICAgICAgIC8vIGZvciAobGV0IGluZGV4ID0gMDsgaW5kZXggPCBjb250cm9sRmllbGRzLmxlbmd0aDsgaW5kZXgrKykge1xuICAgICAgICAvLyAgICAgY2YgPSBjb250cm9sRmllbGRzW2luZGV4XTtcbiAgICAgICAgZm9yIChjb25zdCBjZiBvZiBjb250cm9sRmllbGRzKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5tZW51RmllbGQgJiYgY2YuQXBpTmFtZSAhPT0gJ09iamVjdE1lbnUnKSB7XG4gICAgICAgICAgICAgICAgdGhpcy5oYXNNZW51RmxvYXRpbmdPbk90aGVyRmllbGQgPSB0aGlzLmRvZXNGaWVsZEhhdmFGbG9hdGluZ0ZpZWxkKFxuICAgICAgICAgICAgICAgICAgICBjZixcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZW51RmllbGRcbiAgICAgICAgICAgICAgICApO1xuXG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuaGFzTWVudUZsb2F0aW5nT25PdGhlckZpZWxkKSB7XG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgIH1cblxuICAgIGNvbnZlcnRDdXN0b21GaWVsZHMoXG4gICAgICAgIGNvbnRyb2xGaWVsZHM6IEFycmF5PGFueT4sXG4gICAgICAgIGRhdGFGaWVsZHM6IEFycmF5PGFueT5cbiAgICApOiBQZXBGaWVsZEJhc2VbXSB7XG4gICAgICAgIGlmICh0aGlzLmxheW91dFR5cGUgIT09ICd0YWJsZScpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0U3BlY2lhbEZpZWxkcyhjb250cm9sRmllbGRzLCBkYXRhRmllbGRzKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEhBQ0s6IGNvbnZlcnQgdG8gY2VudGVyIGFsaWdubWVudCBpZiB0YWJsZSB2aWV3ICYgc3BlY2lhbCBmaWVsZHMpXG4gICAgICAgICAgICBjb250cm9sRmllbGRzLmZvckVhY2goKGZpZWxkLCBpbmRleCkgPT4ge1xuICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgZmllbGQuQXBpTmFtZSA9PT0gJ1VuaXRzUXVhbnRpdHknIHx8XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLkFwaU5hbWUgPT09ICdRdWFudGl0eVNlbGVjdG9yJyB8fFxuICAgICAgICAgICAgICAgICAgICBmaWVsZC5BcGlOYW1lID09PSAnT2JqZWN0TWVudScgfHxcbiAgICAgICAgICAgICAgICAgICAgZmllbGQuRmllbGRUeXBlID09PSBGSUVMRF9UWVBFLkltYWdlIHx8XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLkZpZWxkVHlwZSA9PT0gRklFTERfVFlQRS5JbWFnZVVSTCB8fFxuICAgICAgICAgICAgICAgICAgICBmaWVsZC5GaWVsZFR5cGUgPT09IEZJRUxEX1RZUEUuSW5kaWNhdG9ycyB8fFxuICAgICAgICAgICAgICAgICAgICBmaWVsZC5GaWVsZFR5cGUgPT09IEZJRUxEX1RZUEUuQm9vbGVhbiB8fFxuICAgICAgICAgICAgICAgICAgICBmaWVsZC5GaWVsZFR5cGUgPT09IEZJRUxEX1RZUEUuQ2FsY3VsYXRlZEJvb2wgfHxcbiAgICAgICAgICAgICAgICAgICAgZmllbGQuRmllbGRUeXBlID09PSBGSUVMRF9UWVBFLlNpZ25hdHVyZSB8fFxuICAgICAgICAgICAgICAgICAgICBmaWVsZC5GaWVsZFR5cGUgPT09XG4gICAgICAgICAgICAgICAgICAgIEZJRUxEX1RZUEUuTnVtYmVySW50ZWdlclF1YW50aXR5U2VsZWN0b3IgfHxcbiAgICAgICAgICAgICAgICAgICAgZmllbGQuRmllbGRUeXBlID09PSBGSUVMRF9UWVBFLk51bWJlclJlYWxRdWFudGl0eVNlbGVjdG9yIHx8XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLkZpZWxkVHlwZSA9PT0gRklFTERfVFlQRS5QYWNrYWdlIHx8XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLkZpZWxkVHlwZSA9PT0gRklFTERfVFlQRS5OdW1iZXJJbnRlZ2VyRm9yTWF0cml4IHx8XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLkZpZWxkVHlwZSA9PT0gRklFTERfVFlQRS5OdW1iZXJSZWFsRm9yTWF0cml4XG4gICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgIGZpZWxkLkxheW91dC5YQWxpZ25tZW50ID0gWF9BTElHTk1FTlRfVFlQRS5DZW50ZXI7XG4gICAgICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgICAgICAgLy8gSEFDSzogYWxpZ24gdGhlIHJlc3Qgb2YgdGhlIGZpZWxkcyBieSB0aGUgY3VsdHVyZS5cbiAgICAgICAgICAgICAgICAgICAgLy8gZmllbGQuTGF5b3V0LlhBbGlnbm1lbnQgPSB0aGlzLmxheW91dFNlcnZpY2UuaXNSdGwoKSA/IFhfQUxJR05NRU5UX1RZUEUuUmlnaHQgOiBYX0FMSUdOTUVOVF9UWVBFLkxlZnQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cblxuICAgICAgICBjb25zdCBmaWVsZHM6IFBlcEZpZWxkQmFzZVtdID0gW107XG5cbiAgICAgICAgY29udHJvbEZpZWxkcy5mb3JFYWNoKChmaWVsZCwgaW5kZXgpID0+IHtcbiAgICAgICAgICAgIGNvbnN0IGRhdGFGaWVsZCA9IGRhdGFGaWVsZHMuZmlsdGVyKFxuICAgICAgICAgICAgICAgIChkZikgPT4gZGYuQXBpTmFtZSA9PT0gZmllbGQuQXBpTmFtZVxuICAgICAgICAgICAgKVswXTtcblxuICAgICAgICAgICAgaWYgKCFkYXRhRmllbGQpIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIElmIGN1cnJlbnQgdmlldyBpcyBub3QgdGFibGUgdmlldyBhbmQgdGhvc2UgZmllbGRzIGFyZSBzcGVjaWFsLlxuICAgICAgICAgICAgaWYgKFxuICAgICAgICAgICAgICAgIHRoaXMubGF5b3V0VHlwZSAhPT0gJ3RhYmxlJyAmJlxuICAgICAgICAgICAgICAgICgodGhpcy5oYXNNZW51RmxvYXRpbmdPbk90aGVyRmllbGQgJiZcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZW51RmllbGQgJiZcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5tZW51RmllbGQuQXBpTmFtZSA9PT0gZmllbGQuQXBpTmFtZSkgfHxcbiAgICAgICAgICAgICAgICAgICAgKHRoaXMuaW5kaWNhdG9yc0ZpZWxkICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmluZGljYXRvcnNGaWVsZC5BcGlOYW1lID09PSBmaWVsZC5BcGlOYW1lKSB8fFxuICAgICAgICAgICAgICAgICAgICAodGhpcy5oYXNDYW1wYWlnbkZpZWxkICYmXG4gICAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhhc0NhbXBhaWduRmllbGQuQXBpTmFtZSA9PT0gZmllbGQuQXBpTmFtZSkpXG4gICAgICAgICAgICApIHtcbiAgICAgICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIC8vIFNldCB0eXBlIHRvIGxpbmtcbiAgICAgICAgICAgIGlmIChpbmRleCA9PT0gMCAmJiB0aGlzLmZpcnN0RmllbGRBc0xpbmspIHtcbiAgICAgICAgICAgICAgICBkYXRhRmllbGQuRmllbGRUeXBlID0gRklFTERfVFlQRS5JbnRlcm5hbExpbms7XG4gICAgICAgICAgICAgICAgLy8gZGF0YUZpZWxkLlZhbHVlID0gdGhpcy5nZXRJbnRlcm5hbExpbmtIcmVmKCk7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIGlmIChmaWVsZC5BcGlOYW1lID09PSAnT2JqZWN0TWVudScpIHtcbiAgICAgICAgICAgICAgICBkYXRhRmllbGQuRW5hYmxlZCA9IHRydWU7XG4gICAgICAgICAgICAgICAgLy8gSEFDSyA6IFVudGlsIFwiRW5hYmxlZFwiIHJldHVybnMgZnJvbSB0aGUgc2VydmVyLCB3ZSBzZXQgUGVwTWVudSB0byBiZVxuICAgICAgICAgICAgICAgIC8vICAgICAgICBEaXNhYmxlZCBpbiBjYXJ0IG9uIHJlZ3VsYXIgaXRlbXMgYW5kIG5vdCBjYW1waWduIGl0ZW1zLlxuICAgICAgICAgICAgfVxuICAgICAgICAgICAgY29uc3QgY3VzdG9tRmllbGQ6IFBlcEZpZWxkQmFzZSA9IHRoaXMuY3JlYXRlQmFzZUZpZWxkKGZpZWxkLCBkYXRhRmllbGQpO1xuICAgICAgICAgICAgZmllbGRzLnB1c2goY3VzdG9tRmllbGQpO1xuICAgICAgICB9KTtcblxuICAgICAgICByZXR1cm4gZmllbGRzLnNvcnQoKGYxLCBmMikgPT5cbiAgICAgICAgICAgIGYxLnJvdyA+IGYyLnJvd1xuICAgICAgICAgICAgICAgID8gMVxuICAgICAgICAgICAgICAgIDogZjEucm93IDwgZjIucm93XG4gICAgICAgICAgICAgICAgICAgID8gLTFcbiAgICAgICAgICAgICAgICAgICAgOiBmMS5jb2wgPiBmMi5jb2xcbiAgICAgICAgICAgICAgICAgICAgICAgID8gMVxuICAgICAgICAgICAgICAgICAgICAgICAgOiBmMS5jb2wgPCBmMi5jb2xcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICA/IC0xXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgOiAwXG4gICAgICAgICk7XG4gICAgfVxuXG4gICAgb25Gb3JtVmFsaWRhdGlvbkNoYW5nZWQoZm9ybVZhbGlkYXRpb25DaGFuZ2U6IGFueSk6IHZvaWQge1xuICAgICAgICB0aGlzLmZvcm1WYWxpZGF0aW9uQ2hhbmdlLmVtaXQoZm9ybVZhbGlkYXRpb25DaGFuZ2UpO1xuICAgIH1cblxuICAgIG9uVmFsdWVDaGFuZ2VkKGV2ZW50OiBJUGVwRmllbGRWYWx1ZUNoYW5nZUV2ZW50KTogdm9pZCB7XG4gICAgICAgIHRoaXMub25Gb3JtVmFsaWRhdGlvbkNoYW5nZWQodGhpcy5mb3JtLnZhbGlkKTtcblxuICAgICAgICBjb25zdCBmb3JtQ29udHJvbCA9IHRoaXMuZ2V0Rm9ybUNvbnRyb2xCeUlkKGV2ZW50LmtleSk7XG5cbiAgICAgICAgY29uc3QgaXNWYWxpZCA9IGZvcm1Db250cm9sID8gZm9ybUNvbnRyb2wudmFsaWQgOiB0cnVlO1xuICAgICAgICAvLyBjb25zdCBpc1ZhbGlkID0gdHJ1ZTtcblxuICAgICAgICBpZiAoaXNWYWxpZCkge1xuICAgICAgICAgICAgLy8gU2V0IGl0IHRvIGZhbHNlIHRvIGRpc2FibGUgYWxsIGZpZWxkcy5cbiAgICAgICAgICAgIGlmICh0aGlzLmlzSW50ZXJuYWwgJiYgdGhpcy5sYXlvdXRUeXBlID09PSAnZm9ybScpIHtcbiAgICAgICAgICAgICAgICB0aGlzLmlzTG9ja2VkID0gdHJ1ZTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gVXBkYXRlIHRoZSBjdXJyZW50IGZpZWxkIHZhbHVlLlxuICAgICAgICAgICAgY29uc3QgY3VycmVudEZpZWxkID0gdGhpcy5maWVsZHMuZmluZCgoZikgPT4gZi5rZXkgPT09IGV2ZW50LmtleSk7XG4gICAgICAgICAgICBpZiAoY3VycmVudEZpZWxkKSB7XG4gICAgICAgICAgICAgICAgY3VycmVudEZpZWxkLmZvcm1hdHRlZFZhbHVlID0gY3VycmVudEZpZWxkLnZhbHVlID0gZXZlbnQudmFsdWU7XG4gICAgICAgICAgICB9XG5cbiAgICAgICAgICAgIHRoaXMudmFsdWVDaGFuZ2UuZW1pdCh7XG4gICAgICAgICAgICAgICAgaWQ6IHRoaXMuZGF0YS5VSUQudG9TdHJpbmcoKSxcbiAgICAgICAgICAgICAgICB1aU9iamVjdEtleTogdGhpcy5kYXRhLktleSxcbiAgICAgICAgICAgICAgICBrZXk6IGV2ZW50LmtleSxcbiAgICAgICAgICAgICAgICB2YWx1ZTogZXZlbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgY29udHJvbFR5cGU6IGV2ZW50LmNvbnRyb2xUeXBlLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBvbkNsaWNrKGZpZWxkQ2xpY2tFdmVudDogSVBlcEZpZWxkQ2xpY2tFdmVudCk6IHZvaWQge1xuICAgICAgICBjb25zdCBjbGlja2VkVWlDb250cm9sRmllbGQgPSB0aGlzLmRhdGEuRmllbGRzLmZpbHRlcihcbiAgICAgICAgICAgIChmKSA9PiBmLkFwaU5hbWUgPT09IGZpZWxkQ2xpY2tFdmVudC5rZXlcbiAgICAgICAgKVswXTtcbiAgICAgICAgY29uc3QgaWRUeXBlID0gdGhpcy5kYXRhLlR5cGUgPyB0aGlzLmRhdGEuVHlwZS50b1N0cmluZygpIDogJyc7XG5cbiAgICAgICAgaWYgKGNsaWNrZWRVaUNvbnRyb2xGaWVsZCkge1xuICAgICAgICAgICAgdGhpcy5maWVsZENsaWNrLmVtaXQoe1xuICAgICAgICAgICAgICAgIGlkOiB0aGlzLmRhdGEuVUlELnRvU3RyaW5nKCksXG4gICAgICAgICAgICAgICAgdWlPYmplY3RLZXk6IHRoaXMuZGF0YS5LZXksXG4gICAgICAgICAgICAgICAga2V5OiBmaWVsZENsaWNrRXZlbnQua2V5LFxuICAgICAgICAgICAgICAgIGlkVHlwZSxcbiAgICAgICAgICAgICAgICB3aGljaDogZmllbGRDbGlja0V2ZW50LmV2ZW50V2hpY2gsXG4gICAgICAgICAgICAgICAgdmFsdWU6IGZpZWxkQ2xpY2tFdmVudC52YWx1ZSxcbiAgICAgICAgICAgICAgICBjb250cm9sVHlwZTogZmllbGRDbGlja0V2ZW50LmNvbnRyb2xUeXBlLFxuICAgICAgICAgICAgICAgIGZpZWxkVHlwZTogY2xpY2tlZFVpQ29udHJvbEZpZWxkLkZpZWxkVHlwZSxcbiAgICAgICAgICAgICAgICBvdGhlckRhdGE6IGZpZWxkQ2xpY2tFdmVudC5vdGhlckRhdGEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIC8vIEZvciBvdGhlciBhcGkgbmFtZXMgKGxpa2UgZW50ZXIgY2hpbGRyZW4gZXRjKS5cbiAgICAgICAgICAgIHRoaXMuZmllbGRDbGljay5lbWl0KHtcbiAgICAgICAgICAgICAgICBpZDogdGhpcy5kYXRhLlVJRC50b1N0cmluZygpLFxuICAgICAgICAgICAgICAgIHVpT2JqZWN0S2V5OiB0aGlzLmRhdGEuS2V5LFxuICAgICAgICAgICAgICAgIGtleTogZmllbGRDbGlja0V2ZW50LmtleSxcbiAgICAgICAgICAgICAgICBpZFR5cGUsXG4gICAgICAgICAgICAgICAgd2hpY2g6IGZpZWxkQ2xpY2tFdmVudC5ldmVudFdoaWNoLFxuICAgICAgICAgICAgICAgIHZhbHVlOiBmaWVsZENsaWNrRXZlbnQudmFsdWUsXG4gICAgICAgICAgICAgICAgY29udHJvbFR5cGU6IGZpZWxkQ2xpY2tFdmVudC5jb250cm9sVHlwZSxcbiAgICAgICAgICAgICAgICBvdGhlckRhdGE6IGZpZWxkQ2xpY2tFdmVudC5vdGhlckRhdGEsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoaXMgZXZlbnQgaXMgZm9yIGhhbmRsZSB0aGUgaW50ZXJuYWwgcGFnZSBldmVudHMuXG4gICAgb25JbnRlcm5hbEZvcm1GaWVsZENsaWNrZWQoaW50ZXJuYWxGb3JtRmllbGRDbGljazogYW55KTogdm9pZCB7XG4gICAgICAgIHRoaXMuaW50ZXJuYWxGb3JtRmllbGRDbGljay5lbWl0KGludGVybmFsRm9ybUZpZWxkQ2xpY2spO1xuICAgIH1cblxuICAgIC8vIFRoaXMgZXZlbnQgaXMgZm9yIGhhbmRsZSB0aGUgaW50ZXJuYWwgcGFnZSBldmVudHMuXG4gICAgb25JbnRlcm5hbEZvcm1GaWVsZENoYW5nZWQoaW50ZXJuYWxGb3JtRmllbGRDaGFuZ2U6IGFueSk6IHZvaWQge1xuICAgICAgICB0aGlzLmludGVybmFsRm9ybUZpZWxkQ2hhbmdlLmVtaXQoaW50ZXJuYWxGb3JtRmllbGRDaGFuZ2UpO1xuICAgIH1cblxuICAgIC8vIFRoaXMgZXZlbnQgaXMgZm9yIGhhbmRsZSB0aGUgcmVsYXRlZCBpdGVtcyBjaGFuZ2UgZXZlbnRzLlxuICAgIG9uRm9ybVZhbHVlQ2hhbmdlZChldmVudDogSVBlcEZvcm1GaWVsZFZhbHVlQ2hhbmdlRXZlbnQpOiB2b2lkIHtcbiAgICAgICAgLy8gdGhpcy52YWx1ZUNoYW5nZS5lbWl0KGV2ZW50KTtcbiAgICB9XG5cbiAgICAvLyBUaGlzIGV2ZW50IGlzIGZvciBoYW5kbGUgdGhlIHJlbGF0ZWQgaXRlbXMgY2hhbmdlIGV2ZW50cy5cbiAgICBvbkZvcm1GaWVsZENsaWNrKGV2ZW50OiBJUGVwRm9ybUZpZWxkQ2xpY2tFdmVudCk6IHZvaWQge1xuICAgICAgICB0aGlzLmZpZWxkQ2xpY2suZW1pdChldmVudCk7XG4gICAgfVxufVxuIl19