react-msaview 6.5.0 → 8.0.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 (414) hide show
  1. package/README.md +13 -11
  2. package/bundle/index.js +122 -112
  3. package/bundle/index.js.map +4 -4
  4. package/dist/colorSchemes.js +1 -2
  5. package/dist/colorSchemes.js.map +1 -1
  6. package/dist/columnStats.d.ts +28 -0
  7. package/dist/columnStats.js +34 -0
  8. package/dist/columnStats.js.map +1 -0
  9. package/dist/components/DragHandle.d.ts +3 -2
  10. package/dist/components/DragHandle.js +11 -5
  11. package/dist/components/DragHandle.js.map +1 -1
  12. package/dist/components/Loading.js +2 -2
  13. package/dist/components/Loading.js.map +1 -1
  14. package/dist/components/MSAView.js +17 -6
  15. package/dist/components/MSAView.js.map +1 -1
  16. package/dist/components/MSAViewer.d.ts +69 -4
  17. package/dist/components/MSAViewer.js +201 -8
  18. package/dist/components/MSAViewer.js.map +1 -1
  19. package/dist/components/PortalTooltip.d.ts +11 -0
  20. package/dist/components/PortalTooltip.js +29 -0
  21. package/dist/components/PortalTooltip.js.map +1 -0
  22. package/dist/components/ResizeHandles.d.ts +3 -3
  23. package/dist/components/ResizeHandles.js +13 -24
  24. package/dist/components/ResizeHandles.js.map +1 -1
  25. package/dist/components/SequenceTextArea.js +3 -3
  26. package/dist/components/SequenceTextArea.js.map +1 -1
  27. package/dist/components/Track.js +41 -22
  28. package/dist/components/Track.js.map +1 -1
  29. package/dist/components/dialogs/{InterProScanDialog.d.ts → AnnotationFileDialog.d.ts} +2 -2
  30. package/dist/components/dialogs/AnnotationFileDialog.js +92 -0
  31. package/dist/components/dialogs/AnnotationFileDialog.js.map +1 -0
  32. package/dist/components/dialogs/ExportSVGDialog.js +5 -3
  33. package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
  34. package/dist/components/dialogs/FeatureDialog.js +13 -9
  35. package/dist/components/dialogs/FeatureDialog.js.map +1 -1
  36. package/dist/components/dialogs/TrackInfoDialog.js +1 -1
  37. package/dist/components/dialogs/TrackInfoDialog.js.map +1 -1
  38. package/dist/components/header/GappynessSlider.js +6 -11
  39. package/dist/components/header/GappynessSlider.js.map +1 -1
  40. package/dist/components/header/Header.js +7 -0
  41. package/dist/components/header/Header.js.map +1 -1
  42. package/dist/components/header/HeaderStatusArea.js +0 -2
  43. package/dist/components/header/HeaderStatusArea.js.map +1 -1
  44. package/dist/components/header/LoadWarnings.d.ts +6 -0
  45. package/dist/components/header/LoadWarnings.js +35 -0
  46. package/dist/components/header/LoadWarnings.js.map +1 -0
  47. package/dist/components/header/MultiAlignmentSelector.js +0 -0
  48. package/dist/components/header/MultiAlignmentSelector.js.map +1 -1
  49. package/dist/components/header/ScrollZoomIcons.d.ts +6 -0
  50. package/dist/components/header/ScrollZoomIcons.js +35 -0
  51. package/dist/components/header/ScrollZoomIcons.js.map +1 -0
  52. package/dist/components/header/TreeSettingsMenu.js +7 -1
  53. package/dist/components/header/TreeSettingsMenu.js.map +1 -1
  54. package/dist/components/header/UnshareableDataWarning.d.ts +6 -0
  55. package/dist/components/header/UnshareableDataWarning.js +40 -0
  56. package/dist/components/header/UnshareableDataWarning.js.map +1 -0
  57. package/dist/components/header/ZoomControls.js +49 -6
  58. package/dist/components/header/ZoomControls.js.map +1 -1
  59. package/dist/components/header/getAnnotationsMenu.js +11 -14
  60. package/dist/components/header/getAnnotationsMenu.js.map +1 -1
  61. package/dist/components/header/settingsMenuItems.js +10 -7
  62. package/dist/components/header/settingsMenuItems.js.map +1 -1
  63. package/dist/components/import/ImportForm.js +1 -1
  64. package/dist/components/import/ImportForm.js.map +1 -1
  65. package/dist/components/import/ImportFormExamples.js +2 -6
  66. package/dist/components/import/ImportFormExamples.js.map +1 -1
  67. package/dist/components/import/util.js +2 -0
  68. package/dist/components/import/util.js.map +1 -1
  69. package/dist/components/minimap/Minimap.js +1 -2
  70. package/dist/components/minimap/Minimap.js.map +1 -1
  71. package/dist/components/msa/AnnotationLegend.js +27 -19
  72. package/dist/components/msa/AnnotationLegend.js.map +1 -1
  73. package/dist/components/msa/MSACanvas.js +1 -1
  74. package/dist/components/msa/MSACanvas.js.map +1 -1
  75. package/dist/components/msa/MSACanvasBlock.js +17 -20
  76. package/dist/components/msa/MSACanvasBlock.js.map +1 -1
  77. package/dist/components/msa/MSAMouseoverCanvas.js +2 -1
  78. package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
  79. package/dist/components/msa/domainBandCursor.d.ts +7 -11
  80. package/dist/components/msa/domainBandCursor.js +7 -11
  81. package/dist/components/msa/domainBandCursor.js.map +1 -1
  82. package/dist/components/msa/drawFeatureSpans.d.ts +53 -0
  83. package/dist/components/msa/drawFeatureSpans.js +78 -0
  84. package/dist/components/msa/drawFeatureSpans.js.map +1 -0
  85. package/dist/components/msa/legendRows.d.ts +8 -0
  86. package/dist/components/msa/legendRows.js +16 -0
  87. package/dist/components/msa/legendRows.js.map +1 -0
  88. package/dist/components/msa/msaRaster.d.ts +30 -27
  89. package/dist/components/msa/msaRaster.js +193 -90
  90. package/dist/components/msa/msaRaster.js.map +1 -1
  91. package/dist/components/msa/packDomainLanes.d.ts +20 -0
  92. package/dist/components/msa/packDomainLanes.js +33 -0
  93. package/dist/components/msa/packDomainLanes.js.map +1 -0
  94. package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +3 -1
  95. package/dist/components/msa/renderBoxFeatureCanvasBlock.js +51 -87
  96. package/dist/components/msa/renderBoxFeatureCanvasBlock.js.map +1 -1
  97. package/dist/components/msa/renderHighlights.d.ts +44 -4
  98. package/dist/components/msa/renderHighlights.js +99 -11
  99. package/dist/components/msa/renderHighlights.js.map +1 -1
  100. package/dist/components/msa/renderMSABlock.d.ts +1 -2
  101. package/dist/components/msa/renderMSABlock.js +28 -31
  102. package/dist/components/msa/renderMSABlock.js.map +1 -1
  103. package/dist/components/msa/renderMSAMouseover.js +9 -30
  104. package/dist/components/msa/renderMSAMouseover.js.map +1 -1
  105. package/dist/components/msa/tileColor.js +4 -7
  106. package/dist/components/msa/tileColor.js.map +1 -1
  107. package/dist/components/msa/useMsaBlockMouse.d.ts +5 -3
  108. package/dist/components/msa/useMsaBlockMouse.js +6 -6
  109. package/dist/components/msa/useMsaBlockMouse.js.map +1 -1
  110. package/dist/components/renderCtx.d.ts +1 -1
  111. package/dist/components/rowpanels/RowPanelBlock.d.ts +9 -0
  112. package/dist/components/rowpanels/RowPanelBlock.js +86 -0
  113. package/dist/components/rowpanels/RowPanelBlock.js.map +1 -0
  114. package/dist/components/rowpanels/RowPanelHeaders.d.ts +12 -0
  115. package/dist/components/rowpanels/RowPanelHeaders.js +38 -0
  116. package/dist/components/rowpanels/RowPanelHeaders.js.map +1 -0
  117. package/dist/components/{msa/ColumnStats.d.ts → rowpanels/RowPanels.d.ts} +2 -2
  118. package/dist/components/rowpanels/RowPanels.js +32 -0
  119. package/dist/components/rowpanels/RowPanels.js.map +1 -0
  120. package/dist/components/rowpanels/headerLayout.d.ts +1 -0
  121. package/dist/components/rowpanels/headerLayout.js +5 -0
  122. package/dist/components/rowpanels/headerLayout.js.map +1 -0
  123. package/dist/components/rowpanels/renderFeaturePanel.d.ts +21 -0
  124. package/dist/components/rowpanels/renderFeaturePanel.js +37 -0
  125. package/dist/components/rowpanels/renderFeaturePanel.js.map +1 -0
  126. package/dist/components/rowpanels/renderRowPanel.d.ts +23 -0
  127. package/dist/components/rowpanels/renderRowPanel.js +22 -0
  128. package/dist/components/rowpanels/renderRowPanel.js.map +1 -0
  129. package/dist/components/rowpanels/renderStrip.d.ts +20 -0
  130. package/dist/components/rowpanels/renderStrip.js +26 -0
  131. package/dist/components/rowpanels/renderStrip.js.map +1 -0
  132. package/dist/components/tracks/TrackBlocks.js +13 -16
  133. package/dist/components/tracks/TrackBlocks.js.map +1 -1
  134. package/dist/components/tracks/TrackTooltipContent.d.ts +15 -0
  135. package/dist/components/tracks/TrackTooltipContent.js +109 -0
  136. package/dist/components/tracks/TrackTooltipContent.js.map +1 -0
  137. package/dist/components/tracks/drawTracks.d.ts +30 -12
  138. package/dist/components/tracks/drawTracks.js +127 -34
  139. package/dist/components/tracks/drawTracks.js.map +1 -1
  140. package/dist/components/tracks/useTrackHover.d.ts +22 -0
  141. package/dist/components/tracks/useTrackHover.js +30 -0
  142. package/dist/components/tracks/useTrackHover.js.map +1 -0
  143. package/dist/components/tree/CladeLabels.d.ts +12 -0
  144. package/dist/components/tree/CladeLabels.js +48 -0
  145. package/dist/components/tree/CladeLabels.js.map +1 -0
  146. package/dist/components/tree/TreeCanvas.js +6 -4
  147. package/dist/components/tree/TreeCanvas.js.map +1 -1
  148. package/dist/components/tree/TreeCanvasBlock.js +6 -21
  149. package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
  150. package/dist/components/tree/TreeOverview.d.ts +14 -0
  151. package/dist/components/tree/TreeOverview.js +75 -0
  152. package/dist/components/tree/TreeOverview.js.map +1 -0
  153. package/dist/components/tree/TreeRuler.js +11 -5
  154. package/dist/components/tree/TreeRuler.js.map +1 -1
  155. package/dist/components/tree/cladeBrackets.d.ts +25 -0
  156. package/dist/components/tree/cladeBrackets.js +51 -0
  157. package/dist/components/tree/cladeBrackets.js.map +1 -0
  158. package/dist/components/tree/dialogs/TreeNodeInfoDialog.js +2 -2
  159. package/dist/components/tree/dialogs/TreeNodeInfoDialog.js.map +1 -1
  160. package/dist/components/tree/renderTreeCanvas.d.ts +0 -1
  161. package/dist/components/tree/renderTreeCanvas.js +221 -47
  162. package/dist/components/tree/renderTreeCanvas.js.map +1 -1
  163. package/dist/components/tree/renderTreeOverview.d.ts +52 -0
  164. package/dist/components/tree/renderTreeOverview.js +138 -0
  165. package/dist/components/tree/renderTreeOverview.js.map +1 -0
  166. package/dist/components/tree/scaleBar.d.ts +10 -0
  167. package/dist/components/tree/scaleBar.js +24 -0
  168. package/dist/components/tree/scaleBar.js.map +1 -0
  169. package/dist/components/tree/useTreeHover.js +2 -4
  170. package/dist/components/tree/useTreeHover.js.map +1 -1
  171. package/dist/constants.d.ts +18 -1
  172. package/dist/constants.js +51 -8
  173. package/dist/constants.js.map +1 -1
  174. package/dist/createPaletteMap.d.ts +7 -6
  175. package/dist/createPaletteMap.js +10 -9
  176. package/dist/createPaletteMap.js.map +1 -1
  177. package/dist/element.d.ts +13 -0
  178. package/dist/element.js +269 -0
  179. package/dist/element.js.map +1 -0
  180. package/dist/featureFields.d.ts +11 -0
  181. package/dist/featureFields.js +17 -0
  182. package/dist/featureFields.js.map +1 -0
  183. package/dist/fetchUtils.d.ts +7 -7
  184. package/dist/fetchUtils.js +4 -32
  185. package/dist/fetchUtils.js.map +1 -1
  186. package/dist/flatToTree.js +1 -2
  187. package/dist/flatToTree.js.map +1 -1
  188. package/dist/ggplotPalettes.d.ts +10 -0
  189. package/dist/ggplotPalettes.js +58 -0
  190. package/dist/ggplotPalettes.js.map +1 -1
  191. package/dist/hierarchy.d.ts +29 -1
  192. package/dist/hierarchy.js +82 -19
  193. package/dist/hierarchy.js.map +1 -1
  194. package/dist/index.d.ts +10 -1
  195. package/dist/index.js +10 -2
  196. package/dist/index.js.map +1 -1
  197. package/dist/model/DataModel.js +4 -4
  198. package/dist/model/DataModel.js.map +1 -1
  199. package/dist/model/msaModel.d.ts +3 -2
  200. package/dist/model/msaModel.js +3 -2
  201. package/dist/model/msaModel.js.map +1 -1
  202. package/dist/model/treeModel.d.ts +30 -0
  203. package/dist/model/treeModel.js +37 -1
  204. package/dist/model/treeModel.js.map +1 -1
  205. package/dist/model.d.ts +792 -259
  206. package/dist/model.js +2092 -675
  207. package/dist/model.js.map +1 -1
  208. package/dist/mount.d.ts +11 -0
  209. package/dist/mount.js +22 -0
  210. package/dist/mount.js.map +1 -0
  211. package/dist/neighborJoining.js +8 -32
  212. package/dist/neighborJoining.js.map +1 -1
  213. package/dist/renderToStaticMarkup.d.ts +15 -13
  214. package/dist/renderToStaticMarkup.js +37 -25
  215. package/dist/renderToStaticMarkup.js.map +1 -1
  216. package/dist/renderToSvg.js +198 -68
  217. package/dist/renderToSvg.js.map +1 -1
  218. package/dist/rowCoordinateCalculations.d.ts +26 -28
  219. package/dist/rowCoordinateCalculations.js +13 -39
  220. package/dist/rowCoordinateCalculations.js.map +1 -1
  221. package/dist/scales.d.ts +22 -0
  222. package/dist/scales.js +30 -0
  223. package/dist/scales.js.map +1 -0
  224. package/dist/seqPosToGlobalCol.d.ts +2 -3
  225. package/dist/seqPosToGlobalCol.js +5 -4
  226. package/dist/seqPosToGlobalCol.js.map +1 -1
  227. package/dist/sequenceLogo.d.ts +6 -11
  228. package/dist/sequenceLogo.js +6 -11
  229. package/dist/sequenceLogo.js.map +1 -1
  230. package/dist/stripDefault.d.ts +7 -14
  231. package/dist/stripDefault.js +7 -14
  232. package/dist/stripDefault.js.map +1 -1
  233. package/dist/svgTestUtil.d.ts +306 -124
  234. package/dist/types.d.ts +295 -3
  235. package/dist/umd.d.ts +2 -0
  236. package/dist/umd.js +4 -2
  237. package/dist/umd.js.map +1 -1
  238. package/dist/useCanvasAutorun.d.ts +5 -10
  239. package/dist/useCanvasAutorun.js +5 -10
  240. package/dist/useCanvasAutorun.js.map +1 -1
  241. package/dist/useMsaSvgFigure.d.ts +20 -0
  242. package/dist/useMsaSvgFigure.js +46 -0
  243. package/dist/useMsaSvgFigure.js.map +1 -0
  244. package/dist/util.d.ts +10 -4
  245. package/dist/util.js +37 -10
  246. package/dist/util.js.map +1 -1
  247. package/dist/version.d.ts +1 -1
  248. package/dist/version.js +1 -1
  249. package/dist/wuss.d.ts +14 -0
  250. package/dist/wuss.js +55 -0
  251. package/dist/wuss.js.map +1 -0
  252. package/package.json +23 -14
  253. package/src/colorSchemes.ts +1 -2
  254. package/src/columnStats.ts +58 -0
  255. package/src/components/DragHandle.tsx +18 -7
  256. package/src/components/Loading.tsx +14 -8
  257. package/src/components/MSAView.tsx +19 -5
  258. package/src/components/MSAViewer.tsx +326 -10
  259. package/src/components/PortalTooltip.tsx +47 -0
  260. package/src/components/ResizeHandles.tsx +21 -36
  261. package/src/components/SequenceTextArea.tsx +3 -3
  262. package/src/components/Track.tsx +55 -18
  263. package/src/components/dialogs/AnnotationFileDialog.tsx +162 -0
  264. package/src/components/dialogs/ExportSVGDialog.tsx +7 -2
  265. package/src/components/dialogs/FeatureDialog.tsx +13 -9
  266. package/src/components/dialogs/TrackInfoDialog.tsx +1 -1
  267. package/src/components/header/GappynessSlider.tsx +6 -11
  268. package/src/components/header/Header.tsx +10 -0
  269. package/src/components/header/HeaderStatusArea.tsx +0 -5
  270. package/src/components/header/LoadWarnings.tsx +48 -0
  271. package/src/components/header/MultiAlignmentSelector.tsx +0 -0
  272. package/src/components/header/ScrollZoomIcons.tsx +52 -0
  273. package/src/components/header/TreeSettingsMenu.tsx +7 -1
  274. package/src/components/header/UnshareableDataWarning.tsx +56 -0
  275. package/src/components/header/ZoomControls.tsx +74 -14
  276. package/src/components/header/getAnnotationsMenu.ts +13 -17
  277. package/src/components/header/settingsMenuItems.ts +11 -6
  278. package/src/components/import/ImportForm.tsx +2 -2
  279. package/src/components/import/ImportFormExamples.tsx +4 -8
  280. package/src/components/import/util.ts +2 -0
  281. package/src/components/minimap/Minimap.tsx +1 -2
  282. package/src/components/msa/AnnotationLegend.tsx +48 -38
  283. package/src/components/msa/MSACanvas.tsx +3 -5
  284. package/src/components/msa/MSACanvasBlock.tsx +17 -21
  285. package/src/components/msa/MSAMouseoverCanvas.tsx +2 -1
  286. package/src/components/msa/domainBandCursor.ts +7 -11
  287. package/src/components/msa/drawFeatureSpans.ts +150 -0
  288. package/src/components/msa/legendRows.ts +24 -0
  289. package/src/components/msa/msaRaster.ts +236 -88
  290. package/src/components/msa/packDomainLanes.ts +36 -0
  291. package/src/components/msa/renderBoxFeatureCanvasBlock.ts +69 -123
  292. package/src/components/msa/renderHighlights.ts +141 -10
  293. package/src/components/msa/renderMSABlock.ts +29 -38
  294. package/src/components/msa/renderMSAMouseover.ts +9 -39
  295. package/src/components/msa/tileColor.ts +4 -7
  296. package/src/components/msa/useMsaBlockMouse.ts +6 -6
  297. package/src/components/renderCtx.ts +1 -0
  298. package/src/components/rowpanels/RowPanelBlock.tsx +139 -0
  299. package/src/components/rowpanels/RowPanelHeaders.tsx +57 -0
  300. package/src/components/rowpanels/RowPanels.tsx +77 -0
  301. package/src/components/rowpanels/headerLayout.ts +5 -0
  302. package/src/components/rowpanels/renderFeaturePanel.ts +66 -0
  303. package/src/components/rowpanels/renderRowPanel.ts +41 -0
  304. package/src/components/rowpanels/renderStrip.ts +46 -0
  305. package/src/components/tracks/TrackBlocks.tsx +13 -18
  306. package/src/components/tracks/TrackTooltipContent.tsx +156 -0
  307. package/src/components/tracks/drawTracks.ts +169 -38
  308. package/src/components/tracks/useTrackHover.ts +42 -0
  309. package/src/components/tree/CladeLabels.tsx +77 -0
  310. package/src/components/tree/TreeCanvas.tsx +4 -3
  311. package/src/components/tree/TreeCanvasBlock.tsx +10 -32
  312. package/src/components/tree/TreeOverview.tsx +106 -0
  313. package/src/components/tree/TreeRuler.tsx +29 -5
  314. package/src/components/tree/cladeBrackets.ts +73 -0
  315. package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +2 -2
  316. package/src/components/tree/renderTreeCanvas.ts +312 -48
  317. package/src/components/tree/renderTreeOverview.ts +212 -0
  318. package/src/components/tree/scaleBar.ts +23 -0
  319. package/src/components/tree/useTreeHover.ts +2 -4
  320. package/src/constants.ts +61 -8
  321. package/src/createPaletteMap.ts +10 -9
  322. package/src/element.ts +321 -0
  323. package/src/featureFields.ts +19 -0
  324. package/src/fetchUtils.ts +7 -40
  325. package/src/flatToTree.ts +1 -2
  326. package/src/ggplotPalettes.ts +60 -0
  327. package/src/hierarchy.ts +97 -20
  328. package/src/index.ts +46 -6
  329. package/src/model/DataModel.ts +5 -4
  330. package/src/model/msaModel.ts +3 -2
  331. package/src/model/treeModel.ts +42 -0
  332. package/src/model.ts +2492 -793
  333. package/src/mount.tsx +32 -0
  334. package/src/neighborJoining.ts +8 -32
  335. package/src/rawImports.d.ts +9 -0
  336. package/src/renderToStaticMarkup.ts +41 -25
  337. package/src/renderToSvg.tsx +365 -92
  338. package/src/rowCoordinateCalculations.ts +16 -62
  339. package/src/scales.ts +47 -0
  340. package/src/seqPosToGlobalCol.ts +5 -4
  341. package/src/sequenceLogo.ts +6 -11
  342. package/src/stripDefault.ts +7 -14
  343. package/src/types.ts +352 -12
  344. package/src/umd.ts +4 -2
  345. package/src/useCanvasAutorun.ts +5 -10
  346. package/src/useMsaSvgFigure.ts +72 -0
  347. package/src/util.ts +40 -14
  348. package/src/version.ts +1 -1
  349. package/src/wuss.ts +62 -0
  350. package/dist/components/dialogs/InterProScanDialog.js +0 -137
  351. package/dist/components/dialogs/InterProScanDialog.js.map +0 -1
  352. package/dist/components/dialogs/InterProScanFileDialog.d.ts +0 -7
  353. package/dist/components/dialogs/InterProScanFileDialog.js +0 -64
  354. package/dist/components/dialogs/InterProScanFileDialog.js.map +0 -1
  355. package/dist/components/msa/ColumnStats.js +0 -42
  356. package/dist/components/msa/ColumnStats.js.map +0 -1
  357. package/dist/launchInterProScan.d.ts +0 -13
  358. package/dist/launchInterProScan.js +0 -110
  359. package/dist/launchInterProScan.js.map +0 -1
  360. package/dist/useColorContrast.d.ts +0 -10
  361. package/dist/useColorContrast.js +0 -13
  362. package/dist/useColorContrast.js.map +0 -1
  363. package/src/clustalX.test.ts +0 -74
  364. package/src/colSpace.test.ts +0 -67
  365. package/src/collapseLogic.test.ts +0 -115
  366. package/src/colorSchemes.docs.test.ts +0 -57
  367. package/src/columnCounts.test.ts +0 -73
  368. package/src/columnStats.test.ts +0 -94
  369. package/src/columnTracks.test.ts +0 -97
  370. package/src/components/dialogs/InterProScanDialog.tsx +0 -214
  371. package/src/components/dialogs/InterProScanFileDialog.tsx +0 -138
  372. package/src/components/minimap/minimapLayout.test.ts +0 -71
  373. package/src/components/msa/ColumnStats.tsx +0 -54
  374. package/src/components/msa/msaRaster.test.ts +0 -145
  375. package/src/components/msa/renderBoxFeatureCanvasBlock.test.ts +0 -51
  376. package/src/components/tree/renderTreeCanvas.test.ts +0 -296
  377. package/src/dataInitialized.test.ts +0 -42
  378. package/src/domainBands.test.ts +0 -122
  379. package/src/domainLetterColor.test.ts +0 -80
  380. package/src/exportFileName.test.ts +0 -40
  381. package/src/fetchUtils.test.ts +0 -83
  382. package/src/flatToTree.test.ts +0 -51
  383. package/src/hierarchy.test.ts +0 -228
  384. package/src/highlights.test.ts +0 -70
  385. package/src/impgRender.test.tsx +0 -68
  386. package/src/largeTree.test.ts +0 -67
  387. package/src/launchInterProScan.ts +0 -167
  388. package/src/loadErrorDisplay.test.tsx +0 -102
  389. package/src/modelFilehandleLoaders.test.ts +0 -137
  390. package/src/modelReset.test.ts +0 -120
  391. package/src/neighborJoining.test.ts +0 -164
  392. package/src/parseAsn1.test.ts +0 -36
  393. package/src/propertyConservation.test.ts +0 -36
  394. package/src/renderColumnTracksSvg.test.tsx +0 -108
  395. package/src/renderDomainsSvg.test.tsx +0 -118
  396. package/src/renderHighlightsSvg.test.tsx +0 -85
  397. package/src/renderMinimapSvg.test.tsx +0 -62
  398. package/src/renderRasterSvg.test.tsx +0 -144
  399. package/src/renderSequenceLogoSvg.test.tsx +0 -165
  400. package/src/renderToSvg.test.tsx +0 -65
  401. package/src/reset.test.ts +0 -61
  402. package/src/rowCoordinateCalculations.test.ts +0 -211
  403. package/src/rowSpace.test.ts +0 -46
  404. package/src/segmentOverlay.test.ts +0 -70
  405. package/src/seqPosToGlobalCol.test.ts +0 -59
  406. package/src/sequenceLogo.test.ts +0 -88
  407. package/src/setFontSize.test.ts +0 -33
  408. package/src/stripDefault.test.ts +0 -48
  409. package/src/stripDefaultSnapshot.test.ts +0 -87
  410. package/src/treeMetadata.test.ts +0 -39
  411. package/src/useCanvasAutorun.test.tsx +0 -98
  412. package/src/useColorContrast.ts +0 -18
  413. package/src/viewChrome.test.tsx +0 -134
  414. package/src/wheelZoom.test.ts +0 -46
@@ -1,214 +0,0 @@
1
- import React, { useState } from 'react'
2
-
3
- import { Dialog } from '@jbrowse/core/ui'
4
- import { getSession } from '@jbrowse/core/util'
5
- import { Button, DialogActions, DialogContent, Typography } from '@mui/material'
6
- import { observer } from 'mobx-react'
7
- import { getUngappedSequence } from 'msa-parsers'
8
-
9
- import { launchInterProScan } from '../../launchInterProScan.ts'
10
-
11
- import type { MsaViewModel } from '../../model.ts'
12
-
13
- const FAMILIES = 'Families, domains, sites & repeats'
14
- const FEATURES = 'Other sequence features'
15
- const STRUCTURAL = 'Structural domains'
16
- const OTHER = 'Other category'
17
-
18
- // The analyses the EBI iprscan5 endpoint accepts, all on by default. Static, so
19
- // it lives out here rather than being rebuilt on every render of the dialog.
20
- const interProScanPrograms = [
21
- {
22
- name: 'NCBIfam',
23
- category: FAMILIES,
24
- description: 'NCBI RefSeq FAMs including TIGRFAMs',
25
- },
26
- {
27
- name: 'SFLD',
28
- category: FAMILIES,
29
- description: 'Structure function linkage database',
30
- },
31
- {
32
- name: 'Phobius',
33
- category: FEATURES,
34
- description:
35
- 'A combined transmembrane topology and signal peptide predictor',
36
- },
37
- { name: 'SignalP', category: FEATURES },
38
- { name: 'SignalP_EUK', category: OTHER },
39
- { name: 'SignalP_GRAM_POSITIVE', category: OTHER },
40
- { name: 'SignalP_GRAM_NEGATIVE', category: OTHER },
41
- { name: 'SuperFamily', category: STRUCTURAL },
42
- { name: 'Panther', category: FAMILIES },
43
- { name: 'Gene3d', category: STRUCTURAL },
44
- { name: 'HAMAP', category: FAMILIES },
45
- { name: 'PrositeProfiles', category: FAMILIES },
46
- { name: 'PrositePatterns', category: FAMILIES },
47
- { name: 'Coils', category: FEATURES },
48
- { name: 'SMART', category: FAMILIES },
49
- {
50
- name: 'CDD',
51
- category: FAMILIES,
52
- description: 'Conserved Domains Database',
53
- },
54
- { name: 'PRINTS', category: FAMILIES },
55
- { name: 'PfamA', category: FAMILIES },
56
- { name: 'MobiDBLite', category: FEATURES },
57
- { name: 'PIRSF', category: OTHER },
58
- { name: 'TMHMM', category: FEATURES },
59
- { name: 'AntiFam', category: OTHER },
60
- { name: 'FunFam', category: OTHER },
61
- { name: 'PIRSR', category: FAMILIES },
62
- ].map(program => ({ ...program, checked: true }))
63
-
64
- const InterProScanDialog = observer(function ({
65
- handleClose,
66
- model,
67
- }: {
68
- handleClose: () => void
69
- model: MsaViewModel
70
- }) {
71
- const [vals, setVals] = useState(interProScanPrograms)
72
-
73
- const programs = vals.filter(e => e.checked).map(e => e.name)
74
- const [show, setShow] = useState(false)
75
-
76
- return (
77
- <Dialog
78
- maxWidth="xl"
79
- title="Query InterProScan API for domains"
80
- onClose={() => {
81
- handleClose()
82
- }}
83
- open
84
- >
85
- <DialogContent>
86
- <Typography>
87
- This will run InterProScan via the InterProScan API on all rows of the
88
- current MSA
89
- </Typography>
90
- <Button
91
- onClick={() => {
92
- setShow(!show)
93
- }}
94
- >
95
- {show ? 'Hide' : 'Show'} advanced options
96
- </Button>
97
- {show ? (
98
- <div>
99
- <Typography>Select algorithms for InterProScan to run</Typography>
100
- <div>
101
- <Button
102
- variant="contained"
103
- color="secondary"
104
- onClick={() => {
105
- setVals(vals.map(v => ({ ...v, checked: false })))
106
- }}
107
- >
108
- Select none
109
- </Button>
110
- <Button
111
- variant="contained"
112
- color="primary"
113
- onClick={() => {
114
- setVals(vals.map(v => ({ ...v, checked: true })))
115
- }}
116
- >
117
- Select all
118
- </Button>
119
- </div>
120
- <table>
121
- <tbody>
122
- {vals
123
- .toSorted((a, b) => a.category.localeCompare(b.category))
124
- .map(({ name, checked, category, description }) => (
125
- <tr key={name}>
126
- <td>
127
- <input
128
- type="checkbox"
129
- checked={checked}
130
- onChange={() => {
131
- setVals(
132
- vals.map(e =>
133
- e.name === name
134
- ? { ...e, checked: !e.checked }
135
- : e,
136
- ),
137
- )
138
- }}
139
- />
140
- </td>
141
- <td title={description}>{name}</td>
142
- <td>{category}</td>
143
- </tr>
144
- ))}
145
- </tbody>
146
- </table>
147
- </div>
148
- ) : null}
149
- </DialogContent>
150
- <DialogActions>
151
- <Button
152
- variant="contained"
153
- color="secondary"
154
- onClick={() => {
155
- handleClose()
156
- }}
157
- >
158
- Cancel
159
- </Button>
160
- <Button
161
- variant="contained"
162
- color="primary"
163
- onClick={() => {
164
- const controller = new AbortController()
165
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
166
- ;(async () => {
167
- try {
168
- const { rows } = model
169
- if (rows.length > 140) {
170
- throw new Error(
171
- 'Too many sequences, please run InterProScan offline',
172
- )
173
- }
174
- await launchInterProScan({
175
- algorithm: 'interproscan',
176
- programs: programs,
177
- seq: rows
178
- .map(row => [row[0], getUngappedSequence(row[1])])
179
- .filter(f => !!f[1])
180
- .map(row => `>${row[0]}\n${row[1]}`)
181
- .join('\n'),
182
- onProgress: arg => {
183
- model.setStatus(
184
- arg
185
- ? {
186
- ...arg,
187
- onCancel: () => {
188
- controller.abort()
189
- },
190
- }
191
- : undefined,
192
- )
193
- },
194
- model,
195
- signal: controller.signal,
196
- })
197
- } catch (e) {
198
- console.error(e)
199
- getSession(model).notifyError(`${e}`, e)
200
- } finally {
201
- model.setStatus()
202
- }
203
- })()
204
- handleClose()
205
- }}
206
- >
207
- Send sequences to InterProScan
208
- </Button>
209
- </DialogActions>
210
- </Dialog>
211
- )
212
- })
213
-
214
- export default InterProScanDialog
@@ -1,138 +0,0 @@
1
- import React, { useState } from 'react'
2
-
3
- import { Dialog } from '@jbrowse/core/ui'
4
- import { getSession } from '@jbrowse/core/util'
5
- import {
6
- Button,
7
- DialogActions,
8
- DialogContent,
9
- FormControl,
10
- FormControlLabel,
11
- Radio,
12
- RadioGroup,
13
- TextField,
14
- Typography,
15
- } from '@mui/material'
16
- import { observer } from 'mobx-react'
17
- import { interProScanResponseToAnnotations } from 'msa-parsers'
18
-
19
- import { jsonfetch } from '../../fetchUtils.ts'
20
-
21
- import type { MsaViewModel } from '../../model.ts'
22
- import type { InterProScanResponse } from 'msa-parsers'
23
-
24
- const InterProScanFileDialog = observer(function ({
25
- handleClose,
26
- model,
27
- }: {
28
- handleClose: () => void
29
- model: MsaViewModel
30
- }) {
31
- const [file, setFile] = useState<File>()
32
- const [choice, setChoice] = useState('file')
33
- const [interProURL, setInterProURL] = useState('')
34
-
35
- return (
36
- <Dialog
37
- maxWidth="xl"
38
- title="Open InterProScan results"
39
- onClose={() => {
40
- handleClose()
41
- }}
42
- open
43
- >
44
- <DialogContent>
45
- <div>
46
- <Typography>
47
- Open a JSON file of InterProScan results that you run remotely on
48
- EBI servers or locally
49
- </Typography>
50
-
51
- <div style={{ display: 'flex', margin: 30 }}>
52
- <FormControl component="fieldset">
53
- <RadioGroup
54
- value={choice}
55
- onChange={event => {
56
- setChoice(event.target.value)
57
- }}
58
- >
59
- <FormControlLabel value="url" control={<Radio />} label="URL" />
60
- <FormControlLabel
61
- value="file"
62
- control={<Radio />}
63
- label="File"
64
- />
65
- </RadioGroup>
66
- </FormControl>
67
- {choice === 'url' ? (
68
- <div>
69
- <Typography>
70
- Open a InterProScan JSON file remote URL
71
- </Typography>
72
- <TextField
73
- label="URL"
74
- value={interProURL}
75
- onChange={event => {
76
- setInterProURL(event.target.value)
77
- }}
78
- />
79
- </div>
80
- ) : null}
81
- {choice === 'file' ? (
82
- <div style={{ paddingTop: 20 }}>
83
- <Typography>
84
- Open a InterProScan JSON file file from your local drive
85
- </Typography>
86
- <Button variant="outlined" component="label">
87
- Choose File
88
- <input
89
- type="file"
90
- hidden
91
- onChange={({ target }) => {
92
- const file = target.files?.[0]
93
- if (file) {
94
- setFile(file)
95
- }
96
- }}
97
- />
98
- </Button>
99
- </div>
100
- ) : null}
101
- </div>
102
- </div>
103
- </DialogContent>
104
- <DialogActions>
105
- <Button
106
- variant="contained"
107
- color="primary"
108
- onClick={() => {
109
- // eslint-disable-next-line @typescript-eslint/no-floating-promises
110
- ;(async () => {
111
- try {
112
- const ret: InterProScanResponse = file
113
- ? JSON.parse(await file.text())
114
- : await jsonfetch(interProURL)
115
-
116
- model.setAnnotations(interProScanResponseToAnnotations(ret))
117
- getSession(model).notify(
118
- 'Loaded interproscan results',
119
- 'success',
120
- )
121
- } catch (e) {
122
- console.error(e)
123
- getSession(model).notifyError(`${e}`, e)
124
- } finally {
125
- model.setStatus()
126
- }
127
- })()
128
- handleClose()
129
- }}
130
- >
131
- Open results
132
- </Button>
133
- </DialogActions>
134
- </Dialog>
135
- )
136
- })
137
-
138
- export default InterProScanFileDialog
@@ -1,71 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { expect, test } from 'vitest'
3
-
4
- import MSAModelF from '../../model.ts'
5
- import { MINIMAP_BAR_HEIGHT, getMinimapLayout } from './minimapLayout.ts'
6
-
7
- // wide enough to overflow horizontally, tall enough to raise the vertical
8
- // scrollbar — which takes 20px out of the width the alignment actually draws on
9
- function makeModel() {
10
- const names = Array.from({ length: 60 }, (_, i) => `s${i}`)
11
- const model = MSAModelF().create({
12
- type: 'MsaView',
13
- msaFormat: 'fasta',
14
- height: 400,
15
- data: { msa: names.map(n => `>${n}\n${'ACGT'.repeat(50)}`).join('\n') },
16
- })
17
- model.setWidth(1000)
18
- return model
19
- }
20
-
21
- test('the viewport rectangle scales by the canvas width, not the msa area', () => {
22
- const model = makeModel()
23
- expect(model.showVerticalScrollbar).toBe(true)
24
- expect(model.msaCanvasWidth).toBe(model.msaAreaWidth - 20)
25
-
26
- const { unit, s, w } = getMinimapLayout(model)
27
- expect(unit).toBeCloseTo(model.msaCanvasWidth / model.totalWidth)
28
- // unscrolled, the rectangle starts at the left edge and covers the fraction
29
- // of the alignment on screen. Sizing it by msaAreaWidth instead overstated
30
- // that fraction by the scrollbar's width.
31
- expect(s).toBeCloseTo(0)
32
- expect(w).toBeCloseTo(
33
- (model.msaCanvasWidth / model.totalWidth) * model.msaCanvasWidth,
34
- )
35
- })
36
-
37
- test('the rectangle tracks scrollX and the trapezoid spans the bar', () => {
38
- const model = makeModel()
39
- model.setScrollX(-300)
40
-
41
- const { msaCanvasWidth: width } = model
42
- const { s, polygonHeight, polygonPoints } = getMinimapLayout(model)
43
- expect(s).toBeCloseTo((300 / model.totalWidth) * width)
44
- expect(polygonHeight).toBe(model.minimapHeight - MINIMAP_BAR_HEIGHT)
45
- // bottom edge spans the full minimap, top edge is the viewport rectangle
46
- expect(
47
- polygonPoints.endsWith(`0,${polygonHeight} ${width},${polygonHeight}`),
48
- ).toBe(true)
49
- })
50
-
51
- test('an alignment that already fits never overflows the bar', () => {
52
- const model = MSAModelF().create({
53
- type: 'MsaView',
54
- msaFormat: 'fasta',
55
- data: { msa: '>a\nACGT\n>b\nACGT' },
56
- })
57
- model.setWidth(1000)
58
- expect(model.totalWidth).toBeLessThan(model.msaCanvasWidth)
59
- expect(getMinimapLayout(model).w).toBe(model.msaCanvasWidth)
60
- })
61
-
62
- test('an empty alignment collapses to a zero-width unit instead of dividing by zero', () => {
63
- const model = MSAModelF().create({ type: 'MsaView' })
64
- model.setWidth(1000)
65
- expect(model.totalWidth).toBe(0)
66
- const { unit, s, w } = getMinimapLayout(model)
67
- expect(unit).toBe(0)
68
- expect(s).toBeCloseTo(0)
69
- // still clamped to the minimum grabbable width
70
- expect(w).toBe(20)
71
- })
@@ -1,54 +0,0 @@
1
- import React from 'react'
2
-
3
- import { observer } from 'mobx-react'
4
-
5
- import type { MsaViewModel } from '../../model.ts'
6
-
7
- const pct = (n: number) => `${Math.round(n * 100)}%`
8
-
9
- const ColumnStats = observer(function ({ model }: { model: MsaViewModel }) {
10
- const stats = model.mouseOverColumnStats
11
- if (!stats) {
12
- return null
13
- }
14
- const {
15
- col,
16
- total,
17
- conservation,
18
- propertyConservation,
19
- consensusLetter,
20
- consensusFraction,
21
- gapFraction,
22
- distribution,
23
- } = stats
24
- const top = distribution.slice(0, 6)
25
- return (
26
- <div>
27
- <b>Column {col + 1}</b> ({total} seqs)
28
- <br />
29
- Consensus: {consensusLetter || '-'} ({pct(consensusFraction)})
30
- <br />
31
- Conservation: {conservation.toFixed(2)}
32
- {propertyConservation === undefined ? null : (
33
- <>
34
- <br />
35
- Property conservation: {propertyConservation.toFixed(2)}
36
- </>
37
- )}
38
- <br />
39
- Gaps: {pct(gapFraction)}
40
- {top.length > 0 ? (
41
- <>
42
- <br />
43
- {top.map(([letter, count]) => (
44
- <span key={letter} style={{ marginRight: 8 }}>
45
- {letter} {pct(count / total)}
46
- </span>
47
- ))}
48
- </>
49
- ) : null}
50
- </div>
51
- )
52
- })
53
-
54
- export default ColumnStats
@@ -1,145 +0,0 @@
1
- // @vitest-environment jsdom
2
- import { beforeAll, expect, test } from 'vitest'
3
-
4
- import MSAModelF from '../../model.ts'
5
- import { drawMsaRaster, rasterPixels } from './msaRaster.ts'
6
-
7
- import type { RasterSpec } from './msaRaster.ts'
8
-
9
- // the stub context resolves a color by parsing '#rrggbb', so every color the
10
- // raster asks about in this file is written that way
11
- function hexBytes(css: string) {
12
- const hex = css.replace('#', '')
13
- return [
14
- Number.parseInt(hex.slice(0, 2), 16),
15
- Number.parseInt(hex.slice(2, 4), 16),
16
- Number.parseInt(hex.slice(4, 6), 16),
17
- 255,
18
- ]
19
- }
20
-
21
- const drawn: unknown[] = []
22
-
23
- beforeAll(() => {
24
- HTMLCanvasElement.prototype.getContext = function () {
25
- let fillStyle = '#000000'
26
- return {
27
- get fillStyle() {
28
- return fillStyle
29
- },
30
- set fillStyle(v: string) {
31
- fillStyle = v
32
- },
33
- imageSmoothingEnabled: true,
34
- font: '10px sans-serif',
35
- measureText: (t: string) => ({ width: t.length * 6 }),
36
- clearRect: () => {},
37
- fillRect: () => {},
38
- resetTransform: () => {},
39
- scale: () => {},
40
- translate: () => {},
41
- getImageData: () => ({
42
- data: Uint8ClampedArray.from(hexBytes(fillStyle)),
43
- }),
44
- createImageData: (width: number, height: number) => ({
45
- data: new Uint8ClampedArray(width * height * 4),
46
- width,
47
- height,
48
- }),
49
- putImageData: () => {},
50
- drawImage: (image: unknown) => {
51
- drawn.push(image)
52
- },
53
- } as unknown as CanvasRenderingContext2D
54
- } as unknown as typeof HTMLCanvasElement.prototype.getContext
55
- })
56
-
57
- const spec: RasterSpec = {
58
- rowNames: ['a', 'b', 'c'],
59
- columns: new Map([
60
- ['a', 'MKL'],
61
- ['b', 'MKL'],
62
- ['c', 'MK'],
63
- ]),
64
- relativeTo: 'a',
65
- colorAt: (_col, letter) => (letter === 'M' ? '#ff0000' : undefined),
66
- bg: '#000000',
67
- hover: '#00ff00',
68
- }
69
-
70
- const ids: Record<string, number> = { '#ff0000': 1, '#000000': 2, '#00ff00': 3 }
71
- const toPixel = (css: string) => ids[css]!
72
-
73
- test('one pixel per cell, reference matches and short rows', () => {
74
- const px = rasterPixels({
75
- spec,
76
- col0: 0,
77
- row0: 0,
78
- width: 3,
79
- height: 4,
80
- toPixel,
81
- })
82
-
83
- // the reference row itself keeps its scheme colors
84
- expect([...px.slice(0, 3)]).toEqual([1, 2, 2])
85
- // every cell of an identical row reads as a match
86
- expect([...px.slice(3, 6)]).toEqual([3, 3, 3])
87
- // past the end of a short row, and past the last row, stays transparent
88
- expect([...px.slice(6, 9)]).toEqual([3, 3, 0])
89
- expect([...px.slice(9, 12)]).toEqual([0, 0, 0])
90
- })
91
-
92
- test('sampling steps over columns and rows', () => {
93
- const px = rasterPixels({
94
- spec,
95
- col0: 0,
96
- row0: 0,
97
- width: 2,
98
- height: 2,
99
- colStep: 2,
100
- rowStep: 2,
101
- toPixel,
102
- })
103
- // the second sampled column falls past the end of the short row 'c'
104
- expect([...px]).toEqual([1, 2, 3, 0])
105
- })
106
-
107
- function make() {
108
- const model = MSAModelF().create({
109
- id: 'raster',
110
- type: 'MsaView',
111
- msaFormat: 'fasta',
112
- data: { msa: '>a\nMKLVIL\n>b\nMRLVIL\n>c\nMKLAIL' },
113
- })
114
- model.setWidth(1000)
115
- return model
116
- }
117
-
118
- function tilesFor(model: ReturnType<typeof make>) {
119
- drawn.length = 0
120
- const ctx = document.createElement('canvas').getContext('2d')!
121
- drawMsaRaster({ ctx, model, theme: theme(), offsetX: 0, offsetY: 0 })
122
- return [...drawn]
123
- }
124
-
125
- // only the two palette entries the raster reads
126
- const theme = () =>
127
- ({
128
- palette: {
129
- action: { hover: '#00ff00' },
130
- background: { default: '#ffffff' },
131
- },
132
- }) as never
133
-
134
- test('a zoom reuses the tiles, a recolor rebuilds them', () => {
135
- const model = make()
136
- const tile = tilesFor(model)[0]
137
- expect(tile).toBeDefined()
138
-
139
- model.setColWidth(3)
140
- model.setRowHeight(2)
141
- expect(tilesFor(model)[0]).toBe(tile)
142
-
143
- model.setColorSchemeName('clustalx_protein_dynamic')
144
- expect(tilesFor(model)[0]).not.toBe(tile)
145
- })
@@ -1,51 +0,0 @@
1
- import { expect, test } from 'vitest'
2
-
3
- import stateModelFactory from '../../model.ts'
4
- import { renderBoxFeatureCanvasBlock } from './renderBoxFeatureCanvasBlock.ts'
5
-
6
- import type { RenderCtx } from '../renderCtx.ts'
7
-
8
- const row = 'ACDEFGHIKLMNPQRSTVWY'.repeat(3)
9
-
10
- // only `human` carries the gene model; `mouse` is there to push it off the top
11
- // of the block
12
- const msa = `>mouse\n${row}\n>human\n${row}`
13
-
14
- const gff = `##gff-version 3
15
- human src exon 1 20 . . . ID=human.exon1;Name=exon-1
16
- human src exon 21 40 . . . ID=human.exon2;Name=exon-2
17
- human src exon 41 60 . . . ID=human.exon3;Name=exon-3`
18
-
19
- function drawnLabels() {
20
- const model = stateModelFactory().create({
21
- type: 'MsaView',
22
- data: { msa },
23
- })
24
- model.setWidth(1000)
25
- model.setRowHeight(20)
26
- // segment numbers are drawn in place of residue letters, never on top of them
27
- model.setDrawMsaLetters(false)
28
- model.applyGFFText(gff)
29
- expect(model.rowNames).toEqual(['mouse', 'human'])
30
-
31
- const labels: string[] = []
32
- const ctx = {
33
- font: '12px sans-serif',
34
- resetTransform() {},
35
- scale() {},
36
- translate() {},
37
- fillRect() {},
38
- strokeRect() {},
39
- measureText: (text: string) => ({ width: text.length * 6 }),
40
- fillText(text: string) {
41
- labels.push(text)
42
- },
43
- } as unknown as RenderCtx
44
-
45
- renderBoxFeatureCanvasBlock({ model, ctx, offsetX: 0, offsetY: 0 })
46
- return labels
47
- }
48
-
49
- test('segment numbers are drawn once each, even when row 0 has no gene model', () => {
50
- expect(drawnLabels()).toEqual(['1', '2', '3'])
51
- })