@angular/cdk 13.0.0-next.6 → 13.0.0-rc.1

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 (796) hide show
  1. package/a11y/a11y-module.d.ts +9 -7
  2. package/a11y/aria-describer/aria-describer.d.ts +3 -7
  3. package/a11y/focus-monitor/focus-monitor.d.ts +5 -0
  4. package/a11y/focus-trap/configurable-focus-trap-factory.d.ts +3 -7
  5. package/a11y/focus-trap/focus-trap-manager.d.ts +3 -7
  6. package/a11y/focus-trap/focus-trap.d.ts +5 -0
  7. package/a11y/high-contrast-mode/high-contrast-mode-detector.d.ts +3 -0
  8. package/a11y/index.d.ts +0 -1
  9. package/a11y/input-modality/input-modality-detector.d.ts +3 -7
  10. package/a11y/interactivity-checker/interactivity-checker.d.ts +3 -0
  11. package/a11y/live-announcer/live-announcer.d.ts +6 -1
  12. package/a11y/package.json +5 -5
  13. package/accordion/accordion-item.d.ts +3 -0
  14. package/accordion/accordion-module.d.ts +6 -7
  15. package/accordion/accordion.d.ts +3 -0
  16. package/accordion/index.d.ts +0 -1
  17. package/accordion/package.json +5 -5
  18. package/bidi/bidi-module.d.ts +5 -7
  19. package/bidi/dir.d.ts +3 -0
  20. package/bidi/directionality.d.ts +3 -0
  21. package/bidi/index.d.ts +0 -1
  22. package/bidi/package.json +5 -5
  23. package/clipboard/clipboard-module.d.ts +5 -7
  24. package/clipboard/clipboard.d.ts +3 -7
  25. package/clipboard/copy-to-clipboard.d.ts +3 -0
  26. package/clipboard/package.json +5 -5
  27. package/coercion/package.json +5 -5
  28. package/collections/package.json +5 -5
  29. package/collections/unique-selection-dispatcher.d.ts +3 -0
  30. package/drag-drop/client-rect.d.ts +8 -1
  31. package/drag-drop/directives/drag-handle.d.ts +3 -0
  32. package/drag-drop/directives/drag-placeholder.d.ts +3 -0
  33. package/drag-drop/directives/drag-preview.d.ts +3 -0
  34. package/drag-drop/directives/drag.d.ts +3 -0
  35. package/drag-drop/directives/drop-list-group.d.ts +3 -0
  36. package/drag-drop/directives/drop-list.d.ts +3 -0
  37. package/drag-drop/drag-drop-module.d.ts +11 -7
  38. package/drag-drop/drag-drop-registry.d.ts +3 -0
  39. package/drag-drop/drag-drop.d.ts +3 -0
  40. package/drag-drop/index.d.ts +0 -1
  41. package/drag-drop/package.json +5 -5
  42. package/esm2020/a11y/a11y-module.mjs +33 -0
  43. package/esm2020/a11y/aria-describer/aria-describer.mjs +208 -0
  44. package/{esm2015/a11y/aria-describer/aria-reference.js → esm2020/a11y/aria-describer/aria-reference.mjs} +1 -1
  45. package/esm2020/a11y/fake-event-detection.mjs +29 -0
  46. package/esm2020/a11y/focus-monitor/focus-monitor.mjs +400 -0
  47. package/{esm2015/a11y/focus-trap/configurable-focus-trap-config.js → esm2020/a11y/focus-trap/configurable-focus-trap-config.mjs} +0 -0
  48. package/esm2020/a11y/focus-trap/configurable-focus-trap-factory.mjs +53 -0
  49. package/esm2020/a11y/focus-trap/configurable-focus-trap.mjs +51 -0
  50. package/esm2020/a11y/focus-trap/event-listener-inert-strategy.mjs +61 -0
  51. package/esm2020/a11y/focus-trap/focus-trap-inert-strategy.mjs +11 -0
  52. package/esm2020/a11y/focus-trap/focus-trap-manager.mjs +53 -0
  53. package/esm2020/a11y/focus-trap/focus-trap.mjs +399 -0
  54. package/esm2020/a11y/high-contrast-mode/high-contrast-mode-detector.mjs +95 -0
  55. package/esm2020/a11y/index.mjs +5 -0
  56. package/esm2020/a11y/input-modality/input-modality-detector.mjs +176 -0
  57. package/esm2020/a11y/interactivity-checker/interactivity-checker.mjs +238 -0
  58. package/{esm2015/a11y/key-manager/activedescendant-key-manager.js → esm2020/a11y/key-manager/activedescendant-key-manager.mjs} +1 -1
  59. package/{esm2015/a11y/key-manager/focus-key-manager.js → esm2020/a11y/key-manager/focus-key-manager.mjs} +0 -0
  60. package/esm2020/a11y/key-manager/list-key-manager.mjs +321 -0
  61. package/esm2020/a11y/live-announcer/live-announcer-tokens.mjs +19 -0
  62. package/esm2020/a11y/live-announcer/live-announcer.mjs +170 -0
  63. package/{esm2015/a11y/public-api.js → esm2020/a11y/public-api.mjs} +0 -0
  64. package/esm2020/accordion/accordion-item.mjs +167 -0
  65. package/esm2020/accordion/accordion-module.mjs +24 -0
  66. package/esm2020/accordion/accordion.mjs +70 -0
  67. package/esm2020/accordion/index.mjs +5 -0
  68. package/{esm2015/accordion/public-api.js → esm2020/accordion/public-api.mjs} +0 -0
  69. package/esm2020/bidi/bidi-module.mjs +23 -0
  70. package/{esm2015/bidi/dir-document-token.js → esm2020/bidi/dir-document-token.mjs} +1 -1
  71. package/esm2020/bidi/dir.mjs +67 -0
  72. package/esm2020/bidi/directionality.mjs +47 -0
  73. package/esm2020/bidi/index.mjs +5 -0
  74. package/{esm2015/bidi/public-api.js → esm2020/bidi/public-api.mjs} +1 -1
  75. package/esm2020/clipboard/clipboard-module.mjs +23 -0
  76. package/esm2020/clipboard/clipboard.mjs +53 -0
  77. package/esm2020/clipboard/copy-to-clipboard.mjs +99 -0
  78. package/{esm2015/clipboard/index.js → esm2020/clipboard/index.mjs} +0 -0
  79. package/esm2020/clipboard/pending-copy.mjs +67 -0
  80. package/{esm2015/clipboard/public-api.js → esm2020/clipboard/public-api.mjs} +0 -0
  81. package/{esm2015/coercion/array.js → esm2020/coercion/array.mjs} +0 -0
  82. package/{esm2015/coercion/boolean-property.js → esm2020/coercion/boolean-property.mjs} +0 -0
  83. package/{esm2015/coercion/css-pixel-value.js → esm2020/coercion/css-pixel-value.mjs} +0 -0
  84. package/{esm2015/coercion/element.js → esm2020/coercion/element.mjs} +0 -0
  85. package/{esm2015/coercion/index.js → esm2020/coercion/index.mjs} +0 -0
  86. package/{esm2015/coercion/number-property.js → esm2020/coercion/number-property.mjs} +0 -0
  87. package/{esm2015/coercion/public-api.js → esm2020/coercion/public-api.mjs} +0 -0
  88. package/{esm2015/coercion/string-array.js → esm2020/coercion/string-array.mjs} +0 -0
  89. package/{esm2015/collections/array-data-source.js → esm2020/collections/array-data-source.mjs} +1 -1
  90. package/esm2020/collections/collection-viewer.mjs +9 -0
  91. package/{esm2015/collections/data-source.js → esm2020/collections/data-source.mjs} +0 -0
  92. package/esm2020/collections/dispose-view-repeater-strategy.mjs +47 -0
  93. package/{esm2015/collections/index.js → esm2020/collections/index.mjs} +0 -0
  94. package/{esm2015/collections/public-api.js → esm2020/collections/public-api.mjs} +0 -0
  95. package/esm2020/collections/recycle-view-repeater-strategy.mjs +128 -0
  96. package/{esm2015/collections/selection-model.js → esm2020/collections/selection-model.mjs} +2 -2
  97. package/esm2020/collections/tree-adapter.mjs +9 -0
  98. package/esm2020/collections/unique-selection-dispatcher.mjs +55 -0
  99. package/esm2020/collections/view-repeater.mjs +14 -0
  100. package/esm2020/drag-drop/client-rect.mjs +64 -0
  101. package/esm2020/drag-drop/clone-node.mjs +65 -0
  102. package/esm2020/drag-drop/directives/assertions.mjs +18 -0
  103. package/{esm2015/drag-drop/directives/config.js → esm2020/drag-drop/directives/config.mjs} +1 -1
  104. package/esm2020/drag-drop/directives/drag-handle.mjs +66 -0
  105. package/esm2020/drag-drop/directives/drag-placeholder.mjs +36 -0
  106. package/esm2020/drag-drop/directives/drag-preview.mjs +47 -0
  107. package/esm2020/drag-drop/directives/drag.mjs +483 -0
  108. package/esm2020/drag-drop/directives/drop-list-group.mjs +53 -0
  109. package/esm2020/drag-drop/directives/drop-list.mjs +344 -0
  110. package/esm2020/drag-drop/drag-drop-module.mjs +57 -0
  111. package/esm2020/drag-drop/drag-drop-registry.mjs +231 -0
  112. package/esm2020/drag-drop/drag-drop.mjs +57 -0
  113. package/esm2020/drag-drop/drag-events.mjs +9 -0
  114. package/{esm2015/drag-drop/drag-parent.js → esm2020/drag-drop/drag-parent.mjs} +0 -0
  115. package/esm2020/drag-drop/drag-ref.mjs +1108 -0
  116. package/esm2020/drag-drop/drag-styling.mjs +69 -0
  117. package/esm2020/drag-drop/drag-utils.mjs +60 -0
  118. package/esm2020/drag-drop/drop-list-ref.mjs +830 -0
  119. package/{esm2015/drag-drop/index.js → esm2020/drag-drop/index.mjs} +1 -1
  120. package/{esm2015/drag-drop/parent-position-tracker.js → esm2020/drag-drop/parent-position-tracker.mjs} +2 -2
  121. package/{esm2015/drag-drop/public-api.js → esm2020/drag-drop/public-api.mjs} +0 -0
  122. package/esm2020/drag-drop/transition-duration.mjs +36 -0
  123. package/{esm2015/index.js → esm2020/index.mjs} +0 -0
  124. package/{esm2015/keycodes/index.js → esm2020/keycodes/index.mjs} +0 -0
  125. package/{esm2015/keycodes/keycodes.js → esm2020/keycodes/keycodes.mjs} +1 -1
  126. package/{esm2015/keycodes/modifiers.js → esm2020/keycodes/modifiers.mjs} +0 -0
  127. package/{esm2015/keycodes/public-api.js → esm2020/keycodes/public-api.mjs} +0 -0
  128. package/esm2020/layout/breakpoints-observer.mjs +105 -0
  129. package/{esm2015/layout/breakpoints.js → esm2020/layout/breakpoints.mjs} +1 -1
  130. package/{esm2015/layout/index.js → esm2020/layout/index.mjs} +0 -0
  131. package/esm2020/layout/layout-module.mjs +19 -0
  132. package/esm2020/layout/media-matcher.mjs +85 -0
  133. package/{esm2015/layout/public-api.js → esm2020/layout/public-api.mjs} +0 -0
  134. package/{esm2015/observers/index.js → esm2020/observers/index.mjs} +0 -0
  135. package/esm2020/observers/observe-content.mjs +187 -0
  136. package/{esm2015/observers/public-api.js → esm2020/observers/public-api.mjs} +0 -0
  137. package/esm2020/overlay/dispatchers/base-overlay-dispatcher.mjs +52 -0
  138. package/{esm2015/overlay/dispatchers/index.js → esm2020/overlay/dispatchers/index.mjs} +0 -0
  139. package/esm2020/overlay/dispatchers/overlay-keyboard-dispatcher.mjs +63 -0
  140. package/esm2020/overlay/dispatchers/overlay-outside-click-dispatcher.mjs +116 -0
  141. package/esm2020/overlay/fullscreen-overlay-container.mjs +94 -0
  142. package/esm2020/overlay/index.mjs +5 -0
  143. package/esm2020/overlay/overlay-config.mjs +45 -0
  144. package/esm2020/overlay/overlay-container.mjs +81 -0
  145. package/esm2020/overlay/overlay-directives.mjs +427 -0
  146. package/esm2020/overlay/overlay-module.mjs +29 -0
  147. package/esm2020/overlay/overlay-ref.mjs +402 -0
  148. package/{esm2015/overlay/overlay-reference.js → esm2020/overlay/overlay-reference.mjs} +0 -0
  149. package/esm2020/overlay/overlay.mjs +119 -0
  150. package/esm2020/overlay/position/connected-position.mjs +97 -0
  151. package/esm2020/overlay/position/flexible-connected-position-strategy.mjs +959 -0
  152. package/esm2020/overlay/position/global-position-strategy.mjs +203 -0
  153. package/esm2020/overlay/position/overlay-position-builder.mjs +50 -0
  154. package/{esm2015/overlay/position/position-strategy.js → esm2020/overlay/position/position-strategy.mjs} +0 -0
  155. package/esm2020/overlay/position/scroll-clip.mjs +40 -0
  156. package/{esm2015/overlay/public-api.js → esm2020/overlay/public-api.mjs} +0 -0
  157. package/{esm2015/overlay/scroll/block-scroll-strategy.js → esm2020/overlay/scroll/block-scroll-strategy.mjs} +1 -1
  158. package/esm2020/overlay/scroll/close-scroll-strategy.mjs +61 -0
  159. package/{esm2015/overlay/scroll/index.js → esm2020/overlay/scroll/index.mjs} +2 -2
  160. package/{esm2015/overlay/scroll/noop-scroll-strategy.js → esm2020/overlay/scroll/noop-scroll-strategy.mjs} +1 -1
  161. package/{esm2015/overlay/scroll/reposition-scroll-strategy.js → esm2020/overlay/scroll/reposition-scroll-strategy.mjs} +1 -1
  162. package/esm2020/overlay/scroll/scroll-strategy-options.mjs +55 -0
  163. package/{esm2015/overlay/scroll/scroll-strategy.js → esm2020/overlay/scroll/scroll-strategy.mjs} +0 -0
  164. package/{esm2015/platform/features/input-types.js → esm2020/platform/features/input-types.mjs} +1 -1
  165. package/esm2020/platform/features/passive-listeners.mjs +36 -0
  166. package/esm2020/platform/features/scrolling.mjs +85 -0
  167. package/{esm2015/platform/features/shadow-dom.js → esm2020/platform/features/shadow-dom.mjs} +4 -3
  168. package/esm2020/platform/features/test-environment.mjs +27 -0
  169. package/{esm2015/platform/index.js → esm2020/platform/index.mjs} +0 -0
  170. package/esm2020/platform/platform-module.mjs +19 -0
  171. package/esm2020/platform/platform.mjs +85 -0
  172. package/{esm2015/platform/public-api.js → esm2020/platform/public-api.mjs} +0 -0
  173. package/esm2020/portal/dom-portal-outlet.mjs +134 -0
  174. package/{esm2015/portal/index.js → esm2020/portal/index.mjs} +0 -0
  175. package/esm2020/portal/portal-directives.mjs +244 -0
  176. package/{esm2015/portal/portal-errors.js → esm2020/portal/portal-errors.mjs} +1 -1
  177. package/esm2020/portal/portal-injector.mjs +28 -0
  178. package/esm2020/portal/portal.mjs +179 -0
  179. package/{esm2015/portal/public-api.js → esm2020/portal/public-api.mjs} +0 -0
  180. package/{esm2015/public-api.js → esm2020/public-api.mjs} +0 -0
  181. package/esm2020/scrolling/fixed-size-virtual-scroll.mjs +217 -0
  182. package/{esm2015/scrolling/index.js → esm2020/scrolling/index.mjs} +0 -0
  183. package/{esm2015/scrolling/public-api.js → esm2020/scrolling/public-api.mjs} +0 -0
  184. package/esm2020/scrolling/scroll-dispatcher.mjs +163 -0
  185. package/esm2020/scrolling/scrollable.mjs +176 -0
  186. package/esm2020/scrolling/scrolling-module.mjs +52 -0
  187. package/esm2020/scrolling/viewport-ruler.mjs +146 -0
  188. package/esm2020/scrolling/virtual-for-of.mjs +296 -0
  189. package/{esm2015/scrolling/virtual-scroll-repeater.js → esm2020/scrolling/virtual-scroll-repeater.mjs} +0 -0
  190. package/esm2020/scrolling/virtual-scroll-strategy.mjs +11 -0
  191. package/esm2020/scrolling/virtual-scroll-viewport.mjs +378 -0
  192. package/{esm2015/stepper/index.js → esm2020/stepper/index.mjs} +0 -0
  193. package/{esm2015/stepper/public-api.js → esm2020/stepper/public-api.mjs} +0 -0
  194. package/esm2020/stepper/step-header.mjs +30 -0
  195. package/esm2020/stepper/step-label.mjs +23 -0
  196. package/esm2020/stepper/stepper-button.mjs +76 -0
  197. package/esm2020/stepper/stepper-module.mjs +40 -0
  198. package/esm2020/stepper/stepper.mjs +471 -0
  199. package/esm2020/table/can-stick.mjs +44 -0
  200. package/esm2020/table/cell.mjs +222 -0
  201. package/esm2020/table/coalesced-style-scheduler.mjs +91 -0
  202. package/{esm2015/table/index.js → esm2020/table/index.mjs} +0 -0
  203. package/{esm2015/table/public-api.js → esm2020/table/public-api.mjs} +0 -0
  204. package/esm2020/table/row.mjs +254 -0
  205. package/esm2020/table/sticky-position-listener.mjs +11 -0
  206. package/esm2020/table/sticky-styler.mjs +345 -0
  207. package/{esm2015/table/table-errors.js → esm2020/table/table-errors.mjs} +1 -1
  208. package/esm2020/table/table-module.mjs +94 -0
  209. package/esm2020/table/table.mjs +1023 -0
  210. package/esm2020/table/text-column.mjs +153 -0
  211. package/{esm2015/table/tokens.js → esm2020/table/tokens.mjs} +1 -1
  212. package/esm2020/testing/change-detection.mjs +102 -0
  213. package/esm2020/testing/component-harness.mjs +322 -0
  214. package/{esm2015/testing/element-dimensions.js → esm2020/testing/element-dimensions.mjs} +1 -1
  215. package/esm2020/testing/harness-environment.mjs +202 -0
  216. package/{esm2015/testing/index.js → esm2020/testing/index.mjs} +0 -0
  217. package/{esm2015/testing/protractor/index.js → esm2020/testing/protractor/index.mjs} +0 -0
  218. package/esm2020/testing/protractor/protractor-element.mjs +234 -0
  219. package/esm2020/testing/protractor/protractor-harness-environment.mjs +72 -0
  220. package/{esm2015/testing/protractor/public-api.js → esm2020/testing/protractor/public-api.mjs} +0 -0
  221. package/{esm2015/testing/public-api.js → esm2020/testing/public-api.mjs} +0 -0
  222. package/{esm2015/testing/selenium-webdriver/index.js → esm2020/testing/selenium-webdriver/index.mjs} +0 -0
  223. package/{esm2015/testing/selenium-webdriver/public-api.js → esm2020/testing/selenium-webdriver/public-api.mjs} +0 -0
  224. package/esm2020/testing/selenium-webdriver/selenium-web-driver-element.mjs +199 -0
  225. package/esm2020/testing/selenium-webdriver/selenium-web-driver-harness-environment.mjs +87 -0
  226. package/{esm2015/testing/selenium-webdriver/selenium-webdriver-keys.js → esm2020/testing/selenium-webdriver/selenium-webdriver-keys.mjs} +2 -2
  227. package/esm2020/testing/test-element.mjs +48 -0
  228. package/esm2020/testing/testbed/fake-events/dispatch-events.mjs +53 -0
  229. package/esm2020/testing/testbed/fake-events/element-focus.mjs +39 -0
  230. package/esm2020/testing/testbed/fake-events/event-objects.mjs +113 -0
  231. package/{esm2015/testing/testbed/fake-events/index.js → esm2020/testing/testbed/fake-events/index.mjs} +0 -0
  232. package/esm2020/testing/testbed/fake-events/type-in-element.mjs +88 -0
  233. package/{esm2015/testing/testbed/index.js → esm2020/testing/testbed/index.mjs} +0 -0
  234. package/{esm2015/testing/testbed/public-api.js → esm2020/testing/testbed/public-api.mjs} +0 -0
  235. package/esm2020/testing/testbed/task-state-zone-interceptor.mjs +82 -0
  236. package/esm2020/testing/testbed/testbed-harness-environment.mjs +162 -0
  237. package/esm2020/testing/testbed/unit-test-element.mjs +224 -0
  238. package/esm2020/testing/text-filtering.mjs +21 -0
  239. package/esm2020/text-field/autofill.mjs +113 -0
  240. package/esm2020/text-field/autosize.mjs +310 -0
  241. package/{esm2015/text-field/index.js → esm2020/text-field/index.mjs} +0 -0
  242. package/{esm2015/text-field/public-api.js → esm2020/text-field/public-api.mjs} +0 -0
  243. package/esm2020/text-field/text-field-module.mjs +26 -0
  244. package/{esm2015/tree/control/base-tree-control.js → esm2020/tree/control/base-tree-control.mjs} +4 -4
  245. package/{esm2015/tree/control/flat-tree-control.js → esm2020/tree/control/flat-tree-control.mjs} +1 -1
  246. package/esm2020/tree/control/nested-tree-control.mjs +58 -0
  247. package/{esm2015/tree/control/tree-control.js → esm2020/tree/control/tree-control.mjs} +0 -0
  248. package/{esm2015/tree/index.js → esm2020/tree/index.mjs} +0 -0
  249. package/esm2020/tree/nested-node.mjs +117 -0
  250. package/esm2020/tree/node.mjs +35 -0
  251. package/esm2020/tree/outlet.mjs +39 -0
  252. package/esm2020/tree/padding.mjs +131 -0
  253. package/{esm2015/tree/public-api.js → esm2020/tree/public-api.mjs} +0 -0
  254. package/esm2020/tree/toggle.mjs +53 -0
  255. package/{esm2015/tree/tree-errors.js → esm2020/tree/tree-errors.mjs} +0 -0
  256. package/esm2020/tree/tree-module.mjs +49 -0
  257. package/esm2020/tree/tree.mjs +361 -0
  258. package/{esm2015/version.js → esm2020/version.mjs} +1 -1
  259. package/fesm2015/a11y.mjs +2356 -0
  260. package/fesm2015/a11y.mjs.map +1 -0
  261. package/fesm2015/accordion.mjs +267 -0
  262. package/fesm2015/accordion.mjs.map +1 -0
  263. package/fesm2015/bidi.mjs +179 -0
  264. package/fesm2015/bidi.mjs.map +1 -0
  265. package/fesm2015/{cdk.js → cdk.mjs} +2 -2
  266. package/fesm2015/cdk.mjs.map +1 -0
  267. package/fesm2015/clipboard.mjs +253 -0
  268. package/fesm2015/clipboard.mjs.map +1 -0
  269. package/fesm2015/{coercion.js → coercion.mjs} +1 -1
  270. package/fesm2015/coercion.mjs.map +1 -0
  271. package/fesm2015/{collections.js → collections.mjs} +15 -27
  272. package/fesm2015/collections.mjs.map +1 -0
  273. package/fesm2015/drag-drop.mjs +3667 -0
  274. package/fesm2015/drag-drop.mjs.map +1 -0
  275. package/fesm2015/{keycodes.js → keycodes.mjs} +1 -1
  276. package/fesm2015/keycodes.mjs.map +1 -0
  277. package/fesm2015/{layout.js → layout.mjs} +30 -28
  278. package/fesm2015/layout.mjs.map +1 -0
  279. package/fesm2015/{observers.js → observers.mjs} +50 -41
  280. package/fesm2015/observers.mjs.map +1 -0
  281. package/fesm2015/overlay.mjs +3004 -0
  282. package/fesm2015/overlay.mjs.map +1 -0
  283. package/fesm2015/platform.mjs +380 -0
  284. package/fesm2015/platform.mjs.map +1 -0
  285. package/fesm2015/portal.mjs +649 -0
  286. package/fesm2015/portal.mjs.map +1 -0
  287. package/fesm2015/scrolling.mjs +1394 -0
  288. package/fesm2015/scrolling.mjs.map +1 -0
  289. package/fesm2015/{stepper.js → stepper.mjs} +186 -133
  290. package/fesm2015/stepper.mjs.map +1 -0
  291. package/fesm2015/{table.js → table.mjs} +500 -359
  292. package/fesm2015/table.mjs.map +1 -0
  293. package/fesm2015/testing/{protractor.js → protractor.mjs} +12 -25
  294. package/fesm2015/testing/protractor.mjs.map +1 -0
  295. package/fesm2015/testing/{selenium-webdriver.js → selenium-webdriver.mjs} +14 -28
  296. package/fesm2015/testing/selenium-webdriver.mjs.map +1 -0
  297. package/fesm2015/testing/{testbed.js → testbed.mjs} +23 -29
  298. package/fesm2015/testing/testbed.mjs.map +1 -0
  299. package/fesm2015/{testing.js → testing.mjs} +19 -45
  300. package/fesm2015/testing.mjs.map +1 -0
  301. package/fesm2015/text-field.mjs +455 -0
  302. package/fesm2015/text-field.mjs.map +1 -0
  303. package/fesm2015/{tree.js → tree.mjs} +198 -152
  304. package/fesm2015/tree.mjs.map +1 -0
  305. package/{fesm2015/a11y.js → fesm2020/a11y.mjs} +272 -233
  306. package/fesm2020/a11y.mjs.map +1 -0
  307. package/{fesm2015/accordion.js → fesm2020/accordion.mjs} +87 -57
  308. package/fesm2020/accordion.mjs.map +1 -0
  309. package/{fesm2015/bidi.js → fesm2020/bidi.mjs} +47 -31
  310. package/fesm2020/bidi.mjs.map +1 -0
  311. package/fesm2020/cdk.mjs +30 -0
  312. package/fesm2020/cdk.mjs.map +1 -0
  313. package/{fesm2015/clipboard.js → fesm2020/clipboard.mjs} +51 -40
  314. package/fesm2020/clipboard.mjs.map +1 -0
  315. package/fesm2020/coercion.mjs +132 -0
  316. package/fesm2020/coercion.mjs.map +1 -0
  317. package/fesm2020/collections.mjs +472 -0
  318. package/fesm2020/collections.mjs.map +1 -0
  319. package/{fesm2015/drag-drop.js → fesm2020/drag-drop.mjs} +523 -366
  320. package/fesm2020/drag-drop.mjs.map +1 -0
  321. package/fesm2020/keycodes.mjs +159 -0
  322. package/fesm2020/keycodes.mjs.map +1 -0
  323. package/fesm2020/layout.mjs +246 -0
  324. package/fesm2020/layout.mjs.map +1 -0
  325. package/fesm2020/observers.mjs +202 -0
  326. package/fesm2020/observers.mjs.map +1 -0
  327. package/{fesm2015/overlay.js → fesm2020/overlay.mjs} +312 -228
  328. package/fesm2020/overlay.mjs.map +1 -0
  329. package/{fesm2015/platform.js → fesm2020/platform.mjs} +52 -28
  330. package/fesm2020/platform.mjs.map +1 -0
  331. package/{fesm2015/portal.js → fesm2020/portal.mjs} +85 -64
  332. package/fesm2020/portal.mjs.map +1 -0
  333. package/{fesm2015/scrolling.js → fesm2020/scrolling.mjs} +213 -170
  334. package/fesm2020/scrolling.mjs.map +1 -0
  335. package/fesm2020/stepper.mjs +638 -0
  336. package/fesm2020/stepper.mjs.map +1 -0
  337. package/fesm2020/table.mjs +2295 -0
  338. package/fesm2020/table.mjs.map +1 -0
  339. package/fesm2020/testing/protractor.mjs +322 -0
  340. package/fesm2020/testing/protractor.mjs.map +1 -0
  341. package/fesm2020/testing/selenium-webdriver.mjs +362 -0
  342. package/fesm2020/testing/selenium-webdriver.mjs.map +1 -0
  343. package/fesm2020/testing/testbed.mjs +780 -0
  344. package/fesm2020/testing/testbed.mjs.map +1 -0
  345. package/fesm2020/testing.mjs +719 -0
  346. package/fesm2020/testing.mjs.map +1 -0
  347. package/{fesm2015/text-field.js → fesm2020/text-field.mjs} +83 -68
  348. package/fesm2020/text-field.mjs.map +1 -0
  349. package/fesm2020/tree.mjs +967 -0
  350. package/fesm2020/tree.mjs.map +1 -0
  351. package/keycodes/package.json +5 -5
  352. package/layout/breakpoints-observer.d.ts +3 -7
  353. package/layout/layout-module.d.ts +4 -0
  354. package/layout/media-matcher.d.ts +3 -0
  355. package/layout/package.json +5 -5
  356. package/observers/observe-content.d.ts +10 -0
  357. package/observers/package.json +5 -5
  358. package/overlay/dispatchers/base-overlay-dispatcher.d.ts +3 -7
  359. package/overlay/dispatchers/overlay-keyboard-dispatcher.d.ts +3 -7
  360. package/overlay/dispatchers/overlay-outside-click-dispatcher.d.ts +6 -7
  361. package/overlay/fullscreen-overlay-container.d.ts +3 -0
  362. package/overlay/index.d.ts +0 -2
  363. package/overlay/overlay-container.d.ts +3 -7
  364. package/overlay/overlay-directives.d.ts +5 -0
  365. package/overlay/overlay-module.d.ts +8 -7
  366. package/overlay/overlay.d.ts +3 -0
  367. package/overlay/package.json +5 -5
  368. package/overlay/position/flexible-connected-position-strategy.d.ts +2 -2
  369. package/overlay/position/overlay-position-builder.d.ts +3 -0
  370. package/overlay/position/scroll-clip.d.ts +5 -2
  371. package/overlay/scroll/index.d.ts +1 -1
  372. package/overlay/scroll/scroll-strategy-options.d.ts +3 -0
  373. package/package.json +219 -7
  374. package/platform/package.json +5 -5
  375. package/platform/platform-module.d.ts +4 -7
  376. package/platform/platform.d.ts +3 -7
  377. package/portal/package.json +5 -5
  378. package/portal/portal-directives.d.ts +12 -0
  379. package/schematics/ng-add/index.js +3 -3
  380. package/schematics/ng-add/index.mjs +3 -3
  381. package/schematics/ng-add/package-config.js +4 -2
  382. package/schematics/ng-add/package-config.mjs +4 -2
  383. package/schematics/ng-add/schema.js +1 -1
  384. package/schematics/ng-add/schema.mjs +1 -1
  385. package/schematics/ng-generate/drag-drop/index.js +6 -6
  386. package/schematics/ng-generate/drag-drop/index.mjs +6 -6
  387. package/schematics/ng-update/data/attribute-selectors.js +7 -5
  388. package/schematics/ng-update/data/attribute-selectors.mjs +7 -5
  389. package/schematics/ng-update/data/class-names.js +13 -11
  390. package/schematics/ng-update/data/class-names.mjs +13 -11
  391. package/schematics/ng-update/data/constructor-checks.js +28 -20
  392. package/schematics/ng-update/data/constructor-checks.mjs +28 -20
  393. package/schematics/ng-update/data/css-selectors.js +2 -2
  394. package/schematics/ng-update/data/css-selectors.mjs +2 -2
  395. package/schematics/ng-update/data/element-selectors.js +2 -2
  396. package/schematics/ng-update/data/element-selectors.mjs +2 -2
  397. package/schematics/ng-update/data/input-names.js +40 -16
  398. package/schematics/ng-update/data/input-names.mjs +40 -16
  399. package/schematics/ng-update/data/method-call-checks.js +32 -18
  400. package/schematics/ng-update/data/method-call-checks.mjs +32 -18
  401. package/schematics/ng-update/data/output-names.js +8 -6
  402. package/schematics/ng-update/data/output-names.mjs +8 -6
  403. package/schematics/ng-update/data/property-names.js +40 -32
  404. package/schematics/ng-update/data/property-names.mjs +40 -32
  405. package/schematics/ng-update/devkit-file-system.js +2 -2
  406. package/schematics/ng-update/devkit-file-system.mjs +2 -2
  407. package/schematics/ng-update/devkit-migration-rule.js +8 -7
  408. package/schematics/ng-update/devkit-migration-rule.mjs +8 -7
  409. package/schematics/ng-update/devkit-migration.d.ts +1 -1
  410. package/schematics/ng-update/devkit-migration.js +1 -1
  411. package/schematics/ng-update/devkit-migration.mjs +1 -1
  412. package/schematics/ng-update/find-stylesheets.js +3 -3
  413. package/schematics/ng-update/find-stylesheets.mjs +3 -3
  414. package/schematics/ng-update/html-parsing/angular.js +7 -7
  415. package/schematics/ng-update/html-parsing/angular.mjs +7 -7
  416. package/schematics/ng-update/html-parsing/elements.js +2 -2
  417. package/schematics/ng-update/html-parsing/elements.mjs +2 -2
  418. package/schematics/ng-update/index.js +11 -9
  419. package/schematics/ng-update/index.mjs +11 -9
  420. package/schematics/ng-update/migrations/attribute-selectors.js +11 -7
  421. package/schematics/ng-update/migrations/attribute-selectors.mjs +11 -7
  422. package/schematics/ng-update/migrations/class-inheritance.js +3 -3
  423. package/schematics/ng-update/migrations/class-inheritance.mjs +3 -3
  424. package/schematics/ng-update/migrations/class-names.js +7 -6
  425. package/schematics/ng-update/migrations/class-names.mjs +7 -6
  426. package/schematics/ng-update/migrations/constructor-signature.js +16 -13
  427. package/schematics/ng-update/migrations/constructor-signature.mjs +16 -13
  428. package/schematics/ng-update/migrations/css-selectors.js +7 -6
  429. package/schematics/ng-update/migrations/css-selectors.mjs +7 -6
  430. package/schematics/ng-update/migrations/element-selectors.js +7 -6
  431. package/schematics/ng-update/migrations/element-selectors.mjs +7 -6
  432. package/schematics/ng-update/migrations/input-names.js +8 -9
  433. package/schematics/ng-update/migrations/input-names.mjs +8 -9
  434. package/schematics/ng-update/migrations/method-call-arguments.js +4 -3
  435. package/schematics/ng-update/migrations/method-call-arguments.mjs +4 -3
  436. package/schematics/ng-update/migrations/misc-template.js +3 -3
  437. package/schematics/ng-update/migrations/misc-template.mjs +3 -3
  438. package/schematics/ng-update/migrations/output-names.js +7 -8
  439. package/schematics/ng-update/migrations/output-names.mjs +7 -8
  440. package/schematics/ng-update/migrations/property-names.js +4 -3
  441. package/schematics/ng-update/migrations/property-names.mjs +4 -3
  442. package/schematics/ng-update/migrations/symbol-removal.js +2 -2
  443. package/schematics/ng-update/migrations/symbol-removal.mjs +2 -2
  444. package/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.d.ts +14 -0
  445. package/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.js +38 -0
  446. package/schematics/ng-update/migrations/tilde-import-v13/tilde-import-migration.mjs +38 -0
  447. package/schematics/ng-update/typescript/base-types.js +1 -1
  448. package/schematics/ng-update/typescript/base-types.mjs +1 -1
  449. package/schematics/ng-update/typescript/literal.d.ts +1 -1
  450. package/schematics/ng-update/typescript/literal.js +1 -1
  451. package/schematics/ng-update/typescript/literal.mjs +1 -1
  452. package/schematics/ng-update/typescript/module-specifiers.js +5 -5
  453. package/schematics/ng-update/typescript/module-specifiers.mjs +5 -5
  454. package/schematics/ng-update/upgrade-data.js +2 -2
  455. package/schematics/ng-update/upgrade-data.mjs +2 -2
  456. package/schematics/package.json +3 -0
  457. package/schematics/paths.js +3 -3
  458. package/schematics/paths.mjs +3 -3
  459. package/schematics/update-tool/component-resource-collector.js +10 -10
  460. package/schematics/update-tool/component-resource-collector.mjs +10 -10
  461. package/schematics/update-tool/file-system.js +1 -1
  462. package/schematics/update-tool/file-system.mjs +1 -1
  463. package/schematics/update-tool/index.d.ts +4 -1
  464. package/schematics/update-tool/index.js +9 -5
  465. package/schematics/update-tool/index.mjs +9 -5
  466. package/schematics/update-tool/migration.d.ts +1 -1
  467. package/schematics/update-tool/migration.js +1 -1
  468. package/schematics/update-tool/migration.mjs +1 -1
  469. package/schematics/update-tool/target-version.js +1 -1
  470. package/schematics/update-tool/target-version.mjs +1 -1
  471. package/schematics/update-tool/utils/decorators.js +8 -4
  472. package/schematics/update-tool/utils/decorators.mjs +8 -4
  473. package/schematics/update-tool/utils/functions.js +1 -1
  474. package/schematics/update-tool/utils/functions.mjs +1 -1
  475. package/schematics/update-tool/utils/imports.js +2 -2
  476. package/schematics/update-tool/utils/imports.mjs +2 -2
  477. package/schematics/update-tool/utils/line-mappings.js +1 -1
  478. package/schematics/update-tool/utils/line-mappings.mjs +1 -1
  479. package/schematics/update-tool/utils/parse-tsconfig.js +2 -2
  480. package/schematics/update-tool/utils/parse-tsconfig.mjs +2 -2
  481. package/schematics/update-tool/utils/property-name.js +1 -1
  482. package/schematics/update-tool/utils/property-name.mjs +1 -1
  483. package/schematics/update-tool/utils/virtual-host.d.ts +1 -1
  484. package/schematics/update-tool/utils/virtual-host.js +3 -3
  485. package/schematics/update-tool/utils/virtual-host.mjs +3 -3
  486. package/schematics/update-tool/version-changes.js +1 -1
  487. package/schematics/update-tool/version-changes.mjs +1 -1
  488. package/schematics/utils/ast/ng-module-imports.js +5 -3
  489. package/schematics/utils/ast/ng-module-imports.mjs +5 -3
  490. package/schematics/utils/ast.js +5 -5
  491. package/schematics/utils/ast.mjs +5 -5
  492. package/schematics/utils/build-component.js +32 -38
  493. package/schematics/utils/build-component.mjs +32 -38
  494. package/schematics/utils/get-project.js +1 -1
  495. package/schematics/utils/get-project.mjs +1 -1
  496. package/schematics/utils/html-manipulation.js +8 -7
  497. package/schematics/utils/html-manipulation.mjs +8 -7
  498. package/schematics/utils/parse5-element.js +9 -10
  499. package/schematics/utils/parse5-element.mjs +9 -10
  500. package/schematics/utils/project-index-file.js +2 -2
  501. package/schematics/utils/project-index-file.mjs +2 -2
  502. package/schematics/utils/project-main-file.js +2 -2
  503. package/schematics/utils/project-main-file.mjs +2 -2
  504. package/schematics/utils/project-style-file.js +7 -9
  505. package/schematics/utils/project-style-file.mjs +7 -9
  506. package/schematics/utils/project-targets.js +1 -1
  507. package/schematics/utils/project-targets.mjs +1 -1
  508. package/schematics/utils/project-tsconfig-paths.js +4 -4
  509. package/schematics/utils/project-tsconfig-paths.mjs +4 -4
  510. package/schematics/utils/schematic-options.js +7 -5
  511. package/schematics/utils/schematic-options.mjs +7 -5
  512. package/schematics/utils/vendored-ast-utils/index.js +17 -18
  513. package/schematics/utils/vendored-ast-utils/index.mjs +17 -18
  514. package/scrolling/fixed-size-virtual-scroll.d.ts +3 -0
  515. package/scrolling/package.json +5 -5
  516. package/scrolling/scroll-dispatcher.d.ts +3 -7
  517. package/scrolling/scrollable.d.ts +3 -0
  518. package/scrolling/scrolling-module.d.ts +13 -7
  519. package/scrolling/viewport-ruler.d.ts +11 -1
  520. package/scrolling/virtual-for-of.d.ts +3 -0
  521. package/scrolling/virtual-scroll-viewport.d.ts +3 -0
  522. package/stepper/package.json +5 -5
  523. package/stepper/step-header.d.ts +3 -0
  524. package/stepper/step-label.d.ts +3 -0
  525. package/stepper/stepper-button.d.ts +5 -7
  526. package/stepper/stepper-module.d.ts +9 -7
  527. package/stepper/stepper.d.ts +5 -7
  528. package/table/cell.d.ts +15 -0
  529. package/table/coalesced-style-scheduler.d.ts +3 -0
  530. package/table/package.json +5 -5
  531. package/table/row.d.ts +19 -0
  532. package/table/table-module.d.ts +9 -7
  533. package/table/table.d.ts +13 -0
  534. package/table/text-column.d.ts +3 -0
  535. package/testing/package.json +5 -5
  536. package/testing/protractor/package.json +5 -5
  537. package/testing/selenium-webdriver/package.json +5 -5
  538. package/testing/testbed/package.json +5 -5
  539. package/testing/testbed/proxy-zone-types.d.ts +1 -1
  540. package/testing/testbed/zone-types.d.ts +1 -1
  541. package/text-field/autofill.d.ts +5 -0
  542. package/text-field/autosize.d.ts +3 -0
  543. package/text-field/package.json +5 -5
  544. package/text-field/text-field-module.d.ts +7 -7
  545. package/tree/control/base-tree-control.d.ts +1 -1
  546. package/tree/control/nested-tree-control.d.ts +2 -2
  547. package/tree/nested-node.d.ts +3 -0
  548. package/tree/node.d.ts +3 -0
  549. package/tree/outlet.d.ts +3 -0
  550. package/tree/package.json +5 -5
  551. package/tree/padding.d.ts +3 -0
  552. package/tree/toggle.d.ts +3 -0
  553. package/tree/tree-module.d.ts +10 -7
  554. package/tree/tree.d.ts +5 -0
  555. package/a11y/index.metadata.json +0 -1
  556. package/accordion/index.metadata.json +0 -1
  557. package/bidi/index.metadata.json +0 -1
  558. package/bundles/cdk-a11y.umd.js +0 -2752
  559. package/bundles/cdk-a11y.umd.js.map +0 -1
  560. package/bundles/cdk-accordion.umd.js +0 -262
  561. package/bundles/cdk-accordion.umd.js.map +0 -1
  562. package/bundles/cdk-bidi.umd.js +0 -206
  563. package/bundles/cdk-bidi.umd.js.map +0 -1
  564. package/bundles/cdk-clipboard.umd.js +0 -278
  565. package/bundles/cdk-clipboard.umd.js.map +0 -1
  566. package/bundles/cdk-coercion.umd.js +0 -477
  567. package/bundles/cdk-coercion.umd.js.map +0 -1
  568. package/bundles/cdk-collections.umd.js +0 -846
  569. package/bundles/cdk-collections.umd.js.map +0 -1
  570. package/bundles/cdk-drag-drop.umd.js +0 -3915
  571. package/bundles/cdk-drag-drop.umd.js.map +0 -1
  572. package/bundles/cdk-keycodes.umd.js +0 -292
  573. package/bundles/cdk-keycodes.umd.js.map +0 -1
  574. package/bundles/cdk-layout.umd.js +0 -284
  575. package/bundles/cdk-layout.umd.js.map +0 -1
  576. package/bundles/cdk-observers.umd.js +0 -242
  577. package/bundles/cdk-observers.umd.js.map +0 -1
  578. package/bundles/cdk-overlay.umd.js +0 -3417
  579. package/bundles/cdk-overlay.umd.js.map +0 -1
  580. package/bundles/cdk-platform.umd.js +0 -397
  581. package/bundles/cdk-platform.umd.js.map +0 -1
  582. package/bundles/cdk-portal.umd.js +0 -1008
  583. package/bundles/cdk-portal.umd.js.map +0 -1
  584. package/bundles/cdk-scrolling.umd.js +0 -1787
  585. package/bundles/cdk-scrolling.umd.js.map +0 -1
  586. package/bundles/cdk-stepper.umd.js +0 -648
  587. package/bundles/cdk-stepper.umd.js.map +0 -1
  588. package/bundles/cdk-table.umd.js +0 -2730
  589. package/bundles/cdk-table.umd.js.map +0 -1
  590. package/bundles/cdk-testing-protractor.umd.js +0 -833
  591. package/bundles/cdk-testing-protractor.umd.js.map +0 -1
  592. package/bundles/cdk-testing-selenium-webdriver.umd.js +0 -1002
  593. package/bundles/cdk-testing-selenium-webdriver.umd.js.map +0 -1
  594. package/bundles/cdk-testing-testbed.umd.js +0 -1396
  595. package/bundles/cdk-testing-testbed.umd.js.map +0 -1
  596. package/bundles/cdk-testing.umd.js +0 -1285
  597. package/bundles/cdk-testing.umd.js.map +0 -1
  598. package/bundles/cdk-text-field.umd.js +0 -494
  599. package/bundles/cdk-text-field.umd.js.map +0 -1
  600. package/bundles/cdk-tree.umd.js +0 -1308
  601. package/bundles/cdk-tree.umd.js.map +0 -1
  602. package/bundles/cdk.umd.js +0 -38
  603. package/bundles/cdk.umd.js.map +0 -1
  604. package/clipboard/index.metadata.json +0 -1
  605. package/collections/index.metadata.json +0 -1
  606. package/drag-drop/index.metadata.json +0 -1
  607. package/esm2015/a11y/a11y-module.js +0 -30
  608. package/esm2015/a11y/a11y.externs.js +0 -6
  609. package/esm2015/a11y/aria-describer/aria-describer.js +0 -213
  610. package/esm2015/a11y/fake-event-detection.js +0 -28
  611. package/esm2015/a11y/focus-monitor/focus-monitor.js +0 -394
  612. package/esm2015/a11y/focus-trap/configurable-focus-trap-factory.js +0 -52
  613. package/esm2015/a11y/focus-trap/configurable-focus-trap.js +0 -49
  614. package/esm2015/a11y/focus-trap/event-listener-inert-strategy.js +0 -62
  615. package/esm2015/a11y/focus-trap/focus-trap-inert-strategy.js +0 -11
  616. package/esm2015/a11y/focus-trap/focus-trap-manager.js +0 -51
  617. package/esm2015/a11y/focus-trap/focus-trap.js +0 -391
  618. package/esm2015/a11y/high-contrast-mode/high-contrast-mode-detector.js +0 -92
  619. package/esm2015/a11y/index.js +0 -6
  620. package/esm2015/a11y/input-modality/input-modality-detector.js +0 -171
  621. package/esm2015/a11y/interactivity-checker/interactivity-checker.js +0 -237
  622. package/esm2015/a11y/key-manager/list-key-manager.js +0 -317
  623. package/esm2015/a11y/live-announcer/live-announcer-tokens.js +0 -19
  624. package/esm2015/a11y/live-announcer/live-announcer.js +0 -167
  625. package/esm2015/accordion/accordion-item.js +0 -146
  626. package/esm2015/accordion/accordion-module.js +0 -19
  627. package/esm2015/accordion/accordion.externs.js +0 -6
  628. package/esm2015/accordion/accordion.js +0 -63
  629. package/esm2015/accordion/index.js +0 -6
  630. package/esm2015/bidi/bidi-module.js +0 -18
  631. package/esm2015/bidi/bidi.externs.js +0 -6
  632. package/esm2015/bidi/dir.js +0 -58
  633. package/esm2015/bidi/directionality.js +0 -44
  634. package/esm2015/bidi/index.js +0 -6
  635. package/esm2015/cdk.externs.js +0 -0
  636. package/esm2015/clipboard/clipboard-module.js +0 -18
  637. package/esm2015/clipboard/clipboard.externs.js +0 -6
  638. package/esm2015/clipboard/clipboard.js +0 -52
  639. package/esm2015/clipboard/copy-to-clipboard.js +0 -90
  640. package/esm2015/clipboard/pending-copy.js +0 -68
  641. package/esm2015/coercion/coercion.externs.js +0 -0
  642. package/esm2015/collections/collection-viewer.js +0 -9
  643. package/esm2015/collections/collections.externs.js +0 -6
  644. package/esm2015/collections/dispose-view-repeater-strategy.js +0 -48
  645. package/esm2015/collections/recycle-view-repeater-strategy.js +0 -125
  646. package/esm2015/collections/tree-adapter.js +0 -9
  647. package/esm2015/collections/unique-selection-dispatcher.js +0 -53
  648. package/esm2015/collections/view-repeater.js +0 -14
  649. package/esm2015/drag-drop/client-rect.js +0 -60
  650. package/esm2015/drag-drop/clone-node.js +0 -65
  651. package/esm2015/drag-drop/directives/assertions.js +0 -19
  652. package/esm2015/drag-drop/directives/drag-handle.js +0 -57
  653. package/esm2015/drag-drop/directives/drag-placeholder.js +0 -36
  654. package/esm2015/drag-drop/directives/drag-preview.js +0 -42
  655. package/esm2015/drag-drop/directives/drag.js +0 -407
  656. package/esm2015/drag-drop/directives/drop-list-group.js +0 -47
  657. package/esm2015/drag-drop/directives/drop-list.js +0 -301
  658. package/esm2015/drag-drop/drag-drop-module.js +0 -43
  659. package/esm2015/drag-drop/drag-drop-registry.js +0 -231
  660. package/esm2015/drag-drop/drag-drop.externs.js +0 -6
  661. package/esm2015/drag-drop/drag-drop.js +0 -59
  662. package/esm2015/drag-drop/drag-events.js +0 -9
  663. package/esm2015/drag-drop/drag-ref.js +0 -1110
  664. package/esm2015/drag-drop/drag-styling.js +0 -69
  665. package/esm2015/drag-drop/drag-utils.js +0 -60
  666. package/esm2015/drag-drop/drop-list-ref.js +0 -813
  667. package/esm2015/drag-drop/transition-duration.js +0 -36
  668. package/esm2015/keycodes/keycodes.externs.js +0 -6
  669. package/esm2015/layout/breakpoints-observer.js +0 -106
  670. package/esm2015/layout/layout-module.js +0 -14
  671. package/esm2015/layout/layout.externs.js +0 -6
  672. package/esm2015/layout/media-matcher.js +0 -85
  673. package/esm2015/observers/observe-content.js +0 -179
  674. package/esm2015/observers/observers.externs.js +0 -6
  675. package/esm2015/overlay/dispatchers/base-overlay-dispatcher.js +0 -51
  676. package/esm2015/overlay/dispatchers/overlay-keyboard-dispatcher.js +0 -62
  677. package/esm2015/overlay/dispatchers/overlay-outside-click-dispatcher.js +0 -97
  678. package/esm2015/overlay/fullscreen-overlay-container.js +0 -94
  679. package/esm2015/overlay/index.js +0 -7
  680. package/esm2015/overlay/overlay-config.js +0 -45
  681. package/esm2015/overlay/overlay-container.js +0 -85
  682. package/esm2015/overlay/overlay-directives.js +0 -352
  683. package/esm2015/overlay/overlay-module.js +0 -27
  684. package/esm2015/overlay/overlay-ref.js +0 -409
  685. package/esm2015/overlay/overlay.externs.js +0 -6
  686. package/esm2015/overlay/overlay.js +0 -119
  687. package/esm2015/overlay/position/connected-position.js +0 -94
  688. package/esm2015/overlay/position/flexible-connected-position-strategy.js +0 -960
  689. package/esm2015/overlay/position/global-position-strategy.js +0 -197
  690. package/esm2015/overlay/position/overlay-position-builder.js +0 -52
  691. package/esm2015/overlay/position/scroll-clip.js +0 -42
  692. package/esm2015/overlay/scroll/close-scroll-strategy.js +0 -61
  693. package/esm2015/overlay/scroll/scroll-strategy-options.js +0 -57
  694. package/esm2015/platform/features/passive-listeners.js +0 -36
  695. package/esm2015/platform/features/scrolling.js +0 -85
  696. package/esm2015/platform/features/test-environment.js +0 -16
  697. package/esm2015/platform/platform-module.js +0 -14
  698. package/esm2015/platform/platform.externs.js +0 -6
  699. package/esm2015/platform/platform.js +0 -77
  700. package/esm2015/portal/dom-portal-outlet.js +0 -136
  701. package/esm2015/portal/portal-directives.js +0 -221
  702. package/esm2015/portal/portal-injector.js +0 -28
  703. package/esm2015/portal/portal.externs.js +0 -6
  704. package/esm2015/portal/portal.js +0 -179
  705. package/esm2015/scrolling/fixed-size-virtual-scroll.js +0 -188
  706. package/esm2015/scrolling/scroll-dispatcher.js +0 -163
  707. package/esm2015/scrolling/scrollable.js +0 -173
  708. package/esm2015/scrolling/scrolling-module.js +0 -49
  709. package/esm2015/scrolling/scrolling.externs.js +0 -6
  710. package/esm2015/scrolling/viewport-ruler.js +0 -139
  711. package/esm2015/scrolling/virtual-for-of.js +0 -293
  712. package/esm2015/scrolling/virtual-scroll-strategy.js +0 -11
  713. package/esm2015/scrolling/virtual-scroll-viewport.js +0 -371
  714. package/esm2015/stepper/step-header.js +0 -29
  715. package/esm2015/stepper/step-label.js +0 -22
  716. package/esm2015/stepper/stepper-button.js +0 -72
  717. package/esm2015/stepper/stepper-module.js +0 -37
  718. package/esm2015/stepper/stepper.externs.js +0 -6
  719. package/esm2015/stepper/stepper.js +0 -428
  720. package/esm2015/table/can-stick.js +0 -42
  721. package/esm2015/table/cell.js +0 -211
  722. package/esm2015/table/coalesced-style-scheduler.js +0 -89
  723. package/esm2015/table/row.js +0 -244
  724. package/esm2015/table/sticky-position-listener.js +0 -11
  725. package/esm2015/table/sticky-styler.js +0 -336
  726. package/esm2015/table/table-module.js +0 -47
  727. package/esm2015/table/table.externs.js +0 -6
  728. package/esm2015/table/table.js +0 -987
  729. package/esm2015/table/text-column.js +0 -127
  730. package/esm2015/testing/change-detection.js +0 -110
  731. package/esm2015/testing/component-harness.js +0 -344
  732. package/esm2015/testing/harness-environment.js +0 -219
  733. package/esm2015/testing/protractor/protractor-element.js +0 -274
  734. package/esm2015/testing/protractor/protractor-harness-environment.js +0 -79
  735. package/esm2015/testing/protractor/protractor.externs.js +0 -0
  736. package/esm2015/testing/selenium-webdriver/selenium-web-driver-element.js +0 -241
  737. package/esm2015/testing/selenium-webdriver/selenium-web-driver-harness-environment.js +0 -97
  738. package/esm2015/testing/selenium-webdriver/selenium-webdriver.externs.js +0 -0
  739. package/esm2015/testing/test-element.js +0 -48
  740. package/esm2015/testing/testbed/fake-events/dispatch-events.js +0 -53
  741. package/esm2015/testing/testbed/fake-events/element-focus.js +0 -39
  742. package/esm2015/testing/testbed/fake-events/event-objects.js +0 -107
  743. package/esm2015/testing/testbed/fake-events/type-in-element.js +0 -79
  744. package/esm2015/testing/testbed/task-state-zone-interceptor.js +0 -82
  745. package/esm2015/testing/testbed/testbed-harness-environment.js +0 -173
  746. package/esm2015/testing/testbed/testbed.externs.js +0 -0
  747. package/esm2015/testing/testbed/unit-test-element.js +0 -266
  748. package/esm2015/testing/testing.externs.js +0 -0
  749. package/esm2015/testing/text-filtering.js +0 -23
  750. package/esm2015/text-field/autofill.js +0 -117
  751. package/esm2015/text-field/autosize.js +0 -293
  752. package/esm2015/text-field/text-field-module.js +0 -21
  753. package/esm2015/text-field/text-field.externs.js +0 -6
  754. package/esm2015/tree/control/nested-tree-control.js +0 -59
  755. package/esm2015/tree/nested-node.js +0 -112
  756. package/esm2015/tree/node.js +0 -36
  757. package/esm2015/tree/outlet.js +0 -34
  758. package/esm2015/tree/padding.js +0 -119
  759. package/esm2015/tree/toggle.js +0 -46
  760. package/esm2015/tree/tree-module.js +0 -32
  761. package/esm2015/tree/tree.externs.js +0 -6
  762. package/esm2015/tree/tree.js +0 -345
  763. package/fesm2015/a11y.js.map +0 -1
  764. package/fesm2015/accordion.js.map +0 -1
  765. package/fesm2015/bidi.js.map +0 -1
  766. package/fesm2015/cdk.js.map +0 -1
  767. package/fesm2015/clipboard.js.map +0 -1
  768. package/fesm2015/coercion.js.map +0 -1
  769. package/fesm2015/collections.js.map +0 -1
  770. package/fesm2015/drag-drop.js.map +0 -1
  771. package/fesm2015/keycodes.js.map +0 -1
  772. package/fesm2015/layout.js.map +0 -1
  773. package/fesm2015/observers.js.map +0 -1
  774. package/fesm2015/overlay.js.map +0 -1
  775. package/fesm2015/platform.js.map +0 -1
  776. package/fesm2015/portal.js.map +0 -1
  777. package/fesm2015/scrolling.js.map +0 -1
  778. package/fesm2015/stepper.js.map +0 -1
  779. package/fesm2015/table.js.map +0 -1
  780. package/fesm2015/testing/protractor.js.map +0 -1
  781. package/fesm2015/testing/selenium-webdriver.js.map +0 -1
  782. package/fesm2015/testing/testbed.js.map +0 -1
  783. package/fesm2015/testing.js.map +0 -1
  784. package/fesm2015/text-field.js.map +0 -1
  785. package/fesm2015/tree.js.map +0 -1
  786. package/keycodes/index.metadata.json +0 -1
  787. package/layout/index.metadata.json +0 -1
  788. package/observers/index.metadata.json +0 -1
  789. package/overlay/index.metadata.json +0 -1
  790. package/platform/index.metadata.json +0 -1
  791. package/portal/index.metadata.json +0 -1
  792. package/scrolling/index.metadata.json +0 -1
  793. package/stepper/index.metadata.json +0 -1
  794. package/table/index.metadata.json +0 -1
  795. package/text-field/index.metadata.json +0 -1
  796. package/tree/index.metadata.json +0 -1
@@ -0,0 +1,1108 @@
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 { normalizePassiveListenerOptions, _getEventTarget, _getShadowRoot, } from '@angular/cdk/platform';
9
+ import { coerceBooleanProperty, coerceElement } from '@angular/cdk/coercion';
10
+ import { isFakeMousedownFromScreenReader, isFakeTouchstartFromScreenReader } from '@angular/cdk/a11y';
11
+ import { Subscription, Subject } from 'rxjs';
12
+ import { combineTransforms, extendStyles, toggleNativeDragInteractions, toggleVisibility, } from './drag-styling';
13
+ import { getTransformTransitionDurationInMs } from './transition-duration';
14
+ import { getMutableClientRect, adjustClientRect } from './client-rect';
15
+ import { ParentPositionTracker } from './parent-position-tracker';
16
+ import { deepCloneNode } from './clone-node';
17
+ /** Options that can be used to bind a passive event listener. */
18
+ const passiveEventListenerOptions = normalizePassiveListenerOptions({ passive: true });
19
+ /** Options that can be used to bind an active event listener. */
20
+ const activeEventListenerOptions = normalizePassiveListenerOptions({ passive: false });
21
+ /**
22
+ * Time in milliseconds for which to ignore mouse events, after
23
+ * receiving a touch event. Used to avoid doing double work for
24
+ * touch devices where the browser fires fake mouse events, in
25
+ * addition to touch events.
26
+ */
27
+ const MOUSE_EVENT_IGNORE_TIME = 800;
28
+ /** Inline styles to be set as `!important` while dragging. */
29
+ const dragImportantProperties = new Set([
30
+ // Needs to be important, because some `mat-table` sets `position: sticky !important`. See #22781.
31
+ 'position',
32
+ ]);
33
+ /**
34
+ * Reference to a draggable item. Used to manipulate or dispose of the item.
35
+ */
36
+ export class DragRef {
37
+ constructor(element, _config, _document, _ngZone, _viewportRuler, _dragDropRegistry) {
38
+ this._config = _config;
39
+ this._document = _document;
40
+ this._ngZone = _ngZone;
41
+ this._viewportRuler = _viewportRuler;
42
+ this._dragDropRegistry = _dragDropRegistry;
43
+ /**
44
+ * CSS `transform` applied to the element when it isn't being dragged. We need a
45
+ * passive transform in order for the dragged element to retain its new position
46
+ * after the user has stopped dragging and because we need to know the relative
47
+ * position in case they start dragging again. This corresponds to `element.style.transform`.
48
+ */
49
+ this._passiveTransform = { x: 0, y: 0 };
50
+ /** CSS `transform` that is applied to the element while it's being dragged. */
51
+ this._activeTransform = { x: 0, y: 0 };
52
+ /**
53
+ * Whether the dragging sequence has been started. Doesn't
54
+ * necessarily mean that the element has been moved.
55
+ */
56
+ this._hasStartedDragging = false;
57
+ /** Emits when the item is being moved. */
58
+ this._moveEvents = new Subject();
59
+ /** Subscription to pointer movement events. */
60
+ this._pointerMoveSubscription = Subscription.EMPTY;
61
+ /** Subscription to the event that is dispatched when the user lifts their pointer. */
62
+ this._pointerUpSubscription = Subscription.EMPTY;
63
+ /** Subscription to the viewport being scrolled. */
64
+ this._scrollSubscription = Subscription.EMPTY;
65
+ /** Subscription to the viewport being resized. */
66
+ this._resizeSubscription = Subscription.EMPTY;
67
+ /** Cached reference to the boundary element. */
68
+ this._boundaryElement = null;
69
+ /** Whether the native dragging interactions have been enabled on the root element. */
70
+ this._nativeInteractionsEnabled = true;
71
+ /** Elements that can be used to drag the draggable item. */
72
+ this._handles = [];
73
+ /** Registered handles that are currently disabled. */
74
+ this._disabledHandles = new Set();
75
+ /** Layout direction of the item. */
76
+ this._direction = 'ltr';
77
+ /**
78
+ * Amount of milliseconds to wait after the user has put their
79
+ * pointer down before starting to drag the element.
80
+ */
81
+ this.dragStartDelay = 0;
82
+ this._disabled = false;
83
+ /** Emits as the drag sequence is being prepared. */
84
+ this.beforeStarted = new Subject();
85
+ /** Emits when the user starts dragging the item. */
86
+ this.started = new Subject();
87
+ /** Emits when the user has released a drag item, before any animations have started. */
88
+ this.released = new Subject();
89
+ /** Emits when the user stops dragging an item in the container. */
90
+ this.ended = new Subject();
91
+ /** Emits when the user has moved the item into a new container. */
92
+ this.entered = new Subject();
93
+ /** Emits when the user removes the item its container by dragging it into another container. */
94
+ this.exited = new Subject();
95
+ /** Emits when the user drops the item inside a container. */
96
+ this.dropped = new Subject();
97
+ /**
98
+ * Emits as the user is dragging the item. Use with caution,
99
+ * because this event will fire for every pixel that the user has dragged.
100
+ */
101
+ this.moved = this._moveEvents;
102
+ /** Handler for the `mousedown`/`touchstart` events. */
103
+ this._pointerDown = (event) => {
104
+ this.beforeStarted.next();
105
+ // Delegate the event based on whether it started from a handle or the element itself.
106
+ if (this._handles.length) {
107
+ const targetHandle = this._handles.find(handle => {
108
+ const target = _getEventTarget(event);
109
+ return !!target && (target === handle || handle.contains(target));
110
+ });
111
+ if (targetHandle && !this._disabledHandles.has(targetHandle) && !this.disabled) {
112
+ this._initializeDragSequence(targetHandle, event);
113
+ }
114
+ }
115
+ else if (!this.disabled) {
116
+ this._initializeDragSequence(this._rootElement, event);
117
+ }
118
+ };
119
+ /** Handler that is invoked when the user moves their pointer after they've initiated a drag. */
120
+ this._pointerMove = (event) => {
121
+ const pointerPosition = this._getPointerPositionOnPage(event);
122
+ if (!this._hasStartedDragging) {
123
+ const distanceX = Math.abs(pointerPosition.x - this._pickupPositionOnPage.x);
124
+ const distanceY = Math.abs(pointerPosition.y - this._pickupPositionOnPage.y);
125
+ const isOverThreshold = distanceX + distanceY >= this._config.dragStartThreshold;
126
+ // Only start dragging after the user has moved more than the minimum distance in either
127
+ // direction. Note that this is preferrable over doing something like `skip(minimumDistance)`
128
+ // in the `pointerMove` subscription, because we're not guaranteed to have one move event
129
+ // per pixel of movement (e.g. if the user moves their pointer quickly).
130
+ if (isOverThreshold) {
131
+ const isDelayElapsed = Date.now() >= this._dragStartTime + this._getDragStartDelay(event);
132
+ const container = this._dropContainer;
133
+ if (!isDelayElapsed) {
134
+ this._endDragSequence(event);
135
+ return;
136
+ }
137
+ // Prevent other drag sequences from starting while something in the container is still
138
+ // being dragged. This can happen while we're waiting for the drop animation to finish
139
+ // and can cause errors, because some elements might still be moving around.
140
+ if (!container || (!container.isDragging() && !container.isReceiving())) {
141
+ // Prevent the default action as soon as the dragging sequence is considered as
142
+ // "started" since waiting for the next event can allow the device to begin scrolling.
143
+ event.preventDefault();
144
+ this._hasStartedDragging = true;
145
+ this._ngZone.run(() => this._startDragSequence(event));
146
+ }
147
+ }
148
+ return;
149
+ }
150
+ // We only need the preview dimensions if we have a boundary element.
151
+ if (this._boundaryElement) {
152
+ // Cache the preview element rect if we haven't cached it already or if
153
+ // we cached it too early before the element dimensions were computed.
154
+ if (!this._previewRect || (!this._previewRect.width && !this._previewRect.height)) {
155
+ this._previewRect = (this._preview || this._rootElement).getBoundingClientRect();
156
+ }
157
+ }
158
+ // We prevent the default action down here so that we know that dragging has started. This is
159
+ // important for touch devices where doing this too early can unnecessarily block scrolling,
160
+ // if there's a dragging delay.
161
+ event.preventDefault();
162
+ const constrainedPointerPosition = this._getConstrainedPointerPosition(pointerPosition);
163
+ this._hasMoved = true;
164
+ this._lastKnownPointerPosition = pointerPosition;
165
+ this._updatePointerDirectionDelta(constrainedPointerPosition);
166
+ if (this._dropContainer) {
167
+ this._updateActiveDropContainer(constrainedPointerPosition, pointerPosition);
168
+ }
169
+ else {
170
+ const activeTransform = this._activeTransform;
171
+ activeTransform.x =
172
+ constrainedPointerPosition.x - this._pickupPositionOnPage.x + this._passiveTransform.x;
173
+ activeTransform.y =
174
+ constrainedPointerPosition.y - this._pickupPositionOnPage.y + this._passiveTransform.y;
175
+ this._applyRootElementTransform(activeTransform.x, activeTransform.y);
176
+ }
177
+ // Since this event gets fired for every pixel while dragging, we only
178
+ // want to fire it if the consumer opted into it. Also we have to
179
+ // re-enter the zone because we run all of the events on the outside.
180
+ if (this._moveEvents.observers.length) {
181
+ this._ngZone.run(() => {
182
+ this._moveEvents.next({
183
+ source: this,
184
+ pointerPosition: constrainedPointerPosition,
185
+ event,
186
+ distance: this._getDragDistance(constrainedPointerPosition),
187
+ delta: this._pointerDirectionDelta,
188
+ });
189
+ });
190
+ }
191
+ };
192
+ /** Handler that is invoked when the user lifts their pointer up, after initiating a drag. */
193
+ this._pointerUp = (event) => {
194
+ this._endDragSequence(event);
195
+ };
196
+ this.withRootElement(element).withParent(_config.parentDragRef || null);
197
+ this._parentPositions = new ParentPositionTracker(_document, _viewportRuler);
198
+ _dragDropRegistry.registerDragItem(this);
199
+ }
200
+ /** Whether starting to drag this element is disabled. */
201
+ get disabled() {
202
+ return this._disabled || !!(this._dropContainer && this._dropContainer.disabled);
203
+ }
204
+ set disabled(value) {
205
+ const newValue = coerceBooleanProperty(value);
206
+ if (newValue !== this._disabled) {
207
+ this._disabled = newValue;
208
+ this._toggleNativeDragInteractions();
209
+ this._handles.forEach(handle => toggleNativeDragInteractions(handle, newValue));
210
+ }
211
+ }
212
+ /**
213
+ * Returns the element that is being used as a placeholder
214
+ * while the current element is being dragged.
215
+ */
216
+ getPlaceholderElement() {
217
+ return this._placeholder;
218
+ }
219
+ /** Returns the root draggable element. */
220
+ getRootElement() {
221
+ return this._rootElement;
222
+ }
223
+ /**
224
+ * Gets the currently-visible element that represents the drag item.
225
+ * While dragging this is the placeholder, otherwise it's the root element.
226
+ */
227
+ getVisibleElement() {
228
+ return this.isDragging() ? this.getPlaceholderElement() : this.getRootElement();
229
+ }
230
+ /** Registers the handles that can be used to drag the element. */
231
+ withHandles(handles) {
232
+ this._handles = handles.map(handle => coerceElement(handle));
233
+ this._handles.forEach(handle => toggleNativeDragInteractions(handle, this.disabled));
234
+ this._toggleNativeDragInteractions();
235
+ // Delete any lingering disabled handles that may have been destroyed. Note that we re-create
236
+ // the set, rather than iterate over it and filter out the destroyed handles, because while
237
+ // the ES spec allows for sets to be modified while they're being iterated over, some polyfills
238
+ // use an array internally which may throw an error.
239
+ const disabledHandles = new Set();
240
+ this._disabledHandles.forEach(handle => {
241
+ if (this._handles.indexOf(handle) > -1) {
242
+ disabledHandles.add(handle);
243
+ }
244
+ });
245
+ this._disabledHandles = disabledHandles;
246
+ return this;
247
+ }
248
+ /**
249
+ * Registers the template that should be used for the drag preview.
250
+ * @param template Template that from which to stamp out the preview.
251
+ */
252
+ withPreviewTemplate(template) {
253
+ this._previewTemplate = template;
254
+ return this;
255
+ }
256
+ /**
257
+ * Registers the template that should be used for the drag placeholder.
258
+ * @param template Template that from which to stamp out the placeholder.
259
+ */
260
+ withPlaceholderTemplate(template) {
261
+ this._placeholderTemplate = template;
262
+ return this;
263
+ }
264
+ /**
265
+ * Sets an alternate drag root element. The root element is the element that will be moved as
266
+ * the user is dragging. Passing an alternate root element is useful when trying to enable
267
+ * dragging on an element that you might not have access to.
268
+ */
269
+ withRootElement(rootElement) {
270
+ const element = coerceElement(rootElement);
271
+ if (element !== this._rootElement) {
272
+ if (this._rootElement) {
273
+ this._removeRootElementListeners(this._rootElement);
274
+ }
275
+ this._ngZone.runOutsideAngular(() => {
276
+ element.addEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
277
+ element.addEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
278
+ });
279
+ this._initialTransform = undefined;
280
+ this._rootElement = element;
281
+ }
282
+ if (typeof SVGElement !== 'undefined' && this._rootElement instanceof SVGElement) {
283
+ this._ownerSVGElement = this._rootElement.ownerSVGElement;
284
+ }
285
+ return this;
286
+ }
287
+ /**
288
+ * Element to which the draggable's position will be constrained.
289
+ */
290
+ withBoundaryElement(boundaryElement) {
291
+ this._boundaryElement = boundaryElement ? coerceElement(boundaryElement) : null;
292
+ this._resizeSubscription.unsubscribe();
293
+ if (boundaryElement) {
294
+ this._resizeSubscription = this._viewportRuler
295
+ .change(10)
296
+ .subscribe(() => this._containInsideBoundaryOnResize());
297
+ }
298
+ return this;
299
+ }
300
+ /** Sets the parent ref that the ref is nested in. */
301
+ withParent(parent) {
302
+ this._parentDragRef = parent;
303
+ return this;
304
+ }
305
+ /** Removes the dragging functionality from the DOM element. */
306
+ dispose() {
307
+ this._removeRootElementListeners(this._rootElement);
308
+ // Do this check before removing from the registry since it'll
309
+ // stop being considered as dragged once it is removed.
310
+ if (this.isDragging()) {
311
+ // Since we move out the element to the end of the body while it's being
312
+ // dragged, we have to make sure that it's removed if it gets destroyed.
313
+ this._rootElement?.remove();
314
+ }
315
+ this._anchor?.remove();
316
+ this._destroyPreview();
317
+ this._destroyPlaceholder();
318
+ this._dragDropRegistry.removeDragItem(this);
319
+ this._removeSubscriptions();
320
+ this.beforeStarted.complete();
321
+ this.started.complete();
322
+ this.released.complete();
323
+ this.ended.complete();
324
+ this.entered.complete();
325
+ this.exited.complete();
326
+ this.dropped.complete();
327
+ this._moveEvents.complete();
328
+ this._handles = [];
329
+ this._disabledHandles.clear();
330
+ this._dropContainer = undefined;
331
+ this._resizeSubscription.unsubscribe();
332
+ this._parentPositions.clear();
333
+ this._boundaryElement =
334
+ this._rootElement =
335
+ this._ownerSVGElement =
336
+ this._placeholderTemplate =
337
+ this._previewTemplate =
338
+ this._anchor =
339
+ this._parentDragRef =
340
+ null;
341
+ }
342
+ /** Checks whether the element is currently being dragged. */
343
+ isDragging() {
344
+ return this._hasStartedDragging && this._dragDropRegistry.isDragging(this);
345
+ }
346
+ /** Resets a standalone drag item to its initial position. */
347
+ reset() {
348
+ this._rootElement.style.transform = this._initialTransform || '';
349
+ this._activeTransform = { x: 0, y: 0 };
350
+ this._passiveTransform = { x: 0, y: 0 };
351
+ }
352
+ /**
353
+ * Sets a handle as disabled. While a handle is disabled, it'll capture and interrupt dragging.
354
+ * @param handle Handle element that should be disabled.
355
+ */
356
+ disableHandle(handle) {
357
+ if (!this._disabledHandles.has(handle) && this._handles.indexOf(handle) > -1) {
358
+ this._disabledHandles.add(handle);
359
+ toggleNativeDragInteractions(handle, true);
360
+ }
361
+ }
362
+ /**
363
+ * Enables a handle, if it has been disabled.
364
+ * @param handle Handle element to be enabled.
365
+ */
366
+ enableHandle(handle) {
367
+ if (this._disabledHandles.has(handle)) {
368
+ this._disabledHandles.delete(handle);
369
+ toggleNativeDragInteractions(handle, this.disabled);
370
+ }
371
+ }
372
+ /** Sets the layout direction of the draggable item. */
373
+ withDirection(direction) {
374
+ this._direction = direction;
375
+ return this;
376
+ }
377
+ /** Sets the container that the item is part of. */
378
+ _withDropContainer(container) {
379
+ this._dropContainer = container;
380
+ }
381
+ /**
382
+ * Gets the current position in pixels the draggable outside of a drop container.
383
+ */
384
+ getFreeDragPosition() {
385
+ const position = this.isDragging() ? this._activeTransform : this._passiveTransform;
386
+ return { x: position.x, y: position.y };
387
+ }
388
+ /**
389
+ * Sets the current position in pixels the draggable outside of a drop container.
390
+ * @param value New position to be set.
391
+ */
392
+ setFreeDragPosition(value) {
393
+ this._activeTransform = { x: 0, y: 0 };
394
+ this._passiveTransform.x = value.x;
395
+ this._passiveTransform.y = value.y;
396
+ if (!this._dropContainer) {
397
+ this._applyRootElementTransform(value.x, value.y);
398
+ }
399
+ return this;
400
+ }
401
+ /**
402
+ * Sets the container into which to insert the preview element.
403
+ * @param value Container into which to insert the preview.
404
+ */
405
+ withPreviewContainer(value) {
406
+ this._previewContainer = value;
407
+ return this;
408
+ }
409
+ /** Updates the item's sort order based on the last-known pointer position. */
410
+ _sortFromLastPointerPosition() {
411
+ const position = this._lastKnownPointerPosition;
412
+ if (position && this._dropContainer) {
413
+ this._updateActiveDropContainer(this._getConstrainedPointerPosition(position), position);
414
+ }
415
+ }
416
+ /** Unsubscribes from the global subscriptions. */
417
+ _removeSubscriptions() {
418
+ this._pointerMoveSubscription.unsubscribe();
419
+ this._pointerUpSubscription.unsubscribe();
420
+ this._scrollSubscription.unsubscribe();
421
+ }
422
+ /** Destroys the preview element and its ViewRef. */
423
+ _destroyPreview() {
424
+ this._preview?.remove();
425
+ this._previewRef?.destroy();
426
+ this._preview = this._previewRef = null;
427
+ }
428
+ /** Destroys the placeholder element and its ViewRef. */
429
+ _destroyPlaceholder() {
430
+ this._placeholder?.remove();
431
+ this._placeholderRef?.destroy();
432
+ this._placeholder = this._placeholderRef = null;
433
+ }
434
+ /**
435
+ * Clears subscriptions and stops the dragging sequence.
436
+ * @param event Browser event object that ended the sequence.
437
+ */
438
+ _endDragSequence(event) {
439
+ // Note that here we use `isDragging` from the service, rather than from `this`.
440
+ // The difference is that the one from the service reflects whether a dragging sequence
441
+ // has been initiated, whereas the one on `this` includes whether the user has passed
442
+ // the minimum dragging threshold.
443
+ if (!this._dragDropRegistry.isDragging(this)) {
444
+ return;
445
+ }
446
+ this._removeSubscriptions();
447
+ this._dragDropRegistry.stopDragging(this);
448
+ this._toggleNativeDragInteractions();
449
+ if (this._handles) {
450
+ this._rootElement.style.webkitTapHighlightColor = this._rootElementTapHighlight;
451
+ }
452
+ if (!this._hasStartedDragging) {
453
+ return;
454
+ }
455
+ this.released.next({ source: this });
456
+ if (this._dropContainer) {
457
+ // Stop scrolling immediately, instead of waiting for the animation to finish.
458
+ this._dropContainer._stopScrolling();
459
+ this._animatePreviewToPlaceholder().then(() => {
460
+ this._cleanupDragArtifacts(event);
461
+ this._cleanupCachedDimensions();
462
+ this._dragDropRegistry.stopDragging(this);
463
+ });
464
+ }
465
+ else {
466
+ // Convert the active transform into a passive one. This means that next time
467
+ // the user starts dragging the item, its position will be calculated relatively
468
+ // to the new passive transform.
469
+ this._passiveTransform.x = this._activeTransform.x;
470
+ const pointerPosition = this._getPointerPositionOnPage(event);
471
+ this._passiveTransform.y = this._activeTransform.y;
472
+ this._ngZone.run(() => {
473
+ this.ended.next({
474
+ source: this,
475
+ distance: this._getDragDistance(pointerPosition),
476
+ dropPoint: pointerPosition,
477
+ });
478
+ });
479
+ this._cleanupCachedDimensions();
480
+ this._dragDropRegistry.stopDragging(this);
481
+ }
482
+ }
483
+ /** Starts the dragging sequence. */
484
+ _startDragSequence(event) {
485
+ if (isTouchEvent(event)) {
486
+ this._lastTouchEventTime = Date.now();
487
+ }
488
+ this._toggleNativeDragInteractions();
489
+ const dropContainer = this._dropContainer;
490
+ if (dropContainer) {
491
+ const element = this._rootElement;
492
+ const parent = element.parentNode;
493
+ const placeholder = (this._placeholder = this._createPlaceholderElement());
494
+ const anchor = (this._anchor = this._anchor || this._document.createComment(''));
495
+ // Needs to happen before the root element is moved.
496
+ const shadowRoot = this._getShadowRoot();
497
+ // Insert an anchor node so that we can restore the element's position in the DOM.
498
+ parent.insertBefore(anchor, element);
499
+ // There's no risk of transforms stacking when inside a drop container so
500
+ // we can keep the initial transform up to date any time dragging starts.
501
+ this._initialTransform = element.style.transform || '';
502
+ // Create the preview after the initial transform has
503
+ // been cached, because it can be affected by the transform.
504
+ this._preview = this._createPreviewElement();
505
+ // We move the element out at the end of the body and we make it hidden, because keeping it in
506
+ // place will throw off the consumer's `:last-child` selectors. We can't remove the element
507
+ // from the DOM completely, because iOS will stop firing all subsequent events in the chain.
508
+ toggleVisibility(element, false, dragImportantProperties);
509
+ this._document.body.appendChild(parent.replaceChild(placeholder, element));
510
+ this._getPreviewInsertionPoint(parent, shadowRoot).appendChild(this._preview);
511
+ this.started.next({ source: this }); // Emit before notifying the container.
512
+ dropContainer.start();
513
+ this._initialContainer = dropContainer;
514
+ this._initialIndex = dropContainer.getItemIndex(this);
515
+ }
516
+ else {
517
+ this.started.next({ source: this });
518
+ this._initialContainer = this._initialIndex = undefined;
519
+ }
520
+ // Important to run after we've called `start` on the parent container
521
+ // so that it has had time to resolve its scrollable parents.
522
+ this._parentPositions.cache(dropContainer ? dropContainer.getScrollableParents() : []);
523
+ }
524
+ /**
525
+ * Sets up the different variables and subscriptions
526
+ * that will be necessary for the dragging sequence.
527
+ * @param referenceElement Element that started the drag sequence.
528
+ * @param event Browser event object that started the sequence.
529
+ */
530
+ _initializeDragSequence(referenceElement, event) {
531
+ // Stop propagation if the item is inside another
532
+ // draggable so we don't start multiple drag sequences.
533
+ if (this._parentDragRef) {
534
+ event.stopPropagation();
535
+ }
536
+ const isDragging = this.isDragging();
537
+ const isTouchSequence = isTouchEvent(event);
538
+ const isAuxiliaryMouseButton = !isTouchSequence && event.button !== 0;
539
+ const rootElement = this._rootElement;
540
+ const target = _getEventTarget(event);
541
+ const isSyntheticEvent = !isTouchSequence &&
542
+ this._lastTouchEventTime &&
543
+ this._lastTouchEventTime + MOUSE_EVENT_IGNORE_TIME > Date.now();
544
+ const isFakeEvent = isTouchSequence
545
+ ? isFakeTouchstartFromScreenReader(event)
546
+ : isFakeMousedownFromScreenReader(event);
547
+ // If the event started from an element with the native HTML drag&drop, it'll interfere
548
+ // with our own dragging (e.g. `img` tags do it by default). Prevent the default action
549
+ // to stop it from happening. Note that preventing on `dragstart` also seems to work, but
550
+ // it's flaky and it fails if the user drags it away quickly. Also note that we only want
551
+ // to do this for `mousedown` since doing the same for `touchstart` will stop any `click`
552
+ // events from firing on touch devices.
553
+ if (target && target.draggable && event.type === 'mousedown') {
554
+ event.preventDefault();
555
+ }
556
+ // Abort if the user is already dragging or is using a mouse button other than the primary one.
557
+ if (isDragging || isAuxiliaryMouseButton || isSyntheticEvent || isFakeEvent) {
558
+ return;
559
+ }
560
+ // If we've got handles, we need to disable the tap highlight on the entire root element,
561
+ // otherwise iOS will still add it, even though all the drag interactions on the handle
562
+ // are disabled.
563
+ if (this._handles.length) {
564
+ const rootStyles = rootElement.style;
565
+ this._rootElementTapHighlight = rootStyles.webkitTapHighlightColor || '';
566
+ rootStyles.webkitTapHighlightColor = 'transparent';
567
+ }
568
+ this._hasStartedDragging = this._hasMoved = false;
569
+ // Avoid multiple subscriptions and memory leaks when multi touch
570
+ // (isDragging check above isn't enough because of possible temporal and/or dimensional delays)
571
+ this._removeSubscriptions();
572
+ this._pointerMoveSubscription = this._dragDropRegistry.pointerMove.subscribe(this._pointerMove);
573
+ this._pointerUpSubscription = this._dragDropRegistry.pointerUp.subscribe(this._pointerUp);
574
+ this._scrollSubscription = this._dragDropRegistry
575
+ .scrolled(this._getShadowRoot())
576
+ .subscribe(scrollEvent => this._updateOnScroll(scrollEvent));
577
+ if (this._boundaryElement) {
578
+ this._boundaryRect = getMutableClientRect(this._boundaryElement);
579
+ }
580
+ // If we have a custom preview we can't know ahead of time how large it'll be so we position
581
+ // it next to the cursor. The exception is when the consumer has opted into making the preview
582
+ // the same size as the root element, in which case we do know the size.
583
+ const previewTemplate = this._previewTemplate;
584
+ this._pickupPositionInElement =
585
+ previewTemplate && previewTemplate.template && !previewTemplate.matchSize
586
+ ? { x: 0, y: 0 }
587
+ : this._getPointerPositionInElement(referenceElement, event);
588
+ const pointerPosition = (this._pickupPositionOnPage =
589
+ this._lastKnownPointerPosition =
590
+ this._getPointerPositionOnPage(event));
591
+ this._pointerDirectionDelta = { x: 0, y: 0 };
592
+ this._pointerPositionAtLastDirectionChange = { x: pointerPosition.x, y: pointerPosition.y };
593
+ this._dragStartTime = Date.now();
594
+ this._dragDropRegistry.startDragging(this, event);
595
+ }
596
+ /** Cleans up the DOM artifacts that were added to facilitate the element being dragged. */
597
+ _cleanupDragArtifacts(event) {
598
+ // Restore the element's visibility and insert it at its old position in the DOM.
599
+ // It's important that we maintain the position, because moving the element around in the DOM
600
+ // can throw off `NgFor` which does smart diffing and re-creates elements only when necessary,
601
+ // while moving the existing elements in all other cases.
602
+ toggleVisibility(this._rootElement, true, dragImportantProperties);
603
+ this._anchor.parentNode.replaceChild(this._rootElement, this._anchor);
604
+ this._destroyPreview();
605
+ this._destroyPlaceholder();
606
+ this._boundaryRect = this._previewRect = this._initialTransform = undefined;
607
+ // Re-enter the NgZone since we bound `document` events on the outside.
608
+ this._ngZone.run(() => {
609
+ const container = this._dropContainer;
610
+ const currentIndex = container.getItemIndex(this);
611
+ const pointerPosition = this._getPointerPositionOnPage(event);
612
+ const distance = this._getDragDistance(pointerPosition);
613
+ const isPointerOverContainer = container._isOverContainer(pointerPosition.x, pointerPosition.y);
614
+ this.ended.next({ source: this, distance, dropPoint: pointerPosition });
615
+ this.dropped.next({
616
+ item: this,
617
+ currentIndex,
618
+ previousIndex: this._initialIndex,
619
+ container: container,
620
+ previousContainer: this._initialContainer,
621
+ isPointerOverContainer,
622
+ distance,
623
+ dropPoint: pointerPosition,
624
+ });
625
+ container.drop(this, currentIndex, this._initialIndex, this._initialContainer, isPointerOverContainer, distance, pointerPosition);
626
+ this._dropContainer = this._initialContainer;
627
+ });
628
+ }
629
+ /**
630
+ * Updates the item's position in its drop container, or moves it
631
+ * into a new one, depending on its current drag position.
632
+ */
633
+ _updateActiveDropContainer({ x, y }, { x: rawX, y: rawY }) {
634
+ // Drop container that draggable has been moved into.
635
+ let newContainer = this._initialContainer._getSiblingContainerFromPosition(this, x, y);
636
+ // If we couldn't find a new container to move the item into, and the item has left its
637
+ // initial container, check whether the it's over the initial container. This handles the
638
+ // case where two containers are connected one way and the user tries to undo dragging an
639
+ // item into a new container.
640
+ if (!newContainer &&
641
+ this._dropContainer !== this._initialContainer &&
642
+ this._initialContainer._isOverContainer(x, y)) {
643
+ newContainer = this._initialContainer;
644
+ }
645
+ if (newContainer && newContainer !== this._dropContainer) {
646
+ this._ngZone.run(() => {
647
+ // Notify the old container that the item has left.
648
+ this.exited.next({ item: this, container: this._dropContainer });
649
+ this._dropContainer.exit(this);
650
+ // Notify the new container that the item has entered.
651
+ this._dropContainer = newContainer;
652
+ this._dropContainer.enter(this, x, y, newContainer === this._initialContainer &&
653
+ // If we're re-entering the initial container and sorting is disabled,
654
+ // put item the into its starting index to begin with.
655
+ newContainer.sortingDisabled
656
+ ? this._initialIndex
657
+ : undefined);
658
+ this.entered.next({
659
+ item: this,
660
+ container: newContainer,
661
+ currentIndex: newContainer.getItemIndex(this),
662
+ });
663
+ });
664
+ }
665
+ // Dragging may have been interrupted as a result of the events above.
666
+ if (this.isDragging()) {
667
+ this._dropContainer._startScrollingIfNecessary(rawX, rawY);
668
+ this._dropContainer._sortItem(this, x, y, this._pointerDirectionDelta);
669
+ this._applyPreviewTransform(x - this._pickupPositionInElement.x, y - this._pickupPositionInElement.y);
670
+ }
671
+ }
672
+ /**
673
+ * Creates the element that will be rendered next to the user's pointer
674
+ * and will be used as a preview of the element that is being dragged.
675
+ */
676
+ _createPreviewElement() {
677
+ const previewConfig = this._previewTemplate;
678
+ const previewClass = this.previewClass;
679
+ const previewTemplate = previewConfig ? previewConfig.template : null;
680
+ let preview;
681
+ if (previewTemplate && previewConfig) {
682
+ // Measure the element before we've inserted the preview
683
+ // since the insertion could throw off the measurement.
684
+ const rootRect = previewConfig.matchSize ? this._rootElement.getBoundingClientRect() : null;
685
+ const viewRef = previewConfig.viewContainer.createEmbeddedView(previewTemplate, previewConfig.context);
686
+ viewRef.detectChanges();
687
+ preview = getRootNode(viewRef, this._document);
688
+ this._previewRef = viewRef;
689
+ if (previewConfig.matchSize) {
690
+ matchElementSize(preview, rootRect);
691
+ }
692
+ else {
693
+ preview.style.transform = getTransform(this._pickupPositionOnPage.x, this._pickupPositionOnPage.y);
694
+ }
695
+ }
696
+ else {
697
+ const element = this._rootElement;
698
+ preview = deepCloneNode(element);
699
+ matchElementSize(preview, element.getBoundingClientRect());
700
+ if (this._initialTransform) {
701
+ preview.style.transform = this._initialTransform;
702
+ }
703
+ }
704
+ extendStyles(preview.style, {
705
+ // It's important that we disable the pointer events on the preview, because
706
+ // it can throw off the `document.elementFromPoint` calls in the `CdkDropList`.
707
+ 'pointer-events': 'none',
708
+ // We have to reset the margin, because it can throw off positioning relative to the viewport.
709
+ 'margin': '0',
710
+ 'position': 'fixed',
711
+ 'top': '0',
712
+ 'left': '0',
713
+ 'z-index': `${this._config.zIndex || 1000}`,
714
+ }, dragImportantProperties);
715
+ toggleNativeDragInteractions(preview, false);
716
+ preview.classList.add('cdk-drag-preview');
717
+ preview.setAttribute('dir', this._direction);
718
+ if (previewClass) {
719
+ if (Array.isArray(previewClass)) {
720
+ previewClass.forEach(className => preview.classList.add(className));
721
+ }
722
+ else {
723
+ preview.classList.add(previewClass);
724
+ }
725
+ }
726
+ return preview;
727
+ }
728
+ /**
729
+ * Animates the preview element from its current position to the location of the drop placeholder.
730
+ * @returns Promise that resolves when the animation completes.
731
+ */
732
+ _animatePreviewToPlaceholder() {
733
+ // If the user hasn't moved yet, the transitionend event won't fire.
734
+ if (!this._hasMoved) {
735
+ return Promise.resolve();
736
+ }
737
+ const placeholderRect = this._placeholder.getBoundingClientRect();
738
+ // Apply the class that adds a transition to the preview.
739
+ this._preview.classList.add('cdk-drag-animating');
740
+ // Move the preview to the placeholder position.
741
+ this._applyPreviewTransform(placeholderRect.left, placeholderRect.top);
742
+ // If the element doesn't have a `transition`, the `transitionend` event won't fire. Since
743
+ // we need to trigger a style recalculation in order for the `cdk-drag-animating` class to
744
+ // apply its style, we take advantage of the available info to figure out whether we need to
745
+ // bind the event in the first place.
746
+ const duration = getTransformTransitionDurationInMs(this._preview);
747
+ if (duration === 0) {
748
+ return Promise.resolve();
749
+ }
750
+ return this._ngZone.runOutsideAngular(() => {
751
+ return new Promise(resolve => {
752
+ const handler = ((event) => {
753
+ if (!event ||
754
+ (_getEventTarget(event) === this._preview && event.propertyName === 'transform')) {
755
+ this._preview?.removeEventListener('transitionend', handler);
756
+ resolve();
757
+ clearTimeout(timeout);
758
+ }
759
+ });
760
+ // If a transition is short enough, the browser might not fire the `transitionend` event.
761
+ // Since we know how long it's supposed to take, add a timeout with a 50% buffer that'll
762
+ // fire if the transition hasn't completed when it was supposed to.
763
+ const timeout = setTimeout(handler, duration * 1.5);
764
+ this._preview.addEventListener('transitionend', handler);
765
+ });
766
+ });
767
+ }
768
+ /** Creates an element that will be shown instead of the current element while dragging. */
769
+ _createPlaceholderElement() {
770
+ const placeholderConfig = this._placeholderTemplate;
771
+ const placeholderTemplate = placeholderConfig ? placeholderConfig.template : null;
772
+ let placeholder;
773
+ if (placeholderTemplate) {
774
+ this._placeholderRef = placeholderConfig.viewContainer.createEmbeddedView(placeholderTemplate, placeholderConfig.context);
775
+ this._placeholderRef.detectChanges();
776
+ placeholder = getRootNode(this._placeholderRef, this._document);
777
+ }
778
+ else {
779
+ placeholder = deepCloneNode(this._rootElement);
780
+ }
781
+ placeholder.classList.add('cdk-drag-placeholder');
782
+ return placeholder;
783
+ }
784
+ /**
785
+ * Figures out the coordinates at which an element was picked up.
786
+ * @param referenceElement Element that initiated the dragging.
787
+ * @param event Event that initiated the dragging.
788
+ */
789
+ _getPointerPositionInElement(referenceElement, event) {
790
+ const elementRect = this._rootElement.getBoundingClientRect();
791
+ const handleElement = referenceElement === this._rootElement ? null : referenceElement;
792
+ const referenceRect = handleElement ? handleElement.getBoundingClientRect() : elementRect;
793
+ const point = isTouchEvent(event) ? event.targetTouches[0] : event;
794
+ const scrollPosition = this._getViewportScrollPosition();
795
+ const x = point.pageX - referenceRect.left - scrollPosition.left;
796
+ const y = point.pageY - referenceRect.top - scrollPosition.top;
797
+ return {
798
+ x: referenceRect.left - elementRect.left + x,
799
+ y: referenceRect.top - elementRect.top + y,
800
+ };
801
+ }
802
+ /** Determines the point of the page that was touched by the user. */
803
+ _getPointerPositionOnPage(event) {
804
+ const scrollPosition = this._getViewportScrollPosition();
805
+ const point = isTouchEvent(event)
806
+ ? // `touches` will be empty for start/end events so we have to fall back to `changedTouches`.
807
+ // Also note that on real devices we're guaranteed for either `touches` or `changedTouches`
808
+ // to have a value, but Firefox in device emulation mode has a bug where both can be empty
809
+ // for `touchstart` and `touchend` so we fall back to a dummy object in order to avoid
810
+ // throwing an error. The value returned here will be incorrect, but since this only
811
+ // breaks inside a developer tool and the value is only used for secondary information,
812
+ // we can get away with it. See https://bugzilla.mozilla.org/show_bug.cgi?id=1615824.
813
+ event.touches[0] || event.changedTouches[0] || { pageX: 0, pageY: 0 }
814
+ : event;
815
+ const x = point.pageX - scrollPosition.left;
816
+ const y = point.pageY - scrollPosition.top;
817
+ // if dragging SVG element, try to convert from the screen coordinate system to the SVG
818
+ // coordinate system
819
+ if (this._ownerSVGElement) {
820
+ const svgMatrix = this._ownerSVGElement.getScreenCTM();
821
+ if (svgMatrix) {
822
+ const svgPoint = this._ownerSVGElement.createSVGPoint();
823
+ svgPoint.x = x;
824
+ svgPoint.y = y;
825
+ return svgPoint.matrixTransform(svgMatrix.inverse());
826
+ }
827
+ }
828
+ return { x, y };
829
+ }
830
+ /** Gets the pointer position on the page, accounting for any position constraints. */
831
+ _getConstrainedPointerPosition(point) {
832
+ const dropContainerLock = this._dropContainer ? this._dropContainer.lockAxis : null;
833
+ let { x, y } = this.constrainPosition ? this.constrainPosition(point, this) : point;
834
+ if (this.lockAxis === 'x' || dropContainerLock === 'x') {
835
+ y = this._pickupPositionOnPage.y;
836
+ }
837
+ else if (this.lockAxis === 'y' || dropContainerLock === 'y') {
838
+ x = this._pickupPositionOnPage.x;
839
+ }
840
+ if (this._boundaryRect) {
841
+ const { x: pickupX, y: pickupY } = this._pickupPositionInElement;
842
+ const boundaryRect = this._boundaryRect;
843
+ const previewRect = this._previewRect;
844
+ const minY = boundaryRect.top + pickupY;
845
+ const maxY = boundaryRect.bottom - (previewRect.height - pickupY);
846
+ const minX = boundaryRect.left + pickupX;
847
+ const maxX = boundaryRect.right - (previewRect.width - pickupX);
848
+ x = clamp(x, minX, maxX);
849
+ y = clamp(y, minY, maxY);
850
+ }
851
+ return { x, y };
852
+ }
853
+ /** Updates the current drag delta, based on the user's current pointer position on the page. */
854
+ _updatePointerDirectionDelta(pointerPositionOnPage) {
855
+ const { x, y } = pointerPositionOnPage;
856
+ const delta = this._pointerDirectionDelta;
857
+ const positionSinceLastChange = this._pointerPositionAtLastDirectionChange;
858
+ // Amount of pixels the user has dragged since the last time the direction changed.
859
+ const changeX = Math.abs(x - positionSinceLastChange.x);
860
+ const changeY = Math.abs(y - positionSinceLastChange.y);
861
+ // Because we handle pointer events on a per-pixel basis, we don't want the delta
862
+ // to change for every pixel, otherwise anything that depends on it can look erratic.
863
+ // To make the delta more consistent, we track how much the user has moved since the last
864
+ // delta change and we only update it after it has reached a certain threshold.
865
+ if (changeX > this._config.pointerDirectionChangeThreshold) {
866
+ delta.x = x > positionSinceLastChange.x ? 1 : -1;
867
+ positionSinceLastChange.x = x;
868
+ }
869
+ if (changeY > this._config.pointerDirectionChangeThreshold) {
870
+ delta.y = y > positionSinceLastChange.y ? 1 : -1;
871
+ positionSinceLastChange.y = y;
872
+ }
873
+ return delta;
874
+ }
875
+ /** Toggles the native drag interactions, based on how many handles are registered. */
876
+ _toggleNativeDragInteractions() {
877
+ if (!this._rootElement || !this._handles) {
878
+ return;
879
+ }
880
+ const shouldEnable = this._handles.length > 0 || !this.isDragging();
881
+ if (shouldEnable !== this._nativeInteractionsEnabled) {
882
+ this._nativeInteractionsEnabled = shouldEnable;
883
+ toggleNativeDragInteractions(this._rootElement, shouldEnable);
884
+ }
885
+ }
886
+ /** Removes the manually-added event listeners from the root element. */
887
+ _removeRootElementListeners(element) {
888
+ element.removeEventListener('mousedown', this._pointerDown, activeEventListenerOptions);
889
+ element.removeEventListener('touchstart', this._pointerDown, passiveEventListenerOptions);
890
+ }
891
+ /**
892
+ * Applies a `transform` to the root element, taking into account any existing transforms on it.
893
+ * @param x New transform value along the X axis.
894
+ * @param y New transform value along the Y axis.
895
+ */
896
+ _applyRootElementTransform(x, y) {
897
+ const transform = getTransform(x, y);
898
+ const styles = this._rootElement.style;
899
+ // Cache the previous transform amount only after the first drag sequence, because
900
+ // we don't want our own transforms to stack on top of each other.
901
+ // Should be excluded none because none + translate3d(x, y, x) is invalid css
902
+ if (this._initialTransform == null) {
903
+ this._initialTransform =
904
+ styles.transform && styles.transform != 'none' ? styles.transform : '';
905
+ }
906
+ // Preserve the previous `transform` value, if there was one. Note that we apply our own
907
+ // transform before the user's, because things like rotation can affect which direction
908
+ // the element will be translated towards.
909
+ styles.transform = combineTransforms(transform, this._initialTransform);
910
+ }
911
+ /**
912
+ * Applies a `transform` to the preview, taking into account any existing transforms on it.
913
+ * @param x New transform value along the X axis.
914
+ * @param y New transform value along the Y axis.
915
+ */
916
+ _applyPreviewTransform(x, y) {
917
+ // Only apply the initial transform if the preview is a clone of the original element, otherwise
918
+ // it could be completely different and the transform might not make sense anymore.
919
+ const initialTransform = this._previewTemplate?.template ? undefined : this._initialTransform;
920
+ const transform = getTransform(x, y);
921
+ this._preview.style.transform = combineTransforms(transform, initialTransform);
922
+ }
923
+ /**
924
+ * Gets the distance that the user has dragged during the current drag sequence.
925
+ * @param currentPosition Current position of the user's pointer.
926
+ */
927
+ _getDragDistance(currentPosition) {
928
+ const pickupPosition = this._pickupPositionOnPage;
929
+ if (pickupPosition) {
930
+ return { x: currentPosition.x - pickupPosition.x, y: currentPosition.y - pickupPosition.y };
931
+ }
932
+ return { x: 0, y: 0 };
933
+ }
934
+ /** Cleans up any cached element dimensions that we don't need after dragging has stopped. */
935
+ _cleanupCachedDimensions() {
936
+ this._boundaryRect = this._previewRect = undefined;
937
+ this._parentPositions.clear();
938
+ }
939
+ /**
940
+ * Checks whether the element is still inside its boundary after the viewport has been resized.
941
+ * If not, the position is adjusted so that the element fits again.
942
+ */
943
+ _containInsideBoundaryOnResize() {
944
+ let { x, y } = this._passiveTransform;
945
+ if ((x === 0 && y === 0) || this.isDragging() || !this._boundaryElement) {
946
+ return;
947
+ }
948
+ const boundaryRect = this._boundaryElement.getBoundingClientRect();
949
+ const elementRect = this._rootElement.getBoundingClientRect();
950
+ // It's possible that the element got hidden away after dragging (e.g. by switching to a
951
+ // different tab). Don't do anything in this case so we don't clear the user's position.
952
+ if ((boundaryRect.width === 0 && boundaryRect.height === 0) ||
953
+ (elementRect.width === 0 && elementRect.height === 0)) {
954
+ return;
955
+ }
956
+ const leftOverflow = boundaryRect.left - elementRect.left;
957
+ const rightOverflow = elementRect.right - boundaryRect.right;
958
+ const topOverflow = boundaryRect.top - elementRect.top;
959
+ const bottomOverflow = elementRect.bottom - boundaryRect.bottom;
960
+ // If the element has become wider than the boundary, we can't
961
+ // do much to make it fit so we just anchor it to the left.
962
+ if (boundaryRect.width > elementRect.width) {
963
+ if (leftOverflow > 0) {
964
+ x += leftOverflow;
965
+ }
966
+ if (rightOverflow > 0) {
967
+ x -= rightOverflow;
968
+ }
969
+ }
970
+ else {
971
+ x = 0;
972
+ }
973
+ // If the element has become taller than the boundary, we can't
974
+ // do much to make it fit so we just anchor it to the top.
975
+ if (boundaryRect.height > elementRect.height) {
976
+ if (topOverflow > 0) {
977
+ y += topOverflow;
978
+ }
979
+ if (bottomOverflow > 0) {
980
+ y -= bottomOverflow;
981
+ }
982
+ }
983
+ else {
984
+ y = 0;
985
+ }
986
+ if (x !== this._passiveTransform.x || y !== this._passiveTransform.y) {
987
+ this.setFreeDragPosition({ y, x });
988
+ }
989
+ }
990
+ /** Gets the drag start delay, based on the event type. */
991
+ _getDragStartDelay(event) {
992
+ const value = this.dragStartDelay;
993
+ if (typeof value === 'number') {
994
+ return value;
995
+ }
996
+ else if (isTouchEvent(event)) {
997
+ return value.touch;
998
+ }
999
+ return value ? value.mouse : 0;
1000
+ }
1001
+ /** Updates the internal state of the draggable element when scrolling has occurred. */
1002
+ _updateOnScroll(event) {
1003
+ const scrollDifference = this._parentPositions.handleScroll(event);
1004
+ if (scrollDifference) {
1005
+ const target = _getEventTarget(event);
1006
+ // ClientRect dimensions are based on the scroll position of the page and its parent
1007
+ // node so we have to update the cached boundary ClientRect if the user has scrolled.
1008
+ if (this._boundaryRect &&
1009
+ target !== this._boundaryElement &&
1010
+ target.contains(this._boundaryElement)) {
1011
+ adjustClientRect(this._boundaryRect, scrollDifference.top, scrollDifference.left);
1012
+ }
1013
+ this._pickupPositionOnPage.x += scrollDifference.left;
1014
+ this._pickupPositionOnPage.y += scrollDifference.top;
1015
+ // If we're in free drag mode, we have to update the active transform, because
1016
+ // it isn't relative to the viewport like the preview inside a drop list.
1017
+ if (!this._dropContainer) {
1018
+ this._activeTransform.x -= scrollDifference.left;
1019
+ this._activeTransform.y -= scrollDifference.top;
1020
+ this._applyRootElementTransform(this._activeTransform.x, this._activeTransform.y);
1021
+ }
1022
+ }
1023
+ }
1024
+ /** Gets the scroll position of the viewport. */
1025
+ _getViewportScrollPosition() {
1026
+ const cachedPosition = this._parentPositions.positions.get(this._document);
1027
+ return cachedPosition
1028
+ ? cachedPosition.scrollPosition
1029
+ : this._viewportRuler.getViewportScrollPosition();
1030
+ }
1031
+ /**
1032
+ * Lazily resolves and returns the shadow root of the element. We do this in a function, rather
1033
+ * than saving it in property directly on init, because we want to resolve it as late as possible
1034
+ * in order to ensure that the element has been moved into the shadow DOM. Doing it inside the
1035
+ * constructor might be too early if the element is inside of something like `ngFor` or `ngIf`.
1036
+ */
1037
+ _getShadowRoot() {
1038
+ if (this._cachedShadowRoot === undefined) {
1039
+ this._cachedShadowRoot = _getShadowRoot(this._rootElement);
1040
+ }
1041
+ return this._cachedShadowRoot;
1042
+ }
1043
+ /** Gets the element into which the drag preview should be inserted. */
1044
+ _getPreviewInsertionPoint(initialParent, shadowRoot) {
1045
+ const previewContainer = this._previewContainer || 'global';
1046
+ if (previewContainer === 'parent') {
1047
+ return initialParent;
1048
+ }
1049
+ if (previewContainer === 'global') {
1050
+ const documentRef = this._document;
1051
+ // We can't use the body if the user is in fullscreen mode,
1052
+ // because the preview will render under the fullscreen element.
1053
+ // TODO(crisbeto): dedupe this with the `FullscreenOverlayContainer` eventually.
1054
+ return (shadowRoot ||
1055
+ documentRef.fullscreenElement ||
1056
+ documentRef.webkitFullscreenElement ||
1057
+ documentRef.mozFullScreenElement ||
1058
+ documentRef.msFullscreenElement ||
1059
+ documentRef.body);
1060
+ }
1061
+ return coerceElement(previewContainer);
1062
+ }
1063
+ }
1064
+ /**
1065
+ * Gets a 3d `transform` that can be applied to an element.
1066
+ * @param x Desired position of the element along the X axis.
1067
+ * @param y Desired position of the element along the Y axis.
1068
+ */
1069
+ function getTransform(x, y) {
1070
+ // Round the transforms since some browsers will
1071
+ // blur the elements for sub-pixel transforms.
1072
+ return `translate3d(${Math.round(x)}px, ${Math.round(y)}px, 0)`;
1073
+ }
1074
+ /** Clamps a value between a minimum and a maximum. */
1075
+ function clamp(value, min, max) {
1076
+ return Math.max(min, Math.min(max, value));
1077
+ }
1078
+ /** Determines whether an event is a touch event. */
1079
+ function isTouchEvent(event) {
1080
+ // This function is called for every pixel that the user has dragged so we need it to be
1081
+ // as fast as possible. Since we only bind mouse events and touch events, we can assume
1082
+ // that if the event's name starts with `t`, it's a touch event.
1083
+ return event.type[0] === 't';
1084
+ }
1085
+ /**
1086
+ * Gets the root HTML element of an embedded view.
1087
+ * If the root is not an HTML element it gets wrapped in one.
1088
+ */
1089
+ function getRootNode(viewRef, _document) {
1090
+ const rootNodes = viewRef.rootNodes;
1091
+ if (rootNodes.length === 1 && rootNodes[0].nodeType === _document.ELEMENT_NODE) {
1092
+ return rootNodes[0];
1093
+ }
1094
+ const wrapper = _document.createElement('div');
1095
+ rootNodes.forEach(node => wrapper.appendChild(node));
1096
+ return wrapper;
1097
+ }
1098
+ /**
1099
+ * Matches the target element's size to the source's size.
1100
+ * @param target Element that needs to be resized.
1101
+ * @param sourceRect Dimensions of the source element.
1102
+ */
1103
+ function matchElementSize(target, sourceRect) {
1104
+ target.style.width = `${sourceRect.width}px`;
1105
+ target.style.height = `${sourceRect.height}px`;
1106
+ target.style.transform = getTransform(sourceRect.left, sourceRect.top);
1107
+ }
1108
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZHJhZy1yZWYuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvY2RrL2RyYWctZHJvcC9kcmFnLXJlZi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTs7Ozs7O0dBTUc7QUFLSCxPQUFPLEVBQ0wsK0JBQStCLEVBQy9CLGVBQWUsRUFDZixjQUFjLEdBQ2YsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQixPQUFPLEVBQUMscUJBQXFCLEVBQUUsYUFBYSxFQUFDLE1BQU0sdUJBQXVCLENBQUM7QUFDM0UsT0FBTyxFQUFDLCtCQUErQixFQUFFLGdDQUFnQyxFQUFDLE1BQU0sbUJBQW1CLENBQUM7QUFDcEcsT0FBTyxFQUFDLFlBQVksRUFBRSxPQUFPLEVBQWEsTUFBTSxNQUFNLENBQUM7QUFHdkQsT0FBTyxFQUNMLGlCQUFpQixFQUNqQixZQUFZLEVBQ1osNEJBQTRCLEVBQzVCLGdCQUFnQixHQUNqQixNQUFNLGdCQUFnQixDQUFDO0FBQ3hCLE9BQU8sRUFBQyxrQ0FBa0MsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQ3pFLE9BQU8sRUFBQyxvQkFBb0IsRUFBRSxnQkFBZ0IsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNyRSxPQUFPLEVBQUMscUJBQXFCLEVBQUMsTUFBTSwyQkFBMkIsQ0FBQztBQUNoRSxPQUFPLEVBQUMsYUFBYSxFQUFDLE1BQU0sY0FBYyxDQUFDO0FBdUIzQyxpRUFBaUU7QUFDakUsTUFBTSwyQkFBMkIsR0FBRywrQkFBK0IsQ0FBQyxFQUFDLE9BQU8sRUFBRSxJQUFJLEVBQUMsQ0FBQyxDQUFDO0FBRXJGLGlFQUFpRTtBQUNqRSxNQUFNLDBCQUEwQixHQUFHLCtCQUErQixDQUFDLEVBQUMsT0FBTyxFQUFFLEtBQUssRUFBQyxDQUFDLENBQUM7QUFFckY7Ozs7O0dBS0c7QUFDSCxNQUFNLHVCQUF1QixHQUFHLEdBQUcsQ0FBQztBQThCcEMsOERBQThEO0FBQzlELE1BQU0sdUJBQXVCLEdBQUcsSUFB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QUFDakIsQ0FBQztBQUVEOzs7O0dBSUc7QUFDSCxTQUFTLGdCQUFnQixDQUFDLE1BQW1CLEVBQUUsVUFBc0I7SUFDbkUsTUFBTSxDQUFDLEtBQUssQ0FBQyxLQUFLLEdBQUcsR0FBRyxVQUFVLENBQUMsS0FBSyxJQUFJLENBQUM7SUFDN0MsTUFBTSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsR0FBRyxVQUFVLENBQUMsTUFBTSxJQUFJLENBQUM7SUFDL0MsTUFBTSxDQUFDLEtBQUssQ0FBQyxTQUFTLEdBQUcsWUFBWSxDQUFDLFVBQVUsQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0FBQ3pFLENBQUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgR29vZ2xlIExMQyBBbGwgUmlnaHRzIFJlc2VydmVkLlxuICpcbiAqIFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG4gKiBmb3VuZCBpbiB0aGUgTElDRU5TRSBmaWxlIGF0IGh0dHBzOi8vYW5ndWxhci5pby9saWNlbnNlXG4gKi9cblxuaW1wb3J0IHtFbWJlZGRlZFZpZXdSZWYsIEVsZW1lbnRSZWYsIE5nWm9uZSwgVmlld0NvbnRhaW5lclJlZiwgVGVtcGxhdGVSZWZ9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtWaWV3cG9ydFJ1bGVyfSBmcm9tICdAYW5ndWxhci9jZGsvc2Nyb2xsaW5nJztcbmltcG9ydCB7RGlyZWN0aW9ufSBmcm9tICdAYW5ndWxhci9jZGsvYmlkaSc7XG5pbXBvcnQge1xuICBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zLFxuICBfZ2V0RXZlbnRUYXJnZXQsXG4gIF9nZXRTaGFkb3dSb290LFxufSBmcm9tICdAYW5ndWxhci9jZGsvcGxhdGZvcm0nO1xuaW1wb3J0IHtjb2VyY2VCb29sZWFuUHJvcGVydHksIGNvZXJjZUVsZW1lbnR9IGZyb20gJ0Bhbmd1bGFyL2Nkay9jb2VyY2lvbic7XG5pbXBvcnQge2lzRmFrZU1vdXNlZG93bkZyb21TY3JlZW5SZWFkZXIsIGlzRmFrZVRvdWNoc3RhcnRGcm9tU2NyZWVuUmVhZGVyfSBmcm9tICdAYW5ndWxhci9jZGsvYTExeSc7XG5pbXBvcnQge1N1YnNjcmlwdGlvbiwgU3ViamVjdCwgT2JzZXJ2YWJsZX0gZnJvbSAncnhqcyc7XG5pbXBvcnQge0Ryb3BMaXN0UmVmSW50ZXJuYWwgYXMgRHJvcExpc3RSZWZ9IGZyb20gJy4vZHJvcC1saXN0LXJlZic7XG5pbXBvcnQge0RyYWdEcm9wUmVnaXN0cnl9IGZyb20gJy4vZHJhZy1kcm9wLXJlZ2lzdHJ5JztcbmltcG9ydCB7XG4gIGNvbWJpbmVUcmFuc2Zvcm1zLFxuICBleHRlbmRTdHlsZXMsXG4gIHRvZ2dsZU5hdGl2ZURyYWdJbnRlcmFjdGlvbnMsXG4gIHRvZ2dsZVZpc2liaWxpdHksXG59IGZyb20gJy4vZHJhZy1zdHlsaW5nJztcbmltcG9ydCB7Z2V0VHJhbnNmb3JtVHJhbnNpdGlvbkR1cmF0aW9uSW5Nc30gZnJvbSAnLi90cmFuc2l0aW9uLWR1cmF0aW9uJztcbmltcG9ydCB7Z2V0TXV0YWJsZUNsaWVudFJlY3QsIGFkanVzdENsaWVudFJlY3R9IGZyb20gJy4vY2xpZW50LXJlY3QnO1xuaW1wb3J0IHtQYXJlbnRQb3NpdGlvblRyYWNrZXJ9IGZyb20gJy4vcGFyZW50LXBvc2l0aW9uLXRyYWNrZXInO1xuaW1wb3J0IHtkZWVwQ2xvbmVOb2RlfSBmcm9tICcuL2Nsb25lLW5vZGUnO1xuXG4vKiogT2JqZWN0IHRoYXQgY2FuIGJlIHVzZWQgdG8gY29uZmlndXJlIHRoZSBiZWhhdmlvciBvZiBEcmFnUmVmLiAqL1xuZXhwb3J0IGludGVyZmFjZSBEcmFnUmVmQ29uZmlnIHtcbiAgLyoqXG4gICAqIE1pbmltdW0gYW1vdW50IG9mIHBpeGVscyB0aGF0IHRoZSB1c2VyIHNob3VsZFxuICAgKiBkcmFnLCBiZWZvcmUgdGhlIENESyBpbml0aWF0ZXMgYSBkcmFnIHNlcXVlbmNlLlxuICAgKi9cbiAgZHJhZ1N0YXJ0VGhyZXNob2xkOiBudW1iZXI7XG5cbiAgLyoqXG4gICAqIEFtb3VudCB0aGUgcGl4ZWxzIHRoZSB1c2VyIHNob3VsZCBkcmFnIGJlZm9yZSB0aGUgQ0RLXG4gICAqIGNvbnNpZGVycyB0aGVtIHRvIGhhdmUgY2hhbmdlZCB0aGUgZHJhZyBkaXJlY3Rpb24uXG4gICAqL1xuICBwb2ludGVyRGlyZWN0aW9uQ2hhbmdlVGhyZXNob2xkOiBudW1iZXI7XG5cbiAgLyoqIGB6LWluZGV4YCBmb3IgdGhlIGFic29sdXRlbHktcG9zaXRpb25lZCBlbGVtZW50cyB0aGF0IGFyZSBjcmVhdGVkIGJ5IHRoZSBkcmFnIGl0ZW0uICovXG4gIHpJbmRleD86IG51bWJlcjtcblxuICAvKiogUmVmIHRoYXQgdGhlIGN1cnJlbnQgZHJhZyBpdGVtIGlzIG5lc3RlZCBpbi4gKi9cbiAgcGFyZW50RHJhZ1JlZj86IERyYWdSZWY7XG59XG5cbi8qKiBPcHRpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gYmluZCBhIHBhc3NpdmUgZXZlbnQgbGlzdGVuZXIuICovXG5jb25zdCBwYXNzaXZlRXZlbnRMaXN0ZW5lck9wdGlvbnMgPSBub3JtYWxpemVQYXNzaXZlTGlzdGVuZXJPcHRpb25zKHtwYXNzaXZlOiB0cnVlfSk7XG5cbi8qKiBPcHRpb25zIHRoYXQgY2FuIGJlIHVzZWQgdG8gYmluZCBhbiBhY3RpdmUgZXZlbnQgbGlzdGVuZXIuICovXG5jb25zdCBhY3RpdmVFdmVudExpc3RlbmVyT3B0aW9ucyA9IG5vcm1hbGl6ZVBhc3NpdmVMaXN0ZW5lck9wdGlvbnMoe3Bhc3NpdmU6IGZhbHNlfSk7XG5cbi8qKlxuICogVGltZSBpbiBtaWxsaXNlY29uZHMgZm9yIHdoaWNoIHRvIGlnbm9yZSBtb3VzZSBldmVudHMsIGFmdGVyXG4gKiByZWNlaXZpbmcgYSB0b3VjaCBldmVudC4gVXNlZCB0byBhdm9pZCBkb2luZyBkb3VibGUgd29yayBmb3JcbiAqIHRvdWNoIGRldmljZXMgd2hlcmUgdGhlIGJyb3dzZXIgZmlyZXMgZmFrZSBtb3VzZSBldmVudHMsIGluXG4gKiBhZGRpdGlvbiB0byB0b3VjaCBldmVudHMuXG4gKi9cbmNvbnN0IE1PVVNFX0VWRU5UX0lHTk9SRV9USU1FID0gODAwO1xuXG4vLyBUT0RPKGNyaXNiZXRvKTogYWRkIGFuIEFQSSBmb3IgbW92aW5nIGEgZHJhZ2dhYmxlIHVwL2Rvd24gdGhlXG4vLyBsaXN0IHByb2dyYW1tYXRpY2FsbHkuIFVzZWZ1bCBmb3Iga2V5Ym9hcmQgY29udHJvbHMuXG5cbi8qKlxuICogSW50ZXJuYWwgY29tcGlsZS10aW1lLW9ubHkgcmVwcmVzZW50YXRpb24gb2YgYSBgRHJhZ1JlZmAuXG4gKiBVc2VkIHRvIGF2b2lkIGNpcmN1bGFyIGltcG9ydCBpc3N1ZXMgYmV0d2VlbiB0aGUgYERyYWdSZWZgIGFuZCB0aGUgYERyb3BMaXN0UmVmYC5cbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuZXhwb3J0IGludGVyZmFjZSBEcmFnUmVmSW50ZXJuYWwgZXh0ZW5kcyBEcmFnUmVmIHt9XG5cbi8qKiBUZW1wbGF0ZSB0aGF0IGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBhIGRyYWcgaGVscGVyIGVsZW1lbnQgKGUuZy4gYSBwcmV2aWV3IG9yIGEgcGxhY2Vob2xkZXIpLiAqL1xuaW50ZXJmYWNlIERyYWdIZWxwZXJUZW1wbGF0ZTxUID0gYW55PiB7XG4gIHRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxUPiB8IG51bGw7XG4gIHZpZXdDb250YWluZXI6IFZpZXdDb250YWluZXJSZWY7XG4gIGNvbnRleHQ6IFQ7XG59XG5cbi8qKiBUZW1wbGF0ZSB0aGF0IGNhbiBiZSB1c2VkIHRvIGNyZWF0ZSBhIGRyYWcgcHJldmlldyBlbGVtZW50LiAqL1xuaW50ZXJmYWNlIERyYWdQcmV2aWV3VGVtcGxhdGU8VCA9IGFueT4gZXh0ZW5kcyBEcmFnSGVscGVyVGVtcGxhdGU8VD4ge1xuICBtYXRjaFNpemU/OiBib29sZWFuO1xufVxuXG4vKiogUG9pbnQgb24gdGhlIHBhZ2Ugb3Igd2l0aGluIGFuIGVsZW1lbnQuICovXG5leHBvcnQgaW50ZXJmYWNlIFBvaW50IHtcbiAgeDogbnVtYmVyO1xuICB5OiBudW1iZXI7XG59XG5cbi8qKiBJbmxpbmUgc3R5bGVzIHRvIGJlIHNldCBhcyBgIWltcG9ydGFudGAgd2hpbGUgZHJhZ2dpbmcuICovXG5jb25zdCBkcmFnSW1wb3J0YW50UHJvcGVydGllcyA9IG5ldyBTZXQoW1xuICAvLyBOZWVkcyB0byBiZSBpbXBvcnRhbnQsIGJlY2F1c2Ugc29tZSBgbWF0LXRhYmxlYCBzZXRzIGBwb3NpdGlvbjogc3RpY2t5ICFpbXBvcnRhbnRgLiBTZWUgIzIyNzgxLlxuICAncG9zaXRpb24nLFxuXSk7XG5cbi8qKlxuICogUG9zc2libGUgcGxhY2VzIGludG8gd2hpY2ggdGhlIHByZXZpZXcgb2YgYSBkcmFnIGl0ZW0gY2FuIGJlIGluc2VydGVkLlxuICogLSBgZ2xvYmFsYCAtIFByZXZpZXcgd2lsbCBiZSBpbnNlcnRlZCBhdCB0aGUgYm90dG9tIG9mIHRoZSBgPGJvZHk+YC4gVGhlIGFkdmFudGFnZSBpcyB0aGF0XG4gKiB5b3UgZG9uJ3QgaGF2ZSB0byB3b3JyeSBhYm91dCBgb3ZlcmZsb3c6IGhpZGRlbmAgb3IgYHotaW5kZXhgLCBidXQgdGhlIGl0ZW0gd29uJ3QgcmV0YWluXG4gKiBpdHMgaW5oZXJpdGVkIHN0eWxlcy5cbiAqIC0gYHBhcmVudGAgLSBQcmV2aWV3IHdpbGwgYmUgaW5zZXJ0ZWQgaW50byB0aGUgcGFyZW50IG9mIHRoZSBkcmFnIGl0ZW0uIFRoZSBhZHZhbnRhZ2UgaXMgdGhhdFxuICogaW5oZXJpdGVkIHN0eWxlcyB3aWxsIGJlIHByZXNlcnZlZCwgYnV0IGl0IG1heSBiZSBjbGlwcGVkIGJ5IGBvdmVyZmxvdzogaGlkZGVuYCBvciBub3QgYmVcbiAqIHZpc2libGUgZHVlIHRvIGB6LWluZGV4YC4gRnVydGhlcm1vcmUsIHRoZSBwcmV2aWV3IGlzIGdvaW5nIHRvIGhhdmUgYW4gZWZmZWN0IG92ZXIgc2VsZWN0b3JzXG4gKiBsaWtlIGA6bnRoLWNoaWxkYCBhbmQgc29tZSBmbGV4Ym94IGNvbmZpZ3VyYXRpb25zLlxuICogLSBgRWxlbWVudFJlZjxIVE1MRWxlbWVudD4gfCBIVE1MRWxlbWVudGAgLSBQcmV2aWV3IHdpbGwgYmUgaW5zZXJ0ZWQgaW50byBhIHNwZWNpZmljIGVsZW1lbnQuXG4gKiBTYW1lIGFkdmFudGFnZXMgYW5kIGRpc2FkdmFudGFnZXMgYXMgYHBhcmVudGAuXG4gKi9cbmV4cG9ydCB0eXBlIFByZXZpZXdDb250YWluZXIgPSAnZ2xvYmFsJyB8ICdwYXJlbnQnIHwgRWxlbWVudFJlZjxIVE1MRWxlbWVudD4gfCBIVE1MRWxlbWVudDtcblxuLyoqXG4gKiBSZWZlcmVuY2UgdG8gYSBkcmFnZ2FibGUgaXRlbS4gVXNlZCB0byBtYW5pcHVsYXRlIG9yIGRpc3Bvc2Ugb2YgdGhlIGl0ZW0uXG4gKi9cbmV4cG9ydCBjbGFzcyBEcmFnUmVmPFQgPSBhbnk+IHtcbiAgLyoqIEVsZW1lbnQgZGlzcGxheWVkIG5leHQgdG8gdGhlIHVzZXIncyBwb2ludGVyIHdoaWxlIHRoZSBlbGVtZW50IGlzIGRyYWdnZWQuICovXG4gIHByaXZhdGUgX3ByZXZpZXc6IEhUTUxFbGVtZW50O1xuXG4gIC8qKiBSZWZlcmVuY2UgdG8gdGhlIHZpZXcgb2YgdGhlIHByZXZpZXcgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfcHJldmlld1JlZjogRW1iZWRkZWRWaWV3UmVmPGFueT4gfCBudWxsO1xuXG4gIC8qKiBDb250YWluZXIgaW50byB3aGljaCB0byBpbnNlcnQgdGhlIHByZXZpZXcuICovXG4gIHByaXZhdGUgX3ByZXZpZXdDb250YWluZXI6IFByZXZpZXdDb250YWluZXIgfCB1bmRlZmluZWQ7XG5cbiAgLyoqIFJlZmVyZW5jZSB0byB0aGUgdmlldyBvZiB0aGUgcGxhY2Vob2xkZXIgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfcGxhY2Vob2xkZXJSZWY6IEVtYmVkZGVkVmlld1JlZjxhbnk+IHwgbnVsbDtcblxuICAvKiogRWxlbWVudCB0aGF0IGlzIHJlbmRlcmVkIGluc3RlYWQgb2YgdGhlIGRyYWdnYWJsZSBpdGVtIHdoaWxlIGl0IGlzIGJlaW5nIHNvcnRlZC4gKi9cbiAgcHJpdmF0ZSBfcGxhY2Vob2xkZXI6IEhUTUxFbGVtZW50O1xuXG4gIC8qKiBDb29yZGluYXRlcyB3aXRoaW4gdGhlIGVsZW1lbnQgYXQgd2hpY2ggdGhlIHVzZXIgcGlja2VkIHVwIHRoZSBlbGVtZW50LiAqL1xuICBwcml2YXRlIF9waWNrdXBQb3NpdGlvbkluRWxlbWVudDogUG9pbnQ7XG5cbiAgLyoqIENvb3JkaW5hdGVzIG9uIHRoZSBwYWdlIGF0IHdoaWNoIHRoZSB1c2VyIHBpY2tlZCB1cCB0aGUgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfcGlja3VwUG9zaXRpb25PblBhZ2U6IFBvaW50O1xuXG4gIC8qKlxuICAgKiBBbmNob3Igbm9kZSB1c2VkIHRvIHNhdmUgdGhlIHBsYWNlIGluIHRoZSBET00gd2hlcmUgdGhlIGVsZW1lbnQgd2FzXG4gICAqIHBpY2tlZCB1cCBzbyB0aGF0IGl0IGNhbiBiZSByZXN0b3JlZCBhdCB0aGUgZW5kIG9mIHRoZSBkcmFnIHNlcXVlbmNlLlxuICAgKi9cbiAgcHJpdmF0ZSBfYW5jaG9yOiBDb21tZW50O1xuXG4gIC8qKlxuICAgKiBDU1MgYHRyYW5zZm9ybWAgYXBwbGllZCB0byB0aGUgZWxlbWVudCB3aGVuIGl0IGlzbid0IGJlaW5nIGRyYWdnZWQuIFdlIG5lZWQgYVxuICAgKiBwYXNzaXZlIHRyYW5zZm9ybSBpbiBvcmRlciBmb3IgdGhlIGRyYWdnZWQgZWxlbWVudCB0byByZXRhaW4gaXRzIG5ldyBwb3NpdGlvblxuICAgKiBhZnRlciB0aGUgdXNlciBoYXMgc3RvcHBlZCBkcmFnZ2luZyBhbmQgYmVjYXVzZSB3ZSBuZWVkIHRvIGtub3cgdGhlIHJlbGF0aXZlXG4gICAqIHBvc2l0aW9uIGluIGNhc2UgdGhleSBzdGFydCBkcmFnZ2luZyBhZ2Fpbi4gVGhpcyBjb3JyZXNwb25kcyB0byBgZWxlbWVudC5zdHlsZS50cmFuc2Zvcm1gLlxuICAgKi9cbiAgcHJpdmF0ZSBfcGFzc2l2ZVRyYW5zZm9ybTogUG9pbnQgPSB7eDogMCwgeTogMH07XG5cbiAgLyoqIENTUyBgdHJhbnNmb3JtYCB0aGF0IGlzIGFwcGxpZWQgdG8gdGhlIGVsZW1lbnQgd2hpbGUgaXQncyBiZWluZyBkcmFnZ2VkLiAqL1xuICBwcml2YXRlIF9hY3RpdmVUcmFuc2Zvcm06IFBvaW50ID0ge3g6IDAsIHk6IDB9O1xuXG4gIC8qKiBJbmxpbmUgYHRyYW5zZm9ybWAgdmFsdWUgdGhhdCB0aGUgZWxlbWVudCBoYWQgYmVmb3JlIHRoZSBmaXJzdCBkcmFnZ2luZyBzZXF1ZW5jZS4gKi9cbiAgcHJpdmF0ZSBfaW5pdGlhbFRyYW5zZm9ybT86IHN0cmluZztcblxuICAvKipcbiAgICogV2hldGhlciB0aGUgZHJhZ2dpbmcgc2VxdWVuY2UgaGFzIGJlZW4gc3RhcnRlZC4gRG9lc24ndFxuICAgKiBuZWNlc3NhcmlseSBtZWFuIHRoYXQgdGhlIGVsZW1lbnQgaGFzIGJlZW4gbW92ZWQuXG4gICAqL1xuICBwcml2YXRlIF9oYXNTdGFydGVkRHJhZ2dpbmcgPSBmYWxzZTtcblxuICAvKiogV2hldGhlciB0aGUgZWxlbWVudCBoYXMgbW92ZWQgc2luY2UgdGhlIHVzZXIgc3RhcnRlZCBkcmFnZ2luZyBpdC4gKi9cbiAgcHJpdmF0ZSBfaGFzTW92ZWQ6IGJvb2xlYW47XG5cbiAgLyoqIERyb3AgY29udGFpbmVyIGluIHdoaWNoIHRoZSBEcmFnUmVmIHJlc2lkZWQgd2hlbiBkcmFnZ2luZyBiZWdhbi4gKi9cbiAgcHJpdmF0ZSBfaW5pdGlhbENvbnRhaW5lcjogRHJvcExpc3RSZWY7XG5cbiAgLyoqIEluZGV4IGF0IHdoaWNoIHRoZSBpdGVtIHN0YXJ0ZWQgaW4gaXRzIGluaXRpYWwgY29udGFpbmVyLiAqL1xuICBwcml2YXRlIF9pbml0aWFsSW5kZXg6IG51bWJlcjtcblxuICAvKiogQ2FjaGVkIHBvc2l0aW9ucyBvZiBzY3JvbGxhYmxlIHBhcmVudCBlbGVtZW50cy4gKi9cbiAgcHJpdmF0ZSBfcGFyZW50UG9zaXRpb25zOiBQYXJlbnRQb3NpdGlvblRyYWNrZXI7XG5cbiAgLyoqIEVtaXRzIHdoZW4gdGhlIGl0ZW0gaXMgYmVpbmcgbW92ZWQuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgX21vdmVFdmVudHMgPSBuZXcgU3ViamVjdDx7XG4gICAgc291cmNlOiBEcmFnUmVmO1xuICAgIHBvaW50ZXJQb3NpdGlvbjoge3g6IG51bWJlcjsgeTogbnVtYmVyfTtcbiAgICBldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQ7XG4gICAgZGlzdGFuY2U6IFBvaW50O1xuICAgIGRlbHRhOiB7eDogLTEgfCAwIHwgMTsgeTogLTEgfCAwIHwgMX07XG4gIH0+KCk7XG5cbiAgLyoqIEtlZXBzIHRyYWNrIG9mIHRoZSBkaXJlY3Rpb24gaW4gd2hpY2ggdGhlIHVzZXIgaXMgZHJhZ2dpbmcgYWxvbmcgZWFjaCBheGlzLiAqL1xuICBwcml2YXRlIF9wb2ludGVyRGlyZWN0aW9uRGVsdGE6IHt4OiAtMSB8IDAgfCAxOyB5OiAtMSB8IDAgfCAxfTtcblxuICAvKiogUG9pbnRlciBwb3NpdGlvbiBhdCB3aGljaCB0aGUgbGFzdCBjaGFuZ2UgaW4gdGhlIGRlbHRhIG9jY3VycmVkLiAqL1xuICBwcml2YXRlIF9wb2ludGVyUG9zaXRpb25BdExhc3REaXJlY3Rpb25DaGFuZ2U6IFBvaW50O1xuXG4gIC8qKiBQb3NpdGlvbiBvZiB0aGUgcG9pbnRlciBhdCB0aGUgbGFzdCBwb2ludGVyIGV2ZW50LiAqL1xuICBwcml2YXRlIF9sYXN0S25vd25Qb2ludGVyUG9zaXRpb246IFBvaW50O1xuXG4gIC8qKlxuICAgKiBSb290IERPTSBub2RlIG9mIHRoZSBkcmFnIGluc3RhbmNlLiBUaGlzIGlzIHRoZSBlbGVtZW50IHRoYXQgd2lsbFxuICAgKiBiZSBtb3ZlZCBhcm91bmQgYXMgdGhlIHVzZXIgaXMgZHJhZ2dpbmcuXG4gICAqL1xuICBwcml2YXRlIF9yb290RWxlbWVudDogSFRNTEVsZW1lbnQ7XG5cbiAgLyoqXG4gICAqIE5lYXJlc3QgYW5jZXN0b3IgU1ZHLCByZWxhdGl2ZSB0byB3aGljaCBjb29yZGluYXRlcyBhcmUgY2FsY3VsYXRlZCBpZiBkcmFnZ2luZyBTVkdFbGVtZW50XG4gICAqL1xuICBwcml2YXRlIF9vd25lclNWR0VsZW1lbnQ6IFNWR1NWR0VsZW1lbnQgfCBudWxsO1xuXG4gIC8qKlxuICAgKiBJbmxpbmUgc3R5bGUgdmFsdWUgb2YgYC13ZWJraXQtdGFwLWhpZ2hsaWdodC1jb2xvcmAgYXQgdGhlIHRpbWUgdGhlXG4gICAqIGRyYWdnaW5nIHdhcyBzdGFydGVkLiBVc2VkIHRvIHJlc3RvcmUgdGhlIHZhbHVlIG9uY2Ugd2UncmUgZG9uZSBkcmFnZ2luZy5cbiAgICovXG4gIHByaXZhdGUgX3Jvb3RFbGVtZW50VGFwSGlnaGxpZ2h0OiBzdHJpbmc7XG5cbiAgLyoqIFN1YnNjcmlwdGlvbiB0byBwb2ludGVyIG1vdmVtZW50IGV2ZW50cy4gKi9cbiAgcHJpdmF0ZSBfcG9pbnRlck1vdmVTdWJzY3JpcHRpb24gPSBTdWJzY3JpcHRpb24uRU1QVFk7XG5cbiAgLyoqIFN1YnNjcmlwdGlvbiB0byB0aGUgZXZlbnQgdGhhdCBpcyBkaXNwYXRjaGVkIHdoZW4gdGhlIHVzZXIgbGlmdHMgdGhlaXIgcG9pbnRlci4gKi9cbiAgcHJpdmF0ZSBfcG9pbnRlclVwU3Vic2NyaXB0aW9uID0gU3Vic2NyaXB0aW9uLkVNUFRZO1xuXG4gIC8qKiBTdWJzY3JpcHRpb24gdG8gdGhlIHZpZXdwb3J0IGJlaW5nIHNjcm9sbGVkLiAqL1xuICBwcml2YXRlIF9zY3JvbGxTdWJzY3JpcHRpb24gPSBTdWJzY3JpcHRpb24uRU1QVFk7XG5cbiAgLyoqIFN1YnNjcmlwdGlvbiB0byB0aGUgdmlld3BvcnQgYmVpbmcgcmVzaXplZC4gKi9cbiAgcHJpdmF0ZSBfcmVzaXplU3Vic2NyaXB0aW9uID0gU3Vic2NyaXB0aW9uLkVNUFRZO1xuXG4gIC8qKlxuICAgKiBUaW1lIGF0IHdoaWNoIHRoZSBsYXN0IHRvdWNoIGV2ZW50IG9jY3VycmVkLiBVc2VkIHRvIGF2b2lkIGZpcmluZyB0aGUgc2FtZVxuICAgKiBldmVudHMgbXVsdGlwbGUgdGltZXMgb24gdG91Y2ggZGV2aWNlcyB3aGVyZSB0aGUgYnJvd3NlciB3aWxsIGZpcmUgYSBmYWtlXG4gICAqIG1vdXNlIGV2ZW50IGZvciBlYWNoIHRvdWNoIGV2ZW50LCBhZnRlciBhIGNlcnRhaW4gdGltZS5cbiAgICovXG4gIHByaXZhdGUgX2xhc3RUb3VjaEV2ZW50VGltZTogbnVtYmVyO1xuXG4gIC8qKiBUaW1lIGF0IHdoaWNoIHRoZSBsYXN0IGRyYWdnaW5nIHNlcXVlbmNlIHdhcyBzdGFydGVkLiAqL1xuICBwcml2YXRlIF9kcmFnU3RhcnRUaW1lOiBudW1iZXI7XG5cbiAgLyoqIENhY2hlZCByZWZlcmVuY2UgdG8gdGhlIGJvdW5kYXJ5IGVsZW1lbnQuICovXG4gIHByaXZhdGUgX2JvdW5kYXJ5RWxlbWVudDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuICAvKiogV2hldGhlciB0aGUgbmF0aXZlIGRyYWdnaW5nIGludGVyYWN0aW9ucyBoYXZlIGJlZW4gZW5hYmxlZCBvbiB0aGUgcm9vdCBlbGVtZW50LiAqL1xuICBwcml2YXRlIF9uYXRpdmVJbnRlcmFjdGlvbnNFbmFibGVkID0gdHJ1ZTtcblxuICAvKiogQ2FjaGVkIGRpbWVuc2lvbnMgb2YgdGhlIHByZXZpZXcgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfcHJldmlld1JlY3Q/OiBDbGllbnRSZWN0O1xuXG4gIC8qKiBDYWNoZWQgZGltZW5zaW9ucyBvZiB0aGUgYm91bmRhcnkgZWxlbWVudC4gKi9cbiAgcHJpdmF0ZSBfYm91bmRhcnlSZWN0PzogQ2xpZW50UmVjdDtcblxuICAvKiogRWxlbWVudCB0aGF0IHdpbGwgYmUgdXNlZCBhcyBhIHRlbXBsYXRlIHRvIGNyZWF0ZSB0aGUgZHJhZ2dhYmxlIGl0ZW0ncyBwcmV2aWV3LiAqL1xuICBwcml2YXRlIF9wcmV2aWV3VGVtcGxhdGU/OiBEcmFnUHJldmlld1RlbXBsYXRlIHwgbnVsbDtcblxuICAvKiogVGVtcGxhdGUgZm9yIHBsYWNlaG9sZGVyIGVsZW1lbnQgcmVuZGVyZWQgdG8gc2hvdyB3aGVyZSBhIGRyYWdnYWJsZSB3b3VsZCBiZSBkcm9wcGVkLiAqL1xuICBwcml2YXRlIF9wbGFjZWhvbGRlclRlbXBsYXRlPzogRHJhZ0hlbHBlclRlbXBsYXRlIHwgbnVsbDtcblxuICAvKiogRWxlbWVudHMgdGhhdCBjYW4gYmUgdXNlZCB0byBkcmFnIHRoZSBkcmFnZ2FibGUgaXRlbS4gKi9cbiAgcHJpdmF0ZSBfaGFuZGxlczogSFRNTEVsZW1lbnRbXSA9IFtdO1xuXG4gIC8qKiBSZWdpc3RlcmVkIGhhbmRsZXMgdGhhdCBhcmUgY3VycmVudGx5IGRpc2FibGVkLiAqL1xuICBwcml2YXRlIF9kaXNhYmxlZEhhbmRsZXMgPSBuZXcgU2V0PEhUTUxFbGVtZW50PigpO1xuXG4gIC8qKiBEcm9wcGFibGUgY29udGFpbmVyIHRoYXQgdGhlIGRyYWdnYWJsZSBpcyBhIHBhcnQgb2YuICovXG4gIHByaXZhdGUgX2Ryb3BDb250YWluZXI/OiBEcm9wTGlzdFJlZjtcblxuICAvKiogTGF5b3V0IGRpcmVjdGlvbiBvZiB0aGUgaXRlbS4gKi9cbiAgcHJpdmF0ZSBfZGlyZWN0aW9uOiBEaXJlY3Rpb24gPSAnbHRyJztcblxuICAvKiogUmVmIHRoYXQgdGhlIGN1cnJlbnQgZHJhZyBpdGVtIGlzIG5lc3RlZCBpbi4gKi9cbiAgcHJpdmF0ZSBfcGFyZW50RHJhZ1JlZjogRHJhZ1JlZjx1bmtub3duPiB8IG51bGw7XG5cbiAgLyoqXG4gICAqIENhY2hlZCBzaGFkb3cgcm9vdCB0aGF0IHRoZSBlbGVtZW50IGlzIHBsYWNlZCBpbi4gYG51bGxgIG1lYW5zIHRoYXQgdGhlIGVsZW1lbnQgaXNuJ3QgaW5cbiAgICogdGhlIHNoYWRvdyBET00gYW5kIGB1bmRlZmluZWRgIG1lYW5zIHRoYXQgaXQgaGFzbid0IGJlZW4gcmVzb2x2ZWQgeWV0LiBTaG91bGQgYmUgcmVhZCB2aWFcbiAgICogYF9nZXRTaGFkb3dSb290YCwgbm90IGRpcmVjdGx5LlxuICAgKi9cbiAgcHJpdmF0ZSBfY2FjaGVkU2hhZG93Um9vdDogU2hhZG93Um9vdCB8IG51bGwgfCB1bmRlZmluZWQ7XG5cbiAgLyoqIEF4aXMgYWxvbmcgd2hpY2ggZHJhZ2dpbmcgaXMgbG9ja2VkLiAqL1xuICBsb2NrQXhpczogJ3gnIHwgJ3knO1xuXG4gIC8qKlxuICAgKiBBbW91bnQgb2YgbWlsbGlzZWNvbmRzIHRvIHdhaXQgYWZ0ZXIgdGhlIHVzZXIgaGFzIHB1dCB0aGVpclxuICAgKiBwb2ludGVyIGRvd24gYmVmb3JlIHN0YXJ0aW5nIHRvIGRyYWcgdGhlIGVsZW1lbnQuXG4gICAqL1xuICBkcmFnU3RhcnREZWxheTogbnVtYmVyIHwge3RvdWNoOiBudW1iZXI7IG1vdXNlOiBudW1iZXJ9ID0gMDtcblxuICAvKiogQ2xhc3MgdG8gYmUgYWRkZWQgdG8gdGhlIHByZXZpZXcgZWxlbWVudC4gKi9cbiAgcHJldmlld0NsYXNzOiBzdHJpbmcgfCBzdHJpbmdbXSB8IHVuZGVmaW5lZDtcblxuICAvKiogV2hldGhlciBzdGFydGluZyB0byBkcmFnIHRoaXMgZWxlbWVudCBpcyBkaXNhYmxlZC4gKi9cbiAgZ2V0IGRpc2FibGVkKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9kaXNhYmxlZCB8fCAhISh0aGlzLl9kcm9wQ29udGFpbmVyICYmIHRoaXMuX2Ryb3BDb250YWluZXIuZGlzYWJsZWQpO1xuICB9XG4gIHNldCBkaXNhYmxlZCh2YWx1ZTogYm9vbGVhbikge1xuICAgIGNvbnN0IG5ld1ZhbHVlID0gY29lcmNlQm9vbGVhblByb3BlcnR5KHZhbHVlKTtcblxuICAgIGlmIChuZXdWYWx1ZSAhPT0gdGhpcy5fZGlzYWJsZWQpIHtcbiAgICAgIHRoaXMuX2Rpc2FibGVkID0gbmV3VmFsdWU7XG4gICAgICB0aGlzLl90b2dnbGVOYXRpdmVEcmFnSW50ZXJhY3Rpb25zKCk7XG4gICAgICB0aGlzLl9oYW5kbGVzLmZvckVhY2goaGFuZGxlID0+IHRvZ2dsZU5hdGl2ZURyYWdJbnRlcmFjdGlvbnMoaGFuZGxlLCBuZXdWYWx1ZSkpO1xuICAgIH1cbiAgfVxuICBwcml2YXRlIF9kaXNhYmxlZCA9IGZhbHNlO1xuXG4gIC8qKiBFbWl0cyBhcyB0aGUgZHJhZyBzZXF1ZW5jZSBpcyBiZWluZyBwcmVwYXJlZC4gKi9cbiAgcmVhZG9ubHkgYmVmb3JlU3RhcnRlZCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG5cbiAgLyoqIEVtaXRzIHdoZW4gdGhlIHVzZXIgc3RhcnRzIGRyYWdnaW5nIHRoZSBpdGVtLiAqL1xuICByZWFkb25seSBzdGFydGVkID0gbmV3IFN1YmplY3Q8e3NvdXJjZTogRHJhZ1JlZn0+KCk7XG5cbiAgLyoqIEVtaXRzIHdoZW4gdGhlIHVzZXIgaGFzIHJlbGVhc2VkIGEgZHJhZyBpdGVtLCBiZWZvcmUgYW55IGFuaW1hdGlvbnMgaGF2ZSBzdGFydGVkLiAqL1xuICByZWFkb25seSByZWxlYXNlZCA9IG5ldyBTdWJqZWN0PHtzb3VyY2U6IERyYWdSZWZ9PigpO1xuXG4gIC8qKiBFbWl0cyB3aGVuIHRoZSB1c2VyIHN0b3BzIGRyYWdnaW5nIGFuIGl0ZW0gaW4gdGhlIGNvbnRhaW5lci4gKi9cbiAgcmVhZG9ubHkgZW5kZWQgPSBuZXcgU3ViamVjdDx7c291cmNlOiBEcmFnUmVmOyBkaXN0YW5jZTogUG9pbnQ7IGRyb3BQb2ludDogUG9pbnR9PigpO1xuXG4gIC8qKiBFbWl0cyB3aGVuIHRoZSB1c2VyIGhhcyBtb3ZlZCB0aGUgaXRlbSBpbnRvIGEgbmV3IGNvbnRhaW5lci4gKi9cbiAgcmVhZG9ubHkgZW50ZXJlZCA9IG5ldyBTdWJqZWN0PHtjb250YWluZXI6IERyb3BMaXN0UmVmOyBpdGVtOiBEcmFnUmVmOyBjdXJyZW50SW5kZXg6IG51bWJlcn0+KCk7XG5cbiAgLyoqIEVtaXRzIHdoZW4gdGhlIHVzZXIgcmVtb3ZlcyB0aGUgaXRlbSBpdHMgY29udGFpbmVyIGJ5IGRyYWdnaW5nIGl0IGludG8gYW5vdGhlciBjb250YWluZXIuICovXG4gIHJlYWRvbmx5IGV4aXRlZCA9IG5ldyBTdWJqZWN0PHtjb250YWluZXI6IERyb3BMaXN0UmVmOyBpdGVtOiBEcmFnUmVmfT4oKTtcblxuICAvKiogRW1pdHMgd2hlbiB0aGUgdXNlciBkcm9wcyB0aGUgaXRlbSBpbnNpZGUgYSBjb250YWluZXIuICovXG4gIHJlYWRvbmx5IGRyb3BwZWQgPSBuZXcgU3ViamVjdDx7XG4gICAgcHJldmlvdXNJbmRleDogbnVtYmVyO1xuICAgIGN1cnJlbnRJbmRleDogbnVtYmVyO1xuICAgIGl0ZW06IERyYWdSZWY7XG4gICAgY29udGFpbmVyOiBEcm9wTGlzdFJlZjtcbiAgICBwcmV2aW91c0NvbnRhaW5lcjogRHJvcExpc3RSZWY7XG4gICAgZGlzdGFuY2U6IFBvaW50O1xuICAgIGRyb3BQb2ludDogUG9pbnQ7XG4gICAgaXNQb2ludGVyT3ZlckNvbnRhaW5lcjogYm9vbGVhbjtcbiAgfT4oKTtcblxuICAvKipcbiAgICogRW1pdHMgYXMgdGhlIHVzZXIgaXMgZHJhZ2dpbmcgdGhlIGl0ZW0uIFVzZSB3aXRoIGNhdXRpb24sXG4gICAqIGJlY2F1c2UgdGhpcyBldmVudCB3aWxsIGZpcmUgZm9yIGV2ZXJ5IHBpeGVsIHRoYXQgdGhlIHVzZXIgaGFzIGRyYWdnZWQuXG4gICAqL1xuICByZWFkb25seSBtb3ZlZDogT2JzZXJ2YWJsZTx7XG4gICAgc291cmNlOiBEcmFnUmVmO1xuICAgIHBvaW50ZXJQb3NpdGlvbjoge3g6IG51bWJlcjsgeTogbnVtYmVyfTtcbiAgICBldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQ7XG4gICAgZGlzdGFuY2U6IFBvaW50O1xuICAgIGRlbHRhOiB7eDogLTEgfCAwIHwgMTsgeTogLTEgfCAwIHwgMX07XG4gIH0+ID0gdGhpcy5fbW92ZUV2ZW50cztcblxuICAvKiogQXJiaXRyYXJ5IGRhdGEgdGhhdCBjYW4gYmUgYXR0YWNoZWQgdG8gdGhlIGRyYWcgaXRlbS4gKi9cbiAgZGF0YTogVDtcblxuICAvKipcbiAgICogRnVuY3Rpb24gdGhhdCBjYW4gYmUgdXNlZCB0byBjdXN0b21pemUgdGhlIGxvZ2ljIG9mIGhvdyB0aGUgcG9zaXRpb24gb2YgdGhlIGRyYWcgaXRlbVxuICAgKiBpcyBsaW1pdGVkIHdoaWxlIGl0J3MgYmVpbmcgZHJhZ2dlZC4gR2V0cyBjYWxsZWQgd2l0aCBhIHBvaW50IGNvbnRhaW5pbmcgdGhlIGN1cnJlbnQgcG9zaXRpb25cbiAgICogb2YgdGhlIHVzZXIncyBwb2ludGVyIG9uIHRoZSBwYWdlIGFuZCBzaG91bGQgcmV0dXJuIGEgcG9pbnQgZGVzY3JpYmluZyB3aGVyZSB0aGUgaXRlbSBzaG91bGRcbiAgICogYmUgcmVuZGVyZWQuXG4gICAqL1xuICBjb25zdHJhaW5Qb3NpdGlvbj86IChwb2ludDogUG9pbnQsIGRyYWdSZWY6IERyYWdSZWYpID0+IFBvaW50O1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIGVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgSFRNTEVsZW1lbnQsXG4gICAgcHJpdmF0ZSBfY29uZmlnOiBEcmFnUmVmQ29uZmlnLFxuICAgIHByaXZhdGUgX2RvY3VtZW50OiBEb2N1bWVudCxcbiAgICBwcml2YXRlIF9uZ1pvbmU6IE5nWm9uZSxcbiAgICBwcml2YXRlIF92aWV3cG9ydFJ1bGVyOiBWaWV3cG9ydFJ1bGVyLFxuICAgIHByaXZhdGUgX2RyYWdEcm9wUmVnaXN0cnk6IERyYWdEcm9wUmVnaXN0cnk8RHJhZ1JlZiwgRHJvcExpc3RSZWY+LFxuICApIHtcbiAgICB0aGlzLndpdGhSb290RWxlbWVudChlbGVtZW50KS53aXRoUGFyZW50KF9jb25maWcucGFyZW50RHJhZ1JlZiB8fCBudWxsKTtcbiAgICB0aGlzLl9wYXJlbnRQb3NpdGlvbnMgPSBuZXcgUGFyZW50UG9zaXRpb25UcmFja2VyKF9kb2N1bWVudCwgX3ZpZXdwb3J0UnVsZXIpO1xuICAgIF9kcmFnRHJvcFJlZ2lzdHJ5LnJlZ2lzdGVyRHJhZ0l0ZW0odGhpcyk7XG4gIH1cblxuICAvKipcbiAgICogUmV0dXJucyB0aGUgZWxlbWVudCB0aGF0IGlzIGJlaW5nIHVzZWQgYXMgYSBwbGFjZWhvbGRlclxuICAgKiB3aGlsZSB0aGUgY3VycmVudCBlbGVtZW50IGlzIGJlaW5nIGRyYWdnZWQuXG4gICAqL1xuICBnZXRQbGFjZWhvbGRlckVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgIHJldHVybiB0aGlzLl9wbGFjZWhvbGRlcjtcbiAgfVxuXG4gIC8qKiBSZXR1cm5zIHRoZSByb290IGRyYWdnYWJsZSBlbGVtZW50LiAqL1xuICBnZXRSb290RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgcmV0dXJuIHRoaXMuX3Jvb3RFbGVtZW50O1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGN1cnJlbnRseS12aXNpYmxlIGVsZW1lbnQgdGhhdCByZXByZXNlbnRzIHRoZSBkcmFnIGl0ZW0uXG4gICAqIFdoaWxlIGRyYWdnaW5nIHRoaXMgaXMgdGhlIHBsYWNlaG9sZGVyLCBvdGhlcndpc2UgaXQncyB0aGUgcm9vdCBlbGVtZW50LlxuICAgKi9cbiAgZ2V0VmlzaWJsZUVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgIHJldHVybiB0aGlzLmlzRHJhZ2dpbmcoKSA/IHRoaXMuZ2V0UGxhY2Vob2xkZXJFbGVtZW50KCkgOiB0aGlzLmdldFJvb3RFbGVtZW50KCk7XG4gIH1cblxuICAvKiogUmVnaXN0ZXJzIHRoZSBoYW5kbGVzIHRoYXQgY2FuIGJlIHVzZWQgdG8gZHJhZyB0aGUgZWxlbWVudC4gKi9cbiAgd2l0aEhhbmRsZXMoaGFuZGxlczogKEhUTUxFbGVtZW50IHwgRWxlbWVudFJlZjxIVE1MRWxlbWVudD4pW10pOiB0aGlzIHtcbiAgICB0aGlzLl9oYW5kbGVzID0gaGFuZGxlcy5tYXAoaGFuZGxlID0+IGNvZXJjZUVsZW1lbnQoaGFuZGxlKSk7XG4gICAgdGhpcy5faGFuZGxlcy5mb3JFYWNoKGhhbmRsZSA9PiB0b2dnbGVOYXRpdmVEcmFnSW50ZXJhY3Rpb25zKGhhbmRsZSwgdGhpcy5kaXNhYmxlZCkpO1xuICAgIHRoaXMuX3RvZ2dsZU5hdGl2ZURyYWdJbnRlcmFjdGlvbnMoKTtcblxuICAgIC8vIERlbGV0ZSBhbnkgbGluZ2VyaW5nIGRpc2FibGVkIGhhbmRsZXMgdGhhdCBtYXkgaGF2ZSBiZWVuIGRlc3Ryb3llZC4gTm90ZSB0aGF0IHdlIHJlLWNyZWF0ZVxuICAgIC8vIHRoZSBzZXQsIHJhdGhlciB0aGFuIGl0ZXJhdGUgb3ZlciBpdCBhbmQgZmlsdGVyIG91dCB0aGUgZGVzdHJveWVkIGhhbmRsZXMsIGJlY2F1c2Ugd2hpbGVcbiAgICAvLyB0aGUgRVMgc3BlYyBhbGxvd3MgZm9yIHNldHMgdG8gYmUgbW9kaWZpZWQgd2hpbGUgdGhleSdyZSBiZWluZyBpdGVyYXRlZCBvdmVyLCBzb21lIHBvbHlmaWxsc1xuICAgIC8vIHVzZSBhbiBhcnJheSBpbnRlcm5hbGx5IHdoaWNoIG1heSB0aHJvdyBhbiBlcnJvci5cbiAgICBjb25zdCBkaXNhYmxlZEhhbmRsZXMgPSBuZXcgU2V0PEhUTUxFbGVtZW50PigpO1xuICAgIHRoaXMuX2Rpc2FibGVkSGFuZGxlcy5mb3JFYWNoKGhhbmRsZSA9PiB7XG4gICAgICBpZiAodGhpcy5faGFuZGxlcy5pbmRleE9mKGhhbmRsZSkgPiAtMSkge1xuICAgICAgICBkaXNhYmxlZEhhbmRsZXMuYWRkKGhhbmRsZSk7XG4gICAgICB9XG4gICAgfSk7XG4gICAgdGhpcy5fZGlzYWJsZWRIYW5kbGVzID0gZGlzYWJsZWRIYW5kbGVzO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyB0aGUgdGVtcGxhdGUgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIGRyYWcgcHJldmlldy5cbiAgICogQHBhcmFtIHRlbXBsYXRlIFRlbXBsYXRlIHRoYXQgZnJvbSB3aGljaCB0byBzdGFtcCBvdXQgdGhlIHByZXZpZXcuXG4gICAqL1xuICB3aXRoUHJldmlld1RlbXBsYXRlKHRlbXBsYXRlOiBEcmFnUHJldmlld1RlbXBsYXRlIHwgbnVsbCk6IHRoaXMge1xuICAgIHRoaXMuX3ByZXZpZXdUZW1wbGF0ZSA9IHRlbXBsYXRlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFJlZ2lzdGVycyB0aGUgdGVtcGxhdGUgdGhhdCBzaG91bGQgYmUgdXNlZCBmb3IgdGhlIGRyYWcgcGxhY2Vob2xkZXIuXG4gICAqIEBwYXJhbSB0ZW1wbGF0ZSBUZW1wbGF0ZSB0aGF0IGZyb20gd2hpY2ggdG8gc3RhbXAgb3V0IHRoZSBwbGFjZWhvbGRlci5cbiAgICovXG4gIHdpdGhQbGFjZWhvbGRlclRlbXBsYXRlKHRlbXBsYXRlOiBEcmFnSGVscGVyVGVtcGxhdGUgfCBudWxsKTogdGhpcyB7XG4gICAgdGhpcy5fcGxhY2Vob2xkZXJUZW1wbGF0ZSA9IHRlbXBsYXRlO1xuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYW4gYWx0ZXJuYXRlIGRyYWcgcm9vdCBlbGVtZW50LiBUaGUgcm9vdCBlbGVtZW50IGlzIHRoZSBlbGVtZW50IHRoYXQgd2lsbCBiZSBtb3ZlZCBhc1xuICAgKiB0aGUgdXNlciBpcyBkcmFnZ2luZy4gUGFzc2luZyBhbiBhbHRlcm5hdGUgcm9vdCBlbGVtZW50IGlzIHVzZWZ1bCB3aGVuIHRyeWluZyB0byBlbmFibGVcbiAgICogZHJhZ2dpbmcgb24gYW4gZWxlbWVudCB0aGF0IHlvdSBtaWdodCBub3QgaGF2ZSBhY2Nlc3MgdG8uXG4gICAqL1xuICB3aXRoUm9vdEVsZW1lbnQocm9vdEVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgSFRNTEVsZW1lbnQpOiB0aGlzIHtcbiAgICBjb25zdCBlbGVtZW50ID0gY29lcmNlRWxlbWVudChyb290RWxlbWVudCk7XG5cbiAgICBpZiAoZWxlbWVudCAhPT0gdGhpcy5fcm9vdEVsZW1lbnQpIHtcbiAgICAgIGlmICh0aGlzLl9yb290RWxlbWVudCkge1xuICAgICAgICB0aGlzLl9yZW1vdmVSb290RWxlbWVudExpc3RlbmVycyh0aGlzLl9yb290RWxlbWVudCk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuX25nWm9uZS5ydW5PdXRzaWRlQW5ndWxhcigoKSA9PiB7XG4gICAgICAgIGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vkb3duJywgdGhpcy5fcG9pbnRlckRvd24sIGFjdGl2ZUV2ZW50TGlzdGVuZXJPcHRpb25zKTtcbiAgICAgICAgZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKCd0b3VjaHN0YXJ0JywgdGhpcy5fcG9pbnRlckRvd24sIHBhc3NpdmVFdmVudExpc3RlbmVyT3B0aW9ucyk7XG4gICAgICB9KTtcbiAgICAgIHRoaXMuX2luaXRpYWxUcmFuc2Zvcm0gPSB1bmRlZmluZWQ7XG4gICAgICB0aGlzLl9yb290RWxlbWVudCA9IGVsZW1lbnQ7XG4gICAgfVxuXG4gICAgaWYgKHR5cGVvZiBTVkdFbGVtZW50ICE9PSAndW5kZWZpbmVkJyAmJiB0aGlzLl9yb290RWxlbWVudCBpbnN0YW5jZW9mIFNWR0VsZW1lbnQpIHtcbiAgICAgIHRoaXMuX293bmVyU1ZHRWxlbWVudCA9IHRoaXMuX3Jvb3RFbGVtZW50Lm93bmVyU1ZHRWxlbWVudDtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfVxuXG4gIC8qKlxuICAgKiBFbGVtZW50IHRvIHdoaWNoIHRoZSBkcmFnZ2FibGUncyBwb3NpdGlvbiB3aWxsIGJlIGNvbnN0cmFpbmVkLlxuICAgKi9cbiAgd2l0aEJvdW5kYXJ5RWxlbWVudChib3VuZGFyeUVsZW1lbnQ6IEVsZW1lbnRSZWY8SFRNTEVsZW1lbnQ+IHwgSFRNTEVsZW1lbnQgfCBudWxsKTogdGhpcyB7XG4gICAgdGhpcy5fYm91bmRhcnlFbGVtZW50ID0gYm91bmRhcnlFbGVtZW50ID8gY29lcmNlRWxlbWVudChib3VuZGFyeUVsZW1lbnQpIDogbnVsbDtcbiAgICB0aGlzLl9yZXNpemVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICBpZiAoYm91bmRhcnlFbGVtZW50KSB7XG4gICAgICB0aGlzLl9yZXNpemVTdWJzY3JpcHRpb24gPSB0aGlzLl92aWV3cG9ydFJ1bGVyXG4gICAgICAgIC5jaGFuZ2UoMTApXG4gICAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5fY29udGFpbkluc2lkZUJvdW5kYXJ5T25SZXNpemUoKSk7XG4gICAgfVxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqIFNldHMgdGhlIHBhcmVudCByZWYgdGhhdCB0aGUgcmVmIGlzIG5lc3RlZCBpbi4gICovXG4gIHdpdGhQYXJlbnQocGFyZW50OiBEcmFnUmVmPHVua25vd24+IHwgbnVsbCk6IHRoaXMge1xuICAgIHRoaXMuX3BhcmVudERyYWdSZWYgPSBwYXJlbnQ7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogUmVtb3ZlcyB0aGUgZHJhZ2dpbmcgZnVuY3Rpb25hbGl0eSBmcm9tIHRoZSBET00gZWxlbWVudC4gKi9cbiAgZGlzcG9zZSgpIHtcbiAgICB0aGlzLl9yZW1vdmVSb290RWxlbWVudExpc3RlbmVycyh0aGlzLl9yb290RWxlbWVudCk7XG5cbiAgICAvLyBEbyB0aGlzIGNoZWNrIGJlZm9yZSByZW1vdmluZyBmcm9tIHRoZSByZWdpc3RyeSBzaW5jZSBpdCdsbFxuICAgIC8vIHN0b3AgYmVpbmcgY29uc2lkZXJlZCBhcyBkcmFnZ2VkIG9uY2UgaXQgaXMgcmVtb3ZlZC5cbiAgICBpZiAodGhpcy5pc0RyYWdnaW5nKCkpIHtcbiAgICAgIC8vIFNpbmNlIHdlIG1vdmUgb3V0IHRoZSBlbGVtZW50IHRvIHRoZSBlbmQgb2YgdGhlIGJvZHkgd2hpbGUgaXQncyBiZWluZ1xuICAgICAgLy8gZHJhZ2dlZCwgd2UgaGF2ZSB0byBtYWtlIHN1cmUgdGhhdCBpdCdzIHJlbW92ZWQgaWYgaXQgZ2V0cyBkZXN0cm95ZWQuXG4gICAgICB0aGlzLl9yb290RWxlbWVudD8ucmVtb3ZlKCk7XG4gICAgfVxuXG4gICAgdGhpcy5fYW5jaG9yPy5yZW1vdmUoKTtcbiAgICB0aGlzLl9kZXN0cm95UHJldmlldygpO1xuICAgIHRoaXMuX2Rlc3Ryb3lQbGFjZWhvbGRlcigpO1xuICAgIHRoaXMuX2RyYWdEcm9wUmVnaXN0cnkucmVtb3ZlRHJhZ0l0ZW0odGhpcyk7XG4gICAgdGhpcy5fcmVtb3ZlU3Vic2NyaXB0aW9ucygpO1xuICAgIHRoaXMuYmVmb3JlU3RhcnRlZC5jb21wbGV0ZSgpO1xuICAgIHRoaXMuc3RhcnRlZC5jb21wbGV0ZSgpO1xuICAgIHRoaXMucmVsZWFzZWQuY29tcGxldGUoKTtcbiAgICB0aGlzLmVuZGVkLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5lbnRlcmVkLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5leGl0ZWQuY29tcGxldGUoKTtcbiAgICB0aGlzLmRyb3BwZWQuY29tcGxldGUoKTtcbiAgICB0aGlzLl9tb3ZlRXZlbnRzLmNvbXBsZXRlKCk7XG4gICAgdGhpcy5faGFuZGxlcyA9IFtdO1xuICAgIHRoaXMuX2Rpc2FibGVkSGFuZGxlcy5jbGVhcigpO1xuICAgIHRoaXMuX2Ryb3BDb250YWluZXIgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcmVzaXplU3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5fcGFyZW50UG9zaXRpb25zLmNsZWFyKCk7XG4gICAgdGhpcy5fYm91bmRhcnlFbGVtZW50ID1cbiAgICAgIHRoaXMuX3Jvb3RFbGVtZW50ID1cbiAgICAgIHRoaXMuX293bmVyU1ZHRWxlbWVudCA9XG4gICAgICB0aGlzLl9wbGFjZWhvbGRlclRlbXBsYXRlID1cbiAgICAgIHRoaXMuX3ByZXZpZXdUZW1wbGF0ZSA9XG4gICAgICB0aGlzLl9hbmNob3IgPVxuICAgICAgdGhpcy5fcGFyZW50RHJhZ1JlZiA9XG4gICAgICAgIG51bGwhO1xuICB9XG5cbiAgLyoqIENoZWNrcyB3aGV0aGVyIHRoZSBlbGVtZW50IGlzIGN1cnJlbnRseSBiZWluZyBkcmFnZ2VkLiAqL1xuICBpc0RyYWdnaW5nKCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLl9oYXNTdGFydGVkRHJhZ2dpbmcgJiYgdGhpcy5fZHJhZ0Ryb3BSZWdpc3RyeS5pc0RyYWdnaW5nKHRoaXMpO1xuICB9XG5cbiAgLyoqIFJlc2V0cyBhIHN0YW5kYWxvbmUgZHJhZyBpdGVtIHRvIGl0cyBpbml0aWFsIHBvc2l0aW9uLiAqL1xuICByZXNldCgpOiB2b2lkIHtcbiAgICB0aGlzLl9yb290RWxlbWVudC5zdHlsZS50cmFuc2Zvcm0gPSB0aGlzLl9pbml0aWFsVHJhbnNmb3JtIHx8ICcnO1xuICAgIHRoaXMuX2FjdGl2ZVRyYW5zZm9ybSA9IHt4OiAwLCB5OiAwfTtcbiAgICB0aGlzLl9wYXNzaXZlVHJhbnNmb3JtID0ge3g6IDAsIHk6IDB9O1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgYSBoYW5kbGUgYXMgZGlzYWJsZWQuIFdoaWxlIGEgaGFuZGxlIGlzIGRpc2FibGVkLCBpdCdsbCBjYXB0dXJlIGFuZCBpbnRlcnJ1cHQgZHJhZ2dpbmcuXG4gICAqIEBwYXJhbSBoYW5kbGUgSGFuZGxlIGVsZW1lbnQgdGhhdCBzaG91bGQgYmUgZGlzYWJsZWQuXG4gICAqL1xuICBkaXNhYmxlSGFuZGxlKGhhbmRsZTogSFRNTEVsZW1lbnQpIHtcbiAgICBpZiAoIXRoaXMuX2Rpc2FibGVkSGFuZGxlcy5oYXMoaGFuZGxlKSAmJiB0aGlzLl9oYW5kbGVzLmluZGV4T2YoaGFuZGxlKSA+IC0xKSB7XG4gICAgICB0aGlzLl9kaXNhYmxlZEhhbmRsZXMuYWRkKGhhbmRsZSk7XG4gICAgICB0b2dnbGVOYXRpdmVEcmFnSW50ZXJhY3Rpb25zKGhhbmRsZSwgdHJ1ZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIEVuYWJsZXMgYSBoYW5kbGUsIGlmIGl0IGhhcyBiZWVuIGRpc2FibGVkLlxuICAgKiBAcGFyYW0gaGFuZGxlIEhhbmRsZSBlbGVtZW50IHRvIGJlIGVuYWJsZWQuXG4gICAqL1xuICBlbmFibGVIYW5kbGUoaGFuZGxlOiBIVE1MRWxlbWVudCkge1xuICAgIGlmICh0aGlzLl9kaXNhYmxlZEhhbmRsZXMuaGFzKGhhbmRsZSkpIHtcbiAgICAgIHRoaXMuX2Rpc2FibGVkSGFuZGxlcy5kZWxldGUoaGFuZGxlKTtcbiAgICAgIHRvZ2dsZU5hdGl2ZURyYWdJbnRlcmFjdGlvbnMoaGFuZGxlLCB0aGlzLmRpc2FibGVkKTtcbiAgICB9XG4gIH1cblxuICAvKiogU2V0cyB0aGUgbGF5b3V0IGRpcmVjdGlvbiBvZiB0aGUgZHJhZ2dhYmxlIGl0ZW0uICovXG4gIHdpdGhEaXJlY3Rpb24oZGlyZWN0aW9uOiBEaXJlY3Rpb24pOiB0aGlzIHtcbiAgICB0aGlzLl9kaXJlY3Rpb24gPSBkaXJlY3Rpb247XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogU2V0cyB0aGUgY29udGFpbmVyIHRoYXQgdGhlIGl0ZW0gaXMgcGFydCBvZi4gKi9cbiAgX3dpdGhEcm9wQ29udGFpbmVyKGNvbnRhaW5lcjogRHJvcExpc3RSZWYpIHtcbiAgICB0aGlzLl9kcm9wQ29udGFpbmVyID0gY29udGFpbmVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEdldHMgdGhlIGN1cnJlbnQgcG9zaXRpb24gaW4gcGl4ZWxzIHRoZSBkcmFnZ2FibGUgb3V0c2lkZSBvZiBhIGRyb3AgY29udGFpbmVyLlxuICAgKi9cbiAgZ2V0RnJlZURyYWdQb3NpdGlvbigpOiBSZWFkb25seTxQb2ludD4ge1xuICAgIGNvbnN0IHBvc2l0aW9uID0gdGhpcy5pc0RyYWdnaW5nKCkgPyB0aGlzLl9hY3RpdmVUcmFuc2Zvcm0gOiB0aGlzLl9wYXNzaXZlVHJhbnNmb3JtO1xuICAgIHJldHVybiB7eDogcG9zaXRpb24ueCwgeTogcG9zaXRpb24ueX07XG4gIH1cblxuICAvKipcbiAgICogU2V0cyB0aGUgY3VycmVudCBwb3NpdGlvbiBpbiBwaXhlbHMgdGhlIGRyYWdnYWJsZSBvdXRzaWRlIG9mIGEgZHJvcCBjb250YWluZXIuXG4gICAqIEBwYXJhbSB2YWx1ZSBOZXcgcG9zaXRpb24gdG8gYmUgc2V0LlxuICAgKi9cbiAgc2V0RnJlZURyYWdQb3NpdGlvbih2YWx1ZTogUG9pbnQpOiB0aGlzIHtcbiAgICB0aGlzLl9hY3RpdmVUcmFuc2Zvcm0gPSB7eDogMCwgeTogMH07XG4gICAgdGhpcy5fcGFzc2l2ZVRyYW5zZm9ybS54ID0gdmFsdWUueDtcbiAgICB0aGlzLl9wYXNzaXZlVHJhbnNmb3JtLnkgPSB2YWx1ZS55O1xuXG4gICAgaWYgKCF0aGlzLl9kcm9wQ29udGFpbmVyKSB7XG4gICAgICB0aGlzLl9hcHBseVJvb3RFbGVtZW50VHJhbnNmb3JtKHZhbHVlLngsIHZhbHVlLnkpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzO1xuICB9XG5cbiAgLyoqXG4gICAqIFNldHMgdGhlIGNvbnRhaW5lciBpbnRvIHdoaWNoIHRvIGluc2VydCB0aGUgcHJldmlldyBlbGVtZW50LlxuICAgKiBAcGFyYW0gdmFsdWUgQ29udGFpbmVyIGludG8gd2hpY2ggdG8gaW5zZXJ0IHRoZSBwcmV2aWV3LlxuICAgKi9cbiAgd2l0aFByZXZpZXdDb250YWluZXIodmFsdWU6IFByZXZpZXdDb250YWluZXIpOiB0aGlzIHtcbiAgICB0aGlzLl9wcmV2aWV3Q29udGFpbmVyID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICAvKiogVXBkYXRlcyB0aGUgaXRlbSdzIHNvcnQgb3JkZXIgYmFzZWQgb24gdGhlIGxhc3Qta25vd24gcG9pbnRlciBwb3NpdGlvbi4gKi9cbiAgX3NvcnRGcm9tTGFzdFBvaW50ZXJQb3NpdGlvbigpIHtcbiAgICBjb25zdCBwb3NpdGlvbiA9IHRoaXMuX2xhc3RLbm93blBvaW50ZXJQb3NpdGlvbjtcblxuICAgIGlmIChwb3NpdGlvbiAmJiB0aGlzLl9kcm9wQ29udGFpbmVyKSB7XG4gICAgICB0aGlzLl91cGRhdGVBY3RpdmVEcm9wQ29udGFpbmVyKHRoaXMuX2dldENvbnN0cmFpbmVkUG9pbnRlclBvc2l0aW9uKHBvc2l0aW9uKSwgcG9zaXRpb24pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBVbnN1YnNjcmliZXMgZnJvbSB0aGUgZ2xvYmFsIHN1YnNjcmlwdGlvbnMuICovXG4gIHByaXZhdGUgX3JlbW92ZVN1YnNjcmlwdGlvbnMoKSB7XG4gICAgdGhpcy5fcG9pbnRlck1vdmVTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLl9wb2ludGVyVXBTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLl9zY3JvbGxTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgfVxuXG4gIC8qKiBEZXN0cm95cyB0aGUgcHJldmlldyBlbGVtZW50IGFuZCBpdHMgVmlld1JlZi4gKi9cbiAgcHJpdmF0ZSBfZGVzdHJveVByZXZpZXcoKSB7XG4gICAgdGhpcy5fcHJldmlldz8ucmVtb3ZlKCk7XG4gICAgdGhpcy5fcHJldmlld1JlZj8uZGVzdHJveSgpO1xuICAgIHRoaXMuX3ByZXZpZXcgPSB0aGlzLl9wcmV2aWV3UmVmID0gbnVsbCE7XG4gIH1cblxuICAvKiogRGVzdHJveXMgdGhlIHBsYWNlaG9sZGVyIGVsZW1lbnQgYW5kIGl0cyBWaWV3UmVmLiAqL1xuICBwcml2YXRlIF9kZXN0cm95UGxhY2Vob2xkZXIoKSB7XG4gICAgdGhpcy5fcGxhY2Vob2xkZXI/LnJlbW92ZSgpO1xuICAgIHRoaXMuX3BsYWNlaG9sZGVyUmVmPy5kZXN0cm95KCk7XG4gICAgdGhpcy5fcGxhY2Vob2xkZXIgPSB0aGlzLl9wbGFjZWhvbGRlclJlZiA9IG51bGwhO1xuICB9XG5cbiAgLyoqIEhhbmRsZXIgZm9yIHRoZSBgbW91c2Vkb3duYC9gdG91Y2hzdGFydGAgZXZlbnRzLiAqL1xuICBwcml2YXRlIF9wb2ludGVyRG93biA9IChldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpID0+IHtcbiAgICB0aGlzLmJlZm9yZVN0YXJ0ZWQubmV4dCgpO1xuXG4gICAgLy8gRGVsZWdhdGUgdGhlIGV2ZW50IGJhc2VkIG9uIHdoZXRoZXIgaXQgc3RhcnRlZCBmcm9tIGEgaGFuZGxlIG9yIHRoZSBlbGVtZW50IGl0c2VsZi5cbiAgICBpZiAodGhpcy5faGFuZGxlcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHRhcmdldEhhbmRsZSA9IHRoaXMuX2hhbmRsZXMuZmluZChoYW5kbGUgPT4ge1xuICAgICAgICBjb25zdCB0YXJnZXQgPSBfZ2V0RXZlbnRUYXJnZXQoZXZlbnQpO1xuICAgICAgICByZXR1cm4gISF0YXJnZXQgJiYgKHRhcmdldCA9PT0gaGFuZGxlIHx8IGhhbmRsZS5jb250YWlucyh0YXJnZXQgYXMgSFRNTEVsZW1lbnQpKTtcbiAgICAgIH0pO1xuXG4gICAgICBpZiAodGFyZ2V0SGFuZGxlICYmICF0aGlzLl9kaXNhYmxlZEhhbmRsZXMuaGFzKHRhcmdldEhhbmRsZSkgJiYgIXRoaXMuZGlzYWJsZWQpIHtcbiAgICAgICAgdGhpcy5faW5pdGlhbGl6ZURyYWdTZXF1ZW5jZSh0YXJnZXRIYW5kbGUsIGV2ZW50KTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCF0aGlzLmRpc2FibGVkKSB7XG4gICAgICB0aGlzLl9pbml0aWFsaXplRHJhZ1NlcXVlbmNlKHRoaXMuX3Jvb3RFbGVtZW50LCBldmVudCk7XG4gICAgfVxuICB9O1xuXG4gIC8qKiBIYW5kbGVyIHRoYXQgaXMgaW52b2tlZCB3aGVuIHRoZSB1c2VyIG1vdmVzIHRoZWlyIHBvaW50ZXIgYWZ0ZXIgdGhleSd2ZSBpbml0aWF0ZWQgYSBkcmFnLiAqL1xuICBwcml2YXRlIF9wb2ludGVyTW92ZSA9IChldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpID0+IHtcbiAgICBjb25zdCBwb2ludGVyUG9zaXRpb24gPSB0aGlzLl9nZXRQb2ludGVyUG9zaXRpb25PblBhZ2UoZXZlbnQpO1xuXG4gICAgaWYgKCF0aGlzLl9oYXNTdGFydGVkRHJhZ2dpbmcpIHtcbiAgICAgIGNvbnN0IGRpc3RhbmNlWCA9IE1hdGguYWJzKHBvaW50ZXJQb3NpdGlvbi54IC0gdGhpcy5fcGlja3VwUG9zaXRpb25PblBhZ2UueCk7XG4gICAgICBjb25zdCBkaXN0YW5jZVkgPSBNYXRoLmFicyhwb2ludGVyUG9zaXRpb24ueSAtIHRoaXMuX3BpY2t1cFBvc2l0aW9uT25QYWdlLnkpO1xuICAgICAgY29uc3QgaXNPdmVyVGhyZXNob2xkID0gZGlzdGFuY2VYICsgZGlzdGFuY2VZID49IHRoaXMuX2NvbmZpZy5kcmFnU3RhcnRUaHJlc2hvbGQ7XG5cbiAgICAgIC8vIE9ubHkgc3RhcnQgZHJhZ2dpbmcgYWZ0ZXIgdGhlIHVzZXIgaGFzIG1vdmVkIG1vcmUgdGhhbiB0aGUgbWluaW11bSBkaXN0YW5jZSBpbiBlaXRoZXJcbiAgICAgIC8vIGRpcmVjdGlvbi4gTm90ZSB0aGF0IHRoaXMgaXMgcHJlZmVycmFibGUgb3ZlciBkb2luZyBzb21ldGhpbmcgbGlrZSBgc2tpcChtaW5pbXVtRGlzdGFuY2UpYFxuICAgICAgLy8gaW4gdGhlIGBwb2ludGVyTW92ZWAgc3Vic2NyaXB0aW9uLCBiZWNhdXNlIHdlJ3JlIG5vdCBndWFyYW50ZWVkIHRvIGhhdmUgb25lIG1vdmUgZXZlbnRcbiAgICAgIC8vIHBlciBwaXhlbCBvZiBtb3ZlbWVudCAoZS5nLiBpZiB0aGUgdXNlciBtb3ZlcyB0aGVpciBwb2ludGVyIHF1aWNrbHkpLlxuICAgICAgaWYgKGlzT3ZlclRocmVzaG9sZCkge1xuICAgICAgICBjb25zdCBpc0RlbGF5RWxhcHNlZCA9IERhdGUubm93KCkgPj0gdGhpcy5fZHJhZ1N0YXJ0VGltZSArIHRoaXMuX2dldERyYWdTdGFydERlbGF5KGV2ZW50KTtcbiAgICAgICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5fZHJvcENvbnRhaW5lcjtcblxuICAgICAgICBpZiAoIWlzRGVsYXlFbGFwc2VkKSB7XG4gICAgICAgICAgdGhpcy5fZW5kRHJhZ1NlcXVlbmNlKGV2ZW50KTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cblxuICAgICAgICAvLyBQcmV2ZW50IG90aGVyIGRyYWcgc2VxdWVuY2VzIGZyb20gc3RhcnRpbmcgd2hpbGUgc29tZXRoaW5nIGluIHRoZSBjb250YWluZXIgaXMgc3RpbGxcbiAgICAgICAgLy8gYmVpbmcgZHJhZ2dlZC4gVGhpcyBjYW4gaGFwcGVuIHdoaWxlIHdlJ3JlIHdhaXRpbmcgZm9yIHRoZSBkcm9wIGFuaW1hdGlvbiB0byBmaW5pc2hcbiAgICAgICAgLy8gYW5kIGNhbiBjYXVzZSBlcnJvcnMsIGJlY2F1c2Ugc29tZSBlbGVtZW50cyBtaWdodCBzdGlsbCBiZSBtb3ZpbmcgYXJvdW5kLlxuICAgICAgICBpZiAoIWNvbnRhaW5lciB8fCAoIWNvbnRhaW5lci5pc0RyYWdnaW5nKCkgJiYgIWNvbnRhaW5lci5pc1JlY2VpdmluZygpKSkge1xuICAgICAgICAgIC8vIFByZXZlbnQgdGhlIGRlZmF1bHQgYWN0aW9uIGFzIHNvb24gYXMgdGhlIGRyYWdnaW5nIHNlcXVlbmNlIGlzIGNvbnNpZGVyZWQgYXNcbiAgICAgICAgICAvLyBcInN0YXJ0ZWRcIiBzaW5jZSB3YWl0aW5nIGZvciB0aGUgbmV4dCBldmVudCBjYW4gYWxsb3cgdGhlIGRldmljZSB0byBiZWdpbiBzY3JvbGxpbmcuXG4gICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB0aGlzLl9oYXNTdGFydGVkRHJhZ2dpbmcgPSB0cnVlO1xuICAgICAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4gdGhpcy5fc3RhcnREcmFnU2VxdWVuY2UoZXZlbnQpKTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgLy8gV2Ugb25seSBuZWVkIHRoZSBwcmV2aWV3IGRpbWVuc2lvbnMgaWYgd2UgaGF2ZSBhIGJvdW5kYXJ5IGVsZW1lbnQuXG4gICAgaWYgKHRoaXMuX2JvdW5kYXJ5RWxlbWVudCkge1xuICAgICAgLy8gQ2FjaGUgdGhlIHByZXZpZXcgZWxlbWVudCByZWN0IGlmIHdlIGhhdmVuJ3QgY2FjaGVkIGl0IGFscmVhZHkgb3IgaWZcbiAgICAgIC8vIHdlIGNhY2hlZCBpdCB0b28gZWFybHkgYmVmb3JlIHRoZSBlbGVtZW50IGRpbWVuc2lvbnMgd2VyZSBjb21wdXRlZC5cbiAgICAgIGlmICghdGhpcy5fcHJldmlld1JlY3QgfHwgKCF0aGlzLl9wcmV2aWV3UmVjdC53aWR0aCAmJiAhdGhpcy5fcHJldmlld1JlY3QuaGVpZ2h0KSkge1xuICAgICAgICB0aGlzLl9wcmV2aWV3UmVjdCA9ICh0aGlzLl9wcmV2aWV3IHx8IHRoaXMuX3Jvb3RFbGVtZW50KS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBXZSBwcmV2ZW50IHRoZSBkZWZhdWx0IGFjdGlvbiBkb3duIGhlcmUgc28gdGhhdCB3ZSBrbm93IHRoYXQgZHJhZ2dpbmcgaGFzIHN0YXJ0ZWQuIFRoaXMgaXNcbiAgICAvLyBpbXBvcnRhbnQgZm9yIHRvdWNoIGRldmljZXMgd2hlcmUgZG9pbmcgdGhpcyB0b28gZWFybHkgY2FuIHVubmVjZXNzYXJpbHkgYmxvY2sgc2Nyb2xsaW5nLFxuICAgIC8vIGlmIHRoZXJlJ3MgYSBkcmFnZ2luZyBkZWxheS5cbiAgICBldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuXG4gICAgY29uc3QgY29uc3RyYWluZWRQb2ludGVyUG9zaXRpb24gPSB0aGlzLl9nZXRDb25zdHJhaW5lZFBvaW50ZXJQb3NpdGlvbihwb2ludGVyUG9zaXRpb24pO1xuICAgIHRoaXMuX2hhc01vdmVkID0gdHJ1ZTtcbiAgICB0aGlzLl9sYXN0S25vd25Qb2ludGVyUG9zaXRpb24gPSBwb2ludGVyUG9zaXRpb247XG4gICAgdGhpcy5fdXBkYXRlUG9pbnRlckRpcmVjdGlvbkRlbHRhKGNvbnN0cmFpbmVkUG9pbnRlclBvc2l0aW9uKTtcblxuICAgIGlmICh0aGlzLl9kcm9wQ29udGFpbmVyKSB7XG4gICAgICB0aGlzLl91cGRhdGVBY3RpdmVEcm9wQ29udGFpbmVyKGNvbnN0cmFpbmVkUG9pbnRlclBvc2l0aW9uLCBwb2ludGVyUG9zaXRpb24pO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zdCBhY3RpdmVUcmFuc2Zvcm0gPSB0aGlzLl9hY3RpdmVUcmFuc2Zvcm07XG4gICAgICBhY3RpdmVUcmFuc2Zvcm0ueCA9XG4gICAgICAgIGNvbnN0cmFpbmVkUG9pbnRlclBvc2l0aW9uLnggLSB0aGlzLl9waWNrdXBQb3NpdGlvbk9uUGFnZS54ICsgdGhpcy5fcGFzc2l2ZVRyYW5zZm9ybS54O1xuICAgICAgYWN0aXZlVHJhbnNmb3JtLnkgPVxuICAgICAgICBjb25zdHJhaW5lZFBvaW50ZXJQb3NpdGlvbi55IC0gdGhpcy5fcGlja3VwUG9zaXRpb25PblBhZ2UueSArIHRoaXMuX3Bhc3NpdmVUcmFuc2Zvcm0ueTtcblxuICAgICAgdGhpcy5fYXBwbHlSb290RWxlbWVudFRyYW5zZm9ybShhY3RpdmVUcmFuc2Zvcm0ueCwgYWN0aXZlVHJhbnNmb3JtLnkpO1xuICAgIH1cblxuICAgIC8vIFNpbmNlIHRoaXMgZXZlbnQgZ2V0cyBmaXJlZCBmb3IgZXZlcnkgcGl4ZWwgd2hpbGUgZHJhZ2dpbmcsIHdlIG9ubHlcbiAgICAvLyB3YW50IHRvIGZpcmUgaXQgaWYgdGhlIGNvbnN1bWVyIG9wdGVkIGludG8gaXQuIEFsc28gd2UgaGF2ZSB0b1xuICAgIC8vIHJlLWVudGVyIHRoZSB6b25lIGJlY2F1c2Ugd2UgcnVuIGFsbCBvZiB0aGUgZXZlbnRzIG9uIHRoZSBvdXRzaWRlLlxuICAgIGlmICh0aGlzLl9tb3ZlRXZlbnRzLm9ic2VydmVycy5sZW5ndGgpIHtcbiAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICB0aGlzLl9tb3ZlRXZlbnRzLm5leHQoe1xuICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICBwb2ludGVyUG9zaXRpb246IGNvbnN0cmFpbmVkUG9pbnRlclBvc2l0aW9uLFxuICAgICAgICAgIGV2ZW50LFxuICAgICAgICAgIGRpc3RhbmNlOiB0aGlzLl9nZXREcmFnRGlzdGFuY2UoY29uc3RyYWluZWRQb2ludGVyUG9zaXRpb24pLFxuICAgICAgICAgIGRlbHRhOiB0aGlzLl9wb2ludGVyRGlyZWN0aW9uRGVsdGEsXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIC8qKiBIYW5kbGVyIHRoYXQgaXMgaW52b2tlZCB3aGVuIHRoZSB1c2VyIGxpZnRzIHRoZWlyIHBvaW50ZXIgdXAsIGFmdGVyIGluaXRpYXRpbmcgYSBkcmFnLiAqL1xuICBwcml2YXRlIF9wb2ludGVyVXAgPSAoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSA9PiB7XG4gICAgdGhpcy5fZW5kRHJhZ1NlcXVlbmNlKGV2ZW50KTtcbiAgfTtcblxuICAvKipcbiAgICogQ2xlYXJzIHN1YnNjcmlwdGlvbnMgYW5kIHN0b3BzIHRoZSBkcmFnZ2luZyBzZXF1ZW5jZS5cbiAgICogQHBhcmFtIGV2ZW50IEJyb3dzZXIgZXZlbnQgb2JqZWN0IHRoYXQgZW5kZWQgdGhlIHNlcXVlbmNlLlxuICAgKi9cbiAgcHJpdmF0ZSBfZW5kRHJhZ1NlcXVlbmNlKGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCkge1xuICAgIC8vIE5vdGUgdGhhdCBoZXJlIHdlIHVzZSBgaXNEcmFnZ2luZ2AgZnJvbSB0aGUgc2VydmljZSwgcmF0aGVyIHRoYW4gZnJvbSBgdGhpc2AuXG4gICAgLy8gVGhlIGRpZmZlcmVuY2UgaXMgdGhhdCB0aGUgb25lIGZyb20gdGhlIHNlcnZpY2UgcmVmbGVjdHMgd2hldGhlciBhIGRyYWdnaW5nIHNlcXVlbmNlXG4gICAgLy8gaGFzIGJlZW4gaW5pdGlhdGVkLCB3aGVyZWFzIHRoZSBvbmUgb24gYHRoaXNgIGluY2x1ZGVzIHdoZXRoZXIgdGhlIHVzZXIgaGFzIHBhc3NlZFxuICAgIC8vIHRoZSBtaW5pbXVtIGRyYWdnaW5nIHRocmVzaG9sZC5cbiAgICBpZiAoIXRoaXMuX2RyYWdEcm9wUmVnaXN0cnkuaXNEcmFnZ2luZyh0aGlzKSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMuX3JlbW92ZVN1YnNjcmlwdGlvbnMoKTtcbiAgICB0aGlzLl9kcmFnRHJvcFJlZ2lzdHJ5LnN0b3BEcmFnZ2luZyh0aGlzKTtcbiAgICB0aGlzLl90b2dnbGVOYXRpdmVEcmFnSW50ZXJhY3Rpb25zKCk7XG5cbiAgICBpZiAodGhpcy5faGFuZGxlcykge1xuICAgICAgKHRoaXMuX3Jvb3RFbGVtZW50LnN0eWxlIGFzIGFueSkud2Via2l0VGFwSGlnaGxpZ2h0Q29sb3IgPSB0aGlzLl9yb290RWxlbWVudFRhcEhpZ2hsaWdodDtcbiAgICB9XG5cbiAgICBpZiAoIXRoaXMuX2hhc1N0YXJ0ZWREcmFnZ2luZykge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHRoaXMucmVsZWFzZWQubmV4dCh7c291cmNlOiB0aGlzfSk7XG5cbiAgICBpZiAodGhpcy5fZHJvcENvbnRhaW5lcikge1xuICAgICAgLy8gU3RvcCBzY3JvbGxpbmcgaW1tZWRpYXRlbHksIGluc3RlYWQgb2Ygd2FpdGluZyBmb3IgdGhlIGFuaW1hdGlvbiB0byBmaW5pc2guXG4gICAgICB0aGlzLl9kcm9wQ29udGFpbmVyLl9zdG9wU2Nyb2xsaW5nKCk7XG4gICAgICB0aGlzLl9hbmltYXRlUHJldmlld1RvUGxhY2Vob2xkZXIoKS50aGVuKCgpID0+IHtcbiAgICAgICAgdGhpcy5fY2xlYW51cERyYWdBcnRpZmFjdHMoZXZlbnQpO1xuICAgICAgICB0aGlzLl9jbGVhbnVwQ2FjaGVkRGltZW5zaW9ucygpO1xuICAgICAgICB0aGlzLl9kcmFnRHJvcFJlZ2lzdHJ5LnN0b3BEcmFnZ2luZyh0aGlzKTtcbiAgICAgIH0pO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBDb252ZXJ0IHRoZSBhY3RpdmUgdHJhbnNmb3JtIGludG8gYSBwYXNzaXZlIG9uZS4gVGhpcyBtZWFucyB0aGF0IG5leHQgdGltZVxuICAgICAgLy8gdGhlIHVzZXIgc3RhcnRzIGRyYWdnaW5nIHRoZSBpdGVtLCBpdHMgcG9zaXRpb24gd2lsbCBiZSBjYWxjdWxhdGVkIHJlbGF0aXZlbHlcbiAgICAgIC8vIHRvIHRoZSBuZXcgcGFzc2l2ZSB0cmFuc2Zvcm0uXG4gICAgICB0aGlzLl9wYXNzaXZlVHJhbnNmb3JtLnggPSB0aGlzLl9hY3RpdmVUcmFuc2Zvcm0ueDtcbiAgICAgIGNvbnN0IHBvaW50ZXJQb3NpdGlvbiA9IHRoaXMuX2dldFBvaW50ZXJQb3NpdGlvbk9uUGFnZShldmVudCk7XG4gICAgICB0aGlzLl9wYXNzaXZlVHJhbnNmb3JtLnkgPSB0aGlzLl9hY3RpdmVUcmFuc2Zvcm0ueTtcbiAgICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgICB0aGlzLmVuZGVkLm5leHQoe1xuICAgICAgICAgIHNvdXJjZTogdGhpcyxcbiAgICAgICAgICBkaXN0YW5jZTogdGhpcy5fZ2V0RHJhZ0Rpc3RhbmNlKHBvaW50ZXJQb3NpdGlvbiksXG4gICAgICAgICAgZHJvcFBvaW50OiBwb2ludGVyUG9zaXRpb24sXG4gICAgICAgIH0pO1xuICAgICAgfSk7XG4gICAgICB0aGlzLl9jbGVhbnVwQ2FjaGVkRGltZW5zaW9ucygpO1xuICAgICAgdGhpcy5fZHJhZ0Ryb3BSZWdpc3RyeS5zdG9wRHJhZ2dpbmcodGhpcyk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFN0YXJ0cyB0aGUgZHJhZ2dpbmcgc2VxdWVuY2UuICovXG4gIHByaXZhdGUgX3N0YXJ0RHJhZ1NlcXVlbmNlKGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCkge1xuICAgIGlmIChpc1RvdWNoRXZlbnQoZXZlbnQpKSB7XG4gICAgICB0aGlzLl9sYXN0VG91Y2hFdmVudFRpbWUgPSBEYXRlLm5vdygpO1xuICAgIH1cblxuICAgIHRoaXMuX3RvZ2dsZU5hdGl2ZURyYWdJbnRlcmFjdGlvbnMoKTtcblxuICAgIGNvbnN0IGRyb3BDb250YWluZXIgPSB0aGlzLl9kcm9wQ29udGFpbmVyO1xuXG4gICAgaWYgKGRyb3BDb250YWluZXIpIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9yb290RWxlbWVudDtcbiAgICAgIGNvbnN0IHBhcmVudCA9IGVsZW1lbnQucGFyZW50Tm9kZSBhcyBIVE1MRWxlbWVudDtcbiAgICAgIGNvbnN0IHBsYWNlaG9sZGVyID0gKHRoaXMuX3BsYWNlaG9sZGVyID0gdGhpcy5fY3JlYXRlUGxhY2Vob2xkZXJFbGVtZW50KCkpO1xuICAgICAgY29uc3QgYW5jaG9yID0gKHRoaXMuX2FuY2hvciA9IHRoaXMuX2FuY2hvciB8fCB0aGlzLl9kb2N1bWVudC5jcmVhdGVDb21tZW50KCcnKSk7XG5cbiAgICAgIC8vIE5lZWRzIHRvIGhhcHBlbiBiZWZvcmUgdGhlIHJvb3QgZWxlbWVudCBpcyBtb3ZlZC5cbiAgICAgIGNvbnN0IHNoYWRvd1Jvb3QgPSB0aGlzLl9nZXRTaGFkb3dSb290KCk7XG5cbiAgICAgIC8vIEluc2VydCBhbiBhbmNob3Igbm9kZSBzbyB0aGF0IHdlIGNhbiByZXN0b3JlIHRoZSBlbGVtZW50J3MgcG9zaXRpb24gaW4gdGhlIERPTS5cbiAgICAgIHBhcmVudC5pbnNlcnRCZWZvcmUoYW5jaG9yLCBlbGVtZW50KTtcblxuICAgICAgLy8gVGhlcmUncyBubyByaXNrIG9mIHRyYW5zZm9ybXMgc3RhY2tpbmcgd2hlbiBpbnNpZGUgYSBkcm9wIGNvbnRhaW5lciBzb1xuICAgICAgLy8gd2UgY2FuIGtlZXAgdGhlIGluaXRpYWwgdHJhbnNmb3JtIHVwIHRvIGRhdGUgYW55IHRpbWUgZHJhZ2dpbmcgc3RhcnRzLlxuICAgICAgdGhpcy5faW5pdGlhbFRyYW5zZm9ybSA9IGVsZW1lbnQuc3R5bGUudHJhbnNmb3JtIHx8ICcnO1xuXG4gICAgICAvLyBDcmVhdGUgdGhlIHByZXZpZXcgYWZ0ZXIgdGhlIGluaXRpYWwgdHJhbnNmb3JtIGhhc1xuICAgICAgLy8gYmVlbiBjYWNoZWQsIGJlY2F1c2UgaXQgY2FuIGJlIGFmZmVjdGVkIGJ5IHRoZSB0cmFuc2Zvcm0uXG4gICAgICB0aGlzLl9wcmV2aWV3ID0gdGhpcy5fY3JlYXRlUHJldmlld0VsZW1lbnQoKTtcblxuICAgICAgLy8gV2UgbW92ZSB0aGUgZWxlbWVudCBvdXQgYXQgdGhlIGVuZCBvZiB0aGUgYm9keSBhbmQgd2UgbWFrZSBpdCBoaWRkZW4sIGJlY2F1c2Uga2VlcGluZyBpdCBpblxuICAgICAgLy8gcGxhY2Ugd2lsbCB0aHJvdyBvZmYgdGhlIGNvbnN1bWVyJ3MgYDpsYXN0LWNoaWxkYCBzZWxlY3RvcnMuIFdlIGNhbid0IHJlbW92ZSB0aGUgZWxlbWVudFxuICAgICAgLy8gZnJvbSB0aGUgRE9NIGNvbXBsZXRlbHksIGJlY2F1c2UgaU9TIHdpbGwgc3RvcCBmaXJpbmcgYWxsIHN1YnNlcXVlbnQgZXZlbnRzIGluIHRoZSBjaGFpbi5cbiAgICAgIHRvZ2dsZVZpc2liaWxpdHkoZWxlbWVudCwgZmFsc2UsIGRyYWdJbXBvcnRhbnRQcm9wZXJ0aWVzKTtcbiAgICAgIHRoaXMuX2RvY3VtZW50LmJvZHkuYXBwZW5kQ2hpbGQocGFyZW50LnJlcGxhY2VDaGlsZChwbGFjZWhvbGRlciwgZWxlbWVudCkpO1xuICAgICAgdGhpcy5fZ2V0UHJldmlld0luc2VydGlvblBvaW50KHBhcmVudCwgc2hhZG93Um9vdCkuYXBwZW5kQ2hpbGQodGhpcy5fcHJldmlldyk7XG4gICAgICB0aGlzLnN0YXJ0ZWQubmV4dCh7c291cmNlOiB0aGlzfSk7IC8vIEVtaXQgYmVmb3JlIG5vdGlmeWluZyB0aGUgY29udGFpbmVyLlxuICAgICAgZHJvcENvbnRhaW5lci5zdGFydCgpO1xuICAgICAgdGhpcy5faW5pdGlhbENvbnRhaW5lciA9IGRyb3BDb250YWluZXI7XG4gICAgICB0aGlzLl9pbml0aWFsSW5kZXggPSBkcm9wQ29udGFpbmVyLmdldEl0ZW1JbmRleCh0aGlzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5zdGFydGVkLm5leHQoe3NvdXJjZTogdGhpc30pO1xuICAgICAgdGhpcy5faW5pdGlhbENvbnRhaW5lciA9IHRoaXMuX2luaXRpYWxJbmRleCA9IHVuZGVmaW5lZCE7XG4gICAgfVxuXG4gICAgLy8gSW1wb3J0YW50IHRvIHJ1biBhZnRlciB3ZSd2ZSBjYWxsZWQgYHN0YXJ0YCBvbiB0aGUgcGFyZW50IGNvbnRhaW5lclxuICAgIC8vIHNvIHRoYXQgaXQgaGFzIGhhZCB0aW1lIHRvIHJlc29sdmUgaXRzIHNjcm9sbGFibGUgcGFyZW50cy5cbiAgICB0aGlzLl9wYXJlbnRQb3NpdGlvbnMuY2FjaGUoZHJvcENvbnRhaW5lciA/IGRyb3BDb250YWluZXIuZ2V0U2Nyb2xsYWJsZVBhcmVudHMoKSA6IFtdKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBTZXRzIHVwIHRoZSBkaWZmZXJlbnQgdmFyaWFibGVzIGFuZCBzdWJzY3JpcHRpb25zXG4gICAqIHRoYXQgd2lsbCBiZSBuZWNlc3NhcnkgZm9yIHRoZSBkcmFnZ2luZyBzZXF1ZW5jZS5cbiAgICogQHBhcmFtIHJlZmVyZW5jZUVsZW1lbnQgRWxlbWVudCB0aGF0IHN0YXJ0ZWQgdGhlIGRyYWcgc2VxdWVuY2UuXG4gICAqIEBwYXJhbSBldmVudCBCcm93c2VyIGV2ZW50IG9iamVjdCB0aGF0IHN0YXJ0ZWQgdGhlIHNlcXVlbmNlLlxuICAgKi9cbiAgcHJpdmF0ZSBfaW5pdGlhbGl6ZURyYWdTZXF1ZW5jZShyZWZlcmVuY2VFbGVtZW50OiBIVE1MRWxlbWVudCwgZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSB7XG4gICAgLy8gU3RvcCBwcm9wYWdhdGlvbiBpZiB0aGUgaXRlbSBpcyBpbnNpZGUgYW5vdGhlclxuICAgIC8vIGRyYWdnYWJsZSBzbyB3ZSBkb24ndCBzdGFydCBtdWx0aXBsZSBkcmFnIHNlcXVlbmNlcy5cbiAgICBpZiAodGhpcy5fcGFyZW50RHJhZ1JlZikge1xuICAgICAgZXZlbnQuc3RvcFByb3BhZ2F0aW9uKCk7XG4gICAgfVxuXG4gICAgY29uc3QgaXNEcmFnZ2luZyA9IHRoaXMuaXNEcmFnZ2luZygpO1xuICAgIGNvbnN0IGlzVG91Y2hTZXF1ZW5jZSA9IGlzVG91Y2hFdmVudChldmVudCk7XG4gICAgY29uc3QgaXNBdXhpbGlhcnlNb3VzZUJ1dHRvbiA9ICFpc1RvdWNoU2VxdWVuY2UgJiYgKGV2ZW50IGFzIE1vdXNlRXZlbnQpLmJ1dHRvbiAhPT0gMDtcbiAgICBjb25zdCByb290RWxlbWVudCA9IHRoaXMuX3Jvb3RFbGVtZW50O1xuICAgIGNvbnN0IHRhcmdldCA9IF9nZXRFdmVudFRhcmdldChldmVudCk7XG4gICAgY29uc3QgaXNTeW50aGV0aWNFdmVudCA9XG4gICAgICAhaXNUb3VjaFNlcXVlbmNlICYmXG4gICAgICB0aGlzLl9sYXN0VG91Y2hFdmVudFRpbWUgJiZcbiAgICAgIHRoaXMuX2xhc3RUb3VjaEV2ZW50VGltZSArIE1PVVNFX0VWRU5UX0lHTk9SRV9USU1FID4gRGF0ZS5ub3coKTtcbiAgICBjb25zdCBpc0Zha2VFdmVudCA9IGlzVG91Y2hTZXF1ZW5jZVxuICAgICAgPyBpc0Zha2VUb3VjaHN0YXJ0RnJvbVNjcmVlblJlYWRlcihldmVudCBhcyBUb3VjaEV2ZW50KVxuICAgICAgOiBpc0Zha2VNb3VzZWRvd25Gcm9tU2NyZWVuUmVhZGVyKGV2ZW50IGFzIE1vdXNlRXZlbnQpO1xuXG4gICAgLy8gSWYgdGhlIGV2ZW50IHN0YXJ0ZWQgZnJvbSBhbiBlbGVtZW50IHdpdGggdGhlIG5hdGl2ZSBIVE1MIGRyYWcmZHJvcCwgaXQnbGwgaW50ZXJmZXJlXG4gICAgLy8gd2l0aCBvdXIgb3duIGRyYWdnaW5nIChlLmcuIGBpbWdgIHRhZ3MgZG8gaXQgYnkgZGVmYXVsdCkuIFByZXZlbnQgdGhlIGRlZmF1bHQgYWN0aW9uXG4gICAgLy8gdG8gc3RvcCBpdCBmcm9tIGhhcHBlbmluZy4gTm90ZSB0aGF0IHByZXZlbnRpbmcgb24gYGRyYWdzdGFydGAgYWxzbyBzZWVtcyB0byB3b3JrLCBidXRcbiAgICAvLyBpdCdzIGZsYWt5IGFuZCBpdCBmYWlscyBpZiB0aGUgdXNlciBkcmFncyBpdCBhd2F5IHF1aWNrbHkuIEFsc28gbm90ZSB0aGF0IHdlIG9ubHkgd2FudFxuICAgIC8vIHRvIGRvIHRoaXMgZm9yIGBtb3VzZWRvd25gIHNpbmNlIGRvaW5nIHRoZSBzYW1lIGZvciBgdG91Y2hzdGFydGAgd2lsbCBzdG9wIGFueSBgY2xpY2tgXG4gICAgLy8gZXZlbnRzIGZyb20gZmlyaW5nIG9uIHRvdWNoIGRldmljZXMuXG4gICAgaWYgKHRhcmdldCAmJiAodGFyZ2V0IGFzIEhUTUxFbGVtZW50KS5kcmFnZ2FibGUgJiYgZXZlbnQudHlwZSA9PT0gJ21vdXNlZG93bicpIHtcbiAgICAgIGV2ZW50LnByZXZlbnREZWZhdWx0KCk7XG4gICAgfVxuXG4gICAgLy8gQWJvcnQgaWYgdGhlIHVzZXIgaXMgYWxyZWFkeSBkcmFnZ2luZyBvciBpcyB1c2luZyBhIG1vdXNlIGJ1dHRvbiBvdGhlciB0aGFuIHRoZSBwcmltYXJ5IG9uZS5cbiAgICBpZiAoaXNEcmFnZ2luZyB8fCBpc0F1eGlsaWFyeU1vdXNlQnV0dG9uIHx8IGlzU3ludGhldGljRXZlbnQgfHwgaXNGYWtlRXZlbnQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICAvLyBJZiB3ZSd2ZSBnb3QgaGFuZGxlcywgd2UgbmVlZCB0byBkaXNhYmxlIHRoZSB0YXAgaGlnaGxpZ2h0IG9uIHRoZSBlbnRpcmUgcm9vdCBlbGVtZW50LFxuICAgIC8vIG90aGVyd2lzZSBpT1Mgd2lsbCBzdGlsbCBhZGQgaXQsIGV2ZW4gdGhvdWdoIGFsbCB0aGUgZHJhZyBpbnRlcmFjdGlvbnMgb24gdGhlIGhhbmRsZVxuICAgIC8vIGFyZSBkaXNhYmxlZC5cbiAgICBpZiAodGhpcy5faGFuZGxlcy5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHJvb3RTdHlsZXMgPSByb290RWxlbWVudC5zdHlsZSBhcyBhbnk7XG4gICAgICB0aGlzLl9yb290RWxlbWVudFRhcEhpZ2hsaWdodCA9IHJvb3RTdHlsZXMud2Via2l0VGFwSGlnaGxpZ2h0Q29sb3IgfHwgJyc7XG4gICAgICByb290U3R5bGVzLndlYmtpdFRhcEhpZ2hsaWdodENvbG9yID0gJ3RyYW5zcGFyZW50JztcbiAgICB9XG5cbiAgICB0aGlzLl9oYXNTdGFydGVkRHJhZ2dpbmcgPSB0aGlzLl9oYXNNb3ZlZCA9IGZhbHNlO1xuXG4gICAgLy8gQXZvaWQgbXVsdGlwbGUgc3Vic2NyaXB0aW9ucyBhbmQgbWVtb3J5IGxlYWtzIHdoZW4gbXVsdGkgdG91Y2hcbiAgICAvLyAoaXNEcmFnZ2luZyBjaGVjayBhYm92ZSBpc24ndCBlbm91Z2ggYmVjYXVzZSBvZiBwb3NzaWJsZSB0ZW1wb3JhbCBhbmQvb3IgZGltZW5zaW9uYWwgZGVsYXlzKVxuICAgIHRoaXMuX3JlbW92ZVN1YnNjcmlwdGlvbnMoKTtcbiAgICB0aGlzLl9wb2ludGVyTW92ZVN1YnNjcmlwdGlvbiA9IHRoaXMuX2RyYWdEcm9wUmVnaXN0cnkucG9pbnRlck1vdmUuc3Vic2NyaWJlKHRoaXMuX3BvaW50ZXJNb3ZlKTtcbiAgICB0aGlzLl9wb2ludGVyVXBTdWJzY3JpcHRpb24gPSB0aGlzLl9kcmFnRHJvcFJlZ2lzdHJ5LnBvaW50ZXJVcC5zdWJzY3JpYmUodGhpcy5fcG9pbnRlclVwKTtcbiAgICB0aGlzLl9zY3JvbGxTdWJzY3JpcHRpb24gPSB0aGlzLl9kcmFnRHJvcFJlZ2lzdHJ5XG4gICAgICAuc2Nyb2xsZWQodGhpcy5fZ2V0U2hhZG93Um9vdCgpKVxuICAgICAgLnN1YnNjcmliZShzY3JvbGxFdmVudCA9PiB0aGlzLl91cGRhdGVPblNjcm9sbChzY3JvbGxFdmVudCkpO1xuXG4gICAgaWYgKHRoaXMuX2JvdW5kYXJ5RWxlbWVudCkge1xuICAgICAgdGhpcy5fYm91bmRhcnlSZWN0ID0gZ2V0TXV0YWJsZUNsaWVudFJlY3QodGhpcy5fYm91bmRhcnlFbGVtZW50KTtcbiAgICB9XG5cbiAgICAvLyBJZiB3ZSBoYXZlIGEgY3VzdG9tIHByZXZpZXcgd2UgY2FuJ3Qga25vdyBhaGVhZCBvZiB0aW1lIGhvdyBsYXJnZSBpdCdsbCBiZSBzbyB3ZSBwb3NpdGlvblxuICAgIC8vIGl0IG5leHQgdG8gdGhlIGN1cnNvci4gVGhlIGV4Y2VwdGlvbiBpcyB3aGVuIHRoZSBjb25zdW1lciBoYXMgb3B0ZWQgaW50byBtYWtpbmcgdGhlIHByZXZpZXdcbiAgICAvLyB0aGUgc2FtZSBzaXplIGFzIHRoZSByb290IGVsZW1lbnQsIGluIHdoaWNoIGNhc2Ugd2UgZG8ga25vdyB0aGUgc2l6ZS5cbiAgICBjb25zdCBwcmV2aWV3VGVtcGxhdGUgPSB0aGlzLl9wcmV2aWV3VGVtcGxhdGU7XG4gICAgdGhpcy5fcGlja3VwUG9zaXRpb25JbkVsZW1lbnQgPVxuICAgICAgcHJldmlld1RlbXBsYXRlICYmIHByZXZpZXdUZW1wbGF0ZS50ZW1wbGF0ZSAmJiAhcHJldmlld1RlbXBsYXRlLm1hdGNoU2l6ZVxuICAgICAgICA/IHt4OiAwLCB5OiAwfVxuICAgICAgICA6IHRoaXMuX2dldFBvaW50ZXJQb3NpdGlvbkluRWxlbWVudChyZWZlcmVuY2VFbGVtZW50LCBldmVudCk7XG4gICAgY29uc3QgcG9pbnRlclBvc2l0aW9uID1cbiAgICAgICh0aGlzLl9waWNrdXBQb3NpdGlvbk9uUGFnZSA9XG4gICAgICB0aGlzLl9sYXN0S25vd25Qb2ludGVyUG9zaXRpb24gPVxuICAgICAgICB0aGlzLl9nZXRQb2ludGVyUG9zaXRpb25PblBhZ2UoZXZlbnQpKTtcbiAgICB0aGlzLl9wb2ludGVyRGlyZWN0aW9uRGVsdGEgPSB7eDogMCwgeTogMH07XG4gICAgdGhpcy5fcG9pbnRlclBvc2l0aW9uQXRMYXN0RGlyZWN0aW9uQ2hhbmdlID0ge3g6IHBvaW50ZXJQb3NpdGlvbi54LCB5OiBwb2ludGVyUG9zaXRpb24ueX07XG4gICAgdGhpcy5fZHJhZ1N0YXJ0VGltZSA9IERhdGUubm93KCk7XG4gICAgdGhpcy5fZHJhZ0Ryb3BSZWdpc3RyeS5zdGFydERyYWdnaW5nKHRoaXMsIGV2ZW50KTtcbiAgfVxuXG4gIC8qKiBDbGVhbnMgdXAgdGhlIERPTSBhcnRpZmFjdHMgdGhhdCB3ZXJlIGFkZGVkIHRvIGZhY2lsaXRhdGUgdGhlIGVsZW1lbnQgYmVpbmcgZHJhZ2dlZC4gKi9cbiAgcHJpdmF0ZSBfY2xlYW51cERyYWdBcnRpZmFjdHMoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KSB7XG4gICAgLy8gUmVzdG9yZSB0aGUgZWxlbWVudCdzIHZpc2liaWxpdHkgYW5kIGluc2VydCBpdCBhdCBpdHMgb2xkIHBvc2l0aW9uIGluIHRoZSBET00uXG4gICAgLy8gSXQncyBpbXBvcnRhbnQgdGhhdCB3ZSBtYWludGFpbiB0aGUgcG9zaXRpb24sIGJlY2F1c2UgbW92aW5nIHRoZSBlbGVtZW50IGFyb3VuZCBpbiB0aGUgRE9NXG4gICAgLy8gY2FuIHRocm93IG9mZiBgTmdGb3JgIHdoaWNoIGRvZXMgc21hcnQgZGlmZmluZyBhbmQgcmUtY3JlYXRlcyBlbGVtZW50cyBvbmx5IHdoZW4gbmVjZXNzYXJ5LFxuICAgIC8vIHdoaWxlIG1vdmluZyB0aGUgZXhpc3RpbmcgZWxlbWVudHMgaW4gYWxsIG90aGVyIGNhc2VzLlxuICAgIHRvZ2dsZVZpc2liaWxpdHkodGhpcy5fcm9vdEVsZW1lbnQsIHRydWUsIGRyYWdJbXBvcnRhbnRQcm9wZXJ0aWVzKTtcbiAgICB0aGlzLl9hbmNob3IucGFyZW50Tm9kZSEucmVwbGFjZUNoaWxkKHRoaXMuX3Jvb3RFbGVtZW50LCB0aGlzLl9hbmNob3IpO1xuXG4gICAgdGhpcy5fZGVzdHJveVByZXZpZXcoKTtcbiAgICB0aGlzLl9kZXN0cm95UGxhY2Vob2xkZXIoKTtcbiAgICB0aGlzLl9ib3VuZGFyeVJlY3QgPSB0aGlzLl9wcmV2aWV3UmVjdCA9IHRoaXMuX2luaXRpYWxUcmFuc2Zvcm0gPSB1bmRlZmluZWQ7XG5cbiAgICAvLyBSZS1lbnRlciB0aGUgTmdab25lIHNpbmNlIHdlIGJvdW5kIGBkb2N1bWVudGAgZXZlbnRzIG9uIHRoZSBvdXRzaWRlLlxuICAgIHRoaXMuX25nWm9uZS5ydW4oKCkgPT4ge1xuICAgICAgY29uc3QgY29udGFpbmVyID0gdGhpcy5fZHJvcENvbnRhaW5lciE7XG4gICAgICBjb25zdCBjdXJyZW50SW5kZXggPSBjb250YWluZXIuZ2V0SXRlbUluZGV4KHRoaXMpO1xuICAgICAgY29uc3QgcG9pbnRlclBvc2l0aW9uID0gdGhpcy5fZ2V0UG9pbnRlclBvc2l0aW9uT25QYWdlKGV2ZW50KTtcbiAgICAgIGNvbnN0IGRpc3RhbmNlID0gdGhpcy5fZ2V0RHJhZ0Rpc3RhbmNlKHBvaW50ZXJQb3NpdGlvbik7XG4gICAgICBjb25zdCBpc1BvaW50ZXJPdmVyQ29udGFpbmVyID0gY29udGFpbmVyLl9pc092ZXJDb250YWluZXIoXG4gICAgICAgIHBvaW50ZXJQb3NpdGlvbi54LFxuICAgICAgICBwb2ludGVyUG9zaXRpb24ueSxcbiAgICAgICk7XG5cbiAgICAgIHRoaXMuZW5kZWQubmV4dCh7c291cmNlOiB0aGlzLCBkaXN0YW5jZSwgZHJvcFBvaW50OiBwb2ludGVyUG9zaXRpb259KTtcbiAgICAgIHRoaXMuZHJvcHBlZC5uZXh0KHtcbiAgICAgICAgaXRlbTogdGhpcyxcbiAgICAgICAgY3VycmVudEluZGV4LFxuICAgICAgICBwcmV2aW91c0luZGV4OiB0aGlzLl9pbml0aWFsSW5kZXgsXG4gICAgICAgIGNvbnRhaW5lcjogY29udGFpbmVyLFxuICAgICAgICBwcmV2aW91c0NvbnRhaW5lcjogdGhpcy5faW5pdGlhbENvbnRhaW5lcixcbiAgICAgICAgaXNQb2ludGVyT3ZlckNvbnRhaW5lcixcbiAgICAgICAgZGlzdGFuY2UsXG4gICAgICAgIGRyb3BQb2ludDogcG9pbnRlclBvc2l0aW9uLFxuICAgICAgfSk7XG4gICAgICBjb250YWluZXIuZHJvcChcbiAgICAgICAgdGhpcyxcbiAgICAgICAgY3VycmVudEluZGV4LFxuICAgICAgICB0aGlzLl9pbml0aWFsSW5kZXgsXG4gICAgICAgIHRoaXMuX2luaXRpYWxDb250YWluZXIsXG4gICAgICAgIGlzUG9pbnRlck92ZXJDb250YWluZXIsXG4gICAgICAgIGRpc3RhbmNlLFxuICAgICAgICBwb2ludGVyUG9zaXRpb24sXG4gICAgICApO1xuICAgICAgdGhpcy5fZHJvcENvbnRhaW5lciA9IHRoaXMuX2luaXRpYWxDb250YWluZXI7XG4gICAgfSk7XG4gIH1cblxuICAvKipcbiAgICogVXBkYXRlcyB0aGUgaXRlbSdzIHBvc2l0aW9uIGluIGl0cyBkcm9wIGNvbnRhaW5lciwgb3IgbW92ZXMgaXRcbiAgICogaW50byBhIG5ldyBvbmUsIGRlcGVuZGluZyBvbiBpdHMgY3VycmVudCBkcmFnIHBvc2l0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBfdXBkYXRlQWN0aXZlRHJvcENvbnRhaW5lcih7eCwgeX06IFBvaW50LCB7eDogcmF3WCwgeTogcmF3WX06IFBvaW50KSB7XG4gICAgLy8gRHJvcCBjb250YWluZXIgdGhhdCBkcmFnZ2FibGUgaGFzIGJlZW4gbW92ZWQgaW50by5cbiAgICBsZXQgbmV3Q29udGFpbmVyID0gdGhpcy5faW5pdGlhbENvbnRhaW5lci5fZ2V0U2libGluZ0NvbnRhaW5lckZyb21Qb3NpdGlvbih0aGlzLCB4LCB5KTtcblxuICAgIC8vIElmIHdlIGNvdWxkbid0IGZpbmQgYSBuZXcgY29udGFpbmVyIHRvIG1vdmUgdGhlIGl0ZW0gaW50bywgYW5kIHRoZSBpdGVtIGhhcyBsZWZ0IGl0c1xuICAgIC8vIGluaXRpYWwgY29udGFpbmVyLCBjaGVjayB3aGV0aGVyIHRoZSBpdCdzIG92ZXIgdGhlIGluaXRpYWwgY29udGFpbmVyLiBUaGlzIGhhbmRsZXMgdGhlXG4gICAgLy8gY2FzZSB3aGVyZSB0d28gY29udGFpbmVycyBhcmUgY29ubmVjdGVkIG9uZSB3YXkgYW5kIHRoZSB1c2VyIHRyaWVzIHRvIHVuZG8gZHJhZ2dpbmcgYW5cbiAgICAvLyBpdGVtIGludG8gYSBuZXcgY29udGFpbmVyLlxuICAgIGlmIChcbiAgICAgICFuZXdDb250YWluZXIgJiZcbiAgICAgIHRoaXMuX2Ryb3BDb250YWluZXIgIT09IHRoaXMuX2luaXRpYWxDb250YWluZXIgJiZcbiAgICAgIHRoaXMuX2luaXRpYWxDb250YWluZXIuX2lzT3ZlckNvbnRhaW5lcih4LCB5KVxuICAgICkge1xuICAgICAgbmV3Q29udGFpbmVyID0gdGhpcy5faW5pdGlhbENvbnRhaW5lcjtcbiAgICB9XG5cbiAgICBpZiAobmV3Q29udGFpbmVyICYmIG5ld0NvbnRhaW5lciAhPT0gdGhpcy5fZHJvcENvbnRhaW5lcikge1xuICAgICAgdGhpcy5fbmdab25lLnJ1bigoKSA9PiB7XG4gICAgICAgIC8vIE5vdGlmeSB0aGUgb2xkIGNvbnRhaW5lciB0aGF0IHRoZSBpdGVtIGhhcyBsZWZ0LlxuICAgICAgICB0aGlzLmV4aXRlZC5uZXh0KHtpdGVtOiB0aGlzLCBjb250YWluZXI6IHRoaXMuX2Ryb3BDb250YWluZXIhfSk7XG4gICAgICAgIHRoaXMuX2Ryb3BDb250YWluZXIhLmV4aXQodGhpcyk7XG4gICAgICAgIC8vIE5vdGlmeSB0aGUgbmV3IGNvbnRhaW5lciB0aGF0IHRoZSBpdGVtIGhhcyBlbnRlcmVkLlxuICAgICAgICB0aGlzLl9kcm9wQ29udGFpbmVyID0gbmV3Q29udGFpbmVyITtcbiAgICAgICAgdGhpcy5fZHJvcENvbnRhaW5lci5lbnRlcihcbiAgICAgICAgICB0aGlzLFxuICAgICAgICAgIHgsXG4gICAgICAgICAgeSxcbiAgICAgICAgICBuZXdDb250YWluZXIgPT09IHRoaXMuX2luaXRpYWxDb250YWluZXIgJiZcbiAgICAgICAgICAgIC8vIElmIHdlJ3JlIHJlLWVudGVyaW5nIHRoZSBpbml0aWFsIGNvbnRhaW5lciBhbmQgc29ydGluZyBpcyBkaXNhYmxlZCxcbiAgICAgICAgICAgIC8vIHB1dCBpdGVtIHRoZSBpbnRvIGl0cyBzdGFydGluZyBpbmRleCB0byBiZWdpbiB3aXRoLlxuICAgICAgICAgICAgbmV3Q29udGFpbmVyLnNvcnRpbmdEaXNhYmxlZFxuICAgICAgICAgICAgPyB0aGlzLl9pbml0aWFsSW5kZXhcbiAgICAgICAgICAgIDogdW5kZWZpbmVkLFxuICAgICAgICApO1xuICAgICAgICB0aGlzLmVudGVyZWQubmV4dCh7XG4gICAgICAgICAgaXRlbTogdGhpcyxcbiAgICAgICAgICBjb250YWluZXI6IG5ld0NvbnRhaW5lciEsXG4gICAgICAgICAgY3VycmVudEluZGV4OiBuZXdDb250YWluZXIhLmdldEl0ZW1JbmRleCh0aGlzKSxcbiAgICAgICAgfSk7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICAvLyBEcmFnZ2luZyBtYXkgaGF2ZSBiZWVuIGludGVycnVwdGVkIGFzIGEgcmVzdWx0IG9mIHRoZSBldmVudHMgYWJvdmUuXG4gICAgaWYgKHRoaXMuaXNEcmFnZ2luZygpKSB7XG4gICAgICB0aGlzLl9kcm9wQ29udGFpbmVyIS5fc3RhcnRTY3JvbGxpbmdJZk5lY2Vzc2FyeShyYXdYLCByYXdZKTtcbiAgICAgIHRoaXMuX2Ryb3BDb250YWluZXIhLl9zb3J0SXRlbSh0aGlzLCB4LCB5LCB0aGlzLl9wb2ludGVyRGlyZWN0aW9uRGVsdGEpO1xuICAgICAgdGhpcy5fYXBwbHlQcmV2aWV3VHJhbnNmb3JtKFxuICAgICAgICB4IC0gdGhpcy5fcGlja3VwUG9zaXRpb25JbkVsZW1lbnQueCxcbiAgICAgICAgeSAtIHRoaXMuX3BpY2t1cFBvc2l0aW9uSW5FbGVtZW50LnksXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8qKlxuICAgKiBDcmVhdGVzIHRoZSBlbGVtZW50IHRoYXQgd2lsbCBiZSByZW5kZXJlZCBuZXh0IHRvIHRoZSB1c2VyJ3MgcG9pbnRlclxuICAgKiBhbmQgd2lsbCBiZSB1c2VkIGFzIGEgcHJldmlldyBvZiB0aGUgZWxlbWVudCB0aGF0IGlzIGJlaW5nIGRyYWdnZWQuXG4gICAqL1xuICBwcml2YXRlIF9jcmVhdGVQcmV2aWV3RWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XG4gICAgY29uc3QgcHJldmlld0NvbmZpZyA9IHRoaXMuX3ByZXZpZXdUZW1wbGF0ZTtcbiAgICBjb25zdCBwcmV2aWV3Q2xhc3MgPSB0aGlzLnByZXZpZXdDbGFzcztcbiAgICBjb25zdCBwcmV2aWV3VGVtcGxhdGUgPSBwcmV2aWV3Q29uZmlnID8gcHJldmlld0NvbmZpZy50ZW1wbGF0ZSA6IG51bGw7XG4gICAgbGV0IHByZXZpZXc6IEhUTUxFbGVtZW50O1xuXG4gICAgaWYgKHByZXZpZXdUZW1wbGF0ZSAmJiBwcmV2aWV3Q29uZmlnKSB7XG4gICAgICAvLyBNZWFzdXJlIHRoZSBlbGVtZW50IGJlZm9yZSB3ZSd2ZSBpbnNlcnRlZCB0aGUgcHJldmlld1xuICAgICAgLy8gc2luY2UgdGhlIGluc2VydGlvbiBjb3VsZCB0aHJvdyBvZmYgdGhlIG1lYXN1cmVtZW50LlxuICAgICAgY29uc3Qgcm9vdFJlY3QgPSBwcmV2aWV3Q29uZmlnLm1hdGNoU2l6ZSA/IHRoaXMuX3Jvb3RFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIDogbnVsbDtcbiAgICAgIGNvbnN0IHZpZXdSZWYgPSBwcmV2aWV3Q29uZmlnLnZpZXdDb250YWluZXIuY3JlYXRlRW1iZWRkZWRWaWV3KFxuICAgICAgICBwcmV2aWV3VGVtcGxhdGUsXG4gICAgICAgIHByZXZpZXdDb25maWcuY29udGV4dCxcbiAgICAgICk7XG4gICAgICB2aWV3UmVmLmRldGVjdENoYW5nZXMoKTtcbiAgICAgIHByZXZpZXcgPSBnZXRSb290Tm9kZSh2aWV3UmVmLCB0aGlzLl9kb2N1bWVudCk7XG4gICAgICB0aGlzLl9wcmV2aWV3UmVmID0gdmlld1JlZjtcbiAgICAgIGlmIChwcmV2aWV3Q29uZmlnLm1hdGNoU2l6ZSkge1xuICAgICAgICBtYXRjaEVsZW1lbnRTaXplKHByZXZpZXcsIHJvb3RSZWN0ISk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwcmV2aWV3LnN0eWxlLnRyYW5zZm9ybSA9IGdldFRyYW5zZm9ybShcbiAgICAgICAgICB0aGlzLl9waWNrdXBQb3NpdGlvbk9uUGFnZS54LFxuICAgICAgICAgIHRoaXMuX3BpY2t1cFBvc2l0aW9uT25QYWdlLnksXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGVsZW1lbnQgPSB0aGlzLl9yb290RWxlbWVudDtcbiAgICAgIHByZXZpZXcgPSBkZWVwQ2xvbmVOb2RlKGVsZW1lbnQpO1xuICAgICAgbWF0Y2hFbGVtZW50U2l6ZShwcmV2aWV3LCBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpKTtcblxuICAgICAgaWYgKHRoaXMuX2luaXRpYWxUcmFuc2Zvcm0pIHtcbiAgICAgICAgcHJldmlldy5zdHlsZS50cmFuc2Zvcm0gPSB0aGlzLl9pbml0aWFsVHJhbnNmb3JtO1xuICAgICAgfVxuICAgIH1cblxuICAgIGV4dGVuZFN0eWxlcyhcbiAgICAgIHByZXZpZXcuc3R5bGUsXG4gICAgICB7XG4gICAgICAgIC8vIEl0J3MgaW1wb3J0YW50IHRoYXQgd2UgZGlzYWJsZSB0aGUgcG9pbnRlciBldmVudHMgb24gdGhlIHByZXZpZXcsIGJlY2F1c2VcbiAgICAgICAgLy8gaXQgY2FuIHRocm93IG9mZiB0aGUgYGRvY3VtZW50LmVsZW1lbnRGcm9tUG9pbnRgIGNhbGxzIGluIHRoZSBgQ2RrRHJvcExpc3RgLlxuICAgICAgICAncG9pbnRlci1ldmVudHMnOiAnbm9uZScsXG4gICAgICAgIC8vIFdlIGhhdmUgdG8gcmVzZXQgdGhlIG1hcmdpbiwgYmVjYXVzZSBpdCBjYW4gdGhyb3cgb2ZmIHBvc2l0aW9uaW5nIHJlbGF0aXZlIHRvIHRoZSB2aWV3cG9ydC5cbiAgICAgICAgJ21hcmdpbic6ICcwJyxcbiAgICAgICAgJ3Bvc2l0aW9uJzogJ2ZpeGVkJyxcbiAgICAgICAgJ3RvcCc6ICcwJyxcbiAgICAgICAgJ2xlZnQnOiAnMCcsXG4gICAgICAgICd6LWluZGV4JzogYCR7dGhpcy5fY29uZmlnLnpJbmRleCB8fCAxMDAwfWAsXG4gICAgICB9LFxuICAgICAgZHJhZ0ltcG9ydGFudFByb3BlcnRpZXMsXG4gICAgKTtcblxuICAgIHRvZ2dsZU5hdGl2ZURyYWdJbnRlcmFjdGlvbnMocHJldmlldywgZmFsc2UpO1xuICAgIHByZXZpZXcuY2xhc3NMaXN0LmFkZCgnY2RrLWRyYWctcHJldmlldycpO1xuICAgIHByZXZpZXcuc2V0QXR0cmlidXRlKCdkaXInLCB0aGlzLl9kaXJlY3Rpb24pO1xuXG4gICAgaWYgKHByZXZpZXdDbGFzcykge1xuICAgICAgaWYgKEFycmF5LmlzQXJyYXkocHJldmlld0NsYXNzKSkge1xuICAgICAgICBwcmV2aWV3Q2xhc3MuZm9yRWFjaChjbGFzc05hbWUgPT4gcHJldmlldy5jbGFzc0xpc3QuYWRkKGNsYXNzTmFtZSkpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcHJldmlldy5jbGFzc0xpc3QuYWRkKHByZXZpZXdDbGFzcyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIHByZXZpZXc7XG4gIH1cblxuICAvKipcbiAgICogQW5pbWF0ZXMgdGhlIHByZXZpZXcgZWxlbWVudCBmcm9tIGl0cyBjdXJyZW50IHBvc2l0aW9uIHRvIHRoZSBsb2NhdGlvbiBvZiB0aGUgZHJvcCBwbGFjZWhvbGRlci5cbiAgICogQHJldHVybnMgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHdoZW4gdGhlIGFuaW1hdGlvbiBjb21wbGV0ZXMuXG4gICAqL1xuICBwcml2YXRlIF9hbmltYXRlUHJldmlld1RvUGxhY2Vob2xkZXIoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgLy8gSWYgdGhlIHVzZXIgaGFzbid0IG1vdmVkIHlldCwgdGhlIHRyYW5zaXRpb25lbmQgZXZlbnQgd29uJ3QgZmlyZS5cbiAgICBpZiAoIXRoaXMuX2hhc01vdmVkKSB7XG4gICAgICByZXR1cm4gUHJvbWlzZS5yZXNvbHZlKCk7XG4gICAgfVxuXG4gICAgY29uc3QgcGxhY2Vob2xkZXJSZWN0ID0gdGhpcy5fcGxhY2Vob2xkZXIuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG5cbiAgICAvLyBBcHBseSB0aGUgY2xhc3MgdGhhdCBhZGRzIGEgdHJhbnNpdGlvbiB0byB0aGUgcHJldmlldy5cbiAgICB0aGlzLl9wcmV2aWV3LmNsYXNzTGlzdC5hZGQoJ2Nkay1kcmFnLWFuaW1hdGluZycpO1xuXG4gICAgLy8gTW92ZSB0aGUgcHJldmlldyB0byB0aGUgcGxhY2Vob2xkZXIgcG9zaXRpb24uXG4gICAgdGhpcy5fYXBwbHlQcmV2aWV3VHJhbnNmb3JtKHBsYWNlaG9sZGVyUmVjdC5sZWZ0LCBwbGFjZWhvbGRlclJlY3QudG9wKTtcblxuICAgIC8vIElmIHRoZSBlbGVtZW50IGRvZXNuJ3QgaGF2ZSBhIGB0cmFuc2l0aW9uYCwgdGhlIGB0cmFuc2l0aW9uZW5kYCBldmVudCB3b24ndCBmaXJlLiBTaW5jZVxuICAgIC8vIHdlIG5lZWQgdG8gdHJpZ2dlciBhIHN0eWxlIHJlY2FsY3VsYXRpb24gaW4gb3JkZXIgZm9yIHRoZSBgY2RrLWRyYWctYW5pbWF0aW5nYCBjbGFzcyB0b1xuICAgIC8vIGFwcGx5IGl0cyBzdHlsZSwgd2UgdGFrZSBhZHZhbnRhZ2Ugb2YgdGhlIGF2YWlsYWJsZSBpbmZvIHRvIGZpZ3VyZSBvdXQgd2hldGhlciB3ZSBuZWVkIHRvXG4gICAgLy8gYmluZCB0aGUgZXZlbnQgaW4gdGhlIGZpcnN0IHBsYWNlLlxuICAgIGNvbnN0IGR1cmF0aW9uID0gZ2V0VHJhbnNmb3JtVHJhbnNpdGlvbkR1cmF0aW9uSW5Ncyh0aGlzLl9wcmV2aWV3KTtcblxuICAgIGlmIChkdXJhdGlvbiA9PT0gMCkge1xuICAgICAgcmV0dXJuIFByb21pc2UucmVzb2x2ZSgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLl9uZ1pvbmUucnVuT3V0c2lkZUFuZ3VsYXIoKCkgPT4ge1xuICAgICAgcmV0dXJuIG5ldyBQcm9taXNlKHJlc29sdmUgPT4ge1xuICAgICAgICBjb25zdCBoYW5kbGVyID0gKChldmVudDogVHJhbnNpdGlvbkV2ZW50KSA9PiB7XG4gICAgICAgICAgaWYgKFxuICAgICAgICAgICAgIWV2ZW50IHx8XG4gICAgICAgICAgICAoX2dldEV2ZW50VGFyZ2V0KGV2ZW50KSA9PT0gdGhpcy5fcHJldmlldyAmJiBldmVudC5wcm9wZXJ0eU5hbWUgPT09ICd0cmFuc2Zvcm0nKVxuICAgICAgICAgICkge1xuICAgICAgICAgICAgdGhpcy5fcHJldmlldz8ucmVtb3ZlRXZlbnRMaXN0ZW5lcigndHJhbnNpdGlvbmVuZCcsIGhhbmRsZXIpO1xuICAgICAgICAgICAgcmVzb2x2ZSgpO1xuICAgICAgICAgICAgY2xlYXJUaW1lb3V0KHRpbWVvdXQpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSkgYXMgRXZlbnRMaXN0ZW5lck9yRXZlbnRMaXN0ZW5lck9iamVjdDtcblxuICAgICAgICAvLyBJZiBhIHRyYW5zaXRpb24gaXMgc2hvcnQgZW5vdWdoLCB0aGUgYnJvd3NlciBtaWdodCBub3QgZmlyZSB0aGUgYHRyYW5zaXRpb25lbmRgIGV2ZW50LlxuICAgICAgICAvLyBTaW5jZSB3ZSBrbm93IGhvdyBsb25nIGl0J3Mgc3VwcG9zZWQgdG8gdGFrZSwgYWRkIGEgdGltZW91dCB3aXRoIGEgNTAlIGJ1ZmZlciB0aGF0J2xsXG4gICAgICAgIC8vIGZpcmUgaWYgdGhlIHRyYW5zaXRpb24gaGFzbid0IGNvbXBsZXRlZCB3aGVuIGl0IHdhcyBzdXBwb3NlZCB0by5cbiAgICAgICAgY29uc3QgdGltZW91dCA9IHNldFRpbWVvdXQoaGFuZGxlciBhcyBGdW5jdGlvbiwgZHVyYXRpb24gKiAxLjUpO1xuICAgICAgICB0aGlzLl9wcmV2aWV3LmFkZEV2ZW50TGlzdGVuZXIoJ3RyYW5zaXRpb25lbmQnLCBoYW5kbGVyKTtcbiAgICAgIH0pO1xuICAgIH0pO1xuICB9XG5cbiAgLyoqIENyZWF0ZXMgYW4gZWxlbWVudCB0aGF0IHdpbGwgYmUgc2hvd24gaW5zdGVhZCBvZiB0aGUgY3VycmVudCBlbGVtZW50IHdoaWxlIGRyYWdnaW5nLiAqL1xuICBwcml2YXRlIF9jcmVhdGVQbGFjZWhvbGRlckVsZW1lbnQoKTogSFRNTEVsZW1lbnQge1xuICAgIGNvbnN0IHBsYWNlaG9sZGVyQ29uZmlnID0gdGhpcy5fcGxhY2Vob2xkZXJUZW1wbGF0ZTtcbiAgICBjb25zdCBwbGFjZWhvbGRlclRlbXBsYXRlID0gcGxhY2Vob2xkZXJDb25maWcgPyBwbGFjZWhvbGRlckNvbmZpZy50ZW1wbGF0ZSA6IG51bGw7XG4gICAgbGV0IHBsYWNlaG9sZGVyOiBIVE1MRWxlbWVudDtcblxuICAgIGlmIChwbGFjZWhvbGRlclRlbXBsYXRlKSB7XG4gICAgICB0aGlzLl9wbGFjZWhvbGRlclJlZiA9IHBsYWNlaG9sZGVyQ29uZmlnIS52aWV3Q29udGFpbmVyLmNyZWF0ZUVtYmVkZGVkVmlldyhcbiAgICAgICAgcGxhY2Vob2xkZXJUZW1wbGF0ZSxcbiAgICAgICAgcGxhY2Vob2xkZXJDb25maWchLmNvbnRleHQsXG4gICAgICApO1xuICAgICAgdGhpcy5fcGxhY2Vob2xkZXJSZWYuZGV0ZWN0Q2hhbmdlcygpO1xuICAgICAgcGxhY2Vob2xkZXIgPSBnZXRSb290Tm9kZSh0aGlzLl9wbGFjZWhvbGRlclJlZiwgdGhpcy5fZG9jdW1lbnQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBwbGFjZWhvbGRlciA9IGRlZXBDbG9uZU5vZGUodGhpcy5fcm9vdEVsZW1lbnQpO1xuICAgIH1cblxuICAgIHBsYWNlaG9sZGVyLmNsYXNzTGlzdC5hZGQoJ2Nkay1kcmFnLXBsYWNlaG9sZGVyJyk7XG4gICAgcmV0dXJuIHBsYWNlaG9sZGVyO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpZ3VyZXMgb3V0IHRoZSBjb29yZGluYXRlcyBhdCB3aGljaCBhbiBlbGVtZW50IHdhcyBwaWNrZWQgdXAuXG4gICAqIEBwYXJhbSByZWZlcmVuY2VFbGVtZW50IEVsZW1lbnQgdGhhdCBpbml0aWF0ZWQgdGhlIGRyYWdnaW5nLlxuICAgKiBAcGFyYW0gZXZlbnQgRXZlbnQgdGhhdCBpbml0aWF0ZWQgdGhlIGRyYWdnaW5nLlxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0UG9pbnRlclBvc2l0aW9uSW5FbGVtZW50KFxuICAgIHJlZmVyZW5jZUVsZW1lbnQ6IEhUTUxFbGVtZW50LFxuICAgIGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCxcbiAgKTogUG9pbnQge1xuICAgIGNvbnN0IGVsZW1lbnRSZWN0ID0gdGhpcy5fcm9vdEVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgY29uc3QgaGFuZGxlRWxlbWVudCA9IHJlZmVyZW5jZUVsZW1lbnQgPT09IHRoaXMuX3Jvb3RFbGVtZW50ID8gbnVsbCA6IHJlZmVyZW5jZUVsZW1lbnQ7XG4gICAgY29uc3QgcmVmZXJlbmNlUmVjdCA9IGhhbmRsZUVsZW1lbnQgPyBoYW5kbGVFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpIDogZWxlbWVudFJlY3Q7XG4gICAgY29uc3QgcG9pbnQgPSBpc1RvdWNoRXZlbnQoZXZlbnQpID8gZXZlbnQudGFyZ2V0VG91Y2hlc1swXSA6IGV2ZW50O1xuICAgIGNvbnN0IHNjcm9sbFBvc2l0aW9uID0gdGhpcy5fZ2V0Vmlld3BvcnRTY3JvbGxQb3NpdGlvbigpO1xuICAgIGNvbnN0IHggPSBwb2ludC5wYWdlWCAtIHJlZmVyZW5jZVJlY3QubGVmdCAtIHNjcm9sbFBvc2l0aW9uLmxlZnQ7XG4gICAgY29uc3QgeSA9IHBvaW50LnBhZ2VZIC0gcmVmZXJlbmNlUmVjdC50b3AgLSBzY3JvbGxQb3NpdGlvbi50b3A7XG5cbiAgICByZXR1cm4ge1xuICAgICAgeDogcmVmZXJlbmNlUmVjdC5sZWZ0IC0gZWxlbWVudFJlY3QubGVmdCArIHgsXG4gICAgICB5OiByZWZlcmVuY2VSZWN0LnRvcCAtIGVsZW1lbnRSZWN0LnRvcCArIHksXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBEZXRlcm1pbmVzIHRoZSBwb2ludCBvZiB0aGUgcGFnZSB0aGF0IHdhcyB0b3VjaGVkIGJ5IHRoZSB1c2VyLiAqL1xuICBwcml2YXRlIF9nZXRQb2ludGVyUG9zaXRpb25PblBhZ2UoZXZlbnQ6IE1vdXNlRXZlbnQgfCBUb3VjaEV2ZW50KTogUG9pbnQge1xuICAgIGNvbnN0IHNjcm9sbFBvc2l0aW9uID0gdGhpcy5fZ2V0Vmlld3BvcnRTY3JvbGxQb3NpdGlvbigpO1xuICAgIGNvbnN0IHBvaW50ID0gaXNUb3VjaEV2ZW50KGV2ZW50KVxuICAgICAgPyAvLyBgdG91Y2hlc2Agd2lsbCBiZSBlbXB0eSBmb3Igc3RhcnQvZW5kIGV2ZW50cyBzbyB3ZSBoYXZlIHRvIGZhbGwgYmFjayB0byBgY2hhbmdlZFRvdWNoZXNgLlxuICAgICAgICAvLyBBbHNvIG5vdGUgdGhhdCBvbiByZWFsIGRldmljZXMgd2UncmUgZ3VhcmFudGVlZCBmb3IgZWl0aGVyIGB0b3VjaGVzYCBvciBgY2hhbmdlZFRvdWNoZXNgXG4gICAgICAgIC8vIHRvIGhhdmUgYSB2YWx1ZSwgYnV0IEZpcmVmb3ggaW4gZGV2aWNlIGVtdWxhdGlvbiBtb2RlIGhhcyBhIGJ1ZyB3aGVyZSBib3RoIGNhbiBiZSBlbXB0eVxuICAgICAgICAvLyBmb3IgYHRvdWNoc3RhcnRgIGFuZCBgdG91Y2hlbmRgIHNvIHdlIGZhbGwgYmFjayB0byBhIGR1bW15IG9iamVjdCBpbiBvcmRlciB0byBhdm9pZFxuICAgICAgICAvLyB0aHJvd2luZyBhbiBlcnJvci4gVGhlIHZhbHVlIHJldHVybmVkIGhlcmUgd2lsbCBiZSBpbmNvcnJlY3QsIGJ1dCBzaW5jZSB0aGlzIG9ubHlcbiAgICAgICAgLy8gYnJlYWtzIGluc2lkZSBhIGRldmVsb3BlciB0b29sIGFuZCB0aGUgdmFsdWUgaXMgb25seSB1c2VkIGZvciBzZWNvbmRhcnkgaW5mb3JtYXRpb24sXG4gICAgICAgIC8vIHdlIGNhbiBnZXQgYXdheSB3aXRoIGl0LiBTZWUgaHR0cHM6Ly9idWd6aWxsYS5tb3ppbGxhLm9yZy9zaG93X2J1Zy5jZ2k/aWQ9MTYxNTgyNC5cbiAgICAgICAgZXZlbnQudG91Y2hlc1swXSB8fCBldmVudC5jaGFuZ2VkVG91Y2hlc1swXSB8fCB7cGFnZVg6IDAsIHBhZ2VZOiAwfVxuICAgICAgOiBldmVudDtcblxuICAgIGNvbnN0IHggPSBwb2ludC5wYWdlWCAtIHNjcm9sbFBvc2l0aW9uLmxlZnQ7XG4gICAgY29uc3QgeSA9IHBvaW50LnBhZ2VZIC0gc2Nyb2xsUG9zaXRpb24udG9wO1xuXG4gICAgLy8gaWYgZHJhZ2dpbmcgU1ZHIGVsZW1lbnQsIHRyeSB0byBjb252ZXJ0IGZyb20gdGhlIHNjcmVlbiBjb29yZGluYXRlIHN5c3RlbSB0byB0aGUgU1ZHXG4gICAgLy8gY29vcmRpbmF0ZSBzeXN0ZW1cbiAgICBpZiAodGhpcy5fb3duZXJTVkdFbGVtZW50KSB7XG4gICAgICBjb25zdCBzdmdNYXRyaXggPSB0aGlzLl9vd25lclNWR0VsZW1lbnQuZ2V0U2NyZWVuQ1RNKCk7XG4gICAgICBpZiAoc3ZnTWF0cml4KSB7XG4gICAgICAgIGNvbnN0IHN2Z1BvaW50ID0gdGhpcy5fb3duZXJTVkdFbGVtZW50LmNyZWF0ZVNWR1BvaW50KCk7XG4gICAgICAgIHN2Z1BvaW50LnggPSB4O1xuICAgICAgICBzdmdQb2ludC55ID0geTtcbiAgICAgICAgcmV0dXJuIHN2Z1BvaW50Lm1hdHJpeFRyYW5zZm9ybShzdmdNYXRyaXguaW52ZXJzZSgpKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4ge3gsIHl9O1xuICB9XG5cbiAgLyoqIEdldHMgdGhlIHBvaW50ZXIgcG9zaXRpb24gb24gdGhlIHBhZ2UsIGFjY291bnRpbmcgZm9yIGFueSBwb3NpdGlvbiBjb25zdHJhaW50cy4gKi9cbiAgcHJpdmF0ZSBfZ2V0Q29uc3RyYWluZWRQb2ludGVyUG9zaXRpb24ocG9pbnQ6IFBvaW50KTogUG9pbnQge1xuICAgIGNvbnN0IGRyb3BDb250YWluZXJMb2NrID0gdGhpcy5fZHJvcENvbnRhaW5lciA/IHRoaXMuX2Ryb3BDb250YWluZXIubG9ja0F4aXMgOiBudWxsO1xuICAgIGxldCB7eCwgeX0gPSB0aGlzLmNvbnN0cmFpblBvc2l0aW9uID8gdGhpcy5jb25zdHJhaW5Qb3NpdGlvbihwb2ludCwgdGhpcykgOiBwb2ludDtcblxuICAgIGlmICh0aGlzLmxvY2tBeGlzID09PSAneCcgfHwgZHJvcENvbnRhaW5lckxvY2sgPT09ICd4Jykge1xuICAgICAgeSA9IHRoaXMuX3BpY2t1cFBvc2l0aW9uT25QYWdlLnk7XG4gICAgfSBlbHNlIGlmICh0aGlzLmxvY2tBeGlzID09PSAneScgfHwgZHJvcENvbnRhaW5lckxvY2sgPT09ICd5Jykge1xuICAgICAgeCA9IHRoaXMuX3BpY2t1cFBvc2l0aW9uT25QYWdlLng7XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2JvdW5kYXJ5UmVjdCkge1xuICAgICAgY29uc3Qge3g6IHBpY2t1cFgsIHk6IHBpY2t1cFl9ID0gdGhpcy5fcGlja3VwUG9zaXRpb25JbkVsZW1lbnQ7XG4gICAgICBjb25zdCBib3VuZGFyeVJlY3QgPSB0aGlzLl9ib3VuZGFyeVJlY3Q7XG4gICAgICBjb25zdCBwcmV2aWV3UmVjdCA9IHRoaXMuX3ByZXZpZXdSZWN0ITtcbiAgICAgIGNvbnN0IG1pblkgPSBib3VuZGFyeVJlY3QudG9wICsgcGlja3VwWTtcbiAgICAgIGNvbnN0IG1heFkgPSBib3VuZGFyeVJlY3QuYm90dG9tIC0gKHByZXZpZXdSZWN0LmhlaWdodCAtIHBpY2t1cFkpO1xuICAgICAgY29uc3QgbWluWCA9IGJvdW5kYXJ5UmVjdC5sZWZ0ICsgcGlja3VwWDtcbiAgICAgIGNvbnN0IG1heFggPSBib3VuZGFyeVJlY3QucmlnaHQgLSAocHJldmlld1JlY3Qud2lkdGggLSBwaWNrdXBYKTtcblxuICAgICAgeCA9IGNsYW1wKHgsIG1pblgsIG1heFgpO1xuICAgICAgeSA9IGNsYW1wKHksIG1pblksIG1heFkpO1xuICAgIH1cblxuICAgIHJldHVybiB7eCwgeX07XG4gIH1cblxuICAvKiogVXBkYXRlcyB0aGUgY3VycmVudCBkcmFnIGRlbHRhLCBiYXNlZCBvbiB0aGUgdXNlcidzIGN1cnJlbnQgcG9pbnRlciBwb3NpdGlvbiBvbiB0aGUgcGFnZS4gKi9cbiAgcHJpdmF0ZSBfdXBkYXRlUG9pbnRlckRpcmVjdGlvbkRlbHRhKHBvaW50ZXJQb3NpdGlvbk9uUGFnZTogUG9pbnQpIHtcbiAgICBjb25zdCB7eCwgeX0gPSBwb2ludGVyUG9zaXRpb25PblBhZ2U7XG4gICAgY29uc3QgZGVsdGEgPSB0aGlzLl9wb2ludGVyRGlyZWN0aW9uRGVsdGE7XG4gICAgY29uc3QgcG9zaXRpb25TaW5jZUxhc3RDaGFuZ2UgPSB0aGlzLl9wb2ludGVyUG9zaXRpb25BdExhc3REaXJlY3Rpb25DaGFuZ2U7XG5cbiAgICAvLyBBbW91bnQgb2YgcGl4ZWxzIHRoZSB1c2VyIGhhcyBkcmFnZ2VkIHNpbmNlIHRoZSBsYXN0IHRpbWUgdGhlIGRpcmVjdGlvbiBjaGFuZ2VkLlxuICAgIGNvbnN0IGNoYW5nZVggPSBNYXRoLmFicyh4IC0gcG9zaXRpb25TaW5jZUxhc3RDaGFuZ2UueCk7XG4gICAgY29uc3QgY2hhbmdlWSA9IE1hdGguYWJzKHkgLSBwb3NpdGlvblNpbmNlTGFzdENoYW5nZS55KTtcblxuICAgIC8vIEJlY2F1c2Ugd2UgaGFuZGxlIHBvaW50ZXIgZXZlbnRzIG9uIGEgcGVyLXBpeGVsIGJhc2lzLCB3ZSBkb24ndCB3YW50IHRoZSBkZWx0YVxuICAgIC8vIHRvIGNoYW5nZSBmb3IgZXZlcnkgcGl4ZWwsIG90aGVyd2lzZSBhbnl0aGluZyB0aGF0IGRlcGVuZHMgb24gaXQgY2FuIGxvb2sgZXJyYXRpYy5cbiAgICAvLyBUbyBtYWtlIHRoZSBkZWx0YSBtb3JlIGNvbnNpc3RlbnQsIHdlIHRyYWNrIGhvdyBtdWNoIHRoZSB1c2VyIGhhcyBtb3ZlZCBzaW5jZSB0aGUgbGFzdFxuICAgIC8vIGRlbHRhIGNoYW5nZSBhbmQgd2Ugb25seSB1cGRhdGUgaXQgYWZ0ZXIgaXQgaGFzIHJlYWNoZWQgYSBjZXJ0YWluIHRocmVzaG9sZC5cbiAgICBpZiAoY2hhbmdlWCA+IHRoaXMuX2NvbmZpZy5wb2ludGVyRGlyZWN0aW9uQ2hhbmdlVGhyZXNob2xkKSB7XG4gICAgICBkZWx0YS54ID0geCA+IHBvc2l0aW9uU2luY2VMYXN0Q2hhbmdlLnggPyAxIDogLTE7XG4gICAgICBwb3NpdGlvblNpbmNlTGFzdENoYW5nZS54ID0geDtcbiAgICB9XG5cbiAgICBpZiAoY2hhbmdlWSA+IHRoaXMuX2NvbmZpZy5wb2ludGVyRGlyZWN0aW9uQ2hhbmdlVGhyZXNob2xkKSB7XG4gICAgICBkZWx0YS55ID0geSA+IHBvc2l0aW9uU2luY2VMYXN0Q2hhbmdlLnkgPyAxIDogLTE7XG4gICAgICBwb3NpdGlvblNpbmNlTGFzdENoYW5nZS55ID0geTtcbiAgICB9XG5cbiAgICByZXR1cm4gZGVsdGE7XG4gIH1cblxuICAvKiogVG9nZ2xlcyB0aGUgbmF0aXZlIGRyYWcgaW50ZXJhY3Rpb25zLCBiYXNlZCBvbiBob3cgbWFueSBoYW5kbGVzIGFyZSByZWdpc3RlcmVkLiAqL1xuICBwcml2YXRlIF90b2dnbGVOYXRpdmVEcmFnSW50ZXJhY3Rpb25zKCkge1xuICAgIGlmICghdGhpcy5fcm9vdEVsZW1lbnQgfHwgIXRoaXMuX2hhbmRsZXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb25zdCBzaG91bGRFbmFibGUgPSB0aGlzLl9oYW5kbGVzLmxlbmd0aCA+IDAgfHwgIXRoaXMuaXNEcmFnZ2luZygpO1xuXG4gICAgaWYgKHNob3VsZEVuYWJsZSAhPT0gdGhpcy5fbmF0aXZlSW50ZXJhY3Rpb25zRW5hYmxlZCkge1xuICAgICAgdGhpcy5fbmF0aXZlSW50ZXJhY3Rpb25zRW5hYmxlZCA9IHNob3VsZEVuYWJsZTtcbiAgICAgIHRvZ2dsZU5hdGl2ZURyYWdJbnRlcmFjdGlvbnModGhpcy5fcm9vdEVsZW1lbnQsIHNob3VsZEVuYWJsZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJlbW92ZXMgdGhlIG1hbnVhbGx5LWFkZGVkIGV2ZW50IGxpc3RlbmVycyBmcm9tIHRoZSByb290IGVsZW1lbnQuICovXG4gIHByaXZhdGUgX3JlbW92ZVJvb3RFbGVtZW50TGlzdGVuZXJzKGVsZW1lbnQ6IEhUTUxFbGVtZW50KSB7XG4gICAgZWxlbWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZWRvd24nLCB0aGlzLl9wb2ludGVyRG93biwgYWN0aXZlRXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xuICAgIGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigndG91Y2hzdGFydCcsIHRoaXMuX3BvaW50ZXJEb3duLCBwYXNzaXZlRXZlbnRMaXN0ZW5lck9wdGlvbnMpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFwcGxpZXMgYSBgdHJhbnNmb3JtYCB0byB0aGUgcm9vdCBlbGVtZW50LCB0YWtpbmcgaW50byBhY2NvdW50IGFueSBleGlzdGluZyB0cmFuc2Zvcm1zIG9uIGl0LlxuICAgKiBAcGFyYW0geCBOZXcgdHJhbnNmb3JtIHZhbHVlIGFsb25nIHRoZSBYIGF4aXMuXG4gICAqIEBwYXJhbSB5IE5ldyB0cmFuc2Zvcm0gdmFsdWUgYWxvbmcgdGhlIFkgYXhpcy5cbiAgICovXG4gIHByaXZhdGUgX2FwcGx5Um9vdEVsZW1lbnRUcmFuc2Zvcm0oeDogbnVtYmVyLCB5OiBudW1iZXIpIHtcbiAgICBjb25zdCB0cmFuc2Zvcm0gPSBnZXRUcmFuc2Zvcm0oeCwgeSk7XG4gICAgY29uc3Qgc3R5bGVzID0gdGhpcy5fcm9vdEVsZW1lbnQuc3R5bGU7XG5cbiAgICAvLyBDYWNoZSB0aGUgcHJldmlvdXMgdHJhbnNmb3JtIGFtb3VudCBvbmx5IGFmdGVyIHRoZSBmaXJzdCBkcmFnIHNlcXVlbmNlLCBiZWNhdXNlXG4gICAgLy8gd2UgZG9uJ3Qgd2FudCBvdXIgb3duIHRyYW5zZm9ybXMgdG8gc3RhY2sgb24gdG9wIG9mIGVhY2ggb3RoZXIuXG4gICAgLy8gU2hvdWxkIGJlIGV4Y2x1ZGVkIG5vbmUgYmVjYXVzZSBub25lICsgdHJhbnNsYXRlM2QoeCwgeSwgeCkgaXMgaW52YWxpZCBjc3NcbiAgICBpZiAodGhpcy5faW5pdGlhbFRyYW5zZm9ybSA9PSBudWxsKSB7XG4gICAgICB0aGlzLl9pbml0aWFsVHJhbnNmb3JtID1cbiAgICAgICAgc3R5bGVzLnRyYW5zZm9ybSAmJiBzdHlsZXMudHJhbnNmb3JtICE9ICdub25lJyA/IHN0eWxlcy50cmFuc2Zvcm0gOiAnJztcbiAgICB9XG5cbiAgICAvLyBQcmVzZXJ2ZSB0aGUgcHJldmlvdXMgYHRyYW5zZm9ybWAgdmFsdWUsIGlmIHRoZXJlIHdhcyBvbmUuIE5vdGUgdGhhdCB3ZSBhcHBseSBvdXIgb3duXG4gICAgLy8gdHJhbnNmb3JtIGJlZm9yZSB0aGUgdXNlcidzLCBiZWNhdXNlIHRoaW5ncyBsaWtlIHJvdGF0aW9uIGNhbiBhZmZlY3Qgd2hpY2ggZGlyZWN0aW9uXG4gICAgLy8gdGhlIGVsZW1lbnQgd2lsbCBiZSB0cmFuc2xhdGVkIHRvd2FyZHMuXG4gICAgc3R5bGVzLnRyYW5zZm9ybSA9IGNvbWJpbmVUcmFuc2Zvcm1zKHRyYW5zZm9ybSwgdGhpcy5faW5pdGlhbFRyYW5zZm9ybSk7XG4gIH1cblxuICAvKipcbiAgICogQXBwbGllcyBhIGB0cmFuc2Zvcm1gIHRvIHRoZSBwcmV2aWV3LCB0YWtpbmcgaW50byBhY2NvdW50IGFueSBleGlzdGluZyB0cmFuc2Zvcm1zIG9uIGl0LlxuICAgKiBAcGFyYW0geCBOZXcgdHJhbnNmb3JtIHZhbHVlIGFsb25nIHRoZSBYIGF4aXMuXG4gICAqIEBwYXJhbSB5IE5ldyB0cmFuc2Zvcm0gdmFsdWUgYWxvbmcgdGhlIFkgYXhpcy5cbiAgICovXG4gIHByaXZhdGUgX2FwcGx5UHJldmlld1RyYW5zZm9ybSh4OiBudW1iZXIsIHk6IG51bWJlcikge1xuICAgIC8vIE9ubHkgYXBwbHkgdGhlIGluaXRpYWwgdHJhbnNmb3JtIGlmIHRoZSBwcmV2aWV3IGlzIGEgY2xvbmUgb2YgdGhlIG9yaWdpbmFsIGVsZW1lbnQsIG90aGVyd2lzZVxuICAgIC8vIGl0IGNvdWxkIGJlIGNvbXBsZXRlbHkgZGlmZmVyZW50IGFuZCB0aGUgdHJhbnNmb3JtIG1pZ2h0IG5vdCBtYWtlIHNlbnNlIGFueW1vcmUuXG4gICAgY29uc3QgaW5pdGlhbFRyYW5zZm9ybSA9IHRoaXMuX3ByZXZpZXdUZW1wbGF0ZT8udGVtcGxhdGUgPyB1bmRlZmluZWQgOiB0aGlzLl9pbml0aWFsVHJhbnNmb3JtO1xuICAgIGNvbnN0IHRyYW5zZm9ybSA9IGdldFRyYW5zZm9ybSh4LCB5KTtcbiAgICB0aGlzLl9wcmV2aWV3LnN0eWxlLnRyYW5zZm9ybSA9IGNvbWJpbmVUcmFuc2Zvcm1zKHRyYW5zZm9ybSwgaW5pdGlhbFRyYW5zZm9ybSk7XG4gIH1cblxuICAvKipcbiAgICogR2V0cyB0aGUgZGlzdGFuY2UgdGhhdCB0aGUgdXNlciBoYXMgZHJhZ2dlZCBkdXJpbmcgdGhlIGN1cnJlbnQgZHJhZyBzZXF1ZW5jZS5cbiAgICogQHBhcmFtIGN1cnJlbnRQb3NpdGlvbiBDdXJyZW50IHBvc2l0aW9uIG9mIHRoZSB1c2VyJ3MgcG9pbnRlci5cbiAgICovXG4gIHByaXZhdGUgX2dldERyYWdEaXN0YW5jZShjdXJyZW50UG9zaXRpb246IFBvaW50KTogUG9pbnQge1xuICAgIGNvbnN0IHBpY2t1cFBvc2l0aW9uID0gdGhpcy5fcGlja3VwUG9zaXRpb25PblBhZ2U7XG5cbiAgICBpZiAocGlja3VwUG9zaXRpb24pIHtcbiAgICAgIHJldHVybiB7eDogY3VycmVudFBvc2l0aW9uLnggLSBwaWNrdXBQb3NpdGlvbi54LCB5OiBjdXJyZW50UG9zaXRpb24ueSAtIHBpY2t1cFBvc2l0aW9uLnl9O1xuICAgIH1cblxuICAgIHJldHVybiB7eDogMCwgeTogMH07XG4gIH1cblxuICAvKiogQ2xlYW5zIHVwIGFueSBjYWNoZWQgZWxlbWVudCBkaW1lbnNpb25zIHRoYXQgd2UgZG9uJ3QgbmVlZCBhZnRlciBkcmFnZ2luZyBoYXMgc3RvcHBlZC4gKi9cbiAgcHJpdmF0ZSBfY2xlYW51cENhY2hlZERpbWVuc2lvbnMoKSB7XG4gICAgdGhpcy5fYm91bmRhcnlSZWN0ID0gdGhpcy5fcHJldmlld1JlY3QgPSB1bmRlZmluZWQ7XG4gICAgdGhpcy5fcGFyZW50UG9zaXRpb25zLmNsZWFyKCk7XG4gIH1cblxuICAvKipcbiAgICogQ2hlY2tzIHdoZXRoZXIgdGhlIGVsZW1lbnQgaXMgc3RpbGwgaW5zaWRlIGl0cyBib3VuZGFyeSBhZnRlciB0aGUgdmlld3BvcnQgaGFzIGJlZW4gcmVzaXplZC5cbiAgICogSWYgbm90LCB0aGUgcG9zaXRpb24gaXMgYWRqdXN0ZWQgc28gdGhhdCB0aGUgZWxlbWVudCBmaXRzIGFnYWluLlxuICAgKi9cbiAgcHJpdmF0ZSBfY29udGFpbkluc2lkZUJvdW5kYXJ5T25SZXNpemUoKSB7XG4gICAgbGV0IHt4LCB5fSA9IHRoaXMuX3Bhc3NpdmVUcmFuc2Zvcm07XG5cbiAgICBpZiAoKHggPT09IDAgJiYgeSA9PT0gMCkgfHwgdGhpcy5pc0RyYWdnaW5nKCkgfHwgIXRoaXMuX2JvdW5kYXJ5RWxlbWVudCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGJvdW5kYXJ5UmVjdCA9IHRoaXMuX2JvdW5kYXJ5RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICBjb25zdCBlbGVtZW50UmVjdCA9IHRoaXMuX3Jvb3RFbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG4gICAgLy8gSXQncyBwb3NzaWJsZSB0aGF0IHRoZSBlbGVtZW50IGdvdCBoaWRkZW4gYXdheSBhZnRlciBkcmFnZ2luZyAoZS5nLiBieSBzd2l0Y2hpbmcgdG8gYVxuICAgIC8vIGRpZmZlcmVudCB0YWIpLiBEb24ndCBkbyBhbnl0aGluZyBpbiB0aGlzIGNhc2Ugc28gd2UgZG9uJ3QgY2xlYXIgdGhlIHVzZXIncyBwb3NpdGlvbi5cbiAgICBpZiAoXG4gICAgICAoYm91bmRhcnlSZWN0LndpZHRoID09PSAwICYmIGJvdW5kYXJ5UmVjdC5oZWlnaHQgPT09IDApIHx8XG4gICAgICAoZWxlbWVudFJlY3Qud2lkdGggPT09IDAgJiYgZWxlbWVudFJlY3QuaGVpZ2h0ID09PSAwKVxuICAgICkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGNvbnN0IGxlZnRPdmVyZmxvdyA9IGJvdW5kYXJ5UmVjdC5sZWZ0IC0gZWxlbWVudFJlY3QubGVmdDtcbiAgICBjb25zdCByaWdodE92ZXJmbG93ID0gZWxlbWVudFJlY3QucmlnaHQgLSBib3VuZGFyeVJlY3QucmlnaHQ7XG4gICAgY29uc3QgdG9wT3ZlcmZsb3cgPSBib3VuZGFyeVJlY3QudG9wIC0gZWxlbWVudFJlY3QudG9wO1xuICAgIGNvbnN0IGJvdHRvbU92ZXJmbG93ID0gZWxlbWVudFJlY3QuYm90dG9tIC0gYm91bmRhcnlSZWN0LmJvdHRvbTtcblxuICAgIC8vIElmIHRoZSBlbGVtZW50IGhhcyBiZWNvbWUgd2lkZXIgdGhhbiB0aGUgYm91bmRhcnksIHdlIGNhbid0XG4gICAgLy8gZG8gbXVjaCB0byBtYWtlIGl0IGZpdCBzbyB3ZSBqdXN0IGFuY2hvciBpdCB0byB0aGUgbGVmdC5cbiAgICBpZiAoYm91bmRhcnlSZWN0LndpZHRoID4gZWxlbWVudFJlY3Qud2lkdGgpIHtcbiAgICAgIGlmIChsZWZ0T3ZlcmZsb3cgPiAwKSB7XG4gICAgICAgIHggKz0gbGVmdE92ZXJmbG93O1xuICAgICAgfVxuXG4gICAgICBpZiAocmlnaHRPdmVyZmxvdyA+IDApIHtcbiAgICAgICAgeCAtPSByaWdodE92ZXJmbG93O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB4ID0gMDtcbiAgICB9XG5cbiAgICAvLyBJZiB0aGUgZWxlbWVudCBoYXMgYmVjb21lIHRhbGxlciB0aGFuIHRoZSBib3VuZGFyeSwgd2UgY2FuJ3RcbiAgICAvLyBkbyBtdWNoIHRvIG1ha2UgaXQgZml0IHNvIHdlIGp1c3QgYW5jaG9yIGl0IHRvIHRoZSB0b3AuXG4gICAgaWYgKGJvdW5kYXJ5UmVjdC5oZWlnaHQgPiBlbGVtZW50UmVjdC5oZWlnaHQpIHtcbiAgICAgIGlmICh0b3BPdmVyZmxvdyA+IDApIHtcbiAgICAgICAgeSArPSB0b3BPdmVyZmxvdztcbiAgICAgIH1cblxuICAgICAgaWYgKGJvdHRvbU92ZXJmbG93ID4gMCkge1xuICAgICAgICB5IC09IGJvdHRvbU92ZXJmbG93O1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB5ID0gMDtcbiAgICB9XG5cbiAgICBpZiAoeCAhPT0gdGhpcy5fcGFzc2l2ZVRyYW5zZm9ybS54IHx8IHkgIT09IHRoaXMuX3Bhc3NpdmVUcmFuc2Zvcm0ueSkge1xuICAgICAgdGhpcy5zZXRGcmVlRHJhZ1Bvc2l0aW9uKHt5LCB4fSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEdldHMgdGhlIGRyYWcgc3RhcnQgZGVsYXksIGJhc2VkIG9uIHRoZSBldmVudCB0eXBlLiAqL1xuICBwcml2YXRlIF9nZXREcmFnU3RhcnREZWxheShldmVudDogTW91c2VFdmVudCB8IFRvdWNoRXZlbnQpOiBudW1iZXIge1xuICAgIGNvbnN0IHZhbHVlID0gdGhpcy5kcmFnU3RhcnREZWxheTtcblxuICAgIGlmICh0eXBlb2YgdmFsdWUgPT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChpc1RvdWNoRXZlbnQoZXZlbnQpKSB7XG4gICAgICByZXR1cm4gdmFsdWUudG91Y2g7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbHVlID8gdmFsdWUubW91c2UgOiAwO1xuICB9XG5cbiAgLyoqIFVwZGF0ZXMgdGhlIGludGVybmFsIHN0YXRlIG9mIHRoZSBkcmFnZ2FibGUgZWxlbWVudCB3aGVuIHNjcm9sbGluZyBoYXMgb2NjdXJyZWQuICovXG4gIHByaXZhdGUgX3VwZGF0ZU9uU2Nyb2xsKGV2ZW50OiBFdmVudCkge1xuICAgIGNvbnN0IHNjcm9sbERpZmZlcmVuY2UgPSB0aGlzLl9wYXJlbnRQb3NpdGlvbnMuaGFuZGxlU2Nyb2xsKGV2ZW50KTtcblxuICAgIGlmIChzY3JvbGxEaWZmZXJlbmNlKSB7XG4gICAgICBjb25zdCB0YXJnZXQgPSBfZ2V0RXZlbnRUYXJnZXQ8SFRNTEVsZW1lbnQgfCBEb2N1bWVudD4oZXZlbnQpITtcblxuICAgICAgLy8gQ2xpZW50UmVjdCBkaW1lbnNpb25zIGFyZSBiYXNlZCBvbiB0aGUgc2Nyb2xsIHBvc2l0aW9uIG9mIHRoZSBwYWdlIGFuZCBpdHMgcGFyZW50XG4gICAgICAvLyBub2RlIHNvIHdlIGhhdmUgdG8gdXBkYXRlIHRoZSBjYWNoZWQgYm91bmRhcnkgQ2xpZW50UmVjdCBpZiB0aGUgdXNlciBoYXMgc2Nyb2xsZWQuXG4gICAgICBpZiAoXG4gICAgICAgIHRoaXMuX2JvdW5kYXJ5UmVjdCAmJlxuICAgICAgICB0YXJnZXQgIT09IHRoaXMuX2JvdW5kYXJ5RWxlbWVudCAmJlxuICAgICAgICB0YXJnZXQuY29udGFpbnModGhpcy5fYm91bmRhcnlFbGVtZW50KVxuICAgICAgKSB7XG4gICAgICAgIGFkanVzdENsaWVudFJlY3QodGhpcy5fYm91bmRhcnlSZWN0LCBzY3JvbGxEaWZmZXJlbmNlLnRvcCwgc2Nyb2xsRGlmZmVyZW5jZS5sZWZ0KTtcbiAgICAgIH1cblxuICAgICAgdGhpcy5fcGlja3VwUG9zaXRpb25PblBhZ2UueCArPSBzY3JvbGxEaWZmZXJlbmNlLmxlZnQ7XG4gICAgICB0aGlzLl9waWNrdXBQb3NpdGlvbk9uUGFnZS55ICs9IHNjcm9sbERpZmZlcmVuY2UudG9wO1xuXG4gICAgICAvLyBJZiB3ZSdyZSBpbiBmcmVlIGRyYWcgbW9kZSwgd2UgaGF2ZSB0byB1cGRhdGUgdGhlIGFjdGl2ZSB0cmFuc2Zvcm0sIGJlY2F1c2VcbiAgICAgIC8vIGl0IGlzbid0IHJlbGF0aXZlIHRvIHRoZSB2aWV3cG9ydCBsaWtlIHRoZSBwcmV2aWV3IGluc2lkZSBhIGRyb3AgbGlzdC5cbiAgICAgIGlmICghdGhpcy5fZHJvcENvbnRhaW5lcikge1xuICAgICAgICB0aGlzLl9hY3RpdmVUcmFuc2Zvcm0ueCAtPSBzY3JvbGxEaWZmZXJlbmNlLmxlZnQ7XG4gICAgICAgIHRoaXMuX2FjdGl2ZVRyYW5zZm9ybS55IC09IHNjcm9sbERpZmZlcmVuY2UudG9wO1xuICAgICAgICB0aGlzLl9hcHBseVJvb3RFbGVtZW50VHJhbnNmb3JtKHRoaXMuX2FjdGl2ZVRyYW5zZm9ybS54LCB0aGlzLl9hY3RpdmVUcmFuc2Zvcm0ueSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIEdldHMgdGhlIHNjcm9sbCBwb3NpdGlvbiBvZiB0aGUgdmlld3BvcnQuICovXG4gIHByaXZhdGUgX2dldFZpZXdwb3J0U2Nyb2xsUG9zaXRpb24oKSB7XG4gICAgY29uc3QgY2FjaGVkUG9zaXRpb24gPSB0aGlzLl9wYXJlbnRQb3NpdGlvbnMucG9zaXRpb25zLmdldCh0aGlzLl9kb2N1bWVudCk7XG4gICAgcmV0dXJuIGNhY2hlZFBvc2l0aW9uXG4gICAgICA/IGNhY2hlZFBvc2l0aW9uLnNjcm9sbFBvc2l0aW9uXG4gICAgICA6IHRoaXMuX3ZpZXdwb3J0UnVsZXIuZ2V0Vmlld3BvcnRTY3JvbGxQb3NpdGlvbigpO1xuICB9XG5cbiAgLyoqXG4gICAqIExhemlseSByZXNvbHZlcyBhbmQgcmV0dXJucyB0aGUgc2hhZG93IHJvb3Qgb2YgdGhlIGVsZW1lbnQuIFdlIGRvIHRoaXMgaW4gYSBmdW5jdGlvbiwgcmF0aGVyXG4gICAqIHRoYW4gc2F2aW5nIGl0IGluIHByb3BlcnR5IGRpcmVjdGx5IG9uIGluaXQsIGJlY2F1c2Ugd2Ugd2FudCB0byByZXNvbHZlIGl0IGFzIGxhdGUgYXMgcG9zc2libGVcbiAgICogaW4gb3JkZXIgdG8gZW5zdXJlIHRoYXQgdGhlIGVsZW1lbnQgaGFzIGJlZW4gbW92ZWQgaW50byB0aGUgc2hhZG93IERPTS4gRG9pbmcgaXQgaW5zaWRlIHRoZVxuICAgKiBjb25zdHJ1Y3RvciBtaWdodCBiZSB0b28gZWFybHkgaWYgdGhlIGVsZW1lbnQgaXMgaW5zaWRlIG9mIHNvbWV0aGluZyBsaWtlIGBuZ0ZvcmAgb3IgYG5nSWZgLlxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0U2hhZG93Um9vdCgpOiBTaGFkb3dSb290IHwgbnVsbCB7XG4gICAgaWYgKHRoaXMuX2NhY2hlZFNoYWRvd1Jvb3QgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhpcy5fY2FjaGVkU2hhZG93Um9vdCA9IF9nZXRTaGFkb3dSb290KHRoaXMuX3Jvb3RFbGVtZW50KTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5fY2FjaGVkU2hhZG93Um9vdDtcbiAgfVxuXG4gIC8qKiBHZXRzIHRoZSBlbGVtZW50IGludG8gd2hpY2ggdGhlIGRyYWcgcHJldmlldyBzaG91bGQgYmUgaW5zZXJ0ZWQuICovXG4gIHByaXZhdGUgX2dldFByZXZpZXdJbnNlcnRpb25Qb2ludChcbiAgICBpbml0aWFsUGFyZW50OiBIVE1MRWxlbWVudCxcbiAgICBzaGFkb3dSb290OiBTaGFkb3dSb290IHwgbnVsbCxcbiAgKTogSFRNTEVsZW1lbnQge1xuICAgIGNvbnN0IHByZXZpZXdDb250YWluZXIgPSB0aGlzLl9wcmV2aWV3Q29udGFpbmVyIHx8ICdnbG9iYWwnO1xuXG4gICAgaWYgKHByZXZpZXdDb250YWluZXIgPT09ICdwYXJlbnQnKSB7XG4gICAgICByZXR1cm4gaW5pdGlhbFBhcmVudDtcbiAgICB9XG5cbiAgICBpZiAocHJldmlld0NvbnRhaW5lciA9PT0gJ2dsb2JhbCcpIHtcbiAgICAgIGNvbnN0IGRvY3VtZW50UmVmID0gdGhpcy5fZG9jdW1lbnQ7XG5cbiAgICAgIC8vIFdlIGNhbid0IHVzZSB0aGUgYm9keSBpZiB0aGUgdXNlciBpcyBpbiBmdWxsc2NyZWVuIG1vZGUsXG4gICAgICAvLyBiZWNhdXNlIHRoZSBwcmV2aWV3IHdpbGwgcmVuZGVyIHVuZGVyIHRoZSBmdWxsc2NyZWVuIGVsZW1lbnQuXG4gICAgICAvLyBUT0RPKGNyaXNiZXRvKTogZGVkdXBlIHRoaXMgd2l0aCB0aGUgYEZ1bGxzY3JlZW5PdmVybGF5Q29udGFpbmVyYCBldmVudHVhbGx5LlxuICAgICAgcmV0dXJuIChcbiAgICAgICAgc2hhZG93Um9vdCB8fFxuICAgICAgICBkb2N1bWVudFJlZi5mdWxsc2NyZWVuRWxlbWVudCB8fFxuICAgICAgICAoZG9jdW1lbnRSZWYgYXMgYW55KS53ZWJraXRGdWxsc2NyZWVuRWxlbWVudCB8fFxuICAgICAgICAoZG9jdW1lbnRSZWYgYXMgYW55KS5tb3pGdWxsU2NyZWVuRWxlbWVudCB8fFxuICAgICAgICAoZG9jdW1lbnRSZWYgYXMgYW55KS5tc0Z1bGxzY3JlZW5FbGVtZW50IHx8XG4gICAgICAgIGRvY3VtZW50UmVmLmJvZHlcbiAgICAgICk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGNvZXJjZUVsZW1lbnQocHJldmlld0NvbnRhaW5lcik7XG4gIH1cbn1cblxuLyoqXG4gKiBHZXRzIGEgM2QgYHRyYW5zZm9ybWAgdGhhdCBjYW4gYmUgYXBwbGllZCB0byBhbiBlbGVtZW50LlxuICogQHBhcmFtIHggRGVzaXJlZCBwb3NpdGlvbiBvZiB0aGUgZWxlbWVudCBhbG9uZyB0aGUgWCBheGlzLlxuICogQHBhcmFtIHkgRGVzaXJlZCBwb3NpdGlvbiBvZiB0aGUgZWxlbWVudCBhbG9uZyB0aGUgWSBheGlzLlxuICovXG5mdW5jdGlvbiBnZXRUcmFuc2Zvcm0oeDogbnVtYmVyLCB5OiBudW1iZXIpOiBzdHJpbmcge1xuICAvLyBSb3VuZCB0aGUgdHJhbnNmb3JtcyBzaW5jZSBzb21lIGJyb3dzZXJzIHdpbGxcbiAgLy8gYmx1ciB0aGUgZWxlbWVudHMgZm9yIHN1Yi1waXhlbCB0cmFuc2Zvcm1zLlxuICByZXR1cm4gYHRyYW5zbGF0ZTNkKCR7TWF0aC5yb3VuZCh4KX1weCwgJHtNYXRoLnJvdW5kKHkpfXB4LCAwKWA7XG59XG5cbi8qKiBDbGFtcHMgYSB2YWx1ZSBiZXR3ZWVuIGEgbWluaW11bSBhbmQgYSBtYXhpbXVtLiAqL1xuZnVuY3Rpb24gY2xhbXAodmFsdWU6IG51bWJlciwgbWluOiBudW1iZXIsIG1heDogbnVtYmVyKSB7XG4gIHJldHVybiBNYXRoLm1heChtaW4sIE1hdGgubWluKG1heCwgdmFsdWUpKTtcbn1cblxuLyoqIERldGVybWluZXMgd2hldGhlciBhbiBldmVudCBpcyBhIHRvdWNoIGV2ZW50LiAqL1xuZnVuY3Rpb24gaXNUb3VjaEV2ZW50KGV2ZW50OiBNb3VzZUV2ZW50IHwgVG91Y2hFdmVudCk6IGV2ZW50IGlzIFRvdWNoRXZlbnQge1xuICAvLyBUaGlzIGZ1bmN0aW9uIGlzIGNhbGxlZCBmb3IgZXZlcnkgcGl4ZWwgdGhhdCB0aGUgdXNlciBoYXMgZHJhZ2dlZCBzbyB3ZSBuZWVkIGl0IHRvIGJlXG4gIC8vIGFzIGZhc3QgYXMgcG9zc2libGUuIFNpbmNlIHdlIG9ubHkgYmluZCBtb3VzZSBldmVudHMgYW5kIHRvdWNoIGV2ZW50cywgd2UgY2FuIGFzc3VtZVxuICAvLyB0aGF0IGlmIHRoZSBldmVudCdzIG5hbWUgc3RhcnRzIHdpdGggYHRgLCBpdCdzIGEgdG91Y2ggZXZlbnQuXG4gIHJldHVybiBldmVudC50eXBlWzBdID09PSAndCc7XG59XG5cbi8qKlxuICogR2V0cyB0aGUgcm9vdCBIVE1MIGVsZW1lbnQgb2YgYW4gZW1iZWRkZWQgdmlldy5cbiAqIElmIHRoZSByb290IGlzIG5vdCBhbiBIVE1MIGVsZW1lbnQgaXQgZ2V0cyB3cmFwcGVkIGluIG9uZS5cbiAqL1xuZnVuY3Rpb24gZ2V0Um9vdE5vZGUodmlld1JlZjogRW1iZWRkZWRWaWV3UmVmPGFueT4sIF9kb2N1bWVudDogRG9jdW1lbnQpOiBIVE1MRWxlbWVudCB7XG4gIGNvbnN0IHJvb3ROb2RlczogTm9kZVtdID0gdmlld1JlZi5yb290Tm9kZXM7XG5cbiAgaWYgKHJvb3ROb2Rlcy5sZW5ndGggPT09IDEgJiYgcm9vdE5vZGVzWzBdLm5vZGVUeXBlID09PSBfZG9jdW1lbnQuRUxFTUVOVF9OT0RFKSB7XG4gICAgcmV0dXJuIHJvb3ROb2Rlc1swXSBhcyBIVE1MRWxlbWVudDtcbiAgfVxuXG4gIGNvbnN0IHdyYXBwZXIgPSBfZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gIHJvb3ROb2Rlcy5mb3JFYWNoKG5vZGUgPT4gd3JhcHBlci5hcHBlbmRDaGlsZChub2RlKSk7XG4gIHJldHVybiB3cmFwcGVyO1xufVxuXG4vKipcbiAqIE1hdGNoZXMgdGhlIHRhcmdldCBlbGVtZW50J3Mgc2l6ZSB0byB0aGUgc291cmNlJ3Mgc2l6ZS5cbiAqIEBwYXJhbSB0YXJnZXQgRWxlbWVudCB0aGF0IG5lZWRzIHRvIGJlIHJlc2l6ZWQuXG4gKiBAcGFyYW0gc291cmNlUmVjdCBEaW1lbnNpb25zIG9mIHRoZSBzb3VyY2UgZWxlbWVudC5cbiAqL1xuZnVuY3Rpb24gbWF0Y2hFbGVtZW50U2l6ZSh0YXJnZXQ6IEhUTUxFbGVtZW50LCBzb3VyY2VSZWN0OiBDbGllbnRSZWN0KTogdm9pZCB7XG4gIHRhcmdldC5zdHlsZS53aWR0aCA9IGAke3NvdXJjZVJlY3Qud2lkdGh9cHhgO1xuICB0YXJnZXQuc3R5bGUuaGVpZ2h0ID0gYCR7c291cmNlUmVjdC5oZWlnaHR9cHhgO1xuICB0YXJnZXQuc3R5bGUudHJhbnNmb3JtID0gZ2V0VHJhbnNmb3JtKHNvdXJjZVJlY3QubGVmdCwgc291cmNlUmVjdC50b3ApO1xufVxuIl19