@jbrowse/launch-args 5.0.0-beta.16 → 5.0.0-beta.18
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm/comparative.d.ts +62 -0
- package/esm/comparative.js +187 -0
- package/esm/displaySettings.d.ts +160 -0
- package/esm/displaySettings.js +686 -0
- package/esm/displaySlots.generated.d.ts +2 -0
- package/esm/displaySlots.generated.js +23 -0
- package/esm/fileAdapter.d.ts +2 -0
- package/esm/fileAdapter.js +5 -0
- package/esm/fileInput.d.ts +35 -16
- package/esm/fileInput.js +96 -30
- package/esm/hostedGenomes.d.ts +39 -0
- package/esm/hostedGenomes.js +45 -0
- package/esm/index.d.ts +8 -4
- package/esm/index.js +8 -4
- package/esm/launchPlan.d.ts +73 -9
- package/esm/launchPlan.js +156 -66
- package/esm/modifierValues.d.ts +10 -0
- package/esm/modifierValues.js +47 -0
- package/esm/parseArgv.d.ts +35 -5
- package/esm/parseArgv.js +56 -23
- package/esm/slotPath.d.ts +48 -0
- package/esm/slotPath.js +211 -0
- package/package.json +7 -4
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
import type { Adapter } from './fileAdapter.ts';
|
|
2
|
+
import type { Assembly, Track } from './fileInput.ts';
|
|
3
|
+
import type { Entry } from './parseArgv.ts';
|
|
4
|
+
/** The comparison flags, each naming the adapter that reads its file. */
|
|
5
|
+
export declare const syntenyFlagAdapters: {
|
|
6
|
+
readonly paf: 'PAFAdapter';
|
|
7
|
+
readonly blasttab: 'BlastTabularAdapter';
|
|
8
|
+
readonly chain: 'ChainAdapter';
|
|
9
|
+
readonly delta: 'DeltaAdapter';
|
|
10
|
+
};
|
|
11
|
+
export type SyntenyFlag = keyof typeof syntenyFlagAdapters;
|
|
12
|
+
export declare const syntenyFlags: SyntenyFlag[];
|
|
13
|
+
export declare function isSyntenyFlag(key: string): key is SyntenyFlag;
|
|
14
|
+
/**
|
|
15
|
+
* What an entry is to a comparative view: a genome (`--genome`, `--fasta`,
|
|
16
|
+
* `--chromSizes` or a bare genome file), a comparison (a comparison flag or a
|
|
17
|
+
* bare file the format table reads as a SyntenyTrack), or neither. A bare
|
|
18
|
+
* file's role comes from its name alone.
|
|
19
|
+
*/
|
|
20
|
+
export declare function comparativeRole([key, [file]]: Entry): "genome" | "synteny" | undefined;
|
|
21
|
+
/**
|
|
22
|
+
* Whether a command line describes a comparative view: a second genome, or a
|
|
23
|
+
* comparison file. A lone genome is a linear view.
|
|
24
|
+
*/
|
|
25
|
+
export declare function hasComparativeArgs(entries: Entry[]): boolean;
|
|
26
|
+
/**
|
|
27
|
+
* The SyntenyTrack for a comparison file between two stacked genomes, upper
|
|
28
|
+
* first. The adapter's file format decides which is the query.
|
|
29
|
+
*/
|
|
30
|
+
export declare function syntenyTrack(adapter: Adapter, file: string, upperAssembly: string, lowerAssembly: string, name?: string): Track;
|
|
31
|
+
/** One row of a comparative view, as a session spec's `views` lists it. */
|
|
32
|
+
export interface ComparativeRow {
|
|
33
|
+
assembly: string;
|
|
34
|
+
loc?: string;
|
|
35
|
+
}
|
|
36
|
+
export interface ComparativeData {
|
|
37
|
+
/** each genome file once, in the order the command line first names it */
|
|
38
|
+
assemblies: Assembly[];
|
|
39
|
+
/**
|
|
40
|
+
* each `--genome` once, whose assembly and comparisons come from its hosted
|
|
41
|
+
* config: see `hostedComparative`
|
|
42
|
+
*/
|
|
43
|
+
hosted: string[];
|
|
44
|
+
/** in stacking order: the first is the top row and a dotplot's x axis */
|
|
45
|
+
rows: ComparativeRow[];
|
|
46
|
+
syntenyTracks: Track[];
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* The genomes and comparisons of a comparative view, in command-line order.
|
|
50
|
+
*
|
|
51
|
+
* - Each genome opens a row, at its `loc:` or whole, with its `aliases:` and
|
|
52
|
+
* `cytobands:`, named after its file, and two files of one name throw.
|
|
53
|
+
* - One file named twice is a self-comparison, two rows of one assembly that
|
|
54
|
+
* take its `aliases:` and `cytobands:` from the first row.
|
|
55
|
+
* - A `--genome` opens a row of a hosted genome, at its `loc:` or whole, and
|
|
56
|
+
* throws on a genome file of the same name.
|
|
57
|
+
* - A comparison file binds to the gap between the genome before it and the
|
|
58
|
+
* next one; a trailing one, written after both, clamps to the last gap.
|
|
59
|
+
* - A comparison takes `name:`; any other modifier, on it or on a genome,
|
|
60
|
+
* throws.
|
|
61
|
+
*/
|
|
62
|
+
export declare function buildComparative(entries: Entry[]): ComparativeData;
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import path from 'node:path';
|
|
2
|
+
import { fileNameOf } from '@jbrowse/add-track-core';
|
|
3
|
+
import { adapterTypeByName, syntenyAdapterTypes } from './fileAdapter.js';
|
|
4
|
+
import { fileAdapter, genomeAssembly, isGenomeFlag, isSequenceAdapter, } from './fileInput.js';
|
|
5
|
+
import { FILE_FLAG, isUrl, modifierValue, splitModifier } from './parseArgv.js';
|
|
6
|
+
/** The comparison flags, each naming the adapter that reads its file. */
|
|
7
|
+
export const syntenyFlagAdapters = {
|
|
8
|
+
paf: 'PAFAdapter',
|
|
9
|
+
blasttab: 'BlastTabularAdapter',
|
|
10
|
+
chain: 'ChainAdapter',
|
|
11
|
+
delta: 'DeltaAdapter',
|
|
12
|
+
};
|
|
13
|
+
export const syntenyFlags = Object.keys(syntenyFlagAdapters);
|
|
14
|
+
/**
|
|
15
|
+
* Whether a comparison file's query is the upper of the two genomes it sits
|
|
16
|
+
* between, the one written first, keyed by the adapter that reads it.
|
|
17
|
+
*
|
|
18
|
+
* - PAF, PIF, MashMap and BLAST list the query first, as minimap2 and blast
|
|
19
|
+
* align a query against a target, so the upper genome is the query.
|
|
20
|
+
* - A chain or delta file maps target to query (a UCSC
|
|
21
|
+
* `targetToQuery.over.chain` maps FROM the target), so the upper genome is
|
|
22
|
+
* the target. Getting it backwards mis-maps every coordinate and most
|
|
23
|
+
* alignments drop out.
|
|
24
|
+
*/
|
|
25
|
+
const upperIsQuery = {
|
|
26
|
+
PAFAdapter: true,
|
|
27
|
+
PairwiseIndexedPAFAdapter: true,
|
|
28
|
+
MashMapAdapter: true,
|
|
29
|
+
BlastTabularAdapter: true,
|
|
30
|
+
ChainAdapter: false,
|
|
31
|
+
DeltaAdapter: false,
|
|
32
|
+
};
|
|
33
|
+
export function isSyntenyFlag(key) {
|
|
34
|
+
return Object.hasOwn(syntenyFlagAdapters, key);
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* What an entry is to a comparative view: a genome (`--genome`, `--fasta`,
|
|
38
|
+
* `--chromSizes` or a bare genome file), a comparison (a comparison flag or a
|
|
39
|
+
* bare file the format table reads as a SyntenyTrack), or neither. A bare
|
|
40
|
+
* file's role comes from its name alone.
|
|
41
|
+
*/
|
|
42
|
+
export function comparativeRole([key, [file]]) {
|
|
43
|
+
if (key === 'genome' || isGenomeFlag(key)) {
|
|
44
|
+
return 'genome';
|
|
45
|
+
}
|
|
46
|
+
else if (isSyntenyFlag(key)) {
|
|
47
|
+
return 'synteny';
|
|
48
|
+
}
|
|
49
|
+
const type = key === FILE_FLAG && file ? adapterTypeByName(file) : undefined;
|
|
50
|
+
return !type
|
|
51
|
+
? undefined
|
|
52
|
+
: isSequenceAdapter({ type })
|
|
53
|
+
? 'genome'
|
|
54
|
+
: syntenyAdapterTypes.has(type)
|
|
55
|
+
? 'synteny'
|
|
56
|
+
: undefined;
|
|
57
|
+
}
|
|
58
|
+
/**
|
|
59
|
+
* Whether a command line describes a comparative view: a second genome, or a
|
|
60
|
+
* comparison file. A lone genome is a linear view.
|
|
61
|
+
*/
|
|
62
|
+
export function hasComparativeArgs(entries) {
|
|
63
|
+
const roles = entries.map(comparativeRole);
|
|
64
|
+
return (roles.includes('synteny') || roles.filter(r => r === 'genome').length > 1);
|
|
65
|
+
}
|
|
66
|
+
/**
|
|
67
|
+
* The SyntenyTrack for a comparison file between two stacked genomes, upper
|
|
68
|
+
* first. The adapter's file format decides which is the query.
|
|
69
|
+
*/
|
|
70
|
+
export function syntenyTrack(adapter, file, upperAssembly, lowerAssembly, name = fileNameOf(file)) {
|
|
71
|
+
const queryFirst = upperIsQuery[adapter.type];
|
|
72
|
+
if (queryFirst === undefined) {
|
|
73
|
+
throw new Error(`${file} is a ${adapter.type} file, which the command line cannot place between two genomes; add it as a track in the app`);
|
|
74
|
+
}
|
|
75
|
+
const queryAssembly = queryFirst ? upperAssembly : lowerAssembly;
|
|
76
|
+
const targetAssembly = queryFirst ? lowerAssembly : upperAssembly;
|
|
77
|
+
return {
|
|
78
|
+
type: 'SyntenyTrack',
|
|
79
|
+
trackId: fileNameOf(file),
|
|
80
|
+
name,
|
|
81
|
+
// [query, target], as comparative-adapters reads it
|
|
82
|
+
assemblyNames: [queryAssembly, targetAssembly],
|
|
83
|
+
adapter: { ...adapter, queryAssembly, targetAssembly },
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
const ASSEMBLY_MODIFIERS = ['aliases', 'cytobands'];
|
|
87
|
+
// local paths compare resolved, so `./a.fa` and `a.fa` are one file
|
|
88
|
+
function sameFile(a, b) {
|
|
89
|
+
return (a === b || (!isUrl(a) && !isUrl(b) && path.resolve(a) === path.resolve(b)));
|
|
90
|
+
}
|
|
91
|
+
// whether a repeat row sets `key:` to a value its first row did not
|
|
92
|
+
function changes(firstMods, mods, key) {
|
|
93
|
+
const value = modifierValue(mods, key);
|
|
94
|
+
const was = modifierValue(firstMods, key);
|
|
95
|
+
return value !== undefined && (was === undefined || !sameFile(was, value));
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* The genomes and comparisons of a comparative view, in command-line order.
|
|
99
|
+
*
|
|
100
|
+
* - Each genome opens a row, at its `loc:` or whole, with its `aliases:` and
|
|
101
|
+
* `cytobands:`, named after its file, and two files of one name throw.
|
|
102
|
+
* - One file named twice is a self-comparison, two rows of one assembly that
|
|
103
|
+
* take its `aliases:` and `cytobands:` from the first row.
|
|
104
|
+
* - A `--genome` opens a row of a hosted genome, at its `loc:` or whole, and
|
|
105
|
+
* throws on a genome file of the same name.
|
|
106
|
+
* - A comparison file binds to the gap between the genome before it and the
|
|
107
|
+
* next one; a trailing one, written after both, clamps to the last gap.
|
|
108
|
+
* - A comparison takes `name:`; any other modifier, on it or on a genome,
|
|
109
|
+
* throws.
|
|
110
|
+
*/
|
|
111
|
+
export function buildComparative(entries) {
|
|
112
|
+
const assemblies = [];
|
|
113
|
+
const genomes = new Map();
|
|
114
|
+
const hosted = new Set();
|
|
115
|
+
const rows = [];
|
|
116
|
+
const comparisons = [];
|
|
117
|
+
const pushRow = (assembly, mods) => {
|
|
118
|
+
const loc = modifierValue(mods, 'loc');
|
|
119
|
+
rows.push(loc ? { assembly, loc } : { assembly });
|
|
120
|
+
};
|
|
121
|
+
for (const entry of entries) {
|
|
122
|
+
const [key, vals] = entry;
|
|
123
|
+
const [file = '', ...mods] = vals;
|
|
124
|
+
const role = comparativeRole(entry);
|
|
125
|
+
const label = key === FILE_FLAG ? file : `--${key} ${file}`;
|
|
126
|
+
if (key === 'genome') {
|
|
127
|
+
if (!file) {
|
|
128
|
+
throw new Error('--genome requires a genome name, such as hg38');
|
|
129
|
+
}
|
|
130
|
+
const extra = mods.filter(mod => splitModifier(mod)?.[0] !== 'loc');
|
|
131
|
+
if (extra.length) {
|
|
132
|
+
throw new Error(`${label} takes loc:, not ${extra.join(' ')}; its hosted config supplies the rest`);
|
|
133
|
+
}
|
|
134
|
+
const sameName = genomes.get(file);
|
|
135
|
+
if (sameName) {
|
|
136
|
+
throw new Error(`${sameName.file} and --genome ${file} are both named ${file}; rename or link the file`);
|
|
137
|
+
}
|
|
138
|
+
hosted.add(file);
|
|
139
|
+
pushRow(file, mods);
|
|
140
|
+
}
|
|
141
|
+
else if (role === 'genome') {
|
|
142
|
+
const { assembly, unused } = genomeAssembly(key, vals, assemblies.length === 0 ? 'refseq' : `${fileNameOf(file)}-refseq`);
|
|
143
|
+
const extra = unused.filter(mod => splitModifier(mod)?.[0] !== 'loc');
|
|
144
|
+
if (extra.length) {
|
|
145
|
+
throw new Error(`${label} takes loc:, aliases: and cytobands:, not ${extra.join(' ')}`);
|
|
146
|
+
}
|
|
147
|
+
const first = genomes.get(assembly.name);
|
|
148
|
+
if (hosted.has(assembly.name)) {
|
|
149
|
+
throw new Error(`--genome ${assembly.name} and ${file} are both named ${assembly.name}; rename or link the file`);
|
|
150
|
+
}
|
|
151
|
+
else if (!first) {
|
|
152
|
+
genomes.set(assembly.name, { file, mods });
|
|
153
|
+
assemblies.push(assembly);
|
|
154
|
+
}
|
|
155
|
+
else if (!sameFile(first.file, file)) {
|
|
156
|
+
throw new Error(`${first.file} and ${file} are both named ${assembly.name}, and a genome takes its file's name; rename or link one of them`);
|
|
157
|
+
}
|
|
158
|
+
else if (ASSEMBLY_MODIFIERS.some(key => changes(first.mods, mods, key))) {
|
|
159
|
+
throw new Error(`${label} repeats ${assembly.name}, which takes its aliases: and cytobands: on its first row; a repeat row takes loc:, or restates them unchanged`);
|
|
160
|
+
}
|
|
161
|
+
pushRow(assembly.name, mods);
|
|
162
|
+
}
|
|
163
|
+
else if (role === 'synteny') {
|
|
164
|
+
if (!file) {
|
|
165
|
+
throw new Error(`--${key} requires a file argument`);
|
|
166
|
+
}
|
|
167
|
+
const extra = mods.filter(mod => splitModifier(mod)?.[0] !== 'name');
|
|
168
|
+
if (extra.length) {
|
|
169
|
+
throw new Error(`${label} takes name:, not ${extra.join(' ')}`);
|
|
170
|
+
}
|
|
171
|
+
comparisons.push({ entry, before: rows.length });
|
|
172
|
+
}
|
|
173
|
+
}
|
|
174
|
+
const numLevels = rows.length - 1;
|
|
175
|
+
const syntenyTracks = comparisons.map(({ entry, before }) => {
|
|
176
|
+
const [key, [file = '', ...mods]] = entry;
|
|
177
|
+
if (numLevels < 1) {
|
|
178
|
+
throw new Error(`${file} compares two genomes, and this command line names one; add another FASTA, 2bit, .chrom.sizes or --genome`);
|
|
179
|
+
}
|
|
180
|
+
const level = Math.min(Math.max(before - 1, 0), numLevels - 1);
|
|
181
|
+
const adapter = fileAdapter(file, {
|
|
182
|
+
adapterType: isSyntenyFlag(key) ? syntenyFlagAdapters[key] : undefined,
|
|
183
|
+
});
|
|
184
|
+
return syntenyTrack(adapter, file, rows[level].assembly, rows[level + 1].assembly, modifierValue(mods, 'name'));
|
|
185
|
+
});
|
|
186
|
+
return { assemblies, hosted: [...hosted], rows, syntenyTracks };
|
|
187
|
+
}
|
|
@@ -0,0 +1,160 @@
|
|
|
1
|
+
import { mergeSettings } from './slotPath.ts';
|
|
2
|
+
/**
|
|
3
|
+
* The family of display a track opens as, which says which modifiers write
|
|
4
|
+
* keys that display declares. `other` takes the all-tracks modifiers and slot
|
|
5
|
+
* writes alone.
|
|
6
|
+
*/
|
|
7
|
+
export type Category = 'alignments' | 'wiggle' | 'feature' | 'variant' | 'hic' | 'other';
|
|
8
|
+
export { mergeSettings };
|
|
9
|
+
export declare const ALL_CATEGORIES: readonly ["alignments", "wiggle", "feature", "variant", "hic", "other"];
|
|
10
|
+
export declare const categorizedDisplayTypes: string[];
|
|
11
|
+
export declare function displayCategory(displayType: string | undefined): Category;
|
|
12
|
+
export declare const ALIGNMENTS_COLOR_FIELDS: readonly ['strand', 'firstOfPairStrand', 'mapq', 'insertSize', 'pairOrientation', 'insertSizeAndOrientation', 'mateRefName', 'mateAssembly'];
|
|
13
|
+
export declare const FACET_ONLY_FIELDS: readonly ['pairing', 'split', 'spliced', 'svSignal'];
|
|
14
|
+
export declare const COLOR_SCHEMES: readonly ['viridis', 'magma', 'inferno', 'cividis', 'juicebox', 'fall', 'reds', 'blues', 'redblue', 'purpleorange', 'redgreyblue', 'redyellowblue'];
|
|
15
|
+
/** The alignments compactness presets' read heights. */
|
|
16
|
+
export declare const ALIGNMENTS_COMPACTNESS: {
|
|
17
|
+
readonly normal: 7;
|
|
18
|
+
readonly compact: 3;
|
|
19
|
+
readonly 'super-compact': 1;
|
|
20
|
+
};
|
|
21
|
+
export declare const HEIGHT_MODES: readonly ['fixed', 'grow', 'fit'];
|
|
22
|
+
export declare const READ_CATEGORY_KEYS: readonly ['spliced', 'svSignal', 'alone', 'split'];
|
|
23
|
+
type Scalar = string | number | boolean;
|
|
24
|
+
/**
|
|
25
|
+
* One entry of a display's `filter`, core's `FieldPredicate` (ADR-238): the
|
|
26
|
+
* tests a record's `field` must pass. On an alignments display (ADR-240) the
|
|
27
|
+
* bare `{ field }` clears the field, defaults included.
|
|
28
|
+
*/
|
|
29
|
+
export interface FilterEntry {
|
|
30
|
+
field: string;
|
|
31
|
+
equal?: Scalar;
|
|
32
|
+
lt?: number;
|
|
33
|
+
lte?: number;
|
|
34
|
+
gt?: number;
|
|
35
|
+
gte?: number;
|
|
36
|
+
oneOf?: Scalar[];
|
|
37
|
+
valid?: boolean;
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* A `filter` list as a JSON bag or a `filter=` write gives it, each entry
|
|
41
|
+
* checked as the config schema checks one and a string read as its
|
|
42
|
+
* shorthand. Throws on what the schema would refuse, v4's object form
|
|
43
|
+
* included.
|
|
44
|
+
*/
|
|
45
|
+
export declare function filterEntriesOf(list: unknown): FilterEntry[];
|
|
46
|
+
export interface ColorScaleObject {
|
|
47
|
+
type?: string;
|
|
48
|
+
domain?: unknown[];
|
|
49
|
+
range?: string[];
|
|
50
|
+
names?: string[];
|
|
51
|
+
scheme?: string;
|
|
52
|
+
reverse?: boolean;
|
|
53
|
+
unknown?: string;
|
|
54
|
+
invalid?: string;
|
|
55
|
+
}
|
|
56
|
+
/** A color channel as written; a bare string is the field. */
|
|
57
|
+
export interface ColorObject {
|
|
58
|
+
value?: string;
|
|
59
|
+
field?: string;
|
|
60
|
+
scale?: ColorScaleObject;
|
|
61
|
+
legend?: {
|
|
62
|
+
title?: string;
|
|
63
|
+
descending?: boolean;
|
|
64
|
+
};
|
|
65
|
+
}
|
|
66
|
+
export type ColorChannel = string | ColorObject;
|
|
67
|
+
/**
|
|
68
|
+
* The settings the named modifiers write. Every other setting is a
|
|
69
|
+
* `path=value` slot write, which the display validates itself.
|
|
70
|
+
*/
|
|
71
|
+
export interface DisplaySnapshot {
|
|
72
|
+
height?: number;
|
|
73
|
+
forceLoad?: boolean;
|
|
74
|
+
mark?: {
|
|
75
|
+
height?: number;
|
|
76
|
+
};
|
|
77
|
+
displayMode?: 'normal' | 'compact' | 'superCompact';
|
|
78
|
+
heightMode?: (typeof HEIGHT_MODES)[number];
|
|
79
|
+
growMaxHeight?: number;
|
|
80
|
+
sort?: string | {
|
|
81
|
+
field: string;
|
|
82
|
+
pos: number;
|
|
83
|
+
refName: string;
|
|
84
|
+
within?: number;
|
|
85
|
+
};
|
|
86
|
+
pileup?: {
|
|
87
|
+
mark?: {
|
|
88
|
+
height?: number;
|
|
89
|
+
};
|
|
90
|
+
bases?: {
|
|
91
|
+
show?: boolean;
|
|
92
|
+
encoding?: {
|
|
93
|
+
color?: string;
|
|
94
|
+
};
|
|
95
|
+
unmodified?: {
|
|
96
|
+
show?: boolean;
|
|
97
|
+
};
|
|
98
|
+
};
|
|
99
|
+
};
|
|
100
|
+
readConnections?: {
|
|
101
|
+
show?: boolean;
|
|
102
|
+
mark?: 'link' | 'rule';
|
|
103
|
+
placement?: 'up' | 'down';
|
|
104
|
+
};
|
|
105
|
+
sashimi?: {
|
|
106
|
+
show?: boolean;
|
|
107
|
+
placement?: 'up' | 'down' | 'auto';
|
|
108
|
+
};
|
|
109
|
+
filter?: FilterEntry[];
|
|
110
|
+
encoding?: {
|
|
111
|
+
color?: ColorChannel;
|
|
112
|
+
};
|
|
113
|
+
legend?: {
|
|
114
|
+
show?: boolean;
|
|
115
|
+
};
|
|
116
|
+
variantLayout?: 'genomic' | 'columns';
|
|
117
|
+
}
|
|
118
|
+
/**
|
|
119
|
+
* A track's modifiers read into display settings. `sort` is the center-line
|
|
120
|
+
* sort's field, which needs the view's center to become a setting, and
|
|
121
|
+
* `displayType` the display `display:` picks.
|
|
122
|
+
*/
|
|
123
|
+
export interface DisplaySettings {
|
|
124
|
+
snap: DisplaySnapshot;
|
|
125
|
+
sort?: {
|
|
126
|
+
field: string;
|
|
127
|
+
};
|
|
128
|
+
displayType?: string;
|
|
129
|
+
}
|
|
130
|
+
/** The display a `display:` modifier asks for; the last one given wins. */
|
|
131
|
+
export declare function requestedDisplayType(modifiers: string[]): string | undefined;
|
|
132
|
+
/** The named track modifiers; any other setting is a `path=value` write. */
|
|
133
|
+
export declare const trackModifierNames: string[];
|
|
134
|
+
/**
|
|
135
|
+
* A track's modifiers read into display settings for `displayType`, the
|
|
136
|
+
* display the track opens as. A named modifier writes only slots that display
|
|
137
|
+
* declares. Without a display type, a modifier whose write depends on it
|
|
138
|
+
* throws, and every other one writes its setting for the display to accept or
|
|
139
|
+
* refuse. A member write is `memberWrites`'s, and `warn` hears of a modifier
|
|
140
|
+
* that does nothing on the display.
|
|
141
|
+
*/
|
|
142
|
+
export declare function buildDisplaySnapshot(displayType: string | undefined, opts: string[], warn?: (message: string) => void): DisplaySettings;
|
|
143
|
+
/**
|
|
144
|
+
* Throws for a modifier no kind of track takes: an unknown name, a malformed
|
|
145
|
+
* slot write, or a value each display it applies to refuses. An app that
|
|
146
|
+
* applies the modifiers only once the track is open checks them first, so the
|
|
147
|
+
* command line fails rather than the open.
|
|
148
|
+
*/
|
|
149
|
+
export declare function checkModifiers(opts: string[]): void;
|
|
150
|
+
/**
|
|
151
|
+
* A track's member writes: each `encoding.color.field=…` modifier, and a hic
|
|
152
|
+
* track's `color:<scheme>`, which names one member of the color channel the
|
|
153
|
+
* track already configures.
|
|
154
|
+
*/
|
|
155
|
+
export declare function memberWrites(displayType: string | undefined, opts: string[]): string[];
|
|
156
|
+
/**
|
|
157
|
+
* The patch a track's member writes make: each write applied over the value
|
|
158
|
+
* `configured` gives the setting it names, so the rest of that setting stays.
|
|
159
|
+
*/
|
|
160
|
+
export declare function memberPatch(members: string[], configured: (setting: string) => unknown): Record<string, unknown>;
|