ngx-bootstrap 3.1.2 → 3.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (441) hide show
  1. package/CHANGELOG.md +236 -0
  2. package/CONTRIBUTING.md +1 -1
  3. package/README.md +8 -5
  4. package/accordion/package.json +1 -1
  5. package/alert/package.json +1 -1
  6. package/bundles/ngx-bootstrap.es2015.js +13985 -11505
  7. package/bundles/ngx-bootstrap.es2015.js.map +1 -1
  8. package/bundles/ngx-bootstrap.umd.js +2 -1
  9. package/bundles/ngx-bootstrap.umd.js.map +1 -1
  10. package/bundles/ngx-bootstrap.umd.min.js +1 -1
  11. package/buttons/package.json +1 -1
  12. package/carousel/package.json +1 -1
  13. package/chronos/bundles/ngx-bootstrap-chronos.umd.js +217 -63
  14. package/chronos/bundles/ngx-bootstrap-chronos.umd.js.map +1 -1
  15. package/chronos/bundles/ngx-bootstrap-chronos.umd.min.js +1 -1
  16. package/chronos/bundles/ngx-bootstrap-chronos.umd.min.js.map +1 -1
  17. package/chronos/esm2015/i18n/ca.js +128 -0
  18. package/chronos/esm2015/i18n/lt.js +1 -1
  19. package/chronos/esm2015/i18n/pl.js +7 -1
  20. package/chronos/esm2015/index.js +2 -2
  21. package/chronos/esm2015/ngx-bootstrap-chronos.js +2 -2
  22. package/chronos/esm2015/public_api.js +3 -2
  23. package/chronos/esm2015/utils/date-compare.js +20 -1
  24. package/chronos/esm5/i18n/ca.js +128 -0
  25. package/chronos/esm5/i18n/lt.js +1 -1
  26. package/chronos/esm5/i18n/pl.js +7 -1
  27. package/chronos/esm5/index.js +2 -2
  28. package/chronos/esm5/ngx-bootstrap-chronos.js +2 -2
  29. package/chronos/esm5/public_api.js +3 -2
  30. package/chronos/esm5/utils/date-compare.js +20 -1
  31. package/chronos/fesm2015/ngx-bootstrap-chronos.js +223 -67
  32. package/chronos/fesm2015/ngx-bootstrap-chronos.js.map +1 -1
  33. package/chronos/fesm5/ngx-bootstrap-chronos.js +224 -67
  34. package/chronos/fesm5/ngx-bootstrap-chronos.js.map +1 -1
  35. package/chronos/i18n/ca.d.ts +2 -0
  36. package/chronos/ngx-bootstrap-chronos.metadata.json +1 -1
  37. package/chronos/package.json +1 -1
  38. package/chronos/public_api.d.ts +2 -1
  39. package/chronos/utils/date-compare.d.ts +2 -0
  40. package/collapse/package.json +1 -1
  41. package/component-loader/bundles/ngx-bootstrap-component-loader.umd.js +11 -1
  42. package/component-loader/bundles/ngx-bootstrap-component-loader.umd.js.map +1 -1
  43. package/component-loader/bundles/ngx-bootstrap-component-loader.umd.min.js +1 -1
  44. package/component-loader/bundles/ngx-bootstrap-component-loader.umd.min.js.map +1 -1
  45. package/component-loader/component-loader.class.d.ts +1 -1
  46. package/component-loader/esm2015/component-loader.class.js +12 -2
  47. package/component-loader/esm2015/listen-options.model.js +3 -1
  48. package/component-loader/esm5/component-loader.class.js +12 -2
  49. package/component-loader/esm5/listen-options.model.js +3 -1
  50. package/component-loader/fesm2015/ngx-bootstrap-component-loader.js +12 -2
  51. package/component-loader/fesm2015/ngx-bootstrap-component-loader.js.map +1 -1
  52. package/component-loader/fesm5/ngx-bootstrap-component-loader.js +12 -2
  53. package/component-loader/fesm5/ngx-bootstrap-component-loader.js.map +1 -1
  54. package/component-loader/listen-options.model.d.ts +1 -0
  55. package/component-loader/ngx-bootstrap-component-loader.metadata.json +1 -1
  56. package/component-loader/package.json +1 -1
  57. package/datepicker/base/bs-datepicker-container.d.ts +5 -1
  58. package/datepicker/bs-datepicker-inline.component.d.ts +48 -0
  59. package/datepicker/bs-datepicker-inline.config.d.ts +3 -0
  60. package/datepicker/bs-datepicker.component.d.ts +14 -0
  61. package/datepicker/bs-datepicker.config.d.ts +22 -1
  62. package/datepicker/bs-datepicker.css +56 -5
  63. package/datepicker/bs-datepicker.css.map +3 -3
  64. package/datepicker/bs-datepicker.module.d.ts +0 -1
  65. package/datepicker/bs-datepicker.scss +21 -8
  66. package/datepicker/bs-daterangepicker.component.d.ts +5 -0
  67. package/datepicker/bundles/ngx-bootstrap-datepicker.umd.js +2967 -2546
  68. package/datepicker/bundles/ngx-bootstrap-datepicker.umd.js.map +1 -1
  69. package/datepicker/bundles/ngx-bootstrap-datepicker.umd.min.js +1 -1
  70. package/datepicker/bundles/ngx-bootstrap-datepicker.umd.min.js.map +1 -1
  71. package/datepicker/engine/flag-days-calendar.d.ts +2 -0
  72. package/datepicker/engine/view-mode.d.ts +1 -1
  73. package/datepicker/esm2015/base/bs-datepicker-container.js +22 -1
  74. package/datepicker/esm2015/bs-datepicker-inline.component.js +179 -0
  75. package/datepicker/esm2015/bs-datepicker-inline.config.js +22 -0
  76. package/datepicker/esm2015/bs-datepicker-input.directive.js +2 -1
  77. package/datepicker/esm2015/bs-datepicker.component.js +34 -2
  78. package/datepicker/esm2015/bs-datepicker.config.js +28 -1
  79. package/datepicker/esm2015/bs-datepicker.module.js +10 -11
  80. package/datepicker/esm2015/bs-daterangepicker-input.directive.js +9 -4
  81. package/datepicker/esm2015/bs-daterangepicker.component.js +17 -2
  82. package/datepicker/esm2015/engine/flag-days-calendar.js +16 -6
  83. package/datepicker/esm2015/engine/view-mode.js +4 -3
  84. package/datepicker/esm2015/models/index.js +7 -1
  85. package/datepicker/esm2015/ngx-bootstrap-datepicker.js +19 -18
  86. package/datepicker/esm2015/public_api.js +11 -9
  87. package/datepicker/esm2015/reducer/bs-datepicker.actions.js +27 -1
  88. package/datepicker/esm2015/reducer/bs-datepicker.effects.js +25 -11
  89. package/datepicker/esm2015/reducer/bs-datepicker.reducer.js +15 -5
  90. package/datepicker/esm2015/reducer/bs-datepicker.state.js +9 -1
  91. package/datepicker/esm2015/themes/bs/bs-datepicker-container.component.js +5 -3
  92. package/datepicker/esm2015/themes/bs/bs-datepicker-day-decorator.directive.js +33 -2
  93. package/datepicker/esm2015/themes/bs/bs-datepicker-inline-container.component.js +50 -0
  94. package/datepicker/esm2015/themes/bs/bs-daterangepicker-container.component.js +5 -3
  95. package/datepicker/esm2015/themes/bs/bs-days-calendar-view.component.js +71 -4
  96. package/datepicker/esm2015/utils/bs-calendar-utils.js +13 -2
  97. package/datepicker/esm5/base/bs-datepicker-container.js +34 -1
  98. package/datepicker/esm5/bs-datepicker-inline.component.js +196 -0
  99. package/datepicker/esm5/bs-datepicker-inline.config.js +29 -0
  100. package/datepicker/esm5/bs-datepicker-input.directive.js +2 -1
  101. package/datepicker/esm5/bs-datepicker.component.js +34 -2
  102. package/datepicker/esm5/bs-datepicker.config.js +28 -1
  103. package/datepicker/esm5/bs-datepicker.module.js +10 -7
  104. package/datepicker/esm5/bs-daterangepicker-input.directive.js +9 -4
  105. package/datepicker/esm5/bs-daterangepicker.component.js +17 -2
  106. package/datepicker/esm5/engine/flag-days-calendar.js +16 -6
  107. package/datepicker/esm5/engine/view-mode.js +4 -3
  108. package/datepicker/esm5/models/index.js +7 -1
  109. package/datepicker/esm5/ngx-bootstrap-datepicker.js +19 -18
  110. package/datepicker/esm5/public_api.js +11 -9
  111. package/datepicker/esm5/reducer/bs-datepicker.actions.js +35 -1
  112. package/datepicker/esm5/reducer/bs-datepicker.effects.js +33 -11
  113. package/datepicker/esm5/reducer/bs-datepicker.reducer.js +15 -5
  114. package/datepicker/esm5/reducer/bs-datepicker.state.js +9 -1
  115. package/datepicker/esm5/themes/bs/bs-datepicker-container.component.js +5 -3
  116. package/datepicker/esm5/themes/bs/bs-datepicker-day-decorator.directive.js +30 -3
  117. package/datepicker/esm5/themes/bs/bs-datepicker-inline-container.component.js +48 -0
  118. package/datepicker/esm5/themes/bs/bs-daterangepicker-container.component.js +5 -3
  119. package/datepicker/esm5/themes/bs/bs-days-calendar-view.component.js +75 -3
  120. package/datepicker/esm5/utils/bs-calendar-utils.js +13 -2
  121. package/datepicker/fesm2015/ngx-bootstrap-datepicker.js +3192 -2829
  122. package/datepicker/fesm2015/ngx-bootstrap-datepicker.js.map +1 -1
  123. package/datepicker/fesm5/ngx-bootstrap-datepicker.js +3407 -2994
  124. package/datepicker/fesm5/ngx-bootstrap-datepicker.js.map +1 -1
  125. package/datepicker/models/index.d.ts +3 -0
  126. package/datepicker/ngx-bootstrap-datepicker.d.ts +17 -16
  127. package/datepicker/ngx-bootstrap-datepicker.metadata.json +1 -1
  128. package/datepicker/package.json +1 -1
  129. package/datepicker/public_api.d.ts +11 -8
  130. package/datepicker/reducer/bs-datepicker.actions.d.ts +4 -0
  131. package/datepicker/reducer/bs-datepicker.effects.d.ts +4 -2
  132. package/datepicker/reducer/bs-datepicker.state.d.ts +4 -0
  133. package/datepicker/themes/bs/bs-datepicker-day-decorator.directive.d.ts +8 -1
  134. package/datepicker/themes/bs/bs-datepicker-inline-container.component.d.ts +9 -0
  135. package/datepicker/themes/bs/bs-days-calendar-view.component.d.ts +8 -1
  136. package/datepicker/utils/bs-calendar-utils.d.ts +1 -0
  137. package/datepicker/utils/scss/mixins.css.map +4 -2
  138. package/datepicker/utils/scss/mixins.scss +10 -0
  139. package/dropdown/bs-dropdown-container.component.d.ts +3 -0
  140. package/dropdown/bs-dropdown-toggle.directive.d.ts +3 -1
  141. package/dropdown/bs-dropdown.config.d.ts +2 -0
  142. package/dropdown/bs-dropdown.directive.d.ts +8 -2
  143. package/dropdown/bs-dropdown.state.d.ts +1 -0
  144. package/dropdown/bundles/ngx-bootstrap-dropdown.umd.js +62 -5
  145. package/dropdown/bundles/ngx-bootstrap-dropdown.umd.js.map +1 -1
  146. package/dropdown/bundles/ngx-bootstrap-dropdown.umd.min.js +1 -1
  147. package/dropdown/bundles/ngx-bootstrap-dropdown.umd.min.js.map +1 -1
  148. package/dropdown/esm2015/bs-dropdown-container.component.js +13 -2
  149. package/dropdown/esm2015/bs-dropdown-toggle.directive.js +10 -3
  150. package/dropdown/esm2015/bs-dropdown.config.js +10 -1
  151. package/dropdown/esm2015/bs-dropdown.directive.js +30 -3
  152. package/dropdown/esm2015/bs-dropdown.module.js +2 -2
  153. package/dropdown/esm2015/bs-dropdown.state.js +3 -1
  154. package/dropdown/esm5/bs-dropdown-container.component.js +19 -2
  155. package/dropdown/esm5/bs-dropdown-toggle.directive.js +9 -3
  156. package/dropdown/esm5/bs-dropdown.config.js +10 -1
  157. package/dropdown/esm5/bs-dropdown.directive.js +40 -3
  158. package/dropdown/esm5/bs-dropdown.module.js +2 -2
  159. package/dropdown/esm5/bs-dropdown.state.js +3 -1
  160. package/dropdown/fesm2015/ngx-bootstrap-dropdown.js +49 -5
  161. package/dropdown/fesm2015/ngx-bootstrap-dropdown.js.map +1 -1
  162. package/dropdown/fesm5/ngx-bootstrap-dropdown.js +64 -5
  163. package/dropdown/fesm5/ngx-bootstrap-dropdown.js.map +1 -1
  164. package/dropdown/ngx-bootstrap-dropdown.metadata.json +1 -1
  165. package/dropdown/package.json +1 -1
  166. package/esm2015/ngx-bootstrap.js +2 -2
  167. package/esm2015/public_api.js +2 -2
  168. package/esm5/ngx-bootstrap.js +2 -2
  169. package/esm5/public_api.js +2 -2
  170. package/fesm2015/ngx-bootstrap.js +1 -1
  171. package/fesm5/ngx-bootstrap.js +1 -1
  172. package/locale/bundles/ngx-bootstrap-locale.umd.js +2 -1
  173. package/locale/bundles/ngx-bootstrap-locale.umd.js.map +1 -1
  174. package/locale/bundles/ngx-bootstrap-locale.umd.min.js +1 -1
  175. package/locale/esm2015/ngx-bootstrap-locale.js +2 -2
  176. package/locale/esm2015/public_api.js +2 -1
  177. package/locale/esm5/ngx-bootstrap-locale.js +2 -2
  178. package/locale/esm5/public_api.js +2 -1
  179. package/locale/fesm2015/ngx-bootstrap-locale.js +1 -1
  180. package/locale/fesm5/ngx-bootstrap-locale.js +1 -1
  181. package/locale/ngx-bootstrap-locale.metadata.json +1 -1
  182. package/locale/package.json +1 -1
  183. package/locale/public_api.d.ts +1 -0
  184. package/mini-ngrx/package.json +1 -1
  185. package/modal/bs-modal-ref.service.d.ts +4 -0
  186. package/modal/bundles/ngx-bootstrap-modal.umd.js +8 -1
  187. package/modal/bundles/ngx-bootstrap-modal.umd.js.map +1 -1
  188. package/modal/bundles/ngx-bootstrap-modal.umd.min.js +1 -1
  189. package/modal/bundles/ngx-bootstrap-modal.umd.min.js.map +1 -1
  190. package/modal/esm2015/bs-modal-ref.service.js +10 -1
  191. package/modal/esm2015/bs-modal.service.js +4 -1
  192. package/modal/esm5/bs-modal-ref.service.js +10 -1
  193. package/modal/esm5/bs-modal.service.js +4 -1
  194. package/modal/fesm2015/ngx-bootstrap-modal.js +8 -1
  195. package/modal/fesm2015/ngx-bootstrap-modal.js.map +1 -1
  196. package/modal/fesm5/ngx-bootstrap-modal.js +8 -1
  197. package/modal/fesm5/ngx-bootstrap-modal.js.map +1 -1
  198. package/modal/package.json +1 -1
  199. package/package.json +2 -2
  200. package/pagination/esm2015/models/index.js +1 -4
  201. package/pagination/esm5/models/index.js +1 -4
  202. package/pagination/models/index.d.ts +0 -1
  203. package/pagination/package.json +1 -1
  204. package/popover/bundles/ngx-bootstrap-popover.umd.js +3 -2
  205. package/popover/bundles/ngx-bootstrap-popover.umd.js.map +1 -1
  206. package/popover/bundles/ngx-bootstrap-popover.umd.min.js +1 -1
  207. package/popover/bundles/ngx-bootstrap-popover.umd.min.js.map +1 -1
  208. package/popover/esm2015/popover-container.component.js +19 -8
  209. package/popover/esm5/popover-container.component.js +3 -2
  210. package/popover/fesm2015/ngx-bootstrap-popover.js +19 -8
  211. package/popover/fesm2015/ngx-bootstrap-popover.js.map +1 -1
  212. package/popover/fesm5/ngx-bootstrap-popover.js +3 -2
  213. package/popover/fesm5/ngx-bootstrap-popover.js.map +1 -1
  214. package/popover/ngx-bootstrap-popover.metadata.json +1 -1
  215. package/popover/package.json +1 -1
  216. package/positioning/bundles/ngx-bootstrap-positioning.umd.js +1192 -252
  217. package/positioning/bundles/ngx-bootstrap-positioning.umd.js.map +1 -1
  218. package/positioning/bundles/ngx-bootstrap-positioning.umd.min.js +1 -1
  219. package/positioning/bundles/ngx-bootstrap-positioning.umd.min.js.map +1 -1
  220. package/positioning/esm2015/models/index.js +44 -0
  221. package/positioning/esm2015/modifiers/arrow.js +54 -0
  222. package/positioning/esm2015/modifiers/flip.js +65 -0
  223. package/positioning/esm2015/modifiers/index.js +11 -0
  224. package/positioning/esm2015/modifiers/initData.js +34 -0
  225. package/positioning/esm2015/modifiers/preventOverflow.js +70 -0
  226. package/positioning/esm2015/modifiers/shift.js +29 -0
  227. package/positioning/esm2015/ng-positioning.js +19 -220
  228. package/positioning/esm2015/positioning.service.js +44 -4
  229. package/positioning/esm2015/utils/computeAutoPlacement.js +64 -0
  230. package/positioning/esm2015/utils/findCommonOffsetParent.js +47 -0
  231. package/positioning/esm2015/utils/getBordersSize.js +20 -0
  232. package/positioning/esm2015/utils/getBoundaries.js +66 -0
  233. package/positioning/esm2015/utils/getBoundingClientRect.js +61 -0
  234. package/positioning/esm2015/utils/getClientRect.js +13 -0
  235. package/positioning/esm2015/utils/getFixedPositionOffsetParent.js +26 -0
  236. package/positioning/esm2015/utils/getOffsetParent.js +37 -0
  237. package/positioning/esm2015/utils/getOffsetRectRelativeToArbitraryNode.js +62 -0
  238. package/positioning/esm2015/utils/getOffsets.js +20 -0
  239. package/positioning/esm2015/utils/getOppositePlacement.js +15 -0
  240. package/positioning/esm2015/utils/getOppositeVariation.js +20 -0
  241. package/positioning/esm2015/utils/getOuterSizes.js +21 -0
  242. package/positioning/esm2015/utils/getParentNode.js +17 -0
  243. package/positioning/esm2015/utils/getReferenceOffsets.js +21 -0
  244. package/positioning/esm2015/utils/getRoot.js +17 -0
  245. package/positioning/esm2015/utils/getScroll.js +22 -0
  246. package/positioning/esm2015/utils/getScrollParent.js +32 -0
  247. package/positioning/esm2015/utils/getStyleComputedProperty.js +21 -0
  248. package/positioning/esm2015/utils/getTargetOffsets.js +38 -0
  249. package/positioning/esm2015/utils/getViewportOffsetRectRelativeToArtbitraryNode.js +29 -0
  250. package/positioning/esm2015/utils/getWindowSizes.js +34 -0
  251. package/positioning/esm2015/utils/includeScroll.js +23 -0
  252. package/positioning/esm2015/utils/index.js +28 -0
  253. package/positioning/esm2015/utils/isBrowser.js +7 -0
  254. package/positioning/esm2015/utils/isFixed.js +22 -0
  255. package/positioning/esm2015/utils/isIE.js +22 -0
  256. package/positioning/esm2015/utils/isNumeric.js +14 -0
  257. package/positioning/esm2015/utils/isOffsetContainer.js +18 -0
  258. package/positioning/esm2015/utils/setAllStyles.js +55 -0
  259. package/positioning/esm2015/utils/setStyles.js +28 -0
  260. package/positioning/esm5/models/index.js +44 -0
  261. package/positioning/esm5/modifiers/arrow.js +56 -0
  262. package/positioning/esm5/modifiers/flip.js +66 -0
  263. package/positioning/esm5/modifiers/index.js +11 -0
  264. package/positioning/esm5/modifiers/initData.js +34 -0
  265. package/positioning/esm5/modifiers/preventOverflow.js +73 -0
  266. package/positioning/esm5/modifiers/shift.js +31 -0
  267. package/positioning/esm5/ng-positioning.js +24 -247
  268. package/positioning/esm5/positioning.service.js +49 -5
  269. package/positioning/esm5/utils/computeAutoPlacement.js +72 -0
  270. package/positioning/esm5/utils/findCommonOffsetParent.js +47 -0
  271. package/positioning/esm5/utils/getBordersSize.js +20 -0
  272. package/positioning/esm5/utils/getBoundaries.js +68 -0
  273. package/positioning/esm5/utils/getBoundingClientRect.js +61 -0
  274. package/positioning/esm5/utils/getClientRect.js +14 -0
  275. package/positioning/esm5/utils/getFixedPositionOffsetParent.js +26 -0
  276. package/positioning/esm5/utils/getOffsetParent.js +37 -0
  277. package/positioning/esm5/utils/getOffsetRectRelativeToArbitraryNode.js +63 -0
  278. package/positioning/esm5/utils/getOffsets.js +20 -0
  279. package/positioning/esm5/utils/getOppositePlacement.js +15 -0
  280. package/positioning/esm5/utils/getOppositeVariation.js +20 -0
  281. package/positioning/esm5/utils/getOuterSizes.js +21 -0
  282. package/positioning/esm5/utils/getParentNode.js +17 -0
  283. package/positioning/esm5/utils/getReferenceOffsets.js +22 -0
  284. package/positioning/esm5/utils/getRoot.js +17 -0
  285. package/positioning/esm5/utils/getScroll.js +23 -0
  286. package/positioning/esm5/utils/getScrollParent.js +32 -0
  287. package/positioning/esm5/utils/getStyleComputedProperty.js +21 -0
  288. package/positioning/esm5/utils/getTargetOffsets.js +38 -0
  289. package/positioning/esm5/utils/getViewportOffsetRectRelativeToArtbitraryNode.js +30 -0
  290. package/positioning/esm5/utils/getWindowSizes.js +34 -0
  291. package/positioning/esm5/utils/includeScroll.js +24 -0
  292. package/positioning/esm5/utils/index.js +28 -0
  293. package/positioning/esm5/utils/isBrowser.js +7 -0
  294. package/positioning/esm5/utils/isFixed.js +22 -0
  295. package/positioning/esm5/utils/isIE.js +22 -0
  296. package/positioning/esm5/utils/isNumeric.js +14 -0
  297. package/positioning/esm5/utils/isOffsetContainer.js +18 -0
  298. package/positioning/esm5/utils/setAllStyles.js +55 -0
  299. package/positioning/esm5/utils/setStyles.js +28 -0
  300. package/positioning/fesm2015/ngx-bootstrap-positioning.js +1108 -211
  301. package/positioning/fesm2015/ngx-bootstrap-positioning.js.map +1 -1
  302. package/positioning/fesm5/ngx-bootstrap-positioning.js +1148 -249
  303. package/positioning/fesm5/ngx-bootstrap-positioning.js.map +1 -1
  304. package/positioning/models/index.d.ts +27 -0
  305. package/positioning/modifiers/arrow.d.ts +2 -0
  306. package/positioning/modifiers/flip.d.ts +2 -0
  307. package/positioning/modifiers/index.d.ts +5 -0
  308. package/positioning/modifiers/initData.d.ts +2 -0
  309. package/positioning/modifiers/preventOverflow.d.ts +2 -0
  310. package/positioning/modifiers/shift.d.ts +2 -0
  311. package/positioning/ng-positioning.d.ts +7 -10
  312. package/positioning/ngx-bootstrap-positioning.metadata.json +1 -1
  313. package/positioning/package.json +1 -1
  314. package/positioning/positioning.service.d.ts +7 -1
  315. package/positioning/utils/computeAutoPlacement.d.ts +2 -0
  316. package/positioning/utils/findCommonOffsetParent.d.ts +1 -0
  317. package/positioning/utils/getBordersSize.d.ts +4 -0
  318. package/positioning/utils/getBoundaries.d.ts +1 -0
  319. package/positioning/utils/getBoundingClientRect.d.ts +2 -0
  320. package/positioning/utils/getClientRect.d.ts +5 -0
  321. package/positioning/utils/getFixedPositionOffsetParent.d.ts +1 -0
  322. package/positioning/utils/getOffsetParent.d.ts +1 -0
  323. package/positioning/utils/getOffsetRectRelativeToArbitraryNode.d.ts +2 -0
  324. package/positioning/utils/getOffsets.d.ts +2 -0
  325. package/positioning/utils/getOppositePlacement.d.ts +4 -0
  326. package/positioning/utils/getOppositeVariation.d.ts +4 -0
  327. package/positioning/utils/getOuterSizes.d.ts +7 -0
  328. package/positioning/utils/getParentNode.d.ts +4 -0
  329. package/positioning/utils/getReferenceOffsets.d.ts +2 -0
  330. package/positioning/utils/getRoot.d.ts +4 -0
  331. package/positioning/utils/getScroll.d.ts +4 -0
  332. package/positioning/utils/getScrollParent.d.ts +1 -0
  333. package/positioning/utils/getStyleComputedProperty.d.ts +4 -0
  334. package/positioning/utils/getTargetOffsets.d.ts +2 -0
  335. package/positioning/utils/getViewportOffsetRectRelativeToArtbitraryNode.d.ts +2 -0
  336. package/positioning/utils/getWindowSizes.d.ts +4 -0
  337. package/positioning/utils/includeScroll.d.ts +2 -0
  338. package/positioning/utils/index.d.ts +22 -0
  339. package/positioning/utils/isBrowser.d.ts +1 -0
  340. package/positioning/utils/isFixed.d.ts +1 -0
  341. package/positioning/utils/isIE.d.ts +1 -0
  342. package/positioning/utils/isNumeric.d.ts +4 -0
  343. package/positioning/utils/isOffsetContainer.d.ts +1 -0
  344. package/positioning/utils/setAllStyles.d.ts +6 -0
  345. package/positioning/utils/setStyles.d.ts +5 -0
  346. package/progressbar/package.json +1 -1
  347. package/rating/bundles/ngx-bootstrap-rating.umd.js +3 -1
  348. package/rating/bundles/ngx-bootstrap-rating.umd.js.map +1 -1
  349. package/rating/bundles/ngx-bootstrap-rating.umd.min.js.map +1 -1
  350. package/rating/esm2015/rating.component.js +3 -1
  351. package/rating/esm5/rating.component.js +3 -1
  352. package/rating/fesm2015/ngx-bootstrap-rating.js +3 -1
  353. package/rating/fesm2015/ngx-bootstrap-rating.js.map +1 -1
  354. package/rating/fesm5/ngx-bootstrap-rating.js +3 -1
  355. package/rating/fesm5/ngx-bootstrap-rating.js.map +1 -1
  356. package/rating/package.json +1 -1
  357. package/schematics/ng-add/index.js +17 -9
  358. package/schematics/ng-add/index.js.map +1 -1
  359. package/schematics/ng-add/index.spec.js +2 -3
  360. package/schematics/ng-add/index.spec.js.map +1 -1
  361. package/sortable/package.json +1 -1
  362. package/tabs/package.json +1 -1
  363. package/timepicker/bundles/ngx-bootstrap-timepicker.umd.js +3 -1
  364. package/timepicker/bundles/ngx-bootstrap-timepicker.umd.js.map +1 -1
  365. package/timepicker/bundles/ngx-bootstrap-timepicker.umd.min.js +1 -1
  366. package/timepicker/bundles/ngx-bootstrap-timepicker.umd.min.js.map +1 -1
  367. package/timepicker/esm2015/timepicker.component.js +5 -1
  368. package/timepicker/esm5/timepicker.component.js +5 -1
  369. package/timepicker/fesm2015/ngx-bootstrap-timepicker.js +3 -1
  370. package/timepicker/fesm2015/ngx-bootstrap-timepicker.js.map +1 -1
  371. package/timepicker/fesm5/ngx-bootstrap-timepicker.js +3 -1
  372. package/timepicker/fesm5/ngx-bootstrap-timepicker.js.map +1 -1
  373. package/timepicker/ngx-bootstrap-timepicker.metadata.json +1 -1
  374. package/timepicker/package.json +1 -1
  375. package/timepicker/timepicker.component.d.ts +1 -0
  376. package/tooltip/bundles/ngx-bootstrap-tooltip.umd.js +15 -4
  377. package/tooltip/bundles/ngx-bootstrap-tooltip.umd.js.map +1 -1
  378. package/tooltip/bundles/ngx-bootstrap-tooltip.umd.min.js +1 -1
  379. package/tooltip/bundles/ngx-bootstrap-tooltip.umd.min.js.map +1 -1
  380. package/tooltip/esm2015/tooltip-container.component.js +15 -7
  381. package/tooltip/esm2015/tooltip.config.js +10 -1
  382. package/tooltip/esm2015/tooltip.directive.js +13 -4
  383. package/tooltip/esm5/tooltip-container.component.js +6 -2
  384. package/tooltip/esm5/tooltip.config.js +10 -1
  385. package/tooltip/esm5/tooltip.directive.js +13 -4
  386. package/tooltip/fesm2015/ngx-bootstrap-tooltip.js +25 -10
  387. package/tooltip/fesm2015/ngx-bootstrap-tooltip.js.map +1 -1
  388. package/tooltip/fesm5/ngx-bootstrap-tooltip.js +16 -5
  389. package/tooltip/fesm5/ngx-bootstrap-tooltip.js.map +1 -1
  390. package/tooltip/ngx-bootstrap-tooltip.metadata.json +1 -1
  391. package/tooltip/package.json +1 -1
  392. package/tooltip/tooltip-container.component.d.ts +1 -0
  393. package/tooltip/tooltip.config.d.ts +2 -0
  394. package/tooltip/tooltip.directive.d.ts +2 -0
  395. package/typeahead/bundles/ngx-bootstrap-typeahead.umd.js +93 -35
  396. package/typeahead/bundles/ngx-bootstrap-typeahead.umd.js.map +1 -1
  397. package/typeahead/bundles/ngx-bootstrap-typeahead.umd.min.js +1 -1
  398. package/typeahead/bundles/ngx-bootstrap-typeahead.umd.min.js.map +1 -1
  399. package/typeahead/esm2015/ngx-bootstrap-typeahead.js +2 -2
  400. package/typeahead/esm2015/public_api.js +2 -1
  401. package/typeahead/esm2015/typeahead-container.component.js +15 -4
  402. package/typeahead/esm2015/typeahead.config.js +55 -0
  403. package/typeahead/esm2015/typeahead.directive.js +68 -32
  404. package/typeahead/esm2015/typeahead.module.js +3 -2
  405. package/typeahead/esm5/ngx-bootstrap-typeahead.js +2 -2
  406. package/typeahead/esm5/public_api.js +2 -1
  407. package/typeahead/esm5/typeahead-container.component.js +12 -4
  408. package/typeahead/esm5/typeahead.config.js +57 -0
  409. package/typeahead/esm5/typeahead.directive.js +69 -34
  410. package/typeahead/esm5/typeahead.module.js +3 -2
  411. package/typeahead/fesm2015/ngx-bootstrap-typeahead.js +96 -36
  412. package/typeahead/fesm2015/ngx-bootstrap-typeahead.js.map +1 -1
  413. package/typeahead/fesm5/ngx-bootstrap-typeahead.js +95 -38
  414. package/typeahead/fesm5/ngx-bootstrap-typeahead.js.map +1 -1
  415. package/typeahead/ngx-bootstrap-typeahead.metadata.json +1 -1
  416. package/typeahead/package.json +1 -1
  417. package/typeahead/public_api.d.ts +1 -0
  418. package/typeahead/typeahead-container.component.d.ts +1 -1
  419. package/typeahead/typeahead.config.d.ts +11 -0
  420. package/typeahead/typeahead.directive.d.ts +14 -5
  421. package/utils/bundles/ngx-bootstrap-utils.umd.js +31 -11
  422. package/utils/bundles/ngx-bootstrap-utils.umd.js.map +1 -1
  423. package/utils/bundles/ngx-bootstrap-utils.umd.min.js +1 -1
  424. package/utils/bundles/ngx-bootstrap-utils.umd.min.js.map +1 -1
  425. package/utils/esm2015/facade/browser.js +13 -14
  426. package/utils/esm2015/ngx-bootstrap-utils.js +2 -2
  427. package/utils/esm2015/public_api.js +2 -2
  428. package/utils/esm2015/triggers.js +23 -1
  429. package/utils/esm5/facade/browser.js +10 -11
  430. package/utils/esm5/ngx-bootstrap-utils.js +2 -2
  431. package/utils/esm5/public_api.js +2 -2
  432. package/utils/esm5/triggers.js +23 -1
  433. package/utils/facade/browser.d.ts +5 -5
  434. package/utils/fesm2015/ngx-bootstrap-utils.js +34 -15
  435. package/utils/fesm2015/ngx-bootstrap-utils.js.map +1 -1
  436. package/utils/fesm5/ngx-bootstrap-utils.js +31 -12
  437. package/utils/fesm5/ngx-bootstrap-utils.js.map +1 -1
  438. package/utils/ngx-bootstrap-utils.metadata.json +1 -1
  439. package/utils/package.json +1 -1
  440. package/utils/public_api.d.ts +1 -1
  441. package/utils/triggers.d.ts +2 -0
@@ -1,286 +1,1148 @@
1
- import { Injectable, ElementRef } from '@angular/core';
1
+ import { __assign } from 'tslib';
2
+ import { Injectable, ElementRef, RendererFactory2 } from '@angular/core';
3
+ import { fromEvent, merge, of, animationFrameScheduler, Subject } from 'rxjs';
2
4
 
3
5
  /**
4
6
  * @fileoverview added by tsickle
5
7
  * @suppress {checkTypes} checked by tsc
6
8
  */
7
9
  /**
8
- * @copyright Valor Software
9
- * @copyright Angular ng-bootstrap team
10
+ * Get CSS computed property of the given element
11
+ * @param {?} element
12
+ * @param {?=} property
13
+ * @return {?}
14
+ */
15
+ function getStyleComputedProperty(element, property) {
16
+ if (element.nodeType !== 1) {
17
+ return [];
18
+ }
19
+ // NOTE: 1 DOM access here
20
+ var /** @type {?} */ window = element.ownerDocument.defaultView;
21
+ var /** @type {?} */ css = window.getComputedStyle(element, null);
22
+ return property ? css[property] : css;
23
+ }
24
+
25
+ /**
26
+ * @fileoverview added by tsickle
27
+ * @suppress {checkTypes} checked by tsc
28
+ */
29
+ /**
30
+ * Returns the parentNode or the host of the element
31
+ * @param {?} element
32
+ * @return {?}
33
+ */
34
+ function getParentNode(element) {
35
+ if (element.nodeName === 'HTML') {
36
+ return element;
37
+ }
38
+ return element.parentNode || element.host;
39
+ }
40
+
41
+ /**
42
+ * @fileoverview added by tsickle
43
+ * @suppress {checkTypes} checked by tsc
44
+ */
45
+ /**
46
+ * @param {?} element
47
+ * @return {?}
48
+ */
49
+ function getScrollParent(element) {
50
+ // Return body, `getScroll` will take care to get the correct `scrollTop` from it
51
+ if (!element) {
52
+ return document.body;
53
+ }
54
+ switch (element.nodeName) {
55
+ case 'HTML':
56
+ case 'BODY':
57
+ return element.ownerDocument.body;
58
+ case '#document':
59
+ return element.body;
60
+ default:
61
+ }
62
+ // Firefox want us to check `-x` and `-y` variations as well
63
+ var _a = getStyleComputedProperty(element), overflow = _a.overflow, overflowX = _a.overflowX, overflowY = _a.overflowY;
64
+ if (/(auto|scroll|overlay)/.test(String(overflow) + String(overflowY) + String(overflowX))) {
65
+ return element;
66
+ }
67
+ return getScrollParent(getParentNode(element));
68
+ }
69
+
70
+ /**
71
+ * @fileoverview added by tsickle
72
+ * @suppress {checkTypes} checked by tsc
73
+ */
74
+ var /** @type {?} */ isBrowser = typeof window !== 'undefined' && typeof document !== 'undefined';
75
+
76
+ /**
77
+ * @fileoverview added by tsickle
78
+ * @suppress {checkTypes} checked by tsc
79
+ */
80
+ var /** @type {?} */ isIE11 = isBrowser && !!((/** @type {?} */ (window)).MSInputMethodContext && (/** @type {?} */ (document)).documentMode);
81
+ var /** @type {?} */ isIE10 = isBrowser && /MSIE 10/.test(navigator.userAgent);
82
+ /**
83
+ * @param {?=} version
84
+ * @return {?}
85
+ */
86
+ function isIE(version) {
87
+ if (version === 11) {
88
+ return isIE11;
89
+ }
90
+ if (version === 10) {
91
+ return isIE10;
92
+ }
93
+ return isIE11 || isIE10;
94
+ }
95
+
96
+ /**
97
+ * @fileoverview added by tsickle
98
+ * @suppress {checkTypes} checked by tsc
99
+ */
100
+ /**
101
+ * @param {?} element
102
+ * @return {?}
103
+ */
104
+ function getOffsetParent(element) {
105
+ if (!element) {
106
+ return document.documentElement;
107
+ }
108
+ var /** @type {?} */ noOffsetParent = isIE(10) ? document.body : null;
109
+ // NOTE: 1 DOM access here
110
+ var /** @type {?} */ offsetParent = element.offsetParent || null;
111
+ // Skip hidden elements which don't have an offsetParent
112
+ var /** @type {?} */ sibling;
113
+ while (offsetParent === noOffsetParent && element.nextElementSibling) {
114
+ sibling = element.nextElementSibling;
115
+ offsetParent = sibling.offsetParent;
116
+ }
117
+ var /** @type {?} */ nodeName = offsetParent && offsetParent.nodeName;
118
+ if (!nodeName || nodeName === 'BODY' || nodeName === 'HTML') {
119
+ return sibling ? sibling.ownerDocument.documentElement : document.documentElement;
120
+ }
121
+ // .offsetParent will return the closest TH, TD or TABLE in case
122
+ // no offsetParent is present, I hate this job...
123
+ if (['TH', 'TD', 'TABLE'].indexOf(offsetParent.nodeName) !== -1 &&
124
+ getStyleComputedProperty(offsetParent, 'position') === 'static') {
125
+ return getOffsetParent(offsetParent);
126
+ }
127
+ return offsetParent;
128
+ }
129
+
130
+ /**
131
+ * @fileoverview added by tsickle
132
+ * @suppress {checkTypes} checked by tsc
133
+ */
134
+ /**
135
+ * @param {?} element
136
+ * @return {?}
137
+ */
138
+ function isOffsetContainer(element) {
139
+ var nodeName = element.nodeName;
140
+ if (nodeName === 'BODY') {
141
+ return false;
142
+ }
143
+ return (nodeName === 'HTML' || getOffsetParent(element.firstElementChild) === element);
144
+ }
145
+
146
+ /**
147
+ * @fileoverview added by tsickle
148
+ * @suppress {checkTypes} checked by tsc
149
+ */
150
+ /**
151
+ * Finds the root node (document, shadowDOM root) of the given element
152
+ * @param {?} node
153
+ * @return {?}
154
+ */
155
+ function getRoot(node) {
156
+ if (node.parentNode !== null) {
157
+ return getRoot(node.parentNode);
158
+ }
159
+ return node;
160
+ }
161
+
162
+ /**
163
+ * @fileoverview added by tsickle
164
+ * @suppress {checkTypes} checked by tsc
165
+ */
166
+ /**
167
+ * @param {?} element1
168
+ * @param {?} element2
169
+ * @return {?}
170
+ */
171
+ function findCommonOffsetParent(element1, element2) {
172
+ // This check is needed to avoid errors in case one of the elements isn't defined for any reason
173
+ if (!element1 || !element1.nodeType || !element2 || !element2.nodeType) {
174
+ return document.documentElement;
175
+ }
176
+ // Here we make sure to give as "start" the element that comes first in the DOM
177
+ /* tslint:disable-next-line: no-bitwise */
178
+ var /** @type {?} */ order = element1.compareDocumentPosition(element2) & Node.DOCUMENT_POSITION_FOLLOWING;
179
+ var /** @type {?} */ start = order ? element1 : element2;
180
+ var /** @type {?} */ end = order ? element2 : element1;
181
+ // Get common ancestor container
182
+ var /** @type {?} */ range = document.createRange();
183
+ range.setStart(start, 0);
184
+ range.setEnd(end, 0);
185
+ var commonAncestorContainer = range.commonAncestorContainer;
186
+ // Both nodes are inside #document
187
+ if ((element1 !== commonAncestorContainer &&
188
+ element2 !== commonAncestorContainer) ||
189
+ start.contains(end)) {
190
+ if (isOffsetContainer(commonAncestorContainer)) {
191
+ return commonAncestorContainer;
192
+ }
193
+ return getOffsetParent(commonAncestorContainer);
194
+ }
195
+ // one of the nodes is inside shadowDOM, find which one
196
+ var /** @type {?} */ element1root = getRoot(element1);
197
+ if (element1root.host) {
198
+ return findCommonOffsetParent(element1root.host, element2);
199
+ }
200
+ else {
201
+ return findCommonOffsetParent(element1, getRoot(element2).host);
202
+ }
203
+ }
204
+
205
+ /**
206
+ * @fileoverview added by tsickle
207
+ * @suppress {checkTypes} checked by tsc
208
+ */
209
+ /**
210
+ * Helper to detect borders of a given element
211
+ */
212
+ /**
213
+ * @param {?} styles
214
+ * @param {?} axis
215
+ * @return {?}
216
+ */
217
+ function getBordersSize(styles, axis) {
218
+ var /** @type {?} */ sideA = axis === 'x' ? 'Left' : 'Top';
219
+ var /** @type {?} */ sideB = sideA === 'Left' ? 'Right' : 'Bottom';
220
+ return (parseFloat(styles["border" + sideA + "Width"]) +
221
+ parseFloat(styles["border" + sideB + "Width"]));
222
+ }
223
+
224
+ /**
225
+ * @fileoverview added by tsickle
226
+ * @suppress {checkTypes} checked by tsc
227
+ */
228
+ /**
229
+ * @param {?} axis
230
+ * @param {?} body
231
+ * @param {?} html
232
+ * @param {?} computedStyle
233
+ * @return {?}
234
+ */
235
+ function getSize(axis, body, html, computedStyle) {
236
+ return Math.max(body["offset" + axis], body["scroll" + axis], html["client" + axis], html["offset" + axis], html["scroll" + axis], isIE(10)
237
+ ? (parseInt(html["offset" + axis], 10) +
238
+ parseInt(computedStyle["margin" + (axis === 'Height' ? 'Top' : 'Left')], 10) +
239
+ parseInt(computedStyle["margin" + (axis === 'Height' ? 'Bottom' : 'Right')], 10))
240
+ : 0);
241
+ }
242
+ /**
243
+ * @param {?} document
244
+ * @return {?}
245
+ */
246
+ function getWindowSizes(document) {
247
+ var /** @type {?} */ body = document.body;
248
+ var /** @type {?} */ html = document.documentElement;
249
+ var /** @type {?} */ computedStyle = isIE(10) && getComputedStyle(html);
250
+ return {
251
+ height: getSize('Height', body, html, computedStyle),
252
+ width: getSize('Width', body, html, computedStyle)
253
+ };
254
+ }
255
+
256
+ /**
257
+ * @fileoverview added by tsickle
258
+ * @suppress {checkTypes} checked by tsc
259
+ */
260
+ /**
261
+ * Gets the scroll value of the given element in the given side (top and left)
262
+ * @param {?} element
263
+ * @param {?=} side
264
+ * @return {?}
265
+ */
266
+ function getScroll(element, side) {
267
+ if (side === void 0) { side = 'top'; }
268
+ var /** @type {?} */ upperSide = side === 'top' ? 'scrollTop' : 'scrollLeft';
269
+ var /** @type {?} */ nodeName = element.nodeName;
270
+ if (nodeName === 'BODY' || nodeName === 'HTML') {
271
+ var /** @type {?} */ html = element.ownerDocument.documentElement;
272
+ var /** @type {?} */ scrollingElement = element.ownerDocument.scrollingElement || html;
273
+ return scrollingElement[upperSide];
274
+ }
275
+ return element[upperSide];
276
+ }
277
+
278
+ /**
279
+ * @fileoverview added by tsickle
280
+ * @suppress {checkTypes} checked by tsc
281
+ */
282
+ /**
283
+ * @param {?} offsets
284
+ * @return {?}
285
+ */
286
+ function getClientRect(offsets) {
287
+ return __assign({}, offsets, { right: offsets.left + offsets.width, bottom: offsets.top + offsets.height });
288
+ }
289
+
290
+ /**
291
+ * @fileoverview added by tsickle
292
+ * @suppress {checkTypes} checked by tsc
293
+ */
294
+ /**
295
+ * @param {?} element
296
+ * @return {?}
297
+ */
298
+ function getBoundingClientRect(element) {
299
+ var /** @type {?} */ rect = {};
300
+ // IE10 10 FIX: Please, don't ask, the element isn't
301
+ // considered in DOM in some circumstances...
302
+ // This isn't reproducible in IE10 compatibility mode of IE11
303
+ try {
304
+ if (isIE(10)) {
305
+ rect = element.getBoundingClientRect();
306
+ var /** @type {?} */ scrollTop = getScroll(element, 'top');
307
+ var /** @type {?} */ scrollLeft = getScroll(element, 'left');
308
+ rect.top += scrollTop;
309
+ rect.left += scrollLeft;
310
+ rect.bottom += scrollTop;
311
+ rect.right += scrollLeft;
312
+ }
313
+ else {
314
+ rect = element.getBoundingClientRect();
315
+ }
316
+ }
317
+ catch (/** @type {?} */ e) {
318
+ return undefined;
319
+ }
320
+ var /** @type {?} */ result = {
321
+ left: rect.left,
322
+ top: rect.top,
323
+ width: rect.right - rect.left,
324
+ height: rect.bottom - rect.top
325
+ };
326
+ // subtract scrollbar size from sizes
327
+ var /** @type {?} */ sizes = element.nodeName === 'HTML' ? getWindowSizes(element.ownerDocument) : {};
328
+ var /** @type {?} */ width = sizes.width || element.clientWidth || result.right - result.left;
329
+ var /** @type {?} */ height = sizes.height || element.clientHeight || result.bottom - result.top;
330
+ var /** @type {?} */ horizScrollbar = element.offsetWidth - width;
331
+ var /** @type {?} */ vertScrollbar = element.offsetHeight - height;
332
+ // if an hypothetical scrollbar is detected, we must be sure it's not a `border`
333
+ // we make this check conditional for performance reasons
334
+ if (horizScrollbar || vertScrollbar) {
335
+ var /** @type {?} */ styles = getStyleComputedProperty(element);
336
+ horizScrollbar -= getBordersSize(styles, 'x');
337
+ vertScrollbar -= getBordersSize(styles, 'y');
338
+ result.width -= horizScrollbar;
339
+ result.height -= vertScrollbar;
340
+ }
341
+ return getClientRect(result);
342
+ }
343
+
344
+ /**
345
+ * @fileoverview added by tsickle
346
+ * @suppress {checkTypes} checked by tsc
347
+ */
348
+ /**
349
+ * @param {?} rect
350
+ * @param {?} element
351
+ * @param {?=} subtract
352
+ * @return {?}
353
+ */
354
+ function includeScroll(rect, element, subtract) {
355
+ if (subtract === void 0) { subtract = false; }
356
+ var /** @type {?} */ scrollTop = getScroll(element, 'top');
357
+ var /** @type {?} */ scrollLeft = getScroll(element, 'left');
358
+ var /** @type {?} */ modifier = subtract ? -1 : 1;
359
+ rect.top += scrollTop * modifier;
360
+ rect.bottom += scrollTop * modifier;
361
+ rect.left += scrollLeft * modifier;
362
+ rect.right += scrollLeft * modifier;
363
+ return rect;
364
+ }
365
+
366
+ /**
367
+ * @fileoverview added by tsickle
368
+ * @suppress {checkTypes} checked by tsc
369
+ */
370
+ /**
371
+ * @param {?} children
372
+ * @param {?} parent
373
+ * @param {?=} fixedPosition
374
+ * @return {?}
375
+ */
376
+ function getOffsetRectRelativeToArbitraryNode(children, parent, fixedPosition) {
377
+ if (fixedPosition === void 0) { fixedPosition = false; }
378
+ var /** @type {?} */ isIE10 = isIE(10);
379
+ var /** @type {?} */ isHTML = parent.nodeName === 'HTML';
380
+ var /** @type {?} */ childrenRect = getBoundingClientRect(children);
381
+ var /** @type {?} */ parentRect = getBoundingClientRect(parent);
382
+ var /** @type {?} */ scrollParent = getScrollParent(children);
383
+ var /** @type {?} */ styles = getStyleComputedProperty(parent);
384
+ var /** @type {?} */ borderTopWidth = parseFloat(styles.borderTopWidth);
385
+ var /** @type {?} */ borderLeftWidth = parseFloat(styles.borderLeftWidth);
386
+ // In cases where the parent is fixed, we must ignore negative scroll in offset calc
387
+ if (fixedPosition && isHTML) {
388
+ parentRect.top = Math.max(parentRect.top, 0);
389
+ parentRect.left = Math.max(parentRect.left, 0);
390
+ }
391
+ var /** @type {?} */ offsets = getClientRect({
392
+ top: childrenRect.top - parentRect.top - borderTopWidth,
393
+ left: childrenRect.left - parentRect.left - borderLeftWidth,
394
+ width: childrenRect.width,
395
+ height: childrenRect.height
396
+ });
397
+ offsets.marginTop = 0;
398
+ offsets.marginLeft = 0;
399
+ // Subtract margins of documentElement in case it's being used as parent
400
+ // we do this only on HTML because it's the only element that behaves
401
+ // differently when margins are applied to it. The margins are included in
402
+ // the box of the documentElement, in the other cases not.
403
+ if (!isIE10 && isHTML) {
404
+ var /** @type {?} */ marginTop = parseFloat(styles.marginTop);
405
+ var /** @type {?} */ marginLeft = parseFloat(styles.marginLeft);
406
+ offsets.top -= borderTopWidth - marginTop;
407
+ offsets.bottom -= borderTopWidth - marginTop;
408
+ offsets.left -= borderLeftWidth - marginLeft;
409
+ offsets.right -= borderLeftWidth - marginLeft;
410
+ // Attach marginTop and marginLeft because in some circumstances we may need them
411
+ offsets.marginTop = marginTop;
412
+ offsets.marginLeft = marginLeft;
413
+ }
414
+ if (isIE10 && !fixedPosition
415
+ ? parent.contains(scrollParent)
416
+ : parent === scrollParent && scrollParent.nodeName !== 'BODY') {
417
+ offsets = includeScroll(offsets, parent);
418
+ }
419
+ return offsets;
420
+ }
421
+
422
+ /**
423
+ * @fileoverview added by tsickle
424
+ * @suppress {checkTypes} checked by tsc
425
+ */
426
+ /**
427
+ * @param {?} element
428
+ * @param {?=} excludeScroll
429
+ * @return {?}
430
+ */
431
+ function getViewportOffsetRectRelativeToArtbitraryNode(element, excludeScroll) {
432
+ if (excludeScroll === void 0) { excludeScroll = false; }
433
+ var /** @type {?} */ html = element.ownerDocument.documentElement;
434
+ var /** @type {?} */ relativeOffset = getOffsetRectRelativeToArbitraryNode(element, html);
435
+ var /** @type {?} */ width = Math.max(html.clientWidth, window.innerWidth || 0);
436
+ var /** @type {?} */ height = Math.max(html.clientHeight, window.innerHeight || 0);
437
+ var /** @type {?} */ scrollTop = !excludeScroll ? getScroll(html) : 0;
438
+ var /** @type {?} */ scrollLeft = !excludeScroll ? getScroll(html, 'left') : 0;
439
+ var /** @type {?} */ offset = {
440
+ top: scrollTop - Number(relativeOffset.top) + Number(relativeOffset.marginTop),
441
+ left: scrollLeft - Number(relativeOffset.left) + Number(relativeOffset.marginLeft),
442
+ width: width,
443
+ height: height
444
+ };
445
+ return getClientRect(offset);
446
+ }
447
+
448
+ /**
449
+ * @fileoverview added by tsickle
450
+ * @suppress {checkTypes} checked by tsc
451
+ */
452
+ /**
453
+ * @param {?} element
454
+ * @return {?}
455
+ */
456
+ function isFixed(element) {
457
+ var /** @type {?} */ nodeName = element.nodeName;
458
+ if (nodeName === 'BODY' || nodeName === 'HTML') {
459
+ return false;
460
+ }
461
+ if (getStyleComputedProperty(element, 'position') === 'fixed') {
462
+ return true;
463
+ }
464
+ return isFixed(getParentNode(element));
465
+ }
466
+
467
+ /**
468
+ * @fileoverview added by tsickle
469
+ * @suppress {checkTypes} checked by tsc
470
+ */
471
+ /**
472
+ * @param {?} element
473
+ * @return {?}
474
+ */
475
+ function getFixedPositionOffsetParent(element) {
476
+ // This check is needed to avoid errors in case one of the elements isn't defined for any reason
477
+ if (!element || !element.parentElement || isIE()) {
478
+ return document.documentElement;
479
+ }
480
+ var /** @type {?} */ el = element.parentElement;
481
+ while (el && getStyleComputedProperty(el, 'transform') === 'none') {
482
+ el = el.parentElement;
483
+ }
484
+ return el || document.documentElement;
485
+ }
486
+
487
+ /**
488
+ * @fileoverview added by tsickle
489
+ * @suppress {checkTypes} checked by tsc
490
+ */
491
+ /**
492
+ * @param {?} target
493
+ * @param {?} host
494
+ * @param {?=} padding
495
+ * @param {?=} boundariesElement
496
+ * @param {?=} fixedPosition
497
+ * @return {?}
498
+ */
499
+ function getBoundaries(target, host, padding, boundariesElement, fixedPosition) {
500
+ if (padding === void 0) { padding = 0; }
501
+ if (fixedPosition === void 0) { fixedPosition = false; }
502
+ // NOTE: 1 DOM access here
503
+ var /** @type {?} */ boundaries = { top: 0, left: 0 };
504
+ var /** @type {?} */ offsetParent = fixedPosition ? getFixedPositionOffsetParent(target) : findCommonOffsetParent(target, host);
505
+ // Handle viewport case
506
+ if (boundariesElement === 'viewport') {
507
+ boundaries = getViewportOffsetRectRelativeToArtbitraryNode(offsetParent, fixedPosition);
508
+ }
509
+ else {
510
+ // Handle other cases based on DOM element used as boundaries
511
+ var /** @type {?} */ boundariesNode = void 0;
512
+ if (boundariesElement === 'scrollParent') {
513
+ boundariesNode = getScrollParent(getParentNode(host));
514
+ if (boundariesNode.nodeName === 'BODY') {
515
+ boundariesNode = target.ownerDocument.documentElement;
516
+ }
517
+ }
518
+ else if (boundariesElement === 'window') {
519
+ boundariesNode = target.ownerDocument.documentElement;
520
+ }
521
+ else {
522
+ boundariesNode = boundariesElement;
523
+ }
524
+ var /** @type {?} */ offsets = getOffsetRectRelativeToArbitraryNode(boundariesNode, offsetParent, fixedPosition);
525
+ // In case of HTML, we need a different computation
526
+ if (boundariesNode.nodeName === 'HTML' && !isFixed(offsetParent)) {
527
+ var _a = getWindowSizes(target.ownerDocument), height = _a.height, width = _a.width;
528
+ boundaries.top += offsets.top - offsets.marginTop;
529
+ boundaries.bottom = Number(height) + Number(offsets.top);
530
+ boundaries.left += offsets.left - offsets.marginLeft;
531
+ boundaries.right = Number(width) + Number(offsets.left);
532
+ }
533
+ else {
534
+ // for all the other DOM elements, this one is good
535
+ boundaries = offsets;
536
+ }
537
+ }
538
+ // Add paddings
539
+ boundaries.left += padding;
540
+ boundaries.top += padding;
541
+ boundaries.right -= padding;
542
+ boundaries.bottom -= padding;
543
+ return boundaries;
544
+ }
545
+
546
+ /**
547
+ * @fileoverview added by tsickle
548
+ * @suppress {checkTypes} checked by tsc
549
+ */
550
+ /**
551
+ * @param {?} __0
552
+ * @return {?}
553
+ */
554
+ function getArea(_a) {
555
+ var width = _a.width, height = _a.height;
556
+ return width * height;
557
+ }
558
+ /**
559
+ * @param {?} placement
560
+ * @param {?} refRect
561
+ * @param {?} target
562
+ * @param {?} host
563
+ * @param {?} boundariesElement
564
+ * @param {?=} padding
565
+ * @return {?}
566
+ */
567
+ function computeAutoPlacement(placement, refRect, target, host, boundariesElement, padding) {
568
+ if (padding === void 0) { padding = 0; }
569
+ if (placement.indexOf('auto') === -1) {
570
+ return placement;
571
+ }
572
+ if (placement.indexOf('auto') !== -1
573
+ && (placement.indexOf('left') !== -1
574
+ || placement.indexOf('right') !== -1
575
+ || placement.indexOf('top') !== -1
576
+ || placement.indexOf('bottom') !== -1)) {
577
+ return placement.split(' ')[1] || '';
578
+ }
579
+ var /** @type {?} */ boundaries = getBoundaries(target, host, padding, boundariesElement);
580
+ var /** @type {?} */ rects = {
581
+ top: {
582
+ width: boundaries.width,
583
+ height: refRect.top - boundaries.top
584
+ },
585
+ right: {
586
+ width: boundaries.right - refRect.right,
587
+ height: boundaries.height
588
+ },
589
+ bottom: {
590
+ width: boundaries.width,
591
+ height: boundaries.bottom - refRect.bottom
592
+ },
593
+ left: {
594
+ width: refRect.left - boundaries.left,
595
+ height: boundaries.height
596
+ }
597
+ };
598
+ var /** @type {?} */ sortedAreas = Object.keys(rects)
599
+ .map(function (key) {
600
+ return (__assign({ key: key }, rects[key], { area: getArea(rects[key]) }));
601
+ })
602
+ .sort(function (a, b) { return b.area - a.area; });
603
+ var /** @type {?} */ filteredAreas = sortedAreas.filter(function (_a) {
604
+ var width = _a.width, height = _a.height;
605
+ return width >= target.clientWidth && height >= target.clientHeight;
606
+ });
607
+ var /** @type {?} */ computedPlacement = filteredAreas.length > 0
608
+ ? filteredAreas[0].key
609
+ : sortedAreas[0].key;
610
+ var /** @type {?} */ variation = placement.split(' ')[1];
611
+ target.className = target.className.replace(/auto/g, computedPlacement);
612
+ return computedPlacement + (variation ? "-" + variation : '');
613
+ }
614
+
615
+ /**
616
+ * @fileoverview added by tsickle
617
+ * @suppress {checkTypes} checked by tsc
618
+ */
619
+ /**
620
+ * @param {?} data
621
+ * @return {?}
622
+ */
623
+ function getOffsets(data) {
624
+ return {
625
+ width: data.offsets.target.width,
626
+ height: data.offsets.target.height,
627
+ left: Math.floor(data.offsets.target.left),
628
+ top: Math.round(data.offsets.target.top),
629
+ bottom: Math.round(data.offsets.target.bottom),
630
+ right: Math.floor(data.offsets.target.right)
631
+ };
632
+ }
633
+
634
+ /**
635
+ * @fileoverview added by tsickle
636
+ * @suppress {checkTypes} checked by tsc
637
+ */
638
+ /**
639
+ * Get the opposite placement of the given one
640
+ * @param {?} placement
641
+ * @return {?}
642
+ */
643
+ function getOppositePlacement(placement) {
644
+ var /** @type {?} */ hash = { left: 'right', right: 'left', bottom: 'top', top: 'bottom' };
645
+ return placement.replace(/left|right|bottom|top/g, function (matched) { return hash[matched]; });
646
+ }
647
+
648
+ /**
649
+ * @fileoverview added by tsickle
650
+ * @suppress {checkTypes} checked by tsc
651
+ */
652
+ /**
653
+ * Get the opposite placement variation of the given one
654
+ * @param {?} variation
655
+ * @return {?}
656
+ */
657
+ function getOppositeVariation(variation) {
658
+ if (variation === 'right') {
659
+ return 'left';
660
+ }
661
+ else if (variation === 'left') {
662
+ return 'right';
663
+ }
664
+ return variation;
665
+ }
666
+
667
+ /**
668
+ * @fileoverview added by tsickle
669
+ * @suppress {checkTypes} checked by tsc
670
+ */
671
+ /**
672
+ * Get the outer sizes of the given element (offset size + margins)
673
+ * @param {?} element
674
+ * @return {?}
675
+ */
676
+ function getOuterSizes(element) {
677
+ var /** @type {?} */ window = element.ownerDocument.defaultView;
678
+ var /** @type {?} */ styles = window.getComputedStyle(element);
679
+ var /** @type {?} */ x = parseFloat(styles.marginTop || 0) + parseFloat(styles.marginBottom || 0);
680
+ var /** @type {?} */ y = parseFloat(styles.marginLeft || 0) + parseFloat(styles.marginRight || 0);
681
+ return {
682
+ width: Number(element.offsetWidth) + y,
683
+ height: Number(element.offsetHeight) + x
684
+ };
685
+ }
686
+
687
+ /**
688
+ * @fileoverview added by tsickle
689
+ * @suppress {checkTypes} checked by tsc
690
+ */
691
+ /**
692
+ * @param {?} target
693
+ * @param {?} host
694
+ * @param {?=} fixedPosition
695
+ * @return {?}
696
+ */
697
+ function getReferenceOffsets(target, host, fixedPosition) {
698
+ if (fixedPosition === void 0) { fixedPosition = null; }
699
+ var /** @type {?} */ commonOffsetParent = fixedPosition
700
+ ? getFixedPositionOffsetParent(target)
701
+ : findCommonOffsetParent(target, host);
702
+ return getOffsetRectRelativeToArbitraryNode(host, commonOffsetParent, fixedPosition);
703
+ }
704
+
705
+ /**
706
+ * @fileoverview added by tsickle
707
+ * @suppress {checkTypes} checked by tsc
708
+ */
709
+ /**
710
+ * @param {?} target
711
+ * @param {?} hostOffsets
712
+ * @param {?} position
713
+ * @return {?}
714
+ */
715
+ function getTargetOffsets(target, hostOffsets, position) {
716
+ var /** @type {?} */ placement = position.split(' ')[0];
717
+ // Get target node sizes
718
+ var /** @type {?} */ targetRect = getOuterSizes(target);
719
+ // Add position, width and height to our offsets object
720
+ var /** @type {?} */ targetOffsets = {
721
+ width: targetRect.width,
722
+ height: targetRect.height
723
+ };
724
+ // depending by the target placement we have to compute its offsets slightly differently
725
+ var /** @type {?} */ isHoriz = ['right', 'left'].indexOf(placement) !== -1;
726
+ var /** @type {?} */ mainSide = isHoriz ? 'top' : 'left';
727
+ var /** @type {?} */ secondarySide = isHoriz ? 'left' : 'top';
728
+ var /** @type {?} */ measurement = isHoriz ? 'height' : 'width';
729
+ var /** @type {?} */ secondaryMeasurement = !isHoriz ? 'height' : 'width';
730
+ targetOffsets[mainSide] =
731
+ hostOffsets[mainSide] +
732
+ hostOffsets[measurement] / 2 -
733
+ targetRect[measurement] / 2;
734
+ targetOffsets[secondarySide] = placement === secondarySide
735
+ ? hostOffsets[secondarySide] - targetRect[secondaryMeasurement]
736
+ : hostOffsets[getOppositePlacement(secondarySide)];
737
+ return targetOffsets;
738
+ }
739
+
740
+ /**
741
+ * @fileoverview added by tsickle
742
+ * @suppress {checkTypes} checked by tsc
743
+ */
744
+ /**
745
+ * Tells if a given input is a number
746
+ * @param {?} n
747
+ * @return {?}
748
+ */
749
+ function isNumeric(n) {
750
+ return n !== '' && !isNaN(parseFloat(n)) && isFinite(n);
751
+ }
752
+
753
+ /**
754
+ * @fileoverview added by tsickle
755
+ * @suppress {checkTypes} checked by tsc
756
+ */
757
+ /**
758
+ * @param {?} data
759
+ * @param {?=} renderer
760
+ * @return {?}
761
+ */
762
+ function setAllStyles$$1(data, renderer) {
763
+ var /** @type {?} */ target = data.instance.target;
764
+ var /** @type {?} */ offsets = getOffsets(data);
765
+ setStyles(target, {
766
+ 'will-change': 'transform',
767
+ top: '0px',
768
+ left: '0px',
769
+ transform: "translate3d(" + offsets.left + "px, " + offsets.top + "px, 0px)"
770
+ }, renderer);
771
+ if (data.instance.arrow) {
772
+ setStyles(data.instance.arrow, data.offsets.arrow, renderer);
773
+ }
774
+ if (data.placementAuto) {
775
+ if (renderer) {
776
+ renderer.setAttribute(target, 'class', target.className.replace(/bs-popover-auto/g, "bs-popover-" + data.placement));
777
+ renderer.setAttribute(target, 'class', target.className.replace(/bs-tooltip-auto/g, "bs-tooltip-" + data.placement));
778
+ renderer.setAttribute(target, 'class', target.className.replace(/\sauto/g, "s" + data.placement));
779
+ if (target.className.match(/popover/g)) {
780
+ renderer.addClass(target, 'popover-auto');
781
+ }
782
+ if (target.className.match(/tooltip/g)) {
783
+ renderer.addClass(target, 'tooltip-auto');
784
+ }
785
+ }
786
+ else {
787
+ target.className = target.className.replace(/bs-popover-auto/g, "bs-popover-" + data.placement);
788
+ target.className = target.className.replace(/bs-tooltip-auto/g, "bs-tooltip-" + data.placement);
789
+ target.className = target.className.replace(/\sauto/g, "s" + data.placement);
790
+ if (target.className.match(/popover/g)) {
791
+ target.classList.add('popover-auto');
792
+ }
793
+ if (target.className.match(/tooltip/g)) {
794
+ target.classList.add('tooltip-auto');
795
+ }
796
+ }
797
+ }
798
+ if (renderer) {
799
+ renderer.setAttribute(target, 'class', target.className.replace(/left|right|top|bottom/g, "" + data.placement));
800
+ }
801
+ else {
802
+ target.className = target.className.replace(/left|right|top|bottom/g, "" + data.placement);
803
+ }
804
+ }
805
+
806
+ /**
807
+ * @fileoverview added by tsickle
808
+ * @suppress {checkTypes} checked by tsc
809
+ */
810
+ /**
811
+ * @param {?} element
812
+ * @param {?} styles
813
+ * @param {?=} renderer
814
+ * @return {?}
815
+ */
816
+ function setStyles(element, styles, renderer) {
817
+ Object.keys(styles).forEach(function (prop) {
818
+ var /** @type {?} */ unit = '';
819
+ // add unit if the value is numeric and is one of the following
820
+ if (['width', 'height', 'top', 'right', 'bottom', 'left'].indexOf(prop) !== -1 &&
821
+ isNumeric(styles[prop])) {
822
+ unit = 'px';
823
+ }
824
+ if (renderer) {
825
+ renderer.setStyle(element, prop, "" + String(styles[prop]) + unit);
826
+ return;
827
+ }
828
+ element.style[prop] = String(styles[prop]) + unit;
829
+ });
830
+ }
831
+
832
+ /**
833
+ * @fileoverview added by tsickle
834
+ * @suppress {checkTypes} checked by tsc
835
+ */
836
+
837
+ /**
838
+ * @fileoverview added by tsickle
839
+ * @suppress {checkTypes} checked by tsc
840
+ */
841
+ /**
842
+ * @param {?} data
843
+ * @return {?}
844
+ */
845
+ function arrow(data) {
846
+ var /** @type {?} */ targetOffsets = data.offsets.target;
847
+ // if arrowElement is a string, suppose it's a CSS selector
848
+ var /** @type {?} */ arrowElement = data.instance.target.querySelector('.arrow');
849
+ // if arrowElement is not found, don't run the modifier
850
+ if (!arrowElement) {
851
+ return data;
852
+ }
853
+ var /** @type {?} */ isVertical = ['left', 'right'].indexOf(data.placement) !== -1;
854
+ var /** @type {?} */ len = isVertical ? 'height' : 'width';
855
+ var /** @type {?} */ sideCapitalized = isVertical ? 'Top' : 'Left';
856
+ var /** @type {?} */ side = sideCapitalized.toLowerCase();
857
+ var /** @type {?} */ altSide = isVertical ? 'left' : 'top';
858
+ var /** @type {?} */ opSide = isVertical ? 'bottom' : 'right';
859
+ var /** @type {?} */ arrowElementSize = getOuterSizes(arrowElement)[len];
860
+ // top/left side
861
+ if (data.offsets.host[opSide] - arrowElementSize < targetOffsets[side]) {
862
+ targetOffsets[side] -=
863
+ targetOffsets[side] - (data.offsets.host[opSide] - arrowElementSize);
864
+ }
865
+ // bottom/right side
866
+ if (Number(data.offsets.host[side]) + Number(arrowElementSize) > targetOffsets[opSide]) {
867
+ targetOffsets[side] +=
868
+ Number(data.offsets.host[side]) + Number(arrowElementSize) - Number(targetOffsets[opSide]);
869
+ }
870
+ targetOffsets = getClientRect(targetOffsets);
871
+ // compute center of the target
872
+ var /** @type {?} */ center = Number(data.offsets.host[side]) + Number(data.offsets.host[len] / 2 - arrowElementSize / 2);
873
+ // Compute the sideValue using the updated target offsets
874
+ // take target margin in account because we don't have this info available
875
+ var /** @type {?} */ css = getStyleComputedProperty(data.instance.target);
876
+ var /** @type {?} */ targetMarginSide = parseFloat(css["margin" + sideCapitalized]);
877
+ var /** @type {?} */ targetBorderSide = parseFloat(css["border" + sideCapitalized + "Width"]);
878
+ var /** @type {?} */ sideValue = center - targetOffsets[side] - targetMarginSide - targetBorderSide;
879
+ // prevent arrowElement from being placed not contiguously to its target
880
+ sideValue = Math.max(Math.min(targetOffsets[len] - arrowElementSize, sideValue), 0);
881
+ data.offsets.arrow = (_a = {},
882
+ _a[side] = Math.round(sideValue),
883
+ _a[altSide] = '' // make sure to unset any eventual altSide value from the DOM node
884
+ ,
885
+ _a);
886
+ data.instance.arrow = arrowElement;
887
+ return data;
888
+ var _a;
889
+ }
890
+
891
+ /**
892
+ * @fileoverview added by tsickle
893
+ * @suppress {checkTypes} checked by tsc
894
+ */
895
+ /**
896
+ * @param {?} data
897
+ * @return {?}
898
+ */
899
+ function flip(data) {
900
+ data.offsets.target = getClientRect(data.offsets.target);
901
+ var /** @type {?} */ boundaries = getBoundaries(data.instance.target, data.instance.host, 0, // padding
902
+ 'viewport', false // positionFixed
903
+ );
904
+ var /** @type {?} */ placement = data.placement.split(' ')[0];
905
+ var /** @type {?} */ variation = data.placement.split(' ')[1] || '';
906
+ var /** @type {?} */ adaptivePosition = variation
907
+ ? getOppositePlacement(placement)
908
+ : computeAutoPlacement('auto', data.offsets.host, data.instance.target, data.instance.host, 'viewport', 0);
909
+ var /** @type {?} */ flipOrder = [placement, adaptivePosition];
910
+ /* tslint:disable-next-line: cyclomatic-complexity */
911
+ flipOrder.forEach(function (step, index) {
912
+ if (placement !== step || flipOrder.length === index + 1) {
913
+ return data;
914
+ }
915
+ placement = data.placement.split(' ')[0];
916
+ // using floor because the host offsets may contain decimals we are not going to consider here
917
+ var /** @type {?} */ overlapsRef = (placement === 'left' &&
918
+ Math.floor(data.offsets.target.right) > Math.floor(data.offsets.host.left)) ||
919
+ (placement === 'right' &&
920
+ Math.floor(data.offsets.target.left) < Math.floor(data.offsets.host.right)) ||
921
+ (placement === 'top' &&
922
+ Math.floor(data.offsets.target.bottom) > Math.floor(data.offsets.host.top)) ||
923
+ (placement === 'bottom' &&
924
+ Math.floor(data.offsets.target.top) < Math.floor(data.offsets.host.bottom));
925
+ var /** @type {?} */ overflowsLeft = Math.floor(data.offsets.target.left) < Math.floor(boundaries.left);
926
+ var /** @type {?} */ overflowsRight = Math.floor(data.offsets.target.right) > Math.floor(boundaries.right);
927
+ var /** @type {?} */ overflowsTop = Math.floor(data.offsets.target.top) < Math.floor(boundaries.top);
928
+ var /** @type {?} */ overflowsBottom = Math.floor(data.offsets.target.bottom) > Math.floor(boundaries.bottom);
929
+ var /** @type {?} */ overflowsBoundaries = (placement === 'left' && overflowsLeft) ||
930
+ (placement === 'right' && overflowsRight) ||
931
+ (placement === 'top' && overflowsTop) ||
932
+ (placement === 'bottom' && overflowsBottom);
933
+ // flip the variation if required
934
+ var /** @type {?} */ isVertical = ['top', 'bottom'].indexOf(placement) !== -1;
935
+ var /** @type {?} */ flippedVariation = ((isVertical && variation === 'left' && overflowsLeft) ||
936
+ (isVertical && variation === 'right' && overflowsRight) ||
937
+ (!isVertical && variation === 'left' && overflowsTop) ||
938
+ (!isVertical && variation === 'right' && overflowsBottom));
939
+ if (overlapsRef || overflowsBoundaries || flippedVariation) {
940
+ // this boolean to detect any flip loop
941
+ if (overlapsRef || overflowsBoundaries) {
942
+ placement = flipOrder[index + 1];
943
+ }
944
+ if (flippedVariation) {
945
+ variation = getOppositeVariation(variation);
946
+ }
947
+ data.placement = placement + (variation ? " " + variation : '');
948
+ data.offsets.target = __assign({}, data.offsets.target, getTargetOffsets(data.instance.target, data.offsets.host, data.placement));
949
+ }
950
+ });
951
+ return data;
952
+ }
953
+
954
+ /**
955
+ * @fileoverview added by tsickle
956
+ * @suppress {checkTypes} checked by tsc
957
+ */
958
+ /**
959
+ * @param {?} targetElement
960
+ * @param {?} hostElement
961
+ * @param {?} position
962
+ * @return {?}
963
+ */
964
+ function initData(targetElement, hostElement, position) {
965
+ var /** @type {?} */ hostElPosition = getReferenceOffsets(targetElement, hostElement);
966
+ var /** @type {?} */ targetOffset = getTargetOffsets(targetElement, hostElPosition, position);
967
+ var /** @type {?} */ placement = computeAutoPlacement(position, hostElPosition, targetElement, hostElement, 'viewport', 0);
968
+ var /** @type {?} */ placementAuto = position.indexOf('auto') !== -1;
969
+ return {
970
+ instance: {
971
+ target: targetElement,
972
+ host: hostElement,
973
+ arrow: null
974
+ },
975
+ offsets: {
976
+ target: targetOffset,
977
+ host: hostElPosition,
978
+ arrow: null
979
+ },
980
+ positionFixed: false,
981
+ placement: placement,
982
+ placementAuto: placementAuto
983
+ };
984
+ }
985
+
986
+ /**
987
+ * @fileoverview added by tsickle
988
+ * @suppress {checkTypes} checked by tsc
989
+ */
990
+ /**
991
+ * @param {?} data
992
+ * @return {?}
993
+ */
994
+ function preventOverflow(data) {
995
+ // NOTE: DOM access here
996
+ // resets the targetOffsets's position so that the document size can be calculated excluding
997
+ // the size of the targetOffsets element itself
998
+ var /** @type {?} */ transformProp = 'transform';
999
+ var /** @type {?} */ targetStyles = data.instance.target.style; // assignment to help minification
1000
+ var top = targetStyles.top, left = targetStyles.left, _a = transformProp, transform = targetStyles[_a];
1001
+ targetStyles.top = '';
1002
+ targetStyles.left = '';
1003
+ targetStyles[transformProp] = '';
1004
+ var /** @type {?} */ boundaries = getBoundaries(data.instance.target, data.instance.host, 0, // padding
1005
+ 'scrollParent', false // positionFixed
1006
+ );
1007
+ // NOTE: DOM access here
1008
+ // restores the original style properties after the offsets have been computed
1009
+ targetStyles.top = top;
1010
+ targetStyles.left = left;
1011
+ targetStyles[transformProp] = transform;
1012
+ var /** @type {?} */ order = ['left', 'right', 'top', 'bottom'];
1013
+ var /** @type {?} */ check = {
1014
+ primary: /**
1015
+ * @param {?} placement
1016
+ * @return {?}
1017
+ */
1018
+ function (placement) {
1019
+ var /** @type {?} */ value = data.offsets.target[placement];
1020
+ if (data.offsets.target[placement] < boundaries[placement] &&
1021
+ !false // options.escapeWithReference
1022
+ ) {
1023
+ value = Math.max(data.offsets.target[placement], boundaries[placement]);
1024
+ }
1025
+ return _a = {}, _a[placement] = value, _a;
1026
+ var _a;
1027
+ },
1028
+ secondary: /**
1029
+ * @param {?} placement
1030
+ * @return {?}
1031
+ */
1032
+ function (placement) {
1033
+ var /** @type {?} */ mainSide = placement === 'right' ? 'left' : 'top';
1034
+ var /** @type {?} */ value = data.offsets.target[mainSide];
1035
+ if (data.offsets.target[placement] > boundaries[placement] &&
1036
+ !false // escapeWithReference
1037
+ ) {
1038
+ value = Math.min(data.offsets.target[mainSide], boundaries[placement] -
1039
+ (placement === 'right' ? data.offsets.target.width : data.offsets.target.height));
1040
+ }
1041
+ return _a = {}, _a[mainSide] = value, _a;
1042
+ var _a;
1043
+ }
1044
+ };
1045
+ var /** @type {?} */ side;
1046
+ order.forEach(function (placement) {
1047
+ side = ['left', 'top']
1048
+ .indexOf(placement) !== -1
1049
+ ? 'primary'
1050
+ : 'secondary';
1051
+ data.offsets.target = __assign({}, data.offsets.target, check[side](placement));
1052
+ });
1053
+ return data;
1054
+ }
1055
+
1056
+ /**
1057
+ * @fileoverview added by tsickle
1058
+ * @suppress {checkTypes} checked by tsc
1059
+ */
1060
+ /**
1061
+ * @param {?} data
1062
+ * @return {?}
1063
+ */
1064
+ function shift(data) {
1065
+ var /** @type {?} */ placement = data.placement;
1066
+ var /** @type {?} */ basePlacement = placement.split(' ')[0];
1067
+ var /** @type {?} */ shiftvariation = placement.split(' ')[1];
1068
+ if (shiftvariation) {
1069
+ var _a = data.offsets, host = _a.host, target = _a.target;
1070
+ var /** @type {?} */ isVertical = ['bottom', 'top'].indexOf(basePlacement) !== -1;
1071
+ var /** @type {?} */ side = isVertical ? 'left' : 'top';
1072
+ var /** @type {?} */ measurement = isVertical ? 'width' : 'height';
1073
+ var /** @type {?} */ shiftOffsets = {
1074
+ left: (_b = {}, _b[side] = host[side], _b),
1075
+ right: (_c = {},
1076
+ _c[side] = host[side] + host[measurement] - host[measurement],
1077
+ _c)
1078
+ };
1079
+ data.offsets.target = __assign({}, target, shiftOffsets[shiftvariation]);
1080
+ }
1081
+ return data;
1082
+ var _b, _c;
1083
+ }
1084
+
1085
+ /**
1086
+ * @fileoverview added by tsickle
1087
+ * @suppress {checkTypes} checked by tsc
1088
+ */
1089
+
1090
+ /**
1091
+ * @fileoverview added by tsickle
1092
+ * @suppress {checkTypes} checked by tsc
10
1093
  */
11
1094
  var Positioning = /** @class */ (function () {
12
1095
  function Positioning() {
13
1096
  }
14
1097
  /**
15
- * @param {?} element
1098
+ * @param {?} hostElement
1099
+ * @param {?} targetElement
16
1100
  * @param {?=} round
17
1101
  * @return {?}
18
1102
  */
19
1103
  Positioning.prototype.position = /**
20
- * @param {?} element
1104
+ * @param {?} hostElement
1105
+ * @param {?} targetElement
21
1106
  * @param {?=} round
22
1107
  * @return {?}
23
1108
  */
24
- function (element, round) {
1109
+ function (hostElement, targetElement, round) {
25
1110
  if (round === void 0) { round = true; }
26
- var /** @type {?} */ elPosition;
27
- var /** @type {?} */ parentOffset = {
28
- width: 0,
29
- height: 0,
30
- top: 0,
31
- bottom: 0,
32
- left: 0,
33
- right: 0
34
- };
35
- if (this.getStyle(element, 'position') === 'fixed') {
36
- var /** @type {?} */ bcRect = element.getBoundingClientRect();
37
- elPosition = {
38
- width: bcRect.width,
39
- height: bcRect.height,
40
- top: bcRect.top,
41
- bottom: bcRect.bottom,
42
- left: bcRect.left,
43
- right: bcRect.right
44
- };
45
- }
46
- else {
47
- var /** @type {?} */ offsetParentEl = this.offsetParent(element);
48
- elPosition = this.offset(element, false);
49
- if (offsetParentEl !== document.documentElement) {
50
- parentOffset = this.offset(offsetParentEl, false);
51
- }
52
- parentOffset.top += offsetParentEl.clientTop;
53
- parentOffset.left += offsetParentEl.clientLeft;
54
- }
55
- elPosition.top -= parentOffset.top;
56
- elPosition.bottom -= parentOffset.top;
57
- elPosition.left -= parentOffset.left;
58
- elPosition.right -= parentOffset.left;
59
- if (round) {
60
- elPosition.top = Math.round(elPosition.top);
61
- elPosition.bottom = Math.round(elPosition.bottom);
62
- elPosition.left = Math.round(elPosition.left);
63
- elPosition.right = Math.round(elPosition.right);
64
- }
65
- return elPosition;
1111
+ return this.offset(hostElement, targetElement, false);
66
1112
  };
67
1113
  /**
68
- * @param {?} element
1114
+ * @param {?} hostElement
1115
+ * @param {?} targetElement
69
1116
  * @param {?=} round
70
1117
  * @return {?}
71
1118
  */
72
1119
  Positioning.prototype.offset = /**
73
- * @param {?} element
1120
+ * @param {?} hostElement
1121
+ * @param {?} targetElement
74
1122
  * @param {?=} round
75
1123
  * @return {?}
76
1124
  */
77
- function (element, round) {
1125
+ function (hostElement, targetElement, round) {
78
1126
  if (round === void 0) { round = true; }
79
- var /** @type {?} */ elBcr = element.getBoundingClientRect();
80
- var /** @type {?} */ viewportOffset = {
81
- top: window.pageYOffset - document.documentElement.clientTop,
82
- left: window.pageXOffset - document.documentElement.clientLeft
83
- };
84
- var /** @type {?} */ elOffset = {
85
- height: elBcr.height || element.offsetHeight,
86
- width: elBcr.width || element.offsetWidth,
87
- top: elBcr.top + viewportOffset.top,
88
- bottom: elBcr.bottom + viewportOffset.top,
89
- left: elBcr.left + viewportOffset.left,
90
- right: elBcr.right + viewportOffset.left
91
- };
92
- if (round) {
93
- elOffset.height = Math.round(elOffset.height);
94
- elOffset.width = Math.round(elOffset.width);
95
- elOffset.top = Math.round(elOffset.top);
96
- elOffset.bottom = Math.round(elOffset.bottom);
97
- elOffset.left = Math.round(elOffset.left);
98
- elOffset.right = Math.round(elOffset.right);
99
- }
100
- return elOffset;
1127
+ return getReferenceOffsets(targetElement, hostElement);
101
1128
  };
102
1129
  /**
103
1130
  * @param {?} hostElement
104
1131
  * @param {?} targetElement
105
- * @param {?} placement
1132
+ * @param {?} position
106
1133
  * @param {?=} appendToBody
107
1134
  * @return {?}
108
1135
  */
109
1136
  Positioning.prototype.positionElements = /**
110
1137
  * @param {?} hostElement
111
1138
  * @param {?} targetElement
112
- * @param {?} placement
1139
+ * @param {?} position
113
1140
  * @param {?=} appendToBody
114
1141
  * @return {?}
115
1142
  */
116
- function (hostElement, targetElement, placement, appendToBody) {
117
- var /** @type {?} */ hostElPosition = appendToBody
118
- ? this.offset(hostElement, false)
119
- : this.position(hostElement, false);
120
- var /** @type {?} */ targetElStyles = this.getAllStyles(targetElement);
121
- var /** @type {?} */ targetElBCR = targetElement.getBoundingClientRect();
122
- var /** @type {?} */ placementPrimary = placement.split(' ')[0] || 'top';
123
- var /** @type {?} */ placementSecondary = placement.split(' ')[1] || 'center';
124
- var /** @type {?} */ targetElPosition = {
125
- height: targetElBCR.height || targetElement.offsetHeight,
126
- width: targetElBCR.width || targetElement.offsetWidth,
127
- top: 0,
128
- bottom: targetElBCR.height || targetElement.offsetHeight,
129
- left: 0,
130
- right: targetElBCR.width || targetElement.offsetWidth
131
- };
132
- var /** @type {?} */ shiftHeight = {
133
- top: hostElPosition.top,
134
- center: hostElPosition.top +
135
- hostElPosition.height / 2 -
136
- targetElPosition.height / 2,
137
- bottom: hostElPosition.top + hostElPosition.height
138
- };
139
- var /** @type {?} */ shiftWidth = {
140
- left: hostElPosition.left,
141
- center: hostElPosition.left +
142
- hostElPosition.width / 2 -
143
- targetElPosition.width / 2,
144
- right: hostElPosition.left + hostElPosition.width
145
- };
146
- if (placementPrimary === 'auto') {
147
- var /** @type {?} */ newPlacementPrimary = this.autoPosition(targetElPosition, hostElPosition, targetElement, placementSecondary);
148
- if (!newPlacementPrimary)
149
- newPlacementPrimary = this.autoPosition(targetElPosition, hostElPosition, targetElement);
150
- if (newPlacementPrimary)
151
- placementPrimary = newPlacementPrimary;
152
- targetElement.classList.add(placementPrimary);
153
- }
154
- switch (placementPrimary) {
155
- case 'top':
156
- targetElPosition.top =
157
- hostElPosition.top -
158
- (targetElPosition.height +
159
- parseFloat(targetElStyles.marginBottom));
160
- targetElPosition.bottom +=
161
- hostElPosition.top - targetElPosition.height;
162
- targetElPosition.left = shiftWidth[placementSecondary];
163
- targetElPosition.right += shiftWidth[placementSecondary];
164
- break;
165
- case 'bottom':
166
- targetElPosition.top = shiftHeight[placementPrimary];
167
- targetElPosition.bottom += shiftHeight[placementPrimary];
168
- targetElPosition.left = shiftWidth[placementSecondary];
169
- targetElPosition.right += shiftWidth[placementSecondary];
170
- break;
171
- case 'left':
172
- targetElPosition.top = shiftHeight[placementSecondary];
173
- targetElPosition.bottom += shiftHeight[placementSecondary];
174
- targetElPosition.left =
175
- hostElPosition.left -
176
- (targetElPosition.width + parseFloat(targetElStyles.marginRight));
177
- targetElPosition.right +=
178
- hostElPosition.left - targetElPosition.width;
179
- break;
180
- case 'right':
181
- targetElPosition.top = shiftHeight[placementSecondary];
182
- targetElPosition.bottom += shiftHeight[placementSecondary];
183
- targetElPosition.left = shiftWidth[placementPrimary];
184
- targetElPosition.right += shiftWidth[placementPrimary];
185
- break;
186
- }
187
- targetElPosition.top = Math.round(targetElPosition.top);
188
- targetElPosition.bottom = Math.round(targetElPosition.bottom);
189
- targetElPosition.left = Math.round(targetElPosition.left);
190
- targetElPosition.right = Math.round(targetElPosition.right);
191
- return targetElPosition;
192
- };
193
- /**
194
- * @param {?} targetElPosition
195
- * @param {?} hostElPosition
196
- * @param {?} targetElement
197
- * @param {?=} preferredPosition
198
- * @return {?}
199
- */
200
- Positioning.prototype.autoPosition = /**
201
- * @param {?} targetElPosition
202
- * @param {?} hostElPosition
203
- * @param {?} targetElement
204
- * @param {?=} preferredPosition
205
- * @return {?}
206
- */
207
- function (targetElPosition, hostElPosition, targetElement, preferredPosition) {
208
- if ((!preferredPosition || preferredPosition === 'right') &&
209
- targetElPosition.left + hostElPosition.left - targetElPosition.width <
210
- 0) {
211
- return 'right';
212
- }
213
- else if ((!preferredPosition || preferredPosition === 'top') &&
214
- targetElPosition.bottom +
215
- hostElPosition.bottom +
216
- targetElPosition.height >
217
- window.innerHeight) {
218
- return 'top';
219
- }
220
- else if ((!preferredPosition || preferredPosition === 'bottom') &&
221
- targetElPosition.top + hostElPosition.top - targetElPosition.height < 0) {
222
- return 'bottom';
223
- }
224
- else if ((!preferredPosition || preferredPosition === 'left') &&
225
- targetElPosition.right +
226
- hostElPosition.right +
227
- targetElPosition.width >
228
- window.innerWidth) {
229
- return 'left';
230
- }
231
- return null;
232
- };
233
- /**
234
- * @param {?} element
235
- * @return {?}
236
- */
237
- Positioning.prototype.getAllStyles = /**
238
- * @param {?} element
239
- * @return {?}
240
- */
241
- function (element) {
242
- return window.getComputedStyle(element);
243
- };
244
- /**
245
- * @param {?} element
246
- * @param {?} prop
247
- * @return {?}
248
- */
249
- Positioning.prototype.getStyle = /**
250
- * @param {?} element
251
- * @param {?} prop
252
- * @return {?}
253
- */
254
- function (element, prop) {
255
- return (/** @type {?} */ (this.getAllStyles(element)))[prop];
256
- };
257
- /**
258
- * @param {?} element
259
- * @return {?}
260
- */
261
- Positioning.prototype.isStaticPositioned = /**
262
- * @param {?} element
263
- * @return {?}
264
- */
265
- function (element) {
266
- return (this.getStyle(element, 'position') || 'static') === 'static';
267
- };
268
- /**
269
- * @param {?} element
270
- * @return {?}
271
- */
272
- Positioning.prototype.offsetParent = /**
273
- * @param {?} element
274
- * @return {?}
275
- */
276
- function (element) {
277
- var /** @type {?} */ offsetParentEl = /** @type {?} */ (element.offsetParent) || document.documentElement;
278
- while (offsetParentEl &&
279
- offsetParentEl !== document.documentElement &&
280
- this.isStaticPositioned(offsetParentEl)) {
281
- offsetParentEl = /** @type {?} */ (offsetParentEl.offsetParent);
282
- }
283
- return offsetParentEl || document.documentElement;
1143
+ function (hostElement, targetElement, position, appendToBody) {
1144
+ var /** @type {?} */ chainOfModifiers = [flip, shift, preventOverflow, arrow];
1145
+ return chainOfModifiers.reduce(function (modifiedData, modifier) { return modifier(modifiedData); }, initData(targetElement, hostElement, position));
284
1146
  };
285
1147
  return Positioning;
286
1148
  }());
@@ -290,12 +1152,12 @@ var /** @type {?} */ positionService = new Positioning();
290
1152
  * @param {?} targetElement
291
1153
  * @param {?} placement
292
1154
  * @param {?=} appendToBody
1155
+ * @param {?=} renderer
293
1156
  * @return {?}
294
1157
  */
295
- function positionElements(hostElement, targetElement, placement, appendToBody) {
296
- var /** @type {?} */ pos = positionService.positionElements(hostElement, targetElement, placement, appendToBody);
297
- targetElement.style.top = pos.top + "px";
298
- targetElement.style.left = pos.left + "px";
1158
+ function positionElements(hostElement, targetElement, placement, appendToBody, renderer) {
1159
+ var /** @type {?} */ data = positionService.positionElements(hostElement, targetElement, placement, appendToBody);
1160
+ setAllStyles$$1(data, renderer);
299
1161
  }
300
1162
 
301
1163
  /**
@@ -303,7 +1165,18 @@ function positionElements(hostElement, targetElement, placement, appendToBody) {
303
1165
  * @suppress {checkTypes} checked by tsc
304
1166
  */
305
1167
  var PositioningService = /** @class */ (function () {
306
- function PositioningService() {
1168
+ function PositioningService(rendererFactory) {
1169
+ var _this = this;
1170
+ this.update$$ = new Subject();
1171
+ this.events$ = merge(fromEvent(window, 'scroll'), fromEvent(window, 'resize'), of(0, animationFrameScheduler), this.update$$);
1172
+ this.positionElements = new Map();
1173
+ this.events$
1174
+ .subscribe(function () {
1175
+ _this.positionElements
1176
+ .forEach(function (positionElement) {
1177
+ positionElements(_getHtmlElement(positionElement.target), _getHtmlElement(positionElement.element), positionElement.attachment, positionElement.appendToBody, rendererFactory.createRenderer(null, null));
1178
+ });
1179
+ });
307
1180
  }
308
1181
  /**
309
1182
  * @param {?} options
@@ -314,12 +1187,38 @@ var PositioningService = /** @class */ (function () {
314
1187
  * @return {?}
315
1188
  */
316
1189
  function (options) {
317
- var element = options.element, target = options.target, attachment = options.attachment, appendToBody = options.appendToBody;
318
- positionElements(_getHtmlElement(target), _getHtmlElement(element), attachment, appendToBody);
1190
+ this.addPositionElement(options);
1191
+ this.update$$.next();
1192
+ };
1193
+ /**
1194
+ * @param {?} options
1195
+ * @return {?}
1196
+ */
1197
+ PositioningService.prototype.addPositionElement = /**
1198
+ * @param {?} options
1199
+ * @return {?}
1200
+ */
1201
+ function (options) {
1202
+ this.positionElements.set(_getHtmlElement(options.element), options);
1203
+ };
1204
+ /**
1205
+ * @param {?} elRef
1206
+ * @return {?}
1207
+ */
1208
+ PositioningService.prototype.deletePositionElement = /**
1209
+ * @param {?} elRef
1210
+ * @return {?}
1211
+ */
1212
+ function (elRef) {
1213
+ this.positionElements.delete(_getHtmlElement(elRef));
319
1214
  };
320
1215
  PositioningService.decorators = [
321
1216
  { type: Injectable }
322
1217
  ];
1218
+ /** @nocollapse */
1219
+ PositioningService.ctorParameters = function () { return [
1220
+ { type: RendererFactory2, },
1221
+ ]; };
323
1222
  return PositioningService;
324
1223
  }());
325
1224
  /**
@@ -349,4 +1248,4 @@ function _getHtmlElement(element) {
349
1248
 
350
1249
  export { positionElements, Positioning, PositioningService };
351
1250
 
352
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWJvb3RzdHJhcC1wb3NpdGlvbmluZy5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy9uZy1wb3NpdGlvbmluZy50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy9wb3NpdGlvbmluZy5zZXJ2aWNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQGNvcHlyaWdodCBWYWxvciBTb2Z0d2FyZVxuICogQGNvcHlyaWdodCBBbmd1bGFyIG5nLWJvb3RzdHJhcCB0ZWFtXG4gKi9cblxuLy8gcHJldmlvdXMgdmVyc2lvbjpcbi8vIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyLXVpL2Jvb3RzdHJhcC9ibG9iLzA3YzMxZDA3MzFmN2NiMDY4YTE5MzJiOGUwMWQyMzEyYjc5NmI0ZWMvc3JjL3Bvc2l0aW9uL3Bvc2l0aW9uLmpzXG4vLyB0c2xpbnQ6ZGlzYWJsZVxuZXhwb3J0IGNsYXNzIFBvc2l0aW9uaW5nIHtcbiAgcHVibGljIHBvc2l0aW9uKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCByb3VuZCA9IHRydWUpOiBDbGllbnRSZWN0IHtcbiAgICBsZXQgZWxQb3NpdGlvbjogQ2xpZW50UmVjdDtcbiAgICBsZXQgcGFyZW50T2Zmc2V0OiBDbGllbnRSZWN0ID0ge1xuICAgICAgd2lkdGg6IDAsXG4gICAgICBoZWlnaHQ6IDAsXG4gICAgICB0b3A6IDAsXG4gICAgICBib3R0b206IDAsXG4gICAgICBsZWZ0OiAwLFxuICAgICAgcmlnaHQ6IDBcbiAgICB9O1xuXG4gICAgaWYgKHRoaXMuZ2V0U3R5bGUoZWxlbWVudCwgJ3Bvc2l0aW9uJykgPT09ICdmaXhlZCcpIHtcbiAgICAgIGNvbnN0IGJjUmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBlbFBvc2l0aW9uID0ge1xuICAgICAgICB3aWR0aDogYmNSZWN0LndpZHRoLFxuICAgICAgICBoZWlnaHQ6IGJjUmVjdC5oZWlnaHQsXG4gICAgICAgIHRvcDogYmNSZWN0LnRvcCxcbiAgICAgICAgYm90dG9tOiBiY1JlY3QuYm90dG9tLFxuICAgICAgICBsZWZ0OiBiY1JlY3QubGVmdCxcbiAgICAgICAgcmlnaHQ6IGJjUmVjdC5yaWdodFxuICAgICAgfTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3Qgb2Zmc2V0UGFyZW50RWwgPSB0aGlzLm9mZnNldFBhcmVudChlbGVtZW50KTtcblxuICAgICAgZWxQb3NpdGlvbiA9IHRoaXMub2Zmc2V0KGVsZW1lbnQsIGZhbHNlKTtcblxuICAgICAgaWYgKG9mZnNldFBhcmVudEVsICE9PSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQpIHtcbiAgICAgICAgcGFyZW50T2Zmc2V0ID0gdGhpcy5vZmZzZXQob2Zmc2V0UGFyZW50RWwsIGZhbHNlKTtcbiAgICAgIH1cblxuICAgICAgcGFyZW50T2Zmc2V0LnRvcCArPSBvZmZzZXRQYXJlbnRFbC5jbGllbnRUb3A7XG4gICAgICBwYXJlbnRPZmZzZXQubGVmdCArPSBvZmZzZXRQYXJlbnRFbC5jbGllbnRMZWZ0O1xuICAgIH1cblxuICAgIGVsUG9zaXRpb24udG9wIC09IHBhcmVudE9mZnNldC50b3A7XG4gICAgZWxQb3NpdGlvbi5ib3R0b20gLT0gcGFyZW50T2Zmc2V0LnRvcDtcbiAgICBlbFBvc2l0aW9uLmxlZnQgLT0gcGFyZW50T2Zmc2V0LmxlZnQ7XG4gICAgZWxQb3NpdGlvbi5yaWdodCAtPSBwYXJlbnRPZmZzZXQubGVmdDtcblxuICAgIGlmIChyb3VuZCkge1xuICAgICAgZWxQb3NpdGlvbi50b3AgPSBNYXRoLnJvdW5kKGVsUG9zaXRpb24udG9wKTtcbiAgICAgIGVsUG9zaXRpb24uYm90dG9tID0gTWF0aC5yb3VuZChlbFBvc2l0aW9uLmJvdHRvbSk7XG4gICAgICBlbFBvc2l0aW9uLmxlZnQgPSBNYXRoLnJvdW5kKGVsUG9zaXRpb24ubGVmdCk7XG4gICAgICBlbFBvc2l0aW9uLnJpZ2h0ID0gTWF0aC5yb3VuZChlbFBvc2l0aW9uLnJpZ2h0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxQb3NpdGlvbjtcbiAgfVxuXG4gIHB1YmxpYyBvZmZzZXQoZWxlbWVudDogSFRNTEVsZW1lbnQsIHJvdW5kID0gdHJ1ZSk6IENsaWVudFJlY3Qge1xuICAgIGNvbnN0IGVsQmNyID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCB2aWV3cG9ydE9mZnNldCA9IHtcbiAgICAgIHRvcDogd2luZG93LnBhZ2VZT2Zmc2V0IC0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LmNsaWVudFRvcCxcbiAgICAgIGxlZnQ6IHdpbmRvdy5wYWdlWE9mZnNldCAtIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5jbGllbnRMZWZ0XG4gICAgfTtcblxuICAgIGxldCBlbE9mZnNldCA9IHtcbiAgICAgIGhlaWdodDogZWxCY3IuaGVpZ2h0IHx8IGVsZW1lbnQub2Zmc2V0SGVpZ2h0LFxuICAgICAgd2lkdGg6IGVsQmNyLndpZHRoIHx8IGVsZW1lbnQub2Zmc2V0V2lkdGgsXG4gICAgICB0b3A6IGVsQmNyLnRvcCArIHZpZXdwb3J0T2Zmc2V0LnRvcCxcbiAgICAgIGJvdHRvbTogZWxCY3IuYm90dG9tICsgdmlld3BvcnRPZmZzZXQudG9wLFxuICAgICAgbGVmdDogZWxCY3IubGVmdCArIHZpZXdwb3J0T2Zmc2V0LmxlZnQsXG4gICAgICByaWdodDogZWxCY3IucmlnaHQgKyB2aWV3cG9ydE9mZnNldC5sZWZ0XG4gICAgfTtcblxuICAgIGlmIChyb3VuZCkge1xuICAgICAgZWxPZmZzZXQuaGVpZ2h0ID0gTWF0aC5yb3VuZChlbE9mZnNldC5oZWlnaHQpO1xuICAgICAgZWxPZmZzZXQud2lkdGggPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LndpZHRoKTtcbiAgICAgIGVsT2Zmc2V0LnRvcCA9IE1hdGgucm91bmQoZWxPZmZzZXQudG9wKTtcbiAgICAgIGVsT2Zmc2V0LmJvdHRvbSA9IE1hdGgucm91bmQoZWxPZmZzZXQuYm90dG9tKTtcbiAgICAgIGVsT2Zmc2V0LmxlZnQgPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LmxlZnQpO1xuICAgICAgZWxPZmZzZXQucmlnaHQgPSBNYXRoLnJvdW5kKGVsT2Zmc2V0LnJpZ2h0KTtcbiAgICB9XG5cbiAgICByZXR1cm4gZWxPZmZzZXQ7XG4gIH1cblxuICBwdWJsaWMgcG9zaXRpb25FbGVtZW50cyhcbiAgICBob3N0RWxlbWVudDogSFRNTEVsZW1lbnQsXG4gICAgdGFyZ2V0RWxlbWVudDogSFRNTEVsZW1lbnQsXG4gICAgcGxhY2VtZW50OiBzdHJpbmcsXG4gICAgYXBwZW5kVG9Cb2R5PzogYm9vbGVhblxuICApOiBDbGllbnRSZWN0IHtcbiAgICBjb25zdCBob3N0RWxQb3NpdGlvbiA9IGFwcGVuZFRvQm9keVxuICAgICAgPyB0aGlzLm9mZnNldChob3N0RWxlbWVudCwgZmFsc2UpXG4gICAgICA6IHRoaXMucG9zaXRpb24oaG9zdEVsZW1lbnQsIGZhbHNlKTtcbiAgICBjb25zdCB0YXJnZXRFbFN0eWxlcyA9IHRoaXMuZ2V0QWxsU3R5bGVzKHRhcmdldEVsZW1lbnQpO1xuICAgIGNvbnN0IHRhcmdldEVsQkNSID0gdGFyZ2V0RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBsZXQgcGxhY2VtZW50UHJpbWFyeSA9IHBsYWNlbWVudC5zcGxpdCgnICcpWzBdIHx8ICd0b3AnO1xuICAgIGNvbnN0IHBsYWNlbWVudFNlY29uZGFyeSA9IHBsYWNlbWVudC5zcGxpdCgnICcpWzFdIHx8ICdjZW50ZXInO1xuXG4gICAgbGV0IHRhcmdldEVsUG9zaXRpb246IENsaWVudFJlY3QgPSB7XG4gICAgICBoZWlnaHQ6IHRhcmdldEVsQkNSLmhlaWdodCB8fCB0YXJnZXRFbGVtZW50Lm9mZnNldEhlaWdodCxcbiAgICAgIHdpZHRoOiB0YXJnZXRFbEJDUi53aWR0aCB8fCB0YXJnZXRFbGVtZW50Lm9mZnNldFdpZHRoLFxuICAgICAgdG9wOiAwLFxuICAgICAgYm90dG9tOiB0YXJnZXRFbEJDUi5oZWlnaHQgfHwgdGFyZ2V0RWxlbWVudC5vZmZzZXRIZWlnaHQsXG4gICAgICBsZWZ0OiAwLFxuICAgICAgcmlnaHQ6IHRhcmdldEVsQkNSLndpZHRoIHx8IHRhcmdldEVsZW1lbnQub2Zmc2V0V2lkdGhcbiAgICB9O1xuXG4gICAgY29uc3Qgc2hpZnRIZWlnaHQ6IGFueSA9IHtcbiAgICAgIHRvcDogaG9zdEVsUG9zaXRpb24udG9wLFxuICAgICAgY2VudGVyOlxuICAgICAgICBob3N0RWxQb3NpdGlvbi50b3AgK1xuICAgICAgICBob3N0RWxQb3NpdGlvbi5oZWlnaHQgLyAyIC1cbiAgICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5oZWlnaHQgLyAyLFxuICAgICAgYm90dG9tOiBob3N0RWxQb3NpdGlvbi50b3AgKyBob3N0RWxQb3NpdGlvbi5oZWlnaHRcbiAgICB9O1xuICAgIGNvbnN0IHNoaWZ0V2lkdGg6IGFueSA9IHtcbiAgICAgIGxlZnQ6IGhvc3RFbFBvc2l0aW9uLmxlZnQsXG4gICAgICBjZW50ZXI6XG4gICAgICAgIGhvc3RFbFBvc2l0aW9uLmxlZnQgK1xuICAgICAgICBob3N0RWxQb3NpdGlvbi53aWR0aCAvIDIgLVxuICAgICAgICB0YXJnZXRFbFBvc2l0aW9uLndpZHRoIC8gMixcbiAgICAgIHJpZ2h0OiBob3N0RWxQb3NpdGlvbi5sZWZ0ICsgaG9zdEVsUG9zaXRpb24ud2lkdGhcbiAgICB9OyAgICBcblxuICAgIGlmIChwbGFjZW1lbnRQcmltYXJ5ID09PSAnYXV0bycpIHtcbiAgICAgIGxldCBuZXdQbGFjZW1lbnRQcmltYXJ5ID0gdGhpcy5hdXRvUG9zaXRpb24oXG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24sXG4gICAgICAgIGhvc3RFbFBvc2l0aW9uLFxuICAgICAgICB0YXJnZXRFbGVtZW50LFxuICAgICAgICBwbGFjZW1lbnRTZWNvbmRhcnlcbiAgICAgICk7XG4gICAgICBpZiAoIW5ld1BsYWNlbWVudFByaW1hcnkpXG4gICAgICAgIG5ld1BsYWNlbWVudFByaW1hcnkgPSB0aGlzLmF1dG9Qb3NpdGlvbihcbiAgICAgICAgICB0YXJnZXRFbFBvc2l0aW9uLFxuICAgICAgICAgIGhvc3RFbFBvc2l0aW9uLFxuICAgICAgICAgIHRhcmdldEVsZW1lbnRcbiAgICAgICAgKTtcbiAgICAgIGlmIChuZXdQbGFjZW1lbnRQcmltYXJ5KSBwbGFjZW1lbnRQcmltYXJ5ID0gbmV3UGxhY2VtZW50UHJpbWFyeTtcbiAgICAgIHRhcmdldEVsZW1lbnQuY2xhc3NMaXN0LmFkZChwbGFjZW1lbnRQcmltYXJ5KTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHBsYWNlbWVudFByaW1hcnkpIHtcbiAgICAgIGNhc2UgJ3RvcCc6XG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24udG9wID1cbiAgICAgICAgICBob3N0RWxQb3NpdGlvbi50b3AgLVxuICAgICAgICAgICh0YXJnZXRFbFBvc2l0aW9uLmhlaWdodCArXG4gICAgICAgICAgICBwYXJzZUZsb2F0KHRhcmdldEVsU3R5bGVzLm1hcmdpbkJvdHRvbSkpO1xuICAgICAgICB0YXJnZXRFbFBvc2l0aW9uLmJvdHRvbSArPVxuICAgICAgICAgIGhvc3RFbFBvc2l0aW9uLnRvcCAtIHRhcmdldEVsUG9zaXRpb24uaGVpZ2h0O1xuICAgICAgICB0YXJnZXRFbFBvc2l0aW9uLmxlZnQgPSBzaGlmdFdpZHRoW3BsYWNlbWVudFNlY29uZGFyeV07XG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24ucmlnaHQgKz0gc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnldO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2JvdHRvbSc6XG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24udG9wID0gc2hpZnRIZWlnaHRbcGxhY2VtZW50UHJpbWFyeV07XG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24uYm90dG9tICs9IHNoaWZ0SGVpZ2h0W3BsYWNlbWVudFByaW1hcnldO1xuICAgICAgICB0YXJnZXRFbFBvc2l0aW9uLmxlZnQgPSBzaGlmdFdpZHRoW3BsYWNlbWVudFNlY29uZGFyeV07XG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24ucmlnaHQgKz0gc2hpZnRXaWR0aFtwbGFjZW1lbnRTZWNvbmRhcnldO1xuICAgICAgICBicmVhaztcbiAgICAgIGNhc2UgJ2xlZnQnOlxuICAgICAgICB0YXJnZXRFbFBvc2l0aW9uLnRvcCA9IHNoaWZ0SGVpZ2h0W3BsYWNlbWVudFNlY29uZGFyeV07XG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24uYm90dG9tICs9IHNoaWZ0SGVpZ2h0W3BsYWNlbWVudFNlY29uZGFyeV07XG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24ubGVmdCA9XG4gICAgICAgICAgaG9zdEVsUG9zaXRpb24ubGVmdCAtXG4gICAgICAgICAgKHRhcmdldEVsUG9zaXRpb24ud2lkdGggKyBwYXJzZUZsb2F0KHRhcmdldEVsU3R5bGVzLm1hcmdpblJpZ2h0KSk7XG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24ucmlnaHQgKz1cbiAgICAgICAgICBob3N0RWxQb3NpdGlvbi5sZWZ0IC0gdGFyZ2V0RWxQb3NpdGlvbi53aWR0aDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdyaWdodCc6XG4gICAgICAgIHRhcmdldEVsUG9zaXRpb24udG9wID0gc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcbiAgICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5ib3R0b20gKz0gc2hpZnRIZWlnaHRbcGxhY2VtZW50U2Vjb25kYXJ5XTtcbiAgICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5sZWZ0ID0gc2hpZnRXaWR0aFtwbGFjZW1lbnRQcmltYXJ5XTtcbiAgICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5yaWdodCArPSBzaGlmdFdpZHRoW3BsYWNlbWVudFByaW1hcnldO1xuICAgICAgICBicmVhaztcbiAgICB9XG5cbiAgICB0YXJnZXRFbFBvc2l0aW9uLnRvcCA9IE1hdGgucm91bmQodGFyZ2V0RWxQb3NpdGlvbi50b3ApO1xuICAgIHRhcmdldEVsUG9zaXRpb24uYm90dG9tID0gTWF0aC5yb3VuZCh0YXJnZXRFbFBvc2l0aW9uLmJvdHRvbSk7XG4gICAgdGFyZ2V0RWxQb3NpdGlvbi5sZWZ0ID0gTWF0aC5yb3VuZCh0YXJnZXRFbFBvc2l0aW9uLmxlZnQpO1xuICAgIHRhcmdldEVsUG9zaXRpb24ucmlnaHQgPSBNYXRoLnJvdW5kKHRhcmdldEVsUG9zaXRpb24ucmlnaHQpO1xuXG4gICAgcmV0dXJuIHRhcmdldEVsUG9zaXRpb247XG4gIH1cblxuICBwcml2YXRlIGF1dG9Qb3NpdGlvbihcbiAgICB0YXJnZXRFbFBvc2l0aW9uOiBDbGllbnRSZWN0LFxuICAgIGhvc3RFbFBvc2l0aW9uOiBDbGllbnRSZWN0LFxuICAgIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50LFxuICAgIHByZWZlcnJlZFBvc2l0aW9uPzogc3RyaW5nXG4gICkge1xuICAgIGlmIChcbiAgICAgICghcHJlZmVycmVkUG9zaXRpb24gfHwgcHJlZmVycmVkUG9zaXRpb24gPT09ICdyaWdodCcpICYmXG4gICAgICB0YXJnZXRFbFBvc2l0aW9uLmxlZnQgKyBob3N0RWxQb3NpdGlvbi5sZWZ0IC0gdGFyZ2V0RWxQb3NpdGlvbi53aWR0aCA8XG4gICAgICAgIDBcbiAgICApIHtcbiAgICAgIHJldHVybiAncmlnaHQnO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAoIXByZWZlcnJlZFBvc2l0aW9uIHx8IHByZWZlcnJlZFBvc2l0aW9uID09PSAndG9wJykgJiZcbiAgICAgIHRhcmdldEVsUG9zaXRpb24uYm90dG9tICtcbiAgICAgICAgaG9zdEVsUG9zaXRpb24uYm90dG9tICtcbiAgICAgICAgdGFyZ2V0RWxQb3NpdGlvbi5oZWlnaHQgPlxuICAgICAgICB3aW5kb3cuaW5uZXJIZWlnaHRcbiAgICApIHtcbiAgICAgIHJldHVybiAndG9wJztcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgKCFwcmVmZXJyZWRQb3NpdGlvbiB8fCBwcmVmZXJyZWRQb3NpdGlvbiA9PT0gJ2JvdHRvbScpICYmXG4gICAgICB0YXJnZXRFbFBvc2l0aW9uLnRvcCArIGhvc3RFbFBvc2l0aW9uLnRvcCAtIHRhcmdldEVsUG9zaXRpb24uaGVpZ2h0IDwgMFxuICAgICkge1xuICAgICAgcmV0dXJuICdib3R0b20nO1xuICAgIH0gZWxzZSBpZiAoXG4gICAgICAoIXByZWZlcnJlZFBvc2l0aW9uIHx8IHByZWZlcnJlZFBvc2l0aW9uID09PSAnbGVmdCcpICYmXG4gICAgICB0YXJnZXRFbFBvc2l0aW9uLnJpZ2h0ICtcbiAgICAgICAgaG9zdEVsUG9zaXRpb24ucmlnaHQgK1xuICAgICAgICB0YXJnZXRFbFBvc2l0aW9uLndpZHRoID5cbiAgICAgICAgd2luZG93LmlubmVyV2lkdGhcbiAgICApIHtcbiAgICAgIHJldHVybiAnbGVmdCc7XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRBbGxTdHlsZXMoZWxlbWVudDogSFRNTEVsZW1lbnQpIHtcbiAgICByZXR1cm4gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCk7XG4gIH1cblxuICBwcml2YXRlIGdldFN0eWxlKGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBwcm9wOiBzdHJpbmcpOiBzdHJpbmcge1xuICAgIHJldHVybiAodGhpcy5nZXRBbGxTdHlsZXMoZWxlbWVudCkgYXMgYW55KVtwcm9wXTtcbiAgfVxuXG4gIHByaXZhdGUgaXNTdGF0aWNQb3NpdGlvbmVkKGVsZW1lbnQ6IEhUTUxFbGVtZW50KTogYm9vbGVhbiB7XG4gICAgcmV0dXJuICh0aGlzLmdldFN0eWxlKGVsZW1lbnQsICdwb3NpdGlvbicpIHx8ICdzdGF0aWMnKSA9PT0gJ3N0YXRpYyc7XG4gIH1cblxuICBwcml2YXRlIG9mZnNldFBhcmVudChlbGVtZW50OiBIVE1MRWxlbWVudCk6IEhUTUxFbGVtZW50IHtcbiAgICBsZXQgb2Zmc2V0UGFyZW50RWwgPVxuICAgICAgPEhUTUxFbGVtZW50PmVsZW1lbnQub2Zmc2V0UGFyZW50IHx8IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcblxuICAgIHdoaWxlIChcbiAgICAgIG9mZnNldFBhcmVudEVsICYmXG4gICAgICBvZmZzZXRQYXJlbnRFbCAhPT0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50ICYmXG4gICAgICB0aGlzLmlzU3RhdGljUG9zaXRpb25lZChvZmZzZXRQYXJlbnRFbClcbiAgICApIHtcbiAgICAgIG9mZnNldFBhcmVudEVsID0gPEhUTUxFbGVtZW50Pm9mZnNldFBhcmVudEVsLm9mZnNldFBhcmVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gb2Zmc2V0UGFyZW50RWwgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICB9XG59XG5cbmNvbnN0IHBvc2l0aW9uU2VydmljZSA9IG5ldyBQb3NpdGlvbmluZygpO1xuXG5leHBvcnQgZnVuY3Rpb24gcG9zaXRpb25FbGVtZW50cyhcbiAgaG9zdEVsZW1lbnQ6IEhUTUxFbGVtZW50LFxuICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgcGxhY2VtZW50OiBzdHJpbmcsXG4gIGFwcGVuZFRvQm9keT86IGJvb2xlYW5cbik6IHZvaWQge1xuICBjb25zdCBwb3MgPSBwb3NpdGlvblNlcnZpY2UucG9zaXRpb25FbGVtZW50cyhcbiAgICBob3N0RWxlbWVudCxcbiAgICB0YXJnZXRFbGVtZW50LFxuICAgIHBsYWNlbWVudCxcbiAgICBhcHBlbmRUb0JvZHlcbiAgKTtcblxuICB0YXJnZXRFbGVtZW50LnN0eWxlLnRvcCA9IGAke3Bvcy50b3B9cHhgO1xuICB0YXJnZXRFbGVtZW50LnN0eWxlLmxlZnQgPSBgJHtwb3MubGVmdH1weGA7XG59XG4iLCJpbXBvcnQgeyBJbmplY3RhYmxlLCBFbGVtZW50UmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBwb3NpdGlvbkVsZW1lbnRzIH0gZnJvbSAnLi9uZy1wb3NpdGlvbmluZyc7XG5cbmV4cG9ydCBpbnRlcmZhY2UgUG9zaXRpb25pbmdPcHRpb25zIHtcbiAgLyoqIFRoZSBET00gZWxlbWVudCwgRWxlbWVudFJlZiwgb3IgYSBzZWxlY3RvciBzdHJpbmcgb2YgYW4gZWxlbWVudCB3aGljaCB3aWxsIGJlIG1vdmVkICovXG4gIGVsZW1lbnQ/OiBIVE1MRWxlbWVudCB8IEVsZW1lbnRSZWYgfCBzdHJpbmc7XG5cbiAgLyoqIFRoZSBET00gZWxlbWVudCwgRWxlbWVudFJlZiwgb3IgYSBzZWxlY3RvciBzdHJpbmcgb2YgYW4gZWxlbWVudCB3aGljaCB0aGUgZWxlbWVudCB3aWxsIGJlIGF0dGFjaGVkIHRvICAqL1xuICB0YXJnZXQ/OiBIVE1MRWxlbWVudCB8IEVsZW1lbnRSZWYgfCBzdHJpbmc7XG5cbiAgLyoqXG4gICAqIEEgc3RyaW5nIG9mIHRoZSBmb3JtICd2ZXJ0LWF0dGFjaG1lbnQgaG9yaXotYXR0YWNobWVudCcgb3IgJ3BsYWNlbWVudCdcbiAgICogLSBwbGFjZW1lbnQgY2FuIGJlIFwidG9wXCIsIFwiYm90dG9tXCIsIFwibGVmdFwiLCBcInJpZ2h0XCJcbiAgICogbm90IHlldCBzdXBwb3J0ZWQ6XG4gICAqIC0gdmVydC1hdHRhY2htZW50IGNhbiBiZSBhbnkgb2YgJ3RvcCcsICdtaWRkbGUnLCAnYm90dG9tJ1xuICAgKiAtIGhvcml6LWF0dGFjaG1lbnQgY2FuIGJlIGFueSBvZiAnbGVmdCcsICdjZW50ZXInLCAncmlnaHQnXG4gICAqL1xuICBhdHRhY2htZW50Pzogc3RyaW5nO1xuXG4gIC8qKiBBIHN0cmluZyBzaW1pbGFyIHRvIGBhdHRhY2htZW50YC4gVGhlIG9uZSBkaWZmZXJlbmNlIGlzIHRoYXQsIGlmIGl0J3Mgbm90IHByb3ZpZGVkLFxuICAgKiBgdGFyZ2V0QXR0YWNobWVudGAgd2lsbCBhc3N1bWUgdGhlIG1pcnJvciBpbWFnZSBvZiBgYXR0YWNobWVudGAuXG4gICAqL1xuICB0YXJnZXRBdHRhY2htZW50Pzogc3RyaW5nO1xuXG4gIC8qKiBBIHN0cmluZyBvZiB0aGUgZm9ybSAndmVydC1vZmZzZXQgaG9yaXotb2Zmc2V0J1xuICAgKiAtIHZlcnQtb2Zmc2V0IGFuZCBob3Jpei1vZmZzZXQgY2FuIGJlIG9mIHRoZSBmb3JtIFwiMjBweFwiIG9yIFwiNTUlXCJcbiAgICovXG4gIG9mZnNldD86IHN0cmluZztcblxuICAvKiogQSBzdHJpbmcgc2ltaWxhciB0byBgb2Zmc2V0YCwgYnV0IHJlZmVycmluZyB0byB0aGUgb2Zmc2V0IG9mIHRoZSB0YXJnZXQgKi9cbiAgdGFyZ2V0T2Zmc2V0Pzogc3RyaW5nO1xuXG4gIC8qKiBJZiB0cnVlIGNvbXBvbmVudCB3aWxsIGJlIGF0dGFjaGVkIHRvIGJvZHkgKi9cbiAgYXBwZW5kVG9Cb2R5PzogYm9vbGVhbjtcbn1cblxuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIFBvc2l0aW9uaW5nU2VydmljZSB7XG4gIHBvc2l0aW9uKG9wdGlvbnM6IFBvc2l0aW9uaW5nT3B0aW9ucyk6IHZvaWQge1xuICAgIGNvbnN0IHtlbGVtZW50LCB0YXJnZXQsIGF0dGFjaG1lbnQsIGFwcGVuZFRvQm9keX0gPSBvcHRpb25zO1xuICAgIHBvc2l0aW9uRWxlbWVudHMoXG4gICAgICBfZ2V0SHRtbEVsZW1lbnQodGFyZ2V0KSxcbiAgICAgIF9nZXRIdG1sRWxlbWVudChlbGVtZW50KSxcbiAgICAgIGF0dGFjaG1lbnQsXG4gICAgICBhcHBlbmRUb0JvZHlcbiAgICApO1xuICB9XG5cbn1cblxuZnVuY3Rpb24gX2dldEh0bWxFbGVtZW50KGVsZW1lbnQ6IEhUTUxFbGVtZW50IHwgRWxlbWVudFJlZiB8IHN0cmluZyk6IEhUTUxFbGVtZW50IHtcbiAgLy8gaXQgbWVhbnMgdGhhdCB3ZSBnb3QgYSBzZWxlY3RvclxuICBpZiAodHlwZW9mIGVsZW1lbnQgPT09ICdzdHJpbmcnKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoZWxlbWVudCk7XG4gIH1cblxuICBpZiAoZWxlbWVudCBpbnN0YW5jZW9mIEVsZW1lbnRSZWYpIHtcbiAgICByZXR1cm4gZWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnQ7XG59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
1251
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWJvb3RzdHJhcC1wb3NpdGlvbmluZy5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9nZXRTdHlsZUNvbXB1dGVkUHJvcGVydHkudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvZ2V0UGFyZW50Tm9kZS50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9nZXRTY3JvbGxQYXJlbnQudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvaXNCcm93c2VyLnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL3V0aWxzL2lzSUUudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvZ2V0T2Zmc2V0UGFyZW50LnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL3V0aWxzL2lzT2Zmc2V0Q29udGFpbmVyLnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL3V0aWxzL2dldFJvb3QudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvZmluZENvbW1vbk9mZnNldFBhcmVudC50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9nZXRCb3JkZXJzU2l6ZS50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9nZXRXaW5kb3dTaXplcy50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9nZXRTY3JvbGwudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvZ2V0Q2xpZW50UmVjdC50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9nZXRCb3VuZGluZ0NsaWVudFJlY3QudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvaW5jbHVkZVNjcm9sbC50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9nZXRPZmZzZXRSZWN0UmVsYXRpdmVUb0FyYml0cmFyeU5vZGUudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvZ2V0Vmlld3BvcnRPZmZzZXRSZWN0UmVsYXRpdmVUb0FydGJpdHJhcnlOb2RlLnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL3V0aWxzL2lzRml4ZWQudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvZ2V0Rml4ZWRQb3NpdGlvbk9mZnNldFBhcmVudC50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9nZXRCb3VuZGFyaWVzLnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL3V0aWxzL2NvbXB1dGVBdXRvUGxhY2VtZW50LnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL3V0aWxzL2dldE9mZnNldHMudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvZ2V0T3Bwb3NpdGVQbGFjZW1lbnQudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvZ2V0T3Bwb3NpdGVWYXJpYXRpb24udHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvZ2V0T3V0ZXJTaXplcy50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9nZXRSZWZlcmVuY2VPZmZzZXRzLnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL3V0aWxzL2dldFRhcmdldE9mZnNldHMudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvdXRpbHMvaXNOdW1lcmljLnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL3V0aWxzL3NldEFsbFN0eWxlcy50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy91dGlscy9zZXRTdHlsZXMudHMiLCJuZzovL25neC1ib290c3RyYXAvcG9zaXRpb25pbmcvbW9kaWZpZXJzL2Fycm93LnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL21vZGlmaWVycy9mbGlwLnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL21vZGlmaWVycy9pbml0RGF0YS50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy9tb2RpZmllcnMvcHJldmVudE92ZXJmbG93LnRzIiwibmc6Ly9uZ3gtYm9vdHN0cmFwL3Bvc2l0aW9uaW5nL21vZGlmaWVycy9zaGlmdC50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy9uZy1wb3NpdGlvbmluZy50cyIsIm5nOi8vbmd4LWJvb3RzdHJhcC9wb3NpdGlvbmluZy9wb3NpdGlvbmluZy5zZXJ2aWNlLnRzIl0sInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogR2V0IENTUyBjb21wdXRlZCBwcm9wZXJ0eSBvZiB0aGUgZ2l2ZW4gZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0U3R5bGVDb21wdXRlZFByb3BlcnR5KGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBwcm9wZXJ0eT86IHN0cmluZyk6IGFueSB7XG4gIGlmIChlbGVtZW50Lm5vZGVUeXBlICE9PSAxKSB7XG4gICAgcmV0dXJuIFtdO1xuICB9XG4gIC8vIE5PVEU6IDEgRE9NIGFjY2VzcyBoZXJlXG4gIGNvbnN0IHdpbmRvdyA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5kZWZhdWx0VmlldztcbiAgY29uc3QgY3NzID0gd2luZG93LmdldENvbXB1dGVkU3R5bGUoZWxlbWVudCwgbnVsbCk7XG5cbiAgcmV0dXJuIHByb3BlcnR5ID8gY3NzW3Byb3BlcnR5XSA6IGNzcztcbn1cbiIsIi8qKlxuICogUmV0dXJucyB0aGUgcGFyZW50Tm9kZSBvciB0aGUgaG9zdCBvZiB0aGUgZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0UGFyZW50Tm9kZShlbGVtZW50OiBhbnkpOiBhbnkge1xuICBpZiAoZWxlbWVudC5ub2RlTmFtZSA9PT0gJ0hUTUwnKSB7XG4gICAgcmV0dXJuIGVsZW1lbnQ7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudC5wYXJlbnROb2RlIHx8IGVsZW1lbnQuaG9zdDtcbn1cbiIsIi8qKlxuICogUmV0dXJucyB0aGUgc2Nyb2xsaW5nIHBhcmVudCBvZiB0aGUgZ2l2ZW4gZWxlbWVudFxuICovXG5pbXBvcnQgeyBnZXRTdHlsZUNvbXB1dGVkUHJvcGVydHkgfSBmcm9tICcuL2dldFN0eWxlQ29tcHV0ZWRQcm9wZXJ0eSc7XG5pbXBvcnQgeyBnZXRQYXJlbnROb2RlIH0gZnJvbSAnLi9nZXRQYXJlbnROb2RlJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFNjcm9sbFBhcmVudChlbGVtZW50OiBhbnkpOiBhbnkge1xuICAvLyBSZXR1cm4gYm9keSwgYGdldFNjcm9sbGAgd2lsbCB0YWtlIGNhcmUgdG8gZ2V0IHRoZSBjb3JyZWN0IGBzY3JvbGxUb3BgIGZyb20gaXRcbiAgaWYgKCFlbGVtZW50KSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmJvZHk7XG4gIH1cblxuICBzd2l0Y2ggKGVsZW1lbnQubm9kZU5hbWUpIHtcbiAgICBjYXNlICdIVE1MJzpcbiAgICBjYXNlICdCT0RZJzpcbiAgICAgIHJldHVybiBlbGVtZW50Lm93bmVyRG9jdW1lbnQuYm9keTtcbiAgICBjYXNlICcjZG9jdW1lbnQnOlxuICAgICAgcmV0dXJuIGVsZW1lbnQuYm9keTtcbiAgICBkZWZhdWx0OlxuICB9XG5cbiAgLy8gRmlyZWZveCB3YW50IHVzIHRvIGNoZWNrIGAteGAgYW5kIGAteWAgdmFyaWF0aW9ucyBhcyB3ZWxsXG4gIGNvbnN0IHsgb3ZlcmZsb3csIG92ZXJmbG93WCwgb3ZlcmZsb3dZIH0gPSBnZXRTdHlsZUNvbXB1dGVkUHJvcGVydHkoZWxlbWVudCk7XG4gIGlmICgvKGF1dG98c2Nyb2xsfG92ZXJsYXkpLy50ZXN0KFN0cmluZyhvdmVyZmxvdykgKyBTdHJpbmcob3ZlcmZsb3dZKSArIFN0cmluZyhvdmVyZmxvd1gpKSkge1xuICAgIHJldHVybiBlbGVtZW50O1xuICB9XG5cbiAgcmV0dXJuIGdldFNjcm9sbFBhcmVudChnZXRQYXJlbnROb2RlKGVsZW1lbnQpKTtcbn1cbiIsImV4cG9ydCBjb25zdCBpc0Jyb3dzZXIgPSB0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJyAmJiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnO1xuIiwiLyoqXG4gKiBEZXRlcm1pbmVzIGlmIHRoZSBicm93c2VyIGlzIEludGVybmV0IEV4cGxvcmVyXG4gKi9cbmltcG9ydCB7IGlzQnJvd3NlciB9IGZyb20gJy4vaXNCcm93c2VyJztcblxuY29uc3QgaXNJRTExID0gaXNCcm93c2VyICYmICEhKCh3aW5kb3cgYXMgYW55KS5NU0lucHV0TWV0aG9kQ29udGV4dCAmJiAoZG9jdW1lbnQgYXMgYW55KS5kb2N1bWVudE1vZGUpO1xuY29uc3QgaXNJRTEwID0gaXNCcm93c2VyICYmIC9NU0lFIDEwLy50ZXN0KG5hdmlnYXRvci51c2VyQWdlbnQpO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNJRSh2ZXJzaW9uPzogbnVtYmVyKSB7XG4gIGlmICh2ZXJzaW9uID09PSAxMSkge1xuICAgIHJldHVybiBpc0lFMTE7XG4gIH1cbiAgaWYgKHZlcnNpb24gPT09IDEwKSB7XG4gICAgcmV0dXJuIGlzSUUxMDtcbiAgfVxuXG4gIHJldHVybiBpc0lFMTEgfHwgaXNJRTEwO1xufVxuIiwiLyoqXG4gKiBSZXR1cm5zIHRoZSBvZmZzZXQgcGFyZW50IG9mIHRoZSBnaXZlbiBlbGVtZW50XG4gKi9cbmltcG9ydCB7IGdldFN0eWxlQ29tcHV0ZWRQcm9wZXJ0eSB9IGZyb20gJy4vZ2V0U3R5bGVDb21wdXRlZFByb3BlcnR5JztcbmltcG9ydCB7IGlzSUUgfSBmcm9tICcuL2lzSUUnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0T2Zmc2V0UGFyZW50KGVsZW1lbnQ6IGFueSk6IGFueSB7XG4gIGlmICghZWxlbWVudCkge1xuICAgIHJldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gIH1cblxuICBjb25zdCBub09mZnNldFBhcmVudCA9IGlzSUUoMTApID8gZG9jdW1lbnQuYm9keSA6IG51bGw7XG5cbiAgLy8gTk9URTogMSBET00gYWNjZXNzIGhlcmVcbiAgbGV0IG9mZnNldFBhcmVudCA9IGVsZW1lbnQub2Zmc2V0UGFyZW50IHx8IG51bGw7XG4gIC8vIFNraXAgaGlkZGVuIGVsZW1lbnRzIHdoaWNoIGRvbid0IGhhdmUgYW4gb2Zmc2V0UGFyZW50XG5cbiAgbGV0IHNpYmxpbmc6IGFueTtcblxuICB3aGlsZSAob2Zmc2V0UGFyZW50ID09PSBub09mZnNldFBhcmVudCAmJiBlbGVtZW50Lm5leHRFbGVtZW50U2libGluZykge1xuICAgIHNpYmxpbmcgPSBlbGVtZW50Lm5leHRFbGVtZW50U2libGluZztcbiAgICBvZmZzZXRQYXJlbnQgPSBzaWJsaW5nLm9mZnNldFBhcmVudDtcbiAgfVxuXG4gIGNvbnN0IG5vZGVOYW1lID0gb2Zmc2V0UGFyZW50ICYmIG9mZnNldFBhcmVudC5ub2RlTmFtZTtcblxuICBpZiAoIW5vZGVOYW1lIHx8IG5vZGVOYW1lID09PSAnQk9EWScgfHwgbm9kZU5hbWUgPT09ICdIVE1MJykge1xuICAgIHJldHVybiBzaWJsaW5nID8gc2libGluZy5vd25lckRvY3VtZW50LmRvY3VtZW50RWxlbWVudCA6IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgfVxuXG4gIC8vIC5vZmZzZXRQYXJlbnQgd2lsbCByZXR1cm4gdGhlIGNsb3Nlc3QgVEgsIFREIG9yIFRBQkxFIGluIGNhc2VcbiAgLy8gbm8gb2Zmc2V0UGFyZW50IGlzIHByZXNlbnQsIEkgaGF0ZSB0aGlzIGpvYi4uLlxuICBpZiAoXG4gICAgWydUSCcsICdURCcsICdUQUJMRSddLmluZGV4T2Yob2Zmc2V0UGFyZW50Lm5vZGVOYW1lKSAhPT0gLTEgJiZcbiAgICBnZXRTdHlsZUNvbXB1dGVkUHJvcGVydHkob2Zmc2V0UGFyZW50LCAncG9zaXRpb24nKSA9PT0gJ3N0YXRpYydcbiAgKSB7XG4gICAgcmV0dXJuIGdldE9mZnNldFBhcmVudChvZmZzZXRQYXJlbnQpO1xuICB9XG5cbiAgcmV0dXJuIG9mZnNldFBhcmVudDtcbn1cbiIsImltcG9ydCB7IGdldE9mZnNldFBhcmVudCB9IGZyb20gJy4vZ2V0T2Zmc2V0UGFyZW50JztcblxuZXhwb3J0IGZ1bmN0aW9uIGlzT2Zmc2V0Q29udGFpbmVyKGVsZW1lbnQ6IGFueSkge1xuICBjb25zdCB7IG5vZGVOYW1lIH0gPSBlbGVtZW50O1xuICBpZiAobm9kZU5hbWUgPT09ICdCT0RZJykge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIHJldHVybiAoXG4gICAgbm9kZU5hbWUgPT09ICdIVE1MJyB8fCBnZXRPZmZzZXRQYXJlbnQoZWxlbWVudC5maXJzdEVsZW1lbnRDaGlsZCkgPT09IGVsZW1lbnRcbiAgKTtcbn1cbiIsIi8qKlxuICogRmluZHMgdGhlIHJvb3Qgbm9kZSAoZG9jdW1lbnQsIHNoYWRvd0RPTSByb290KSBvZiB0aGUgZ2l2ZW4gZWxlbWVudFxuICovXG5leHBvcnQgZnVuY3Rpb24gZ2V0Um9vdChub2RlOiBOb2RlKTogYW55IHtcbiAgaWYgKG5vZGUucGFyZW50Tm9kZSAhPT0gbnVsbCkge1xuICAgIHJldHVybiBnZXRSb290KG5vZGUucGFyZW50Tm9kZSk7XG4gIH1cblxuICByZXR1cm4gbm9kZTtcbn1cbiIsIi8qKlxuICogRmluZHMgdGhlIG9mZnNldCBwYXJlbnQgY29tbW9uIHRvIHRoZSB0d28gcHJvdmlkZWQgbm9kZXNcbiAqL1xuaW1wb3J0IHsgaXNPZmZzZXRDb250YWluZXIgfSBmcm9tICcuL2lzT2Zmc2V0Q29udGFpbmVyJztcbmltcG9ydCB7IGdldFJvb3QgfSBmcm9tICcuL2dldFJvb3QnO1xuaW1wb3J0IHsgZ2V0T2Zmc2V0UGFyZW50IH0gZnJvbSAnLi9nZXRPZmZzZXRQYXJlbnQnO1xuXG5leHBvcnQgZnVuY3Rpb24gZmluZENvbW1vbk9mZnNldFBhcmVudChlbGVtZW50MTogSFRNTEVsZW1lbnQsIGVsZW1lbnQyOiBIVE1MRWxlbWVudCk6IGFueSB7XG4gIC8vIFRoaXMgY2hlY2sgaXMgbmVlZGVkIHRvIGF2b2lkIGVycm9ycyBpbiBjYXNlIG9uZSBvZiB0aGUgZWxlbWVudHMgaXNuJ3QgZGVmaW5lZCBmb3IgYW55IHJlYXNvblxuICBpZiAoIWVsZW1lbnQxIHx8ICFlbGVtZW50MS5ub2RlVHlwZSB8fCAhZWxlbWVudDIgfHwgIWVsZW1lbnQyLm5vZGVUeXBlKSB7XG4gICAgcmV0dXJuIGRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgfVxuXG4gIC8vIEhlcmUgd2UgbWFrZSBzdXJlIHRvIGdpdmUgYXMgXCJzdGFydFwiIHRoZSBlbGVtZW50IHRoYXQgY29tZXMgZmlyc3QgaW4gdGhlIERPTVxuICAvKiB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6IG5vLWJpdHdpc2UgKi9cbiAgY29uc3Qgb3JkZXIgPSBlbGVtZW50MS5jb21wYXJlRG9jdW1lbnRQb3NpdGlvbihlbGVtZW50MikgJiBOb2RlLkRPQ1VNRU5UX1BPU0lUSU9OX0ZPTExPV0lORztcblxuICBjb25zdCBzdGFydCA9IG9yZGVyID8gZWxlbWVudDEgOiBlbGVtZW50MjtcbiAgY29uc3QgZW5kID0gb3JkZXIgPyBlbGVtZW50MiA6IGVsZW1lbnQxO1xuXG4gIC8vIEdldCBjb21tb24gYW5jZXN0b3IgY29udGFpbmVyXG4gIGNvbnN0IHJhbmdlID0gZG9jdW1lbnQuY3JlYXRlUmFuZ2UoKTtcbiAgcmFuZ2Uuc2V0U3RhcnQoc3RhcnQsIDApO1xuICByYW5nZS5zZXRFbmQoZW5kLCAwKTtcbiAgY29uc3QgeyBjb21tb25BbmNlc3RvckNvbnRhaW5lciB9ID0gcmFuZ2U7XG5cbiAgLy8gQm90aCBub2RlcyBhcmUgaW5zaWRlICNkb2N1bWVudFxuICBpZiAoXG4gICAgKGVsZW1lbnQxICE9PSBjb21tb25BbmNlc3RvckNvbnRhaW5lciAmJlxuICAgICAgZWxlbWVudDIgIT09IGNvbW1vbkFuY2VzdG9yQ29udGFpbmVyKSB8fFxuICAgIHN0YXJ0LmNvbnRhaW5zKGVuZClcbiAgKSB7XG4gICAgaWYgKGlzT2Zmc2V0Q29udGFpbmVyKGNvbW1vbkFuY2VzdG9yQ29udGFpbmVyKSkge1xuICAgICAgcmV0dXJuIGNvbW1vbkFuY2VzdG9yQ29udGFpbmVyO1xuICAgIH1cblxuICAgIHJldHVybiBnZXRPZmZzZXRQYXJlbnQoY29tbW9uQW5jZXN0b3JDb250YWluZXIpO1xuICB9XG5cbiAgLy8gb25lIG9mIHRoZSBub2RlcyBpcyBpbnNpZGUgc2hhZG93RE9NLCBmaW5kIHdoaWNoIG9uZVxuICBjb25zdCBlbGVtZW50MXJvb3QgPSBnZXRSb290KGVsZW1lbnQxKTtcbiAgaWYgKGVsZW1lbnQxcm9vdC5ob3N0KSB7XG4gICAgcmV0dXJuIGZpbmRDb21tb25PZmZzZXRQYXJlbnQoZWxlbWVudDFyb290Lmhvc3QsIGVsZW1lbnQyKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmluZENvbW1vbk9mZnNldFBhcmVudChlbGVtZW50MSwgZ2V0Um9vdChlbGVtZW50MikuaG9zdCk7XG4gIH1cbn1cbiIsIi8qKlxuICogSGVscGVyIHRvIGRldGVjdCBib3JkZXJzIG9mIGEgZ2l2ZW4gZWxlbWVudFxuICovXG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRCb3JkZXJzU2l6ZShzdHlsZXM6IENTU1N0eWxlRGVjbGFyYXRpb24sIGF4aXM6IHN0cmluZykge1xuICBjb25zdCBzaWRlQSA9IGF4aXMgPT09ICd4JyA/ICdMZWZ0JyA6ICdUb3AnO1xuICBjb25zdCBzaWRlQiA9IHNpZGVBID09PSAnTGVmdCcgPyAnUmlnaHQnIDogJ0JvdHRvbSc7XG5cbiAgcmV0dXJuIChcbiAgICBwYXJzZUZsb2F0KHN0eWxlc1tgYm9yZGVyJHtzaWRlQX1XaWR0aGBdKSArXG4gICAgcGFyc2VGbG9hdChzdHlsZXNbYGJvcmRlciR7c2lkZUJ9V2lkdGhgXSlcbiAgKTtcbn1cbiIsImltcG9ydCB7IGlzSUUgfSBmcm9tICcuL2lzSUUnO1xuXG5mdW5jdGlvbiBnZXRTaXplKGF4aXM6IHN0cmluZywgYm9keTogSFRNTEVsZW1lbnQsIGh0bWw6IEhUTUxFbGVtZW50LCBjb21wdXRlZFN0eWxlOiBDU1NTdHlsZURlY2xhcmF0aW9uKSB7XG4gIHJldHVybiBNYXRoLm1heChcbiAgICBib2R5W2BvZmZzZXQke2F4aXN9YF0sXG4gICAgYm9keVtgc2Nyb2xsJHtheGlzfWBdLFxuICAgIGh0bWxbYGNsaWVudCR7YXhpc31gXSxcbiAgICBodG1sW2BvZmZzZXQke2F4aXN9YF0sXG4gICAgaHRtbFtgc2Nyb2xsJHtheGlzfWBdLFxuICAgIGlzSUUoMTApXG4gICAgICA/IChwYXJzZUludChodG1sW2BvZmZzZXQke2F4aXN9YF0sIDEwKSArXG4gICAgICBwYXJzZUludChjb21wdXRlZFN0eWxlW2BtYXJnaW4ke2F4aXMgPT09ICdIZWlnaHQnID8gJ1RvcCcgOiAnTGVmdCd9YF0sIDEwKSArXG4gICAgICBwYXJzZUludChjb21wdXRlZFN0eWxlW2BtYXJnaW4ke2F4aXMgPT09ICdIZWlnaHQnID8gJ0JvdHRvbScgOiAnUmlnaHQnfWBdLCAxMCkpXG4gICAgOiAwXG4gICk7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRXaW5kb3dTaXplcyhkb2N1bWVudDogRG9jdW1lbnQpIHtcbiAgY29uc3QgYm9keSA9IGRvY3VtZW50LmJvZHk7XG4gIGNvbnN0IGh0bWwgPSBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gIGNvbnN0IGNvbXB1dGVkU3R5bGUgPSBpc0lFKDEwKSAmJiBnZXRDb21wdXRlZFN0eWxlKGh0bWwpO1xuXG4gIHJldHVybiB7XG4gICAgaGVpZ2h0OiBnZXRTaXplKCdIZWlnaHQnLCBib2R5LCBodG1sLCBjb21wdXRlZFN0eWxlKSxcbiAgICB3aWR0aDogZ2V0U2l6ZSgnV2lkdGgnLCBib2R5LCBodG1sLCBjb21wdXRlZFN0eWxlKVxuICB9O1xufVxuIiwiLyoqXG4gKiBHZXRzIHRoZSBzY3JvbGwgdmFsdWUgb2YgdGhlIGdpdmVuIGVsZW1lbnQgaW4gdGhlIGdpdmVuIHNpZGUgKHRvcCBhbmQgbGVmdClcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldFNjcm9sbChlbGVtZW50OiBIVE1MRWxlbWVudCwgc2lkZSA9ICd0b3AnKSB7XG4gIGNvbnN0IHVwcGVyU2lkZSA9IHNpZGUgPT09ICd0b3AnID8gJ3Njcm9sbFRvcCcgOiAnc2Nyb2xsTGVmdCc7XG4gIGNvbnN0IG5vZGVOYW1lID0gZWxlbWVudC5ub2RlTmFtZTtcblxuICBpZiAobm9kZU5hbWUgPT09ICdCT0RZJyB8fCBub2RlTmFtZSA9PT0gJ0hUTUwnKSB7XG4gICAgY29uc3QgaHRtbCA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gICAgY29uc3Qgc2Nyb2xsaW5nRWxlbWVudCA9IGVsZW1lbnQub3duZXJEb2N1bWVudC5zY3JvbGxpbmdFbGVtZW50IHx8IGh0bWw7XG5cbiAgICByZXR1cm4gc2Nyb2xsaW5nRWxlbWVudFt1cHBlclNpZGVdO1xuICB9XG5cbiAgcmV0dXJuIGVsZW1lbnRbdXBwZXJTaWRlXTtcbn1cbiIsIi8qKlxuICogR2l2ZW4gZWxlbWVudCBvZmZzZXRzLCBnZW5lcmF0ZSBhbiBvdXRwdXQgc2ltaWxhciB0byBnZXRCb3VuZGluZ0NsaWVudFJlY3RcbiAqL1xuaW1wb3J0IHsgT2Zmc2V0cyB9IGZyb20gJy4uL21vZGVscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRDbGllbnRSZWN0KG9mZnNldHM6IE9mZnNldHMpOiBPZmZzZXRzIHtcbiAgcmV0dXJuIHtcbiAgICAuLi5vZmZzZXRzLFxuICAgIHJpZ2h0OiBvZmZzZXRzLmxlZnQgKyBvZmZzZXRzLndpZHRoLFxuICAgIGJvdHRvbTogb2Zmc2V0cy50b3AgKyBvZmZzZXRzLmhlaWdodFxuICB9O1xufVxuIiwiLyoqXG4gKiBHZXQgYm91bmRpbmcgY2xpZW50IHJlY3Qgb2YgZ2l2ZW4gZWxlbWVudFxuICovXG5pbXBvcnQgeyBnZXRTdHlsZUNvbXB1dGVkUHJvcGVydHkgfSBmcm9tICcuL2dldFN0eWxlQ29tcHV0ZWRQcm9wZXJ0eSc7XG5pbXBvcnQgeyBnZXRCb3JkZXJzU2l6ZSB9IGZyb20gJy4vZ2V0Qm9yZGVyc1NpemUnO1xuaW1wb3J0IHsgZ2V0V2luZG93U2l6ZXMgfSBmcm9tICcuL2dldFdpbmRvd1NpemVzJztcbmltcG9ydCB7IGdldFNjcm9sbCB9IGZyb20gJy4vZ2V0U2Nyb2xsJztcbmltcG9ydCB7IGdldENsaWVudFJlY3QgfSBmcm9tICcuL2dldENsaWVudFJlY3QnO1xuaW1wb3J0IHsgaXNJRSB9IGZyb20gJy4vaXNJRSc7XG5pbXBvcnQgeyBPZmZzZXRzIH0gZnJvbSAnLi4vbW9kZWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJvdW5kaW5nQ2xpZW50UmVjdChlbGVtZW50OiBIVE1MRWxlbWVudCk6IE9mZnNldHMge1xuICBsZXQgcmVjdDogYW55ID0ge307XG5cbiAgLy8gSUUxMCAxMCBGSVg6IFBsZWFzZSwgZG9uJ3QgYXNrLCB0aGUgZWxlbWVudCBpc24ndFxuICAvLyBjb25zaWRlcmVkIGluIERPTSBpbiBzb21lIGNpcmN1bXN0YW5jZXMuLi5cbiAgLy8gVGhpcyBpc24ndCByZXByb2R1Y2libGUgaW4gSUUxMCBjb21wYXRpYmlsaXR5IG1vZGUgb2YgSUUxMVxuICB0cnkge1xuICAgIGlmIChpc0lFKDEwKSkge1xuICAgICAgcmVjdCA9IGVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCBzY3JvbGxUb3AgPSBnZXRTY3JvbGwoZWxlbWVudCwgJ3RvcCcpO1xuICAgICAgY29uc3Qgc2Nyb2xsTGVmdCA9IGdldFNjcm9sbChlbGVtZW50LCAnbGVmdCcpO1xuICAgICAgcmVjdC50b3AgKz0gc2Nyb2xsVG9wO1xuICAgICAgcmVjdC5sZWZ0ICs9IHNjcm9sbExlZnQ7XG4gICAgICByZWN0LmJvdHRvbSArPSBzY3JvbGxUb3A7XG4gICAgICByZWN0LnJpZ2h0ICs9IHNjcm9sbExlZnQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIH1cbiAgfSBjYXRjaCAoZSkge1xuICAgIHJldHVybiB1bmRlZmluZWQ7XG4gIH1cblxuICBjb25zdCByZXN1bHQ6IGFueSA9IHtcbiAgICBsZWZ0OiByZWN0LmxlZnQsXG4gICAgdG9wOiByZWN0LnRvcCxcbiAgICB3aWR0aDogcmVjdC5yaWdodCAtIHJlY3QubGVmdCxcbiAgICBoZWlnaHQ6IHJlY3QuYm90dG9tIC0gcmVjdC50b3BcbiAgfTtcblxuICAvLyBzdWJ0cmFjdCBzY3JvbGxiYXIgc2l6ZSBmcm9tIHNpemVzXG4gIGNvbnN0IHNpemVzOiBhbnkgPSBlbGVtZW50Lm5vZGVOYW1lID09PSAnSFRNTCcgPyBnZXRXaW5kb3dTaXplcyhlbGVtZW50Lm93bmVyRG9jdW1lbnQpIDoge307XG4gIGNvbnN0IHdpZHRoID1cbiAgICBzaXplcy53aWR0aCB8fCBlbGVtZW50LmNsaWVudFdpZHRoIHx8IHJlc3VsdC5yaWdodCAtIHJlc3VsdC5sZWZ0O1xuICBjb25zdCBoZWlnaHQgPVxuICAgIHNpemVzLmhlaWdodCB8fCBlbGVtZW50LmNsaWVudEhlaWdodCB8fCByZXN1bHQuYm90dG9tIC0gcmVzdWx0LnRvcDtcblxuICBsZXQgaG9yaXpTY3JvbGxiYXIgPSBlbGVtZW50Lm9mZnNldFdpZHRoIC0gd2lkdGg7XG4gIGxldCB2ZXJ0U2Nyb2xsYmFyID0gZWxlbWVudC5vZmZzZXRIZWlnaHQgLSBoZWlnaHQ7XG5cbiAgLy8gaWYgYW4gaHlwb3RoZXRpY2FsIHNjcm9sbGJhciBpcyBkZXRlY3RlZCwgd2UgbXVzdCBiZSBzdXJlIGl0J3Mgbm90IGEgYGJvcmRlcmBcbiAgLy8gd2UgbWFrZSB0aGlzIGNoZWNrIGNvbmRpdGlvbmFsIGZvciBwZXJmb3JtYW5jZSByZWFzb25zXG4gIGlmIChob3JpelNjcm9sbGJhciB8fCB2ZXJ0U2Nyb2xsYmFyKSB7XG4gICAgY29uc3Qgc3R5bGVzID0gZ2V0U3R5bGVDb21wdXRlZFByb3BlcnR5KGVsZW1lbnQpO1xuICAgIGhvcml6U2Nyb2xsYmFyIC09IGdldEJvcmRlcnNTaXplKHN0eWxlcywgJ3gnKTtcbiAgICB2ZXJ0U2Nyb2xsYmFyIC09IGdldEJvcmRlcnNTaXplKHN0eWxlcywgJ3knKTtcblxuICAgIHJlc3VsdC53aWR0aCAtPSBob3JpelNjcm9sbGJhcjtcbiAgICByZXN1bHQuaGVpZ2h0IC09IHZlcnRTY3JvbGxiYXI7XG4gIH1cblxuICByZXR1cm4gZ2V0Q2xpZW50UmVjdChyZXN1bHQpO1xufVxuIiwiLyoqXG4gKiBTdW0gb3Igc3VidHJhY3QgdGhlIGVsZW1lbnQgc2Nyb2xsIHZhbHVlcyAobGVmdCBhbmQgdG9wKSBmcm9tIGEgZ2l2ZW4gcmVjdCBvYmplY3RcbiAqL1xuaW1wb3J0IHsgZ2V0U2Nyb2xsIH0gZnJvbSAnLi9nZXRTY3JvbGwnO1xuaW1wb3J0IHsgT2Zmc2V0cyB9IGZyb20gJy4uL21vZGVscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBpbmNsdWRlU2Nyb2xsKHJlY3Q6IE9mZnNldHMsIGVsZW1lbnQ6IEhUTUxFbGVtZW50LCBzdWJ0cmFjdCA9IGZhbHNlKSB7XG4gIGNvbnN0IHNjcm9sbFRvcCA9IGdldFNjcm9sbChlbGVtZW50LCAndG9wJyk7XG4gIGNvbnN0IHNjcm9sbExlZnQgPSBnZXRTY3JvbGwoZWxlbWVudCwgJ2xlZnQnKTtcbiAgY29uc3QgbW9kaWZpZXIgPSBzdWJ0cmFjdCA/IC0xIDogMTtcbiAgcmVjdC50b3AgKz0gc2Nyb2xsVG9wICogbW9kaWZpZXI7XG4gIHJlY3QuYm90dG9tICs9IHNjcm9sbFRvcCAqIG1vZGlmaWVyO1xuICByZWN0LmxlZnQgKz0gc2Nyb2xsTGVmdCAqIG1vZGlmaWVyO1xuICByZWN0LnJpZ2h0ICs9IHNjcm9sbExlZnQgKiBtb2RpZmllcjtcblxuICByZXR1cm4gcmVjdDtcbn1cbiIsImltcG9ydCB7IGdldEJvdW5kaW5nQ2xpZW50UmVjdCB9IGZyb20gJy4vZ2V0Qm91bmRpbmdDbGllbnRSZWN0JztcbmltcG9ydCB7IGdldENsaWVudFJlY3QgfSBmcm9tICcuL2dldENsaWVudFJlY3QnO1xuaW1wb3J0IHsgZ2V0U2Nyb2xsUGFyZW50IH0gZnJvbSAnLi9nZXRTY3JvbGxQYXJlbnQnO1xuaW1wb3J0IHsgZ2V0U3R5bGVDb21wdXRlZFByb3BlcnR5IH0gZnJvbSAnLi9nZXRTdHlsZUNvbXB1dGVkUHJvcGVydHknO1xuaW1wb3J0IHsgaW5jbHVkZVNjcm9sbCB9IGZyb20gJy4vaW5jbHVkZVNjcm9sbCc7XG5pbXBvcnQgeyBpc0lFIGFzIHJ1bklzSUUgfSBmcm9tICcuL2lzSUUnO1xuaW1wb3J0IHsgT2Zmc2V0cyB9IGZyb20gJy4uL21vZGVscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBnZXRPZmZzZXRSZWN0UmVsYXRpdmVUb0FyYml0cmFyeU5vZGUoXG4gIGNoaWxkcmVuOiBIVE1MRWxlbWVudCxcbiAgcGFyZW50OiBIVE1MRWxlbWVudCxcbiAgZml4ZWRQb3NpdGlvbiA9IGZhbHNlXG4pOiBPZmZzZXRzIHtcbiAgY29uc3QgaXNJRTEwID0gcnVuSXNJRSgxMCk7XG4gIGNvbnN0IGlzSFRNTCA9IHBhcmVudC5ub2RlTmFtZSA9PT0gJ0hUTUwnO1xuICBjb25zdCBjaGlsZHJlblJlY3Q6IGFueSA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChjaGlsZHJlbik7XG4gIGNvbnN0IHBhcmVudFJlY3Q6IGFueSA9IGdldEJvdW5kaW5nQ2xpZW50UmVjdChwYXJlbnQpO1xuICBjb25zdCBzY3JvbGxQYXJlbnQgPSBnZXRTY3JvbGxQYXJlbnQoY2hpbGRyZW4pO1xuXG4gIGNvbnN0IHN0eWxlcyA9IGdldFN0eWxlQ29tcHV0ZWRQcm9wZXJ0eShwYXJlbnQpO1xuICBjb25zdCBib3JkZXJUb3BXaWR0aCA9IHBhcnNlRmxvYXQoc3R5bGVzLmJvcmRlclRvcFdpZHRoKTtcbiAgY29uc3QgYm9yZGVyTGVmdFdpZHRoID0gcGFyc2VGbG9hdChzdHlsZXMuYm9yZGVyTGVmdFdpZHRoKTtcblxuICAvLyBJbiBjYXNlcyB3aGVyZSB0aGUgcGFyZW50IGlzIGZpeGVkLCB3ZSBtdXN0IGlnbm9yZSBuZWdhdGl2ZSBzY3JvbGwgaW4gb2Zmc2V0IGNhbGNcbiAgaWYgKGZpeGVkUG9zaXRpb24gJiYgaXNIVE1MKSB7XG4gICAgcGFyZW50UmVjdC50b3AgPSBNYXRoLm1heChwYXJlbnRSZWN0LnRvcCwgMCk7XG4gICAgcGFyZW50UmVjdC5sZWZ0ID0gTWF0aC5tYXgocGFyZW50UmVjdC5sZWZ0LCAwKTtcbiAgfVxuXG4gIGxldCBvZmZzZXRzOiBPZmZzZXRzID0gZ2V0Q2xpZW50UmVjdCh7XG4gICAgdG9wOiBjaGlsZHJlblJlY3QudG9wIC0gcGFyZW50UmVjdC50b3AgLSBib3JkZXJUb3BXaWR0aCxcbiAgICBsZWZ0OiBjaGlsZHJlblJlY3QubGVmdCAtIHBhcmVudFJlY3QubGVmdCAtIGJvcmRlckxlZnRXaWR0aCxcbiAgICB3aWR0aDogY2hpbGRyZW5SZWN0LndpZHRoLFxuICAgIGhlaWdodDogY2hpbGRyZW5SZWN0LmhlaWdodFxuICB9KTtcblxuICBvZmZzZXRzLm1hcmdpblRvcCA9IDA7XG4gIG9mZnNldHMubWFyZ2luTGVmdCA9IDA7XG5cbiAgLy8gU3VidHJhY3QgbWFyZ2lucyBvZiBkb2N1bWVudEVsZW1lbnQgaW4gY2FzZSBpdCdzIGJlaW5nIHVzZWQgYXMgcGFyZW50XG4gIC8vIHdlIGRvIHRoaXMgb25seSBvbiBIVE1MIGJlY2F1c2UgaXQncyB0aGUgb25seSBlbGVtZW50IHRoYXQgYmVoYXZlc1xuICAvLyBkaWZmZXJlbnRseSB3aGVuIG1hcmdpbnMgYXJlIGFwcGxpZWQgdG8gaXQuIFRoZSBtYXJnaW5zIGFyZSBpbmNsdWRlZCBpblxuICAvLyB0aGUgYm94IG9mIHRoZSBkb2N1bWVudEVsZW1lbnQsIGluIHRoZSBvdGhlciBjYXNlcyBub3QuXG4gIGlmICghaXNJRTEwICYmIGlzSFRNTCkge1xuICAgIGNvbnN0IG1hcmdpblRvcCA9IHBhcnNlRmxvYXQoc3R5bGVzLm1hcmdpblRvcCk7XG4gICAgY29uc3QgbWFyZ2luTGVmdCA9IHBhcnNlRmxvYXQoc3R5bGVzLm1hcmdpbkxlZnQpO1xuXG4gICAgb2Zmc2V0cy50b3AgLT0gYm9yZGVyVG9wV2lkdGggLSBtYXJnaW5Ub3A7XG4gICAgb2Zmc2V0cy5ib3R0b20gLT0gYm9yZGVyVG9wV2lkdGggLSBtYXJnaW5Ub3A7XG4gICAgb2Zmc2V0cy5sZWZ0IC09IGJvcmRlckxlZnRXaWR0aCAtIG1hcmdpbkxlZnQ7XG4gICAgb2Zmc2V0cy5yaWdodCAtPSBib3JkZXJMZWZ0V2lkdGggLSBtYXJnaW5MZWZ0O1xuXG4gICAgLy8gQXR0YWNoIG1hcmdpblRvcCBhbmQgbWFyZ2luTGVmdCBiZWNhdXNlIGluIHNvbWUgY2lyY3Vtc3RhbmNlcyB3ZSBtYXkgbmVlZCB0aGVtXG4gICAgb2Zmc2V0cy5tYXJnaW5Ub3AgPSBtYXJnaW5Ub3A7XG4gICAgb2Zmc2V0cy5tYXJnaW5MZWZ0ID0gbWFyZ2luTGVmdDtcbiAgfVxuXG4gIGlmIChcbiAgICBpc0lFMTAgJiYgIWZpeGVkUG9zaXRpb25cbiAgICAgID8gcGFyZW50LmNvbnRhaW5zKHNjcm9sbFBhcmVudClcbiAgICAgIDogcGFyZW50ID09PSBzY3JvbGxQYXJlbnQgJiYgc2Nyb2xsUGFyZW50Lm5vZGVOYW1lICE9PSAnQk9EWSdcbiAgKSB7XG4gICAgb2Zmc2V0cyA9IGluY2x1ZGVTY3JvbGwob2Zmc2V0cywgcGFyZW50KTtcbiAgfVxuXG4gIHJldHVybiBvZmZzZXRzO1xufVxuIiwiaW1wb3J0IHsgZ2V0Q2xpZW50UmVjdCB9IGZyb20gJy4vZ2V0Q2xpZW50UmVjdCc7XG5pbXBvcnQgeyBnZXRPZmZzZXRSZWN0UmVsYXRpdmVUb0FyYml0cmFyeU5vZGUgfSBmcm9tICcuL2dldE9mZnNldFJlY3RSZWxhdGl2ZVRvQXJiaXRyYXJ5Tm9kZSc7XG5pbXBvcnQgeyBnZXRTY3JvbGwgfSBmcm9tICcuL2dldFNjcm9sbCc7XG5pbXBvcnQgeyBPZmZzZXRzIH0gZnJvbSAnLi4vbW9kZWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldFZpZXdwb3J0T2Zmc2V0UmVjdFJlbGF0aXZlVG9BcnRiaXRyYXJ5Tm9kZShlbGVtZW50OiBIVE1MRWxlbWVudCwgZXhjbHVkZVNjcm9sbCA9IGZhbHNlKTogT2Zmc2V0cyB7XG4gIGNvbnN0IGh0bWwgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICBjb25zdCByZWxhdGl2ZU9mZnNldCA9IGdldE9mZnNldFJlY3RSZWxhdGl2ZVRvQXJiaXRyYXJ5Tm9kZShlbGVtZW50LCBodG1sKTtcbiAgY29uc3Qgd2lkdGggPSBNYXRoLm1heChodG1sLmNsaWVudFdpZHRoLCB3aW5kb3cuaW5uZXJXaWR0aCB8fCAwKTtcbiAgY29uc3QgaGVpZ2h0ID0gTWF0aC5tYXgoaHRtbC5jbGllbnRIZWlnaHQsIHdpbmRvdy5pbm5lckhlaWdodCB8fCAwKTtcblxuICBjb25zdCBzY3JvbGxUb3AgPSAhZXhjbHVkZVNjcm9sbCA/IGdldFNjcm9sbChodG1sKSA6IDA7XG4gIGNvbnN0IHNjcm9sbExlZnQgPSAhZXhjbHVkZVNjcm9sbCA/IGdldFNjcm9sbChodG1sLCAnbGVmdCcpIDogMDtcblxuICBjb25zdCBvZmZzZXQgPSB7XG4gICAgdG9wOiBzY3JvbGxUb3AgLSBOdW1iZXIocmVsYXRpdmVPZmZzZXQudG9wKSArIE51bWJlcihyZWxhdGl2ZU9mZnNldC5tYXJnaW5Ub3ApLFxuICAgIGxlZnQ6IHNjcm9sbExlZnQgLSBOdW1iZXIocmVsYXRpdmVPZmZzZXQubGVmdCkgKyBOdW1iZXIocmVsYXRpdmVPZmZzZXQubWFyZ2luTGVmdCksXG4gICAgd2lkdGgsXG4gICAgaGVpZ2h0XG4gIH07XG5cbiAgcmV0dXJuIGdldENsaWVudFJlY3Qob2Zmc2V0KTtcbn1cbiIsIi8qKlxuICogQ2hlY2sgaWYgdGhlIGdpdmVuIGVsZW1lbnQgaXMgZml4ZWQgb3IgaXMgaW5zaWRlIGEgZml4ZWQgcGFyZW50XG4gKi9cbmltcG9ydCB7IGdldFN0eWxlQ29tcHV0ZWRQcm9wZXJ0eSB9IGZyb20gJy4vZ2V0U3R5bGVDb21wdXRlZFByb3BlcnR5JztcbmltcG9ydCB7IGdldFBhcmVudE5vZGUgfSBmcm9tICcuL2dldFBhcmVudE5vZGUnO1xuXG5leHBvcnQgZnVuY3Rpb24gaXNGaXhlZChlbGVtZW50OiBIVE1MRWxlbWVudCk6IGJvb2xlYW4ge1xuICBjb25zdCBub2RlTmFtZSA9IGVsZW1lbnQubm9kZU5hbWU7XG4gIGlmIChub2RlTmFtZSA9PT0gJ0JPRFknIHx8IG5vZGVOYW1lID09PSAnSFRNTCcpIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbiAgaWYgKGdldFN0eWxlQ29tcHV0ZWRQcm9wZXJ0eShlbGVtZW50LCAncG9zaXRpb24nKSA9PT0gJ2ZpeGVkJykge1xuICAgIHJldHVybiB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGlzRml4ZWQoZ2V0UGFyZW50Tm9kZShlbGVtZW50KSk7XG59XG4iLCIvKipcbiAqIEZpbmRzIHRoZSBmaXJzdCBwYXJlbnQgb2YgYW4gZWxlbWVudCB0aGF0IGhhcyBhIHRyYW5zZm9ybWVkIHByb3BlcnR5IGRlZmluZWRcbiAqL1xuXG5pbXBvcnQgeyBnZXRTdHlsZUNvbXB1dGVkUHJvcGVydHkgfSBmcm9tICcuL2dldFN0eWxlQ29tcHV0ZWRQcm9wZXJ0eSc7XG5pbXBvcnQgeyBpc0lFIH0gZnJvbSAnLi9pc0lFJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEZpeGVkUG9zaXRpb25PZmZzZXRQYXJlbnQoZWxlbWVudDogSFRNTEVsZW1lbnQpOiBIVE1MRWxlbWVudCB7XG4gIC8vIFRoaXMgY2hlY2sgaXMgbmVlZGVkIHRvIGF2b2lkIGVycm9ycyBpbiBjYXNlIG9uZSBvZiB0aGUgZWxlbWVudHMgaXNuJ3QgZGVmaW5lZCBmb3IgYW55IHJlYXNvblxuICBpZiAoIWVsZW1lbnQgfHwgIWVsZW1lbnQucGFyZW50RWxlbWVudCB8fCBpc0lFKCkpIHtcbiAgIHJldHVybiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQ7XG4gIH1cblxuICBsZXQgZWwgPSBlbGVtZW50LnBhcmVudEVsZW1lbnQ7XG5cbiAgd2hpbGUgKGVsICYmIGdldFN0eWxlQ29tcHV0ZWRQcm9wZXJ0eShlbCwgJ3RyYW5zZm9ybScpID09PSAnbm9uZScpIHtcbiAgICBlbCA9IGVsLnBhcmVudEVsZW1lbnQ7XG4gIH1cblxuICByZXR1cm4gZWwgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xufVxuIiwiLyoqXG4gKiBDb21wdXRlZCB0aGUgYm91bmRhcmllcyBsaW1pdHMgYW5kIHJldHVybiB0aGVtXG4gKi9cbmltcG9ydCB7IGdldFNjcm9sbFBhcmVudCB9IGZyb20gJy4vZ2V0U2Nyb2xsUGFyZW50JztcbmltcG9ydCB7IGdldFBhcmVudE5vZGUgfSBmcm9tICcuL2dldFBhcmVudE5vZGUnO1xuaW1wb3J0IHsgZmluZENvbW1vbk9mZnNldFBhcmVudCB9IGZyb20gJy4vZmluZENvbW1vbk9mZnNldFBhcmVudCc7XG5pbXBvcnQgeyBnZXRPZmZzZXRSZWN0UmVsYXRpdmVUb0FyYml0cmFyeU5vZGUgfSBmcm9tICcuL2dldE9mZnNldFJlY3RSZWxhdGl2ZVRvQXJiaXRyYXJ5Tm9kZSc7XG5pbXBvcnQgeyBnZXRWaWV3cG9ydE9mZnNldFJlY3RSZWxhdGl2ZVRvQXJ0Yml0cmFyeU5vZGUgfSBmcm9tICcuL2dldFZpZXdwb3J0T2Zmc2V0UmVjdFJlbGF0aXZlVG9BcnRiaXRyYXJ5Tm9kZSc7XG5pbXBvcnQgeyBnZXRXaW5kb3dTaXplcyB9IGZyb20gJy4vZ2V0V2luZG93U2l6ZXMnO1xuaW1wb3J0IHsgaXNGaXhlZCB9IGZyb20gJy4vaXNGaXhlZCc7XG5pbXBvcnQgeyBnZXRGaXhlZFBvc2l0aW9uT2Zmc2V0UGFyZW50IH0gZnJvbSAnLi9nZXRGaXhlZFBvc2l0aW9uT2Zmc2V0UGFyZW50JztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldEJvdW5kYXJpZXMoXG4gIHRhcmdldDogSFRNTEVsZW1lbnQsXG4gIGhvc3Q6IEhUTUxFbGVtZW50LFxuICBwYWRkaW5nID0gMCxcbiAgYm91bmRhcmllc0VsZW1lbnQ6IHN0cmluZyxcbiAgZml4ZWRQb3NpdGlvbiA9IGZhbHNlXG4pIHtcbiAgLy8gTk9URTogMSBET00gYWNjZXNzIGhlcmVcblxuICBsZXQgYm91bmRhcmllczogYW55ID0geyB0b3A6IDAsIGxlZnQ6IDAgfTtcbiAgY29uc3Qgb2Zmc2V0UGFyZW50ID0gZml4ZWRQb3NpdGlvbiA/IGdldEZpeGVkUG9zaXRpb25PZmZzZXRQYXJlbnQodGFyZ2V0KSA6IGZpbmRDb21tb25PZmZzZXRQYXJlbnQodGFyZ2V0LCBob3N0KTtcblxuICAvLyBIYW5kbGUgdmlld3BvcnQgY2FzZVxuICBpZiAoYm91bmRhcmllc0VsZW1lbnQgPT09ICd2aWV3cG9ydCcpIHtcbiAgICBib3VuZGFyaWVzID0gZ2V0Vmlld3BvcnRPZmZzZXRSZWN0UmVsYXRpdmVUb0FydGJpdHJhcnlOb2RlKG9mZnNldFBhcmVudCwgZml4ZWRQb3NpdGlvbik7XG4gIH0gZWxzZSB7XG4gICAgLy8gSGFuZGxlIG90aGVyIGNhc2VzIGJhc2VkIG9uIERPTSBlbGVtZW50IHVzZWQgYXMgYm91bmRhcmllc1xuICAgIGxldCBib3VuZGFyaWVzTm9kZTtcbiAgICBpZiAoYm91bmRhcmllc0VsZW1lbnQgPT09ICdzY3JvbGxQYXJlbnQnKSB7XG4gICAgICBib3VuZGFyaWVzTm9kZSA9IGdldFNjcm9sbFBhcmVudChnZXRQYXJlbnROb2RlKGhvc3QpKTtcbiAgICAgIGlmIChib3VuZGFyaWVzTm9kZS5ub2RlTmFtZSA9PT0gJ0JPRFknKSB7XG4gICAgICAgIGJvdW5kYXJpZXNOb2RlID0gdGFyZ2V0Lm93bmVyRG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICAgICAgfVxuICAgIH0gZWxzZSBpZiAoYm91bmRhcmllc0VsZW1lbnQgPT09ICd3aW5kb3cnKSB7XG4gICAgICBib3VuZGFyaWVzTm9kZSA9IHRhcmdldC5vd25lckRvY3VtZW50LmRvY3VtZW50RWxlbWVudDtcbiAgICB9IGVsc2Uge1xuICAgICAgYm91bmRhcmllc05vZGUgPSBib3VuZGFyaWVzRWxlbWVudDtcbiAgICB9XG5cbiAgICBjb25zdCBvZmZzZXRzID0gZ2V0T2Zmc2V0UmVjdFJlbGF0aXZlVG9BcmJpdHJhcnlOb2RlKFxuICAgICAgYm91bmRhcmllc05vZGUsXG4gICAgICBvZmZzZXRQYXJlbnQsXG4gICAgICBmaXhlZFBvc2l0aW9uXG4gICAgKTtcblxuICAgIC8vIEluIGNhc2Ugb2YgSFRNTCwgd2UgbmVlZCBhIGRpZmZlcmVudCBjb21wdXRhdGlvblxuICAgIGlmIChib3VuZGFyaWVzTm9kZS5ub2RlTmFtZSA9PT0gJ0hUTUwnICYmICFpc0ZpeGVkKG9mZnNldFBhcmVudCkpIHtcbiAgICAgIGNvbnN0IHsgaGVpZ2h0LCB3aWR0aCB9ID0gZ2V0V2luZG93U2l6ZXModGFyZ2V0Lm93bmVyRG9jdW1lbnQpO1xuICAgICAgYm91bmRhcmllcy50b3AgKz0gb2Zmc2V0cy50b3AgLSBvZmZzZXRzLm1hcmdpblRvcDtcbiAgICAgIGJvdW5kYXJpZXMuYm90dG9tID0gTnVtYmVyKGhlaWdodCkgKyBOdW1iZXIob2Zmc2V0cy50b3ApO1xuICAgICAgYm91bmRhcmllcy5sZWZ0ICs9IG9mZnNldHMubGVmdCAtIG9mZnNldHMubWFyZ2luTGVmdDtcbiAgICAgIGJvdW5kYXJpZXMucmlnaHQgPSBOdW1iZXIod2lkdGgpICsgTnVtYmVyKG9mZnNldHMubGVmdCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGZvciBhbGwgdGhlIG90aGVyIERPTSBlbGVtZW50cywgdGhpcyBvbmUgaXMgZ29vZFxuICAgICAgYm91bmRhcmllcyA9IG9mZnNldHM7XG4gICAgfVxuICB9XG5cbiAgLy8gQWRkIHBhZGRpbmdzXG4gIGJvdW5kYXJpZXMubGVmdCArPSBwYWRkaW5nO1xuICBib3VuZGFyaWVzLnRvcCArPSBwYWRkaW5nO1xuICBib3VuZGFyaWVzLnJpZ2h0IC09IHBhZGRpbmc7XG4gIGJvdW5kYXJpZXMuYm90dG9tIC09IHBhZGRpbmc7XG5cbiAgcmV0dXJuIGJvdW5kYXJpZXM7XG59XG4iLCIvKipcbiAqIFV0aWxpdHkgdXNlZCB0byB0cmFuc2Zvcm0gdGhlIGBhdXRvYCBwbGFjZW1lbnQgdG8gdGhlIHBsYWNlbWVudCB3aXRoIG1vcmVcbiAqIGF2YWlsYWJsZSBzcGFjZS5cbiAqL1xuaW1wb3J0IHsgZ2V0Qm91bmRhcmllcyB9IGZyb20gJy4vZ2V0Qm91bmRhcmllcyc7XG5pbXBvcnQgeyBPZmZzZXRzIH0gZnJvbSAnLi4vbW9kZWxzJztcblxuZnVuY3Rpb24gZ2V0QXJlYSh7IHdpZHRoLCBoZWlnaHQgfTogeyBba2V5OiBzdHJpbmddOiBudW1iZXIgfSkge1xuICByZXR1cm4gd2lkdGggKiBoZWlnaHQ7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjb21wdXRlQXV0b1BsYWNlbWVudChcbiAgcGxhY2VtZW50OiBzdHJpbmcsXG4gIHJlZlJlY3Q6IE9mZnNldHMsXG4gIHRhcmdldDogSFRNTEVsZW1lbnQsXG4gIGhvc3Q6IEhUTUxFbGVtZW50LFxuICBib3VuZGFyaWVzRWxlbWVudDogc3RyaW5nLFxuICBwYWRkaW5nID0gMFxuKSB7XG4gIGlmIChwbGFjZW1lbnQuaW5kZXhPZignYXV0bycpID09PSAtMSkge1xuICAgIHJldHVybiBwbGFjZW1lbnQ7XG4gIH1cblxuICBpZiAocGxhY2VtZW50LmluZGV4T2YoJ2F1dG8nKSAhPT0gLTFcbiAgICAmJiAocGxhY2VtZW50LmluZGV4T2YoJ2xlZnQnKSAhPT0gLTFcbiAgICB8fCBwbGFjZW1lbnQuaW5kZXhPZigncmlnaHQnKSAhPT0gLTFcbiAgICB8fCBwbGFjZW1lbnQuaW5kZXhPZigndG9wJykgIT09IC0xXG4gICAgfHwgcGxhY2VtZW50LmluZGV4T2YoJ2JvdHRvbScpICE9PSAtMSkpIHtcblxuICAgIHJldHVybiBwbGFjZW1lbnQuc3BsaXQoJyAnKVsxXSB8fCAnJztcbiAgfVxuXG4gIGNvbnN0IGJvdW5kYXJpZXMgPSBnZXRCb3VuZGFyaWVzKHRhcmdldCwgaG9zdCwgcGFkZGluZywgYm91bmRhcmllc0VsZW1lbnQpO1xuXG4gIGNvbnN0IHJlY3RzOiBhbnkgPSB7XG4gICAgdG9wOiB7XG4gICAgICB3aWR0aDogYm91bmRhcmllcy53aWR0aCxcbiAgICAgIGhlaWdodDogcmVmUmVjdC50b3AgLSBib3VuZGFyaWVzLnRvcFxuICAgIH0sXG4gICAgcmlnaHQ6IHtcbiAgICAgIHdpZHRoOiBib3VuZGFyaWVzLnJpZ2h0IC0gcmVmUmVjdC5yaWdodCxcbiAgICAgIGhlaWdodDogYm91bmRhcmllcy5oZWlnaHRcbiAgICB9LFxuICAgIGJvdHRvbToge1xuICAgICAgd2lkdGg6IGJvdW5kYXJpZXMud2lkdGgsXG4gICAgICBoZWlnaHQ6IGJvdW5kYXJpZXMuYm90dG9tIC0gcmVmUmVjdC5ib3R0b21cbiAgICB9LFxuICAgIGxlZnQ6IHtcbiAgICAgIHdpZHRoOiByZWZSZWN0LmxlZnQgLSBib3VuZGFyaWVzLmxlZnQsXG4gICAgICBoZWlnaHQ6IGJvdW5kYXJpZXMuaGVpZ2h0XG4gICAgfVxuICB9O1xuXG4gIGNvbnN0IHNvcnRlZEFyZWFzID0gT2JqZWN0LmtleXMocmVjdHMpXG4gICAgLm1hcChrZXkgPT4gKHtcbiAgICAgIGtleSxcbiAgICAgIC4uLnJlY3RzW2tleV0sXG4gICAgICBhcmVhOiBnZXRBcmVhKHJlY3RzW2tleV0pXG4gICAgfSkpXG4gICAgLnNvcnQoKGEsIGIpID0+IGIuYXJlYSAtIGEuYXJlYSk7XG5cbiAgY29uc3QgZmlsdGVyZWRBcmVhcyA9IHNvcnRlZEFyZWFzLmZpbHRlcihcbiAgICAoeyB3aWR0aCwgaGVpZ2h0IH0pID0+XG4gICAgICB3aWR0aCA+PSB0YXJnZXQuY2xpZW50V2lkdGggJiYgaGVpZ2h0ID49IHRhcmdldC5jbGllbnRIZWlnaHRcbiAgKTtcblxuICBjb25zdCBjb21wdXRlZFBsYWNlbWVudDogc3RyaW5nID0gZmlsdGVyZWRBcmVhcy5sZW5ndGggPiAwXG4gICAgPyBmaWx0ZXJlZEFyZWFzWzBdLmtleVxuICAgIDogc29ydGVkQXJlYXNbMF0ua2V5O1xuXG4gIGNvbnN0IHZhcmlhdGlvbiA9IHBsYWNlbWVudC5zcGxpdCgnICcpWzFdO1xuXG4gIHRhcmdldC5jbGFzc05hbWUgPSB0YXJnZXQuY2xhc3NOYW1lLnJlcGxhY2UoL2F1dG8vZywgY29tcHV0ZWRQbGFjZW1lbnQpO1xuXG4gIHJldHVybiBjb21wdXRlZFBsYWNlbWVudCArICh2YXJpYXRpb24gPyBgLSR7dmFyaWF0aW9ufWAgOiAnJyk7XG59XG4iLCJpbXBvcnQgeyBEYXRhLCBPZmZzZXRzIH0gZnJvbSAnLi4vbW9kZWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGdldE9mZnNldHMoZGF0YTogRGF0YSk6IE9mZnNldHMge1xuICByZXR1cm4ge1xuICAgIHdpZHRoOiBkYXRhLm9mZnNldHMudGFyZ2V0LndpZHRoLFxuICAgIGhlaWdodDogZGF0YS5vZmZzZXRzLnRhcmdldC5oZWlnaHQsXG4gICAgbGVmdDogTWF0aC5mbG9vcihkYXRhLm9mZnNldHMudGFyZ2V0LmxlZnQpLFxuICAgIHRvcDogTWF0aC5yb3VuZChkYXRhLm9mZnNldHMudGFyZ2V0LnRvcCksXG4gICAgYm90dG9tOiBNYXRoLnJvdW5kKGRhdGEub2Zmc2V0cy50YXJnZXQuYm90dG9tKSxcbiAgICByaWdodDogTWF0aC5mbG9vcihkYXRhLm9mZnNldHMudGFyZ2V0LnJpZ2h0KVxuICB9O1xufVxuIiwiLyoqXG4gKiBHZXQgdGhlIG9wcG9zaXRlIHBsYWNlbWVudCBvZiB0aGUgZ2l2ZW4gb25lXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRPcHBvc2l0ZVBsYWNlbWVudChwbGFjZW1lbnQ6IHN0cmluZykge1xuICBjb25zdCBoYXNoID0geyBsZWZ0OiAncmlnaHQnLCByaWdodDogJ2xlZnQnLCBib3R0b206ICd0b3AnLCB0b3A6ICdib3R0b20nIH07XG5cbiAgcmV0dXJuIHBsYWNlbWVudC5yZXBsYWNlKC9sZWZ0fHJpZ2h0fGJvdHRvbXx0b3AvZywgbWF0Y2hlZCA9PiBoYXNoW21hdGNoZWRdKTtcbn1cbiIsIi8qKlxuICogR2V0IHRoZSBvcHBvc2l0ZSBwbGFjZW1lbnQgdmFyaWF0aW9uIG9mIHRoZSBnaXZlbiBvbmVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIGdldE9wcG9zaXRlVmFyaWF0aW9uKHZhcmlhdGlvbjogc3RyaW5nKSB7XG4gIGlmICh2YXJpYXRpb24gPT09ICdyaWdodCcpIHtcbiAgICByZXR1cm4gJ2xlZnQnO1xuICB9IGVsc2UgaWYgKHZhcmlhdGlvbiA9PT0gJ2xlZnQnKSB7XG4gICAgcmV0dXJuICdyaWdodCc7XG4gIH1cblxuICByZXR1cm4gdmFyaWF0aW9uO1xufVxuIiwiLyoqXG4gKiBHZXQgdGhlIG91dGVyIHNpemVzIG9mIHRoZSBnaXZlbiBlbGVtZW50IChvZmZzZXQgc2l6ZSArIG1hcmdpbnMpXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBnZXRPdXRlclNpemVzKGVsZW1lbnQ6IGFueSkge1xuICBjb25zdCB3aW5kb3cgPSBlbGVtZW50Lm93bmVyRG9jdW1lbnQuZGVmYXVsdFZpZXc7XG4gIGNvbnN0IHN0eWxlcyA9IHdpbmRvdy5nZXRDb21wdXRlZFN0eWxlKGVsZW1lbnQpO1xuICBjb25zdCB4ID0gcGFyc2VGbG9hdChzdHlsZXMubWFyZ2luVG9wIHx8IDApICsgcGFyc2VGbG9hdChzdHlsZXMubWFyZ2luQm90dG9tIHx8IDApO1xuICBjb25zdCB5ID0gcGFyc2VGbG9hdChzdHlsZXMubWFyZ2luTGVmdCB8fCAwKSArIHBhcnNlRmxvYXQoc3R5bGVzLm1hcmdpblJpZ2h0IHx8IDApO1xuXG4gIHJldHVybiB7XG4gICAgd2lkdGg6IE51bWJlcihlbGVtZW50Lm9mZnNldFdpZHRoKSArIHksXG4gICAgaGVpZ2h0OiBOdW1iZXIoZWxlbWVudC5vZmZzZXRIZWlnaHQpICsgeFxuICB9O1xufVxuIiwiLyoqXG4gKiBHZXQgb2Zmc2V0cyB0byB0aGUgcmVmZXJlbmNlIGVsZW1lbnRcbiAqL1xuaW1wb3J0IHsgZmluZENvbW1vbk9mZnNldFBhcmVudCB9IGZyb20gJy4vZmluZENvbW1vbk9mZnNldFBhcmVudCc7XG5pbXBvcnQgeyBnZXRPZmZzZXRSZWN0UmVsYXRpdmVUb0FyYml0cmFyeU5vZGUgfSBmcm9tICcuL2dldE9mZnNldFJlY3RSZWxhdGl2ZVRvQXJiaXRyYXJ5Tm9kZSc7XG5pbXBvcnQgeyBnZXRGaXhlZFBvc2l0aW9uT2Zmc2V0UGFyZW50IH0gZnJvbSAnLi9nZXRGaXhlZFBvc2l0aW9uT2Zmc2V0UGFyZW50JztcbmltcG9ydCB7IE9mZnNldHMgfSBmcm9tICcuLi9tb2RlbHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0UmVmZXJlbmNlT2Zmc2V0cyhcbiAgdGFyZ2V0OiBIVE1MRWxlbWVudCxcbiAgaG9zdDogSFRNTEVsZW1lbnQsXG4gIGZpeGVkUG9zaXRpb246IGJvb2xlYW4gPSBudWxsXG4pOiBPZmZzZXRzIHtcbiAgY29uc3QgY29tbW9uT2Zmc2V0UGFyZW50ID0gZml4ZWRQb3NpdGlvblxuICAgID8gZ2V0Rml4ZWRQb3NpdGlvbk9mZnNldFBhcmVudCh0YXJnZXQpXG4gICAgOiBmaW5kQ29tbW9uT2Zmc2V0UGFyZW50KHRhcmdldCwgaG9zdCk7XG5cbiAgcmV0dXJuIGdldE9mZnNldFJlY3RSZWxhdGl2ZVRvQXJiaXRyYXJ5Tm9kZShob3N0LCBjb21tb25PZmZzZXRQYXJlbnQsIGZpeGVkUG9zaXRpb24pO1xufVxuIiwiLyoqXG4gKiBHZXQgb2Zmc2V0cyB0byB0aGUgdGFyZ2V0XG4gKi9cbmltcG9ydCB7IGdldE9wcG9zaXRlUGxhY2VtZW50IH0gZnJvbSAnLi9nZXRPcHBvc2l0ZVBsYWNlbWVudCc7XG5pbXBvcnQgeyBnZXRPdXRlclNpemVzIH0gZnJvbSAnLi9nZXRPdXRlclNpemVzJztcbmltcG9ydCB7IE9mZnNldHMgfSBmcm9tICcuLi9tb2RlbHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZ2V0VGFyZ2V0T2Zmc2V0cyhcbiAgdGFyZ2V0OiBIVE1MRWxlbWVudCxcbiAgaG9zdE9mZnNldHM6IE9mZnNldHMsXG4gIHBvc2l0aW9uOiBzdHJpbmdcbik6IE9mZnNldHMge1xuICBjb25zdCBwbGFjZW1lbnQgPSBwb3NpdGlvbi5zcGxpdCgnICcpWzBdO1xuXG4gIC8vIEdldCB0YXJnZXQgbm9kZSBzaXplc1xuICBjb25zdCB0YXJnZXRSZWN0ID0gZ2V0T3V0ZXJTaXplcyh0YXJnZXQpO1xuXG4gIC8vIEFkZCBwb3NpdGlvbiwgd2lkdGggYW5kIGhlaWdodCB0byBvdXIgb2Zmc2V0cyBvYmplY3RcbiAgY29uc3QgdGFyZ2V0T2Zmc2V0cyA9IHtcbiAgICB3aWR0aDogdGFyZ2V0UmVjdC53aWR0aCxcbiAgICBoZWlnaHQ6IHRhcmdldFJlY3QuaGVpZ2h0XG4gIH07XG5cbiAgLy8gZGVwZW5kaW5nIGJ5IHRoZSB0YXJnZXQgcGxhY2VtZW50IHdlIGhhdmUgdG8gY29tcHV0ZSBpdHMgb2Zmc2V0cyBzbGlnaHRseSBkaWZmZXJlbnRseVxuICBjb25zdCBpc0hvcml6ID0gWydyaWdodCcsICdsZWZ0J10uaW5kZXhPZihwbGFjZW1lbnQpICE9PSAtMTtcbiAgY29uc3QgbWFpblNpZGUgPSBpc0hvcml6ID8gJ3RvcCcgOiAnbGVmdCc7XG4gIGNvbnN0IHNlY29uZGFyeVNpZGUgPSBpc0hvcml6ID8gJ2xlZnQnIDogJ3RvcCc7XG4gIGNvbnN0IG1lYXN1cmVtZW50ID0gaXNIb3JpeiA/ICdoZWlnaHQnIDogJ3dpZHRoJztcbiAgY29uc3Qgc2Vjb25kYXJ5TWVhc3VyZW1lbnQgPSAhaXNIb3JpeiA/ICdoZWlnaHQnIDogJ3dpZHRoJztcblxuICB0YXJnZXRPZmZzZXRzW21haW5TaWRlXSA9XG4gICAgaG9zdE9mZnNldHNbbWFpblNpZGVdICtcbiAgICBob3N0T2Zmc2V0c1ttZWFzdXJlbWVudF0gLyAyIC1cbiAgICB0YXJnZXRSZWN0W21lYXN1cmVtZW50XSAvIDI7XG5cbiAgdGFyZ2V0T2Zmc2V0c1tzZWNvbmRhcnlTaWRlXSA9IHBsYWNlbWVudCA9PT0gc2Vjb25kYXJ5U2lkZVxuICAgID8gaG9zdE9mZnNldHNbc2Vjb25kYXJ5U2lkZV0gLSB0YXJnZXRSZWN0W3NlY29uZGFyeU1lYXN1cmVtZW50XVxuICAgIDogaG9zdE9mZnNldHNbZ2V0T3Bwb3NpdGVQbGFjZW1lbnQoc2Vjb25kYXJ5U2lkZSldO1xuXG4gIHJldHVybiB0YXJnZXRPZmZzZXRzO1xufVxuIiwiLyoqXG4gKiBUZWxscyBpZiBhIGdpdmVuIGlucHV0IGlzIGEgbnVtYmVyXG4gKi9cbmV4cG9ydCBmdW5jdGlvbiBpc051bWVyaWMobjogYW55KSB7XG4gIHJldHVybiBuICE9PSAnJyAmJiAhaXNOYU4ocGFyc2VGbG9hdChuKSkgJiYgaXNGaW5pdGUobik7XG59XG4iLCIvKipcbiAqIFNldCB0aGUgc3R5bGUgdG8gdGhlIGdpdmVuIHBvcHBlclxuICovXG5pbXBvcnQgeyBSZW5kZXJlcjIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgRGF0YSB9IGZyb20gJy4uL21vZGVscyc7XG5pbXBvcnQgeyBnZXRPZmZzZXRzLCBzZXRTdHlsZXMgfSBmcm9tICcuL2luZGV4JztcblxuZXhwb3J0IGZ1bmN0aW9uIHNldEFsbFN0eWxlcyhkYXRhOiBEYXRhLCByZW5kZXJlcj86IFJlbmRlcmVyMik6IHZvaWQge1xuICBjb25zdCB0YXJnZXQgPSBkYXRhLmluc3RhbmNlLnRhcmdldDtcblxuICBjb25zdCBvZmZzZXRzID0gZ2V0T2Zmc2V0cyhkYXRhKTtcblxuICBzZXRTdHlsZXModGFyZ2V0LCB7XG4gICAgJ3dpbGwtY2hhbmdlJzogJ3RyYW5zZm9ybScsXG4gICAgdG9wOiAnMHB4JyxcbiAgICBsZWZ0OiAnMHB4JyxcbiAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUzZCgke29mZnNldHMubGVmdH1weCwgJHtvZmZzZXRzLnRvcH1weCwgMHB4KWBcbiAgfSwgcmVuZGVyZXIpO1xuXG4gIGlmIChkYXRhLmluc3RhbmNlLmFycm93KSB7XG4gICAgc2V0U3R5bGVzKGRhdGEuaW5zdGFuY2UuYXJyb3csIGRhdGEub2Zmc2V0cy5hcnJvdywgcmVuZGVyZXIpO1xuICB9XG5cbiAgaWYgKGRhdGEucGxhY2VtZW50QXV0bykge1xuICAgIGlmIChyZW5kZXJlcikge1xuICAgICAgcmVuZGVyZXIuc2V0QXR0cmlidXRlKHRhcmdldCwgJ2NsYXNzJyxcbiAgICAgICAgdGFyZ2V0LmNsYXNzTmFtZS5yZXBsYWNlKC9icy1wb3BvdmVyLWF1dG8vZywgYGJzLXBvcG92ZXItJHtkYXRhLnBsYWNlbWVudH1gKVxuICAgICAgKTtcbiAgICAgIHJlbmRlcmVyLnNldEF0dHJpYnV0ZSh0YXJnZXQsICdjbGFzcycsXG4gICAgICAgIHRhcmdldC5jbGFzc05hbWUucmVwbGFjZSgvYnMtdG9vbHRpcC1hdXRvL2csIGBicy10b29sdGlwLSR7ZGF0YS5wbGFjZW1lbnR9YClcbiAgICAgICk7XG5cbiAgICAgIHJlbmRlcmVyLnNldEF0dHJpYnV0ZSh0YXJnZXQsICdjbGFzcycsXG4gICAgICAgIHRhcmdldC5jbGFzc05hbWUucmVwbGFjZSgvXFxzYXV0by9nLCBgXFxzJHtkYXRhLnBsYWNlbWVudH1gKVxuICAgICAgKTtcblxuICAgICAgaWYgKHRhcmdldC5jbGFzc05hbWUubWF0Y2goL3BvcG92ZXIvZykpIHtcbiAgICAgICAgcmVuZGVyZXIuYWRkQ2xhc3ModGFyZ2V0LCAncG9wb3Zlci1hdXRvJyk7XG4gICAgICB9XG5cbiAgICAgIGlmICh0YXJnZXQuY2xhc3NOYW1lLm1hdGNoKC90b29sdGlwL2cpKSB7XG4gICAgICAgIHJlbmRlcmVyLmFkZENsYXNzKHRhcmdldCwgJ3Rvb2x0aXAtYXV0bycpO1xuICAgICAgfVxuXG5cbiAgICB9IGVsc2Uge1xuICAgICAgdGFyZ2V0LmNsYXNzTmFtZSA9IHRhcmdldC5jbGFzc05hbWUucmVwbGFjZSgvYnMtcG9wb3Zlci1hdXRvL2csIGBicy1wb3BvdmVyLSR7ZGF0YS5wbGFjZW1lbnR9YCk7XG4gICAgICB0YXJnZXQuY2xhc3NOYW1lID0gdGFyZ2V0LmNsYXNzTmFtZS5yZXBsYWNlKC9icy10b29sdGlwLWF1dG8vZywgYGJzLXRvb2x0aXAtJHtkYXRhLnBsYWNlbWVudH1gKTtcbiAgICAgIHRhcmdldC5jbGFzc05hbWUgPSB0YXJnZXQuY2xhc3NOYW1lLnJlcGxhY2UoL1xcc2F1dG8vZywgYFxccyR7ZGF0YS5wbGFjZW1lbnR9YCk7XG5cbiAgICAgIGlmICh0YXJnZXQuY2xhc3NOYW1lLm1hdGNoKC9wb3BvdmVyL2cpKSB7XG4gICAgICAgIHRhcmdldC5jbGFzc0xpc3QuYWRkKCdwb3BvdmVyLWF1dG8nKTtcbiAgICAgIH1cblxuICAgICAgaWYgKHRhcmdldC5jbGFzc05hbWUubWF0Y2goL3Rvb2x0aXAvZykpIHtcbiAgICAgICAgdGFyZ2V0LmNsYXNzTGlzdC5hZGQoJ3Rvb2x0aXAtYXV0bycpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChyZW5kZXJlcikge1xuICAgIHJlbmRlcmVyLnNldEF0dHJpYnV0ZSh0YXJnZXQsICdjbGFzcycsIHRhcmdldC5jbGFzc05hbWUucmVwbGFjZSgvbGVmdHxyaWdodHx0b3B8Ym90dG9tL2csIGAke2RhdGEucGxhY2VtZW50fWApKTtcbiAgfSBlbHNlIHtcbiAgICB0YXJnZXQuY2xhc3NOYW1lID0gdGFyZ2V0LmNsYXNzTmFtZS5yZXBsYWNlKC9sZWZ0fHJpZ2h0fHRvcHxib3R0b20vZywgYCR7ZGF0YS5wbGFjZW1lbnR9YCk7XG4gIH1cbn1cbiIsIi8qKlxuICogU2V0IHRoZSBzdHlsZSB0byB0aGUgZ2l2ZW4gcG9wcGVyXG4gKi9cbmltcG9ydCB7IFJlbmRlcmVyMiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBpc051bWVyaWMgfSBmcm9tICcuL2lzTnVtZXJpYyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzZXRTdHlsZXMoZWxlbWVudDogSFRNTEVsZW1lbnQsIHN0eWxlczogYW55LCByZW5kZXJlcj86IFJlbmRlcmVyMikge1xuICBPYmplY3Qua2V5cyhzdHlsZXMpLmZvckVhY2goKHByb3A6IGFueSkgPT4ge1xuICAgIGxldCB1bml0ID0gJyc7XG4gICAgLy8gYWRkIHVuaXQgaWYgdGhlIHZhbHVlIGlzIG51bWVyaWMgYW5kIGlzIG9uZSBvZiB0aGUgZm9sbG93aW5nXG4gICAgaWYgKFsnd2lkdGgnLCAnaGVpZ2h0JywgJ3RvcCcsICdyaWdodCcsICdib3R0b20nLCAnbGVmdCddLmluZGV4T2YocHJvcCkgIT09IC0xICYmXG4gICAgICBpc051bWVyaWMoc3R5bGVzW3Byb3BdKSkge1xuICAgICAgdW5pdCA9ICdweCc7XG4gICAgfVxuXG4gICAgaWYgKHJlbmRlcmVyKSB7XG4gICAgICByZW5kZXJlci5zZXRTdHlsZShlbGVtZW50LCBwcm9wLCBgJHtTdHJpbmcoc3R5bGVzW3Byb3BdKX0ke3VuaXR9YCk7XG5cbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBlbGVtZW50LnN0eWxlW3Byb3BdID0gU3RyaW5nKHN0eWxlc1twcm9wXSkgKyB1bml0O1xuICB9KTtcbn1cbiIsImltcG9ydCB7IGdldENsaWVudFJlY3QsIGdldE91dGVyU2l6ZXMsIGdldFN0eWxlQ29tcHV0ZWRQcm9wZXJ0eSB9IGZyb20gJy4uL3V0aWxzJztcbmltcG9ydCB7IERhdGEgfSBmcm9tICcuLi9tb2RlbHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gYXJyb3coZGF0YTogRGF0YSkge1xuICBsZXQgdGFyZ2V0T2Zmc2V0cyA9IGRhdGEub2Zmc2V0cy50YXJnZXQ7XG4gIC8vIGlmIGFycm93RWxlbWVudCBpcyBhIHN0cmluZywgc3VwcG9zZSBpdCdzIGEgQ1NTIHNlbGVjdG9yXG4gIGNvbnN0IGFycm93RWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsID0gZGF0YS5pbnN0YW5jZS50YXJnZXQucXVlcnlTZWxlY3RvcignLmFycm93Jyk7XG5cbiAgLy8gaWYgYXJyb3dFbGVtZW50IGlzIG5vdCBmb3VuZCwgZG9uJ3QgcnVuIHRoZSBtb2RpZmllclxuICBpZiAoIWFycm93RWxlbWVudCkge1xuICAgIHJldHVybiBkYXRhO1xuICB9XG5cbiAgY29uc3QgaXNWZXJ0aWNhbCA9IFsnbGVmdCcsICdyaWdodCddLmluZGV4T2YoZGF0YS5wbGFjZW1lbnQpICE9PSAtMTtcblxuICBjb25zdCBsZW4gPSBpc1ZlcnRpY2FsID8gJ2hlaWdodCcgOiAnd2lkdGgnO1xuICBjb25zdCBzaWRlQ2FwaXRhbGl6ZWQgPSBpc1ZlcnRpY2FsID8gJ1RvcCcgOiAnTGVmdCc7XG4gIGNvbnN0IHNpZGUgPSBzaWRlQ2FwaXRhbGl6ZWQudG9Mb3dlckNhc2UoKTtcbiAgY29uc3QgYWx0U2lkZSA9IGlzVmVydGljYWwgPyAnbGVmdCcgOiAndG9wJztcbiAgY29uc3Qgb3BTaWRlID0gaXNWZXJ0aWNhbCA/ICdib3R0b20nIDogJ3JpZ2h0JztcbiAgY29uc3QgYXJyb3dFbGVtZW50U2l6ZSA9IGdldE91dGVyU2l6ZXMoYXJyb3dFbGVtZW50KVtsZW5dO1xuXG4gIC8vIHRvcC9sZWZ0IHNpZGVcbiAgaWYgKGRhdGEub2Zmc2V0cy5ob3N0W29wU2lkZV0gLSBhcnJvd0VsZW1lbnRTaXplIDwgdGFyZ2V0T2Zmc2V0c1tzaWRlXSkge1xuICAgIHRhcmdldE9mZnNldHNbc2lkZV0gLT1cbiAgICAgIHRhcmdldE9mZnNldHNbc2lkZV0gLSAoZGF0YS5vZmZzZXRzLmhvc3Rbb3BTaWRlXSAtIGFycm93RWxlbWVudFNpemUpO1xuICB9XG4gIC8vIGJvdHRvbS9yaWdodCBzaWRlXG4gIGlmIChOdW1iZXIoZGF0YS5vZmZzZXRzLmhvc3Rbc2lkZV0pICsgTnVtYmVyKGFycm93RWxlbWVudFNpemUpID4gdGFyZ2V0T2Zmc2V0c1tvcFNpZGVdKSB7XG4gICAgdGFyZ2V0T2Zmc2V0c1tzaWRlXSArPVxuICAgICAgTnVtYmVyKGRhdGEub2Zmc2V0cy5ob3N0W3NpZGVdKSArIE51bWJlcihhcnJvd0VsZW1lbnRTaXplKSAtIE51bWJlcih0YXJnZXRPZmZzZXRzW29wU2lkZV0pO1xuICB9XG4gIHRhcmdldE9mZnNldHMgPSBnZXRDbGllbnRSZWN0KHRhcmdldE9mZnNldHMpO1xuXG4gIC8vIGNvbXB1dGUgY2VudGVyIG9mIHRoZSB0YXJnZXRcbiAgY29uc3QgY2VudGVyID0gTnVtYmVyKGRhdGEub2Zmc2V0cy5ob3N0W3NpZGVdKSArIE51bWJlcihkYXRhLm9mZnNldHMuaG9zdFtsZW5dIC8gMiAtIGFycm93RWxlbWVudFNpemUgLyAyKTtcblxuICAvLyBDb21wdXRlIHRoZSBzaWRlVmFsdWUgdXNpbmcgdGhlIHVwZGF0ZWQgdGFyZ2V0IG9mZnNldHNcbiAgLy8gdGFrZSB0YXJnZXQgbWFyZ2luIGluIGFjY291bnQgYmVjYXVzZSB3ZSBkb24ndCBoYXZlIHRoaXMgaW5mbyBhdmFpbGFibGVcbiAgY29uc3QgY3NzID0gZ2V0U3R5bGVDb21wdXRlZFByb3BlcnR5KGRhdGEuaW5zdGFuY2UudGFyZ2V0KTtcblxuICBjb25zdCB0YXJnZXRNYXJnaW5TaWRlID0gcGFyc2VGbG9hdChjc3NbYG1hcmdpbiR7c2lkZUNhcGl0YWxpemVkfWBdKTtcbiAgY29uc3QgdGFyZ2V0Qm9yZGVyU2lkZSA9IHBhcnNlRmxvYXQoY3NzW2Bib3JkZXIke3NpZGVDYXBpdGFsaXplZH1XaWR0aGBdKTtcbiAgbGV0IHNpZGVWYWx1ZSA9XG4gICAgY2VudGVyIC0gdGFyZ2V0T2Zmc2V0c1tzaWRlXSAtIHRhcmdldE1hcmdpblNpZGUgLSB0YXJnZXRCb3JkZXJTaWRlO1xuXG4gIC8vIHByZXZlbnQgYXJyb3dFbGVtZW50IGZyb20gYmVpbmcgcGxhY2VkIG5vdCBjb250aWd1b3VzbHkgdG8gaXRzIHRhcmdldFxuICBzaWRlVmFsdWUgPSBNYXRoLm1heChNYXRoLm1pbih0YXJnZXRPZmZzZXRzW2xlbl0gLSBhcnJvd0VsZW1lbnRTaXplLCBzaWRlVmFsdWUpLCAwKTtcblxuICBkYXRhLm9mZnNldHMuYXJyb3cgPSB7XG4gICAgW3NpZGVdOiBNYXRoLnJvdW5kKHNpZGVWYWx1ZSksXG4gICAgW2FsdFNpZGVdOiAnJyAvLyBtYWtlIHN1cmUgdG8gdW5zZXQgYW55IGV2ZW50dWFsIGFsdFNpZGUgdmFsdWUgZnJvbSB0aGUgRE9NIG5vZGVcbiAgfTtcblxuICBkYXRhLmluc3RhbmNlLmFycm93ID0gYXJyb3dFbGVtZW50O1xuXG4gIHJldHVybiBkYXRhO1xufVxuIiwiaW1wb3J0IHtcbiAgY29tcHV0ZUF1dG9QbGFjZW1lbnQsXG4gIGdldEJvdW5kYXJpZXMsIGdldENsaWVudFJlY3QsXG4gIGdldE9wcG9zaXRlUGxhY2VtZW50LFxuICBnZXRPcHBvc2l0ZVZhcmlhdGlvbixcbiAgZ2V0VGFyZ2V0T2Zmc2V0c1xufSBmcm9tICcuLi91dGlscyc7XG5cbmltcG9ydCB7IERhdGEgfSBmcm9tICcuLi9tb2RlbHMnO1xuXG5leHBvcnQgZnVuY3Rpb24gZmxpcChkYXRhOiBEYXRhKTogRGF0YSB7XG4gIGRhdGEub2Zmc2V0cy50YXJnZXQgPSBnZXRDbGllbnRSZWN0KGRhdGEub2Zmc2V0cy50YXJnZXQpO1xuXG4gIGNvbnN0IGJvdW5kYXJpZXMgPSBnZXRCb3VuZGFyaWVzKFxuICAgIGRhdGEuaW5zdGFuY2UudGFyZ2V0LFxuICAgIGRhdGEuaW5zdGFuY2UuaG9zdCxcbiAgICAwLCAvLyBwYWRkaW5nXG4gICAgJ3ZpZXdwb3J0JyxcbiAgICBmYWxzZSAvLyBwb3NpdGlvbkZpeGVkXG4gICk7XG5cbiAgbGV0IHBsYWNlbWVudCA9IGRhdGEucGxhY2VtZW50LnNwbGl0KCcgJylbMF07XG4gIGxldCB2YXJpYXRpb24gPSBkYXRhLnBsYWNlbWVudC5zcGxpdCgnICcpWzFdIHx8ICcnO1xuXG4gIGNvbnN0IGFkYXB0aXZlUG9zaXRpb24gPSB2YXJpYXRpb25cbiAgICA/IGdldE9wcG9zaXRlUGxhY2VtZW50KHBsYWNlbWVudClcbiAgICA6IGNvbXB1dGVBdXRvUGxhY2VtZW50KCdhdXRvJywgZGF0YS5vZmZzZXRzLmhvc3QsIGRhdGEuaW5zdGFuY2UudGFyZ2V0LCBkYXRhLmluc3RhbmNlLmhvc3QsICd2aWV3cG9ydCcsIDApO1xuXG4gIGNvbnN0IGZsaXBPcmRlciA9IFtwbGFjZW1lbnQsIGFkYXB0aXZlUG9zaXRpb25dO1xuXG4gIC8qIHRzbGludDpkaXNhYmxlLW5leHQtbGluZTogY3ljbG9tYXRpYy1jb21wbGV4aXR5ICovXG4gIGZsaXBPcmRlci5mb3JFYWNoKChzdGVwLCBpbmRleCkgPT4ge1xuICAgIGlmIChwbGFjZW1lbnQgIT09IHN0ZXAgfHwgZmxpcE9yZGVyLmxlbmd0aCA9PT0gaW5kZXggKyAxKSB7XG4gICAgICByZXR1cm4gZGF0YTtcbiAgICB9XG5cbiAgICBwbGFjZW1lbnQgPSBkYXRhLnBsYWNlbWVudC5zcGxpdCgnICcpWzBdO1xuXG4gICAgLy8gdXNpbmcgZmxvb3IgYmVjYXVzZSB0aGUgaG9zdCBvZmZzZXRzIG1heSBjb250YWluIGRlY2ltYWxzIHdlIGFyZSBub3QgZ29pbmcgdG8gY29uc2lkZXIgaGVyZVxuICAgIGNvbnN0IG92ZXJsYXBzUmVmID1cbiAgICAgIChwbGFjZW1lbnQgPT09ICdsZWZ0JyAmJlxuICAgICAgICBNYXRoLmZsb29yKGRhdGEub2Zmc2V0cy50YXJnZXQucmlnaHQpID4gTWF0aC5mbG9vcihkYXRhLm9mZnNldHMuaG9zdC5sZWZ0KSkgfHxcbiAgICAgIChwbGFjZW1lbnQgPT09ICdyaWdodCcgJiZcbiAgICAgICAgTWF0aC5mbG9vcihkYXRhLm9mZnNldHMudGFyZ2V0LmxlZnQpIDwgTWF0aC5mbG9vcihkYXRhLm9mZnNldHMuaG9zdC5yaWdodCkpIHx8XG4gICAgICAocGxhY2VtZW50ID09PSAndG9wJyAmJlxuICAgICAgICBNYXRoLmZsb29yKGRhdGEub2Zmc2V0cy50YXJnZXQuYm90dG9tKSA+IE1hdGguZmxvb3IoZGF0YS5vZmZzZXRzLmhvc3QudG9wKSkgfHxcbiAgICAgIChwbGFjZW1lbnQgPT09ICdib3R0b20nICYmXG4gICAgICAgIE1hdGguZmxvb3IoZGF0YS5vZmZzZXRzLnRhcmdldC50b3ApIDwgTWF0aC5mbG9vcihkYXRhLm9mZnNldHMuaG9zdC5ib3R0b20pKTtcblxuICAgIGNvbnN0IG92ZXJmbG93c0xlZnQgPSBNYXRoLmZsb29yKGRhdGEub2Zmc2V0cy50YXJnZXQubGVmdCkgPCBNYXRoLmZsb29yKGJvdW5kYXJpZXMubGVmdCk7XG4gICAgY29uc3Qgb3ZlcmZsb3dzUmlnaHQgPSBNYXRoLmZsb29yKGRhdGEub2Zmc2V0cy50YXJnZXQucmlnaHQpID4gTWF0aC5mbG9vcihib3VuZGFyaWVzLnJpZ2h0KTtcbiAgICBjb25zdCBvdmVyZmxvd3NUb3AgPSBNYXRoLmZsb29yKGRhdGEub2Zmc2V0cy50YXJnZXQudG9wKSA8IE1hdGguZmxvb3IoYm91bmRhcmllcy50b3ApO1xuICAgIGNvbnN0IG92ZXJmbG93c0JvdHRvbSA9IE1hdGguZmxvb3IoZGF0YS5vZmZzZXRzLnRhcmdldC5ib3R0b20pID4gTWF0aC5mbG9vcihib3VuZGFyaWVzLmJvdHRvbSk7XG5cbiAgICBjb25zdCBvdmVyZmxvd3NCb3VuZGFyaWVzID1cbiAgICAgIChwbGFjZW1lbnQgPT09ICdsZWZ0JyAmJiBvdmVyZmxvd3NMZWZ0KSB8fFxuICAgICAgKHBsYWNlbWVudCA9PT0gJ3JpZ2h0JyAmJiBvdmVyZmxvd3NSaWdodCkgfHxcbiAgICAgIChwbGFjZW1lbnQgPT09ICd0b3AnICYmIG92ZXJmbG93c1RvcCkgfHxcbiAgICAgIChwbGFjZW1lbnQgPT09ICdib3R0b20nICYmIG92ZXJmbG93c0JvdHRvbSk7XG5cbiAgICAvLyBmbGlwIHRoZSB2YXJpYXRpb24gaWYgcmVxdWlyZWRcbiAgICBjb25zdCBpc1ZlcnRpY2FsID0gWyd0b3AnLCAnYm90dG9tJ10uaW5kZXhPZihwbGFjZW1lbnQpICE9PSAtMTtcbiAgICBjb25zdCBmbGlwcGVkVmFyaWF0aW9uID1cbiAgICAgICgoaXNWZXJ0aWNhbCAmJiB2YXJpYXRpb24gPT09ICdsZWZ0JyAmJiBvdmVyZmxvd3NMZWZ0KSB8fFxuICAgICAgICAoaXNWZXJ0aWNhbCAmJiB2YXJpYXRpb24gPT09ICdyaWdodCcgJiYgb3ZlcmZsb3dzUmlnaHQpIHx8XG4gICAgICAgICghaXNWZXJ0aWNhbCAmJiB2YXJpYXRpb24gPT09ICdsZWZ0JyAmJiBvdmVyZmxvd3NUb3ApIHx8XG4gICAgICAgICghaXNWZXJ0aWNhbCAmJiB2YXJpYXRpb24gPT09ICdyaWdodCcgJiYgb3ZlcmZsb3dzQm90dG9tKSk7XG5cbiAgICBpZiAob3ZlcmxhcHNSZWYgfHwgb3ZlcmZsb3dzQm91bmRhcmllcyB8fCBmbGlwcGVkVmFyaWF0aW9uKSB7XG4gICAgICAvLyB0aGlzIGJvb2xlYW4gdG8gZGV0ZWN0IGFueSBmbGlwIGxvb3BcbiAgICAgIGlmIChvdmVybGFwc1JlZiB8fCBvdmVyZmxvd3NCb3VuZGFyaWVzKSB7XG4gICAgICAgIHBsYWNlbWVudCA9IGZsaXBPcmRlcltpbmRleCArIDFdO1xuICAgICAgfVxuXG4gICAgICBpZiAoZmxpcHBlZFZhcmlhdGlvbikge1xuICAgICAgICB2YXJpYXRpb24gPSBnZXRPcHBvc2l0ZVZhcmlhdGlvbih2YXJpYXRpb24pO1xuICAgICAgfVxuXG4gICAgICBkYXRhLnBsYWNlbWVudCA9IHBsYWNlbWVudCArICh2YXJpYXRpb24gPyBgICR7dmFyaWF0aW9ufWAgOiAnJyk7XG5cbiAgICAgIGRhdGEub2Zmc2V0cy50YXJnZXQgPSB7XG4gICAgICAgIC4uLmRhdGEub2Zmc2V0cy50YXJnZXQsXG4gICAgICAgIC4uLmdldFRhcmdldE9mZnNldHMoXG4gICAgICAgICAgZGF0YS5pbnN0YW5jZS50YXJnZXQsXG4gICAgICAgICAgZGF0YS5vZmZzZXRzLmhvc3QsXG4gICAgICAgICAgZGF0YS5wbGFjZW1lbnRcbiAgICAgICAgKVxuICAgICAgfTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBkYXRhO1xufVxuIiwiaW1wb3J0IHtcbiAgY29tcHV0ZUF1dG9QbGFjZW1lbnQsXG4gIGdldFJlZmVyZW5jZU9mZnNldHMsXG4gIGdldFRhcmdldE9mZnNldHNcbn0gZnJvbSAnLi4vdXRpbHMnO1xuXG5pbXBvcnQgeyBEYXRhIH0gZnJvbSAnLi4vbW9kZWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIGluaXREYXRhKHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50LCBob3N0RWxlbWVudDogSFRNTEVsZW1lbnQsIHBvc2l0aW9uOiBzdHJpbmcpOiBEYXRhIHtcblxuICBjb25zdCBob3N0RWxQb3NpdGlvbiA9IGdldFJlZmVyZW5jZU9mZnNldHModGFyZ2V0RWxlbWVudCwgaG9zdEVsZW1lbnQpO1xuICBjb25zdCB0YXJnZXRPZmZzZXQgPSBnZXRUYXJnZXRPZmZzZXRzKHRhcmdldEVsZW1lbnQsIGhvc3RFbFBvc2l0aW9uLCBwb3NpdGlvbik7XG5cbiAgY29uc3QgcGxhY2VtZW50ID0gY29tcHV0ZUF1dG9QbGFjZW1lbnQocG9zaXRpb24sIGhvc3RFbFBvc2l0aW9uLCB0YXJnZXRFbGVtZW50LCBob3N0RWxlbWVudCwgJ3ZpZXdwb3J0JywgMCk7XG4gIGNvbnN0IHBsYWNlbWVudEF1dG8gPSBwb3NpdGlvbi5pbmRleE9mKCdhdXRvJykgIT09IC0xO1xuXG4gIHJldHVybiB7XG4gICAgaW5zdGFuY2U6IHtcbiAgICAgIHRhcmdldDogdGFyZ2V0RWxlbWVudCxcbiAgICAgIGhvc3Q6IGhvc3RFbGVtZW50LFxuICAgICAgYXJyb3c6IG51bGxcbiAgICB9LFxuICAgIG9mZnNldHM6IHtcbiAgICAgIHRhcmdldDogdGFyZ2V0T2Zmc2V0LFxuICAgICAgaG9zdDogaG9zdEVsUG9zaXRpb24sXG4gICAgICBhcnJvdzogbnVsbFxuICAgIH0sXG4gICAgcG9zaXRpb25GaXhlZDogZmFsc2UsXG4gICAgcGxhY2VtZW50LFxuICAgIHBsYWNlbWVudEF1dG9cbiAgfTtcbn1cbiIsImltcG9ydCB7IGdldEJvdW5kYXJpZXMgfSBmcm9tICcuLi91dGlscyc7XG5pbXBvcnQgeyBEYXRhIH0gZnJvbSAnLi4vbW9kZWxzJztcblxuZXhwb3J0IGZ1bmN0aW9uIHByZXZlbnRPdmVyZmxvdyhkYXRhOiBEYXRhKSB7XG5cbiAgLy8gTk9URTogRE9NIGFjY2VzcyBoZXJlXG4gIC8vIHJlc2V0cyB0aGUgdGFyZ2V0T2Zmc2V0cydzIHBvc2l0aW9uIHNvIHRoYXQgdGhlIGRvY3VtZW50IHNpemUgY2FuIGJlIGNhbGN1bGF0ZWQgZXhjbHVkaW5nXG4gIC8vIHRoZSBzaXplIG9mIHRoZSB0YXJnZXRPZmZzZXRzIGVsZW1lbnQgaXRzZWxmXG4gIGNvbnN0IHRyYW5zZm9ybVByb3AgPSAndHJhbnNmb3JtJztcbiAgY29uc3QgdGFyZ2V0U3R5bGVzID0gZGF0YS5pbnN0YW5jZS50YXJnZXQuc3R5bGU7IC8vIGFzc2lnbm1lbnQgdG8gaGVscCBtaW5pZmljYXRpb25cbiAgY29uc3QgeyB0b3AsIGxlZnQsIFt0cmFuc2Zvcm1Qcm9wXTogdHJhbnNmb3JtIH0gPSB0YXJnZXRTdHlsZXM7XG4gIHRhcmdldFN0eWxlcy50b3AgPSAnJztcbiAgdGFyZ2V0U3R5bGVzLmxlZnQgPSAnJztcbiAgdGFyZ2V0U3R5bGVzW3RyYW5zZm9ybVByb3BdID0gJyc7XG5cbiAgY29uc3QgYm91bmRhcmllcyA9IGdldEJvdW5kYXJpZXMoXG4gICAgZGF0YS5pbnN0YW5jZS50YXJnZXQsXG4gICAgZGF0YS5pbnN0YW5jZS5ob3N0LFxuICAgIDAsIC8vIHBhZGRpbmdcbiAgICAnc2Nyb2xsUGFyZW50JyxcbiAgICBmYWxzZSAvLyBwb3NpdGlvbkZpeGVkXG4gICk7XG5cbiAgLy8gTk9URTogRE9NIGFjY2VzcyBoZXJlXG4gIC8vIHJlc3RvcmVzIHRoZSBvcmlnaW5hbCBzdHlsZSBwcm9wZXJ0aWVzIGFmdGVyIHRoZSBvZmZzZXRzIGhhdmUgYmVlbiBjb21wdXRlZFxuICB0YXJnZXRTdHlsZXMudG9wID0gdG9wO1xuICB0YXJnZXRTdHlsZXMubGVmdCA9IGxlZnQ7XG4gIHRhcmdldFN0eWxlc1t0cmFuc2Zvcm1Qcm9wXSA9IHRyYW5zZm9ybTtcblxuICBjb25zdCBvcmRlciA9IFsnbGVmdCcsICdyaWdodCcsICd0b3AnLCAnYm90dG9tJ107XG5cbiAgY29uc3QgY2hlY2sgPSB7XG4gICAgcHJpbWFyeShwbGFjZW1lbnQ6IHN0cmluZykge1xuICAgICAgbGV0IHZhbHVlID0gZGF0YS5vZmZzZXRzLnRhcmdldFtwbGFjZW1lbnRdO1xuICAgICAgaWYgKFxuICAgICAgICBkYXRhLm9mZnNldHMudGFyZ2V0W3BsYWNlbWVudF0gPCBib3VuZGFyaWVzW3BsYWNlbWVudF0gJiZcbiAgICAgICAgIWZhbHNlIC8vIG9wdGlvbnMuZXNjYXBlV2l0aFJlZmVyZW5jZVxuICAgICAgKSB7XG4gICAgICAgIHZhbHVlID0gTWF0aC5tYXgoZGF0YS5vZmZzZXRzLnRhcmdldFtwbGFjZW1lbnRdLCBib3VuZGFyaWVzW3BsYWNlbWVudF0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4geyBbcGxhY2VtZW50XTogdmFsdWUgfTtcbiAgICB9LFxuICAgIHNlY29uZGFyeShwbGFjZW1lbnQ6IHN0cmluZykge1xuICAgICAgY29uc3QgbWFpblNpZGUgPSBwbGFjZW1lbnQgPT09ICdyaWdodCcgPyAnbGVmdCcgOiAndG9wJztcbiAgICAgIGxldCB2YWx1ZSA9IGRhdGEub2Zmc2V0cy50YXJnZXRbbWFpblNpZGVdO1xuICAgICAgaWYgKFxuICAgICAgICBkYXRhLm9mZnNldHMudGFyZ2V0W3BsYWNlbWVudF0gPiBib3VuZGFyaWVzW3BsYWNlbWVudF0gJiZcbiAgICAgICAgIWZhbHNlIC8vIGVzY2FwZVdpdGhSZWZlcmVuY2VcbiAgICAgICkge1xuICAgICAgICB2YWx1ZSA9IE1hdGgubWluKFxuICAgICAgICAgIGRhdGEub2Zmc2V0cy50YXJnZXRbbWFpblNpZGVdLFxuICAgICAgICAgIGJvdW5kYXJpZXNbcGxhY2VtZW50XSAtXG4gICAgICAgICAgKHBsYWNlbWVudCA9PT0gJ3JpZ2h0JyA/IGRhdGEub2Zmc2V0cy50YXJnZXQud2lkdGggOiBkYXRhLm9mZnNldHMudGFyZ2V0LmhlaWdodClcbiAgICAgICAgKTtcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIHsgW21haW5TaWRlXTogdmFsdWUgfTtcbiAgICB9XG4gIH07XG5cbiAgbGV0IHNpZGU6IHN0cmluZztcblxuICBvcmRlci5mb3JFYWNoKHBsYWNlbWVudCA9PiB7XG4gICAgc2lkZSA9IFsnbGVmdCcsICd0b3AnXVxuICAgICAgLmluZGV4T2YocGxhY2VtZW50KSAhPT0gLTFcbiAgICAgID8gJ3ByaW1hcnknXG4gICAgICA6ICdzZWNvbmRhcnknO1xuXG4gICAgZGF0YS5vZmZzZXRzLnRhcmdldCA9IHsgLi4uZGF0YS5vZmZzZXRzLnRhcmdldCwgLi4uY2hlY2tbc2lkZV0ocGxhY2VtZW50KSB9O1xuXG4gIH0pO1xuXG4gIHJldHVybiBkYXRhO1xufVxuIiwiaW1wb3J0IHsgRGF0YSB9IGZyb20gJy4uL21vZGVscyc7XG5cbmV4cG9ydCBmdW5jdGlvbiBzaGlmdChkYXRhOiBEYXRhKTogRGF0YSB7XG4gIGNvbnN0IHBsYWNlbWVudCA9IGRhdGEucGxhY2VtZW50O1xuICBjb25zdCBiYXNlUGxhY2VtZW50ID0gcGxhY2VtZW50LnNwbGl0KCcgJylbMF07XG4gIGNvbnN0IHNoaWZ0dmFyaWF0aW9uID0gcGxhY2VtZW50LnNwbGl0KCcgJylbMV07XG5cbiAgaWYgKHNoaWZ0dmFyaWF0aW9uKSB7XG4gICAgY29uc3QgeyBob3N0LCB0YXJnZXQgfSA9IGRhdGEub2Zmc2V0cztcbiAgICBjb25zdCBpc1ZlcnRpY2FsID0gWydib3R0b20nLCAndG9wJ10uaW5kZXhPZihiYXNlUGxhY2VtZW50KSAhPT0gLTE7XG4gICAgY29uc3Qgc2lkZSA9IGlzVmVydGljYWwgPyAnbGVmdCcgOiAndG9wJztcbiAgICBjb25zdCBtZWFzdXJlbWVudCA9IGlzVmVydGljYWwgPyAnd2lkdGgnIDogJ2hlaWdodCc7XG5cbiAgICBjb25zdCBzaGlmdE9mZnNldHMgPSB7XG4gICAgICBsZWZ0OiB7IFtzaWRlXTogaG9zdFtzaWRlXSB9LFxuICAgICAgcmlnaHQ6IHtcbiAgICAgICAgW3NpZGVdOiBob3N0W3NpZGVdICsgaG9zdFttZWFzdXJlbWVudF0gLSBob3N0W21lYXN1cmVtZW50XVxuICAgICAgfVxuICAgIH07XG5cbiAgICBkYXRhLm9mZnNldHMudGFyZ2V0ID0geyAuLi50YXJnZXQsIC4uLnNoaWZ0T2Zmc2V0c1tzaGlmdHZhcmlhdGlvbl0gfTtcbiAgfVxuXG4gIHJldHVybiBkYXRhO1xufVxuIiwiLyoqXG4gKiBAY29weXJpZ2h0IFZhbG9yIFNvZnR3YXJlXG4gKiBAY29weXJpZ2h0IEZlZGVyaWNvIFppdm9sbyBhbmQgY29udHJpYnV0b3JzXG4gKi9cbmltcG9ydCB7IFJlbmRlcmVyMiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQgeyBnZXRSZWZlcmVuY2VPZmZzZXRzLCBzZXRBbGxTdHlsZXMgfSBmcm9tICcuL3V0aWxzJztcblxuaW1wb3J0IHsgYXJyb3csIGZsaXAsIHByZXZlbnRPdmVyZmxvdywgc2hpZnQsIGluaXREYXRhIH0gZnJvbSAnLi9tb2RpZmllcnMnO1xuaW1wb3J0IHsgRGF0YSwgT2Zmc2V0cyB9IGZyb20gJy4vbW9kZWxzJztcblxuXG5leHBvcnQgY2xhc3MgUG9zaXRpb25pbmcge1xuICBwb3NpdGlvbihob3N0RWxlbWVudDogSFRNTEVsZW1lbnQsIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50LCByb3VuZCA9IHRydWUpOiBPZmZzZXRzIHtcbiAgICByZXR1cm4gdGhpcy5vZmZzZXQoaG9zdEVsZW1lbnQsIHRhcmdldEVsZW1lbnQsIGZhbHNlKTtcbiAgfVxuXG4gIG9mZnNldChob3N0RWxlbWVudDogSFRNTEVsZW1lbnQsIHRhcmdldEVsZW1lbnQ6IEhUTUxFbGVtZW50LCByb3VuZCA9IHRydWUpOiBPZmZzZXRzIHtcbiAgICByZXR1cm4gZ2V0UmVmZXJlbmNlT2Zmc2V0cyh0YXJnZXRFbGVtZW50LCBob3N0RWxlbWVudCk7XG4gIH1cblxuICBwb3NpdGlvbkVsZW1lbnRzKFxuICAgIGhvc3RFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgICBwb3NpdGlvbjogc3RyaW5nLFxuICAgIGFwcGVuZFRvQm9keT86IGJvb2xlYW5cbiAgKTogRGF0YSB7XG4gICAgY29uc3QgY2hhaW5PZk1vZGlmaWVycyA9IFtmbGlwLCBzaGlmdCwgcHJldmVudE92ZXJmbG93LCBhcnJvd107XG5cbiAgICByZXR1cm4gY2hhaW5PZk1vZGlmaWVycy5yZWR1Y2UoXG4gICAgICAobW9kaWZpZWREYXRhLCBtb2RpZmllcikgPT4gbW9kaWZpZXIobW9kaWZpZWREYXRhKSxcbiAgICAgIGluaXREYXRhKHRhcmdldEVsZW1lbnQsIGhvc3RFbGVtZW50LCBwb3NpdGlvbilcbiAgICApO1xuICB9XG59XG5cbmNvbnN0IHBvc2l0aW9uU2VydmljZSA9IG5ldyBQb3NpdGlvbmluZygpO1xuXG5leHBvcnQgZnVuY3Rpb24gcG9zaXRpb25FbGVtZW50cyhcbiAgaG9zdEVsZW1lbnQ6IEhUTUxFbGVtZW50LFxuICB0YXJnZXRFbGVtZW50OiBIVE1MRWxlbWVudCxcbiAgcGxhY2VtZW50OiBzdHJpbmcsXG4gIGFwcGVuZFRvQm9keT86IGJvb2xlYW4sXG4gIHJlbmRlcmVyPzogUmVuZGVyZXIyXG4pOiB2b2lkIHtcblxuICBjb25zdCBkYXRhID0gcG9zaXRpb25TZXJ2aWNlLnBvc2l0aW9uRWxlbWVudHMoXG4gICAgaG9zdEVsZW1lbnQsXG4gICAgdGFyZ2V0RWxlbWVudCxcbiAgICBwbGFjZW1lbnQsXG4gICAgYXBwZW5kVG9Cb2R5XG4gICk7XG5cbiAgc2V0QWxsU3R5bGVzKGRhdGEsIHJlbmRlcmVyKTtcbn1cbiIsImltcG9ydCB7IEluamVjdGFibGUsIEVsZW1lbnRSZWYsIFJlbmRlcmVyRmFjdG9yeTIgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgcG9zaXRpb25FbGVtZW50cyB9IGZyb20gJy4vbmctcG9zaXRpb25pbmcnO1xuaW1wb3J0IHsgZnJvbUV2ZW50LCBtZXJnZSwgb2YsIGFuaW1hdGlvbkZyYW1lU2NoZWR1bGVyLCBTdWJqZWN0IH0gZnJvbSAncnhqcyc7XG5cblxuZXhwb3J0IGludGVyZmFjZSBQb3NpdGlvbmluZ09wdGlvbnMge1xuICAvKiogVGhlIERPTSBlbGVtZW50LCBFbGVtZW50UmVmLCBvciBhIHNlbGVjdG9yIHN0cmluZyBvZiBhbiBlbGVtZW50IHdoaWNoIHdpbGwgYmUgbW92ZWQgKi9cbiAgZWxlbWVudD86IEhUTUxFbGVtZW50IHwgRWxlbWVudFJlZiB8IHN0cmluZztcblxuICAvKiogVGhlIERPTSBlbGVtZW50LCBFbGVtZW50UmVmLCBvciBhIHNlbGVjdG9yIHN0cmluZyBvZiBhbiBlbGVtZW50IHdoaWNoIHRoZSBlbGVtZW50IHdpbGwgYmUgYXR0YWNoZWQgdG8gICovXG4gIHRhcmdldD86IEhUTUxFbGVtZW50IHwgRWxlbWVudFJlZiB8IHN0cmluZztcblxuICAvKipcbiAgICogQSBzdHJpbmcgb2YgdGhlIGZvcm0gJ3ZlcnQtYXR0YWNobWVudCBob3Jpei1hdHRhY2htZW50JyBvciAncGxhY2VtZW50J1xuICAgKiAtIHBsYWNlbWVudCBjYW4gYmUgXCJ0b3BcIiwgXCJib3R0b21cIiwgXCJsZWZ0XCIsIFwicmlnaHRcIlxuICAgKiBub3QgeWV0IHN1cHBvcnRlZDpcbiAgICogLSB2ZXJ0LWF0dGFjaG1lbnQgY2FuIGJlIGFueSBvZiAndG9wJywgJ21pZGRsZScsICdib3R0b20nXG4gICAqIC0gaG9yaXotYXR0YWNobWVudCBjYW4gYmUgYW55IG9mICdsZWZ0JywgJ2NlbnRlcicsICdyaWdodCdcbiAgICovXG4gIGF0dGFjaG1lbnQ/OiBzdHJpbmc7XG5cbiAgLyoqIEEgc3RyaW5nIHNpbWlsYXIgdG8gYGF0dGFjaG1lbnRgLiBUaGUgb25lIGRpZmZlcmVuY2UgaXMgdGhhdCwgaWYgaXQncyBub3QgcHJvdmlkZWQsXG4gICAqIGB0YXJnZXRBdHRhY2htZW50YCB3aWxsIGFzc3VtZSB0aGUgbWlycm9yIGltYWdlIG9mIGBhdHRhY2htZW50YC5cbiAgICovXG4gIHRhcmdldEF0dGFjaG1lbnQ/OiBzdHJpbmc7XG5cbiAgLyoqIEEgc3RyaW5nIG9mIHRoZSBmb3JtICd2ZXJ0LW9mZnNldCBob3Jpei1vZmZzZXQnXG4gICAqIC0gdmVydC1vZmZzZXQgYW5kIGhvcml6LW9mZnNldCBjYW4gYmUgb2YgdGhlIGZvcm0gXCIyMHB4XCIgb3IgXCI1NSVcIlxuICAgKi9cbiAgb2Zmc2V0Pzogc3RyaW5nO1xuXG4gIC8qKiBBIHN0cmluZyBzaW1pbGFyIHRvIGBvZmZzZXRgLCBidXQgcmVmZXJyaW5nIHRvIHRoZSBvZmZzZXQgb2YgdGhlIHRhcmdldCAqL1xuICB0YXJnZXRPZmZzZXQ/OiBzdHJpbmc7XG5cbiAgLyoqIElmIHRydWUgY29tcG9uZW50IHdpbGwgYmUgYXR0YWNoZWQgdG8gYm9keSAqL1xuICBhcHBlbmRUb0JvZHk/OiBib29sZWFuO1xufVxuXG5cbkBJbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBQb3NpdGlvbmluZ1NlcnZpY2Uge1xuICBwcml2YXRlIHVwZGF0ZSQkID0gbmV3IFN1YmplY3Q8bnVsbD4oKTtcblxuICBwcml2YXRlIGV2ZW50cyQ6IGFueSA9IG1lcmdlKFxuICAgIGZyb21FdmVudCh3aW5kb3csICdzY3JvbGwnKSxcbiAgICBmcm9tRXZlbnQod2luZG93LCAncmVzaXplJyksXG4gICAgb2YoMCwgYW5pbWF0aW9uRnJhbWVTY2hlZHVsZXIpLFxuICAgIHRoaXMudXBkYXRlJCRcbiAgKTtcblxuICBwcml2YXRlIHBvc2l0aW9uRWxlbWVudHMgPSBuZXcgTWFwKCk7XG5cbiAgY29uc3RydWN0b3IocmVuZGVyZXJGYWN0b3J5OiBSZW5kZXJlckZhY3RvcnkyKSB7XG4gICAgdGhpcy5ldmVudHMkXG4gICAgICAuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgdGhpcy5wb3NpdGlvbkVsZW1lbnRzXG4gICAgICAgICAgLmZvckVhY2goKHBvc2l0aW9uRWxlbWVudDogUG9zaXRpb25pbmdPcHRpb25zKSA9PiB7XG4gICAgICAgICAgICBwb3NpdGlvbkVsZW1lbnRzKFxuICAgICAgICAgICAgICBfZ2V0SHRtbEVsZW1lbnQocG9zaXRpb25FbGVtZW50LnRhcmdldCksXG4gICAgICAgICAgICAgIF9nZXRIdG1sRWxlbWVudChwb3NpdGlvbkVsZW1lbnQuZWxlbWVudCksXG4gICAgICAgICAgICAgIHBvc2l0aW9uRWxlbWVudC5hdHRhY2htZW50LFxuICAgICAgICAgICAgICBwb3NpdGlvbkVsZW1lbnQuYXBwZW5kVG9Cb2R5LFxuICAgICAgICAgICAgICByZW5kZXJlckZhY3RvcnkuY3JlYXRlUmVuZGVyZXIobnVsbCwgbnVsbClcbiAgICAgICAgICAgICk7XG4gICAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHBvc2l0aW9uKG9wdGlvbnM6IFBvc2l0aW9uaW5nT3B0aW9ucyk6IHZvaWQge1xuICAgIHRoaXMuYWRkUG9zaXRpb25FbGVtZW50KG9wdGlvbnMpO1xuICAgIHRoaXMudXBkYXRlJCQubmV4dCgpO1xuICB9XG5cbiAgYWRkUG9zaXRpb25FbGVtZW50KG9wdGlvbnM6IFBvc2l0aW9uaW5nT3B0aW9ucyk6IHZvaWQge1xuICAgIHRoaXMucG9zaXRpb25FbGVtZW50cy5zZXQoX2dldEh0bWxFbGVtZW50KG9wdGlvbnMuZWxlbWVudCksIG9wdGlvbnMpO1xuICB9XG5cbiAgZGVsZXRlUG9zaXRpb25FbGVtZW50KGVsUmVmOiBFbGVtZW50UmVmKTogdm9pZCB7XG4gICAgdGhpcy5wb3NpdGlvbkVsZW1lbnRzLmRlbGV0ZShfZ2V0SHRtbEVsZW1lbnQoZWxSZWYpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBfZ2V0SHRtbEVsZW1lbnQoZWxlbWVudDogSFRNTEVsZW1lbnQgfCBFbGVtZW50UmVmIHwgc3RyaW5nKTogSFRNTEVsZW1lbnQge1xuICAvLyBpdCBtZWFucyB0aGF0IHdlIGdvdCBhIHNlbGVjdG9yXG4gIGlmICh0eXBlb2YgZWxlbWVudCA9PT0gJ3N0cmluZycpIHtcbiAgICByZXR1cm4gZG9jdW1lbnQucXVlcnlTZWxlY3RvcihlbGVtZW50KTtcbiAgfVxuXG4gIGlmIChlbGVtZW50IGluc3RhbmNlb2YgRWxlbWVudFJlZikge1xuICAgIHJldHVybiBlbGVtZW50Lm5hdGl2ZUVsZW1lbnQ7XG4gIH1cblxuICByZXR1cm4gZWxlbWVudDtcbn1cbiJdLCJuYW1lcyI6WyJydW5Jc0lFIiwic2V0QWxsU3R5bGVzIl0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7OztBQUdBLGtDQUF5QyxPQUFvQixFQUFFLFFBQWlCO0lBQzlFLElBQUksT0FBTyxDQUFDLFFBQVEsS0FBSyxDQUFDLEVBQUU7UUFDMUIsT0FBTyxF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