react-msaview 4.1.1 → 4.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.
- package/bundle/index.js +104 -213
- package/bundle/index.js.LICENSE.txt +173 -0
- package/bundle/index.js.map +1 -0
- package/dist/components/TextTrack.d.ts +2 -1
- package/dist/components/TextTrack.js.map +1 -1
- package/dist/components/Track.js.map +1 -1
- package/dist/components/header/Header.js +10 -3
- package/dist/components/header/Header.js.map +1 -1
- package/dist/components/header/HeaderMenu.js +199 -11
- package/dist/components/header/HeaderMenu.js.map +1 -1
- package/dist/components/header/MultiAlignmentSelector.js +3 -3
- package/dist/components/header/MultiAlignmentSelector.js.map +1 -1
- package/dist/components/header/{HeaderMenuExtra.d.ts → SettingsMenu.d.ts} +2 -2
- package/dist/components/header/SettingsMenu.js +141 -0
- package/dist/components/header/SettingsMenu.js.map +1 -0
- package/dist/components/header/ZoomControls.d.ts +1 -1
- package/dist/components/header/ZoomControls.js +1 -46
- package/dist/components/header/ZoomControls.js.map +1 -1
- package/dist/components/header/ZoomMenu.d.ts +6 -0
- package/dist/components/header/ZoomMenu.js +33 -0
- package/dist/components/header/ZoomMenu.js.map +1 -0
- package/dist/components/header/ZoomStar.d.ts +6 -0
- package/dist/components/header/ZoomStar.js +40 -0
- package/dist/components/header/ZoomStar.js.map +1 -0
- package/dist/components/tree/renderTreeCanvas.js +6 -3
- package/dist/components/tree/renderTreeCanvas.js.map +1 -1
- package/dist/flatToTree.d.ts +17 -0
- package/dist/flatToTree.js +41 -0
- package/dist/flatToTree.js.map +1 -0
- package/dist/model.d.ts +21 -28
- package/dist/model.js +47 -32
- package/dist/model.js.map +1 -1
- package/dist/parseAsn1.d.ts +34 -0
- package/dist/parseAsn1.js +385 -0
- package/dist/parseAsn1.js.map +1 -0
- package/dist/parseAsn1.test.d.ts +1 -0
- package/dist/parseAsn1.test.js +8 -0
- package/dist/parseAsn1.test.js.map +1 -0
- package/dist/parsers/ClustalMSA.d.ts +1 -1
- package/dist/parsers/ClustalMSA.js.map +1 -1
- package/dist/parsers/EmfMSA.d.ts +1 -1
- package/dist/parsers/FastaMSA.d.ts +1 -1
- package/dist/parsers/StockholmMSA.d.ts +1 -1
- package/dist/parsers/StockholmMSA.js.map +1 -1
- package/dist/renderToSvg.d.ts +3 -2
- package/dist/renderToSvg.js.map +1 -1
- package/dist/reparseTree.d.ts +1 -1
- package/dist/reparseTree.js +2 -0
- package/dist/reparseTree.js.map +1 -1
- package/dist/types.d.ts +38 -0
- package/dist/types.js +2 -0
- package/dist/types.js.map +1 -0
- package/dist/util.d.ts +6 -20
- package/dist/util.js +19 -0
- package/dist/util.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/dist/version.js +1 -1
- package/dist/webpack.d.ts +5 -0
- package/dist/webpack.js +7 -0
- package/dist/webpack.js.map +1 -0
- package/package.json +4 -3
- package/src/__snapshots__/parseAsn1.test.ts.snap +2400 -0
- package/src/components/TextTrack.tsx +2 -1
- package/src/components/Track.tsx +0 -2
- package/src/components/header/Header.tsx +11 -3
- package/src/components/header/HeaderMenu.tsx +215 -11
- package/src/components/header/MultiAlignmentSelector.tsx +7 -6
- package/src/components/header/SettingsMenu.tsx +169 -0
- package/src/components/header/ZoomControls.tsx +1 -52
- package/src/components/header/ZoomMenu.tsx +42 -0
- package/src/components/header/ZoomStar.tsx +74 -0
- package/src/components/msa/renderBoxFeatureCanvasBlock.ts +1 -1
- package/src/components/msa/renderMSABlock.ts +1 -1
- package/src/components/tree/renderTreeCanvas.ts +13 -3
- package/src/flatToTree.ts +57 -0
- package/src/model.ts +75 -61
- package/src/parseAsn1.test.ts +11 -0
- package/src/parseAsn1.ts +494 -0
- package/src/parsers/ClustalMSA.ts +2 -1
- package/src/parsers/EmfMSA.ts +1 -1
- package/src/parsers/FastaMSA.ts +1 -1
- package/src/parsers/StockholmMSA.ts +4 -1
- package/src/renderToSvg.tsx +6 -4
- package/src/reparseTree.ts +3 -1
- package/src/types.ts +44 -0
- package/src/util.ts +26 -22
- package/src/version.ts +1 -1
- package/src/webpack.ts +9 -0
- package/dist/components/header/HeaderMenuExtra.js +0 -122
- package/dist/components/header/HeaderMenuExtra.js.map +0 -1
- package/src/components/header/HeaderMenuExtra.tsx +0 -135
|
@@ -0,0 +1,74 @@
|
|
|
1
|
+
import React from 'react'
|
|
2
|
+
|
|
3
|
+
import RestartAlt from '@mui/icons-material/RestartAlt'
|
|
4
|
+
import { IconButton } from '@mui/material'
|
|
5
|
+
import { observer } from 'mobx-react'
|
|
6
|
+
import { makeStyles } from 'tss-react/mui'
|
|
7
|
+
|
|
8
|
+
import type { MsaViewModel } from '../../model'
|
|
9
|
+
|
|
10
|
+
const useStyles = makeStyles()(theme => ({
|
|
11
|
+
dpad: {
|
|
12
|
+
display: 'grid',
|
|
13
|
+
gridTemplateColumns: 'repeat(3, 1fr)',
|
|
14
|
+
},
|
|
15
|
+
icon: {
|
|
16
|
+
padding: theme.spacing(0.5),
|
|
17
|
+
},
|
|
18
|
+
}))
|
|
19
|
+
|
|
20
|
+
const ZoomStar = observer(function ({ model }: { model: MsaViewModel }) {
|
|
21
|
+
const { classes } = useStyles()
|
|
22
|
+
return (
|
|
23
|
+
<div className={classes.dpad}>
|
|
24
|
+
<div />
|
|
25
|
+
<IconButton
|
|
26
|
+
className={classes.icon}
|
|
27
|
+
onClick={() => {
|
|
28
|
+
model.zoomInVertical()
|
|
29
|
+
}}
|
|
30
|
+
>
|
|
31
|
+
Y+
|
|
32
|
+
</IconButton>
|
|
33
|
+
<div />
|
|
34
|
+
|
|
35
|
+
<IconButton
|
|
36
|
+
className={classes.icon}
|
|
37
|
+
onClick={() => {
|
|
38
|
+
model.zoomOutHorizontal()
|
|
39
|
+
}}
|
|
40
|
+
>
|
|
41
|
+
X-
|
|
42
|
+
</IconButton>
|
|
43
|
+
<IconButton
|
|
44
|
+
className={classes.icon}
|
|
45
|
+
onClick={() => {
|
|
46
|
+
model.resetZoom()
|
|
47
|
+
}}
|
|
48
|
+
>
|
|
49
|
+
<RestartAlt />
|
|
50
|
+
</IconButton>
|
|
51
|
+
<IconButton
|
|
52
|
+
className={classes.icon}
|
|
53
|
+
onClick={() => {
|
|
54
|
+
model.zoomInHorizontal()
|
|
55
|
+
}}
|
|
56
|
+
>
|
|
57
|
+
X+
|
|
58
|
+
</IconButton>
|
|
59
|
+
|
|
60
|
+
<div />
|
|
61
|
+
<IconButton
|
|
62
|
+
className={classes.icon}
|
|
63
|
+
onClick={() => {
|
|
64
|
+
model.zoomOutVertical()
|
|
65
|
+
}}
|
|
66
|
+
>
|
|
67
|
+
Y-
|
|
68
|
+
</IconButton>
|
|
69
|
+
<div />
|
|
70
|
+
</div>
|
|
71
|
+
)
|
|
72
|
+
})
|
|
73
|
+
|
|
74
|
+
export default ZoomStar
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { getClustalXColor, getPercentIdentityColor } from '../../colorSchemes'
|
|
2
2
|
|
|
3
3
|
import type { MsaViewModel } from '../../model'
|
|
4
|
-
import type { NodeWithIdsAndLength } from '../../
|
|
4
|
+
import type { NodeWithIdsAndLength } from '../../types'
|
|
5
5
|
import type { Theme } from '@mui/material'
|
|
6
6
|
import type { HierarchyNode } from 'd3-hierarchy'
|
|
7
7
|
|
|
@@ -31,9 +31,15 @@ export function renderTree({
|
|
|
31
31
|
theme: Theme
|
|
32
32
|
blockSizeYOverride?: number
|
|
33
33
|
}) {
|
|
34
|
-
const {
|
|
34
|
+
const {
|
|
35
|
+
hierarchy,
|
|
36
|
+
allBranchesLength0,
|
|
37
|
+
showBranchLen: showBranchLenPre,
|
|
38
|
+
blockSize,
|
|
39
|
+
} = model
|
|
35
40
|
const by = blockSizeYOverride || blockSize
|
|
36
41
|
ctx.strokeStyle = theme.palette.text.primary
|
|
42
|
+
const showBranchLen = allBranchesLength0 ? false : showBranchLenPre
|
|
37
43
|
for (const link of hierarchy.links()) {
|
|
38
44
|
const { source, target } = link
|
|
39
45
|
if (target.height === 0 && !showBranchLen) {
|
|
@@ -77,12 +83,14 @@ export function renderNodeBubbles({
|
|
|
77
83
|
}) {
|
|
78
84
|
const {
|
|
79
85
|
hierarchy,
|
|
80
|
-
showBranchLen,
|
|
86
|
+
showBranchLen: showBranchLenPre,
|
|
87
|
+
allBranchesLength0,
|
|
81
88
|
collapsed,
|
|
82
89
|
blockSize,
|
|
83
90
|
marginLeft: ml,
|
|
84
91
|
} = model
|
|
85
92
|
const by = blockSizeYOverride || blockSize
|
|
93
|
+
const showBranchLen = allBranchesLength0 ? false : showBranchLenPre
|
|
86
94
|
for (const node of hierarchy.descendants()) {
|
|
87
95
|
const val = showBranchLen ? 'len' : 'y'
|
|
88
96
|
// @ts-expect-error
|
|
@@ -131,7 +139,8 @@ export function renderTreeLabels({
|
|
|
131
139
|
}) {
|
|
132
140
|
const {
|
|
133
141
|
fontSize,
|
|
134
|
-
showBranchLen,
|
|
142
|
+
showBranchLen: showBranchLenPre,
|
|
143
|
+
allBranchesLength0,
|
|
135
144
|
treeMetadata,
|
|
136
145
|
hierarchy,
|
|
137
146
|
collapsed,
|
|
@@ -153,6 +162,7 @@ export function renderTreeLabels({
|
|
|
153
162
|
} else {
|
|
154
163
|
ctx.textAlign = 'start'
|
|
155
164
|
}
|
|
165
|
+
const showBranchLen = allBranchesLength0 ? false : showBranchLenPre
|
|
156
166
|
for (const node of leaves) {
|
|
157
167
|
const {
|
|
158
168
|
data: { name, id },
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
// Define the input item interface
|
|
2
|
+
interface FlatItem {
|
|
3
|
+
id: number
|
|
4
|
+
parent?: number
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
// Define the tree node interface
|
|
8
|
+
interface TreeNode {
|
|
9
|
+
id: string
|
|
10
|
+
name: string
|
|
11
|
+
parent?: string
|
|
12
|
+
children: TreeNode[]
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
/**
|
|
16
|
+
* Parses a flat list of items into a tree structure
|
|
17
|
+
* @param items - Array of flat items with id and optional parent
|
|
18
|
+
* @returns Array of root tree nodes
|
|
19
|
+
*/
|
|
20
|
+
export function flatToTree(items: FlatItem[]): TreeNode {
|
|
21
|
+
// Create a map to store all nodes by their id for quick lookup
|
|
22
|
+
const nodeMap = new Map<number, TreeNode>()
|
|
23
|
+
|
|
24
|
+
// First pass: Create all tree nodes
|
|
25
|
+
items.forEach(item => {
|
|
26
|
+
nodeMap.set(item.id, {
|
|
27
|
+
...item,
|
|
28
|
+
id: `${item.id}`,
|
|
29
|
+
name: `${item.id}`,
|
|
30
|
+
parent: item.parent !== undefined ? `${item.parent}` : undefined,
|
|
31
|
+
children: [],
|
|
32
|
+
})
|
|
33
|
+
})
|
|
34
|
+
|
|
35
|
+
// Second pass: Build parent-child relationships
|
|
36
|
+
const roots: TreeNode[] = []
|
|
37
|
+
|
|
38
|
+
items.forEach(item => {
|
|
39
|
+
const node = nodeMap.get(item.id)!
|
|
40
|
+
|
|
41
|
+
if (item.parent !== undefined) {
|
|
42
|
+
// This item has a parent, add it to parent's children
|
|
43
|
+
const parentNode = nodeMap.get(item.parent)
|
|
44
|
+
if (parentNode) {
|
|
45
|
+
parentNode.children.push(node)
|
|
46
|
+
} else {
|
|
47
|
+
// Parent doesn't exist, treat as root
|
|
48
|
+
roots.push(node)
|
|
49
|
+
}
|
|
50
|
+
} else {
|
|
51
|
+
// This item has no parent, it's a root node
|
|
52
|
+
roots.push(node)
|
|
53
|
+
}
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
return roots[0]!
|
|
57
|
+
}
|
package/src/model.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
|
-
import React from 'react'
|
|
2
|
-
|
|
3
1
|
import { groupBy, notEmpty, sum } from '@jbrowse/core/util'
|
|
4
2
|
import { openLocation } from '@jbrowse/core/util/io'
|
|
5
3
|
import { ElementId, FileLocation } from '@jbrowse/core/util/types/mst'
|
|
6
4
|
import { colord } from 'colord'
|
|
7
5
|
import { ascending } from 'd3-array'
|
|
8
6
|
import { cluster, hierarchy } from 'd3-hierarchy'
|
|
7
|
+
import { parseEmfTree } from 'emf-js'
|
|
9
8
|
import { saveAs } from 'file-saver'
|
|
10
9
|
import { autorun, transaction } from 'mobx'
|
|
11
10
|
import { addDisposer, cast, types } from 'mobx-state-tree'
|
|
@@ -15,16 +14,17 @@ import Stockholm from 'stockholm-js'
|
|
|
15
14
|
import { blocksX, blocksY } from './calculateBlocks'
|
|
16
15
|
import colorSchemes from './colorSchemes'
|
|
17
16
|
import TextTrack from './components/TextTrack'
|
|
17
|
+
import { flatToTree } from './flatToTree'
|
|
18
18
|
import palettes from './ggplotPalettes'
|
|
19
19
|
import { measureTextCanvas } from './measureTextCanvas'
|
|
20
20
|
import { DataModelF } from './model/DataModel'
|
|
21
21
|
import { DialogQueueSessionMixin } from './model/DialogQueue'
|
|
22
22
|
import { MSAModelF } from './model/msaModel'
|
|
23
23
|
import { TreeModelF } from './model/treeModel'
|
|
24
|
+
import { parseAsn1 } from './parseAsn1'
|
|
24
25
|
import parseNewick from './parseNewick'
|
|
25
26
|
import ClustalMSA from './parsers/ClustalMSA'
|
|
26
27
|
import EmfMSA from './parsers/EmfMSA'
|
|
27
|
-
import EmfTree from './parsers/EmfTree'
|
|
28
28
|
import FastaMSA from './parsers/FastaMSA'
|
|
29
29
|
import StockholmMSA from './parsers/StockholmMSA'
|
|
30
30
|
import { reparseTree } from './reparseTree'
|
|
@@ -36,46 +36,31 @@ import {
|
|
|
36
36
|
clamp,
|
|
37
37
|
collapse,
|
|
38
38
|
generateNodeIds,
|
|
39
|
+
isGzip,
|
|
39
40
|
len,
|
|
41
|
+
localStorageGetBoolean,
|
|
42
|
+
localStorageSetBoolean,
|
|
40
43
|
maxLength,
|
|
41
44
|
setBrLength,
|
|
42
45
|
skipBlanks,
|
|
43
46
|
} from './util'
|
|
44
47
|
|
|
45
48
|
import type { InterProScanResults } from './launchInterProScan'
|
|
46
|
-
import type {
|
|
49
|
+
import type {
|
|
50
|
+
Accession,
|
|
51
|
+
BasicTrack,
|
|
52
|
+
NodeWithIds,
|
|
53
|
+
NodeWithIdsAndLength,
|
|
54
|
+
TextTrackModel,
|
|
55
|
+
} from './types'
|
|
47
56
|
import type { FileLocation as FileLocationType } from '@jbrowse/core/util/types'
|
|
48
57
|
import type { Theme } from '@mui/material'
|
|
49
58
|
import type { HierarchyNode } from 'd3-hierarchy'
|
|
50
59
|
import type { Instance } from 'mobx-state-tree'
|
|
51
60
|
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
description: string
|
|
56
|
-
}
|
|
57
|
-
export interface BasicTrackModel {
|
|
58
|
-
id: string
|
|
59
|
-
name: string
|
|
60
|
-
associatedRowName?: string
|
|
61
|
-
height: number
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
export interface TextTrackModel extends BasicTrackModel {
|
|
65
|
-
customColorScheme?: Record<string, string>
|
|
66
|
-
data: string
|
|
67
|
-
}
|
|
68
|
-
|
|
69
|
-
export interface ITextTrack {
|
|
70
|
-
ReactComponent: React.FC<any>
|
|
71
|
-
model: TextTrackModel
|
|
72
|
-
}
|
|
73
|
-
|
|
74
|
-
export type BasicTrack = ITextTrack
|
|
75
|
-
|
|
76
|
-
export function isGzip(buf: Uint8Array) {
|
|
77
|
-
return buf[0] === 31 && buf[1] === 139 && buf[2] === 8
|
|
78
|
-
}
|
|
61
|
+
const defaultRowHeight = 16
|
|
62
|
+
const defaultColWidth = 12
|
|
63
|
+
const showZoomStarKey = 'msa-showZoomStar'
|
|
79
64
|
|
|
80
65
|
/**
|
|
81
66
|
* #stateModel MsaView
|
|
@@ -101,6 +86,10 @@ function stateModelFactory() {
|
|
|
101
86
|
* #property
|
|
102
87
|
*/
|
|
103
88
|
showDomains: false,
|
|
89
|
+
/**
|
|
90
|
+
* #property
|
|
91
|
+
*/
|
|
92
|
+
hideGaps: true,
|
|
104
93
|
/**
|
|
105
94
|
* #property
|
|
106
95
|
*/
|
|
@@ -125,15 +114,6 @@ function stateModelFactory() {
|
|
|
125
114
|
* #property
|
|
126
115
|
*/
|
|
127
116
|
drawMsaLetters: true,
|
|
128
|
-
/**
|
|
129
|
-
* #property
|
|
130
|
-
*/
|
|
131
|
-
hideGaps: false,
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* #property
|
|
135
|
-
*/
|
|
136
|
-
drawTreeText: true,
|
|
137
117
|
|
|
138
118
|
/**
|
|
139
119
|
* #property
|
|
@@ -145,7 +125,7 @@ function stateModelFactory() {
|
|
|
145
125
|
* #property
|
|
146
126
|
* height of each row, px
|
|
147
127
|
*/
|
|
148
|
-
rowHeight:
|
|
128
|
+
rowHeight: defaultRowHeight,
|
|
149
129
|
|
|
150
130
|
/**
|
|
151
131
|
* #property
|
|
@@ -163,7 +143,7 @@ function stateModelFactory() {
|
|
|
163
143
|
* #property
|
|
164
144
|
* width of columns, px
|
|
165
145
|
*/
|
|
166
|
-
colWidth:
|
|
146
|
+
colWidth: defaultColWidth,
|
|
167
147
|
|
|
168
148
|
/**
|
|
169
149
|
* #property
|
|
@@ -250,6 +230,12 @@ function stateModelFactory() {
|
|
|
250
230
|
* screens
|
|
251
231
|
*/
|
|
252
232
|
highResScaleFactor: 2,
|
|
233
|
+
|
|
234
|
+
/**
|
|
235
|
+
* #volatile
|
|
236
|
+
* obtained from localStorage
|
|
237
|
+
*/
|
|
238
|
+
showZoomStar: localStorageGetBoolean(showZoomStarKey, false),
|
|
253
239
|
/**
|
|
254
240
|
* #volatile
|
|
255
241
|
*/
|
|
@@ -363,6 +349,12 @@ function stateModelFactory() {
|
|
|
363
349
|
setLoadingMSA(arg: boolean) {
|
|
364
350
|
self.loadingMSA = arg
|
|
365
351
|
},
|
|
352
|
+
/**
|
|
353
|
+
* #volatile
|
|
354
|
+
*/
|
|
355
|
+
setShowZoomStar(arg: boolean) {
|
|
356
|
+
self.showZoomStar = arg
|
|
357
|
+
},
|
|
366
358
|
/**
|
|
367
359
|
* #action
|
|
368
360
|
*/
|
|
@@ -635,26 +627,26 @@ function stateModelFactory() {
|
|
|
635
627
|
*/
|
|
636
628
|
get tree(): NodeWithIds {
|
|
637
629
|
const text = self.data.tree
|
|
638
|
-
|
|
639
|
-
|
|
640
|
-
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
return reparseTree(ret)
|
|
630
|
+
return text
|
|
631
|
+
? reparseTree(
|
|
632
|
+
generateNodeIds(
|
|
633
|
+
text.startsWith('BioTreeContainer')
|
|
634
|
+
? flatToTree(parseAsn1(text))
|
|
635
|
+
: parseNewick(
|
|
636
|
+
text.startsWith('SEQ') ? parseEmfTree(text).tree : text,
|
|
637
|
+
),
|
|
638
|
+
),
|
|
639
|
+
)
|
|
640
|
+
: reparseTree(
|
|
641
|
+
this.MSA?.getTree() || {
|
|
642
|
+
noTree: true,
|
|
643
|
+
children: [],
|
|
644
|
+
id: 'empty',
|
|
645
|
+
name: 'empty',
|
|
646
|
+
},
|
|
647
|
+
)
|
|
657
648
|
},
|
|
649
|
+
|
|
658
650
|
/**
|
|
659
651
|
* #getter
|
|
660
652
|
*/
|
|
@@ -846,6 +838,13 @@ function stateModelFactory() {
|
|
|
846
838
|
get leaves() {
|
|
847
839
|
return this.hierarchy.leaves()
|
|
848
840
|
},
|
|
841
|
+
|
|
842
|
+
/**
|
|
843
|
+
* #getter
|
|
844
|
+
*/
|
|
845
|
+
get allBranchesLength0() {
|
|
846
|
+
return this.hierarchy.links().every(s => !s.source.data.length)
|
|
847
|
+
},
|
|
849
848
|
}))
|
|
850
849
|
.views(self => ({
|
|
851
850
|
/**
|
|
@@ -937,6 +936,13 @@ function stateModelFactory() {
|
|
|
937
936
|
self.drawMsaLetters = arg
|
|
938
937
|
},
|
|
939
938
|
|
|
939
|
+
/**
|
|
940
|
+
* #action
|
|
941
|
+
*/
|
|
942
|
+
resetZoom() {
|
|
943
|
+
self.setColWidth(defaultColWidth)
|
|
944
|
+
self.setRowHeight(defaultRowHeight)
|
|
945
|
+
},
|
|
940
946
|
/**
|
|
941
947
|
* #action
|
|
942
948
|
*/
|
|
@@ -1379,6 +1385,14 @@ function stateModelFactory() {
|
|
|
1379
1385
|
}),
|
|
1380
1386
|
)
|
|
1381
1387
|
|
|
1388
|
+
// autorun saves local settings
|
|
1389
|
+
addDisposer(
|
|
1390
|
+
self,
|
|
1391
|
+
autorun(() => {
|
|
1392
|
+
localStorageSetBoolean(showZoomStarKey, self.showZoomStar)
|
|
1393
|
+
}),
|
|
1394
|
+
)
|
|
1395
|
+
|
|
1382
1396
|
// autorun opens treeFilehandle
|
|
1383
1397
|
addDisposer(
|
|
1384
1398
|
self,
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import fs from 'fs'
|
|
2
|
+
|
|
3
|
+
import { expect, test } from 'vitest'
|
|
4
|
+
|
|
5
|
+
import { parseAsn1 } from './parseAsn1'
|
|
6
|
+
|
|
7
|
+
const r = fs.readFileSync(require.resolve('../test/data/tree.asn'), 'utf8')
|
|
8
|
+
|
|
9
|
+
test('real data file', () => {
|
|
10
|
+
expect(parseAsn1(r)).toMatchSnapshot()
|
|
11
|
+
})
|