# LGVSyntenyDisplay

Auto-generated @jbrowse/mobx-state-tree API for the current JBrowse release —
see [pluggable elements](https://jbrowse.org/jb2-staging/docs/developer_guide/) for concepts. Provided by the
`linear-comparative-view` plugin.
[View source](https://github.com/GMOD/jbrowse-components/blob/main/plugins/linear-comparative-view/src/LGVSyntenyDisplay/model.ts).

## Example usage

Shows a `SyntenyTrack`'s alignments in a plain linear view (rather than the
two-row synteny view). Same track config as a synteny track — just pick this
display type:

```js
{
  type: 'SyntenyTrack',
  trackId: 'hg38_vs_mm10',
  name: 'hg38 vs mm10',
  assemblyNames: ['hg38', 'mm10'],
  adapter: {
    type: 'PAFAdapter',
    uri: 'https://example.com/hg38_vs_mm10.paf',
    queryAssembly: 'hg38',
    targetAssembly: 'mm10',
  },
  displays: [
    {
      type: 'LGVSyntenyDisplay',
      displayId: 'hg38_vs_mm10-LGVSyntenyDisplay',
    },
  ],
}
```

displays location of "synteny" feature in a plain LGV, allowing linking out to
external synteny views

The configuration slots for this model are documented on its
[config schema page](../../config/lgvsyntenydisplay).

Members a composed model contributes are listed here too, so these tables are
the whole surface.

## Properties

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="property-type">**type**</span><br><code>type: types.literal('LGVSyntenyDisplay')</code> |  | LGVSyntenyDisplay |
| <span id="property-configuration">**configuration**</span><br><code>configuration: ConfigurationReference(schema)</code> |  | LGVSyntenyDisplay |
| <span id="property-lodmode">**lodMode**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>lodMode: types.stripDefault( types.enumeration('LodMode', ['aut…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>lodMode: types.stripDefault(&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;types.enumeration('LodMode', ['auto', 'fine', 'coarse']),&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;'auto',&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;)</code></pre></dialog></span> | Level-of-detail tier selection for tiered PIF adapters. 'auto' uses the adapter's bpPerPx threshold; 'fine' pins the per-row CIGAR tier (t/q); 'coarse' the no-CIGAR tier (T/Q). Matches the synteny view and dotplot setting of the same name — this display draws the same tracks and had no way to pin a tier. | LGVSyntenyDisplay |
| <span id="property-id">**id**</span><br><code>id: ElementId</code> |  | [BaseDisplay](../basedisplay#property-id) |

## Volatiles

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="volatile-debugarcgeometry">**debugArcGeometry**</span><br><code>debugArcGeometry: false</code> | <span data-pagefind-ignore>Draws the arc band's own geometry over the canvas — see `ArcDebugOverlay`. Volatile rather than a config slot: it is a diagnostic for "why is this arc this shape", not a display setting, so it should not survive into a saved session or a shared link.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-debugarcgeometry) |
| <span id="volatile-featureidundermouse">**featureIdUnderMouse**</span><br><code>featureIdUnderMouse: undefined as undefined &#124; string</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-featureidundermouse) |
| <span id="volatile-mouseoverextrainformation">**mouseoverExtraInformation**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>mouseoverExtraInformation: undefined as TooltipPayload &#124; undefi…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>mouseoverExtraInformation: undefined as TooltipPayload &#124; undefined</code></pre></dialog></span> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-mouseoverextrainformation) |
| <span id="volatile-contextmenufeature">**contextMenuFeature**</span><br><code>contextMenuFeature: undefined as Feature &#124; undefined</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-contextmenufeature) |
| <span id="volatile-contextmenufeatureid">**contextMenuFeatureId**</span><br><code>contextMenuFeatureId: undefined as string &#124; undefined</code> | <span data-pagefind-ignore>The read/feature id under a right-click, known synchronously (the hit test carries it) unlike `contextMenuFeature`, which only lands after an RPC. A menu item that can act from the id alone — or fetch the feature in its own onClick — reads this, so it doesn't blink into existence a fetch later.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-contextmenufeatureid) |
| <span id="volatile-contextmenuanchor">**contextMenuAnchor**</span><br><code>contextMenuAnchor: undefined as ContextMenuAnchor &#124; undefined</code> | <span data-pagefind-ignore>Viewport point the right-click menu opens at, and the single "is the menu open" flag. Undefined = closed.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-contextmenuanchor) |
| <span id="volatile-contextmenuhit">**contextMenuHit**</span><br><code>contextMenuHit: undefined as ContextMenuHit &#124; undefined</code> | <span data-pagefind-ignore>Everything the right-click's hit test resolved — the block, the clicked column, and whichever mark answered — as one value, so a consumer can't read a block without its hit and closing the menu can't forget a field. See `ContextMenuHit`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-contextmenuhit) |
| <span id="volatile-rpcdatamap">**rpcDataMap**</span><br><code>rpcDataMap: regionDataMap&lt;GroupedAlignmentsResult&gt;('rpcDataMap')</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-rpcdatamap) |
| <span id="volatile-scrolltop">**scrollTop**</span><br><code>scrollTop: 0</code> | <span data-pagefind-ignore>pileup vertical scroll offset in px. Also read by the BreakpointSplitView overlay to position its SVG curves.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-scrolltop) |
| <span id="volatile-collapsedgroups">**collapsedGroups**</span><br><code>collapsedGroups: observable.set&lt;string&gt;()</code> | <span data-pagefind-ignore>Group keys whose pileup is collapsed to just its coverage band (in-track grouping). Keyed by group key so it survives re-fetches; volatile so it resets on reload. A key means nothing outside the grouping that issued it — `''` is the ungrouped lane AND several dimensions' catch-all bucket — so the whole set is dropped when `groupKeySpace` moves (`AlignmentsGroupKeySpaceReset`).</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-collapsedgroups) |
| <span id="volatile-groupmaxheightoverrides">**groupMaxHeightOverrides**</span><br><code>groupMaxHeightOverrides: observable.map&lt;string, number&gt;()</code> | <span data-pagefind-ignore>Per-group pileup height override in px (in-track grouping). Keyed by group key, volatile like `collapsedGroups` and dropped alongside it on a key-space change; absent keys fall back to the display-wide `maxHeight`. Lets a dense section be shrunk independently.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-groupmaxheightoverrides) |
| <span id="volatile-fittedheightpx">**fittedHeightPx**</span><br><code>fittedHeightPx: 0</code> | <span data-pagefind-ignore>Cache of the current fitted read height in px, kept in sync by the afterAttach autorun while `fitHeightToDisplay` is on. A volatile (not a getter) because the fit height derives from late layout getters that the early `featureHeight` getter can't reference — the autorun bridges that ordering. 0 until first computed / when nothing fits.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-fittedheightpx) |
| <span id="volatile-highlightedchainreadids">**highlightedChainReadIds**</span><br><code>highlightedChainReadIds: [] as string[]</code> | <span data-pagefind-ignore>Read ids of the chain under the cursor — NOT chain ids; see `readIdsByChainName`, which is where they come from.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-highlightedchainreadids) |
| <span id="volatile-selectedchainreadids">**selectedChainReadIds**</span><br><code>selectedChainReadIds: [] as string[]</code> | <span data-pagefind-ignore>Read ids of the clicked chain. Same id space as the hover set above.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-selectedchainreadids) |
| <span id="volatile-overcigaritem">**overCigarItem**</span><br><code>overCigarItem: false</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-overcigaritem) |
| <span id="volatile-hovercoverageband">**hoverCoverageBand**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>hoverCoverageBand: undefined as &#124; { topOffset: number; coverage…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>hoverCoverageBand: undefined as&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#124; { topOffset: number; coverageHeight: number }&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#124; undefined</code></pre></dialog></span> | <span data-pagefind-ignore>Screen-px coverage band of the section currently under a coverage/indicator hover. Drives the tooltip's vertical hover bar so it lands on the hovered group's coverage band, not always the top one. `undefined` when not hovering coverage.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-hovercoverageband) |
| <span id="volatile-hoveredarchighlight">**hoveredArcHighlight**</span><br><code>hoveredArcHighlight: undefined as ArcHighlight &#124; undefined</code> | <span data-pagefind-ignore>The read-connection arc under the cursor, as the ink to draw over it — `ArcHoverOverlay`'s whole input. A SNAPSHOT, resolved at the mousemove that found the arc, exactly like the tooltip it appears with: both describe where the cursor was, and both refresh on the next move. `undefined` when not on an arc.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#volatile-hoveredarchighlight) |
| <span id="volatile-error">**error**</span><br><code>error: undefined as unknown</code> |  | [BaseDisplay](../basedisplay#volatile-error) |
| <span id="volatile-statusmessage">**statusMessage**</span><br><code>statusMessage: undefined as string &#124; undefined</code> |  | [BaseDisplay](../basedisplay#volatile-statusmessage) |
| <span id="volatile-statusprogress">**statusProgress**</span><br><code>statusProgress: undefined as number &#124; undefined</code> | <span data-pagefind-ignore>determinate progress fraction [0,1] for the current status, or undefined when the in-flight phase is indeterminate. Set alongside `statusMessage` by `setStatusMessage`; a display that never shows a bar simply leaves it undefined.</span> | [BaseDisplay](../basedisplay#volatile-statusprogress) |
| <span id="volatile-loadedregions">**loadedRegions**</span><br><code>loadedRegions: regionDataMap&lt;LoadedRegion&gt;('loadedRegions')</code> | <span data-pagefind-ignore>regions whose data has been fetched and committed, keyed by displayedRegionIndex; populated only after the fetch work callback returns</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#volatile-loadedregions) |
| <span id="volatile-forceloadtrack">**forceLoadTrack**</span><br><code>forceLoadTrack: false</code> | <span data-pagefind-ignore>The force-load button's track-wide approval. Volatile so it never reaches a saved session; the `forceLoad` config slot is the durable form.</span> | [RegionTooLargeMixin](../regiontoolargemixin#volatile-forceloadtrack) |
| <span id="volatile-byteestimate">**byteEstimate**</span><br><code>byteEstimate: undefined as ByteEstimate &#124; undefined</code> | <span data-pagefind-ignore>The last byte measurement: bytes, the span they were taken at, and whether zooming has been shown not to shrink them. Survives `clearAllRpcData`; dropped on chromosome navigation and on a tier swap.</span> | [RegionTooLargeMixin](../regiontoolargemixin#volatile-byteestimate) |
| <span id="volatile-gatemeasuredviewportkey">**gateMeasuredViewportKey**</span><br><code>gateMeasuredViewportKey: undefined as string &#124; undefined</code> | <span data-pagefind-ignore>The viewport key the gate last asked the adapter about, on either axis. Separate from `byteEstimate` because a density refusal measures no bytes.</span> | [RegionTooLargeMixin](../regiontoolargemixin#volatile-gatemeasuredviewportkey) |
| <span id="volatile-canvasdrawn">**canvasDrawn**</span><br><code>canvasDrawn: false</code> | <span data-pagefind-ignore>flips true on first paint; read by test selectors to detect render</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-canvasdrawn) |
| <span id="volatile-currentrenderingbackend">**currentRenderingBackend**</span><br><code>currentRenderingBackend: undefined</code> | <span data-pagefind-ignore>current backend reference, updated on context-loss recovery. Typed `unknown` (not generic `B`) on purpose: this mixin is composed by every display via a non-generic factory, so the per-display backend type `B` isn't known here — it's supplied at `attachRenderingBackend<B>` and narrowed with `as B` inside the autoruns. Don't "fix" the cast.</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-currentrenderingbackend) |
| <span id="volatile-rendertick">**renderTick**</span><br><code>renderTick: 0</code> | <span data-pagefind-ignore>counter the render autorun observes; bumped to force a re-render</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-rendertick) |
| <span id="volatile-autorunsinstalled">**autorunsInstalled**</span><br><code>autorunsInstalled: false</code> | <span data-pagefind-ignore>guards attachRenderingBackend so the autorun pair spawns once per instance</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-autorunsinstalled) |
| <span id="volatile-rendererror">**renderError**</span><br><code>renderError: undefined</code> | <span data-pagefind-ignore>the render-backend (GPU/Canvas2D init or context-loss) error, or undefined. Single source of truth for the render-error terminal state: `useRenderingBackend` writes it from the canvas-init mechanism so the model — not React-local hook state — owns every terminal state. Read by `displayPhase` (whose `renderError` term outranks `loading`, suppressing the scrim) and by `DisplayChrome` (shows the retry overlay).</span> | [RenderLifecycleMixin](../renderlifecyclemixin#volatile-rendererror) |
| <span id="volatile-activestoptoken">**activeStopToken**</span><br><code>activeStopToken: undefined as StopToken &#124; undefined</code> | <span data-pagefind-ignore>stop token of the in-flight fetch, or undefined when idle</span> | [FetchMixin](../fetchmixin#volatile-activestoptoken) |
| <span id="volatile-fetchgeneration">**fetchGeneration**</span><br><code>fetchGeneration: 0</code> | <span data-pagefind-ignore>bumps at every fetch end; autoruns read it to re-evaluate, and it doubles as the staleness epoch inside runFetch</span> | [FetchMixin](../fetchmixin#volatile-fetchgeneration) |
| <span id="volatile-reloadcounter">**reloadCounter**</span><br><code>reloadCounter: 0</code> | <span data-pagefind-ignore>Bumped by `reload()` and read unconditionally by the fetch autoruns, so a user retry re-runs the body even where nothing else moved — after an error every other fetch input is unchanged. It is also the half that survives a `reload()` override that forgets to invalidate, which is the dead Retry button `makeRetryContractCheck` reports. Declared here because this is the one mixin both LGV fetch foundations compose, the same argument that put `fetchInert` below; the comparative family carries its own on `SyntenyFetchStateMixin` (ADR-054).</span> | [FetchMixin](../fetchmixin#volatile-reloadcounter) |
| <span id="volatile-statuswindow">**statusWindow**</span><br><code>statusWindow: createStatusWindow(writeStatus(self))</code> | <span data-pagefind-ignore>This display's status field, and the only thing that writes it: one throttle window, one slot per concurrent operation, so N parallel per-region fetches thin to one stream between them rather than N and a second operation cannot end the first one's label (ADR-081). Lent whole to `createStopTokenRotation` by a display that also runs a bare-autorun fetch — see `StatusReporter`.</span> | [FetchMixin](../fetchmixin#volatile-statuswindow) |
| <span id="volatile-fetchcanceled">**fetchCanceled**</span><br><code>fetchCanceled: false</code> | <span data-pagefind-ignore>true after the user explicitly cancels a load (the loading overlay's cancel button → `cancelFetchByUser`). A durable, blocking state — unlike `cancelFetch`, it does not retrigger the fetch autoruns — so the load stays stopped until the user retries (`reload`) or the viewport changes. Any new fetch clears it (`runFetch` resets it at the start).</span> | [FetchMixin](../fetchmixin#volatile-fetchcanceled) |
| <span id="volatile-fetchrotation">**fetchRotation**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>fetchRotation: createStopTokenRotation(self, { statusWindow: se…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>fetchRotation: createStopTokenRotation(self, {&#10;&#160;&#160;&#160;&#160;&#160;&#160;&#160;&#160;statusWindow: self.statusWindow,&#10;&#160;&#160;&#160;&#160;&#160;&#160;})</code></pre></dialog></span> | <span data-pagefind-ignore>**The latest-wins machine this mixin is a wrapper around**, and not a second one: `createStopTokenRotation` owns token rotation, the `isCurrent` guard, the status slot and the supersede-versus-end rule (ADR-080, ADR-081), for every fetch in the codebase that has one. `runFetch` adds the observable bookkeeping a display needs on top — `isLoading`, `error`, `fetchGeneration`, `fetchCanceled` — and nothing else.<br><br>It was two implementations of that machine until 2026-08-20, which is how they came to disagree about whether a completed fetch releases its token. A display's *primary* fetch is this wrapper; a second concurrent fetch on the same node holds a rotation of its own, which is why the primitive is the thing that exists and this is the thing built on it (ADR-054 §1).<br><br>It is lent this display's `statusWindow`, so the fetch takes a slot on the one field rather than opening a second window over it — the whole point of `StatusReporter`.</span> | [FetchMixin](../fetchmixin#volatile-fetchrotation) |

## Getters

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="getter-featurewidgettype">**featureWidgetType**</span><br><code>{ type: string; id: string; }</code> | synteny features open the SyntenyFeatureWidget; the inherited `selectFeature` action reads this getter, so no override is needed. | LGVSyntenyDisplay |
| <span id="getter-featurenoun">**featureNoun**</span><br><code>string</code> | A row here is a PAF block, not a read — the group-label chips say "Show all features". The ONE place that word is chosen: the two menu builders below that take a `noun` read it from here rather than spelling it again, so the chips and the menus cannot end up naming the same row two different things. | LGVSyntenyDisplay |
| <span id="getter-derivativepathevidence">**derivativePathEvidence**</span><br><code>DerivativePathEvidence</code> | A chain here is one contig's blocks, and an assembly carries one or two contigs across a locus, so one is a route. Nothing names a block the view has not fetched (a PAF line has no SA tag), so a route is only what is on screen. | LGVSyntenyDisplay |
| <span id="getter-hideselfalignments">**hideSelfAlignments**</span><br><code>boolean</code> | Whether the view's own assembly lane is hidden — see the slot. | LGVSyntenyDisplay |
| <span id="getter-hiddengroupkeys">**hiddenGroupKeys**</span><br><code>ReadonlySet&lt;string&gt;</code> | The lane an all-vs-all track draws for the view's own assembly: its mate-assembly group key IS that assembly name. Hidden as a group key rather than filtered out of the fetch, so unchecking the option shows it again without a refetch.<br><br>The key is the name the adapter resolved out of the track's `assemblyNames`, and the view may spell the same assembly another way, so every declared name that is this assembly goes in beside the view's own. | LGVSyntenyDisplay |
| <span id="getter-haslodcapableadapter">**hasLodCapableAdapter**</span><br><code>boolean</code> | Whether this track's adapter has tiered storage to switch between — gates the "Level of detail" menu. | LGVSyntenyDisplay |
| <span id="getter-lodtier">**lodTier**</span><br><code>LodTier</code> | The tier this display's fetch asks for. Resolved here, on the main thread, so it lands in `rpcProps` — which is the refetch cache key, so a tier flip trips a refetch and a mid-zoom threshold crossing cannot go unnoticed. Forwarding a raw `bpPerPx` instead would invalidate every fetch on every zoom step; this changes only when the tier flips. | LGVSyntenyDisplay |
| <span id="getter-linkedreads">**linkedReads**</span><br><code>"normal" &#124; "off"</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-linkedreads) |
| <span id="getter-pairsdisplaytypedefault">**pairsDisplayTypeDefault**</span><br><code>Pin</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-pairsdisplaytypedefault) |
| <span id="getter-showbezierconnections">**showBezierConnections**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showbezierconnections) |
| <span id="getter-showcoverage">**showCoverage**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showcoverage) |
| <span id="getter-showpileup">**showPileup**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showpileup) |
| <span id="getter-coverageheight">**coverageHeight**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-coverageheight) |
| <span id="getter-coveragesnpminfrequency">**coverageSnpMinFrequency**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-coveragesnpminfrequency) |
| <span id="getter-showmismatches">**showMismatches**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showmismatches) |
| <span id="getter-showinterbaseindicators">**showInterbaseIndicators**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showinterbaseindicators) |
| <span id="getter-flipstrandlongreadchains">**flipStrandLongReadChains**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-flipstrandlongreadchains) |
| <span id="getter-colorsupplementarychains">**colorSupplementaryChains**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-colorsupplementarychains) |
| <span id="getter-drawinter">**drawInter**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-drawinter) |
| <span id="getter-drawproperpairarcs">**drawProperPairArcs**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether ordinary concordant pairs get an arc. Same definition of concordant as `filterBy.properPairs`, which hides the reads themselves — see `isConcordantPairRead`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-drawproperpairarcs) |
| <span id="getter-mininterchromsupport">**minInterchromSupport**</span><br><code>number</code> | <span data-pagefind-ignore>Reads a translocation must gather, within one fragment length on both sides, before its connector ticks are drawn. See `clusteredInterchromSupport` — the count is over a window because a mate-pair breakpoint is not localized to a base.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-mininterchromsupport) |
| <span id="getter-drawlongrange">**drawLongRange**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-drawlongrange) |
| <span id="getter-arccolorbytype">**arcColorByType**</span><br><code>"insertSize" &#124; "insertSizeAndOrientation" &#124; "orientation"</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-arccolorbytype) |
| <span id="getter-readconnections">**readConnections**</span><br><code>"arc" &#124; "cloud" &#124; "off"</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readconnections) |
| <span id="getter-arcsdisplaytypedefault">**arcsDisplayTypeDefault**</span><br><code>Pin</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-arcsdisplaytypedefault) |
| <span id="getter-readclouddisplaytypedefault">**readCloudDisplayTypeDefault**</span><br><code>Pin</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readclouddisplaytypedefault) |
| <span id="getter-readconnectionsdown">**readConnectionsDown**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readconnectionsdown) |
| <span id="getter-readconnectionsdowndisplaytypedefault">**readConnectionsDownDisplayTypeDefault**</span><br><code>Pin</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readconnectionsdowndisplaytypedefault) |
| <span id="getter-showsashimiarcs">**showSashimiArcs**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showsashimiarcs) |
| <span id="getter-showsashimiarcsdisplaytypedefault">**showSashimiArcsDisplayTypeDefault**</span><br><code>Pin</code> | <span data-pagefind-ignore>"make the current sashimi on/off state the default for all tracks" control (pin) for the submenu's own checkbox.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showsashimiarcsdisplaytypedefault) |
| <span id="getter-sashimiarcsmode">**sashimiArcsMode**</span><br><code>"auto" &#124; "down" &#124; "up"</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sashimiarcsmode) |
| <span id="getter-minsashimiscore">**minSashimiScore**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-minsashimiscore) |
| <span id="getter-sashimiarcsheight">**sashimiArcsHeight**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sashimiarcsheight) |
| <span id="getter-readconnectionsheight">**readConnectionsHeight**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readconnectionsheight) |
| <span id="getter-showsoftclipping">**showSoftClipping**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showsoftclipping) |
| <span id="getter-softclippingdisplaytypedefault">**softClippingDisplayTypeDefault**</span><br><code>Pin</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-softclippingdisplaytypedefault) |
| <span id="getter-view">**view**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>ModelInstanceTypeProps&lt;_OverrideProps&lt;_OverrideProps&lt;…&gt;, { ...;…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>ModelInstanceTypeProps&lt;_OverrideProps&lt;_OverrideProps&lt;…&gt;, { ...; }&gt;&gt; &amp; ... 25 more ... &amp; IStateTreeNode&lt;...&gt;</code></pre></dialog></span> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-view) |
| <span id="getter-ischainmode">**isChainMode**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-ischainmode) |
| <span id="getter-showlinkedreadlines">**showLinkedReadLines**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether to draw the straight-line pass connecting normal read-pairs in pileup layout. Only meaningful when bezier connections are on AND we are in pileup mode — chain layout has its own connecting-line pass that already covers normal pairs WITHIN a region. Neither pass reaches across one (both are per region, one buffer each); that is `bezierArcScope`'s `crossRegion`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showlinkedreadlines) |
| <span id="getter-selectedfeatureid">**selectedFeatureId**</span><br><code>string &#124; undefined</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-selectedfeatureid) |
| <span id="getter-tooltipcomponent">**TooltipComponent**</span><br><code>LazyExoticComponent&lt;…&gt;</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-tooltipcomponent) |
| <span id="getter-detectedmodifications">**detectedModifications**</span><br><code>ReadonlyMap&lt;string, string&gt;</code> | <span data-pagefind-ignore>Modification type code -> painted color, for every type the reads of the LOADED regions declare. This is what the data CONTAINS; what is actually drawn is filtered separately by isModificationTypeVisible and by `presentModifications`, so don't rename this back to "visible".<br><br>Derived rather than accumulated, which is the whole point: it used to be a volatile map that `setRpcData` added to and nothing ever cleared, so it grew for the life of the tab and answered for every locus the user had ever visited. The legend was narrowed off it after the fact; the menu was not, and offered 6mA on a region carrying none.<br><br>Off `rpcDataMap` rather than the laid-out map, on purpose. This one is about what the DATA holds — a type belonging to a hidden group is still a type the user can reveal — and the menu is what asks. The legend, which must not name a color no visible read paints, asks `presentModifications` instead.<br><br>Cheap despite running per fetch: the MM parse reports a handful of type codes per group, so this is O(regions x groups) over arrays of ~1-3 strings, and MobX memoizes it against `rpcDataMap`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-detectedmodifications) |
| <span id="getter-modificationsready">**modificationsReady**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the MM/ML header parse has an answer for what is on screen — a fetch has landed, so an empty `detectedModifications` means "these reads carry none" rather than "nothing has arrived yet". The modifications menu shows "Loading modifications..." until this turns true, and offers the submenu after.<br><br>Derived, like the map it qualifies. It was a volatile flag that `fetchNeeded` set true and nothing ever set back, so it outlived the data it described: after `clearDisplaySpecificData` it still claimed an answer for reads that were no longer loaded, and the menu skipped "Loading modifications..." while the replacing fetch was in flight. Reading the data is what the flag was always trying to say.<br><br>The header parse is ungated (`extractModifications` reads MM headers for every read whatever the scheme, and only mark PLACEMENT is scheme-gated), so arrival of any fetch really does settle this.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-modificationsready) |
| <span id="getter-detectedmodificationtypes">**detectedModificationTypes**</span><br><code>string[]</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-detectedmodificationtypes) |
| <span id="getter-colorby">**colorBy**</span><br><code>ColorBy</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-colorby) |
| <span id="getter-filterby">**filterBy**</span><br><code>FilterBy</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-filterby) |
| <span id="getter-isfitting">**isFitting**</span><br><code>boolean</code> | <span data-pagefind-ignore>True when fit-to-display mode is on AND a pitch has been computed (`fittedHeightPx > 0`, i.e. there are rows and room to fit them). The single gate both size getters read, so it's obvious they either both split the fitted pitch or both fall back to config — never a mix.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-isfitting) |
| <span id="getter-featureheight">**featureHeight**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-featureheight) |
| <span id="getter-featurespacing">**featureSpacing**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-featurespacing) |
| <span id="getter-rowheight">**rowHeight**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-rowheight) |
| <span id="getter-configuredfeatureheight">**configuredFeatureHeight**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-configuredfeatureheight) |
| <span id="getter-maxheight">**maxHeight**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-maxheight) |
| <span id="getter-showsashimilabels">**showSashimiLabels**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether to draw the supporting-read count on each sashimi arc. Resolved through the promotable-slot tiers (resolveConf): an explicit track value pins labels on or off; otherwise it follows the session-wide default, falling back to off. A `maybeBoolean` slot, so (like mismatchAlpha) a session default of "on" can be customized back off on a single track.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showsashimilabels) |
| <span id="getter-showsashimilabelsdisplaytypedefault">**showSashimiLabelsDisplayTypeDefault**</span><br><code>Pin</code> | <span data-pagefind-ignore>"make the current sashimi-label state the default for all tracks" control (pin): symmetric, so it promotes whichever value the track currently shows.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showsashimilabelsdisplaytypedefault) |
| <span id="getter-hidenoncanonicaljunctions">**hideNonCanonicalJunctions**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether junctions with a non-canonical splice motif are dropped from the sashimi arcs. Promotable like `showSashimiLabels`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-hidenoncanonicaljunctions) |
| <span id="getter-hidenoncanonicaljunctionsdisplaytypedefault">**hideNonCanonicalJunctionsDisplayTypeDefault**</span><br><code>Pin</code> | <span data-pagefind-ignore>"make the current non-canonical filter state the default for all tracks" control (pin).</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-hidenoncanonicaljunctionsdisplaytypedefault) |
| <span id="getter-readidsbychainname">**readIdsByChainName**</span><br><code>Map&lt;string, string[]&gt;</code> | <span data-pagefind-ignore>Chain name → the ids of the READS in it. The two id spaces are easy to confuse and nothing else in this model crosses them: `chainNames` (the key here) is a chain's own identity, `readIds` (the values) are the reads', and every consumer of this map resolves the values through `readIdToIndex` / `readIdIndexMap`. Hence the names carried downstream — `highlightedChainReadIds`, `selectedChainReadIds`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readidsbychainname) |
| <span id="getter-showlowfreqmismatches">**showLowFreqMismatches**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showlowfreqmismatches) |
| <span id="getter-filtermismatchesbyfrequency">**filterMismatchesByFrequency**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-filtermismatchesbyfrequency) |
| <span id="getter-mismatchalpha">**mismatchAlpha**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-mismatchalpha) |
| <span id="getter-mismatchalphadisplaytypedefault">**mismatchAlphaDisplayTypeDefault**</span><br><code>Pin</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-mismatchalphadisplaytypedefault) |
| <span id="getter-sortedby">**sortedBy**</span><br><code>SortedBy &#124; undefined</code> | <span data-pagefind-ignore>The single read of the `sortedBy` slot, so the RPC args and the menu checkmarks cannot disagree about which sort is active.<br><br>The refName is normalized here because this slot has two provenances and only one of them is safe. `setSortedByAtPosition` (the center-line "Sort by..." menu) writes a refName taken off the view's own region, canonical by construction; a config or session spec writes whatever the author typed. `sortLayout` gates the sort on `commonRefName === sortedBy.refName` against the loaded regions, so an aliased spec (`chr1` where the assembly is canonicalized `1`) leaves the reads unsorted with the menu still showing the sort as active.<br><br>A sort names a genomic COLUMN — a refName AND a position — so a slot carrying neither half is no sort rather than a broken one, and this getter's `SortedBy` says both are there. The slot is `frozen`, so a config or session spec can put anything in it, and the two halves fail differently: a missing refName reaches `canonicalizeViewRefName`, which lower-cases what it is handed, so it threw a TypeError out of a getter the fetch autorun and the render both read — the whole track replaced by an error over a typo in a spec. A missing `pos` merely compares false against every read and sorts nothing, which is the same answer this now gives explicitly.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sortedby) |
| <span id="getter-largefeaturesfirst">**largeFeaturesFirst**</span><br><code>boolean</code> | <span data-pagefind-ignore>Lay out the widest features in the lowest pileup rows (main-thread tier-2 relayout via laidOutPileupMap). LGVSyntenyDisplay defaults it on. Ignored while an explicit `sortedBy` position sort is active.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-largefeaturesfirst) |
| <span id="getter-splicedreadsfirst">**splicedReadsFirst**</span><br><code>boolean</code> | <span data-pagefind-ignore>Lay out reads whose CIGAR carries a skip in the lowest pileup rows (tier-2 relayout). Ignored while an explicit `sortedBy` position sort is active.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-splicedreadsfirst) |
| <span id="getter-groupby">**groupBy**</span><br><code>GroupBy &#124; undefined</code> | <span data-pagefind-ignore>In-track stacked grouping dimension (undefined = ungrouped). Falls back to the `groupBy` config slot, so a track can be pre-grouped declaratively. Sent to the worker via rpcProps; the worker partitions one fetch into N sections. The slot is `frozen` (unvalidated JSON), so `normalizeGroupBy` is the chokepoint that keeps an unrecognized type or a tag grouping with no tag name from reaching the worker.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-groupby) |
| <span id="getter-effectivegroupby">**effectiveGroupBy**</span><br><code>GroupBy &#124; undefined</code> | <span data-pagefind-ignore>The grouping the fetch will actually partition by, which is what the worker resolves too (`executeRenderAlignmentData`): chain mode degrades a per-read dimension to ungrouped without the slot moving, so the slot alone never says which sections come back.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-effectivegroupby) |
| <span id="getter-groupkeyspace">**groupKeySpace**</span><br><code>string</code> | <span data-pagefind-ignore>Identity of the key space the fetched group keys live in, and so of every collection this model keys by group key — see `groupKeySpaceOf` for why a key alone cannot name its grouping.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-groupkeyspace) |
| <span id="getter-prefersoffset">**prefersOffset**</span><br><code>boolean</code> | <span data-pagefind-ignore>Offset the track label above the visualization when grouping, so the stacked group sections aren't hidden behind an overlapping label.<br><br>Asks whether the grouping will be HONORED, not merely whether it is set: chain mode drops a per-read dimension (`groupByForMode`), and reserving label room for sections that then never get drawn leaves dead space above the plot. Unlike `showsGroupLabels` this can't read the fetched sections — the track label is positioned before any data arrives, and flipping once it lands would jump the layout — but the degradation is decidable from the two settings alone, so no data is needed.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-prefersoffset) |
| <span id="getter-collapsegrouprows">**collapseGroupRows**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether each group draws as a single row, its overlap depth carried by the tint layer rather than by stacking — "is the collapse IN EFFECT". Reads `canCollapseGroupRows` rather than the slot alone, because the slot can be a track-config default (LGVSyntenyDisplay sets one) that either of that getter's conditions leaves inert: ungrouped it would flatten the whole pileup onto one row, and chain mode lays true stacks whatever the slot says (`collapsesRows`). Chain mode is reachable with the slot already ticked and drops the menu row that would untick it, so the two have to agree — the label chip words its height button off this getter.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-collapsegrouprows) |
| <span id="getter-cancollapsegrouprows">**canCollapseGroupRows**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether collapsing can take effect at all, and so whether the "Show..." menu offers the toggle: the grouping has to be honored, and chain mode never collapses (`collapsesRows`) because a chain row is a chain and one row would drop the connecting lines the mode exists for. The menu omits the row rather than showing it disabled, since a click would write a slot no getter reads.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-cancollapsegrouprows) |
| <span id="getter-sortreadsblockedreason">**sortReadsBlockedReason**</span><br><code>string &#124; undefined</code> | <span data-pagefind-ignore>Why an explicit read ordering cannot take effect, or `undefined` when it can — one value carrying both the gate and the copy that names the switch, so a surface cannot grey a control out without saying which setting brings it back, and the two reasons cannot get out of step with the condition that produced them.<br><br>There has to be a pileup to order, and chain layout is handed neither `sortedBy` nor `largeFeaturesFirst` (`buildLaidOutChainMap` takes neither) because its rows are chains, ordered by chain distance. Without this a chain-mode sort was a silent no-op, and the tag mode additionally refetched the region to extract `sortTagValues` (it is in `rpcProps`) that nothing reads.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sortreadsblockedreason) |
| <span id="getter-cansortreads">**canSortReads**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether an explicit read ordering can take effect, and so whether the ordering controls are live. The sibling of `canCollapseGroupRows`, and read by both surfaces that can set an ordering — the track menu's "Sort by..." and the context menu's position-anchored sorts — so the two can't answer it differently.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-cansortreads) |
| <span id="getter-cansizegroupheights">**canSizeGroupHeights**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether a single group's pileup height can be set on its own, and so whether the two surfaces that write `groupMaxHeightOverrides` are offered: the label chip's expand/fit button and the per-group drag handles. Both write the same volatile, so they answer this together — the chip used to be offered where the handle was hidden.<br><br>Nothing to size with the pileup hidden, and in fit mode an override is a lane opting out of the fit the mode just computed: the extra rows overflow the display it was sized to fill. The truncation notice (`isGroupCeilingClipped`) steps aside in fit mode for the same reason.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-cansizegroupheights) |
| <span id="getter-groupheightoverrides">**groupHeightOverrides**</span><br><code>ReadonlyMap&lt;string, number&gt;</code> | <span data-pagefind-ignore>The per-lane pileup-height overrides IN EFFECT, which is not the set banked. Fit derives one read pitch from every lane's FULL row count (`fittedReadPitch`), so a lane the layout still caps at its own override shows fewer rows than the pitch was solved for and leaves exactly that much of the display blank — the one thing the mode promises not to do.<br><br>`setHeightMode` drops the overrides on the explicit switch, but the resolved mode also moves without it (the promotable cascade, a track reset), and there `canSizeGroupHeights` had already taken away both surfaces that could clear one — leaving the lane clipped by a cap `groupClippedBy` reports as `'override'`, which fires no affordance. Inert rather than dropped, so returning to fixed restores what the user set.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-groupheightoverrides) |
| <span id="getter-coveragescaletype">**coverageScaleType**</span><br><code>WiggleScaleType</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-coveragescaletype) |
| <span id="getter-coveragedomain">**coverageDomain**</span><br><code>[number, number] &#124; undefined</code> | <span data-pagefind-ignore>The autoscaled depth domain, spanning every SHOWN group (each block contributes one entry per group's coverage): a shared scale is what makes stacked sections visually comparable, and ungrouped is the one-group case. Hidden lanes are excluded — sizing the visible lanes' axis against a lane the user hid is exactly the comparability this scale exists to give.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-coveragedomain) |
| <span id="getter-coveragedepthdomain">**coverageDepthDomain**</span><br><code>[number, number] &#124; undefined</code> | <span data-pagefind-ignore>The domain the coverage band draws against — `coverageDomain` with a log scale's floor pulled up to one read (see `coverageDepthDomain`).<br><br>**This, not `coverageDomain`, is what every consumer reads**: the y-axis ticks and both renderers' normalizers. `coverageDomain[0]` used to be read by none of them, so a `minScore` bound was resolved into it and then thrown away — the menu reported a manual range in force while the picture was identical.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-coveragedepthdomain) |
| <span id="getter-coverageticks">**coverageTicks**</span><br><code>YScaleTicks &#124; undefined</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-coverageticks) |
| <span id="getter-colorlegendcategories">**colorLegendCategories**</span><br><code>Set&lt;ReadColorCategory&gt;</code> | <span data-pagefind-ignore>Read-color buckets actually present across the rendered reads, the single input that lets the legend list only relevant swatches (see legendUtils). Reads the same baked categories the renderer paints, so the two can't disagree. Empty while the legend is hidden so the O(reads) scan is skipped; MobX memoizes it against `laidOutByGroup`, which already folds in the scheme and the classification opts.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-colorlegendcategories) |
| <span id="getter-presenttagvalues">**presentTagValues**</span><br><code>ReadonlySet&lt;string&gt; &#124; undefined</code> | <span data-pagefind-ignore>The per-read values the CPU-baked schemes actually painted in the rendered reads — tag values, or mate refNames under chromosome painting. The whole swatch list for those schemes, since their color is a pure function of the value (`bakedValueColor`) and so needs no discovered-value table to look up. It replaced one: `colorTagMap` only ever grew, so after panning it held every value the track had ever seen and keyed swatches for a chromosome the user had navigated away from.<br><br>`undefined` for schemes with no such values, which is what tells the legend not to filter — distinct from the empty set, which means the scheme has values and none are on screen. Same showLegend gate as the category scan, for the same reason: it is O(reads).</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-presenttagvalues) |
| <span id="getter-presentmodifications">**presentModifications**</span><br><code>ReadonlySet&lt;string&gt; &#124; undefined</code> | <span data-pagefind-ignore>The modification types actually drawn in the rendered reads. The twin of `presentTagValues`, against the same failure: `detectedModifications` takes each region's types as that region's fetch lands and is never cleared, so keying it whole named every type the track had ever seen — pan off the one locus carrying 6mA and the box still listed 6mA.<br><br>Off `modificationTypes`, which the worker builds from the MARKS rather than from the MM/ML parse, so it is what a reader is looking at. The two sets diverge on bisulfite — no tags to parse, every mark carrying 'm' — and the legend's bisulfite branch answers before this filter for that reason.<br><br>`undefined` outside the modification schemes, which is what tells the legend not to filter; the empty set means the scheme is on and no marks are drawn. Same showLegend gate as the other two scans.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-presentmodifications) |
| <span id="getter-colorpalette">**colorPalette**</span><br><code>ColorPalette</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-colorpalette) |
| <span id="getter-arclegendcategories">**arcLegendCategories**</span><br><code>Set&lt;ReadColorCategory&gt;</code> | <span data-pagefind-ignore>The arc color slots actually plotted, mapped to legend buckets — curved paired-end arcs and the read cloud's flat lines and endpoint squares alike, since both paint from `arcColorByType`. Its own vocabulary when the fills use a different scheme (a track colored by strand still draws insert-size-colored arcs), so it keys its own legend section then and folds into the read key otherwise — see `arcColorsMatchReads`. Empty unless an overlay is on with the legend shown.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-arclegendcategories) |
| <span id="getter-arccolorsmatchreads">**arcColorsMatchReads**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the arc key folds into the read key — the overlay speaking the reads' own vocabulary, in the categories both are actually painting. `arcKeyFoldsIntoReadKey` holds the rule and the reasons the scheme names alone do not settle it.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-arccolorsmatchreads) |
| <span id="getter-overlaplegendkind">**overlapLegendKind**</span><br><code>"chain" &#124; "collapsed" &#124; undefined</code> | <span data-pagefind-ignore>Which overlap mark the reader is looking at, for the legend row that names it — undefined when there is none to name. The two layouts that put more than one feature on a row are drawn differently and the row differs with them: chain mode fills the span with a neutral that is no read category, collapsed rows tint what is underneath (overlap.slang).<br><br>Two conditions, and the second is the one the other swatches already apply to themselves. The pass has to be DRAWING (`shouldDrawOverlaps`, shared with both renderers rather than restated here, so a legend row can't outlive the ink), and some region has to hold an actual interval. Without the second, a paired track in chain mode whose mates happen not to overlap anywhere in view gets a row explaining a mark that isn't on screen — the same failure `presentCategories` and `presentTagValues` exist to prevent, and it would be the common case on long-insert libraries.<br><br>O(regions), not O(reads): the layout already reduced each region's overlaps to one array, so this reads a length per region.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-overlaplegendkind) |
| <span id="getter-arclegendtitle">**arcLegendTitle**</span><br><code>"Arc colors" &#124; "Read cloud colors"</code> | <span data-pagefind-ignore>Heading for the overlay's own color key, named after the overlay the reader is looking at: flat read-cloud lines are not arcs.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-arclegendtitle) |
| <span id="getter-arcbandinput">**arcBandInput**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ showCoverage: boolean; coverageHeight: number; coverageYOffse…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ showCoverage: boolean; coverageHeight: number; coverageYOffset: number; readConnections: "arc" &#124; "cloud" &#124; "off"; readConnectionsDown: boolean; readConnectionsHeight: number; }</code></pre></dialog></span> | <span data-pagefind-ignore>The fields `computeArcBand` reads, bundled so the layout can hand them over whole.<br><br>It used to have a second caller — the insert-size ruler assembled its own band from this, and the bundle was what kept the two assemblies identical. `insertSizeTickSections` now reads the band the LAYOUT placed (`renderSections`), which it had to in order to rule more than the first section, so the ruler and the arcs agree by reading one answer rather than by computing one twice from one input.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-arcbandinput) |
| <span id="getter-sashimidownkeysbygroup">**sashimiDownKeysByGroup**</span><br><code>Map&lt;string, ReadonlySet&lt;string&gt;&gt;</code> | <span data-pagefind-ignore>Per group, which junctions draw in the strip below coverage (by `junctionKey`). The single sashimi side decision: `sashimiDownArcLanes` reads it to reserve the strip and `sashimiArcSections` reads it to place each arc, so the space reserved and the arcs drawn into it can't disagree. Memoized because the 'auto' assignment is O(junctions²) per lane.<br><br>refNames come from `loadedRegions` — keyed by displayedRegionIndex like `rpcDataMap` and updated by the fetch, not by pan — so this stays a tier-1 (fetch) derivation and the pileup doesn't re-lay-out as the user scrolls. A region whose entry hasn't landed yet (the fetch sets `rpcDataMap` and `loadedRegions` in separate actions, so one reaction cycle sees the first without the second) falls back to a key unique to that region rather than a shared '': two regions we can't yet prove share a chromosome must not pool onto one bp number line, which is the whole reason the refName is in the key.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sashimidownkeysbygroup) |
| <span id="getter-sashimidownarclanes">**sashimiDownArcLanes**</span><br><code>Set&lt;string&gt;</code> | <span data-pagefind-ignore>Group keys whose junctions land in the strip below coverage, i.e. the lanes that strip is reserved for. `belowCoverageBandsInput` only needs whether any lane wants the strip, `sections` needs which.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sashimidownarclanes) |
| <span id="getter-belowcoveragebandssettings">**belowCoverageBandsSettings**</span><br><code>BelowCoverageBandsSettings</code> | <span data-pagefind-ignore>The settings half of the below-coverage band geometry — whether each strip MAY be reserved and how tall it is, with neither data half answered. Its two consumers answer those differently: the pooled `belowCoverageBandsInput` asks once for the whole stack, the fit budget once per lane.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-belowcoveragebandssettings) |
| <span id="getter-belowcoveragebandsinput">**belowCoverageBandsInput**</span><br><code>{…}</code> | <span data-pagefind-ignore>Inputs to `belowCoverageBandsGeometry` — the settings above, plus whether ANY lane has arcs or a sashimi junction bound for its strip. Both data halves are pooled over the lanes, which `computeStackedSections` asks per lane: the geometry here is the one ungrouped answer, and there the lanes agree with it because there is only the one. The grouped stack's own total is `totalBandOverhead`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-belowcoveragebandsinput) |
| <span id="getter-totalbandoverhead">**totalBandOverhead**</span><br><code>number</code> | <span data-pagefind-ignore>What the below-coverage strips cost the fit-to-viewport row budget over the whole stack: every lane's own reserved bands, summed the way `computeStackedSections` reserves them.<br><br>Pre-layout by construction — `groupOrder` and the two lane sets are all fetch-tier — which is what lets the layout spend it without routing back through itself.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-totalbandoverhead) |
| <span id="getter-laidoutbygroupuncolored">**laidOutByGroupUncolored**</span><br><code>LaidOutByGroup</code> | <span data-pagefind-ignore>Per-group laid-out data: group key → (region index → laid-out data). Each group lays out independently (own `maxRows` cap) so a dense group can't starve the rest. When grouped, the default cap fits all sections into the viewport (`fitGroupMaxRows`) so the stack doesn't tower and need scrolling; a per-group height drag / expand still overrides it.<br><br>Rows only — the per-read color arrays are baked one computed later, in `laidOutByGroup`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-laidoutbygroupuncolored) |
| <span id="getter-frameschainstrand">**framesChainStrand**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the unpaired chain-strand framing is live, as a BOOLEAN and in its own computed. The boolean is the point: nine of the schemes give one of two answers, so MobX's value comparison stops a scheme switch from invalidating `laidOutByGroupFramed` unless the answer actually moved. Reading `framesUnpairedChainStrand` inline there instead would make the frame solve depend on `colorBy` itself and re-run on every switch — which is what it used to do.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-frameschainstrand) |
| <span id="getter-laidoutbygroupframed">**laidOutByGroupFramed**</span><br><code>LaidOutByGroup</code> | <span data-pagefind-ignore>The laid-out data with every chain's strand frame settled — see `applyChainStrandFrames`, which says why the two passes are here and not in the colour bake below.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-laidoutbygroupframed) |
| <span id="getter-laidoutbygroup">**laidOutByGroup**</span><br><code>ColoredByGroup</code> | <span data-pagefind-ignore>Per-group laid-out data with the per-read color arrays baked on. Every consumer reads this one; `laidOutByGroupUncolored` exists only to be its layout half.<br><br>The split is what keeps recoloring off the layout path. Nothing in `readColorContext` can move a read's row, so folding those settings into the layout computed made a color-scheme flip re-run the placement pass, every per-feature Y remap and the modification Flatbush to change two per-read arrays. Now the layout computed stays memoized across a recolor, and because the overlay spreads its input, `readYs` survives with it — which is the token the GPU renderer's upload memo reads to rewrite only the read pass. Tag colors are baked here rather than in the worker so tag coloring stays a main-thread tier-2 setting (see readTagColors).</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-laidoutbygroup) |
| <span id="getter-grouplayoutcontext">**groupLayoutContext**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ order: GroupId[]; rawByGroup: Map&lt;string, Map&lt;number, WorkerP…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ order: GroupId[]; rawByGroup: Map&lt;string, Map&lt;number, WorkerPileupData&gt;&gt;; isChainMode: boolean; sortedBy: SortedBy &#124; undefined; ... 5 more ...; collapseGroupRows: boolean; }</code></pre></dialog></span> | <span data-pagefind-ignore>The layout mechanics (grouping, sort, soft-clip) shared by the viewport fit pass and any ad-hoc layout — e.g. `fittedFeatureHeight`, which lays every group out uncapped to count rows. Kept apart from the fit policy (row caps), which varies per call, and from the color inputs, which invalidate a later tier.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-grouplayoutcontext) |
| <span id="getter-readcolorcontext">**readColorContext**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ colorBy: ColorBy; colorScheme: number; readColorOpts: {…}; re…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ colorBy: ColorBy; colorScheme: number; readColorOpts: {…}; refNamePosition: ((refName: string) =&gt; number &#124; undefined) &#124; undefined; }</code></pre></dialog></span> | <span data-pagefind-ignore>The per-read color bake's inputs — see `laidOutByGroup` for why they are not part of `groupLayoutContext`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readcolorcontext) |
| <span id="getter-paintedrefnameposition">**paintedRefNamePosition**</span><br><code>((refName: string) =&gt; number &#124; undefined) &#124; undefined</code> | <span data-pagefind-ignore>Where a mate's reference sits in this assembly's own chromosome order, for chromosome painting — the alignments twin of `LinearSyntenyDisplay.paintedChromosomeOrder`, and the thing that lets the palette be handed out rather than hashed into (`refNameColor`).<br><br>It has to come from the ASSEMBLY rather than from the reads on screen, or a chromosome's color would change with what else was in view.<br><br>Canonicalizing first is not optional: a mate reference is `next_ref`, which names a location this fetch did not ask for and so arrives in the FILE's spelling (`1` against an assembly whose canonical name is `chr1`) — see REFNAME_NAMESPACES.md. An uncanonicalized probe misses, and a miss is SILENT: it falls back to the hash and paints a plausible wrong color rather than raising anything.<br><br>Undefined under every other scheme and until the assembly initializes, where the fallback is the right answer rather than a failure.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-paintedrefnameposition) |
| <span id="getter-readcoloropts">**readColorOpts**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ chainMode: boolean; flipStrandLongReadChains: boolean; colorS…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ chainMode: boolean; flipStrandLongReadChains: boolean; colorSupplementaryChains: boolean; }</code></pre></dialog></span> | <span data-pagefind-ignore>The non-scheme inputs to read classification. One bundle so the bake (`overlayReadColorCategories`) and any ad-hoc `readColorCategory` call can't be handed a different set.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readcoloropts) |
| <span id="getter-grouporder">**groupOrder**</span><br><code>GroupId[]</code> | <span data-pagefind-ignore>Group keys + labels in stacking order; a single entry (key '') when ungrouped. Derived straight from the fetched `rpcDataMap` (not from the layout pass), so group identity/order stays stable across relayouts.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-grouporder) |
| <span id="getter-showsgrouplabels">**showsGroupLabels**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the stacked section labels + dividers are drawn. Deliberately NOT `isGrouped`: grouping that happens to yield one section (a region with reads on one strand, a tag with a single value) still reserves the label offset (`prefersOffset`) and still wants its section named and collapsible — otherwise it reads as an ungrouped track with mysterious blank space above it. `isGrouped` stays about the scroll model (>1 section scrolls coverage with its section), which one section doesn't change. Reads the fetched sections rather than `groupBy` — see `hasNamedGroups` for why the setting is the wrong signal.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showsgrouplabels) |
| <span id="getter-rawdatabygroup">**rawDataByGroup**</span><br><code>Map&lt;string, Map&lt;number, WorkerPileupData&gt;&gt;</code> | <span data-pagefind-ignore>Raw (un-laid-out) data regrouped as group key → (region idx → data), insertion-ordered so the first key is the primary group. The arc compute and the per-section sashimi overlay both read one group's raw map from here; ungrouped is the single key `''`.<br><br>Hidden lanes are already gone, like `groupOrder` — so a walk of every entry here is a walk of every DRAWN lane, and no consumer has to re-apply `hiddenGroupKeys`. See `buildRawDataByGroup`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-rawdatabygroup) |
| <span id="getter-loadedregioninfos">**loadedRegionInfos**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ refName: string; start: number; end: number; displayedRegionI…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ refName: string; start: number; end: number; displayedRegionIndex: number; }[]</code></pre></dialog></span> | <span data-pagefind-ignore>The fetched regions as `{refName,start,end,displayedRegionIndex}` — the shape every per-read region scan takes (`computeArcsByGroup`, `computeReadChains`). Regions whose fetch hasn't landed are dropped, so a scan never has to test for a missing entry, and the list is memoized once rather than rebuilt by each consumer.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-loadedregioninfos) |
| <span id="getter-displayedregioninfos">**displayedRegionInfos**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ refName: string; start: number; end: number; displayedRegionI…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ refName: string; start: number; end: number; displayedRegionIndex: number; }[]</code></pre></dialog></span> | <span data-pagefind-ignore>The VIEW's displayed regions in the same shape, which is a different list from `loadedRegionInfos` and answers a different question: not "where did reads come from" but "where can a coordinate be drawn".<br><br>The arc partition (`CrossRegionArc`) keys on this one, because its criterion is whether `view.bpToPx` can project both feet and that projector reads `displayedRegions`. Keying it on the fetched list leaves the original bug alive for a displayed-but-unfetched partner — see `ArcRegions`.<br><br>`displayedRegions` changes on NAVIGATION and not on pan, so `arcsByGroup` keeps the invalidation tier `loadedRegions`' own comment exists to protect: panning within the fetched window still replays the memo.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-displayedregioninfos) |
| <span id="getter-canonicalrefname">**canonicalRefName**</span><br><code>((refName: string) =&gt; string) &#124; undefined</code> | <span data-pagefind-ignore>Normalizer for a refName that arrives in the BAM's own spelling (an SA tag's or RNEXT's `chr1`) rather than the assembly-canonical one a fetched read carries (`1`). Undefined when no assembly is resolved (`loadedAssembly`), where the consumers fall back to identity.<br><br>Shared rather than resolved per consumer because both need it for the same reason: without it a same-chromosome split junction reads as inter-chromosomal, and a derivative path names refNames the view doesn't have.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-canonicalrefname) |
| <span id="getter-arcsresult">**arcsResult**</span><br><code>ArcsByGroupResult</code> | <span data-pagefind-ignore>THE arc resolution, whole: both halves of what this fetch's reads say, from one pass. Read it through `arcsByGroup` (what a per-region pass draws) or `crossRegionArcsByGroup` (what only the overlay can), which are its two faces and are documented there.<br><br>One getter rather than two, because the split between them is a single decision taken per connection inside `resolveArcs` — see `CrossRegionArc`. Two getters resolving independently would each have to re-derive it, and "which half is this arc in" would stop having one answer.<br><br>The heavy connection-resolution pass runs once per group (arcs are pre-grouped by refName so each region lookup is O(1)); ungrouped is the single-group case. Empty when read-connections are off, so the off-path skips the per-read region scan entirely.<br><br>`computeArcsByGroup` owns the whole fan-out rather than a loop here, because the arc COLOR scale (`poolArcScale`: the insert-size band, and whether the read set is paired at all) describes the fetch, not a lane — the same rule the worker follows for `insertSizeStats` and this model follows for `arcsYDomainBp`. Computing it needs every group's arcs in hand, which a per-group loop can't provide.<br><br>Hidden lanes never reach it, because `rawDataByGroup` has already dropped them. They must be skipped, not just left unread: the per-section consumers look this up by an already-filtered `groupOrder` key, but the cross-group scans (`arcsYDomainBp`, `arcLegendCategories`) walk every entry — so a hidden lane's arcs would size the read-cloud Y axis the visible lanes share and key legend swatches for arcs nothing draws, and its reads would shift `poolArcScale` for everyone. Skipping also saves the whole per-read arc pass over a lane no section renders.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-arcsresult) |
| <span id="getter-arcsbygroup">**arcsByGroup**</span><br><code>Map&lt;string, Map&lt;number, ArcsUploadData&gt;&gt;</code> | <span data-pagefind-ignore>The per-region GPU/Canvas2D upload feed. Every consumer that packs, draws or hit-tests a region's arcs reads this; the arcs it does NOT contain are the cross-region ones, which no per-region pass can draw (`CrossRegionArc`) and which `crossRegionArcsByGroup` carries instead.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-arcsbygroup) |
| <span id="getter-crossregionarcsbygroup">**crossRegionArcsByGroup**</span><br><code>Map&lt;string, CrossRegionArc[]&gt;</code> | <span data-pagefind-ignore>Arcs whose two feet are in different displayed regions, per group. Drawn by an SVG overlay across the whole view, because the per-region passes map bp to x through the block's own range and would each extrapolate the far foot to a place the other block is not — see `CrossRegionArc` for the measurement. Empty in a single-region view.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-crossregionarcsbygroup) |
| <span id="getter-hasreadsforderivativepaths">**hasReadsForDerivativePaths**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether there are reads to reconstruct FROM, as opposed to reads that describe no rearrangement. An empty `derivativePathCandidates` means either, and they call for opposite responses: widen the window, or narrow it. A window too large for the track's byte budget renders as `force load` with nothing behind it, and reporting that as "no path is supported here" sends a reader looking for an event that was never fetched.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-hasreadsforderivativepaths) |
| <span id="getter-medianreadspanbp">**medianReadSpanBp**</span><br><code>number</code> | <span data-pagefind-ignore>Median aligned length of the reads in view, in bp — how much reference one alignment covers, which is what decides whether a read can carry a junction at all. The picker's empty state reads it to tell a library that cannot describe a rearrangement from a window that happens to hold none.<br><br>Lazy like any computed, so a pileup pays for this scan only while the picker is open.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-medianreadspanbp) |
| <span id="getter-derivativepathcandidates">**derivativePathCandidates**</span><br><code>DerivativeCandidate[]</code> | <span data-pagefind-ignore>Derivative-allele paths the reads in view describe, most-supported first. Each read's SA chain is already an ordered, oriented list of reference intervals — a derivative path — so the proposal is a grouping of those chains rather than any new analysis. Empty when no reads are loaded, which `hasReadsForDerivativePaths` distinguishes.<br><br>Deliberately NOT gated on `readConnections`: this reads the chains, not the arcs, and a user who wants a reconstruction should not first have to turn on a display option that draws something else.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-derivativepathcandidates) |
| <span id="getter-modificationthreshold">**modificationThreshold**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-modificationthreshold) |
| <span id="getter-colorschemeindex">**colorSchemeIndex**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-colorschemeindex) |
| <span id="getter-showmodifications">**showModifications**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showmodifications) |
| <span id="getter-showperbasequality">**showPerBaseQuality**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showperbasequality) |
| <span id="getter-showperbaseletter">**showPerBaseLetter**</span><br><code>boolean</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showperbaseletter) |
| <span id="getter-readidindexmap">**readIdIndexMap**</span><br><code>ReadIdIndexMap</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readidindexmap) |
| <span id="getter-layoutready">**layoutReady**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether `searchFeatureByID` has a pileup to search. Same name and meaning as the canvas display's; see MultiRegionDisplayMixin.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-layoutready) |
| <span id="getter-readconnectionslinewidth">**readConnectionsLineWidth**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readconnectionslinewidth) |
| <span id="getter-belowcoveragebands">**belowCoverageBands**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ hasArcsBand: boolean; hasSashimiBand: boolean; arcsBandTop: n…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ hasArcsBand: boolean; hasSashimiBand: boolean; arcsBandTop: number; sashimiBandTop: number; bottom: number; }</code></pre></dialog></span> | <span data-pagefind-ignore>Geometry of the bands stacked below coverage in arcs-down mode, top to bottom: coverage → paired-end arcs → sashimi. Single source of truth so the layout height, the renderers, and the three resize handles can't drift apart. `arcsBandTop`/`sashimiBandTop` are each band's top edge; `bottom` is where the pileup begins (== coverageDisplayHeight).</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-belowcoveragebands) |
| <span id="getter-coveragedisplayheight">**coverageDisplayHeight**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-coveragedisplayheight) |
| <span id="getter-lanes">**lanes**</span><br><code>AlignmentLane[]</code> | <span data-pagefind-ignore>The stacked lanes, in stacking order: one `AlignmentLane` per drawn group, ungrouped being the one-lane case.<br><br>The single place a lane's key is turned into its data. Every per-lane collection used to be looked up separately by each consumer — the raw map, the laid-out map, the two arc feeds, the sashimi sides, the collapse/override volatiles — so a lane's identity was a bare string indexed into as many keyed collections as there were questions, each with its own `?? empty` for a key that structurally cannot be missing.<br><br>A projection, not a store: every field is read from the computed that owns it, so the fetch/layout/recolor tiers upstream are untouched and this adds no state to keep in step.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-lanes) |
| <span id="getter-drawnlanes">**drawnLanes**</span><br><code>AlignmentLane[]</code> | <span data-pagefind-ignore>The lanes actually laid out, or the one SYNTHETIC lane. `sections` has to produce a section before any fetch lands — and a grouped fetch over an empty region partitions to zero lanes — so the section pipeline is never handed an empty list. Every collection on it is empty by construction, `maxY` included.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-drawnlanes) |
| <span id="getter-pileuptruncated">**pileupTruncated**</span><br><code>boolean</code> | <span data-pagefind-ignore>True when any pileup hit the display-wide `maxHeight` and overflow reads were collapsed. Reads every lane, not just an ungrouped one: the ceiling is display-wide, so a stacked lane clipped by it is exactly as unreachable as an ungrouped pileup would be, and the per-label affordance deliberately steps aside for it.<br><br>The display-wide answer; what is DRAWN is the per-section `isGroupCeilingClipped`, which carries the suppressions this composes.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-pileuptruncated) |
| <span id="getter-sections">**sections**</span><br><code>SectionsLayout</code> | <span data-pagefind-ignore>Single source of all vertical band geometry, one entry per lane. `computeStackedSections` reproduces the prior ungrouped reserved layout exactly for its single-section (N==1) case, so ungrouped is not a special branch here — it is the one-lane call, over `drawnLanes` so a display with no data still has a section. The sticky-coverage-vs-scroll distinction lives downstream in `buildSectionRenders`, keyed off section count.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sections) |
| <span id="getter-rendersections">**renderSections**</span><br><code>LaneSection[]</code> | <span data-pagefind-ignore>Every lane paired with its band geometry, in stacking order: the list the overlays, the hit-test pipeline and both renderers all walk.<br><br>The pairing is by INDEX and that is structural, not a coincidence — `computeStackedSections` emits one section per lane in order, and both lists come from `drawnLanes`. Deriving the two from different sources is what used to let them disagree whenever a section was synthesized.<br><br>Carrying the lane's own collections here is what retires the by-key lookup every downstream pass used to do (`?? new Map()` for a key that structurally cannot be missing, spelled once per consumer).</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-rendersections) |
| <span id="getter-sourcesections">**sourceSections**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ groupKey: string; laidOutPileupMap: ReadonlyMap&lt;number, Pileu…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ groupKey: string; laidOutPileupMap: ReadonlyMap&lt;number, PileupDataResult&gt;; arcsRpcDataMap: ReadonlyMap&lt;number, ArcsUploadData&gt;; }[]</code></pre></dialog></span> | <span data-pagefind-ignore>Per-section upload input, in stacking order: each section's laid-out region map + arc feed, keyed by group so the renderers can namespace HAL region keys per section.<br><br>Both renderers pair the uploaded section `s` with the drawn section `s` by INDEX (`sectionRegionKey(s, regionIdx)`), so this list and `renderState.sections` must have the same length and order. Both now derive from `renderSections`, making that structural — deriving this one from `groupOrder` instead let the two disagree whenever the section pipeline synthesized its no-data lane (0 uploaded vs 1 drawn), which happens on an empty grouped fetch. That mismatch was benign only because the per-section region lookup missed and the draw skipped.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sourcesections) |
| <span id="getter-bezierarcscope">**bezierArcScope**</span><br><code>BezierArcScope</code> | <span data-pagefind-ignore>What the SVG connection overlay is responsible for drawing — see `BezierArcScope`. Chain mode claims `crossRegion` even with the curved connectors unticked, because it is the only pass that can join a chain's two ends when they land in different displayed regions; the per-region connecting line covers everything else.<br><br>One getter rather than a check at each of the four consumers (the live overlay, the SVG export, the legend, and the pair enumeration itself), since a scope they disagreed on would draw a curve the key doesn't name, or the reverse.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-bezierarcscope) |
| <span id="getter-bezierpairsections">**bezierPairSections**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ topOffset: number; pileupHeight: number; pairs: LinkedPair[];…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ topOffset: number; pileupHeight: number; pairs: LinkedPair[]; }[]</code></pre></dialog></span> | <span data-pagefind-ignore>Scroll/pan-invariant half of the bezier connection overlay: the linked pairs of each section, resolved once per relayout. The read grouping + connection resolution (`enumerateBezierPairs`) is the allocation-heavy step; memoizing it here (this getter never reads `scrollTop`) keeps a scroll frame down to the cheap per-pair screen projection in `computePileupBezierArcsFromModel`. Narrowed by `bezierArcScope`, and empty when that is `none`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-bezierpairsections) |
| <span id="getter-bezierconnectioncolortypes">**bezierConnectionColorTypes**</span><br><code>Set&lt;number&gt;</code> | <span data-pagefind-ignore>Connection types (LINKED_READ_COLOR_*) actually drawn as bezier/line arcs in view, the input that lets the legend list only the connection colors present. `bezierPairSections` is already narrowed to what the overlay draws (`enumerateBezierPairs` applies the scope's own predicate), so this scans the same list the curves come from rather than re-deriving the skip rule beside it. Empty while the legend is hidden so the scan is skipped.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-bezierconnectioncolortypes) |
| <span id="getter-sashimiarcsections">**sashimiArcSections**</span><br><code>SashimiArcSection[]</code> | <span data-pagefind-ignore>Per-section sashimi arcs, in stacking order. The overlay and the SVG export both map over this, so it is the single source for sashimi geometry and neither path can drift; ungrouped is the single-section case (sticky band below sticky coverage). Empty when sashimi is off.<br><br>A computed on purpose (tier 3 — mirrors `bezierPairSections`): the arc math depends on the view's pan/zoom but NOT on scrollTop, so MobX replays the cache while the user scrolls a grouped track. Computing it in the overlay's render instead re-ran the O(n^2) 'auto' side assignment for every section on every scroll frame.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sashimiarcsections) |
| <span id="getter-isgrouped">**isGrouped**</span><br><code>boolean</code> | <span data-pagefind-ignore>True when reads are stacked into >1 group section. Drives the scroll model: ungrouped keeps coverage sticky (only the pileup scrolls); grouped scrolls the whole coverage+pileup stack as one.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-isgrouped) |
| <span id="getter-scrollmodel">**scrollModel**</span><br><code>ScrollModel</code> | <span data-pagefind-ignore>The scroll-projection inputs (`sectionScreen.ts`) every overlay needs to map a content-space Y into screen space. Built once here so the label / resize-handle / coverage-axis overlays don't each re-assemble `{ isGrouped, scrollTop, canvasHeight }` inline.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-scrollmodel) |
| <span id="getter-pileupviewportheight">**pileupViewportHeight**</span><br><code>number</code> | <span data-pagefind-ignore>Height of the scrollable viewport. Ungrouped excludes the sticky coverage band; grouped scrolls the entire display.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-pileupviewportheight) |
| <span id="getter-pileupcontentheight">**pileupContentHeight**</span><br><code>number</code> | <span data-pagefind-ignore>Total scrollable content height. Grouped is the full stacked-sections height; ungrouped is the pileup band alone (coverage is sticky), which is the stacked height minus that sticky coverage band. Both read the laid-out `sections` so the scroll extent tracks the geometry actually drawn — when `showPileup` is off or the group is collapsed the section reserves no pileup rows, so this collapses to 0 and no phantom scroll region opens up below the coverage band.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-pileupcontentheight) |
| <span id="getter-growtargetheight">**growTargetHeight**</span><br><code>number</code> | <span data-pagefind-ignore>HeightModeMixin's grow hook: the full laid-out content height (coverage + pileup + arcs), before the `growMaxHeight` cap. Independent of `self.height` — `laidOutByGroup` fits to `growMaxHeight` in grow mode (not the reactive `height`), and `featureHeight` is the configured value there rather than the fitted pitch — which is what lets the mixin's `height` return it without cycling. `grownHeight`, the `height` override and the grow-aware `resizeHeight` all come from the mixin.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-growtargetheight) |
| <span id="getter-scalebaroverlapleft">**scalebarOverlapLeft**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-scalebaroverlapleft) |
| <span id="getter-showoutline">**showOutline**</span><br><code>any</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-showoutline) |
| <span id="getter-visiblelabels">**visibleLabels**</span><br><code>VisibleLabel[]</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-visiblelabels) |
| <span id="getter-highlightchainreadids">**highlightChainReadIds**</span><br><code>string[]</code> | <span data-pagefind-ignore>Read ids of the hovered chain's members, empty unless in chain mode. Single source for the "is this a chain highlight" decision that both `highlightBoxes` (which ids to box) and `HighlightOverlay` (how strongly to shade them) read, so the two can't drift.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-highlightchainreadids) |
| <span id="getter-highlightboxes">**highlightBoxes**</span><br><code>HighlightBox[]</code> | <span data-pagefind-ignore>Screen boxes for the hovered read / chain, painted by the `HighlightOverlay` div. Deliberately NOT part of `renderState`: the hovered id changes on nearly every mousemove, and routing it through the canvas would repaint the whole pileup each move.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-highlightboxes) |
| <span id="getter-readcategorylabel">**readCategoryLabel**</span><br><code>(c: ReadColorCategory) =&gt; string &#124; undefined</code> | <span data-pagefind-ignore>Names one read color bucket for the hover, with the active scheme's rewording already applied — the same `readCategoryLabelOverrides` the legend box uses, so the tooltip and the swatch it sends the reader to cannot say different things about one color.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-readcategorylabel) |
| <span id="getter-fittedfeatureheight">**fittedFeatureHeight**</span><br><code>number</code> | <span data-pagefind-ignore>The read height that makes every uncollapsed group's reads fill the display without scrolling — the fractional pitch, the 1px floor and the Normal-pitch cap all being `fittedReadPitch`'s.<br><br>The uncapped row count is taken against a fixed `maxHeight`-row cap, independent of the current `featureHeight`, so the fit autorun that writes `featureHeight` can't feed back into this. `fitTargetHeight` is the slot, NOT the reactive `height` getter — the same anti-cycle rule `laidOutByGroup` follows. Fit mode only, where the two are equal, but the slot can never chain back through height->grownHeight->layout->featureHeight if this ever moves.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-fittedfeatureheight) |
| <span id="getter-scrollableheight">**scrollableHeight**</span><br><code>number</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-scrollableheight) |
| <span id="getter-sorttag">**sortTag**</span><br><code>string &#124; undefined</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-sorttag) |
| <span id="getter-renderstate">**renderState**</span><br><code>{…}</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-renderstate) |
| <span id="getter-arcsydomainbp">**arcsYDomainBp**</span><br><code>number &#124; undefined</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-arcsydomainbp) |
| <span id="getter-insertsizeticksections">**insertSizeTickSections**</span><br><code>{ groupKey: string; ticks: YScaleTicks; }[]</code> | <span data-pagefind-ignore>The read cloud's insert-size ruler, per section — see `computeInsertSizeTickSections`. Empty outside read-cloud mode, which is the only mode that puts \|TLEN\| on the band's Y axis.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-insertsizeticksections) |
| <span id="getter-crossregionarcsections">**crossRegionArcSections**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>{ groupKey: string; bandTop: number; bandHeight: number; arcs:…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>{ groupKey: string; bandTop: number; bandHeight: number; arcs: CrossRegionArcShape[]; }[]</code></pre></dialog></span> | <span data-pagefind-ignore>Per-section geometry for the arcs no per-region pass can draw — see `computeCrossRegionArcSections`, which owns the band-local contract this shares with the sashimi and ruler walks.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-crossregionarcsections) |
| <span id="getter-perbasebinbp">**perBaseBinBp**</span><br><code>number</code> | <span data-pagefind-ignore>Genomic bp one per-base cell stands for in the worker's extract: `subPixelBinBp` off the debounced zoom, and `1` in every color mode that does not paint a wall of them.<br><br>Per-base quality and per-base lettering emit one entry per aligned base of EVERY read, so their extract grows with bases x depth where every other pass grows with events — a force-loaded region at the byte gate's ceiling builds millions of them in the worker before anything is packed. Sampling one base per sub-pixel window bounds that by the VIEWPORT rather than by the region, and costs nothing visible: `subPixelBinBp` is 1 at every zoom where a base is still a pixel wide, and above that the samples are half a pixel apart while the cells they paint floor to a whole one, so the wall stays unbroken.<br><br>Not an `rpcProps` field — see `perBaseBinBp` on the RPC args for why a zoom-swinging value belongs at the call site, and `regionFetchKey` below for what invalidates on it instead.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-perbasebinbp) |
| <span id="getter-liveperbasebinbp">**livePerBaseBinBp**</span><br><code>number</code> | <span data-pagefind-ignore>The same bin off the LIVE zoom, and read by `dataSuperseded` alone.<br><br>The debounced bin cannot answer "is the held data sampled finely enough for what is on screen": it is the value the held data was fetched under, so for the whole 500ms the debounce takes to catch up the two agree by construction and a supersession test built on it can only ever say no. That is half the window `dataSuperseded` exists to cover — the debounce half, where the picture is already several octaves coarser than the zoom it is drawn at — and it is the half an export lands in, since a reader zooms and then reaches for the menu.<br><br>It stays out of `regionFetchKey`, which drives the refetch, and the reason is not that a live key would flip more often — the quantization means it flips per octave either way, and wiggle keys on live `bpPerPx` outright (ADR-008). It is that `FetchVisibleRegions` runs on the leading edge, so a live key makes a fast multi-octave gesture issue a refetch at each octave it passes through, and this is the pipeline whose extract is the OOM the per-base bin exists to bound. Latest-wins cancels the RPC, not worker work already running.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-liveperbasebinbp) |
| <span id="getter-hoveredfeature">**hoveredFeature**</span><br><code>SimpleFeature &#124; undefined</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-hoveredfeature) |
| <span id="getter-regionfetchkey">**regionFetchKey**</span><br><code>string</code> | <span data-pagefind-ignore>`MultiRegionDisplayMixin`'s per-region content axis: what a fetch issued right now would produce. Only the per-base bin moves it, so in every other color mode this is one constant string and a zoom never refetches on its account; in the two per-base modes a bin flip refetches the regions on screen and leaves the rest of the held data alone, which is the whole reason the bin is not in `rpcProps`.<br><br>Its own views block, after the getter it reads, for the reason `rpcProps` has one.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-regionfetchkey) |
| <span id="getter-datasuperseded">**dataSuperseded**</span><br><code>boolean</code> | <span data-pagefind-ignore>`MultiRegionDisplayMixin`'s supersession hook: the settled per-base bin has not moved yet, but the live zoom has already left it, so the clear is inevitable and not yet committed.<br><br>**Only the debounce half is here.** Once the settled bin moves, the stamp a region was fetched under stops matching `regionFetchKey` and the foundation's own `isCacheValid` term in `dataCurrent` covers it — this display carried that compare privately until the foundation took it. What no key can state is the window before the debounce catches up: the stamp IS the settled bin, so the two agree by construction while the wall on screen is already several octaves coarser than the zoom it is drawn at. That is the half an export lands in, since a reader zooms and then reaches for the menu.<br><br>A value compare, never a second spelling of the key. Restating the key's string format on the live side would latch this true the day the key grows a second axis, and a latched supersession is an export that hangs to `awaitSvgReady`'s timeout rather than one that fails.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-datasuperseded) |
| <span id="getter-resizablebandbounds">**resizableBandBounds**</span><br><code>{ max: number; }</code> | <span data-pagefind-ignore>The legal range for any of the three drag-resizable bands stacked over the pileup (coverage, read connections, sashimi).<br><br>The ceiling is what makes the drag recoverable. `pileupViewportHeight` floors at 0, so without one a band dragged past the display height squashes the pileup to nothing *and* carries its own resize handle off the bottom edge — leaving no way back except growing the track. Each band is bounded against the display height individually; three of them dragged large can still crowd the pileup, but every one of them stays reachable, which is the property the user needs.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-resizablebandbounds) |
| <span id="getter-gateenabled">**gateEnabled**</span><br><code>boolean</code> | <span data-pagefind-ignore>Opt into RegionTooLargeMixin's byte gate: `fetchNeeded` passes `resolvedByteLimit()` to `RenderAlignmentData`, whose first await is the index estimate — so an over-budget region is refused before a single read is downloaded.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#getter-gateenabled) |
| <span id="getter-parenttrack">**parentTrack**</span><br><code>AbstractTrackModel</code> |  | [BaseDisplay](../basedisplay#getter-parenttrack) |
| <span id="getter-renderingcomponent">**RenderingComponent**</span><br><code>FC&lt;…&gt;</code> |  | [BaseDisplay](../basedisplay#getter-renderingcomponent) |
| <span id="getter-displayblurb">**DisplayBlurb**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>FC&lt;{ model: ModelInstanceTypeProps&lt;{ id: IOptionalIType&lt;ISimple…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>FC&lt;{ model: ModelInstanceTypeProps&lt;{ id: IOptionalIType&lt;ISimpleType&lt;string&gt;, [undefined]&gt;; type: ISimpleType&lt;string&gt;; }&gt; &amp; { ...; } &amp; { ...; } &amp; IStateTreeNode&lt;...&gt;; }&gt; &#124; null</code></pre></dialog></span> |  | [BaseDisplay](../basedisplay#getter-displayblurb) |
| <span id="getter-adapterconfig">**adapterConfig**</span><br><code>Record&lt;string, unknown&gt;</code> |  | [BaseDisplay](../basedisplay#getter-adapterconfig) |
| <span id="getter-isminimized">**isMinimized**</span><br><code>boolean</code> | <span data-pagefind-ignore>Returns true if the parent track is minimized. Used to skip expensive operations like autoruns when track is not visible.</span> | [BaseDisplay](../basedisplay#getter-isminimized) |
| <span id="getter-height">**height**</span><br><code>number</code> |  | [TrackHeightMixin](../trackheightmixin#getter-height) |
| <span id="getter-resizing">**resizing**</span><br><code>boolean</code> | <span data-pagefind-ignore>True for the duration of a height drag on this track, whichever handle is running it. A display whose row geometry is a function of the track height restretches every row per animation frame, and can use this to sit an expensive per-frame layer out of the drag (MAF's dense per-base letter overlay is a Canvas2D pass that scales with rows x columns).<br><br>The flag itself is the track's (`BaseTrackModel`), so the view brackets a drag without needing the active display to have opted into this mixin. Reading it here is what makes `self.resizing` available to a display that did.</span> | [TrackHeightMixin](../trackheightmixin#getter-resizing) |
| <span id="getter-heightmode">**heightMode**</span><br><code>"fit" &#124; "fixed" &#124; "grow"</code> | <span data-pagefind-ignore>The resolved track-height strategy (`fixed`/`grow`/`fit`). Promotable sentinel slot: resolveConf walks the customized-track -> session-default -> `fixed` cascade and never returns the `inherit` sentinel.</span> | [HeightModeMixin](../heightmodemixin#getter-heightmode) |
| <span id="getter-fittargetheight">**fitTargetHeight**</span><br><code>number</code> | <span data-pagefind-ignore>The drag-resizable track height as stored in the config slot — the fit target the fit/grow layout scales or packs content into. Read there instead of the reactive `height` getter to break the grow-mode cycle (`height`->grownHeight->layout->height). Equals `height` in fixed/fit.</span> | [HeightModeMixin](../heightmodemixin#getter-fittargetheight) |
| <span id="getter-growmaxheight">**growMaxHeight**</span><br><code>number</code> | <span data-pagefind-ignore>Ceiling `grow` mode sizes the track to, in px (content past it scrolls). Lives here rather than as a constant so a track whose whole point is a deep pileup can raise it; both displays that own a `grownHeight` read this, so the two can't diverge.</span> | [HeightModeMixin](../heightmodemixin#getter-growmaxheight) |
| <span id="getter-autoheight">**autoHeight**</span><br><code>boolean</code> | <span data-pagefind-ignore>`grow` mode as a boolean, derived from the unified `heightMode` slot.</span> | [HeightModeMixin](../heightmodemixin#getter-autoheight) |
| <span id="getter-fitheighttodisplay">**fitHeightToDisplay**</span><br><code>boolean</code> | <span data-pagefind-ignore>`fit` mode as a boolean, derived from the unified `heightMode` slot.</span> | [HeightModeMixin](../heightmodemixin#getter-fitheighttodisplay) |
| <span id="getter-grownheight">**grownHeight**</span><br><code>number</code> | <span data-pagefind-ignore>Target track height for `grow`: what the content wants, capped so a deep stack doesn't grow the track to thousands of px (the remainder scrolls). What `installGrowExitBake` bakes into the slot on exit.</span> | [HeightModeMixin](../heightmodemixin#getter-grownheight) |
| <span id="getter-host">**host**</span><br><code>RegionHost</code> | <span data-pagefind-ignore>The containing LinearGenomeView, typed once for every display in this family — see `containingHost` for the cast it owns and why both foundations still declare the name.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-host) |
| <span id="getter-canvaswidthpx">**canvasWidthPx**</span><br><code>number</code> | <span data-pagefind-ignore>The CSS width of this display's on-screen canvas, in px — and the `canvasWidth` its `renderState` must carry, since the two have to agree or the bp→px mapping is scaled against a box it doesn't fill.<br><br>`trackWidthPx`, **not** `view.width`: `TrackRenderingContainer` insets the rendering component by the 2px track outline under `contain: strict`, so a `view.width`-wide canvas overhangs its own container and the browser clips the overhang away. It renders almost identically, which is why MAF drifted onto `view.width` uncaught.<br><br>A getter rather than a note on each display, because the choice was being made by copying a neighbour out of four plausible view getters — `width` (the viewport), this one, and `totalWidthPx` / `totalWidthPxWithoutBorders` (the *content* width, which the global family's heatmaps legitimately want: a different question, not a different answer). `no-restricted-syntax` bans the underlying read everywhere but this line, since a second spelling agrees until it doesn't.<br><br>SVG export is the one exception: the export shell has no outline, so `renderSvg` overrides `canvasWidth` with the shell's own width (see `LgvSvgBodyProps`).</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-canvaswidthpx) |
| <span id="getter-canrender">**canRender**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overrides `RenderLifecycleMixin`'s default-true hook with the LGV precondition both foundations share — see `foundationCanRender`.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-canrender) |
| <span id="getter-viewportwithinloadeddata">**viewportWithinLoadedData**</span><br><code>boolean</code> | <span data-pagefind-ignore>true when every visible block lies within an already-fetched region — i.e. the viewport shows data we actually loaded, not the stale fringe left after a zoom-out/pan. Drives the loading overlay through the pre-refetch debounce.<br><br>**Spatial only, and it stays that way.** Whether the data held for a block is still what a fetch would bring back is `isCacheValid`, which `dataCurrent` conjoins for the export gate. The scrim reads this getter alone: a phase that went `loading` on a moved `regionFetchKey` would raise the overlay into every zoom.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-viewportwithinloadeddata) |
| <span id="getter-viewportempty">**viewportEmpty**</span><br><code>boolean</code> | <span data-pagefind-ignore>No content block is on screen, so this display has nothing to fetch and nothing to paint — see `viewportEmpty.ts` for the one viewport that reaches it, how narrow that is, and why the state still has to be terminal rather than a permanent scrim. Both foundations declare it over that one expression, the same way they each declare `host` and `paintInert`.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-viewportempty) |
| <span id="getter-renderblocks">**renderBlocks**</span><br><code>RenderBlock[]</code> | <span data-pagefind-ignore>Shared cached view for every LGV-based GPU display. A single displayedRegion may produce multiple render blocks (shared GPU buffer, different scissor clips on screen). Plugins that want to suppress rendering in certain states (e.g. no domain yet) can override this getter to return [] — the autorun lifecycle will then issue an empty-blocks render that clears the canvas.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-renderblocks) |
| <span id="getter-datacurrent">**dataCurrent**</span><br><code>boolean</code> | <span data-pagefind-ignore>This family's answer to the shared freshness question every display foundation must answer (`dataCurrent`): the held data corresponds to what is on screen right now. Four terms — spatial coverage of every visible block, `loadedRegions.size` to rule out the vacuously-true empty viewport, `isCacheValid` per block, and the display's own `dataSuperseded`. Regions stream in one at a time, so this (not "the first datum arrived") is what keeps a multi-region/whole-genome export complete.<br><br>**`isCacheValid` belongs here and not in the scrim.** Coverage answers "is the data here", never "is it what a fetch now would bring back", so a zoom that moves `regionFetchKey` leaves every held region covered and stale at once — and an export sampling `svgReady` across that window painted bins the worker computed for the previous zoom. `displayPhase` still reads `viewportWithinLoadedData` alone: folding staleness into the phase raises the loading scrim into every zoom, which is the trade REJECTED_IDEAS.md "Folding content staleness into `displayPhase`" turned down and this does not take.<br><br>The term cannot latch, and the reason is structural rather than a case list: a block reaches `fetchNeeded` unless `planRegionFetch` finds it ungated, covered AND cache-valid, and it reads that last term tracked. The `&&` short-circuits ahead of it drop its observables only where the block is fetched anyway, so the key move that closes this gate is the same read, in the same dependency set, that wakes the refetch reopening it.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-datacurrent) |
| <span id="getter-loadedassembly">**loadedAssembly**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { error: unknown; loadingP: Promis…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(ModelInstanceTypeProps&lt;…&gt; &amp; { error: unknown; loadingP: Promise&lt;…&gt; &#124; undefined; ... 10 more ...; refNameMismatches: Map&lt;…&gt;; } &amp; ... 13 more ... &amp; IStateTreeNode&lt;...&gt;) &#124; undefined</code></pre></dialog></span> | <span data-pagefind-ignore>The assembly the data in hand came from, once it can answer about refNames — `undefined` before that.<br><br>Off the first LOADED region rather than the view's displayed ones, which is the distinction that makes it belong here: a display holding fetched data is asking about the assembly THAT data is on, and the view's regions can already have moved on.<br><br>The `initialized` gate is why this returns the assembly rather than its name. `getCanonicalRefName2` and `refNameToIndex` answer WRONGLY rather than throwing before the aliases land — identity, and a miss — so a caller that skips the gate gets a plausible answer and no signal. Handing back `undefined` until it can answer is what makes the caller write its fallback.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-loadedassembly) |
| <span id="getter-svgready">**svgReady**</span><br><code>boolean</code> | <span data-pagefind-ignore>true once an off-screen (SVG) export can safely read this display's data. Policy single-sourced in `computeSvgReady`; this family supplies only the freshness half, which `foundationSvgReady` reads as `dataCurrent` or the vacuous currency of `viewportEmpty`. Off-screen renderers gate on it via `awaitSvgReady(model)` instead of inlining the condition.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-svgready) |
| <span id="getter-paintinert">**paintInert**</span><br><code>boolean</code> | <span data-pagefind-ignore>Fills `RenderLifecycleMixin`'s `paintInert` hook — see there for why a failed fetch has to read as finished to the consumers outside the display, and `foundationPaintInert` for the second such state and why both fetch families answer it through one function. Overridable, as the hook is: a display with a third inert state of its own says so here.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-paintinert) |
| <span id="getter-displayphase">**displayPhase**</span><br><code>DisplayPhase</code> | <span data-pagefind-ignore>The display's mutually-exclusive visual state, mapped in `foundationDisplayPhase` — every foundation calls it and supplies only its staleness argument, so a term added to `computeLoadingTerm` reaches all three without being wired three times.<br><br>This family's argument is spatial: `loading` also covers stale data (viewport past loaded) still on screen through the pre-refetch debounce. A thunk, so a suppressed or already-loading display doesn't subscribe to viewport churn.<br><br>A subclass customizes this through `fetchInert` (FetchMixin), never by overriding the getter — see that hook.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#getter-displayphase) |
| <span id="getter-densitygateenabled">**densityGateEnabled**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the density axis applies. `CanvasFeatureGateMixin` contributes `true` beside its measurement; byte-only displays leave it.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-densitygateenabled) |
| <span id="getter-bytegateadapterconfig">**byteGateAdapterConfig**</span><br><code>Record&lt;string, unknown&gt;</code> | <span data-pagefind-ignore>The adapter config the gate measures — the one at `byteGateAdapterPath`. Overridable for a display whose adapter config is synthesized rather than read off the track.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-bytegateadapterconfig) |
| <span id="getter-configuredfetchsizelimit">**configuredFetchSizeLimit**</span><br><code>number</code> | <span data-pagefind-ignore>The display's `fetchSizeLimit` slot, from `regionTooLargeConfigSchemaFields`.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-configuredfetchsizelimit) |
| <span id="getter-densitytoolarge">**densityTooLarge**</span><br><code>boolean</code> | <span data-pagefind-ignore>The density axis's verdict; canvas overrides it.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-densitytoolarge) |
| <span id="getter-bytegateadapterpath">**byteGateAdapterPath**</span><br><code>string[]</code> | <span data-pagefind-ignore>Where on the track config the measured adapter sits. A tiered display overrides this one hook (MAF: `['adapter', 'summaryAdapter']` while `showSummary`), and both the measurement and the budget follow it.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-bytegateadapterpath) |
| <span id="getter-adapterfetchsizelimit">**adapterFetchSizeLimit**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>The measured adapter's own `fetchSizeLimit` slot, read off the live track config rather than the `adapterConfig` snapshot, which omits slots at their default.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-adapterfetchsizelimit) |
| <span id="getter-configforceload">**configForceLoad**</span><br><code>boolean</code> | <span data-pagefind-ignore>The declarative `forceLoad` slot.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-configforceload) |
| <span id="getter-gateviewport">**gateViewport**</span><br><code>GateViewport &#124; undefined</code> | <span data-pagefind-ignore>What a measurement taken now would be about: the span on screen and a key for the stretch of genome it covers. Undefined until the view is measured, and the mixin's only read of the view. Captured before the fetch's round trip, never at commit.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gateviewport) |
| <span id="getter-bytegateadapterkey">**byteGateAdapterKey**</span><br><code>string</code> | <span data-pagefind-ignore>Which tier the estimate is about, as a comparable string.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-bytegateadapterkey) |
| <span id="getter-aboveforceloadfloor">**aboveForceLoadFloor**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the span on screen is at or above `AUTO_FORCE_LOAD_BP`, the one comparison against that constant. False on an unmeasured view.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-aboveforceloadfloor) |
| <span id="getter-gateexempt">**gateExempt**</span><br><code>boolean</code> | <span data-pagefind-ignore>Nothing may gate on either axis: the `forceLoad` slot or the button.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gateexempt) |
| <span id="getter-estimatedfetchbytes">**estimatedFetchBytes**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>The stored estimate's bytes; undefined when nothing has been measured.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-estimatedfetchbytes) |
| <span id="getter-gatemeasurementstale">**gateMeasurementStale**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the last measurement is about a viewport the user has since left. True before any measurement.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gatemeasurementstale) |
| <span id="getter-gatebytelimit">**gateByteLimit**</span><br><code>number</code> | <span data-pagefind-ignore>The byte budget: the adapter's limit, else the display's, doubled below `AUTO_FORCE_LOAD_BP`. Read only through `resolvedByteLimit()`.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gatebytelimit) |
| <span id="getter-gateactive">**gateActive**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the gate may act right now, on any axis: opted in, not exempt, view measured. The view is read last, so an ungated display never touches it.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gateactive) |
| <span id="getter-densitygateactive">**densityGateActive**</span><br><code>boolean</code> | <span data-pagefind-ignore>`gateActive` plus the density axis's own terms: the axis is on, and the span is above the floor.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-densitygateactive) |
| <span id="getter-toolargestatus">**tooLargeStatus**</span><br><code>RegionTooLargeStatus</code> | <span data-pagefind-ignore>The verdict and its banner text, from the stored estimate against `resolvedByteLimit()` and the density axis when it may act.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-toolargestatus) |
| <span id="getter-regiontoolarge">**regionTooLarge**</span><br><code>boolean</code> |  | [RegionTooLargeMixin](../regiontoolargemixin#getter-regiontoolarge) |
| <span id="getter-regiontoolargereason">**regionTooLargeReason**</span><br><code>string</code> | <span data-pagefind-ignore>Banner text for the axis that tripped; empty when not too large.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-regiontoolargereason) |
| <span id="getter-zoomcanreleasegate">**zoomCanReleaseGate**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether "zoom in to see features" is honest advice. Density always releases on zoom; bytes only if the last zoom-in moved the estimate.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-zoomcanreleasegate) |
| <span id="getter-gateskipsmeasuredviewport">**gateSkipsMeasuredViewport**</span><br><code>boolean</code> | <span data-pagefind-ignore>The skip both fetch skeletons apply: the banner is up and its measurement already describes the viewport on screen.</span> | [RegionTooLargeMixin](../regiontoolargemixin#getter-gateskipsmeasuredviewport) |
| <span id="getter-renderscanvas">**rendersCanvas**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default true): whether this display paints a canvas in its **current** configuration, as opposed to a deliberate static placeholder (LD with the triangle off, sequence past base resolution — both render a message where the `<canvas>` would go, so `canvasRef` is never called and `canvasDrawn` can never flip).<br><br>Lives here, beside `canvasDrawn`, because every consumer of "has this display painted" needs the pair — and until 2026-08 each family declared its own copy (per-region hard-coded `true`, global carried the hook for LD), so a display could express the state only to whichever family it happened to compose. See `painted` below for the reader that was missed.</span> | [RenderLifecycleMixin](../renderlifecyclemixin#getter-renderscanvas) |
| <span id="getter-painted">**painted**</span><br><code>boolean</code> | <span data-pagefind-ignore>**The first-paint answer every consumer outside the display should read**, `canvasDrawn` being only the raw flag: a display that is deliberately not painting a canvas has finished, and saying otherwise is a lie that never resolves.<br><br>The two `rendersCanvas: false` states each had three of their four consumers wired by hand — the loading scrim (`rendersCanvas` / `fetchInert`) and the SVG export (`fetchInert`) — while the fourth, `data-display-drawn`, went on publishing `"false"` forever off the raw flag. That attribute is what `PENDING_DISPLAYS` (`@jbrowse/browser-test-utils`) selects on, so a zoomed-out reference sequence track made every `waitForDisplaysDone` on the page burn its full timeout — silently, since that wait swallows its own. Same shape as `fetchInert` on the comparative side: the reader you forget is the one outside the display, so the display has to publish one name for it.<br><br>`paintInert` is the third term and the same argument once more, for the state where a display *would* paint a canvas and never gets to — a fetch that failed before first paint. See that hook.</span> | [RenderLifecycleMixin](../renderlifecyclemixin#getter-painted) |
| <span id="getter-isloading">**isLoading**</span><br><code>boolean</code> | <span data-pagefind-ignore>true while a fetch is active</span> | [FetchMixin](../fetchmixin#getter-isloading) |
| <span id="getter-isloadingorcanceled">**isLoadingOrCanceled**</span><br><code>boolean</code> | <span data-pagefind-ignore>`isLoading` widened to cover a user-canceled load. **This, not `isLoading`, is what a `displayPhase` loading term wants.** `cancelFetchByUser` clears the stop token synchronously, so `isLoading` goes false the instant the user clicks Cancel — and the loading overlay that unmounts on it is carrying the Retry button, which is the only way back: the state is deliberately durable, so no autorun restarts the fetch on its own. A bare `isLoading` therefore reads as `ready` over a display that is stopped, empty and offering nothing.<br><br>Arc read `isLoading` directly and had exactly that hole. It is a getter here so no family has to remember the second term.</span> | [FetchMixin](../fetchmixin#getter-isloadingorcanceled) |
| <span id="getter-fetchinert">**fetchInert**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default false): the states where this display deliberately never fetches, so it holds no data and none is coming. Sequence sets it past base resolution ("Zoom in to see sequence"); LD sets it with the triangle toggled off.<br><br>**One hook, three readers**, and that is the whole point — a display that grows such a state has one thing to say rather than three, and the reader it would have forgotten is always the one outside itself:<br><br>- the loading scrim (`computeLoadingTerm`), which otherwise parks over the placeholder, permanently once a cancel has been clicked; - the SVG export (`computeSvgReady`'s `extraTerminal`), whose `awaitSvgReady` is an unbounded `when`, so one such display hangs the whole view's export; - the dev-only retry check (`makeRetryContractCheck`), which would otherwise report a dead Retry on a display correctly declining to load anything.<br><br>It was three hooks — `loadingSuppressed`, `svgReadyExtraTerminal` on each of the two foundations, and `fetchInert` on the comparative family, which had already collapsed them. Both LGV displays that override it returned one expression for all three, and one of the three was hard-coded `false` on the global family for a while, which is how LD came to be able to express only half its own state. Same name and same meaning as `SyntenyFetchStateMixin.fetchInert` now, so the retry check reads one field across all three fetch families. ADR-082.<br><br>A hook rather than a `displayPhase` override, because overriding the getter means restating the whole loading condition — which is how sequence came to hold a verbatim copy of the other terms, one `git blame` away from silently missing the next one added.<br><br>It lives **here** because this is the one mixin all three display foundations compose. Same argument, one level down, that put `rendersCanvas` on `RenderLifecycleMixin` beside `canvasDrawn`.</span> | [FetchMixin](../fetchmixin#getter-fetchinert) |
| <span id="getter-awaitingprerequisite">**awaitingPrerequisite**</span><br><code>boolean</code> | <span data-pagefind-ignore>Overridable hook (default false), read only by the dev-only retry check (`makeRetryContractCheck`): "this run declined because a prerequisite fetch in another autorun has not landed, and its arrival wakes this one again". It **defers** the retry verdict to that later run rather than waiving it, so a display cannot spend its retry on a decline it called preliminary.<br><br>Two displays say it, one per fetch foundation, which is why it lives beside `fetchInert` rather than on either: HiC's contacts fetch declines until `CoreGetInfo` lands, and `MultiSampleVariantBaseModel`'s `fetchNeeded` declines until `sourcesBase` does. Both have a `reload()` that wakes the prerequisite's autorun as well as their own.<br><br>**It has to be strictly narrower than the gate it explains.** One that restates the gate's negation makes every decline a deferred one, so no run is ever judged and the display has silently opted out — an exemption by another name. HiC is in that shape deliberately, because its gate and its prerequisite are one condition; what covers its retry instead is `LinearHicDisplay/infoFetchFailure.test.ts`.<br><br>Not for a display deliberately not fetching at all — that is `fetchInert` above, which the loading scrim and the export read too.</span> | [FetchMixin](../fetchmixin#getter-awaitingprerequisite) |
| <span id="getter-rpcpropscachekey">**rpcPropsCacheKey**</span><br><code>string</code> | <span data-pagefind-ignore>The RPC cache key both fetch foundations invalidate on: this display's `rpcProps()` payload serialized to a string. `serializeRpcProps` owns the why, including the silently-dead-axis corollary.<br><br>Here, beside the two hooks above, for the same reason they are: it describes the display, and every foundation composes this mixin. The per-region family watches it from `SettingsInvalidate` and the global one from its fetch autorun's trigger list — one getter and one name, so the two cannot come to invalidate on different axes. The global side built its own local `computed` over the same function until 2026-08, which was the same value under a second spelling.</span> | [FetchMixin](../fetchmixin#getter-rpcpropscachekey) |
| <span id="getter-scaletype">**scaleType**</span><br><code>string</code> |  | [ScoreScaleMixin](../scorescalemixin#getter-scaletype) |
| <span id="getter-autoscaletype">**autoscaleType**</span><br><code>string</code> |  | [ScoreScaleMixin](../scorescalemixin#getter-autoscaletype) |
| <span id="getter-numstddev">**numStdDev**</span><br><code>number</code> |  | [ScoreScaleMixin](../scorescalemixin#getter-numstddev) |
| <span id="getter-minscore">**minScore**</span><br><code>number</code> | <span data-pagefind-ignore>Raw slot value, sentinel intact — see the class comment.</span> | [ScoreScaleMixin](../scorescalemixin#getter-minscore) |
| <span id="getter-maxscore">**maxScore**</span><br><code>number</code> | <span data-pagefind-ignore>Raw slot value, sentinel intact — see the class comment.</span> | [ScoreScaleMixin](../scorescalemixin#getter-maxscore) |
| <span id="getter-defaultscoredomain">**defaultScoreDomain**</span><br><code>[number &#124; undefined, number &#124; undefined]</code> | <span data-pagefind-ignore>Overridable hook: what each end of the domain falls back to where the config leaves its bound unset. `[undefined, undefined]` — the default — means autoscale both ends, which is right for a track whose scores have no absolute meaning (a bigwig's units are its own).<br><br>A display whose scores are bounded *by construction* overrides it, so the axis stops being a function of what happens to be on screen: GC content is a fraction, so 0 and 1 are its real limits and mean the same thing at every locus. Autoscaled, the same GC value drew at different heights depending on where the user had panned, and the track could not be read across loci.<br><br>A hook rather than a config default because the answer can depend on display state — GC's does, on `gcMode` — and rather than each display re-resolving the sentinels below, which is the one thing that must not be duplicated: config bounds still win, precisely because they are checked before this is consulted.</span> | [ScoreScaleMixin](../scorescalemixin#getter-defaultscoredomain) |
| <span id="getter-minscorebound">**minScoreBound**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>Resolved lower bound; `undefined` means autoscale this end.</span> | [ScoreScaleMixin](../scorescalemixin#getter-minscorebound) |
| <span id="getter-maxscorebound">**maxScoreBound**</span><br><code>number &#124; undefined</code> | <span data-pagefind-ignore>Resolved upper bound; `undefined` means autoscale this end.</span> | [ScoreScaleMixin](../scorescalemixin#getter-maxscorebound) |
| <span id="getter-showlegend">**showLegend**</span><br><code>boolean</code> | <span data-pagefind-ignore>Whether the legend is drawn. Resolved through the promotable-slot tiers (`resolveConf`): an explicit track value customizes it either way, otherwise it follows the session-wide default for this display type, falling back to the slot's `promotedBase`.</span> | [LegendMixin](../legendmixin#getter-showlegend) |
| <span id="getter-showlegenddisplaytypedefault">**showLegendDisplayTypeDefault**</span><br><code>Pin</code> | <span data-pagefind-ignore>The "make the current legend visibility the default for all tracks" control. Symmetric, so it promotes whichever value the track currently shows. `showLegendCheckboxItem` takes this as its `pin`.</span> | [LegendMixin](../legendmixin#getter-showlegenddisplaytypedefault) |

## Methods

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="method-rpcprops">**rpcProps**</span><br><code>() =&gt; {…}</code> | Adds the resolved detail tier to the base alignments RPC payload. | LGVSyntenyDisplay |
| <span id="method-contextmenuitems">**contextMenuItems**</span><br><code>() =&gt; MenuItem[]</code> |  | LGVSyntenyDisplay |
| <span id="method-trackmenuitems">**trackMenuItems**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>() =&gt; (MenuItem &#124; { label: string; icon: OverridableComponent&lt;S…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>() =&gt; (MenuItem &#124; { label: string; icon: OverridableComponent&lt;SvgIconTypeMap&lt;{}, "svg"&gt;&gt; &amp; { muiName: string; }; type: "subMenu"; subMenu: (MenuItem &#124; { ...; })[]; } &#124; { ...; })[]</code></pre></dialog></span> |  | LGVSyntenyDisplay |
| <span id="method-sashimiarcsmodedisplaytypedefault">**sashimiArcsModeDisplayTypeDefault**</span><br><code>(mode: "auto" &#124; "down" &#124; "up") =&gt; Pin</code> | <span data-pagefind-ignore>"make this arc placement the default for all tracks" control (pin), one per option of the radio group. A method rather than a getter per value: the options share one slot and differ only in the on-value, so naming each combination was what made the base value 'up' look unpinnable.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-sashimiarcsmodedisplaytypedefault) |
| <span id="method-isgroupcollapsed">**isGroupCollapsed**</span><br><code>(key: string) =&gt; boolean</code> | <span data-pagefind-ignore>Whether a stacked group's pileup is collapsed to just its coverage.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-isgroupcollapsed) |
| <span id="method-hasgroupheightoverride">**hasGroupHeightOverride**</span><br><code>(key: string) =&gt; boolean</code> | <span data-pagefind-ignore>Whether a stacked group carries a custom pileup-height override — set by expanding it (show all reads) or dragging its resize handle (taller or shorter). Drives the group label's restore-to-fit affordance.<br><br>The overrides IN EFFECT, so it cannot say a lane is sized while the layout lays it out on the shared budget — see `groupHeightOverrides`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-hasgroupheightoverride) |
| <span id="method-legenditems">**legendItems**</span><br><code>() =&gt; LegendItem[]</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-legenditems) |
| <span id="method-arclegenditems">**arcLegendItems**</span><br><code>() =&gt; LegendItem[]</code> | <span data-pagefind-ignore>Key for the paired-end arc / read-cloud colors. Empty when no overlay is drawn, or when it shares the reads' scheme and merged into their key — either way its legend section drops out of the box. A *partial* overlap is not resolved here: this stays the complete arc key, and `getAlignmentsLegendSections` folds it into one deduped list.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-arclegenditems) |
| <span id="method-findfeatureinrpcdata">**findFeatureInRpcData**</span><br><code>(featureId: string) =&gt; ReadHit &#124; undefined</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-findfeatureinrpcdata) |
| <span id="method-lanefor">**laneFor**</span><br><code>(key: string) =&gt; AlignmentLane &#124; undefined</code> | <span data-pagefind-ignore>One lane by group key, for the per-key questions a component asks with a `groupKey` in hand. `undefined` for a key that isn't drawn.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-lanefor) |
| <span id="method-groupclippedby">**groupClippedBy**</span><br><code>(key: string) =&gt; RowCapSource &#124; undefined</code> | <span data-pagefind-ignore>Which cap hid reads from a lane's pileup, or `undefined` when nothing was hidden — including for a key that isn't drawn. A read of what the layout pass recorded (`RowCapSource` names them), not a re-derivation: the pass is handed its cap with the policy attached, so the answer comes back out of the layout instead of being reconstructed from a row count afterwards.<br><br>Which cap it was decides what may be offered, and only one answer can be right: expanding a lane banks an override of `maxHeight` px, so a lane already clipped at that ceiling gets the identical cap back — not one extra read appears, while the override silences the flag. The reconstruction this replaced compared a lane's rows against the ceiling, which is true whenever the two caps merely differ; a single-section grouping sat wholly in that hole, since one lane takes the ungrouped cap and never a slice.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-groupclippedby) |
| <span id="method-isgrouptruncated">**isGroupTruncated**</span><br><code>(key: string) =&gt; boolean</code> | <span data-pagefind-ignore>True when a lane's pileup was clipped by a cap the per-lane expand can actually raise — the rule behind the "show all" affordance, which must not appear where it would do nothing. The chip itself asks `laneExpandable` off the section it already holds; this is the same question for the callers that have only a key, like `isGroupCeilingClipped` beside it.<br><br>Two of the caps qualify: a lane's viewport slice, and the single row `collapseGroupRows` gives it. Both expand into a true stack, because banking an override opts the lane out of each.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-isgrouptruncated) |
| <span id="method-isgroupceilingclipped">**isGroupCeilingClipped**</span><br><code>(key: string) =&gt; boolean</code> | <span data-pagefind-ignore>True when THIS lane's pileup was clipped by the display-wide `maxHeight` and its overflow reads were collapsed. Drives the rule drawn across the bottom of the clipped rows — see `PileupTruncationRule`, which is per section because the notice marks the place where the reads stop rather than a state of the whole track.<br><br>A lane field (`ceilingClipped`), so the overlay that walks sections reads it off the section it already holds; this exists for the callers that have only a key. The two display-wide suppressions live where the field is built.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-isgroupceilingclipped) |
| <span id="method-bezierlegenditems">**bezierLegendItems**</span><br><code>() =&gt; LegendItem[]</code> | <span data-pagefind-ignore>Legend swatches for the linked-read connection curves, empty unless the overlay has something to draw (`bezierArcScope`) and at least one connection is in view — including the cross-region connectors chain mode draws without the curved-connector box ticked, since those are colored by the same rules and a color on screen needs its key.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-bezierlegenditems) |
| <span id="method-grouppileupoffset">**groupPileupOffset**</span><br><code>(groupKey: string) =&gt; number</code> | <span data-pagefind-ignore>Content-space Y of a group's pileup relative to the reserved below-coverage height, i.e. how far a read's row shifts because its group is stacked below the others. 0 for the ungrouped/first section, except when that lane drops its arc band (`hasArcs` false), where it goes slightly negative — callers add `coverageDisplayHeight` back, so the sum is the section's real `pileupTop` either way.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-grouppileupoffset) |
| <span id="method-searchfeaturebyid">**searchFeatureByID**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(featureId: string) =&gt; [number, number, number, number] &#124; undef…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(featureId: string) =&gt; [number, number, number, number] &#124; undefined</code></pre></dialog></span> | <span data-pagefind-ignore>Layout rect of a read, for cross-view overlays (BreakpointSplitView's connection curves). Y is relative to the pileup's own top — the caller adds the display's `coverageDisplayHeight` itself (see `computeOverlayY`) — so a grouped read only needs its section's extra stacking offset on top of its row. Without that offset every read outside the first section anchored as if it were in the first one.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-searchfeaturebyid) |
| <span id="method-readidssharingchain">**readIdsSharingChain**</span><br><code>(rpcData: WorkerPileupData, index: number) =&gt; string[]</code> | <span data-pagefind-ignore>Read ids sharing a chain with the read at `index` in `rpcData` — the read's own included, since it is a member of its chain. Empty when the read isn't part of a chain. Shared by hover-highlight and click-select so the two paths can't drift.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-readidssharingchain) |
| <span id="method-getfeatureinfobyid">**getFeatureInfoById**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(featureId: string) =&gt; { id: string; name: string; start: numbe…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(featureId: string) =&gt; { id: string; name: string; start: number; end: number; flags: number; mapq: number; strand: number; refName: string; assemblyName: string; } &#124; undefined</code></pre></dialog></span> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-getfeatureinfobyid) |
| <span id="method-reportarccap">**reportArcCap**</span><br><code>(groupKey: string, dropped: number, kept: number) =&gt; void</code> | <span data-pagefind-ignore>Warn that a lane's cross-region arcs were capped — once per NUMBER rather than once per evaluation. `crossRegionArcSections` re-projects every foot through `view.bpToPx`, so it reads `view.offsetPx` and MobX re-evaluates it on every pan frame; that is correct and necessary, but a bare `console.warn` in there fires per frame for as long as a capped lane is on screen, which is a console nobody can read anything else in.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#method-reportarccap) |
| <span id="method-renderingprops">**renderingProps**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>() =&gt; { displayModel: ModelInstanceTypeProps&lt;{ id: IOptionalITy…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>() =&gt; { displayModel: ModelInstanceTypeProps&lt;{ id: IOptionalIType&lt;…&gt;; type: ISimpleType&lt;string&gt;; }&gt; &amp; { ...; } &amp; { ...; } &amp; { ...; } &amp; IStateTreeNode&lt;...&gt;; }</code></pre></dialog></span> | <span data-pagefind-ignore>props passed to the renderer's React "Rendering" component. these are client-side only and never sent to the worker. includes displayModel and callbacks</span> | [BaseDisplay](../basedisplay#method-renderingprops) |
| <span id="method-regionhasdata">**regionHasData**</span><br><code>(_displayedRegionIndex: number) =&gt; boolean</code> | <span data-pagefind-ignore>Overridable hook (default true): whether the display can actually draw what this region is marked loaded over. Two different displays want it for two different reasons, and both are real:<br><br>- **The reader-side check of the write-side rule.** `loadedRegions` is written where the payload is stored (`RegionFetchContext`), so an entry with nothing behind it means that rule was broken somewhere. Answering off the data map costs a lookup and decides which way the break fails: a refetch, or a viewport that reads as covered against data nobody has and never asks again. Both canvas displays. - **Which of several held payloads answers.** MAF caches a summary tier and a detail tier side by side under one `displayedRegionIndex`, so crossing the threshold inside an already-loaded region changes which map has to answer — something the coverage bounds cannot see at all.<br><br>Separate from `regionFetchKey` on purpose: for MAF a key would refetch the summary on every zoom back out, since both tiers are still held. And the mixin cannot see a display's data map, so a key that changed when data arrived would be the `rpcProps()` loop in different clothes.<br><br>**The fail-open default is load-bearing, not an omission.** A byte-gate refusal never marks a region loaded (the commit sits beside the store and skips refused results), so "marked loaded with nothing behind it" is unreachable from the gate — the one path that stamps without storing is sequence's legitimately-empty-region answer, and a store-derived default there would refetch forever: stamp, store nothing, read uncovered, fetch again. `true` is what lets "this fetch completed and there is genuinely nothing here" be a terminal state.<br><br>A view, not an action, for the reason `regionFetchKey` is a getter.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#method-regionhasdata) |
| <span id="method-iscachevalid">**isCacheValid**</span><br><code>(displayedRegionIndex: number) =&gt; boolean</code> | <span data-pagefind-ignore>Whether the data held for a region still answers the current view. Not a hook a display fills: a display states its rule as `regionFetchKey` (what a fetch now would produce) and `regionHasData` (did the last one store anything), and this compares the key against the one the region was fetched under. A subclass that changes what it fetches spells the change in the key, and one that forgets gets a redundant fetch rather than a cached answer for a zoom the data was never fetched at.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#method-iscachevalid) |
| <span id="method-resolvedbytelimit">**resolvedByteLimit**</span><br><code>() =&gt; number &#124; undefined</code> | <span data-pagefind-ignore>The budget the worker enforces and the banner compares against — the one spelling of that pair. Undefined when the gate may not act.</span> | [RegionTooLargeMixin](../regiontoolargemixin#method-resolvedbytelimit) |
| <span id="method-gatefetchstate">**gateFetchState**</span><br><code>() =&gt; GateFetchState</code> | <span data-pagefind-ignore>The gate as it stands for a fetch about to be issued. Calling it is the capture, which is why it is a method.</span> | [RegionTooLargeMixin](../regiontoolargemixin#method-gatefetchstate) |

## Actions

<!-- prettier-ignore -->
| Member | Description | Defined by |
| --- | --- | --- |
| <span id="action-sethideselfalignments">**setHideSelfAlignments**</span><br><code>(flag: boolean) =&gt; void</code> | Show/hide the view's own assembly lane of an all-vs-all track. | LGVSyntenyDisplay |
| <span id="action-setlodmode">**setLodMode**</span><br><code>(arg: LodMode) =&gt; void</code> |  | LGVSyntenyDisplay |
| <span id="action-setshowcoverage">**setShowCoverage**</span><br><code>(show: boolean) =&gt; void</code> | <span data-pagefind-ignore>The other half of the sashimi/coverage tie. Without it, hiding coverage left "Show sashimi arcs" ticked over a display drawing none — and the worker skips the junction scan entirely when the band is off (`runCoveragePipeline`), so the arcs the checkbox advertised had no data behind them either.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setshowcoverage) |
| <span id="action-clearmouseoverstate">**clearMouseoverState**</span><br><code>() =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-clearmouseoverstate) |
| <span id="action-seterror">**setError**</span><br><code>(error?: unknown) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-seterror) |
| <span id="action-setrpcdata">**setRpcData**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(displayedRegionIndex: number, data: GroupedAlignmentsResult &#124;…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(displayedRegionIndex: number, data: GroupedAlignmentsResult &#124; null) =&gt; void</code></pre></dialog></span> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setrpcdata) |
| <span id="action-cleardisplayspecificdata">**clearDisplaySpecificData**</span><br><code>() =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-cleardisplayspecificdata) |
| <span id="action-clearselection">**clearSelection**</span><br><code>() =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-clearselection) |
| <span id="action-setselectedchainreadids">**setSelectedChainReadIds**</span><br><code>(ids: string[]) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setselectedchainreadids) |
| <span id="action-setcolorscheme">**setColorScheme**</span><br><code>(colorBy: ColorBy) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setcolorscheme) |
| <span id="action-setfilterby">**setFilterBy**</span><br><code>(filterBy: FilterBy) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setfilterby) |
| <span id="action-setshowsoftclipping">**setShowSoftClipping**</span><br><code>(value: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setshowsoftclipping) |
| <span id="action-setmismatchalpha">**setMismatchAlpha**</span><br><code>(value: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setmismatchalpha) |
| <span id="action-setsortedby">**setSortedBy**</span><br><code>(type: string, tag?: string &#124; undefined) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setsortedby) |
| <span id="action-setsortslot">**setSortSlot**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(sortedBy: { type: string; pos: number; refName: string; assemb…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(sortedBy: { type: string; pos: number; refName: string; assemblyName: string; tag?: string &#124; undefined; }) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Commit a sort, the single place the `sortedBy` slot is written. Also drops the layout-order flags: they are peer radios in one group ("Longest reads first" and "Spliced reads first" are flags, a sort is the slot), so exactly one must hold state. Doing it here rather than at the menu means a sort that *doesn't* land — no valid center line, a cancelled tag dialog — leaves the previous ordering intact instead of silently clearing it and unchecking every radio. `computeMultiRegionLayout` would tolerate both being set (an explicit sort wins there anyway); this keeps the menu's checkmarks honest.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setsortslot) |
| <span id="action-setsortedbyatposition">**setSortedByAtPosition**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(arg: { type: string; pos: number; refName: string; tag?: strin…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(arg: { type: string; pos: number; refName: string; tag?: string &#124; undefined; }) =&gt; void</code></pre></dialog></span> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setsortedbyatposition) |
| <span id="action-clearsortedby">**clearSortedBy**</span><br><code>() =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-clearsortedby) |
| <span id="action-setlargefeaturesfirst">**setLargeFeaturesFirst**</span><br><code>(flag: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setlargefeaturesfirst) |
| <span id="action-setsplicedreadsfirst">**setSplicedReadsFirst**</span><br><code>(flag: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setsplicedreadsfirst) |
| <span id="action-setgroupby">**setGroupBy**</span><br><code>(groupBy?: GroupBy &#124; undefined) =&gt; void</code> | <span data-pagefind-ignore>Set (or remove, when undefined) the in-track stacked grouping dimension. A tier-1 refetch setting (in `rpcProps`) — the worker re-partitions the fetch into N sections. Resets the Y scroll since the stacked content height changes. Ungrouping stores an explicit `null` override (not a cleared override) so it beats a configured `groupBy` default rather than falling back to it.<br><br>Doesn't drop the per-lane state: `AlignmentsGroupKeySpaceReset` does that for this write and for the ones no action of this display makes.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setgroupby) |
| <span id="action-dropgrouplanestate">**dropGroupLaneState**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Forget every collapse and height override. Each is keyed by group key, and a group key only names a lane within the grouping that issued it, so a key-space change invalidates all of them at once.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-dropgrouplanestate) |
| <span id="action-setcollapsegrouprows">**setCollapseGroupRows**</span><br><code>(flag: boolean) =&gt; void</code> | <span data-pagefind-ignore>Draw each group as one row (overlap depth shows as tint shading) rather than as its own stack. Clears the per-group height overrides: an override means "this lane opted out of the collapse", which is meaningless once every lane is a stack again.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setcollapsegrouprows) |
| <span id="action-togglegroupcollapsed">**toggleGroupCollapsed**</span><br><code>(key: string) =&gt; void</code> | <span data-pagefind-ignore>Collapse/expand a stacked group's pileup (coverage stays visible).</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-togglegroupcollapsed) |
| <span id="action-togglegroupexpanded">**toggleGroupExpanded**</span><br><code>(key: string) =&gt; void</code> | <span data-pagefind-ignore>Expand a fit-to-viewport group back to the full `maxHeight` cap (show all its reads), or, if it already carries a height override (from expand or a drag), drop the override to return it to the fit budget. Expanding makes the stack overflow the viewport, which engages the pileup scroll. Pairs with `hasGroupHeightOverride`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-togglegroupexpanded) |
| <span id="action-resizegroupheight">**resizeGroupHeight**</span><br><code>(key: string, dy: number) =&gt; void</code> | <span data-pagefind-ignore>Drag a stacked group's pileup band taller/shorter by `dy` px, capping how many rows that group lays out. The continuous-accumulation policy (seed once, floor at a row, pin/skip a fully-shown group) lives in the pure `nextGroupHeightOverride`; this action just gathers the group's live state and commits the result (undefined = leave on the fit budget). Pairs with `hasGroupHeightOverride` / `toggleGroupExpanded`.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-resizegroupheight) |
| <span id="action-setfeatureheight">**setFeatureHeight**</span><br><code>(height?: number &#124; undefined) =&gt; void</code> | <span data-pagefind-ignore>Set the per-read pixel size. The track-sizing mode is a mostly independent axis (changed via setHeightMode): grow keeps growing at the new size. Fit is the exception — it derives the size, so a chosen size would be dormant; picking one drops back to fixed so the pick takes effect.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setfeatureheight) |
| <span id="action-setmaxheight">**setMaxHeight**</span><br><code>(height?: number &#124; undefined) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setmaxheight) |
| <span id="action-setheightmode">**setHeightMode**</span><br><code>(mode: "fit" &#124; "fixed" &#124; "grow") =&gt; void</code> | <span data-pagefind-ignore>The two pieces of transient state a uniform fit/grow contradicts that HeightModeMixin can't know about. The slot write and the scroll reset are its `setHeightMode`, captured as super above.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setheightmode) |
| <span id="action-setfittedheightpx">**setFittedHeightPx**</span><br><code>(px: number) =&gt; void</code> | <span data-pagefind-ignore>Cache the fitted read height so the `featureHeight`/`featureSpacing` getters can split it into a body + derived gap. Written only by the driving autorun.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setfittedheightpx) |
| <span id="action-setshowsashimiarcs">**setShowSashimiArcs**</span><br><code>(show: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setshowsashimiarcs) |
| <span id="action-setreadconnections">**setReadConnections**</span><br><code>(mode?: "arc" &#124; "cloud" &#124; "off" &#124; undefined) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setreadconnections) |
| <span id="action-setreadconnectionsdown">**setReadConnectionsDown**</span><br><code>(down: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setreadconnectionsdown) |
| <span id="action-setdebugarcgeometry">**setDebugArcGeometry**</span><br><code>(on: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setdebugarcgeometry) |
| <span id="action-setshowpileup">**setShowPileup**</span><br><code>(show: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setshowpileup) |
| <span id="action-setcoverageheight">**setCoverageHeight**</span><br><code>(height: number) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setcoverageheight) |
| <span id="action-setcoveragesnpminfrequency">**setCoverageSnpMinFrequency**</span><br><code>(fraction: number) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setcoveragesnpminfrequency) |
| <span id="action-setreadconnectionsheight">**setReadConnectionsHeight**</span><br><code>(height: number) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setreadconnectionsheight) |
| <span id="action-setsashimiarcsheight">**setSashimiArcsHeight**</span><br><code>(height: number) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setsashimiarcsheight) |
| <span id="action-setminsashimiscore">**setMinSashimiScore**</span><br><code>(score: number) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setminsashimiscore) |
| <span id="action-setsashimiarcsmode">**setSashimiArcsMode**</span><br><code>(mode: "auto" &#124; "down" &#124; "up") =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setsashimiarcsmode) |
| <span id="action-setshowsashimilabels">**setShowSashimiLabels**</span><br><code>(show: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setshowsashimilabels) |
| <span id="action-sethidenoncanonicaljunctions">**setHideNonCanonicalJunctions**</span><br><code>(hide: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-sethidenoncanonicaljunctions) |
| <span id="action-setreadconnectionslinewidth">**setReadConnectionsLineWidth**</span><br><code>(width: number) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setreadconnectionslinewidth) |
| <span id="action-setdrawinter">**setDrawInter**</span><br><code>(draw: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setdrawinter) |
| <span id="action-setdrawproperpairarcs">**setDrawProperPairArcs**</span><br><code>(draw: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setdrawproperpairarcs) |
| <span id="action-setmininterchromsupport">**setMinInterchromSupport**</span><br><code>(support: number) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setmininterchromsupport) |
| <span id="action-setdrawlongrange">**setDrawLongRange**</span><br><code>(draw: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setdrawlongrange) |
| <span id="action-setarccolorbytype">**setArcColorByType**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(type: "insertSize" &#124; "insertSizeAndOrientation" &#124; "orientation…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(type: "insertSize" &#124; "insertSizeAndOrientation" &#124; "orientation") =&gt; void</code></pre></dialog></span> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setarccolorbytype) |
| <span id="action-setshowmismatches">**setShowMismatches**</span><br><code>(show: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setshowmismatches) |
| <span id="action-setshowinterbaseindicators">**setShowInterbaseIndicators**</span><br><code>(show: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setshowinterbaseindicators) |
| <span id="action-setflipstrandlongreadchains">**setFlipStrandLongReadChains**</span><br><code>(flag: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setflipstrandlongreadchains) |
| <span id="action-setcolorsupplementarychains">**setColorSupplementaryChains**</span><br><code>(flag: boolean) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setcolorsupplementarychains) |
| <span id="action-setlinkedreads">**setLinkedReads**</span><br><code>(mode: "normal" &#124; "off") =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setlinkedreads) |
| <span id="action-setshowbezierconnections">**setShowBezierConnections**</span><br><code>(flag: boolean) =&gt; void</code> | <span data-pagefind-ignore>Toggle the paired-read connection overlay. A main-thread tier-2/4 setting (read in `laidOutPileupMap` + `renderState`), not in `rpcProps` — toggling it never refetches.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setshowbezierconnections) |
| <span id="action-setfeatureidundermouse">**setFeatureIdUnderMouse**</span><br><code>(feature?: string &#124; undefined) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setfeatureidundermouse) |
| <span id="action-setmouseoverextrainformation">**setMouseoverExtraInformation**</span><br><code>(extra?: TooltipPayload &#124; undefined) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setmouseoverextrainformation) |
| <span id="action-sethoverstate">**setHoverState**</span><br><code>(state: {…}) =&gt; void</code> | <span data-pagefind-ignore>The whole hover state in one action. Every branch of the pileup's mousemove handler goes through here — including the plain-read branch, which used to fire three or four separate setters per move and was the only one that left `hoverCoverageBand` stale. `highlightedChainReadIds` is empty outside chain mode.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-sethoverstate) |
| <span id="action-setcontextmenufeature">**setContextMenuFeature**</span><br><code>(feature?: Feature &#124; undefined) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-setcontextmenufeature) |
| <span id="action-closecontextmenu">**closeContextMenu**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Close the right-click menu and release the hover it pinned. `openContextMenu` boxes the read the menu acts on and `handleMouseLeave` holds that box while the menu is up, so this is the only place the pin comes off — without it the box outlives the menu until the cursor next crosses the pileup, which it need not do at all when the item clicked opened a drawer widget. Mirrors canvas LinearBasicDisplay.closeContextMenu.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-closecontextmenu) |
| <span id="action-selectfeature">**selectFeature**</span><br><code>(feature: Feature) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-selectfeature) |
| <span id="action-startrenderingbackend">**startRenderingBackend**</span><br><code>(backend: AlignmentsRenderingBackend) =&gt; void</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-startrenderingbackend) |
| <span id="action-withfeaturebyid">**withFeatureById**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(featureId: string, onFeat: (feat: Feature) =&gt; void) =&gt; Promise…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(featureId: string, onFeat: (feat: Feature) =&gt; void) =&gt; Promise&lt;void&gt;</code></pre></dialog></span> | <span data-pagefind-ignore>Fetch the feature behind `featureId` and hand it to `onFeat`. For a menu item that needs the whole feature but is offered before one is in hand.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-withfeaturebyid) |
| <span id="action-selectfeaturebyid">**selectFeatureById**</span><br><code>(featureId: string) =&gt; Promise&lt;void&gt;</code> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-selectfeaturebyid) |
| <span id="action-opencontextmenu">**openContextMenu**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(args: { anchor: ContextMenuAnchor; hit?: ContextMenuHit &#124; unde…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(args: { anchor: ContextMenuAnchor; hit?: ContextMenuHit &#124; undefined; featureId?: string &#124; undefined; }) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>Open the right-click menu over a hit. The block, the clicked column and whichever mark answered arrive as one `ContextMenuHit`, which is how a consumer is stopped from reading a block without its hit (the split-state class of bug that silently no-op'd position sorts). The read feature is reset now and, when the hit carries one, populated by an async RPC fetch — so "open the menu for this hit and its read" stays a single call and a repositioned menu can't inherit the prior read's items.<br><br>Dropping the hover is part of opening, not a step the caller does first: the tooltip must go, but the highlight box has to survive as a pin on the menu's own read, and that is a clear-then-re-box order no call site should have to know (or get right in a second one).</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-opencontextmenu) |
| <span id="action-fetchneeded">**fetchNeeded**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(needed: { region: Region; displayedRegionIndex: number; }[]) =…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(needed: { region: Region; displayedRegionIndex: number; }[]) =&gt; Promise&lt;void&gt;</code></pre></dialog></span> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-fetchneeded) |
| <span id="action-rendersvg">**renderSvg**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(opts?: ExportSvgDisplayOptions &#124; undefined) =&gt; Promise&lt;ReactEl…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(opts?: ExportSvgDisplayOptions &#124; undefined) =&gt; Promise&lt;ReactElement&lt;unknown, string &#124; JSXElementConstructor&lt;any&gt;&gt; &#124; Iterable&lt;...&gt; &#124; AwaitedReactNode&gt;</code></pre></dialog></span> |  | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-rendersvg) |
| <span id="action-clearhoveredfeature">**clearHoveredFeature**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Fills `BaseDisplay`'s hover-clear hook, which the fetch foundation's reaction calls on every viewport change.<br><br>The pileup is a sticky canvas, so a pan, a zoom or an internal scroll under a stationary cursor fires no mousemove and no mouseleave, and the highlight box and tooltip go on naming the read that *was* there.</span> | [LinearAlignmentsDisplay](../linearalignmentsdisplay#action-clearhoveredfeature) |
| <span id="action-setstatusmessage">**setStatusMessage**</span><br><code>(status?: RpcStatus &#124; undefined) =&gt; void</code> |  | [BaseDisplay](../basedisplay#action-setstatusmessage) |
| <span id="action-reload">**reload**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>base display reload does nothing, see specialized displays for details</span> | [BaseDisplay](../basedisplay#action-reload) |
| <span id="action-setscrolltop">**setScrollTop**</span><br><code>(scrollTop: number) =&gt; void</code> | <span data-pagefind-ignore>Clamped into `[0, scrollableHeight]`, so no caller has to remember the bound. Unbounded for a display that leaves `scrollableHeight` at its `Infinity` default.</span> | [TrackHeightMixin](../trackheightmixin#action-setscrolltop) |
| <span id="action-setheight">**setHeight**</span><br><code>(displayHeight: number) =&gt; number</code> |  | [TrackHeightMixin](../trackheightmixin#action-setheight) |
| <span id="action-resizeheight">**resizeHeight**</span><br><code>(distance: number) =&gt; number</code> |  | [TrackHeightMixin](../trackheightmixin#action-resizeheight) |
| <span id="action-expandtocontentheight">**expandToContentHeight**</span><br><code>() =&gt; number</code> | <span data-pagefind-ignore>Grow the track by exactly the content it is currently hiding, so a display scrolled over a taller stack ends up showing all of it. The track's resize handle runs this on a double click.<br><br>`scrollableHeight` is the whole measurement — it is already every scrolling display's answer to "how much is off the bottom", so no display has to supply a second one. A display that doesn't scroll internally leaves it at `Infinity` and gets a no-op, as does one already showing everything (0).<br><br>Routed through `resizeHeight` rather than `setHeight` so grow mode's override still gets to leave grow first; going straight to the slot would let the reactive height re-derive `grownHeight` and the double click would appear to do nothing.</span> | [TrackHeightMixin](../trackheightmixin#action-expandtocontentheight) |
| <span id="action-setloadedregion">**setLoadedRegion**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(displayedRegionIndex: number, region: Region, fetchKey?: strin…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(displayedRegionIndex: number, region: Region, fetchKey?: string) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>The raw write behind `ctx.commitRegion`, and **not what a fetch should call**: a display naming its own span is the bug this family spent a release on, and going through the context is what makes that inexpressible — see RegionFetchContext. Direct callers are tests staging an already-loaded display.<br><br>An action so callers after an async boundary stay in MST strict mode. Stamps the region with the fetch key its data came back under. `fetchRegions` passes the key it captured before issuing the RPC; the default reads it *now*, which is right for a caller holding the region already and wrong for anything resuming after an await, where the viewport may have moved under the fetch.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-setloadedregion) |
| <span id="action-droploadedregion">**dropLoadedRegion**</span><br><code>(displayedRegionIndex: number) =&gt; void</code> | <span data-pagefind-ignore>Forget one region — for a display pruning what has scrolled off screen.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-droploadedregion) |
| <span id="action-clearallrpcdata">**clearAllRpcData**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>full reset: cancels fetch, clears error, loadedRegions, display-specific data, and the canvas-drawn flag. The too-large gate is derived (a pure function of the cached estimate × viewport), so it needs no explicit clear here — the fetch autorun re-measures at the new viewport and the verdict follows.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-clearallrpcdata) |
| <span id="action-fetchregions">**fetchRegions**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(needed: IndexedRegion[], work: (ctx: RegionFetchContext) =&gt; Pr…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(needed: IndexedRegion[], work: (ctx: RegionFetchContext) =&gt; Promise&lt;void&gt;) =&gt; Promise&lt;void&gt;</code></pre></dialog></span> | <span data-pagefind-ignore>Run a per-region fetch. The work callback calls `ctx.commitRegion` as it stores each region's payload, which is what marks it loaded — see RegionFetchContext for why this function no longer does that itself. Its only callers are the three helpers in `fetchEachRegion.ts`, which make that call for every display in the family; a display reaching past them owns both `ctx.isStale()` guards and the commit by hand, and none does.<br><br>The fetch key is captured here, at issue, and carried into every commit — never re-read after the await. `ctx.isStale()` trips on a newer fetch or a cancel, not on a viewport that moved under a fetch that is still current, so a key read at commit time would stamp this data with a zoom it was not fetched at.</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-fetchregions) |
| <span id="action-afterattach">**afterAttach**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>installs the fetch-lifecycle autoruns (DisplayedRegionsChange, FetchVisibleRegions, SettingsInvalidate, ClearBlockingStateOnViewportChange)</span> | [MultiRegionDisplayMixin](../multiregiondisplaymixin#action-afterattach) |
| <span id="action-setbyteestimate">**setByteEstimate**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(measurement: { bytes: number; viewport: GateViewport; }) =&gt; vo…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(measurement: { bytes: number; viewport: GateViewport; }) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>The bytes half of a measurement alone, for a test staging a display. Production commits through `commitFetchBytes`.</span> | [RegionTooLargeMixin](../regiontoolargemixin#action-setbyteestimate) |
| <span id="action-clearbyteestimate">**clearByteEstimate**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Drops the estimate and the viewport stamp. `forceLoadTrack` survives: it is a track-wide approval.</span> | [RegionTooLargeMixin](../regiontoolargemixin#action-clearbyteestimate) |
| <span id="action-setforceloadtrack">**setForceLoadTrack**</span><br><code>(flag: boolean) =&gt; void</code> |  | [RegionTooLargeMixin](../regiontoolargemixin#action-setforceloadtrack) |
| <span id="action-commitfetchbytes">**commitFetchBytes**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>(perRegionBytes: (number &#124; undefined)[], issued: GateFetchState…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>(perRegionBytes: (number &#124; undefined)[], issued: GateFetchState) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>The byte axis of a finished fetch, called by the fetch runners with the `gateFetchState()` they captured at issue. Commits the per-region max; an empty batch, or an ungated display, commits nothing.</span> | [RegionTooLargeMixin](../regiontoolargemixin#action-commitfetchbytes) |
| <span id="action-forceload">**forceLoad**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>The banner's button: exempt the track on both axes and refetch.</span> | [RegionTooLargeMixin](../regiontoolargemixin#action-forceload) |
| <span id="action-markcanvasdrawn">**markCanvasDrawn**</span><br><code>() =&gt; void</code> |  | [RenderLifecycleMixin](../renderlifecyclemixin#action-markcanvasdrawn) |
| <span id="action-resetcanvasdrawn">**resetCanvasDrawn**</span><br><code>() =&gt; void</code> |  | [RenderLifecycleMixin](../renderlifecyclemixin#action-resetcanvasdrawn) |
| <span id="action-stoprenderingbackend">**stopRenderingBackend**</span><br><code>() =&gt; void</code> |  | [RenderLifecycleMixin](../renderlifecyclemixin#action-stoprenderingbackend) |
| <span id="action-rendernow">**renderNow**</span><br><code>() =&gt; void</code> |  | [RenderLifecycleMixin](../renderlifecyclemixin#action-rendernow) |
| <span id="action-setrendererror">**setRenderError**</span><br><code>(error: unknown) =&gt; void</code> | <span data-pagefind-ignore>set/clear the render-backend error. Called by `useRenderingBackend`: with the error when the canvas factory rejects (or context-loss re-init fails), and with `undefined` on successful (re)init and on retry.</span> | [RenderLifecycleMixin](../renderlifecyclemixin#action-setrendererror) |
| <span id="action-attachrenderingbackend">**attachRenderingBackend**</span><br><span class="cell-more"><button type="button" class="cell-more-trigger"><code>&lt;B&gt;(backend: B, setup: () =&gt; RenderingBackendCallbacks&lt;B&gt;) =&gt; v…</code></button><dialog class="cell-dialog"><form method="dialog"><button class="cell-dialog-close" aria-label="Close">✕</button></form><pre><code>&lt;B&gt;(backend: B, setup: () =&gt; RenderingBackendCallbacks&lt;B&gt;) =&gt; void</code></pre></dialog></span> | <span data-pagefind-ignore>attach a GPU/Canvas2D backend and install the upload + render autorun pair. Idempotent: re-calling swaps the backend and does not run `setup` again, so the callbacks and everything they close over are the first call's.</span> | [RenderLifecycleMixin](../renderlifecyclemixin#action-attachrenderingbackend) |
| <span id="action-stopactivefetch">**stopActiveFetch**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Abort the in-flight fetch (if any) and retire its slot. The shared preamble of both cancel paths; the difference between them is only what they do to `fetchCanceled` / `fetchGeneration` afterward.</span> | [FetchMixin](../fetchmixin#action-stopactivefetch) |
| <span id="action-openstatusstream">**openStatusStream**</span><br><code>(isCurrent: () =&gt; boolean) =&gt; StatusStream</code> | <span data-pagefind-ignore>Open one operation's slot on the display's status field: an RPC `statusCallback` throttled through the display-wide window and guarded so a callback that fires after the node is torn down (RPCs resolve their status stream asynchronously) is a safe no-op, plus the `clear` that retires the slot when the operation ends.<br><br>**Every operation on the display opens one**, and the two come back together because an operation that never retires goes on voting for a phase that is over. The viewport fetch (`runFetch`), the clustering run and a lent `createStopTokenRotation` are three of them on one field; before ADR-081 each blanked the field outright and the last one to finish decided what the other two were still saying.<br><br>`isCurrent` is required and has no "node is alive" default, because alive is not the interesting question: a *superseded* fetch is on a live node, and its late status repainting the overlay of the fetch that replaced it is the failure this guards. `runFetch` passes `!isStale()`, which is what every display gets for free through `ctx.statusCallback`; a caller outside a fetch (the clustering autorun) passes its own run's flag. Defaulting to `isAlive` made the loose answer the easy one and five displays took it.<br><br>Declared this early only so `runFetch` can put one on every `FetchContext`.</span> | [FetchMixin](../fetchmixin#action-openstatusstream) |
| <span id="action-cancelfetch">**cancelFetch**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>cancel any in-flight fetch and bump fetchGeneration (always bumps, so callers can retrigger fetch autoruns even when nothing was in flight). This is the *internal* reset `clearAllRpcData` runs — it clears any user-cancel flag so the retrigger actually re-fetches.</span> | [FetchMixin](../fetchmixin#action-cancelfetch) |
| <span id="action-cancelfetchbyuser">**cancelFetchByUser**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>User-initiated cancel from the loading overlay. Stops the in-flight fetch and lands in a durable `fetchCanceled` state. Unlike `cancelFetch`, it does NOT bump fetchGeneration — so the fetch autoruns don't immediately restart the load. The user retries via `reload` (the overlay's retry button), or it clears on the next viewport change.</span> | [FetchMixin](../fetchmixin#action-cancelfetchbyuser) |
| <span id="action-beforedestroy">**beforeDestroy**</span><br><code>() =&gt; void</code> | <span data-pagefind-ignore>Release an in-flight fetch's stop token on teardown. Without this, a display destroyed mid-fetch (track/view closed while loading) never signals the worker to abort the now-useless work, and its in-flight HTTP reads keep downloading. MST auto-chains lifecycle hooks, so a composing display can still define its own beforeDestroy.</span> | [FetchMixin](../fetchmixin#action-beforedestroy) |
| <span id="action-endfetch">**endFetch**</span><br><code>(current: boolean, stopToken: StopToken) =&gt; void</code> | <span data-pagefind-ignore>The `finally` half of `runFetch`'s bookkeeping, an action of its own because `runFetchOnce`'s `finally` resumes on a microtask the flow does not own — a direct volatile write there is outside the action context, which is the one thing hoisting the sequence into a shared function costs. The stale branch is a superseded fetch: whoever superseded it — a newer `begin`, or `cancel` — already released this token.</span> | [FetchMixin](../fetchmixin#action-endfetch) |
| <span id="action-runfetch">**runFetch**</span><br><code>(work: (ctx: FetchContext) =&gt; Promise&lt;void&gt;) =&gt; Promise&lt;void&gt;</code> | <span data-pagefind-ignore>Run a cancel-safe fetch (cancels any prior). The work callback gets a FetchContext with a stopToken to forward to the RPC and an isStale() check to short-circuit commits once the user has moved on.<br><br>**The MST-flow wrapper over the shared `runFetchOnce` sequence**, and only the wrapper: the begin/clear/run/commit/error/end order, and the rules that keep a superseded run from writing back, are the same function every other fetch in the tree runs. What this adds is the observable bookkeeping a display needs — `isLoading` through `activeStopToken`, `fetchGeneration`, the user-cancel clear — and the flow itself, which is an action, so `work`'s synchronous prefix runs untracked wherever a fetch autorun calls this.</span> | [FetchMixin](../fetchmixin#action-runfetch) |
| <span id="action-setscaletype">**setScaleType**</span><br><code>(scaleType: string) =&gt; void</code> |  | [ScoreScaleMixin](../scorescalemixin#action-setscaletype) |
| <span id="action-setautoscale">**setAutoscale**</span><br><code>(val?: string &#124; undefined) =&gt; void</code> |  | [ScoreScaleMixin](../scorescalemixin#action-setautoscale) |
| <span id="action-setminscore">**setMinScore**</span><br><code>(val?: number &#124; undefined) =&gt; void</code> |  | [ScoreScaleMixin](../scorescalemixin#action-setminscore) |
| <span id="action-setmaxscore">**setMaxScore**</span><br><code>(val?: number &#124; undefined) =&gt; void</code> |  | [ScoreScaleMixin](../scorescalemixin#action-setmaxscore) |
| <span id="action-setshowlegend">**setShowLegend**</span><br><code>(arg: boolean) =&gt; void</code> |  | [LegendMixin](../legendmixin#action-setshowlegend) |

