react-msaview 9.1.0 → 9.2.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 (278) hide show
  1. package/bundle/index.js +111 -115
  2. package/bundle/index.js.map +4 -4
  3. package/dist/blosum62.d.ts +3 -0
  4. package/dist/blosum62.js +43 -0
  5. package/dist/blosum62.js.map +1 -0
  6. package/dist/colorSchemes.js +1 -0
  7. package/dist/colorSchemes.js.map +1 -1
  8. package/dist/components/Loading.d.ts +3 -2
  9. package/dist/components/Loading.js +2 -2
  10. package/dist/components/Loading.js.map +1 -1
  11. package/dist/components/MSAView.d.ts +3 -2
  12. package/dist/components/MSAView.js +7 -4
  13. package/dist/components/MSAView.js.map +1 -1
  14. package/dist/components/MSAViewer.d.ts +64 -12
  15. package/dist/components/MetadataTable.d.ts +4 -1
  16. package/dist/components/MetadataTable.js +55 -16
  17. package/dist/components/MetadataTable.js.map +1 -1
  18. package/dist/components/Track.js +6 -0
  19. package/dist/components/Track.js.map +1 -1
  20. package/dist/components/controls.js +2 -1
  21. package/dist/components/controls.js.map +1 -1
  22. package/dist/components/dialogs/AnnotationFileDialog.js +7 -2
  23. package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -1
  24. package/dist/components/dialogs/FeatureDialog.js +2 -2
  25. package/dist/components/dialogs/FeatureDialog.js.map +1 -1
  26. package/dist/components/{header/MSASettingsMenu.d.ts → dialogs/GapThresholdDialog.d.ts} +3 -2
  27. package/dist/components/dialogs/GapThresholdDialog.js +15 -0
  28. package/dist/components/dialogs/GapThresholdDialog.js.map +1 -0
  29. package/dist/components/{header → dialogs}/GappynessSlider.d.ts +1 -1
  30. package/dist/components/{header → dialogs}/GappynessSlider.js +3 -10
  31. package/dist/components/dialogs/GappynessSlider.js.map +1 -0
  32. package/dist/components/{header → dialogs}/GoToBox.d.ts +4 -2
  33. package/dist/components/dialogs/GoToBox.js +48 -0
  34. package/dist/components/dialogs/GoToBox.js.map +1 -0
  35. package/dist/components/dialogs/GoToDialog.d.ts +6 -0
  36. package/dist/components/dialogs/GoToDialog.js +10 -0
  37. package/dist/components/dialogs/GoToDialog.js.map +1 -0
  38. package/dist/components/dialogs/MetadataDialog.js +11 -3
  39. package/dist/components/dialogs/MetadataDialog.js.map +1 -1
  40. package/dist/components/dialogs/goTo.d.ts +5 -0
  41. package/dist/components/{header → dialogs}/goTo.js +1 -1
  42. package/dist/components/dialogs/goTo.js.map +1 -0
  43. package/dist/components/dialogs/metadataLabels.d.ts +4 -0
  44. package/dist/components/dialogs/metadataLabels.js +52 -0
  45. package/dist/components/dialogs/metadataLabels.js.map +1 -0
  46. package/dist/components/dialogs/metadataRecord.d.ts +1 -0
  47. package/dist/components/dialogs/metadataRecord.js +38 -0
  48. package/dist/components/dialogs/metadataRecord.js.map +1 -0
  49. package/dist/components/header/Header.d.ts +6 -2
  50. package/dist/components/header/Header.js +30 -32
  51. package/dist/components/header/Header.js.map +1 -1
  52. package/dist/components/header/{TreeSettingsMenu.d.ts → HiddenColumnsChip.d.ts} +2 -2
  53. package/dist/components/header/HiddenColumnsChip.js +15 -0
  54. package/dist/components/header/HiddenColumnsChip.js.map +1 -0
  55. package/dist/components/header/MenuBar.d.ts +6 -0
  56. package/dist/components/header/MenuBar.js +33 -0
  57. package/dist/components/header/MenuBar.js.map +1 -0
  58. package/dist/components/header/ScrollZoomCheckbox.d.ts +7 -0
  59. package/dist/components/header/ScrollZoomCheckbox.js +19 -0
  60. package/dist/components/header/ScrollZoomCheckbox.js.map +1 -0
  61. package/dist/components/header/ZoomControls.js +10 -30
  62. package/dist/components/header/ZoomControls.js.map +1 -1
  63. package/dist/components/header/colorSchemeMenuItems.d.ts +4 -0
  64. package/dist/components/header/colorSchemeMenuItems.js +106 -0
  65. package/dist/components/header/colorSchemeMenuItems.js.map +1 -0
  66. package/dist/components/header/getAnnotationsMenu.d.ts +3 -30
  67. package/dist/components/header/getAnnotationsMenu.js +48 -54
  68. package/dist/components/header/getAnnotationsMenu.js.map +1 -1
  69. package/dist/components/header/menuBarItems.d.ts +11 -0
  70. package/dist/components/header/menuBarItems.js +277 -0
  71. package/dist/components/header/menuBarItems.js.map +1 -0
  72. package/dist/components/import/ImportForm.js +12 -6
  73. package/dist/components/import/ImportForm.js.map +1 -1
  74. package/dist/components/minimap/Minimap.js +7 -3
  75. package/dist/components/minimap/Minimap.js.map +1 -1
  76. package/dist/components/minimap/MinimapSVG.js +2 -1
  77. package/dist/components/minimap/MinimapSVG.js.map +1 -1
  78. package/dist/components/minimap/minimapLayout.d.ts +12 -0
  79. package/dist/components/minimap/minimapLayout.js +20 -0
  80. package/dist/components/minimap/minimapLayout.js.map +1 -1
  81. package/dist/components/msa/MSACanvas.js +26 -9
  82. package/dist/components/msa/MSACanvas.js.map +1 -1
  83. package/dist/components/msa/MSACanvasBlock.js +15 -11
  84. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  85. package/dist/components/msa/MSAMouseoverCanvas.js +2 -2
  86. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  87. package/dist/components/msa/WheelZoomHint.d.ts +7 -0
  88. package/dist/components/msa/WheelZoomHint.js +38 -0
  89. package/dist/components/msa/WheelZoomHint.js.map +1 -0
  90. package/dist/components/msa/msaKeys.js +3 -0
  91. package/dist/components/msa/msaKeys.js.map +1 -1
  92. package/dist/components/msa/msaRaster.d.ts +4 -5
  93. package/dist/components/msa/msaRaster.js +5 -5
  94. package/dist/components/msa/msaRaster.js.map +1 -1
  95. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +22 -2
  96. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  97. package/dist/components/msa/renderHighlights.d.ts +0 -3
  98. package/dist/components/msa/renderHighlights.js +3 -3
  99. package/dist/components/msa/renderHighlights.js.map +1 -1
  100. package/dist/components/msa/renderMSABlock.d.ts +6 -1
  101. package/dist/components/msa/renderMSABlock.js +44 -17
  102. package/dist/components/msa/renderMSABlock.js.map +1 -1
  103. package/dist/components/msa/tileColor.js +7 -0
  104. package/dist/components/msa/tileColor.js.map +1 -1
  105. package/dist/components/rowpanels/RowPanelBlock.js +2 -2
  106. package/dist/components/rowpanels/RowPanelBlock.js.map +1 -1
  107. package/dist/components/settings/MenuItemsForm.d.ts +10 -0
  108. package/dist/components/settings/MenuItemsForm.js +80 -0
  109. package/dist/components/settings/MenuItemsForm.js.map +1 -0
  110. package/dist/components/settings/SettingsPanel.d.ts +12 -0
  111. package/dist/components/settings/SettingsPanel.js +92 -0
  112. package/dist/components/settings/SettingsPanel.js.map +1 -0
  113. package/dist/components/{header/FileMenu.d.ts → settings/TrackList.d.ts} +2 -2
  114. package/dist/components/settings/TrackList.js +58 -0
  115. package/dist/components/settings/TrackList.js.map +1 -0
  116. package/dist/components/tracks/TrackBlocks.js +2 -2
  117. package/dist/components/tracks/TrackBlocks.js.map +1 -1
  118. package/dist/components/tracks/TrackTooltipContent.js +2 -1
  119. package/dist/components/tracks/TrackTooltipContent.js.map +1 -1
  120. package/dist/components/tracks/drawTracks.js +13 -6
  121. package/dist/components/tracks/drawTracks.js.map +1 -1
  122. package/dist/components/tree/TreeCanvasBlock.js +2 -2
  123. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  124. package/dist/components/tree/TreeMenu.js +4 -6
  125. package/dist/components/tree/TreeMenu.js.map +1 -1
  126. package/dist/components/tree/TreeOverview.js +2 -2
  127. package/dist/components/tree/TreeOverview.js.map +1 -1
  128. package/dist/constants.d.ts +4 -1
  129. package/dist/constants.js +7 -1
  130. package/dist/constants.js.map +1 -1
  131. package/dist/darkReader.d.ts +7 -0
  132. package/dist/darkReader.js +42 -0
  133. package/dist/darkReader.js.map +1 -0
  134. package/dist/element.js +22 -47
  135. package/dist/element.js.map +1 -1
  136. package/dist/featurePanels.d.ts +37 -0
  137. package/dist/featurePanels.js +187 -0
  138. package/dist/featurePanels.js.map +1 -0
  139. package/dist/filehandleLoader.d.ts +41 -0
  140. package/dist/filehandleLoader.js +99 -0
  141. package/dist/filehandleLoader.js.map +1 -0
  142. package/dist/index.d.ts +3 -0
  143. package/dist/index.js +2 -0
  144. package/dist/index.js.map +1 -1
  145. package/dist/model/treeModel.d.ts +9 -0
  146. package/dist/model/treeModel.js +12 -1
  147. package/dist/model/treeModel.js.map +1 -1
  148. package/dist/model.d.ts +148 -32
  149. package/dist/model.js +291 -569
  150. package/dist/model.js.map +1 -1
  151. package/dist/neighborJoining.js +1 -40
  152. package/dist/neighborJoining.js.map +1 -1
  153. package/dist/renderToSvg.js +1 -13
  154. package/dist/renderToSvg.js.map +1 -1
  155. package/dist/rerootTree.d.ts +1 -0
  156. package/dist/rerootTree.js +7 -6
  157. package/dist/rerootTree.js.map +1 -1
  158. package/dist/schemeResidueColor.d.ts +12 -0
  159. package/dist/schemeResidueColor.js +33 -0
  160. package/dist/schemeResidueColor.js.map +1 -0
  161. package/dist/similarityColors.d.ts +11 -0
  162. package/dist/similarityColors.js +90 -0
  163. package/dist/similarityColors.js.map +1 -0
  164. package/dist/svgTestUtil.d.ts +64 -12
  165. package/dist/treeDisplay.d.ts +37 -0
  166. package/dist/treeDisplay.js +209 -0
  167. package/dist/treeDisplay.js.map +1 -0
  168. package/dist/types.d.ts +7 -3
  169. package/dist/useWheelScroll.d.ts +3 -1
  170. package/dist/useWheelScroll.js +36 -17
  171. package/dist/useWheelScroll.js.map +1 -1
  172. package/dist/util.d.ts +2 -0
  173. package/dist/util.js +2 -0
  174. package/dist/util.js.map +1 -1
  175. package/dist/version.d.ts +1 -1
  176. package/dist/version.js +1 -1
  177. package/dist/wheelZoom.d.ts +8 -3
  178. package/dist/wheelZoom.js +44 -32
  179. package/dist/wheelZoom.js.map +1 -1
  180. package/dist/zoomSnapshot.d.ts +29 -0
  181. package/dist/zoomSnapshot.js +47 -0
  182. package/dist/zoomSnapshot.js.map +1 -0
  183. package/package.json +11 -11
  184. package/src/blosum62.ts +45 -0
  185. package/src/colorSchemes.ts +1 -0
  186. package/src/components/Loading.tsx +6 -2
  187. package/src/components/MSAView.tsx +22 -5
  188. package/src/components/MetadataTable.tsx +83 -26
  189. package/src/components/Track.tsx +13 -0
  190. package/src/components/controls.ts +2 -1
  191. package/src/components/dialogs/AnnotationFileDialog.tsx +12 -1
  192. package/src/components/dialogs/FeatureDialog.tsx +2 -5
  193. package/src/components/dialogs/GapThresholdDialog.tsx +36 -0
  194. package/src/components/{header → dialogs}/GappynessSlider.tsx +3 -10
  195. package/src/components/{header → dialogs}/GoToBox.tsx +36 -10
  196. package/src/components/dialogs/GoToDialog.tsx +30 -0
  197. package/src/components/dialogs/MetadataDialog.tsx +32 -4
  198. package/src/components/{header → dialogs}/goTo.ts +1 -1
  199. package/src/components/dialogs/metadataLabels.ts +54 -0
  200. package/src/components/dialogs/metadataRecord.tsx +61 -0
  201. package/src/components/header/Header.tsx +75 -42
  202. package/src/components/header/HiddenColumnsChip.tsx +39 -0
  203. package/src/components/header/MenuBar.tsx +64 -0
  204. package/src/components/header/ScrollZoomCheckbox.tsx +46 -0
  205. package/src/components/header/ZoomControls.tsx +20 -35
  206. package/src/components/header/colorSchemeMenuItems.ts +121 -0
  207. package/src/components/header/getAnnotationsMenu.ts +52 -56
  208. package/src/components/header/menuBarItems.ts +357 -0
  209. package/src/components/import/ImportForm.tsx +19 -7
  210. package/src/components/minimap/Minimap.tsx +11 -3
  211. package/src/components/minimap/MinimapSVG.tsx +17 -1
  212. package/src/components/minimap/minimapLayout.ts +27 -0
  213. package/src/components/msa/MSACanvas.tsx +22 -3
  214. package/src/components/msa/MSACanvasBlock.tsx +18 -11
  215. package/src/components/msa/MSAMouseoverCanvas.tsx +2 -2
  216. package/src/components/msa/WheelZoomHint.tsx +56 -0
  217. package/src/components/msa/msaKeys.ts +3 -0
  218. package/src/components/msa/msaRaster.ts +6 -8
  219. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +28 -5
  220. package/src/components/msa/renderHighlights.ts +3 -3
  221. package/src/components/msa/renderMSABlock.ts +51 -15
  222. package/src/components/msa/tileColor.ts +7 -0
  223. package/src/components/rowpanels/RowPanelBlock.tsx +2 -2
  224. package/src/components/settings/MenuItemsForm.tsx +225 -0
  225. package/src/components/settings/SettingsPanel.tsx +156 -0
  226. package/src/components/settings/TrackList.tsx +124 -0
  227. package/src/components/tracks/TrackBlocks.tsx +2 -2
  228. package/src/components/tracks/TrackTooltipContent.tsx +2 -1
  229. package/src/components/tracks/drawTracks.ts +15 -7
  230. package/src/components/tree/TreeCanvasBlock.tsx +2 -2
  231. package/src/components/tree/TreeMenu.tsx +4 -6
  232. package/src/components/tree/TreeOverview.tsx +2 -2
  233. package/src/constants.ts +9 -1
  234. package/src/darkReader.ts +57 -0
  235. package/src/element.ts +34 -57
  236. package/src/featurePanels.ts +269 -0
  237. package/src/filehandleLoader.ts +136 -0
  238. package/src/index.ts +4 -0
  239. package/src/model/treeModel.ts +13 -0
  240. package/src/model.ts +370 -748
  241. package/src/neighborJoining.ts +1 -42
  242. package/src/renderToSvg.tsx +1 -13
  243. package/src/rerootTree.ts +7 -6
  244. package/src/schemeResidueColor.ts +37 -0
  245. package/src/similarityColors.ts +112 -0
  246. package/src/treeDisplay.ts +278 -0
  247. package/src/types.ts +7 -4
  248. package/src/useWheelScroll.ts +43 -22
  249. package/src/util.ts +3 -0
  250. package/src/version.ts +1 -1
  251. package/src/wheelZoom.ts +55 -33
  252. package/src/zoomSnapshot.ts +80 -0
  253. package/dist/components/header/ColorSchemeMenu.d.ts +0 -12
  254. package/dist/components/header/ColorSchemeMenu.js +0 -37
  255. package/dist/components/header/ColorSchemeMenu.js.map +0 -1
  256. package/dist/components/header/FileMenu.js +0 -92
  257. package/dist/components/header/FileMenu.js.map +0 -1
  258. package/dist/components/header/GappynessSlider.js.map +0 -1
  259. package/dist/components/header/GoToBox.js +0 -31
  260. package/dist/components/header/GoToBox.js.map +0 -1
  261. package/dist/components/header/MSASettingsMenu.js +0 -11
  262. package/dist/components/header/MSASettingsMenu.js.map +0 -1
  263. package/dist/components/header/ScrollZoomIcons.d.ts +0 -6
  264. package/dist/components/header/ScrollZoomIcons.js +0 -35
  265. package/dist/components/header/ScrollZoomIcons.js.map +0 -1
  266. package/dist/components/header/TreeSettingsMenu.js +0 -11
  267. package/dist/components/header/TreeSettingsMenu.js.map +0 -1
  268. package/dist/components/header/goTo.d.ts +0 -20
  269. package/dist/components/header/goTo.js.map +0 -1
  270. package/dist/components/header/settingsMenuItems.d.ts +0 -5
  271. package/dist/components/header/settingsMenuItems.js +0 -171
  272. package/dist/components/header/settingsMenuItems.js.map +0 -1
  273. package/src/components/header/ColorSchemeMenu.tsx +0 -56
  274. package/src/components/header/FileMenu.tsx +0 -107
  275. package/src/components/header/MSASettingsMenu.tsx +0 -26
  276. package/src/components/header/ScrollZoomIcons.tsx +0 -52
  277. package/src/components/header/TreeSettingsMenu.tsx +0 -30
  278. package/src/components/header/settingsMenuItems.ts +0 -216
@@ -1,30 +1,34 @@
1
1
  import { useEffect, useRef, useState } from 'react'
2
2
 
3
- import {
4
- SCROLL_ZOOM_DIVISOR,
5
- getZoomNormalizer,
6
- normalizeWheelDelta,
7
- zoomFactorFromAccum,
8
- } from './wheelZoom.ts'
3
+ import { WheelZoomSmoother } from './wheelZoom.ts'
4
+
5
+ const zoomSettleMs = 150
9
6
 
10
7
  export function useWheelScroll({
11
8
  ref,
12
9
  onScrollX,
13
10
  onScrollY,
14
11
  onZoom,
12
+ onZoomSettle,
13
+ onWheelScroll,
15
14
  scrollZoom,
16
15
  }: {
17
16
  ref: React.RefObject<HTMLDivElement | null>
18
17
  onScrollX?: (delta: number) => void
19
18
  onScrollY?: (delta: number) => void
20
19
  onZoom?: (scaleFactor: number, offsetX: number, offsetY: number) => void
20
+ onZoomSettle?: () => void
21
+ onWheelScroll?: (event: WheelEvent) => void
21
22
  scrollZoom?: boolean
22
23
  }) {
23
24
  const scheduled = useRef(false)
24
- const zoomScheduled = useRef(false)
25
+ const zoomFrame = useRef<number | undefined>(undefined)
26
+ const zoomSettle = useRef<ReturnType<typeof setTimeout> | undefined>(
27
+ undefined,
28
+ )
25
29
  const deltaX = useRef(0)
26
30
  const deltaY = useRef(0)
27
- const zoomAccum = useRef(0)
31
+ const zoomSmoother = useRef(new WheelZoomSmoother())
28
32
  const zoomX = useRef(0)
29
33
  const zoomY = useRef(0)
30
34
  const lastZoomTime = useRef<number | null>(null)
@@ -47,28 +51,31 @@ export function useWheelScroll({
47
51
  !event.shiftKey &&
48
52
  Math.abs(event.deltaY) >= Math.abs(event.deltaX)
49
53
  if (onZoom && (isCtrlZoom || isScrollZoom)) {
54
+ const zoom = onZoom
50
55
  const rect = curr!.getBoundingClientRect()
51
- // normalize away deltaMode (line/page), then divide by an adaptive
52
- // factor so fine pinches and coarse notches feel consistent
53
- const dY = normalizeWheelDelta(event.deltaY, event.deltaMode)
54
- const divisor = isCtrlZoom ? getZoomNormalizer(dY) : SCROLL_ZOOM_DIVISOR
55
- zoomAccum.current += dY / divisor
56
+ zoomSmoother.current.add(event.deltaY, event.deltaMode, isCtrlZoom)
56
57
  zoomX.current = event.clientX - rect.left
57
58
  zoomY.current = event.clientY - rect.top
58
- if (!zoomScheduled.current) {
59
- zoomScheduled.current = true
60
- requestAnimationFrame(now => {
59
+ if (zoomFrame.current === undefined) {
60
+ lastZoomTime.current = null
61
+ const frame = (now: number) => {
61
62
  const elapsed =
62
63
  lastZoomTime.current === null ? 16.67 : now - lastZoomTime.current
63
64
  lastZoomTime.current = now
64
- onZoom(
65
- zoomFactorFromAccum(zoomAccum.current, Math.min(100, elapsed)),
65
+ zoom(
66
+ zoomSmoother.current.step(Math.min(100, elapsed)),
66
67
  zoomX.current,
67
68
  zoomY.current,
68
69
  )
69
- zoomAccum.current = 0
70
- zoomScheduled.current = false
71
- })
70
+ clearTimeout(zoomSettle.current)
71
+ zoomSettle.current = setTimeout(() => {
72
+ onZoomSettle?.()
73
+ }, zoomSettleMs)
74
+ zoomFrame.current = zoomSmoother.current.idle
75
+ ? undefined
76
+ : requestAnimationFrame(frame)
77
+ }
78
+ zoomFrame.current = requestAnimationFrame(frame)
72
79
  }
73
80
  event.preventDefault()
74
81
  event.stopPropagation()
@@ -79,6 +86,7 @@ export function useWheelScroll({
79
86
  const consumeX = !!onScrollX && event.deltaX !== 0
80
87
  const consumeY = !!onScrollY && event.deltaY !== 0
81
88
  if (consumeX || consumeY) {
89
+ onWheelScroll?.(event)
82
90
  if (onScrollX) {
83
91
  deltaX.current += event.deltaX
84
92
  }
@@ -107,8 +115,21 @@ export function useWheelScroll({
107
115
  curr.addEventListener('wheel', onWheel, { passive: false })
108
116
  return () => {
109
117
  curr.removeEventListener('wheel', onWheel)
118
+ if (zoomFrame.current !== undefined) {
119
+ cancelAnimationFrame(zoomFrame.current)
120
+ zoomFrame.current = undefined
121
+ }
122
+ clearTimeout(zoomSettle.current)
110
123
  }
111
- }, [ref, onScrollX, onScrollY, onZoom, scrollZoom])
124
+ }, [
125
+ ref,
126
+ onScrollX,
127
+ onScrollY,
128
+ onZoom,
129
+ onZoomSettle,
130
+ onWheelScroll,
131
+ scrollZoom,
132
+ ])
112
133
 
113
134
  useEffect(() => {
114
135
  if (!mouseDragging) {
package/src/util.ts CHANGED
@@ -142,3 +142,6 @@ export function computeRowInsertions(blanks: number[], seq: string) {
142
142
  export function len(a: { end: number; start: number }) {
143
143
  return a.end - a.start
144
144
  }
145
+
146
+ /** reads computeds so a reaction observes them, which keeps them cached */
147
+ export function readComputed(..._values: unknown[]) {}
package/src/version.ts CHANGED
@@ -1 +1 @@
1
- export const version = '9.1.0'
1
+ export const version = '9.2.0'
package/src/wheelZoom.ts CHANGED
@@ -1,47 +1,69 @@
1
- // Wheel / trackpad-pinch delta handling, adapted from @jbrowse/core's
2
- // util/wheelZoom (not yet in our pinned @jbrowse/core). Turns raw wheel deltas
3
- // into a per-frame zoom factor that feels consistent across fine trackpad
4
- // pinches and coarse mouse notches.
1
+ // Chrome and Firefox encode a trackpad pinch as ctrl+wheel with
2
+ // deltaY = -100 * ln(scale), so dividing by 100 tracks the fingers 1:1
3
+ const PINCH_PX_PER_LOG = 100
5
4
 
6
- // Fixed divisor for plain-wheel scroll-zoom mode, where deltas are big notches.
7
- export const SCROLL_ZOOM_DIVISOR = 500
5
+ // a plain scroll covers more pixels than a pinch for the same intent
6
+ const SCROLL_PX_PER_LOG = 400
8
7
 
9
- // Cap the zoom change per millisecond so a burst of momentum-scroll events
10
- // coalesced into one frame can't jump the zoom level (0.2 per ~60fps frame).
11
- const MAX_ZOOM_RATE_PER_MS = 0.2 / 16.67
8
+ // a pixel delta at least this large counts as a wheel notch
9
+ const NOTCH_MIN_PX = 40
10
+
11
+ export const NOTCH_ZOOM = 1.25
12
+
13
+ // the time constant a notch eases in over
14
+ const NOTCH_TAU_MS = 60
15
+
16
+ // a burst of continuous events coalesced into one frame applies at most 2x
17
+ const MAX_FRAME_LOG = Math.log(2)
18
+
19
+ // the queue holds at most four notches, which caps a fast spin
20
+ const MAX_PENDING_LOG = 4 * Math.log(NOTCH_ZOOM)
12
21
 
13
- // Convert a wheel delta to pixels regardless of the browser's deltaMode; some
14
- // browsers/mice report lines or pages instead of pixels.
15
22
  export function normalizeWheelDelta(delta: number, mode: number) {
16
23
  if (mode === 1) {
17
- return delta * 16 // DOM_DELTA_LINE
24
+ return delta * 16
18
25
  }
19
26
  if (mode === 2) {
20
- return delta * 100 // DOM_DELTA_PAGE
27
+ return delta * 100
21
28
  }
22
- return delta // DOM_DELTA_PIXEL
29
+ return delta
23
30
  }
24
31
 
25
- // Adaptive divisor: tiny pinch deltas zoom in larger steps, big mouse notches
26
- // in finer steps, so a trackpad pinch and a mouse wheel feel similar.
27
- export function getZoomNormalizer(deltaY: number) {
28
- const abs = Math.abs(deltaY)
29
- if (abs < 6) {
30
- return 25
31
- }
32
- if (abs > 150) {
33
- return 500
32
+ const clampAbs = (x: number, max: number) => Math.max(-max, Math.min(max, x))
33
+
34
+ // Positive log zooms in. Feed every wheel event to add() and call step() once
35
+ // per animation frame with the time since the last frame; step() returns the
36
+ // multiplier for colWidth/rowHeight.
37
+ export class WheelZoomSmoother {
38
+ private continuous = 0
39
+ private pending = 0
40
+
41
+ add(deltaY: number, deltaMode: number, isPinch: boolean) {
42
+ const px = normalizeWheelDelta(deltaY, deltaMode)
43
+ if (deltaMode !== 0 || Math.abs(px) >= NOTCH_MIN_PX) {
44
+ const notches =
45
+ deltaMode !== 0 ? 1 : Math.min(Math.max(Math.abs(px) / 100, 1), 3)
46
+ this.pending = clampAbs(
47
+ this.pending - Math.sign(px) * notches * Math.log(NOTCH_ZOOM),
48
+ MAX_PENDING_LOG,
49
+ )
50
+ } else {
51
+ this.continuous -= px / (isPinch ? PINCH_PX_PER_LOG : SCROLL_PX_PER_LOG)
52
+ }
34
53
  }
35
- if (abs > 30) {
36
- return 150
54
+
55
+ get idle() {
56
+ return this.continuous === 0 && this.pending === 0
37
57
  }
38
- return 75
39
- }
40
58
 
41
- // Turn accumulated, normalized zoom intent into a colWidth/rowHeight multiplier.
42
- // Positive accum (wheel toward user) zooms out (factor < 1); negative zooms in.
43
- export function zoomFactorFromAccum(zoomAccum: number, elapsedMs: number) {
44
- const max = MAX_ZOOM_RATE_PER_MS * elapsedMs
45
- const d = Math.max(-max, Math.min(max, zoomAccum))
46
- return d > 0 ? 1 / (1 + d) : 1 - d
59
+ step(elapsedMs: number) {
60
+ let eased = this.pending * (1 - Math.exp(-elapsedMs / NOTCH_TAU_MS))
61
+ if (Math.abs(this.pending - eased) < 0.005) {
62
+ eased = this.pending
63
+ }
64
+ this.pending -= eased
65
+ const log = clampAbs(this.continuous + eased, MAX_FRAME_LOG)
66
+ this.continuous = 0
67
+ return Math.exp(log)
68
+ }
47
69
  }
@@ -0,0 +1,80 @@
1
+ import { calculateBlocks } from './calculateBlocks.ts'
2
+
3
+ export interface ZoomSnapshot {
4
+ colWidth: number
5
+ rowHeight: number
6
+ blocksX: number[]
7
+ blocksY: number[]
8
+ }
9
+
10
+ interface Viewport {
11
+ colWidth: number
12
+ rowHeight: number
13
+ scrollX: number
14
+ scrollY: number
15
+ msaAreaWidth: number
16
+ msaAreaHeight: number
17
+ totalWidth: number
18
+ totalHeight: number
19
+ blockSize: number
20
+ }
21
+
22
+ // past this stretch the scaled letters blur enough to redraw
23
+ const maxStretch = 2
24
+
25
+ // a redraw covers this fraction of the viewport again on each side, so a zoom
26
+ // out shrinks it for a few frames before it runs out of picture
27
+ const margin = 0.2
28
+
29
+ function blocksAt(
30
+ view: Viewport,
31
+ axis: 'x' | 'y',
32
+ scale: number,
33
+ marginFraction: number,
34
+ ) {
35
+ const size = axis === 'x' ? view.msaAreaWidth : view.msaAreaHeight
36
+ const pos = -(axis === 'x' ? view.scrollX : view.scrollY)
37
+ const map = axis === 'x' ? view.totalWidth : view.totalHeight
38
+ const pad = size * marginFraction
39
+ return calculateBlocks({
40
+ viewportSize: (size + 2 * pad) / scale,
41
+ viewportPos: (pos - pad) / scale,
42
+ mapSize: map / scale,
43
+ blockSize: view.blockSize,
44
+ })
45
+ }
46
+
47
+ const within = (need: number[], have: number[]) =>
48
+ need.length === 0 ||
49
+ (have.length > 0 && need[0]! >= have[0]! && need.at(-1)! <= have.at(-1)!)
50
+
51
+ // a gesture starts from the blocks already drawn, and each redraw during it
52
+ // adds the margin
53
+ export function takeZoomSnapshot(view: Viewport, withMargin: boolean) {
54
+ const m = withMargin ? margin : 0
55
+ return {
56
+ colWidth: view.colWidth,
57
+ rowHeight: view.rowHeight,
58
+ blocksX: blocksAt(view, 'x', 1, m),
59
+ blocksY: blocksAt(view, 'y', 1, m),
60
+ } satisfies ZoomSnapshot
61
+ }
62
+
63
+ export function zoomSnapshotScale(view: Viewport, snap: ZoomSnapshot) {
64
+ return {
65
+ sx: view.colWidth / snap.colWidth,
66
+ sy: view.rowHeight / snap.rowHeight,
67
+ }
68
+ }
69
+
70
+ // whether the blocks drawn at the snapshot, stretched to the current cell
71
+ // size, still fill the viewport sharply enough
72
+ export function zoomSnapshotCovers(view: Viewport, snap: ZoomSnapshot) {
73
+ const { sx, sy } = zoomSnapshotScale(view, snap)
74
+ return (
75
+ sx <= maxStretch &&
76
+ sy <= maxStretch &&
77
+ within(blocksAt(view, 'x', sx, 0), snap.blocksX) &&
78
+ within(blocksAt(view, 'y', sy, 0), snap.blocksY)
79
+ )
80
+ }
@@ -1,12 +0,0 @@
1
- import React from 'react';
2
- import type { MsaViewModel } from '../../model.ts';
3
- export declare function colorSchemeMenuItems(model: MsaViewModel): {
4
- readonly label: string;
5
- readonly type: 'radio';
6
- readonly checked: boolean;
7
- readonly onClick: () => void;
8
- }[];
9
- declare const ColorSchemeMenu: ({ model }: {
10
- model: MsaViewModel;
11
- }) => React.JSX.Element;
12
- export default ColorSchemeMenu;
@@ -1,37 +0,0 @@
1
- import React from 'react';
2
- import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
3
- import Palette from '@mui/icons-material/Palette';
4
- import { observer } from 'mobx-react';
5
- import colorSchemes from '../../colorSchemes.js';
6
- // While a `customColorScheme` map is set, a checked Custom entry stands for it
7
- // and no named scheme is checked. Picking a named scheme clears the map.
8
- export function colorSchemeMenuItems(model) {
9
- const { colorSchemeName, customColorScheme } = model;
10
- const custom = customColorScheme
11
- ? [
12
- {
13
- label: 'Custom',
14
- type: 'radio',
15
- checked: true,
16
- onClick: () => { },
17
- },
18
- ]
19
- : [];
20
- return [
21
- ...custom,
22
- ...Object.keys(colorSchemes).map(option => ({
23
- label: option,
24
- type: 'radio',
25
- checked: !customColorScheme && colorSchemeName === option,
26
- onClick: () => {
27
- model.setColorSchemeName(option);
28
- },
29
- })),
30
- ];
31
- }
32
- const ColorSchemeMenu = observer(function ({ model }) {
33
- return (React.createElement(CascadingMenuButton, { "data-testid": "color_scheme_menu", tooltip: "Color scheme", closeAfterItemClick: true, anchorOrigin: { vertical: 'bottom', horizontal: 'left' }, transformOrigin: { vertical: 'top', horizontal: 'left' }, menuItems: colorSchemeMenuItems(model) },
34
- React.createElement(Palette, null)));
35
- });
36
- export default ColorSchemeMenu;
37
- //# sourceMappingURL=ColorSchemeMenu.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ColorSchemeMenu.js","sourceRoot":"","sources":["../../../src/components/header/ColorSchemeMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,mBAAmB,MAAM,sCAAsC,CAAA;AACtE,OAAO,OAAO,MAAM,6BAA6B,CAAA;AACjD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,YAAY,MAAM,uBAAuB,CAAA;AAIhD,+EAA+E;AAC/E,yEAAyE;AACzE,MAAM,UAAU,oBAAoB,CAAC,KAAmB;IACtD,MAAM,EAAE,eAAe,EAAE,iBAAiB,EAAE,GAAG,KAAK,CAAA;IACpD,MAAM,MAAM,GAAG,iBAAiB;QAC9B,CAAC,CAAC;YACE;gBACE,KAAK,EAAE,QAAQ;gBACf,IAAI,EAAE,OAAO;gBACb,OAAO,EAAE,IAAI;gBACb,OAAO,EAAE,GAAG,EAAE,GAAE,CAAC;aACT;SACX;QACH,CAAC,CAAC,EAAE,CAAA;IACN,OAAO;QACL,GAAG,MAAM;QACT,GAAG,MAAM,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,GAAG,CAC9B,MAAM,CAAC,EAAE,CACP,CAAC;YACC,KAAK,EAAE,MAAM;YACb,IAAI,EAAE,OAAO;YACb,OAAO,EAAE,CAAC,iBAAiB,IAAI,eAAe,KAAK,MAAM;YACzD,OAAO,EAAE,GAAG,EAAE;gBACZ,KAAK,CAAC,kBAAkB,CAAC,MAAM,CAAC,CAAA;YAClC,CAAC;SACF,CAAU,CACd;KACF,CAAA;AACH,CAAC;AAED,MAAM,eAAe,GAAG,QAAQ,CAAC,UAAU,EAAE,KAAK,EAA2B;IAC3E,OAAO,CACL,oBAAC,mBAAmB,mBACN,mBAAmB,EAC/B,OAAO,EAAC,cAAc,EACtB,mBAAmB,QACnB,YAAY,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,eAAe,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,SAAS,EAAE,oBAAoB,CAAC,KAAK,CAAC;QAEtC,oBAAC,OAAO,OAAG,CACS,CACvB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,eAAe,CAAA"}
@@ -1,92 +0,0 @@
1
- import React, { lazy } from 'react';
2
- import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
3
- import AccountTree from '@mui/icons-material/AccountTree';
4
- import Assignment from '@mui/icons-material/Assignment';
5
- import FolderOpen from '@mui/icons-material/FolderOpen';
6
- import Menu from '@mui/icons-material/Menu';
7
- import PhotoCamera from '@mui/icons-material/PhotoCamera';
8
- import { observer } from 'mobx-react';
9
- import { maxNeighborJoiningRows } from '../../constants.js';
10
- import { getAnnotationsMenu } from './getAnnotationsMenu.js';
11
- const MetadataDialog = lazy(() => import('../dialogs/MetadataDialog.js'));
12
- const ExportSVGDialog = lazy(() => import('../dialogs/ExportSVGDialog.js'));
13
- function neighborJoiningItem(model) {
14
- const rows = model.rowMap.size;
15
- const tooManyRows = rows > maxNeighborJoiningRows;
16
- return {
17
- label: tooManyRows
18
- ? `Calculate neighbor joining tree (over ${maxNeighborJoiningRows} rows, use FastTree)`
19
- : 'Calculate neighbor joining tree (BLOSUM62)',
20
- icon: AccountTree,
21
- disabled: tooManyRows || rows < 2,
22
- onClick: () => {
23
- try {
24
- model.calculateNeighborJoiningTreeFromMSA();
25
- }
26
- catch (e) {
27
- console.error('Failed to calculate NJ tree:', e);
28
- model.addWarning(e instanceof Error ? e.message : String(e));
29
- }
30
- },
31
- };
32
- }
33
- const FileMenu = observer(({ model }) => {
34
- return (React.createElement(CascadingMenuButton, { "data-testid": "file_menu", tooltip: "File", menuItems: [
35
- ...(model.importForm
36
- ? [
37
- {
38
- label: 'Return to import form',
39
- icon: FolderOpen,
40
- onClick: () => {
41
- model.reset();
42
- },
43
- },
44
- ]
45
- : []),
46
- {
47
- label: 'Metadata',
48
- icon: Assignment,
49
- onClick: () => {
50
- model.queueDialog(onClose => [
51
- MetadataDialog,
52
- {
53
- model,
54
- onClose,
55
- },
56
- ]);
57
- },
58
- },
59
- {
60
- label: 'Annotations',
61
- type: 'subMenu',
62
- subMenu: getAnnotationsMenu({
63
- model,
64
- }),
65
- },
66
- neighborJoiningItem(model),
67
- {
68
- label: 'Export tree (Newick)',
69
- icon: AccountTree,
70
- disabled: !!model.tree.noTree,
71
- onClick: () => {
72
- model.exportNewick();
73
- },
74
- },
75
- {
76
- label: 'Export SVG',
77
- icon: PhotoCamera,
78
- onClick: () => {
79
- model.queueDialog(onClose => [
80
- ExportSVGDialog,
81
- {
82
- onClose,
83
- model,
84
- },
85
- ]);
86
- },
87
- },
88
- ], anchorOrigin: { vertical: 'bottom', horizontal: 'left' }, transformOrigin: { vertical: 'top', horizontal: 'left' } },
89
- React.createElement(Menu, null)));
90
- });
91
- export default FileMenu;
92
- //# sourceMappingURL=FileMenu.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"FileMenu.js","sourceRoot":"","sources":["../../../src/components/header/FileMenu.tsx"],"names":[],"mappings":"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"}
@@ -1 +0,0 @@
1
- {"version":3,"file":"GappynessSlider.js","sourceRoot":"","sources":["../../../src/components/header/GappynessSlider.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEvC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAClD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAIrC,MAAM,eAAe,GAAG,QAAQ,CAAC,SAAS,eAAe,CAAC,EACxD,KAAK,GAGN;IACC,MAAM,EAAE,QAAQ,EAAE,gBAAgB,EAAE,GAAG,KAAK,CAAA;IAC5C,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,QAAQ,EAAU,CAAA;IACpD,MAAM,KAAK,GAAG,SAAS,IAAI,gBAAgB,CAAA;IAC3C,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,CACL,6BAAK,KAAK,EAAE,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,QAAQ,EAAE,GAAG,EAAE,CAAC,EAAE;QAI3D,oBAAC,UAAU,IAAC,KAAK,EAAE,EAAE,UAAU,EAAE,QAAQ,EAAE;;YACpB,KAAK;qBACf;QACb,oBAAC,MAAM;QACL,qEAAqE;QACrE,6DAA6D;QAC7D,wEAAwE;QACxE,yCAAyC;QACzC,EAAE;QACF,sEAAsE;QACtE,0DAA0D;QAC1D,EAAE;QACF,uEAAuE;QACvE,qEAAqE;QACrE,uBAAuB;QACvB,EAAE;QACF,iEAAiE;QACjE,uDAAuD;2BAC3C,kBAAkB,EAC9B,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,YAAY,EAAE,EAAE,EAAE,EACvC,GAAG,EAAE,CAAC,EACN,GAAG,EAAE,GAAG,EACR,KAAK,EAAE,KAAK,EACZ,QAAQ,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;gBACnB,YAAY,CAAC,GAAG,CAAC,CAAA;YACnB,CAAC,EACD,iBAAiB,EAAE,CAAC,CAAC,EAAE,GAAG,EAAE,EAAE;gBAC5B,KAAK,CAAC,mBAAmB,CAAC,GAAG,CAAC,CAAA;gBAC9B,YAAY,CAAC,SAAS,CAAC,CAAA;YACzB,CAAC,GACD,CACE,CACP,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,eAAe,CAAA"}
@@ -1,31 +0,0 @@
1
- import React, { useState } from 'react';
2
- import { Autocomplete, TextField } from '@mui/material';
3
- import { observer } from 'mobx-react';
4
- import { findableRowNames, goTo, rowNameSuggestions } from './goTo.js';
5
- const label = 'Go to row or column';
6
- // MUI 9 hands renderInput `slotProps`; MUI 7, which every released JBrowse host
7
- // serves, hands it `inputProps` and no `slotProps` at all
8
- export function labelledInput(params) {
9
- const { slotProps, inputProps } = params;
10
- return slotProps
11
- ? {
12
- slotProps: {
13
- ...slotProps,
14
- htmlInput: { ...slotProps.htmlInput, 'aria-label': label },
15
- },
16
- }
17
- : { inputProps: { ...inputProps, 'aria-label': label } };
18
- }
19
- const GoToBox = observer(function ({ model }) {
20
- const [missed, setMissed] = useState(false);
21
- const names = findableRowNames(model);
22
- return names.length > 1 || model.numColumns > 0 ? (React.createElement(Autocomplete, { freeSolo: true, size: "small", options: names, filterOptions: (options, { inputValue }) => rowNameSuggestions(options, inputValue), value: null, blurOnSelect: true, onInputChange: () => {
23
- setMissed(false);
24
- }, onChange: (_, text) => {
25
- if (text) {
26
- setMissed(!goTo(model, text));
27
- }
28
- }, style: { width: 180, margin: 'auto 8px' }, renderInput: params => (React.createElement(TextField, { ...params, error: missed, placeholder: label, title: "A row name, a column number, or name:residue", ...labelledInput(params) })) })) : null;
29
- });
30
- export default GoToBox;
31
- //# sourceMappingURL=GoToBox.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"GoToBox.js","sourceRoot":"","sources":["../../../src/components/header/GoToBox.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,EAAE,QAAQ,EAAE,MAAM,OAAO,CAAA;AAEvC,OAAO,EAAE,YAAY,EAAE,SAAS,EAAE,MAAM,eAAe,CAAA;AACvD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,gBAAgB,EAAE,IAAI,EAAE,kBAAkB,EAAE,MAAM,WAAW,CAAA;AAKtE,MAAM,KAAK,GAAG,qBAAqB,CAAA;AAEnC,gFAAgF;AAChF,0DAA0D;AAC1D,MAAM,UAAU,aAAa,CAAC,MAAqC;IACjE,MAAM,EAAE,SAAS,EAAE,UAAU,EAAE,GAAG,MAEjC,CAAA;IACD,OAAO,SAAS;QACd,CAAC,CAAC;YACE,SAAS,EAAE;gBACT,GAAG,SAAS;gBACZ,SAAS,EAAE,EAAE,GAAG,SAAS,CAAC,SAAS,EAAE,YAAY,EAAE,KAAK,EAAE;aAC3D;SACF;QACH,CAAC,CAAC,EAAE,UAAU,EAAE,EAAE,GAAG,UAAU,EAAE,YAAY,EAAE,KAAK,EAAE,EAAE,CAAA;AAC5D,CAAC;AAED,MAAM,OAAO,GAAG,QAAQ,CAAC,UAAU,EAAE,KAAK,EAA2B;IACnE,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAA;IAC3C,MAAM,KAAK,GAAG,gBAAgB,CAAC,KAAK,CAAC,CAAA;IACrC,OAAO,KAAK,CAAC,MAAM,GAAG,CAAC,IAAI,KAAK,CAAC,UAAU,GAAG,CAAC,CAAC,CAAC,CAAC,CAChD,oBAAC,YAAY,IACX,QAAQ,QACR,IAAI,EAAC,OAAO,EACZ,OAAO,EAAE,KAAK,EACd,aAAa,EAAE,CAAC,OAAO,EAAE,EAAE,UAAU,EAAE,EAAE,EAAE,CACzC,kBAAkB,CAAC,OAAO,EAAE,UAAU,CAAC,EAEzC,KAAK,EAAE,IAAI,EACX,YAAY,QACZ,aAAa,EAAE,GAAG,EAAE;YAClB,SAAS,CAAC,KAAK,CAAC,CAAA;QAClB,CAAC,EACD,QAAQ,EAAE,CAAC,CAAC,EAAE,IAAI,EAAE,EAAE;YACpB,IAAI,IAAI,EAAE,CAAC;gBACT,SAAS,CAAC,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC,EACD,KAAK,EAAE,EAAE,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,UAAU,EAAE,EACzC,WAAW,EAAE,MAAM,CAAC,EAAE,CAAC,CACrB,oBAAC,SAAS,OACJ,MAAM,EACV,KAAK,EAAE,MAAM,EACb,WAAW,EAAE,KAAK,EAClB,KAAK,EAAC,8CAA8C,KAChD,aAAa,CAAC,MAAM,CAAC,GACzB,CACH,GACD,CACH,CAAC,CAAC,CAAC,IAAI,CAAA;AACV,CAAC,CAAC,CAAA;AAEF,eAAe,OAAO,CAAA"}
@@ -1,11 +0,0 @@
1
- import React from 'react';
2
- import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
3
- import Tune from '@mui/icons-material/Tune';
4
- import { observer } from 'mobx-react';
5
- import { msaSettingsMenuItems } from './settingsMenuItems.js';
6
- const MSASettingsMenu = observer(function ({ model }) {
7
- return (React.createElement(CascadingMenuButton, { "data-testid": "msa_settings_menu", tooltip: "Alignment settings", closeAfterItemClick: false, anchorOrigin: { vertical: 'bottom', horizontal: 'left' }, transformOrigin: { vertical: 'top', horizontal: 'left' }, menuItems: msaSettingsMenuItems(model) },
8
- React.createElement(Tune, null)));
9
- });
10
- export default MSASettingsMenu;
11
- //# sourceMappingURL=MSASettingsMenu.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"MSASettingsMenu.js","sourceRoot":"","sources":["../../../src/components/header/MSASettingsMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,mBAAmB,MAAM,sCAAsC,CAAA;AACtE,OAAO,IAAI,MAAM,0BAA0B,CAAA;AAC3C,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,oBAAoB,EAAE,MAAM,wBAAwB,CAAA;AAI7D,MAAM,eAAe,GAAG,QAAQ,CAAC,UAAU,EAAE,KAAK,EAA2B;IAC3E,OAAO,CACL,oBAAC,mBAAmB,mBACN,mBAAmB,EAC/B,OAAO,EAAC,oBAAoB,EAC5B,mBAAmB,EAAE,KAAK,EAC1B,YAAY,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,eAAe,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,SAAS,EAAE,oBAAoB,CAAC,KAAK,CAAC;QAEtC,oBAAC,IAAI,OAAG,CACY,CACvB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,eAAe,CAAA"}
@@ -1,6 +0,0 @@
1
- import React from 'react';
2
- import type { SvgIconProps } from '@mui/material/SvgIcon';
3
- export declare function MouseScroll(props: SvgIconProps): React.JSX.Element;
4
- export declare function MouseZoomBoth(props: SvgIconProps): React.JSX.Element;
5
- export declare function MouseZoomHorizontal(props: SvgIconProps): React.JSX.Element;
6
- export declare function MouseZoomVertical(props: SvgIconProps): React.JSX.Element;
@@ -1,35 +0,0 @@
1
- import React from 'react';
2
- import SvgIcon from '@mui/material/SvgIcon';
3
- // Mouse glyphs with outward arrows on the axes a wheel zoom scales.
4
- // @mui/icons-material ships only the plain `Mouse`, and three variants that
5
- // differ only in their arrows have to share one body to stay apart at 24px.
6
- // The body's inner subpath runs the opposite sweep, which punches the hole the
7
- // wheel bar sits in.
8
- const BODY = 'M12 5a4 4 0 0 0-4 4v6a4 4 0 0 0 8 0V9a4 4 0 0 0-4-4zm0 2a2 2 0 0 1 2 2v6a2 2 0 0 1-4 0V9a2 2 0 0 1 2-2z';
9
- const WHEEL = 'M11.2 8.6h1.6v3.2h-1.6z';
10
- const LEFT = 'M.4 12 5 15V9z';
11
- const RIGHT = 'M23.6 12 19 9v6z';
12
- const UP = 'M12 .4 15 4H9z';
13
- const DOWN = 'M12 23.6 9 20h6z';
14
- function MouseZoom({ arrows, ...rest }) {
15
- return (React.createElement(SvgIcon, { ...rest },
16
- React.createElement("path", { d: BODY }),
17
- React.createElement("path", { d: WHEEL }),
18
- arrows.map(d => (React.createElement("path", { key: d, d: d })))));
19
- }
20
- // the bare body, for a wheel that scrolls. @mui/icons-material's own `Mouse` is
21
- // a solid silhouette, which would jump to a different drawing when the menu
22
- // changes the mode.
23
- export function MouseScroll(props) {
24
- return React.createElement(MouseZoom, { ...props, arrows: [] });
25
- }
26
- export function MouseZoomBoth(props) {
27
- return React.createElement(MouseZoom, { ...props, arrows: [LEFT, RIGHT, UP, DOWN] });
28
- }
29
- export function MouseZoomHorizontal(props) {
30
- return React.createElement(MouseZoom, { ...props, arrows: [LEFT, RIGHT] });
31
- }
32
- export function MouseZoomVertical(props) {
33
- return React.createElement(MouseZoom, { ...props, arrows: [UP, DOWN] });
34
- }
35
- //# sourceMappingURL=ScrollZoomIcons.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"ScrollZoomIcons.js","sourceRoot":"","sources":["../../../src/components/header/ScrollZoomIcons.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,OAAO,MAAM,uBAAuB,CAAA;AAI3C,oEAAoE;AACpE,4EAA4E;AAC5E,4EAA4E;AAC5E,+EAA+E;AAC/E,qBAAqB;AACrB,MAAM,IAAI,GACR,yGAAyG,CAAA;AAC3G,MAAM,KAAK,GAAG,yBAAyB,CAAA;AACvC,MAAM,IAAI,GAAG,gBAAgB,CAAA;AAC7B,MAAM,KAAK,GAAG,kBAAkB,CAAA;AAChC,MAAM,EAAE,GAAG,gBAAgB,CAAA;AAC3B,MAAM,IAAI,GAAG,kBAAkB,CAAA;AAE/B,SAAS,SAAS,CAAC,EACjB,MAAM,EACN,GAAG,IAAI,EACsC;IAC7C,OAAO,CACL,oBAAC,OAAO,OAAK,IAAI;QACf,8BAAM,CAAC,EAAE,IAAI,GAAI;QACjB,8BAAM,CAAC,EAAE,KAAK,GAAI;QACjB,MAAM,CAAC,GAAG,CAAC,CAAC,CAAC,EAAE,CAAC,CACf,8BAAM,GAAG,EAAE,CAAC,EAAE,CAAC,EAAE,CAAC,GAAI,CACvB,CAAC,CACM,CACX,CAAA;AACH,CAAC;AAED,gFAAgF;AAChF,4EAA4E;AAC5E,oBAAoB;AACpB,MAAM,UAAU,WAAW,CAAC,KAAmB;IAC7C,OAAO,oBAAC,SAAS,OAAK,KAAK,EAAE,MAAM,EAAE,EAAE,GAAI,CAAA;AAC7C,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,KAAmB;IAC/C,OAAO,oBAAC,SAAS,OAAK,KAAK,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,CAAC,GAAI,CAAA;AAClE,CAAC;AAED,MAAM,UAAU,mBAAmB,CAAC,KAAmB;IACrD,OAAO,oBAAC,SAAS,OAAK,KAAK,EAAE,MAAM,EAAE,CAAC,IAAI,EAAE,KAAK,CAAC,GAAI,CAAA;AACxD,CAAC;AAED,MAAM,UAAU,iBAAiB,CAAC,KAAmB;IACnD,OAAO,oBAAC,SAAS,OAAK,KAAK,EAAE,MAAM,EAAE,CAAC,EAAE,EAAE,IAAI,CAAC,GAAI,CAAA;AACrD,CAAC"}
@@ -1,11 +0,0 @@
1
- import React from 'react';
2
- import CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton';
3
- import AccountTree from '@mui/icons-material/AccountTree';
4
- import { observer } from 'mobx-react';
5
- import { treeSettingsMenuItems } from './settingsMenuItems.js';
6
- const TreeSettingsMenu = observer(function ({ model, }) {
7
- return model.noTree ? null : (React.createElement(CascadingMenuButton, { "data-testid": "tree_settings_menu", tooltip: "Tree settings", closeAfterItemClick: false, anchorOrigin: { vertical: 'bottom', horizontal: 'left' }, transformOrigin: { vertical: 'top', horizontal: 'left' }, menuItems: treeSettingsMenuItems(model) },
8
- React.createElement(AccountTree, null)));
9
- });
10
- export default TreeSettingsMenu;
11
- //# sourceMappingURL=TreeSettingsMenu.js.map
@@ -1 +0,0 @@
1
- {"version":3,"file":"TreeSettingsMenu.js","sourceRoot":"","sources":["../../../src/components/header/TreeSettingsMenu.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,OAAO,CAAA;AAEzB,OAAO,mBAAmB,MAAM,sCAAsC,CAAA;AACtE,OAAO,WAAW,MAAM,iCAAiC,CAAA;AACzD,OAAO,EAAE,QAAQ,EAAE,MAAM,YAAY,CAAA;AAErC,OAAO,EAAE,qBAAqB,EAAE,MAAM,wBAAwB,CAAA;AAI9D,MAAM,gBAAgB,GAAG,QAAQ,CAAC,UAAU,EAC1C,KAAK,GAGN;IACC,OAAO,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,CAC3B,oBAAC,mBAAmB,mBACN,oBAAoB,EAChC,OAAO,EAAC,eAAe,EACvB,mBAAmB,EAAE,KAAK,EAC1B,YAAY,EAAE,EAAE,QAAQ,EAAE,QAAQ,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,eAAe,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,UAAU,EAAE,MAAM,EAAE,EACxD,SAAS,EAAE,qBAAqB,CAAC,KAAK,CAAC;QAEvC,oBAAC,WAAW,OAAG,CACK,CACvB,CAAA;AACH,CAAC,CAAC,CAAA;AAEF,eAAe,gBAAgB,CAAA"}
@@ -1,20 +0,0 @@
1
- import type { MsaViewModel } from '../../model.ts';
2
- export declare function findableRowNames(model: MsaViewModel): string[];
3
- export declare function rowNameSuggestions(names: string[], input: string, limit?: number): string[];
4
- /**
5
- * The visible row and column a "Go to" entry names: a row by its name, the
6
- * column the ruler numbers N, or residue N of a row written `name:N`. A name
7
- * is tried whole first, so a row called `chr1:100` stays reachable.
8
- */
9
- export declare function resolveGoTo(model: MsaViewModel, text: string): {
10
- row: number;
11
- col?: undefined;
12
- } | {
13
- row: number | undefined;
14
- col: number;
15
- } | {
16
- row?: undefined;
17
- col: number;
18
- } | undefined;
19
- /** centers the view on the entry's target and lights it; false if none */
20
- export declare function goTo(model: MsaViewModel, text: string): boolean;
@@ -1 +0,0 @@
1
- {"version":3,"file":"goTo.js","sourceRoot":"","sources":["../../../src/components/header/goTo.ts"],"names":[],"mappings":"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"}
@@ -1,5 +0,0 @@
1
- import type { MsaViewModel } from '../../model.ts';
2
- import type { MenuItem } from '@jbrowse/core/ui/Menu';
3
- export declare function wheelSubMenu(model: MsaViewModel): MenuItem[];
4
- export declare function msaSettingsMenuItems(model: MsaViewModel): MenuItem[];
5
- export declare function treeSettingsMenuItems(model: MsaViewModel): MenuItem[];