@jbrowse/plugin-sv-inspector 2.6.1

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 (58) hide show
  1. package/LICENSE +201 -0
  2. package/dist/LaunchSvInspectorView/index.d.ts +3 -0
  3. package/dist/LaunchSvInspectorView/index.js +27 -0
  4. package/dist/LaunchSvInspectorView/index.js.map +1 -0
  5. package/dist/SvInspectorView/components/CircularViewOptions.d.ts +6 -0
  6. package/dist/SvInspectorView/components/CircularViewOptions.js +22 -0
  7. package/dist/SvInspectorView/components/CircularViewOptions.js.map +1 -0
  8. package/dist/SvInspectorView/components/SvInspectorView.d.ts +6 -0
  9. package/dist/SvInspectorView/components/SvInspectorView.js +51 -0
  10. package/dist/SvInspectorView/components/SvInspectorView.js.map +1 -0
  11. package/dist/SvInspectorView/index.d.ts +3 -0
  12. package/dist/SvInspectorView/index.js +35 -0
  13. package/dist/SvInspectorView/index.js.map +1 -0
  14. package/dist/SvInspectorView/models/SvInspectorView.d.ts +881 -0
  15. package/dist/SvInspectorView/models/SvInspectorView.js +317 -0
  16. package/dist/SvInspectorView/models/SvInspectorView.js.map +1 -0
  17. package/dist/SvInspectorView/models/adhocFeatureUtils.d.ts +44 -0
  18. package/dist/SvInspectorView/models/adhocFeatureUtils.js +97 -0
  19. package/dist/SvInspectorView/models/adhocFeatureUtils.js.map +1 -0
  20. package/dist/SvInspectorView/models/breakpointSplitViewFromTableRow.d.ts +4 -0
  21. package/dist/SvInspectorView/models/breakpointSplitViewFromTableRow.js +49 -0
  22. package/dist/SvInspectorView/models/breakpointSplitViewFromTableRow.js.map +1 -0
  23. package/dist/index.d.ts +7 -0
  24. package/dist/index.js +35 -0
  25. package/dist/index.js.map +1 -0
  26. package/esm/LaunchSvInspectorView/index.d.ts +3 -0
  27. package/esm/LaunchSvInspectorView/index.js +25 -0
  28. package/esm/LaunchSvInspectorView/index.js.map +1 -0
  29. package/esm/SvInspectorView/components/CircularViewOptions.d.ts +6 -0
  30. package/esm/SvInspectorView/components/CircularViewOptions.js +17 -0
  31. package/esm/SvInspectorView/components/CircularViewOptions.js.map +1 -0
  32. package/esm/SvInspectorView/components/SvInspectorView.d.ts +6 -0
  33. package/esm/SvInspectorView/components/SvInspectorView.js +46 -0
  34. package/esm/SvInspectorView/components/SvInspectorView.js.map +1 -0
  35. package/esm/SvInspectorView/index.d.ts +3 -0
  36. package/esm/SvInspectorView/index.js +30 -0
  37. package/esm/SvInspectorView/index.js.map +1 -0
  38. package/esm/SvInspectorView/models/SvInspectorView.d.ts +881 -0
  39. package/esm/SvInspectorView/models/SvInspectorView.js +312 -0
  40. package/esm/SvInspectorView/models/SvInspectorView.js.map +1 -0
  41. package/esm/SvInspectorView/models/adhocFeatureUtils.d.ts +44 -0
  42. package/esm/SvInspectorView/models/adhocFeatureUtils.js +90 -0
  43. package/esm/SvInspectorView/models/adhocFeatureUtils.js.map +1 -0
  44. package/esm/SvInspectorView/models/breakpointSplitViewFromTableRow.d.ts +4 -0
  45. package/esm/SvInspectorView/models/breakpointSplitViewFromTableRow.js +42 -0
  46. package/esm/SvInspectorView/models/breakpointSplitViewFromTableRow.js.map +1 -0
  47. package/esm/index.d.ts +7 -0
  48. package/esm/index.js +29 -0
  49. package/esm/index.js.map +1 -0
  50. package/package.json +62 -0
  51. package/src/LaunchSvInspectorView/index.ts +41 -0
  52. package/src/SvInspectorView/components/CircularViewOptions.tsx +47 -0
  53. package/src/SvInspectorView/components/SvInspectorView.tsx +81 -0
  54. package/src/SvInspectorView/index.ts +41 -0
  55. package/src/SvInspectorView/models/SvInspectorView.ts +406 -0
  56. package/src/SvInspectorView/models/adhocFeatureUtils.js +152 -0
  57. package/src/SvInspectorView/models/breakpointSplitViewFromTableRow.js +84 -0
  58. package/src/index.ts +34 -0
@@ -0,0 +1,41 @@
1
+ import PluginManager from '@jbrowse/core/PluginManager'
2
+ import { AbstractSessionModel } from '@jbrowse/core/util'
3
+ import { SvInspectorViewModel } from '../SvInspectorView/models/SvInspectorView'
4
+
5
+ export default (pluginManager: PluginManager) => {
6
+ pluginManager.addToExtensionPoint(
7
+ 'LaunchView-SvInspectorView',
8
+ // @ts-expect-error
9
+ async ({
10
+ session,
11
+ assembly,
12
+ uri,
13
+ fileType,
14
+ }: {
15
+ session: AbstractSessionModel
16
+ assembly: string
17
+ uri: string
18
+ fileType?: string
19
+ }) => {
20
+ // add view, make typescript happy with return type
21
+ const view = session.addView('SvInspectorView') as SvInspectorViewModel
22
+
23
+ if (!view) {
24
+ throw new Error('Failed to initialize view')
25
+ }
26
+ const exts = uri.split('.')
27
+ let ext = exts?.pop()?.toUpperCase()
28
+ if (ext === 'GZ') {
29
+ ext = exts?.pop()?.toUpperCase()
30
+ }
31
+
32
+ view.spreadsheetView.importWizard.setFileType(fileType || ext || '')
33
+ view.spreadsheetView.importWizard.setSelectedAssemblyName(assembly)
34
+ view.spreadsheetView.importWizard.setFileSource({
35
+ uri,
36
+ locationType: 'UriLocation',
37
+ })
38
+ await view.spreadsheetView.importWizard.import(assembly)
39
+ },
40
+ )
41
+ }
@@ -0,0 +1,47 @@
1
+ import React from 'react'
2
+ import { observer } from 'mobx-react'
3
+ import { Grid, FormControlLabel, Checkbox } from '@mui/material'
4
+ import { makeStyles } from 'tss-react/mui'
5
+
6
+ // locals
7
+ import { SvInspectorViewModel } from '../models/SvInspectorView'
8
+
9
+ const useStyles = makeStyles()(theme => ({
10
+ circularViewOptions: {
11
+ padding: theme.spacing(1),
12
+ },
13
+ }))
14
+
15
+ const CircularViewOptions = observer(function ({
16
+ svInspector,
17
+ }: {
18
+ svInspector: SvInspectorViewModel
19
+ }) {
20
+ const { classes } = useStyles()
21
+
22
+ return (
23
+ <Grid
24
+ container
25
+ className={classes.circularViewOptions}
26
+ style={{ height: svInspector.circularViewOptionsBarHeight }}
27
+ >
28
+ <Grid item>
29
+ <FormControlLabel
30
+ control={
31
+ <Checkbox
32
+ checked={svInspector.onlyDisplayRelevantRegionsInCircularView}
33
+ onChange={e =>
34
+ svInspector.setOnlyDisplayRelevantRegionsInCircularView(
35
+ e.target.checked,
36
+ )
37
+ }
38
+ />
39
+ }
40
+ label="show only regions with data"
41
+ />
42
+ </Grid>
43
+ </Grid>
44
+ )
45
+ })
46
+
47
+ export default CircularViewOptions
@@ -0,0 +1,81 @@
1
+ import React from 'react'
2
+ import { observer } from 'mobx-react'
3
+ import { makeStyles } from 'tss-react/mui'
4
+ import { ResizeHandle } from '@jbrowse/core/ui'
5
+
6
+ // locals
7
+ import { SvInspectorViewModel } from '../models/SvInspectorView'
8
+ import CircularViewOptions from './CircularViewOptions'
9
+
10
+ const useStyles = makeStyles()(theme => ({
11
+ resizeHandleVert: {
12
+ background: theme.palette.action.selected,
13
+ width: 4,
14
+ boxSizing: 'border-box',
15
+ borderTop: '1px solid #fafafa',
16
+ },
17
+ resizeHandleHoriz: {
18
+ background: theme.palette.action.selected,
19
+ height: 4,
20
+ boxSizing: 'border-box',
21
+ borderTop: '1px solid #fafafa',
22
+ },
23
+ viewControls: {
24
+ margin: 0,
25
+ },
26
+ viewsContainer: {
27
+ display: 'flex',
28
+ },
29
+ container: {
30
+ overflow: 'hidden',
31
+ },
32
+ }))
33
+
34
+ export default observer(function SvInspectorView({
35
+ model,
36
+ }: {
37
+ model: SvInspectorViewModel
38
+ }) {
39
+ const { classes } = useStyles()
40
+
41
+ const {
42
+ SpreadsheetViewReactComponent,
43
+ CircularViewReactComponent,
44
+ showCircularView,
45
+ } = model
46
+
47
+ return (
48
+ <div className={classes.container}>
49
+ <div className={classes.viewsContainer}>
50
+ <div
51
+ style={{ width: model.spreadsheetView.width }}
52
+ className={classes.container}
53
+ >
54
+ <SpreadsheetViewReactComponent model={model.spreadsheetView} />
55
+ </div>
56
+
57
+ {showCircularView ? (
58
+ <>
59
+ <ResizeHandle
60
+ onDrag={distance => {
61
+ const ret1 = model.circularView.resizeWidth(-distance)
62
+ return model.spreadsheetView.resizeWidth(-ret1)
63
+ }}
64
+ vertical
65
+ flexbox
66
+ className={classes.resizeHandleVert}
67
+ />
68
+ <div style={{ width: model.circularView.width }}>
69
+ <CircularViewOptions svInspector={model} />
70
+ <CircularViewReactComponent model={model.circularView} />
71
+ </div>
72
+ </>
73
+ ) : null}
74
+ </div>
75
+ <ResizeHandle
76
+ onDrag={model.resizeHeight}
77
+ className={classes.resizeHandleHoriz}
78
+ />
79
+ </div>
80
+ )
81
+ })
@@ -0,0 +1,41 @@
1
+ import PluginManager from '@jbrowse/core/PluginManager'
2
+ import ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'
3
+
4
+ import ReactComponent from './components/SvInspectorView'
5
+ import stateModelFactory from './models/SvInspectorView'
6
+ import { Feature, getContainingView, getSession } from '@jbrowse/core/util'
7
+ import { IAnyStateTreeNode } from 'mobx-state-tree'
8
+
9
+ function defaultOnChordClick(
10
+ feature: Feature,
11
+ chordTrack: IAnyStateTreeNode,
12
+ pluginManager: PluginManager,
13
+ ) {
14
+ const session = getSession(chordTrack)
15
+ session.setSelection(feature)
16
+ const view = getContainingView(chordTrack)
17
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
18
+ const viewType = pluginManager.getViewType('BreakpointSplitView') as any
19
+ const viewSnapshot = viewType.snapshotFromBreakendFeature(feature, view)
20
+
21
+ // try to center the offsetPx
22
+ viewSnapshot.views[0].offsetPx -= view.width / 2 + 100
23
+ viewSnapshot.views[1].offsetPx -= view.width / 2 + 100
24
+ viewSnapshot.featureData = feature.toJSON()
25
+
26
+ session.addView('BreakpointSplitView', viewSnapshot)
27
+ }
28
+
29
+ export default (pluginManager: PluginManager) => {
30
+ pluginManager.jexl.addFunction('defaultOnChordClick', defaultOnChordClick)
31
+
32
+ pluginManager.addViewType(() => {
33
+ const stateModel = stateModelFactory(pluginManager)
34
+ return new ViewType({
35
+ name: 'SvInspectorView',
36
+ displayName: 'SV inspector',
37
+ stateModel,
38
+ ReactComponent,
39
+ })
40
+ })
41
+ }
@@ -0,0 +1,406 @@
1
+ import clone from 'clone'
2
+ import { autorun, reaction } from 'mobx'
3
+ import { types, getParent, addDisposer, Instance } from 'mobx-state-tree'
4
+
5
+ import PluginManager from '@jbrowse/core/PluginManager'
6
+ import { getSession, Region } from '@jbrowse/core/util'
7
+ import { readConfObject } from '@jbrowse/core/configuration'
8
+ import { ElementId } from '@jbrowse/core/util/types/mst'
9
+ import { BaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'
10
+ import { SpreadsheetViewStateModel } from '@jbrowse/plugin-spreadsheet-view'
11
+ import { CircularViewStateModel } from '@jbrowse/plugin-circular-view'
12
+
13
+ // icons
14
+ import OpenInNewIcon from '@mui/icons-material/OpenInNew'
15
+ import FolderOpenIcon from '@mui/icons-material/FolderOpen'
16
+
17
+ // locals
18
+ import {
19
+ canOpenBreakpointSplitViewFromTableRow,
20
+ openBreakpointSplitViewFromTableRow,
21
+ getFeatureForRow,
22
+ } from './breakpointSplitViewFromTableRow'
23
+
24
+ /**
25
+ * #stateModel SvInspectorView
26
+ * #category view
27
+ * combination of a spreadsheetview and a circularview
28
+ */
29
+ function SvInspectorViewF(pluginManager: PluginManager) {
30
+ const SpreadsheetViewType = pluginManager.getViewType('SpreadsheetView')
31
+ const CircularViewType = pluginManager.getViewType('CircularView')
32
+
33
+ const SpreadsheetModel =
34
+ SpreadsheetViewType.stateModel as SpreadsheetViewStateModel
35
+ const CircularModel = CircularViewType.stateModel as CircularViewStateModel
36
+
37
+ const minHeight = 400
38
+ const defaultHeight = 550
39
+ const headerHeight = 52
40
+ const circularViewOptionsBarHeight = 52
41
+ return types
42
+ .compose(
43
+ BaseViewModel,
44
+ types.model('SvInspectorView', {
45
+ /**
46
+ * #property
47
+ */
48
+ id: ElementId,
49
+ /**
50
+ * #property
51
+ */
52
+ type: types.literal('SvInspectorView'),
53
+
54
+ /**
55
+ * #property
56
+ */
57
+ height: types.optional(
58
+ types.refinement(
59
+ 'SvInspectorViewHeight',
60
+ types.number,
61
+ n => n >= minHeight,
62
+ ),
63
+ defaultHeight,
64
+ ),
65
+ /**
66
+ * #property
67
+ */
68
+ onlyDisplayRelevantRegionsInCircularView: false,
69
+ /**
70
+ * #property
71
+ * switch specifying whether we are showing the import wizard or the
72
+ * spreadsheet in our viewing area
73
+ */
74
+ mode: types.optional(
75
+ types.enumeration('SvInspectorViewMode', ['import', 'display']),
76
+ 'import',
77
+ ),
78
+ /**
79
+ * #property
80
+ */
81
+ spreadsheetView: types.optional(SpreadsheetModel, () =>
82
+ SpreadsheetModel.create({
83
+ type: 'SpreadsheetView',
84
+ hideVerticalResizeHandle: true,
85
+ }),
86
+ ),
87
+ /**
88
+ * #property
89
+ */
90
+ circularView: types.optional(CircularModel, () =>
91
+ CircularModel.create({
92
+ type: 'CircularView',
93
+ hideVerticalResizeHandle: true,
94
+ hideTrackSelectorButton: true,
95
+ disableImportForm: true,
96
+ }),
97
+ ),
98
+ }),
99
+ )
100
+ .volatile(() => ({
101
+ width: 800,
102
+ }))
103
+ .views(self => ({
104
+ /**
105
+ * #getter
106
+ */
107
+ get selectedRows() {
108
+ // @ts-expect-error
109
+ return self.spreadsheetView.rowSet.selectedRows
110
+ },
111
+ /**
112
+ * #getter
113
+ */
114
+ get assemblyName() {
115
+ const { assembly } = self.spreadsheetView
116
+ return assembly ? readConfObject(assembly, 'name') : undefined
117
+ },
118
+ /**
119
+ * #getter
120
+ */
121
+ get showCircularView() {
122
+ return self.spreadsheetView.mode === 'display'
123
+ },
124
+
125
+ /**
126
+ * #getter
127
+ */
128
+ get features() {
129
+ const session = getSession(self)
130
+ const { spreadsheetView } = self
131
+ const { outputRows = [] } = spreadsheetView
132
+ return outputRows
133
+ .map((r, i) => getFeatureForRow(session, spreadsheetView, r, i))
134
+ .filter(f => !!f)
135
+ },
136
+ /**
137
+ * #getter
138
+ */
139
+ get featuresAdapterConfigSnapshot() {
140
+ return {
141
+ type: 'FromConfigAdapter',
142
+ features: this.features,
143
+ }
144
+ },
145
+ /**
146
+ * #getter
147
+ */
148
+ get featureRefNames() {
149
+ const refs = this.features.map(r => r.refName)
150
+ const CHR2 = this.features.flatMap(r => r.INFO?.CHR2).filter(f => !!f)
151
+ return [...refs, ...CHR2]
152
+ },
153
+ /**
154
+ * #getter
155
+ */
156
+ get featuresCircularTrackConfiguration() {
157
+ return {
158
+ type: 'VariantTrack',
159
+ trackId: `sv-inspector-variant-track-${self.id}`,
160
+ name: 'features from tabular data',
161
+ adapter: this.featuresAdapterConfigSnapshot,
162
+ assemblyNames: [this.assemblyName],
163
+ displays: [
164
+ {
165
+ type: 'ChordVariantDisplay',
166
+ displayId: `sv-inspector-variant-track-chord-display-${self.id}`,
167
+ onChordClick: `jexl:defaultOnChordClick(feature, track, pluginManager)`,
168
+ renderer: { type: 'StructuralVariantChordRenderer' },
169
+ },
170
+ ],
171
+ }
172
+ },
173
+ }))
174
+ .volatile(() => ({
175
+ SpreadsheetViewReactComponent: SpreadsheetViewType.ReactComponent,
176
+ CircularViewReactComponent: CircularViewType.ReactComponent,
177
+ circularViewOptionsBarHeight,
178
+ }))
179
+ .actions(self => ({
180
+ /**
181
+ * #action
182
+ */
183
+ setWidth(newWidth: number) {
184
+ self.width = newWidth
185
+ },
186
+ /**
187
+ * #action
188
+ */
189
+ setHeight(newHeight: number) {
190
+ self.height = newHeight > minHeight ? newHeight : minHeight
191
+ return self.height
192
+ },
193
+ /**
194
+ * #action
195
+ */
196
+ setImportMode() {
197
+ self.spreadsheetView.setImportMode()
198
+ },
199
+ /**
200
+ * #action
201
+ */
202
+ setDisplayMode() {
203
+ self.spreadsheetView.setDisplayMode()
204
+ },
205
+ /**
206
+ * #action
207
+ */
208
+ closeView() {
209
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
210
+ getParent<any>(self, 2).removeView(self)
211
+ },
212
+ /**
213
+ * #action
214
+ */
215
+ setDisplayedRegions(regions: Region[]) {
216
+ self.circularView.setDisplayedRegions(regions)
217
+ },
218
+ /**
219
+ * #action
220
+ */
221
+ setOnlyDisplayRelevantRegionsInCircularView(val: boolean) {
222
+ self.onlyDisplayRelevantRegionsInCircularView = Boolean(val)
223
+ },
224
+ }))
225
+ .views(self => ({
226
+ /**
227
+ * #method
228
+ */
229
+ menuItems() {
230
+ return [
231
+ {
232
+ label: 'Return to import form',
233
+ onClick: () => self.setImportMode(),
234
+ icon: FolderOpenIcon,
235
+ },
236
+ ]
237
+ },
238
+ }))
239
+ .actions(self => ({
240
+ /**
241
+ * #action
242
+ */
243
+ resizeHeight(distance: number) {
244
+ const oldHeight = self.height
245
+ const newHeight = self.setHeight(self.height + distance)
246
+ return newHeight - oldHeight
247
+ },
248
+ afterAttach() {
249
+ // synchronize subview widths
250
+ addDisposer(
251
+ self,
252
+ autorun(
253
+ () => {
254
+ const borderWidth = 1
255
+ if (self.showCircularView) {
256
+ const spreadsheetWidth = Math.round(self.width * 0.66)
257
+ const circularViewWidth = self.width - spreadsheetWidth
258
+ self.spreadsheetView.setWidth(spreadsheetWidth - borderWidth)
259
+ self.circularView.setWidth(circularViewWidth)
260
+ } else {
261
+ self.spreadsheetView.setWidth(self.width)
262
+ }
263
+ },
264
+ { name: 'SvInspectorView width binding' },
265
+ ),
266
+ )
267
+ // synchronize subview heights
268
+ addDisposer(
269
+ self,
270
+ autorun(
271
+ () => {
272
+ self.spreadsheetView.setHeight(self.height - headerHeight)
273
+ self.circularView.setHeight(
274
+ self.height - headerHeight - circularViewOptionsBarHeight,
275
+ )
276
+ },
277
+ { name: 'SvInspectorView height binding' },
278
+ ),
279
+ )
280
+
281
+ // bind circularview displayedRegions to spreadsheet assembly, mediated
282
+ // by the onlyRelevantRegions toggle
283
+ addDisposer(
284
+ self,
285
+ autorun(
286
+ async () => {
287
+ const {
288
+ assemblyName,
289
+ onlyDisplayRelevantRegionsInCircularView,
290
+ circularView,
291
+ featureRefNames,
292
+ } = self
293
+ const { tracks } = circularView
294
+ const { assemblyManager } = getSession(self)
295
+ if (!assemblyName) {
296
+ return
297
+ }
298
+ const asm = await assemblyManager.waitForAssembly(assemblyName)
299
+ if (!asm) {
300
+ return
301
+ }
302
+
303
+ const { getCanonicalRefName, regions = [] } = asm
304
+ if (onlyDisplayRelevantRegionsInCircularView) {
305
+ if (tracks.length === 1) {
306
+ try {
307
+ // canonicalize the store's ref names if necessary
308
+ const refSet = new Set(
309
+ featureRefNames.map(r => getCanonicalRefName(r) || r),
310
+ )
311
+
312
+ circularView.setDisplayedRegions(
313
+ clone(regions.filter(r => refSet.has(r.refName))),
314
+ )
315
+ } catch (e) {
316
+ circularView.setError(e)
317
+ }
318
+ }
319
+ } else {
320
+ circularView.setDisplayedRegions(regions)
321
+ }
322
+ },
323
+ { name: 'SvInspectorView displayed regions bind' },
324
+ ),
325
+ )
326
+
327
+ // bind circularview tracks to our track snapshot view
328
+ addDisposer(
329
+ self,
330
+ reaction(
331
+ () => ({
332
+ generatedTrackConf: self?.featuresCircularTrackConfiguration,
333
+ assemblyName: self?.assemblyName,
334
+ }),
335
+ data => {
336
+ if (!data) {
337
+ return
338
+ }
339
+ const { assemblyName, generatedTrackConf } = data
340
+ const { circularView } = self
341
+ // hide any visible tracks
342
+ circularView.tracks.forEach(t =>
343
+ circularView.hideTrack(t.configuration.trackId),
344
+ )
345
+
346
+ // put our track in as the only track
347
+ if (assemblyName && generatedTrackConf) {
348
+ // @ts-expect-error
349
+ circularView.addTrackConf(generatedTrackConf, {
350
+ assemblyName,
351
+ })
352
+ }
353
+ },
354
+ {
355
+ name: 'SvInspectorView track configuration binding',
356
+ fireImmediately: true,
357
+ },
358
+ ),
359
+ )
360
+
361
+ // bind spreadsheetView row menu actions to us
362
+ addDisposer(
363
+ self,
364
+ autorun(() => {
365
+ self.spreadsheetView.setRowMenuItems(
366
+ // these are the MenuItem entries for the row menu actions in the
367
+ // spreadsheet view. these are installed into the child
368
+ // SpreadsheetView using an autorun below
369
+ [
370
+ {
371
+ label: 'Open split detail view',
372
+ icon: OpenInNewIcon,
373
+ // @ts-expect-error
374
+ disabled(spreadsheetView, spreadsheet, rowNumber, row) {
375
+ return !canOpenBreakpointSplitViewFromTableRow(
376
+ self,
377
+ spreadsheetView,
378
+ spreadsheet,
379
+ row,
380
+ rowNumber,
381
+ )
382
+ },
383
+
384
+ // @ts-expect-error
385
+ onClick(spreadsheetView, spreadsheet, rowNumber, row) {
386
+ openBreakpointSplitViewFromTableRow(
387
+ self,
388
+ spreadsheetView,
389
+ spreadsheet,
390
+ row,
391
+ rowNumber,
392
+ )
393
+ },
394
+ },
395
+ ],
396
+ )
397
+ }),
398
+ )
399
+ },
400
+ }))
401
+ }
402
+
403
+ export type SvInspectorViewStateModel = ReturnType<typeof SvInspectorViewF>
404
+ export type SvInspectorViewModel = Instance<SvInspectorViewStateModel>
405
+
406
+ export default SvInspectorViewF