@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
@@ -1,6 +1,9 @@
1
1
  import { Subscription } from 'rxjs';
2
2
  import { Region, Rectangle, Polygon } from '../../models/region';
3
- import { PIXEL_WORLD_QUANTUM, snapToWorldGrid } from '../../spatial/world-grid';
3
+ import { hitHandle, nearestEdge, nearestVertex, regionContains, regionsInRect, } from '../../region-overlay/region-geometry';
4
+ import { NapariRegionSvgRenderer } from './region-overlay/region-svg-renderer';
5
+ import { OverlayProjection } from './region-overlay/overlay-projection';
6
+ import { applyRegionEdit } from './region-overlay/region-edit';
4
7
  const SVG_NS = 'http://www.w3.org/2000/svg';
5
8
  /**
6
9
  * Min drag before a freehand path records another point, in SCREEN pixels.
@@ -23,24 +26,36 @@ const FREEHAND_STEP_PX = 2;
23
26
  * impossible to create there.
24
27
  */
25
28
  const MIN_RECT_DRAG_PX = 2;
29
+ /**
30
+ * A rubber band smaller than this on both sides, in SCREEN pixels, is a click on empty space
31
+ * (it clears the selection). Screen for the same reason as {@link MIN_RECT_DRAG_PX}: 3 world
32
+ * units is over half of seqFISH's sample.
33
+ */
34
+ const MIN_MARQUEE_PX = 3;
26
35
  /** Click-distance (screen px) within which a polygon click snaps closed onto the first vertex. */
27
36
  const CLOSE_SNAP_PX = 10;
28
37
  /** Screen-px hit radius for grabbing a vertex / rectangle corner handle. */
29
38
  const HANDLE_HIT_PX = 9;
30
- /** Rendered handle size (screen px). */
31
- const HANDLE_SIZE = 7;
39
+ /** Screen-px distance from an open polyline within which a click selects it (as OSD). */
40
+ const OPEN_PATH_HIT_PX = 6;
32
41
  /**
33
42
  * SVG region overlay for the napari-js WebGPU image view (jit-ui#102), mirroring the OSD backend's
34
- * {@link OsdRegionOverlay} but driven by napari's `canvasToWorld`/`worldToCanvas` transforms.
43
+ * {@link OsdRegionOverlay} but driven by napari's `canvasToWorld`/`canvasTransform` transforms
44
+ * (see {@link OverlayViewer} for their coordinate spaces).
35
45
  * Vector shapes are drawn in an absolutely-positioned `<svg>` over the canvas (no need to push
36
- * them through WebGPU). It writes completed shapes to the shared {@link RegionStore} (so save /
37
- * undo / export work identically to OSD) and re-renders from the store on every camera move,
38
- * region change, and selection change.
46
+ * them through WebGPU) by {@link NapariRegionSvgRenderer} over the shared `SvgRegionRenderer`:
47
+ * in world coordinates inside one transformed group, rebuilt on a region or selection change,
48
+ * while a camera move only rewrites the transform (napari-js's `canvasTransform`, the camera
49
+ * centre/zoom) and the few screen-space handles and labels. This class is
50
+ * the gesture controller: pointer handlers, the tool mode, and the edit/draft/marquee state.
51
+ * It writes completed shapes to the shared {@link RegionStore} (so save / undo / export work
52
+ * identically to OSD).
39
53
  *
40
54
  * Supports (jit-ui#102): rectangle / polygon / freehand path drawing, click-select and rubber-band
41
55
  * marquee select, pan/zoom gating via `setControlsEnabled`, body move, vertex move/add/delete,
42
- * bezier handle editing, and donut holes (including hole vertex + hole-bezier-handle editing) —
43
- * full parity with {@link OsdRegionOverlay}.
56
+ * bezier handle editing, and donut holes (including hole vertex + hole-bezier-handle editing).
57
+ * Hit-testing shares `region-overlay/region-geometry` with the OSD overlay, so both follow
58
+ * the same rules (multi-part regions, holes, open polylines, handle-less bezier curves).
44
59
  */
45
60
  export class NapariRegionOverlay {
46
61
  constructor(host, viewer, store) {
@@ -54,55 +69,21 @@ export class NapariRegionOverlay {
54
69
  this.draftRect = null;
55
70
  /** In-progress rubber-band selection marquee (select mode), image-space. */
56
71
  this.marquee = null;
57
- /** Dedicated marquee rect element, updated directly during the drag (no full region redraw). */
58
- this.marqueeEl = null;
59
72
  this.draftPath = null; // freehand or click polygon
60
73
  this.drawing = false; // pointer is down for rect / freehand
61
74
  this.regionsVisible = true;
62
75
  /** In-progress manipulation (select/move modes): dragging a body, a polygon vertex, or a
63
76
  * rectangle corner. `anchor` is the fixed opposite corner for a rectangle resize. */
64
77
  this.edit = null;
65
- /**
66
- * How finely a drawn vertex may be placed, in world units.
67
- *
68
- * One by default, because for an image the world IS pixels and a region should align to
69
- * them. A dataset whose coordinates are not pixels sets it finer — seqFISH's whole
70
- * sample spans about 5 x 7 units, where whole-unit vertices leave roughly six by eight
71
- * placeable positions and no ROI can be drawn at all.
72
- */
73
- this.worldQuantum = PIXEL_WORLD_QUANTUM;
74
78
  // ── pointer handlers ──────────────────────────────────────────────────────
75
79
  this.onPointerDown = (e) => {
76
80
  if (this.mode === 'none')
77
81
  return;
78
82
  e.preventDefault();
79
- const [ix, iy] = this.toImage(e.clientX, e.clientY);
80
- if (this.mode === 'drawrect') {
81
- this.draftRect = { x0: ix, y0: iy, x1: ix, y1: iy };
82
- this.drawing = true;
83
- this.svg.setPointerCapture(e.pointerId);
84
- }
85
- else if (this.mode === 'drawclosedpath' || this.mode === 'drawopenpath') {
86
- this.draftPath = [[ix, iy]];
87
- this.drawing = true;
88
- this.svg.setPointerCapture(e.pointerId);
89
- }
90
- else if (this.mode === 'drawpolygon') {
91
- this.handlePolygonClick(ix, iy, e.clientX, e.clientY);
92
- }
93
- else if (this.mode === 'select' || this.mode === 'move') {
94
- this.beginManipulation(ix, iy, e);
95
- }
96
- else if (this.mode === 'addpoint') {
97
- this.handleAddPoint(ix, iy);
98
- }
99
- else if (this.mode === 'deletepoint') {
100
- this.handleDeletePoint(ix, iy);
101
- }
102
- this.redraw();
83
+ this.projection.withOrigin(() => this.pointerDown(e));
103
84
  };
104
85
  this.onPointerMove = (e) => {
105
- const [ix, iy] = this.toImage(e.clientX, e.clientY);
86
+ const [ix, iy] = this.projection.toImage(e.clientX, e.clientY);
106
87
  if (this.marquee) {
107
88
  this.marquee.x1 = ix;
108
89
  this.marquee.y1 = iy;
@@ -110,7 +91,7 @@ export class NapariRegionOverlay {
110
91
  return;
111
92
  }
112
93
  if (this.edit) {
113
- this.applyManipulation(ix, iy);
94
+ applyRegionEdit(this.store, this.edit, ix, iy);
114
95
  this.redraw();
115
96
  return;
116
97
  }
@@ -121,19 +102,19 @@ export class NapariRegionOverlay {
121
102
  this.draftRect.y1 = iy;
122
103
  }
123
104
  else if (this.draftPath) {
124
- const step = FREEHAND_STEP_PX * this.worldPerCanvasPixel();
105
+ const step = FREEHAND_STEP_PX * this.projection.worldPerCanvasPixel();
125
106
  const last = this.draftPath[this.draftPath.length - 1];
126
107
  if (Math.abs(ix - last[0]) >= step || Math.abs(iy - last[1]) >= step) {
127
108
  this.draftPath.push([ix, iy]);
128
109
  }
129
110
  }
130
- this.redraw();
111
+ this.renderOverlay();
131
112
  };
132
113
  this.onPointerUp = (e) => {
133
114
  if (this.marquee) {
134
115
  const m = this.marquee;
135
116
  this.marquee = null;
136
- this.clearMarqueeEl();
117
+ this.renderer.clearMarquee();
137
118
  try {
138
119
  this.svg.releasePointerCapture(e.pointerId);
139
120
  }
@@ -171,7 +152,7 @@ export class NapariRegionOverlay {
171
152
  const w = Math.abs(x1 - x0);
172
153
  const h = Math.abs(y1 - y0);
173
154
  this.draftRect = null;
174
- const min = MIN_RECT_DRAG_PX * this.worldPerCanvasPixel();
155
+ const min = MIN_RECT_DRAG_PX * this.projection.worldPerCanvasPixel();
175
156
  if (w >= min && h >= min)
176
157
  this.commitRectangle(x, y, w, h);
177
158
  }
@@ -184,6 +165,17 @@ export class NapariRegionOverlay {
184
165
  }
185
166
  this.redraw();
186
167
  };
168
+ /**
169
+ * The pointer gesture ended without a pointerup (the browser cancelled it, or capture was
170
+ * lost): end it without committing. Also fires after every normal release, when nothing
171
+ * is live any more.
172
+ */
173
+ this.onPointerCancel = () => {
174
+ if (!this.edit && !this.drawing && !this.marquee)
175
+ return;
176
+ this.endGesture();
177
+ this.redraw();
178
+ };
187
179
  this.onDblClick = (e) => {
188
180
  if (this.mode !== 'drawpolygon' || !this.draftPath)
189
181
  return;
@@ -207,16 +199,22 @@ export class NapariRegionOverlay {
207
199
  touchAction: 'none',
208
200
  });
209
201
  this.host.appendChild(this.svg);
202
+ this.renderer = new NapariRegionSvgRenderer(this.svg, this.store);
203
+ this.projection = new OverlayProjection(this.svg, this.viewer);
210
204
  this.svg.addEventListener('pointerdown', this.onPointerDown);
211
205
  this.svg.addEventListener('pointermove', this.onPointerMove);
212
206
  this.svg.addEventListener('pointerup', this.onPointerUp);
207
+ this.svg.addEventListener('pointercancel', this.onPointerCancel);
208
+ this.svg.addEventListener('lostpointercapture', this.onPointerCancel);
213
209
  this.svg.addEventListener('dblclick', this.onDblClick);
214
210
  this.subs.add(this.store.getRegionUpdateEvent().subscribe(() => this.redraw()));
215
211
  this.subs.add(this.store.getSelectedShapeIndices$().subscribe((idx) => {
216
212
  this.selected = idx ?? [];
217
213
  this.redraw();
218
214
  }));
219
- this.disconnectCamera = this.viewer.camera.changed.connect(() => this.redraw());
215
+ // A camera move rewrites the renderer's transform and its few screen-space elements;
216
+ // the regions are drawn in world coordinates and are not rebuilt (NAPARI-BOUNDARY-10).
217
+ this.disconnectCamera = this.viewer.camera.changed.connect(() => this.updateCamera());
220
218
  this.redraw();
221
219
  }
222
220
  // ── IRegionOverlay ────────────────────────────────────────────────────────
@@ -232,68 +230,87 @@ export class NapariRegionOverlay {
232
230
  return this.mode !== 'none';
233
231
  }
234
232
  setMode(mode) {
233
+ this.endGesture();
235
234
  this.mode = mode;
236
235
  this.draftRect = null;
237
236
  this.draftPath = null;
238
- this.marquee = null;
239
- this.clearMarqueeEl();
240
- this.drawing = false;
241
237
  // The overlay owns pointer/navigation gating: while a tool is active it captures the pointer
242
238
  // and the napari camera controls are disabled; 'none' hands the pointer back for pan/zoom.
243
239
  const active = mode !== 'none';
244
240
  this.viewer.setControlsEnabled(!active);
245
241
  this.svg.style.pointerEvents = active ? 'auto' : 'none';
246
242
  this.svg.style.cursor = active ? 'crosshair' : 'default';
247
- this.redraw();
243
+ this.renderOverlay();
248
244
  }
249
245
  setSelectedBezier(bezier) {
250
246
  const sel = this.selectedRegion();
251
247
  if (sel?.id != null)
252
248
  this.store.setBezier(sel.id, bezier);
253
249
  }
250
+ /**
251
+ * How finely a drawn vertex may be placed, in world units: one (an image's pixels) by
252
+ * default, finer for a dataset whose coordinates are not pixels (see OverlayProjection).
253
+ */
254
254
  setWorldQuantum(quantum) {
255
- this.worldQuantum = Number.isFinite(quantum) && quantum > 0
256
- ? quantum
257
- : PIXEL_WORLD_QUANTUM;
255
+ this.projection.setWorldQuantum(quantum);
258
256
  }
259
257
  destroy() {
260
258
  this.svg.removeEventListener('pointerdown', this.onPointerDown);
261
259
  this.svg.removeEventListener('pointermove', this.onPointerMove);
262
260
  this.svg.removeEventListener('pointerup', this.onPointerUp);
261
+ this.svg.removeEventListener('pointercancel', this.onPointerCancel);
262
+ this.svg.removeEventListener('lostpointercapture', this.onPointerCancel);
263
263
  this.svg.removeEventListener('dblclick', this.onDblClick);
264
264
  this.disconnectCamera();
265
265
  this.subs.unsubscribe();
266
+ // A drag torn down mid-gesture (a backend switch) must still close its store batch.
267
+ this.endGesture();
266
268
  if (this.svg.parentNode)
267
269
  this.svg.parentNode.removeChild(this.svg);
268
270
  }
269
- // ── coordinate transforms ─────────────────────────────────────────────────
270
- /** Pointer client coords → world coords, snapped to {@link worldQuantum}. */
271
- toImage(clientX, clientY) {
272
- const [wx, wy] = this.viewer.canvasToWorld(clientX, clientY);
273
- return [
274
- snapToWorldGrid(wx, this.worldQuantum),
275
- snapToWorldGrid(wy, this.worldQuantum),
276
- ];
271
+ pointerDown(e) {
272
+ const [ix, iy] = this.projection.toImage(e.clientX, e.clientY);
273
+ if (this.mode === 'drawrect') {
274
+ this.draftRect = { x0: ix, y0: iy, x1: ix, y1: iy };
275
+ this.drawing = true;
276
+ this.svg.setPointerCapture(e.pointerId);
277
+ }
278
+ else if (this.mode === 'drawclosedpath' || this.mode === 'drawopenpath') {
279
+ this.draftPath = [[ix, iy]];
280
+ this.drawing = true;
281
+ this.svg.setPointerCapture(e.pointerId);
282
+ }
283
+ else if (this.mode === 'drawpolygon') {
284
+ this.handlePolygonClick(ix, iy, e.clientX, e.clientY);
285
+ }
286
+ else if (this.mode === 'select' || this.mode === 'move') {
287
+ this.beginManipulation(ix, iy, e);
288
+ }
289
+ else if (this.mode === 'addpoint') {
290
+ this.handleAddPoint(ix, iy, e.clientX, e.clientY);
291
+ }
292
+ else if (this.mode === 'deletepoint') {
293
+ this.handleDeletePoint(ix, iy);
294
+ }
295
+ this.redraw();
277
296
  }
278
297
  /**
279
- * World units spanned by one screen pixel, measured through the viewer's own transform.
280
- *
281
- * Read from the transform rather than from the camera, so it holds for both the 2D and
282
- * the 3D screen-space adapters without either having to expose a zoom. Falls back to 1
283
- * if the transform gives nothing usable, which keeps the established pixel behaviour
284
- * rather than collapsing the threshold to zero and recording a point per event.
298
+ * End whatever pointer gesture is live without committing it: close the store batch a drag
299
+ * opened (so later edits are emitted again) and forget the drag (so a bare hover no longer
300
+ * moves the region), and drop the marquee and a rectangle/freehand draft. A click-placed
301
+ * polygon is not a pointer gesture and survives.
285
302
  */
286
- worldPerCanvasPixel() {
287
- const [x0] = this.viewer.canvasToWorld(0, 0);
288
- const [x1] = this.viewer.canvasToWorld(1, 0);
289
- const per = Math.abs(x1 - x0);
290
- return Number.isFinite(per) && per > 0 ? per : 1;
291
- }
292
- /** Image coords → SVG-local px (the svg overlays the canvas at the same client rect). */
293
- toLocal(imgX, imgY) {
294
- const [cx, cy] = this.viewer.worldToCanvas(imgX, imgY);
295
- const r = this.svg.getBoundingClientRect();
296
- return [cx - r.left, cy - r.top];
303
+ endGesture() {
304
+ if (this.edit)
305
+ this.store.endBatch();
306
+ this.edit = null;
307
+ if (this.drawing) {
308
+ this.draftRect = null;
309
+ this.draftPath = null;
310
+ }
311
+ this.drawing = false;
312
+ this.marquee = null;
313
+ this.renderer.clearMarquee();
297
314
  }
298
315
  /** Click-to-place polygon: add a vertex, or close when clicking near the first one. */
299
316
  handlePolygonClick(ix, iy, clientX, clientY) {
@@ -301,9 +318,7 @@ export class NapariRegionOverlay {
301
318
  this.draftPath = [[ix, iy]];
302
319
  return;
303
320
  }
304
- const [fx, fy] = this.toLocal(this.draftPath[0][0], this.draftPath[0][1]);
305
- const r = this.svg.getBoundingClientRect();
306
- const near = Math.hypot(clientX - r.left - fx, clientY - r.top - fy) <= CLOSE_SNAP_PX &&
321
+ const near = this.projection.screenDist(clientX, clientY, this.draftPath[0][0], this.draftPath[0][1]) <= CLOSE_SNAP_PX &&
307
322
  this.draftPath.length >= 3;
308
323
  if (near) {
309
324
  const pts = this.draftPath;
@@ -320,12 +335,6 @@ export class NapariRegionOverlay {
320
335
  const i = this.selected[0];
321
336
  return i != null && i >= 0 && i < regions.length ? regions[i] : null;
322
337
  }
323
- /** Screen distance (px) between a client point and an image coord. */
324
- screenDist(clientX, clientY, imgX, imgY) {
325
- const [lx, ly] = this.toLocal(imgX, imgY);
326
- const r = this.svg.getBoundingClientRect();
327
- return Math.hypot(clientX - r.left - lx, clientY - r.top - ly);
328
- }
329
338
  /**
330
339
  * Start a select/move interaction: grab a handle (rectangle corner) or vertex of the already-
331
340
  * selected region first; otherwise select the topmost region under the cursor and drag its body.
@@ -333,7 +342,8 @@ export class NapariRegionOverlay {
333
342
  beginManipulation(ix, iy, e) {
334
343
  const sel = this.selectedRegion();
335
344
  if (sel?.bounds) {
336
- const grab = this.hitHandle(sel, e.clientX, e.clientY);
345
+ const [lx, ly] = this.projection.clientToLocal(e.clientX, e.clientY);
346
+ const grab = hitHandle(sel, lx, ly, this.projection.toScreen, HANDLE_HIT_PX);
337
347
  if (grab) {
338
348
  this.store.beginBatch();
339
349
  this.edit = { ...grab, id: sel.id, last: [ix, iy] };
@@ -341,10 +351,12 @@ export class NapariRegionOverlay {
341
351
  return;
342
352
  }
343
353
  }
344
- // Hit-test bodies, topmost first (last drawn renders on top).
354
+ // Hit-test bodies, topmost first (last drawn renders on top), at the exact pointer
355
+ // position — snapping is for placing vertices, not for picking.
345
356
  const regions = this.store.getRegions();
357
+ const [wx, wy] = this.projection.toWorld(e.clientX, e.clientY);
346
358
  for (let i = regions.length - 1; i >= 0; i--) {
347
- if (this.hitTest(regions[i], ix, iy)) {
359
+ if (regionContains(regions[i], wx, wy, { toScreen: this.projection.toScreen, tolPx: OPEN_PATH_HIT_PX })) {
348
360
  this.store.selectRegion(regions[i]);
349
361
  this.store.beginBatch();
350
362
  this.edit = { kind: 'body', id: regions[i].id, last: [ix, iy] };
@@ -363,237 +375,58 @@ export class NapariRegionOverlay {
363
375
  this.store.setSelectedShapeIndices([]);
364
376
  }
365
377
  }
366
- /** Create/update the marquee rect element directly (avoids a full region redraw per move). */
378
+ /** Show the marquee where it is now (only the marquee element: no full region redraw). */
367
379
  updateMarqueeEl() {
368
380
  if (!this.marquee)
369
381
  return;
370
- if (!this.marqueeEl || !this.marqueeEl.parentNode) {
371
- this.marqueeEl = document.createElementNS(SVG_NS, 'rect');
372
- this.marqueeEl.setAttribute('stroke', '#4da3ff');
373
- this.marqueeEl.setAttribute('stroke-width', '1');
374
- this.marqueeEl.setAttribute('stroke-dasharray', '4 3');
375
- this.marqueeEl.setAttribute('fill', '#4da3ff');
376
- this.marqueeEl.setAttribute('fill-opacity', '0.12');
377
- this.marqueeEl.setAttribute('vector-effect', 'non-scaling-stroke');
378
- this.svg.appendChild(this.marqueeEl);
379
- }
380
382
  const { x0, y0, x1, y1 } = this.marquee;
381
- const [lx, ly] = this.toLocal(Math.min(x0, x1), Math.min(y0, y1));
382
- const [rx, ry] = this.toLocal(Math.max(x0, x1), Math.max(y0, y1));
383
- this.marqueeEl.setAttribute('x', `${lx}`);
384
- this.marqueeEl.setAttribute('y', `${ly}`);
385
- this.marqueeEl.setAttribute('width', `${Math.abs(rx - lx)}`);
386
- this.marqueeEl.setAttribute('height', `${Math.abs(ry - ly)}`);
387
- }
388
- /** Remove the marquee element from the SVG. */
389
- clearMarqueeEl() {
390
- if (this.marqueeEl?.parentNode)
391
- this.marqueeEl.parentNode.removeChild(this.marqueeEl);
392
- this.marqueeEl = null;
393
- }
394
- /** Test whether a client point grabs a rectangle corner or a polygon vertex of `region`. */
395
- hitHandle(region, clientX, clientY) {
396
- const b = region.bounds;
397
- if (!b)
398
- return null;
399
- if ('width' in b && 'x' in b) {
400
- const r = b;
401
- const corners = [
402
- [r.x, r.y, [r.x + r.width, r.y + r.height]],
403
- [r.x + r.width, r.y, [r.x, r.y + r.height]],
404
- [r.x, r.y + r.height, [r.x + r.width, r.y]],
405
- [r.x + r.width, r.y + r.height, [r.x, r.y]],
406
- ];
407
- for (const [cx, cy, anchor] of corners) {
408
- if (this.screenDist(clientX, clientY, cx, cy) <= HANDLE_HIT_PX)
409
- return { kind: 'corner', anchor };
410
- }
411
- }
412
- else if ('npoints' in b) {
413
- const p = b;
414
- // Bezier control points first (they sit off the anchors), so they're grabbable.
415
- if (p.bezier && p.handlesIn?.length === p.npoints && p.handlesOut?.length === p.npoints) {
416
- for (let i = 0; i < p.npoints; i++) {
417
- const out = p.handlesOut[i];
418
- const inn = p.handlesIn[i];
419
- if (this.screenDist(clientX, clientY, p.xpoints[i] + out[0], p.ypoints[i] + out[1]) <= HANDLE_HIT_PX) {
420
- return { kind: 'bezier', vertexIndex: i, side: 'out' };
421
- }
422
- if (this.screenDist(clientX, clientY, p.xpoints[i] + inn[0], p.ypoints[i] + inn[1]) <= HANDLE_HIT_PX) {
423
- return { kind: 'bezier', vertexIndex: i, side: 'in' };
424
- }
425
- }
426
- }
427
- for (let i = 0; i < p.npoints; i++) {
428
- if (this.screenDist(clientX, clientY, p.xpoints[i], p.ypoints[i]) <= HANDLE_HIT_PX) {
429
- return { kind: 'vertex', vertexIndex: i };
430
- }
431
- }
432
- // Hole (donut) ring: bezier control points first, then the vertices.
433
- const holes = p.holes ?? [];
434
- const holeBezier = !!(p.bezier && p.holeHandlesIn && p.holeHandlesOut);
435
- for (let hi = 0; hi < holes.length; hi++) {
436
- const ring = holes[hi];
437
- if (holeBezier && p.holeHandlesIn[hi] && p.holeHandlesOut[hi]) {
438
- for (let vi = 0; vi < ring.length; vi++) {
439
- const out = p.holeHandlesOut[hi][vi] ?? [0, 0];
440
- const inn = p.holeHandlesIn[hi][vi] ?? [0, 0];
441
- if (this.screenDist(clientX, clientY, ring[vi][0] + out[0], ring[vi][1] + out[1]) <= HANDLE_HIT_PX) {
442
- return { kind: 'holebezier', holeIndex: hi, vertexIndex: vi, side: 'out' };
443
- }
444
- if (this.screenDist(clientX, clientY, ring[vi][0] + inn[0], ring[vi][1] + inn[1]) <= HANDLE_HIT_PX) {
445
- return { kind: 'holebezier', holeIndex: hi, vertexIndex: vi, side: 'in' };
446
- }
447
- }
448
- }
449
- for (let vi = 0; vi < ring.length; vi++) {
450
- if (this.screenDist(clientX, clientY, ring[vi][0], ring[vi][1]) <= HANDLE_HIT_PX) {
451
- return { kind: 'holevertex', holeIndex: hi, vertexIndex: vi };
452
- }
453
- }
454
- }
455
- }
456
- return null;
457
- }
458
- /** Apply the live drag for the active manipulation (image coords `ix,iy`). */
459
- applyManipulation(ix, iy) {
460
- if (!this.edit)
461
- return;
462
- if (this.edit.kind === 'body') {
463
- const [lx, ly] = this.edit.last;
464
- this.store.moveRegion(this.edit.id, ix - lx, iy - ly);
465
- this.edit.last = [ix, iy];
466
- }
467
- else if (this.edit.kind === 'vertex' && this.edit.vertexIndex != null) {
468
- this.store.moveVertex(this.edit.id, this.edit.vertexIndex, ix, iy);
469
- }
470
- else if (this.edit.kind === 'corner' && this.edit.anchor) {
471
- const [ax, ay] = this.edit.anchor;
472
- const rect = new Rectangle();
473
- rect.x = Math.min(ax, ix);
474
- rect.y = Math.min(ay, iy);
475
- rect.width = Math.abs(ix - ax);
476
- rect.height = Math.abs(iy - ay);
477
- this.store.updateBounds(this.edit.id, rect);
478
- }
479
- else if (this.edit.kind === 'bezier' && this.edit.vertexIndex != null && this.edit.side) {
480
- this.store.moveBezierHandle(this.edit.id, this.edit.vertexIndex, this.edit.side, ix, iy);
481
- }
482
- else if (this.edit.kind === 'holevertex' &&
483
- this.edit.holeIndex != null &&
484
- this.edit.vertexIndex != null) {
485
- this.store.moveHoleVertex(this.edit.id, this.edit.holeIndex, this.edit.vertexIndex, ix, iy);
486
- }
487
- else if (this.edit.kind === 'holebezier' &&
488
- this.edit.holeIndex != null &&
489
- this.edit.vertexIndex != null &&
490
- this.edit.side) {
491
- this.store.moveHoleBezierHandle(this.edit.id, this.edit.holeIndex, this.edit.vertexIndex, this.edit.side, ix, iy);
492
- }
383
+ const [lx, ly] = this.projection.toLocal(Math.min(x0, x1), Math.min(y0, y1));
384
+ const [rx, ry] = this.projection.toLocal(Math.max(x0, x1), Math.max(y0, y1));
385
+ this.renderer.showMarquee(lx, ly, rx, ry);
493
386
  }
494
- /** addpoint mode: insert a vertex on the selected polygon's nearest edge at the click. */
495
- handleAddPoint(ix, iy) {
387
+ /** addpoint mode: insert a vertex at the click on the selected polygon's nearest edge
388
+ * (exterior or a hole ring). */
389
+ handleAddPoint(ix, iy, clientX, clientY) {
496
390
  const sel = this.selectedRegion();
497
- const b = sel?.bounds;
498
- if (!sel || !b || !('npoints' in b))
391
+ if (!sel)
499
392
  return;
500
- const p = b;
501
- let bestSeg = 0;
502
- let bestD = Infinity;
503
- const segs = p.closed === false ? p.npoints - 1 : p.npoints;
504
- for (let s = 0; s < segs; s++) {
505
- const j = (s + 1) % p.npoints;
506
- const d = this.pointSegDist(ix, iy, p.xpoints[s], p.ypoints[s], p.xpoints[j], p.ypoints[j]);
507
- if (d < bestD) {
508
- bestD = d;
509
- bestSeg = s;
510
- }
511
- }
512
- this.store.addVertex(sel.id, bestSeg, ix, iy);
393
+ const [lx, ly] = this.projection.clientToLocal(clientX, clientY);
394
+ const edge = nearestEdge(sel, lx, ly, this.projection.toScreen);
395
+ if (!edge)
396
+ return;
397
+ if (edge.ring < 0)
398
+ this.store.addVertex(sel.id, edge.segIndex, ix, iy);
399
+ else
400
+ this.store.addHoleVertex(sel.id, edge.ring, edge.segIndex, ix, iy);
513
401
  }
514
- /** deletepoint mode: remove the selected polygon's vertex nearest the click. */
402
+ /** deletepoint mode: remove the selected polygon's vertex nearest the click (exterior or a
403
+ * hole ring). */
515
404
  handleDeletePoint(ix, iy) {
516
405
  const sel = this.selectedRegion();
517
- const b = sel?.bounds;
518
- if (!sel || !b || !('npoints' in b))
406
+ if (!sel)
519
407
  return;
520
- const p = b;
521
- let best = -1;
522
- let bestD = Infinity;
523
- for (let i = 0; i < p.npoints; i++) {
524
- const d = Math.hypot(p.xpoints[i] - ix, p.ypoints[i] - iy);
525
- if (d < bestD) {
526
- bestD = d;
527
- best = i;
528
- }
529
- }
530
- if (best >= 0)
531
- this.store.deleteVertex(sel.id, best);
532
- }
533
- /** Distance from point (px,py) to segment (ax,ay)-(bx,by), in image units. */
534
- pointSegDist(px, py, ax, ay, bx, by) {
535
- const dx = bx - ax;
536
- const dy = by - ay;
537
- const len2 = dx * dx + dy * dy || 1;
538
- let t = ((px - ax) * dx + (py - ay) * dy) / len2;
539
- t = Math.max(0, Math.min(1, t));
540
- return Math.hypot(px - (ax + t * dx), py - (ay + t * dy));
408
+ const v = nearestVertex(sel, ix, iy);
409
+ if (!v)
410
+ return;
411
+ if (v.ring < 0)
412
+ this.store.deleteVertex(sel.id, v.index);
413
+ else
414
+ this.store.deleteHoleVertex(sel.id, v.ring, v.index);
541
415
  }
542
- /** Finalize a rubber-band marquee: select every region whose bounding box it overlaps (a tiny
543
- * marquee is treated as a click on empty space → clear the selection). */
416
+ /** Finalize a rubber-band marquee: select every region whose bounding box it overlaps (a
417
+ * marquee under {@link MIN_MARQUEE_PX} is a click on empty space → clear the selection). */
544
418
  finishMarquee(m) {
545
419
  const x0 = Math.min(m.x0, m.x1);
546
420
  const x1 = Math.max(m.x0, m.x1);
547
421
  const y0 = Math.min(m.y0, m.y1);
548
422
  const y1 = Math.max(m.y0, m.y1);
549
- if (x1 - x0 < 3 && y1 - y0 < 3) {
423
+ const min = MIN_MARQUEE_PX * this.projection.worldPerCanvasPixel();
424
+ if (x1 - x0 < min && y1 - y0 < min) {
550
425
  this.store.setSelectedShapeIndices([]);
551
426
  return;
552
427
  }
553
- const indices = [];
554
- this.store.getRegions().forEach((r, i) => {
555
- if (r.isProfile?.())
556
- return;
557
- const bb = this.regionBBox(r);
558
- if (bb && bb.x0 <= x1 && bb.x1 >= x0 && bb.y0 <= y1 && bb.y1 >= y0)
559
- indices.push(i);
560
- });
561
- this.store.setSelectedShapeIndices(indices);
562
- }
563
- /** A region's bounding box in image coords (rectangle, polygon, or multipolygon), or null. */
564
- regionBBox(region) {
565
- const b = region.bounds;
566
- if (!b)
567
- return null;
568
- if ('width' in b && 'x' in b) {
569
- const r = b;
570
- return { x0: r.x, y0: r.y, x1: r.x + r.width, y1: r.y + r.height };
571
- }
572
- const acc = { x0: Infinity, y0: Infinity, x1: -Infinity, y1: -Infinity };
573
- const addRing = (xs, ys) => {
574
- for (let i = 0; i < xs.length; i++) {
575
- if (xs[i] < acc.x0)
576
- acc.x0 = xs[i];
577
- if (xs[i] > acc.x1)
578
- acc.x1 = xs[i];
579
- if (ys[i] < acc.y0)
580
- acc.y0 = ys[i];
581
- if (ys[i] > acc.y1)
582
- acc.y1 = ys[i];
583
- }
584
- };
585
- if ('npoints' in b) {
586
- const p = b;
587
- addRing(p.xpoints, p.ypoints);
588
- }
589
- else if ('polygons' in b) {
590
- for (const p of b.polygons)
591
- addRing(p.xpoints, p.ypoints);
592
- }
593
- else {
594
- return null;
595
- }
596
- return isFinite(acc.x0) ? acc : null;
428
+ const regions = this.store.getRegions();
429
+ this.store.setSelectedShapeIndices(regionsInRect(regions, x0, y0, x1, y1, { skipProfiles: true }));
597
430
  }
598
431
  // ── shape commit ──────────────────────────────────────────────────────────
599
432
  commitRectangle(x, y, width, height) {
@@ -621,29 +454,6 @@ export class NapariRegionOverlay {
621
454
  this.store.addRegion(region);
622
455
  }
623
456
  // ── rendering ─────────────────────────────────────────────────────────────
624
- hitTest(region, x, y) {
625
- const b = region.bounds;
626
- if (!b)
627
- return false;
628
- if ('width' in b && 'x' in b) {
629
- const r = b;
630
- return x >= r.x && x <= r.x + r.width && y >= r.y && y <= r.y + r.height;
631
- }
632
- if ('npoints' in b) {
633
- const p = b;
634
- let inside = false;
635
- for (let i = 0, j = p.npoints - 1; i < p.npoints; j = i++) {
636
- const xi = p.xpoints[i];
637
- const yi = p.ypoints[i];
638
- const xj = p.xpoints[j];
639
- const yj = p.ypoints[j];
640
- if (yi > y !== yj > y && x < ((xj - xi) * (y - yi)) / (yj - yi) + xi)
641
- inside = !inside;
642
- }
643
- return inside;
644
- }
645
- return false;
646
- }
647
457
  /** Show or hide the drawn regions. A region being drawn stays visible either way. */
648
458
  setRegionsVisible(visible) {
649
459
  if (visible === this.regionsVisible)
@@ -651,269 +461,25 @@ export class NapariRegionOverlay {
651
461
  this.regionsVisible = visible;
652
462
  this.redraw();
653
463
  }
654
- redraw() {
655
- while (this.svg.firstChild)
656
- this.svg.removeChild(this.svg.firstChild);
657
- const regions = this.regionsVisible ? this.store.getRegions() : [];
658
- regions.forEach((region, i) => {
659
- if (region.isProfile?.())
660
- return;
661
- const isSel = this.selected.includes(i);
662
- const el = this.buildRegionEl(region, isSel);
663
- if (el)
664
- this.svg.appendChild(el);
665
- this.drawLabel(region);
666
- if (isSel)
667
- this.drawHandles(region);
668
- });
669
- this.drawDraft();
670
- }
671
- /** Draw a region's classification label at its top-left, when labels are enabled (matches OSD). */
672
- drawLabel(region) {
673
- if (!this.store.getShowShapeLabel() || region.isProfile?.())
674
- return;
675
- const label = region.label;
676
- const b = region.bounds;
677
- if (!label || !b)
678
- return;
679
- let ix;
680
- let iy;
681
- if ('width' in b && 'x' in b) {
682
- ix = b.x;
683
- iy = b.y;
684
- }
685
- else if ('npoints' in b) {
686
- const p = b;
687
- ix = p.xpoints.reduce((m, x) => Math.min(m, x), Infinity);
688
- iy = p.ypoints.reduce((m, y) => Math.min(m, y), Infinity);
689
- }
690
- else {
691
- return;
692
- }
693
- const [lx, ly] = this.toLocal(ix, iy);
694
- const text = document.createElementNS(SVG_NS, 'text');
695
- text.setAttribute('x', `${lx}`);
696
- text.setAttribute('y', `${ly - 4}`);
697
- text.setAttribute('fill', '#fff');
698
- text.setAttribute('stroke', '#000');
699
- text.setAttribute('stroke-width', '3');
700
- text.setAttribute('paint-order', 'stroke');
701
- text.setAttribute('font', '12px sans-serif');
702
- text.setAttribute('pointer-events', 'none');
703
- text.textContent = label;
704
- this.svg.appendChild(text);
705
- }
706
- /** Draw grab handles for the selected region: rectangle corners or polygon vertices. */
707
- drawHandles(region) {
708
- const b = region.bounds;
709
- if (!b)
710
- return;
711
- const stroke = region.color || this.store.getShapeColor() || '#00ffff';
712
- const handle = (imgX, imgY) => {
713
- const [lx, ly] = this.toLocal(imgX, imgY);
714
- const el = document.createElementNS(SVG_NS, 'rect');
715
- el.setAttribute('x', `${lx - HANDLE_SIZE / 2}`);
716
- el.setAttribute('y', `${ly - HANDLE_SIZE / 2}`);
717
- el.setAttribute('width', `${HANDLE_SIZE}`);
718
- el.setAttribute('height', `${HANDLE_SIZE}`);
719
- el.setAttribute('fill', '#fff');
720
- el.setAttribute('stroke', stroke);
721
- el.setAttribute('stroke-width', '1.5');
722
- this.svg.appendChild(el);
723
- };
724
- if ('width' in b && 'x' in b) {
725
- const r = b;
726
- handle(r.x, r.y);
727
- handle(r.x + r.width, r.y);
728
- handle(r.x, r.y + r.height);
729
- handle(r.x + r.width, r.y + r.height);
730
- }
731
- else if ('npoints' in b) {
732
- const p = b;
733
- const isBezier = p.bezier && p.handlesIn?.length === p.npoints && p.handlesOut?.length === p.npoints;
734
- for (let i = 0; i < p.npoints; i++)
735
- handle(p.xpoints[i], p.ypoints[i]);
736
- for (const ring of p.holes ?? [])
737
- for (const [hx, hy] of ring)
738
- handle(hx, hy);
739
- // Bezier regions also expose their tangent control points (circles) joined to the anchor
740
- // by a thin line, matching the OSD overlay's editable bezier handles.
741
- if (isBezier) {
742
- const hIn = p.handlesIn;
743
- const hOut = p.handlesOut;
744
- for (let i = 0; i < p.npoints; i++) {
745
- this.drawBezierHandle(p.xpoints[i], p.ypoints[i], hOut[i], stroke);
746
- this.drawBezierHandle(p.xpoints[i], p.ypoints[i], hIn[i], stroke);
747
- }
748
- }
749
- // Donut hole bezier control handles.
750
- if (p.bezier && p.holeHandlesIn && p.holeHandlesOut) {
751
- (p.holes ?? []).forEach((ring, hi) => {
752
- const hIn = p.holeHandlesIn[hi];
753
- const hOut = p.holeHandlesOut[hi];
754
- if (!hIn || !hOut)
755
- return;
756
- ring.forEach(([hx, hy], vi) => {
757
- this.drawBezierHandle(hx, hy, hOut[vi], stroke);
758
- this.drawBezierHandle(hx, hy, hIn[vi], stroke);
759
- });
760
- });
761
- }
762
- }
763
- }
764
- /** Draw one bezier control point (anchor + handle offset) as a small circle connected to its
765
- * anchor by a tangent line. `handle` is the [dx,dy] offset from the anchor in image space. */
766
- drawBezierHandle(ax, ay, handle, stroke) {
767
- if (!handle || (handle[0] === 0 && handle[1] === 0))
768
- return;
769
- const [alx, aly] = this.toLocal(ax, ay);
770
- const [hlx, hly] = this.toLocal(ax + handle[0], ay + handle[1]);
771
- const line = document.createElementNS(SVG_NS, 'line');
772
- line.setAttribute('x1', `${alx}`);
773
- line.setAttribute('y1', `${aly}`);
774
- line.setAttribute('x2', `${hlx}`);
775
- line.setAttribute('y2', `${hly}`);
776
- line.setAttribute('stroke', stroke);
777
- line.setAttribute('stroke-width', '1');
778
- line.setAttribute('stroke-opacity', '0.7');
779
- this.svg.appendChild(line);
780
- const dot = document.createElementNS(SVG_NS, 'circle');
781
- dot.setAttribute('cx', `${hlx}`);
782
- dot.setAttribute('cy', `${hly}`);
783
- dot.setAttribute('r', `${HANDLE_SIZE / 2}`);
784
- dot.setAttribute('fill', stroke);
785
- dot.setAttribute('stroke', '#fff');
786
- dot.setAttribute('stroke-width', '1');
787
- this.svg.appendChild(dot);
788
- }
789
- buildRegionEl(region, isSelected) {
790
- const b = region.bounds;
791
- if (!b)
792
- return null;
793
- const stroke = region.color || this.store.getShapeColor() || '#00ffff';
794
- if ('width' in b && 'x' in b) {
795
- const r = b;
796
- const [lx, ly] = this.toLocal(r.x, r.y);
797
- const [rx, ry] = this.toLocal(r.x + r.width, r.y + r.height);
798
- const el = document.createElementNS(SVG_NS, 'rect');
799
- el.setAttribute('x', `${Math.min(lx, rx)}`);
800
- el.setAttribute('y', `${Math.min(ly, ry)}`);
801
- el.setAttribute('width', `${Math.abs(rx - lx)}`);
802
- el.setAttribute('height', `${Math.abs(ry - ly)}`);
803
- this.style(el, stroke, isSelected);
804
- return el;
805
- }
806
- if ('npoints' in b) {
807
- const p = b;
808
- const isBezier = !!p.bezier && p.handlesIn?.length === p.npoints && p.handlesOut?.length === p.npoints;
809
- const hasHoles = !!(p.holes && p.holes.length);
810
- // Bezier or donut (holes) → a single <path>; holes use even-odd fill so they punch through.
811
- if (isBezier || hasHoles) {
812
- const el = document.createElementNS(SVG_NS, 'path');
813
- el.setAttribute('d', this.polygonPathData(p, isBezier));
814
- if (hasHoles)
815
- el.setAttribute('fill-rule', 'evenodd');
816
- this.style(el, stroke, isSelected);
817
- return el;
818
- }
819
- const pts = p.xpoints
820
- .map((_, i) => this.toLocal(p.xpoints[i], p.ypoints[i]).join(','))
821
- .join(' ');
822
- const el = document.createElementNS(SVG_NS, p.closed === false ? 'polyline' : 'polygon');
823
- el.setAttribute('points', pts);
824
- this.style(el, stroke, isSelected);
825
- return el;
826
- }
827
- return null;
464
+ /** Follow a camera move: one transform attribute plus the screen-space elements. */
465
+ updateCamera() {
466
+ this.renderer.setCamera(this.projection.affine());
828
467
  }
829
- /** Path data for a polygon: the exterior ring (bezier or straight) plus any holes (bezier when
830
- * the donut carries hole handles, else straight) as sub-paths — even-odd fill cuts them out. */
831
- polygonPathData(p, isBezier) {
832
- let d = isBezier
833
- ? this.ringBezierPath(p.xpoints, p.ypoints, p.handlesIn, p.handlesOut, p.closed !== false)
834
- : this.straightPath(p.xpoints, p.ypoints, p.closed !== false);
835
- const holeBezier = !!(p.bezier && p.holeHandlesIn && p.holeHandlesOut);
836
- (p.holes ?? []).forEach((ring, hi) => {
837
- if (ring.length < 3)
838
- return;
839
- const xs = ring.map((pt) => pt[0]);
840
- const ys = ring.map((pt) => pt[1]);
841
- if (holeBezier && p.holeHandlesIn[hi] && p.holeHandlesOut[hi]) {
842
- d += ' ' + this.ringBezierPath(xs, ys, p.holeHandlesIn[hi], p.holeHandlesOut[hi], true);
843
- }
844
- else {
845
- d += ' ' + this.straightPath(xs, ys, true);
846
- }
468
+ /**
469
+ * Rebuild every element from the store: the regions in world coordinates (one transformed
470
+ * group), their labels, and the overlay. Reads no layout: the camera affine is the viewer's.
471
+ */
472
+ redraw() {
473
+ this.renderer.setCamera(this.projection.affine());
474
+ this.renderer.render(this.regionsVisible ? this.store.getRegions() : [], this.selected);
475
+ this.renderOverlay();
476
+ }
477
+ /** Rebuild the screen-space overlay only: the selected regions' handles and the draft. */
478
+ renderOverlay() {
479
+ this.renderer.renderOverlay(this.regionsVisible ? this.store.getRegions() : [], this.selected, {
480
+ rect: this.draftRect,
481
+ path: this.draftPath,
847
482
  });
848
- return d;
849
- }
850
- /** SVG path data for a straight ring/polyline in image coords (closed appends `Z`). */
851
- straightPath(xs, ys, closed) {
852
- let d = '';
853
- for (let i = 0; i < xs.length; i++) {
854
- const [lx, ly] = this.toLocal(xs[i], ys[i]);
855
- d += (i === 0 ? 'M' : ' L') + ` ${lx},${ly}`;
856
- }
857
- return closed ? d + ' Z' : d;
858
- }
859
- /** SVG cubic-bezier path data for any ring (exterior or hole): anchors joined by cubic segments
860
- * whose control points are `anchor + handleOut` (leaving) and `nextAnchor + handleIn` (arriving),
861
- * in image space. Used for both the exterior and (donut) hole rings. */
862
- ringBezierPath(xs, ys, hIn, hOut, closed) {
863
- const n = xs.length;
864
- const anchor = (i) => this.toLocal(xs[i], ys[i]);
865
- const ctrlOut = (i) => this.toLocal(xs[i] + (hOut[i]?.[0] ?? 0), ys[i] + (hOut[i]?.[1] ?? 0));
866
- const ctrlIn = (i) => this.toLocal(xs[i] + (hIn[i]?.[0] ?? 0), ys[i] + (hIn[i]?.[1] ?? 0));
867
- const [sx, sy] = anchor(0);
868
- let d = `M ${sx},${sy}`;
869
- const segments = closed ? n : n - 1;
870
- for (let s = 0; s < segments; s++) {
871
- const i = s;
872
- const j = (s + 1) % n;
873
- const [c1x, c1y] = ctrlOut(i);
874
- const [c2x, c2y] = ctrlIn(j);
875
- const [ex, ey] = anchor(j);
876
- d += ` C ${c1x},${c1y} ${c2x},${c2y} ${ex},${ey}`;
877
- }
878
- if (closed)
879
- d += ' Z';
880
- return d;
881
- }
882
- style(el, stroke, isSelected) {
883
- el.setAttribute('stroke', stroke);
884
- el.setAttribute('stroke-width', isSelected ? '4' : '2');
885
- el.setAttribute('fill', isSelected ? stroke : 'none');
886
- el.setAttribute('fill-opacity', isSelected ? '0.35' : '0');
887
- el.setAttribute('vector-effect', 'non-scaling-stroke');
888
- }
889
- /** Draw the in-progress rectangle / path preview. */
890
- drawDraft() {
891
- if (this.draftRect) {
892
- const { x0, y0, x1, y1 } = this.draftRect;
893
- const [lx, ly] = this.toLocal(Math.min(x0, x1), Math.min(y0, y1));
894
- const [rx, ry] = this.toLocal(Math.max(x0, x1), Math.max(y0, y1));
895
- const el = document.createElementNS(SVG_NS, 'rect');
896
- el.setAttribute('x', `${lx}`);
897
- el.setAttribute('y', `${ly}`);
898
- el.setAttribute('width', `${Math.abs(rx - lx)}`);
899
- el.setAttribute('height', `${Math.abs(ry - ly)}`);
900
- this.styleDraft(el);
901
- this.svg.appendChild(el);
902
- }
903
- if (this.draftPath && this.draftPath.length) {
904
- const pts = this.draftPath.map(([x, y]) => this.toLocal(x, y).join(',')).join(' ');
905
- const el = document.createElementNS(SVG_NS, 'polyline');
906
- el.setAttribute('points', pts);
907
- this.styleDraft(el);
908
- this.svg.appendChild(el);
909
- }
910
- }
911
- styleDraft(el) {
912
- el.setAttribute('stroke', this.store.getShapeColor() || '#00ffff');
913
- el.setAttribute('stroke-width', '2');
914
- el.setAttribute('stroke-dasharray', '4 3');
915
- el.setAttribute('fill', 'none');
916
- el.setAttribute('vector-effect', 'non-scaling-stroke');
917
483
  }
918
484
  }
919
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXJlZ2lvbi1vdmVybGF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvbmFwYXJpLWpzL25hcGFyaS1yZWdpb24tb3ZlcmxheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3BDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRWpFLE9BQU8sRUFBRSxtQkFBbUIsRUFBRSxlQUFlLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUVoRixNQUFNLE1BQU0sR0FBRyw0QkFBNEIsQ0FBQztBQUM1Qzs7Ozs7Ozs7O0dBU0c7QUFDSCxNQUFNLGdCQUFnQixHQUFHLENBQUMsQ0FBQztBQUMzQjs7Ozs7Ozs7R0FRRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBQzNCLGtHQUFrRztBQUNsRyxNQUFNLGFBQWEsR0FBRyxFQUFFLENBQUM7QUFDekIsNEVBQTRFO0FBQzVFLE1BQU0sYUFBYSxHQUFHLENBQUMsQ0FBQztBQUN4Qix3Q0FBd0M7QUFDeEMsTUFBTSxXQUFXLEdBQUcsQ0FBQyxDQUFDO0FBaUJ0Qjs7Ozs7Ozs7Ozs7O0dBWUc7QUFDSCxNQUFNLE9BQU8sbUJBQW1CO0lBOEI5QixZQUNtQixJQUFpQixFQUNqQixNQUFxQixFQUNyQixLQUFrQjtRQUZsQixTQUFJLEdBQUosSUFBSSxDQUFhO1FBQ2pCLFdBQU0sR0FBTixNQUFNLENBQWU7UUFDckIsVUFBSyxHQUFMLEtBQUssQ0FBYTtRQS9CcEIsU0FBSSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFHbkMsU0FBSSxHQUFtQixNQUFNLENBQUM7UUFDOUIsYUFBUSxHQUFhLEVBQUUsQ0FBQztRQUVoQywrQ0FBK0M7UUFDdkMsY0FBUyxHQUE4RCxJQUFJLENBQUM7UUFDcEYs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LElBQUksQ0FBQyxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDM0QsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQztZQUNsQyxNQUFNLElBQUksR0FBRyxJQUFJLFNBQVMsRUFBRSxDQUFDO1lBQzdCLElBQUksQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDMUIsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUMxQixJQUFJLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUM7WUFDaEMsSUFBSSxDQUFDLEtBQUssQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDOUMsQ0FBQzthQUFNLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssUUFBUSxJQUFJLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUksSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDO1lBQzFGLElBQUksQ0FBQyxLQUFLLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUUsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzNGLENBQUM7YUFBTSxJQUNMLElBQUksQ0FBQyxJQUFJLENBQUMsSUFBSSxLQUFLLFlBQVk7WUFDL0IsSUFBSSxDQUFDLElBQUksQ0FBQyxTQUFTLElBQUksSUFBSTtZQUMzQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsSUFBSSxJQUFJLEVBQzdCLENBQUM7WUFDRCxJQUFJLENBQUMsS0FBSyxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDOUYsQ0FBQzthQUFNLElBQ0wsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEtBQUssWUFBWTtZQUMvQixJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsSUFBSSxJQUFJO1lBQzNCLElBQUksQ0FBQyxJQUFJLENBQUMsV0FBVyxJQUFJLElBQUk7WUFDN0IsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQ2QsQ0FBQztZQUNELElBQUksQ0FBQyxLQUFLLENBQUMsb0JBQW9CLENBQzdCLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxFQUNaLElBQUksQ0FBQyxJQUFJLENBQUMsU0FBUyxFQUNuQixJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFDckIsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLEVBQ2QsRUFBRSxFQUNGLEVBQUUsQ0FDSCxDQUFDO1FBQ0osQ0FBQztJQUNILENBQUM7SUFFRCwwRkFBMEY7SUFDbEYsY0FBYyxDQUFDLEVBQVUsRUFBRSxFQUFVO1FBQzNDLE1BQU0sR0FBRyxHQUFHLElBQUksQ0FBQyxjQUFjLEVBQUUsQ0FBQztRQUNsQyxNQUFNLENBQUMsR0FBRyxHQUFHLEVBQUUsTUFBTSxDQUFDO1FBQ3RCLElBQUksQ0FBQyxHQUFHLElBQUksQ0FBQyxDQUFDLElBQUksQ0FBQyxDQUFDLFNBQVMsSUFBSSxDQUFDLENBQUM7WUFBRSxPQUFPO1FBQzVDLE1BQU0sQ0FBQyxHQUFHLENBQVksQ0FBQztRQUN2QixJQUFJLE9BQU8sR0FBRyxDQUFDLENBQUM7UUFDaEIsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDO1FBQ3JCLE1BQU0sSUFBSSxHQUFHLENBQUMsQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLE9BQU8sQ0FBQztRQUM1RCxLQUFLLElBQUksQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsSUFBSSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDOUIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQztZQUM5QixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzVGLElBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDO2dCQUNkLEtBQUssR0FBRyxDQUFDLENBQUM7Z0JBQ1YsT0FBTyxHQUFHLENBQUMsQ0FBQztZQUNkLENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxPQUFPLEVBQUUsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO0lBQ2hELENBQUM7SUFFRCxnRkFBZ0Y7SUFDeEUsaUJBQWlCLENBQUMsRUFBVSxFQUFFLEVBQVU7UUFDOUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLGNBQWMsRUFBRSxDQUFDO1FBQ2xDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsRUFBRSxNQUFNLENBQUM7UUFDdEIsSUFBSSxDQUFDLEdBQUcsSUFBSSxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsU0FBUyxJQUFJLENBQUMsQ0FBQztZQUFFLE9BQU87UUFDNUMsTUFBTSxDQUFDLEdBQUcsQ0FBWSxDQUFDO1FBQ3ZCLElBQUksSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO1FBQ2QsSUFBSSxLQUFLLEdBQUcsUUFBUSxDQUFDO1FBQ3JCLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7WUFDbkMsTUFBTSxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDO1lBQzNELElBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxDQUFDO2dCQUNkLEtBQUssR0FBRyxDQUFDLENBQUM7Z0JBQ1YsSUFBSSxHQUFHLENBQUMsQ0FBQztZQUNYLENBQUM7UUFDSCxDQUFDO1FBQ0QsSUFBSSxJQUFJLElBQUksQ0FBQztZQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsSUFBSSxDQUFDLENBQUM7SUFDdkQsQ0FBQztJQUVELDhFQUE4RTtJQUN0RSxZQUFZLENBQ2xCLEVBQVUsRUFDVixFQUFVLEVBQ1YsRUFBVSxFQUNWLEVBQVUsRUFDVixFQUFVLEVBQ1YsRUFBVTtRQUVWLE1BQU0sRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLENBQUM7UUFDbkIsTUFBTSxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsQ0FBQztRQUNuQixNQUFNLElBQUksR0FBRyxFQUFFLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQztRQUNqRCxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNoQyxPQUFPLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxHQUFHLENBQUMsRUFBRSxHQUFHLENBQUMsR0FBRyxFQUFFLENBQUMsRUFBRSxFQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDNUQsQ0FBQztJQUVEOytFQUMyRTtJQUNuRSxhQUFhLENBQUMsQ0FBcUQ7UUFDekUsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNoQyxNQUFNLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ2hDLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDaEMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNoQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxJQUFJLEVBQUUsR0FBRyxFQUFFLEdBQUcsQ0FBQyxFQUFFLENBQUM7WUFDL0IsSUFBSSxDQUFDLEtBQUssQ0FBQyx1QkFBdUIsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUN2QyxPQUFPO1FBQ1QsQ0FBQztRQUNELE1BQU0sT0FBTyxHQUFhLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsS0FBSyxDQUFDLFVBQVUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUN2QyxJQUFJLENBQUMsQ0FBQyxTQUFTLEVBQUUsRUFBRTtnQkFBRSxPQUFPO1lBQzVCLE1BQU0sRUFBRSxHQUFHLElBQUksQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUIsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLEVBQUUsSUFBSSxFQUFFO2dCQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDdEYsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsS0FBSyxDQUFDLHVCQUF1QixDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQzlDLENBQUM7SUFFRCw4RkFBOEY7SUFDdEYsVUFBVSxDQUNoQixNQUFjO1FBRWQsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUN4QixJQUFJLENBQUMsQ0FBQztZQUFFLE9BQU8sSUFBSSxDQUFDO1FBQ3BCLElBQUksT0FBTyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDN0IsTUFBTSxDQUFDLEdBQUcsQ0FBYyxDQUFDO1lBQ3pCLE9BQU8sRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsS0FBSyxFQUFFLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNyRSxDQUFDO1FBQ0QsTUFBTSxHQUFHLEdBQUcsRUFBRSxFQUFFLEVBQUUsUUFBUSxFQUFFLEVBQUUsRUFBRSxRQUFRLEVBQUUsRUFBRSxFQUFFLENBQUMsUUFBUSxFQUFFLEVBQUUsRUFBRSxDQUFDLFFBQVEsRUFBRSxDQUFDO1FBQ3pFLE1BQU0sT0FBTyxHQUFHLENBQUMsRUFBWSxFQUFFLEVBQVksRUFBUSxFQUFFO1lBQ25ELEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxFQUFFLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFLENBQUM7Z0JBQ25DLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFO29CQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUNuQyxJQUFJLEVBQUUsQ0FBQyxDQUFDLENBQUMsR0FBRyxHQUFHLENBQUMsRUFBRTtvQkFBRSxHQUFHLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDbkMsSUFBSSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsR0FBRyxDQUFDLEVBQUU7b0JBQUUsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ25DLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxHQUFHLEdBQUcsQ0FBQyxFQUFFO29CQUFFLEdBQUcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3JDLENBQUM7UUFDSCxDQUFDLENBQUM7UUFDRixJQUFJLFNBQVMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNuQixNQUFNLENBQUMsR0FBRyxDQUFZLENBQUM7WUFDdkIsT0FBTyxDQUFDLENBQUMsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ2hDLENBQUM7YUFBTSxJQUFJLFVBQVUsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUMzQixLQUFLLE1BQU0sQ0FBQyxJQUFLLENBQTZCLENBQUMsUUFBUTtnQkFBRSxPQUFPLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLENBQUM7UUFDekYsQ0FBQzthQUFNLENBQUM7WUFDTixPQUFPLElBQUksQ0FBQztRQUNkLENBQUM7UUFDRCxPQUFPLFFBQVEsQ0FBQyxHQUFHLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDO0lBQ3ZDLENBQUM7SUFFRCw2RUFBNkU7SUFDckUsZUFBZSxDQUFDLENBQVMsRUFBRSxDQUFTLEVBQUUsS0FBYSxFQUFFLE1BQWM7UUFDekUsTUFBTSxJQUFJLEdBQUcsSUFBSSxTQUFTLEVBQUUsQ0FBQztRQUM3QixJQUFJLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUNYLElBQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ1gsSUFBSSxDQUFDLEtBQUssR0FBRyxLQUFLLENBQUM7UUFDbkIsSUFBSSxDQUFDLE1BQU0sR0FBRyxNQUFNLENBQUM7UUFDckIsTUFBTSxNQUFNLEdBQUcsSUFBSSxNQUFNLEVBQUUsQ0FBQztRQUM1QixNQUFNLENBQUMsTUFBTSxHQUFHLElBQUksQ0FBQztRQUNyQixNQUFNLENBQUMsS0FBSyxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUMsYUFBYSxFQUFFLENBQUM7UUFDMUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7SUFDL0IsQ0FBQztJQUVPLGFBQWEsQ0FBQyxNQUErQixFQUFFLE1BQWU7UUFDcEUsTUFBTSxJQUFJLEdBQUcsSUFBSSxPQUFPLEVBQUUsQ0FBQztRQUMzQixJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxNQUFNLENBQUM7UUFDN0IsSUFBSSxDQUFDLE9BQU8sR0FBRyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN2QyxJQUFJLENBQUMsT0FBTyxHQUFHLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxXQUFXLEdBQUcsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUNuRCxJQUFJLENBQUMsTUFBTSxHQUFHLE1BQU0sQ0FBQztRQUNyQixNQUFNLE1BQU0sR0FBRyxJQUFJLE1BQU0sRUFBRSxDQUFDO1FBQzVCLE1BQU0sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDO1FBQ3JCLE1BQU0sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUMxQyxNQUFNLENBQUMsS0FBSyxHQUFHLFFBQVEsQ0FBQztRQUN4QixJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsQ0FBQyxNQUFNLENBQUMsQ0FBQztJQUMvQixDQUFDO0lBRUQsNkVBQTZFO0lBQ3JFLE9BQU8sQ0FBQyxNQUFjLEVBQUUsQ0FBUyxFQUFFLENBQVM7UUFDbEQsTUFBTSxDQUFDLEdBQUcsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUN4QixJQUFJLENBQUMsQ0FBQztZQUFFLE9BQU8sS0FBSyxDQUFDO1FBQ3JCLElBQUksT0FBTyxJQUFJLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDN0IsTUFBTSxDQUFDLEdBQUcsQ0FBYyxDQUFDO1lBQ3pCLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsTUFBTSxDQUFDO1FBQzNFLENBQUM7UUFDRCxJQUFJLFNBQVMsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUNuQixNQUFNLENBQUMsR0FBRyxDQUFZLENBQUM7WUFDdkIsSUFBSSxNQUFNLEdBQUcsS0FBSyxDQUFDO1lBQ25CLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQztnQkFDMUQsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDeEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDeEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDeEIsTUFBTSxFQUFFLEdBQUcsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDeEIsSUFBSSxFQUFFLEdBQUcsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsR0FBRyxFQUFFO29CQUFFLE1BQU0sR0FBRyxDQUFDLE1BQU0sQ0FBQztZQUN6RixDQUFDO1lBQ0QsT0FBTyxNQUFNLENBQUM7UUFDaEIsQ0FBQztRQUNELE9BQU8sS0FBSyxDQUFDO0lBQ2YsQ0FBQztJQUVELHFGQUFxRjtJQUNyRixpQkFBaUIsQ0FBQyxPQUFnQjtRQUNoQyxJQUFJLE9BQU8sS0FBSyxJQUFJLENBQUMsY0FBYztZQUFFLE9BQU87UUFDNUMsSUFBSSxDQUFDLGNBQWMsR0FBRyxPQUFPLENBQUM7UUFDOUIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFRCxNQUFNO1FBQ0osT0FBTyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVU7WUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3RFLE1BQU0sT0FBTyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsVUFBVSxFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUNuRSxPQUFPLENBQUMsT0FBTyxDQUFDLENBQUMsTUFBTSxFQUFFLENBQUMsRUFBRSxFQUFFO1lBQzVCLElBQUksTUFBTSxDQUFDLFNBQVMsRUFBRSxFQUFFO2dCQUFFLE9BQU87WUFDakMsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDeEMsTUFBTSxFQUFFLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7WUFDN0MsSUFBSSxFQUFFO2dCQUFFLElBQUksQ0FBQyxHQUFHLENBQUMsV0FBVyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1lBQ2pDLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxDQUFDLENBQUM7WUFDdkIsSUFBSSxLQUFLO2dCQUFFLElBQUksQ0FBQyxXQUFXLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDdEMsQ0FBQyxDQUFDLENBQUM7UUFDSCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVELG1HQUFtRztJQUMzRixTQUFTLENBQUMsTUFBYztRQUM5QixJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxpQkFBaUIsRUFBRSxJQUFJLE1BQU0sQ0FBQyxTQUFTLEVBQUUsRUFBRTtZQUFFLE9BQU87UUFDcEUsTUFBTSxLQUFLLEdBQUcsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUMzQixNQUFNLENBQUMsR0FBRyxNQUFNLENBQUMsTUFBTSxDQUFDO1FBQ3hCLElBQUksQ0FBQyxLQUFLLElBQUksQ0FBQyxDQUFDO1lBQUUsT0FBTztRQUN6QixJQUFJLEVBQVUsQ0FBQztRQUNmLElBQUksRUFBVSxDQUFDO1FBQ2YsSUFBSSxPQUFPLElBQUksQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQztZQUM3QixFQUFFLEdBQUksQ0FBZSxDQUFDLENBQUMsQ0FBQztZQUN4QixFQUFFLEdBQUksQ0FBZSxDQUFDLENBQUMsQ0FBQztRQUMxQixDQUFDO2FBQU0sSUFBSSxTQUFTLElBQUksQ0FBQyxFQUFFLENBQUM7WUFDMUIsTUFBTSxDQUFDLEdBQUcsQ0FBWSxDQUFDO1lBQ3ZCLEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1lBQzFELEVBQUUsR0FBRyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzVELENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTztRQUNULENBQUM7UUFDRCxNQUFNLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsRUFBRSxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQ3RDLE1BQU0sSUFBSSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3RELElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUNoQyxJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsR0FBRyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxZQUFZLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ2xDLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3BDLElBQUksQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3ZDLElBQUksQ0FBQyxZQUFZLENBQUMsYUFBYSxFQUFFLFFBQVEsQ0FBQyxDQUFDO1FBQzNDLElBQUks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RUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDekUsTUFBTSxNQUFNLEdBQUcsQ0FBQyxDQUFTLEVBQW9CLEVBQUUsQ0FDN0MsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQ3ZFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzNCLElBQUksQ0FBQyxHQUFHLEtBQUssRUFBRSxJQUFJLEVBQUUsRUFBRSxDQUFDO1FBQ3hCLE1BQU0sUUFBUSxHQUFHLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO1FBQ3BDLEtBQUssSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFLENBQUMsR0FBRyxRQUFRLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNsQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDWixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7WUFDdEIsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxPQUFPLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDOUIsTUFBTSxDQUFDLEdBQUcsRUFBRSxHQUFHLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDN0IsTUFBTSxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsR0FBRyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDM0IsQ0FBQyxJQUFJLE1BQU0sR0FBRyxJQUFJLEdBQUcsSUFBSSxHQUFHLElBQUksR0FBRyxJQUFJLEVBQUUsSUFBSSxFQUFFLEVBQUUsQ0FBQztRQUNwRCxDQUFDO1FBQ0QsSUFBSSxNQUFNO1lBQUUsQ0FBQyxJQUFJLElBQUksQ0FBQztRQUN0QixPQUFPLENBQUMsQ0FBQztJQUNYLENBQUM7SUFFTyxLQUFLLENBQUMsRUFBYyxFQUFFLE1BQWMsRUFBRSxVQUFtQjtRQUMvRCxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUNsQyxFQUFFLENBQUMsWUFBWSxDQUFDLGNBQWMsRUFBRSxVQUFVLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUM7UUFDeEQsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsVUFBVSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3RELEVBQUUsQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLFVBQVUsQ0FBQyxDQUFDLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQztRQUMzRCxFQUFFLENBQUMsWUFBWSxDQUFDLGVBQWUsRUFBRSxvQkFBb0IsQ0FBQyxDQUFDO0lBQ3pELENBQUM7SUFFRCxxREFBcUQ7SUFDN0MsU0FBUztRQUNmLElBQUksSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDO1lBQ25CLE1BQU0sRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsU0FBUyxDQUFDO1lBQzFDLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2xFLE1BQU0sQ0FBQyxFQUFFLEVBQUUsRUFBRSxDQUFDLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsRUFBRSxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDO1lBQ2xFLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1lBQ3BELEVBQUUsQ0FBQyxZQUFZLENBQUMsR0FBRyxFQUFFLEdBQUcsRUFBRSxFQUFFLENBQUMsQ0FBQztZQUM5QixFQUFFLENBQUMsWUFBWSxDQUFDLEdBQUcsRUFBRSxHQUFHLEVBQUUsRUFBRSxDQUFDLENBQUM7WUFDOUIsRUFBRSxDQUFDLFlBQVksQ0FBQyxPQUFPLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDakQsRUFBRSxDQUFDLFlBQVksQ0FBQyxRQUFRLEVBQUUsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsR0FBRyxFQUFFLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDbEQsSUFBSSxDQUFDLFVBQVUsQ0FBQyxFQUFFLENBQUMsQ0FBQztZQUNwQixJQUFJLENBQUMsR0FBRyxDQUFDLFdBQVcsQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUMzQixDQUFDO1FBQ0QsSUFBSSxJQUFJLENBQUMsU0FBUyxJQUFJLElBQUksQ0FBQyxTQUFTLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDNUMsTUFBTSxHQUFHLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxDQUFDO1lBQ25GLE1BQU0sRUFBRSxHQUFHLFFBQVEsQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO1lBQ3hELEVBQUUsQ0FBQyxZQUFZLENBQUMsUUFBUSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7WUFDcEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxXQUFXLENBQUMsRUFBRSxDQUFDLENBQUM7UUFDM0IsQ0FBQztJQUNILENBQUM7SUFFTyxVQUFVLENBQUMsRUFBYztRQUMvQixFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLGFBQWEsRUFBRSxJQUFJLFNBQVMsQ0FBQyxDQUFDO1FBQ25FLEVBQUUsQ0FBQyxZQUFZLENBQUMsY0FBYyxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQ3JDLEVBQUUsQ0FBQyxZQUFZLENBQUMsa0JBQWtCLEVBQUUsS0FBSyxDQUFDLENBQUM7UUFDM0MsRUFBRSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDaEMsRUFBRSxDQUFDLFlBQVksQ0FBQyxlQUFlLEVBQUUsb0JBQW9CLENBQUMsQ0FBQztJQUN6RCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcblxuaW1wb3J0IHsgSVJlZ2lvbk92ZXJsYXksIFJlZ2lvblRvb2xNb2RlIH0gZnJvbSAnLi4vLi4vY29udHJhY3RzL3JlZ2lvbi1vdmVybGF5LmNvbnRyYWN0JztcbmltcG9ydCB7IFJlZ2lvbiwgUmVjdGFuZ2xlLCBQb2x5Z29uIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3JlZ2lvbic7XG5pbXBvcnQgeyBSZWdpb25TdG9yZSB9IGZyb20gJy4uLy4uL3N0b3JlL3JlZ2lvbi1zdG9yZS5zZXJ2aWNlJztcbmltcG9ydCB7IFBJWEVMX1dPUkxEX1FVQU5UVU0sIHNuYXBUb1dvcmxkR3JpZCB9IGZyb20gJy4uLy4uL3NwYXRpYWwvd29ybGQtZ3JpZCc7XG5cbmNvbnN0IFNWR19OUyA9ICdodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Zyc7XG4vKipcbiAqIE1pbiBkcmFnIGJlZm9yZSBhIGZyZWVoYW5kIHBhdGggcmVjb3JkcyBhbm90aGVyIHBvaW50LCBpbiBTQ1JFRU4gcGl4ZWxzLlxuICpcbiAqIFNjcmVlbiByYXRoZXIgdGhhbiB3b3JsZCwgd2hpY2ggaXMgd2hhdCBcIjIgaW1hZ2UgcHhcIiBhbHdheXMgbWVhbnQgaW4gcHJhY3RpY2U6IGF0IDEwMCVcbiAqIHpvb20gb3ZlciBhbiBpbWFnZSB0aGUgdHdvIGFyZSB0aGUgc2FtZSB0aGluZy4gVGFrZW4gYXMgd29ybGQgdW5pdHMgaXQgYnJlYWtzIG9uIGFueVxuICogZGF0YXNldCB3aG9zZSB3b3JsZCBpcyBzbWFsbCDigJQgc2VxRklTSCdzIHNhbXBsZSBzcGFucyBhYm91dCA1IHVuaXRzLCBzbyBhIDItdW5pdFxuICogdGhyZXNob2xkIHJlY29yZHMgYSBwb2ludCBldmVyeSA0MCUgb2YgdGhlIHdheSBhY3Jvc3MgYW5kIGEgZnJlZWhhbmQgUk9JIGNvbWVzIG91dCBhcyBhXG4gKiB0cmlhbmdsZS4gQWdhaW5zdCB0aGUgc2NyZWVuIGl0IGFsc28gZG9lcyB0aGUgcmlnaHQgdGhpbmcgdW5kZXIgem9vbTogZHJhd2luZyB6b29tZWQgaW5cbiAqIHJlY29yZHMgYSBmaW5lciBwYXRoLCBiZWNhdXNlIHRoYXQgaXMgZXhhY3RseSB3aGVuIHRoZSBleHRyYSBkZXRhaWwgaXMgdmlzaWJsZS5cbiAqL1xuY29uc3QgRlJFRUhBTkRfU1RFUF9QWCA9IDI7XG4vKipcbiAqIFNtYWxsZXN0IGNvbW1pdHRlZCByZWN0YW5nbGUsIGluIFNDUkVFTiBwaXhlbHMgb24gZWFjaCBzaWRlLlxuICpcbiAqIEl0cyBqb2IgaXMgdG8gdGhyb3cgYXdheSBhIGNsaWNrIHRoYXQgd2FzIG5vdCBhIGRyYWcuIEhlbGQgaW4gd29ybGQgdW5pdHMg4oCUIHdoaWNoIGl0IHdhc1xuICog4oCUIGl0IGluc3RlYWQgdGhyb3dzIGF3YXkgcmVhbCBkcmFncyBvbiBhbnkgZGF0YXNldCB3aG9zZSB3b3JsZCBpcyBzbWFsbDogaW4gc2VxRklTSCdzXG4gKiB+NSB4IDcgdW5pdCBzYW1wbGUgYSByZWN0YW5nbGUgaGFkIHRvIGNvdmVyIDQwJSBvZiB0aGUgd2lkdGggdG8gY29tbWl0IGF0IGFsbCwgYW5kXG4gKiBhbnl0aGluZyBzbWFsbGVyIHZhbmlzaGVkIHdpdGggbm8gZmVlZGJhY2suIFRoYXQgd2FzIHRoZSBkaXJlY3QgY2F1c2Ugb2YgUk9JcyBiZWluZ1xuICogaW1wb3NzaWJsZSB0byBjcmVhdGUgdGhlcmUuXG4gKi9cbmNvbnN0IE1JTl9SRUNUX0RSQUdfUFggPSAyO1xuLyoqIENsaWNrLWRpc3RhbmNlIChzY3JlZW4gcHgpIHdpdGhpbiB3aGljaCBhIHBvbHlnb24gY2xpY2sgc25hcHMgY2xvc2VkIG9udG8gdGhlIGZpcnN0IHZlcnRleC4gKi9cbmNvbnN0IENMT1NFX1NOQVBfUFggPSAxMDtcbi8qKiBTY3JlZW4tcHggaGl0IHJhZGl1cyBmb3IgZ3JhYmJpbmcgYSB2ZXJ0ZXggLyByZWN0YW5nbGUgY29ybmVyIGhhbmRsZS4gKi9cbmNvbnN0IEhBTkRMRV9ISVRfUFggPSA5O1xuLyoqIFJlbmRlcmVkIGhhbmRsZSBzaXplIChzY3JlZW4gcHgpLiAqL1xuY29uc3QgSEFORExFX1NJWkUgPSA3O1xuXG4vKipcbiAqIFRoZSBzbGljZSBvZiB0aGUgbmFwYXJpIFZpZXdlciB0aGUgb3ZlcmxheSBuZWVkcyAoY29vcmQgdHJhbnNmb3JtcyArIGNvbnRyb2wgZ2F0aW5nKS5cbiAqXG4gKiBFeHBvcnRlZCBiZWNhdXNlIHRoZSAzRCBzcGF0aWFsIG1vZGUgc3VwcGxpZXMgYSBTQ1JFRU4tU1BBQ0UgaW1wbGVtZW50YXRpb24gb2YgaXQ6IHRoZXJlIHRoZVxuICogZHJhd24gc2hhcGUgaXMgYSBsYXNzbyBpbiBjYW52YXMgcGl4ZWxzLCBub3QgYSByZWN0YW5nbGUgaW4gaW1hZ2Ugc3BhY2UsIHNvIFwid29ybGRcIiBpcyB0aGVcbiAqIGNhbnZhcyBpdHNlbGYgYW5kIGJvdGggdHJhbnNmb3JtcyBjb2xsYXBzZSB0byBpZGVudGl0eS4gVGhhdCBsZXRzIHRoZSAzRCB2aWV3IHJldXNlIHRoaXMgd2hvbGVcbiAqIG92ZXJsYXkg4oCUIGV2ZXJ5IHRvb2wsIHRoZSBoYW5kbGVzLCB0aGUgc3RvcmUgcm91bmQtdHJpcCDigJQgd2l0aCBubyAzRC1zcGVjaWZpYyBkcmF3aW5nIGNvZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3ZlcmxheVZpZXdlciB7XG4gIGNhbnZhc1RvV29ybGQoY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdO1xuICB3b3JsZFRvQ2FudmFzKHdvcmxkWDogbnVtYmVyLCB3b3JsZFk6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl07XG4gIHNldENvbnRyb2xzRW5hYmxlZChlbmFibGVkOiBib29sZWFuKTogdm9pZDtcbiAgcmVhZG9ubHkgY2FtZXJhOiB7IHJlYWRvbmx5IGNoYW5nZWQ6IHsgY29ubmVjdChsaXN0ZW5lcjogKCkgPT4gdm9pZCk6ICgpID0+IHZvaWQgfSB9O1xufVxuXG4vKipcbiAqIFNWRyByZWdpb24gb3ZlcmxheSBmb3IgdGhlIG5hcGFyaS1qcyBXZWJHUFUgaW1hZ2UgdmlldyAoaml0LXVpIzEwMiksIG1pcnJvcmluZyB0aGUgT1NEIGJhY2tlbmQnc1xuICoge0BsaW5rIE9zZFJlZ2lvbk92ZXJsYXl9IGJ1dCBkcml2ZW4gYnkgbmFwYXJpJ3MgYGNhbnZhc1RvV29ybGRgL2B3b3JsZFRvQ2FudmFzYCB0cmFuc2Zvcm1zLlxuICogVmVjdG9yIHNoYXBlcyBhcmUgZHJhd24gaW4gYW4gYWJzb2x1dGVseS1wb3NpdGlvbmVkIGA8c3ZnPmAgb3ZlciB0aGUgY2FudmFzIChubyBuZWVkIHRvIHB1c2hcbiAqIHRoZW0gdGhyb3VnaCBXZWJHUFUpLiBJdCB3cml0ZXMgY29tcGxldGVkIHNoYXBlcyB0byB0aGUgc2hhcmVkIHtAbGluayBSZWdpb25TdG9yZX0gKHNvIHNhdmUgL1xuICogdW5kbyAvIGV4cG9ydCB3b3JrIGlkZW50aWNhbGx5IHRvIE9TRCkgYW5kIHJlLXJlbmRlcnMgZnJvbSB0aGUgc3RvcmUgb24gZXZlcnkgY2FtZXJhIG1vdmUsXG4gKiByZWdpb24gY2hhbmdlLCBhbmQgc2VsZWN0aW9uIGNoYW5nZS5cbiAqXG4gKiBTdXBwb3J0cyAoaml0LXVpIzEwMik6IHJlY3RhbmdsZSAvIHBvbHlnb24gLyBmcmVlaGFuZCBwYXRoIGRyYXdpbmcsIGNsaWNrLXNlbGVjdCBhbmQgcnViYmVyLWJhbmRcbiAqIG1hcnF1ZWUgc2VsZWN0LCBwYW4vem9vbSBnYXRpbmcgdmlhIGBzZXRDb250cm9sc0VuYWJsZWRgLCBib2R5IG1vdmUsIHZlcnRleCBtb3ZlL2FkZC9kZWxldGUsXG4gKiBiZXppZXIgaGFuZGxlIGVkaXRpbmcsIGFuZCBkb251dCBob2xlcyAoaW5jbHVkaW5nIGhvbGUgdmVydGV4ICsgaG9sZS1iZXppZXItaGFuZGxlIGVkaXRpbmcpIOKAlFxuICogZnVsbCBwYXJpdHkgd2l0aCB7QGxpbmsgT3NkUmVnaW9uT3ZlcmxheX0uXG4gKi9cbmV4cG9ydCBjbGFzcyBOYXBhcmlSZWdpb25PdmVybGF5IGltcGxlbWVudHMgSVJlZ2lvbk92ZXJsYXkge1xuICBwcml2YXRlIHJlYWRvbmx5IHN2ZzogU1ZHU1ZHRWxlbWVudDtcbiAgcHJpdmF0ZSByZWFkb25seSBzdWJzID0gbmV3IFN1YnNjcmlwdGlvbigpO1xuICBwcml2YXRlIHJlYWRvbmx5IGRpc2Nvbm5lY3RDYW1lcmE6ICgpID0+IHZvaWQ7XG5cbiAgcHJpdmF0ZSBtb2RlOiBSZWdpb25Ub29sTW9kZSA9ICdub25lJztcbiAgcHJpdmF0ZSBzZWxlY3RlZDogbnVtYmVyW10gPSBbXTtcblxuICAvKiogSW4tcHJvZ3Jlc3MgZHJhd2luZyBzdGF0ZSAoaW1hZ2Utc3BhY2UpLiAqL1xuICBwcml2YXRlIGRyYWZ0UmVjdDogeyB4MDogbnVtYmVyOyB5MDogbnVtYmVyOyB4MTogbnVtYmVyOyB5MTogbnVtYmVyIH0gfCBudWxsID0gbnVsbDtcbiAgLyoqIEluLXByb2dyZXNzIHJ1YmJlci1iYW5kIHNlbGVjdGlvbiBtYXJxdWVlIChzZWxlY3QgbW9kZSksIGltYWdlLXNwYWNlLiAqL1xuICBwcml2YXRlIG1hcnF1ZWU6IHsgeDA6IG51bWJlcjsgeTA6IG51bWJlcjsgeDE6IG51bWJlcjsgeTE6IG51bWJlciB9IHwgbnVsbCA9IG51bGw7XG4gIC8qKiBEZWRpY2F0ZWQgbWFycXVlZSByZWN0IGVsZW1lbnQsIHVwZGF0ZWQgZGlyZWN0bHkgZHVyaW5nIHRoZSBkcmFnIChubyBmdWxsIHJlZ2lvbiByZWRyYXcpLiAqL1xuICBwcml2YXRlIG1hcnF1ZWVFbDogU1ZHUmVjdEVsZW1lbnQgfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBkcmFmdFBhdGg6IEFycmF5PFtudW1iZXIsIG51bWJlcl0+IHwgbnVsbCA9IG51bGw7IC8vIGZyZWVoYW5kIG9yIGNsaWNrIHBvbHlnb25cbiAgcHJpdmF0ZSBkcmF3aW5nID0gZmFsc2U7IC8vIHBvaW50ZXIgaXMgZG93biBmb3IgcmVjdCAvIGZyZWVoYW5kXG4gIHByaXZhdGUgcmVnaW9uc1Zpc2libGUgPSB0cnVlO1xuXG4gIC8qKiBJbi1wcm9ncmVzcyBtYW5pcHVsYXRpb24gKHNlbGVjdC9tb3ZlIG1vZGVzKTogZHJhZ2dpbmcgYSBib2R5LCBhIHBvbHlnb24gdmVydGV4LCBvciBhXG4gICAqICByZWN0YW5nbGUgY29ybmVyLiBgYW5jaG9yYCBpcyB0aGUgZml4ZWQgb3Bwb3NpdGUgY29ybmVyIGZvciBhIHJlY3RhbmdsZSByZXNpemUuICovXG4gIHByaXZhdGUgZWRpdDoge1xuICAgIGtpbmQ6ICdib2R5JyB8ICd2ZXJ0ZXgnIHwgJ2Nvcm5lcicgfCAnYmV6aWVyJyB8ICdob2xldmVydGV4JyB8ICdob2xlYmV6aWVyJztcbiAgICBpZDogbnVtYmVyO1xuICAgIHZlcnRleEluZGV4PzogbnVtYmVyO1xuICAgIGhvbGVJbmRleD86IG51bWJlcjtcbiAgICBzaWRlPzogJ2luJyB8ICdvdXQnO1xuICAgIGFuY2hvcj86IFtudW1iZXIsIG51bWJlcl07XG4gICAgbGFzdDogW251bWJlciwgbnVtYmVyXTtcbiAgfSB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaG9zdDogSFRNTEVsZW1lbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSB2aWV3ZXI6IE92ZXJsYXlWaWV3ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzdG9yZTogUmVnaW9uU3RvcmUsXG4gICkge1xuICAgIGlmIChnZXRDb21wdXRlZFN0eWxlKGhvc3QpLnBvc2l0aW9uID09PSAnc3RhdGljJykgaG9zdC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5zdmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAnc3ZnJyk7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLnN2Zy5zdHlsZSwge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICBpbnNldDogJzAnLFxuICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgekluZGV4OiAnMjAnLFxuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLCAvLyB1bnRpbCBhIHRvb2wgYWN0aXZhdGVzXG4gICAgICB0b3VjaEFjdGlvbjogJ25vbmUnLFxuICAgIH0gYXMgUGFydGlhbDxDU1NTdHlsZURlY2xhcmF0aW9uPik7XG4gICAgdGhpcy5ob3N0LmFwcGVuZENoaWxkKHRoaXMuc3ZnKTtcblxuICAgIHRoaXMuc3ZnLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5vblBvaW50ZXJEb3duKTtcbiAgICB0aGlzLnN2Zy5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMub25Qb2ludGVyTW92ZSk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcignZGJsY2xpY2snLCB0aGlzLm9uRGJsQ2xpY2spO1xuXG4gICAgdGhpcy5zdWJzLmFkZCh0aGlzLnN0b3JlLmdldFJlZ2lvblVwZGF0ZUV2ZW50KCkuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVkcmF3KCkpKTtcbiAgICB0aGlzLnN1YnMuYWRkKFxuICAgICAgdGhpcy5zdG9yZS5nZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyQoKS5zdWJzY3JpYmUoKGlkeCkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkID0gaWR4ID8/IFtdO1xuICAgICAgICB0aGlzLnJlZHJhdygpO1xuICAgICAgfSksXG4gICAgKTtcbiAgICB0aGlzLmRpc2Nvbm5lY3RDYW1lcmEgPSB0aGlzLnZpZXdlci5jYW1lcmEuY2hhbmdlZC5jb25uZWN0KCgpID0+IHRoaXMucmVkcmF3KCkpO1xuICAgIHRoaXMucmVkcmF3KCk7XG4gIH1cblxuICAvLyDilIDilIAgSVJlZ2lvbk92ZXJsYXkg4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSA4pSAXG4gIC8qKlxuICAgKiBXaGV0aGVyIGEgcmVnaW9uIHRvb2wgY3VycmVudGx5IG93bnMgdGhlIHBvaW50ZXIuXG4gICAqXG4gICAqIEV4cG9zZWQgc28gdGhlIHNwYXRpYWwgdmlld3MgY2FuIHRlbGwgYSBiYXJlIGNsaWNrIG9uIHRoZSBjbG91ZCAoc2VsZWN0IHRoZVxuICAgKiBjbGFzcyB1bmRlciB0aGUgY3Vyc29yKSBmcm9tIGEgY2xpY2sgdGhhdCBiZWxvbmdzIHRvIGEgZHJhd2luZyBnZXN0dXJlIOKAlFxuICAgKiBwbGFjaW5nIGEgcG9seWdvbiB2ZXJ0ZXggaXMgYWxzbyBhIGNsaWNrIHRoYXQgZG9lcyBub3QgbW92ZSwgYW5kIGl0IG11c3Qgbm90XG4gICAqIGNoYW5nZSB0aGUgc2VsZWN0aW9uIGJlaGluZCB0aGUgc2hhcGUgYmVpbmcgZHJhd24uXG4gICAqL1xuICBnZXQgdG9vbEFjdGl2ZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5tb2RlICE9PSAnbm9uZSc7XG4gIH1cblxuICBzZXRNb2RlKG1vZGU6IFJlZ2lvblRvb2xNb2RlKTogdm9pZCB7XG4gICAgdGhpcy5tb2RlID0gbW9kZTtcbiAgICB0aGlzLmRyYWZ0UmVjdCA9IG51bGw7XG4gICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgIHRoaXMubWFycXVlZSA9IG51bGw7XG4gICAgdGhpcy5jbGVhck1hcnF1ZWVFbCgpO1xuICAgIHRoaXMuZHJhd2luZyA9IGZhbHNlO1xuICAgIC8vIFRoZSBvdmVybGF5IG93bnMgcG9pbnRlci9uYXZpZ2F0aW9uIGdhdGluZzogd2hpbGUgYSB0b29sIGlzIGFjdGl2ZSBpdCBjYXB0dXJlcyB0aGUgcG9pbnRlclxuICAgIC8vIGFuZCB0aGUgbmFwYXJpIGNhbWVyYSBjb250cm9scyBhcmUgZGlzYWJsZWQ7ICdub25lJyBoYW5kcyB0aGUgcG9pbnRlciBiYWNrIGZvciBwYW4vem9vbS5cbiAgICBjb25zdCBhY3RpdmUgPSBtb2RlICE9PSAnbm9uZSc7XG4gICAgdGhpcy52aWV3ZXIuc2V0Q29udHJvbHNFbmFibGVkKCFhY3RpdmUpO1xuICAgIHRoaXMuc3ZnLnN0eWxlLnBvaW50ZXJFdmVudHMgPSBhY3RpdmUgPyAnYXV0bycgOiAnbm9uZSc7XG4gICAgdGhpcy5zdmcuc3R5bGUuY3Vyc29yID0gYWN0aXZlID8gJ2Nyb3NzaGFpcicgOiAnZGVmYXVsdCc7XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfVxuXG4gIHNldFNlbGVjdGVkQmV6aWVyKGJlemllcjogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb24oKTtcbiAgICBpZiAoc2VsPy5pZCAhPSBudWxsKSB0aGlzLnN0b3JlLnNldEJlemllcihzZWwuaWQsIGJlemllcik7XG4gIH1cblxuICAvKipcbiAgICogSG93IGZpbmVseSBhIGRyYXduIHZlcnRleCBtYXkgYmUgcGxhY2VkLCBpbiB3b3JsZCB1bml0cy5cbiAgICpcbiAgICogT25lIGJ5IGRlZmF1bHQsIGJlY2F1c2UgZm9yIGFuIGltYWdlIHRoZSB3b3JsZCBJUyBwaXhlbHMgYW5kIGEgcmVnaW9uIHNob3VsZCBhbGlnbiB0b1xuICAgKiB0aGVtLiBBIGRhdGFzZXQgd2hvc2UgY29vcmRpbmF0ZXMgYXJlIG5vdCBwaXhlbHMgc2V0cyBpdCBmaW5lciDigJQgc2VxRklTSCdzIHdob2xlXG4gICAqIHNhbXBsZSBzcGFucyBhYm91dCA1IHggNyB1bml0cywgd2hlcmUgd2hvbGUtdW5pdCB2ZXJ0aWNlcyBsZWF2ZSByb3VnaGx5IHNpeCBieSBlaWdodFxuICAgKiBwbGFjZWFibGUgcG9zaXRpb25zIGFuZCBubyBST0kgY2FuIGJlIGRyYXduIGF0IGFsbC5cbiAgICovXG4gIHByaXZhdGUgd29ybGRRdWFudHVtID0gUElYRUxfV09STERfUVVBTlRVTTtcblxuICBzZXRXb3JsZFF1YW50dW0ocXVhbnR1bTogbnVtYmVyKTogdm9pZCB7XG4gICAgdGhpcy53b3JsZFF1YW50dW0gPSBOdW1iZXIuaXNGaW5pdGUocXVhbnR1bSkgJiYgcXVhbnR1bSA+IDBcbiAgICAgID8gcXVhbnR1bVxuICAgICAgOiBQSVhFTF9XT1JMRF9RVUFOVFVNO1xuICB9XG5cbiAgZGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLnN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVyZG93bicsIHRoaXMub25Qb2ludGVyRG93bik7XG4gICAgdGhpcy5zdmcucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcm1vdmUnLCB0aGlzLm9uUG9pbnRlck1vdmUpO1xuICAgIHRoaXMuc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJ1cCcsIHRoaXMub25Qb2ludGVyVXApO1xuICAgIHRoaXMuc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2RibGNsaWNrJywgdGhpcy5vbkRibENsaWNrKTtcbiAgICB0aGlzLmRpc2Nvbm5lY3RDYW1lcmEoKTtcbiAgICB0aGlzLnN1YnMudW5zdWJzY3JpYmUoKTtcbiAgICBpZiAodGhpcy5zdmcucGFyZW50Tm9kZSkgdGhpcy5zdmcucGFyZW50Tm9kZS5yZW1vdmVDaGlsZCh0aGlzLnN2Zyk7XG4gIH1cblxuICAvLyDilIDilIAgY29vcmRpbmF0ZSB0cmFuc2Zvcm1zIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvKiogUG9pbnRlciBjbGllbnQgY29vcmRzIOKGkiB3b3JsZCBjb29yZHMsIHNuYXBwZWQgdG8ge0BsaW5rIHdvcmxkUXVhbnR1bX0uICovXG4gIHByaXZhdGUgdG9JbWFnZShjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGNvbnN0IFt3eCwgd3ldID0gdGhpcy52aWV3ZXIuY2FudmFzVG9Xb3JsZChjbGllbnRYLCBjbGllbnRZKTtcbiAgICByZXR1cm4gW1xuICAgICAgc25hcFRvV29ybGRHcmlkKHd4LCB0aGlzLndvcmxkUXVhbnR1bSksXG4gICAgICBzbmFwVG9Xb3JsZEdyaWQod3ksIHRoaXMud29ybGRRdWFudHVtKSxcbiAgICBdO1xuICB9XG5cbiAgLyoqXG4gICAqIFdvcmxkIHVuaXRzIHNwYW5uZWQgYnkgb25lIHNjcmVlbiBwaXhlbCwgbWVhc3VyZWQgdGhyb3VnaCB0aGUgdmlld2VyJ3Mgb3duIHRyYW5zZm9ybS5cbiAgICpcbiAgICogUmVhZCBmcm9tIHRoZSB0cmFuc2Zvcm0gcmF0aGVyIHRoYW4gZnJvbSB0aGUgY2FtZXJhLCBzbyBpdCBob2xkcyBmb3IgYm90aCB0aGUgMkQgYW5kXG4gICAqIHRoZSAzRCBzY3JlZW4tc3BhY2UgYWRhcHRlcnMgd2l0aG91dCBlaXRoZXIgaGF2aW5nIHRvIGV4cG9zZSBhIHpvb20uIEZhbGxzIGJhY2sgdG8gMVxuICAgKiBpZiB0aGUgdHJhbnNmb3JtIGdpdmVzIG5vdGhpbmcgdXNhYmxlLCB3aGljaCBrZWVwcyB0aGUgZXN0YWJsaXNoZWQgcGl4ZWwgYmVoYXZpb3VyXG4gICAqIHJhdGhlciB0aGFuIGNvbGxhcHNpbmcgdGhlIHRocmVzaG9sZCB0byB6ZXJvIGFuZCByZWNvcmRpbmcgYSBwb2ludCBwZXIgZXZlbnQuXG4gICAqL1xuICBwcml2YXRlIHdvcmxkUGVyQ2FudmFzUGl4ZWwoKTogbnVtYmVyIHtcbiAgICBjb25zdCBbeDBdID0gdGhpcy52aWV3ZXIuY2FudmFzVG9Xb3JsZCgwLCAwKTtcbiAgICBjb25zdCBbeDFdID0gdGhpcy52aWV3ZXIuY2FudmFzVG9Xb3JsZCgxLCAwKTtcbiAgICBjb25zdCBwZXIgPSBNYXRoLmFicyh4MSAtIHgwKTtcbiAgICByZXR1cm4gTnVtYmVyLmlzRmluaXRlKHBlcikgJiYgcGVyID4gMCA/IHBlciA6IDE7XG4gIH1cblxuICAvKiogSW1hZ2UgY29vcmRzIOKGkiBTVkctbG9jYWwgcHggKHRoZSBzdmcgb3ZlcmxheXMgdGhlIGNhbnZhcyBhdCB0aGUgc2FtZSBjbGllbnQgcmVjdCkuICovXG4gIHByaXZhdGUgdG9Mb2NhbChpbWdYOiBudW1iZXIsIGltZ1k6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0ge1xuICAgIGNvbnN0IFtjeCwgY3ldID0gdGhpcy52aWV3ZXIud29ybGRUb0NhbnZhcyhpbWdYLCBpbWdZKTtcbiAgICBjb25zdCByID0gdGhpcy5zdmcuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgcmV0dXJuIFtjeCAtIHIubGVmdCwgY3kgLSByLnRvcF07XG4gIH1cblxuICAvLyDilIDilIAgcG9pbnRlciBoYW5kbGVycyDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJEb3duID0gKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGlmICh0aGlzLm1vZGUgPT09ICdub25lJykgcmV0dXJuO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBbaXgsIGl5XSA9IHRoaXMudG9JbWFnZShlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdyZWN0Jykge1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSB7IHgwOiBpeCwgeTA6IGl5LCB4MTogaXgsIHkxOiBpeSB9O1xuICAgICAgdGhpcy5kcmF3aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuc3ZnLnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdjbG9zZWRwYXRoJyB8fCB0aGlzLm1vZGUgPT09ICdkcmF3b3BlbnBhdGgnKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICB0aGlzLmRyYXdpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZHJhd3BvbHlnb24nKSB7XG4gICAgICB0aGlzLmhhbmRsZVBvbHlnb25DbGljayhpeCwgaXksIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ3NlbGVjdCcgfHwgdGhpcy5tb2RlID09PSAnbW92ZScpIHtcbiAgICAgIHRoaXMuYmVnaW5NYW5pcHVsYXRpb24oaXgsIGl5LCBlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2FkZHBvaW50Jykge1xuICAgICAgdGhpcy5oYW5kbGVBZGRQb2ludChpeCwgaXkpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZGVsZXRlcG9pbnQnKSB7XG4gICAgICB0aGlzLmhhbmRsZURlbGV0ZVBvaW50KGl4LCBpeSk7XG4gICAgfVxuICAgIHRoaXMucmVkcmF3KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJNb3ZlID0gKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IFtpeCwgaXldID0gdGhpcy50b0ltYWdlKGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICBpZiAodGhpcy5tYXJxdWVlKSB7XG4gICAgICB0aGlzLm1hcnF1ZWUueDEgPSBpeDtcbiAgICAgIHRoaXMubWFycXVlZS55MSA9IGl5O1xuICAgICAgdGhpcy51cGRhdGVNYXJxdWVlRWwoKTsgLy8gdXBkYXRlIGp1c3QgdGhlIG1hcnF1ZWUgcmVjdCDigJQgTk9UIGEgZnVsbCByZWdpb24gcmVkcmF3XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmVkaXQpIHtcbiAgICAgIHRoaXMuYXBwbHlNYW5pcHVsYXRpb24oaXgsIGl5KTtcbiAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5kcmF3aW5nKSByZXR1cm47XG4gICAgaWYgKHRoaXMuZHJhZnRSZWN0KSB7XG4gICAgICB0aGlzLmRyYWZ0UmVjdC54MSA9IGl4O1xuICAgICAgdGhpcy5kcmFmdFJlY3QueTEgPSBpeTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICBjb25zdCBzdGVwID0gRlJFRUhBTkRfU1RFUF9QWCAqIHRoaXMud29ybGRQZXJDYW52YXNQaXhlbCgpO1xuICAgICAgY29uc3QgbGFzdCA9IHRoaXMuZHJhZnRQYXRoW3RoaXMuZHJhZnRQYXRoLmxlbmd0aCAtIDFdO1xuICAgICAgaWYgKE1hdGguYWJzKGl4IC0gbGFzdFswXSkgPj0gc3RlcCB8fCBNYXRoLmFicyhpeSAtIGxhc3RbMV0pID49IHN0ZXApIHtcbiAgICAgICAgdGhpcy5kcmFmdFBhdGgucHVzaChbaXgsIGl5XSk7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMucmVkcmF3KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJVcCA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tYXJxdWVlKSB7XG4gICAgICBjb25zdCBtID0gdGhpcy5tYXJxdWVlO1xuICAgICAgdGhpcy5tYXJxdWVlID0gbnVsbDtcbiAgICAgIHRoaXMuY2xlYXJNYXJxdWVlRWwoKTtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuc3ZnLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogYWxyZWFkeSByZWxlYXNlZCAqL1xuICAgICAgfVxuICAgICAgdGhpcy5maW5pc2hNYXJxdWVlKG0pOyAvLyBzZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyDihpIgb25lIHJlZHJhdyB2aWEgdGhlIHNlbGVjdGlvbiBzdWJzY3JpcHRpb25cbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuZWRpdCkge1xuICAgICAgdGhpcy5zdG9yZS5lbmRCYXRjaCgpO1xuICAgICAgdGhpcy5lZGl0ID0gbnVsbDtcbiAgICAgIHRyeSB7XG4gICAgICAgIHRoaXMuc3ZnLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICB9IGNhdGNoIHtcbiAgICAgICAgLyogYWxyZWFkeSByZWxlYXNlZCAqL1xuICAgICAgfVxuICAgICAgdGhpcy5yZWRyYXcoKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKCF0aGlzLmRyYXdpbmcpIHJldHVybjtcbiAgICB0aGlzLmRyYXdpbmcgPSBmYWxzZTtcbiAgICB0cnkge1xuICAgICAgdGhpcy5zdmcucmVsZWFzZVBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICB9IGNhdGNoIHtcbiAgICAgIC8qIGNhcHR1cmUgbWF5IGFscmVhZHkgYmUgcmVsZWFzZWQgKi9cbiAgICB9XG4gICAgaWYgKHRoaXMuZHJhZnRSZWN0KSB7XG4gICAgICBjb25zdCB7IHgwLCB5MCwgeDEsIHkxIH0gPSB0aGlzLmRyYWZ0UmVjdDtcbiAgICAgIGNvbnN0IHggPSBNYXRoLm1pbih4MCwgeDEpO1xuICAgICAgY29uc3QgeSA9IE1hdGgubWluKHkwLCB5MSk7XG4gICAgICBjb25zdCB3ID0gTWF0aC5hYnMoeDEgLSB4MCk7XG4gICAgICBjb25zdCBoID0gTWF0aC5hYnMoeTEgLSB5MCk7XG4gICAgICB0aGlzLmRyYWZ0UmVjdCA9IG51bGw7XG4gICAgICBjb25zdCBtaW4gPSBNSU5fUkVDVF9EUkFHX1BYICogdGhpcy53b3JsZFBlckNhbnZhc1BpeGVsKCk7XG4gICAgICBpZiAodyA+PSBtaW4gJiYgaCA+PSBtaW4pIHRoaXMuY29tbWl0UmVjdGFuZ2xlKHgsIHksIHcsIGgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kcmFmdFBhdGgpIHtcbiAgICAgIGNvbnN0IHB0cyA9IHRoaXMuZHJhZnRQYXRoO1xuICAgICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgICAgY29uc3QgY2xvc2VkID0gdGhpcy5tb2RlID09PSAnZHJhd2Nsb3NlZHBhdGgnO1xuICAgICAgaWYgKHB0cy5sZW5ndGggPj0gKGNsb3NlZCA/IDMgOiAyKSkgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgY2xvc2VkKTtcbiAgICB9XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKiogQ2xpY2stdG8tcGxhY2UgcG9seWdvbjogYWRkIGEgdmVydGV4LCBvciBjbG9zZSB3aGVuIGNsaWNraW5nIG5lYXIgdGhlIGZpcnN0IG9uZS4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVQb2x5Z29uQ2xpY2soaXg6IG51bWJlciwgaXk6IG51bWJlciwgY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IFtmeCwgZnldID0gdGhpcy50b0xvY2FsKHRoaXMuZHJhZnRQYXRoWzBdWzBdLCB0aGlzLmRyYWZ0UGF0aFswXVsxXSk7XG4gICAgY29uc3QgciA9IHRoaXMuc3ZnLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIGNvbnN0IG5lYXIgPVxuICAgICAgTWF0aC5oeXBvdChjbGllbnRYIC0gci5sZWZ0IC0gZngsIGNsaWVudFkgLSByLnRvcCAtIGZ5KSA8PSBDTE9TRV9TTkFQX1BYICYmXG4gICAgICB0aGlzLmRyYWZ0UGF0aC5sZW5ndGggPj0gMztcbiAgICBpZiAobmVhcikge1xuICAgICAgY29uc3QgcHRzID0gdGhpcy5kcmFmdFBhdGg7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgICB0aGlzLmNvbW1pdFBvbHlnb24ocHRzLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kcmFmdFBhdGgucHVzaChbaXgsIGl5XSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvbkRibENsaWNrID0gKGU6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tb2RlICE9PSAnZHJhd3BvbHlnb24nIHx8ICF0aGlzLmRyYWZ0UGF0aCkgcmV0dXJuO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBwdHMgPSB0aGlzLmRyYWZ0UGF0aDtcbiAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgaWYgKHB0cy5sZW5ndGggPj0gMykgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgdHJ1ZSk7XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKiogVGhlIGN1cnJlbnRseS1zZWxlY3RlZCByZWdpb24gKHNpbmdsZSBzZWxlY3Rpb24pLCBvciBudWxsLiAqL1xuICBwcml2YXRlIHNlbGVjdGVkUmVnaW9uKCk6IFJlZ2lvbiB8IG51bGwge1xuICAgIGNvbnN0IHJlZ2lvbnMgPSB0aGlzLnN0b3JlLmdldFJlZ2lvbnMoKTtcbiAgICBjb25zdCBpID0gdGhpcy5zZWxlY3RlZFswXTtcbiAgICByZXR1cm4gaSAhPSBudWxsICYmIGkgPj0gMCAmJiBpIDwgcmVnaW9ucy5sZW5ndGggPyByZWdpb25zW2ldIDogbnVsbDtcbiAgfVxuXG4gIC8qKiBTY3JlZW4gZGlzdGFuY2UgKHB4KSBiZXR3ZWVuIGEgY2xpZW50IHBvaW50IGFuZCBhbiBpbWFnZSBjb29yZC4gKi9cbiAgcHJpdmF0ZSBzY3JlZW5EaXN0KGNsaWVudFg6IG51bWJlciwgY2xpZW50WTogbnVtYmVyLCBpbWdYOiBudW1iZXIsIGltZ1k6IG51bWJlcik6IG51bWJlciB7XG4gICAgY29uc3QgW2x4LCBseV0gPSB0aGlzLnRvTG9jYWwoaW1nWCwgaW1nWSk7XG4gICAgY29uc3QgciA9IHRoaXMuc3ZnLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuICAgIHJldHVybiBNYXRoLmh5cG90KGNsaWVudFggLSByLmxlZnQgLSBseCwgY2xpZW50WSAtIHIudG9wIC0gbHkpO1xuICB9XG5cbiAgLyoqXG4gICAqIFN0YXJ0IGEgc2VsZWN0L21vdmUgaW50ZXJhY3Rpb246IGdyYWIgYSBoYW5kbGUgKHJlY3RhbmdsZSBjb3JuZXIpIG9yIHZlcnRleCBvZiB0aGUgYWxyZWFkeS1cbiAgICogc2VsZWN0ZWQgcmVnaW9uIGZpcnN0OyBvdGhlcndpc2Ugc2VsZWN0IHRoZSB0b3Btb3N0IHJlZ2lvbiB1bmRlciB0aGUgY3Vyc29yIGFuZCBkcmFnIGl0cyBib2R5LlxuICAgKi9cbiAgcHJpdmF0ZSBiZWdpbk1hbmlwdWxhdGlvbihpeDogbnVtYmVyLCBpeTogbnVtYmVyLCBlOiBQb2ludGVyRXZlbnQpOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkUmVnaW9uKCk7XG4gICAgaWYgKHNlbD8uYm91bmRzKSB7XG4gICAgICBjb25zdCBncmFiID0gdGhpcy5oaXRIYW5kbGUoc2VsLCBlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgICBpZiAoZ3JhYikge1xuICAgICAgICB0aGlzLnN0b3JlLmJlZ2luQmF0Y2goKTtcbiAgICAgICAgdGhpcy5lZGl0ID0geyAuLi5ncmFiLCBpZDogc2VsLmlkLCBsYXN0OiBbaXgsIGl5XSB9O1xuICAgICAgICB0aGlzLnN2Zy5zZXRQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gSGl0LXRlc3QgYm9kaWVzLCB0b3Btb3N0IGZpcnN0IChsYXN0IGRyYXduIHJlbmRlcnMgb24gdG9wKS5cbiAgICBjb25zdCByZWdpb25zID0gdGhpcy5zdG9yZS5nZXRSZWdpb25zKCk7XG4gICAgZm9yIChsZXQgaSA9IHJlZ2lvbnMubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICAgIGlmICh0aGlzLmhpdFRlc3QocmVnaW9uc1tpXSwgaXgsIGl5KSkge1xuICAgICAgICB0aGlzLnN0b3JlLnNlbGVjdFJlZ2lvbihyZWdpb25zW2ldKTtcbiAgICAgICAgdGhpcy5zdG9yZS5iZWdpbkJhdGNoKCk7XG4gICAgICAgIHRoaXMuZWRpdCA9IHsga2luZDogJ2JvZHknLCBpZDogcmVnaW9uc1tpXS5pZCwgbGFzdDogW2l4LCBpeV0gfTtcbiAgICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEVtcHR5IHNwYWNlOiBpbiBzZWxlY3QgbW9kZSBzdGFydCBhIHJ1YmJlci1iYW5kIG1hcnF1ZWUgKHNlbGVjdHMgdGhlIHJlZ2lvbnMgaXQgY292ZXJzIG9uXG4gICAgLy8gcmVsZWFzZSk7IGluIG1vdmUgbW9kZSBqdXN0IGNsZWFyIHRoZSBzZWxlY3Rpb24uXG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ3NlbGVjdCcpIHtcbiAgICAgIHRoaXMubWFycXVlZSA9IHsgeDA6IGl4LCB5MDogaXksIHgxOiBpeCwgeTE6IGl5IH07XG4gICAgICB0aGlzLnVwZGF0ZU1hcnF1ZWVFbCgpO1xuICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLnN0b3JlLnNldFNlbGVjdGVkU2hhcGVJbmRpY2VzKFtdKTtcbiAgICB9XG4gIH1cblxuICAvKiogQ3JlYXRlL3VwZGF0ZSB0aGUgbWFycXVlZSByZWN0IGVsZW1lbnQgZGlyZWN0bHkgKGF2b2lkcyBhIGZ1bGwgcmVnaW9uIHJlZHJhdyBwZXIgbW92ZSkuICovXG4gIHByaXZhdGUgdXBkYXRlTWFycXVlZUVsKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5tYXJxdWVlKSByZXR1cm47XG4gICAgaWYgKCF0aGlzLm1hcnF1ZWVFbCB8fCAhdGhpcy5tYXJxdWVlRWwucGFyZW50Tm9kZSkge1xuICAgICAgdGhpcy5tYXJxdWVlRWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAncmVjdCcpO1xuICAgICAgdGhpcy5tYXJxdWVlRWwuc2V0QXR0cmlidXRlKCdzdHJva2UnLCAnIzRkYTNmZicpO1xuICAgICAgdGhpcy5tYXJxdWVlRWwuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCAnMScpO1xuICAgICAgdGhpcy5tYXJxdWVlRWwuc2V0QXR0cmlidXRlKCdzdHJva2UtZGFzaGFycmF5JywgJzQgMycpO1xuICAgICAgdGhpcy5tYXJxdWVlRWwuc2V0QXR0cmlidXRlKCdmaWxsJywgJyM0ZGEzZmYnKTtcbiAgICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgJzAuMTInKTtcbiAgICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgndmVjdG9yLWVmZmVjdCcsICdub24tc2NhbGluZy1zdHJva2UnKTtcbiAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKHRoaXMubWFycXVlZUVsKTtcbiAgICB9XG4gICAgY29uc3QgeyB4MCwgeTAsIHgxLCB5MSB9ID0gdGhpcy5tYXJxdWVlO1xuICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKE1hdGgubWluKHgwLCB4MSksIE1hdGgubWluKHkwLCB5MSkpO1xuICAgIGNvbnN0IFtyeCwgcnldID0gdGhpcy50b0xvY2FsKE1hdGgubWF4KHgwLCB4MSksIE1hdGgubWF4KHkwLCB5MSkpO1xuICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgneCcsIGAke2x4fWApO1xuICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgneScsIGAke2x5fWApO1xuICAgIHRoaXMubWFycXVlZUVsLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBgJHtNYXRoLmFicyhyeCAtIGx4KX1gKTtcbiAgICB0aGlzLm1hcnF1ZWVFbC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGAke01hdGguYWJzKHJ5IC0gbHkpfWApO1xuICB9XG5cbiAgLyoqIFJlbW92ZSB0aGUgbWFycXVlZSBlbGVtZW50IGZyb20gdGhlIFNWRy4gKi9cbiAgcHJpdmF0ZSBjbGVhck1hcnF1ZWVFbCgpOiB2b2lkIHtcbiAgICBpZiAodGhpcy5tYXJxdWVlRWw/LnBhcmVudE5vZGUpIHRoaXMubWFycXVlZUVsLnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5tYXJxdWVlRWwpO1xuICAgIHRoaXMubWFycXVlZUVsID0gbnVsbDtcbiAgfVxuXG4gIC8qKiBUZXN0IHdoZXRoZXIgYSBjbGllbnQgcG9pbnQgZ3JhYnMgYSByZWN0YW5nbGUgY29ybmVyIG9yIGEgcG9seWdvbiB2ZXJ0ZXggb2YgYHJlZ2lvbmAuICovXG4gIHByaXZhdGUgaGl0SGFuZGxlKFxuICAgIHJlZ2lvbjogUmVnaW9uLFxuICAgIGNsaWVudFg6IG51bWJlcixcbiAgICBjbGllbnRZOiBudW1iZXIsXG4gICk6XG4gICAgfCB7IGtpbmQ6ICdjb3JuZXInOyBhbmNob3I6IFtudW1iZXIsIG51bWJlcl0gfVxuICAgIHwgeyBraW5kOiAndmVydGV4JzsgdmVydGV4SW5kZXg6IG51bWJlciB9XG4gICAgfCB7IGtpbmQ6ICdiZXppZXInOyB2ZXJ0ZXhJbmRleDogbnVtYmVyOyBzaWRlOiAnaW4nIHwgJ291dCcgfVxuICAgIHwgeyBraW5kOiAnaG9sZXZlcnRleCc7IGhvbGVJbmRleDogbnVtYmVyOyB2ZXJ0ZXhJbmRleDogbnVtYmVyIH1cbiAgICB8IHsga2luZDogJ2hvbGViZXppZXInOyBob2xlSW5kZXg6IG51bWJlcjsgdmVydGV4SW5kZXg6IG51bWJlcjsgc2lkZTogJ2luJyB8ICdvdXQnIH1cbiAgICB8IG51bGwge1xuICAgIGNvbnN0IGIgPSByZWdpb24uYm91bmRzO1xuICAgIGlmICghYikgcmV0dXJuIG51bGw7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgY29uc3QgciA9IGIgYXMgUmVjdGFuZ2xlO1xuICAgICAgY29uc3QgY29ybmVyczogQXJyYXk8W251bWJlciwgbnVtYmVyLCBbbnVtYmVyLCBudW1iZXJdXT4gPSBbXG4gICAgICAgIFtyLngsIHIueSwgW3IueCArIHIud2lkdGgsIHIueSArIHIuaGVpZ2h0XV0sXG4gICAgICAgIFtyLnggKyByLndpZHRoLCByLnksIFtyLngsIHIueSArIHIuaGVpZ2h0XV0sXG4gICAgICAgIFtyLngsIHIueSArIHIuaGVpZ2h0LCBbci54ICsgci53aWR0aCwgci55XV0sXG4gICAgICAgIFtyLnggKyByLndpZHRoLCByLnkgKyByLmhlaWdodCwgW3IueCwgci55XV0sXG4gICAgICBdO1xuICAgICAgZm9yIChjb25zdCBbY3gsIGN5LCBhbmNob3JdIG9mIGNvcm5lcnMpIHtcbiAgICAgICAgaWYgKHRoaXMuc2NyZWVuRGlzdChjbGllbnRYLCBjbGllbnRZLCBjeCwgY3kpIDw9IEhBTkRMRV9ISVRfUFgpIHJldHVybiB7IGtpbmQ6ICdjb3JuZXInLCBhbmNob3IgfTtcbiAgICAgIH1cbiAgICB9IGVsc2UgaWYgKCducG9pbnRzJyBpbiBiKSB7XG4gICAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgICAgLy8gQmV6aWVyIGNvbnRyb2wgcG9pbnRzIGZpcnN0ICh0aGV5IHNpdCBvZmYgdGhlIGFuY2hvcnMpLCBzbyB0aGV5J3JlIGdyYWJiYWJsZS5cbiAgICAgIGlmIChwLmJlemllciAmJiBwLmhhbmRsZXNJbj8ubGVuZ3RoID09PSBwLm5wb2ludHMgJiYgcC5oYW5kbGVzT3V0Py5sZW5ndGggPT09IHAubnBvaW50cykge1xuICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHAubnBvaW50czsgaSsrKSB7XG4gICAgICAgICAgY29uc3Qgb3V0ID0gcC5oYW5kbGVzT3V0W2ldO1xuICAgICAgICAgIGNvbnN0IGlubiA9IHAuaGFuZGxlc0luW2ldO1xuICAgICAgICAgIGlmICh0aGlzLnNjcmVlbkRpc3QoY2xpZW50WCwgY2xpZW50WSwgcC54cG9pbnRzW2ldICsgb3V0WzBdLCBwLnlwb2ludHNbaV0gKyBvdXRbMV0pIDw9IEhBTkRMRV9ISVRfUFgpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGtpbmQ6ICdiZXppZXInLCB2ZXJ0ZXhJbmRleDogaSwgc2lkZTogJ291dCcgfTtcbiAgICAgICAgICB9XG4gICAgICAgICAgaWYgKHRoaXMuc2NyZWVuRGlzdChjbGllbnRYLCBjbGllbnRZLCBwLnhwb2ludHNbaV0gKyBpbm5bMF0sIHAueXBvaW50c1tpXSArIGlublsxXSkgPD0gSEFORExFX0hJVF9QWCkge1xuICAgICAgICAgICAgcmV0dXJuIHsga2luZDogJ2JlemllcicsIHZlcnRleEluZGV4OiBpLCBzaWRlOiAnaW4nIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICBmb3IgKGxldCBpID0gMDsgaSA8IHAubnBvaW50czsgaSsrKSB7XG4gICAgICAgIGlmICh0aGlzLnNjcmVlbkRpc3QoY2xpZW50WCwgY2xpZW50WSwgcC54cG9pbnRzW2ldLCBwLnlwb2ludHNbaV0pIDw9IEhBTkRMRV9ISVRfUFgpIHtcbiAgICAgICAgICByZXR1cm4geyBraW5kOiAndmVydGV4JywgdmVydGV4SW5kZXg6IGkgfTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgLy8gSG9sZSAoZG9udXQpIHJpbmc6IGJlemllciBjb250cm9sIHBvaW50cyBmaXJzdCwgdGhlbiB0aGUgdmVydGljZXMuXG4gICAgICBjb25zdCBob2xlcyA9IHAuaG9sZXMgPz8gW107XG4gICAgICBjb25zdCBob2xlQmV6aWVyID0gISEocC5iZXppZXIgJiYgcC5ob2xlSGFuZGxlc0luICYmIHAuaG9sZUhhbmRsZXNPdXQpO1xuICAgICAgZm9yIChsZXQgaGkgPSAwOyBoaSA8IGhvbGVzLmxlbmd0aDsgaGkrKykge1xuICAgICAgICBjb25zdCByaW5nID0gaG9sZXNbaGldO1xuICAgICAgICBpZiAoaG9sZUJlemllciAmJiBwLmhvbGVIYW5kbGVzSW4hW2hpXSAmJiBwLmhvbGVIYW5kbGVzT3V0IVtoaV0pIHtcbiAgICAgICAgICBmb3IgKGxldCB2aSA9IDA7IHZpIDwgcmluZy5sZW5ndGg7IHZpKyspIHtcbiAgICAgICAgICAgIGNvbnN0IG91dCA9IHAuaG9sZUhhbmRsZXNPdXQhW2hpXVt2aV0gPz8gWzAsIDBdO1xuICAgICAgICAgICAgY29uc3QgaW5uID0gcC5ob2xlSGFuZGxlc0luIVtoaV1bdmldID8/IFswLCAwXTtcbiAgICAgICAgICAgIGlmICh0aGlzLnNjcmVlbkRpc3QoY2xpZW50WCwgY2xpZW50WSwgcmluZ1t2aV1bMF0gKyBvdXRbMF0sIHJpbmdbdmldWzFdICsgb3V0WzFdKSA8PSBIQU5ETEVfSElUX1BYKSB7XG4gICAgICAgICAgICAgIHJldHVybiB7IGtpbmQ6ICdob2xlYmV6aWVyJywgaG9sZUluZGV4OiBoaSwgdmVydGV4SW5kZXg6IHZpLCBzaWRlOiAnb3V0JyB9O1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgaWYgKHRoaXMuc2NyZWVuRGlzdChjbGllbnRYLCBjbGllbnRZLCByaW5nW3ZpXVswXSArIGlublswXSwgcmluZ1t2aV1bMV0gKyBpbm5bMV0pIDw9IEhBTkRMRV9ISVRfUFgpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHsga2luZDogJ2hvbGViZXppZXInLCBob2xlSW5kZXg6IGhpLCB2ZXJ0ZXhJbmRleDogdmksIHNpZGU6ICdpbicgfTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgICAgZm9yIChsZXQgdmkgPSAwOyB2aSA8IHJpbmcubGVuZ3RoOyB2aSsrKSB7XG4gICAgICAgICAgaWYgKHRoaXMuc2NyZWVuRGlzdChjbGllbnRYLCBjbGllbnRZLCByaW5nW3ZpXVswXSwgcmluZ1t2aV1bMV0pIDw9IEhBTkRMRV9ISVRfUFgpIHtcbiAgICAgICAgICAgIHJldHVybiB7IGtpbmQ6ICdob2xldmVydGV4JywgaG9sZUluZGV4OiBoaSwgdmVydGV4SW5kZXg6IHZpIH07XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgLyoqIEFwcGx5IHRoZSBsaXZlIGRyYWcgZm9yIHRoZSBhY3RpdmUgbWFuaXB1bGF0aW9uIChpbWFnZSBjb29yZHMgYGl4LGl5YCkuICovXG4gIHByaXZhdGUgYXBwbHlNYW5pcHVsYXRpb24oaXg6IG51bWJlciwgaXk6IG51bWJlcik6IHZvaWQge1xuICAgIGlmICghdGhpcy5lZGl0KSByZXR1cm47XG4gICAgaWYgKHRoaXMuZWRpdC5raW5kID09PSAnYm9keScpIHtcbiAgICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy5lZGl0Lmxhc3Q7XG4gICAgICB0aGlzLnN0b3JlLm1vdmVSZWdpb24odGhpcy5lZGl0LmlkLCBpeCAtIGx4LCBpeSAtIGx5KTtcbiAgICAgIHRoaXMuZWRpdC5sYXN0ID0gW2l4LCBpeV07XG4gICAgfSBlbHNlIGlmICh0aGlzLmVkaXQua2luZCA9PT0gJ3ZlcnRleCcgJiYgdGhpcy5lZGl0LnZlcnRleEluZGV4ICE9IG51bGwpIHtcbiAgICAgIHRoaXMuc3RvcmUubW92ZVZlcnRleCh0aGlzLmVkaXQuaWQsIHRoaXMuZWRpdC52ZXJ0ZXhJbmRleCwgaXgsIGl5KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZWRpdC5raW5kID09PSAnY29ybmVyJyAmJiB0aGlzLmVkaXQuYW5jaG9yKSB7XG4gICAgICBjb25zdCBbYXgsIGF5XSA9IHRoaXMuZWRpdC5hbmNob3I7XG4gICAgICBjb25zdCByZWN0ID0gbmV3IFJlY3RhbmdsZSgpO1xuICAgICAgcmVjdC54ID0gTWF0aC5taW4oYXgsIGl4KTtcbiAgICAgIHJlY3QueSA9IE1hdGgubWluKGF5LCBpeSk7XG4gICAgICByZWN0LndpZHRoID0gTWF0aC5hYnMoaXggLSBheCk7XG4gICAgICByZWN0LmhlaWdodCA9IE1hdGguYWJzKGl5IC0gYXkpO1xuICAgICAgdGhpcy5zdG9yZS51cGRhdGVCb3VuZHModGhpcy5lZGl0LmlkLCByZWN0KTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZWRpdC5raW5kID09PSAnYmV6aWVyJyAmJiB0aGlzLmVkaXQudmVydGV4SW5kZXggIT0gbnVsbCAmJiB0aGlzLmVkaXQuc2lkZSkge1xuICAgICAgdGhpcy5zdG9yZS5tb3ZlQmV6aWVySGFuZGxlKHRoaXMuZWRpdC5pZCwgdGhpcy5lZGl0LnZlcnRleEluZGV4LCB0aGlzLmVkaXQuc2lkZSwgaXgsIGl5KTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5lZGl0LmtpbmQgPT09ICdob2xldmVydGV4JyAmJlxuICAgICAgdGhpcy5lZGl0LmhvbGVJbmRleCAhPSBudWxsICYmXG4gICAgICB0aGlzLmVkaXQudmVydGV4SW5kZXggIT0gbnVsbFxuICAgICkge1xuICAgICAgdGhpcy5zdG9yZS5tb3ZlSG9sZVZlcnRleCh0aGlzLmVkaXQuaWQsIHRoaXMuZWRpdC5ob2xlSW5kZXgsIHRoaXMuZWRpdC52ZXJ0ZXhJbmRleCwgaXgsIGl5KTtcbiAgICB9IGVsc2UgaWYgKFxuICAgICAgdGhpcy5lZGl0LmtpbmQgPT09ICdob2xlYmV6aWVyJyAmJlxuICAgICAgdGhpcy5lZGl0LmhvbGVJbmRleCAhPSBudWxsICYmXG4gICAgICB0aGlzLmVkaXQudmVydGV4SW5kZXggIT0gbnVsbCAmJlxuICAgICAgdGhpcy5lZGl0LnNpZGVcbiAgICApIHtcbiAgICAgIHRoaXMuc3RvcmUubW92ZUhvbGVCZXppZXJIYW5kbGUoXG4gICAgICAgIHRoaXMuZWRpdC5pZCxcbiAgICAgICAgdGhpcy5lZGl0LmhvbGVJbmRleCxcbiAgICAgICAgdGhpcy5lZGl0LnZlcnRleEluZGV4LFxuICAgICAgICB0aGlzLmVkaXQuc2lkZSxcbiAgICAgICAgaXgsXG4gICAgICAgIGl5LFxuICAgICAgKTtcbiAgICB9XG4gIH1cblxuICAvKiogYWRkcG9pbnQgbW9kZTogaW5zZXJ0IGEgdmVydGV4IG9uIHRoZSBzZWxlY3RlZCBwb2x5Z29uJ3MgbmVhcmVzdCBlZGdlIGF0IHRoZSBjbGljay4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVBZGRQb2ludChpeDogbnVtYmVyLCBpeTogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFJlZ2lvbigpO1xuICAgIGNvbnN0IGIgPSBzZWw/LmJvdW5kcztcbiAgICBpZiAoIXNlbCB8fCAhYiB8fCAhKCducG9pbnRzJyBpbiBiKSkgcmV0dXJuO1xuICAgIGNvbnN0IHAgPSBiIGFzIFBvbHlnb247XG4gICAgbGV0IGJlc3RTZWcgPSAwO1xuICAgIGxldCBiZXN0RCA9IEluZmluaXR5O1xuICAgIGNvbnN0IHNlZ3MgPSBwLmNsb3NlZCA9PT0gZmFsc2UgPyBwLm5wb2ludHMgLSAxIDogcC5ucG9pbnRzO1xuICAgIGZvciAobGV0IHMgPSAwOyBzIDwgc2VnczsgcysrKSB7XG4gICAgICBjb25zdCBqID0gKHMgKyAxKSAlIHAubnBvaW50cztcbiAgICAgIGNvbnN0IGQgPSB0aGlzLnBvaW50U2VnRGlzdChpeCwgaXksIHAueHBvaW50c1tzXSwgcC55cG9pbnRzW3NdLCBwLnhwb2ludHNbal0sIHAueXBvaW50c1tqXSk7XG4gICAgICBpZiAoZCA8IGJlc3REKSB7XG4gICAgICAgIGJlc3REID0gZDtcbiAgICAgICAgYmVzdFNlZyA9IHM7XG4gICAgICB9XG4gICAgfVxuICAgIHRoaXMuc3RvcmUuYWRkVmVydGV4KHNlbC5pZCwgYmVzdFNlZywgaXgsIGl5KTtcbiAgfVxuXG4gIC8qKiBkZWxldGVwb2ludCBtb2RlOiByZW1vdmUgdGhlIHNlbGVjdGVkIHBvbHlnb24ncyB2ZXJ0ZXggbmVhcmVzdCB0aGUgY2xpY2suICovXG4gIHByaXZhdGUgaGFuZGxlRGVsZXRlUG9pbnQoaXg6IG51bWJlciwgaXk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb24oKTtcbiAgICBjb25zdCBiID0gc2VsPy5ib3VuZHM7XG4gICAgaWYgKCFzZWwgfHwgIWIgfHwgISgnbnBvaW50cycgaW4gYikpIHJldHVybjtcbiAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgIGxldCBiZXN0ID0gLTE7XG4gICAgbGV0IGJlc3REID0gSW5maW5pdHk7XG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwLm5wb2ludHM7IGkrKykge1xuICAgICAgY29uc3QgZCA9IE1hdGguaHlwb3QocC54cG9pbnRzW2ldIC0gaXgsIHAueXBvaW50c1tpXSAtIGl5KTtcbiAgICAgIGlmIChkIDwgYmVzdEQpIHtcbiAgICAgICAgYmVzdEQgPSBkO1xuICAgICAgICBiZXN0ID0gaTtcbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGJlc3QgPj0gMCkgdGhpcy5zdG9yZS5kZWxldGVWZXJ0ZXgoc2VsLmlkLCBiZXN0KTtcbiAgfVxuXG4gIC8qKiBEaXN0YW5jZSBmcm9tIHBvaW50IChweCxweSkgdG8gc2VnbWVudCAoYXgsYXkpLShieCxieSksIGluIGltYWdlIHVuaXRzLiAqL1xuICBwcml2YXRlIHBvaW50U2VnRGlzdChcbiAgICBweDogbnVtYmVyLFxuICAgIHB5OiBudW1iZXIsXG4gICAgYXg6IG51bWJlcixcbiAgICBheTogbnVtYmVyLFxuICAgIGJ4OiBudW1iZXIsXG4gICAgYnk6IG51bWJlcixcbiAgKTogbnVtYmVyIHtcbiAgICBjb25zdCBkeCA9IGJ4IC0gYXg7XG4gICAgY29uc3QgZHkgPSBieSAtIGF5O1xuICAgIGNvbnN0IGxlbjIgPSBkeCAqIGR4ICsgZHkgKiBkeSB8fCAxO1xuICAgIGxldCB0ID0gKChweCAtIGF4KSAqIGR4ICsgKHB5IC0gYXkpICogZHkpIC8gbGVuMjtcbiAgICB0ID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgdCkpO1xuICAgIHJldHVybiBNYXRoLmh5cG90KHB4IC0gKGF4ICsgdCAqIGR4KSwgcHkgLSAoYXkgKyB0ICogZHkpKTtcbiAgfVxuXG4gIC8qKiBGaW5hbGl6ZSBhIHJ1YmJlci1iYW5kIG1hcnF1ZWU6IHNlbGVjdCBldmVyeSByZWdpb24gd2hvc2UgYm91bmRpbmcgYm94IGl0IG92ZXJsYXBzIChhIHRpbnlcbiAgICogIG1hcnF1ZWUgaXMgdHJlYXRlZCBhcyBhIGNsaWNrIG9uIGVtcHR5IHNwYWNlIOKGkiBjbGVhciB0aGUgc2VsZWN0aW9uKS4gKi9cbiAgcHJpdmF0ZSBmaW5pc2hNYXJxdWVlKG06IHsgeDA6IG51bWJlcjsgeTA6IG51bWJlcjsgeDE6IG51bWJlcjsgeTE6IG51bWJlciB9KTogdm9pZCB7XG4gICAgY29uc3QgeDAgPSBNYXRoLm1pbihtLngwLCBtLngxKTtcbiAgICBjb25zdCB4MSA9IE1hdGgubWF4KG0ueDAsIG0ueDEpO1xuICAgIGNvbnN0IHkwID0gTWF0aC5taW4obS55MCwgbS55MSk7XG4gICAgY29uc3QgeTEgPSBNYXRoLm1heChtLnkwLCBtLnkxKTtcbiAgICBpZiAoeDEgLSB4MCA8IDMgJiYgeTEgLSB5MCA8IDMpIHtcbiAgICAgIHRoaXMuc3RvcmUuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoW10pO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBpbmRpY2VzOiBudW1iZXJbXSA9IFtdO1xuICAgIHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpLmZvckVhY2goKHIsIGkpID0+IHtcbiAgICAgIGlmIChyLmlzUHJvZmlsZT8uKCkpIHJldHVybjtcbiAgICAgIGNvbnN0IGJiID0gdGhpcy5yZWdpb25CQm94KHIpO1xuICAgICAgaWYgKGJiICYmIGJiLngwIDw9IHgxICYmIGJiLngxID49IHgwICYmIGJiLnkwIDw9IHkxICYmIGJiLnkxID49IHkwKSBpbmRpY2VzLnB1c2goaSk7XG4gICAgfSk7XG4gICAgdGhpcy5zdG9yZS5zZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyhpbmRpY2VzKTtcbiAgfVxuXG4gIC8qKiBBIHJlZ2lvbidzIGJvdW5kaW5nIGJveCBpbiBpbWFnZSBjb29yZHMgKHJlY3RhbmdsZSwgcG9seWdvbiwgb3IgbXVsdGlwb2x5Z29uKSwgb3IgbnVsbC4gKi9cbiAgcHJpdmF0ZSByZWdpb25CQm94KFxuICAgIHJlZ2lvbjogUmVnaW9uLFxuICApOiB7IHgwOiBudW1iZXI7IHkwOiBudW1iZXI7IHgxOiBudW1iZXI7IHkxOiBudW1iZXIgfSB8IG51bGwge1xuICAgIGNvbnN0IGIgPSByZWdpb24uYm91bmRzO1xuICAgIGlmICghYikgcmV0dXJuIG51bGw7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgY29uc3QgciA9IGIgYXMgUmVjdGFuZ2xlO1xuICAgICAgcmV0dXJuIHsgeDA6IHIueCwgeTA6IHIueSwgeDE6IHIueCArIHIud2lkdGgsIHkxOiByLnkgKyByLmhlaWdodCB9O1xuICAgIH1cbiAgICBjb25zdCBhY2MgPSB7IHgwOiBJbmZpbml0eSwgeTA6IEluZmluaXR5LCB4MTogLUluZmluaXR5LCB5MTogLUluZmluaXR5IH07XG4gICAgY29uc3QgYWRkUmluZyA9ICh4czogbnVtYmVyW10sIHlzOiBudW1iZXJbXSk6IHZvaWQgPT4ge1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCB4cy5sZW5ndGg7IGkrKykge1xuICAgICAgICBpZiAoeHNbaV0gPCBhY2MueDApIGFjYy54MCA9IHhzW2ldO1xuICAgICAgICBpZiAoeHNbaV0gPiBhY2MueDEpIGFjYy54MSA9IHhzW2ldO1xuICAgICAgICBpZiAoeXNbaV0gPCBhY2MueTApIGFjYy55MCA9IHlzW2ldO1xuICAgICAgICBpZiAoeXNbaV0gPiBhY2MueTEpIGFjYy55MSA9IHlzW2ldO1xuICAgICAgfVxuICAgIH07XG4gICAgaWYgKCducG9pbnRzJyBpbiBiKSB7XG4gICAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgICAgYWRkUmluZyhwLnhwb2ludHMsIHAueXBvaW50cyk7XG4gICAgfSBlbHNlIGlmICgncG9seWdvbnMnIGluIGIpIHtcbiAgICAgIGZvciAoY29uc3QgcCBvZiAoYiBhcyB7IHBvbHlnb25zOiBQb2x5Z29uW10gfSkucG9seWdvbnMpIGFkZFJpbmcocC54cG9pbnRzLCBwLnlwb2ludHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIGlzRmluaXRlKGFjYy54MCkgPyBhY2MgOiBudWxsO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNoYXBlIGNvbW1pdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSBjb21taXRSZWN0YW5nbGUoeDogbnVtYmVyLCB5OiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcmVjdCA9IG5ldyBSZWN0YW5nbGUoKTtcbiAgICByZWN0LnggPSB4O1xuICAgIHJlY3QueSA9IHk7XG4gICAgcmVjdC53aWR0aCA9IHdpZHRoO1xuICAgIHJlY3QuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIGNvbnN0IHJlZ2lvbiA9IG5ldyBSZWdpb24oKTtcbiAgICByZWdpb24uYm91bmRzID0gcmVjdDtcbiAgICByZWdpb24uY29sb3IgPSB0aGlzLnN0b3JlLmdldFNoYXBlQ29sb3IoKTtcbiAgICB0aGlzLnN0b3JlLmFkZFJlZ2lvbihyZWdpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21taXRQb2x5Z29uKHBvaW50czogQXJyYXk8W251bWJlciwgbnVtYmVyXT4sIGNsb3NlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHBvbHkgPSBuZXcgUG9seWdvbigpO1xuICAgIHBvbHkubnBvaW50cyA9IHBvaW50cy5sZW5ndGg7XG4gICAgcG9seS54cG9pbnRzID0gcG9pbnRzLm1hcCgocCkgPT4gcFswXSk7XG4gICAgcG9seS55cG9pbnRzID0gcG9pbnRzLm1hcCgocCkgPT4gcFsxXSk7XG4gICAgcG9seS5jb29yZGluYXRlcyA9IHBvaW50cy5tYXAoKHApID0+IFtwWzBdLCBwWzFdXSk7XG4gICAgcG9seS5jbG9zZWQgPSBjbG9zZWQ7XG4gICAgY29uc3QgcmVnaW9uID0gbmV3IFJlZ2lvbigpO1xuICAgIHJlZ2lvbi5ib3VuZHMgPSBwb2x5O1xuICAgIHJlZ2lvbi5jb2xvciA9IHRoaXMuc3RvcmUuZ2V0U2hhcGVDb2xvcigpO1xuICAgIHJlZ2lvbi5sYWJlbCA9ICdSZWdpb24nO1xuICAgIHRoaXMuc3RvcmUuYWRkUmVnaW9uKHJlZ2lvbik7XG4gIH1cblxuICAvLyDilIDilIAgcmVuZGVyaW5nIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBwcml2YXRlIGhpdFRlc3QocmVnaW9uOiBSZWdpb24sIHg6IG51bWJlciwgeTogbnVtYmVyKTogYm9vbGVhbiB7XG4gICAgY29uc3QgYiA9IHJlZ2lvbi5ib3VuZHM7XG4gICAgaWYgKCFiKSByZXR1cm4gZmFsc2U7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgY29uc3QgciA9IGIgYXMgUmVjdGFuZ2xlO1xuICAgICAgcmV0dXJuIHggPj0gci54ICYmIHggPD0gci54ICsgci53aWR0aCAmJiB5ID49IHIueSAmJiB5IDw9IHIueSArIHIuaGVpZ2h0O1xuICAgIH1cbiAgICBpZiAoJ25wb2ludHMnIGluIGIpIHtcbiAgICAgIGNvbnN0IHAgPSBiIGFzIFBvbHlnb247XG4gICAgICBsZXQgaW5zaWRlID0gZmFsc2U7XG4gICAgICBmb3IgKGxldCBpID0gMCwgaiA9IHAubnBvaW50cyAtIDE7IGkgPCBwLm5wb2ludHM7IGogPSBpKyspIHtcbiAgICAgICAgY29uc3QgeGkgPSBwLnhwb2ludHNbaV07XG4gICAgICAgIGNvbnN0IHlpID0gcC55cG9pbnRzW2ldO1xuICAgICAgICBjb25zdCB4aiA9IHAueHBvaW50c1tqXTtcbiAgICAgICAgY29uc3QgeWogPSBwLnlwb2ludHNbal07XG4gICAgICAgIGlmICh5aSA+IHkgIT09IHlqID4geSAmJiB4IDwgKCh4aiAtIHhpKSAqICh5IC0geWkpKSAvICh5aiAtIHlpKSArIHhpKSBpbnNpZGUgPSAhaW5zaWRlO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGluc2lkZTtcbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgLyoqIFNob3cgb3IgaGlkZSB0aGUgZHJhd24gcmVnaW9ucy4gQSByZWdpb24gYmVpbmcgZHJhd24gc3RheXMgdmlzaWJsZSBlaXRoZXIgd2F5LiAqL1xuICBzZXRSZWdpb25zVmlzaWJsZSh2aXNpYmxlOiBib29sZWFuKTogdm9pZCB7XG4gICAgaWYgKHZpc2libGUgPT09IHRoaXMucmVnaW9uc1Zpc2libGUpIHJldHVybjtcbiAgICB0aGlzLnJlZ2lvbnNWaXNpYmxlID0gdmlzaWJsZTtcbiAgICB0aGlzLnJlZHJhdygpO1xuICB9XG5cbiAgcmVkcmF3KCk6IHZvaWQge1xuICAgIHdoaWxlICh0aGlzLnN2Zy5maXJzdENoaWxkKSB0aGlzLnN2Zy5yZW1vdmVDaGlsZCh0aGlzLnN2Zy5maXJzdENoaWxkKTtcbiAgICBjb25zdCByZWdpb25zID0gdGhpcy5yZWdpb25zVmlzaWJsZSA/IHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpIDogW107XG4gICAgcmVnaW9ucy5mb3JFYWNoKChyZWdpb24sIGkpID0+IHtcbiAgICAgIGlmIChyZWdpb24uaXNQcm9maWxlPy4oKSkgcmV0dXJuO1xuICAgICAgY29uc3QgaXNTZWwgPSB0aGlzLnNlbGVjdGVkLmluY2x1ZGVzKGkpO1xuICAgICAgY29uc3QgZWwgPSB0aGlzLmJ1aWxkUmVnaW9uRWwocmVnaW9uLCBpc1NlbCk7XG4gICAgICBpZiAoZWwpIHRoaXMuc3ZnLmFwcGVuZENoaWxkKGVsKTtcbiAgICAgIHRoaXMuZHJhd0xhYmVsKHJlZ2lvbik7XG4gICAgICBpZiAoaXNTZWwpIHRoaXMuZHJhd0hhbmRsZXMocmVnaW9uKTtcbiAgICB9KTtcbiAgICB0aGlzLmRyYXdEcmFmdCgpO1xuICB9XG5cbiAgLyoqIERyYXcgYSByZWdpb24ncyBjbGFzc2lmaWNhdGlvbiBsYWJlbCBhdCBpdHMgdG9wLWxlZnQsIHdoZW4gbGFiZWxzIGFyZSBlbmFibGVkIChtYXRjaGVzIE9TRCkuICovXG4gIHByaXZhdGUgZHJhd0xhYmVsKHJlZ2lvbjogUmVnaW9uKTogdm9pZCB7XG4gICAgaWYgKCF0aGlzLnN0b3JlLmdldFNob3dTaGFwZUxhYmVsKCkgfHwgcmVnaW9uLmlzUHJvZmlsZT8uKCkpIHJldHVybjtcbiAgICBjb25zdCBsYWJlbCA9IHJlZ2lvbi5sYWJlbDtcbiAgICBjb25zdCBiID0gcmVnaW9uLmJvdW5kcztcbiAgICBpZiAoIWxhYmVsIHx8ICFiKSByZXR1cm47XG4gICAgbGV0IGl4OiBudW1iZXI7XG4gICAgbGV0IGl5OiBudW1iZXI7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgaXggPSAoYiBhcyBSZWN0YW5nbGUpLng7XG4gICAgICBpeSA9IChiIGFzIFJlY3RhbmdsZSkueTtcbiAgICB9IGVsc2UgaWYgKCducG9pbnRzJyBpbiBiKSB7XG4gICAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgICAgaXggPSBwLnhwb2ludHMucmVkdWNlKChtLCB4KSA9PiBNYXRoLm1pbihtLCB4KSwgSW5maW5pdHkpO1xuICAgICAgaXkgPSBwLnlwb2ludHMucmVkdWNlKChtLCB5KSA9PiBNYXRoLm1pbihtLCB5KSwgSW5maW5pdHkpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKGl4LCBpeSk7XG4gICAgY29uc3QgdGV4dCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICd0ZXh0Jyk7XG4gICAgdGV4dC5zZXRBdHRyaWJ1dGUoJ3gnLCBgJHtseH1gKTtcbiAgICB0ZXh0LnNldEF0dHJpYnV0ZSgneScsIGAke2x5IC0gNH1gKTtcbiAgICB0ZXh0LnNldEF0dHJpYnV0ZSgnZmlsbCcsICcjZmZmJyk7XG4gICAgdGV4dC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsICcjMDAwJyk7XG4gICAgdGV4dC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsICczJyk7XG4gICAgdGV4dC5zZXRBdHRyaWJ1dGUoJ3BhaW50LW9yZGVyJywgJ3N0cm9rZScpO1xuICAgIHRleHQuc2V0QXR0cmlidXRlKCdmb250JywgJzEycHggc2Fucy1zZXJpZicpO1xuICAgIHRleHQuc2V0QXR0cmlidXRlKCdwb2ludGVyLWV2ZW50cycsICdub25lJyk7XG4gICAgdGV4dC50ZXh0Q29udGVudCA9IGxhYmVsO1xuICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKHRleHQpO1xuICB9XG5cbiAgLyoqIERyYXcgZ3JhYiBoYW5kbGVzIGZvciB0aGUgc2VsZWN0ZWQgcmVnaW9uOiByZWN0YW5nbGUgY29ybmVycyBvciBwb2x5Z29uIHZlcnRpY2VzLiAqL1xuICBwcml2YXRlIGRyYXdIYW5kbGVzKHJlZ2lvbjogUmVnaW9uKTogdm9pZCB7XG4gICAgY29uc3QgYiA9IHJlZ2lvbi5ib3VuZHM7XG4gICAgaWYgKCFiKSByZXR1cm47XG4gICAgY29uc3Qgc3Ryb2tlID0gcmVnaW9uLmNvbG9yIHx8IHRoaXMuc3RvcmUuZ2V0U2hhcGVDb2xvcigpIHx8ICcjMDBmZmZmJztcbiAgICBjb25zdCBoYW5kbGUgPSAoaW1nWDogbnVtYmVyLCBpbWdZOiBudW1iZXIpOiB2b2lkID0+IHtcbiAgICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKGltZ1gsIGltZ1kpO1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAncmVjdCcpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCd4JywgYCR7bHggLSBIQU5ETEVfU0laRSAvIDJ9YCk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3knLCBgJHtseSAtIEhBTkRMRV9TSVpFIC8gMn1gKTtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBgJHtIQU5ETEVfU0laRX1gKTtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgYCR7SEFORExFX1NJWkV9YCk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnI2ZmZicpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdzdHJva2UnLCBzdHJva2UpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCAnMS41Jyk7XG4gICAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChlbCk7XG4gICAgfTtcbiAgICBpZiAoJ3dpZHRoJyBpbiBiICYmICd4JyBpbiBiKSB7XG4gICAgICBjb25zdCByID0gYiBhcyBSZWN0YW5nbGU7XG4gICAgICBoYW5kbGUoci54LCByLnkpO1xuICAgICAgaGFuZGxlKHIueCArIHIud2lkdGgsIHIueSk7XG4gICAgICBoYW5kbGUoci54LCByLnkgKyByLmhlaWdodCk7XG4gICAgICBoYW5kbGUoci54ICsgci53aWR0aCwgci55ICsgci5oZWlnaHQpO1xuICAgIH0gZWxzZSBpZiAoJ25wb2ludHMnIGluIGIpIHtcbiAgICAgIGNvbnN0IHAgPSBiIGFzIFBvbHlnb247XG4gICAgICBjb25zdCBpc0JlemllciA9IHAuYmV6aWVyICYmIHAuaGFuZGxlc0luPy5sZW5ndGggPT09IHAubnBvaW50cyAmJiBwLmhhbmRsZXNPdXQ/Lmxlbmd0aCA9PT0gcC5ucG9pbnRzO1xuICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBwLm5wb2ludHM7IGkrKykgaGFuZGxlKHAueHBvaW50c1tpXSwgcC55cG9pbnRzW2ldKTtcbiAgICAgIGZvciAoY29uc3QgcmluZyBvZiBwLmhvbGVzID8/IFtdKSBmb3IgKGNvbnN0IFtoeCwgaHldIG9mIHJpbmcpIGhhbmRsZShoeCwgaHkpO1xuICAgICAgLy8gQmV6aWVyIHJlZ2lvbnMgYWxzbyBleHBvc2UgdGhlaXIgdGFuZ2VudCBjb250cm9sIHBvaW50cyAoY2lyY2xlcykgam9pbmVkIHRvIHRoZSBhbmNob3JcbiAgICAgIC8vIGJ5IGEgdGhpbiBsaW5lLCBtYXRjaGluZyB0aGUgT1NEIG92ZXJsYXkncyBlZGl0YWJsZSBiZXppZXIgaGFuZGxlcy5cbiAgICAgIGlmIChpc0Jlemllcikge1xuICAgICAgICBjb25zdCBoSW4gPSBwLmhhbmRsZXNJbiBhcyBudW1iZXJbXVtdO1xuICAgICAgICBjb25zdCBoT3V0ID0gcC5oYW5kbGVzT3V0IGFzIG51bWJlcltdW107XG4gICAgICAgIGZvciAobGV0IGkgPSAwOyBpIDwgcC5ucG9pbnRzOyBpKyspIHtcbiAgICAgICAgICB0aGlzLmRyYXdCZXppZXJIYW5kbGUocC54cG9pbnRzW2ldLCBwLnlwb2ludHNbaV0sIGhPdXRbaV0sIHN0cm9rZSk7XG4gICAgICAgICAgdGhpcy5kcmF3QmV6aWVySGFuZGxlKHAueHBvaW50c1tpXSwgcC55cG9pbnRzW2ldLCBoSW5baV0sIHN0cm9rZSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIC8vIERvbnV0IGhvbGUgYmV6aWVyIGNvbnRyb2wgaGFuZGxlcy5cbiAgICAgIGlmIChwLmJlemllciAmJiBwLmhvbGVIYW5kbGVzSW4gJiYgcC5ob2xlSGFuZGxlc091dCkge1xuICAgICAgICAocC5ob2xlcyA/PyBbXSkuZm9yRWFjaCgocmluZywgaGkpID0+IHtcbiAgICAgICAgICBjb25zdCBoSW4gPSBwLmhvbGVIYW5kbGVzSW4hW2hpXTtcbiAgICAgICAgICBjb25zdCBoT3V0ID0gcC5ob2xlSGFuZGxlc091dCFbaGldO1xuICAgICAgICAgIGlmICghaEluIHx8ICFoT3V0KSByZXR1cm47XG4gICAgICAgICAgcmluZy5mb3JFYWNoKChbaHgsIGh5XSwgdmkpID0+IHtcbiAgICAgICAgICAgIHRoaXMuZHJhd0JlemllckhhbmRsZShoeCwgaHksIGhPdXRbdmldLCBzdHJva2UpO1xuICAgICAgICAgICAgdGhpcy5kcmF3QmV6aWVySGFuZGxlKGh4LCBoeSwgaEluW3ZpXSwgc3Ryb2tlKTtcbiAgICAgICAgICB9KTtcbiAgICAgICAgfSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIERyYXcgb25lIGJlemllciBjb250cm9sIHBvaW50IChhbmNob3IgKyBoYW5kbGUgb2Zmc2V0KSBhcyBhIHNtYWxsIGNpcmNsZSBjb25uZWN0ZWQgdG8gaXRzXG4gICAqICBhbmNob3IgYnkgYSB0YW5nZW50IGxpbmUuIGBoYW5kbGVgIGlzIHRoZSBbZHgsZHldIG9mZnNldCBmcm9tIHRoZSBhbmNob3IgaW4gaW1hZ2Ugc3BhY2UuICovXG4gIHByaXZhdGUgZHJhd0JlemllckhhbmRsZShheDogbnVtYmVyLCBheTogbnVtYmVyLCBoYW5kbGU6IG51bWJlcltdLCBzdHJva2U6IHN0cmluZyk6IHZvaWQge1xuICAgIGlmICghaGFuZGxlIHx8IChoYW5kbGVbMF0gPT09IDAgJiYgaGFuZGxlWzFdID09PSAwKSkgcmV0dXJuO1xuICAgIGNvbnN0IFthbHgsIGFseV0gPSB0aGlzLnRvTG9jYWwoYXgsIGF5KTtcbiAgICBjb25zdCBbaGx4LCBobHldID0gdGhpcy50b0xvY2FsKGF4ICsgaGFuZGxlWzBdLCBheSArIGhhbmRsZVsxXSk7XG4gICAgY29uc3QgbGluZSA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICdsaW5lJyk7XG4gICAgbGluZS5zZXRBdHRyaWJ1dGUoJ3gxJywgYCR7YWx4fWApO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKCd5MScsIGAke2FseX1gKTtcbiAgICBsaW5lLnNldEF0dHJpYnV0ZSgneDInLCBgJHtobHh9YCk7XG4gICAgbGluZS5zZXRBdHRyaWJ1dGUoJ3kyJywgYCR7aGx5fWApO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2UnLCBzdHJva2UpO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCAnMScpO1xuICAgIGxpbmUuc2V0QXR0cmlidXRlKCdzdHJva2Utb3BhY2l0eScsICcwLjcnKTtcbiAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChsaW5lKTtcbiAgICBjb25zdCBkb3QgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAnY2lyY2xlJyk7XG4gICAgZG90LnNldEF0dHJpYnV0ZSgnY3gnLCBgJHtobHh9YCk7XG4gICAgZG90LnNldEF0dHJpYnV0ZSgnY3knLCBgJHtobHl9YCk7XG4gICAgZG90LnNldEF0dHJpYnV0ZSgncicsIGAke0hBTkRMRV9TSVpFIC8gMn1gKTtcbiAgICBkb3Quc2V0QXR0cmlidXRlKCdmaWxsJywgc3Ryb2tlKTtcbiAgICBkb3Quc2V0QXR0cmlidXRlKCdzdHJva2UnLCAnI2ZmZicpO1xuICAgIGRvdC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsICcxJyk7XG4gICAgdGhpcy5zdmcuYXBwZW5kQ2hpbGQoZG90KTtcbiAgfVxuXG4gIHByaXZhdGUgYnVpbGRSZWdpb25FbChyZWdpb246IFJlZ2lvbiwgaXNTZWxlY3RlZDogYm9vbGVhbik6IFNWR0VsZW1lbnQgfCBudWxsIHtcbiAgICBjb25zdCBiID0gcmVnaW9uLmJvdW5kcztcbiAgICBpZiAoIWIpIHJldHVybiBudWxsO1xuICAgIGNvbnN0IHN0cm9rZSA9IHJlZ2lvbi5jb2xvciB8fCB0aGlzLnN0b3JlLmdldFNoYXBlQ29sb3IoKSB8fCAnIzAwZmZmZic7XG4gICAgaWYgKCd3aWR0aCcgaW4gYiAmJiAneCcgaW4gYikge1xuICAgICAgY29uc3QgciA9IGIgYXMgUmVjdGFuZ2xlO1xuICAgICAgY29uc3QgW2x4LCBseV0gPSB0aGlzLnRvTG9jYWwoci54LCByLnkpO1xuICAgICAgY29uc3QgW3J4LCByeV0gPSB0aGlzLnRvTG9jYWwoci54ICsgci53aWR0aCwgci55ICsgci5oZWlnaHQpO1xuICAgICAgY29uc3QgZWwgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAncmVjdCcpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCd4JywgYCR7TWF0aC5taW4obHgsIHJ4KX1gKTtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgneScsIGAke01hdGgubWluKGx5LCByeSl9YCk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgYCR7TWF0aC5hYnMocnggLSBseCl9YCk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ2hlaWdodCcsIGAke01hdGguYWJzKHJ5IC0gbHkpfWApO1xuICAgICAgdGhpcy5zdHlsZShlbCwgc3Ryb2tlLCBpc1NlbGVjdGVkKTtcbiAgICAgIHJldHVybiBlbDtcbiAgICB9XG4gICAgaWYgKCducG9pbnRzJyBpbiBiKSB7XG4gICAgICBjb25zdCBwID0gYiBhcyBQb2x5Z29uO1xuICAgICAgY29uc3QgaXNCZXppZXIgPVxuICAgICAgICAhIXAuYmV6aWVyICYmIHAuaGFuZGxlc0luPy5sZW5ndGggPT09IHAubnBvaW50cyAmJiBwLmhhbmRsZXNPdXQ/Lmxlbmd0aCA9PT0gcC5ucG9pbnRzO1xuICAgICAgY29uc3QgaGFzSG9sZXMgPSAhIShwLmhvbGVzICYmIHAuaG9sZXMubGVuZ3RoKTtcbiAgICAgIC8vIEJlemllciBvciBkb251dCAoaG9sZXMpIOKGkiBhIHNpbmdsZSA8cGF0aD47IGhvbGVzIHVzZSBldmVuLW9kZCBmaWxsIHNvIHRoZXkgcHVuY2ggdGhyb3VnaC5cbiAgICAgIGlmIChpc0JlemllciB8fCBoYXNIb2xlcykge1xuICAgICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICdwYXRoJyk7XG4gICAgICAgIGVsLnNldEF0dHJpYnV0ZSgnZCcsIHRoaXMucG9seWdvblBhdGhEYXRhKHAsIGlzQmV6aWVyKSk7XG4gICAgICAgIGlmIChoYXNIb2xlcykgZWwuc2V0QXR0cmlidXRlKCdmaWxsLXJ1bGUnLCAnZXZlbm9kZCcpO1xuICAgICAgICB0aGlzLnN0eWxlKGVsLCBzdHJva2UsIGlzU2VsZWN0ZWQpO1xuICAgICAgICByZXR1cm4gZWw7XG4gICAgICB9XG4gICAgICBjb25zdCBwdHMgPSBwLnhwb2ludHNcbiAgICAgICAgLm1hcCgoXywgaSkgPT4gdGhpcy50b0xvY2FsKHAueHBvaW50c1tpXSwgcC55cG9pbnRzW2ldKS5qb2luKCcsJykpXG4gICAgICAgIC5qb2luKCcgJyk7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsIHAuY2xvc2VkID09PSBmYWxzZSA/ICdwb2x5bGluZScgOiAncG9seWdvbicpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdwb2ludHMnLCBwdHMpO1xuICAgICAgdGhpcy5zdHlsZShlbCwgc3Ryb2tlLCBpc1NlbGVjdGVkKTtcbiAgICAgIHJldHVybiBlbDtcbiAgICB9XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cblxuICAvKiogUGF0aCBkYXRhIGZvciBhIHBvbHlnb246IHRoZSBleHRlcmlvciByaW5nIChiZXppZXIgb3Igc3RyYWlnaHQpIHBsdXMgYW55IGhvbGVzIChiZXppZXIgd2hlblxuICAgKiAgdGhlIGRvbnV0IGNhcnJpZXMgaG9sZSBoYW5kbGVzLCBlbHNlIHN0cmFpZ2h0KSBhcyBzdWItcGF0aHMg4oCUIGV2ZW4tb2RkIGZpbGwgY3V0cyB0aGVtIG91dC4gKi9cbiAgcHJpdmF0ZSBwb2x5Z29uUGF0aERhdGEocDogUG9seWdvbiwgaXNCZXppZXI6IGJvb2xlYW4pOiBzdHJpbmcge1xuICAgIGxldCBkID0gaXNCZXppZXJcbiAgICAgID8gdGhpcy5yaW5nQmV6aWVyUGF0aChwLnhwb2ludHMsIHAueXBvaW50cywgcC5oYW5kbGVzSW4hLCBwLmhhbmRsZXNPdXQhLCBwLmNsb3NlZCAhPT0gZmFsc2UpXG4gICAgICA6IHRoaXMuc3RyYWlnaHRQYXRoKHAueHBvaW50cywgcC55cG9pbnRzLCBwLmNsb3NlZCAhPT0gZmFsc2UpO1xuICAgIGNvbnN0IGhvbGVCZXppZXIgPSAhIShwLmJlemllciAmJiBwLmhvbGVIYW5kbGVzSW4gJiYgcC5ob2xlSGFuZGxlc091dCk7XG4gICAgKHAuaG9sZXMgPz8gW10pLmZvckVhY2goKHJpbmcsIGhpKSA9PiB7XG4gICAgICBpZiAocmluZy5sZW5ndGggPCAzKSByZXR1cm47XG4gICAgICBjb25zdCB4cyA9IHJpbmcubWFwKChwdCkgPT4gcHRbMF0pO1xuICAgICAgY29uc3QgeXMgPSByaW5nLm1hcCgocHQpID0+IHB0WzFdKTtcbiAgICAgIGlmIChob2xlQmV6aWVyICYmIHAuaG9sZUhhbmRsZXNJbiFbaGldICYmIHAuaG9sZUhhbmRsZXNPdXQhW2hpXSkge1xuICAgICAgICBkICs9ICcgJyArIHRoaXMucmluZ0JlemllclBhdGgoeHMsIHlzLCBwLmhvbGVIYW5kbGVzSW4hW2hpXSwgcC5ob2xlSGFuZGxlc091dCFbaGldLCB0cnVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGQgKz0gJyAnICsgdGhpcy5zdHJhaWdodFBhdGgoeHMsIHlzLCB0cnVlKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICByZXR1cm4gZDtcbiAgfVxuXG4gIC8qKiBTVkcgcGF0aCBkYXRhIGZvciBhIHN0cmFpZ2h0IHJpbmcvcG9seWxpbmUgaW4gaW1hZ2UgY29vcmRzIChjbG9zZWQgYXBwZW5kcyBgWmApLiAqL1xuICBwcml2YXRlIHN0cmFpZ2h0UGF0aCh4czogbnVtYmVyW10sIHlzOiBudW1iZXJbXSwgY2xvc2VkOiBib29sZWFuKTogc3RyaW5nIHtcbiAgICBsZXQgZCA9ICcnO1xuICAgIGZvciAobGV0IGkgPSAwOyBpIDwgeHMubGVuZ3RoOyBpKyspIHtcbiAgICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKHhzW2ldLCB5c1tpXSk7XG4gICAgICBkICs9IChpID09PSAwID8gJ00nIDogJyBMJykgKyBgICR7bHh9LCR7bHl9YDtcbiAgICB9XG4gICAgcmV0dXJuIGNsb3NlZCA/IGQgKyAnIFonIDogZDtcbiAgfVxuXG4gIC8qKiBTVkcgY3ViaWMtYmV6aWVyIHBhdGggZGF0YSBmb3IgYW55IHJpbmcgKGV4dGVyaW9yIG9yIGhvbGUpOiBhbmNob3JzIGpvaW5lZCBieSBjdWJpYyBzZWdtZW50c1xuICAgKiAgd2hvc2UgY29udHJvbCBwb2ludHMgYXJlIGBhbmNob3IgKyBoYW5kbGVPdXRgIChsZWF2aW5nKSBhbmQgYG5leHRBbmNob3IgKyBoYW5kbGVJbmAgKGFycml2aW5nKSxcbiAgICogIGluIGltYWdlIHNwYWNlLiBVc2VkIGZvciBib3RoIHRoZSBleHRlcmlvciBhbmQgKGRvbnV0KSBob2xlIHJpbmdzLiAqL1xuICBwcml2YXRlIHJpbmdCZXppZXJQYXRoKFxuICAgIHhzOiBudW1iZXJbXSxcbiAgICB5czogbnVtYmVyW10sXG4gICAgaEluOiBudW1iZXJbXVtdLFxuICAgIGhPdXQ6IG51bWJlcltdW10sXG4gICAgY2xvc2VkOiBib29sZWFuLFxuICApOiBzdHJpbmcge1xuICAgIGNvbnN0IG4gPSB4cy5sZW5ndGg7XG4gICAgY29uc3QgYW5jaG9yID0gKGk6IG51bWJlcik6IFtudW1iZXIsIG51bWJlcl0gPT4gdGhpcy50b0xvY2FsKHhzW2ldLCB5c1tpXSk7XG4gICAgY29uc3QgY3RybE91dCA9IChpOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdID0+XG4gICAgICB0aGlzLnRvTG9jYWwoeHNbaV0gKyAoaE91dFtpXT8uWzBdID8/IDApLCB5c1tpXSArIChoT3V0W2ldPy5bMV0gPz8gMCkpO1xuICAgIGNvbnN0IGN0cmxJbiA9IChpOiBudW1iZXIpOiBbbnVtYmVyLCBudW1iZXJdID0+XG4gICAgICB0aGlzLnRvTG9jYWwoeHNbaV0gKyAoaEluW2ldPy5bMF0gPz8gMCksIHlzW2ldICsgKGhJbltpXT8uWzFdID8/IDApKTtcbiAgICBjb25zdCBbc3gsIHN5XSA9IGFuY2hvcigwKTtcbiAgICBsZXQgZCA9IGBNICR7c3h9LCR7c3l9YDtcbiAgICBjb25zdCBzZWdtZW50cyA9IGNsb3NlZCA/IG4gOiBuIC0gMTtcbiAgICBmb3IgKGxldCBzID0gMDsgcyA8IHNlZ21lbnRzOyBzKyspIHtcbiAgICAgIGNvbnN0IGkgPSBzO1xuICAgICAgY29uc3QgaiA9IChzICsgMSkgJSBuO1xuICAgICAgY29uc3QgW2MxeCwgYzF5XSA9IGN0cmxPdXQoaSk7XG4gICAgICBjb25zdCBbYzJ4LCBjMnldID0gY3RybEluKGopO1xuICAgICAgY29uc3QgW2V4LCBleV0gPSBhbmNob3Ioaik7XG4gICAgICBkICs9IGAgQyAke2MxeH0sJHtjMXl9ICR7YzJ4fSwke2MyeX0gJHtleH0sJHtleX1gO1xuICAgIH1cbiAgICBpZiAoY2xvc2VkKSBkICs9ICcgWic7XG4gICAgcmV0dXJuIGQ7XG4gIH1cblxuICBwcml2YXRlIHN0eWxlKGVsOiBTVkdFbGVtZW50LCBzdHJva2U6IHN0cmluZywgaXNTZWxlY3RlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGVsLnNldEF0dHJpYnV0ZSgnc3Ryb2tlJywgc3Ryb2tlKTtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZS13aWR0aCcsIGlzU2VsZWN0ZWQgPyAnNCcgOiAnMicpO1xuICAgIGVsLnNldEF0dHJpYnV0ZSgnZmlsbCcsIGlzU2VsZWN0ZWQgPyBzdHJva2UgOiAnbm9uZScpO1xuICAgIGVsLnNldEF0dHJpYnV0ZSgnZmlsbC1vcGFjaXR5JywgaXNTZWxlY3RlZCA/ICcwLjM1JyA6ICcwJyk7XG4gICAgZWwuc2V0QXR0cmlidXRlKCd2ZWN0b3ItZWZmZWN0JywgJ25vbi1zY2FsaW5nLXN0cm9rZScpO1xuICB9XG5cbiAgLyoqIERyYXcgdGhlIGluLXByb2dyZXNzIHJlY3RhbmdsZSAvIHBhdGggcHJldmlldy4gKi9cbiAgcHJpdmF0ZSBkcmF3RHJhZnQoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZHJhZnRSZWN0KSB7XG4gICAgICBjb25zdCB7IHgwLCB5MCwgeDEsIHkxIH0gPSB0aGlzLmRyYWZ0UmVjdDtcbiAgICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy50b0xvY2FsKE1hdGgubWluKHgwLCB4MSksIE1hdGgubWluKHkwLCB5MSkpO1xuICAgICAgY29uc3QgW3J4LCByeV0gPSB0aGlzLnRvTG9jYWwoTWF0aC5tYXgoeDAsIHgxKSwgTWF0aC5tYXgoeTAsIHkxKSk7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICdyZWN0Jyk7XG4gICAgICBlbC5zZXRBdHRyaWJ1dGUoJ3gnLCBgJHtseH1gKTtcbiAgICAgIGVsLnNldEF0dHJpYnV0ZSgneScsIGAke2x5fWApO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCd3aWR0aCcsIGAke01hdGguYWJzKHJ4IC0gbHgpfWApO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdoZWlnaHQnLCBgJHtNYXRoLmFicyhyeSAtIGx5KX1gKTtcbiAgICAgIHRoaXMuc3R5bGVEcmFmdChlbCk7XG4gICAgICB0aGlzLnN2Zy5hcHBlbmRDaGlsZChlbCk7XG4gICAgfVxuICAgIGlmICh0aGlzLmRyYWZ0UGF0aCAmJiB0aGlzLmRyYWZ0UGF0aC5sZW5ndGgpIHtcbiAgICAgIGNvbnN0IHB0cyA9IHRoaXMuZHJhZnRQYXRoLm1hcCgoW3gsIHldKSA9PiB0aGlzLnRvTG9jYWwoeCwgeSkuam9pbignLCcpKS5qb2luKCcgJyk7XG4gICAgICBjb25zdCBlbCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhTVkdfTlMsICdwb2x5bGluZScpO1xuICAgICAgZWwuc2V0QXR0cmlidXRlKCdwb2ludHMnLCBwdHMpO1xuICAgICAgdGhpcy5zdHlsZURyYWZ0KGVsKTtcbiAgICAgIHRoaXMuc3ZnLmFwcGVuZENoaWxkKGVsKTtcbiAgICB9XG4gIH1cblxuICBwcml2YXRlIHN0eWxlRHJhZnQoZWw6IFNWR0VsZW1lbnQpOiB2b2lkIHtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ3N0cm9rZScsIHRoaXMuc3RvcmUuZ2V0U2hhcGVDb2xvcigpIHx8ICcjMDBmZmZmJyk7XG4gICAgZWwuc2V0QXR0cmlidXRlKCdzdHJva2Utd2lkdGgnLCAnMicpO1xuICAgIGVsLnNldEF0dHJpYnV0ZSgnc3Ryb2tlLWRhc2hhcnJheScsICc0IDMnKTtcbiAgICBlbC5zZXRBdHRyaWJ1dGUoJ2ZpbGwnLCAnbm9uZScpO1xuICAgIGVsLnNldEF0dHJpYnV0ZSgndmVjdG9yLWVmZmVjdCcsICdub24tc2NhbGluZy1zdHJva2UnKTtcbiAgfVxufVxuIl19
485
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmFwYXJpLXJlZ2lvbi1vdmVybGF5LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vc3JjL2xpYi9pbXBsZW1lbnRhdGlvbnMvbmFwYXJpLWpzL25hcGFyaS1yZWdpb24tb3ZlcmxheS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBR3BDLE9BQU8sRUFBRSxNQUFNLEVBQUUsU0FBUyxFQUFFLE9BQU8sRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBSWpFLE9BQU8sRUFDTCxTQUFTLEVBQ1QsV0FBVyxFQUNYLGFBQWEsRUFDYixjQUFjLEVBQ2QsYUFBYSxHQUNkLE1BQU0sc0NBQXNDLENBQUM7QUFFOUMsT0FBTyxFQUFXLHVCQUF1QixFQUFFLE1BQU0sc0NBQXNDLENBQUM7QUFDeEYsT0FBTyxFQUFFLGlCQUFpQixFQUFFLE1BQU0scUNBQXFDLENBQUM7QUFDeEUsT0FBTyxFQUFjLGVBQWUsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTNFLE1BQU0sTUFBTSxHQUFHLDRCQUE0QixDQUFDO0FBQzVDOzs7Ozs7Ozs7R0FTRztBQUNILE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBQzNCOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxnQkFBZ0IsR0FBRyxDQUFDLENBQUM7QUFDM0I7Ozs7R0FJRztBQUNILE1BQU0sY0FBYyxHQUFHLENBQUMsQ0FBQztBQUN6QixrR0FBa0c7QUFDbEcsTUFBTSxhQUFhLEdBQUcsRUFBRSxDQUFDO0FBQ3pCLDRFQUE0RTtBQUM1RSxNQUFNLGFBQWEsR0FBRyxDQUFDLENBQUM7QUFDeEIseUZBQXlGO0FBQ3pGLE1BQU0sZ0JBQWdCLEdBQUcsQ0FBQyxDQUFDO0FBNkIzQjs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBa0JHO0FBQ0gsTUFBTSxPQUFPLG1CQUFtQjtJQXVCOUIsWUFDbUIsSUFBaUIsRUFDakIsTUFBcUIsRUFDckIsS0FBa0I7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QzdGLElBQUksRUFBRSxJQUFJLENBQUMsU0FBUztZQUNwQixJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVM7U0FDckIsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5cbmltcG9ydCB7IElSZWdpb25PdmVybGF5LCBSZWdpb25Ub29sTW9kZSB9IGZyb20gJy4uLy4uL2NvbnRyYWN0cy9yZWdpb24tb3ZlcmxheS5jb250cmFjdCc7XG5pbXBvcnQgeyBSZWdpb24sIFJlY3RhbmdsZSwgUG9seWdvbiB9IGZyb20gJy4uLy4uL21vZGVscy9yZWdpb24nO1xuaW1wb3J0IHsgUmVnaW9uU3RvcmUgfSBmcm9tICcuLi8uLi9zdG9yZS9yZWdpb24tc3RvcmUuc2VydmljZSc7XG5pbXBvcnQgdHlwZSB7IEFmZmluZSB9IGZyb20gJy4uLy4uL3JlZ2lvbi1vdmVybGF5L3N2Zy1yZWdpb24tcmVuZGVyZXInO1xuXG5pbXBvcnQge1xuICBoaXRIYW5kbGUsXG4gIG5lYXJlc3RFZGdlLFxuICBuZWFyZXN0VmVydGV4LFxuICByZWdpb25Db250YWlucyxcbiAgcmVnaW9uc0luUmVjdCxcbn0gZnJvbSAnLi4vLi4vcmVnaW9uLW92ZXJsYXkvcmVnaW9uLWdlb21ldHJ5JztcblxuaW1wb3J0IHsgRHJhZ0JveCwgTmFwYXJpUmVnaW9uU3ZnUmVuZGVyZXIgfSBmcm9tICcuL3JlZ2lvbi1vdmVybGF5L3JlZ2lvbi1zdmctcmVuZGVyZXInO1xuaW1wb3J0IHsgT3ZlcmxheVByb2plY3Rpb24gfSBmcm9tICcuL3JlZ2lvbi1vdmVybGF5L292ZXJsYXktcHJvamVjdGlvbic7XG5pbXBvcnQgeyBSZWdpb25FZGl0LCBhcHBseVJlZ2lvbkVkaXQgfSBmcm9tICcuL3JlZ2lvbi1vdmVybGF5L3JlZ2lvbi1lZGl0JztcblxuY29uc3QgU1ZHX05TID0gJ2h0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnJztcbi8qKlxuICogTWluIGRyYWcgYmVmb3JlIGEgZnJlZWhhbmQgcGF0aCByZWNvcmRzIGFub3RoZXIgcG9pbnQsIGluIFNDUkVFTiBwaXhlbHMuXG4gKlxuICogU2NyZWVuIHJhdGhlciB0aGFuIHdvcmxkLCB3aGljaCBpcyB3aGF0IFwiMiBpbWFnZSBweFwiIGFsd2F5cyBtZWFudCBpbiBwcmFjdGljZTogYXQgMTAwJVxuICogem9vbSBvdmVyIGFuIGltYWdlIHRoZSB0d28gYXJlIHRoZSBzYW1lIHRoaW5nLiBUYWtlbiBhcyB3b3JsZCB1bml0cyBpdCBicmVha3Mgb24gYW55XG4gKiBkYXRhc2V0IHdob3NlIHdvcmxkIGlzIHNtYWxsIOKAlCBzZXFGSVNIJ3Mgc2FtcGxlIHNwYW5zIGFib3V0IDUgdW5pdHMsIHNvIGEgMi11bml0XG4gKiB0aHJlc2hvbGQgcmVjb3JkcyBhIHBvaW50IGV2ZXJ5IDQwJSBvZiB0aGUgd2F5IGFjcm9zcyBhbmQgYSBmcmVlaGFuZCBST0kgY29tZXMgb3V0IGFzIGFcbiAqIHRyaWFuZ2xlLiBBZ2FpbnN0IHRoZSBzY3JlZW4gaXQgYWxzbyBkb2VzIHRoZSByaWdodCB0aGluZyB1bmRlciB6b29tOiBkcmF3aW5nIHpvb21lZCBpblxuICogcmVjb3JkcyBhIGZpbmVyIHBhdGgsIGJlY2F1c2UgdGhhdCBpcyBleGFjdGx5IHdoZW4gdGhlIGV4dHJhIGRldGFpbCBpcyB2aXNpYmxlLlxuICovXG5jb25zdCBGUkVFSEFORF9TVEVQX1BYID0gMjtcbi8qKlxuICogU21hbGxlc3QgY29tbWl0dGVkIHJlY3RhbmdsZSwgaW4gU0NSRUVOIHBpeGVscyBvbiBlYWNoIHNpZGUuXG4gKlxuICogSXRzIGpvYiBpcyB0byB0aHJvdyBhd2F5IGEgY2xpY2sgdGhhdCB3YXMgbm90IGEgZHJhZy4gSGVsZCBpbiB3b3JsZCB1bml0cyDigJQgd2hpY2ggaXQgd2FzXG4gKiDigJQgaXQgaW5zdGVhZCB0aHJvd3MgYXdheSByZWFsIGRyYWdzIG9uIGFueSBkYXRhc2V0IHdob3NlIHdvcmxkIGlzIHNtYWxsOiBpbiBzZXFGSVNIJ3NcbiAqIH41IHggNyB1bml0IHNhbXBsZSBhIHJlY3RhbmdsZSBoYWQgdG8gY292ZXIgNDAlIG9mIHRoZSB3aWR0aCB0byBjb21taXQgYXQgYWxsLCBhbmRcbiAqIGFueXRoaW5nIHNtYWxsZXIgdmFuaXNoZWQgd2l0aCBubyBmZWVkYmFjay4gVGhhdCB3YXMgdGhlIGRpcmVjdCBjYXVzZSBvZiBST0lzIGJlaW5nXG4gKiBpbXBvc3NpYmxlIHRvIGNyZWF0ZSB0aGVyZS5cbiAqL1xuY29uc3QgTUlOX1JFQ1RfRFJBR19QWCA9IDI7XG4vKipcbiAqIEEgcnViYmVyIGJhbmQgc21hbGxlciB0aGFuIHRoaXMgb24gYm90aCBzaWRlcywgaW4gU0NSRUVOIHBpeGVscywgaXMgYSBjbGljayBvbiBlbXB0eSBzcGFjZVxuICogKGl0IGNsZWFycyB0aGUgc2VsZWN0aW9uKS4gU2NyZWVuIGZvciB0aGUgc2FtZSByZWFzb24gYXMge0BsaW5rIE1JTl9SRUNUX0RSQUdfUFh9OiAzIHdvcmxkXG4gKiB1bml0cyBpcyBvdmVyIGhhbGYgb2Ygc2VxRklTSCdzIHNhbXBsZS5cbiAqL1xuY29uc3QgTUlOX01BUlFVRUVfUFggPSAzO1xuLyoqIENsaWNrLWRpc3RhbmNlIChzY3JlZW4gcHgpIHdpdGhpbiB3aGljaCBhIHBvbHlnb24gY2xpY2sgc25hcHMgY2xvc2VkIG9udG8gdGhlIGZpcnN0IHZlcnRleC4gKi9cbmNvbnN0IENMT1NFX1NOQVBfUFggPSAxMDtcbi8qKiBTY3JlZW4tcHggaGl0IHJhZGl1cyBmb3IgZ3JhYmJpbmcgYSB2ZXJ0ZXggLyByZWN0YW5nbGUgY29ybmVyIGhhbmRsZS4gKi9cbmNvbnN0IEhBTkRMRV9ISVRfUFggPSA5O1xuLyoqIFNjcmVlbi1weCBkaXN0YW5jZSBmcm9tIGFuIG9wZW4gcG9seWxpbmUgd2l0aGluIHdoaWNoIGEgY2xpY2sgc2VsZWN0cyBpdCAoYXMgT1NEKS4gKi9cbmNvbnN0IE9QRU5fUEFUSF9ISVRfUFggPSA2O1xuXG4vKipcbiAqIFRoZSBzbGljZSBvZiB0aGUgbmFwYXJpIFZpZXdlciB0aGUgb3ZlcmxheSBuZWVkcyAoY29vcmQgdHJhbnNmb3JtcyArIGNvbnRyb2wgZ2F0aW5nKS5cbiAqXG4gKiBDT09SRElOQVRFIFNQQUNFUzogYGNhbnZhc1RvV29ybGRgIHRha2VzIENMSUVOVCBwaXhlbHMgKHZpZXdwb3J0IGNvb3JkaW5hdGVzLCBhcyBhIHBvaW50ZXJcbiAqIGV2ZW50J3MgYGNsaWVudFgvWWApLCBleGFjdGx5IGFzIG5hcGFyaS1qcyBgVmlld2VyLmNhbnZhc1RvV29ybGRgIGRvZXMuIGBjYW52YXNUcmFuc2Zvcm1gIGlzXG4gKiB0aGUgY2FtZXJhJ3Mgd29ybGQg4oaSIENBTlZBUy1MT0NBTCBDU1MtcGl4ZWwgYWZmaW5lLCBuYXBhcmktanMgYFZpZXdlci5jYW52YXNUcmFuc2Zvcm1gLCB3aGljaFxuICogcmVhZHMgbm8gbGF5b3V0OiBkcmF3aW5nIGFuZCBmb2xsb3dpbmcgdGhlIGNhbWVyYSB1c2UgaXQsIHNvIGEgY2FtZXJhIGZyYW1lIGNvc3RzIG9uZVxuICogYG1hdHJpeCguLi4pYCBhbmQgbm8gYGdldEJvdW5kaW5nQ2xpZW50UmVjdCgpYCAocmV2aWV3IE5BUEFSSS1CT1VOREFSWS0xMCkuIFRoZSBzdmcgY292ZXJzIHRoZVxuICogcGxvdCBob3N0IGFuZCB0aGUgY2FudmFzIGlzIHRoZSBob3N0J3MgaW4tZmxvdyBjaGlsZCBhdCBpdHMgdG9wLWxlZnQsIHNvIGNhbnZhcy1sb2NhbCBhbmRcbiAqIHN2Zy1sb2NhbCBwaXhlbHMgYXJlIHRoZSBzYW1lOyBhIHBvaW50ZXIncyBjbGllbnQgcGl4ZWxzIGFyZSBtYXBwZWQgaW50byB0aGUgc3ZnIGJ5IHRoZVxuICogb3ZlcmxheSBpdHNlbGYuXG4gKlxuICogRXhwb3J0ZWQgYmVjYXVzZSB0aGUgM0Qgc3BhdGlhbCBtb2RlIHN1cHBsaWVzIGEgU0NSRUVOLVNQQUNFIGltcGxlbWVudGF0aW9uIG9mIGl0OiB0aGVyZSB0aGVcbiAqIGRyYXduIHNoYXBlIGlzIGEgbGFzc28gaW4gY2FudmFzIHBpeGVscywgbm90IGEgcmVjdGFuZ2xlIGluIGltYWdlIHNwYWNlLCBzbyBcIndvcmxkXCIgaXMgdGhlXG4gKiBjYW52YXMgaXRzZWxmIOKAlCBgY2FudmFzVG9Xb3JsZGAgaXMgdGhlIGNsaWVudCDihpIgY2FudmFzIG9mZnNldCBhbmQgYGNhbnZhc1RyYW5zZm9ybWAgdGhlXG4gKiBpZGVudGl0eS4gVGhhdCBsZXRzIHRoZSAzRCB2aWV3IHJldXNlIHRoaXMgd2hvbGUgb3ZlcmxheSDigJQgZXZlcnkgdG9vbCwgdGhlIGhhbmRsZXMsIHRoZSBzdG9yZVxuICogcm91bmQtdHJpcCDigJQgd2l0aCBubyAzRC1zcGVjaWZpYyBkcmF3aW5nIGNvZGUuXG4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgT3ZlcmxheVZpZXdlciB7XG4gIC8qKiBDbGllbnQgcHgg4oaSIHdvcmxkLiAqL1xuICBjYW52YXNUb1dvcmxkKGNsaWVudFg6IG51bWJlciwgY2xpZW50WTogbnVtYmVyKTogW251bWJlciwgbnVtYmVyXTtcbiAgLyoqIFdvcmxkIOKGkiBjYW52YXMtbG9jYWwgKD0gc3ZnLWxvY2FsKSBDU1MgcHgsIGFzIGFuIFNWRyBhZmZpbmUgYFthLCBiLCBjLCBkLCBlLCBmXWAuICovXG4gIGNhbnZhc1RyYW5zZm9ybSgpOiBBZmZpbmU7XG4gIHNldENvbnRyb2xzRW5hYmxlZChlbmFibGVkOiBib29sZWFuKTogdm9pZDtcbiAgcmVhZG9ubHkgY2FtZXJhOiB7IHJlYWRvbmx5IGNoYW5nZWQ6IHsgY29ubmVjdChsaXN0ZW5lcjogKCkgPT4gdm9pZCk6ICgpID0+IHZvaWQgfSB9O1xufVxuXG4vKipcbiAqIFNWRyByZWdpb24gb3ZlcmxheSBmb3IgdGhlIG5hcGFyaS1qcyBXZWJHUFUgaW1hZ2UgdmlldyAoaml0LXVpIzEwMiksIG1pcnJvcmluZyB0aGUgT1NEIGJhY2tlbmQnc1xuICoge0BsaW5rIE9zZFJlZ2lvbk92ZXJsYXl9IGJ1dCBkcml2ZW4gYnkgbmFwYXJpJ3MgYGNhbnZhc1RvV29ybGRgL2BjYW52YXNUcmFuc2Zvcm1gIHRyYW5zZm9ybXNcbiAqIChzZWUge0BsaW5rIE92ZXJsYXlWaWV3ZXJ9IGZvciB0aGVpciBjb29yZGluYXRlIHNwYWNlcykuXG4gKiBWZWN0b3Igc2hhcGVzIGFyZSBkcmF3biBpbiBhbiBhYnNvbHV0ZWx5LXBvc2l0aW9uZWQgYDxzdmc+YCBvdmVyIHRoZSBjYW52YXMgKG5vIG5lZWQgdG8gcHVzaFxuICogdGhlbSB0aHJvdWdoIFdlYkdQVSkgYnkge0BsaW5rIE5hcGFyaVJlZ2lvblN2Z1JlbmRlcmVyfSBvdmVyIHRoZSBzaGFyZWQgYFN2Z1JlZ2lvblJlbmRlcmVyYDpcbiAqIGluIHdvcmxkIGNvb3JkaW5hdGVzIGluc2lkZSBvbmUgdHJhbnNmb3JtZWQgZ3JvdXAsIHJlYnVpbHQgb24gYSByZWdpb24gb3Igc2VsZWN0aW9uIGNoYW5nZSxcbiAqIHdoaWxlIGEgY2FtZXJhIG1vdmUgb25seSByZXdyaXRlcyB0aGUgdHJhbnNmb3JtIChuYXBhcmktanMncyBgY2FudmFzVHJhbnNmb3JtYCwgdGhlIGNhbWVyYVxuICogY2VudHJlL3pvb20pIGFuZCB0aGUgZmV3IHNjcmVlbi1zcGFjZSBoYW5kbGVzIGFuZCBsYWJlbHMuIFRoaXMgY2xhc3MgaXNcbiAqIHRoZSBnZXN0dXJlIGNvbnRyb2xsZXI6IHBvaW50ZXIgaGFuZGxlcnMsIHRoZSB0b29sIG1vZGUsIGFuZCB0aGUgZWRpdC9kcmFmdC9tYXJxdWVlIHN0YXRlLlxuICogSXQgd3JpdGVzIGNvbXBsZXRlZCBzaGFwZXMgdG8gdGhlIHNoYXJlZCB7QGxpbmsgUmVnaW9uU3RvcmV9IChzbyBzYXZlIC8gdW5kbyAvIGV4cG9ydCB3b3JrXG4gKiBpZGVudGljYWxseSB0byBPU0QpLlxuICpcbiAqIFN1cHBvcnRzIChqaXQtdWkjMTAyKTogcmVjdGFuZ2xlIC8gcG9seWdvbiAvIGZyZWVoYW5kIHBhdGggZHJhd2luZywgY2xpY2stc2VsZWN0IGFuZCBydWJiZXItYmFuZFxuICogbWFycXVlZSBzZWxlY3QsIHBhbi96b29tIGdhdGluZyB2aWEgYHNldENvbnRyb2xzRW5hYmxlZGAsIGJvZHkgbW92ZSwgdmVydGV4IG1vdmUvYWRkL2RlbGV0ZSxcbiAqIGJlemllciBoYW5kbGUgZWRpdGluZywgYW5kIGRvbnV0IGhvbGVzIChpbmNsdWRpbmcgaG9sZSB2ZXJ0ZXggKyBob2xlLWJlemllci1oYW5kbGUgZWRpdGluZykuXG4gKiBIaXQtdGVzdGluZyBzaGFyZXMgYHJlZ2lvbi1vdmVybGF5L3JlZ2lvbi1nZW9tZXRyeWAgd2l0aCB0aGUgT1NEIG92ZXJsYXksIHNvIGJvdGggZm9sbG93XG4gKiB0aGUgc2FtZSBydWxlcyAobXVsdGktcGFydCByZWdpb25zLCBob2xlcywgb3BlbiBwb2x5bGluZXMsIGhhbmRsZS1sZXNzIGJlemllciBjdXJ2ZXMpLlxuICovXG5leHBvcnQgY2xhc3MgTmFwYXJpUmVnaW9uT3ZlcmxheSBpbXBsZW1lbnRzIElSZWdpb25PdmVybGF5IHtcbiAgcHJpdmF0ZSByZWFkb25seSBzdmc6IFNWR1NWR0VsZW1lbnQ7XG4gIHByaXZhdGUgcmVhZG9ubHkgcmVuZGVyZXI6IE5hcGFyaVJlZ2lvblN2Z1JlbmRlcmVyO1xuICAvKiogQ2xpZW50IOKGlCBzdmctbG9jYWwg4oaUIHdvcmxkIGNvbnZlcnNpb25zLCB3aXRoIHRoZSBzdmcgb3JpZ2luIHJlYWQgb25jZSBwZXIgZ2VzdHVyZS9yZWRyYXcuICovXG4gIHByaXZhdGUgcmVhZG9ubHkgcHJvamVjdGlvbjogT3ZlcmxheVByb2plY3Rpb247XG4gIHByaXZhdGUgcmVhZG9ubHkgc3VicyA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBkaXNjb25uZWN0Q2FtZXJhOiAoKSA9PiB2b2lkO1xuXG4gIHByaXZhdGUgbW9kZTogUmVnaW9uVG9vbE1vZGUgPSAnbm9uZSc7XG4gIHByaXZhdGUgc2VsZWN0ZWQ6IG51bWJlcltdID0gW107XG5cbiAgLyoqIEluLXByb2dyZXNzIGRyYXdpbmcgc3RhdGUgKGltYWdlLXNwYWNlKS4gKi9cbiAgcHJpdmF0ZSBkcmFmdFJlY3Q6IERyYWdCb3ggfCBudWxsID0gbnVsbDtcbiAgLyoqIEluLXByb2dyZXNzIHJ1YmJlci1iYW5kIHNlbGVjdGlvbiBtYXJxdWVlIChzZWxlY3QgbW9kZSksIGltYWdlLXNwYWNlLiAqL1xuICBwcml2YXRlIG1hcnF1ZWU6IERyYWdCb3ggfCBudWxsID0gbnVsbDtcbiAgcHJpdmF0ZSBkcmFmdFBhdGg6IEFycmF5PFtudW1iZXIsIG51bWJlcl0+IHwgbnVsbCA9IG51bGw7IC8vIGZyZWVoYW5kIG9yIGNsaWNrIHBvbHlnb25cbiAgcHJpdmF0ZSBkcmF3aW5nID0gZmFsc2U7IC8vIHBvaW50ZXIgaXMgZG93biBmb3IgcmVjdCAvIGZyZWVoYW5kXG4gIHByaXZhdGUgcmVnaW9uc1Zpc2libGUgPSB0cnVlO1xuXG4gIC8qKiBJbi1wcm9ncmVzcyBtYW5pcHVsYXRpb24gKHNlbGVjdC9tb3ZlIG1vZGVzKTogZHJhZ2dpbmcgYSBib2R5LCBhIHBvbHlnb24gdmVydGV4LCBvciBhXG4gICAqICByZWN0YW5nbGUgY29ybmVyLiBgYW5jaG9yYCBpcyB0aGUgZml4ZWQgb3Bwb3NpdGUgY29ybmVyIGZvciBhIHJlY3RhbmdsZSByZXNpemUuICovXG4gIHByaXZhdGUgZWRpdDogUmVnaW9uRWRpdCB8IG51bGwgPSBudWxsO1xuXG4gIGNvbnN0cnVjdG9yKFxuICAgIHByaXZhdGUgcmVhZG9ubHkgaG9zdDogSFRNTEVsZW1lbnQsXG4gICAgcHJpdmF0ZSByZWFkb25seSB2aWV3ZXI6IE92ZXJsYXlWaWV3ZXIsXG4gICAgcHJpdmF0ZSByZWFkb25seSBzdG9yZTogUmVnaW9uU3RvcmUsXG4gICkge1xuICAgIGlmIChnZXRDb21wdXRlZFN0eWxlKGhvc3QpLnBvc2l0aW9uID09PSAnc3RhdGljJykgaG9zdC5zdHlsZS5wb3NpdGlvbiA9ICdyZWxhdGl2ZSc7XG4gICAgdGhpcy5zdmcgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoU1ZHX05TLCAnc3ZnJyk7XG4gICAgT2JqZWN0LmFzc2lnbih0aGlzLnN2Zy5zdHlsZSwge1xuICAgICAgcG9zaXRpb246ICdhYnNvbHV0ZScsXG4gICAgICBpbnNldDogJzAnLFxuICAgICAgd2lkdGg6ICcxMDAlJyxcbiAgICAgIGhlaWdodDogJzEwMCUnLFxuICAgICAgekluZGV4OiAnMjAnLFxuICAgICAgcG9pbnRlckV2ZW50czogJ25vbmUnLCAvLyB1bnRpbCBhIHRvb2wgYWN0aXZhdGVzXG4gICAgICB0b3VjaEFjdGlvbjogJ25vbmUnLFxuICAgIH0gYXMgUGFydGlhbDxDU1NTdHlsZURlY2xhcmF0aW9uPik7XG4gICAgdGhpcy5ob3N0LmFwcGVuZENoaWxkKHRoaXMuc3ZnKTtcbiAgICB0aGlzLnJlbmRlcmVyID0gbmV3IE5hcGFyaVJlZ2lvblN2Z1JlbmRlcmVyKHRoaXMuc3ZnLCB0aGlzLnN0b3JlKTtcbiAgICB0aGlzLnByb2plY3Rpb24gPSBuZXcgT3ZlcmxheVByb2plY3Rpb24odGhpcy5zdmcsIHRoaXMudmlld2VyKTtcblxuICAgIHRoaXMuc3ZnLmFkZEV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5vblBvaW50ZXJEb3duKTtcbiAgICB0aGlzLnN2Zy5hZGRFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMub25Qb2ludGVyTW92ZSk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIHRoaXMub25Qb2ludGVyQ2FuY2VsKTtcbiAgICB0aGlzLnN2Zy5hZGRFdmVudExpc3RlbmVyKCdsb3N0cG9pbnRlcmNhcHR1cmUnLCB0aGlzLm9uUG9pbnRlckNhbmNlbCk7XG4gICAgdGhpcy5zdmcuYWRkRXZlbnRMaXN0ZW5lcignZGJsY2xpY2snLCB0aGlzLm9uRGJsQ2xpY2spO1xuXG4gICAgdGhpcy5zdWJzLmFkZCh0aGlzLnN0b3JlLmdldFJlZ2lvblVwZGF0ZUV2ZW50KCkuc3Vic2NyaWJlKCgpID0+IHRoaXMucmVkcmF3KCkpKTtcbiAgICB0aGlzLnN1YnMuYWRkKFxuICAgICAgdGhpcy5zdG9yZS5nZXRTZWxlY3RlZFNoYXBlSW5kaWNlcyQoKS5zdWJzY3JpYmUoKGlkeCkgPT4ge1xuICAgICAgICB0aGlzLnNlbGVjdGVkID0gaWR4ID8/IFtdO1xuICAgICAgICB0aGlzLnJlZHJhdygpO1xuICAgICAgfSksXG4gICAgKTtcbiAgICAvLyBBIGNhbWVyYSBtb3ZlIHJld3JpdGVzIHRoZSByZW5kZXJlcidzIHRyYW5zZm9ybSBhbmQgaXRzIGZldyBzY3JlZW4tc3BhY2UgZWxlbWVudHM7XG4gICAgLy8gdGhlIHJlZ2lvbnMgYXJlIGRyYXduIGluIHdvcmxkIGNvb3JkaW5hdGVzIGFuZCBhcmUgbm90IHJlYnVpbHQgKE5BUEFSSS1CT1VOREFSWS0xMCkuXG4gICAgdGhpcy5kaXNjb25uZWN0Q2FtZXJhID0gdGhpcy52aWV3ZXIuY2FtZXJhLmNoYW5nZWQuY29ubmVjdCgoKSA9PiB0aGlzLnVwZGF0ZUNhbWVyYSgpKTtcbiAgICB0aGlzLnJlZHJhdygpO1xuICB9XG5cbiAgLy8g4pSA4pSAIElSZWdpb25PdmVybGF5IOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvKipcbiAgICogV2hldGhlciBhIHJlZ2lvbiB0b29sIGN1cnJlbnRseSBvd25zIHRoZSBwb2ludGVyLlxuICAgKlxuICAgKiBFeHBvc2VkIHNvIHRoZSBzcGF0aWFsIHZpZXdzIGNhbiB0ZWxsIGEgYmFyZSBjbGljayBvbiB0aGUgY2xvdWQgKHNlbGVjdCB0aGVcbiAgICogY2xhc3MgdW5kZXIgdGhlIGN1cnNvcikgZnJvbSBhIGNsaWNrIHRoYXQgYmVsb25ncyB0byBhIGRyYXdpbmcgZ2VzdHVyZSDigJRcbiAgICogcGxhY2luZyBhIHBvbHlnb24gdmVydGV4IGlzIGFsc28gYSBjbGljayB0aGF0IGRvZXMgbm90IG1vdmUsIGFuZCBpdCBtdXN0IG5vdFxuICAgKiBjaGFuZ2UgdGhlIHNlbGVjdGlvbiBiZWhpbmQgdGhlIHNoYXBlIGJlaW5nIGRyYXduLlxuICAgKi9cbiAgZ2V0IHRvb2xBY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubW9kZSAhPT0gJ25vbmUnO1xuICB9XG5cbiAgc2V0TW9kZShtb2RlOiBSZWdpb25Ub29sTW9kZSk6IHZvaWQge1xuICAgIHRoaXMuZW5kR2VzdHVyZSgpO1xuICAgIHRoaXMubW9kZSA9IG1vZGU7XG4gICAgdGhpcy5kcmFmdFJlY3QgPSBudWxsO1xuICAgIHRoaXMuZHJhZnRQYXRoID0gbnVsbDtcbiAgICAvLyBUaGUgb3ZlcmxheSBvd25zIHBvaW50ZXIvbmF2aWdhdGlvbiBnYXRpbmc6IHdoaWxlIGEgdG9vbCBpcyBhY3RpdmUgaXQgY2FwdHVyZXMgdGhlIHBvaW50ZXJcbiAgICAvLyBhbmQgdGhlIG5hcGFyaSBjYW1lcmEgY29udHJvbHMgYXJlIGRpc2FibGVkOyAnbm9uZScgaGFuZHMgdGhlIHBvaW50ZXIgYmFjayBmb3IgcGFuL3pvb20uXG4gICAgY29uc3QgYWN0aXZlID0gbW9kZSAhPT0gJ25vbmUnO1xuICAgIHRoaXMudmlld2VyLnNldENvbnRyb2xzRW5hYmxlZCghYWN0aXZlKTtcbiAgICB0aGlzLnN2Zy5zdHlsZS5wb2ludGVyRXZlbnRzID0gYWN0aXZlID8gJ2F1dG8nIDogJ25vbmUnO1xuICAgIHRoaXMuc3ZnLnN0eWxlLmN1cnNvciA9IGFjdGl2ZSA/ICdjcm9zc2hhaXInIDogJ2RlZmF1bHQnO1xuICAgIHRoaXMucmVuZGVyT3ZlcmxheSgpO1xuICB9XG5cbiAgc2V0U2VsZWN0ZWRCZXppZXIoYmV6aWVyOiBib29sZWFuKTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFJlZ2lvbigpO1xuICAgIGlmIChzZWw/LmlkICE9IG51bGwpIHRoaXMuc3RvcmUuc2V0QmV6aWVyKHNlbC5pZCwgYmV6aWVyKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBIb3cgZmluZWx5IGEgZHJhd24gdmVydGV4IG1heSBiZSBwbGFjZWQsIGluIHdvcmxkIHVuaXRzOiBvbmUgKGFuIGltYWdlJ3MgcGl4ZWxzKSBieVxuICAgKiBkZWZhdWx0LCBmaW5lciBmb3IgYSBkYXRhc2V0IHdob3NlIGNvb3JkaW5hdGVzIGFyZSBub3QgcGl4ZWxzIChzZWUgT3ZlcmxheVByb2plY3Rpb24pLlxuICAgKi9cbiAgc2V0V29ybGRRdWFudHVtKHF1YW50dW06IG51bWJlcik6IHZvaWQge1xuICAgIHRoaXMucHJvamVjdGlvbi5zZXRXb3JsZFF1YW50dW0ocXVhbnR1bSk7XG4gIH1cblxuICBkZXN0cm95KCk6IHZvaWQge1xuICAgIHRoaXMuc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ3BvaW50ZXJkb3duJywgdGhpcy5vblBvaW50ZXJEb3duKTtcbiAgICB0aGlzLnN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdwb2ludGVybW92ZScsIHRoaXMub25Qb2ludGVyTW92ZSk7XG4gICAgdGhpcy5zdmcucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcnVwJywgdGhpcy5vblBvaW50ZXJVcCk7XG4gICAgdGhpcy5zdmcucmVtb3ZlRXZlbnRMaXN0ZW5lcigncG9pbnRlcmNhbmNlbCcsIHRoaXMub25Qb2ludGVyQ2FuY2VsKTtcbiAgICB0aGlzLnN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdsb3N0cG9pbnRlcmNhcHR1cmUnLCB0aGlzLm9uUG9pbnRlckNhbmNlbCk7XG4gICAgdGhpcy5zdmcucmVtb3ZlRXZlbnRMaXN0ZW5lcignZGJsY2xpY2snLCB0aGlzLm9uRGJsQ2xpY2spO1xuICAgIHRoaXMuZGlzY29ubmVjdENhbWVyYSgpO1xuICAgIHRoaXMuc3Vicy51bnN1YnNjcmliZSgpO1xuICAgIC8vIEEgZHJhZyB0b3JuIGRvd24gbWlkLWdlc3R1cmUgKGEgYmFja2VuZCBzd2l0Y2gpIG11c3Qgc3RpbGwgY2xvc2UgaXRzIHN0b3JlIGJhdGNoLlxuICAgIHRoaXMuZW5kR2VzdHVyZSgpO1xuICAgIGlmICh0aGlzLnN2Zy5wYXJlbnROb2RlKSB0aGlzLnN2Zy5wYXJlbnROb2RlLnJlbW92ZUNoaWxkKHRoaXMuc3ZnKTtcbiAgfVxuXG4gIC8vIOKUgOKUgCBwb2ludGVyIGhhbmRsZXJzIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICBwcml2YXRlIHJlYWRvbmx5IG9uUG9pbnRlckRvd24gPSAoZTogUG9pbnRlckV2ZW50KTogdm9pZCA9PiB7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ25vbmUnKSByZXR1cm47XG4gICAgZS5wcmV2ZW50RGVmYXVsdCgpO1xuICAgIHRoaXMucHJvamVjdGlvbi53aXRoT3JpZ2luKCgpID0+IHRoaXMucG9pbnRlckRvd24oZSkpO1xuICB9O1xuXG4gIHByaXZhdGUgcG9pbnRlckRvd24oZTogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgY29uc3QgW2l4LCBpeV0gPSB0aGlzLnByb2plY3Rpb24udG9JbWFnZShlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdyZWN0Jykge1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSB7IHgwOiBpeCwgeTA6IGl5LCB4MTogaXgsIHkxOiBpeSB9O1xuICAgICAgdGhpcy5kcmF3aW5nID0gdHJ1ZTtcbiAgICAgIHRoaXMuc3ZnLnNldFBvaW50ZXJDYXB0dXJlKGUucG9pbnRlcklkKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2RyYXdjbG9zZWRwYXRoJyB8fCB0aGlzLm1vZGUgPT09ICdkcmF3b3BlbnBhdGgnKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICB0aGlzLmRyYXdpbmcgPSB0cnVlO1xuICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5tb2RlID09PSAnZHJhd3BvbHlnb24nKSB7XG4gICAgICB0aGlzLmhhbmRsZVBvbHlnb25DbGljayhpeCwgaXksIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ3NlbGVjdCcgfHwgdGhpcy5tb2RlID09PSAnbW92ZScpIHtcbiAgICAgIHRoaXMuYmVnaW5NYW5pcHVsYXRpb24oaXgsIGl5LCBlKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2FkZHBvaW50Jykge1xuICAgICAgdGhpcy5oYW5kbGVBZGRQb2ludChpeCwgaXksIGUuY2xpZW50WCwgZS5jbGllbnRZKTtcbiAgICB9IGVsc2UgaWYgKHRoaXMubW9kZSA9PT0gJ2RlbGV0ZXBvaW50Jykge1xuICAgICAgdGhpcy5oYW5kbGVEZWxldGVQb2ludChpeCwgaXkpO1xuICAgIH1cbiAgICB0aGlzLnJlZHJhdygpO1xuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJNb3ZlID0gKGU6IFBvaW50ZXJFdmVudCk6IHZvaWQgPT4ge1xuICAgIGNvbnN0IFtpeCwgaXldID0gdGhpcy5wcm9qZWN0aW9uLnRvSW1hZ2UoZS5jbGllbnRYLCBlLmNsaWVudFkpO1xuICAgIGlmICh0aGlzLm1hcnF1ZWUpIHtcbiAgICAgIHRoaXMubWFycXVlZS54MSA9IGl4O1xuICAgICAgdGhpcy5tYXJxdWVlLnkxID0gaXk7XG4gICAgICB0aGlzLnVwZGF0ZU1hcnF1ZWVFbCgpOyAvLyB1cGRhdGUganVzdCB0aGUgbWFycXVlZSByZWN0IOKAlCBOT1QgYSBmdWxsIHJlZ2lvbiByZWRyYXdcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgaWYgKHRoaXMuZWRpdCkge1xuICAgICAgYXBwbHlSZWdpb25FZGl0KHRoaXMuc3RvcmUsIHRoaXMuZWRpdCwgaXgsIGl5KTtcbiAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5kcmF3aW5nKSByZXR1cm47XG4gICAgaWYgKHRoaXMuZHJhZnRSZWN0KSB7XG4gICAgICB0aGlzLmRyYWZ0UmVjdC54MSA9IGl4O1xuICAgICAgdGhpcy5kcmFmdFJlY3QueTEgPSBpeTtcbiAgICB9IGVsc2UgaWYgKHRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICBjb25zdCBzdGVwID0gRlJFRUhBTkRfU1RFUF9QWCAqIHRoaXMucHJvamVjdGlvbi53b3JsZFBlckNhbnZhc1BpeGVsKCk7XG4gICAgICBjb25zdCBsYXN0ID0gdGhpcy5kcmFmdFBhdGhbdGhpcy5kcmFmdFBhdGgubGVuZ3RoIC0gMV07XG4gICAgICBpZiAoTWF0aC5hYnMoaXggLSBsYXN0WzBdKSA+PSBzdGVwIHx8IE1hdGguYWJzKGl5IC0gbGFzdFsxXSkgPj0gc3RlcCkge1xuICAgICAgICB0aGlzLmRyYWZ0UGF0aC5wdXNoKFtpeCwgaXldKTtcbiAgICAgIH1cbiAgICB9XG4gICAgdGhpcy5yZW5kZXJPdmVybGF5KCk7XG4gIH07XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvblBvaW50ZXJVcCA9IChlOiBQb2ludGVyRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tYXJxdWVlKSB7XG4gICAgICBjb25zdCBtID0gdGhpcy5tYXJxdWVlO1xuICAgICAgdGhpcy5tYXJxdWVlID0gbnVsbDtcbiAgICAgIHRoaXMucmVuZGVyZXIuY2xlYXJNYXJxdWVlKCk7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLnN2Zy5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGFscmVhZHkgcmVsZWFzZWQgKi9cbiAgICAgIH1cbiAgICAgIHRoaXMuZmluaXNoTWFycXVlZShtKTsgLy8gc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMg4oaSIG9uZSByZWRyYXcgdmlhIHRoZSBzZWxlY3Rpb24gc3Vic2NyaXB0aW9uXG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICh0aGlzLmVkaXQpIHtcbiAgICAgIHRoaXMuc3RvcmUuZW5kQmF0Y2goKTtcbiAgICAgIHRoaXMuZWRpdCA9IG51bGw7XG4gICAgICB0cnkge1xuICAgICAgICB0aGlzLnN2Zy5yZWxlYXNlUG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgfSBjYXRjaCB7XG4gICAgICAgIC8qIGFscmVhZHkgcmVsZWFzZWQgKi9cbiAgICAgIH1cbiAgICAgIHRoaXMucmVkcmF3KCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGlmICghdGhpcy5kcmF3aW5nKSByZXR1cm47XG4gICAgdGhpcy5kcmF3aW5nID0gZmFsc2U7XG4gICAgdHJ5IHtcbiAgICAgIHRoaXMuc3ZnLnJlbGVhc2VQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgfSBjYXRjaCB7XG4gICAgICAvKiBjYXB0dXJlIG1heSBhbHJlYWR5IGJlIHJlbGVhc2VkICovXG4gICAgfVxuICAgIGlmICh0aGlzLmRyYWZ0UmVjdCkge1xuICAgICAgY29uc3QgeyB4MCwgeTAsIHgxLCB5MSB9ID0gdGhpcy5kcmFmdFJlY3Q7XG4gICAgICBjb25zdCB4ID0gTWF0aC5taW4oeDAsIHgxKTtcbiAgICAgIGNvbnN0IHkgPSBNYXRoLm1pbih5MCwgeTEpO1xuICAgICAgY29uc3QgdyA9IE1hdGguYWJzKHgxIC0geDApO1xuICAgICAgY29uc3QgaCA9IE1hdGguYWJzKHkxIC0geTApO1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSBudWxsO1xuICAgICAgY29uc3QgbWluID0gTUlOX1JFQ1RfRFJBR19QWCAqIHRoaXMucHJvamVjdGlvbi53b3JsZFBlckNhbnZhc1BpeGVsKCk7XG4gICAgICBpZiAodyA+PSBtaW4gJiYgaCA+PSBtaW4pIHRoaXMuY29tbWl0UmVjdGFuZ2xlKHgsIHksIHcsIGgpO1xuICAgIH0gZWxzZSBpZiAodGhpcy5kcmFmdFBhdGgpIHtcbiAgICAgIGNvbnN0IHB0cyA9IHRoaXMuZHJhZnRQYXRoO1xuICAgICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgICAgY29uc3QgY2xvc2VkID0gdGhpcy5tb2RlID09PSAnZHJhd2Nsb3NlZHBhdGgnO1xuICAgICAgaWYgKHB0cy5sZW5ndGggPj0gKGNsb3NlZCA/IDMgOiAyKSkgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgY2xvc2VkKTtcbiAgICB9XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKipcbiAgICogVGhlIHBvaW50ZXIgZ2VzdHVyZSBlbmRlZCB3aXRob3V0IGEgcG9pbnRlcnVwICh0aGUgYnJvd3NlciBjYW5jZWxsZWQgaXQsIG9yIGNhcHR1cmUgd2FzXG4gICAqIGxvc3QpOiBlbmQgaXQgd2l0aG91dCBjb21taXR0aW5nLiBBbHNvIGZpcmVzIGFmdGVyIGV2ZXJ5IG5vcm1hbCByZWxlYXNlLCB3aGVuIG5vdGhpbmdcbiAgICogaXMgbGl2ZSBhbnkgbW9yZS5cbiAgICovXG4gIHByaXZhdGUgcmVhZG9ubHkgb25Qb2ludGVyQ2FuY2VsID0gKCk6IHZvaWQgPT4ge1xuICAgIGlmICghdGhpcy5lZGl0ICYmICF0aGlzLmRyYXdpbmcgJiYgIXRoaXMubWFycXVlZSkgcmV0dXJuO1xuICAgIHRoaXMuZW5kR2VzdHVyZSgpO1xuICAgIHRoaXMucmVkcmF3KCk7XG4gIH07XG5cbiAgLyoqXG4gICAqIEVuZCB3aGF0ZXZlciBwb2ludGVyIGdlc3R1cmUgaXMgbGl2ZSB3aXRob3V0IGNvbW1pdHRpbmcgaXQ6IGNsb3NlIHRoZSBzdG9yZSBiYXRjaCBhIGRyYWdcbiAgICogb3BlbmVkIChzbyBsYXRlciBlZGl0cyBhcmUgZW1pdHRlZCBhZ2FpbikgYW5kIGZvcmdldCB0aGUgZHJhZyAoc28gYSBiYXJlIGhvdmVyIG5vIGxvbmdlclxuICAgKiBtb3ZlcyB0aGUgcmVnaW9uKSwgYW5kIGRyb3AgdGhlIG1hcnF1ZWUgYW5kIGEgcmVjdGFuZ2xlL2ZyZWVoYW5kIGRyYWZ0LiBBIGNsaWNrLXBsYWNlZFxuICAgKiBwb2x5Z29uIGlzIG5vdCBhIHBvaW50ZXIgZ2VzdHVyZSBhbmQgc3Vydml2ZXMuXG4gICAqL1xuICBwcml2YXRlIGVuZEdlc3R1cmUoKTogdm9pZCB7XG4gICAgaWYgKHRoaXMuZWRpdCkgdGhpcy5zdG9yZS5lbmRCYXRjaCgpO1xuICAgIHRoaXMuZWRpdCA9IG51bGw7XG4gICAgaWYgKHRoaXMuZHJhd2luZykge1xuICAgICAgdGhpcy5kcmFmdFJlY3QgPSBudWxsO1xuICAgICAgdGhpcy5kcmFmdFBhdGggPSBudWxsO1xuICAgIH1cbiAgICB0aGlzLmRyYXdpbmcgPSBmYWxzZTtcbiAgICB0aGlzLm1hcnF1ZWUgPSBudWxsO1xuICAgIHRoaXMucmVuZGVyZXIuY2xlYXJNYXJxdWVlKCk7XG4gIH1cblxuICAvKiogQ2xpY2stdG8tcGxhY2UgcG9seWdvbjogYWRkIGEgdmVydGV4LCBvciBjbG9zZSB3aGVuIGNsaWNraW5nIG5lYXIgdGhlIGZpcnN0IG9uZS4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVQb2x5Z29uQ2xpY2soaXg6IG51bWJlciwgaXk6IG51bWJlciwgY2xpZW50WDogbnVtYmVyLCBjbGllbnRZOiBudW1iZXIpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuZHJhZnRQYXRoKSB7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IFtbaXgsIGl5XV07XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5lYXIgPVxuICAgICAgdGhpcy5wcm9qZWN0aW9uLnNjcmVlbkRpc3QoY2xpZW50WCwgY2xpZW50WSwgdGhpcy5kcmFmdFBhdGhbMF1bMF0sIHRoaXMuZHJhZnRQYXRoWzBdWzFdKSA8PSBDTE9TRV9TTkFQX1BYICYmXG4gICAgICB0aGlzLmRyYWZ0UGF0aC5sZW5ndGggPj0gMztcbiAgICBpZiAobmVhcikge1xuICAgICAgY29uc3QgcHRzID0gdGhpcy5kcmFmdFBhdGg7XG4gICAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgICB0aGlzLmNvbW1pdFBvbHlnb24ocHRzLCB0cnVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5kcmFmdFBhdGgucHVzaChbaXgsIGl5XSk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSByZWFkb25seSBvbkRibENsaWNrID0gKGU6IE1vdXNlRXZlbnQpOiB2b2lkID0+IHtcbiAgICBpZiAodGhpcy5tb2RlICE9PSAnZHJhd3BvbHlnb24nIHx8ICF0aGlzLmRyYWZ0UGF0aCkgcmV0dXJuO1xuICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICBjb25zdCBwdHMgPSB0aGlzLmRyYWZ0UGF0aDtcbiAgICB0aGlzLmRyYWZ0UGF0aCA9IG51bGw7XG4gICAgaWYgKHB0cy5sZW5ndGggPj0gMykgdGhpcy5jb21taXRQb2x5Z29uKHB0cywgdHJ1ZSk7XG4gICAgdGhpcy5yZWRyYXcoKTtcbiAgfTtcblxuICAvKiogVGhlIGN1cnJlbnRseS1zZWxlY3RlZCByZWdpb24gKHNpbmdsZSBzZWxlY3Rpb24pLCBvciBudWxsLiAqL1xuICBwcml2YXRlIHNlbGVjdGVkUmVnaW9uKCk6IFJlZ2lvbiB8IG51bGwge1xuICAgIGNvbnN0IHJlZ2lvbnMgPSB0aGlzLnN0b3JlLmdldFJlZ2lvbnMoKTtcbiAgICBjb25zdCBpID0gdGhpcy5zZWxlY3RlZFswXTtcbiAgICByZXR1cm4gaSAhPSBudWxsICYmIGkgPj0gMCAmJiBpIDwgcmVnaW9ucy5sZW5ndGggPyByZWdpb25zW2ldIDogbnVsbDtcbiAgfVxuXG4gIC8qKlxuICAgKiBTdGFydCBhIHNlbGVjdC9tb3ZlIGludGVyYWN0aW9uOiBncmFiIGEgaGFuZGxlIChyZWN0YW5nbGUgY29ybmVyKSBvciB2ZXJ0ZXggb2YgdGhlIGFscmVhZHktXG4gICAqIHNlbGVjdGVkIHJlZ2lvbiBmaXJzdDsgb3RoZXJ3aXNlIHNlbGVjdCB0aGUgdG9wbW9zdCByZWdpb24gdW5kZXIgdGhlIGN1cnNvciBhbmQgZHJhZyBpdHMgYm9keS5cbiAgICovXG4gIHByaXZhdGUgYmVnaW5NYW5pcHVsYXRpb24oaXg6IG51bWJlciwgaXk6IG51bWJlciwgZTogUG9pbnRlckV2ZW50KTogdm9pZCB7XG4gICAgY29uc3Qgc2VsID0gdGhpcy5zZWxlY3RlZFJlZ2lvbigpO1xuICAgIGlmIChzZWw/LmJvdW5kcykge1xuICAgICAgY29uc3QgW2x4LCBseV0gPSB0aGlzLnByb2plY3Rpb24uY2xpZW50VG9Mb2NhbChlLmNsaWVudFgsIGUuY2xpZW50WSk7XG4gICAgICBjb25zdCBncmFiID0gaGl0SGFuZGxlKHNlbCwgbHgsIGx5LCB0aGlzLnByb2plY3Rpb24udG9TY3JlZW4sIEhBTkRMRV9ISVRfUFgpO1xuICAgICAgaWYgKGdyYWIpIHtcbiAgICAgICAgdGhpcy5zdG9yZS5iZWdpbkJhdGNoKCk7XG4gICAgICAgIHRoaXMuZWRpdCA9IHsgLi4uZ3JhYiwgaWQ6IHNlbC5pZCwgbGFzdDogW2l4LCBpeV0gfTtcbiAgICAgICAgdGhpcy5zdmcuc2V0UG9pbnRlckNhcHR1cmUoZS5wb2ludGVySWQpO1xuICAgICAgICByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICAgIC8vIEhpdC10ZXN0IGJvZGllcywgdG9wbW9zdCBmaXJzdCAobGFzdCBkcmF3biByZW5kZXJzIG9uIHRvcCksIGF0IHRoZSBleGFjdCBwb2ludGVyXG4gICAgLy8gcG9zaXRpb24g4oCUIHNuYXBwaW5nIGlzIGZvciBwbGFjaW5nIHZlcnRpY2VzLCBub3QgZm9yIHBpY2tpbmcuXG4gICAgY29uc3QgcmVnaW9ucyA9IHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpO1xuICAgIGNvbnN0IFt3eCwgd3ldID0gdGhpcy5wcm9qZWN0aW9uLnRvV29ybGQoZS5jbGllbnRYLCBlLmNsaWVudFkpO1xuICAgIGZvciAobGV0IGkgPSByZWdpb25zLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICBpZiAocmVnaW9uQ29udGFpbnMocmVnaW9uc1tpXSwgd3gsIHd5LCB7IHRvU2NyZWVuOiB0aGlzLnByb2plY3Rpb24udG9TY3JlZW4sIHRvbFB4OiBPUEVOX1BBVEhfSElUX1BYIH0pKSB7XG4gICAgICAgIHRoaXMuc3RvcmUuc2VsZWN0UmVnaW9uKHJlZ2lvbnNbaV0pO1xuICAgICAgICB0aGlzLnN0b3JlLmJlZ2luQmF0Y2goKTtcbiAgICAgICAgdGhpcy5lZGl0ID0geyBraW5kOiAnYm9keScsIGlkOiByZWdpb25zW2ldLmlkLCBsYXN0OiBbaXgsIGl5XSB9O1xuICAgICAgICB0aGlzLnN2Zy5zZXRQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gRW1wdHkgc3BhY2U6IGluIHNlbGVjdCBtb2RlIHN0YXJ0IGEgcnViYmVyLWJhbmQgbWFycXVlZSAoc2VsZWN0cyB0aGUgcmVnaW9ucyBpdCBjb3ZlcnMgb25cbiAgICAvLyByZWxlYXNlKTsgaW4gbW92ZSBtb2RlIGp1c3QgY2xlYXIgdGhlIHNlbGVjdGlvbi5cbiAgICBpZiAodGhpcy5tb2RlID09PSAnc2VsZWN0Jykge1xuICAgICAgdGhpcy5tYXJxdWVlID0geyB4MDogaXgsIHkwOiBpeSwgeDE6IGl4LCB5MTogaXkgfTtcbiAgICAgIHRoaXMudXBkYXRlTWFycXVlZUVsKCk7XG4gICAgICB0aGlzLnN2Zy5zZXRQb2ludGVyQ2FwdHVyZShlLnBvaW50ZXJJZCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc3RvcmUuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMoW10pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBTaG93IHRoZSBtYXJxdWVlIHdoZXJlIGl0IGlzIG5vdyAob25seSB0aGUgbWFycXVlZSBlbGVtZW50OiBubyBmdWxsIHJlZ2lvbiByZWRyYXcpLiAqL1xuICBwcml2YXRlIHVwZGF0ZU1hcnF1ZWVFbCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMubWFycXVlZSkgcmV0dXJuO1xuICAgIGNvbnN0IHsgeDAsIHkwLCB4MSwgeTEgfSA9IHRoaXMubWFycXVlZTtcbiAgICBjb25zdCBbbHgsIGx5XSA9IHRoaXMucHJvamVjdGlvbi50b0xvY2FsKE1hdGgubWluKHgwLCB4MSksIE1hdGgubWluKHkwLCB5MSkpO1xuICAgIGNvbnN0IFtyeCwgcnldID0gdGhpcy5wcm9qZWN0aW9uLnRvTG9jYWwoTWF0aC5tYXgoeDAsIHgxKSwgTWF0aC5tYXgoeTAsIHkxKSk7XG4gICAgdGhpcy5yZW5kZXJlci5zaG93TWFycXVlZShseCwgbHksIHJ4LCByeSk7XG4gIH1cblxuICAvKiogYWRkcG9pbnQgbW9kZTogaW5zZXJ0IGEgdmVydGV4IGF0IHRoZSBjbGljayBvbiB0aGUgc2VsZWN0ZWQgcG9seWdvbidzIG5lYXJlc3QgZWRnZVxuICAgKiAgKGV4dGVyaW9yIG9yIGEgaG9sZSByaW5nKS4gKi9cbiAgcHJpdmF0ZSBoYW5kbGVBZGRQb2ludChpeDogbnVtYmVyLCBpeTogbnVtYmVyLCBjbGllbnRYOiBudW1iZXIsIGNsaWVudFk6IG51bWJlcik6IHZvaWQge1xuICAgIGNvbnN0IHNlbCA9IHRoaXMuc2VsZWN0ZWRSZWdpb24oKTtcbiAgICBpZiAoIXNlbCkgcmV0dXJuO1xuICAgIGNvbnN0IFtseCwgbHldID0gdGhpcy5wcm9qZWN0aW9uLmNsaWVudFRvTG9jYWwoY2xpZW50WCwgY2xpZW50WSk7XG4gICAgY29uc3QgZWRnZSA9IG5lYXJlc3RFZGdlKHNlbCwgbHgsIGx5LCB0aGlzLnByb2plY3Rpb24udG9TY3JlZW4pO1xuICAgIGlmICghZWRnZSkgcmV0dXJuO1xuICAgIGlmIChlZGdlLnJpbmcgPCAwKSB0aGlzLnN0b3JlLmFkZFZlcnRleChzZWwuaWQsIGVkZ2Uuc2VnSW5kZXgsIGl4LCBpeSk7XG4gICAgZWxzZSB0aGlzLnN0b3JlLmFkZEhvbGVWZXJ0ZXgoc2VsLmlkLCBlZGdlLnJpbmcsIGVkZ2Uuc2VnSW5kZXgsIGl4LCBpeSk7XG4gIH1cblxuICAvKiogZGVsZXRlcG9pbnQgbW9kZTogcmVtb3ZlIHRoZSBzZWxlY3RlZCBwb2x5Z29uJ3MgdmVydGV4IG5lYXJlc3QgdGhlIGNsaWNrIChleHRlcmlvciBvciBhXG4gICAqICBob2xlIHJpbmcpLiAqL1xuICBwcml2YXRlIGhhbmRsZURlbGV0ZVBvaW50KGl4OiBudW1iZXIsIGl5OiBudW1iZXIpOiB2b2lkIHtcbiAgICBjb25zdCBzZWwgPSB0aGlzLnNlbGVjdGVkUmVnaW9uKCk7XG4gICAgaWYgKCFzZWwpIHJldHVybjtcbiAgICBjb25zdCB2ID0gbmVhcmVzdFZlcnRleChzZWwsIGl4LCBpeSk7XG4gICAgaWYgKCF2KSByZXR1cm47XG4gICAgaWYgKHYucmluZyA8IDApIHRoaXMuc3RvcmUuZGVsZXRlVmVydGV4KHNlbC5pZCwgdi5pbmRleCk7XG4gICAgZWxzZSB0aGlzLnN0b3JlLmRlbGV0ZUhvbGVWZXJ0ZXgoc2VsLmlkLCB2LnJpbmcsIHYuaW5kZXgpO1xuICB9XG5cbiAgLyoqIEZpbmFsaXplIGEgcnViYmVyLWJhbmQgbWFycXVlZTogc2VsZWN0IGV2ZXJ5IHJlZ2lvbiB3aG9zZSBib3VuZGluZyBib3ggaXQgb3ZlcmxhcHMgKGFcbiAgICogIG1hcnF1ZWUgdW5kZXIge0BsaW5rIE1JTl9NQVJRVUVFX1BYfSBpcyBhIGNsaWNrIG9uIGVtcHR5IHNwYWNlIOKGkiBjbGVhciB0aGUgc2VsZWN0aW9uKS4gKi9cbiAgcHJpdmF0ZSBmaW5pc2hNYXJxdWVlKG06IERyYWdCb3gpOiB2b2lkIHtcbiAgICBjb25zdCB4MCA9IE1hdGgubWluKG0ueDAsIG0ueDEpO1xuICAgIGNvbnN0IHgxID0gTWF0aC5tYXgobS54MCwgbS54MSk7XG4gICAgY29uc3QgeTAgPSBNYXRoLm1pbihtLnkwLCBtLnkxKTtcbiAgICBjb25zdCB5MSA9IE1hdGgubWF4KG0ueTAsIG0ueTEpO1xuICAgIGNvbnN0IG1pbiA9IE1JTl9NQVJRVUVFX1BYICogdGhpcy5wcm9qZWN0aW9uLndvcmxkUGVyQ2FudmFzUGl4ZWwoKTtcbiAgICBpZiAoeDEgLSB4MCA8IG1pbiAmJiB5MSAtIHkwIDwgbWluKSB7XG4gICAgICB0aGlzLnN0b3JlLnNldFNlbGVjdGVkU2hhcGVJbmRpY2VzKFtdKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcmVnaW9ucyA9IHRoaXMuc3RvcmUuZ2V0UmVnaW9ucygpO1xuICAgIHRoaXMuc3RvcmUuc2V0U2VsZWN0ZWRTaGFwZUluZGljZXMocmVnaW9uc0luUmVjdChyZWdpb25zLCB4MCwgeTAsIHgxLCB5MSwgeyBza2lwUHJvZmlsZXM6IHRydWUgfSkpO1xuICB9XG5cbiAgLy8g4pSA4pSAIHNoYXBlIGNvbW1pdCDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIDilIBcbiAgcHJpdmF0ZSBjb21taXRSZWN0YW5nbGUoeDogbnVtYmVyLCB5OiBudW1iZXIsIHdpZHRoOiBudW1iZXIsIGhlaWdodDogbnVtYmVyKTogdm9pZCB7XG4gICAgY29uc3QgcmVjdCA9IG5ldyBSZWN0YW5nbGUoKTtcbiAgICByZWN0LnggPSB4O1xuICAgIHJlY3QueSA9IHk7XG4gICAgcmVjdC53aWR0aCA9IHdpZHRoO1xuICAgIHJlY3QuaGVpZ2h0ID0gaGVpZ2h0O1xuICAgIGNvbnN0IHJlZ2lvbiA9IG5ldyBSZWdpb24oKTtcbiAgICByZWdpb24uYm91bmRzID0gcmVjdDtcbiAgICByZWdpb24uY29sb3IgPSB0aGlzLnN0b3JlLmdldFNoYXBlQ29sb3IoKTtcbiAgICB0aGlzLnN0b3JlLmFkZFJlZ2lvbihyZWdpb24pO1xuICB9XG5cbiAgcHJpdmF0ZSBjb21taXRQb2x5Z29uKHBvaW50czogQXJyYXk8W251bWJlciwgbnVtYmVyXT4sIGNsb3NlZDogYm9vbGVhbik6IHZvaWQge1xuICAgIGNvbnN0IHBvbHkgPSBuZXcgUG9seWdvbigpO1xuICAgIHBvbHkubnBvaW50cyA9IHBvaW50cy5sZW5ndGg7XG4gICAgcG9seS54cG9pbnRzID0gcG9pbnRzLm1hcCgocCkgPT4gcFswXSk7XG4gICAgcG9seS55cG9pbnRzID0gcG9pbnRzLm1hcCgocCkgPT4gcFsxXSk7XG4gICAgcG9seS5jb29yZGluYXRlcyA9IHBvaW50cy5tYXAoKHApID0+IFtwWzBdLCBwWzFdXSk7XG4gICAgcG9seS5jbG9zZWQgPSBjbG9zZWQ7XG4gICAgY29uc3QgcmVnaW9uID0gbmV3IFJlZ2lvbigpO1xuICAgIHJlZ2lvbi5ib3VuZHMgPSBwb2x5O1xuICAgIHJlZ2lvbi5jb2xvciA9IHRoaXMuc3RvcmUuZ2V0U2hhcGVDb2xvcigpO1xuICAgIHJlZ2lvbi5sYWJlbCA9ICdSZWdpb24nO1xuICAgIHRoaXMuc3RvcmUuYWRkUmVnaW9uKHJlZ2lvbik7XG4gIH1cblxuICAvLyDilIDilIAgcmVuZGVyaW5nIOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgOKUgFxuICAvKiogU2hvdyBvciBoaWRlIHRoZSBkcmF3biByZWdpb25zLiBBIHJlZ2lvbiBiZWluZyBkcmF3biBzdGF5cyB2aXNpYmxlIGVpdGhlciB3YXkuICovXG4gIHNldFJlZ2lvbnNWaXNpYmxlKHZpc2libGU6IGJvb2xlYW4pOiB2b2lkIHtcbiAgICBpZiAodmlzaWJsZSA9PT0gdGhpcy5yZWdpb25zVmlzaWJsZSkgcmV0dXJuO1xuICAgIHRoaXMucmVnaW9uc1Zpc2libGUgPSB2aXNpYmxlO1xuICAgIHRoaXMucmVkcmF3KCk7XG4gIH1cblxuICAvKiogRm9sbG93IGEgY2FtZXJhIG1vdmU6IG9uZSB0cmFuc2Zvcm0gYXR0cmlidXRlIHBsdXMgdGhlIHNjcmVlbi1zcGFjZSBlbGVtZW50cy4gKi9cbiAgcHJpdmF0ZSB1cGRhdGVDYW1lcmEoKTogdm9pZCB7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRDYW1lcmEodGhpcy5wcm9qZWN0aW9uLmFmZmluZSgpKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZWJ1aWxkIGV2ZXJ5IGVsZW1lbnQgZnJvbSB0aGUgc3RvcmU6IHRoZSByZWdpb25zIGluIHdvcmxkIGNvb3JkaW5hdGVzIChvbmUgdHJhbnNmb3JtZWRcbiAgICogZ3JvdXApLCB0aGVpciBsYWJlbHMsIGFuZCB0aGUgb3ZlcmxheS4gUmVhZHMgbm8gbGF5b3V0OiB0aGUgY2FtZXJhIGFmZmluZSBpcyB0aGUgdmlld2VyJ3MuXG4gICAqL1xuICByZWRyYXcoKTogdm9pZCB7XG4gICAgdGhpcy5yZW5kZXJlci5zZXRDYW1lcmEodGhpcy5wcm9qZWN0aW9uLmFmZmluZSgpKTtcbiAgICB0aGlzLnJlbmRlcmVyLnJlbmRlcih0aGlzLnJlZ2lvbnNWaXNpYmxlID8gdGhpcy5zdG9yZS5nZXRSZWdpb25zKCkgOiBbXSwgdGhpcy5zZWxlY3RlZCk7XG4gICAgdGhpcy5yZW5kZXJPdmVybGF5KCk7XG4gIH1cblxuICAvKiogUmVidWlsZCB0aGUgc2NyZWVuLXNwYWNlIG92ZXJsYXkgb25seTogdGhlIHNlbGVjdGVkIHJlZ2lvbnMnIGhhbmRsZXMgYW5kIHRoZSBkcmFmdC4gKi9cbiAgcHJpdmF0ZSByZW5kZXJPdmVybGF5KCk6IHZvaWQge1xuICAgIHRoaXMucmVuZGVyZXIucmVuZGVyT3ZlcmxheSh0aGlzLnJlZ2lvbnNWaXNpYmxlID8gdGhpcy5zdG9yZS5nZXRSZWdpb25zKCkgOiBbXSwgdGhpcy5zZWxlY3RlZCwge1xuICAgICAgcmVjdDogdGhpcy5kcmFmdFJlY3QsXG4gICAgICBwYXRoOiB0aGlzLmRyYWZ0UGF0aCxcbiAgICB9KTtcbiAgfVxufVxuIl19