@jax-data-science/sci-image-visualizer 0.8.3 → 0.9.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (525) hide show
  1. package/README.md +201 -460
  2. package/esm2022/index.mjs +28 -15
  3. package/esm2022/lib/channel-histogram/channel-histogram.component.mjs +163 -91
  4. package/esm2022/lib/contracts/capabilities.contract.mjs +4 -3
  5. package/esm2022/lib/contracts/cell-segmenter.contract.mjs +1 -1
  6. package/esm2022/lib/contracts/channel-histogram-api.contract.mjs +5 -1
  7. package/esm2022/lib/contracts/color.mjs +60 -0
  8. package/esm2022/lib/contracts/colormap-lut.mjs +213 -57
  9. package/esm2022/lib/contracts/coordinate-transform.contract.mjs +1 -1
  10. package/esm2022/lib/contracts/display-types.mjs +11 -1
  11. package/esm2022/lib/contracts/instance-segmenter.contract.mjs +1 -1
  12. package/esm2022/lib/contracts/intensity.mjs +48 -5
  13. package/esm2022/lib/contracts/plot-type-contribution.contract.mjs +1 -1
  14. package/esm2022/lib/contracts/plot-type.mjs +134 -17
  15. package/esm2022/lib/contracts/ports/image-state.port.mjs +4 -1
  16. package/esm2022/lib/contracts/ports/preferences.port.mjs +5 -1
  17. package/esm2022/lib/contracts/ports/region-io.port.mjs +2 -1
  18. package/esm2022/lib/contracts/ports/spatial-data.port.mjs +5 -1
  19. package/esm2022/lib/contracts/ports/tile-access.port.mjs +2 -1
  20. package/esm2022/lib/contracts/region-editor-api.contract.mjs +1 -1
  21. package/esm2022/lib/contracts/region-overlay.contract.mjs +1 -1
  22. package/esm2022/lib/contracts/sam.contract.mjs +1 -1
  23. package/esm2022/lib/contracts/semantic-segmenter.contract.mjs +1 -1
  24. package/esm2022/lib/contracts/spatial-dataset.contract.mjs +3 -1
  25. package/esm2022/lib/contracts/toolbar-tool.contract.mjs +6 -4
  26. package/esm2022/lib/contracts/visualizer.contract.mjs +1 -1
  27. package/esm2022/lib/contracts/viz-config.mjs +2 -1
  28. package/esm2022/lib/geometry/contour.mjs +63 -0
  29. package/esm2022/lib/geometry/raster.mjs +98 -0
  30. package/esm2022/lib/geometry/ring.mjs +201 -0
  31. package/esm2022/lib/hex-color-picker/hex-color-picker.component.mjs +202 -102
  32. package/esm2022/lib/implementations/base-store-visualizer.mjs +201 -48
  33. package/esm2022/lib/implementations/napari-js/napari-axes-gizmo.mjs +65 -0
  34. package/esm2022/lib/implementations/napari-js/napari-display-state.mjs +136 -0
  35. package/esm2022/lib/implementations/napari-js/napari-helpers.mjs +199 -0
  36. package/esm2022/lib/implementations/napari-js/napari-image-2d-scene.mjs +602 -0
  37. package/esm2022/lib/implementations/napari-js/napari-loading-badge.mjs +3 -4
  38. package/esm2022/lib/implementations/napari-js/napari-loading-state.mjs +66 -0
  39. package/esm2022/lib/implementations/napari-js/napari-region-overlay.mjs +157 -591
  40. package/esm2022/lib/implementations/napari-js/napari-scene.mjs +2 -0
  41. package/esm2022/lib/implementations/napari-js/napari-spatial-2d-scene.mjs +614 -0
  42. package/esm2022/lib/implementations/napari-js/napari-spatial-3d-scene.mjs +769 -0
  43. package/esm2022/lib/implementations/napari-js/napari-spatial-encoding.mjs +199 -0
  44. package/esm2022/lib/implementations/napari-js/napari-spatial-hover.mjs +263 -0
  45. package/esm2022/lib/implementations/napari-js/napari-spatial-scene.mjs +159 -0
  46. package/esm2022/lib/implementations/napari-js/napari-spatial-tiles.mjs +106 -1408
  47. package/esm2022/lib/implementations/napari-js/napari-spatial-tooltip.mjs +2 -2
  48. package/esm2022/lib/implementations/napari-js/napari-surface-scene.mjs +271 -0
  49. package/esm2022/lib/implementations/napari-js/napari-tile-client.mjs +562 -0
  50. package/esm2022/lib/implementations/napari-js/napari-tool-bridge.mjs +344 -0
  51. package/esm2022/lib/implementations/napari-js/napari-visualizer.service.mjs +358 -4218
  52. package/esm2022/lib/implementations/napari-js/napari-volume-scene.mjs +439 -0
  53. package/esm2022/lib/implementations/napari-js/napari-volume-z-handle.mjs +6 -6
  54. package/esm2022/lib/implementations/napari-js/region-overlay/overlay-projection.mjs +96 -0
  55. package/esm2022/lib/implementations/napari-js/region-overlay/region-edit.mjs +35 -0
  56. package/esm2022/lib/implementations/napari-js/region-overlay/region-svg-renderer.mjs +182 -0
  57. package/esm2022/lib/implementations/napari-js/spatial-tiles/categorical-lookup.mjs +30 -0
  58. package/esm2022/lib/implementations/napari-js/spatial-tiles/cell-layers.mjs +274 -0
  59. package/esm2022/lib/implementations/napari-js/spatial-tiles/density-layer.mjs +144 -0
  60. package/esm2022/lib/implementations/napari-js/spatial-tiles/layer-groups.mjs +165 -0
  61. package/esm2022/lib/implementations/napari-js/spatial-tiles/plan-context.mjs +78 -0
  62. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-hover.mjs +182 -0
  63. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-jobs.mjs +369 -0
  64. package/esm2022/lib/implementations/napari-js/spatial-tiles/transcript-layers.mjs +306 -0
  65. package/esm2022/lib/implementations/osd/display-pipeline.mjs +102 -40
  66. package/esm2022/lib/implementations/osd/histogram-sampler.mjs +56 -31
  67. package/esm2022/lib/implementations/osd/openseadragon-viewer-options.mjs +128 -0
  68. package/esm2022/lib/implementations/osd/openseadragon-visualizer.service.mjs +333 -1685
  69. package/esm2022/lib/implementations/osd/osd-coordinate-transform.mjs +1 -1
  70. package/esm2022/lib/implementations/osd/osd-coords.mjs +5 -6
  71. package/esm2022/lib/implementations/osd/osd-export.mjs +122 -0
  72. package/esm2022/lib/implementations/osd/osd-lib.mjs +15 -1
  73. package/esm2022/lib/implementations/osd/osd-navigator-chrome.mjs +205 -0
  74. package/esm2022/lib/implementations/osd/osd-pixel-readback.mjs +68 -0
  75. package/esm2022/lib/implementations/osd/osd-region-overlay-draw.mjs +153 -0
  76. package/esm2022/lib/implementations/osd/osd-region-overlay.mjs +185 -718
  77. package/esm2022/lib/implementations/osd/osd-scale-bar.mjs +52 -60
  78. package/esm2022/lib/implementations/osd/osd-tile-source.mjs +105 -0
  79. package/esm2022/lib/implementations/osd/osd-viewer-like.mjs +2 -0
  80. package/esm2022/lib/implementations/osd/osd-viewer-mount.mjs +44 -0
  81. package/esm2022/lib/implementations/osd/osd-viewport.mjs +184 -0
  82. package/esm2022/lib/implementations/osd/osd-zoom.mjs +7 -1
  83. package/esm2022/lib/implementations/osd/simple-source.mjs +395 -0
  84. package/esm2022/lib/implementations/osd/slice-cache.mjs +53 -48
  85. package/esm2022/lib/implementations/osd/tile-client.mjs +32 -11
  86. package/esm2022/lib/implementations/osd/tile-recolor.mjs +330 -0
  87. package/esm2022/lib/implementations/plotly/omics-trace-builders.mjs +161 -73
  88. package/esm2022/lib/implementations/plotly/plotly-coordinate-transform.mjs +1 -1
  89. package/esm2022/lib/implementations/plotly/plotly-image-loader.mjs +112 -0
  90. package/esm2022/lib/implementations/plotly/plotly-image-recolor.mjs +178 -0
  91. package/esm2022/lib/implementations/plotly/plotly-intensity-inset.mjs +33 -0
  92. package/esm2022/lib/implementations/plotly/plotly-isosurface-controls.mjs +83 -0
  93. package/esm2022/lib/implementations/plotly/plotly-layouts.mjs +121 -0
  94. package/esm2022/lib/implementations/plotly/plotly-readback.mjs +117 -0
  95. package/esm2022/lib/implementations/plotly/plotly-region-overlay.mjs +19 -10
  96. package/esm2022/lib/implementations/plotly/plotly-shape-projection.mjs +223 -0
  97. package/esm2022/lib/implementations/plotly/plotly-trace-builders.mjs +79 -19
  98. package/esm2022/lib/implementations/plotly/plotly-zoom-controller.mjs +223 -0
  99. package/esm2022/lib/implementations/plotly/plotly.service.mjs +439 -1655
  100. package/esm2022/lib/implementations/region-centroids.mjs +47 -0
  101. package/esm2022/lib/implementations/simple-slice-access.service.mjs +22 -12
  102. package/esm2022/lib/implementations/spatial-data-http/spatial-data-http.service.mjs +172 -92
  103. package/esm2022/lib/implementations/spatial-data-http/spatial-wire.mjs +103 -22
  104. package/esm2022/lib/implementations/tile-server/index.mjs +6 -0
  105. package/esm2022/lib/implementations/tile-server/native-histogram.mjs +30 -0
  106. package/esm2022/lib/implementations/tile-server/poll-descriptor.mjs +65 -0
  107. package/esm2022/lib/implementations/tile-server/tile-protocol.mjs +42 -0
  108. package/esm2022/lib/implementations/tile-server/transport.mjs +135 -0
  109. package/esm2022/lib/intensity/intensity-profile.mjs +107 -0
  110. package/esm2022/lib/intensity/intensity-profile.service.mjs +223 -0
  111. package/esm2022/lib/intensity-inset/intensity-inset.component.mjs +133 -0
  112. package/esm2022/lib/models/bezier.mjs +1 -11
  113. package/esm2022/lib/models/class-preset.mjs +41 -3
  114. package/esm2022/lib/models/geometry.mjs +27 -164
  115. package/esm2022/lib/models/polygon-edit.mjs +254 -0
  116. package/esm2022/lib/models/polygon-factory.mjs +118 -0
  117. package/esm2022/lib/models/region-clone.mjs +68 -0
  118. package/esm2022/lib/models/region-geojson.mjs +373 -0
  119. package/esm2022/lib/models/region.mjs +34 -33
  120. package/esm2022/lib/models/shape.mjs +18 -16
  121. package/esm2022/lib/plot-mode/contribution-host.mjs +297 -0
  122. package/esm2022/lib/plot-mode/plot-mode-controller.mjs +9 -6
  123. package/esm2022/lib/plot-mode/plot-type-menu.mjs +85 -0
  124. package/esm2022/lib/plot-mode/tool-params-model.mjs +87 -0
  125. package/esm2022/lib/plot.utilities.mjs +296 -473
  126. package/esm2022/lib/processing/image-crop.mjs +1 -1
  127. package/esm2022/lib/processing/processing-image.mjs +28 -15
  128. package/esm2022/lib/provide-visualization.mjs +40 -14
  129. package/esm2022/lib/region-editor/classes-panel/classes-panel.component.mjs +99 -0
  130. package/esm2022/lib/region-editor/file-stem.mjs +13 -0
  131. package/esm2022/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.mjs +118 -0
  132. package/esm2022/lib/region-editor/mask-export.service.mjs +98 -0
  133. package/esm2022/lib/region-editor/mask-raster.mjs +11 -5
  134. package/esm2022/lib/region-editor/region-color-dialog/region-color-dialog.component.mjs +56 -0
  135. package/esm2022/lib/region-editor/region-editor-help/region-editor-help.component.mjs +28 -0
  136. package/esm2022/lib/region-editor/region-editor.component.mjs +402 -651
  137. package/esm2022/lib/region-editor/region-metrics.mjs +68 -0
  138. package/esm2022/lib/region-editor/region-persistence.service.mjs +134 -0
  139. package/esm2022/lib/region-editor/region-table/region-table.component.mjs +153 -0
  140. package/esm2022/lib/region-editor/save-mask-dialog/save-mask-dialog.component.mjs +91 -0
  141. package/esm2022/lib/region-editor/save-regions-dialog/save-regions-dialog.component.mjs +92 -0
  142. package/esm2022/lib/region-ops.service.mjs +28 -70
  143. package/esm2022/lib/region-overlay/region-geometry.mjs +360 -0
  144. package/esm2022/lib/region-overlay/region-hit-test.mjs +103 -0
  145. package/esm2022/lib/region-overlay/svg-region-renderer.mjs +228 -0
  146. package/esm2022/lib/render-orchestrator.mjs +14 -11
  147. package/esm2022/lib/render-session.mjs +207 -0
  148. package/esm2022/lib/routing-visualizer.service.mjs +459 -411
  149. package/esm2022/lib/spatial/density-raster.mjs +14 -0
  150. package/esm2022/lib/spatial/embedding-compute-coordinator.mjs +239 -0
  151. package/esm2022/lib/spatial/embedding-compute.mjs +43 -10
  152. package/esm2022/lib/spatial/gene-search.mjs +1 -1
  153. package/esm2022/lib/spatial/glyphs.mjs +97 -0
  154. package/esm2022/lib/spatial/lod.mjs +187 -0
  155. package/esm2022/lib/spatial/spatial-controls.facade.mjs +200 -0
  156. package/esm2022/lib/spatial/spatial-density.mjs +25 -16
  157. package/esm2022/lib/spatial/spatial-encoding.mjs +26 -82
  158. package/esm2022/lib/spatial/spatial-expression.mjs +43 -42
  159. package/esm2022/lib/spatial/spatial-framing.mjs +1 -1
  160. package/esm2022/lib/spatial/spatial-heatmap.mjs +6 -3
  161. package/esm2022/lib/spatial/spatial-hover.mjs +5 -33
  162. package/esm2022/lib/spatial/spatial-panel-model.mjs +282 -0
  163. package/esm2022/lib/spatial/spatial-sections.mjs +1 -1
  164. package/esm2022/lib/spatial/spatial-selection.mjs +33 -46
  165. package/esm2022/lib/spatial/spatial-tile-merge.mjs +219 -0
  166. package/esm2022/lib/spatial/spatial-tiles.mjs +12 -648
  167. package/esm2022/lib/spatial/spatial-volume-image.mjs +2 -4
  168. package/esm2022/lib/spatial/stats.mjs +71 -0
  169. package/esm2022/lib/spatial/transcript-grouping.mjs +307 -0
  170. package/esm2022/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.mjs +150 -0
  171. package/esm2022/lib/spatial-controls/spatial-charts/chart-data-model.mjs +309 -0
  172. package/esm2022/lib/spatial-controls/spatial-charts/chart-help.mjs +145 -0
  173. package/esm2022/lib/spatial-controls/spatial-charts/plotly-chart-host.mjs +158 -0
  174. package/esm2022/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.mjs +47 -0
  175. package/esm2022/lib/spatial-controls/spatial-charts/spatial-charts.component.mjs +297 -802
  176. package/esm2022/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.mjs +89 -0
  177. package/esm2022/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.mjs +52 -0
  178. package/esm2022/lib/spatial-controls/spatial-controls.component.mjs +143 -1238
  179. package/esm2022/lib/spatial-controls/spatial-gene-picker.mjs +153 -0
  180. package/esm2022/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.mjs +241 -0
  181. package/esm2022/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.mjs +193 -0
  182. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.component.mjs +132 -0
  183. package/esm2022/lib/spatial-controls/spatial-key/spatial-key.model.mjs +67 -0
  184. package/esm2022/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.mjs +147 -0
  185. package/esm2022/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.mjs +300 -0
  186. package/esm2022/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.mjs +370 -0
  187. package/esm2022/lib/store/class-color.util.mjs +46 -3
  188. package/esm2022/lib/store/region-history.mjs +146 -0
  189. package/esm2022/lib/store/region-scope-cache.mjs +140 -0
  190. package/esm2022/lib/store/region-selection.mjs +82 -0
  191. package/esm2022/lib/store/region-store.service.mjs +279 -675
  192. package/esm2022/lib/store/spatial-selection.service.mjs +2 -2
  193. package/esm2022/lib/store/visualizer-store.service.mjs +49 -71
  194. package/esm2022/lib/toast-outlets.mjs +5 -4
  195. package/esm2022/lib/toolbar/brush/brush-tool.service.mjs +92 -434
  196. package/esm2022/lib/toolbar/canvas-tools.mjs +20 -0
  197. package/esm2022/lib/toolbar/crop/slide-crop.mjs +26 -42
  198. package/esm2022/lib/toolbar/plot-type-selector/plot-type-selector.component.mjs +85 -0
  199. package/esm2022/lib/toolbar/region-tools/region-tool-buttons.mjs +74 -0
  200. package/esm2022/lib/toolbar/region-tools/region-tools.component.mjs +114 -0
  201. package/esm2022/lib/toolbar/segmentation/cell-segment-tool.service.mjs +74 -78
  202. package/esm2022/lib/toolbar/segmentation/cellpose-segmenter.service.mjs +50 -8
  203. package/esm2022/lib/toolbar/segmentation/onnx-sam-session.mjs +61 -42
  204. package/esm2022/lib/toolbar/segmentation/pending-calls.mjs +47 -0
  205. package/esm2022/lib/toolbar/segmentation/sam-model-registry.mjs +12 -4
  206. package/esm2022/lib/toolbar/segmentation/sam-onnx-core.mjs +70 -14
  207. package/esm2022/lib/toolbar/segmentation/sam-point-tool.service.mjs +135 -172
  208. package/esm2022/lib/toolbar/segmentation/sam-prompt.mjs +9 -90
  209. package/esm2022/lib/toolbar/segmentation/sam-session.service.mjs +183 -0
  210. package/esm2022/lib/toolbar/segmentation/sam-tool.service.mjs +95 -150
  211. package/esm2022/lib/toolbar/segmentation/segmentation-commit.mjs +12 -0
  212. package/esm2022/lib/toolbar/segmentation/segmentation-runner.mjs +108 -0
  213. package/esm2022/lib/toolbar/segmentation-tools/segmentation-tools.component.mjs +155 -0
  214. package/esm2022/lib/toolbar/stack-controls/stack-controls.component.mjs +81 -0
  215. package/esm2022/lib/toolbar/tool-kit/async-tool-status.mjs +37 -0
  216. package/esm2022/lib/toolbar/tool-kit/canvas-tool-manager.mjs +63 -0
  217. package/esm2022/lib/toolbar/tool-kit/canvas-tool.mjs +2 -0
  218. package/esm2022/lib/toolbar/tool-kit/frame-pixels.mjs +108 -0
  219. package/esm2022/lib/toolbar/tool-kit/mask-stroke-editor.mjs +306 -0
  220. package/esm2022/lib/toolbar/tool-kit/matrix-frame.mjs +61 -0
  221. package/esm2022/lib/toolbar/tool-kit/tool-overlay.mjs +140 -0
  222. package/esm2022/lib/toolbar/tool-kit/undo-gesture.mjs +24 -0
  223. package/esm2022/lib/toolbar/tool-slider/tool-slider.component.mjs +63 -0
  224. package/esm2022/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.mjs +50 -0
  225. package/esm2022/lib/toolbar/toolbar.component.mjs +68 -117
  226. package/esm2022/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.mjs +93 -115
  227. package/esm2022/lib/toolbar/view-controls/view-controls.component.mjs +107 -0
  228. package/esm2022/lib/toolbar/wand/wand-region-grow.mjs +321 -0
  229. package/esm2022/lib/toolbar/wand/wand-tool.service.mjs +121 -416
  230. package/esm2022/lib/toolbar/wand/wand.service.mjs +30 -894
  231. package/esm2022/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.mjs +48 -90
  232. package/esm2022/lib/util/mark-for-check.mjs +17 -0
  233. package/esm2022/lib/util/supersede.mjs +56 -0
  234. package/esm2022/lib/visualization.module.mjs +39 -141
  235. package/esm2022/lib/visualizer/floating-drag.directive.mjs +58 -0
  236. package/esm2022/lib/visualizer/region-actions.mjs +149 -0
  237. package/esm2022/lib/visualizer/region-load.mjs +60 -0
  238. package/esm2022/lib/visualizer/spatial-dataset-binder.mjs +163 -0
  239. package/esm2022/lib/visualizer/tool-modes.mjs +113 -0
  240. package/esm2022/lib/visualizer/viewer-shortcuts.mjs +167 -0
  241. package/esm2022/lib/visualizer/visualizer-context-menu.mjs +119 -0
  242. package/esm2022/lib/visualizer.component.mjs +480 -1902
  243. package/esm2022/lib/workers/spatial-math-ops.mjs +43 -0
  244. package/esm2022/lib/workers/spatial-math-worker.mjs +10 -0
  245. package/esm2022/lib/workers/spatial-math.mjs +190 -0
  246. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs +41083 -0
  247. package/fesm2022/jax-data-science-sci-image-visualizer-jax-data-science-sci-image-visualizer-Csxlnq7I.mjs.map +1 -0
  248. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs +238 -0
  249. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-Bkujqg7m.mjs.map +1 -0
  250. package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs +12 -0
  251. package/fesm2022/jax-data-science-sci-image-visualizer-spatial-math-worker-BzVFFqGS.mjs.map +1 -0
  252. package/fesm2022/jax-data-science-sci-image-visualizer.mjs +41 -34467
  253. package/fesm2022/jax-data-science-sci-image-visualizer.mjs.map +1 -1
  254. package/fesm2022/mask.worker.js +36 -917
  255. package/fesm2022/onnx-sam.worker.js +52 -16
  256. package/fesm2022/spatial-math.worker.js +471 -0
  257. package/fesm2022/tsne.worker.js +32 -15
  258. package/index.d.ts +13 -10
  259. package/lib/channel-histogram/channel-histogram.component.d.ts +53 -43
  260. package/lib/contracts/capabilities.contract.d.ts +4 -2
  261. package/lib/contracts/cell-segmenter.contract.d.ts +1 -0
  262. package/lib/contracts/channel-histogram-api.contract.d.ts +4 -0
  263. package/lib/contracts/color.d.ts +27 -0
  264. package/lib/contracts/colormap-lut.d.ts +19 -4
  265. package/lib/contracts/coordinate-transform.contract.d.ts +3 -3
  266. package/lib/contracts/display-types.d.ts +21 -0
  267. package/lib/contracts/instance-segmenter.contract.d.ts +5 -0
  268. package/lib/contracts/intensity.d.ts +13 -2
  269. package/lib/contracts/plot-type.d.ts +3 -1
  270. package/lib/contracts/ports/image-state.port.d.ts +6 -2
  271. package/lib/contracts/ports/preferences.port.d.ts +4 -0
  272. package/lib/contracts/ports/region-io.port.d.ts +1 -0
  273. package/lib/contracts/ports/spatial-data.port.d.ts +4 -10
  274. package/lib/contracts/ports/tile-access.port.d.ts +1 -0
  275. package/lib/contracts/region-editor-api.contract.d.ts +1 -1
  276. package/lib/contracts/region-overlay.contract.d.ts +5 -0
  277. package/lib/contracts/sam.contract.d.ts +7 -0
  278. package/lib/contracts/semantic-segmenter.contract.d.ts +6 -0
  279. package/lib/contracts/spatial-dataset.contract.d.ts +19 -6
  280. package/lib/contracts/toolbar-tool.contract.d.ts +1 -0
  281. package/lib/contracts/visualizer.contract.d.ts +221 -54
  282. package/lib/contracts/viz-config.d.ts +1 -0
  283. package/lib/geometry/contour.d.ts +24 -0
  284. package/lib/geometry/raster.d.ts +42 -0
  285. package/lib/geometry/ring.d.ts +67 -0
  286. package/lib/hex-color-picker/hex-color-picker.component.d.ts +61 -27
  287. package/lib/implementations/base-store-visualizer.d.ts +61 -15
  288. package/lib/implementations/napari-js/napari-axes-gizmo.d.ts +36 -0
  289. package/lib/implementations/napari-js/napari-display-state.d.ts +76 -0
  290. package/lib/implementations/napari-js/napari-helpers.d.ts +129 -0
  291. package/lib/implementations/napari-js/napari-image-2d-scene.d.ts +162 -0
  292. package/lib/implementations/napari-js/napari-loading-badge.d.ts +0 -1
  293. package/lib/implementations/napari-js/napari-loading-state.d.ts +30 -0
  294. package/lib/implementations/napari-js/napari-region-overlay.d.ts +62 -70
  295. package/lib/implementations/napari-js/napari-scene.d.ts +93 -0
  296. package/lib/implementations/napari-js/napari-spatial-2d-scene.d.ts +163 -0
  297. package/lib/implementations/napari-js/napari-spatial-3d-scene.d.ts +212 -0
  298. package/lib/implementations/napari-js/napari-spatial-encoding.d.ts +114 -0
  299. package/lib/implementations/napari-js/napari-spatial-hover.d.ts +89 -0
  300. package/lib/implementations/napari-js/napari-spatial-scene.d.ts +118 -0
  301. package/lib/implementations/napari-js/napari-spatial-tiles.d.ts +56 -263
  302. package/lib/implementations/napari-js/napari-spatial-tooltip.d.ts +1 -1
  303. package/lib/implementations/napari-js/napari-surface-scene.d.ts +76 -0
  304. package/lib/implementations/napari-js/napari-tile-client.d.ts +214 -0
  305. package/lib/implementations/napari-js/napari-tool-bridge.d.ts +179 -0
  306. package/lib/implementations/napari-js/napari-visualizer.service.d.ts +121 -883
  307. package/lib/implementations/napari-js/napari-volume-scene.d.ts +104 -0
  308. package/lib/implementations/napari-js/napari-volume-z-handle.d.ts +8 -12
  309. package/lib/implementations/napari-js/region-overlay/overlay-projection.d.ts +59 -0
  310. package/lib/implementations/napari-js/region-overlay/region-edit.d.ts +15 -0
  311. package/lib/implementations/napari-js/region-overlay/region-svg-renderer.d.ts +54 -0
  312. package/lib/implementations/napari-js/spatial-tiles/categorical-lookup.d.ts +26 -0
  313. package/lib/implementations/napari-js/spatial-tiles/cell-layers.d.ts +70 -0
  314. package/lib/implementations/napari-js/spatial-tiles/density-layer.d.ts +61 -0
  315. package/lib/implementations/napari-js/spatial-tiles/layer-groups.d.ts +67 -0
  316. package/lib/implementations/napari-js/spatial-tiles/plan-context.d.ts +38 -0
  317. package/lib/implementations/napari-js/spatial-tiles/transcript-hover.d.ts +71 -0
  318. package/lib/implementations/napari-js/spatial-tiles/transcript-jobs.d.ts +105 -0
  319. package/lib/implementations/napari-js/spatial-tiles/transcript-layers.d.ts +56 -0
  320. package/lib/implementations/osd/display-pipeline.d.ts +38 -9
  321. package/lib/implementations/osd/histogram-sampler.d.ts +22 -12
  322. package/lib/implementations/osd/openseadragon-viewer-options.d.ts +35 -0
  323. package/lib/implementations/osd/openseadragon-visualizer.service.d.ts +78 -354
  324. package/lib/implementations/osd/osd-coordinate-transform.d.ts +2 -1
  325. package/lib/implementations/osd/osd-coords.d.ts +6 -4
  326. package/lib/implementations/osd/osd-export.d.ts +36 -0
  327. package/lib/implementations/osd/osd-lib.d.ts +7 -0
  328. package/lib/implementations/osd/osd-navigator-chrome.d.ts +69 -0
  329. package/lib/implementations/osd/osd-pixel-readback.d.ts +22 -0
  330. package/lib/implementations/osd/osd-region-overlay-draw.d.ts +37 -0
  331. package/lib/implementations/osd/osd-region-overlay.d.ts +36 -48
  332. package/lib/implementations/osd/osd-scale-bar.d.ts +8 -6
  333. package/lib/implementations/osd/osd-tile-source.d.ts +49 -0
  334. package/lib/implementations/osd/osd-viewer-like.d.ts +100 -0
  335. package/lib/implementations/osd/osd-viewer-mount.d.ts +14 -0
  336. package/lib/implementations/osd/osd-viewport.d.ts +77 -0
  337. package/lib/implementations/osd/osd-zoom.d.ts +6 -0
  338. package/lib/implementations/osd/simple-source.d.ts +161 -0
  339. package/lib/implementations/osd/slice-cache.d.ts +12 -3
  340. package/lib/implementations/osd/tile-client.d.ts +11 -14
  341. package/lib/implementations/osd/tile-recolor.d.ts +141 -0
  342. package/lib/implementations/plotly/omics-trace-builders.d.ts +32 -20
  343. package/lib/implementations/plotly/plotly-image-loader.d.ts +49 -0
  344. package/lib/implementations/plotly/plotly-image-recolor.d.ts +75 -0
  345. package/lib/implementations/plotly/plotly-intensity-inset.d.ts +8 -0
  346. package/lib/implementations/plotly/plotly-isosurface-controls.d.ts +38 -0
  347. package/lib/implementations/plotly/plotly-layouts.d.ts +188 -0
  348. package/lib/implementations/plotly/plotly-readback.d.ts +41 -0
  349. package/lib/implementations/plotly/plotly-region-overlay.d.ts +2 -2
  350. package/lib/implementations/plotly/plotly-shape-projection.d.ts +92 -0
  351. package/lib/implementations/plotly/plotly-trace-builders.d.ts +23 -12
  352. package/lib/implementations/plotly/plotly-zoom-controller.d.ts +86 -0
  353. package/lib/implementations/plotly/plotly.service.d.ts +136 -401
  354. package/lib/implementations/region-centroids.d.ts +14 -0
  355. package/lib/implementations/simple-slice-access.service.d.ts +7 -4
  356. package/lib/implementations/spatial-data-http/spatial-data-http.service.d.ts +42 -18
  357. package/lib/implementations/spatial-data-http/spatial-wire.d.ts +34 -9
  358. package/lib/implementations/tile-server/index.d.ts +5 -0
  359. package/lib/implementations/tile-server/native-histogram.d.ts +25 -0
  360. package/lib/implementations/tile-server/poll-descriptor.d.ts +39 -0
  361. package/lib/implementations/tile-server/tile-protocol.d.ts +80 -0
  362. package/lib/implementations/tile-server/transport.d.ts +62 -0
  363. package/lib/intensity/intensity-profile.d.ts +66 -0
  364. package/lib/intensity/intensity-profile.service.d.ts +108 -0
  365. package/lib/intensity-inset/intensity-inset.component.d.ts +58 -0
  366. package/lib/models/bezier.d.ts +0 -5
  367. package/lib/models/class-preset.d.ts +18 -0
  368. package/lib/models/geometry.d.ts +14 -48
  369. package/lib/models/polygon-edit.d.ts +72 -0
  370. package/lib/models/polygon-factory.d.ts +40 -0
  371. package/lib/models/region-clone.d.ts +20 -0
  372. package/lib/models/region-geojson.d.ts +17 -0
  373. package/lib/models/region.d.ts +40 -4
  374. package/lib/models/shape.d.ts +8 -0
  375. package/lib/plot-mode/contribution-host.d.ts +125 -0
  376. package/lib/plot-mode/plot-type-menu.d.ts +60 -0
  377. package/lib/plot-mode/tool-params-model.d.ts +49 -0
  378. package/lib/plot.utilities.d.ts +19 -30
  379. package/lib/processing/processing-image.d.ts +5 -2
  380. package/lib/provide-visualization.d.ts +19 -2
  381. package/lib/region-editor/classes-panel/classes-panel.component.d.ts +56 -0
  382. package/lib/region-editor/file-stem.d.ts +7 -0
  383. package/lib/region-editor/manage-classes-dialog/manage-classes-dialog.component.d.ts +45 -0
  384. package/lib/region-editor/mask-export.service.d.ts +54 -0
  385. package/lib/region-editor/mask-raster.d.ts +2 -8
  386. package/lib/region-editor/region-color-dialog/region-color-dialog.component.d.ts +29 -0
  387. package/lib/region-editor/region-editor-help/region-editor-help.component.d.ts +11 -0
  388. package/lib/region-editor/region-editor.component.d.ts +166 -199
  389. package/lib/region-editor/region-metrics.d.ts +26 -0
  390. package/lib/region-editor/region-persistence.service.d.ts +69 -0
  391. package/lib/region-editor/region-table/region-table.component.d.ts +83 -0
  392. package/lib/region-editor/save-mask-dialog/save-mask-dialog.component.d.ts +36 -0
  393. package/lib/region-editor/save-regions-dialog/save-regions-dialog.component.d.ts +37 -0
  394. package/lib/region-ops.service.d.ts +1 -7
  395. package/lib/region-overlay/region-geometry.d.ts +157 -0
  396. package/lib/region-overlay/region-hit-test.d.ts +38 -0
  397. package/lib/region-overlay/svg-region-renderer.d.ts +110 -0
  398. package/lib/render-orchestrator.d.ts +6 -2
  399. package/lib/render-session.d.ts +75 -0
  400. package/lib/routing-visualizer.service.d.ts +110 -58
  401. package/lib/spatial/density-raster.d.ts +6 -0
  402. package/lib/spatial/embedding-compute-coordinator.d.ts +123 -0
  403. package/lib/spatial/embedding-compute.d.ts +21 -2
  404. package/lib/spatial/glyphs.d.ts +16 -0
  405. package/lib/spatial/lod.d.ts +94 -0
  406. package/lib/spatial/spatial-controls.facade.d.ts +64 -0
  407. package/lib/spatial/spatial-density.d.ts +15 -5
  408. package/lib/spatial/spatial-encoding.d.ts +11 -44
  409. package/lib/spatial/spatial-expression.d.ts +40 -22
  410. package/lib/spatial/spatial-framing.d.ts +1 -0
  411. package/lib/spatial/spatial-heatmap.d.ts +2 -0
  412. package/lib/spatial/spatial-hover.d.ts +4 -16
  413. package/lib/spatial/spatial-panel-model.d.ts +135 -0
  414. package/lib/spatial/spatial-selection.d.ts +21 -26
  415. package/lib/spatial/spatial-tile-merge.d.ts +41 -0
  416. package/lib/spatial/spatial-tiles.d.ts +9 -256
  417. package/lib/spatial/stats.d.ts +38 -0
  418. package/lib/spatial/transcript-grouping.d.ts +119 -0
  419. package/lib/spatial-controls/spatial-cells-panel/spatial-cells-panel.component.d.ts +64 -0
  420. package/lib/spatial-controls/spatial-charts/chart-data-model.d.ts +153 -0
  421. package/lib/spatial-controls/spatial-charts/chart-help.d.ts +69 -0
  422. package/lib/spatial-controls/spatial-charts/plotly-chart-host.d.ts +98 -0
  423. package/lib/spatial-controls/spatial-charts/spatial-chart-window/spatial-chart-window.component.d.ts +26 -0
  424. package/lib/spatial-controls/spatial-charts/spatial-charts.component.d.ts +101 -260
  425. package/lib/spatial-controls/spatial-charts/spatial-embedding-controls/spatial-embedding-controls.component.d.ts +43 -0
  426. package/lib/spatial-controls/spatial-charts/spatial-heatmap-controls/spatial-heatmap-controls.component.d.ts +27 -0
  427. package/lib/spatial-controls/spatial-controls.component.d.ts +68 -448
  428. package/lib/spatial-controls/spatial-gene-picker.d.ts +86 -0
  429. package/lib/spatial-controls/spatial-gene-tree/spatial-gene-tree.component.d.ts +102 -0
  430. package/lib/spatial-controls/spatial-groups-panel/spatial-groups-panel.component.d.ts +72 -0
  431. package/lib/spatial-controls/spatial-key/spatial-key.component.d.ts +66 -0
  432. package/lib/spatial-controls/spatial-key/spatial-key.model.d.ts +33 -0
  433. package/lib/spatial-controls/spatial-marker-genes-form/spatial-marker-genes-form.component.d.ts +64 -0
  434. package/lib/spatial-controls/spatial-observations-panel/spatial-observations-panel.component.d.ts +117 -0
  435. package/lib/spatial-controls/spatial-transcripts-panel/spatial-transcripts-panel.component.d.ts +142 -0
  436. package/lib/store/class-color.util.d.ts +35 -1
  437. package/lib/store/region-history.d.ts +66 -0
  438. package/lib/store/region-scope-cache.d.ts +63 -0
  439. package/lib/store/region-selection.d.ts +36 -0
  440. package/lib/store/region-store.service.d.ts +104 -112
  441. package/lib/store/visualizer-store.service.d.ts +22 -33
  442. package/lib/toast-outlets.d.ts +4 -3
  443. package/lib/toolbar/brush/brush-tool.service.d.ts +31 -98
  444. package/lib/toolbar/canvas-tools.d.ts +20 -0
  445. package/lib/toolbar/crop/slide-crop.d.ts +10 -4
  446. package/lib/toolbar/plot-type-selector/plot-type-selector.component.d.ts +38 -0
  447. package/lib/toolbar/region-tools/region-tool-buttons.d.ts +21 -0
  448. package/lib/toolbar/region-tools/region-tools.component.d.ts +60 -0
  449. package/lib/toolbar/segmentation/cell-segment-tool.service.d.ts +10 -14
  450. package/lib/toolbar/segmentation/cellpose-segmenter.service.d.ts +12 -2
  451. package/lib/toolbar/segmentation/onnx-sam-session.d.ts +22 -3
  452. package/lib/toolbar/segmentation/pending-calls.d.ts +31 -0
  453. package/lib/toolbar/segmentation/sam-model-registry.d.ts +9 -3
  454. package/lib/toolbar/segmentation/sam-onnx-core.d.ts +18 -5
  455. package/lib/toolbar/segmentation/sam-point-tool.service.d.ts +46 -32
  456. package/lib/toolbar/segmentation/sam-prompt.d.ts +7 -31
  457. package/lib/toolbar/segmentation/sam-session.service.d.ts +74 -0
  458. package/lib/toolbar/segmentation/sam-tool.service.d.ts +23 -30
  459. package/lib/toolbar/segmentation/segmentation-commit.d.ts +8 -0
  460. package/lib/toolbar/segmentation/segmentation-runner.d.ts +52 -0
  461. package/lib/toolbar/segmentation-tools/segmentation-tools.component.d.ts +87 -0
  462. package/lib/toolbar/stack-controls/stack-controls.component.d.ts +40 -0
  463. package/lib/toolbar/tool-kit/async-tool-status.d.ts +21 -0
  464. package/lib/toolbar/tool-kit/canvas-tool-manager.d.ts +36 -0
  465. package/lib/toolbar/tool-kit/canvas-tool.d.ts +86 -0
  466. package/lib/toolbar/tool-kit/frame-pixels.d.ts +45 -0
  467. package/lib/toolbar/tool-kit/mask-stroke-editor.d.ts +125 -0
  468. package/lib/toolbar/tool-kit/matrix-frame.d.ts +40 -0
  469. package/lib/toolbar/tool-kit/tool-overlay.d.ts +60 -0
  470. package/lib/toolbar/tool-kit/undo-gesture.d.ts +17 -0
  471. package/lib/toolbar/tool-slider/tool-slider.component.d.ts +33 -0
  472. package/lib/toolbar/toolbar-help-dialog/toolbar-help-dialog.component.d.ts +24 -0
  473. package/lib/toolbar/toolbar.component.d.ts +47 -83
  474. package/lib/toolbar/vertex-eraser/vertex-eraser-tool.service.d.ts +33 -40
  475. package/lib/toolbar/view-controls/view-controls.component.d.ts +54 -0
  476. package/lib/toolbar/wand/wand-region-grow.d.ts +49 -0
  477. package/lib/toolbar/wand/wand-tool.service.d.ts +39 -124
  478. package/lib/toolbar/wand/wand.service.d.ts +22 -116
  479. package/lib/toolbar/zoom-to-box/zoom-to-box-tool.service.d.ts +17 -37
  480. package/lib/util/mark-for-check.d.ts +11 -0
  481. package/lib/util/supersede.d.ts +53 -0
  482. package/lib/visualization.module.d.ts +18 -39
  483. package/lib/visualizer/floating-drag.directive.d.ts +30 -0
  484. package/lib/visualizer/region-actions.d.ts +54 -0
  485. package/lib/visualizer/region-load.d.ts +27 -0
  486. package/lib/visualizer/spatial-dataset-binder.d.ts +74 -0
  487. package/lib/visualizer/tool-modes.d.ts +49 -0
  488. package/lib/visualizer/viewer-shortcuts.d.ts +71 -0
  489. package/lib/visualizer/visualizer-context-menu.d.ts +55 -0
  490. package/lib/visualizer.component.d.ts +201 -447
  491. package/lib/workers/spatial-math-ops.d.ts +65 -0
  492. package/lib/workers/spatial-math-worker.d.ts +7 -0
  493. package/lib/workers/spatial-math.d.ts +74 -0
  494. package/package.json +12 -3
  495. package/src/lib/styles/_viz-icons-rules.scss +73 -0
  496. package/src/lib/styles/viz-icons.scss +14 -0
  497. package/esm2022/lib/implementations/napari-js/napari-axes-labels.mjs +0 -97
  498. package/esm2022/lib/implementations/napari-js/napari-navigator.mjs +0 -195
  499. package/esm2022/lib/implementations/napari-js/napari-scale-bar.mjs +0 -92
  500. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs +0 -329
  501. package/fesm2022/jax-data-science-sci-image-visualizer-onnx-sam-session-BwP-A11m.mjs.map +0 -1
  502. package/lib/implementations/napari-js/napari-axes-labels.d.ts +0 -49
  503. package/lib/implementations/napari-js/napari-navigator.d.ts +0 -72
  504. package/lib/implementations/napari-js/napari-scale-bar.d.ts +0 -35
  505. package/src/lib/assets/cell-detection.svg +0 -37
  506. package/src/lib/assets/click.svg +0 -1
  507. package/src/lib/assets/colormap-luts.json +0 -1
  508. package/src/lib/assets/edit-selection-white.svg +0 -47
  509. package/src/lib/assets/icons/colormap-earth.png +0 -0
  510. package/src/lib/assets/icons/colormap-placeholder.png +0 -0
  511. package/src/lib/assets/icons/colormap-pubu.png +0 -0
  512. package/src/lib/assets/interactive-segmentation-cursor.svg +0 -1
  513. package/src/lib/assets/picture-segmentation.svg +0 -43
  514. package/src/lib/assets/test/download-379.svg +0 -1
  515. package/src/lib/assets/test/download-98.svg +0 -1
  516. package/src/lib/assets/test/json-1.svg +0 -1
  517. package/src/lib/assets/test/load-53.svg +0 -1
  518. package/src/lib/assets/test/mask-44.svg +0 -1
  519. package/src/lib/assets/test/mask-download-44.svg +0 -15
  520. package/src/lib/assets/test/mask-save-44.svg +0 -11
  521. package/src/lib/assets/test/overlay-1.svg +0 -1
  522. package/src/lib/assets/test/overlay-4.svg +0 -1
  523. package/src/lib/assets/test/region-26.svg +0 -1
  524. package/src/lib/assets/test/save-56.svg +0 -1
  525. package/src/lib/assets/test/upload-43.svg +0 -1
@@ -0,0 +1,439 @@
1
+ import { MultiChannelVolumeView, histogramScalar } from 'napari-js';
2
+ import { formatLength } from 'napari-js/overlays';
3
+ import { NapariVolumeZHandle } from './napari-volume-z-handle';
4
+ import { Axes3dGizmo, surface3dControls } from './napari-axes-gizmo';
5
+ import { SCATTER3D_MAX_POINTS, SCATTER3D_MAX_XY, VOLUME_WORLD_INPLANE_REF, isServerlessMultichannel, stackDepth, tintFor, toIHistogram, toNapariGamma, volumeResolutionFor, } from './napari-helpers';
6
+ /** The intensity histogram of an assembled uint8 channel (or the single grayscale volume, key 0). */
7
+ function channelHistogram(data, channel, bins) {
8
+ if (!data.size)
9
+ return null;
10
+ const plane = data.get(channel) ?? data.get(0);
11
+ return plane ? toIHistogram(histogramScalar(plane, bins, 0, 255)) : null;
12
+ }
13
+ /** Assemble `info`'s stack into a uint8 volume under the stack progress bar; null once `loading`
14
+ * aborts (a Cancel or a new plot). The caller owns the loading flag and takes `loading` once per
15
+ * load: a Cancel replaces `ctx.loading()`, and a multichannel volume assembles channels in turn. */
16
+ function assemble(ctx, info, opts, loading, channel) {
17
+ return ctx.tiles.assembleVolume(info, opts, channel, {
18
+ signal: loading,
19
+ progress: (p) => ctx.stack.progress(p),
20
+ });
21
+ }
22
+ /**
23
+ * NAPARI_VOLUME / NAPARI_ISOSURFACE (review Appendix B, cluster F): the stack assembled into a
24
+ * decimated volume — one additive, tinted `VolumeLayer` per channel for a multichannel image, a
25
+ * single grayscale volume otherwise — with the axes gizmo and the in-view Z-height handle.
26
+ */
27
+ export class VolumeScene {
28
+ constructor(ctx, info, rendering) {
29
+ this.ctx = ctx;
30
+ this.info = info;
31
+ this.rendering = rendering;
32
+ /** napari-js high-level view owning the volume layers. */
33
+ this.view = null;
34
+ /** True when the volume is composited from per-channel layers (vs a single grayscale volume). */
35
+ this.multichannel = false;
36
+ /** Volume world box at Z-scale 1 (base) + the sampled voxel depth — enough to recompute the
37
+ * Z-axis voxel scale, axes depth, and overlay anchors as the handle stretches Z. */
38
+ this.worldBase = null;
39
+ this.sampledDepth = 1;
40
+ this.dims = null;
41
+ /** Assembled uint8 volume data per channel (key = channel index), kept for the volume intensity
42
+ * histogram. Key 0 holds the grayscale/composite volume in the single-channel case. */
43
+ this.channelData = new Map();
44
+ this.gizmo = null;
45
+ this.zHandle = null;
46
+ this.displaySub = null;
47
+ }
48
+ /**
49
+ * Assemble and render the volume, then add the axes gizmo + labels and the Z handle and follow
50
+ * the display state.
51
+ */
52
+ async mount() {
53
+ const { ctx, info } = this;
54
+ const loading = ctx.loading(); // bail before rendering on a Cancel / new plot
55
+ const desc = await ctx.tiles.ensureDescriptor(ctx.info());
56
+ // Serverless multichannel (tiled:false + channelUrls): no tile descriptor, so
57
+ // derive the channel count from imageMeta and assemble each band from its own
58
+ // channelUrls[z][c] plane (fetchImage does the per-channel routing).
59
+ const simpleMc = isServerlessMultichannel(ctx.tiles.isSimple(info), info);
60
+ const channelCount = simpleMc ? info.imageMeta[0].channelCount : (desc?.channels ?? 1);
61
+ const multichannel = simpleMc || (!!desc?.multichannel && channelCount > 1);
62
+ this.channelData.clear();
63
+ this.multichannel = multichannel;
64
+ const view = new MultiChannelVolumeView(ctx.viewer);
65
+ this.view = view;
66
+ const { dims, channels } = await this.assembleChannels(desc, channelCount, loading);
67
+ if (!dims || !channels.length || loading.aborted)
68
+ return; // cancelled → don't render
69
+ const world = this.worldBox(dims);
70
+ // Base box (Z-scale = 1) + the sampled depth drive the live Z-height handle below; the persisted
71
+ // `volumeZScale` (user drag) applies on top so changing resolution keeps the chosen height.
72
+ this.worldBase = world;
73
+ this.sampledDepth = Math.max(1, dims.depth);
74
+ const worldZ = world.depth * ctx.settings.volumeZScale;
75
+ const voxelSize = [
76
+ world.width / dims.width,
77
+ world.height / dims.height,
78
+ worldZ / this.sampledDepth,
79
+ ];
80
+ for (const ch of channels)
81
+ ch.voxelSize = voxelSize;
82
+ view.render(this.multichannel ? 'multichannel' : 'grayscale', channels, { rendering: this.rendering });
83
+ ctx.setImageSize(dims.width, dims.height);
84
+ this.dims = dims;
85
+ // 3D coordinate-axes / scale gizmo + labels, sharing the volume's world box so the gizmo tracks
86
+ // the rendered proportions. Physical scale text still comes from the FULL image extent.
87
+ const box = { width: world.width, height: world.height, depth: worldZ };
88
+ this.gizmo = new Axes3dGizmo(ctx.viewer, ctx.host, box, this.axesLabels(box), {
89
+ visible: ctx.settings.axesVisible,
90
+ });
91
+ // In-view drag handle at the TOP END OF THE Z AXIS (the box's min-XY corner, where the blue
92
+ // "Z" axis + label live), so it reads as the Z-height control. Floated a little past the axis
93
+ // tip (×1.12) so the grip clears the "Z · …" label. Drag ↕ to restretch Z live.
94
+ this.zHandle = new NapariVolumeZHandle(ctx.host, ctx.viewer.camera3d, {
95
+ topAnchor: () => [
96
+ -this.worldBase.width / 2,
97
+ -this.worldBase.height / 2,
98
+ ((this.worldBase.depth * ctx.settings.volumeZScale) / 2) * 1.12,
99
+ ],
100
+ getScale: () => ctx.settings.volumeZScale,
101
+ setScale: (s) => this.setZScale(s),
102
+ });
103
+ this.followDisplayState();
104
+ }
105
+ /**
106
+ * Assemble each channel's volume from the server tiles (or the single grayscale volume) under
107
+ * the stack progress bar, with the display settings it is drawn with. `dims` is null when
108
+ * nothing was assembled (a Cancel, a new plot, or no slices).
109
+ */
110
+ async assembleChannels(desc, channelCount, loading) {
111
+ const { ctx, info } = this;
112
+ const res = volumeResolutionFor(ctx.settings.resolutionScale);
113
+ const states = ctx.store.currentChannelStates();
114
+ // Assemble per-channel scalar volumes from the server tiles (jit-specific); the napari-js view
115
+ // owns the layer orchestration (one additive tinted volume per channel, or a single grayscale
116
+ // volume). The adapter computes each channel's colormap (incl. the reverse flip) and invert.
117
+ let dims = null;
118
+ const channels = [];
119
+ ctx.stack.loading(true);
120
+ ctx.stack.progress(0);
121
+ try {
122
+ if (this.multichannel) {
123
+ for (let c = 0; c < channelCount; c++) {
124
+ const vol = await assemble(ctx, info, res, loading, c);
125
+ if (loading.aborted)
126
+ break; // a Cancel / new plot: fetch no further channel
127
+ if (!vol)
128
+ continue;
129
+ dims = vol;
130
+ this.channelData.set(c, vol.data);
131
+ const st = states.find((s) => s.index === c);
132
+ const color = st?.color ?? desc?.channelInfo?.[c]?.color ?? tintFor(c);
133
+ channels.push({
134
+ data: vol.data,
135
+ width: vol.width,
136
+ height: vol.height,
137
+ depth: vol.depth,
138
+ colormap: ctx.display.channelTintColormap(color),
139
+ contrastLimits: [st?.min ?? 0, st?.max ?? 255],
140
+ gamma: toNapariGamma(st?.gamma), // ImageJ γ → napari-js γ
141
+ invert: ctx.display.invert,
142
+ visible: st?.visible ?? true,
143
+ });
144
+ }
145
+ }
146
+ else {
147
+ const vol = await assemble(ctx, info, res, loading);
148
+ if (vol) {
149
+ dims = vol;
150
+ this.channelData.set(0, vol.data);
151
+ const st = states[0];
152
+ channels.push({
153
+ data: vol.data,
154
+ width: vol.width,
155
+ height: vol.height,
156
+ depth: vol.depth,
157
+ colormap: ctx.display.volumeColormap(st),
158
+ contrastLimits: [st?.min ?? 0, st?.max ?? 255],
159
+ gamma: toNapariGamma(st?.gamma), // ImageJ γ → napari-js γ
160
+ invert: ctx.display.invert,
161
+ });
162
+ }
163
+ }
164
+ }
165
+ finally {
166
+ ctx.stack.loading(false);
167
+ ctx.stack.progress(0);
168
+ }
169
+ return { dims, channels };
170
+ }
171
+ /** The volume's world box for the assembled `dims`, independent of the decimate factor. */
172
+ worldBox(dims) {
173
+ const { ctx } = this;
174
+ // Resolution-invariant world box; the per-axis `voxelSize` (napari `scale`) maps the sampled
175
+ // grid onto it.
176
+ //
177
+ // A stack that declares its physical spacing on ALL THREE axes gets its true
178
+ // extent as the world box — the only way anisotropy survives, and what makes a
179
+ // resampled 40 x 40 x 200 µm volume read as a brain instead of a cube-aspect
180
+ // brick. It needs none of the reference-box arithmetic: a physical box is
181
+ // already independent of the decimate factor.
182
+ //
183
+ // Everything else keeps that arithmetic. Sizing the box by the sampled voxel
184
+ // counts made higher in-plane resolution grow X/Y while the depth stayed the
185
+ // (constant) slice count — so Z appeared to shrink at higher resolution.
186
+ // Anchoring the in-plane long side to a fixed reference and letting Z span the
187
+ // full slice count makes the box shape identical at every decimate factor.
188
+ const meta = ctx.info()?.imageMeta?.[0];
189
+ const mppXYZ = meta?.mppX && meta?.mppY && meta?.mppZ ? [meta.mppX, meta.mppY, meta.mppZ] : null;
190
+ // The image's DECLARED pixel dimensions, which is what mpp is per: the sampled
191
+ // dims are decimated, so sizing a physical box by them would make the world
192
+ // box depend on the resolution the user happens to be viewing at.
193
+ const imageDesc = ctx.tiles.currentDescriptor(ctx.info());
194
+ const fullW = imageDesc?.width ?? meta?.x ?? dims.width;
195
+ const fullH = imageDesc?.height ?? meta?.y ?? dims.height;
196
+ const fullD = stackDepth(ctx.info()) || dims.depth;
197
+ if (mppXYZ) {
198
+ return {
199
+ width: fullW * mppXYZ[0],
200
+ height: fullH * mppXYZ[1],
201
+ depth: fullD * mppXYZ[2],
202
+ };
203
+ }
204
+ const fullLong = Math.max(1, fullW, fullH);
205
+ return {
206
+ width: (fullW * VOLUME_WORLD_INPLANE_REF) / fullLong,
207
+ height: (fullH * VOLUME_WORLD_INPLANE_REF) / fullLong,
208
+ depth: fullD,
209
+ };
210
+ }
211
+ /**
212
+ * The whole stack is already on screen: no plane to step. (This used to write `viewer.dims.z`,
213
+ * which only a tiled 2D image reads — a volume raymarches every slice — and schedule a readback
214
+ * of a frame that had not changed. The toolbar shows no slice control in volume / isosurface
215
+ * mode, as Plotly's isosurface ignores the slice too.)
216
+ */
217
+ setZ() {
218
+ /* nothing to step */
219
+ }
220
+ /** The intensity histogram of the assembled (downsampled) uint8 volume for the requested
221
+ * channel (multichannel) or the single grayscale volume. */
222
+ histogram(channel, bins) {
223
+ return channelHistogram(this.channelData, channel, bins);
224
+ }
225
+ isoControls() {
226
+ if (!this.view)
227
+ return null;
228
+ return {
229
+ setIsoRange: (isoMin, isoMax) => {
230
+ // Apply to every channel's volume layer.
231
+ for (const layer of this.view?.layers ?? []) {
232
+ layer.contrastLimits = [isoMin, isoMax];
233
+ layer.rendering = 'iso';
234
+ layer.isoThreshold = 0.5;
235
+ }
236
+ this.ctx.viewer.requestRender();
237
+ },
238
+ };
239
+ }
240
+ surface3dControls() {
241
+ return this.view ? surface3dControls(this.ctx, () => this.gizmo) : null;
242
+ }
243
+ dispose() {
244
+ this.displaySub?.unsubscribe();
245
+ this.displaySub = null;
246
+ this.gizmo?.destroy();
247
+ this.gizmo = null;
248
+ this.zHandle?.destroy();
249
+ this.zHandle = null;
250
+ this.worldBase = null;
251
+ }
252
+ /**
253
+ * Restretch the volume's Z height live (driven by the in-view {@link NapariVolumeZHandle}). Only
254
+ * the per-axis `voxelSize` / axes depth change — the voxel textures are untouched — so dragging is
255
+ * smooth. `factor` is relative to the volume's natural proportions (1). Persists across re-mounts
256
+ * (resolution changes) so the chosen height sticks.
257
+ */
258
+ setZScale(factor) {
259
+ const { settings } = this.ctx;
260
+ settings.volumeZScale = Math.min(10, Math.max(0.1, factor));
261
+ const base = this.worldBase;
262
+ if (!base || !this.view)
263
+ return;
264
+ const worldZ = base.depth * settings.volumeZScale;
265
+ const vsZ = worldZ / this.sampledDepth;
266
+ for (const layer of this.view.layers) {
267
+ const [sx, sy] = layer.voxelSize;
268
+ layer.voxelSize = [sx, sy, vsZ];
269
+ }
270
+ this.gizmo?.setDepth(worldZ, this.axesLabels({ width: base.width, height: base.height, depth: worldZ }));
271
+ this.zHandle?.reposition();
272
+ this.ctx.viewer.requestRender();
273
+ }
274
+ /** The X/Y/Z axis-end label specs for the gizmo. Anchors are in the volume's centred world box
275
+ * (matching the AxesLayer geometry); the scale text reflects the FULL image extent — physical µm
276
+ * when µm/pixel is known, else pixel (X/Y) / slice (Z) counts. */
277
+ axesLabels(vol) {
278
+ const hx = vol.width / 2;
279
+ const hy = vol.height / 2;
280
+ const hz = vol.depth / 2;
281
+ // Measured from the IMAGE's own extent, never from the world box: the box is a
282
+ // shape (and for a physically sized volume it is already in µm, so reading a
283
+ // pixel count off it and multiplying by mpp would scale the label twice).
284
+ const { px, mpp } = this.imageExtent();
285
+ const len = (n, um) => (um > 0 ? formatLength(n * um, 'µm') : `${n} px`);
286
+ return [
287
+ { anchor: [hx, -hy, -hz], text: `X · ${len(px[0], mpp[0])}`, color: '#ed4545' },
288
+ { anchor: [-hx, hy, -hz], text: `Y · ${len(px[1], mpp[1])}`, color: '#4dd959' },
289
+ // Physical when the stack declares its slice spacing (`mppZ`) — a resampled
290
+ // volume knows how thick it is; a plain z-stack can only say how many slices.
291
+ { anchor: [-hx, -hy, hz], text: `Z · ${len(px[2], mpp[2])}`, color: '#668cff' },
292
+ ];
293
+ }
294
+ /**
295
+ * The image's declared extent in pixels/slices, and its physical spacing per
296
+ * axis in µm (0 = undeclared, and then that axis reads in pixels).
297
+ *
298
+ * One place, because the volume world box and the axis labels have to agree
299
+ * about what the image's real dimensions are — the sampled grid is decimated and
300
+ * says nothing about either.
301
+ */
302
+ imageExtent() {
303
+ const info = this.ctx.info();
304
+ const meta = info?.imageMeta?.[0];
305
+ const dims = this.dims;
306
+ const desc = this.ctx.tiles.currentDescriptor(info);
307
+ const mppX = desc?.mppX || meta?.mppX || 0;
308
+ return {
309
+ px: [
310
+ desc?.width ?? meta?.x ?? dims?.width ?? 1,
311
+ desc?.height ?? meta?.y ?? dims?.height ?? 1,
312
+ stackDepth(info) || dims?.depth || 1,
313
+ ],
314
+ // A descriptor that reports only mppX is square-pixel by convention, which is
315
+ // what the 2D scale bar already assumes of it.
316
+ mpp: [mppX, desc?.mppY || meta?.mppY || mppX, meta?.mppZ || 0],
317
+ };
318
+ }
319
+ /** The store's colormap, reverse, invert and channel windows → the volume's transfer function:
320
+ * colour (channel tint or selected colormap), the intensity window (min/max → contrastLimits)
321
+ * and gamma, mirroring the grayscale image's display controls so the histogram pane drives the
322
+ * 3D render. */
323
+ followDisplayState() {
324
+ const { display } = this.ctx;
325
+ this.displaySub = display.watch((channels) => {
326
+ const view = this.view;
327
+ if (!view)
328
+ return;
329
+ if (this.multichannel) {
330
+ // Each channel's layer is tinted by its colour and gets its own window/gamma/visibility.
331
+ view.layers.forEach((_, c) => {
332
+ const st = channels.find((s) => s.index === c);
333
+ view.updateChannel(c, {
334
+ colormap: display.channelTintColormap(st?.color ?? '#ffffff'),
335
+ invert: display.invert,
336
+ ...(st
337
+ ? {
338
+ contrastLimits: [st.min, st.max],
339
+ gamma: toNapariGamma(st.gamma), // ImageJ γ → napari-js γ
340
+ visible: st.visible,
341
+ }
342
+ : {}),
343
+ });
344
+ });
345
+ }
346
+ else {
347
+ const st = channels[0];
348
+ view.updateChannel(0, {
349
+ colormap: display.volumeColormap(st),
350
+ invert: display.invert,
351
+ ...(st ? { contrastLimits: [st.min, st.max], gamma: toNapariGamma(st.gamma) } : {}),
352
+ });
353
+ }
354
+ });
355
+ }
356
+ }
357
+ /**
358
+ * NAPARI_SCATTER3D (review Appendix B, cluster H): the downsampled voxel grid as a 3D point cloud
359
+ * coloured by intensity (the napari-js analog of Plotly's voxel scatter3d). Assembles a coarse
360
+ * volume, then emits a flat-strided sample of voxels (capped at `SCATTER3D_MAX_POINTS`).
361
+ */
362
+ export class Scatter3dScene {
363
+ constructor(ctx, info) {
364
+ this.ctx = ctx;
365
+ this.info = info;
366
+ this.layer = null;
367
+ /** The assembled volume (key 0), for the intensity histogram. */
368
+ this.channelData = new Map();
369
+ this.displaySub = null;
370
+ }
371
+ async mount() {
372
+ const { ctx } = this;
373
+ const res = volumeResolutionFor(ctx.settings.resolutionScale);
374
+ ctx.stack.loading(true);
375
+ ctx.stack.progress(0);
376
+ let vol = null;
377
+ try {
378
+ vol = await assemble(ctx, this.info, { maxSlice: Math.min(res.maxSlice, SCATTER3D_MAX_XY), sliceStep: res.sliceStep }, ctx.loading());
379
+ }
380
+ finally {
381
+ ctx.stack.loading(false);
382
+ ctx.stack.progress(0);
383
+ }
384
+ if (!vol || ctx.signal.aborted)
385
+ return;
386
+ const { data, width, height, depth } = vol;
387
+ const zScale = Math.max(width, height) / Math.max(1, depth); // ≈ cubic aspect
388
+ const total = width * height * depth;
389
+ const stride = Math.max(1, Math.ceil(total / SCATTER3D_MAX_POINTS));
390
+ const pos = [];
391
+ const val = [];
392
+ for (let i = 0; i < total; i += stride) {
393
+ const x = i % width;
394
+ const y = Math.floor(i / width) % height;
395
+ const zi = Math.floor(i / (width * height));
396
+ pos.push(x, y, zi * zScale);
397
+ val.push(data[i]);
398
+ }
399
+ const st = ctx.store.currentChannelStates()[0];
400
+ this.layer = ctx.viewer.addPoints3D(new Float32Array(pos), new Float32Array(val), {
401
+ colormap: ctx.display.volumeColormap(st),
402
+ contrastLimits: [st?.min ?? 0, st?.max ?? 255],
403
+ invert: ctx.display.invert,
404
+ size: 3,
405
+ });
406
+ ctx.setImageSize(width, height);
407
+ // Feed the intensity histogram from the assembled volume (key 0).
408
+ this.channelData.clear();
409
+ this.channelData.set(0, data);
410
+ // Store colormap / reverse / invert / channel window → the cloud's colormap + contrast.
411
+ this.displaySub = ctx.display.watch((channels) => {
412
+ const layer = this.layer;
413
+ if (!layer)
414
+ return;
415
+ const s = channels[0];
416
+ layer.colormap = ctx.display.volumeColormap(s);
417
+ layer.invert = ctx.display.invert;
418
+ if (s)
419
+ layer.contrastLimits = [s.min, s.max];
420
+ ctx.viewer.requestRender();
421
+ });
422
+ ctx.tools.scheduleReadback();
423
+ }
424
+ /** The whole stack is already on screen: no plane to step. */
425
+ setZ() {
426
+ /* nothing to step */
427
+ }
428
+ histogram(channel, bins) {
429
+ return channelHistogram(this.channelData, channel, bins);
430
+ }
431
+ surface3dControls() {
432
+ return this.layer ? surface3dControls(this.ctx, () => null) : null;
433
+ }
434
+ dispose() {
435
+ this.displaySub?.unsubscribe();
436
+ this.displaySub = null;
437
+ }
438
+ }
439
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXZvbHVtZS1zY2VuZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvaW1wbGVtZW50YXRpb25zL25hcGFyaS1qcy9uYXBhcmktdm9sdW1lLXNjZW5lLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUNBLE9BQU8sRUFBRSxzQkFBc0IsRUFBRSxlQUFlLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFFcEUsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLG9CQUFvQixDQUFDO0FBTWxELE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxNQUFNLDBCQUEwQixDQUFDO0FBRy9ELE9BQU8sRUFBRSxXQUFXLEVBQVEsaUJBQWlCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUMzRSxPQUFPLEVBQ0wsb0JBQW9CLEVBQ3BCLGdCQUFnQixFQUNoQix3QkFBd0IsRUFDeEIsd0JBQXdCLEVBQ3hCLFVBQVUsRUFDVixPQUFPLEVBQ1AsWUFBWSxFQUNaLGFBQWEsRUFDYixtQkFBbUIsR0FDcEIsTUFBTSxrQkFBa0IsQ0FBQztBQUcxQixxR0FBcUc7QUFDckcsU0FBUyxnQkFBZ0IsQ0FBQyxJQUE2QixFQUFFLE9BQWUsRUFBRSxJQUFZO0lBQ3BGLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSTtRQUFFLE9BQU8sSUFBSSxDQUFDO0lBQzVCLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUMvQyxPQUFPLEtBQUssQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLGVBQWUsQ0FBQyxLQUFLLEVBQUUsSUFBSSxFQUFFLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7QUFDM0UsQ0FBQztBQUVEOztxR0FFcUc7QUFDckcsU0FBUyxRQUFRLENBQ2YsR0FBaUIsRUFDakIsSUFBNEIsRUFDNUIsSUFBK0MsRUFDL0MsT0FBb0IsRUFDcEIsT0FBZ0I7SUFFaEIsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRTtRQUNuRCxNQUFNLEVBQUUsT0FBTztRQUNmLFFBQVEsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDO0tBQ3ZDLENBQUMsQ0FBQztBQUNMLENBQUM7QUFFRDs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLFdBQVc7SUFpQnRCLFlBQ21CLEdBQWlCLEVBQ2pCLElBQTRCLEVBQzVCLFNBQXdCO1FBRnhCLFFBQUcsR0FBSCxHQUFHLENBQWM7UUFDakIsU0FBSSxHQUFKLElBQUksQ0FBd0I7UUFDNUIsY0FBUyxHQUFULFNBQVMsQ0FBZTtRQW5CM0MsMERBQTBEO1FBQzFELFNBQUksR0FBa0MsSUFBSSxDQUFDO1FBQzNDLGlHQUFpRztRQUN6RixpQkFBWSxHQUFHLEtBQUssQ0FBQztRQUM3Qjs2RkFDcUY7UUFDN0UsY0FBUyxHQUFnQixJQUFJLENBQUM7UUFDOUIsaUJBQVksR0FBRyxDQUFDLENBQUM7UUFDakIsU0FBSSxHQUFnQixJQUFJLENBQUM7UUFDakM7Z0dBQ3dGO1FBQ3ZFLGdCQUFXLEdBQUcsSUFBSSxHQUFHLEVBQXNCLENBQUM7UUFDN0QsVUFBSyxHQUF1QixJQUFJLENBQUM7UUFDekIsWUFBTyxHQUErQixJQUFJLENBQUM7UUFDM0MsZUFBVSxHQUF3QixJQUFJLENBQUM7SUFNNUMsQ0FBQztJQUVKOzs7T0FHRztJQUNILEtBQUssQ0FBQyxLQUFLO1FBQ1QsTUFBTSxFQUFFLEdBQUcsRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDM0IsTUFBTSxPQUFPLEdBQUcsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsK0NBQStDO1FBQzlFLE1BQU0sSUFBSSxHQUFHLE1BQU0sR0FBRyxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQztRQUMxRCw4RUFBOEU7UUFDOUUsOEVBQThFO1FBQzlFLHFFQUFxRTtRQUNyRSxNQUFNLFFBQVEsR0FBRyx3QkFBd0IsQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUMxRSxNQUFNLFlBQVksR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLElBQUssQ0FBQyxTQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxRQUFRLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDekYsTUFBTSxZQUFZLEdBQUcsUUFBUSxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxZQUFZLElBQUksWUFBWSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBRTVFLElBQUksQ0FBQyxXQUFXLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDekIsSUFBSSxDQUFDLFlBQVksR0FBRyxZQUFZLENBQUM7UUFDakMsTUFBTSxJQUFJLEdBQUcsSUFBSSxzQkFBc0IsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDcEQsSUFBSSxDQUFDLElBQUksR0FBRyxJQUFJLENBQUM7UUFDakIsTUFBTSxFQUFFLElBQUksRUFBRSxRQUFRLEVBQUUsR0FBRyxNQUFNLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUUsWUFBWSxFQUFFLE9BQU8sQ0FBQyxDQUFDO1FBQ3BGLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxJQUFJLE9BQU8sQ0FBQyxPQUFPO1lBQUUsT0FBTyxDQUFDLDJCQUEyQjtRQUVyRixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xDLGlHQUFpRztRQUNqRyw0RkFBNEY7UUFDNUYsSUFBSSxDQUFDLFNBQVMsR0FBRyxLQUFLLENBQUM7UUFDdkIsSUFBSSxDQUFDLFlBQVksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDNUMsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLEtBQUssR0FBRyxHQUFHLENBQUMsUUFBUSxDQUFDLFlBQVksQ0FBQztRQUN2RCxNQUFNLFNBQVMsR0FBNkI7WUFDMUMsS0FBSyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsS0FBSztZQUN4QixLQUFLLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQyxNQUFNO1lBQzFCLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBWTtTQUMzQixDQUFDO1FBQ0YsS0FBSyxNQUFNLEVBQUUsSUFBSSxRQUFRO1lBQUUsRUFBRSxDQUFDLFNBQVMsR0FBRyxTQUFTLENBQUM7UUFFcEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxRQUFRLEVBQUUsRUFBRSxTQUFTLEVBQUUsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDdkcsR0FBRyxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztRQUVqQixnR0FBZ0c7UUFDaEcsd0ZBQXdGO1FBQ3hGLE1BQU0sR0FBRyxHQUFHLEVBQUUsS0FBSyxFQUFFLEtBQUssQ0FBQyxLQUFLLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxNQUFNLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxDQUFDO1FBQ3hFLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxXQUFXLENBQUMsR0FBRyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsSUFBSSxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQzVFLE9BQU8sRUFBRSxHQUFHLENBQUMsUUFBUSxDQUFDLFdBQVc7U0FDbEMsQ0FBQyxDQUFDO1FBQ0gsNEZBQTRGO1FBQzVGLDhGQUE4RjtRQUM5RixnRkFBZ0Y7UUFDaEYsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLEVBQUU7WUFDcEUsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDO2dCQUNmLENBQUMsSUFBSSxDQUFDLFNBQVUsQ0FBQyxLQUFLLEdBQUcsQ0FBQztnQkFDMUIsQ0FBQyxJQUFJLENBQUMsU0FBVSxDQUFDLE1BQU0sR0FBRyxDQUFDO2dCQUMzQixDQUFDLENBQUMsSUFBSSxDQUFDLFNBQVUsQ0FBQyxLQUFLLEdBQUcsR0FBRyxDQUFDLFFBQVEsQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxJQUFJO2FBQ2pFO1lBQ0QsUUFBUSxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxRQUFRLENBQUMsWUFBWTtZQUN6QyxRQUFRLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDO1NBQ25DLENBQUMsQ0FBQztRQUNILElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQzVCLENBQUM7SUFFRDs7OztPQUlHO0lBQ0ssS0FBSyxDQUFDLGdCQUFnQixDQUM1QixJQUEyQixFQUMzQixZQUFvQixFQUNwQixPQUFvQjtRQUVwQixNQUFNLEVBQUUsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLElBQUksQ0FBQztRQUMzQixNQUFNLEdBQUcsR0FBRyxtQkFBbUIsQ0FBQyxHQUFHLENBQUMsUUFBUSxDQUFDLGVBQWUsQ0FBQyxDQUFDO1FBQzlELE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUUsQ0FBQztRQUVoRCwrRkFBK0Y7UUFDL0YsOEZBQThGO1FBQzlGLDZGQUE2RjtRQUM3RixJQUFJLElBQUksR0FBZ0IsSUFBSSxDQUFDO1FBQzdCLE1BQU0sUUFBUSxHQUFvQixFQUFFLENBQUM7UUFDckMsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDeEIsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEIsSUFBSSxDQUFDO1lBQ0gsSUFBSSxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7Z0JBQ3RCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxZQUFZLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztvQkFDdEMsTUFBTSxHQUFHLEdBQUcsTUFBTSxRQUFRLENBQUMsR0FBRyxFQUFFLElBQUksRUFBRSxHQUFHLEVBQUUsT0FBTyxFQUFFLENBQUMsQ0FBQyxDQUFDO29CQUN2RCxJQUFJLE9BQU8sQ0FBQyxPQUFPO3dCQUFFLE1BQU0sQ0FBQyxnREFBZ0Q7b0JBQzVFLElBQUksQ0FBQyxHQUFHO3dCQUFFLFNBQVM7b0JBQ25CLElBQUksR0FBRyxHQUFHLENBQUM7b0JBQ1gsSUFBSSxDQUFDLFdBQVcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQztvQkFDbEMsTUFBTSxFQUFFLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQztvQkFDN0MsTUFBTSxLQUFLLEdBQUcsRUFBRSxFQUFFLEtBQUssSUFBSSxJQUFJLEVBQUUsV0FBVyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsS0FBSyxJQUFJLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDdkUsUUFBUSxDQUFDLElBQUksQ0FBQzt3QkFDWixJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUk7d0JBQ2QsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLO3dCQUNoQixNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU07d0JBQ2xCLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSzt3QkFDaEIsUUFBUSxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsbUJBQW1CLENBQUMsS0FBSyxDQUFDO3dCQUNoRCxjQUFjLEVBQUUsQ0FBQyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsRUFBRSxFQUFFLEVBQUUsR0FBRyxJQUFJLEdBQUcsQ0FBQzt3QkFDOUMsS0FBSyxFQUFFLGFBQWEsQ0FBQyxFQUFFLEVBQUUsS0FBSyxDQUFDLEVBQUUseUJBQXlCO3dCQUMxRCxNQUFNLEVBQUUsR0FBRyxDQUFDLE9BQU8sQ0FBQyxNQUFNO3dCQUMxQixPQUFPLEVBQUUsRUFBRSxFQUFFLE9BQU8sSUFBSSxJQUFJO3FCQUM3QixDQUFDLENBQUM7Z0JBQ0wsQ0FBQztZQUNILENBQUM7aUJBQU0sQ0FBQztnQkFDTixNQUFNLEdBQUcsR0FBRyxNQUFNLFFBQVEsQ0FBQyxHQUFHLEVBQUUsSUFBSSxFQUFFLEdBQUcsRUFBRSxPQUFPLENBQUMsQ0FBQztnQkFDcEQsSUFBSSxHQUFHLEVBQUUsQ0FBQztvQkFDUixJQUFJLEdBQUcsR0FBRyxDQUFDO29CQUNYLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUM7b0JBQ2xDLE1BQU0sRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztvQkFDckIsUUFBUSxDQUFDLElBQUksQ0FBQzt3QkFDWixJQUFJLEVBQUUsR0FBRyxDQUFDLElBQUk7d0JBQ2QsS0FBSyxFQUFFLEdBQUcsQ0FBQyxLQUFLO3dCQUNoQixNQUFNLEVBQUUsR0FBRyxDQUFDLE1BQU07d0JBQ2xCLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSzt3QkFDaEIsUUFBUSxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQzt3QkFDeEMsY0FBYyxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUM7d0JBQzlDLEtBQUssRUFBRSxhQUFhLENBQUMsRUFBRSxFQUFFLEtBQUssQ0FBQyxFQUFFLHlCQUF5Qjt3QkFDMUQsTUFBTSxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTTtxQkFDM0IsQ0FBQyxDQUFDO2dCQUNMLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztnQkFBUyxDQUFDO1lBQ1QsR0FBRyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDekIsR0FBRyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDeEIsQ0FBQztRQUNELE9BQU8sRUFBRSxJQUFJLEVBQUUsUUFBUSxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUVELDJGQUEyRjtJQUNuRixRQUFRLENBQUMsSUFBVTtRQUN6QixNQUFNLEVBQUUsR0FBRyxFQUFFLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLDZGQUE2RjtRQUM3RixnQkFBZ0I7UUFDaEIsRUFBRTtRQUNGLDZFQUE2RTtRQUM3RSwrRUFBK0U7UUFDL0UsNkVBQTZFO1FBQzdFLDBFQUEwRTtRQUMxRSw4Q0FBOEM7UUFDOUMsRUFBRTtRQUNGLDZFQUE2RTtRQUM3RSw2RUFBNkU7UUFDN0UseUVBQXlFO1FBQ3pFLCtFQUErRTtRQUMvRSwyRUFBMkU7UUFDM0UsTUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksRUFBRSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3hDLE1BQU0sTUFBTSxHQUNWLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLElBQUksSUFBSSxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUNwRiwrRUFBK0U7UUFDL0UsNEVBQTRFO1FBQzVFLGtFQUFrRTtRQUNsRSxNQUFNLFNBQVMsR0FBRyxHQUFHLENBQUMsS0FBSyxDQUFDLGlCQUFpQixDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO1FBQzFELE1BQU0sS0FBSyxHQUFHLFNBQVMsRUFBRSxLQUFLLElBQUksSUFBSSxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ3hELE1BQU0sS0FBSyxHQUFHLFNBQVMsRUFBRSxNQUFNLElBQUksSUFBSSxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsTUFBTSxDQUFDO1FBQzFELE1BQU0sS0FBSyxHQUFHLFVBQVUsQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDO1FBQ25ELElBQUksTUFBTSxFQUFFLENBQUM7WUFDWCxPQUFPO2dCQUNMLEtBQUssRUFBRSxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDeEIsTUFBTSxFQUFFLEtBQUssR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDO2dCQUN6QixLQUFLLEVBQUUsS0FBSyxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUM7YUFDekIsQ0FBQztRQUNKLENBQUM7UUFDRCxNQUFNLFFBQVEsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0MsT0FBTztZQUNMLEtBQUssRUFBRSxDQUFDLEtBQUssR0FBRyx3QkFBd0IsQ0FBQyxHQUFHLFFBQVE7WUFDcEQsTUFBTSxFQUFFLENBQUMsS0FBSyxHQUFHLHdCQUF3QixDQUFDLEdBQUcsUUFBUTtZQUNyRCxLQUFLLEVBQUUsS0FBSztTQUNiLENBQUM7SUFDSixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxJQUFJO1FBQ0YscUJBQXFCO0lBQ3ZCLENBQUM7SUFFRDtpRUFDNkQ7SUFDN0QsU0FBUyxDQUFDLE9BQWUsRUFBRSxJQUFZO1FBQ3JDLE9BQU8sZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDM0QsQ0FBQztJQUVELFdBQVc7UUFDVCxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPLElBQUksQ0FBQztRQUM1QixPQUFPO1lBQ0wsV0FBVyxFQUFFLENBQUMsTUFBYyxFQUFFLE1BQWMsRUFBUSxFQUFFO2dCQUNwRCx5Q0FBeUM7Z0JBQ3pDLEtBQUssTUFBTSxLQUFLLElBQUksSUFBSSxDQUFDLElBQUksRUFBRSxNQUFNLElBQUksRUFBRSxFQUFFLENBQUM7b0JBQzVDLEtBQUssQ0FBQyxjQUFjLEdBQUcsQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7b0JBQ3hDLEtBQUssQ0FBQyxTQUFTLEdBQUcsS0FBSyxDQUFDO29CQUN4QixLQUFLLENBQUMsWUFBWSxHQUFHLEdBQUcsQ0FBQztnQkFDM0IsQ0FBQztnQkFDRCxJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztZQUNsQyxDQUFDO1NBQ0YsQ0FBQztJQUNKLENBQUM7SUFFRCxpQkFBaUI7UUFDZixPQUFPLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7SUFDMUUsQ0FBQztJQUVELE9BQU87UUFDTCxJQUFJLENBQUMsVUFBVSxFQUFFLFdBQVcsRUFBRSxDQUFDO1FBQy9CLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDO1FBQ3ZCLElBQUksQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLENBQUM7UUFDdEIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7UUFDbEIsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLEVBQUUsQ0FBQztRQUN4QixJQUFJLENBQUMsT0FBTyxHQUFHLElBQUksQ0FBQztRQUNwQixJQUFJLENBQUMsU0FBUyxHQUFHLElBQUksQ0FBQztJQUN4QixDQUFDO0lBRUQ7Ozs7O09BS0c7SUFDSCxTQUFTLENBQUMsTUFBYztRQUN0QixNQUFNLEVBQUUsUUFBUSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQztRQUM5QixRQUFRLENBQUMsWUFBWSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsR0FBRyxFQUFFLE1BQU0sQ0FBQyxDQUFDLENBQUM7UUFDNUQsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQztRQUM1QixJQUFJLENBQUMsSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUk7WUFBRSxPQUFPO1FBQ2hDLE1BQU0sTUFBTSxHQUFHLElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDLFlBQVksQ0FBQztRQUNsRCxNQUFNLEdBQUcsR0FBRyxNQUFNLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUN2QyxLQUFLLE1BQU0sS0FBSyxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDckMsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxLQUFLLENBQUMsU0FBUyxDQUFDO1lBQ2pDLEtBQUssQ0FBQyxTQUFTLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ2xDLENBQUM7UUFDRCxJQUFJLENBQUMsS0FBSyxFQUFFLFFBQVEsQ0FBQyxNQUFNLEVBQUUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSyxFQUFFLE1BQU0sRUFBRSxJQUFJLENBQUMsTUFBTSxFQUFFLEtBQUssRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLENBQUM7UUFDekcsSUFBSSxDQUFDLE9BQU8sRUFBRSxVQUFVLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztJQUNsQyxDQUFDO0lBRUQ7O3VFQUVtRTtJQUNuRSxVQUFVLENBQUMsR0FBUztRQUNsQixNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUN6QixNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUMxQixNQUFNLEVBQUUsR0FBRyxHQUFHLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztRQUN6QiwrRUFBK0U7UUFDL0UsNkVBQTZFO1FBQzdFLDBFQUEwRTtRQUMxRSxNQUFNLEVBQUUsRUFBRSxFQUFFLEdBQUcsRUFBRSxHQUFHLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUN2QyxNQUFNLEdBQUcsR0FBRyxDQUFDLENBQVMsRUFBRSxFQUFVLEVBQVUsRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsWUFBWSxDQUFDLENBQUMsR0FBRyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNqRyxPQUFPO1lBQ0wsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRTtZQUMvRSxFQUFFLE1BQU0sRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLEVBQUUsQ0FBQyxFQUFFLElBQUksRUFBRSxPQUFPLEdBQUcsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxLQUFLLEVBQUUsU0FBUyxFQUFFO1lBQy9FLDRFQUE0RTtZQUM1RSw4RUFBOEU7WUFDOUUsRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLEVBQUUsT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBRTtTQUNoRixDQUFDO0lBQ0osQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSyxXQUFXO1FBQ2pCLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDN0IsTUFBTSxJQUFJLEdBQUcsSUFBSSxFQUFFLFNBQVMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ2xDLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxJQUFJLENBQUM7UUFDdkIsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsaUJBQWlCLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDcEQsTUFBTSxJQUFJLEdBQUcsSUFBSSxFQUFFLElBQUksSUFBSSxJQUFJLEVBQUUsSUFBSSxJQUFJLENBQUMsQ0FBQztRQUMzQyxPQUFPO1lBQ0wsRUFBRSxFQUFFO2dCQUNGLElBQUksRUFBRSxLQUFLLElBQUksSUFBSSxFQUFFLENBQUMsSUFBSSxJQUFJLEVBQUUsS0FBSyxJQUFJLENBQUM7Z0JBQzFDLElBQUksRUFBRSxNQUFNLElBQUksSUFBSSxFQUFFLENBQUMsSUFBSSxJQUFJLEVBQUUsTUFBTSxJQUFJLENBQUM7Z0JBQzVDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxJQUFJLEVBQUUsS0FBSyxJQUFJLENBQUM7YUFDckM7WUFDRCw4RUFBOEU7WUFDOUUsK0NBQStDO1lBQy9DLEdBQUcsRUFBRSxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsSUFBSSxJQUFJLElBQUksRUFBRSxJQUFJLElBQUksSUFBSSxFQUFFLElBQUksRUFBRSxJQUFJLElBQUksQ0FBQyxDQUFDO1NBQy9ELENBQUM7SUFDSixDQUFDO0lBRUQ7OztxQkFHaUI7SUFDVCxrQkFBa0I7UUFDeEIsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUM7UUFDN0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxPQUFPLENBQUMsS0FBSyxDQUFDLENBQUMsUUFBUSxFQUFFLEVBQUU7WUFDM0MsTUFBTSxJQUFJLEdBQUcsSUFBSSxDQUFDLElBQUksQ0FBQztZQUN2QixJQUFJLENBQUMsSUFBSTtnQkFBRSxPQUFPO1lBQ2xCLElBQUksSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO2dCQUN0Qix5RkFBeUY7Z0JBQ3pGLElBQUksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFO29CQUMzQixNQUFNLEVBQUUsR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDO29CQUMvQyxJQUFJLENBQUMsYUFBYSxDQUFDLENBQUMsRUFBRTt3QkFDcEIsUUFBUSxFQUFFLE9BQU8sQ0FBQyxtQkFBbUIsQ0FBQyxFQUFFLEVBQUUsS0FBSyxJQUFJLFNBQVMsQ0FBQzt3QkFDN0QsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO3dCQUN0QixHQUFHLENBQUMsRUFBRTs0QkFDSixDQUFDLENBQUM7Z0NBQ0UsY0FBYyxFQUFFLENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFxQjtnQ0FDcEQsS0FBSyxFQUFFLGFBQWEsQ0FBQyxFQUFFLENBQUMsS0FBSyxDQUFDLEVBQUUseUJBQXlCO2dDQUN6RCxPQUFPLEVBQUUsRUFBRSxDQUFDLE9BQU87NkJBQ3BCOzRCQUNILENBQUMsQ0FBQyxFQUFFLENBQUM7cUJBQ1IsQ0FBQyxDQUFDO2dCQUNMLENBQUMsQ0FBQyxDQUFDO1lBQ0wsQ0FBQztpQkFBTSxDQUFDO2dCQUNOLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdkIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDLEVBQUU7b0JBQ3BCLFFBQVEsRUFBRSxPQUFPLENBQUMsY0FBYyxDQUFDLEVBQUUsQ0FBQztvQkFDcEMsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNO29CQUN0QixHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLGNBQWMsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBcUIsRUFBRSxLQUFLLEVBQUUsYUFBYSxDQUFDLEVBQUUsQ0FBQyxLQUFLLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7aUJBQ3hHLENBQUMsQ0FBQztZQUNMLENBQUM7UUFDSCxDQUFDLENBQUMsQ0FBQztJQUNMLENBQUM7Q0FDRjtBQUVEOzs7O0dBSUc7QUFDSCxNQUFNLE9BQU8sY0FBYztJQU16QixZQUNtQixHQUFpQixFQUNqQixJQUE0QjtRQUQ1QixRQUFHLEdBQUgsR0FBRyxDQUFjO1FBQ2pCLFNBQUksR0FBSixJQUFJLENBQXdCO1FBUHZDLFVBQUssR0FBeUIsSUFBSSxDQUFDO1FBQzNDLGlFQUFpRTtRQUNoRCxnQkFBVyxHQUFHLElBQUksR0FBRyxFQUFzQixDQUFDO1FBQ3JELGVBQVUsR0FBd0IsSUFBSSxDQUFDO0lBSzVDLENBQUM7SUFFSixLQUFLLENBQUMsS0FBSztRQUNULE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxJQUFJLENBQUM7UUFDckIsTUFBTSxHQUFHLEdBQUcsbUJBQW1CLENBQUMsR0FBRyxDQUFDLFFBQVEsQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUM5RCxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQztRQUN4QixHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN0QixJQUFJLEdBQUcsR0FBMkIsSUFBSSxDQUFDO1FBQ3ZDLElBQUksQ0FBQztZQUNILEdBQUcsR0FBRyxNQUFNLFFBQVEsQ0FDbEIsR0FBRyxFQUNILElBQUksQ0FBQyxJQUFJLEVBQ1QsRUFBRSxRQUFRLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsUUFBUSxFQUFFLGdCQUFnQixDQUFDLEVBQUUsU0FBUyxFQUFFLEdBQUcsQ0FBQyxTQUFTLEVBQUUsRUFDaEYsR0FBRyxDQUFDLE9BQU8sRUFBRSxDQUNkLENBQUM7UUFDSixDQUFDO2dCQUFTLENBQUM7WUFDVCxHQUFHLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN6QixHQUFHLENBQUMsS0FBSyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN4QixDQUFDO1FBQ0QsSUFBSSxDQUFDLEdBQUcsSUFBSSxHQUFHLENBQUMsTUFBTSxDQUFDLE9BQU87WUFBRSxPQUFPO1FBRXZDLE1BQU0sRUFBRSxJQUFJLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxLQUFLLEVBQUUsR0FBRyxHQUFHLENBQUM7UUFDM0MsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsS0FBSyxDQUFDLENBQUMsQ0FBQyxpQkFBaUI7UUFDOUUsTUFBTSxLQUFLLEdBQUcsS0FBSyxHQUFHLE1BQU0sR0FBRyxLQUFLLENBQUM7UUFDckMsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLEdBQUcsb0JBQW9CLENBQUMsQ0FBQyxDQUFDO1FBQ3BFLE1BQU0sR0FBRyxHQUFhLEVBQUUsQ0FBQztRQUN6QixNQUFNLEdBQUcsR0FBYSxFQUFFLENBQUM7UUFDekIsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDLElBQUksTUFBTSxFQUFFLENBQUM7WUFDdkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxHQUFHLEtBQUssQ0FBQztZQUNwQixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsR0FBRyxNQUFNLENBQUM7WUFDekMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQztZQUM1QyxHQUFHLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxHQUFHLE1BQU0sQ0FBQyxDQUFDO1lBQzVCLEdBQUcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDcEIsQ0FBQztRQUVELE1BQU0sRUFBRSxHQUFHLEdBQUcsQ0FBQyxLQUFLLENBQUMsb0JBQW9CLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUMvQyxJQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsV0FBVyxDQUFDLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLElBQUksWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFO1lBQ2hGLFFBQVEsRUFBRSxHQUFHLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxFQUFFLENBQUM7WUFDeEMsY0FBYyxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsSUFBSSxDQUFDLEVBQUUsRUFBRSxFQUFFLEdBQUcsSUFBSSxHQUFHLENBQUM7WUFDOUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTTtZQUMxQixJQUFJLEVBQUUsQ0FBQztTQUNSLENBQUMsQ0FBQztRQUNILEdBQUcsQ0FBQyxZQUFZLENBQUMsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2hDLGtFQUFrRTtRQUNsRSxJQUFJLENBQUMsV0FBVyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsQ0FBQztRQUM5Qix3RkFBd0Y7UUFDeEYsSUFBSSxDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLEtBQUssQ0FBQyxDQUFDLFFBQVEsRUFBRSxFQUFFO1lBQy9DLE1BQU0sS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7WUFDekIsSUFBSSxDQUFDLEtBQUs7Z0JBQUUsT0FBTztZQUNuQixNQUFNLENBQUMsR0FBRyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEIsS0FBSyxDQUFDLFFBQVEsR0FBRyxHQUFHLENBQUMsT0FBTyxDQUFDLGNBQWMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUMvQyxLQUFLLENBQUMsTUFBTSxHQUFHLEdBQUcsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDO1lBQ2xDLElBQUksQ0FBQztnQkFBRSxLQUFLLENBQUMsY0FBYyxHQUFHLENBQUMsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDN0MsR0FBRyxDQUFDLE1BQU0sQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUM3QixDQUFDLENBQUMsQ0FBQztRQUNILEdBQUcsQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLEVBQUUsQ0FBQztJQUMvQixDQUFDO0lBRUQsOERBQThEO0lBQzlELElBQUk7UUFDRixxQkFBcUI7SUFDdkIsQ0FBQztJQUVELFNBQVMsQ0FBQyxPQUFlLEVBQUUsSUFBWTtRQUNyQyxPQUFPLGdCQUFnQixDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsT0FBTyxFQUFFLElBQUksQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRCxpQkFBaUI7UUFDZixPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLGlCQUFpQixDQUFDLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUNyRSxDQUFDO0lBRUQsT0FBTztRQUNMLElBQUksQ0FBQyxVQUFVLEVBQUUsV0FBVyxFQUFFLENBQUM7UUFDL0IsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7SUFDekIsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBNdWx0aUNoYW5uZWxWb2x1bWVWaWV3LCBoaXN0b2dyYW1TY2FsYXIgfSBmcm9tICduYXBhcmktanMnO1xuaW1wb3J0IHR5cGUgeyBQb2ludHMzRExheWVyLCBWb2x1bWVDaGFubmVsIH0gZnJvbSAnbmFwYXJpLWpzJztcbmltcG9ydCB7IGZvcm1hdExlbmd0aCB9IGZyb20gJ25hcGFyaS1qcy9vdmVybGF5cyc7XG5pbXBvcnQgdHlwZSB7IEF4aXNMYWJlbFNwZWMgfSBmcm9tICduYXBhcmktanMvb3ZlcmxheXMnO1xuXG5pbXBvcnQgeyBJSW1hZ2VJbmZvIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL2ltYWdlLmNvbnRyYWN0JztcbmltcG9ydCB7IElIaXN0b2dyYW0gfSBmcm9tICcuLi8uLi9jb250cmFjdHMvY2hhbm5lbC1oaXN0b2dyYW0tYXBpLmNvbnRyYWN0JztcbmltcG9ydCB7IElJc29zdXJmYWNlQ29udHJvbHMsIElTdXJmYWNlM2RDb250cm9scyB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy92aXN1YWxpemVyLmNvbnRyYWN0JztcbmltcG9ydCB7IE5hcGFyaVZvbHVtZVpIYW5kbGUgfSBmcm9tICcuL25hcGFyaS12b2x1bWUtei1oYW5kbGUnO1xuaW1wb3J0IHsgQXNzZW1ibGVkVm9sdW1lIH0gZnJvbSAnLi9uYXBhcmktdGlsZS1jbGllbnQnO1xuaW1wb3J0IHsgVGlsZURlc2NyaXB0b3IgfSBmcm9tICcuLi90aWxlLXNlcnZlcic7XG5pbXBvcnQgeyBBeGVzM2RHaXptbywgQm94Mywgc3VyZmFjZTNkQ29udHJvbHMgfSBmcm9tICcuL25hcGFyaS1heGVzLWdpem1vJztcbmltcG9ydCB7XG4gIFNDQVRURVIzRF9NQVhfUE9JTlRTLFxuICBTQ0FUVEVSM0RfTUFYX1hZLFxuICBWT0xVTUVfV09STERfSU5QTEFORV9SRUYsXG4gIGlzU2VydmVybGVzc011bHRpY2hhbm5lbCxcbiAgc3RhY2tEZXB0aCxcbiAgdGludEZvcixcbiAgdG9JSGlzdG9ncmFtLFxuICB0b05hcGFyaUdhbW1hLFxuICB2b2x1bWVSZXNvbHV0aW9uRm9yLFxufSBmcm9tICcuL25hcGFyaS1oZWxwZXJzJztcbmltcG9ydCB0eXBlIHsgTmFwYXJpU2NlbmUsIFNjZW5lQ29udGV4dCB9IGZyb20gJy4vbmFwYXJpLXNjZW5lJztcblxuLyoqIFRoZSBpbnRlbnNpdHkgaGlzdG9ncmFtIG9mIGFuIGFzc2VtYmxlZCB1aW50OCBjaGFubmVsIChvciB0aGUgc2luZ2xlIGdyYXlzY2FsZSB2b2x1bWUsIGtleSAwKS4gKi9cbmZ1bmN0aW9uIGNoYW5uZWxIaXN0b2dyYW0oZGF0YTogTWFwPG51bWJlciwgVWludDhBcnJheT4sIGNoYW5uZWw6IG51bWJlciwgYmluczogbnVtYmVyKTogSUhpc3RvZ3JhbSB8IG51bGwge1xuICBpZiAoIWRhdGEuc2l6ZSkgcmV0dXJuIG51bGw7XG4gIGNvbnN0IHBsYW5lID0gZGF0YS5nZXQoY2hhbm5lbCkgPz8gZGF0YS5nZXQoMCk7XG4gIHJldHVybiBwbGFuZSA/IHRvSUhpc3RvZ3JhbShoaXN0b2dyYW1TY2FsYXIocGxhbmUsIGJpbnMsIDAsIDI1NSkpIDogbnVsbDtcbn1cblxuLyoqIEFzc2VtYmxlIGBpbmZvYCdzIHN0YWNrIGludG8gYSB1aW50OCB2b2x1bWUgdW5kZXIgdGhlIHN0YWNrIHByb2dyZXNzIGJhcjsgbnVsbCBvbmNlIGBsb2FkaW5nYFxuICogIGFib3J0cyAoYSBDYW5jZWwgb3IgYSBuZXcgcGxvdCkuIFRoZSBjYWxsZXIgb3ducyB0aGUgbG9hZGluZyBmbGFnIGFuZCB0YWtlcyBgbG9hZGluZ2Agb25jZSBwZXJcbiAqICBsb2FkOiBhIENhbmNlbCByZXBsYWNlcyBgY3R4LmxvYWRpbmcoKWAsIGFuZCBhIG11bHRpY2hhbm5lbCB2b2x1bWUgYXNzZW1ibGVzIGNoYW5uZWxzIGluIHR1cm4uICovXG5mdW5jdGlvbiBhc3NlbWJsZShcbiAgY3R4OiBTY2VuZUNvbnRleHQsXG4gIGluZm86IElJbWFnZUluZm8gfCB1bmRlZmluZWQsXG4gIG9wdHM6IHsgbWF4U2xpY2U/OiBudW1iZXI7IHNsaWNlU3RlcD86IG51bWJlciB9LFxuICBsb2FkaW5nOiBBYm9ydFNpZ25hbCxcbiAgY2hhbm5lbD86IG51bWJlcixcbik6IFByb21pc2U8QXNzZW1ibGVkVm9sdW1lIHwgbnVsbD4ge1xuICByZXR1cm4gY3R4LnRpbGVzLmFzc2VtYmxlVm9sdW1lKGluZm8sIG9wdHMsIGNoYW5uZWwsIHtcbiAgICBzaWduYWw6IGxvYWRpbmcsXG4gICAgcHJvZ3Jlc3M6IChwKSA9PiBjdHguc3RhY2sucHJvZ3Jlc3MocCksXG4gIH0pO1xufVxuXG4vKipcbiAqIE5BUEFSSV9WT0xVTUUgLyBOQVBBUklfSVNPU1VSRkFDRSAocmV2aWV3IEFwcGVuZGl4IEIsIGNsdXN0ZXIgRik6IHRoZSBzdGFjayBhc3NlbWJsZWQgaW50byBhXG4gKiBkZWNpbWF0ZWQgdm9sdW1lIOKAlCBvbmUgYWRkaXRpdmUsIHRpbnRlZCBgVm9sdW1lTGF5ZXJgIHBlciBjaGFubmVsIGZvciBhIG11bHRpY2hhbm5lbCBpbWFnZSwgYVxuICogc2luZ2xlIGdyYXlzY2FsZSB2b2x1bWUgb3RoZXJ3aXNlIOKAlCB3aXRoIHRoZSBheGVzIGdpem1vIGFuZCB0aGUgaW4tdmlldyBaLWhlaWdodCBoYW5kbGUuXG4gKi9cbmV4cG9ydCBjbGFzcyBWb2x1bWVTY2VuZSBpbXBsZW1lbnRzIE5hcGFyaVNjZW5lIHtcbiAgLyoqIG5hcGFyaS1qcyBoaWdoLWxldmVsIHZpZXcgb3duaW5nIHRoZSB2b2x1bWUgbGF5ZXJzLiAqL1xuICB2aWV3OiBNdWx0aUNoYW5uZWxWb2x1bWVWaWV3IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUcnVlIHdoZW4gdGhlIHZvbHVtZSBpcyBjb21wb3NpdGVkIGZyb20gcGVyLWNoYW5uZWwgbGF5ZXJzICh2cyBhIHNpbmdsZSBncmF5c2NhbGUgdm9sdW1lKS4gKi9cbiAgcHJpdmF0ZSBtdWx0aWNoYW5uZWwgPSBmYWxzZTtcbiAgLyoqIFZvbHVtZSB3b3JsZCBib3ggYXQgWi1zY2FsZSAxIChiYXNlKSArIHRoZSBzYW1wbGVkIHZveGVsIGRlcHRoIOKAlCBlbm91Z2ggdG8gcmVjb21wdXRlIHRoZVxuICAgKiAgWi1heGlzIHZveGVsIHNjYWxlLCBheGVzIGRlcHRoLCBhbmQgb3ZlcmxheSBhbmNob3JzIGFzIHRoZSBoYW5kbGUgc3RyZXRjaGVzIFouICovXG4gIHByaXZhdGUgd29ybGRCYXNlOiBCb3gzIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgc2FtcGxlZERlcHRoID0gMTtcbiAgcHJpdmF0ZSBkaW1zOiBCb3gzIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBBc3NlbWJsZWQgdWludDggdm9sdW1lIGRhdGEgcGVyIGNoYW5uZWwgKGtleSA9IGNoYW5uZWwgaW5kZXgpLCBrZXB0IGZvciB0aGUgdm9sdW1lIGludGVuc2l0eVxuICAgKiAgaGlzdG9ncmFtLiBLZXkgMCBob2xkcyB0aGUgZ3JheXNjYWxlL2NvbXBvc2l0ZSB2b2x1bWUgaW4gdGhlIHNpbmdsZS1jaGFubmVsIGNhc2UuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgY2hhbm5lbERhdGEgPSBuZXcgTWFwPG51bWJlciwgVWludDhBcnJheT4oKTtcbiAgZ2l6bW86IEF4ZXMzZEdpem1vIHwgbnVsbCA9IG51bGw7XG4gIHByaXZhdGUgekhhbmRsZTogTmFwYXJpVm9sdW1lWkhhbmRsZSB8IG51bGwgPSBudWxsO1xuICBwcml2YXRlIGRpc3BsYXlTdWI6IFN1YnNjcmlwdGlvbiB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY3R4OiBTY2VuZUNvbnRleHQsXG4gICAgcHJpdmF0ZSByZWFkb25seSBpbmZvOiBJSW1hZ2VJbmZvIHwgdW5kZWZpbmVkLFxuICAgIHByaXZhdGUgcmVhZG9ubHkgcmVuZGVyaW5nOiAnaXNvJyB8ICdtaXAnLFxuICApIHt9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGFuZCByZW5kZXIgdGhlIHZvbHVtZSwgdGhlbiBhZGQgdGhlIGF4ZXMgZ2l6bW8gKyBsYWJlbHMgYW5kIHRoZSBaIGhhbmRsZSBhbmQgZm9sbG93XG4gICAqIHRoZSBkaXNwbGF5IHN0YXRlLlxuICAgKi9cbiAgYXN5bmMgbW91bnQoKTogUHJvbWlzZTx2b2lkPiB7XG4gICAgY29uc3QgeyBjdHgsIGluZm8gfSA9IHRoaXM7XG4gICAgY29uc3QgbG9hZGluZyA9IGN0eC5sb2FkaW5nKCk7IC8vIGJhaWwgYmVmb3JlIHJlbmRlcmluZyBvbiBhIENhbmNlbCAvIG5ldyBwbG90XG4gICAgY29uc3QgZGVzYyA9IGF3YWl0IGN0eC50aWxlcy5lbnN1cmVEZXNjcmlwdG9yKGN0eC5pbmZvKCkpO1xuICAgIC8vIFNlcnZlcmxlc3MgbXVsdGljaGFubmVsICh0aWxlZDpmYWxzZSArIGNoYW5uZWxVcmxzKTogbm8gdGlsZSBkZXNjcmlwdG9yLCBzb1xuICAgIC8vIGRlcml2ZSB0aGUgY2hhbm5lbCBjb3VudCBmcm9tIGltYWdlTWV0YSBhbmQgYXNzZW1ibGUgZWFjaCBiYW5kIGZyb20gaXRzIG93blxuICAgIC8vIGNoYW5uZWxVcmxzW3pdW2NdIHBsYW5lIChmZXRjaEltYWdlIGRvZXMgdGhlIHBlci1jaGFubmVsIHJvdXRpbmcpLlxuICAgIGNvbnN0IHNpbXBsZU1jID0gaXNTZXJ2ZXJsZXNzTXVsdGljaGFubmVsKGN0eC50aWxlcy5pc1NpbXBsZShpbmZvKSwgaW5mbyk7XG4gICAgY29uc3QgY2hhbm5lbENvdW50ID0gc2ltcGxlTWMgPyBpbmZvIS5pbWFnZU1ldGEhWzBdLmNoYW5uZWxDb3VudCA6IChkZXNjPy5jaGFubmVscyA/PyAxKTtcbiAgICBjb25zdCBtdWx0aWNoYW5uZWwgPSBzaW1wbGVNYyB8fCAoISFkZXNjPy5tdWx0aWNoYW5uZWwgJiYgY2hhbm5lbENvdW50ID4gMSk7XG5cbiAgICB0aGlzLmNoYW5uZWxEYXRhLmNsZWFyKCk7XG4gICAgdGhpcy5tdWx0aWNoYW5uZWwgPSBtdWx0aWNoYW5uZWw7XG4gICAgY29uc3QgdmlldyA9IG5ldyBNdWx0aUNoYW5uZWxWb2x1bWVWaWV3KGN0eC52aWV3ZXIpO1xuICAgIHRoaXMudmlldyA9IHZpZXc7XG4gICAgY29uc3QgeyBkaW1zLCBjaGFubmVscyB9ID0gYXdhaXQgdGhpcy5hc3NlbWJsZUNoYW5uZWxzKGRlc2MsIGNoYW5uZWxDb3VudCwgbG9hZGluZyk7XG4gICAgaWYgKCFkaW1zIHx8ICFjaGFubmVscy5sZW5ndGggfHwgbG9hZGluZy5hYm9ydGVkKSByZXR1cm47IC8vIGNhbmNlbGxlZCDihpIgZG9uJ3QgcmVuZGVyXG5cbiAgICBjb25zdCB3b3JsZCA9IHRoaXMud29ybGRCb3goZGltcyk7XG4gICAgLy8gQmFzZSBib3ggKFotc2NhbGUgPSAxKSArIHRoZSBzYW1wbGVkIGRlcHRoIGRyaXZlIHRoZSBsaXZlIFotaGVpZ2h0IGhhbmRsZSBiZWxvdzsgdGhlIHBlcnNpc3RlZFxuICAgIC8vIGB2b2x1bWVaU2NhbGVgICh1c2VyIGRyYWcpIGFwcGxpZXMgb24gdG9wIHNvIGNoYW5naW5nIHJlc29sdXRpb24ga2VlcHMgdGhlIGNob3NlbiBoZWlnaHQuXG4gICAgdGhpcy53b3JsZEJhc2UgPSB3b3JsZDtcbiAgICB0aGlzLnNhbXBsZWREZXB0aCA9IE1hdGgubWF4KDEsIGRpbXMuZGVwdGgpO1xuICAgIGNvbnN0IHdvcmxkWiA9IHdvcmxkLmRlcHRoICogY3R4LnNldHRpbmdzLnZvbHVtZVpTY2FsZTtcbiAgICBjb25zdCB2b3hlbFNpemU6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXSA9IFtcbiAgICAgIHdvcmxkLndpZHRoIC8gZGltcy53aWR0aCxcbiAgICAgIHdvcmxkLmhlaWdodCAvIGRpbXMuaGVpZ2h0LFxuICAgICAgd29ybGRaIC8gdGhpcy5zYW1wbGVkRGVwdGgsXG4gICAgXTtcbiAgICBmb3IgKGNvbnN0IGNoIG9mIGNoYW5uZWxzKSBjaC52b3hlbFNpemUgPSB2b3hlbFNpemU7XG5cbiAgICB2aWV3LnJlbmRlcih0aGlzLm11bHRpY2hhbm5lbCA/ICdtdWx0aWNoYW5uZWwnIDogJ2dyYXlzY2FsZScsIGNoYW5uZWxzLCB7IHJlbmRlcmluZzogdGhpcy5yZW5kZXJpbmcgfSk7XG4gICAgY3R4LnNldEltYWdlU2l6ZShkaW1zLndpZHRoLCBkaW1zLmhlaWdodCk7XG4gICAgdGhpcy5kaW1zID0gZGltcztcblxuICAgIC8vIDNEIGNvb3JkaW5hdGUtYXhlcyAvIHNjYWxlIGdpem1vICsgbGFiZWxzLCBzaGFyaW5nIHRoZSB2b2x1bWUncyB3b3JsZCBib3ggc28gdGhlIGdpem1vIHRyYWNrc1xuICAgIC8vIHRoZSByZW5kZXJlZCBwcm9wb3J0aW9ucy4gUGh5c2ljYWwgc2NhbGUgdGV4dCBzdGlsbCBjb21lcyBmcm9tIHRoZSBGVUxMIGltYWdlIGV4dGVudC5cbiAgICBjb25zdCBib3ggPSB7IHdpZHRoOiB3b3JsZC53aWR0aCwgaGVpZ2h0OiB3b3JsZC5oZWlnaHQsIGRlcHRoOiB3b3JsZFogfTtcbiAgICB0aGlzLmdpem1vID0gbmV3IEF4ZXMzZEdpem1vKGN0eC52aWV3ZXIsIGN0eC5ob3N0LCBib3gsIHRoaXMuYXhlc0xhYmVscyhib3gpLCB7XG4gICAgICB2aXNpYmxlOiBjdHguc2V0dGluZ3MuYXhlc1Zpc2libGUsXG4gICAgfSk7XG4gICAgLy8gSW4tdmlldyBkcmFnIGhhbmRsZSBhdCB0aGUgVE9QIEVORCBPRiBUSEUgWiBBWElTICh0aGUgYm94J3MgbWluLVhZIGNvcm5lciwgd2hlcmUgdGhlIGJsdWVcbiAgICAvLyBcIlpcIiBheGlzICsgbGFiZWwgbGl2ZSksIHNvIGl0IHJlYWRzIGFzIHRoZSBaLWhlaWdodCBjb250cm9sLiBGbG9hdGVkIGEgbGl0dGxlIHBhc3QgdGhlIGF4aXNcbiAgICAvLyB0aXAgKMOXMS4xMikgc28gdGhlIGdyaXAgY2xlYXJzIHRoZSBcIlogwrcg4oCmXCIgbGFiZWwuIERyYWcg4oaVIHRvIHJlc3RyZXRjaCBaIGxpdmUuXG4gICAgdGhpcy56SGFuZGxlID0gbmV3IE5hcGFyaVZvbHVtZVpIYW5kbGUoY3R4Lmhvc3QsIGN0eC52aWV3ZXIuY2FtZXJhM2QsIHtcbiAgICAgIHRvcEFuY2hvcjogKCkgPT4gW1xuICAgICAgICAtdGhpcy53b3JsZEJhc2UhLndpZHRoIC8gMixcbiAgICAgICAgLXRoaXMud29ybGRCYXNlIS5oZWlnaHQgLyAyLFxuICAgICAgICAoKHRoaXMud29ybGRCYXNlIS5kZXB0aCAqIGN0eC5zZXR0aW5ncy52b2x1bWVaU2NhbGUpIC8gMikgKiAxLjEyLFxuICAgICAgXSxcbiAgICAgIGdldFNjYWxlOiAoKSA9PiBjdHguc2V0dGluZ3Mudm9sdW1lWlNjYWxlLFxuICAgICAgc2V0U2NhbGU6IChzKSA9PiB0aGlzLnNldFpTY2FsZShzKSxcbiAgICB9KTtcbiAgICB0aGlzLmZvbGxvd0Rpc3BsYXlTdGF0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIEFzc2VtYmxlIGVhY2ggY2hhbm5lbCdzIHZvbHVtZSBmcm9tIHRoZSBzZXJ2ZXIgdGlsZXMgKG9yIHRoZSBzaW5nbGUgZ3JheXNjYWxlIHZvbHVtZSkgdW5kZXJcbiAgICogdGhlIHN0YWNrIHByb2dyZXNzIGJhciwgd2l0aCB0aGUgZGlzcGxheSBzZXR0aW5ncyBpdCBpcyBkcmF3biB3aXRoLiBgZGltc2AgaXMgbnVsbCB3aGVuXG4gICAqIG5vdGhpbmcgd2FzIGFzc2VtYmxlZCAoYSBDYW5jZWwsIGEgbmV3IHBsb3QsIG9yIG5vIHNsaWNlcykuXG4gICAqL1xuICBwcml2YXRlIGFzeW5jIGFzc2VtYmxlQ2hhbm5lbHMoXG4gICAgZGVzYzogVGlsZURlc2NyaXB0b3IgfCBudWxsLFxuICAgIGNoYW5uZWxDb3VudDogbnVtYmVyLFxuICAgIGxvYWRpbmc6IEFib3J0U2lnbmFsLFxuICApOiBQcm9taXNlPHsgZGltczogQm94MyB8IG51bGw7IGNoYW5uZWxzOiBWb2x1bWVDaGFubmVsW10gfT4ge1xuICAgIGNvbnN0IHsgY3R4LCBpbmZvIH0gPSB0aGlzO1xuICAgIGNvbnN0IHJlcyA9IHZvbHVtZVJlc29sdXRpb25Gb3IoY3R4LnNldHRpbmdzLnJlc29sdXRpb25TY2FsZSk7XG4gICAgY29uc3Qgc3RhdGVzID0gY3R4LnN0b3JlLmN1cnJlbnRDaGFubmVsU3RhdGVzKCk7XG5cbiAgICAvLyBBc3NlbWJsZSBwZXItY2hhbm5lbCBzY2FsYXIgdm9sdW1lcyBmcm9tIHRoZSBzZXJ2ZXIgdGlsZXMgKGppdC1zcGVjaWZpYyk7IHRoZSBuYXBhcmktanMgdmlld1xuICAgIC8vIG93bnMgdGhlIGxheWVyIG9yY2hlc3RyYXRpb24gKG9uZSBhZGRpdGl2ZSB0aW50ZWQgdm9sdW1lIHBlciBjaGFubmVsLCBvciBhIHNpbmdsZSBncmF5c2NhbGVcbiAgICAvLyB2b2x1bWUpLiBUaGUgYWRhcHRlciBjb21wdXRlcyBlYWNoIGNoYW5uZWwncyBjb2xvcm1hcCAoaW5jbC4gdGhlIHJldmVyc2UgZmxpcCkgYW5kIGludmVydC5cbiAgICBsZXQgZGltczogQm94MyB8IG51bGwgPSBudWxsO1xuICAgIGNvbnN0IGNoYW5uZWxzOiBWb2x1bWVDaGFubmVsW10gPSBbXTtcbiAgICBjdHguc3RhY2subG9hZGluZyh0cnVlKTtcbiAgICBjdHguc3RhY2sucHJvZ3Jlc3MoMCk7XG4gICAgdHJ5IHtcbiAgICAgIGlmICh0aGlzLm11bHRpY2hhbm5lbCkge1xuICAgICAgICBmb3IgKGxldCBjID0gMDsgYyA8IGNoYW5uZWxDb3VudDsgYysrKSB7XG4gICAgICAgICAgY29uc3Qgdm9sID0gYXdhaXQgYXNzZW1ibGUoY3R4LCBpbmZvLCByZXMsIGxvYWRpbmcsIGMpO1xuICAgICAgICAgIGlmIChsb2FkaW5nLmFib3J0ZWQpIGJyZWFrOyAvLyBhIENhbmNlbCAvIG5ldyBwbG90OiBmZXRjaCBubyBmdXJ0aGVyIGNoYW5uZWxcbiAgICAgICAgICBpZiAoIXZvbCkgY29udGludWU7XG4gICAgICAgICAgZGltcyA9IHZvbDtcbiAgICAgICAgICB0aGlzLmNoYW5uZWxEYXRhLnNldChjLCB2b2wuZGF0YSk7XG4gICAgICAgICAgY29uc3Qgc3QgPSBzdGF0ZXMuZmluZCgocykgPT4gcy5pbmRleCA9PT0gYyk7XG4gICAgICAgICAgY29uc3QgY29sb3IgPSBzdD8uY29sb3IgPz8gZGVzYz8uY2hhbm5lbEluZm8/LltjXT8uY29sb3IgPz8gdGludEZvcihjKTtcbiAgICAgICAgICBjaGFubmVscy5wdXNoKHtcbiAgICAgICAgICAgIGRhdGE6IHZvbC5kYXRhLFxuICAgICAgICAgICAgd2lkdGg6IHZvbC53aWR0aCxcbiAgICAgICAgICAgIGhlaWdodDogdm9sLmhlaWdodCxcbiAgICAgICAgICAgIGRlcHRoOiB2b2wuZGVwdGgsXG4gICAgICAgICAgICBjb2xvcm1hcDogY3R4LmRpc3BsYXkuY2hhbm5lbFRpbnRDb2xvcm1hcChjb2xvciksXG4gICAgICAgICAgICBjb250cmFzdExpbWl0czogW3N0Py5taW4gPz8gMCwgc3Q/Lm1heCA/PyAyNTVdLFxuICAgICAgICAgICAgZ2FtbWE6IHRvTmFwYXJpR2FtbWEoc3Q/LmdhbW1hKSwgLy8gSW1hZ2VKIM6zIOKGkiBuYXBhcmktanMgzrNcbiAgICAgICAgICAgIGludmVydDogY3R4LmRpc3BsYXkuaW52ZXJ0LFxuICAgICAgICAgICAgdmlzaWJsZTogc3Q/LnZpc2libGUgPz8gdHJ1ZSxcbiAgICAgICAgICB9KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgdm9sID0gYXdhaXQgYXNzZW1ibGUoY3R4LCBpbmZvLCByZXMsIGxvYWRpbmcpO1xuICAgICAgICBpZiAodm9sKSB7XG4gICAgICAgICAgZGltcyA9IHZvbDtcbiAgICAgICAgICB0aGlzLmNoYW5uZWxEYXRhLnNldCgwLCB2b2wuZGF0YSk7XG4gICAgICAgICAgY29uc3Qgc3QgPSBzdGF0ZXNbMF07XG4gICAgICAgICAgY2hhbm5lbHMucHVzaCh7XG4gICAgICAgICAgICBkYXRhOiB2b2wuZGF0YSxcbiAgICAgICAgICAgIHdpZHRoOiB2b2wud2lkdGgsXG4gICAgICAgICAgICBoZWlnaHQ6IHZvbC5oZWlnaHQsXG4gICAgICAgICAgICBkZXB0aDogdm9sLmRlcHRoLFxuICAgICAgICAgICAgY29sb3JtYXA6IGN0eC5kaXNwbGF5LnZvbHVtZUNvbG9ybWFwKHN0KSxcbiAgICAgICAgICAgIGNvbnRyYXN0TGltaXRzOiBbc3Q/Lm1pbiA/PyAwLCBzdD8ubWF4ID8/IDI1NV0sXG4gICAgICAgICAgICBnYW1tYTogdG9OYXBhcmlHYW1tYShzdD8uZ2FtbWEpLCAvLyBJbWFnZUogzrMg4oaSIG5hcGFyaS1qcyDOs1xuICAgICAgICAgICAgaW52ZXJ0OiBjdHguZGlzcGxheS5pbnZlcnQsXG4gICAgICAgICAgfSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9IGZpbmFsbHkge1xuICAgICAgY3R4LnN0YWNrLmxvYWRpbmcoZmFsc2UpO1xuICAgICAgY3R4LnN0YWNrLnByb2dyZXNzKDApO1xuICAgIH1cbiAgICByZXR1cm4geyBkaW1zLCBjaGFubmVscyB9O1xuICB9XG5cbiAgLyoqIFRoZSB2b2x1bWUncyB3b3JsZCBib3ggZm9yIHRoZSBhc3NlbWJsZWQgYGRpbXNgLCBpbmRlcGVuZGVudCBvZiB0aGUgZGVjaW1hdGUgZmFjdG9yLiAqL1xuICBwcml2YXRlIHdvcmxkQm94KGRpbXM6IEJveDMpOiBCb3gzIHtcbiAgICBjb25zdCB7IGN0eCB9ID0gdGhpcztcbiAgICAvLyBSZXNvbHV0aW9uLWludmFyaWFudCB3b3JsZCBib3g7IHRoZSBwZXItYXhpcyBgdm94ZWxTaXplYCAobmFwYXJpIGBzY2FsZWApIG1hcHMgdGhlIHNhbXBsZWRcbiAgICAvLyBncmlkIG9udG8gaXQuXG4gICAgLy9cbiAgICAvLyBBIHN0YWNrIHRoYXQgZGVjbGFyZXMgaXRzIHBoeXNpY2FsIHNwYWNpbmcgb24gQUxMIFRIUkVFIGF4ZXMgZ2V0cyBpdHMgdHJ1ZVxuICAgIC8vIGV4dGVudCBhcyB0aGUgd29ybGQgYm94IOKAlCB0aGUgb25seSB3YXkgYW5pc290cm9weSBzdXJ2aXZlcywgYW5kIHdoYXQgbWFrZXMgYVxuICAgIC8vIHJlc2FtcGxlZCA0MCB4IDQwIHggMjAwIMK1bSB2b2x1bWUgcmVhZCBhcyBhIGJyYWluIGluc3RlYWQgb2YgYSBjdWJlLWFzcGVjdFxuICAgIC8vIGJyaWNrLiBJdCBuZWVkcyBub25lIG9mIHRoZSByZWZlcmVuY2UtYm94IGFyaXRobWV0aWM6IGEgcGh5c2ljYWwgYm94IGlzXG4gICAgLy8gYWxyZWFkeSBpbmRlcGVuZGVudCBvZiB0aGUgZGVjaW1hdGUgZmFjdG9yLlxuICAgIC8vXG4gICAgLy8gRXZlcnl0aGluZyBlbHNlIGtlZXBzIHRoYXQgYXJpdGhtZXRpYy4gU2l6aW5nIHRoZSBib3ggYnkgdGhlIHNhbXBsZWQgdm94ZWxcbiAgICAvLyBjb3VudHMgbWFkZSBoaWdoZXIgaW4tcGxhbmUgcmVzb2x1dGlvbiBncm93IFgvWSB3aGlsZSB0aGUgZGVwdGggc3RheWVkIHRoZVxuICAgIC8vIChjb25zdGFudCkgc2xpY2UgY291bnQg4oCUIHNvIFogYXBwZWFyZWQgdG8gc2hyaW5rIGF0IGhpZ2hlciByZXNvbHV0aW9uLlxuICAgIC8vIEFuY2hvcmluZyB0aGUgaW4tcGxhbmUgbG9uZyBzaWRlIHRvIGEgZml4ZWQgcmVmZXJlbmNlIGFuZCBsZXR0aW5nIFogc3BhbiB0aGVcbiAgICAvLyBmdWxsIHNsaWNlIGNvdW50IG1ha2VzIHRoZSBib3ggc2hhcGUgaWRlbnRpY2FsIGF0IGV2ZXJ5IGRlY2ltYXRlIGZhY3Rvci5cbiAgICBjb25zdCBtZXRhID0gY3R4LmluZm8oKT8uaW1hZ2VNZXRhPy5bMF07XG4gICAgY29uc3QgbXBwWFlaOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfCBudWxsID1cbiAgICAgIG1ldGE/Lm1wcFggJiYgbWV0YT8ubXBwWSAmJiBtZXRhPy5tcHBaID8gW21ldGEubXBwWCwgbWV0YS5tcHBZLCBtZXRhLm1wcFpdIDogbnVsbDtcbiAgICAvLyBUaGUgaW1hZ2UncyBERUNMQVJFRCBwaXhlbCBkaW1lbnNpb25zLCB3aGljaCBpcyB3aGF0IG1wcCBpcyBwZXI6IHRoZSBzYW1wbGVkXG4gICAgLy8gZGltcyBhcmUgZGVjaW1hdGVkLCBzbyBzaXppbmcgYSBwaHlzaWNhbCBib3ggYnkgdGhlbSB3b3VsZCBtYWtlIHRoZSB3b3JsZFxuICAgIC8vIGJveCBkZXBlbmQgb24gdGhlIHJlc29sdXRpb24gdGhlIHVzZXIgaGFwcGVucyB0byBiZSB2aWV3aW5nIGF0LlxuICAgIGNvbnN0IGltYWdlRGVzYyA9IGN0eC50aWxlcy5jdXJyZW50RGVzY3JpcHRvcihjdHguaW5mbygpKTtcbiAgICBjb25zdCBmdWxsVyA9IGltYWdlRGVzYz8ud2lkdGggPz8gbWV0YT8ueCA/PyBkaW1zLndpZHRoO1xuICAgIGNvbnN0IGZ1bGxIID0gaW1hZ2VEZXNjPy5oZWlnaHQgPz8gbWV0YT8ueSA/PyBkaW1zLmhlaWdodDtcbiAgICBjb25zdCBmdWxsRCA9IHN0YWNrRGVwdGgoY3R4LmluZm8oKSkgfHwgZGltcy5kZXB0aDtcbiAgICBpZiAobXBwWFlaKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB3aWR0aDogZnVsbFcgKiBtcHBYWVpbMF0sXG4gICAgICAgIGhlaWdodDogZnVsbEggKiBtcHBYWVpbMV0sXG4gICAgICAgIGRlcHRoOiBmdWxsRCAqIG1wcFhZWlsyXSxcbiAgICAgIH07XG4gICAgfVxuICAgIGNvbnN0IGZ1bGxMb25nID0gTWF0aC5tYXgoMSwgZnVsbFcsIGZ1bGxIKTtcbiAgICByZXR1cm4ge1xuICAgICAgd2lkdGg6IChmdWxsVyAqIFZPTFVNRV9XT1JMRF9JTlBMQU5FX1JFRikgLyBmdWxsTG9uZyxcbiAgICAgIGhlaWdodDogKGZ1bGxIICogVk9MVU1FX1dPUkxEX0lOUExBTkVfUkVGKSAvIGZ1bGxMb25nLFxuICAgICAgZGVwdGg6IGZ1bGxELFxuICAgIH07XG4gIH1cblxuICAvKipcbiAgICogVGhlIHdob2xlIHN0YWNrIGlzIGFscmVhZHkgb24gc2NyZWVuOiBubyBwbGFuZSB0byBzdGVwLiAoVGhpcyB1c2VkIHRvIHdyaXRlIGB2aWV3ZXIuZGltcy56YCxcbiAgICogd2hpY2ggb25seSBhIHRpbGVkIDJEIGltYWdlIHJlYWRzIOKAlCBhIHZvbHVtZSByYXltYXJjaGVzIGV2ZXJ5IHNsaWNlIOKAlCBhbmQgc2NoZWR1bGUgYSByZWFkYmFja1xuICAgKiBvZiBhIGZyYW1lIHRoYXQgaGFkIG5vdCBjaGFuZ2VkLiBUaGUgdG9vbGJhciBzaG93cyBubyBzbGljZSBjb250cm9sIGluIHZvbHVtZSAvIGlzb3N1cmZhY2VcbiAgICogbW9kZSwgYXMgUGxvdGx5J3MgaXNvc3VyZmFjZSBpZ25vcmVzIHRoZSBzbGljZSB0b28uKVxuICAgKi9cbiAgc2V0WigpOiB2b2lkIHtcbiAgICAvKiBub3RoaW5nIHRvIHN0ZXAgKi9cbiAgfVxuXG4gIC8qKiBUaGUgaW50ZW5zaXR5IGhpc3RvZ3JhbSBvZiB0aGUgYXNzZW1ibGVkIChkb3duc2FtcGxlZCkgdWludDggdm9sdW1lIGZvciB0aGUgcmVxdWVzdGVkXG4gICAqICBjaGFubmVsIChtdWx0aWNoYW5uZWwpIG9yIHRoZSBzaW5nbGUgZ3JheXNjYWxlIHZvbHVtZS4gKi9cbiAgaGlzdG9ncmFtKGNoYW5uZWw6IG51bWJlciwgYmluczogbnVtYmVyKTogSUhpc3RvZ3JhbSB8IG51bGwge1xuICAgIHJldHVybiBjaGFubmVsSGlzdG9ncmFtKHRoaXMuY2hhbm5lbERhdGEsIGNoYW5uZWwsIGJpbnMpO1xuICB9XG5cbiAgaXNvQ29udHJvbHMoKTogSUlzb3N1cmZhY2VDb250cm9scyB8IG51bGwge1xuICAgIGlmICghdGhpcy52aWV3KSByZXR1cm4gbnVsbDtcbiAgICByZXR1cm4ge1xuICAgICAgc2V0SXNvUmFuZ2U6IChpc29NaW46IG51bWJlciwgaXNvTWF4OiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgICAgLy8gQXBwbHkgdG8gZXZlcnkgY2hhbm5lbCdzIHZvbHVtZSBsYXllci5cbiAgICAgICAgZm9yIChjb25zdCBsYXllciBvZiB0aGlzLnZpZXc/LmxheWVycyA/PyBbXSkge1xuICAgICAgICAgIGxheWVyLmNvbnRyYXN0TGltaXRzID0gW2lzb01pbiwgaXNvTWF4XTtcbiAgICAgICAgICBsYXllci5yZW5kZXJpbmcgPSAnaXNvJztcbiAgICAgICAgICBsYXllci5pc29UaHJlc2hvbGQgPSAwLjU7XG4gICAgICAgIH1cbiAgICAgICAgdGhpcy5jdHgudmlld2VyLnJlcXVlc3RSZW5kZXIoKTtcbiAgICAgIH0sXG4gICAgfTtcbiAgfVxuXG4gIHN1cmZhY2UzZENvbnRyb2xzKCk6IElTdXJmYWNlM2RDb250cm9scyB8IG51bGwge1xuICAgIHJldHVybiB0aGlzLnZpZXcgPyBzdXJmYWNlM2RDb250cm9scyh0aGlzLmN0eCwgKCkgPT4gdGhpcy5naXptbykgOiBudWxsO1xuICB9XG5cbiAgZGlzcG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLmRpc3BsYXlTdWI/LnVuc3Vic2NyaWJlKCk7XG4gICAgdGhpcy5kaXNwbGF5U3ViID0gbnVsbDtcbiAgICB0aGlzLmdpem1vPy5kZXN0cm95KCk7XG4gICAgdGhpcy5naXptbyA9IG51bGw7XG4gICAgdGhpcy56SGFuZGxlPy5kZXN0cm95KCk7XG4gICAgdGhpcy56SGFuZGxlID0gbnVsbDtcbiAgICB0aGlzLndvcmxkQmFzZSA9IG51bGw7XG4gIH1cblxuICAvKipcbiAgICogUmVzdHJldGNoIHRoZSB2b2x1bWUncyBaIGhlaWdodCBsaXZlIChkcml2ZW4gYnkgdGhlIGluLXZpZXcge0BsaW5rIE5hcGFyaVZvbHVtZVpIYW5kbGV9KS4gT25seVxuICAgKiB0aGUgcGVyLWF4aXMgYHZveGVsU2l6ZWAgLyBheGVzIGRlcHRoIGNoYW5nZSDigJQgdGhlIHZveGVsIHRleHR1cmVzIGFyZSB1bnRvdWNoZWQg4oCUIHNvIGRyYWdnaW5nIGlzXG4gICAqIHNtb290aC4gYGZhY3RvcmAgaXMgcmVsYXRpdmUgdG8gdGhlIHZvbHVtZSdzIG5hdHVyYWwgcHJvcG9ydGlvbnMgKDEpLiBQZXJzaXN0cyBhY3Jvc3MgcmUtbW91bnRzXG4gICAqIChyZXNvbHV0aW9uIGNoYW5nZXMpIHNvIHRoZSBjaG9zZW4gaGVpZ2h0IHN0aWNrcy5cbiAgICovXG4gIHNldFpTY2FsZShmYWN0b3I6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHsgc2V0dGluZ3MgfSA9IHRoaXMuY3R4O1xuICAgIHNldHRpbmdzLnZvbHVtZVpTY2FsZSA9IE1hdGgubWluKDEwLCBNYXRoLm1heCgwLjEsIGZhY3RvcikpO1xuICAgIGNvbnN0IGJhc2UgPSB0aGlzLndvcmxkQmFzZTtcbiAgICBpZiAoIWJhc2UgfHwgIXRoaXMudmlldykgcmV0dXJuO1xuICAgIGNvbnN0IHdvcmxkWiA9IGJhc2UuZGVwdGggKiBzZXR0aW5ncy52b2x1bWVaU2NhbGU7XG4gICAgY29uc3QgdnNaID0gd29ybGRaIC8gdGhpcy5zYW1wbGVkRGVwdGg7XG4gICAgZm9yIChjb25zdCBsYXllciBvZiB0aGlzLnZpZXcubGF5ZXJzKSB7XG4gICAgICBjb25zdCBbc3gsIHN5XSA9IGxheWVyLnZveGVsU2l6ZTtcbiAgICAgIGxheWVyLnZveGVsU2l6ZSA9IFtzeCwgc3ksIHZzWl07XG4gICAgfVxuICAgIHRoaXMuZ2l6bW8/LnNldERlcHRoKHdvcmxkWiwgdGhpcy5heGVzTGFiZWxzKHsgd2lkdGg6IGJhc2Uud2lkdGgsIGhlaWdodDogYmFzZS5oZWlnaHQsIGRlcHRoOiB3b3JsZFogfSkpO1xuICAgIHRoaXMuekhhbmRsZT8ucmVwb3NpdGlvbigpO1xuICAgIHRoaXMuY3R4LnZpZXdlci5yZXF1ZXN0UmVuZGVyKCk7XG4gIH1cblxuICAvKiogVGhlIFgvWS9aIGF4aXMtZW5kIGxhYmVsIHNwZWNzIGZvciB0aGUgZ2l6bW8uIEFuY2hvcnMgYXJlIGluIHRoZSB2b2x1bWUncyBjZW50cmVkIHdvcmxkIGJveFxuICAgKiAgKG1hdGNoaW5nIHRoZSBBeGVzTGF5ZXIgZ2VvbWV0cnkpOyB0aGUgc2NhbGUgdGV4dCByZWZsZWN0cyB0aGUgRlVMTCBpbWFnZSBleHRlbnQg4oCUIHBoeXNpY2FsIMK1bVxuICAgKiAgd2hlbiDCtW0vcGl4ZWwgaXMga25vd24sIGVsc2UgcGl4ZWwgKFgvWSkgLyBzbGljZSAoWikgY291bnRzLiAqL1xuICBheGVzTGFiZWxzKHZvbDogQm94Myk6IEF4aXNMYWJlbFNwZWNbXSB7XG4gICAgY29uc3QgaHggPSB2b2wud2lkdGggLyAyO1xuICAgIGNvbnN0IGh5ID0gdm9sLmhlaWdodCAvIDI7XG4gICAgY29uc3QgaHogPSB2b2wuZGVwdGggLyAyO1xuICAgIC8vIE1lYXN1cmVkIGZyb20gdGhlIElNQUdFJ3Mgb3duIGV4dGVudCwgbmV2ZXIgZnJvbSB0aGUgd29ybGQgYm94OiB0aGUgYm94IGlzIGFcbiAgICAvLyBzaGFwZSAoYW5kIGZvciBhIHBoeXNpY2FsbHkgc2l6ZWQgdm9sdW1lIGl0IGlzIGFscmVhZHkgaW4gwrVtLCBzbyByZWFkaW5nIGFcbiAgICAvLyBwaXhlbCBjb3VudCBvZmYgaXQgYW5kIG11bHRpcGx5aW5nIGJ5IG1wcCB3b3VsZCBzY2FsZSB0aGUgbGFiZWwgdHdpY2UpLlxuICAgIGNvbnN0IHsgcHgsIG1wcCB9ID0gdGhpcy5pbWFnZUV4dGVudCgpO1xuICAgIGNvbnN0IGxlbiA9IChuOiBudW1iZXIsIHVtOiBudW1iZXIpOiBzdHJpbmcgPT4gKHVtID4gMCA/IGZvcm1hdExlbmd0aChuICogdW0sICfCtW0nKSA6IGAke259IHB4YCk7XG4gICAgcmV0dXJuIFtcbiAgICAgIHsgYW5jaG9yOiBbaHgsIC1oeSwgLWh6XSwgdGV4dDogYFggwrcgJHtsZW4ocHhbMF0sIG1wcFswXSl9YCwgY29sb3I6ICcjZWQ0NTQ1JyB9LFxuICAgICAgeyBhbmNob3I6IFstaHgsIGh5LCAtaHpdLCB0ZXh0OiBgWSDCtyAke2xlbihweFsxXSwgbXBwWzFdKX1gLCBjb2xvcjogJyM0ZGQ5NTknIH0sXG4gICAgICAvLyBQaHlzaWNhbCB3aGVuIHRoZSBzdGFjayBkZWNsYXJlcyBpdHMgc2xpY2Ugc3BhY2luZyAoYG1wcFpgKSDigJQgYSByZXNhbXBsZWRcbiAgICAgIC8vIHZvbHVtZSBrbm93cyBob3cgdGhpY2sgaXQgaXM7IGEgcGxhaW4gei1zdGFjayBjYW4gb25seSBzYXkgaG93IG1hbnkgc2xpY2VzLlxuICAgICAgeyBhbmNob3I6IFstaHgsIC1oeSwgaHpdLCB0ZXh0OiBgWiDCtyAke2xlbihweFsyXSwgbXBwWzJdKX1gLCBjb2xvcjogJyM2NjhjZmYnIH0sXG4gICAgXTtcbiAgfVxuXG4gIC8qKlxuICAgKiBUaGUgaW1hZ2UncyBkZWNsYXJlZCBleHRlbnQgaW4gcGl4ZWxzL3NsaWNlcywgYW5kIGl0cyBwaHlzaWNhbCBzcGFjaW5nIHBlclxuICAgKiBheGlzIGluIMK1bSAoMCA9IHVuZGVjbGFyZWQsIGFuZCB0aGVuIHRoYXQgYXhpcyByZWFkcyBpbiBwaXhlbHMpLlxuICAgKlxuICAgKiBPbmUgcGxhY2UsIGJlY2F1c2UgdGhlIHZvbHVtZSB3b3JsZCBib3ggYW5kIHRoZSBheGlzIGxhYmVscyBoYXZlIHRvIGFncmVlXG4gICAqIGFib3V0IHdoYXQgdGhlIGltYWdlJ3MgcmVhbCBkaW1lbnNpb25zIGFyZSDigJQgdGhlIHNhbXBsZWQgZ3JpZCBpcyBkZWNpbWF0ZWQgYW5kXG4gICAqIHNheXMgbm90aGluZyBhYm91dCBlaXRoZXIuXG4gICAqL1xuICBwcml2YXRlIGltYWdlRXh0ZW50KCk6IHsgcHg6IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTsgbXBwOiBbbnVtYmVyLCBudW1iZXIsIG51bWJlcl0gfSB7XG4gICAgY29uc3QgaW5mbyA9IHRoaXMuY3R4LmluZm8oKTtcbiAgICBjb25zdCBtZXRhID0gaW5mbz8uaW1hZ2VNZXRhPy5bMF07XG4gICAgY29uc3QgZGltcyA9IHRoaXMuZGltcztcbiAgICBjb25zdCBkZXNjID0gdGhpcy5jdHgudGlsZXMuY3VycmVudERlc2NyaXB0b3IoaW5mbyk7XG4gICAgY29uc3QgbXBwWCA9IGRlc2M/Lm1wcFggfHwgbWV0YT8ubXBwWCB8fCAwO1xuICAgIHJldHVybiB7XG4gICAgICBweDogW1xuICAgICAgICBkZXNjPy53aWR0aCA/PyBtZXRhPy54ID8/IGRpbXM/LndpZHRoID8/IDEsXG4gICAgICAgIGRlc2M/LmhlaWdodCA/PyBtZXRhPy55ID8/IGRpbXM/LmhlaWdodCA/PyAxLFxuICAgICAgICBzdGFja0RlcHRoKGluZm8pIHx8IGRpbXM/LmRlcHRoIHx8IDEsXG4gICAgICBdLFxuICAgICAgLy8gQSBkZXNjcmlwdG9yIHRoYXQgcmVwb3J0cyBvbmx5IG1wcFggaXMgc3F1YXJlLXBpeGVsIGJ5IGNvbnZlbnRpb24sIHdoaWNoIGlzXG4gICAgICAvLyB3aGF0IHRoZSAyRCBzY2FsZSBiYXIgYWxyZWFkeSBhc3N1bWVzIG9mIGl0LlxuICAgICAgbXBwOiBbbXBwWCwgZGVzYz8ubXBwWSB8fCBtZXRhPy5tcHBZIHx8IG1wcFgsIG1ldGE/Lm1wcFogfHwgMF0sXG4gICAgfTtcbiAgfVxuXG4gIC8qKiBUaGUgc3RvcmUncyBjb2xvcm1hcCwgcmV2ZXJzZSwgaW52ZXJ0IGFuZCBjaGFubmVsIHdpbmRvd3Mg4oaSIHRoZSB2b2x1bWUncyB0cmFuc2ZlciBmdW5jdGlvbjpcbiAgICogIGNvbG91ciAoY2hhbm5lbCB0aW50IG9yIHNlbGVjdGVkIGNvbG9ybWFwKSwgdGhlIGludGVuc2l0eSB3aW5kb3cgKG1pbi9tYXgg4oaSIGNvbnRyYXN0TGltaXRzKVxuICAgKiAgYW5kIGdhbW1hLCBtaXJyb3JpbmcgdGhlIGdyYXlzY2FsZSBpbWFnZSdzIGRpc3BsYXkgY29udHJvbHMgc28gdGhlIGhpc3RvZ3JhbSBwYW5lIGRyaXZlcyB0aGVcbiAgICogIDNEIHJlbmRlci4gKi9cbiAgcHJpdmF0ZSBmb2xsb3dEaXNwbGF5U3RhdGUoKTogdm9pZCB7XG4gICAgY29uc3QgeyBkaXNwbGF5IH0gPSB0aGlzLmN0eDtcbiAgICB0aGlzLmRpc3BsYXlTdWIgPSBkaXNwbGF5LndhdGNoKChjaGFubmVscykgPT4ge1xuICAgICAgY29uc3QgdmlldyA9IHRoaXMudmlldztcbiAgICAgIGlmICghdmlldykgcmV0dXJuO1xuICAgICAgaWYgKHRoaXMubXVsdGljaGFubmVsKSB7XG4gICAgICAgIC8vIEVhY2ggY2hhbm5lbCdzIGxheWVyIGlzIHRpbnRlZCBieSBpdHMgY29sb3VyIGFuZCBnZXRzIGl0cyBvd24gd2luZG93L2dhbW1hL3Zpc2liaWxpdHkuXG4gICAgICAgIHZpZXcubGF5ZXJzLmZvckVhY2goKF8sIGMpID0+IHtcbiAgICAgICAgICBjb25zdCBzdCA9IGNoYW5uZWxzLmZpbmQoKHMpID0+IHMuaW5kZXggPT09IGMpO1xuICAgICAgICAgIHZpZXcudXBkYXRlQ2hhbm5lbChjLCB7XG4gICAgICAgICAgICBjb2xvcm1hcDogZGlzcGxheS5jaGFubmVsVGludENvbG9ybWFwKHN0Py5jb2xvciA/PyAnI2ZmZmZmZicpLFxuICAgICAgICAgICAgaW52ZXJ0OiBkaXNwbGF5LmludmVydCxcbiAgICAgICAgICAgIC4uLihzdFxuICAgICAgICAgICAgICA/IHtcbiAgICAgICAgICAgICAgICAgIGNvbnRyYXN0TGltaXRzOiBbc3QubWluLCBzdC5tYXhdIGFzIFtudW1iZXIsIG51bWJlcl0sXG4gICAgICAgICAgICAgICAgICBnYW1tYTogdG9OYXBhcmlHYW1tYShzdC5nYW1tYSksIC8vIEltYWdlSiDOsyDihpIgbmFwYXJpLWpzIM6zXG4gICAgICAgICAgICAgICAgICB2aXNpYmxlOiBzdC52aXNpYmxlLFxuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgOiB7fSksXG4gICAgICAgICAgfSk7XG4gICAgICAgIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3Qgc3QgPSBjaGFubmVsc1swXTtcbiAgICAgICAgdmlldy51cGRhdGVDaGFubmVsKDAsIHtcbiAgICAgICAgICBjb2xvcm1hcDogZGlzcGxheS52b2x1bWVDb2xvcm1hcChzdCksXG4gICAgICAgICAgaW52ZXJ0OiBkaXNwbGF5LmludmVydCxcbiAgICAgICAgICAuLi4oc3QgPyB7IGNvbnRyYXN0TGltaXRzOiBbc3QubWluLCBzdC5tYXhdIGFzIFtudW1iZXIsIG51bWJlcl0sIGdhbW1hOiB0b05hcGFyaUdhbW1hKHN0LmdhbW1hKSB9IDoge30pLFxuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxufVxuXG4vKipcbiAqIE5BUEFSSV9TQ0FUVEVSM0QgKHJldmlldyBBcHBlbmRpeCBCLCBjbHVzdGVyIEgpOiB0aGUgZG93bnNhbXBsZWQgdm94ZWwgZ3JpZCBhcyBhIDNEIHBvaW50IGNsb3VkXG4gKiBjb2xvdXJlZCBieSBpbnRlbnNpdHkgKHRoZSBuYXBhcmktanMgYW5hbG9nIG9mIFBsb3RseSdzIHZveGVsIHNjYXR0ZXIzZCkuIEFzc2VtYmxlcyBhIGNvYXJzZVxuICogdm9sdW1lLCB0aGVuIGVtaXRzIGEgZmxhdC1zdHJpZGVkIHNhbXBsZSBvZiB2b3hlbHMgKGNhcHBlZCBhdCBgU0NBVFRFUjNEX01BWF9QT0lOVFNgKS5cbiAqL1xuZXhwb3J0IGNsYXNzIFNjYXR0ZXIzZFNjZW5lIGltcGxlbWVudHMgTmFwYXJpU2NlbmUge1xuICBwcml2YXRlIGxheWVyOiBQb2ludHMzRExheWVyIHwgbnVsbCA9IG51bGw7XG4gIC8qKiBUaGUgYXNzZW1ibGVkIHZvbHVtZSAoa2V5IDApLCBmb3IgdGhlIGludGVuc2l0eSBoaXN0b2dyYW0uICovXG4gIHByaXZhdGUgcmVhZG9ubHkgY2hhbm5lbERhdGEgPSBuZXcgTWFwPG51bWJlciwgVWludDhBcnJheT4oKTtcbiAgcHJpdmF0ZSBkaXNwbGF5U3ViOiBTdWJzY3JpcHRpb24gfCBudWxsID0gbnVsbDtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGN0eDogU2NlbmVDb250ZXh0LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaW5mbzogSUltYWdlSW5mbyB8IHVuZGVmaW5lZCxcbiAgKSB7fVxuXG4gIGFzeW5jIG1vdW50KCk6IFByb21pc2U8dm9pZD4ge1xuICAgIGNvbnN0IHsgY3R4IH0gPSB0aGlzO1xuICAgIGNvbnN0IHJlcyA9IHZvbHVtZVJlc29sdXRpb25Gb3IoY3R4LnNldHRpbmdzLnJlc29sdXRpb25TY2FsZSk7XG4gICAgY3R4LnN0YWNrLmxvYWRpbmcodHJ1ZSk7XG4gICAgY3R4LnN0YWNrLnByb2dyZXNzKDApO1xuICAgIGxldCB2b2w6IEFzc2VtYmxlZFZvbHVtZSB8IG51bGwgPSBudWxsO1xuICAgIHRyeSB7XG4gICAgICB2b2wgPSBhd2FpdCBhc3NlbWJsZShcbiAgICAgICAgY3R4LFxuICAgICAgICB0aGlzLmluZm8sXG4gICAgICAgIHsgbWF4U2xpY2U6IE1hdGgubWluKHJlcy5tYXhTbGljZSwgU0NBVFRFUjNEX01BWF9YWSksIHNsaWNlU3RlcDogcmVzLnNsaWNlU3RlcCB9LFxuICAgICAgICBjdHgubG9hZGluZygpLFxuICAgICAgKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgY3R4LnN0YWNrLmxvYWRpbmcoZmFsc2UpO1xuICAgICAgY3R4LnN0YWNrLnByb2dyZXNzKDApO1xuICAgIH1cbiAgICBpZiAoIXZvbCB8fCBjdHguc2lnbmFsLmFib3J0ZWQpIHJldHVybjtcblxuICAgIGNvbnN0IHsgZGF0YSwgd2lkdGgsIGhlaWdodCwgZGVwdGggfSA9IHZvbDtcbiAgICBjb25zdCB6U2NhbGUgPSBNYXRoLm1heCh3aWR0aCwgaGVpZ2h0KSAvIE1hdGgubWF4KDEsIGRlcHRoKTsgLy8g4omIIGN1YmljIGFzcGVjdFxuICAgIGNvbnN0IHRvdGFsID0gd2lkdGggKiBoZWlnaHQgKiBkZXB0aDtcbiAgICBjb25zdCBzdHJpZGUgPSBNYXRoLm1heCgxLCBNYXRoLmNlaWwodG90YWwgLyBTQ0FUVEVSM0RfTUFYX1BPSU5UUykpO1xuICAgIGNvbnN0IHBvczogbnVtYmVyW10gPSBbXTtcbiAgICBjb25zdCB2YWw6IG51bWJlcltdID0gW107XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0b3RhbDsgaSArPSBzdHJpZGUpIHtcbiAgICAgIGNvbnN0IHggPSBpICUgd2lkdGg7XG4gICAgICBjb25zdCB5ID0gTWF0aC5mbG9vcihpIC8gd2lkdGgpICUgaGVpZ2h0O1xuICAgICAgY29uc3QgemkgPSBNYXRoLmZsb29yKGkgLyAod2lkdGggKiBoZWlnaHQpKTtcbiAgICAgIHBvcy5wdXNoKHgsIHksIHppICogelNjYWxlKTtcbiAgICAgIHZhbC5wdXNoKGRhdGFbaV0pO1xuICAgIH1cblxuICAgIGNvbnN0IHN0ID0gY3R4LnN0b3JlLmN1cnJlbnRDaGFubmVsU3RhdGVzKClbMF07XG4gICAgdGhpcy5sYXllciA9IGN0eC52aWV3ZXIuYWRkUG9pbnRzM0QobmV3IEZsb2F0MzJBcnJheShwb3MpLCBuZXcgRmxvYXQzMkFycmF5KHZhbCksIHtcbiAgICAgIGNvbG9ybWFwOiBjdHguZGlzcGxheS52b2x1bWVDb2xvcm1hcChzdCksXG4gICAgICBjb250cmFzdExpbWl0czogW3N0Py5taW4gPz8gMCwgc3Q/Lm1heCA/PyAyNTVdLFxuICAgICAgaW52ZXJ0OiBjdHguZGlzcGxheS5pbnZlcnQsXG4gICAgICBzaXplOiAzLFxuICAgIH0pO1xuICAgIGN0eC5zZXRJbWFnZVNpemUod2lkdGgsIGhlaWdodCk7XG4gICAgLy8gRmVlZCB0aGUgaW50ZW5zaXR5IGhpc3RvZ3JhbSBmcm9tIHRoZSBhc3NlbWJsZWQgdm9sdW1lIChrZXkgMCkuXG4gICAgdGhpcy5jaGFubmVsRGF0YS5jbGVhcigpO1xuICAgIHRoaXMuY2hhbm5lbERhdGEuc2V0KDAsIGRhdGEpO1xuICAgIC8vIFN0b3JlIGNvbG9ybWFwIC8gcmV2ZXJzZSAvIGludmVydCAvIGNoYW5uZWwgd2luZG93IOKGkiB0aGUgY2xvdWQncyBjb2xvcm1hcCArIGNvbnRyYXN0LlxuICAgIHRoaXMuZGlzcGxheVN1YiA9IGN0eC5kaXNwbGF5LndhdGNoKChjaGFubmVscykgPT4ge1xuICAgICAgY29uc3QgbGF5ZXIgPSB0aGlzLmxheWVyO1xuICAgICAgaWYgKCFsYXllcikgcmV0dXJuO1xuICAgICAgY29uc3QgcyA9IGNoYW5uZWxzWzBdO1xuICAgICAgbGF5ZXIuY29sb3JtYXAgPSBjdHguZGlzcGxheS52b2x1bWVDb2xvcm1hcChzKTtcbiAgICAgIGxheWVyLmludmVydCA9IGN0eC5kaXNwbGF5LmludmVydDtcbiAgICAgIGlmIChzKSBsYXllci5jb250cmFzdExpbWl0cyA9IFtzLm1pbiwgcy5tYXhdO1xuICAgICAgY3R4LnZpZXdlci5yZXF1ZXN0UmVuZGVyKCk7XG4gICAgfSk7XG4gICAgY3R4LnRvb2xzLnNjaGVkdWxlUmVhZGJhY2soKTtcbiAgfVxuXG4gIC8qKiBUaGUgd2hvbGUgc3RhY2sgaXMgYWxyZWFkeSBvbiBzY3JlZW46IG5vIHBsYW5lIHRvIHN0ZXAuICovXG4gIHNldFooKTogdm9pZCB7XG4gICAgLyogbm90aGluZyB0byBzdGVwICovXG4gIH1cblxuICBoaXN0b2dyYW0oY2hhbm5lbDogbnVtYmVyLCBiaW5zOiBudW1iZXIpOiBJSGlzdG9ncmFtIHwgbnVsbCB7XG4gICAgcmV0dXJuIGNoYW5uZWxIaXN0b2dyYW0odGhpcy5jaGFubmVsRGF0YSwgY2hhbm5lbCwgYmlucyk7XG4gIH1cblxuICBzdXJmYWNlM2RDb250cm9scygpOiBJU3VyZmFjZTNkQ29udHJvbHMgfCBudWxsIHtcbiAgICByZXR1cm4gdGhpcy5sYXllciA/IHN1cmZhY2UzZENvbnRyb2xzKHRoaXMuY3R4LCAoKSA9PiBudWxsKSA6IG51bGw7XG4gIH1cblxuICBkaXNwb3NlKCk6IHZvaWQge1xuICAgIHRoaXMuZGlzcGxheVN1Yj8udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLmRpc3BsYXlTdWIgPSBudWxsO1xuICB9XG59XG4iXX0=
@@ -1,14 +1,14 @@
1
1
  /**
2
2
  * Draggable Z-height handle for the napari-js WebGPU volume (jit-ui#102). A small DOM grip is drawn
3
- * over the 3D canvas at the projected top-face centre of the volume box (reusing the axes-label
4
- * {@link projectPoint} projection, so it tracks the box as the volume orbits). Dragging it up makes
3
+ * over the 3D canvas at the projected top-face centre of the volume box (projected with napari-js's
4
+ * {@link projectPoint}, as the axes labels are, so it tracks the box as the volume orbits). Dragging it up makes
5
5
  * the volume taller, down makes it flatter — the host maps the drag to a Z-scale factor and
6
6
  * restretches the volume + axes live (only the model matrix changes; the voxel texture is untouched).
7
7
  *
8
- * Direct-manipulation counterpart of {@link NapariAxesLabels}: both are absolute-positioned overlays
9
- * updated on every `camera3d.changed`, but this one accepts pointer input.
8
+ * Direct-manipulation counterpart of napari-js's `AxesLabelsOverlay`: both are absolute-positioned
9
+ * overlays updated on every `camera3d.changed`, but this one accepts pointer input.
10
10
  */
11
- import { projectPoint } from './napari-axes-labels';
11
+ import { projectPoint } from 'napari-js';
12
12
  const DEFAULTS = { pixelsPerDouble: 180, minScale: 0.1, maxScale: 10 };
13
13
  export class NapariVolumeZHandle {
14
14
  constructor(host, camera3d, opts) {
@@ -123,4 +123,4 @@ export class NapariVolumeZHandle {
123
123
  this.el.parentNode?.removeChild(this.el);
124
124
  }
125
125
  }
126
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXZvbHVtZS16LWhhbmRsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvaW1wbGVtZW50YXRpb25zL25hcGFyaS1qcy9uYXBhcmktdm9sdW1lLXotaGFuZGxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7R0FTRztBQUNILE9BQU8sRUFBcUIsWUFBWSxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFnQnZFLE1BQU0sUUFBUSxHQUFHLEVBQUUsZUFBZSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUV2RSxNQUFNLE9BQU8sbUJBQW1CO0lBVTlCLFlBQ21CLElBQWlCLEVBQ2pCLFFBQTJCLEVBQzVDLElBQTBCO1FBRlQsU0FBSSxHQUFKLElBQUksQ0FBYTtRQUNqQixhQUFRLEdBQVIsUUFBUSxDQUFtQjtRQVB0QyxZQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ2YsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsZUFBVSxHQUFHLENBQUMsQ0FBQztRQXlFTixrQkFBYSxHQUFHLENBQUMsQ0FBZSxFQUFRLEVBQUU7WUFDekQsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ25CLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDeEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDO1FBRWUsa0JBQWEsR0FBRyxDQUFDLENBQWUs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QUM7UUFDL0QsSUFBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxhQUFhLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsV0FBVyxFQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQztRQUMzRCxJQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLGVBQWUsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDL0QsSUFBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxVQUFVLEVBQUUsSUFBSSxDQUFDLGFBQWEsQ0FBQyxDQUFDO1FBQzVELElBQUksQ0FBQyxFQUFFLENBQUMsVUFBVSxFQUFFLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDM0MsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBEcmFnZ2FibGUgWi1oZWlnaHQgaGFuZGxlIGZvciB0aGUgbmFwYXJpLWpzIFdlYkdQVSB2b2x1bWUgKGppdC11aSMxMDIpLiBBIHNtYWxsIERPTSBncmlwIGlzIGRyYXduXG4gKiBvdmVyIHRoZSAzRCBjYW52YXMgYXQgdGhlIHByb2plY3RlZCB0b3AtZmFjZSBjZW50cmUgb2YgdGhlIHZvbHVtZSBib3ggKHJldXNpbmcgdGhlIGF4ZXMtbGFiZWxcbiAqIHtAbGluayBwcm9qZWN0UG9pbnR9IHByb2plY3Rpb24sIHNvIGl0IHRyYWNrcyB0aGUgYm94IGFzIHRoZSB2b2x1bWUgb3JiaXRzKS4gRHJhZ2dpbmcgaXQgdXAgbWFrZXNcbiAqIHRoZSB2b2x1bWUgdGFsbGVyLCBkb3duIG1ha2VzIGl0IGZsYXR0ZXIg4oCUIHRoZSBob3N0IG1hcHMgdGhlIGRyYWcgdG8gYSBaLXNjYWxlIGZhY3RvciBhbmRcbiAqIHJlc3RyZXRjaGVzIHRoZSB2b2x1bWUgKyBheGVzIGxpdmUgKG9ubHkgdGhlIG1vZGVsIG1hdHJpeCBjaGFuZ2VzOyB0aGUgdm94ZWwgdGV4dHVyZSBpcyB1bnRvdWNoZWQpLlxuICpcbiAqIERpcmVjdC1tYW5pcHVsYXRpb24gY291bnRlcnBhcnQgb2Yge0BsaW5rIE5hcGFyaUF4ZXNMYWJlbHN9OiBib3RoIGFyZSBhYnNvbHV0ZS1wb3NpdGlvbmVkIG92ZXJsYXlzXG4gKiB1cGRhdGVkIG9uIGV2ZXJ5IGBjYW1lcmEzZC5jaGFuZ2VkYCwgYnV0IHRoaXMgb25lIGFjY2VwdHMgcG9pbnRlciBpbnB1dC5cbiAqL1xuaW1wb3J0IHsgQXhlc0xhYmVsQ2FtZXJhM0QsIHByb2plY3RQb2ludCB9IGZyb20gJy4vbmFwYXJpLWF4ZXMtbGFiZWxzJztcblxuZXhwb3J0IGludGVyZmFjZSBWb2x1bWVaSGFuZGxlT3B0aW9ucyB7XG4gIC8qKiBDdXJyZW50IHRvcC1mYWNlLWNlbnRyZSB3b3JsZCBwb2ludCAodGhlIGJveCBpcyBjZW50cmVkIGF0IHRoZSBvcmlnaW4sIHNvIGBbMCwgMCwgK2hhbGZaXWApLiAqL1xuICB0b3BBbmNob3I6ICgpID0+IFtudW1iZXIsIG51bWJlciwgbnVtYmVyXTtcbiAgLyoqIFRoZSBjdXJyZW50IFotc2NhbGUgZmFjdG9yICgxID0gdGhlIHZvbHVtZSdzIGRlZmF1bHQgcHJvcG9ydGlvbnMpLiAqL1xuICBnZXRTY2FsZTogKCkgPT4gbnVtYmVyO1xuICAvKiogQXBwbHkgYSBuZXcgWi1zY2FsZSBmYWN0b3Ig4oCUIHRoZSBob3N0IHJlc3RyZXRjaGVzIHRoZSB2b2x1bWUgKyBheGVzIGFuZCByZXBvc2l0aW9ucyBvdmVybGF5cy4gKi9cbiAgc2V0U2NhbGU6IChzY2FsZTogbnVtYmVyKSA9PiB2b2lkO1xuICAvKiogVmVydGljYWwgZHJhZyAocHgpIGZvciBvbmUgZG91YmxpbmcvaGFsdmluZyBvZiB0aGUgWiBoZWlnaHQuIExhcmdlciA9IGxlc3Mgc2Vuc2l0aXZlLiAqL1xuICBwaXhlbHNQZXJEb3VibGU/OiBudW1iZXI7XG4gIC8qKiBDbGFtcCBmb3IgdGhlIFotc2NhbGUgZmFjdG9yLiAqL1xuICBtaW5TY2FsZT86IG51bWJlcjtcbiAgbWF4U2NhbGU/OiBudW1iZXI7XG59XG5cbmNvbnN0IERFRkFVTFRTID0geyBwaXhlbHNQZXJEb3VibGU6IDE4MCwgbWluU2NhbGU6IDAuMSwgbWF4U2NhbGU6IDEwIH07XG5cbmV4cG9ydCBjbGFzcyBOYXBhcmlWb2x1bWVaSGFuZGxlIHtcbiAgcHJpdmF0ZSByZWFkb25seSBlbDogSFRNTERpdkVsZW1lbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgZGlzY29ubmVjdENhbWVyYTogKCkgPT4gdm9pZDtcbiAgcHJpdmF0ZSByZWFkb25seSByZXNpemVPYnNlcnZlcj86IFJlc2l6ZU9ic2VydmVyO1xuICBwcml2YXRlIHJlYWRvbmx5IG9wdHM6IFJlcXVpcmVkPFZvbHVtZVpIYW5kbGVPcHRpb25zPjtcbiAgcHJpdmF0ZSB2aXNpYmxlID0gdHJ1ZTtcbiAgcHJpdmF0ZSBkcmFnZ2luZyA9IGZhbHNlO1xuICBwcml2YXRlIHN0YXJ0WSA9IDA7XG4gIHByaXZhdGUgc3RhcnRTY2FsZSA9IDE7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSByZWFkb25seSBob3N0OiBIVE1MRWxlbWVudCxcbiAgICBwcml2YXRlIHJlYWRvbmx5IGNhbWVyYTNkOiBBeGVzTGFiZWxDYW1lcmEzRCxcbiAgICBvcHRzOiBWb2x1bWVaSGFuZGxlT3B0aW9ucyxcbiAgKSB7XG4gICAgdGhpcy5vcHRzID0geyAuLi5ERUZBVUxUUywgLi4ub3B0cyB9O1xuICAgIGlmIChnZXRDb21wdXRlZFN0eWxlKGhvc3QpLnBvc2l0aW9uID09PSAnc3RhdGljJykgaG9zdC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG5cbiAgICB0aGlzLmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLmVsLnN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIHpJbmRleDogJzMxJyxcbiAgICAgIHdpZHRoOiAnMjJweCcsXG4gICAgICBoZWlnaHQ6ICcyMnB4JyxcbiAgICAgIG1hcmdpbkxlZnQ6ICctMTFweCcsXG4gICAgICBtYXJnaW5Ub3A6ICctMTFweCcsXG4gICAgICBib3JkZXJSYWRpdXM6ICc1MCUnLFxuICAgICAgYmFja2dyb3VuZDogJ3JnYmEoMTAyLDE0MCwyNTUsMC44NSknLCAvLyBtYXRjaGVzIHRoZSBaIGF4aXMgY29sb3VyICgjNjY4Y2ZmKVxuICAgICAgYm9yZGVyOiAnMS41cHggc29saWQgI2ZmZicsXG4gICAgICBib3hTaGFkb3c6ICcwIDAgNHB4IHJnYmEoMCwwLDAsMC42KScsXG4gICAgICBjb2xvcjogJyNmZmYnLFxuICAgICAgZm9udDogJzEzcHggc2Fucy1zZXJpZicsXG4gICAgICBsaW5lSGVpZ2h0OiAnMjBweCcsXG4gICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgY3Vyc29yOiAnbnMtcmVzaXplJyxcbiAgICAgIHRvdWNoQWN0aW9uOiAnbm9uZScsXG4gICAgICB1c2VyU2VsZWN0OiAnbm9uZScsXG4gICAgfSBhcyBQYXJ0aWFsPENTU1N0eWxlRGVjbGFyYXRpb24+KTtcbiAgICB0aGlzLmVsLnRleHRDb250ZW50ID0gJ+KGlSc7XG4gICAgdGhpcy5lbC50aXRsZSA9ICdEcmFnIHRvIGNoYW5nZSB0aGUgdm9sdW1lIGhlaWdodCAoWikuIERvdWJsZS1jbGljayB0byByZXNldC4nO1xuICAgIHRoaXMuaG9zdC5hcHBlbmRDaGlsZCh0aGlzLmVsKTtcblxuICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCB0aGlzLm9uUG9pbnRlckRvd24pO1xuICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCB0aGlzLm9uUG9pbnRlck1vdmUpO1xuICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCdkYmxjbGljaycsIHRoaXMub25Eb3VibGVDbGljayk7XG5cbiAgICB0aGlzLmRpc2Nvbm5lY3RDYW1lcmEgPSB0aGlzLmNhbWVyYTNkLmNoYW5nZWQuY29ubmVjdCgoKSA9PiB0aGlzLnJlcG9zaXRpb24oKSk7XG4gICAgaWYgKHR5cGVvZiBSZXNpemVPYnNlcnZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4gdGhpcy5yZXBvc2l0aW9uKCkpO1xuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlci5vYnNlcnZlKHRoaXMuaG9zdCk7XG4gICAgfVxuICAgIHRoaXMucmVwb3NpdGlvbigpO1xuICB9XG5cbiAgc2V0VmlzaWJsZSh2aXNpYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy52aXNpYmxlID0gdmlzaWJsZTtcbiAgICB0aGlzLnJlcG9zaXRpb24oKTtcbiAgfVxuXG4gIC8qKiBSZXByb2plY3QgdGhlIGhhbmRsZSB0byB0aGUgY3VycmVudCB0b3AtZmFjZSBhbmNob3IuIENhbGxlZCBvbiBjYW1lcmEgbW92ZSwgcmVzaXplLCBhbmQgYWZ0ZXJcbiAgICogIHRoZSBob3N0IGFwcGxpZXMgYSBuZXcgc2NhbGUgKHNvIHRoZSBncmlwIGZvbGxvd3MgdGhlIGdyb3dpbmcvc2hyaW5raW5nIGJveCkuICovXG4gIHJlcG9zaXRpb24oKTogdm9pZCB7XG4gICAgY29uc3QgdncgPSB0aGlzLmhvc3QuY2xpZW50V2lkdGg7XG4gICAgY29uc3QgdmggPSB0aGlzLmhvc3QuY2xpZW50SGVpZ2h0O1xuICAgIGlmICghdGhpcy52aXNpYmxlIHx8IHZ3IDw9IDAgfHwgdmggPD0gMCkge1xuICAgICAgdGhpcy5lbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtdnAgPSB0aGlzLmNhbWVyYTNkLnZpZXdQcm9qZWN0aW9uKHZ3LCB2aCk7XG4gICAgY29uc3QgcyA9IHByb2plY3RQb2ludChtdnAsIHRoaXMub3B0cy50b3BBbmNob3IoKSwgdncsIHZoKTtcbiAgICBpZiAoIXMudmlzaWJsZSkge1xuICAgICAgdGhpcy5lbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVsLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICB0aGlzLmVsLnN0eWxlLmxlZnQgPSBgJHtzLnh9cHhgO1xuICAgIHRoaXMuZWwuc3R5bGUudG9wID0gYCR7cy55fXB4YDtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgb25Qb2ludGVyRG93biA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgICB0aGlzLnN0YXJ0WSA9IGUuY2xpZW50WTtcbiAgICB0aGlzLnN0YXJ0U2NhbGUgPSB0aGlzLm9wdHMuZ2V0U2NhbGUoKTtcbiAgICB0aGlzLmVsLnNldFBvaW50ZXJDYXB0dXJlPy4oZS5wb2ludGVySWQpO1xuICB9O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgb25Qb2ludGVyTW92ZSA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAoIXRoaXMuZHJhZ2dpbmcpIHJldHVybjtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAvLyBVcCAobmVnYXRpdmUgZHkpIOKGkiB0YWxsZXIuIEV4cG9uZW50aWFsIHNvIGVhY2ggYHBpeGVsc1BlckRvdWJsZWAgcHggZG91Ymxlcy9oYWx2ZXMgdGhlIGhlaWdodC5cbiAgICBjb25zdCBkeSA9IGUuY2xpZW50WSAtIHRoaXMuc3RhcnRZO1xuICAgIGNvbnN0IGZhY3RvciA9IE1hdGgucG93KDIsIC1keSAvIHRoaXMub3B0cy5waXhlbHNQZXJEb3VibGUpO1xuICAgIGNvbnN0IG5leHQgPSBNYXRoLm1pbihcbiAgICAgIHRoaXMub3B0cy5tYXhTY2FsZSxcbiAgICAgIE1hdGgubWF4KHRoaXMub3B0cy5taW5TY2FsZSwgdGhpcy5zdGFydFNjYWxlICogZmFjdG9yKSxcbiAgICApO1xuICAgIHRoaXMub3B0cy5zZXRTY2FsZShuZXh0KTtcbiAgICB0aGlzLnJlcG9zaXRpb24oKTtcbiAgfTtcblxuICBwcml2YXRlIHJlYWRvbmx5IG9uUG9pbnRlclVwID0gKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGlmICghdGhpcy5kcmFnZ2luZykgcmV0dXJuO1xuICAgIHRoaXMuZHJhZ2dpbmcgPSBmYWxzZTtcbiAgICBpZiAodGhpcy5lbC5oYXNQb2ludGVyQ2FwdHVyZT8uKGUucG9pbnRlcklkKSkgdGhpcy5lbC5yZWxlYXNlUG9pbnRlckNhcHR1cmU/LihlLnBvaW50ZXJJZCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvbkRvdWJsZUNsaWNrID0gKGU6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLm9wdHMuc2V0U2NhbGUoMSk7XG4gICAgdGhpcy5yZXBvc2l0aW9uKCk7XG4gIH07XG5cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLmRpc2Nvbm5lY3RDYW1lcmEoKTtcbiAgICB0aGlzLnJlc2l6ZU9ic2VydmVyPy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIHRoaXMub25Qb2ludGVyRG93bik7XG4gICAgdGhpcy5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMub25Qb2ludGVyTW92ZSk7XG4gICAgdGhpcy5lbC5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVydXAnLCB0aGlzLm9uUG9pbnRlclVwKTtcbiAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJjYW5jZWwnLCB0aGlzLm9uUG9pbnRlclVwKTtcbiAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2RibGNsaWNrJywgdGhpcy5vbkRvdWJsZUNsaWNrKTtcbiAgICB0aGlzLmVsLnBhcmVudE5vZGU/LnJlbW92ZUNoaWxkKHRoaXMuZWwpO1xuICB9XG59XG4iXX0=
126
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXZvbHVtZS16LWhhbmRsZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3NyYy9saWIvaW1wbGVtZW50YXRpb25zL25hcGFyaS1qcy9uYXBhcmktdm9sdW1lLXotaGFuZGxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7R0FTRztBQUNILE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFzQnpDLE1BQU0sUUFBUSxHQUFHLEVBQUUsZUFBZSxFQUFFLEdBQUcsRUFBRSxRQUFRLEVBQUUsR0FBRyxFQUFFLFFBQVEsRUFBRSxFQUFFLEVBQUUsQ0FBQztBQUV2RSxNQUFNLE9BQU8sbUJBQW1CO0lBVTlCLFlBQ21CLElBQWlCLEVBQ2pCLFFBQXlCLEVBQzFDLElBQTBCO1FBRlQsU0FBSSxHQUFKLElBQUksQ0FBYTtRQUNqQixhQUFRLEdBQVIsUUFBUSxDQUFpQjtRQVBwQyxZQUFPLEdBQUcsSUFBSSxDQUFDO1FBQ2YsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixXQUFNLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsZUFBVSxHQUFHLENBQUMsQ0FBQztRQXlFTixrQkFBYSxHQUFHLENBQUMsQ0FBZSxFQUFRLEVBQUU7WUFDekQsQ0FBQyxDQUFDLGNBQWMsRUFBRSxDQUFDO1lBQ25CLENBQUMsQ0FBQyxlQUFlLEVBQUUsQ0FBQztZQUNwQixJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztZQUNyQixJQUFJLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxPQUFPLENBQUM7WUFDeEIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFFBQVEsRUFBRSxDQUFDO1lBQ3ZDLElBQUksQ0FBQyxFQUFFLENBQUMsaUJBQWlCLEVBQUUsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUM7UUFDM0MsQ0FBQyxDQUFDO1FBRWUsa0JBQWEsR0FBRyxDQUFDLENBQWUsRUFB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Qy9ELElBQUksQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUMvRCxJQUFJLENBQUMsRUFBRSxDQUFDLG1CQUFtQixDQUFDLFdBQVcsRUFBRSxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLEVBQUUsQ0FBQyxtQkFBbUIsQ0FBQyxlQUFlLEVBQUUsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQy9ELElBQUksQ0FBQyxFQUFFLENBQUMsbUJBQW1CLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztRQUM1RCxJQUFJLENBQUMsRUFBRSxDQUFDLFVBQVUsRUFBRSxXQUFXLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogRHJhZ2dhYmxlIFotaGVpZ2h0IGhhbmRsZSBmb3IgdGhlIG5hcGFyaS1qcyBXZWJHUFUgdm9sdW1lIChqaXQtdWkjMTAyKS4gQSBzbWFsbCBET00gZ3JpcCBpcyBkcmF3blxuICogb3ZlciB0aGUgM0QgY2FudmFzIGF0IHRoZSBwcm9qZWN0ZWQgdG9wLWZhY2UgY2VudHJlIG9mIHRoZSB2b2x1bWUgYm94IChwcm9qZWN0ZWQgd2l0aCBuYXBhcmktanMnc1xuICoge0BsaW5rIHByb2plY3RQb2ludH0sIGFzIHRoZSBheGVzIGxhYmVscyBhcmUsIHNvIGl0IHRyYWNrcyB0aGUgYm94IGFzIHRoZSB2b2x1bWUgb3JiaXRzKS4gRHJhZ2dpbmcgaXQgdXAgbWFrZXNcbiAqIHRoZSB2b2x1bWUgdGFsbGVyLCBkb3duIG1ha2VzIGl0IGZsYXR0ZXIg4oCUIHRoZSBob3N0IG1hcHMgdGhlIGRyYWcgdG8gYSBaLXNjYWxlIGZhY3RvciBhbmRcbiAqIHJlc3RyZXRjaGVzIHRoZSB2b2x1bWUgKyBheGVzIGxpdmUgKG9ubHkgdGhlIG1vZGVsIG1hdHJpeCBjaGFuZ2VzOyB0aGUgdm94ZWwgdGV4dHVyZSBpcyB1bnRvdWNoZWQpLlxuICpcbiAqIERpcmVjdC1tYW5pcHVsYXRpb24gY291bnRlcnBhcnQgb2YgbmFwYXJpLWpzJ3MgYEF4ZXNMYWJlbHNPdmVybGF5YDogYm90aCBhcmUgYWJzb2x1dGUtcG9zaXRpb25lZFxuICogb3ZlcmxheXMgdXBkYXRlZCBvbiBldmVyeSBgY2FtZXJhM2QuY2hhbmdlZGAsIGJ1dCB0aGlzIG9uZSBhY2NlcHRzIHBvaW50ZXIgaW5wdXQuXG4gKi9cbmltcG9ydCB7IHByb2plY3RQb2ludCB9IGZyb20gJ25hcGFyaS1qcyc7XG5cbi8qKiBUaGUgc2xpY2Ugb2YgbmFwYXJpJ3MgQ2FtZXJhM0QgdGhlIGhhbmRsZSByZWFkcy4gYHZpZXdQcm9qZWN0aW9uYCBpcyBjb2x1bW4tbWFqb3IgKGdsLW1hdHJpeCkuICovXG5leHBvcnQgaW50ZXJmYWNlIFpIYW5kbGVDYW1lcmEzRCB7XG4gIHZpZXdQcm9qZWN0aW9uKHZ3OiBudW1iZXIsIHZoOiBudW1iZXIpOiBBcnJheUxpa2U8bnVtYmVyPjtcbiAgcmVhZG9ubHkgY2hhbmdlZDogeyBjb25uZWN0KGxpc3RlbmVyOiAoKSA9PiB2b2lkKTogKCkgPT4gdm9pZCB9O1xufVxuXG5leHBvcnQgaW50ZXJmYWNlIFZvbHVtZVpIYW5kbGVPcHRpb25zIHtcbiAgLyoqIEN1cnJlbnQgdG9wLWZhY2UtY2VudHJlIHdvcmxkIHBvaW50ICh0aGUgYm94IGlzIGNlbnRyZWQgYXQgdGhlIG9yaWdpbiwgc28gYFswLCAwLCAraGFsZlpdYCkuICovXG4gIHRvcEFuY2hvcjogKCkgPT4gW251bWJlciwgbnVtYmVyLCBudW1iZXJdO1xuICAvKiogVGhlIGN1cnJlbnQgWi1zY2FsZSBmYWN0b3IgKDEgPSB0aGUgdm9sdW1lJ3MgZGVmYXVsdCBwcm9wb3J0aW9ucykuICovXG4gIGdldFNjYWxlOiAoKSA9PiBudW1iZXI7XG4gIC8qKiBBcHBseSBhIG5ldyBaLXNjYWxlIGZhY3RvciDigJQgdGhlIGhvc3QgcmVzdHJldGNoZXMgdGhlIHZvbHVtZSArIGF4ZXMgYW5kIHJlcG9zaXRpb25zIG92ZXJsYXlzLiAqL1xuICBzZXRTY2FsZTogKHNjYWxlOiBudW1iZXIpID0+IHZvaWQ7XG4gIC8qKiBWZXJ0aWNhbCBkcmFnIChweCkgZm9yIG9uZSBkb3VibGluZy9oYWx2aW5nIG9mIHRoZSBaIGhlaWdodC4gTGFyZ2VyID0gbGVzcyBzZW5zaXRpdmUuICovXG4gIHBpeGVsc1BlckRvdWJsZT86IG51bWJlcjtcbiAgLyoqIENsYW1wIGZvciB0aGUgWi1zY2FsZSBmYWN0b3IuICovXG4gIG1pblNjYWxlPzogbnVtYmVyO1xuICBtYXhTY2FsZT86IG51bWJlcjtcbn1cblxuY29uc3QgREVGQVVMVFMgPSB7IHBpeGVsc1BlckRvdWJsZTogMTgwLCBtaW5TY2FsZTogMC4xLCBtYXhTY2FsZTogMTAgfTtcblxuZXhwb3J0IGNsYXNzIE5hcGFyaVZvbHVtZVpIYW5kbGUge1xuICBwcml2YXRlIHJlYWRvbmx5IGVsOiBIVE1MRGl2RWxlbWVudDtcbiAgcHJpdmF0ZSByZWFkb25seSBkaXNjb25uZWN0Q2FtZXJhOiAoKSA9PiB2b2lkO1xuICBwcml2YXRlIHJlYWRvbmx5IHJlc2l6ZU9ic2VydmVyPzogUmVzaXplT2JzZXJ2ZXI7XG4gIHByaXZhdGUgcmVhZG9ubHkgb3B0czogUmVxdWlyZWQ8Vm9sdW1lWkhhbmRsZU9wdGlvbnM+O1xuICBwcml2YXRlIHZpc2libGUgPSB0cnVlO1xuICBwcml2YXRlIGRyYWdnaW5nID0gZmFsc2U7XG4gIHByaXZhdGUgc3RhcnRZID0gMDtcbiAgcHJpdmF0ZSBzdGFydFNjYWxlID0gMTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIHJlYWRvbmx5IGhvc3Q6IEhUTUxFbGVtZW50LFxuICAgIHByaXZhdGUgcmVhZG9ubHkgY2FtZXJhM2Q6IFpIYW5kbGVDYW1lcmEzRCxcbiAgICBvcHRzOiBWb2x1bWVaSGFuZGxlT3B0aW9ucyxcbiAgKSB7XG4gICAgdGhpcy5vcHRzID0geyAuLi5ERUZBVUxUUywgLi4ub3B0cyB9O1xuICAgIGlmIChnZXRDb21wdXRlZFN0eWxlKGhvc3QpLnBvc2l0aW9uID09PSAnc3RhdGljJykgaG9zdC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG5cbiAgICB0aGlzLmVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCgnZGl2Jyk7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLmVsLnN0eWxlLCB7XG4gICAgICBwb3NpdGlvbjogJ2Fic29sdXRlJyxcbiAgICAgIHpJbmRleDogJzMxJyxcbiAgICAgIHdpZHRoOiAnMjJweCcsXG4gICAgICBoZWlnaHQ6ICcyMnB4JyxcbiAgICAgIG1hcmdpbkxlZnQ6ICctMTFweCcsXG4gICAgICBtYXJnaW5Ub3A6ICctMTFweCcsXG4gICAgICBib3JkZXJSYWRpdXM6ICc1MCUnLFxuICAgICAgYmFja2dyb3VuZDogJ3JnYmEoMTAyLDE0MCwyNTUsMC44NSknLCAvLyBtYXRjaGVzIHRoZSBaIGF4aXMgY29sb3VyICgjNjY4Y2ZmKVxuICAgICAgYm9yZGVyOiAnMS41cHggc29saWQgI2ZmZicsXG4gICAgICBib3hTaGFkb3c6ICcwIDAgNHB4IHJnYmEoMCwwLDAsMC42KScsXG4gICAgICBjb2xvcjogJyNmZmYnLFxuICAgICAgZm9udDogJzEzcHggc2Fucy1zZXJpZicsXG4gICAgICBsaW5lSGVpZ2h0OiAnMjBweCcsXG4gICAgICB0ZXh0QWxpZ246ICdjZW50ZXInLFxuICAgICAgY3Vyc29yOiAnbnMtcmVzaXplJyxcbiAgICAgIHRvdWNoQWN0aW9uOiAnbm9uZScsXG4gICAgICB1c2VyU2VsZWN0OiAnbm9uZScsXG4gICAgfSBhcyBQYXJ0aWFsPENTU1N0eWxlRGVjbGFyYXRpb24+KTtcbiAgICB0aGlzLmVsLnRleHRDb250ZW50ID0gJ+KGlSc7XG4gICAgdGhpcy5lbC50aXRsZSA9ICdEcmFnIHRvIGNoYW5nZSB0aGUgdm9sdW1lIGhlaWdodCAoWikuIERvdWJsZS1jbGljayB0byByZXNldC4nO1xuICAgIHRoaXMuaG9zdC5hcHBlbmRDaGlsZCh0aGlzLmVsKTtcblxuICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmRvd24nLCB0aGlzLm9uUG9pbnRlckRvd24pO1xuICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCB0aGlzLm9uUG9pbnRlck1vdmUpO1xuICAgIHRoaXMuZWwuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVyY2FuY2VsJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5lbC5hZGRFdmVudExpc3RlbmVyKCdkYmxjbGljaycsIHRoaXMub25Eb3VibGVDbGljayk7XG5cbiAgICB0aGlzLmRpc2Nvbm5lY3RDYW1lcmEgPSB0aGlzLmNhbWVyYTNkLmNoYW5nZWQuY29ubmVjdCgoKSA9PiB0aGlzLnJlcG9zaXRpb24oKSk7XG4gICAgaWYgKHR5cGVvZiBSZXNpemVPYnNlcnZlciAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICAgIHRoaXMucmVzaXplT2JzZXJ2ZXIgPSBuZXcgUmVzaXplT2JzZXJ2ZXIoKCkgPT4gdGhpcy5yZXBvc2l0aW9uKCkpO1xuICAgICAgdGhpcy5yZXNpemVPYnNlcnZlci5vYnNlcnZlKHRoaXMuaG9zdCk7XG4gICAgfVxuICAgIHRoaXMucmVwb3NpdGlvbigpO1xuICB9XG5cbiAgc2V0VmlzaWJsZSh2aXNpYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy52aXNpYmxlID0gdmlzaWJsZTtcbiAgICB0aGlzLnJlcG9zaXRpb24oKTtcbiAgfVxuXG4gIC8qKiBSZXByb2plY3QgdGhlIGhhbmRsZSB0byB0aGUgY3VycmVudCB0b3AtZmFjZSBhbmNob3IuIENhbGxlZCBvbiBjYW1lcmEgbW92ZSwgcmVzaXplLCBhbmQgYWZ0ZXJcbiAgICogIHRoZSBob3N0IGFwcGxpZXMgYSBuZXcgc2NhbGUgKHNvIHRoZSBncmlwIGZvbGxvd3MgdGhlIGdyb3dpbmcvc2hyaW5raW5nIGJveCkuICovXG4gIHJlcG9zaXRpb24oKTogdm9pZCB7XG4gICAgY29uc3QgdncgPSB0aGlzLmhvc3QuY2xpZW50V2lkdGg7XG4gICAgY29uc3QgdmggPSB0aGlzLmhvc3QuY2xpZW50SGVpZ2h0O1xuICAgIGlmICghdGhpcy52aXNpYmxlIHx8IHZ3IDw9IDAgfHwgdmggPD0gMCkge1xuICAgICAgdGhpcy5lbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBtdnAgPSB0aGlzLmNhbWVyYTNkLnZpZXdQcm9qZWN0aW9uKHZ3LCB2aCk7XG4gICAgY29uc3QgcyA9IHByb2plY3RQb2ludChtdnAsIHRoaXMub3B0cy50b3BBbmNob3IoKSwgdncsIHZoKTtcbiAgICBpZiAoIXMudmlzaWJsZSkge1xuICAgICAgdGhpcy5lbC5zdHlsZS5kaXNwbGF5ID0gJ25vbmUnO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICB0aGlzLmVsLnN0eWxlLmRpc3BsYXkgPSAnJztcbiAgICB0aGlzLmVsLnN0eWxlLmxlZnQgPSBgJHtzLnh9cHhgO1xuICAgIHRoaXMuZWwuc3R5bGUudG9wID0gYCR7cy55fXB4YDtcbiAgfVxuXG4gIHByaXZhdGUgcmVhZG9ubHkgb25Qb2ludGVyRG93biA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB0aGlzLmRyYWdnaW5nID0gdHJ1ZTtcbiAgICB0aGlzLnN0YXJ0WSA9IGUuY2xpZW50WTtcbiAgICB0aGlzLnN0YXJ0U2NhbGUgPSB0aGlzLm9wdHMuZ2V0U2NhbGUoKTtcbiAgICB0aGlzLmVsLnNldFBvaW50ZXJDYXB0dXJlPy4oZS5wb2ludGVySWQpO1xuICB9O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgb25Qb2ludGVyTW92ZSA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAoIXRoaXMuZHJhZ2dpbmcpIHJldHVybjtcbiAgICBlLnByZXZlbnREZWZhdWx0KCk7XG4gICAgZS5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICAvLyBVcCAobmVnYXRpdmUgZHkpIOKGkiB0YWxsZXIuIEV4cG9uZW50aWFsIHNvIGVhY2ggYHBpeGVsc1BlckRvdWJsZWAgcHggZG91Ymxlcy9oYWx2ZXMgdGhlIGhlaWdodC5cbiAgICBjb25zdCBkeSA9IGUuY2xpZW50WSAtIHRoaXMuc3RhcnRZO1xuICAgIGNvbnN0IGZhY3RvciA9IE1hdGgucG93KDIsIC1keSAvIHRoaXMub3B0cy5waXhlbHNQZXJEb3VibGUpO1xuICAgIGNvbnN0IG5leHQgPSBNYXRoLm1pbih0aGlzLm9wdHMubWF4U2NhbGUsIE1hdGgubWF4KHRoaXMub3B0cy5taW5TY2FsZSwgdGhpcy5zdGFydFNjYWxlICogZmFjdG9yKSk7XG4gICAgdGhpcy5vcHRzLnNldFNjYWxlKG5leHQpO1xuICAgIHRoaXMucmVwb3NpdGlvbigpO1xuICB9O1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgb25Qb2ludGVyVXAgPSAoZTogUG9pbnRlckV2ZW50KTogdm9pZCA9PiB7XG4gICAgaWYgKCF0aGlzLmRyYWdnaW5nKSByZXR1cm47XG4gICAgdGhpcy5kcmFnZ2luZyA9IGZhbHNlO1xuICAgIGlmICh0aGlzLmVsLmhhc1BvaW50ZXJDYXB0dXJlPy4oZS5wb2ludGVySWQpKSB0aGlzLmVsLnJlbGVhc2VQb2ludGVyQ2FwdHVyZT8uKGUucG9pbnRlcklkKTtcbiAgfTtcblxuICBwcml2YXRlIHJlYWRvbmx5IG9uRG91YmxlQ2xpY2sgPSAoZTogTW91c2VFdmVudCk6IHZvaWQgPT4ge1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBlLnN0b3BQcm9wYWdhdGlvbigpO1xuICAgIHRoaXMub3B0cy5zZXRTY2FsZSgxKTtcbiAgICB0aGlzLnJlcG9zaXRpb24oKTtcbiAgfTtcblxuICBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuZGlzY29ubmVjdENhbWVyYSgpO1xuICAgIHRoaXMucmVzaXplT2JzZXJ2ZXI/LmRpc2Nvbm5lY3QoKTtcbiAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5vblBvaW50ZXJEb3duKTtcbiAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJtb3ZlJywgdGhpcy5vblBvaW50ZXJNb3ZlKTtcbiAgICB0aGlzLmVsLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIHRoaXMub25Qb2ludGVyVXApO1xuICAgIHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIHRoaXMub25Qb2ludGVyVXApO1xuICAgIHRoaXMuZWwucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGJsY2xpY2snLCB0aGlzLm9uRG91YmxlQ2xpY2spO1xuICAgIHRoaXMuZWwucGFyZW50Tm9kZT8ucmVtb3ZlQ2hpbGQodGhpcy5lbCk7XG4gIH1cbn1cbiJdfQ==