@angular/cdk 13.0.0-next.7 → 13.0.0-rc.2

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 (855) hide show
  1. package/a11y/a11y-module.d.ts +9 -7
  2. package/a11y/a11y_public_index.d.ts +4 -0
  3. package/a11y/aria-describer/aria-describer.d.ts +3 -7
  4. package/a11y/focus-monitor/focus-monitor.d.ts +5 -0
  5. package/a11y/focus-trap/configurable-focus-trap-factory.d.ts +3 -7
  6. package/a11y/focus-trap/focus-trap-manager.d.ts +3 -7
  7. package/a11y/focus-trap/focus-trap.d.ts +5 -0
  8. package/a11y/high-contrast-mode/high-contrast-mode-detector.d.ts +3 -0
  9. package/a11y/index.d.ts +5 -2
  10. package/a11y/input-modality/input-modality-detector.d.ts +3 -7
  11. package/a11y/interactivity-checker/interactivity-checker.d.ts +3 -0
  12. package/a11y/live-announcer/live-announcer.d.ts +6 -1
  13. package/a11y/package.json +6 -6
  14. package/accordion/accordion-item.d.ts +3 -0
  15. package/accordion/accordion-module.d.ts +6 -7
  16. package/accordion/accordion.d.ts +3 -0
  17. package/accordion/accordion_public_index.d.ts +4 -0
  18. package/accordion/index.d.ts +5 -2
  19. package/accordion/package.json +6 -6
  20. package/bidi/bidi-module.d.ts +5 -7
  21. package/bidi/bidi_public_index.d.ts +4 -0
  22. package/bidi/dir.d.ts +3 -0
  23. package/bidi/directionality.d.ts +3 -0
  24. package/bidi/index.d.ts +5 -2
  25. package/bidi/package.json +6 -6
  26. package/clipboard/clipboard-module.d.ts +5 -7
  27. package/clipboard/clipboard.d.ts +3 -7
  28. package/clipboard/clipboard_public_index.d.ts +4 -0
  29. package/clipboard/copy-to-clipboard.d.ts +3 -0
  30. package/clipboard/index.d.ts +5 -1
  31. package/clipboard/package.json +6 -6
  32. package/coercion/package.json +5 -5
  33. package/collections/collections_public_index.d.ts +4 -0
  34. package/collections/index.d.ts +5 -1
  35. package/collections/package.json +6 -6
  36. package/collections/unique-selection-dispatcher.d.ts +3 -0
  37. package/drag-drop/client-rect.d.ts +8 -1
  38. package/drag-drop/directives/drag-handle.d.ts +3 -0
  39. package/drag-drop/directives/drag-placeholder.d.ts +3 -0
  40. package/drag-drop/directives/drag-preview.d.ts +3 -0
  41. package/drag-drop/directives/drag.d.ts +3 -0
  42. package/drag-drop/directives/drop-list-group.d.ts +3 -0
  43. package/drag-drop/directives/drop-list.d.ts +3 -0
  44. package/drag-drop/drag-drop-module.d.ts +11 -7
  45. package/drag-drop/drag-drop-registry.d.ts +3 -0
  46. package/drag-drop/drag-drop.d.ts +3 -0
  47. package/drag-drop/drag-drop_public_index.d.ts +4 -0
  48. package/drag-drop/index.d.ts +5 -2
  49. package/drag-drop/package.json +6 -6
  50. package/esm2020/a11y/a11y-module.mjs +33 -0
  51. package/esm2020/a11y/a11y_public_index.mjs +5 -0
  52. package/esm2020/a11y/aria-describer/aria-describer.mjs +208 -0
  53. package/{esm2015/a11y/aria-describer/aria-reference.js → esm2020/a11y/aria-describer/aria-reference.mjs} +1 -1
  54. package/esm2020/a11y/fake-event-detection.mjs +29 -0
  55. package/esm2020/a11y/focus-monitor/focus-monitor.mjs +400 -0
  56. package/{esm2015/a11y/focus-trap/configurable-focus-trap-config.js → esm2020/a11y/focus-trap/configurable-focus-trap-config.mjs} +0 -0
  57. package/esm2020/a11y/focus-trap/configurable-focus-trap-factory.mjs +53 -0
  58. package/esm2020/a11y/focus-trap/configurable-focus-trap.mjs +51 -0
  59. package/esm2020/a11y/focus-trap/event-listener-inert-strategy.mjs +61 -0
  60. package/esm2020/a11y/focus-trap/focus-trap-inert-strategy.mjs +11 -0
  61. package/esm2020/a11y/focus-trap/focus-trap-manager.mjs +53 -0
  62. package/esm2020/a11y/focus-trap/focus-trap.mjs +399 -0
  63. package/esm2020/a11y/high-contrast-mode/high-contrast-mode-detector.mjs +95 -0
  64. package/esm2020/a11y/index.mjs +9 -0
  65. package/esm2020/a11y/input-modality/input-modality-detector.mjs +176 -0
  66. package/esm2020/a11y/interactivity-checker/interactivity-checker.mjs +238 -0
  67. package/{esm2015/a11y/key-manager/activedescendant-key-manager.js → esm2020/a11y/key-manager/activedescendant-key-manager.mjs} +1 -1
  68. package/{esm2015/a11y/key-manager/focus-key-manager.js → esm2020/a11y/key-manager/focus-key-manager.mjs} +0 -0
  69. package/esm2020/a11y/key-manager/list-key-manager.mjs +321 -0
  70. package/esm2020/a11y/live-announcer/live-announcer-tokens.mjs +19 -0
  71. package/esm2020/a11y/live-announcer/live-announcer.mjs +170 -0
  72. package/{esm2015/a11y/public-api.js → esm2020/a11y/public-api.mjs} +0 -0
  73. package/esm2020/accordion/accordion-item.mjs +167 -0
  74. package/esm2020/accordion/accordion-module.mjs +24 -0
  75. package/esm2020/accordion/accordion.mjs +70 -0
  76. package/esm2020/accordion/accordion_public_index.mjs +5 -0
  77. package/esm2020/accordion/index.mjs +9 -0
  78. package/{esm2015/accordion/public-api.js → esm2020/accordion/public-api.mjs} +0 -0
  79. package/esm2020/bidi/bidi-module.mjs +23 -0
  80. package/esm2020/bidi/bidi_public_index.mjs +5 -0
  81. package/{esm2015/bidi/dir-document-token.js → esm2020/bidi/dir-document-token.mjs} +1 -1
  82. package/esm2020/bidi/dir.mjs +67 -0
  83. package/esm2020/bidi/directionality.mjs +47 -0
  84. package/esm2020/bidi/index.mjs +9 -0
  85. package/{esm2015/bidi/public-api.js → esm2020/bidi/public-api.mjs} +1 -1
  86. package/esm2020/clipboard/clipboard-module.mjs +23 -0
  87. package/esm2020/clipboard/clipboard.mjs +53 -0
  88. package/esm2020/clipboard/clipboard_public_index.mjs +5 -0
  89. package/esm2020/clipboard/copy-to-clipboard.mjs +99 -0
  90. package/esm2020/clipboard/index.mjs +9 -0
  91. package/esm2020/clipboard/pending-copy.mjs +67 -0
  92. package/{esm2015/clipboard/public-api.js → esm2020/clipboard/public-api.mjs} +0 -0
  93. package/{esm2015/coercion/array.js → esm2020/coercion/array.mjs} +0 -0
  94. package/{esm2015/coercion/boolean-property.js → esm2020/coercion/boolean-property.mjs} +0 -0
  95. package/{esm2015/coercion/css-pixel-value.js → esm2020/coercion/css-pixel-value.mjs} +0 -0
  96. package/{esm2015/coercion/element.js → esm2020/coercion/element.mjs} +0 -0
  97. package/{esm2015/coercion/index.js → esm2020/coercion/index.mjs} +0 -0
  98. package/{esm2015/coercion/number-property.js → esm2020/coercion/number-property.mjs} +0 -0
  99. package/{esm2015/coercion/public-api.js → esm2020/coercion/public-api.mjs} +0 -0
  100. package/{esm2015/coercion/string-array.js → esm2020/coercion/string-array.mjs} +0 -0
  101. package/{esm2015/collections/array-data-source.js → esm2020/collections/array-data-source.mjs} +1 -1
  102. package/esm2020/collections/collection-viewer.mjs +9 -0
  103. package/esm2020/collections/collections_public_index.mjs +5 -0
  104. package/{esm2015/collections/data-source.js → esm2020/collections/data-source.mjs} +0 -0
  105. package/esm2020/collections/dispose-view-repeater-strategy.mjs +47 -0
  106. package/esm2020/collections/index.mjs +9 -0
  107. package/{esm2015/collections/public-api.js → esm2020/collections/public-api.mjs} +0 -0
  108. package/esm2020/collections/recycle-view-repeater-strategy.mjs +128 -0
  109. package/{esm2015/collections/selection-model.js → esm2020/collections/selection-model.mjs} +2 -2
  110. package/esm2020/collections/tree-adapter.mjs +9 -0
  111. package/esm2020/collections/unique-selection-dispatcher.mjs +55 -0
  112. package/esm2020/collections/view-repeater.mjs +14 -0
  113. package/esm2020/drag-drop/client-rect.mjs +64 -0
  114. package/esm2020/drag-drop/clone-node.mjs +65 -0
  115. package/esm2020/drag-drop/directives/assertions.mjs +18 -0
  116. package/{esm2015/drag-drop/directives/config.js → esm2020/drag-drop/directives/config.mjs} +1 -1
  117. package/esm2020/drag-drop/directives/drag-handle.mjs +66 -0
  118. package/esm2020/drag-drop/directives/drag-placeholder.mjs +36 -0
  119. package/esm2020/drag-drop/directives/drag-preview.mjs +47 -0
  120. package/esm2020/drag-drop/directives/drag.mjs +483 -0
  121. package/esm2020/drag-drop/directives/drop-list-group.mjs +53 -0
  122. package/esm2020/drag-drop/directives/drop-list.mjs +344 -0
  123. package/esm2020/drag-drop/drag-drop-module.mjs +57 -0
  124. package/esm2020/drag-drop/drag-drop-registry.mjs +231 -0
  125. package/esm2020/drag-drop/drag-drop.mjs +57 -0
  126. package/esm2020/drag-drop/drag-drop_public_index.mjs +5 -0
  127. package/esm2020/drag-drop/drag-events.mjs +9 -0
  128. package/{esm2015/drag-drop/drag-parent.js → esm2020/drag-drop/drag-parent.mjs} +0 -0
  129. package/esm2020/drag-drop/drag-ref.mjs +1108 -0
  130. package/esm2020/drag-drop/drag-styling.mjs +69 -0
  131. package/esm2020/drag-drop/drag-utils.mjs +60 -0
  132. package/esm2020/drag-drop/drop-list-ref.mjs +830 -0
  133. package/esm2020/drag-drop/index.mjs +9 -0
  134. package/{esm2015/drag-drop/parent-position-tracker.js → esm2020/drag-drop/parent-position-tracker.mjs} +2 -2
  135. package/{esm2015/drag-drop/public-api.js → esm2020/drag-drop/public-api.mjs} +0 -0
  136. package/esm2020/drag-drop/transition-duration.mjs +36 -0
  137. package/{esm2015/index.js → esm2020/index.mjs} +0 -0
  138. package/esm2020/keycodes/index.mjs +9 -0
  139. package/{esm2015/keycodes/keycodes.js → esm2020/keycodes/keycodes.mjs} +1 -1
  140. package/esm2020/keycodes/keycodes_public_index.mjs +5 -0
  141. package/{esm2015/keycodes/modifiers.js → esm2020/keycodes/modifiers.mjs} +0 -0
  142. package/{esm2015/keycodes/public-api.js → esm2020/keycodes/public-api.mjs} +0 -0
  143. package/esm2020/layout/breakpoints-observer.mjs +105 -0
  144. package/{esm2015/layout/breakpoints.js → esm2020/layout/breakpoints.mjs} +1 -1
  145. package/esm2020/layout/index.mjs +9 -0
  146. package/esm2020/layout/layout-module.mjs +19 -0
  147. package/esm2020/layout/layout_public_index.mjs +5 -0
  148. package/esm2020/layout/media-matcher.mjs +85 -0
  149. package/{esm2015/layout/public-api.js → esm2020/layout/public-api.mjs} +0 -0
  150. package/esm2020/observers/index.mjs +9 -0
  151. package/esm2020/observers/observe-content.mjs +187 -0
  152. package/esm2020/observers/observers_public_index.mjs +5 -0
  153. package/{esm2015/observers/public-api.js → esm2020/observers/public-api.mjs} +0 -0
  154. package/esm2020/overlay/dispatchers/base-overlay-dispatcher.mjs +52 -0
  155. package/{esm2015/overlay/dispatchers/index.js → esm2020/overlay/dispatchers/index.mjs} +0 -0
  156. package/esm2020/overlay/dispatchers/overlay-keyboard-dispatcher.mjs +63 -0
  157. package/esm2020/overlay/dispatchers/overlay-outside-click-dispatcher.mjs +116 -0
  158. package/esm2020/overlay/fullscreen-overlay-container.mjs +94 -0
  159. package/esm2020/overlay/index.mjs +9 -0
  160. package/esm2020/overlay/overlay-config.mjs +45 -0
  161. package/esm2020/overlay/overlay-container.mjs +81 -0
  162. package/esm2020/overlay/overlay-directives.mjs +427 -0
  163. package/esm2020/overlay/overlay-module.mjs +29 -0
  164. package/esm2020/overlay/overlay-ref.mjs +402 -0
  165. package/{esm2015/overlay/overlay-reference.js → esm2020/overlay/overlay-reference.mjs} +0 -0
  166. package/esm2020/overlay/overlay.mjs +119 -0
  167. package/esm2020/overlay/overlay_public_index.mjs +5 -0
  168. package/esm2020/overlay/position/connected-position.mjs +97 -0
  169. package/esm2020/overlay/position/flexible-connected-position-strategy.mjs +959 -0
  170. package/esm2020/overlay/position/global-position-strategy.mjs +203 -0
  171. package/esm2020/overlay/position/overlay-position-builder.mjs +50 -0
  172. package/{esm2015/overlay/position/position-strategy.js → esm2020/overlay/position/position-strategy.mjs} +0 -0
  173. package/esm2020/overlay/position/scroll-clip.mjs +40 -0
  174. package/{esm2015/overlay/public-api.js → esm2020/overlay/public-api.mjs} +0 -0
  175. package/{esm2015/overlay/scroll/block-scroll-strategy.js → esm2020/overlay/scroll/block-scroll-strategy.mjs} +1 -1
  176. package/esm2020/overlay/scroll/close-scroll-strategy.mjs +61 -0
  177. package/{esm2015/overlay/scroll/index.js → esm2020/overlay/scroll/index.mjs} +2 -2
  178. package/{esm2015/overlay/scroll/noop-scroll-strategy.js → esm2020/overlay/scroll/noop-scroll-strategy.mjs} +1 -1
  179. package/{esm2015/overlay/scroll/reposition-scroll-strategy.js → esm2020/overlay/scroll/reposition-scroll-strategy.mjs} +1 -1
  180. package/esm2020/overlay/scroll/scroll-strategy-options.mjs +55 -0
  181. package/{esm2015/overlay/scroll/scroll-strategy.js → esm2020/overlay/scroll/scroll-strategy.mjs} +0 -0
  182. package/{esm2015/platform/features/input-types.js → esm2020/platform/features/input-types.mjs} +1 -1
  183. package/esm2020/platform/features/passive-listeners.mjs +36 -0
  184. package/esm2020/platform/features/scrolling.mjs +85 -0
  185. package/{esm2015/platform/features/shadow-dom.js → esm2020/platform/features/shadow-dom.mjs} +4 -3
  186. package/esm2020/platform/features/test-environment.mjs +27 -0
  187. package/esm2020/platform/index.mjs +9 -0
  188. package/esm2020/platform/platform-module.mjs +19 -0
  189. package/esm2020/platform/platform.mjs +85 -0
  190. package/esm2020/platform/platform_public_index.mjs +5 -0
  191. package/{esm2015/platform/public-api.js → esm2020/platform/public-api.mjs} +0 -0
  192. package/esm2020/portal/dom-portal-outlet.mjs +134 -0
  193. package/esm2020/portal/index.mjs +9 -0
  194. package/esm2020/portal/portal-directives.mjs +244 -0
  195. package/{esm2015/portal/portal-errors.js → esm2020/portal/portal-errors.mjs} +1 -1
  196. package/esm2020/portal/portal-injector.mjs +28 -0
  197. package/esm2020/portal/portal.mjs +179 -0
  198. package/esm2020/portal/portal_public_index.mjs +5 -0
  199. package/{esm2015/portal/public-api.js → esm2020/portal/public-api.mjs} +0 -0
  200. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  201. package/esm2020/scrolling/fixed-size-virtual-scroll.mjs +217 -0
  202. package/esm2020/scrolling/index.mjs +9 -0
  203. package/{esm2015/scrolling/public-api.js → esm2020/scrolling/public-api.mjs} +0 -0
  204. package/esm2020/scrolling/scroll-dispatcher.mjs +163 -0
  205. package/esm2020/scrolling/scrollable.mjs +176 -0
  206. package/esm2020/scrolling/scrolling-module.mjs +52 -0
  207. package/esm2020/scrolling/scrolling_public_index.mjs +5 -0
  208. package/esm2020/scrolling/viewport-ruler.mjs +146 -0
  209. package/esm2020/scrolling/virtual-for-of.mjs +296 -0
  210. package/{esm2015/scrolling/virtual-scroll-repeater.js → esm2020/scrolling/virtual-scroll-repeater.mjs} +0 -0
  211. package/esm2020/scrolling/virtual-scroll-strategy.mjs +11 -0
  212. package/esm2020/scrolling/virtual-scroll-viewport.mjs +378 -0
  213. package/esm2020/stepper/index.mjs +9 -0
  214. package/{esm2015/stepper/public-api.js → esm2020/stepper/public-api.mjs} +0 -0
  215. package/esm2020/stepper/step-header.mjs +30 -0
  216. package/esm2020/stepper/step-label.mjs +23 -0
  217. package/esm2020/stepper/stepper-button.mjs +76 -0
  218. package/esm2020/stepper/stepper-module.mjs +40 -0
  219. package/esm2020/stepper/stepper.mjs +471 -0
  220. package/esm2020/stepper/stepper_public_index.mjs +5 -0
  221. package/esm2020/table/can-stick.mjs +44 -0
  222. package/esm2020/table/cell.mjs +222 -0
  223. package/esm2020/table/coalesced-style-scheduler.mjs +91 -0
  224. package/esm2020/table/index.mjs +9 -0
  225. package/{esm2015/table/public-api.js → esm2020/table/public-api.mjs} +0 -0
  226. package/esm2020/table/row.mjs +254 -0
  227. package/esm2020/table/sticky-position-listener.mjs +11 -0
  228. package/esm2020/table/sticky-styler.mjs +345 -0
  229. package/{esm2015/table/table-errors.js → esm2020/table/table-errors.mjs} +1 -1
  230. package/esm2020/table/table-module.mjs +94 -0
  231. package/esm2020/table/table.mjs +1023 -0
  232. package/esm2020/table/table_public_index.mjs +5 -0
  233. package/esm2020/table/text-column.mjs +153 -0
  234. package/{esm2015/table/tokens.js → esm2020/table/tokens.mjs} +1 -1
  235. package/esm2020/testing/change-detection.mjs +102 -0
  236. package/esm2020/testing/component-harness.mjs +322 -0
  237. package/{esm2015/testing/element-dimensions.js → esm2020/testing/element-dimensions.mjs} +1 -1
  238. package/esm2020/testing/harness-environment.mjs +202 -0
  239. package/{esm2015/testing/index.js → esm2020/testing/index.mjs} +0 -0
  240. package/{esm2015/testing/protractor/index.js → esm2020/testing/protractor/index.mjs} +0 -0
  241. package/esm2020/testing/protractor/protractor-element.mjs +234 -0
  242. package/esm2020/testing/protractor/protractor-harness-environment.mjs +72 -0
  243. package/{esm2015/testing/protractor/public-api.js → esm2020/testing/protractor/public-api.mjs} +0 -0
  244. package/{esm2015/testing/public-api.js → esm2020/testing/public-api.mjs} +0 -0
  245. package/{esm2015/testing/selenium-webdriver/index.js → esm2020/testing/selenium-webdriver/index.mjs} +0 -0
  246. package/{esm2015/testing/selenium-webdriver/public-api.js → esm2020/testing/selenium-webdriver/public-api.mjs} +0 -0
  247. package/esm2020/testing/selenium-webdriver/selenium-web-driver-element.mjs +199 -0
  248. package/esm2020/testing/selenium-webdriver/selenium-web-driver-harness-environment.mjs +87 -0
  249. package/{esm2015/testing/selenium-webdriver/selenium-webdriver-keys.js → esm2020/testing/selenium-webdriver/selenium-webdriver-keys.mjs} +2 -2
  250. package/esm2020/testing/test-element.mjs +48 -0
  251. package/esm2020/testing/testbed/fake-events/dispatch-events.mjs +53 -0
  252. package/esm2020/testing/testbed/fake-events/element-focus.mjs +39 -0
  253. package/esm2020/testing/testbed/fake-events/event-objects.mjs +113 -0
  254. package/{esm2015/testing/testbed/fake-events/index.js → esm2020/testing/testbed/fake-events/index.mjs} +0 -0
  255. package/esm2020/testing/testbed/fake-events/type-in-element.mjs +88 -0
  256. package/{esm2015/testing/testbed/index.js → esm2020/testing/testbed/index.mjs} +0 -0
  257. package/{esm2015/testing/testbed/public-api.js → esm2020/testing/testbed/public-api.mjs} +0 -0
  258. package/esm2020/testing/testbed/task-state-zone-interceptor.mjs +82 -0
  259. package/esm2020/testing/testbed/testbed-harness-environment.mjs +162 -0
  260. package/esm2020/testing/testbed/unit-test-element.mjs +224 -0
  261. package/esm2020/testing/text-filtering.mjs +21 -0
  262. package/esm2020/text-field/autofill.mjs +113 -0
  263. package/esm2020/text-field/autosize.mjs +310 -0
  264. package/esm2020/text-field/index.mjs +9 -0
  265. package/{esm2015/text-field/public-api.js → esm2020/text-field/public-api.mjs} +0 -0
  266. package/esm2020/text-field/text-field-module.mjs +26 -0
  267. package/esm2020/text-field/text-field_public_index.mjs +5 -0
  268. package/{esm2015/tree/control/base-tree-control.js → esm2020/tree/control/base-tree-control.mjs} +4 -4
  269. package/{esm2015/tree/control/flat-tree-control.js → esm2020/tree/control/flat-tree-control.mjs} +1 -1
  270. package/esm2020/tree/control/nested-tree-control.mjs +58 -0
  271. package/{esm2015/tree/control/tree-control.js → esm2020/tree/control/tree-control.mjs} +0 -0
  272. package/esm2020/tree/index.mjs +9 -0
  273. package/esm2020/tree/nested-node.mjs +117 -0
  274. package/esm2020/tree/node.mjs +35 -0
  275. package/esm2020/tree/outlet.mjs +39 -0
  276. package/esm2020/tree/padding.mjs +131 -0
  277. package/{esm2015/tree/public-api.js → esm2020/tree/public-api.mjs} +0 -0
  278. package/esm2020/tree/toggle.mjs +53 -0
  279. package/{esm2015/tree/tree-errors.js → esm2020/tree/tree-errors.mjs} +0 -0
  280. package/esm2020/tree/tree-module.mjs +49 -0
  281. package/esm2020/tree/tree.mjs +361 -0
  282. package/esm2020/tree/tree_public_index.mjs +5 -0
  283. package/{esm2015/version.js → esm2020/version.mjs} +1 -1
  284. package/fesm2015/{a11y.js → a11y.mjs} +289 -254
  285. package/fesm2015/a11y.mjs.map +1 -0
  286. package/fesm2015/accordion.mjs +275 -0
  287. package/fesm2015/accordion.mjs.map +1 -0
  288. package/fesm2015/bidi.mjs +187 -0
  289. package/fesm2015/bidi.mjs.map +1 -0
  290. package/fesm2015/{cdk.js → cdk.mjs} +2 -2
  291. package/fesm2015/cdk.mjs.map +1 -0
  292. package/fesm2015/clipboard.mjs +261 -0
  293. package/fesm2015/clipboard.mjs.map +1 -0
  294. package/fesm2015/{coercion.js → coercion.mjs} +1 -1
  295. package/fesm2015/coercion.mjs.map +1 -0
  296. package/fesm2015/{collections.js → collections.mjs} +20 -24
  297. package/fesm2015/collections.mjs.map +1 -0
  298. package/fesm2015/drag-drop.mjs +3675 -0
  299. package/fesm2015/drag-drop.mjs.map +1 -0
  300. package/fesm2015/{keycodes.js → keycodes.mjs} +9 -1
  301. package/fesm2015/keycodes.mjs.map +1 -0
  302. package/fesm2015/{layout.js → layout.mjs} +38 -28
  303. package/fesm2015/layout.mjs.map +1 -0
  304. package/fesm2015/{observers.js → observers.mjs} +58 -41
  305. package/fesm2015/observers.mjs.map +1 -0
  306. package/fesm2015/overlay.mjs +3012 -0
  307. package/fesm2015/overlay.mjs.map +1 -0
  308. package/fesm2015/platform.mjs +388 -0
  309. package/fesm2015/platform.mjs.map +1 -0
  310. package/fesm2015/portal.mjs +657 -0
  311. package/fesm2015/portal.mjs.map +1 -0
  312. package/fesm2015/scrolling.mjs +1402 -0
  313. package/fesm2015/scrolling.mjs.map +1 -0
  314. package/fesm2015/{stepper.js → stepper.mjs} +194 -133
  315. package/fesm2015/stepper.mjs.map +1 -0
  316. package/fesm2015/{table.js → table.mjs} +508 -359
  317. package/fesm2015/table.mjs.map +1 -0
  318. package/fesm2015/testing/{protractor.js → protractor.mjs} +12 -25
  319. package/fesm2015/testing/protractor.mjs.map +1 -0
  320. package/fesm2015/testing/{selenium-webdriver.js → selenium-webdriver.mjs} +14 -28
  321. package/fesm2015/testing/selenium-webdriver.mjs.map +1 -0
  322. package/fesm2015/testing/{testbed.js → testbed.mjs} +23 -29
  323. package/fesm2015/testing/testbed.mjs.map +1 -0
  324. package/fesm2015/{testing.js → testing.mjs} +19 -45
  325. package/fesm2015/testing.mjs.map +1 -0
  326. package/fesm2015/text-field.mjs +463 -0
  327. package/fesm2015/text-field.mjs.map +1 -0
  328. package/fesm2015/{tree.js → tree.mjs} +206 -152
  329. package/fesm2015/tree.mjs.map +1 -0
  330. package/fesm2020/a11y.mjs +2376 -0
  331. package/fesm2020/a11y.mjs.map +1 -0
  332. package/{fesm2015/accordion.js → fesm2020/accordion.mjs} +95 -57
  333. package/fesm2020/accordion.mjs.map +1 -0
  334. package/{fesm2015/bidi.js → fesm2020/bidi.mjs} +55 -31
  335. package/fesm2020/bidi.mjs.map +1 -0
  336. package/fesm2020/cdk.mjs +30 -0
  337. package/fesm2020/cdk.mjs.map +1 -0
  338. package/{fesm2015/clipboard.js → fesm2020/clipboard.mjs} +59 -40
  339. package/fesm2020/clipboard.mjs.map +1 -0
  340. package/fesm2020/coercion.mjs +132 -0
  341. package/fesm2020/coercion.mjs.map +1 -0
  342. package/fesm2020/collections.mjs +480 -0
  343. package/fesm2020/collections.mjs.map +1 -0
  344. package/{fesm2015/drag-drop.js → fesm2020/drag-drop.mjs} +528 -369
  345. package/fesm2020/drag-drop.mjs.map +1 -0
  346. package/fesm2020/keycodes.mjs +167 -0
  347. package/fesm2020/keycodes.mjs.map +1 -0
  348. package/fesm2020/layout.mjs +254 -0
  349. package/fesm2020/layout.mjs.map +1 -0
  350. package/fesm2020/observers.mjs +210 -0
  351. package/fesm2020/observers.mjs.map +1 -0
  352. package/{fesm2015/overlay.js → fesm2020/overlay.mjs} +320 -228
  353. package/fesm2020/overlay.mjs.map +1 -0
  354. package/{fesm2015/platform.js → fesm2020/platform.mjs} +60 -28
  355. package/fesm2020/platform.mjs.map +1 -0
  356. package/{fesm2015/portal.js → fesm2020/portal.mjs} +93 -64
  357. package/fesm2020/portal.mjs.map +1 -0
  358. package/{fesm2015/scrolling.js → fesm2020/scrolling.mjs} +221 -170
  359. package/fesm2020/scrolling.mjs.map +1 -0
  360. package/fesm2020/stepper.mjs +646 -0
  361. package/fesm2020/stepper.mjs.map +1 -0
  362. package/fesm2020/table.mjs +2303 -0
  363. package/fesm2020/table.mjs.map +1 -0
  364. package/fesm2020/testing/protractor.mjs +322 -0
  365. package/fesm2020/testing/protractor.mjs.map +1 -0
  366. package/fesm2020/testing/selenium-webdriver.mjs +362 -0
  367. package/fesm2020/testing/selenium-webdriver.mjs.map +1 -0
  368. package/fesm2020/testing/testbed.mjs +780 -0
  369. package/fesm2020/testing/testbed.mjs.map +1 -0
  370. package/fesm2020/testing.mjs +719 -0
  371. package/fesm2020/testing.mjs.map +1 -0
  372. package/{fesm2015/text-field.js → fesm2020/text-field.mjs} +91 -68
  373. package/fesm2020/text-field.mjs.map +1 -0
  374. package/fesm2020/tree.mjs +975 -0
  375. package/fesm2020/tree.mjs.map +1 -0
  376. package/keycodes/index.d.ts +5 -1
  377. package/keycodes/keycodes_public_index.d.ts +4 -0
  378. package/keycodes/package.json +6 -6
  379. package/layout/breakpoints-observer.d.ts +3 -7
  380. package/layout/index.d.ts +5 -1
  381. package/layout/layout-module.d.ts +4 -0
  382. package/layout/layout_public_index.d.ts +4 -0
  383. package/layout/media-matcher.d.ts +3 -0
  384. package/layout/package.json +6 -6
  385. package/observers/index.d.ts +5 -1
  386. package/observers/observe-content.d.ts +10 -0
  387. package/observers/observers_public_index.d.ts +4 -0
  388. package/observers/package.json +6 -6
  389. package/overlay/dispatchers/base-overlay-dispatcher.d.ts +3 -7
  390. package/overlay/dispatchers/overlay-keyboard-dispatcher.d.ts +3 -7
  391. package/overlay/dispatchers/overlay-outside-click-dispatcher.d.ts +6 -7
  392. package/overlay/fullscreen-overlay-container.d.ts +3 -0
  393. package/overlay/index.d.ts +5 -3
  394. package/overlay/overlay-container.d.ts +3 -7
  395. package/overlay/overlay-directives.d.ts +5 -0
  396. package/overlay/overlay-module.d.ts +8 -7
  397. package/overlay/overlay.d.ts +3 -0
  398. package/overlay/overlay_public_index.d.ts +4 -0
  399. package/overlay/package.json +6 -6
  400. package/overlay/position/flexible-connected-position-strategy.d.ts +2 -2
  401. package/overlay/position/overlay-position-builder.d.ts +3 -0
  402. package/overlay/position/scroll-clip.d.ts +5 -2
  403. package/overlay/scroll/index.d.ts +1 -1
  404. package/overlay/scroll/scroll-strategy-options.d.ts +3 -0
  405. package/package.json +219 -7
  406. package/platform/index.d.ts +5 -1
  407. package/platform/package.json +6 -6
  408. package/platform/platform-module.d.ts +4 -7
  409. package/platform/platform.d.ts +3 -7
  410. package/platform/platform_public_index.d.ts +4 -0
  411. package/portal/index.d.ts +5 -1
  412. package/portal/package.json +6 -6
  413. package/portal/portal-directives.d.ts +12 -0
  414. package/portal/portal_public_index.d.ts +4 -0
  415. package/schematics/ng-add/index.js +3 -3
  416. package/schematics/ng-add/index.mjs +3 -3
  417. package/schematics/ng-add/package-config.js +4 -2
  418. package/schematics/ng-add/package-config.mjs +4 -2
  419. package/schematics/ng-add/schema.js +1 -1
  420. package/schematics/ng-add/schema.mjs +1 -1
  421. package/schematics/ng-generate/drag-drop/index.js +6 -6
  422. package/schematics/ng-generate/drag-drop/index.mjs +6 -6
  423. package/schematics/ng-update/data/attribute-selectors.js +7 -5
  424. package/schematics/ng-update/data/attribute-selectors.mjs +7 -5
  425. package/schematics/ng-update/data/class-names.js +13 -11
  426. package/schematics/ng-update/data/class-names.mjs +13 -11
  427. package/schematics/ng-update/data/constructor-checks.js +28 -20
  428. package/schematics/ng-update/data/constructor-checks.mjs +28 -20
  429. package/schematics/ng-update/data/css-selectors.js +2 -2
  430. package/schematics/ng-update/data/css-selectors.mjs +2 -2
  431. package/schematics/ng-update/data/element-selectors.js +2 -2
  432. package/schematics/ng-update/data/element-selectors.mjs +2 -2
  433. package/schematics/ng-update/data/input-names.js +40 -16
  434. package/schematics/ng-update/data/input-names.mjs +40 -16
  435. package/schematics/ng-update/data/method-call-checks.js +32 -18
  436. package/schematics/ng-update/data/method-call-checks.mjs +32 -18
  437. package/schematics/ng-update/data/output-names.js +8 -6
  438. package/schematics/ng-update/data/output-names.mjs +8 -6
  439. package/schematics/ng-update/data/property-names.js +40 -32
  440. package/schematics/ng-update/data/property-names.mjs +40 -32
  441. package/schematics/ng-update/devkit-file-system.js +2 -2
  442. package/schematics/ng-update/devkit-file-system.mjs +2 -2
  443. package/schematics/ng-update/devkit-migration-rule.js +8 -7
  444. package/schematics/ng-update/devkit-migration-rule.mjs +8 -7
  445. package/schematics/ng-update/devkit-migration.d.ts +3 -2
  446. package/schematics/ng-update/devkit-migration.js +1 -1
  447. package/schematics/ng-update/devkit-migration.mjs +1 -1
  448. package/schematics/ng-update/find-stylesheets.js +3 -3
  449. package/schematics/ng-update/find-stylesheets.mjs +3 -3
  450. package/schematics/ng-update/html-parsing/angular.js +7 -7
  451. package/schematics/ng-update/html-parsing/angular.mjs +7 -7
  452. package/schematics/ng-update/html-parsing/elements.js +2 -2
  453. package/schematics/ng-update/html-parsing/elements.mjs +2 -2
  454. package/schematics/ng-update/index.js +11 -9
  455. package/schematics/ng-update/index.mjs +11 -9
  456. package/schematics/ng-update/migrations/attribute-selectors.js +11 -7
  457. package/schematics/ng-update/migrations/attribute-selectors.mjs +11 -7
  458. package/schematics/ng-update/migrations/class-inheritance.js +3 -3
  459. package/schematics/ng-update/migrations/class-inheritance.mjs +3 -3
  460. package/schematics/ng-update/migrations/class-names.js +7 -6
  461. package/schematics/ng-update/migrations/class-names.mjs +7 -6
  462. package/schematics/ng-update/migrations/constructor-signature.js +16 -13
  463. package/schematics/ng-update/migrations/constructor-signature.mjs +16 -13
  464. package/schematics/ng-update/migrations/css-selectors.js +7 -6
  465. package/schematics/ng-update/migrations/css-selectors.mjs +7 -6
  466. package/schematics/ng-update/migrations/element-selectors.js +7 -6
  467. package/schematics/ng-update/migrations/element-selectors.mjs +7 -6
  468. package/schematics/ng-update/migrations/input-names.js +8 -9
  469. package/schematics/ng-update/migrations/input-names.mjs +8 -9
  470. package/schematics/ng-update/migrations/method-call-arguments.js +4 -3
  471. package/schematics/ng-update/migrations/method-call-arguments.mjs +4 -3
  472. package/schematics/ng-update/migrations/misc-template.js +3 -3
  473. package/schematics/ng-update/migrations/misc-template.mjs +3 -3
  474. package/schematics/ng-update/migrations/output-names.js +7 -8
  475. package/schematics/ng-update/migrations/output-names.mjs +7 -8
  476. package/schematics/ng-update/migrations/property-names.js +4 -3
  477. package/schematics/ng-update/migrations/property-names.mjs +4 -3
  478. package/schematics/ng-update/migrations/symbol-removal.js +2 -2
  479. package/schematics/ng-update/migrations/symbol-removal.mjs +2 -2
  480. package/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.d.ts +14 -0
  481. package/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.js +38 -0
  482. package/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.mjs +38 -0
  483. package/schematics/ng-update/typescript/base-types.js +1 -1
  484. package/schematics/ng-update/typescript/base-types.mjs +1 -1
  485. package/schematics/ng-update/typescript/literal.d.ts +1 -1
  486. package/schematics/ng-update/typescript/literal.js +1 -1
  487. package/schematics/ng-update/typescript/literal.mjs +1 -1
  488. package/schematics/ng-update/typescript/module-specifiers.js +5 -5
  489. package/schematics/ng-update/typescript/module-specifiers.mjs +5 -5
  490. package/schematics/ng-update/upgrade-data.js +2 -2
  491. package/schematics/ng-update/upgrade-data.mjs +2 -2
  492. package/schematics/package.json +3 -0
  493. package/schematics/paths.js +3 -3
  494. package/schematics/paths.mjs +3 -3
  495. package/schematics/update-tool/component-resource-collector.js +10 -10
  496. package/schematics/update-tool/component-resource-collector.mjs +10 -10
  497. package/schematics/update-tool/file-system.js +1 -1
  498. package/schematics/update-tool/file-system.mjs +1 -1
  499. package/schematics/update-tool/index.d.ts +4 -1
  500. package/schematics/update-tool/index.js +9 -5
  501. package/schematics/update-tool/index.mjs +9 -5
  502. package/schematics/update-tool/migration.d.ts +1 -1
  503. package/schematics/update-tool/migration.js +1 -1
  504. package/schematics/update-tool/migration.mjs +1 -1
  505. package/schematics/update-tool/target-version.js +1 -1
  506. package/schematics/update-tool/target-version.mjs +1 -1
  507. package/schematics/update-tool/utils/decorators.js +8 -4
  508. package/schematics/update-tool/utils/decorators.mjs +8 -4
  509. package/schematics/update-tool/utils/functions.js +1 -1
  510. package/schematics/update-tool/utils/functions.mjs +1 -1
  511. package/schematics/update-tool/utils/imports.js +2 -2
  512. package/schematics/update-tool/utils/imports.mjs +2 -2
  513. package/schematics/update-tool/utils/line-mappings.js +1 -1
  514. package/schematics/update-tool/utils/line-mappings.mjs +1 -1
  515. package/schematics/update-tool/utils/parse-tsconfig.js +2 -2
  516. package/schematics/update-tool/utils/parse-tsconfig.mjs +2 -2
  517. package/schematics/update-tool/utils/property-name.js +1 -1
  518. package/schematics/update-tool/utils/property-name.mjs +1 -1
  519. package/schematics/update-tool/utils/virtual-host.d.ts +1 -1
  520. package/schematics/update-tool/utils/virtual-host.js +3 -3
  521. package/schematics/update-tool/utils/virtual-host.mjs +3 -3
  522. package/schematics/update-tool/version-changes.js +1 -1
  523. package/schematics/update-tool/version-changes.mjs +1 -1
  524. package/schematics/utils/ast/ng-module-imports.js +5 -3
  525. package/schematics/utils/ast/ng-module-imports.mjs +5 -3
  526. package/schematics/utils/ast.js +5 -5
  527. package/schematics/utils/ast.mjs +5 -5
  528. package/schematics/utils/build-component.js +32 -38
  529. package/schematics/utils/build-component.mjs +32 -38
  530. package/schematics/utils/get-project.js +1 -1
  531. package/schematics/utils/get-project.mjs +1 -1
  532. package/schematics/utils/html-manipulation.js +8 -7
  533. package/schematics/utils/html-manipulation.mjs +8 -7
  534. package/schematics/utils/parse5-element.js +9 -10
  535. package/schematics/utils/parse5-element.mjs +9 -10
  536. package/schematics/utils/project-index-file.js +2 -2
  537. package/schematics/utils/project-index-file.mjs +2 -2
  538. package/schematics/utils/project-main-file.js +2 -2
  539. package/schematics/utils/project-main-file.mjs +2 -2
  540. package/schematics/utils/project-style-file.js +7 -9
  541. package/schematics/utils/project-style-file.mjs +7 -9
  542. package/schematics/utils/project-targets.js +1 -1
  543. package/schematics/utils/project-targets.mjs +1 -1
  544. package/schematics/utils/project-tsconfig-paths.js +4 -4
  545. package/schematics/utils/project-tsconfig-paths.mjs +4 -4
  546. package/schematics/utils/schematic-options.js +7 -5
  547. package/schematics/utils/schematic-options.mjs +7 -5
  548. package/schematics/utils/vendored-ast-utils/index.js +17 -18
  549. package/schematics/utils/vendored-ast-utils/index.mjs +17 -18
  550. package/scrolling/fixed-size-virtual-scroll.d.ts +3 -0
  551. package/scrolling/index.d.ts +5 -1
  552. package/scrolling/package.json +6 -6
  553. package/scrolling/scroll-dispatcher.d.ts +3 -7
  554. package/scrolling/scrollable.d.ts +3 -0
  555. package/scrolling/scrolling-module.d.ts +13 -7
  556. package/scrolling/scrolling_public_index.d.ts +4 -0
  557. package/scrolling/viewport-ruler.d.ts +11 -1
  558. package/scrolling/virtual-for-of.d.ts +3 -0
  559. package/scrolling/virtual-scroll-viewport.d.ts +3 -0
  560. package/stepper/index.d.ts +5 -1
  561. package/stepper/package.json +6 -6
  562. package/stepper/step-header.d.ts +3 -0
  563. package/stepper/step-label.d.ts +3 -0
  564. package/stepper/stepper-button.d.ts +5 -7
  565. package/stepper/stepper-module.d.ts +9 -7
  566. package/stepper/stepper.d.ts +5 -7
  567. package/stepper/stepper_public_index.d.ts +4 -0
  568. package/table/cell.d.ts +15 -0
  569. package/table/coalesced-style-scheduler.d.ts +3 -0
  570. package/table/index.d.ts +5 -1
  571. package/table/package.json +6 -6
  572. package/table/row.d.ts +19 -0
  573. package/table/table-module.d.ts +9 -7
  574. package/table/table.d.ts +13 -0
  575. package/table/table_public_index.d.ts +4 -0
  576. package/table/text-column.d.ts +3 -0
  577. package/testing/package.json +5 -5
  578. package/testing/protractor/package.json +5 -5
  579. package/testing/selenium-webdriver/package.json +5 -5
  580. package/testing/testbed/package.json +5 -5
  581. package/testing/testbed/proxy-zone-types.d.ts +1 -1
  582. package/testing/testbed/zone-types.d.ts +1 -1
  583. package/text-field/autofill.d.ts +5 -0
  584. package/text-field/autosize.d.ts +3 -0
  585. package/text-field/index.d.ts +5 -1
  586. package/text-field/package.json +6 -6
  587. package/text-field/text-field-module.d.ts +7 -7
  588. package/text-field/text-field_public_index.d.ts +4 -0
  589. package/tree/control/base-tree-control.d.ts +1 -1
  590. package/tree/control/nested-tree-control.d.ts +2 -2
  591. package/tree/index.d.ts +5 -1
  592. package/tree/nested-node.d.ts +3 -0
  593. package/tree/node.d.ts +3 -0
  594. package/tree/outlet.d.ts +3 -0
  595. package/tree/package.json +6 -6
  596. package/tree/padding.d.ts +3 -0
  597. package/tree/toggle.d.ts +3 -0
  598. package/tree/tree-module.d.ts +10 -7
  599. package/tree/tree.d.ts +5 -0
  600. package/tree/tree_public_index.d.ts +4 -0
  601. package/a11y/index.metadata.json +0 -1
  602. package/accordion/index.metadata.json +0 -1
  603. package/bidi/index.metadata.json +0 -1
  604. package/bundles/cdk-a11y.umd.js +0 -2752
  605. package/bundles/cdk-a11y.umd.js.map +0 -1
  606. package/bundles/cdk-accordion.umd.js +0 -262
  607. package/bundles/cdk-accordion.umd.js.map +0 -1
  608. package/bundles/cdk-bidi.umd.js +0 -206
  609. package/bundles/cdk-bidi.umd.js.map +0 -1
  610. package/bundles/cdk-clipboard.umd.js +0 -278
  611. package/bundles/cdk-clipboard.umd.js.map +0 -1
  612. package/bundles/cdk-coercion.umd.js +0 -477
  613. package/bundles/cdk-coercion.umd.js.map +0 -1
  614. package/bundles/cdk-collections.umd.js +0 -846
  615. package/bundles/cdk-collections.umd.js.map +0 -1
  616. package/bundles/cdk-drag-drop.umd.js +0 -3921
  617. package/bundles/cdk-drag-drop.umd.js.map +0 -1
  618. package/bundles/cdk-keycodes.umd.js +0 -292
  619. package/bundles/cdk-keycodes.umd.js.map +0 -1
  620. package/bundles/cdk-layout.umd.js +0 -284
  621. package/bundles/cdk-layout.umd.js.map +0 -1
  622. package/bundles/cdk-observers.umd.js +0 -242
  623. package/bundles/cdk-observers.umd.js.map +0 -1
  624. package/bundles/cdk-overlay.umd.js +0 -3417
  625. package/bundles/cdk-overlay.umd.js.map +0 -1
  626. package/bundles/cdk-platform.umd.js +0 -397
  627. package/bundles/cdk-platform.umd.js.map +0 -1
  628. package/bundles/cdk-portal.umd.js +0 -1008
  629. package/bundles/cdk-portal.umd.js.map +0 -1
  630. package/bundles/cdk-scrolling.umd.js +0 -1787
  631. package/bundles/cdk-scrolling.umd.js.map +0 -1
  632. package/bundles/cdk-stepper.umd.js +0 -648
  633. package/bundles/cdk-stepper.umd.js.map +0 -1
  634. package/bundles/cdk-table.umd.js +0 -2730
  635. package/bundles/cdk-table.umd.js.map +0 -1
  636. package/bundles/cdk-testing-protractor.umd.js +0 -833
  637. package/bundles/cdk-testing-protractor.umd.js.map +0 -1
  638. package/bundles/cdk-testing-selenium-webdriver.umd.js +0 -1002
  639. package/bundles/cdk-testing-selenium-webdriver.umd.js.map +0 -1
  640. package/bundles/cdk-testing-testbed.umd.js +0 -1396
  641. package/bundles/cdk-testing-testbed.umd.js.map +0 -1
  642. package/bundles/cdk-testing.umd.js +0 -1285
  643. package/bundles/cdk-testing.umd.js.map +0 -1
  644. package/bundles/cdk-text-field.umd.js +0 -494
  645. package/bundles/cdk-text-field.umd.js.map +0 -1
  646. package/bundles/cdk-tree.umd.js +0 -1308
  647. package/bundles/cdk-tree.umd.js.map +0 -1
  648. package/bundles/cdk.umd.js +0 -38
  649. package/bundles/cdk.umd.js.map +0 -1
  650. package/clipboard/index.metadata.json +0 -1
  651. package/collections/index.metadata.json +0 -1
  652. package/drag-drop/index.metadata.json +0 -1
  653. package/esm2015/a11y/a11y-module.js +0 -30
  654. package/esm2015/a11y/a11y.externs.js +0 -6
  655. package/esm2015/a11y/aria-describer/aria-describer.js +0 -213
  656. package/esm2015/a11y/fake-event-detection.js +0 -28
  657. package/esm2015/a11y/focus-monitor/focus-monitor.js +0 -394
  658. package/esm2015/a11y/focus-trap/configurable-focus-trap-factory.js +0 -52
  659. package/esm2015/a11y/focus-trap/configurable-focus-trap.js +0 -49
  660. package/esm2015/a11y/focus-trap/event-listener-inert-strategy.js +0 -62
  661. package/esm2015/a11y/focus-trap/focus-trap-inert-strategy.js +0 -11
  662. package/esm2015/a11y/focus-trap/focus-trap-manager.js +0 -51
  663. package/esm2015/a11y/focus-trap/focus-trap.js +0 -391
  664. package/esm2015/a11y/high-contrast-mode/high-contrast-mode-detector.js +0 -92
  665. package/esm2015/a11y/index.js +0 -6
  666. package/esm2015/a11y/input-modality/input-modality-detector.js +0 -171
  667. package/esm2015/a11y/interactivity-checker/interactivity-checker.js +0 -237
  668. package/esm2015/a11y/key-manager/list-key-manager.js +0 -317
  669. package/esm2015/a11y/live-announcer/live-announcer-tokens.js +0 -19
  670. package/esm2015/a11y/live-announcer/live-announcer.js +0 -167
  671. package/esm2015/accordion/accordion-item.js +0 -146
  672. package/esm2015/accordion/accordion-module.js +0 -19
  673. package/esm2015/accordion/accordion.externs.js +0 -6
  674. package/esm2015/accordion/accordion.js +0 -63
  675. package/esm2015/accordion/index.js +0 -6
  676. package/esm2015/bidi/bidi-module.js +0 -18
  677. package/esm2015/bidi/bidi.externs.js +0 -6
  678. package/esm2015/bidi/dir.js +0 -58
  679. package/esm2015/bidi/directionality.js +0 -44
  680. package/esm2015/bidi/index.js +0 -6
  681. package/esm2015/cdk.externs.js +0 -0
  682. package/esm2015/clipboard/clipboard-module.js +0 -18
  683. package/esm2015/clipboard/clipboard.externs.js +0 -6
  684. package/esm2015/clipboard/clipboard.js +0 -52
  685. package/esm2015/clipboard/copy-to-clipboard.js +0 -90
  686. package/esm2015/clipboard/index.js +0 -5
  687. package/esm2015/clipboard/pending-copy.js +0 -68
  688. package/esm2015/coercion/coercion.externs.js +0 -0
  689. package/esm2015/collections/collection-viewer.js +0 -9
  690. package/esm2015/collections/collections.externs.js +0 -6
  691. package/esm2015/collections/dispose-view-repeater-strategy.js +0 -48
  692. package/esm2015/collections/index.js +0 -5
  693. package/esm2015/collections/recycle-view-repeater-strategy.js +0 -125
  694. package/esm2015/collections/tree-adapter.js +0 -9
  695. package/esm2015/collections/unique-selection-dispatcher.js +0 -53
  696. package/esm2015/collections/view-repeater.js +0 -14
  697. package/esm2015/drag-drop/client-rect.js +0 -60
  698. package/esm2015/drag-drop/clone-node.js +0 -65
  699. package/esm2015/drag-drop/directives/assertions.js +0 -19
  700. package/esm2015/drag-drop/directives/drag-handle.js +0 -57
  701. package/esm2015/drag-drop/directives/drag-placeholder.js +0 -36
  702. package/esm2015/drag-drop/directives/drag-preview.js +0 -42
  703. package/esm2015/drag-drop/directives/drag.js +0 -413
  704. package/esm2015/drag-drop/directives/drop-list-group.js +0 -47
  705. package/esm2015/drag-drop/directives/drop-list.js +0 -301
  706. package/esm2015/drag-drop/drag-drop-module.js +0 -43
  707. package/esm2015/drag-drop/drag-drop-registry.js +0 -231
  708. package/esm2015/drag-drop/drag-drop.externs.js +0 -6
  709. package/esm2015/drag-drop/drag-drop.js +0 -59
  710. package/esm2015/drag-drop/drag-events.js +0 -9
  711. package/esm2015/drag-drop/drag-ref.js +0 -1110
  712. package/esm2015/drag-drop/drag-styling.js +0 -69
  713. package/esm2015/drag-drop/drag-utils.js +0 -60
  714. package/esm2015/drag-drop/drop-list-ref.js +0 -813
  715. package/esm2015/drag-drop/index.js +0 -5
  716. package/esm2015/drag-drop/transition-duration.js +0 -36
  717. package/esm2015/keycodes/index.js +0 -5
  718. package/esm2015/keycodes/keycodes.externs.js +0 -6
  719. package/esm2015/layout/breakpoints-observer.js +0 -106
  720. package/esm2015/layout/index.js +0 -5
  721. package/esm2015/layout/layout-module.js +0 -14
  722. package/esm2015/layout/layout.externs.js +0 -6
  723. package/esm2015/layout/media-matcher.js +0 -85
  724. package/esm2015/observers/index.js +0 -5
  725. package/esm2015/observers/observe-content.js +0 -179
  726. package/esm2015/observers/observers.externs.js +0 -6
  727. package/esm2015/overlay/dispatchers/base-overlay-dispatcher.js +0 -51
  728. package/esm2015/overlay/dispatchers/overlay-keyboard-dispatcher.js +0 -62
  729. package/esm2015/overlay/dispatchers/overlay-outside-click-dispatcher.js +0 -97
  730. package/esm2015/overlay/fullscreen-overlay-container.js +0 -94
  731. package/esm2015/overlay/index.js +0 -7
  732. package/esm2015/overlay/overlay-config.js +0 -45
  733. package/esm2015/overlay/overlay-container.js +0 -85
  734. package/esm2015/overlay/overlay-directives.js +0 -352
  735. package/esm2015/overlay/overlay-module.js +0 -27
  736. package/esm2015/overlay/overlay-ref.js +0 -409
  737. package/esm2015/overlay/overlay.externs.js +0 -6
  738. package/esm2015/overlay/overlay.js +0 -119
  739. package/esm2015/overlay/position/connected-position.js +0 -94
  740. package/esm2015/overlay/position/flexible-connected-position-strategy.js +0 -960
  741. package/esm2015/overlay/position/global-position-strategy.js +0 -197
  742. package/esm2015/overlay/position/overlay-position-builder.js +0 -52
  743. package/esm2015/overlay/position/scroll-clip.js +0 -42
  744. package/esm2015/overlay/scroll/close-scroll-strategy.js +0 -61
  745. package/esm2015/overlay/scroll/scroll-strategy-options.js +0 -57
  746. package/esm2015/platform/features/passive-listeners.js +0 -36
  747. package/esm2015/platform/features/scrolling.js +0 -85
  748. package/esm2015/platform/features/test-environment.js +0 -16
  749. package/esm2015/platform/index.js +0 -5
  750. package/esm2015/platform/platform-module.js +0 -14
  751. package/esm2015/platform/platform.externs.js +0 -6
  752. package/esm2015/platform/platform.js +0 -77
  753. package/esm2015/portal/dom-portal-outlet.js +0 -136
  754. package/esm2015/portal/index.js +0 -5
  755. package/esm2015/portal/portal-directives.js +0 -221
  756. package/esm2015/portal/portal-injector.js +0 -28
  757. package/esm2015/portal/portal.externs.js +0 -6
  758. package/esm2015/portal/portal.js +0 -179
  759. package/esm2015/scrolling/fixed-size-virtual-scroll.js +0 -188
  760. package/esm2015/scrolling/index.js +0 -5
  761. package/esm2015/scrolling/scroll-dispatcher.js +0 -163
  762. package/esm2015/scrolling/scrollable.js +0 -173
  763. package/esm2015/scrolling/scrolling-module.js +0 -49
  764. package/esm2015/scrolling/scrolling.externs.js +0 -6
  765. package/esm2015/scrolling/viewport-ruler.js +0 -139
  766. package/esm2015/scrolling/virtual-for-of.js +0 -293
  767. package/esm2015/scrolling/virtual-scroll-strategy.js +0 -11
  768. package/esm2015/scrolling/virtual-scroll-viewport.js +0 -371
  769. package/esm2015/stepper/index.js +0 -5
  770. package/esm2015/stepper/step-header.js +0 -29
  771. package/esm2015/stepper/step-label.js +0 -22
  772. package/esm2015/stepper/stepper-button.js +0 -72
  773. package/esm2015/stepper/stepper-module.js +0 -37
  774. package/esm2015/stepper/stepper.externs.js +0 -6
  775. package/esm2015/stepper/stepper.js +0 -428
  776. package/esm2015/table/can-stick.js +0 -42
  777. package/esm2015/table/cell.js +0 -211
  778. package/esm2015/table/coalesced-style-scheduler.js +0 -89
  779. package/esm2015/table/index.js +0 -5
  780. package/esm2015/table/row.js +0 -244
  781. package/esm2015/table/sticky-position-listener.js +0 -11
  782. package/esm2015/table/sticky-styler.js +0 -336
  783. package/esm2015/table/table-module.js +0 -47
  784. package/esm2015/table/table.externs.js +0 -6
  785. package/esm2015/table/table.js +0 -987
  786. package/esm2015/table/text-column.js +0 -127
  787. package/esm2015/testing/change-detection.js +0 -110
  788. package/esm2015/testing/component-harness.js +0 -344
  789. package/esm2015/testing/harness-environment.js +0 -219
  790. package/esm2015/testing/protractor/protractor-element.js +0 -274
  791. package/esm2015/testing/protractor/protractor-harness-environment.js +0 -79
  792. package/esm2015/testing/protractor/protractor.externs.js +0 -0
  793. package/esm2015/testing/selenium-webdriver/selenium-web-driver-element.js +0 -241
  794. package/esm2015/testing/selenium-webdriver/selenium-web-driver-harness-environment.js +0 -97
  795. package/esm2015/testing/selenium-webdriver/selenium-webdriver.externs.js +0 -0
  796. package/esm2015/testing/test-element.js +0 -48
  797. package/esm2015/testing/testbed/fake-events/dispatch-events.js +0 -53
  798. package/esm2015/testing/testbed/fake-events/element-focus.js +0 -39
  799. package/esm2015/testing/testbed/fake-events/event-objects.js +0 -107
  800. package/esm2015/testing/testbed/fake-events/type-in-element.js +0 -79
  801. package/esm2015/testing/testbed/task-state-zone-interceptor.js +0 -82
  802. package/esm2015/testing/testbed/testbed-harness-environment.js +0 -173
  803. package/esm2015/testing/testbed/testbed.externs.js +0 -0
  804. package/esm2015/testing/testbed/unit-test-element.js +0 -266
  805. package/esm2015/testing/testing.externs.js +0 -0
  806. package/esm2015/testing/text-filtering.js +0 -23
  807. package/esm2015/text-field/autofill.js +0 -117
  808. package/esm2015/text-field/autosize.js +0 -293
  809. package/esm2015/text-field/index.js +0 -5
  810. package/esm2015/text-field/text-field-module.js +0 -21
  811. package/esm2015/text-field/text-field.externs.js +0 -6
  812. package/esm2015/tree/control/nested-tree-control.js +0 -59
  813. package/esm2015/tree/index.js +0 -5
  814. package/esm2015/tree/nested-node.js +0 -112
  815. package/esm2015/tree/node.js +0 -36
  816. package/esm2015/tree/outlet.js +0 -34
  817. package/esm2015/tree/padding.js +0 -119
  818. package/esm2015/tree/toggle.js +0 -46
  819. package/esm2015/tree/tree-module.js +0 -32
  820. package/esm2015/tree/tree.externs.js +0 -6
  821. package/esm2015/tree/tree.js +0 -345
  822. package/fesm2015/a11y.js.map +0 -1
  823. package/fesm2015/accordion.js.map +0 -1
  824. package/fesm2015/bidi.js.map +0 -1
  825. package/fesm2015/cdk.js.map +0 -1
  826. package/fesm2015/clipboard.js.map +0 -1
  827. package/fesm2015/coercion.js.map +0 -1
  828. package/fesm2015/collections.js.map +0 -1
  829. package/fesm2015/drag-drop.js.map +0 -1
  830. package/fesm2015/keycodes.js.map +0 -1
  831. package/fesm2015/layout.js.map +0 -1
  832. package/fesm2015/observers.js.map +0 -1
  833. package/fesm2015/overlay.js.map +0 -1
  834. package/fesm2015/platform.js.map +0 -1
  835. package/fesm2015/portal.js.map +0 -1
  836. package/fesm2015/scrolling.js.map +0 -1
  837. package/fesm2015/stepper.js.map +0 -1
  838. package/fesm2015/table.js.map +0 -1
  839. package/fesm2015/testing/protractor.js.map +0 -1
  840. package/fesm2015/testing/selenium-webdriver.js.map +0 -1
  841. package/fesm2015/testing/testbed.js.map +0 -1
  842. package/fesm2015/testing.js.map +0 -1
  843. package/fesm2015/text-field.js.map +0 -1
  844. package/fesm2015/tree.js.map +0 -1
  845. package/keycodes/index.metadata.json +0 -1
  846. package/layout/index.metadata.json +0 -1
  847. package/observers/index.metadata.json +0 -1
  848. package/overlay/index.metadata.json +0 -1
  849. package/platform/index.metadata.json +0 -1
  850. package/portal/index.metadata.json +0 -1
  851. package/scrolling/index.metadata.json +0 -1
  852. package/stepper/index.metadata.json +0 -1
  853. package/table/index.metadata.json +0 -1
  854. package/text-field/index.metadata.json +0 -1
  855. package/tree/index.metadata.json +0 -1
@@ -1,960 +0,0 @@
1
- /**
2
- * @license
3
- * Copyright Google LLC All Rights Reserved.
4
- *
5
- * Use of this source code is governed by an MIT-style license that can be
6
- * found in the LICENSE file at https://angular.io/license
7
- */
8
- import { ElementRef } from '@angular/core';
9
- import { ConnectedOverlayPositionChange, validateHorizontalPosition, validateVerticalPosition, } from './connected-position';
10
- import { Subscription, Subject } from 'rxjs';
11
- import { isElementScrolledOutsideView, isElementClippedByScrolling } from './scroll-clip';
12
- import { coerceCssPixelValue, coerceArray } from '@angular/cdk/coercion';
13
- // TODO: refactor clipping detection into a separate thing (part of scrolling module)
14
- // TODO: doesn't handle both flexible width and height when it has to scroll along both axis.
15
- /** Class to be added to the overlay bounding box. */
16
- const boundingBoxClass = 'cdk-overlay-connected-position-bounding-box';
17
- /** Regex used to split a string on its CSS units. */
18
- const cssUnitPattern = /([A-Za-z%]+)$/;
19
- /**
20
- * A strategy for positioning overlays. Using this strategy, an overlay is given an
21
- * implicit position relative some origin element. The relative position is defined in terms of
22
- * a point on the origin element that is connected to a point on the overlay element. For example,
23
- * a basic dropdown is connecting the bottom-left corner of the origin to the top-left corner
24
- * of the overlay.
25
- */
26
- export class FlexibleConnectedPositionStrategy {
27
- constructor(connectedTo, _viewportRuler, _document, _platform, _overlayContainer) {
28
- this._viewportRuler = _viewportRuler;
29
- this._document = _document;
30
- this._platform = _platform;
31
- this._overlayContainer = _overlayContainer;
32
- /** Last size used for the bounding box. Used to avoid resizing the overlay after open. */
33
- this._lastBoundingBoxSize = { width: 0, height: 0 };
34
- /** Whether the overlay was pushed in a previous positioning. */
35
- this._isPushed = false;
36
- /** Whether the overlay can be pushed on-screen on the initial open. */
37
- this._canPush = true;
38
- /** Whether the overlay can grow via flexible width/height after the initial open. */
39
- this._growAfterOpen = false;
40
- /** Whether the overlay's width and height can be constrained to fit within the viewport. */
41
- this._hasFlexibleDimensions = true;
42
- /** Whether the overlay position is locked. */
43
- this._positionLocked = false;
44
- /** Amount of space that must be maintained between the overlay and the edge of the viewport. */
45
- this._viewportMargin = 0;
46
- /** The Scrollable containers used to check scrollable view properties on position change. */
47
- this._scrollables = [];
48
- /** Ordered list of preferred positions, from most to least desirable. */
49
- this._preferredPositions = [];
50
- /** Subject that emits whenever the position changes. */
51
- this._positionChanges = new Subject();
52
- /** Subscription to viewport size changes. */
53
- this._resizeSubscription = Subscription.EMPTY;
54
- /** Default offset for the overlay along the x axis. */
55
- this._offsetX = 0;
56
- /** Default offset for the overlay along the y axis. */
57
- this._offsetY = 0;
58
- /** Keeps track of the CSS classes that the position strategy has applied on the overlay panel. */
59
- this._appliedPanelClasses = [];
60
- /** Observable sequence of position changes. */
61
- this.positionChanges = this._positionChanges;
62
- this.setOrigin(connectedTo);
63
- }
64
- /** Ordered list of preferred positions, from most to least desirable. */
65
- get positions() {
66
- return this._preferredPositions;
67
- }
68
- /** Attaches this position strategy to an overlay. */
69
- attach(overlayRef) {
70
- if (this._overlayRef && overlayRef !== this._overlayRef &&
71
- (typeof ngDevMode === 'undefined' || ngDevMode)) {
72
- throw Error('This position strategy is already attached to an overlay');
73
- }
74
- this._validatePositions();
75
- overlayRef.hostElement.classList.add(boundingBoxClass);
76
- this._overlayRef = overlayRef;
77
- this._boundingBox = overlayRef.hostElement;
78
- this._pane = overlayRef.overlayElement;
79
- this._isDisposed = false;
80
- this._isInitialRender = true;
81
- this._lastPosition = null;
82
- this._resizeSubscription.unsubscribe();
83
- this._resizeSubscription = this._viewportRuler.change().subscribe(() => {
84
- // When the window is resized, we want to trigger the next reposition as if it
85
- // was an initial render, in order for the strategy to pick a new optimal position,
86
- // otherwise position locking will cause it to stay at the old one.
87
- this._isInitialRender = true;
88
- this.apply();
89
- });
90
- }
91
- /**
92
- * Updates the position of the overlay element, using whichever preferred position relative
93
- * to the origin best fits on-screen.
94
- *
95
- * The selection of a position goes as follows:
96
- * - If any positions fit completely within the viewport as-is,
97
- * choose the first position that does so.
98
- * - If flexible dimensions are enabled and at least one satifies the given minimum width/height,
99
- * choose the position with the greatest available size modified by the positions' weight.
100
- * - If pushing is enabled, take the position that went off-screen the least and push it
101
- * on-screen.
102
- * - If none of the previous criteria were met, use the position that goes off-screen the least.
103
- * @docs-private
104
- */
105
- apply() {
106
- // We shouldn't do anything if the strategy was disposed or we're on the server.
107
- if (this._isDisposed || !this._platform.isBrowser) {
108
- return;
109
- }
110
- // If the position has been applied already (e.g. when the overlay was opened) and the
111
- // consumer opted into locking in the position, re-use the old position, in order to
112
- // prevent the overlay from jumping around.
113
- if (!this._isInitialRender && this._positionLocked && this._lastPosition) {
114
- this.reapplyLastPosition();
115
- return;
116
- }
117
- this._clearPanelClasses();
118
- this._resetOverlayElementStyles();
119
- this._resetBoundingBoxStyles();
120
- // We need the bounding rects for the origin and the overlay to determine how to position
121
- // the overlay relative to the origin.
122
- // We use the viewport rect to determine whether a position would go off-screen.
123
- this._viewportRect = this._getNarrowedViewportRect();
124
- this._originRect = this._getOriginRect();
125
- this._overlayRect = this._pane.getBoundingClientRect();
126
- const originRect = this._originRect;
127
- const overlayRect = this._overlayRect;
128
- const viewportRect = this._viewportRect;
129
- // Positions where the overlay will fit with flexible dimensions.
130
- const flexibleFits = [];
131
- // Fallback if none of the preferred positions fit within the viewport.
132
- let fallback;
133
- // Go through each of the preferred positions looking for a good fit.
134
- // If a good fit is found, it will be applied immediately.
135
- for (let pos of this._preferredPositions) {
136
- // Get the exact (x, y) coordinate for the point-of-origin on the origin element.
137
- let originPoint = this._getOriginPoint(originRect, pos);
138
- // From that point-of-origin, get the exact (x, y) coordinate for the top-left corner of the
139
- // overlay in this position. We use the top-left corner for calculations and later translate
140
- // this into an appropriate (top, left, bottom, right) style.
141
- let overlayPoint = this._getOverlayPoint(originPoint, overlayRect, pos);
142
- // Calculate how well the overlay would fit into the viewport with this point.
143
- let overlayFit = this._getOverlayFit(overlayPoint, overlayRect, viewportRect, pos);
144
- // If the overlay, without any further work, fits into the viewport, use this position.
145
- if (overlayFit.isCompletelyWithinViewport) {
146
- this._isPushed = false;
147
- this._applyPosition(pos, originPoint);
148
- return;
149
- }
150
- // If the overlay has flexible dimensions, we can use this position
151
- // so long as there's enough space for the minimum dimensions.
152
- if (this._canFitWithFlexibleDimensions(overlayFit, overlayPoint, viewportRect)) {
153
- // Save positions where the overlay will fit with flexible dimensions. We will use these
154
- // if none of the positions fit *without* flexible dimensions.
155
- flexibleFits.push({
156
- position: pos,
157
- origin: originPoint,
158
- overlayRect,
159
- boundingBoxRect: this._calculateBoundingBoxRect(originPoint, pos)
160
- });
161
- continue;
162
- }
163
- // If the current preferred position does not fit on the screen, remember the position
164
- // if it has more visible area on-screen than we've seen and move onto the next preferred
165
- // position.
166
- if (!fallback || fallback.overlayFit.visibleArea < overlayFit.visibleArea) {
167
- fallback = { overlayFit, overlayPoint, originPoint, position: pos, overlayRect };
168
- }
169
- }
170
- // If there are any positions where the overlay would fit with flexible dimensions, choose the
171
- // one that has the greatest area available modified by the position's weight
172
- if (flexibleFits.length) {
173
- let bestFit = null;
174
- let bestScore = -1;
175
- for (const fit of flexibleFits) {
176
- const score = fit.boundingBoxRect.width * fit.boundingBoxRect.height * (fit.position.weight || 1);
177
- if (score > bestScore) {
178
- bestScore = score;
179
- bestFit = fit;
180
- }
181
- }
182
- this._isPushed = false;
183
- this._applyPosition(bestFit.position, bestFit.origin);
184
- return;
185
- }
186
- // When none of the preferred positions fit within the viewport, take the position
187
- // that went off-screen the least and attempt to push it on-screen.
188
- if (this._canPush) {
189
- // TODO(jelbourn): after pushing, the opening "direction" of the overlay might not make sense.
190
- this._isPushed = true;
191
- this._applyPosition(fallback.position, fallback.originPoint);
192
- return;
193
- }
194
- // All options for getting the overlay within the viewport have been exhausted, so go with the
195
- // position that went off-screen the least.
196
- this._applyPosition(fallback.position, fallback.originPoint);
197
- }
198
- detach() {
199
- this._clearPanelClasses();
200
- this._lastPosition = null;
201
- this._previousPushAmount = null;
202
- this._resizeSubscription.unsubscribe();
203
- }
204
- /** Cleanup after the element gets destroyed. */
205
- dispose() {
206
- if (this._isDisposed) {
207
- return;
208
- }
209
- // We can't use `_resetBoundingBoxStyles` here, because it resets
210
- // some properties to zero, rather than removing them.
211
- if (this._boundingBox) {
212
- extendStyles(this._boundingBox.style, {
213
- top: '',
214
- left: '',
215
- right: '',
216
- bottom: '',
217
- height: '',
218
- width: '',
219
- alignItems: '',
220
- justifyContent: '',
221
- });
222
- }
223
- if (this._pane) {
224
- this._resetOverlayElementStyles();
225
- }
226
- if (this._overlayRef) {
227
- this._overlayRef.hostElement.classList.remove(boundingBoxClass);
228
- }
229
- this.detach();
230
- this._positionChanges.complete();
231
- this._overlayRef = this._boundingBox = null;
232
- this._isDisposed = true;
233
- }
234
- /**
235
- * This re-aligns the overlay element with the trigger in its last calculated position,
236
- * even if a position higher in the "preferred positions" list would now fit. This
237
- * allows one to re-align the panel without changing the orientation of the panel.
238
- */
239
- reapplyLastPosition() {
240
- if (!this._isDisposed && (!this._platform || this._platform.isBrowser)) {
241
- this._originRect = this._getOriginRect();
242
- this._overlayRect = this._pane.getBoundingClientRect();
243
- this._viewportRect = this._getNarrowedViewportRect();
244
- const lastPosition = this._lastPosition || this._preferredPositions[0];
245
- const originPoint = this._getOriginPoint(this._originRect, lastPosition);
246
- this._applyPosition(lastPosition, originPoint);
247
- }
248
- }
249
- /**
250
- * Sets the list of Scrollable containers that host the origin element so that
251
- * on reposition we can evaluate if it or the overlay has been clipped or outside view. Every
252
- * Scrollable must be an ancestor element of the strategy's origin element.
253
- */
254
- withScrollableContainers(scrollables) {
255
- this._scrollables = scrollables;
256
- return this;
257
- }
258
- /**
259
- * Adds new preferred positions.
260
- * @param positions List of positions options for this overlay.
261
- */
262
- withPositions(positions) {
263
- this._preferredPositions = positions;
264
- // If the last calculated position object isn't part of the positions anymore, clear
265
- // it in order to avoid it being picked up if the consumer tries to re-apply.
266
- if (positions.indexOf(this._lastPosition) === -1) {
267
- this._lastPosition = null;
268
- }
269
- this._validatePositions();
270
- return this;
271
- }
272
- /**
273
- * Sets a minimum distance the overlay may be positioned to the edge of the viewport.
274
- * @param margin Required margin between the overlay and the viewport edge in pixels.
275
- */
276
- withViewportMargin(margin) {
277
- this._viewportMargin = margin;
278
- return this;
279
- }
280
- /** Sets whether the overlay's width and height can be constrained to fit within the viewport. */
281
- withFlexibleDimensions(flexibleDimensions = true) {
282
- this._hasFlexibleDimensions = flexibleDimensions;
283
- return this;
284
- }
285
- /** Sets whether the overlay can grow after the initial open via flexible width/height. */
286
- withGrowAfterOpen(growAfterOpen = true) {
287
- this._growAfterOpen = growAfterOpen;
288
- return this;
289
- }
290
- /** Sets whether the overlay can be pushed on-screen if none of the provided positions fit. */
291
- withPush(canPush = true) {
292
- this._canPush = canPush;
293
- return this;
294
- }
295
- /**
296
- * Sets whether the overlay's position should be locked in after it is positioned
297
- * initially. When an overlay is locked in, it won't attempt to reposition itself
298
- * when the position is re-applied (e.g. when the user scrolls away).
299
- * @param isLocked Whether the overlay should locked in.
300
- */
301
- withLockedPosition(isLocked = true) {
302
- this._positionLocked = isLocked;
303
- return this;
304
- }
305
- /**
306
- * Sets the origin, relative to which to position the overlay.
307
- * Using an element origin is useful for building components that need to be positioned
308
- * relatively to a trigger (e.g. dropdown menus or tooltips), whereas using a point can be
309
- * used for cases like contextual menus which open relative to the user's pointer.
310
- * @param origin Reference to the new origin.
311
- */
312
- setOrigin(origin) {
313
- this._origin = origin;
314
- return this;
315
- }
316
- /**
317
- * Sets the default offset for the overlay's connection point on the x-axis.
318
- * @param offset New offset in the X axis.
319
- */
320
- withDefaultOffsetX(offset) {
321
- this._offsetX = offset;
322
- return this;
323
- }
324
- /**
325
- * Sets the default offset for the overlay's connection point on the y-axis.
326
- * @param offset New offset in the Y axis.
327
- */
328
- withDefaultOffsetY(offset) {
329
- this._offsetY = offset;
330
- return this;
331
- }
332
- /**
333
- * Configures that the position strategy should set a `transform-origin` on some elements
334
- * inside the overlay, depending on the current position that is being applied. This is
335
- * useful for the cases where the origin of an animation can change depending on the
336
- * alignment of the overlay.
337
- * @param selector CSS selector that will be used to find the target
338
- * elements onto which to set the transform origin.
339
- */
340
- withTransformOriginOn(selector) {
341
- this._transformOriginSelector = selector;
342
- return this;
343
- }
344
- /**
345
- * Gets the (x, y) coordinate of a connection point on the origin based on a relative position.
346
- */
347
- _getOriginPoint(originRect, pos) {
348
- let x;
349
- if (pos.originX == 'center') {
350
- // Note: when centering we should always use the `left`
351
- // offset, otherwise the position will be wrong in RTL.
352
- x = originRect.left + (originRect.width / 2);
353
- }
354
- else {
355
- const startX = this._isRtl() ? originRect.right : originRect.left;
356
- const endX = this._isRtl() ? originRect.left : originRect.right;
357
- x = pos.originX == 'start' ? startX : endX;
358
- }
359
- let y;
360
- if (pos.originY == 'center') {
361
- y = originRect.top + (originRect.height / 2);
362
- }
363
- else {
364
- y = pos.originY == 'top' ? originRect.top : originRect.bottom;
365
- }
366
- return { x, y };
367
- }
368
- /**
369
- * Gets the (x, y) coordinate of the top-left corner of the overlay given a given position and
370
- * origin point to which the overlay should be connected.
371
- */
372
- _getOverlayPoint(originPoint, overlayRect, pos) {
373
- // Calculate the (overlayStartX, overlayStartY), the start of the
374
- // potential overlay position relative to the origin point.
375
- let overlayStartX;
376
- if (pos.overlayX == 'center') {
377
- overlayStartX = -overlayRect.width / 2;
378
- }
379
- else if (pos.overlayX === 'start') {
380
- overlayStartX = this._isRtl() ? -overlayRect.width : 0;
381
- }
382
- else {
383
- overlayStartX = this._isRtl() ? 0 : -overlayRect.width;
384
- }
385
- let overlayStartY;
386
- if (pos.overlayY == 'center') {
387
- overlayStartY = -overlayRect.height / 2;
388
- }
389
- else {
390
- overlayStartY = pos.overlayY == 'top' ? 0 : -overlayRect.height;
391
- }
392
- // The (x, y) coordinates of the overlay.
393
- return {
394
- x: originPoint.x + overlayStartX,
395
- y: originPoint.y + overlayStartY,
396
- };
397
- }
398
- /** Gets how well an overlay at the given point will fit within the viewport. */
399
- _getOverlayFit(point, rawOverlayRect, viewport, position) {
400
- // Round the overlay rect when comparing against the
401
- // viewport, because the viewport is always rounded.
402
- const overlay = getRoundedBoundingClientRect(rawOverlayRect);
403
- let { x, y } = point;
404
- let offsetX = this._getOffset(position, 'x');
405
- let offsetY = this._getOffset(position, 'y');
406
- // Account for the offsets since they could push the overlay out of the viewport.
407
- if (offsetX) {
408
- x += offsetX;
409
- }
410
- if (offsetY) {
411
- y += offsetY;
412
- }
413
- // How much the overlay would overflow at this position, on each side.
414
- let leftOverflow = 0 - x;
415
- let rightOverflow = (x + overlay.width) - viewport.width;
416
- let topOverflow = 0 - y;
417
- let bottomOverflow = (y + overlay.height) - viewport.height;
418
- // Visible parts of the element on each axis.
419
- let visibleWidth = this._subtractOverflows(overlay.width, leftOverflow, rightOverflow);
420
- let visibleHeight = this._subtractOverflows(overlay.height, topOverflow, bottomOverflow);
421
- let visibleArea = visibleWidth * visibleHeight;
422
- return {
423
- visibleArea,
424
- isCompletelyWithinViewport: (overlay.width * overlay.height) === visibleArea,
425
- fitsInViewportVertically: visibleHeight === overlay.height,
426
- fitsInViewportHorizontally: visibleWidth == overlay.width,
427
- };
428
- }
429
- /**
430
- * Whether the overlay can fit within the viewport when it may resize either its width or height.
431
- * @param fit How well the overlay fits in the viewport at some position.
432
- * @param point The (x, y) coordinates of the overlat at some position.
433
- * @param viewport The geometry of the viewport.
434
- */
435
- _canFitWithFlexibleDimensions(fit, point, viewport) {
436
- if (this._hasFlexibleDimensions) {
437
- const availableHeight = viewport.bottom - point.y;
438
- const availableWidth = viewport.right - point.x;
439
- const minHeight = getPixelValue(this._overlayRef.getConfig().minHeight);
440
- const minWidth = getPixelValue(this._overlayRef.getConfig().minWidth);
441
- const verticalFit = fit.fitsInViewportVertically ||
442
- (minHeight != null && minHeight <= availableHeight);
443
- const horizontalFit = fit.fitsInViewportHorizontally ||
444
- (minWidth != null && minWidth <= availableWidth);
445
- return verticalFit && horizontalFit;
446
- }
447
- return false;
448
- }
449
- /**
450
- * Gets the point at which the overlay can be "pushed" on-screen. If the overlay is larger than
451
- * the viewport, the top-left corner will be pushed on-screen (with overflow occuring on the
452
- * right and bottom).
453
- *
454
- * @param start Starting point from which the overlay is pushed.
455
- * @param overlay Dimensions of the overlay.
456
- * @param scrollPosition Current viewport scroll position.
457
- * @returns The point at which to position the overlay after pushing. This is effectively a new
458
- * originPoint.
459
- */
460
- _pushOverlayOnScreen(start, rawOverlayRect, scrollPosition) {
461
- // If the position is locked and we've pushed the overlay already, reuse the previous push
462
- // amount, rather than pushing it again. If we were to continue pushing, the element would
463
- // remain in the viewport, which goes against the expectations when position locking is enabled.
464
- if (this._previousPushAmount && this._positionLocked) {
465
- return {
466
- x: start.x + this._previousPushAmount.x,
467
- y: start.y + this._previousPushAmount.y
468
- };
469
- }
470
- // Round the overlay rect when comparing against the
471
- // viewport, because the viewport is always rounded.
472
- const overlay = getRoundedBoundingClientRect(rawOverlayRect);
473
- const viewport = this._viewportRect;
474
- // Determine how much the overlay goes outside the viewport on each
475
- // side, which we'll use to decide which direction to push it.
476
- const overflowRight = Math.max(start.x + overlay.width - viewport.width, 0);
477
- const overflowBottom = Math.max(start.y + overlay.height - viewport.height, 0);
478
- const overflowTop = Math.max(viewport.top - scrollPosition.top - start.y, 0);
479
- const overflowLeft = Math.max(viewport.left - scrollPosition.left - start.x, 0);
480
- // Amount by which to push the overlay in each axis such that it remains on-screen.
481
- let pushX = 0;
482
- let pushY = 0;
483
- // If the overlay fits completely within the bounds of the viewport, push it from whichever
484
- // direction is goes off-screen. Otherwise, push the top-left corner such that its in the
485
- // viewport and allow for the trailing end of the overlay to go out of bounds.
486
- if (overlay.width <= viewport.width) {
487
- pushX = overflowLeft || -overflowRight;
488
- }
489
- else {
490
- pushX = start.x < this._viewportMargin ? (viewport.left - scrollPosition.left) - start.x : 0;
491
- }
492
- if (overlay.height <= viewport.height) {
493
- pushY = overflowTop || -overflowBottom;
494
- }
495
- else {
496
- pushY = start.y < this._viewportMargin ? (viewport.top - scrollPosition.top) - start.y : 0;
497
- }
498
- this._previousPushAmount = { x: pushX, y: pushY };
499
- return {
500
- x: start.x + pushX,
501
- y: start.y + pushY,
502
- };
503
- }
504
- /**
505
- * Applies a computed position to the overlay and emits a position change.
506
- * @param position The position preference
507
- * @param originPoint The point on the origin element where the overlay is connected.
508
- */
509
- _applyPosition(position, originPoint) {
510
- this._setTransformOrigin(position);
511
- this._setOverlayElementStyles(originPoint, position);
512
- this._setBoundingBoxStyles(originPoint, position);
513
- if (position.panelClass) {
514
- this._addPanelClasses(position.panelClass);
515
- }
516
- // Save the last connected position in case the position needs to be re-calculated.
517
- this._lastPosition = position;
518
- // Notify that the position has been changed along with its change properties.
519
- // We only emit if we've got any subscriptions, because the scroll visibility
520
- // calculcations can be somewhat expensive.
521
- if (this._positionChanges.observers.length) {
522
- const scrollableViewProperties = this._getScrollVisibility();
523
- const changeEvent = new ConnectedOverlayPositionChange(position, scrollableViewProperties);
524
- this._positionChanges.next(changeEvent);
525
- }
526
- this._isInitialRender = false;
527
- }
528
- /** Sets the transform origin based on the configured selector and the passed-in position. */
529
- _setTransformOrigin(position) {
530
- if (!this._transformOriginSelector) {
531
- return;
532
- }
533
- const elements = this._boundingBox.querySelectorAll(this._transformOriginSelector);
534
- let xOrigin;
535
- let yOrigin = position.overlayY;
536
- if (position.overlayX === 'center') {
537
- xOrigin = 'center';
538
- }
539
- else if (this._isRtl()) {
540
- xOrigin = position.overlayX === 'start' ? 'right' : 'left';
541
- }
542
- else {
543
- xOrigin = position.overlayX === 'start' ? 'left' : 'right';
544
- }
545
- for (let i = 0; i < elements.length; i++) {
546
- elements[i].style.transformOrigin = `${xOrigin} ${yOrigin}`;
547
- }
548
- }
549
- /**
550
- * Gets the position and size of the overlay's sizing container.
551
- *
552
- * This method does no measuring and applies no styles so that we can cheaply compute the
553
- * bounds for all positions and choose the best fit based on these results.
554
- */
555
- _calculateBoundingBoxRect(origin, position) {
556
- const viewport = this._viewportRect;
557
- const isRtl = this._isRtl();
558
- let height, top, bottom;
559
- if (position.overlayY === 'top') {
560
- // Overlay is opening "downward" and thus is bound by the bottom viewport edge.
561
- top = origin.y;
562
- height = viewport.height - top + this._viewportMargin;
563
- }
564
- else if (position.overlayY === 'bottom') {
565
- // Overlay is opening "upward" and thus is bound by the top viewport edge. We need to add
566
- // the viewport margin back in, because the viewport rect is narrowed down to remove the
567
- // margin, whereas the `origin` position is calculated based on its `ClientRect`.
568
- bottom = viewport.height - origin.y + this._viewportMargin * 2;
569
- height = viewport.height - bottom + this._viewportMargin;
570
- }
571
- else {
572
- // If neither top nor bottom, it means that the overlay is vertically centered on the
573
- // origin point. Note that we want the position relative to the viewport, rather than
574
- // the page, which is why we don't use something like `viewport.bottom - origin.y` and
575
- // `origin.y - viewport.top`.
576
- const smallestDistanceToViewportEdge = Math.min(viewport.bottom - origin.y + viewport.top, origin.y);
577
- const previousHeight = this._lastBoundingBoxSize.height;
578
- height = smallestDistanceToViewportEdge * 2;
579
- top = origin.y - smallestDistanceToViewportEdge;
580
- if (height > previousHeight && !this._isInitialRender && !this._growAfterOpen) {
581
- top = origin.y - (previousHeight / 2);
582
- }
583
- }
584
- // The overlay is opening 'right-ward' (the content flows to the right).
585
- const isBoundedByRightViewportEdge = (position.overlayX === 'start' && !isRtl) ||
586
- (position.overlayX === 'end' && isRtl);
587
- // The overlay is opening 'left-ward' (the content flows to the left).
588
- const isBoundedByLeftViewportEdge = (position.overlayX === 'end' && !isRtl) ||
589
- (position.overlayX === 'start' && isRtl);
590
- let width, left, right;
591
- if (isBoundedByLeftViewportEdge) {
592
- right = viewport.width - origin.x + this._viewportMargin;
593
- width = origin.x - this._viewportMargin;
594
- }
595
- else if (isBoundedByRightViewportEdge) {
596
- left = origin.x;
597
- width = viewport.right - origin.x;
598
- }
599
- else {
600
- // If neither start nor end, it means that the overlay is horizontally centered on the
601
- // origin point. Note that we want the position relative to the viewport, rather than
602
- // the page, which is why we don't use something like `viewport.right - origin.x` and
603
- // `origin.x - viewport.left`.
604
- const smallestDistanceToViewportEdge = Math.min(viewport.right - origin.x + viewport.left, origin.x);
605
- const previousWidth = this._lastBoundingBoxSize.width;
606
- width = smallestDistanceToViewportEdge * 2;
607
- left = origin.x - smallestDistanceToViewportEdge;
608
- if (width > previousWidth && !this._isInitialRender && !this._growAfterOpen) {
609
- left = origin.x - (previousWidth / 2);
610
- }
611
- }
612
- return { top: top, left: left, bottom: bottom, right: right, width, height };
613
- }
614
- /**
615
- * Sets the position and size of the overlay's sizing wrapper. The wrapper is positioned on the
616
- * origin's connection point and stetches to the bounds of the viewport.
617
- *
618
- * @param origin The point on the origin element where the overlay is connected.
619
- * @param position The position preference
620
- */
621
- _setBoundingBoxStyles(origin, position) {
622
- const boundingBoxRect = this._calculateBoundingBoxRect(origin, position);
623
- // It's weird if the overlay *grows* while scrolling, so we take the last size into account
624
- // when applying a new size.
625
- if (!this._isInitialRender && !this._growAfterOpen) {
626
- boundingBoxRect.height = Math.min(boundingBoxRect.height, this._lastBoundingBoxSize.height);
627
- boundingBoxRect.width = Math.min(boundingBoxRect.width, this._lastBoundingBoxSize.width);
628
- }
629
- const styles = {};
630
- if (this._hasExactPosition()) {
631
- styles.top = styles.left = '0';
632
- styles.bottom = styles.right = styles.maxHeight = styles.maxWidth = '';
633
- styles.width = styles.height = '100%';
634
- }
635
- else {
636
- const maxHeight = this._overlayRef.getConfig().maxHeight;
637
- const maxWidth = this._overlayRef.getConfig().maxWidth;
638
- styles.height = coerceCssPixelValue(boundingBoxRect.height);
639
- styles.top = coerceCssPixelValue(boundingBoxRect.top);
640
- styles.bottom = coerceCssPixelValue(boundingBoxRect.bottom);
641
- styles.width = coerceCssPixelValue(boundingBoxRect.width);
642
- styles.left = coerceCssPixelValue(boundingBoxRect.left);
643
- styles.right = coerceCssPixelValue(boundingBoxRect.right);
644
- // Push the pane content towards the proper direction.
645
- if (position.overlayX === 'center') {
646
- styles.alignItems = 'center';
647
- }
648
- else {
649
- styles.alignItems = position.overlayX === 'end' ? 'flex-end' : 'flex-start';
650
- }
651
- if (position.overlayY === 'center') {
652
- styles.justifyContent = 'center';
653
- }
654
- else {
655
- styles.justifyContent = position.overlayY === 'bottom' ? 'flex-end' : 'flex-start';
656
- }
657
- if (maxHeight) {
658
- styles.maxHeight = coerceCssPixelValue(maxHeight);
659
- }
660
- if (maxWidth) {
661
- styles.maxWidth = coerceCssPixelValue(maxWidth);
662
- }
663
- }
664
- this._lastBoundingBoxSize = boundingBoxRect;
665
- extendStyles(this._boundingBox.style, styles);
666
- }
667
- /** Resets the styles for the bounding box so that a new positioning can be computed. */
668
- _resetBoundingBoxStyles() {
669
- extendStyles(this._boundingBox.style, {
670
- top: '0',
671
- left: '0',
672
- right: '0',
673
- bottom: '0',
674
- height: '',
675
- width: '',
676
- alignItems: '',
677
- justifyContent: '',
678
- });
679
- }
680
- /** Resets the styles for the overlay pane so that a new positioning can be computed. */
681
- _resetOverlayElementStyles() {
682
- extendStyles(this._pane.style, {
683
- top: '',
684
- left: '',
685
- bottom: '',
686
- right: '',
687
- position: '',
688
- transform: '',
689
- });
690
- }
691
- /** Sets positioning styles to the overlay element. */
692
- _setOverlayElementStyles(originPoint, position) {
693
- const styles = {};
694
- const hasExactPosition = this._hasExactPosition();
695
- const hasFlexibleDimensions = this._hasFlexibleDimensions;
696
- const config = this._overlayRef.getConfig();
697
- if (hasExactPosition) {
698
- const scrollPosition = this._viewportRuler.getViewportScrollPosition();
699
- extendStyles(styles, this._getExactOverlayY(position, originPoint, scrollPosition));
700
- extendStyles(styles, this._getExactOverlayX(position, originPoint, scrollPosition));
701
- }
702
- else {
703
- styles.position = 'static';
704
- }
705
- // Use a transform to apply the offsets. We do this because the `center` positions rely on
706
- // being in the normal flex flow and setting a `top` / `left` at all will completely throw
707
- // off the position. We also can't use margins, because they won't have an effect in some
708
- // cases where the element doesn't have anything to "push off of". Finally, this works
709
- // better both with flexible and non-flexible positioning.
710
- let transformString = '';
711
- let offsetX = this._getOffset(position, 'x');
712
- let offsetY = this._getOffset(position, 'y');
713
- if (offsetX) {
714
- transformString += `translateX(${offsetX}px) `;
715
- }
716
- if (offsetY) {
717
- transformString += `translateY(${offsetY}px)`;
718
- }
719
- styles.transform = transformString.trim();
720
- // If a maxWidth or maxHeight is specified on the overlay, we remove them. We do this because
721
- // we need these values to both be set to "100%" for the automatic flexible sizing to work.
722
- // The maxHeight and maxWidth are set on the boundingBox in order to enforce the constraint.
723
- // Note that this doesn't apply when we have an exact position, in which case we do want to
724
- // apply them because they'll be cleared from the bounding box.
725
- if (config.maxHeight) {
726
- if (hasExactPosition) {
727
- styles.maxHeight = coerceCssPixelValue(config.maxHeight);
728
- }
729
- else if (hasFlexibleDimensions) {
730
- styles.maxHeight = '';
731
- }
732
- }
733
- if (config.maxWidth) {
734
- if (hasExactPosition) {
735
- styles.maxWidth = coerceCssPixelValue(config.maxWidth);
736
- }
737
- else if (hasFlexibleDimensions) {
738
- styles.maxWidth = '';
739
- }
740
- }
741
- extendStyles(this._pane.style, styles);
742
- }
743
- /** Gets the exact top/bottom for the overlay when not using flexible sizing or when pushing. */
744
- _getExactOverlayY(position, originPoint, scrollPosition) {
745
- // Reset any existing styles. This is necessary in case the
746
- // preferred position has changed since the last `apply`.
747
- let styles = { top: '', bottom: '' };
748
- let overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);
749
- if (this._isPushed) {
750
- overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);
751
- }
752
- let virtualKeyboardOffset = this._overlayContainer.getContainerElement().getBoundingClientRect().top;
753
- // Normally this would be zero, however when the overlay is attached to an input (e.g. in an
754
- // autocomplete), mobile browsers will shift everything in order to put the input in the middle
755
- // of the screen and to make space for the virtual keyboard. We need to account for this offset,
756
- // otherwise our positioning will be thrown off.
757
- overlayPoint.y -= virtualKeyboardOffset;
758
- // We want to set either `top` or `bottom` based on whether the overlay wants to appear
759
- // above or below the origin and the direction in which the element will expand.
760
- if (position.overlayY === 'bottom') {
761
- // When using `bottom`, we adjust the y position such that it is the distance
762
- // from the bottom of the viewport rather than the top.
763
- const documentHeight = this._document.documentElement.clientHeight;
764
- styles.bottom = `${documentHeight - (overlayPoint.y + this._overlayRect.height)}px`;
765
- }
766
- else {
767
- styles.top = coerceCssPixelValue(overlayPoint.y);
768
- }
769
- return styles;
770
- }
771
- /** Gets the exact left/right for the overlay when not using flexible sizing or when pushing. */
772
- _getExactOverlayX(position, originPoint, scrollPosition) {
773
- // Reset any existing styles. This is necessary in case the preferred position has
774
- // changed since the last `apply`.
775
- let styles = { left: '', right: '' };
776
- let overlayPoint = this._getOverlayPoint(originPoint, this._overlayRect, position);
777
- if (this._isPushed) {
778
- overlayPoint = this._pushOverlayOnScreen(overlayPoint, this._overlayRect, scrollPosition);
779
- }
780
- // We want to set either `left` or `right` based on whether the overlay wants to appear "before"
781
- // or "after" the origin, which determines the direction in which the element will expand.
782
- // For the horizontal axis, the meaning of "before" and "after" change based on whether the
783
- // page is in RTL or LTR.
784
- let horizontalStyleProperty;
785
- if (this._isRtl()) {
786
- horizontalStyleProperty = position.overlayX === 'end' ? 'left' : 'right';
787
- }
788
- else {
789
- horizontalStyleProperty = position.overlayX === 'end' ? 'right' : 'left';
790
- }
791
- // When we're setting `right`, we adjust the x position such that it is the distance
792
- // from the right edge of the viewport rather than the left edge.
793
- if (horizontalStyleProperty === 'right') {
794
- const documentWidth = this._document.documentElement.clientWidth;
795
- styles.right = `${documentWidth - (overlayPoint.x + this._overlayRect.width)}px`;
796
- }
797
- else {
798
- styles.left = coerceCssPixelValue(overlayPoint.x);
799
- }
800
- return styles;
801
- }
802
- /**
803
- * Gets the view properties of the trigger and overlay, including whether they are clipped
804
- * or completely outside the view of any of the strategy's scrollables.
805
- */
806
- _getScrollVisibility() {
807
- // Note: needs fresh rects since the position could've changed.
808
- const originBounds = this._getOriginRect();
809
- const overlayBounds = this._pane.getBoundingClientRect();
810
- // TODO(jelbourn): instead of needing all of the client rects for these scrolling containers
811
- // every time, we should be able to use the scrollTop of the containers if the size of those
812
- // containers hasn't changed.
813
- const scrollContainerBounds = this._scrollables.map(scrollable => {
814
- return scrollable.getElementRef().nativeElement.getBoundingClientRect();
815
- });
816
- return {
817
- isOriginClipped: isElementClippedByScrolling(originBounds, scrollContainerBounds),
818
- isOriginOutsideView: isElementScrolledOutsideView(originBounds, scrollContainerBounds),
819
- isOverlayClipped: isElementClippedByScrolling(overlayBounds, scrollContainerBounds),
820
- isOverlayOutsideView: isElementScrolledOutsideView(overlayBounds, scrollContainerBounds),
821
- };
822
- }
823
- /** Subtracts the amount that an element is overflowing on an axis from its length. */
824
- _subtractOverflows(length, ...overflows) {
825
- return overflows.reduce((currentValue, currentOverflow) => {
826
- return currentValue - Math.max(currentOverflow, 0);
827
- }, length);
828
- }
829
- /** Narrows the given viewport rect by the current _viewportMargin. */
830
- _getNarrowedViewportRect() {
831
- // We recalculate the viewport rect here ourselves, rather than using the ViewportRuler,
832
- // because we want to use the `clientWidth` and `clientHeight` as the base. The difference
833
- // being that the client properties don't include the scrollbar, as opposed to `innerWidth`
834
- // and `innerHeight` that do. This is necessary, because the overlay container uses
835
- // 100% `width` and `height` which don't include the scrollbar either.
836
- const width = this._document.documentElement.clientWidth;
837
- const height = this._document.documentElement.clientHeight;
838
- const scrollPosition = this._viewportRuler.getViewportScrollPosition();
839
- return {
840
- top: scrollPosition.top + this._viewportMargin,
841
- left: scrollPosition.left + this._viewportMargin,
842
- right: scrollPosition.left + width - this._viewportMargin,
843
- bottom: scrollPosition.top + height - this._viewportMargin,
844
- width: width - (2 * this._viewportMargin),
845
- height: height - (2 * this._viewportMargin),
846
- };
847
- }
848
- /** Whether the we're dealing with an RTL context */
849
- _isRtl() {
850
- return this._overlayRef.getDirection() === 'rtl';
851
- }
852
- /** Determines whether the overlay uses exact or flexible positioning. */
853
- _hasExactPosition() {
854
- return !this._hasFlexibleDimensions || this._isPushed;
855
- }
856
- /** Retrieves the offset of a position along the x or y axis. */
857
- _getOffset(position, axis) {
858
- if (axis === 'x') {
859
- // We don't do something like `position['offset' + axis]` in
860
- // order to avoid breking minifiers that rename properties.
861
- return position.offsetX == null ? this._offsetX : position.offsetX;
862
- }
863
- return position.offsetY == null ? this._offsetY : position.offsetY;
864
- }
865
- /** Validates that the current position match the expected values. */
866
- _validatePositions() {
867
- if (typeof ngDevMode === 'undefined' || ngDevMode) {
868
- if (!this._preferredPositions.length) {
869
- throw Error('FlexibleConnectedPositionStrategy: At least one position is required.');
870
- }
871
- // TODO(crisbeto): remove these once Angular's template type
872
- // checking is advanced enough to catch these cases.
873
- this._preferredPositions.forEach(pair => {
874
- validateHorizontalPosition('originX', pair.originX);
875
- validateVerticalPosition('originY', pair.originY);
876
- validateHorizontalPosition('overlayX', pair.overlayX);
877
- validateVerticalPosition('overlayY', pair.overlayY);
878
- });
879
- }
880
- }
881
- /** Adds a single CSS class or an array of classes on the overlay panel. */
882
- _addPanelClasses(cssClasses) {
883
- if (this._pane) {
884
- coerceArray(cssClasses).forEach(cssClass => {
885
- if (cssClass !== '' && this._appliedPanelClasses.indexOf(cssClass) === -1) {
886
- this._appliedPanelClasses.push(cssClass);
887
- this._pane.classList.add(cssClass);
888
- }
889
- });
890
- }
891
- }
892
- /** Clears the classes that the position strategy has applied from the overlay panel. */
893
- _clearPanelClasses() {
894
- if (this._pane) {
895
- this._appliedPanelClasses.forEach(cssClass => {
896
- this._pane.classList.remove(cssClass);
897
- });
898
- this._appliedPanelClasses = [];
899
- }
900
- }
901
- /** Returns the ClientRect of the current origin. */
902
- _getOriginRect() {
903
- const origin = this._origin;
904
- if (origin instanceof ElementRef) {
905
- return origin.nativeElement.getBoundingClientRect();
906
- }
907
- // Check for Element so SVG elements are also supported.
908
- if (origin instanceof Element) {
909
- return origin.getBoundingClientRect();
910
- }
911
- const width = origin.width || 0;
912
- const height = origin.height || 0;
913
- // If the origin is a point, return a client rect as if it was a 0x0 element at the point.
914
- return {
915
- top: origin.y,
916
- bottom: origin.y + height,
917
- left: origin.x,
918
- right: origin.x + width,
919
- height,
920
- width
921
- };
922
- }
923
- }
924
- /** Shallow-extends a stylesheet object with another stylesheet object. */
925
- function extendStyles(destination, source) {
926
- for (let key in source) {
927
- if (source.hasOwnProperty(key)) {
928
- destination[key] = source[key];
929
- }
930
- }
931
- return destination;
932
- }
933
- /**
934
- * Extracts the pixel value as a number from a value, if it's a number
935
- * or a CSS pixel string (e.g. `1337px`). Otherwise returns null.
936
- */
937
- function getPixelValue(input) {
938
- if (typeof input !== 'number' && input != null) {
939
- const [value, units] = input.split(cssUnitPattern);
940
- return (!units || units === 'px') ? parseFloat(value) : null;
941
- }
942
- return input || null;
943
- }
944
- /**
945
- * Gets a version of an element's bounding `ClientRect` where all the values are rounded down to
946
- * the nearest pixel. This allows us to account for the cases where there may be sub-pixel
947
- * deviations in the `ClientRect` returned by the browser (e.g. when zoomed in with a percentage
948
- * size, see #21350).
949
- */
950
- function getRoundedBoundingClientRect(clientRect) {
951
- return {
952
- top: Math.floor(clientRect.top),
953
- right: Math.floor(clientRect.right),
954
- bottom: Math.floor(clientRect.bottom),
955
- left: Math.floor(clientRect.left),
956
- width: Math.floor(clientRect.width),
957
- height: Math.floor(clientRect.height)
958
- };
959
- }
960
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZmxleGlibGUtY29ubmVjdGVkLXBvc2l0aW9uLXN0cmF0ZWd5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vc3JjL2Nkay9vdmVybGF5L3Bvc2l0aW9uL2ZsZXhpYmxlLWNvbm5lY3RlZC1wb3NpdGlvbi1zdHJhdGVneS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFHSCxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sZUFBZSxDQUFDO0FBRXpDLE9BQU8sRUFDTCw4QkFBOEIsRUFHOUIsMEJBQTBCLEVBQzFCLHdCQUF3QixHQUN6QixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBYSxZQUFZLEVBQUUsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBRXZELE9BQU8sRUFBQyw0QkFBNEIsRUFBRSwyQkFBMkIsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUN4RixPQUFPLEVBQUMsbUJBQW1CLEVBQUUsV0FBVyxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFJdkUscUZBQXFGO0FBQ3JGLDZGQUE2RjtBQUU3RixxREFBcUQ7QUFDckQsTUFBTSxnQkFBZ0IsR0FBRyw2Q0FBNkMsQ0FBQztBQUV2RSxxREFBcUQ7QUFDckQsTUFBTSxjQUFjLEdBQUcsZUFBZSxDQUFDO0FBUXZDOzs7Ozs7R0FNRztBQUNILE1BQU0sT0FBTyxpQ0FBaUM7SUEwRjVDLFlBQ0ksV0FBb0QsRUFBVSxjQUE2QixFQUNuRixTQUFtQixFQUFVLFNBQW1CLEVBQ2hELGlCQUFtQztRQUZtQixtQkFBYyxHQUFkLGNBQWMsQ0FBZTtRQUNuRixjQUFTLEdBQVQsU0FBUyxDQUFVO1FBQVUsY0FBUyxHQUFULFNBQVMsQ0FBVTtRQUNoRCxzQkFBaUIsR0FBakIsaUJBQWlCLENBQWtCO1FBdEYvQywwRkFBMEY7UUFDbEYseUJBQW9CLEdBQUcsRUFBQyxLQUFLLEVBQUUsQ0FBQyxFQUFFLE1BQU0sRUFBRSxDQUFDLEVBQUMsQ0FB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QUFDLE1BQU0sR0FBRyxNQUFNLENBQUMsS0FBSyxHQUFHLE1BQU0sQ0FBQyxTQUFTLEdBQUcsTUFBTSxDQUFDLFFBQVEsR0FBRyxFQUFFLENBQUM7WUFDdkUsTUFBTSxDQUFDLEtBQUssR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztTQUN2QzthQUFNO1lBQ0wsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxTQUFTLENBQUM7WUFDekQsTUFBTSxRQUFRLEdBQUcsSUFBSSxDQUFDLFdBQVcsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxRQUFRLENBQUM7WUFFdkQsTUFBTSxDQUFDLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUQsTUFBTSxDQUFDLEdBQUcsR0FBRyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEQsTUFBTSxDQUFDLE1BQU0sR0FBRyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDNUQsTUFBTSxDQUFDLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDMUQsTUFBTSxDQUFDLElBQUksR0FBRyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7WUFDeEQsTUFBTSxDQUFDLEtBQUssR0FBRyxtQkFBbUIsQ0FBQyxlQUFlLENBQUMsS0FBSyxDQUFDLENBQUM7WUFFMUQsc0RBQXNEO1lBQ3RELElBQUksUUFBUSxDQUFDLFFBQVEsS0FBSyxRQUFRLEVBQUU7Z0JBQ2xDLE1BQU0sQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDO2FBQzlCO2lCQUFNO2dCQUNMLE1BQU0sQ0FBQyxVQUFVLEdBQUcsUUFBUSxDQUFDLFFBQVEsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDO2FBQzdFO1lBRUQsSUFBSSxRQUFRLENBQUMsUUFBUSxLQUFLLFFBQVEs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QUFXLENBQUM7QUFDckIsQ0FBQztBQUdEOzs7R0FHRztBQUNILFNBQVMsYUFBYSxDQUFDLEtBQW1DO0lBQ3hELElBQUksT0FBTyxLQUFLLEtBQUssUUFBUSxJQUFJLEtBQUssSUFBSSxJQUFJLEVBQUU7UUFDOUMsTUFBTSxDQUFDLEtBQUssRUFBRSxLQUFLLENBQUMsR0FBRyxLQUFLLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxDQUFDO1FBQ25ELE9BQU8sQ0FBQyxDQUFDLEtBQUssSUFBSSxLQUFLLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0tBQzlEO0lBRUQsT0FBTyxLQUFLLElBQUksSUFBSSxDQUFDO0FBQ3ZCLENBQUM7QUFFRDs7Ozs7R0FLRztBQUNILFNBQVMsNEJBQTRCLENBQUMsVUFBc0I7SUFDMUQsT0FBTztRQUNMLEdBQUcsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUM7UUFDL0IsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQztRQUNuQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDO1FBQ3JDLElBQUksRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUM7UUFDakMsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQztRQUNuQyxNQUFNLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsTUFBTSxDQUFDO0tBQ3RDLENBQUM7QUFDSixDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7UG9zaXRpb25TdHJhdGVneX0gZnJvbSAnLi9wb3NpdGlvbi1zdHJhdGVneSc7XG5pbXBvcnQge0VsZW1lbnRSZWZ9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtWaWV3cG9ydFJ1bGVyLCBDZGtTY3JvbGxhYmxlLCBWaWV3cG9ydFNjcm9sbFBvc2l0aW9ufSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7XG4gIENvbm5lY3RlZE92ZXJsYXlQb3NpdGlvbkNoYW5nZSxcbiAgQ29ubmVjdGlvblBvc2l0aW9uUGFpcixcbiAgU2Nyb2xsaW5nVmlzaWJpbGl0eSxcbiAgdmFsaWRhdGVIb3Jpem9udGFsUG9zaXRpb24sXG4gIHZhbGlkYXRlVmVydGljYWxQb3NpdGlvbixcbn0gZnJvbSAnLi9jb25uZWN0ZWQtcG9zaXRpb24nO1xuaW1wb3J0IHtPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24sIFN1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtPdmVybGF5UmVmZXJlbmNlfSBmcm9tICcuLi9vdmVybGF5LXJlZmVyZW5jZSc7XG5pbXBvcnQge2lzRWxlbWVudFNjcm9sbGVkT3V0c2lkZVZpZXcsIGlzRWxlbWVudENsaXBwZWRCeVNjcm9sbGluZ30gZnJvbSAnLi9zY3JvbGwtY2xpcCc7XG5pbXBvcnQge2NvZXJjZUNzc1BpeGVsVmFsdWUsIGNvZXJjZUFycmF5fSBmcm9tICdAYW5ndWxhci9jZGsvY29lcmNpb24nO1xuaW1wb3J0IHtQbGF0Zm9ybX0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BsYXRmb3JtJztcbmltcG9ydCB7T3ZlcmxheUNvbnRhaW5lcn0gZnJvbSAnLi4vb3ZlcmxheS1jb250YWluZXInO1xuXG4vLyBUT0RPOiByZWZhY3RvciBjbGlwcGluZyBkZXRlY3Rpb24gaW50byBhIHNlcGFyYXRlIHRoaW5nIChwYXJ0IG9mIHNjcm9sbGluZyBtb2R1bGUpXG4vLyBUT0RPOiBkb2Vzbid0IGhhbmRsZSBib3RoIGZsZXhpYmxlIHdpZHRoIGFuZCBoZWlnaHQgd2hlbiBpdCBoYXMgdG8gc2Nyb2xsIGFsb25nIGJvdGggYXhpcy5cblxuLyoqIENsYXNzIHRvIGJlIGFkZGVkIHRvIHRoZSBvdmVybGF5IGJvdW5kaW5nIGJveC4gKi9cbmNvbnN0IGJvdW5kaW5nQm94Q2xhc3MgPSAnY2RrLW92ZXJsYXktY29ubmVjdGVkLXBvc2l0aW9uLWJvdW5kaW5nLWJveCc7XG5cbi8qKiBSZWdleCB1c2VkIHRvIHNwbGl0IGEgc3RyaW5nIG9uIGl0cyBDU1MgdW5pdHMuICovXG5jb25zdCBjc3NVbml0UGF0dGVybiA9IC8oW0EtWmEteiVdKykkLztcblxuLyoqIFBvc3NpYmxlIHZhbHVlcyB0aGF0IGNhbiBiZSBzZXQgYXMgdGhlIG9yaWdpbiBvZiBhIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneS4gKi9cbmV4cG9ydCB0eXBlIEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneU9yaWdpbiA9IEVsZW1lbnRSZWYgfCBFbGVtZW50IHwgUG9pbnQgJiB7XG4gIHdpZHRoPzogbnVtYmVyO1xuICBoZWlnaHQ/OiBudW1iZXI7XG59O1xuXG4vKipcbiAqIEEgc3RyYXRlZ3kgZm9yIHBvc2l0aW9uaW5nIG92ZXJsYXlzLiBVc2luZyB0aGlzIHN0cmF0ZWd5LCBhbiBvdmVybGF5IGlzIGdpdmVuIGFuXG4gKiBpbXBsaWNpdCBwb3NpdGlvbiByZWxhdGl2ZSBzb21lIG9yaWdpbiBlbGVtZW50LiBUaGUgcmVsYXRpdmUgcG9zaXRpb24gaXMgZGVmaW5lZCBpbiB0ZXJtcyBvZlxuICogYSBwb2ludCBvbiB0aGUgb3JpZ2luIGVsZW1lbnQgdGhhdCBpcyBjb25uZWN0ZWQgdG8gYSBwb2ludCBvbiB0aGUgb3ZlcmxheSBlbGVtZW50LiBGb3IgZXhhbXBsZSxcbiAqIGEgYmFzaWMgZHJvcGRvd24gaXMgY29ubmVjdGluZyB0aGUgYm90dG9tLWxlZnQgY29ybmVyIG9mIHRoZSBvcmlnaW4gdG8gdGhlIHRvcC1sZWZ0IGNvcm5lclxuICogb2YgdGhlIG92ZXJsYXkuXG4gKi9cbmV4cG9ydCBjbGFzcyBGbGV4aWJsZUNvbm5lY3RlZFBvc2l0aW9uU3RyYXRlZ3kgaW1wbGVtZW50cyBQb3NpdGlvblN0cmF0ZWd5IHtcbiAgLyoqIFRoZSBvdmVybGF5IHRvIHdoaWNoIHRoaXMgc3RyYXRlZ3kgaXMgYXR0YWNoZWQuICovXG4gIHByaXZhdGUgX292ZXJsYXlSZWY6IE92ZXJsYXlSZWZlcmVuY2U7XG5cbiAgLyoqIFdoZXRoZXIgd2UncmUgcGVyZm9ybWluZyB0aGUgdmVyeSBmaXJzdCBwb3NpdGlvbmluZyBvZiB0aGUgb3ZlcmxheS4gKi9cbiAgcHJpdmF0ZSBfaXNJbml0aWFsUmVuZGVyOiBib29sZWFuO1xuXG4gIC8qKiBMYXN0IHNpemUgdXNlZCBmb3IgdGhlIGJvdW5kaW5nIGJveC4gVXNlZCB0byBhdm9pZCByZXNpemluZyB0aGUgb3ZlcmxheSBhZnRlciBvcGVuLiAqL1xuICBwcml2YXRlIF9sYXN0Qm91bmRpbmdCb3hTaXplID0ge3dpZHRoOiAwLCBoZWlnaHQ6IDB9O1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBvdmVybGF5IHdhcyBwdXNoZWQgaW4gYSBwcmV2aW91cyBwb3NpdGlvbmluZy4gKi9cbiAgcHJpdmF0ZSBfaXNQdXNoZWQgPSBmYWxzZTtcblxuICAvKiogV2hldGhlciB0aGUgb3ZlcmxheSBjYW4gYmUgcHVzaGVkIG9uLXNjcmVlbiBvbiB0aGUgaW5pdGlhbCBvcGVuLiAqL1xuICBwcml2YXRlIF9jYW5QdXNoID0gdHJ1ZTtcblxuICAvKiogV2hldGhlciB0aGUgb3ZlcmxheSBjYW4gZ3JvdyB2aWEgZmxleGlibGUgd2lkdGgvaGVpZ2h0IGFmdGVyIHRoZSBpbml0aWFsIG9wZW4uICovXG4gIHByaXZhdGUgX2dyb3dBZnRlck9wZW4gPSBmYWxzZTtcblxuICAvKiogV2hldGhlciB0aGUgb3ZlcmxheSdzIHdpZHRoIGFuZCBoZWlnaHQgY2FuIGJlIGNvbnN0cmFpbmVkIHRvIGZpdCB3aXRoaW4gdGhlIHZpZXdwb3J0LiAqL1xuICBwcml2YXRlIF9oYXNGbGV4aWJsZURpbWVuc2lvbnMgPSB0cnVlO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBvdmVybGF5IHBvc2l0aW9uIGlzIGxvY2tlZC4gKi9cbiAgcHJpdmF0ZSBfcG9zaXRpb25Mb2NrZWQgPSBmYWxzZTtcblxuICAvKiogQ2FjaGVkIG9yaWdpbiBkaW1lbnNpb25zICovXG4gIHByaXZhdGUgX29yaWdpblJlY3Q6IENsaWVudFJlY3Q7XG5cbiAgLyoqIENhY2hlZCBvdmVybGF5IGRpbWVuc2lvbnMgKi9cbiAgcHJpdmF0ZSBfb3ZlcmxheVJlY3Q6IENsaWVudFJlY3Q7XG5cbiAgLyoqIENhY2hlZCB2aWV3cG9ydCBkaW1lbnNpb25zICovXG4gIHByaXZhdGUgX3ZpZXdwb3J0UmVjdDogQ2xpZW50UmVjdDtcblxuICAvKiogQW1vdW50IG9mIHNwYWNlIHRoYXQgbXVzdCBiZSBtYWludGFpbmVkIGJldHdlZW4gdGhlIG92ZXJsYXkgYW5kIHRoZSBlZGdlIG9mIHRoZSB2aWV3cG9ydC4gKi9cbiAgcHJpdmF0ZSBfdmlld3BvcnRNYXJnaW4gPSAwO1xuXG4gIC8qKiBUaGUgU2Nyb2xsYWJsZSBjb250YWluZXJzIHVzZWQgdG8gY2hlY2sgc2Nyb2xsYWJsZSB2aWV3IHByb3BlcnRpZXMgb24gcG9zaXRpb24gY2hhbmdlLiAqL1xuICBwcml2YXRlIF9zY3JvbGxhYmxlczogQ2RrU2Nyb2xsYWJsZVtdID0gW107XG5cbiAgLyoqIE9yZGVyZWQgbGlzdCBvZiBwcmVmZXJyZWQgcG9zaXRpb25zLCBmcm9tIG1vc3QgdG8gbGVhc3QgZGVzaXJhYmxlLiAqL1xuICBfcHJlZmVycmVkUG9zaXRpb25zOiBDb25uZWN0aW9uUG9zaXRpb25QYWlyW10gPSBbXTtcblxuICAvKiogVGhlIG9yaWdpbiBlbGVtZW50IGFnYWluc3Qgd2hpY2ggdGhlIG92ZXJsYXkgd2lsbCBiZSBwb3NpdGlvbmVkLiAqL1xuICBwcml2YXRlIF9vcmlnaW46IEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneU9yaWdpbjtcblxuICAvKiogVGhlIG92ZXJsYXkgcGFuZSBlbGVtZW50LiAqL1xuICBwcml2YXRlIF9wYW5lOiBIVE1MRWxlbWVudDtcblxuICAvKiogV2hldGhlciB0aGUgc3RyYXRlZ3kgaGFzIGJlZW4gZGlzcG9zZWQgb2YgYWxyZWFkeS4gKi9cbiAgcHJpdmF0ZSBfaXNEaXNwb3NlZDogYm9vbGVhbjtcblxuICAvKipcbiAgICogUGFyZW50IGVsZW1lbnQgZm9yIHRoZSBvdmVybGF5IHBhbmVsIHVzZWQgdG8gY29uc3RyYWluIHRoZSBvdmVybGF5IHBhbmVsJ3Mgc2l6ZSB0byBmaXRcbiAgICogd2l0aGluIHRoZSB2aWV3cG9ydC5cbiAgICovXG4gIHByaXZhdGUgX2JvdW5kaW5nQm94OiBIVE1MRWxlbWVudCB8IG51bGw7XG5cbiAgLyoqIFRoZSBsYXN0IHBvc2l0aW9uIHRvIGhhdmUgYmVlbiBjYWxjdWxhdGVkIGFzIHRoZSBiZXN0IGZpdCBwb3NpdGlvbi4gKi9cbiAgcHJpdmF0ZSBfbGFzdFBvc2l0aW9uOiBDb25uZWN0ZWRQb3NpdGlvbiB8IG51bGw7XG5cbiAgLyoqIFN1YmplY3QgdGhhdCBlbWl0cyB3aGVuZXZlciB0aGUgcG9zaXRpb24gY2hhbmdlcy4gKi9cbiAgcHJpdmF0ZSByZWFkb25seSBfcG9zaXRpb25DaGFuZ2VzID0gbmV3IFN1YmplY3Q8Q29ubmVjdGVkT3ZlcmxheVBvc2l0aW9uQ2hhbmdlPigpO1xuXG4gIC8qKiBTdWJzY3JpcHRpb24gdG8gdmlld3BvcnQgc2l6ZSBjaGFuZ2VzLiAqL1xuICBwcml2YXRlIF9yZXNpemVTdWJzY3JpcHRpb24gPSBTdWJzY3JpcHRpb24uRU1QVFk7XG5cbiAgLyoqIERlZmF1bHQgb2Zmc2V0IGZvciB0aGUgb3ZlcmxheSBhbG9uZyB0aGUgeCBheGlzLiAqL1xuICBwcml2YXRlIF9vZmZzZXRYID0gMDtcblxuICAvKiogRGVmYXVsdCBvZmZzZXQgZm9yIHRoZSBvdmVybGF5IGFsb25nIHRoZSB5IGF4aXMuICovXG4gIHByaXZhdGUgX29mZnNldFkgPSAwO1xuXG4gIC8qKiBTZWxlY3RvciB0byBiZSB1c2VkIHdoZW4gZmluZGluZyB0aGUgZWxlbWVudHMgb24gd2hpY2ggdG8gc2V0IHRoZSB0cmFuc2Zvcm0gb3JpZ2luLiAqL1xuICBwcml2YXRlIF90cmFuc2Zvcm1PcmlnaW5TZWxlY3Rvcjogc3RyaW5nO1xuXG4gIC8qKiBLZWVwcyB0cmFjayBvZiB0aGUgQ1NTIGNsYXNzZXMgdGhhdCB0aGUgcG9zaXRpb24gc3RyYXRlZ3kgaGFzIGFwcGxpZWQgb24gdGhlIG92ZXJsYXkgcGFuZWwuICovXG4gIHByaXZhdGUgX2FwcGxpZWRQYW5lbENsYXNzZXM6IHN0cmluZ1tdID0gW107XG5cbiAgLyoqIEFtb3VudCBieSB3aGljaCB0aGUgb3ZlcmxheSB3YXMgcHVzaGVkIGluIGVhY2ggYXhpcyBkdXJpbmcgdGhlIGxhc3QgdGltZSBpdCB3YXMgcG9zaXRpb25lZC4gKi9cbiAgcHJpdmF0ZSBfcHJldmlvdXNQdXNoQW1vdW50OiB7eDogbnVtYmVyLCB5OiBudW1iZXJ9IHwgbnVsbDtcblxuICAvKiogT2JzZXJ2YWJsZSBzZXF1ZW5jZSBvZiBwb3NpdGlvbiBjaGFuZ2VzLiAqL1xuICBwb3NpdGlvbkNoYW5nZXM6IE9ic2VydmFibGU8Q29ubmVjdGVkT3ZlcmxheVBvc2l0aW9uQ2hhbmdlPiA9IHRoaXMuX3Bvc2l0aW9uQ2hhbmdlcztcblxuICAvKiogT3JkZXJlZCBsaXN0IG9mIHByZWZlcnJlZCBwb3NpdGlvbnMsIGZyb20gbW9zdCB0byBsZWFzdCBkZXNpcmFibGUuICovXG4gIGdldCBwb3NpdGlvbnMoKTogQ29ubmVjdGlvblBvc2l0aW9uUGFpcltdIHtcbiAgICByZXR1cm4gdGhpcy5fcHJlZmVycmVkUG9zaXRpb25zO1xuICB9XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBjb25uZWN0ZWRUbzogRmxleGlibGVDb25uZWN0ZWRQb3NpdGlvblN0cmF0ZWd5T3JpZ2luLCBwcml2YXRlIF92aWV3cG9ydFJ1bGVyOiBWaWV3cG9ydFJ1bGVyLFxuICAgICAgcHJpdmF0ZSBfZG9jdW1lbnQ6IERvY3VtZW50LCBwcml2YXRlIF9wbGF0Zm9ybTogUGxhdGZvcm0sXG4gICAgICBwcml2YXRlIF9vdmVybGF5Q29udGFpbmVyOiBPdmVybGF5Q29udGFpbmVyKSB7XG4gICAgdGhpcy5zZXRPcmlnaW4oY29ubmVjdGVkVG8pO1xuICB9XG5cbiAgLyoqIEF0dGFjaGVzIHRoaXMgcG9zaXRpb24gc3RyYXRlZ3kgdG8gYW4gb3ZlcmxheS4gKi9cbiAgYXR0YWNoKG92ZXJsYXlSZWY6IE92ZXJsYXlSZWZlcmVuY2UpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5fb3ZlcmxheVJlZiAmJiBvdmVybGF5UmVmICE9PSB0aGlzLl9vdmVybGF5UmVmICYmXG4gICAgICAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSkge1xuICAgICAgdGhyb3cgRXJyb3IoJ1RoaXMgcG9zaXRpb24gc3RyYXRlZ3kgaXMgYWxyZWFkeSBhdHRhY2hlZCB0byBhbiBvdmVybGF5Jyk7XG4gICAgfVxuXG4gICAgdGhpcy5fdmFsaWRhdGVQb3NpdGlvbnMoKTtcblxuICAgIG92ZXJsYXlSZWYuaG9zdEVsZW1lbnQuY2xhc3NMaXN0LmFkZChib3VuZGluZ0JveENsYXNzKTtcblxuICAgIHRoaXMuX292ZXJsYXlSZWYgPSBvdmVybGF5UmVmO1xuICAgIHRoaXMuX2JvdW5kaW5nQm94ID0gb3ZlcmxheVJlZi5ob3N0RWxlbWVudDtcbiAgICB0aGlzLl9wYW5lID0gb3ZlcmxheVJlZi5vdmVybGF5RWxlbWVudDtcbiAgICB0aGlzLl9pc0Rpc3Bvc2VkID0gZmFsc2U7XG4gICAgdGhpcy5faXNJbml0aWFsUmVuZGVyID0gdHJ1ZTtcbiAgICB0aGlzLl9sYXN0UG9zaXRpb24gPSBudWxsO1xuICAgIHRoaXMuX3Jlc2l6ZVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX3Jlc2l6ZVN1YnNjcmlwdGlvbiA9IHRoaXMuX3ZpZXdwb3J0UnVsZXIuY2hhbmdlKCkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIC8vIFdoZW4gdGhlIHdpbmRvdyBpcyByZXNpemVkLCB3ZSB3YW50IHRvIHRyaWdnZXIgdGhlIG5leHQgcmVwb3NpdGlvbiBhcyBpZiBpdFxuICAgICAgLy8gd2FzIGFuIGluaXRpYWwgcmVuZGVyLCBpbiBvcmRlciBmb3IgdGhlIHN0cmF0ZWd5IHRvIHBpY2sgYSBuZXcgb3B0aW1hbCBwb3NpdGlvbixcbiAgICAgIC8vIG90aGVyd2lzZSBwb3NpdGlvbiBsb2NraW5nIHdpbGwgY2F1c2UgaXQgdG8gc3RheSBhdCB0aGUgb2xkIG9uZS5cbiAgICAgIHRoaXMuX2lzSW5pdGlhbFJlbmRlciA9IHRydWU7XG4gICAgICB0aGlzLmFwcGx5KCk7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgcG9zaXRpb24gb2YgdGhlIG92ZXJsYXkgZWxlbWVudCwgdXNpbmcgd2hpY2hldmVyIHByZWZlcnJlZCBwb3NpdGlvbiByZWxhdGl2ZVxuICAgKiB0byB0aGUgb3JpZ2luIGJlc3QgZml0cyBvbi1zY3JlZW4uXG4gICAqXG4gICAqIFRoZSBzZWxlY3Rpb24gb2YgYSBwb3NpdGlvbiBnb2VzIGFzIGZvbGxvd3M6XG4gICAqICAtIElmIGFueSBwb3NpdGlvbnMgZml0IGNvbXBsZXRlbHkgd2l0aGluIHRoZSB2aWV3cG9ydCBhcy1pcyxcbiAgICogICAgICBjaG9vc2UgdGhlIGZpcnN0IHBvc2l0aW9uIHRoYXQgZG9lcyBzby5cbiAgICogIC0gSWYgZmxleGlibGUgZGltZW5zaW9ucyBhcmUgZW5hYmxlZCBhbmQgYXQgbGVhc3Qgb25lIHNhdGlmaWVzIHRoZSBnaXZlbiBtaW5pbXVtIHdpZHRoL2hlaWdodCxcbiAgICogICAgICBjaG9vc2UgdGhlIHBvc2l0aW9uIHdpdGggdGhlIGdyZWF0ZXN0IGF2YWlsYWJsZSBzaXplIG1vZGlmaWVkIGJ5IHRoZSBwb3NpdGlvbnMnIHdlaWdodC5cbiAgICogIC0gSWYgcHVzaGluZyBpcyBlbmFibGVkLCB0YWtlIHRoZSBwb3NpdGlvbiB0aGF0IHdlbnQgb2ZmLXNjcmVlbiB0aGUgbGVhc3QgYW5kIHB1c2ggaXRcbiAgICogICAgICBvbi1zY3JlZW4uXG4gICAqICAtIElmIG5vbmUgb2YgdGhlIHByZXZpb3VzIGNyaXRlcmlhIHdlcmUgbWV0LCB1c2UgdGhlIHBvc2l0aW9uIHRoYXQgZ29lcyBvZmYtc2NyZWVuIHRoZSBsZWFzdC5cbiAgICogQGRvY3MtcHJpdmF0ZVxuICAgKi9cbiAgYXBwbHkoKTogdm9pZCB7XG4gICAgLy8gV2Ugc2hvdWxkbid0IGRvIGFueXRoaW5nIGlmIHRoZSBzdHJhdGVneSB3YXMgZGlzcG9zZWQgb3Igd2UncmUgb24gdGhlIHNlcnZlci5cbiAgICBpZiAodGhpcy5faXNEaXNwb3NlZCB8fCAhdGhpcy5fcGxhdGZvcm0uaXNCcm93c2VyKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gSWYgdGhlIHBvc2l0aW9uIGhhcyBiZWVuIGFwcGxpZWQgYWxyZWFkeSAoZS5nLiB3aGVuIHRoZSBvdmVybGF5IHdhcyBvcGVuZWQpIGFuZCB0aGVcbiAgICAvLyBjb25zdW1lciBvcHRlZCBpbnRvIGxvY2tpbmcgaW4gdGhlIHBvc2l0aW9uLCByZS11c2UgdGhlIG9sZCBwb3NpdGlvbiwgaW4gb3JkZXIgdG9cbiAgICAvLyBwcmV2ZW50IHRoZSBvdmVybGF5IGZyb20ganVtcGluZyBhcm91bmQuXG4gICAgaWYgKCF0aGlzLl9pc0luaXRpYWxSZW5kZXIgJiYgdGhpcy5fcG9zaXRpb25Mb2NrZWQgJiYgdGhpcy5fbGFzdFBvc2l0aW9uKSB7XG4gICAgICB0aGlzLnJlYXBwbHlMYXN0UG9zaXRpb24oKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICB0aGlzLl9jbGVhclBhbmVsQ2xhc3NlcygpO1xuICAgIHRoaXMuX3Jlc2V0T3ZlcmxheUVsZW1lbnRTdHlsZXMoKTtcbiAgICB0aGlzLl9yZXNldEJvdW5kaW5nQm94U3R5bGVzKCk7XG5cbiAgICAvLyBXZSBuZWVkIHRoZSBib3VuZGluZyByZWN0cyBmb3IgdGhlIG9yaWdpbiBhbmQgdGhlIG92ZXJsYXkgdG8gZGV0ZXJtaW5lIGhvdyB0byBwb3NpdGlvblxuICAgIC8vIHRoZSBvdmVybGF5IHJlbGF0aXZlIHRvIHRoZSBvcmlnaW4uXG4gICAgLy8gV2UgdXNlIHRoZSB2aWV3cG9ydCByZWN0IHRvIGRldGVybWluZSB3aGV0aGVyIGEgcG9zaXRpb24gd291bGQgZ28gb2ZmLXNjcmVlbi5cbiAgICB0aGlzLl92aWV3cG9ydFJlY3QgPSB0aGlzLl9nZXROYXJyb3dlZFZpZXdwb3J0UmVjdCgpO1xuICAgIHRoaXMuX29yaWdpblJlY3QgPSB0aGlzLl9nZXRPcmlnaW5SZWN0KCk7XG4gICAgdGhpcy5fb3ZlcmxheVJlY3QgPSB0aGlzLl9wYW5lLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgY29uc3Qgb3JpZ2luUmVjdCA9IHRoaXMuX29yaWdpblJlY3Q7XG4gICAgY29uc3Qgb3ZlcmxheVJlY3QgPSB0aGlzLl9vdmVybGF5UmVjdDtcbiAgICBjb25zdCB2aWV3cG9ydFJlY3QgPSB0aGlzLl92aWV3cG9ydFJlY3Q7XG5cbiAgICAvLyBQb3NpdGlvbnMgd2hlcmUgdGhlIG92ZXJsYXkgd2lsbCBmaXQgd2l0aCBmbGV4aWJsZSBkaW1lbnNpb25zLlxuICAgIGNvbnN0IGZsZXhpYmxlRml0czogRmxleGlibGVGaXRbXSA9IFtdO1xuXG4gICAgLy8gRmFsbGJhY2sgaWYgbm9uZSBvZiB0aGUgcHJlZmVycmVkIHBvc2l0aW9ucyBmaXQgd2l0aGluIHRoZSB2aWV3cG9ydC5cbiAgICBsZXQgZmFsbGJhY2s6IEZhbGxiYWNrUG9zaXRpb24gfCB1bmRlZmluZWQ7XG5cbiAgICAvLyBHbyB0aHJvdWdoIGVhY2ggb2YgdGhlIHByZWZlcnJlZCBwb3NpdGlvbnMgbG9va2luZyBmb3IgYSBnb29kIGZpdC5cbiAgICAvLyBJZiBhIGdvb2QgZml0IGlzIGZvdW5kLCBpdCB3aWxsIGJlIGFwcGxpZWQgaW1tZWRpYXRlbHkuXG4gICAgZm9yIChsZXQgcG9zIG9mIHRoaXMuX3ByZWZlcnJlZFBvc2l0aW9ucykge1xuICAgICAgLy8gR2V0IHRoZSBleGFjdCAoeCwgeSkgY29vcmRpbmF0ZSBmb3IgdGhlIHBvaW50LW9mLW9yaWdpbiBvbiB0aGUgb3JpZ2luIGVsZW1lbnQuXG4gICAgICBsZXQgb3JpZ2luUG9pbnQgPSB0aGlzLl9nZXRPcmlnaW5Qb2ludChvcmlnaW5SZWN0LCBwb3MpO1xuXG4gICAgICAvLyBGcm9tIHRoYXQgcG9pbnQtb2Ytb3JpZ2luLCBnZXQgdGhlIGV4YWN0ICh4LCB5KSBjb29yZGluYXRlIGZvciB0aGUgdG9wLWxlZnQgY29ybmVyIG9mIHRoZVxuICAgICAgLy8gb3ZlcmxheSBpbiB0aGlzIHBvc2l0aW9uLiBXZSB1c2UgdGhlIHRvcC1sZWZ0IGNvcm5lciBmb3IgY2FsY3VsYXRpb25zIGFuZCBsYXRlciB0cmFuc2xhdGVcbiAgICAgIC8vIHRoaXMgaW50byBhbiBhcHByb3ByaWF0ZSAodG9wLCBsZWZ0LCBib3R0b20sIHJpZ2h0KSBzdHlsZS5cbiAgICAgIGxldCBvdmVybGF5UG9pbnQgPSB0aGlzLl9nZXRPdmVybGF5UG9pbnQob3JpZ2luUG9pbnQsIG92ZXJsYXlSZWN0LCBwb3MpO1xuXG4gICAgICAvLyBDYWxjdWxhdGUgaG93IHdlbGwgdGhlIG92ZXJsYXkgd291bGQgZml0IGludG8gdGhlIHZpZXdwb3J0IHdpdGggdGhpcyBwb2ludC5cbiAgICAgIGxldCBvdmVybGF5Rml0ID0gdGhpcy5fZ2V0T3ZlcmxheUZpdChvdmVybGF5UG9pbnQsIG92ZXJsYXlSZWN0LCB2aWV3cG9ydFJlY3QsIHBvcyk7XG5cbiAgICAgIC8vIElmIHRoZSBvdmVybGF5LCB3aXRob3V0IGFueSBmdXJ0aGVyIHdvcmssIGZpdHMgaW50byB0aGUgdmlld3BvcnQsIHVzZSB0aGlzIHBvc2l0aW9uLlxuICAgICAgaWYgKG92ZXJsYXlGaXQuaXNDb21wbGV0ZWx5V2l0aGluVmlld3BvcnQpIHtcbiAgICAgICAgdGhpcy5faXNQdXNoZWQgPSBmYWxzZTtcbiAgICAgICAgdGhpcy5fYXBwbHlQb3NpdGlvbihwb3MsIG9yaWdpblBvaW50KTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuXG4gICAgICAvLyBJZiB0aGUgb3ZlcmxheSBoYXMgZmxleGlibGUgZGltZW5zaW9ucywgd2UgY2FuIHVzZSB0aGlzIHBvc2l0aW9uXG4gICAgICAvLyBzbyBsb25nIGFzIHRoZXJlJ3MgZW5vdWdoIHNwYWNlIGZvciB0aGUgbWluaW11bSBkaW1lbnNpb25zLlxuICAgICAgaWYgKHRoaXMuX2NhbkZpdFdpdGhGbGV4aWJsZURpbWVuc2lvbnMob3ZlcmxheUZpdCwgb3ZlcmxheVBvaW50LCB2aWV3cG9ydFJlY3QpKSB7XG4gICAgICAgIC8vIFNhdmUgcG9zaXRpb25zIHdoZXJlIHRoZSBvdmVybGF5IHdpbGwgZml0IHdpdGggZmxleGlibGUgZGltZW5zaW9ucy4gV2Ugd2lsbCB1c2UgdGhlc2VcbiAgICAgICAgLy8gaWYgbm9uZSBvZiB0aGUgcG9zaXRpb25zIGZpdCAqd2l0aG91dCogZmxleGlibGUgZGltZW5zaW9ucy5cbiAgICAgICAgZmxleGlibGVGaXRzLnB1c2goe1xuICAgICAgICAgIHBvc2l0aW9uOiBwb3MsXG4gICAgICAgICAgb3JpZ2luOiBvcmlnaW5Qb2ludCxcbiAgICAgICAgICBvdmVybGF5UmVjdCxcbiAgICAgICAgICBib3VuZGluZ0JveFJlY3Q6IHRoaXMuX2NhbGN1bGF0ZUJvdW5kaW5nQm94UmVjdChvcmlnaW5Qb2ludCwgcG9zKVxuICAgICAgICB9KTtcblxuICAgICAgICBjb250aW51ZTtcbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlIGN1cnJlbnQgcHJlZmVycmVkIHBvc2l0aW9uIGRvZXMgbm90IGZpdCBvbiB0aGUgc2NyZWVuLCByZW1lbWJlciB0aGUgcG9zaXRpb25cbiAgICAgIC8vIGlmIGl0IGhhcyBtb3JlIHZpc2libGUgYXJlYSBvbi1zY3JlZW4gdGhhbiB3ZSd2ZSBzZWVuIGFuZCBtb3ZlIG9udG8gdGhlIG5leHQgcHJlZmVycmVkXG4gICAgICAvLyBwb3NpdGlvbi5cbiAgICAgIGlmICghZmFsbGJhY2sgfHwgZmFsbGJhY2sub3ZlcmxheUZpdC52aXNpYmxlQXJlYSA8IG92ZXJsYXlGaXQudmlzaWJsZUFyZWEpIHtcbiAgICAgICAgZmFsbGJhY2sgPSB7b3ZlcmxheUZpdCwgb3ZlcmxheVBvaW50LCBvcmlnaW5Qb2ludCwgcG9zaXRpb246IHBvcywgb3ZlcmxheVJlY3R9O1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIElmIHRoZXJlIGFyZSBhbnkgcG9zaXRpb25zIHdoZXJlIHRoZSBvdmVybGF5IHdvdWxkIGZpdCB3aXRoIGZsZXhpYmxlIGRpbWVuc2lvbnMsIGNob29zZSB0aGVcbiAgICAvLyBvbmUgdGhhdCBoYXMgdGhlIGdyZWF0ZXN0IGFyZWEgYXZhaWxhYmxlIG1vZGlmaWVkIGJ5IHRoZSBwb3NpdGlvbidzIHdlaWdodFxuICAgIGlmIChmbGV4aWJsZUZpdHMubGVuZ3RoKSB7XG4gICAgICBsZXQgYmVzdEZpdDogRmxleGlibGVGaXQgfCBudWxsID0gbnVsbDtcbiAgICAgIGxldCBiZXN0U2NvcmUgPSAtMTtcbiAgICAgIGZvciAoY29uc3QgZml0IG9mIGZsZXhpYmxlRml0cykge1xuICAgICAgICBjb25zdCBzY29yZSA9XG4gICAgICAgICAgICBmaXQuYm91bmRpbmdCb3hSZWN0LndpZHRoICogZml0LmJvdW5kaW5nQm94UmVjdC5oZWlnaHQgKiAoZml0LnBvc2l0aW9uLndlaWdodCB8fCAxKTtcbiAgICAgICAgaWYgKHNjb3JlID4gYmVzdFNjb3JlKSB7XG4gICAgICAgICAgYmVzdFNjb3JlID0gc2NvcmU7XG4gICAgICAgICAgYmVzdEZpdCA9IGZpdDtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICB0aGlzLl9pc1B1c2hlZCA9IGZhbHNlO1xuICAgICAgdGhpcy5fYXBwbHlQb3NpdGlvbihiZXN0Rml0IS5wb3NpdGlvbiwgYmVzdEZpdCEub3JpZ2luKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBXaGVuIG5vbmUgb2YgdGhlIHByZWZlcnJlZCBwb3NpdGlvbnMgZml0IHdpdGhpbiB0aGUgdmlld3BvcnQsIHRha2UgdGhlIHBvc2l0aW9uXG4gICAgLy8gdGhhdCB3ZW50IG9mZi1zY3JlZW4gdGhlIGxlYXN0IGFuZCBhdHRlbXB0IHRvIHB1c2ggaXQgb24tc2NyZWVuLlxuICAgIGlmICh0aGlzLl9jYW5QdXNoKSB7XG4gICAgICAvLyBUT0RPKGplbGJvdXJuKTogYWZ0ZXIgcHVzaGluZywgdGhlIG9wZW5pbmcgXCJkaXJlY3Rpb25cIiBvZiB0aGUgb3ZlcmxheSBtaWdodCBub3QgbWFrZSBzZW5zZS5cbiAgICAgIHRoaXMuX2lzUHVzaGVkID0gdHJ1ZTtcbiAgICAgIHRoaXMuX2FwcGx5UG9zaXRpb24oZmFsbGJhY2shLnBvc2l0aW9uLCBmYWxsYmFjayEub3JpZ2luUG9pbnQpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIEFsbCBvcHRpb25zIGZvciBnZXR0aW5nIHRoZSBvdmVybGF5IHdpdGhpbiB0aGUgdmlld3BvcnQgaGF2ZSBiZWVuIGV4aGF1c3RlZCwgc28gZ28gd2l0aCB0aGVcbiAgICAvLyBwb3NpdGlvbiB0aGF0IHdlbnQgb2ZmLXNjcmVlbiB0aGUgbGVhc3QuXG4gICAgdGhpcy5fYXBwbHlQb3NpdGlvbihmYWxsYmFjayEucG9zaXRpb24sIGZhbGxiYWNrIS5vcmlnaW5Qb2ludCk7XG4gIH1cblxuICBkZXRhY2goKTogdm9pZCB7XG4gICAgdGhpcy5fY2xlYXJQYW5lbENsYXNzZXMoKTtcbiAgICB0aGlzLl9sYXN0UG9zaXRpb24gPSBudWxsO1xuICAgIHRoaXMuX3ByZXZpb3VzUHVzaEFtb3VudCA9IG51bGw7XG4gICAgdGhpcy5fcmVzaXplU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gIH1cblxuICAvKiogQ2xlYW51cCBhZnRlciB0aGUgZWxlbWVudCBnZXRzIGRlc3Ryb3llZC4gKi9cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5faXNEaXNwb3NlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIFdlIGNhbid0IHVzZSBgX3Jlc2V0Qm91bmRpbmdCb3hTdHlsZXNgIGhlcmUsIGJlY2F1c2UgaXQgcmVzZXRzXG4gICAgLy8gc29tZSBwcm9wZXJ0aWVzIHRvIHplcm8sIHJhdGhlciB0aGFuIHJlbW92aW5nIHRoZW0uXG4gICAgaWYgKHRoaXMuX2JvdW5kaW5nQm94KSB7XG4gICAgICBleHRlbmRTdHlsZXModGhpcy5fYm91bmRpbmdCb3guc3R5bGUsIHtcbiAgICAgICAgdG9wOiAnJyxcbiAgICAgICAgbGVmdDogJycsXG4gICAgICAgIHJpZ2h0OiAnJyxcbiAgICAgICAgYm90dG9tOiAnJyxcbiAgICAgICAgaGVpZ2h0OiAnJyxcbiAgICAgICAgd2lkdGg6ICcnLFxuICAgICAgICBhbGlnbkl0ZW1zOiAnJyxcbiAgICAgICAganVzdGlmeUNvbnRlbnQ6ICcnLFxuICAgICAgfSBhcyBDU1NTdHlsZURlY2xhcmF0aW9uKTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5fcGFuZSkge1xuICAgICAgdGhpcy5fcmVzZXRPdmVybGF5RWxlbWVudFN0eWxlcygpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9vdmVybGF5UmVmKSB7XG4gICAgICB0aGlzLl9vdmVybGF5UmVmLmhvc3RFbGVtZW50LmNsYXNzTGlzdC5yZW1vdmUoYm91bmRpbmdCb3hDbGFzcyk7XG4gICAgfVxuXG4gICAgdGhpcy5kZXRhY2goKTtcbiAgICB0aGlzLl9wb3NpdGlvbkNoYW5nZXMuY29tcGxldGUoKTtcbiAgICB0aGlzLl9vdmVybGF5UmVmID0gdGhpcy5fYm91bmRpbmdCb3ggPSBudWxsITtcbiAgICB0aGlzLl9pc0Rpc3Bvc2VkID0gdHJ1ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGlzIHJlLWFsaWducyB0aGUgb3ZlcmxheSBlbGVtZW50IHdpdGggdGhlIHRyaWdnZXIgaW4gaXRzIGxhc3QgY2FsY3VsYXRlZCBwb3NpdGlvbixcbiAgICogZXZlbiBpZiBhIHBvc2l0aW9uIGhpZ2hlciBpbiB0aGUgXCJwcmVmZXJyZWQgcG9zaXRpb25zXCIgbGlzdCB3b3VsZCBub3cgZml0LiBUaGlzXG4gICAqIGFsbG93cyBvbmUgdG8gcmUtYWxpZ24gdGhlIHBhbmVsIHdpdGhvdXQgY2hhbmdpbmcgdGhlIG9yaWVudGF0aW9uIG9mIHRoZSBwYW5lbC5cbiAgICovXG4gIHJlYXBwbHlMYXN0UG9zaXRpb24oKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLl9pc0Rpc3Bvc2VkICYmICghdGhpcy5fcGxhdGZvcm0gfHwgdGhpcy5fcGxhdGZvcm0uaXNCcm93c2VyKSkge1xuICAgICAgdGhpcy5fb3JpZ2luUmVjdCA9IHRoaXMuX2dldE9yaWdpblJlY3QoKTtcbiAgICAgIHRoaXMuX292ZXJsYXlSZWN0ID0gdGhpcy5fcGFuZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHRoaXMuX3ZpZXdwb3J0UmVjdCA9IHRoaXMuX2dldE5hcnJvd2VkVmlld3BvcnRSZWN0KCk7XG5cbiAgICAgIGNvbnN0IGxhc3RQb3NpdGlvbiA9IHRoaXMuX2xhc3RQb3NpdGlvbiB8fCB0aGlzLl9wcmVmZXJyZWRQb3NpdGlvbnNbMF07XG4gICAgICBjb25zdCBvcmlnaW5Qb2ludCA9IHRoaXMuX2dldE9yaWdpblBvaW50KHRoaXMuX29yaWdpblJlY3QsIGxhc3RQb3NpdGlvbik7XG5cbiAgICAgIHRoaXMuX2FwcGx5UG9zaXRpb24obGFzdFBvc2l0aW9uLCBvcmlnaW5Qb2ludCk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGxpc3Qgb2YgU2Nyb2xsYWJsZSBjb250YWluZXJzIHRoYXQgaG9zdCB0aGUgb3JpZ2luIGVsZW1lbnQgc28gdGhhdFxuICAgKiBvbiByZXBvc2l0aW9uIHdlIGNhbiBldmFsdWF0ZSBpZiBpdCBvciB0aGUgb3ZlcmxheSBoYXMgYmVlbiBjbGlwcGVkIG9yIG91dHNpZGUgdmlldy4gRXZlcnlcbiAgICogU2Nyb2xsYWJsZSBtdXN0IGJlIGFuIGFuY2VzdG9yIGVsZW1lbnQgb2YgdGhlIHN0cmF0ZWd5J3Mgb3JpZ2luIGVsZW1lbnQuXG4gICAqL1xuICB3aXRoU2Nyb2xsYWJsZUNvbnRhaW5lcnMoc2Nyb2xsYWJsZXM6IENka1Njcm9sbGFibGVbXSk6IHRoaXMge1xuICAgIHRoaXMuX3Njcm9sbGFibGVzID0gc2Nyb2xsYWJsZXM7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogQWRkcyBuZXcgcHJlZmVycmVkIHBvc2l0aW9ucy5cbiAgICogQHBhcmFtIHBvc2l0aW9ucyBMaXN0IG9mIHBvc2l0aW9ucyBvcHRpb25zIGZvciB0aGlzIG92ZXJsYXkuXG4gICAqL1xuICB3aXRoUG9zaXRpb25zKHBvc2l0aW9uczogQ29ubmVjdGVkUG9zaXRpb25bXSk6IHRoaXMge1xuICAgIHRoaXMuX3ByZWZlcnJlZFBvc2l0aW9ucyA9IHBvc2l0aW9ucztcblxuICAgIC8vIElmIHRoZSBsYXN0IGNhbGN1bGF0ZWQgcG9zaXRpb24gb2JqZWN0IGlzbid0IHBhcnQgb2YgdGhlIHBvc2l0aW9ucyBhbnltb3JlLCBjbGVhclxuICAgIC8vIGl0IGluIG9yZGVyIHRvIGF2b2lkIGl0IGJlaW5nIHBpY2tlZCB1cCBpZiB0aGUgY29uc3VtZXIgdHJpZXMgdG8gcmUtYXBwbHkuXG4gICAgaWYgKHBvc2l0aW9ucy5pbmRleE9mKHRoaXMuX2xhc3RQb3NpdGlvbiEpID09PSAtMSkge1xuICAgICAgdGhpcy5fbGFzdFBvc2l0aW9uID0gbnVsbDtcbiAgICB9XG5cbiAgICB0aGlzLl92YWxpZGF0ZVBvc2l0aW9ucygpO1xuXG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyBhIG1pbmltdW0gZGlzdGFuY2UgdGhlIG92ZXJsYXkgbWF5IGJlIHBvc2l0aW9uZWQgdG8gdGhlIGVkZ2Ugb2YgdGhlIHZpZXdwb3J0LlxuICAgKiBAcGFyYW0gbWFyZ2luIFJlcXVpcmVkIG1hcmdpbiBiZXR3ZWVuIHRoZSBvdmVybGF5IGFuZCB0aGUgdmlld3BvcnQgZWRnZSBpbiBwaXhlbHMuXG4gICAqL1xuICB3aXRoVmlld3BvcnRNYXJnaW4obWFyZ2luOiBudW1iZXIpOiB0aGlzIHtcbiAgICB0aGlzLl92aWV3cG9ydE1hcmdpbiA9IG1hcmdpbjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKiBTZXRzIHdoZXRoZXIgdGhlIG92ZXJsYXkncyB3aWR0aCBhbmQgaGVpZ2h0IGNhbiBiZSBjb25zdHJhaW5lZCB0byBmaXQgd2l0aGluIHRoZSB2aWV3cG9ydC4gKi9cbiAgd2l0aEZsZXhpYmxlRGltZW5zaW9ucyhmbGV4aWJsZURpbWVuc2lvbnMgPSB0cnVlKTogdGhpcyB7XG4gICAgdGhpcy5faGFzRmxleGlibGVEaW1lbnNpb25zID0gZmxleGlibGVEaW1lbnNpb25zO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIFNldHMgd2hldGhlciB0aGUgb3ZlcmxheSBjYW4gZ3JvdyBhZnRlciB0aGUgaW5pdGlhbCBvcGVuIHZpYSBmbGV4aWJsZSB3aWR0aC9oZWlnaHQuICovXG4gIHdpdGhHcm93QWZ0ZXJPcGVuKGdyb3dBZnRlck9wZW4gPSB0cnVlKTogdGhpcyB7XG4gICAgdGhpcy5fZ3Jvd0FmdGVyT3BlbiA9IGdyb3dBZnRlck9wZW47XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogU2V0cyB3aGV0aGVyIHRoZSBvdmVybGF5IGNhbiBiZSBwdXNoZWQgb24tc2NyZWVuIGlmIG5vbmUgb2YgdGhlIHByb3ZpZGVkIHBvc2l0aW9ucyBmaXQuICovXG4gIHdpdGhQdXNoKGNhblB1c2ggPSB0cnVlKTogdGhpcyB7XG4gICAgdGhpcy5fY2FuUHVzaCA9IGNhblB1c2g7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB3aGV0aGVyIHRoZSBvdmVybGF5J3MgcG9zaXRpb24gc2hvdWxkIGJlIGxvY2tlZCBpbiBhZnRlciBpdCBpcyBwb3NpdGlvbmVkXG4gICAqIGluaXRpYWxseS4gV2hlbiBhbiBvdmVybGF5IGlzIGxvY2tlZCBpbiwgaXQgd29uJ3QgYXR0ZW1wdCB0byByZXBvc2l0aW9uIGl0c2VsZlxuICAgKiB3aGVuIHRoZSBwb3NpdGlvbiBpcyByZS1hcHBsaWVkIChlLmcuIHdoZW4gdGhlIHVzZXIgc2Nyb2xscyBhd2F5KS5cbiAgICogQHBhcmFtIGlzTG9ja2VkIFdoZXRoZXIgdGhlIG92ZXJsYXkgc2hvdWxkIGxvY2tlZCBpbi5cbiAgICovXG4gIHdpdGhMb2NrZWRQb3NpdGlvbihpc0xvY2tlZCA9IHRydWUpOiB0aGlzIHtcbiAgICB0aGlzLl9wb3NpdGlvbkxvY2tlZCA9IGlzTG9ja2VkO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIG9yaWdpbiwgcmVsYXRpdmUgdG8gd2hpY2ggdG8gcG9zaXRpb24gdGhlIG92ZXJsYXkuXG4gICAqIFVzaW5nIGFuIGVsZW1lbnQgb3JpZ2luIGlzIHVzZWZ1bCBmb3IgYnVpbGRpbmcgY29tcG9uZW50cyB0aGF0IG5lZWQgdG8gYmUgcG9zaXRpb25lZFxuICAgKiByZWxhdGl2ZWx5IHRvIGEgdHJpZ2dlciAoZS5nLiBkcm9wZG93biBtZW51cyBvciB0b29sdGlwcyksIHdoZXJlYXMgdXNpbmcgYSBwb2ludCBjYW4gYmVcbiAgICogdXNlZCBmb3IgY2FzZXMgbGlrZSBjb250ZXh0dWFsIG1lbnVzIHdoaWNoIG9wZW4gcmVsYXRpdmUgdG8gdGhlIHVzZXIncyBwb2ludGVyLlxuICAgKiBAcGFyYW0gb3JpZ2luIFJlZmVyZW5jZSB0byB0aGUgbmV3IG9yaWdpbi5cbiAgICovXG4gIHNldE9yaWdpbihvcmlnaW46IEZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneU9yaWdpbik6IHRoaXMge1xuICAgIHRoaXMuX29yaWdpbiA9IG9yaWdpbjtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBkZWZhdWx0IG9mZnNldCBmb3IgdGhlIG92ZXJsYXkncyBjb25uZWN0aW9uIHBvaW50IG9uIHRoZSB4LWF4aXMuXG4gICAqIEBwYXJhbSBvZmZzZXQgTmV3IG9mZnNldCBpbiB0aGUgWCBheGlzLlxuICAgKi9cbiAgd2l0aERlZmF1bHRPZmZzZXRYKG9mZnNldDogbnVtYmVyKTogdGhpcyB7XG4gICAgdGhpcy5fb2Zmc2V0WCA9IG9mZnNldDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHRoZSBkZWZhdWx0IG9mZnNldCBmb3IgdGhlIG92ZXJsYXkncyBjb25uZWN0aW9uIHBvaW50IG9uIHRoZSB5LWF4aXMuXG4gICAqIEBwYXJhbSBvZmZzZXQgTmV3IG9mZnNldCBpbiB0aGUgWSBheGlzLlxuICAgKi9cbiAgd2l0aERlZmF1bHRPZmZzZXRZKG9mZnNldDogbnVtYmVyKTogdGhpcyB7XG4gICAgdGhpcy5fb2Zmc2V0WSA9IG9mZnNldDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBDb25maWd1cmVzIHRoYXQgdGhlIHBvc2l0aW9uIHN0cmF0ZWd5IHNob3VsZCBzZXQgYSBgdHJhbnNmb3JtLW9yaWdpbmAgb24gc29tZSBlbGVtZW50c1xuICAgKiBpbnNpZGUgdGhlIG92ZXJsYXksIGRlcGVuZGluZyBvbiB0aGUgY3VycmVudCBwb3NpdGlvbiB0aGF0IGlzIGJlaW5nIGFwcGxpZWQuIFRoaXMgaXNcbiAgICogdXNlZnVsIGZvciB0aGUgY2FzZXMgd2hlcmUgdGhlIG9yaWdpbiBvZiBhbiBhbmltYXRpb24gY2FuIGNoYW5nZSBkZXBlbmRpbmcgb24gdGhlXG4gICAqIGFsaWdubWVudCBvZiB0aGUgb3ZlcmxheS5cbiAgICogQHBhcmFtIHNlbGVjdG9yIENTUyBzZWxlY3RvciB0aGF0IHdpbGwgYmUgdXNlZCB0byBmaW5kIHRoZSB0YXJnZXRcbiAgICogICAgZWxlbWVudHMgb250byB3aGljaCB0byBzZXQgdGhlIHRyYW5zZm9ybSBvcmlnaW4uXG4gICAqL1xuICB3aXRoVHJhbnNmb3JtT3JpZ2luT24oc2VsZWN0b3I6IHN0cmluZyk6IHRoaXMge1xuICAgIHRoaXMuX3RyYW5zZm9ybU9yaWdpblNlbGVjdG9yID0gc2VsZWN0b3I7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgKHgsIHkpIGNvb3JkaW5hdGUgb2YgYSBjb25uZWN0aW9uIHBvaW50IG9uIHRoZSBvcmlnaW4gYmFzZWQgb24gYSByZWxhdGl2ZSBwb3NpdGlvbi5cbiAgICovXG4gIHByaXZhdGUgX2dldE9yaWdpblBvaW50KG9yaWdpblJlY3Q6IENsaWVudFJlY3QsIHBvczogQ29ubmVjdGVkUG9zaXRpb24pOiBQb2ludCB7XG4gICAgbGV0IHg6IG51bWJlcjtcbiAgICBpZiAocG9zLm9yaWdpblggPT0gJ2NlbnRlcicpIHtcbiAgICAgIC8vIE5vdGU6IHdoZW4gY2VudGVyaW5nIHdlIHNob3VsZCBhbHdheXMgdXNlIHRoZSBgbGVmdGBcbiAgICAgIC8vIG9mZnNldCwgb3RoZXJ3aXNlIHRoZSBwb3NpdGlvbiB3aWxsIGJlIHdyb25nIGluIFJUTC5cbiAgICAgIHggPSBvcmlnaW5SZWN0LmxlZnQgKyAob3JpZ2luUmVjdC53aWR0aCAvIDIpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBzdGFydFggPSB0aGlzLl9pc1J0bCgpID8gb3JpZ2luUmVjdC5yaWdodCA6IG9yaWdpblJlY3QubGVmdDtcbiAgICAgIGNvbnN0IGVuZFggPSB0aGlzLl9pc1J0bCgpID8gb3JpZ2luUmVjdC5sZWZ0IDogb3JpZ2luUmVjdC5yaWdodDtcbiAgICAgIHggPSBwb3Mub3JpZ2luWCA9PSAnc3RhcnQnID8gc3RhcnRYIDogZW5kWDtcbiAgICB9XG5cbiAgICBsZXQgeTogbnVtYmVyO1xuICAgIGlmIChwb3Mub3JpZ2luWSA9PSAnY2VudGVyJykge1xuICAgICAgeSA9IG9yaWdpblJlY3QudG9wICsgKG9yaWdpblJlY3QuaGVpZ2h0IC8gMik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHkgPSBwb3Mub3JpZ2luWSA9PSAndG9wJyA/IG9yaWdpblJlY3QudG9wIDogb3JpZ2luUmVjdC5ib3R0b207XG4gICAgfVxuXG4gICAgcmV0dXJuIHt4LCB5fTtcbiAgfVxuXG5cbiAgLyoqXG4gICAqIEdldHMgdGhlICh4LCB5KSBjb29yZGluYXRlIG9mIHRoZSB0b3AtbGVmdCBjb3JuZXIgb2YgdGhlIG92ZXJsYXkgZ2l2ZW4gYSBnaXZlbiBwb3NpdGlvbiBhbmRcbiAgICogb3JpZ2luIHBvaW50IHRvIHdoaWNoIHRoZSBvdmVybGF5IHNob3VsZCBiZSBjb25uZWN0ZWQuXG4gICAqL1xuICBwcml2YXRlIF9nZXRPdmVybGF5UG9pbnQoXG4gICAgICBvcmlnaW5Qb2ludDogUG9pbnQsXG4gICAgICBvdmVybGF5UmVjdDogQ2xpZW50UmVjdCxcbiAgICAgIHBvczogQ29ubmVjdGVkUG9zaXRpb24pOiBQb2ludCB7XG5cbiAgICAvLyBDYWxjdWxhdGUgdGhlIChvdmVybGF5U3RhcnRYLCBvdmVybGF5U3RhcnRZKSwgdGhlIHN0YXJ0IG9mIHRoZVxuICAgIC8vIHBvdGVudGlhbCBvdmVybGF5IHBvc2l0aW9uIHJlbGF0aXZlIHRvIHRoZSBvcmlnaW4gcG9pbnQuXG4gICAgbGV0IG92ZXJsYXlTdGFydFg6IG51bWJlcjtcbiAgICBpZiAocG9zLm92ZXJsYXlYID09ICdjZW50ZXInKSB7XG4gICAgICBvdmVybGF5U3RhcnRYID0gLW92ZXJsYXlSZWN0LndpZHRoIC8gMjtcbiAgICB9IGVsc2UgaWYgKHBvcy5vdmVybGF5WCA9PT0gJ3N0YXJ0Jykge1xuICAgICAgb3ZlcmxheVN0YXJ0WCA9IHRoaXMuX2lzUnRsKCkgPyAtb3ZlcmxheVJlY3Qud2lkdGggOiAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBvdmVybGF5U3RhcnRYID0gdGhpcy5faXNSdGwoKSA/IDAgOiAtb3ZlcmxheVJlY3Qud2lkdGg7XG4gICAgfVxuXG4gICAgbGV0IG92ZXJsYXlTdGFydFk6IG51bWJlcjtcbiAgICBpZiAocG9zLm92ZXJsYXlZID09ICdjZW50ZXInKSB7XG4gICAgICBvdmVybGF5U3RhcnRZID0gLW92ZXJsYXlSZWN0LmhlaWdodCAvIDI7XG4gICAgfSBlbHNlIHtcbiAgICAgIG92ZXJsYXlTdGFydFkgPSBwb3Mub3ZlcmxheVkgPT0gJ3RvcCcgPyAwIDogLW92ZXJsYXlSZWN0LmhlaWdodDtcbiAgICB9XG5cbiAgICAvLyBUaGUgKHgsIHkpIGNvb3JkaW5hdGVzIG9mIHRoZSBvdmVybGF5LlxuICAgIHJldHVybiB7XG4gICAgICB4OiBvcmlnaW5Qb2ludC54ICsgb3ZlcmxheVN0YXJ0WCxcbiAgICAgIHk6IG9yaWdpblBvaW50LnkgKyBvdmVybGF5U3RhcnRZLFxuICAgIH07XG4gIH1cblxuICAvKiogR2V0cyBob3cgd2VsbCBhbiBvdmVybGF5IGF0IHRoZSBnaXZlbiBwb2ludCB3aWxsIGZpdCB3aXRoaW4gdGhlIHZpZXdwb3J0LiAqL1xuICBwcml2YXRlIF9nZXRPdmVybGF5Rml0KHBvaW50OiBQb2ludCwgcmF3T3ZlcmxheVJlY3Q6IENsaWVudFJlY3QsIHZpZXdwb3J0OiBDbGllbnRSZWN0LFxuICAgIHBvc2l0aW9uOiBDb25uZWN0ZWRQb3NpdGlvbik6IE92ZXJsYXlGaXQge1xuXG4gICAgLy8gUm91bmQgdGhlIG92ZXJsYXkgcmVjdCB3aGVuIGNvbXBhcmluZyBhZ2FpbnN0IHRoZVxuICAgIC8vIHZpZXdwb3J0LCBiZWNhdXNlIHRoZSB2aWV3cG9ydCBpcyBhbHdheXMgcm91bmRlZC5cbiAgICBjb25zdCBvdmVybGF5ID0gZ2V0Um91bmRlZEJvdW5kaW5nQ2xpZW50UmVjdChyYXdPdmVybGF5UmVjdCk7XG4gICAgbGV0IHt4LCB5fSA9IHBvaW50O1xuICAgIGxldCBvZmZzZXRYID0gdGhpcy5fZ2V0T2Zmc2V0KHBvc2l0aW9uLCAneCcpO1xuICAgIGxldCBvZmZzZXRZID0gdGhpcy5fZ2V0T2Zmc2V0KHBvc2l0aW9uLCAneScpO1xuXG4gICAgLy8gQWNjb3VudCBmb3IgdGhlIG9mZnNldHMgc2luY2UgdGhleSBjb3VsZCBwdXNoIHRoZSBvdmVybGF5IG91dCBvZiB0aGUgdmlld3BvcnQuXG4gICAgaWYgKG9mZnNldFgpIHtcbiAgICAgIHggKz0gb2Zmc2V0WDtcbiAgICB9XG5cbiAgICBpZiAob2Zmc2V0WSkge1xuICAgICAgeSArPSBvZmZzZXRZO1xuICAgIH1cblxuICAgIC8vIEhvdyBtdWNoIHRoZSBvdmVybGF5IHdvdWxkIG92ZXJmbG93IGF0IHRoaXMgcG9zaXRpb24sIG9uIGVhY2ggc2lkZS5cbiAgICBsZXQgbGVmdE92ZXJmbG93ID0gMCAtIHg7XG4gICAgbGV0IHJpZ2h0T3ZlcmZsb3cgPSAoeCArIG92ZXJsYXkud2lkdGgpIC0gdmlld3BvcnQud2lkdGg7XG4gICAgbGV0IHRvcE92ZXJmbG93ID0gMCAtIHk7XG4gICAgbGV0IGJvdHRvbU92ZXJmbG93ID0gKHkgKyBvdmVybGF5LmhlaWdodCkgLSB2aWV3cG9ydC5oZWlnaHQ7XG5cbiAgICAvLyBWaXNpYmxlIHBhcnRzIG9mIHRoZSBlbGVtZW50IG9uIGVhY2ggYXhpcy5cbiAgICBsZXQgdmlzaWJsZVdpZHRoID0gdGhpcy5fc3VidHJhY3RPdmVyZmxvd3Mob3ZlcmxheS53aWR0aCwgbGVmdE92ZXJmbG93LCByaWdodE92ZXJmbG93KTtcbiAgICBsZXQgdmlzaWJsZUhlaWdodCA9IHRoaXMuX3N1YnRyYWN0T3ZlcmZsb3dzKG92ZXJsYXkuaGVpZ2h0LCB0b3BPdmVyZmxvdywgYm90dG9tT3ZlcmZsb3cpO1xuICAgIGxldCB2aXNpYmxlQXJlYSA9IHZpc2libGVXaWR0aCAqIHZpc2libGVIZWlnaHQ7XG5cbiAgICByZXR1cm4ge1xuICAgICAgdmlzaWJsZUFyZWEsXG4gICAgICBpc0NvbXBsZXRlbHlXaXRoaW5WaWV3cG9ydDogKG92ZXJsYXkud2lkdGggKiBvdmVybGF5LmhlaWdodCkgPT09IHZpc2libGVBcmVhLFxuICAgICAgZml0c0luVmlld3BvcnRWZXJ0aWNhbGx5OiB2aXNpYmxlSGVpZ2h0ID09PSBvdmVybGF5LmhlaWdodCxcbiAgICAgIGZpdHNJblZpZXdwb3J0SG9yaXpvbnRhbGx5OiB2aXNpYmxlV2lkdGggPT0gb3ZlcmxheS53aWR0aCxcbiAgICB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFdoZXRoZXIgdGhlIG92ZXJsYXkgY2FuIGZpdCB3aXRoaW4gdGhlIHZpZXdwb3J0IHdoZW4gaXQgbWF5IHJlc2l6ZSBlaXRoZXIgaXRzIHdpZHRoIG9yIGhlaWdodC5cbiAgICogQHBhcmFtIGZpdCBIb3cgd2VsbCB0aGUgb3ZlcmxheSBmaXRzIGluIHRoZSB2aWV3cG9ydCBhdCBzb21lIHBvc2l0aW9uLlxuICAgKiBAcGFyYW0gcG9pbnQgVGhlICh4LCB5KSBjb29yZGluYXRlcyBvZiB0aGUgb3ZlcmxhdCBhdCBzb21lIHBvc2l0aW9uLlxuICAgKiBAcGFyYW0gdmlld3BvcnQgVGhlIGdlb21ldHJ5IG9mIHRoZSB2aWV3cG9ydC5cbiAgICovXG4gIHByaXZhdGUgX2NhbkZpdFdpdGhGbGV4aWJsZURpbWVuc2lvbnMoZml0OiBPdmVybGF5Rml0LCBwb2ludDogUG9pbnQsIHZpZXdwb3J0OiBDbGllbnRSZWN0KSB7XG4gICAgaWYgKHRoaXMuX2hhc0ZsZXhpYmxlRGltZW5zaW9ucykge1xuICAgICAgY29uc3QgYXZhaWxhYmxlSGVpZ2h0ID0gdmlld3BvcnQuYm90dG9tIC0gcG9pbnQueTtcbiAgICAgIGNvbnN0IGF2YWlsYWJsZVdpZHRoID0gdmlld3BvcnQucmlnaHQgLSBwb2ludC54O1xuICAgICAgY29uc3QgbWluSGVpZ2h0ID0gZ2V0UGl4ZWxWYWx1ZSh0aGlzLl9vdmVybGF5UmVmLmdldENvbmZpZygpLm1pbkhlaWdodCk7XG4gICAgICBjb25zdCBtaW5XaWR0aCA9IGdldFBpeGVsVmFsdWUodGhpcy5fb3ZlcmxheVJlZi5nZXRDb25maWcoKS5taW5XaWR0aCk7XG5cbiAgICAgIGNvbnN0IHZlcnRpY2FsRml0ID0gZml0LmZpdHNJblZpZXdwb3J0VmVydGljYWxseSB8fFxuICAgICAgICAgIChtaW5IZWlnaHQgIT0gbnVsbCAmJiBtaW5IZWlnaHQgPD0gYXZhaWxhYmxlSGVpZ2h0KTtcbiAgICAgIGNvbnN0IGhvcml6b250YWxGaXQgPSBmaXQuZml0c0luVmlld3BvcnRIb3Jpem9udGFsbHkgfHxcbiAgICAgICAgICAobWluV2lkdGggIT0gbnVsbCAmJiBtaW5XaWR0aCA8PSBhdmFpbGFibGVXaWR0aCk7XG5cbiAgICAgIHJldHVybiB2ZXJ0aWNhbEZpdCAmJiBob3Jpem9udGFsRml0O1xuICAgIH1cbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgcG9pbnQgYXQgd2hpY2ggdGhlIG92ZXJsYXkgY2FuIGJlIFwicHVzaGVkXCIgb24tc2NyZWVuLiBJZiB0aGUgb3ZlcmxheSBpcyBsYXJnZXIgdGhhblxuICAgKiB0aGUgdmlld3BvcnQsIHRoZSB0b3AtbGVmdCBjb3JuZXIgd2lsbCBiZSBwdXNoZWQgb24tc2NyZWVuICh3aXRoIG92ZXJmbG93IG9jY3VyaW5nIG9uIHRoZVxuICAgKiByaWdodCBhbmQgYm90dG9tKS5cbiAgICpcbiAgICogQHBhcmFtIHN0YXJ0IFN0YXJ0aW5nIHBvaW50IGZyb20gd2hpY2ggdGhlIG92ZXJsYXkgaXMgcHVzaGVkLlxuICAgKiBAcGFyYW0gb3ZlcmxheSBEaW1lbnNpb25zIG9mIHRoZSBvdmVybGF5LlxuICAgKiBAcGFyYW0gc2Nyb2xsUG9zaXRpb24gQ3VycmVudCB2aWV3cG9ydCBzY3JvbGwgcG9zaXRpb24uXG4gICAqIEByZXR1cm5zIFRoZSBwb2ludCBhdCB3aGljaCB0byBwb3NpdGlvbiB0aGUgb3ZlcmxheSBhZnRlciBwdXNoaW5nLiBUaGlzIGlzIGVmZmVjdGl2ZWx5IGEgbmV3XG4gICAqICAgICBvcmlnaW5Qb2ludC5cbiAgICovXG4gIHByaXZhdGUgX3B1c2hPdmVybGF5T25TY3JlZW4oc3RhcnQ6IFBvaW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJhd092ZXJsYXlSZWN0OiBDbGllbnRSZWN0LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFBvc2l0aW9uOiBWaWV3cG9ydFNjcm9sbFBvc2l0aW9uKTogUG9pbnQge1xuICAgIC8vIElmIHRoZSBwb3NpdGlvbiBpcyBsb2NrZWQgYW5kIHdlJ3ZlIHB1c2hlZCB0aGUgb3ZlcmxheSBhbHJlYWR5LCByZXVzZSB0aGUgcHJldmlvdXMgcHVzaFxuICAgIC8vIGFtb3VudCwgcmF0aGVyIHRoYW4gcHVzaGluZyBpdCBhZ2Fpbi4gSWYgd2Ugd2VyZSB0byBjb250aW51ZSBwdXNoaW5nLCB0aGUgZWxlbWVudCB3b3VsZFxuICAgIC8vIHJlbWFpbiBpbiB0aGUgdmlld3BvcnQsIHdoaWNoIGdvZXMgYWdhaW5zdCB0aGUgZXhwZWN0YXRpb25zIHdoZW4gcG9zaXRpb24gbG9ja2luZyBpcyBlbmFibGVkLlxuICAgIGlmICh0aGlzLl9wcmV2aW91c1B1c2hBbW91bnQgJiYgdGhpcy5fcG9zaXRpb25Mb2NrZWQpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHg6IHN0YXJ0LnggKyB0aGlzLl9wcmV2aW91c1B1c2hBbW91bnQueCxcbiAgICAgICAgeTogc3RhcnQueSArIHRoaXMuX3ByZXZpb3VzUHVzaEFtb3VudC55XG4gICAgICB9O1xuICAgIH1cblxuICAgIC8vIFJvdW5kIHRoZSBvdmVybGF5IHJlY3Qgd2hlbiBjb21wYXJpbmcgYWdhaW5zdCB0aGVcbiAgICAvLyB2aWV3cG9ydCwgYmVjYXVzZSB0aGUgdmlld3BvcnQgaXMgYWx3YXlzIHJvdW5kZWQuXG4gICAgY29uc3Qgb3ZlcmxheSA9IGdldFJvdW5kZWRCb3VuZGluZ0NsaWVudFJlY3QocmF3T3ZlcmxheVJlY3QpO1xuICAgIGNvbnN0IHZpZXdwb3J0ID0gdGhpcy5fdmlld3BvcnRSZWN0O1xuXG4gICAgLy8gRGV0ZXJtaW5lIGhvdyBtdWNoIHRoZSBvdmVybGF5IGdvZXMgb3V0c2lkZSB0aGUgdmlld3BvcnQgb24gZWFjaFxuICAgIC8vIHNpZGUsIHdoaWNoIHdlJ2xsIHVzZSB0byBkZWNpZGUgd2hpY2ggZGlyZWN0aW9uIHRvIHB1c2ggaXQuXG4gICAgY29uc3Qgb3ZlcmZsb3dSaWdodCA9IE1hdGgubWF4KHN0YXJ0LnggKyBvdmVybGF5LndpZHRoIC0gdmlld3BvcnQud2lkdGgsIDApO1xuICAgIGNvbnN0IG92ZXJmbG93Qm90dG9tID0gTWF0aC5tYXgoc3RhcnQueSArIG92ZXJsYXkuaGVpZ2h0IC0gdmlld3BvcnQuaGVpZ2h0LCAwKTtcbiAgICBjb25zdCBvdmVyZmxvd1RvcCA9IE1hdGgubWF4KHZpZXdwb3J0LnRvcCAtIHNjcm9sbFBvc2l0aW9uLnRvcCAtIHN0YXJ0LnksIDApO1xuICAgIGNvbnN0IG92ZXJmbG93TGVmdCA9IE1hdGgubWF4KHZpZXdwb3J0LmxlZnQgLSBzY3JvbGxQb3NpdGlvbi5sZWZ0IC0gc3RhcnQueCwgMCk7XG5cbiAgICAvLyBBbW91bnQgYnkgd2hpY2ggdG8gcHVzaCB0aGUgb3ZlcmxheSBpbiBlYWNoIGF4aXMgc3VjaCB0aGF0IGl0IHJlbWFpbnMgb24tc2NyZWVuLlxuICAgIGxldCBwdXNoWCA9IDA7XG4gICAgbGV0IHB1c2hZID0gMDtcblxuICAgIC8vIElmIHRoZSBvdmVybGF5IGZpdHMgY29tcGxldGVseSB3aXRoaW4gdGhlIGJvdW5kcyBvZiB0aGUgdmlld3BvcnQsIHB1c2ggaXQgZnJvbSB3aGljaGV2ZXJcbiAgICAvLyBkaXJlY3Rpb24gaXMgZ29lcyBvZmYtc2NyZWVuLiBPdGhlcndpc2UsIHB1c2ggdGhlIHRvcC1sZWZ0IGNvcm5lciBzdWNoIHRoYXQgaXRzIGluIHRoZVxuICAgIC8vIHZpZXdwb3J0IGFuZCBhbGxvdyBmb3IgdGhlIHRyYWlsaW5nIGVuZCBvZiB0aGUgb3ZlcmxheSB0byBnbyBvdXQgb2YgYm91bmRzLlxuICAgIGlmIChvdmVybGF5LndpZHRoIDw9IHZpZXdwb3J0LndpZHRoKSB7XG4gICAgICBwdXNoWCA9IG92ZXJmbG93TGVmdCB8fCAtb3ZlcmZsb3dSaWdodDtcbiAgICB9IGVsc2Uge1xuICAgICAgcHVzaFggPSBzdGFydC54IDwgdGhpcy5fdmlld3BvcnRNYXJnaW4gPyAodmlld3BvcnQubGVmdCAtIHNjcm9sbFBvc2l0aW9uLmxlZnQpIC0gc3RhcnQueCA6IDA7XG4gICAgfVxuXG4gICAgaWYgKG92ZXJsYXkuaGVpZ2h0IDw9IHZpZXdwb3J0LmhlaWdodCkge1xuICAgICAgcHVzaFkgPSBvdmVyZmxvd1RvcCB8fCAtb3ZlcmZsb3dCb3R0b207XG4gICAgfSBlbHNlIHtcbiAgICAgIHB1c2hZID0gc3RhcnQueSA8IHRoaXMuX3ZpZXdwb3J0TWFyZ2luID8gKHZpZXdwb3J0LnRvcCAtIHNjcm9sbFBvc2l0aW9uLnRvcCkgLSBzdGFydC55IDogMDtcbiAgICB9XG5cbiAgICB0aGlzLl9wcmV2aW91c1B1c2hBbW91bnQgPSB7eDogcHVzaFgsIHk6IHB1c2hZfTtcblxuICAgIHJldHVybiB7XG4gICAgICB4OiBzdGFydC54ICsgcHVzaFgsXG4gICAgICB5OiBzdGFydC55ICsgcHVzaFksXG4gICAgfTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBcHBsaWVzIGEgY29tcHV0ZWQgcG9zaXRpb24gdG8gdGhlIG92ZXJsYXkgYW5kIGVtaXRzIGEgcG9zaXRpb24gY2hhbmdlLlxuICAgKiBAcGFyYW0gcG9zaXRpb24gVGhlIHBvc2l0aW9uIHByZWZlcmVuY2VcbiAgICogQHBhcmFtIG9yaWdpblBvaW50IFRoZSBwb2ludCBvbiB0aGUgb3JpZ2luIGVsZW1lbnQgd2hlcmUgdGhlIG92ZXJsYXkgaXMgY29ubmVjdGVkLlxuICAgKi9cbiAgcHJpdmF0ZSBfYXBwbHlQb3NpdGlvbihwb3NpdGlvbjogQ29ubmVjdGVkUG9zaXRpb24sIG9yaWdpblBvaW50OiBQb2ludCkge1xuICAgIHRoaXMuX3NldFRyYW5zZm9ybU9yaWdpbihwb3NpdGlvbik7XG4gICAgdGhpcy5fc2V0T3ZlcmxheUVsZW1lbnRTdHlsZXMob3JpZ2luUG9pbnQsIHBvc2l0aW9uKTtcbiAgICB0aGlzLl9zZXRCb3VuZGluZ0JveFN0eWxlcyhvcmlnaW5Qb2ludCwgcG9zaXRpb24pO1xuXG4gICAgaWYgKHBvc2l0aW9uLnBhbmVsQ2xhc3MpIHtcbiAgICAgIHRoaXMuX2FkZFBhbmVsQ2xhc3Nlcyhwb3NpdGlvbi5wYW5lbENsYXNzKTtcbiAgICB9XG5cbiAgICAvLyBTYXZlIHRoZSBsYXN0IGNvbm5lY3RlZCBwb3NpdGlvbiBpbiBjYXNlIHRoZSBwb3NpdGlvbiBuZWVkcyB0byBiZSByZS1jYWxjdWxhdGVkLlxuICAgIHRoaXMuX2xhc3RQb3NpdGlvbiA9IHBvc2l0aW9uO1xuXG4gICAgLy8gTm90aWZ5IHRoYXQgdGhlIHBvc2l0aW9uIGhhcyBiZWVuIGNoYW5nZWQgYWxvbmcgd2l0aCBpdHMgY2hhbmdlIHByb3BlcnRpZXMuXG4gICAgLy8gV2Ugb25seSBlbWl0IGlmIHdlJ3ZlIGdvdCBhbnkgc3Vic2NyaXB0aW9ucywgYmVjYXVzZSB0aGUgc2Nyb2xsIHZpc2liaWxpdHlcbiAgICAvLyBjYWxjdWxjYXRpb25zIGNhbiBiZSBzb21ld2hhdCBleHBlbnNpdmUuXG4gICAgaWYgKHRoaXMuX3Bvc2l0aW9uQ2hhbmdlcy5vYnNlcnZlcnMubGVuZ3RoKSB7XG4gICAgICBjb25zdCBzY3JvbGxhYmxlVmlld1Byb3BlcnRpZXMgPSB0aGlzLl9nZXRTY3JvbGxWaXNpYmlsaXR5KCk7XG4gICAgICBjb25zdCBjaGFuZ2VFdmVudCA9IG5ldyBDb25uZWN0ZWRPdmVybGF5UG9zaXRpb25DaGFuZ2UocG9zaXRpb24sIHNjcm9sbGFibGVWaWV3UHJvcGVydGllcyk7XG4gICAgICB0aGlzLl9wb3NpdGlvbkNoYW5nZXMubmV4dChjaGFuZ2VFdmVudCk7XG4gICAgfVxuXG4gICAgdGhpcy5faXNJbml0aWFsUmVuZGVyID0gZmFsc2U7XG4gIH1cblxuICAvKiogU2V0cyB0aGUgdHJhbnNmb3JtIG9yaWdpbiBiYXNlZCBvbiB0aGUgY29uZmlndXJlZCBzZWxlY3RvciBhbmQgdGhlIHBhc3NlZC1pbiBwb3NpdGlvbi4gICovXG4gIHByaXZhdGUgX3NldFRyYW5zZm9ybU9yaWdpbihwb3NpdGlvbjogQ29ubmVjdGVkUG9zaXRpb24pIHtcbiAgICBpZiAoIXRoaXMuX3RyYW5zZm9ybU9yaWdpblNlbGVjdG9yKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgZWxlbWVudHM6IE5vZGVMaXN0T2Y8SFRNTEVsZW1lbnQ+ID1cbiAgICAgICAgdGhpcy5fYm91bmRpbmdCb3ghLnF1ZXJ5U2VsZWN0b3JBbGwodGhpcy5fdHJhbnNmb3JtT3JpZ2luU2VsZWN0b3IpO1xuICAgIGxldCB4T3JpZ2luOiAnbGVmdCcgfCAncmlnaHQnIHwgJ2NlbnRlcic7XG4gICAgbGV0IHlPcmlnaW46ICd0b3AnIHwgJ2JvdHRvbScgfCAnY2VudGVyJyA9IHBvc2l0aW9uLm92ZXJsYXlZO1xuXG4gICAgaWYgKHBvc2l0aW9uLm92ZXJsYXlYID09PSAnY2VudGVyJykge1xuICAgICAgeE9yaWdpbiA9ICdjZW50ZXInO1xuICAgIH0gZWxzZSBpZiAodGhpcy5faXNSdGwoKSkge1xuICAgICAgeE9yaWdpbiA9IHBvc2l0aW9uLm92ZXJsYXlYID09PSAnc3RhcnQnID8gJ3JpZ2h0JyA6ICdsZWZ0JztcbiAgICB9IGVsc2Uge1xuICAgICAgeE9yaWdpbiA9IHBvc2l0aW9uLm92ZXJsYXlYID09PSAnc3RhcnQnID8gJ2xlZnQnIDogJ3JpZ2h0JztcbiAgICB9XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGVsZW1lbnRzLmxlbmd0aDsgaSsrKSB7XG4gICAgICBlbGVtZW50c1tpXS5zdHlsZS50cmFuc2Zvcm1PcmlnaW4gPSBgJHt4T3JpZ2lufSAke3lPcmlnaW59YDtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgcG9zaXRpb24gYW5kIHNpemUgb2YgdGhlIG92ZXJsYXkncyBzaXppbmcgY29udGFpbmVyLlxuICAgKlxuICAgKiBUaGlzIG1ldGhvZCBkb2VzIG5vIG1lYXN1cmluZyBhbmQgYXBwbGllcyBubyBzdHlsZXMgc28gdGhhdCB3ZSBjYW4gY2hlYXBseSBjb21wdXRlIHRoZVxuICAgKiBib3VuZHMgZm9yIGFsbCBwb3NpdGlvbnMgYW5kIGNob29zZSB0aGUgYmVzdCBmaXQgYmFzZWQgb24gdGhlc2UgcmVzdWx0cy5cbiAgICovXG4gIHByaXZhdGUgX2NhbGN1bGF0ZUJvdW5kaW5nQm94UmVjdChvcmlnaW46IFBvaW50LCBwb3NpdGlvbjogQ29ubmVjdGVkUG9zaXRpb24pOiBCb3VuZGluZ0JveFJlY3Qge1xuICAgIGNvbnN0IHZpZXdwb3J0ID0gdGhpcy5fdmlld3BvcnRSZWN0O1xuICAgIGNvbnN0IGlzUnRsID0gdGhpcy5faXNSdGwoKTtcbiAgICBsZXQgaGVpZ2h0OiBudW1iZXIsIHRvcDogbnVtYmVyLCBib3R0b206IG51bWJlcjtcblxuICAgIGlmIChwb3NpdGlvbi5vdmVybGF5WSA9PT0gJ3RvcCcpIHtcbiAgICAgIC8vIE92ZXJsYXkgaXMgb3BlbmluZyBcImRvd253YXJkXCIgYW5kIHRodXMgaXMgYm91bmQgYnkgdGhlIGJvdHRvbSB2aWV3cG9ydCBlZGdlLlxuICAgICAgdG9wID0gb3JpZ2luLnk7XG4gICAgICBoZWlnaHQgPSB2aWV3cG9ydC5oZWlnaHQgLSB0b3AgKyB0aGlzLl92aWV3cG9ydE1hcmdpbjtcbiAgICB9IGVsc2UgaWYgKHBvc2l0aW9uLm92ZXJsYXlZID09PSAnYm90dG9tJykge1xuICAgICAgLy8gT3ZlcmxheSBpcyBvcGVuaW5nIFwidXB3YXJkXCIgYW5kIHRodXMgaXMgYm91bmQgYnkgdGhlIHRvcCB2aWV3cG9ydCBlZGdlLiBXZSBuZWVkIHRvIGFkZFxuICAgICAgLy8gdGhlIHZpZXdwb3J0IG1hcmdpbiBiYWNrIGluLCBiZWNhdXNlIHRoZSB2aWV3cG9ydCByZWN0IGlzIG5hcnJvd2VkIGRvd24gdG8gcmVtb3ZlIHRoZVxuICAgICAgLy8gbWFyZ2luLCB3aGVyZWFzIHRoZSBgb3JpZ2luYCBwb3NpdGlvbiBpcyBjYWxjdWxhdGVkIGJhc2VkIG9uIGl0cyBgQ2xpZW50UmVjdGAuXG4gICAgICBib3R0b20gPSB2aWV3cG9ydC5oZWlnaHQgLSBvcmlnaW4ueSArIHRoaXMuX3ZpZXdwb3J0TWFyZ2luICogMjtcbiAgICAgIGhlaWdodCA9IHZpZXdwb3J0LmhlaWdodCAtIGJvdHRvbSArIHRoaXMuX3ZpZXdwb3J0TWFyZ2luO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJZiBuZWl0aGVyIHRvcCBub3IgYm90dG9tLCBpdCBtZWFucyB0aGF0IHRoZSBvdmVybGF5IGlzIHZlcnRpY2FsbHkgY2VudGVyZWQgb24gdGhlXG4gICAgICAvLyBvcmlnaW4gcG9pbnQuIE5vdGUgdGhhdCB3ZSB3YW50IHRoZSBwb3NpdGlvbiByZWxhdGl2ZSB0byB0aGUgdmlld3BvcnQsIHJhdGhlciB0aGFuXG4gICAgICAvLyB0aGUgcGFnZSwgd2hpY2ggaXMgd2h5IHdlIGRvbid0IHVzZSBzb21ldGhpbmcgbGlrZSBgdmlld3BvcnQuYm90dG9tIC0gb3JpZ2luLnlgIGFuZFxuICAgICAgLy8gYG9yaWdpbi55IC0gdmlld3BvcnQudG9wYC5cbiAgICAgIGNvbnN0IHNtYWxsZXN0RGlzdGFuY2VUb1ZpZXdwb3J0RWRnZSA9XG4gICAgICAgICAgTWF0aC5taW4odmlld3BvcnQuYm90dG9tIC0gb3JpZ2luLnkgKyB2aWV3cG9ydC50b3AsIG9yaWdpbi55KTtcblxuICAgICAgY29uc3QgcHJldmlvdXNIZWlnaHQgPSB0aGlzLl9sYXN0Qm91bmRpbmdCb3hTaXplLmhlaWdodDtcblxuICAgICAgaGVpZ2h0ID0gc21hbGxlc3REaXN0YW5jZVRvVmlld3BvcnRFZGdlICogMjtcbiAgICAgIHRvcCA9IG9yaWdpbi55IC0gc21hbGxlc3REaXN0YW5jZVRvVmlld3BvcnRFZGdlO1xuXG4gICAgICBpZiAoaGVpZ2h0ID4gcHJldmlvdXNIZWlnaHQgJiYgIXRoaXMuX2lzSW5pdGlhbFJlbmRlciAmJiAhdGhpcy5fZ3Jvd0FmdGVyT3Blbikge1xuICAgICAgICB0b3AgPSBvcmlnaW4ueSAtIChwcmV2aW91c0hlaWdodCAvIDIpO1xuICAgICAgfVxuICAgIH1cblxuICAgIC8vIFRoZSBvdmVybGF5IGlzIG9wZW5pbmcgJ3JpZ2h0LXdhcmQnICh0aGUgY29udGVudCBmbG93cyB0byB0aGUgcmlnaHQpLlxuICAgIGNvbnN0IGlzQm91bmRlZEJ5UmlnaHRWaWV3cG9ydEVkZ2UgPVxuICAgICAgICAocG9zaXRpb24ub3ZlcmxheVggPT09ICdzdGFydCcgJiYgIWlzUnRsKSB8fFxuICAgICAgICAocG9zaXRpb24ub3ZlcmxheVggPT09ICdlbmQnICYmIGlzUnRsKTtcblxuICAgIC8vIFRoZSBvdmVybGF5IGlzIG9wZW5pbmcgJ2xlZnQtd2FyZCcgKHRoZSBjb250ZW50IGZsb3dzIHRvIHRoZSBsZWZ0KS5cbiAgICBjb25zdCBpc0JvdW5kZWRCeUxlZnRWaWV3cG9ydEVkZ2UgPVxuICAgICAgICAocG9zaXRpb24ub3ZlcmxheVggPT09ICdlbmQnICYmICFpc1J0bCkgfHxcbiAgICAgICAgKHBvc2l0aW9uLm92ZXJsYXlYID09PSAnc3RhcnQnICYmIGlzUnRsKTtcblxuICAgIGxldCB3aWR0aDogbnVtYmVyLCBsZWZ0OiBudW1iZXIsIHJpZ2h0OiBudW1iZXI7XG5cbiAgICBpZiAoaXNCb3VuZGVkQnlMZWZ0Vmlld3BvcnRFZGdlKSB7XG4gICAgICByaWdodCA9IHZpZXdwb3J0LndpZHRoIC0gb3JpZ2luLnggKyB0aGlzLl92aWV3cG9ydE1hcmdpbjtcbiAgICAgIHdpZHRoID0gb3JpZ2luLnggLSB0aGlzLl92aWV3cG9ydE1hcmdpbjtcbiAgICB9IGVsc2UgaWYgKGlzQm91bmRlZEJ5UmlnaHRWaWV3cG9ydEVkZ2UpIHtcbiAgICAgIGxlZnQgPSBvcmlnaW4ueDtcbiAgICAgIHdpZHRoID0gdmlld3BvcnQucmlnaHQgLSBvcmlnaW4ueDtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gSWYgbmVpdGhlciBzdGFydCBub3IgZW5kLCBpdCBtZWFucyB0aGF0IHRoZSBvdmVybGF5IGlzIGhvcml6b250YWxseSBjZW50ZXJlZCBvbiB0aGVcbiAgICAgIC8vIG9yaWdpbiBwb2ludC4gTm90ZSB0aGF0IHdlIHdhbnQgdGhlIHBvc2l0aW9uIHJlbGF0aXZlIHRvIHRoZSB2aWV3cG9ydCwgcmF0aGVyIHRoYW5cbiAgICAgIC8vIHRoZSBwYWdlLCB3aGljaCBpcyB3aHkgd2UgZG9uJ3QgdXNlIHNvbWV0aGluZyBsaWtlIGB2aWV3cG9ydC5yaWdodCAtIG9yaWdpbi54YCBhbmRcbiAgICAgIC8vIGBvcmlnaW4ueCAtIHZpZXdwb3J0LmxlZnRgLlxuICAgICAgY29uc3Qgc21hbGxlc3REaXN0YW5jZVRvVmlld3BvcnRFZGdlID1cbiAgICAgICAgICBNYXRoLm1pbih2aWV3cG9ydC5yaWdodCAtIG9yaWdpbi54ICsgdmlld3BvcnQubGVmdCwgb3JpZ2luLngpO1xuICAgICAgY29uc3QgcHJldmlvdXNXaWR0aCA9IHRoaXMuX2xhc3RCb3VuZGluZ0JveFNpemUud2lkdGg7XG5cbiAgICAgIHdpZHRoID0gc21hbGxlc3REaXN0YW5jZVRvVmlld3BvcnRFZGdlICogMjtcbiAgICAgIGxlZnQgPSBvcmlnaW4ueCAtIHNtYWxsZXN0RGlzdGFuY2VUb1ZpZXdwb3J0RWRnZTtcblxuICAgICAgaWYgKHdpZHRoID4gcHJldmlvdXNXaWR0aCAmJiAhdGhpcy5faXNJbml0aWFsUmVuZGVyICYmICF0aGlzLl9ncm93QWZ0ZXJPcGVuKSB7XG4gICAgICAgIGxlZnQgPSBvcmlnaW4ueCAtIChwcmV2aW91c1dpZHRoIC8gMik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHt0b3A6IHRvcCEsIGxlZnQ6IGxlZnQhLCBib3R0b206IGJvdHRvbSEsIHJpZ2h0OiByaWdodCEsIHdpZHRoLCBoZWlnaHR9O1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIHBvc2l0aW9uIGFuZCBzaXplIG9mIHRoZSBvdmVybGF5J3Mgc2l6aW5nIHdyYXBwZXIuIFRoZSB3cmFwcGVyIGlzIHBvc2l0aW9uZWQgb24gdGhlXG4gICAqIG9yaWdpbidzIGNvbm5lY3Rpb24gcG9pbnQgYW5kIHN0ZXRjaGVzIHRvIHRoZSBib3VuZHMgb2YgdGhlIHZpZXdwb3J0LlxuICAgKlxuICAgKiBAcGFyYW0gb3JpZ2luIFRoZSBwb2ludCBvbiB0aGUgb3JpZ2luIGVsZW1lbnQgd2hlcmUgdGhlIG92ZXJsYXkgaXMgY29ubmVjdGVkLlxuICAgKiBAcGFyYW0gcG9zaXRpb24gVGhlIHBvc2l0aW9uIHByZWZlcmVuY2VcbiAgICovXG4gIHByaXZhdGUgX3NldEJvdW5kaW5nQm94U3R5bGVzKG9yaWdpbjogUG9pbnQsIHBvc2l0aW9uOiBDb25uZWN0ZWRQb3NpdGlvbik6IHZvaWQge1xuICAgIGNvbnN0IGJvdW5kaW5nQm94UmVjdCA9IHRoaXMuX2NhbGN1bGF0ZUJvdW5kaW5nQm94UmVjdChvcmlnaW4sIHBvc2l0aW9uKTtcblxuICAgIC8vIEl0J3Mgd2VpcmQgaWYgdGhlIG92ZXJsYXkgKmdyb3dzKiB3aGlsZSBzY3JvbGxpbmcsIHNvIHdlIHRha2UgdGhlIGxhc3Qgc2l6ZSBpbnRvIGFjY291bnRcbiAgICAvLyB3aGVuIGFwcGx5aW5nIGEgbmV3IHNpemUuXG4gICAgaWYgKCF0aGlzLl9pc0luaXRpYWxSZW5kZXIgJiYgIXRoaXMuX2dyb3dBZnRlck9wZW4pIHtcbiAgICAgIGJvdW5kaW5nQm94UmVjdC5oZWlnaHQgPSBNYXRoLm1pbihib3VuZGluZ0JveFJlY3QuaGVpZ2h0LCB0aGlzLl9sYXN0Qm91bmRpbmdCb3hTaXplLmhlaWdodCk7XG4gICAgICBib3VuZGluZ0JveFJlY3Qud2lkdGggPSBNYXRoLm1pbihib3VuZGluZ0JveFJlY3Qud2lkdGgsIHRoaXMuX2xhc3RCb3VuZGluZ0JveFNpemUud2lkdGgpO1xuICAgIH1cblxuICAgIGNvbnN0IHN0eWxlcyA9IHt9IGFzIENTU1N0eWxlRGVjbGFyYXRpb247XG5cbiAgICBpZiAodGhpcy5faGFzRXhhY3RQb3NpdGlvbigpKSB7XG4gICAgICBzdHlsZXMudG9wID0gc3R5bGVzLmxlZnQgPSAnMCc7XG4gICAgICBzdHlsZXMuYm90dG9tID0gc3R5bGVzLnJpZ2h0ID0gc3R5bGVzLm1heEhlaWdodCA9IHN0eWxlcy5tYXhXaWR0aCA9ICcnO1xuICAgICAgc3R5bGVzLndpZHRoID0gc3R5bGVzLmhlaWdodCA9ICcxMDAlJztcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgbWF4SGVpZ2h0ID0gdGhpcy5fb3ZlcmxheVJlZi5nZXRDb25maWcoKS5tYXhIZWlnaHQ7XG4gICAgICBjb25zdCBtYXhXaWR0aCA9IHRoaXMuX292ZXJsYXlSZWYuZ2V0Q29uZmlnKCkubWF4V2lkdGg7XG5cbiAgICAgIHN0eWxlcy5oZWlnaHQgPSBjb2VyY2VDc3NQaXhlbFZhbHVlKGJvdW5kaW5nQm94UmVjdC5oZWlnaHQpO1xuICAgICAgc3R5bGVzLnRvcCA9IGNvZXJjZUNzc1BpeGVsVmFsdWUoYm91bmRpbmdCb3hSZWN0LnRvcCk7XG4gICAgICBzdHlsZXMuYm90dG9tID0gY29lcmNlQ3NzUGl4ZWxWYWx1ZShib3VuZGluZ0JveFJlY3QuYm90dG9tKTtcbiAgICAgIHN0eWxlcy53aWR0aCA9IGNvZXJjZUNzc1BpeGVsVmFsdWUoYm91bmRpbmdCb3hSZWN0LndpZHRoKTtcbiAgICAgIHN0eWxlcy5sZWZ0ID0gY29lcmNlQ3NzUGl4ZWxWYWx1ZShib3VuZGluZ0JveFJlY3QubGVmdCk7XG4gICAgICBzdHlsZXMucmlnaHQgPSBjb2VyY2VDc3NQaXhlbFZhbHVlKGJvdW5kaW5nQm94UmVjdC5yaWdodCk7XG5cbiAgICAgIC8vIFB1c2ggdGhlIHBhbmUgY29udGVudCB0b3dhcmRzIHRoZSBwcm9wZXIgZGlyZWN0aW9uLlxuICAgICAgaWYgKHBvc2l0aW9uLm92ZXJsYXlYID09PSAnY2VudGVyJykge1xuICAgICAgICBzdHlsZXMuYWxpZ25JdGVtcyA9ICdjZW50ZXInO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3R5bGVzLmFsaWduSXRlbXMgPSBwb3NpdGlvbi5vdmVybGF5WCA9PT0gJ2VuZCcgPyAnZmxleC1lbmQnIDogJ2ZsZXgtc3RhcnQnO1xuICAgICAgfVxuXG4gICAgICBpZiAocG9zaXRpb24ub3ZlcmxheVkgPT09ICdjZW50ZXInKSB7XG4gICAgICAgIHN0eWxlcy5qdXN0aWZ5Q29udGVudCA9ICdjZW50ZXInO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3R5bGVzLmp1c3RpZnlDb250ZW50ID0gcG9zaXRpb24ub3ZlcmxheVkgPT09ICdib3R0b20nID8gJ2ZsZXgtZW5kJyA6ICdmbGV4LXN0YXJ0JztcbiAgICAgIH1cblxuICAgICAgaWYgKG1heEhlaWdodCkge1xuICAgICAgICBzdHlsZXMubWF4SGVpZ2h0ID0gY29lcmNlQ3NzUGl4ZWxWYWx1ZShtYXhIZWlnaHQpO1xuICAgICAgfVxuXG4gICAgICBpZiAobWF4V2lkdGgpIHtcbiAgICAgICAgc3R5bGVzLm1heFdpZHRoID0gY29lcmNlQ3NzUGl4ZWxWYWx1ZShtYXhXaWR0aCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5fbGFzdEJvdW5kaW5nQm94U2l6ZSA9IGJvdW5kaW5nQm94UmVjdDtcblxuICAgIGV4dGVuZFN0eWxlcyh0aGlzLl9ib3VuZGluZ0JveCEuc3R5bGUsIHN0eWxlcyk7XG4gIH1cblxuICAvKiogUmVzZXRzIHRoZSBzdHlsZXMgZm9yIHRoZSBib3VuZGluZyBib3ggc28gdGhhdCBhIG5ldyBwb3NpdGlvbmluZyBjYW4gYmUgY29tcHV0ZWQuICovXG4gIHByaXZhdGUgX3Jlc2V0Qm91bmRpbmdCb3hTdHlsZXMoKSB7XG4gICAgZXh0ZW5kU3R5bGVzKHRoaXMuX2JvdW5kaW5nQm94IS5zdHlsZSwge1xuICAgICAgdG9wOiAnMCcsXG4gICAgICBsZWZ0OiAnMCcsXG4gICAgICByaWdodDogJzAnLFxuICAgICAgYm90dG9tOiAnMCcsXG4gICAgICBoZWlnaHQ6ICcnLFxuICAgICAgd2lkdGg6ICcnLFxuICAgICAgYWxpZ25JdGVtczogJycsXG4gICAgICBqdXN0aWZ5Q29udGVudDogJycsXG4gICAgfSBhcyBDU1NTdHlsZURlY2xhcmF0aW9uKTtcbiAgfVxuXG4gIC8qKiBSZXNldHMgdGhlIHN0eWxlcyBmb3IgdGhlIG92ZXJsYXkgcGFuZSBzbyB0aGF0IGEgbmV3IHBvc2l0aW9uaW5nIGNhbiBiZSBjb21wdXRlZC4gKi9cbiAgcHJpdmF0ZSBfcmVzZXRPdmVybGF5RWxlbWVudFN0eWxlcygpIHtcbiAgICBleHRlbmRTdHlsZXModGhpcy5fcGFuZS5zdHlsZSwge1xuICAgICAgdG9wOiAnJyxcbiAgICAgIGxlZnQ6ICcnLFxuICAgICAgYm90dG9tOiAnJyxcbiAgICAgIHJpZ2h0OiAnJyxcbiAgICAgIHBvc2l0aW9uOiAnJyxcbiAgICAgIHRyYW5zZm9ybTogJycsXG4gICAgfSBhcyBDU1NTdHlsZURlY2xhcmF0aW9uKTtcbiAgfVxuXG4gIC8qKiBTZXRzIHBvc2l0aW9uaW5nIHN0eWxlcyB0byB0aGUgb3ZlcmxheSBlbGVtZW50LiAqL1xuICBwcml2YXRlIF9zZXRPdmVybGF5RWxlbWVudFN0eWxlcyhvcmlnaW5Qb2ludDogUG9pbnQsIHBvc2l0aW9uOiBDb25uZWN0ZWRQb3NpdGlvbik6IHZvaWQge1xuICAgIGNvbnN0IHN0eWxlcyA9IHt9IGFzIENTU1N0eWxlRGVjbGFyYXRpb247XG4gICAgY29uc3QgaGFzRXhhY3RQb3NpdGlvbiA9IHRoaXMuX2hhc0V4YWN0UG9zaXRpb24oKTtcbiAgICBjb25zdCBoYXNGbGV4aWJsZURpbWVuc2lvbnMgPSB0aGlzLl9oYXNGbGV4aWJsZURpbWVuc2lvbnM7XG4gICAgY29uc3QgY29uZmlnID0gdGhpcy5fb3ZlcmxheVJlZi5nZXRDb25maWcoKTtcblxuICAgIGlmIChoYXNFeGFjdFBvc2l0aW9uKSB7XG4gICAgICBjb25zdCBzY3JvbGxQb3NpdGlvbiA9IHRoaXMuX3ZpZXdwb3J0UnVsZXIuZ2V0Vmlld3BvcnRTY3JvbGxQb3NpdGlvbigpO1xuICAgICAgZXh0ZW5kU3R5bGVzKHN0eWxlcywgdGhpcy5fZ2V0RXhhY3RPdmVybGF5WShwb3NpdGlvbiwgb3JpZ2luUG9pbnQsIHNjcm9sbFBvc2l0aW9uKSk7XG4gICAgICBleHRlbmRTdHlsZXMoc3R5bGVzLCB0aGlzLl9nZXRFeGFjdE92ZXJsYXlYKHBvc2l0aW9uLCBvcmlnaW5Qb2ludCwgc2Nyb2xsUG9zaXRpb24pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc3R5bGVzLnBvc2l0aW9uID0gJ3N0YXRpYyc7XG4gICAgfVxuXG4gICAgLy8gVXNlIGEgdHJhbnNmb3JtIHRvIGFwcGx5IHRoZSBvZmZzZXRzLiBXZSBkbyB0aGlzIGJlY2F1c2UgdGhlIGBjZW50ZXJgIHBvc2l0aW9ucyByZWx5IG9uXG4gICAgLy8gYmVpbmcgaW4gdGhlIG5vcm1hbCBmbGV4IGZsb3cgYW5kIHNldHRpbmcgYSBgdG9wYCAvIGBsZWZ0YCBhdCBhbGwgd2lsbCBjb21wbGV0ZWx5IHRocm93XG4gICAgLy8gb2ZmIHRoZSBwb3NpdGlvbi4gV2UgYWxzbyBjYW4ndCB1c2UgbWFyZ2lucywgYmVjYXVzZSB0aGV5IHdvbid0IGhhdmUgYW4gZWZmZWN0IGluIHNvbWVcbiAgICAvLyBjYXNlcyB3aGVyZSB0aGUgZWxlbWVudCBkb2Vzbid0IGhhdmUgYW55dGhpbmcgdG8gXCJwdXNoIG9mZiBvZlwiLiBGaW5hbGx5LCB0aGlzIHdvcmtzXG4gICAgLy8gYmV0dGVyIGJvdGggd2l0aCBmbGV4aWJsZSBhbmQgbm9uLWZsZXhpYmxlIHBvc2l0aW9uaW5nLlxuICAgIGxldCB0cmFuc2Zvcm1TdHJpbmcgPSAnJztcbiAgICBsZXQgb2Zmc2V0WCA9IHRoaXMuX2dldE9mZnNldChwb3NpdGlvbiwgJ3gnKTtcbiAgICBsZXQgb2Zmc2V0WSA9IHRoaXMuX2dldE9mZnNldChwb3NpdGlvbiwgJ3knKTtcblxuICAgIGlmIChvZmZzZXRYKSB7XG4gICAgICB0cmFuc2Zvcm1TdHJpbmcgKz0gYHRyYW5zbGF0ZVgoJHtvZmZzZXRYfXB4KSBgO1xuICAgIH1cblxuICAgIGlmIChvZmZzZXRZKSB7XG4gICAgICB0cmFuc2Zvcm1TdHJpbmcgKz0gYHRyYW5zbGF0ZVkoJHtvZmZzZXRZfXB4KWA7XG4gICAgfVxuXG4gICAgc3R5bGVzLnRyYW5zZm9ybSA9IHRyYW5zZm9ybVN0cmluZy50cmltKCk7XG5cbiAgICAvLyBJZiBhIG1heFdpZHRoIG9yIG1heEhlaWdodCBpcyBzcGVjaWZpZWQgb24gdGhlIG92ZXJsYXksIHdlIHJlbW92ZSB0aGVtLiBXZSBkbyB0aGlzIGJlY2F1c2VcbiAgICAvLyB3ZSBuZWVkIHRoZXNlIHZhbHVlcyB0byBib3RoIGJlIHNldCB0byBcIjEwMCVcIiBmb3IgdGhlIGF1dG9tYXRpYyBmbGV4aWJsZSBzaXppbmcgdG8gd29yay5cbiAgICAvLyBUaGUgbWF4SGVpZ2h0IGFuZCBtYXhXaWR0aCBhcmUgc2V0IG9uIHRoZSBib3VuZGluZ0JveCBpbiBvcmRlciB0byBlbmZvcmNlIHRoZSBjb25zdHJhaW50LlxuICAgIC8vIE5vdGUgdGhhdCB0aGlzIGRvZXNuJ3QgYXBwbHkgd2hlbiB3ZSBoYXZlIGFuIGV4YWN0IHBvc2l0aW9uLCBpbiB3aGljaCBjYXNlIHdlIGRvIHdhbnQgdG9cbiAgICAvLyBhcHBseSB0aGVtIGJlY2F1c2UgdGhleSdsbCBiZSBjbGVhcmVkIGZyb20gdGhlIGJvdW5kaW5nIGJveC5cbiAgICBpZiAoY29uZmlnLm1heEhlaWdodCkge1xuICAgICAgaWYgKGhhc0V4YWN0UG9zaXRpb24pIHtcbiAgICAgICAgc3R5bGVzLm1heEhlaWdodCA9IGNvZXJjZUNzc1BpeGVsVmFsdWUoY29uZmlnLm1heEhlaWdodCk7XG4gICAgICB9IGVsc2UgaWYgKGhhc0ZsZXhpYmxlRGltZW5zaW9ucykge1xuICAgICAgICBzdHlsZXMubWF4SGVpZ2h0ID0gJyc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGNvbmZpZy5tYXhXaWR0aCkge1xuICAgICAgaWYgKGhhc0V4YWN0UG9zaXRpb24pIHtcbiAgICAgICAgc3R5bGVzLm1heFdpZHRoID0gY29lcmNlQ3NzUGl4ZWxWYWx1ZShjb25maWcubWF4V2lkdGgpO1xuICAgICAgfSBlbHNlIGlmIChoYXNGbGV4aWJsZURpbWVuc2lvbnMpIHtcbiAgICAgICAgc3R5bGVzLm1heFdpZHRoID0gJyc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZXh0ZW5kU3R5bGVzKHRoaXMuX3BhbmUuc3R5bGUsIHN0eWxlcyk7XG4gIH1cblxuICAvKiogR2V0cyB0aGUgZXhhY3QgdG9wL2JvdHRvbSBmb3IgdGhlIG92ZXJsYXkgd2hlbiBub3QgdXNpbmcgZmxleGlibGUgc2l6aW5nIG9yIHdoZW4gcHVzaGluZy4gKi9cbiAgcHJpdmF0ZSBfZ2V0RXhhY3RPdmVybGF5WShwb3NpdGlvbjogQ29ubmVjdGVkUG9zaXRpb24sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgb3JpZ2luUG9pbnQ6IFBvaW50LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHNjcm9sbFBvc2l0aW9uOiBWaWV3cG9ydFNjcm9sbFBvc2l0aW9uKSB7XG4gICAgLy8gUmVzZXQgYW55IGV4aXN0aW5nIHN0eWxlcy4gVGhpcyBpcyBuZWNlc3NhcnkgaW4gY2FzZSB0aGVcbiAgICAvLyBwcmVmZXJyZWQgcG9zaXRpb24gaGFzIGNoYW5nZWQgc2luY2UgdGhlIGxhc3QgYGFwcGx5YC5cbiAgICBsZXQgc3R5bGVzID0ge3RvcDogJycsIGJvdHRvbTogJyd9IGFzIENTU1N0eWxlRGVjbGFyYXRpb247XG4gICAgbGV0IG92ZXJsYXlQb2ludCA9IHRoaXMuX2dldE92ZXJsYXlQb2ludChvcmlnaW5Qb2ludCwgdGhpcy5fb3ZlcmxheVJlY3QsIHBvc2l0aW9uKTtcblxuICAgIGlmICh0aGlzLl9pc1B1c2hlZCkge1xuICAgICAgb3ZlcmxheVBvaW50ID0gdGhpcy5fcHVzaE92ZXJsYXlPblNjcmVlbihvdmVybGF5UG9pbnQsIHRoaXMuX292ZXJsYXlSZWN0LCBzY3JvbGxQb3NpdGlvbik7XG4gICAgfVxuXG4gICAgbGV0IHZpcnR1YWxLZXlib2FyZE9mZnNldCA9XG4gICAgICAgIHRoaXMuX292ZXJsYXlDb250YWluZXIuZ2V0Q29udGFpbmVyRWxlbWVudCgpLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLnRvcDtcblxuICAgIC8vIE5vcm1hbGx5IHRoaXMgd291bGQgYmUgemVybywgaG93ZXZlciB3aGVuIHRoZSBvdmVybGF5IGlzIGF0dGFjaGVkIHRvIGFuIGlucHV0IChlLmcuIGluIGFuXG4gICAgLy8gYXV0b2NvbXBsZXRlKSwgbW9iaWxlIGJyb3dzZXJzIHdpbGwgc2hpZnQgZXZlcnl0aGluZyBpbiBvcmRlciB0byBwdXQgdGhlIGlucHV0IGluIHRoZSBtaWRkbGVcbiAgICAvLyBvZiB0aGUgc2NyZWVuIGFuZCB0byBtYWtlIHNwYWNlIGZvciB0aGUgdmlydHVhbCBrZXlib2FyZC4gV2UgbmVlZCB0byBhY2NvdW50IGZvciB0aGlzIG9mZnNldCxcbiAgICAvLyBvdGhlcndpc2Ugb3VyIHBvc2l0aW9uaW5nIHdpbGwgYmUgdGhyb3duIG9mZi5cbiAgICBvdmVybGF5UG9pbnQueSAtPSB2aXJ0dWFsS2V5Ym9hcmRPZmZzZXQ7XG5cbiAgICAvLyBXZSB3YW50IHRvIHNldCBlaXRoZXIgYHRvcGAgb3IgYGJvdHRvbWAgYmFzZWQgb24gd2hldGhlciB0aGUgb3ZlcmxheSB3YW50cyB0byBhcHBlYXJcbiAgICAvLyBhYm92ZSBvciBiZWxvdyB0aGUgb3JpZ2luIGFuZCB0aGUgZGlyZWN0aW9uIGluIHdoaWNoIHRoZSBlbGVtZW50IHdpbGwgZXhwYW5kLlxuICAgIGlmIChwb3NpdGlvbi5vdmVybGF5WSA9PT0gJ2JvdHRvbScpIHtcbiAgICAgIC8vIFdoZW4gdXNpbmcgYGJvdHRvbWAsIHdlIGFkanVzdCB0aGUgeSBwb3NpdGlvbiBzdWNoIHRoYXQgaXQgaXMgdGhlIGRpc3RhbmNlXG4gICAgICAvLyBmcm9tIHRoZSBib3R0b20gb2YgdGhlIHZpZXdwb3J0IHJhdGhlciB0aGFuIHRoZSB0b3AuXG4gICAgICBjb25zdCBkb2N1bWVudEhlaWdodCA9IHRoaXMuX2RvY3VtZW50LmRvY3VtZW50RWxlbWVudCEuY2xpZW50SGVpZ2h0O1xuICAgICAgc3R5bGVzLmJvdHRvbSA9IGAke2RvY3VtZW50SGVpZ2h0IC0gKG92ZXJsYXlQb2ludC55ICsgdGhpcy5fb3ZlcmxheVJlY3QuaGVpZ2h0KX1weGA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0eWxlcy50b3AgPSBjb2VyY2VDc3NQaXhlbFZhbHVlKG92ZXJsYXlQb2ludC55KTtcbiAgICB9XG5cbiAgICByZXR1cm4gc3R5bGVzO1xuICB9XG5cbiAgLyoqIEdldHMgdGhlIGV4YWN0IGxlZnQvcmlnaHQgZm9yIHRoZSBvdmVybGF5IHdoZW4gbm90IHVzaW5nIGZsZXhpYmxlIHNpemluZyBvciB3aGVuIHB1c2hpbmcuICovXG4gIHByaXZhdGUgX2dldEV4YWN0T3ZlcmxheVgocG9zaXRpb246IENvbm5lY3RlZFBvc2l0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9yaWdpblBvaW50OiBQb2ludCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBzY3JvbGxQb3NpdGlvbjogVmlld3BvcnRTY3JvbGxQb3NpdGlvbikge1xuICAgIC8vIFJlc2V0IGFueSBleGlzdGluZyBzdHlsZXMuIFRoaXMgaXMgbmVjZXNzYXJ5IGluIGNhc2UgdGhlIHByZWZlcnJlZCBwb3NpdGlvbiBoYXNcbiAgICAvLyBjaGFuZ2VkIHNpbmNlIHRoZSBsYXN0IGBhcHBseWAuXG4gICAgbGV0IHN0eWxlcyA9IHtsZWZ0OiAnJywgcmlnaHQ6ICcnfSBhcyBDU1NTdHlsZURlY2xhcmF0aW9uO1xuICAgIGxldCBvdmVybGF5UG9pbnQgPSB0aGlzLl9nZXRPdmVybGF5UG9pbnQob3JpZ2luUG9pbnQsIHRoaXMuX292ZXJsYXlSZWN0LCBwb3NpdGlvbik7XG5cbiAgICBpZiAodGhpcy5faXNQdXNoZWQpIHtcbiAgICAgIG92ZXJsYXlQb2ludCA9IHRoaXMuX3B1c2hPdmVybGF5T25TY3JlZW4ob3ZlcmxheVBvaW50LCB0aGlzLl9vdmVybGF5UmVjdCwgc2Nyb2xsUG9zaXRpb24pO1xuICAgIH1cblxuICAgIC8vIFdlIHdhbnQgdG8gc2V0IGVpdGhlciBgbGVmdGAgb3IgYHJpZ2h0YCBiYXNlZCBvbiB3aGV0aGVyIHRoZSBvdmVybGF5IHdhbnRzIHRvIGFwcGVhciBcImJlZm9yZVwiXG4gICAgLy8gb3IgXCJhZnRlclwiIHRoZSBvcmlnaW4sIHdoaWNoIGRldGVybWluZXMgdGhlIGRpcmVjdGlvbiBpbiB3aGljaCB0aGUgZWxlbWVudCB3aWxsIGV4cGFuZC5cbiAgICAvLyBGb3IgdGhlIGhvcml6b250YWwgYXhpcywgdGhlIG1lYW5pbmcgb2YgXCJiZWZvcmVcIiBhbmQgXCJhZnRlclwiIGNoYW5nZSBiYXNlZCBvbiB3aGV0aGVyIHRoZVxuICAgIC8vIHBhZ2UgaXMgaW4gUlRMIG9yIExUUi5cbiAgICBsZXQgaG9yaXpvbnRhbFN0eWxlUHJvcGVydHk6ICdsZWZ0JyB8ICdyaWdodCc7XG5cbiAgICBpZiAodGhpcy5faXNSdGwoKSkge1xuICAgICAgaG9yaXpvbnRhbFN0eWxlUHJvcGVydHkgPSBwb3NpdGlvbi5vdmVybGF5WCA9PT0gJ2VuZCcgPyAnbGVmdCcgOiAncmlnaHQnO1xuICAgIH0gZWxzZSB7XG4gICAgICBob3Jpem9udGFsU3R5bGVQcm9wZXJ0eSA9IHBvc2l0aW9uLm92ZXJsYXlYID09PSAnZW5kJyA/ICdyaWdodCcgOiAnbGVmdCc7XG4gICAgfVxuXG4gICAgLy8gV2hlbiB3ZSdyZSBzZXR0aW5nIGByaWdodGAsIHdlIGFkanVzdCB0aGUgeCBwb3NpdGlvbiBzdWNoIHRoYXQgaXQgaXMgdGhlIGRpc3RhbmNlXG4gICAgLy8gZnJvbSB0aGUgcmlnaHQgZWRnZSBvZiB0aGUgdmlld3BvcnQgcmF0aGVyIHRoYW4gdGhlIGxlZnQgZWRnZS5cbiAgICBpZiAoaG9yaXpvbnRhbFN0eWxlUHJvcGVydHkgPT09ICdyaWdodCcpIHtcbiAgICAgIGNvbnN0IGRvY3VtZW50V2lkdGggPSB0aGlzLl9kb2N1bWVudC5kb2N1bWVudEVsZW1lbnQhLmNsaWVudFdpZHRoO1xuICAgICAgc3R5bGVzLnJpZ2h0ID0gYCR7ZG9jdW1lbnRXaWR0aCAtIChvdmVybGF5UG9pbnQueCArIHRoaXMuX292ZXJsYXlSZWN0LndpZHRoKX1weGA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0eWxlcy5sZWZ0ID0gY29lcmNlQ3NzUGl4ZWxWYWx1ZShvdmVybGF5UG9pbnQueCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHN0eWxlcztcbiAgfVxuXG4gIC8qKlxuICAgKiBHZXRzIHRoZSB2aWV3IHByb3BlcnRpZXMgb2YgdGhlIHRyaWdnZXIgYW5kIG92ZXJsYXksIGluY2x1ZGluZyB3aGV0aGVyIHRoZXkgYXJlIGNsaXBwZWRcbiAgICogb3IgY29tcGxldGVseSBvdXRzaWRlIHRoZSB2aWV3IG9mIGFueSBvZiB0aGUgc3RyYXRlZ3kncyBzY3JvbGxhYmxlcy5cbiAgICovXG4gIHByaXZhdGUgX2dldFNjcm9sbFZpc2liaWxpdHkoKTogU2Nyb2xsaW5nVmlzaWJpbGl0eSB7XG4gICAgLy8gTm90ZTogbmVlZHMgZnJlc2ggcmVjdHMgc2luY2UgdGhlIHBvc2l0aW9uIGNvdWxkJ3ZlIGNoYW5nZWQuXG4gICAgY29uc3Qgb3JpZ2luQm91bmRzID0gdGhpcy5fZ2V0T3JpZ2luUmVjdCgpO1xuICAgIGNvbnN0IG92ZXJsYXlCb3VuZHMgPSAgdGhpcy5fcGFuZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIC8vIFRPRE8oamVsYm91cm4pOiBpbnN0ZWFkIG9mIG5lZWRpbmcgYWxsIG9mIHRoZSBjbGllbnQgcmVjdHMgZm9yIHRoZXNlIHNjcm9sbGluZyBjb250YWluZXJzXG4gICAgLy8gZXZlcnkgdGltZSwgd2Ugc2hvdWxkIGJlIGFibGUgdG8gdXNlIHRoZSBzY3JvbGxUb3Agb2YgdGhlIGNvbnRhaW5lcnMgaWYgdGhlIHNpemUgb2YgdGhvc2VcbiAgICAvLyBjb250YWluZXJzIGhhc24ndCBjaGFuZ2VkLlxuICAgIGNvbnN0IHNjcm9sbENvbnRhaW5lckJvdW5kcyA9IHRoaXMuX3Njcm9sbGFibGVzLm1hcChzY3JvbGxhYmxlID0+IHtcbiAgICAgIHJldHVybiBzY3JvbGxhYmxlLmdldEVsZW1lbnRSZWYoKS5uYXRpdmVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHtcbiAgICAgIGlzT3JpZ2luQ2xpcHBlZDogaXNFbGVtZW50Q2xpcHBlZEJ5U2Nyb2xsaW5nKG9yaWdpbkJvdW5kcywgc2Nyb2xsQ29udGFpbmVyQm91bmRzKSxcbiAgICAgIGlzT3JpZ2luT3V0c2lkZVZpZXc6IGlzRWxlbWVudFNjcm9sbGVkT3V0c2lkZVZpZXcob3JpZ2luQm91bmRzLCBzY3JvbGxDb250YWluZXJCb3VuZHMpLFxuICAgICAgaXNPdmVybGF5Q2xpcHBlZDogaXNFbGVtZW50Q2xpcHBlZEJ5U2Nyb2xsaW5nKG92ZXJsYXlCb3VuZHMsIHNjcm9sbENvbnRhaW5lckJvdW5kcyksXG4gICAgICBpc092ZXJsYXlPdXRzaWRlVmlldzogaXNFbGVtZW50U2Nyb2xsZWRPdXRzaWRlVmlldyhvdmVybGF5Qm91bmRzLCBzY3JvbGxDb250YWluZXJCb3VuZHMpLFxuICAgIH07XG4gIH1cblxuICAvKiogU3VidHJhY3RzIHRoZSBhbW91bnQgdGhhdCBhbiBlbGVtZW50IGlzIG92ZXJmbG93aW5nIG9uIGFuIGF4aXMgZnJvbSBpdHMgbGVuZ3RoLiAqL1xuICBwcml2YXRlIF9zdWJ0cmFjdE92ZXJmbG93cyhsZW5ndGg6IG51bWJlciwgLi4ub3ZlcmZsb3dzOiBudW1iZXJbXSk6IG51bWJlciB7XG4gICAgcmV0dXJuIG92ZXJmbG93cy5yZWR1Y2UoKGN1cnJlbnRWYWx1ZTogbnVtYmVyLCBjdXJyZW50T3ZlcmZsb3c6IG51bWJlcikgPT4ge1xuICAgICAgcmV0dXJuIGN1cnJlbnRWYWx1ZSAtIE1hdGgubWF4KGN1cnJlbnRPdmVyZmxvdywgMCk7XG4gICAgfSwgbGVuZ3RoKTtcbiAgfVxuXG4gIC8qKiBOYXJyb3dzIHRoZSBnaXZlbiB2aWV3cG9ydCByZWN0IGJ5IHRoZSBjdXJyZW50IF92aWV3cG9ydE1hcmdpbi4gKi9cbiAgcHJpdmF0ZSBfZ2V0TmFycm93ZWRWaWV3cG9ydFJlY3QoKTogQ2xpZW50UmVjdCB7XG4gICAgLy8gV2UgcmVjYWxjdWxhdGUgdGhlIHZpZXdwb3J0IHJlY3QgaGVyZSBvdXJzZWx2ZXMsIHJhdGhlciB0aGFuIHVzaW5nIHRoZSBWaWV3cG9ydFJ1bGVyLFxuICAgIC8vIGJlY2F1c2Ugd2Ugd2FudCB0byB1c2UgdGhlIGBjbGllbnRXaWR0aGAgYW5kIGBjbGllbnRIZWlnaHRgIGFzIHRoZSBiYXNlLiBUaGUgZGlmZmVyZW5jZVxuICAgIC8vIGJlaW5nIHRoYXQgdGhlIGNsaWVudCBwcm9wZXJ0aWVzIGRvbid0IGluY2x1ZGUgdGhlIHNjcm9sbGJhciwgYXMgb3Bwb3NlZCB0byBgaW5uZXJXaWR0aGBcbiAgICAvLyBhbmQgYGlubmVySGVpZ2h0YCB0aGF0IGRvLiBUaGlzIGlzIG5lY2Vzc2FyeSwgYmVjYXVzZSB0aGUgb3ZlcmxheSBjb250YWluZXIgdXNlc1xuICAgIC8vIDEwMCUgYHdpZHRoYCBhbmQgYGhlaWdodGAgd2hpY2ggZG9uJ3QgaW5jbHVkZSB0aGUgc2Nyb2xsYmFyIGVpdGhlci5cbiAgICBjb25zdCB3aWR0aCA9IHRoaXMuX2RvY3VtZW50LmRvY3VtZW50RWxlbWVudCEuY2xpZW50V2lkdGg7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5fZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50IS5jbGllbnRIZWlnaHQ7XG4gICAgY29uc3Qgc2Nyb2xsUG9zaXRpb24gPSB0aGlzLl92aWV3cG9ydFJ1bGVyLmdldFZpZXdwb3J0U2Nyb2xsUG9zaXRpb24oKTtcblxuICAgIHJldHVybiB7XG4gICAgICB0b3A6ICAgIHNjcm9sbFBvc2l0aW9uLnRvcCArIHRoaXMuX3ZpZXdwb3J0TWFyZ2luLFxuICAgICAgbGVmdDogICBzY3JvbGxQb3NpdGlvbi5sZWZ0ICsgdGhpcy5fdmlld3BvcnRNYXJnaW4sXG4gICAgICByaWdodDogIHNjcm9sbFBvc2l0aW9uLmxlZnQgKyB3aWR0aCAtIHRoaXMuX3ZpZXdwb3J0TWFyZ2luLFxuICAgICAgYm90dG9tOiBzY3JvbGxQb3NpdGlvbi50b3AgKyBoZWlnaHQgLSB0aGlzLl92aWV3cG9ydE1hcmdpbixcbiAgICAgIHdpZHRoOiAgd2lkdGggIC0gKDIgKiB0aGlzLl92aWV3cG9ydE1hcmdpbiksXG4gICAgICBoZWlnaHQ6IGhlaWdodCAtICgyICogdGhpcy5fdmlld3BvcnRNYXJnaW4pLFxuICAgIH07XG4gIH1cblxuICAvKiogV2hldGhlciB0aGUgd2UncmUgZGVhbGluZyB3aXRoIGFuIFJUTCBjb250ZXh0ICovXG4gIHByaXZhdGUgX2lzUnRsKCkge1xuICAgIHJldHVybiB0aGlzLl9vdmVybGF5UmVmLmdldERpcmVjdGlvbigpID09PSAncnRsJztcbiAgfVxuXG4gIC8qKiBEZXRlcm1pbmVzIHdoZXRoZXIgdGhlIG92ZXJsYXkgdXNlcyBleGFjdCBvciBmbGV4aWJsZSBwb3NpdGlvbmluZy4gKi9cbiAgcHJpdmF0ZSBfaGFzRXhhY3RQb3NpdGlvbigpIHtcbiAgICByZXR1cm4gIXRoaXMuX2hhc0ZsZXhpYmxlRGltZW5zaW9ucyB8fCB0aGlzLl9pc1B1c2hlZDtcbiAgfVxuXG4gIC8qKiBSZXRyaWV2ZXMgdGhlIG9mZnNldCBvZiBhIHBvc2l0aW9uIGFsb25nIHRoZSB4IG9yIHkgYXhpcy4gKi9cbiAgcHJpdmF0ZSBfZ2V0T2Zmc2V0KHBvc2l0aW9uOiBDb25uZWN0ZWRQb3NpdGlvbiwgYXhpczogJ3gnIHwgJ3knKSB7XG4gICAgaWYgKGF4aXMgPT09ICd4Jykge1xuICAgICAgLy8gV2UgZG9uJ3QgZG8gc29tZXRoaW5nIGxpa2UgYHBvc2l0aW9uWydvZmZzZXQnICsgYXhpc11gIGluXG4gICAgICAvLyBvcmRlciB0byBhdm9pZCBicmVraW5nIG1pbmlmaWVycyB0aGF0IHJlbmFtZSBwcm9wZXJ0aWVzLlxuICAgICAgcmV0dXJuIHBvc2l0aW9uLm9mZnNldFggPT0gbnVsbCA/IHRoaXMuX29mZnNldFggOiBwb3NpdGlvbi5vZmZzZXRYO1xuICAgIH1cblxuICAgIHJldHVybiBwb3NpdGlvbi5vZmZzZXRZID09IG51bGwgPyB0aGlzLl9vZmZzZXRZIDogcG9zaXRpb24ub2Zmc2V0WTtcbiAgfVxuXG4gIC8qKiBWYWxpZGF0ZXMgdGhhdCB0aGUgY3VycmVudCBwb3NpdGlvbiBtYXRjaCB0aGUgZXhwZWN0ZWQgdmFsdWVzLiAqL1xuICBwcml2YXRlIF92YWxpZGF0ZVBvc2l0aW9ucygpOiB2b2lkIHtcbiAgICBpZiAodHlwZW9mIG5nRGV2TW9kZSA9PT0gJ3VuZGVmaW5lZCcgfHwgbmdEZXZNb2RlKSB7XG4gICAgICBpZiAoIXRoaXMuX3ByZWZlcnJlZFBvc2l0aW9ucy5sZW5ndGgpIHtcbiAgICAgICAgdGhyb3cgRXJyb3IoJ0ZsZXhpYmxlQ29ubmVjdGVkUG9zaXRpb25TdHJhdGVneTogQXQgbGVhc3Qgb25lIHBvc2l0aW9uIGlzIHJlcXVpcmVkLicpO1xuICAgICAgfVxuXG4gICAgICAvLyBUT0RPKGNyaXNiZXRvKTogcmVtb3ZlIHRoZXNlIG9uY2UgQW5ndWxhcidzIHRlbXBsYXRlIHR5cGVcbiAgICAgIC8vIGNoZWNraW5nIGlzIGFkdmFuY2VkIGVub3VnaCB0byBjYXRjaCB0aGVzZSBjYXNlcy5cbiAgICAgIHRoaXMuX3ByZWZlcnJlZFBvc2l0aW9ucy5mb3JFYWNoKHBhaXIgPT4ge1xuICAgICAgICB2YWxpZGF0ZUhvcml6b250YWxQb3NpdGlvbignb3JpZ2luWCcsIHBhaXIub3JpZ2luWCk7XG4gICAgICAgIHZhbGlkYXRlVmVydGljYWxQb3NpdGlvbignb3JpZ2luWScsIHBhaXIub3JpZ2luWSk7XG4gICAgICAgIHZhbGlkYXRlSG9yaXpvbnRhbFBvc2l0aW9uKCdvdmVybGF5WCcsIHBhaXIub3ZlcmxheVgpO1xuICAgICAgICB2YWxpZGF0ZVZlcnRpY2FsUG9zaXRpb24oJ292ZXJsYXlZJywgcGFpci5vdmVybGF5WSk7XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKiogQWRkcyBhIHNpbmdsZSBDU1MgY2xhc3Mgb3IgYW4gYXJyYXkgb2YgY2xhc3NlcyBvbiB0aGUgb3ZlcmxheSBwYW5lbC4gKi9cbiAgcHJpdmF0ZSBfYWRkUGFuZWxDbGFzc2VzKGNzc0NsYXNzZXM6IHN0cmluZyB8IHN0cmluZ1tdKSB7XG4gICAgaWYgKHRoaXMuX3BhbmUpIHtcbiAgICAgIGNvZXJjZUFycmF5KGNzc0NsYXNzZXMpLmZvckVhY2goY3NzQ2xhc3MgPT4ge1xuICAgICAgICBpZiAoY3NzQ2xhc3MgIT09ICcnICYmIHRoaXMuX2FwcGxpZWRQYW5lbENsYXNzZXMuaW5kZXhPZihjc3NDbGFzcykgPT09IC0xKSB7XG4gICAgICAgICAgdGhpcy5fYXBwbGllZFBhbmVsQ2xhc3Nlcy5wdXNoKGNzc0NsYXNzKTtcbiAgICAgICAgICB0aGlzLl9wYW5lLmNsYXNzTGlzdC5hZGQoY3NzQ2xhc3MpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9XG4gIH1cblxuICAvKiogQ2xlYXJzIHRoZSBjbGFzc2VzIHRoYXQgdGhlIHBvc2l0aW9uIHN0cmF0ZWd5IGhhcyBhcHBsaWVkIGZyb20gdGhlIG92ZXJsYXkgcGFuZWwuICovXG4gIHByaXZhdGUgX2NsZWFyUGFuZWxDbGFzc2VzKCkge1xuICAgIGlmICh0aGlzLl9wYW5lKSB7XG4gICAgICB0aGlzLl9hcHBsaWVkUGFuZWxDbGFzc2VzLmZvckVhY2goY3NzQ2xhc3MgPT4ge1xuICAgICAgICB0aGlzLl9wYW5lLmNsYXNzTGlzdC5yZW1vdmUoY3NzQ2xhc3MpO1xuICAgICAgfSk7XG4gICAgICB0aGlzLl9hcHBsaWVkUGFuZWxDbGFzc2VzID0gW107XG4gICAgfVxuICB9XG5cbiAgLyoqIFJldHVybnMgdGhlIENsaWVudFJlY3Qgb2YgdGhlIGN1cnJlbnQgb3JpZ2luLiAqL1xuICBwcml2YXRlIF9nZXRPcmlnaW5SZWN0KCk6IENsaWVudFJlY3Qge1xuICAgIGNvbnN0IG9yaWdpbiA9IHRoaXMuX29yaWdpbjtcblxuICAgIGlmIChvcmlnaW4gaW5zdGFuY2VvZiBFbGVtZW50UmVmKSB7XG4gICAgICByZXR1cm4gb3JpZ2luLm5hdGl2ZUVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgfVxuXG4gICAgLy8gQ2hlY2sgZm9yIEVsZW1lbnQgc28gU1ZHIGVsZW1lbnRzIGFyZSBhbHNvIHN1cHBvcnRlZC5cbiAgICBpZiAob3JpZ2luIGluc3RhbmNlb2YgRWxlbWVudCkge1xuICAgICAgcmV0dXJuIG9yaWdpbi5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICB9XG5cbiAgICBjb25zdCB3aWR0aCA9IG9yaWdpbi53aWR0aCB8fCAwO1xuICAgIGNvbnN0IGhlaWdodCA9IG9yaWdpbi5oZWlnaHQgfHwgMDtcblxuICAgIC8vIElmIHRoZSBvcmlnaW4gaXMgYSBwb2ludCwgcmV0dXJuIGEgY2xpZW50IHJlY3QgYXMgaWYgaXQgd2FzIGEgMHgwIGVsZW1lbnQgYXQgdGhlIHBvaW50LlxuICAgIHJldHVybiB7XG4gICAgICB0b3A6IG9yaWdpbi55LFxuICAgICAgYm90dG9tOiBvcmlnaW4ueSArIGhlaWdodCxcbiAgICAgIGxlZnQ6IG9yaWdpbi54LFxuICAgICAgcmlnaHQ6IG9yaWdpbi54ICsgd2lkdGgsXG4gICAgICBoZWlnaHQsXG4gICAgICB3aWR0aFxuICAgIH07XG4gIH1cbn1cblxuLyoqIEEgc2ltcGxlICh4LCB5KSBjb29yZGluYXRlLiAqL1xuaW50ZXJmYWNlIFBvaW50IHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG59XG5cbi8qKiBSZWNvcmQgb2YgbWVhc3VyZW1lbnRzIGZvciBob3cgYW4gb3ZlcmxheSAoYXQgYSBnaXZlbiBwb3NpdGlvbikgZml0cyBpbnRvIHRoZSB2aWV3cG9ydC4gKi9cbmludGVyZmFjZSBPdmVybGF5Rml0IHtcbiAgLyoqIFdoZXRoZXIgdGhlIG92ZXJsYXkgZml0cyBjb21wbGV0ZWx5IGluIHRoZSB2aWV3cG9ydC4gKi9cbiAgaXNDb21wbGV0ZWx5V2l0aGluVmlld3BvcnQ6IGJvb2xlYW47XG5cbiAgLyoqIFdoZXRoZXIgdGhlIG92ZXJsYXkgZml0cyBpbiB0aGUgdmlld3BvcnQgb24gdGhlIHktYXhpcy4gKi9cbiAgZml0c0luVmlld3BvcnRWZXJ0aWNhbGx5OiBib29sZWFuO1xuXG4gIC8qKiBXaGV0aGVyIHRoZSBvdmVybGF5IGZpdHMgaW4gdGhlIHZpZXdwb3J0IG9uIHRoZSB4LWF4aXMuICovXG4gIGZpdHNJblZpZXdwb3J0SG9yaXpvbnRhbGx5OiBib29sZWFuO1xuXG4gIC8qKiBUaGUgdG90YWwgdmlzaWJsZSBhcmVhIChpbiBweF4yKSBvZiB0aGUgb3ZlcmxheSBpbnNpZGUgdGhlIHZpZXdwb3J0LiAqL1xuICB2aXNpYmxlQXJlYTogbnVtYmVyO1xufVxuXG4vKiogUmVjb3JkIG9mIHRoZSBtZWFzdXJtZW50cyBkZXRlcm1pbmluZyB3aGV0aGVyIGFuIG92ZXJsYXkgd2lsbCBmaXQgaW4gYSBzcGVjaWZpYyBwb3NpdGlvbi4gKi9cbmludGVyZmFjZSBGYWxsYmFja1Bvc2l0aW9uIHtcbiAgcG9zaXRpb246IENvbm5lY3RlZFBvc2l0aW9uO1xuICBvcmlnaW5Qb2ludDogUG9pbnQ7XG4gIG92ZXJsYXlQb2ludDogUG9pbnQ7XG4gIG92ZXJsYXlGaXQ6IE92ZXJsYXlGaXQ7XG4gIG92ZXJsYXlSZWN0OiBDbGllbnRSZWN0O1xufVxuXG4vKiogUG9zaXRpb24gYW5kIHNpemUgb2YgdGhlIG92ZXJsYXkgc2l6aW5nIHdyYXBwZXIgZm9yIGEgc3BlY2lmaWMgcG9zaXRpb24uICovXG5pbnRlcmZhY2UgQm91bmRpbmdCb3hSZWN0IHtcbiAgdG9wOiBudW1iZXI7XG4gIGxlZnQ6IG51bWJlcjtcbiAgYm90dG9tOiBudW1iZXI7XG4gIHJpZ2h0OiBudW1iZXI7XG4gIGhlaWdodDogbnVtYmVyO1xuICB3aWR0aDogbnVtYmVyO1xufVxuXG4vKiogUmVjb3JkIG9mIG1lYXN1cmVzIGRldGVybWluaW5nIGhvdyB3ZWxsIGEgZ2l2ZW4gcG9zaXRpb24gd2lsbCBmaXQgd2l0aCBmbGV4aWJsZSBkaW1lbnNpb25zLiAqL1xuaW50ZXJmYWNlIEZsZXhpYmxlRml0IHtcbiAgcG9zaXRpb246IENvbm5lY3RlZFBvc2l0aW9uO1xuICBvcmlnaW46IFBvaW50O1xuICBvdmVybGF5UmVjdDogQ2xpZW50UmVjdDtcbiAgYm91bmRpbmdCb3hSZWN0OiBCb3VuZGluZ0JveFJlY3Q7XG59XG5cbi8qKiBBIGNvbm5lY3RlZCBwb3NpdGlvbiBhcyBzcGVjaWZpZWQgYnkgdGhlIHVzZXIuICovXG5leHBvcnQgaW50ZXJmYWNlIENvbm5lY3RlZFBvc2l0aW9uIHtcbiAgb3JpZ2luWDogJ3N0YXJ0JyB8ICdjZW50ZXInIHwgJ2VuZCc7XG4gIG9yaWdpblk6ICd0b3AnIHwgJ2NlbnRlcicgfCAnYm90dG9tJztcblxuICBvdmVybGF5WDogJ3N0YXJ0JyB8ICdjZW50ZXInIHwgJ2VuZCc7XG4gIG92ZXJsYXlZOiAndG9wJyB8ICdjZW50ZXInIHwgJ2JvdHRvbSc7XG5cbiAgd2VpZ2h0PzogbnVtYmVyO1xuICBvZmZzZXRYPzogbnVtYmVyO1xuICBvZmZzZXRZPzogbnVtYmVyO1xuICBwYW5lbENsYXNzPzogc3RyaW5nIHwgc3RyaW5nW107XG59XG5cbi8qKiBTaGFsbG93LWV4dGVuZHMgYSBzdHlsZXNoZWV0IG9iamVjdCB3aXRoIGFub3RoZXIgc3R5bGVzaGVldCBvYmplY3QuICovXG5mdW5jdGlvbiBleHRlbmRTdHlsZXMoZGVzdGluYXRpb246IENTU1N0eWxlRGVjbGFyYXRpb24sXG4gICAgICAgICAgICAgICAgICAgICAgc291cmNlOiBDU1NTdHlsZURlY2xhcmF0aW9uKTogQ1NTU3R5bGVEZWNsYXJhdGlvbiB7XG4gIGZvciAobGV0IGtleSBpbiBzb3VyY2UpIHtcbiAgICBpZiAoc291cmNlLmhhc093blByb3BlcnR5KGtleSkpIHtcbiAgICAgIGRlc3RpbmF0aW9uW2tleV0gPSBzb3VyY2Vba2V5XTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZGVzdGluYXRpb247XG59XG5cblxuLyoqXG4gKiBFeHRyYWN0cyB0aGUgcGl4ZWwgdmFsdWUgYXMgYSBudW1iZXIgZnJvbSBhIHZhbHVlLCBpZiBpdCdzIGEgbnVtYmVyXG4gKiBvciBhIENTUyBwaXhlbCBzdHJpbmcgKGUuZy4gYDEzMzdweGApLiBPdGhlcndpc2UgcmV0dXJucyBudWxsLlxuICovXG5mdW5jdGlvbiBnZXRQaXhlbFZhbHVlKGlucHV0OiBudW1iZXJ8c3RyaW5nfG51bGx8dW5kZWZpbmVkKTogbnVtYmVyfG51bGwge1xuICBpZiAodHlwZW9mIGlucHV0ICE9PSAnbnVtYmVyJyAmJiBpbnB1dCAhPSBudWxsKSB7XG4gICAgY29uc3QgW3ZhbHVlLCB1bml0c10gPSBpbnB1dC5zcGxpdChjc3NVbml0UGF0dGVybik7XG4gICAgcmV0dXJuICghdW5pdHMgfHwgdW5pdHMgPT09ICdweCcpID8gcGFyc2VGbG9hdCh2YWx1ZSkgOiBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGlucHV0IHx8IG51bGw7XG59XG5cbi8qKlxuICogR2V0cyBhIHZlcnNpb24gb2YgYW4gZWxlbWVudCdzIGJvdW5kaW5nIGBDbGllbnRSZWN0YCB3aGVyZSBhbGwgdGhlIHZhbHVlcyBhcmUgcm91bmRlZCBkb3duIHRvXG4gKiB0aGUgbmVhcmVzdCBwaXhlbC4gVGhpcyBhbGxvd3MgdXMgdG8gYWNjb3VudCBmb3IgdGhlIGNhc2VzIHdoZXJlIHRoZXJlIG1heSBiZSBzdWItcGl4ZWxcbiAqIGRldmlhdGlvbnMgaW4gdGhlIGBDbGllbnRSZWN0YCByZXR1cm5lZCBieSB0aGUgYnJvd3NlciAoZS5nLiB3aGVuIHpvb21lZCBpbiB3aXRoIGEgcGVyY2VudGFnZVxuICogc2l6ZSwgc2VlICMyMTM1MCkuXG4gKi9cbmZ1bmN0aW9uIGdldFJvdW5kZWRCb3VuZGluZ0NsaWVudFJlY3QoY2xpZW50UmVjdDogQ2xpZW50UmVjdCk6IENsaWVudFJlY3Qge1xuICByZXR1cm4ge1xuICAgIHRvcDogTWF0aC5mbG9vcihjbGllbnRSZWN0LnRvcCksXG4gICAgcmlnaHQ6IE1hdGguZmxvb3IoY2xpZW50UmVjdC5yaWdodCksXG4gICAgYm90dG9tOiBNYXRoLmZsb29yKGNsaWVudFJlY3QuYm90dG9tKSxcbiAgICBsZWZ0OiBNYXRoLmZsb29yKGNsaWVudFJlY3QubGVmdCksXG4gICAgd2lkdGg6IE1hdGguZmxvb3IoY2xpZW50UmVjdC53aWR0aCksXG4gICAgaGVpZ2h0OiBNYXRoLmZsb29yKGNsaWVudFJlY3QuaGVpZ2h0KVxuICB9O1xufVxuIl19