jbrowse-plugin-msaview 5.2.0 → 5.3.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 (84) hide show
  1. package/dist/MsaViewPanel/model.d.ts +25 -29
  2. package/dist/chunks/AboutDialog-447TIFAW.js +2 -0
  3. package/dist/chunks/{AboutDialog-IRBPUPJK.js.map → AboutDialog-447TIFAW.js.map} +4 -4
  4. package/dist/chunks/AnnotationFileDialog-S3N5EHHE.js +2 -0
  5. package/dist/chunks/AnnotationFileDialog-S3N5EHHE.js.map +7 -0
  6. package/dist/chunks/ExportSVGDialog-7ZHKKQ7W.js +2 -0
  7. package/dist/chunks/ExportSVGDialog-7ZHKKQ7W.js.map +7 -0
  8. package/dist/chunks/{FeatureDialog-ZBX3XQZ5.js → FeatureDialog-EEOGSLOG.js} +1 -1
  9. package/dist/chunks/{FeatureDialog-ZBX3XQZ5.js.map → FeatureDialog-EEOGSLOG.js.map} +1 -1
  10. package/dist/chunks/HelpDialog-TCWNBZOV.js +2 -0
  11. package/dist/chunks/HelpDialog-TCWNBZOV.js.map +7 -0
  12. package/dist/chunks/{LaunchMsaViewDialog-GJAUPGFC.js → LaunchMsaViewDialog-R6CNRASN.js} +2 -2
  13. package/dist/chunks/{LaunchMsaViewDialog-GJAUPGFC.js.map → LaunchMsaViewDialog-R6CNRASN.js.map} +1 -1
  14. package/dist/chunks/MetadataDialog-MNSI6NEW.js +2 -0
  15. package/dist/chunks/{MetadataDialog-KZWQFRF7.js.map → MetadataDialog-MNSI6NEW.js.map} +2 -2
  16. package/dist/chunks/MsaViewPanel-R2WAER5O.js +2 -0
  17. package/dist/chunks/{MsaViewPanel-RUZAKFCB.js.map → MsaViewPanel-R2WAER5O.js.map} +1 -1
  18. package/dist/chunks/{TrackInfoDialog-IFIG77WO.js → TrackInfoDialog-W2F77IPG.js} +2 -2
  19. package/dist/chunks/{TrackInfoDialog-IFIG77WO.js.map → TrackInfoDialog-W2F77IPG.js.map} +1 -1
  20. package/dist/chunks/TreeNodeInfoDialog-T5XMPG3R.js +2 -0
  21. package/dist/chunks/{TreeNodeInfoDialog-VRCVIF26.js.map → TreeNodeInfoDialog-T5XMPG3R.js.map} +2 -2
  22. package/dist/chunks/chunk-6EOYBBT4.js +2 -0
  23. package/dist/chunks/chunk-6EOYBBT4.js.map +7 -0
  24. package/dist/chunks/chunk-A63PUWQZ.js +6 -0
  25. package/dist/chunks/chunk-A63PUWQZ.js.map +7 -0
  26. package/dist/chunks/{chunk-NI3VGKQP.js → chunk-BAM67QHH.js} +2 -2
  27. package/dist/chunks/chunk-CSCUNTGJ.js +18 -0
  28. package/dist/chunks/chunk-CSCUNTGJ.js.map +7 -0
  29. package/dist/chunks/chunk-DEFUNIWW.js +8 -0
  30. package/dist/chunks/chunk-DEFUNIWW.js.map +7 -0
  31. package/dist/chunks/{chunk-YOTSFJMU.js → chunk-ERCMNTEQ.js} +1 -1
  32. package/dist/chunks/{chunk-YOTSFJMU.js.map → chunk-ERCMNTEQ.js.map} +1 -1
  33. package/dist/chunks/{chunk-GDFVLZYX.js → chunk-FEUZKN5V.js} +2 -2
  34. package/dist/chunks/{chunk-GDFVLZYX.js.map → chunk-FEUZKN5V.js.map} +1 -1
  35. package/dist/chunks/{chunk-GIHMPOCO.js → chunk-JF6CW6MO.js} +1 -1
  36. package/dist/chunks/{chunk-GIHMPOCO.js.map → chunk-JF6CW6MO.js.map} +1 -1
  37. package/dist/chunks/chunk-K55ZVN73.js +5 -0
  38. package/dist/chunks/chunk-K55ZVN73.js.map +7 -0
  39. package/dist/chunks/chunk-L6CBIH6H.js +2 -0
  40. package/dist/chunks/chunk-L6CBIH6H.js.map +7 -0
  41. package/dist/chunks/{chunk-F3EC6OCO.js → chunk-NWHZOZMG.js} +1 -1
  42. package/dist/chunks/{chunk-F3EC6OCO.js.map → chunk-NWHZOZMG.js.map} +1 -1
  43. package/dist/chunks/chunk-OVAXNTPN.js +2 -0
  44. package/dist/chunks/chunk-OVAXNTPN.js.map +7 -0
  45. package/dist/chunks/chunk-TSHN6J7U.js +2 -0
  46. package/dist/chunks/chunk-TSHN6J7U.js.map +7 -0
  47. package/dist/chunks/{chunk-H6IQBAW7.js → chunk-WAPIOD25.js} +5 -5
  48. package/dist/chunks/{chunk-H6IQBAW7.js.map → chunk-WAPIOD25.js.map} +1 -1
  49. package/dist/chunks/chunk-XVNCZQMR.js +2 -0
  50. package/dist/chunks/{chunk-ZCT7RD24.js.map → chunk-XVNCZQMR.js.map} +1 -1
  51. package/dist/chunks/{dist-CMWKVHC7.js → dist-GXYZN4ZR.js} +2 -2
  52. package/dist/chunks/{dist-CMWKVHC7.js.map → dist-GXYZN4ZR.js.map} +3 -3
  53. package/dist/chunks/dist-N4ZJK63Q.js +2 -0
  54. package/dist/chunks/{model-VE7IYWNU.js → model-TCPB6WNJ.js} +2 -2
  55. package/dist/chunks/{model-VE7IYWNU.js.map → model-TCPB6WNJ.js.map} +1 -1
  56. package/dist/chunks/renderToSvg-53FEV6IJ.js +2 -0
  57. package/dist/jbrowse-plugin-msaview.esm.js +2 -2
  58. package/dist/jbrowse-plugin-msaview.esm.js.map +1 -1
  59. package/dist/version.d.ts +1 -1
  60. package/dist/version.js +1 -1
  61. package/package.json +2 -2
  62. package/src/version.ts +1 -1
  63. package/dist/chunks/AboutDialog-IRBPUPJK.js +0 -2
  64. package/dist/chunks/AnnotationFileDialog-FCYYZ4JN.js +0 -2
  65. package/dist/chunks/AnnotationFileDialog-FCYYZ4JN.js.map +0 -7
  66. package/dist/chunks/ExportSVGDialog-TYYPI6VB.js +0 -2
  67. package/dist/chunks/ExportSVGDialog-TYYPI6VB.js.map +0 -7
  68. package/dist/chunks/MetadataDialog-KZWQFRF7.js +0 -2
  69. package/dist/chunks/MsaViewPanel-RUZAKFCB.js +0 -2
  70. package/dist/chunks/TreeNodeInfoDialog-VRCVIF26.js +0 -2
  71. package/dist/chunks/chunk-F726IWCW.js +0 -2
  72. package/dist/chunks/chunk-F726IWCW.js.map +0 -7
  73. package/dist/chunks/chunk-NMYD2GWF.js +0 -18
  74. package/dist/chunks/chunk-NMYD2GWF.js.map +0 -7
  75. package/dist/chunks/chunk-QQ5LZUIO.js +0 -11
  76. package/dist/chunks/chunk-QQ5LZUIO.js.map +0 -7
  77. package/dist/chunks/chunk-QUWPHTZQ.js +0 -2
  78. package/dist/chunks/chunk-QUWPHTZQ.js.map +0 -7
  79. package/dist/chunks/chunk-ZCT7RD24.js +0 -2
  80. package/dist/chunks/dist-R73J3CC3.js +0 -2
  81. package/dist/chunks/renderToSvg-VDXAB7TT.js +0 -2
  82. /package/dist/chunks/{chunk-NI3VGKQP.js.map → chunk-BAM67QHH.js.map} +0 -0
  83. /package/dist/chunks/{dist-R73J3CC3.js.map → dist-N4ZJK63Q.js.map} +0 -0
  84. /package/dist/chunks/{renderToSvg-VDXAB7TT.js.map → renderToSvg-53FEV6IJ.js.map} +0 -0
@@ -0,0 +1,7 @@
1
+ {
2
+ "version": 3,
3
+ "sources": ["global-externals:@jbrowse/core/ui/ErrorBoundary", "global-externals:@jbrowse/core/ui/BaseTooltip", "global-externals:@jbrowse/core/util/useMeasure", "global-externals:@jbrowse/core/ui/CascadingMenuButton", "global-externals:@mui/material/styles", "global-externals:@jbrowse/core/util/types/mst", "global-externals:@jbrowse/core/ui/theme", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/headlessRenderEnv.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/expandSpec.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/Loading.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/MSAView.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/ResizeHandles.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/Track.tsx", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/ArrowDropDown.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/useWheelScroll.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/wheelZoom.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/msaKeys.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tracks/TrackBlocks.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/useCanvasAutorun.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tracks/TrackTooltipContent.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/selectionDrag.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/useHoverAnchor.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tracks/useTrackHover.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/VerticalScrollbar.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/Header.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/StatusMessage.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/ColorSchemeMenu.tsx", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Palette.mjs", "../../node_modules/.pnpm/@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3.0_react@19.3.0_supports-co_f865fc377d8bf48f45a9781b96c6eea4/node_modules/@mui/material/colors/red.mjs", "../../node_modules/.pnpm/@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3.0_react@19.3.0_supports-co_f865fc377d8bf48f45a9781b96c6eea4/node_modules/@mui/material/colors/blue.mjs", "../../node_modules/.pnpm/@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3.0_react@19.3.0_supports-co_f865fc377d8bf48f45a9781b96c6eea4/node_modules/@mui/material/colors/green.mjs", "../../node_modules/.pnpm/@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3.0_react@19.3.0_supports-co_f865fc377d8bf48f45a9781b96c6eea4/node_modules/@mui/material/colors/orange.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/colorSchemes.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/FileMenu.tsx", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/AccountTree.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Assignment.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/FolderOpen.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Menu.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/PhotoCamera.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/getAnnotationsMenu.ts", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/FilterAlt.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/MenuBook.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Sort.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Visibility.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/GappynessSlider.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/GoToBox.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/goTo.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/HeaderInfoArea.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/LoadWarnings.tsx", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Warning.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/MSASettingsMenu.tsx", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Tune.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/ScrollZoomIcons.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/settingsMenuItems.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/MultiAlignmentSelector.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/SelectionMenu.tsx", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/Clear.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/ContentCopy.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/ZoomIn.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/TreeSettingsMenu.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/UnshareableDataWarning.tsx", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/LinkOff.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/header/ZoomControls.tsx", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/FitScreen.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/RestartAlt.mjs", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/ZoomOut.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/minimap/Minimap.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/MSAPanel.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/AnnotationLegend.tsx", "../../node_modules/.pnpm/@mui+icons-material@9.4.0_@mui+material@9.4.0_@emotion+react@11.14.0_@types+react@19.3._3766ec55733e6b150ee672ad270cc236/node_modules/@mui/icons-material/ExpandLess.mjs", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/MSACanvas.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/Loading.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/MSACanvasBlock.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/useMsaBlockMouse.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/MSAMouseoverCanvas.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/renderMSAMouseover.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/rowpanels/RowPanelHeaders.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/rowpanels/RowPanels.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/rowpanels/RowPanelBlock.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/featureFields.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/TreeOverview.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/TreePanel.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/TreeCanvas.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/CladeLabels.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/TreeCanvasBlock.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/TreeMenu.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/useTreeHover.ts", "../../node_modules/.pnpm/flatqueue@3.1.0/node_modules/flatqueue/index.js", "../../node_modules/.pnpm/flatbush@4.6.2/node_modules/flatbush/index.js", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/clickMap.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/renderTreeMouseover.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/TreeRuler.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/import/ImportForm.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/import/ImportFormExamples.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/import/data/seq2.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/import/util.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/MSAViewer.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/model.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/blockFasta.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/calculateBlocks.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/clustalX.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/columnStats.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/msa/packDomainLanes.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/components/tree/scaleBar.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/ggplotPalettes.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/createPaletteMap.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/exportFileName.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/featuresLayer.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/fetchUtils.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/flatToTree.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/model/DataModel.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/model/DialogQueue.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/model/msaModel.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/stripDefault.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/model/treeModel.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/neighborJoining.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/parseAsn1.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/propertyConservation.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/rerootTree.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/rowCoordinateCalculations.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/scales.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/seqPosToGlobalCol.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/tipLabels.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/writeNewick.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/wuss.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/viewerSnapshot.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/mount.tsx", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/element.ts", "../../node_modules/.pnpm/react-msaview@9.1.0_3e54acfe76b6ad0d26e91cd532b7f775/node_modules/react-msaview/src/useMsaSvgFigure.ts"],
4
+ "sourcesContent": ["module.exports = JBrowseExports[\"@jbrowse/core/ui/ErrorBoundary\"];", "module.exports = JBrowseExports[\"@jbrowse/core/ui/BaseTooltip\"];", "module.exports = JBrowseExports[\"@jbrowse/core/util/useMeasure\"];", "module.exports = JBrowseExports[\"@jbrowse/core/ui/CascadingMenuButton\"];", "module.exports = JBrowseExports[\"@mui/material/styles\"];", "module.exports = JBrowseExports[\"@jbrowse/core/util/types/mst\"];", "module.exports = JBrowseExports[\"@jbrowse/core/ui/theme\"];", "/**\n * DOM shims for driving `renderToSvg` outside a browser -- the SVG-export\n * tests, the README figure generator, and react-msaview-cli all need them.\n *\n * jsdom implements neither DOMMatrix nor a canvas 2D context, and\n * `@jbrowse/svgcanvas` needs both: it tracks the current transform as a real\n * matrix, and the renderers ask a throwaway canvas to measure text.\n *\n * The matrix stub has to accept the ARRAY constructor. svgcanvas normalizes\n * every transform through `new DOMMatrix([a, b, c, d, e, f])`, so a stub that\n * only takes six positional arguments silently binds the whole array to `a` and\n * leaves the rest undefined -- every emitted transform then carries `NaN` in its\n * x components, which no assertion on a drawn x-position can survive.\n */\nimport { CHAR_WIDTH_RATIO } from './measureTextCanvas.ts'\n\nclass HeadlessDOMMatrix {\n a: number\n b: number\n c: number\n d: number\n e: number\n f: number\n\n constructor(init?: number[]) {\n const [a = 1, b = 0, c = 0, d = 1, e = 0, f = 0] = init ?? []\n this.a = a\n this.b = b\n this.c = c\n this.d = d\n this.e = e\n this.f = f\n }\n\n multiply(o: HeadlessDOMMatrix) {\n return new HeadlessDOMMatrix([\n this.a * o.a + this.c * o.b,\n this.b * o.a + this.d * o.b,\n this.a * o.c + this.c * o.d,\n this.b * o.c + this.d * o.d,\n this.a * o.e + this.c * o.f + this.e,\n this.b * o.e + this.d * o.f + this.f,\n ])\n }\n\n translate(x: number, y = 0) {\n return this.multiply(new HeadlessDOMMatrix([1, 0, 0, 1, x, y]))\n }\n\n scale(x: number, y = x) {\n return this.multiply(new HeadlessDOMMatrix([x, 0, 0, y, 0, 0]))\n }\n}\n\nclass HeadlessDOMPoint {\n constructor(\n public x = 0,\n public y = 0,\n ) {}\n\n matrixTransform(m: HeadlessDOMMatrix) {\n return new HeadlessDOMPoint(\n m.a * this.x + m.c * this.y + m.e,\n m.b * this.x + m.d * this.y + m.f,\n )\n }\n}\n\n/**\n * Install the shims, into `globalThis` by default. A Node caller that builds\n * its own jsdom passes that window instead, because Node has no global\n * HTMLCanvasElement to patch.\n *\n * Without `measureContext`, `measureText` reports 0.6em per character, close\n * enough to a real sans-serif average for layout and exactly predictable: a\n * test can compute the width a renderer will see. A caller with a real canvas,\n * such as react-msaview-cli with @napi-rs/canvas, passes one of its 2D\n * contexts as `measureContext` to measure with the installed fonts.\n *\n * `contextExtras` adds to the context a test hands out -- the raster test\n * supplies the ImageData methods that make the export take its image path.\n */\nexport function installHeadlessRenderEnv(\n win: unknown = globalThis,\n contextExtras: Partial<CanvasRenderingContext2D> = {},\n measureContext?: MeasureContext,\n) {\n const g = globalThis as Record<string, unknown>\n g.DOMMatrix = HeadlessDOMMatrix\n g.DOMPoint = HeadlessDOMPoint\n const canvas = (win as { HTMLCanvasElement: typeof HTMLCanvasElement })\n .HTMLCanvasElement\n canvas.prototype.getContext = function () {\n let font = '10px sans-serif'\n return Object.assign(\n {\n get font() {\n return font\n },\n set font(v: string) {\n font = v\n },\n measureText: (t: string) => {\n if (measureContext) {\n measureContext.font = font\n return { width: measureContext.measureText(t).width }\n }\n return {\n width:\n t.length * (Number.parseFloat(font) || 10) * CHAR_WIDTH_RATIO,\n }\n },\n },\n contextExtras,\n ) as unknown as CanvasRenderingContext2D\n } as unknown as typeof HTMLCanvasElement.prototype.getContext\n}\n\nexport interface MeasureContext {\n font: string\n measureText(text: string): { width: number }\n}\n", "import type { ColumnTrackSpec, Highlight, Region } from './types.ts'\n\n/**\n * `row: null` opts one entry out of the spec's `query` row, back to alignment\n * columns.\n */\ntype RowChoice = { row?: string | null }\n\nexport type HighlightShorthand =\n | number\n | string\n | (Omit<Highlight, 'row'> & RowChoice)\n\nexport type RegionShorthand = string | (Omit<Region, 'row'> & RowChoice)\n\nexport type ColumnTrackShorthand = Omit<\n ColumnTrackSpec,\n 'id' | 'kind' | 'row'\n> &\n RowChoice & {\n id?: string\n kind?: ColumnTrackSpec['kind']\n /** the 1-based position `values` or `data` begins at */\n start?: number\n }\n\n/**\n * The short forms a hand-written or generated link can use. Every long form\n * passes through unchanged, so a snapshot is also a valid spec.\n */\nexport interface MsaSpec {\n /**\n * The row the spec is about: sets `relativeTo`, and is the `row` of every\n * highlight, region and column track that names none\n */\n query?: string\n /** a url, or the alignment itself when it spans more than one line */\n msa?: string\n /** a url, or a newick string when it starts with \"(\" */\n tree?: string\n highlights?: HighlightShorthand[]\n region?: RegionShorthand\n columnTracks?: ColumnTrackShorthand[]\n [key: string]: unknown\n}\n\n/**\n * The label a single-residue shorthand highlight gets, filled in from the\n * sequence when drawn: `175` on a row reading R there becomes \"R175\".\n */\nexport const residueLabel = '{residue}{position}'\n\nconst span = /^(\\d+)(?:-(\\d+))?(?:\\s+(.+))?$/\n\nfunction parseSpan(text: string, what: string) {\n const match = span.exec(text.trim())\n if (!match) {\n throw new Error(\n `${what} \"${text}\" is not \"start\", \"start-end\" or either followed by a label`,\n )\n }\n const a = Number(match[1])\n const b = match[2] === undefined ? a : Number(match[2])\n return { start: Math.min(a, b), end: Math.max(a, b), label: match[3] }\n}\n\nfunction withRow<T extends RowChoice>(entry: T, query?: string) {\n const { row, ...rest } = entry\n const resolved = row === undefined ? query : (row ?? undefined)\n return resolved === undefined ? rest : { ...rest, row: resolved }\n}\n\nfunction expandHighlight(entry: HighlightShorthand, query?: string) {\n if (typeof entry === 'object') {\n return (\n entry.rows\n ? entry\n : withRow(entry, entry.start === undefined ? undefined : query)\n ) as Highlight\n }\n const { start, end, label } = parseSpan(String(entry), 'highlight')\n const single = start === end && query !== undefined\n return {\n ...(query === undefined ? {} : { row: query }),\n start,\n end,\n ...(label ? { label } : single ? { label: residueLabel } : {}),\n }\n}\n\nfunction expandRegion(region: RegionShorthand, query?: string) {\n if (typeof region === 'string') {\n const { start, end } = parseSpan(region, 'region')\n const parsed: Omit<Region, 'row'> & RowChoice = { start, end }\n return withRow(parsed, query) as Region\n }\n return withRow(region, query) as Region\n}\n\nfunction slug(name: string) {\n return name\n .toLowerCase()\n .replaceAll(/[^a-z0-9]+/g, '-')\n .replaceAll(/^-|-$/g, '')\n}\n\nfunction kindOf(track: ColumnTrackShorthand) {\n if (track.kind) {\n return track.kind\n }\n if (track.values) {\n return 'bar'\n }\n if (track.data !== undefined) {\n return 'text'\n }\n if (track.arcs) {\n return 'arc'\n }\n throw new Error(\n `column track \"${track.name}\" has no values, data or arcs to take its kind from`,\n )\n}\n\nfunction expandTrack(\n track: ColumnTrackShorthand,\n query: string | undefined,\n ids: Set<string>,\n): ColumnTrackSpec {\n const { start, ...rest } = track\n const pad = start && start > 1 ? start - 1 : 0\n let id = track.id ?? (slug(track.name) || 'track')\n for (let n = 2; !track.id && ids.has(id); n++) {\n id = `${slug(track.name) || 'track'}-${n}`\n }\n ids.add(id)\n return {\n ...(withRow(rest, query) as Omit<ColumnTrackSpec, 'id' | 'kind'>),\n id,\n kind: kindOf(track),\n ...(pad && track.values\n ? { values: [...Array<number>(pad).fill(0), ...track.values] }\n : {}),\n ...(pad && track.data !== undefined\n ? { data: ' '.repeat(pad) + track.data }\n : {}),\n }\n}\n\nfunction isInlineMsa(msa: string) {\n return msa.includes('\\n')\n}\n\nfunction isInlineTree(tree: string) {\n return tree.trimStart().startsWith('(')\n}\n\nfunction uri(location: string) {\n return { uri: location, locationType: 'UriLocation' as const }\n}\n\n/**\n * Expand the short forms of an MsaView spec into the snapshot the model takes.\n * Idempotent, and a no-op on a spec that uses none of them.\n */\nexport function expandSpec(spec: MsaSpec): Record<string, unknown> {\n const { query, msa, tree, highlights, region, columnTracks, ...rest } = spec\n const data = {\n ...(rest.data as Record<string, unknown> | undefined),\n ...(msa !== undefined && isInlineMsa(msa) ? { msa } : {}),\n ...(tree !== undefined && isInlineTree(tree) ? { tree } : {}),\n }\n const ids = new Set(\n (columnTracks ?? []).map(t => t.id).filter(id => id !== undefined),\n )\n return {\n ...rest,\n ...(msa !== undefined && !isInlineMsa(msa)\n ? { msaFilehandle: uri(msa) }\n : {}),\n ...(tree !== undefined && !isInlineTree(tree)\n ? { treeFilehandle: uri(tree) }\n : {}),\n ...(Object.keys(data).length > 0 ? { data } : {}),\n ...(query !== undefined && rest.relativeTo === undefined\n ? { relativeTo: query }\n : {}),\n ...(highlights\n ? { highlights: highlights.map(h => expandHighlight(h, query)) }\n : {}),\n ...(region === undefined ? {} : { region: expandRegion(region, query) }),\n ...(columnTracks\n ? { columnTracks: columnTracks.map(t => expandTrack(t, query, ids)) }\n : {}),\n }\n}\n", "import React from 'react'\n\nimport { ErrorMessage } from '@jbrowse/core/ui'\nimport { ErrorBoundary } from '@jbrowse/core/ui/ErrorBoundary'\nimport { Button } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport MSAView from './MSAView.tsx'\nimport StatusMessage from './StatusMessage.tsx'\nimport ImportForm from './import/ImportForm.tsx'\n\nimport type { MsaViewModel } from '../model.ts'\n\nconst Reset = observer(function ({\n model,\n error,\n}: {\n model: MsaViewModel\n error: unknown\n}) {\n return (\n <div>\n <ErrorMessage error={error} />\n {model.importForm ? (\n <Button\n variant=\"contained\"\n color=\"primary\"\n onClick={() => {\n model.reset()\n }}\n >\n Return to import form\n </Button>\n ) : null}\n </div>\n )\n})\n\nconst Loading = observer(function ({ model }: { model: MsaViewModel }) {\n const {\n isLoading,\n dataInitialized,\n data,\n error,\n resetCount,\n msaFilehandle,\n treeFilehandle,\n importForm,\n } = model\n const hasData = !!(data.msa || data.tree)\n // a failed load keeps its filehandle, so the error outranks the spinner\n const loading = !error && !!(msaFilehandle || treeFilehandle || isLoading)\n\n return (\n <div>\n {/* keyed on the reset counter: the boundary holds the error it caught\n until it is remounted, so without this \"Return to import form\" put\n the model back and left the error screen up */}\n <ErrorBoundary\n key={resetCount}\n FallbackComponent={e => <Reset model={model} error={e.error} />}\n >\n {dataInitialized ? (\n isLoading ? (\n <StatusMessage model={model} variant=\"page\" />\n ) : (\n <MSAView model={model} />\n )\n ) : hasData ? (\n <Reset model={model} error={error} />\n ) : (\n <>\n {loading ? <StatusMessage model={model} variant=\"page\" /> : null}\n {importForm ? (\n <div style={{ display: loading ? 'none' : undefined }}>\n <ImportForm model={model} />\n </div>\n ) : error ? (\n <ErrorMessage error={error} />\n ) : null}\n </>\n )}\n </ErrorBoundary>\n </div>\n )\n})\n\nexport default Loading\n", "import React, { Suspense } from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport {\n HorizontalResizeHandle,\n VerticalResizeHandle,\n} from './ResizeHandles.tsx'\nimport Track from './Track.tsx'\nimport VerticalScrollbar from './VerticalScrollbar.tsx'\nimport Header from './header/Header.tsx'\nimport Minimap from './minimap/Minimap.tsx'\nimport MSAPanel from './msa/MSAPanel.tsx'\nimport { clickColor, hoverColor, selectionFill } from './overlayColors.ts'\nimport RowPanelHeaders from './rowpanels/RowPanelHeaders.tsx'\nimport RowPanels from './rowpanels/RowPanels.tsx'\nimport TreeOverview from './tree/TreeOverview.tsx'\nimport TreePanel from './tree/TreePanel.tsx'\nimport TreeRuler from './tree/TreeRuler.tsx'\n\nimport type { MsaViewModel } from '../model.ts'\n\n// The band above the panels: the tree overview and scale bar, the strip\n// headers, and the minimap over the alignment. The spacer stands in for the\n// resize handle, so the minimap starts exactly where the alignment canvas does.\nconst TopArea = observer(function ({ model }: { model: MsaViewModel }) {\n const { showHorizontalScrollbar, showTreeOverview, resizeHandleWidth } = model\n return (\n <div style={{ display: 'flex' }}>\n <div style={{ flexShrink: 0 }}>\n {showTreeOverview ? <TreeOverview model={model} /> : null}\n <TreeRuler model={model} />\n </div>\n <RowPanelHeaders model={model} />\n <div style={{ width: resizeHandleWidth, flexShrink: 0 }} />\n {showHorizontalScrollbar ? <Minimap model={model} /> : null}\n </div>\n )\n})\n\nconst TrackColumnIndicator = observer(function ({\n model,\n}: {\n model: MsaViewModel\n}) {\n const {\n mouseCol,\n mouseClickCol,\n colWidth,\n scrollX,\n effectiveTreeAreaWidth,\n rowPanelsWidth,\n resizeHandleWidth,\n totalTrackAreaHeight,\n msaCanvasWidth,\n resolvedSelection,\n } = model\n\n // the selected columns, the hovered column, then the pinned one, matching\n // the alignment's own overlay\n const bands = [\n {\n start: resolvedSelection?.startCol,\n end: resolvedSelection?.endCol,\n color: selectionFill,\n },\n { start: mouseCol, end: mouseCol, color: hoverColor },\n { start: mouseClickCol, end: mouseClickCol, color: clickColor },\n ]\n\n return (\n <div\n style={{\n position: 'absolute',\n left: effectiveTreeAreaWidth + rowPanelsWidth + resizeHandleWidth,\n top: 0,\n width: msaCanvasWidth,\n height: totalTrackAreaHeight,\n overflow: 'hidden',\n pointerEvents: 'none',\n }}\n >\n {bands.map(({ start, end, color }) =>\n start === undefined || end === undefined ? null : (\n <div\n key={color}\n style={{\n position: 'absolute',\n left: start * colWidth + scrollX,\n top: 0,\n width: (end - start + 1) * colWidth,\n height: totalTrackAreaHeight,\n backgroundColor: color,\n zIndex: 100,\n }}\n />\n ),\n )}\n </div>\n )\n})\n\nconst TrackArea = observer(function ({ model }: { model: MsaViewModel }) {\n const { turnedOnTracks } = model\n if (turnedOnTracks.length === 0) {\n return null\n }\n return (\n <div style={{ position: 'relative' }}>\n <TrackColumnIndicator model={model} />\n {turnedOnTracks.map(track => (\n <Track key={track.model.id} model={model} track={track} />\n ))}\n </div>\n )\n})\n\nconst MainArea = observer(function ({ model }: { model: MsaViewModel }) {\n const { showVerticalScrollbar } = model\n\n return (\n <div style={{ display: 'flex' }}>\n <TreePanel model={model} />\n <RowPanels model={model} />\n <VerticalResizeHandle model={model} />\n <MSAPanel model={model} />\n {showVerticalScrollbar ? <VerticalScrollbar model={model} /> : null}\n </div>\n )\n})\n\nconst View = observer(function ({ model }: { model: MsaViewModel }) {\n return (\n <div style={{ position: 'relative' }}>\n <TopArea model={model} />\n <TrackArea model={model} />\n <MainArea model={model} />\n </div>\n )\n})\n\nconst MSAView = observer(function ({ model }: { model: MsaViewModel }) {\n const { height, hideHeader, viewInitialized, DialogComponent, DialogProps } =\n model\n\n return (\n <div>\n {viewInitialized ? (\n <>\n <div style={{ height, overflow: 'clip' }}>\n {hideHeader ? null : <Header model={model} />}\n <View model={model} />\n </div>\n <HorizontalResizeHandle model={model} />\n\n {DialogComponent ? (\n <Suspense fallback={null}>\n <DialogComponent {...DialogProps} />\n </Suspense>\n ) : null}\n </>\n ) : null}\n </div>\n )\n})\n\nexport default MSAView\n", "import React, { useCallback } from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport DragHandle from './DragHandle.tsx'\n\nimport type { MsaViewModel } from '../model.ts'\nimport type { BasicTrack } from '../types.ts'\n\nconst minViewHeight = 50\n\nexport const VerticalResizeHandle = observer(function ({\n model,\n}: {\n model: MsaViewModel\n}) {\n const onDrag = useCallback(\n (delta: number, startWidth: number) => {\n model.setTreeAreaWidth(\n Math.min(\n Math.max(0, startWidth + delta),\n model.width - model.resizeHandleWidth,\n ),\n )\n },\n [model],\n )\n return (\n <DragHandle\n axis=\"x\"\n variant=\"resizer\"\n getStart={() => model.effectiveTreeAreaWidth}\n onDrag={onDrag}\n style={{ width: model.resizeHandleWidth }}\n />\n )\n})\n\nexport const HorizontalResizeHandle = observer(function ({\n model,\n}: {\n model: MsaViewModel\n}) {\n const onDrag = useCallback(\n (delta: number, startHeight: number) => {\n model.setHeight(Math.max(minViewHeight, startHeight + delta))\n },\n [model],\n )\n return (\n <DragHandle\n axis=\"y\"\n variant=\"resizer\"\n getStart={() => model.height}\n onDrag={onDrag}\n style={{ width: '100%', height: model.resizeHandleWidth }}\n />\n )\n})\n\nexport const TrackResizeHandle = observer(function ({\n model,\n track,\n}: {\n model: MsaViewModel\n track: BasicTrack\n}) {\n const { id, heightKey, height } = track.model\n // tracks sharing a key resize together, so only the last turned-on one of\n // them carries the divider: a second between conservation and property\n // conservation would move the pair this one already moves. The drag divides\n // across the group, so its bottom edge follows the cursor rather than half\n const siblings = model.turnedOnTracks.filter(\n t => t.model.heightKey === heightKey,\n )\n const count = siblings.length\n const onDrag = useCallback(\n (delta: number, startHeight: number) => {\n if (heightKey) {\n model.setTrackHeight(\n heightKey,\n Math.max(10, startHeight + delta / count),\n )\n }\n },\n [model, heightKey, count],\n )\n return heightKey && siblings.at(-1)?.model.id === id ? (\n <DragHandle\n axis=\"y\"\n variant=\"resizer\"\n getStart={() => height}\n onDrag={onDrag}\n style={{\n position: 'absolute',\n bottom: 0,\n left: 0,\n width: '100%',\n height: model.resizeHandleWidth,\n zIndex: 1,\n }}\n />\n ) : null\n})\n", "import React, { lazy, useCallback, useRef, useState } from 'react'\n\nimport BaseTooltip from '@jbrowse/core/ui/BaseTooltip'\nimport { makeStyles } from '@jbrowse/core/util/tss-react'\nimport ArrowDropDownIcon from '@mui/icons-material/ArrowDropDown'\nimport { IconButton, Menu, MenuItem } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { useWheelScroll } from '../useWheelScroll.ts'\nimport { onMsaKey } from './msa/msaKeys.ts'\nimport TrackBlocks from './tracks/TrackBlocks.tsx'\nimport TrackTooltipContent from './tracks/TrackTooltipContent.tsx'\nimport { useTrackHover } from './tracks/useTrackHover.ts'\n\nimport type { MsaViewModel } from '../model.ts'\nimport type { BasicTrack } from '../types.ts'\n\nconst TrackInfoDialog = lazy(() => import('./dialogs/TrackInfoDialog.tsx'))\n\nconst useStyles = makeStyles()(theme => ({\n button: {\n padding: 0,\n },\n // a hairline under every track but the last, across the labels as well as\n // the alignment. The divider a track's resize handle draws covers only the\n // alignment, and tracks sharing a height have no handle between them. Inset,\n // so the line costs no layout height: totalTrackAreaHeight sums the model's\n // heights, and the column indicator is drawn against that sum\n row: {\n display: 'flex',\n '&:not(:last-child)': {\n boxShadow: `inset 0 -1px 0 ${theme.palette.divider}`,\n },\n },\n}))\n\nconst TrackLabel = observer(function TrackLabel({\n model,\n track,\n}: {\n model: MsaViewModel\n track: BasicTrack\n}) {\n const [anchorEl, setAnchorEl] = useState<HTMLButtonElement>()\n const closeMenu = () => {\n setAnchorEl(undefined)\n }\n const { drawLabels, fontSize, effectiveTreeAreaWidth: width } = model\n const {\n model: { name, height },\n } = track\n const { classes } = useStyles()\n const trackLabelHeight = Math.min(height, fontSize)\n\n return (\n // a flex row, not inline text: zooming in grows fontSize against a tree\n // area the leaf labels sized, and a name that wrapped took its menu button\n // onto a second line, under the next track's button\n <div\n style={{\n width,\n height,\n flexShrink: 0,\n display: 'flex',\n alignItems: 'flex-start',\n justifyContent: 'flex-end',\n gap: 2,\n fontSize: trackLabelHeight,\n }}\n >\n <span\n title={name}\n style={{\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n }}\n >\n {drawLabels ? name : ''}\n </span>\n <IconButton\n className={classes.button}\n aria-label={`${name} track menu`}\n style={{\n width: trackLabelHeight,\n height: trackLabelHeight,\n flexShrink: 0,\n }}\n onClick={event => {\n setAnchorEl(event.currentTarget)\n }}\n >\n <ArrowDropDownIcon />\n </IconButton>\n {anchorEl ? (\n <Menu\n anchorEl={anchorEl}\n transitionDuration={0}\n open\n onClose={() => {\n closeMenu()\n }}\n >\n <MenuItem\n dense\n onClick={() => {\n model.toggleTrack(track.model.id)\n closeMenu()\n }}\n >\n Hide track\n </MenuItem>\n <MenuItem\n dense\n onClick={() => {\n model.queueDialog(onClose => [\n TrackInfoDialog,\n { onClose, model: track.model },\n ])\n closeMenu()\n }}\n >\n Get info\n </MenuItem>\n </Menu>\n ) : null}\n </div>\n )\n})\n\nconst Track = observer(function ({\n model,\n track,\n}: {\n model: MsaViewModel\n track: BasicTrack\n}) {\n const { resizeHandleWidth, rowPanelsWidth, showColumnStats } = model\n const {\n model: { height },\n } = track\n const ref = useRef<HTMLDivElement>(null)\n const onScrollX = useCallback(\n (d: number) => {\n model.doScrollX(d)\n },\n [model],\n )\n useWheelScroll({ ref, onScrollX })\n const { classes } = useStyles()\n const { anchor, onMouseMove, onMouseDown, onMouseLeave } = useTrackHover({\n model,\n tooltip: showColumnStats,\n })\n\n return (\n <div className={classes.row} style={{ height }}>\n <TrackLabel model={model} track={track} />\n {/* the row panels are row space, so a track leaves their column empty\n and starts where the alignment canvas does */}\n <div\n style={{ width: rowPanelsWidth + resizeHandleWidth, flexShrink: 0 }}\n />\n <div\n ref={ref}\n data-testid={`track_${track.model.id}`}\n tabIndex={-1}\n style={{ outline: 'none' }}\n onKeyDown={event => {\n if (onMsaKey(model, event)) {\n event.preventDefault()\n }\n }}\n onMouseMove={event => {\n if (ref.current) {\n onMouseMove(event, ref.current)\n }\n }}\n onMouseDown={event => {\n if (ref.current) {\n onMouseDown(event, ref.current)\n }\n }}\n onMouseLeave={() => {\n onMouseLeave()\n }}\n >\n <TrackBlocks model={model} track={track} />\n {anchor ? (\n <BaseTooltip clientPoint={anchor.clientPoint}>\n <TrackTooltipContent\n model={model}\n track={track}\n col={anchor.value}\n />\n </BaseTooltip>\n ) : null}\n </div>\n </div>\n )\n})\n\nexport default Track\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"m7 10 5 5 5-5z\"\n}), 'ArrowDropDown');", "import { useEffect, useRef, useState } from 'react'\n\nimport {\n SCROLL_ZOOM_DIVISOR,\n getZoomNormalizer,\n normalizeWheelDelta,\n zoomFactorFromAccum,\n} from './wheelZoom.ts'\n\nexport function useWheelScroll({\n ref,\n onScrollX,\n onScrollY,\n onZoom,\n scrollZoom,\n}: {\n ref: React.RefObject<HTMLDivElement | null>\n onScrollX?: (delta: number) => void\n onScrollY?: (delta: number) => void\n onZoom?: (scaleFactor: number, offsetX: number, offsetY: number) => void\n scrollZoom?: boolean\n}) {\n const scheduled = useRef(false)\n const zoomScheduled = useRef(false)\n const deltaX = useRef(0)\n const deltaY = useRef(0)\n const zoomAccum = useRef(0)\n const zoomX = useRef(0)\n const zoomY = useRef(0)\n const lastZoomTime = useRef<number | null>(null)\n const prevX = useRef(0)\n const prevY = useRef(0)\n const [mouseDragging, setMouseDragging] = useState(false)\n\n useEffect(() => {\n const curr = ref.current\n if (!curr) {\n return\n }\n function onWheel(event: WheelEvent) {\n // ctrlKey is also set by trackpad pinch gestures on all platforms. when\n // scrollZoom is on, a plain vertical-dominant wheel zooms too; holding\n // shift is the escape hatch to pan instead.\n const isCtrlZoom = event.ctrlKey || event.metaKey\n const isScrollZoom =\n scrollZoom &&\n !event.shiftKey &&\n Math.abs(event.deltaY) >= Math.abs(event.deltaX)\n if (onZoom && (isCtrlZoom || isScrollZoom)) {\n const rect = curr!.getBoundingClientRect()\n // normalize away deltaMode (line/page), then divide by an adaptive\n // factor so fine pinches and coarse notches feel consistent\n const dY = normalizeWheelDelta(event.deltaY, event.deltaMode)\n const divisor = isCtrlZoom ? getZoomNormalizer(dY) : SCROLL_ZOOM_DIVISOR\n zoomAccum.current += dY / divisor\n zoomX.current = event.clientX - rect.left\n zoomY.current = event.clientY - rect.top\n if (!zoomScheduled.current) {\n zoomScheduled.current = true\n requestAnimationFrame(now => {\n const elapsed =\n lastZoomTime.current === null ? 16.67 : now - lastZoomTime.current\n lastZoomTime.current = now\n onZoom(\n zoomFactorFromAccum(zoomAccum.current, Math.min(100, elapsed)),\n zoomX.current,\n zoomY.current,\n )\n zoomAccum.current = 0\n zoomScheduled.current = false\n })\n }\n event.preventDefault()\n event.stopPropagation()\n return\n }\n // only swallow the wheel event on an axis we actually handle, otherwise a\n // vertical wheel over an x-only scroller (e.g. a Track) blocks page scroll\n const consumeX = !!onScrollX && event.deltaX !== 0\n const consumeY = !!onScrollY && event.deltaY !== 0\n if (consumeX || consumeY) {\n if (onScrollX) {\n deltaX.current += event.deltaX\n }\n if (onScrollY) {\n deltaY.current += event.deltaY\n }\n\n if (!scheduled.current) {\n scheduled.current = true\n requestAnimationFrame(() => {\n if (onScrollX) {\n onScrollX(-deltaX.current)\n deltaX.current = 0\n }\n if (onScrollY) {\n onScrollY(-deltaY.current)\n deltaY.current = 0\n }\n scheduled.current = false\n })\n }\n event.preventDefault()\n event.stopPropagation()\n }\n }\n curr.addEventListener('wheel', onWheel, { passive: false })\n return () => {\n curr.removeEventListener('wheel', onWheel)\n }\n }, [ref, onScrollX, onScrollY, onZoom, scrollZoom])\n\n useEffect(() => {\n if (!mouseDragging) {\n return\n }\n function globalMouseMove(event: MouseEvent) {\n event.preventDefault()\n const distanceX = event.clientX - prevX.current\n const distanceY = event.clientY - prevY.current\n if ((distanceX && onScrollX) || (distanceY && onScrollY)) {\n if (!scheduled.current) {\n scheduled.current = true\n requestAnimationFrame(() => {\n onScrollX?.(distanceX)\n onScrollY?.(distanceY)\n scheduled.current = false\n prevX.current = event.clientX\n prevY.current = event.clientY\n })\n }\n }\n }\n\n function globalMouseUp() {\n prevX.current = 0\n prevY.current = 0\n setMouseDragging(false)\n }\n\n window.addEventListener('mousemove', globalMouseMove, true)\n window.addEventListener('mouseup', globalMouseUp, true)\n return () => {\n window.removeEventListener('mousemove', globalMouseMove, true)\n window.removeEventListener('mouseup', globalMouseUp, true)\n }\n }, [mouseDragging, onScrollX, onScrollY])\n\n function onMouseDown(event: React.MouseEvent) {\n if (event.button === 0) {\n prevX.current = event.clientX\n prevY.current = event.clientY\n setMouseDragging(true)\n }\n }\n\n function onMouseUp(event: React.MouseEvent) {\n event.preventDefault()\n setMouseDragging(false)\n }\n\n return { onMouseDown, onMouseUp }\n}\n", "// Wheel / trackpad-pinch delta handling, adapted from @jbrowse/core's\n// util/wheelZoom (not yet in our pinned @jbrowse/core). Turns raw wheel deltas\n// into a per-frame zoom factor that feels consistent across fine trackpad\n// pinches and coarse mouse notches.\n\n// Fixed divisor for plain-wheel scroll-zoom mode, where deltas are big notches.\nexport const SCROLL_ZOOM_DIVISOR = 500\n\n// Cap the zoom change per millisecond so a burst of momentum-scroll events\n// coalesced into one frame can't jump the zoom level (0.2 per ~60fps frame).\nconst MAX_ZOOM_RATE_PER_MS = 0.2 / 16.67\n\n// Convert a wheel delta to pixels regardless of the browser's deltaMode; some\n// browsers/mice report lines or pages instead of pixels.\nexport function normalizeWheelDelta(delta: number, mode: number) {\n if (mode === 1) {\n return delta * 16 // DOM_DELTA_LINE\n }\n if (mode === 2) {\n return delta * 100 // DOM_DELTA_PAGE\n }\n return delta // DOM_DELTA_PIXEL\n}\n\n// Adaptive divisor: tiny pinch deltas zoom in larger steps, big mouse notches\n// in finer steps, so a trackpad pinch and a mouse wheel feel similar.\nexport function getZoomNormalizer(deltaY: number) {\n const abs = Math.abs(deltaY)\n if (abs < 6) {\n return 25\n }\n if (abs > 150) {\n return 500\n }\n if (abs > 30) {\n return 150\n }\n return 75\n}\n\n// Turn accumulated, normalized zoom intent into a colWidth/rowHeight multiplier.\n// Positive accum (wheel toward user) zooms out (factor < 1); negative zooms in.\nexport function zoomFactorFromAccum(zoomAccum: number, elapsedMs: number) {\n const max = MAX_ZOOM_RATE_PER_MS * elapsedMs\n const d = Math.max(-max, Math.min(max, zoomAccum))\n return d > 0 ? 1 / (1 + d) : 1 - d\n}\n", "import type { MsaViewModel } from '../../model.ts'\n\nexport function onMsaKey(\n model: MsaViewModel,\n { key, shiftKey }: { key: string; shiftKey: boolean },\n) {\n const { colWidth, rowHeight, msaCanvasWidth, msaAreaHeight } = model\n const dx = shiftKey ? msaCanvasWidth : colWidth\n const dy = shiftKey ? msaAreaHeight : rowHeight\n switch (key) {\n case 'ArrowLeft':\n model.doScrollX(dx)\n return true\n case 'ArrowRight':\n model.doScrollX(-dx)\n return true\n case 'ArrowUp':\n model.doScrollY(dy)\n return true\n case 'ArrowDown':\n model.doScrollY(-dy)\n return true\n case '+':\n case '=':\n model.zoomIn()\n return true\n case '-':\n model.zoomOut()\n return true\n case 'Home':\n model.setScrollX(0)\n return true\n case 'End':\n model.setScrollX(model.maxScrollX)\n return true\n case 'Escape':\n if (model.selection) {\n model.clearSelection()\n return true\n }\n return false\n default:\n return false\n }\n}\n", "import React from 'react'\n\nimport { useTheme } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { useCanvasAutorun } from '../../useCanvasAutorun.ts'\nimport { TrackResizeHandle } from '../ResizeHandles.tsx'\nimport { drawTrackBlock } from './drawTracks.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { BasicTrack } from '../../types.ts'\n\nconst TrackBlock = observer(function ({\n model,\n track,\n offsetX,\n}: {\n model: MsaViewModel\n track: BasicTrack\n offsetX: number\n}) {\n const { blockSize, highResScaleFactor } = model\n const { height } = track.model\n const theme = useTheme()\n const canvasWidth = blockSize * highResScaleFactor\n const canvasHeight = height * highResScaleFactor\n\n const ref = useCanvasAutorun({\n draw: ctx => {\n ctx.resetTransform()\n ctx.clearRect(0, 0, canvasWidth, canvasHeight)\n drawTrackBlock({ model, ctx, track, offsetX, theme })\n },\n width: canvasWidth,\n height: canvasHeight,\n deps: [model, track, offsetX, theme],\n })\n\n return (\n <canvas\n ref={ref}\n width={canvasWidth}\n height={canvasHeight}\n style={{\n position: 'absolute',\n left: offsetX,\n width: blockSize,\n height,\n }}\n />\n )\n})\n\n/**\n * The canvas blocks covering one track's row of the alignment. Every track kind\n * shares this host: what differs between conservation, sequence logo and the\n * Stockholm text tracks is which draw function `drawTrackBlock` dispatches to,\n * not how the blocks are laid out or kept in sync with the horizontal scroll.\n */\nconst TrackBlocks = observer(function ({\n model,\n track,\n}: {\n model: MsaViewModel\n track: BasicTrack\n}) {\n // msaCanvasWidth, not msaAreaWidth: tracks stop where the alignment canvas\n // does, not 20px further under the vertical scrollbar, so their columns and\n // the hover indicator line up with the alignment\n const { blocksX, msaCanvasWidth, scrollX } = model\n const { kind, height, data, arcs } = track.model\n\n // a track with nothing to draw would still take up its vertical space\n if ((kind === 'text' && !data) || (kind === 'arc' && !arcs?.length)) {\n return null\n }\n\n return (\n <div\n style={{\n position: 'relative',\n height,\n width: msaCanvasWidth,\n overflow: 'hidden',\n }}\n >\n {/* one transform for the whole block set, matching MSACanvas */}\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `translateX(${scrollX}px)`,\n willChange: 'transform',\n }}\n >\n {blocksX.map(bx => (\n <TrackBlock key={bx} model={model} track={track} offsetX={bx} />\n ))}\n </div>\n <TrackResizeHandle model={model} track={track} />\n </div>\n )\n})\n\nexport default TrackBlocks\n", "import { useEffect, useRef } from 'react'\n\nimport { autorun } from 'mobx'\n\nimport type React from 'react'\n\n/**\n * Wires a canvas ref to a mobx autorun: grabs the 2d context once the canvas\n * mounts and re-runs `draw` whenever any observable it reads changes.\n *\n * `width`/`height` are the canvas backing store size (logical size times the\n * high-res scale factor). Assigning either clears the bitmap, and React assigns\n * them after the mobx reaction has drawn at the old size, so the effect redraws\n * when they change.\n *\n * `deps` covers everything else the effect should re-subscribe on, matching a\n * normal useEffect dep array.\n */\nexport function useCanvasAutorun({\n draw,\n width,\n height,\n deps,\n}: {\n draw: (ctx: CanvasRenderingContext2D) => void\n width: number\n height: number\n deps: React.DependencyList\n}) {\n const ref = useRef<HTMLCanvasElement>(null)\n // the autorun tracks its own observable reads, so `draw` is intentionally not\n // a dependency; `deps` plus the canvas size control when it re-subscribes\n useEffect(() => {\n const ctx = ref.current?.getContext('2d')\n return ctx\n ? autorun(() => {\n draw(ctx)\n })\n : undefined\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [...deps, width, height])\n return ref\n}\n", "import React from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport { columnLogoStack } from '../../sequenceLogo.ts'\nimport { barTrackValues } from './drawTracks.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { BasicTrack } from '../../types.ts'\n\nconst pct = (n: number) => `${Math.round(n * 100)}%`\n\nconst MAX_PARTNERS = 8\n\nfunction ColumnLabel({ model, col }: { model: MsaViewModel; col: number }) {\n const { relativeTo } = model\n const pos = relativeTo\n ? model.visibleColToSeqPosOneBased(relativeTo, col)\n : undefined\n return (\n <b>\n Column {col + 1}\n {pos === undefined ? null : ` (${relativeTo}:${pos})`}\n </b>\n )\n}\n\nfunction BarTooltip({\n model,\n track,\n col,\n}: {\n model: MsaViewModel\n track: BasicTrack\n col: number\n}) {\n const { id, name } = track.model\n const value = barTrackValues(model, id)[col]\n return value === undefined ? null : (\n <div>\n <ColumnLabel model={model} col={col} />\n <br />\n {name}: {value.toFixed(2)}\n </div>\n )\n}\n\nfunction LogoTooltip({ model, col }: { model: MsaViewModel; col: number }) {\n const stats = model.columnStatsAt(col)\n if (!stats) {\n return null\n }\n const { total, consensusLetter, consensusFraction, gapFraction } = stats\n const stack = columnLogoStack(model.colStats, col, model.alphabetMaxBits)\n const bits = stack.reduce((a, b) => a + b.bits, 0)\n return (\n <div>\n <ColumnLabel model={model} col={col} /> ({total} seqs)\n <br />\n Information: {bits.toFixed(2)} bits\n <br />\n Consensus: {consensusLetter || '-'} ({pct(consensusFraction)})\n <br />\n Gaps: {pct(gapFraction)}\n <br />\n {stats.distribution.slice(0, 6).map(([letter, count]) => (\n <span key={letter} style={{ marginRight: 8 }}>\n {letter} {pct(count / total)}\n </span>\n ))}\n </div>\n )\n}\n\nfunction TextTooltip({\n model,\n track,\n col,\n}: {\n model: MsaViewModel\n track: BasicTrack\n col: number\n}) {\n const { name, data } = track.model\n const letter = data?.[col]\n return letter === undefined ? null : (\n <div>\n <ColumnLabel model={model} col={col} />\n <br />\n {name}: {letter === ' ' ? 'blank' : letter}\n </div>\n )\n}\n\nfunction ArcTooltip({\n model,\n track,\n col,\n}: {\n model: MsaViewModel\n track: BasicTrack\n col: number\n}) {\n const { name, arcs } = track.model\n const partners = (arcs ?? [])\n .filter(arc => arc.start === col || arc.end === col)\n .map(arc => (arc.start === col ? arc.end : arc.start) + 1)\n return partners.length === 0 ? null : (\n <div>\n <ColumnLabel model={model} col={col} />\n <br />\n {name}: pairs with {partners.slice(0, MAX_PARTNERS).join(', ')}\n {partners.length > MAX_PARTNERS ? '...' : null}\n </div>\n )\n}\n\n/**\n * One track's reading at the hovered column: a bar track's value, the logo's\n * information content and composition, the columns an arc joins, the letter on a\n * text track. `drawTrackBlock` dispatches on the same `kind`, so a new kind\n * needs a case in both.\n */\nconst TrackTooltipContent = observer(function ({\n model,\n track,\n col,\n}: {\n model: MsaViewModel\n track: BasicTrack\n col: number\n}) {\n switch (track.model.kind) {\n case 'bar': {\n return <BarTooltip model={model} track={track} col={col} />\n }\n case 'logo': {\n return <LogoTooltip model={model} col={col} />\n }\n case 'text': {\n return <TextTooltip model={model} track={track} col={col} />\n }\n case 'arc': {\n return <ArcTooltip model={model} track={track} col={col} />\n }\n case 'ruler': {\n return (\n <div>\n <ColumnLabel model={model} col={col} />\n </div>\n )\n }\n }\n})\n\nexport default TrackTooltipContent\n", "import { isAlive } from '@jbrowse/mobx-state-tree'\n\nimport type { MsaViewModel } from '../model.ts'\n\n// a press that travels further than this, in px, is a drag and not a click\nexport const maxClickTravel = 3\n\nexport interface ClientPoint {\n clientX: number\n clientY: number\n}\n\n/**\n * Follows a press through the window until its release, selecting the block\n * between the cell it started on and the cell under the pointer. The selection\n * starts once the pointer travels past `maxClickTravel`, so a press that stays\n * put reaches the click handlers unchanged. `cellAt` maps a client point to a\n * visible column and row index, or a column alone to select across every row.\n */\nexport function dragSelection(\n model: MsaViewModel,\n start: ClientPoint,\n cellAt: (point: ClientPoint) => { col: number; row?: number },\n) {\n const anchor = cellAt(start)\n const { clientX, clientY } = start\n let dragging = false\n function onMove(event: MouseEvent) {\n dragging ||=\n Math.hypot(event.clientX - clientX, event.clientY - clientY) >\n maxClickTravel\n if (dragging && isAlive(model)) {\n model.selectBlock(anchor, cellAt(event))\n }\n }\n function onUp() {\n window.removeEventListener('mousemove', onMove)\n window.removeEventListener('mouseup', onUp)\n }\n window.addEventListener('mousemove', onMove)\n window.addEventListener('mouseup', onUp)\n}\n", "import { useState } from 'react'\n\nexport interface HoverAnchor<T> {\n clientPoint: { x: number; y: number }\n value: T\n}\n\n/**\n * The thing under the pointer and the point a tooltip about it hangs from,\n * 15px below the cursor so the tooltip clears it.\n */\nexport function useHoverAnchor<T>() {\n const [anchor, setAnchor] = useState<HoverAnchor<T>>()\n\n function hoverAt(\n event: { clientX: number; clientY: number },\n value: T | undefined,\n ) {\n setAnchor(\n value === undefined\n ? undefined\n : { value, clientPoint: { x: event.clientX, y: event.clientY + 15 } },\n )\n }\n\n function clearAnchor() {\n setAnchor(undefined)\n }\n\n return { anchor, hoverAt, clearAnchor }\n}\n", "import { dragSelection } from '../selectionDrag.ts'\nimport { useHoverAnchor } from '../useHoverAnchor.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type React from 'react'\n\n/**\n * Translates pointer events over a track's row into the hovered column and a\n * tooltip anchor. The track shares the alignment's columns, so hovering it sets\n * the model's mouse column too and the alignment's hover band follows along. A\n * drag along the row selects the columns it covers across every row.\n *\n * `tooltip` off skips the anchor, so a track whose tooltip is turned off still\n * drives the hover band without re-rendering on every mouse move.\n */\nexport function useTrackHover({\n model,\n tooltip,\n}: {\n model: MsaViewModel\n tooltip: boolean\n}) {\n const { anchor, hoverAt, clearAnchor } = useHoverAnchor<number>()\n\n // the blocks are laid out in column space and scrolled by a transform on\n // their container, so the pointer's column comes off the untransformed row\n function colAt(clientX: number, left: number) {\n return Math.floor((clientX - left - model.scrollX) / model.colWidth)\n }\n\n function onMouseMove(event: React.MouseEvent, el: HTMLElement) {\n const col = colAt(event.clientX, el.getBoundingClientRect().left)\n const hit = col >= 0 && col < model.numColumns\n model.setMousePos(hit ? col : undefined, undefined)\n if (tooltip) {\n hoverAt(event, hit ? col : undefined)\n }\n }\n\n // a press on a track's canvas, which leaves out the resize divider under it.\n // The row takes the focus, so Escape reaches onMsaKey from there too\n function onMouseDown(event: React.MouseEvent, el: HTMLElement) {\n if (event.button === 0 && event.target instanceof HTMLCanvasElement) {\n event.preventDefault()\n el.focus({ preventScroll: true })\n const { left } = el.getBoundingClientRect()\n dragSelection(model, event, ({ clientX }) => ({\n col: colAt(clientX, left),\n }))\n }\n }\n\n function onMouseLeave() {\n clearAnchor()\n model.setMousePos(undefined, undefined)\n }\n\n return {\n anchor: tooltip ? anchor : undefined,\n onMouseMove,\n onMouseDown,\n onMouseLeave,\n }\n}\n", "import React, { useCallback } from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport DragHandle from './DragHandle.tsx'\n\nimport type { MsaViewModel } from '../model.ts'\n\nconst width = 20\n\nconst VerticalScrollbar = observer(({ model }: { model: MsaViewModel }) => {\n const { msaAreaHeight, scrollY, totalHeight } = model\n const unit = msaAreaHeight / totalHeight\n const t = -scrollY * unit\n const b = (-scrollY + msaAreaHeight) * unit\n\n const onDrag = useCallback(\n (delta: number, startScroll: number) => {\n model.setScrollY(startScroll - delta / unit)\n },\n [model, unit],\n )\n\n return (\n <div\n onMouseDown={event => {\n if (event.button === 0 && event.target === event.currentTarget) {\n const y =\n event.clientY - event.currentTarget.getBoundingClientRect().top\n model.setScrollY(-y / unit + msaAreaHeight / 2)\n }\n }}\n style={{\n position: 'relative',\n width,\n height: msaAreaHeight,\n borderLeft: '1px solid #555',\n borderTop: '1px solid #555',\n boxSizing: 'border-box',\n }}\n >\n <DragHandle\n axis=\"y\"\n variant=\"thumb\"\n getStart={() => model.scrollY}\n onDrag={onDrag}\n style={{\n top: Math.max(0, t),\n left: 0,\n boxSizing: 'border-box',\n width,\n height: Math.max(b - t, 20),\n }}\n />\n </div>\n )\n})\nexport default VerticalScrollbar\n", "import React, { lazy, useEffect } from 'react'\n\nimport useMeasure from '@jbrowse/core/util/useMeasure'\nimport Help from '@mui/icons-material/Help'\nimport { IconButton, Tooltip } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport StatusMessage from '../StatusMessage.tsx'\nimport ColorSchemeMenu from './ColorSchemeMenu.tsx'\nimport FileMenu from './FileMenu.tsx'\nimport GappynessSlider from './GappynessSlider.tsx'\nimport GoToBox from './GoToBox.tsx'\nimport HeaderInfoArea from './HeaderInfoArea.tsx'\nimport LoadWarnings from './LoadWarnings.tsx'\nimport MSASettingsMenu from './MSASettingsMenu.tsx'\nimport MultiAlignmentSelector from './MultiAlignmentSelector.tsx'\nimport SelectionMenu from './SelectionMenu.tsx'\nimport TreeSettingsMenu from './TreeSettingsMenu.tsx'\nimport UnshareableDataWarning from './UnshareableDataWarning.tsx'\nimport ZoomControls from './ZoomControls.tsx'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst HelpDialog = lazy(() => import('../dialogs/HelpDialog.tsx'))\n\nconst Header = observer(function ({ model }: { model: MsaViewModel }) {\n const [ref, { height }] = useMeasure()\n useEffect(() => {\n model.setHeaderHeight(height ?? 0)\n }, [model, height])\n useEffect(\n () => () => {\n model.setHeaderHeight(0)\n },\n [model],\n )\n return (\n <div ref={ref} style={{ display: 'flex', flexWrap: 'wrap' }}>\n <FileMenu model={model} />\n <ColorSchemeMenu model={model} />\n <TreeSettingsMenu model={model} />\n <MSASettingsMenu model={model} />\n <ZoomControls model={model} />\n <GappynessSlider model={model} />\n <GoToBox model={model} />\n <div style={{ paddingLeft: 20, margin: 'auto' }}>\n <MultiAlignmentSelector model={model} />\n </div>\n {/* zero flex-basis, so what appears here on a selection or a hover\n shrinks into the header's spare width and never wraps it */}\n <div style={{ flex: '1 1 0', minWidth: 0, display: 'flex' }}>\n <SelectionMenu model={model} />\n <HeaderInfoArea model={model} />\n </div>\n <LoadWarnings model={model} />\n <UnshareableDataWarning model={model} />\n <StatusMessage model={model} variant=\"header\" />\n <Tooltip title=\"Mouse & keyboard help\">\n <IconButton\n aria-label=\"Mouse & keyboard help\"\n onClick={() => {\n model.queueDialog(onClose => [HelpDialog, { model, onClose }])\n }}\n >\n <Help />\n </IconButton>\n </Tooltip>\n </div>\n )\n})\n\nexport default Header\n", "import React from 'react'\n\nimport { LoadingEllipses } from '@jbrowse/core/ui'\nimport { makeStyles } from '@jbrowse/core/util/tss-react'\nimport { Button, CircularProgress, Typography } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport type { MsaViewModel } from '../model.ts'\n\nconst useStyles = makeStyles()({\n page: {\n display: 'flex',\n alignItems: 'center',\n gap: 12,\n padding: 20,\n },\n header: {\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n margin: 'auto',\n marginLeft: 10,\n },\n})\n\n/**\n * The model's status line with its Cancel button: a spinner and a heading in\n * place of the view while it loads, or a line in the header afterwards, which\n * disappears when there is no status.\n */\nconst StatusMessage = observer(function ({\n model,\n variant,\n}: {\n model: MsaViewModel\n variant: 'page' | 'header'\n}) {\n const { status } = model\n const { classes } = useStyles()\n if (variant === 'header' && !status) {\n return null\n }\n const message = status?.msg ?? 'Loading...'\n const onCancel = status?.onCancel\n return (\n <div className={classes[variant]}>\n {variant === 'page' ? (\n <>\n <CircularProgress size={24} />\n <Typography variant=\"h6\">{message}</Typography>\n </>\n ) : (\n <LoadingEllipses message={message} component=\"span\" />\n )}\n {onCancel ? (\n <Button\n variant={variant === 'page' ? 'outlined' : 'text'}\n size=\"small\"\n onClick={() => {\n onCancel()\n }}\n >\n Cancel\n </Button>\n ) : null}\n </div>\n )\n})\n\nexport default StatusMessage\n", "import React from 'react'\n\nimport CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'\nimport Palette from '@mui/icons-material/Palette'\nimport { observer } from 'mobx-react'\n\nimport colorSchemes from '../../colorSchemes.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\n// While a `customColorScheme` map is set, a checked Custom entry stands for it\n// and no named scheme is checked. Picking a named scheme clears the map.\nexport function colorSchemeMenuItems(model: MsaViewModel) {\n const { colorSchemeName, customColorScheme } = model\n const custom = customColorScheme\n ? [\n {\n label: 'Custom',\n type: 'radio',\n checked: true,\n onClick: () => {},\n } as const,\n ]\n : []\n return [\n ...custom,\n ...Object.keys(colorSchemes).map(\n option =>\n ({\n label: option,\n type: 'radio',\n checked: !customColorScheme && colorSchemeName === option,\n onClick: () => {\n model.setColorSchemeName(option)\n },\n }) as const,\n ),\n ]\n}\n\nconst ColorSchemeMenu = observer(function ({ model }: { model: MsaViewModel }) {\n return (\n <CascadingMenuButton\n data-testid=\"color_scheme_menu\"\n tooltip=\"Color scheme\"\n closeAfterItemClick\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n menuItems={colorSchemeMenuItems(model)}\n >\n <Palette />\n </CascadingMenuButton>\n )\n})\n\nexport default ColorSchemeMenu\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10c1.38 0 2.5-1.12 2.5-2.5 0-.61-.23-1.2-.64-1.67-.08-.1-.13-.21-.13-.33 0-.28.22-.5.5-.5H16c3.31 0 6-2.69 6-6 0-4.96-4.49-9-10-9m5.5 11c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5m-3-4c-.83 0-1.5-.67-1.5-1.5S13.67 6 14.5 6s1.5.67 1.5 1.5S15.33 9 14.5 9M5 11.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5S7.33 13 6.5 13 5 12.33 5 11.5m6-4c0 .83-.67 1.5-1.5 1.5S8 8.33 8 7.5 8.67 6 9.5 6s1.5.67 1.5 1.5\"\n}), 'Palette');", "const red = {\n 50: '#ffebee',\n 100: '#ffcdd2',\n 200: '#ef9a9a',\n 300: '#e57373',\n 400: '#ef5350',\n 500: '#f44336',\n 600: '#e53935',\n 700: '#d32f2f',\n 800: '#c62828',\n 900: '#b71c1c',\n A100: '#ff8a80',\n A200: '#ff5252',\n A400: '#ff1744',\n A700: '#d50000'\n};\nexport default red;", "const blue = {\n 50: '#e3f2fd',\n 100: '#bbdefb',\n 200: '#90caf9',\n 300: '#64b5f6',\n 400: '#42a5f5',\n 500: '#2196f3',\n 600: '#1e88e5',\n 700: '#1976d2',\n 800: '#1565c0',\n 900: '#0d47a1',\n A100: '#82b1ff',\n A200: '#448aff',\n A400: '#2979ff',\n A700: '#2962ff'\n};\nexport default blue;", "const green = {\n 50: '#e8f5e9',\n 100: '#c8e6c9',\n 200: '#a5d6a7',\n 300: '#81c784',\n 400: '#66bb6a',\n 500: '#4caf50',\n 600: '#43a047',\n 700: '#388e3c',\n 800: '#2e7d32',\n 900: '#1b5e20',\n A100: '#b9f6ca',\n A200: '#69f0ae',\n A400: '#00e676',\n A700: '#00c853'\n};\nexport default green;", "const orange = {\n 50: '#fff3e0',\n 100: '#ffe0b2',\n 200: '#ffcc80',\n 300: '#ffb74d',\n 400: '#ffa726',\n 500: '#ff9800',\n 600: '#fb8c00',\n 700: '#f57c00',\n 800: '#ef6c00',\n 900: '#e65100',\n A100: '#ffd180',\n A200: '#ffab40',\n A400: '#ff9100',\n A700: '#ff6d00'\n};\nexport default orange;", "import { blue, green, orange, red } from '@mui/material/colors'\nimport { colord } from 'colord'\n\nimport { transform } from './util.ts'\n\n// standard A/C/G/T(/U) coloring, shared by the `jbrowse_dna` and `nucleotide`\n// scheme names\nconst dna = {\n A: green[500],\n C: blue[500],\n G: orange[500],\n T: red[500],\n U: red[500],\n}\n\n// Record<string, ...> so a free-string scheme name can index it\nconst colorSchemes: Record<string, Record<string, string>> = {\n none: {},\n nucleotide: dna,\n clustal: {\n G: 'orange',\n P: 'orange',\n S: 'orange',\n T: 'orange',\n H: 'red',\n K: 'red',\n R: 'red',\n F: 'blue',\n W: 'blue',\n Y: 'blue',\n I: 'green',\n L: 'green',\n M: 'green',\n V: 'green',\n },\n lesk: {\n G: 'orange',\n A: 'orange',\n S: 'orange',\n T: 'orange',\n C: 'green',\n V: 'green',\n I: 'green',\n L: 'green',\n P: 'green',\n F: 'green',\n Y: 'green',\n M: 'green',\n W: 'green',\n N: 'magenta',\n Q: 'magenta',\n H: 'magenta',\n D: 'red',\n E: 'red',\n K: 'blue',\n R: 'blue',\n },\n maeditor: {\n A: 'lightgreen',\n G: 'lightgreen',\n C: 'green',\n D: 'darkgreen',\n E: 'darkgreen',\n N: 'darkgreen',\n Q: 'darkgreen',\n I: 'blue',\n L: 'blue',\n M: 'blue',\n V: 'blue',\n F: '#c8a2c8',\n W: '#c8a2c8',\n Y: '#c8a2c8',\n H: 'darkblue',\n K: 'orange',\n R: 'orange',\n P: 'pink',\n S: 'red',\n T: 'red',\n },\n\n percent_identity_dynamic: {},\n // https://github.com/biotite-dev/biotite/blob/8c460972f8ab904312f130dfb80f3efc8c9bd7c5/src/biotite/sequence/graphics/color_schemes/flower.json\n flower: {\n A: '#b18a51',\n C: '#ff5701',\n D: '#01a578',\n E: '#2da0a1',\n F: '#fa559d',\n G: '#b1c23c',\n H: '#0194f9',\n I: '#f27663',\n K: '#7fc3d7',\n L: '#df6e75',\n M: '#fe9daf',\n N: '#0bcec6',\n P: '#4fa32a',\n Q: '#7295ae',\n R: '#83bff1',\n S: '#b4bd9b',\n T: '#d2b576',\n V: '#fd997b',\n W: '#ff2ded',\n Y: '#c96ecf',\n },\n rainbow_dna: {\n A: '#3737f5',\n C: '#37f537',\n G: '#f5f537',\n T: '#f53737',\n U: '#f53737',\n },\n\n // https://github.com/biotite-dev/biotite/blob/8c460972f8ab904312f130dfb80f3efc8c9bd7c5/src/biotite/sequence/graphics/color_schemes/clustalx_protein.json\n clustalx_protein: {\n A: '#197fe5',\n C: '#e57f7f',\n D: '#cc4ccc',\n E: '#cc4ccc',\n F: '#197fe5',\n G: '#e5994c',\n H: '#19b2b2',\n I: '#197fe5',\n K: '#e53319',\n L: '#197fe5',\n M: '#197fe5',\n N: '#19cc19',\n P: '#cccc00',\n Q: '#19cc19',\n R: '#e53319',\n S: '#19cc19',\n T: '#19cc19',\n V: '#197fe5',\n W: '#197fe5',\n Y: '#19b2b2',\n },\n\n // this has special handling\n clustalx_protein_dynamic: {},\n\n clustalx_dna: {\n A: '#e53319',\n C: '#197fe5',\n G: '#e5994c',\n T: '#19cc19',\n U: '#19cc19',\n },\n jbrowse_dna: dna,\n jalview_buried: {\n A: '#00a35c',\n R: '#00fc03',\n N: '#00eb14',\n D: '#00eb14',\n C: '#0000ff',\n Q: '#00f10e',\n E: '#00f10e',\n G: '#009d62',\n H: '#00d52a',\n I: '#0054ab',\n L: '#007b84',\n K: '#00ff00',\n M: '#009768',\n F: '#008778',\n P: '#00e01f',\n S: '#00d52a',\n T: '#00db24',\n W: '#00a857',\n Y: '#00e619',\n V: '#005fa0',\n B: '#00eb14',\n X: '#00b649',\n Z: '#00f10e',\n },\n\n jalview_hydrophobicity: {\n A: '#ad0052',\n R: '#0000ff',\n N: '#0c00f3',\n D: '#0c00f3',\n C: '#c2003d',\n Q: '#0c00f3',\n E: '#0c00f3',\n G: '#6a0095',\n H: '#1500ea',\n I: '#ff0000',\n L: '#ea0015',\n K: '#0000ff',\n M: '#b0004f',\n F: '#cb0034',\n P: '#4600b9',\n S: '#5e00a1',\n T: '#61009e',\n W: '#5b00a4',\n Y: '#4f00b0',\n V: '#f60009',\n B: '#0c00f3',\n X: '#680097',\n Z: '#0c00f3',\n },\n\n jalview_prophelix: {\n A: '#e718e7',\n R: '#6f906f',\n N: '#1be41b',\n D: '#778877',\n C: '#23dc23',\n Q: '#926d92',\n E: '#ff00ff',\n G: '#00ff00',\n H: '#758a75',\n I: '#8a758a',\n L: '#ae51ae',\n K: '#a05fa0',\n M: '#ef10ef',\n F: '#986798',\n P: '#00ff00',\n S: '#36c936',\n T: '#47b847',\n W: '#8a758a',\n Y: '#21de21',\n V: '#857a85',\n B: '#49b649',\n X: '#758a75',\n Z: '#c936c9',\n },\n\n jalview_propstrand: {\n A: '#5858a7',\n R: '#6b6b94',\n N: '#64649b',\n D: '#2121de',\n C: '#9d9d62',\n Q: '#8c8c73',\n E: '#0000ff',\n G: '#4949b6',\n H: '#60609f',\n I: '#ecec13',\n L: '#b2b24d',\n K: '#4747b8',\n M: '#82827d',\n F: '#c2c23d',\n P: '#2323dc',\n S: '#4949b6',\n T: '#9d9d62',\n W: '#c0c03f',\n Y: '#d3d32c',\n V: '#ffff00',\n B: '#4343bc',\n X: '#797986',\n Z: '#4747b8',\n },\n\n jalview_propturn: {\n A: '#2cd3d3',\n R: '#708f8f',\n N: '#ff0000',\n D: '#e81717',\n C: '#a85757',\n Q: '#3fc0c0',\n E: '#778888',\n G: '#ff0000',\n H: '#708f8f',\n I: '#00ffff',\n L: '#1ce3e3',\n K: '#7e8181',\n M: '#1ee1e1',\n F: '#1ee1e1',\n P: '#f60909',\n S: '#e11e1e',\n T: '#738c8c',\n W: '#738c8c',\n Y: '#9d6262',\n V: '#07f8f8',\n B: '#f30c0c',\n X: '#7c8383',\n Z: '#5ba4a4',\n },\n\n jalview_taylor: {\n A: '#ccff00',\n R: '#0000ff',\n N: '#cc00ff',\n D: '#ff0000',\n C: '#ffff00',\n Q: '#ff00cc',\n E: '#ff0066',\n G: '#ff9900',\n H: '#0066ff',\n I: '#66ff00',\n L: '#33ff00',\n K: '#6600ff',\n M: '#00ff00',\n F: '#00ff66',\n P: '#ffcc00',\n S: '#ff3300',\n T: '#ff6600',\n W: '#00ccff',\n Y: '#00ffcc',\n V: '#99ff00',\n },\n\n jalview_zappo: {\n A: '#ffafaf',\n R: '#6464ff',\n N: '#00ff00',\n D: '#ff0000',\n C: '#ffff00',\n Q: '#00ff00',\n E: '#ff0000',\n G: '#ff00ff',\n H: '#6464ff',\n I: '#ffafaf',\n L: '#ffafaf',\n K: '#6464ff',\n M: '#ffafaf',\n F: '#ffc800',\n P: '#ff00ff',\n S: '#00ff00',\n T: '#00ff00',\n W: '#ffc800',\n Y: '#ffc800',\n V: '#ffafaf',\n },\n\n cinema: {\n H: 'blue',\n K: 'blue',\n R: 'blue',\n D: 'red',\n E: 'red',\n S: 'green',\n T: 'green',\n N: 'green',\n Q: 'green',\n A: 'white',\n V: 'white',\n L: 'white',\n I: 'white',\n M: 'white',\n F: 'magenta',\n W: 'magenta',\n Y: 'magenta',\n P: 'brown',\n G: 'brown',\n C: 'yellow',\n B: 'gray',\n Z: 'gray',\n X: 'gray',\n '-': 'gray',\n '.': 'gray',\n },\n}\n\n// turn all supplied colors to hex colors which getContrastText from mui\n// requires\nexport default transform(colorSchemes, ([key, val]) => [\n key,\n transform(val, ([letter, color]) => [letter, colord(color).toHex()]),\n])\n\nconst letterTables = new WeakMap<\n Record<string, string>,\n Record<string, string>\n>()\n\n/**\n * A letter map as the renderer looks letters up. The model upper-cases every\n * row before coloring it, so a table keys its letters in upper case and a map\n * may key them in either. The table is cached per map, so its identity is\n * stable enough for the raster cache to key on.\n */\nexport function letterColorTable(map: Record<string, string>) {\n let table = letterTables.get(map)\n if (!table) {\n table = transform(map, ([letter, color]) => [letter.toUpperCase(), color])\n letterTables.set(map, table)\n }\n return table\n}\n", "import React, { lazy } from 'react'\n\nimport CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'\nimport AccountTree from '@mui/icons-material/AccountTree'\nimport Assignment from '@mui/icons-material/Assignment'\nimport FolderOpen from '@mui/icons-material/FolderOpen'\nimport Menu from '@mui/icons-material/Menu'\nimport PhotoCamera from '@mui/icons-material/PhotoCamera'\nimport { observer } from 'mobx-react'\n\nimport { maxNeighborJoiningRows } from '../../constants.ts'\nimport { getAnnotationsMenu } from './getAnnotationsMenu.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst MetadataDialog = lazy(() => import('../dialogs/MetadataDialog.tsx'))\nconst ExportSVGDialog = lazy(() => import('../dialogs/ExportSVGDialog.tsx'))\n\nfunction neighborJoiningItem(model: MsaViewModel) {\n const rows = model.rowMap.size\n const tooManyRows = rows > maxNeighborJoiningRows\n return {\n label: tooManyRows\n ? `Calculate neighbor joining tree (over ${maxNeighborJoiningRows} rows, use FastTree)`\n : 'Calculate neighbor joining tree (BLOSUM62)',\n icon: AccountTree,\n disabled: tooManyRows || rows < 2,\n onClick: () => {\n try {\n model.calculateNeighborJoiningTreeFromMSA()\n } catch (e) {\n console.error('Failed to calculate NJ tree:', e)\n model.addWarning(e instanceof Error ? e.message : String(e))\n }\n },\n }\n}\n\nconst FileMenu = observer(({ model }: { model: MsaViewModel }) => {\n return (\n <CascadingMenuButton\n data-testid=\"file_menu\"\n tooltip=\"File\"\n menuItems={[\n ...(model.importForm\n ? [\n {\n label: 'Return to import form',\n icon: FolderOpen,\n onClick: () => {\n model.reset()\n },\n },\n ]\n : []),\n {\n label: 'Metadata',\n icon: Assignment,\n onClick: () => {\n model.queueDialog(onClose => [\n MetadataDialog,\n {\n model,\n onClose,\n },\n ])\n },\n },\n {\n label: 'Annotations',\n type: 'subMenu',\n subMenu: getAnnotationsMenu({\n model,\n }),\n },\n neighborJoiningItem(model),\n {\n label: 'Export tree (Newick)',\n icon: AccountTree,\n disabled: !!model.tree.noTree,\n onClick: () => {\n model.exportNewick()\n },\n },\n {\n label: 'Export SVG',\n icon: PhotoCamera,\n onClick: () => {\n model.queueDialog(onClose => [\n ExportSVGDialog,\n {\n onClose,\n model,\n },\n ])\n },\n },\n ]}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n >\n <Menu />\n </CascadingMenuButton>\n )\n})\n\nexport default FileMenu\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M22 11V3h-7v3H9V3H2v8h7V8h2v10h4v3h7v-8h-7v3h-2V8h2v3z\"\n}), 'AccountTree');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M19 3h-4.18C14.4 1.84 13.3 1 12 1s-2.4.84-2.82 2H5c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h14c1.1 0 2-.9 2-2V5c0-1.1-.9-2-2-2m-7 0c.55 0 1 .45 1 1s-.45 1-1 1-1-.45-1-1 .45-1 1-1m2 14H7v-2h7zm3-4H7v-2h10zm0-4H7V7h10z\"\n}), 'Assignment');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M20 6h-8l-2-2H4c-1.1 0-1.99.9-1.99 2L2 18c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V8c0-1.1-.9-2-2-2m0 12H4V8h16z\"\n}), 'FolderOpen');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M3 18h18v-2H3zm0-5h18v-2H3zm0-7v2h18V6z\"\n}), 'Menu');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon([/*#__PURE__*/_jsx(\"circle\", {\n cx: \"12\",\n cy: \"12\",\n r: \"3.2\"\n}, \"0\"), /*#__PURE__*/_jsx(\"path\", {\n d: \"M9 2 7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5\"\n}, \"1\")], 'PhotoCamera');", "import { lazy } from 'react'\n\nimport FilterAlt from '@mui/icons-material/FilterAlt'\nimport FolderOpen from '@mui/icons-material/FolderOpen'\nimport MenuBook from '@mui/icons-material/MenuBook'\nimport Sort from '@mui/icons-material/Sort'\nimport Visibility from '@mui/icons-material/Visibility'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst FeatureFilterDialog = lazy(() => import('../dialogs/FeatureDialog.tsx'))\nconst AnnotationFileDialog = lazy(\n () => import('../dialogs/AnnotationFileDialog.tsx'),\n)\n\nconst domainsTutorial = 'https://gmod.org/JBrowseMSA/tutorials/protein_family'\n\nexport function getAnnotationsMenu({ model }: { model: MsaViewModel }) {\n const { showDomains, actuallyShowDomains, subFeatureRows, noDomains } = model\n const noneLoaded = noDomains ? ' (none loaded)' : ''\n return [\n {\n label: 'Open annotation file...',\n icon: FolderOpen,\n onClick: () => {\n model.queueDialog(handleClose => [\n AnnotationFileDialog,\n {\n handleClose,\n model,\n },\n ])\n },\n },\n // `react-msaview-cli interpro` reads InterPro's precomputed matches in\n // seconds, and `interproscan` covers rows InterPro has not seen; this links\n // the tutorial for both\n {\n label: 'How to get a domain file...',\n icon: MenuBook,\n onClick: () => {\n window.open(domainsTutorial, '_blank', 'noopener,noreferrer')\n },\n },\n {\n label: `Show annotations${noneLoaded}`,\n disabled: noDomains,\n icon: Visibility,\n checked: actuallyShowDomains,\n type: 'checkbox' as const,\n onClick: () => {\n model.setShowDomains(!showDomains)\n },\n },\n {\n label: `Use sub-row layout${noneLoaded}`,\n disabled: noDomains,\n checked: actuallyShowDomains ? subFeatureRows : false,\n icon: Sort,\n type: 'checkbox' as const,\n onClick: () => {\n model.setSubFeatureRows(!subFeatureRows)\n },\n },\n {\n label: `Filter annotations${noneLoaded}`,\n icon: FilterAlt,\n disabled: noDomains,\n onClick: () => {\n model.queueDialog(onClose => [\n FeatureFilterDialog,\n {\n onClose,\n model,\n },\n ])\n },\n },\n ]\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M4.25 5.61C6.27 8.2 10 13 10 13v6c0 .55.45 1 1 1h2c.55 0 1-.45 1-1v-6s3.72-4.8 5.74-7.39c.51-.66.04-1.61-.79-1.61H5.04c-.83 0-1.3.95-.79 1.61\"\n}), 'FilterAlt');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon([/*#__PURE__*/_jsx(\"path\", {\n d: \"M21 5c-1.11-.35-2.33-.5-3.5-.5-1.95 0-4.05.4-5.5 1.5-1.45-1.1-3.55-1.5-5.5-1.5S2.45 4.9 1 6v14.65c0 .25.25.5.5.5.1 0 .15-.05.25-.05C3.1 20.45 5.05 20 6.5 20c1.95 0 4.05.4 5.5 1.5 1.35-.85 3.8-1.5 5.5-1.5 1.65 0 3.35.3 4.75 1.05.1.05.15.05.25.05.25 0 .5-.25.5-.5V6c-.6-.45-1.25-.75-2-1m0 13.5c-1.1-.35-2.3-.5-3.5-.5-1.7 0-4.15.65-5.5 1.5V8c1.35-.85 3.8-1.5 5.5-1.5 1.2 0 2.4.15 3.5.5z\"\n}, \"0\"), /*#__PURE__*/_jsx(\"path\", {\n d: \"M17.5 10.5c.88 0 1.73.09 2.5.26V9.24c-.79-.15-1.64-.24-2.5-.24-1.7 0-3.24.29-4.5.83v1.66c1.13-.64 2.7-.99 4.5-.99M13 12.49v1.66c1.13-.64 2.7-.99 4.5-.99.88 0 1.73.09 2.5.26V11.9c-.79-.15-1.64-.24-2.5-.24-1.7 0-3.24.3-4.5.83m4.5 1.84c-1.7 0-3.24.29-4.5.83v1.66c1.13-.64 2.7-.99 4.5-.99.88 0 1.73.09 2.5.26v-1.52c-.79-.16-1.64-.24-2.5-.24\"\n}, \"1\")], 'MenuBook');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M3 18h6v-2H3zM3 6v2h18V6zm0 7h12v-2H3z\"\n}), 'Sort');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M12 4.5C7 4.5 2.73 7.61 1 12c1.73 4.39 6 7.5 11 7.5s9.27-3.11 11-7.5c-1.73-4.39-6-7.5-11-7.5M12 17c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5m0-8c-1.66 0-3 1.34-3 3s1.34 3 3 3 3-1.34 3-3-1.34-3-3-3\"\n}), 'Visibility');", "import React, { useState } from 'react'\n\nimport { Slider, Typography } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst GappynessSlider = observer(function GappynessSlider({\n model,\n}: {\n model: MsaViewModel\n}) {\n const { hideGaps, allowedGappyness } = model\n const [dragValue, setDragValue] = useState<number>()\n const value = dragValue ?? allowedGappyness\n if (!hideGaps) {\n return null\n }\n return (\n <div style={{ display: 'flex', alignItems: 'center', gap: 8 }}>\n {/* the threshold is inclusive: blanks are columns whose gap count is at\n least ceil(allowedGappyness% of the rows), so at 100 it hides the\n columns that are entirely gaps rather than nothing */}\n <Typography style={{ whiteSpace: 'nowrap' }}>\n Hide columns w/ &ge;{value}% gaps\n </Typography>\n <Slider\n // In JBrowse other MUI Sliders share the page, so `.MuiSlider-thumb`\n // can match the wrong one. Tests and screenshot specs target\n // `[data-testid=\"gappyness_slider\"] input`, the hidden range input that\n // takes focus and arrow/PageUp/PageDown.\n //\n // Not `slotProps={{ input: ... }}`: that widens `onChange`'s `val` to\n // `number | number[]`, which setAllowedGappyness rejects.\n //\n // The thumb follows local state while dragging and the model takes the\n // value on release, since each write recomputes the gap columns over\n // the whole alignment.\n //\n // The thumb centers on the track's ends, so the margin keeps its\n // overhang off the label and the row search beside it.\n data-testid=\"gappyness_slider\"\n style={{ width: 100, marginInline: 10 }}\n min={1}\n max={100}\n value={value}\n onChange={(_, val) => {\n setDragValue(val)\n }}\n onChangeCommitted={(_, val) => {\n model.setAllowedGappyness(val)\n setDragValue(undefined)\n }}\n />\n </div>\n )\n})\n\nexport default GappynessSlider\n", "import React, { useState } from 'react'\n\nimport { Autocomplete, TextField } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { findableRowNames, goTo, rowNameSuggestions } from './goTo.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { AutocompleteRenderInputParams } from '@mui/material'\n\nconst label = 'Go to row or column'\n\n// MUI 9 hands renderInput `slotProps`; MUI 7, which every released JBrowse host\n// serves, hands it `inputProps` and no `slotProps` at all\nexport function labelledInput(params: AutocompleteRenderInputParams) {\n const { slotProps, inputProps } = params as Partial<\n AutocompleteRenderInputParams & { inputProps: object }\n >\n return slotProps\n ? {\n slotProps: {\n ...slotProps,\n htmlInput: { ...slotProps.htmlInput, 'aria-label': label },\n },\n }\n : { inputProps: { ...inputProps, 'aria-label': label } }\n}\n\nconst GoToBox = observer(function ({ model }: { model: MsaViewModel }) {\n const [missed, setMissed] = useState(false)\n const names = findableRowNames(model)\n return names.length > 1 || model.numColumns > 0 ? (\n <Autocomplete\n freeSolo\n size=\"small\"\n options={names}\n filterOptions={(options, { inputValue }) =>\n rowNameSuggestions(options, inputValue)\n }\n value={null}\n blurOnSelect\n onInputChange={() => {\n setMissed(false)\n }}\n onChange={(_, text) => {\n if (text) {\n setMissed(!goTo(model, text))\n }\n }}\n style={{ width: 180, margin: 'auto 8px' }}\n renderInput={params => (\n <TextField\n {...params}\n error={missed}\n placeholder={label}\n title=\"A row name, a column number, or name:residue\"\n {...labelledInput(params)}\n />\n )}\n />\n ) : null\n})\n\nexport default GoToBox\n", "import type { MsaViewModel } from '../../model.ts'\n\nexport function findableRowNames(model: MsaViewModel) {\n const collapsed = new Set(model.collapsed)\n return model.leaves\n .filter(({ data: { id, name } }) => !(collapsed.has(id) && name === id))\n .map(leaf => leaf.data.name)\n}\n\n// not MUI's createFilterOptions: JBrowse hosts do not re-export it, so\n// jbrowse-plugin-msaview would fail to load\nexport function rowNameSuggestions(names: string[], input: string, limit = 50) {\n const query = input.toLowerCase()\n return names\n .filter(name => name.toLowerCase().includes(query))\n .slice(0, limit)\n}\n\n/**\n * The visible row and column a \"Go to\" entry names: a row by its name, the\n * column the ruler numbers N, or residue N of a row written `name:N`. A name\n * is tried whole first, so a row called `chr1:100` stays reachable.\n */\nexport function resolveGoTo(model: MsaViewModel, text: string) {\n const query = text.trim()\n const row = model.rowNamesSet.get(query)\n if (row !== undefined) {\n return { row }\n }\n const residue = /^(.+):(\\d+)$/.exec(query)\n if (residue) {\n const [, name = '', pos] = residue\n const rowIndex = model.rowNamesSet.get(name)\n const col =\n rowIndex === undefined ? undefined : columnOfResidue(model, name, +pos!)\n return col === undefined ? undefined : { row: rowIndex, col }\n }\n if (/^\\d+$/.test(query)) {\n const n = +query\n const { relativeTo, numColumns } = model\n const col = relativeTo\n ? columnOfResidue(model, relativeTo, n)\n : n >= 1 && n <= numColumns\n ? n - 1\n : undefined\n return col === undefined ? undefined : { col }\n }\n return undefined\n}\n\n// seqPosToVisibleCol maps a residue past the row's end to the column after\n// it; here that residue names nothing\nfunction columnOfResidue(model: MsaViewModel, name: string, pos: number) {\n const globalCol = model.seqPosIndex(name)?.[pos - 1]\n return globalCol === undefined\n ? undefined\n : model.globalColToVisibleCol(globalCol)\n}\n\n/** centers the view on the entry's target and lights it; false if none */\nexport function goTo(model: MsaViewModel, text: string) {\n const target = resolveGoTo(model, text)\n if (target) {\n const { row, col } = target\n const { rowHeight, colWidth, msaAreaHeight, msaAreaWidth } = model\n if (row !== undefined) {\n model.setScrollY(-(row + 0.5) * rowHeight + msaAreaHeight / 2)\n }\n if (col !== undefined) {\n model.setScrollX(-(col + 0.5) * colWidth + msaAreaWidth / 2)\n }\n model.setMousePos(col, row)\n }\n return target !== undefined\n}\n", "import React from 'react'\n\nimport { makeStyles } from '@jbrowse/core/util/tss-react'\nimport { Typography } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst useStyles = makeStyles()({\n container: {\n display: 'flex',\n overflow: 'hidden',\n margin: 'auto',\n marginLeft: 10,\n },\n nameFirst: {\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n minWidth: 0,\n },\n nameRest: {\n whiteSpace: 'nowrap',\n flexShrink: 0,\n },\n})\n\nconst HeaderInfoArea = observer(function ({ model }: { model: MsaViewModel }) {\n const { mouseOverRowName, mouseCol } = model\n const { classes } = useStyles()\n if (!mouseOverRowName || mouseCol === undefined) {\n return null\n }\n const mid = Math.floor(mouseOverRowName.length / 2)\n const pos = model.visibleColToSeqPosOneBased(mouseOverRowName, mouseCol)\n const letter = model.visibleColToRowLetter(mouseOverRowName, mouseCol)\n return (\n <Typography\n component=\"div\"\n className={classes.container}\n title={mouseOverRowName}\n >\n <span className={classes.nameFirst}>\n {mouseOverRowName.slice(0, mid)}\n </span>\n <span className={classes.nameRest}>\n {mouseOverRowName.slice(mid)}:{pos} ({letter})\n </span>\n </Typography>\n )\n})\n\nexport default HeaderInfoArea\n", "import React from 'react'\n\nimport Warning from '@mui/icons-material/Warning'\nimport { Button, Tooltip } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport type { MsaViewModel } from '../../model.ts'\n\n// A failed optional layer, such as a 404 on the annotations or row metadata\n// that is not JSON, shows here as a dismissible warning. Setting `error` would\n// clear dataInitialized and hide the loaded alignment.\nconst LoadWarnings = observer(function ({ model }: { model: MsaViewModel }) {\n const { warnings } = model\n if (warnings.length === 0) {\n return null\n }\n return (\n <Tooltip title={`${warnings.join(' ')} (click to dismiss)`}>\n <Button\n aria-label=\"Dismiss warnings\"\n color=\"warning\"\n size=\"small\"\n startIcon={<Warning fontSize=\"small\" />}\n style={{ margin: 'auto', marginLeft: 10, whiteSpace: 'nowrap' }}\n onClick={() => {\n model.clearWarnings()\n }}\n >\n {warnings.length > 1 ? `${warnings.length} warnings` : 'Warning'}\n </Button>\n </Tooltip>\n )\n})\n\nexport default LoadWarnings\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M1 21h22L12 2zm12-3h-2v-2h2zm0-4h-2v-4h2z\"\n}), 'Warning');", "import React from 'react'\n\nimport CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'\nimport Tune from '@mui/icons-material/Tune'\nimport { observer } from 'mobx-react'\n\nimport { msaSettingsMenuItems } from './settingsMenuItems.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst MSASettingsMenu = observer(function ({ model }: { model: MsaViewModel }) {\n return (\n <CascadingMenuButton\n data-testid=\"msa_settings_menu\"\n tooltip=\"Alignment settings\"\n closeAfterItemClick={false}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n menuItems={msaSettingsMenuItems(model)}\n >\n <Tune />\n </CascadingMenuButton>\n )\n})\n\nexport default MSASettingsMenu\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M3 17v2h6v-2zM3 5v2h10V5zm10 16v-2h8v-2h-8v-2h-2v6zM7 9v2H3v2h4v2h2V9zm14 4v-2H11v2zm-6-4h2V7h4V5h-4V3h-2z\"\n}), 'Tune');", "import React from 'react'\n\nimport SvgIcon from '@mui/material/SvgIcon'\n\nimport type { SvgIconProps } from '@mui/material/SvgIcon'\n\n// Mouse glyphs with outward arrows on the axes a wheel zoom scales.\n// @mui/icons-material ships only the plain `Mouse`, and three variants that\n// differ only in their arrows have to share one body to stay apart at 24px.\n// The body's inner subpath runs the opposite sweep, which punches the hole the\n// wheel bar sits in.\nconst BODY =\n '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'\nconst WHEEL = 'M11.2 8.6h1.6v3.2h-1.6z'\nconst LEFT = 'M.4 12 5 15V9z'\nconst RIGHT = 'M23.6 12 19 9v6z'\nconst UP = 'M12 .4 15 4H9z'\nconst DOWN = 'M12 23.6 9 20h6z'\n\nfunction MouseZoom({\n arrows,\n ...rest\n}: SvgIconProps & { arrows: readonly string[] }) {\n return (\n <SvgIcon {...rest}>\n <path d={BODY} />\n <path d={WHEEL} />\n {arrows.map(d => (\n <path key={d} d={d} />\n ))}\n </SvgIcon>\n )\n}\n\n// the bare body, for a wheel that scrolls. @mui/icons-material's own `Mouse` is\n// a solid silhouette, which would jump to a different drawing when the menu\n// changes the mode.\nexport function MouseScroll(props: SvgIconProps) {\n return <MouseZoom {...props} arrows={[]} />\n}\n\nexport function MouseZoomBoth(props: SvgIconProps) {\n return <MouseZoom {...props} arrows={[LEFT, RIGHT, UP, DOWN]} />\n}\n\nexport function MouseZoomHorizontal(props: SvgIconProps) {\n return <MouseZoom {...props} arrows={[LEFT, RIGHT]} />\n}\n\nexport function MouseZoomVertical(props: SvgIconProps) {\n return <MouseZoom {...props} arrows={[UP, DOWN]} />\n}\n", "import { treeOrders } from '../../constants.ts'\nimport {\n MouseScroll,\n MouseZoomBoth,\n MouseZoomHorizontal,\n MouseZoomVertical,\n} from './ScrollZoomIcons.tsx'\n\nimport type { ScrollZoomAxis } from '../../constants.ts'\nimport type { MsaViewModel } from '../../model.ts'\nimport type { TreeOrder } from '../../types.ts'\nimport type { MenuItem } from '@jbrowse/core/ui/Menu'\n\nfunction radio(label: string, checked: boolean, onClick: () => void) {\n return { label, type: 'radio' as const, checked, onClick }\n}\n\nconst treeOrderLabels: Record<TreeOrder, string> = {\n branchLength: 'By branch length',\n input: 'As written',\n ladderize: 'Ladderize, small clades first',\n ladderizeReverse: 'Ladderize, large clades first',\n}\n\nfunction outgroupLabel(outgroup: string[]) {\n const [first, ...rest] = outgroup\n return rest.length === 0\n ? `Outgroup ${first}`\n : `Outgroup ${first} \u2026 ${rest.at(-1)}`\n}\n\nfunction toggle(label: string, checked: boolean, set: (arg: boolean) => void) {\n return {\n label,\n type: 'checkbox' as const,\n checked,\n onClick: () => {\n set(!checked)\n },\n }\n}\n\n// the only place in the UI to turn a hidden track back on\nfunction tracksSubMenu(model: MsaViewModel): MenuItem[] {\n const shown = new Set(model.turnedOnTracks.map(t => t.model.id))\n return model.tracks.map(({ model: { id, name } }) =>\n toggle(name, shown.has(id), () => {\n model.toggleTrack(id)\n }),\n )\n}\n\nconst wheelModes: {\n label: string\n axis?: ScrollZoomAxis\n icon: typeof MouseScroll\n helpText: string\n}[] = [\n {\n label: 'Scrolls the alignment',\n icon: MouseScroll,\n helpText: 'Ctrl+wheel zooms both axes at the cursor.',\n },\n {\n label: 'Zooms both axes',\n axis: 'both',\n icon: MouseZoomBoth,\n helpText: 'Hold shift to pan while the wheel zooms.',\n },\n {\n label: 'Zooms columns only',\n axis: 'horizontal',\n icon: MouseZoomHorizontal,\n helpText:\n 'Holds the row height, so the labels and letters stay at their size while the alignment compresses.',\n },\n {\n label: 'Zooms rows only',\n axis: 'vertical',\n icon: MouseZoomVertical,\n helpText:\n 'Holds the column width, so the alignment stays as wide while the rows grow or shrink.',\n },\n]\n\nexport function wheelSubMenu(model: MsaViewModel): MenuItem[] {\n const active = model.scrollZoom ? model.scrollZoomAxis : undefined\n return wheelModes.map(({ label, axis, icon, helpText }) => ({\n ...radio(label, axis === active, () => {\n model.setScrollZoom(axis !== undefined)\n if (axis !== undefined) {\n model.setScrollZoomAxis(axis)\n }\n }),\n icon,\n helpText,\n }))\n}\n\nexport function msaSettingsMenuItems(model: MsaViewModel): MenuItem[] {\n const { drawMsaLetters, hideGaps, bgColor, showColumnStats } = model\n return [\n {\n label: 'Tracks',\n type: 'subMenu' as const,\n subMenu: tracksSubMenu(model),\n },\n {\n label: 'Mouse wheel',\n type: 'subMenu' as const,\n subMenu: wheelSubMenu(model),\n },\n { type: 'divider' as const },\n toggle('Show track values on hover', showColumnStats, arg => {\n model.setShowColumnStats(arg)\n }),\n toggle('Draw letters', drawMsaLetters, arg => {\n model.setDrawMsaLetters(arg)\n }),\n // inverted: bgColor colors the tile, and off colors the letter\n toggle('Color letters, not cells', !bgColor, arg => {\n model.setBgColor(!arg)\n }),\n toggle('Hide gappy columns', hideGaps, arg => {\n model.setHideGaps(arg)\n }),\n ]\n}\n\nexport function treeSettingsMenuItems(model: MsaViewModel): MenuItem[] {\n const {\n drawTree,\n showBranchLen,\n labelsAlignRight,\n drawNodeBubbles,\n drawNodeLabels,\n drawLabels,\n treeAreaWidth,\n showTreeOverview,\n treeOrder,\n treeRoot,\n rotated,\n } = model\n return [\n {\n label: 'Order',\n type: 'subMenu' as const,\n subMenu: [\n ...treeOrders.map(order =>\n radio(treeOrderLabels[order], treeOrder === order, () => {\n model.setTreeOrder(order)\n }),\n ),\n { type: 'divider' as const },\n {\n label: 'Undo rotations',\n disabled: rotated.length === 0,\n onClick: () => {\n model.clearRotated()\n },\n },\n ],\n },\n {\n label: 'Root',\n type: 'subMenu' as const,\n subMenu: [\n radio('As written', treeRoot === undefined, () => {\n model.setTreeRoot(undefined)\n }),\n radio('Midpoint', treeRoot === 'midpoint', () => {\n model.setTreeRoot('midpoint')\n }),\n // \"Reroot here\" in a node's menu sets the outgroup, so this only\n // reports it\n ...(typeof treeRoot === 'object'\n ? [\n {\n ...radio(outgroupLabel(treeRoot.outgroup), true, () => {}),\n disabled: true,\n },\n ]\n : []),\n ],\n },\n { type: 'divider' as const },\n toggle('Show branch length', showBranchLen, arg => {\n model.setShowBranchLen(arg)\n }),\n toggle('Show tree', drawTree, arg => {\n model.setDrawTree(arg)\n }),\n toggle('Draw bubbles on tree branches', drawNodeBubbles, arg => {\n model.setDrawNodeBubbles(arg)\n }),\n toggle('Draw internal node labels', drawNodeLabels, arg => {\n model.setDrawNodeLabels(arg)\n }),\n toggle('Show tree overview', showTreeOverview, arg => {\n model.setShowTreeOverview(arg)\n }),\n toggle('Tree labels align right', labelsAlignRight, arg => {\n model.setLabelsAlignRight(arg)\n }),\n toggle('Draw labels', drawLabels, arg => {\n model.setDrawLabels(arg)\n }),\n toggle(\n 'Fit tree area to labels and tree',\n treeAreaWidth === undefined,\n arg => {\n model.setTreeAreaWidth(arg ? undefined : model.effectiveTreeAreaWidth)\n },\n ),\n ]\n}\n", "import React from 'react'\n\nimport { MenuItem, TextField } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst MultiAlignmentSelector = observer(function ({\n model,\n}: {\n model: MsaViewModel\n}) {\n const { currentAlignment, alignmentNames } = model\n // names (gf.DE) can repeat, so disambiguate duplicates by occurrence to get a\n // collision-free key tied to content rather than position: this survives the\n // list being replaced (new file) without React reusing stale MenuItem DOM.\n // value stays the index because selection is positional in the model.\n const seen = new Map<string, number>()\n return alignmentNames.length > 0 ? (\n <TextField\n select\n variant=\"outlined\"\n value={currentAlignment}\n size=\"small\"\n onChange={event => {\n model.setCurrentAlignment(+event.target.value)\n }}\n >\n {alignmentNames.map((option, index) => {\n const n = seen.get(option) ?? 0\n seen.set(option, n + 1)\n return (\n <MenuItem key={n === 0 ? option : `${option}\u0000${n}`} value={index}>\n {option}\n </MenuItem>\n )\n })}\n </TextField>\n ) : null\n})\nexport default MultiAlignmentSelector\n", "import React, { useState } from 'react'\n\nimport ArrowDropDown from '@mui/icons-material/ArrowDropDown'\nimport Clear from '@mui/icons-material/Clear'\nimport ContentCopy from '@mui/icons-material/ContentCopy'\nimport ZoomIn from '@mui/icons-material/ZoomIn'\nimport {\n Button,\n ListItemIcon,\n ListItemText,\n Menu,\n MenuItem,\n Tooltip,\n} from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport copy from '../../vendor/copyToClipboard.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nfunction count(n: number, noun: string) {\n return `${n.toLocaleString('en-US')} ${noun}${n === 1 ? '' : 's'}`\n}\n\n/**\n * The selected block's size, as a button opening what to do with it. It\n * renders only while there is a selection. Header.tsx puts it in the slot\n * with no width of its own, so the label ellipsizes before it could wrap the\n * header onto a second line.\n */\nconst SelectionMenu = observer(function ({ model }: { model: MsaViewModel }) {\n const [anchorEl, setAnchorEl] = useState<HTMLElement>()\n const { selectionSize, selectionFileSpan } = model\n if (!selectionSize || !selectionFileSpan) {\n return null\n }\n const label = `${count(selectionSize.columns, 'column')} \u00D7 ${count(selectionSize.rows, 'row')}`\n const items = [\n {\n text: 'Copy as FASTA',\n Icon: ContentCopy,\n act: () => {\n copy(model.selectionFasta)\n },\n },\n {\n text: 'Zoom to selection',\n Icon: ZoomIn,\n act: () => {\n model.zoomToSelection()\n },\n },\n {\n text: 'Clear selection',\n Icon: Clear,\n act: () => {\n model.clearSelection()\n },\n },\n ]\n return (\n <>\n <Tooltip\n title={`Columns ${selectionFileSpan.start}-${selectionFileSpan.end} selected. Shift-drag the alignment to select, Escape to clear`}\n >\n <Button\n size=\"small\"\n aria-label={`Selection: ${label}`}\n endIcon={<ArrowDropDown />}\n onClick={event => {\n setAnchorEl(event.currentTarget)\n }}\n style={{\n margin: 'auto 0 auto 8px',\n flexShrink: 0,\n maxWidth: '100%',\n minWidth: 0,\n textTransform: 'none',\n whiteSpace: 'nowrap',\n }}\n >\n <span style={{ overflow: 'hidden', textOverflow: 'ellipsis' }}>\n {label}\n </span>\n </Button>\n </Tooltip>\n {anchorEl ? (\n <Menu\n anchorEl={anchorEl}\n open\n transitionDuration={0}\n onClose={() => {\n setAnchorEl(undefined)\n }}\n >\n {items.map(({ text, Icon, act }) => (\n <MenuItem\n key={text}\n dense\n onClick={() => {\n act()\n setAnchorEl(undefined)\n }}\n >\n <ListItemIcon>\n <Icon fontSize=\"small\" />\n </ListItemIcon>\n <ListItemText>{text}</ListItemText>\n </MenuItem>\n ))}\n </Menu>\n ) : null}\n </>\n )\n})\n\nexport default SelectionMenu\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M19 6.41 17.59 5 12 10.59 6.41 5 5 6.41 10.59 12 5 17.59 6.41 19 12 13.41 17.59 19 19 17.59 13.41 12z\"\n}), 'Clear');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2m0 16H8V7h11z\"\n}), 'ContentCopy');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon([/*#__PURE__*/_jsx(\"path\", {\n d: \"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14\"\n}, \"0\"), /*#__PURE__*/_jsx(\"path\", {\n d: \"M12 10h-2v2H9v-2H7V9h2V7h1v2h2z\"\n}, \"1\")], 'ZoomIn');", "import React from 'react'\n\nimport CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'\nimport AccountTree from '@mui/icons-material/AccountTree'\nimport { observer } from 'mobx-react'\n\nimport { treeSettingsMenuItems } from './settingsMenuItems.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst TreeSettingsMenu = observer(function ({\n model,\n}: {\n model: MsaViewModel\n}) {\n return model.noTree ? null : (\n <CascadingMenuButton\n data-testid=\"tree_settings_menu\"\n tooltip=\"Tree settings\"\n closeAfterItemClick={false}\n anchorOrigin={{ vertical: 'bottom', horizontal: 'left' }}\n transformOrigin={{ vertical: 'top', horizontal: 'left' }}\n menuItems={treeSettingsMenuItems(model)}\n >\n <AccountTree />\n </CascadingMenuButton>\n )\n})\n\nexport default TreeSettingsMenu\n", "import React from 'react'\n\nimport { makeStyles } from '@jbrowse/core/util/tss-react'\nimport LinkOff from '@mui/icons-material/LinkOff'\nimport { Tooltip, Typography } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst useStyles = makeStyles()(theme => ({\n warning: {\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n margin: 'auto',\n marginLeft: 10,\n whiteSpace: 'nowrap',\n color: theme.palette.warning.main,\n cursor: 'help',\n },\n}))\n\nfunction size(bytes: number) {\n return bytes < 1_000_000\n ? `${Math.round(bytes / 1000)} kB`\n : `${(bytes / 1_000_000).toFixed(1)} MB`\n}\n\n// Lists loaded documents the snapshot, and so a shared URL, omits. See\n// `unshareableData` on the model.\nconst UnshareableDataWarning = observer(function ({\n model,\n}: {\n model: MsaViewModel\n}) {\n const { unshareableData } = model\n const { classes } = useStyles()\n if (unshareableData.length === 0) {\n return null\n }\n const what = unshareableData\n .map(({ what, bytes }) => `${what} (${size(bytes)})`)\n .join(' and the ')\n return (\n <Tooltip\n title={`The ${what} came from this computer and is too large to travel in a URL, so a link to this page opens without it. Serve the file over HTTP and open it by URL to share the view.`}\n >\n <Typography component=\"div\" className={classes.warning}>\n <LinkOff fontSize=\"small\" />\n Not in the link\n </Typography>\n </Tooltip>\n )\n})\n\nexport default UnshareableDataWarning\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M17 7h-4v1.9h4c1.71 0 3.1 1.39 3.1 3.1 0 1.43-.98 2.63-2.31 2.98l1.46 1.46C20.88 15.61 22 13.95 22 12c0-2.76-2.24-5-5-5m-1 4h-2.19l2 2H16zM2 4.27l3.11 3.11C3.29 8.12 2 9.91 2 12c0 2.76 2.24 5 5 5h4v-1.9H7c-1.71 0-3.1-1.39-3.1-3.1 0-1.59 1.21-2.9 2.76-3.07L8.73 11H8v2h2.73L13 15.27V17h1.73l4.01 4L20 19.74 3.27 3z\"\n}), 'LinkOff');", "import React from 'react'\n\nimport CascadingMenuButton from '@jbrowse/core/ui/CascadingMenuButton'\nimport FitScreen from '@mui/icons-material/FitScreen'\nimport RestartAlt from '@mui/icons-material/RestartAlt'\nimport ZoomIn from '@mui/icons-material/ZoomIn'\nimport ZoomOut from '@mui/icons-material/ZoomOut'\nimport { IconButton, Tooltip } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst ZoomControls = observer(function ZoomControls({\n model,\n}: {\n model: MsaViewModel\n}) {\n return (\n <>\n <Tooltip title=\"Zoom in\">\n <IconButton\n aria-label=\"Zoom in\"\n onClick={() => {\n model.zoomIn()\n }}\n >\n <ZoomIn />\n </IconButton>\n </Tooltip>\n <Tooltip title=\"Zoom out\">\n <IconButton\n aria-label=\"Zoom out\"\n onClick={() => {\n model.zoomOut()\n }}\n >\n <ZoomOut />\n </IconButton>\n </Tooltip>\n <CascadingMenuButton\n data-testid=\"fit_menu\"\n tooltip=\"Fit or reset zoom\"\n menuItems={[\n {\n label: 'Fit to window',\n onClick: () => {\n model.fit()\n },\n },\n {\n label: 'Fit horizontally',\n onClick: () => {\n model.fitHorizontally()\n },\n },\n {\n label: 'Fit vertically',\n onClick: () => {\n model.fitVertically()\n },\n },\n { type: 'divider' },\n {\n label: 'Reset zoom',\n icon: RestartAlt,\n onClick: () => {\n model.resetZoom()\n },\n },\n ]}\n >\n <FitScreen />\n </CascadingMenuButton>\n </>\n )\n})\n\nexport default ZoomControls\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M17 4h3c1.1 0 2 .9 2 2v2h-2V6h-3zM4 8V6h3V4H4c-1.1 0-2 .9-2 2v2zm16 8v2h-3v2h3c1.1 0 2-.9 2-2v-2zM7 18H4v-2H2v2c0 1.1.9 2 2 2h3zM18 8H6v8h12z\"\n}), 'FitScreen');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M12 5V2L8 6l4 4V7c3.31 0 6 2.69 6 6 0 2.97-2.17 5.43-5 5.91v2.02c3.95-.49 7-3.85 7-7.93 0-4.42-3.58-8-8-8m-6 8c0-1.65.67-3.15 1.76-4.24L6.34 7.34C4.9 8.79 4 10.79 4 13c0 4.08 3.05 7.44 7 7.93v-2.02c-2.83-.48-5-2.94-5-5.91\"\n}), 'RestartAlt');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M15.5 14h-.79l-.28-.27C15.41 12.59 16 11.11 16 9.5 16 5.91 13.09 3 9.5 3S3 5.91 3 9.5 5.91 16 9.5 16c1.61 0 3.09-.59 4.23-1.57l.27.28v.79l5 4.99L20.49 19zm-6 0C7.01 14 5 11.99 5 9.5S7.01 5 9.5 5 14 7.01 14 9.5 11.99 14 9.5 14M7 9h5v1H7z\"\n}), 'ZoomOut');", "import React, { useCallback } from 'react'\n\nimport { useTheme } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { useCanvasAutorun } from '../../useCanvasAutorun.ts'\nimport DragHandle, { scrollbarThumbFill } from '../DragHandle.tsx'\nimport { msaThumbnail } from '../msa/msaRaster.ts'\nimport { MINIMAP_BAR_HEIGHT, getMinimapLayout } from './minimapLayout.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst Minimap = observer(function ({ model }: { model: MsaViewModel }) {\n const { minimapHeight, msaCanvasWidth, highResScaleFactor } = model\n const theme = useTheme()\n const { unit, s, w, polygonHeight, polygonPoints } = getMinimapLayout(model)\n\n // the whole alignment, sampled down to the bar\n const barWidth = Math.round(msaCanvasWidth * highResScaleFactor)\n const barHeight = Math.round(MINIMAP_BAR_HEIGHT * highResScaleFactor)\n const ref = useCanvasAutorun({\n draw: ctx => {\n ctx.resetTransform()\n ctx.clearRect(0, 0, barWidth, barHeight)\n const thumbnail = msaThumbnail({\n model,\n theme,\n height: MINIMAP_BAR_HEIGHT,\n })\n if (thumbnail) {\n ctx.imageSmoothingEnabled = true\n ctx.drawImage(\n thumbnail,\n 0,\n 0,\n thumbnail.width,\n thumbnail.height,\n 0,\n 0,\n barWidth,\n barHeight,\n )\n }\n },\n width: barWidth,\n height: barHeight,\n deps: [model, theme],\n })\n\n const onDrag = useCallback(\n (delta: number, startScroll: number) => {\n model.setScrollX(startScroll - delta / unit)\n },\n [model, unit],\n )\n\n return (\n // sized and placed to match the alignment canvas exactly: a minimap that\n // spans a different width than the columns it maps puts its viewport\n // rectangle over the wrong ones\n <div\n style={{\n position: 'relative',\n height: minimapHeight,\n width: msaCanvasWidth,\n flexShrink: 0,\n }}\n >\n <canvas\n ref={ref}\n width={barWidth}\n height={barHeight}\n onMouseDown={event => {\n if (event.button === 0 && unit > 0) {\n const x =\n event.clientX - event.currentTarget.getBoundingClientRect().left\n model.setScrollX(-x / unit + msaCanvasWidth / 2)\n }\n }}\n style={{\n display: 'block',\n width: msaCanvasWidth,\n height: MINIMAP_BAR_HEIGHT,\n boxSizing: 'border-box',\n border: `1px solid ${theme.palette.text.secondary}`,\n }}\n />\n <DragHandle\n axis=\"x\"\n variant=\"thumb\"\n getStart={() => model.scrollX}\n onDrag={onDrag}\n style={{\n top: 0,\n left: Math.max(0, s),\n height: MINIMAP_BAR_HEIGHT,\n width: w,\n }}\n />\n\n <svg height={polygonHeight} width={msaCanvasWidth}>\n <polygon fill={scrollbarThumbFill} points={polygonPoints} />\n </svg>\n </div>\n )\n})\n\nexport default Minimap\n", "import React from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport AnnotationLegend from './AnnotationLegend.tsx'\nimport MSACanvas from './MSACanvas.tsx'\nimport MSAMouseoverCanvas from './MSAMouseoverCanvas.tsx'\n\n// types\nimport type { MsaViewModel } from '../../model.ts'\n\nconst MSAPanel = observer(function ({ model }: { model: MsaViewModel }) {\n return (\n <div style={{ position: 'relative' }}>\n <MSACanvas model={model} />\n <MSAMouseoverCanvas model={model} />\n <AnnotationLegend model={model} />\n </div>\n )\n})\n\nexport default MSAPanel\n", "import React from 'react'\n\nimport ExpandLess from '@mui/icons-material/ExpandLess'\nimport ExpandMore from '@mui/icons-material/ExpandMore'\nimport { IconButton, Paper, Typography } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { legendZIndex } from '../../constants.ts'\nimport { legendRows } from './legendRows.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst AnnotationLegend = observer(function ({\n model,\n}: {\n model: MsaViewModel\n}) {\n const { legends, showDomainLegend: expanded } = model\n const rows = legendRows(legends)\n const ExpandIcon = expanded ? ExpandLess : ExpandMore\n\n return rows.length > 0 ? (\n <Paper\n elevation={3}\n style={{\n position: 'absolute',\n top: 4,\n right: 4,\n zIndex: legendZIndex,\n maxWidth: 220,\n maxHeight: '60%',\n display: 'flex',\n flexDirection: 'column',\n opacity: 0.95,\n pointerEvents: 'none',\n }}\n >\n <IconButton\n size=\"small\"\n title={expanded ? 'Collapse key' : 'Expand key'}\n style={{\n padding: 1,\n pointerEvents: 'auto',\n ...(expanded && { position: 'absolute', top: 0, right: 0 }),\n }}\n onClick={() => {\n model.setShowDomainLegend(!expanded)\n }}\n >\n <ExpandIcon style={{ fontSize: 14 }} />\n </IconButton>\n {expanded ? (\n <div style={{ overflow: 'auto', padding: '2px 6px 4px' }}>\n {rows.map((row, i) => (\n <div\n key={row.key}\n style={{\n display: 'flex',\n alignItems: 'center',\n gap: 4,\n marginRight: i === 0 ? 18 : 0,\n }}\n >\n {row.color ? (\n <div\n style={{\n width: 9,\n height: 9,\n flexShrink: 0,\n background: row.color,\n }}\n />\n ) : null}\n <Typography\n variant=\"caption\"\n noWrap\n title={\n row.hint && row.hint !== row.label\n ? `${row.label} (${row.hint})`\n : row.label\n }\n style={{\n fontSize: 10,\n lineHeight: 1.4,\n fontWeight: row.color ? undefined : 'bold',\n pointerEvents: 'auto',\n }}\n >\n {row.label}\n </Typography>\n </div>\n ))}\n </div>\n ) : null}\n </Paper>\n ) : null\n})\n\nexport default AnnotationLegend\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"m12 8-6 6 1.41 1.41L12 10.83l4.59 4.58L18 14z\"\n}), 'ExpandLess');", "import React, { useCallback, useRef } from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport { useWheelScroll } from '../../useWheelScroll.ts'\nimport { alignmentAriaLabel } from '../controls.ts'\nimport Loading from './Loading.tsx'\nimport MSACanvasBlock from './MSACanvasBlock.tsx'\nimport { onMsaKey } from './msaKeys.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst MSACanvas = observer(function ({ model }: { model: MsaViewModel }) {\n const {\n MSA,\n msaFilehandle,\n height,\n msaCanvasWidth,\n blocks2d,\n scrollZoom,\n scrollX,\n scrollY,\n } = model\n const ref = useRef<HTMLDivElement>(null)\n const onScrollX = useCallback(\n (d: number) => {\n model.doScrollX(d)\n },\n [model],\n )\n const onScrollY = useCallback(\n (d: number) => {\n model.doScrollY(d)\n },\n [model],\n )\n const onZoom = useCallback(\n (scaleFactor: number, offsetX: number, offsetY: number) => {\n model.zoomToPos(scaleFactor, offsetX, offsetY, model.wheelZoomAxis)\n },\n [model],\n )\n const { onMouseDown, onMouseUp } = useWheelScroll({\n ref,\n onScrollX,\n onScrollY,\n onZoom,\n scrollZoom,\n })\n\n return (\n <div\n ref={ref}\n // screenshot callouts anchor to columns from this rect's origin:\n // col*colWidth + scrollX, row*rowHeight + scrollY\n data-testid=\"msa_canvas\"\n tabIndex={0}\n aria-label={alignmentAriaLabel}\n onKeyDown={event => {\n if (onMsaKey(model, event)) {\n event.preventDefault()\n }\n }}\n onMouseDown={event => {\n // a shifted press selects cells (useMsaBlockMouse), so it takes the\n // focus Escape clears from, and leaves out the pan and the page's own\n // text selection\n if (event.shiftKey) {\n event.preventDefault()\n ref.current?.focus({ preventScroll: true })\n } else {\n onMouseDown(event)\n }\n }}\n onMouseUp={onMouseUp}\n style={{\n position: 'relative',\n height,\n width: msaCanvasWidth,\n overflow: 'hidden',\n }}\n >\n {!MSA && !msaFilehandle ? null : MSA ? (\n // one transform for the whole block set, so a scroll frame is a\n // compositor move rather than a style write per block\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `translate(${scrollX}px, ${scrollY}px)`,\n willChange: 'transform',\n }}\n >\n {blocks2d.map(([bx, by]) => (\n <MSACanvasBlock\n key={`${bx}_${by}`}\n model={model}\n offsetX={bx}\n offsetY={by}\n />\n ))}\n </div>\n ) : (\n <Loading />\n )}\n </div>\n )\n})\n\nexport default MSACanvas\n", "import React from 'react'\n\nimport { CircularProgress, Typography } from '@mui/material'\nexport default function Loading() {\n return (\n <div\n style={{\n position: 'absolute',\n left: '50%',\n top: '50%',\n }}\n >\n <CircularProgress />\n <Typography>Loading...</Typography>\n </div>\n )\n}\n", "import React from 'react'\n\nimport BaseTooltip from '@jbrowse/core/ui/BaseTooltip'\nimport { useTheme } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { useCanvasAutorun } from '../../useCanvasAutorun.ts'\nimport { drawMsaRaster, rasterApplies } from './msaRaster.ts'\nimport { renderBoxFeatureCanvasBlock } from './renderBoxFeatureCanvasBlock.ts'\nimport { renderMSABlock } from './renderMSABlock.ts'\nimport { useMsaBlockMouse } from './useMsaBlockMouse.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst MSACanvasBlock = observer(function ({\n model,\n offsetX,\n offsetY,\n}: {\n model: MsaViewModel\n offsetX: number\n offsetY: number\n}) {\n const { blockSize, highResScaleFactor } = model\n const theme = useTheme()\n const { anchor, onMouseMove, onMouseDown, onClick, onMouseLeave } =\n useMsaBlockMouse({ model, offsetX, offsetY })\n\n const canvasSize = blockSize * highResScaleFactor\n const ref = useCanvasAutorun({\n draw: ctx => {\n ctx.resetTransform()\n ctx.clearRect(0, 0, canvasSize, canvasSize)\n renderBoxFeatureCanvasBlock({\n ctx,\n theme,\n offsetX,\n offsetY,\n model,\n })\n const rasterTiles = rasterApplies(model)\n if (rasterTiles) {\n drawMsaRaster({ ctx, model, theme, offsetX, offsetY })\n }\n renderMSABlock({\n ctx,\n theme,\n offsetX,\n offsetY,\n model,\n rasterTiles,\n })\n },\n width: canvasSize,\n height: canvasSize,\n deps: [model, offsetX, offsetY, theme],\n })\n\n const { hoveredInsertion, mouseOverDomains } = model\n\n return (\n <>\n <canvas\n ref={ref}\n onMouseMove={event => {\n if (ref.current) {\n onMouseMove(event, ref.current)\n }\n }}\n onMouseDown={event => {\n if (ref.current) {\n onMouseDown(event, ref.current)\n }\n }}\n onClick={event => {\n if (ref.current) {\n onClick(event, ref.current)\n }\n }}\n onMouseLeave={() => {\n onMouseLeave()\n }}\n width={canvasSize}\n height={canvasSize}\n style={{\n position: 'absolute',\n top: offsetY,\n left: offsetX,\n width: blockSize,\n height: blockSize,\n }}\n />\n {anchor ? (\n <BaseTooltip clientPoint={anchor.clientPoint}>\n {hoveredInsertion ? (\n <>\n Insertion ({hoveredInsertion.letters.length}\n {model.sequenceType === 'amino' ? 'aa' : 'bp'}):{' '}\n {hoveredInsertion.letters.length > 20\n ? `${hoveredInsertion.letters.slice(0, 20)}...`\n : hoveredInsertion.letters}\n </>\n ) : (\n mouseOverDomains.map(d => (\n <div key={`${d.accession}-${d.start}-${d.end}`}>\n <b>{d.name}</b> ({d.accession}) {d.start}-{d.end}\n {d.description ? (\n <>\n <br />\n {d.description}\n </>\n ) : null}\n </div>\n ))\n )}\n </BaseTooltip>\n ) : null}\n </>\n )\n})\n\nexport default MSACanvasBlock\n", "import { useRef } from 'react'\n\nimport { dragSelection, maxClickTravel } from '../selectionDrag.ts'\nimport { useHoverAnchor } from '../useHoverAnchor.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { ClientPoint } from '../selectionDrag.ts'\nimport type React from 'react'\n\n/**\n * Translates pointer events over one MSA block into model column/row hover and\n * click state, and reports where a tooltip should be anchored.\n *\n * The anchor is only tracked when there is something to show (an insertion or a\n * domain under the cursor), so plain mouse movement over the alignment updates\n * the canvas overlay without re-rendering this component. Each track tooltips\n * its own column statistics, and the header reads out the hovered row, residue\n * and position.\n */\nexport function useMsaBlockMouse({\n model,\n offsetX,\n offsetY,\n}: {\n model: MsaViewModel\n offsetX: number\n offsetY: number\n}) {\n const { anchor, hoverAt, clearAnchor } = useHoverAnchor<true>()\n const downAt = useRef<{ x: number; y: number }>(undefined)\n\n // The block's rect places its cells on the page. A drag keeps the mapping\n // it started with, so each point subtracts the scroll since then.\n function cellMapper(el: HTMLElement) {\n const { left, top } = el.getBoundingClientRect()\n const { scrollX, scrollY } = model\n return ({ clientX, clientY }: ClientPoint) => ({\n col: Math.floor(\n (clientX - left + offsetX - (model.scrollX - scrollX)) / model.colWidth,\n ),\n row: Math.floor(\n (clientY - top + offsetY - (model.scrollY - scrollY)) / model.rowHeight,\n ),\n })\n }\n\n function colRow(event: React.MouseEvent, el: HTMLElement) {\n return cellMapper(el)(event)\n }\n\n // a block can extend past the alignment (the last block is a full tile wide,\n // and the panel is taller than the rows when there are few of them), so a\n // pointer inside the block is not necessarily over a cell\n function inBounds({ col, row }: { col: number; row: number }) {\n return col >= 0 && col < model.numColumns && row >= 0 && row < model.numRows\n }\n\n function onMouseMove(event: React.MouseEvent, el: HTMLElement) {\n const pos = colRow(event, el)\n const hit = inBounds(pos)\n model.setMousePos(hit ? pos.col : undefined, hit ? pos.row : undefined)\n\n const hasTooltip =\n !!model.hoveredInsertion || model.mouseOverDomains.length > 0\n hoverAt(event, hasTooltip || undefined)\n }\n\n // shift+drag selects a block; MSACanvas leaves a shifted press out of its\n // pan\n function onMouseDown(event: React.MouseEvent, el: HTMLElement) {\n downAt.current = { x: event.clientX, y: event.clientY }\n if (event.shiftKey && event.button === 0) {\n dragSelection(model, event, cellMapper(el))\n }\n }\n\n function onClick(event: React.MouseEvent, el: HTMLElement) {\n const down = downAt.current\n downAt.current = undefined\n if (\n down &&\n Math.hypot(event.clientX - down.x, event.clientY - down.y) >\n maxClickTravel\n ) {\n return\n }\n const pos = colRow(event, el)\n const { col, row } = pos\n const { mouseClickCol, mouseClickRow } = model\n // clicking the same cell again clears the pinned crosshair, and so does\n // clicking past the end of the alignment -- there is no cell to pin there\n const same = col === mouseClickCol && row === mouseClickRow\n const keep = inBounds(pos) && !same\n model.setMouseClickPos(keep ? col : undefined, keep ? row : undefined)\n }\n\n function onMouseLeave() {\n model.setMousePos()\n clearAnchor()\n }\n\n return { anchor, onMouseMove, onMouseDown, onClick, onMouseLeave }\n}\n", "import React from 'react'\n\nimport { isAlive } from '@jbrowse/mobx-state-tree'\nimport { useTheme } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { msaOverlayZIndex } from '../../constants.ts'\nimport { useCanvasAutorun } from '../../useCanvasAutorun.ts'\nimport { renderMouseover } from './renderMSAMouseover.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst MSAMouseoverCanvas = observer(function ({\n model,\n}: {\n model: MsaViewModel\n}) {\n const { height, msaCanvasWidth: width, highResScaleFactor } = model\n const theme = useTheme()\n const canvasWidth = width * highResScaleFactor\n const canvasHeight = height * highResScaleFactor\n const ref = useCanvasAutorun({\n draw: ctx => {\n if (isAlive(model)) {\n renderMouseover({ ctx, model, theme })\n }\n },\n width: canvasWidth,\n height: canvasHeight,\n deps: [model, theme],\n })\n\n return (\n <canvas\n ref={ref}\n id=\"mouseover\"\n width={canvasWidth}\n height={canvasHeight}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width,\n height,\n zIndex: msaOverlayZIndex,\n pointerEvents: 'none',\n }}\n />\n )\n})\n\nexport default MSAMouseoverCanvas\n", "import { clickColor, hoverColor, multiRowHoverColor } from '../overlayColors.ts'\nimport {\n renderPersistentHighlights,\n renderSelection,\n} from './renderHighlights.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { Theme } from '@mui/material'\n\nexport function renderMouseover({\n ctx,\n model,\n theme,\n}: {\n ctx: CanvasRenderingContext2D\n model: MsaViewModel\n theme: Theme\n}) {\n const {\n mouseCol,\n colWidth,\n msaCanvasWidth: width,\n height,\n rowHeight,\n scrollX,\n scrollY,\n mouseRow,\n mouseClickRow,\n mouseClickCol,\n highResScaleFactor,\n hoveredRowIndices,\n } = model\n ctx.resetTransform()\n ctx.clearRect(0, 0, width * highResScaleFactor, height * highResScaleFactor)\n ctx.scale(highResScaleFactor, highResScaleFactor)\n\n // rows and columns sit at a fixed pitch, so an index is all it takes to place\n // a full-width or full-height band (matching fillRow in TreeCanvas)\n const rowBand = (index: number) => {\n ctx.fillRect(0, index * rowHeight + scrollY, width, rowHeight)\n }\n const colBand = (index: number) => {\n ctx.fillRect(index * colWidth + scrollX, 0, colWidth, height)\n }\n\n renderPersistentHighlights({\n ctx,\n model,\n theme,\n offsetX: -scrollX,\n offsetY: -scrollY,\n width,\n height,\n })\n renderSelection({ ctx, model, offsetX: -scrollX, offsetY: -scrollY, height })\n\n // every tip under a hovered tree node stays lit\n ctx.fillStyle = multiRowHoverColor\n for (const rowIndex of hoveredRowIndices) {\n rowBand(rowIndex)\n }\n\n ctx.fillStyle = hoverColor\n if (mouseCol !== undefined) {\n colBand(mouseCol)\n }\n if (mouseRow !== undefined) {\n rowBand(mouseRow)\n }\n ctx.fillStyle = clickColor\n if (mouseClickCol !== undefined) {\n colBand(mouseClickCol)\n }\n if (mouseClickRow !== undefined) {\n rowBand(mouseClickRow)\n }\n}\n", "import React from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport { headerRunsAcross } from './headerLayout.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\n/**\n * The row panel headers, in a band above the panels beside the tree ruler and\n * the minimap. A narrow strip's name is DOM text turned on its side, since the\n * canvas layer has no rotation, and the SVG export draws it with a\n * `rotate(-90)`. A panel wider than the band is tall writes its name across.\n */\nconst RowPanelHeaders = observer(function ({ model }: { model: MsaViewModel }) {\n const { resolvedRowPanels, rowPanelsHeaderHeight, fontSize } = model\n return resolvedRowPanels.length > 0 ? (\n <div\n style={{\n display: 'flex',\n flexShrink: 0,\n height: rowPanelsHeaderHeight,\n alignItems: 'flex-end',\n }}\n >\n {resolvedRowPanels.map(panel => {\n const across = headerRunsAcross(panel.width)\n return (\n <div\n key={panel.id}\n title={panel.header}\n style={{\n width: panel.width,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n ...(across\n ? { fontSize, textAlign: 'center' }\n : {\n height: rowPanelsHeaderHeight,\n fontSize: Math.min(fontSize, panel.width),\n // vertical-rl reads top to bottom, and the half turn makes\n // it read upwards from the strip, as rotate(-90) exports\n writingMode: 'vertical-rl',\n transform: 'rotate(180deg)',\n }),\n }}\n >\n {panel.header}\n </div>\n )\n })}\n </div>\n ) : null\n})\n\nexport default RowPanelHeaders\n", "import React, { useCallback, useRef } from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport { useWheelScroll } from '../../useWheelScroll.ts'\nimport RowPanelBlock from './RowPanelBlock.tsx'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { ResolvedRowPanel } from '../../types.ts'\n\nconst RowPanel = observer(function ({\n model,\n panel,\n}: {\n model: MsaViewModel\n panel: ResolvedRowPanel\n}) {\n const ref = useRef<HTMLDivElement>(null)\n const { height, blocksY, scrollY } = model\n const onScrollY = useCallback(\n (d: number) => {\n model.doScrollY(d)\n },\n [model],\n )\n const { onMouseDown, onMouseUp } = useWheelScroll({ ref, onScrollY })\n\n return (\n <div\n ref={ref}\n data-testid={`rowpanel_${panel.id}`}\n onMouseDown={onMouseDown}\n onMouseUp={onMouseUp}\n style={{\n height,\n width: panel.width,\n flexShrink: 0,\n overflow: 'hidden',\n position: 'relative',\n }}\n >\n {/* one transform for the whole block set, matching TreeCanvas: the\n strips scroll in lockstep with the tree and the alignment */}\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `translateY(${scrollY}px)`,\n willChange: 'transform',\n }}\n >\n {blocksY.map(block => (\n <RowPanelBlock\n key={block}\n model={model}\n panel={panel}\n offsetY={block}\n />\n ))}\n </div>\n </div>\n )\n})\n\nconst RowPanels = observer(function ({ model }: { model: MsaViewModel }) {\n const { resolvedRowPanels } = model\n return resolvedRowPanels.length > 0 ? (\n <div style={{ display: 'flex', flexShrink: 0 }}>\n {resolvedRowPanels.map(panel => (\n <RowPanel key={panel.id} model={model} panel={panel} />\n ))}\n </div>\n ) : null\n})\n\nexport default RowPanels\n", "import React from 'react'\n\nimport BaseTooltip from '@jbrowse/core/ui/BaseTooltip'\nimport { useTheme } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { featureField, featureName } from '../../featureFields.ts'\nimport { useCanvasAutorun } from '../../useCanvasAutorun.ts'\nimport { useHoverAnchor } from '../useHoverAnchor.ts'\nimport { renderRowPanel } from './renderRowPanel.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { ResolvedRowPanel } from '../../types.ts'\n\n// what the cell or span under the pointer reads, which is the field a strip\n// colors by, and a span's name, its coordinates and its encoded field\nfunction hoverLines({\n model,\n panel,\n name,\n x,\n}: {\n model: MsaViewModel\n panel: ResolvedRowPanel\n name: string\n x: number\n}) {\n if (panel.kind === 'strip') {\n return [\n `${panel.header}: ${model.rowDataOf(name)?.[panel.field] ?? '(none)'}`,\n ]\n }\n const span = panel.spans\n .get(name)\n ?.findLast(s => x >= s.xStart && x <= s.xEnd)\n if (!span) {\n return []\n }\n const { annotation } = span\n const strand =\n annotation.strand === undefined\n ? ''\n : annotation.strand < 0\n ? ' (-)'\n : ' (+)'\n const value = panel.field ? featureField(annotation, panel.field) : undefined\n return [\n featureName(annotation) ?? annotation.accession,\n `${annotation.start}-${annotation.end}${strand}`,\n ...(value === undefined ? [] : [`${panel.field}: ${value}`]),\n ]\n}\n\nconst RowPanelBlock = observer(function ({\n model,\n panel,\n offsetY,\n}: {\n model: MsaViewModel\n panel: ResolvedRowPanel\n offsetY: number\n}) {\n const { anchor, hoverAt, clearAnchor } = useHoverAnchor<{\n name: string\n lines: string[]\n }>()\n const theme = useTheme()\n const { blockSize, highResScaleFactor, rowHeight } = model\n const width = panel.width\n const height = blockSize\n const canvasWidth = width * highResScaleFactor\n const canvasHeight = height * highResScaleFactor\n\n const ref = useCanvasAutorun({\n draw: ctx => {\n ctx.resetTransform()\n ctx.clearRect(0, 0, canvasWidth, canvasHeight)\n renderRowPanel({ ctx, model, theme, panel, x: 0, offsetY })\n },\n width: canvasWidth,\n height: canvasHeight,\n deps: [model, theme, panel, offsetY],\n })\n\n return (\n <>\n <canvas\n ref={ref}\n width={canvasWidth}\n height={canvasHeight}\n style={{ position: 'absolute', top: offsetY, left: 0, width, height }}\n onMouseMove={event => {\n // the blocks are laid out in row space and scrolled by a transform\n // on their container, so the pointer's row comes off the canvas box\n const { left, top } = event.currentTarget.getBoundingClientRect()\n const row = Math.floor((event.clientY - top + offsetY) / rowHeight)\n const name = model.leaves[row]?.data.name\n const lines =\n name === undefined\n ? []\n : hoverLines({\n model,\n panel,\n name,\n x: event.clientX - left,\n })\n hoverAt(\n event,\n name === undefined || lines.length === 0\n ? undefined\n : { name, lines },\n )\n model.setMousePos(undefined, name === undefined ? undefined : row)\n }}\n onMouseLeave={() => {\n clearAnchor()\n model.setMousePos(undefined, undefined)\n }}\n />\n {anchor ? (\n <BaseTooltip clientPoint={anchor.clientPoint}>\n <div>{anchor.value.name}</div>\n {anchor.value.lines.map(line => (\n <div key={line}>{line}</div>\n ))}\n </BaseTooltip>\n ) : null}\n </>\n )\n})\n\nexport default RowPanelBlock\n", "import type { Annotation } from './types.ts'\n\n/**\n * The value a feature gives an encoded field: an Annotation property, else one\n * of the GFF attributes the parser kept.\n */\nexport function featureField(annotation: Annotation, field: string) {\n const own = (annotation as unknown as Record<string, unknown>)[field]\n const value = own ?? annotation.attributes?.[field]\n return typeof value === 'string' ? value : undefined\n}\n\n/**\n * The name a feature answers to in a transform: its GFF `Name` attribute, else\n * the name the parser gave it.\n */\nexport function featureName(annotation: Annotation) {\n return featureField(annotation, 'Name') ?? featureField(annotation, 'name')\n}\n", "import React, { useState } from 'react'\n\nimport { useTheme } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { useCanvasAutorun } from '../../useCanvasAutorun.ts'\nimport {\n drawTreeOverview,\n drawTreeOverviewBox,\n treeOverviewImage,\n} from './renderTreeOverview.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\n/**\n * The brush on the row scale: the whole tree drawn small above the tree panel,\n * with the focused subtree boxed. A click focuses the subtree under the\n * pointer, and a click inside the box clears the focus.\n *\n * The tree itself comes off a cached offscreen canvas, so the frames a pointer\n * moving across it costs are a blit and two boxes.\n */\nconst TreeOverview = observer(function ({ model }: { model: MsaViewModel }) {\n const { effectiveTreeAreaWidth, overviewHeight, highResScaleFactor } = model\n const theme = useTheme()\n const [hover, setHover] = useState<{ id: string; rows: [number, number] }>()\n const width = Math.round(effectiveTreeAreaWidth * highResScaleFactor)\n const height = Math.round(overviewHeight * highResScaleFactor)\n\n const ref = useCanvasAutorun({\n draw: ctx => {\n ctx.resetTransform()\n ctx.clearRect(0, 0, width, height)\n const image = treeOverviewImage({\n model,\n theme,\n width: effectiveTreeAreaWidth,\n height: overviewHeight,\n scale: highResScaleFactor,\n })\n ctx.scale(highResScaleFactor, highResScaleFactor)\n const box = {\n model,\n ctx,\n width: effectiveTreeAreaWidth,\n height: overviewHeight,\n }\n if (image) {\n ctx.drawImage(\n image,\n 0,\n 0,\n image.width,\n image.height,\n 0,\n 0,\n box.width,\n box.height,\n )\n } else {\n drawTreeOverview({ ...box, theme })\n }\n if (hover) {\n drawTreeOverviewBox({\n ...box,\n rows: hover.rows,\n color: theme.palette.text.secondary,\n })\n }\n const focus = model.treeOverviewFocusRows\n if (focus) {\n drawTreeOverviewBox({\n ...box,\n rows: focus,\n color: theme.palette.text.primary,\n })\n }\n },\n width,\n height,\n deps: [model, theme, hover],\n })\n\n return (\n <canvas\n data-testid=\"tree_overview\"\n ref={ref}\n width={width}\n height={height}\n style={{\n display: 'block',\n flexShrink: 0,\n cursor: 'pointer',\n width: effectiveTreeAreaWidth,\n height: overviewHeight,\n }}\n onMouseMove={event => {\n const hit = model.treeOverviewHit(event.nativeEvent.offsetY)\n setHover(prev => (prev?.id === hit?.id ? prev : hit))\n }}\n onMouseLeave={() => {\n setHover(undefined)\n }}\n onClick={event => {\n model.treeOverviewClick(event.nativeEvent.offsetY)\n }}\n />\n )\n})\n\nexport default TreeOverview\n", "import React from 'react'\n\nimport { observer } from 'mobx-react'\n\nimport TreeCanvas from './TreeCanvas.tsx'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst TreePanel = observer(function ({ model }: { model: MsaViewModel }) {\n const { effectiveTreeAreaWidth } = model\n return (\n <div\n style={{\n overflow: 'hidden',\n flexShrink: 0,\n width: effectiveTreeAreaWidth,\n }}\n >\n <TreeCanvas model={model} />\n </div>\n )\n})\n\nexport default TreePanel\n", "import React, { useCallback, useRef } from 'react'\n\nimport { isAlive } from '@jbrowse/mobx-state-tree'\nimport { observer } from 'mobx-react'\n\nimport { useCanvasAutorun } from '../../useCanvasAutorun.ts'\nimport { useWheelScroll } from '../../useWheelScroll.ts'\nimport CladeLabels from './CladeLabels.tsx'\nimport TreeCanvasBlock from './TreeCanvasBlock.tsx'\nimport { renderTreeMouseover } from './renderTreeMouseover.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst TreeCanvas = observer(function ({ model }: { model: MsaViewModel }) {\n const ref = useRef<HTMLDivElement>(null)\n const {\n height,\n blocksY,\n effectiveTreeAreaWidth,\n scrollY,\n highResScaleFactor,\n } = model\n const onScrollY = useCallback(\n (d: number) => {\n model.doScrollY(d)\n },\n [model],\n )\n const { onMouseDown, onMouseUp } = useWheelScroll({ ref, onScrollY })\n\n const canvasWidth = effectiveTreeAreaWidth * highResScaleFactor\n const canvasHeight = height * highResScaleFactor\n const mouseoverRef = useCanvasAutorun({\n draw: ctx => {\n if (isAlive(model)) {\n renderTreeMouseover({ ctx, model })\n }\n },\n width: canvasWidth,\n height: canvasHeight,\n deps: [model],\n })\n\n return (\n <div\n ref={ref}\n onMouseDown={onMouseDown}\n onMouseUp={onMouseUp}\n style={{\n height,\n position: 'relative',\n width: effectiveTreeAreaWidth,\n }}\n >\n {/* one transform for the whole block set, matching MSACanvas: the tree\n scrolls in lockstep with the alignment and on the same compositor move */}\n <div\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n transform: `translateY(${scrollY}px)`,\n willChange: 'transform',\n }}\n >\n {blocksY.map(block => (\n <TreeCanvasBlock key={block} model={model} offsetY={block} />\n ))}\n <CladeLabels model={model} />\n </div>\n <canvas\n ref={mouseoverRef}\n width={canvasWidth}\n height={canvasHeight}\n style={{\n position: 'absolute',\n top: 0,\n left: 0,\n width: effectiveTreeAreaWidth,\n height,\n zIndex: 1000,\n pointerEvents: 'none',\n }}\n />\n </div>\n )\n})\n\nexport default TreeCanvas\n", "import React from 'react'\n\nimport { useTheme } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { cladeLabelBoxes } from './cladeBrackets.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\n/**\n * The label of each bracket, in the gutter beside its bar, where the canvas\n * draws the bar itself. The text is DOM text, turned on its side for a clade\n * shorter than the font, the way the strip headers are; the SVG export draws\n * the same labels with a `rotate(-90)`.\n */\nconst CladeLabels = observer(function ({ model }: { model: MsaViewModel }) {\n const theme = useTheme()\n const { fontSize } = model\n return (\n <>\n {cladeLabelBoxes(model).map(box => (\n <div\n key={box.key}\n title={box.label}\n style={{\n position: 'absolute',\n left: box.left,\n top: box.top,\n width: box.width,\n height: box.height,\n display: 'flex',\n alignItems: 'center',\n color: box.color ?? theme.palette.text.primary,\n fontSize,\n overflow: 'hidden',\n textOverflow: 'ellipsis',\n whiteSpace: 'nowrap',\n pointerEvents: 'none',\n // vertical-rl reads top to bottom, and the half turn makes it\n // read upwards, which is what rotate(-90) exports\n ...(box.horizontal\n ? {}\n : { writingMode: 'vertical-rl', transform: 'rotate(180deg)' }),\n }}\n >\n {box.label}\n </div>\n ))}\n </>\n )\n})\n\nexport default CladeLabels\n", "import React, { useState } from 'react'\n\nimport BaseTooltip from '@jbrowse/core/ui/BaseTooltip'\nimport { makeStyles } from '@jbrowse/core/util/tss-react'\nimport { useTheme } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { useCanvasAutorun } from '../../useCanvasAutorun.ts'\nimport TreeMenu from './TreeMenu.tsx'\nimport { renderTreeCanvas } from './renderTreeCanvas.ts'\nimport { useTreeHover } from './useTreeHover.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { TreeMenuTarget } from './TreeMenu.tsx'\n\nconst useStyles = makeStyles()(theme => ({\n hover: {\n position: 'absolute',\n pointerEvents: 'none',\n zIndex: 100,\n background: theme.palette.action.hover,\n },\n}))\n\nconst TreeCanvasBlock = observer(function ({\n model,\n offsetY,\n}: {\n model: MsaViewModel\n offsetY: number\n}) {\n const { classes } = useStyles()\n const theme = useTheme()\n const [menu, setMenu] = useState<TreeMenuTarget>()\n const { clickMap, anchor, hitTest, onMouseMove, onMouseLeave } = useTreeHover(\n { model, offsetY },\n )\n const hovered = anchor?.value\n\n const { effectiveTreeAreaWidth, blockSize, highResScaleFactor } = model\n // TreePanel clips to the tree area, so a wider canvas is wasted backing store\n const width = effectiveTreeAreaWidth\n const height = blockSize\n\n const canvasWidth = width * highResScaleFactor\n const canvasHeight = height * highResScaleFactor\n const ref = useCanvasAutorun({\n draw: ctx => {\n ctx.resetTransform()\n ctx.clearRect(0, 0, canvasWidth, canvasHeight)\n renderTreeCanvas({\n ctx,\n model,\n offsetY,\n clickMap,\n theme,\n })\n },\n width: canvasWidth,\n height: canvasHeight,\n deps: [model, clickMap, offsetY, theme],\n })\n\n const style = {\n width,\n height,\n top: offsetY,\n left: 0,\n position: 'absolute',\n } as const\n\n return (\n <>\n {menu ? (\n <TreeMenu\n node={menu}\n model={model}\n onClose={() => {\n setMenu(undefined)\n }}\n />\n ) : null}\n\n <canvas\n ref={ref}\n width={canvasWidth}\n height={canvasHeight}\n style={{ ...style, cursor: hovered ? 'pointer' : 'default' }}\n onMouseMove={event => {\n onMouseMove(event)\n }}\n onMouseLeave={() => {\n onMouseLeave()\n }}\n onClick={event => {\n const entry = hitTest(event)\n if (entry) {\n setMenu({\n x: event.clientX,\n y: event.clientY,\n id: entry.id,\n name: entry.name,\n leaf: !entry.branch,\n })\n }\n }}\n />\n\n {/* direct-hover highlight, drawn only for leaf labels */}\n {hovered && !hovered.branch ? (\n <div\n className={classes.hover}\n style={{\n left: hovered.minX,\n top: hovered.minY,\n width: hovered.maxX - hovered.minX,\n height: hovered.maxY - hovered.minY,\n }}\n />\n ) : null}\n\n {anchor ? (\n <BaseTooltip clientPoint={anchor.clientPoint}>\n {anchor.value.label ?? anchor.value.name}\n </BaseTooltip>\n ) : null}\n </>\n )\n})\n\nexport default TreeCanvasBlock\n", "import React, { lazy } from 'react'\n\nimport { Menu, MenuItem } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst TreeNodeInfoDialog = lazy(\n () => import('./dialogs/TreeNodeInfoDialog.tsx'),\n)\n\nexport interface TreeMenuTarget {\n x: number\n y: number\n name: string\n id: string\n leaf: boolean\n}\n\nconst TreeMenu = observer(function ({\n node,\n model,\n onClose,\n}: {\n node: TreeMenuTarget\n model: MsaViewModel\n onClose: () => void\n}) {\n const { collapsed, showOnly, relativeTo } = model\n const { name, id, leaf } = node\n const isCollapsed = collapsed.includes(id)\n const isRoot = id === model.tree.id\n const noun = leaf ? 'subtree' : 'this node'\n return (\n <Menu\n anchorReference=\"anchorPosition\"\n anchorPosition={{ left: node.x, top: node.y }}\n transitionDuration={0}\n open\n onClose={onClose}\n >\n <MenuItem dense disabled>\n {name}\n </MenuItem>\n {leaf ? (\n <MenuItem\n dense\n onClick={() => {\n model.queueDialog(onClose => [\n TreeNodeInfoDialog,\n { info: model.getRowData(name), model, nodeName: name, onClose },\n ])\n onClose()\n }}\n >\n More info...\n </MenuItem>\n ) : null}\n <MenuItem\n dense\n onClick={() => {\n model.toggleCollapsed(id)\n onClose()\n }}\n >\n {isCollapsed ? `Expand ${noun}` : `Collapse ${noun}`}\n </MenuItem>\n {leaf ? null : (\n <MenuItem\n dense\n onClick={() => {\n model.setShowOnly(showOnly === id ? undefined : id)\n onClose()\n }}\n >\n {showOnly === id\n ? 'Disable show only this node'\n : 'Show only this node'}\n </MenuItem>\n )}\n {leaf || isCollapsed ? null : (\n <MenuItem\n dense\n onClick={() => {\n model.toggleRotated(id)\n onClose()\n }}\n >\n Rotate this node\n </MenuItem>\n )}\n {isRoot ? null : (\n <MenuItem\n dense\n onClick={() => {\n model.rerootAt(id)\n onClose()\n }}\n >\n Reroot here\n </MenuItem>\n )}\n {leaf ? (\n <MenuItem\n dense\n onClick={() => {\n model.drawRelativeTo(name)\n onClose()\n }}\n >\n Indicate differences from this row\n </MenuItem>\n ) : null}\n {leaf && relativeTo ? (\n <MenuItem\n dense\n onClick={() => {\n model.drawRelativeTo(undefined)\n onClose()\n }}\n >\n Clear reference row\n </MenuItem>\n ) : null}\n </Menu>\n )\n})\n\nexport default TreeMenu\n", "import { useState } from 'react'\n\nimport { useHoverAnchor } from '../useHoverAnchor.ts'\nimport { ClickMapIndex } from './clickMap.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { ClickEntry } from './clickMap.ts'\nimport type React from 'react'\n\n/**\n * Owns hit-testing for one tree block: the spatial index the render pass fills\n * in, the entry under the pointer with its tooltip anchor, and the model hover\n * state that the MSA panel mirrors.\n */\nexport function useTreeHover({\n model,\n offsetY,\n}: {\n model: MsaViewModel\n offsetY: number\n}) {\n const [clickMap] = useState(() => new ClickMapIndex())\n const { anchor, hoverAt, clearAnchor } = useHoverAnchor<ClickEntry>()\n\n // leaf labels win over the branch/bubble targets they overlap, so a click on a\n // name opens the leaf's menu\n function hitTest(event: React.MouseEvent) {\n const x = event.nativeEvent.offsetX\n const y = event.nativeEvent.offsetY + offsetY\n const entries = clickMap.search({\n minX: x,\n maxX: x + 1,\n minY: y,\n maxY: y + 1,\n })\n return entries.find(entry => !entry.branch) ?? entries[0]\n }\n\n function onMouseMove(event: React.MouseEvent) {\n const entry = hitTest(event)\n hoverAt(event, entry)\n // hovering an internal node highlights every tip below it; hovering a leaf\n // label additionally drives the single-row highlight\n model.setHoveredTreeNode(entry?.id)\n model.setMousePos(\n undefined,\n entry && !entry.branch ? model.rowNamesSet.get(entry.name) : undefined,\n )\n }\n\n function onMouseLeave() {\n clearAnchor()\n model.setHoveredTreeNode(undefined)\n model.setMousePos(undefined, undefined)\n }\n\n return { clickMap, anchor, hitTest, onMouseMove, onMouseLeave }\n}\n", "\n/**\n * @typedef {Float64ArrayConstructor | Float32ArrayConstructor |\n * Uint32ArrayConstructor | Int32ArrayConstructor | Uint16ArrayConstructor |\n * Int16ArrayConstructor | Uint8ArrayConstructor | Int8ArrayConstructor} TypedArrayConstructor\n */\n\n/** @template [T=number] */\nexport default class FlatQueue {\n\n /**\n * Creates an empty queue. If `capacity` is provided, the queue is backed by fixed-size typed\n * arrays for better performance and memory use, but can't grow beyond `capacity`. `values` uses\n * `ValuesArray` (default `Float64Array`) and `ids` uses `IdsArray` (default `Uint32Array`); pass\n * narrower constructors like `Uint16Array` if your values or ids are known to fit them.\n *\n * @param {number} [capacity]\n * @param {TypedArrayConstructor} [ValuesArray]\n * @param {TypedArrayConstructor} [IdsArray]\n */\n constructor(capacity = Infinity, ValuesArray = Float64Array, IdsArray = Uint32Array) {\n const fixed = capacity !== Infinity;\n\n /** @type {T[]} */\n this.ids = fixed ? /** @type {T[]} */ (/** @type {unknown} */ (new IdsArray(capacity))) : [];\n\n /** @type {number[]} */\n this.values = fixed ? /** @type {number[]} */ (/** @type {unknown} */ (new ValuesArray(capacity))) : [];\n\n /** Maximum number of items the queue can hold; `Infinity` for regular-array queues, which grow on demand. */\n this.capacity = capacity;\n\n /** Number of items in the queue. */\n this.length = 0;\n }\n\n /** Removes all items from the queue. */\n clear() {\n this.length = 0;\n }\n\n /**\n * Adds `item` to the queue with the specified `priority`.\n *\n * `priority` must be a number. Items are sorted and returned from low to high priority. Multiple items\n * with the same priority value can be added to the queue, but there is no guaranteed order between these items.\n *\n * For fixed-capacity queues, throws a `RangeError` if the queue is already full.\n *\n * @param {T} item\n * @param {number} priority\n */\n push(item, priority) {\n if (this.length === this.capacity) throw new RangeError('Queue is at capacity.');\n\n let pos = this.length++;\n\n while (pos > 0) {\n const parent = (pos - 1) >> 1;\n const parentValue = this.values[parent];\n if (priority >= parentValue) break;\n this.ids[pos] = this.ids[parent];\n this.values[pos] = parentValue;\n pos = parent;\n }\n\n this.ids[pos] = item;\n this.values[pos] = priority;\n }\n\n /**\n * Removes and returns the item from the head of this queue, which is one of\n * the items with the lowest priority. If this queue is empty, returns `undefined`.\n */\n pop() {\n if (this.length === 0) return undefined;\n\n const ids = this.ids,\n values = this.values,\n top = ids[0],\n last = --this.length;\n\n if (last > 0) {\n const id = ids[last];\n const value = values[last];\n let pos = 0;\n const halfLen = last >> 1;\n\n while (pos < halfLen) {\n const left = (pos << 1) + 1;\n const right = left + 1;\n const child = left + (+(right < last) & +(values[right] < values[left]));\n if (values[child] >= value) break;\n ids[pos] = ids[child];\n values[pos] = values[child];\n pos = child;\n }\n\n ids[pos] = id;\n values[pos] = value;\n }\n\n return top;\n }\n\n /** Returns the item from the head of this queue without removing it. If this queue is empty, returns `undefined`. */\n peek() {\n return this.length > 0 ? this.ids[0] : undefined;\n }\n\n /**\n * Returns the priority value of the item at the head of this queue without\n * removing it. If this queue is empty, returns `undefined`.\n */\n peekValue() {\n return this.length > 0 ? this.values[0] : undefined;\n }\n\n /**\n * Shrinks the internal arrays to `this.length`. No-op for queues with fixed capacity.\n *\n * `pop()` and `clear()` calls don't free memory automatically to avoid unnecessary resize operations.\n * This also means that items that have been added to the queue can't be garbage collected until\n * a new item is pushed in their place, or this method is called.\n */\n shrink() {\n if (Array.isArray(this.ids)) this.ids.length = this.length;\n if (Array.isArray(this.values)) this.values.length = this.length;\n }\n}\n", "import FlatQueue from 'flatqueue';\n\nconst ARRAY_TYPES = [Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array];\nconst VERSION = 3; // serialized format version\n\n/** @typedef {Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor} TypedArrayConstructor */\n/** @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array} TypedArray */\n\nexport default class Flatbush {\n\n /**\n * Recreate a Flatbush index from raw `ArrayBuffer` or `SharedArrayBuffer` data.\n * @param {ArrayBufferLike} data\n * @param {number} [byteOffset=0] byte offset to the start of the Flatbush buffer in the referenced ArrayBuffer.\n * @returns {Flatbush} index\n */\n static from(data, byteOffset = 0) {\n if (byteOffset % 8 !== 0) {\n throw new Error('byteOffset must be 8-byte aligned.');\n }\n\n if (!data || data.byteLength === undefined || 'buffer' in data) {\n throw new Error('Data must be an instance of ArrayBuffer or SharedArrayBuffer.');\n }\n\n const [magic, versionAndType] = new Uint8Array(data, byteOffset + 0, 2);\n if (magic !== 0xfb) {\n throw new Error('Data does not appear to be in a Flatbush format.');\n }\n const version = versionAndType >> 4;\n if (version !== VERSION) {\n throw new Error(`Got v${version} data when expected v${VERSION}.`);\n }\n const ArrayType = ARRAY_TYPES[versionAndType & 0x0f];\n if (!ArrayType) {\n throw new Error('Unrecognized array type.');\n }\n const [nodeSize] = new Uint16Array(data, byteOffset + 2, 1);\n const [numItems] = new Uint32Array(data, byteOffset + 4, 1);\n\n return new Flatbush(numItems, nodeSize, ArrayType, undefined, data, byteOffset);\n }\n\n /**\n * Create a Flatbush index that will hold a given number of items.\n * @param {number} numItems\n * @param {number} [nodeSize=16] Size of the tree node (16 by default).\n * @param {TypedArrayConstructor} [ArrayType=Float64Array] The array type used for coordinates storage (`Float64Array` by default).\n * @param {ArrayBufferConstructor | SharedArrayBufferConstructor} [ArrayBufferType=ArrayBuffer] The array buffer type used to store data (`ArrayBuffer` by default).\n * @param {ArrayBufferLike} [data] (Only used internally)\n * @param {number} [byteOffset=0] (Only used internally)\n */\n constructor(numItems, nodeSize = 16, ArrayType = Float64Array, ArrayBufferType = ArrayBuffer, data, byteOffset = 0) {\n if (numItems === undefined) throw new Error('Missing required argument: numItems.');\n if (isNaN(numItems) || numItems <= 0) throw new Error(`Unexpected numItems value: ${numItems}.`);\n\n this.numItems = +numItems;\n this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535);\n this.byteOffset = byteOffset;\n\n // calculate the total number of nodes in the R-tree to allocate space for\n // and the index of each tree level (used in search later)\n let n = numItems;\n let numNodes = n;\n this._levelBounds = [n * 4];\n do {\n n = Math.ceil(n / this.nodeSize);\n numNodes += n;\n this._levelBounds.push(numNodes * 4);\n } while (n !== 1);\n\n this.ArrayType = ArrayType;\n this.IndexArrayType = numNodes < 16384 ? Uint16Array : Uint32Array;\n\n const arrayTypeIndex = ARRAY_TYPES.indexOf(ArrayType);\n const nodesByteSize = numNodes * 4 * ArrayType.BYTES_PER_ELEMENT;\n\n if (arrayTypeIndex < 0) {\n throw new Error(`Unexpected typed array class: ${ArrayType}.`);\n }\n\n /** @type {new(b: ArrayBufferLike, o: number, l: number) => TypedArray} */\n const BoxCtor = ArrayType;\n /** @type {new(b: ArrayBufferLike, o: number, l: number) => Uint16Array | Uint32Array} */\n const IdxCtor = this.IndexArrayType;\n\n if (data) {\n this.data = data;\n this._boxes = new BoxCtor(data, byteOffset + 8, numNodes * 4);\n this._indices = new IdxCtor(data, byteOffset + 8 + nodesByteSize, numNodes);\n\n this._pos = numNodes * 4;\n this.minX = this._boxes[this._pos - 4];\n this.minY = this._boxes[this._pos - 3];\n this.maxX = this._boxes[this._pos - 2];\n this.maxY = this._boxes[this._pos - 1];\n\n } else {\n const data = this.data = new ArrayBufferType(8 + nodesByteSize + numNodes * this.IndexArrayType.BYTES_PER_ELEMENT);\n this._boxes = new BoxCtor(data, 8, numNodes * 4);\n this._indices = new IdxCtor(data, 8 + nodesByteSize, numNodes);\n this._pos = 0;\n this.minX = Infinity;\n this.minY = Infinity;\n this.maxX = -Infinity;\n this.maxY = -Infinity;\n\n new Uint8Array(data, 0, 2).set([0xfb, (VERSION << 4) + arrayTypeIndex]);\n new Uint16Array(data, 2, 1)[0] = nodeSize;\n new Uint32Array(data, 4, 1)[0] = numItems;\n }\n\n // a priority queue for k-nearest-neighbors queries\n /** @type FlatQueue<number> */\n this._queue = new FlatQueue();\n }\n\n /**\n * Add a given rectangle to the index.\n * @param {number} minX\n * @param {number} minY\n * @param {number} maxX\n * @param {number} maxY\n * @returns {number} A zero-based, incremental number that represents the newly added rectangle.\n */\n add(minX, minY, maxX = minX, maxY = minY) {\n const pos = this._pos;\n const index = pos >> 2;\n const boxes = this._boxes;\n this._indices[index] = index;\n boxes[pos] = minX;\n boxes[pos + 1] = minY;\n boxes[pos + 2] = maxX;\n boxes[pos + 3] = maxY;\n this._pos = pos + 4;\n\n if (minX < this.minX) this.minX = minX;\n if (minY < this.minY) this.minY = minY;\n if (maxX > this.maxX) this.maxX = maxX;\n if (maxY > this.maxY) this.maxY = maxY;\n\n return index;\n }\n\n /** Perform indexing of the added rectangles. */\n finish() {\n if (this._pos >> 2 !== this.numItems) {\n throw new Error(`Added ${this._pos >> 2} items when expected ${this.numItems}.`);\n }\n const boxes = this._boxes;\n\n if (this.numItems <= this.nodeSize) {\n // only one node, skip sorting and just fill the root box\n boxes[this._pos++] = this.minX;\n boxes[this._pos++] = this.minY;\n boxes[this._pos++] = this.maxX;\n boxes[this._pos++] = this.maxY;\n return;\n }\n\n const {numItems, minX, minY, nodeSize, _indices: indices, _levelBounds: levelBounds} = this;\n const width = (this.maxX - minX) || 1;\n const height = (this.maxY - minY) || 1;\n const hilbertValues = new Int32Array(numItems);\n const hilbertMax = (1 << 16) - 1;\n const sx = hilbertMax / width;\n const sy = hilbertMax / height;\n\n // map item centers into Hilbert coordinate space and calculate Hilbert values\n for (let i = 0, pos = 0; i < numItems; i++) {\n const itemMinX = boxes[pos++];\n const itemMinY = boxes[pos++];\n const itemMaxX = boxes[pos++];\n const itemMaxY = boxes[pos++];\n const x = (sx * ((itemMinX + itemMaxX) / 2 - minX)) | 0;\n const y = (sy * ((itemMinY + itemMaxY) / 2 - minY)) | 0;\n hilbertValues[i] = hilbert(x, y);\n }\n\n // sort items by their Hilbert value (for packing later)\n sort(hilbertValues, boxes, indices, 0, numItems - 1, nodeSize);\n\n // generate nodes at each tree level, bottom-up\n let pos = numItems * 4;\n for (let i = 0, readPos = 0; i < levelBounds.length - 1; i++) {\n const end = levelBounds[i];\n\n // generate a parent node for each block of consecutive <nodeSize> nodes\n while (readPos < end) {\n const nodeIndex = readPos;\n\n // calculate bbox for the new node\n let nodeMinX = boxes[readPos++];\n let nodeMinY = boxes[readPos++];\n let nodeMaxX = boxes[readPos++];\n let nodeMaxY = boxes[readPos++];\n for (let j = 1; j < nodeSize && readPos < end; j++) {\n nodeMinX = Math.min(nodeMinX, boxes[readPos++]);\n nodeMinY = Math.min(nodeMinY, boxes[readPos++]);\n nodeMaxX = Math.max(nodeMaxX, boxes[readPos++]);\n nodeMaxY = Math.max(nodeMaxY, boxes[readPos++]);\n }\n\n // add the new node to the tree data\n indices[pos >> 2] = nodeIndex;\n boxes[pos++] = nodeMinX;\n boxes[pos++] = nodeMinY;\n boxes[pos++] = nodeMaxX;\n boxes[pos++] = nodeMaxY;\n }\n }\n this._pos = pos;\n }\n\n /**\n * Search the index by a bounding box.\n * @param {number} minX\n * @param {number} minY\n * @param {number} maxX\n * @param {number} maxY\n * @param {(index: number, x0: number, y0: number, x1: number, y1: number) => boolean} [filterFn] An optional function that is called on every found item; if supplied, only items for which this function returns true will be included in the results array.\n * @returns {number[]} An array of indices of items intersecting or touching the given bounding box.\n */\n search(minX, minY, maxX, maxY, filterFn) {\n if (this._pos !== this._boxes.length) {\n throw new Error('Data not yet indexed - call index.finish().');\n }\n const {_boxes: boxes, _levelBounds: levelBounds, _indices: indices, nodeSize} = this;\n const numItems4 = this.numItems * 4;\n\n /** @type number | undefined */\n let nodeIndex = boxes.length - 4;\n let level = levelBounds.length - 1; // start at the root level\n const q = [];\n const results = [];\n\n let contained = false; // whether the current node's bbox is fully inside the query\n\n while (nodeIndex !== undefined) {\n // find the end index of the node, capped at the level boundary\n const end = Math.min(nodeIndex + nodeSize * 4, levelBounds[level]);\n const isNode = nodeIndex >= numItems4;\n\n if (contained) {\n this._collectContained(nodeIndex, end, level, numItems4, results, filterFn);\n\n } else {\n // search through child nodes\n for (let /** @type {number} */ pos = nodeIndex; pos < end; pos += 4) {\n // check if node bbox intersects with query bbox\n const x0 = boxes[pos];\n if (maxX < x0) continue;\n const y0 = boxes[pos + 1];\n if (maxY < y0) continue;\n const x1 = boxes[pos + 2];\n if (minX > x1) continue;\n const y1 = boxes[pos + 3];\n if (minY > y1) continue;\n\n const index = indices[pos >> 2] | 0;\n\n if (isNode) {\n // node intersects; flag it as contained if its bbox is fully inside the query\n const c = +(minX <= x0 && minY <= y0 && maxX >= x1 && maxY >= y1);\n q.push(index | c, level - 1); // node; add it and its level to the search queue\n\n } else if (filterFn === undefined || filterFn(index, x0, y0, x1, y1)) {\n results.push(index); // leaf item\n }\n }\n }\n\n level = /** @type {number} */ (q.pop());\n nodeIndex = q.pop();\n if (nodeIndex !== undefined) {\n contained = (nodeIndex & 1) === 1;\n nodeIndex &= ~1;\n }\n }\n\n return results;\n }\n\n /**\n * Collect all leaves of a subtree that's fully inside the query, skipping intersection tests.\n * Because the tree is packed bottom-up, those leaves occupy one contiguous block of the leaf\n * level, so we skip traversal entirely: descend to the first leaf, then sweep the flat range.\n * @param {number} nodeIndex\n * @param {number} end\n * @param {number} level\n * @param {number} numItems4\n * @param {number[]} results\n * @param {((index: number, x0: number, y0: number, x1: number, y1: number) => boolean) | undefined} filterFn\n */\n _collectContained(nodeIndex, end, level, numItems4, results, filterFn) {\n const boxes = this._boxes;\n const indices = this._indices;\n let pos = nodeIndex;\n for (let l = level; l > 0; l--) pos = indices[pos >> 2];\n const leafEnd = Math.min(pos + (end - nodeIndex) * this.nodeSize ** level, numItems4);\n if (filterFn === undefined) {\n for (; pos < leafEnd; pos += 4) results.push(indices[pos >> 2] | 0);\n } else {\n for (; pos < leafEnd; pos += 4) {\n const index = indices[pos >> 2] | 0;\n if (filterFn(index, boxes[pos], boxes[pos + 1], boxes[pos + 2], boxes[pos + 3])) results.push(index);\n }\n }\n }\n\n /**\n * Search items in order of distance from the given point.\n * @param {number} x\n * @param {number} y\n * @param {number} [maxResults=Infinity]\n * @param {number} [maxDistance=Infinity]\n * @param {(index: number) => boolean} [filterFn] An optional function for filtering the results.\n * @returns {number[]} An array of indices of items found.\n */\n neighbors(x, y, maxResults = Infinity, maxDistance = Infinity, filterFn) {\n if (this._pos !== this._boxes.length) {\n throw new Error('Data not yet indexed - call index.finish().');\n }\n const {_boxes: boxes, _levelBounds: levelBounds, _indices: indices, _queue: q, nodeSize} = this;\n const numItems4 = this.numItems * 4;\n const nodeSize4 = nodeSize * 4;\n const results = [];\n const maxDistSquared = maxDistance * maxDistance;\n\n // For a single nearest neighbor (maxResults === 1), track the closest leaf seen so far and use\n // it as a tightened distance bound, skipping pushes of nodes/leaves that can't beat it\n const trackNearest = maxResults === 1;\n let bound = maxDistSquared;\n\n // Tree nodes and leaves share the queue; encode leaves with LSB = 1 so we can tell them\n // apart with `& 1`. Seed with the root node \u2014 any priority works since the queue is empty.\n q.push((boxes.length - 4) << 1, 0);\n\n while (q.length) {\n const top = q.ids[0];\n // if the closest queued entry is a leaf, it's the next result in distance order\n if (top & 1) {\n q.pop();\n results.push(top >> 1);\n if (results.length === maxResults) break;\n continue;\n }\n\n q.pop();\n const nodeIndex = top >> 1;\n const isLeafLevel = nodeIndex < numItems4;\n const end = Math.min(nodeIndex + nodeSize4, upperBound(nodeIndex, levelBounds));\n\n for (let pos = nodeIndex; pos < end; pos += 4) {\n const minX = boxes[pos];\n const minY = boxes[pos + 1];\n const maxX = boxes[pos + 2];\n const maxY = boxes[pos + 3];\n const dx = Math.max(Math.max(minX - x, x - maxX), 0);\n const dy = Math.max(Math.max(minY - y, y - maxY), 0);\n const dist = dx * dx + dy * dy;\n if (dist > bound) continue;\n\n const childIndex = indices[pos >> 2] | 0;\n if (isLeafLevel) {\n if (filterFn === undefined || filterFn(childIndex)) {\n q.push((childIndex << 1) | 1, dist); // leaf item (odd id)\n if (trackNearest && dist < bound) bound = dist; // tighten bound to the closest leaf so far\n }\n } else {\n q.push(childIndex << 1, dist); // node (even id)\n }\n }\n }\n\n q.clear();\n return results;\n }\n}\n\n/**\n * Binary search for the first value in the array bigger than the given.\n * @param {number} value\n * @param {number[]} arr\n */\nfunction upperBound(value, arr) {\n let i = 0;\n let j = arr.length - 1;\n while (i < j) {\n const m = (i + j) >> 1;\n if (arr[m] > value) {\n j = m;\n } else {\n i = m + 1;\n }\n }\n return arr[i];\n}\n\n/**\n * Custom quicksort that partially sorts bbox data alongside the hilbert values.\n * @param {Int32Array} values\n * @param {TypedArray} boxes\n * @param {Uint16Array | Uint32Array} indices\n * @param {number} left\n * @param {number} right\n * @param {number} nodeSize\n */\nfunction sort(values, boxes, indices, left, right, nodeSize) {\n const stack = [left, right];\n\n while (stack.length) {\n const r = stack.pop() || 0;\n const l = stack.pop() || 0;\n\n if (r - l <= nodeSize && Math.floor(l / nodeSize) >= Math.floor(r / nodeSize)) continue;\n\n const a = values[l];\n const b = values[(l + r) >> 1];\n const c = values[r];\n const pivot = ((a > b) !== (a > c)) ? a :\n ((b < a) !== (b < c)) ? b : c;\n\n let i = l - 1;\n let j = r + 1;\n\n while (true) {\n do i++; while (values[i] < pivot);\n do j--; while (values[j] > pivot);\n if (i >= j) break;\n swap(values, boxes, indices, i, j);\n }\n\n stack.push(l, j, j + 1, r);\n }\n}\n\n/**\n * Swap two values and two corresponding boxes.\n * @param {Int32Array} values\n * @param {TypedArray} boxes\n * @param {Uint16Array | Uint32Array} indices\n * @param {number} i\n * @param {number} j\n */\nfunction swap(values, boxes, indices, i, j) {\n const temp = values[i];\n values[i] = values[j];\n values[j] = temp;\n\n const k = 4 * i;\n const m = 4 * j;\n\n const a = boxes[k];\n const b = boxes[k + 1];\n const c = boxes[k + 2];\n const d = boxes[k + 3];\n boxes[k] = boxes[m];\n boxes[k + 1] = boxes[m + 1];\n boxes[k + 2] = boxes[m + 2];\n boxes[k + 3] = boxes[m + 3];\n boxes[m] = a;\n boxes[m + 1] = b;\n boxes[m + 2] = c;\n boxes[m + 3] = d;\n\n const e = indices[i];\n indices[i] = indices[j];\n indices[j] = e;\n}\n\n/**\n * Fast Hilbert curve algorithm by http://threadlocalmutex.com/\n * Ported from C++ https://github.com/rawrunprotected/hilbert_curves (public domain)\n * @param {number} x\n * @param {number} y\n */\nfunction hilbert(x, y) {\n let a = x ^ y;\n let b = 0xFFFF ^ a;\n let c = 0xFFFF ^ (x | y);\n let d = x & (y ^ 0xFFFF);\n\n let A = a | (b >> 1);\n let B = (a >> 1) ^ a;\n let C = c ^ ((c >> 1) ^ (b & (d >> 1)));\n let D = d ^ ((a & (c >> 1)) ^ (d >> 1));\n\n a = (A & (A >> 2)) ^ (B & (B >> 2));\n b = (A & (B >> 2)) ^ (B & ((A ^ B) >> 2));\n c = C ^ ((A & (C >> 2)) ^ (B & (D >> 2)));\n d = D ^ ((B & (C >> 2)) ^ ((A ^ B) & (D >> 2)));\n\n A = (a & (a >> 4)) ^ (b & (b >> 4));\n B = (a & (b >> 4)) ^ (b & ((a ^ b) >> 4));\n C = c ^ ((a & (c >> 4)) ^ (b & (d >> 4)));\n D = d ^ ((b & (c >> 4)) ^ ((a ^ b) & (d >> 4)));\n\n c = C ^ ((A & (C >> 8)) ^ (B & (D >> 8)));\n d = D ^ ((B & (C >> 8)) ^ ((A ^ B) & (D >> 8)));\n\n c ^= c >> 1;\n d ^= d >> 1;\n a = x ^ y;\n b = d | (0xFFFF ^ (a | c));\n\n a = (a | (a << 8)) & 0x00FF00FF;\n a = (a | (a << 4)) & 0x0F0F0F0F;\n a = (a | (a << 2)) & 0x33333333;\n a = (a | (a << 1)) & 0x55555555;\n\n b = (b | (b << 8)) & 0x00FF00FF;\n b = (b | (b << 4)) & 0x0F0F0F0F;\n b = (b | (b << 2)) & 0x33333333;\n b = (b | (b << 1)) & 0x55555555;\n\n // shift into signed SMI range for performance\n return (((b << 1) | a) >>> 0) - 0x80000000;\n}\n", "import Flatbush from 'flatbush'\n\nexport interface ClickEntry {\n name: string\n /** the text a tip label draws, which may be cut short */\n label?: string\n id: string\n branch?: boolean\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\ninterface Box {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\n// Spatial index of clickable tree elements (leaf labels, node bubbles,\n// collapsed-clade triangles). Entries are collected during a render pass, then\n// finish() builds the Flatbush index queried by hit-testing.\nexport class ClickMapIndex {\n private flatbush: Flatbush | null = null\n private entries: ClickEntry[] = []\n\n clear() {\n this.flatbush = null\n this.entries = []\n }\n\n insert(entry: ClickEntry) {\n this.entries.push(entry)\n }\n\n finish() {\n if (this.entries.length === 0) {\n this.flatbush = null\n } else {\n this.flatbush = new Flatbush(this.entries.length)\n for (const entry of this.entries) {\n this.flatbush.add(entry.minX, entry.minY, entry.maxX, entry.maxY)\n }\n this.flatbush.finish()\n }\n }\n\n search(box: Box): ClickEntry[] {\n return (\n this.flatbush\n ?.search(box.minX, box.minY, box.maxX, box.maxY)\n .map(i => this.entries[i]!) ?? []\n )\n }\n}\n", "import { treeHoverColor } from '../overlayColors.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nexport function renderTreeMouseover({\n ctx,\n model,\n}: {\n ctx: CanvasRenderingContext2D\n model: MsaViewModel\n}) {\n const {\n rowHeight,\n effectiveTreeAreaWidth: width,\n height,\n scrollY,\n mouseRow,\n referenceRowIndex,\n hoveredRowIndices,\n highResScaleFactor,\n } = model\n ctx.resetTransform()\n ctx.clearRect(0, 0, width * highResScaleFactor, height * highResScaleFactor)\n ctx.scale(highResScaleFactor, highResScaleFactor)\n\n const rowBand = (index: number) => {\n ctx.fillRect(0, index * rowHeight + scrollY, width, rowHeight)\n }\n\n ctx.fillStyle = treeHoverColor\n for (const index of hoveredRowIndices) {\n rowBand(index)\n }\n if (\n mouseRow !== undefined &&\n mouseRow !== referenceRowIndex &&\n !hoveredRowIndices.includes(mouseRow)\n ) {\n rowBand(mouseRow)\n }\n}\n", "import React from 'react'\n\nimport { useTheme } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { treeScaleBarHeight as h } from '../../constants.ts'\nimport ScaleBarSVG from './ScaleBarSVG.tsx'\n\nimport type { MsaViewModel } from '../../model.ts'\n\n// The gutter above the tree panel, the width of the tree area, so the strip\n// headers beside it start where the strips do. A phylogram fills it with a\n// scale bar: without one the branch lengths are drawn to a scale nothing\n// states.\nconst TreeRuler = observer(({ model }: { model: MsaViewModel }) => {\n const { effectiveTreeAreaWidth, marginLeft, treeScaleBar: bar } = model\n const theme = useTheme()\n\n return (\n <div style={{ flexShrink: 0, width: effectiveTreeAreaWidth }}>\n {bar ? (\n <svg\n width={effectiveTreeAreaWidth}\n height={h}\n style={{ display: 'block' }}\n >\n <ScaleBarSVG\n bar={bar}\n marginLeft={marginLeft}\n y={h}\n color={theme.palette.text.primary}\n />\n </svg>\n ) : null}\n </div>\n )\n})\n\nexport default TreeRuler\n", "import React, { useState } from 'react'\n\nimport { ErrorMessage, FileSelector } from '@jbrowse/core/ui'\nimport { Box, Button, Container, Typography } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport ImportFormExamples from './ImportFormExamples.tsx'\nimport { load } from './util.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\nconst phone = '@media (max-width: 640px)'\n\nconst ImportForm = observer(function ({ model }: { model: MsaViewModel }) {\n const [msaFile, setMsaFile] = useState<FileLocation>()\n const [treeFile, setTreeFile] = useState<FileLocation>()\n const [gffFile, setGffFile] = useState<FileLocation>()\n const { error } = model\n\n return (\n <Container>\n <Box sx={{ width: '50%', [phone]: { width: '100%' } }}>\n {error ? <ErrorMessage error={error} /> : null}\n <Typography>\n Open an MSA file (FASTA, Stockholm, Clustal, A3M or EMF format) and/or\n a tree file (Newick format).\n </Typography>\n <Typography color=\"text.secondary\">\n An MSA alone or a tree alone is enough, and a Stockholm file with an\n embedded tree needs no separate tree file.\n </Typography>\n </Box>\n\n <Box\n sx={{\n display: 'flex',\n justifyContent: 'center',\n alignItems: 'center',\n gap: '40px',\n [phone]: {\n flexDirection: 'column',\n alignItems: 'stretch',\n gap: '16px',\n },\n }}\n >\n <div>\n <div>\n <Typography>MSA file or URL</Typography>\n <FileSelector location={msaFile} setLocation={setMsaFile} />\n </div>\n <div>\n <Typography>Tree file or URL</Typography>\n <FileSelector location={treeFile} setLocation={setTreeFile} />\n </div>\n <div>\n <Typography>Annotation GFF file or URL (optional)</Typography>\n <FileSelector location={gffFile} setLocation={setGffFile} />\n </div>\n </div>\n <div>\n <Button\n onClick={() => {\n try {\n load(model, msaFile, treeFile, gffFile)\n } catch (e) {\n console.error(e)\n model.setError(e)\n }\n }}\n variant=\"contained\"\n color=\"primary\"\n disabled={!msaFile && !treeFile}\n >\n Open\n </Button>\n </div>\n\n <div>\n <Typography>Examples</Typography>\n <ImportFormExamples model={model} />\n </div>\n </Box>\n </Container>\n )\n})\n\nexport default ImportForm\n", "import React from 'react'\n\nimport { Link, Typography } from '@mui/material'\nimport { observer } from 'mobx-react'\n\nimport { smallMSA, smallTree } from './data/seq2.ts'\nimport { load } from './util.ts'\n\nimport type { MsaViewModel } from '../../model.ts'\n\nconst BASE = 'https://jbrowse.org/genomes/multiple_sequence_alignments'\nconst TREES = 'https://jbrowse.org/genomes/newick_trees'\nconst DEMO = 'https://gmod.org/JBrowseMSA/demo/data'\n\n// each example points at remote files (msa/tree/gff urls) or carries its data\n// inline\ninterface Example {\n label: string\n msa?: string\n tree?: string\n gff?: string\n inline?: { msa: string; tree?: string }\n}\n\nconst examples: Example[] = [\n {\n label: 'NLRP1 in 12 mammals, with Pfam domains',\n msa: `${DEMO}/nlrp1.aln`,\n tree: `${DEMO}/nlrp1.nh`,\n gff: `${DEMO}/nlrp1-domains.gff`,\n },\n {\n label: '474 human protein kinase domains, with a FastTree tree',\n msa: `${DEMO}/kinase-pocket/kinase-pocket.afa`,\n tree: `${DEMO}/kinase-pocket/kinase-pocket.nwk`,\n },\n {\n label: 'RSV-A G gene in 1,840 genomes, with the Nextstrain tree',\n msa: `${DEMO}/scale/rsv-full.aln`,\n tree: `${DEMO}/scale/rsv-full.nh`,\n },\n {\n label: '230k COVID-19 samples (tree only)',\n tree: `${TREES}/sarscov2phylo.pub.ft.nh`,\n },\n {\n label: 'Pfam SARS-CoV-2 families, multi-Stockholm with domains',\n msa: `${BASE}/pfam-cov2.stock`,\n gff: `${BASE}/pfam-cov2-domains.gff`,\n },\n {\n label: 'Small protein alignment and tree',\n inline: { msa: smallMSA, tree: smallTree },\n },\n]\n\nfunction uri(url?: string) {\n return url ? { uri: url, locationType: 'UriLocation' as const } : undefined\n}\n\nconst ImportFormExamples = observer(function ({\n model,\n}: {\n model: MsaViewModel\n}) {\n return (\n <ul>\n {examples.map(({ label, msa, tree, gff, inline }) => (\n <li key={label}>\n <Link\n href=\"#\"\n onClick={event => {\n event.preventDefault()\n model.setError(undefined)\n try {\n if (inline) {\n model.setData(inline)\n } else {\n load(model, uri(msa), uri(tree), uri(gff))\n }\n } catch (e) {\n console.error(e)\n model.setError(e)\n }\n }}\n >\n <Typography component=\"span\">{label}</Typography>\n </Link>\n </li>\n ))}\n </ul>\n )\n})\n\nexport default ImportFormExamples\n", "export const smallMSA = `CLUSTAL O(1.2.3) multiple sequence alignment\nUniProt/Swiss-Prot|P26898|IL2RA_SHEEP MEPSLLMWRFFVFIVVPGCVTEACHDDPPSLRNA----------MFKVLRYE----VGTM\nUniProt/Swiss-Prot|P01590|IL2RA_MOUSE MEPRLLMLGFLSLTIVPSCRAELCLYDPPEVPNA----------TFKALSYK----NGTI\nUniProt/Swiss-Prot|P41690|IL2RA_FELCA MEPSLLLWGILTFVVVHGHVTELCDENPPDIQHA----------TFKALTYK----TGTM\nUniProt/Swiss-Prot|P01589|IL2RA_HUMAN MDSYLLMWGLLTFIMVPGCQAELCDDDPPEIPHA----------TFKAMAYK----EGTM\nUniProt/Swiss-Prot|Q5MNY4|IL2RA_MACMU MDPYLLMWGLLTFITVPGCQAELCDDDPPKITHA----------TFKAVAYK----EGTM\nUniProt/Swiss-Prot|Q95118|IL2RG_BOVIN -----------------------------------LLMWGLLT-----------------\nUniProt/Swiss-Prot|P40321|IL2RG_CANFA MLKPPLPLRSLLFLQLSLLGVGLNSTVPMPNGNEDIT------PDFFLTATPSETLSVSS\nUniProt/Swiss-Prot|P26896|IL2RB_RAT MATVDLSWRLPLYILLLLLATT--------------------------------WVSAAV\nUniProt/Swiss-Prot|Q8BZM1|GLMN_MOUSE PLPLRSLLFLQLPLLGVGLNP------------------PLPLRSLLFLQLPLLGVGLNP\nUniProt/Swiss-Prot|P36835|IL2_CAPHI -----------LLGVGLNPKFLTP------------------------------------\nUniProt/Swiss-Prot|Q7JFM4|IL2_AOTVO MLKPPLPLRSLLFLQLPLLGVGLNPKFLTPSGNEDIGGKPGTGGDFFLTSTPAGTLDVST\nUniProt/Swiss-Prot|Q29416|IL2_CANFA --------------LFLQLSLLG-------------------------------------\n`\n\nexport const smallTree =\n '(((UniProt/Swiss-Prot|P26898|IL2RA_SHEEP:0.24036,(UniProt/Swiss-Prot|P41690|IL2RA_FELCA:0.17737,(UniProt/Swiss-Prot|P01589|IL2RA_HUMAN:0.03906,UniProt/Swiss-Prot|Q5MNY4|IL2RA_MACMU:0.03787):0.13033):0.04964):0.02189,UniProt/Swiss-Prot|P01590|IL2RA_MOUSE:0.23072):0.06814,(((UniProt/Swiss-Prot|Q95118|IL2RG_BOVIN:0.09600,UniProt/Swiss-Prot|P40321|IL2RG_CANFA:0.09845):0.25333,UniProt/Swiss-Prot|Q29416|IL2_CANFA:-0.35055):0.10231,(UniProt/Swiss-Prot|P26896|IL2RB_RAT:0.33631,UniProt/Swiss-Prot|Q7JFM4|IL2_AOTVO:-0.33631):0.10166):0.01607,(UniProt/Swiss-Prot|Q8BZM1|GLMN_MOUSE:0.32378,UniProt/Swiss-Prot|P36835|IL2_CAPHI:-0.32378):0.09999)'\n", "import type { MsaViewModel } from '../../model.ts'\nimport type { FileLocation } from '@jbrowse/core/util'\n\nexport function load(\n model: MsaViewModel,\n msaFile?: FileLocation,\n treeFile?: FileLocation,\n gffFile?: FileLocation,\n) {\n model.setError(undefined)\n if (msaFile) {\n model.setMSAFilehandle(msaFile)\n }\n if (treeFile) {\n model.setTreeFilehandle(treeFile)\n }\n if (gffFile) {\n model.setGFFFilehandle(gffFile)\n // a file opened by hand shows even if the overlay was hidden earlier\n model.setShowDomains(true)\n }\n}\n", "import React, {\n forwardRef,\n useEffect,\n useImperativeHandle,\n useRef,\n useState,\n} from 'react'\n\nimport useMeasure from '@jbrowse/core/util/useMeasure'\nimport { destroy, isAlive } from '@jbrowse/mobx-state-tree'\nimport { ThemeProvider } from '@mui/material/styles'\nimport { compareStructural, reaction, when } from 'mobx'\n\nimport MSAModelF from '../model.ts'\nimport {\n fileLocations,\n resolveTheme,\n viewerHighlights,\n viewerSnapshot,\n} from '../viewerSnapshot.ts'\nimport Loading from './Loading.tsx'\n\nimport type { MsaViewModel } from '../model.ts'\nimport type {\n Cell,\n Clade,\n ColorScheme,\n ColumnTrackSpec,\n Encoding,\n Feature,\n Highlight,\n MsaSelection,\n Region,\n ResidueEncoding,\n ResidueMapping,\n RowDataInput,\n RowPanelSpec,\n TreeOrder,\n TreeRoot,\n Viewport,\n} from '../types.ts'\nimport type { FileLocation as FileLocationType } from '@jbrowse/core/util/types'\nimport type { ThemeOptions } from '@mui/material/styles'\nimport type { ForwardedRef } from 'react'\n\nexport interface MSAViewerProps {\n msa?: string\n tree?: string\n gff?: string\n msaFilehandle?: FileLocationType\n treeFilehandle?: FileLocationType\n gffFilehandle?: FileLocationType\n /** a URL the viewer fetches the alignment from; `msaFilehandle` wins */\n msaUrl?: string\n /** a URL the viewer fetches the Newick tree from; `treeFilehandle` wins */\n treeUrl?: string\n /** a URL the viewer fetches the GFF from; `gffFilehandle` wins */\n gffUrl?: string\n /**\n * a scheme name from the built-in table, or `{map}`, a color per residue\n * letter that leaves every other letter uncolored\n */\n colorScheme?: ColorScheme\n height?: number\n /** initial per-column pixel width (zoom level) */\n colWidth?: number\n /** initial per-row pixel height */\n rowHeight?: number\n /**\n * hide columns at least this percent gaps (default 100, i.e. hide nothing)\n */\n allowedGappyness?: number\n /**\n * alignment columns, 1-based like `highlights`, drawn as one `{start, end}`\n * highlight per run of adjacent columns\n */\n highlightColumns?: number[]\n /**\n * labeled highlights in 1-based inclusive coordinates: `{start, end}` for\n * alignment columns, `{row, start, end}` for residues of that row, `{rows}`\n * for whole rows, each with an optional `label` and `color`\n */\n highlights?: Highlight[]\n /**\n * features on the rows as data, drawn with the GFF's: `{row, start, end}` in\n * residues of that row, 1-based and inclusive, with an optional `name`,\n * `description`, `type`, `strand` and `color`, and any other field an\n * encoding reads (see docs/layers.md)\n */\n features?: Feature[]\n /**\n * clades of the tree with a mark drawn over them: `{mrca, tips, mark}` or\n * `{range, tips, mark}`, where `mark` is `highlight`, `bracket`, `collapse`\n * or `focus` (see docs/layers.md)\n */\n clades?: Clade[]\n /** row name to diff every other row against (matches render as \".\") */\n relativeTo?: string\n /** tracks supplied as data: per-column bar values or a text row (see docs/layers.md) */\n columnTracks?: ColumnTrackSpec[]\n /** which residue of which structure each row's residues are (see docs/layers.md) */\n residueMappings?: ResidueMapping[]\n /** extra fields per row name, such as a lineage or a host (see docs/layers.md) */\n rowData?: RowDataInput\n /**\n * what the viewer's marks read from a table: `{channel, field, scale?}`,\n * where `channel` is `tipLabel`, `rowTint` or `branch` over `rowData`, or\n * `featureFill` or `featureLabel` over the annotations (see docs/layers.md)\n */\n encodings?: Encoding[]\n /**\n * panels between the tree and the alignment, one cell per row:\n * `{kind: 'strip', field, scale?, width?, header?}` colors each row by a\n * `rowData` field (see docs/layers.md)\n */\n rowPanels?: RowPanelSpec[]\n /** draw the phylogenetic tree (default true); false leaves a labels-only gutter */\n drawTree?: boolean\n /** fixed width (px) of the tree/label area; unset fits it to the labels and the tree */\n treeAreaWidth?: number\n /** draw branch lengths (default true); false draws a cladogram */\n showBranchLen?: boolean\n /**\n * the order each node's children draw in: `branchLength` (default,\n * shortest first), `input` (as the file gives them), `ladderize` (fewest\n * tips first) or `ladderizeReverse` (most tips first)\n */\n treeOrder?: TreeOrder\n /**\n * reroot the tree: `midpoint`, or `{outgroup: [tip names]}` on the branch\n * above those tips' common ancestor\n */\n treeRoot?: TreeRoot\n /**\n * which channel `colorScheme` paints: `fill` (default) colors the background\n * of the cell a residue sits in, `color` colors the letter itself and leaves\n * the background plain, which lets a domain overlay mark each span with a bar\n * under the row and the residue colors show through\n */\n residueEncoding?: ResidueEncoding\n /**\n * a span to zoom and scroll to once the alignment loads, and again whenever\n * it changes: `{row, start, end}` in residues of that row, or `{start, end}`\n * in columns, 1-based and inclusive\n */\n region?: Region\n /**\n * the selected block: `{start, end}` columns of the file, 1-based and\n * inclusive, and `rows` by name, every row where absent\n */\n selection?: MsaSelection\n /** leave out the toolbar, for a page drawing its own controls */\n hideHeader?: boolean\n /**\n * 'light' (default), 'dark', or MUI theme options (palette, typography)\n * merged over the JBrowse theme\n */\n theme?: 'light' | 'dark' | ThemeOptions\n /** the cell under the pointer, or undefined when it leaves the alignment */\n onCellHover?: (cell: Cell | undefined) => void\n /** the cell a click pinned, or undefined when a click clears it */\n onCellClick?: (cell: Cell | undefined) => void\n /** the alignment columns on screen, after every scroll, zoom and resize */\n onViewportChange?: (viewport: Viewport | undefined) => void\n /**\n * the selected block, after each change a drag, the header menu, Escape or\n * the `selection` prop makes, or undefined when it clears\n */\n onSelectionChange?: (selection: MsaSelection | undefined) => void\n /**\n * the model the viewer built, for the model API; called again with the new\n * model when msa, tree, msaUrl, treeUrl, msaFilehandle or treeFilehandle\n * changes\n */\n onModel?: (model: MsaViewModel) => void\n}\n\ntype DataSource = Pick<\n MSAViewerProps,\n 'msa' | 'tree' | 'msaFilehandle' | 'treeFilehandle'\n>\n\nfunction sameSource(a: DataSource, b: DataSource) {\n return (\n a.msa === b.msa &&\n a.tree === b.tree &&\n JSON.stringify([a.msaFilehandle, a.treeFilehandle]) ===\n JSON.stringify([b.msaFilehandle, b.treeFilehandle])\n )\n}\n\n/**\n * A new alignment or tree needs a new model, so the viewer remounts when one\n * of those props changes and keeps its model across every other change,\n * including a new annotation file. A `ref` holds the current model.\n */\nconst MSAViewer = forwardRef<MsaViewModel, MSAViewerProps>(\n function MSAViewer(props, ref) {\n const resolved = { ...props, ...fileLocations(props) }\n const { msa, tree, msaFilehandle, treeFilehandle } = resolved\n const source = { msa, tree, msaFilehandle, treeFilehandle }\n const [shown, setShown] = useState({ source, generation: 0 })\n if (!sameSource(shown.source, source)) {\n setShown({ source, generation: shown.generation + 1 })\n }\n return <Viewer key={shown.generation} modelRef={ref} {...resolved} />\n },\n)\n\nexport default MSAViewer\n\nfunction useModelReaction<\n K extends 'hoveredCell' | 'clickedCell' | 'viewport' | 'selection',\n>(\n model: MsaViewModel,\n key: K,\n handler: ((value: MsaViewModel[K]) => void) | undefined,\n) {\n const latest = useRef(handler)\n useEffect(() => {\n latest.current = handler\n })\n const listening = !!handler\n useEffect(\n () =>\n listening\n ? reaction(\n () => model[key],\n value => {\n latest.current?.(value)\n },\n { equals: compareStructural },\n )\n : undefined,\n [model, key, listening],\n )\n}\n\ninterface SyncedProp {\n read: (props: MSAViewerProps) => unknown\n apply: (model: MsaViewModel, value: unknown, props: MSAViewerProps) => void\n inSnapshot?: boolean\n}\n\nfunction synced<T>(\n read: (props: MSAViewerProps) => T,\n apply: (model: MsaViewModel, value: T, props: MSAViewerProps) => void,\n { inSnapshot = false } = {},\n): SyncedProp {\n return {\n read,\n apply: apply as SyncedProp['apply'],\n inSnapshot,\n }\n}\n\nfunction ifSet<T>(set: (model: MsaViewModel, value: T) => void) {\n return (model: MsaViewModel, value: T | undefined) => {\n if (value !== undefined) {\n set(model, value)\n }\n }\n}\n\n/**\n * How each prop reaches the mounted model. `inSnapshot` marks a prop the\n * snapshot already applied, so only a later change reaches its setter.\n */\nconst syncedProps = [\n synced(\n p => p.height,\n ifSet((m, v) => {\n m.setHeight(v)\n }),\n ),\n synced(\n p => p.colWidth,\n ifSet((m, v) => {\n m.setColWidth(v)\n }),\n ),\n synced(\n p => p.rowHeight,\n ifSet((m, v) => {\n m.setRowHeight(v)\n }),\n ),\n synced(\n p => p.allowedGappyness,\n ifSet((m, v) => {\n m.setAllowedGappyness(v)\n }),\n ),\n synced(\n p => p.drawTree,\n ifSet((m, v) => {\n m.setDrawTree(v)\n }),\n ),\n synced(\n p => p.treeAreaWidth,\n ifSet((m, v) => {\n m.setTreeAreaWidth(v)\n }),\n ),\n synced(\n p => p.showBranchLen,\n ifSet((m, v) => {\n m.setShowBranchLen(v)\n }),\n ),\n synced(\n p => p.treeOrder,\n ifSet((m, v) => {\n m.setTreeOrder(v)\n }),\n ),\n synced(\n p => p.residueEncoding,\n ifSet((m, v) => {\n m.setBgColor(v === 'fill')\n }),\n ),\n synced(\n p => !!p.hideHeader,\n (m, v) => {\n m.setHideHeader(v)\n },\n ),\n synced(\n p => p.relativeTo,\n (m, v) => {\n m.drawRelativeTo(v)\n },\n ),\n synced(\n p => p.gffFilehandle,\n (m, location, { gff }) => {\n if (location) {\n m.setGFFFilehandle(location)\n } else {\n m.setGFF(gff)\n }\n },\n { inSnapshot: true },\n ),\n synced(\n p => p.gff,\n (m, v) => {\n m.setGFF(v)\n },\n { inSnapshot: true },\n ),\n synced(\n p => p.colorScheme,\n (m, scheme) => {\n if (typeof scheme === 'string') {\n m.setColorSchemeName(scheme)\n } else if (scheme) {\n m.setCustomColorScheme(scheme.map)\n }\n },\n ),\n synced(viewerHighlights, (m, v) => {\n m.setHighlights(v)\n }),\n synced(\n p => p.features ?? [],\n (m, v) => {\n m.setFeatures(v)\n },\n ),\n synced(\n p => p.selection,\n (m, v) => {\n m.setSelection(v)\n },\n ),\n synced(\n p => p.treeRoot,\n (m, v) => {\n m.setTreeRoot(v)\n },\n ),\n synced(\n p => p.clades ?? [],\n (m, v) => {\n m.setClades(v)\n },\n ),\n synced(\n p => p.columnTracks ?? [],\n (m, v) => {\n m.setColumnTracks(v)\n },\n ),\n synced(\n p => p.residueMappings ?? [],\n (m, v) => {\n m.setResidueMappings(v)\n },\n ),\n synced(\n p => p.rowData,\n (m, table) => {\n if (table && Object.keys(table).length) {\n m.setRowData(table)\n }\n },\n ),\n synced(\n p => p.encodings ?? [],\n (m, v) => {\n m.setEncodings(v)\n },\n ),\n synced(\n p => p.rowPanels ?? [],\n (m, v) => {\n m.setRowPanels(v)\n },\n ),\n]\n\n/**\n * Applies each prop whose content changed since the last render. Comparing\n * JSON keys lets a host pass a freshly computed array every render, and\n * applying only a changed prop keeps a change made inside the viewer across\n * the host's next render. The model receives a parsed copy, never the host's\n * own object.\n */\nfunction useSyncedProps(model: MsaViewModel, props: MSAViewerProps) {\n const applied = useRef<string[] | undefined>(undefined)\n useEffect(() => {\n const keys = syncedProps.map(({ read }) =>\n JSON.stringify(read(props) ?? null),\n )\n applied.current ??= syncedProps.map(({ inSnapshot }, i) =>\n inSnapshot ? keys[i]! : '',\n )\n const last = applied.current\n syncedProps.forEach(({ apply }, i) => {\n const key = keys[i]!\n if (last[i] !== key) {\n last[i] = key\n apply(model, JSON.parse(key) ?? undefined, props)\n }\n })\n })\n}\n\nfunction Viewer({\n modelRef,\n ...props\n}: MSAViewerProps & { modelRef: ForwardedRef<MsaViewModel> }) {\n const {\n region,\n theme,\n onCellHover,\n onCellClick,\n onViewportChange,\n onSelectionChange,\n onModel,\n } = props\n const [model] = useState(() => {\n const model = MSAModelF().create(viewerSnapshot(props))\n model.setImportForm(false)\n return model\n })\n\n const destroyTimer = useRef<ReturnType<typeof setTimeout> | undefined>(\n undefined,\n )\n\n const [ref, { width }] = useMeasure()\n useEffect(() => {\n if (width) {\n model.setWidth(width)\n }\n }, [model, width])\n\n useSyncedProps(model, props)\n\n const regionKey = JSON.stringify(region ?? null)\n useEffect(() => {\n const target = JSON.parse(regionKey) as Region | null\n return target\n ? when(\n () => model.viewInitialized && model.numColumns > 0,\n () => {\n model.revealRegion(target)\n },\n )\n : undefined\n }, [model, regionKey])\n\n useModelReaction(model, 'hoveredCell', onCellHover)\n useModelReaction(model, 'clickedCell', onCellClick)\n useModelReaction(model, 'viewport', onViewportChange)\n useModelReaction(model, 'selection', onSelectionChange)\n\n useImperativeHandle(modelRef, () => model, [model])\n\n const latestOnModel = useRef(onModel)\n useEffect(() => {\n latestOnModel.current = onModel\n })\n useEffect(() => {\n latestOnModel.current?.(model)\n }, [model])\n\n // destroy releases the model's matchMedia listener and fetches. It waits a\n // tick because StrictMode remounts with the same state, and the remount's\n // effect cancels it.\n useEffect(() => {\n if (destroyTimer.current !== undefined) {\n clearTimeout(destroyTimer.current)\n destroyTimer.current = undefined\n }\n return () => {\n destroyTimer.current = setTimeout(() => {\n destroyTimer.current = undefined\n if (isAlive(model)) {\n destroy(model)\n }\n })\n }\n }, [model])\n\n return (\n <ThemeProvider theme={resolveTheme(theme)}>\n <div ref={ref}>\n <Loading model={model} />\n </div>\n </ThemeProvider>\n )\n}\n", "import { clamp, groupBy, notEmpty, sum } from '@jbrowse/core/util'\nimport { openLocation } from '@jbrowse/core/util/io'\nimport { ElementId, FileLocation } from '@jbrowse/core/util/types/mst'\nimport {\n addDisposer,\n applySnapshot,\n cast,\n getSnapshot,\n isAlive,\n types,\n} from '@jbrowse/mobx-state-tree'\nimport {\n autorun,\n compareStructural,\n computed,\n reaction,\n transaction,\n} from 'mobx'\nimport {\n generateNodeIds,\n gffToAnnotations,\n parseEmfTree,\n parseGFF,\n parseMSA,\n parseNewick,\n} from 'msa-parsers'\n\nimport { blockFasta } from './blockFasta.ts'\nimport { calculateBlocks } from './calculateBlocks.ts'\nimport { clustalXColumnColors } from './clustalX.ts'\nimport colorSchemes, { letterColorTable } from './colorSchemes.ts'\nimport { columnCountsFromRows, letterOfResidueSlot } from './columnCounts.ts'\nimport { columnStats } from './columnStats.ts'\nimport { packDomainLanes } from './components/msa/packDomainLanes.ts'\nimport { visibleColRange } from './components/msa/visibleColRange.ts'\nimport { cladeGutterWidth } from './components/tree/cladeBrackets.ts'\nimport { scaleBarLength } from './components/tree/scaleBar.ts'\nimport {\n cladeHighlightAlpha,\n cladeHighlightColor,\n defaultAllowedGappyness,\n defaultColWidth,\n defaultColorSchemeName,\n defaultCurrentAlignment,\n defaultDrawMsaLetters,\n defaultFeaturePanelWidth,\n defaultHeight,\n defaultHideGaps,\n defaultRowHeight,\n defaultScrollX,\n defaultScrollY,\n defaultScrollZoom,\n defaultScrollZoomAxis,\n defaultShowDomainLegend,\n defaultShowDomains,\n defaultSubFeatureRows,\n fontSizeFor,\n labelFitFontSize,\n maxCellSize,\n maxFitTreeWidth,\n maxTreeAreaShare,\n maxInlineSnapshotBytes as defaultMaxInlineSnapshotBytes,\n maxNeighborJoiningRows,\n minColWidth,\n minLetterColWidth,\n minLetterRowHeight,\n minRowHeight,\n minTreeWidth,\n pxPerTreeDepth,\n rowPanelHeaderHeight,\n rowTintAlpha,\n scrollZoomAxes,\n segmentFeatureTypes,\n segmentShades,\n treeScaleBarHeight,\n} from './constants.ts'\nimport { createPaletteMap } from './createPaletteMap.ts'\nimport { exportFileName } from './exportFileName.ts'\nimport { featureField, featureName } from './featureFields.ts'\nimport { featuresToAnnotations } from './featuresLayer.ts'\nimport { fetchTextWithProgress, isAbortError } from './fetchUtils.ts'\nimport { flatToTree } from './flatToTree.ts'\nimport {\n collapse,\n find,\n forEachDescendant,\n hierarchy,\n layoutTree,\n leafIndex,\n leaves,\n mrca,\n nodeCoveringRows,\n sort,\n sum as hierarchySum,\n} from './hierarchy.ts'\nimport { DataModelF } from './model/DataModel.ts'\nimport { DialogQueueSessionMixin } from './model/DialogQueue.ts'\nimport { MSAModelF } from './model/msaModel.ts'\nimport { TreeModelF } from './model/treeModel.ts'\nimport { calculateNeighborJoiningTree } from './neighborJoining.ts'\nimport { parseAsn1 } from './parseAsn1.ts'\nimport { calculatePropertyConservation } from './propertyConservation.ts'\nimport { midpointRoot, rerootTree } from './rerootTree.ts'\nimport {\n globalColToVisibleCol,\n seqPosOfGlobalCol,\n visibleColToGlobalCol,\n visibleColsBefore,\n} from './rowCoordinateCalculations.ts'\nimport { resolveScale } from './scales.ts'\nimport { buildSeqPosIndex } from './seqPosToGlobalCol.ts'\nimport { maxBitsFor } from './sequenceLogo.ts'\nimport { stripDefault } from './stripDefault.ts'\nimport { treeTips, widestLabel } from './tipLabels.ts'\nimport {\n computeRowInsertions,\n dropBlanks,\n len,\n outlineColor,\n skipBlanks,\n withAlpha,\n} from './util.ts'\nimport { saveAs } from './vendor/fileSaver.ts'\nimport { writeNewick } from './writeNewick.ts'\nimport { parseWuss } from './wuss.ts'\n\nimport type { ColumnStats } from './columnStats.ts'\nimport type { ScrollZoomAxis } from './constants.ts'\nimport type { HierarchyNode } from './hierarchy.ts'\nimport type { ExportSvgOptions } from './renderToSvg.tsx'\nimport type { TreeNode } from './rerootTree.ts'\nimport type { ScaleSpec } from './scales.ts'\nimport type {\n Annotation,\n Arc,\n BasicTrack,\n Cell,\n Clade,\n CladeMark,\n ResidueMappingProblem,\n ColumnTrackSpec,\n DomainBand,\n Encoding,\n EncodingChannel,\n Feature,\n Highlight,\n Legend,\n LegendEntry,\n MsaSelection,\n NodeWithIds,\n Region,\n ResidueMapping,\n ResidueSegment,\n ResolvedClade,\n ResolvedEncoding,\n ResolvedFeaturePanel,\n ResolvedHighlight,\n ResolvedSelection,\n TreeOrder,\n TreeRoot,\n ResolvedRowPanel,\n ResolvedStripPanel,\n RowFeaturesSpec,\n RowPanelSpan,\n RowDataInput,\n RowPanelSpec,\n RowResidue,\n StructureResidue,\n TrackKind,\n UnshareableData,\n Viewport,\n} from './types.ts'\nimport type { FileLocation as FileLocationType } from '@jbrowse/core/util/types'\nimport type { Instance } from '@jbrowse/mobx-state-tree'\nimport type { IComputedValue } from 'mobx'\n\nfunction parseTreeText(text: string) {\n if (text.startsWith('BioTreeContainer')) {\n return flatToTree(parseAsn1(text))\n }\n return parseNewick(text.startsWith('SEQ') ? parseEmfTree(text).tree : text)\n}\n\n// The height each kind draws at before the user drags a divider. A text track\n// is absent: it is one alignment row tall and follows rowHeight, so the zoom\n// controls already size it.\nexport const defaultTrackHeights: Partial<Record<TrackKind, number>> = {\n bar: 40,\n // taller than a bar track: in a 40px stack of four residues each glyph is\n // too short to identify. Twice the height of the tracks above it, so it\n // starts hidden\n logo: 80,\n arc: 50,\n ruler: 20,\n}\n\n// the kinds a divider resizes. The ruler is a fixed scale, and a text track\n// follows the vertical zoom.\nconst resizableKinds = new Set<TrackKind>(['bar', 'logo', 'arc'])\n\nconst defaultOffTracks = new Set(['sequence-logo', 'position-ruler'])\n\n// a data track carries its own height rather than its kind's, so its divider\n// resizes it alone\nconst ownHeightKey = (id: string) => `own:${id}`\n\n// base-pair arcs: one color for nested helices, one for pseudoknots, which cross\n// them\nconst HELIX_ARC = '#4e79a7'\nconst PSEUDOKNOT_ARC = '#e15759'\n\n// the fill of a span under a scale that gives its value no color, such as a\n// gene a `map` over gene names leaves out\nconst UNSCALED_FEATURE = '#d9d9d9'\n\n// the fraction of a span a following one may cover before it takes a lane of\n// its own in a `features` panel\nconst laneOverlap = 0.1\n\n// a row panel's own width, or a default: the row height, which makes a strip\n// cell square, and a gene neighborhood's width for a features panel. The row\n// height is read only when used, so a panel with a width of its own does not\n// recompute on a vertical zoom\nfunction rowPanelWidth(panel: RowPanelSpec, view: { rowHeight: number }) {\n return (\n panel.width ??\n (panel.kind === 'features' ? defaultFeaturePanelWidth : view.rowHeight)\n )\n}\n\n// one row of the row table as the channels read it. A number or a boolean\n// reads as its string, the way a GFF value does, and null or an object drops\nfunction stringFields(row: unknown) {\n if (typeof row !== 'object' || row === null) {\n return undefined\n }\n const fields: Record<string, string> = {}\n for (const [field, value] of Object.entries(row)) {\n if (typeof value === 'string') {\n fields[field] = value\n } else if (typeof value === 'number' || typeof value === 'boolean') {\n fields[field] = String(value)\n }\n }\n return fields\n}\n\n// the color each row takes from a field of the row table under a scale\nfunction colorByRow(\n rowData: Record<string, Record<string, string> | undefined>,\n field: string,\n colorOf: (value: string) => string | undefined,\n) {\n const colors = new Map<string, string>()\n for (const [name, row] of Object.entries(rowData)) {\n const value = row?.[field]\n const color = value === undefined ? undefined : colorOf(value)\n if (color) {\n colors.set(name, color)\n }\n }\n return colors\n}\n\ntype StripPanelScale = Omit<ResolvedStripPanel, 'id' | 'width' | 'offsetX'>\ntype FeaturePanelScale = Omit<\n ResolvedFeaturePanel,\n 'id' | 'width' | 'offsetX' | 'spans'\n>\n\n// the fill and outline of every feature in a list: its own GFF `color=` first,\n// then the scale an encoding resolves over one of its fields, then the\n// accession palette\nfunction featureColorMap(\n annotations: Annotation[],\n encoding:\n | { field: string; colorOf: (value: string) => string | undefined }\n | undefined,\n fillPalette: Record<string, string>,\n) {\n const strokes = new Map<string, string>()\n const strokeOf = (fill: string) => {\n const hit = strokes.get(fill)\n if (hit !== undefined) {\n return hit\n }\n const stroke = outlineColor(fill)\n strokes.set(fill, stroke)\n return stroke\n }\n return new Map(\n annotations.map(annotation => {\n const value = encoding\n ? featureField(annotation, encoding.field)\n : undefined\n const fill =\n annotation.color ??\n (value === undefined ? undefined : encoding!.colorOf(value)) ??\n (encoding ? UNSCALED_FEATURE : fillPalette[annotation.accession]!)\n return [annotation, { fill, stroke: strokeOf(fill) }]\n }),\n )\n}\n\n// the text a label channel draws inside each span, for the features carrying\n// the field it names\nfunction featureLabelMap(annotations: Annotation[], field: string) {\n const labels = new Map<Annotation, string>()\n for (const annotation of annotations) {\n const value = featureField(annotation, field)\n if (value !== undefined) {\n labels.set(annotation, value)\n }\n }\n return labels\n}\n\n/** what `packDomainLanes` needs to lay a row out, before it has its lane */\ntype Unlaned = Omit<RowPanelSpan, 'lane' | 'laneCount'> & {\n startCol: number\n endCol: number\n}\n\n/**\n * Lanes for `position: \"strandpile\"`, gggenomes' `position_strandpile`: the\n * forward features stack above the line and the reverse below it, each strand\n * packing on its own. The deepest row on each side sets the grid every row lays\n * out on, so the line between the strands sits at one height down the panel and\n * a reader can scan it. A feature with no strand piles with the forward ones.\n */\nfunction strandpileLanes(\n rows: [string, Unlaned[]][],\n): Map<string, RowPanelSpan[]> {\n const piled = rows.map(([name, bands]) => {\n const reverse = packDomainLanes(\n bands.filter(b => b.annotation.strand === -1),\n )\n const forward = packDomainLanes(\n bands.filter(b => b.annotation.strand !== -1),\n )\n return { name, forward, reverse }\n })\n const up = Math.max(0, ...piled.map(p => p.forward[0]?.laneCount ?? 0))\n const down = Math.max(0, ...piled.map(p => p.reverse[0]?.laneCount ?? 0))\n const laneCount = up + down\n return new Map(\n piled.map(({ name, forward, reverse }) => [\n name,\n [\n // forward level 0 is the lane just above the line, stacking upward\n ...forward.map(b => ({ ...b, lane: up - 1 - b.lane, laneCount })),\n ...reverse.map(b => ({ ...b, lane: up + b.lane, laneCount })),\n ],\n ]),\n )\n}\n\n/** one row's spans laid out by the panel's `position` */\nfunction panelLanes(\n panel: RowFeaturesSpec,\n rows: [string, Unlaned[]][],\n): Map<string, RowPanelSpan[]> {\n return panel.position === 'strandpile'\n ? strandpileLanes(rows)\n : new Map(rows.map(([name, bands]) => [name, packDomainLanes(bands)]))\n}\n\n/**\n * The spans a `features` panel draws, keyed by row name and measured in the\n * panel's own pixels. `column` takes the bands the overlay draws, at the\n * alignment's column width. `position` packs each row's features in its own\n * residue positions, shifted by an `align` transform, and maps the extent they\n * cover across every row onto the panel width, so a row with no alignment\n * still has an x.\n */\nfunction featurePanelSpans({\n panel,\n width,\n colWidth,\n domainBands,\n annotationsByRow,\n shifts,\n}: {\n panel: RowFeaturesSpec\n width: number\n colWidth: number\n domainBands: Map<string, DomainBand[]>\n annotationsByRow: Record<string, Annotation[]>\n shifts: Map<string, number> | undefined\n}): Map<string, RowPanelSpan[]> {\n if (panel.x === 'column') {\n return panelLanes(\n panel,\n [...domainBands].map(([name, bands]) => [\n name,\n bands.map(band => ({\n ...band,\n xStart: band.startCol * colWidth,\n xEnd: band.endCol * colWidth,\n })),\n ]),\n )\n }\n const shifted = Object.entries(annotationsByRow).map(\n ([name, annotations]) => {\n const shift = shifts?.get(name) ?? 0\n return [\n name,\n annotations.map(annotation => ({\n annotation,\n start: annotation.start - 1 + shift,\n end: annotation.end + shift,\n })),\n ] as const\n },\n )\n let min = Infinity\n let max = -Infinity\n for (const [, features] of shifted) {\n for (const { start, end } of features) {\n min = Math.min(min, start)\n max = Math.max(max, end)\n }\n }\n // a gene arrow ends where its feature does, so the extent maps onto the whole\n // panel less the pixel the rightmost stroke needs\n const drawable = Math.max(1, width - 1)\n const scale = max > min ? drawable / (max - min) : 0\n // a lane opens where a span covers more than a tenth of the one before it,\n // which keeps the genes of an operon on one lane: adjacent genes commonly\n // share a few bases, and a stop codon overlapping the next start reads as a\n // second lane over the whole row\n return panelLanes(\n panel,\n shifted.map(([name, features]) => [\n name,\n features.map(({ annotation, start, end }) => ({\n annotation,\n xStart: (start - min) * scale,\n xEnd: (end - min) * scale,\n startCol: start,\n endCol: end - (end - start) * laneOverlap,\n })),\n ]),\n )\n}\n\n// a scale over the values a field takes across every feature loaded, so hiding\n// a type in the filter dialog leaves the rest in their colors, and a legend of\n// the values the features drawn carry\nfunction resolveFeatureScale(\n field: string,\n scale: ScaleSpec | undefined,\n annotations: Annotation[],\n drawn: Annotation[],\n) {\n const valuesOf = (list: Annotation[]) =>\n list.map(a => featureField(a, field)).filter(notEmpty)\n const resolved = resolveScale(scale, valuesOf(annotations))\n const shown = new Set(valuesOf(drawn))\n return {\n field,\n ...resolved,\n legend: resolved.legend.filter(entry => shown.has(entry.id)),\n }\n}\n\nconst columnTrackBytes = new WeakMap<ColumnTrackSpec, number>()\n\nfunction columnTrackSize(track: ColumnTrackSpec) {\n let bytes = columnTrackBytes.get(track)\n if (bytes === undefined) {\n bytes = JSON.stringify(track).length\n columnTrackBytes.set(track, bytes)\n }\n return bytes\n}\n\n// a data track over this size stays in the live model but leaves the snapshot,\n// the same rule DataModel applies to an inline document\nfunction columnTrackSizes(tracks?: readonly ColumnTrackSpec[]) {\n return (tracks ?? []).map(columnTrackSize)\n}\n\nfunction smallColumnTracks(\n tracks: ColumnTrackSpec[] | undefined,\n maxInlineSnapshotBytes: number,\n) {\n const sizes = columnTrackSizes(tracks)\n const kept = tracks?.filter((_t, i) => sizes[i]! <= maxInlineSnapshotBytes)\n return kept?.length ? { columnTracks: kept } : {}\n}\n\n/**\n * The snapshot properties reset() carries across a return to the import form:\n * display preferences and layout, nothing derived from the loaded file.\n *\n * reset() applies a default snapshot filtered to this list, so any property\n * left off it resets, including downstream composed ones (e.g. the jbrowse\n * plugin's). Node ids are path-derived (node-0-0-1), so a carried-over\n * `collapsed` or `showOnly` id would match a real node in the next tree and\n * fold it.\n *\n * Exported for modelReset.test.ts.\n */\nexport const preservedOnReset = new Set([\n 'id',\n 'type',\n 'height',\n 'drawMsaLetters',\n 'scrollZoom',\n 'scrollZoomAxis',\n 'bgColor',\n 'colorSchemeName',\n 'customColorScheme',\n 'showColumnStats',\n 'drawLabels',\n 'labelsAlignRight',\n 'treeAreaWidth',\n 'treeWidth',\n 'showBranchLen',\n 'treeOrder',\n 'drawTree',\n 'drawNodeBubbles',\n 'drawNodeLabels',\n 'showTreeOverview',\n 'overviewHeight',\n 'turnedOffTracks',\n 'trackHeights',\n 'hideGaps',\n 'allowedGappyness',\n 'subFeatureRows',\n 'showDomainLegend',\n])\n\n// `turnedOffTracks` holds only the user's explicit choices, so a hidden-by-default\n// track writes nothing into the snapshot. A file-supplied track passes its own\n// `defaultOff`, since the count varies by file: a Pfam seed has a couple of #=GR\n// lines, an Rfam family one per row.\nfunction trackIsOff(\n turnedOffTracks: { get: (id: string) => boolean | undefined },\n id: string,\n defaultOff?: boolean,\n) {\n return turnedOffTracks.get(id) ?? (defaultOff || defaultOffTracks.has(id))\n}\n\n// the marks that set tree state from a node rather than drawing\nconst seedingMarks = new Set<CladeMark>(['collapse', 'focus', 'rotate'])\n\n// shared empty results, so observers don't see a fresh [] as a change\nconst noDomains: Annotation[] = []\nconst noClades: ResolvedClade[] = []\n\n/**\n * Each tip of the full tree in the order the tree draws it, with the on-screen\n * row that shows it: its own, or the row of the collapsed node standing for it\n */\nfunction tipRows(root: HierarchyNode<NodeWithIds>) {\n const rows = new Map<string, { order: number; row: number }>()\n let row = 0\n const pushReversed = (\n stack: HierarchyNode<NodeWithIds>[],\n nodes: HierarchyNode<NodeWithIds>[],\n ) => {\n for (let i = nodes.length - 1; i >= 0; i--) {\n stack.push(nodes[i]!)\n }\n }\n const stack = [root]\n while (stack.length > 0) {\n const node = stack.pop()!\n if (node.children?.length) {\n pushReversed(stack, node.children)\n } else {\n const hidden = [node]\n while (hidden.length > 0) {\n const tip = hidden.pop()!\n const kids = tip.children ?? tip._children\n if (kids?.length) {\n pushReversed(hidden, kids)\n } else {\n rows.set(tip.data.name, { order: rows.size, row })\n }\n }\n row++\n }\n }\n return rows\n}\n\n/**\n * The rows a clade covers and the node an `mrca` names, or undefined when the\n * clade does not resolve: a tip name the tree does not have or has twice, or a\n * leaf count `tips` disagrees with. A `range` counts its tips in the order\n * `tips` gives them, so a collapsed clade inside it counts every leaf it\n * stands for. `index` is the memoized leaf pass over the tree.\n */\nfunction cladeRows(\n clade: Clade,\n root: HierarchyNode<NodeWithIds>,\n index: Map<string, HierarchyNode<NodeWithIds> | undefined>,\n tips: Map<string, { order: number; row: number }>,\n): { rows: [number, number]; nodeId?: string } | undefined {\n if (clade.range) {\n const [a, b] = clade.range.map(name =>\n index.get(name) ? tips.get(name) : undefined,\n )\n if (a === undefined || b === undefined) {\n return undefined\n }\n const [first, last] = a.order <= b.order ? [a, b] : [b, a]\n return last.order - first.order + 1 === clade.tips\n ? { rows: [first.row, last.row] }\n : undefined\n }\n const node = clade.mrca ? mrca(root, clade.mrca, index) : undefined\n if (!node) {\n return undefined\n }\n const nodeTips = leaves(node)\n if (nodeTips.length !== clade.tips) {\n return undefined\n }\n let first = Infinity\n let last = -Infinity\n for (const tip of nodeTips) {\n const row = tips.get(tip.data.name)?.row\n if (row !== undefined) {\n first = Math.min(first, row)\n last = Math.max(last, row)\n }\n }\n return first <= last\n ? { rows: [first, last], nodeId: node.data.id }\n : undefined\n}\n\n/**\n * Every clade that resolves, with its fill color settled, against the rows of\n * `displayed`, the tree as drawn. The tree panel resolves against the\n * displayed rows and the overview against its own, so both take the tree they\n * draw. A `range` record names no node, so the seeding marks, which need one,\n * drop it.\n */\nfunction resolveClades(\n clades: Clade[],\n root: HierarchyNode<NodeWithIds>,\n displayed: HierarchyNode<NodeWithIds>,\n): ResolvedClade[] {\n const index = leafIndex(root)\n const tips = tipRows(displayed)\n return clades.flatMap(clade => {\n const resolved = cladeRows(clade, root, index, tips)\n const seeding = seedingMarks.has(clade.mark)\n return resolved && !(seeding && resolved.nodeId === undefined)\n ? [\n {\n ...resolved,\n mark: clade.mark,\n color: withAlpha(\n clade.color ?? cladeHighlightColor,\n cladeHighlightAlpha,\n ),\n markColor: clade.color,\n label: clade.label,\n },\n ]\n : []\n })\n}\n\nconst childOrders: Record<\n TreeOrder,\n ((a: HierarchyNode, b: HierarchyNode) => number) | undefined\n> = {\n input: undefined,\n branchLength: (a, b) => (a.data.length ?? 1) - (b.data.length ?? 1),\n ladderize: (a, b) => a.value! - b.value!,\n ladderizeReverse: (a, b) => b.value! - a.value!,\n}\n\n/**\n * The tree with the display transforms applied: leaf counts summed, children\n * put in `order` and each `rotated` node's reversed, `showOnly` taken as the\n * new root, and each `collapsed` clade folded. The overview builds the same\n * tree without the focus, so it shows the focused subtree inside the whole.\n */\nfunction buildTreeRoot(\n tree: NodeWithIds,\n {\n collapsed,\n rotated,\n order,\n showOnly,\n }: {\n collapsed: readonly string[]\n rotated: readonly string[]\n order: TreeOrder\n showOnly?: string\n },\n) {\n let hier = hierarchy(tree, d => d.children)\n hierarchySum(hier, d => (d.children.length > 0 ? 0 : 1))\n const compare = childOrders[order]\n if (compare) {\n sort(hier, compare)\n }\n if (rotated.length > 0) {\n const flip = new Set(rotated)\n forEachDescendant(hier, n => {\n if (flip.has(n.data.id)) {\n n.children?.reverse()\n }\n })\n }\n\n if (showOnly) {\n const res = find(hier, n => n.data.id === showOnly)\n if (res) {\n hier = res\n }\n }\n\n for (const collapsedId of collapsed) {\n const node = find(hier, n => n.data.id === collapsedId)\n if (node) {\n if (node.children) {\n collapse(node)\n } else if (node.parent?.children) {\n node.parent.children = node.parent.children.filter(\n c => c.data.id !== collapsedId,\n )\n }\n }\n }\n\n return hier\n}\n\n/**\n * The node whose branch an outgroup roots the tree on: the outgroup's most\n * recent common ancestor, or the rest of the tips' where that ancestor is the\n * root, since the outgroup then straddles the root and the branch above the\n * other side is the same branch of the unrooted tree.\n */\nfunction outgroupNode(root: HierarchyNode, outgroup: string[]) {\n const index = leafIndex(root)\n const node = mrca(root, outgroup, index)\n if (node !== root) {\n return node\n }\n const out = new Set(outgroup)\n const rest = leaves(root)\n .map(n => n.data.name)\n .filter(name => !out.has(name))\n const other = mrca(root, rest, index)\n return other === root ? undefined : other\n}\n\n/**\n * `tree` rerooted as `treeRoot` asks, with fresh path ids. The ids of the tree\n * as written become names on unnamed nodes, and a rerooting would carry them\n * along as labels, so they come off first.\n */\nfunction rootTree(tree: NodeWithIds, treeRoot: TreeRoot) {\n const plain = new Map<NodeWithIds, TreeNode>()\n for (const node of preorder(tree).reverse()) {\n plain.set(node, {\n name: node.name === node.id ? undefined : node.name,\n length: node.length,\n children: node.children.map(c => plain.get(c)!),\n })\n }\n const input = plain.get(tree)!\n if (treeRoot === 'midpoint') {\n return generateNodeIds(midpointRoot(input))\n }\n const target = outgroupNode(\n hierarchy(tree, d => d.children),\n treeRoot.outgroup,\n )\n return target\n ? generateNodeIds(rerootTree(input, plain.get(target.data)!))\n : tree\n}\n\n// the inclusive tip indices a node covers, from its xMin/xMax in a layout one\n// row per tip\nfunction tipRange(node: HierarchyNode): [number, number] {\n return [Math.round(node.xMin! - 0.5), Math.round(node.xMax! - 0.5)]\n}\n\n// the channels reading the feature table; every other channel reads rowData\nconst featureChannels = new Set<EncodingChannel>([\n 'featureFill',\n 'featureLabel',\n])\n\n// seqPos -> column indexes per row, keyed on the parse so they are garbage\n// collected with it. A computed would rebuild every row's index when read\n// outside a reactive context.\n// Newick tools write a colon in a name as an underscore, so a tree's row\n// `chr1_100-200` is the GFF's `chr1:100-200`, as FastaMSA.getRow resolves it\nfunction annotationRowName(id: string, rowNames: Map<string, number>) {\n if (rowNames.has(id)) {\n return id\n }\n const underscored = id.replaceAll(':', '_')\n return rowNames.has(underscored) ? underscored : id\n}\n\nconst seqPosIndexCache = new WeakMap<object, Map<string, Int32Array>>()\n\n// A segment is a 1:1 run. A segment whose sides differ in length is malformed,\n// and the lookups treat it like an uncovered position.\nfunction sameLength(segment: ResidueSegment) {\n return (\n segment.rowEnd - segment.rowStart ===\n segment.structEnd - segment.structStart\n )\n}\n\n// fit() divides the viewport by the row or column count and multiplies back, so\n// an exact fit can land a fraction of a pixel over. A plain `>` would then show\n// a scrollbar that shrinks the viewport and leaves a gap.\nfunction overflows(content: number, viewport: number) {\n return content - viewport > 0.5\n}\n\nfunction inRanges(ranges: [number, number][] | undefined, position: number) {\n return !!ranges?.some(([start, end]) => position >= start && position <= end)\n}\n\n// sorted integers as inclusive [first, last] runs of consecutive values\nfunction consecutiveRuns(sorted: number[]) {\n const runs: [number, number][] = []\n for (const n of sorted) {\n const last = runs.at(-1)\n if (last && n <= last[1] + 1) {\n last[1] = Math.max(last[1], n)\n } else {\n runs.push([n, n])\n }\n }\n return runs\n}\n\n// the value every one of a node's children reports, or undefined where one of\n// them has no value or they disagree\nfunction sharedValue(values: (string | undefined)[]) {\n const [first] = values\n return first !== undefined && values.every(v => v === first)\n ? first\n : undefined\n}\n\n// preorder, so reversing the list puts every node after its descendants\nfunction preorder(tree: NodeWithIds) {\n const order: NodeWithIds[] = []\n const stack = [tree]\n while (stack.length > 0) {\n const node = stack.pop()!\n order.push(node)\n for (const child of node.children) {\n stack.push(child)\n }\n }\n return order\n}\n\n/**\n * #stateModel MsaView\n *\n * The main MSAView state model. Holds the loaded alignment, tree, and optional\n * overlay annotations, plus all display state (color scheme, zoom,\n * scroll, collapsed clades). It composes in members from `DialogQueueSessionMixin`,\n * `Tree`, and `MSAModel` (see Inherited members below). Data is loaded reactively\n * from the `msaFilehandle` / `treeFilehandle` / `gffFilehandle` properties, or set\n * directly with `setData`. Most state is persisted into the shareable URL.\n *\n * #example\n * ```js\n * import { MSAModelF } from 'react-msaview'\n * import { types } from '@jbrowse/mobx-state-tree'\n *\n * const RootModel = types.model({ view: types.optional(MSAModelF(), {}) })\n * const root = RootModel.create({})\n * root.view.setData({ msa: '>seq1\\nACGT\\n>seq2\\nACGT' })\n * ```\n *\n * `maxInlineSnapshotBytes` is the largest pasted or local document, and the\n * largest data track, the snapshot keeps; a larger one stays in the live model\n * and `unshareableData` names it. The standalone app, whose links carry the\n * snapshot in the URL fragment, raises it.\n */\nfunction stateModelFactory({\n maxInlineSnapshotBytes = defaultMaxInlineSnapshotBytes,\n}: { maxInlineSnapshotBytes?: number } = {}) {\n return types\n .compose(\n DialogQueueSessionMixin(),\n TreeModelF(),\n MSAModelF(),\n types.model('MsaView', {\n /**\n * #property\n * id of view, randomly generated if not provided\n */\n id: ElementId,\n\n /**\n * #property\n */\n showDomains: stripDefault(types.boolean, defaultShowDomains),\n /**\n * #property\n * whether the domain legend is expanded. The legend floats over the\n * top-right of the alignment and covers residues, so a session or\n * figure can open with it collapsed.\n */\n showDomainLegend: stripDefault(types.boolean, defaultShowDomainLegend),\n /**\n * #property\n */\n hideGaps: stripDefault(types.boolean, defaultHideGaps),\n /**\n * #property\n */\n allowedGappyness: stripDefault(types.number, defaultAllowedGappyness),\n /**\n * #property\n */\n subFeatureRows: stripDefault(types.boolean, defaultSubFeatureRows),\n\n /**\n * #property\n * hardcoded view type\n */\n type: types.literal('MsaView'),\n\n /**\n * #property\n */\n drawMsaLetters: stripDefault(types.boolean, defaultDrawMsaLetters),\n\n /**\n * #property\n * zoom in/out on plain mouse-wheel without holding ctrl\n */\n scrollZoom: stripDefault(types.boolean, defaultScrollZoom),\n\n /**\n * #property\n * which cell dimensions a wheel zoom scales, while `scrollZoom` is on\n */\n scrollZoomAxis: stripDefault(\n types.enumeration('ScrollZoomAxis', [...scrollZoomAxes]),\n defaultScrollZoomAxis,\n ),\n\n /**\n * #property\n * height of the div containing the view, px\n */\n height: stripDefault(types.number, defaultHeight),\n\n /**\n * #property\n * height of each row, px\n */\n rowHeight: stripDefault(types.number, defaultRowHeight),\n\n /**\n * #property\n * scroll position, Y-offset, px\n */\n scrollY: stripDefault(types.number, defaultScrollY),\n\n /**\n * #property\n * scroll position, X-offset, px\n */\n scrollX: stripDefault(types.number, defaultScrollX),\n\n /**\n * #property\n * width of columns, px\n */\n colWidth: stripDefault(types.number, defaultColWidth),\n\n /**\n * #property\n * filehandle object for the tree\n */\n treeFilehandle: types.maybe(FileLocation),\n\n /**\n * #property\n * filehandle object for the MSA (which could contain a tree e.g. with\n * stockholm files)\n */\n msaFilehandle: types.maybe(FileLocation),\n\n /**\n * #property\n * filehandle object for tree metadata\n */\n treeMetadataFilehandle: types.maybe(FileLocation),\n\n /**\n * #property\n * filehandle object for a GFF file of overlay annotations\n */\n gffFilehandle: types.maybe(FileLocation),\n\n /**\n * #property\n */\n currentAlignment: stripDefault(types.number, defaultCurrentAlignment),\n\n /**\n * #property\n * array of tree parent nodes that are 'collapsed' (all children are\n * hidden)\n */\n collapsed: stripDefault(types.array(types.string), []),\n\n /**\n * #property\n * tree nodes whose children draw in reverse order, which is ggtree's\n * `rotate`: the same tree, with the clades on either side of the node\n * swapped\n */\n rotated: stripDefault(types.array(types.string), []),\n\n /**\n * #property\n * where the tree is rooted: `midpoint` roots it halfway along the\n * longest path between two tips, `{outgroup}` on the branch above\n * the tips named, and undefined keeps the file's root\n */\n treeRoot: types.frozen<TreeRoot | undefined>(),\n\n /**\n * #property\n * focus on particular subtree\n */\n showOnly: types.maybe(types.string),\n /**\n * #property\n * the user's explicit show/hide choice per track id, keyed by id with\n * the value meaning \"off\". A track the user has never touched is absent\n * and falls back to its own default (see `defaultOffTracks`), so a\n * hidden-by-default track adds nothing to the shared URL.\n */\n turnedOffTracks: stripDefault(types.map(types.boolean), {}),\n\n /**\n * #property\n * the height of every track one divider resizes, keyed by `heightKey`:\n * the `kind` for the computed tracks, `own:<id>` for a data track. A\n * key is absent until the user drags that divider, and\n * `defaultTrackHeights` answers for it until then, so an untouched\n * viewer adds nothing to the shared URL.\n */\n trackHeights: stripDefault(types.map(types.number), {}),\n /**\n * #property\n * tracks supplied as data: per-column values drawn as bars, or a\n * per-column string drawn as a text track. See docs/layers.md\n */\n columnTracks: stripDefault(\n types.array(types.frozen<ColumnTrackSpec>()),\n [],\n ),\n\n /**\n * #property\n * row-to-structure residue correspondence, computed outside the viewer\n * (e.g. from SIFTS). Matching by sequence equality places a tagged\n * construct, a truncation or a subsequence row on the wrong residue.\n * See docs/layers.md\n */\n residueMappings: stripDefault(\n types.array(types.frozen<ResidueMapping>()),\n [],\n ),\n\n /**\n * #property\n * data from the loaded tree/msa/treeMetadata, generally loaded by\n * autorun\n */\n data: types.optional(DataModelF(maxInlineSnapshotBytes), {}),\n\n /**\n * #property\n * the user's explicit hide choices per annotation accession, keyed by\n * accession with the value meaning \"off\", like `turnedOffTracks`. An\n * untouched accession is absent and drawn, so the shared URL grows\n * only with the user's filters\n */\n turnedOffFeatures: stripDefault(types.map(types.boolean), {}),\n /**\n * #property\n */\n relativeTo: types.maybe(types.string),\n /**\n * #property\n * declarative seed for the highlighted-columns overlay (visible column\n * indices). Unlike the volatile `highlightedColumns` (driven by\n * transient genome-hover sync), this persists in the snapshot/URL so a\n * shared link can open with specific columns highlighted. Applied once\n * in afterCreate.\n */\n highlightColumns: types.frozen<number[] | undefined>(),\n /**\n * #property\n * labeled highlights in 1-based inclusive coordinates: a column span\n * `{start, end}`, a residue span `{row, start, end}` of a named row,\n * or a row set `{rows}`, each with an optional `label` and `color`.\n * Persists in the snapshot and the URL.\n */\n highlights: stripDefault(types.array(types.frozen<Highlight>()), []),\n /**\n * #property\n * features on the rows as data, `{row, start, end, name, ...}` in\n * residues of each row, drawn with the GFF's annotations. Persists in\n * the snapshot and the URL.\n */\n features: stripDefault(types.array(types.frozen<Feature>()), []),\n /**\n * #property\n * the block the reader selected: `{start, end}` columns of the file,\n * 1-based inclusive like a column highlight, and `rows` by name, every\n * row where absent. Undefined until something is selected, so a view\n * without one adds nothing to the shared URL.\n */\n selection: types.frozen<MsaSelection | undefined>(),\n /**\n * #property\n * where the view opens, in `highlights` coordinates: `{row, start,\n * end}` zooms onto residues of that row and scrolls the row to the\n * middle, `{start, end}` zooms onto alignment columns. Applied once the\n * alignment and any tree file have loaded, then cleared, so a reloaded\n * session keeps the reader's own scroll.\n */\n region: types.frozen<Region | undefined>(),\n /**\n * #property\n * clades of the tree with a mark drawn over them. `mrca` names tips\n * whose common ancestor is the clade, or `range` its first and last\n * tip in display order, and `tips` is the leaf count the producer\n * measured. `mark` is `highlight`, `bracket`, `collapse`, `focus` or\n * `rotate`.\n * See docs/layers.md\n */\n clades: stripDefault(types.array(types.frozen<Clade>()), []),\n /**\n * #property\n * what the viewer's own marks read from `rowData`:\n * `{channel, field, scale?}` per channel, where `channel` is\n * `tipLabel` or `rowTint`. See docs/layers.md\n */\n encodings: stripDefault(types.array(types.frozen<Encoding>()), []),\n /**\n * #property\n * panels drawn between the tree and the alignment:\n * `{kind: \"strip\", field, scale?, width?, header?}` colors one cell\n * per row from a `rowData` field, and\n * `{kind: \"features\", x, encoding?, transform?, width?, header?}`\n * draws the spans the GFF carries. See docs/layers.md\n */\n rowPanels: stripDefault(types.array(types.frozen<RowPanelSpec>()), []),\n }),\n )\n .volatile(() => ({\n /**\n * #volatile\n */\n headerHeight: 0,\n /**\n * #volatile\n * leaves the toolbar out, for a host drawing its own controls. Kept out\n * of the snapshot so a link opened in the full app shows the toolbar.\n */\n hideHeader: false,\n /**\n * #volatile\n * shows the import form while the view has no data. MSAViewer turns it\n * off, since its host supplies the data and the form is the demo app's\n */\n importForm: true,\n /**\n * #volatile\n */\n status: undefined as { msg: string; onCancel?: () => void } | undefined,\n /**\n * #volatile\n * canvas scale factor, from the device pixel ratio\n */\n highResScaleFactor:\n typeof window === 'undefined' ? 1 : window.devicePixelRatio,\n\n /**\n * #volatile\n */\n loadingMSA: false,\n /**\n * #volatile\n */\n loadingTree: false,\n /**\n * #volatile\n */\n volatileWidth: undefined as number | undefined,\n /**\n * #volatile\n * resize handle width between tree and msa area, px\n */\n resizeHandleWidth: 5,\n\n /**\n * #volatile\n * size of blocks of content to be drawn, px\n */\n blockSize: 500,\n\n /**\n * #volatile\n * the currently mouse-hovered row\n */\n mouseRow: undefined as number | undefined,\n\n /**\n * #volatile\n * the currently mouse-hovered column\n */\n mouseCol: undefined as number | undefined,\n\n /**\n * #volatile\n * the currently mouse-click row\n */\n mouseClickRow: undefined as number | undefined,\n\n /**\n * #volatile\n * the currently mouse-click column\n */\n mouseClickCol: undefined as number | undefined,\n\n /**\n * #volatile\n * the currently hovered tree node ID and its descendant leaf names\n */\n hoveredTreeNode: undefined as\n | { nodeId: string; descendantNames: string[] }\n | undefined,\n\n /**\n * #volatile\n * array of column indices to highlight\n */\n highlightedColumns: undefined as number[] | undefined,\n\n /**\n * #volatile\n * transient highlights keyed by owner, so a structure viewer's hover and\n * a genome view's hover each clear only their own. Not persisted.\n */\n transientHighlights: {} as Record<string, Highlight[]>,\n\n /**\n * #volatile\n */\n minimapHeight: 56,\n\n /**\n * #volatile\n */\n marginLeft: 20,\n\n /**\n * #volatile\n */\n // eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion\n error: undefined as unknown,\n\n /**\n * #volatile\n * non-fatal load problems: an optional layer that failed to load, an\n * overlay that failed to parse. `error` replaces the view and is for the\n * alignment itself. `warnings` adds the ones derived from the data\n */\n loadWarnings: [] as string[],\n\n /**\n * #volatile\n * derived warnings the user dismissed, which stay hidden while the data\n * behind them holds\n */\n dismissedWarnings: [] as string[],\n\n /**\n * #volatile\n * bumped by reset(). The error boundary above the view uses it as its key,\n * since the boundary keeps its caught error until remounted\n */\n resetCount: 0,\n\n /**\n * #volatile\n * set by a host that restores the loaded documents itself, such as a\n * jbrowse session or a page that refetches them. `unshareableData` then\n * reports nothing\n */\n hostCarriesData: false,\n\n /**\n * #volatile\n * overlay annotations drawn on the alignment. InterProScan JSON, GFF and\n * user uploads all convert to this flat list\n */\n annotations: [] as Annotation[],\n }))\n .actions(self => ({\n /**\n * #action\n * draw the alignment with positions numbered relative to the given row's\n * sequence (its node id), instead of in raw MSA-column coordinates\n */\n drawRelativeTo(id: string | undefined) {\n self.relativeTo = id\n },\n /**\n * #action\n * hide columns that are entirely (or mostly, see allowedGappyness) gaps\n */\n setHideGaps(arg: boolean) {\n self.hideGaps = arg\n },\n /**\n * #action\n */\n setAllowedGappyness(arg: number) {\n self.allowedGappyness = arg\n },\n /**\n * #action\n */\n setLoadingMSA(arg: boolean) {\n self.loadingMSA = arg\n },\n /**\n * #action\n */\n setLoadingTree(arg: boolean) {\n self.loadingTree = arg\n },\n /**\n * #action\n */\n setWidth(arg: number) {\n self.volatileWidth = arg\n },\n /**\n * #action\n * update the canvas scale factor when the device pixel ratio changes\n * (moving between monitors, browser zoom)\n */\n setHighResScaleFactor(arg: number) {\n self.highResScaleFactor = arg\n },\n /**\n * #action\n * set the height of the view in px\n */\n setHeight(height: number) {\n self.height = height\n },\n\n /**\n * #action\n * set error state\n */\n setError(error?: unknown) {\n self.error = error\n },\n\n /**\n * #action\n * record a non-fatal load problem: a layer that failed to load, a file\n * that failed to parse. A message already on the list is not added again\n */\n addWarning(warning: string) {\n if (!self.loadWarnings.includes(warning)) {\n self.loadWarnings = [...self.loadWarnings, warning]\n }\n },\n\n /**\n * #action\n * declare that this host restores the loaded documents itself, which\n * hides the \"Not in the link\" warning. See `hostCarriesData`\n */\n setHostCarriesData(arg: boolean) {\n self.hostCarriesData = arg\n },\n\n /**\n * #action\n * set mouse position (row, column) in the MSA\n *\n * Public API: a host calls this (and reads `mouseCol`) to sync hover with\n * its own view, such as a genome view or 3D structure. Keep the name and\n * signature stable.\n */\n setMousePos(col?: number, row?: number) {\n self.mouseCol = col\n self.mouseRow = row\n },\n\n /**\n * #action\n * set highlighted columns\n *\n * Public API: jbrowse-plugin-msaview calls this from its\n * afterCreateAutoruns, and MSAViewer passes its `highlightColumns` prop\n * through it.\n */\n setHighlightedColumns(columns?: number[]) {\n self.highlightedColumns = columns\n },\n /**\n * #action\n */\n setRegion(region?: Region) {\n self.region = region\n },\n /**\n * #action\n */\n setHighlights(highlights: Highlight[]) {\n self.highlights.replace(highlights)\n },\n /**\n * #action\n */\n setFeatures(features: Feature[]) {\n self.features.replace(features)\n },\n /**\n * #action\n * select a block, in `selection` coordinates. `start` and `end` may come\n * in either order.\n */\n setSelection(selection?: MsaSelection) {\n const next = selection && {\n start: Math.min(selection.start, selection.end),\n end: Math.max(selection.start, selection.end),\n ...(selection.rows ? { rows: selection.rows } : {}),\n }\n if (!compareStructural(next, self.selection)) {\n self.selection = next\n }\n },\n /**\n * #action\n */\n clearSelection() {\n this.setSelection(undefined)\n },\n\n /**\n * #action\n * replace the clades the viewer marks (see docs/layers.md)\n */\n setClades(clades: Clade[]) {\n self.clades.replace(clades)\n },\n /**\n * #action\n * show `highlights` for `owner`, replacing that owner's previous ones and\n * leaving other owners' in place\n */\n applyHighlight(owner: string, highlights: Highlight[]) {\n self.transientHighlights = {\n ...self.transientHighlights,\n [owner]: highlights,\n }\n },\n /**\n * #action\n * remove `owner`'s highlights, leaving other owners' in place\n */\n clearHighlight(owner: string) {\n if (owner in self.transientHighlights) {\n const { [owner]: _dropped, ...rest } = self.transientHighlights\n self.transientHighlights = rest\n }\n },\n /**\n * #action\n * toggle the annotation overlay on the alignment\n */\n setShowDomains(arg: boolean) {\n self.showDomains = arg\n },\n /**\n * #action\n * expand or collapse the domain legend that floats over the alignment\n */\n setShowDomainLegend(arg: boolean) {\n self.showDomainLegend = arg\n },\n /**\n * #action\n */\n setSubFeatureRows(arg: boolean) {\n self.subFeatureRows = arg\n },\n /**\n * #action\n * set mouse click position (row, column) in the MSA\n */\n setMouseClickPos(col?: number, row?: number) {\n self.mouseClickCol = col\n self.mouseClickRow = row\n },\n\n /**\n * #action\n * set row height (px)\n */\n setRowHeight(n: number) {\n self.rowHeight = n\n },\n\n /**\n * #action\n * set col width (px)\n */\n setColWidth(n: number) {\n self.colWidth = n\n },\n\n /**\n * #action\n * switch to another alignment of a multi-alignment file (Stockholm).\n * Clears the collapsed and rotated node ids, the subtree in focus, the\n * reference row and the scroll position, which all refer to the\n * previous alignment\n */\n setCurrentAlignment(n: number) {\n if (n === self.currentAlignment) {\n return\n }\n transaction(() => {\n self.currentAlignment = n\n self.collapsed.clear()\n self.rotated.clear()\n this.setShowOnly(undefined)\n this.drawRelativeTo(undefined)\n self.scrollX = 0\n self.scrollY = 0\n })\n },\n\n /**\n * #action\n * collapse or un-collapse the subtree rooted at the given tree node id\n */\n toggleCollapsed(node: string) {\n if (self.collapsed.includes(node)) {\n self.collapsed.remove(node)\n } else {\n self.collapsed.push(node)\n }\n },\n\n /**\n * #action\n * reverse the order of the given node's children, or restore it\n */\n toggleRotated(node: string) {\n if (self.rotated.includes(node)) {\n self.rotated.remove(node)\n } else {\n self.rotated.push(node)\n }\n },\n\n /**\n * #action\n */\n clearRotated() {\n self.rotated.clear()\n },\n\n /**\n * #action\n * reroot the tree. Clears `collapsed`, `rotated` and `showOnly`, whose\n * path-derived node ids name other nodes in the rerooted tree\n */\n setTreeRoot(treeRoot?: TreeRoot) {\n if (compareStructural(self.treeRoot, treeRoot)) {\n return\n }\n transaction(() => {\n self.treeRoot = treeRoot\n self.collapsed.clear()\n self.rotated.clear()\n this.setShowOnly(undefined)\n })\n },\n\n /**\n * #action\n * show only the subtree rooted at the given node id (pass undefined to\n * show the whole tree again)\n */\n setShowOnly(node?: string) {\n self.showOnly = node\n },\n\n /**\n * #action\n * set the alignment/tree/metadata/domain data directly from strings,\n * bypassing the filehandle loaders\n */\n setData(data: {\n msa?: string\n tree?: string\n treeMetadata?: string\n gff?: string\n }) {\n self.data = cast(data)\n },\n\n /**\n * #action\n */\n setMSAFilehandle(msaFilehandle?: FileLocationType) {\n self.msaFilehandle = cast(msaFilehandle)\n },\n\n /**\n * #action\n */\n setTreeFilehandle(treeFilehandle?: FileLocationType) {\n self.treeFilehandle = cast(treeFilehandle)\n },\n\n /**\n * #action\n */\n setTreeMetadataFilehandle(treeMetadataFilehandle?: FileLocationType) {\n self.treeMetadataFilehandle = cast(treeMetadataFilehandle)\n },\n\n /**\n * #action\n */\n setGFFFilehandle(gffFilehandle?: FileLocationType) {\n self.gffFilehandle = cast(gffFilehandle)\n },\n\n /**\n * #action\n */\n setMSA(result: string) {\n self.data.setMSA(result)\n },\n\n /**\n * #action\n */\n setTree(result: string) {\n self.data.setTree(result)\n },\n\n /**\n * #action\n */\n setTreeMetadata(result: string) {\n self.data.setTreeMetadata(result)\n },\n\n /**\n * #action\n * store the GFF text in the snapshot like the alignment and tree. The\n * parsed annotations are volatile and a blob filehandle is cleared once\n * read, so the text is the only persisted copy. An autorun parses it\n * into annotations, and clears the ones it drew when the text goes.\n */\n setGFF(result?: string) {\n self.data.setGFF(result)\n },\n }))\n\n .views(self => ({\n /**\n * #getter\n * hideGaps takes effect when a collapse or a focus hides rows, whose\n * residues leave columns all gaps among the rest, or when\n * allowedGappyness is under 100\n */\n get hideGapsEffective() {\n return (\n self.hideGaps &&\n (self.collapsed.length > 0 ||\n self.showOnly !== undefined ||\n self.allowedGappyness < 100)\n )\n },\n /**\n * #getter\n * the annotations the overlay, the legend and the encodings draw: the\n * GFF's, then the `features` layer's\n */\n get allAnnotations(): Annotation[] {\n return self.features.length > 0\n ? [...self.annotations, ...featuresToAnnotations(self.features)]\n : self.annotations\n },\n /**\n * #getter\n */\n get actuallyShowDomains() {\n return self.showDomains && this.allAnnotations.length > 0\n },\n /**\n * #getter\n * whether the host restores the loaded documents outside the snapshot.\n * When true, `unshareableData` is empty.\n *\n * A simple host sets `hostCarriesData`. A host where this depends on how\n * the view was opened overrides the getter in its own composed model's\n * `.views` block; jbrowse-plugin-msaview's indexed-location views refetch\n * from a URL the session holds, while its data-store views do not.\n * `unshareableData` reads it off `self`, so an override takes effect.\n */\n get hostRestoresData() {\n return self.hostCarriesData\n },\n get viewInitialized() {\n return self.volatileWidth !== undefined\n },\n /**\n * #getter\n */\n get width() {\n if (self.volatileWidth === undefined) {\n throw new Error('not initialized')\n }\n return self.volatileWidth\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get colorScheme() {\n const { customColorScheme, colorSchemeName } = self\n // colorSchemeName is a free string (menus, snapshots, URL params), so a\n // stale name falls back to the default\n return customColorScheme\n ? letterColorTable(customColorScheme)\n : (colorSchemes[colorSchemeName] ??\n colorSchemes[defaultColorSchemeName]!)\n },\n\n /**\n * #getter\n * the scheme coloring each cell from its column's statistics, or\n * undefined while the cells take a fixed color per letter, from the\n * built-in table or from `customColorScheme`\n */\n get dynamicColorSchemeName() {\n const { customColorScheme, colorSchemeName } = self\n return !customColorScheme && colorSchemeName.includes('dynamic')\n ? colorSchemeName\n : undefined\n },\n\n /**\n * #getter\n */\n get header() {\n return this.MSA?.getHeader() ?? {}\n },\n\n /**\n * #getter\n */\n get alignmentNames() {\n return this.MSA?.alignmentNames ?? []\n },\n /**\n * #getter\n */\n get noTree() {\n return !!this.tree.noTree\n },\n get noDomains() {\n return self.allAnnotations.length === 0\n },\n\n /**\n * #getter\n * loaded documents left out of the snapshot, largest first. A file opened\n * from disk or pasted in becomes inline text, and DataModel drops an\n * inline document past `maxInlineSnapshotBytes`.\n *\n * The header lists these, and the standalone app drops `#data=` from\n * the address bar while the list is non-empty or the encoded link would\n * pass its `maxLinkLength`, so a copied link never opens an empty viewer\n * unannounced. A document fetched from a URL never appears here, since\n * the snapshot keeps its filehandle.\n *\n * Empty when `hostCarriesData` is true.\n */\n get unshareableData(): UnshareableData[] {\n if (self.hostRestoresData) {\n return []\n }\n const { data } = self\n // data tracks past the limit also leave the snapshot\n const trackBytes = columnTrackSizes(self.columnTracks)\n .filter(bytes => bytes > maxInlineSnapshotBytes)\n .reduce((a, b) => a + b, 0)\n return (\n [\n ['alignment', data.msa, self.msaFilehandle],\n ['tree', data.tree, self.treeFilehandle],\n ['annotations', data.gff, self.gffFilehandle],\n ['row metadata', data.treeMetadata, self.treeMetadataFilehandle],\n ] as const\n )\n .flatMap<UnshareableData>(([what, text, filehandle]) =>\n !filehandle && text && text.length > maxInlineSnapshotBytes\n ? [{ what, bytes: text.length }]\n : [],\n )\n .concat(\n trackBytes ? [{ what: 'data tracks', bytes: trackBytes }] : [],\n )\n .sort((a, b) => b.bytes - a.bytes)\n },\n menuItems() {\n return []\n },\n /**\n * #getter\n * the row table: extra fields per row, keyed by row name, which the\n * `encodings` channels read. It is stored as the JSON string\n * `data.treeMetadata`, the name that travels in existing links, so the\n * inline size limit and `treeMetadataFilehandle` cover it. The tree area\n * fit reads it on every layout, so a malformed user-supplied file\n * returns {} instead of throwing out of rendering, and every field is a\n * string by the time a scale sorts it.\n */\n get rowData(): Record<string, Record<string, string> | undefined> {\n const text = self.data.treeMetadata\n if (!text) {\n return {}\n }\n try {\n const parsed: unknown = JSON.parse(text)\n return typeof parsed === 'object' && parsed !== null\n ? Object.fromEntries(\n Object.entries(parsed).map(([name, row]) => [\n name,\n stringFields(row),\n ]),\n )\n : {}\n } catch (e) {\n console.error('failed to parse rowData', e)\n return {}\n }\n },\n /**\n * #method\n * one row's fields, the single reader of the row table\n */\n rowDataOf(name: string) {\n return this.rowData[name]\n },\n /**\n * #getter\n * the field names the row table carries, sorted, for a producer or a UI\n * choosing one to encode\n */\n get rowFields(): string[] {\n const fields = new Set<string>()\n for (const row of Object.values(this.rowData)) {\n for (const field of Object.keys(row ?? {})) {\n fields.add(field)\n }\n }\n return [...fields].sort((a, b) => a.localeCompare(b))\n },\n /**\n * #getter\n */\n get MSA() {\n const text = self.data.msa\n // uses parseMSA so the named MSAParserType return type is portable\n // to downstream consumers (avoids TS2883 with default exports)\n return text\n ? parseMSA(text, self.currentAlignment, self.msaFormat)\n : null\n },\n /**\n * #getter\n */\n get numColumns() {\n return (this.MSA?.getWidth() ?? 0) - this.blanks.length\n },\n\n /**\n * #getter\n * the tree the file or the alignment gives, before `treeRoot`\n */\n get inputTree(): NodeWithIds {\n const text = self.data.tree\n return text\n ? generateNodeIds(parseTreeText(text))\n : (this.MSA?.getTree() ?? {\n noTree: true,\n children: [],\n id: 'empty',\n name: 'empty',\n })\n },\n\n /**\n * #getter\n * the tree as the file or the alignment gives it, rerooted where\n * `treeRoot` asks. Every node id, and so `collapsed`, `rotated` and\n * `showOnly`, refers to this tree.\n */\n get tree(): NodeWithIds {\n const tree = this.inputTree\n return self.treeRoot && !tree.noTree\n ? rootTree(tree, self.treeRoot)\n : tree\n },\n\n /**\n * #getter\n * Returns the list of row (sequence) names in display order.\n * Part of the public API used by downstream consumers (e.g. jbrowse plugins).\n */\n get rowNames(): string[] {\n return this.leaves.map(n => n.data.name)\n },\n /**\n * #getter\n */\n get rowNamesSet() {\n return new Map(\n this.leaves.map((leaf, index) => [leaf.data.name, index] as const),\n )\n },\n /**\n * #getter\n * `clades` resolved to the rows each one covers. The tip names resolve\n * against `tree` rather than `root`, so a clade whose ancestor the user\n * collapsed keeps its rows. One leaf pass over the tree serves every\n * clade. A `range` record names no node, so `collapse`, `focus` and\n * `rotate`, which need one, drop it.\n */\n get resolvedClades(): ResolvedClade[] {\n if (self.clades.length === 0) {\n return noClades\n }\n return resolveClades(\n self.clades,\n hierarchy(this.tree, d => d.children),\n this.root,\n )\n },\n /**\n * #getter\n * the pixel column reserved at the right of the tree area for the bracket\n * mark, which the tip labels and the tree itself stay clear of. Zero\n * where no clade draws a bar or a label.\n */\n get cladeGutterWidth() {\n return cladeGutterWidth(self.clades)\n },\n /**\n * #getter\n * whether a tree draws beside the labels: false for a file with no\n * tree, and with drawTree off\n */\n get treeDrawn() {\n return self.drawTree && !this.noTree\n },\n /**\n * #getter\n * the leaf names of the whole tree and its depth in levels. The fit\n * reads these, so a collapse or a focus leaves the tree area as it is\n */\n get treeTips() {\n return treeTips(this.tree)\n },\n /**\n * #getter\n * the widest tip label at labelFitFontSize, measured whether or not a\n * zoom hides the labels\n */\n get maxTipLabelWidth() {\n return widestLabel(\n this.treeTips.names.map(name => this.rowDataOf(name)?.genome || name),\n labelFitFontSize,\n )\n },\n /**\n * #getter\n * the px the tip labels take across the tree area: the widest label at\n * labelFitFontSize and the gaps either side of it, or 0 with drawLabels\n * off\n */\n get labelColumnWidth() {\n return self.drawLabels\n ? this.maxTipLabelWidth + (this.treeDrawn ? 10 : 6)\n : 0\n },\n /**\n * #getter\n * the tree area width while treeAreaWidth is undefined: the label column\n * beside a tree that widens with its depth, up to maxTreeAreaShare of the\n * view, or the room the row panels leave where there is no alignment.\n * Where that binds, the tree keeps minTreeWidth and the renderer\n * ellipsizes the labels\n */\n get fittedTreeAreaWidth() {\n const chrome = self.marginLeft + this.cladeGutterWidth\n const tree = this.treeDrawn\n ? (self.treeWidth ??\n clamp(\n this.treeTips.depth * pxPerTreeDepth,\n minTreeWidth,\n maxFitTreeWidth,\n ))\n : 0\n const fit = chrome + tree + this.labelColumnWidth\n const room = self.viewInitialized\n ? this.numColumns > 0\n ? self.width * maxTreeAreaShare\n : self.width - this.rowPanelsWidth - self.resizeHandleWidth\n : Infinity\n const cap = Math.max(room, chrome + Math.min(tree, minTreeWidth))\n return Math.ceil(Math.min(fit, cap))\n },\n /**\n * #getter\n * the width of the area the tree and its labels draw in, px:\n * treeAreaWidth where set, the fit otherwise\n */\n get effectiveTreeAreaWidth() {\n return self.treeAreaWidth ?? this.fittedTreeAreaWidth\n },\n /**\n * #getter\n * the width of the tree, px: treeWidth where set, otherwise the tree\n * area less the label column, which a zoom hiding the labels gives to\n * the tree\n */\n get effectiveTreeWidth() {\n const labels = this.showTreeText ? this.labelColumnWidth : 0\n return (\n self.treeWidth ??\n Math.max(\n minTreeWidth,\n Math.floor(\n this.effectiveTreeAreaWidth -\n self.marginLeft -\n this.cladeGutterWidth -\n labels,\n ),\n )\n )\n },\n /**\n * #getter\n */\n get showTreeText() {\n return self.drawLabels && self.rowHeight >= minLetterRowHeight\n },\n /**\n * #getter\n */\n get mouseOverRowName() {\n const { mouseRow } = self\n return mouseRow === undefined\n ? undefined\n : this.leaves[mouseRow]?.data.name\n },\n /**\n * #getter\n * Returns insertion info if mouse is hovering over an insertion indicator\n */\n get hoveredInsertion() {\n const { mouseCol, mouseRow } = self\n if (mouseCol !== undefined && mouseRow !== undefined) {\n const rowName = this.leaves[mouseRow]?.data.name\n if (rowName) {\n const insertion = this.insertionPositions\n .get(rowName)\n ?.find(ins => ins.pos === mouseCol)\n if (insertion) {\n return { rowName, col: mouseCol, letters: insertion.letters }\n }\n }\n }\n return undefined\n },\n\n /**\n * #getter\n */\n get root() {\n return buildTreeRoot(this.tree, {\n collapsed: self.collapsed,\n rotated: self.rotated,\n order: self.treeOrder,\n showOnly: self.showOnly,\n })\n },\n\n /**\n * #getter\n * the tree as Newick in the order and with the root it is drawn, with\n * every clade, collapsed or out of focus\n */\n get treeNewick() {\n return writeNewick(\n buildTreeRoot(this.tree, {\n collapsed: [],\n rotated: self.rotated,\n order: self.treeOrder,\n }),\n )\n },\n\n /**\n * #getter\n * height of the band the tree overview draws in, zero when it is off\n */\n get treeOverviewHeight() {\n return self.showTreeOverview ? self.overviewHeight : 0\n },\n\n /**\n * #getter\n * the whole tree laid out for the overview, or undefined when the\n * overview is off. The focus is left out, so the focused subtree draws\n * inside the whole tree, and the collapsed clades are folded, since\n * those are rows the view no longer has. `x` is in tip-index space and\n * `len` is a fraction of the root-to-tip length, so one layout serves\n * any band size.\n */\n get treeOverviewLayout() {\n if (!self.showTreeOverview) {\n return undefined\n }\n const layout = layoutTree(\n buildTreeRoot(this.tree, {\n collapsed: self.collapsed,\n rotated: self.rotated,\n order: self.treeOrder,\n }),\n { rowHeight: 1, treeWidth: 1 },\n )\n return {\n root: layout.root,\n numTips: layout.leaves.length,\n maxDepthToLeaf: layout.root.depthToLeaf,\n showBranchLen: self.showBranchLen && layout.rootToTipLength > 0,\n }\n },\n\n /**\n * #getter\n * the `clades` highlights in the overview's own row space, which the\n * focus does not narrow\n */\n get treeOverviewClades(): ResolvedClade[] {\n const layout = this.treeOverviewLayout\n if (!layout || self.clades.length === 0) {\n return noClades\n }\n return resolveClades(\n self.clades,\n hierarchy(this.tree, d => d.children),\n layout.root,\n )\n },\n\n /**\n * #getter\n * the inclusive tip rows the focused subtree covers in the overview,\n * which is the box drawn on it. undefined with no focus\n */\n get treeOverviewFocusRows(): [number, number] | undefined {\n const layout = this.treeOverviewLayout\n if (!layout || !self.showOnly) {\n return undefined\n }\n const node = find(layout.root, n => n.data.id === self.showOnly)\n return node ? tipRange(node) : undefined\n },\n\n /**\n * #method\n * the subtree a point `y` pixels down the tree overview picks: the\n * deepest one whose tip range covers every row under that pixel, with\n * the rows it covers. A pixel stands for several tips on a large tree,\n * which is what keeps the pick off the individual tips. undefined when\n * the overview is off or the point picks the whole tree.\n */\n treeOverviewHit(y: number) {\n const layout = this.treeOverviewLayout\n if (!layout) {\n return undefined\n }\n const { root, numTips } = layout\n const perPixel = numTips / self.overviewHeight\n const first = clamp(Math.floor(y * perPixel), 0, numTips - 1)\n const last = clamp(\n Math.ceil((y + 1) * perPixel) - 1,\n first,\n numTips - 1,\n )\n let node = nodeCoveringRows(root, first + 0.5, last + 0.5)\n // focusing one tip leaves a single row on screen, so the pick lifts to\n // the subtree that tip sits in\n while (!node.children && node.parent) {\n node = node.parent\n }\n return node === root\n ? undefined\n : { id: node.data.id, rows: tipRange(node) }\n },\n\n /**\n * #getter\n * the pixel column the row panels occupy between the tree and the\n * alignment, the sum of each record's width\n */\n get rowPanelsWidth() {\n return sum(self.rowPanels.map(p => rowPanelWidth(p, self)))\n },\n /**\n * #getter\n * height of the band the row panel headers draw in, which is zero with\n * no row panels and leaves the top area as it was\n */\n get rowPanelsHeaderHeight() {\n return self.rowPanels.length > 0 ? rowPanelHeaderHeight : 0\n },\n /**\n * #getter\n * widget width minus the tree area and the row panels gives the space\n * for the MSA\n */\n get msaAreaWidth() {\n return (\n self.width -\n this.effectiveTreeAreaWidth -\n this.rowPanelsWidth -\n self.resizeHandleWidth\n )\n },\n\n /**\n * #getter\n * the right edge the tip labels end at, which is the tree area less the\n * margin and the bracket gutter\n */\n get treeAreaWidthMinusMargin() {\n return (\n this.effectiveTreeAreaWidth - self.marginLeft - this.cladeGutterWidth\n )\n },\n /**\n * #getter\n */\n get blanks() {\n const { hideGapsEffective, allowedGappyness } = self\n if (!hideGapsEffective) {\n return []\n }\n const strs = this.leaves\n .map(leaf => this.MSA?.getRow(leaf.data.name))\n .filter(notEmpty)\n if (strs.length === 0) {\n return []\n }\n // ragged input (a3m, hand-edited fasta) can have rows shorter than the\n // alignment; the widest row of the whole alignment, collapsed rows\n // included, defines the column count as it does for numColumns, and a\n // row that stops early counts as gapped for the remainder\n const numCols = this.MSA?.getWidth() ?? 0\n const numRows = strs.length\n const threshold = Math.ceil((allowedGappyness / 100) * numRows)\n const blankCounts = new Uint32Array(numCols)\n for (let j = 0; j < numRows; j++) {\n const str = strs[j]!\n const len = str.length\n for (let i = 0; i < numCols; i++) {\n // bit trick: (code - 45) >>> 0 <= 1 checks for '-' (45) or '.' (46)\n if (i >= len || (str.charCodeAt(i) - 45) >>> 0 <= 1) {\n blankCounts[i]!++\n }\n }\n }\n const blanks = []\n for (let i = 0; i < numCols; i++) {\n if (blankCounts[i]! >= threshold) {\n blanks.push(i)\n }\n }\n return blanks\n },\n /**\n * #getter\n * Returns a map of row name to array of insertions with display position and letters\n */\n get insertionPositions() {\n const { blanks, rows } = this\n if (blanks.length === 0) {\n return new Map<string, { pos: number; letters: string }[]>()\n }\n const result = new Map<string, { pos: number; letters: string }[]>()\n for (const [name, seq] of rows) {\n const insertions = computeRowInsertions(blanks, seq)\n if (insertions.length > 0) {\n result.set(name, insertions)\n }\n }\n return result\n },\n /**\n * #getter\n */\n get rows() {\n const MSA = this.MSA\n return this.leaves\n .map(leaf => [leaf.data.name, MSA?.getRow(leaf.data.name)] as const)\n .filter((f): f is [string, string] => !!f[1])\n },\n /**\n * #getter\n * number of rows on screen: the leaf count, which includes tree leaves\n * with no matching MSA row (drawn blank), unlike `rows.length`.\n */\n get numRows() {\n return this.leaves.length\n },\n\n /**\n * #method\n * index of the global column holding each ungapped sequence position of a\n * row. The domain overlay resolves thousands of these per redraw. Built\n * lazily per row and cached on the parse.\n */\n seqPosIndex(rowName: string): Int32Array | undefined {\n const MSA = this.MSA\n if (!MSA) {\n return undefined\n }\n let cache = seqPosIndexCache.get(MSA)\n if (!cache) {\n cache = new Map()\n seqPosIndexCache.set(MSA, cache)\n }\n let index = cache.get(rowName)\n if (!index) {\n const seq = MSA.getRow(rowName)\n if (!seq) {\n return undefined\n }\n index = buildSeqPosIndex(seq)\n cache.set(rowName, index)\n }\n return index\n },\n\n /**\n * #method\n * the row's aligned sequence by the name the tree gives it, including\n * rows a collapsed clade hides. `MSA.getRow` resolves a FASTA name whose\n * colon a Newick tool wrote as an underscore, which `rowMap` does not\n */\n rowSequence(name: string) {\n return this.MSA?.getRow(name) || undefined\n },\n /**\n * #getter\n * every sequence in the alignment, keyed by the alignment's own row\n * names, including rows a collapsed clade hides\n */\n get rowMap() {\n const MSA = this.MSA\n return new Map(\n MSA?.getNames()\n .map(name => [name, MSA.getRow(name)] as const)\n .filter(([, seq]) => !!seq),\n )\n },\n /**\n * #getter\n */\n get columns() {\n const columns2d = this.columns2d\n return new Map(\n this.rows.map((row, index) => [row[0], columns2d[index]!] as const),\n )\n },\n /**\n * #getter\n */\n get columns2d() {\n const { hideGapsEffective } = self\n return this.rows.map(([, str]) =>\n (hideGapsEffective\n ? skipBlanks(this.blanks, str)\n : str\n ).toUpperCase(),\n )\n },\n /**\n * #getter\n */\n get fontSize() {\n return fontSizeFor(self.rowHeight)\n },\n /**\n * #getter\n */\n get colStats() {\n return columnCountsFromRows(this.columns2d, this.numColumns)\n },\n\n /**\n * #getter\n * Detects sequence type based on letters present in the alignment.\n * Returns 'dna', 'rna', or 'amino'.\n */\n get sequenceType(): 'dna' | 'rna' | 'amino' {\n const letters = this.colStats.lettersPresent\n // the two-base IUPAC codes keep an ambiguous read nucleotide; the\n // three-base ones (B, D, H, V) are common amino acids, so they don't\n const ambiguous = ['N', 'R', 'Y', 'K', 'M', 'S', 'W']\n const dna = new Set(['A', 'C', 'G', 'T', ...ambiguous])\n const rna = new Set(['A', 'C', 'G', 'U', ...ambiguous])\n const isDna = letters.size > 0 && [...letters].every(l => dna.has(l))\n const isRna = letters.size > 0 && [...letters].every(l => rna.has(l))\n return isDna ? 'dna' : isRna ? 'rna' : 'amino'\n },\n\n /**\n * #getter\n * Pre-computed consensus letter and percent identity color per column.\n * Used by percent_identity_dynamic color scheme.\n */\n get colConsensus() {\n const { colStats } = this\n return Array.from({ length: colStats.numColumns }, (_, col) => {\n const total = colStats.total(col)\n let maxCount = 0\n let letter = ''\n colStats.forEachResidue(col, (slot, count) => {\n if (count > maxCount) {\n maxCount = count\n letter = letterOfResidueSlot(slot)\n }\n })\n const proportion = total ? maxCount / total : 0\n return {\n letter,\n color:\n proportion > 0.4\n ? `hsl(240, 30%, ${100 * Math.max(1 - proportion / 3, 0.3)}%)`\n : undefined,\n }\n })\n },\n\n /**\n * #getter\n * Pre-computed ClustalX colors per column.\n * Returns a map of letter -> color for each column.\n * ref http://www.jalview.org/help/html/colourSchemes/clustal.html\n */\n get colClustalX() {\n const { colStats } = this\n return Array.from({ length: colStats.numColumns }, (_, col) =>\n clustalXColumnColors(colStats, col),\n )\n },\n\n /**\n * #getter\n * Conservation score per column using Shannon entropy (biojs-msa style).\n * Conservation = (1 - H/Hmax) * (1 - gapFraction)\n * Returns values 0-1 where 1 = fully conserved, 0 = no conservation.\n */\n get conservation() {\n const { colStats, alphabetMaxBits } = this\n return Array.from({ length: colStats.numColumns }, (_, col) => {\n const total = colStats.total(col)\n const gapCount = colStats.gapCount(col)\n return total > gapCount\n ? Math.max(0, 1 - colStats.entropy(col) / alphabetMaxBits) *\n (1 - gapCount / total)\n : 0\n })\n },\n /**\n * #getter\n * The information content of a fully conserved column, in bits, which\n * depends on the alphabet. Both the entropy ceiling `conservation`\n * normalizes against and the y-axis ceiling of the sequence logo track.\n */\n get alphabetMaxBits() {\n return maxBitsFor(this.sequenceType)\n },\n /**\n * #getter\n * Per-column conservation of physicochemical property class (amino acids\n * only). Surfaces conservative-substitution sites that identity-based\n * conservation misses. Empty for nucleotide alignments.\n */\n get propertyConservation() {\n return this.sequenceType === 'amino'\n ? calculatePropertyConservation(this.colStats)\n : []\n },\n /**\n * #getter\n * `root` laid out on new nodes in row and branch-length units, read in\n * pixels through `rowHeight` and `effectiveTreeWidth`. A zoom leaves it\n * and every node in it as they are, and an observer reading a node's `x`\n * or `len` observes the size it scales by.\n */\n get treeLayout() {\n const treeWidth = () => this.effectiveTreeWidth\n return layoutTree(this.root, {\n get rowHeight() {\n return self.rowHeight\n },\n get treeWidth() {\n return treeWidth()\n },\n })\n },\n\n /**\n * #getter\n * the laid-out tree, with pixel positions on every node\n */\n get hierarchy(): HierarchyNode<NodeWithIds> {\n return this.treeLayout.root\n },\n\n /**\n * #getter\n */\n get totalHeight() {\n return this.leaves.length * self.rowHeight\n },\n\n /**\n * #getter\n */\n get leaves(): HierarchyNode<NodeWithIds>[] {\n return this.treeLayout.leaves\n },\n\n /**\n * #getter\n * branch-length extent of the displayed tree, root to farthest tip, in\n * the tree's own units\n */\n get rootToTipLength() {\n return this.treeLayout.rootToTipLength\n },\n\n /**\n * #getter\n * pixels per unit of branch length in the phylogram layout, 0 in\n * cladogram mode. The tree's scale bar uses it.\n */\n get pxPerBranchLength() {\n const max = this.rootToTipLength\n return this.showBranchLenEffective && max\n ? this.effectiveTreeWidth / max\n : 0\n },\n\n /**\n * #getter\n * max topological depth to a tip, used to scale cladogram x-positions\n */\n get maxDepthToLeaf() {\n return this.treeLayout.root.depthToLeaf\n },\n\n /**\n * #getter\n */\n get allBranchesLength0() {\n return this.rootToTipLength === 0\n },\n\n /**\n * #getter\n * effective showBranchLen accounting for allBranchesLength0\n */\n get showBranchLenEffective() {\n return this.allBranchesLength0 ? false : self.showBranchLen\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get totalWidth() {\n return self.numColumns * self.colWidth\n },\n }))\n\n .views(self => ({\n /**\n * #getter\n */\n get showMsaLetters() {\n return (\n self.drawMsaLetters &&\n self.rowHeight >= minLetterRowHeight &&\n self.colWidth >= minLetterColWidth &&\n self.colWidth > self.rowHeight / 2\n )\n },\n }))\n .views(self => {\n // a spec is a frozen value, so it keys its computed until setColumnTracks\n // replaces it\n const columnTrackModels = new WeakMap<\n ColumnTrackSpec,\n IComputedValue<BasicTrack>\n >()\n return {\n /**\n * #getter\n * a data track's values or string, projected from its row's residues\n * onto alignment columns when it names a row\n */\n get columnTrackContent() {\n const { MSA, blanks, hideGapsEffective } = self\n const width = MSA?.getWidth() ?? 0\n const project = <T>(track: ColumnTrackSpec, items: T[], fill: T) => {\n if (!track.row) {\n return items\n }\n const out = Array.from({ length: width }, () => fill)\n const index = self.seqPosIndex(track.row)\n items.forEach((item, seqPos) => {\n const col = index?.[seqPos]\n if (col !== undefined) {\n out[col] = item\n }\n })\n return out\n }\n const skip = <T>(items: T[]) =>\n hideGapsEffective ? dropBlanks(blanks, items) : items\n // an arc endpoint maps row residue -> column -> visible column.\n // visibleColsBefore, not globalColToVisibleCol, so an endpoint in a\n // hidden column moves to the neighboring visible one and the arc stays\n const resolve = (track: ColumnTrackSpec, pos: number) => {\n const col = track.row\n ? self.seqPosIndex(track.row)?.[pos - 1]\n : pos - 1\n if (col === undefined || col < 0 || col >= width) {\n return undefined\n }\n return hideGapsEffective ? visibleColsBefore(blanks, col) : col\n }\n return new Map<\n string,\n { values?: number[]; data?: string; arcs?: Arc[] }\n >(\n self.columnTracks.map(track => {\n if (track.kind === 'arc') {\n const arcs = (track.arcs ?? [])\n .map(arc => {\n const start = resolve(track, Math.min(arc.start, arc.end))\n const end = resolve(track, Math.max(arc.start, arc.end))\n return start !== undefined &&\n end !== undefined &&\n start < end\n ? { start, end, color: arc.color }\n : undefined\n })\n .filter(notEmpty)\n return [track.id, { arcs }] as const\n }\n if (track.kind === 'bar') {\n const max = track.max ?? 1\n const values = skip(project(track, track.values ?? [], 0)).map(\n v => Math.min(1, Math.max(0, v / max)),\n )\n return [track.id, { values }] as const\n }\n const data = skip(\n project(track, (track.data ?? '').split(''), ' '),\n )\n return [track.id, { data: data.join('') }] as const\n }),\n )\n },\n /**\n * #method\n * the height a track draws at: what the user dragged its divider to,\n * then the height its snapshot asked for, then its kind's default. Only\n * a text track falls through to rowHeight\n */\n trackHeight(kind: TrackKind, heightKey: string = kind, given?: number) {\n return (\n self.trackHeights.get(heightKey) ??\n given ??\n defaultTrackHeights[kind] ??\n self.rowHeight\n )\n },\n /**\n * #method\n * the track a column track spec draws as, computed once per spec. A\n * text track's height falls through to rowHeight, and its own computed\n * confines the vertical zoom to it, so a sibling keeps its object and\n * its canvas skips the redraw\n */\n columnTrackModel(track: ColumnTrackSpec): BasicTrack {\n let computedModel = columnTrackModels.get(track)\n if (!computedModel) {\n computedModel = computed(() => {\n const heightKey = resizableKinds.has(track.kind)\n ? ownHeightKey(track.id)\n : undefined\n const content = this.columnTrackContent.get(track.id)\n return {\n model: {\n id: track.id,\n name: track.name,\n kind: track.kind,\n heightKey,\n height: this.trackHeight(track.kind, heightKey, track.height),\n barColor: track.color,\n arcColor: track.color,\n customColorScheme: track.colors,\n data: content?.data,\n arcs: content?.arcs,\n },\n }\n })\n columnTrackModels.set(track, computedModel)\n }\n return computedModel.get()\n },\n /**\n * #getter\n */\n get columnTrackModels(): BasicTrack[] {\n return self.columnTracks.map(track => this.columnTrackModel(track))\n },\n }\n })\n .views(self => ({\n /**\n * #getter\n */\n get secondaryStructureConsensus() {\n return self.MSA?.secondaryStructureConsensus\n },\n\n /**\n * #getter\n * the base pairs of the consensus secondary structure, as arcs, in\n * visible column space (hidden columns are removed before parsing)\n */\n get secondaryStructureArcs(): Arc[] | undefined {\n const { blanks, hideGapsEffective } = self\n const ss = this.secondaryStructureConsensus\n if (!ss) {\n return undefined\n }\n return parseWuss(hideGapsEffective ? skipBlanks(blanks, ss) : ss).map(\n ({ start, end, pseudoknot }) => ({\n start,\n end,\n color: pseudoknot ? PSEUDOKNOT_ARC : HELIX_ARC,\n }),\n )\n },\n\n /**\n * #getter\n */\n get adapterTrackModels(): BasicTrack[] {\n const { MSA, hideGapsEffective, blanks } = self\n const tracks = (MSA?.tracks ?? []).filter(t => !!t.data)\n if (tracks.length === 0) {\n // return before reading rowHeight, so zooming does not rebuild the\n // list and redraw every track canvas\n return []\n }\n const { rowHeight } = self\n return tracks.map(t => ({\n model: {\n ...t,\n kind: 'text' as const,\n data: hideGapsEffective ? skipBlanks(blanks, t.data!) : t.data,\n height: rowHeight,\n },\n }))\n },\n\n /**\n * #getter\n * the consensus secondary structure as a track, when there is one. A\n * separate getter keeps the object stable across zoom, so its canvas\n * does not redraw\n */\n get basePairTrackModels(): BasicTrack[] {\n const arcs = this.secondaryStructureArcs\n return arcs?.length\n ? [\n {\n model: {\n id: 'base-pairs',\n name: 'Base pairs',\n kind: 'arc' as const,\n heightKey: 'arc',\n height: self.trackHeight('arc'),\n arcs,\n },\n },\n ]\n : []\n },\n\n /**\n * #getter\n * the tracks computed from the alignment; they depend on their heights\n * and the alphabet, not on zoom\n */\n get computedTrackModels(): BasicTrack[] {\n return [\n {\n id: 'conservation',\n name: 'Conservation',\n kind: 'bar' as const,\n barColor: 'gray',\n },\n ...(self.sequenceType === 'amino'\n ? [\n {\n id: 'property-conservation',\n name: 'Property conservation',\n kind: 'bar' as const,\n barColor: '#6a51a3',\n },\n ]\n : []),\n {\n id: 'sequence-logo',\n name: 'Sequence logo',\n kind: 'logo' as const,\n },\n // last, so it sits against the alignment it numbers\n {\n id: 'position-ruler',\n name: 'Position',\n kind: 'ruler' as const,\n },\n ].map(model => ({\n // every computed track of a kind shares that kind's height, so the\n // kind is its key\n model: {\n ...model,\n heightKey: resizableKinds.has(model.kind) ? model.kind : undefined,\n height: self.trackHeight(model.kind),\n },\n }))\n },\n\n get tracks(): BasicTrack[] {\n return [\n ...this.adapterTrackModels,\n ...this.basePairTrackModels,\n ...self.columnTrackModels,\n // every computed track reads the alignment's columns, and a tree, a\n // GFF and a features panel draw a figure with none\n ...(self.numColumns > 0 ? this.computedTrackModels : []),\n ]\n },\n\n /**\n * #getter\n */\n get turnedOnTracks() {\n return this.tracks.filter(\n f =>\n !trackIsOff(self.turnedOffTracks, f.model.id, f.model.defaultOff),\n )\n },\n\n /**\n * #getter\n */\n get showHorizontalScrollbar() {\n return overflows(self.totalWidth, self.msaAreaWidth)\n },\n\n /**\n * #method\n * Return the character a row holds at a visible column: a residue, or\n * the gap character (`-` or `.`) on a gap. Undefined for a row name the\n * alignment does not have or a column past the row's end.\n *\n * @param rowName - The name of the row\n * @param visibleCol - The visible column index (what the user sees on screen)\n * @returns The character at that position\n */\n visibleColToRowLetter(rowName: string, visibleCol: number) {\n return self.rowSequence(rowName)?.[\n this.visibleColToGlobalCol(visibleCol)\n ]\n },\n\n /**\n * #method\n * Convert a visible column to a row-specific sequence position (0-based).\n * Returns undefined if the position is a gap in the sequence.\n *\n * Public API, like the sibling converters (visibleColToGlobalCol,\n * seqPosToVisibleCol, globalColToVisibleCol, seqPosToGlobalCol) hosts\n * use to translate between columns and residue positions. Keep them\n * stable.\n *\n * @param rowName - The name of the row\n * @param visibleCol - The visible column index\n * @returns The sequence position (0-based), or undefined if it's a gap\n */\n visibleColToSeqPos(rowName: string, visibleCol: number) {\n // binary search: this runs on every mouse move, and scanning a\n // 30k-column row per event takes the whole frame\n return seqPosOfGlobalCol(\n self.seqPosIndex(rowName),\n this.visibleColToGlobalCol(visibleCol),\n )\n },\n\n /**\n * #method\n * Convert a visible column to a row-specific sequence position (1-based).\n * Returns undefined if the position is a gap in the sequence.\n *\n * @param rowName - The name of the row\n * @param visibleCol - The visible column index\n * @returns The sequence position (1-based), or undefined if it's a gap\n */\n visibleColToSeqPosOneBased(rowName: string, visibleCol: number) {\n const val = this.visibleColToSeqPos(rowName, visibleCol)\n return val !== undefined ? val + 1 : undefined\n },\n\n /**\n * #method\n * Convert a global column index to a visible column index.\n * Returns undefined if the column is hidden (in blanks).\n * This is the inverse of visibleColToGlobalCol.\n *\n * @param globalCol - The global column index in the full MSA\n * @returns The visible column index, or undefined if the column is hidden\n */\n globalColToVisibleCol(globalCol: number) {\n const { blanks, hideGapsEffective } = self\n if (!hideGapsEffective) {\n return globalCol\n }\n return globalColToVisibleCol(blanks, globalCol)\n },\n\n /**\n * #method\n * Convert a visible column index (what a mouse handler reports) to a\n * column of the full alignment. A host indexing its own per-column data\n * needs this when columns are hidden.\n *\n * @param visibleCol - The visible column index\n * @returns The global column index in the full MSA\n */\n visibleColToGlobalCol(visibleCol: number) {\n const { blanks, hideGapsEffective } = self\n return hideGapsEffective\n ? visibleColToGlobalCol(blanks, visibleCol)\n : visibleCol\n },\n\n /**\n * #method\n * Convert a sequence position (ungapped) to a global column index.\n * Returns undefined for a row name the alignment does not have.\n *\n * @param rowName - The name of the row\n * @param seqPos - The sequence position (0-based, ungapped)\n * @returns The global column index in the full MSA, or undefined\n */\n seqPosToGlobalCol(rowName: string, seqPos: number) {\n const seq = self.rowSequence(rowName)\n if (seq === undefined) {\n return undefined\n }\n const col = self.seqPosIndex(rowName)?.[seqPos]\n // past the end of the ungapped sequence: 0 for the degenerate all-gap\n // row, otherwise one past the last column\n return col ?? (seqPos === 0 ? 0 : seq.length)\n },\n\n /**\n * #method\n * the global column of a span's last residue, clamping a position past\n * the end of the row to its last residue. Undefined for a row name the\n * alignment does not have, or a row with no residues.\n *\n * @param rowName - The name of the row\n * @param seqPos - The sequence position (0-based, ungapped)\n */\n seqEndToGlobalCol(rowName: string, seqPos: number) {\n const index = self.seqPosIndex(rowName)\n return index && index.length > 0\n ? index[Math.min(seqPos, index.length - 1)]\n : undefined\n },\n\n /**\n * #method\n * Convert a sequence position (ungapped) directly to a visible column index.\n * This combines seqPosToGlobalCol and globalColToVisibleCol.\n *\n * @param rowName - The name of the row\n * @param seqPos - The sequence position (0-based, ungapped)\n * @returns The visible column index, or undefined if the column is hidden\n */\n seqPosToVisibleCol(rowName: string, seqPos: number) {\n const globalCol = this.seqPosToGlobalCol(rowName, seqPos)\n return globalCol === undefined\n ? undefined\n : this.globalColToVisibleCol(globalCol)\n },\n\n /**\n * #method\n * the visible columns a span covers, in highlight coordinates: `start`\n * and `end` are 1-based residues of `row`, or columns of the file\n * without it. A fractional position, as a zoom gesture reports one,\n * widens to the whole residue or column it falls in. A span entirely on\n * hidden columns, or naming a row the alignment lacks, gives undefined.\n */\n visibleSpan({ row, start: rawStart, end: rawEnd }: Region) {\n const { blanks } = self\n const start = Math.max(1, Math.floor(rawStart))\n const end = Math.ceil(rawEnd)\n let startGlobal = start - 1\n let endGlobal = Math.min(end, self.MSA?.getWidth() ?? end) - 1\n if (row !== undefined) {\n const rowStart = this.seqPosToGlobalCol(row, start - 1)\n const rowEnd = this.seqEndToGlobalCol(row, end - 1)\n if (rowStart === undefined || rowEnd === undefined) {\n return undefined\n }\n startGlobal = rowStart\n endGlobal = rowEnd\n }\n const startCol =\n this.globalColToVisibleCol(startGlobal) ??\n visibleColsBefore(blanks, startGlobal)\n const endCol =\n this.globalColToVisibleCol(endGlobal) ??\n visibleColsBefore(blanks, endGlobal) - 1\n return startCol <= endCol ? { startCol, endCol } : undefined\n },\n\n /**\n * #getter\n * why each ignored residue mapping is ignored, so a host can tell a\n * missing structure from a mapping made against a different alignment.\n */\n get residueMappingProblems(): ResidueMappingProblem[] {\n const problems: ResidueMappingProblem[] = []\n for (const mapping of self.residueMappings) {\n const where = { row: mapping.row, structureId: mapping.structure.id }\n const residues = self.seqPosIndex(mapping.row)?.length\n if (residues === undefined) {\n problems.push({\n ...where,\n scope: 'mapping',\n reason: 'no such row in the alignment',\n })\n continue\n }\n if (\n mapping.rowLength !== undefined &&\n mapping.rowLength !== residues\n ) {\n problems.push({\n ...where,\n scope: 'mapping',\n reason: `computed against a ${mapping.rowLength}-residue row; this one has ${residues}`,\n })\n continue\n }\n const overrun = mapping.segments.find(\n segment => segment.rowEnd > residues || segment.rowStart < 1,\n )\n if (overrun) {\n problems.push({\n ...where,\n scope: 'mapping',\n reason: `segment ${overrun.rowStart}-${overrun.rowEnd} does not fit a ${residues}-residue row`,\n })\n continue\n }\n for (const segment of mapping.segments) {\n if (!sameLength(segment)) {\n problems.push({\n ...where,\n scope: 'segment',\n reason: `segment ${segment.rowStart}-${segment.rowEnd} maps to ${segment.structStart}-${segment.structEnd}, which is a different length`,\n })\n }\n }\n }\n return problems\n },\n\n /**\n * #getter\n * the mappings that fit the loaded alignment. A row-level problem drops\n * the whole mapping; a malformed segment drops only that segment.\n */\n get usableResidueMappings(): ResidueMapping[] {\n const unusable = new Set(\n this.residueMappingProblems\n .filter(problem => problem.scope === 'mapping')\n .map(problem => `${problem.row}\\u0000${problem.structureId}`),\n )\n return self.residueMappings\n .filter(m => !unusable.has(`${m.row}\\u0000${m.structure.id}`))\n .map(m => ({\n ...m,\n segments: m.segments.filter(sameLength),\n }))\n },\n\n /**\n * #getter\n * the structures with usable mappings. A row can map onto several, such\n * as an experimental entry and a predicted model.\n */\n get mappedStructures() {\n return this.usableResidueMappings.map(m => ({\n row: m.row,\n structure: m.structure,\n }))\n },\n\n /**\n * #method\n * The structure residue for a row residue. Returns undefined when no\n * segment covers `seqPos`, or when the row maps onto several structures\n * and `structureId` does not pick one (see `mappedStructures`).\n *\n * Positions are 1-based, like `residueMappings` and `highlights`; the\n * column helpers above are 0-based.\n *\n * @param rowName - The alignment row\n * @param seqPos - Residue of that row, 1-based\n * @param structureId - Which structure, when the row maps onto several\n */\n structureResidue(\n rowName: string,\n seqPos: number,\n structureId?: string,\n ): StructureResidue | undefined {\n const hits: StructureResidue[] = []\n for (const mapping of this.usableResidueMappings) {\n if (mapping.row !== rowName) {\n continue\n }\n if (\n structureId !== undefined &&\n mapping.structure.id !== structureId\n ) {\n continue\n }\n const segment = mapping.segments.find(\n seg => seqPos >= seg.rowStart && seqPos <= seg.rowEnd,\n )\n if (segment) {\n const position = segment.structStart + (seqPos - segment.rowStart)\n hits.push({\n structure: mapping.structure,\n position,\n observed: !inRanges(mapping.unobserved, position),\n })\n }\n }\n return hits.length === 1 ? hits[0] : undefined\n },\n\n /**\n * #method\n * The row residue for a structure residue; the inverse of\n * `structureResidue`, returning undefined in the same cases. `asymId`\n * picks a chain when several mappings share an entry id, as in a\n * homodimer.\n *\n * @param structureId - The structure's id, as the mapping names it\n * @param position - Residue of that structure, 1-based label_seq_id\n * @param asymId - Which chain, when the id alone is ambiguous\n */\n rowResidue(\n structureId: string,\n position: number,\n asymId?: string,\n ): RowResidue | undefined {\n const hits: RowResidue[] = []\n for (const mapping of this.usableResidueMappings) {\n if (mapping.structure.id !== structureId) {\n continue\n }\n if (asymId !== undefined && mapping.structure.asymId !== asymId) {\n continue\n }\n const segment = mapping.segments.find(\n seg => position >= seg.structStart && position <= seg.structEnd,\n )\n if (segment) {\n hits.push({\n rowName: mapping.row,\n seqPos: segment.rowStart + (position - segment.structStart),\n })\n }\n }\n return hits.length === 1 ? hits[0] : undefined\n },\n }))\n\n .views(self => ({\n /**\n * #getter\n * the branch-length scale bar over the tree, undefined in cladogram mode\n * or when the tree area is too narrow for one\n */\n get treeScaleBar() {\n return scaleBarLength(\n self.pxPerBranchLength,\n self.effectiveTreeAreaWidth - self.marginLeft * 2,\n )\n },\n /**\n * #getter\n * the band across the top: the minimap over the alignment, the row panel\n * headers, and the tree overview stacked on the scale bar, as tall as the\n * tallest of the three\n */\n get topBandHeight() {\n return Math.max(\n self.showHorizontalScrollbar ? self.minimapHeight : 0,\n self.rowPanelsHeaderHeight,\n self.treeOverviewHeight +\n (this.treeScaleBar ? treeScaleBarHeight : 0),\n )\n },\n /**\n * #getter\n * the vertical space for alignment rows: the widget height less the\n * header, the top band and the tracks. Shared by blocksY, maxScrollY, the\n * vertical scrollbar and fitVertically.\n */\n get msaAreaHeight() {\n return (\n self.height -\n this.topBandHeight -\n self.headerHeight -\n this.totalTrackAreaHeight\n )\n },\n /**\n * #getter\n * total height of track area (px)\n */\n get totalTrackAreaHeight() {\n return sum(self.turnedOnTracks.map(r => r.model.height))\n },\n /**\n * one representative annotation per accession, for the legend, the\n * filter dialog and the palettes\n */\n get annotationTypes() {\n // first occurrence wins; only name, description and segment start are\n // read from it\n const types = new Map<string, Annotation>()\n for (const annot of self.allAnnotations) {\n if (!types.has(annot.accession)) {\n types.set(annot.accession, annot)\n }\n }\n return types\n },\n get filteredAnnotations() {\n return self.allAnnotations.filter(\n r => !self.turnedOffFeatures.get(r.accession),\n )\n },\n get annotationsByRow() {\n const { rowNamesSet } = self\n return groupBy(this.filteredAnnotations, r =>\n annotationRowName(r.id, rowNamesSet),\n )\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get showVerticalScrollbar() {\n return overflows(self.totalHeight, self.msaAreaHeight)\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get dataInitialized() {\n // truthiness, not `!== ''`: DataModel drops an inline document over\n // 50kb from the snapshot, so a restored session can hold `undefined`\n return !!(self.data.msa || self.data.tree) && !self.error\n },\n /**\n * #getter\n */\n get blocksX() {\n return calculateBlocks({\n viewportSize: self.msaAreaWidth,\n viewportPos: -self.scrollX,\n blockSize: self.blockSize,\n mapSize: self.totalWidth,\n })\n },\n /**\n * #getter\n */\n get blocksY() {\n return calculateBlocks({\n viewportSize: self.msaAreaHeight,\n viewportPos: -self.scrollY,\n blockSize: self.blockSize,\n mapSize: self.totalHeight,\n })\n },\n }))\n .views(self => ({\n /**\n * #getter\n */\n get verticalScrollbarWidth() {\n return self.showVerticalScrollbar ? 20 : 0\n },\n /**\n * #getter\n * width of the alignment canvas: the msa area less the vertical\n * scrollbar. showHorizontalScrollbar must not read it, since that feeds\n * msaAreaHeight -> showVerticalScrollbar and would form a cycle\n */\n get msaCanvasWidth() {\n return self.msaAreaWidth - this.verticalScrollbarWidth\n },\n /**\n * #getter\n * most-negative allowed scrollX, which keeps the last column in view\n */\n get maxScrollX() {\n return Math.min(-self.totalWidth + this.msaCanvasWidth, 0)\n },\n /**\n * #getter\n */\n get blocks2d() {\n return self.blocksY.flatMap(by =>\n self.blocksX.map(bx => [bx, by] as const),\n )\n },\n\n /**\n * #getter\n */\n get isLoading() {\n return self.loadingMSA || self.loadingTree\n },\n /**\n * #getter\n * warnings that follow from the loaded data and clear when it changes. A\n * GFF whose first column names rows of some other alignment parses\n * without error and draws nothing\n */\n get dataWarnings(): string[] {\n const { annotations, rowNamesSet } = self\n return self.dataInitialized &&\n annotations.length > 0 &&\n !annotations.some(a =>\n rowNamesSet.has(annotationRowName(a.id, rowNamesSet)),\n )\n ? [\n `0 of ${annotations.length} annotations name a row in this alignment`,\n ]\n : []\n },\n /**\n * #getter\n * the load warnings and the undismissed data warnings, for the header\n */\n get warnings(): string[] {\n return [\n ...self.loadWarnings,\n ...this.dataWarnings.filter(w => !self.dismissedWarnings.includes(w)),\n ]\n },\n /**\n * #getter\n * most-negative allowed scrollY, which keeps the last row in view\n */\n get maxScrollY() {\n return Math.min(-self.totalHeight + self.msaAreaHeight, 0)\n },\n /**\n * #getter\n * axis a wheel zoom scales, for ctrl+wheel as much as for scroll-zoom.\n * With scroll-zoom off the toolbar shows no axis, so ctrl+wheel takes\n * both.\n */\n get wheelZoomAxis(): ScrollZoomAxis {\n return self.scrollZoom ? self.scrollZoomAxis : 'both'\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n setDrawMsaLetters(arg: boolean) {\n self.drawMsaLetters = arg\n },\n\n /**\n * #action\n */\n clearWarnings() {\n self.loadWarnings = []\n self.dismissedWarnings = self.dataWarnings\n },\n\n /**\n * #action\n */\n setScrollZoom(arg: boolean) {\n self.scrollZoom = arg\n },\n\n /**\n * #action\n */\n setScrollZoomAxis(arg: ScrollZoomAxis) {\n self.scrollZoomAxis = arg\n },\n\n /**\n * #action\n * set hovered tree node and its descendants\n */\n setHoveredTreeNode(nodeId?: string) {\n // called on every tree mousemove; `find` walks the whole hierarchy and a\n // new object redraws the tree and MSA overlays\n if (nodeId === self.hoveredTreeNode?.nodeId) {\n return\n }\n if (!nodeId) {\n self.hoveredTreeNode = undefined\n return\n }\n const node = find(self.hierarchy, n => n.data.id === nodeId)\n self.hoveredTreeNode = node\n ? {\n nodeId,\n descendantNames: leaves(node).map(leaf => leaf.data.name),\n }\n : undefined\n },\n\n /**\n * #action\n * Calculate a neighbor joining tree from the current MSA using BLOSUM62\n * distances. Throws above `maxNeighborJoiningRows`: the join loop is\n * cubic and runs on the main thread, and 800 rows freeze the tab for ten\n * seconds with no cancel.\n */\n calculateNeighborJoiningTreeFromMSA() {\n // every sequence, including rows in collapsed clades\n const rows = [...self.rowMap]\n if (rows.length < 2) {\n throw new Error('Need at least 2 sequences to build a tree')\n }\n if (rows.length > maxNeighborJoiningRows) {\n throw new Error(\n `Neighbor joining here is capped at ${maxNeighborJoiningRows} sequences and this alignment has ${rows.length}. Build the tree with FastTree or IQ-TREE and open it alongside the alignment: https://gmod.org/JBrowseMSA/tutorials/protein_family`,\n )\n }\n this.replaceTree(calculateNeighborJoiningTree(rows))\n },\n\n /**\n * #action\n * root the tree on the branch above the given node. The node's tips are\n * a split of the unrooted tree, and the side of it that is a clade in\n * the tree as written stands for it as an outgroup, by its first and\n * last tip, so the root survives the path ids changing under it\n */\n rerootAt(nodeId: string) {\n const shown = find(\n hierarchy(self.tree, d => d.children),\n n => n.data.id === nodeId,\n )\n if (!shown?.parent) {\n return\n }\n const node = outgroupNode(\n hierarchy(self.inputTree, d => d.children),\n leaves(shown).map(n => n.data.name),\n )\n if (node) {\n const tips = leaves(node)\n self.setTreeRoot({\n outgroup: [\n ...new Set([tips[0]!.data.name, tips.at(-1)!.data.name]),\n ],\n })\n }\n },\n\n /**\n * #action\n * swap in a different tree over the same alignment. Clears `collapsed`,\n * `rotated` and `showOnly`, since path-derived node ids (node-0-0-1) from the old\n * tree would match unrelated nodes in the new one, and the tree's\n * filehandle, which the snapshot would otherwise reopen in place of\n * the new tree\n */\n replaceTree(newick: string) {\n transaction(() => {\n self.setTreeFilehandle(undefined)\n self.collapsed.clear()\n self.rotated.clear()\n self.setShowOnly(undefined)\n self.setTree(newick)\n })\n },\n\n /**\n * #action\n * restore the default column width and row height\n */\n resetZoom() {\n self.setColWidth(defaultColWidth)\n self.setRowHeight(defaultRowHeight)\n },\n /**\n * #action\n * zoom by `scaleFactor` about the center of the alignment area\n */\n zoomAtCenter(scaleFactor: number, axis: ScrollZoomAxis = 'both') {\n this.zoomToPos(\n scaleFactor,\n self.msaCanvasWidth / 2,\n self.msaAreaHeight / 2,\n axis,\n )\n },\n /**\n * #action\n */\n zoomIn() {\n this.zoomAtCenter(1.5)\n },\n /**\n * #action\n */\n zoomOut() {\n this.zoomAtCenter(0.75)\n },\n /**\n * #action\n * Smoothly zoom by a continuous scaleFactor. The column under the cursor\n * (offsetX/offsetY, px relative to the MSA area) stays anchored\n * horizontally. Vertically the anchor is biased toward y=0 when the\n * alignment nearly fits the viewport, fading to cursor-anchoring as the\n * alignment grows taller than the viewport.\n * Drives wheel/trackpad-pinch zoom. `axis` holds one cell dimension\n * fixed; the held axis still re-anchors its scroll offset, since the\n * other one can change how much of the alignment fits.\n */\n zoomToPos(\n scaleFactor: number,\n offsetX: number,\n offsetY: number,\n axis: ScrollZoomAxis = 'both',\n ) {\n transaction(() => {\n const colInView = (-self.scrollX + offsetX) / self.colWidth\n const rowInView = (-self.scrollY + offsetY) / self.rowHeight\n if (axis !== 'vertical') {\n self.colWidth = clamp(\n self.colWidth * scaleFactor,\n minColWidth,\n maxCellSize,\n )\n }\n if (axis !== 'horizontal') {\n self.rowHeight = clamp(\n self.rowHeight * scaleFactor,\n minRowHeight,\n maxCellSize,\n )\n }\n self.scrollX = clamp(\n offsetX - colInView * self.colWidth,\n self.maxScrollX,\n 0,\n )\n\n const anchoredScrollY = offsetY - rowInView * self.rowHeight\n // -maxScrollY is the overflow past the viewport, 0 when it fits\n const overflow = Math.max(0, -self.maxScrollY)\n const visibleHeight = self.totalHeight - overflow\n const topBias =\n visibleHeight > 0 ? clamp(1 - overflow / visibleHeight, 0, 1) : 1\n self.scrollY = clamp(\n anchoredScrollY * (1 - topBias),\n self.maxScrollY,\n 0,\n )\n })\n },\n /**\n * #action\n */\n doScrollY(deltaY: number) {\n this.setScrollY(self.scrollY + deltaY)\n },\n\n /**\n * #action\n * set scroll Y-offset (px), clamped to keep the alignment in view\n */\n setScrollY(n: number) {\n self.scrollY = clamp(n, self.maxScrollY, 0)\n },\n\n /**\n * #action\n * Set the overlay annotations (an empty list clears them). InterProScan,\n * GFF, user uploads and NCBI CDD all arrive here as Annotation[].\n *\n * Leaves `showDomains` alone, because a restored snapshot reloads its\n * GFF and must keep a hidden overlay hidden.\n */\n setAnnotations(annotations: Annotation[]) {\n self.annotations = annotations\n },\n\n applyGFFText(gffText: string) {\n this.setAnnotations(gffToAnnotations(parseGFF(gffText)))\n },\n\n /**\n * #action\n */\n doScrollX(deltaX: number) {\n this.setScrollX(self.scrollX + deltaX)\n },\n\n /**\n * #action\n */\n setScrollX(n: number) {\n self.scrollX = clamp(n, self.maxScrollX, 0)\n },\n\n /**\n * #action\n */\n setColumnTracks(tracks: ColumnTrackSpec[]) {\n self.columnTracks.replace(tracks)\n },\n /**\n * #action\n * replace the row table, which the model keeps as the JSON string\n * `data.treeMetadata` (see docs/layers.md)\n */\n setRowData(rowData: RowDataInput) {\n self.data.setTreeMetadata(JSON.stringify(rowData))\n },\n /**\n * #action\n * replace what the viewer's marks read from the row table\n */\n setEncodings(encodings: Encoding[]) {\n self.encodings.replace(encodings)\n },\n /**\n * #action\n * replace the panels drawn between the tree and the alignment\n */\n setRowPanels(panels: RowPanelSpec[]) {\n self.rowPanels.replace(panels)\n },\n /**\n * #action\n * replace the alignment<->structure correspondence (see docs/layers.md)\n */\n setResidueMappings(mappings: ResidueMapping[]) {\n self.residueMappings.replace(mappings)\n },\n /**\n * #action\n */\n toggleTrack(id: string) {\n const defaultOff = self.MSA?.tracks.find(t => t.id === id)?.defaultOff\n self.turnedOffTracks.set(\n id,\n !trackIsOff(self.turnedOffTracks, id, defaultOff),\n )\n },\n /**\n * #action\n */\n setStatus(status?: { msg: string; onCancel?: () => void }) {\n self.status = status\n },\n }))\n .views(self => ({\n /**\n * #method\n * the cell at a visible column and row index, in the coordinates a host\n * writes highlights in. On a gap `residue` is undefined and `letter` is\n * the gap character\n */\n cellAt(visibleCol: number, rowIndex?: number): Cell {\n const column = self.visibleColToGlobalCol(visibleCol)\n const row =\n rowIndex === undefined ? undefined : self.leaves[rowIndex]?.data.name\n return row === undefined\n ? { column: column + 1 }\n : {\n column: column + 1,\n row,\n residue: self.visibleColToSeqPosOneBased(row, visibleCol),\n letter: self.rowSequence(row)?.[column],\n }\n },\n /**\n * #getter\n * the cell under the pointer. Public API: MSAViewer's onCellHover\n * reports it.\n */\n get hoveredCell() {\n const { mouseCol, mouseRow } = self\n return mouseCol === undefined\n ? undefined\n : this.cellAt(mouseCol, mouseRow)\n },\n /**\n * #getter\n * the cell a click pinned. Public API: MSAViewer's onCellClick reports it.\n */\n get clickedCell() {\n const { mouseClickCol, mouseClickRow } = self\n return mouseClickCol === undefined\n ? undefined\n : this.cellAt(mouseClickCol, mouseClickRow)\n },\n /**\n * #getter\n * the columns on screen. Public API: MSAViewer's onViewportChange reports\n * it.\n */\n get viewport(): Viewport | undefined {\n const { scrollX, colWidth, numColumns, viewInitialized } = self\n if (numColumns === 0 || !viewInitialized) {\n return undefined\n }\n const { xStart, xEnd } = visibleColRange({\n offsetX: -scrollX,\n blockWidth: self.msaCanvasWidth,\n colWidth,\n })\n const last = Math.max(0, Math.min(xEnd, numColumns) - 1)\n return {\n startColumn: self.visibleColToGlobalCol(Math.min(xStart, last)) + 1,\n endColumn: self.visibleColToGlobalCol(last) + 1,\n }\n },\n /**\n * #getter\n * ordinal segment types (exons etc.), ordered by sequence position so\n * exon-1..exon-14 run left-to-right; colored by alternating shade and\n * labeled by number, with no legend row\n */\n get segmentDomainTypes() {\n return [...self.annotationTypes.values()]\n .filter(d => segmentFeatureTypes.has(d.featureType ?? ''))\n .toSorted((a, b) => a.start - b.start)\n },\n /**\n * #getter\n * categorical feature types (InterPro domains and the like) that each get\n * their own color and a legend entry\n */\n get categoricalDomainTypes() {\n return [...self.annotationTypes.values()].filter(\n d => !segmentFeatureTypes.has(d.featureType ?? ''),\n )\n },\n get fillPalette() {\n const segments = Object.fromEntries(\n this.segmentDomainTypes.map((d, i) => [\n d.accession,\n segmentShades[i % segmentShades.length]!,\n ]),\n )\n const categorical = createPaletteMap(\n this.categoricalDomainTypes.map(d => d.accession),\n )\n return { ...segments, ...categorical }\n },\n /**\n * #getter\n * the encoding coloring the overlay's spans, undefined when none does,\n * which leaves each span the color its accession takes in `fillPalette`\n */\n get featureFillEncoding(): ResolvedEncoding | undefined {\n return this.resolvedEncodings.find(e => e.channel === 'featureFill')\n },\n\n /**\n * #getter\n * the fill and outline of every feature's span: its own GFF `color=`\n * first, then the `featureFill` scale, then the accession palette.\n * Computed once per change of the features, the encodings or the palette\n */\n get featureColors(): Map<Annotation, { fill: string; stroke: string }> {\n return featureColorMap(\n self.filteredAnnotations,\n this.featureFillEncoding,\n this.fillPalette,\n )\n },\n\n /**\n * #getter\n * the text the `featureLabel` channel draws inside each span, undefined\n * when no encoding names the channel. A data channel, so it draws\n * whether or not the residue letters do\n */\n get featureLabels(): Map<Annotation, string> | undefined {\n const encoding = this.resolvedEncodings.find(\n e => e.channel === 'featureLabel',\n )\n return encoding\n ? featureLabelMap(self.filteredAnnotations, encoding.field)\n : undefined\n },\n\n /**\n * #getter\n * accession -> number drawn on each segment band: the trailing number of\n * the feature name (\"exon-3\" -> \"3\"), else its 1-based position\n */\n get segmentLabels() {\n return new Map(\n this.segmentDomainTypes.map((d, i) => {\n const m = /(\\d+)\\s*$/.exec(d.name)\n return [d.accession, m ? m[1]! : `${i + 1}`]\n }),\n )\n },\n\n /**\n * #getter\n * the domain types currently drawn on the alignment (filtered-on), shared\n * by the on-screen legend and the SVG export legend: the categorical types\n * ordered by sequence position. Ordinal segments (exons) are numbered on\n * the band instead\n */\n get visibleDomainTypes() {\n return this.categoricalDomainTypes\n .filter(d => !self.turnedOffFeatures.get(d.accession))\n .toSorted((a, b) => a.start - b.start)\n },\n\n /**\n * #getter\n * the categorical color keys drawn for this view, shared by the on-screen\n * legend overlay and the SVG export's reserved column. The domain overlay\n * produces the first, listing the `featureFill` scale where an encoding\n * names one. Every field a row-table encoding or a row panel reads\n * produces one more, so two channels over one field, or two strips over\n * it, list that field once. A strip's `legend` names the title it lists\n * under, so strips over eight fields with one set of colors list one\n * legend between them\n */\n get legends(): Legend[] {\n const { featureFillEncoding, fillPalette, visibleDomainTypes } = this\n const byKey = new Map<string, Legend>()\n // the accession palette keys on no field, so it takes a key of its own\n const add = (\n field: string | undefined,\n entries: LegendEntry[],\n id?: string,\n ) => {\n if (entries.length === 0) {\n return\n }\n const key = field === undefined ? 'domains' : `field:${field}`\n const legend = byKey.get(key)\n if (legend) {\n const seen = new Set(legend.entries.map(e => e.id))\n legend.entries.push(...entries.filter(e => !seen.has(e.id)))\n } else {\n byKey.set(key, {\n id: id ?? (field === undefined ? 'domains' : `rowData-${field}`),\n title: field ?? 'Domains',\n entries: [...entries],\n })\n }\n }\n // the overlay draws the domain key; with no columns it draws nothing,\n // and a features panel taking the same colors lists them instead\n if (self.actuallyShowDomains && self.numColumns > 0) {\n add(\n featureFillEncoding?.field,\n featureFillEncoding\n ? featureFillEncoding.legend\n : visibleDomainTypes.map(d => ({\n id: d.accession,\n label: d.name,\n color: d.color ?? fillPalette[d.accession]!,\n })),\n 'domains',\n )\n }\n for (const { channel, field, legend } of this.resolvedEncodings) {\n if (!featureChannels.has(channel)) {\n add(field, legend)\n }\n }\n for (const { legendTitle, legend } of this.rowPanelScales) {\n add(legendTitle, legend)\n }\n return [...byKey.values()]\n },\n\n /**\n * #getter\n * whether the overlay marks each domain with a bar under its row instead\n * of filling the row behind the letters. Letter-color mode hands the\n * background to the color scheme, so a filled box would paint over it and\n * leave the setting with nothing to show. Sub-row layout already stacks\n * the boxes clear of the letters, and with the letters too small to draw\n * the filled box is the only thing left to read.\n */\n get domainUnderline() {\n return (\n self.actuallyShowDomains &&\n !self.bgColor &&\n !self.subFeatureRows &&\n self.showMsaLetters\n )\n },\n\n /**\n * #getter\n * every filtered-on annotation resolved to the visible column span it is\n * drawn across, keyed by row name. Each row is ordered longest-first so a\n * nested short domain draws on top, and each band carries the lane the\n * sub-row layout puts it in. Resolved once here instead of per canvas\n * block per redraw; the letter renderer also reads the band colors to\n * pick legible letter colors.\n */\n get domainBands() {\n const { blanks } = self\n const bands = new Map<string, DomainBand[]>()\n for (const [name, annotations] of Object.entries(\n self.annotationsByRow,\n )) {\n const rowBands = annotations\n .toSorted((a, b) => len(b) - len(a))\n .map(annotation => {\n // annotation positions are 1-based and inclusive. endCol is\n // exclusive, one past the last residue's column, so the band does\n // not extend over a following gap run. An endpoint in a hidden\n // column moves to the neighboring boundary. Bands with no visible\n // columns, or naming a missing row, are dropped.\n const start = self.seqPosToGlobalCol(name, annotation.start - 1)\n const end = self.seqEndToGlobalCol(name, annotation.end - 1)\n if (start === undefined || end === undefined) {\n return undefined\n }\n const startCol = visibleColsBefore(blanks, start)\n const endCol = visibleColsBefore(blanks, end + 1)\n return endCol > startCol\n ? { annotation, startCol, endCol }\n : undefined\n })\n .filter(notEmpty)\n // numbered after filtering, so a dropped band leaves no gap\n .map((band, stackIndex) => ({ ...band, stackIndex }))\n if (rowBands.length > 0) {\n bands.set(name, packDomainLanes(rowBands))\n }\n }\n return bands\n },\n\n /**\n * #getter\n * the same bands ordered by start column, for left-to-right sweeps (the\n * letter renderer walks columns and needs the band covering each one)\n */\n get domainBandsByStart() {\n return new Map(\n [...this.domainBands].map(\n ([name, bands]) =>\n [\n name,\n bands.toSorted((a, b) => a.startCol - b.startCol),\n ] as const,\n ),\n )\n },\n\n /**\n * #getter\n * domain annotations under the mouse, hit-tested against the exact visible\n * column span each box is drawn at (so it matches the overlay across gaps)\n */\n get mouseOverDomains(): Annotation[] {\n const { mouseCol } = self\n const name = self.mouseOverRowName\n if (name === undefined || mouseCol === undefined) {\n return noDomains\n }\n const hits = (this.domainBands.get(name) ?? [])\n .filter(b => mouseCol >= b.startCol && mouseCol < b.endCol)\n .map(b => b.annotation)\n return hits.length > 0 ? hits : noDomains\n },\n\n /**\n * #getter\n * row index of the reference row (`relativeTo`), undefined when unset\n */\n get referenceRowIndex() {\n const { relativeTo } = self\n return relativeTo === undefined\n ? undefined\n : self.rowNamesSet.get(relativeTo)\n },\n\n /**\n * #getter\n * row indices highlighted by the current tree hover (a hovered internal\n * node highlights every tip below it). Shared by the tree and MSA overlay\n * canvases, via the memoized name->index map.\n */\n get hoveredRowIndices() {\n const { hoveredTreeNode, rowNamesSet } = self\n return hoveredTreeNode\n ? hoveredTreeNode.descendantNames\n .map(name => rowNamesSet.get(name))\n .filter(notEmpty)\n : []\n },\n\n /**\n * #getter\n * contiguous runs of `highlightedColumns`, so a run of highlighted columns\n * draws as one bordered band. Memoized because the overlay canvas redraws\n * on every mouse move.\n */\n get highlightedColumnRuns() {\n return consecutiveRuns(\n [...(self.highlightedColumns ?? [])].sort((a, b) => a - b),\n ).map(([start, end]) => ({ start, end }))\n },\n\n /**\n * #method\n * a highlight label with `{residue}` and `{position}` filled in from the\n * row's letter at `start`, which is how the `175` shorthand draws \"R175\"\n */\n fillHighlightLabel(label: string, row?: string, start?: number) {\n if (!label.includes('{')) {\n return label\n }\n const col =\n row && start !== undefined\n ? self.seqPosIndex(row)?.[start - 1]\n : undefined\n const residue =\n row && col !== undefined ? (self.MSA?.getRow(row)[col] ?? '') : ''\n return label\n .replaceAll('{residue}', residue)\n .replaceAll('{position}', start === undefined ? '' : String(start))\n },\n\n /**\n * #getter\n * `highlights` projected onto what is on screen: residue spans go\n * through the named row's gap structure, column spans through the\n * hidden-column list, and a span that lands entirely on hidden columns\n * is dropped. Row names that match no row are ignored.\n */\n get resolvedHighlights(): ResolvedHighlight[] {\n const { rowNamesSet, transientHighlights } = self\n // persisted highlights first, so transient ones draw on top\n const all = [\n ...self.highlights,\n ...Object.values(transientHighlights).flat(),\n ]\n return all.flatMap(({ row, rows, start, end, label, color }) => {\n const base = {\n label: label && this.fillHighlightLabel(label, row, start),\n color,\n }\n if (rows) {\n const rowIndices = rows\n .map(name => rowNamesSet.get(name))\n .filter(notEmpty)\n return rowIndices.length ? [{ ...base, rowIndices }] : []\n }\n if (start === undefined || end === undefined) {\n return []\n }\n const span = self.visibleSpan({ row, start, end })\n return span ? [{ ...base, ...span, rowIndices: [] }] : []\n })\n },\n\n /**\n * #getter\n * `selection` projected onto what is on screen, the way\n * `resolvedHighlights` projects a column span and a row set. A\n * selection whose columns are all hidden, or whose rows are all\n * collapsed away or unknown, resolves to undefined.\n */\n get resolvedSelection(): ResolvedSelection | undefined {\n const { selection, rowNamesSet, numRows } = self\n const span =\n selection &&\n self.visibleSpan({ start: selection.start, end: selection.end })\n if (!selection || !span) {\n return undefined\n }\n const rowRuns = selection.rows\n ? consecutiveRuns(\n selection.rows\n .map(name => rowNamesSet.get(name))\n .filter(notEmpty)\n .sort((a, b) => a - b),\n )\n : numRows > 0\n ? [[0, numRows - 1] as [number, number]]\n : []\n return rowRuns.length > 0 ? { ...span, rowRuns } : undefined\n },\n\n /**\n * #getter\n * the columns and rows the selection covers, for the header's readout.\n * Columns count the file's columns from `start` to `end`, hidden ones\n * included, as `selectionFasta` copies them.\n */\n get selectionSize() {\n const resolved = this.resolvedSelection\n const span = this.selectionFileSpan\n return resolved && span\n ? {\n columns: span.end - span.start + 1,\n rows: sum(resolved.rowRuns.map(([a, b]) => b - a + 1)),\n }\n : undefined\n },\n\n /**\n * #getter\n * `selection`'s columns clamped to the file's\n */\n get selectionFileSpan() {\n const { selection } = self\n const width = self.MSA?.getWidth() ?? 0\n const start = Math.max(1, Math.floor(selection?.start ?? 0))\n const end = Math.min(width, Math.ceil(selection?.end ?? 0))\n return selection && start <= end ? { start, end } : undefined\n },\n\n /**\n * #getter\n * the selected block as FASTA: the selected rows on screen, top to\n * bottom, each with its letters across the file's columns from `start`\n * to `end`, gaps included\n */\n get selectionFasta() {\n const { rowNames } = self\n const resolved = this.resolvedSelection\n const span = this.selectionFileSpan\n if (!resolved || !span) {\n return ''\n }\n const rows = resolved.rowRuns\n .flatMap(([first, last]) => rowNames.slice(first, last + 1))\n .flatMap(name => {\n const seq = self.rowSequence(name)\n return seq === undefined ? [] : [[name, seq] as const]\n })\n return blockFasta(rows, span.start, span.end)\n },\n\n /**\n * #method\n * per-column summary statistics: consensus residue and its identity\n * fraction, both conservation scores, gap fraction, and the sorted non-gap\n * residue distribution. undefined past the end of the alignment or for an\n * all-gap column.\n */\n columnStatsAt(col: number): ColumnStats | undefined {\n const { colStats, conservation, propertyConservation } = self\n return columnStats({\n col,\n colStats,\n conservation,\n propertyConservation,\n })\n },\n\n /**\n * #method\n */\n getRowData(name: string) {\n return {\n data: self.MSA?.getRowData(name),\n rowData: self.rowDataOf(name),\n }\n },\n\n /**\n * #getter\n * each encoding with its scale resolved against the values its field\n * takes: a feature channel reads them across every feature loaded, every\n * other channel across the row table. Resolved once per change of that\n * table or the encodings, never per row per frame.\n */\n get resolvedEncodings(): ResolvedEncoding[] {\n const rows = Object.values(self.rowData)\n return self.encodings.map(encoding => ({\n ...encoding,\n ...(featureChannels.has(encoding.channel)\n ? resolveFeatureScale(\n encoding.field,\n encoding.scale,\n self.allAnnotations,\n self.filteredAnnotations,\n )\n : resolveScale(\n encoding.scale,\n rows.map(row => row?.[encoding.field]).filter(notEmpty),\n )),\n }))\n },\n\n /**\n * #getter\n * each row panel's scale resolved against the values its field takes,\n * giving the colors, labels and legend entries. Reads no cell size, so\n * a zoom reuses it and the legends built from it.\n */\n get rowPanelScales(): (StripPanelScale | FeaturePanelScale)[] {\n const { rowData } = self\n const { fillPalette, featureFillEncoding, featureLabels } = this\n const annotations = self.filteredAnnotations\n return self.rowPanels.map(panel => {\n if (panel.kind === 'features') {\n const color = panel.encoding?.color\n const encoding = color\n ? resolveFeatureScale(\n color.field,\n color.scale,\n self.allAnnotations,\n annotations,\n )\n : featureFillEncoding\n const label = panel.encoding?.label\n return {\n kind: panel.kind,\n x: panel.x,\n header: panel.header ?? '',\n field: encoding?.field,\n legendTitle: encoding?.field,\n colors: color\n ? featureColorMap(annotations, encoding, fillPalette)\n : this.featureColors,\n labels: label\n ? featureLabelMap(annotations, label)\n : featureLabels,\n legend:\n encoding?.legend ??\n this.visibleDomainTypes.map(d => ({\n id: d.accession,\n label: d.name,\n color: d.color ?? fillPalette[d.accession]!,\n })),\n }\n }\n const { colorOf, legend } = resolveScale(\n panel.scale,\n Object.values(rowData)\n .map(row => row?.[panel.field])\n .filter(notEmpty),\n )\n return {\n kind: panel.kind,\n field: panel.field,\n header: panel.header ?? panel.field,\n legendTitle: panel.legend ?? panel.field,\n colors: colorByRow(rowData, panel.field, colorOf),\n legend,\n }\n })\n },\n\n /**\n * #getter\n * each row panel with its scale from `rowPanelScales` and its geometry:\n * the pixel column it draws in and, for a features panel, the spans per\n * row. Resolved once per change of those inputs, never per block per\n * frame.\n */\n get resolvedRowPanels(): ResolvedRowPanel[] {\n const scales = this.rowPanelScales\n let offsetX = 0\n return self.rowPanels.map((panel, index) => {\n const width = rowPanelWidth(panel, self)\n const base = { id: `rowpanel-${index}`, width, offsetX }\n offsetX += width\n if (panel.kind === 'features') {\n const align = panel.transform?.find(t => t.type === 'align')\n return {\n ...base,\n ...(scales[index] as FeaturePanelScale),\n spans: featurePanelSpans({\n panel,\n width,\n colWidth: self.colWidth,\n domainBands: this.domainBands,\n annotationsByRow: self.annotationsByRow,\n shifts: align\n ? this.featureAlignShifts.get(align.on)\n : undefined,\n }),\n }\n }\n return { ...base, ...(scales[index] as StripPanelScale) }\n })\n },\n\n /**\n * #getter\n * the shift an `align` transform gives each row, keyed by the feature\n * name it aligns on: the offset putting the first feature of that name\n * at zero. A row carrying no such feature is absent, and keeps its own\n * origin.\n */\n get featureAlignShifts(): Map<string, Map<string, number>> {\n const names = new Set(\n self.rowPanels.flatMap(panel =>\n panel.kind === 'features' && panel.x === 'position'\n ? (panel.transform ?? [])\n .filter(t => t.type === 'align')\n .map(t => t.on)\n : [],\n ),\n )\n return new Map(\n [...names].map(on => [\n on,\n new Map(\n Object.entries(self.annotationsByRow)\n .map(([name, annotations]) => {\n const hit = annotations.find(a => featureName(a) === on)\n return hit ? ([name, 1 - hit.start] as const) : undefined\n })\n .filter(notEmpty),\n ),\n ]),\n )\n },\n\n /**\n * #getter\n * the color the `tipLabel` channel gives each row, by row name. Undefined\n * when no encoding names the channel, which leaves the labels the theme's\n * text color.\n */\n get tipLabelColors(): Map<string, string> | undefined {\n const encoding = this.resolvedEncodings.find(\n e => e.channel === 'tipLabel',\n )\n return encoding\n ? colorByRow(self.rowData, encoding.field, encoding.colorOf)\n : undefined\n },\n\n /**\n * #getter\n * the wash the `rowTint` channel draws over each row, indexed by row, or\n * undefined when no encoding names the channel. The overlay draws these,\n * so a tint stays out of the raster tile cache and its keys.\n */\n get rowTints(): (string | undefined)[] | undefined {\n const encoding = this.resolvedEncodings.find(\n e => e.channel === 'rowTint',\n )\n if (!encoding) {\n return undefined\n }\n const colors = colorByRow(\n self.rowData,\n encoding.field,\n encoding.colorOf,\n )\n return self.rowNames.map(name => {\n const color = colors.get(name)\n return color && withAlpha(color, rowTintAlpha)\n })\n },\n\n /**\n * #getter\n * the color the `branch` channel gives each tree edge, by the node id at\n * the edge's far end, or undefined when no encoding names the channel. A\n * node takes the field value its tips agree on, so a clade of one value\n * colors down from where it splits off, and a node whose tips disagree or\n * whose value has no color is absent and draws in the default color.\n *\n * The pass runs over the whole tree, never `root`, so a collapsed or\n * focused clade keeps the color the full tree gives it.\n */\n get branchColors(): Map<string, string> | undefined {\n const encoding = this.resolvedEncodings.find(\n e => e.channel === 'branch',\n )\n if (!encoding) {\n return undefined\n }\n const order = preorder(self.tree)\n const values = new Map<NodeWithIds, string | undefined>()\n const colors = new Map<string, string>()\n for (let i = order.length - 1; i >= 0; i--) {\n const node = order[i]!\n const value =\n node.children.length > 0\n ? sharedValue(node.children.map(child => values.get(child)))\n : self.rowDataOf(node.name)?.[encoding.field]\n values.set(node, value)\n const color =\n value === undefined ? undefined : encoding.colorOf(value)\n if (color) {\n colors.set(node.id, color)\n }\n }\n return colors\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n setHeaderHeight(arg: number) {\n self.headerHeight = arg\n },\n /**\n * #action\n */\n setHideHeader(arg: boolean) {\n self.hideHeader = arg\n },\n /**\n * #action\n */\n setImportForm(arg: boolean) {\n self.importForm = arg\n },\n /**\n * #action\n * focus the subtree a click `y` pixels down the tree overview lands on.\n * A click inside the box already drawn there clears the focus, the way\n * clicking the focused branch again does.\n */\n treeOverviewClick(y: number) {\n const hit = self.treeOverviewHit(y)\n const focus = self.treeOverviewFocusRows\n const inside =\n !!focus && !!hit && hit.rows[0] >= focus[0] && hit.rows[1] <= focus[1]\n self.setShowOnly(inside || !hit ? undefined : hit.id)\n },\n /**\n * #action\n * resize every track sharing a `heightKey`; see `trackHeights`\n */\n setTrackHeight(heightKey: string, height: number) {\n self.trackHeights.set(heightKey, height)\n },\n /**\n * #action\n * Return to the import form: reset every property not in\n * `preservedOnReset` to its default, then clear the file-derived\n * volatiles applySnapshot does not touch.\n */\n reset() {\n self.resetCount++\n self.loadWarnings = []\n self.dismissedWarnings = []\n self.setStatus(undefined)\n applySnapshot(\n self,\n Object.fromEntries(\n Object.entries(getSnapshot(self) as Record<string, unknown>).filter(\n ([key]) => preservedOnReset.has(key),\n ),\n ),\n )\n self.setError(undefined)\n self.setAnnotations([])\n self.setHighlightedColumns(undefined)\n self.transientHighlights = {}\n self.setMousePos(undefined, undefined)\n self.setMouseClickPos(undefined, undefined)\n self.setHoveredTreeNode(undefined)\n },\n /**\n * #action\n */\n async exportSVG(opts: ExportSvgOptions) {\n const { renderToSvg } = await import('./renderToSvg.tsx')\n const html = await renderToSvg(self as MsaViewModel, opts)\n const blob = new Blob([html], { type: 'image/svg+xml' })\n saveAs(blob, exportFileName(self.msaFilehandle, 'svg'))\n },\n /**\n * #action\n * save `treeNewick` as a file\n */\n exportNewick() {\n const blob = new Blob([self.treeNewick], { type: 'text/plain' })\n saveAs(\n blob,\n exportFileName(\n self.treeFilehandle ?? self.msaFilehandle,\n 'nwk',\n 'tree',\n ),\n )\n },\n /**\n * #action\n * show or hide an annotation type. Only hidden types are recorded; see\n * `turnedOffFeatures`\n */\n setFilter(accession: string, shown: boolean) {\n if (shown) {\n self.turnedOffFeatures.delete(accession)\n } else {\n self.turnedOffFeatures.set(accession, true)\n }\n },\n\n /**\n * #action\n */\n fit() {\n // two passes: each direction's viewport depends on whether the other\n // overflows (the minimap takes height, the vertical scrollbar width)\n transaction(() => {\n for (let pass = 0; pass < 2; pass++) {\n this.fitHorizontally()\n this.fitVertically()\n }\n })\n },\n /**\n * #action\n */\n fitVertically() {\n if (self.numRows > 0) {\n self.rowHeight = clamp(\n self.msaAreaHeight / self.numRows,\n minRowHeight,\n maxCellSize,\n )\n }\n self.scrollY = 0\n },\n /**\n * #action\n * zoom and scroll so a span fills the alignment's width, in highlight\n * coordinates (see visibleSpan). Does nothing before the viewer knows\n * its width, or for a span that resolves to no visible column.\n */\n zoomToRegion(region: Region) {\n const span = self.visibleSpan(region)\n if (!span || !self.viewInitialized) {\n return\n }\n transaction(() => {\n self.colWidth = clamp(\n self.msaCanvasWidth / (span.endCol - span.startCol + 1),\n minColWidth,\n maxCellSize,\n )\n self.scrollX = clamp(\n -span.startCol * self.colWidth,\n self.maxScrollX,\n 0,\n )\n })\n },\n /**\n * #action\n * zoomToRegion, and for a region naming a row, also scroll that row to\n * the middle of the alignment, as Go to does. What `region` opens on; a\n * caller following a range as it moves wants zoomToRegion alone, which\n * leaves the reader's vertical scroll where they put it.\n */\n revealRegion(region: Region) {\n transaction(() => {\n this.zoomToRegion(region)\n const row =\n region.row === undefined\n ? undefined\n : self.rowNamesSet.get(region.row)\n if (row !== undefined && self.viewInitialized) {\n self.setScrollY(\n -(row + 0.5) * self.rowHeight + self.msaAreaHeight / 2,\n )\n }\n })\n },\n /**\n * #action\n * zoom and scroll so the selected columns fill the alignment's width,\n * and, where the selection names its rows, so those rows fill its height\n */\n zoomToSelection() {\n const { selection, resolvedSelection } = self\n if (!selection || !resolvedSelection) {\n return\n }\n transaction(() => {\n this.zoomToRegion({ start: selection.start, end: selection.end })\n if (selection.rows && self.viewInitialized) {\n const { rowRuns } = resolvedSelection\n const first = rowRuns[0]![0]\n const last = rowRuns.at(-1)![1]\n self.rowHeight = clamp(\n self.msaAreaHeight / (last - first + 1),\n minRowHeight,\n maxCellSize,\n )\n self.scrollY = clamp(-first * self.rowHeight, self.maxScrollY, 0)\n }\n })\n },\n /**\n * #action\n * select the block between two cells given as visible column and row\n * indices, the coordinates a drag reports, clamped to the alignment. A\n * cell with no `row` selects the columns across every row, and so does a\n * block spanning every row on screen.\n */\n selectBlock(\n anchor: { col: number; row?: number },\n head: { col: number; row?: number },\n ) {\n const { numColumns, numRows, rowNames } = self\n if (numColumns === 0 || numRows === 0) {\n return\n }\n const ordered = (a: number, b: number, last: number) =>\n [clamp(a, 0, last), clamp(b, 0, last)].sort((x, y) => x - y) as [\n number,\n number,\n ]\n const [startCol, endCol] = ordered(anchor.col, head.col, numColumns - 1)\n const [firstRow, lastRow] =\n anchor.row === undefined || head.row === undefined\n ? [0, numRows - 1]\n : ordered(anchor.row, head.row, numRows - 1)\n const everyRow = firstRow === 0 && lastRow === numRows - 1\n self.setSelection({\n start: self.visibleColToGlobalCol(startCol) + 1,\n end: self.visibleColToGlobalCol(endCol) + 1,\n ...(everyRow ? {} : { rows: rowNames.slice(firstRow, lastRow + 1) }),\n })\n },\n /**\n * #action\n */\n fitHorizontally() {\n if (self.numColumns > 0) {\n // msaCanvasWidth excludes the vertical scrollbar's 20px\n self.colWidth = clamp(\n self.msaCanvasWidth / self.numColumns,\n minColWidth,\n maxCellSize,\n )\n }\n self.scrollX = 0\n },\n\n afterCreate() {\n if (self.highlightColumns?.length) {\n self.setHighlightedColumns(self.highlightColumns)\n }\n\n // The `collapse`, `focus` and `rotate` clade marks seed the collapsed\n // list, the subtree in focus and the rotated nodes, which the tree,\n // `hideGapsEffective` and the alignment all read. The tree arrives with\n // the model for inline data and later for a filehandle, so the seeding\n // waits for it and then runs once per data load, per change of\n // `clades` and per reroot, which clears the node ids the seeding\n // wrote: expanding a seeded clade sticks until one of those changes.\n // `dataInitialized` is true once the MSA alone has loaded, when the\n // tree is still the flat stub, so a tree filehandle holds the seeding\n // until its text lands.\n addDisposer(\n self,\n reaction(\n () =>\n self.dataInitialized && !(self.treeFilehandle && !self.data.tree)\n ? { clades: getSnapshot(self.clades), treeRoot: self.treeRoot }\n : undefined,\n seed => {\n if (!seed?.clades.length) {\n return\n }\n for (const { mark, nodeId } of self.resolvedClades) {\n if (nodeId === undefined) {\n continue\n }\n if (mark === 'collapse' && !self.collapsed.includes(nodeId)) {\n self.toggleCollapsed(nodeId)\n } else if (mark === 'focus') {\n self.setShowOnly(nodeId)\n } else if (\n mark === 'rotate' &&\n !self.rotated.includes(nodeId)\n ) {\n self.toggleRotated(nodeId)\n }\n }\n },\n { fireImmediately: true, equals: compareStructural },\n ),\n )\n\n // zoomToRegion needs a width and resolves residues through the visible\n // columns, so this waits for both, and for a tree file whose collapsed\n // clades would hide columns and move the target after the zoom\n addDisposer(\n self,\n autorun(() => {\n const { region } = self\n if (\n region &&\n self.viewInitialized &&\n self.numColumns > 0 &&\n !(self.treeFilehandle && !self.data.tree)\n ) {\n this.revealRegion(region)\n self.setRegion(undefined)\n }\n }),\n )\n\n // the matchMedia query is pinned to the current device pixel ratio, so\n // each change re-registers against the new one\n if (\n typeof window !== 'undefined' &&\n typeof window.matchMedia === 'function'\n ) {\n const query = () =>\n window.matchMedia(`(resolution: ${window.devicePixelRatio}dppx)`)\n let mql = query()\n const onChange = () => {\n self.setHighResScaleFactor(window.devicePixelRatio)\n mql.removeEventListener('change', onChange)\n mql = query()\n mql.addEventListener('change', onChange)\n }\n mql.addEventListener('change', onChange)\n addDisposer(self, () => {\n mql.removeEventListener('change', onChange)\n })\n }\n\n /**\n * Fetch a filehandle whenever it changes, and hand the text to\n * `onLoad`.\n *\n * A generation guard keeps a slower superseded request from overwriting\n * the newer one's data, status or loading flag. A superseded or cleared\n * request is aborted and clears its status line.\n *\n * `clearFilehandle` runs after a local file loads, since a blob has no\n * URL to refetch, and when the user cancels, which returns the view to\n * the import form.\n *\n * `what` names the layer in a failure message. An `optional` layer\n * (annotations, row metadata) that fails adds a warning instead of an\n * error.\n */\n const loadOnFilehandleChange = ({\n what,\n getFilehandle,\n onLoad,\n setLoading,\n clearFilehandle,\n optional = false,\n }: {\n what: string\n getFilehandle: () => FileLocationType | undefined\n onLoad: (text: string) => void\n setLoading?: (arg: boolean) => void\n clearFilehandle?: () => void\n optional?: boolean\n }) => {\n let generation = 0\n let cancelInFlight: (() => void) | undefined\n addDisposer(self, () => {\n cancelInFlight?.()\n })\n addDisposer(\n self,\n autorun(async () => {\n const filehandle = getFilehandle()\n const current = ++generation\n cancelInFlight?.()\n cancelInFlight = undefined\n if (!filehandle) {\n setLoading?.(false)\n return\n }\n const isCurrent = () => current === generation && isAlive(self)\n const controller = new AbortController()\n cancelInFlight = () => {\n controller.abort()\n if (isAlive(self)) {\n self.setStatus(undefined)\n }\n }\n try {\n setLoading?.(true)\n if (!optional) {\n self.setError(undefined)\n }\n const text = await fetchTextWithProgress(\n openLocation(filehandle),\n status => {\n if (isCurrent()) {\n self.setStatus(status)\n }\n },\n { controller },\n )\n if (isCurrent()) {\n transaction(() => {\n onLoad(text)\n if (filehandle.locationType === 'BlobLocation') {\n clearFilehandle?.()\n }\n })\n }\n } catch (e) {\n if (isCurrent()) {\n if (isAbortError(e)) {\n clearFilehandle?.()\n } else {\n console.error(e)\n if (optional) {\n self.addWarning(`The ${what} did not load: ${e}`)\n } else {\n self.setError(e)\n }\n }\n }\n } finally {\n if (isCurrent()) {\n cancelInFlight = undefined\n setLoading?.(false)\n }\n }\n }),\n )\n }\n\n loadOnFilehandleChange({\n what: 'tree',\n getFilehandle: () => self.treeFilehandle,\n onLoad: text => {\n self.setTree(text)\n },\n setLoading: arg => {\n self.setLoadingTree(arg)\n },\n clearFilehandle: () => {\n self.setTreeFilehandle(undefined)\n },\n })\n\n // treeMetadata has no import-form step, so no loading flag or cancel\n loadOnFilehandleChange({\n what: 'row metadata',\n optional: true,\n getFilehandle: () => self.treeMetadataFilehandle,\n onLoad: text => {\n self.setTreeMetadata(text)\n },\n })\n\n // parses data.gff into annotations. Clearing the text clears only the\n // annotations this autorun applied, not ones a host set directly\n let appliedGFF = false\n addDisposer(\n self,\n autorun(() => {\n const gffText = self.data.gff\n if (gffText) {\n try {\n self.applyGFFText(gffText)\n appliedGFF = true\n } catch (e) {\n console.error(e)\n self.addWarning(`The annotations did not parse: ${e}`)\n }\n } else if (appliedGFF) {\n appliedGFF = false\n self.setAnnotations([])\n }\n }),\n )\n\n // gffFilehandle loads into data.gff, which the autorun above parses\n loadOnFilehandleChange({\n what: 'annotations',\n optional: true,\n getFilehandle: () => self.gffFilehandle,\n onLoad: text => {\n self.setGFF(text)\n },\n clearFilehandle: () => {\n self.setGFFFilehandle(undefined)\n },\n })\n\n loadOnFilehandleChange({\n what: 'alignment',\n getFilehandle: () => self.msaFilehandle,\n onLoad: text => {\n self.setMSA(text)\n },\n setLoading: arg => {\n self.setLoadingMSA(arg)\n },\n clearFilehandle: () => {\n self.setMSAFilehandle(undefined)\n },\n })\n\n // Keep computeds alive that are read outside reactions, so they are not\n // recomputed on every access: self.columns (and through it the\n // parseMSA result), and the column statistics that dynamic color\n // schemes and the mousemove-driven hover tooltip read.\n // xref solution https://github.com/mobxjs/mobx/issues/266#issuecomment-222007278\n // xref problem https://github.com/GMOD/react-msaview/issues/75\n addDisposer(\n self,\n autorun(() => {\n if (self.dynamicColorSchemeName) {\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n self.colStats\n }\n if (self.showColumnStats) {\n // everything the hover tooltip reads per column\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n self.colStats\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n self.conservation\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n self.propertyConservation\n }\n // eslint-disable-next-line @typescript-eslint/no-unused-expressions\n self.columns\n }),\n )\n },\n }))\n .postProcessSnapshot(({ data, columnTracks, ...rest }) => ({\n // stripDefault handles per-property defaults; this drops inline documents\n // whose filehandle can refetch them\n ...rest,\n ...smallColumnTracks(columnTracks, maxInlineSnapshotBytes),\n data: {\n ...(rest.treeFilehandle ? {} : { tree: data.tree }),\n ...(rest.msaFilehandle ? {} : { msa: data.msa }),\n ...(rest.treeMetadataFilehandle\n ? {}\n : { treeMetadata: data.treeMetadata }),\n ...(rest.gffFilehandle ? {} : { gff: data.gff }),\n },\n }))\n}\n\nexport default stateModelFactory\n\nexport type MsaViewStateModel = ReturnType<typeof stateModelFactory>\nexport type MsaViewModel = Instance<MsaViewStateModel>\n", "/**\n * FASTA for a block of the alignment: each row's letters from column `start`\n * to `end`, 1-based and inclusive, under its name. Gaps stay in, and a row that\n * ends before `end` is padded with gaps, so every record is the block's width.\n */\nexport function blockFasta(\n rows: readonly (readonly [string, string])[],\n start: number,\n end: number,\n) {\n const width = Math.max(0, end - start + 1)\n return rows\n .map(\n ([name, seq]) =>\n `>${name}\\n${seq.slice(start - 1, end).padEnd(width, '-')}\\n`,\n )\n .join('')\n}\n", "// Returns the block offsets (in pixels) needed to cover the viewport along one\n// axis. mapSize/viewportPos/viewportSize are all in pixels. The clamp pins the\n// block set to the content edge, so an over-scroll past the end still fills\n// the viewport, and content smaller than the viewport mounts only the blocks\n// it covers: none for a tree-only figure with zero columns.\nexport function calculateBlocks({\n mapSize,\n blockSize,\n viewportPos,\n viewportSize,\n}: {\n mapSize: number\n blockSize: number\n viewportPos: number\n viewportSize: number\n}) {\n const clamped = Math.max(0, Math.min(viewportPos, mapSize - viewportSize))\n const end = Math.min(clamped + viewportSize, mapSize)\n const minTile = Math.floor(clamped / blockSize)\n const maxTile = Math.ceil(end / blockSize) - 1\n\n const blocks = []\n for (let tile = minTile; tile <= maxTile; tile++) {\n blocks.push(tile * blockSize)\n }\n return blocks\n}\n", "// ClustalX consensus coloring.\n// ref http://www.jalview.org/help/html/colourSchemes/clustal.html\n\nimport type { ColumnCounts } from './columnCounts.ts'\n\nconst BLUE = 'rgb(128,179,230)'\nconst RED = '#d88'\nconst MAGENTA_E = 'rgb(192, 72, 192)'\nconst MAGENTA_D = 'rgb(204, 77, 204)'\nconst GREEN = '#8f8'\nconst GREEN_ST = 'rgb(26,204,26)'\nconst PINK = 'rgb(240, 128, 128)'\nconst ORANGE = 'rgb(240, 144, 72)'\nconst YELLOW = 'rgb(204, 204, 0)'\nconst CYAN = 'rgb(26, 179, 179)'\n\n/**\n * Computes the ClustalX letter->color map for a single alignment column, read\n * out of the alignment-wide `ColumnCounts` tally.\n */\nexport function clustalXColumnColors(counts: ColumnCounts, col: number) {\n const total = counts.total(col)\n const count = (letter: string) => counts.count(col, letter)\n const W = count('W')\n const L = count('L')\n const V = count('V')\n const I = count('I')\n const M = count('M')\n const A = count('A')\n const F = count('F')\n const C = count('C')\n const H = count('H')\n const P = count('P')\n const R = count('R')\n const K = count('K')\n const Q = count('Q')\n const E = count('E')\n const D = count('D')\n const T = count('T')\n const S = count('S')\n const G = count('G')\n const Y = count('Y')\n const N = count('N')\n\n const hydrophobic = W + L + V + I + M + A + F + C + H + P + Y\n const KR = K + R\n const QE = Q + E\n const ED = E + D\n const TS = T + S\n const p = (subtotal: number) => subtotal / total\n\n const colors: Record<string, string> = {}\n\n if (p(hydrophobic) > 0.6) {\n colors.W = BLUE\n colors.L = BLUE\n colors.V = BLUE\n colors.A = BLUE\n colors.I = BLUE\n colors.M = BLUE\n colors.F = BLUE\n colors.C = BLUE\n }\n\n if (p(KR) > 0.6 || p(K) > 0.8 || p(R) > 0.8 || p(Q) > 0.8) {\n colors.K = RED\n colors.R = RED\n }\n\n if (p(KR) > 0.6 || p(QE) > 0.5 || p(E) > 0.8 || p(Q) > 0.8 || p(D) > 0.8) {\n colors.E = MAGENTA_E\n }\n\n if (p(KR) > 0.6 || p(ED) > 0.5 || p(K) > 0.8 || p(R) > 0.8 || p(Q) > 0.8) {\n colors.D = MAGENTA_D\n }\n\n if (p(N) > 0.5 || p(Y) > 0.85) {\n colors.N = GREEN\n }\n\n if (\n p(KR) > 0.6 ||\n p(QE) > 0.6 ||\n p(Q) > 0.85 ||\n p(E) > 0.85 ||\n p(K) > 0.85 ||\n p(R) > 0.85\n ) {\n colors.Q = GREEN\n }\n\n if (p(hydrophobic) > 0.6 || p(TS) > 0.5 || p(S) > 0.85 || p(T) > 0.85) {\n colors.S = GREEN_ST\n colors.T = GREEN_ST\n }\n\n if (p(C) > 0.85) {\n colors.C = PINK\n }\n\n if (G > 0) {\n colors.G = ORANGE\n }\n\n if (P > 0) {\n colors.P = YELLOW\n }\n\n if (\n p(hydrophobic) > 0.6 ||\n p(W) > 0.85 ||\n p(Y) > 0.85 ||\n p(A) > 0.85 ||\n p(C) > 0.85 ||\n p(P) > 0.85 ||\n p(Q) > 0.85 ||\n p(F) > 0.85 ||\n p(H) > 0.85 ||\n p(I) > 0.85 ||\n p(L) > 0.85 ||\n p(M) > 0.85 ||\n p(V) > 0.85\n ) {\n colors.H = CYAN\n colors.Y = CYAN\n }\n\n return colors\n}\n", "import type { ColumnCounts } from './columnCounts.ts'\n\nexport interface ColumnStats {\n col: number\n total: number\n gaps: number\n gapFraction: number\n conservation: number\n propertyConservation: number | undefined\n consensusLetter: string\n consensusCount: number\n consensusFraction: number\n distribution: [string, number][]\n}\n\n/**\n * Summarize one column: consensus residue and its identity fraction, the two\n * conservation scores, gap fraction, and the non-gap residue distribution\n * sorted by count. undefined past the end of the alignment or for a column with\n * no sequences.\n *\n * A module-level function: a getter that reached the method through `this` made\n * TypeScript infer the whole views object to type it, and fell back to `any`.\n */\nexport function columnStats({\n col,\n colStats,\n conservation,\n propertyConservation,\n}: {\n col: number\n colStats: ColumnCounts\n conservation: number[]\n propertyConservation: number[]\n}): ColumnStats | undefined {\n if (col >= colStats.numColumns) {\n return undefined\n }\n const total = colStats.total(col)\n if (!total) {\n return undefined\n }\n const gaps = colStats.gapCount(col)\n const distribution = colStats.residueEntries(col).sort((a, b) => b[1] - a[1])\n const consensus = distribution[0]\n return {\n col,\n total,\n gaps,\n gapFraction: gaps / total,\n conservation: conservation[col] ?? 0,\n propertyConservation: propertyConservation[col],\n consensusLetter: consensus?.[0] ?? '',\n consensusCount: consensus?.[1] ?? 0,\n consensusFraction: consensus ? consensus[1] / total : 0,\n distribution,\n }\n}\n", "/**\n * Assigns each of one row's bands a lane: the first lane whose last band ends\n * before this one starts, so only bands that actually overlap stack. A row of\n * adjacent exons packs into a single lane; a family with a domain nested inside\n * it takes two.\n *\n * Packing runs left to right, but the result keeps the input's largest-first\n * paint order. `laneCount` is the row's depth, which the renderer divides the\n * row height by so a deep stack stays inside its own row.\n *\n * The coordinates are whatever the caller packs in: alignment columns for the\n * overlay, residue positions for a `features` row panel.\n */\nexport function packDomainLanes<T extends { startCol: number; endCol: number }>(\n bands: T[],\n): (T & { lane: number; laneCount: number })[] {\n const laneEnds: number[] = []\n const lanes = new Array<number>(bands.length)\n const byStart = bands\n .map((_, i) => i)\n .sort((a, b) => bands[a]!.startCol - bands[b]!.startCol)\n\n for (const i of byStart) {\n const { startCol, endCol } = bands[i]!\n const found = laneEnds.findIndex(end => end <= startCol)\n const lane = found === -1 ? laneEnds.length : found\n laneEnds[lane] = endCol\n lanes[i] = lane\n }\n\n return bands.map((band, i) => ({\n ...band,\n lane: lanes[i]!,\n laneCount: laneEnds.length,\n }))\n}\n", "/**\n * A round branch-length step and its width in pixels: the largest 1/2/5 x 10^n\n * substitutions-per-site that fits in `maxPx`, aiming at about half of it.\n * Returns undefined in cladogram mode, where the x-positions carry no length.\n */\nexport function scaleBarLength(pxPerUnit: number, maxPx: number) {\n if (pxPerUnit <= 0 || maxPx < 20) {\n return undefined\n }\n const target = maxPx / 2 / pxPerUnit\n const magnitude = 10 ** Math.floor(Math.log10(target))\n const mantissa = target / magnitude\n const step = (mantissa >= 5 ? 5 : mantissa >= 2 ? 2 : 1) * magnitude\n const px = step * pxPerUnit\n return px > maxPx\n ? undefined\n : {\n step,\n px,\n // a length of 0.02 reads as 0.02, not 0.020000000000000004\n label: `${Number(step.toPrecision(2))}`,\n }\n}\n", "const palettes = [\n ['#F8766D'],\n ['#F8766D', '#00BFC4'],\n ['#F8766D', '#00BA38', '#619CFF'],\n ['#F8766D', '#7CAE00', '#00BFC4', '#C77CFF'],\n ['#F8766D', '#A3A500', '#00BF7D', '#00B0F6', '#E76BF3'],\n ['#F8766D', '#B79F00', '#00BA38', '#00BFC4', '#619CFF', '#F564E3'],\n ['#F8766D', '#C49A00', '#53B400', '#00C094', '#00B6EB', '#A58AFF', '#FB61D7'],\n [\n '#F8766D',\n '#CD9600',\n '#7CAE00',\n '#00BE67',\n '#00BFC4',\n '#00A9FF',\n '#C77CFF',\n '#FF61CC',\n ],\n]\n\nexport default palettes\n\n/**\n * Fixed categorical palettes a scale names. `ggplot` is not one of them: it is\n * the ramp above, which picks its colors from the number of keys.\n */\nexport const namedPalettes: Record<string, readonly string[]> = {\n set1: [\n '#e41a1c',\n '#377eb8',\n '#4daf4a',\n '#984ea3',\n '#ff7f00',\n '#ffff33',\n '#a65628',\n '#f781bf',\n '#999999',\n ],\n dark2: [\n '#1b9e77',\n '#d95f02',\n '#7570b3',\n '#e7298a',\n '#66a61e',\n '#e6ab02',\n '#a6761d',\n '#666666',\n ],\n // Okabe-Ito, which stays distinguishable under the common forms of color\n // blindness\n okabeito: [\n '#e69f00',\n '#56b4e9',\n '#009e73',\n '#f0e442',\n '#0072b2',\n '#d55e00',\n '#cc79a7',\n '#000000',\n ],\n tableau: [\n '#4e79a7',\n '#f28e2b',\n '#e15759',\n '#76b7b2',\n '#59a14f',\n '#edc948',\n '#b07aa1',\n '#ff9da7',\n '#9c755f',\n '#bab0ac',\n ],\n}\n\n/**\n * The colors a palette name asks for. `ggplot`, an unknown name, and no name at\n * all give undefined, which `createPaletteMap` answers with the hue ramp.\n */\nexport function paletteNamed(name?: string) {\n return name === undefined ? undefined : namedPalettes[name]\n}\n", "import { colord } from 'colord'\n\nimport palettes from './ggplotPalettes.ts'\n\n/**\n * Creates a map from keys to colors. `palette` names the colors to take in\n * order, such as the list a scale asked for by name; without it the keys take\n * the ggplot palette of their own size. Beyond the colors available \u2014 a\n * gene-structure overlay with one feature per exon, or nine keys on an\n * eight-color palette \u2014 every key gets an evenly spaced HSL hue instead, so no\n * two keys share a color.\n */\nexport function createPaletteMap(keys: string[], palette?: readonly string[]) {\n const n = keys.length\n const colors = palette ?? palettes[n - 1]\n if (colors && n <= colors.length) {\n return Object.fromEntries(keys.map((key, i) => [key, colors[i]!]))\n }\n return Object.fromEntries(\n keys.map((key, i) => [\n key,\n colord({ h: (i * 360) / n, s: 60, l: 60 }).toHex(),\n ]),\n )\n}\n", "import type { FileLocation } from '@jbrowse/core/util/types'\n\n/**\n * The name to save an export under: the loaded file's name with the extension\n * swapped, or `fallback` when the data was pasted in.\n */\nexport function exportFileName(\n location: FileLocation | undefined,\n extension: string,\n fallback = 'image',\n) {\n const loc = location as\n | { uri?: string; localPath?: string; name?: string }\n | undefined\n const path = loc?.uri ?? loc?.localPath ?? loc?.name\n const base = path\n ?.split(/[?#]/)[0]\n ?.split(/[/\\\\]/)\n .pop()\n ?.replace(/\\.[^.]*$/, '')\n return `${base || fallback}.${extension}`\n}\n", "import type { Annotation, Feature } from './types.ts'\n\nconst placement = new Set(['row', 'start', 'end'])\n\n// The colors and labels are maps keyed by annotation, and a getter read\n// outside a reaction recomputes on every read. Caching on the frozen feature\n// gives it one annotation however often the layer converts.\nconst converted = new WeakMap<Feature, Annotation>()\n\n/**\n * The `features` layer as the annotations a GFF would parse to. Every field\n * but the placement is also an attribute, as a string like a GFF value, so an\n * encoding reads `type` or a host's own field the way it reads a GFF column 9\n * key.\n */\nexport function featuresToAnnotations(features: Feature[]): Annotation[] {\n return features.map(feature => {\n const cached = converted.get(feature)\n if (cached) {\n return cached\n }\n const annotation = featureAnnotation(feature)\n converted.set(feature, annotation)\n return annotation\n })\n}\n\nfunction featureAnnotation(feature: Feature): Annotation {\n const { row, start, end, name, description, type, strand, color } = feature\n const accession = name ?? `${row}:${start}-${end}`\n const attributes = Object.fromEntries(\n Object.entries(feature)\n .filter(([key, value]) => !placement.has(key) && value !== undefined)\n .map(([key, value]) => [key, String(value)]),\n )\n return {\n id: row,\n accession,\n name: name ?? accession,\n description: description ?? name ?? accession,\n featureType: type,\n start,\n end,\n strand: strand === '+' ? 1 : strand === '-' ? -1 : undefined,\n color,\n attributes,\n }\n}\n", "import { fetchAndMaybeUnzipText } from '@jbrowse/core/util'\n\nimport type { RpcStatus } from '@jbrowse/core/util'\n\n/**\n * Extract the human-readable text from a status value, which core reports\n * either as a bare string or as a `{message, current, total}` progress object.\n *\n * Inlined rather than imported from `@jbrowse/core/util` on purpose:\n * `statusMessageText` is a recent core export, and in the UMD plugin build\n * `@jbrowse/core/util` is an external resolved against whatever core the host\n * jbrowse-web ships. Against an older host this import lands as `undefined` and\n * every download tick throws `statusMessageText is not a function`. Keeping the\n * one-liner local makes the viewer work on old and new hosts alike.\n */\nfunction statusMessageText(status: RpcStatus | undefined) {\n return typeof status === 'string' ? status : status?.message\n}\n\nexport interface FetchStatus {\n msg: string\n onCancel?: () => void\n}\n\ntype Filehandle = Parameters<typeof fetchAndMaybeUnzipText>[0]\n\ntype ProgressFetcher = (\n loc: Filehandle,\n opts: { signal: AbortSignal; statusCallback: (status: RpcStatus) => void },\n) => Promise<string>\n\n/**\n * Fetch text from a filehandle while reporting download/unzip progress through\n * setStatus, and wiring a Cancel handler that aborts the underlying request.\n * The status is always cleared once the fetch settles. The fetcher is injectable\n * for testing, and so is the AbortController: a caller that can supersede its\n * own request -- the model's loaders, when the filehandle changes under them --\n * holds one and aborts the download it no longer wants.\n */\nexport async function fetchTextWithProgress(\n loc: Filehandle,\n setStatus: (status?: FetchStatus) => void,\n {\n fetcher = fetchAndMaybeUnzipText,\n controller = new AbortController(),\n }: { fetcher?: ProgressFetcher; controller?: AbortController } = {},\n) {\n try {\n return await fetcher(loc, {\n signal: controller.signal,\n statusCallback: status => {\n const msg = statusMessageText(status)\n setStatus(\n msg\n ? {\n msg,\n onCancel: () => {\n controller.abort()\n },\n }\n : undefined,\n )\n },\n })\n } finally {\n setStatus(undefined)\n }\n}\n\nexport function isAbortError(e: unknown) {\n return e instanceof DOMException && e.name === 'AbortError'\n}\n", "interface FlatItem {\n id: number\n parent?: number\n // NCBI BioTreeContainer features, already un-remapped by parseAsn1. Both are\n // strings there: the ASN.1 encodes every feature value as one.\n label?: string\n dist?: string\n}\n\ninterface TreeNode {\n id: string\n name: string\n length?: number\n children: TreeNode[]\n}\n\nexport function flatToTree(items: FlatItem[]): TreeNode {\n const nodeMap = new Map(\n items.map(item => {\n const length = item.dist === undefined ? undefined : Number(item.dist)\n return [\n item.id,\n {\n id: `${item.id}`,\n // NCBI's tree viewer shows the label\n name: item.label || `${item.id}`,\n ...(length !== undefined && Number.isFinite(length)\n ? { length }\n : {}),\n children: [] as TreeNode[],\n },\n ]\n }),\n )\n\n let root: TreeNode | undefined\n for (const item of items) {\n const node = nodeMap.get(item.id)!\n const parent =\n item.parent !== undefined ? nodeMap.get(item.parent) : undefined\n if (parent) {\n parent.children.push(node)\n } else {\n root ??= node\n }\n }\n\n if (root === undefined) {\n // no node lacks a (resolvable) parent: empty input, or every node's parent\n // points back into the set (a cycle). returning undefined here would crash\n // cryptically downstream, so fail with a diagnosable message instead\n throw new Error(\n 'could not build tree from flat node list: no root found (input was empty or contains a parent cycle)',\n )\n }\n\n return root\n}\n", "import { types } from '@jbrowse/mobx-state-tree'\n\nimport { maxInlineSnapshotBytes } from '../constants.ts'\n\n/**\n * #stateModel DataModel\n * the data stored for the model. this is sometimes temporary in the case that\n * e.g. msaFilehandle is available on the parent model, because then the msa\n * data will not be persisted in saved session snapshots, it will be fetched\n * from msaFilehandle at startup\n */\nexport function DataModelF(maxInlineBytes = maxInlineSnapshotBytes) {\n return types\n .model({\n /**\n * #property\n */\n tree: types.maybe(types.string),\n /**\n * #property\n */\n msa: types.maybe(types.string),\n /**\n * #property\n */\n treeMetadata: types.maybe(types.string),\n /**\n * #property\n */\n gff: types.maybe(types.string),\n })\n .actions(self => ({\n /**\n * #action\n */\n setTree(tree?: string) {\n self.tree = tree\n },\n /**\n * #action\n */\n setMSA(msa?: string) {\n self.msa = msa\n },\n /**\n * #action\n */\n setTreeMetadata(treeMetadata?: string) {\n self.treeMetadata = treeMetadata\n },\n /**\n * #action\n */\n setGFF(gff?: string) {\n self.gff = gff\n },\n }))\n .postProcessSnapshot(snap =>\n // drops any field over maxInlineBytes; the parent model's\n // `unshareableData` reports what was dropped\n Object.fromEntries(\n Object.entries(snap).map(([key, text]) => [\n key,\n text && text.length > maxInlineBytes ? undefined : text,\n ]),\n ),\n )\n}\n", "import { types } from '@jbrowse/mobx-state-tree'\n\nimport type { DialogComponentType } from '@jbrowse/core/util'\n\n/**\n * #stateModel DialogQueueSessionMixin\n */\nexport function DialogQueueSessionMixin() {\n return types\n .model('DialogQueueSessionMixin', {})\n .volatile(() => ({\n queueOfDialogs: [] as [DialogComponentType, any][],\n }))\n .views(self => ({\n /**\n * #getter\n */\n get DialogComponent() {\n return self.queueOfDialogs[0]?.[0]\n },\n /**\n * #getter\n */\n get DialogProps() {\n return self.queueOfDialogs[0]?.[1]\n },\n }))\n .actions(self => ({\n /**\n * #action\n */\n removeActiveDialog() {\n self.queueOfDialogs = self.queueOfDialogs.slice(1)\n },\n /**\n * #action\n */\n queueDialog(\n cb: (doneCallback: () => void) => [DialogComponentType, unknown],\n ) {\n const [component, props] = cb(() => {\n this.removeActiveDialog()\n })\n self.queueOfDialogs = [...self.queueOfDialogs, [component, props]]\n },\n }))\n}\n", "import { types } from '@jbrowse/mobx-state-tree'\n\nimport {\n defaultBgColor,\n defaultColorSchemeName,\n defaultShowColumnStats,\n} from '../constants.ts'\nimport { stripDefault } from '../stripDefault.ts'\n\nimport type { MSAFormat } from 'msa-parsers'\n\nconst msaFormats: MSAFormat[] = ['stockholm', 'a3m', 'fasta', 'emf', 'clustal']\n\n/**\n * #stateModel MSAModel\n */\nexport function MSAModelF() {\n return types\n .model({\n /**\n * #property\n * draw MSA tiles with a background color\n */\n bgColor: stripDefault(types.boolean, defaultBgColor),\n\n /**\n * #property\n * default color scheme name\n */\n colorSchemeName: stripDefault(types.string, defaultColorSchemeName),\n\n /**\n * #property\n * a color per residue letter, which replaces the `colorSchemeName` table\n * while set. A letter the map leaves out takes no color\n */\n customColorScheme: types.frozen<Record<string, string> | undefined>(),\n\n /**\n * #property\n * show a tooltip with the hovered column's value for a track while\n * hovering that track: the conservation scores, the logo's composition,\n * an arc's partner columns\n */\n showColumnStats: stripDefault(types.boolean, defaultShowColumnStats),\n\n /**\n * #property\n * force the MSA data to be parsed as a specific format instead of relying\n * on auto-detection (which is ambiguous between e.g. fasta and a3m)\n */\n msaFormat: types.maybe(\n types.enumeration<MSAFormat>('MSAFormat', msaFormats),\n ),\n })\n .actions(self => ({\n /**\n * #action\n * pick a scheme from the built-in table, which clears\n * `customColorScheme`\n */\n setColorSchemeName(name: string) {\n self.colorSchemeName = name\n self.customColorScheme = undefined\n },\n\n /**\n * #action\n * color residues from a map of letter to color, or pass undefined to\n * return to `colorSchemeName`\n */\n setCustomColorScheme(map?: Record<string, string>) {\n self.customColorScheme = map\n },\n\n /**\n * #action\n */\n setBgColor(arg: boolean) {\n self.bgColor = arg\n },\n\n /**\n * #action\n */\n setShowColumnStats(arg: boolean) {\n self.showColumnStats = arg\n },\n\n /**\n * #action\n * force a specific MSA parser, or pass undefined to auto-detect\n */\n setMSAFormat(arg?: MSAFormat) {\n self.msaFormat = arg\n },\n }))\n}\n", "import { types } from '@jbrowse/mobx-state-tree'\n\nimport type {\n IAnyType,\n IOptionalIType,\n OptionalDefaultValueOrFunction,\n} from '@jbrowse/mobx-state-tree'\n\n/**\n * `types.stripDefault`, degrading to `types.optional` on hosts that lack it.\n *\n * stripDefault keeps defaulted properties out of snapshots, and only the\n * mobx-state-tree in unreleased @jbrowse/core has it. The plugin bundle\n * externalizes mobx-state-tree, so the host's copy is known only at runtime, and\n * calling a missing stripDefault during model construction makes PluginLoader\n * reject and the whole app show its error page.\n *\n * The signatures are identical; on older hosts, defaults reappear in snapshots\n * and shared URLs. stripDefaultSnapshot.test.ts pins the stripped behaviour.\n */\nexport function stripDefault<IT extends IAnyType>(\n type: IT,\n defaultValue: OptionalDefaultValueOrFunction<IT>,\n): IOptionalIType<IT, [undefined]> {\n return typeof types.stripDefault === 'function'\n ? types.stripDefault(type, defaultValue)\n : types.optional(type, defaultValue)\n}\n", "import { types } from '@jbrowse/mobx-state-tree'\n\nimport {\n defaultDrawLabels,\n defaultDrawNodeBubbles,\n defaultDrawNodeLabels,\n defaultDrawTree,\n defaultLabelsAlignRight,\n defaultOverviewHeight,\n defaultShowBranchLen,\n defaultTreeOrder,\n defaultShowTreeOverview,\n treeOrders,\n} from '../constants.ts'\nimport { stripDefault } from '../stripDefault.ts'\n\nimport type { TreeOrder } from '../types.ts'\n\n/**\n * #stateModel Tree\n */\nexport function TreeModelF() {\n return types\n .model({\n /**\n * #property\n */\n drawLabels: stripDefault(types.boolean, defaultDrawLabels),\n /**\n * #property\n * right-align the labels\n */\n labelsAlignRight: stripDefault(types.boolean, defaultLabelsAlignRight),\n\n /**\n * #property\n * width of the area the tree and its labels draw in, px. Undefined fits\n * the area to the labels and the tree; `effectiveTreeAreaWidth` reads\n * the width either way\n */\n treeAreaWidth: types.maybe(types.number),\n\n /**\n * #property\n * width of the tree within the tree area, px. Undefined gives the tree\n * the area less the labels; `effectiveTreeWidth` reads the width either\n * way\n */\n treeWidth: types.maybe(types.number),\n\n /**\n * #property\n * use \"branch length\" e.g. evolutionary distance to draw tree branch\n * lengths. if false, the layout is a \"cladogram\" that does not take into\n * account evolutionary distances\n */\n showBranchLen: stripDefault(types.boolean, defaultShowBranchLen),\n\n /**\n * #property\n * the order each node's children draw in: `branchLength` (shortest\n * first), `input` (as the file gives them), `ladderize` (fewest tips\n * first) or `ladderizeReverse` (most tips first)\n */\n treeOrder: stripDefault(\n types.enumeration<TreeOrder>('TreeOrder', [...treeOrders]),\n defaultTreeOrder,\n ),\n\n /**\n * #property\n * draw tree, boolean\n */\n drawTree: stripDefault(types.boolean, defaultDrawTree),\n\n /**\n * #property\n * draw node bubbles on the tree; the branches stay clickable either way\n */\n drawNodeBubbles: stripDefault(types.boolean, defaultDrawNodeBubbles),\n\n /**\n * #property\n * draw the label a newick file gives an internal node, which is where a\n * bootstrap or posterior support value lands\n */\n drawNodeLabels: stripDefault(types.boolean, defaultDrawNodeLabels),\n\n /**\n * #property\n * draw the whole tree small above the tree panel, with the focused\n * subtree boxed. A click on it focuses the subtree under the pointer\n */\n showTreeOverview: stripDefault(types.boolean, defaultShowTreeOverview),\n\n /**\n * #property\n * height of the tree overview band, px\n */\n overviewHeight: stripDefault(types.number, defaultOverviewHeight),\n })\n .actions(self => ({\n /**\n * #action\n * set the tree area width, px, or undefined to fit it to the labels and\n * the tree. The tree then fills the area less the labels\n */\n setTreeAreaWidth(n: number | undefined) {\n self.treeAreaWidth = n === undefined ? undefined : Math.round(n)\n self.treeWidth = undefined\n },\n /**\n * #action\n * set the tree width, px, or undefined to fill the tree area less the\n * labels\n */\n setTreeWidth(n: number | undefined) {\n self.treeWidth = n === undefined ? undefined : Math.round(n)\n },\n\n /**\n * #action\n */\n setLabelsAlignRight(arg: boolean) {\n self.labelsAlignRight = arg\n },\n /**\n * #action\n */\n setDrawTree(arg: boolean) {\n self.drawTree = arg\n },\n\n /**\n * #action\n */\n setShowBranchLen(arg: boolean) {\n self.showBranchLen = arg\n },\n\n /**\n * #action\n */\n setTreeOrder(order: TreeOrder) {\n self.treeOrder = order\n },\n\n /**\n * #action\n */\n setDrawNodeBubbles(arg: boolean) {\n self.drawNodeBubbles = arg\n },\n /**\n * #action\n */\n setDrawNodeLabels(arg: boolean) {\n self.drawNodeLabels = arg\n },\n /**\n * #action\n */\n setShowTreeOverview(arg: boolean) {\n self.showTreeOverview = arg\n },\n /**\n * #action\n */\n setDrawLabels(arg: boolean) {\n self.drawLabels = arg\n },\n }))\n}\n", "// Neighbor Joining tree construction using BLOSUM62 distances\n// Based on Saitou & Nei (1987) \"The neighbor-joining method\"\n\n// prettier-ignore\nconst BLOSUM62_KEYS = 'ARNDCQEGHILKMFPSTWYVBZX*'\n// prettier-ignore\nconst BLOSUM62_DATA = [\n [ 4,-1,-2,-2, 0,-1,-1, 0,-2,-1,-1,-1,-1,-2,-1, 1, 0,-3,-2, 0,-2,-1, 0,-4],\n [-1, 5, 0,-2,-3, 1, 0,-2, 0,-3,-2, 2,-1,-3,-2,-1,-1,-3,-2,-3,-1, 0,-1,-4],\n [-2, 0, 6, 1,-3, 0, 0, 0, 1,-3,-3, 0,-2,-3,-2, 1, 0,-4,-2,-3, 3, 0,-1,-4],\n [-2,-2, 1, 6,-3, 0, 2,-1,-1,-3,-4,-1,-3,-3,-1, 0,-1,-4,-3,-3, 4, 1,-1,-4],\n [ 0,-3,-3,-3, 9,-3,-4,-3,-3,-1,-1,-3,-1,-2,-3,-1,-1,-2,-2,-1,-3,-3,-2,-4],\n [-1, 1, 0, 0,-3, 5, 2,-2, 0,-3,-2, 1, 0,-3,-1, 0,-1,-2,-1,-2, 0, 3,-1,-4],\n [-1, 0, 0, 2,-4, 2, 5,-2, 0,-3,-3, 1,-2,-3,-1, 0,-1,-3,-2,-2, 1, 4,-1,-4],\n [ 0,-2, 0,-1,-3,-2,-2, 6,-2,-4,-4,-2,-3,-3,-2, 0,-2,-2,-3,-3,-1,-2,-1,-4],\n [-2, 0, 1,-1,-3, 0, 0,-2, 8,-3,-3,-1,-2,-1,-2,-1,-2,-2, 2,-3, 0, 0,-1,-4],\n [-1,-3,-3,-3,-1,-3,-3,-4,-3, 4, 2,-3, 1, 0,-3,-2,-1,-3,-1, 3,-3,-3,-1,-4],\n [-1,-2,-3,-4,-1,-2,-3,-4,-3, 2, 4,-2, 2, 0,-3,-2,-1,-2,-1, 1,-4,-3,-1,-4],\n [-1, 2, 0,-1,-3, 1, 1,-2,-1,-3,-2, 5,-1,-3,-1, 0,-1,-3,-2,-2, 0, 1,-1,-4],\n [-1,-1,-2,-3,-1, 0,-2,-3,-2, 1, 2,-1, 5, 0,-2,-1,-1,-1,-1, 1,-3,-1,-1,-4],\n [-2,-3,-3,-3,-2,-3,-3,-3,-1, 0, 0,-3, 0, 6,-4,-2,-2, 1, 3,-1,-3,-3,-1,-4],\n [-1,-2,-2,-1,-3,-1,-1,-2,-2,-3,-3,-1,-2,-4, 7,-1,-1,-4,-3,-2,-2,-1,-2,-4],\n [ 1,-1, 1, 0,-1, 0, 0, 0,-1,-2,-2, 0,-1,-2,-1, 4, 1,-3,-2,-2, 0, 0, 0,-4],\n [ 0,-1, 0,-1,-1,-1,-1,-2,-2,-1,-1,-1,-1,-2,-1, 1, 5,-2,-2, 0,-1,-1, 0,-4],\n [-3,-3,-4,-4,-2,-2,-3,-2,-2,-3,-2,-3,-1, 1,-4,-3,-2,11, 2,-3,-4,-3,-2,-4],\n [-2,-2,-2,-3,-2,-1,-2,-3, 2,-1,-1,-2,-1, 3,-3,-2,-2, 2, 7,-1,-3,-2,-1,-4],\n [ 0,-3,-3,-3,-1,-2,-2,-3,-3, 3, 1,-2, 1,-1,-2,-2, 0,-3,-1, 4,-3,-2,-1,-4],\n [-2,-1, 3, 4,-3, 0, 1,-1, 0,-3,-4, 0,-3,-3,-2, 0,-1,-4,-3,-3, 4, 1,-1,-4],\n [-1, 0, 0, 1,-3, 3, 4,-2, 0,-3,-3, 1,-1,-3,-1, 0,-1,-3,-2,-2, 1, 4,-1,-4],\n [ 0,-1,-1,-1,-2,-1,-1,-1,-1,-1,-1,-1,-1,-1,-2, 0, 0,-2,-1,-1,-1,-1,-1,-4],\n [-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4,-4, 1],\n]\n\nconst NUM_SYMBOLS = BLOSUM62_KEYS.length\nconst BLOSUM62 = Int8Array.from(BLOSUM62_DATA.flat())\n\n// charCode -> row/column in BLOSUM62, -1 for anything the matrix does not name.\n// On a 120x800 alignment a Map keyed by upper-cased character took 2.6s to\n// build a tree, against 0.34s for this table.\nconst symbolOfCode = new Int8Array(128).fill(-1)\nfor (let i = 0; i < NUM_SYMBOLS; i++) {\n const key = BLOSUM62_KEYS[i]!\n symbolOfCode[key.charCodeAt(0)] = i\n symbolOfCode[key.toLowerCase().charCodeAt(0)] = i\n}\n\n// gap, or past the end of a row shorter than the alignment\nconst GAP = -2\n\n// stockholm and a3m also write gaps as '.'\nfunction symbolAt(seq: string, i: number) {\n if (i >= seq.length) {\n return GAP\n }\n const code = seq.charCodeAt(i)\n // bit trick: (code - 45) >>> 0 <= 1 checks for '-' (45) or '.' (46)\n if ((code - 45) >>> 0 <= 1) {\n return GAP\n }\n return code < 128 ? symbolOfCode[code]! : -1\n}\n\nfunction blosumScore(a: number, b: number) {\n return a < 0 || b < 0 ? -4 : BLOSUM62[a * NUM_SYMBOLS + b]!\n}\n\nfunction computePairwiseDistance(seq1: string, seq2: string) {\n // a3m and hand-edited fasta produce short rows; past its end a row counts as\n // gapped, as in the model's `blanks` getter\n const len = Math.max(seq1.length, seq2.length)\n let compared = 0\n let totalScore = 0\n let maxPossibleScore = 0\n\n for (let i = 0; i < len; i++) {\n const a = symbolAt(seq1, i)\n const b = symbolAt(seq2, i)\n\n const aGap = a === GAP\n const bGap = b === GAP\n if (aGap && bGap) {\n continue\n }\n\n compared++\n if (aGap || bGap) {\n continue\n }\n\n totalScore += blosumScore(a, b)\n maxPossibleScore += Math.max(blosumScore(a, a), blosumScore(b, b))\n }\n\n if (compared === 0) {\n return 1\n }\n\n if (maxPossibleScore <= 0) {\n return 1\n }\n\n const normalizedScore = totalScore / maxPossibleScore\n const clampedScore = Math.max(0.01, Math.min(1, normalizedScore))\n\n // Kimura-like correction: d = -ln(similarity)\n return -Math.log(clampedScore)\n}\n\nfunction computeDistanceMatrix(rows: readonly [string, string][]) {\n const n = rows.length\n const distances: number[][] = []\n\n for (let i = 0; i < n; i++) {\n distances[i] = []\n for (let j = 0; j < n; j++) {\n if (i === j) {\n distances[i]![j] = 0\n } else if (j < i) {\n distances[i]![j] = distances[j]![i]!\n } else {\n distances[i]![j] = computePairwiseDistance(rows[i]![1], rows[j]![1])\n }\n }\n }\n\n return distances\n}\n\ninterface NJNode {\n name?: string\n left?: NJNode\n right?: NJNode\n leftLength?: number\n rightLength?: number\n}\n\nfunction neighborJoining(distances: number[][], names: string[]): NJNode {\n const n = distances.length\n if (n < 2) {\n return { name: names[0] }\n }\n if (n === 2) {\n const d = distances[0]![1]!\n return {\n left: { name: names[0] },\n right: { name: names[1] },\n leftLength: d / 2,\n rightLength: d / 2,\n }\n }\n\n const D: number[][] = []\n for (let i = 0; i < n; i++) {\n D[i] = [...distances[i]!]\n }\n const nodes: (NJNode | undefined)[] = names.map(name => ({ name }))\n\n let remaining = n\n\n while (remaining > 2) {\n const active: number[] = []\n for (let i = 0; i < nodes.length; i++) {\n if (nodes[i] !== undefined) {\n active.push(i)\n }\n }\n\n const r = new Map<number, number>()\n for (const i of active) {\n let sum = 0\n for (const j of active) {\n if (i !== j) {\n sum += D[i]![j]!\n }\n }\n r.set(i, sum)\n }\n\n let minQ = Infinity\n let minI = -1\n let minJ = -1\n\n for (let ai = 0; ai < active.length; ai++) {\n for (let aj = ai + 1; aj < active.length; aj++) {\n const i = active[ai]!\n const j = active[aj]!\n const q = (remaining - 2) * D[i]![j]! - r.get(i)! - r.get(j)!\n\n if (q < minQ) {\n minQ = q\n minI = i\n minJ = j\n }\n }\n }\n\n const dij = D[minI]![minJ]!\n const ri = r.get(minI)!\n const rj = r.get(minJ)!\n\n let limbI = dij / 2 + (ri - rj) / (2 * (remaining - 2))\n let limbJ = dij - limbI\n\n limbI = Math.max(0, limbI)\n limbJ = Math.max(0, limbJ)\n\n const newNode: NJNode = {\n left: nodes[minI],\n right: nodes[minJ],\n leftLength: limbI,\n rightLength: limbJ,\n }\n\n // the merged node reuses minI's slot\n for (const k of active) {\n if (k !== minI && k !== minJ) {\n const newDist = (D[minI]![k]! + D[minJ]![k]! - dij) / 2\n D[minI]![k] = Math.max(0, newDist)\n D[k]![minI] = Math.max(0, newDist)\n }\n }\n\n nodes[minJ] = undefined\n nodes[minI] = newNode\n\n remaining--\n }\n\n const finalActive: number[] = []\n for (let i = 0; i < nodes.length; i++) {\n if (nodes[i] !== undefined) {\n finalActive.push(i)\n }\n }\n\n if (finalActive.length === 2) {\n const i = finalActive[0]!\n const j = finalActive[1]!\n const d = D[i]![j]!\n return {\n left: nodes[i],\n right: nodes[j],\n leftLength: d / 2,\n rightLength: d / 2,\n }\n }\n\n return nodes[finalActive[0]!]!\n}\n\nfunction withBranchLength(newick: string, branchLength?: number) {\n return branchLength === undefined\n ? newick\n : `${newick}:${branchLength.toFixed(6)}`\n}\n\n// iterative: an NJ tree of N leaves can be a caterpillar of depth ~N\nfunction nodeToNewick(root: NJNode): string {\n const postOrder: NJNode[] = []\n const stack: NJNode[] = [root]\n while (stack.length > 0) {\n const node = stack.pop()!\n postOrder.push(node)\n if (node.left) {\n stack.push(node.left)\n }\n if (node.right) {\n stack.push(node.right)\n }\n }\n\n const newickByNode = new Map<NJNode, string>()\n for (let i = postOrder.length - 1; i >= 0; i--) {\n const node = postOrder[i]!\n if (node.name !== undefined && !node.left && !node.right) {\n newickByNode.set(node, `'${node.name.replaceAll(\"'\", \"''\")}'`)\n } else {\n const left = node.left\n ? withBranchLength(newickByNode.get(node.left)!, node.leftLength)\n : ''\n const right = node.right\n ? withBranchLength(newickByNode.get(node.right)!, node.rightLength)\n : ''\n newickByNode.set(node, `(${left},${right})`)\n }\n }\n return newickByNode.get(root)!\n}\n\nexport function calculateNeighborJoiningTree(\n rows: readonly [string, string][],\n) {\n if (rows.length < 2) {\n throw new Error('Need at least 2 sequences to build a tree')\n }\n\n const names = rows.map(r => r[0])\n const distances = computeDistanceMatrix(rows)\n const tree = neighborJoining(distances, names)\n\n return nodeToNewick(tree) + ';'\n}\n", "export interface ASNNode {\n id: number\n parent?: number\n features?: ASNFeature[]\n}\n\nexport interface ASNFeature {\n featureid: number\n value: string\n}\n\nexport interface ASNDictEntry {\n id: number\n name: string\n}\n\nexport interface BioTreeContainer {\n fdict: ASNDictEntry[]\n nodes: ASNNode[]\n}\n\nconst remap: Record<string, string> = {\n $NODE_COLLAPSED: 'collapsed',\n $NODE_COLOR: 'color',\n $LABEL_BG_COLOR: 'color',\n 'seq-id': 'seqId',\n 'seq-title': 'seqTitle',\n 'align-index': 'alignIndex',\n 'accession-nbr': 'accessionNbr',\n 'blast-name': 'blastName',\n 'common-name': 'commonName',\n 'leaf-count': 'leafCount',\n}\n\n// index just past the '}' closing the '{' at openIdx, or -1 when it never\n// closes. Braces nest (a node holds features, which hold values), so finding the\n// end of a block means counting depth rather than taking the next '}'.\nfunction afterMatchingBrace(str: string, openIdx: number) {\n let depth = 1\n let pos = openIdx + 1\n while (pos < str.length && depth > 0) {\n if (str[pos] === '{') {\n depth++\n } else if (str[pos] === '}') {\n depth--\n }\n pos++\n }\n return depth === 0 ? pos : -1\n}\n\n// the contents of each top-level {...} block in str, siblings only\nfunction extractBracedBlocks(str: string): string[] {\n const blocks: string[] = []\n let pos = 0\n while (pos < str.length) {\n const openIdx = str.indexOf('{', pos)\n if (openIdx === -1) {\n break\n }\n const end = afterMatchingBrace(str, openIdx)\n if (end === -1) {\n break\n }\n blocks.push(str.slice(openIdx + 1, end - 1).trim())\n pos = end\n }\n return blocks\n}\n\nfunction findBracedContent(str: string, after: number) {\n const openIdx = str.indexOf('{', after)\n if (openIdx === -1) {\n return undefined\n }\n const end = afterMatchingBrace(str, openIdx)\n return end === -1 ? undefined : str.slice(openIdx + 1, end - 1).trim()\n}\n\nexport function parseAsn1(\n asnString: string,\n): { id: number; parent: number; name: string }[] {\n const normalized = asnString\n .replace(/\\s+/g, ' ')\n .replace(/\\s*{\\s*/g, '{')\n .replace(/\\s*}\\s*/g, '}')\n .replace(/\\s*,\\s*/g, ',')\n .replace(/\\s*::\\s*=\\s*/g, '::=')\n .replace(/^.*?::=/, '')\n\n const sections = extractSections(normalized)\n const { fdict, nodes } = sections\n if (fdict === undefined || nodes === undefined) {\n // a truncated/malformed BioTreeContainer would otherwise pass undefined to\n // extractBracedBlocks and crash cryptically; fail with a clear message\n throw new Error(\n `invalid BioTreeContainer ASN.1: missing '${fdict === undefined ? 'fdict' : 'nodes'}' section`,\n )\n }\n\n const dict = Object.fromEntries(\n extractBracedBlocks(fdict).flatMap(block => {\n const entry = parseDictEntry(block)\n return entry ? [[entry.id, remap[entry.name] || entry.name]] : []\n }),\n )\n\n return extractBracedBlocks(nodes).flatMap(block => {\n const node = parseNode(block)\n if (!node) {\n return []\n }\n const { features = [], ...rest } = node\n return [\n {\n ...rest,\n ...Object.fromEntries(\n features.map(f => [dict[f.featureid], f.value] as const),\n ),\n } as { id: number; parent: number; name: string },\n ]\n })\n}\n\nfunction extractSections(asnString: string): Record<string, string> {\n const sections: Record<string, string> = {}\n let content = asnString.trim()\n if (content.startsWith('{') && content.endsWith('}')) {\n content = content.slice(1, -1).trim()\n }\n\n let pos = 0\n while (pos < content.length) {\n while (pos < content.length && /\\s/.test(content[pos]!)) {\n pos++\n }\n if (pos >= content.length) {\n break\n }\n\n const nameStart = pos\n while (pos < content.length && /\\w/.test(content[pos]!)) {\n pos++\n }\n\n if (\n pos >= content.length ||\n (content[pos] !== ' ' && content[pos] !== '{')\n ) {\n pos = content.indexOf(',', pos)\n pos = pos === -1 ? content.length : pos + 1\n continue\n }\n\n const name = content.slice(nameStart, pos).trim()\n\n while (pos < content.length && /\\s/.test(content[pos]!)) {\n pos++\n }\n\n if (pos >= content.length || content[pos] !== '{') {\n pos = content.indexOf(',', pos)\n pos = pos === -1 ? content.length : pos + 1\n continue\n }\n\n const end = afterMatchingBrace(content, pos)\n if (end === -1) {\n break\n }\n sections[name] = content.slice(pos + 1, end - 1).trim()\n\n pos = content.indexOf(',', end)\n pos = pos === -1 ? content.length : pos + 1\n }\n\n return sections\n}\n\nfunction parseDictEntry(entryString: string): ASNDictEntry | null {\n const idMatch = /id\\s+(\\d+)/.exec(entryString)\n const nameMatch = /name\\s+\"((?:[^\"\\\\]|\\\\.)*)\"/s.exec(entryString)\n if (!idMatch || !nameMatch) {\n return null\n }\n return {\n id: parseInt(idMatch[1]!, 10),\n name: nameMatch[1]!.replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\'),\n }\n}\n\nfunction parseNode(nodeString: string): ASNNode | null {\n const idMatch = /id\\s+(\\d+)/.exec(nodeString)\n if (!idMatch) {\n return null\n }\n const parentMatch = /parent\\s+(\\d+)/.exec(nodeString)\n const featuresIdx = nodeString.indexOf('features')\n const featuresContent =\n featuresIdx !== -1 ? findBracedContent(nodeString, featuresIdx) : undefined\n\n return {\n id: parseInt(idMatch[1]!, 10),\n ...(parentMatch ? { parent: parseInt(parentMatch[1]!, 10) } : {}),\n features: featuresContent\n ? extractBracedBlocks(featuresContent).flatMap(block => {\n const f = parseFeature(block)\n return f ? [f] : []\n })\n : [],\n }\n}\n\nfunction parseFeature(featureString: string): ASNFeature | null {\n const featureidMatch = /featureid\\s+(\\d+)/.exec(featureString)\n const valueMatch = /value\\s+\"((?:[^\"\\\\]|\\\\.)*)\"/s.exec(featureString)\n if (!featureidMatch || !valueMatch) {\n return null\n }\n return {\n featureid: parseInt(featureidMatch[1]!, 10),\n value: valueMatch[1]!.replace(/\\\\\"/g, '\"').replace(/\\\\\\\\/g, '\\\\'),\n }\n}\n", "import { numResidueSlots, residueSlotOfLetter } from './columnCounts.ts'\n\nimport type { ColumnCounts } from './columnCounts.ts'\n\n// Disjoint physicochemical classes for the 20 standard amino acids. Property\n// conservation asks a different question than identity conservation: a column\n// can vary in exact residue yet stay within one property class (a conservative\n// substitution), which often marks a functionally constrained site that plain\n// identity conservation reports as variable.\n//\n// Histidine is grouped with the aromatics (it is only weakly/conditionally\n// positive at physiological pH); this mirrors common substitution-class schemes.\nconst aminoPropertyClass: Record<string, string> = {\n A: 'hydrophobic',\n V: 'hydrophobic',\n L: 'hydrophobic',\n I: 'hydrophobic',\n M: 'hydrophobic',\n C: 'hydrophobic',\n F: 'aromatic',\n W: 'aromatic',\n Y: 'aromatic',\n H: 'aromatic',\n K: 'positive',\n R: 'positive',\n D: 'negative',\n E: 'negative',\n S: 'polar',\n T: 'polar',\n N: 'polar',\n Q: 'polar',\n G: 'special',\n P: 'special',\n}\n\nconst propertyClasses = [...new Set(Object.values(aminoPropertyClass))]\nconst maxPropertyEntropy = Math.log2(propertyClasses.length)\n\n// residue slot -> index into propertyClasses (-1 for residues with no class,\n// e.g. X or '*'), so the per-column tally needs no string lookups\nconst classOfSlot = new Int8Array(numResidueSlots).fill(-1)\nfor (const [letter, cls] of Object.entries(aminoPropertyClass)) {\n classOfSlot[residueSlotOfLetter(letter)] = propertyClasses.indexOf(cls)\n}\n\n/**\n * Per-column property conservation using Shannon entropy over physicochemical\n * classes rather than exact residues. Returns 0-1 where 1 = every non-gap\n * residue shares one property class. Mirrors the identity-conservation formula\n * so the two tracks are directly comparable: (1 - H/Hmax) * (1 - gapFraction).\n */\nexport function calculatePropertyConservation(counts: ColumnCounts) {\n const classCounts = new Float64Array(propertyClasses.length)\n return Array.from({ length: counts.numColumns }, (_, col) => {\n const total = counts.total(col)\n let score = 0\n if (total) {\n classCounts.fill(0)\n let nonGapTotal = 0\n counts.forEachResidue(col, (slot, count) => {\n const cls = classOfSlot[slot]!\n if (cls >= 0) {\n classCounts[cls]! += count\n nonGapTotal += count\n }\n })\n if (nonGapTotal > 0) {\n let entropy = 0\n for (const count of classCounts) {\n if (count > 0) {\n const freq = count / nonGapTotal\n entropy -= freq * Math.log2(freq)\n }\n }\n const gapFraction = (total - nonGapTotal) / total\n score =\n Math.max(0, 1 - entropy / maxPropertyEntropy) * (1 - gapFraction)\n }\n }\n return score\n })\n}\n", "/**\n * Rerooting over the plain node `parseNewick` produces, the shape\n * `@gmod/newick` and jbrowse-components' tree sidebar share, so these can move\n * into that package unchanged.\n *\n * Every traversal is iterative, for the reason the ones in `@gmod/newick` are: a\n * caterpillar tree is as deep as it has leaves, and recursion overflows the\n * stack past about 5000 of them.\n */\nexport interface TreeNode {\n name?: string\n length?: number\n children?: TreeNode[]\n}\n\nfunction preorder<N extends TreeNode>(root: N) {\n const order: N[] = []\n const parents = new Map<N, N>()\n const stack = [root]\n while (stack.length > 0) {\n const node = stack.pop()!\n order.push(node)\n for (const child of (node.children ?? []) as N[]) {\n parents.set(child, node)\n stack.push(child)\n }\n }\n return { order, parents }\n}\n\nfunction hasLengths(order: TreeNode[]) {\n return order.some(n => n.length !== undefined)\n}\n\n// the root's two children make one branch of the unrooted tree, which is the\n// branch a rerooting at either of them splits\nfunction mergedSibling<N extends TreeNode>(root: N, target: N) {\n return root.children?.length === 2\n ? (root.children.find(c => c !== target) as N | undefined)\n : undefined\n}\n\n/**\n * The tree rooted on the branch above `target`, `offset` up from it, or at the\n * middle of that branch without one. Where the root has two children, their\n * branches are one branch of the unrooted tree, and `offset` runs across both.\n *\n * The nodes between `target` and the old root turn over. A name on one of them\n * labels the branch above it, which is where a support value sits, so the name\n * follows that branch to the node now at its lower end. A two-child root has\n * nothing left to split once one child leaves, so it drops out and its\n * branches join.\n */\nexport function rerootTree<N extends TreeNode>(\n root: N,\n target: N,\n offset?: number,\n): TreeNode {\n const { order, parents } = preorder(root)\n if (!parents.has(target)) {\n return root\n }\n const lengths = hasLengths(order)\n const sibling =\n parents.get(target) === root ? mergedSibling(root, target) : undefined\n const branch = (target.length ?? 0) + (sibling?.length ?? 0)\n const at = Math.min(Math.max(offset ?? branch / 2, 0), branch)\n const length = (n: number) => (lengths ? n : undefined)\n\n const path = [target]\n for (let n = parents.get(target); n; n = parents.get(n)) {\n path.push(n)\n }\n // Built from the old root down, so the node each turned node now hangs\n // `above` it already exists. undefined where the old root dropped out.\n let above: TreeNode | undefined\n for (let i = path.length - 1; i >= 1; i--) {\n const node = path[i]!\n const below = path[i - 1]!\n const children = node.children!.filter(c => c !== below)\n if (above) {\n children.push(above)\n }\n if (children.length === 0) {\n above = undefined\n } else if (i === path.length - 1 && children.length === 1) {\n const only = children[0]!\n above = {\n ...only,\n length: length(\n (only.length ?? 0) + (below.length ?? 0) - (i === 1 ? at : 0),\n ),\n }\n } else {\n above = {\n ...node,\n name: i === 1 ? undefined : below.name,\n children,\n length: length((below.length ?? 0) - (i === 1 ? at : 0)),\n }\n }\n }\n return {\n children: [{ ...target, length: length(at) }, ...(above ? [above] : [])],\n }\n}\n\n/**\n * The tree rooted halfway along the longest path between two tips, which is\n * where a clock would put the root: the usual choice for the unrooted tree\n * FastTree, IQ-TREE or neighbor joining writes. A tree with no branch lengths\n * counts branches.\n */\nexport function midpointRoot<N extends TreeNode>(root: N): TreeNode {\n const { order, parents } = preorder(root)\n const tips = order.filter(n => !n.children?.length)\n if (tips.length < 2) {\n return root\n }\n const lengths = hasLengths(order)\n const weight = (n: N) => (lengths ? (n.length ?? 0) : 1)\n\n // distance from `from` to every node over the unrooted tree, and the\n // neighbor each was reached through\n function reach(from: N) {\n const dist = new Map<N, number>([[from, 0]])\n const via = new Map<N, N>()\n const stack = [from]\n while (stack.length > 0) {\n const node = stack.pop()!\n const d = dist.get(node)!\n const parent = parents.get(node)\n if (parent && !dist.has(parent)) {\n dist.set(parent, d + weight(node))\n via.set(parent, node)\n stack.push(parent)\n }\n for (const child of (node.children ?? []) as N[]) {\n if (!dist.has(child)) {\n dist.set(child, d + weight(child))\n via.set(child, node)\n stack.push(child)\n }\n }\n }\n return { dist, via }\n }\n function farthest(dist: Map<N, number>) {\n return tips.reduce((best, tip) =>\n dist.get(tip)! > dist.get(best)! ? tip : best,\n )\n }\n\n const a = farthest(reach(tips[0]!).dist)\n const { dist, via } = reach(a)\n const b = farthest(dist)\n if (b === a) {\n return root\n }\n const half = dist.get(b)! / 2\n let node = b\n let next = via.get(node)!\n while (dist.get(next)! > half) {\n node = next\n next = via.get(node)!\n }\n // the midpoint lies on the branch between `node` and `next`, and whichever\n // of them is the child carries that branch\n return parents.get(node) === next\n ? rerootTree(root, node, dist.get(node)! - half)\n : rerootTree(root, next, half - dist.get(next)!)\n}\n", "/**\n * MSA Coordinate Systems:\n *\n * 1. **Global Column (globalCol)**: The column index in the full, unfiltered MSA.\n * Range: 0 to (MSA width - 1)\n * This is the \"true\" column position before any gap-hiding is applied.\n *\n * 2. **Visible Column (visibleCol)**: The column index after hiding gappy columns.\n * Range: 0 to (numColumns - 1) where numColumns = MSA width - blanks.length\n * This is what the user sees on screen when \"Hide columns w/ N% gaps\" is enabled.\n * When gap hiding is disabled, visibleCol === globalCol.\n *\n * 3. **Sequence Position (seqPos)**: The position within a specific row's ungapped sequence.\n * Range: 0 to (ungapped sequence length - 1)\n * This counts only non-gap characters ('-' and '.' are gaps).\n * Each row can have different seqPos values for the same globalCol due to gaps.\n */\n\n/**\n * Index of the first element in `[0, len)` for which `pred` holds, over a range\n * where `pred` is false up to some point and true from there on. Both\n * conversions below are that shape, since `blanks` is sorted ascending.\n */\nfunction partitionPoint(len: number, pred: (i: number) => boolean) {\n let left = 0\n let right = len\n while (left < right) {\n const mid = (left + right) >>> 1\n if (pred(mid)) {\n right = mid\n } else {\n left = mid + 1\n }\n }\n return left\n}\n\n/**\n * Convert a visible column index to a global column index.\n * This is used when translating mouse/screen coordinates to MSA coordinates.\n *\n * @param blanks - Sorted array of global column indices that are hidden\n * @param visibleCol - The visible column index (what the user sees on screen)\n * @returns The corresponding global column index in the full MSA\n */\nexport function visibleColToGlobalCol(blanks: number[], visibleCol: number) {\n // `blanks[i] - i` counts the visible columns before the i-th blank, so the\n // first blank with more than visibleCol of them in front of it is the first\n // one sitting past this column. Its index is how many blanks shift it right.\n return (\n visibleCol + partitionPoint(blanks.length, i => blanks[i]! - i > visibleCol)\n )\n}\n\n/**\n * Convert a global column index to a visible column index.\n * This is the inverse of visibleColToGlobalCol.\n *\n * @param blanks - Sorted array of global column indices that are hidden\n * @param globalCol - The global column index in the full MSA\n * @returns The visible column index, or undefined if the column is hidden\n */\nexport function globalColToVisibleCol(\n blanks: number[],\n globalCol: number,\n): number | undefined {\n const blanksBefore = countBlanksBefore(blanks, globalCol)\n return blanks[blanksBefore] === globalCol\n ? undefined // Column is hidden\n : globalCol - blanksBefore\n}\n\nfunction countBlanksBefore(blanks: number[], globalCol: number) {\n return partitionPoint(blanks.length, i => blanks[i]! >= globalCol)\n}\n\n/**\n * How many visible columns come before a global column. For a visible column\n * that is its own visible index; for a hidden one it is the index of the next\n * visible column, i.e. where the hidden column collapses to.\n *\n * Spans use this, since globalColToVisibleCol drops a span whenever either end\n * lands in a hidden column.\n *\n * @param blanks - Sorted array of global column indices that are hidden\n * @param globalCol - The global column index in the full MSA\n */\nexport function visibleColsBefore(blanks: number[], globalCol: number) {\n return globalCol - countBlanksBefore(blanks, globalCol)\n}\n\n/**\n * The ungapped position a row holds at a global column, or undefined when that\n * column is a gap in the row or past its end.\n *\n * Binary-searches the row's ascending seqPos index; it runs on every mouse\n * move, and scanning a 30k-column row per event takes the whole frame.\n *\n * @param index - The row's seqPos -> global column index (buildSeqPosIndex)\n * @param globalCol - The global column index in the full MSA\n */\nexport function seqPosOfGlobalCol(\n index: Int32Array | undefined,\n globalCol: number,\n) {\n if (!index) {\n return undefined\n }\n const seqPos = partitionPoint(index.length, i => index[i]! >= globalCol)\n return index[seqPos] === globalCol ? seqPos : undefined\n}\n", "import { createPaletteMap } from './createPaletteMap.ts'\nimport { paletteNamed } from './ggplotPalettes.ts'\n\nimport type { LegendEntry } from './types.ts'\n\n/** how a channel reads a field: a palette by name, or a color per value */\nexport interface ScaleSpec {\n palette?: string\n map?: Record<string, string>\n}\n\nexport interface ResolvedScale {\n kind: 'categorical'\n colorOf: (value: string) => string | undefined\n legend: LegendEntry[]\n}\n\n/**\n * The scale a channel reads its field through. `values` are the field's values,\n * in any order and with repeats; the domain is their distinct values sorted, so\n * a value keeps its color when rows are re-ordered, collapsed or filtered.\n *\n * `{map}` colors the values the producer named and leaves the rest uncolored.\n * `{palette}` takes the colors of a named palette, and a spec with neither\n * takes the ggplot palette of the domain's size. Every scale is categorical\n * today; a continuous one waits for a caller.\n */\nexport function resolveScale(\n spec: ScaleSpec | undefined,\n values: Iterable<string>,\n): ResolvedScale {\n const domain = [...new Set(values)].sort((a, b) => a.localeCompare(b))\n const { map, palette } = spec ?? {}\n const colors = map ?? createPaletteMap(domain, paletteNamed(palette))\n const present = new Set(domain)\n const labels = map ? Object.keys(map).filter(v => present.has(v)) : domain\n return {\n kind: 'categorical',\n colorOf: (value: string) => colors[value],\n // a categorical value is its own label, and the id a legend keys on\n legend: labels.map(value => ({\n id: value,\n label: value,\n color: colors[value]!,\n })),\n }\n}\n", "/**\n * The global column of every ungapped sequence position in a row, i.e.\n * index[seqPos] is the column holding the seqPos-th non-gap character.\n *\n * The domain overlay resolves one position per feature per row on every redraw,\n * and scanning the row for each would be quadratic.\n *\n * @example\n * // Row: \"A-TG-C\" (A at 0, T at 2, G at 3, C at 5)\n * buildSeqPosIndex('A-TG-C') // \u2192 [0, 2, 3, 5]\n */\nexport function buildSeqPosIndex(row: string) {\n const index = new Int32Array(row.length)\n let n = 0\n for (let col = 0; col < row.length; col++) {\n // bit trick: (code - 45) >>> 0 <= 1 checks for '-' (45) or '.' (46)\n if (!((row.charCodeAt(col) - 45) >>> 0 <= 1)) {\n index[n++] = col\n }\n }\n // slice, not subarray: a subarray keeps the whole row-length buffer alive,\n // and a gappy alignment's indexes are held for as long as the parse is\n return index.slice(0, n)\n}\n", "import { measureTextCanvas } from './measureTextCanvas.ts'\n\nimport type { NodeWithIds } from './types.ts'\n\n// A label's width follows its length closely enough that the widest one is\n// among the longest few, so a 230k-tip tree measures this many strings.\nconst measuredLabels = 100\n\n/** the leaf names of a tree, and its depth in levels from the root */\nexport function treeTips(tree: NodeWithIds) {\n const names: string[] = []\n let depth = 0\n const stack: [NodeWithIds, number][] = [[tree, 0]]\n for (let entry = stack.pop(); entry; entry = stack.pop()) {\n const [node, level] = entry\n const { children } = node\n if (children.length > 0) {\n for (const child of children) {\n stack.push([child, level + 1])\n }\n } else {\n names.push(node.name)\n depth = Math.max(depth, level)\n }\n }\n return { names, depth }\n}\n\n/** the width of the widest label at `fontSize`, measuring the longest few */\nexport function widestLabel(labels: string[], fontSize: number) {\n const counts: number[] = []\n for (const label of labels) {\n counts[label.length] = (counts[label.length] ?? 0) + 1\n }\n let shortest = counts.length\n for (let seen = 0; shortest > 0 && seen < measuredLabels;) {\n shortest--\n seen += counts[shortest] ?? 0\n }\n let widest = 0\n let ties = 0\n for (const label of labels) {\n if (\n label.length > shortest ||\n (label.length === shortest && ties++ < measuredLabels)\n ) {\n widest = Math.max(widest, measureTextCanvas(label, fontSize))\n }\n }\n return widest\n}\n", "import { descendants } from './hierarchy.ts'\n\nimport type { HierarchyNode } from './hierarchy.ts'\n\n// a name holding any of these reads back as grammar unless it is quoted\nconst needsQuotes = /[\\s(),:;[\\]']/\n\nfunction quote(name: string) {\n return needsQuotes.test(name) ? `'${name.replaceAll(\"'\", \"''\")}'` : name\n}\n\n/**\n * The tree as Newick, in the order it is drawn. An internal node whose name is\n * only its generated id goes unnamed. Each subtree's string is dropped once its\n * parent takes it in, since a caterpillar tree is as deep as it has tips and\n * keeping every one is quadratic.\n */\nexport function writeNewick(root: HierarchyNode) {\n const written = new Map<HierarchyNode, string>()\n for (const node of descendants(root).reverse()) {\n const { id, name, length } = node.data\n let text = ''\n if (node.children) {\n text = `(${node.children.map(c => written.get(c)!).join(',')})`\n for (const child of node.children) {\n written.delete(child)\n }\n }\n if (!(node.children && name === id)) {\n text += quote(name)\n }\n if (length !== undefined) {\n text += `:${length}`\n }\n written.set(node, text)\n }\n return `${written.get(root)!};`\n}\n", "// WUSS notation (Rfam's `#=GC SS_cons`) names a consensus secondary structure\n// by pairing columns. Nested helices use bracket pairs -- <>, (), [], {} --\n// each type kept on its own stack, and a pseudoknot, which by definition\n// crosses a helix it cannot nest inside, uses a letter pair instead: `A` opens\n// and `a` closes, `B`/`b` for a second one. Everything else (. , _ - : ~) is\n// unpaired.\n\nconst closeToOpen: Record<string, string> = {\n '>': '<',\n ')': '(',\n ']': '[',\n '}': '{',\n}\nconst opens = new Set(Object.values(closeToOpen))\n\nexport interface BasePair {\n /** 0-based column */\n start: number\n /** 0-based column */\n end: number\n /** the pair crosses a helix rather than nesting inside one */\n pseudoknot: boolean\n}\n\n/**\n * The base pairs a WUSS string encodes, as 0-based column indexes. Unmatched\n * brackets are dropped rather than throwing: a hand-edited or truncated\n * alignment should still draw the helices it does close.\n */\nexport function parseWuss(ss: string): BasePair[] {\n const stacks = new Map<string, number[]>()\n const pairs: BasePair[] = []\n const push = (key: string, col: number) => {\n const stack = stacks.get(key)\n if (stack) {\n stack.push(col)\n } else {\n stacks.set(key, [col])\n }\n }\n const pop = (key: string, col: number, pseudoknot: boolean) => {\n const start = stacks.get(key)?.pop()\n if (start !== undefined) {\n pairs.push({ start, end: col, pseudoknot })\n }\n }\n\n for (let col = 0; col < ss.length; col++) {\n const ch = ss[col]!\n const opener = closeToOpen[ch]\n if (opens.has(ch)) {\n push(ch, col)\n } else if (opener) {\n pop(opener, col, false)\n } else if (ch >= 'A' && ch <= 'Z') {\n push(ch, col)\n } else if (ch >= 'a' && ch <= 'z') {\n pop(ch.toUpperCase(), col, true)\n }\n }\n return pairs.sort((a, b) => a.start - b.start)\n}\n", "import { createJBrowseTheme } from '@jbrowse/core/ui/theme'\n\nimport type { MSAViewerProps } from './components/MSAViewer.tsx'\nimport type { ColorScheme, Highlight } from './types.ts'\n\nexport function colorSchemeSnapshot(scheme: ColorScheme | undefined) {\n return typeof scheme === 'string'\n ? { colorSchemeName: scheme }\n : scheme\n ? { customColorScheme: scheme.map }\n : {}\n}\n\n/**\n * The `highlightColumns` prop as `highlights`: one `{start, end}` per run of\n * adjacent 1-based alignment columns\n */\nexport function columnHighlights(columns: number[] = []) {\n const sorted = [...new Set(columns)].sort((a, b) => a - b)\n const runs: { start: number; end: number }[] = []\n for (const column of sorted) {\n const last = runs.at(-1)\n if (last?.end === column - 1) {\n last.end = column\n } else {\n runs.push({ start: column, end: column })\n }\n }\n return runs\n}\n\nexport function viewerHighlights({\n highlights = [],\n highlightColumns,\n}: Pick<MSAViewerProps, 'highlights' | 'highlightColumns'>): Highlight[] {\n return [...highlights, ...columnHighlights(highlightColumns)]\n}\n\nfunction urlLocation(uri: string | undefined) {\n return uri ? { uri, locationType: 'UriLocation' as const } : undefined\n}\n\n/** each filehandle prop, or the URL prop standing in for it */\nexport function fileLocations({\n msaFilehandle,\n treeFilehandle,\n gffFilehandle,\n msaUrl,\n treeUrl,\n gffUrl,\n}: MSAViewerProps) {\n return {\n msaFilehandle: msaFilehandle ?? urlLocation(msaUrl),\n treeFilehandle: treeFilehandle ?? urlLocation(treeUrl),\n gffFilehandle: gffFilehandle ?? urlLocation(gffUrl),\n }\n}\n\nexport function resolveTheme(theme: MSAViewerProps['theme']) {\n return createJBrowseTheme(\n theme === 'dark'\n ? { palette: { mode: 'dark' } }\n : typeof theme === 'object'\n ? theme\n : undefined,\n )\n}\n\n/**\n * The model snapshot `MSAViewer` creates from its props. The CLI's `--props`\n * reads the same JSON the R and Python widgets send, so a figure exported\n * headlessly draws what the widget drew.\n */\nexport function viewerSnapshot(props: MSAViewerProps) {\n const {\n msa,\n tree,\n gff,\n rowData,\n colorScheme,\n height,\n colWidth,\n rowHeight,\n allowedGappyness,\n highlightColumns,\n highlights,\n features,\n selection,\n clades,\n relativeTo,\n columnTracks,\n residueMappings,\n encodings,\n rowPanels,\n drawTree,\n treeAreaWidth,\n showBranchLen,\n treeOrder,\n treeRoot,\n region,\n residueEncoding,\n } = props\n const { msaFilehandle, treeFilehandle, gffFilehandle } = fileLocations(props)\n return {\n type: 'MsaView' as const,\n ...(msa || tree || gff || rowData\n ? {\n data: {\n msa: msa ?? '',\n tree: tree ?? '',\n gff,\n // the row table is stored as this JSON string, which is what a\n // shared URL and the size limit already cover\n ...(rowData ? { treeMetadata: JSON.stringify(rowData) } : {}),\n },\n }\n : {}),\n ...(msaFilehandle ? { msaFilehandle } : {}),\n ...(treeFilehandle ? { treeFilehandle } : {}),\n ...(gffFilehandle ? { gffFilehandle } : {}),\n ...colorSchemeSnapshot(colorScheme),\n ...(height ? { height } : {}),\n ...(colWidth ? { colWidth } : {}),\n ...(rowHeight ? { rowHeight } : {}),\n ...(allowedGappyness !== undefined ? { allowedGappyness } : {}),\n ...(highlights || highlightColumns\n ? { highlights: viewerHighlights({ highlights, highlightColumns }) }\n : {}),\n ...(features ? { features } : {}),\n ...(selection ? { selection } : {}),\n ...(clades ? { clades } : {}),\n ...(relativeTo ? { relativeTo } : {}),\n ...(columnTracks ? { columnTracks } : {}),\n ...(residueMappings ? { residueMappings } : {}),\n ...(encodings ? { encodings } : {}),\n ...(rowPanels ? { rowPanels } : {}),\n ...(drawTree !== undefined ? { drawTree } : {}),\n ...(treeAreaWidth ? { treeAreaWidth } : {}),\n ...(showBranchLen !== undefined ? { showBranchLen } : {}),\n ...(treeOrder ? { treeOrder } : {}),\n ...(treeRoot ? { treeRoot } : {}),\n ...(region ? { region } : {}),\n ...(residueEncoding !== undefined\n ? { bgColor: residueEncoding === 'fill' }\n : {}),\n }\n}\n", "import React from 'react'\n\nimport { createRoot } from 'react-dom/client'\n\nimport MSAViewer from './components/MSAViewer.tsx'\n\nimport type { MSAViewerProps } from './components/MSAViewer.tsx'\n\nexport interface MountedViewer {\n /** merge new props over the current ones */\n update: (props: Partial<MSAViewerProps>) => void\n destroy: () => void\n}\n\n/**\n * Render MSAViewer into an element, for a host that is not a React app: a\n * script tag, an R htmlwidget, a notebook widget, a custom element.\n */\nexport function mount(el: HTMLElement, props: MSAViewerProps): MountedViewer {\n const root = createRoot(el)\n let current = props\n root.render(<MSAViewer {...current} />)\n return {\n update(next) {\n current = { ...current, ...next }\n root.render(<MSAViewer {...current} />)\n },\n destroy() {\n root.unmount()\n },\n }\n}\n", "import { when } from 'mobx'\n\nimport { mount } from './mount.tsx'\n\nimport type { MSAViewerProps } from './components/MSAViewer.tsx'\nimport type { MsaViewModel } from './model.ts'\nimport type { MountedViewer } from './mount.tsx'\nimport type {\n Cell,\n ColorScheme,\n ColumnTrackSpec,\n Feature,\n Highlight,\n MsaSelection,\n ResidueMapping,\n Viewport,\n} from './types.ts'\n\ntype ElementData = Pick<\n MSAViewerProps,\n | 'msa'\n | 'tree'\n | 'gff'\n | 'features'\n | 'colorScheme'\n | 'highlights'\n | 'columnTracks'\n | 'residueMappings'\n | 'selection'\n>\n\ninterface NightingaleManager extends HTMLElement {\n register: (element: HTMLElement) => void\n unregister: (element: HTMLElement) => void\n}\n\nconst ownAttributes = [\n 'msa-url',\n 'tree-url',\n 'gff-url',\n 'color-scheme',\n 'height',\n 'hide-header',\n 'theme',\n 'reference-row',\n 'tree-area-width',\n] as const\n\n// the attributes a <nightingale-manager> writes on the elements it holds\nconst nightingaleAttributes = ['display-start', 'display-end', 'highlight']\n\nfunction numberAttribute(value: string | null | undefined) {\n const n = value ? Number(value) : Number.NaN\n return Number.isFinite(n) ? n : undefined\n}\n\n// Nightingale writes a highlight as \"start:end,start:end\", 1-based inclusive\nfunction parseHighlight(value: string | null, row?: string): Highlight[] {\n return (value ?? '').split(',').flatMap(span => {\n const [start, end] = span.split(':').map(numberAttribute)\n return start === undefined ? [] : [{ row, start, end: end ?? start }]\n })\n}\n\nfunction residueAtColumn(model: MsaViewModel, row: string, column: number) {\n const visible = model.globalColToVisibleCol(column - 1)\n return visible === undefined\n ? undefined\n : model.visibleColToSeqPosOneBased(row, visible)\n}\n\n// the first and last residues of `row` inside the viewport's columns\nfunction residueRange(model: MsaViewModel, row: string, viewport: Viewport) {\n let start: number | undefined\n let end: number | undefined\n for (let c = viewport.startColumn; c <= viewport.endColumn && !start; c++) {\n start = residueAtColumn(model, row, c)\n }\n for (let c = viewport.endColumn; c >= viewport.startColumn && !end; c--) {\n end = residueAtColumn(model, row, c)\n }\n return start && end ? { start, end } : undefined\n}\n\n/**\n * Registers a custom element that renders MSAViewer, for pages with no React.\n * Attributes: msa-url, tree-url, gff-url, color-scheme, height, hide-header,\n * theme, tree-area-width and reference-row. Properties: msa, tree and gff text,\n * features, colorScheme, highlights, columnTracks, residueMappings and\n * selection. The\n * colorScheme property takes a `{map}` the color-scheme attribute cannot hold,\n * and wins over the attribute while set. Events: cell-hover, cell-click,\n * viewport-change and selection-change, each with the MSAViewer callback's\n * value as detail.\n *\n * Inside a <nightingale-manager>, the element registers with it and speaks its\n * protocol: it follows the display-start, display-end and highlight attributes\n * the manager writes, and reports its own range and hovered residue as change\n * events. Positions are residues of reference-row, or columns without one.\n */\nexport function defineMsaElement(tagName = 'jbrowse-msa') {\n const existing = customElements.get(tagName)\n if (existing) {\n return existing\n }\n\n class MsaElement extends HTMLElement {\n static observedAttributes = [...ownAttributes, ...nightingaleAttributes]\n\n #viewer?: MountedViewer\n #model?: MsaViewModel\n #manager?: NightingaleManager\n #cancelRange?: () => void\n #rangePending = false\n #reported?: { start: number; end: number }\n #data: ElementData = {}\n\n get msa() {\n return this.#data.msa\n }\n set msa(value: string | undefined) {\n this.#setData({ msa: value })\n }\n get tree() {\n return this.#data.tree\n }\n set tree(value: string | undefined) {\n this.#setData({ tree: value })\n }\n get gff() {\n return this.#data.gff\n }\n set gff(value: string | undefined) {\n this.#setData({ gff: value })\n }\n get features() {\n return this.#data.features\n }\n set features(value: Feature[] | undefined) {\n this.#setData({ features: value })\n }\n get colorScheme() {\n return this.#data.colorScheme\n }\n set colorScheme(value: ColorScheme | undefined) {\n this.#setData({ colorScheme: value })\n }\n get highlights() {\n return this.#data.highlights\n }\n set highlights(value: Highlight[] | undefined) {\n this.#setData({ highlights: value })\n }\n get columnTracks() {\n return this.#data.columnTracks\n }\n set columnTracks(value: ColumnTrackSpec[] | undefined) {\n this.#setData({ columnTracks: value })\n }\n get residueMappings() {\n return this.#data.residueMappings\n }\n set residueMappings(value: ResidueMapping[] | undefined) {\n this.#setData({ residueMappings: value })\n }\n // the viewer's selection, which the reader's drags change\n get selection() {\n return this.#model ? this.#model.selection : this.#data.selection\n }\n set selection(value: MsaSelection | undefined) {\n this.#setData({ selection: value })\n }\n\n get #referenceRow() {\n return this.getAttribute('reference-row') ?? undefined\n }\n\n #setData(data: ElementData) {\n this.#data = { ...this.#data, ...data }\n this.#viewer?.update(this.#props())\n }\n\n #props(): MSAViewerProps {\n const theme = this.getAttribute('theme')\n return {\n ...this.#data,\n msaUrl: this.getAttribute('msa-url') ?? undefined,\n treeUrl: this.getAttribute('tree-url') ?? undefined,\n gffUrl: this.getAttribute('gff-url') ?? undefined,\n colorScheme:\n this.#data.colorScheme ??\n this.getAttribute('color-scheme') ??\n undefined,\n height: numberAttribute(this.getAttribute('height')),\n treeAreaWidth: numberAttribute(this.getAttribute('tree-area-width')),\n hideHeader: this.hasAttribute('hide-header'),\n theme: theme === 'dark' ? 'dark' : 'light',\n onCellHover: cell => {\n this.#emit('cell-hover', cell)\n this.#reportHover(cell)\n },\n onCellClick: cell => {\n this.#emit('cell-click', cell)\n },\n onViewportChange: viewport => {\n this.#emit('viewport-change', viewport)\n this.#reportRange(viewport)\n },\n onSelectionChange: selection => {\n this.#emit('selection-change', selection)\n },\n onModel: model => {\n this.#model = model\n this.#followRange()\n this.#followHighlight()\n },\n }\n }\n\n #emit(type: string, detail: unknown) {\n this.dispatchEvent(new CustomEvent(type, { detail }))\n }\n\n #nightingaleChange(detail: Record<string, unknown>) {\n if (this.#manager) {\n this.dispatchEvent(\n new CustomEvent('change', {\n detail,\n bubbles: true,\n cancelable: true,\n }),\n )\n }\n }\n\n #reportHover(cell: Cell | undefined) {\n const model = this.#model\n const row = this.#referenceRow\n const position =\n cell && model && row\n ? residueAtColumn(model, row, cell.column)\n : cell?.column\n this.#nightingaleChange({\n type: 'highlight',\n value: position === undefined ? null : `${position}:${position}`,\n })\n }\n\n #reportRange(viewport: Viewport | undefined) {\n const model = this.#model\n const row = this.#referenceRow\n if (!viewport || !model) {\n return\n }\n const range = row\n ? residueRange(model, row, viewport)\n : { start: viewport.startColumn, end: viewport.endColumn }\n const shownStart = numberAttribute(this.getAttribute('display-start'))\n const shownEnd = numberAttribute(this.getAttribute('display-end'))\n // a range the manager just wrote comes back within a column of itself,\n // since the viewer shows whole columns\n const echo =\n range &&\n shownStart !== undefined &&\n shownEnd !== undefined &&\n Math.abs(range.start - shownStart) <= 1 &&\n Math.abs(range.end - shownEnd) <= 1\n if (range && !echo) {\n this.#reported = range\n this.#nightingaleChange({\n 'display-start': range.start,\n 'display-end': range.end,\n })\n }\n }\n\n #followRange() {\n const model = this.#model\n const start = numberAttribute(this.getAttribute('display-start'))\n const end = numberAttribute(this.getAttribute('display-end'))\n const reported = this.#reported\n // the manager writes the range this element reported back onto it, and\n // zooming to it again would snap the reader's own zoom to whole residues\n if (reported && reported.start === start && reported.end === end) {\n return\n }\n this.#cancelRange?.()\n if (model && start !== undefined && end !== undefined) {\n const row = this.#referenceRow\n this.#cancelRange = when(\n () => model.viewInitialized && model.numColumns > 0,\n () => {\n model.zoomToRegion({ row, start, end })\n },\n )\n }\n }\n\n #followHighlight() {\n const spans = parseHighlight(\n this.getAttribute('highlight'),\n this.#referenceRow,\n )\n if (spans.length) {\n this.#model?.applyHighlight('nightingale', spans)\n } else {\n this.#model?.clearHighlight('nightingale')\n }\n }\n\n connectedCallback() {\n if (!this.style.display) {\n this.style.display = 'block'\n }\n this.#viewer = mount(this, this.#props())\n const manager = this.closest<NightingaleManager>('nightingale-manager')\n if (manager) {\n void customElements.whenDefined('nightingale-manager').then(() => {\n if (this.isConnected) {\n this.#manager = manager\n manager.register(this)\n }\n })\n }\n }\n\n disconnectedCallback() {\n this.#manager?.unregister(this)\n this.#manager = undefined\n this.#cancelRange?.()\n this.#viewer?.destroy()\n this.#viewer = undefined\n this.#model = undefined\n }\n\n attributeChangedCallback(name: string) {\n if (name === 'display-start' || name === 'display-end') {\n // the manager writes the two attributes one after the other, and a\n // zoom between them reports a range that overwrites the second\n if (!this.#rangePending) {\n this.#rangePending = true\n queueMicrotask(() => {\n this.#rangePending = false\n this.#followRange()\n })\n }\n } else if (name === 'highlight') {\n this.#followHighlight()\n } else {\n this.#viewer?.update(this.#props())\n }\n }\n }\n\n customElements.define(tagName, MsaElement)\n return MsaElement\n}\n", "import { useEffect, useState } from 'react'\n\nimport { createJBrowseTheme } from '@jbrowse/core/ui/theme'\nimport { getSnapshot } from '@jbrowse/mobx-state-tree'\nimport { compareShallow, reaction } from 'mobx'\n\nimport { renderToSvg } from './renderToSvg.tsx'\n\nimport type { MsaViewModel } from './model.ts'\nimport type { Theme } from '@mui/material'\n\nexport interface MsaSvgFigure {\n /** the SVG document for what is on screen, once the first draw finishes */\n svg?: string\n error?: unknown\n}\n\n/**\n * The viewer's SVG export of its viewport, as markup for the page to insert.\n * It redraws after the view settles: `delay` ms after the last scroll, zoom,\n * resize, highlight or change to the snapshot. A draw a later one overtakes is\n * dropped.\n *\n * The figure's row names and letters are SVG text, so the browser's find\n * locates them, a reader can select them, and print stylesheets apply.\n */\nexport function useMsaSvgFigure(\n model: MsaViewModel,\n {\n theme,\n includeTracks = false,\n delay = 300,\n }: { theme?: Theme; includeTracks?: boolean; delay?: number } = {},\n) {\n const [figure, setFigure] = useState<MsaSvgFigure>({})\n useEffect(() => {\n let latest = 0\n const dispose = reaction(\n () =>\n model.viewInitialized && model.dataInitialized\n ? [\n getSnapshot(model),\n model.width,\n model.height,\n model.resolvedHighlights,\n model.highlightedColumnRuns,\n ]\n : undefined,\n key => {\n if (!key) {\n return\n }\n const draw = ++latest\n renderToSvg(model, {\n theme: theme ?? createJBrowseTheme(),\n exportType: 'viewport',\n includeTracks,\n }).then(\n svg => {\n if (draw === latest) {\n setFigure({ svg })\n }\n },\n (error: unknown) => {\n if (draw === latest) {\n setFigure({ error })\n }\n },\n )\n },\n { delay, fireImmediately: true, equals: compareShallow },\n )\n return () => {\n latest = -1\n dispose()\n }\n }, [model, theme, includeTracks, delay])\n return figure\n}\n"],
5
+ "mappings": "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ACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,WAGL,kBAAmB,CACjB,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,WAGL,mBAAoB,CAClB,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,WAGL,iBAAkB,CAChB,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,WAGL,eAAgB,CACd,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,WAGL,cAAe,CACb,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,UACH,EAAG,U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,EAAG,EAAE,GAAI,EAAG,EAAE,GAAI,EAAE,GAAG,GAAI,EAAE,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAG,GAAI,EAAG,EAAE,GAAG,EAAE,EACxE,CAAE,EAAE,GAAI,EAAE,GAAG,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,EACxE,CAAC,GAAI,EAAG,EAAE,GAAG,GAAI,EAAG,EAAE,GAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAI,EAAE,GAAI,EAAG,EAAE,GAAG,EAAE,EACxE,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAI,EAAG,EAAE,GAAI,EAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAG,EAAE,EACxE,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAI,EAAG,EAAE,GAAI,EAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAG,EAAE,EACxE,CAAC,GAAI,EAAG,EAAE,GAAG,GAAI,EAAG,EAAE,GAAG,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAG,GAAI,EAAG,EAAE,GAAG,EAAE,EACxE,CAAC,GAAG,GAAG,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAI,EAAG,EAAE,GAAI,EAAG,EAAE,GAAG,GAAG,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAG,EAAE,EACxE,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAI,EAAG,EAAE,GAAI,EAAG,EAAE,GAAG,GAAG,GAAI,EAAG,EAAE,GAAG,GAAG,GAAG,GAAG,EAAE,EACxE,CAAC,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAI,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE,EACxE,CAAE,EAAE,GAAI,EAAG,EAAE,GAAI,EAAG,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",
6
+ "names": ["require_ErrorBoundary", "__commonJSMin", "exports", "module", "require_BaseTooltip", "__commonJSMin", "exports", "module", "require_useMeasure", "__commonJSMin", "exports", "module", "require_CascadingMenuButton", "__commonJSMin", "exports", "module", "require_styles", "__commonJSMin", "exports", "module", "require_mst", "__commonJSMin", "exports", "module", "require_theme", "__commonJSMin", "exports", "module", "HeadlessDOMMatrix", "_HeadlessDOMMatrix", "init", "a", "b", "c", "d", "e", "f", "o", "x", "y", "HeadlessDOMPoint", "_HeadlessDOMPoint", "m", "installHeadlessRenderEnv", "win", "contextExtras", "measureContext", "g", "canvas", "font", "v", "t", "CHAR_WIDTH_RATIO", "residueLabel", "span", "parseSpan", "text", "what", "match", "a", "b", "withRow", "entry", "query", "row", "rest", "resolved", "expandHighlight", "start", "end", "label", "expandRegion", "region", "slug", "name", "kindOf", "track", "expandTrack", "ids", "pad", "id", "n", "isInlineMsa", "msa", "isInlineTree", "tree", "uri", "location", "expandSpec", "spec", "highlights", "columnTracks", "data", "t", "h", "import_react", "import_ui", "import_ErrorBoundary", "import_material", "import_mobx_react", "import_react", "import_mobx_react", "import_react", "import_mobx_react", "minViewHeight", "VerticalResizeHandle", "model", "onDrag", "delta", "startWidth", "React", "DragHandle", "HorizontalResizeHandle", "startHeight", "TrackResizeHandle", "track", "id", "heightKey", "height", "siblings", "t", "count", "import_react", "import_BaseTooltip", "import_tss_react", "import_jsx_runtime", "ArrowDropDown_default", "_jsx", "import_material", "import_mobx_react", "import_react", "MAX_ZOOM_RATE_PER_MS", "normalizeWheelDelta", "delta", "mode", "getZoomNormalizer", "deltaY", "abs", "zoomFactorFromAccum", "zoomAccum", "elapsedMs", "max", "d", "useWheelScroll", "ref", "onScrollX", "onScrollY", "onZoom", "scrollZoom", "scheduled", "zoomScheduled", "deltaX", "deltaY", "zoomAccum", "zoomX", "zoomY", "lastZoomTime", "prevX", "prevY", "mouseDragging", "setMouseDragging", "curr", "onWheel", "event", "isCtrlZoom", "isScrollZoom", "rect", "dY", "normalizeWheelDelta", "divisor", "getZoomNormalizer", "now", "elapsed", "zoomFactorFromAccum", "consumeX", "consumeY", "globalMouseMove", "distanceX", "distanceY", "globalMouseUp", "onMouseDown", "onMouseUp", "onMsaKey", "model", "key", "shiftKey", "colWidth", "rowHeight", "msaCanvasWidth", "msaAreaHeight", "dx", "dy", "import_react", "import_material", "import_mobx_react", "import_react", "import_mobx", "useCanvasAutorun", "draw", "width", "height", "deps", "ref", "ctx", "TrackBlock", "model", "track", "offsetX", "blockSize", "highResScaleFactor", "height", "theme", "canvasWidth", "canvasHeight", "ref", "useCanvasAutorun", "ctx", "drawTrackBlock", "React", "TrackBlocks", "blocksX", "msaCanvasWidth", "scrollX", "kind", "data", "arcs", "bx", "TrackResizeHandle", "TrackBlocks_default", "import_react", "import_mobx_react", "pct", "MAX_PARTNERS", "ColumnLabel", "model", "col", "relativeTo", "pos", "React", "BarTooltip", "track", "id", "name", "value", "barTrackValues", "LogoTooltip", "stats", "total", "consensusLetter", "consensusFraction", "gapFraction", "bits", "columnLogoStack", "a", "b", "letter", "count", "TextTooltip", "data", "ArcTooltip", "arcs", "partners", "arc", "TrackTooltipContent", "TrackTooltipContent_default", "import_mobx_state_tree", "maxClickTravel", "dragSelection", "model", "start", "cellAt", "anchor", "clientX", "clientY", "dragging", "onMove", "event", "onUp", "import_react", "useHoverAnchor", "anchor", "setAnchor", "hoverAt", "event", "value", "clearAnchor", "useTrackHover", "model", "tooltip", "anchor", "hoverAt", "clearAnchor", "useHoverAnchor", "colAt", "clientX", "left", "onMouseMove", "event", "el", "col", "hit", "onMouseDown", "dragSelection", "onMouseLeave", "TrackInfoDialog", "useStyles", "theme", "TrackLabel", "model", "track", "anchorEl", "setAnchorEl", "closeMenu", "drawLabels", "fontSize", "width", "name", "height", "classes", "trackLabelHeight", "React", "event", "ArrowDropDown_default", "onClose", "Track", "resizeHandleWidth", "rowPanelsWidth", "showColumnStats", "ref", "onScrollX", "d", "useWheelScroll", "anchor", "onMouseMove", "onMouseDown", "onMouseLeave", "useTrackHover", "onMsaKey", "TrackBlocks_default", "BaseTooltip", "TrackTooltipContent_default", "Track_default", "import_react", "import_mobx_react", "width", "VerticalScrollbar", "model", "msaAreaHeight", "scrollY", "totalHeight", "unit", "t", "b", "onDrag", "delta", "startScroll", "React", "event", "y", "DragHandle", "VerticalScrollbar_default", "import_react", "import_useMeasure", "import_material", "import_mobx_react", "import_react", "import_ui", "import_tss_react", "import_material", "import_mobx_react", "useStyles", "StatusMessage", "model", "variant", "status", "classes", "message", "onCancel", "React", "StatusMessage_default", "import_react", "import_CascadingMenuButton", "import_jsx_runtime", "Palette_default", "_jsx", "import_mobx_react", "red", "red_default", "blue", "blue_default", "green", "green_default", "orange", "orange_default", "dna", "green_default", "blue_default", "orange_default", "red_default", "colorSchemes", "colorSchemes_default", "transform", "key", "val", "letter", "color", "A", "letterTables", "letterColorTable", "map", "table", "colorSchemeMenuItems", "model", "colorSchemeName", "customColorScheme", "colorSchemes_default", "option", "ColorSchemeMenu", "React", "CascadingMenuButton", "Palette_default", "ColorSchemeMenu_default", "import_react", "import_CascadingMenuButton", "import_jsx_runtime", "AccountTree_default", "_jsx", "import_jsx_runtime", "Assignment_default", "_jsx", "import_jsx_runtime", "FolderOpen_default", "_jsx", "import_jsx_runtime", "Menu_default", "_jsx", "import_jsx_runtime", "PhotoCamera_default", "_jsx", "import_mobx_react", "import_react", "import_jsx_runtime", "FilterAlt_default", "_jsx", "import_jsx_runtime", "MenuBook_default", "_jsx", "import_jsx_runtime", "Sort_default", "_jsx", "import_jsx_runtime", "Visibility_default", "_jsx", "FeatureFilterDialog", "AnnotationFileDialog", "domainsTutorial", "getAnnotationsMenu", "model", "showDomains", "actuallyShowDomains", "subFeatureRows", "noDomains", "noneLoaded", "FolderOpen_default", "handleClose", "MenuBook_default", "Visibility_default", "Sort_default", "FilterAlt_default", "onClose", "MetadataDialog", "ExportSVGDialog", "neighborJoiningItem", "model", "rows", "tooManyRows", "maxNeighborJoiningRows", "AccountTree_default", "e", "FileMenu", "React", "CascadingMenuButton", "FolderOpen_default", "Assignment_default", "onClose", "getAnnotationsMenu", "PhotoCamera_default", "Menu_default", "FileMenu_default", "import_react", "import_material", "import_mobx_react", "GappynessSlider", "model", "hideGaps", "allowedGappyness", "dragValue", "setDragValue", "value", "React", "_", "val", "GappynessSlider_default", "import_react", "import_material", "import_mobx_react", "findableRowNames", "model", "collapsed", "id", "name", "leaf", "rowNameSuggestions", "names", "input", "limit", "query", "resolveGoTo", "text", "row", "residue", "pos", "rowIndex", "col", "columnOfResidue", "n", "relativeTo", "numColumns", "globalCol", "goTo", "target", "rowHeight", "colWidth", "msaAreaHeight", "msaAreaWidth", "label", "labelledInput", "params", "slotProps", "inputProps", "GoToBox", "model", "missed", "setMissed", "names", "findableRowNames", "React", "options", "inputValue", "rowNameSuggestions", "_", "text", "goTo", "GoToBox_default", "import_react", "import_tss_react", "import_material", "import_mobx_react", "useStyles", "HeaderInfoArea", "model", "mouseOverRowName", "mouseCol", "classes", "mid", "pos", "letter", "React", "HeaderInfoArea_default", "import_react", "import_jsx_runtime", "Warning_default", "_jsx", "import_material", "import_mobx_react", "LoadWarnings", "model", "warnings", "React", "Warning_default", "LoadWarnings_default", "import_react", "import_CascadingMenuButton", "import_jsx_runtime", "Tune_default", "_jsx", "import_mobx_react", "import_react", "import_SvgIcon", "BODY", "WHEEL", "LEFT", "RIGHT", "UP", "DOWN", "MouseZoom", "arrows", "rest", "React", "SvgIcon", "d", "MouseScroll", "props", "MouseZoomBoth", "MouseZoomHorizontal", "MouseZoomVertical", "radio", "label", "checked", "onClick", "treeOrderLabels", "outgroupLabel", "outgroup", "first", "rest", "toggle", "set", "tracksSubMenu", "model", "shown", "id", "name", "wheelModes", "MouseScroll", "MouseZoomBoth", "MouseZoomHorizontal", "MouseZoomVertical", "wheelSubMenu", "active", "axis", "icon", "helpText", "msaSettingsMenuItems", "drawMsaLetters", "hideGaps", "bgColor", "showColumnStats", "arg", "treeSettingsMenuItems", "drawTree", "showBranchLen", "labelsAlignRight", "drawNodeBubbles", "drawNodeLabels", "drawLabels", "treeAreaWidth", "showTreeOverview", "treeOrder", "treeRoot", "rotated", "treeOrders", "order", "MSASettingsMenu", "model", "React", "CascadingMenuButton", "msaSettingsMenuItems", "Tune_default", "MSASettingsMenu_default", "import_react", "import_material", "import_mobx_react", "MultiAlignmentSelector", "model", "currentAlignment", "alignmentNames", "seen", "React", "event", "option", "index", "n", "MultiAlignmentSelector_default", "import_react", "import_jsx_runtime", "Clear_default", "_jsx", "import_jsx_runtime", "ContentCopy_default", "_jsx", "import_jsx_runtime", "ZoomIn_default", "_jsx", "import_material", "import_mobx_react", "count", "noun", "SelectionMenu", "model", "anchorEl", "setAnchorEl", "selectionSize", "selectionFileSpan", "label", "items", "ContentCopy_default", "copy", "ZoomIn_default", "Clear_default", "React", "ArrowDropDown_default", "event", "text", "Icon", "act", "SelectionMenu_default", "import_react", "import_CascadingMenuButton", "import_mobx_react", "TreeSettingsMenu", "model", "React", "CascadingMenuButton", "treeSettingsMenuItems", "AccountTree_default", "TreeSettingsMenu_default", "import_react", "import_tss_react", "import_jsx_runtime", "LinkOff_default", "_jsx", "import_material", "import_mobx_react", "useStyles", "theme", "size", "bytes", "UnshareableDataWarning", "model", "unshareableData", "classes", "what", "React", "LinkOff_default", "UnshareableDataWarning_default", "import_react", "import_CascadingMenuButton", "import_jsx_runtime", "FitScreen_default", "_jsx", "import_jsx_runtime", "RestartAlt_default", "_jsx", "import_jsx_runtime", "ZoomOut_default", "_jsx", "import_material", "import_mobx_react", "ZoomControls", "model", "React", "ZoomIn_default", "ZoomOut_default", "CascadingMenuButton", "RestartAlt_default", "FitScreen_default", "ZoomControls_default", "HelpDialog", "Header", "model", "ref", "height", "useMeasure", "React", "FileMenu_default", "ColorSchemeMenu_default", "TreeSettingsMenu_default", "MSASettingsMenu_default", "ZoomControls_default", "GappynessSlider_default", "GoToBox_default", "MultiAlignmentSelector_default", "SelectionMenu_default", "HeaderInfoArea_default", "LoadWarnings_default", "UnshareableDataWarning_default", "StatusMessage_default", "onClose", "Help_default", "Header_default", "import_react", "import_material", "import_mobx_react", "Minimap", "model", "minimapHeight", "msaCanvasWidth", "highResScaleFactor", "theme", "unit", "w", "polygonHeight", "polygonPoints", "getMinimapLayout", "barWidth", "barHeight", "ref", "useCanvasAutorun", "ctx", "thumbnail", "msaThumbnail", "onDrag", "delta", "startScroll", "React", "event", "x", "DragHandle", "scrollbarThumbFill", "Minimap_default", "import_react", "import_mobx_react", "import_react", "import_jsx_runtime", "ExpandLess_default", "_jsx", "import_material", "import_mobx_react", "AnnotationLegend", "model", "legends", "expanded", "rows", "legendRows", "ExpandIcon", "ExpandLess_default", "ExpandMore_default", "React", "legendZIndex", "row", "i", "AnnotationLegend_default", "import_react", "import_mobx_react", "import_react", "import_material", "Loading", "React", "import_react", "import_BaseTooltip", "import_material", "import_mobx_react", "import_react", "useMsaBlockMouse", "model", "offsetX", "offsetY", "anchor", "hoverAt", "clearAnchor", "useHoverAnchor", "downAt", "cellMapper", "el", "left", "top", "scrollX", "scrollY", "clientX", "clientY", "colRow", "event", "inBounds", "col", "row", "onMouseMove", "pos", "hit", "hasTooltip", "onMouseDown", "dragSelection", "onClick", "down", "maxClickTravel", "mouseClickCol", "mouseClickRow", "same", "keep", "onMouseLeave", "MSACanvasBlock", "model", "offsetX", "offsetY", "blockSize", "highResScaleFactor", "theme", "anchor", "onMouseMove", "onMouseDown", "onClick", "onMouseLeave", "useMsaBlockMouse", "canvasSize", "ref", "useCanvasAutorun", "ctx", "renderBoxFeatureCanvasBlock", "rasterTiles", "rasterApplies", "drawMsaRaster", "renderMSABlock", "hoveredInsertion", "mouseOverDomains", "React", "event", "BaseTooltip", "d", "MSACanvasBlock_default", "MSACanvas", "model", "MSA", "msaFilehandle", "height", "msaCanvasWidth", "blocks2d", "scrollZoom", "scrollX", "scrollY", "ref", "onScrollX", "d", "onScrollY", "onZoom", "scaleFactor", "offsetX", "offsetY", "onMouseDown", "onMouseUp", "useWheelScroll", "React", "alignmentAriaLabel", "event", "onMsaKey", "bx", "by", "MSACanvasBlock_default", "Loading", "MSACanvas_default", "import_react", "import_mobx_state_tree", "import_material", "import_mobx_react", "renderMouseover", "ctx", "model", "theme", "mouseCol", "colWidth", "width", "height", "rowHeight", "scrollX", "scrollY", "mouseRow", "mouseClickRow", "mouseClickCol", "highResScaleFactor", "hoveredRowIndices", "rowBand", "index", "colBand", "renderPersistentHighlights", "renderSelection", "multiRowHoverColor", "rowIndex", "hoverColor", "clickColor", "MSAMouseoverCanvas", "model", "height", "width", "highResScaleFactor", "theme", "canvasWidth", "canvasHeight", "ref", "useCanvasAutorun", "ctx", "renderMouseover", "React", "msaOverlayZIndex", "MSAMouseoverCanvas_default", "MSAPanel", "model", "React", "MSACanvas_default", "MSAMouseoverCanvas_default", "AnnotationLegend_default", "MSAPanel_default", "import_react", "import_mobx_react", "RowPanelHeaders", "model", "resolvedRowPanels", "rowPanelsHeaderHeight", "fontSize", "React", "panel", "across", "headerRunsAcross", "RowPanelHeaders_default", "import_react", "import_mobx_react", "import_react", "import_BaseTooltip", "import_material", "import_mobx_react", "featureField", "annotation", "field", "value", "featureName", "hoverLines", "model", "panel", "name", "x", "span", "s", "annotation", "strand", "value", "featureField", "featureName", "RowPanelBlock", "offsetY", "anchor", "hoverAt", "clearAnchor", "useHoverAnchor", "theme", "blockSize", "highResScaleFactor", "rowHeight", "width", "height", "canvasWidth", "canvasHeight", "ref", "useCanvasAutorun", "ctx", "renderRowPanel", "React", "event", "left", "top", "row", "lines", "BaseTooltip", "line", "RowPanelBlock_default", "RowPanel", "model", "panel", "ref", "height", "blocksY", "scrollY", "onScrollY", "d", "onMouseDown", "onMouseUp", "useWheelScroll", "React", "block", "RowPanelBlock_default", "RowPanels", "resolvedRowPanels", "RowPanels_default", "import_react", "import_material", "import_mobx_react", "TreeOverview", "model", "effectiveTreeAreaWidth", "overviewHeight", "highResScaleFactor", "theme", "hover", "setHover", "width", "height", "ref", "useCanvasAutorun", "ctx", "image", "treeOverviewImage", "box", "drawTreeOverview", "drawTreeOverviewBox", "focus", "React", "event", "hit", "prev", "TreeOverview_default", "import_react", "import_mobx_react", "import_react", "import_mobx_state_tree", "import_mobx_react", "import_react", "import_material", "import_mobx_react", "CladeLabels", "model", "theme", "fontSize", "React", "cladeLabelBoxes", "box", "CladeLabels_default", "import_react", "import_BaseTooltip", "import_tss_react", "import_material", "import_mobx_react", "import_react", "import_material", "import_mobx_react", "TreeNodeInfoDialog", "TreeMenu", "node", "model", "onClose", "collapsed", "showOnly", "relativeTo", "name", "id", "leaf", "isCollapsed", "isRoot", "noun", "React", "TreeMenu_default", "import_react", "FlatQueue", "capacity", "ValuesArray", "IdsArray", "fixed", "item", "priority", "pos", "parent", "parentValue", "ids", "values", "top", "last", "id", "value", "halfLen", "left", "right", "child", "ARRAY_TYPES", "VERSION", "Flatbush", "_Flatbush", "data", "byteOffset", "magic", "versionAndType", "version", "ArrayType", "nodeSize", "numItems", "ArrayBufferType", "n", "numNodes", "arrayTypeIndex", "nodesByteSize", "BoxCtor", "IdxCtor", "FlatQueue", "minX", "minY", "maxX", "maxY", "pos", "index", "boxes", "indices", "levelBounds", "width", "height", "hilbertValues", "hilbertMax", "sx", "sy", "i", "itemMinX", "itemMinY", "itemMaxX", "itemMaxY", "x", "y", "hilbert", "sort", "readPos", "end", "nodeIndex", "nodeMinX", "nodeMinY", "nodeMaxX", "nodeMaxY", "j", "filterFn", "numItems4", "level", "q", "results", "contained", "isNode", "x0", "y0", "x1", "y1", "c", "l", "leafEnd", "maxResults", "maxDistance", "nodeSize4", "maxDistSquared", "trackNearest", "bound", "top", "isLeafLevel", "upperBound", "dx", "dy", "dist", "childIndex", "value", "arr", "m", "values", "left", "right", "stack", "r", "a", "b", "pivot", "swap", "temp", "k", "e", "d", "A", "B", "C", "D", "ClickMapIndex", "entry", "Flatbush", "box", "i", "useTreeHover", "model", "offsetY", "clickMap", "ClickMapIndex", "anchor", "hoverAt", "clearAnchor", "useHoverAnchor", "hitTest", "event", "x", "y", "entries", "entry", "onMouseMove", "onMouseLeave", "useStyles", "theme", "TreeCanvasBlock", "model", "offsetY", "classes", "menu", "setMenu", "clickMap", "anchor", "hitTest", "onMouseMove", "onMouseLeave", "useTreeHover", "hovered", "effectiveTreeAreaWidth", "blockSize", "highResScaleFactor", "width", "height", "canvasWidth", "canvasHeight", "ref", "useCanvasAutorun", "ctx", "renderTreeCanvas", "style", "React", "TreeMenu_default", "event", "entry", "BaseTooltip", "TreeCanvasBlock_default", "renderTreeMouseover", "ctx", "model", "rowHeight", "width", "height", "scrollY", "mouseRow", "referenceRowIndex", "hoveredRowIndices", "highResScaleFactor", "rowBand", "index", "treeHoverColor", "TreeCanvas", "model", "ref", "height", "blocksY", "effectiveTreeAreaWidth", "scrollY", "highResScaleFactor", "onScrollY", "d", "onMouseDown", "onMouseUp", "useWheelScroll", "canvasWidth", "canvasHeight", "mouseoverRef", "useCanvasAutorun", "ctx", "renderTreeMouseover", "React", "block", "TreeCanvasBlock_default", "CladeLabels_default", "TreeCanvas_default", "TreePanel", "model", "effectiveTreeAreaWidth", "React", "TreeCanvas_default", "TreePanel_default", "import_react", "import_material", "import_mobx_react", "TreeRuler", "model", "effectiveTreeAreaWidth", "marginLeft", "bar", "theme", "React", "treeScaleBarHeight", "ScaleBarSVG", "TreeRuler_default", "TopArea", "model", "showHorizontalScrollbar", "showTreeOverview", "resizeHandleWidth", "React", "TreeOverview_default", "TreeRuler_default", "RowPanelHeaders_default", "Minimap_default", "TrackColumnIndicator", "mouseCol", "mouseClickCol", "colWidth", "scrollX", "effectiveTreeAreaWidth", "rowPanelsWidth", "totalTrackAreaHeight", "msaCanvasWidth", "resolvedSelection", "bands", "selectionFill", "hoverColor", "clickColor", "start", "end", "color", "TrackArea", "turnedOnTracks", "track", "Track_default", "MainArea", "showVerticalScrollbar", "TreePanel_default", "RowPanels_default", "VerticalResizeHandle", "MSAPanel_default", "VerticalScrollbar_default", "View", "MSAView", "height", "hideHeader", "viewInitialized", "DialogComponent", "DialogProps", "Header_default", "HorizontalResizeHandle", "MSAView_default", "import_react", "import_ui", "import_material", "import_mobx_react", "import_react", "import_material", "import_mobx_react", "smallMSA", "smallTree", "load", "model", "msaFile", "treeFile", "gffFile", "BASE", "TREES", "DEMO", "examples", "smallMSA", "smallTree", "uri", "url", "ImportFormExamples", "model", "React", "label", "msa", "tree", "gff", "inline", "event", "load", "e", "ImportFormExamples_default", "phone", "ImportForm", "model", "msaFile", "setMsaFile", "treeFile", "setTreeFile", "gffFile", "setGffFile", "error", "React", "load", "e", "ImportFormExamples_default", "ImportForm_default", "Reset", "model", "error", "React", "Loading", "isLoading", "dataInitialized", "data", "resetCount", "msaFilehandle", "treeFilehandle", "importForm", "hasData", "loading", "e", "StatusMessage_default", "MSAView_default", "ImportForm_default", "Loading_default", "import_react", "import_useMeasure", "import_mobx_state_tree", "import_styles", "import_mobx", "import_util", "import_io", "import_mst", "import_mobx_state_tree", "import_mobx", "blockFasta", "rows", "start", "end", "width", "name", "seq", "calculateBlocks", "mapSize", "blockSize", "viewportPos", "viewportSize", "clamped", "end", "minTile", "maxTile", "blocks", "tile", "BLUE", "RED", "MAGENTA_E", "MAGENTA_D", "GREEN", "GREEN_ST", "PINK", "ORANGE", "YELLOW", "CYAN", "clustalXColumnColors", "counts", "col", "total", "count", "letter", "W", "L", "V", "I", "M", "A", "F", "C", "H", "P", "R", "K", "Q", "E", "D", "T", "S", "G", "Y", "N", "hydrophobic", "KR", "QE", "ED", "TS", "p", "subtotal", "colors", "columnStats", "col", "colStats", "conservation", "propertyConservation", "total", "gaps", "distribution", "a", "b", "consensus", "packDomainLanes", "bands", "laneEnds", "lanes", "byStart", "_", "a", "b", "i", "startCol", "endCol", "found", "end", "lane", "band", "scaleBarLength", "pxPerUnit", "maxPx", "target", "magnitude", "mantissa", "step", "px", "palettes", "ggplotPalettes_default", "namedPalettes", "paletteNamed", "name", "createPaletteMap", "keys", "palette", "n", "colors", "ggplotPalettes_default", "key", "A", "exportFileName", "location", "extension", "fallback", "loc", "placement", "converted", "featuresToAnnotations", "features", "feature", "cached", "annotation", "featureAnnotation", "row", "start", "end", "name", "description", "type", "strand", "color", "accession", "attributes", "key", "value", "import_util", "statusMessageText", "status", "fetchTextWithProgress", "loc", "setStatus", "fetcher", "controller", "msg", "isAbortError", "e", "flatToTree", "items", "nodeMap", "item", "length", "root", "node", "parent", "import_mobx_state_tree", "DataModelF", "maxInlineBytes", "maxInlineSnapshotBytes", "self", "tree", "msa", "treeMetadata", "gff", "snap", "key", "text", "import_mobx_state_tree", "DialogQueueSessionMixin", "self", "cb", "component", "props", "import_mobx_state_tree", "import_mobx_state_tree", "stripDefault", "type", "defaultValue", "msaFormats", "MSAModelF", "stripDefault", "defaultBgColor", "defaultColorSchemeName", "defaultShowColumnStats", "self", "name", "map", "arg", "import_mobx_state_tree", "TreeModelF", "stripDefault", "defaultDrawLabels", "defaultLabelsAlignRight", "defaultShowBranchLen", "treeOrders", "defaultTreeOrder", "defaultDrawTree", "defaultDrawNodeBubbles", "defaultDrawNodeLabels", "defaultShowTreeOverview", "defaultOverviewHeight", "self", "n", "arg", "order", "BLOSUM62_KEYS", "BLOSUM62_DATA", "NUM_SYMBOLS", "BLOSUM62", "symbolOfCode", "i", "key", "GAP", "symbolAt", "seq", "code", "blosumScore", "a", "b", "computePairwiseDistance", "seq1", "seq2", "len", "compared", "totalScore", "maxPossibleScore", "aGap", "bGap", "normalizedScore", "clampedScore", "computeDistanceMatrix", "rows", "n", "distances", "j", "neighborJoining", "names", "d", "D", "nodes", "name", "remaining", "active", "r", "sum", "minQ", "minI", "minJ", "ai", "aj", "q", "dij", "ri", "rj", "limbI", "limbJ", "newNode", "k", "newDist", "finalActive", "withBranchLength", "newick", "branchLength", "nodeToNewick", "root", "postOrder", "stack", "node", "newickByNode", "left", "right", "calculateNeighborJoiningTree", "tree", "remap", "afterMatchingBrace", "str", "openIdx", "depth", "pos", "extractBracedBlocks", "blocks", "end", "findBracedContent", "after", "parseAsn1", "asnString", "normalized", "sections", "extractSections", "fdict", "nodes", "dict", "block", "entry", "parseDictEntry", "node", "parseNode", "features", "rest", "f", "content", "nameStart", "name", "entryString", "idMatch", "nameMatch", "nodeString", "parentMatch", "featuresIdx", "featuresContent", "parseFeature", "featureString", "featureidMatch", "valueMatch", "aminoPropertyClass", "propertyClasses", "maxPropertyEntropy", "classOfSlot", "numResidueSlots", "letter", "cls", "residueSlotOfLetter", "calculatePropertyConservation", "counts", "classCounts", "_", "col", "total", "score", "nonGapTotal", "slot", "count", "entropy", "freq", "gapFraction", "preorder", "root", "order", "parents", "stack", "node", "child", "hasLengths", "n", "mergedSibling", "target", "c", "rerootTree", "offset", "lengths", "sibling", "branch", "at", "length", "path", "above", "i", "below", "children", "only", "midpointRoot", "tips", "weight", "reach", "from", "dist", "via", "d", "parent", "farthest", "best", "tip", "a", "b", "half", "next", "partitionPoint", "len", "pred", "left", "right", "mid", "visibleColToGlobalCol", "blanks", "visibleCol", "i", "globalColToVisibleCol", "globalCol", "blanksBefore", "countBlanksBefore", "visibleColsBefore", "seqPosOfGlobalCol", "index", "seqPos", "resolveScale", "spec", "values", "domain", "a", "b", "map", "palette", "colors", "createPaletteMap", "paletteNamed", "present", "labels", "v", "value", "buildSeqPosIndex", "row", "index", "n", "col", "measuredLabels", "treeTips", "tree", "names", "depth", "stack", "entry", "node", "level", "children", "child", "widestLabel", "labels", "fontSize", "counts", "label", "shortest", "seen", "widest", "ties", "measureTextCanvas", "needsQuotes", "quote", "name", "writeNewick", "root", "written", "node", "descendants", "id", "length", "text", "c", "child", "closeToOpen", "opens", "parseWuss", "ss", "stacks", "pairs", "push", "key", "col", "stack", "pop", "pseudoknot", "start", "ch", "opener", "a", "b", "parseTreeText", "text", "flatToTree", "parseAsn1", "parse", "parseEmfTree", "defaultTrackHeights", "resizableKinds", "defaultOffTracks", "ownHeightKey", "id", "HELIX_ARC", "PSEUDOKNOT_ARC", "UNSCALED_FEATURE", "laneOverlap", "rowPanelWidth", "panel", "view", "defaultFeaturePanelWidth", "stringFields", "row", "fields", "field", "value", "colorByRow", "rowData", "colorOf", "colors", "name", "color", "featureColorMap", "annotations", "encoding", "fillPalette", "strokes", "strokeOf", "fill", "hit", "stroke", "outlineColor", "annotation", "featureField", "featureLabelMap", "labels", "strandpileLanes", "rows", "piled", "bands", "reverse", "packDomainLanes", "b", "forward", "up", "p", "down", "laneCount", "panelLanes", "featurePanelSpans", "width", "colWidth", "domainBands", "annotationsByRow", "shifts", "band", "shifted", "shift", "min", "max", "features", "start", "end", "drawable", "scale", "resolveFeatureScale", "drawn", "valuesOf", "list", "a", "resolved", "resolveScale", "shown", "entry", "columnTrackBytes", "columnTrackSize", "track", "bytes", "columnTrackSizes", "tracks", "smallColumnTracks", "maxInlineSnapshotBytes", "sizes", "kept", "_t", "preservedOnReset", "trackIsOff", "turnedOffTracks", "defaultOff", "seedingMarks", "noDomains", "noClades", "tipRows", "root", "pushReversed", "stack", "nodes", "i", "node", "hidden", "tip", "kids", "cladeRows", "clade", "index", "tips", "first", "last", "mrca", "nodeTips", "leaves", "resolveClades", "clades", "displayed", "leafIndex", "seeding", "withAlpha", "cladeHighlightColor", "cladeHighlightAlpha", "childOrders", "buildTreeRoot", "tree", "collapsed", "rotated", "order", "showOnly", "hier", "hierarchy", "d", "sum", "compare", "sort", "flip", "forEachDescendant", "n", "res", "find", "collapsedId", "collapse", "outgroupNode", "outgroup", "out", "rest", "other", "rootTree", "treeRoot", "plain", "preorder", "c", "input", "generateNodeIds", "midpointRoot", "target", "rerootTree", "tipRange", "featureChannels", "annotationRowName", "rowNames", "underscored", "seqPosIndexCache", "sameLength", "segment", "overflows", "content", "viewport", "inRanges", "ranges", "position", "consecutiveRuns", "sorted", "runs", "sharedValue", "values", "v", "child", "stateModelFactory", "DialogQueueSessionMixin", "TreeModelF", "MSAModelF", "stripDefault", "defaultDrawMsaLetters", "defaultScrollZoom", "scrollZoomAxes", "defaultScrollZoomAxis", "DataModelF", "self", "arg", "height", "error", "warning", "col", "columns", "region", "highlights", "selection", "next", "owner", "_dropped", "data", "msaFilehandle", "treeFilehandle", "treeMetadataFilehandle", "gffFilehandle", "result", "featuresToAnnotations", "customColorScheme", "colorSchemeName", "letterColorTable", "colorSchemes_default", "defaultColorSchemeName", "trackBytes", "what", "filehandle", "parsed", "e", "parseMSA", "leaf", "cladeGutterWidth", "treeTips", "widestLabel", "labelFitFontSize", "chrome", "pxPerTreeDepth", "minTreeWidth", "maxFitTreeWidth", "fit", "room", "maxTreeAreaShare", "cap", "minLetterRowHeight", "mouseRow", "mouseCol", "rowName", "insertion", "ins", "writeNewick", "layout", "layoutTree", "y", "numTips", "perPixel", "nodeCoveringRows", "rowPanelHeaderHeight", "hideGapsEffective", "allowedGappyness", "strs", "numCols", "numRows", "threshold", "blankCounts", "j", "str", "len", "blanks", "seq", "insertions", "computeRowInsertions", "MSA", "f", "cache", "buildSeqPosIndex", "columns2d", "skipBlanks", "fontSizeFor", "columnCountsFromRows", "letters", "ambiguous", "dna", "rna", "isDna", "isRna", "colStats", "_", "total", "maxCount", "letter", "slot", "count", "letterOfResidueSlot", "proportion", "clustalXColumnColors", "alphabetMaxBits", "gapCount", "maxBitsFor", "calculatePropertyConservation", "treeWidth", "minLetterColWidth", "columnTrackModels", "project", "items", "item", "seqPos", "skip", "dropBlanks", "resolve", "pos", "visibleColsBefore", "arcs", "arc", "kind", "heightKey", "given", "computedModel", "ss", "parseWuss", "pseudoknot", "t", "rowHeight", "model", "visibleCol", "seqPosOfGlobalCol", "val", "globalCol", "globalColToVisibleCol", "visibleColToGlobalCol", "rawStart", "rawEnd", "startGlobal", "endGlobal", "rowStart", "rowEnd", "startCol", "endCol", "problems", "mapping", "where", "residues", "overrun", "unusable", "problem", "m", "structureId", "hits", "seg", "asymId", "scaleBarLength", "treeScaleBarHeight", "r", "types", "annot", "rowNamesSet", "calculateBlocks", "by", "bx", "w", "nodeId", "maxNeighborJoiningRows", "calculateNeighborJoiningTree", "newick", "scaleFactor", "axis", "offsetX", "offsetY", "colInView", "rowInView", "minColWidth", "maxCellSize", "minRowHeight", "anchoredScrollY", "overflow", "visibleHeight", "topBias", "deltaY", "gffText", "gffToAnnotations", "parseGFF", "deltaX", "encodings", "panels", "mappings", "status", "rowIndex", "column", "mouseClickCol", "mouseClickRow", "scrollX", "numColumns", "viewInitialized", "xStart", "xEnd", "visibleColRange", "segmentFeatureTypes", "segments", "segmentShades", "categorical", "createPaletteMap", "featureFillEncoding", "visibleDomainTypes", "byKey", "add", "entries", "key", "legend", "seen", "channel", "legendTitle", "rowBands", "stackIndex", "relativeTo", "hoveredTreeNode", "label", "residue", "transientHighlights", "base", "rowIndices", "span", "rowRuns", "blockFasta", "conservation", "propertyConservation", "columnStats", "featureLabels", "scales", "align", "names", "on", "featureName", "rowTintAlpha", "focus", "inside", "opts", "renderToSvg", "html", "blob", "saveAs", "exportFileName", "accession", "pass", "resolvedSelection", "anchor", "head", "ordered", "x", "firstRow", "lastRow", "everyRow", "seed", "mark", "query", "mql", "onChange", "loadOnFilehandleChange", "getFilehandle", "onLoad", "setLoading", "clearFilehandle", "optional", "generation", "cancelInFlight", "current", "isCurrent", "controller", "fetchTextWithProgress", "isAbortError", "appliedGFF", "columnTracks", "model_default", "import_theme", "colorSchemeSnapshot", "scheme", "columnHighlights", "columns", "sorted", "a", "b", "runs", "column", "last", "viewerHighlights", "highlights", "highlightColumns", "urlLocation", "uri", "fileLocations", "msaFilehandle", "treeFilehandle", "gffFilehandle", "msaUrl", "treeUrl", "gffUrl", "resolveTheme", "theme", "viewerSnapshot", "props", "msa", "tree", "gff", "rowData", "colorScheme", "height", "colWidth", "rowHeight", "allowedGappyness", "features", "selection", "clades", "relativeTo", "columnTracks", "residueMappings", "encodings", "rowPanels", "drawTree", "treeAreaWidth", "showBranchLen", "treeOrder", "treeRoot", "region", "residueEncoding", "sameSource", "a", "b", "MSAViewer", "props", "ref", "resolved", "fileLocations", "msa", "tree", "msaFilehandle", "treeFilehandle", "source", "shown", "setShown", "React", "Viewer", "MSAViewer_default", "useModelReaction", "model", "key", "handler", "latest", "listening", "value", "synced", "read", "apply", "inSnapshot", "ifSet", "set", "syncedProps", "p", "m", "v", "location", "gff", "scheme", "viewerHighlights", "table", "useSyncedProps", "applied", "keys", "i", "last", "modelRef", "region", "theme", "onCellHover", "onCellClick", "onViewportChange", "onSelectionChange", "onModel", "model_default", "viewerSnapshot", "destroyTimer", "width", "useMeasure", "regionKey", "target", "latestOnModel", "resolveTheme", "Loading_default", "import_react", "import_client", "mount", "el", "props", "root", "current", "React", "MSAViewer_default", "next", "import_mobx", "ownAttributes", "nightingaleAttributes", "numberAttribute", "value", "n", "parseHighlight", "row", "span", "start", "end", "residueAtColumn", "model", "column", "visible", "residueRange", "viewport", "c", "defineMsaElement", "tagName", "existing", "MsaElement", "#viewer", "#model", "#manager", "#cancelRange", "#rangePending", "#reported", "#data", "#setData", "#referenceRow", "data", "#props", "theme", "cell", "#emit", "#reportHover", "#reportRange", "selection", "#followRange", "#followHighlight", "type", "detail", "#nightingaleChange", "position", "range", "shownStart", "shownEnd", "echo", "reported", "spans", "mount", "manager", "name", "import_react", "import_theme", "import_mobx_state_tree", "import_mobx", "useMsaSvgFigure", "model", "theme", "includeTracks", "delay", "figure", "setFigure", "latest", "dispose", "key", "draw", "renderToSvg", "svg", "error"]
7
+ }