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