react-msaview 4.8.1 → 5.0.3
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.
- package/README.md +9 -2
- package/bundle/index.js +87 -187
- package/bundle/index.js.LICENSE.txt +0 -83
- package/bundle/index.js.map +1 -1
- package/dist/colorSchemes.js +1 -1
- package/dist/colorSchemes.js.map +1 -1
- package/dist/components/ConservationTrack.d.ts +2 -2
- package/dist/components/ConservationTrack.js +1 -2
- package/dist/components/ConservationTrack.js.map +1 -1
- package/dist/components/Loading.d.ts +1 -1
- package/dist/components/Loading.js +2 -2
- package/dist/components/Loading.js.map +1 -1
- package/dist/components/MSAView.d.ts +1 -1
- package/dist/components/MSAView.js +8 -8
- package/dist/components/MSAView.js.map +1 -1
- package/dist/components/ResizeHandles.d.ts +1 -1
- package/dist/components/SequenceTextArea.js +2 -2
- package/dist/components/SequenceTextArea.js.map +1 -1
- package/dist/components/TextTrack.d.ts +2 -2
- package/dist/components/TextTrack.js +1 -1
- package/dist/components/TextTrack.js.map +1 -1
- package/dist/components/Track.d.ts +1 -1
- package/dist/components/Track.js +1 -1
- package/dist/components/Track.js.map +1 -1
- package/dist/components/VerticalScrollbar.d.ts +1 -1
- package/dist/components/dialogs/AboutDialog.js +1 -1
- package/dist/components/dialogs/AboutDialog.js.map +1 -1
- package/dist/components/dialogs/AddTrackDialog.d.ts +1 -1
- package/dist/components/dialogs/DomainDialog.d.ts +1 -1
- package/dist/components/dialogs/DomainDialog.js +3 -3
- package/dist/components/dialogs/DomainDialog.js.map +1 -1
- package/dist/components/dialogs/ExportSVGDialog.d.ts +1 -1
- package/dist/components/dialogs/ExportSVGDialog.js +1 -1
- package/dist/components/dialogs/ExportSVGDialog.js.map +1 -1
- package/dist/components/dialogs/FeatureDialog.d.ts +1 -1
- package/dist/components/dialogs/FeatureDialog.js +1 -1
- package/dist/components/dialogs/FeatureDialog.js.map +1 -1
- package/dist/components/dialogs/InterProScanDialog.d.ts +1 -1
- package/dist/components/dialogs/InterProScanDialog.js +1 -1
- package/dist/components/dialogs/InterProScanDialog.js.map +1 -1
- package/dist/components/dialogs/MetadataDialog.d.ts +1 -1
- package/dist/components/dialogs/MetadataDialog.js +1 -1
- package/dist/components/dialogs/MetadataDialog.js.map +1 -1
- package/dist/components/dialogs/SettingsDialog.d.ts +1 -1
- package/dist/components/dialogs/SettingsDialog.js +2 -2
- package/dist/components/dialogs/SettingsDialog.js.map +1 -1
- package/dist/components/dialogs/TrackInfoDialog.js +1 -1
- package/dist/components/dialogs/TrackInfoDialog.js.map +1 -1
- package/dist/components/dialogs/UserProvidedDomainsDialog.d.ts +1 -1
- package/dist/components/dialogs/UserProvidedDomainsDialog.js +1 -1
- package/dist/components/dialogs/UserProvidedDomainsDialog.js.map +1 -1
- package/dist/components/header/GappynessSlider.d.ts +1 -1
- package/dist/components/header/Header.d.ts +1 -1
- package/dist/components/header/Header.js +10 -10
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderInfoArea.d.ts +1 -1
- package/dist/components/header/HeaderMenu.d.ts +1 -1
- package/dist/components/header/HeaderMenu.js +6 -6
- package/dist/components/header/HeaderMenu.js.map +1 -1
- package/dist/components/header/HeaderStatusArea.d.ts +1 -1
- package/dist/components/header/MultiAlignmentSelector.d.ts +1 -1
- package/dist/components/header/SettingsMenu.d.ts +1 -1
- package/dist/components/header/SettingsMenu.js +1 -1
- package/dist/components/header/SettingsMenu.js.map +1 -1
- package/dist/components/header/ZoomControls.d.ts +1 -1
- package/dist/components/header/ZoomMenu.d.ts +1 -1
- package/dist/components/header/ZoomStar.d.ts +1 -1
- package/dist/components/import/ImportForm.d.ts +1 -1
- package/dist/components/import/ImportForm.js +2 -2
- package/dist/components/import/ImportForm.js.map +1 -1
- package/dist/components/import/ImportFormExamples.d.ts +1 -1
- package/dist/components/import/ImportFormExamples.js +2 -2
- package/dist/components/import/ImportFormExamples.js.map +1 -1
- package/dist/components/import/util.d.ts +1 -1
- package/dist/components/minimap/Minimap.d.ts +1 -1
- package/dist/components/minimap/MinimapSVG.d.ts +1 -1
- package/dist/components/msa/MSACanvas.d.ts +1 -1
- package/dist/components/msa/MSACanvas.js +2 -2
- package/dist/components/msa/MSACanvas.js.map +1 -1
- package/dist/components/msa/MSACanvasBlock.d.ts +1 -1
- package/dist/components/msa/MSACanvasBlock.js +3 -3
- package/dist/components/msa/MSACanvasBlock.js.map +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.d.ts +1 -1
- package/dist/components/msa/MSAMouseoverCanvas.js +2 -2
- package/dist/components/msa/MSAMouseoverCanvas.js.map +1 -1
- package/dist/components/msa/MSAPanel.d.ts +1 -1
- package/dist/components/msa/MSAPanel.js +2 -2
- package/dist/components/msa/MSAPanel.js.map +1 -1
- package/dist/components/msa/renderBoxFeatureCanvasBlock.d.ts +1 -1
- package/dist/components/msa/renderMSABlock.d.ts +1 -1
- package/dist/components/msa/renderMSAMouseover.d.ts +1 -1
- package/dist/components/tracks/renderTracksSvg.d.ts +2 -2
- package/dist/components/tree/TreeBranchMenu.d.ts +1 -1
- package/dist/components/tree/TreeCanvas.d.ts +1 -1
- package/dist/components/tree/TreeCanvas.js +3 -3
- package/dist/components/tree/TreeCanvas.js.map +1 -1
- package/dist/components/tree/TreeCanvasBlock.d.ts +1 -1
- package/dist/components/tree/TreeCanvasBlock.js +3 -3
- package/dist/components/tree/TreeCanvasBlock.js.map +1 -1
- package/dist/components/tree/TreeNodeMenu.d.ts +1 -1
- package/dist/components/tree/TreeNodeMenu.js +1 -1
- package/dist/components/tree/TreeNodeMenu.js.map +1 -1
- package/dist/components/tree/TreePanel.d.ts +1 -1
- package/dist/components/tree/TreePanel.js +1 -1
- package/dist/components/tree/TreePanel.js.map +1 -1
- package/dist/components/tree/TreeRuler.d.ts +1 -1
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.d.ts +1 -1
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.js +1 -1
- package/dist/components/tree/dialogs/TreeNodeInfoDialog.js.map +1 -1
- package/dist/components/tree/renderTreeCanvas.d.ts +1 -1
- package/dist/createPaletteMap.d.ts +7 -0
- package/dist/createPaletteMap.js +11 -0
- package/dist/createPaletteMap.js.map +1 -0
- package/dist/createPaletteMap.test.d.ts +1 -0
- package/dist/createPaletteMap.test.js +49 -0
- package/dist/createPaletteMap.test.js.map +1 -0
- package/dist/index.d.ts +3 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/launchInterProScan.d.ts +1 -1
- package/dist/launchInterProScan.js +1 -1
- package/dist/launchInterProScan.js.map +1 -1
- package/dist/model/DataModel.d.ts +5 -5
- package/dist/model/DataModel.js +1 -1
- package/dist/model/DataModel.js.map +1 -1
- package/dist/model/DialogQueue.d.ts +2 -2
- package/dist/model/DialogQueue.js +1 -1
- package/dist/model/DialogQueue.js.map +1 -1
- package/dist/model/msaModel.d.ts +4 -4
- package/dist/model/msaModel.js +2 -2
- package/dist/model/msaModel.js.map +1 -1
- package/dist/model/treeModel.d.ts +10 -10
- package/dist/model/treeModel.js +2 -2
- package/dist/model/treeModel.js.map +1 -1
- package/dist/model.d.ts +524 -420
- package/dist/model.js +63 -40
- package/dist/model.js.map +1 -1
- package/dist/neighborJoining.test.js +1 -1
- package/dist/neighborJoining.test.js.map +1 -1
- package/dist/parseAsn1.test.js +1 -1
- package/dist/parseAsn1.test.js.map +1 -1
- package/dist/renderToSvg.d.ts +1 -1
- package/dist/renderToSvg.js +10 -10
- package/dist/renderToSvg.js.map +1 -1
- package/dist/reparseTree.d.ts +1 -1
- package/dist/rowCoordinateCalculations.js +1 -1
- package/dist/rowCoordinateCalculations.js.map +1 -1
- package/dist/rowCoordinateCalculations.test.js +1 -1
- package/dist/rowCoordinateCalculations.test.js.map +1 -1
- package/dist/seqPosToGlobalCol.js +1 -1
- package/dist/seqPosToGlobalCol.js.map +1 -1
- package/dist/seqPosToGlobalCol.test.js +1 -1
- package/dist/seqPosToGlobalCol.test.js.map +1 -1
- package/dist/util.d.ts +1 -1
- package/dist/vendor/copyToClipboard.d.ts +10 -0
- package/dist/vendor/copyToClipboard.js +113 -0
- package/dist/vendor/copyToClipboard.js.map +1 -0
- package/dist/vendor/fileSaver.d.ts +11 -0
- package/dist/vendor/fileSaver.js +80 -0
- package/dist/vendor/fileSaver.js.map +1 -0
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/webpack.d.ts +2 -2
- package/dist/webpack.js +2 -2
- package/dist/webpack.js.map +1 -1
- package/package.json +26 -23
- package/src/colorSchemes.ts +1 -1
- package/src/components/ConservationTrack.tsx +3 -4
- package/src/components/Loading.tsx +3 -3
- package/src/components/MSAView.tsx +12 -9
- package/src/components/ResizeHandles.tsx +1 -1
- package/src/components/SequenceTextArea.tsx +2 -2
- package/src/components/TextTrack.tsx +3 -3
- package/src/components/Track.tsx +2 -2
- package/src/components/VerticalScrollbar.tsx +1 -1
- package/src/components/dialogs/AboutDialog.tsx +1 -1
- package/src/components/dialogs/AddTrackDialog.tsx +1 -1
- package/src/components/dialogs/DomainDialog.tsx +4 -4
- package/src/components/dialogs/ExportSVGDialog.tsx +2 -2
- package/src/components/dialogs/FeatureDialog.tsx +2 -2
- package/src/components/dialogs/InterProScanDialog.tsx +2 -2
- package/src/components/dialogs/MetadataDialog.tsx +2 -2
- package/src/components/dialogs/SettingsDialog.tsx +3 -3
- package/src/components/dialogs/TrackInfoDialog.tsx +2 -1
- package/src/components/dialogs/UserProvidedDomainsDialog.tsx +3 -3
- package/src/components/header/GappynessSlider.tsx +1 -1
- package/src/components/header/Header.tsx +11 -11
- package/src/components/header/HeaderInfoArea.tsx +1 -1
- package/src/components/header/HeaderMenu.tsx +9 -7
- package/src/components/header/HeaderStatusArea.tsx +1 -1
- package/src/components/header/MultiAlignmentSelector.tsx +1 -1
- package/src/components/header/SettingsMenu.tsx +2 -2
- package/src/components/header/ZoomControls.tsx +1 -1
- package/src/components/header/ZoomMenu.tsx +1 -1
- package/src/components/header/ZoomStar.tsx +1 -1
- package/src/components/import/ImportForm.tsx +3 -3
- package/src/components/import/ImportFormExamples.tsx +3 -3
- package/src/components/import/util.ts +1 -1
- package/src/components/minimap/Minimap.tsx +1 -1
- package/src/components/minimap/MinimapSVG.tsx +1 -1
- package/src/components/msa/MSACanvas.tsx +3 -3
- package/src/components/msa/MSACanvasBlock.tsx +4 -4
- package/src/components/msa/MSAMouseoverCanvas.tsx +3 -3
- package/src/components/msa/MSAPanel.tsx +3 -3
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +2 -2
- package/src/components/msa/renderMSABlock.ts +2 -2
- package/src/components/msa/renderMSAMouseover.ts +1 -1
- package/src/components/tracks/renderTracksSvg.ts +2 -2
- package/src/components/tree/TreeBranchMenu.tsx +1 -1
- package/src/components/tree/TreeCanvas.tsx +4 -4
- package/src/components/tree/TreeCanvasBlock.tsx +4 -4
- package/src/components/tree/TreeNodeMenu.tsx +4 -2
- package/src/components/tree/TreePanel.tsx +2 -2
- package/src/components/tree/TreeRuler.tsx +1 -1
- package/src/components/tree/dialogs/TreeNodeInfoDialog.tsx +2 -2
- package/src/components/tree/renderTreeCanvas.ts +1 -1
- package/src/createPaletteMap.test.ts +57 -0
- package/src/createPaletteMap.ts +11 -0
- package/src/index.ts +3 -2
- package/src/launchInterProScan.ts +2 -2
- package/src/model/DataModel.ts +1 -1
- package/src/model/DialogQueue.ts +1 -1
- package/src/model/msaModel.ts +2 -2
- package/src/model/treeModel.ts +2 -2
- package/src/model.ts +71 -46
- package/src/neighborJoining.test.ts +1 -1
- package/src/parseAsn1.test.ts +1 -1
- package/src/renderToSvg.tsx +17 -19
- package/src/reparseTree.ts +1 -1
- package/src/rowCoordinateCalculations.test.ts +1 -1
- package/src/rowCoordinateCalculations.ts +1 -1
- package/src/seqPosToGlobalCol.test.ts +1 -1
- package/src/seqPosToGlobalCol.ts +1 -1
- package/src/util.ts +1 -1
- package/src/vendor/copyToClipboard.ts +125 -0
- package/src/vendor/fileSaver.ts +107 -0
- package/src/version.ts +1 -1
- package/src/webpack.ts +2 -2
- package/dist/__snapshots__/parseAsn1.test.js.snap +0 -2400
- package/src/declare.d.ts +0 -1
package/src/model.ts
CHANGED
|
@@ -9,6 +9,11 @@ import {
|
|
|
9
9
|
} from '@jbrowse/core/util'
|
|
10
10
|
import { openLocation } from '@jbrowse/core/util/io'
|
|
11
11
|
import { ElementId, FileLocation } from '@jbrowse/core/util/types/mst'
|
|
12
|
+
import { addDisposer, cast, types } from '@jbrowse/mobx-state-tree'
|
|
13
|
+
import { colord } from 'colord'
|
|
14
|
+
import { ascending } from 'd3-array'
|
|
15
|
+
import { cluster, hierarchy } from 'd3-hierarchy'
|
|
16
|
+
import { autorun, transaction } from 'mobx'
|
|
12
17
|
import {
|
|
13
18
|
A3mMSA,
|
|
14
19
|
ClustalMSA,
|
|
@@ -22,17 +27,11 @@ import {
|
|
|
22
27
|
parseNewick,
|
|
23
28
|
stockholmSniff,
|
|
24
29
|
} from 'msa-parsers'
|
|
25
|
-
import { colord } from 'colord'
|
|
26
|
-
import { ascending } from 'd3-array'
|
|
27
|
-
import { cluster, hierarchy } from 'd3-hierarchy'
|
|
28
|
-
import { saveAs } from 'file-saver'
|
|
29
|
-
import { autorun, transaction } from 'mobx'
|
|
30
|
-
import { addDisposer, cast, types } from 'mobx-state-tree'
|
|
31
30
|
|
|
32
|
-
import { blocksX, blocksY } from './calculateBlocks'
|
|
33
|
-
import colorSchemes from './colorSchemes'
|
|
34
|
-
import ConservationTrack from './components/ConservationTrack'
|
|
35
|
-
import TextTrack from './components/TextTrack'
|
|
31
|
+
import { blocksX, blocksY } from './calculateBlocks.ts'
|
|
32
|
+
import colorSchemes from './colorSchemes.ts'
|
|
33
|
+
import ConservationTrack from './components/ConservationTrack.tsx'
|
|
34
|
+
import TextTrack from './components/TextTrack.tsx'
|
|
36
35
|
import {
|
|
37
36
|
defaultAllowedGappyness,
|
|
38
37
|
defaultBgColor,
|
|
@@ -56,37 +55,38 @@ import {
|
|
|
56
55
|
defaultTreeAreaWidth,
|
|
57
56
|
defaultTreeWidth,
|
|
58
57
|
defaultTreeWidthMatchesArea,
|
|
59
|
-
} from './constants'
|
|
60
|
-
import {
|
|
61
|
-
import
|
|
62
|
-
import { measureTextCanvas } from './measureTextCanvas'
|
|
63
|
-
import { DataModelF } from './model/DataModel'
|
|
64
|
-
import { DialogQueueSessionMixin } from './model/DialogQueue'
|
|
65
|
-
import { MSAModelF } from './model/msaModel'
|
|
66
|
-
import { TreeModelF } from './model/treeModel'
|
|
67
|
-
import { calculateNeighborJoiningTree } from './neighborJoining'
|
|
68
|
-
import { parseAsn1 } from './parseAsn1'
|
|
69
|
-
import { reparseTree } from './reparseTree'
|
|
58
|
+
} from './constants.ts'
|
|
59
|
+
import { createPaletteMap } from './createPaletteMap.ts'
|
|
60
|
+
import { flatToTree } from './flatToTree.ts'
|
|
61
|
+
import { measureTextCanvas } from './measureTextCanvas.ts'
|
|
62
|
+
import { DataModelF } from './model/DataModel.ts'
|
|
63
|
+
import { DialogQueueSessionMixin } from './model/DialogQueue.ts'
|
|
64
|
+
import { MSAModelF } from './model/msaModel.ts'
|
|
65
|
+
import { TreeModelF } from './model/treeModel.ts'
|
|
66
|
+
import { calculateNeighborJoiningTree } from './neighborJoining.ts'
|
|
67
|
+
import { parseAsn1 } from './parseAsn1.ts'
|
|
68
|
+
import { reparseTree } from './reparseTree.ts'
|
|
70
69
|
import {
|
|
71
70
|
globalColToVisibleCol,
|
|
72
71
|
visibleColToGlobalCol,
|
|
73
72
|
visibleColToSeqPosForRow,
|
|
74
|
-
} from './rowCoordinateCalculations'
|
|
75
|
-
import { seqPosToGlobalCol } from './seqPosToGlobalCol'
|
|
76
|
-
import { collapse, len, maxLength, setBrLength, skipBlanks } from './util'
|
|
73
|
+
} from './rowCoordinateCalculations.ts'
|
|
74
|
+
import { seqPosToGlobalCol } from './seqPosToGlobalCol.ts'
|
|
75
|
+
import { collapse, len, maxLength, setBrLength, skipBlanks } from './util.ts'
|
|
76
|
+
import { saveAs } from './vendor/fileSaver.ts'
|
|
77
77
|
|
|
78
|
-
import type { InterProScanResults } from './launchInterProScan'
|
|
78
|
+
import type { InterProScanResults } from './launchInterProScan.ts'
|
|
79
79
|
import type {
|
|
80
80
|
Accession,
|
|
81
81
|
BasicTrack,
|
|
82
82
|
NodeWithIds,
|
|
83
83
|
NodeWithIdsAndLength,
|
|
84
84
|
TextTrackModel,
|
|
85
|
-
} from './types'
|
|
85
|
+
} from './types.ts'
|
|
86
86
|
import type { FileLocation as FileLocationType } from '@jbrowse/core/util/types'
|
|
87
|
+
import type { Instance } from '@jbrowse/mobx-state-tree'
|
|
87
88
|
import type { Theme } from '@mui/material'
|
|
88
89
|
import type { HierarchyNode } from 'd3-hierarchy'
|
|
89
|
-
import type { Instance } from 'mobx-state-tree'
|
|
90
90
|
|
|
91
91
|
const showZoomStarKey = 'msa-showZoomStar'
|
|
92
92
|
|
|
@@ -460,7 +460,7 @@ function stateModelFactory() {
|
|
|
460
460
|
}
|
|
461
461
|
|
|
462
462
|
// Get all descendant leaf names
|
|
463
|
-
const descendantNames = node.leaves().map(
|
|
463
|
+
const descendantNames = node.leaves().map(leaf => leaf.data.name)
|
|
464
464
|
|
|
465
465
|
self.hoveredTreeNode = { nodeId, descendantNames }
|
|
466
466
|
},
|
|
@@ -999,6 +999,34 @@ function stateModelFactory() {
|
|
|
999
999
|
return this.colStats.map(val => sum(Object.values(val)))
|
|
1000
1000
|
},
|
|
1001
1001
|
|
|
1002
|
+
/**
|
|
1003
|
+
* #getter
|
|
1004
|
+
* Detects sequence type based on letters present in the alignment.
|
|
1005
|
+
* Returns 'dna', 'rna', or 'amino'.
|
|
1006
|
+
*/
|
|
1007
|
+
get sequenceType(): 'dna' | 'rna' | 'amino' {
|
|
1008
|
+
const letters = new Set<string>()
|
|
1009
|
+
for (const stats of this.colStats) {
|
|
1010
|
+
for (const letter of Object.keys(stats)) {
|
|
1011
|
+
const upper = letter.toUpperCase()
|
|
1012
|
+
if (upper !== '-' && upper !== '.') {
|
|
1013
|
+
letters.add(upper)
|
|
1014
|
+
}
|
|
1015
|
+
}
|
|
1016
|
+
}
|
|
1017
|
+
const dna = new Set(['A', 'C', 'G', 'T', 'N'])
|
|
1018
|
+
const rna = new Set(['A', 'C', 'G', 'U', 'N'])
|
|
1019
|
+
const isDna = [...letters].every(l => dna.has(l))
|
|
1020
|
+
const isRna = [...letters].every(l => rna.has(l))
|
|
1021
|
+
if (isDna && !letters.has('U')) {
|
|
1022
|
+
return 'dna'
|
|
1023
|
+
}
|
|
1024
|
+
if (isRna && !letters.has('T')) {
|
|
1025
|
+
return 'rna'
|
|
1026
|
+
}
|
|
1027
|
+
return 'amino'
|
|
1028
|
+
},
|
|
1029
|
+
|
|
1002
1030
|
/**
|
|
1003
1031
|
* #getter
|
|
1004
1032
|
* Pre-computed consensus letter and percent identity color per column.
|
|
@@ -1175,8 +1203,8 @@ function stateModelFactory() {
|
|
|
1175
1203
|
* Returns values 0-1 where 1 = fully conserved, 0 = no conservation.
|
|
1176
1204
|
*/
|
|
1177
1205
|
get conservation() {
|
|
1178
|
-
const { colStats, colStatsSums } = this
|
|
1179
|
-
const alphabetSize = 20
|
|
1206
|
+
const { colStats, colStatsSums, sequenceType } = this
|
|
1207
|
+
const alphabetSize = sequenceType === 'amino' ? 20 : 4
|
|
1180
1208
|
const maxEntropy = Math.log2(alphabetSize)
|
|
1181
1209
|
|
|
1182
1210
|
return colStats.map((stats, i) => {
|
|
@@ -1191,13 +1219,18 @@ function stateModelFactory() {
|
|
|
1191
1219
|
return 0
|
|
1192
1220
|
}
|
|
1193
1221
|
|
|
1194
|
-
|
|
1222
|
+
const merged: Record<string, number> = {}
|
|
1195
1223
|
for (const letter of Object.keys(stats)) {
|
|
1196
1224
|
if (letter === '-' || letter === '.') {
|
|
1197
1225
|
continue
|
|
1198
1226
|
}
|
|
1199
|
-
const
|
|
1200
|
-
|
|
1227
|
+
const upper = letter.toUpperCase()
|
|
1228
|
+
merged[upper] = (merged[upper] || 0) + stats[letter]!
|
|
1229
|
+
}
|
|
1230
|
+
|
|
1231
|
+
let entropy = 0
|
|
1232
|
+
for (const key of Object.keys(merged)) {
|
|
1233
|
+
const freq = merged[key]! / nonGapTotal
|
|
1201
1234
|
if (freq > 0) {
|
|
1202
1235
|
entropy -= freq * Math.log2(freq)
|
|
1203
1236
|
}
|
|
@@ -1612,9 +1645,9 @@ function stateModelFactory() {
|
|
|
1612
1645
|
* @returns The global column index in the full MSA
|
|
1613
1646
|
*/
|
|
1614
1647
|
seqPosToGlobalCol(rowName: string, seqPos: number) {
|
|
1615
|
-
const {
|
|
1616
|
-
const index =
|
|
1617
|
-
return index !==
|
|
1648
|
+
const { rows } = self
|
|
1649
|
+
const index = this.rowNamesSet.get(rowName)
|
|
1650
|
+
return index !== undefined && rows[index]
|
|
1618
1651
|
? seqPosToGlobalCol({
|
|
1619
1652
|
row: rows[index][1],
|
|
1620
1653
|
seqPos,
|
|
@@ -1728,15 +1761,7 @@ function stateModelFactory() {
|
|
|
1728
1761
|
* #getter
|
|
1729
1762
|
*/
|
|
1730
1763
|
get fillPalette() {
|
|
1731
|
-
|
|
1732
|
-
let i = 0
|
|
1733
|
-
const map = {} as Record<string, string>
|
|
1734
|
-
for (const key of arr) {
|
|
1735
|
-
const k = Math.min(arr.length - 1, palettes.length - 1)
|
|
1736
|
-
map[key] = palettes[k]![i]!
|
|
1737
|
-
i++
|
|
1738
|
-
}
|
|
1739
|
-
return map
|
|
1764
|
+
return createPaletteMap([...self.tidyInterProAnnotationTypes.keys()])
|
|
1740
1765
|
},
|
|
1741
1766
|
/**
|
|
1742
1767
|
* #getter
|
|
@@ -1792,7 +1817,7 @@ function stateModelFactory() {
|
|
|
1792
1817
|
includeTracks?: boolean
|
|
1793
1818
|
exportType: string
|
|
1794
1819
|
}) {
|
|
1795
|
-
const { renderToSvg } = await import('./renderToSvg')
|
|
1820
|
+
const { renderToSvg } = await import('./renderToSvg.tsx')
|
|
1796
1821
|
const html = await renderToSvg(self as MsaViewModel, opts)
|
|
1797
1822
|
const blob = new Blob([html], { type: 'image/svg+xml' })
|
|
1798
1823
|
saveAs(blob, 'image.svg')
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { calculateNeighborJoiningTree } from './neighborJoining'
|
|
3
|
+
import { calculateNeighborJoiningTree } from './neighborJoining.ts'
|
|
4
4
|
|
|
5
5
|
describe('calculateNeighborJoiningTree', () => {
|
|
6
6
|
test('generates valid Newick tree for 2 sequences', () => {
|
package/src/parseAsn1.test.ts
CHANGED
package/src/renderToSvg.tsx
CHANGED
|
@@ -4,15 +4,16 @@ import React from 'react'
|
|
|
4
4
|
import { renderToStaticMarkup } from '@jbrowse/core/util'
|
|
5
5
|
import { when } from 'mobx'
|
|
6
6
|
|
|
7
|
-
import MinimapSVG from './components/minimap/MinimapSVG'
|
|
8
|
-
import { renderBoxFeatureCanvasBlock } from './components/msa/renderBoxFeatureCanvasBlock'
|
|
9
|
-
import { renderMSABlock } from './components/msa/renderMSABlock'
|
|
10
|
-
import { renderAllTracks } from './components/tracks/renderTracksSvg'
|
|
11
|
-
import { renderTreeCanvas } from './components/tree/renderTreeCanvas'
|
|
12
|
-
import { colorContrast } from './util'
|
|
7
|
+
import MinimapSVG from './components/minimap/MinimapSVG.tsx'
|
|
8
|
+
import { renderBoxFeatureCanvasBlock } from './components/msa/renderBoxFeatureCanvasBlock.ts'
|
|
9
|
+
import { renderMSABlock } from './components/msa/renderMSABlock.ts'
|
|
10
|
+
import { renderAllTracks } from './components/tracks/renderTracksSvg.ts'
|
|
11
|
+
import { renderTreeCanvas } from './components/tree/renderTreeCanvas.ts'
|
|
12
|
+
import { colorContrast } from './util.ts'
|
|
13
13
|
|
|
14
|
-
import type { MsaViewModel } from './model'
|
|
14
|
+
import type { MsaViewModel } from './model.ts'
|
|
15
15
|
import type { Theme } from '@mui/material'
|
|
16
|
+
import type { Context as ContextType } from '@jbrowse/svgcanvas'
|
|
16
17
|
|
|
17
18
|
export interface ExportSvgOptions {
|
|
18
19
|
theme: Theme
|
|
@@ -80,7 +81,7 @@ async function render({
|
|
|
80
81
|
includeMinimap?: boolean
|
|
81
82
|
includeTracks?: boolean
|
|
82
83
|
}) {
|
|
83
|
-
const { Context } = await import('svgcanvas')
|
|
84
|
+
const { Context } = await import('@jbrowse/svgcanvas')
|
|
84
85
|
const Wrapper = includeMinimap ? MinimapWrapper : NullWrapper
|
|
85
86
|
|
|
86
87
|
return renderToStaticMarkup(
|
|
@@ -131,17 +132,16 @@ function CoreRendering({
|
|
|
131
132
|
contentHeight: number
|
|
132
133
|
offsetX: number
|
|
133
134
|
offsetY: number
|
|
134
|
-
Context:
|
|
135
|
-
width: number,
|
|
136
|
-
height: number,
|
|
137
|
-
) => CanvasRenderingContext2D & { getSvg: () => { innerHTML: string } }
|
|
135
|
+
Context: typeof ContextType
|
|
138
136
|
}) {
|
|
139
137
|
const { treeAreaWidth, colorScheme, id } = model
|
|
140
138
|
const clipId1 = `tree-${id}`
|
|
141
139
|
const clipId2 = `msa-${id}`
|
|
142
140
|
const contrastScheme = colorContrast(colorScheme, theme)
|
|
143
|
-
|
|
144
|
-
const
|
|
141
|
+
|
|
142
|
+
const ctx1 = new Context(width, contentHeight) as any
|
|
143
|
+
|
|
144
|
+
const ctx2 = new Context(width, contentHeight) as any
|
|
145
145
|
renderBoxFeatureCanvasBlock({
|
|
146
146
|
ctx: ctx2,
|
|
147
147
|
offsetX,
|
|
@@ -209,16 +209,14 @@ function TrackRendering({
|
|
|
209
209
|
width: number
|
|
210
210
|
trackHeight: number
|
|
211
211
|
offsetX: number
|
|
212
|
-
Context:
|
|
213
|
-
width: number,
|
|
214
|
-
height: number,
|
|
215
|
-
) => CanvasRenderingContext2D & { getSvg: () => { innerHTML: string } }
|
|
212
|
+
Context: typeof ContextType
|
|
216
213
|
}) {
|
|
217
214
|
const { treeAreaWidth, colorScheme, id } = model
|
|
218
215
|
const clipId = `tracks-${id}`
|
|
219
216
|
const contrastScheme = colorContrast(colorScheme, theme)
|
|
220
217
|
const msaAreaWidth = width - treeAreaWidth
|
|
221
|
-
|
|
218
|
+
|
|
219
|
+
const ctx = new Context(msaAreaWidth, trackHeight) as any
|
|
222
220
|
|
|
223
221
|
renderAllTracks({
|
|
224
222
|
model,
|
package/src/reparseTree.ts
CHANGED
|
@@ -5,7 +5,7 @@ import {
|
|
|
5
5
|
globalColToVisibleCol,
|
|
6
6
|
visibleColToGlobalCol,
|
|
7
7
|
visibleColToSeqPos,
|
|
8
|
-
} from './rowCoordinateCalculations'
|
|
8
|
+
} from './rowCoordinateCalculations.ts'
|
|
9
9
|
|
|
10
10
|
// Tests for visibleColToGlobalCol (visible → global)
|
|
11
11
|
test('visibleColToGlobalCol with blanks at positions [2, 5, 8]', () => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { describe, expect, test } from 'vitest'
|
|
2
2
|
|
|
3
|
-
import { seqPosToGlobalCol } from './seqPosToGlobalCol'
|
|
3
|
+
import { seqPosToGlobalCol } from './seqPosToGlobalCol.ts'
|
|
4
4
|
|
|
5
5
|
describe('seqPosToGlobalCol', () => {
|
|
6
6
|
test('converts sequence position to global column with no gaps', () => {
|
package/src/seqPosToGlobalCol.ts
CHANGED
package/src/util.ts
CHANGED
|
@@ -2,7 +2,7 @@ import { colord, extend } from 'colord'
|
|
|
2
2
|
import namesPlugin from 'colord/plugins/names'
|
|
3
3
|
import { max } from 'd3-array'
|
|
4
4
|
|
|
5
|
-
import type { NodeWithIds } from './types'
|
|
5
|
+
import type { NodeWithIds } from './types.ts'
|
|
6
6
|
import type { Theme } from '@mui/material'
|
|
7
7
|
import type { HierarchyNode } from 'd3-hierarchy'
|
|
8
8
|
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Copy text to clipboard utility.
|
|
3
|
+
* Uses modern Clipboard API with fallback to execCommand.
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
function deselectCurrent() {
|
|
7
|
+
const selection = document.getSelection()
|
|
8
|
+
if (!selection?.rangeCount) {
|
|
9
|
+
return () => {}
|
|
10
|
+
}
|
|
11
|
+
const active = document.activeElement as HTMLElement | null
|
|
12
|
+
|
|
13
|
+
const ranges: Range[] = []
|
|
14
|
+
for (let i = 0; i < selection.rangeCount; i++) {
|
|
15
|
+
ranges.push(selection.getRangeAt(i))
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
const tagName = active?.tagName.toUpperCase()
|
|
19
|
+
if (tagName === 'INPUT' || tagName === 'TEXTAREA') {
|
|
20
|
+
active?.blur()
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
selection.removeAllRanges()
|
|
24
|
+
return () => {
|
|
25
|
+
if (selection.type === 'Caret') {
|
|
26
|
+
selection.removeAllRanges()
|
|
27
|
+
}
|
|
28
|
+
if (!selection.rangeCount) {
|
|
29
|
+
for (const range of ranges) {
|
|
30
|
+
selection.addRange(range)
|
|
31
|
+
}
|
|
32
|
+
}
|
|
33
|
+
active?.focus()
|
|
34
|
+
}
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
export interface CopyOptions {
|
|
38
|
+
debug?: boolean
|
|
39
|
+
format?: string
|
|
40
|
+
onCopy?: (clipboardData: DataTransfer) => void
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
export default function copy(text: string, options?: CopyOptions): boolean {
|
|
44
|
+
const debug = options?.debug || false
|
|
45
|
+
let success = false
|
|
46
|
+
let reselectPrevious: (() => void) | undefined
|
|
47
|
+
let range: Range | undefined
|
|
48
|
+
let selection: Selection | null = null
|
|
49
|
+
let mark: HTMLSpanElement | undefined
|
|
50
|
+
|
|
51
|
+
try {
|
|
52
|
+
reselectPrevious = deselectCurrent()
|
|
53
|
+
range = document.createRange()
|
|
54
|
+
selection = document.getSelection()
|
|
55
|
+
|
|
56
|
+
mark = document.createElement('span')
|
|
57
|
+
mark.textContent = text
|
|
58
|
+
mark.ariaHidden = 'true'
|
|
59
|
+
mark.style.all = 'unset'
|
|
60
|
+
mark.style.position = 'fixed'
|
|
61
|
+
mark.style.top = '0'
|
|
62
|
+
mark.style.clip = 'rect(0, 0, 0, 0)'
|
|
63
|
+
mark.style.whiteSpace = 'pre'
|
|
64
|
+
mark.style.webkitUserSelect = 'text'
|
|
65
|
+
;(mark.style as unknown as Record<string, string>).MozUserSelect = 'text'
|
|
66
|
+
;(mark.style as unknown as Record<string, string>).msUserSelect = 'text'
|
|
67
|
+
mark.style.userSelect = 'text'
|
|
68
|
+
|
|
69
|
+
mark.addEventListener('copy', e => {
|
|
70
|
+
e.stopPropagation()
|
|
71
|
+
if (options?.format) {
|
|
72
|
+
e.preventDefault()
|
|
73
|
+
if (e.clipboardData) {
|
|
74
|
+
e.clipboardData.clearData()
|
|
75
|
+
e.clipboardData.setData(options.format, text)
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
if (options?.onCopy && e.clipboardData) {
|
|
79
|
+
e.preventDefault()
|
|
80
|
+
options.onCopy(e.clipboardData)
|
|
81
|
+
}
|
|
82
|
+
})
|
|
83
|
+
|
|
84
|
+
document.body.append(mark)
|
|
85
|
+
range.selectNodeContents(mark)
|
|
86
|
+
selection?.addRange(range)
|
|
87
|
+
|
|
88
|
+
const successful = document.execCommand('copy')
|
|
89
|
+
if (!successful) {
|
|
90
|
+
throw new Error('copy command was unsuccessful')
|
|
91
|
+
}
|
|
92
|
+
success = true
|
|
93
|
+
} catch (err) {
|
|
94
|
+
if (debug) {
|
|
95
|
+
console.error('unable to copy using execCommand:', err)
|
|
96
|
+
}
|
|
97
|
+
try {
|
|
98
|
+
const clipboardData = (window as unknown as Record<string, DataTransfer>)
|
|
99
|
+
.clipboardData
|
|
100
|
+
if (clipboardData) {
|
|
101
|
+
clipboardData.setData(options?.format || 'text', text)
|
|
102
|
+
options?.onCopy?.(clipboardData)
|
|
103
|
+
success = true
|
|
104
|
+
}
|
|
105
|
+
} catch (err2) {
|
|
106
|
+
if (debug) {
|
|
107
|
+
console.error('unable to copy using clipboardData:', err2)
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
} finally {
|
|
111
|
+
if (selection) {
|
|
112
|
+
if (typeof selection.removeRange === 'function' && range) {
|
|
113
|
+
selection.removeRange(range)
|
|
114
|
+
} else {
|
|
115
|
+
selection.removeAllRanges()
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
if (mark) {
|
|
119
|
+
mark.remove()
|
|
120
|
+
}
|
|
121
|
+
reselectPrevious?.()
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
return success
|
|
125
|
+
}
|
|
@@ -0,0 +1,107 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* FileSaver.js
|
|
3
|
+
* A saveAs() FileSaver implementation.
|
|
4
|
+
*
|
|
5
|
+
* By Eli Grey, http://eligrey.com
|
|
6
|
+
* License: MIT
|
|
7
|
+
* source: http://purl.eligrey.com/github/FileSaver.js
|
|
8
|
+
*
|
|
9
|
+
* Vendored and converted to ESM/TypeScript for pure ESM compatibility.
|
|
10
|
+
*/
|
|
11
|
+
|
|
12
|
+
function click(node: HTMLAnchorElement) {
|
|
13
|
+
try {
|
|
14
|
+
node.dispatchEvent(new MouseEvent('click'))
|
|
15
|
+
} catch {
|
|
16
|
+
const evt = document.createEvent('MouseEvents')
|
|
17
|
+
evt.initMouseEvent(
|
|
18
|
+
'click',
|
|
19
|
+
true,
|
|
20
|
+
true,
|
|
21
|
+
window,
|
|
22
|
+
0,
|
|
23
|
+
0,
|
|
24
|
+
0,
|
|
25
|
+
80,
|
|
26
|
+
20,
|
|
27
|
+
false,
|
|
28
|
+
false,
|
|
29
|
+
false,
|
|
30
|
+
false,
|
|
31
|
+
0,
|
|
32
|
+
null,
|
|
33
|
+
)
|
|
34
|
+
node.dispatchEvent(evt)
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
// Detect WebView inside a native macOS app by ruling out all browsers
|
|
39
|
+
const isMacOSWebView =
|
|
40
|
+
typeof navigator !== 'undefined' &&
|
|
41
|
+
navigator.userAgent.includes('Macintosh') &&
|
|
42
|
+
navigator.userAgent.includes('AppleWebKit') &&
|
|
43
|
+
!navigator.userAgent.includes('Safari')
|
|
44
|
+
|
|
45
|
+
export function saveAs(blob: Blob | string, name?: string) {
|
|
46
|
+
if (typeof window === 'undefined') {
|
|
47
|
+
return
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
const URL = window.URL
|
|
51
|
+
const a = document.createElement('a')
|
|
52
|
+
name = name || (blob instanceof Blob ? 'download' : 'download')
|
|
53
|
+
|
|
54
|
+
// Use download attribute if available and not macOS WebView
|
|
55
|
+
if ('download' in HTMLAnchorElement.prototype && !isMacOSWebView) {
|
|
56
|
+
a.download = name
|
|
57
|
+
a.rel = 'noopener'
|
|
58
|
+
|
|
59
|
+
if (typeof blob === 'string') {
|
|
60
|
+
a.href = blob
|
|
61
|
+
click(a)
|
|
62
|
+
} else {
|
|
63
|
+
a.href = URL.createObjectURL(blob)
|
|
64
|
+
setTimeout(() => {
|
|
65
|
+
URL.revokeObjectURL(a.href)
|
|
66
|
+
}, 40000)
|
|
67
|
+
setTimeout(() => {
|
|
68
|
+
click(a)
|
|
69
|
+
}, 0)
|
|
70
|
+
}
|
|
71
|
+
return
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
// Fallback for browsers without download attribute support
|
|
75
|
+
if (typeof blob === 'string') {
|
|
76
|
+
window.open(blob, '_blank')
|
|
77
|
+
return
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
const isSafari =
|
|
81
|
+
/constructor/i.test(
|
|
82
|
+
(window as unknown as { HTMLElement: unknown }).HTMLElement?.toString() ??
|
|
83
|
+
'',
|
|
84
|
+
) || !!(window as unknown as { safari?: unknown }).safari
|
|
85
|
+
const isChromeIOS = /CriOS\/[\d]+/.test(navigator.userAgent)
|
|
86
|
+
|
|
87
|
+
if (
|
|
88
|
+
(isChromeIOS || isSafari || isMacOSWebView) &&
|
|
89
|
+
typeof FileReader !== 'undefined'
|
|
90
|
+
) {
|
|
91
|
+
const reader = new FileReader()
|
|
92
|
+
reader.onloadend = () => {
|
|
93
|
+
let url = reader.result as string
|
|
94
|
+
url = isChromeIOS
|
|
95
|
+
? url
|
|
96
|
+
: url.replace(/^data:[^;]*;/, 'data:attachment/file;')
|
|
97
|
+
window.open(url, '_blank')
|
|
98
|
+
}
|
|
99
|
+
reader.readAsDataURL(blob)
|
|
100
|
+
} else {
|
|
101
|
+
const url = URL.createObjectURL(blob)
|
|
102
|
+
window.open(url, '_blank')
|
|
103
|
+
setTimeout(() => {
|
|
104
|
+
URL.revokeObjectURL(url)
|
|
105
|
+
}, 40000)
|
|
106
|
+
}
|
|
107
|
+
}
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '
|
|
1
|
+
export const version = '5.0.3'
|
package/src/webpack.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import * as React from 'react'
|
|
2
2
|
|
|
3
|
-
export { default as MSAView } from './components/Loading'
|
|
4
|
-
export { type MsaViewModel, default as MSAModelF } from './model'
|
|
3
|
+
export { default as MSAView } from './components/Loading.tsx'
|
|
4
|
+
export { type MsaViewModel, default as MSAModelF } from './model.ts'
|
|
5
5
|
|
|
6
6
|
export * from 'react-dom/client'
|
|
7
7
|
|