jbrowse-plugin-graphgenomeviewer 4.0.2 → 4.0.4
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 +6 -5
- package/dist/chunks/AddTrackWorkflow-I4EPGFPJ.js +2 -0
- package/dist/chunks/{AddTrackWorkflow-TPCKXM2H.js.map → AddTrackWorkflow-I4EPGFPJ.js.map} +2 -2
- package/dist/chunks/{GraphGenomeView-WPKSNN4I.js → GraphGenomeView-BQYWWF6Z.js} +2 -2
- package/dist/chunks/LinearGraphDisplay-7O3VQHKU.js +2 -0
- package/dist/chunks/{LinearGraphDisplay-7POYIRIB.js.map → LinearGraphDisplay-7O3VQHKU.js.map} +2 -2
- package/dist/chunks/chunk-5WJPRX4N.js +2 -0
- package/dist/chunks/{chunk-A4ZWFDQY.js.map → chunk-5WJPRX4N.js.map} +2 -2
- package/dist/chunks/{chunk-SDTCVLC3.js → chunk-RSAY56Y4.js} +2 -2
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +2 -2
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +3 -3
- package/package.json +1 -1
- package/src/GraphAddTrackWorkflow/buildTrackConfig.test.ts +4 -0
- package/src/GraphAddTrackWorkflow/buildTrackConfig.ts +13 -1
- package/src/GraphGenomeView/host.ts +26 -7
- package/src/GraphGenomeView/layoutModes.ts +10 -0
- package/src/GraphGenomeView/model.ts +15 -4
- package/src/LinearGraphDisplay/LinearGraphDisplay.test.ts +73 -21
- package/src/LinearGraphDisplay/components/LinearGraphDisplay.tsx +1 -0
- package/src/LinearGraphDisplay/model.ts +36 -0
- package/src/version.ts +1 -1
- package/dist/chunks/AddTrackWorkflow-TPCKXM2H.js +0 -2
- package/dist/chunks/LinearGraphDisplay-7POYIRIB.js +0 -2
- package/dist/chunks/chunk-A4ZWFDQY.js +0 -2
- /package/dist/chunks/{GraphGenomeView-WPKSNN4I.js.map → GraphGenomeView-BQYWWF6Z.js.map} +0 -0
- /package/dist/chunks/{chunk-SDTCVLC3.js.map → chunk-RSAY56Y4.js.map} +0 -0
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "jbrowse-plugin-graphgenomeviewer",
|
|
3
|
-
"version": "4.0.
|
|
3
|
+
"version": "4.0.4",
|
|
4
4
|
"description": "JBrowse 2 graph genome (pangenome) view: rGFA reference-anchored layouts, the Bandage force-directed engine, and haplotype lanes read from a gbz-base database",
|
|
5
5
|
"license": "GPL-3.0-or-later",
|
|
6
6
|
"repository": {
|
|
@@ -23,6 +23,10 @@ describe('buildTrackConfig', () => {
|
|
|
23
23
|
trackId: 'hprc',
|
|
24
24
|
name: 'HPRC graph',
|
|
25
25
|
assemblyNames: ['hg38'],
|
|
26
|
+
displays: [
|
|
27
|
+
{ type: 'LinearGraphDisplay', displayId: 'hprc-LinearGraphDisplay' },
|
|
28
|
+
{ type: 'LinearBasicDisplay', displayId: 'hprc-LinearBasicDisplay' },
|
|
29
|
+
],
|
|
26
30
|
adapter: {
|
|
27
31
|
type: 'RgfaTabixAdapter',
|
|
28
32
|
segmentsLocation: segs,
|
|
@@ -108,7 +108,19 @@ export function buildTrackConfig(args: {
|
|
|
108
108
|
assemblyNames: [assembly],
|
|
109
109
|
adapter: buildAdapterConfig(args),
|
|
110
110
|
...(choice === 'RgfaTabixAdapter'
|
|
111
|
-
? {
|
|
111
|
+
? {
|
|
112
|
+
displays: [
|
|
113
|
+
{
|
|
114
|
+
type: 'LinearGraphDisplay',
|
|
115
|
+
displayId: `${trackId}-LinearGraphDisplay`,
|
|
116
|
+
},
|
|
117
|
+
{
|
|
118
|
+
type: 'LinearBasicDisplay',
|
|
119
|
+
displayId: `${trackId}-LinearBasicDisplay`,
|
|
120
|
+
},
|
|
121
|
+
],
|
|
122
|
+
displayDefaults: { showLabels: 'none' },
|
|
123
|
+
}
|
|
112
124
|
: {}),
|
|
113
125
|
}
|
|
114
126
|
}
|
|
@@ -105,9 +105,15 @@ export function hostWindow(view: LinearHost): HostWindow | undefined {
|
|
|
105
105
|
|
|
106
106
|
// The window plus one window-width each side, clamped to the displayed
|
|
107
107
|
// region, with the margins narrowed until the whole cut fits under `capBp`.
|
|
108
|
-
export function hostCut(
|
|
108
|
+
export function hostCut(
|
|
109
|
+
window: HostWindow,
|
|
110
|
+
capBp: number,
|
|
111
|
+
margins = true,
|
|
112
|
+
): SubgraphRegion {
|
|
109
113
|
const visible = window.end - window.start
|
|
110
|
-
const margin =
|
|
114
|
+
const margin = margins
|
|
115
|
+
? Math.max(0, Math.min(window.span, (capBp - visible) / 2))
|
|
116
|
+
: 0
|
|
111
117
|
return {
|
|
112
118
|
refName: window.refName,
|
|
113
119
|
assemblyName: window.assemblyName,
|
|
@@ -116,11 +122,24 @@ export function hostCut(window: HostWindow, capBp: number): SubgraphRegion {
|
|
|
116
122
|
}
|
|
117
123
|
}
|
|
118
124
|
|
|
119
|
-
|
|
125
|
+
// With margins, a cut holds while the window is inside it; without, only the
|
|
126
|
+
// window itself does, since the drawing is the window.
|
|
127
|
+
export function cutHolds(
|
|
128
|
+
cut: SubgraphRegion | undefined,
|
|
129
|
+
window: HostWindow,
|
|
130
|
+
margins = true,
|
|
131
|
+
) {
|
|
132
|
+
if (
|
|
133
|
+
cut?.refName !== window.refName ||
|
|
134
|
+
cut.assemblyName !== window.assemblyName
|
|
135
|
+
) {
|
|
136
|
+
return false
|
|
137
|
+
}
|
|
138
|
+
if (margins) {
|
|
139
|
+
return cut.start <= window.start && window.end <= cut.end
|
|
140
|
+
}
|
|
141
|
+
const exact = hostCut(window, Infinity, false)
|
|
120
142
|
return (
|
|
121
|
-
cut
|
|
122
|
-
cut.assemblyName === window.assemblyName &&
|
|
123
|
-
cut.start <= window.start &&
|
|
124
|
-
window.end <= cut.end
|
|
143
|
+
Math.abs(cut.start - exact.start) < 1 && Math.abs(cut.end - exact.end) < 1
|
|
125
144
|
)
|
|
126
145
|
}
|
|
@@ -39,6 +39,10 @@ export interface LayoutMode {
|
|
|
39
39
|
// rest rather than hiding them, so the reason a mode is unavailable stays
|
|
40
40
|
// visible instead of the menu silently changing shape between graphs
|
|
41
41
|
available: (graph: Graph) => boolean
|
|
42
|
+
// whether the drawing puts reference bp on x, so a host places it and a cut
|
|
43
|
+
// carries margins to pan over. A mode without one draws its own picture of
|
|
44
|
+
// the window, so its cut is the window alone.
|
|
45
|
+
referenceAxis: boolean
|
|
42
46
|
// whether `run` draws this graph itself, as opposed to handing off to the
|
|
43
47
|
// engine. Not the same question as `available` and not derivable from it:
|
|
44
48
|
// 'force' is available for every graph and draws none of them itself. The two
|
|
@@ -63,6 +67,7 @@ export const LAYOUT_MODES = [
|
|
|
63
67
|
description:
|
|
64
68
|
'x is reference bp, one row per stable rank. Needs rGFA tags or a reference path.',
|
|
65
69
|
run: anchoredLayout,
|
|
70
|
+
referenceAxis: true,
|
|
66
71
|
available: hasBackbone,
|
|
67
72
|
drawsLocally: hasBackbone,
|
|
68
73
|
},
|
|
@@ -72,6 +77,7 @@ export const LAYOUT_MODES = [
|
|
|
72
77
|
description:
|
|
73
78
|
'x is reference bp, one row per contributing assembly. Needs rGFA tags or a reference path.',
|
|
74
79
|
run: sampleRowLayout,
|
|
80
|
+
referenceAxis: true,
|
|
75
81
|
available: hasAlleles,
|
|
76
82
|
drawsLocally: hasAlleles,
|
|
77
83
|
},
|
|
@@ -81,6 +87,7 @@ export const LAYOUT_MODES = [
|
|
|
81
87
|
description:
|
|
82
88
|
"x is each walk's own bp: one bar per haplotype, sequence the reference also carries in blue and sequence it does not in purple, so a repeat expansion reads as bar length. Needs W or P lines.",
|
|
83
89
|
run: walkRowLayout,
|
|
90
|
+
referenceAxis: true,
|
|
84
91
|
available: hasWalks,
|
|
85
92
|
drawsLocally: hasWalks,
|
|
86
93
|
},
|
|
@@ -90,6 +97,7 @@ export const LAYOUT_MODES = [
|
|
|
90
97
|
description:
|
|
91
98
|
'x is reference order, not bp: every node gets room, bubbles read as lenses. Needs rGFA tags or a reference path.',
|
|
92
99
|
run: orderedLayout,
|
|
100
|
+
referenceAxis: false,
|
|
93
101
|
available: hasBackbone,
|
|
94
102
|
drawsLocally: hasBackbone,
|
|
95
103
|
},
|
|
@@ -99,6 +107,7 @@ export const LAYOUT_MODES = [
|
|
|
99
107
|
description:
|
|
100
108
|
'The reference as a line with one typed glyph per bubble, from the bubble index or from the graph itself: SNP, indel, deletion, inversion, repeat array. Click a glyph to open the graph inside it.',
|
|
101
109
|
run: variantMapLayout,
|
|
110
|
+
referenceAxis: true,
|
|
102
111
|
available: hasBackbone,
|
|
103
112
|
drawsLocally: hasBackbone,
|
|
104
113
|
},
|
|
@@ -107,6 +116,7 @@ export const LAYOUT_MODES = [
|
|
|
107
116
|
label: FORCE_LAYOUT_LABEL,
|
|
108
117
|
description: 'OGDF FMMM, via the external Bandage engine.',
|
|
109
118
|
run: () => undefined,
|
|
119
|
+
referenceAxis: false,
|
|
110
120
|
available: () => true,
|
|
111
121
|
drawsLocally: () => false,
|
|
112
122
|
},
|
|
@@ -2504,7 +2504,11 @@ export default function stateModelFactory() {
|
|
|
2504
2504
|
// its edge re-cuts the window plus a window-width each side, on the tier
|
|
2505
2505
|
// the zoom asks for. Overlapping re-cuts are ordered by doSubgraphLoad's
|
|
2506
2506
|
// liveLoad, so the latest window wins.
|
|
2507
|
+
// Returns whether it re-cut. A layout that draws its own picture of the
|
|
2508
|
+
// window is cut to the window alone; one the host places carries
|
|
2509
|
+
// margins to pan over.
|
|
2507
2510
|
settleOn(seen: HostWindow) {
|
|
2511
|
+
const margins = layoutModeByValue(self.layoutMode).referenceAxis
|
|
2508
2512
|
const above = self.coarseAboveBpPerPx
|
|
2509
2513
|
const tier =
|
|
2510
2514
|
above !== undefined && seen.bpPerPx > above ? 'coarse' : 'fine'
|
|
@@ -2516,14 +2520,15 @@ export default function stateModelFactory() {
|
|
|
2516
2520
|
: undefined
|
|
2517
2521
|
if (
|
|
2518
2522
|
self.cutNote !== undefined ||
|
|
2519
|
-
(tier === self.cutTier && cutHolds(self.loadedRegion, seen))
|
|
2523
|
+
(tier === self.cutTier && cutHolds(self.loadedRegion, seen, margins))
|
|
2520
2524
|
) {
|
|
2521
|
-
return
|
|
2525
|
+
return false
|
|
2522
2526
|
}
|
|
2523
2527
|
self.coarseCut = tier === 'coarse'
|
|
2524
|
-
self.loadedRegion = hostCut(seen, cap)
|
|
2528
|
+
self.loadedRegion = hostCut(seen, cap, margins)
|
|
2525
2529
|
self.recuts++
|
|
2526
2530
|
void self.reloadSubgraph()
|
|
2531
|
+
return true
|
|
2527
2532
|
},
|
|
2528
2533
|
}))
|
|
2529
2534
|
.actions(self => ({
|
|
@@ -2832,7 +2837,13 @@ export default function stateModelFactory() {
|
|
|
2832
2837
|
// A layout picked from a menu: the mode, then the drawing it makes.
|
|
2833
2838
|
switchLayout(mode: LayoutModeValue) {
|
|
2834
2839
|
self.setLayoutMode(mode)
|
|
2835
|
-
|
|
2840
|
+
const { host } = self
|
|
2841
|
+
const seen = host ? hostWindow(host) : undefined
|
|
2842
|
+
// A cut the new mode would make differently is made again, and that
|
|
2843
|
+
// reload lays the graph out; otherwise the layout alone is redone.
|
|
2844
|
+
return seen && self.settleOn(seen)
|
|
2845
|
+
? Promise.resolve()
|
|
2846
|
+
: self.recomputeLayout()
|
|
2836
2847
|
},
|
|
2837
2848
|
retryLoad() {
|
|
2838
2849
|
if (self.loadedTrackId && self.loadedRegion) {
|
|
@@ -13,6 +13,7 @@ import { types } from '@jbrowse/mobx-state-tree'
|
|
|
13
13
|
import { linearGenomeViewStateModelFactory } from '@jbrowse/plugin-linear-genome-view'
|
|
14
14
|
|
|
15
15
|
import LinearGraphDisplayF from './index'
|
|
16
|
+
import GbzBaseSyntenyAdapterF from '../GbzBaseSyntenyAdapter/index'
|
|
16
17
|
import RgfaTabixAdapterF from '../RgfaTabixAdapter/index'
|
|
17
18
|
|
|
18
19
|
import type { LinearGraphDisplayModel } from './model'
|
|
@@ -97,25 +98,28 @@ function createEnvironment({ tiered = true } = {}) {
|
|
|
97
98
|
console.warn = vi.fn()
|
|
98
99
|
const pluginManager = new PluginManager()
|
|
99
100
|
RgfaTabixAdapterF(pluginManager)
|
|
100
|
-
pluginManager
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
101
|
+
GbzBaseSyntenyAdapterF(pluginManager)
|
|
102
|
+
for (const name of ['FeatureTrack', 'SyntenyTrack']) {
|
|
103
|
+
pluginManager.addTrackType(() => {
|
|
104
|
+
const trackConfigSchema = ConfigurationSchema(
|
|
105
|
+
name,
|
|
106
|
+
{},
|
|
107
|
+
{
|
|
108
|
+
baseConfiguration: createBaseTrackConfig(pluginManager),
|
|
109
|
+
explicitIdentifier: 'trackId',
|
|
110
|
+
},
|
|
111
|
+
)
|
|
112
|
+
return new TrackType({
|
|
113
|
+
name,
|
|
114
|
+
configSchema: trackConfigSchema,
|
|
115
|
+
stateModel: createBaseTrackModel(
|
|
116
|
+
pluginManager,
|
|
117
|
+
name,
|
|
118
|
+
trackConfigSchema,
|
|
119
|
+
),
|
|
120
|
+
})
|
|
117
121
|
})
|
|
118
|
-
}
|
|
122
|
+
}
|
|
119
123
|
LinearGraphDisplayF(pluginManager)
|
|
120
124
|
pluginManager.addViewType(
|
|
121
125
|
() =>
|
|
@@ -155,7 +159,20 @@ function createEnvironment({ tiered = true } = {}) {
|
|
|
155
159
|
},
|
|
156
160
|
{ pluginManager },
|
|
157
161
|
)
|
|
158
|
-
const
|
|
162
|
+
const gbzTrackConfig = trackSchema.create(
|
|
163
|
+
{
|
|
164
|
+
type: 'SyntenyTrack',
|
|
165
|
+
trackId: 'walks',
|
|
166
|
+
name: 'walks',
|
|
167
|
+
assemblyNames: [ASM, 'HG1.1', 'HG2.1'],
|
|
168
|
+
adapter: { type: 'GbzBaseSyntenyAdapter', assemblyNames: [ASM] },
|
|
169
|
+
displays: [
|
|
170
|
+
{ type: 'LinearGraphDisplay', displayId: 'walks-LinearGraphDisplay' },
|
|
171
|
+
],
|
|
172
|
+
},
|
|
173
|
+
{ pluginManager },
|
|
174
|
+
)
|
|
175
|
+
const trackConfigs = [trackConfig, gbzTrackConfig]
|
|
159
176
|
|
|
160
177
|
const assemblyRegions = [
|
|
161
178
|
{ refName: REF, start: 0, end: CONTIG, assemblyName: ASM },
|
|
@@ -321,19 +338,44 @@ test('with no coarse tier the margins narrow to the cap, and past it the last cu
|
|
|
321
338
|
expect(pane.cutNote).toMatch(/Holding the last cut/)
|
|
322
339
|
})
|
|
323
340
|
|
|
324
|
-
test('a layout whose x is not reference bp draws its own viewport, and still re-cuts', async () => {
|
|
341
|
+
test('a layout whose x is not reference bp draws its own viewport of the window alone, and still re-cuts', async () => {
|
|
325
342
|
const { view, pane, cuts } = await shownGraph()
|
|
326
343
|
await pane.switchLayout('force')
|
|
344
|
+
await wait(SETTLE_MS)
|
|
327
345
|
expect(pane.hostPlacesX).toBe(false)
|
|
328
346
|
expect(pane.viewportOwner).not.toBe('host')
|
|
347
|
+
expect(cuts).toHaveLength(2)
|
|
348
|
+
expect(cuts[1]!.region).toMatchObject({ start: 1_000_000, end: 1_060_000 })
|
|
329
349
|
view.scrollTo(2_000_000 / view.bpPerPx)
|
|
330
350
|
await wait(SETTLE_MS)
|
|
331
|
-
expect(cuts).toHaveLength(
|
|
351
|
+
expect(cuts).toHaveLength(3)
|
|
352
|
+
expect(cuts[2]!.region.start).toBe(2_000_000)
|
|
353
|
+
expect(Math.abs(cuts[2]!.region.end - 2_060_000)).toBeLessThanOrEqual(1)
|
|
332
354
|
await pane.switchLayout('auto')
|
|
355
|
+
await wait(SETTLE_MS)
|
|
333
356
|
expect(pane.hostPlacesX).toBe(true)
|
|
334
357
|
expect(graphX(pane, 2_030_000)).toBeCloseTo(lgvX(view, 2_030_000), 6)
|
|
335
358
|
})
|
|
336
359
|
|
|
360
|
+
test('a launch in the force layout cuts the window alone', async () => {
|
|
361
|
+
const { view, cuts } = createEnvironment()
|
|
362
|
+
view.zoomTo(60_000 / WIDTH_PX)
|
|
363
|
+
view.scrollTo(1_000_000 / view.bpPerPx)
|
|
364
|
+
view.showTrack(
|
|
365
|
+
'graph',
|
|
366
|
+
{},
|
|
367
|
+
{
|
|
368
|
+
type: 'LinearGraphDisplay',
|
|
369
|
+
pane: { layoutMode: 'force' },
|
|
370
|
+
},
|
|
371
|
+
)
|
|
372
|
+
const display = view.tracks[0]!.displays[0] as LinearGraphDisplayModel
|
|
373
|
+
display.pane.startRenderingBackend(fakeRenderer())
|
|
374
|
+
await wait(SETTLE_MS)
|
|
375
|
+
expect(cuts).toHaveLength(1)
|
|
376
|
+
expect(cuts[0]!.region).toMatchObject({ start: 1_000_000, end: 1_060_000 })
|
|
377
|
+
})
|
|
378
|
+
|
|
337
379
|
test('the track is as tall as its rows, up to the configured height', async () => {
|
|
338
380
|
const { display, pane } = await shownGraph()
|
|
339
381
|
expect(display.height).toBe(pane.canvasHeight)
|
|
@@ -385,6 +427,16 @@ test('a launch that states one pane prop takes the rest from the config', async
|
|
|
385
427
|
expect(display.pane.hostPlacesX).toBe(true)
|
|
386
428
|
})
|
|
387
429
|
|
|
430
|
+
test('a GBZ track cuts for the lanes it names', async () => {
|
|
431
|
+
const { view } = createEnvironment()
|
|
432
|
+
view.zoomTo(60_000 / WIDTH_PX)
|
|
433
|
+
view.scrollTo(1_000_000 / view.bpPerPx)
|
|
434
|
+
view.showTrack('walks')
|
|
435
|
+
const display = view.tracks[0]!.displays[0] as LinearGraphDisplayModel
|
|
436
|
+
expect(display.type).toBe('LinearGraphDisplay')
|
|
437
|
+
expect(display.pane.subgraphHaplotypes).toEqual(['HG1.1', 'HG2.1'])
|
|
438
|
+
})
|
|
439
|
+
|
|
388
440
|
test('the track menu offers the layouts, colours and the settings dialog', async () => {
|
|
389
441
|
const { display } = await shownGraph()
|
|
390
442
|
const labels = display
|
|
@@ -29,6 +29,7 @@ const LinearGraphDisplay = observer(function LinearGraphDisplay({
|
|
|
29
29
|
data-cut-tier={pane.cutTier}
|
|
30
30
|
data-recuts={pane.recuts}
|
|
31
31
|
data-node-count={pane.hasGraph ? pane.nodeCount : undefined}
|
|
32
|
+
data-loading={pane.isLoading ? '' : undefined}
|
|
32
33
|
style={{
|
|
33
34
|
position: 'relative',
|
|
34
35
|
width: pane.width,
|
|
@@ -12,6 +12,7 @@ import { COLOR_SCHEMES } from '../GraphGenomeView/colorSchemes'
|
|
|
12
12
|
import { isLinearHost } from '../GraphGenomeView/host'
|
|
13
13
|
import { LAYOUT_MODES } from '../GraphGenomeView/layoutModes'
|
|
14
14
|
import paneModelFactory from '../GraphGenomeView/model'
|
|
15
|
+
import { trackLanes } from '../launchSubgraph/subgraphTracks'
|
|
15
16
|
|
|
16
17
|
import type { LinearGraphDisplayConfigModel } from './configSchema'
|
|
17
18
|
import type { MenuItem } from '@jbrowse/core/ui'
|
|
@@ -141,6 +142,31 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
141
142
|
},
|
|
142
143
|
]
|
|
143
144
|
: []),
|
|
145
|
+
...(pane.layoutMode === 'walkrows' && pane.repeatChoices.length > 0
|
|
146
|
+
? [
|
|
147
|
+
{
|
|
148
|
+
label: 'Repeat',
|
|
149
|
+
subMenu: [
|
|
150
|
+
{
|
|
151
|
+
type: 'radio' as const,
|
|
152
|
+
label: 'Whole window',
|
|
153
|
+
checked: pane.repeatKey === '',
|
|
154
|
+
onClick: () => {
|
|
155
|
+
pane.setRepeatKey('')
|
|
156
|
+
},
|
|
157
|
+
},
|
|
158
|
+
...pane.repeatChoices.map(({ key, name, unit }) => ({
|
|
159
|
+
type: 'radio' as const,
|
|
160
|
+
label: `${name} · ${unit.toLocaleString()} bp unit`,
|
|
161
|
+
checked: pane.repeatKey === key,
|
|
162
|
+
onClick: () => {
|
|
163
|
+
pane.setRepeatKey(key)
|
|
164
|
+
},
|
|
165
|
+
})),
|
|
166
|
+
],
|
|
167
|
+
},
|
|
168
|
+
]
|
|
169
|
+
: []),
|
|
144
170
|
...(pane.hostPlacesX
|
|
145
171
|
? []
|
|
146
172
|
: [
|
|
@@ -233,6 +259,16 @@ export function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {
|
|
|
233
259
|
const { pane } = self
|
|
234
260
|
self.applyConfig()
|
|
235
261
|
pane.adoptTrack(self.trackId)
|
|
262
|
+
// A GBZ track cuts for the lanes it names, as its lanes display
|
|
263
|
+
// draws them, unless a launch or a reader picked others.
|
|
264
|
+
if (
|
|
265
|
+
pane.subgraphHaplotypes === undefined &&
|
|
266
|
+
self.adapterConfig.type === 'GbzBaseSyntenyAdapter'
|
|
267
|
+
) {
|
|
268
|
+
pane.setSubgraphHaplotypes(
|
|
269
|
+
trackLanes(self.parentTrack.configuration),
|
|
270
|
+
)
|
|
271
|
+
}
|
|
236
272
|
pane.startHosting()
|
|
237
273
|
addDisposer(
|
|
238
274
|
self,
|
package/src/version.ts
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
export const version = '4.0.
|
|
1
|
+
export const version = '4.0.4'
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as z}from"./chunk-FCWXYIFC.js";import{a as $}from"./chunk-D7XFR2IV.js";import{a as H}from"./chunk-J4OLMLS5.js";import{a as L,b as j,c as O,d as J,e as U}from"./chunk-XEJ47DLD.js";import{a as D,b as r}from"./chunk-FY3BTKY4.js";var C=D((Z,y)=>{y.exports=JBrowseExports["@jbrowse/core/util/tss-react"]});var c=r(U(),1),p=r(J(),1),m=r(H(),1),E=r(C(),1),B=r(z(),1),i=r(O(),1),P=r(j(),1);var b=r($(),1),S={RgfaTabixAdapter:"rGFA segments (tabix BED pair)",MinigraphBubbleAdapter:"Minigraph bubbles (tabix BED)"},R={RgfaTabixAdapter:"Path to segments BED (.segs.bed.gz from build_rgfa_tabix.sh; the .links.bed.gz and both .tbi are assumed beside it)",MinigraphBubbleAdapter:"Path to bubbles BED (.bed.gz from gfatools bubble; the .tbi is assumed beside it)"},u=".segs.bed.gz";function f(t){return"uri"in t?t.uri:"localPath"in t?t.localPath:""}function X(t){let e=f(t);if(!e.endsWith(u))throw new Error(`Expected a segments BED ending in ${u}, got ${e||"a blob"}`);let a=`${e.slice(0,-u.length)}.links.bed.gz`;return"uri"in t?{...t,uri:a}:"localPath"in t?{...t,localPath:a}:t}function A(t,e){return e?{location:e,indexType:(0,b.makeIndexType)(f(e),"CSI","TBI")}:{location:(0,b.makeIndex)(t,".tbi"),indexType:"TBI"}}function q(t,e){return e!==void 0&&f(e).endsWith(".csi")?{location:(0,b.makeIndex)(t,".csi"),indexType:"CSI"}:{location:(0,b.makeIndex)(t,".tbi"),indexType:"TBI"}}function I(t,e){let a=e.trim();return a?{assemblyNameToPanSN:{[t]:a}}:{}}function K({choice:t,loc:e,indexLoc:a,assembly:s,sample:l}){if(t==="MinigraphBubbleAdapter")return{type:"MinigraphBubbleAdapter",bubblesLocation:e,index:A(e,a),...I(s,l)};let d=X(e);return{type:"RgfaTabixAdapter",segmentsLocation:e,segmentsIndex:A(e,a),linksLocation:d,linksIndex:q(d,a),...I(s,l)}}function G(t){let{choice:e,assembly:a,trackId:s,name:l}=t;return{type:"FeatureTrack",trackId:s,name:l,assemblyNames:[a],adapter:K(t),...e==="RgfaTabixAdapter"?{displayDefaults:{showLabels:"none"}}:{}}}var n=r(L(),1),Q=(0,E.makeStyles)()(t=>({paper:{margin:t.spacing(),padding:t.spacing()},field:{marginTop:t.spacing(2)},submit:{marginTop:25,marginBottom:100,display:"block"}})),V=["RgfaTabixAdapter","MinigraphBubbleAdapter"],Y=(0,P.observer)(function({model:e}){let{classes:a}=Q(),s=(0,m.getSession)(e),l=(0,B.getRoot)(e),[d,M]=(0,c.useState)("RgfaTabixAdapter"),[g,N]=(0,c.useState)(),[F,v]=(0,c.useState)(),[k,w]=(0,c.useState)(""),[h,_]=(0,c.useState)("Pangenome graph"),[x,T]=(0,c.useState)();function W(){if(!(!g||!e.assembly))try{T(void 0);let o=h.trim();(0,m.addTrackFromWidget)({model:e,session:s,conf:G({choice:d,loc:g,indexLoc:F,assembly:e.assembly,sample:k,trackId:(0,m.makeTrackId)({name:o}),name:o})})}catch(o){T(o)}}return(0,n.jsxs)(i.Paper,{className:a.paper,children:[x?(0,n.jsx)(p.ErrorMessage,{error:x}):null,(0,n.jsxs)(i.FormControl,{children:[(0,n.jsx)(i.FormLabel,{children:"File type"}),(0,n.jsx)(i.RadioGroup,{value:d,onChange:o=>{M(o.target.value)},children:V.map(o=>(0,n.jsx)(i.FormControlLabel,{value:o,control:(0,n.jsx)(i.Radio,{}),label:S[o]},o))})]}),(0,n.jsx)(p.FileSelector,{location:g,name:R[d],rootModel:l,setLocation:N}),(0,n.jsx)(p.FileSelector,{location:F,name:"Path to tabix index (optional; the sibling .tbi is assumed, a .csi is recognised by name)",rootModel:l,setLocation:v}),(0,n.jsx)(i.TextField,{className:a.field,value:k,onChange:o=>{w(o.target.value)},label:"Sample name in the graph",slotProps:{htmlInput:{"data-testid":"graph-sample-input"}},helperText:"Optional. The PanSN prefix the graph gives this assembly, e.g. GRCh38 for HPRC's GRCh38#0#chr1; leave blank when the graph's stable names are bare",placeholder:"GRCh38",fullWidth:!0}),(0,n.jsx)(i.TextField,{className:a.field,value:h,helperText:"Track name",slotProps:{htmlInput:{"data-testid":"graph-track-name-input"}},onChange:o=>{_(o.target.value)}}),(0,n.jsx)(p.AssemblySelector,{session:s,helperText:"Select assembly to add track to",selected:e.assembly,onChange:o=>{e.setAssembly(o)},fullWidth:!0}),(0,n.jsx)(i.Button,{variant:"contained",className:a.submit,disabled:!g||!h.trim()||!e.assembly,onClick:W,children:"Submit"})]})}),ae=Y;export{ae as default};
|
|
2
|
-
//# sourceMappingURL=AddTrackWorkflow-TPCKXM2H.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{a as r,b as i}from"./chunk-SDTCVLC3.js";import"./chunk-A4ZWFDQY.js";import"./chunk-ZNGDWZ6Z.js";import"./chunk-OHT6UX4C.js";import"./chunk-OP7IRVG6.js";import"./chunk-F4C3BEPV.js";import{a as e,b as s,c as u}from"./chunk-XEJ47DLD.js";import{b as o}from"./chunk-FY3BTKY4.js";var d=o(u(),1),n=o(s(),1);var t=o(e(),1),h={position:"absolute",left:8,top:4,zIndex:5,background:"rgba(255,255,255,0.82)",padding:"0 4px",borderRadius:3},c=(0,n.observer)(function({model:p}){let{pane:a,height:l}=p;return(0,t.jsxs)("div",{"data-testid":"linear-graph-display","data-layout":a.layoutMode,"data-cut-tier":a.cutTier,"data-recuts":a.recuts,"data-node-count":a.hasGraph?a.nodeCount:void 0,style:{position:"relative",width:a.width,height:l,overflow:"hidden"},children:[(0,t.jsx)(r,{model:a,toolbar:!1}),a.hasGraph?null:(0,t.jsx)(i,{model:a}),a.cutNote?(0,t.jsx)(d.Typography,{variant:"caption",color:"warning.main",style:h,"data-testid":"graph-cut-note",children:a.cutNote}):null]})}),g=c;export{g as default};
|
|
2
|
-
//# sourceMappingURL=LinearGraphDisplay-7POYIRIB.js.map
|
|
@@ -1,2 +0,0 @@
|
|
|
1
|
-
import{c as Ve}from"./chunk-ZNGDWZ6Z.js";import{A as Ge,B as Oe,a as ue,b as S,c as Ne,d as F,e as j,f as Ue,h as we,p as ke,v as qe,w as Je,y as Ze,z as Qe}from"./chunk-OP7IRVG6.js";import{a as Re,b as je,c as Ke}from"./chunk-F4C3BEPV.js";import{a as Me}from"./chunk-XEJ47DLD.js";import{a as Ie,b as ee}from"./chunk-FY3BTKY4.js";var tt=Ie((yo,et)=>{et.exports=JBrowseExports["@mui/material/SvgIcon"]});var _e=Ie((Mo,nt)=>{nt.exports=JBrowseExports["@jbrowse/core/util/colorBits"]});var Yn=Ie((mr,At)=>{At.exports=JBrowseExports["@jbrowse/render-core/canvas2dUtils"]});var T=ee(tt(),1);var C=ee(_e(),1);var A=ee(_e(),1);function de(e,t){return(0,A.packAbgr)((0,A.abgrRed)(e),(0,A.abgrGreen)(e),(0,A.abgrBlue)(e),Math.round((0,A.abgrAlpha)(e)*t))}function Ro(e,t){return(0,A.packAbgr)(Math.min(255,Math.round((0,A.abgrRed)(e)*t)),Math.min(255,Math.round((0,A.abgrGreen)(e)*t)),Math.min(255,Math.round((0,A.abgrBlue)(e)*t)),(0,A.abgrAlpha)(e))}var Ft=4;function fe(e){let t=new Map;function n(o,r){let s=t.get(o);s?s.push(r):t.set(o,[r])}for(let o of e.edges)n(o.from,o.to),n(o.to,o.from);return t}function jt({nodeId:e,nodeById:t,neighbors:n}){let o=new Set([e]),r=[e],s=1/0,a=-1/0;for(let i=0;i<Ft&&r.length>0;i++){let l=[];for(let f of r){let d=n.get(f);if(d){for(let u of d)if(!o.has(u)){o.add(u);let c=t.get(u);c&&S(c)?(s=Math.min(s,c.stable.start+c.length),a=Math.max(a,c.stable.start)):l.push(u)}}}r=l}return s===1/0?void 0:{start:Math.min(s,a),end:Math.max(s,a)}}function Kt({nodeId:e,nodeById:t,neighbors:n}){let o=t.get(e);return o===void 0?void 0:S(o)?{start:o.stable.start,end:o.stable.start+o.length}:jt({nodeId:e,nodeById:t,neighbors:n})}function ot(e){let t=new Map(e.nodes.map(r=>[r.id,r])),n=fe(e),o=new Map;for(let r of e.nodes){let s=Kt({nodeId:r.id,nodeById:t,neighbors:n});s&&o.set(r.id,(s.start+s.end)/2)}return o}function vo(e){let t=n=>Math.round(n*100)/100;return e.map((n,o)=>`${o?"L":"M"}${t(n.x)},${t(n.y)}`).join("")}function rt(e,t,n,o,r){let s=Math.hypot(o-t,n-e);if(s===0)return[n,o];let a=(n-e)/s,i=(o-t)/s;return[n+r*a,o+r*i]}function Pe(e,t){let n=1-t,o=n*n*n,r=3*n*n*t,s=3*n*t*t,a=t*t*t;return{x:o*e.x0+r*e.cx0+s*e.cx1+a*e.x1,y:o*e.y0+r*e.cy0+s*e.cy1+a*e.y1}}function Co(e){let t=e[Math.floor(e.length/2)];return t?Pe(t,.5):void 0}function Eo(e){let t=1/0,n=1/0,o=-1/0,r=-1/0;for(let s of e)t=Math.min(t,s.x0,s.cx0,s.cx1,s.x1),o=Math.max(o,s.x0,s.cx0,s.cx1,s.x1),n=Math.min(n,s.y0,s.cy0,s.cy1,s.y1),r=Math.max(r,s.y0,s.cy0,s.cy1,s.y1);return{minX:t,minY:n,maxX:o,maxY:r}}function Ut(e,t,n){let o=Pe(e,t),r=Pe(e,n),s=(n-t)/3,a=st(e,t),i=st(e,n);return{x0:o.x,y0:o.y,cx0:o.x+a.x*s,cy0:o.y+a.y*s,cx1:r.x-i.x*s,cy1:r.y-i.y*s,x1:r.x,y1:r.y}}function st(e,t){let n=1-t,o=3*n*n,r=6*n*t,s=3*t*t;return{x:o*(e.cx0-e.x0)+r*(e.cx1-e.cx0)+s*(e.x1-e.cx1),y:o*(e.cy0-e.y0)+r*(e.cy1-e.cy0)+s*(e.y1-e.cy1)}}function ut(e,t){let n=[];for(let o of e){let r=Math.hypot(o.cx0-o.x0,o.cy0-o.y0)+Math.hypot(o.cx1-o.cx0,o.cy1-o.cy0)+Math.hypot(o.x1-o.cx1,o.y1-o.cy1),s=Math.max(3,Math.round(r/t)|1);for(let a=0;a<s;a+=2)n.push([Ut(o,a/s,(a+1)/s)])}return n}function dt(e,t,n){let o=new Array(e.length);for(let r=0;r<e.length;r++){let s=e[r];o[r]={x0:s.x0+t,y0:s.y0+n,cx0:s.cx0+t,cy0:s.cy0+n,cx1:s.cx1+t,cy1:s.cy1+n,x1:s.x1+t,y1:s.y1+n}}return o}function at(e,t){let n=e.length-1;return t==="end"?{at:e[n],inward:e[n-1]}:{at:e[0],inward:e[1]}}var Vt=.5,qt=80;function it(e){let t=1/0,n=-1/0;for(let o of e)t=Math.min(t,o.x),n=Math.max(n,o.x);return{min:t,max:n}}function ct(e,t){return Math.max(0,t.min-e,e-t.max)}function lt(e,t,n){let o=ct(e[0].x,t),r=ct(e[e.length-1].x,t);return o===r?n:o<r?"start":"end"}function Jt(e,t){return{from:lt(e,it(t),"end"),to:lt(t,it(e),"start")}}var Zt=.75,Qt=1.15,en=.35,tn=60;function nn(e,t,n,o,r,s){let a=Math.hypot(n-e,o-t),i=a===0?1:(n-e)/a,l=a===0?0:(o-t)/a,f=0,d=1/0,u=-1/0;for(let h of r){let g=h.x-e,b=h.y-t,y=g*-l+b*i;Math.abs(y)>Math.abs(f)&&(f=y);let N=g*i+b*l;d=Math.min(d,N),u=Math.max(u,N)}let c=r.length?u-d:0,m=Math.max(Math.abs(f)*Qt/Zt,c*en),p=s===void 0?m:Math.min(m,s);return f<0?-p:p}function Se({scaleX:e,scaleY:t}){return t/e}var on=3;function Be(e,t,n){let o=t.x-e.x,r=(t.y-e.y)*n,s=Math.hypot(o,r);return s===0?void 0:{x:o/s,y:r/s}}function ft(e,t,n,o,r=on){let s=Se(o),a=Be(e[e.length-1],t[0],s)??Be(e[0],e.at(-1),s)??Be(t[0],t.at(-1),s)??{x:1,y:0},i=[];for(let l=0;l<n;l++){let f=(l-(n-1)/2)*r;i.push({x:-a.y*f,y:a.x*f/s})}return i}function Te(e,t){return e.map(n=>({x:n.x,y:n.y*t}))}function rn(e,t){for(let n of e)n.y0/=t,n.cy0/=t,n.cy1/=t,n.y1/=t;return e}function pe(e,t,n,o,r,s,a=[],i){let l=s.scaleX,f=Se(s),d=i??(s.pixelRows?tn:void 0);if(f!==1)return rn(pe(Te(e,f),Te(t,f),n,o,r*f,{scaleX:l,scaleY:l},Te(a,f),d===void 0?void 0:d*f),f);let u=n?{from:"end",to:"start"}:Jt(e,t),c=at(e,u.from),m=at(t,u.to),p=c.at,h=m.at,g=p.x+o,b=p.y+r,y=h.x+o,N=h.y+r;if(n){let w=1,M=0;if(c.inward){let J=p.x-c.inward.x,Z=p.y-c.inward.y,$=Math.hypot(J,Z);$>0&&(w=J/$,M=Z/$)}let R=Math.min(50,50*l),L=-M,G=w,I=(p.x+h.x)/2+o+L*R,V=(p.y+h.y)/2+r+G*R,ne=g+w*R,q=b+M*R,P=y-w*R,k=N-M*R;return[{x0:g,y0:b,cx0:ne,cy0:q,cx1:ne+L*R,cy1:q+G*R,x1:I,y1:V},{x0:I,y0:V,cx0:P+L*R,cy0:k+G*R,cx1:P,cy1:k,x1:y,y1:N}]}else{let w=c.inward??{x:p.x-(h.x-p.x),y:p.y-(h.y-p.y)},M=m.inward??{x:h.x-(p.x-h.x),y:h.y-(p.y-h.y)},R=Math.hypot(y-g,N-b),L=(H,_,D,re)=>{let z=_.x-H.x,W=_.y-H.y,X=Math.hypot(z,W),Q=X===0?0:(D*z+re*W)/X;return Math.max(0,Math.min(R*Vt,qt,Q*.5))},G=h.x-p.x,I=h.y-p.y,[V,ne]=rt(w.x,w.y,p.x,p.y,L(w,p,G,I)),[q,P]=rt(M.x,M.y,h.x,h.y,L(M,h,-G,-I)),k=a.length?nn(g,b,y,N,a,d):0,J=R===0?1:R,Z=(y-g)/J,$=(N-b)/J,me=-$*k,x=Z*k,v=Z*Math.abs(k),O=$*Math.abs(k);return[{x0:g,y0:b,cx0:V+o+me-v,cy0:ne+r+x-O,cx1:q+o+me+v,cy1:P+r+x+O,x1:y,y1:N}]}}var sn=1;function $e(e,t){return t.flatMap(n=>e[n]??[])}function Oo(e,t,n){let o=e[t.from],r=e[t.to];return o?.length&&r?.length?pe(o,r,t.from===t.to,0,0,n,$e(e,t.bypassed)):void 0}function an(e){let t=new Map;for(let n of e.nodes)if(S(n)){let o=t.get(n.stable.refName);o?o.push(n):t.set(n.stable.refName,[n])}for(let n of t.values())n.sort((o,r)=>o.stable.start-r.stable.start);return t}function cn(e,t,n){let o=[];if(e)for(let r=Ue(e,t);r<e.length;r++){let s=e[r];if(s.stable.start>=n)break;s.stable.start+s.length<=n&&o.push(s.id)}return o}function ln(e,t,n,o){let{fromStrand:r,toStrand:s}=e;if(r===void 0||s===void 0)return!0;let a=r===(t.stable.strand??"+"),i=s===(n.stable.strand??"+");return o?a&&i:!a&&!i}function _o(e){let t=new Map(e.nodes.map(r=>[r.id,r])),n=an(e),o=[];for(let r=0;r<e.edges.length;r++){let s=e.edges[r],a=t.get(s.from),i=t.get(s.to);if(a!==void 0&&i!==void 0&&S(a)&&S(i)&&a.stable.refName===i.stable.refName){let l=a.stable.start<=i.stable.start,[f,d]=l?[a,i]:[i,a],u=f.stable.start+f.length,c=d.stable.start,m=c-u;if(m>=sn&&ln(s,a,i,l)){let p=f.stable.refName;o.push({edgeIndex:r,from:s.from,to:s.to,refName:p,start:u,end:c,bp:m,bypassed:cn(n.get(p),u,c)})}}}return o}var pt=new WeakMap;function mt(e,t,n,o,r){let{scaleX:s,scaleY:a}=n,i=pt.get(e);if(i?.graph===t&&i.scaleX===s&&i.scaleY===a&&i.deletions===o&&i.version===r)return i.curves;let l=new Map;for(let f=0;f<t.edges.length;f++){let d=t.edges[f],u=e[d.from],c=e[d.to];if(u?.length&&c?.length){let m=o?.get(f);l.set(f,pe(u,c,d.from===d.to,0,0,n,m?$e(e,m):[]))}}return pt.set(e,{graph:t,scaleX:s,scaleY:a,deletions:o,version:r,curves:l}),l}var un=(0,C.packAbgr)(119,119,119,217),ht=(0,C.packAbgr)(136,136,136,217),dn=(0,C.packAbgr)(24,24,28,240),fn=2.2,pn=(0,C.packAbgr)(30,30,36,245),mn=1.8,Ae=.18,hn=11,bn=1.2,gn=1e-6,yn=12,xn=.45;function Mn(e,t=1){let n=t===1?e:e.map(r=>({x:r.x,y:r.y*t})),o=[];for(let r=0;r<n.length;r++){let s=0,a=0;if(r===0){let i=n[1].x-n[0].x,l=n[1].y-n[0].y,f=Math.hypot(i,l);f>0&&(s=-l/f,a=i/f)}else if(r===n.length-1){let i=n[r].x-n[r-1].x,l=n[r].y-n[r-1].y,f=Math.hypot(i,l);f>0&&(s=-l/f,a=i/f)}else{let i=n[r].x-n[r-1].x,l=n[r].y-n[r-1].y,f=Math.hypot(i,l),d=n[r+1].x-n[r].x,u=n[r+1].y-n[r].y,c=Math.hypot(d,u);if(f>0&&c>0){let m=-l/f,p=i/f,h=-u/c,g=d/c;s=(m+h)/2,a=(p+g)/2;let b=m*s+p*a;b>.1&&(s/=b,a/=b)}else f>0?(s=-l/f,a=i/f):c>0&&(s=-u/c,a=d/c)}o.push({nx:s,ny:a})}return o}function Rn(e,t,n,o=1){return e.map((r,s)=>({x:r.x+t[s].nx*n,y:r.y+t[s].ny*n/o}))}function Le(e,t,n,o){return(0,C.packAbgr)(Math.round(e*255),Math.round(t*255),Math.round(n*255),Math.round(o*255))}function ve(e,t,n){let o=(1-Math.abs(2*n-1))*t,r=o*(1-Math.abs(e/60%2-1)),s=n-o/2,a=0,i=0,l=0;return e<60?(a=o,i=r):e<120?(a=r,i=o):e<180?(i=o,l=r):e<240?(i=r,l=o):e<300?(a=r,l=o):(a=o,l=r),[a+s,i+s,l+s]}var Nn=[[68,1,84],[59,82,139],[33,145,140],[94,201,98],[253,231,37]],wn=[[237,137,44],[158,42,122]],Sn=[[220,50,50],[50,120,220]];function He(e,t){let n=Math.max(0,Math.min(1,t))*(e.length-1),o=Math.min(e.length-2,Math.floor(n)),r=n-o,s=e[o],a=e[o+1];return(0,C.packAbgr)(Math.round(s[0]+(a[0]-s[0])*r),Math.round(s[1]+(a[1]-s[1])*r),Math.round(s[2]+(a[2]-s[2])*r),255)}function An(e,t){let[n,o,r]=ve(Ze(e),Ge,Oe);return Le(n,o,r,t)}var Ln=300,vn=.7,Cn=.5,En=(0,C.packAbgr)(60,65,72,255);function Fo(e,t){let n=ot(e);if(t&&t.end>t.start)return{start:t.start,span:t.end-t.start,midpoints:n};let o=1/0,r=-1/0;for(let s of n.values())o=Math.min(o,s),r=Math.max(r,s);return{start:o===1/0?0:o,span:r>o?r-o:1,midpoints:n}}function In(e){let t=1/0,n=-1/0,o=1/0,r=-1/0,s=0;for(let a of e.nodes)a.stable!==void 0&&a.stable.rank>s&&(s=a.stable.rank),a.depth<t&&(t=a.depth),a.depth>n&&(n=a.depth),a.length<o&&(o=a.length),a.length>r&&(r=a.length);return{minDepth:t,maxDepth:n,minLength:o,maxLength:r,maxRank:s,nodeCount:e.nodes.length}}function kn(e,t,n,o){switch(n){case"random":return An(e.id,1);case"depth":return He(Nn,o.maxDepth>o.minDepth?(e.depth-o.minDepth)/(o.maxDepth-o.minDepth):.5);case"node-length":return He(Sn,o.maxLength>o.minLength?(e.length-o.minLength)/(o.maxLength-o.minLength):.5);case"stable-rank":return e.stable===void 0?(0,C.packAbgr)(160,160,160,255):e.stable.rank===0?(0,C.packAbgr)(52,152,219,255):He(wn,o.maxRank>1?(e.stable.rank-1)/(o.maxRank-1):0);case"reference-position":{let r=o.referenceRamp,s=r?.midpoints.get(e.id);if(r===void 0||s===void 0)return(0,C.packAbgr)(160,160,160,255);if(e.stable!==void 0&&e.stable.rank>0)return En;let a=Math.max(0,Math.min(1,(s-r.start)/r.span)),[i,l,f]=ve(a*Ln,vn,Cn);return Le(i,l,f,1)}case"grey":return(0,C.packAbgr)(160,160,160,255);case"rainbow":{let r=o.nodeCount>1?t/o.nodeCount*360:0,[s,a,i]=ve(r,.75,.5);return Le(s,a,i,1)}default:return(0,C.packAbgr)(52,152,219,255)}}function Gn(e,t=1){let n=e.x1-e.cx1,o=(e.y1-e.cy1)*t;return Math.hypot(n,o)>0?Math.atan2(o,n):Math.atan2((e.y1-e.y0)*t,e.x1-e.x0)}function On(e,t){let n=!1;for(let o=0;o<e.length-1&&!n;o++){let r=e[o],s=e[o+1];n=Math.max(r.x,s.x)>=t.minX&&Math.min(r.x,s.x)<=t.maxX&&Math.max(r.y,s.y)>=t.minY&&Math.min(r.y,s.y)<=t.maxY}return n}function _n(e,t){for(let n of e){let o=Math.min(n.x0,n.cx0,n.cx1,n.x1),r=Math.max(n.x0,n.cx0,n.cx1,n.x1),s=Math.min(n.y0,n.cy0,n.cy1,n.y1),a=Math.max(n.y0,n.cy0,n.cy1,n.y1);if(r>=t.minX&&o<=t.maxX&&a>=t.minY&&s<=t.maxY)return!0}return!1}var bt=new WeakMap;function Bn(e){let t=bt.get(e);if(!t){let n=[],o=new Map,r=e.paths??[];for(let s=0;s<r.length;s++){let[a,i,l]=ve(Qe(s,r.length),Ge,Oe);n.push(Le(a,i,l,.85)),o.has(r[s].name)||o.set(r[s].name,s)}t={pathColorByIndex:n,pathIndexByName:o},bt.set(e,t)}return t}var gt=new WeakMap,Tn=new Map;function Pn(e){let t=gt.get(e);if(!t){t=new Map;for(let[n,o]of(e.paths??[]).entries())for(let r of new Set(o.nodeIds)){let s=t.get(r);s?s.push(n):t.set(r,[n])}gt.set(e,t)}return t}function jo(e){let{nodePositions:t,graph:n,nodeById:o,colorScheme:r,contigThickness:s,connectorThickness:a,drawPaths:i,nodeWidth:l="uniform",highlight:f,axis:d,linearLayout:u,viewportBounds:c,referenceRamp:m,deletions:p,hiddenEdges:h,version:g=0}=e,b=l==="depth"?qe(n):0,y=d.scaleX,N=Se(d),w=mt(t,n,d,p,g),M=[],R=new Map,L=[],G=new Map,I=[],V=new Map,ne={...In(n),referenceRamp:m},q=new Map;if(r==="rainbow")for(let x=0;x<n.nodes.length;x++)q.set(n.nodes[x].id,x);let P=n.paths?.length??0,{pathColorByIndex:k,pathIndexByName:J}=Bn(n),Z=x=>k[J.get(x)??-1]??ht,$=i&&P>1?Pn(n):Tn,me=y>(u?1:xn);for(let x=0;x<n.edges.length;x++){let v=n.edges[x],O=t[v.from],H=t[v.to],_=w.get(x);if(!O?.length||!H?.length||!_||h?.has(x))continue;let D=v.pathIds?.length??0,z=p?.get(x)!==void 0,W=f?.edgeIndexes.has(x)??!1,X=a/2*(z?fn:1)*(W?mn:1),Q=i&&D>0,se=z?dn:un,oe=f?W?pn:de(se,Ae):se,he=(ye,xe,B,ce)=>{let Y=ye===0&&xe===0?_:dt(_,ye,xe);if(!(c&&!_n(Y,c))){if(z)for(let le of ut(Y,hn/y))I.push({curves:le,thickness:X,color:B});else I.push({curves:Y,thickness:X,color:B});if(me&&ce!==void 0){let le=Y[Y.length-1];L.push({x:le.x1,y:le.y1,angle:Gn(le,N),size:yn,color:ce})}}},be=I.length,ae=L.length;if(!Q)he(0,0,oe,oe);else{let ye=ft(O,H,D,d),xe=Math.floor((D-1)/2);for(let B=0;B<D;B++){let ce=ye[B],Y=Z(v.pathIds[B]);he(ce.x,ce.y,f&&v.pathIds[B]!==f.name?de(Y,Ae):Y,B===xe?oe:void 0)}}let ge=I.length-be;ge>0&&V.set(x,{start:be,count:ge});let ie=L.length-ae;ie>0&&G.set(x,{start:ae,count:ie})}for(let[x,v]of Object.entries(t)){let O=o.get(x);if(!O||c&&!On(v,c))continue;let H=kn(O,q.get(x)??0,r,ne),_=f!==void 0&&!f.nodeIds.has(x),D=_?de(H,Ae):H,re=Je(O,s,l,b),z=re/2,W=M.length,X=$.get(x),Q=re/P,se=v.length>=2;if(se&&X?.length&&Q>=bn){let he=Mn(v,N),be=1/Math.max(y,gn);for(let ae of X){let ge=(ae-(P-1)/2)*Q*be,ie=k[ae]??ht;M.push({points:Rn(v,he,ge,N),thickness:Q/2,color:_?de(ie,Ae):ie})}}else se&&M.push({points:v,thickness:z,color:D});let oe=M.length-W;oe>0&&R.set(x,{start:W,count:oe})}return{nodeStrokes:M,nodeStrokeRuns:R,arrows:L,arrowRuns:G,edgeCurves:I,edgeCurveRuns:V}}function qo(e){return ue(e)?yt(e):void 0}function yt(e){return{sample:Re(e.stable.refName),haplotype:je(e.stable.refName),refName:Ke(e.stable.refName),start:e.stable.start,end:e.stable.start+e.length}}function $n(e,t){let n=[...e].sort((s,a)=>s.start-a.start),o,r;for(let s of n)r=r&&s.start-r.end<=t?{start:r.start,end:Math.max(r.end,s.end)}:{start:s.start,end:s.end},(!o||r.end-r.start>o.end-o.start)&&(o=r);return o}function Hn(e){return`${e.haplotype??e.sample}\0${e.refName}`}function Jo(e,{maxGap:t=1/0}={}){let n=new Map;for(let r of e.nodes)if(ue(r)){let s=yt(r),a=Hn(s),i=n.get(a);i?(i.spans.push({start:s.start,end:s.end}),i.rank=Math.min(i.rank,r.stable.rank)):n.set(a,{sample:s.sample,haplotype:s.haplotype,refName:s.refName,rank:r.stable.rank,spans:[{start:s.start,end:s.end}]})}let o=new Map;for(let r of n.values()){let s=$n(r.spans,t);if(s){let a={sample:r.sample,haplotype:r.haplotype,refName:r.refName,start:s.start,end:s.end,rank:r.rank,nodeCount:r.spans.length},i=r.haplotype??r.sample,l=o.get(i);(!l||a.nodeCount>l.nodeCount)&&o.set(i,a)}}return[...o.values()].sort((r,s)=>+(r.rank!==0)-+(s.rank!==0)||r.sample.localeCompare(s.sample)||(r.haplotype??"").localeCompare(s.haplotype??""))}function Dn(e,t){return(t.haplotype===void 0?void 0:e(t.haplotype))??e(t.sample)}function Zo(e,t){return e.flatMap(n=>{let o=Dn(t,n);return o===void 0?[]:[{...n,sample:o}]})}function Qo(e){return`${e.refName}:${e.start+1}-${e.end}`}function De(e){return`${e.refName}:${(e.start+1).toLocaleString()}-${e.end.toLocaleString()}`}var xt=ee(Me(),1),Mt=(0,T.createSvgIcon)((0,xt.jsx)("path",{d:"M9.01 14H2v2h7.01v3L13 15l-3.99-4zm5.98-1v-3H22V8h-7.01V5L11 9z"}),"CompareArrows");var Rt=ee(Me(),1),Nt=(0,T.createSvgIcon)((0,Rt.jsx)("path",{d:"M17 5h-2V3h2zm-2 16h2v-2.59L19.59 21 21 19.59 18.41 17H21v-2h-6zm4-12h2V7h-2zm0 4h2v-2h-2zm-8 8h2v-2h-2zM7 5h2V3H7zM3 17h2v-2H3zm2 4v-2H3c0 1.1.9 2 2 2M19 3v2h2c0-1.1-.9-2-2-2m-8 2h2V3h-2zM3 9h2V7H3zm4 12h2v-2H7zm-4-8h2v-2H3zm0-8h2V3c-1.1 0-2 .9-2 2"}),"HighlightAlt");var wt=ee(Me(),1),ze=(0,T.createSvgIcon)((0,wt.jsx)("path",{d:"M3 16h5v-2H3zm6.5 0h5v-2h-5zm6.5 0h5v-2h-5zM3 20h2v-2H3zm4 0h2v-2H7zm4 0h2v-2h-2zm4 0h2v-2h-2zm4 0h2v-2h-2zM3 12h8v-2H3zm10 0h8v-2h-8zM3 4v4h18V4z"}),"LineStyle");var zn="Linear genome view",Wn="Linear synteny view",Xn="No synteny track in this session aligns these assemblies";function St({label:e,icon:t,entries:n,entryLabel:o,onSelect:r,disabledHelpText:s,nameTheOnlyEntry:a=!0}){let[i]=n,l=s?[{label:e,icon:t,disabled:!0,disabledHelpText:s,onClick:()=>{}}]:[];return n.length===0?l:n.length===1&&i?[{label:a?`${e} \u2014 ${o(i)}`:e,icon:t,onClick:r(i)}]:[{label:e,icon:t,type:"subMenu",subMenu:n.map(f=>({label:o(f),onClick:r(f)}))}]}function dr({contributors:e,syntenyTracks:t,onShowLinear:n,onShowSynteny:o}){let r=t[0]?.coverage??e.length;return[...St({label:zn,icon:ze,entries:e,entryLabel:s=>`${s.sample} ${De(s)}`,onSelect:s=>()=>{n({location:s,assembly:s.sample})}}),...e.length>=2?St({label:`${Wn} (${r} assemblies)`,icon:Mt,entries:t,entryLabel:s=>s.coverage<r?`${s.name} (${s.coverage} of ${r})`:s.name,nameTheOnlyEntry:!1,disabledHelpText:Xn,onSelect:s=>()=>{o(s.trackId)}}):[]]}function fr({own:e,reference:t,highlight:n,onShowLinear:o,onHighlight:r}){let s=[e?{label:`Open in ${e.assembly} \u2014 ${De(e.location)}`,target:e}:void 0,t&&t.assembly!==e?.assembly?{label:`Open in ${t.assembly} \u2014 around this node`,target:t}:void 0].filter(a=>a!==void 0);return[...r&&n?[{label:`Highlight in ${n.assembly}`,icon:Nt,onClick:()=>{r(n)}}]:[],...s.map(({label:a,target:i})=>({label:a,icon:ze,onClick:()=>{o(i)}}))]}var Fn=40;function te(e){return e>=1e4?`${(e/1e3).toFixed(0)} kb`:e>=1e3?`${(e/1e3).toFixed(1)} kb`:`${e} bp`}function jn(e,t){let n=te(e),o=te(t),r=o.slice(o.indexOf(" "));return n.endsWith(r)?`${n.slice(0,-r.length)}\u2013${o}`:`${n}\u2013${o}`}function Lt(e){return e>=Ve?"\u22652.1B routes":e>=1e5?`${(e/1e3).toFixed(0)}k routes`:`${e} routes`}function br(e){let t=Kn(e);return e.partial?{...t,label:`${t.label}, partial`}:t}function Kn(e){let t=e.end-e.start,{shortestAlleleLength:n,longestAlleleLength:o,pathCount:r,segmentCount:s,inversion:a}=e,i=jn(n,o);if(s>=Fn)return{kind:"superbubble",label:`${i} superbubble, ${s} segments, ${Lt(r)}${a?", inv":""}`};if(a)return{kind:"inversion",label:`${te(o)} inv`};if(r>=8&&o>5*Math.max(n,1))return{kind:"repeat",label:`${i} repeat array, ${Lt(r)}`};let l=r>2?`, ${r} alleles`:"";return n===o&&n===t?t<=1?{kind:"snp",label:"SNP"}:{kind:"substitution",label:`${te(t)} sub`}:t===0||n===t?{kind:"insertion",label:`\u2264${te(o-t)} ins${l}`}:o===t?{kind:"deletion",label:`${te(t-n)} del${l}`}:{kind:"complex",label:`${te(t)} ref \u2192 ${i}, ${r} alleles`}}var gr={snp:"#5b6b7a",substitution:"#5b6b7a",insertion:"#2f8fd6",deletion:"#c94040",inversion:"#e07b00",repeat:"#8e3fbf",superbubble:"#8e3fbf",complex:"#8e3fbf"},yr={snp:"SNP",substitution:"substitution",insertion:"insertion",deletion:"deletion",inversion:"inversion",repeat:"repeat array",superbubble:"superbubble",complex:"site"};function xr(e){return e.segments.split(",").filter(Boolean)}function Nr(e){let t=new Map,n=new Map,o=(c,m,p)=>{let h=c.get(m);h?h.push(p):c.set(m,[p])};for(let c of e.edges)o(t,c.from,c.to),o(n,c.to,c.from);let r=(c,m)=>c!==m&&t.get(c)?.length===1&&n.get(m)?.length===1,s=new Map,a=new Map;for(let c of e.nodes){let m=n.get(c.id);if(s.has(c.id)||m?.length===1&&r(m[0],c.id))continue;let p=[c.id];for(;;){let h=t.get(p.at(-1))?.[0];if(h===void 0||s.has(h)||!r(p.at(-1),h))break;p.push(h)}for(let h of p)s.set(h,c.id);p.length>1&&a.set(c.id,p)}for(let c of e.nodes)s.has(c.id)||s.set(c.id,c.id);let i=new Map(e.nodes.map(c=>[c.id,c])),l=[];for(let c of e.nodes){if(s.get(c.id)!==c.id)continue;let m=a.get(c.id);if(!m){l.push(c);continue}let p=m.map(b=>i.get(b)),h=p.filter(S),g=h.length?h.reduce((b,y)=>b.stable.start<=y.stable.start?b:y):p[0];l.push({id:c.id,name:c.name,length:p.reduce((b,y)=>b+y.length,0),depth:c.depth,stable:g.stable})}let f=new Set;for(let c of a.values())for(let m=1;m<c.length;m++)f.add(`${c[m-1]}>${c[m]}`);let d=new Set,u=[];for(let c of e.edges){let m=`${s.get(c.from)}>${s.get(c.to)}`;f.has(`${c.from}>${c.to}`)||d.has(m)||(d.add(m),u.push({from:s.get(c.from),to:s.get(c.to)}))}return{graph:{...e,nodes:l,edges:u,paths:void 0,pathVisits:void 0},runs:a}}function wr(e,t,n){let o={...e};for(let[r,s]of t){let a=e[r];if(!a?.length)continue;delete o[r];let i=Xe(a),l=i.at(-1),f=s.map(c=>Math.max(n(c),0)),d=f.reduce((c,m)=>c+m,0)||s.length,u=0;s.forEach((c,m)=>{let p=d?f[m]/d*l:l/s.length,h=m===s.length-1?l:u+p;o[c]=vt(a,i,u,h),u=h})}return o}function Sr(e,t,n){if(e.length===0)return[];let o=Xe(e),r=o.at(-1);return vt(e,o,t*r,n*r)}function Ar(e){let t=Xe(e);return We(e,t,t.at(-1)/2)}function Xe(e){let t=[0];for(let n=1;n<e.length;n++)t.push(t[n-1]+Math.hypot(e[n].x-e[n-1].x,e[n].y-e[n-1].y));return t}function We(e,t,n){if(n<=0)return{...e[0]};let o=1;for(;o<t.length&&t[o]<n;)o++;if(o>=t.length)return{...e.at(-1)};let r=t[o]-t[o-1],s=r>0?(n-t[o-1])/r:0,a=e[o-1],i=e[o];return{x:a.x+(i.x-a.x)*s,y:a.y+(i.y-a.y)*s}}function vt(e,t,n,o){let r=[We(e,t,n)];for(let s=0;s<e.length;s++)t[s]>n&&t[s]<o&&r.push({...e[s]});return r.push(We(e,t,o)),r}function Ct(e){return e.sample??Re(e.name)}function Un(e){return e.haplotype!==void 0&&e.sample!==void 0?`${e.sample}#${e.haplotype}`:Ct(e)}function Vn(e,t,n,o=!0){if(!n||!o)return{ids:e,complete:!0};let r=-1,s=-1,a=-1/0,i=1/0;if(e.forEach((f,d)=>{let u=t.get(f);u&&(u.end<=n.start&&u.end>a&&(a=u.end,r=d),u.start>=n.end&&u.start<i&&(i=u.start,s=d))}),r<0||s<0)return{ids:e,complete:!1};let l=e.slice(Math.min(r,s)+1,Math.max(r,s));return{ids:r<s?l:l.reverse(),complete:!0}}function Et(e,t,n){let o=e.paths??[],r=o.find(p=>ke(p.name).name===e.referencePath)??o[0];if(!r||o.length<2)return;let s=new Map(e.nodes.map(p=>[p.id,p.length])),a=new Set(r.nodeIds),i=e.anchorPaths?.find(p=>p.name===ke(r.name).name)?.start??0,l=t&&t.end>t.start?t:void 0,f=new Map,d=i;for(let p of r.nodeIds){let h=s.get(p)??0;f.has(p)||f.set(p,{start:d,end:d+h}),d+=h}let u=l===void 0||[...f.values()].some(p=>p.end<=l.start)&&[...f.values()].some(p=>p.start>=l.end),c=p=>{let{ids:h,complete:g}=Vn(p.nodeIds,f,l,u),b=[],y=0,N=0;for(let w of h){let M=s.get(w)??0,R=a.has(w),L=b.at(-1);L?.onReference===R?L.bp+=M:b.push({start:y,bp:M,onReference:R}),y+=M,R||(N+=M)}return{name:p.name,label:Un(p),sample:Ct(p),bp:y,offReferenceBp:N,complete:g,runs:b}};return{origin:l?l.start:i,unit:n,reference:c(r),rows:o.filter(p=>p!==r).map(c).sort((p,h)=>Number(h.complete)-Number(p.complete)||h.bp-p.bp||p.label.localeCompare(h.label))}}var qn=1.3;function Jn(e){let t=e.reference.bp;for(let n of e.rows)t=Math.max(t,n.bp);return{maxX:e.origin+t*qn,maxY:e.rows.length*20}}function It(e,t){let n=F(e),o=Et(e,t);if(n.length===0||!o)return;let r=j(n),s=[{label:o.reference.label,y:0},...o.rows.map((a,i)=>({label:a.label,y:(i+1)*20}))];return{nodePositions:r,rowLabels:s,referenceAxis:!0,pixelRows:!0,extent:Jn(o)}}function Ce(e){let t=e.split("#"),n=t.length>=2?Number(t[1]):Number.NaN;return{sample:t[0]??e,haplotype:Number.isFinite(n)?n:void 0}}function Zn(e,t,n,o){let r=[],s=[],a=[e];for(o.add(e);a.length>0;){let i=a.pop(),l=t.get(i);if(l){r.push(l);for(let f of n.get(i)??[]){let d=t.get(f);d&&(d.stable.rank===0?s.push(d):o.has(f)||(o.add(f),a.push(f)))}}}return{members:r,anchors:s}}function Qn(e){if(new Set(e.map(i=>i.stable.refName)).size!==1||e.length<2)return;let n=[...e].sort((i,l)=>i.stable.start-l.stable.start),o=n[0],r=n.at(-1),s=o.stable.start+o.length,a=r.stable.start;return a>=s?{start:s,end:a,entry:o}:void 0}function eo(e,t,n){let o=new Map(e.map(a=>[a.id,a])),r=new Map,s=[];for(let a of n.get(t.id)??[])o.has(a)&&(r.set(a,0),s.push(a));if(s.length===0)for(let a of e)r.set(a.id,0),s.push(a.id);for(let a of s){let i=r.get(a)+o.get(a).length;for(let l of n.get(a)??[])if(o.has(l)){let f=r.get(l);(f===void 0||i<f)&&(r.set(l,i),s.push(l))}}return r}function to(e,t,n){let o=eo(e,t,n),r=[...e].sort((l,f)=>o.get(l.id)-o.get(f.id)),s=new Map(r.map((l,f)=>[l.id,f])),a=new Map(e.map(l=>[l.id,l])),i=new Map;for(let[l,f]of r.entries()){let d=0;for(let u of n.get(f.id)??[]){let c=a.get(u);c&&s.get(u)<l&&(d=Math.max(d,i.get(u)+c.length))}i.set(f.id,d)}return{offsets:i,ordered:r}}function Gt(e){let t=new Map(e.nodes.filter(ue).map(s=>[s.id,s])),n=fe(e),o=new Set,r=[];for(let s of t.values())if(s.stable.rank!==0&&!o.has(s.id)){let{members:a,anchors:i}=Zn(s.id,t,n,o),l=Qn(i);if(l){let{offsets:f,ordered:d}=to(a,l.entry,n);r.push({start:l.start,refSpan:l.end-l.start,nodeIds:d.map(u=>u.id),nodeOffsets:d.map(u=>f.get(u.id)),pathLength:d.reduce((u,c)=>Math.max(u,f.get(c.id)+c.length),0)})}}return r.sort((s,a)=>s.start-a.start)}var no=1,oo=.015;function Ee({graph:e,span:t,rowY:n,positions:o}){let r=t*oo,s=Gt(e),a=new Map(e.nodes.map(d=>[d.id,d])),i=[];for(let d of s){let u=d.refSpan-d.pathLength;u>=no&&i.push({nodeIds:d.nodeIds,bp:u});let c=Math.max(d.refSpan,r),m=d.pathLength>0?c/d.pathLength:0;d.nodeIds.forEach((p,h)=>{let g=a.get(p);if(g){let b=d.nodeOffsets[h],y=c/d.nodeIds.length,N=M=>d.start+M*m,w=n(g);o[p]=m?[{x:N(b),y:w},{x:N(b+g.length),y:w}]:[{x:d.start+h*y,y:w},{x:d.start+(h+1)*y,y:w}]}})}let l=fe(e),f=Object.keys(o);for(let d of f){let u=o[d].at(-1).x;for(let c of l.get(d)??[]){let m=a.get(c);if(m&&!(c in o)){let p=n(m);o[c]=[{x:u,y:p},{x:u+r,y:p}],f.push(c)}}}return i}function ro(e){let t=new Set;for(let n of e.nodes)n.stable&&t.add(n.stable.rank);return new Map([...t].sort((n,o)=>n-o).map((n,o)=>[n,o]))}function Ot(e,t){let n=F(e);if(n.length===0)return;let o=we(n,t),r=ro(e),s=j(n),a=Ee({graph:e,span:o,rowY:l=>(l.stable?r.get(l.stable.rank)??r.size:r.size)*20,positions:s}),i=[...r].map(([l,f])=>({label:l===0?"Reference (rank 0)":`Rank ${l}`,y:f*20}));return{nodePositions:s,rowLabels:i,referenceAxis:!0,pixelRows:!0,alleleDeletions:a}}var so=12,Ye=20;function _t(e){return 10+8*Math.log2(1+e.length)}function K(e,t){return e<t?-1:e>t?1:0}function Tt(e,t){return K(e.at,t.at)||K(e.side,t.side)||K(e.hops,t.hops)}var Bt={at:1/0,side:0,hops:0};function ao(e){let t=new Map(e.nodes.map(o=>[o.id,o])),n=lo(e);return e.nodes.map(o=>o.id).sort((o,r)=>Tt(n.get(o)??Bt,n.get(r)??Bt)||K(t.get(o).name,t.get(r).name)||K(o,r))}function io(e,t){let n=new Set(e.nodes.map(d=>d.id)),o=new Map(t.map(d=>[d.id,d.stable.start])),r=new Map,s=new Map;t.forEach((d,u)=>{s.set(d.id,t[u-1]?.id),r.set(d.id,t[u+1]?.id)});let a=t[0]?.id,i=(d,u)=>{let c=r.get(d);r.set(d,u),s.set(u,d),r.set(u,c),c!==void 0&&s.set(c,u)},l=(d,u)=>{let c=s.get(d);c===void 0?(a=u,s.set(u,void 0),r.set(u,d),s.set(d,u)):i(c,u)};for(let d of e.paths??[]){let u=0,c=0,m;for(let b of d.nodeIds){let y=o.get(b);y!==void 0&&(m!==void 0&&y!==m&&(y>m?u++:c++),m=y)}let p=c>u?[...d.nodeIds].reverse():d.nodeIds,h,g=new Set;for(let b of p)if(r.has(b)){if(h===void 0)for(let y of g)l(b,y);h=b}else n.has(b)&&(h===void 0?g.add(b):(i(h,b),h=b))}let f=[];for(let d=a;d!==void 0;d=r.get(d))f.push(d);return f}function co(e,t){let n=[...t.entries()].sort(([a,i],[l,f])=>Tt(i,f)||K(a,l)).map(([a])=>a),o=n.length;for(let a of n){let i=t.get(a);for(let l of e.get(a)??[])t.has(l)||(t.set(l,{at:i.at,side:1,hops:i.hops+1}),n.push(l))}let r=new Set(n.slice(o)),s=new Set;for(let a of r){if(s.has(a))continue;let{at:i}=t.get(a),l=[a];s.add(a);let f=!0;for(let d of l){let{hops:u}=t.get(d),c=!0,m=!1;for(let p of e.get(d)??[]){let h=t.get(p);h.at===i&&r.has(p)?(c&&=h.hops<=u,s.has(p)||(s.add(p),l.push(p))):h.at!==i&&(m||=h.at<i,f&&=h.at<i)}f&&=!c||m}if(f)for(let d of l){let u=t.get(d);t.set(d,{...u,side:-1,hops:-u.hops})}}}function lo(e){let t=new Set(e.nodes.map(s=>s.id)),n=new Map;for(let s of e.edges)!t.has(s.from)||!t.has(s.to)||((n.get(s.from)??n.set(s.from,[]).get(s.from)).push(s.to),(n.get(s.to)??n.set(s.to,[]).get(s.to)).push(s.from));let o=e.nodes.filter(S).sort((s,a)=>K(s.stable.start,a.stable.start)||K(s.name,a.name)),r=new Map;return io(e,o).forEach((s,a)=>{r.set(s,{at:a,side:0,hops:0})}),co(n,r),r}function uo(e){let t=new Map(e.nodes.map(u=>[u.id,u])),n=ao(e),o=new Map(n.map((u,c)=>[u,c])),r=u=>S(t.get(u)),s=new Map(n.map(u=>[u,[]])),a=new Map(n.map(u=>[u,[]])),i=(u,c)=>{s.get(c).push(u),a.get(u).push(c)};for(let u of e.edges)u.from===u.to||!o.has(u.from)||!o.has(u.to)||(o.get(u.from)<o.get(u.to)?i(u.from,u.to):i(u.to,u.from));let l=n.filter(r);for(let u=1;u<l.length;u++)i(l[u-1],l[u]);let f=new Map;for(let u of n){let c=0;for(let m of s.get(u))c=Math.max(c,f.get(m)+1);f.set(u,c)}for(let u=n.length-1;u>=0;u--){let c=n[u],m=a.get(c);if(r(c)||m.length===0)continue;let p=1/0;for(let b of m)p=Math.min(p,f.get(b));let h=f.get(c),g=Math.max(h,p-1);f.set(c,Math.floor((h+g)/2))}let d=[];for(let u of n)(d[f.get(u)]??=[]).push(u);return{layers:d,layerOf:f,preds:s}}function Pt(e){if(!e.nodes.some(S))return;let t=new Map(e.nodes.map(u=>[u.id,u])),n=u=>S(t.get(u)),{layers:o,layerOf:r,preds:s}=uo(e),a=o.map(u=>{let c=0;for(let m of u)c=Math.max(c,_t(t.get(m)));return c}),i=[],l=0;for(let u=0;u<o.length;u++)i[u]=l,l+=a[u]+so;let f=new Map;for(let u of o){let c=[];for(let p of u){if(n(p)){f.set(p,0);continue}let h=s.get(p).filter(b=>f.has(b)),g=0;for(let b of h)g+=f.get(b)/h.length;c.push({id:p,ideal:g===0?Ye:g})}c.sort((p,h)=>p.ideal-h.ideal);let m=new Set([0]);for(let{id:p,ideal:h}of c){let g=Math.round(h/Ye);g===0&&(g=h>=0?1:-1);for(let b=1;m.has(g);b++)m.has(g+b)?m.has(g-b)||(g-=b):g+=b;m.add(g),f.set(p,g*Ye)}}let d={};for(let u of e.nodes){let c=r.get(u.id),m=_t(u),p=i[c]+a[c]/2,h=f.get(u.id);d[u.id]=[{x:p-m/2,y:h},{x:p+m/2,y:h}]}return{nodePositions:d,referenceAxis:!1,pixelRows:!0}}function fo(e,t){let n=new Map;for(let r of e.nodes)if(Ne(r)){let{sample:s}=Ce(r.stable.refName);n.set(s,(n.get(s)??0)+r.length)}let o=new Map(t.map((r,s)=>[r,s]));return[...n.keys()].sort((r,s)=>(o.get(r)??1/0)-(o.get(s)??1/0)||n.get(s)-n.get(r)||r.localeCompare(s))}function $t(e,t,n=[]){let o=F(e),r=fo(e,n);if(o.length===0||r.length===0)return;let s=we(o,t),a=new Map(r.map((c,m)=>[c,m+1])),i=j(o),l=r.length+1,f=Ee({graph:e,span:s,rowY:c=>{let m=c.stable;return((m?a.get(Ce(m.refName).sample):void 0)??l)*20},positions:i}),u=[{label:Ce(o[0].stable.refName).sample,y:0},...r.map(c=>({label:c,y:a.get(c)*20}))];return{nodePositions:i,rowLabels:u,sampleRows:r,referenceAxis:!0,pixelRows:!0,alleleDeletions:f}}function Ht(e){let t=F(e);if(t.length!==0)return{nodePositions:j(t),referenceAxis:!0,pixelRows:!0}}var po="Force-directed layout",U=e=>e.nodes.some(S),Dt=e=>U(e)&&(e.paths?.length??0)>1,zt=e=>U(e)&&e.nodes.some(Ne),Fe=[{value:"auto",label:"Anchored",description:"x is reference bp, one row per stable rank. Needs rGFA tags or a reference path.",run:Ot,available:U,drawsLocally:U},{value:"samplerows",label:"Sample rows",description:"x is reference bp, one row per contributing assembly. Needs rGFA tags or a reference path.",run:$t,available:zt,drawsLocally:zt},{value:"walkrows",label:"Walk rows",description:"x is each walk's own bp: one bar per haplotype, sequence the reference also carries in blue and sequence it does not in purple, so a repeat expansion reads as bar length. Needs W or P lines.",run:It,available:Dt,drawsLocally:Dt},{value:"ordered",label:"Ordered",description:"x is reference order, not bp: every node gets room, bubbles read as lenses. Needs rGFA tags or a reference path.",run:Pt,available:U,drawsLocally:U},{value:"variants",label:"Variant map",description:"The reference as a line with one typed glyph per bubble, from the bubble index or from the graph itself: SNP, indel, deletion, inversion, repeat array. Click a glyph to open the graph inside it.",run:Ht,available:U,drawsLocally:U},{value:"force",label:po,description:"OGDF FMMM, via the external Bandage engine.",run:()=>{},available:()=>!0,drawsLocally:()=>!1}],as=Fe.map(e=>e.value);function is(e,t){return!mo(e).drawsLocally(t)}function mo(e){return Fe.find(t=>t.value===e)??Fe[0]}function ho(e,t){return Math.abs(t-e)<=.1*Math.max(e,t)}function bo(e,t){let n=e.length,o=t.length,r=Array.from({length:n+1},()=>new Array(o+1).fill(0)),s=Array.from({length:n+1},()=>new Array(o+1).fill(!1));for(let i=n-1;i>=0;i--)for(let l=o-1;l>=0;l--){let f=Math.abs(e[i]-t[l])+r[i+1][l+1],d=n-i>o-l?r[i+1][l]:1/0,u=o-l>n-i?r[i][l+1]:1/0;r[i][l]=Math.min(f,d,u),s[i][l]=r[i][l]===f}let a=new Array(n).fill(void 0);for(let i=0,l=0;i<n&&l<o;)s[i][l]?a[i++]=l++:n-i>o-l?i++:l++;return a}function Wt(e,t){return e.map((n,o)=>({item:n,i:o})).sort((n,o)=>t(n.item)-t(o.item))}var Xt=e=>e.spanningReads!==0;function go(e,t){let n=new Map,o=new Set,r=Wt(e,a=>a.bp),s=[[r.filter(a=>a.item.complete),t.filter(Xt)],[r,t]];for(let[a,i]of s){let l=a.filter(d=>!n.has(d.i)),f=Wt(i.filter(d=>!o.has(d)),d=>d.bp);bo(l.map(d=>d.item.bp),f.map(d=>d.item.bp)).forEach((d,u)=>{if(d!==void 0){let c=l[u],m=f[d].item;o.add(m),n.set(c.i,{...m,agrees:c.item.complete&&Xt(m)?ho(c.item.bp,m.bp):void 0})}})}return n}function ls(e,t){if(!t)return e;let n=new Map,o=new Map;for(let r of e)o.set(r.sample,[...o.get(r.sample)??[],r]);for(let[r,s]of o){let a=t[r];if(a)for(let[i,l]of go(s,a))n.set(s[i],l)}return e.map(r=>({...r,call:n.get(r)}))}var Yt=ee(Me(),1),fs=(0,T.createSvgIcon)((0,Yt.jsx)("path",{d:"M19.14 12.94c.04-.3.06-.61.06-.94 0-.32-.02-.64-.07-.94l2.03-1.58c.18-.14.23-.41.12-.61l-1.92-3.32c-.12-.22-.37-.29-.59-.22l-2.39.96c-.5-.38-1.03-.7-1.62-.94l-.36-2.54c-.04-.24-.24-.41-.48-.41h-3.84c-.24 0-.43.17-.47.41l-.36 2.54c-.59.24-1.13.57-1.62.94l-2.39-.96c-.22-.08-.47 0-.59.22L2.74 8.87c-.12.21-.08.47.12.61l2.03 1.58c-.05.3-.09.63-.09.94s.02.64.07.94l-2.03 1.58c-.18.14-.23.41-.12.61l1.92 3.32c.12.22.37.29.59.22l2.39-.96c.5.38 1.03.7 1.62.94l.36 2.54c.05.24.24.41.48.41h3.84c.24 0 .44-.17.47-.41l.36-2.54c.59-.24 1.13-.56 1.62-.94l2.39.96c.22.08.47 0 .59-.22l1.92-3.32c.12-.22.07-.47-.12-.61zM12 15.6c-1.98 0-3.6-1.62-3.6-3.6s1.62-3.6 3.6-3.6 3.6 1.62 3.6 3.6-1.62 3.6-3.6 3.6"}),"Settings");export{T as a,_e as b,Yn as c,te as d,br as e,gr as f,yr as g,xr as h,vo as i,Co as j,Eo as k,dt as l,Se as m,ft as n,ao as o,Oo as p,_o as q,Nr as r,wr as s,Sr as t,Ar as u,fe as v,Kt as w,Et as x,Jn as y,Fe as z,as as A,is as B,mo as C,Ro as D,mt as E,Ln as F,Fo as G,jo as H,ls as I,qo as J,Jo as K,Dn as L,Zo as M,Qo as N,De as O,dr as P,fr as Q,fs as R};
|
|
2
|
-
//# sourceMappingURL=chunk-A4ZWFDQY.js.map
|
|
File without changes
|
|
File without changes
|