jbrowse-plugin-graphgenomeviewer 7.1.11 → 7.1.13
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/dist/chunks/GbzBaseSyntenyAdapter-NB6WBBZH.js +2 -0
- package/dist/chunks/GbzBaseSyntenyAdapter-NB6WBBZH.js.map +7 -0
- package/dist/chunks/WalkTabixSyntenyAdapter-WBHOZLAN.js +2 -0
- package/dist/chunks/WalkTabixSyntenyAdapter-WBHOZLAN.js.map +7 -0
- package/dist/chunks/chunk-JLGPQO5L.js +4 -0
- package/dist/chunks/{chunk-U4U5ZOCH.js.map → chunk-JLGPQO5L.js.map} +4 -4
- package/dist/chunks/{chunk-OBQFV4NL.js → chunk-LXCMWL7B.js} +2 -2
- package/dist/chunks/chunk-M2D7NUOY.js +2 -0
- package/dist/chunks/{chunk-T4HOC6O3.js.map → chunk-M2D7NUOY.js.map} +4 -4
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js +3 -3
- package/dist/jbrowse-plugin-graphgenomeviewer.esm.js.map +2 -2
- package/package.json +1 -1
- package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.test.ts +2 -4
- package/src/GbzBaseSyntenyAdapter/GbzBaseSyntenyAdapter.ts +9 -8
- package/src/RgfaTabixAdapter/test_data/walks3_lanepairs.GRCh38.walks.bed.gz +0 -0
- package/src/RgfaTabixAdapter/test_data/walks3_lanepairs.GRCh38.walks.bed.gz.tbi +0 -0
- package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.test.ts +128 -3
- package/src/WalkTabixSyntenyAdapter/WalkTabixSyntenyAdapter.ts +4 -10
- package/src/WalkTabixSyntenyAdapter/walkLanes.ts +60 -0
- package/src/synteny/clipFeatureToRegion.test.ts +23 -0
- package/src/synteny/clipFeatureToRegion.ts +4 -1
- package/src/synteny/laneZoomNotice.test.ts +55 -0
- package/src/synteny/laneZoomNotice.ts +34 -0
- package/src/version.ts +1 -1
- package/dist/chunks/GbzBaseSyntenyAdapter-2MA3I6BM.js +0 -2
- package/dist/chunks/GbzBaseSyntenyAdapter-2MA3I6BM.js.map +0 -7
- package/dist/chunks/WalkTabixSyntenyAdapter-AIC3W7FL.js +0 -2
- package/dist/chunks/WalkTabixSyntenyAdapter-AIC3W7FL.js.map +0 -7
- package/dist/chunks/chunk-PJ43KEV6.js +0 -2
- package/dist/chunks/chunk-PJ43KEV6.js.map +0 -7
- package/dist/chunks/chunk-T4HOC6O3.js +0 -2
- package/dist/chunks/chunk-U4U5ZOCH.js +0 -4
- /package/dist/chunks/{chunk-OBQFV4NL.js.map → chunk-LXCMWL7B.js.map} +0 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["host:@jbrowse/core/Plugin", "../node_modules/.pnpm/@mui+icons-material@9.5.0_@mui+material@9.5.0_@emotion+react@11.14.0_@types+react@19.3._abf953b0c56c79ebdc461ec953894a27/node_modules/@mui/icons-material/BubbleChart.mjs", "host:@jbrowse/core/pluggableElementTypes/AdapterType", "../src/GbzBaseSyntenyAdapter/configSchema.ts", "../src/GbzBaseSyntenyAdapter/index.ts", "host:@jbrowse/core/pluggableElementTypes", "host:@jbrowse/core/data_adapters/dataAdapterCache", "../src/adapterImplementing.ts", "../src/GetGraphHaplotypes.ts", "../src/GetGraphReads.ts", "host:@jbrowse/core/util/librpc", "../src/GetSubgraph.ts", "../src/GraphAddTrackWorkflow/index.ts", "../src/GraphComputeLayout.ts", "host:@jbrowse/core/pluggableElementTypes/ViewType", "host:@jbrowse/core/util/withLaunchInput", "host:@jbrowse/core/pluggableElementTypes/models", "../src/GraphGenomeView/hoverHighlight.ts", "../node_modules/.pnpm/@mui+icons-material@9.5.0_@mui+material@9.5.0_@emotion+react@11.14.0_@types+react@19.3._abf953b0c56c79ebdc461ec953894a27/node_modules/@mui/icons-material/ContentCopy.mjs", "../node_modules/.pnpm/@mui+icons-material@9.5.0_@mui+material@9.5.0_@emotion+react@11.14.0_@types+react@19.3._abf953b0c56c79ebdc461ec953894a27/node_modules/@mui/icons-material/Hub.mjs", "../node_modules/.pnpm/@mui+icons-material@9.5.0_@mui+material@9.5.0_@emotion+react@11.14.0_@types+react@19.3._abf953b0c56c79ebdc461ec953894a27/node_modules/@mui/icons-material/Palette.mjs", "../node_modules/.pnpm/@mui+icons-material@9.5.0_@mui+material@9.5.0_@emotion+react@11.14.0_@types+react@19.3._abf953b0c56c79ebdc461ec953894a27/node_modules/@mui/icons-material/PhotoCamera.mjs", "../node_modules/.pnpm/@jbrowse+bandage-core@11.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-SOMZGDVS.js", "../node_modules/.pnpm/@jbrowse+bandage-core@11.0.0/node_modules/@jbrowse/bandage-core/dist/layout/trimToWindow.js", "../node_modules/.pnpm/@jbrowse+bandage-core@11.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-BIOKXS3M.js", "../src/GraphGenomeView/pane/keepInView.ts", "../node_modules/.pnpm/@jbrowse+bandage-core@11.0.0/node_modules/@jbrowse/bandage-core/dist/chunks/chunk-SI3BB4DO.js", "../src/GraphGenomeView/pane/tubeMapViews.ts", "../src/GraphGenomeView/pane/settingActions.ts", "host:@jbrowse/core/util/unzip", "../src/GraphGenomeView/gfaText.ts", "../src/GraphGenomeView/walkRowsCut.ts", "../src/GraphGenomeView/pane/loadActions.ts", "../src/hoverSync/lgvHover.ts", "../src/hoverSync/rowWalks.ts", "../src/GraphGenomeView/pane/renderingActions.ts", "../src/launchFromGraph/launchTracks.ts", "../node_modules/.pnpm/@mui+icons-material@9.5.0_@mui+material@9.5.0_@emotion+react@11.14.0_@types+react@19.3._abf953b0c56c79ebdc461ec953894a27/node_modules/@mui/icons-material/RocketLaunch.mjs", "../src/launchFromGraph/pushLaunchItem.ts", "../src/launchFromGraph/syntenyTracks.ts", "../src/GraphGenomeView/download.ts", "../src/GraphGenomeView/pane/launchActions.ts", "../src/GraphGenomeView/model.ts", "../src/GraphGenomeView/viewModel.ts", "../src/GraphGenomeView/index.ts", "../src/GraphTrack/index.ts", "../src/LaunchGraphGenomeView.ts", "host:@jbrowse/core/pluggableElementTypes/DisplayType", "host:@jbrowse/display-kit/trackHeightConfigSchemaFields", "../src/LinearGraphDisplay/configSchema.ts", "host:@jbrowse/core/svg/svgReady", "host:@jbrowse/display-kit/TrackHeightMixin", "host:@jbrowse/display-kit/plotMenu", "host:@jbrowse/render-core/displayPhase", "../src/LinearGraphDisplay/denseWindow.ts", "../src/LinearGraphDisplay/model.ts", "../src/LinearGraphDisplay/index.ts", "../src/MinigraphBubbleAdapter/configSchema.ts", "../src/MinigraphBubbleAdapter/index.ts", "../src/RgfaTabixAdapter/configSchema.ts", "../src/RgfaTabixAdapter/index.ts", "../src/WalkTabixSyntenyAdapter/configSchema.ts", "../src/WalkTabixSyntenyAdapter/index.ts", "../src/graphTrackDefaults/index.ts", "../src/hoverSync/graphViewHighlights.ts", "../src/hoverSync/GraphNodeHighlight.tsx", "../src/hoverSync/index.tsx", "../src/panSNAliases/index.ts", "../src/pluginName.ts", "../src/version.ts", "../src/index.ts"],
|
|
4
|
-
"sourcesContent": ["const host = JBrowseExports[\"@jbrowse/core/Plugin\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/Plugin\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon([/*#__PURE__*/_jsx(\"circle\", {\n cx: \"7.2\",\n cy: \"14.4\",\n r: \"3.2\"\n}, \"0\"), /*#__PURE__*/_jsx(\"circle\", {\n cx: \"14.8\",\n cy: \"18\",\n r: \"2\"\n}, \"1\"), /*#__PURE__*/_jsx(\"circle\", {\n cx: \"15.2\",\n cy: \"8.8\",\n r: \"4.8\"\n}, \"2\")], 'BubbleChart');", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/AdapterType\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes/AdapterType\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "import { GBZ_CUT_DEFAULTS } from '@jbrowse/bandage-core/gbzWindow'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport { splitUri } from '../locationName'\nimport { fileLocationSlot, tabixIndexSchema } from '../panSNTabix.ts'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config GbzBaseSyntenyAdapter\n * #trackType GraphTrack\n * #fileFormat synteny | gbz-base pangenome database | Haplotype alignments read from the graph at query time, no PAF conversion\n * Serves a pangenome graph stored as a gbz-base SQLite database (`.gbz.db`) as\n * haplotype-versus-reference alignments, the shape `MultiWaySyntenyDisplay`\n * draws as one lane per haplotype. A window on the reference is located on the\n * graph's reference path, every haplotype's walk through the nodes it covers\n * is recovered and named, and each haplotype becomes one alignment record with\n * a CIGAR, so the graph is read through HTTP range requests with no offline\n * conversion. Naming the walks takes the companion haplotype index that\n * `gbz-haplotype-index` writes; without it the graph cannot say which\n * haplotype a walk belongs to.\n *\n * Only the fine tier exists: a whole-chromosome view stays on a PIF's coarse\n * tier. A window of the anchor answers any two lanes' alignment, so the\n * multi-way display fetches each adjacent lane pair directly.\n *\n * #example\n * ```js\n * {\n * type: 'GbzBaseSyntenyAdapter',\n * uri: 'hprc-v2.gbz.db',\n * assemblyNames: ['hg38'],\n * assemblyNameToPanSN: { hg38: 'GRCh38#0' },\n * }\n * ```\n */\nconst GbzBaseSyntenyAdapter = ConfigurationSchema(\n 'GbzBaseSyntenyAdapter',\n {\n /**\n * #slot\n * The first entry is the anchor: the JBrowse assembly the graph's reference\n * sample is loaded as. A haplotype needs no entry: its lane draws on the\n * session assembly named or aliased by its PanSN prefix (`HG002.1` with the\n * alias `HG002#1`), or the one `assemblyNameToPanSN` maps to it. A further\n * entry names an assembly by its sample (`HG002`), which takes both of the\n * sample's lanes. A haplotype with no assembly is still a lane, labelled by\n * its PanSN prefix.\n */\n assemblyNames: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * The `.gbz.db` written by `gbz-base construct`; read by HTTP range\n * requests, so it can be large.\n */\n gbzDbLocation: fileLocationSlot('/path/to/graph.gbz.db'),\n /**\n * #slot\n * The haplotype index `gbz-haplotype-index` writes beside the graph\n * database, which names its walks. One with stray rows (the tool from\n * 0.2.0) lets a fetch for a chosen set of lanes walk only those\n * haplotypes. Empty means `graph.haplotype-index.db` beside\n * `graph.gbz.db` if there is one; otherwise the walks go unnamed.\n */\n haplotypeIndexLocation: fileLocationSlot(''),\n /**\n * #slot\n * Reads aligned to the graph as GAF, which the tube map layouts draw under\n * the haplotypes. Its segment names have to be the cut's: numeric node ids,\n * or `vg giraffe --named-coordinates` on a graph whose segments were\n * renamed or chopped. Empty means no reads.\n */\n readsLocation: fileLocationSlot(''),\n /**\n * #slot\n * The `tabix -p gaf` index of a bgzipped `readsLocation`, which fetches the\n * reads over each window's node ids. Empty reads the GAF whole, up to 50 MB.\n */\n readsIndex: tabixIndexSchema('GbzBaseReadsIndex'),\n /**\n * #slot\n * A tab-separated table of per-sample metadata, which the graph view's\n * walk rows group by (\"Group by...\"). Its header row names the columns\n * (`population`, `superpopulation`, ...), and its first column is the\n * walk's sample (`HG00097`) or haplotype (`HG00097#1`). Empty means no\n * grouping.\n */\n samplesTsvLocation: fileLocationSlot(''),\n /**\n * #slot\n * How the graph view's subgraph is extended past the nodes the reference\n * window touches. `contained` adds every top-level snarl with both\n * boundary nodes in the window, which is what brings back the bubbles a\n * reference-only walk leaves out; a haplotype still breaks into a new W\n * line wherever it leaves the window's nodes (a 60 kb C4 window on the\n * HPRC graph: 2,703 nodes, 8,083 walks for 464 haplotypes). `overlapping`\n * also follows snarls that leave the window, so every haplotype is one\n * walk (464), at the price of every node in those snarls (4,184 there,\n * 24,547 across the KIV-2 repeat). `none` leaves only the bp `context`.\n */\n subgraphSnarls: {\n type: 'stringEnum',\n model: types.enumeration('SnarlOutput', [\n 'none',\n 'contained',\n 'overlapping',\n ]),\n defaultValue: GBZ_CUT_DEFAULTS.snarls,\n },\n /**\n * #slot\n * The graph sample the anchor window is located on. Empty means the sample\n * the anchor's PanSN prefix names, or the database's one reference sample\n * (`gbwt_reference_samples`) when the anchor names none; a database with\n * several reference samples then needs this set.\n */\n referenceSample: {\n type: 'string',\n defaultValue: '',\n },\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN prefix in the graph, sample or\n * haplotype level (`{ hg38: 'GRCh38#0', 'HG002.1': 'HG002#1' }`). Each\n * session assembly with a `sample#haplotype` alias (`HG002#1`) is mapped to\n * it already, so this is the override: an entry takes its prefix from any\n * assembly aliased to it. An assembly in neither maps to itself.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * Graph context around the window, in bp, on top of `subgraphSnarls`: the\n * cut, its reference walk and every haplotype walk extend this far past\n * the window on each side. A haplotype walk breaks into pieces wherever it\n * leaves the cut's nodes, so context and snarls together decide whether a\n * lane's bubble is one record or several. A window inside a snarl far\n * larger than itself (MHC class II on the HPRC graph, 90 kb) is 1.1M pieces\n * at 0 and 464 walks at 1000, three times faster.\n */\n context: {\n type: 'number',\n defaultValue: GBZ_CUT_DEFAULTS.context,\n advanced: true,\n },\n /**\n * #slot\n * The most graph nodes one window may load before the query fails rather\n * than reading a whole chromosome into the worker.\n */\n nodeLimit: {\n type: 'number',\n defaultValue: GBZ_CUT_DEFAULTS.limit,\n advanced: true,\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n *\n * preprocessor to allow minimal config, where a `.gz` `reads` is taken to\n * be bgzipped with a `.tbi` beside it:\n * ```json\n * {\n * \"type\": \"GbzBaseSyntenyAdapter\",\n * \"uri\": \"graph.gbz.db\",\n * \"reads\": \"reads.gaf.gz\",\n * \"assemblyNames\": [\"hg38\"]\n * }\n * ```\n */\n preProcessSnapshot: snap => {\n const { uri, baseUri, reads } = snap\n return {\n ...snap,\n ...(uri ? { gbzDbLocation: { uri, baseUri } } : {}),\n ...(typeof reads === 'string'\n ? {\n readsLocation: { uri: reads, baseUri },\n ...readsIndexBeside(reads, baseUri),\n }\n : {}),\n }\n },\n },\n)\n\n// a bgzipped GAF's index, before any query string its url carries\nfunction readsIndexBeside(reads: string, baseUri: unknown) {\n const { name, query } = splitUri(reads)\n return name.endsWith('.gz')\n ? { readsIndex: { location: { uri: `${name}.tbi${query}`, baseUri } } }\n : {}\n}\n\nexport type GbzBaseSyntenyAdapterConfig = Instance<typeof GbzBaseSyntenyAdapter>\n\nexport default GbzBaseSyntenyAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function GbzBaseSyntenyAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'GbzBaseSyntenyAdapter',\n displayName: 'gbz-base pangenome adapter',\n configSchema,\n // The same opened database serves the graph display's subgraph.\n // headerLanes: getHeader declares every haplotype as a lane, which is\n // what makes MultiWaySyntenyDisplay read the header of an untiered\n // adapter and offer its lane picker over the whole graph.\n // lanePairsOnAnchor: a window of the anchor answers any two lanes'\n // alignment to each other, so the display fetches each adjacent pair\n // rather than composing it through the reference.\n // lanePairBatches: every pair on a window comes from one cut\n adapterCapabilities: [\n 'getSubgraph',\n 'headerLanes',\n 'lanePairsOnAnchor',\n 'lanePairBatches',\n ],\n adapterMetadata: {\n category: 'Synteny adapters',\n },\n getAdapterClass: () =>\n import('./GbzBaseSyntenyAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const AdapterType = /* @__PURE__ */ read(\"AdapterType\")\nexport const AddTrackWorkflowType = /* @__PURE__ */ read(\"AddTrackWorkflowType\")\nexport const BaseConnectionModelFactory = /* @__PURE__ */ read(\"BaseConnectionModelFactory\")\nexport const BaseDisplay = /* @__PURE__ */ read(\"BaseDisplay\")\nexport const BaseInternetAccountConfig = /* @__PURE__ */ read(\"BaseInternetAccountConfig\")\nexport const BaseViewModel = /* @__PURE__ */ read(\"BaseViewModel\")\nexport const ConnectionType = /* @__PURE__ */ read(\"ConnectionType\")\nexport const DisplayType = /* @__PURE__ */ read(\"DisplayType\")\nexport const InternetAccount = /* @__PURE__ */ read(\"InternetAccount\")\nexport const InternetAccountType = /* @__PURE__ */ read(\"InternetAccountType\")\nexport const RpcMethodType = /* @__PURE__ */ read(\"RpcMethodType\")\nexport const RpcMethodTypeWithRenameRegion = /* @__PURE__ */ read(\"RpcMethodTypeWithRenameRegion\")\nexport const RpcMethodTypeWithRenameRegions = /* @__PURE__ */ read(\"RpcMethodTypeWithRenameRegions\")\nexport const TextSearchAdapterType = /* @__PURE__ */ read(\"TextSearchAdapterType\")\nexport const TrackType = /* @__PURE__ */ read(\"TrackType\")\nexport const ViewType = /* @__PURE__ */ read(\"ViewType\")\nexport const WidgetType = /* @__PURE__ */ read(\"WidgetType\")\nexport const addDisplayMenuItems = /* @__PURE__ */ read(\"addDisplayMenuItems\")\nexport const addViewMenuItems = /* @__PURE__ */ read(\"addViewMenuItems\")\nexport const baseConnectionConfig = /* @__PURE__ */ read(\"baseConnectionConfig\")\nexport const createBaseTrackConfig = /* @__PURE__ */ read(\"createBaseTrackConfig\")\nexport const createBaseTrackModel = /* @__PURE__ */ read(\"createBaseTrackModel\")\nexport const extendDisplayType = /* @__PURE__ */ read(\"extendDisplayType\")\nexport const extendViewType = /* @__PURE__ */ read(\"extendViewType\")\nexport const preprocessTrackConfigSnapshot = /* @__PURE__ */ read(\"preprocessTrackConfigSnapshot\")\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/core/data_adapters/dataAdapterCache\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/data_adapters/dataAdapterCache\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const READS_REFERENCE = /* @__PURE__ */ read(\"READS_REFERENCE\")\nexport const adapterConfigCacheKey = /* @__PURE__ */ read(\"adapterConfigCacheKey\")\nexport const clearAdapterCache = /* @__PURE__ */ read(\"clearAdapterCache\")\nexport const freeAdapterResources = /* @__PURE__ */ read(\"freeAdapterResources\")\nexport const getAdapter = /* @__PURE__ */ read(\"getAdapter\")\nexport default host && host.__esModule ? host.default : host", "import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// The adapter a request's config names, as T when it has `method`, else\n// undefined. `name` is its class name, for saying which adapter lacks it.\nexport async function adapterImplementing<T extends object>(\n pluginManager: PluginManager,\n {\n sessionId,\n adapterConfig,\n }: { sessionId: string; adapterConfig: Record<string, unknown> },\n method: keyof T & string,\n) {\n const { dataAdapter } = await getAdapter(\n pluginManager,\n sessionId,\n adapterConfig,\n )\n const implemented =\n typeof (dataAdapter as unknown as Record<string, unknown>)[method] ===\n 'function'\n return {\n adapter: implemented ? (dataAdapter as unknown as T) : undefined,\n name: dataAdapter.constructor.name,\n }\n}\n", "import { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport { adapterImplementing } from './adapterImplementing'\n\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The haplotypes a graph names without a cut, for the track's haplotype picker:\n// a walk-indexed rGFA's header lines. Undefined where the graph names none, and\n// the picker falls back to typed names.\n\nexport interface GetGraphHaplotypesArgs {\n adapterConfig: Record<string, unknown>\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetGraphHaplotypes: {\n args: GetGraphHaplotypesArgs\n return: string[] | undefined\n }\n }\n}\n\ninterface HaplotypeNamesAdapter {\n getHaplotypeNames(opts: {\n signal?: AbortSignal\n }): Promise<string[] | undefined>\n}\n\nexport default class GetGraphHaplotypes extends RpcMethodType<'GetGraphHaplotypes'> {\n name = 'GetGraphHaplotypes' as const\n\n async execute(args: RpcExecuteArgs<'GetGraphHaplotypes'>) {\n const { adapter } = await adapterImplementing<HaplotypeNamesAdapter>(\n this.pluginManager,\n args,\n 'getHaplotypeNames',\n )\n return adapter?.getHaplotypeNames({ signal: args.signal })\n }\n}\n", "import { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport { adapterImplementing } from './adapterImplementing'\nimport { snapshotNamesFile } from './locationName.ts'\n\nimport type { GafReads } from './gaf/gafFile'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The reads aligned over a cut's segments, from an adapter whose config names\n// a GAF (GbzBaseSyntenyAdapter's `readsLocation`). Asked after the cut is\n// parsed, because the segment names are what a GAF index is keyed by.\n\nexport interface GetGraphReadsArgs {\n adapterConfig: Record<string, unknown>\n nodeNames: string[]\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetGraphReads: {\n args: GetGraphReadsArgs\n return: GafReads\n }\n }\n}\n\ninterface ReadsAdapter {\n getReads(\n nodeNames: string[],\n opts: { signal?: AbortSignal },\n ): Promise<GafReads>\n}\n\n// Whether an adapter config as written names reads, so a graph without them\n// makes no round trip to ask\nexport function namesReads(adapterConfig: Record<string, unknown>) {\n return (\n (typeof adapterConfig.reads === 'string' && adapterConfig.reads !== '') ||\n snapshotNamesFile(adapterConfig.readsLocation)\n )\n}\n\nexport default class GetGraphReads extends RpcMethodType<'GetGraphReads'> {\n name = 'GetGraphReads' as const\n\n async execute(args: RpcExecuteArgs<'GetGraphReads'>) {\n const { nodeNames, signal } = args\n const { adapter } = await adapterImplementing<ReadsAdapter>(\n this.pluginManager,\n args,\n 'getReads',\n )\n return adapter\n ? adapter.getReads(nodeNames, { signal })\n : { records: [], total: 0 }\n }\n}\n", "const host = JBrowseExports[\"@jbrowse/core/util/librpc\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/util/librpc\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const RpcClient = /* @__PURE__ */ read(\"RpcClient\")\nexport const RpcServer = /* @__PURE__ */ read(\"RpcServer\")\nexport const deserializeError = /* @__PURE__ */ read(\"deserializeError\")\nexport const isRpcResult = /* @__PURE__ */ read(\"isRpcResult\")\nexport const rpcResult = /* @__PURE__ */ read(\"rpcResult\")\nexport const rpcResultWithArrayBuffers = /* @__PURE__ */ read(\"rpcResultWithArrayBuffers\")\nexport const serializeError = /* @__PURE__ */ read(\"serializeError\")\nexport const unwrapRpcResult = /* @__PURE__ */ read(\"unwrapRpcResult\")\nexport default host && host.__esModule ? host.default : host", "import { gfaTables } from '@jbrowse/bandage-core/gfa/gfaTables'\nimport { RpcMethodTypeWithRenameRegion } from '@jbrowse/core/pluggableElementTypes'\nimport { rpcResultWithArrayBuffers } from '@jbrowse/core/util/librpc'\n\nimport { adapterImplementing } from './adapterImplementing'\n\nimport type { WalkCut } from './RgfaTabixAdapter/walkRowRuns.ts'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\nimport type { Region } from '@jbrowse/core/util'\n\n// No `sessionId`, `signal` or `statusCallback` here: those belong to the\n// CALL, not to this payload, and core's `EntriesDeclaringCallLevelFields` fails\n// the build for a registry entry that declares one. `execute` still receives\n// them, because `RpcExecuteArgs` intersects `RpcCallContext` in.\n// `hops` is how far past the window a cut follows links, which only the rGFA\n// cut reads; the GBZ cut has its own bp `context` slot. `haplotypes` is the\n// set the cut is for, lane assembly names or PanSN prefixes, which the GBZ cut\n// and a walk-indexed rGFA cut read: they keep those walks, the reference's,\n// and the nodes they visit. Undefined or empty\n// is every haplotype. `tier` picks which of an rGFA track's two index pairs the\n// cut reads, the adapter's own or its `coarse` one; fine when absent.\nexport type SubgraphTier = 'fine' | 'coarse'\n\nexport interface SubgraphCutOptions {\n hops?: number\n haplotypes?: string[]\n tier?: SubgraphTier\n // which snarls a GBZ cut follows past the window, over the track's\n // `subgraphSnarls`; 'overlapping' when the layout measures whole walks\n snarls?: 'none' | 'contained' | 'overlapping'\n // a cut for walk rows: its runs come with the tables, and the\n // step budget, which guards a Graph of every step, does not apply\n walkRows?: boolean\n}\n\n// What an adapter's cut is handed: the payload, plus the call's own signal so\n// a cut the view has moved on from stops reading.\nexport interface SubgraphAdapterOptions extends SubgraphCutOptions {\n signal?: AbortSignal\n}\n\nexport interface SubgraphRegion {\n refName: string\n assemblyName: string\n start: number\n end: number\n}\n\nexport interface GetSubgraphArgs {\n adapterConfig: Record<string, unknown>\n region: Region\n opts?: SubgraphCutOptions\n}\n\n// A cut is tables, whose typed arrays cross to the main thread without a copy,\n// or GFA text the tables cannot hold\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetSubgraph: {\n args: GetSubgraphArgs\n return: string | WalkCut\n transferables: WalkCut\n }\n }\n}\n\n// Adapters that can cut a local subgraph out of a graph file implement this:\n// RgfaTabixAdapter, WalkTabixSyntenyAdapter and GbzBaseSyntenyAdapter.\ninterface SubgraphAdapter {\n getSubgraph(\n region: Region,\n opts?: SubgraphAdapterOptions,\n ): Promise<string | WalkCut>\n}\n\n// RpcMethodTypeWithRenameRegion, not the plain RpcMethodType: the base class is\n// what maps `region.refName` from the assembly's spelling onto the adapter's own\n// before the call crosses to the worker. Without it a launch on an hg38 whose\n// contigs are bare (`6`, which is what every GRCh38 FASTA on jbrowse.org uses)\n// asked RgfaTabixAdapter for `GRCh38#0#6`, matched nothing, and opened a view\n// reading \"0 nodes, 0 edges\" with no error. The segments track drew the whole\n// time, because CoreGetFeatures renames and this did not, so the graph looked\n// broken while its own track looked fine. `assemblyNameToPanSN` covers the\n// sample half of a PanSN name only; the contig half is refName aliasing, which\n// the assembly already knows and this now consults.\nexport default class GetSubgraph extends RpcMethodTypeWithRenameRegion<'GetSubgraph'> {\n name = 'GetSubgraph' as const\n\n // Parameterized by the registry key, not left at the default `string`: a bare\n // RpcMethodTypeWithRenameRegion resolves RpcExecuteArgs to `unknown`, so\n // `execute` type-checks against nothing at all. `invoke` has already run\n // `deserializeArguments` by the time this is called, so it does not.\n async execute(args: RpcExecuteArgs<'GetSubgraph'>) {\n // `signal` arrives on every call and has to be named to be forwarded:\n // unnamed, a cut the view had replaced went on querying to the end, one\n // tabix read per off-reference segment per hop.\n const { region, opts, signal } = args\n const { adapter, name } = await adapterImplementing<SubgraphAdapter>(\n this.pluginManager,\n args,\n 'getSubgraph',\n )\n // A text cut is read into tables here, off the main thread: a GBZ cut of\n // every haplotype is tens of MB of W lines\n if (adapter) {\n const cut = await adapter.getSubgraph(region, { ...opts, signal })\n if (typeof cut !== 'string') {\n return rpcResultWithArrayBuffers(cut)\n }\n const tables = cut ? gfaTables(cut) : undefined\n return tables ? rpcResultWithArrayBuffers(tables) : cut\n }\n // The pane's cutSubgraph reports an empty result as a track that cannot\n // cut subgraphs\n console.warn(`[GetSubgraph] ${name} does not implement getSubgraph`)\n return ''\n }\n}\n", "import { lazy } from 'react'\n\nimport { AddTrackWorkflowType } from '@jbrowse/core/pluggableElementTypes'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nconst GraphAddTrackWidget = lazy(() => import('./AddTrackWorkflow'))\n\nexport default function GraphAddTrackWorkflowF(pluginManager: PluginManager) {\n pluginManager.addAddTrackWorkflowType(\n () =>\n new AddTrackWorkflowType({\n name: 'Pangenome graph track',\n displayName: 'Add pangenome graph track',\n ReactComponent: GraphAddTrackWidget,\n stateModel: types.model({}),\n }),\n )\n}\n", "import { layoutEngine } from '@jbrowse/bandage-core/layoutEngines'\nimport { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport type { EngineRequest } from '@jbrowse/bandage-core/pipeline'\nimport type { LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The payload is the pipeline's EngineRequest, the same request a standalone\n// page hands the engine. `sessionId` and `statusCallback` are the CALL's, not\n// the payload's: core's `EntriesDeclaringCallLevelFields` fails the build for a\n// registry entry that declares either. `execute` still receives both, through\n// `RpcExecuteArgs`'s intersection with `RpcCallContext`.\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GraphComputeLayout: {\n args: EngineRequest\n return: { result: LayoutResult; duration: number }\n }\n }\n}\n\nexport default class GraphComputeLayout extends RpcMethodType<'GraphComputeLayout'> {\n name = 'GraphComputeLayout' as const\n\n async execute(args: RpcExecuteArgs<'GraphComputeLayout'>) {\n const { graph, options, statusCallback } = args\n\n statusCallback?.('Computing layout')\n return layoutEngine({ graph, options })\n }\n}\n", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/ViewType\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes/ViewType\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/core/util/withLaunchInput\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/util/withLaunchInput\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const defineLaunchKeys = /* @__PURE__ */ read(\"defineLaunchKeys\")\nexport const isTrackRecipe = /* @__PURE__ */ read(\"isTrackRecipe\")\nexport const legacyInitMessage = /* @__PURE__ */ read(\"legacyInitMessage\")\nexport const pendingLaunch = /* @__PURE__ */ read(\"pendingLaunch\")\nexport const snapshotSettings = /* @__PURE__ */ read(\"snapshotSettings\")\nexport const unknownKeysMessage = /* @__PURE__ */ read(\"unknownKeysMessage\")\nexport const withLaunchInput = /* @__PURE__ */ read(\"withLaunchInput\")\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/models\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes/models\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const BaseConnectionModelFactory = /* @__PURE__ */ read(\"BaseConnectionModelFactory\")\nexport const BaseDisplay = /* @__PURE__ */ read(\"BaseDisplay\")\nexport const BaseInternetAccountConfig = /* @__PURE__ */ read(\"BaseInternetAccountConfig\")\nexport const BaseViewModel = /* @__PURE__ */ read(\"BaseViewModel\")\nexport const InternetAccount = /* @__PURE__ */ read(\"InternetAccount\")\nexport const baseConnectionConfig = /* @__PURE__ */ read(\"baseConnectionConfig\")\nexport const createBaseTrackConfig = /* @__PURE__ */ read(\"createBaseTrackConfig\")\nexport const createBaseTrackModel = /* @__PURE__ */ read(\"createBaseTrackModel\")\nexport const migrateRetiredDisplays = /* @__PURE__ */ read(\"migrateRetiredDisplays\")\nexport const preprocessTrackConfigSnapshot = /* @__PURE__ */ read(\"preprocessTrackConfigSnapshot\")\nexport default host && host.__esModule ? host.default : host", "// What the pointer lights: nothing, a hovered node, or also an edge under it\n// and the node at a linear view's pointer bp\nexport type HoverHighlight = 'off' | 'nodes' | 'everything'\n\nexport const HOVER_HIGHLIGHT_VALUES: HoverHighlight[] = [\n 'off',\n 'nodes',\n 'everything',\n]\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2m0 16H8V7h11z\"\n}), 'ContentCopy');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M8.4 18.2c.38.5.6 1.12.6 1.8 0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3c.44 0 .85.09 1.23.26l1.41-1.77c-.92-1.03-1.29-2.39-1.09-3.69l-2.03-.68c-.54.83-1.46 1.38-2.52 1.38-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3c0 .07 0 .14-.01.21l2.03.68c.64-1.21 1.82-2.09 3.22-2.32V5.91C9.96 5.57 9 4.4 9 3c0-1.66 1.34-3 3-3s3 1.34 3 3c0 1.4-.96 2.57-2.25 2.91v2.16c1.4.23 2.58 1.11 3.22 2.32L18 9.71V9.5c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3c-1.06 0-1.98-.55-2.52-1.37l-2.03.68c.2 1.29-.16 2.65-1.09 3.69l1.41 1.77Q17.34 17 18 17c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3c0-.68.22-1.3.6-1.8l-1.41-1.77c-1.35.75-3.01.76-4.37 0z\"\n}), 'Hub');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10c1.38 0 2.5-1.12 2.5-2.5 0-.61-.23-1.2-.64-1.67-.08-.1-.13-.21-.13-.33 0-.28.22-.5.5-.5H16c3.31 0 6-2.69 6-6 0-4.96-4.49-9-10-9m5.5 11c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5m-3-4c-.83 0-1.5-.67-1.5-1.5S13.67 6 14.5 6s1.5.67 1.5 1.5S15.33 9 14.5 9M5 11.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5S7.33 13 6.5 13 5 12.33 5 11.5m6-4c0 .83-.67 1.5-1.5 1.5S8 8.33 8 7.5 8.67 6 9.5 6s1.5.67 1.5 1.5\"\n}), 'Palette');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon([/*#__PURE__*/_jsx(\"circle\", {\n cx: \"12\",\n cy: \"12\",\n r: \"3.2\"\n}, \"0\"), /*#__PURE__*/_jsx(\"path\", {\n d: \"M9 2 7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5\"\n}, \"1\")], 'PhotoCamera');", "import {\n ownStrand\n} from \"./chunk-UBQSRCWR.js\";\nimport {\n groupBy\n} from \"./chunk-BSOZW3FC.js\";\nimport {\n isBackbone\n} from \"./chunk-RJWPJCIB.js\";\n\n// src/foldVariants.ts\nfunction foldVariants(graph, belowBp) {\n if (!(belowBp > 0) || graph.paths?.length || !graph.nodes.some((node) => isBackbone(node))) {\n return graph;\n }\n const { nodes, edges } = readForward(graph);\n const index = new Map(nodes.map((node, i) => [node.id, i]));\n const sides = edges.map(forwardSides);\n const links = linksAt(nodes.length, edges, sides, index);\n const allele = alleleOf(nodes, edges, sides, index);\n const members = groupBy(allele.keys(), (i) => allele[i]);\n const kept = new Uint8Array(nodes.length);\n const big = [];\n for (const group of members.values()) {\n if (alleleContent(group, nodes, links, allele) >= belowBp) {\n for (const i of group) {\n kept[i] = 1;\n }\n if (!isBackbone(nodes[group[0]])) {\n big.push(group);\n }\n }\n }\n const { dist, pred } = distancesFromBackbone(nodes, links);\n for (const group of big) {\n for (const [i, side] of alleleEnds(group, nodes, links, allele)) {\n let next = nearestOutside(i, side, links, allele, dist, nodes);\n while (next !== void 0 && !kept[next]) {\n kept[next] = 1;\n next = isBackbone(nodes[next]) ? void 0 : pred[next];\n }\n }\n }\n const keptEdges = edges.filter((edge, k) => {\n const a = index.get(edge.from);\n const b = index.get(edge.to);\n if (a === void 0 || b === void 0) {\n return false;\n }\n const skip = skipped(nodes[a], sides[k].from, nodes[b], sides[k].to);\n return kept[a] && kept[b] && !(skip > 0 && skip < belowBp);\n });\n return mergeAlleleRuns({ ...graph, nodes, edges: keptEdges }, kept, allele);\n}\nfunction readForward({ nodes, edges }) {\n const reversed = new Set(\n nodes.filter((node) => node.stable?.strand === \"-\").map((node) => node.id)\n );\n if (reversed.size === 0) {\n return { nodes, edges };\n }\n const read = (id, strand) => {\n const own = strand ?? ownStrand(id);\n return reversed.has(id) ? complement(own) : own;\n };\n return {\n nodes: nodes.map(\n (node) => reversed.has(node.id) ? { ...node, stable: { ...node.stable, strand: \"+\" } } : node\n ),\n edges: edges.map(\n (edge) => reversed.has(edge.from) || reversed.has(edge.to) ? {\n ...edge,\n fromStrand: read(edge.from, edge.fromStrand),\n toStrand: read(edge.to, edge.toStrand)\n } : edge\n )\n };\n}\nfunction complement(strand) {\n return strand === \"+\" ? \"-\" : \"+\";\n}\nfunction forwardSides(edge) {\n return {\n from: (edge.fromStrand ?? ownStrand(edge.from)) === \"+\" ? \"e\" : \"s\",\n to: (edge.toStrand ?? ownStrand(edge.to)) === \"+\" ? \"s\" : \"e\"\n };\n}\nfunction linksAt(count, edges, sides, index) {\n const links = Array.from({ length: count }, () => []);\n edges.forEach((edge, k) => {\n const a = index.get(edge.from);\n const b = index.get(edge.to);\n if (a !== void 0 && b !== void 0) {\n const { from, to } = sides[k];\n links[a].push({ other: b, side: from, otherSide: to });\n links[b].push({ other: a, side: to, otherSide: from });\n }\n });\n return links;\n}\nfunction onOneSequence(a, b) {\n const sa = a.stable;\n const sb = b.stable;\n return sa && sb?.refName === sa.refName && sb.rank === sa.rank ? [sa, sb] : void 0;\n}\nfunction continues(a, aSide, b, bSide) {\n const pair = onOneSequence(a, b);\n if (!pair) {\n return false;\n }\n const [sa, sb] = pair;\n return aSide === \"e\" && bSide === \"s\" && sa.start + a.length === sb.start || bSide === \"e\" && aSide === \"s\" && sb.start + b.length === sa.start;\n}\nfunction skipped(a, aSide, b, bSide) {\n const pair = onOneSequence(a, b);\n if (!pair || continues(a, aSide, b, bSide)) {\n return 0;\n }\n const [sa, sb] = pair;\n return Math.abs(position(sb, b, bSide) - position(sa, a, aSide));\n}\nfunction position({ start }, node, side) {\n return side === \"s\" ? start : start + node.length;\n}\nfunction alleleOf(nodes, edges, sides, index) {\n const parent = nodes.map((_, i) => i);\n const find = (i) => {\n while (parent[i] !== i) {\n parent[i] = parent[parent[i]];\n i = parent[i];\n }\n return i;\n };\n edges.forEach((edge, k) => {\n const a = index.get(edge.from);\n const b = index.get(edge.to);\n if (a !== void 0 && b !== void 0 && continues(nodes[a], sides[k].from, nodes[b], sides[k].to)) {\n parent[find(a)] = find(b);\n }\n });\n return nodes.map((_, i) => find(i));\n}\nfunction alleleContent(group, nodes, links, allele) {\n if (isBackbone(nodes[group[0]])) {\n return Infinity;\n }\n let length = 0;\n let refName;\n let lo = Infinity;\n let hi = -Infinity;\n let oneSequence = true;\n for (const i of group) {\n length += nodes[i].length;\n for (const { other, otherSide } of links[i]) {\n const node = nodes[other];\n if (allele[other] !== allele[i] && isBackbone(node)) {\n refName ??= node.stable.refName;\n oneSequence &&= node.stable.refName === refName;\n const at = position(node.stable, node, otherSide);\n lo = Math.min(lo, at);\n hi = Math.max(hi, at);\n }\n }\n }\n return oneSequence && hi > lo ? Math.max(length, hi - lo) : length;\n}\nfunction alleleEnds(group, nodes, links, allele) {\n const start = (i) => nodes[i].stable?.start ?? 0;\n const end = (i) => start(i) + nodes[i].length;\n let first = group[0];\n let last = group[0];\n for (const i of group) {\n if (start(i) < start(first)) {\n first = i;\n }\n if (end(i) > end(last)) {\n last = i;\n }\n }\n const ends = [];\n for (const i of /* @__PURE__ */ new Set([first, last])) {\n for (const side of [\"s\", \"e\"]) {\n if (!links[i].some(\n (link) => link.side === side && allele[link.other] === allele[i]\n )) {\n ends.push([i, side]);\n }\n }\n }\n return ends;\n}\nfunction nearestOutside(i, side, links, allele, dist, nodes) {\n let best;\n for (const link of links[i]) {\n const j = link.other;\n if (link.side === side && allele[j] !== allele[i] && Number.isFinite(dist[j]) && (best === void 0 || dist[j] < dist[best] || dist[j] === dist[best] && nodes[j].name < nodes[best].name)) {\n best = j;\n }\n }\n return best;\n}\nfunction distancesFromBackbone(nodes, links) {\n const dist = new Float64Array(nodes.length).fill(Infinity);\n const pred = new Int32Array(nodes.length).fill(-1);\n const heap = new MinHeap(\n ([da, a], [db, b]) => da - db || cmp(nodes[a].name, nodes[b].name)\n );\n nodes.forEach((node, i) => {\n if (isBackbone(node)) {\n dist[i] = 0;\n heap.push([0, i]);\n }\n });\n for (let top = heap.pop(); top !== void 0; top = heap.pop()) {\n const [d0, i] = top;\n if (d0 > dist[i]) {\n continue;\n }\n for (const { other } of links[i]) {\n if (isBackbone(nodes[other])) {\n continue;\n }\n const d = d0 + nodes[other].length;\n if (d < dist[other]) {\n dist[other] = d;\n pred[other] = i;\n heap.push([d, other]);\n } else if (d === dist[other] && cmp(nodes[i].name, nodes[pred[other]].name) < 0) {\n pred[other] = i;\n }\n }\n }\n return { dist, pred: Array.from(pred, (p) => p < 0 ? void 0 : p) };\n}\nfunction cmp(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\nvar MinHeap = class {\n constructor(order) {\n this.order = order;\n this.items = [];\n }\n push(item) {\n const { items } = this;\n items.push(item);\n let i = items.length - 1;\n while (i > 0) {\n const up = i - 1 >> 1;\n if (this.order(items[i], items[up]) >= 0) {\n break;\n }\n ;\n [items[i], items[up]] = [items[up], items[i]];\n i = up;\n }\n }\n pop() {\n const { items } = this;\n const top = items[0];\n const last = items.pop();\n if (items.length > 0 && last !== void 0) {\n items[0] = last;\n let i = 0;\n for (; ; ) {\n const l = 2 * i + 1;\n const r = l + 1;\n let m = i;\n if (l < items.length && this.order(items[l], items[m]) < 0) {\n m = l;\n }\n if (r < items.length && this.order(items[r], items[m]) < 0) {\n m = r;\n }\n if (m === i) {\n break;\n }\n ;\n [items[i], items[m]] = [items[m], items[i]];\n i = m;\n }\n }\n return top;\n }\n};\nfunction mergeAlleleRuns(graph, kept, allele) {\n const { nodes, edges } = graph;\n const index = new Map(nodes.map((node, i) => [node.id, i]));\n const sides = edges.map(forwardSides);\n const ends = edges.map((edge, k) => [\n { i: index.get(edge.from), side: sides[k].from },\n { i: index.get(edge.to), side: sides[k].to }\n ]);\n const degree = /* @__PURE__ */ new Map();\n const sideKey = (i, side) => `${i}${side}`;\n for (const pair of ends) {\n for (const { i, side } of pair) {\n degree.set(sideKey(i, side), (degree.get(sideKey(i, side)) ?? 0) + 1);\n }\n }\n const next = /* @__PURE__ */ new Map();\n const hasPrev = /* @__PURE__ */ new Set();\n const internal = /* @__PURE__ */ new Set();\n ends.forEach(([a, b], k) => {\n if (a.i !== b.i && allele[a.i] === allele[b.i] && continues(nodes[a.i], a.side, nodes[b.i], b.side) && degree.get(sideKey(a.i, a.side)) === 1 && degree.get(sideKey(b.i, b.side)) === 1) {\n const [left, right] = a.side === \"e\" ? [a, b] : [b, a];\n next.set(left.i, { j: right.i, out: left.side, in: right.side });\n hasPrev.add(right.i);\n internal.add(k);\n }\n });\n const headOf = nodes.map((_, i) => i);\n const outer = /* @__PURE__ */ new Map();\n const merged = /* @__PURE__ */ new Map();\n nodes.forEach((_, i) => {\n if (!kept[i] || hasPrev.has(i) || !next.has(i)) {\n return;\n }\n const run = [i];\n let into = flip(next.get(i).out);\n outer.set(sideKey(i, into), \"s\");\n for (let step = next.get(i); step; step = next.get(step.j)) {\n run.push(step.j);\n into = step.in;\n }\n outer.set(sideKey(run.at(-1), flip(into)), \"e\");\n for (const j of run) {\n headOf[j] = i;\n }\n merged.set(i, mergedNode(run.map((j) => nodes[j])));\n });\n const endpoint = ({ i, side }) => ({\n id: nodes[headOf[i]].id,\n side: headOf[i] === i && !merged.has(i) ? side : outer.get(sideKey(i, side))\n });\n return {\n ...graph,\n nodes: nodes.flatMap(\n (node, i) => !kept[i] || headOf[i] !== i ? [] : [merged.get(i) ?? node]\n ),\n edges: edges.flatMap((edge, k) => {\n if (internal.has(k)) {\n return [];\n }\n const [a, b] = ends[k];\n if (!merged.has(headOf[a.i]) && !merged.has(headOf[b.i])) {\n return [edge];\n }\n const from = endpoint(a);\n const to = endpoint(b);\n return [\n {\n ...edge,\n from: from.id,\n to: to.id,\n fromStrand: from.side === \"e\" ? \"+\" : \"-\",\n toStrand: to.side === \"s\" ? \"+\" : \"-\"\n }\n ];\n })\n };\n}\nfunction flip(side) {\n return side === \"s\" ? \"e\" : \"s\";\n}\nfunction mergedNode(run) {\n const { samples: firstSamples, ...first } = run[0];\n const length = run.reduce((sum, node) => sum + node.length, 0);\n const depth = length > 0 ? run.reduce((sum, node) => sum + node.depth * node.length, 0) / length : first.depth;\n const samples = run.every((node) => node.samples) ? run.reduce(\n (common, node) => common.filter((s) => node.samples.includes(s)),\n firstSamples\n ) : void 0;\n return samples ? { ...first, length, depth, samples } : { ...first, length, depth };\n}\n\nexport {\n foldVariants\n};\n", "import {\n pathOrigin,\n trimOrigins\n} from \"../chunks/chunk-B5X2RLJG.js\";\nimport {\n PathVisitsBuilder\n} from \"../chunks/chunk-ZPZ7GNBT.js\";\nimport \"../chunks/chunk-BSOZW3FC.js\";\nimport {\n isBackbone,\n overlapsWindow\n} from \"../chunks/chunk-RJWPJCIB.js\";\nimport \"../chunks/chunk-HOAIOEI7.js\";\nimport \"../chunks/chunk-4XWZNPQ2.js\";\n\n// src/layout/trimToWindow.ts\nfunction trimToWindow(graph, window) {\n const inWindow = new Set(\n graph.nodes.filter((n) => isBackbone(n) && overlapsWindow(n, window)).map((n) => n.id)\n );\n const paths = graph.paths ?? [];\n if (inWindow.size === 0 || paths.length === 0) {\n return graph;\n }\n const spans = paths.map((path) => {\n let first = -1;\n let last = -1;\n path.nodeIds.forEach((id, i) => {\n if (inWindow.has(id)) {\n if (first < 0) {\n first = i;\n }\n last = i;\n }\n });\n return first < 0 ? void 0 : { first, last };\n });\n if (spans.every(\n (span, i) => span?.first === 0 && span.last === paths[i].nodeIds.length - 1\n )) {\n return graph;\n }\n const kept = /* @__PURE__ */ new Set();\n const trimmed = [];\n const stretches = /* @__PURE__ */ new Map();\n paths.forEach((path, i) => {\n const span = spans[i];\n if (span) {\n const nodeIds = path.nodeIds.slice(span.first, span.last + 1);\n for (const id of nodeIds) {\n kept.add(id);\n }\n trimmed.push({ ...path, nodeIds });\n stretches.set(path.name, { first: span.first, nodeIds });\n }\n });\n return {\n ...graph,\n nodes: graph.nodes.filter((n) => kept.has(n.id)),\n edges: graph.edges.filter((e) => kept.has(e.from) && kept.has(e.to)),\n paths: trimmed,\n pathVisits: graph.pathVisits && trimVisits(\n graph.pathVisits,\n paths,\n spans,\n new Map(graph.nodes.map((n) => [n.id, n.name]))\n ),\n anchorPaths: trimOrigins(graph, stretches)\n };\n}\nfunction trimVisits(visits, paths, spans, nameOf) {\n const next = visits.replay();\n const out = new PathVisitsBuilder();\n paths.forEach((path, p) => {\n const origin = visits.pathIndex(pathOrigin(path.name).name);\n const span = spans[p];\n path.nodeIds.forEach((id, i) => {\n const segment = nameOf.get(id) ?? id;\n const at = next(visits.slot(segment), origin);\n if (at >= 0 && span && i >= span.first && i <= span.last) {\n out.add(\n segment,\n visits.paths[origin],\n visits.samples[origin],\n visits.start[at],\n visits.reversed[at] === 1\n );\n }\n });\n });\n return out.build();\n}\nfunction clipToWindow(graph, window, reachBp) {\n const nodes = graph.nodes.map((node) => {\n if (!isBackbone(node)) {\n return node;\n }\n const from = node.stable.start;\n const to = from + node.length;\n const [start, end] = overlapsWindow(node, window) ? [Math.max(from, window.start), Math.min(to, window.end)] : to <= window.start ? [Math.max(from, to - reachBp), to] : [from, Math.min(to, from + reachBp)];\n return start === from && end === to ? node : { ...node, length: end - start, stable: { ...node.stable, start } };\n });\n return nodes.some((node, i) => node !== graph.nodes[i]) ? { ...graph, nodes } : graph;\n}\nexport {\n clipToWindow,\n trimToWindow\n};\n", "import {\n pathSteps\n} from \"./chunk-PK5QQOMN.js\";\nimport {\n pathOrigin\n} from \"./chunk-B5X2RLJG.js\";\nimport {\n pushTo\n} from \"./chunk-BSOZW3FC.js\";\n\n// src/tubeMap/bundle.ts\nfunction bundleRoutes(graph, groupOf = () => \"\", merge = true) {\n const paths = graph.paths ?? [];\n const steps = pathSteps(graph);\n const piecesOf = /* @__PURE__ */ new Map();\n paths.forEach((path, i) => {\n pushTo(piecesOf, pathOrigin(path.name).name, i);\n });\n const routeOf = (i) => steps[i].map((s) => `${s.node.id}${s.strand}`).join(\",\");\n const recordsOf = (walk) => piecesOf.get(walk).map((i) => paths[i]);\n const routeRank = /* @__PURE__ */ new Map();\n const bundles = /* @__PURE__ */ new Map();\n for (const [walk, pieces] of piecesOf) {\n const route = walk === graph.referencePath ? `\\0${walk}` : pieces.map(routeOf).join(\"|\");\n const group = groupOf(walk);\n const rank = routeRank.get(route) ?? routeRank.size;\n routeRank.set(route, rank);\n const key = `${route}\t${group}`;\n const bundle = bundles.get(key);\n if (bundle) {\n bundle.walks.push(walk);\n } else {\n bundles.set(key, { rank, group, walks: [walk] });\n }\n }\n if (merge && bundles.size === piecesOf.size) {\n return graph;\n }\n const ordered = [...bundles.values()].sort(\n (a, b) => a.rank - b.rank || a.group.localeCompare(b.group)\n );\n if (!merge) {\n return {\n ...graph,\n paths: ordered.flatMap(({ walks }) => walks.flatMap(recordsOf))\n };\n }\n const kept = ordered.flatMap(\n ({ walks }) => recordsOf(walks[0]).map(\n (path) => walks.length > 1 ? { ...path, members: walks } : path\n )\n );\n const keptWalks = new Set(ordered.map((b) => b.walks[0]));\n return {\n ...graph,\n paths: kept,\n anchorPaths: graph.anchorPaths?.filter((p) => keptWalks.has(p.name)),\n pathVisits: graph.pathVisits?.filter((path) => keptWalks.has(path))\n };\n}\n\nexport {\n bundleRoutes\n};\n", "// How much of the drawing a pan or zoom leaves on screen in each axis, or\n// all of it when it is smaller\nconst KEEP_IN_VIEW_PX = 48\n\n// The shift that brings a span starting at `lo`, `size` px long, back to\n// overlapping [0, extent] by `margin` px\nfunction shiftIntoView(lo: number, size: number, extent: number) {\n const margin = Math.min(KEEP_IN_VIEW_PX, size, extent)\n return Math.max(0, margin - (lo + size)) - Math.max(0, lo - (extent - margin))\n}\n\ninterface DrawingBox {\n minX: number\n minY: number\n w: number\n h: number\n}\n\n// layout units to pane px, per axis\nexport interface ScreenTransform {\n scaleX: number\n scaleY: number\n translateX: number\n translateY: number\n}\n\nexport function keepInView(\n bounds: DrawingBox,\n t: ScreenTransform,\n view: { width: number; height: number },\n) {\n return {\n translateX:\n t.translateX +\n shiftIntoView(\n bounds.minX * t.scaleX + t.translateX,\n bounds.w * t.scaleX,\n view.width,\n ),\n translateY:\n t.translateY +\n shiftIntoView(\n bounds.minY * t.scaleY + t.translateY,\n bounds.h * t.scaleY,\n view.height,\n ),\n }\n}\n\nexport function onScreen(\n bounds: DrawingBox,\n t: ScreenTransform,\n view: { width: number; height: number },\n) {\n const left = bounds.minX * t.scaleX + t.translateX\n const top = bounds.minY * t.scaleY + t.translateY\n return (\n left < view.width &&\n left + bounds.w * t.scaleX > 0 &&\n top < view.height &&\n top + bounds.h * t.scaleY > 0\n )\n}\n", "import {\n referenceKnots,\n warpX\n} from \"./chunk-MYDHU2UV.js\";\n\n// src/tubeMap/frame.ts\nvar MIN_TUBE_Y_SCALE = 0.05;\nvar NODE_BOX_PAD = 9;\nfunction squeeze(drawing, usableHeight) {\n const { minY, maxY } = drawing.layout.bounds;\n const h = maxY - minY;\n return drawing.columns && h > 0 ? Math.max(MIN_TUBE_Y_SCALE, Math.min(1, usableHeight / h)) : 1;\n}\nfunction tubeMapFrame(drawing, view) {\n const { scaleX, translateX, translateY } = view;\n const yScale = view.scaleY * squeeze(drawing, view.usableHeight);\n const y = (ty) => (ty - drawing.yOffset) * yScale + translateY;\n const { columns } = drawing;\n if (columns) {\n const knots = referenceKnots(columns, (bp) => bp * scaleX + translateX);\n return { x: (tx) => warpX(knots, tx), y, yScale };\n }\n return { x: (tx) => tx * scaleX + translateX, y, yScale };\n}\nfunction tubeMapNodeAt(drawing, { x, y }, sx, sy) {\n let hit = null;\n drawing.layout.nodes.forEach((node) => {\n if (node.order >= 0 && x(node.x - NODE_BOX_PAD) <= sx && sx <= x(node.x + node.pixelWidth + NODE_BOX_PAD) && y(node.y - NODE_BOX_PAD) <= sy && sy <= y(node.y + node.contentHeight + NODE_BOX_PAD)) {\n hit = node.name;\n }\n });\n return hit;\n}\n\nexport {\n tubeMapFrame,\n tubeMapNodeAt\n};\n", "import { formatBp } from '@jbrowse/bandage-core/graphLabels'\nimport { referenceBoxes, rulerBoxes } from '@jbrowse/bandage-core/tubeMap/axis'\nimport {\n connectorAt,\n drawLitConnector,\n tubeMapConnectors,\n} from '@jbrowse/bandage-core/tubeMap/connectors'\nimport { deviationMarks } from '@jbrowse/bandage-core/tubeMap/deviations'\nimport {\n drawTubeMapHighlight,\n mismatchOnScreen,\n mismatchesLegible,\n tubeMapMismatchAt,\n tubeMapPicture,\n tubeMapTrackAt,\n} from '@jbrowse/bandage-core/tubeMap/draw'\nimport {\n tubeMapFrame,\n tubeMapNodeAt,\n} from '@jbrowse/bandage-core/tubeMap/frame'\nimport { tubeMapNodeColors } from '@jbrowse/bandage-core/tubeMap/nodeColors'\nimport { computed } from 'mobx'\n\nimport {\n NO_VALUE_TUBE,\n PANEL_GAP,\n PANEL_TUBE,\n TINTED_TUBES,\n boxOf,\n memberAt,\n paintPanelHover,\n walksThrough,\n} from '../tubeMapPanels'\nimport { withFitViews } from './fitViews'\nimport { HOVER_BRIGHTEN } from './paneBase'\nimport { trackedDpr } from '../trackedDpr'\n\nimport type { HoveredTube } from './paneBase'\nimport type { Canvas2DRenderer } from '@jbrowse/bandage-core/renderer/Canvas2DRenderer'\nimport type { RenderBatch } from '@jbrowse/bandage-core/renderer/types'\nimport type { TubeMapPicture } from '@jbrowse/bandage-core/tubeMap/draw'\nimport type { TubeMapTransform } from '@jbrowse/bandage-core/tubeMap/frame'\nimport type { TubeMapMismatch } from '@jbrowse/bandage-core/tubeMap/mismatches'\n\nconst MAX_SHOWN_BASES = 20\n// a squeezed stack of panels thins no further, as one tube map does\nconst MIN_PANEL_Y_SCALE = 0.05\n\nconst MAX_LISTED = 6\n\nfunction listed(names: string[]) {\n const more = names.length - MAX_LISTED\n return more > 0\n ? `${names.slice(0, MAX_LISTED).join(', ')} and ${more} more`\n : names.join(', ')\n}\n\nfunction mismatchText(m: TubeMapMismatch) {\n if (m.kind === 'deletion') {\n return `deletion of ${formatBp(m.length)}`\n }\n if (m.kind === 'substitution') {\n return `substitution ${m.seq}`\n }\n const seq = m.seq ?? ''\n const shown =\n seq.length > MAX_SHOWN_BASES ? `${seq.slice(0, MAX_SHOWN_BASES)}\u2026` : seq\n return `insertion of ${formatBp(seq.length)} ${shown}`.trim()\n}\n\n// Which kinds of read mark are on screen, stopping once all three are found\nfunction mismatchKindsShown(\n picture: TubeMapPicture | undefined,\n frame: TubeMapTransform | undefined,\n width: number,\n) {\n const kinds = { substitution: false, insertion: false, deletion: false }\n if (picture && frame && mismatchesLegible(frame.yScale)) {\n let missing = 3\n for (const m of picture.mismatches) {\n if (!kinds[m.kind] && mismatchOnScreen(m, { x: frame.x, width })) {\n kinds[m.kind] = true\n if (--missing === 0) {\n break\n }\n }\n }\n }\n return kinds\n}\n\nexport const withTubeMapViews = withFitViews\n .views(self => ({\n get tubeMapFrame() {\n const drawing = self.layoutResult?.tubeMap\n return drawing\n ? tubeMapFrame(drawing, {\n ...self.screenTransform,\n usableHeight: self.usableHeight,\n })\n : undefined\n },\n // the reference ruler under the tubes, unless the linear view's ruler\n // is already the axis\n get tubeMapRulerBoxes() {\n const reference = self.tubeMapReference\n return reference && !self.hostPlacesX && !self.layoutResult?.tubeMapPanels\n ? rulerBoxes(reference)\n : undefined\n },\n // Split on the reference axis, the panels share x, so one ruler under\n // the last reads for them all; on the own axis each panel has its own\n get tubeMapPanelRulerBoxes() {\n const { layoutResult } = self\n const last = layoutResult?.tubeMapPanels?.at(-1)\n return last && layoutResult?.referenceAxis && !self.hostPlacesX\n ? rulerBoxes(referenceBoxes(last.result.tubeMap))\n : undefined\n },\n // The connectors run from the top of the pane down to the tubes' top\n get connectorZoneBottom() {\n const picture = self.tubeMapPicture\n const frame = this.tubeMapFrame\n return picture && frame ? frame.y(picture.bounds.minY) - 2 : 0\n },\n // The bands' tops follow every frame of a pan in the linear view and\n // their bottoms every pan of the tubes\n get tubeMapConnectors() {\n const boxes = self.tubeMapConnectedBoxes\n const frame = this.tubeMapFrame\n const bp = boxes && frame ? self.hostBpFrame : undefined\n return boxes && frame && bp\n ? tubeMapConnectors(\n boxes,\n b => b * bp.scale + bp.translateX,\n frame.x,\n self.paneWidth,\n )\n : []\n },\n // What each panel of a split tube map draws, which no pan or hover\n // changes: its picture, its tubes, its boxes' tints and its folded\n // variants\n get tubeMapPanelPictures() {\n const panels = self.layoutResult?.tubeMapPanels\n if (!panels) {\n return undefined\n }\n const { field } = self.facetSetting\n return panels.map(panel => {\n const drawing = panel.result.tubeMap\n const { graph, coarse } = drawing\n return {\n panel,\n label:\n panel.label ??\n (field === 'walk' ? self.walkLabel(panel.paths[0]!) : panel.key),\n picture: tubeMapPicture(drawing),\n tubeColors: self.tubeColorsOf(graph, drawing.pathColors),\n nodeColors: self.tubeMapNodeColors\n ? tubeMapNodeColors(\n graph,\n self.effectiveColorScheme,\n self.referenceRamp,\n )\n : undefined,\n deviations: coarse ? deviationMarks(drawing, coarse.deviations) : [],\n }\n })\n },\n }))\n .views(self => ({\n // The node the pointer is on: inside a merged run, the member at the\n // pointer's bp, so a run spanning the window counts what is under it\n get hoveredMember() {\n const id = self.hoveredNode\n const members =\n id === null ? undefined : self.hoverDrawing?.members.get(id)\n if (!members) {\n return id\n }\n const at = self.hoveredAt\n const i = self.hoveredPanel\n const under = i === null ? undefined : this.tubeMapPanelViews?.[i]\n // sparse, so forEach, which skips its holes, as tubeMapNodeAt does\n let box: { x: number; pixelWidth: number } | undefined\n under?.panel.result.tubeMap.layout.nodes.forEach(n => {\n if (n.name === id) {\n box = n\n }\n })\n const member =\n at && under && box\n ? memberAt(\n members,\n m => self.nodeSpan(m),\n under.frame.x(box.x),\n under.frame.x(box.x + box.pixelWidth),\n at.x,\n )\n : undefined\n return member ?? members[0]\n },\n // For the hovered box, the box each panel draws it in and how many of\n // that panel's haplotypes pass through it: a frequency per group\n get tubeMapPanelHover() {\n const id = self.hoveredNode\n const pictures = self.tubeMapPanelPictures\n if (id === null || !pictures) {\n return undefined\n }\n const node = this.hoveredMember ?? id\n return pictures.map(({ panel }) => {\n const drawing = panel.result.tubeMap\n const box = boxOf(drawing, node)\n return box ? { box, ...walksThrough(drawing.graph, box) } : undefined\n })\n },\n // apart from the pictures, so a lane row's hover redraws no panel\n get tubeMapPanelTubeColors() {\n return self.tubeMapPanelPictures?.map(({ panel, tubeColors }) => {\n const { graph } = panel.result.tubeMap\n return self.fadeUnhovered(\n tubeColors,\n graph.paths ?? [],\n graph.referencePath,\n )\n })\n },\n // Each panel through the pane's transform at its place down the stack.\n // On the reference axis the stack squeezes into the pane as one map does.\n get tubeMapPanelViews() {\n const pictures = self.tubeMapPanelPictures\n const tubeColors = this.tubeMapPanelTubeColors\n const layout = self.layoutResult\n if (!pictures || !tubeColors || !layout) {\n return undefined\n }\n // the titles keep their px and the drawings squeeze into the rest\n const titles = pictures.length * PANEL_GAP\n const drawings = pictures.reduce((h, p) => h + p.panel.height, 0)\n const usable = self.usableHeight - titles\n const yScale =\n self.scaleY *\n (layout.referenceAxis && drawings > 0\n ? Math.max(MIN_PANEL_Y_SCALE, Math.min(1, usable / drawings))\n : 1)\n let y = self.translateY\n return pictures.map((p, i) => {\n const { panel } = p\n const minY = panel.result.extent?.minY ?? 0\n const titleTop = y\n const top = titleTop + PANEL_GAP\n y = top + panel.height * yScale\n return {\n ...p,\n tubeColors: tubeColors[i]!,\n frame: tubeMapFrame(panel.result.tubeMap, {\n scaleX: self.scaleX,\n translateX: self.translateX,\n scaleY: yScale,\n translateY: top - minY * yScale,\n usableHeight: Infinity,\n }),\n titleTop,\n top,\n bottom: y,\n }\n })\n },\n // the panel a pane y falls in, its title's gap included\n tubeMapPanelAt(sy: number) {\n const i =\n this.tubeMapPanelViews?.findIndex(\n v => v.titleTop <= sy && sy <= v.bottom,\n ) ?? -1\n return i < 0 ? null : i\n },\n }))\n .views(self => ({\n // The hover alone, onto a transparent canvas over the drawing, so a\n // pointer move repaints what it lights rather than every stroke under\n // it. `batch` is what the canvas below holds.\n paintHover(r: Canvas2DRenderer, batch: RenderBatch) {\n const picture = self.tubeMapPicture\n const frame = self.tubeMapFrame\n const node = self.hoverLayerNode\n if (picture && frame) {\n const { ctx, canvas } = r\n const dpr = trackedDpr(self.paneWidth, self.canvasHeight)\n ctx.setTransform(1, 0, 0, 1, 0, 0)\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n const panels = self.tubeMapPanelViews\n if (panels) {\n paintPanelHover(ctx, panels, self.tubeMapPanelHover, {\n width: self.paneWidth,\n lit: node !== null,\n })\n } else {\n drawTubeMapHighlight(ctx, picture, {\n ...frame,\n width: self.paneWidth,\n highlightNode: node,\n })\n }\n drawLitConnector(\n ctx,\n self.tubeMapConnectors,\n self.connectorZoneBottom,\n node,\n )\n ctx.setTransform(1, 0, 0, 1, 0, 0)\n } else {\n r.uploadGeometry(batch)\n r.setNodeHighlights(\n node === null ? new Map() : new Map([[node, HOVER_BRIGHTEN]]),\n )\n r.setEdgeHighlight(self.hoveredEdge, HOVER_BRIGHTEN)\n r.updateTransform(self.paintTransform)\n r.renderHighlights()\n }\n },\n }))\n .views(self => {\n // Compared by value: the marks in view are read off the transform, and\n // the legend should redraw when a kind comes or goes, not every pan frame.\n // The rest of the key reads no transform, so a pan leaves it cached.\n const sameJson = (a: unknown, b: unknown) =>\n JSON.stringify(a) === JSON.stringify(b)\n const marksInView = computed(\n () =>\n mismatchKindsShown(\n self.layoutResult?.tubeMapPanels !== undefined\n ? undefined\n : self.tubeMapPicture,\n self.tubeMapFrame,\n self.paneWidth,\n ),\n { equals: sameJson },\n )\n const keys = computed(\n () => {\n const layout = self.layoutResult\n const split = layout?.tubeMapPanels !== undefined\n const reads = split ? [] : (layout?.tubeMap?.layout.reads ?? [])\n const paths = self.drawnGraph?.paths ?? []\n const coloring = self.tubeMapColoring\n const kind = self.tubeColorKind\n return {\n bundled: paths.some(p => p.members),\n // tubes in a column's hues, keyed value by value\n values:\n kind === 'value' && coloring\n ? [\n ...[...coloring.palette].map(([value, color]) => ({\n value,\n color,\n })),\n ...(coloring.unvalued\n ? [\n {\n value: `${coloring.field}: none`,\n color: NO_VALUE_TUBE,\n },\n ]\n : []),\n ]\n : undefined,\n // tubes coloured reference and haplotype rather than per walk\n roles: kind === 'role' || kind === 'tinted',\n haplotypeTube: kind === 'tinted' ? TINTED_TUBES[0]! : PANEL_TUBE,\n logWidths: layout?.tubeMap !== undefined && !layout.referenceAxis,\n foldBp:\n self.tubeMapDeviations.length > 0 ? self.tubeMapFold : undefined,\n forwardReads: reads.some(r => !r.is_reverse),\n reverseReads: reads.some(r => r.is_reverse),\n }\n },\n { equals: sameJson },\n )\n return {\n // What the tube map's legend has to explain: that on the own axis a\n // box is as wide as the log of its length, the fold its walks' ticks\n // stand for, the reads' strands, and the marks on the reads in view\n get tubeMapKeys() {\n return { ...keys.get(), ...marksInView.get() }\n },\n }\n })\n .views(self => ({\n // The drawing under a pane y: its panel's while the map is split\n tubeMapUnder(sy: number) {\n const views = self.tubeMapPanelViews\n if (views) {\n const i = self.tubeMapPanelAt(sy)\n const v = i === null ? undefined : views[i]\n return v && { drawing: v.panel.result.tubeMap, ...v }\n }\n const drawing = self.layoutResult?.tubeMap\n const picture = self.tubeMapPicture\n const frame = self.tubeMapFrame\n return drawing && picture && frame\n ? { drawing, picture, frame }\n : undefined\n },\n tubeMapNodeAt(sx: number, sy: number) {\n const under = this.tubeMapUnder(sy)\n return (\n (under ? tubeMapNodeAt(under.drawing, under.frame, sx, sy) : null) ??\n connectorAt(self.tubeMapConnectors, self.connectorZoneBottom, sx, sy) ??\n null\n )\n },\n // The tube under a pane point, and the mismatch mark on it if any\n tubeAt(sx: number, sy: number): HoveredTube | null {\n const under = this.tubeMapUnder(sy)\n if (!under) {\n return null\n }\n const { picture, frame } = under\n const mismatch = tubeMapMismatchAt(picture, frame, sx, sy)\n const track = mismatch?.readId ?? tubeMapTrackAt(picture, frame, sx, sy)\n return track === undefined ? null : { track, mismatch }\n },\n // A tube names its haplotype; a read its MAPQ and strand, and the\n // mismatch under the pointer\n get hoveredTubeText() {\n const tube = self.hoveredTube\n const layout = self.layoutResult?.tubeMap?.layout\n const read = tube && layout?.reads.find(r => r.id === tube.track)\n if (tube && read) {\n const mapq = read.mapping_quality\n return {\n label: read.name ?? 'read',\n readout: [\n `MAPQ ${mapq ?? 'unknown'}`,\n `${read.is_reverse ? 'reverse' : 'forward'} strand`,\n ...(tube.mismatch ? [mismatchText(tube.mismatch)] : []),\n ].join(', '),\n }\n }\n const path = tube ? self.hoverGraph?.paths?.[tube.track] : undefined\n const members = path?.members\n return members\n ? {\n label: `${members.length} haplotypes`,\n readout: `one route: ${listed(members.map(m => self.walkLabel(m)))}`,\n }\n : path\n ? { label: self.walkLabel(path.name), readout: 'haplotype' }\n : undefined\n },\n }))\n", "import { segmentAt } from '@jbrowse/bandage-core/layout/walkStrip'\nimport { anchorFromPaths } from '@jbrowse/bandage-core/pathAnchoring'\nimport { clampZoom, fittedTranslateY } from '@jbrowse/bandage-core/pipeline'\nimport { zoomAbout } from '@jbrowse/bandage-core/viewport'\nimport { getSession, isSessionModelWithWidgets } from '@jbrowse/core/util'\nimport { isAlive } from '@jbrowse/mobx-state-tree'\n\nimport { keepInView, onScreen } from './keepInView'\nimport {\n blendInto,\n canMorph,\n morphStarts,\n motionAllowed,\n routeStarts,\n runMorph,\n} from './morph'\nimport { VIEWPORT_DEBOUNCE_MS, forceLayouts } from './paneBase'\nimport { withTubeMapViews } from './tubeMapViews'\nimport { nodeOwnLocation } from '../../launchFromGraph/contributors'\nimport { withRows } from '../../launchFromGraph/linearViewTarget'\nimport { withLayer } from '../graphLayers'\nimport { colorOfScheme } from '../nodeColor'\nimport { sizeOfNodeWidth } from '../nodeSize'\n\nimport type { GraphGrammar } from './graphViews'\nimport type { ScreenTransform } from './keepInView'\nimport type { MorphEntering } from './morph'\nimport type { HoveredTube, TubeMapRoutes } from './paneBase'\nimport type { GraphLayer } from '../graphLayers'\nimport type { HoverHighlight } from '../hoverHighlight'\nimport type { WalkRowGroupBy } from '../walkRowGroups'\nimport type { BubbleSpread } from '@jbrowse/bandage-core/bubbleSpreads'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport type { FacetSetting } from '@jbrowse/bandage-core/facetGrid'\nimport type { LayoutEngineKind } from '@jbrowse/bandage-core/layoutEngines'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { NodeWidth } from '@jbrowse/bandage-core/nodeWidths'\nimport type { Bounds } from '@jbrowse/bandage-core/pipeline'\nimport type { RenderBatch } from '@jbrowse/bandage-core/renderer/types'\nimport type { LayoutResult } from '@jbrowse/bandage-core/types'\nimport type {\n WalkEncoding,\n WalkLayer,\n} from '@jbrowse/bandage-core/walkEncoding'\n\nexport const withSettingActions = withTubeMapViews\n .actions(() => ({\n // each host overrides: a view assigns its props, a track display writes\n // its config. Its own block, so the setters below reach the override\n // through `self`\n writeGrammar(_settings: GraphGrammar) {},\n }))\n .actions(self => ({\n // A pan or zoom never leaves the drawing wholly off screen, where\n // nothing says which way it went. A host's x is its own.\n keepDrawingInView() {\n const bounds = self.layoutBounds\n const view = self.viewBox\n if (\n !bounds ||\n self.viewportOwner === 'fit' ||\n !self.paneMeasured ||\n view.width <= 0 ||\n view.height <= 0\n ) {\n return\n }\n const t = keepInView(bounds, self, view)\n if (self.viewportOwner !== 'host') {\n self.translateX = t.translateX\n }\n self.translateY = t.translateY\n },\n }))\n .actions(self => {\n // a stated reference-position domain, kept through schemes that take\n // none so switching back restores it\n let keptDomain: typeof self.statedColorDomain\n return {\n setColorScheme(scheme: ColorScheme) {\n if (\n self.statedColorDomain ||\n self.chosenColorScheme === 'reference-position'\n ) {\n keptDomain = self.statedColorDomain\n }\n self.writeGrammar({ color: colorOfScheme(scheme, keptDomain) })\n },\n }\n })\n .actions(self => ({\n setError(error: unknown) {\n self.error = error\n self.isLoading = false\n self.statusMessage = ''\n },\n finishLoading() {\n self.isLoading = false\n self.statusMessage = ''\n },\n setStatusMessage(message: string) {\n self.statusMessage = message\n },\n setFetchMs(ms: number) {\n self.lastFetchMs = ms\n },\n setLayoutMs(ms: number) {\n self.lastLayoutMs = ms\n },\n setGeometryMetrics(\n ms: number,\n batch: RenderBatch,\n built: { scale: number; bounds: Bounds },\n ) {\n self.lastGeometryMs = ms\n self.lastGeometryStrokeCount = batch.nodeStrokes.length\n self.builtViewport = { ...built, viewportDirty: self.viewportDirty }\n self.drawnBatch = batch\n },\n markPainted() {\n self.paintedViewport = self.builtViewport\n },\n setLayoutQuality(quality: number) {\n self.layoutQuality = quality\n },\n setLayoutEngine(engine: LayoutEngineKind) {\n self.layoutEngine = engine\n },\n setLinearLayout(linear: boolean) {\n self.linearLayout = linear\n },\n setLayoutMode(mode: LayoutModeValue) {\n self.writeGrammar({ layoutMode: mode })\n },\n setHover(hover: HoverHighlight) {\n self.writeGrammar({ hover })\n if (!self.hoverLightsEverything) {\n self.hoveredEdge = null\n }\n },\n // Re-anchor in place rather than re-parsing: the coordinate walk is\n // already recorded on the graph, and only which path counts as rank 0\n // changes. The caller recomputes the layout, the same way it does after\n // setLayoutMode. An rGFA is left alone \u2014 its coordinates are not derived.\n setReferencePath(name: string) {\n self.referencePath = name\n const graph = self.graph\n if (graph?.anchoredBy === 'paths') {\n const reanchored = anchorFromPaths(graph, name)\n forceLayouts.inherit(graph, reanchored)\n self.graph = reanchored\n }\n },\n setLayer(layer: GraphLayer, on: boolean) {\n self.writeGrammar({ layers: withLayer(self.grammar.layers, layer, on) })\n },\n setShowPerf(show: boolean) {\n self.showPerf = show\n },\n setBubbleSpread(spread: BubbleSpread) {\n self.bubbleSpread = spread\n },\n setMaxGraphNodes(limit: number) {\n self.maxGraphNodes = limit\n },\n setNodeWidth(width: NodeWidth) {\n self.writeGrammar({\n size: sizeOfNodeWidth(width, self.contigThickness),\n })\n },\n setTubeMapFold(bp: number) {\n self.tubeMapFold = bp\n },\n setTubeMapRoutes(routes: TubeMapRoutes) {\n self.tubeMapRoutes = routes\n },\n setTubeMapColorBy(field: string) {\n self.tubeMapColorBy = field\n },\n setGeneTrackId(trackId: string) {\n self.geneTrackId = trackId\n },\n setRepeatTrackId(trackId: string) {\n self.repeatTrackId = trackId\n },\n setRepeatKey(key: string) {\n self.repeatKey = key\n },\n setWalkLayers(layers: WalkLayer[]) {\n self.walkLayers = layers\n },\n // Lift the walks named, in that order, keeping the colour any of them\n // already had\n liftWalks(names: string[]) {\n const had = new Map(self.walkLayers.map(l => [l.walk, l]))\n self.walkLayers = names.map(walk => had.get(walk) ?? { walk })\n },\n // A picker's set, which lists only this cut's walks: the lifted walks it\n // cannot show keep their layers for when a cut has them again\n liftAmongChoices(names: string[]) {\n const shown = new Set(self.walkChoices.map(c => c.name))\n this.liftWalks([\n ...names,\n ...self.walkLayers.map(l => l.walk).filter(walk => !shown.has(walk)),\n ])\n },\n // The field the panels split on; a change of field drops the order\n // written for the old one and keeps the column count\n // Panels off clears only panels, leaving a walk-row grouping the facet\n // holds instead\n setFacet(field: FacetSetting['field']) {\n const facet = self.facetSetting\n if (field === '') {\n if (facet.field !== '') {\n self.writeGrammar({ facet: {} })\n }\n } else {\n self.writeGrammar({\n facet: {\n ...facet,\n field,\n domain: field === facet.field ? facet.domain : [],\n },\n })\n }\n },\n toggleWalk(walk: string) {\n const layers = self.walkLayers\n self.walkLayers = layers.some(l => l.walk === walk)\n ? layers.filter(l => l.walk !== walk)\n : [...layers, { walk }]\n },\n setWalkColor(walk: string, color: Partial<WalkEncoding>) {\n self.walkLayers = self.walkLayers.map(l =>\n l.walk === walk ? { ...l, color: { ...l.color, ...color } } : l,\n )\n },\n setWalkRowSamples(samples: string[] | undefined) {\n self.writeGrammar({ rows: samples ? { kept: samples } : {} })\n },\n setWalkRowGroupBy(groupBy: WalkRowGroupBy | undefined) {\n if (groupBy || self.walkRowGroupBy) {\n self.writeGrammar({ facet: groupBy ?? {} })\n }\n },\n // Pair with a linear view for the hover sync, without ever repointing an\n // existing pairing: a graph launched *from* an LGV is already paired with\n // it, and stealing that would break the sync the user came in on. So a\n // launch out of the graph only claims the slot when it is empty.\n //\n // A slot naming a view that has been closed is empty too. Held, the view\n // the graph opened next never got its hover, since a highlight is drawn\n // only in the paired view.\n pairWithLinearView(viewId: string) {\n const paired = self.connectedViewId\n const stillOpen =\n paired !== undefined &&\n withRows([...getSession(self).views]).some(\n view => (view as { id?: unknown }).id === paired,\n )\n if (!stillOpen) {\n self.connectedViewId = viewId\n }\n },\n setHoveredNode(nodeId: string | null, at?: { x: number; y: number }) {\n self.hoveredNode = nodeId\n self.hoveredAt = nodeId === null ? null : (at ?? null)\n },\n setHoveredPanel(panel: number | null) {\n self.hoveredPanel = panel\n },\n setHoveredTube(tube: HoveredTube | null) {\n const was = self.hoveredTube\n if (tube?.track !== was?.track || tube?.mismatch !== was?.mismatch) {\n self.hoveredTube = tube\n }\n },\n setHoveredRowWalks(walks: string[]) {\n if (walks.join('\\n') !== self.hoveredRowWalks.join('\\n')) {\n self.hoveredRowWalks = walks\n }\n },\n setHoveredWalkRow(name: string | null) {\n self.hoveredWalkRow = name\n },\n setHoveredBubble(bubble: MinigraphBubble | null) {\n self.hoveredBubble = bubble\n },\n setPointerInPane(inside: boolean) {\n self.pointerInPane = inside\n },\n setWalkStrip(show: boolean) {\n this.setLayer('walkStrip', show)\n self.stripHover = null\n },\n // The pointer over the strip: the node under it becomes the hovered\n // node, so the drawing, the tooltip and a linked linear view follow\n setStripHover(hover: { row: string; offset: number } | null) {\n self.stripHover = hover\n const bars = self.walkStripRows\n const frame = self.walkStripFrame\n const row =\n hover && bars\n ? [bars.reference, ...bars.rows].find(r => r.name === hover.row)\n : undefined\n const node =\n row && frame && self.graph\n ? segmentAt(self.graph, row, hover!.offset, frame.scaleX)\n : undefined\n self.hoveredNode = node ?? null\n },\n setLegendSize(size: { width: number; height: number }) {\n self.legendSize = size\n },\n setHoveredEdge(edgeIdx: number | null) {\n self.hoveredEdge = self.hoverLightsEverything ? edgeIdx : null\n },\n setSelectedNode(nodeId: string | null) {\n self.selectedNode = nodeId\n },\n setDraggingNode(nodeId: string | null) {\n self.draggingNode = nodeId\n },\n setPanning(panning: boolean) {\n self.isPanning = panning\n },\n stopDragging() {\n self.draggingNode = null\n self.isPanning = false\n },\n clearHover() {\n self.hoveredNode = null\n self.hoveredAt = null\n self.hoveredTube = null\n self.hoveredPanel = null\n self.hoveredWalkRow = null\n self.hoveredBubble = null\n self.hoveredEdge = null\n },\n // Everything that names a part of the current graph. Reset when the graph\n // is replaced, and by clearGraph.\n clearInteractionState() {\n this.clearHover()\n self.hoveredRowWalks = []\n self.stripHover = null\n self.selectedNode = null\n self.draggingNode = null\n self.isPanning = false\n },\n showNodeDetails(nodeId: string) {\n const node = self.nodeById?.get(nodeId)\n if (node) {\n const session = getSession(self)\n const region = self.graphRegion\n // refName/start/end are what makes the widget show a location rather\n // than a bare id, and they are the same span the linear view\n // highlights on hover.\n const span = region ? self.nodeSpan(nodeId) : undefined\n if (isSessionModelWithWidgets(session)) {\n session.showWidget(\n session.addWidget('BaseFeatureWidget', 'baseFeature', {\n featureData: {\n id: node.id,\n name: node.name,\n length: node.length,\n depth: node.depth,\n rank: node.stable?.rank,\n stableName: node.stable?.refName,\n // The assembly that contributed this segment, split off the\n // stable name. On an HPRC graph this is the only thing that\n // says which of 400-odd haplotypes an allele came from.\n contributingAssembly: nodeOwnLocation(node)?.sample,\n // and the haplotype, where the graph's names state one:\n // the assembly to load to open this node on its own\n // coordinates\n contributingHaplotype: nodeOwnLocation(node)?.haplotype,\n // Every haplotype whose path visits it, which only a path\n // GFA records. Absent on an rGFA, where\n // `contributingAssembly` is the first-seen assembly alone.\n sampleCount: node.samples?.length,\n samples: node.samples,\n ...(region && span\n ? {\n refName: region.refName,\n assemblyName: region.assemblyName,\n start: span.start,\n end: span.end,\n }\n : {}),\n },\n }),\n )\n }\n }\n },\n\n // A gesture on a hosted graph moves the linear view, and the frame\n // clock brings x back here; y stays the pane's own.\n setTransform(s: number, tx: number, ty: number) {\n const { host } = self\n if (self.viewportOwner === 'host' && host) {\n host.horizontalScroll(self.translateX - tx)\n } else {\n self.viewportOwner = 'user'\n self.scale = clampZoom(s)\n self.translateX = tx\n }\n self.translateY = ty\n self.keepDrawingInView()\n },\n zoom(factor: number, centerX: number, centerY: number) {\n const { host } = self\n if (self.viewportOwner === 'host' && host) {\n host.zoomTo(host.bpPerPx / factor, centerX)\n return\n }\n self.viewportOwner = 'user'\n const t = zoomAbout(self, factor, centerX, centerY, self.pixelRows)\n self.scale = t.scale\n self.translateX = t.translateX\n self.translateY = t.translateY\n self.keepDrawingInView()\n },\n setViewportDirty() {\n self.viewportRebuildPending = false\n self.viewportDirty++\n },\n // The positions themselves moved, as opposed to the window onto them.\n setPositionsDirty() {\n self.positionsVersion++\n },\n // one frame of a morph: the positions moved in place, and what it brings\n // in has faded in this far, in one rebuild\n setMorphFrame(entering: MorphEntering | undefined) {\n self.morphEntering = entering\n self.positionsVersion++\n },\n zoomToFit() {\n // A host owns x, so a fit while hosted places the rows only.\n if (self.viewportOwner === 'host') {\n const bounds = self.layoutBounds\n const { usableHeight } = self\n if (bounds && usableHeight > 0) {\n self.translateY = fittedTranslateY(\n bounds,\n usableHeight,\n self.scaleY,\n self.fitPads.top,\n )\n }\n return\n }\n // Nothing to fit into before the canvas is measured. The fit autorun\n // runs again once width lands, so skipping beats persisting a negative\n // scale into the session snapshot.\n const fit = self.fittedTransform\n if (fit) {\n self.scale = fit.scale\n self.translateX = fit.translateX\n self.translateY = fit.translateY\n }\n },\n clearPerfMetrics() {\n self.lastFetchMs = undefined\n self.lastLayoutMs = undefined\n self.lastGeometryMs = undefined\n self.lastGeometryStrokeCount = undefined\n self.builtViewport = undefined\n },\n }))\n .actions(self => ({\n // The frame clock. Unclamped, since clampZoom's floor is there to keep a\n // scale finite and 1 / bpPerPx already is; clamped, a whole-chromosome\n // window would stop lining up.\n hostTransform(scale: number, translateX: number) {\n const engaging = self.viewportOwner !== 'host'\n if (engaging) {\n self.viewportOwner = 'host'\n }\n self.scale = scale\n self.translateX = translateX\n if (engaging) {\n self.zoomToFit()\n }\n },\n // A new layout under a view the user placed. One that replaces a\n // drawing is fitted unless both are on the reference's bp and some of it\n // is still on screen: a force run or a fresh cut draws in coordinates of\n // its own, where the old transform shows nothing in particular. The\n // first layout after a restored session keeps the saved view, pulled\n // into the pane once its width is known.\n followNewLayout(previous: LayoutResult | undefined) {\n const bounds = self.layoutBounds\n if (\n self.viewportOwner !== 'user' ||\n !bounds ||\n previous === self.layoutResult\n ) {\n return\n }\n const keepsAxis = previous?.referenceAxis === true && self.xIsReferenceBp\n if (\n previous === undefined ||\n (keepsAxis &&\n (!self.paneMeasured || onScreen(bounds, self, self.viewBox)))\n ) {\n self.keepDrawingInView()\n } else {\n self.viewportOwner = 'fit'\n self.zoomToFit()\n }\n },\n // Faceting changes the box the drawing is fitted into, so a drawing the\n // user placed is fitted again; a host keeps its x\n refitView() {\n if (self.viewportOwner === 'user') {\n self.viewportOwner = 'fit'\n }\n self.zoomToFit()\n },\n // A drawing still on the reference stays where the host left it; one\n // whose x no longer means bp is refit.\n releaseHost() {\n if (self.viewportOwner === 'host') {\n if (self.xIsReferenceBp) {\n self.viewportOwner = 'user'\n } else {\n self.viewportOwner = 'fit'\n self.zoomToFit()\n }\n }\n },\n }))\n .actions(self => {\n // Pan/zoom can wait: the geometry on screen is still correct while the\n // gesture runs (the viewport bounds carry 20% overscan), so rebuilding is\n // deferred until the user settles.\n function scheduleViewportDirty() {\n clearTimeout(self.viewportDirtyTimer)\n self.viewportRebuildPending = true\n self.viewportDirtyTimer = setTimeout(() => {\n if (isAlive(self)) {\n self.setViewportDirty()\n }\n }, VIEWPORT_DEBOUNCE_MS)\n }\n\n // A node drag cannot wait \u2014 the node only moves on screen when its\n // geometry is rebuilt \u2014 but a bump costs a full geometry rebuild plus\n // invalidation of both hit-detection indexes, and mousemove fires in\n // bursts well above the frame rate. Coalescing to the next frame keeps the\n // drag live while bounding that work to once per frame instead of once\n // per event.\n function requestPositionsDirtyFrame() {\n cancelAnimationFrame(self.positionsDirtyFrame)\n self.positionsDirtyFrame = requestAnimationFrame(() => {\n if (isAlive(self)) {\n self.setPositionsDirty()\n }\n })\n }\n\n let morph: { frame: number; finish: () => void } | undefined\n\n function stopMorph() {\n if (morph) {\n cancelAnimationFrame(morph.frame)\n morph = undefined\n }\n }\n\n function finishMorph() {\n const running = morph\n stopMorph()\n running?.finish()\n }\n\n return {\n // Slides the drawing from what `previous` drew under `before` to the\n // layout just landed, so a re-cut or a relayout reads as one picture\n // moving rather than a jump. Positions move in place as a drag moves\n // them, a frame at a time; anything new grows out of its neighbours.\n morphFrom(previous: LayoutResult | undefined, before: ScreenTransform) {\n const next = self.layoutResult\n // the layout cache handing back the drawing on screen leaves its\n // morph running\n if (previous === next) {\n return\n }\n // The cache keeps the layouts a morph blends in place, so one cut\n // short is still finished, and this one starts from a copy of where\n // it had got to on screen\n const shown =\n morph && previous\n ? structuredClone(previous.nodePositions)\n : previous?.nodePositions\n finishMorph()\n const graph = self.graph\n if (\n !previous ||\n !shown ||\n !next ||\n !graph ||\n !canMorph(previous, next, graph.nodes.length, !!self.facetGrid) ||\n !motionAllowed()\n ) {\n return\n }\n // the fit autorun lands after this action; the start needs its frame\n if (self.viewportOwner === 'fit') {\n self.zoomToFit()\n }\n const routes = next.deletionRoutes ?? {}\n const ends = structuredClone({ nodes: next.nodePositions, routes })\n const nodeStarts = morphStarts(\n shown,\n before,\n next.nodePositions,\n self.screenTransform,\n graph.edges,\n )\n const starts = {\n nodes: nodeStarts,\n routes: routeStarts(routes, graph.edges, nodeStarts, ends.nodes),\n }\n const ids = new Set(\n Object.keys(next.nodePositions).filter(id => !shown[id]),\n )\n const blend = (t: number) => {\n blendInto(next.nodePositions, starts.nodes, ends.nodes, t)\n blendInto(routes, starts.routes, ends.routes, t)\n if (isAlive(self)) {\n self.setMorphFrame(\n t < 1 && ids.size > 0\n ? { layout: next, ids, alpha: t }\n : undefined,\n )\n }\n }\n blend(0)\n morph = runMorph(\n blend,\n () => isAlive(self) && self.layoutResult === next,\n () => {\n morph = undefined\n },\n )\n },\n finishMorph,\n // Moves the position objects IN PLACE, which is the one thing\n // jbrowse-components' upload invariant says not to do (\"per-region\n // upload values must be freshly constructed, never mutated \u2014 backends\n // diff by reference identity\"), so it is worth saying why this is not\n // that case and what it costs instead.\n //\n // Nothing here diffs by identity: the geometry is rebuilt wholesale and\n // handed over as one batch, so `nodePositions` identity is not a\n // protocol between the model and the backend the way a per-region map\n // is. What identity DOES drive is the fit: the zoom-to-fit autorun and\n // `layoutBounds` \u2014 and so `canvasHeight` \u2014 key off `layoutResult`, and\n // they mean \"a new LAYOUT arrived\", not \"a node moved\". Publishing a\n // fresh positions record per frame of a drag would refit the drawing\n // and resize the pane under the cursor, sixty times a second.\n //\n // So the change is announced by `positionsVersion` instead, and every\n // cache that would otherwise trust identity takes it as a key. The cost\n // of that trade is that the version is a thing to remember: a caller\n // that mutates here and does not bump it gets stale curves, stale hit\n // boxes and stale labels, silently. Everything downstream of it is\n // reached from this one action.\n moveNode(nodeId: string, dx: number, dy: number) {\n finishMorph()\n const positions = self.layoutResult?.nodePositions\n if (positions?.[nodeId]) {\n for (const seg of positions[nodeId]) {\n seg.x += dx\n seg.y += dy\n }\n requestPositionsDirtyFrame()\n }\n },\n scheduleViewportDirty,\n }\n })\n", "const host = JBrowseExports[\"@jbrowse/core/util/unzip\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/util/unzip\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const unzip = /* @__PURE__ */ read(\"unzip\")\nexport default host && host.__esModule ? host.default : host", "import { unzip } from '@jbrowse/core/util/unzip'\n\n// A GFA's text, from its bytes as read, gzipped (by its magic bytes) or not\nexport async function gfaText(bytes: Uint8Array) {\n const gzipped = bytes[0] === 0x1f && bytes[1] === 0x8b\n return new TextDecoder().decode(gzipped ? await unzip(bytes) : bytes)\n}\n", "import {\n backboneNodes,\n backbonePositions,\n overlapsWindow,\n} from '@jbrowse/bandage-core/anchoredNodes'\nimport {\n walkRowLabels,\n walkRowsExtent,\n} from '@jbrowse/bandage-core/layout/walkRowLayout'\nimport { loadGraph } from '@jbrowse/bandage-core/pipeline'\n\nimport { walkPath } from '../RgfaTabixAdapter/walkRowRuns.ts'\n\nimport type { WalkCut } from '../RgfaTabixAdapter/walkRowRuns.ts'\nimport type { GraphTables } from '@jbrowse/bandage-core/gfa/graphTables'\nimport type { WalkRows } from '@jbrowse/bandage-core/layout/walkRows'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\n\n/**\n * The Graph a walk-rows cut parses to: nodes with their depth over every\n * walk, links, and the reference walk, with every other walk named and\n * stepless. The rows come from the cut's runs, so no object per step is\n * built for them; a layout that draws nodes parses the cut whole.\n */\nexport function walkRowsGraph(\n cut: WalkCut,\n name: string,\n referencePath: string | undefined,\n): Graph {\n const w = cut.walks\n const first = w.offsets[1] ?? 0\n const light: GraphTables = {\n nodes: cut.nodes,\n links: cut.links,\n walks: {\n names: w.names.slice(0, 1),\n starts: w.starts.subarray(0, 1),\n ends: w.ends.subarray(0, 1),\n offsets: Int32Array.of(0, first),\n steps: w.steps.subarray(0, first),\n reversed: w.reversed.subarray(0, first),\n },\n }\n const graph = loadGraph(light, name, { referencePath })\n const depth = new Int32Array(cut.nodes.names.length)\n for (const node of w.steps) {\n depth[node]!++\n }\n graph.nodes.forEach((node, i) => {\n node.depth = Math.max(depth[i]!, 1)\n })\n const stubs = w.names.slice(1).flatMap((walk, i) => {\n if (w.offsets[i + 2]! <= w.offsets[i + 1]!) {\n return []\n }\n return [{ ...walkPath(walk), nodeIds: [], start: w.starts[i + 1]! }]\n })\n graph.paths = [...(graph.paths ?? []), ...stubs]\n return graph\n}\n\n/** bandage-core's walkRowLayout, over rows already made */\nexport function walkRowLayoutOf(\n graph: Graph,\n walks: WalkRows,\n region?: { start: number; end: number },\n): LayoutResult | undefined {\n const backbone = backboneNodes(graph)\n if (backbone.length === 0) {\n return undefined\n }\n const overWindow = region\n ? backbone.filter(n => overlapsWindow(n, region))\n : backbone\n return {\n nodePositions: backbonePositions(\n overWindow.length > 0 ? overWindow : backbone,\n ),\n rowLabels: walkRowLabels(walks),\n referenceAxis: true,\n pixelRows: true,\n extent: walkRowsExtent(walks),\n }\n}\n", "import { sameBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport { bubbleSegmentIds } from '@jbrowse/bandage-core/bubbles/classifyBubble'\nimport { foldVariants } from '@jbrowse/bandage-core/foldVariants'\nimport { regionLabel } from '@jbrowse/bandage-core/hoverText'\nimport {\n clipToWindow,\n trimToWindow,\n} from '@jbrowse/bandage-core/layout/trimToWindow'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n anchorFromPaths,\n chooseReferencePath,\n} from '@jbrowse/bandage-core/pathAnchoring'\nimport { engineSettingsOf, loadGraph } from '@jbrowse/bandage-core/pipeline'\nimport { assemblyWalk } from '@jbrowse/bandage-core/reference'\nimport { bundleRoutes } from '@jbrowse/bandage-core/tubeMap/bundle'\nimport { coarsenTubeMap } from '@jbrowse/bandage-core/tubeMap/coarsen'\nimport { readConfObject } from '@jbrowse/core/configuration'\nimport {\n getRpcSessionId,\n getSession,\n statusMessageText,\n} from '@jbrowse/core/util'\nimport { openLocation } from '@jbrowse/core/util/io'\nimport { flow, getEnv, isAlive } from '@jbrowse/mobx-state-tree'\n\nimport {\n EMPTY_BATCH,\n TUBE_MAP_MODES,\n bubblePrefix,\n fileName,\n forceLayouts,\n} from './paneBase'\nimport { withSettingActions } from './settingActions'\nimport { namesReads } from '../../GetGraphReads'\nimport { walkRowsOf } from '../../RgfaTabixAdapter/walkRowRuns.ts'\nimport { geneModelsFrom } from '../genes/geneFeatures'\nimport { gfaText } from '../gfaText'\nimport { repeatArraysFrom } from '../repeats/repeatFeatures'\nimport {\n graphOfPaths,\n tubeMapPanelGroups,\n withTubeMapPanels,\n} from '../tubeMapPanels'\nimport { parseSamplesTsv } from '../walkRowGroups'\nimport { walkRowLayoutOf, walkRowsGraph } from '../walkRowsCut.ts'\n\nimport type { SubgraphCutOptions, SubgraphRegion } from '../../GetSubgraph'\nimport type { WalkCut } from '../../RgfaTabixAdapter/walkRowRuns.ts'\nimport type { GafReads } from '../../gaf/gafFile'\nimport type { PaneLayout } from '../tubeMapPanels'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { GeneModel } from '@jbrowse/bandage-core/genes/genePins'\nimport type { EngineRequest } from '@jbrowse/bandage-core/pipeline'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { Feature } from '@jbrowse/core/util'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\nconst withEngineSettings = withSettingActions.views(self => ({\n get engineSettings() {\n return engineSettingsOf({\n engine: self.layoutEngine,\n quality: self.layoutQuality,\n linearLayout: self.linearLayout,\n bubbleSpread: self.bubbleSpread,\n showDeletionEdges: self.showDeletionEdges,\n })\n },\n}))\n\nexport const withLoadActions = withEngineSettings.actions(self => {\n let loadController: AbortController | undefined\n // the samples TSV location the table was read from, or is being read from\n let sampleTableKey: string | undefined\n // The engine run the live layout waits on, which alone writes the status\n // line, and each run by the promise the force cache hands every request\n // that shares it\n let awaitedRun: object | undefined\n const runOf = new WeakMap<Promise<unknown>, object>()\n\n // A StatusCallback takes an RpcStatus, which `statusMessageText` reads\n function callEngine(request: EngineRequest, run: object) {\n const { rpcManager } = getSession(self)\n return rpcManager.call(getRpcSessionId(self), 'GraphComputeLayout', {\n ...request,\n signal: loadController?.signal,\n statusCallback: status => {\n if (run === awaitedRun) {\n self.setStatusMessage(statusMessageText(status) ?? '')\n }\n },\n }) as Promise<{ result: LayoutResult; duration: number }>\n }\n\n // Single dispatch point for every layout mode. A mode that returns a\n // result computed it locally; one that returns undefined can't draw this\n // graph and hands off to the remote FMMM engine, which is also how\n // 'force' is expressed. See LAYOUT_MODES.\n function* computeLayout(graph: Graph) {\n const start = performance.now()\n const tubeMap = TUBE_MAP_MODES.has(self.chosenLayoutMode)\n // a tube map draws the window; the cut's context is for walk rows\n const region = self.graphRegion\n const drawn = tubeMap && region ? trimToWindow(graph, region) : graph\n // reads are placed by the cut's segment names, which a fold renames\n const coarse =\n tubeMap && self.tubeMapFold > 0 && !drawn.reads\n ? coarsenTubeMap(drawn, self.tubeMapFold)\n : undefined\n const laid = coarse?.graph ?? drawn\n const bundled = (g: Graph) =>\n tubeMap && self.tubeMapRoutes !== 'each'\n ? bundleRoutes(\n g,\n self.tubeMapColoring?.valueOf,\n self.tubeMapRoutes === 'bundled',\n )\n : g\n const runs = self.walkCut?.walkRowRuns\n const local =\n self.chosenLayoutMode === 'walkrows' && runs\n ? walkRowLayoutOf(graph, walkRowsOf(runs), self.graphRegion)\n : layoutModeByValue(self.chosenLayoutMode).run(\n bundled(laid),\n self.graphRegion,\n self.host ? self.layoutResult?.sampleRows : undefined,\n )\n if (local) {\n const withCoarse = (r: LayoutResult) =>\n coarse && r.tubeMap ? { ...r, tubeMap: { ...r.tubeMap, coarse } } : r\n const whole = withCoarse(local)\n const split = self.tubeMapPanelSplit\n const result: PaneLayout =\n tubeMap && split\n ? withTubeMapPanels(\n whole,\n tubeMapPanelGroups(laid, split).map(group => {\n const panel = layoutModeByValue(self.chosenLayoutMode).run(\n bundled(graphOfPaths(laid, group.paths)),\n self.graphRegion,\n )\n return { ...group, result: panel && withCoarse(panel) }\n }),\n )\n : whole\n return {\n result,\n duration: performance.now() - start,\n mode: self.chosenLayoutMode,\n }\n }\n const settings = self.engineSettings\n const hit = forceLayouts.ready(graph, settings)\n if (hit) {\n return {\n result: hit,\n duration: performance.now() - start,\n mode: 'force' as const,\n }\n }\n const run = {}\n const pending = forceLayouts.layout(graph, settings, r =>\n callEngine(r, run),\n )\n awaitedRun = runOf.get(pending) ?? run\n runOf.set(pending, awaitedRun)\n const forced = (yield pending) as { result: LayoutResult; duration: number }\n return { ...forced, mode: 'force' as const }\n }\n\n // Which layout request is the live one. A layout is async and nothing in\n // the UI waits for it, so several are routinely in flight: every engine\n // setting lays the graph out again on change, and a force layout takes\n // seconds where an anchored one is instant.\n //\n // The graph identity below is not enough to order them, because the\n // competing requests are usually layouts of the SAME graph. Left to\n // resolve order the last one to FINISH won rather than the last one\n // asked for, so switching away from a slow force layout \u2014 to an anchored\n // mode, a cheaper bubble spread, a lower quality \u2014 drew the abandoned\n // one over the top of the chosen one seconds later, with the dropdown\n // still naming the choice that was discarded.\n let liveRequest = 0\n let liveRequestPending = false\n // the error the last failed layout raised, which the next one to land clears\n let layoutError: unknown\n // the graph the layout on screen was computed for\n let laidOutGraph: Graph | undefined\n // a haplotype's genes by track and contig span\n const walkGeneCache = new Map<string, GeneModel[]>()\n\n function dropLayoutOfReplacedGraph() {\n if (self.graph !== laidOutGraph) {\n laidOutGraph = undefined\n self.layoutResult = undefined\n self.drawnLayoutMode = undefined\n }\n }\n\n // Applied under a guard because a layout is async and the user can load a\n // different graph, or ask for a different layout of it, while one is in\n // flight; the stale result must not land.\n function* layoutInto(graph: Graph) {\n const request = ++liveRequest\n liveRequestPending = true\n awaitedRun = undefined\n const isLive = () => self.graph === graph && request === liveRequest\n const signal = loadController?.signal\n let computed\n try {\n // the node cap is a drawing's cost, and walk rows draw a bar per walk\n if (self.modeDrawsNodes && graph.nodes.length > self.maxGraphNodes) {\n throw new Error(\n `Graph too large to draw: ${graph.nodes.length.toLocaleString()} nodes (limit ${self.maxGraphNodes.toLocaleString()}). Pick Layout \u2192 Walk rows, zoom in to a smaller region, or raise the node limit in Graph settings.`,\n )\n }\n computed = yield* computeLayout(graph)\n } catch (e) {\n // A discarded layout's failure is not the user's problem: the drawing\n // they asked for is on screen or on its way, and raising a banner\n // over it reports a graph as broken because a setting they moved on\n // from could not be drawn. An aborted one was discarded by the load\n // that replaced it, even when the graph is still the same object.\n if (!isLive() || signal?.aborted) {\n return false\n }\n layoutError = e\n dropLayoutOfReplacedGraph()\n throw e\n } finally {\n if (request === liveRequest) {\n liveRequestPending = false\n settle()\n }\n }\n const live = isLive()\n if (live) {\n if (layoutError !== undefined && self.error === layoutError) {\n self.error = undefined\n }\n layoutError = undefined\n const previous = self.layoutResult\n const before = self.screenTransform\n laidOutGraph = graph\n self.layoutResult = computed.result\n self.drawnLayoutMode = computed.mode\n self.setLayoutMs(computed.duration)\n self.followNewLayout(previous)\n self.morphFrom(previous, before)\n }\n return live\n }\n\n // The walk a path graph's track puts on the region's assembly: the one\n // that names it, else the one chooseReferencePath infers\n function loadedReference(graph: Graph, region: SubgraphRegion) {\n const paths = graph.anchorPaths\n return graph.anchoredBy === 'paths' && paths\n ? (\n assemblyWalk(graph, self.assemblySpellings(region.assemblyName)) ??\n chooseReferencePath(paths, region.assemblyName)\n )?.name\n : undefined\n }\n\n // A cut parsed, its reference walk named: a tag-anchored walk-file cut\n // anchors on its nodes' tags, and names its walk on the region's assembly\n // so walk keys measure against it\n function parseCut(\n source: string | WalkCut,\n name: string,\n region: SubgraphRegion | undefined,\n whole = false,\n ) {\n const referencePath = self.referencePath || region?.assemblyName\n const parsed =\n typeof source !== 'string' && source.walkRowRuns && !whole\n ? walkRowsGraph(source, name, referencePath)\n : loadGraph(source, name, { referencePath })\n if (\n parsed.anchoredBy === 'tags' &&\n !parsed.referencePath &&\n parsed.paths?.length &&\n region\n ) {\n parsed.referencePath = assemblyWalk(\n parsed,\n self.assemblySpellings(region.assemblyName),\n )?.name\n }\n return parsed\n }\n\n // Replaces the graph on screen and the cut it came from, and drops the\n // annotations read beside the last graph. It drops the hover and the\n // selection too, because hoveredEdge is an index into graph.edges and\n // hoveredNode/selectedNode are ids, which would point the tooltip and the\n // highlight at whatever sits there in the new graph.\n function resetCut(cut?: {\n graph: Graph\n walkCut: WalkCut | undefined\n region: SubgraphRegion | undefined\n loadedReferencePath: string | undefined\n foldedBelowBp: number | undefined\n readsShown: { shown: number; total: number } | undefined\n }) {\n self.graph = cut?.graph\n self.walkCut = cut?.walkCut\n self.graphRegion = cut?.region\n self.loadedReferencePath = cut?.loadedReferencePath\n self.foldedBelowBp = cut?.foldedBelowBp\n self.readsShown = cut?.readsShown\n self.indexBubbles = undefined\n self.geneTrackFeatures = undefined\n self.walkGeneFeatures = undefined\n walkGeneCache.clear()\n self.repeatArrays = undefined\n self.clearInteractionState()\n }\n\n // `keepSelection` for a re-cut of the same source: node ids survive one\n // where edge indexes do not, so the selection is found again by id.\n // `readsOf` fetches the reads over the parsed graph before its one\n // layout, since the tube map lays them out with the paths. `foldBelowBp`\n // is what a host's zoom cannot show: variants under it fold into the\n // reference, and the drawing is clipped to the region it was cut for.\n function* parseAndLayout(\n source: string | WalkCut,\n name: string,\n region: SubgraphRegion | undefined,\n keepSelection = false,\n readsOf?: (graph: Graph) => Promise<GafReads>,\n foldBelowBp = 0,\n // reads over the cut that need no layout, started with it so a layout\n // that fails or runs long neither drops nor delays them\n alongside?: () => Promise<unknown>,\n ) {\n const signal = loadController?.signal\n const walkCut =\n typeof source !== 'string' && source.walkRowRuns ? source : undefined\n const parsed = parseCut(source, name, region)\n const loaded = region ? loadedReference(parsed, region) : undefined\n const anchored =\n !self.referencePath &&\n loaded !== undefined &&\n loaded !== parsed.referencePath\n ? anchorFromPaths(parsed, loaded)\n : parsed\n const folded =\n foldBelowBp > 0 && !readsOf\n ? foldVariants(anchored, foldBelowBp)\n : anchored\n const graph =\n region && folded !== anchored\n ? clipToWindow(folded, region, foldBelowBp)\n : folded\n let readsShown: { shown: number; total: number } | undefined\n if (readsOf) {\n self.setStatusMessage('Reading alignments')\n try {\n const { records, total } = (yield readsOf(graph)) as GafReads\n graph.reads = records\n readsShown = { shown: records.length, total }\n } catch (e) {\n if (signal?.aborted) {\n return\n }\n console.warn('[GraphGenomeView] no reads for this graph', e)\n }\n if (signal?.aborted) {\n return\n }\n }\n const selected = keepSelection ? self.selectedNode : null\n resetCut({\n graph,\n walkCut,\n region,\n loadedReferencePath: loaded,\n foldedBelowBp: folded === anchored ? undefined : foldBelowBp,\n readsShown,\n })\n // a re-cut keeps the bubbles still in it open\n const names = new Set(graph.nodes.map(n => n.name))\n self.openBubbles = self.openBubbles.filter(b =>\n bubbleSegmentIds(b).some(id => names.has(id)),\n )\n // against the new graph's own nodes: nodeById reads through the layout,\n // which is still the last graph's\n if (selected !== null && graph.nodes.some(n => n.id === selected)) {\n self.selectedNode = selected\n }\n self.setStatusMessage('Computing layout')\n const reads = alongside?.()\n reads?.catch(() => undefined)\n yield* layoutInto(graph)\n // a load superseded mid-layout leaves the status to the one replacing it\n if (reads && !signal?.aborted) {\n self.setStatusMessage('Reading annotations')\n yield reads\n }\n }\n\n // Which load is the live one, for the reason liveRequest orders layouts:\n // every change in the settings dialog re-cuts, a remote cut takes seconds,\n // and the last one to finish is not the last one asked for.\n let liveLoad = 0\n // the load still fetching, parsing or reading annotations, whose spinner a\n // layout of the graph already on screen must not clear\n let loadInFlight: number | undefined\n\n function beginLoad() {\n const load = ++liveLoad\n loadController?.abort()\n loadController = new AbortController()\n loadInFlight = load\n self.loadCanceled = false\n return {\n isLive: () => load === liveLoad,\n signal: loadController.signal,\n }\n }\n\n // The spinner stays up while a load or the layout last asked for is in\n // flight. Clearing it sooner reports \"done\" while the layout the user\n // asked for is still computing, the common case when a cheap choice\n // follows an expensive one.\n function settle() {\n if (loadInFlight === undefined && !liveRequestPending) {\n self.finishLoading()\n }\n }\n\n function endLoad() {\n loadInFlight = undefined\n settle()\n }\n\n // Runs `body` as a load. It raises the spinner and clears the error first,\n // and while it is the live load it reports a failure and ends the spinner.\n function* runLoad(\n label: string,\n body: (load: {\n isLive: () => boolean\n signal: AbortSignal\n }) => Generator<PromiseLike<unknown>, void, unknown>,\n ) {\n const load = beginLoad()\n self.isLoading = true\n self.error = undefined\n try {\n yield* body(load)\n } catch (e) {\n if (load.isLive()) {\n console.error(`[GraphGenomeView.${label}]`, e)\n self.error = e\n }\n } finally {\n if (load.isLive()) {\n endLoad()\n }\n }\n }\n\n // Features over the cut. A failed read warns and returns undefined, so an\n // annotation never fails the load.\n function* readFeatures(\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n what: string,\n signal?: AbortSignal,\n ) {\n try {\n return (yield getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'CoreGetFeatures',\n { adapterConfig, regions: [region], signal },\n )) as Feature[]\n } catch (e) {\n console.warn(`[GraphGenomeView] no ${what} for this graph`, e)\n return undefined\n }\n }\n\n // The bubble index that the hosted HPRC build keeps beside its segments,\n // `<prefix>.bubbles.bed.gz`, read through the bubble adapter over the same\n // window. A graph whose source has no such file, the ordinary case for a\n // graph of one's own, keeps its derived bubbles, so a failure here is not\n // the graph's problem. A coarse cut reads none: its nodes are the\n // bubbles, and the index over its window can run to a chromosome's rows.\n function* loadBubbles(\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n isLive: () => boolean,\n signal?: AbortSignal,\n foldBelowBp = 0,\n ) {\n // The track config arrives as written, so the prefix is either the\n // `uri` shorthand or the segments location it expands to.\n const prefix = bubblePrefix(adapterConfig)\n if (adapterConfig.type !== 'RgfaTabixAdapter' || prefix === undefined) {\n return\n }\n const features = yield* readFeatures(\n {\n type: 'MinigraphBubbleAdapter',\n uri: `${prefix}.bubbles.bed.gz`,\n baseUri: adapterConfig.baseUri,\n assemblyNameToPanSN: adapterConfig.assemblyNameToPanSN,\n },\n region,\n 'bubble index',\n signal,\n )\n if (features && isLive()) {\n self.indexBubbles = features.flatMap(f => {\n const start = f.get('start')\n const end = f.get('end')\n const longestAlleleLength = f.get('longestAlleleLength') as number\n return Math.max(end - start, longestAlleleLength) < foldBelowBp\n ? []\n : [\n {\n refName: region.refName,\n start,\n end,\n segmentCount: f.get('segmentCount') as number,\n pathCount: (f.get('pathCount') as number | undefined) ?? 0,\n inversion: f.get('inversion') as boolean,\n shortestAlleleLength: f.get('shortestAlleleLength') as number,\n longestAlleleLength,\n segments: f.get('segments') as string,\n shortestAllele: undefined,\n longestAllele: undefined,\n },\n ]\n })\n }\n }\n\n // A session track's features over the cut, undefined when the session has\n // no such track\n function* trackFeatures(\n trackId: string | undefined,\n region: SubgraphRegion,\n what: string,\n signal?: AbortSignal,\n ) {\n const config = trackId ? self.sessionTrack(trackId) : undefined\n if (!config) {\n return undefined\n }\n return yield* readFeatures(\n readConfObject(config, 'adapter'),\n region,\n what,\n signal,\n )\n }\n\n // The annotation tracks read over the cut: genes, which `geneFeatures`\n // makes genes of for the backbone to carry, and tandem repeat arrays, for\n // the walk rows to measure between and tile by\n const annotations = {\n genes: {\n trackId: () => self.geneTrack?.trackId,\n set: (features: Feature[] | undefined) => {\n self.geneTrackFeatures = features\n },\n },\n repeats: {\n trackId: () => self.repeatTrack?.trackId,\n set: (features: Feature[] | undefined) => {\n self.repeatArrays = features && repeatArraysFrom(features)\n },\n },\n }\n type Annotation = keyof typeof annotations\n\n // Lands only while the track it read is still the one chosen, so a slow\n // read cannot land over the pick that followed it\n function* loadAnnotation(\n kind: Annotation,\n region: SubgraphRegion,\n isLive: () => boolean,\n signal?: AbortSignal,\n ) {\n const { trackId, set } = annotations[kind]\n const track = trackId()\n const features = yield* trackFeatures(track, region, kind, signal)\n if (features && isLive() && trackId() === track) {\n set(features)\n }\n }\n\n // The annotation reads over a cut, each landing as it arrives\n function annotationReads(\n region: SubgraphRegion,\n isLive: () => boolean,\n signal: AbortSignal,\n ) {\n return (['genes', 'repeats'] as const).map(kind =>\n flow(loadAnnotation)(kind, region, isLive, signal),\n )\n }\n\n // One annotation read again alone, for a track change\n function* reloadAnnotation(kind: Annotation) {\n const region = self.graphRegion\n if (region) {\n annotations[kind].set(undefined)\n yield* loadAnnotation(kind, region, () => self.graphRegion === region)\n }\n }\n\n // Raises `isLoading` before any fetch, so a view waiting on a remote file\n // shows its loading state instead of the import form. Text already in\n // hand is parsed without yielding first. `region` is the window a\n // declared file was stated beside, which the parse anchors on and the\n // annotations are read over.\n function* loadWholeGFA(\n name: string,\n source: string | ((signal: AbortSignal) => Promise<string>),\n region?: SubgraphRegion,\n ) {\n yield* runLoad('loadWholeGFA', function* ({ isLive, signal }) {\n const text =\n typeof source === 'string' ? source : ((yield source(signal)) as string)\n if (!isLive()) {\n return\n }\n yield* parseAndLayout(\n text,\n name,\n region,\n false,\n undefined,\n 0,\n region && (() => Promise.all(annotationReads(region, isLive, signal))),\n )\n })\n }\n\n function abortLoad() {\n loadController?.abort()\n loadController = undefined\n loadInFlight = undefined\n liveLoad++\n liveRequest++\n liveRequestPending = false\n awaitedRun = undefined\n }\n\n // The graph a layout of the current mode draws: a walk-rows cut's\n // stepless walks parsed whole once a layout that draws nodes needs them\n function wholeGraph() {\n const cut = self.walkCut\n const graph = self.graph\n if (!cut || !graph || self.chosenLayoutMode === 'walkrows') {\n return graph\n }\n const whole = parseCut(cut, graph.name, self.graphRegion, true)\n self.graph = whole\n self.walkCut = undefined\n return whole\n }\n\n // Drops the graph and all it derived, and ends any load in flight, which\n // would otherwise land its graph afterwards\n function dropGraph() {\n abortLoad()\n self.finishMorph()\n self.morphEntering = undefined\n self.drawnBatch = EMPTY_BATCH\n self.paintedViewport = undefined\n resetCut()\n laidOutGraph = undefined\n layoutError = undefined\n self.layoutResult = undefined\n self.drawnLayoutMode = undefined\n self.walkRowSampleTable = undefined\n sampleTableKey = undefined\n self.openBubbles = []\n self.error = undefined\n self.isLoading = false\n self.loadCanceled = false\n self.statusMessage = ''\n self.clearPerfMetrics()\n // the next graph has nothing to do with where the user left this one\n if (self.viewportOwner === 'user') {\n self.viewportOwner = 'fit'\n }\n }\n\n return {\n // back to the import form\n clearGraph() {\n dropGraph()\n },\n // The user's stop before anything is drawn. The source stays, so a\n // retry can load it again.\n cancelLoad() {\n if (self.canCancelLoad) {\n dropGraph()\n self.loadCanceled = true\n }\n },\n // The user's stop, leaving whatever is drawn under it, and dropping a\n // swapped-in graph whose layout never landed\n stopLoad() {\n abortLoad()\n dropLayoutOfReplacedGraph()\n if (!self.layoutResult) {\n resetCut()\n }\n self.isLoading = false\n self.statusMessage = ''\n self.loadCanceled = true\n },\n beforeDestroy() {\n abortLoad()\n },\n loadGFA: flow(function* (text: string, name = 'Imported GFA') {\n yield* loadWholeGFA(name, text)\n }),\n // A file the user picked, read inside the load so the form shows its\n // progress rather than sitting idle through a large read\n loadGFAFile: flow(function* (file: Blob, name: string) {\n self.setStatusMessage('Reading file')\n yield* loadWholeGFA(name, () =>\n file.arrayBuffer().then(buf => gfaText(new Uint8Array(buf))),\n )\n }),\n loadGFAFromLocation: flow(function* (\n location: FileLocation,\n region?: SubgraphRegion,\n ) {\n self.setStatusMessage('Fetching GFA')\n yield* loadWholeGFA(\n fileName(location) || 'GFA',\n signal =>\n openLocation(location, getEnv(self).pluginManager)\n .readFile({ signal })\n .then(gfaText),\n region,\n )\n }),\n // One cut of a region, laid out with the annotations over it. Whether\n // the region may be cut is the caller's call; overlapping cuts are\n // ordered by liveLoad, so the latest one lands.\n cutSubgraph: flow(function* (\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n opts: SubgraphCutOptions = {},\n foldBelowBp = 0,\n ) {\n yield* runLoad('cutSubgraph', function* ({ isLive, signal }) {\n self.setStatusMessage('Fetching subgraph')\n const fetchStart = performance.now()\n const cut = (yield getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetSubgraph',\n { adapterConfig, region, opts, signal },\n )) as string | WalkCut\n if (!isLive()) {\n return\n }\n self.setFetchMs(performance.now() - fetchStart)\n if (!cut) {\n throw new Error(\n 'Adapter returned no GFA \u2014 region may be outside indexed data or the adapter does not implement getSubgraph',\n )\n }\n yield* parseAndLayout(\n cut,\n regionLabel(region),\n region,\n true,\n namesReads(adapterConfig)\n ? graph =>\n getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetGraphReads',\n {\n adapterConfig,\n nodeNames: graph.nodes.map(n => n.name),\n signal,\n },\n )\n : undefined,\n foldBelowBp,\n // Independent remote reads, each landing as it arrives. A coarse\n // cut reads no bubble index: its nodes are the bubbles, and the\n // index over its window can run to a chromosome's rows.\n () =>\n Promise.all([\n opts.tier === 'coarse'\n ? undefined\n : flow(loadBubbles)(\n adapterConfig,\n region,\n isLive,\n signal,\n self.foldedBelowBp,\n ),\n ...annotationReads(region, isLive, signal),\n ]),\n )\n })\n }),\n // A track change re-reads that annotation alone. The graph, its layout\n // and any open bubble stay as they are.\n reloadRepeats: flow(function* () {\n yield* reloadAnnotation('repeats')\n }),\n reloadGenes: flow(function* () {\n yield* reloadAnnotation('genes')\n }),\n // The source track's samples TSV, read once per location, for walk\n // rows to group by. A failed read leaves the rows ungrouped, says so,\n // and is tried again on the next call.\n loadWalkRowSampleTable: flow(function* () {\n const location = self.walkRowSamplesTsv\n const key = location ? JSON.stringify(location) : undefined\n if (key === sampleTableKey) {\n return\n }\n sampleTableKey = key\n self.walkRowSampleTable = undefined\n if (!location) {\n return\n }\n try {\n const text = (yield openLocation(\n location,\n getEnv(self).pluginManager,\n ).readFile('utf8')) as string\n if (isAlive(self) && key === sampleTableKey) {\n self.walkRowSampleTable = parseSamplesTsv(text)\n }\n } catch (e) {\n if (isAlive(self) && key === sampleTableKey) {\n sampleTableKey = undefined\n getSession(self).notify(\n `Walk rows cannot be grouped: the samples table did not load (${String(e)})`,\n 'warning',\n )\n }\n }\n }),\n // The walk rows' genes, each row's from its haplotype's assembly. A\n // row's genes are its own contig's, so they take the row's name for\n // their contig, whatever the track calls it.\n loadWalkGenes: flow(function* () {\n const reads = self.walkGeneReads?.reads ?? []\n const key = JSON.stringify(reads)\n const graph = self.graph\n const fetched = new Map<string, GeneModel[]>()\n yield Promise.all(\n reads.map(({ row, trackId, region }) =>\n flow(function* () {\n const cacheKey = `${trackId} ${region.refName}:${region.start}-${region.end}`\n let genes = walkGeneCache.get(cacheKey)\n if (!genes) {\n const features = yield* trackFeatures(\n trackId,\n region,\n 'haplotype genes',\n )\n if (!features) {\n return\n }\n genes = geneModelsFrom(features).map(g => ({\n ...g,\n refName: region.refName,\n }))\n walkGeneCache.set(cacheKey, genes)\n }\n fetched.set(row, genes)\n })(),\n ),\n )\n if (\n isAlive(self) &&\n self.graph === graph &&\n JSON.stringify(self.walkGeneReads?.reads ?? []) === key\n ) {\n self.walkGeneFeatures = reads.length ? fetched : undefined\n }\n }),\n // Open a bubble in place: it keeps its colour, the rest of the drawing\n // greys, and the bubbles inside it get labels of their own. Opening an\n // open one closes it and those inside it.\n toggleBubble(bubble: MinigraphBubble) {\n const open = self.openBubbles\n const at = open.findIndex(o => sameBubble(o, bubble))\n if (at >= 0) {\n self.openBubbles = open.slice(0, at)\n return\n }\n const names = new Set(bubbleSegmentIds(bubble))\n if (!self.graph?.nodes.some(n => names.has(n.name))) {\n getSession(self).notify(\n 'None of the segments of this bubble are in the cut; widen the graph context to open it',\n 'info',\n )\n return\n }\n const insides = self.openBubbleInsides\n let parent = insides.length - 1\n while (\n parent >= 0 &&\n !insides[parent]!.some(b => sameBubble(b, bubble))\n ) {\n parent--\n }\n self.openBubbles = [...open.slice(0, parent + 1), bubble]\n },\n closeBubbles() {\n if (self.openBubbles.length > 0) {\n self.openBubbles = []\n }\n },\n recomputeLayout: flow(function* () {\n const graph = wholeGraph()\n if (!graph) {\n return\n }\n self.isLoading = true\n self.setStatusMessage('Computing layout')\n try {\n yield* layoutInto(graph)\n } catch (e) {\n console.error('[GraphGenomeView.recomputeLayout]', e)\n self.error = e\n }\n }),\n }\n})\n", "import { isBackbone } from '@jbrowse/bandage-core/anchoredNodes'\n\nimport { isRecord } from '../isRecord'\n\nimport type { SubgraphRegion } from '../GetSubgraph'\nimport type { GraphNode } from '@jbrowse/bandage-core/types'\n\n// What a LinearGenomeView writes to `session.hovered` on every mousemove (see\n// LinearGenomeViewContainer): the bp under the cursor, plus the feature under it\n// if the topmost track had one. Nothing names the source VIEW, so a graph view\n// filters by whether the position falls in the region it was cut from \u2014 but the\n// position does name the source ASSEMBLY, and that turns out to be the half\n// that matters.\nexport interface LgvHover {\n refName: string\n // The 0-based base under the pointer, the convention `stable.start` and the\n // cut region are in. Not the LGV's own `coord`, which is 1-based for display.\n coord: number\n // The assembly the hovered view is showing. `hoverPosition` is a\n // `PxToBpResult`, i.e. the displayed region the pointer landed in spread flat,\n // so this is that region's own `assemblyName`.\n //\n // Read because refName alone does not identify a locus in a session holding\n // several assemblies, which is every session these graphs are launched in. A\n // PanSN name reduces to a bare contig \u2014 the E. coli pangenome loads five\n // strains each with one refName `chr`, and HPRC's hg38 and a GenArk haplotype\n // both call it `chr6` \u2014 so a synteny stack's rows all answer to the same\n // name at unrelated coordinates. Without this the hover on ANY row lit up a\n // node in the graph, and the node then published its own reference interval\n // back into every linear view.\n //\n // Optional because the channel is typed `unknown` and read structurally: a\n // hover that states no assembly is taken at its word rather than dropped.\n assemblyName?: string\n featureName?: string\n}\n\ninterface FeatureLike {\n get: (key: string) => unknown\n}\n\nfunction isFeatureLike(value: unknown): value is FeatureLike {\n return isRecord(value) && typeof value.get === 'function'\n}\n\n// A display hovers either a Feature, read with `get`, or a plain hit item with\n// a `name` of its own, which is what the canvas feature display hands over.\n// Reading only the first left the exact segment match dead on that display.\nfunction hoveredName(feature: unknown) {\n const name = isFeatureLike(feature)\n ? feature.get('name')\n : isRecord(feature)\n ? feature.name\n : undefined\n return typeof name === 'string' ? name : undefined\n}\n\n// `hovered` is typed `unknown` on the session by design \u2014 it is a shared channel\n// every view writes its own shape to \u2014 so this reads the LGV's shape out of it\n// structurally rather than asserting a type onto it.\nexport function readLgvHover(hovered: unknown): LgvHover | undefined {\n let result: LgvHover | undefined\n if (isRecord(hovered) && isRecord(hovered.hoverPosition)) {\n const { refName, coord, coord0, assemblyName } = hovered.hoverPosition\n if (typeof refName === 'string' && typeof coord === 'number') {\n result = {\n refName,\n // `coord` is 1-based; a host that states the 0-based `coord0` is\n // taken at its word. Read as 0-based, the last base of every node lit\n // the next one, and a 1 bp node could not be reached at all.\n coord: typeof coord0 === 'number' ? coord0 : coord - 1,\n assemblyName:\n typeof assemblyName === 'string' ? assemblyName : undefined,\n featureName: hoveredName(hovered.hoverFeature),\n }\n }\n }\n return result\n}\n\n// Whether a hover is one this graph can answer: the same assembly, the same\n// stable sequence, and inside the window the cut was made for.\n//\n// The assembly is checked FIRST and is the whole reason this is not just a\n// coordinate test. See LgvHover.assemblyName: a graph cut from K12 and a\n// synteny row on Sakai both call their sequence `chr`, so on refName and\n// coordinate alone every row of the stack matched and the graph highlighted a\n// K12 node at Sakai's offset. A hover that names no assembly still passes,\n// which is what a hand-written channel writer and the older LGVs get.\nexport function hoverInRegion(hover: LgvHover, region: SubgraphRegion) {\n return (\n (hover.assemblyName === undefined ||\n hover.assemblyName === region.assemblyName) &&\n hover.refName === region.refName &&\n hover.coord >= region.start &&\n hover.coord < region.end\n )\n}\n\n// The graph node a linear-view hover points at.\n//\n// The feature under the cursor is the exact answer when the graph's own segments\n// track is what's hovered: an RgfaTabixAdapter feature's name is the segment id,\n// which is `GraphNode.name` (`GraphNode.id` carries a strand suffix, so the\n// match has to be on name). Any other track \u2014 genes, bubbles \u2014 supplies only a\n// coordinate, which still identifies the backbone segment covering it: the\n// backbone tiles the reference exactly once, whether rGFA's rank 0 declared it\n// or a reference path's own steps did.\nexport function nodeForLgvHover({\n hover,\n nodes,\n}: {\n hover: LgvHover\n nodes: GraphNode[]\n}) {\n let byName: string | undefined\n let byCoord: string | undefined\n for (const node of nodes) {\n if (node.name === hover.featureName) {\n byName = node.id\n } else if (\n byCoord === undefined &&\n isBackbone(node) &&\n hover.coord >= node.stable.start &&\n hover.coord < node.stable.start + node.length\n ) {\n byCoord = node.id\n }\n }\n // An exact segment match wins over the coordinate it happens to sit at.\n return byName ?? byCoord ?? null\n}\n", "import { panSNSample } from '@jbrowse/bandage-core/pansn'\nimport { pathOrigin } from '@jbrowse/bandage-core/pathAnchoring'\n\n// A per-sample lane names its rows its own way: a phased callset `HG00097 HP0`,\n// counting haplotypes from 0, a MAF `HG00097.1`, counting from 1 as PanSN does,\n// and anything else by the bare sample\nconst PHASED_ROW = /^(.+) HP(\\d+)$/\nconst DOTTED_ROW = /^(.+)\\.(\\d+)$/\n\n// A bare sample can end in `.2` too, an accession for one, so each reading is\n// tried in turn\nfunction readings(row: string) {\n const phased = PHASED_ROW.exec(row)\n const dotted = DOTTED_ROW.exec(row)\n return [\n ...(phased\n ? [{ sample: phased[1]!, haplotype: String(Number(phased[2]) + 1) }]\n : []),\n ...(dotted ? [{ sample: dotted[1]!, haplotype: dotted[2] }] : []),\n { sample: row, haplotype: undefined },\n ]\n}\n\nfunction haplotypeOf(pathName: string) {\n return pathOrigin(pathName).name.split('#')[1]\n}\n\n// The walks a hovered lane row stands for: the one of its haplotype, or every\n// walk of a bare sample. A cut often holds one haplotype of a sample, so a row\n// naming the other matches nothing rather than the one it holds.\nexport function walksForRow(row: string, paths: readonly { name: string }[]) {\n const names = paths.map(p => p.name)\n for (const { sample, haplotype } of readings(row)) {\n const walks = names.filter(\n name =>\n panSNSample(pathOrigin(name).name) === sample &&\n (haplotype === undefined || haplotypeOf(name) === haplotype),\n )\n if (walks.length > 0) {\n return walks\n }\n }\n return []\n}\n", "import { contains } from '@jbrowse/bandage-core/viewport'\nimport { getSession } from '@jbrowse/core/util'\nimport { addDisposer } from '@jbrowse/mobx-state-tree'\nimport { autorun, reaction, untracked } from 'mobx'\n\nimport { withLoadActions } from './loadActions'\nimport {\n EMPTY_BATCH,\n TUBE_MAP_MODES,\n dependOn,\n paneViewportOf,\n} from './paneBase'\nimport {\n hoverInRegion,\n nodeForLgvHover,\n readLgvHover,\n} from '../../hoverSync/lgvHover'\nimport { walksForRow } from '../../hoverSync/rowWalks'\nimport { trackedDpr } from '../trackedDpr'\n\nimport type { LayoutEngineKind } from '@jbrowse/bandage-core/layoutEngines'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { Renderer } from '@jbrowse/bandage-core/renderer/types'\n\nexport const withRenderingActions = withLoadActions\n .actions(self => ({\n startRenderingBackend(backend: Renderer) {\n if (!self.autorunsInstalled) {\n // Autorun: keep the view fitted to the graph until the user moves it.\n // Reading fittedTransform tracks everything the fit depends on, so\n // it re-fits as the layout arrives, the canvas is measured and the\n // genes over a tube map claim their rows. A manual pan/zoom (or a\n // restored-session transform) makes the viewport the user's, and a\n // host makes it the linear view's.\n addDisposer(\n self,\n autorun(() => {\n if (\n self.fittedTransform &&\n untracked(() => self.viewportOwner === 'fit')\n ) {\n self.zoomToFit()\n }\n }),\n )\n\n // A narrower or shorter pane can leave a placed drawing off screen\n addDisposer(\n self,\n reaction(\n () => `${self.viewBox.width} ${self.viewBox.height}`,\n () => {\n self.keepDrawingInView()\n },\n ),\n )\n addDisposer(\n self,\n // Faceting on or off, its columns, its count of panels and what\n // they split by each reshape the boxes the drawing is fitted into\n reaction(\n () => {\n const grid = self.facetGrid\n return grid\n ? `${self.facetSetting.field} ${self.facetPanels?.length} ${grid.columns}`\n : ''\n },\n () => {\n self.refitView()\n },\n ),\n )\n // The walk rows' genes follow the rows: a new cut, a repeat pick or\n // a sample filter changes which haplotypes and spans they read\n addDisposer(\n self,\n reaction(\n () => ({\n graph: self.graph,\n reads: JSON.stringify(self.walkGeneReads?.reads ?? []),\n }),\n () => {\n void self.loadWalkGenes()\n },\n {\n fireImmediately: true,\n equals: (a, b) => a.graph === b.graph && a.reads === b.reads,\n },\n ),\n )\n // Walk rows and tube map panels read the source track's samples\n // TSV, to group by its columns, again for a graph after a dropped one\n addDisposer(\n self,\n reaction(\n () =>\n self.hasGraph &&\n (self.chosenLayoutMode === 'walkrows' ||\n TUBE_MAP_MODES.has(self.chosenLayoutMode))\n ? JSON.stringify(self.walkRowSamplesTsv ?? null)\n : undefined,\n key => {\n if (key !== undefined) {\n void self.loadWalkRowSampleTable()\n }\n },\n { fireImmediately: true },\n ),\n )\n // A host fits the rows once, when it takes the pane over, which is\n // before the legend measures the room it needs above them\n addDisposer(\n self,\n reaction(\n () => self.fitPadTop,\n () => {\n if (self.viewportOwner === 'host') {\n self.zoomToFit()\n }\n },\n ),\n )\n\n // Autorun: mirror a connected linear view's hover onto the graph. An\n // LGV writes `{hoverPosition, hoverFeature}` to session.hovered on\n // every mousemove; neither field names the source view, so the guard\n // is that the position lies in the region this graph was cut from.\n // A pointer over the pane itself is the host's too, at a bp its x\n // only means on a reference-axis layout, so there the pane's own hit\n // test is the hover. A row naming a walk always lifts it; the node at\n // a bp lights only on `hover: 'everything'`, since every track's\n // pointer passes over some node's bp.\n //\n // Only `hovered` and the setting are tracked \u2014 the graph reads are\n // untracked, so a geometry rebuild can't re-fire this and clobber a\n // hover the canvas itself set. Assigning an unchanged id doesn't notify, so a hover\n // that travels within one segment costs nothing downstream.\n addDisposer(\n self,\n autorun(() => {\n const hover = readLgvHover(getSession(self).hovered)\n const lightsNode = self.hoverLightsEverything\n untracked(() => {\n const region = self.graphRegion\n const graph = self.graph\n const inRegion =\n hover && region && hoverInRegion(hover, region)\n ? hover\n : undefined\n // a row naming a walk is the hover, not the node at its bp,\n // whose band would cover the row's own cells\n const rowWalks =\n inRegion?.featureName && graph?.paths\n ? walksForRow(inRegion.featureName, graph.paths)\n : []\n if (region && graph && !self.pointerInPane) {\n self.setHoveredNode(\n inRegion && lightsNode && rowWalks.length === 0\n ? nodeForLgvHover({ hover: inRegion, nodes: graph.nodes })\n : null,\n )\n }\n self.setHoveredRowWalks(rowWalks)\n })\n }),\n )\n\n // Reaction: drop a hover the pointer cannot still be over.\n //\n // A hover is set by a mousemove on the canvas, and here the drawing\n // moves under a STATIONARY cursor on three axes \u2014 the wheel zoom, the\n // toolbar's zoom and fit buttons, and a pan \u2014 none of which fire a\n // pointer event. Left alone the tooltip goes on naming the node that\n // used to be under the cursor, `hoverHighlight` goes on publishing its\n // span, and the paired linear view paints a band over the wrong\n // sequence until the mouse happens to move.\n //\n // This is jbrowse-components' `installClearHoverOnViewportChange`\n // (BaseLinearDisplay), whose three axes are bpPerPx / offsetPx /\n // scrollTop; a graph view's are its own transform. Its rule is worth\n // restating rather than just citing: a sticky canvas gets no\n // mousemove and no mouseleave for any of them. Not imported because\n // it lives in the LGV plugin and reads a containing LGV, and this\n // plugin deliberately takes no runtime dependency on that plugin\n // (see hoverSync/index.tsx).\n //\n // A `reaction`, not an autorun, for the reason stated there: the\n // effect touches hover state, and an autorun would re-enter itself.\n // Selection is untouched \u2014 a click is a choice, and the content\n // moving does not unmake it.\n addDisposer(\n self,\n reaction(\n () => `${self.scale}-${self.translateX}-${self.translateY}`,\n () => {\n self.clearHover()\n },\n { name: 'GraphClearHoverOnViewportChange' },\n ),\n )\n\n // Autorun: a zoom, or a pan that leaves the window the last build\n // covered, schedules a debounced rebuild. A pan inside it costs a\n // repaint and nothing else. Skips the first run.\n let firstViewport = true\n addDisposer(\n self,\n autorun(() => {\n const { scale } = self\n const viewport = paneViewportOf(self)\n if (firstViewport) {\n firstViewport = false\n return\n }\n const built = untracked(() => self.builtViewport)\n if (built?.scale === scale && contains(built.bounds, viewport)) {\n return\n }\n self.scheduleViewportDirty()\n }),\n )\n\n // Autorun: the selection. The hover paints on a layer of its own.\n addDisposer(\n self,\n autorun(() => {\n const b = self.currentRenderingBackend as Renderer | undefined\n if (b) {\n self.applySelection(b)\n self.renderNow()\n }\n }),\n )\n }\n\n // The second argument is a SETUP THUNK, not the callbacks themselves:\n // anything it closes over lives exactly as long as the callbacks that\n // read it, which is what lets a per-backend memo work.\n self.attachRenderingBackend<Renderer>(backend, () => ({\n // Autorun: rebuild geometry when graph data or display options\n // change. scale/translate are untracked so they don't trigger a full\n // rebuild \u2014 only the debounced viewportDirty flag does.\n upload: (b: Renderer) => {\n dependOn(trackedDpr())\n b.resize(self.paneWidth, self.canvasHeight)\n if (self.layoutResult?.tubeMap || self.facetPanels) {\n dependOn(self.viewportDirty)\n b.uploadGeometry(EMPTY_BATCH)\n self.setGeometryMetrics(0, EMPTY_BATCH, {\n scale: untracked(() => self.scale),\n bounds: untracked(() => self.viewportToBuild()),\n })\n return true\n }\n const geometryStart = performance.now()\n const built = self.buildDrawing(\n self.drawnHighlight,\n self.effectiveDrawPaths,\n )\n if (built) {\n b.uploadGeometry(built.batch)\n self.setGeometryMetrics(\n performance.now() - geometryStart,\n built.batch,\n {\n scale: untracked(() => self.scale),\n bounds: built.viewportBounds,\n },\n )\n return true\n }\n // Nothing reached the backend, so the autorun may skip the redraw\n // it would otherwise force. Safe despite the resize above: with no\n // positions there is nothing to draw, which is the same case\n // `render` below returns false for.\n return false\n },\n // Autorun: re-render on pan/zoom/theme without rebuilding geometry\n render: (b: Renderer) => {\n if (!self.nodePositions) {\n return false\n }\n self.paint(b)\n self.markPainted()\n return true\n },\n releaseTargets: (b: Renderer) => {\n b.releaseOffscreenTargets()\n },\n }))\n },\n }))\n .actions(self => ({\n // The drawing made again for a layout mode that changed from `from`; a\n // host overrides it with what its source needs, such as a recut\n relayoutFrom(_from: LayoutModeValue): Promise<unknown> {\n return self.recomputeLayout()\n },\n }))\n .actions(self => ({\n relayout(from: LayoutModeValue) {\n self.handledLayoutMode = self.chosenLayoutMode\n return self.relayoutFrom(from)\n },\n }))\n .actions(self => ({\n // A layout picked from a menu: the mode, then the drawing it makes.\n switchLayout(mode: LayoutModeValue) {\n const from = self.chosenLayoutMode\n self.setLayoutMode(mode)\n return self.relayout(from)\n },\n // loads the source again, for a host that has one\n retryLoad() {},\n afterAttach() {\n // A restored session that already carries a non-default transform is\n // the user's own view \u2014 mark it so the fit autorun leaves it alone.\n if (!self.isDefaultViewport) {\n self.viewportOwner = 'user'\n }\n // A gene or repeat track change over the same cut re-reads that\n // annotation alone, whatever made it: the settings dialog, a track\n // added to the session, undo or a session delta. A new cut reads its\n // own.\n for (const [trackOf, reload] of [\n [() => self.geneTrack?.trackId, () => self.reloadGenes()],\n [() => self.repeatTrack?.trackId, () => self.reloadRepeats()],\n ] as const) {\n addDisposer(\n self,\n reaction(\n () => ({ track: trackOf(), region: self.graphRegion }),\n (now, was) => {\n if (now.region && now.region === was.region) {\n void reload()\n }\n },\n {\n equals: (a, b) => a.track === b.track && a.region === b.region,\n },\n ),\n )\n }\n // The layout set by anything but the menu: the config editor, Reset\n // track settings, undo, a session delta\n addDisposer(\n self,\n reaction(\n () => self.chosenLayoutMode,\n (to, from) => {\n if (to !== self.handledLayoutMode) {\n void self.relayout(from)\n }\n },\n ),\n )\n // An engine setting or the node cap lays the graph out again whatever\n // changed it: the settings dialog, the menu, the config editor, Reset\n // track settings, undo or a session delta. A change of layout mode lays\n // the graph out through relayout, so this reaction skips it.\n addDisposer(\n self,\n reaction(\n () => ({\n mode: self.chosenLayoutMode,\n engine: JSON.stringify(self.engineSettings),\n maxNodes: self.maxGraphNodes,\n }),\n (now, was) => {\n if (\n self.graph &&\n now.mode === was.mode &&\n ((now.engine !== was.engine && self.usesLayoutEngine) ||\n (now.maxNodes !== was.maxNodes && self.modeDrawsNodes))\n ) {\n void self.recomputeLayout()\n }\n },\n {\n equals: (a, b) =>\n a.mode === b.mode &&\n a.engine === b.engine &&\n a.maxNodes === b.maxNodes,\n },\n ),\n )\n // a tube map lays out again for its fold, its panels, its routes and\n // the column its routes split by\n addDisposer(\n self,\n reaction(\n () =>\n TUBE_MAP_MODES.has(self.chosenLayoutMode)\n ? JSON.stringify({\n fold: self.tubeMapFold,\n facet: self.facetSetting,\n groupBy: self.walkRowGroupBy,\n table: self.walkRowGroupBy && self.walkRowSampleTable?.length,\n routes: self.tubeMapRoutes,\n bundledBy:\n self.tubeMapRoutes !== 'each'\n ? self.tubeMapColoring?.field\n : undefined,\n })\n : undefined,\n (facet, was) => {\n if (facet !== undefined && was !== undefined && self.graph) {\n void self.recomputeLayout()\n }\n },\n ),\n )\n },\n }))\n .actions(self => ({\n // Sets the engine and the mode in one action, so the engine reaction\n // sees the mode change and leaves the relayout to switchLayout\n switchForceEngine(engine: LayoutEngineKind) {\n self.setLayoutEngine(engine)\n return self.chosenLayoutMode === 'force'\n ? undefined\n : self.switchLayout('force')\n },\n }))\n", "import { readConfObject } from '@jbrowse/core/configuration'\n\nimport { canonicalAssemblyName, trackAssemblies } from './launchFromGraph'\n\nimport type { TrackScanSession } from './launchFromGraph'\n\nconst ANNOTATION_TRACK_TYPE = 'FeatureTrack'\n\n// What to turn on in a linear view the graph opens on `assemblyName`.\n//\n// A launch used to carry the graph's own track and nothing else, and that track\n// is configured for the reference alone \u2014 so `Launch view` \u2192 `CFT073 chr:\u2026`\n// landed on `No tracks active`, which answers \"where is this strain's sequence?\"\n// with an empty pane. What the session does hold for a contributing assembly is\n// that assembly's own annotation, and on a pangenome config that is one track\n// per strain (`CFT073_genes`), which is exactly what makes the landing readable.\n//\n// Annotation tracks only, not everything configured for the assembly. A launch\n// is a jump to a locus, and an alignments or coverage track turned on behind the\n// user's back fetches data nobody asked for; a FeatureTrack at a 50 kb window is\n// a tabix range query.\n//\n// `first` is the graph's own track when the launch is on the reference, so the\n// segments the graph drew sit at the top of the view rather than wherever config\n// order puts them.\nexport function launchTracks({\n session,\n assemblyName,\n first,\n}: {\n session: TrackScanSession\n assemblyName: string\n first?: string\n}) {\n const wanted = canonicalAssemblyName(session, assemblyName)\n const found: string[] = []\n for (const track of session.tracks) {\n const trackId: unknown = readConfObject(track, 'trackId')\n if (\n readConfObject(track, 'type') === ANNOTATION_TRACK_TYPE &&\n typeof trackId === 'string' &&\n trackId !== first &&\n trackAssemblies(session, track).includes(wanted)\n ) {\n found.push(trackId)\n }\n }\n return first ? [first, ...found] : found\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M9.19 6.35c-2.04 2.29-3.44 5.58-3.57 5.89L2 10.69l4.05-4.05c.47-.47 1.15-.68 1.81-.55zM11.17 17s3.74-1.55 5.89-3.7c5.4-5.4 4.5-9.62 4.21-10.57-.95-.3-5.17-1.19-10.57 4.21C8.55 9.09 7 12.83 7 12.83zm6.48-2.19c-2.29 2.04-5.58 3.44-5.89 3.57L13.31 22l4.05-4.05c.47-.47.68-1.15.55-1.81zM9 18c0 .83-.34 1.58-.88 2.12C6.94 21.3 2 22 2 22s.7-4.94 1.88-6.12C4.42 15.34 5.17 15 6 15c1.66 0 3 1.34 3 3m4-9c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2\"\n}), 'RocketLaunch');", "import { LAUNCH_LABEL, pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport RocketLaunchIcon from '@mui/icons-material/RocketLaunch'\n\nimport type { MenuItem, SubMenuItem } from '@jbrowse/core/ui'\n\nexport function pushLaunchItem(items: MenuItem[], item: MenuItem) {\n pushLaunchViewMenuItem(items, item)\n const group = items.find(\n (i): i is SubMenuItem => 'subMenu' in i && i.label === LAUNCH_LABEL,\n )\n if (group && !group.icon) {\n group.icon = RocketLaunchIcon\n }\n}\n", "import { readConfObject } from '@jbrowse/core/configuration'\nimport { getTrackName } from '@jbrowse/core/util/tracks'\nimport { getEnv, isStateTreeNode } from '@jbrowse/mobx-state-tree'\n\nimport { trackAssemblies } from './launchFromGraph'\n\nimport type { TrackScanSession } from './launchFromGraph'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\n\nexport interface LaunchableSyntenyTrack {\n trackId: string\n name: string\n // how many of the requested assemblies this track covers, so a whole-set\n // all-vs-all sorts above a pairwise alignment covering two of them\n coverage: number\n}\n\nconst SYNTENY_TRACK_TYPE = 'SyntenyTrack'\nconst SYNTENY_ADAPTER_CATEGORY = 'Synteny adapters'\n\n// A SyntenyTrack, or any track reading a synteny adapter (a GraphTrack over a\n// gbz-base database). Core's isSyntenyTrack makes the same test on newer hosts.\nfunction isSyntenyTrack(track: AnyConfigurationModel) {\n if (readConfObject(track, 'type') === SYNTENY_TRACK_TYPE) {\n return true\n }\n const adapterType: unknown = track.adapter?.type\n if (typeof adapterType !== 'string' || !isStateTreeNode(track)) {\n return false\n }\n const { pluginManager } = getEnv<{ pluginManager?: PluginManager }>(track)\n return (\n !!pluginManager?.hasAdapterType(adapterType) &&\n pluginManager.getAdapterType(adapterType).adapterMetadata?.category ===\n SYNTENY_ADAPTER_CATEGORY\n )\n}\n\n// Synteny datasets in the session that align at least two of `assemblyNames`.\n//\n// Two is the floor because that is the floor for a synteny view; more is better,\n// and an all-vs-all covering every contributing assembly is what makes the\n// multi-panel launch worth offering at all.\nexport function launchableSyntenyTracks(\n session: TrackScanSession,\n assemblyNames: string[],\n) {\n const wanted = new Set(assemblyNames)\n const found: LaunchableSyntenyTrack[] = []\n for (const track of session.tracks) {\n const trackId: unknown = readConfObject(track, 'trackId')\n if (isSyntenyTrack(track) && typeof trackId === 'string') {\n const coverage = trackAssemblies(session, track).filter(name =>\n wanted.has(name),\n ).length\n if (coverage >= 2) {\n found.push({ trackId, name: getTrackName(track, session), coverage })\n }\n }\n }\n return found.sort((a, b) => b.coverage - a.coverage)\n}\n", "// Hands `text` to the browser as a file to save\nexport function downloadText(\n text: string,\n name: string,\n type = 'image/svg+xml',\n) {\n const url = URL.createObjectURL(new Blob([text], { type }))\n const a = document.createElement('a')\n a.href = url\n a.download = name\n a.click()\n setTimeout(() => {\n URL.revokeObjectURL(url)\n }, 0)\n}\n", "import { COLOR_SCHEMES } from '@jbrowse/bandage-core/colorSchemes'\nimport { FACET_FIELDS } from '@jbrowse/bandage-core/facetGrid'\nimport {\n LAYOUT_MODES,\n layoutModeByValue,\n} from '@jbrowse/bandage-core/layoutModes'\nimport { getSession } from '@jbrowse/core/util'\nimport ContentCopyIcon from '@mui/icons-material/ContentCopy'\nimport HubIcon from '@mui/icons-material/Hub'\nimport PaletteIcon from '@mui/icons-material/Palette'\nimport PhotoCameraIcon from '@mui/icons-material/PhotoCamera'\nimport VisibilityIcon from '@mui/icons-material/Visibility'\n\nimport {\n ChooseSamplesDialog,\n ChooseWalksDialog,\n HighlightColorDialog,\n TUBE_MAP_FOLDS,\n TUBE_MAP_MODES,\n TUBE_MAP_ROUTES,\n WALK_MENU_ITEMS,\n} from './paneBase'\nimport { withRenderingActions } from './renderingActions'\nimport { graphLaunchMenuItems } from '../../launchFromGraph/graphMenuItems'\nimport {\n highlightInLinearView,\n launchSyntenyView,\n showInLinearView,\n} from '../../launchFromGraph/launchFromGraph'\nimport { launchTracks } from '../../launchFromGraph/launchTracks'\nimport { pushLaunchItem } from '../../launchFromGraph/pushLaunchItem'\nimport { launchableSyntenyTracks } from '../../launchFromGraph/syntenyTracks'\nimport { downloadText } from '../download'\nimport { HOVER_HIGHLIGHT_VALUES } from '../hoverHighlight'\nimport { TUBE_MAP_PANELS, tubeMapPanelGroups } from '../tubeMapPanels'\n\nimport type { GraphLocation } from '../../launchFromGraph/contributors'\nimport type { GraphLayer } from '../graphLayers'\nimport type { TubeMapPanelSplit } from '../tubeMapPanels'\nimport type { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport type { LayoutEngineKind } from '@jbrowse/bandage-core/layoutEngines'\nimport type { MenuItem } from '@jbrowse/core/ui'\n\nconst ENGINE_NAMES: readonly (readonly [LayoutEngineKind, string])[] = [\n ['fmmm', 'FMMM'],\n ['stress', 'stress'],\n]\n\nconst layoutMenuLabel = (mode: { label: string }) =>\n mode.label.replace(/ layout$/, '')\n\nfunction radioItems<T>(\n options: readonly { value: T; label: string; disabled?: boolean }[],\n current: T | undefined,\n onPick: (value: T) => void,\n): MenuItem[] {\n return options.map(({ value, label, disabled }) => ({\n type: 'radio',\n label,\n disabled,\n checked: value === current,\n onClick: () => {\n onPick(value)\n },\n }))\n}\n\nexport const withLaunchActions = withRenderingActions\n .actions(self => ({\n // Move the linear view already on screen, or open one if there is none,\n // and pair with whichever it was. A view being created gets the session's\n // annotation for the assembly it opens on (see launchTracks), led by the\n // graph's own segments track when the launch is on the reference \u2014 the one\n // assembly that track is configured for.\n //\n // Only a view on the reference is paired with. A node's hover band is on\n // that assembly, so paired with a view on another the band fails that\n // view's assembly check and the reference view's id check, and is drawn\n // nowhere.\n showInLinearView(target: { location: GraphLocation; assembly: string }) {\n const session = getSession(self)\n const onReference = target.assembly === self.graphRegion?.assemblyName\n const viewId = showInLinearView({\n session,\n location: target.location,\n assembly: target.assembly,\n connectedViewId: self.pairedViewId,\n tracks: launchTracks({\n session,\n assemblyName: target.assembly,\n first: onReference ? self.sourceTrackId : undefined,\n }),\n })\n if (onReference) {\n self.pairWithLinearView(viewId)\n }\n },\n // Mark the node's reference interval in the linear view beside the graph.\n // Not an action that opens anything: with no view to mark, the menu does\n // not offer it (see nodeLaunchMenuItems).\n highlightInLinearView(target: {\n location: GraphLocation\n assembly: string\n }) {\n highlightInLinearView({\n session: getSession(self),\n location: target.location,\n assembly: target.assembly,\n connectedViewId: self.pairedViewId,\n })\n },\n showSyntenyView(trackId: string) {\n launchSyntenyView({\n session: getSession(self),\n contributors: self.launchableAssemblies,\n trackId,\n graphTrackId: self.sourceTrackId,\n })\n },\n }))\n .views(self => ({\n // Synteny datasets that could fill the panels of a multi-genome launch.\n // Below two openable contributors there is nothing to compare, so the scan\n // is skipped rather than run and discarded.\n get syntenyLaunchTracks() {\n const samples = self.launchableAssemblies.map(c => c.sample)\n return samples.length >= 2\n ? launchableSyntenyTracks(getSession(self), samples)\n : []\n },\n }))\n .views(self => ({\n // Which samples' walks walk rows show: every one, those whose walk and\n // the picked repeat's call disagree, or a set picked by name\n walkRowSampleMenuItems(): MenuItem[] {\n const { disagreeing } = self.walkRowSampleChoices\n const shown = self.walkRowSamples\n const same = (a: string[]) => a.join('\\n') === shown?.join('\\n')\n return [\n {\n type: 'radio',\n label: 'Every sample',\n checked: shown === undefined,\n onClick: () => {\n self.setWalkRowSamples(undefined)\n },\n },\n ...(disagreeing.length > 0\n ? [\n {\n type: 'radio' as const,\n label: 'Where walk and call disagree',\n checked: same(disagreeing),\n onClick: () => {\n self.setWalkRowSamples(disagreeing)\n },\n },\n ]\n : []),\n {\n type: 'radio',\n label: 'Choose samples...',\n checked: shown !== undefined && !same(disagreeing),\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseSamplesDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n },\n // Which sample table column walk rows stack into sections by\n walkRowGroupMenuItems(): MenuItem[] {\n const field = self.walkRowGroups ? self.walkRowGroupBy?.field : undefined\n return radioItems(\n [\n { value: undefined, label: 'None' },\n ...self.walkRowGroupFields.map(c => ({ value: c, label: c })),\n ],\n field,\n c => {\n self.setWalkRowGroupBy(c === undefined ? undefined : { field: c })\n },\n )\n },\n // A tube map's panels: none, a sample's or a walk's each, or a group of\n // samples' each by a column of the source track's sample table\n tubeMapPanelMenuItems(): MenuItem[] {\n const { graph, walkRowSampleTable: table } = self\n const { field } = self.facetSetting\n const column = field === '' ? self.walkRowGroupBy?.field : undefined\n const splits = (split: TubeMapPanelSplit) =>\n !!graph && tubeMapPanelGroups(graph, split).length > 1\n return [\n ...radioItems(\n TUBE_MAP_PANELS.map(item => ({\n value: item.field,\n label: item.label,\n disabled: item.field !== '' && !splits({ by: item.field }),\n })),\n column ? undefined : field,\n by => {\n self.setFacet(by)\n if (by === '') {\n self.setWalkRowGroupBy(undefined)\n }\n },\n ),\n ...radioItems(\n self.walkRowGroupFields.map(c => ({\n value: c,\n label: `By ${c}`,\n disabled: !table || !splits({ by: 'column', field: c, table }),\n })),\n column,\n c => {\n self.setFacet('')\n self.setWalkRowGroupBy({ field: c })\n },\n ),\n ]\n },\n // `repeat` false where a toolbar already picks the repeat\n layoutOptionMenuItems({ repeat = true } = {}): MenuItem[] {\n return [\n ...(TUBE_MAP_MODES.has(self.chosenLayoutMode)\n ? [\n {\n label: 'Fold variants',\n // reads are placed by the cut's names, which a fold renames\n subMenu: radioItems(\n TUBE_MAP_FOLDS.map(({ bp, label }) => ({\n value: bp,\n label,\n disabled: bp > 0 && self.graph?.reads !== undefined,\n })),\n self.graph?.reads ? 0 : self.tubeMapFold,\n self.setTubeMapFold,\n ),\n },\n {\n label: 'Panels',\n subMenu: this.tubeMapPanelMenuItems(),\n },\n {\n label: 'Routes',\n subMenu: radioItems(\n TUBE_MAP_ROUTES,\n self.tubeMapRoutes,\n self.setTubeMapRoutes,\n ),\n },\n ...(self.walkRowGroupFields.length > 0\n ? [\n {\n label: 'Tube color',\n subMenu: radioItems(\n ['', ...self.walkRowGroupFields].map(field => ({\n value: field,\n label: field ? `By ${field}` : 'By role',\n })),\n self.tubeMapColorBy,\n self.setTubeMapColorBy,\n ),\n },\n ]\n : []),\n ]\n : []),\n ...(repeat &&\n self.chosenLayoutMode === 'walkrows' &&\n self.repeatChoices.length > 0\n ? [\n {\n label: 'Repeat',\n subMenu: radioItems(\n self.repeatOptions,\n self.selectedRepeat?.key ?? '',\n self.setRepeatKey,\n ),\n },\n ]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' && self.walkRowBars\n ? [{ label: 'Samples', subMenu: this.walkRowSampleMenuItems() }]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' &&\n self.walkRowBars &&\n self.walkRowGroupFields.length > 0\n ? [{ label: 'Group by...', subMenu: this.walkRowGroupMenuItems() }]\n : []),\n ]\n },\n showMenuItems(): MenuItem[] {\n const layerItem = (label: string, layer: GraphLayer) => ({\n type: 'checkbox' as const,\n label,\n checked: self.layerSet.has(layer),\n onClick: () => {\n self.setLayer(layer, !self.layerSet.has(layer))\n },\n })\n return [\n layerItem('Show bubble halos', 'bubbles'),\n layerItem('Show deletion edges', 'deletions'),\n {\n label: 'Hover highlight',\n subMenu: radioItems(\n HOVER_HIGHLIGHT_VALUES.map(value => ({\n value,\n label: value[0]!.toUpperCase() + value.slice(1),\n })),\n self.chosenHover,\n self.setHover,\n ),\n },\n layerItem('Show genes on the backbone', 'genes'),\n ...(self.referenceStripApplies\n ? [layerItem('Show reference strip', 'referenceStrip')]\n : []),\n ]\n },\n exportMenuItems(): MenuItem[] {\n return [\n {\n label: 'Export SVG',\n icon: PhotoCameraIcon,\n disabled: self.figureUnavailable !== undefined,\n disabledHelpText: self.figureUnavailable,\n onClick: () => {\n const svg = self.figure()\n if (svg) {\n downloadText(\n svg,\n `${(self.graph?.name ?? 'graph').replaceAll(/[^\\w.-]+/g, '_')}.svg`,\n )\n }\n },\n },\n {\n label: 'Copy figure spec',\n icon: ContentCopyIcon,\n disabled: self.figureSpecUnavailable !== undefined,\n disabledHelpText: self.figureSpecUnavailable,\n onClick: () => {\n const spec = self.figureSpec()\n const session = getSession(self)\n navigator.clipboard\n .writeText(`${JSON.stringify(spec, null, 2)}\\n`)\n .then(() => {\n session.notify(\n 'Figure spec copied. Save it as spec.json and run: npx -p @jbrowse/bandage-core bandage-figure spec.json -o figure.svg',\n 'info',\n )\n })\n .catch((e: unknown) => {\n session.notify(`Could not copy the figure spec: ${String(e)}`)\n })\n },\n },\n ]\n },\n // `picks` false where a toolbar already picks the walks, leaving what is\n // done with those picked\n highlightMenuItems({ picks = true } = {}): MenuItem[] {\n const walks = picks ? self.walkChoices : []\n if (\n self.walkChoices.length === 0 ||\n !self.liftsWalks ||\n (!picks && self.walkLayers.length === 0)\n ) {\n return []\n }\n const lifted = (name: string) =>\n self.walkLayers.some(l => l.walk === name)\n const many = walks.length > WALK_MENU_ITEMS\n return [\n { type: 'subHeader', label: 'Highlight' },\n ...(many\n ? [\n {\n label: 'Choose haplotypes...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseWalksDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(many ? walks.filter(walk => lifted(walk.name)) : walks).map(\n walk => ({\n type: 'checkbox' as const,\n label: walk.label,\n checked: lifted(walk.name),\n onClick: () => {\n self.toggleWalk(walk.name)\n },\n }),\n ),\n {\n label: 'Clear highlights',\n disabled: self.walkLayers.length === 0,\n onClick: () => {\n self.setWalkLayers([])\n },\n },\n ...(self.drawnWalks.length > 0\n ? [\n {\n label: 'Color highlighted...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n HighlightColorDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(self.walkLayers.length > 1 && self.modeDrawsNodes\n ? [\n { type: 'subHeader' as const, label: 'Arrange' },\n ...radioItems(\n FACET_FIELDS.map(({ value, label }) => ({\n value,\n label: value === 'walk' ? 'A panel per haplotype' : label,\n })),\n self.facetSetting.field,\n self.setFacet,\n ),\n ]\n : []),\n ]\n },\n colorSchemeLabel(value: ColorScheme): string {\n const label = COLOR_SCHEMES.find(s => s.value === value)?.label ?? value\n return value === 'auto'\n ? `${label} (${this.colorSchemeLabel(self.effectiveColorScheme)})`\n : label\n },\n graphMenuItems(): MenuItem[] {\n const options = this.layoutOptionMenuItems()\n const mode = layoutModeByValue(self.chosenLayoutMode)\n const engine = ENGINE_NAMES.find(([e]) => e === self.layoutEngine)![1]\n return [\n {\n label: `Layout: ${layoutMenuLabel(mode)}${mode.value === 'force' ? ` (${engine})` : ''}`,\n icon: HubIcon,\n subMenu: [\n ...LAYOUT_MODES.flatMap(mode => {\n const item = {\n type: 'radio' as const,\n disabled: self.graph ? !mode.available(self.graph) : false,\n disabledHelpText: mode.description,\n }\n return mode.value === 'force'\n ? ENGINE_NAMES.map(([engine, name]) => ({\n ...item,\n label: `${layoutMenuLabel(mode)} (${name})`,\n checked:\n self.chosenLayoutMode === mode.value &&\n self.layoutEngine === engine,\n onClick: () => {\n void self.switchForceEngine(engine)\n },\n }))\n : [\n {\n ...item,\n label: layoutMenuLabel(mode),\n checked: self.chosenLayoutMode === mode.value,\n onClick: () => {\n void self.switchLayout(mode.value)\n },\n },\n ]\n }),\n ...(options.length > 0\n ? [{ type: 'divider' as const }, ...options]\n : []),\n ...(self.hostPlacesX\n ? []\n : [\n { type: 'divider' as const },\n {\n label: 'Zoom to fit',\n onClick: () => {\n self.refitView()\n },\n },\n ]),\n ],\n },\n {\n label: `Color: ${self.colorSchemeLock?.value ?? this.colorSchemeLabel(self.chosenColorScheme)}`,\n icon: PaletteIcon,\n disabled: self.colorSchemeLock !== undefined,\n disabledHelpText: self.colorSchemeLock?.why,\n subMenu: radioItems(\n COLOR_SCHEMES.map(({ value }) => ({\n value,\n label: this.colorSchemeLabel(value),\n })),\n self.chosenColorScheme,\n self.setColorScheme,\n ),\n },\n {\n label: 'Show...',\n icon: VisibilityIcon,\n subMenu: this.showMenuItems(),\n },\n ]\n },\n // the graph's way out, in the \"Launch view\" submenu every view shares\n launchMenuItems(): MenuItem[] {\n const items: MenuItem[] = []\n const contributors = self.launchableAssemblies\n const reference = self.graphRegion?.assemblyName\n for (const item of graphLaunchMenuItems({\n contributors,\n linearContributors: self.host\n ? contributors.filter(c => c.sample !== reference)\n : contributors,\n syntenyTracks: self.syntenyLaunchTracks,\n onShowLinear: target => {\n self.showInLinearView(target)\n },\n onShowSynteny: trackId => {\n self.showSyntenyView(trackId)\n },\n })) {\n pushLaunchItem(items, item)\n }\n return items\n },\n }))\n", "import { cutsWholeWalks as wholeWalksRule } from '@jbrowse/bandage-core/layout/walkStrip'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { getSession } from '@jbrowse/core/util'\n\nimport {\n configHaplotypes,\n graphReferenceAssembly,\n offReferenceProblem,\n} from '../graphTrackConfig'\nimport { canonicalAssemblyName } from '../launchFromGraph/launchFromGraph'\nimport { withLaunchActions } from './pane/launchActions'\n\nimport type { SubgraphCutOptions, SubgraphRegion } from '../GetSubgraph'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\nexport { MAX_GRAPH_REGION_BP, fileName, formatSpanBp } from './pane/paneBase'\n\n// The pane every graph drawing is: a view of its own, or a display inside a\n// linear view. Built in stages under pane/, each extending the one before,\n// and given here the cut options both hosts share.\nexport const GraphPane = withLaunchActions\n .views(self => ({\n // the config's defaultHaplotypes, which a cut is for until the user\n // picks others\n get trackHaplotypes(): string[] | undefined {\n const adapter = self.sourceAdapter\n return adapter && configHaplotypes(adapter)\n },\n }))\n .views(self => ({\n get cutHaplotypes() {\n return self.subgraphHaplotypes ?? self.trackHaplotypes\n },\n // Why the source track cannot cut `region`, which is a window on an\n // assembly other than the graph's reference. A track may name its\n // reference by an alias of the assembly the window is on.\n offReference(region: SubgraphRegion) {\n const track = self.sourceTrack\n const reference = track && graphReferenceAssembly(track)\n const session = getSession(self)\n return reference === undefined\n ? undefined\n : offReferenceProblem(\n canonicalAssemblyName(session, reference),\n canonicalAssemblyName(session, region.assemblyName),\n )\n },\n // Walk rows, and the strip of them under a node layout, measure whole\n // walks, which a GBZ cut only follows when asked, so a layout change\n // that changes whether the drawing needs them cuts the track again.\n cutChangedFrom(from: LayoutModeValue) {\n const before = wholeWalksRule(layoutModeByValue(from), {\n walkStrip: self.walkStrip,\n host: !!self.host,\n })\n return (\n self.cutsWholeWalks !== before ||\n (from === 'walkrows') !== (self.chosenLayoutMode === 'walkrows')\n )\n },\n }))\n .views(self => ({\n get cutOptions(): SubgraphCutOptions {\n return {\n hops: self.subgraphContext,\n haplotypes: self.cutHaplotypes,\n ...(self.chosenLayoutMode === 'walkrows' ? { walkRows: true } : {}),\n ...(self.cutsWholeWalks ? { snarls: 'overlapping' as const } : {}),\n }\n },\n }))\n\nexport type GraphPaneModel = Instance<typeof GraphPane>\n", "import {\n LAYOUT_MODE_VALUES,\n layoutModeByValue,\n} from '@jbrowse/bandage-core/layoutModes'\nimport { BaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'\nimport { getSession } from '@jbrowse/core/util'\nimport { addDisposer, isAlive, types } from '@jbrowse/mobx-state-tree'\nimport { reaction } from 'mobx'\n\nimport { HOVER_HIGHLIGHT_VALUES } from './hoverHighlight'\nimport { lenientMaybeEnum } from './lenientEnum'\nimport { GraphPane, fileName, formatSpanBp } from './model'\nimport { canonicalRegion } from '../launchFromGraph/launchFromGraph'\n\nimport type { GraphLayers } from './graphLayers'\nimport type { NodeColor } from './nodeColor'\nimport type { NodeSize } from './nodeSize'\nimport type { SubgraphRegion } from '../GetSubgraph'\nimport type { GraphGrammar, GraphRows } from './pane/graphViews'\nimport type { FacetInput } from '@jbrowse/bandage-core/facetGrid'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { FileLocation } from '@jbrowse/core/util/types'\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\nexport default function stateModelFactory() {\n return types\n .compose(\n 'GraphGenomeView',\n BaseViewModel,\n GraphPane,\n types.model({\n type: types.literal('GraphGenomeView'),\n // a whole GFA the view loads on attach, kept so the source round-trips\n // through a session snapshot\n gfaLocation: types.maybe(types.frozen<FileLocation>()),\n // the reference window the file or the cut was stated beside\n loadedRegion: types.maybe(types.frozen<SubgraphRegion>()),\n // A session track the view cuts `loadedRegion` from once, as 4.0\n // sessions and the docs' figure specs state it. Following the linear\n // view is the track's job (LinearGraphDisplay).\n loadedTrackId: types.optional(types.string, ''),\n // unset is force\n layoutMode: lenientMaybeEnum(LAYOUT_MODE_VALUES),\n color: types.maybe(types.frozen<NodeColor>()),\n size: types.maybe(types.frozen<NodeSize>()),\n layers: types.maybe(types.frozen<GraphLayers>()),\n facet: types.maybe(types.frozen<FacetInput>()),\n rows: types.maybe(types.frozen<GraphRows>()),\n // unset is nodes\n hover: lenientMaybeEnum(HOVER_HIGHLIGHT_VALUES),\n }),\n )\n .views(self => ({\n get grammar(): GraphGrammar {\n return {\n layoutMode: self.layoutMode,\n color: self.color,\n size: self.size,\n layers: self.layers,\n facet: self.facet,\n rows: self.rows,\n hover: self.hover,\n }\n },\n }))\n .actions(self => ({\n writeGrammar(settings: GraphGrammar) {\n Object.assign(self, settings)\n },\n }))\n .volatile(() => ({\n widthMeasured: false,\n }))\n .actions(self => {\n const setBaseWidth = self.setWidth\n return {\n setWidth(width: number) {\n setBaseWidth(width)\n self.widthMeasured = true\n },\n }\n })\n .views(self => ({\n get rpcSessionId() {\n return self.id\n },\n // a view is not its own containing view\n get paneWidth() {\n return self.width\n },\n // until then the width is BaseViewModel's 800 px default\n get paneMeasured() {\n return self.widthMeasured\n },\n get sourceGfaLocation() {\n return self.gfaLocation\n },\n get sourceTrack(): AnyConfigurationModel | undefined {\n return self.loadedTrackId\n ? self.sessionTrack(self.loadedTrackId)\n : undefined\n },\n get canRetryLoad() {\n return (\n self.gfaLocation !== undefined ||\n (self.loadedTrackId !== '' && self.loadedRegion !== undefined)\n )\n },\n }))\n .views(self => ({\n get hasPendingSource() {\n return self.canRetryLoad && !self.graph && !self.loadCanceled\n },\n menuItems() {\n return [...self.exportMenuItems(), ...self.launchMenuItems()]\n },\n }))\n .actions(self => {\n const clearPane = self.clearGraph\n function loadRegion(region: SubgraphRegion | undefined) {\n if (self.gfaLocation) {\n // a whole file has no assembly to name the view by\n if (!self.displayName) {\n self.setDisplayName(fileName(self.gfaLocation))\n }\n return self.loadGFAFromLocation(self.gfaLocation, region)\n }\n if (!self.loadedTrackId || !region) {\n return undefined\n }\n const adapter = self.sourceAdapter\n const span = region.end - region.start\n const problem = self.offReference(region)\n if (!adapter) {\n self.setError(\n new Error(\n `The track this graph was cut from, \"${self.loadedTrackId}\", is not in this session`,\n ),\n )\n } else if (problem) {\n self.setError(new Error(problem))\n } else if (span > self.maxRegionBp) {\n self.setError(\n new Error(\n `Region too large (${formatSpanBp(span)}) \u2014 zoom in to view graph (max ${formatSpanBp(self.maxRegionBp)})`,\n ),\n )\n } else {\n return self.cutSubgraph(adapter, region, self.cutOptions)\n }\n return undefined\n }\n return {\n // the stated source goes too, or a reloaded session would load the\n // dismissed graph again, and so does a name taken from its file\n clearGraph() {\n clearPane()\n if (\n self.gfaLocation &&\n self.displayName === fileName(self.gfaLocation)\n ) {\n self.displayName = undefined\n }\n self.gfaLocation = undefined\n self.loadedRegion = undefined\n self.loadedTrackId = ''\n },\n // The graph keeps the region by the session's names, which hover sync\n // and launches compare with, so a stated alias resolves first, once\n // its assembly's refName aliases have loaded.\n load(): Promise<void> | undefined {\n const stated = self.loadedRegion\n const session = getSession(self)\n const { assemblyManager } = session\n const assembly =\n stated && assemblyManager.has(stated.assemblyName)\n ? assemblyManager.get(stated.assemblyName)\n : undefined\n return stated && assembly?.initialized === false\n ? assemblyManager\n .waitForAssembly(stated.assemblyName)\n .catch(() => undefined)\n .then(() =>\n self.loadedRegion === stated\n ? loadRegion(canonicalRegion(session, stated))\n : undefined,\n )\n : loadRegion(stated && canonicalRegion(session, stated))\n },\n }\n })\n .actions(self => ({\n retryLoad() {\n void self.load()\n },\n setGfaLocation(location: FileLocation) {\n self.gfaLocation = location\n },\n // the strip's toggle cuts the track again too (afterAttach)\n relayoutFrom(from: LayoutModeValue) {\n return self.loadedTrackId && self.cutChangedFrom(from)\n ? self.load()\n : self.recomputeLayout()\n },\n // Stated as the source once it loads, so a saved session reopens it; a\n // URL that fails stays in the import form to be corrected.\n async openGfaLocation(location: FileLocation) {\n await self.loadGFAFromLocation(location)\n if (isAlive(self) && self.hasGraph) {\n this.setGfaLocation(location)\n if (!self.displayName) {\n self.setDisplayName(fileName(location))\n }\n }\n },\n // Here rather than when the rendering backend starts: the canvas only\n // mounts once there is a graph, so a view whose graph must be fetched\n // would never fetch it.\n afterAttach() {\n if (!self.graph) {\n void self.load()\n }\n addDisposer(\n self,\n reaction(\n () => self.walkStrip,\n () => {\n if (\n self.loadedTrackId &&\n !layoutModeByValue(self.chosenLayoutMode).wholeWalks\n ) {\n void self.load()\n }\n },\n ),\n )\n },\n }))\n}\n\nexport type GraphGenomeViewModel = Instance<\n ReturnType<typeof stateModelFactory>\n>\n", "import { lazy } from 'react'\n\nimport ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'\nimport { defineLaunchKeys } from '@jbrowse/core/util/withLaunchInput'\n\nimport modelFactory from './viewModel'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// No launch keys, declared so `loadSessionSpec` reports a spec's unknown keys\n// instead of dropping them silently.\nconst graphLaunchKeys = defineLaunchKeys<object>()({})\n\nexport default function GraphGenomeViewF(pluginManager: PluginManager) {\n pluginManager.addViewType(() => {\n return new ViewType({\n name: 'GraphGenomeView',\n displayName: 'Graph genome view',\n stateModel: modelFactory(),\n launchKeys: graphLaunchKeys,\n ReactComponent: lazy(() => import('./components/GraphGenomeView')),\n })\n })\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport {\n TrackType,\n createBaseTrackConfig,\n createBaseTrackModel,\n} from '@jbrowse/core/pluggableElementTypes'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\n\n// core's synteny displays, copied to ask for headerLanes so only the gbz-base\n// and walk-tabix adapters open in a synteny, dotplot or circular view\nexport const SYNTENY_DISPLAYS = [\n 'MultiWaySyntenyDisplay',\n 'LinearSyntenyDisplay',\n 'DotplotDisplay',\n 'ChordSyntenyDisplay',\n]\n\nfunction displaysInOrder(pluginManager: PluginManager): DisplayType[] {\n const displays = pluginManager.getElementTypesInGroup(\n 'display',\n ) as DisplayType[]\n const named = (name: string) => displays.find(d => d.name === name)\n const needsLanes = (display: DisplayType | undefined) =>\n display &&\n Object.assign(Object.create(display) as DisplayType, {\n adapterCapabilities: ['headerLanes'],\n })\n return [\n named('LinearGraphDisplay'),\n named('LinearBasicDisplay'),\n ...SYNTENY_DISPLAYS.map(name => needsLanes(named(name))),\n ].filter((d): d is DisplayType => d !== undefined)\n}\n\nexport default function GraphTrackF(pluginManager: PluginManager) {\n pluginManager.addTrackType(() => {\n const configSchema = ConfigurationSchema(\n 'GraphTrack',\n {},\n {\n baseConfiguration: createBaseTrackConfig(pluginManager),\n explicitIdentifier: 'trackId',\n },\n )\n const track = new TrackType({\n name: 'GraphTrack',\n displayName: 'Pangenome graph track',\n configSchema,\n stateModel: createBaseTrackModel(\n pluginManager,\n 'GraphTrack',\n configSchema,\n ),\n })\n for (const display of displaysInOrder(pluginManager)) {\n track.addDisplayType(display)\n }\n return track\n })\n}\n", "import type modelFactory from './GraphGenomeView/viewModel'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\nimport type { SnapshotIn } from '@jbrowse/mobx-state-tree'\n\n// Every view prop, taken off the model so a new prop widens the launch with\n// it; `type` is the dispatch key, not a setting.\nexport type LaunchGraphGenomeViewArgs = Partial<\n Omit<SnapshotIn<ReturnType<typeof modelFactory>>, 'type'>\n> & {\n session: AbstractSessionModel\n}\n\ndeclare module '@jbrowse/core/PluginManager' {\n interface ExtensionPointRegistry {\n 'LaunchView-GraphGenomeView': {\n args: LaunchGraphGenomeViewArgs\n result: LaunchGraphGenomeViewArgs\n }\n }\n}\n\nexport default function LaunchGraphGenomeViewF(pluginManager: PluginManager) {\n /** #extensionPoint LaunchView-GraphGenomeView | async | Programmatically launch a graph genome view */\n pluginManager.addToExtensionPoint('LaunchView-GraphGenomeView', args => {\n const { session, ...spec } = args\n session.addView('GraphGenomeView', spec)\n return args\n })\n}\n", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/DisplayType\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes/DisplayType\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/display-kit/trackHeightConfigSchemaFields\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/display-kit/trackHeightConfigSchemaFields\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const trackHeightConfigSchemaFields = /* @__PURE__ */ read(\"trackHeightConfigSchemaFields\")\nexport default host && host.__esModule ? host.default : host", "import { LAYOUT_MODE_VALUES } from '@jbrowse/bandage-core/layoutModes'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { trackHeightConfigSchemaFields } from '@jbrowse/display-kit/trackHeightConfigSchemaFields'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport { HOVER_HIGHLIGHT_VALUES } from '../GraphGenomeView/hoverHighlight'\n\n/**\n * #config LinearGraphDisplay\n * The graph drawn as a track of the linear genome view. A layout whose x is\n * reference bp draws under the view's coordinates and re-cuts as the view\n * moves; force, ordered and walk rows draw in their own coordinates, fitted to\n * the track.\n */\nexport function configSchemaFactory() {\n return ConfigurationSchema(\n 'LinearGraphDisplay',\n {\n /**\n * #slot\n * the layout the track opens in\n */\n layoutMode: {\n type: 'stringEnum',\n model: types.enumeration('LayoutMode', LAYOUT_MODE_VALUES),\n defaultValue: 'auto',\n },\n /**\n * #slot\n * the node color: `grey` or `uniform`, or the field nodes are colored\n * by, `depth`, `length`, `rank`, `position` or `id` (`scale:\n * 'categorical'` or `scheme: 'rainbow'`). `domainMin`/`domainMax` span\n * the position ramp. `{}` colors an anchored graph by position.\n * ```js\n * { color: { field: 'depth' } }\n * ```\n */\n color: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * the node thickness: a px number draws every node that thick;\n * `{ field: 'depth', value }` thickens a node the more paths carry it,\n * around `value` px\n */\n size: {\n type: 'frozen',\n defaultValue: { field: 'depth', value: 6 },\n },\n /**\n * #slot\n * what the drawing adds over its nodes and edges, stated as changes to\n * the defaults: `paths`, `bubbles` and `walkStrip` are off, `deletions`,\n * `genes` and `referenceStrip` on\n * ```js\n * { layers: { bubbles: true, genes: false } }\n * ```\n */\n layers: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * one section per value of a field: a node layout draws a panel per\n * `walk` or `sample`, and walk rows stack into a section per value of\n * a sample table column. A bare field, or `{ field, domain, columns }`\n */\n facet: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * the rows walk rows draw: `{ kept: [...] }` names the samples shown\n */\n rows: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * what the pointer lights: `nodes` lightens a hovered node and bands its\n * span on the view; `everything` also lights edges, and the node at the\n * view's pointer bp\n */\n hover: {\n type: 'stringEnum',\n model: types.enumeration('HoverHighlight', HOVER_HIGHLIGHT_VALUES),\n defaultValue: 'nodes',\n },\n ...trackHeightConfigSchemaFields({\n defaultHeight: 300,\n height: 'the height of the track the graph is drawn in',\n }),\n },\n { explicitlyTyped: true, explicitIdentifier: 'displayId' },\n )\n}\n\nexport type LinearGraphDisplayConfigModel = ReturnType<\n typeof configSchemaFactory\n>\n", "const host = JBrowseExports[\"@jbrowse/core/svg/svgReady\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/svg/svgReady\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const awaitSvgReady = /* @__PURE__ */ read(\"awaitSvgReady\")\nexport const awaitSvgRenders = /* @__PURE__ */ read(\"awaitSvgRenders\")\nexport const awaitViewInitialized = /* @__PURE__ */ read(\"awaitViewInitialized\")\nexport const computeSvgReady = /* @__PURE__ */ read(\"computeSvgReady\")\nexport const throwOnExportErrors = /* @__PURE__ */ read(\"throwOnExportErrors\")\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/display-kit/TrackHeightMixin\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/display-kit/TrackHeightMixin\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/display-kit/plotMenu\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/display-kit/plotMenu\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const editPlotMenuItems = /* @__PURE__ */ read(\"editPlotMenuItems\")\nexport const openPlotDialog = /* @__PURE__ */ read(\"openPlotDialog\")\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/render-core/displayPhase\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/render-core/displayPhase\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const computeActivityPhase = /* @__PURE__ */ read(\"computeActivityPhase\")\nexport const computeDisplayPhase = /* @__PURE__ */ read(\"computeDisplayPhase\")\nexport const computeDisplayStatusPhase = /* @__PURE__ */ read(\"computeDisplayStatusPhase\")\nexport default host && host.__esModule ? host.default : host", "import type { SubgraphRegion } from '../GetSubgraph'\nimport type { HostWindow } from '../GraphGenomeView/host'\n\n// Whether `seen` is near where a cut came back over its node limit. The graph\n// is as dense as that only near it, so the refusal stands for windows as wide\n// or wider on the same contig within one window-width of it.\nexport function denseCovers(\n dense: SubgraphRegion | undefined,\n seen: HostWindow,\n) {\n if (\n dense?.refName !== seen.refName ||\n dense.assemblyName !== seen.assemblyName\n ) {\n return false\n }\n const span = dense.end - dense.start\n return (\n seen.end - seen.start >= span &&\n seen.end > dense.start - span &&\n seen.start < dense.end + span\n )\n}\n", "import { lazy } from 'react'\nimport type { ReactNode } from 'react'\n\nimport { LAYOUT_ENGINE_VALUES } from '@jbrowse/bandage-core/layoutEngines'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n ConfigurationReference,\n getConf,\n setConf,\n} from '@jbrowse/core/configuration'\nimport { BaseDisplay } from '@jbrowse/core/pluggableElementTypes'\nimport { computeSvgReady } from '@jbrowse/core/svg/svgReady'\nimport { getRpcSessionId, getSession } from '@jbrowse/core/util'\nimport TrackHeightMixin from '@jbrowse/display-kit/TrackHeightMixin'\nimport { editPlotMenuItems } from '@jbrowse/display-kit/plotMenu'\nimport { addDisposer, isAlive, types } from '@jbrowse/mobx-state-tree'\nimport {\n computeActivityPhase,\n computeDisplayStatusPhase,\n} from '@jbrowse/render-core/displayPhase'\nimport BubbleChartIcon from '@mui/icons-material/BubbleChart'\nimport RouteIcon from '@mui/icons-material/Route'\nimport SettingsIcon from '@mui/icons-material/Settings'\nimport { reaction } from 'mobx'\n\nimport { isNodeLimitError } from '../nodeLimitError'\nimport { denseCovers } from './denseWindow'\nimport { cutHolds, hostCut, hostWindow } from '../GraphGenomeView/host'\nimport { lenientOptionalEnum } from '../GraphGenomeView/lenientEnum'\nimport { GraphPane, formatSpanBp } from '../GraphGenomeView/model'\nimport { FACET_KEY_PX } from '../GraphGenomeView/pane/fitViews'\nimport { paneBase } from '../GraphGenomeView/pane/paneBase'\nimport {\n configHaplotypes,\n cutsByHaplotype,\n trackLanes,\n walkIndexed,\n} from '../graphTrackConfig'\nimport { pushLaunchItem } from '../launchFromGraph/pushLaunchItem'\n\nimport type { LinearGraphDisplayConfigModel } from './configSchema'\nimport type { SubgraphRegion, SubgraphTier } from '../GetSubgraph'\nimport type { GraphLayers } from '../GraphGenomeView/graphLayers'\nimport type { HostWindow } from '../GraphGenomeView/host'\nimport type { GraphGrammar } from '../GraphGenomeView/pane/graphViews'\nimport type { LaunchGraphGenomeViewArgs } from '../LaunchGraphGenomeView'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { MenuItem } from '@jbrowse/core/ui'\nimport type { ExportSvgDisplayOptions } from '@jbrowse/display-kit/types'\nimport type { Instance, SnapshotOut } from '@jbrowse/mobx-state-tree'\nimport type { DisplayStatusPhase } from '@jbrowse/render-core/displayPhase'\n\ntype GraphViewSpec = Omit<LaunchGraphGenomeViewArgs, 'session'>\n\n// the pane's viewport, which a new graph view fits to its drawing\nconst VIEWPORT_PROPS = new Set(['scale', 'translateX', 'translateY'])\n\ntype PaneSettings = Omit<\n SnapshotOut<typeof paneBase>,\n 'scale' | 'translateX' | 'translateY'\n>\n\nfunction paneSettings(pane: Instance<typeof paneBase>) {\n return Object.fromEntries(\n Object.keys(paneBase.properties)\n .filter(key => !VIEWPORT_PROPS.has(key))\n .map(key => [key, pane[key as keyof typeof pane]]),\n ) as PaneSettings\n}\n\n// A variant under this many of the linear view's pixels folds into the\n// reference before layout, so the drawing gains detail as the view zooms in.\n// It is the width `gfa-to-tabix build` gives a backbone node at the zoom a\n// graph hands over to its coarse tier, so a tier folded at its handover draws\n// what the fine cut drew just below it.\nexport const FOLD_PX = 10\n\n// The linear view's bp per px past which a coarse tier is cut: its own\n// `aboveBpPerPx`, else the zoom at which the fine cut folds what the tier did\nexport function coarseHandover(coarse: unknown) {\n const { aboveBpPerPx, foldBelowBp } = (coarse ?? {}) as {\n aboveBpPerPx?: unknown\n foldBelowBp?: unknown\n }\n return typeof aboveBpPerPx === 'number'\n ? aboveBpPerPx\n : typeof foldBelowBp === 'number' && foldBelowBp > 0\n ? foldBelowBp / FOLD_PX\n : undefined\n}\n\nconst GraphTrackSettingsDialog = lazy(\n () => import('./components/GraphTrackSettingsDialog'),\n)\n\nexport function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {\n return types\n .compose(\n 'LinearGraphDisplay',\n BaseDisplay,\n TrackHeightMixin(),\n GraphPane,\n types.model({\n type: types.literal('LinearGraphDisplay'),\n configuration: ConfigurationReference(configSchema),\n // a zoom re-cuts the graph, and stress keeps the drawing's\n // orientation across re-cuts where FMMM turns it (ADR-044)\n layoutEngine: lenientOptionalEnum(LAYOUT_ENGINE_VALUES, 'stress'),\n // the window the graph on screen was asked for, so a restored\n // session cuts it again\n cutRegion: types.maybe(types.frozen<SubgraphRegion>()),\n // whether that cut came from the track's coarse pair\n // (RgfaTabixAdapter), on which no bp cap applies\n coarseCut: types.optional(types.boolean, false),\n }),\n )\n .volatile(() => ({\n recuts: 0,\n // the host window the settle clock last woke on\n settledWindow: undefined as HostWindow | undefined,\n // where a cut came back over its node limit (denseCovers)\n dense: undefined as SubgraphRegion | undefined,\n // the haplotypes a walk-indexed graph's header names, once read\n haplotypeNames: undefined as string[] | undefined,\n // the fold the latest cut asked for\n cutFoldBp: 0,\n }))\n .views(self => ({\n get grammar(): GraphGrammar {\n return {\n layoutMode: getConf(self, 'layoutMode'),\n color: getConf(self, 'color'),\n size: getConf(self, 'size'),\n layers: getConf(self, 'layers') as GraphLayers,\n facet: getConf(self, 'facet'),\n rows: getConf(self, 'rows'),\n hover: getConf(self, 'hover'),\n }\n },\n // The linear view leaves its highlight bands off this track while false\n get drawsGenomicCoordinates() {\n return self.layoutResult === undefined || self.hostPlacesX\n },\n get canvasHeight() {\n return self.height\n },\n get canRetryLoad() {\n return self.cutRegion !== undefined\n },\n // the config's defaultHaplotypes, else the lanes the track names\n get trackHaplotypes() {\n const adapter = self.sourceAdapter\n const track = self.sourceTrack\n return (\n (adapter && configHaplotypes(adapter)) ?? (track && trackLanes(track))\n )\n },\n // the linear view's zoom past which the track's coarse pair is cut, or\n // undefined for a track with none\n get coarseAboveBpPerPx() {\n return coarseHandover(self.sourceAdapter?.coarse)\n },\n }))\n .views(self => ({\n tierAt(bpPerPx: number): SubgraphTier {\n const above = self.coarseAboveBpPerPx\n return above !== undefined && bpPerPx > above ? 'coarse' : 'fine'\n },\n capFor(tier: SubgraphTier) {\n return tier === 'coarse' ? Infinity : self.maxRegionBp\n },\n // Whether a zoom has moved far enough from the one the drawing was\n // folded for that folding again would show or hide more. A graph with\n // walks is never folded, and a fold rounded to 0 bp counts as 1 bp.\n foldDrifted(bpPerPx: number) {\n const want = FOLD_PX * bpPerPx\n const had = self.cutFoldBp\n return (\n !self.graph?.paths?.length &&\n (want >= 2 * Math.max(had, 1) ||\n (self.foldedBelowBp !== undefined && want <= had / 2))\n )\n },\n get cutTier(): SubgraphTier {\n return self.coarseCut && self.coarseAboveBpPerPx !== undefined\n ? 'coarse'\n : 'fine'\n },\n }))\n .views(self => ({\n get settledCapBp() {\n const seen = self.settledWindow\n return seen ? self.capFor(self.tierAt(seen.bpPerPx)) : Infinity\n },\n }))\n .views(self => ({\n get regionTooLarge() {\n const seen = self.settledWindow\n return seen !== undefined && seen.end - seen.start > self.settledCapBp\n },\n get regionTooLargeReason() {\n const seen = self.settledWindow\n return seen\n ? `Region too large for a graph cut (${formatSpanBp(seen.end - seen.start)}, max ${formatSpanBp(self.settledCapBp)})`\n : ''\n },\n get zoomCanReleaseGate() {\n return true\n },\n get fetchCanceled() {\n return self.loadCanceled\n },\n }))\n .views(self => ({\n get svgReady() {\n return computeSvgReady(\n {\n error: self.error,\n regionTooLarge: self.regionTooLarge,\n extraTerminal: false,\n fetchCanceled: self.loadCanceled,\n },\n () => !self.isLoading && self.hasGraph && !!self.layoutResult,\n )\n },\n }))\n .views(self => ({\n // A backend that failed is an error the canvas reports with its retry;\n // the status chrome has no renderError phase of its own. A cut refused\n // over its node limit is an error marked regionTooLarge, which core's\n // error bar shows as a zoom-in notice instead.\n get displayPhase(): DisplayStatusPhase {\n return computeDisplayStatusPhase(\n {\n regionTooLarge: self.regionTooLarge,\n error: self.error ?? self.renderError,\n },\n () =>\n computeActivityPhase(\n {\n isMinimized: self.isMinimized,\n fetchInert: false,\n viewportEmpty:\n self.host?.initialized === true &&\n self.host.hasVisibleContent === false,\n isLoading: self.isLoading || !self.hasGraph,\n fetchCanceled: self.loadCanceled,\n awaitingDependentData: false,\n rendersCanvas: true,\n canvasDrawn: self.painted && self.geometryPainted,\n },\n () => true,\n () => self.host?.effectiveBodyMounted ?? true,\n ),\n )\n },\n }))\n .actions(self => ({\n // Into the config, so a share link, Edit plot and Reset track\n // settings all see it\n writeGrammar(settings: GraphGrammar) {\n for (const [slot, value] of Object.entries(settings)) {\n setConf(self, slot as keyof GraphGrammar, value)\n }\n },\n // The setters describe the next cut, which recut makes\n setSubgraphContext(hops: number) {\n self.subgraphContext = hops\n self.dense = undefined\n },\n setSubgraphHaplotypes(haplotypes: string[] | undefined) {\n self.subgraphHaplotypes = haplotypes\n self.dense = undefined\n },\n setDense(window: SubgraphRegion | undefined) {\n self.dense = window\n },\n setHaplotypeNames(names: string[] | undefined) {\n self.haplotypeNames = names\n },\n setMaxRegionBp(bp: number) {\n self.maxRegionBp = bp\n },\n // Cut `cutRegion` again with the current options. A coarse cut hops as\n // a fine one does, since a tier is the same graph folded.\n cut() {\n const region = self.cutRegion\n const adapterConfig = self.sourceAdapter\n if (!region || !adapterConfig) {\n return\n }\n const problem = self.offReference(region)\n if (problem) {\n self.clearGraph()\n self.setError(new Error(problem))\n return\n }\n const coarse = self.cutTier === 'coarse'\n self.cutFoldBp = Math.round(\n FOLD_PX * (self.settledWindow?.bpPerPx ?? self.host?.bpPerPx ?? 0),\n )\n return self.cutSubgraph(\n adapterConfig,\n region,\n { ...self.cutOptions, tier: coarse ? 'coarse' : undefined },\n self.cutFoldBp,\n )\n },\n }))\n .actions(self => ({\n recutAt(seen: HostWindow) {\n const tier = self.tierAt(seen.bpPerPx)\n self.coarseCut = tier === 'coarse'\n self.cutRegion = hostCut(\n seen,\n self.capFor(tier),\n layoutModeByValue(self.chosenLayoutMode).cutMargins,\n )\n self.recuts++\n return self.cut()\n },\n }))\n .actions(self => ({\n // The settle clock. A window the cut still holds fetches nothing; one\n // past its edge re-cuts, on the tier the zoom asks for, with margins\n // when the host places x and the window alone when the layout draws\n // its own picture of it. A canceled cut is re-made by the next move,\n // and a window a refused cut covers keeps its notice without asking\n // again. Returns whether it re-cut.\n settleOn(seen: HostWindow): boolean {\n self.settledWindow = seen\n const margins = layoutModeByValue(self.chosenLayoutMode).cutMargins\n if (\n self.regionTooLarge ||\n denseCovers(self.dense, seen) ||\n (!self.loadCanceled &&\n self.tierAt(seen.bpPerPx) === self.cutTier &&\n cutHolds(self.cutRegion, seen, margins) &&\n !self.foldDrifted(seen.bpPerPx))\n ) {\n return false\n }\n // An outrun cut resolves without touching the error, so the error\n // is this cut's only while no later one has started\n const cut = self.recutAt(seen)\n const recut = self.recuts\n void Promise.resolve(cut).then(() => {\n if (\n isAlive(self) &&\n self.recuts === recut &&\n isNodeLimitError(self.error)\n ) {\n this.refuseDenseCut(seen)\n }\n })\n return true\n },\n // A cut refused for its node count holds nothing, so a window\n // narrower than this one cuts again\n refuseDenseCut(seen: HostWindow) {\n self.setDense(seen)\n self.cutRegion = undefined\n this.settleOn(self.settledWindow ?? seen)\n },\n // Cut the region again with the current options, or the window on\n // screen where a refused cut left no region\n recut() {\n if (self.cutRegion) {\n void self.cut()\n } else if (self.settledWindow) {\n this.settleOn(self.settledWindow)\n }\n },\n relayoutFrom(from: LayoutModeValue) {\n const seen = self.host ? hostWindow(self.host) : undefined\n if (\n seen &&\n !self.regionTooLarge &&\n (self.cutChangedFrom(from) ||\n layoutModeByValue(from).cutMargins !==\n layoutModeByValue(self.chosenLayoutMode).cutMargins)\n ) {\n return self.recutAt(seen)\n }\n return self.recomputeLayout()\n },\n retryLoad() {\n void self.cut()\n },\n reload() {\n void self.cut()\n },\n cancelFetchByUser() {\n self.stopLoad()\n },\n }))\n .actions(self => ({\n // A failed read leaves the picker taking typed names\n async fetchHaplotypeNames(\n adapterConfig: Record<string, unknown>,\n signal?: AbortSignal,\n ) {\n try {\n const names = await getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetGraphHaplotypes',\n { adapterConfig, signal },\n )\n if (isAlive(self) && !signal?.aborted) {\n self.setHaplotypeNames(names)\n }\n } catch (e) {\n if (!signal?.aborted) {\n console.warn('[LinearGraphDisplay] no haplotype names', e)\n }\n }\n },\n }))\n .actions(self => ({\n stretchWithHost(\n before: { bpPerPx: number; offsetPx: number },\n now: { bpPerPx: number; offsetPx: number },\n ) {\n const bounds = self.layoutBounds\n if (!bounds || !self.followsHostView) {\n return\n }\n // no longer the fit, so the fit autorun cannot undo it before the\n // re-cut lands; followNewLayout fits the new drawing\n if (self.viewportOwner === 'fit') {\n self.viewportOwner = 'user'\n }\n const k = before.bpPerPx / now.bpPerPx\n const midY =\n self.translateY + self.scaleY * (bounds.minY + bounds.h / 2)\n self.scale *= k\n self.translateX = k * (self.translateX + before.offsetPx) - now.offsetPx\n self.translateY = midY - k * (midY - self.translateY)\n },\n }))\n .actions(self => ({\n forceLoad() {\n const seen = self.settledWindow\n if (seen) {\n self.setMaxRegionBp(Math.ceil(seen.end - seen.start))\n self.settleOn(seen)\n }\n },\n // The host's two clocks. The frame clock moves x with every frame of\n // the linear view and fetches nothing; the settle clock wakes on its\n // debounced blocks.\n afterAttach() {\n if (self.cutRegion && !self.graph) {\n void self.cut()\n }\n let namesRead: AbortController | undefined\n addDisposer(self, () => {\n namesRead?.abort()\n })\n addDisposer(\n self,\n reaction(\n () => {\n const adapter = self.sourceAdapter\n return adapter && walkIndexed(adapter) ? adapter : undefined\n },\n adapterConfig => {\n namesRead?.abort()\n namesRead = undefined\n self.setHaplotypeNames(undefined)\n if (adapterConfig) {\n namesRead = new AbortController()\n void self.fetchHaplotypeNames(adapterConfig, namesRead.signal)\n }\n },\n {\n fireImmediately: true,\n // a lane adapter's config is rebuilt whenever an assembly is\n // added, which would drop and re-read the names\n equals: (a, b) => JSON.stringify(a) === JSON.stringify(b),\n name: 'GraphHaplotypeNames',\n },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.hostPlacesX,\n places => {\n if (!places) {\n self.releaseHost()\n }\n },\n { name: 'GraphHostPlacesX' },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.hostFrame,\n frame => {\n if (frame) {\n self.hostTransform(frame.scale, frame.translateX)\n }\n },\n {\n equals: (a, b) =>\n a?.scale === b?.scale && a?.translateX === b?.translateX,\n fireImmediately: true,\n name: 'GraphHostFrame',\n },\n ),\n )\n // The stretch clock: a drawing whose x is not bp follows the host's\n // zoom and pan as a screen-space map, x' = k x + c, until the re-cut\n // lands and morphs from it, as a linear track stretches its blocks\n let seen: { bpPerPx: number; offsetPx: number } | undefined\n addDisposer(\n self,\n reaction(\n () =>\n self.host && !self.hostPlacesX\n ? { bpPerPx: self.host.bpPerPx, offsetPx: self.host.offsetPx }\n : undefined,\n now => {\n const before = seen\n seen = now\n if (now && before && now.bpPerPx > 0) {\n self.stretchWithHost(before, now)\n }\n },\n {\n equals: (a, b) =>\n a?.bpPerPx === b?.bpPerPx && a?.offsetPx === b?.offsetPx,\n fireImmediately: true,\n name: 'GraphHostStretch',\n },\n ),\n )\n // A track clips what runs past its height, so side-by-side panels\n // grow it to what they need as a pane of their own. Only a change in\n // the panels does this, so a track shrunk afterwards stays shrunk.\n addDisposer(\n self,\n reaction(\n () => `${self.facetSetting.field} ${self.facetPlacement?.count}`,\n () => {\n const needs =\n (self.facetGridIn(self.paneCeiling - FACET_KEY_PX)?.total ??\n 0) + FACET_KEY_PX\n if ((self.facetGrid?.total ?? 0) + FACET_KEY_PX > self.height) {\n self.setHeight(Math.max(self.height, Math.ceil(needs)))\n }\n },\n { name: 'GraphFacetHeight' },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.host?.coarseDynamicBlocks,\n blocks => {\n const { host } = self\n const seen = blocks && host ? hostWindow(host) : undefined\n if (seen) {\n self.settleOn(seen)\n }\n },\n { fireImmediately: true, name: 'GraphHostSettle' },\n ),\n )\n },\n }))\n .views(self => ({\n // The window on screen as a view of its own, drawn as the track draws\n // it: the cut less the margins it holds for panning. A window forced\n // past the cap carries its own span as the cap.\n get graphViewSpec() {\n const seen = self.host ? hostWindow(self.host) : undefined\n const trackId = self.sourceTrackId\n if (\n !seen ||\n !trackId ||\n !self.hasGraph ||\n self.coarseCut ||\n self.regionTooLarge ||\n denseCovers(self.dense, seen)\n ) {\n return undefined\n }\n const start = Math.floor(seen.start)\n const end = Math.ceil(seen.end)\n return {\n ...paneSettings(self),\n loadedTrackId: trackId,\n loadedRegion: {\n refName: seen.refName,\n assemblyName: seen.assemblyName,\n start,\n end,\n },\n subgraphHaplotypes: self.cutHaplotypes,\n maxRegionBp: Math.max(self.maxRegionBp, end - start),\n ...self.grammar,\n layoutMode: self.chosenLayoutMode,\n connectedViewId: self.host?.id,\n } satisfies GraphViewSpec\n },\n }))\n .actions(self => ({\n openGraphView() {\n const spec = self.graphViewSpec\n if (spec) {\n getSession(self).addView('GraphGenomeView', spec)\n }\n },\n }))\n .views(self => ({\n // Which haplotypes a GBZ or walk-indexed cut is for: every one in the\n // graph, the config's default set or the assemblies the track names,\n // or a list chosen in Graph settings\n cutMenuItems(): MenuItem[] {\n const adapter = self.sourceAdapter\n const track = self.sourceTrack\n if (!adapter || !track || !cutsByHaplotype(adapter)) {\n return []\n }\n const defaults = configHaplotypes(adapter)\n const lanes = trackLanes(track)\n const names = self.haplotypeNames\n const chosen = self.subgraphHaplotypes\n const recut = (haplotypes: string[] | undefined) => {\n self.setSubgraphHaplotypes(haplotypes)\n self.recut()\n }\n return [\n { type: 'subHeader', label: 'Load' },\n {\n type: 'radio',\n label: names\n ? `Every haplotype in the graph (${names.length.toLocaleString()})`\n : 'Every haplotype in the graph',\n checked: chosen ? chosen.length === 0 : !defaults && !lanes,\n onClick: () => {\n recut([])\n },\n },\n ...(defaults || lanes\n ? [\n {\n type: 'radio' as const,\n label: defaults\n ? \"The track's default haplotypes\"\n : `The track's ${lanes?.length} assemblies`,\n checked: chosen === undefined,\n onClick: () => {\n recut(undefined)\n },\n },\n ]\n : []),\n {\n type: 'radio',\n label: 'Chosen in Graph settings...',\n checked: (chosen?.length ?? 0) > 0,\n onClick: () => {\n this.openSettings()\n },\n },\n ]\n },\n openSettings() {\n getSession(self).queueDialog(onClose => [\n GraphTrackSettingsDialog,\n { model: self, onClose },\n ])\n },\n async renderSvg(opts?: ExportSvgDisplayOptions): Promise<ReactNode> {\n const { renderGraphTrackSvg } = await import('./renderSvg')\n return renderGraphTrackSvg(\n self as unknown as LinearGraphDisplayModel,\n opts,\n )\n },\n trackMenuItems(): MenuItem[] {\n const launches = self.launchMenuItems()\n pushLaunchItem(launches, {\n label: 'Graph genome view',\n icon: BubbleChartIcon,\n disabled: !self.graphViewSpec,\n disabledHelpText:\n self.error && !isNodeLimitError(self.error)\n ? 'The track could not cut a graph here'\n : self.isLoading && !self.hasGraph\n ? 'The track is still cutting its graph'\n : 'Zoom in until the track cuts a graph',\n onClick: () => {\n self.openGraphView()\n },\n })\n const haplotypes = [\n ...this.cutMenuItems(),\n ...self.highlightMenuItems(),\n ]\n return [\n ...(haplotypes.length > 0\n ? [{ label: 'Haplotypes', icon: RouteIcon, subMenu: haplotypes }]\n : []),\n ...self.graphMenuItems(),\n {\n label: 'Graph settings...',\n icon: SettingsIcon,\n helpText: 'Subgraph, drawing and force-directed layout',\n onClick: () => {\n this.openSettings()\n },\n },\n ...launches,\n ...editPlotMenuItems(self),\n ]\n },\n }))\n}\n\nexport type LinearGraphDisplayStateModel = ReturnType<typeof stateModelFactory>\nexport type LinearGraphDisplayModel = Instance<LinearGraphDisplayStateModel>\n// what the track's own settings read, which the menus that open them cannot\n// name without naming themselves\nexport type LinearGraphCutModel = Omit<\n LinearGraphDisplayModel,\n 'trackMenuItems' | 'cutMenuItems' | 'openSettings' | 'renderSvg'\n>\n", "import { lazy } from 'react'\n\nimport DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\n\nimport { configSchemaFactory } from './configSchema'\nimport { stateModelFactory } from './model'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function LinearGraphDisplayF(pluginManager: PluginManager) {\n pluginManager.addDisplayType(() => {\n const configSchema = configSchemaFactory()\n return Object.assign(\n new DisplayType({\n name: 'LinearGraphDisplay',\n displayName: 'Graph',\n configSchema,\n stateModel: stateModelFactory(configSchema),\n // FeatureTrack and SyntenyTrack for the configs and share links that\n // name the graph display on one, which 4.0.7 and before required\n trackType: ['GraphTrack', 'FeatureTrack', 'SyntenyTrack'],\n viewType: 'LinearGenomeView',\n ReactComponent: lazy(() => import('./components/LinearGraphDisplay')),\n }),\n { adapterCapabilities: ['getSubgraph'] },\n )\n })\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\n\nimport { fileLocationSlot, tabixIndexSchema, tbiBeside } from '../panSNTabix.ts'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config MinigraphBubbleAdapter\n * #trackType FeatureTrack\n * #fileFormat graph | Minigraph bubble BED | `gfatools bubble` output; HPRC publishes one ready-made, so no preprocessing at all\n * the tabix-indexed BED `gfatools bubble` writes for a minigraph graph: one row\n * per bubble, on the reference's own coordinates. Unlike\n * [RgfaTabixAdapter](/docs/config/rgfatabixadapter) this needs no index build of\n * your own, because HPRC publishes this file beside its minigraph graph.\n *\n * It shows *where* the graph varies and by how much, not the graph itself.\n *\n * #example\n * ```js\n * {\n * type: 'MinigraphBubbleAdapter',\n * uri: 'https://jbrowse.org/demos/hprc/hprc-v2.1-mc-grch38.bubbles.bed.gz',\n * assemblyNameToPanSN: { hg38: 'GRCh38' },\n * }\n * ```\n */\n\nfunction normalizeSnapshot(snap: Record<string, unknown>) {\n const { uri, baseUri, csi } = snap\n return typeof uri === 'string'\n ? {\n ...snap,\n bubblesLocation: { uri, baseUri },\n index: tbiBeside(uri, baseUri, csi),\n }\n : snap\n}\n\nconst MinigraphBubbleAdapter = ConfigurationSchema(\n 'MinigraphBubbleAdapter',\n {\n /**\n * #slot\n */\n bubblesLocation: fileLocationSlot('/path/to/graph.bb.bed.gz'),\n /**\n * #slot\n */\n index: tabixIndexSchema(\n 'MinigraphBubbleIndex',\n '/path/to/graph.bb.bed.gz.tbi',\n ),\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN sample prefix, for when they\n * differ. `gfatools bubble` names each row after the graph's stable\n * sequence, so a Minigraph-Cactus graph yields `GRCh38#0#chr6` and an\n * `hg38` assembly needs `{ hg38: 'GRCh38' }`; HPRC's published v1.0\n * minigraph bubbles are bare (`chr6`) and need nothing.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n * preprocessor to allow the minimal config\n * ```json\n * { \"type\": \"MinigraphBubbleAdapter\", \"uri\": \"graph.bb.bed.gz\" }\n * ```\n */\n preProcessSnapshot: normalizeSnapshot,\n },\n)\n\nexport type MinigraphBubbleAdapterConfig = Instance<\n typeof MinigraphBubbleAdapter\n>\n\nexport default MinigraphBubbleAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function MinigraphBubbleAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'MinigraphBubbleAdapter',\n displayName: 'Minigraph bubble BED adapter',\n configSchema,\n adapterMetadata: {\n category: 'Graph adapters',\n },\n getAdapterClass: () =>\n import('./MinigraphBubbleAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { WALK_BUDGETS } from '@jbrowse/graph-walks'\n\nimport {\n fileLocationSlot,\n tabixIndexSchema,\n tbiBeside,\n walksLocations,\n} from '../panSNTabix.ts'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config RgfaTabixAdapter\n * #trackType GraphTrack\n * #fileFormat graph | Indexed GFA | Built by `gfa-to-tabix`; serves segments as features and extracts local subgraphs\n * two tabix-indexed BED files, one of a graph's segments and one of its links,\n * written by [gfa-to-tabix](https://github.com/GMOD/gfa-to-tabix) from an rGFA\n * or from a plain GFA with paths. Both of its layouts are read: `anchored`,\n * where one query per file returns the graph under a region, and `contig`,\n * where the adapter follows links onto other contigs.\n *\n * The `uri` shorthand takes the prefix the build script was given and resolves\n * `<uri>.segs.bed.gz`, `<uri>.links.bed.gz` and their `.tbi` indexes. `coarse`\n * takes the same shorthand for a second pair at one node per bubble, built by\n * `gfa-to-tabix fold`, plus either the zoom past which a graph view following\n * a linear view cuts it (`aboveBpPerPx`) or the size it was folded at\n * (`foldBelowBp`), from which the plugin derives that zoom.\n *\n * `walksUri` takes the prefix of a walk file in place of `uri`, and resolves\n * `<walksUri>.walks.bed.gz` and its `.tbi`. `gfa-to-tabix --walks -o <prefix>`\n * writes one per reference sample, so a track names one as\n * `<prefix>.<sample>`. The adapter reads walk format 3, which gfa-to-tabix\n * writes from 1.1, through @jbrowse/graph-walks. Such a graph's cut carries\n * the haplotypes' walks, and `defaultHaplotypes` names the ones it is cut for\n * until the user picks others.\n *\n * #example\n * ```js\n * {\n * type: 'RgfaTabixAdapter',\n * uri: 'https://example.com/hprc.rgfa',\n * coarse: { uri: 'https://example.com/hprc.fold10000', foldBelowBp: 10000 },\n * }\n * ```\n *\n * #example\n * ```js\n * {\n * type: 'RgfaTabixAdapter',\n * walksUri: 'https://example.org/hprc-v2.1-mc-grch38.GRCh38',\n * assemblyNameToPanSN: { hg38: 'GRCh38' },\n * defaultHaplotypes: ['HG002', 'HG00733', 'HG02257', 'NA19240'],\n * }\n * ```\n */\n\nfunction prefixLocations(snap: Record<string, unknown>) {\n const { uri, baseUri, csi } = snap\n return typeof uri === 'string'\n ? {\n ...snap,\n segmentsLocation: { uri: `${uri}.segs.bed.gz`, baseUri },\n segmentsIndex: tbiBeside(`${uri}.segs.bed.gz`, baseUri, csi),\n linksLocation: { uri: `${uri}.links.bed.gz`, baseUri },\n linksIndex: tbiBeside(`${uri}.links.bed.gz`, baseUri, csi),\n }\n : snap\n}\n\nfunction normalizeSnapshot(snap: Record<string, unknown>) {\n const { coarse, baseUri, csi } = snap\n return walksLocations(\n prefixLocations(\n typeof coarse === 'object' && coarse !== null\n ? { ...snap, coarse: prefixLocations({ baseUri, csi, ...coarse }) }\n : snap,\n ),\n )\n}\n\nconst RgfaTabixCoarseTier = ConfigurationSchema('RgfaTabixCoarseTier', {\n /**\n * #slot\n * The linear view's bp per px past which a graph following it cuts this\n * pair. Unset, with `foldBelowBp` unset too, means the track has no coarse\n * tier. There is no default,\n * because the zoom a fine cut stays drawable to depends on the graph's\n * density: a minigraph graph averages ~7 kb per segment, a base-level pggb\n * graph ~17 bp.\n */\n aboveBpPerPx: { type: 'maybeNumber' },\n /**\n * #slot\n * The size, in bp, this pair was folded at (`gfa-to-tabix fold --below`).\n * When `aboveBpPerPx` is unset, the handover is `foldBelowBp / 10`, the zoom\n * at which the fine cut folds the same variants away.\n */\n foldBelowBp: { type: 'maybeNumber' },\n /**\n * #slot\n */\n segmentsLocation: fileLocationSlot('/path/to/graph.tier.segs.bed.gz'),\n /**\n * #slot\n */\n segmentsIndex: tabixIndexSchema(\n 'RgfaCoarseSegmentsIndex',\n '/path/to/graph.tier.segs.bed.gz.tbi',\n ),\n /**\n * #slot\n */\n linksLocation: fileLocationSlot('/path/to/graph.tier.links.bed.gz'),\n /**\n * #slot\n */\n linksIndex: tabixIndexSchema(\n 'RgfaCoarseLinksIndex',\n '/path/to/graph.tier.links.bed.gz.tbi',\n ),\n})\n\nconst RgfaTabixAdapter = ConfigurationSchema(\n 'RgfaTabixAdapter',\n {\n /**\n * #slot\n * one row per segment: `stableName start end segmentId rank`, as emitted by\n * `gfatools gfa2bed -m`\n */\n segmentsLocation: fileLocationSlot('/path/to/graph.segs.bed.gz'),\n /**\n * #slot\n */\n segmentsIndex: tabixIndexSchema(\n 'RgfaSegmentsIndex',\n '/path/to/graph.segs.bed.gz.tbi',\n ),\n /**\n * #slot\n * one row per link per endpoint, each carrying both endpoints in full so a\n * neighbour on another stable sequence needs no segment-id lookup\n */\n linksLocation: fileLocationSlot('/path/to/graph.links.bed.gz'),\n /**\n * #slot\n */\n linksIndex: tabixIndexSchema(\n 'RgfaLinksIndex',\n '/path/to/graph.links.bed.gz.tbi',\n ),\n /**\n * #slot\n * a `gfa-to-tabix --walks` file in walk format 3: per reference chunk,\n * the reference's path, the ways haplotypes leave it and each haplotype's\n * piece. Unset means the graph has no walks.\n */\n walksLocation: fileLocationSlot(''),\n /**\n * #slot\n */\n walksIndex: tabixIndexSchema('RgfaWalksIndex'),\n /**\n * #slot\n * the most haplotype steps a cut keeps; a window whose walks hold more\n * shows a zoom-in notice instead, as does one whose rows hold eight times\n * as many. Counts only the haplotypes the cut is for, so fewer haplotypes\n * draw a wider window. Walk rows draw runs rather than steps and are\n * bounded by `walkByteBudget` alone.\n */\n walkStepBudget: {\n type: 'integer',\n defaultValue: WALK_BUDGETS.stepBudget,\n },\n /**\n * #slot\n * the most compressed bytes a cut of a walk-indexed graph fetches from its\n * walk file, as its Tabix index estimates it before any row is read; a\n * window over it shows a zoom-in notice instead. The budget covers every\n * haplotype, since a chunk's rows are filed for all of them.\n */\n walkByteBudget: {\n type: 'integer',\n defaultValue: WALK_BUDGETS.byteBudget,\n },\n /**\n * #slot\n * the haplotypes a walk-indexed graph is cut for until the user picks\n * others in the track's Haplotypes menu or Graph settings, as PanSN prefixes\n * (`HG002#1`, or `HG002` for both of its haplotypes). Empty means every\n * haplotype, or the lanes the track's `assemblyNames` lists after its\n * reference.\n */\n defaultHaplotypes: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN sample prefix in the graph, for\n * when they differ. Defaults to identity: the assembly name is assumed to be\n * the PanSN sample name, and a graph whose stable names are bare (minigraph\n * writes `chr1`) needs nothing here at all.\n *\n * Minigraph-Cactus writes PanSN stable names, so HPRC's release-2 graph\n * calls the reference `GRCh38#0#chr1` and an `hg38` assembly needs\n * `{ hg38: 'GRCh38' }`. The prefix is what disambiguates: that same graph\n * also contains `CHM13#0#chr1`, so matching on the contig alone would\n * silently resolve to the wrong sample.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * The same graph at one node per bubble, which a graph view following a\n * linear view cuts once that view is zoomed out past `aboveBpPerPx`, and\n * which no bp cap applies to. `{ uri, aboveBpPerPx }` or `{ uri,\n * foldBelowBp }`, where `uri` is a prefix as the adapter's own is;\n * `aboveBpPerPx` wins when both are given.\n */\n coarse: RgfaTabixCoarseTier,\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n * preprocessor to allow the minimal config\n * ```json\n * { \"type\": \"RgfaTabixAdapter\", \"uri\": \"graph.rgfa\" }\n * ```\n * or, for the GRCh38 set of a graph built by `gfa-to-tabix --walks -o\n * chr22`,\n * ```json\n * { \"type\": \"RgfaTabixAdapter\", \"walksUri\": \"chr22.GRCh38\" }\n * ```\n */\n preProcessSnapshot: normalizeSnapshot,\n },\n)\n\nexport type RgfaTabixAdapterConfig = Instance<typeof RgfaTabixAdapter>\n\nexport default RgfaTabixAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function RgfaTabixAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'RgfaTabixAdapter',\n displayName: 'Indexed rGFA adapter',\n configSchema,\n // what a graph display needs of its track's adapter\n adapterCapabilities: ['getSubgraph'],\n adapterMetadata: {\n category: 'Graph adapters',\n },\n getAdapterClass: () =>\n import('./RgfaTabixAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { WALK_BUDGETS } from '@jbrowse/graph-walks'\n\nimport {\n fileLocationSlot,\n tabixIndexSchema,\n walksLocations,\n} from '../panSNTabix.ts'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config WalkTabixSyntenyAdapter\n * #trackType GraphTrack\n * #fileFormat synteny | Walk-indexed graph | Built by `gfa-to-tabix --walks`; haplotype lanes and local subgraphs from three tabix files\n * Serves a pangenome graph whose haplotype walks\n * [gfa-to-tabix](https://github.com/GMOD/gfa-to-tabix) `--walks` filed under\n * chunks of a reference, as haplotype-versus-reference alignments, the shape\n * `MultiWaySyntenyDisplay` draws as one lane per haplotype, and as the graph\n * display's cut. A window on the reference reads the walk rows filed under\n * it, and each haplotype is aligned to the reference, or to another\n * haplotype, on the nodes both walks visit. No base is compared, so a short\n * bubble with equal bases on both sides is written as mismatches and any other\n * as an insertion and a deletion.\n *\n * `walksUri` takes the prefix of one reference's walk file, `<prefix>.<sample>`,\n * and resolves `<walksUri>.walks.bed.gz` and its `.tbi`. The adapter reads walk\n * format 3, which gfa-to-tabix writes from 1.1, through @jbrowse/graph-walks.\n * Only a window on the anchor is answered.\n *\n * #example\n * ```js\n * {\n * type: 'WalkTabixSyntenyAdapter',\n * walksUri: 'https://example.org/hprc-v2.1-mc-grch38.GRCh38',\n * assemblyNames: ['hg38'],\n * assemblyNameToPanSN: { hg38: 'GRCh38' },\n * }\n * ```\n */\n\nconst WalkTabixSyntenyAdapter = ConfigurationSchema(\n 'WalkTabixSyntenyAdapter',\n {\n /**\n * #slot\n * The first entry is the anchor: the JBrowse assembly the walk file's\n * reference sample is loaded as. A haplotype needs no entry: its lane\n * draws on the session assembly `assemblyNameToPanSN` maps to it, at\n * haplotype (`HG002#1`) or sample (`HG002`) depth, and a haplotype with no\n * assembly is still a lane, labelled by its PanSN prefix.\n */\n assemblyNames: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * a `gfa-to-tabix --walks` file in walk format 3\n */\n walksLocation: fileLocationSlot('/path/to/graph.walks.bed.gz'),\n /**\n * #slot\n */\n walksIndex: tabixIndexSchema('WalkTabixWalksIndex'),\n /**\n * #slot\n * the most haplotype steps one window keeps; a window whose walks hold\n * more shows a zoom-in notice instead, as does one whose rows hold eight\n * times as many. Counts only the haplotypes asked for. Walk rows draw\n * runs rather than steps and are bounded by `walkByteBudget` alone.\n */\n walkStepBudget: {\n type: 'integer',\n defaultValue: WALK_BUDGETS.stepBudget,\n },\n /**\n * #slot\n * the most compressed bytes one window fetches from the walk file, as its\n * Tabix index estimates it before any row is read; a window over it shows\n * a zoom-in notice instead.\n */\n walkByteBudget: {\n type: 'integer',\n defaultValue: WALK_BUDGETS.byteBudget,\n },\n /**\n * #slot\n * the haplotypes the graph display is cut for until the user picks\n * others, as PanSN prefixes (`HG002#1`, or `HG002` for both of its\n * haplotypes). Empty means the lanes the track's `assemblyNames` lists\n * after its reference, else every haplotype.\n */\n defaultHaplotypes: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * A tab-separated table of per-sample metadata, which the graph view's\n * walk rows group by. Its header row names the columns, and its first\n * column is the walk's sample (`HG00097`) or haplotype (`HG00097#1`).\n * Empty means no grouping.\n */\n samplesTsvLocation: fileLocationSlot(''),\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN prefix in the graph, sample or\n * haplotype level (`{ hg38: 'GRCh38', 'HG002.1': 'HG002#1' }`). An\n * assembly not listed maps to itself.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n * preprocessor to allow the minimal config, for the GRCh38 set of a graph\n * built by `gfa-to-tabix --walks -o chr22`\n * ```json\n * {\n * \"type\": \"WalkTabixSyntenyAdapter\",\n * \"walksUri\": \"chr22.GRCh38\",\n * \"assemblyNames\": [\"hg38\"],\n * \"assemblyNameToPanSN\": { \"hg38\": \"GRCh38\" }\n * }\n * ```\n */\n preProcessSnapshot: walksLocations,\n },\n)\n\nexport type WalkTabixSyntenyAdapterConfig = Instance<\n typeof WalkTabixSyntenyAdapter\n>\n\nexport default WalkTabixSyntenyAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function WalkTabixSyntenyAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'WalkTabixSyntenyAdapter',\n displayName: 'Walk-indexed graph adapter',\n configSchema,\n // the capabilities GbzBaseSyntenyAdapter declares, for the same\n // reasons: the header lists every haplotype as a lane, and one read\n // of an anchor window answers any pair of lanes, or several\n adapterCapabilities: [\n 'getSubgraph',\n 'headerLanes',\n 'lanePairsOnAnchor',\n 'lanePairBatches',\n ],\n adapterMetadata: {\n category: 'Synteny adapters',\n },\n getAdapterClass: () =>\n import('./WalkTabixSyntenyAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { buildAdapterConfig } from '../GraphAddTrackWorkflow/buildTrackConfig'\nimport { isSegmentsLocation } from '../GraphAddTrackWorkflow/graphManifest'\nimport {\n WALKS_SUFFIX,\n locationName,\n readsSiblings,\n walkFileSample,\n} from '../locationName'\nimport { LANE_ADAPTERS } from '../panSNAliases/trackAdapterConfig'\n\nimport type { GraphFileChoice } from '../GraphAddTrackWorkflow/buildTrackConfig'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { FileLocation } from '@jbrowse/core/util'\nimport type {\n AdapterGuesser,\n TrackTypeGuesser,\n} from '@jbrowse/core/util/tracks'\n\ntype TrackConfigSnapshot = Record<string, unknown>\n\nconst GRAPH_ADAPTERS = new Set(['RgfaTabixAdapter', 'GbzBaseSyntenyAdapter'])\n\nexport function isGbzLocation(loc: FileLocation) {\n return locationName(loc).toLowerCase().endsWith('.gbz.db')\n}\n\n// A lanes adapter cuts on the first assembly it names. A track added through\n// Add track names that assembly on the track alone.\nexport function withLaneAnchor(snap: TrackConfigSnapshot) {\n const adapter = snap.adapter as\n { type?: string; assemblyNames?: unknown[] } | undefined\n return adapter?.type !== undefined &&\n LANE_ADAPTERS.has(adapter.type) &&\n !adapter.assemblyNames?.length &&\n Array.isArray(snap.assemblyNames) &&\n snap.assemblyNames.length > 0\n ? { ...snap, adapter: { ...adapter, assemblyNames: snap.assemblyNames } }\n : snap\n}\n\n// A walk file opened with no PanSN map reads as the sample its name gives, on\n// the track's assembly; a guessed adapter had no assembly to key that by\nexport function withWalkReference(snap: TrackConfigSnapshot) {\n const adapter = snap.adapter as\n | {\n type?: string\n walksLocation?: FileLocation\n assemblyNameToPanSN?: unknown\n }\n | undefined\n const [assembly] = Array.isArray(snap.assemblyNames)\n ? (snap.assemblyNames as string[])\n : []\n const sample =\n adapter?.type === 'RgfaTabixAdapter' && adapter.walksLocation\n ? walkFileSample(adapter.walksLocation)\n : undefined\n return assembly &&\n sample &&\n sample !== assembly &&\n adapter?.assemblyNameToPanSN === undefined\n ? {\n ...snap,\n adapter: { ...adapter, assemblyNameToPanSN: { [assembly]: sample } },\n }\n : snap\n}\n\nexport function guessGraphAdapter(\n file: FileLocation,\n index?: FileLocation,\n adapterHint?: string,\n) {\n const guess = (choice: GraphFileChoice) =>\n buildAdapterConfig({\n choice,\n loc: file,\n indexLoc: index,\n assembly: '',\n sample: '',\n })\n if (\n (!adapterHint || adapterHint === 'GbzBaseSyntenyAdapter') &&\n isGbzLocation(file)\n ) {\n return guess('GbzBaseSyntenyAdapter')\n }\n if (!adapterHint || adapterHint === 'RgfaTabixAdapter') {\n if (isSegmentsLocation(file)) {\n return guess('RgfaTabixAdapter')\n }\n // a file picked in the browser has no index beside it to assume\n if (\n locationName(file).endsWith(WALKS_SUFFIX) &&\n (index !== undefined || readsSiblings(file))\n ) {\n return guess('RgfaTabixWalks')\n }\n }\n return undefined\n}\n\nexport default function GraphTrackDefaultsF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint(\n 'Core-preProcessTrackConfig',\n withLaneAnchor,\n )\n pluginManager.addToExtensionPoint(\n 'Core-preProcessTrackConfig',\n withWalkReference,\n )\n pluginManager.addToExtensionPoint(\n 'Core-guessAdapterForLocation',\n (next: AdapterGuesser): AdapterGuesser =>\n (file, index, adapterHint) =>\n guessGraphAdapter(file, index, adapterHint) ??\n next(file, index, adapterHint),\n )\n pluginManager.addToExtensionPoint(\n 'Core-guessTrackTypeForLocation',\n (next: TrackTypeGuesser): TrackTypeGuesser =>\n (adapterName, file) =>\n GRAPH_ADAPTERS.has(adapterName)\n ? 'GraphTrack'\n : next(adapterName, file),\n )\n}\n", "import { isRecord } from '../isRecord'\nimport { withRows } from '../launchFromGraph/linearViewTarget'\n\nexport interface HighlightRegion {\n refName: string\n start: number\n end: number\n assemblyName?: string\n}\n\nexport interface GraphViewHighlight {\n key: string\n region: HighlightRegion\n}\n\nfunction readRegion(value: unknown): HighlightRegion | undefined {\n let region: HighlightRegion | undefined\n if (isRecord(value)) {\n const { refName, start, end, assemblyName } = value\n if (\n typeof refName === 'string' &&\n typeof start === 'number' &&\n typeof end === 'number'\n ) {\n region = {\n refName,\n start,\n end,\n assemblyName:\n typeof assemblyName === 'string' ? assemblyName : undefined,\n }\n }\n }\n return region\n}\n\n// Whether a graph view's highlights belong on a given linear view.\n// `connectedViewId` is written by the launch menu, so a launched pair is\n// explicit. A graph view without one \u2014 a hand-written session snapshot, or\n// `Add > Graph genome view` followed by a subgraph load \u2014 matches any linear\n// view, because the alternative is silently drawing nothing.\n//\n// So does one whose linear view has been closed. Held to an id nothing answers\n// to, it matched no view and its hover drew nowhere for the rest of the\n// session, the view it next opened included.\nfunction isConnected(\n view: Record<string, unknown>,\n linearViewId: string,\n liveViewIds: ReadonlySet<unknown>,\n) {\n const connectedViewId = view.connectedViewId\n return (\n connectedViewId === undefined ||\n connectedViewId === linearViewId ||\n !liveViewIds.has(connectedViewId)\n )\n}\n\n// ...and whether the view can mean anything by it. `getHighlightCoords`\n// canonicalizes a refName against the region's OWN assembly and then lays it\n// out against this view's displayed regions, without ever asking whether the\n// two are the same assembly \u2014 so a band handed to the wrong view is drawn, at\n// coordinates that belong to somebody else's genome.\n//\n// That is not hypothetical for an unpaired graph, which by the rule above\n// matches every linear view in the session. A synteny stack's rows are LGVs on\n// different assemblies, and a PanSN name reduces to a bare contig: the five\n// E. coli strains each have one refName `chr`, so a graph cut from K12 painted\n// its K12 interval across Sakai's row and CFT073's at their own offsets. With\n// the assembly checked the reference row keeps the band and the rest correctly\n// draw nothing.\n//\n// A region stating no assembly still passes \u2014 `readRegion` leaves it optional,\n// and the fallback is the behaviour every existing snapshot has.\nfunction isOnAssembly(\n region: HighlightRegion,\n assemblyNames: string[] | undefined,\n) {\n return (\n region.assemblyName === undefined ||\n assemblyNames === undefined ||\n assemblyNames.includes(region.assemblyName)\n )\n}\n\n// The graph displays in a linear view's own tracks, connected to it by where\n// they sit.\nfunction trackGraphs(view: Record<string, unknown>) {\n const tracks = Array.isArray(view.tracks) ? view.tracks : []\n return tracks.flatMap((track: unknown) =>\n isRecord(track) && Array.isArray(track.displays)\n ? track.displays.filter(\n (display: unknown) =>\n isRecord(display) && display.type === 'LinearGraphDisplay',\n )\n : [],\n ) as Record<string, unknown>[]\n}\n\n// The highlights a linear view should draw for the graph views connected to it.\n// Reads `session.views` structurally: the members it needs are declared by\n// GraphGenomeView, not by the AbstractViewModel the session array is typed as.\nexport function graphViewHighlights(\n views: unknown[],\n linearViewId: string,\n // the drawing view's own assemblies, so a band is only drawn where its\n // coordinates mean something \u2014 see isOnAssembly\n linearAssemblyNames?: string[],\n): GraphViewHighlight[] {\n const highlights: GraphViewHighlight[] = []\n const candidates = withRows(views)\n const liveViewIds = new Set(\n candidates.map(view => (isRecord(view) ? view.id : undefined)),\n )\n for (const view of candidates) {\n if (isRecord(view) && view.id === linearViewId) {\n for (const display of trackGraphs(view)) {\n const region = readRegion(display.hoverHighlight)\n if (region && isOnAssembly(region, linearAssemblyNames)) {\n highlights.push({\n key: typeof display.id === 'string' ? display.id : 'graph-track',\n region,\n })\n }\n }\n }\n if (\n isRecord(view) &&\n view.type === 'GraphGenomeView' &&\n isConnected(view, linearViewId, liveViewIds)\n ) {\n const region = readRegion(view.hoverHighlight)\n if (region && isOnAssembly(region, linearAssemblyNames)) {\n highlights.push({\n key: typeof view.id === 'string' ? view.id : 'graph',\n region,\n })\n }\n }\n }\n return highlights\n}\n", "import { getSession } from '@jbrowse/core/util'\nimport { alpha } from '@mui/material'\nimport { observer } from 'mobx-react'\nimport { makeStyles } from 'tss-react/mui'\n\nimport { graphViewHighlights } from './graphViewHighlights'\n\nimport type { HighlightRegion } from './graphViewHighlights'\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\nconst useStyles = makeStyles()(theme => ({\n highlight: {\n height: '100%',\n position: 'absolute',\n background: alpha(theme.palette.primary.main, 0.08),\n borderLeft: `1px solid ${alpha(theme.palette.primary.main, 0.4)}`,\n borderRight: `1px solid ${alpha(theme.palette.primary.main, 0.4)}`,\n pointerEvents: 'none',\n zIndex: 10,\n },\n}))\n\n// One band over the linear view for a hovered graph node. `getHighlightCoords`\n// is the LGV's own projection \u2014 it canonicalizes the refName and floors the\n// width to 3 px, so a pure insertion (a zero-length reference span) still shows\n// as a mark rather than vanishing.\nconst Highlight = observer(function Highlight({\n model,\n region,\n}: {\n model: LinearGenomeViewModel\n region: HighlightRegion\n}) {\n const { classes } = useStyles()\n const coords = model.getHighlightCoords(region)\n return coords ? (\n <div\n data-testid=\"graph-node-highlight\"\n className={classes.highlight}\n style={{ left: coords.left, width: coords.width }}\n />\n ) : null\n})\n\nconst GraphNodeHighlight = observer(function GraphNodeHighlight({\n model,\n}: {\n model: LinearGenomeViewModel\n}) {\n const { views } = getSession(model)\n return (\n <>\n {graphViewHighlights([...views], model.id, model.assemblyNames).map(\n ({ key, region }) => (\n <Highlight key={`graph-hover-${key}`} model={model} region={region} />\n ),\n )}\n </>\n )\n})\n\nexport default GraphNodeHighlight\n", "import GraphNodeHighlight from './GraphNodeHighlight'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// The graph-to-linear half of the hover sync. The reverse half needs no mount\n// point: an LGV already publishes its hover to `session.hovered`, and the graph\n// view's own autorun reads it (see GraphGenomeView/pane/renderingActions.ts).\n//\n// Mounted through the extension point rather than imported by the LGV, so this\n// plugin never imports @jbrowse/plugin-linear-genome-view at runtime: it is not\n// one of JBrowse's shared globals, so a value import would bundle a second copy\n// of that whole plugin.\nconst POINT = 'LinearGenomeView-TracksContainerComponent'\n\nexport default function GraphHoverSyncF(pluginManager: PluginManager) {\n pluginManager.contributeToExtensionPoint(POINT, ({ model }) => (\n <GraphNodeHighlight key=\"graphgenomeview-hover-highlight\" model={model} />\n ))\n}\n", "import { DisplayType } from '@jbrowse/core/pluggableElementTypes'\n\nimport { trackAdapterConfig } from './trackAdapterConfig'\nimport { SYNTENY_DISPLAYS } from '../GraphTrack/index'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { IAnyModelType } from '@jbrowse/mobx-state-tree'\n\n// Core's synteny displays send `adapterConfig` with every request, the lane\n// listing's included, so overriding the getter reaches them all\nfunction withTrackAdapterConfig(model: IAnyModelType) {\n return model.views(self => ({\n get adapterConfig(): Record<string, unknown> {\n return trackAdapterConfig(self, self.parentTrack.configuration)\n },\n }))\n}\n\nexport default function PanSNAliasesF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint('Core-extendPluggableElement', element => {\n if (\n element instanceof DisplayType &&\n SYNTENY_DISPLAYS.includes(element.name)\n ) {\n element.extendStateModel(withTrackAdapterConfig)\n }\n return element\n })\n}\n", "// The name JBrowse knows this plugin by, which a config's `plugins` entry\n// states beside its `esmUrl`.\nexport const PLUGIN_NAME = 'GraphGenomeView'\n", "export const version = '7.1.11'\n", "import Plugin from '@jbrowse/core/Plugin'\nimport { isAbstractMenuManager } from '@jbrowse/core/util'\nimport BubbleChartIcon from '@mui/icons-material/BubbleChart'\n\nimport GbzBaseSyntenyAdapterF from './GbzBaseSyntenyAdapter/index'\nimport GetGraphHaplotypes from './GetGraphHaplotypes'\nimport GetGraphReads from './GetGraphReads'\nimport GetSubgraph from './GetSubgraph'\nimport GraphAddTrackWorkflowF from './GraphAddTrackWorkflow/index'\nimport GraphComputeLayout from './GraphComputeLayout'\nimport GraphGenomeViewF from './GraphGenomeView/index'\nimport GraphTrackF from './GraphTrack/index'\nimport LaunchGraphGenomeViewF from './LaunchGraphGenomeView'\nimport LinearGraphDisplayF from './LinearGraphDisplay/index'\nimport MinigraphBubbleAdapterF from './MinigraphBubbleAdapter/index'\nimport RgfaTabixAdapterF from './RgfaTabixAdapter/index'\nimport WalkTabixSyntenyAdapterF from './WalkTabixSyntenyAdapter/index'\nimport GraphTrackDefaultsF from './graphTrackDefaults/index'\nimport GraphHoverSyncF from './hoverSync/index'\nimport PanSNAliasesF from './panSNAliases/index'\nimport { PLUGIN_NAME } from './pluginName'\nimport { version } from './version'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\n\nexport default class GraphGenomeViewPlugin extends Plugin {\n name = PLUGIN_NAME\n version = version\n\n install(pluginManager: PluginManager) {\n GraphGenomeViewF(pluginManager)\n LinearGraphDisplayF(pluginManager)\n GraphTrackF(pluginManager)\n LaunchGraphGenomeViewF(pluginManager)\n GraphHoverSyncF(pluginManager)\n RgfaTabixAdapterF(pluginManager)\n MinigraphBubbleAdapterF(pluginManager)\n GbzBaseSyntenyAdapterF(pluginManager)\n WalkTabixSyntenyAdapterF(pluginManager)\n GraphAddTrackWorkflowF(pluginManager)\n GraphTrackDefaultsF(pluginManager)\n PanSNAliasesF(pluginManager)\n pluginManager.addRpcMethod(() => new GraphComputeLayout(pluginManager))\n pluginManager.addRpcMethod(() => new GetSubgraph(pluginManager))\n pluginManager.addRpcMethod(() => new GetGraphReads(pluginManager))\n pluginManager.addRpcMethod(() => new GetGraphHaplotypes(pluginManager))\n }\n\n // A throw from configure() takes the whole session to its error page, and a\n // menu entry is not worth that: hubs 1.0.9 did exactly this to every\n // jbrowse.org/ucsc launch by appending to a menu a released host defines as\n // a function. The view is still reachable without the entry.\n configure(pluginManager: PluginManager) {\n try {\n if (isAbstractMenuManager(pluginManager.rootModel)) {\n pluginManager.rootModel.appendToSubMenu(['Add'], {\n label: 'Graph genome view',\n icon: BubbleChartIcon,\n onClick: (session: AbstractSessionModel) => {\n session.addView('GraphGenomeView', {})\n },\n })\n }\n } catch (e) {\n console.warn('[GraphGenomeView] could not add the Add menu entry', e)\n }\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["const host = JBrowseExports[\"@jbrowse/core/Plugin\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/Plugin\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon([/*#__PURE__*/_jsx(\"circle\", {\n cx: \"7.2\",\n cy: \"14.4\",\n r: \"3.2\"\n}, \"0\"), /*#__PURE__*/_jsx(\"circle\", {\n cx: \"14.8\",\n cy: \"18\",\n r: \"2\"\n}, \"1\"), /*#__PURE__*/_jsx(\"circle\", {\n cx: \"15.2\",\n cy: \"8.8\",\n r: \"4.8\"\n}, \"2\")], 'BubbleChart');", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/AdapterType\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes/AdapterType\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "import { GBZ_CUT_DEFAULTS } from '@jbrowse/bandage-core/gbzWindow'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport { splitUri } from '../locationName'\nimport { fileLocationSlot, tabixIndexSchema } from '../panSNTabix.ts'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config GbzBaseSyntenyAdapter\n * #trackType GraphTrack\n * #fileFormat synteny | gbz-base pangenome database | Haplotype alignments read from the graph at query time, no PAF conversion\n * Serves a pangenome graph stored as a gbz-base SQLite database (`.gbz.db`) as\n * haplotype-versus-reference alignments, the shape `MultiWaySyntenyDisplay`\n * draws as one lane per haplotype. A window on the reference is located on the\n * graph's reference path, every haplotype's walk through the nodes it covers\n * is recovered and named, and each haplotype becomes one alignment record with\n * a CIGAR, so the graph is read through HTTP range requests with no offline\n * conversion. Naming the walks takes the companion haplotype index that\n * `gbz-haplotype-index` writes; without it the graph cannot say which\n * haplotype a walk belongs to.\n *\n * Only the fine tier exists: a whole-chromosome view stays on a PIF's coarse\n * tier. A window of the anchor answers any two lanes' alignment, so the\n * multi-way display fetches each adjacent lane pair directly.\n *\n * #example\n * ```js\n * {\n * type: 'GbzBaseSyntenyAdapter',\n * uri: 'hprc-v2.gbz.db',\n * assemblyNames: ['hg38'],\n * assemblyNameToPanSN: { hg38: 'GRCh38#0' },\n * }\n * ```\n */\nconst GbzBaseSyntenyAdapter = ConfigurationSchema(\n 'GbzBaseSyntenyAdapter',\n {\n /**\n * #slot\n * The first entry is the anchor: the JBrowse assembly the graph's reference\n * sample is loaded as. A haplotype needs no entry: its lane draws on the\n * session assembly named or aliased by its PanSN prefix (`HG002.1` with the\n * alias `HG002#1`), or the one `assemblyNameToPanSN` maps to it. A further\n * entry names an assembly by its sample (`HG002`), which takes both of the\n * sample's lanes. A haplotype with no assembly is still a lane, labelled by\n * its PanSN prefix.\n */\n assemblyNames: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * The `.gbz.db` written by `gbz-base construct`; read by HTTP range\n * requests, so it can be large.\n */\n gbzDbLocation: fileLocationSlot('/path/to/graph.gbz.db'),\n /**\n * #slot\n * The haplotype index `gbz-haplotype-index` writes beside the graph\n * database, which names its walks. One with stray rows (the tool from\n * 0.2.0) lets a fetch for a chosen set of lanes walk only those\n * haplotypes. Empty means `graph.haplotype-index.db` beside\n * `graph.gbz.db` if there is one; otherwise the walks go unnamed.\n */\n haplotypeIndexLocation: fileLocationSlot(''),\n /**\n * #slot\n * Reads aligned to the graph as GAF, which the tube map layouts draw under\n * the haplotypes. Its segment names have to be the cut's: numeric node ids,\n * or `vg giraffe --named-coordinates` on a graph whose segments were\n * renamed or chopped. Empty means no reads.\n */\n readsLocation: fileLocationSlot(''),\n /**\n * #slot\n * The `tabix -p gaf` index of a bgzipped `readsLocation`, which fetches the\n * reads over each window's node ids. Empty reads the GAF whole, up to 50 MB.\n */\n readsIndex: tabixIndexSchema('GbzBaseReadsIndex'),\n /**\n * #slot\n * A tab-separated table of per-sample metadata, which the graph view's\n * walk rows group by (\"Group by...\"). Its header row names the columns\n * (`population`, `superpopulation`, ...), and its first column is the\n * walk's sample (`HG00097`) or haplotype (`HG00097#1`). Empty means no\n * grouping.\n */\n samplesTsvLocation: fileLocationSlot(''),\n /**\n * #slot\n * How the graph view's subgraph is extended past the nodes the reference\n * window touches. `contained` adds every top-level snarl with both\n * boundary nodes in the window, which is what brings back the bubbles a\n * reference-only walk leaves out; a haplotype still breaks into a new W\n * line wherever it leaves the window's nodes (a 60 kb C4 window on the\n * HPRC graph: 2,703 nodes, 8,083 walks for 464 haplotypes). `overlapping`\n * also follows snarls that leave the window, so every haplotype is one\n * walk (464), at the price of every node in those snarls (4,184 there,\n * 24,547 across the KIV-2 repeat). `none` leaves only the bp `context`.\n */\n subgraphSnarls: {\n type: 'stringEnum',\n model: types.enumeration('SnarlOutput', [\n 'none',\n 'contained',\n 'overlapping',\n ]),\n defaultValue: GBZ_CUT_DEFAULTS.snarls,\n },\n /**\n * #slot\n * The graph sample the anchor window is located on. Empty means the sample\n * the anchor's PanSN prefix names, or the database's one reference sample\n * (`gbwt_reference_samples`) when the anchor names none; a database with\n * several reference samples then needs this set.\n */\n referenceSample: {\n type: 'string',\n defaultValue: '',\n },\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN prefix in the graph, sample or\n * haplotype level (`{ hg38: 'GRCh38#0', 'HG002.1': 'HG002#1' }`). Each\n * session assembly with a `sample#haplotype` alias (`HG002#1`) is mapped to\n * it already, so this is the override: an entry takes its prefix from any\n * assembly aliased to it. An assembly in neither maps to itself.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * Graph context around the window, in bp, on top of `subgraphSnarls`: the\n * cut, its reference walk and every haplotype walk extend this far past\n * the window on each side. A haplotype walk breaks into pieces wherever it\n * leaves the cut's nodes, so context and snarls together decide whether a\n * lane's bubble is one record or several. A window inside a snarl far\n * larger than itself (MHC class II on the HPRC graph, 90 kb) is 1.1M pieces\n * at 0 and 464 walks at 1000, three times faster.\n */\n context: {\n type: 'number',\n defaultValue: GBZ_CUT_DEFAULTS.context,\n advanced: true,\n },\n /**\n * #slot\n * The most graph nodes one window may load before the query fails rather\n * than reading a whole chromosome into the worker.\n */\n nodeLimit: {\n type: 'number',\n defaultValue: GBZ_CUT_DEFAULTS.limit,\n advanced: true,\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n *\n * preprocessor to allow minimal config, where a `.gz` `reads` is taken to\n * be bgzipped with a `.tbi` beside it:\n * ```json\n * {\n * \"type\": \"GbzBaseSyntenyAdapter\",\n * \"uri\": \"graph.gbz.db\",\n * \"reads\": \"reads.gaf.gz\",\n * \"assemblyNames\": [\"hg38\"]\n * }\n * ```\n */\n preProcessSnapshot: snap => {\n const { uri, baseUri, reads } = snap\n return {\n ...snap,\n ...(uri ? { gbzDbLocation: { uri, baseUri } } : {}),\n ...(typeof reads === 'string'\n ? {\n readsLocation: { uri: reads, baseUri },\n ...readsIndexBeside(reads, baseUri),\n }\n : {}),\n }\n },\n },\n)\n\n// a bgzipped GAF's index, before any query string its url carries\nfunction readsIndexBeside(reads: string, baseUri: unknown) {\n const { name, query } = splitUri(reads)\n return name.endsWith('.gz')\n ? { readsIndex: { location: { uri: `${name}.tbi${query}`, baseUri } } }\n : {}\n}\n\nexport type GbzBaseSyntenyAdapterConfig = Instance<typeof GbzBaseSyntenyAdapter>\n\nexport default GbzBaseSyntenyAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function GbzBaseSyntenyAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'GbzBaseSyntenyAdapter',\n displayName: 'gbz-base pangenome adapter',\n configSchema,\n // The same opened database serves the graph display's subgraph.\n // headerLanes: getHeader declares every haplotype as a lane, which is\n // what makes MultiWaySyntenyDisplay read the header of an untiered\n // adapter and offer its lane picker over the whole graph.\n // lanePairsOnAnchor: a window of the anchor answers any two lanes'\n // alignment to each other, so the display fetches each adjacent pair\n // rather than composing it through the reference.\n // lanePairBatches: every pair on a window comes from one cut\n adapterCapabilities: [\n 'getSubgraph',\n 'headerLanes',\n 'lanePairsOnAnchor',\n 'lanePairBatches',\n ],\n adapterMetadata: {\n category: 'Synteny adapters',\n },\n getAdapterClass: () =>\n import('./GbzBaseSyntenyAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const AdapterType = /* @__PURE__ */ read(\"AdapterType\")\nexport const AddTrackWorkflowType = /* @__PURE__ */ read(\"AddTrackWorkflowType\")\nexport const BaseConnectionModelFactory = /* @__PURE__ */ read(\"BaseConnectionModelFactory\")\nexport const BaseDisplay = /* @__PURE__ */ read(\"BaseDisplay\")\nexport const BaseInternetAccountConfig = /* @__PURE__ */ read(\"BaseInternetAccountConfig\")\nexport const BaseViewModel = /* @__PURE__ */ read(\"BaseViewModel\")\nexport const ConnectionType = /* @__PURE__ */ read(\"ConnectionType\")\nexport const DisplayType = /* @__PURE__ */ read(\"DisplayType\")\nexport const InternetAccount = /* @__PURE__ */ read(\"InternetAccount\")\nexport const InternetAccountType = /* @__PURE__ */ read(\"InternetAccountType\")\nexport const RpcMethodType = /* @__PURE__ */ read(\"RpcMethodType\")\nexport const RpcMethodTypeWithRenameRegion = /* @__PURE__ */ read(\"RpcMethodTypeWithRenameRegion\")\nexport const RpcMethodTypeWithRenameRegions = /* @__PURE__ */ read(\"RpcMethodTypeWithRenameRegions\")\nexport const TextSearchAdapterType = /* @__PURE__ */ read(\"TextSearchAdapterType\")\nexport const TrackType = /* @__PURE__ */ read(\"TrackType\")\nexport const ViewType = /* @__PURE__ */ read(\"ViewType\")\nexport const WidgetType = /* @__PURE__ */ read(\"WidgetType\")\nexport const addDisplayMenuItems = /* @__PURE__ */ read(\"addDisplayMenuItems\")\nexport const addViewMenuItems = /* @__PURE__ */ read(\"addViewMenuItems\")\nexport const baseConnectionConfig = /* @__PURE__ */ read(\"baseConnectionConfig\")\nexport const createBaseTrackConfig = /* @__PURE__ */ read(\"createBaseTrackConfig\")\nexport const createBaseTrackModel = /* @__PURE__ */ read(\"createBaseTrackModel\")\nexport const extendDisplayType = /* @__PURE__ */ read(\"extendDisplayType\")\nexport const extendViewType = /* @__PURE__ */ read(\"extendViewType\")\nexport const preprocessTrackConfigSnapshot = /* @__PURE__ */ read(\"preprocessTrackConfigSnapshot\")\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/core/data_adapters/dataAdapterCache\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/data_adapters/dataAdapterCache\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const READS_REFERENCE = /* @__PURE__ */ read(\"READS_REFERENCE\")\nexport const adapterConfigCacheKey = /* @__PURE__ */ read(\"adapterConfigCacheKey\")\nexport const clearAdapterCache = /* @__PURE__ */ read(\"clearAdapterCache\")\nexport const freeAdapterResources = /* @__PURE__ */ read(\"freeAdapterResources\")\nexport const getAdapter = /* @__PURE__ */ read(\"getAdapter\")\nexport default host && host.__esModule ? host.default : host", "import { getAdapter } from '@jbrowse/core/data_adapters/dataAdapterCache'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// The adapter a request's config names, as T when it has `method`, else\n// undefined. `name` is its class name, for saying which adapter lacks it.\nexport async function adapterImplementing<T extends object>(\n pluginManager: PluginManager,\n {\n sessionId,\n adapterConfig,\n }: { sessionId: string; adapterConfig: Record<string, unknown> },\n method: keyof T & string,\n) {\n const { dataAdapter } = await getAdapter(\n pluginManager,\n sessionId,\n adapterConfig,\n )\n const implemented =\n typeof (dataAdapter as unknown as Record<string, unknown>)[method] ===\n 'function'\n return {\n adapter: implemented ? (dataAdapter as unknown as T) : undefined,\n name: dataAdapter.constructor.name,\n }\n}\n", "import { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport { adapterImplementing } from './adapterImplementing'\n\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The haplotypes a graph names without a cut, for the track's haplotype picker:\n// a walk-indexed rGFA's header lines. Undefined where the graph names none, and\n// the picker falls back to typed names.\n\nexport interface GetGraphHaplotypesArgs {\n adapterConfig: Record<string, unknown>\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetGraphHaplotypes: {\n args: GetGraphHaplotypesArgs\n return: string[] | undefined\n }\n }\n}\n\ninterface HaplotypeNamesAdapter {\n getHaplotypeNames(opts: {\n signal?: AbortSignal\n }): Promise<string[] | undefined>\n}\n\nexport default class GetGraphHaplotypes extends RpcMethodType<'GetGraphHaplotypes'> {\n name = 'GetGraphHaplotypes' as const\n\n async execute(args: RpcExecuteArgs<'GetGraphHaplotypes'>) {\n const { adapter } = await adapterImplementing<HaplotypeNamesAdapter>(\n this.pluginManager,\n args,\n 'getHaplotypeNames',\n )\n return adapter?.getHaplotypeNames({ signal: args.signal })\n }\n}\n", "import { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport { adapterImplementing } from './adapterImplementing'\nimport { snapshotNamesFile } from './locationName.ts'\n\nimport type { GafReads } from './gaf/gafFile'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The reads aligned over a cut's segments, from an adapter whose config names\n// a GAF (GbzBaseSyntenyAdapter's `readsLocation`). Asked after the cut is\n// parsed, because the segment names are what a GAF index is keyed by.\n\nexport interface GetGraphReadsArgs {\n adapterConfig: Record<string, unknown>\n nodeNames: string[]\n}\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetGraphReads: {\n args: GetGraphReadsArgs\n return: GafReads\n }\n }\n}\n\ninterface ReadsAdapter {\n getReads(\n nodeNames: string[],\n opts: { signal?: AbortSignal },\n ): Promise<GafReads>\n}\n\n// Whether an adapter config as written names reads, so a graph without them\n// makes no round trip to ask\nexport function namesReads(adapterConfig: Record<string, unknown>) {\n return (\n (typeof adapterConfig.reads === 'string' && adapterConfig.reads !== '') ||\n snapshotNamesFile(adapterConfig.readsLocation)\n )\n}\n\nexport default class GetGraphReads extends RpcMethodType<'GetGraphReads'> {\n name = 'GetGraphReads' as const\n\n async execute(args: RpcExecuteArgs<'GetGraphReads'>) {\n const { nodeNames, signal } = args\n const { adapter } = await adapterImplementing<ReadsAdapter>(\n this.pluginManager,\n args,\n 'getReads',\n )\n return adapter\n ? adapter.getReads(nodeNames, { signal })\n : { records: [], total: 0 }\n }\n}\n", "const host = JBrowseExports[\"@jbrowse/core/util/librpc\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/util/librpc\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const RpcClient = /* @__PURE__ */ read(\"RpcClient\")\nexport const RpcServer = /* @__PURE__ */ read(\"RpcServer\")\nexport const deserializeError = /* @__PURE__ */ read(\"deserializeError\")\nexport const isRpcResult = /* @__PURE__ */ read(\"isRpcResult\")\nexport const rpcResult = /* @__PURE__ */ read(\"rpcResult\")\nexport const rpcResultWithArrayBuffers = /* @__PURE__ */ read(\"rpcResultWithArrayBuffers\")\nexport const serializeError = /* @__PURE__ */ read(\"serializeError\")\nexport const unwrapRpcResult = /* @__PURE__ */ read(\"unwrapRpcResult\")\nexport default host && host.__esModule ? host.default : host", "import { gfaTables } from '@jbrowse/bandage-core/gfa/gfaTables'\nimport { RpcMethodTypeWithRenameRegion } from '@jbrowse/core/pluggableElementTypes'\nimport { rpcResultWithArrayBuffers } from '@jbrowse/core/util/librpc'\n\nimport { adapterImplementing } from './adapterImplementing'\n\nimport type { WalkCut } from './RgfaTabixAdapter/walkRowRuns.ts'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\nimport type { Region } from '@jbrowse/core/util'\n\n// No `sessionId`, `signal` or `statusCallback` here: those belong to the\n// CALL, not to this payload, and core's `EntriesDeclaringCallLevelFields` fails\n// the build for a registry entry that declares one. `execute` still receives\n// them, because `RpcExecuteArgs` intersects `RpcCallContext` in.\n// `hops` is how far past the window a cut follows links, which only the rGFA\n// cut reads; the GBZ cut has its own bp `context` slot. `haplotypes` is the\n// set the cut is for, lane assembly names or PanSN prefixes, which the GBZ cut\n// and a walk-indexed rGFA cut read: they keep those walks, the reference's,\n// and the nodes they visit. Undefined or empty\n// is every haplotype. `tier` picks which of an rGFA track's two index pairs the\n// cut reads, the adapter's own or its `coarse` one; fine when absent.\nexport type SubgraphTier = 'fine' | 'coarse'\n\nexport interface SubgraphCutOptions {\n hops?: number\n haplotypes?: string[]\n tier?: SubgraphTier\n // which snarls a GBZ cut follows past the window, over the track's\n // `subgraphSnarls`; 'overlapping' when the layout measures whole walks\n snarls?: 'none' | 'contained' | 'overlapping'\n // a cut for walk rows: its runs come with the tables, and the\n // step budget, which guards a Graph of every step, does not apply\n walkRows?: boolean\n}\n\n// What an adapter's cut is handed: the payload, plus the call's own signal so\n// a cut the view has moved on from stops reading.\nexport interface SubgraphAdapterOptions extends SubgraphCutOptions {\n signal?: AbortSignal\n}\n\nexport interface SubgraphRegion {\n refName: string\n assemblyName: string\n start: number\n end: number\n}\n\nexport interface GetSubgraphArgs {\n adapterConfig: Record<string, unknown>\n region: Region\n opts?: SubgraphCutOptions\n}\n\n// A cut is tables, whose typed arrays cross to the main thread without a copy,\n// or GFA text the tables cannot hold\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GetSubgraph: {\n args: GetSubgraphArgs\n return: string | WalkCut\n transferables: WalkCut\n }\n }\n}\n\n// Adapters that can cut a local subgraph out of a graph file implement this:\n// RgfaTabixAdapter, WalkTabixSyntenyAdapter and GbzBaseSyntenyAdapter.\ninterface SubgraphAdapter {\n getSubgraph(\n region: Region,\n opts?: SubgraphAdapterOptions,\n ): Promise<string | WalkCut>\n}\n\n// RpcMethodTypeWithRenameRegion, not the plain RpcMethodType: the base class is\n// what maps `region.refName` from the assembly's spelling onto the adapter's own\n// before the call crosses to the worker. Without it a launch on an hg38 whose\n// contigs are bare (`6`, which is what every GRCh38 FASTA on jbrowse.org uses)\n// asked RgfaTabixAdapter for `GRCh38#0#6`, matched nothing, and opened a view\n// reading \"0 nodes, 0 edges\" with no error. The segments track drew the whole\n// time, because CoreGetFeatures renames and this did not, so the graph looked\n// broken while its own track looked fine. `assemblyNameToPanSN` covers the\n// sample half of a PanSN name only; the contig half is refName aliasing, which\n// the assembly already knows and this now consults.\nexport default class GetSubgraph extends RpcMethodTypeWithRenameRegion<'GetSubgraph'> {\n name = 'GetSubgraph' as const\n\n // Parameterized by the registry key, not left at the default `string`: a bare\n // RpcMethodTypeWithRenameRegion resolves RpcExecuteArgs to `unknown`, so\n // `execute` type-checks against nothing at all. `invoke` has already run\n // `deserializeArguments` by the time this is called, so it does not.\n async execute(args: RpcExecuteArgs<'GetSubgraph'>) {\n // `signal` arrives on every call and has to be named to be forwarded:\n // unnamed, a cut the view had replaced went on querying to the end, one\n // tabix read per off-reference segment per hop.\n const { region, opts, signal } = args\n const { adapter, name } = await adapterImplementing<SubgraphAdapter>(\n this.pluginManager,\n args,\n 'getSubgraph',\n )\n // A text cut is read into tables here, off the main thread: a GBZ cut of\n // every haplotype is tens of MB of W lines\n if (adapter) {\n const cut = await adapter.getSubgraph(region, { ...opts, signal })\n if (typeof cut !== 'string') {\n return rpcResultWithArrayBuffers(cut)\n }\n const tables = cut ? gfaTables(cut) : undefined\n return tables ? rpcResultWithArrayBuffers(tables) : cut\n }\n // The pane's cutSubgraph reports an empty result as a track that cannot\n // cut subgraphs\n console.warn(`[GetSubgraph] ${name} does not implement getSubgraph`)\n return ''\n }\n}\n", "import { lazy } from 'react'\n\nimport { AddTrackWorkflowType } from '@jbrowse/core/pluggableElementTypes'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nconst GraphAddTrackWidget = lazy(() => import('./AddTrackWorkflow'))\n\nexport default function GraphAddTrackWorkflowF(pluginManager: PluginManager) {\n pluginManager.addAddTrackWorkflowType(\n () =>\n new AddTrackWorkflowType({\n name: 'Pangenome graph track',\n displayName: 'Add pangenome graph track',\n ReactComponent: GraphAddTrackWidget,\n stateModel: types.model({}),\n }),\n )\n}\n", "import { layoutEngine } from '@jbrowse/bandage-core/layoutEngines'\nimport { RpcMethodType } from '@jbrowse/core/pluggableElementTypes'\n\nimport type { EngineRequest } from '@jbrowse/bandage-core/pipeline'\nimport type { LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { RpcExecuteArgs } from '@jbrowse/core/rpc/RpcRegistry'\n\n// The payload is the pipeline's EngineRequest, the same request a standalone\n// page hands the engine. `sessionId` and `statusCallback` are the CALL's, not\n// the payload's: core's `EntriesDeclaringCallLevelFields` fails the build for a\n// registry entry that declares either. `execute` still receives both, through\n// `RpcExecuteArgs`'s intersection with `RpcCallContext`.\n\ndeclare module '@jbrowse/core/rpc/RpcRegistry' {\n interface RpcRegistry {\n GraphComputeLayout: {\n args: EngineRequest\n return: { result: LayoutResult; duration: number }\n }\n }\n}\n\nexport default class GraphComputeLayout extends RpcMethodType<'GraphComputeLayout'> {\n name = 'GraphComputeLayout' as const\n\n async execute(args: RpcExecuteArgs<'GraphComputeLayout'>) {\n const { graph, options, statusCallback } = args\n\n statusCallback?.('Computing layout')\n return layoutEngine({ graph, options })\n }\n}\n", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/ViewType\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes/ViewType\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/core/util/withLaunchInput\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/util/withLaunchInput\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const defineLaunchKeys = /* @__PURE__ */ read(\"defineLaunchKeys\")\nexport const isTrackRecipe = /* @__PURE__ */ read(\"isTrackRecipe\")\nexport const legacyInitMessage = /* @__PURE__ */ read(\"legacyInitMessage\")\nexport const pendingLaunch = /* @__PURE__ */ read(\"pendingLaunch\")\nexport const snapshotSettings = /* @__PURE__ */ read(\"snapshotSettings\")\nexport const unknownKeysMessage = /* @__PURE__ */ read(\"unknownKeysMessage\")\nexport const withLaunchInput = /* @__PURE__ */ read(\"withLaunchInput\")\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/models\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes/models\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const BaseConnectionModelFactory = /* @__PURE__ */ read(\"BaseConnectionModelFactory\")\nexport const BaseDisplay = /* @__PURE__ */ read(\"BaseDisplay\")\nexport const BaseInternetAccountConfig = /* @__PURE__ */ read(\"BaseInternetAccountConfig\")\nexport const BaseViewModel = /* @__PURE__ */ read(\"BaseViewModel\")\nexport const InternetAccount = /* @__PURE__ */ read(\"InternetAccount\")\nexport const baseConnectionConfig = /* @__PURE__ */ read(\"baseConnectionConfig\")\nexport const createBaseTrackConfig = /* @__PURE__ */ read(\"createBaseTrackConfig\")\nexport const createBaseTrackModel = /* @__PURE__ */ read(\"createBaseTrackModel\")\nexport const migrateRetiredDisplays = /* @__PURE__ */ read(\"migrateRetiredDisplays\")\nexport const preprocessTrackConfigSnapshot = /* @__PURE__ */ read(\"preprocessTrackConfigSnapshot\")\nexport default host && host.__esModule ? host.default : host", "// What the pointer lights: nothing, a hovered node, or also an edge under it\n// and the node at a linear view's pointer bp\nexport type HoverHighlight = 'off' | 'nodes' | 'everything'\n\nexport const HOVER_HIGHLIGHT_VALUES: HoverHighlight[] = [\n 'off',\n 'nodes',\n 'everything',\n]\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M16 1H4c-1.1 0-2 .9-2 2v14h2V3h12zm3 4H8c-1.1 0-2 .9-2 2v14c0 1.1.9 2 2 2h11c1.1 0 2-.9 2-2V7c0-1.1-.9-2-2-2m0 16H8V7h11z\"\n}), 'ContentCopy');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M8.4 18.2c.38.5.6 1.12.6 1.8 0 1.66-1.34 3-3 3s-3-1.34-3-3 1.34-3 3-3c.44 0 .85.09 1.23.26l1.41-1.77c-.92-1.03-1.29-2.39-1.09-3.69l-2.03-.68c-.54.83-1.46 1.38-2.52 1.38-1.66 0-3-1.34-3-3s1.34-3 3-3 3 1.34 3 3c0 .07 0 .14-.01.21l2.03.68c.64-1.21 1.82-2.09 3.22-2.32V5.91C9.96 5.57 9 4.4 9 3c0-1.66 1.34-3 3-3s3 1.34 3 3c0 1.4-.96 2.57-2.25 2.91v2.16c1.4.23 2.58 1.11 3.22 2.32L18 9.71V9.5c0-1.66 1.34-3 3-3s3 1.34 3 3-1.34 3-3 3c-1.06 0-1.98-.55-2.52-1.37l-2.03.68c.2 1.29-.16 2.65-1.09 3.69l1.41 1.77Q17.34 17 18 17c1.66 0 3 1.34 3 3s-1.34 3-3 3-3-1.34-3-3c0-.68.22-1.3.6-1.8l-1.41-1.77c-1.35.75-3.01.76-4.37 0z\"\n}), 'Hub');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M12 2C6.49 2 2 6.49 2 12s4.49 10 10 10c1.38 0 2.5-1.12 2.5-2.5 0-.61-.23-1.2-.64-1.67-.08-.1-.13-.21-.13-.33 0-.28.22-.5.5-.5H16c3.31 0 6-2.69 6-6 0-4.96-4.49-9-10-9m5.5 11c-.83 0-1.5-.67-1.5-1.5s.67-1.5 1.5-1.5 1.5.67 1.5 1.5-.67 1.5-1.5 1.5m-3-4c-.83 0-1.5-.67-1.5-1.5S13.67 6 14.5 6s1.5.67 1.5 1.5S15.33 9 14.5 9M5 11.5c0-.83.67-1.5 1.5-1.5s1.5.67 1.5 1.5S7.33 13 6.5 13 5 12.33 5 11.5m6-4c0 .83-.67 1.5-1.5 1.5S8 8.33 8 7.5 8.67 6 9.5 6s1.5.67 1.5 1.5\"\n}), 'Palette');", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon([/*#__PURE__*/_jsx(\"circle\", {\n cx: \"12\",\n cy: \"12\",\n r: \"3.2\"\n}, \"0\"), /*#__PURE__*/_jsx(\"path\", {\n d: \"M9 2 7.17 4H4c-1.1 0-2 .9-2 2v12c0 1.1.9 2 2 2h16c1.1 0 2-.9 2-2V6c0-1.1-.9-2-2-2h-3.17L15 2zm3 15c-2.76 0-5-2.24-5-5s2.24-5 5-5 5 2.24 5 5-2.24 5-5 5\"\n}, \"1\")], 'PhotoCamera');", "import {\n ownStrand\n} from \"./chunk-UBQSRCWR.js\";\nimport {\n groupBy\n} from \"./chunk-BSOZW3FC.js\";\nimport {\n isBackbone\n} from \"./chunk-RJWPJCIB.js\";\n\n// src/foldVariants.ts\nfunction foldVariants(graph, belowBp) {\n if (!(belowBp > 0) || graph.paths?.length || !graph.nodes.some((node) => isBackbone(node))) {\n return graph;\n }\n const { nodes, edges } = readForward(graph);\n const index = new Map(nodes.map((node, i) => [node.id, i]));\n const sides = edges.map(forwardSides);\n const links = linksAt(nodes.length, edges, sides, index);\n const allele = alleleOf(nodes, edges, sides, index);\n const members = groupBy(allele.keys(), (i) => allele[i]);\n const kept = new Uint8Array(nodes.length);\n const big = [];\n for (const group of members.values()) {\n if (alleleContent(group, nodes, links, allele) >= belowBp) {\n for (const i of group) {\n kept[i] = 1;\n }\n if (!isBackbone(nodes[group[0]])) {\n big.push(group);\n }\n }\n }\n const { dist, pred } = distancesFromBackbone(nodes, links);\n for (const group of big) {\n for (const [i, side] of alleleEnds(group, nodes, links, allele)) {\n let next = nearestOutside(i, side, links, allele, dist, nodes);\n while (next !== void 0 && !kept[next]) {\n kept[next] = 1;\n next = isBackbone(nodes[next]) ? void 0 : pred[next];\n }\n }\n }\n const keptEdges = edges.filter((edge, k) => {\n const a = index.get(edge.from);\n const b = index.get(edge.to);\n if (a === void 0 || b === void 0) {\n return false;\n }\n const skip = skipped(nodes[a], sides[k].from, nodes[b], sides[k].to);\n return kept[a] && kept[b] && !(skip > 0 && skip < belowBp);\n });\n return mergeAlleleRuns({ ...graph, nodes, edges: keptEdges }, kept, allele);\n}\nfunction readForward({ nodes, edges }) {\n const reversed = new Set(\n nodes.filter((node) => node.stable?.strand === \"-\").map((node) => node.id)\n );\n if (reversed.size === 0) {\n return { nodes, edges };\n }\n const read = (id, strand) => {\n const own = strand ?? ownStrand(id);\n return reversed.has(id) ? complement(own) : own;\n };\n return {\n nodes: nodes.map(\n (node) => reversed.has(node.id) ? { ...node, stable: { ...node.stable, strand: \"+\" } } : node\n ),\n edges: edges.map(\n (edge) => reversed.has(edge.from) || reversed.has(edge.to) ? {\n ...edge,\n fromStrand: read(edge.from, edge.fromStrand),\n toStrand: read(edge.to, edge.toStrand)\n } : edge\n )\n };\n}\nfunction complement(strand) {\n return strand === \"+\" ? \"-\" : \"+\";\n}\nfunction forwardSides(edge) {\n return {\n from: (edge.fromStrand ?? ownStrand(edge.from)) === \"+\" ? \"e\" : \"s\",\n to: (edge.toStrand ?? ownStrand(edge.to)) === \"+\" ? \"s\" : \"e\"\n };\n}\nfunction linksAt(count, edges, sides, index) {\n const links = Array.from({ length: count }, () => []);\n edges.forEach((edge, k) => {\n const a = index.get(edge.from);\n const b = index.get(edge.to);\n if (a !== void 0 && b !== void 0) {\n const { from, to } = sides[k];\n links[a].push({ other: b, side: from, otherSide: to });\n links[b].push({ other: a, side: to, otherSide: from });\n }\n });\n return links;\n}\nfunction onOneSequence(a, b) {\n const sa = a.stable;\n const sb = b.stable;\n return sa && sb?.refName === sa.refName && sb.rank === sa.rank ? [sa, sb] : void 0;\n}\nfunction continues(a, aSide, b, bSide) {\n const pair = onOneSequence(a, b);\n if (!pair) {\n return false;\n }\n const [sa, sb] = pair;\n return aSide === \"e\" && bSide === \"s\" && sa.start + a.length === sb.start || bSide === \"e\" && aSide === \"s\" && sb.start + b.length === sa.start;\n}\nfunction skipped(a, aSide, b, bSide) {\n const pair = onOneSequence(a, b);\n if (!pair || continues(a, aSide, b, bSide)) {\n return 0;\n }\n const [sa, sb] = pair;\n return Math.abs(position(sb, b, bSide) - position(sa, a, aSide));\n}\nfunction position({ start }, node, side) {\n return side === \"s\" ? start : start + node.length;\n}\nfunction alleleOf(nodes, edges, sides, index) {\n const parent = nodes.map((_, i) => i);\n const find = (i) => {\n while (parent[i] !== i) {\n parent[i] = parent[parent[i]];\n i = parent[i];\n }\n return i;\n };\n edges.forEach((edge, k) => {\n const a = index.get(edge.from);\n const b = index.get(edge.to);\n if (a !== void 0 && b !== void 0 && continues(nodes[a], sides[k].from, nodes[b], sides[k].to)) {\n parent[find(a)] = find(b);\n }\n });\n return nodes.map((_, i) => find(i));\n}\nfunction alleleContent(group, nodes, links, allele) {\n if (isBackbone(nodes[group[0]])) {\n return Infinity;\n }\n let length = 0;\n let refName;\n let lo = Infinity;\n let hi = -Infinity;\n let oneSequence = true;\n for (const i of group) {\n length += nodes[i].length;\n for (const { other, otherSide } of links[i]) {\n const node = nodes[other];\n if (allele[other] !== allele[i] && isBackbone(node)) {\n refName ??= node.stable.refName;\n oneSequence &&= node.stable.refName === refName;\n const at = position(node.stable, node, otherSide);\n lo = Math.min(lo, at);\n hi = Math.max(hi, at);\n }\n }\n }\n return oneSequence && hi > lo ? Math.max(length, hi - lo) : length;\n}\nfunction alleleEnds(group, nodes, links, allele) {\n const start = (i) => nodes[i].stable?.start ?? 0;\n const end = (i) => start(i) + nodes[i].length;\n let first = group[0];\n let last = group[0];\n for (const i of group) {\n if (start(i) < start(first)) {\n first = i;\n }\n if (end(i) > end(last)) {\n last = i;\n }\n }\n const ends = [];\n for (const i of /* @__PURE__ */ new Set([first, last])) {\n for (const side of [\"s\", \"e\"]) {\n if (!links[i].some(\n (link) => link.side === side && allele[link.other] === allele[i]\n )) {\n ends.push([i, side]);\n }\n }\n }\n return ends;\n}\nfunction nearestOutside(i, side, links, allele, dist, nodes) {\n let best;\n for (const link of links[i]) {\n const j = link.other;\n if (link.side === side && allele[j] !== allele[i] && Number.isFinite(dist[j]) && (best === void 0 || dist[j] < dist[best] || dist[j] === dist[best] && nodes[j].name < nodes[best].name)) {\n best = j;\n }\n }\n return best;\n}\nfunction distancesFromBackbone(nodes, links) {\n const dist = new Float64Array(nodes.length).fill(Infinity);\n const pred = new Int32Array(nodes.length).fill(-1);\n const heap = new MinHeap(\n ([da, a], [db, b]) => da - db || cmp(nodes[a].name, nodes[b].name)\n );\n nodes.forEach((node, i) => {\n if (isBackbone(node)) {\n dist[i] = 0;\n heap.push([0, i]);\n }\n });\n for (let top = heap.pop(); top !== void 0; top = heap.pop()) {\n const [d0, i] = top;\n if (d0 > dist[i]) {\n continue;\n }\n for (const { other } of links[i]) {\n if (isBackbone(nodes[other])) {\n continue;\n }\n const d = d0 + nodes[other].length;\n if (d < dist[other]) {\n dist[other] = d;\n pred[other] = i;\n heap.push([d, other]);\n } else if (d === dist[other] && cmp(nodes[i].name, nodes[pred[other]].name) < 0) {\n pred[other] = i;\n }\n }\n }\n return { dist, pred: Array.from(pred, (p) => p < 0 ? void 0 : p) };\n}\nfunction cmp(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\nvar MinHeap = class {\n constructor(order) {\n this.order = order;\n this.items = [];\n }\n push(item) {\n const { items } = this;\n items.push(item);\n let i = items.length - 1;\n while (i > 0) {\n const up = i - 1 >> 1;\n if (this.order(items[i], items[up]) >= 0) {\n break;\n }\n ;\n [items[i], items[up]] = [items[up], items[i]];\n i = up;\n }\n }\n pop() {\n const { items } = this;\n const top = items[0];\n const last = items.pop();\n if (items.length > 0 && last !== void 0) {\n items[0] = last;\n let i = 0;\n for (; ; ) {\n const l = 2 * i + 1;\n const r = l + 1;\n let m = i;\n if (l < items.length && this.order(items[l], items[m]) < 0) {\n m = l;\n }\n if (r < items.length && this.order(items[r], items[m]) < 0) {\n m = r;\n }\n if (m === i) {\n break;\n }\n ;\n [items[i], items[m]] = [items[m], items[i]];\n i = m;\n }\n }\n return top;\n }\n};\nfunction mergeAlleleRuns(graph, kept, allele) {\n const { nodes, edges } = graph;\n const index = new Map(nodes.map((node, i) => [node.id, i]));\n const sides = edges.map(forwardSides);\n const ends = edges.map((edge, k) => [\n { i: index.get(edge.from), side: sides[k].from },\n { i: index.get(edge.to), side: sides[k].to }\n ]);\n const degree = /* @__PURE__ */ new Map();\n const sideKey = (i, side) => `${i}${side}`;\n for (const pair of ends) {\n for (const { i, side } of pair) {\n degree.set(sideKey(i, side), (degree.get(sideKey(i, side)) ?? 0) + 1);\n }\n }\n const next = /* @__PURE__ */ new Map();\n const hasPrev = /* @__PURE__ */ new Set();\n const internal = /* @__PURE__ */ new Set();\n ends.forEach(([a, b], k) => {\n if (a.i !== b.i && allele[a.i] === allele[b.i] && continues(nodes[a.i], a.side, nodes[b.i], b.side) && degree.get(sideKey(a.i, a.side)) === 1 && degree.get(sideKey(b.i, b.side)) === 1) {\n const [left, right] = a.side === \"e\" ? [a, b] : [b, a];\n next.set(left.i, { j: right.i, out: left.side, in: right.side });\n hasPrev.add(right.i);\n internal.add(k);\n }\n });\n const headOf = nodes.map((_, i) => i);\n const outer = /* @__PURE__ */ new Map();\n const merged = /* @__PURE__ */ new Map();\n nodes.forEach((_, i) => {\n if (!kept[i] || hasPrev.has(i) || !next.has(i)) {\n return;\n }\n const run = [i];\n let into = flip(next.get(i).out);\n outer.set(sideKey(i, into), \"s\");\n for (let step = next.get(i); step; step = next.get(step.j)) {\n run.push(step.j);\n into = step.in;\n }\n outer.set(sideKey(run.at(-1), flip(into)), \"e\");\n for (const j of run) {\n headOf[j] = i;\n }\n merged.set(i, mergedNode(run.map((j) => nodes[j])));\n });\n const endpoint = ({ i, side }) => ({\n id: nodes[headOf[i]].id,\n side: headOf[i] === i && !merged.has(i) ? side : outer.get(sideKey(i, side))\n });\n return {\n ...graph,\n nodes: nodes.flatMap(\n (node, i) => !kept[i] || headOf[i] !== i ? [] : [merged.get(i) ?? node]\n ),\n edges: edges.flatMap((edge, k) => {\n if (internal.has(k)) {\n return [];\n }\n const [a, b] = ends[k];\n if (!merged.has(headOf[a.i]) && !merged.has(headOf[b.i])) {\n return [edge];\n }\n const from = endpoint(a);\n const to = endpoint(b);\n return [\n {\n ...edge,\n from: from.id,\n to: to.id,\n fromStrand: from.side === \"e\" ? \"+\" : \"-\",\n toStrand: to.side === \"s\" ? \"+\" : \"-\"\n }\n ];\n })\n };\n}\nfunction flip(side) {\n return side === \"s\" ? \"e\" : \"s\";\n}\nfunction mergedNode(run) {\n const { samples: firstSamples, ...first } = run[0];\n const length = run.reduce((sum, node) => sum + node.length, 0);\n const depth = length > 0 ? run.reduce((sum, node) => sum + node.depth * node.length, 0) / length : first.depth;\n const samples = run.every((node) => node.samples) ? run.reduce(\n (common, node) => common.filter((s) => node.samples.includes(s)),\n firstSamples\n ) : void 0;\n return samples ? { ...first, length, depth, samples } : { ...first, length, depth };\n}\n\nexport {\n foldVariants\n};\n", "import {\n pathOrigin,\n trimOrigins\n} from \"../chunks/chunk-B5X2RLJG.js\";\nimport {\n PathVisitsBuilder\n} from \"../chunks/chunk-ZPZ7GNBT.js\";\nimport \"../chunks/chunk-BSOZW3FC.js\";\nimport {\n isBackbone,\n overlapsWindow\n} from \"../chunks/chunk-RJWPJCIB.js\";\nimport \"../chunks/chunk-HOAIOEI7.js\";\nimport \"../chunks/chunk-4XWZNPQ2.js\";\n\n// src/layout/trimToWindow.ts\nfunction trimToWindow(graph, window) {\n const inWindow = new Set(\n graph.nodes.filter((n) => isBackbone(n) && overlapsWindow(n, window)).map((n) => n.id)\n );\n const paths = graph.paths ?? [];\n if (inWindow.size === 0 || paths.length === 0) {\n return graph;\n }\n const spans = paths.map((path) => {\n let first = -1;\n let last = -1;\n path.nodeIds.forEach((id, i) => {\n if (inWindow.has(id)) {\n if (first < 0) {\n first = i;\n }\n last = i;\n }\n });\n return first < 0 ? void 0 : { first, last };\n });\n if (spans.every(\n (span, i) => span?.first === 0 && span.last === paths[i].nodeIds.length - 1\n )) {\n return graph;\n }\n const kept = /* @__PURE__ */ new Set();\n const trimmed = [];\n const stretches = /* @__PURE__ */ new Map();\n paths.forEach((path, i) => {\n const span = spans[i];\n if (span) {\n const nodeIds = path.nodeIds.slice(span.first, span.last + 1);\n for (const id of nodeIds) {\n kept.add(id);\n }\n trimmed.push({ ...path, nodeIds });\n stretches.set(path.name, { first: span.first, nodeIds });\n }\n });\n return {\n ...graph,\n nodes: graph.nodes.filter((n) => kept.has(n.id)),\n edges: graph.edges.filter((e) => kept.has(e.from) && kept.has(e.to)),\n paths: trimmed,\n pathVisits: graph.pathVisits && trimVisits(\n graph.pathVisits,\n paths,\n spans,\n new Map(graph.nodes.map((n) => [n.id, n.name]))\n ),\n anchorPaths: trimOrigins(graph, stretches)\n };\n}\nfunction trimVisits(visits, paths, spans, nameOf) {\n const next = visits.replay();\n const out = new PathVisitsBuilder();\n paths.forEach((path, p) => {\n const origin = visits.pathIndex(pathOrigin(path.name).name);\n const span = spans[p];\n path.nodeIds.forEach((id, i) => {\n const segment = nameOf.get(id) ?? id;\n const at = next(visits.slot(segment), origin);\n if (at >= 0 && span && i >= span.first && i <= span.last) {\n out.add(\n segment,\n visits.paths[origin],\n visits.samples[origin],\n visits.start[at],\n visits.reversed[at] === 1\n );\n }\n });\n });\n return out.build();\n}\nfunction clipToWindow(graph, window, reachBp) {\n const nodes = graph.nodes.map((node) => {\n if (!isBackbone(node)) {\n return node;\n }\n const from = node.stable.start;\n const to = from + node.length;\n const [start, end] = overlapsWindow(node, window) ? [Math.max(from, window.start), Math.min(to, window.end)] : to <= window.start ? [Math.max(from, to - reachBp), to] : [from, Math.min(to, from + reachBp)];\n return start === from && end === to ? node : { ...node, length: end - start, stable: { ...node.stable, start } };\n });\n return nodes.some((node, i) => node !== graph.nodes[i]) ? { ...graph, nodes } : graph;\n}\nexport {\n clipToWindow,\n trimToWindow\n};\n", "import {\n pathSteps\n} from \"./chunk-PK5QQOMN.js\";\nimport {\n pathOrigin\n} from \"./chunk-B5X2RLJG.js\";\nimport {\n pushTo\n} from \"./chunk-BSOZW3FC.js\";\n\n// src/tubeMap/bundle.ts\nfunction bundleRoutes(graph, groupOf = () => \"\", merge = true) {\n const paths = graph.paths ?? [];\n const steps = pathSteps(graph);\n const piecesOf = /* @__PURE__ */ new Map();\n paths.forEach((path, i) => {\n pushTo(piecesOf, pathOrigin(path.name).name, i);\n });\n const routeOf = (i) => steps[i].map((s) => `${s.node.id}${s.strand}`).join(\",\");\n const recordsOf = (walk) => piecesOf.get(walk).map((i) => paths[i]);\n const routeRank = /* @__PURE__ */ new Map();\n const bundles = /* @__PURE__ */ new Map();\n for (const [walk, pieces] of piecesOf) {\n const route = walk === graph.referencePath ? `\\0${walk}` : pieces.map(routeOf).join(\"|\");\n const group = groupOf(walk);\n const rank = routeRank.get(route) ?? routeRank.size;\n routeRank.set(route, rank);\n const key = `${route}\t${group}`;\n const bundle = bundles.get(key);\n if (bundle) {\n bundle.walks.push(walk);\n } else {\n bundles.set(key, { rank, group, walks: [walk] });\n }\n }\n if (merge && bundles.size === piecesOf.size) {\n return graph;\n }\n const ordered = [...bundles.values()].sort(\n (a, b) => a.rank - b.rank || a.group.localeCompare(b.group)\n );\n if (!merge) {\n return {\n ...graph,\n paths: ordered.flatMap(({ walks }) => walks.flatMap(recordsOf))\n };\n }\n const kept = ordered.flatMap(\n ({ walks }) => recordsOf(walks[0]).map(\n (path) => walks.length > 1 ? { ...path, members: walks } : path\n )\n );\n const keptWalks = new Set(ordered.map((b) => b.walks[0]));\n return {\n ...graph,\n paths: kept,\n anchorPaths: graph.anchorPaths?.filter((p) => keptWalks.has(p.name)),\n pathVisits: graph.pathVisits?.filter((path) => keptWalks.has(path))\n };\n}\n\nexport {\n bundleRoutes\n};\n", "// How much of the drawing a pan or zoom leaves on screen in each axis, or\n// all of it when it is smaller\nconst KEEP_IN_VIEW_PX = 48\n\n// The shift that brings a span starting at `lo`, `size` px long, back to\n// overlapping [0, extent] by `margin` px\nfunction shiftIntoView(lo: number, size: number, extent: number) {\n const margin = Math.min(KEEP_IN_VIEW_PX, size, extent)\n return Math.max(0, margin - (lo + size)) - Math.max(0, lo - (extent - margin))\n}\n\ninterface DrawingBox {\n minX: number\n minY: number\n w: number\n h: number\n}\n\n// layout units to pane px, per axis\nexport interface ScreenTransform {\n scaleX: number\n scaleY: number\n translateX: number\n translateY: number\n}\n\nexport function keepInView(\n bounds: DrawingBox,\n t: ScreenTransform,\n view: { width: number; height: number },\n) {\n return {\n translateX:\n t.translateX +\n shiftIntoView(\n bounds.minX * t.scaleX + t.translateX,\n bounds.w * t.scaleX,\n view.width,\n ),\n translateY:\n t.translateY +\n shiftIntoView(\n bounds.minY * t.scaleY + t.translateY,\n bounds.h * t.scaleY,\n view.height,\n ),\n }\n}\n\nexport function onScreen(\n bounds: DrawingBox,\n t: ScreenTransform,\n view: { width: number; height: number },\n) {\n const left = bounds.minX * t.scaleX + t.translateX\n const top = bounds.minY * t.scaleY + t.translateY\n return (\n left < view.width &&\n left + bounds.w * t.scaleX > 0 &&\n top < view.height &&\n top + bounds.h * t.scaleY > 0\n )\n}\n", "import {\n referenceKnots,\n warpX\n} from \"./chunk-MYDHU2UV.js\";\n\n// src/tubeMap/frame.ts\nvar MIN_TUBE_Y_SCALE = 0.05;\nvar NODE_BOX_PAD = 9;\nfunction squeeze(drawing, usableHeight) {\n const { minY, maxY } = drawing.layout.bounds;\n const h = maxY - minY;\n return drawing.columns && h > 0 ? Math.max(MIN_TUBE_Y_SCALE, Math.min(1, usableHeight / h)) : 1;\n}\nfunction tubeMapFrame(drawing, view) {\n const { scaleX, translateX, translateY } = view;\n const yScale = view.scaleY * squeeze(drawing, view.usableHeight);\n const y = (ty) => (ty - drawing.yOffset) * yScale + translateY;\n const { columns } = drawing;\n if (columns) {\n const knots = referenceKnots(columns, (bp) => bp * scaleX + translateX);\n return { x: (tx) => warpX(knots, tx), y, yScale };\n }\n return { x: (tx) => tx * scaleX + translateX, y, yScale };\n}\nfunction tubeMapNodeAt(drawing, { x, y }, sx, sy) {\n let hit = null;\n drawing.layout.nodes.forEach((node) => {\n if (node.order >= 0 && x(node.x - NODE_BOX_PAD) <= sx && sx <= x(node.x + node.pixelWidth + NODE_BOX_PAD) && y(node.y - NODE_BOX_PAD) <= sy && sy <= y(node.y + node.contentHeight + NODE_BOX_PAD)) {\n hit = node.name;\n }\n });\n return hit;\n}\n\nexport {\n tubeMapFrame,\n tubeMapNodeAt\n};\n", "import { formatBp } from '@jbrowse/bandage-core/graphLabels'\nimport { referenceBoxes, rulerBoxes } from '@jbrowse/bandage-core/tubeMap/axis'\nimport {\n connectorAt,\n drawLitConnector,\n tubeMapConnectors,\n} from '@jbrowse/bandage-core/tubeMap/connectors'\nimport { deviationMarks } from '@jbrowse/bandage-core/tubeMap/deviations'\nimport {\n drawTubeMapHighlight,\n mismatchOnScreen,\n mismatchesLegible,\n tubeMapMismatchAt,\n tubeMapPicture,\n tubeMapTrackAt,\n} from '@jbrowse/bandage-core/tubeMap/draw'\nimport {\n tubeMapFrame,\n tubeMapNodeAt,\n} from '@jbrowse/bandage-core/tubeMap/frame'\nimport { tubeMapNodeColors } from '@jbrowse/bandage-core/tubeMap/nodeColors'\nimport { computed } from 'mobx'\n\nimport {\n NO_VALUE_TUBE,\n PANEL_GAP,\n PANEL_TUBE,\n TINTED_TUBES,\n boxOf,\n memberAt,\n paintPanelHover,\n walksThrough,\n} from '../tubeMapPanels'\nimport { withFitViews } from './fitViews'\nimport { HOVER_BRIGHTEN } from './paneBase'\nimport { trackedDpr } from '../trackedDpr'\n\nimport type { HoveredTube } from './paneBase'\nimport type { Canvas2DRenderer } from '@jbrowse/bandage-core/renderer/Canvas2DRenderer'\nimport type { RenderBatch } from '@jbrowse/bandage-core/renderer/types'\nimport type { TubeMapPicture } from '@jbrowse/bandage-core/tubeMap/draw'\nimport type { TubeMapTransform } from '@jbrowse/bandage-core/tubeMap/frame'\nimport type { TubeMapMismatch } from '@jbrowse/bandage-core/tubeMap/mismatches'\n\nconst MAX_SHOWN_BASES = 20\n// a squeezed stack of panels thins no further, as one tube map does\nconst MIN_PANEL_Y_SCALE = 0.05\n\nconst MAX_LISTED = 6\n\nfunction listed(names: string[]) {\n const more = names.length - MAX_LISTED\n return more > 0\n ? `${names.slice(0, MAX_LISTED).join(', ')} and ${more} more`\n : names.join(', ')\n}\n\nfunction mismatchText(m: TubeMapMismatch) {\n if (m.kind === 'deletion') {\n return `deletion of ${formatBp(m.length)}`\n }\n if (m.kind === 'substitution') {\n return `substitution ${m.seq}`\n }\n const seq = m.seq ?? ''\n const shown =\n seq.length > MAX_SHOWN_BASES ? `${seq.slice(0, MAX_SHOWN_BASES)}\u2026` : seq\n return `insertion of ${formatBp(seq.length)} ${shown}`.trim()\n}\n\n// Which kinds of read mark are on screen, stopping once all three are found\nfunction mismatchKindsShown(\n picture: TubeMapPicture | undefined,\n frame: TubeMapTransform | undefined,\n width: number,\n) {\n const kinds = { substitution: false, insertion: false, deletion: false }\n if (picture && frame && mismatchesLegible(frame.yScale)) {\n let missing = 3\n for (const m of picture.mismatches) {\n if (!kinds[m.kind] && mismatchOnScreen(m, { x: frame.x, width })) {\n kinds[m.kind] = true\n if (--missing === 0) {\n break\n }\n }\n }\n }\n return kinds\n}\n\nexport const withTubeMapViews = withFitViews\n .views(self => ({\n get tubeMapFrame() {\n const drawing = self.layoutResult?.tubeMap\n return drawing\n ? tubeMapFrame(drawing, {\n ...self.screenTransform,\n usableHeight: self.usableHeight,\n })\n : undefined\n },\n // the reference ruler under the tubes, unless the linear view's ruler\n // is already the axis\n get tubeMapRulerBoxes() {\n const reference = self.tubeMapReference\n return reference && !self.hostPlacesX && !self.layoutResult?.tubeMapPanels\n ? rulerBoxes(reference)\n : undefined\n },\n // Split on the reference axis, the panels share x, so one ruler under\n // the last reads for them all; on the own axis each panel has its own\n get tubeMapPanelRulerBoxes() {\n const { layoutResult } = self\n const last = layoutResult?.tubeMapPanels?.at(-1)\n return last && layoutResult?.referenceAxis && !self.hostPlacesX\n ? rulerBoxes(referenceBoxes(last.result.tubeMap))\n : undefined\n },\n // The connectors run from the top of the pane down to the tubes' top\n get connectorZoneBottom() {\n const picture = self.tubeMapPicture\n const frame = this.tubeMapFrame\n return picture && frame ? frame.y(picture.bounds.minY) - 2 : 0\n },\n // The bands' tops follow every frame of a pan in the linear view and\n // their bottoms every pan of the tubes\n get tubeMapConnectors() {\n const boxes = self.tubeMapConnectedBoxes\n const frame = this.tubeMapFrame\n const bp = boxes && frame ? self.hostBpFrame : undefined\n return boxes && frame && bp\n ? tubeMapConnectors(\n boxes,\n b => b * bp.scale + bp.translateX,\n frame.x,\n self.paneWidth,\n )\n : []\n },\n // What each panel of a split tube map draws, which no pan or hover\n // changes: its picture, its tubes, its boxes' tints and its folded\n // variants\n get tubeMapPanelPictures() {\n const panels = self.layoutResult?.tubeMapPanels\n if (!panels) {\n return undefined\n }\n const { field } = self.facetSetting\n return panels.map(panel => {\n const drawing = panel.result.tubeMap\n const { graph, coarse } = drawing\n return {\n panel,\n label:\n panel.label ??\n (field === 'walk' ? self.walkLabel(panel.paths[0]!) : panel.key),\n picture: tubeMapPicture(drawing),\n tubeColors: self.tubeColorsOf(graph, drawing.pathColors),\n nodeColors: self.tubeMapNodeColors\n ? tubeMapNodeColors(\n graph,\n self.effectiveColorScheme,\n self.referenceRamp,\n )\n : undefined,\n deviations: coarse ? deviationMarks(drawing, coarse.deviations) : [],\n }\n })\n },\n }))\n .views(self => ({\n // The node the pointer is on: inside a merged run, the member at the\n // pointer's bp, so a run spanning the window counts what is under it\n get hoveredMember() {\n const id = self.hoveredNode\n const members =\n id === null ? undefined : self.hoverDrawing?.members.get(id)\n if (!members) {\n return id\n }\n const at = self.hoveredAt\n const i = self.hoveredPanel\n const under = i === null ? undefined : this.tubeMapPanelViews?.[i]\n // sparse, so forEach, which skips its holes, as tubeMapNodeAt does\n let box: { x: number; pixelWidth: number } | undefined\n under?.panel.result.tubeMap.layout.nodes.forEach(n => {\n if (n.name === id) {\n box = n\n }\n })\n const member =\n at && under && box\n ? memberAt(\n members,\n m => self.nodeSpan(m),\n under.frame.x(box.x),\n under.frame.x(box.x + box.pixelWidth),\n at.x,\n )\n : undefined\n return member ?? members[0]\n },\n // For the hovered box, the box each panel draws it in and how many of\n // that panel's haplotypes pass through it: a frequency per group\n get tubeMapPanelHover() {\n const id = self.hoveredNode\n const pictures = self.tubeMapPanelPictures\n if (id === null || !pictures) {\n return undefined\n }\n const node = this.hoveredMember ?? id\n return pictures.map(({ panel }) => {\n const drawing = panel.result.tubeMap\n const box = boxOf(drawing, node)\n return box ? { box, ...walksThrough(drawing.graph, box) } : undefined\n })\n },\n // apart from the pictures, so a lane row's hover redraws no panel\n get tubeMapPanelTubeColors() {\n return self.tubeMapPanelPictures?.map(({ panel, tubeColors }) => {\n const { graph } = panel.result.tubeMap\n return self.fadeUnhovered(\n tubeColors,\n graph.paths ?? [],\n graph.referencePath,\n )\n })\n },\n // Each panel through the pane's transform at its place down the stack.\n // On the reference axis the stack squeezes into the pane as one map does.\n get tubeMapPanelViews() {\n const pictures = self.tubeMapPanelPictures\n const tubeColors = this.tubeMapPanelTubeColors\n const layout = self.layoutResult\n if (!pictures || !tubeColors || !layout) {\n return undefined\n }\n // the titles keep their px and the drawings squeeze into the rest\n const titles = pictures.length * PANEL_GAP\n const drawings = pictures.reduce((h, p) => h + p.panel.height, 0)\n const usable = self.usableHeight - titles\n const yScale =\n self.scaleY *\n (layout.referenceAxis && drawings > 0\n ? Math.max(MIN_PANEL_Y_SCALE, Math.min(1, usable / drawings))\n : 1)\n let y = self.translateY\n return pictures.map((p, i) => {\n const { panel } = p\n const minY = panel.result.extent?.minY ?? 0\n const titleTop = y\n const top = titleTop + PANEL_GAP\n y = top + panel.height * yScale\n return {\n ...p,\n tubeColors: tubeColors[i]!,\n frame: tubeMapFrame(panel.result.tubeMap, {\n scaleX: self.scaleX,\n translateX: self.translateX,\n scaleY: yScale,\n translateY: top - minY * yScale,\n usableHeight: Infinity,\n }),\n titleTop,\n top,\n bottom: y,\n }\n })\n },\n // the panel a pane y falls in, its title's gap included\n tubeMapPanelAt(sy: number) {\n const i =\n this.tubeMapPanelViews?.findIndex(\n v => v.titleTop <= sy && sy <= v.bottom,\n ) ?? -1\n return i < 0 ? null : i\n },\n }))\n .views(self => ({\n // The hover alone, onto a transparent canvas over the drawing, so a\n // pointer move repaints what it lights rather than every stroke under\n // it. `batch` is what the canvas below holds.\n paintHover(r: Canvas2DRenderer, batch: RenderBatch) {\n const picture = self.tubeMapPicture\n const frame = self.tubeMapFrame\n const node = self.hoverLayerNode\n if (picture && frame) {\n const { ctx, canvas } = r\n const dpr = trackedDpr(self.paneWidth, self.canvasHeight)\n ctx.setTransform(1, 0, 0, 1, 0, 0)\n ctx.clearRect(0, 0, canvas.width, canvas.height)\n ctx.setTransform(dpr, 0, 0, dpr, 0, 0)\n const panels = self.tubeMapPanelViews\n if (panels) {\n paintPanelHover(ctx, panels, self.tubeMapPanelHover, {\n width: self.paneWidth,\n lit: node !== null,\n })\n } else {\n drawTubeMapHighlight(ctx, picture, {\n ...frame,\n width: self.paneWidth,\n highlightNode: node,\n })\n }\n drawLitConnector(\n ctx,\n self.tubeMapConnectors,\n self.connectorZoneBottom,\n node,\n )\n ctx.setTransform(1, 0, 0, 1, 0, 0)\n } else {\n r.uploadGeometry(batch)\n r.setNodeHighlights(\n node === null ? new Map() : new Map([[node, HOVER_BRIGHTEN]]),\n )\n r.setEdgeHighlight(self.hoveredEdge, HOVER_BRIGHTEN)\n r.updateTransform(self.paintTransform)\n r.renderHighlights()\n }\n },\n }))\n .views(self => {\n // Compared by value: the marks in view are read off the transform, and\n // the legend should redraw when a kind comes or goes, not every pan frame.\n // The rest of the key reads no transform, so a pan leaves it cached.\n const sameJson = (a: unknown, b: unknown) =>\n JSON.stringify(a) === JSON.stringify(b)\n const marksInView = computed(\n () =>\n mismatchKindsShown(\n self.layoutResult?.tubeMapPanels !== undefined\n ? undefined\n : self.tubeMapPicture,\n self.tubeMapFrame,\n self.paneWidth,\n ),\n { equals: sameJson },\n )\n const keys = computed(\n () => {\n const layout = self.layoutResult\n const split = layout?.tubeMapPanels !== undefined\n const reads = split ? [] : (layout?.tubeMap?.layout.reads ?? [])\n const paths = self.drawnGraph?.paths ?? []\n const coloring = self.tubeMapColoring\n const kind = self.tubeColorKind\n return {\n bundled: paths.some(p => p.members),\n // tubes in a column's hues, keyed value by value\n values:\n kind === 'value' && coloring\n ? [\n ...[...coloring.palette].map(([value, color]) => ({\n value,\n color,\n })),\n ...(coloring.unvalued\n ? [\n {\n value: `${coloring.field}: none`,\n color: NO_VALUE_TUBE,\n },\n ]\n : []),\n ]\n : undefined,\n // tubes coloured reference and haplotype rather than per walk\n roles: kind === 'role' || kind === 'tinted',\n haplotypeTube: kind === 'tinted' ? TINTED_TUBES[0]! : PANEL_TUBE,\n logWidths: layout?.tubeMap !== undefined && !layout.referenceAxis,\n foldBp:\n self.tubeMapDeviations.length > 0 ? self.tubeMapFold : undefined,\n forwardReads: reads.some(r => !r.is_reverse),\n reverseReads: reads.some(r => r.is_reverse),\n }\n },\n { equals: sameJson },\n )\n return {\n // What the tube map's legend has to explain: that on the own axis a\n // box is as wide as the log of its length, the fold its walks' ticks\n // stand for, the reads' strands, and the marks on the reads in view\n get tubeMapKeys() {\n return { ...keys.get(), ...marksInView.get() }\n },\n }\n })\n .views(self => ({\n // The drawing under a pane y: its panel's while the map is split\n tubeMapUnder(sy: number) {\n const views = self.tubeMapPanelViews\n if (views) {\n const i = self.tubeMapPanelAt(sy)\n const v = i === null ? undefined : views[i]\n return v && { drawing: v.panel.result.tubeMap, ...v }\n }\n const drawing = self.layoutResult?.tubeMap\n const picture = self.tubeMapPicture\n const frame = self.tubeMapFrame\n return drawing && picture && frame\n ? { drawing, picture, frame }\n : undefined\n },\n tubeMapNodeAt(sx: number, sy: number) {\n const under = this.tubeMapUnder(sy)\n return (\n (under ? tubeMapNodeAt(under.drawing, under.frame, sx, sy) : null) ??\n connectorAt(self.tubeMapConnectors, self.connectorZoneBottom, sx, sy) ??\n null\n )\n },\n // The tube under a pane point, and the mismatch mark on it if any\n tubeAt(sx: number, sy: number): HoveredTube | null {\n const under = this.tubeMapUnder(sy)\n if (!under) {\n return null\n }\n const { picture, frame } = under\n const mismatch = tubeMapMismatchAt(picture, frame, sx, sy)\n const track = mismatch?.readId ?? tubeMapTrackAt(picture, frame, sx, sy)\n return track === undefined ? null : { track, mismatch }\n },\n // A tube names its haplotype; a read its MAPQ and strand, and the\n // mismatch under the pointer\n get hoveredTubeText() {\n const tube = self.hoveredTube\n const layout = self.layoutResult?.tubeMap?.layout\n const read = tube && layout?.reads.find(r => r.id === tube.track)\n if (tube && read) {\n const mapq = read.mapping_quality\n return {\n label: read.name ?? 'read',\n readout: [\n `MAPQ ${mapq ?? 'unknown'}`,\n `${read.is_reverse ? 'reverse' : 'forward'} strand`,\n ...(tube.mismatch ? [mismatchText(tube.mismatch)] : []),\n ].join(', '),\n }\n }\n const path = tube ? self.hoverGraph?.paths?.[tube.track] : undefined\n const members = path?.members\n return members\n ? {\n label: `${members.length} haplotypes`,\n readout: `one route: ${listed(members.map(m => self.walkLabel(m)))}`,\n }\n : path\n ? { label: self.walkLabel(path.name), readout: 'haplotype' }\n : undefined\n },\n }))\n", "import { segmentAt } from '@jbrowse/bandage-core/layout/walkStrip'\nimport { anchorFromPaths } from '@jbrowse/bandage-core/pathAnchoring'\nimport { clampZoom, fittedTranslateY } from '@jbrowse/bandage-core/pipeline'\nimport { zoomAbout } from '@jbrowse/bandage-core/viewport'\nimport { getSession, isSessionModelWithWidgets } from '@jbrowse/core/util'\nimport { isAlive } from '@jbrowse/mobx-state-tree'\n\nimport { keepInView, onScreen } from './keepInView'\nimport {\n blendInto,\n canMorph,\n morphStarts,\n motionAllowed,\n routeStarts,\n runMorph,\n} from './morph'\nimport { VIEWPORT_DEBOUNCE_MS, forceLayouts } from './paneBase'\nimport { withTubeMapViews } from './tubeMapViews'\nimport { nodeOwnLocation } from '../../launchFromGraph/contributors'\nimport { withRows } from '../../launchFromGraph/linearViewTarget'\nimport { withLayer } from '../graphLayers'\nimport { colorOfScheme } from '../nodeColor'\nimport { sizeOfNodeWidth } from '../nodeSize'\n\nimport type { GraphGrammar } from './graphViews'\nimport type { ScreenTransform } from './keepInView'\nimport type { MorphEntering } from './morph'\nimport type { HoveredTube, TubeMapRoutes } from './paneBase'\nimport type { GraphLayer } from '../graphLayers'\nimport type { HoverHighlight } from '../hoverHighlight'\nimport type { WalkRowGroupBy } from '../walkRowGroups'\nimport type { BubbleSpread } from '@jbrowse/bandage-core/bubbleSpreads'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport type { FacetSetting } from '@jbrowse/bandage-core/facetGrid'\nimport type { LayoutEngineKind } from '@jbrowse/bandage-core/layoutEngines'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { NodeWidth } from '@jbrowse/bandage-core/nodeWidths'\nimport type { Bounds } from '@jbrowse/bandage-core/pipeline'\nimport type { RenderBatch } from '@jbrowse/bandage-core/renderer/types'\nimport type { LayoutResult } from '@jbrowse/bandage-core/types'\nimport type {\n WalkEncoding,\n WalkLayer,\n} from '@jbrowse/bandage-core/walkEncoding'\n\nexport const withSettingActions = withTubeMapViews\n .actions(() => ({\n // each host overrides: a view assigns its props, a track display writes\n // its config. Its own block, so the setters below reach the override\n // through `self`\n writeGrammar(_settings: GraphGrammar) {},\n }))\n .actions(self => ({\n // A pan or zoom never leaves the drawing wholly off screen, where\n // nothing says which way it went. A host's x is its own.\n keepDrawingInView() {\n const bounds = self.layoutBounds\n const view = self.viewBox\n if (\n !bounds ||\n self.viewportOwner === 'fit' ||\n !self.paneMeasured ||\n view.width <= 0 ||\n view.height <= 0\n ) {\n return\n }\n const t = keepInView(bounds, self, view)\n if (self.viewportOwner !== 'host') {\n self.translateX = t.translateX\n }\n self.translateY = t.translateY\n },\n }))\n .actions(self => {\n // a stated reference-position domain, kept through schemes that take\n // none so switching back restores it\n let keptDomain: typeof self.statedColorDomain\n return {\n setColorScheme(scheme: ColorScheme) {\n if (\n self.statedColorDomain ||\n self.chosenColorScheme === 'reference-position'\n ) {\n keptDomain = self.statedColorDomain\n }\n self.writeGrammar({ color: colorOfScheme(scheme, keptDomain) })\n },\n }\n })\n .actions(self => ({\n setError(error: unknown) {\n self.error = error\n self.isLoading = false\n self.statusMessage = ''\n },\n finishLoading() {\n self.isLoading = false\n self.statusMessage = ''\n },\n setStatusMessage(message: string) {\n self.statusMessage = message\n },\n setFetchMs(ms: number) {\n self.lastFetchMs = ms\n },\n setLayoutMs(ms: number) {\n self.lastLayoutMs = ms\n },\n setGeometryMetrics(\n ms: number,\n batch: RenderBatch,\n built: { scale: number; bounds: Bounds },\n ) {\n self.lastGeometryMs = ms\n self.lastGeometryStrokeCount = batch.nodeStrokes.length\n self.builtViewport = { ...built, viewportDirty: self.viewportDirty }\n self.drawnBatch = batch\n },\n markPainted() {\n self.paintedViewport = self.builtViewport\n },\n setLayoutQuality(quality: number) {\n self.layoutQuality = quality\n },\n setLayoutEngine(engine: LayoutEngineKind) {\n self.layoutEngine = engine\n },\n setLinearLayout(linear: boolean) {\n self.linearLayout = linear\n },\n setLayoutMode(mode: LayoutModeValue) {\n self.writeGrammar({ layoutMode: mode })\n },\n setHover(hover: HoverHighlight) {\n self.writeGrammar({ hover })\n if (!self.hoverLightsEverything) {\n self.hoveredEdge = null\n }\n },\n // Re-anchor in place rather than re-parsing: the coordinate walk is\n // already recorded on the graph, and only which path counts as rank 0\n // changes. The caller recomputes the layout, the same way it does after\n // setLayoutMode. An rGFA is left alone \u2014 its coordinates are not derived.\n setReferencePath(name: string) {\n self.referencePath = name\n const graph = self.graph\n if (graph?.anchoredBy === 'paths') {\n const reanchored = anchorFromPaths(graph, name)\n forceLayouts.inherit(graph, reanchored)\n self.graph = reanchored\n }\n },\n setLayer(layer: GraphLayer, on: boolean) {\n self.writeGrammar({ layers: withLayer(self.grammar.layers, layer, on) })\n },\n setShowPerf(show: boolean) {\n self.showPerf = show\n },\n setBubbleSpread(spread: BubbleSpread) {\n self.bubbleSpread = spread\n },\n setMaxGraphNodes(limit: number) {\n self.maxGraphNodes = limit\n },\n setNodeWidth(width: NodeWidth) {\n self.writeGrammar({\n size: sizeOfNodeWidth(width, self.contigThickness),\n })\n },\n setTubeMapFold(bp: number) {\n self.tubeMapFold = bp\n },\n setTubeMapRoutes(routes: TubeMapRoutes) {\n self.tubeMapRoutes = routes\n },\n setTubeMapColorBy(field: string) {\n self.tubeMapColorBy = field\n },\n setGeneTrackId(trackId: string) {\n self.geneTrackId = trackId\n },\n setRepeatTrackId(trackId: string) {\n self.repeatTrackId = trackId\n },\n setRepeatKey(key: string) {\n self.repeatKey = key\n },\n setWalkLayers(layers: WalkLayer[]) {\n self.walkLayers = layers\n },\n // Lift the walks named, in that order, keeping the colour any of them\n // already had\n liftWalks(names: string[]) {\n const had = new Map(self.walkLayers.map(l => [l.walk, l]))\n self.walkLayers = names.map(walk => had.get(walk) ?? { walk })\n },\n // A picker's set, which lists only this cut's walks: the lifted walks it\n // cannot show keep their layers for when a cut has them again\n liftAmongChoices(names: string[]) {\n const shown = new Set(self.walkChoices.map(c => c.name))\n this.liftWalks([\n ...names,\n ...self.walkLayers.map(l => l.walk).filter(walk => !shown.has(walk)),\n ])\n },\n // The field the panels split on; a change of field drops the order\n // written for the old one and keeps the column count\n // Panels off clears only panels, leaving a walk-row grouping the facet\n // holds instead\n setFacet(field: FacetSetting['field']) {\n const facet = self.facetSetting\n if (field === '') {\n if (facet.field !== '') {\n self.writeGrammar({ facet: {} })\n }\n } else {\n self.writeGrammar({\n facet: {\n ...facet,\n field,\n domain: field === facet.field ? facet.domain : [],\n },\n })\n }\n },\n toggleWalk(walk: string) {\n const layers = self.walkLayers\n self.walkLayers = layers.some(l => l.walk === walk)\n ? layers.filter(l => l.walk !== walk)\n : [...layers, { walk }]\n },\n setWalkColor(walk: string, color: Partial<WalkEncoding>) {\n self.walkLayers = self.walkLayers.map(l =>\n l.walk === walk ? { ...l, color: { ...l.color, ...color } } : l,\n )\n },\n setWalkRowSamples(samples: string[] | undefined) {\n self.writeGrammar({ rows: samples ? { kept: samples } : {} })\n },\n setWalkRowGroupBy(groupBy: WalkRowGroupBy | undefined) {\n if (groupBy || self.walkRowGroupBy) {\n self.writeGrammar({ facet: groupBy ?? {} })\n }\n },\n // Pair with a linear view for the hover sync, without ever repointing an\n // existing pairing: a graph launched *from* an LGV is already paired with\n // it, and stealing that would break the sync the user came in on. So a\n // launch out of the graph only claims the slot when it is empty.\n //\n // A slot naming a view that has been closed is empty too. Held, the view\n // the graph opened next never got its hover, since a highlight is drawn\n // only in the paired view.\n pairWithLinearView(viewId: string) {\n const paired = self.connectedViewId\n const stillOpen =\n paired !== undefined &&\n withRows([...getSession(self).views]).some(\n view => (view as { id?: unknown }).id === paired,\n )\n if (!stillOpen) {\n self.connectedViewId = viewId\n }\n },\n setHoveredNode(nodeId: string | null, at?: { x: number; y: number }) {\n self.hoveredNode = nodeId\n self.hoveredAt = nodeId === null ? null : (at ?? null)\n },\n setHoveredPanel(panel: number | null) {\n self.hoveredPanel = panel\n },\n setHoveredTube(tube: HoveredTube | null) {\n const was = self.hoveredTube\n if (tube?.track !== was?.track || tube?.mismatch !== was?.mismatch) {\n self.hoveredTube = tube\n }\n },\n setHoveredRowWalks(walks: string[]) {\n if (walks.join('\\n') !== self.hoveredRowWalks.join('\\n')) {\n self.hoveredRowWalks = walks\n }\n },\n setHoveredWalkRow(name: string | null) {\n self.hoveredWalkRow = name\n },\n setHoveredBubble(bubble: MinigraphBubble | null) {\n self.hoveredBubble = bubble\n },\n setPointerInPane(inside: boolean) {\n self.pointerInPane = inside\n },\n setWalkStrip(show: boolean) {\n this.setLayer('walkStrip', show)\n self.stripHover = null\n },\n // The pointer over the strip: the node under it becomes the hovered\n // node, so the drawing, the tooltip and a linked linear view follow\n setStripHover(hover: { row: string; offset: number } | null) {\n self.stripHover = hover\n const bars = self.walkStripRows\n const frame = self.walkStripFrame\n const row =\n hover && bars\n ? [bars.reference, ...bars.rows].find(r => r.name === hover.row)\n : undefined\n const node =\n row && frame && self.graph\n ? segmentAt(self.graph, row, hover!.offset, frame.scaleX)\n : undefined\n self.hoveredNode = node ?? null\n },\n setLegendSize(size: { width: number; height: number }) {\n self.legendSize = size\n },\n setHoveredEdge(edgeIdx: number | null) {\n self.hoveredEdge = self.hoverLightsEverything ? edgeIdx : null\n },\n setSelectedNode(nodeId: string | null) {\n self.selectedNode = nodeId\n },\n setDraggingNode(nodeId: string | null) {\n self.draggingNode = nodeId\n },\n setPanning(panning: boolean) {\n self.isPanning = panning\n },\n stopDragging() {\n self.draggingNode = null\n self.isPanning = false\n },\n clearHover() {\n self.hoveredNode = null\n self.hoveredAt = null\n self.hoveredTube = null\n self.hoveredPanel = null\n self.hoveredWalkRow = null\n self.hoveredBubble = null\n self.hoveredEdge = null\n },\n // Everything that names a part of the current graph. Reset when the graph\n // is replaced, and by clearGraph.\n clearInteractionState() {\n this.clearHover()\n self.hoveredRowWalks = []\n self.stripHover = null\n self.selectedNode = null\n self.draggingNode = null\n self.isPanning = false\n },\n showNodeDetails(nodeId: string) {\n const node = self.nodeById?.get(nodeId)\n if (node) {\n const session = getSession(self)\n const region = self.graphRegion\n // refName/start/end are what makes the widget show a location rather\n // than a bare id, and they are the same span the linear view\n // highlights on hover.\n const span = region ? self.nodeSpan(nodeId) : undefined\n if (isSessionModelWithWidgets(session)) {\n session.showWidget(\n session.addWidget('BaseFeatureWidget', 'baseFeature', {\n featureData: {\n id: node.id,\n name: node.name,\n length: node.length,\n depth: node.depth,\n rank: node.stable?.rank,\n stableName: node.stable?.refName,\n // The assembly that contributed this segment, split off the\n // stable name. On an HPRC graph this is the only thing that\n // says which of 400-odd haplotypes an allele came from.\n contributingAssembly: nodeOwnLocation(node)?.sample,\n // and the haplotype, where the graph's names state one:\n // the assembly to load to open this node on its own\n // coordinates\n contributingHaplotype: nodeOwnLocation(node)?.haplotype,\n // Every haplotype whose path visits it, which only a path\n // GFA records. Absent on an rGFA, where\n // `contributingAssembly` is the first-seen assembly alone.\n sampleCount: node.samples?.length,\n samples: node.samples,\n ...(region && span\n ? {\n refName: region.refName,\n assemblyName: region.assemblyName,\n start: span.start,\n end: span.end,\n }\n : {}),\n },\n }),\n )\n }\n }\n },\n\n // A gesture on a hosted graph moves the linear view, and the frame\n // clock brings x back here; y stays the pane's own.\n setTransform(s: number, tx: number, ty: number) {\n const { host } = self\n if (self.viewportOwner === 'host' && host) {\n host.horizontalScroll(self.translateX - tx)\n } else {\n self.viewportOwner = 'user'\n self.scale = clampZoom(s)\n self.translateX = tx\n }\n self.translateY = ty\n self.keepDrawingInView()\n },\n zoom(factor: number, centerX: number, centerY: number) {\n const { host } = self\n if (self.viewportOwner === 'host' && host) {\n host.zoomTo(host.bpPerPx / factor, centerX)\n return\n }\n self.viewportOwner = 'user'\n const t = zoomAbout(self, factor, centerX, centerY, self.pixelRows)\n self.scale = t.scale\n self.translateX = t.translateX\n self.translateY = t.translateY\n self.keepDrawingInView()\n },\n setViewportDirty() {\n self.viewportRebuildPending = false\n self.viewportDirty++\n },\n // The positions themselves moved, as opposed to the window onto them.\n setPositionsDirty() {\n self.positionsVersion++\n },\n // one frame of a morph: the positions moved in place, and what it brings\n // in has faded in this far, in one rebuild\n setMorphFrame(entering: MorphEntering | undefined) {\n self.morphEntering = entering\n self.positionsVersion++\n },\n zoomToFit() {\n // A host owns x, so a fit while hosted places the rows only.\n if (self.viewportOwner === 'host') {\n const bounds = self.layoutBounds\n const { usableHeight } = self\n if (bounds && usableHeight > 0) {\n self.translateY = fittedTranslateY(\n bounds,\n usableHeight,\n self.scaleY,\n self.fitPads.top,\n )\n }\n return\n }\n // Nothing to fit into before the canvas is measured. The fit autorun\n // runs again once width lands, so skipping beats persisting a negative\n // scale into the session snapshot.\n const fit = self.fittedTransform\n if (fit) {\n self.scale = fit.scale\n self.translateX = fit.translateX\n self.translateY = fit.translateY\n }\n },\n clearPerfMetrics() {\n self.lastFetchMs = undefined\n self.lastLayoutMs = undefined\n self.lastGeometryMs = undefined\n self.lastGeometryStrokeCount = undefined\n self.builtViewport = undefined\n },\n }))\n .actions(self => ({\n // The frame clock. Unclamped, since clampZoom's floor is there to keep a\n // scale finite and 1 / bpPerPx already is; clamped, a whole-chromosome\n // window would stop lining up.\n hostTransform(scale: number, translateX: number) {\n const engaging = self.viewportOwner !== 'host'\n if (engaging) {\n self.viewportOwner = 'host'\n }\n self.scale = scale\n self.translateX = translateX\n if (engaging) {\n self.zoomToFit()\n }\n },\n // A new layout under a view the user placed. One that replaces a\n // drawing is fitted unless both are on the reference's bp and some of it\n // is still on screen: a force run or a fresh cut draws in coordinates of\n // its own, where the old transform shows nothing in particular. The\n // first layout after a restored session keeps the saved view, pulled\n // into the pane once its width is known.\n followNewLayout(previous: LayoutResult | undefined) {\n const bounds = self.layoutBounds\n if (\n self.viewportOwner !== 'user' ||\n !bounds ||\n previous === self.layoutResult\n ) {\n return\n }\n const keepsAxis = previous?.referenceAxis === true && self.xIsReferenceBp\n if (\n previous === undefined ||\n (keepsAxis &&\n (!self.paneMeasured || onScreen(bounds, self, self.viewBox)))\n ) {\n self.keepDrawingInView()\n } else {\n self.viewportOwner = 'fit'\n self.zoomToFit()\n }\n },\n // Faceting changes the box the drawing is fitted into, so a drawing the\n // user placed is fitted again; a host keeps its x\n refitView() {\n if (self.viewportOwner === 'user') {\n self.viewportOwner = 'fit'\n }\n self.zoomToFit()\n },\n // A drawing still on the reference stays where the host left it; one\n // whose x no longer means bp is refit.\n releaseHost() {\n if (self.viewportOwner === 'host') {\n if (self.xIsReferenceBp) {\n self.viewportOwner = 'user'\n } else {\n self.viewportOwner = 'fit'\n self.zoomToFit()\n }\n }\n },\n }))\n .actions(self => {\n // Pan/zoom can wait: the geometry on screen is still correct while the\n // gesture runs (the viewport bounds carry 20% overscan), so rebuilding is\n // deferred until the user settles.\n function scheduleViewportDirty() {\n clearTimeout(self.viewportDirtyTimer)\n self.viewportRebuildPending = true\n self.viewportDirtyTimer = setTimeout(() => {\n if (isAlive(self)) {\n self.setViewportDirty()\n }\n }, VIEWPORT_DEBOUNCE_MS)\n }\n\n // A node drag cannot wait \u2014 the node only moves on screen when its\n // geometry is rebuilt \u2014 but a bump costs a full geometry rebuild plus\n // invalidation of both hit-detection indexes, and mousemove fires in\n // bursts well above the frame rate. Coalescing to the next frame keeps the\n // drag live while bounding that work to once per frame instead of once\n // per event.\n function requestPositionsDirtyFrame() {\n cancelAnimationFrame(self.positionsDirtyFrame)\n self.positionsDirtyFrame = requestAnimationFrame(() => {\n if (isAlive(self)) {\n self.setPositionsDirty()\n }\n })\n }\n\n let morph: { frame: number; finish: () => void } | undefined\n\n function stopMorph() {\n if (morph) {\n cancelAnimationFrame(morph.frame)\n morph = undefined\n }\n }\n\n function finishMorph() {\n const running = morph\n stopMorph()\n running?.finish()\n }\n\n return {\n // Slides the drawing from what `previous` drew under `before` to the\n // layout just landed, so a re-cut or a relayout reads as one picture\n // moving rather than a jump. Positions move in place as a drag moves\n // them, a frame at a time; anything new grows out of its neighbours.\n morphFrom(previous: LayoutResult | undefined, before: ScreenTransform) {\n const next = self.layoutResult\n // the layout cache handing back the drawing on screen leaves its\n // morph running\n if (previous === next) {\n return\n }\n // The cache keeps the layouts a morph blends in place, so one cut\n // short is still finished, and this one starts from a copy of where\n // it had got to on screen\n const shown =\n morph && previous\n ? structuredClone(previous.nodePositions)\n : previous?.nodePositions\n finishMorph()\n const graph = self.graph\n if (\n !previous ||\n !shown ||\n !next ||\n !graph ||\n !canMorph(previous, next, graph.nodes.length, !!self.facetGrid) ||\n !motionAllowed()\n ) {\n return\n }\n // the fit autorun lands after this action; the start needs its frame\n if (self.viewportOwner === 'fit') {\n self.zoomToFit()\n }\n const routes = next.deletionRoutes ?? {}\n const ends = structuredClone({ nodes: next.nodePositions, routes })\n const nodeStarts = morphStarts(\n shown,\n before,\n next.nodePositions,\n self.screenTransform,\n graph.edges,\n )\n const starts = {\n nodes: nodeStarts,\n routes: routeStarts(routes, graph.edges, nodeStarts, ends.nodes),\n }\n const ids = new Set(\n Object.keys(next.nodePositions).filter(id => !shown[id]),\n )\n const blend = (t: number) => {\n blendInto(next.nodePositions, starts.nodes, ends.nodes, t)\n blendInto(routes, starts.routes, ends.routes, t)\n if (isAlive(self)) {\n self.setMorphFrame(\n t < 1 && ids.size > 0\n ? { layout: next, ids, alpha: t }\n : undefined,\n )\n }\n }\n blend(0)\n morph = runMorph(\n blend,\n () => isAlive(self) && self.layoutResult === next,\n () => {\n morph = undefined\n },\n )\n },\n finishMorph,\n // Moves the position objects IN PLACE, which is the one thing\n // jbrowse-components' upload invariant says not to do (\"per-region\n // upload values must be freshly constructed, never mutated \u2014 backends\n // diff by reference identity\"), so it is worth saying why this is not\n // that case and what it costs instead.\n //\n // Nothing here diffs by identity: the geometry is rebuilt wholesale and\n // handed over as one batch, so `nodePositions` identity is not a\n // protocol between the model and the backend the way a per-region map\n // is. What identity DOES drive is the fit: the zoom-to-fit autorun and\n // `layoutBounds` \u2014 and so `canvasHeight` \u2014 key off `layoutResult`, and\n // they mean \"a new LAYOUT arrived\", not \"a node moved\". Publishing a\n // fresh positions record per frame of a drag would refit the drawing\n // and resize the pane under the cursor, sixty times a second.\n //\n // So the change is announced by `positionsVersion` instead, and every\n // cache that would otherwise trust identity takes it as a key. The cost\n // of that trade is that the version is a thing to remember: a caller\n // that mutates here and does not bump it gets stale curves, stale hit\n // boxes and stale labels, silently. Everything downstream of it is\n // reached from this one action.\n moveNode(nodeId: string, dx: number, dy: number) {\n finishMorph()\n const positions = self.layoutResult?.nodePositions\n if (positions?.[nodeId]) {\n for (const seg of positions[nodeId]) {\n seg.x += dx\n seg.y += dy\n }\n requestPositionsDirtyFrame()\n }\n },\n scheduleViewportDirty,\n }\n })\n", "const host = JBrowseExports[\"@jbrowse/core/util/unzip\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/util/unzip\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const unzip = /* @__PURE__ */ read(\"unzip\")\nexport default host && host.__esModule ? host.default : host", "import { unzip } from '@jbrowse/core/util/unzip'\n\n// A GFA's text, from its bytes as read, gzipped (by its magic bytes) or not\nexport async function gfaText(bytes: Uint8Array) {\n const gzipped = bytes[0] === 0x1f && bytes[1] === 0x8b\n return new TextDecoder().decode(gzipped ? await unzip(bytes) : bytes)\n}\n", "import {\n backboneNodes,\n backbonePositions,\n overlapsWindow,\n} from '@jbrowse/bandage-core/anchoredNodes'\nimport {\n walkRowLabels,\n walkRowsExtent,\n} from '@jbrowse/bandage-core/layout/walkRowLayout'\nimport { loadGraph } from '@jbrowse/bandage-core/pipeline'\n\nimport { walkPath } from '../RgfaTabixAdapter/walkRowRuns.ts'\n\nimport type { WalkCut } from '../RgfaTabixAdapter/walkRowRuns.ts'\nimport type { GraphTables } from '@jbrowse/bandage-core/gfa/graphTables'\nimport type { WalkRows } from '@jbrowse/bandage-core/layout/walkRows'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\n\n/**\n * The Graph a walk-rows cut parses to: nodes with their depth over every\n * walk, links, and the reference walk, with every other walk named and\n * stepless. The rows come from the cut's runs, so no object per step is\n * built for them; a layout that draws nodes parses the cut whole.\n */\nexport function walkRowsGraph(\n cut: WalkCut,\n name: string,\n referencePath: string | undefined,\n): Graph {\n const w = cut.walks\n const first = w.offsets[1] ?? 0\n const light: GraphTables = {\n nodes: cut.nodes,\n links: cut.links,\n walks: {\n names: w.names.slice(0, 1),\n starts: w.starts.subarray(0, 1),\n ends: w.ends.subarray(0, 1),\n offsets: Int32Array.of(0, first),\n steps: w.steps.subarray(0, first),\n reversed: w.reversed.subarray(0, first),\n },\n }\n const graph = loadGraph(light, name, { referencePath })\n const depth = new Int32Array(cut.nodes.names.length)\n for (const node of w.steps) {\n depth[node]!++\n }\n graph.nodes.forEach((node, i) => {\n node.depth = Math.max(depth[i]!, 1)\n })\n const stubs = w.names.slice(1).flatMap((walk, i) => {\n if (w.offsets[i + 2]! <= w.offsets[i + 1]!) {\n return []\n }\n return [{ ...walkPath(walk), nodeIds: [], start: w.starts[i + 1]! }]\n })\n graph.paths = [...(graph.paths ?? []), ...stubs]\n return graph\n}\n\n/** bandage-core's walkRowLayout, over rows already made */\nexport function walkRowLayoutOf(\n graph: Graph,\n walks: WalkRows,\n region?: { start: number; end: number },\n): LayoutResult | undefined {\n const backbone = backboneNodes(graph)\n if (backbone.length === 0) {\n return undefined\n }\n const overWindow = region\n ? backbone.filter(n => overlapsWindow(n, region))\n : backbone\n return {\n nodePositions: backbonePositions(\n overWindow.length > 0 ? overWindow : backbone,\n ),\n rowLabels: walkRowLabels(walks),\n referenceAxis: true,\n pixelRows: true,\n extent: walkRowsExtent(walks),\n }\n}\n", "import { sameBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport { bubbleSegmentIds } from '@jbrowse/bandage-core/bubbles/classifyBubble'\nimport { foldVariants } from '@jbrowse/bandage-core/foldVariants'\nimport { regionLabel } from '@jbrowse/bandage-core/hoverText'\nimport {\n clipToWindow,\n trimToWindow,\n} from '@jbrowse/bandage-core/layout/trimToWindow'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n anchorFromPaths,\n chooseReferencePath,\n} from '@jbrowse/bandage-core/pathAnchoring'\nimport { engineSettingsOf, loadGraph } from '@jbrowse/bandage-core/pipeline'\nimport { assemblyWalk } from '@jbrowse/bandage-core/reference'\nimport { bundleRoutes } from '@jbrowse/bandage-core/tubeMap/bundle'\nimport { coarsenTubeMap } from '@jbrowse/bandage-core/tubeMap/coarsen'\nimport { readConfObject } from '@jbrowse/core/configuration'\nimport {\n getRpcSessionId,\n getSession,\n statusMessageText,\n} from '@jbrowse/core/util'\nimport { openLocation } from '@jbrowse/core/util/io'\nimport { flow, getEnv, isAlive } from '@jbrowse/mobx-state-tree'\n\nimport {\n EMPTY_BATCH,\n TUBE_MAP_MODES,\n bubblePrefix,\n fileName,\n forceLayouts,\n} from './paneBase'\nimport { withSettingActions } from './settingActions'\nimport { namesReads } from '../../GetGraphReads'\nimport { walkRowsOf } from '../../RgfaTabixAdapter/walkRowRuns.ts'\nimport { geneModelsFrom } from '../genes/geneFeatures'\nimport { gfaText } from '../gfaText'\nimport { repeatArraysFrom } from '../repeats/repeatFeatures'\nimport {\n graphOfPaths,\n tubeMapPanelGroups,\n withTubeMapPanels,\n} from '../tubeMapPanels'\nimport { parseSamplesTsv } from '../walkRowGroups'\nimport { walkRowLayoutOf, walkRowsGraph } from '../walkRowsCut.ts'\n\nimport type { SubgraphCutOptions, SubgraphRegion } from '../../GetSubgraph'\nimport type { WalkCut } from '../../RgfaTabixAdapter/walkRowRuns.ts'\nimport type { GafReads } from '../../gaf/gafFile'\nimport type { PaneLayout } from '../tubeMapPanels'\nimport type { MinigraphBubble } from '@jbrowse/bandage-core/bubbles/bubbleLine'\nimport type { GeneModel } from '@jbrowse/bandage-core/genes/genePins'\nimport type { EngineRequest } from '@jbrowse/bandage-core/pipeline'\nimport type { Graph, LayoutResult } from '@jbrowse/bandage-core/types'\nimport type { Feature } from '@jbrowse/core/util'\nimport type { FileLocation } from '@jbrowse/core/util/types'\n\nconst withEngineSettings = withSettingActions.views(self => ({\n get engineSettings() {\n return engineSettingsOf({\n engine: self.layoutEngine,\n quality: self.layoutQuality,\n linearLayout: self.linearLayout,\n bubbleSpread: self.bubbleSpread,\n showDeletionEdges: self.showDeletionEdges,\n })\n },\n}))\n\nexport const withLoadActions = withEngineSettings.actions(self => {\n let loadController: AbortController | undefined\n // the samples TSV location the table was read from, or is being read from\n let sampleTableKey: string | undefined\n // The engine run the live layout waits on, which alone writes the status\n // line, and each run by the promise the force cache hands every request\n // that shares it\n let awaitedRun: object | undefined\n const runOf = new WeakMap<Promise<unknown>, object>()\n\n // A StatusCallback takes an RpcStatus, which `statusMessageText` reads\n function callEngine(request: EngineRequest, run: object) {\n const { rpcManager } = getSession(self)\n return rpcManager.call(getRpcSessionId(self), 'GraphComputeLayout', {\n ...request,\n signal: loadController?.signal,\n statusCallback: status => {\n if (run === awaitedRun) {\n self.setStatusMessage(statusMessageText(status) ?? '')\n }\n },\n }) as Promise<{ result: LayoutResult; duration: number }>\n }\n\n // Single dispatch point for every layout mode. A mode that returns a\n // result computed it locally; one that returns undefined can't draw this\n // graph and hands off to the remote FMMM engine, which is also how\n // 'force' is expressed. See LAYOUT_MODES.\n function* computeLayout(graph: Graph) {\n const start = performance.now()\n const tubeMap = TUBE_MAP_MODES.has(self.chosenLayoutMode)\n // a tube map draws the window; the cut's context is for walk rows\n const region = self.graphRegion\n const drawn = tubeMap && region ? trimToWindow(graph, region) : graph\n // reads are placed by the cut's segment names, which a fold renames\n const coarse =\n tubeMap && self.tubeMapFold > 0 && !drawn.reads\n ? coarsenTubeMap(drawn, self.tubeMapFold)\n : undefined\n const laid = coarse?.graph ?? drawn\n const bundled = (g: Graph) =>\n tubeMap && self.tubeMapRoutes !== 'each'\n ? bundleRoutes(\n g,\n self.tubeMapColoring?.valueOf,\n self.tubeMapRoutes === 'bundled',\n )\n : g\n const runs = self.walkCut?.walkRowRuns\n const local =\n self.chosenLayoutMode === 'walkrows' && runs\n ? walkRowLayoutOf(graph, walkRowsOf(runs), self.graphRegion)\n : layoutModeByValue(self.chosenLayoutMode).run(\n bundled(laid),\n self.graphRegion,\n self.host ? self.layoutResult?.sampleRows : undefined,\n )\n if (local) {\n const withCoarse = (r: LayoutResult) =>\n coarse && r.tubeMap ? { ...r, tubeMap: { ...r.tubeMap, coarse } } : r\n const whole = withCoarse(local)\n const split = self.tubeMapPanelSplit\n const result: PaneLayout =\n tubeMap && split\n ? withTubeMapPanels(\n whole,\n tubeMapPanelGroups(laid, split).map(group => {\n const panel = layoutModeByValue(self.chosenLayoutMode).run(\n bundled(graphOfPaths(laid, group.paths)),\n self.graphRegion,\n )\n return { ...group, result: panel && withCoarse(panel) }\n }),\n )\n : whole\n return {\n result,\n duration: performance.now() - start,\n mode: self.chosenLayoutMode,\n }\n }\n const settings = self.engineSettings\n const hit = forceLayouts.ready(graph, settings)\n if (hit) {\n return {\n result: hit,\n duration: performance.now() - start,\n mode: 'force' as const,\n }\n }\n const run = {}\n const pending = forceLayouts.layout(graph, settings, r =>\n callEngine(r, run),\n )\n awaitedRun = runOf.get(pending) ?? run\n runOf.set(pending, awaitedRun)\n const forced = (yield pending) as { result: LayoutResult; duration: number }\n return { ...forced, mode: 'force' as const }\n }\n\n // Which layout request is the live one. A layout is async and nothing in\n // the UI waits for it, so several are routinely in flight: every engine\n // setting lays the graph out again on change, and a force layout takes\n // seconds where an anchored one is instant.\n //\n // The graph identity below is not enough to order them, because the\n // competing requests are usually layouts of the SAME graph. Left to\n // resolve order the last one to FINISH won rather than the last one\n // asked for, so switching away from a slow force layout \u2014 to an anchored\n // mode, a cheaper bubble spread, a lower quality \u2014 drew the abandoned\n // one over the top of the chosen one seconds later, with the dropdown\n // still naming the choice that was discarded.\n let liveRequest = 0\n let liveRequestPending = false\n // the error the last failed layout raised, which the next one to land clears\n let layoutError: unknown\n // the graph the layout on screen was computed for\n let laidOutGraph: Graph | undefined\n // a haplotype's genes by track and contig span\n const walkGeneCache = new Map<string, GeneModel[]>()\n\n function dropLayoutOfReplacedGraph() {\n if (self.graph !== laidOutGraph) {\n laidOutGraph = undefined\n self.layoutResult = undefined\n self.drawnLayoutMode = undefined\n }\n }\n\n // Applied under a guard because a layout is async and the user can load a\n // different graph, or ask for a different layout of it, while one is in\n // flight; the stale result must not land.\n function* layoutInto(graph: Graph) {\n const request = ++liveRequest\n liveRequestPending = true\n awaitedRun = undefined\n const isLive = () => self.graph === graph && request === liveRequest\n const signal = loadController?.signal\n let computed\n try {\n // the node cap is a drawing's cost, and walk rows draw a bar per walk\n if (self.modeDrawsNodes && graph.nodes.length > self.maxGraphNodes) {\n throw new Error(\n `Graph too large to draw: ${graph.nodes.length.toLocaleString()} nodes (limit ${self.maxGraphNodes.toLocaleString()}). Pick Layout \u2192 Walk rows, zoom in to a smaller region, or raise the node limit in Graph settings.`,\n )\n }\n computed = yield* computeLayout(graph)\n } catch (e) {\n // A discarded layout's failure is not the user's problem: the drawing\n // they asked for is on screen or on its way, and raising a banner\n // over it reports a graph as broken because a setting they moved on\n // from could not be drawn. An aborted one was discarded by the load\n // that replaced it, even when the graph is still the same object.\n if (!isLive() || signal?.aborted) {\n return false\n }\n layoutError = e\n dropLayoutOfReplacedGraph()\n throw e\n } finally {\n if (request === liveRequest) {\n liveRequestPending = false\n settle()\n }\n }\n const live = isLive()\n if (live) {\n if (layoutError !== undefined && self.error === layoutError) {\n self.error = undefined\n }\n layoutError = undefined\n const previous = self.layoutResult\n const before = self.screenTransform\n laidOutGraph = graph\n self.layoutResult = computed.result\n self.drawnLayoutMode = computed.mode\n self.setLayoutMs(computed.duration)\n self.followNewLayout(previous)\n self.morphFrom(previous, before)\n }\n return live\n }\n\n // The walk a path graph's track puts on the region's assembly: the one\n // that names it, else the one chooseReferencePath infers\n function loadedReference(graph: Graph, region: SubgraphRegion) {\n const paths = graph.anchorPaths\n return graph.anchoredBy === 'paths' && paths\n ? (\n assemblyWalk(graph, self.assemblySpellings(region.assemblyName)) ??\n chooseReferencePath(paths, region.assemblyName)\n )?.name\n : undefined\n }\n\n // A cut parsed, its reference walk named: a tag-anchored walk-file cut\n // anchors on its nodes' tags, and names its walk on the region's assembly\n // so walk keys measure against it\n function parseCut(\n source: string | WalkCut,\n name: string,\n region: SubgraphRegion | undefined,\n whole = false,\n ) {\n const referencePath = self.referencePath || region?.assemblyName\n const parsed =\n typeof source !== 'string' && source.walkRowRuns && !whole\n ? walkRowsGraph(source, name, referencePath)\n : loadGraph(source, name, { referencePath })\n if (\n parsed.anchoredBy === 'tags' &&\n !parsed.referencePath &&\n parsed.paths?.length &&\n region\n ) {\n parsed.referencePath = assemblyWalk(\n parsed,\n self.assemblySpellings(region.assemblyName),\n )?.name\n }\n return parsed\n }\n\n // Replaces the graph on screen and the cut it came from, and drops the\n // annotations read beside the last graph. It drops the hover and the\n // selection too, because hoveredEdge is an index into graph.edges and\n // hoveredNode/selectedNode are ids, which would point the tooltip and the\n // highlight at whatever sits there in the new graph.\n function resetCut(cut?: {\n graph: Graph\n walkCut: WalkCut | undefined\n region: SubgraphRegion | undefined\n loadedReferencePath: string | undefined\n foldedBelowBp: number | undefined\n readsShown: { shown: number; total: number } | undefined\n }) {\n self.graph = cut?.graph\n self.walkCut = cut?.walkCut\n self.graphRegion = cut?.region\n self.loadedReferencePath = cut?.loadedReferencePath\n self.foldedBelowBp = cut?.foldedBelowBp\n self.readsShown = cut?.readsShown\n self.indexBubbles = undefined\n self.geneTrackFeatures = undefined\n self.walkGeneFeatures = undefined\n walkGeneCache.clear()\n self.repeatArrays = undefined\n self.clearInteractionState()\n }\n\n // `keepSelection` for a re-cut of the same source: node ids survive one\n // where edge indexes do not, so the selection is found again by id.\n // `readsOf` fetches the reads over the parsed graph before its one\n // layout, since the tube map lays them out with the paths. `foldBelowBp`\n // is what a host's zoom cannot show: variants under it fold into the\n // reference, and the drawing is clipped to the region it was cut for.\n function* parseAndLayout(\n source: string | WalkCut,\n name: string,\n region: SubgraphRegion | undefined,\n keepSelection = false,\n readsOf?: (graph: Graph) => Promise<GafReads>,\n foldBelowBp = 0,\n // reads over the cut that need no layout, started with it so a layout\n // that fails or runs long neither drops nor delays them\n alongside?: () => Promise<unknown>,\n ) {\n const signal = loadController?.signal\n const walkCut =\n typeof source !== 'string' && source.walkRowRuns ? source : undefined\n const parsed = parseCut(source, name, region)\n const loaded = region ? loadedReference(parsed, region) : undefined\n const anchored =\n !self.referencePath &&\n loaded !== undefined &&\n loaded !== parsed.referencePath\n ? anchorFromPaths(parsed, loaded)\n : parsed\n const folded =\n foldBelowBp > 0 && !readsOf\n ? foldVariants(anchored, foldBelowBp)\n : anchored\n const graph =\n region && folded !== anchored\n ? clipToWindow(folded, region, foldBelowBp)\n : folded\n let readsShown: { shown: number; total: number } | undefined\n if (readsOf) {\n self.setStatusMessage('Reading alignments')\n try {\n const { records, total } = (yield readsOf(graph)) as GafReads\n graph.reads = records\n readsShown = { shown: records.length, total }\n } catch (e) {\n if (signal?.aborted) {\n return\n }\n console.warn('[GraphGenomeView] no reads for this graph', e)\n }\n if (signal?.aborted) {\n return\n }\n }\n const selected = keepSelection ? self.selectedNode : null\n resetCut({\n graph,\n walkCut,\n region,\n loadedReferencePath: loaded,\n foldedBelowBp: folded === anchored ? undefined : foldBelowBp,\n readsShown,\n })\n // a re-cut keeps the bubbles still in it open\n const names = new Set(graph.nodes.map(n => n.name))\n self.openBubbles = self.openBubbles.filter(b =>\n bubbleSegmentIds(b).some(id => names.has(id)),\n )\n // against the new graph's own nodes: nodeById reads through the layout,\n // which is still the last graph's\n if (selected !== null && graph.nodes.some(n => n.id === selected)) {\n self.selectedNode = selected\n }\n self.setStatusMessage('Computing layout')\n const reads = alongside?.()\n reads?.catch(() => undefined)\n yield* layoutInto(graph)\n // a load superseded mid-layout leaves the status to the one replacing it\n if (reads && !signal?.aborted) {\n self.setStatusMessage('Reading annotations')\n yield reads\n }\n }\n\n // Which load is the live one, for the reason liveRequest orders layouts:\n // every change in the settings dialog re-cuts, a remote cut takes seconds,\n // and the last one to finish is not the last one asked for.\n let liveLoad = 0\n // the load still fetching, parsing or reading annotations, whose spinner a\n // layout of the graph already on screen must not clear\n let loadInFlight: number | undefined\n\n function beginLoad() {\n const load = ++liveLoad\n loadController?.abort()\n loadController = new AbortController()\n loadInFlight = load\n self.loadCanceled = false\n return {\n isLive: () => load === liveLoad,\n signal: loadController.signal,\n }\n }\n\n // The spinner stays up while a load or the layout last asked for is in\n // flight. Clearing it sooner reports \"done\" while the layout the user\n // asked for is still computing, the common case when a cheap choice\n // follows an expensive one.\n function settle() {\n if (loadInFlight === undefined && !liveRequestPending) {\n self.finishLoading()\n }\n }\n\n function endLoad() {\n loadInFlight = undefined\n settle()\n }\n\n // Runs `body` as a load. It raises the spinner and clears the error first,\n // and while it is the live load it reports a failure and ends the spinner.\n function* runLoad(\n label: string,\n body: (load: {\n isLive: () => boolean\n signal: AbortSignal\n }) => Generator<PromiseLike<unknown>, void, unknown>,\n ) {\n const load = beginLoad()\n self.isLoading = true\n self.error = undefined\n try {\n yield* body(load)\n } catch (e) {\n if (load.isLive()) {\n console.error(`[GraphGenomeView.${label}]`, e)\n self.error = e\n }\n } finally {\n if (load.isLive()) {\n endLoad()\n }\n }\n }\n\n // Features over the cut. A failed read warns and returns undefined, so an\n // annotation never fails the load.\n function* readFeatures(\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n what: string,\n signal?: AbortSignal,\n ) {\n try {\n return (yield getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'CoreGetFeatures',\n { adapterConfig, regions: [region], signal },\n )) as Feature[]\n } catch (e) {\n console.warn(`[GraphGenomeView] no ${what} for this graph`, e)\n return undefined\n }\n }\n\n // The bubble index that the hosted HPRC build keeps beside its segments,\n // `<prefix>.bubbles.bed.gz`, read through the bubble adapter over the same\n // window. A graph whose source has no such file, the ordinary case for a\n // graph of one's own, keeps its derived bubbles, so a failure here is not\n // the graph's problem. A coarse cut reads none: its nodes are the\n // bubbles, and the index over its window can run to a chromosome's rows.\n function* loadBubbles(\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n isLive: () => boolean,\n signal?: AbortSignal,\n foldBelowBp = 0,\n ) {\n // The track config arrives as written, so the prefix is either the\n // `uri` shorthand or the segments location it expands to.\n const prefix = bubblePrefix(adapterConfig)\n if (adapterConfig.type !== 'RgfaTabixAdapter' || prefix === undefined) {\n return\n }\n const features = yield* readFeatures(\n {\n type: 'MinigraphBubbleAdapter',\n uri: `${prefix}.bubbles.bed.gz`,\n baseUri: adapterConfig.baseUri,\n assemblyNameToPanSN: adapterConfig.assemblyNameToPanSN,\n },\n region,\n 'bubble index',\n signal,\n )\n if (features && isLive()) {\n self.indexBubbles = features.flatMap(f => {\n const start = f.get('start')\n const end = f.get('end')\n const longestAlleleLength = f.get('longestAlleleLength') as number\n return Math.max(end - start, longestAlleleLength) < foldBelowBp\n ? []\n : [\n {\n refName: region.refName,\n start,\n end,\n segmentCount: f.get('segmentCount') as number,\n pathCount: (f.get('pathCount') as number | undefined) ?? 0,\n inversion: f.get('inversion') as boolean,\n shortestAlleleLength: f.get('shortestAlleleLength') as number,\n longestAlleleLength,\n segments: f.get('segments') as string,\n shortestAllele: undefined,\n longestAllele: undefined,\n },\n ]\n })\n }\n }\n\n // A session track's features over the cut, undefined when the session has\n // no such track\n function* trackFeatures(\n trackId: string | undefined,\n region: SubgraphRegion,\n what: string,\n signal?: AbortSignal,\n ) {\n const config = trackId ? self.sessionTrack(trackId) : undefined\n if (!config) {\n return undefined\n }\n return yield* readFeatures(\n readConfObject(config, 'adapter'),\n region,\n what,\n signal,\n )\n }\n\n // The annotation tracks read over the cut: genes, which `geneFeatures`\n // makes genes of for the backbone to carry, and tandem repeat arrays, for\n // the walk rows to measure between and tile by\n const annotations = {\n genes: {\n trackId: () => self.geneTrack?.trackId,\n set: (features: Feature[] | undefined) => {\n self.geneTrackFeatures = features\n },\n },\n repeats: {\n trackId: () => self.repeatTrack?.trackId,\n set: (features: Feature[] | undefined) => {\n self.repeatArrays = features && repeatArraysFrom(features)\n },\n },\n }\n type Annotation = keyof typeof annotations\n\n // Lands only while the track it read is still the one chosen, so a slow\n // read cannot land over the pick that followed it\n function* loadAnnotation(\n kind: Annotation,\n region: SubgraphRegion,\n isLive: () => boolean,\n signal?: AbortSignal,\n ) {\n const { trackId, set } = annotations[kind]\n const track = trackId()\n const features = yield* trackFeatures(track, region, kind, signal)\n if (features && isLive() && trackId() === track) {\n set(features)\n }\n }\n\n // The annotation reads over a cut, each landing as it arrives\n function annotationReads(\n region: SubgraphRegion,\n isLive: () => boolean,\n signal: AbortSignal,\n ) {\n return (['genes', 'repeats'] as const).map(kind =>\n flow(loadAnnotation)(kind, region, isLive, signal),\n )\n }\n\n // One annotation read again alone, for a track change\n function* reloadAnnotation(kind: Annotation) {\n const region = self.graphRegion\n if (region) {\n annotations[kind].set(undefined)\n yield* loadAnnotation(kind, region, () => self.graphRegion === region)\n }\n }\n\n // Raises `isLoading` before any fetch, so a view waiting on a remote file\n // shows its loading state instead of the import form. Text already in\n // hand is parsed without yielding first. `region` is the window a\n // declared file was stated beside, which the parse anchors on and the\n // annotations are read over.\n function* loadWholeGFA(\n name: string,\n source: string | ((signal: AbortSignal) => Promise<string>),\n region?: SubgraphRegion,\n ) {\n yield* runLoad('loadWholeGFA', function* ({ isLive, signal }) {\n const text =\n typeof source === 'string' ? source : ((yield source(signal)) as string)\n if (!isLive()) {\n return\n }\n yield* parseAndLayout(\n text,\n name,\n region,\n false,\n undefined,\n 0,\n region && (() => Promise.all(annotationReads(region, isLive, signal))),\n )\n })\n }\n\n function abortLoad() {\n loadController?.abort()\n loadController = undefined\n loadInFlight = undefined\n liveLoad++\n liveRequest++\n liveRequestPending = false\n awaitedRun = undefined\n }\n\n // The graph a layout of the current mode draws: a walk-rows cut's\n // stepless walks parsed whole once a layout that draws nodes needs them\n function wholeGraph() {\n const cut = self.walkCut\n const graph = self.graph\n if (!cut || !graph || self.chosenLayoutMode === 'walkrows') {\n return graph\n }\n const whole = parseCut(cut, graph.name, self.graphRegion, true)\n self.graph = whole\n self.walkCut = undefined\n return whole\n }\n\n // Drops the graph and all it derived, and ends any load in flight, which\n // would otherwise land its graph afterwards\n function dropGraph() {\n abortLoad()\n self.finishMorph()\n self.morphEntering = undefined\n self.drawnBatch = EMPTY_BATCH\n self.paintedViewport = undefined\n resetCut()\n laidOutGraph = undefined\n layoutError = undefined\n self.layoutResult = undefined\n self.drawnLayoutMode = undefined\n self.walkRowSampleTable = undefined\n sampleTableKey = undefined\n self.openBubbles = []\n self.error = undefined\n self.isLoading = false\n self.loadCanceled = false\n self.statusMessage = ''\n self.clearPerfMetrics()\n // the next graph has nothing to do with where the user left this one\n if (self.viewportOwner === 'user') {\n self.viewportOwner = 'fit'\n }\n }\n\n return {\n // back to the import form\n clearGraph() {\n dropGraph()\n },\n // The user's stop before anything is drawn. The source stays, so a\n // retry can load it again.\n cancelLoad() {\n if (self.canCancelLoad) {\n dropGraph()\n self.loadCanceled = true\n }\n },\n // The user's stop, leaving whatever is drawn under it, and dropping a\n // swapped-in graph whose layout never landed\n stopLoad() {\n abortLoad()\n dropLayoutOfReplacedGraph()\n if (!self.layoutResult) {\n resetCut()\n }\n self.isLoading = false\n self.statusMessage = ''\n self.loadCanceled = true\n },\n beforeDestroy() {\n abortLoad()\n },\n loadGFA: flow(function* (text: string, name = 'Imported GFA') {\n yield* loadWholeGFA(name, text)\n }),\n // A file the user picked, read inside the load so the form shows its\n // progress rather than sitting idle through a large read\n loadGFAFile: flow(function* (file: Blob, name: string) {\n self.setStatusMessage('Reading file')\n yield* loadWholeGFA(name, () =>\n file.arrayBuffer().then(buf => gfaText(new Uint8Array(buf))),\n )\n }),\n loadGFAFromLocation: flow(function* (\n location: FileLocation,\n region?: SubgraphRegion,\n ) {\n self.setStatusMessage('Fetching GFA')\n yield* loadWholeGFA(\n fileName(location) || 'GFA',\n signal =>\n openLocation(location, getEnv(self).pluginManager)\n .readFile({ signal })\n .then(gfaText),\n region,\n )\n }),\n // One cut of a region, laid out with the annotations over it. Whether\n // the region may be cut is the caller's call; overlapping cuts are\n // ordered by liveLoad, so the latest one lands.\n cutSubgraph: flow(function* (\n adapterConfig: Record<string, unknown>,\n region: SubgraphRegion,\n opts: SubgraphCutOptions = {},\n foldBelowBp = 0,\n ) {\n yield* runLoad('cutSubgraph', function* ({ isLive, signal }) {\n self.setStatusMessage('Fetching subgraph')\n const fetchStart = performance.now()\n const cut = (yield getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetSubgraph',\n { adapterConfig, region, opts, signal },\n )) as string | WalkCut\n if (!isLive()) {\n return\n }\n self.setFetchMs(performance.now() - fetchStart)\n if (!cut) {\n throw new Error(\n 'Adapter returned no GFA \u2014 region may be outside indexed data or the adapter does not implement getSubgraph',\n )\n }\n yield* parseAndLayout(\n cut,\n regionLabel(region),\n region,\n true,\n namesReads(adapterConfig)\n ? graph =>\n getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetGraphReads',\n {\n adapterConfig,\n nodeNames: graph.nodes.map(n => n.name),\n signal,\n },\n )\n : undefined,\n foldBelowBp,\n // Independent remote reads, each landing as it arrives. A coarse\n // cut reads no bubble index: its nodes are the bubbles, and the\n // index over its window can run to a chromosome's rows.\n () =>\n Promise.all([\n opts.tier === 'coarse'\n ? undefined\n : flow(loadBubbles)(\n adapterConfig,\n region,\n isLive,\n signal,\n self.foldedBelowBp,\n ),\n ...annotationReads(region, isLive, signal),\n ]),\n )\n })\n }),\n // A track change re-reads that annotation alone. The graph, its layout\n // and any open bubble stay as they are.\n reloadRepeats: flow(function* () {\n yield* reloadAnnotation('repeats')\n }),\n reloadGenes: flow(function* () {\n yield* reloadAnnotation('genes')\n }),\n // The source track's samples TSV, read once per location, for walk\n // rows to group by. A failed read leaves the rows ungrouped, says so,\n // and is tried again on the next call.\n loadWalkRowSampleTable: flow(function* () {\n const location = self.walkRowSamplesTsv\n const key = location ? JSON.stringify(location) : undefined\n if (key === sampleTableKey) {\n return\n }\n sampleTableKey = key\n self.walkRowSampleTable = undefined\n if (!location) {\n return\n }\n try {\n const text = (yield openLocation(\n location,\n getEnv(self).pluginManager,\n ).readFile('utf8')) as string\n if (isAlive(self) && key === sampleTableKey) {\n self.walkRowSampleTable = parseSamplesTsv(text)\n }\n } catch (e) {\n if (isAlive(self) && key === sampleTableKey) {\n sampleTableKey = undefined\n getSession(self).notify(\n `Walk rows cannot be grouped: the samples table did not load (${String(e)})`,\n 'warning',\n )\n }\n }\n }),\n // The walk rows' genes, each row's from its haplotype's assembly. A\n // row's genes are its own contig's, so they take the row's name for\n // their contig, whatever the track calls it.\n loadWalkGenes: flow(function* () {\n const reads = self.walkGeneReads?.reads ?? []\n const key = JSON.stringify(reads)\n const graph = self.graph\n const fetched = new Map<string, GeneModel[]>()\n yield Promise.all(\n reads.map(({ row, trackId, region }) =>\n flow(function* () {\n const cacheKey = `${trackId} ${region.refName}:${region.start}-${region.end}`\n let genes = walkGeneCache.get(cacheKey)\n if (!genes) {\n const features = yield* trackFeatures(\n trackId,\n region,\n 'haplotype genes',\n )\n if (!features) {\n return\n }\n genes = geneModelsFrom(features).map(g => ({\n ...g,\n refName: region.refName,\n }))\n walkGeneCache.set(cacheKey, genes)\n }\n fetched.set(row, genes)\n })(),\n ),\n )\n if (\n isAlive(self) &&\n self.graph === graph &&\n JSON.stringify(self.walkGeneReads?.reads ?? []) === key\n ) {\n self.walkGeneFeatures = reads.length ? fetched : undefined\n }\n }),\n // Open a bubble in place: it keeps its colour, the rest of the drawing\n // greys, and the bubbles inside it get labels of their own. Opening an\n // open one closes it and those inside it.\n toggleBubble(bubble: MinigraphBubble) {\n const open = self.openBubbles\n const at = open.findIndex(o => sameBubble(o, bubble))\n if (at >= 0) {\n self.openBubbles = open.slice(0, at)\n return\n }\n const names = new Set(bubbleSegmentIds(bubble))\n if (!self.graph?.nodes.some(n => names.has(n.name))) {\n getSession(self).notify(\n 'None of the segments of this bubble are in the cut; widen the graph context to open it',\n 'info',\n )\n return\n }\n const insides = self.openBubbleInsides\n let parent = insides.length - 1\n while (\n parent >= 0 &&\n !insides[parent]!.some(b => sameBubble(b, bubble))\n ) {\n parent--\n }\n self.openBubbles = [...open.slice(0, parent + 1), bubble]\n },\n closeBubbles() {\n if (self.openBubbles.length > 0) {\n self.openBubbles = []\n }\n },\n recomputeLayout: flow(function* () {\n const graph = wholeGraph()\n if (!graph) {\n return\n }\n self.isLoading = true\n self.setStatusMessage('Computing layout')\n try {\n yield* layoutInto(graph)\n } catch (e) {\n console.error('[GraphGenomeView.recomputeLayout]', e)\n self.error = e\n }\n }),\n }\n})\n", "import { isBackbone } from '@jbrowse/bandage-core/anchoredNodes'\n\nimport { isRecord } from '../isRecord'\n\nimport type { SubgraphRegion } from '../GetSubgraph'\nimport type { GraphNode } from '@jbrowse/bandage-core/types'\n\n// What a LinearGenomeView writes to `session.hovered` on every mousemove (see\n// LinearGenomeViewContainer): the bp under the cursor, plus the feature under it\n// if the topmost track had one. Nothing names the source VIEW, so a graph view\n// filters by whether the position falls in the region it was cut from \u2014 but the\n// position does name the source ASSEMBLY, and that turns out to be the half\n// that matters.\nexport interface LgvHover {\n refName: string\n // The 0-based base under the pointer, the convention `stable.start` and the\n // cut region are in. Not the LGV's own `coord`, which is 1-based for display.\n coord: number\n // The assembly the hovered view is showing. `hoverPosition` is a\n // `PxToBpResult`, i.e. the displayed region the pointer landed in spread flat,\n // so this is that region's own `assemblyName`.\n //\n // Read because refName alone does not identify a locus in a session holding\n // several assemblies, which is every session these graphs are launched in. A\n // PanSN name reduces to a bare contig \u2014 the E. coli pangenome loads five\n // strains each with one refName `chr`, and HPRC's hg38 and a GenArk haplotype\n // both call it `chr6` \u2014 so a synteny stack's rows all answer to the same\n // name at unrelated coordinates. Without this the hover on ANY row lit up a\n // node in the graph, and the node then published its own reference interval\n // back into every linear view.\n //\n // Optional because the channel is typed `unknown` and read structurally: a\n // hover that states no assembly is taken at its word rather than dropped.\n assemblyName?: string\n featureName?: string\n}\n\ninterface FeatureLike {\n get: (key: string) => unknown\n}\n\nfunction isFeatureLike(value: unknown): value is FeatureLike {\n return isRecord(value) && typeof value.get === 'function'\n}\n\n// A display hovers either a Feature, read with `get`, or a plain hit item with\n// a `name` of its own, which is what the canvas feature display hands over.\n// Reading only the first left the exact segment match dead on that display.\nfunction hoveredName(feature: unknown) {\n const name = isFeatureLike(feature)\n ? feature.get('name')\n : isRecord(feature)\n ? feature.name\n : undefined\n return typeof name === 'string' ? name : undefined\n}\n\n// `hovered` is typed `unknown` on the session by design \u2014 it is a shared channel\n// every view writes its own shape to \u2014 so this reads the LGV's shape out of it\n// structurally rather than asserting a type onto it.\nexport function readLgvHover(hovered: unknown): LgvHover | undefined {\n let result: LgvHover | undefined\n if (isRecord(hovered) && isRecord(hovered.hoverPosition)) {\n const { refName, coord, coord0, assemblyName } = hovered.hoverPosition\n if (typeof refName === 'string' && typeof coord === 'number') {\n result = {\n refName,\n // `coord` is 1-based; a host that states the 0-based `coord0` is\n // taken at its word. Read as 0-based, the last base of every node lit\n // the next one, and a 1 bp node could not be reached at all.\n coord: typeof coord0 === 'number' ? coord0 : coord - 1,\n assemblyName:\n typeof assemblyName === 'string' ? assemblyName : undefined,\n featureName: hoveredName(hovered.hoverFeature),\n }\n }\n }\n return result\n}\n\n// Whether a hover is one this graph can answer: the same assembly, the same\n// stable sequence, and inside the window the cut was made for.\n//\n// The assembly is checked FIRST and is the whole reason this is not just a\n// coordinate test. See LgvHover.assemblyName: a graph cut from K12 and a\n// synteny row on Sakai both call their sequence `chr`, so on refName and\n// coordinate alone every row of the stack matched and the graph highlighted a\n// K12 node at Sakai's offset. A hover that names no assembly still passes,\n// which is what a hand-written channel writer and the older LGVs get.\nexport function hoverInRegion(hover: LgvHover, region: SubgraphRegion) {\n return (\n (hover.assemblyName === undefined ||\n hover.assemblyName === region.assemblyName) &&\n hover.refName === region.refName &&\n hover.coord >= region.start &&\n hover.coord < region.end\n )\n}\n\n// The graph node a linear-view hover points at.\n//\n// The feature under the cursor is the exact answer when the graph's own segments\n// track is what's hovered: an RgfaTabixAdapter feature's name is the segment id,\n// which is `GraphNode.name` (`GraphNode.id` carries a strand suffix, so the\n// match has to be on name). Any other track \u2014 genes, bubbles \u2014 supplies only a\n// coordinate, which still identifies the backbone segment covering it: the\n// backbone tiles the reference exactly once, whether rGFA's rank 0 declared it\n// or a reference path's own steps did.\nexport function nodeForLgvHover({\n hover,\n nodes,\n}: {\n hover: LgvHover\n nodes: GraphNode[]\n}) {\n let byName: string | undefined\n let byCoord: string | undefined\n for (const node of nodes) {\n if (node.name === hover.featureName) {\n byName = node.id\n } else if (\n byCoord === undefined &&\n isBackbone(node) &&\n hover.coord >= node.stable.start &&\n hover.coord < node.stable.start + node.length\n ) {\n byCoord = node.id\n }\n }\n // An exact segment match wins over the coordinate it happens to sit at.\n return byName ?? byCoord ?? null\n}\n", "import { panSNSample } from '@jbrowse/bandage-core/pansn'\nimport { pathOrigin } from '@jbrowse/bandage-core/pathAnchoring'\n\n// A per-sample lane names its rows its own way: a phased callset `HG00097 HP0`,\n// counting haplotypes from 0, a MAF `HG00097.1`, counting from 1 as PanSN does,\n// and anything else by the bare sample\nconst PHASED_ROW = /^(.+) HP(\\d+)$/\nconst DOTTED_ROW = /^(.+)\\.(\\d+)$/\n\n// A bare sample can end in `.2` too, an accession for one, so each reading is\n// tried in turn\nfunction readings(row: string) {\n const phased = PHASED_ROW.exec(row)\n const dotted = DOTTED_ROW.exec(row)\n return [\n ...(phased\n ? [{ sample: phased[1]!, haplotype: String(Number(phased[2]) + 1) }]\n : []),\n ...(dotted ? [{ sample: dotted[1]!, haplotype: dotted[2] }] : []),\n { sample: row, haplotype: undefined },\n ]\n}\n\nfunction haplotypeOf(pathName: string) {\n return pathOrigin(pathName).name.split('#')[1]\n}\n\n// The walks a hovered lane row stands for: the one of its haplotype, or every\n// walk of a bare sample. A cut often holds one haplotype of a sample, so a row\n// naming the other matches nothing rather than the one it holds.\nexport function walksForRow(row: string, paths: readonly { name: string }[]) {\n const names = paths.map(p => p.name)\n for (const { sample, haplotype } of readings(row)) {\n const walks = names.filter(\n name =>\n panSNSample(pathOrigin(name).name) === sample &&\n (haplotype === undefined || haplotypeOf(name) === haplotype),\n )\n if (walks.length > 0) {\n return walks\n }\n }\n return []\n}\n", "import { contains } from '@jbrowse/bandage-core/viewport'\nimport { getSession } from '@jbrowse/core/util'\nimport { addDisposer } from '@jbrowse/mobx-state-tree'\nimport { autorun, reaction, untracked } from 'mobx'\n\nimport { withLoadActions } from './loadActions'\nimport {\n EMPTY_BATCH,\n TUBE_MAP_MODES,\n dependOn,\n paneViewportOf,\n} from './paneBase'\nimport {\n hoverInRegion,\n nodeForLgvHover,\n readLgvHover,\n} from '../../hoverSync/lgvHover'\nimport { walksForRow } from '../../hoverSync/rowWalks'\nimport { trackedDpr } from '../trackedDpr'\n\nimport type { LayoutEngineKind } from '@jbrowse/bandage-core/layoutEngines'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { Renderer } from '@jbrowse/bandage-core/renderer/types'\n\nexport const withRenderingActions = withLoadActions\n .actions(self => ({\n startRenderingBackend(backend: Renderer) {\n if (!self.autorunsInstalled) {\n // Autorun: keep the view fitted to the graph until the user moves it.\n // Reading fittedTransform tracks everything the fit depends on, so\n // it re-fits as the layout arrives, the canvas is measured and the\n // genes over a tube map claim their rows. A manual pan/zoom (or a\n // restored-session transform) makes the viewport the user's, and a\n // host makes it the linear view's.\n addDisposer(\n self,\n autorun(() => {\n if (\n self.fittedTransform &&\n untracked(() => self.viewportOwner === 'fit')\n ) {\n self.zoomToFit()\n }\n }),\n )\n\n // A narrower or shorter pane can leave a placed drawing off screen\n addDisposer(\n self,\n reaction(\n () => `${self.viewBox.width} ${self.viewBox.height}`,\n () => {\n self.keepDrawingInView()\n },\n ),\n )\n addDisposer(\n self,\n // Faceting on or off, its columns, its count of panels and what\n // they split by each reshape the boxes the drawing is fitted into\n reaction(\n () => {\n const grid = self.facetGrid\n return grid\n ? `${self.facetSetting.field} ${self.facetPanels?.length} ${grid.columns}`\n : ''\n },\n () => {\n self.refitView()\n },\n ),\n )\n // The walk rows' genes follow the rows: a new cut, a repeat pick or\n // a sample filter changes which haplotypes and spans they read\n addDisposer(\n self,\n reaction(\n () => ({\n graph: self.graph,\n reads: JSON.stringify(self.walkGeneReads?.reads ?? []),\n }),\n () => {\n void self.loadWalkGenes()\n },\n {\n fireImmediately: true,\n equals: (a, b) => a.graph === b.graph && a.reads === b.reads,\n },\n ),\n )\n // Walk rows and tube map panels read the source track's samples\n // TSV, to group by its columns, again for a graph after a dropped one\n addDisposer(\n self,\n reaction(\n () =>\n self.hasGraph &&\n (self.chosenLayoutMode === 'walkrows' ||\n TUBE_MAP_MODES.has(self.chosenLayoutMode))\n ? JSON.stringify(self.walkRowSamplesTsv ?? null)\n : undefined,\n key => {\n if (key !== undefined) {\n void self.loadWalkRowSampleTable()\n }\n },\n { fireImmediately: true },\n ),\n )\n // A host fits the rows once, when it takes the pane over, which is\n // before the legend measures the room it needs above them\n addDisposer(\n self,\n reaction(\n () => self.fitPadTop,\n () => {\n if (self.viewportOwner === 'host') {\n self.zoomToFit()\n }\n },\n ),\n )\n\n // Autorun: mirror a connected linear view's hover onto the graph. An\n // LGV writes `{hoverPosition, hoverFeature}` to session.hovered on\n // every mousemove; neither field names the source view, so the guard\n // is that the position lies in the region this graph was cut from.\n // A pointer over the pane itself is the host's too, at a bp its x\n // only means on a reference-axis layout, so there the pane's own hit\n // test is the hover. A row naming a walk always lifts it; the node at\n // a bp lights only on `hover: 'everything'`, since every track's\n // pointer passes over some node's bp.\n //\n // Only `hovered` and the setting are tracked \u2014 the graph reads are\n // untracked, so a geometry rebuild can't re-fire this and clobber a\n // hover the canvas itself set. Assigning an unchanged id doesn't notify, so a hover\n // that travels within one segment costs nothing downstream.\n addDisposer(\n self,\n autorun(() => {\n const hover = readLgvHover(getSession(self).hovered)\n const lightsNode = self.hoverLightsEverything\n untracked(() => {\n const region = self.graphRegion\n const graph = self.graph\n const inRegion =\n hover && region && hoverInRegion(hover, region)\n ? hover\n : undefined\n // a row naming a walk is the hover, not the node at its bp,\n // whose band would cover the row's own cells\n const rowWalks =\n inRegion?.featureName && graph?.paths\n ? walksForRow(inRegion.featureName, graph.paths)\n : []\n if (region && graph && !self.pointerInPane) {\n self.setHoveredNode(\n inRegion && lightsNode && rowWalks.length === 0\n ? nodeForLgvHover({ hover: inRegion, nodes: graph.nodes })\n : null,\n )\n }\n self.setHoveredRowWalks(rowWalks)\n })\n }),\n )\n\n // Reaction: drop a hover the pointer cannot still be over.\n //\n // A hover is set by a mousemove on the canvas, and here the drawing\n // moves under a STATIONARY cursor on three axes \u2014 the wheel zoom, the\n // toolbar's zoom and fit buttons, and a pan \u2014 none of which fire a\n // pointer event. Left alone the tooltip goes on naming the node that\n // used to be under the cursor, `hoverHighlight` goes on publishing its\n // span, and the paired linear view paints a band over the wrong\n // sequence until the mouse happens to move.\n //\n // This is jbrowse-components' `installClearHoverOnViewportChange`\n // (BaseLinearDisplay), whose three axes are bpPerPx / offsetPx /\n // scrollTop; a graph view's are its own transform. Its rule is worth\n // restating rather than just citing: a sticky canvas gets no\n // mousemove and no mouseleave for any of them. Not imported because\n // it lives in the LGV plugin and reads a containing LGV, and this\n // plugin deliberately takes no runtime dependency on that plugin\n // (see hoverSync/index.tsx).\n //\n // A `reaction`, not an autorun, for the reason stated there: the\n // effect touches hover state, and an autorun would re-enter itself.\n // Selection is untouched \u2014 a click is a choice, and the content\n // moving does not unmake it.\n addDisposer(\n self,\n reaction(\n () => `${self.scale}-${self.translateX}-${self.translateY}`,\n () => {\n self.clearHover()\n },\n { name: 'GraphClearHoverOnViewportChange' },\n ),\n )\n\n // Autorun: a zoom, or a pan that leaves the window the last build\n // covered, schedules a debounced rebuild. A pan inside it costs a\n // repaint and nothing else. Skips the first run.\n let firstViewport = true\n addDisposer(\n self,\n autorun(() => {\n const { scale } = self\n const viewport = paneViewportOf(self)\n if (firstViewport) {\n firstViewport = false\n return\n }\n const built = untracked(() => self.builtViewport)\n if (built?.scale === scale && contains(built.bounds, viewport)) {\n return\n }\n self.scheduleViewportDirty()\n }),\n )\n\n // Autorun: the selection. The hover paints on a layer of its own.\n addDisposer(\n self,\n autorun(() => {\n const b = self.currentRenderingBackend as Renderer | undefined\n if (b) {\n self.applySelection(b)\n self.renderNow()\n }\n }),\n )\n }\n\n // The second argument is a SETUP THUNK, not the callbacks themselves:\n // anything it closes over lives exactly as long as the callbacks that\n // read it, which is what lets a per-backend memo work.\n self.attachRenderingBackend<Renderer>(backend, () => ({\n // Autorun: rebuild geometry when graph data or display options\n // change. scale/translate are untracked so they don't trigger a full\n // rebuild \u2014 only the debounced viewportDirty flag does.\n upload: (b: Renderer) => {\n dependOn(trackedDpr())\n b.resize(self.paneWidth, self.canvasHeight)\n if (self.layoutResult?.tubeMap || self.facetPanels) {\n dependOn(self.viewportDirty)\n b.uploadGeometry(EMPTY_BATCH)\n self.setGeometryMetrics(0, EMPTY_BATCH, {\n scale: untracked(() => self.scale),\n bounds: untracked(() => self.viewportToBuild()),\n })\n return true\n }\n const geometryStart = performance.now()\n const built = self.buildDrawing(\n self.drawnHighlight,\n self.effectiveDrawPaths,\n )\n if (built) {\n b.uploadGeometry(built.batch)\n self.setGeometryMetrics(\n performance.now() - geometryStart,\n built.batch,\n {\n scale: untracked(() => self.scale),\n bounds: built.viewportBounds,\n },\n )\n return true\n }\n // Nothing reached the backend, so the autorun may skip the redraw\n // it would otherwise force. Safe despite the resize above: with no\n // positions there is nothing to draw, which is the same case\n // `render` below returns false for.\n return false\n },\n // Autorun: re-render on pan/zoom/theme without rebuilding geometry\n render: (b: Renderer) => {\n if (!self.nodePositions) {\n return false\n }\n self.paint(b)\n self.markPainted()\n return true\n },\n releaseTargets: (b: Renderer) => {\n b.releaseOffscreenTargets()\n },\n }))\n },\n }))\n .actions(self => ({\n // The drawing made again for a layout mode that changed from `from`; a\n // host overrides it with what its source needs, such as a recut\n relayoutFrom(_from: LayoutModeValue): Promise<unknown> {\n return self.recomputeLayout()\n },\n }))\n .actions(self => ({\n relayout(from: LayoutModeValue) {\n self.handledLayoutMode = self.chosenLayoutMode\n return self.relayoutFrom(from)\n },\n }))\n .actions(self => ({\n // A layout picked from a menu: the mode, then the drawing it makes.\n switchLayout(mode: LayoutModeValue) {\n const from = self.chosenLayoutMode\n self.setLayoutMode(mode)\n return self.relayout(from)\n },\n // loads the source again, for a host that has one\n retryLoad() {},\n afterAttach() {\n // A restored session that already carries a non-default transform is\n // the user's own view \u2014 mark it so the fit autorun leaves it alone.\n if (!self.isDefaultViewport) {\n self.viewportOwner = 'user'\n }\n // A gene or repeat track change over the same cut re-reads that\n // annotation alone, whatever made it: the settings dialog, a track\n // added to the session, undo or a session delta. A new cut reads its\n // own.\n for (const [trackOf, reload] of [\n [() => self.geneTrack?.trackId, () => self.reloadGenes()],\n [() => self.repeatTrack?.trackId, () => self.reloadRepeats()],\n ] as const) {\n addDisposer(\n self,\n reaction(\n () => ({ track: trackOf(), region: self.graphRegion }),\n (now, was) => {\n if (now.region && now.region === was.region) {\n void reload()\n }\n },\n {\n equals: (a, b) => a.track === b.track && a.region === b.region,\n },\n ),\n )\n }\n // The layout set by anything but the menu: the config editor, Reset\n // track settings, undo, a session delta\n addDisposer(\n self,\n reaction(\n () => self.chosenLayoutMode,\n (to, from) => {\n if (to !== self.handledLayoutMode) {\n void self.relayout(from)\n }\n },\n ),\n )\n // An engine setting or the node cap lays the graph out again whatever\n // changed it: the settings dialog, the menu, the config editor, Reset\n // track settings, undo or a session delta. A change of layout mode lays\n // the graph out through relayout, so this reaction skips it.\n addDisposer(\n self,\n reaction(\n () => ({\n mode: self.chosenLayoutMode,\n engine: JSON.stringify(self.engineSettings),\n maxNodes: self.maxGraphNodes,\n }),\n (now, was) => {\n if (\n self.graph &&\n now.mode === was.mode &&\n ((now.engine !== was.engine && self.usesLayoutEngine) ||\n (now.maxNodes !== was.maxNodes && self.modeDrawsNodes))\n ) {\n void self.recomputeLayout()\n }\n },\n {\n equals: (a, b) =>\n a.mode === b.mode &&\n a.engine === b.engine &&\n a.maxNodes === b.maxNodes,\n },\n ),\n )\n // a tube map lays out again for its fold, its panels, its routes and\n // the column its routes split by\n addDisposer(\n self,\n reaction(\n () =>\n TUBE_MAP_MODES.has(self.chosenLayoutMode)\n ? JSON.stringify({\n fold: self.tubeMapFold,\n facet: self.facetSetting,\n groupBy: self.walkRowGroupBy,\n table: self.walkRowGroupBy && self.walkRowSampleTable?.length,\n routes: self.tubeMapRoutes,\n bundledBy:\n self.tubeMapRoutes !== 'each'\n ? self.tubeMapColoring?.field\n : undefined,\n })\n : undefined,\n (facet, was) => {\n if (facet !== undefined && was !== undefined && self.graph) {\n void self.recomputeLayout()\n }\n },\n ),\n )\n },\n }))\n .actions(self => ({\n // Sets the engine and the mode in one action, so the engine reaction\n // sees the mode change and leaves the relayout to switchLayout\n switchForceEngine(engine: LayoutEngineKind) {\n self.setLayoutEngine(engine)\n return self.chosenLayoutMode === 'force'\n ? undefined\n : self.switchLayout('force')\n },\n }))\n", "import { readConfObject } from '@jbrowse/core/configuration'\n\nimport { canonicalAssemblyName, trackAssemblies } from './launchFromGraph'\n\nimport type { TrackScanSession } from './launchFromGraph'\n\nconst ANNOTATION_TRACK_TYPE = 'FeatureTrack'\n\n// What to turn on in a linear view the graph opens on `assemblyName`.\n//\n// A launch used to carry the graph's own track and nothing else, and that track\n// is configured for the reference alone \u2014 so `Launch view` \u2192 `CFT073 chr:\u2026`\n// landed on `No tracks active`, which answers \"where is this strain's sequence?\"\n// with an empty pane. What the session does hold for a contributing assembly is\n// that assembly's own annotation, and on a pangenome config that is one track\n// per strain (`CFT073_genes`), which is exactly what makes the landing readable.\n//\n// Annotation tracks only, not everything configured for the assembly. A launch\n// is a jump to a locus, and an alignments or coverage track turned on behind the\n// user's back fetches data nobody asked for; a FeatureTrack at a 50 kb window is\n// a tabix range query.\n//\n// `first` is the graph's own track when the launch is on the reference, so the\n// segments the graph drew sit at the top of the view rather than wherever config\n// order puts them.\nexport function launchTracks({\n session,\n assemblyName,\n first,\n}: {\n session: TrackScanSession\n assemblyName: string\n first?: string\n}) {\n const wanted = canonicalAssemblyName(session, assemblyName)\n const found: string[] = []\n for (const track of session.tracks) {\n const trackId: unknown = readConfObject(track, 'trackId')\n if (\n readConfObject(track, 'type') === ANNOTATION_TRACK_TYPE &&\n typeof trackId === 'string' &&\n trackId !== first &&\n trackAssemblies(session, track).includes(wanted)\n ) {\n found.push(trackId)\n }\n }\n return first ? [first, ...found] : found\n}\n", "\"use client\";\n\nimport createSvgIcon from \"./utils/createSvgIcon.mjs\";\nimport { jsx as _jsx } from \"react/jsx-runtime\";\nexport default createSvgIcon(/*#__PURE__*/_jsx(\"path\", {\n d: \"M9.19 6.35c-2.04 2.29-3.44 5.58-3.57 5.89L2 10.69l4.05-4.05c.47-.47 1.15-.68 1.81-.55zM11.17 17s3.74-1.55 5.89-3.7c5.4-5.4 4.5-9.62 4.21-10.57-.95-.3-5.17-1.19-10.57 4.21C8.55 9.09 7 12.83 7 12.83zm6.48-2.19c-2.29 2.04-5.58 3.44-5.89 3.57L13.31 22l4.05-4.05c.47-.47.68-1.15.55-1.81zM9 18c0 .83-.34 1.58-.88 2.12C6.94 21.3 2 22 2 22s.7-4.94 1.88-6.12C4.42 15.34 5.17 15 6 15c1.66 0 3 1.34 3 3m4-9c0-1.1.9-2 2-2s2 .9 2 2-.9 2-2 2-2-.9-2-2\"\n}), 'RocketLaunch');", "import { LAUNCH_LABEL, pushLaunchViewMenuItem } from '@jbrowse/core/ui'\nimport RocketLaunchIcon from '@mui/icons-material/RocketLaunch'\n\nimport type { MenuItem, SubMenuItem } from '@jbrowse/core/ui'\n\nexport function pushLaunchItem(items: MenuItem[], item: MenuItem) {\n pushLaunchViewMenuItem(items, item)\n const group = items.find(\n (i): i is SubMenuItem => 'subMenu' in i && i.label === LAUNCH_LABEL,\n )\n if (group && !group.icon) {\n group.icon = RocketLaunchIcon\n }\n}\n", "import { readConfObject } from '@jbrowse/core/configuration'\nimport { getTrackName } from '@jbrowse/core/util/tracks'\nimport { getEnv, isStateTreeNode } from '@jbrowse/mobx-state-tree'\n\nimport { trackAssemblies } from './launchFromGraph'\n\nimport type { TrackScanSession } from './launchFromGraph'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\n\nexport interface LaunchableSyntenyTrack {\n trackId: string\n name: string\n // how many of the requested assemblies this track covers, so a whole-set\n // all-vs-all sorts above a pairwise alignment covering two of them\n coverage: number\n}\n\nconst SYNTENY_TRACK_TYPE = 'SyntenyTrack'\nconst SYNTENY_ADAPTER_CATEGORY = 'Synteny adapters'\n\n// A SyntenyTrack, or any track reading a synteny adapter (a GraphTrack over a\n// gbz-base database). Core's isSyntenyTrack makes the same test on newer hosts.\nfunction isSyntenyTrack(track: AnyConfigurationModel) {\n if (readConfObject(track, 'type') === SYNTENY_TRACK_TYPE) {\n return true\n }\n const adapterType: unknown = track.adapter?.type\n if (typeof adapterType !== 'string' || !isStateTreeNode(track)) {\n return false\n }\n const { pluginManager } = getEnv<{ pluginManager?: PluginManager }>(track)\n return (\n !!pluginManager?.hasAdapterType(adapterType) &&\n pluginManager.getAdapterType(adapterType).adapterMetadata?.category ===\n SYNTENY_ADAPTER_CATEGORY\n )\n}\n\n// Synteny datasets in the session that align at least two of `assemblyNames`.\n//\n// Two is the floor because that is the floor for a synteny view; more is better,\n// and an all-vs-all covering every contributing assembly is what makes the\n// multi-panel launch worth offering at all.\nexport function launchableSyntenyTracks(\n session: TrackScanSession,\n assemblyNames: string[],\n) {\n const wanted = new Set(assemblyNames)\n const found: LaunchableSyntenyTrack[] = []\n for (const track of session.tracks) {\n const trackId: unknown = readConfObject(track, 'trackId')\n if (isSyntenyTrack(track) && typeof trackId === 'string') {\n const coverage = trackAssemblies(session, track).filter(name =>\n wanted.has(name),\n ).length\n if (coverage >= 2) {\n found.push({ trackId, name: getTrackName(track, session), coverage })\n }\n }\n }\n return found.sort((a, b) => b.coverage - a.coverage)\n}\n", "// Hands `text` to the browser as a file to save\nexport function downloadText(\n text: string,\n name: string,\n type = 'image/svg+xml',\n) {\n const url = URL.createObjectURL(new Blob([text], { type }))\n const a = document.createElement('a')\n a.href = url\n a.download = name\n a.click()\n setTimeout(() => {\n URL.revokeObjectURL(url)\n }, 0)\n}\n", "import { COLOR_SCHEMES } from '@jbrowse/bandage-core/colorSchemes'\nimport { FACET_FIELDS } from '@jbrowse/bandage-core/facetGrid'\nimport {\n LAYOUT_MODES,\n layoutModeByValue,\n} from '@jbrowse/bandage-core/layoutModes'\nimport { getSession } from '@jbrowse/core/util'\nimport ContentCopyIcon from '@mui/icons-material/ContentCopy'\nimport HubIcon from '@mui/icons-material/Hub'\nimport PaletteIcon from '@mui/icons-material/Palette'\nimport PhotoCameraIcon from '@mui/icons-material/PhotoCamera'\nimport VisibilityIcon from '@mui/icons-material/Visibility'\n\nimport {\n ChooseSamplesDialog,\n ChooseWalksDialog,\n HighlightColorDialog,\n TUBE_MAP_FOLDS,\n TUBE_MAP_MODES,\n TUBE_MAP_ROUTES,\n WALK_MENU_ITEMS,\n} from './paneBase'\nimport { withRenderingActions } from './renderingActions'\nimport { graphLaunchMenuItems } from '../../launchFromGraph/graphMenuItems'\nimport {\n highlightInLinearView,\n launchSyntenyView,\n showInLinearView,\n} from '../../launchFromGraph/launchFromGraph'\nimport { launchTracks } from '../../launchFromGraph/launchTracks'\nimport { pushLaunchItem } from '../../launchFromGraph/pushLaunchItem'\nimport { launchableSyntenyTracks } from '../../launchFromGraph/syntenyTracks'\nimport { downloadText } from '../download'\nimport { HOVER_HIGHLIGHT_VALUES } from '../hoverHighlight'\nimport { TUBE_MAP_PANELS, tubeMapPanelGroups } from '../tubeMapPanels'\n\nimport type { GraphLocation } from '../../launchFromGraph/contributors'\nimport type { GraphLayer } from '../graphLayers'\nimport type { TubeMapPanelSplit } from '../tubeMapPanels'\nimport type { ColorScheme } from '@jbrowse/bandage-core/colorSchemes'\nimport type { LayoutEngineKind } from '@jbrowse/bandage-core/layoutEngines'\nimport type { MenuItem } from '@jbrowse/core/ui'\n\nconst ENGINE_NAMES: readonly (readonly [LayoutEngineKind, string])[] = [\n ['fmmm', 'FMMM'],\n ['stress', 'stress'],\n]\n\nconst layoutMenuLabel = (mode: { label: string }) =>\n mode.label.replace(/ layout$/, '')\n\nfunction radioItems<T>(\n options: readonly { value: T; label: string; disabled?: boolean }[],\n current: T | undefined,\n onPick: (value: T) => void,\n): MenuItem[] {\n return options.map(({ value, label, disabled }) => ({\n type: 'radio',\n label,\n disabled,\n checked: value === current,\n onClick: () => {\n onPick(value)\n },\n }))\n}\n\nexport const withLaunchActions = withRenderingActions\n .actions(self => ({\n // Move the linear view already on screen, or open one if there is none,\n // and pair with whichever it was. A view being created gets the session's\n // annotation for the assembly it opens on (see launchTracks), led by the\n // graph's own segments track when the launch is on the reference \u2014 the one\n // assembly that track is configured for.\n //\n // Only a view on the reference is paired with. A node's hover band is on\n // that assembly, so paired with a view on another the band fails that\n // view's assembly check and the reference view's id check, and is drawn\n // nowhere.\n showInLinearView(target: { location: GraphLocation; assembly: string }) {\n const session = getSession(self)\n const onReference = target.assembly === self.graphRegion?.assemblyName\n const viewId = showInLinearView({\n session,\n location: target.location,\n assembly: target.assembly,\n connectedViewId: self.pairedViewId,\n tracks: launchTracks({\n session,\n assemblyName: target.assembly,\n first: onReference ? self.sourceTrackId : undefined,\n }),\n })\n if (onReference) {\n self.pairWithLinearView(viewId)\n }\n },\n // Mark the node's reference interval in the linear view beside the graph.\n // Not an action that opens anything: with no view to mark, the menu does\n // not offer it (see nodeLaunchMenuItems).\n highlightInLinearView(target: {\n location: GraphLocation\n assembly: string\n }) {\n highlightInLinearView({\n session: getSession(self),\n location: target.location,\n assembly: target.assembly,\n connectedViewId: self.pairedViewId,\n })\n },\n showSyntenyView(trackId: string) {\n launchSyntenyView({\n session: getSession(self),\n contributors: self.launchableAssemblies,\n trackId,\n graphTrackId: self.sourceTrackId,\n })\n },\n }))\n .views(self => ({\n // Synteny datasets that could fill the panels of a multi-genome launch.\n // Below two openable contributors there is nothing to compare, so the scan\n // is skipped rather than run and discarded.\n get syntenyLaunchTracks() {\n const samples = self.launchableAssemblies.map(c => c.sample)\n return samples.length >= 2\n ? launchableSyntenyTracks(getSession(self), samples)\n : []\n },\n }))\n .views(self => ({\n // Which samples' walks walk rows show: every one, those whose walk and\n // the picked repeat's call disagree, or a set picked by name\n walkRowSampleMenuItems(): MenuItem[] {\n const { disagreeing } = self.walkRowSampleChoices\n const shown = self.walkRowSamples\n const same = (a: string[]) => a.join('\\n') === shown?.join('\\n')\n return [\n {\n type: 'radio',\n label: 'Every sample',\n checked: shown === undefined,\n onClick: () => {\n self.setWalkRowSamples(undefined)\n },\n },\n ...(disagreeing.length > 0\n ? [\n {\n type: 'radio' as const,\n label: 'Where walk and call disagree',\n checked: same(disagreeing),\n onClick: () => {\n self.setWalkRowSamples(disagreeing)\n },\n },\n ]\n : []),\n {\n type: 'radio',\n label: 'Choose samples...',\n checked: shown !== undefined && !same(disagreeing),\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseSamplesDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n },\n // Which sample table column walk rows stack into sections by\n walkRowGroupMenuItems(): MenuItem[] {\n const field = self.walkRowGroups ? self.walkRowGroupBy?.field : undefined\n return radioItems(\n [\n { value: undefined, label: 'None' },\n ...self.walkRowGroupFields.map(c => ({ value: c, label: c })),\n ],\n field,\n c => {\n self.setWalkRowGroupBy(c === undefined ? undefined : { field: c })\n },\n )\n },\n // A tube map's panels: none, a sample's or a walk's each, or a group of\n // samples' each by a column of the source track's sample table\n tubeMapPanelMenuItems(): MenuItem[] {\n const { graph, walkRowSampleTable: table } = self\n const { field } = self.facetSetting\n const column = field === '' ? self.walkRowGroupBy?.field : undefined\n const splits = (split: TubeMapPanelSplit) =>\n !!graph && tubeMapPanelGroups(graph, split).length > 1\n return [\n ...radioItems(\n TUBE_MAP_PANELS.map(item => ({\n value: item.field,\n label: item.label,\n disabled: item.field !== '' && !splits({ by: item.field }),\n })),\n column ? undefined : field,\n by => {\n self.setFacet(by)\n if (by === '') {\n self.setWalkRowGroupBy(undefined)\n }\n },\n ),\n ...radioItems(\n self.walkRowGroupFields.map(c => ({\n value: c,\n label: `By ${c}`,\n disabled: !table || !splits({ by: 'column', field: c, table }),\n })),\n column,\n c => {\n self.setFacet('')\n self.setWalkRowGroupBy({ field: c })\n },\n ),\n ]\n },\n // `repeat` false where a toolbar already picks the repeat\n layoutOptionMenuItems({ repeat = true } = {}): MenuItem[] {\n return [\n ...(TUBE_MAP_MODES.has(self.chosenLayoutMode)\n ? [\n {\n label: 'Fold variants',\n // reads are placed by the cut's names, which a fold renames\n subMenu: radioItems(\n TUBE_MAP_FOLDS.map(({ bp, label }) => ({\n value: bp,\n label,\n disabled: bp > 0 && self.graph?.reads !== undefined,\n })),\n self.graph?.reads ? 0 : self.tubeMapFold,\n self.setTubeMapFold,\n ),\n },\n {\n label: 'Panels',\n subMenu: this.tubeMapPanelMenuItems(),\n },\n {\n label: 'Routes',\n subMenu: radioItems(\n TUBE_MAP_ROUTES,\n self.tubeMapRoutes,\n self.setTubeMapRoutes,\n ),\n },\n ...(self.walkRowGroupFields.length > 0\n ? [\n {\n label: 'Tube color',\n subMenu: radioItems(\n ['', ...self.walkRowGroupFields].map(field => ({\n value: field,\n label: field ? `By ${field}` : 'By role',\n })),\n self.tubeMapColorBy,\n self.setTubeMapColorBy,\n ),\n },\n ]\n : []),\n ]\n : []),\n ...(repeat &&\n self.chosenLayoutMode === 'walkrows' &&\n self.repeatChoices.length > 0\n ? [\n {\n label: 'Repeat',\n subMenu: radioItems(\n self.repeatOptions,\n self.selectedRepeat?.key ?? '',\n self.setRepeatKey,\n ),\n },\n ]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' && self.walkRowBars\n ? [{ label: 'Samples', subMenu: this.walkRowSampleMenuItems() }]\n : []),\n ...(self.chosenLayoutMode === 'walkrows' &&\n self.walkRowBars &&\n self.walkRowGroupFields.length > 0\n ? [{ label: 'Group by...', subMenu: this.walkRowGroupMenuItems() }]\n : []),\n ]\n },\n showMenuItems(): MenuItem[] {\n const layerItem = (label: string, layer: GraphLayer) => ({\n type: 'checkbox' as const,\n label,\n checked: self.layerSet.has(layer),\n onClick: () => {\n self.setLayer(layer, !self.layerSet.has(layer))\n },\n })\n return [\n layerItem('Show bubble halos', 'bubbles'),\n layerItem('Show deletion edges', 'deletions'),\n {\n label: 'Hover highlight',\n subMenu: radioItems(\n HOVER_HIGHLIGHT_VALUES.map(value => ({\n value,\n label: value[0]!.toUpperCase() + value.slice(1),\n })),\n self.chosenHover,\n self.setHover,\n ),\n },\n layerItem('Show genes on the backbone', 'genes'),\n ...(self.referenceStripApplies\n ? [layerItem('Show reference strip', 'referenceStrip')]\n : []),\n ]\n },\n exportMenuItems(): MenuItem[] {\n return [\n {\n label: 'Export SVG',\n icon: PhotoCameraIcon,\n disabled: self.figureUnavailable !== undefined,\n disabledHelpText: self.figureUnavailable,\n onClick: () => {\n const svg = self.figure()\n if (svg) {\n downloadText(\n svg,\n `${(self.graph?.name ?? 'graph').replaceAll(/[^\\w.-]+/g, '_')}.svg`,\n )\n }\n },\n },\n {\n label: 'Copy figure spec',\n icon: ContentCopyIcon,\n disabled: self.figureSpecUnavailable !== undefined,\n disabledHelpText: self.figureSpecUnavailable,\n onClick: () => {\n const spec = self.figureSpec()\n const session = getSession(self)\n navigator.clipboard\n .writeText(`${JSON.stringify(spec, null, 2)}\\n`)\n .then(() => {\n session.notify(\n 'Figure spec copied. Save it as spec.json and run: npx -p @jbrowse/bandage-core bandage-figure spec.json -o figure.svg',\n 'info',\n )\n })\n .catch((e: unknown) => {\n session.notify(`Could not copy the figure spec: ${String(e)}`)\n })\n },\n },\n ]\n },\n // `picks` false where a toolbar already picks the walks, leaving what is\n // done with those picked\n highlightMenuItems({ picks = true } = {}): MenuItem[] {\n const walks = picks ? self.walkChoices : []\n if (\n self.walkChoices.length === 0 ||\n !self.liftsWalks ||\n (!picks && self.walkLayers.length === 0)\n ) {\n return []\n }\n const lifted = (name: string) =>\n self.walkLayers.some(l => l.walk === name)\n const many = walks.length > WALK_MENU_ITEMS\n return [\n { type: 'subHeader', label: 'Highlight' },\n ...(many\n ? [\n {\n label: 'Choose haplotypes...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n ChooseWalksDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(many ? walks.filter(walk => lifted(walk.name)) : walks).map(\n walk => ({\n type: 'checkbox' as const,\n label: walk.label,\n checked: lifted(walk.name),\n onClick: () => {\n self.toggleWalk(walk.name)\n },\n }),\n ),\n {\n label: 'Clear highlights',\n disabled: self.walkLayers.length === 0,\n onClick: () => {\n self.setWalkLayers([])\n },\n },\n ...(self.drawnWalks.length > 0\n ? [\n {\n label: 'Color highlighted...',\n onClick: () => {\n getSession(self).queueDialog(onClose => [\n HighlightColorDialog,\n { model: self, onClose },\n ])\n },\n },\n ]\n : []),\n ...(self.walkLayers.length > 1 && self.modeDrawsNodes\n ? [\n { type: 'subHeader' as const, label: 'Arrange' },\n ...radioItems(\n FACET_FIELDS.map(({ value, label }) => ({\n value,\n label: value === 'walk' ? 'A panel per haplotype' : label,\n })),\n self.facetSetting.field,\n self.setFacet,\n ),\n ]\n : []),\n ]\n },\n colorSchemeLabel(value: ColorScheme): string {\n const label = COLOR_SCHEMES.find(s => s.value === value)?.label ?? value\n return value === 'auto'\n ? `${label} (${this.colorSchemeLabel(self.effectiveColorScheme)})`\n : label\n },\n graphMenuItems(): MenuItem[] {\n const options = this.layoutOptionMenuItems()\n const mode = layoutModeByValue(self.chosenLayoutMode)\n const engine = ENGINE_NAMES.find(([e]) => e === self.layoutEngine)![1]\n return [\n {\n label: `Layout: ${layoutMenuLabel(mode)}${mode.value === 'force' ? ` (${engine})` : ''}`,\n icon: HubIcon,\n subMenu: [\n ...LAYOUT_MODES.flatMap(mode => {\n const item = {\n type: 'radio' as const,\n disabled: self.graph ? !mode.available(self.graph) : false,\n disabledHelpText: mode.description,\n }\n return mode.value === 'force'\n ? ENGINE_NAMES.map(([engine, name]) => ({\n ...item,\n label: `${layoutMenuLabel(mode)} (${name})`,\n checked:\n self.chosenLayoutMode === mode.value &&\n self.layoutEngine === engine,\n onClick: () => {\n void self.switchForceEngine(engine)\n },\n }))\n : [\n {\n ...item,\n label: layoutMenuLabel(mode),\n checked: self.chosenLayoutMode === mode.value,\n onClick: () => {\n void self.switchLayout(mode.value)\n },\n },\n ]\n }),\n ...(options.length > 0\n ? [{ type: 'divider' as const }, ...options]\n : []),\n ...(self.hostPlacesX\n ? []\n : [\n { type: 'divider' as const },\n {\n label: 'Zoom to fit',\n onClick: () => {\n self.refitView()\n },\n },\n ]),\n ],\n },\n {\n label: `Color: ${self.colorSchemeLock?.value ?? this.colorSchemeLabel(self.chosenColorScheme)}`,\n icon: PaletteIcon,\n disabled: self.colorSchemeLock !== undefined,\n disabledHelpText: self.colorSchemeLock?.why,\n subMenu: radioItems(\n COLOR_SCHEMES.map(({ value }) => ({\n value,\n label: this.colorSchemeLabel(value),\n })),\n self.chosenColorScheme,\n self.setColorScheme,\n ),\n },\n {\n label: 'Show...',\n icon: VisibilityIcon,\n subMenu: this.showMenuItems(),\n },\n ]\n },\n // the graph's way out, in the \"Launch view\" submenu every view shares\n launchMenuItems(): MenuItem[] {\n const items: MenuItem[] = []\n const contributors = self.launchableAssemblies\n const reference = self.graphRegion?.assemblyName\n for (const item of graphLaunchMenuItems({\n contributors,\n linearContributors: self.host\n ? contributors.filter(c => c.sample !== reference)\n : contributors,\n syntenyTracks: self.syntenyLaunchTracks,\n onShowLinear: target => {\n self.showInLinearView(target)\n },\n onShowSynteny: trackId => {\n self.showSyntenyView(trackId)\n },\n })) {\n pushLaunchItem(items, item)\n }\n return items\n },\n }))\n", "import { cutsWholeWalks as wholeWalksRule } from '@jbrowse/bandage-core/layout/walkStrip'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport { getSession } from '@jbrowse/core/util'\n\nimport {\n configHaplotypes,\n graphReferenceAssembly,\n offReferenceProblem,\n} from '../graphTrackConfig'\nimport { canonicalAssemblyName } from '../launchFromGraph/launchFromGraph'\nimport { withLaunchActions } from './pane/launchActions'\n\nimport type { SubgraphCutOptions, SubgraphRegion } from '../GetSubgraph'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\nexport { MAX_GRAPH_REGION_BP, fileName, formatSpanBp } from './pane/paneBase'\n\n// The pane every graph drawing is: a view of its own, or a display inside a\n// linear view. Built in stages under pane/, each extending the one before,\n// and given here the cut options both hosts share.\nexport const GraphPane = withLaunchActions\n .views(self => ({\n // the config's defaultHaplotypes, which a cut is for until the user\n // picks others\n get trackHaplotypes(): string[] | undefined {\n const adapter = self.sourceAdapter\n return adapter && configHaplotypes(adapter)\n },\n }))\n .views(self => ({\n get cutHaplotypes() {\n return self.subgraphHaplotypes ?? self.trackHaplotypes\n },\n // Why the source track cannot cut `region`, which is a window on an\n // assembly other than the graph's reference. A track may name its\n // reference by an alias of the assembly the window is on.\n offReference(region: SubgraphRegion) {\n const track = self.sourceTrack\n const reference = track && graphReferenceAssembly(track)\n const session = getSession(self)\n return reference === undefined\n ? undefined\n : offReferenceProblem(\n canonicalAssemblyName(session, reference),\n canonicalAssemblyName(session, region.assemblyName),\n )\n },\n // Walk rows, and the strip of them under a node layout, measure whole\n // walks, which a GBZ cut only follows when asked, so a layout change\n // that changes whether the drawing needs them cuts the track again.\n cutChangedFrom(from: LayoutModeValue) {\n const before = wholeWalksRule(layoutModeByValue(from), {\n walkStrip: self.walkStrip,\n host: !!self.host,\n })\n return (\n self.cutsWholeWalks !== before ||\n (from === 'walkrows') !== (self.chosenLayoutMode === 'walkrows')\n )\n },\n }))\n .views(self => ({\n get cutOptions(): SubgraphCutOptions {\n return {\n hops: self.subgraphContext,\n haplotypes: self.cutHaplotypes,\n ...(self.chosenLayoutMode === 'walkrows' ? { walkRows: true } : {}),\n ...(self.cutsWholeWalks ? { snarls: 'overlapping' as const } : {}),\n }\n },\n }))\n\nexport type GraphPaneModel = Instance<typeof GraphPane>\n", "import {\n LAYOUT_MODE_VALUES,\n layoutModeByValue,\n} from '@jbrowse/bandage-core/layoutModes'\nimport { BaseViewModel } from '@jbrowse/core/pluggableElementTypes/models'\nimport { getSession } from '@jbrowse/core/util'\nimport { addDisposer, isAlive, types } from '@jbrowse/mobx-state-tree'\nimport { reaction } from 'mobx'\n\nimport { HOVER_HIGHLIGHT_VALUES } from './hoverHighlight'\nimport { lenientMaybeEnum } from './lenientEnum'\nimport { GraphPane, fileName, formatSpanBp } from './model'\nimport { canonicalRegion } from '../launchFromGraph/launchFromGraph'\n\nimport type { GraphLayers } from './graphLayers'\nimport type { NodeColor } from './nodeColor'\nimport type { NodeSize } from './nodeSize'\nimport type { SubgraphRegion } from '../GetSubgraph'\nimport type { GraphGrammar, GraphRows } from './pane/graphViews'\nimport type { FacetInput } from '@jbrowse/bandage-core/facetGrid'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { AnyConfigurationModel } from '@jbrowse/core/configuration'\nimport type { FileLocation } from '@jbrowse/core/util/types'\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\nexport default function stateModelFactory() {\n return types\n .compose(\n 'GraphGenomeView',\n BaseViewModel,\n GraphPane,\n types.model({\n type: types.literal('GraphGenomeView'),\n // a whole GFA the view loads on attach, kept so the source round-trips\n // through a session snapshot\n gfaLocation: types.maybe(types.frozen<FileLocation>()),\n // the reference window the file or the cut was stated beside\n loadedRegion: types.maybe(types.frozen<SubgraphRegion>()),\n // A session track the view cuts `loadedRegion` from once, as 4.0\n // sessions and the docs' figure specs state it. Following the linear\n // view is the track's job (LinearGraphDisplay).\n loadedTrackId: types.optional(types.string, ''),\n // unset is force\n layoutMode: lenientMaybeEnum(LAYOUT_MODE_VALUES),\n color: types.maybe(types.frozen<NodeColor>()),\n size: types.maybe(types.frozen<NodeSize>()),\n layers: types.maybe(types.frozen<GraphLayers>()),\n facet: types.maybe(types.frozen<FacetInput>()),\n rows: types.maybe(types.frozen<GraphRows>()),\n // unset is nodes\n hover: lenientMaybeEnum(HOVER_HIGHLIGHT_VALUES),\n }),\n )\n .views(self => ({\n get grammar(): GraphGrammar {\n return {\n layoutMode: self.layoutMode,\n color: self.color,\n size: self.size,\n layers: self.layers,\n facet: self.facet,\n rows: self.rows,\n hover: self.hover,\n }\n },\n }))\n .actions(self => ({\n writeGrammar(settings: GraphGrammar) {\n Object.assign(self, settings)\n },\n }))\n .volatile(() => ({\n widthMeasured: false,\n }))\n .actions(self => {\n const setBaseWidth = self.setWidth\n return {\n setWidth(width: number) {\n setBaseWidth(width)\n self.widthMeasured = true\n },\n }\n })\n .views(self => ({\n get rpcSessionId() {\n return self.id\n },\n // a view is not its own containing view\n get paneWidth() {\n return self.width\n },\n // until then the width is BaseViewModel's 800 px default\n get paneMeasured() {\n return self.widthMeasured\n },\n get sourceGfaLocation() {\n return self.gfaLocation\n },\n get sourceTrack(): AnyConfigurationModel | undefined {\n return self.loadedTrackId\n ? self.sessionTrack(self.loadedTrackId)\n : undefined\n },\n get canRetryLoad() {\n return (\n self.gfaLocation !== undefined ||\n (self.loadedTrackId !== '' && self.loadedRegion !== undefined)\n )\n },\n }))\n .views(self => ({\n get hasPendingSource() {\n return self.canRetryLoad && !self.graph && !self.loadCanceled\n },\n menuItems() {\n return [...self.exportMenuItems(), ...self.launchMenuItems()]\n },\n }))\n .actions(self => {\n const clearPane = self.clearGraph\n function loadRegion(region: SubgraphRegion | undefined) {\n if (self.gfaLocation) {\n // a whole file has no assembly to name the view by\n if (!self.displayName) {\n self.setDisplayName(fileName(self.gfaLocation))\n }\n return self.loadGFAFromLocation(self.gfaLocation, region)\n }\n if (!self.loadedTrackId || !region) {\n return undefined\n }\n const adapter = self.sourceAdapter\n const span = region.end - region.start\n const problem = self.offReference(region)\n if (!adapter) {\n self.setError(\n new Error(\n `The track this graph was cut from, \"${self.loadedTrackId}\", is not in this session`,\n ),\n )\n } else if (problem) {\n self.setError(new Error(problem))\n } else if (span > self.maxRegionBp) {\n self.setError(\n new Error(\n `Region too large (${formatSpanBp(span)}) \u2014 zoom in to view graph (max ${formatSpanBp(self.maxRegionBp)})`,\n ),\n )\n } else {\n return self.cutSubgraph(adapter, region, self.cutOptions)\n }\n return undefined\n }\n return {\n // the stated source goes too, or a reloaded session would load the\n // dismissed graph again, and so does a name taken from its file\n clearGraph() {\n clearPane()\n if (\n self.gfaLocation &&\n self.displayName === fileName(self.gfaLocation)\n ) {\n self.displayName = undefined\n }\n self.gfaLocation = undefined\n self.loadedRegion = undefined\n self.loadedTrackId = ''\n },\n // The graph keeps the region by the session's names, which hover sync\n // and launches compare with, so a stated alias resolves first, once\n // its assembly's refName aliases have loaded.\n load(): Promise<void> | undefined {\n const stated = self.loadedRegion\n const session = getSession(self)\n const { assemblyManager } = session\n const assembly =\n stated && assemblyManager.has(stated.assemblyName)\n ? assemblyManager.get(stated.assemblyName)\n : undefined\n return stated && assembly?.initialized === false\n ? assemblyManager\n .waitForAssembly(stated.assemblyName)\n .catch(() => undefined)\n .then(() =>\n self.loadedRegion === stated\n ? loadRegion(canonicalRegion(session, stated))\n : undefined,\n )\n : loadRegion(stated && canonicalRegion(session, stated))\n },\n }\n })\n .actions(self => ({\n retryLoad() {\n void self.load()\n },\n setGfaLocation(location: FileLocation) {\n self.gfaLocation = location\n },\n // the strip's toggle cuts the track again too (afterAttach)\n relayoutFrom(from: LayoutModeValue) {\n return self.loadedTrackId && self.cutChangedFrom(from)\n ? self.load()\n : self.recomputeLayout()\n },\n // Stated as the source once it loads, so a saved session reopens it; a\n // URL that fails stays in the import form to be corrected.\n async openGfaLocation(location: FileLocation) {\n await self.loadGFAFromLocation(location)\n if (isAlive(self) && self.hasGraph) {\n this.setGfaLocation(location)\n if (!self.displayName) {\n self.setDisplayName(fileName(location))\n }\n }\n },\n // Here rather than when the rendering backend starts: the canvas only\n // mounts once there is a graph, so a view whose graph must be fetched\n // would never fetch it.\n afterAttach() {\n if (!self.graph) {\n void self.load()\n }\n addDisposer(\n self,\n reaction(\n () => self.walkStrip,\n () => {\n if (\n self.loadedTrackId &&\n !layoutModeByValue(self.chosenLayoutMode).wholeWalks\n ) {\n void self.load()\n }\n },\n ),\n )\n },\n }))\n}\n\nexport type GraphGenomeViewModel = Instance<\n ReturnType<typeof stateModelFactory>\n>\n", "import { lazy } from 'react'\n\nimport ViewType from '@jbrowse/core/pluggableElementTypes/ViewType'\nimport { defineLaunchKeys } from '@jbrowse/core/util/withLaunchInput'\n\nimport modelFactory from './viewModel'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// No launch keys, declared so `loadSessionSpec` reports a spec's unknown keys\n// instead of dropping them silently.\nconst graphLaunchKeys = defineLaunchKeys<object>()({})\n\nexport default function GraphGenomeViewF(pluginManager: PluginManager) {\n pluginManager.addViewType(() => {\n return new ViewType({\n name: 'GraphGenomeView',\n displayName: 'Graph genome view',\n stateModel: modelFactory(),\n launchKeys: graphLaunchKeys,\n ReactComponent: lazy(() => import('./components/GraphGenomeView')),\n })\n })\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport {\n TrackType,\n createBaseTrackConfig,\n createBaseTrackModel,\n} from '@jbrowse/core/pluggableElementTypes'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\n\n// core's synteny displays, copied to ask for headerLanes so only the gbz-base\n// and walk-tabix adapters open in a synteny, dotplot or circular view\nexport const SYNTENY_DISPLAYS = [\n 'MultiWaySyntenyDisplay',\n 'LinearSyntenyDisplay',\n 'DotplotDisplay',\n 'ChordSyntenyDisplay',\n]\n\nfunction displaysInOrder(pluginManager: PluginManager): DisplayType[] {\n const displays = pluginManager.getElementTypesInGroup(\n 'display',\n ) as DisplayType[]\n const named = (name: string) => displays.find(d => d.name === name)\n const needsLanes = (display: DisplayType | undefined) =>\n display &&\n Object.assign(Object.create(display) as DisplayType, {\n adapterCapabilities: ['headerLanes'],\n })\n return [\n named('LinearGraphDisplay'),\n named('LinearBasicDisplay'),\n ...SYNTENY_DISPLAYS.map(name => needsLanes(named(name))),\n ].filter((d): d is DisplayType => d !== undefined)\n}\n\nexport default function GraphTrackF(pluginManager: PluginManager) {\n pluginManager.addTrackType(() => {\n const configSchema = ConfigurationSchema(\n 'GraphTrack',\n {},\n {\n baseConfiguration: createBaseTrackConfig(pluginManager),\n explicitIdentifier: 'trackId',\n },\n )\n const track = new TrackType({\n name: 'GraphTrack',\n displayName: 'Pangenome graph track',\n configSchema,\n stateModel: createBaseTrackModel(\n pluginManager,\n 'GraphTrack',\n configSchema,\n ),\n })\n for (const display of displaysInOrder(pluginManager)) {\n track.addDisplayType(display)\n }\n return track\n })\n}\n", "import type modelFactory from './GraphGenomeView/viewModel'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\nimport type { SnapshotIn } from '@jbrowse/mobx-state-tree'\n\n// Every view prop, taken off the model so a new prop widens the launch with\n// it; `type` is the dispatch key, not a setting.\nexport type LaunchGraphGenomeViewArgs = Partial<\n Omit<SnapshotIn<ReturnType<typeof modelFactory>>, 'type'>\n> & {\n session: AbstractSessionModel\n}\n\ndeclare module '@jbrowse/core/PluginManager' {\n interface ExtensionPointRegistry {\n 'LaunchView-GraphGenomeView': {\n args: LaunchGraphGenomeViewArgs\n result: LaunchGraphGenomeViewArgs\n }\n }\n}\n\nexport default function LaunchGraphGenomeViewF(pluginManager: PluginManager) {\n /** #extensionPoint LaunchView-GraphGenomeView | async | Programmatically launch a graph genome view */\n pluginManager.addToExtensionPoint('LaunchView-GraphGenomeView', args => {\n const { session, ...spec } = args\n session.addView('GraphGenomeView', spec)\n return args\n })\n}\n", "const host = JBrowseExports[\"@jbrowse/core/pluggableElementTypes/DisplayType\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/pluggableElementTypes/DisplayType\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/display-kit/trackHeightConfigSchemaFields\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/display-kit/trackHeightConfigSchemaFields\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const trackHeightConfigSchemaFields = /* @__PURE__ */ read(\"trackHeightConfigSchemaFields\")\nexport default host && host.__esModule ? host.default : host", "import { LAYOUT_MODE_VALUES } from '@jbrowse/bandage-core/layoutModes'\nimport { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { trackHeightConfigSchemaFields } from '@jbrowse/display-kit/trackHeightConfigSchemaFields'\nimport { types } from '@jbrowse/mobx-state-tree'\n\nimport { HOVER_HIGHLIGHT_VALUES } from '../GraphGenomeView/hoverHighlight'\n\n/**\n * #config LinearGraphDisplay\n * The graph drawn as a track of the linear genome view. A layout whose x is\n * reference bp draws under the view's coordinates and re-cuts as the view\n * moves; force, ordered and walk rows draw in their own coordinates, fitted to\n * the track.\n */\nexport function configSchemaFactory() {\n return ConfigurationSchema(\n 'LinearGraphDisplay',\n {\n /**\n * #slot\n * the layout the track opens in\n */\n layoutMode: {\n type: 'stringEnum',\n model: types.enumeration('LayoutMode', LAYOUT_MODE_VALUES),\n defaultValue: 'auto',\n },\n /**\n * #slot\n * the node color: `grey` or `uniform`, or the field nodes are colored\n * by, `depth`, `length`, `rank`, `position` or `id` (`scale:\n * 'categorical'` or `scheme: 'rainbow'`). `domainMin`/`domainMax` span\n * the position ramp. `{}` colors an anchored graph by position.\n * ```js\n * { color: { field: 'depth' } }\n * ```\n */\n color: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * the node thickness: a px number draws every node that thick;\n * `{ field: 'depth', value }` thickens a node the more paths carry it,\n * around `value` px\n */\n size: {\n type: 'frozen',\n defaultValue: { field: 'depth', value: 6 },\n },\n /**\n * #slot\n * what the drawing adds over its nodes and edges, stated as changes to\n * the defaults: `paths`, `bubbles` and `walkStrip` are off, `deletions`,\n * `genes` and `referenceStrip` on\n * ```js\n * { layers: { bubbles: true, genes: false } }\n * ```\n */\n layers: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * one section per value of a field: a node layout draws a panel per\n * `walk` or `sample`, and walk rows stack into a section per value of\n * a sample table column. A bare field, or `{ field, domain, columns }`\n */\n facet: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * the rows walk rows draw: `{ kept: [...] }` names the samples shown\n */\n rows: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * what the pointer lights: `nodes` lightens a hovered node and bands its\n * span on the view; `everything` also lights edges, and the node at the\n * view's pointer bp\n */\n hover: {\n type: 'stringEnum',\n model: types.enumeration('HoverHighlight', HOVER_HIGHLIGHT_VALUES),\n defaultValue: 'nodes',\n },\n ...trackHeightConfigSchemaFields({\n defaultHeight: 300,\n height: 'the height of the track the graph is drawn in',\n }),\n },\n { explicitlyTyped: true, explicitIdentifier: 'displayId' },\n )\n}\n\nexport type LinearGraphDisplayConfigModel = ReturnType<\n typeof configSchemaFactory\n>\n", "const host = JBrowseExports[\"@jbrowse/core/svg/svgReady\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/core/svg/svgReady\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const awaitSvgReady = /* @__PURE__ */ read(\"awaitSvgReady\")\nexport const awaitSvgRenders = /* @__PURE__ */ read(\"awaitSvgRenders\")\nexport const awaitViewInitialized = /* @__PURE__ */ read(\"awaitViewInitialized\")\nexport const computeSvgReady = /* @__PURE__ */ read(\"computeSvgReady\")\nexport const throwOnExportErrors = /* @__PURE__ */ read(\"throwOnExportErrors\")\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/display-kit/TrackHeightMixin\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/display-kit/TrackHeightMixin\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/display-kit/plotMenu\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/display-kit/plotMenu\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const editPlotMenuItems = /* @__PURE__ */ read(\"editPlotMenuItems\")\nexport const openPlotDialog = /* @__PURE__ */ read(\"openPlotDialog\")\nexport default host && host.__esModule ? host.default : host", "const host = JBrowseExports[\"@jbrowse/render-core/displayPhase\"]\nconst read = name =>\n host != null && name in Object(host)\n ? host[name]\n : Object.assign(\n function () {\n throw new Error(\n \"This JBrowse does not provide '\" + name + \"' from '\" + \"@jbrowse/render-core/displayPhase\" + \"' to plugins: GraphGenomeView was built for a different JBrowse version, so update the plugin or JBrowse\",\n )\n },\n { jbrowseHostMissing: name },\n )\nexport const computeActivityPhase = /* @__PURE__ */ read(\"computeActivityPhase\")\nexport const computeDisplayPhase = /* @__PURE__ */ read(\"computeDisplayPhase\")\nexport const computeDisplayStatusPhase = /* @__PURE__ */ read(\"computeDisplayStatusPhase\")\nexport default host && host.__esModule ? host.default : host", "import type { SubgraphRegion } from '../GetSubgraph'\nimport type { HostWindow } from '../GraphGenomeView/host'\n\n// Whether `seen` is near where a cut came back over its node limit. The graph\n// is as dense as that only near it, so the refusal stands for windows as wide\n// or wider on the same contig within one window-width of it.\nexport function denseCovers(\n dense: SubgraphRegion | undefined,\n seen: HostWindow,\n) {\n if (\n dense?.refName !== seen.refName ||\n dense.assemblyName !== seen.assemblyName\n ) {\n return false\n }\n const span = dense.end - dense.start\n return (\n seen.end - seen.start >= span &&\n seen.end > dense.start - span &&\n seen.start < dense.end + span\n )\n}\n", "import { lazy } from 'react'\nimport type { ReactNode } from 'react'\n\nimport { LAYOUT_ENGINE_VALUES } from '@jbrowse/bandage-core/layoutEngines'\nimport { layoutModeByValue } from '@jbrowse/bandage-core/layoutModes'\nimport {\n ConfigurationReference,\n getConf,\n setConf,\n} from '@jbrowse/core/configuration'\nimport { BaseDisplay } from '@jbrowse/core/pluggableElementTypes'\nimport { computeSvgReady } from '@jbrowse/core/svg/svgReady'\nimport { getRpcSessionId, getSession } from '@jbrowse/core/util'\nimport TrackHeightMixin from '@jbrowse/display-kit/TrackHeightMixin'\nimport { editPlotMenuItems } from '@jbrowse/display-kit/plotMenu'\nimport { addDisposer, isAlive, types } from '@jbrowse/mobx-state-tree'\nimport {\n computeActivityPhase,\n computeDisplayStatusPhase,\n} from '@jbrowse/render-core/displayPhase'\nimport BubbleChartIcon from '@mui/icons-material/BubbleChart'\nimport RouteIcon from '@mui/icons-material/Route'\nimport SettingsIcon from '@mui/icons-material/Settings'\nimport { reaction } from 'mobx'\n\nimport { isNodeLimitError } from '../nodeLimitError'\nimport { denseCovers } from './denseWindow'\nimport { cutHolds, hostCut, hostWindow } from '../GraphGenomeView/host'\nimport { lenientOptionalEnum } from '../GraphGenomeView/lenientEnum'\nimport { GraphPane, formatSpanBp } from '../GraphGenomeView/model'\nimport { FACET_KEY_PX } from '../GraphGenomeView/pane/fitViews'\nimport { paneBase } from '../GraphGenomeView/pane/paneBase'\nimport {\n configHaplotypes,\n cutsByHaplotype,\n trackLanes,\n walkIndexed,\n} from '../graphTrackConfig'\nimport { pushLaunchItem } from '../launchFromGraph/pushLaunchItem'\n\nimport type { LinearGraphDisplayConfigModel } from './configSchema'\nimport type { SubgraphRegion, SubgraphTier } from '../GetSubgraph'\nimport type { GraphLayers } from '../GraphGenomeView/graphLayers'\nimport type { HostWindow } from '../GraphGenomeView/host'\nimport type { GraphGrammar } from '../GraphGenomeView/pane/graphViews'\nimport type { LaunchGraphGenomeViewArgs } from '../LaunchGraphGenomeView'\nimport type { LayoutModeValue } from '@jbrowse/bandage-core/layoutModes'\nimport type { MenuItem } from '@jbrowse/core/ui'\nimport type { ExportSvgDisplayOptions } from '@jbrowse/display-kit/types'\nimport type { Instance, SnapshotOut } from '@jbrowse/mobx-state-tree'\nimport type { DisplayStatusPhase } from '@jbrowse/render-core/displayPhase'\n\ntype GraphViewSpec = Omit<LaunchGraphGenomeViewArgs, 'session'>\n\n// the pane's viewport, which a new graph view fits to its drawing\nconst VIEWPORT_PROPS = new Set(['scale', 'translateX', 'translateY'])\n\ntype PaneSettings = Omit<\n SnapshotOut<typeof paneBase>,\n 'scale' | 'translateX' | 'translateY'\n>\n\nfunction paneSettings(pane: Instance<typeof paneBase>) {\n return Object.fromEntries(\n Object.keys(paneBase.properties)\n .filter(key => !VIEWPORT_PROPS.has(key))\n .map(key => [key, pane[key as keyof typeof pane]]),\n ) as PaneSettings\n}\n\n// A variant under this many of the linear view's pixels folds into the\n// reference before layout, so the drawing gains detail as the view zooms in.\n// It is the width `gfa-to-tabix build` gives a backbone node at the zoom a\n// graph hands over to its coarse tier, so a tier folded at its handover draws\n// what the fine cut drew just below it.\nexport const FOLD_PX = 10\n\n// The linear view's bp per px past which a coarse tier is cut: its own\n// `aboveBpPerPx`, else the zoom at which the fine cut folds what the tier did\nexport function coarseHandover(coarse: unknown) {\n const { aboveBpPerPx, foldBelowBp } = (coarse ?? {}) as {\n aboveBpPerPx?: unknown\n foldBelowBp?: unknown\n }\n return typeof aboveBpPerPx === 'number'\n ? aboveBpPerPx\n : typeof foldBelowBp === 'number' && foldBelowBp > 0\n ? foldBelowBp / FOLD_PX\n : undefined\n}\n\nconst GraphTrackSettingsDialog = lazy(\n () => import('./components/GraphTrackSettingsDialog'),\n)\n\nexport function stateModelFactory(configSchema: LinearGraphDisplayConfigModel) {\n return types\n .compose(\n 'LinearGraphDisplay',\n BaseDisplay,\n TrackHeightMixin(),\n GraphPane,\n types.model({\n type: types.literal('LinearGraphDisplay'),\n configuration: ConfigurationReference(configSchema),\n // a zoom re-cuts the graph, and stress keeps the drawing's\n // orientation across re-cuts where FMMM turns it (ADR-044)\n layoutEngine: lenientOptionalEnum(LAYOUT_ENGINE_VALUES, 'stress'),\n // the window the graph on screen was asked for, so a restored\n // session cuts it again\n cutRegion: types.maybe(types.frozen<SubgraphRegion>()),\n // whether that cut came from the track's coarse pair\n // (RgfaTabixAdapter), on which no bp cap applies\n coarseCut: types.optional(types.boolean, false),\n }),\n )\n .volatile(() => ({\n recuts: 0,\n // the host window the settle clock last woke on\n settledWindow: undefined as HostWindow | undefined,\n // where a cut came back over its node limit (denseCovers)\n dense: undefined as SubgraphRegion | undefined,\n // the haplotypes a walk-indexed graph's header names, once read\n haplotypeNames: undefined as string[] | undefined,\n // the fold the latest cut asked for\n cutFoldBp: 0,\n }))\n .views(self => ({\n get grammar(): GraphGrammar {\n return {\n layoutMode: getConf(self, 'layoutMode'),\n color: getConf(self, 'color'),\n size: getConf(self, 'size'),\n layers: getConf(self, 'layers') as GraphLayers,\n facet: getConf(self, 'facet'),\n rows: getConf(self, 'rows'),\n hover: getConf(self, 'hover'),\n }\n },\n // The linear view leaves its highlight bands off this track while false\n get drawsGenomicCoordinates() {\n return self.layoutResult === undefined || self.hostPlacesX\n },\n get canvasHeight() {\n return self.height\n },\n get canRetryLoad() {\n return self.cutRegion !== undefined\n },\n // the config's defaultHaplotypes, else the lanes the track names\n get trackHaplotypes() {\n const adapter = self.sourceAdapter\n const track = self.sourceTrack\n return (\n (adapter && configHaplotypes(adapter)) ?? (track && trackLanes(track))\n )\n },\n // the linear view's zoom past which the track's coarse pair is cut, or\n // undefined for a track with none\n get coarseAboveBpPerPx() {\n return coarseHandover(self.sourceAdapter?.coarse)\n },\n }))\n .views(self => ({\n tierAt(bpPerPx: number): SubgraphTier {\n const above = self.coarseAboveBpPerPx\n return above !== undefined && bpPerPx > above ? 'coarse' : 'fine'\n },\n capFor(tier: SubgraphTier) {\n return tier === 'coarse' ? Infinity : self.maxRegionBp\n },\n // Whether a zoom has moved far enough from the one the drawing was\n // folded for that folding again would show or hide more. A graph with\n // walks is never folded, and a fold rounded to 0 bp counts as 1 bp.\n foldDrifted(bpPerPx: number) {\n const want = FOLD_PX * bpPerPx\n const had = self.cutFoldBp\n return (\n !self.graph?.paths?.length &&\n (want >= 2 * Math.max(had, 1) ||\n (self.foldedBelowBp !== undefined && want <= had / 2))\n )\n },\n get cutTier(): SubgraphTier {\n return self.coarseCut && self.coarseAboveBpPerPx !== undefined\n ? 'coarse'\n : 'fine'\n },\n }))\n .views(self => ({\n get settledCapBp() {\n const seen = self.settledWindow\n return seen ? self.capFor(self.tierAt(seen.bpPerPx)) : Infinity\n },\n }))\n .views(self => ({\n get regionTooLarge() {\n const seen = self.settledWindow\n return seen !== undefined && seen.end - seen.start > self.settledCapBp\n },\n get regionTooLargeReason() {\n const seen = self.settledWindow\n return seen\n ? `Region too large for a graph cut (${formatSpanBp(seen.end - seen.start)}, max ${formatSpanBp(self.settledCapBp)})`\n : ''\n },\n get zoomCanReleaseGate() {\n return true\n },\n get fetchCanceled() {\n return self.loadCanceled\n },\n }))\n .views(self => ({\n get svgReady() {\n return computeSvgReady(\n {\n error: self.error,\n regionTooLarge: self.regionTooLarge,\n extraTerminal: false,\n fetchCanceled: self.loadCanceled,\n },\n () => !self.isLoading && self.hasGraph && !!self.layoutResult,\n )\n },\n }))\n .views(self => ({\n // A backend that failed is an error the canvas reports with its retry;\n // the status chrome has no renderError phase of its own. A cut refused\n // over its node limit is an error marked regionTooLarge, which core's\n // error bar shows as a zoom-in notice instead.\n get displayPhase(): DisplayStatusPhase {\n return computeDisplayStatusPhase(\n {\n regionTooLarge: self.regionTooLarge,\n error: self.error ?? self.renderError,\n },\n () =>\n computeActivityPhase(\n {\n isMinimized: self.isMinimized,\n fetchInert: false,\n viewportEmpty:\n self.host?.initialized === true &&\n self.host.hasVisibleContent === false,\n isLoading: self.isLoading || !self.hasGraph,\n fetchCanceled: self.loadCanceled,\n awaitingDependentData: false,\n rendersCanvas: true,\n canvasDrawn: self.painted && self.geometryPainted,\n },\n () => true,\n () => self.host?.effectiveBodyMounted ?? true,\n ),\n )\n },\n }))\n .actions(self => ({\n // Into the config, so a share link, Edit plot and Reset track\n // settings all see it\n writeGrammar(settings: GraphGrammar) {\n for (const [slot, value] of Object.entries(settings)) {\n setConf(self, slot as keyof GraphGrammar, value)\n }\n },\n // The setters describe the next cut, which recut makes\n setSubgraphContext(hops: number) {\n self.subgraphContext = hops\n self.dense = undefined\n },\n setSubgraphHaplotypes(haplotypes: string[] | undefined) {\n self.subgraphHaplotypes = haplotypes\n self.dense = undefined\n },\n setDense(window: SubgraphRegion | undefined) {\n self.dense = window\n },\n setHaplotypeNames(names: string[] | undefined) {\n self.haplotypeNames = names\n },\n setMaxRegionBp(bp: number) {\n self.maxRegionBp = bp\n },\n // Cut `cutRegion` again with the current options. A coarse cut hops as\n // a fine one does, since a tier is the same graph folded.\n cut() {\n const region = self.cutRegion\n const adapterConfig = self.sourceAdapter\n if (!region || !adapterConfig) {\n return\n }\n const problem = self.offReference(region)\n if (problem) {\n self.clearGraph()\n self.setError(new Error(problem))\n return\n }\n const coarse = self.cutTier === 'coarse'\n self.cutFoldBp = Math.round(\n FOLD_PX * (self.settledWindow?.bpPerPx ?? self.host?.bpPerPx ?? 0),\n )\n return self.cutSubgraph(\n adapterConfig,\n region,\n { ...self.cutOptions, tier: coarse ? 'coarse' : undefined },\n self.cutFoldBp,\n )\n },\n }))\n .actions(self => ({\n recutAt(seen: HostWindow) {\n const tier = self.tierAt(seen.bpPerPx)\n self.coarseCut = tier === 'coarse'\n self.cutRegion = hostCut(\n seen,\n self.capFor(tier),\n layoutModeByValue(self.chosenLayoutMode).cutMargins,\n )\n self.recuts++\n return self.cut()\n },\n }))\n .actions(self => ({\n // The settle clock. A window the cut still holds fetches nothing; one\n // past its edge re-cuts, on the tier the zoom asks for, with margins\n // when the host places x and the window alone when the layout draws\n // its own picture of it. A canceled cut is re-made by the next move,\n // and a window a refused cut covers keeps its notice without asking\n // again. Returns whether it re-cut.\n settleOn(seen: HostWindow): boolean {\n self.settledWindow = seen\n const margins = layoutModeByValue(self.chosenLayoutMode).cutMargins\n if (\n self.regionTooLarge ||\n denseCovers(self.dense, seen) ||\n (!self.loadCanceled &&\n self.tierAt(seen.bpPerPx) === self.cutTier &&\n cutHolds(self.cutRegion, seen, margins) &&\n !self.foldDrifted(seen.bpPerPx))\n ) {\n return false\n }\n // An outrun cut resolves without touching the error, so the error\n // is this cut's only while no later one has started\n const cut = self.recutAt(seen)\n const recut = self.recuts\n void Promise.resolve(cut).then(() => {\n if (\n isAlive(self) &&\n self.recuts === recut &&\n isNodeLimitError(self.error)\n ) {\n this.refuseDenseCut(seen)\n }\n })\n return true\n },\n // A cut refused for its node count holds nothing, so a window\n // narrower than this one cuts again\n refuseDenseCut(seen: HostWindow) {\n self.setDense(seen)\n self.cutRegion = undefined\n this.settleOn(self.settledWindow ?? seen)\n },\n // Cut the region again with the current options, or the window on\n // screen where a refused cut left no region\n recut() {\n if (self.cutRegion) {\n void self.cut()\n } else if (self.settledWindow) {\n this.settleOn(self.settledWindow)\n }\n },\n relayoutFrom(from: LayoutModeValue) {\n const seen = self.host ? hostWindow(self.host) : undefined\n if (\n seen &&\n !self.regionTooLarge &&\n (self.cutChangedFrom(from) ||\n layoutModeByValue(from).cutMargins !==\n layoutModeByValue(self.chosenLayoutMode).cutMargins)\n ) {\n return self.recutAt(seen)\n }\n return self.recomputeLayout()\n },\n retryLoad() {\n void self.cut()\n },\n reload() {\n void self.cut()\n },\n cancelFetchByUser() {\n self.stopLoad()\n },\n }))\n .actions(self => ({\n // A failed read leaves the picker taking typed names\n async fetchHaplotypeNames(\n adapterConfig: Record<string, unknown>,\n signal?: AbortSignal,\n ) {\n try {\n const names = await getSession(self).rpcManager.call(\n getRpcSessionId(self),\n 'GetGraphHaplotypes',\n { adapterConfig, signal },\n )\n if (isAlive(self) && !signal?.aborted) {\n self.setHaplotypeNames(names)\n }\n } catch (e) {\n if (!signal?.aborted) {\n console.warn('[LinearGraphDisplay] no haplotype names', e)\n }\n }\n },\n }))\n .actions(self => ({\n stretchWithHost(\n before: { bpPerPx: number; offsetPx: number },\n now: { bpPerPx: number; offsetPx: number },\n ) {\n const bounds = self.layoutBounds\n if (!bounds || !self.followsHostView) {\n return\n }\n // no longer the fit, so the fit autorun cannot undo it before the\n // re-cut lands; followNewLayout fits the new drawing\n if (self.viewportOwner === 'fit') {\n self.viewportOwner = 'user'\n }\n const k = before.bpPerPx / now.bpPerPx\n const midY =\n self.translateY + self.scaleY * (bounds.minY + bounds.h / 2)\n self.scale *= k\n self.translateX = k * (self.translateX + before.offsetPx) - now.offsetPx\n self.translateY = midY - k * (midY - self.translateY)\n },\n }))\n .actions(self => ({\n forceLoad() {\n const seen = self.settledWindow\n if (seen) {\n self.setMaxRegionBp(Math.ceil(seen.end - seen.start))\n self.settleOn(seen)\n }\n },\n // The host's two clocks. The frame clock moves x with every frame of\n // the linear view and fetches nothing; the settle clock wakes on its\n // debounced blocks.\n afterAttach() {\n if (self.cutRegion && !self.graph) {\n void self.cut()\n }\n let namesRead: AbortController | undefined\n addDisposer(self, () => {\n namesRead?.abort()\n })\n addDisposer(\n self,\n reaction(\n () => {\n const adapter = self.sourceAdapter\n return adapter && walkIndexed(adapter) ? adapter : undefined\n },\n adapterConfig => {\n namesRead?.abort()\n namesRead = undefined\n self.setHaplotypeNames(undefined)\n if (adapterConfig) {\n namesRead = new AbortController()\n void self.fetchHaplotypeNames(adapterConfig, namesRead.signal)\n }\n },\n {\n fireImmediately: true,\n // a lane adapter's config is rebuilt whenever an assembly is\n // added, which would drop and re-read the names\n equals: (a, b) => JSON.stringify(a) === JSON.stringify(b),\n name: 'GraphHaplotypeNames',\n },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.hostPlacesX,\n places => {\n if (!places) {\n self.releaseHost()\n }\n },\n { name: 'GraphHostPlacesX' },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.hostFrame,\n frame => {\n if (frame) {\n self.hostTransform(frame.scale, frame.translateX)\n }\n },\n {\n equals: (a, b) =>\n a?.scale === b?.scale && a?.translateX === b?.translateX,\n fireImmediately: true,\n name: 'GraphHostFrame',\n },\n ),\n )\n // The stretch clock: a drawing whose x is not bp follows the host's\n // zoom and pan as a screen-space map, x' = k x + c, until the re-cut\n // lands and morphs from it, as a linear track stretches its blocks\n let seen: { bpPerPx: number; offsetPx: number } | undefined\n addDisposer(\n self,\n reaction(\n () =>\n self.host && !self.hostPlacesX\n ? { bpPerPx: self.host.bpPerPx, offsetPx: self.host.offsetPx }\n : undefined,\n now => {\n const before = seen\n seen = now\n if (now && before && now.bpPerPx > 0) {\n self.stretchWithHost(before, now)\n }\n },\n {\n equals: (a, b) =>\n a?.bpPerPx === b?.bpPerPx && a?.offsetPx === b?.offsetPx,\n fireImmediately: true,\n name: 'GraphHostStretch',\n },\n ),\n )\n // A track clips what runs past its height, so side-by-side panels\n // grow it to what they need as a pane of their own. Only a change in\n // the panels does this, so a track shrunk afterwards stays shrunk.\n addDisposer(\n self,\n reaction(\n () => `${self.facetSetting.field} ${self.facetPlacement?.count}`,\n () => {\n const needs =\n (self.facetGridIn(self.paneCeiling - FACET_KEY_PX)?.total ??\n 0) + FACET_KEY_PX\n if ((self.facetGrid?.total ?? 0) + FACET_KEY_PX > self.height) {\n self.setHeight(Math.max(self.height, Math.ceil(needs)))\n }\n },\n { name: 'GraphFacetHeight' },\n ),\n )\n addDisposer(\n self,\n reaction(\n () => self.host?.coarseDynamicBlocks,\n blocks => {\n const { host } = self\n const seen = blocks && host ? hostWindow(host) : undefined\n if (seen) {\n self.settleOn(seen)\n }\n },\n { fireImmediately: true, name: 'GraphHostSettle' },\n ),\n )\n },\n }))\n .views(self => ({\n // The window on screen as a view of its own, drawn as the track draws\n // it: the cut less the margins it holds for panning. A window forced\n // past the cap carries its own span as the cap.\n get graphViewSpec() {\n const seen = self.host ? hostWindow(self.host) : undefined\n const trackId = self.sourceTrackId\n if (\n !seen ||\n !trackId ||\n !self.hasGraph ||\n self.coarseCut ||\n self.regionTooLarge ||\n denseCovers(self.dense, seen)\n ) {\n return undefined\n }\n const start = Math.floor(seen.start)\n const end = Math.ceil(seen.end)\n return {\n ...paneSettings(self),\n loadedTrackId: trackId,\n loadedRegion: {\n refName: seen.refName,\n assemblyName: seen.assemblyName,\n start,\n end,\n },\n subgraphHaplotypes: self.cutHaplotypes,\n maxRegionBp: Math.max(self.maxRegionBp, end - start),\n ...self.grammar,\n layoutMode: self.chosenLayoutMode,\n connectedViewId: self.host?.id,\n } satisfies GraphViewSpec\n },\n }))\n .actions(self => ({\n openGraphView() {\n const spec = self.graphViewSpec\n if (spec) {\n getSession(self).addView('GraphGenomeView', spec)\n }\n },\n }))\n .views(self => ({\n // Which haplotypes a GBZ or walk-indexed cut is for: every one in the\n // graph, the config's default set or the assemblies the track names,\n // or a list chosen in Graph settings\n cutMenuItems(): MenuItem[] {\n const adapter = self.sourceAdapter\n const track = self.sourceTrack\n if (!adapter || !track || !cutsByHaplotype(adapter)) {\n return []\n }\n const defaults = configHaplotypes(adapter)\n const lanes = trackLanes(track)\n const names = self.haplotypeNames\n const chosen = self.subgraphHaplotypes\n const recut = (haplotypes: string[] | undefined) => {\n self.setSubgraphHaplotypes(haplotypes)\n self.recut()\n }\n return [\n { type: 'subHeader', label: 'Load' },\n {\n type: 'radio',\n label: names\n ? `Every haplotype in the graph (${names.length.toLocaleString()})`\n : 'Every haplotype in the graph',\n checked: chosen ? chosen.length === 0 : !defaults && !lanes,\n onClick: () => {\n recut([])\n },\n },\n ...(defaults || lanes\n ? [\n {\n type: 'radio' as const,\n label: defaults\n ? \"The track's default haplotypes\"\n : `The track's ${lanes?.length} assemblies`,\n checked: chosen === undefined,\n onClick: () => {\n recut(undefined)\n },\n },\n ]\n : []),\n {\n type: 'radio',\n label: 'Chosen in Graph settings...',\n checked: (chosen?.length ?? 0) > 0,\n onClick: () => {\n this.openSettings()\n },\n },\n ]\n },\n openSettings() {\n getSession(self).queueDialog(onClose => [\n GraphTrackSettingsDialog,\n { model: self, onClose },\n ])\n },\n async renderSvg(opts?: ExportSvgDisplayOptions): Promise<ReactNode> {\n const { renderGraphTrackSvg } = await import('./renderSvg')\n return renderGraphTrackSvg(\n self as unknown as LinearGraphDisplayModel,\n opts,\n )\n },\n trackMenuItems(): MenuItem[] {\n const launches = self.launchMenuItems()\n pushLaunchItem(launches, {\n label: 'Graph genome view',\n icon: BubbleChartIcon,\n disabled: !self.graphViewSpec,\n disabledHelpText:\n self.error && !isNodeLimitError(self.error)\n ? 'The track could not cut a graph here'\n : self.isLoading && !self.hasGraph\n ? 'The track is still cutting its graph'\n : 'Zoom in until the track cuts a graph',\n onClick: () => {\n self.openGraphView()\n },\n })\n const haplotypes = [\n ...this.cutMenuItems(),\n ...self.highlightMenuItems(),\n ]\n return [\n ...(haplotypes.length > 0\n ? [{ label: 'Haplotypes', icon: RouteIcon, subMenu: haplotypes }]\n : []),\n ...self.graphMenuItems(),\n {\n label: 'Graph settings...',\n icon: SettingsIcon,\n helpText: 'Subgraph, drawing and force-directed layout',\n onClick: () => {\n this.openSettings()\n },\n },\n ...launches,\n ...editPlotMenuItems(self),\n ]\n },\n }))\n}\n\nexport type LinearGraphDisplayStateModel = ReturnType<typeof stateModelFactory>\nexport type LinearGraphDisplayModel = Instance<LinearGraphDisplayStateModel>\n// what the track's own settings read, which the menus that open them cannot\n// name without naming themselves\nexport type LinearGraphCutModel = Omit<\n LinearGraphDisplayModel,\n 'trackMenuItems' | 'cutMenuItems' | 'openSettings' | 'renderSvg'\n>\n", "import { lazy } from 'react'\n\nimport DisplayType from '@jbrowse/core/pluggableElementTypes/DisplayType'\n\nimport { configSchemaFactory } from './configSchema'\nimport { stateModelFactory } from './model'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function LinearGraphDisplayF(pluginManager: PluginManager) {\n pluginManager.addDisplayType(() => {\n const configSchema = configSchemaFactory()\n return Object.assign(\n new DisplayType({\n name: 'LinearGraphDisplay',\n displayName: 'Graph',\n configSchema,\n stateModel: stateModelFactory(configSchema),\n // FeatureTrack and SyntenyTrack for the configs and share links that\n // name the graph display on one, which 4.0.7 and before required\n trackType: ['GraphTrack', 'FeatureTrack', 'SyntenyTrack'],\n viewType: 'LinearGenomeView',\n ReactComponent: lazy(() => import('./components/LinearGraphDisplay')),\n }),\n { adapterCapabilities: ['getSubgraph'] },\n )\n })\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\n\nimport { fileLocationSlot, tabixIndexSchema, tbiBeside } from '../panSNTabix.ts'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config MinigraphBubbleAdapter\n * #trackType FeatureTrack\n * #fileFormat graph | Minigraph bubble BED | `gfatools bubble` output; HPRC publishes one ready-made, so no preprocessing at all\n * the tabix-indexed BED `gfatools bubble` writes for a minigraph graph: one row\n * per bubble, on the reference's own coordinates. Unlike\n * [RgfaTabixAdapter](/docs/config/rgfatabixadapter) this needs no index build of\n * your own, because HPRC publishes this file beside its minigraph graph.\n *\n * It shows *where* the graph varies and by how much, not the graph itself.\n *\n * #example\n * ```js\n * {\n * type: 'MinigraphBubbleAdapter',\n * uri: 'https://jbrowse.org/demos/hprc/hprc-v2.1-mc-grch38.bubbles.bed.gz',\n * assemblyNameToPanSN: { hg38: 'GRCh38' },\n * }\n * ```\n */\n\nfunction normalizeSnapshot(snap: Record<string, unknown>) {\n const { uri, baseUri, csi } = snap\n return typeof uri === 'string'\n ? {\n ...snap,\n bubblesLocation: { uri, baseUri },\n index: tbiBeside(uri, baseUri, csi),\n }\n : snap\n}\n\nconst MinigraphBubbleAdapter = ConfigurationSchema(\n 'MinigraphBubbleAdapter',\n {\n /**\n * #slot\n */\n bubblesLocation: fileLocationSlot('/path/to/graph.bb.bed.gz'),\n /**\n * #slot\n */\n index: tabixIndexSchema(\n 'MinigraphBubbleIndex',\n '/path/to/graph.bb.bed.gz.tbi',\n ),\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN sample prefix, for when they\n * differ. `gfatools bubble` names each row after the graph's stable\n * sequence, so a Minigraph-Cactus graph yields `GRCh38#0#chr6` and an\n * `hg38` assembly needs `{ hg38: 'GRCh38' }`; HPRC's published v1.0\n * minigraph bubbles are bare (`chr6`) and need nothing.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n * preprocessor to allow the minimal config\n * ```json\n * { \"type\": \"MinigraphBubbleAdapter\", \"uri\": \"graph.bb.bed.gz\" }\n * ```\n */\n preProcessSnapshot: normalizeSnapshot,\n },\n)\n\nexport type MinigraphBubbleAdapterConfig = Instance<\n typeof MinigraphBubbleAdapter\n>\n\nexport default MinigraphBubbleAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function MinigraphBubbleAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'MinigraphBubbleAdapter',\n displayName: 'Minigraph bubble BED adapter',\n configSchema,\n adapterMetadata: {\n category: 'Graph adapters',\n },\n getAdapterClass: () =>\n import('./MinigraphBubbleAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { WALK_BUDGETS } from '@jbrowse/graph-walks'\n\nimport {\n fileLocationSlot,\n tabixIndexSchema,\n tbiBeside,\n walksLocations,\n} from '../panSNTabix.ts'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config RgfaTabixAdapter\n * #trackType GraphTrack\n * #fileFormat graph | Indexed GFA | Built by `gfa-to-tabix`; serves segments as features and extracts local subgraphs\n * two tabix-indexed BED files, one of a graph's segments and one of its links,\n * written by [gfa-to-tabix](https://github.com/GMOD/gfa-to-tabix) from an rGFA\n * or from a plain GFA with paths. Both of its layouts are read: `anchored`,\n * where one query per file returns the graph under a region, and `contig`,\n * where the adapter follows links onto other contigs.\n *\n * The `uri` shorthand takes the prefix the build script was given and resolves\n * `<uri>.segs.bed.gz`, `<uri>.links.bed.gz` and their `.tbi` indexes. `coarse`\n * takes the same shorthand for a second pair at one node per bubble, built by\n * `gfa-to-tabix fold`, plus either the zoom past which a graph view following\n * a linear view cuts it (`aboveBpPerPx`) or the size it was folded at\n * (`foldBelowBp`), from which the plugin derives that zoom.\n *\n * `walksUri` takes the prefix of a walk file in place of `uri`, and resolves\n * `<walksUri>.walks.bed.gz` and its `.tbi`. `gfa-to-tabix --walks -o <prefix>`\n * writes one per reference sample, so a track names one as\n * `<prefix>.<sample>`. The adapter reads walk format 3, which gfa-to-tabix\n * writes from 1.1, through @jbrowse/graph-walks. Such a graph's cut carries\n * the haplotypes' walks, and `defaultHaplotypes` names the ones it is cut for\n * until the user picks others.\n *\n * #example\n * ```js\n * {\n * type: 'RgfaTabixAdapter',\n * uri: 'https://example.com/hprc.rgfa',\n * coarse: { uri: 'https://example.com/hprc.fold10000', foldBelowBp: 10000 },\n * }\n * ```\n *\n * #example\n * ```js\n * {\n * type: 'RgfaTabixAdapter',\n * walksUri: 'https://example.org/hprc-v2.1-mc-grch38.GRCh38',\n * assemblyNameToPanSN: { hg38: 'GRCh38' },\n * defaultHaplotypes: ['HG002', 'HG00733', 'HG02257', 'NA19240'],\n * }\n * ```\n */\n\nfunction prefixLocations(snap: Record<string, unknown>) {\n const { uri, baseUri, csi } = snap\n return typeof uri === 'string'\n ? {\n ...snap,\n segmentsLocation: { uri: `${uri}.segs.bed.gz`, baseUri },\n segmentsIndex: tbiBeside(`${uri}.segs.bed.gz`, baseUri, csi),\n linksLocation: { uri: `${uri}.links.bed.gz`, baseUri },\n linksIndex: tbiBeside(`${uri}.links.bed.gz`, baseUri, csi),\n }\n : snap\n}\n\nfunction normalizeSnapshot(snap: Record<string, unknown>) {\n const { coarse, baseUri, csi } = snap\n return walksLocations(\n prefixLocations(\n typeof coarse === 'object' && coarse !== null\n ? { ...snap, coarse: prefixLocations({ baseUri, csi, ...coarse }) }\n : snap,\n ),\n )\n}\n\nconst RgfaTabixCoarseTier = ConfigurationSchema('RgfaTabixCoarseTier', {\n /**\n * #slot\n * The linear view's bp per px past which a graph following it cuts this\n * pair. Unset, with `foldBelowBp` unset too, means the track has no coarse\n * tier. There is no default,\n * because the zoom a fine cut stays drawable to depends on the graph's\n * density: a minigraph graph averages ~7 kb per segment, a base-level pggb\n * graph ~17 bp.\n */\n aboveBpPerPx: { type: 'maybeNumber' },\n /**\n * #slot\n * The size, in bp, this pair was folded at (`gfa-to-tabix fold --below`).\n * When `aboveBpPerPx` is unset, the handover is `foldBelowBp / 10`, the zoom\n * at which the fine cut folds the same variants away.\n */\n foldBelowBp: { type: 'maybeNumber' },\n /**\n * #slot\n */\n segmentsLocation: fileLocationSlot('/path/to/graph.tier.segs.bed.gz'),\n /**\n * #slot\n */\n segmentsIndex: tabixIndexSchema(\n 'RgfaCoarseSegmentsIndex',\n '/path/to/graph.tier.segs.bed.gz.tbi',\n ),\n /**\n * #slot\n */\n linksLocation: fileLocationSlot('/path/to/graph.tier.links.bed.gz'),\n /**\n * #slot\n */\n linksIndex: tabixIndexSchema(\n 'RgfaCoarseLinksIndex',\n '/path/to/graph.tier.links.bed.gz.tbi',\n ),\n})\n\nconst RgfaTabixAdapter = ConfigurationSchema(\n 'RgfaTabixAdapter',\n {\n /**\n * #slot\n * one row per segment: `stableName start end segmentId rank`, as emitted by\n * `gfatools gfa2bed -m`\n */\n segmentsLocation: fileLocationSlot('/path/to/graph.segs.bed.gz'),\n /**\n * #slot\n */\n segmentsIndex: tabixIndexSchema(\n 'RgfaSegmentsIndex',\n '/path/to/graph.segs.bed.gz.tbi',\n ),\n /**\n * #slot\n * one row per link per endpoint, each carrying both endpoints in full so a\n * neighbour on another stable sequence needs no segment-id lookup\n */\n linksLocation: fileLocationSlot('/path/to/graph.links.bed.gz'),\n /**\n * #slot\n */\n linksIndex: tabixIndexSchema(\n 'RgfaLinksIndex',\n '/path/to/graph.links.bed.gz.tbi',\n ),\n /**\n * #slot\n * a `gfa-to-tabix --walks` file in walk format 3: per reference chunk,\n * the reference's path, the ways haplotypes leave it and each haplotype's\n * piece. Unset means the graph has no walks.\n */\n walksLocation: fileLocationSlot(''),\n /**\n * #slot\n */\n walksIndex: tabixIndexSchema('RgfaWalksIndex'),\n /**\n * #slot\n * the most haplotype steps a cut keeps; a window whose walks hold more\n * shows a zoom-in notice instead, as does one whose rows hold eight times\n * as many. Counts only the haplotypes the cut is for, so fewer haplotypes\n * draw a wider window. Walk rows draw runs rather than steps and are\n * bounded by `walkByteBudget` alone.\n */\n walkStepBudget: {\n type: 'integer',\n defaultValue: WALK_BUDGETS.stepBudget,\n },\n /**\n * #slot\n * the most compressed bytes a cut of a walk-indexed graph fetches from its\n * walk file, as its Tabix index estimates it before any row is read; a\n * window over it shows a zoom-in notice instead. The budget covers every\n * haplotype, since a chunk's rows are filed for all of them.\n */\n walkByteBudget: {\n type: 'integer',\n defaultValue: WALK_BUDGETS.byteBudget,\n },\n /**\n * #slot\n * the haplotypes a walk-indexed graph is cut for until the user picks\n * others in the track's Haplotypes menu or Graph settings, as PanSN prefixes\n * (`HG002#1`, or `HG002` for both of its haplotypes). Empty means every\n * haplotype, or the lanes the track's `assemblyNames` lists after its\n * reference.\n */\n defaultHaplotypes: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN sample prefix in the graph, for\n * when they differ. Defaults to identity: the assembly name is assumed to be\n * the PanSN sample name, and a graph whose stable names are bare (minigraph\n * writes `chr1`) needs nothing here at all.\n *\n * Minigraph-Cactus writes PanSN stable names, so HPRC's release-2 graph\n * calls the reference `GRCh38#0#chr1` and an `hg38` assembly needs\n * `{ hg38: 'GRCh38' }`. The prefix is what disambiguates: that same graph\n * also contains `CHM13#0#chr1`, so matching on the contig alone would\n * silently resolve to the wrong sample.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n /**\n * #slot\n * The same graph at one node per bubble, which a graph view following a\n * linear view cuts once that view is zoomed out past `aboveBpPerPx`, and\n * which no bp cap applies to. `{ uri, aboveBpPerPx }` or `{ uri,\n * foldBelowBp }`, where `uri` is a prefix as the adapter's own is;\n * `aboveBpPerPx` wins when both are given.\n */\n coarse: RgfaTabixCoarseTier,\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n *\n * preprocessor to allow the minimal config\n * ```json\n * { \"type\": \"RgfaTabixAdapter\", \"uri\": \"graph.rgfa\" }\n * ```\n * or, for the GRCh38 set of a graph built by `gfa-to-tabix --walks -o\n * chr22`,\n * ```json\n * { \"type\": \"RgfaTabixAdapter\", \"walksUri\": \"chr22.GRCh38\" }\n * ```\n */\n preProcessSnapshot: normalizeSnapshot,\n },\n)\n\nexport type RgfaTabixAdapterConfig = Instance<typeof RgfaTabixAdapter>\n\nexport default RgfaTabixAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function RgfaTabixAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'RgfaTabixAdapter',\n displayName: 'Indexed rGFA adapter',\n configSchema,\n // what a graph display needs of its track's adapter\n adapterCapabilities: ['getSubgraph'],\n adapterMetadata: {\n category: 'Graph adapters',\n },\n getAdapterClass: () =>\n import('./RgfaTabixAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { ConfigurationSchema } from '@jbrowse/core/configuration'\nimport { WALK_BUDGETS } from '@jbrowse/graph-walks'\n\nimport {\n fileLocationSlot,\n tabixIndexSchema,\n walksLocations,\n} from '../panSNTabix.ts'\n\nimport type { Instance } from '@jbrowse/mobx-state-tree'\n\n/**\n * #config WalkTabixSyntenyAdapter\n * #trackType GraphTrack\n * #fileFormat synteny | Walk-indexed graph | Built by `gfa-to-tabix --walks`; haplotype lanes and local subgraphs from three tabix files\n * Serves a pangenome graph whose haplotype walks\n * [gfa-to-tabix](https://github.com/GMOD/gfa-to-tabix) `--walks` filed under\n * chunks of a reference, as haplotype-versus-reference alignments, the shape\n * `MultiWaySyntenyDisplay` draws as one lane per haplotype, and as the graph\n * display's cut. A window on the reference reads the walk rows filed under\n * it, and each haplotype is aligned to the reference, or to another\n * haplotype, on the nodes both walks visit. No base is compared, so a short\n * bubble with equal bases on both sides is written as mismatches and any other\n * as an insertion and a deletion.\n *\n * `walksUri` takes the prefix of one reference's walk file, `<prefix>.<sample>`,\n * and resolves `<walksUri>.walks.bed.gz` and its `.tbi`. The adapter reads walk\n * format 3, which gfa-to-tabix writes from 1.1, through @jbrowse/graph-walks.\n * Only a window on the anchor is answered.\n *\n * #example\n * ```js\n * {\n * type: 'WalkTabixSyntenyAdapter',\n * walksUri: 'https://example.org/hprc-v2.1-mc-grch38.GRCh38',\n * assemblyNames: ['hg38'],\n * assemblyNameToPanSN: { hg38: 'GRCh38' },\n * }\n * ```\n */\n\nconst WalkTabixSyntenyAdapter = ConfigurationSchema(\n 'WalkTabixSyntenyAdapter',\n {\n /**\n * #slot\n * The first entry is the anchor: the JBrowse assembly the walk file's\n * reference sample is loaded as. A haplotype needs no entry: its lane\n * draws on the session assembly `assemblyNameToPanSN` maps to it, at\n * haplotype (`HG002#1`) or sample (`HG002`) depth, and a haplotype with no\n * assembly is still a lane, labelled by its PanSN prefix.\n */\n assemblyNames: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * a `gfa-to-tabix --walks` file in walk format 3\n */\n walksLocation: fileLocationSlot('/path/to/graph.walks.bed.gz'),\n /**\n * #slot\n */\n walksIndex: tabixIndexSchema('WalkTabixWalksIndex'),\n /**\n * #slot\n * the most haplotype steps one window keeps; a window whose walks hold\n * more shows a zoom-in notice instead, as does one whose rows hold eight\n * times as many. Counts only the haplotypes asked for. Walk rows draw\n * runs rather than steps and are bounded by `walkByteBudget` alone.\n */\n walkStepBudget: {\n type: 'integer',\n defaultValue: WALK_BUDGETS.stepBudget,\n },\n /**\n * #slot\n * the most compressed bytes one window fetches from the walk file, as its\n * Tabix index estimates it before any row is read; a window over it shows\n * a zoom-in notice instead.\n */\n walkByteBudget: {\n type: 'integer',\n defaultValue: WALK_BUDGETS.byteBudget,\n },\n /**\n * #slot\n * the haplotypes the graph display is cut for until the user picks\n * others, as PanSN prefixes (`HG002#1`, or `HG002` for both of its\n * haplotypes). Empty means the lanes the track's `assemblyNames` lists\n * after its reference, else every haplotype.\n */\n defaultHaplotypes: {\n type: 'stringArray',\n defaultValue: [],\n },\n /**\n * #slot\n * A tab-separated table of per-sample metadata, which the graph view's\n * walk rows group by. Its header row names the columns, and its first\n * column is the walk's sample (`HG00097`) or haplotype (`HG00097#1`).\n * Empty means no grouping.\n */\n samplesTsvLocation: fileLocationSlot(''),\n /**\n * #slot\n * Maps a JBrowse assembly name to its PanSN prefix in the graph, sample or\n * haplotype level (`{ hg38: 'GRCh38', 'HG002.1': 'HG002#1' }`). An\n * assembly not listed maps to itself.\n */\n assemblyNameToPanSN: {\n type: 'frozen',\n defaultValue: {},\n },\n },\n {\n explicitlyTyped: true,\n\n /**\n * #preProcessSnapshot\n * preprocessor to allow the minimal config, for the GRCh38 set of a graph\n * built by `gfa-to-tabix --walks -o chr22`\n * ```json\n * {\n * \"type\": \"WalkTabixSyntenyAdapter\",\n * \"walksUri\": \"chr22.GRCh38\",\n * \"assemblyNames\": [\"hg38\"],\n * \"assemblyNameToPanSN\": { \"hg38\": \"GRCh38\" }\n * }\n * ```\n */\n preProcessSnapshot: walksLocations,\n },\n)\n\nexport type WalkTabixSyntenyAdapterConfig = Instance<\n typeof WalkTabixSyntenyAdapter\n>\n\nexport default WalkTabixSyntenyAdapter\n", "import AdapterType from '@jbrowse/core/pluggableElementTypes/AdapterType'\n\nimport configSchema from './configSchema.ts'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\nexport default function WalkTabixSyntenyAdapterF(pluginManager: PluginManager) {\n pluginManager.addAdapterType(\n () =>\n new AdapterType({\n name: 'WalkTabixSyntenyAdapter',\n displayName: 'Walk-indexed graph adapter',\n configSchema,\n // the capabilities GbzBaseSyntenyAdapter declares, for the same\n // reasons: the header lists every haplotype as a lane, and one read\n // of an anchor window answers any pair of lanes, or several\n adapterCapabilities: [\n 'getSubgraph',\n 'headerLanes',\n 'lanePairsOnAnchor',\n 'lanePairBatches',\n ],\n adapterMetadata: {\n category: 'Synteny adapters',\n },\n getAdapterClass: () =>\n import('./WalkTabixSyntenyAdapter.ts').then(r => r.default),\n }),\n )\n}\n", "import { buildAdapterConfig } from '../GraphAddTrackWorkflow/buildTrackConfig'\nimport { isSegmentsLocation } from '../GraphAddTrackWorkflow/graphManifest'\nimport {\n WALKS_SUFFIX,\n locationName,\n readsSiblings,\n walkFileSample,\n} from '../locationName'\nimport { LANE_ADAPTERS } from '../panSNAliases/trackAdapterConfig'\n\nimport type { GraphFileChoice } from '../GraphAddTrackWorkflow/buildTrackConfig'\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { FileLocation } from '@jbrowse/core/util'\nimport type {\n AdapterGuesser,\n TrackTypeGuesser,\n} from '@jbrowse/core/util/tracks'\n\ntype TrackConfigSnapshot = Record<string, unknown>\n\nconst GRAPH_ADAPTERS = new Set(['RgfaTabixAdapter', 'GbzBaseSyntenyAdapter'])\n\nexport function isGbzLocation(loc: FileLocation) {\n return locationName(loc).toLowerCase().endsWith('.gbz.db')\n}\n\n// A lanes adapter cuts on the first assembly it names. A track added through\n// Add track names that assembly on the track alone.\nexport function withLaneAnchor(snap: TrackConfigSnapshot) {\n const adapter = snap.adapter as\n { type?: string; assemblyNames?: unknown[] } | undefined\n return adapter?.type !== undefined &&\n LANE_ADAPTERS.has(adapter.type) &&\n !adapter.assemblyNames?.length &&\n Array.isArray(snap.assemblyNames) &&\n snap.assemblyNames.length > 0\n ? { ...snap, adapter: { ...adapter, assemblyNames: snap.assemblyNames } }\n : snap\n}\n\n// A walk file opened with no PanSN map reads as the sample its name gives, on\n// the track's assembly; a guessed adapter had no assembly to key that by\nexport function withWalkReference(snap: TrackConfigSnapshot) {\n const adapter = snap.adapter as\n | {\n type?: string\n walksLocation?: FileLocation\n assemblyNameToPanSN?: unknown\n }\n | undefined\n const [assembly] = Array.isArray(snap.assemblyNames)\n ? (snap.assemblyNames as string[])\n : []\n const sample =\n adapter?.type === 'RgfaTabixAdapter' && adapter.walksLocation\n ? walkFileSample(adapter.walksLocation)\n : undefined\n return assembly &&\n sample &&\n sample !== assembly &&\n adapter?.assemblyNameToPanSN === undefined\n ? {\n ...snap,\n adapter: { ...adapter, assemblyNameToPanSN: { [assembly]: sample } },\n }\n : snap\n}\n\nexport function guessGraphAdapter(\n file: FileLocation,\n index?: FileLocation,\n adapterHint?: string,\n) {\n const guess = (choice: GraphFileChoice) =>\n buildAdapterConfig({\n choice,\n loc: file,\n indexLoc: index,\n assembly: '',\n sample: '',\n })\n if (\n (!adapterHint || adapterHint === 'GbzBaseSyntenyAdapter') &&\n isGbzLocation(file)\n ) {\n return guess('GbzBaseSyntenyAdapter')\n }\n if (!adapterHint || adapterHint === 'RgfaTabixAdapter') {\n if (isSegmentsLocation(file)) {\n return guess('RgfaTabixAdapter')\n }\n // a file picked in the browser has no index beside it to assume\n if (\n locationName(file).endsWith(WALKS_SUFFIX) &&\n (index !== undefined || readsSiblings(file))\n ) {\n return guess('RgfaTabixWalks')\n }\n }\n return undefined\n}\n\nexport default function GraphTrackDefaultsF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint(\n 'Core-preProcessTrackConfig',\n withLaneAnchor,\n )\n pluginManager.addToExtensionPoint(\n 'Core-preProcessTrackConfig',\n withWalkReference,\n )\n pluginManager.addToExtensionPoint(\n 'Core-guessAdapterForLocation',\n (next: AdapterGuesser): AdapterGuesser =>\n (file, index, adapterHint) =>\n guessGraphAdapter(file, index, adapterHint) ??\n next(file, index, adapterHint),\n )\n pluginManager.addToExtensionPoint(\n 'Core-guessTrackTypeForLocation',\n (next: TrackTypeGuesser): TrackTypeGuesser =>\n (adapterName, file) =>\n GRAPH_ADAPTERS.has(adapterName)\n ? 'GraphTrack'\n : next(adapterName, file),\n )\n}\n", "import { isRecord } from '../isRecord'\nimport { withRows } from '../launchFromGraph/linearViewTarget'\n\nexport interface HighlightRegion {\n refName: string\n start: number\n end: number\n assemblyName?: string\n}\n\nexport interface GraphViewHighlight {\n key: string\n region: HighlightRegion\n}\n\nfunction readRegion(value: unknown): HighlightRegion | undefined {\n let region: HighlightRegion | undefined\n if (isRecord(value)) {\n const { refName, start, end, assemblyName } = value\n if (\n typeof refName === 'string' &&\n typeof start === 'number' &&\n typeof end === 'number'\n ) {\n region = {\n refName,\n start,\n end,\n assemblyName:\n typeof assemblyName === 'string' ? assemblyName : undefined,\n }\n }\n }\n return region\n}\n\n// Whether a graph view's highlights belong on a given linear view.\n// `connectedViewId` is written by the launch menu, so a launched pair is\n// explicit. A graph view without one \u2014 a hand-written session snapshot, or\n// `Add > Graph genome view` followed by a subgraph load \u2014 matches any linear\n// view, because the alternative is silently drawing nothing.\n//\n// So does one whose linear view has been closed. Held to an id nothing answers\n// to, it matched no view and its hover drew nowhere for the rest of the\n// session, the view it next opened included.\nfunction isConnected(\n view: Record<string, unknown>,\n linearViewId: string,\n liveViewIds: ReadonlySet<unknown>,\n) {\n const connectedViewId = view.connectedViewId\n return (\n connectedViewId === undefined ||\n connectedViewId === linearViewId ||\n !liveViewIds.has(connectedViewId)\n )\n}\n\n// ...and whether the view can mean anything by it. `getHighlightCoords`\n// canonicalizes a refName against the region's OWN assembly and then lays it\n// out against this view's displayed regions, without ever asking whether the\n// two are the same assembly \u2014 so a band handed to the wrong view is drawn, at\n// coordinates that belong to somebody else's genome.\n//\n// That is not hypothetical for an unpaired graph, which by the rule above\n// matches every linear view in the session. A synteny stack's rows are LGVs on\n// different assemblies, and a PanSN name reduces to a bare contig: the five\n// E. coli strains each have one refName `chr`, so a graph cut from K12 painted\n// its K12 interval across Sakai's row and CFT073's at their own offsets. With\n// the assembly checked the reference row keeps the band and the rest correctly\n// draw nothing.\n//\n// A region stating no assembly still passes \u2014 `readRegion` leaves it optional,\n// and the fallback is the behaviour every existing snapshot has.\nfunction isOnAssembly(\n region: HighlightRegion,\n assemblyNames: string[] | undefined,\n) {\n return (\n region.assemblyName === undefined ||\n assemblyNames === undefined ||\n assemblyNames.includes(region.assemblyName)\n )\n}\n\n// The graph displays in a linear view's own tracks, connected to it by where\n// they sit.\nfunction trackGraphs(view: Record<string, unknown>) {\n const tracks = Array.isArray(view.tracks) ? view.tracks : []\n return tracks.flatMap((track: unknown) =>\n isRecord(track) && Array.isArray(track.displays)\n ? track.displays.filter(\n (display: unknown) =>\n isRecord(display) && display.type === 'LinearGraphDisplay',\n )\n : [],\n ) as Record<string, unknown>[]\n}\n\n// The highlights a linear view should draw for the graph views connected to it.\n// Reads `session.views` structurally: the members it needs are declared by\n// GraphGenomeView, not by the AbstractViewModel the session array is typed as.\nexport function graphViewHighlights(\n views: unknown[],\n linearViewId: string,\n // the drawing view's own assemblies, so a band is only drawn where its\n // coordinates mean something \u2014 see isOnAssembly\n linearAssemblyNames?: string[],\n): GraphViewHighlight[] {\n const highlights: GraphViewHighlight[] = []\n const candidates = withRows(views)\n const liveViewIds = new Set(\n candidates.map(view => (isRecord(view) ? view.id : undefined)),\n )\n for (const view of candidates) {\n if (isRecord(view) && view.id === linearViewId) {\n for (const display of trackGraphs(view)) {\n const region = readRegion(display.hoverHighlight)\n if (region && isOnAssembly(region, linearAssemblyNames)) {\n highlights.push({\n key: typeof display.id === 'string' ? display.id : 'graph-track',\n region,\n })\n }\n }\n }\n if (\n isRecord(view) &&\n view.type === 'GraphGenomeView' &&\n isConnected(view, linearViewId, liveViewIds)\n ) {\n const region = readRegion(view.hoverHighlight)\n if (region && isOnAssembly(region, linearAssemblyNames)) {\n highlights.push({\n key: typeof view.id === 'string' ? view.id : 'graph',\n region,\n })\n }\n }\n }\n return highlights\n}\n", "import { getSession } from '@jbrowse/core/util'\nimport { alpha } from '@mui/material'\nimport { observer } from 'mobx-react'\nimport { makeStyles } from 'tss-react/mui'\n\nimport { graphViewHighlights } from './graphViewHighlights'\n\nimport type { HighlightRegion } from './graphViewHighlights'\nimport type { LinearGenomeViewModel } from '@jbrowse/plugin-linear-genome-view'\n\nconst useStyles = makeStyles()(theme => ({\n highlight: {\n height: '100%',\n position: 'absolute',\n background: alpha(theme.palette.primary.main, 0.08),\n borderLeft: `1px solid ${alpha(theme.palette.primary.main, 0.4)}`,\n borderRight: `1px solid ${alpha(theme.palette.primary.main, 0.4)}`,\n pointerEvents: 'none',\n zIndex: 10,\n },\n}))\n\n// One band over the linear view for a hovered graph node. `getHighlightCoords`\n// is the LGV's own projection \u2014 it canonicalizes the refName and floors the\n// width to 3 px, so a pure insertion (a zero-length reference span) still shows\n// as a mark rather than vanishing.\nconst Highlight = observer(function Highlight({\n model,\n region,\n}: {\n model: LinearGenomeViewModel\n region: HighlightRegion\n}) {\n const { classes } = useStyles()\n const coords = model.getHighlightCoords(region)\n return coords ? (\n <div\n data-testid=\"graph-node-highlight\"\n className={classes.highlight}\n style={{ left: coords.left, width: coords.width }}\n />\n ) : null\n})\n\nconst GraphNodeHighlight = observer(function GraphNodeHighlight({\n model,\n}: {\n model: LinearGenomeViewModel\n}) {\n const { views } = getSession(model)\n return (\n <>\n {graphViewHighlights([...views], model.id, model.assemblyNames).map(\n ({ key, region }) => (\n <Highlight key={`graph-hover-${key}`} model={model} region={region} />\n ),\n )}\n </>\n )\n})\n\nexport default GraphNodeHighlight\n", "import GraphNodeHighlight from './GraphNodeHighlight'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\n\n// The graph-to-linear half of the hover sync. The reverse half needs no mount\n// point: an LGV already publishes its hover to `session.hovered`, and the graph\n// view's own autorun reads it (see GraphGenomeView/pane/renderingActions.ts).\n//\n// Mounted through the extension point rather than imported by the LGV, so this\n// plugin never imports @jbrowse/plugin-linear-genome-view at runtime: it is not\n// one of JBrowse's shared globals, so a value import would bundle a second copy\n// of that whole plugin.\nconst POINT = 'LinearGenomeView-TracksContainerComponent'\n\nexport default function GraphHoverSyncF(pluginManager: PluginManager) {\n pluginManager.contributeToExtensionPoint(POINT, ({ model }) => (\n <GraphNodeHighlight key=\"graphgenomeview-hover-highlight\" model={model} />\n ))\n}\n", "import { DisplayType } from '@jbrowse/core/pluggableElementTypes'\n\nimport { trackAdapterConfig } from './trackAdapterConfig'\nimport { SYNTENY_DISPLAYS } from '../GraphTrack/index'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { IAnyModelType } from '@jbrowse/mobx-state-tree'\n\n// Core's synteny displays send `adapterConfig` with every request, the lane\n// listing's included, so overriding the getter reaches them all\nfunction withTrackAdapterConfig(model: IAnyModelType) {\n return model.views(self => ({\n get adapterConfig(): Record<string, unknown> {\n return trackAdapterConfig(self, self.parentTrack.configuration)\n },\n }))\n}\n\nexport default function PanSNAliasesF(pluginManager: PluginManager) {\n pluginManager.addToExtensionPoint('Core-extendPluggableElement', element => {\n if (\n element instanceof DisplayType &&\n SYNTENY_DISPLAYS.includes(element.name)\n ) {\n element.extendStateModel(withTrackAdapterConfig)\n }\n return element\n })\n}\n", "// The name JBrowse knows this plugin by, which a config's `plugins` entry\n// states beside its `esmUrl`.\nexport const PLUGIN_NAME = 'GraphGenomeView'\n", "export const version = '7.1.13'\n", "import Plugin from '@jbrowse/core/Plugin'\nimport { isAbstractMenuManager } from '@jbrowse/core/util'\nimport BubbleChartIcon from '@mui/icons-material/BubbleChart'\n\nimport GbzBaseSyntenyAdapterF from './GbzBaseSyntenyAdapter/index'\nimport GetGraphHaplotypes from './GetGraphHaplotypes'\nimport GetGraphReads from './GetGraphReads'\nimport GetSubgraph from './GetSubgraph'\nimport GraphAddTrackWorkflowF from './GraphAddTrackWorkflow/index'\nimport GraphComputeLayout from './GraphComputeLayout'\nimport GraphGenomeViewF from './GraphGenomeView/index'\nimport GraphTrackF from './GraphTrack/index'\nimport LaunchGraphGenomeViewF from './LaunchGraphGenomeView'\nimport LinearGraphDisplayF from './LinearGraphDisplay/index'\nimport MinigraphBubbleAdapterF from './MinigraphBubbleAdapter/index'\nimport RgfaTabixAdapterF from './RgfaTabixAdapter/index'\nimport WalkTabixSyntenyAdapterF from './WalkTabixSyntenyAdapter/index'\nimport GraphTrackDefaultsF from './graphTrackDefaults/index'\nimport GraphHoverSyncF from './hoverSync/index'\nimport PanSNAliasesF from './panSNAliases/index'\nimport { PLUGIN_NAME } from './pluginName'\nimport { version } from './version'\n\nimport type PluginManager from '@jbrowse/core/PluginManager'\nimport type { AbstractSessionModel } from '@jbrowse/core/util'\n\nexport default class GraphGenomeViewPlugin extends Plugin {\n name = PLUGIN_NAME\n version = version\n\n install(pluginManager: PluginManager) {\n GraphGenomeViewF(pluginManager)\n LinearGraphDisplayF(pluginManager)\n GraphTrackF(pluginManager)\n LaunchGraphGenomeViewF(pluginManager)\n GraphHoverSyncF(pluginManager)\n RgfaTabixAdapterF(pluginManager)\n MinigraphBubbleAdapterF(pluginManager)\n GbzBaseSyntenyAdapterF(pluginManager)\n WalkTabixSyntenyAdapterF(pluginManager)\n GraphAddTrackWorkflowF(pluginManager)\n GraphTrackDefaultsF(pluginManager)\n PanSNAliasesF(pluginManager)\n pluginManager.addRpcMethod(() => new GraphComputeLayout(pluginManager))\n pluginManager.addRpcMethod(() => new GetSubgraph(pluginManager))\n pluginManager.addRpcMethod(() => new GetGraphReads(pluginManager))\n pluginManager.addRpcMethod(() => new GetGraphHaplotypes(pluginManager))\n }\n\n // A throw from configure() takes the whole session to its error page, and a\n // menu entry is not worth that: hubs 1.0.9 did exactly this to every\n // jbrowse.org/ucsc launch by appending to a menu a released host defines as\n // a function. The view is still reachable without the entry.\n configure(pluginManager: PluginManager) {\n try {\n if (isAbstractMenuManager(pluginManager.rootModel)) {\n pluginManager.rootModel.appendToSubMenu(['Add'], {\n label: 'Graph genome view',\n icon: BubbleChartIcon,\n onClick: (session: AbstractSessionModel) => {\n session.addView('GraphGenomeView', {})\n },\n })\n }\n } catch (e) {\n console.warn('[GraphGenomeView] could not add the Add menu entry', e)\n }\n }\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["host", "Plugin_default", "host", "BubbleChart_default", "createSvgIcon", "jsx", "host", "AdapterType_default", "host", "GbzBaseSyntenyAdapter", "ConfigurationSchema", "fileLocationSlot", "tabixIndexSchema", "types", "GBZ_CUT_DEFAULTS", "snap", "uri", "baseUri", "reads", "readsIndexBeside", "name", "query", "splitUri", "configSchema_default", "GbzBaseSyntenyAdapterF", "pluginManager", "AdapterType_default", "configSchema_default", "r", "host", "read", "name", "AddTrackWorkflowType", "read", "BaseDisplay", "read", "DisplayType", "read", "RpcMethodType", "read", "RpcMethodTypeWithRenameRegion", "TrackType", "read", "createBaseTrackConfig", "read", "createBaseTrackModel", "pluggableElementTypes_default", "host", "host", "read", "name", "getAdapter", "read", "dataAdapterCache_default", "host", "adapterImplementing", "pluginManager", "sessionId", "adapterConfig", "method", "dataAdapter", "getAdapter", "GetGraphHaplotypes", "RpcMethodType", "args", "adapter", "adapterImplementing", "namesReads", "adapterConfig", "snapshotNamesFile", "GetGraphReads", "RpcMethodType", "args", "nodeNames", "signal", "adapter", "adapterImplementing", "host", "read", "name", "rpcResultWithArrayBuffers", "read", "librpc_default", "host", "GetSubgraph", "RpcMethodTypeWithRenameRegion", "args", "region", "opts", "signal", "adapter", "name", "adapterImplementing", "cut", "rpcResultWithArrayBuffers", "tables", "gfaTables", "GraphAddTrackWidget", "lazy", "GraphAddTrackWorkflowF", "pluginManager", "AddTrackWorkflowType", "types", "GraphComputeLayout", "RpcMethodType", "args", "graph", "options", "statusCallback", "layoutEngine", "host", "ViewType_default", "host", "host", "read", "name", "defineLaunchKeys", "withLaunchInput_default", "host", "host", "read", "name", "BaseViewModel", "read", "models_default", "host", "HOVER_HIGHLIGHT_VALUES", "ContentCopy_default", "createSvgIcon", "jsx", "Hub_default", "createSvgIcon", "jsx", "Palette_default", "createSvgIcon", "jsx", "PhotoCamera_default", "createSvgIcon", "jsx", "foldVariants", "graph", "belowBp", "node", "isBackbone", "nodes", "edges", "readForward", "index", "i", "sides", "forwardSides", "links", "linksAt", "allele", "alleleOf", "members", "groupBy", "kept", "big", "group", "alleleContent", "dist", "pred", "distancesFromBackbone", "side", "alleleEnds", "next", "nearestOutside", "keptEdges", "edge", "k", "a", "b", "skip", "skipped", "mergeAlleleRuns", "reversed", "read", "id", "strand", "own", "ownStrand", "complement", "count", "from", "to", "onOneSequence", "sa", "sb", "continues", "aSide", "bSide", "pair", "position", "start", "parent", "_", "find", "length", "refName", "lo", "hi", "oneSequence", "other", "otherSide", "at", "end", "first", "last", "ends", "link", "best", "j", "heap", "MinHeap", "da", "db", "cmp", "top", "d0", "d", "p", "order", "item", "items", "up", "l", "r", "m", "degree", "sideKey", "hasPrev", "internal", "left", "right", "headOf", "outer", "merged", "run", "into", "flip", "step", "mergedNode", "endpoint", "firstSamples", "sum", "depth", "samples", "common", "trimToWindow", "graph", "window", "inWindow", "n", "isBackbone", "overlapsWindow", "paths", "spans", "path", "first", "last", "id", "i", "span", "kept", "trimmed", "stretches", "nodeIds", "e", "trimVisits", "trimOrigins", "visits", "nameOf", "next", "out", "PathVisitsBuilder", "origin", "pathOrigin", "segment", "at", "clipToWindow", "reachBp", "nodes", "node", "from", "to", "start", "end", "bundleRoutes", "graph", "groupOf", "merge", "paths", "steps", "pathSteps", "piecesOf", "path", "i", "pushTo", "pathOrigin", "routeOf", "s", "recordsOf", "walk", "routeRank", "bundles", "pieces", "route", "group", "rank", "key", "bundle", "ordered", "a", "walks", "kept", "keptWalks", "b", "p", "shiftIntoView", "lo", "size", "extent", "margin", "keepInView", "bounds", "view", "onScreen", "left", "top", "MIN_TUBE_Y_SCALE", "NODE_BOX_PAD", "squeeze", "drawing", "usableHeight", "minY", "maxY", "h", "tubeMapFrame", "view", "scaleX", "translateX", "translateY", "yScale", "y", "ty", "columns", "knots", "referenceKnots", "bp", "tx", "warpX", "tubeMapNodeAt", "x", "sx", "sy", "hit", "node", "MAX_SHOWN_BASES", "MIN_PANEL_Y_SCALE", "MAX_LISTED", "listed", "names", "more", "mismatchText", "m", "formatBp", "seq", "shown", "mismatchKindsShown", "picture", "frame", "width", "kinds", "mismatchesLegible", "missing", "mismatchOnScreen", "withTubeMapViews", "withFitViews", "self", "drawing", "tubeMapFrame", "reference", "rulerBoxes", "layoutResult", "last", "referenceBoxes", "boxes", "bp", "tubeMapConnectors", "b", "panels", "field", "panel", "graph", "coarse", "tubeMapPicture", "tubeMapNodeColors", "deviationMarks", "id", "members", "at", "i", "under", "box", "n", "memberAt", "pictures", "node", "boxOf", "walksThrough", "tubeColors", "layout", "titles", "PANEL_GAP", "drawings", "h", "p", "usable", "yScale", "y", "minY", "titleTop", "top", "sy", "v", "r", "batch", "ctx", "canvas", "dpr", "trackedDpr", "paintPanelHover", "drawTubeMapHighlight", "drawLitConnector", "HOVER_BRIGHTEN", "sameJson", "a", "marksInView", "computed", "keys", "reads", "paths", "coloring", "kind", "value", "color", "NO_VALUE_TUBE", "TINTED_TUBES", "PANEL_TUBE", "views", "sx", "tubeMapNodeAt", "connectorAt", "mismatch", "tubeMapMismatchAt", "track", "tubeMapTrackAt", "tube", "read", "mapq", "path", "withSettingActions", "withTubeMapViews", "_settings", "self", "bounds", "view", "t", "keepInView", "keptDomain", "scheme", "colorOfScheme", "error", "message", "ms", "batch", "built", "quality", "engine", "linear", "mode", "hover", "name", "graph", "reanchored", "anchorFromPaths", "forceLayouts", "layer", "on", "withLayer", "show", "spread", "limit", "width", "sizeOfNodeWidth", "bp", "routes", "field", "trackId", "key", "layers", "names", "had", "l", "walk", "shown", "c", "facet", "color", "samples", "groupBy", "viewId", "paired", "withRows", "getSession", "nodeId", "at", "panel", "tube", "was", "walks", "bubble", "inside", "bars", "frame", "row", "r", "node", "segmentAt", "size", "edgeIdx", "panning", "session", "region", "span", "isSessionModelWithWidgets", "nodeOwnLocation", "s", "tx", "ty", "host", "clampZoom", "factor", "centerX", "centerY", "zoomAbout", "entering", "usableHeight", "fittedTranslateY", "fit", "scale", "translateX", "engaging", "previous", "keepsAxis", "onScreen", "scheduleViewportDirty", "isAlive", "VIEWPORT_DEBOUNCE_MS", "requestPositionsDirtyFrame", "morph", "stopMorph", "finishMorph", "running", "before", "next", "canMorph", "motionAllowed", "ends", "nodeStarts", "morphStarts", "starts", "routeStarts", "ids", "id", "blend", "blendInto", "runMorph", "dx", "dy", "positions", "seg", "host", "read", "name", "unzip", "unzip_default", "gfaText", "bytes", "gzipped", "unzip", "walkRowsGraph", "cut", "name", "referencePath", "w", "first", "light", "graph", "loadGraph", "depth", "node", "i", "stubs", "walk", "walkPath", "walkRowLayoutOf", "walks", "region", "backbone", "backboneNodes", "overWindow", "n", "overlapsWindow", "backbonePositions", "walkRowLabels", "walkRowsExtent", "withEngineSettings", "withSettingActions", "self", "engineSettingsOf", "withLoadActions", "loadController", "sampleTableKey", "awaitedRun", "runOf", "callEngine", "request", "run", "rpcManager", "getSession", "getRpcSessionId", "status", "statusMessageText", "computeLayout", "graph", "start", "tubeMap", "TUBE_MAP_MODES", "region", "drawn", "trimToWindow", "coarse", "coarsenTubeMap", "laid", "bundled", "g", "bundleRoutes", "runs", "local", "walkRowLayoutOf", "walkRowsOf", "layoutModeByValue", "withCoarse", "r", "whole", "split", "withTubeMapPanels", "tubeMapPanelGroups", "group", "panel", "graphOfPaths", "settings", "hit", "forceLayouts", "pending", "liveRequest", "liveRequestPending", "layoutError", "laidOutGraph", "walkGeneCache", "dropLayoutOfReplacedGraph", "layoutInto", "isLive", "signal", "computed", "e", "settle", "live", "previous", "before", "loadedReference", "paths", "assemblyWalk", "chooseReferencePath", "parseCut", "source", "name", "referencePath", "parsed", "walkRowsGraph", "loadGraph", "resetCut", "cut", "parseAndLayout", "keepSelection", "readsOf", "foldBelowBp", "alongside", "walkCut", "loaded", "anchored", "anchorFromPaths", "folded", "foldVariants", "clipToWindow", "readsShown", "records", "total", "selected", "names", "n", "b", "bubbleSegmentIds", "id", "reads", "liveLoad", "loadInFlight", "beginLoad", "load", "endLoad", "runLoad", "label", "body", "readFeatures", "adapterConfig", "what", "loadBubbles", "prefix", "bubblePrefix", "features", "f", "end", "longestAlleleLength", "trackFeatures", "trackId", "config", "readConfObject", "annotations", "repeatArraysFrom", "loadAnnotation", "kind", "set", "track", "annotationReads", "flow", "reloadAnnotation", "loadWholeGFA", "text", "abortLoad", "wholeGraph", "dropGraph", "EMPTY_BATCH", "file", "buf", "gfaText", "location", "fileName", "openLocation", "getEnv", "opts", "fetchStart", "regionLabel", "namesReads", "key", "isAlive", "parseSamplesTsv", "fetched", "row", "cacheKey", "genes", "geneModelsFrom", "bubble", "open", "at", "o", "sameBubble", "insides", "parent", "isFeatureLike", "value", "isRecord", "hoveredName", "feature", "name", "readLgvHover", "hovered", "result", "refName", "coord", "coord0", "assemblyName", "hoverInRegion", "hover", "region", "nodeForLgvHover", "nodes", "byName", "byCoord", "node", "isBackbone", "PHASED_ROW", "DOTTED_ROW", "readings", "row", "phased", "dotted", "haplotypeOf", "pathName", "pathOrigin", "walksForRow", "paths", "names", "p", "sample", "haplotype", "walks", "name", "panSNSample", "withRenderingActions", "withLoadActions", "self", "backend", "addDisposer", "autorun", "untracked", "reaction", "grid", "a", "b", "TUBE_MAP_MODES", "key", "hover", "readLgvHover", "getSession", "lightsNode", "region", "graph", "inRegion", "hoverInRegion", "rowWalks", "walksForRow", "nodeForLgvHover", "firstViewport", "scale", "viewport", "paneViewportOf", "built", "contains", "dependOn", "trackedDpr", "EMPTY_BATCH", "geometryStart", "_from", "from", "mode", "trackOf", "reload", "now", "was", "to", "facet", "engine", "ANNOTATION_TRACK_TYPE", "launchTracks", "session", "assemblyName", "first", "wanted", "canonicalAssemblyName", "found", "track", "trackId", "readConfObject", "trackAssemblies", "RocketLaunch_default", "createSvgIcon", "jsx", "pushLaunchItem", "items", "item", "pushLaunchViewMenuItem", "group", "i", "LAUNCH_LABEL", "RocketLaunch_default", "SYNTENY_TRACK_TYPE", "SYNTENY_ADAPTER_CATEGORY", "isSyntenyTrack", "track", "readConfObject", "adapterType", "isStateTreeNode", "pluginManager", "getEnv", "launchableSyntenyTracks", "session", "assemblyNames", "wanted", "found", "trackId", "coverage", "trackAssemblies", "name", "getTrackName", "a", "b", "downloadText", "text", "name", "type", "url", "a", "ENGINE_NAMES", "layoutMenuLabel", "mode", "radioItems", "options", "current", "onPick", "value", "label", "disabled", "withLaunchActions", "withRenderingActions", "self", "target", "session", "getSession", "onReference", "viewId", "showInLinearView", "launchTracks", "highlightInLinearView", "trackId", "launchSyntenyView", "samples", "c", "launchableSyntenyTracks", "disagreeing", "shown", "same", "a", "onClose", "ChooseSamplesDialog", "field", "graph", "table", "column", "splits", "split", "tubeMapPanelGroups", "TUBE_MAP_PANELS", "item", "by", "repeat", "TUBE_MAP_MODES", "TUBE_MAP_FOLDS", "bp", "TUBE_MAP_ROUTES", "layerItem", "layer", "HOVER_HIGHLIGHT_VALUES", "PhotoCamera_default", "svg", "downloadText", "ContentCopy_default", "spec", "e", "picks", "walks", "lifted", "name", "l", "many", "WALK_MENU_ITEMS", "ChooseWalksDialog", "walk", "HighlightColorDialog", "FACET_FIELDS", "COLOR_SCHEMES", "s", "layoutModeByValue", "engine", "Hub_default", "LAYOUT_MODES", "Palette_default", "Visibility_default", "items", "contributors", "reference", "graphLaunchMenuItems", "pushLaunchItem", "GraphPane", "withLaunchActions", "self", "adapter", "configHaplotypes", "region", "track", "reference", "graphReferenceAssembly", "session", "getSession", "offReferenceProblem", "canonicalAssemblyName", "from", "before", "cutsWholeWalks", "layoutModeByValue", "stateModelFactory", "types", "BaseViewModel", "GraphPane", "lenientMaybeEnum", "LAYOUT_MODE_VALUES", "HOVER_HIGHLIGHT_VALUES", "self", "settings", "setBaseWidth", "width", "clearPane", "loadRegion", "region", "fileName", "adapter", "span", "problem", "formatSpanBp", "stated", "session", "getSession", "assemblyManager", "assembly", "canonicalRegion", "location", "from", "isAlive", "addDisposer", "reaction", "layoutModeByValue", "graphLaunchKeys", "defineLaunchKeys", "GraphGenomeViewF", "pluginManager", "ViewType_default", "stateModelFactory", "lazy", "SYNTENY_DISPLAYS", "displaysInOrder", "pluginManager", "displays", "named", "name", "d", "needsLanes", "display", "GraphTrackF", "configSchema", "ConfigurationSchema", "createBaseTrackConfig", "track", "TrackType", "createBaseTrackModel", "LaunchGraphGenomeViewF", "pluginManager", "args", "session", "spec", "host", "DisplayType_default", "host", "host", "read", "name", "trackHeightConfigSchemaFields", "trackHeightConfigSchemaFields_default", "configSchemaFactory", "ConfigurationSchema", "types", "LAYOUT_MODE_VALUES", "HOVER_HIGHLIGHT_VALUES", "trackHeightConfigSchemaFields", "host", "read", "name", "computeSvgReady", "read", "svgReady_default", "host", "host", "TrackHeightMixin_default", "host", "host", "read", "name", "editPlotMenuItems", "plotMenu_default", "host", "host", "read", "name", "computeActivityPhase", "computeDisplayStatusPhase", "read", "displayPhase_default", "host", "denseCovers", "dense", "seen", "span", "VIEWPORT_PROPS", "paneSettings", "pane", "paneBase", "key", "FOLD_PX", "coarseHandover", "coarse", "aboveBpPerPx", "foldBelowBp", "GraphTrackSettingsDialog", "lazy", "stateModelFactory", "configSchema", "types", "BaseDisplay", "TrackHeightMixin_default", "GraphPane", "ConfigurationReference", "lenientOptionalEnum", "LAYOUT_ENGINE_VALUES", "self", "getConf", "adapter", "track", "configHaplotypes", "trackLanes", "bpPerPx", "above", "tier", "want", "had", "seen", "formatSpanBp", "computeSvgReady", "computeDisplayStatusPhase", "computeActivityPhase", "settings", "slot", "value", "setConf", "hops", "haplotypes", "window", "names", "bp", "region", "adapterConfig", "problem", "hostCut", "layoutModeByValue", "margins", "denseCovers", "cutHolds", "cut", "recut", "isAlive", "isNodeLimitError", "from", "hostWindow", "signal", "getSession", "getRpcSessionId", "e", "before", "now", "bounds", "k", "midY", "namesRead", "addDisposer", "reaction", "walkIndexed", "a", "b", "places", "frame", "needs", "FACET_KEY_PX", "blocks", "host", "trackId", "start", "end", "spec", "cutsByHaplotype", "defaults", "lanes", "chosen", "onClose", "opts", "renderGraphTrackSvg", "launches", "pushLaunchItem", "BubbleChart_default", "Route_default", "Settings_default", "editPlotMenuItems", "LinearGraphDisplayF", "pluginManager", "configSchema", "configSchemaFactory", "DisplayType_default", "stateModelFactory", "lazy", "normalizeSnapshot", "snap", "uri", "baseUri", "csi", "tbiBeside", "MinigraphBubbleAdapter", "ConfigurationSchema", "fileLocationSlot", "tabixIndexSchema", "configSchema_default", "MinigraphBubbleAdapterF", "pluginManager", "AdapterType_default", "configSchema_default", "r", "prefixLocations", "snap", "uri", "baseUri", "csi", "tbiBeside", "normalizeSnapshot", "coarse", "walksLocations", "RgfaTabixCoarseTier", "ConfigurationSchema", "fileLocationSlot", "tabixIndexSchema", "RgfaTabixAdapter", "WALK_BUDGETS", "configSchema_default", "RgfaTabixAdapterF", "pluginManager", "AdapterType_default", "configSchema_default", "r", "WalkTabixSyntenyAdapter", "ConfigurationSchema", "fileLocationSlot", "tabixIndexSchema", "WALK_BUDGETS", "walksLocations", "configSchema_default", "WalkTabixSyntenyAdapterF", "pluginManager", "AdapterType_default", "configSchema_default", "r", "GRAPH_ADAPTERS", "isGbzLocation", "loc", "locationName", "withLaneAnchor", "snap", "adapter", "LANE_ADAPTERS", "withWalkReference", "assembly", "sample", "walkFileSample", "guessGraphAdapter", "file", "index", "adapterHint", "guess", "choice", "buildAdapterConfig", "isSegmentsLocation", "WALKS_SUFFIX", "readsSiblings", "GraphTrackDefaultsF", "pluginManager", "next", "adapterName", "readRegion", "value", "region", "isRecord", "refName", "start", "end", "assemblyName", "isConnected", "view", "linearViewId", "liveViewIds", "connectedViewId", "isOnAssembly", "assemblyNames", "trackGraphs", "track", "display", "graphViewHighlights", "views", "linearAssemblyNames", "highlights", "candidates", "withRows", "useStyles", "makeStyles", "theme", "alpha", "Highlight", "observer", "model", "region", "classes", "coords", "jsx", "GraphNodeHighlight", "views", "getSession", "Fragment", "graphViewHighlights", "key", "GraphNodeHighlight_default", "POINT", "GraphHoverSyncF", "pluginManager", "model", "jsx", "GraphNodeHighlight_default", "withTrackAdapterConfig", "model", "self", "trackAdapterConfig", "PanSNAliasesF", "pluginManager", "element", "DisplayType", "SYNTENY_DISPLAYS", "PLUGIN_NAME", "version", "GraphGenomeViewPlugin", "Plugin_default", "PLUGIN_NAME", "version", "pluginManager", "GraphGenomeViewF", "LinearGraphDisplayF", "GraphTrackF", "LaunchGraphGenomeViewF", "GraphHoverSyncF", "RgfaTabixAdapterF", "MinigraphBubbleAdapterF", "GbzBaseSyntenyAdapterF", "WalkTabixSyntenyAdapterF", "GraphAddTrackWorkflowF", "GraphTrackDefaultsF", "PanSNAliasesF", "GraphComputeLayout", "GetSubgraph", "GetGraphReads", "GetGraphHaplotypes", "isAbstractMenuManager", "BubbleChart_default", "session", "e"]
|
|
7
7
|
}
|