From 354658ce6f7a984e6d4a2f5377d25d891096b3f0 Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Sat, 30 Sep 2023 15:53:53 -0700
Subject: [PATCH 1/9] use igvxhr for hub parsing
---
js/ucsc/ucscHub.js | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/js/ucsc/ucscHub.js b/js/ucsc/ucscHub.js
index bcd0e56d2..7d60e7cbf 100644
--- a/js/ucsc/ucscHub.js
+++ b/js/ucsc/ucscHub.js
@@ -6,6 +6,8 @@
https://genome.ucsc.edu/goldenpath/help/trackDb/trackDbHub.html
*/
+import { igvxhr} from "../../node_modules/igv-utils/src/index.js"
+
class Hub {
static async loadHub(options) {
@@ -326,8 +328,7 @@ class Stanza {
*/
async function loadStanzas(options) {
- const response = await fetch(options.url)
- const data = await response.text()
+ const data = await igvxhr.loadString(options.url)
const lines = data.split(/\n|\r\n|\r/g)
const nodes = []
From 700f69d33a89134d68c261f21165d2c56a3405c9 Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Wed, 4 Oct 2023 16:53:14 -0700
Subject: [PATCH 2/9] Use unsigned short for certain BB fields, add unit test.
---
js/bigwig/bwReader.js | 12 ++--
test/testBigwig.js | 136 ++++++------------------------------------
2 files changed, 24 insertions(+), 124 deletions(-)
diff --git a/js/bigwig/bwReader.js b/js/bigwig/bwReader.js
index 11c0cdf92..594471e50 100644
--- a/js/bigwig/bwReader.js
+++ b/js/bigwig/bwReader.js
@@ -379,8 +379,8 @@ class BWReader {
}
}))
let binaryParser = new BinaryParser(new DataView(data))
- const extensionSize = binaryParser.getShort()
- const extraIndexCount = binaryParser.getShort()
+ const extensionSize = binaryParser.getUShort()
+ const extraIndexCount = binaryParser.getUShort()
const extraIndexListOffset = binaryParser.getLong()
if(extraIndexCount === 0) return
@@ -399,17 +399,17 @@ class BWReader {
const indexOffset = []
for (let i = 0; i < extraIndexCount; i++) {
- type.push(binaryParser.getShort())
+ type.push(binaryParser.getUShort())
- const fc = binaryParser.getShort()
+ const fc = binaryParser.getUShort()
fieldCount.push(fc)
indexOffset.push(binaryParser.getLong())
reserved.push(binaryParser.getInt())
for (let j = 0; j < fc; j++) {
- const fieldId = binaryParser.getShort()
- reserved.push(binaryParser.getShort())
+ const fieldId = binaryParser.getUShort()
+ reserved.push(binaryParser.getUShort())
}
}
this.header.extraIndexCount = extraIndexCount
diff --git a/test/testBigwig.js b/test/testBigwig.js
index 6fc6c5f7d..093e1dcf5 100644
--- a/test/testBigwig.js
+++ b/test/testBigwig.js
@@ -50,123 +50,23 @@ suite("testBigWig", function () {
})
- const dataURL = "https://data.broadinstitute.org/igvdata/test/data/"
-
-// test("No data", async function () {
-//
-// this.timeout(10000);
-// const bw = FeatureSource (
-// {
-// format: 'bigwig',
-// url: dataURL + 'bigwig/manyChromosomes.bigWig'}
-// );
-// const features = await bw.getFeatures({chr: 'NoSuchChromosome', start: 0, end: 100});
-// assert.equal(0, features.length);
-//
-// });
-//
-// test("Many chromosomes", async function () {
-//
-// this.timeout(20000);
-// const bw = new BWSource(
-// {url: dataURL + 'bigwig/manyChromosomes.bigWig'}
-// );
-//
-// const features = await bw.getFeatures({chr: 'AluJb', start: 0, end: 100});
-// assert.equal(99, features.length);
-// features.forEach(function (f) {
-// assert.equal("AluJb", f.chr);
-//
-// })
-// })
-//
-//
-// test("Bigwig meta data", async function () {
-//
-// this.timeout(10000);
-//
-// const url = dataURL + "bigwig/bigWigExample.bw";
-// const bwReader = new BWReader({url: url});
-//
-// const header = await bwReader.loadHeader();
-//
-// assert.ok(header);
-//
-// assert.equal(4, header.bwVersion);
-// assert.equal(10, header.nZoomLevels);
-// assert.equal(344, header.chromTreeOffset);
-// assert.equal(393, header.fullDataOffset);
-// assert.equal(15751049, header.fullIndexOffset);
-//
-// // Summary data
-// assert.equal(35106705, bwReader.totalSummary.basesCovered);
-// assert.equal(0, bwReader.totalSummary.minVal);
-// assert.equal(100, bwReader.totalSummary.maxVal);
-// assert.equal(77043134252.78125, bwReader.totalSummary.sumSquares);
-//
-// // // chrom tree -- values taken from IGV java
-// var ctHeader = bwReader.chromTree.header;
-// assert.equal(1, ctHeader.blockSize);
-// assert.equal(5, ctHeader.keySize);
-// assert.equal(8, ctHeader.valSize);
-// assert.equal(1, ctHeader.itemCount);
-//
-// // chrom lookup == there's only 1 chromosome in this test file
-// var chrName = "chr21";
-// var chrIdx = bwReader.chromTree.chromToID[chrName];
-// assert.equal(0, chrIdx);
-//
-//
-// // Total data count -- note this is the # of "sections", not the # of data points. Verified with grep
-// assert.equal(6857, bwReader.header.dataCount);
-//
-// var type = bwReader.type;
-// assert.equal("bigwig", type);
-//
-// });
-//
-// test("R+ Tree", async function () {
-//
-// this.timeout(10000);
-// const url = dataURL + "bigwig/bigWigExample.bw";
-// const bwReader = new BWReader({url: url});
-// const header = await bwReader.loadHeader();
-// const offset = header.fullIndexOffset;
-// bwReader.loadRPTree(offset).then(function (rpTree) {
-// assert.ok(rpTree.rootNode);
-// });
-// });
-//
-// test("Wig features", async function () {
-//
-// this.timeout(20000);
-// //chr21:19,146,376-19,193,466
-// const url = dataURL + "bigwig/bigWigExample.bw",
-// chr = "chr21",
-// start = 19168957,
-// end = 19170640;
-//
-// const bWSource = new BWSource({url: url});
-// const features = await bWSource.getFeatures({chr: chr, start: start, end: end});
-// assert.ok(features);
-// assert.equal(features.length, 337); // Verified in iPad app
-// });
-
- // test("Zoom data", async function () {
- //
- // this.timeout(10000);
- //
- // //chr21:19,146,376-19,193,466
- // const url = dataURL + "bigwig/bigWigExample.bw",
- // chr = "chr21",
- // start = 18728264,
- // end = 26996291,
- // bpPerPixel = 10765.6611328125; // To match iOS unit test
- // const bWSource = new BWSource({url: url});
- // const features = await bWSource.getFeatures({chr, start, end, bpPerPixel});
- // assert.ok(features);
- // assert.equal(features.length, 1293); // Verified in iPad app
- //
- // })
+
+ test("Compressed bigwig", async function () {
+
+ this.timeout(10000)
+
+ //chr21:19,146,376-19,193,466
+ const url = "https://hgdownload.soe.ucsc.edu/hubs/GCA/009/914/755/GCA_009914755.4/bbi/GCA_009914755.4_T2T-CHM13v2.0.gc5Base.bw",
+ chr = "CP068275.2",
+ start = 26490012,
+ end = 26490012 + 1,
+ bpPerPixel = 1
+
+ const bwReader = new BWReader({url: url})
+ const features = await bwReader.readFeatures(chr, start, chr, end, bpPerPixel)
+ assert.equal(features.length, 1) // Verified in iPad app
+
+ })
+
})
\ No newline at end of file
From 5cce5e6e3c18980842f1a58009d103cdd16fc682 Mon Sep 17 00:00:00 2001
From: jrobinso <933148+jrobinso@users.noreply.github.com>
Date: Thu, 5 Oct 2023 15:28:33 -0700
Subject: [PATCH 3/9] Add a global spinnner.
---
css/dom.css | 1 +
css/dom.css.map | 2 +-
css/dom.scss | 1 +
js/browser.js | 19 +++++++++++++++++++
js/embedCss.js | 2 +-
js/igv-create.js | 9 +++++++--
6 files changed, 30 insertions(+), 4 deletions(-)
diff --git a/css/dom.css b/css/dom.css
index 6d2645185..f5dd39609 100644
--- a/css/dom.css
+++ b/css/dom.css
@@ -1431,6 +1431,7 @@
user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
+ min-height: 160px;
}
.igv-viewport {
diff --git a/css/dom.css.map b/css/dom.css.map
index 9847fd964..e53cbf05f 100644
--- a/css/dom.css.map
+++ b/css/dom.css.map
@@ -1 +1 @@
-{"version":3,"sourceRoot":"","sources":["_navbar.scss","_font.scss","_color.scss","_dom-misc.scss","_apple_crayon_color.scss","_igv-center-line.scss","_igv-cursor-guide.scss","dom.scss","_igv-user-feedback.scss","_igv-generic-dialog-container.scss","_igv-generic-container.scss","_igv-menu-popup.scss","_spinner.scss","_roi.scss"],"names":[],"mappings":"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CA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,OAhGkB;;AAmGpB;EACE;EACA;;;AAKJ;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EAEA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AHxIN;EAEE;EACA;EACA;EAEA;EAEA;EACA;EAEA;EAEA;EAEA;EACA;EACA;EAEA,aPpBsB;EOqBtB;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE;EAEA;EACA;EAEA;EAEA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAKJ;EACE;EACA;EAEA;;AAEA;EACE;EACA;EACA;;;AIpEN;EAEE;EAEA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAIA;EACE;EAEA;EACA;EACA;EAIA;EACA;EAEA;EACA;;;AAKJ;EACE;IAAK;IAAmC;;;AAG1C;EACE;IAAK;IAAmC;;;ACrB1C;EAEE;EACA;EAEA,aAhCkB;EAiClB;EACA;EACA,OAlCmB;EAoCnB;EAEA;EAEA,eArCsB;EAsCtB,cArCa;EAsCb;EACA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE,QA/CyB;EAiDzB;EACA,wBArDoB;EAsDpB,yBAtDoB;EAwDpB,qBAvDW;EAwDX;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,OAvES;;AA0EX;EACE;EACA;;AAMJ;EAGE;EAEA,2BAzE0B;EA0E1B,4BA1E0B;EA2E1B;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;;AAGA;EACE,QApGM;EAqGN;EAEA;EACA;EACA,qBApGiB;;AAuGnB;EACE;;AAGF;EAGE;EACA;EAEA;EAEA;EACA;EACA;;AAGF;EACE;EACA;;;AAQN;EACE;EACA,OAhJ+B;;;AAoJjC;EACE;EACA;EAIA;EACA;EAEA,cAjJqB;EAkJrB,eA7I4B;EA8I5B;EACA;EAEA,aA9IwB;EA+IxB;EACA;EAEA;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","file":"dom.css"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["_navbar.scss","_font.scss","_color.scss","_dom-misc.scss","_apple_crayon_color.scss","_igv-center-line.scss","_igv-cursor-guide.scss","dom.scss","_igv-user-feedback.scss","_igv-generic-dialog-container.scss","_igv-generic-container.scss","_igv-menu-popup.scss","_spinner.scss","_roi.scss"],"names":[],"mappings":"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CA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,OAhGkB;;AAmGpB;EACE;EACA;;;AAKJ;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EAEA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AHxIN;EAEE;EACA;EACA;EAEA;EAEA;EACA;EAEA;EAEA;EAEA;EACA;EACA;EAEA,aPpBsB;EOqBtB;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE;EAEA;EACA;EAEA;EAEA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAKJ;EACE;EACA;EAEA;;AAEA;EACE;EACA;EACA;;;AIpEN;EAEE;EAEA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAIA;EACE;EAEA;EACA;EACA;EAIA;EACA;EAEA;EACA;;;AAKJ;EACE;IAAK;IAAmC;;;AAG1C;EACE;IAAK;IAAmC;;;ACrB1C;EAEE;EACA;EAEA,aAhCkB;EAiClB;EACA;EACA,OAlCmB;EAoCnB;EAEA;EAEA,eArCsB;EAsCtB,cArCa;EAsCb;EACA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE,QA/CyB;EAiDzB;EACA,wBArDoB;EAsDpB,yBAtDoB;EAwDpB,qBAvDW;EAwDX;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,OAvES;;AA0EX;EACE;EACA;;AAMJ;EAGE;EAEA,2BAzE0B;EA0E1B,4BA1E0B;EA2E1B;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;;AAGA;EACE,QApGM;EAqGN;EAEA;EACA;EACA,qBApGiB;;AAuGnB;EACE;;AAGF;EAGE;EACA;EAEA;EAEA;EACA;EACA;;AAGF;EACE;EACA;;;AAQN;EACE;EACA,OAhJ+B;;;AAoJjC;EACE;EACA;EAIA;EACA;EAEA,cAjJqB;EAkJrB,eA7I4B;EA8I5B;EACA;EAEA,aA9IwB;EA+IxB;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;EAkEA;;AA/DA;EACE,QAzKQ;EA2KR;EACA;EACA;EACA,aA9KQ;;AAkLV;EAEE;EACA,wBA3K0B;EA4K1B,yBA5K0B;EA6K1B;EAEA,qBApLmB;EAqLnB;EACA;EAEA,kBA9K6B;EAgL7B;EAEA;EACA;EACA;EACA;EACA;;AAEA;EAEE;EACA;EACA;EAEA;EAEA;EACA;EACA;;AAGF;EACE;EACA;EACA,QA5MwB;EA6MxB,OA7MwB;EA8MxB,OApNiB;;AAsNjB;EACE;;AAIJ;EACE;EACA;;AAQJ;EAEE;EACA;EAMA;EACA;EAEA;EACA;EACA;EAGA;;AAGF;EACE;EACA;EACA;EACA;EAEA,QApQQ;EAsQR;EAEA;;AAIF;EAEE,QA9QQ;EAgRR;EACA;EACA;EACA;EACA;EAGA;EAEA;EAEA,kBAtRmB;EAuRnB;EACA;EAEA,qBA1RmB;EA2RnB;EACA;;AAEA;EACE;EACA;EACA,aAtSM;EAwSN;EAEA;EAEA,QA5SM;EA+SN;EACA;EAEA,oBA7SiB;EA8SjB;EACA;;AAIF;EACE;;AAMJ;EAEE;EACA;EAEA;EAEA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EAEE,QAnVM;EAqVN;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA,aA9VI;EAgWJ;EAEA;EAEA,QApWI;EAsWJ;EACA;EACA;EAEA;EACA;EACA;;AAGF;EACE;;AAKJ;EACE;;AAKJ;EAEE,QA5Xc;EA6Xd,aA7Xc;EA+Xd,kBA3XmB;EA4XnB;EACA;EAEA;EACA,2BA3X0B;EA4X1B,4BA5X0B;EA6X1B;EAEA,kBA1X6B;EA4X7B;EACA;EACA;EACA;EACA;;;AAMJ;EACE;;;AAGF;EAEE;EAEA,QAtZ4B;EAwZ5B;EAEA,aA1Z4B;EA4Z5B;EACA;EAEA,aZ/asB;EYgbtB;EACA;EAEA;EAEA;EACA;EAEA;EAEA;EACA;EACA;EACA,eA5a4B;;;AA+a9B;EACE;EACA;;;AAIF;EACE;EAEA;EACA;EACA;EAEA;EAEA;EAEA;EAUA;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;EAGA;;;AAKJ;EACE;EACA;EAEA;EAEA,cAreqB;EAserB,eAje4B;EAke5B;EACA;EAEA,aAlewB;EAoexB;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;;AAGF;EAEE,wBAvf0B;EAwf1B,yBAxf0B;EAyf1B;EACA;EACA;;AAIF;EAEE,2BAjgB0B;EAkgB1B,4BAlgB0B;EAmgB1B;EACA;EACA;;;AAOJ;EAEE,QAxhBU;EA0hBV;EAEA;EACA;EACA;EAEA,aAhiBU;EAkiBV;;;AAIF;EAEE;EAEA;EACA;EACA;EAEA;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EAGA;;AAGF;EACE;EACA;EACA;EACA;EAGA;;;ANjiBJ;EAEE;EAEA;EACA;EACA;EACA;EACA;EAEA;EAEA;EACA;EACA;EAEA;;;AAGF;EACE;EAEA,YAvD2B;EAwD3B;EACA;EACA;;;AAIF;EACE;EACA;;AAEA;EACE;EACA;;;AAIJ;EAEE;EAEA;EACA;EACA;EACA;EACA;EAEA;;;AAIF;EACE,OArFsB;EAsFtB,aArFuB;EAsFvB,cAtFuB;EAuFvB,kBHxGsB;;;AG2GxB;EAtEE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAmEA,OAjHsB;;AAmHtB;EACE,YApGyB;EAqGzB;;;AAIJ;EACE;EAnFA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAiFF;EAxFE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAqFF;EA5FE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAyFF;EAhGE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EA6FA,OAzI0B;;AA2I1B;EAEE;EAEA,YAjIyB;EAkIzB,OAhJwB;;AAkJxB;EAEE;EAEA;EACA;EACA,MAtJqB;EAwJrB,OAvJsB;EAyJtB,cA3J6B;EA4J7B;EAGA;EAEA;EACA;EAEA;EACA;;AAMF;EACE;;;AAON;EA/IE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EA4IA,OAnL4B;EAqL5B;;AAGA;EACE;EACA;EACA;EAEA,YApLyB;EAqLzB;EAEA;EACA;EACA;EACA;EAEA;;AAGF;EACE;;AAIF;EACE;EAEA,YAvMyB;EAwMzB;EAEA;EACA;;;AAKJ;EAzLE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAsLA,OA3NiC;;AA8NjC;EAEE;EACA;EACA;EACA;EACA;EAEA,YA/NyB;EAgOzB;EACA;;AAGA;EACE;EAEA;EACA;EACA;EACA,OLxOqB;;AK2OvB;EACE;EACA","file":"dom.css"}
\ No newline at end of file
diff --git a/css/dom.scss b/css/dom.scss
index 7f1365ec6..9cfc377d5 100644
--- a/css/dom.scss
+++ b/css/dom.scss
@@ -64,6 +64,7 @@ $igv-zoom-in-notice-height: 16px;
-webkit-user-select: none;
-ms-user-select: none;
+ min-height: 160px;
}
.igv-viewport {
diff --git a/js/browser.js b/js/browser.js
index 977808f9b..d5428e9d0 100755
--- a/js/browser.js
+++ b/js/browser.js
@@ -81,6 +81,17 @@ class Browser {
this.root = DOMUtils.div({class: 'igv-container'})
parentDiv.appendChild(this.root)
+
+
+ // spinner
+ this.spinner = DOMUtils.div({class: 'igv-loading-spinner-container'})
+ this.root.appendChild(this.spinner)
+
+ this.spinner.appendChild(DOMUtils.div())
+ this.spinner.style.width = '64px'
+ this.spinner.style.height = '64px'
+ this.stopSpinner()
+
this.alert = new Alert(this.root)
this.columnContainer = DOMUtils.div({class: 'igv-column-container'})
@@ -129,6 +140,14 @@ class Browser {
this.setControls(config)
}
+ startSpinner() {
+ this.spinner.style.display = 'flex'
+ }
+
+ stopSpinner() {
+ this.spinner.style.display = 'none'
+ }
+
initialize(config) {
if (config.gtex) {
diff --git a/js/embedCss.js b/js/embedCss.js
index 36f673281..90ef9f10f 100644
--- a/js/embedCss.js
+++ b/js/embedCss.js
@@ -1,6 +1,6 @@
function embedCSS() {
- var css = '.igv-navbar {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n color: #444;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n line-height: 32px;\n padding-left: 8px;\n padding-right: 8px;\n margin-top: 2px;\n margin-bottom: 6px;\n height: 32px;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: #f3f3f3;\n}\n.igv-navbar .igv-navbar-left-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-left-container .igv-logo {\n width: 34px;\n height: 32px;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\n height: 32px;\n margin-left: 4px;\n margin-right: 4px;\n user-select: none;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n height: 100%;\n width: 125px;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n display: block;\n cursor: pointer;\n width: 100px;\n height: 75%;\n outline: none;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n margin-left: 8px;\n height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 240px;\n height: 22px;\n line-height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n cursor: text;\n width: 85%;\n height: 22px;\n line-height: 22px;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n text-align: left;\n padding-left: 8px;\n margin-right: 8px;\n outline: none;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: white;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n cursor: pointer;\n height: 16px;\n width: 16px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n margin-left: 4px;\n user-select: none;\n}\n.igv-navbar .igv-navbar-right-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\n margin-left: 0;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\n margin-left: 0;\n margin-right: 0;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n display: block;\n height: fit-content;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n display: block;\n width: 125px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n display: none;\n}\n\n.igv-navbar-button {\n display: block;\n box-sizing: unset;\n padding-left: 6px;\n padding-right: 6px;\n height: 18px;\n text-transform: capitalize;\n user-select: none;\n line-height: 18px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 11px;\n font-weight: 200;\n color: #737373;\n background-color: #f3f3f3;\n border-color: #737373;\n border-style: solid;\n border-width: thin;\n border-radius: 6px;\n}\n\n.igv-navbar-button-clicked {\n color: white;\n background-color: #737373;\n}\n\n.igv-navbar-button:hover {\n cursor: pointer;\n}\n\n.igv-zoom-in-notice-container {\n z-index: 1024;\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translate(-50%, 0%);\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n background-color: white;\n}\n.igv-zoom-in-notice-container > div {\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n width: 100%;\n height: 100%;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: #3f3f3f;\n}\n\n.igv-zoom-in-notice {\n position: absolute;\n top: 10px;\n left: 50%;\n}\n.igv-zoom-in-notice div {\n position: relative;\n left: -50%;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #3f3f3f;\n background-color: rgba(255, 255, 255, 0.51);\n z-index: 64;\n}\n\n.igv-container-spinner {\n position: absolute;\n top: 90%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1024;\n width: 24px;\n height: 24px;\n pointer-events: none;\n color: #737373;\n}\n\n.igv-multi-locus-close-button {\n position: absolute;\n top: 2px;\n right: 0;\n padding-left: 2px;\n padding-right: 2px;\n width: 12px;\n height: 12px;\n color: #666666;\n background-color: white;\n z-index: 1000;\n}\n.igv-multi-locus-close-button > svg {\n vertical-align: top;\n}\n\n.igv-multi-locus-close-button:hover {\n cursor: pointer;\n color: #434343;\n}\n\n.igv-multi-locus-ruler-label {\n z-index: 64;\n position: absolute;\n top: 2px;\n left: 0;\n width: 100%;\n height: 12px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-multi-locus-ruler-label > div {\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n.igv-multi-locus-ruler-label > div {\n cursor: pointer;\n}\n\n.igv-multi-locus-ruler-label-square-dot {\n z-index: 64;\n position: absolute;\n left: 50%;\n top: 5%;\n transform: translate(-50%, 0%);\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\n width: 14px;\n height: 14px;\n}\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\n margin-left: 16px;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n}\n\n.igv-ruler-sweeper {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 26px;\n bottom: 0;\n left: 0;\n width: 0;\n z-index: 99999;\n background-color: rgba(68, 134, 247, 0.25);\n}\n\n.igv-ruler-tooltip {\n pointer-events: none;\n z-index: 128;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 32px;\n background-color: transparent;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ruler-tooltip > div {\n pointer-events: none;\n width: 128px;\n height: auto;\n padding: 1px;\n color: #373737;\n font-size: 10px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n background-color: white;\n border-style: solid;\n border-width: thin;\n border-color: #373737;\n}\n\n.igv-track-label {\n position: absolute;\n left: 8px;\n top: 8px;\n width: auto;\n height: auto;\n max-width: 50%;\n padding-left: 4px;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n text-align: center;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-color: #444;\n border-radius: 2px;\n border-style: solid;\n border-width: thin;\n background-color: white;\n z-index: 128;\n cursor: pointer;\n}\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n background-color: #e8e8e8;\n}\n\n.igv-track-label-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-top: 4px;\n}\n\n.igv-center-line {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n z-index: 8;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-left-style: dashed;\n border-left-width: thin;\n border-right-style: dashed;\n border-right-width: thin;\n}\n\n.igv-center-line-wide {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(127, 127, 127, 0.51);\n}\n\n.igv-center-line-thin {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(0, 0, 0, 0);\n}\n\n.igv-cursor-guide-horizontal {\n display: none;\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 50%;\n height: 1px;\n z-index: 1;\n margin-left: 50px;\n margin-right: 54px;\n border-top-style: dotted;\n border-top-width: thin;\n border-top-color: rgba(127, 127, 127, 0.76);\n}\n\n.igv-cursor-guide-vertical {\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n width: 1px;\n z-index: 1;\n border-left-style: dotted;\n border-left-width: thin;\n border-left-color: rgba(127, 127, 127, 0.76);\n display: none;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-generic-dialog-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-generic-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-generic-container div:first-child i {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-menu-popup {\n position: absolute;\n top: 0;\n left: 0;\n width: max-content;\n z-index: 4096;\n cursor: pointer;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background: white;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-end;\n text-align: left;\n}\n.igv-menu-popup > div:not(:first-child) {\n width: 100%;\n}\n.igv-menu-popup > div:not(:first-child) > div {\n background: white;\n}\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\n padding-left: 4px;\n padding-right: 4px;\n}\n.igv-menu-popup > div:not(:first-child) > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-menu-popup > div:not(:first-child) > div:hover {\n background: #efefef;\n}\n\n.igv-menu-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-bottom: 1px;\n padding-top: 1px;\n}\n\n.igv-menu-popup-header {\n position: relative;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-menu-popup-header div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-menu-popup-header div:hover {\n cursor: pointer;\n color: #444;\n}\n\n.igv-menu-popup-check-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 20px;\n margin-right: 4px;\n background-color: transparent;\n}\n.igv-menu-popup-check-container div {\n padding-top: 2px;\n padding-left: 8px;\n}\n.igv-menu-popup-check-container div:first-child {\n position: relative;\n width: 12px;\n height: 12px;\n}\n.igv-menu-popup-check-container div:first-child svg {\n position: absolute;\n width: 12px;\n height: 12px;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-loading-spinner-container {\n z-index: 1024;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-loading-spinner-container > div {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 4px solid rgba(128, 128, 128, 0.5);\n border-top-color: rgb(255, 255, 255);\n animation: spin 1s ease-in-out infinite;\n -webkit-animation: spin 1s ease-in-out infinite;\n}\n\n@keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.igv-roi-menu-next-gen {\n position: absolute;\n z-index: 512;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background-color: white;\n width: 192px;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu-next-gen > div:first-child {\n height: 24px;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-roi-menu-next-gen > div:first-child > div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-roi-menu-next-gen > div:first-child > div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-menu-next-gen > div:last-child {\n background-color: white;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n text-align: start;\n vertical-align: middle;\n}\n.igv-roi-menu-next-gen > div:last-child > div {\n height: 24px;\n padding-left: 4px;\n border-bottom-style: solid;\n border-bottom-width: thin;\n border-bottom-color: #7f7f7f;\n}\n.igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {\n background-color: rgba(127, 127, 127, 0.1);\n}\n.igv-roi-menu-next-gen > div:last-child div:first-child {\n font-style: italic;\n text-align: center;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-menu-next-gen > div:last-child > div:last-child {\n border-bottom-width: 0;\n border-bottom-color: transparent;\n}\n\n.igv-roi-placeholder {\n font-style: normal;\n color: rgba(75, 75, 75, 0.6);\n}\n\n.igv-roi-table {\n position: absolute;\n z-index: 1024;\n width: min-content;\n max-width: 1600px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n cursor: default;\n}\n.igv-roi-table > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table > div:first-child > div:first-child {\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n margin-left: 4px;\n margin-right: 4px;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table > .igv-roi-table-description {\n padding: 4px;\n margin-left: 4px;\n word-break: break-all;\n overflow-y: auto;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-goto-explainer {\n margin-top: 5px;\n margin-left: 4px;\n color: #7F7F7F;\n font-style: italic;\n height: 24px;\n border-top: solid lightgray;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: #7f7f7f;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n overflow: auto;\n resize: both;\n max-width: 1600px;\n height: 360px;\n background-color: transparent;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: transparent;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n cursor: pointer;\n height: 20px;\n user-select: none;\n line-height: 20px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 13px;\n font-weight: 400;\n color: black;\n padding-left: 6px;\n padding-right: 6px;\n background-color: rgb(239, 239, 239);\n border-color: black;\n border-style: solid;\n border-width: thin;\n border-radius: 3px;\n}\n\n.igv-roi-table-button:hover {\n font-weight: 400;\n background-color: rgba(0, 0, 0, 0.13);\n}\n\n.igv-roi-region {\n z-index: 64;\n position: absolute;\n top: 0;\n bottom: 0;\n pointer-events: none;\n overflow: visible;\n margin-top: 44px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-region > div {\n position: relative;\n width: 100%;\n height: 8px;\n pointer-events: auto;\n}\n\n.igv-roi-menu {\n position: absolute;\n z-index: 1024;\n width: 144px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu > div:not(:last-child) {\n border-bottom-color: rgba(128, 128, 128, 0.5);\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-menu > div:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-color: transparent;\n border-top-style: solid;\n border-top-width: 0;\n}\n.igv-roi-menu > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n}\n\n.igv-roi-menu-row {\n height: 24px;\n padding-left: 8px;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n background-color: white;\n}\n\n.igv-roi-menu-row-edit-description {\n width: -webkit-fill-available;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-menu-row-edit-description > label {\n margin-left: 2px;\n margin-bottom: 0;\n display: block;\n width: -webkit-fill-available;\n}\n.igv-roi-menu-row-edit-description > input {\n display: block;\n margin-left: 2px;\n margin-right: 2px;\n margin-bottom: 1px;\n width: -webkit-fill-available;\n}\n\n.igv-container {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 4px;\n user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n}\n\n.igv-viewport {\n position: relative;\n margin-top: 5px;\n line-height: 1;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.igv-viewport-content {\n position: relative;\n width: 100%;\n}\n.igv-viewport-content > canvas {\n position: relative;\n display: block;\n}\n\n.igv-column-container {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n width: 100%;\n}\n\n.igv-column-shim {\n width: 1px;\n margin-left: 2px;\n margin-right: 2px;\n background-color: #545453;\n}\n\n.igv-axis-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 50px;\n}\n.igv-axis-column > div {\n margin-top: 5px;\n width: 100%;\n}\n\n.igv-column {\n position: relative;\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-sample-info-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-sample-name-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-scrollbar-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 14px;\n}\n.igv-scrollbar-column > div {\n position: relative;\n margin-top: 5px;\n width: 14px;\n}\n.igv-scrollbar-column > div > div {\n cursor: pointer;\n position: absolute;\n top: 0;\n left: 2px;\n width: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: #c4c4c4;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.igv-scrollbar-column > div > div:hover {\n background-color: #c4c4c4;\n}\n\n.igv-track-drag-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 12px;\n background-color: white;\n}\n.igv-track-drag-column > .igv-track-drag-handle {\n z-index: 512;\n position: relative;\n cursor: pointer;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n background-color: #c4c4c4;\n}\n.igv-track-drag-column .igv-track-drag-handle-hover {\n background-color: #787878;\n}\n.igv-track-drag-column > .igv-track-drag-shim {\n position: relative;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n}\n\n.igv-gear-menu-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 28px;\n}\n.igv-gear-menu-column > div {\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n margin-top: 5px;\n width: 100%;\n background: white;\n}\n.igv-gear-menu-column > div > div {\n position: relative;\n margin-top: 4px;\n width: 16px;\n height: 16px;\n color: #7F7F7F;\n}\n.igv-gear-menu-column > div > div:hover {\n cursor: pointer;\n color: #444;\n}\n\n/*# sourceMappingURL=dom.css.map */\n'
+ var css = '.igv-navbar {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n color: #444;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n line-height: 32px;\n padding-left: 8px;\n padding-right: 8px;\n margin-top: 2px;\n margin-bottom: 6px;\n height: 32px;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: #f3f3f3;\n}\n.igv-navbar .igv-navbar-left-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-left-container .igv-logo {\n width: 34px;\n height: 32px;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\n height: 32px;\n margin-left: 4px;\n margin-right: 4px;\n user-select: none;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n height: 100%;\n width: 125px;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n display: block;\n cursor: pointer;\n width: 100px;\n height: 75%;\n outline: none;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n margin-left: 8px;\n height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 240px;\n height: 22px;\n line-height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n cursor: text;\n width: 85%;\n height: 22px;\n line-height: 22px;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n text-align: left;\n padding-left: 8px;\n margin-right: 8px;\n outline: none;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: white;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n cursor: pointer;\n height: 16px;\n width: 16px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n margin-left: 4px;\n user-select: none;\n}\n.igv-navbar .igv-navbar-right-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\n margin-left: 0;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\n margin-left: 0;\n margin-right: 0;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n display: block;\n height: fit-content;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n display: block;\n width: 125px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n display: none;\n}\n\n.igv-navbar-button {\n display: block;\n box-sizing: unset;\n padding-left: 6px;\n padding-right: 6px;\n height: 18px;\n text-transform: capitalize;\n user-select: none;\n line-height: 18px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 11px;\n font-weight: 200;\n color: #737373;\n background-color: #f3f3f3;\n border-color: #737373;\n border-style: solid;\n border-width: thin;\n border-radius: 6px;\n}\n\n.igv-navbar-button-clicked {\n color: white;\n background-color: #737373;\n}\n\n.igv-navbar-button:hover {\n cursor: pointer;\n}\n\n.igv-zoom-in-notice-container {\n z-index: 1024;\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translate(-50%, 0%);\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n background-color: white;\n}\n.igv-zoom-in-notice-container > div {\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n width: 100%;\n height: 100%;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: #3f3f3f;\n}\n\n.igv-zoom-in-notice {\n position: absolute;\n top: 10px;\n left: 50%;\n}\n.igv-zoom-in-notice div {\n position: relative;\n left: -50%;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #3f3f3f;\n background-color: rgba(255, 255, 255, 0.51);\n z-index: 64;\n}\n\n.igv-container-spinner {\n position: absolute;\n top: 90%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1024;\n width: 24px;\n height: 24px;\n pointer-events: none;\n color: #737373;\n}\n\n.igv-multi-locus-close-button {\n position: absolute;\n top: 2px;\n right: 0;\n padding-left: 2px;\n padding-right: 2px;\n width: 12px;\n height: 12px;\n color: #666666;\n background-color: white;\n z-index: 1000;\n}\n.igv-multi-locus-close-button > svg {\n vertical-align: top;\n}\n\n.igv-multi-locus-close-button:hover {\n cursor: pointer;\n color: #434343;\n}\n\n.igv-multi-locus-ruler-label {\n z-index: 64;\n position: absolute;\n top: 2px;\n left: 0;\n width: 100%;\n height: 12px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-multi-locus-ruler-label > div {\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n.igv-multi-locus-ruler-label > div {\n cursor: pointer;\n}\n\n.igv-multi-locus-ruler-label-square-dot {\n z-index: 64;\n position: absolute;\n left: 50%;\n top: 5%;\n transform: translate(-50%, 0%);\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\n width: 14px;\n height: 14px;\n}\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\n margin-left: 16px;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n}\n\n.igv-ruler-sweeper {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 26px;\n bottom: 0;\n left: 0;\n width: 0;\n z-index: 99999;\n background-color: rgba(68, 134, 247, 0.25);\n}\n\n.igv-ruler-tooltip {\n pointer-events: none;\n z-index: 128;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 32px;\n background-color: transparent;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ruler-tooltip > div {\n pointer-events: none;\n width: 128px;\n height: auto;\n padding: 1px;\n color: #373737;\n font-size: 10px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n background-color: white;\n border-style: solid;\n border-width: thin;\n border-color: #373737;\n}\n\n.igv-track-label {\n position: absolute;\n left: 8px;\n top: 8px;\n width: auto;\n height: auto;\n max-width: 50%;\n padding-left: 4px;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n text-align: center;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-color: #444;\n border-radius: 2px;\n border-style: solid;\n border-width: thin;\n background-color: white;\n z-index: 128;\n cursor: pointer;\n}\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n background-color: #e8e8e8;\n}\n\n.igv-track-label-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-top: 4px;\n}\n\n.igv-center-line {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n z-index: 8;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-left-style: dashed;\n border-left-width: thin;\n border-right-style: dashed;\n border-right-width: thin;\n}\n\n.igv-center-line-wide {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(127, 127, 127, 0.51);\n}\n\n.igv-center-line-thin {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(0, 0, 0, 0);\n}\n\n.igv-cursor-guide-horizontal {\n display: none;\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 50%;\n height: 1px;\n z-index: 1;\n margin-left: 50px;\n margin-right: 54px;\n border-top-style: dotted;\n border-top-width: thin;\n border-top-color: rgba(127, 127, 127, 0.76);\n}\n\n.igv-cursor-guide-vertical {\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n width: 1px;\n z-index: 1;\n border-left-style: dotted;\n border-left-width: thin;\n border-left-color: rgba(127, 127, 127, 0.76);\n display: none;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-generic-dialog-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-generic-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-generic-container div:first-child i {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-menu-popup {\n position: absolute;\n top: 0;\n left: 0;\n width: max-content;\n z-index: 4096;\n cursor: pointer;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background: white;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-end;\n text-align: left;\n}\n.igv-menu-popup > div:not(:first-child) {\n width: 100%;\n}\n.igv-menu-popup > div:not(:first-child) > div {\n background: white;\n}\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\n padding-left: 4px;\n padding-right: 4px;\n}\n.igv-menu-popup > div:not(:first-child) > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-menu-popup > div:not(:first-child) > div:hover {\n background: #efefef;\n}\n\n.igv-menu-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-bottom: 1px;\n padding-top: 1px;\n}\n\n.igv-menu-popup-header {\n position: relative;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-menu-popup-header div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-menu-popup-header div:hover {\n cursor: pointer;\n color: #444;\n}\n\n.igv-menu-popup-check-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 20px;\n margin-right: 4px;\n background-color: transparent;\n}\n.igv-menu-popup-check-container div {\n padding-top: 2px;\n padding-left: 8px;\n}\n.igv-menu-popup-check-container div:first-child {\n position: relative;\n width: 12px;\n height: 12px;\n}\n.igv-menu-popup-check-container div:first-child svg {\n position: absolute;\n width: 12px;\n height: 12px;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-loading-spinner-container {\n z-index: 1024;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-loading-spinner-container > div {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 4px solid rgba(128, 128, 128, 0.5);\n border-top-color: rgb(255, 255, 255);\n animation: spin 1s ease-in-out infinite;\n -webkit-animation: spin 1s ease-in-out infinite;\n}\n\n@keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.igv-roi-menu-next-gen {\n position: absolute;\n z-index: 512;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background-color: white;\n width: 192px;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu-next-gen > div:first-child {\n height: 24px;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-roi-menu-next-gen > div:first-child > div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-roi-menu-next-gen > div:first-child > div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-menu-next-gen > div:last-child {\n background-color: white;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n text-align: start;\n vertical-align: middle;\n}\n.igv-roi-menu-next-gen > div:last-child > div {\n height: 24px;\n padding-left: 4px;\n border-bottom-style: solid;\n border-bottom-width: thin;\n border-bottom-color: #7f7f7f;\n}\n.igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {\n background-color: rgba(127, 127, 127, 0.1);\n}\n.igv-roi-menu-next-gen > div:last-child div:first-child {\n font-style: italic;\n text-align: center;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-menu-next-gen > div:last-child > div:last-child {\n border-bottom-width: 0;\n border-bottom-color: transparent;\n}\n\n.igv-roi-placeholder {\n font-style: normal;\n color: rgba(75, 75, 75, 0.6);\n}\n\n.igv-roi-table {\n position: absolute;\n z-index: 1024;\n width: min-content;\n max-width: 1600px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n cursor: default;\n}\n.igv-roi-table > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table > div:first-child > div:first-child {\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n margin-left: 4px;\n margin-right: 4px;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table > .igv-roi-table-description {\n padding: 4px;\n margin-left: 4px;\n word-break: break-all;\n overflow-y: auto;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-goto-explainer {\n margin-top: 5px;\n margin-left: 4px;\n color: #7F7F7F;\n font-style: italic;\n height: 24px;\n border-top: solid lightgray;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: #7f7f7f;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n overflow: auto;\n resize: both;\n max-width: 1600px;\n height: 360px;\n background-color: transparent;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: transparent;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n cursor: pointer;\n height: 20px;\n user-select: none;\n line-height: 20px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 13px;\n font-weight: 400;\n color: black;\n padding-left: 6px;\n padding-right: 6px;\n background-color: rgb(239, 239, 239);\n border-color: black;\n border-style: solid;\n border-width: thin;\n border-radius: 3px;\n}\n\n.igv-roi-table-button:hover {\n font-weight: 400;\n background-color: rgba(0, 0, 0, 0.13);\n}\n\n.igv-roi-region {\n z-index: 64;\n position: absolute;\n top: 0;\n bottom: 0;\n pointer-events: none;\n overflow: visible;\n margin-top: 44px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-region > div {\n position: relative;\n width: 100%;\n height: 8px;\n pointer-events: auto;\n}\n\n.igv-roi-menu {\n position: absolute;\n z-index: 1024;\n width: 144px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu > div:not(:last-child) {\n border-bottom-color: rgba(128, 128, 128, 0.5);\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-menu > div:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-color: transparent;\n border-top-style: solid;\n border-top-width: 0;\n}\n.igv-roi-menu > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n}\n\n.igv-roi-menu-row {\n height: 24px;\n padding-left: 8px;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n background-color: white;\n}\n\n.igv-roi-menu-row-edit-description {\n width: -webkit-fill-available;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-menu-row-edit-description > label {\n margin-left: 2px;\n margin-bottom: 0;\n display: block;\n width: -webkit-fill-available;\n}\n.igv-roi-menu-row-edit-description > input {\n display: block;\n margin-left: 2px;\n margin-right: 2px;\n margin-bottom: 1px;\n width: -webkit-fill-available;\n}\n\n.igv-container {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 4px;\n user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n min-height: 160px;\n}\n\n.igv-viewport {\n position: relative;\n margin-top: 5px;\n line-height: 1;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.igv-viewport-content {\n position: relative;\n width: 100%;\n}\n.igv-viewport-content > canvas {\n position: relative;\n display: block;\n}\n\n.igv-column-container {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n width: 100%;\n}\n\n.igv-column-shim {\n width: 1px;\n margin-left: 2px;\n margin-right: 2px;\n background-color: #545453;\n}\n\n.igv-axis-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 50px;\n}\n.igv-axis-column > div {\n margin-top: 5px;\n width: 100%;\n}\n\n.igv-column {\n position: relative;\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-sample-info-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-sample-name-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-scrollbar-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 14px;\n}\n.igv-scrollbar-column > div {\n position: relative;\n margin-top: 5px;\n width: 14px;\n}\n.igv-scrollbar-column > div > div {\n cursor: pointer;\n position: absolute;\n top: 0;\n left: 2px;\n width: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: #c4c4c4;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.igv-scrollbar-column > div > div:hover {\n background-color: #c4c4c4;\n}\n\n.igv-track-drag-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 12px;\n background-color: white;\n}\n.igv-track-drag-column > .igv-track-drag-handle {\n z-index: 512;\n position: relative;\n cursor: pointer;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n background-color: #c4c4c4;\n}\n.igv-track-drag-column .igv-track-drag-handle-hover {\n background-color: #787878;\n}\n.igv-track-drag-column > .igv-track-drag-shim {\n position: relative;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n}\n\n.igv-gear-menu-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 28px;\n}\n.igv-gear-menu-column > div {\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n margin-top: 5px;\n width: 100%;\n background: white;\n}\n.igv-gear-menu-column > div > div {\n position: relative;\n margin-top: 4px;\n width: 16px;\n height: 16px;\n color: #7F7F7F;\n}\n.igv-gear-menu-column > div > div:hover {\n cursor: pointer;\n color: #444;\n}\n\n/*# sourceMappingURL=dom.css.map */\n'
var style = document.createElement('style')
style.setAttribute('type', 'text/css')
diff --git a/js/igv-create.js b/js/igv-create.js
index beafb94bf..1643bb224 100644
--- a/js/igv-create.js
+++ b/js/igv-create.js
@@ -68,7 +68,9 @@ async function createBrowser(parentDiv, config) {
const browser = new Browser(config, parentDiv)
allBrowsers.push(browser)
- // Load initial session
+ // Lod initial sessio
+ browser.startSpinner()
+
const sessionURL = config.sessionURL || config.session || config.hubURL
if (sessionURL) {
await browser.loadSession({
@@ -78,7 +80,10 @@ async function createBrowser(parentDiv, config) {
await browser.loadSessionObject(config)
}
- browser.navbarManager.navbarDidResize(browser.$navigation.width())
+ browser.stopSpinner()
+
+ navbarDidResize(browser, browser.$navigation.width())
+
return browser
From 67cf4f34cef978549ebe4eb9404d661c20b1707d Mon Sep 17 00:00:00 2001
From: Jim Robinson <933148+jrobinso@users.noreply.github.com>
Date: Thu, 5 Oct 2023 16:59:42 -0700
Subject: [PATCH 4/9] Slow hub (#1707)
* use igvxhr for hub parsing
* Use unsigned short for certain BB fields, add unit test.
* add slow hub example
* Some temporary optimizations -- use chromSizes.txt file to define sizes, load cytbobanUrlBB and chromAliasBB asyncr
* fix tests
---
dev/ucsc/slowHub.html | 65 ++++++++++++++++++++++++++++++++++++++
js/genome/chromSizes.js | 32 ++++++++++++++++++-
js/genome/cytoband.js | 28 ++++++++--------
js/genome/genome.js | 16 +++++++++-
js/genome/genomeUtils.js | 44 ++++++++++++++++++--------
js/ucsc/ucscHub.js | 4 +++
test/testAlignmentUtils.js | 2 +-
test/testGenomeUtils.js | 2 +-
8 files changed, 162 insertions(+), 31 deletions(-)
create mode 100644 dev/ucsc/slowHub.html
diff --git a/dev/ucsc/slowHub.html b/dev/ucsc/slowHub.html
new file mode 100644
index 000000000..0a8aea578
--- /dev/null
+++ b/dev/ucsc/slowHub.html
@@ -0,0 +1,65 @@
+
+
+
+ twobit
+
+
+
+
+
+
+ Many chromosomes ~ same size
+
+ Many chromosomes - gradually decreasing
+ chromosomes
+
+ 24 large chromosomes
+
+ T2T
+
+
+
+ Enter full URL to hub.txt file
+
+
+
+Load hub as genome
+Load hub as session
+
+
+
+
+
+
+
+
diff --git a/js/genome/chromSizes.js b/js/genome/chromSizes.js
index a57dc7ec0..320a9bf1d 100644
--- a/js/genome/chromSizes.js
+++ b/js/genome/chromSizes.js
@@ -32,6 +32,9 @@ const splitLines = StringUtils.splitLines
const reservedProperties = new Set(['fastaURL', 'indexURL', 'cytobandURL', 'indexed'])
+/**
+ * Represents a reference object created from a ChromSizes file. This is unusual, primarily for testing.
+ */
class ChromSizes {
#chromosomeNames
@@ -41,7 +44,6 @@ class ChromSizes {
this.url = url
}
-
async init() {
return this.loadAll()
}
@@ -83,5 +85,33 @@ class ChromSizes {
}
+async function loadChromSizes(url) {
+
+ const chromosomeSizes = new Map();
+
+ let data
+ if (isDataURL(url)) {
+ let bytes = BGZip.decodeDataURI(url)
+ data = ""
+ for (let b of bytes) {
+ data += String.fromCharCode(b)
+ }
+ } else {
+ data = await igvxhr.load(url, {})
+ }
+
+ const lines = splitLines(data)
+ let order = 0
+ for (let nextLine of lines) {
+ const tokens = nextLine.split('\t')
+ if(tokens.length > 1) {
+ const chrLength = Number.parseInt(tokens[1])
+ chromosomeSizes.set(tokens[0], new Chromosome(tokens[0], order++, chrLength))
+ }
+ }
+ return chromosomeSizes
+}
+
export default ChromSizes
+export {loadChromSizes}
diff --git a/js/genome/cytoband.js b/js/genome/cytoband.js
index 733655a81..0ab9cd1b1 100644
--- a/js/genome/cytoband.js
+++ b/js/genome/cytoband.js
@@ -3,19 +3,21 @@ import {BGZip, igvxhr, StringUtils} from "../../node_modules/igv-utils/src/index
import BWReader from "../bigwig/bwReader.js"
import Chromosome from "./chromosome.js"
-const Cytoband = function (start, end, name, typestain) {
- this.start = start
- this.end = end
- this.name = name
- this.stain = 0
-
- // Set the type, either p, n, or c
- if (typestain === 'acen') {
- this.type = 'c'
- } else {
- this.type = typestain.charAt(1)
- if (this.type === 'p') {
- this.stain = parseInt(typestain.substring(4))
+class Cytoband {
+ constructor(start, end, name, typestain) {
+ this.start = start
+ this.end = end
+ this.name = name
+ this.stain = 0
+
+ // Set the type, either p, n, or c
+ if (typestain === 'acen') {
+ this.type = 'c'
+ } else {
+ this.type = typestain.charAt(1)
+ if (this.type === 'p') {
+ this.stain = parseInt(typestain.substring(4))
+ }
}
}
}
diff --git a/js/genome/genome.js b/js/genome/genome.js
index d2a7e7879..b706897ce 100644
--- a/js/genome/genome.js
+++ b/js/genome/genome.js
@@ -40,7 +40,11 @@ class Genome {
}
// Build the alias table and correct cytoband sequence names
- this.chrAliasTable = createAliasTable(this.chromosomes, aliases)
+ if(aliases) {
+ this.chrAliasTable = createAliasTable(this.chromosomes, aliases)
+ } else {
+ this.chrAliasTable = {}
+ }
if (cytobands) {
this.cytobands = {}
@@ -57,10 +61,20 @@ class Genome {
this.chromosomes.set("all", new Chromosome("all", 0, l))
//this.chromosomeNames.unshift("all")
}
+ }
+ updateChromosomes(chromosomes) {
+ for(let key of chromosomes.keys()) {
+ this.chromosomes.set(key, chromosomes.get(key))
+ }
+ }
+ updateAliases(aliases) {
+ this.chrAliasTable = createAliasTable(this.chromosomes, aliases);
}
+
+
get description() {
return this.config.description || `${this.id}\n${this.name}`
}
diff --git a/js/genome/genomeUtils.js b/js/genome/genomeUtils.js
index 9f5f908e1..c426dd529 100644
--- a/js/genome/genomeUtils.js
+++ b/js/genome/genomeUtils.js
@@ -1,6 +1,7 @@
import Genome from "./genome.js"
import {loadFasta} from "./fasta.js"
import {loadCytobands, loadCytobandsBB} from "./cytoband.js"
+import {loadChromSizes} from "./chromSizes.js"
import {buildOptions} from "../util/igvUtils.js"
import {igvxhr, StringUtils} from "../../node_modules/igv-utils/src/index.js"
import BWReader from "../bigwig/bwReader.js"
@@ -18,29 +19,44 @@ const GenomeUtils = {
let aliases
let chromosomes
let cytobands
- if (options.aliasBbURL) { // Order is important, try this first
- const abb = await loadAliasesBB(options.aliasBbURL, options)
- aliases = abb.aliases
- chromosomes = abb.chromosomes
+
+
+ if (options.chromSizes) { // Order is important, try this first
+ chromosomes = await loadChromSizes(options.chromSizes)
} else {
chromosomes = sequence.chromosomes
- if (options.aliasURL) {
- aliases = await loadAliases(options.aliasURL, options)
- }
}
- if (options.cytobandBbURL) {
- const cc = await loadCytobandsBB(options.cytobandBbURL, options)
- cytobands = cc.cytobands
- if (!chromosomes) {
- chromosomes = cc.chromosomes
- }
- } else if (options.cytobandURL) {
+
+ if (options.cytobandURL) {
cytobands = await loadCytobands(options.cytobandURL, options)
}
+ if (options.aliasURL) {
+ aliases = await loadAliases(options.aliasURL, options)
+ }
+
+
const genome = new Genome(options, sequence, aliases, chromosomes, cytobands)
+ if (options.cytobandBbURL) {
+
+ loadCytobandsBB(options.cytobandBbURL, options).then((cc) => {
+ if (!chromosomes) {
+ genome.updateChromosomes(cc.chromosomes)
+ }
+ genome.cytobands = cc.cytobands
+ })
+ }
+ if (options.aliasBbURL) {
+ loadAliasesBB(options.aliasBbURL, options)
+ .then(abb => {
+ genome.updateChromosomes(abb.chromosomes)
+ genome.updateAliases(abb.aliases)
+ })
+ }
+
+
return genome
},
diff --git a/js/ucsc/ucscHub.js b/js/ucsc/ucscHub.js
index 7d60e7cbf..7cbf6def6 100644
--- a/js/ucsc/ucscHub.js
+++ b/js/ucsc/ucscHub.js
@@ -113,6 +113,10 @@ isPcr dynablat-01.soe.ucsc.edu 4040 dynamic GCF/000/186/305/GCF_000186305.1
}
config.description = config.id
+
+ if (this.genomeStanza.hasProperty("chromSizes")) {
+ config.chromSizes = this.baseURL + this.genomeStanza.getProperty("chromSizes")
+ }
if (this.genomeStanza.hasProperty("description")) {
config.description += `\n${this.genomeStanza.getProperty("description")}`
}
diff --git a/test/testAlignmentUtils.js b/test/testAlignmentUtils.js
index 6d99cb804..aef5a04df 100755
--- a/test/testAlignmentUtils.js
+++ b/test/testAlignmentUtils.js
@@ -7,7 +7,7 @@ suite("testAlignmentUtils", function () {
test("Alignment packing", async function () {
-
+ this.timeout(10000)
const chr = 'chr22'
const start = 24375132
const end = 24385311
diff --git a/test/testGenomeUtils.js b/test/testGenomeUtils.js
index 9903d01f2..2e0e5e939 100644
--- a/test/testGenomeUtils.js
+++ b/test/testGenomeUtils.js
@@ -126,7 +126,7 @@ suite("testGenomeUtils", function () {
id: "GCF_016699485.2",
format: "2bit",
twobitURL: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.2bit",
- aliasBbURL: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.chromAlias.bb"
+ chromSizes: "https://hgdownload.gi.ucsc.edu/hubs//GCA/011/100/615/GCA_011100615.1/GCA_011100615.1.chrom.sizes.txt"
}
From 514e65a0678d53a467a7dacc99b868bcb44e7e95 Mon Sep 17 00:00:00 2001
From: Douglass Turner
Date: Thu, 5 Oct 2023 23:57:38 -0400
Subject: [PATCH 5/9] Latest edits. Rebased to master (#1706)
* Support for selecting multiple tracks for group autoscale and overlay. Also supports applying common menu actions to multiple tracks at once.
* Navbar changes -- switch to icons when window is narrow
---
css/_navbar.scss | 246 ++++++++--
css/_roi.scss | 57 +--
css/dom.css | 255 +++++++---
css/dom.css.map | 3 +-
css/dom.scss | 33 +-
dev/misc/multi-select.html | 384 +++++++++++++++
dev/misc/navbar-buttons.html | 143 ++++++
dev/multi-select/multi-select.html | 311 ++++++++++++
dev/roi/roi.html | 1 -
dev/sampleInfo/sampleInfo.html | 95 +---
dev/ucsc/slowHub.html | 19 -
dev/wig/bigWigs.html | 2 +
dev/wig/wigs.html | 84 ++--
js/bam/bamTrack.js | 73 +--
js/blat/blatTrack.js | 10 +-
js/browser.js | 68 ++-
js/cnvpytor/cnvpytorTrack.js | 27 +-
js/embedCss.js | 4 +-
js/feature/featureTrack.js | 54 +-
js/feature/interactionTrack.js | 11 +-
js/feature/mergedTrack.js | 11 +-
js/feature/segTrack.js | 63 ++-
js/feature/wigTrack.js | 24 +-
js/gcnv/gcnvTrack.js | 2 +-
js/gtex/eqtlTrack.js | 2 +-
js/gwas/gwasTrack.js | 2 +-
js/igv-create.js | 9 +-
js/navbarManager.js | 86 ----
js/responsiveNavbar.js | 89 ++++
js/rna/rnaStruct.js | 11 +-
js/roi/ROIManager.js | 10 +-
js/roi/ROIMenu.js | 2 +-
.../roiTableControl.js} | 40 +-
js/rulerViewport.js | 2 +-
js/sample/sampleInfoControl.js | 47 +-
js/sample/sampleInfoViewport.js | 26 +-
js/{ui => sample}/sampleNameControl.js | 57 +--
js/trackBase.js | 51 +-
js/trackView.js | 175 ++++---
js/trackViewport.js | 4 +-
js/ui/centerLineButton.js | 86 ++--
js/ui/cursorGuideButton.js | 58 ++-
js/ui/dataRangeDialog.js | 34 +-
js/ui/menuPopup.js | 194 +++++---
js/ui/menuUtils.js | 463 +++++++++++-------
js/ui/multiTrackSelectButton.js | 88 ++++
js/ui/navbarButton.js | 138 ++++++
js/ui/navbarIcons/buttonLabel.js | 26 +
js/ui/navbarIcons/centerline.js | 23 +
js/ui/navbarIcons/cursor.js | 31 ++
js/ui/navbarIcons/multiSelect.js | 45 ++
js/ui/navbarIcons/roi.js | 27 +
js/ui/navbarIcons/sampleInfo.js | 72 +++
js/ui/navbarIcons/sampleNames.js | 27 +
js/ui/navbarIcons/saveImage.js | 165 +++++++
js/ui/navbarIcons/trackLabels.js | 29 ++
js/ui/roiTableControl.js | 81 ---
js/ui/saveImageControl.js | 129 +++++
js/ui/trackLabelControl.js | 55 +--
js/ui/viewportCenterLine.js | 2 +-
js/util/colorPalletes.js | 62 ++-
js/util/paintAxis.js | 3 +-
js/variant/variantTrack.js | 9 +-
package.json | 1 +
64 files changed, 3308 insertions(+), 1133 deletions(-)
create mode 100644 dev/misc/multi-select.html
create mode 100644 dev/misc/navbar-buttons.html
create mode 100644 dev/multi-select/multi-select.html
delete mode 100644 js/navbarManager.js
create mode 100644 js/responsiveNavbar.js
rename js/{ui/svgSaveControl.js => roi/roiTableControl.js} (52%)
rename js/{ui => sample}/sampleNameControl.js (59%)
create mode 100644 js/ui/multiTrackSelectButton.js
create mode 100644 js/ui/navbarButton.js
create mode 100644 js/ui/navbarIcons/buttonLabel.js
create mode 100644 js/ui/navbarIcons/centerline.js
create mode 100644 js/ui/navbarIcons/cursor.js
create mode 100644 js/ui/navbarIcons/multiSelect.js
create mode 100644 js/ui/navbarIcons/roi.js
create mode 100644 js/ui/navbarIcons/sampleInfo.js
create mode 100644 js/ui/navbarIcons/sampleNames.js
create mode 100644 js/ui/navbarIcons/saveImage.js
create mode 100644 js/ui/navbarIcons/trackLabels.js
delete mode 100644 js/ui/roiTableControl.js
create mode 100644 js/ui/saveImageControl.js
diff --git a/css/_navbar.scss b/css/_navbar.scss
index 34655b950..6e8afda0f 100644
--- a/css/_navbar.scss
+++ b/css/_navbar.scss
@@ -12,6 +12,12 @@ $igv-navbar-button-border-radius: 6px;
$igv-navbar-locus-search-height: $igv-navbar-height - 10px;
+$igv-navbar-icon-button-size: 24px;
+
+$igv-save-image-y-origin: 1.5 * $igv-navbar-icon-button-size;
+$igv-save-svg-image-x-origin: -3*$igv-navbar-icon-button-size/4;
+$igv-save-png-image-x-origin: 3*$igv-navbar-icon-button-size/4;
+
.igv-navbar {
display: flex;
@@ -21,8 +27,7 @@ $igv-navbar-locus-search-height: $igv-navbar-height - 10px;
align-items: center;
box-sizing: border-box;
- width: 100%
-;
+ width: 100%;
color: #444;
font-size: $igv-navbar-font-size;
font-family: $igv-default-font-face;
@@ -197,33 +202,24 @@ $igv-navbar-locus-search-height: $igv-navbar-height - 10px;
justify-content: space-between;
align-items: center;
- height: $igv-navbar-height;
- line-height: $igv-navbar-height;
-
.igv-navbar-toggle-button-container {
-
display: flex;
flex-flow: row;
flex-wrap: nowrap;
- justify-content: space-between;
+ justify-content: flex-end;
align-items: center;
+ }
- height: 100%;
-
- div {
- margin-left: 0;
- margin-right: 4px;
- }
+ .igv-navbar-toggle-button-container-hidden {
- div:last-child {
- margin-left: 0;
- margin-right: 0;
- }
+ display: flex;
+ flex-flow: row;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ align-items: center;
- }
+ height: 100%;
- .igv-navbar-toggle-button-container-750 {
- display: none;
}
.igv-zoom-widget {
@@ -232,8 +228,8 @@ $igv-navbar-locus-search-height: $igv-navbar-height - 10px;
font-size: 18px;
- height: $igv-navbar-height;
- line-height: $igv-navbar-height;
+ //height: $igv-navbar-height;
+ //line-height: $igv-navbar-height;
margin-left: 8px;
@@ -254,20 +250,18 @@ $igv-navbar-locus-search-height: $igv-navbar-height - 10px;
// zoom-out
div:first-child {
- height: 24px;
- width: 24px;
+ height: 20px;
+ width: 20px;
margin-left: unset;
- margin-right: 8px;
- //background-color: magenta;
+ margin-right: 4px;
}
// zoom-in
div:last-child {
- height: 24px;
- width: 24px;
- margin-left: 8px;
+ height: 20px;
+ width: 20px;
+ margin-left: 4px;
margin-right: unset;
- //background-color: lime;
}
div:nth-child(even) {
@@ -306,26 +300,26 @@ $igv-navbar-locus-search-height: $igv-navbar-height - 10px;
justify-content: flex-end;
align-items: center;
-
+ // container: zoom-out | zoom-slider | zoom-in
div {
cursor: pointer;
margin-left: unset;
margin-right: unset;
}
- // "-" zoom button
+ // zoom-out
div:first-child {
- height: 24px;
- width: 24px;
+ height: 20px;
+ width: 20px;
margin-left: unset;
- margin-right: 8px;
+ margin-right: 4px;
}
- // "+" zoom button
+ // zoom-in
div:last-child {
- height: 24px;
- width: 24px;
- margin-left: 8px;
+ height: 20px;
+ width: 20px;
+ margin-left: 4px;
margin-right: unset;
}
@@ -387,11 +381,183 @@ $igv-navbar-locus-search-height: $igv-navbar-height - 10px;
border-radius: $igv-navbar-button-border-radius;
}
+.igv-navbar-button:hover {
+ cursor: pointer;
+}
+
.igv-navbar-button-clicked {
color: white;
background-color: $igv-navbar-toggle-dark-dark;
}
-.igv-navbar-button:hover {
+.igv-navbar-icon-button {
cursor: pointer;
+ //z-index: 2048;
+
+ position: relative;
+ width: $igv-navbar-icon-button-size;
+ height: $igv-navbar-icon-button-size;
+ margin-left: 4px;
+ margin-right: 4px;
+ border: none;
+
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+
+ >div:first-child {
+
+ z-index: 512;
+
+ position: absolute;
+ top: $igv-save-image-y-origin;
+ left: $igv-save-svg-image-x-origin;
+
+ width: $igv-navbar-icon-button-size;
+ height: $igv-navbar-icon-button-size;
+
+ border: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ }
+
+ >div:last-child {
+
+ z-index: 512;
+
+ position: absolute;
+ top: $igv-save-image-y-origin;
+ left: $igv-save-png-image-x-origin;
+
+ width: $igv-navbar-icon-button-size;
+ height: $igv-navbar-icon-button-size;
+
+ border: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ }
+}
+
+.igv-navbar-text-button {
+ cursor: pointer;
+ //z-index: 2049;
+
+ position: relative;
+ //width: 90px;
+ //height: 20px;
+ margin-left: 2px;
+ margin-right: 2px;
+ border: none;
+
+ // to position svg properly
+ display: flex;
+ justify-content: center;
+ align-items: center;
+
+ >div:nth-child(2) {
+
+ z-index: 512;
+
+ position: absolute;
+ top: $igv-save-image-y-origin;
+ left: 0;
+
+ width: 38px;
+ height: 18px;
+
+ border: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ }
+
+ >div:nth-child(3) {
+
+ z-index: 512;
+
+ position: absolute;
+ top: $igv-save-image-y-origin;
+ left: 42px;
+
+ width: 38px;
+ height: 18px;
+
+ border: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+ }
+
+}
+
+#igv-text-button-label {
+ text-anchor: middle;
+ dominant-baseline: middle;
+}
+
+.igv-navbar-text-button-svg-inactive {
+ rect {
+ stroke: #737373;
+ fill: white;
+ }
+ text {
+ fill: #737373;
+ }
+}
+
+.igv-navbar-text-button-svg-hover {
+ rect {
+ stroke: #737373;
+ fill: #737373;
+ }
+ text {
+ fill: white;
+ }
+
+}
+
+#igv-save-svg-group {
+ rect {
+ stroke: #737373;
+ fill: white;
+ }
+ text {
+ fill: #737373;
+ }
+
+}
+
+#igv-save-svg-group:hover {
+ rect {
+ stroke: #737373;
+ fill: #737373;
+ }
+ text {
+ fill: white;
+ }
+
+}
+
+#igv-save-png-group {
+ rect {
+ stroke: #737373;
+ fill: white;
+ }
+ text {
+ fill: #737373;
+ }
+
+}
+
+#igv-save-png-group:hover {
+ rect {
+ stroke: #737373;
+ fill: #737373;
+ }
+ text {
+ fill: white;
+ }
+
}
diff --git a/css/_roi.scss b/css/_roi.scss
index 73d5cca8e..037fc3bd4 100644
--- a/css/_roi.scss
+++ b/css/_roi.scss
@@ -25,7 +25,7 @@ $igv-roi-table-font-face: 'Open Sans', sans-serif;
$igv-roi-table-background-color: #eee;
// menu container
-.igv-roi-menu-next-gen {
+.igv-roi-menu {
position: absolute;
z-index: 512;
@@ -104,9 +104,9 @@ $igv-roi-table-background-color: #eee;
text-align: start;
vertical-align: middle;
- //cursor: pointer;
> div {
+
height: $dimension;
padding-left: 4px;
@@ -116,6 +116,7 @@ $igv-roi-table-background-color: #eee;
}
> div:not(:first-child):hover {
+ cursor: pointer;
background-color: rgba(127, 127, 127, 0.1);
}
@@ -211,7 +212,7 @@ $igv-roi-table-background-color: #eee;
text-align: center;
white-space: nowrap;
text-overflow: ellipsis;
-
+
overflow: hidden;
margin-left: 4px;
@@ -491,56 +492,6 @@ $igv-roi-table-background-color: #eee;
}
}
-.igv-roi-menu {
- position: absolute;
- z-index: 1024;
-
- width: (6 * $dimension);
-
- border-color: $igv-roi-border-color;
- border-radius: $igv-roi-table-border-radius;
- border-style: solid;
- border-width: thin;
-
- font-family: $igv-roi-table-font-face;
-
- background-color: white;
-
- display: flex;
- flex-flow: column;
- flex-wrap: nowrap;
- justify-content: flex-start;
- align-items: stretch;
-
- > div:not(:last-child) {
- border-bottom-color: rgba(128, 128, 128, 0.50);
- border-bottom-style: solid;
- border-bottom-width: thin;
- }
-
- > div:first-child {
-
- border-top-left-radius: $igv-roi-table-border-radius;
- border-top-right-radius: $igv-roi-table-border-radius;
- border-top-color: transparent;
- border-top-style: solid;
- border-top-width: 0;
-
- }
-
- > div:last-child {
-
- border-bottom-left-radius: $igv-roi-table-border-radius;
- border-bottom-right-radius: $igv-roi-table-border-radius;
- border-bottom-color: transparent;
- border-bottom-style: solid;
- border-bottom-width: 0;
-
- }
-
-
-}
-
.igv-roi-menu-row {
height: $dimension;
diff --git a/css/dom.css b/css/dom.css
index f5dd39609..e0022ebd0 100644
--- a/css/dom.css
+++ b/css/dom.css
@@ -130,33 +130,25 @@
flex-wrap: nowrap;
justify-content: space-between;
align-items: center;
- height: 32px;
- line-height: 32px;
}
.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {
display: flex;
flex-flow: row;
flex-wrap: nowrap;
- justify-content: space-between;
+ justify-content: flex-end;
align-items: center;
- height: 100%;
}
-.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {
- margin-left: 0;
- margin-right: 4px;
-}
-.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {
- margin-left: 0;
- margin-right: 0;
-}
-.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {
- display: none;
+.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-hidden {
+ display: flex;
+ flex-flow: row;
+ flex-wrap: nowrap;
+ justify-content: flex-start;
+ align-items: center;
+ height: 100%;
}
.igv-navbar .igv-navbar-right-container .igv-zoom-widget {
color: #737373;
font-size: 18px;
- height: 32px;
- line-height: 32px;
margin-left: 8px;
user-select: none;
display: flex;
@@ -171,15 +163,15 @@
margin-right: unset;
}
.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {
- height: 24px;
- width: 24px;
+ height: 20px;
+ width: 20px;
margin-left: unset;
- margin-right: 8px;
+ margin-right: 4px;
}
.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {
- height: 24px;
- width: 24px;
- margin-left: 8px;
+ height: 20px;
+ width: 20px;
+ margin-left: 4px;
margin-right: unset;
}
.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {
@@ -212,15 +204,15 @@
margin-right: unset;
}
.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {
- height: 24px;
- width: 24px;
+ height: 20px;
+ width: 20px;
margin-left: unset;
- margin-right: 8px;
+ margin-right: 4px;
}
.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {
- height: 24px;
- width: 24px;
- margin-left: 8px;
+ height: 20px;
+ width: 20px;
+ margin-left: 4px;
margin-right: unset;
}
.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {
@@ -262,13 +254,138 @@
border-radius: 6px;
}
+.igv-navbar-button:hover {
+ cursor: pointer;
+}
+
.igv-navbar-button-clicked {
color: white;
background-color: #737373;
}
-.igv-navbar-button:hover {
+.igv-navbar-icon-button {
cursor: pointer;
+ position: relative;
+ width: 24px;
+ height: 24px;
+ margin-left: 4px;
+ margin-right: 4px;
+ border: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.igv-navbar-icon-button > div:first-child {
+ z-index: 512;
+ position: absolute;
+ top: 36px;
+ left: -18px;
+ width: 24px;
+ height: 24px;
+ border: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.igv-navbar-icon-button > div:last-child {
+ z-index: 512;
+ position: absolute;
+ top: 36px;
+ left: 18px;
+ width: 24px;
+ height: 24px;
+ border: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+
+.igv-navbar-text-button {
+ cursor: pointer;
+ position: relative;
+ margin-left: 2px;
+ margin-right: 2px;
+ border: none;
+ display: flex;
+ justify-content: center;
+ align-items: center;
+}
+.igv-navbar-text-button > div:nth-child(2) {
+ z-index: 512;
+ position: absolute;
+ top: 36px;
+ left: 0;
+ width: 38px;
+ height: 18px;
+ border: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+.igv-navbar-text-button > div:nth-child(3) {
+ z-index: 512;
+ position: absolute;
+ top: 36px;
+ left: 42px;
+ width: 38px;
+ height: 18px;
+ border: none;
+ background-size: contain;
+ background-repeat: no-repeat;
+ background-position: center;
+}
+
+#igv-text-button-label {
+ text-anchor: middle;
+ dominant-baseline: middle;
+}
+
+.igv-navbar-text-button-svg-inactive rect {
+ stroke: #737373;
+ fill: white;
+}
+.igv-navbar-text-button-svg-inactive text {
+ fill: #737373;
+}
+
+.igv-navbar-text-button-svg-hover rect {
+ stroke: #737373;
+ fill: #737373;
+}
+.igv-navbar-text-button-svg-hover text {
+ fill: white;
+}
+
+#igv-save-svg-group rect {
+ stroke: #737373;
+ fill: white;
+}
+#igv-save-svg-group text {
+ fill: #737373;
+}
+
+#igv-save-svg-group:hover rect {
+ stroke: #737373;
+ fill: #737373;
+}
+#igv-save-svg-group:hover text {
+ fill: white;
+}
+
+#igv-save-png-group rect {
+ stroke: #737373;
+ fill: white;
+}
+#igv-save-png-group text {
+ fill: #737373;
+}
+
+#igv-save-png-group:hover rect {
+ stroke: #737373;
+ fill: #737373;
+}
+#igv-save-png-group:hover text {
+ fill: white;
}
.igv-zoom-in-notice-container {
@@ -1033,7 +1150,7 @@
transform: rotate(360deg);
}
}
-.igv-roi-menu-next-gen {
+.igv-roi-menu {
position: absolute;
z-index: 512;
font-family: "Open Sans", sans-serif;
@@ -1052,7 +1169,7 @@
justify-content: flex-start;
align-items: stretch;
}
-.igv-roi-menu-next-gen > div:first-child {
+.igv-roi-menu > div:first-child {
height: 24px;
border-top-color: transparent;
border-top-left-radius: 4px;
@@ -1067,17 +1184,17 @@
justify-content: flex-end;
align-items: center;
}
-.igv-roi-menu-next-gen > div:first-child > div {
+.igv-roi-menu > div:first-child > div {
margin-right: 4px;
height: 12px;
width: 12px;
color: #7F7F7F;
}
-.igv-roi-menu-next-gen > div:first-child > div:hover {
+.igv-roi-menu > div:first-child > div:hover {
cursor: pointer;
color: #444;
}
-.igv-roi-menu-next-gen > div:last-child {
+.igv-roi-menu > div:last-child {
background-color: white;
border-bottom-left-radius: 4px;
border-bottom-right-radius: 4px;
@@ -1092,17 +1209,18 @@
text-align: start;
vertical-align: middle;
}
-.igv-roi-menu-next-gen > div:last-child > div {
+.igv-roi-menu > div:last-child > div {
height: 24px;
padding-left: 4px;
border-bottom-style: solid;
border-bottom-width: thin;
border-bottom-color: #7f7f7f;
}
-.igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {
+.igv-roi-menu > div:last-child > div:not(:first-child):hover {
+ cursor: pointer;
background-color: rgba(127, 127, 127, 0.1);
}
-.igv-roi-menu-next-gen > div:last-child div:first-child {
+.igv-roi-menu > div:last-child div:first-child {
font-style: italic;
text-align: center;
padding-right: 4px;
@@ -1110,7 +1228,7 @@
overflow: hidden;
text-overflow: ellipsis;
}
-.igv-roi-menu-next-gen > div:last-child > div:last-child {
+.igv-roi-menu > div:last-child > div:last-child {
border-bottom-width: 0;
border-bottom-color: transparent;
}
@@ -1345,42 +1463,6 @@
pointer-events: auto;
}
-.igv-roi-menu {
- position: absolute;
- z-index: 1024;
- width: 144px;
- border-color: #7f7f7f;
- border-radius: 4px;
- border-style: solid;
- border-width: thin;
- font-family: "Open Sans", sans-serif;
- background-color: white;
- display: flex;
- flex-flow: column;
- flex-wrap: nowrap;
- justify-content: flex-start;
- align-items: stretch;
-}
-.igv-roi-menu > div:not(:last-child) {
- border-bottom-color: rgba(128, 128, 128, 0.5);
- border-bottom-style: solid;
- border-bottom-width: thin;
-}
-.igv-roi-menu > div:first-child {
- border-top-left-radius: 4px;
- border-top-right-radius: 4px;
- border-top-color: transparent;
- border-top-style: solid;
- border-top-width: 0;
-}
-.igv-roi-menu > div:last-child {
- border-bottom-left-radius: 4px;
- border-bottom-right-radius: 4px;
- border-bottom-color: transparent;
- border-bottom-style: solid;
- border-bottom-width: 0;
-}
-
.igv-roi-menu-row {
height: 24px;
padding-left: 8px;
@@ -1480,9 +1562,27 @@
width: 50px;
}
.igv-axis-column > div {
+ position: relative;
margin-top: 5px;
width: 100%;
}
+.igv-axis-column > div > div {
+ z-index: 512;
+ position: absolute;
+ top: 8px;
+ left: 8px;
+ width: fit-content;
+ height: fit-content;
+ background-color: transparent;
+ display: grid;
+ align-items: start;
+ justify-items: center;
+}
+.igv-axis-column > div > div > input {
+ display: block;
+ margin: unset;
+ cursor: pointer;
+}
.igv-column {
position: relative;
@@ -1574,11 +1674,16 @@
border-width: 0;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
+}
+.igv-track-drag-column .igv-track-drag-handle-color {
background-color: #c4c4c4;
}
-.igv-track-drag-column .igv-track-drag-handle-hover {
+.igv-track-drag-column .igv-track-drag-handle-hover-color {
background-color: #787878;
}
+.igv-track-drag-column .igv-track-drag-handle-selected-color {
+ background-color: #0963fa;
+}
.igv-track-drag-column > .igv-track-drag-shim {
position: relative;
margin-top: 5px;
diff --git a/css/dom.css.map b/css/dom.css.map
index e53cbf05f..a0273930b 100644
--- a/css/dom.css.map
+++ b/css/dom.css.map
@@ -1 +1,2 @@
-{"version":3,"sourceRoot":"","sources":["_navbar.scss","_font.scss","_color.scss","_dom-misc.scss","_apple_crayon_color.scss","_igv-center-line.scss","_igv-cursor-guide.scss","dom.scss","_igv-user-feedback.scss","_igv-generic-dialog-container.scss","_igv-generic-container.scss","_igv-menu-popup.scss","_spinner.scss","_roi.scss"],"names":[],"mappings":"AAcA;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA,WAvBqB;EAwBrB,aC3BsB;ED4BtB;EACA,aAvBkB;EAyBlB;EACA;EAEA;EACA;EAEA,QA/BkB;EAiClB;EACA;EACA;EACA,cElCiB;EFmCjB,kBA3C8B;;AA6C9B;EAEE;EACA;EACA;EACA;EACA;EAEA,QA/CgB;EAgDhB,aAhDgB;;AAkDhB;EACE;EACA,QApDc;EAqDd;;AAGF;EACE,QAzDc;EA0Dd;EACA;EACA;EAEA,aA9Dc;EA+Dd;EACA;;AAGF;EAEE;EACA;EACA;EACA;EACA;EAEA;;AAEA;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EAEE;EAEA;EAEA;EACA;EAEA;EAEA,WAxGa;EAyGb,aC5Gc;ED6Gd;;AAKJ;EACE;EACA;EACA;EACA;EACA;EAEA;EACA,QA9GyB;;AAiHzB;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA,QA1HuB;EA2HvB,aA3HuB;;AA8HvB;EACE;EAEA;EAEA,QAnIqB;EAoIrB,aApIqB;EAsIrB,WA/IW;EAgJX,aCnJY;EDoJZ;EACA;EAEA;EACA;EAEA;EAEA;EACA;EACA;EACA,cEvJO;EFyJP;;AAIF;EACE;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAMJ;EACE;EACA;;AASR;EAEE;EACA;EACA;EACA;EACA;EAEA,QAjMgB;EAkMhB,aAlMgB;;AAoMhB;EAEE;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;;AAKJ;EACE;;AAGF;EAEE,OArOwB;EAuOxB;EAEA,QApOc;EAqOd,aArOc;EAuOd;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAKF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;;AAIF;EACE;EACA;;AAGF;EACE;;AAKJ;EAEE,OAlSwB;EAoSxB;EAEA,QAjSc;EAkSd,aAlSc;EAoSd;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA;;AAGF;EACE;EACA;EACA;;AAGF;EACE;;AAKJ;EACE;;;AAMN;EAEE;EAEA;EAEA;EACA;EAEA,QAtWyB;EAuWzB;EAEA;EAEA,aA3WyB;EA6WzB;EACA;EAEA,aCxXsB;EDyXtB,WArX4B;EAsX5B;EAEA,OA3X4B;EA4X5B,kBA7X8B;EA+X9B,cA9X4B;EA+X5B;EACA;EACA,eAxXgC;;;AA2XlC;EACE;EACA,kBAtY4B;;;AAyY9B;EACE;;;AGxYF;EAEE;EAEA;EAEA;EACA;EAEA;EAGA;EACA;EACA;EACA;EACA;EAGA;;AAEA;EAEE;EACA;EAEA;EACA;EAEA;EACA;EAEA,aFnCoB;EEoCpB;EACA;EACA;;;AAIJ;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA,aFlDoB;EEmDpB;EACA;EACA;EACA;EACA;;;AAKJ;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA,OHvE4B;;;AG0E9B;EACE;EACA;EACA;EAEA;EACA;EAEA,OAlFmC;EAmFnC,QAnFmC;EAqFnC;EACA;EAEA;;AAEA;EACE;;;AAKJ;EACE;EACA;;;AAGF;EAEE;EAEA;EACA;EACA;EAEA;EACA,QA9GmC;EAgHnC;EACA;EACA;EACA;EACA;;AAEA;EACE,aFxHoB;EEyHpB,WAxHiC;EAyHjC;EACA;;AAGF;EACE;;;AAKJ;EAEE;EAEA;EAEA;EACA;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;;AAGF;EACE;EACA,aF7JoB;EE8JpB;EACA;EACA;;;AAMJ;EAEE;EAEA;EAEA;EACA;EACA;EACA;EAEA;EAEA;EAEA,kBDzKwB;;;AC4K1B;EACE;EACA;EAEA;EACA;EACA;EAEA;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EAEA;EACA;EAEA;EAEA,ODlMkB;ECmMlB;EACA,aFrNoB;EEsNpB;EAEA;EAEA;EACA;EACA,cD3MkB;;;ACgNtB;EAEE;EAEA;EACA;EAEA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EAEA,aFnPsB;EEoPtB;EACA;EAEA;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;EAEA;EAEA;EAEA;;;AAGF;AAAA;AAAA;EAGE,kBClQyB;;;ADyQ3B;EACE;EACA;EACA;;;AErRF;EAEE;EAEA;EAEA;EACA;EACA;EACA;EACA;EAEA;EAEA;EACA;EACA;EAEA;EACA;EACA;EACA;;;AAIF;EACE;EAEA;EACA;;;AAGF;EACE;EACA;EACA;;;ACpCF;EAEE;EAEA;EAEA;EACA;EACA;EAEA;EACA;EACA;EAEA;EACA;EAEA;EAEA,aClBsB;EDmBtB;EAEA;EACA;EACA;;;AAGF;EAEE;EAEA;EACA;EACA;EAEA;EACA;EACA;EAEA;EACA;EAEA;EAEA;EACA;EACA;EAEA;;;AE/CF;EAEE;EACA;EACA;EAEA;EAEA;EACA;EAEA;EAEA;EAEA;EACA;EACA;EAEA,aPpBsB;EOqBtB;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE;EAEA;EACA;EAEA;EAEA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAKJ;EACE;EACA;EAEA;;AAEA;EACE;EACA;EACA;;;ACzCN;EAEE;EACA;EACA;EACA;EACA;EAEA,cPrByB;EOsBzB,eAxC2C;EAyC3C;EACA;EAEA,aR7CsB;EQ8CtB;EACA;EAEA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EAEA,wBAvEyC;EAwEzC,yBAxEyC;EAyEzC,qBPvDuB;EOwDvB;EACA;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA,OPlEqB;;AOqEvB;EACE;EACA;;AAMJ;EAEE,OPjFkB;EOmFlB;EACA;EACA;EAEA;EACA;EACA;EAEA;EAEA;;AAIF;EACE;EAEA;EACA;EAEA,OPvGkB;EOyGlB;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EAEA;EACA;EACA;EAEA;;AArIJ;EACE;EACA;EACA;EAEA;EAEA,aRfoB;EQgBpB;EACA;EACA;EAEA;EAEA;EACA;EACA,cPRa;EOUb;;AAuHA;EACE;EACA;;AAMJ;EACE;EAEA;EACA;EAEA,OP9IkB;EOgJlB;EAEA;EACA;EACA;EACA;EACA;;AA/JF;EACE;EACA;EACA;EAEA;EAEA,aRfoB;EQgBpB;EACA;EACA;EAEA;EAEA;EACA;EACA,cPRa;EOUb;;AAgJA;EACE;;AAMJ;EAEE;EACA,QAjLgB;EAmLhB;EACA;EACA;EACA;EACA;;AAEA;EACE;EAEA;EACA,aRhMkB;EQiMlB;EACA;EAEA,OAhMa;EAiMb,QAlMc;EAoMd,aApMc;EAqMd;EAEA;EACA;EACA;EACA;;AAIF;EACE;EACA;EACA,kBPlNgB;;AOqNlB;EACE;EACA;EACA,kBPrNoB;;AOwNtB;EACE;EACA,kBP5NsB;;AO+NxB;EACE;EACA,kBP9N0B;;AOoO9B;EAEE;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EAEA;EACA;EACA;EACA,aR9PkB;EQ+PlB;EACA;EAEA;EACA;EACA;EACA,eApQuC;EAqQvC;;AAGF;EACE;EACA;;;AC1QN;EAEE;EACA;EACA;EAEA;EAEA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EAEE;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;ACpCN;EACE;EACA;EACA;EAGA;EAEA;EAEA;EAEA,aAjByB;EAkBzB;EACA;EACA,OAlB0B;EAoB1B;EAEA,eAvB6B;EAwB7B,cAtBoB;EAuBpB;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE,2BAjDyB;EAkDzB,4BAlDyB;EAmDzB;EACA;EACA;;AAGF;EACE;;;AAON;EACE;EACA;EACA;EACA;;;AAGF;EAEE;EACA;EACA;EACA;EAEA;EACA,wBA/E6B;EAgF7B,yBAhF6B;EAkF7B,qBAhFoB;EAiFpB;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,OAhGkB;;AAmGpB;EACE;EACA;;;AAKJ;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EAEA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AHxIN;EAEE;EACA;EACA;EAEA;EAEA;EACA;EAEA;EAEA;EAEA;EACA;EACA;EAEA,aPpBsB;EOqBtB;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE;EAEA;EACA;EAEA;EAEA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAKJ;EACE;EACA;EAEA;;AAEA;EACE;EACA;EACA;;;AIpEN;EAEE;EAEA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAIA;EACE;EAEA;EACA;EACA;EAIA;EACA;EAEA;EACA;;;AAKJ;EACE;IAAK;IAAmC;;;AAG1C;EACE;IAAK;IAAmC;;;ACrB1C;EAEE;EACA;EAEA,aAhCkB;EAiClB;EACA;EACA,OAlCmB;EAoCnB;EAEA;EAEA,eArCsB;EAsCtB,cArCa;EAsCb;EACA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE,QA/CyB;EAiDzB;EACA,wBArDoB;EAsDpB,yBAtDoB;EAwDpB,qBAvDW;EAwDX;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,OAvES;;AA0EX;EACE;EACA;;AAMJ;EAGE;EAEA,2BAzE0B;EA0E1B,4BA1E0B;EA2E1B;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;;AAGA;EACE,QApGM;EAqGN;EAEA;EACA;EACA,qBApGiB;;AAuGnB;EACE;;AAGF;EAGE;EACA;EAEA;EAEA;EACA;EACA;;AAGF;EACE;EACA;;;AAQN;EACE;EACA,OAhJ+B;;;AAoJjC;EACE;EACA;EAIA;EACA;EAEA,cAjJqB;EAkJrB,eA7I4B;EA8I5B;EACA;EAEA,aA9IwB;EA+IxB;EACA;EAEA;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","file":"dom.css"}
\ No newline at end of file
+{"version":3,"sourceRoot":"","sources":["_navbar.scss","_font.scss","_color.scss","_dom-misc.scss","_apple_crayon_color.scss","_igv-center-line.scss","_igv-cursor-guide.scss","dom.scss","_igv-user-feedback.scss","_igv-generic-dialog-container.scss","_igv-generic-container.scss","_igv-menu-popup.scss","_spinner.scss","_roi.scss"],"names":[],"mappings":"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;EAqQvC;;AAGF;EACE;EACA;;;AC1QN;EAEE;EACA;EACA;EAEA;EAEA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EAEE;EAEA;EACA;EACA;EACA;EACA;EAEA;EACA;EAEA;;AAEA;EACE;EACA;EACA;EACA;EACA;EACA;EACA;;;ACpCN;EACE;EACA;EACA;EAGA;EAEA;EAEA;EAEA,aAjByB;EAkBzB;EACA;EACA,OAlB0B;EAoB1B;EAEA,eAvB6B;EAwB7B,cAtBoB;EAuBpB;EACA;EAEA;EACA;EACA;EACA;EACA;EAEA;;AAEA;EACE;;AAEA;EACE;;AAGF;EACE;EACA;;AAGF;EACE,2BAjDyB;EAkDzB,4BAlDyB;EAmDzB;EACA;EACA;;AAGF;EACE;;;AAON;EACE;EACA;EACA;EACA;;;AAGF;EAEE;EACA;EACA;EACA;EAEA;EACA,wBA/E6B;EAgF7B,yBAhF6B;EAkF7B,qBAhFoB;EAiFpB;EACA;EAEA;EAEA;EACA;EACA;EACA;EACA;;AAEA;EACE;EACA;EACA;EACA,OAhGkB;;AAmGpB;EACE;EACA;;;AAKJ;EAEE;EACA;EACA;EACA;EACA;EAEA;EACA;EACA;EAEA;;AAEA;EACE;EACA;;AAGF;EACE;EACA;EACA;;AAEA;EACE;EACA;EACA;;;AHxIN;EAEE;EACA;EACA;EAEA;EAEA;EACA;EAEA;EAEA;EAEA;EACA;EACA;EAEA,aPpBsB;EOqBtB;EACA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAGA;EACE;EAEA;EACA;EAEA;EAEA;EACA;EACA;;AAGA;EACE;EACA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;EACA;;AAKJ;EACE;EACA;EAEA;;AAEA;EACE;EACA;EACA;;;AIpEN;EAEE;EAEA;EACA;EACA;EACA;EAEA;EACA;EAEA;EACA;EACA;EACA;EACA;;AAIA;EACE;EAEA;EACA;EACA;EAIA;EACA;EAEA;EACA;;;AAKJ;EACE;IAAK;IAAmC;;;AAG1C;EACE;IAAK;IAAmC;;;ACrB1C;EAEE;EACA;EAEA,aAhCkB;EAiClB;EACA;EACA,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CA;EACA;EACA;;;AAyGF;EAhHE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AA6GF;EApHE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;;;AAiHF;EAxHE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAqHA,OAjK0B;;AAmK1B;EAEE;EAEA,YAzJyB;EA0JzB,OAxKwB;;AA0KxB;EAEE;EAEA;EACA;EACA,MA9KqB;EAgLrB,OA/KsB;EAiLtB,cAnL6B;EAoL7B;EAGA;EAEA;EACA;EAEA;EACA;;AAMF;EACE;;;AAON;EAvKE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAoKA,OA3M4B;EA6M5B;;AAGA;EACE;EACA;EACA;EAEA,YA5MyB;EA6MzB;EAEA;EACA;EACA;EACA;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;;AAGF;EACE;EAEA,YApOyB;EAqOzB;EAEA;EACA;;;AAKJ;EAtNE;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EAmNA,OAxPiC;;AA2PjC;EAEE;EACA;EACA;EACA;EACA;EAEA,YA5PyB;EA6PzB;EACA;;AAGA;EACE;EAEA;EACA;EACA;EACA,OLrQqB;;AKwQvB;EACE;EACA","file":"dom.css"}
+
diff --git a/css/dom.scss b/css/dom.scss
index 9cfc377d5..fd5b0f8c6 100644
--- a/css/dom.scss
+++ b/css/dom.scss
@@ -115,8 +115,32 @@ $igv-zoom-in-notice-height: 16px;
width: $igv-axis-column-width;
>div {
+ position: relative;
+
margin-top: $igv-column-item-margin-top;
width: 100%;
+
+ //background-color: rgba(101, 211, 19, 1);
+
+ >div {
+ z-index: 512;
+ position: absolute;
+ top:8px;
+ left: 8px;
+ width: fit-content;
+ height: fit-content;
+ background-color: transparent;
+ display: grid;
+ align-items: start;
+ justify-items: center;
+ //place-items: flex-start center;
+ >input {
+ display: block;
+ margin: unset;
+ cursor: pointer;
+ }
+ }
+
}
}
@@ -202,13 +226,18 @@ $igv-zoom-in-notice-height: 16px;
border-width: 0;
border-top-right-radius: 6px;
border-bottom-right-radius: 6px;
+ }
+ .igv-track-drag-handle-color {
background-color: #c4c4c4;
}
- .igv-track-drag-handle-hover {
+ .igv-track-drag-handle-hover-color {
background-color: #787878;
- //background-color: magenta;
+ }
+
+ .igv-track-drag-handle-selected-color {
+ background-color: #0963fa;
}
>.igv-track-drag-shim {
diff --git a/dev/misc/multi-select.html b/dev/misc/multi-select.html
new file mode 100644
index 000000000..c7875a22d
--- /dev/null
+++ b/dev/misc/multi-select.html
@@ -0,0 +1,384 @@
+
+
+
+
+
+ Multi Select Dev
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/misc/navbar-buttons.html b/dev/misc/navbar-buttons.html
new file mode 100644
index 000000000..9c67e2780
--- /dev/null
+++ b/dev/misc/navbar-buttons.html
@@ -0,0 +1,143 @@
+
+
+
+
+
+ Navbar Button Dev
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/dev/multi-select/multi-select.html b/dev/multi-select/multi-select.html
new file mode 100644
index 000000000..2b310c67e
--- /dev/null
+++ b/dev/multi-select/multi-select.html
@@ -0,0 +1,311 @@
+
+
+
+
+
+
+
+
+
+
+ Multiple Track Selection
+
+
+
+
+
+Multiple Track Selection
+
+
+
+
+
+
+
+
diff --git a/dev/roi/roi.html b/dev/roi/roi.html
index 55a7efe6e..60eb154a0 100644
--- a/dev/roi/roi.html
+++ b/dev/roi/roi.html
@@ -28,7 +28,6 @@
genome: "hg19",
showROITableButton: true,
- showROITable: true,
// Define two global "region of interest" sets, the first with a bed file, the second with an explicit array
// of regions
diff --git a/dev/sampleInfo/sampleInfo.html b/dev/sampleInfo/sampleInfo.html
index 6674c82f5..9ab9df96a 100644
--- a/dev/sampleInfo/sampleInfo.html
+++ b/dev/sampleInfo/sampleInfo.html
@@ -5,8 +5,7 @@
IGV - Dev
-
+
@@ -15,11 +14,11 @@
-
-
+
+
-
-
+
+
@@ -36,94 +35,44 @@
// locus: 'ace',
// locus: 'all',
showSampleNames: true,
- // showCursorGuide: true,
- tracks:
- [
- {
- name: 'GBM Copy Number',
- // displayMode: "SQUISHED",
- url: 'https://www.dropbox.com/s/4jufc6dbedpk3qz/GBMCopyNumber.seg.gz?dl=0'
- },
- {
- type: 'sampleinfo',
- url: 'https://www.dropbox.com/s/zn8nkd7bhdlg84x/GBMSampleInfo.txt?dl=0'
- }
- ]
- };
+ tracks: [
+ // {
+ // name: 'GBM Copy Number',
+ // url: 'https://www.dropbox.com/s/4jufc6dbedpk3qz/GBMCopyNumber.seg.gz?dl=0'
+ // },
+ // {
+ // type: 'sampleinfo',
+ // url: 'https://www.dropbox.com/s/zn8nkd7bhdlg84x/GBMSampleInfo.txt?dl=0'
+ // }
- const shoebox_sample_name_bug =
- {
- // "version": "2.16.0",
- // "showSampleNames": true,
- // "sampleNameViewportWidth": 6,
- "reference": {
- "id": "hg38",
- "name": "Human (GRCh38/hg38)",
- "fastaURL": "https://igv-genepattern-org.s3.amazonaws.com/genomes/seq/hg38/hg38.fa",
- "indexURL": "https://igv-genepattern-org.s3.amazonaws.com/genomes/seq/hg38/hg38.fa.fai",
- "cytobandURL": "https://s3.amazonaws.com/igv.org.genomes/hg38/annotations/cytoBandIdeo.txt.gz",
- "aliasURL": "https://s3.amazonaws.com/igv.org.genomes/hg38/hg38_alias.tab",
- "chromosomeOrder": "chr1, chr2, chr3, chr4, chr5, chr6, chr7, chr8, chr9, chr10, chr11, chr12, chr13, chr14, chr15, chr16, chr17, chr18, chr19, chr20, chr21, chr22, chrX, chrY"
- },
- "locus": "chr20:56,411,666-56,424,888",
- "roi": [],
- "tracks": [
- {
- "type": "sampleinfo",
- "url": "https://www.dropbox.com/s/oeg6y37mvyfjif3/sampleInfo.txt?dl=0"
- },
- {
- "type": "sequence",
- "order": -9007199254740991
- },
- {
- "url": "https://www.dropbox.com/s/qxpnqfvbiqs0eyz/model1.allChr.f.2.hg38.r10.hic?dl=0",
- "filename": "model1.allChr.f.2.hg38.r10.hic",
- "name": "model1.allChr.f.2.hg38.r10.hic",
- "format": "hic",
- "type": "shoebox",
- "height": 500,
- "visibilityWindow": 1000000,
- "order": 4,
- "maxWGCount": 9007199254740991,
- "displayMode": "EXPANDED"
- },
- {
- "name": "Refseq Genes",
- "format": "refgene",
- "url": "https://hgdownload.soe.ucsc.edu/goldenPath/hg38/database/ncbiRefSeq.txt.gz",
- "indexed": false,
- "removable": false,
- "order": 1000000,
- "infoURL": "https://www.ncbi.nlm.nih.gov/gene/?term=$$",
- "type": "annotation",
- "height": 70
- }
]
};
let browser
(async () => {
browser = await igv.createBrowser(document.getElementById('myDiv'), config)
- console.log(`browser ${browser.guid} is good to go.`)
+ console.log(`browser ${ browser.guid } is good to go.`)
document.getElementById('processFileInput').addEventListener('click', processFile)
document.getElementById('processURLInput').addEventListener('click', processUrl)
document.getElementById('processTrackURLInput').addEventListener('click', processTrackUrl)
})()
async function processFile() {
- const [file] = document.getElementById("fileInput").files
- await browser.loadTrackList([{type: 'sampleinfo', url: file}])
+ const [ file ] = document.getElementById("fileInput").files
+ await browser.loadTrack({ type: 'sampleinfo', url: file })
+ await browser.layoutChange()
}
async function processUrl() {
const url = document.getElementById("urlInput").value
- await browser.loadTrackList([{type: 'sampleinfo', url}])
+ await browser.loadTrack({ type: 'sampleinfo', url })
+ await browser.layoutChange()
}
async function processTrackUrl() {
const url = document.getElementById("trackURLInput").value
- await browser.loadTrackList([{url}])
+ await browser.loadTrack({ url })
+ await browser.layoutChange()
}
diff --git a/dev/ucsc/slowHub.html b/dev/ucsc/slowHub.html
index 0a8aea578..5857a5530 100644
--- a/dev/ucsc/slowHub.html
+++ b/dev/ucsc/slowHub.html
@@ -6,25 +6,6 @@
-
-
- Many chromosomes ~ same size
-
- Many chromosomes - gradually decreasing
- chromosomes
-
- 24 large chromosomes
-
- T2T
-
-
-
- Enter full URL to hub.txt file
-
-
-
-
Load hub as genome
-
Load hub as session
diff --git a/dev/wig/bigWigs.html b/dev/wig/bigWigs.html
index 0e92ae61a..6a372da20 100644
--- a/dev/wig/bigWigs.html
+++ b/dev/wig/bigWigs.html
@@ -23,6 +23,7 @@
{
"url": "https://www.encodeproject.org/files/ENCFF754TJH/@@download/ENCFF754TJH.bigWig",
"name": "Encode bigwig",
+ color: 'rgb(255,0,0)',
"metadata" : {
"Foo": "bar",
"Bar": 999.999
@@ -41,6 +42,7 @@
},
{
"url": "https://s3-us-west-2.amazonaws.com/ilmn.igv-test/test2.bigWig",
+ color: 'rgb(0,0,255)',
"name": "Big BigWig"
},
diff --git a/dev/wig/wigs.html b/dev/wig/wigs.html
index b9323a115..6a6cd97a5 100644
--- a/dev/wig/wigs.html
+++ b/dev/wig/wigs.html
@@ -23,53 +23,55 @@
genome: "hg19",
tracks: [
{
- name: 'All negative points',
- url: '../../test/data/wig/allNegativewig.bedgraph',
- indexed: false,
- graphType: "points",
- guideLines: [
- {dotted: true, y: 0, color: "green"},
- {dotted: true, y: -0.25, color: "blue"},
- {dotted: true, y: -0.5, color: "red"}
- ]
+ name: 'All pos bars',
+ url: '../../test/data/wig/allPositive.bedgraph',
+ // color: '#0f0',
+ indexed: false
},
{
name: 'All negative bars',
url: '../../test/data/wig/allNegativewig.bedgraph',
+ // color: '#f00',
indexed: false
},
- {
- name: 'Mixed_pos_neg_points',
- url: '../../test/data/wig/mixedPosNeg.bedgraph',
- indexed: false,
- graphType: "points",
- guideLines: [
- {dotted: true, y: 0, color: "green"},
- {dotted: true, y: -0.5, color: "blue"},
- {dotted: true, y: 0.5, color: "red"}
- ]
- },
- {
- name: 'Mixed pos neg bars',
- url: '../../test/data/wig/mixedPosNeg.bedgraph',
- indexed: false
- },
- {
- name: 'All pos points',
- url: '../../test/data/wig/allPositive.bedgraph',
- indexed: false,
- graphType: "points",
- guideLines: [
- {dotted: true, y: 0, color: "green"},
- {dotted: true, y: 0.25, color: "blue"},
- {dotted: true, y: 0.5, color: "red"}
- ]
- },
- {
- name: 'All pos bars',
- url: '../../test/data/wig/allPositive.bedgraph',
- indexed: false
- }
+ // {
+ // name: 'All negative points',
+ // url: '../../test/data/wig/allNegativewig.bedgraph',
+ // indexed: false,
+ // graphType: "points",
+ // guideLines: [
+ // {dotted: true, y: 0, color: "green"},
+ // {dotted: true, y: -0.25, color: "blue"},
+ // {dotted: true, y: -0.5, color: "red"}
+ // ]
+ // },
+ // {
+ // name: 'All pos points',
+ // url: '../../test/data/wig/allPositive.bedgraph',
+ // indexed: false,
+ // graphType: "points",
+ // guideLines: [
+ // {dotted: true, y: 0, color: "green"},
+ // {dotted: true, y: 0.25, color: "blue"},
+ // {dotted: true, y: 0.5, color: "red"}
+ // ]
+ // },
+ // {
+ // name: 'Mixed_pos_neg_points',
+ // url: '../../test/data/wig/mixedPosNeg.bedgraph',
+ // indexed: false,
+ // graphType: "points",
+ // guideLines: [
+ // {dotted: true, y: 0, color: "green"},
+ // {dotted: true, y: -0.5, color: "blue"},
+ // {dotted: true, y: 0.5, color: "red"}
+ // ]
+ // },
+ // {
+ // name: 'Mixed pos neg bars',
+ // url: '../../test/data/wig/mixedPosNeg.bedgraph',
+ // indexed: false
+ // },
]
};
diff --git a/js/bam/bamTrack.js b/js/bam/bamTrack.js
index e9a73052e..a9a3daf29 100644
--- a/js/bam/bamTrack.js
+++ b/js/bam/bamTrack.js
@@ -268,11 +268,10 @@ class BAMTrack extends TrackBase {
menuItemList() {
-
// Start with overage track items
let menuItems = []
- menuItems = menuItems.concat(MenuUtils.numericDataMenuItems(this.trackView))
+ menuItems = menuItems.concat(this.numericDataMenuItems())
// Color by items
menuItems.push('
')
@@ -305,30 +304,36 @@ class BAMTrack extends TrackBase {
}
menuItems.push('
')
+
+ function showCoverageHandler() {
+ this.showCoverage = !this.showCoverage
+ adjustTrackHeight()
+ this.trackView.checkContentHeight()
+ this.trackView.repaintViews()
+ }
+
menuItems.push({
object: $(createCheckbox("Show Coverage", this.showCoverage)),
- click: () => {
- this.showCoverage = !this.showCoverage
- adjustTrackHeight()
- this.trackView.checkContentHeight()
- this.trackView.repaintViews()
- }
+ click: showCoverageHandler
})
+
+ function showAlignmentHandler() {
+ this.showAlignments = !this.showAlignments
+ adjustTrackHeight()
+ this.trackView.checkContentHeight()
+ this.trackView.repaintViews()
+ }
+
menuItems.push({
object: $(createCheckbox("Show Alignments", this.showAlignments)),
- click: () => {
- this.showAlignments = !this.showAlignments
- adjustTrackHeight()
- this.trackView.checkContentHeight()
- this.trackView.repaintViews()
- }
+ click: showAlignmentHandler
})
// Show all bases
menuItems.push('
')
menuItems.push({
object: $(createCheckbox("Show all bases", this.showAllBases)),
- click: () => {
+ click: function showAllBasesHandler(){
this.showAllBases = !this.showAllBases
this.config.showAllBases = this.showAllBases
this.trackView.repaintViews()
@@ -339,7 +344,7 @@ class BAMTrack extends TrackBase {
menuItems.push('
')
menuItems.push({
object: $(createCheckbox("Show mismatches", this.showMismatches)),
- click: () => {
+ click: function showMismatchesHandler() {
this.showMismatches = !this.showMismatches
this.config.showMismatches = this.showMismatches
this.trackView.repaintViews()
@@ -349,10 +354,9 @@ class BAMTrack extends TrackBase {
// Insertions
menuItems.push({
object: $(createCheckbox("Show insertions", this.showInsertions)),
- click: () => {
+ click: function showInsertionsHandler() {
this.showInsertions = !this.showInsertions
this.config.showInsertions = this.showInsertions
- const alignmentContainers = this.getCachedAlignmentContainers()
this.trackView.repaintViews()
}
})
@@ -360,7 +364,7 @@ class BAMTrack extends TrackBase {
// Soft clips
menuItems.push({
object: $(createCheckbox("Show soft clips", this.showSoftClips)),
- click: () => {
+ click: function showSoftClipsHandler() {
this.showSoftClips = !this.showSoftClips
this.config.showSoftClips = this.showSoftClips
this.featureSource.setShowSoftClips(this.showSoftClips)
@@ -377,7 +381,7 @@ class BAMTrack extends TrackBase {
menuItems.push('
')
menuItems.push({
object: $(createCheckbox("View as pairs", this.viewAsPairs)),
- click: () => {
+ click: function viewAsPairsHandler() {
this.viewAsPairs = !this.viewAsPairs
this.config.viewAsPairs = this.viewAsPairs
this.featureSource.setViewAsPairs(this.viewAsPairs)
@@ -397,7 +401,7 @@ class BAMTrack extends TrackBase {
if (this.alignmentTrack.hasPairs) {
menuItems.push({
label: 'Add discordant pairs to circular view',
- click: () => {
+ click: function discordantPairsHandler() {
for (let viewport of this.trackView.viewports) {
this.addPairedChordsForViewport(viewport)
}
@@ -407,7 +411,7 @@ class BAMTrack extends TrackBase {
if (this.alignmentTrack.hasSupplemental) {
menuItems.push({
label: 'Add split reads to circular view',
- click: () => {
+ click: function splitReadsHandler() {
for (let viewport of this.trackView.viewports) {
this.addSplitChordsForViewport(viewport)
}
@@ -425,7 +429,7 @@ class BAMTrack extends TrackBase {
menuItems.push({
object: $(createCheckbox("expand", this.alignmentTrack.displayMode === "EXPANDED")),
- click: () => {
+ click: function expandHandler() {
this.alignmentTrack.displayMode = "EXPANDED"
this.config.displayMode = "EXPANDED"
this.trackView.checkContentHeight()
@@ -435,7 +439,7 @@ class BAMTrack extends TrackBase {
menuItems.push({
object: $(createCheckbox("squish", this.alignmentTrack.displayMode === "SQUISHED")),
- click: () => {
+ click: function squishHandler() {
this.alignmentTrack.displayMode = "SQUISHED"
this.config.displayMode = "SQUISHED"
this.trackView.checkContentHeight()
@@ -454,20 +458,27 @@ class BAMTrack extends TrackBase {
* @returns {{init: undefined, name: undefined, click: clickHandler, object: (jQuery|HTMLElement|jQuery.fn.init)}}
*/
colorByCB(menuItem, showCheck) {
+
const $e = $(createCheckbox(menuItem.label, showCheck))
- const clickHandler = (ev) => {
- if (menuItem.key !== 'tag') {
+ if (menuItem.key !== 'tag') {
+
+ function clickHandler() {
if (menuItem.key === this.alignmentTrack.colorBy) {
this.alignmentTrack.colorBy = 'none'
this.config.colorBy = 'none'
- this.trackView.repaintViews()
} else {
this.alignmentTrack.colorBy = menuItem.key
this.config.colorBy = menuItem.key
- this.trackView.repaintViews()
}
- } else {
+ this.trackView.repaintViews()
+ }
+
+ return {name: undefined, object: $e, click: clickHandler, init: undefined}
+ } else {
+
+ function dialogPresentationHandler(ev) {
+
this.browser.inputDialog.present({
label: 'Tag Name',
value: this.alignmentTrack.colorByTag ? this.alignmentTrack.colorByTag : '',
@@ -485,12 +496,12 @@ class BAMTrack extends TrackBase {
this.trackView.repaintViews()
}
}, ev)
-
}
+ return {name: undefined, object: $e, dialog: dialogPresentationHandler, init: undefined}
+
}
- return {name: undefined, object: $e, click: clickHandler, init: undefined}
}
/**
diff --git a/js/blat/blatTrack.js b/js/blat/blatTrack.js
index f18e45b7a..9ca26b8d4 100644
--- a/js/blat/blatTrack.js
+++ b/js/blat/blatTrack.js
@@ -63,10 +63,12 @@ class BlatTrack extends FeatureTrack {
const menuItems = super.menuItemList()
menuItems.push('
')
- menuItems.push({
- label: 'Open table view',
- click: () => this.openTableView()
- })
+
+ function click() {
+ this.openTableView()
+ }
+ menuItems.push({ label: 'Open table view', click })
+
return menuItems
}
diff --git a/js/browser.js b/js/browser.js
index d5428e9d0..cebb14f79 100755
--- a/js/browser.js
+++ b/js/browser.js
@@ -21,19 +21,19 @@ import version from "./version.js"
import FeatureSource from "./feature/featureSource.js"
import {defaultNucleotideColors} from "./util/nucleotideColors.js"
import search from "./search.js"
-import NavbarManager from "./navbarManager.js"
+import {navbarDidResize} from "./responsiveNavbar.js"
import ChromosomeSelectWidget from "./ui/chromosomeSelectWidget.js"
import WindowSizePanel from "./windowSizePanel.js"
import CursorGuide from "./ui/cursorGuide.js"
import CursorGuideButton from "./ui/cursorGuideButton.js"
import CenterLineButton from './ui/centerLineButton.js'
import TrackLabelControl from "./ui/trackLabelControl.js"
-import SampleNameControl from "./ui/sampleNameControl.js"
+import SampleNameControl from "./sample/sampleNameControl.js"
import SampleInfoControl from "./sample/sampleInfoControl.js"
import ZoomWidget from "./ui/zoomWidget.js"
import DataRangeDialog from "./ui/dataRangeDialog.js"
import HtsgetReader from "./htsget/htsgetReader.js"
-import SVGSaveControl from "./ui/svgSaveControl.js"
+import SaveImageControl from "./ui/saveImageControl.js"
import MenuPopup from "./ui/menuPopup.js"
import {viewportColumnManager} from './viewportColumnManager.js'
import ViewportCenterLine from './ui/viewportCenterLine.js'
@@ -47,13 +47,14 @@ import ROIManager from './roi/ROIManager.js'
import ROITable from './roi/ROITable.js'
import ROIMenu from './roi/ROIMenu.js'
import TrackROISet from "./roi/trackROISet.js"
-import ROITableControl from './ui/roiTableControl.js'
+import ROITableControl from './roi/roiTableControl.js'
import SampleInfo from "./sample/sampleInfo.js"
import SampleInfoViewport from "./sample/sampleInfoViewport.js"
import HicFile from "./hic/straw/hicFile.js"
import {translateSession} from "./hic/shoeboxUtils.js"
import Hub from "./ucsc/ucscHub.js"
-
+import MultiTrackSelectButton from "./ui/multiTrackSelectButton.js"
+import MenuUtils from "./ui/menuUtils.js"
// css - $igv-scrollbar-outer-width: 14px;
const igv_scrollbar_outer_width = 14
@@ -99,6 +100,8 @@ class Browser {
this.menuPopup = new MenuPopup(this.columnContainer)
+ this.menuUtils = new MenuUtils(this)
+
this.initialize(config)
this.trackViews = []
@@ -162,19 +165,16 @@ class Browser {
this.nucleotideColors[key.toLowerCase()] = this.nucleotideColors[key]
}
- this.trackLabelsVisible = config.showTrackLabels
+ this.doShowTrackLabels = config.showTrackLabels
- this.roiTableVisible = config.showROITable
- this.showROITableButton = config.showROITableButton
+ this.doShowROITable = config.showROITable
+ this.doShowROITableButton = config.doShowROITableButton
- this.isCenterLineVisible = config.showCenterGuide
+ this.doShowCenterLine = config.showCenterGuide
- this.cursorGuideVisible = config.showCursorGuide
-
- this.showSampleInfoButton = false
+ this.doShowCursorGuide = config.showCursorGuide
this.showSampleNames = config.showSampleNames
- this.showSampleNameButton = config.showSampleNameButton
this.sampleNameViewportWidth = undefined
@@ -211,8 +211,6 @@ class Browser {
createStandardControls(config) {
- this.navbarManager = new NavbarManager(this)
-
const $navBar = $('
', {class: 'igv-navbar'})
this.$navigation = $navBar
@@ -274,6 +272,8 @@ class Browser {
$navbarRightContainer.append($toggle_button_container)
this.$toggle_button_container = $toggle_button_container
+ this.multiTrackSelectButton = new MultiTrackSelectButton(this, $toggle_button_container.get(0))
+
this.cursorGuide = new CursorGuide(this.columnContainer, this)
this.cursorGuideButton = new CursorGuideButton(this, $toggle_button_container.get(0))
@@ -291,7 +291,7 @@ class Browser {
this.sampleNameControl = new SampleNameControl($toggle_button_container.get(0), this)
if (true === config.showSVGButton) {
- this.svgSaveControl = new SVGSaveControl($toggle_button_container.get(0), this)
+ this.saveImageControl = new SaveImageControl($toggle_button_container.get(0), this)
}
if (config.customButtons) {
@@ -809,11 +809,17 @@ class Browser {
const isWGV = (this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr))
- this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV)
+ navbarDidResize(this, this.$navigation.width(), isWGV)
+
+ toggleTrackLabels(this.trackViews, this.doShowTrackLabels)
- toggleTrackLabels(this.trackViews, this.trackLabelsVisible)
+ if (this.doShowCenterLine && GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr)) {
+ this.centerLineButton.boundMouseClickHandler()
+ }
- this.setCenterLineAndCenterLineButtonVisibility(!GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr))
+ if (this.doShowCursorGuide && GenomeUtils.isWholeGenomeView(referenceFrameList[0].chr)) {
+ this.cursorGuideButton.boundMouseClickHandler()
+ }
}
@@ -826,9 +832,9 @@ class Browser {
}
// cursor guide
- setCursorGuideVisibility(cursorGuideVisible) {
+ setCursorGuideVisibility(doShowCursorGuide) {
- if (cursorGuideVisible) {
+ if (doShowCursorGuide) {
this.cursorGuide.show()
} else {
this.cursorGuide.hide()
@@ -840,9 +846,9 @@ class Browser {
}
// center line
- setCenterLineVisibility(isCenterLineVisible) {
+ setCenterLineVisibility(doShowCenterLine) {
for (let centerLine of this.centerLineList) {
- if (true === isCenterLineVisible) {
+ if (true === doShowCenterLine) {
centerLine.show()
centerLine.repaint()
} else {
@@ -851,18 +857,6 @@ class Browser {
}
}
- setCenterLineAndCenterLineButtonVisibility(isCenterLineVisible) {
-
- for (let centerLine of this.centerLineList) {
- const isShown = isCenterLineVisible && centerLine.isVisible
- isShown ? centerLine.show() : centerLine.container.style.display = 'none'
- }
-
- const isShown = isCenterLineVisible && this.centerLineButton.isVisible
- isShown ? this.centerLineButton.show() : this.centerLineButton.button.style.display = 'none'
-
- }
-
/**
* Public API function. Load a list of tracks.
*
@@ -955,7 +949,7 @@ class Browser {
const trackView = new TrackView(this, this.columnContainer, newTrack)
this.trackViews.push(trackView)
- toggleTrackLabels(this.trackViews, this.trackLabelsVisible)
+ toggleTrackLabels(this.trackViews, this.doShowTrackLabels)
if (typeof newTrack.postInit === 'function') {
try {
@@ -1366,7 +1360,7 @@ class Browser {
if (this.referenceFrameList) {
const isWGV = this.isMultiLocusWholeGenomeView() || GenomeUtils.isWholeGenomeView(this.referenceFrameList[0].chr)
- this.navbarManager.navbarDidResize(this.$navigation.width(), isWGV)
+ navbarDidResize(this, this.$navigation.width(), isWGV)
}
resize.call(this)
diff --git a/js/cnvpytor/cnvpytorTrack.js b/js/cnvpytor/cnvpytorTrack.js
index c47faf41f..6c9ded55d 100644
--- a/js/cnvpytor/cnvpytorTrack.js
+++ b/js/cnvpytor/cnvpytorTrack.js
@@ -48,7 +48,7 @@ class CNVPytorTrack extends TrackBase {
super(config, browser)
this.featureType = 'numeric'
this.paintAxis = paintAxis
-
+
if (!config.max) {
this.defaultScale = true
this.autoscale = false
@@ -93,7 +93,7 @@ class CNVPytorTrack extends TrackBase {
}
get_signal_colors() {
-
+
let signal_colors = [
{ singal_name: 'RD_Raw', color: this.colors[0] },
{ singal_name: 'RD_Raw_gc_coor', color: this.colors[1] },
@@ -112,7 +112,6 @@ class CNVPytorTrack extends TrackBase {
this.header = await this.getHeader()
const cnvpytor_obj = new CNVpytorVCF(this.featureSource.reader.features, this.bin_size)
-
let wigFeatures;
let bafFeatures;
this.wigFeatures_obj = {}
@@ -120,9 +119,9 @@ class CNVPytorTrack extends TrackBase {
let dataWigs;
if(this.config.cnv_caller == '2D'){
-
+
dataWigs = await cnvpytor_obj.read_rd_baf('2D')
-
+
wigFeatures = dataWigs[0]
bafFeatures = dataWigs[1]
this.wigFeatures_obj[this.bin_size]['2D'] = wigFeatures[2]
@@ -135,14 +134,14 @@ class CNVPytorTrack extends TrackBase {
this.wigFeatures_obj[this.bin_size]['ReadDepth'] = wigFeatures[2]
this.available_callers = ['ReadDepth']
}
-
+
this.wigFeatures_obj[this.bin_size]['RD_Raw'] = wigFeatures[0]
this.wigFeatures_obj[this.bin_size]['RD_Raw_gc_coor'] = wigFeatures[1]
this.wigFeatures_obj[this.bin_size]['BAF1'] = bafFeatures[0]
this.wigFeatures_obj[this.bin_size]['BAF2'] = bafFeatures[1]
-
+
this.available_bins = [this.bin_size]
-
+
this.set_available_callers()
} else {
@@ -252,14 +251,14 @@ class CNVPytorTrack extends TrackBase {
if (this.flipAxis !== undefined) {
items.push({
label: "Flip y-axis",
- click: () => {
+ click: function flipYAxisHandler() {
this.flipAxis = !this.flipAxis
this.trackView.repaintViews()
}
})
}
- items = items.concat(MenuUtils.numericDataMenuItems(this.trackView))
+ items = items.concat(this.numericDataMenuItems())
items.push('
')
items.push("Bin Sizes")
@@ -267,7 +266,7 @@ class CNVPytorTrack extends TrackBase {
const checkBox = createCheckbox(rd_bin, rd_bin === this.bin_size)
items.push({
object: $(checkBox),
- click: async () => {
+ click: async function binSizesHandler() {
this.bin_size = rd_bin
await this.recreate_tracks(rd_bin)
@@ -285,7 +284,7 @@ class CNVPytorTrack extends TrackBase {
const checkBox = createCheckbox(signal_dct[signal_name], signal_name === this.signal_name)
items.push({
object: $(checkBox),
- click: async () => {
+ click: async function signalTypeHandler() {
this.signal_name = signal_name
await this.recreate_tracks(this.bin_size)
this.clearCachedFeatures()
@@ -303,7 +302,7 @@ class CNVPytorTrack extends TrackBase {
const checkBox = createCheckbox(cnv_caller, cnv_caller === this.cnv_caller)
items.push({
object: $(checkBox),
- click: async () => {
+ click: async function cnvCallerHandler() {
this.cnv_caller = cnv_caller
await this.recreate_tracks(this.bin_size)
this.clearCachedFeatures()
@@ -336,7 +335,7 @@ class CNVPytorTrack extends TrackBase {
tconf.isMergedTrack = true
tconf.features = wig
tconf.name = signal_name
- tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color)
+ tconf.color = this.signal_colors.filter(x => x.singal_name === signal_name).map(x => x.color)
const t = await this.browser.createTrack(tconf)
if (t) {
t.autoscale = false // Scaling done from merged track
diff --git a/js/embedCss.js b/js/embedCss.js
index 90ef9f10f..c3b99b990 100644
--- a/js/embedCss.js
+++ b/js/embedCss.js
@@ -1,6 +1,8 @@
function embedCSS() {
- var css = '.igv-navbar {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n color: #444;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n line-height: 32px;\n padding-left: 8px;\n padding-right: 8px;\n margin-top: 2px;\n margin-bottom: 6px;\n height: 32px;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: #f3f3f3;\n}\n.igv-navbar .igv-navbar-left-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-left-container .igv-logo {\n width: 34px;\n height: 32px;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\n height: 32px;\n margin-left: 4px;\n margin-right: 4px;\n user-select: none;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n height: 100%;\n width: 125px;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n display: block;\n cursor: pointer;\n width: 100px;\n height: 75%;\n outline: none;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n margin-left: 8px;\n height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 240px;\n height: 22px;\n line-height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n cursor: text;\n width: 85%;\n height: 22px;\n line-height: 22px;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n text-align: left;\n padding-left: 8px;\n margin-right: 8px;\n outline: none;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: white;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n cursor: pointer;\n height: 16px;\n width: 16px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n margin-left: 4px;\n user-select: none;\n}\n.igv-navbar .igv-navbar-right-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div {\n margin-left: 0;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container div:last-child {\n margin-left: 0;\n margin-right: 0;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-750 {\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n display: block;\n height: fit-content;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n display: block;\n width: 125px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n height: 24px;\n width: 24px;\n margin-left: unset;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n height: 24px;\n width: 24px;\n margin-left: 8px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n display: none;\n}\n\n.igv-navbar-button {\n display: block;\n box-sizing: unset;\n padding-left: 6px;\n padding-right: 6px;\n height: 18px;\n text-transform: capitalize;\n user-select: none;\n line-height: 18px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 11px;\n font-weight: 200;\n color: #737373;\n background-color: #f3f3f3;\n border-color: #737373;\n border-style: solid;\n border-width: thin;\n border-radius: 6px;\n}\n\n.igv-navbar-button-clicked {\n color: white;\n background-color: #737373;\n}\n\n.igv-navbar-button:hover {\n cursor: pointer;\n}\n\n.igv-zoom-in-notice-container {\n z-index: 1024;\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translate(-50%, 0%);\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n background-color: white;\n}\n.igv-zoom-in-notice-container > div {\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n width: 100%;\n height: 100%;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: #3f3f3f;\n}\n\n.igv-zoom-in-notice {\n position: absolute;\n top: 10px;\n left: 50%;\n}\n.igv-zoom-in-notice div {\n position: relative;\n left: -50%;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #3f3f3f;\n background-color: rgba(255, 255, 255, 0.51);\n z-index: 64;\n}\n\n.igv-container-spinner {\n position: absolute;\n top: 90%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1024;\n width: 24px;\n height: 24px;\n pointer-events: none;\n color: #737373;\n}\n\n.igv-multi-locus-close-button {\n position: absolute;\n top: 2px;\n right: 0;\n padding-left: 2px;\n padding-right: 2px;\n width: 12px;\n height: 12px;\n color: #666666;\n background-color: white;\n z-index: 1000;\n}\n.igv-multi-locus-close-button > svg {\n vertical-align: top;\n}\n\n.igv-multi-locus-close-button:hover {\n cursor: pointer;\n color: #434343;\n}\n\n.igv-multi-locus-ruler-label {\n z-index: 64;\n position: absolute;\n top: 2px;\n left: 0;\n width: 100%;\n height: 12px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-multi-locus-ruler-label > div {\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n.igv-multi-locus-ruler-label > div {\n cursor: pointer;\n}\n\n.igv-multi-locus-ruler-label-square-dot {\n z-index: 64;\n position: absolute;\n left: 50%;\n top: 5%;\n transform: translate(-50%, 0%);\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\n width: 14px;\n height: 14px;\n}\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\n margin-left: 16px;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n}\n\n.igv-ruler-sweeper {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 26px;\n bottom: 0;\n left: 0;\n width: 0;\n z-index: 99999;\n background-color: rgba(68, 134, 247, 0.25);\n}\n\n.igv-ruler-tooltip {\n pointer-events: none;\n z-index: 128;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 32px;\n background-color: transparent;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ruler-tooltip > div {\n pointer-events: none;\n width: 128px;\n height: auto;\n padding: 1px;\n color: #373737;\n font-size: 10px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n background-color: white;\n border-style: solid;\n border-width: thin;\n border-color: #373737;\n}\n\n.igv-track-label {\n position: absolute;\n left: 8px;\n top: 8px;\n width: auto;\n height: auto;\n max-width: 50%;\n padding-left: 4px;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n text-align: center;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-color: #444;\n border-radius: 2px;\n border-style: solid;\n border-width: thin;\n background-color: white;\n z-index: 128;\n cursor: pointer;\n}\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n background-color: #e8e8e8;\n}\n\n.igv-track-label-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-top: 4px;\n}\n\n.igv-center-line {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n z-index: 8;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-left-style: dashed;\n border-left-width: thin;\n border-right-style: dashed;\n border-right-width: thin;\n}\n\n.igv-center-line-wide {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(127, 127, 127, 0.51);\n}\n\n.igv-center-line-thin {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(0, 0, 0, 0);\n}\n\n.igv-cursor-guide-horizontal {\n display: none;\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 50%;\n height: 1px;\n z-index: 1;\n margin-left: 50px;\n margin-right: 54px;\n border-top-style: dotted;\n border-top-width: thin;\n border-top-color: rgba(127, 127, 127, 0.76);\n}\n\n.igv-cursor-guide-vertical {\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n width: 1px;\n z-index: 1;\n border-left-style: dotted;\n border-left-width: thin;\n border-left-color: rgba(127, 127, 127, 0.76);\n display: none;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-generic-dialog-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-generic-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-generic-container div:first-child i {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-menu-popup {\n position: absolute;\n top: 0;\n left: 0;\n width: max-content;\n z-index: 4096;\n cursor: pointer;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background: white;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-end;\n text-align: left;\n}\n.igv-menu-popup > div:not(:first-child) {\n width: 100%;\n}\n.igv-menu-popup > div:not(:first-child) > div {\n background: white;\n}\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\n padding-left: 4px;\n padding-right: 4px;\n}\n.igv-menu-popup > div:not(:first-child) > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-menu-popup > div:not(:first-child) > div:hover {\n background: #efefef;\n}\n\n.igv-menu-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-bottom: 1px;\n padding-top: 1px;\n}\n\n.igv-menu-popup-header {\n position: relative;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-menu-popup-header div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-menu-popup-header div:hover {\n cursor: pointer;\n color: #444;\n}\n\n.igv-menu-popup-check-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 20px;\n margin-right: 4px;\n background-color: transparent;\n}\n.igv-menu-popup-check-container div {\n padding-top: 2px;\n padding-left: 8px;\n}\n.igv-menu-popup-check-container div:first-child {\n position: relative;\n width: 12px;\n height: 12px;\n}\n.igv-menu-popup-check-container div:first-child svg {\n position: absolute;\n width: 12px;\n height: 12px;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-loading-spinner-container {\n z-index: 1024;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-loading-spinner-container > div {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 4px solid rgba(128, 128, 128, 0.5);\n border-top-color: rgb(255, 255, 255);\n animation: spin 1s ease-in-out infinite;\n -webkit-animation: spin 1s ease-in-out infinite;\n}\n\n@keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.igv-roi-menu-next-gen {\n position: absolute;\n z-index: 512;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background-color: white;\n width: 192px;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu-next-gen > div:first-child {\n height: 24px;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-roi-menu-next-gen > div:first-child > div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-roi-menu-next-gen > div:first-child > div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-menu-next-gen > div:last-child {\n background-color: white;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n text-align: start;\n vertical-align: middle;\n}\n.igv-roi-menu-next-gen > div:last-child > div {\n height: 24px;\n padding-left: 4px;\n border-bottom-style: solid;\n border-bottom-width: thin;\n border-bottom-color: #7f7f7f;\n}\n.igv-roi-menu-next-gen > div:last-child > div:not(:first-child):hover {\n background-color: rgba(127, 127, 127, 0.1);\n}\n.igv-roi-menu-next-gen > div:last-child div:first-child {\n font-style: italic;\n text-align: center;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-menu-next-gen > div:last-child > div:last-child {\n border-bottom-width: 0;\n border-bottom-color: transparent;\n}\n\n.igv-roi-placeholder {\n font-style: normal;\n color: rgba(75, 75, 75, 0.6);\n}\n\n.igv-roi-table {\n position: absolute;\n z-index: 1024;\n width: min-content;\n max-width: 1600px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n cursor: default;\n}\n.igv-roi-table > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table > div:first-child > div:first-child {\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n margin-left: 4px;\n margin-right: 4px;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table > .igv-roi-table-description {\n padding: 4px;\n margin-left: 4px;\n word-break: break-all;\n overflow-y: auto;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-goto-explainer {\n margin-top: 5px;\n margin-left: 4px;\n color: #7F7F7F;\n font-style: italic;\n height: 24px;\n border-top: solid lightgray;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: #7f7f7f;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n overflow: auto;\n resize: both;\n max-width: 1600px;\n height: 360px;\n background-color: transparent;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: transparent;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n cursor: pointer;\n height: 20px;\n user-select: none;\n line-height: 20px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 13px;\n font-weight: 400;\n color: black;\n padding-left: 6px;\n padding-right: 6px;\n background-color: rgb(239, 239, 239);\n border-color: black;\n border-style: solid;\n border-width: thin;\n border-radius: 3px;\n}\n\n.igv-roi-table-button:hover {\n font-weight: 400;\n background-color: rgba(0, 0, 0, 0.13);\n}\n\n.igv-roi-region {\n z-index: 64;\n position: absolute;\n top: 0;\n bottom: 0;\n pointer-events: none;\n overflow: visible;\n margin-top: 44px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-region > div {\n position: relative;\n width: 100%;\n height: 8px;\n pointer-events: auto;\n}\n\n.igv-roi-menu {\n position: absolute;\n z-index: 1024;\n width: 144px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu > div:not(:last-child) {\n border-bottom-color: rgba(128, 128, 128, 0.5);\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-menu > div:first-child {\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-color: transparent;\n border-top-style: solid;\n border-top-width: 0;\n}\n.igv-roi-menu > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n}\n\n.igv-roi-menu-row {\n height: 24px;\n padding-left: 8px;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n background-color: white;\n}\n\n.igv-roi-menu-row-edit-description {\n width: -webkit-fill-available;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-menu-row-edit-description > label {\n margin-left: 2px;\n margin-bottom: 0;\n display: block;\n width: -webkit-fill-available;\n}\n.igv-roi-menu-row-edit-description > input {\n display: block;\n margin-left: 2px;\n margin-right: 2px;\n margin-bottom: 1px;\n width: -webkit-fill-available;\n}\n\n.igv-container {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 4px;\n user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n min-height: 160px;\n}\n\n.igv-viewport {\n position: relative;\n margin-top: 5px;\n line-height: 1;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.igv-viewport-content {\n position: relative;\n width: 100%;\n}\n.igv-viewport-content > canvas {\n position: relative;\n display: block;\n}\n\n.igv-column-container {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n width: 100%;\n}\n\n.igv-column-shim {\n width: 1px;\n margin-left: 2px;\n margin-right: 2px;\n background-color: #545453;\n}\n\n.igv-axis-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 50px;\n}\n.igv-axis-column > div {\n margin-top: 5px;\n width: 100%;\n}\n\n.igv-column {\n position: relative;\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-sample-info-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-sample-name-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-scrollbar-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 14px;\n}\n.igv-scrollbar-column > div {\n position: relative;\n margin-top: 5px;\n width: 14px;\n}\n.igv-scrollbar-column > div > div {\n cursor: pointer;\n position: absolute;\n top: 0;\n left: 2px;\n width: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: #c4c4c4;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.igv-scrollbar-column > div > div:hover {\n background-color: #c4c4c4;\n}\n\n.igv-track-drag-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 12px;\n background-color: white;\n}\n.igv-track-drag-column > .igv-track-drag-handle {\n z-index: 512;\n position: relative;\n cursor: pointer;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n background-color: #c4c4c4;\n}\n.igv-track-drag-column .igv-track-drag-handle-hover {\n background-color: #787878;\n}\n.igv-track-drag-column > .igv-track-drag-shim {\n position: relative;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n}\n\n.igv-gear-menu-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 28px;\n}\n.igv-gear-menu-column > div {\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n margin-top: 5px;\n width: 100%;\n background: white;\n}\n.igv-gear-menu-column > div > div {\n position: relative;\n margin-top: 4px;\n width: 16px;\n height: 16px;\n color: #7F7F7F;\n}\n.igv-gear-menu-column > div > div:hover {\n cursor: pointer;\n color: #444;\n}\n\n/*# sourceMappingURL=dom.css.map */\n'
+
+ var css = '.igv-navbar {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n box-sizing: border-box;\n width: 100%;\n color: #444;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n line-height: 32px;\n padding-left: 8px;\n padding-right: 8px;\n margin-top: 2px;\n margin-bottom: 6px;\n height: 32px;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: #f3f3f3;\n}\n.igv-navbar .igv-navbar-left-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 32px;\n line-height: 32px;\n}\n.igv-navbar .igv-navbar-left-container .igv-logo {\n width: 34px;\n height: 32px;\n margin-right: 8px;\n}\n.igv-navbar .igv-navbar-left-container .igv-current-genome {\n height: 32px;\n margin-left: 4px;\n margin-right: 4px;\n user-select: none;\n line-height: 32px;\n vertical-align: middle;\n text-align: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container {\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n height: 100%;\n width: 125px;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-chromosome-select-widget-container select {\n display: block;\n cursor: pointer;\n width: 100px;\n height: 75%;\n outline: none;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n margin-left: 8px;\n height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 240px;\n height: 22px;\n line-height: 22px;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container input.igv-search-input {\n cursor: text;\n width: 85%;\n height: 22px;\n line-height: 22px;\n font-size: 12px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n text-align: left;\n padding-left: 8px;\n margin-right: 8px;\n outline: none;\n border-style: solid;\n border-radius: 3px;\n border-width: thin;\n border-color: #bfbfbf;\n background-color: white;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-search-container .igv-search-icon-container {\n cursor: pointer;\n height: 16px;\n width: 16px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-navbar .igv-navbar-left-container .igv-navbar-genomic-location .igv-locus-size-group .igv-windowsize-panel-container {\n margin-left: 4px;\n user-select: none;\n}\n.igv-navbar .igv-navbar-right-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-navbar-toggle-button-container-hidden {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n height: 100%;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget {\n color: #737373;\n font-size: 18px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:first-child {\n height: 20px;\n width: 20px;\n margin-left: unset;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:last-child {\n height: 20px;\n width: 20px;\n margin-left: 4px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget div:nth-child(even) {\n display: block;\n height: fit-content;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget input {\n display: block;\n width: 125px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 {\n color: #737373;\n font-size: 18px;\n height: 32px;\n line-height: 32px;\n margin-left: 8px;\n user-select: none;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div {\n cursor: pointer;\n margin-left: unset;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:first-child {\n height: 20px;\n width: 20px;\n margin-left: unset;\n margin-right: 4px;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:last-child {\n height: 20px;\n width: 20px;\n margin-left: 4px;\n margin-right: unset;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 div:nth-child(even) {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 input {\n width: 0;\n height: 0;\n display: none;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-900 svg {\n display: block;\n}\n.igv-navbar .igv-navbar-right-container .igv-zoom-widget-hidden {\n display: none;\n}\n\n.igv-navbar-button {\n display: block;\n box-sizing: unset;\n padding-left: 6px;\n padding-right: 6px;\n height: 18px;\n text-transform: capitalize;\n user-select: none;\n line-height: 18px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 11px;\n font-weight: 200;\n color: #737373;\n background-color: #f3f3f3;\n border-color: #737373;\n border-style: solid;\n border-width: thin;\n border-radius: 6px;\n}\n\n.igv-navbar-button:hover {\n cursor: pointer;\n}\n\n.igv-navbar-button-clicked {\n color: white;\n background-color: #737373;\n}\n\n.igv-navbar-icon-button {\n cursor: pointer;\n position: relative;\n width: 24px;\n height: 24px;\n margin-left: 4px;\n margin-right: 4px;\n border: none;\n background-size: contain;\n background-repeat: no-repeat;\n background-position: center;\n}\n.igv-navbar-icon-button > div:first-child {\n z-index: 512;\n position: absolute;\n top: 36px;\n left: -18px;\n width: 24px;\n height: 24px;\n border: none;\n background-size: contain;\n background-repeat: no-repeat;\n background-position: center;\n}\n.igv-navbar-icon-button > div:last-child {\n z-index: 512;\n position: absolute;\n top: 36px;\n left: 18px;\n width: 24px;\n height: 24px;\n border: none;\n background-size: contain;\n background-repeat: no-repeat;\n background-position: center;\n}\n\n.igv-navbar-text-button {\n cursor: pointer;\n position: relative;\n margin-left: 2px;\n margin-right: 2px;\n border: none;\n display: flex;\n justify-content: center;\n align-items: center;\n}\n.igv-navbar-text-button > div:nth-child(2) {\n z-index: 512;\n position: absolute;\n top: 36px;\n left: 0;\n width: 38px;\n height: 18px;\n border: none;\n background-size: contain;\n background-repeat: no-repeat;\n background-position: center;\n}\n.igv-navbar-text-button > div:nth-child(3) {\n z-index: 512;\n position: absolute;\n top: 36px;\n left: 42px;\n width: 38px;\n height: 18px;\n border: none;\n background-size: contain;\n background-repeat: no-repeat;\n background-position: center;\n}\n\n#igv-text-button-label {\n text-anchor: middle;\n dominant-baseline: middle;\n}\n\n.igv-navbar-text-button-svg-inactive rect {\n stroke: #737373;\n fill: white;\n}\n.igv-navbar-text-button-svg-inactive text {\n fill: #737373;\n}\n\n.igv-navbar-text-button-svg-hover rect {\n stroke: #737373;\n fill: #737373;\n}\n.igv-navbar-text-button-svg-hover text {\n fill: white;\n}\n\n#igv-save-svg-group rect {\n stroke: #737373;\n fill: white;\n}\n#igv-save-svg-group text {\n fill: #737373;\n}\n\n#igv-save-svg-group:hover rect {\n stroke: #737373;\n fill: #737373;\n}\n#igv-save-svg-group:hover text {\n fill: white;\n}\n\n#igv-save-png-group rect {\n stroke: #737373;\n fill: white;\n}\n#igv-save-png-group text {\n fill: #737373;\n}\n\n#igv-save-png-group:hover rect {\n stroke: #737373;\n fill: #737373;\n}\n#igv-save-png-group:hover text {\n fill: white;\n}\n\n.igv-zoom-in-notice-container {\n z-index: 1024;\n position: absolute;\n top: 8px;\n left: 50%;\n transform: translate(-50%, 0%);\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n background-color: white;\n}\n.igv-zoom-in-notice-container > div {\n padding-left: 4px;\n padding-right: 4px;\n padding-top: 2px;\n padding-bottom: 2px;\n width: 100%;\n height: 100%;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: #3f3f3f;\n}\n\n.igv-zoom-in-notice {\n position: absolute;\n top: 10px;\n left: 50%;\n}\n.igv-zoom-in-notice div {\n position: relative;\n left: -50%;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #3f3f3f;\n background-color: rgba(255, 255, 255, 0.51);\n z-index: 64;\n}\n\n.igv-container-spinner {\n position: absolute;\n top: 90%;\n left: 50%;\n transform: translate(-50%, -50%);\n z-index: 1024;\n width: 24px;\n height: 24px;\n pointer-events: none;\n color: #737373;\n}\n\n.igv-multi-locus-close-button {\n position: absolute;\n top: 2px;\n right: 0;\n padding-left: 2px;\n padding-right: 2px;\n width: 12px;\n height: 12px;\n color: #666666;\n background-color: white;\n z-index: 1000;\n}\n.igv-multi-locus-close-button > svg {\n vertical-align: top;\n}\n\n.igv-multi-locus-close-button:hover {\n cursor: pointer;\n color: #434343;\n}\n\n.igv-multi-locus-ruler-label {\n z-index: 64;\n position: absolute;\n top: 2px;\n left: 0;\n width: 100%;\n height: 12px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-multi-locus-ruler-label > div {\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n color: rgb(16, 16, 16);\n background-color: white;\n}\n.igv-multi-locus-ruler-label > div {\n cursor: pointer;\n}\n\n.igv-multi-locus-ruler-label-square-dot {\n z-index: 64;\n position: absolute;\n left: 50%;\n top: 5%;\n transform: translate(-50%, 0%);\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-multi-locus-ruler-label-square-dot > div:first-child {\n width: 14px;\n height: 14px;\n}\n.igv-multi-locus-ruler-label-square-dot > div:last-child {\n margin-left: 16px;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n color: rgb(16, 16, 16);\n}\n\n.igv-ruler-sweeper {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 26px;\n bottom: 0;\n left: 0;\n width: 0;\n z-index: 99999;\n background-color: rgba(68, 134, 247, 0.25);\n}\n\n.igv-ruler-tooltip {\n pointer-events: none;\n z-index: 128;\n position: absolute;\n top: 0;\n left: 0;\n width: 1px;\n height: 32px;\n background-color: transparent;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-ruler-tooltip > div {\n pointer-events: none;\n width: 128px;\n height: auto;\n padding: 1px;\n color: #373737;\n font-size: 10px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n background-color: white;\n border-style: solid;\n border-width: thin;\n border-color: #373737;\n}\n\n.igv-track-label {\n position: absolute;\n left: 8px;\n top: 8px;\n width: auto;\n height: auto;\n max-width: 50%;\n padding-left: 4px;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n text-align: center;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-color: #444;\n border-radius: 2px;\n border-style: solid;\n border-width: thin;\n background-color: white;\n z-index: 128;\n cursor: pointer;\n}\n\n.igv-track-label:hover,\n.igv-track-label:focus,\n.igv-track-label:active {\n background-color: #e8e8e8;\n}\n\n.igv-track-label-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-top: 4px;\n}\n\n.igv-center-line {\n display: none;\n pointer-events: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n transform: translateX(-50%);\n z-index: 8;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n border-left-style: dashed;\n border-left-width: thin;\n border-right-style: dashed;\n border-right-width: thin;\n}\n\n.igv-center-line-wide {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(127, 127, 127, 0.51);\n}\n\n.igv-center-line-thin {\n background-color: rgba(0, 0, 0, 0);\n border-left-color: rgba(127, 127, 127, 0.51);\n border-right-color: rgba(0, 0, 0, 0);\n}\n\n.igv-cursor-guide-horizontal {\n display: none;\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n left: 0;\n right: 0;\n top: 50%;\n height: 1px;\n z-index: 1;\n margin-left: 50px;\n margin-right: 54px;\n border-top-style: dotted;\n border-top-width: thin;\n border-top-color: rgba(127, 127, 127, 0.76);\n}\n\n.igv-cursor-guide-vertical {\n pointer-events: none;\n user-select: none;\n -moz-user-select: none;\n -webkit-user-select: none;\n position: absolute;\n top: 0;\n bottom: 0;\n left: 50%;\n width: 1px;\n z-index: 1;\n border-left-style: dotted;\n border-left-width: thin;\n border-left-color: rgba(127, 127, 127, 0.76);\n display: none;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-generic-dialog-container {\n position: absolute;\n top: 0;\n left: 0;\n width: 300px;\n height: 200px;\n border-color: #7F7F7F;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n z-index: 2048;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-generic-dialog-container .igv-generic-dialog-header div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-generic-dialog-container .igv-generic-dialog-one-liner {\n color: #373737;\n width: 95%;\n height: 24px;\n line-height: 24px;\n text-align: left;\n margin-top: 8px;\n padding-left: 8px;\n overflow-wrap: break-word;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input {\n margin-top: 8px;\n width: 95%;\n height: 24px;\n color: #373737;\n line-height: 24px;\n padding-left: 8px;\n background-color: white;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input div {\n width: 30%;\n height: 100%;\n font-size: 16px;\n text-align: right;\n padding-right: 8px;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-label-input input {\n width: 50%;\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input {\n margin-top: 8px;\n width: calc(100% - 16px);\n height: 24px;\n color: #373737;\n line-height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n display: block;\n height: 100%;\n width: 100%;\n padding-left: 4px;\n font-family: \"Open Sans\", sans-serif;\n font-weight: 400;\n color: #373737;\n text-align: left;\n outline: none;\n border-style: solid;\n border-width: thin;\n border-color: #7F7F7F;\n background-color: white;\n}\n.igv-generic-dialog-container .igv-generic-dialog-input input {\n font-size: 16px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel {\n width: 100%;\n height: 28px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div {\n margin-top: 32px;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: 14px;\n font-weight: 400;\n width: 75px;\n height: 28px;\n line-height: 28px;\n text-align: center;\n border-color: transparent;\n border-style: solid;\n border-width: thin;\n border-radius: 2px;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child {\n margin-left: 32px;\n margin-right: 0;\n background-color: #5ea4e0;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child {\n margin-left: 0;\n margin-right: 32px;\n background-color: #c4c4c4;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:first-child:hover {\n cursor: pointer;\n background-color: #3b5c7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok-cancel div:last-child:hover {\n cursor: pointer;\n background-color: #7f7f7f;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok {\n width: 100%;\n height: 36px;\n margin-top: 32px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div {\n width: 98px;\n height: 36px;\n line-height: 36px;\n text-align: center;\n color: white;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n border-color: white;\n border-style: solid;\n border-width: thin;\n border-radius: 4px;\n background-color: #2B81AF;\n}\n.igv-generic-dialog-container .igv-generic-dialog-ok div:hover {\n cursor: pointer;\n background-color: #25597f;\n}\n\n.igv-generic-container {\n position: absolute;\n top: 0;\n left: 0;\n z-index: 2048;\n background-color: white;\n cursor: pointer;\n display: flex;\n flex-direction: row;\n flex-wrap: wrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-generic-container div:first-child {\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n height: 24px;\n width: 100%;\n background-color: #dddddd;\n}\n.igv-generic-container div:first-child i {\n display: block;\n color: #5f5f5f;\n cursor: pointer;\n width: 14px;\n height: 14px;\n margin-right: 8px;\n margin-bottom: 4px;\n}\n\n.igv-menu-popup {\n position: absolute;\n top: 0;\n left: 0;\n width: max-content;\n z-index: 4096;\n cursor: pointer;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background: white;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-end;\n text-align: left;\n}\n.igv-menu-popup > div:not(:first-child) {\n width: 100%;\n}\n.igv-menu-popup > div:not(:first-child) > div {\n background: white;\n}\n.igv-menu-popup > div:not(:first-child) > div.context-menu {\n padding-left: 4px;\n padding-right: 4px;\n}\n.igv-menu-popup > div:not(:first-child) > div:last-child {\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-menu-popup > div:not(:first-child) > div:hover {\n background: #efefef;\n}\n\n.igv-menu-popup-shim {\n padding-left: 8px;\n padding-right: 8px;\n padding-bottom: 1px;\n padding-top: 1px;\n}\n\n.igv-menu-popup-header {\n position: relative;\n width: 100%;\n height: 24px;\n cursor: move;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-menu-popup-header div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-menu-popup-header div:hover {\n cursor: pointer;\n color: #444;\n}\n\n.igv-menu-popup-check-container {\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n width: 100%;\n height: 20px;\n margin-right: 4px;\n background-color: transparent;\n}\n.igv-menu-popup-check-container div {\n padding-top: 2px;\n padding-left: 8px;\n}\n.igv-menu-popup-check-container div:first-child {\n position: relative;\n width: 12px;\n height: 12px;\n}\n.igv-menu-popup-check-container div:first-child svg {\n position: absolute;\n width: 12px;\n height: 12px;\n}\n\n.igv-user-feedback {\n position: fixed;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 512px;\n height: 360px;\n z-index: 2048;\n background-color: white;\n border-color: #a2a2a2;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: medium;\n font-weight: 400;\n color: #444;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n}\n.igv-user-feedback div:first-child {\n position: relative;\n height: 24px;\n width: 100%;\n background-color: white;\n border-bottom-color: #a2a2a2;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-user-feedback div:first-child div {\n position: absolute;\n top: 2px;\n width: 16px;\n height: 16px;\n background-color: transparent;\n}\n.igv-user-feedback div:first-child div:first-child {\n left: 8px;\n}\n.igv-user-feedback div:first-child div:last-child {\n cursor: pointer;\n right: 8px;\n}\n.igv-user-feedback div:last-child {\n width: 100%;\n height: calc(100% - 24px);\n border-width: 0;\n}\n.igv-user-feedback div:last-child div {\n width: auto;\n height: auto;\n margin: 8px;\n}\n\n.igv-loading-spinner-container {\n z-index: 1024;\n position: absolute;\n top: 50%;\n left: 50%;\n transform: translate(-50%, -50%);\n width: 32px;\n height: 32px;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: center;\n align-items: center;\n}\n.igv-loading-spinner-container > div {\n box-sizing: border-box;\n width: 100%;\n height: 100%;\n border-radius: 50%;\n border: 4px solid rgba(128, 128, 128, 0.5);\n border-top-color: rgb(255, 255, 255);\n animation: spin 1s ease-in-out infinite;\n -webkit-animation: spin 1s ease-in-out infinite;\n}\n\n@keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n@-webkit-keyframes spin {\n to {\n -webkit-transform: rotate(360deg);\n transform: rotate(360deg);\n }\n}\n.igv-roi-menu {\n position: absolute;\n z-index: 512;\n font-family: \"Open Sans\", sans-serif;\n font-size: small;\n font-weight: 400;\n color: #4b4b4b;\n background-color: white;\n width: 192px;\n border-radius: 4px;\n border-color: #7F7F7F;\n border-style: solid;\n border-width: thin;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-menu > div:first-child {\n height: 24px;\n border-top-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-color: #7F7F7F;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: flex-end;\n align-items: center;\n}\n.igv-roi-menu > div:first-child > div {\n margin-right: 4px;\n height: 12px;\n width: 12px;\n color: #7F7F7F;\n}\n.igv-roi-menu > div:first-child > div:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-menu > div:last-child {\n background-color: white;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-color: transparent;\n border-bottom-style: solid;\n border-bottom-width: 0;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n text-align: start;\n vertical-align: middle;\n}\n.igv-roi-menu > div:last-child > div {\n height: 24px;\n padding-left: 4px;\n border-bottom-style: solid;\n border-bottom-width: thin;\n border-bottom-color: #7f7f7f;\n}\n.igv-roi-menu > div:last-child > div:not(:first-child):hover {\n cursor: pointer;\n background-color: rgba(127, 127, 127, 0.1);\n}\n.igv-roi-menu > div:last-child div:first-child {\n font-style: italic;\n text-align: center;\n padding-right: 4px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n}\n.igv-roi-menu > div:last-child > div:last-child {\n border-bottom-width: 0;\n border-bottom-color: transparent;\n}\n\n.igv-roi-placeholder {\n font-style: normal;\n color: rgba(75, 75, 75, 0.6);\n}\n\n.igv-roi-table {\n position: absolute;\n z-index: 1024;\n width: min-content;\n max-width: 1600px;\n border-color: #7f7f7f;\n border-radius: 4px;\n border-style: solid;\n border-width: thin;\n font-family: \"Open Sans\", sans-serif;\n font-size: 12px;\n font-weight: 400;\n background-color: white;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n cursor: default;\n}\n.igv-roi-table > div {\n height: 24px;\n font-size: 14px;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n}\n.igv-roi-table > div:first-child {\n border-color: transparent;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-top-width: 0;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n background-color: #eee;\n cursor: move;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-between;\n align-items: center;\n}\n.igv-roi-table > div:first-child > div:first-child {\n text-align: center;\n white-space: nowrap;\n text-overflow: ellipsis;\n overflow: hidden;\n margin-left: 4px;\n margin-right: 4px;\n width: calc(100% - 4px - 12px);\n}\n.igv-roi-table > div:first-child > div:last-child {\n margin-right: 4px;\n margin-bottom: 2px;\n height: 12px;\n width: 12px;\n color: #7f7f7f;\n}\n.igv-roi-table > div:first-child > div:last-child > svg {\n display: block;\n}\n.igv-roi-table > div:first-child > div:last-child:hover {\n cursor: pointer;\n color: #444;\n}\n.igv-roi-table > .igv-roi-table-description {\n padding: 4px;\n margin-left: 4px;\n word-break: break-all;\n overflow-y: auto;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-goto-explainer {\n margin-top: 5px;\n margin-left: 4px;\n color: #7F7F7F;\n font-style: italic;\n height: 24px;\n border-top: solid lightgray;\n background-color: transparent;\n}\n.igv-roi-table > .igv-roi-table-column-titles {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n padding-right: 16px;\n background-color: white;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: #7f7f7f;\n border-bottom-style: solid;\n border-bottom-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: #7f7f7f;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-column-titles > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container {\n overflow: auto;\n resize: both;\n max-width: 1600px;\n height: 360px;\n background-color: transparent;\n display: flex;\n flex-flow: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row {\n height: 24px;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div {\n font-size: 14px;\n vertical-align: middle;\n line-height: 24px;\n text-align: left;\n margin-left: 4px;\n height: 24px;\n white-space: nowrap;\n overflow: hidden;\n text-overflow: ellipsis;\n border-right-color: transparent;\n border-right-style: solid;\n border-right-width: thin;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row > div:last-child {\n border-right: unset;\n}\n.igv-roi-table > .igv-roi-table-row-container > .igv-roi-table-row-hover {\n background-color: rgba(0, 0, 0, 0.04);\n}\n.igv-roi-table > div:last-child {\n height: 32px;\n line-height: 32px;\n border-top-color: #7f7f7f;\n border-top-style: solid;\n border-top-width: thin;\n border-bottom-color: transparent;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n border-bottom-width: 0;\n background-color: #eee;\n display: flex;\n flex-flow: row;\n flex-wrap: nowrap;\n justify-content: space-around;\n align-items: center;\n}\n\n.igv-roi-table-row-selected {\n background-color: rgba(0, 0, 0, 0.125);\n}\n\n.igv-roi-table-button {\n cursor: pointer;\n height: 20px;\n user-select: none;\n line-height: 20px;\n text-align: center;\n vertical-align: middle;\n font-family: \"Open Sans\", sans-serif;\n font-size: 13px;\n font-weight: 400;\n color: black;\n padding-left: 6px;\n padding-right: 6px;\n background-color: rgb(239, 239, 239);\n border-color: black;\n border-style: solid;\n border-width: thin;\n border-radius: 3px;\n}\n\n.igv-roi-table-button:hover {\n font-weight: 400;\n background-color: rgba(0, 0, 0, 0.13);\n}\n\n.igv-roi-region {\n z-index: 64;\n position: absolute;\n top: 0;\n bottom: 0;\n pointer-events: none;\n overflow: visible;\n margin-top: 44px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n}\n.igv-roi-region > div {\n position: relative;\n width: 100%;\n height: 8px;\n pointer-events: auto;\n}\n\n.igv-roi-menu-row {\n height: 24px;\n padding-left: 8px;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n line-height: 24px;\n background-color: white;\n}\n\n.igv-roi-menu-row-edit-description {\n width: -webkit-fill-available;\n font-size: small;\n text-align: start;\n vertical-align: middle;\n background-color: white;\n padding-left: 4px;\n padding-right: 4px;\n padding-bottom: 4px;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: stretch;\n align-items: stretch;\n}\n.igv-roi-menu-row-edit-description > label {\n margin-left: 2px;\n margin-bottom: 0;\n display: block;\n width: -webkit-fill-available;\n}\n.igv-roi-menu-row-edit-description > input {\n display: block;\n margin-left: 2px;\n margin-right: 2px;\n margin-bottom: 1px;\n width: -webkit-fill-available;\n}\n\n.igv-container {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n padding-top: 4px;\n user-select: none;\n -webkit-user-select: none;\n -ms-user-select: none;\n min-height: 160px;\n}\n\n.igv-viewport {\n position: relative;\n margin-top: 5px;\n line-height: 1;\n overflow-x: hidden;\n overflow-y: hidden;\n}\n\n.igv-viewport-content {\n position: relative;\n width: 100%;\n}\n.igv-viewport-content > canvas {\n position: relative;\n display: block;\n}\n\n.igv-column-container {\n position: relative;\n display: flex;\n flex-direction: row;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: stretch;\n width: 100%;\n}\n\n.igv-column-shim {\n width: 1px;\n margin-left: 2px;\n margin-right: 2px;\n background-color: #545453;\n}\n\n.igv-axis-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 50px;\n}\n.igv-axis-column > div {\n position: relative;\n margin-top: 5px;\n width: 100%;\n}\n.igv-axis-column > div > div {\n z-index: 512;\n position: absolute;\n top: 8px;\n left: 8px;\n width: fit-content;\n height: fit-content;\n background-color: transparent;\n display: grid;\n align-items: start;\n justify-items: center;\n}\n.igv-axis-column > div > div > input {\n display: block;\n margin: unset;\n cursor: pointer;\n}\n\n.igv-column {\n position: relative;\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-sample-info-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-sample-name-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n}\n\n.igv-scrollbar-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 14px;\n}\n.igv-scrollbar-column > div {\n position: relative;\n margin-top: 5px;\n width: 14px;\n}\n.igv-scrollbar-column > div > div {\n cursor: pointer;\n position: absolute;\n top: 0;\n left: 2px;\n width: 8px;\n border-width: 1px;\n border-style: solid;\n border-color: #c4c4c4;\n border-top-left-radius: 4px;\n border-top-right-radius: 4px;\n border-bottom-left-radius: 4px;\n border-bottom-right-radius: 4px;\n}\n.igv-scrollbar-column > div > div:hover {\n background-color: #c4c4c4;\n}\n\n.igv-track-drag-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 12px;\n background-color: white;\n}\n.igv-track-drag-column > .igv-track-drag-handle {\n z-index: 512;\n position: relative;\n cursor: pointer;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n border-top-right-radius: 6px;\n border-bottom-right-radius: 6px;\n}\n.igv-track-drag-column .igv-track-drag-handle-color {\n background-color: #c4c4c4;\n}\n.igv-track-drag-column .igv-track-drag-handle-hover-color {\n background-color: #787878;\n}\n.igv-track-drag-column .igv-track-drag-handle-selected-color {\n background-color: #0963fa;\n}\n.igv-track-drag-column > .igv-track-drag-shim {\n position: relative;\n margin-top: 5px;\n width: 100%;\n border-style: solid;\n border-width: 0;\n}\n\n.igv-gear-menu-column {\n position: relative;\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: flex-start;\n box-sizing: border-box;\n height: 100%;\n width: 28px;\n}\n.igv-gear-menu-column > div {\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n justify-content: flex-start;\n align-items: center;\n margin-top: 5px;\n width: 100%;\n background: white;\n}\n.igv-gear-menu-column > div > div {\n position: relative;\n margin-top: 4px;\n width: 16px;\n height: 16px;\n color: #7F7F7F;\n}\n.igv-gear-menu-column > div > div:hover {\n cursor: pointer;\n color: #444;\n}\n\n/*# sourceMappingURL=dom.css.map */\n'
+
var style = document.createElement('style')
style.setAttribute('type', 'text/css')
diff --git a/js/feature/featureTrack.js b/js/feature/featureTrack.js
index 09a5f1e3e..030de0189 100755
--- a/js/feature/featureTrack.js
+++ b/js/feature/featureTrack.js
@@ -333,36 +333,40 @@ class FeatureTrack extends TrackBase {
if (this.render === renderSnp) {
menuItems.push('
')
- for (let colorScheme of ["function", "class"]) {
- menuItems.push({
- object: $(createCheckbox('Color by ' + colorScheme, colorScheme === this.colorBy)),
- click: () => {
- this.colorBy = colorScheme
- this.trackView.repaintViews()
- }
- })
+
+ for (const colorScheme of ["function", "class"]) {
+
+ const object = $(createCheckbox(`Color by ${ colorScheme }`, colorScheme === this.colorBy))
+
+ function colorSchemeHandler() {
+ this.colorBy = colorScheme
+ this.trackView.repaintViews()
+ }
+ menuItems.push({ object, click:colorSchemeHandler })
}
}
menuItems.push('
')
- for (let displayMode of ["COLLAPSED", "SQUISHED", "EXPANDED"]) {
- const lut =
- {
- "COLLAPSED": "Collapse",
- "SQUISHED": "Squish",
- "EXPANDED": "Expand"
- }
- menuItems.push(
- {
- object: $(createCheckbox(lut[displayMode], displayMode === this.displayMode)),
- click: () => {
- this.displayMode = displayMode
- this.config.displayMode = displayMode
- this.trackView.checkContentHeight()
- this.trackView.repaintViews()
- }
- })
+ const lut =
+ {
+ "COLLAPSED": "Collapse",
+ "SQUISHED": "Squish",
+ "EXPANDED": "Expand"
+ };
+
+ for (const displayMode of ["COLLAPSED", "SQUISHED", "EXPANDED"]) {
+
+ const object = $(createCheckbox(lut[displayMode], displayMode === this.displayMode))
+
+ function displayModeHandler() {
+ this.displayMode = displayMode
+ this.config.displayMode = displayMode
+ this.trackView.checkContentHeight()
+ this.trackView.repaintViews()
+ }
+
+ menuItems.push({ object, click:displayModeHandler })
}
return menuItems
diff --git a/js/feature/interactionTrack.js b/js/feature/interactionTrack.js
index c20f283af..bd09615ab 100644
--- a/js/feature/interactionTrack.js
+++ b/js/feature/interactionTrack.js
@@ -483,7 +483,7 @@ class InteractionTrack extends TrackBase {
items.push(
{
object: $(createCheckbox(lut[arcType], arcType === this.arcType)),
- click: () => {
+ click: function arcTypeHandler() {
this.arcType = arcType
this.trackView.repaintViews()
}
@@ -494,14 +494,14 @@ class InteractionTrack extends TrackBase {
items.push({
name: "Toggle arc direction",
- click: () => {
+ click: function toggleArcDirectionHandler() {
this.arcOrientation = !this.arcOrientation
this.trackView.repaintViews()
}
})
items.push({
name: this.showBlocks ? "Hide Blocks" : "Show Blocks",
- click: () => {
+ click: function blockVisibiltyHandler() {
this.showBlocks = !this.showBlocks
this.trackView.repaintViews()
}
@@ -509,15 +509,14 @@ class InteractionTrack extends TrackBase {
if (this.arcType === "proportional" || this.arcType === "inView" || this.arcType === "partialInView") {
- // MenuUtils.numericDataMenuItems(this.trackView).forEach(item => items.push(item))
- items = items.concat(MenuUtils.numericDataMenuItems(this.trackView))
+ items = items.concat(this.numericDataMenuItems())
}
if (this.browser.circularView) {
items.push('
')
items.push({
label: 'Add interactions to circular view',
- click: () => {
+ click: function addInteractionsHandler() {
for (let viewport of this.trackView.viewports) {
this.addChordsForViewport(viewport.referenceFrame)
}
diff --git a/js/feature/mergedTrack.js b/js/feature/mergedTrack.js
index 5393f2e28..ca4f180d8 100644
--- a/js/feature/mergedTrack.js
+++ b/js/feature/mergedTrack.js
@@ -26,7 +26,6 @@
import TrackBase from "../trackBase.js"
import paintAxis from "../util/paintAxis.js"
-import MenuUtils from "../ui/menuUtils.js"
import {FeatureUtils} from "../../node_modules/igv-utils/src/index.js"
@@ -70,6 +69,7 @@ class MergedTrack extends TrackBase {
}
}
+ this.alpha = this.config.alpha || 0.5
this.flipAxis = this.config.flipAxis ? this.config.flipAxis : false
this.logScale = this.config.logScale ? this.config.logScale : false
this.autoscale = this.config.autoscale || this.config.max === undefined
@@ -106,18 +106,18 @@ class MergedTrack extends TrackBase {
}
menuItemList() {
- let items = []
+ const items = []
if (this.flipAxis !== undefined) {
items.push({
label: "Flip y-axis",
- click: () => {
+ click: function flipYAxisHandler(){
this.flipAxis = !this.flipAxis
this.trackView.repaintViews()
}
})
}
- items = items.concat(MenuUtils.numericDataMenuItems(this.trackView))
+ items.push(...this.numericDataMenuItems())
return items
}
@@ -139,6 +139,9 @@ class MergedTrack extends TrackBase {
for (let i = 0, len = this.tracks.length; i < len; i++) {
const trackOptions = Object.assign({}, options)
trackOptions.features = mergedFeatures.featureArrays[i]
+
+ trackOptions.alpha = this.alpha
+
this.tracks[i].dataRange = this.dataRange
this.tracks[i].flipAxis = this.flipAxis
this.tracks[i].logScale = this.logScale
diff --git a/js/feature/segTrack.js b/js/feature/segTrack.js
index a552cd925..143f17f18 100755
--- a/js/feature/segTrack.js
+++ b/js/feature/segTrack.js
@@ -106,7 +106,17 @@ class SegTrack extends TrackBase {
menuItems.push('
')
menuItems.push("Sort by attribute:")
for (const attribute of this.browser.sampleInfo.getAttributeNames()) {
- menuItems.push(sortByAttribute(this.trackView, attribute))
+
+ const object = $('
')
+ object.html(` ${ attribute.split(emptySpaceReplacement).join(' ') }`)
+
+ function attributeSort() {
+ this.sampleKeys = this.browser.sampleInfo.getSortedSampleKeysByAttribute(this.sampleKeys, attribute, this.trackView.sampleInfoViewport.sortDirection)
+ this.trackView.repaintViews()
+ this.trackView.sampleInfoViewport.sortDirection *= -1
+ }
+
+ menuItems.push({ object, click:attributeSort })
}
}
@@ -119,23 +129,22 @@ class SegTrack extends TrackBase {
if (this.type === 'shoebox' && this.sbColorScale) {
menuItems.push('
')
- menuItems.push({
- object: $('
Set color scale threshold
'),
- click: e => {
- this.browser.inputDialog.present({
- label: 'Color Scale Threshold',
- value: this.sbColorScale.threshold,
- callback: () => {
- const t = Number(this.browser.inputDialog.value, 10)
- if(t) {
- this.sbColorScale.setThreshold(t)
- this.trackView.repaintViews()
- }
+
+ function dialogPresentationHandler(e) {
+ this.browser.inputDialog.present({
+ label: 'Color Scale Threshold',
+ value: this.sbColorScale.threshold,
+ callback: () => {
+ const t = Number(this.browser.inputDialog.value, 10)
+ if(t) {
+ this.sbColorScale.setThreshold(t)
+ this.trackView.repaintViews()
}
- }, e)
- }
+ }
+ }, e)
+ }
- })
+ menuItems.push({ object: $('
Set color scale threshold
'), dialog: dialogPresentationHandler })
}
menuItems.push('
')
@@ -146,7 +155,7 @@ class SegTrack extends TrackBase {
menuItems.push(
{
object: $(checkBox),
- click: () => {
+ click: function displayModeHandler() {
this.displayMode = displayMode
this.config.displayMode = displayMode
this.trackView.checkContentHeight()
@@ -532,32 +541,16 @@ function sortBySampleName(trackView) {
const object = $('
')
object.text('Sort by sample names')
- const click = () => {
+ function sampleNameSort () {
trackView.track.sampleKeys.sort((a, b) => trackView.sampleNameViewport.sortDirection * a.localeCompare(b))
trackView.repaintViews()
trackView.sampleNameViewport.sortDirection *= -1
}
- return { object, click }
+ return { object, click:sampleNameSort }
}
-function sortByAttribute(trackView, attribute) {
-
- const object = $('
')
- object.html(` ${ attribute.split(emptySpaceReplacement).join(' ') }`)
-
- const click = () => {
- trackView.track.sampleKeys = trackView.browser.sampleInfo.getSortedSampleKeysByAttribute(trackView.track.sampleKeys, attribute, trackView.sampleInfoViewport.sortDirection)
- trackView.repaintViews()
- trackView.sampleInfoViewport.sortDirection *= -1
- }
-
- return { object, click }
-
-}
-
-
// Default copy number scales
const POS_COLOR_SCALE = {low: 0.1, lowR: 255, lowG: 255, lowB: 255, high: 1.5, highR: 255, highG: 0, highB: 0}
const NEG_COLOR_SCALE = {low: -1.5, lowR: 0, lowG: 0, lowB: 255, high: -0.1, highR: 255, highG: 255, highB: 255}
diff --git a/js/feature/wigTrack.js b/js/feature/wigTrack.js
index b7cb685fc..22796641a 100755
--- a/js/feature/wigTrack.js
+++ b/js/feature/wigTrack.js
@@ -5,7 +5,6 @@ import BWSource from "../bigwig/bwSource.js"
import IGVGraphics from "../igv-canvas.js"
import paintAxis from "../util/paintAxis.js"
import {IGVColor, StringUtils} from "../../node_modules/igv-utils/src/index.js"
-import MenuUtils from "../ui/menuUtils.js"
import summarizeWigData from "../bigwig/summarizeWigData.js"
const DEFAULT_COLOR = 'rgb(150, 150, 150)'
@@ -104,20 +103,20 @@ class WigTrack extends TrackBase {
}
menuItemList() {
- let items = []
+ const items = []
if (this.flipAxis !== undefined) {
items.push('
')
- items.push({
- label: "Flip y-axis",
- click: () => {
- this.flipAxis = !this.flipAxis
- this.trackView.repaintViews()
- }
- })
+
+ function click() {
+ this.flipAxis = !this.flipAxis
+ this.trackView.repaintViews()
+ }
+
+ items.push({ label: 'Flip y-axis', click })
}
- items = items.concat(MenuUtils.numericDataMenuItems(this.trackView))
+ items.push(...this.numericDataMenuItems())
return items
}
@@ -196,10 +195,10 @@ class WigTrack extends TrackBase {
const rectEnd = Math.ceil((f.end - bpStart) / bpPerPixel)
const width = Math.max(1, rectEnd - x)
- const color = this.getColorForFeature(f)
+ const color = options.alpha ? IGVColor.addAlpha(this.getColorForFeature(f), options.alpha) : this.getColorForFeature(f)
if (this.graphType === "line") {
- if (lastY != undefined) {
+ if (lastY !== undefined) {
IGVGraphics.strokeLine(ctx, lastPixelEnd, lastY, x, y, {
"fillStyle": color,
"strokeStyle": color
@@ -330,5 +329,4 @@ class WigTrack extends TrackBase {
}
-
export default WigTrack
diff --git a/js/gcnv/gcnvTrack.js b/js/gcnv/gcnvTrack.js
index 7518afd9c..ca9138c98 100755
--- a/js/gcnv/gcnvTrack.js
+++ b/js/gcnv/gcnvTrack.js
@@ -76,7 +76,7 @@ class GCNVTrack extends TrackBase {
}
menuItemList() {
- return MenuUtils.numericDataMenuItems(this.trackView)
+ return this.numericDataMenuItems()
}
async getFeatures(chr, start, end) {
diff --git a/js/gtex/eqtlTrack.js b/js/gtex/eqtlTrack.js
index cbd388fed..c4fcac2c2 100755
--- a/js/gtex/eqtlTrack.js
+++ b/js/gtex/eqtlTrack.js
@@ -235,7 +235,7 @@ class EqtlTrack extends TrackBase {
}
menuItemList() {
- return MenuUtils.numericDataMenuItems(this.trackView)
+ return this.numericDataMenuItems()
}
doAutoscale(featureList) {
diff --git a/js/gwas/gwasTrack.js b/js/gwas/gwasTrack.js
index e8b00786a..716e52f0d 100644
--- a/js/gwas/gwasTrack.js
+++ b/js/gwas/gwasTrack.js
@@ -245,7 +245,7 @@ class GWASTrack extends TrackBase {
}
menuItemList() {
- return MenuUtils.numericDataMenuItems(this.trackView)
+ return this.numericDataMenuItems()
}
doAutoscale(featureList) {
diff --git a/js/igv-create.js b/js/igv-create.js
index 1643bb224..2ec4d058b 100644
--- a/js/igv-create.js
+++ b/js/igv-create.js
@@ -26,6 +26,7 @@
import {GoogleAuth, igvxhr} from '../node_modules/igv-utils/src/index.js'
import Browser from "./browser.js"
import GenomeUtils from "./genome/genomeUtils.js"
+import {navbarDidResize} from "./responsiveNavbar.js"
let allBrowsers = []
@@ -68,6 +69,7 @@ async function createBrowser(parentDiv, config) {
const browser = new Browser(config, parentDiv)
allBrowsers.push(browser)
+
// Lod initial sessio
browser.startSpinner()
@@ -81,10 +83,8 @@ async function createBrowser(parentDiv, config) {
}
browser.stopSpinner()
-
navbarDidResize(browser, browser.$navigation.width())
-
return browser
}
@@ -143,8 +143,8 @@ function setDefaults(config) {
config.showTrackLabels = true
}
- if (undefined === config.showROITableButton) {
- config.showROITableButton = false
+ if (undefined === config.doShowROITableButton) {
+ config.doShowROITableButton = false
}
if (undefined === config.showROITable) {
@@ -155,7 +155,6 @@ function setDefaults(config) {
config.showCursorTrackingGuideButton = true
}
-
if (undefined === config.showCursorGuide) {
config.showCursorGuide = config.showCursorTrackingGuide || false // showCursorTrackingGuide is a synonym
}
diff --git a/js/navbarManager.js b/js/navbarManager.js
deleted file mode 100644
index 1af567427..000000000
--- a/js/navbarManager.js
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2014 Broad Institute
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-import $ from "./vendor/jquery-3.3.1.slim.js"
-import GenomeUtils from "./genome/genomeUtils.js"
-
-class NavbarManager {
-
- constructor(browser) {
- this.browser = browser
- }
-
- navbarDidResize(width) {
- this.updateNavbar(this.createResponsiveClassSchedule(width))
- }
-
- updateNavbar(responsiveClassSchedule) {
-
- this.browser.$toggle_button_container.removeClass()
- this.browser.$toggle_button_container.addClass(responsiveClassSchedule.$toggle_button_container)
-
- $(this.browser.zoomWidget.zoomContainer).removeClass()
- $(this.browser.zoomWidget.zoomContainer).addClass(responsiveClassSchedule.zoomContainer)
- }
-
- createResponsiveClassSchedule(navbarWidth) {
-
- let candidates = {}
-
- const isWGV = this.browser.isMultiLocusWholeGenomeView() ||
- (this.browser.referenceFrameList &&
- GenomeUtils.isWholeGenomeView(this.browser.referenceFrameList[0].chr))
-
-
- if (isWGV) {
- this.browser.windowSizePanel.hide()
- } else {
- this.browser.windowSizePanel.show()
- }
-
- if (navbarWidth > 990) {
- candidates.$toggle_button_container = 'igv-navbar-toggle-button-container'
- candidates.zoomContainer = 'igv-zoom-widget'
- } else if (navbarWidth > 860) {
- candidates.$toggle_button_container = 'igv-navbar-toggle-button-container'
- candidates.zoomContainer = 'igv-zoom-widget-900'
- } else if (navbarWidth > 540) {
- candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750'
- candidates.zoomContainer = 'igv-zoom-widget-900'
- } else {
- candidates.$toggle_button_container = 'igv-navbar-toggle-button-container-750'
- candidates.zoomContainer = 'igv-zoom-widget-900'
- this.browser.windowSizePanel.hide()
- }
-
- if (isWGV) {
- candidates['zoomContainer'] = 'igv-zoom-widget-hidden'
- }
-
- return candidates
- }
-}
-
-export default NavbarManager
diff --git a/js/responsiveNavbar.js b/js/responsiveNavbar.js
new file mode 100644
index 000000000..27d32994c
--- /dev/null
+++ b/js/responsiveNavbar.js
@@ -0,0 +1,89 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2014 Broad Institute
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+import $ from "./vendor/jquery-3.3.1.slim.js"
+import {StringUtils} from "../node_modules/igv-utils/src/index.js"
+import GenomeUtils from "./genome/genomeUtils.js"
+import NavbarButton from "./ui/navbarButton.js"
+
+const navbarResponsiveClasses = {}
+
+const responsiveThreshold = 8
+let textButtonContainerWidth = undefined
+
+function navbarDidResize(browser, width) {
+
+ const currentClass = NavbarButton.currentNavbarButtonClass(browser)
+ if ('igv-navbar-text-button' === currentClass) {
+ textButtonContainerWidth = browser.$navigation.get(0).querySelector('.igv-navbar-right-container').getBoundingClientRect().width
+ }
+
+ const responsiveClasses = getResponsiveClasses(browser, width)
+
+ $(browser.zoomWidget.zoomContainer).removeClass()
+ $(browser.zoomWidget.zoomContainer).addClass(responsiveClasses.zoomContainer)
+
+ browser.fireEvent('navbar-resize', [ responsiveClasses.navbarButton ])
+}
+
+function getResponsiveClasses(browser, navbarWidth) {
+
+ const isWGV =
+ (browser.isMultiLocusWholeGenomeView()) ||
+ (browser.referenceFrameList && GenomeUtils.isWholeGenomeView(browser.referenceFrameList[0].chr))
+
+ isWGV ? browser.windowSizePanel.hide() : browser.windowSizePanel.show()
+
+ const { x: leftContainerX, width: leftContainerWidth } = browser.$navigation.get(0).querySelector('.igv-navbar-left-container').getBoundingClientRect()
+ const leftContainerExtent = leftContainerX + leftContainerWidth
+ const { x:rightContainerX} = browser.$navigation.get(0).querySelector('.igv-navbar-right-container').getBoundingClientRect()
+
+ const delta = rightContainerX - leftContainerExtent
+
+ const currentClass = NavbarButton.currentNavbarButtonClass(browser)
+
+ // console.log(`Current class ${ currentClass } Delta: ${ StringUtils.numberFormatter(Math.floor(delta))}`)
+
+ if ('igv-navbar-text-button' === currentClass && delta < responsiveThreshold) {
+ navbarResponsiveClasses.navbarButton = 'igv-navbar-icon-button'
+ } else if (textButtonContainerWidth && 'igv-navbar-icon-button' === currentClass) {
+ const length = navbarWidth - leftContainerExtent
+ if (length - textButtonContainerWidth > responsiveThreshold) {
+ navbarResponsiveClasses.navbarButton = 'igv-navbar-text-button'
+ }
+
+ }
+
+
+ if (isWGV) {
+ navbarResponsiveClasses.zoomContainer = 'igv-zoom-widget-hidden'
+ } else {
+ navbarResponsiveClasses.zoomContainer = navbarWidth > 860 ? 'igv-zoom-widget' : 'igv-zoom-widget-900'
+ }
+
+ return navbarResponsiveClasses
+}
+
+export { navbarDidResize, navbarResponsiveClasses }
diff --git a/js/rna/rnaStruct.js b/js/rna/rnaStruct.js
index ac254405e..250900888 100644
--- a/js/rna/rnaStruct.js
+++ b/js/rna/rnaStruct.js
@@ -211,15 +211,12 @@ class RnaStructTrack extends TrackBase {
}
menuItemList() {
-
- var self = this
-
return [
{
name: "Toggle arc direction",
- click: function () {
- self.arcOrientation = !self.arcOrientation
- self.trackView.repaintViews()
+ click: function toggleArcDirectionHandler() {
+ this.arcOrientation = !this.arcOrientation
+ this.trackView.repaintViews()
}
}
]
@@ -342,4 +339,4 @@ class RNAFeatureSource {
}
}
-export default RnaStructTrack
\ No newline at end of file
+export default RnaStructTrack
diff --git a/js/roi/ROIManager.js b/js/roi/ROIManager.js
index c2e6c1e10..03ccd28ea 100644
--- a/js/roi/ROIManager.js
+++ b/js/roi/ROIManager.js
@@ -19,8 +19,8 @@ class ROIManager {
async initialize() {
if (this.roiSets.length > 0) {
- this.browser.showROITableButton = true
- this.browser.roiTableControl.setVisibility(this.browser.showROITableButton)
+ this.browser.doShowROITableButton = true
+ this.browser.roiTableControl.setVisibility(this.browser.doShowROITableButton)
}
const promises = this.roiSets.map(roiSet => this.renderROISet({
@@ -107,7 +107,7 @@ class ROIManager {
userDefinedROISet.addFeature(feature)
- if (false === this.browser.showROITableButton) {
+ if (false === this.browser.doShowROITableButton) {
this.setROITableButtonVisibility(true)
}
@@ -118,8 +118,8 @@ class ROIManager {
}
setROITableButtonVisibility(isVisible) {
- this.browser.showROITableButton = isVisible
- this.browser.roiTableControl.setVisibility(this.browser.showROITableButton)
+ this.browser.doShowROITableButton = isVisible
+ this.browser.roiTableControl.setVisibility(this.browser.doShowROITableButton)
}
async renderAllROISets() {
diff --git a/js/roi/ROIMenu.js b/js/roi/ROIMenu.js
index 2b620dbe9..030d14fde 100644
--- a/js/roi/ROIMenu.js
+++ b/js/roi/ROIMenu.js
@@ -6,7 +6,7 @@ class ROIMenu {
this.browser = browser
// container
- this.container = DOMUtils.div({ class: 'igv-roi-menu-next-gen' })
+ this.container = DOMUtils.div({ class: 'igv-roi-menu' })
parent.appendChild(this.container)
// header
diff --git a/js/ui/svgSaveControl.js b/js/roi/roiTableControl.js
similarity index 52%
rename from js/ui/svgSaveControl.js
rename to js/roi/roiTableControl.js
index bb10a9c0e..93360fb25 100644
--- a/js/ui/svgSaveControl.js
+++ b/js/roi/roiTableControl.js
@@ -24,14 +24,40 @@
* THE SOFTWARE.
*/
-import {DOMUtils} from '../../node_modules/igv-ui/dist/igv-ui.js'
+import NavbarButton from "../ui/navbarButton.js"
+import {roiImage, roiImageHover} from "../ui/navbarIcons/roi.js"
+import { buttonLabel } from "../ui/navbarIcons/buttonLabel.js"
-const SVGSaveControl = function (parent, browser) {
- const button = DOMUtils.div({class: 'igv-navbar-button'})
- parent.append(button)
+class ROITableControl extends NavbarButton {
- button.textContent = 'Save SVG'
- button.addEventListener('click', () => browser.saveSVGtoFile({}))
+ constructor(parent, browser) {
+
+ super(browser, parent, 'ROI', buttonLabel, roiImage, roiImageHover, browser.doShowROITable)
+
+ this.button.addEventListener('mouseenter', () => {
+ if (false === browser.doShowROITable) {
+ this.setState(true)
+ }
+ })
+
+ this.button.addEventListener('mouseleave', () => {
+ if (false === browser.doShowROITable) {
+ this.setState(false)
+ }
+ })
+
+ this.button.addEventListener('click', () => this.buttonHandler(!browser.doShowROITable))
+
+ this.setVisibility(browser.doShowROITableButton)
+
+ }
+
+ buttonHandler(status) {
+ this.browser.doShowROITable = status
+ this.setState(this.browser.doShowROITable)
+ this.browser.setROITableVisibility(this.browser.doShowROITable)
+ }
}
-export default SVGSaveControl
+
+export default ROITableControl
diff --git a/js/rulerViewport.js b/js/rulerViewport.js
index 1ac007879..750bf209c 100644
--- a/js/rulerViewport.js
+++ b/js/rulerViewport.js
@@ -147,7 +147,7 @@ class RulerViewport extends TrackViewport {
mouseMove(event) {
- if (true === this.browser.cursorGuideVisible) {
+ if (true === this.browser.doShowCursorGuide) {
if (undefined === currentViewport) {
currentViewport = this
diff --git a/js/sample/sampleInfoControl.js b/js/sample/sampleInfoControl.js
index 4345f79ca..f26879d5f 100644
--- a/js/sample/sampleInfoControl.js
+++ b/js/sample/sampleInfoControl.js
@@ -24,23 +24,39 @@
* THE SOFTWARE.
*/
-import {DOMUtils} from "../../node_modules/igv-ui/dist/igv-ui.js"
+import NavbarButton from "../ui/navbarButton.js"
+import {sampleInfoImage, sampleInfoImageHover} from "../ui/navbarIcons/sampleInfo.js"
+import { buttonLabel } from "../ui/navbarIcons/buttonLabel.js"
-class SampleInfoControl {
+class SampleInfoControl extends NavbarButton {
constructor(parent, browser) {
- this.button = DOMUtils.div({class: 'igv-navbar-button'})
- parent.appendChild(this.button)
+ super(browser, parent, 'Sample Info', buttonLabel, sampleInfoImage, sampleInfoImageHover, false)
- this.button.innerText = 'Sample Info'
+ this.showSampleInfo = false
- this.setButtonVisibility(false)
+ this.button.addEventListener('mouseenter', () => {
+ if (false === this.showSampleInfo) {
+ this.setState(true)
+ }
+ })
+
+ this.button.addEventListener('mouseleave', () => {
+ if (false === this.showSampleInfo) {
+ this.setState(false)
+ }
+ })
this.button.addEventListener('click', () => {
this.showSampleInfo = !this.showSampleInfo
- this.setButtonState(this.showSampleInfo)
+
+ for (const {sampleInfoViewport} of browser.trackViews) {
+ false === this.showSampleInfo ? sampleInfoViewport.hide() : sampleInfoViewport.show()
+ }
+
+ this.setState(this.showSampleInfo)
browser.layoutChange()
@@ -51,27 +67,16 @@ class SampleInfoControl {
setButtonVisibility(isVisible) {
this.showSampleInfo = isVisible
- this.setButtonState(isVisible)
- if (true === isVisible) {
+ this.setState(this.showSampleInfo)
+
+ if (true === this.showSampleInfo) {
this.show()
} else {
this.hide()
}
}
- setButtonState(showSampleInfo) {
- true === showSampleInfo ? this.button.classList.add('igv-navbar-button-clicked') : this.button.classList.remove('igv-navbar-button-clicked')
- }
-
- hide() {
- this.button.style.display = 'none'
- }
-
- show() {
- this.button.style.display = 'block'
- }
-
}
export default SampleInfoControl
diff --git a/js/sample/sampleInfoViewport.js b/js/sample/sampleInfoViewport.js
index bba2e561f..e4663aac6 100644
--- a/js/sample/sampleInfoViewport.js
+++ b/js/sample/sampleInfoViewport.js
@@ -35,10 +35,28 @@ class SampleInfoViewport {
}
static getSampleInfoColumnWidth(browser) {
- const found = browser.findTracks(t => typeof t.getSamples === 'function')
- return (found.length > 0 && browser.sampleInfo.isInitialized() && true === browser.sampleInfoControl.showSampleInfo)
- ? sampleInfoTileXShim + browser.sampleInfo.getAttributeNames().length * sampleInfoTileWidth
- : 0
+
+ if (undefined === browser.sampleInfo.getAttributeNames()) {
+ return 0
+ } else {
+
+ const found = browser.findTracks(t => typeof t.getSamples === 'function')
+ const isFound = found.length > 0
+
+ const isInitialized = browser.sampleInfo.isInitialized()
+
+ const doShowSampleInfo = browser.sampleInfoControl.showSampleInfo
+
+ const status = isFound && isInitialized && doShowSampleInfo
+
+ if (false === status) {
+ return 0
+ } else {
+ const sampleInfoAttributeCount = browser.sampleInfo.getAttributeNames().length
+ return sampleInfoAttributeCount * sampleInfoTileWidth + sampleInfoTileXShim
+ }
+
+ }
}
checkCanvas() {
diff --git a/js/ui/sampleNameControl.js b/js/sample/sampleNameControl.js
similarity index 59%
rename from js/ui/sampleNameControl.js
rename to js/sample/sampleNameControl.js
index be2d77e61..21f0a5c6c 100644
--- a/js/ui/sampleNameControl.js
+++ b/js/sample/sampleNameControl.js
@@ -24,65 +24,48 @@
* THE SOFTWARE.
*/
-import {DOMUtils} from '../../node_modules/igv-ui/dist/igv-ui.js'
+import NavbarButton from "../ui/navbarButton.js"
+import {sampleNameImage, sampleNameImageHover} from "../ui/navbarIcons/sampleNames.js"
+import { sampleNameButtonLabel } from "../ui/navbarIcons/buttonLabel.js"
-class SampleNameControl {
+class SampleNameControl extends NavbarButton {
constructor(parent, browser) {
- this.button = DOMUtils.div({class: 'igv-navbar-button'})
- parent.appendChild(this.button)
+ super(browser, parent, 'Sample Names', sampleNameButtonLabel, sampleNameImage, sampleNameImageHover, browser.config.showSampleNames)
- this.button.innerText = 'Sample Names'
-
- this.setState(browser.showSampleNames)
+ this.button.addEventListener('mouseenter', () => {
+ if (false === browser.showSampleNames) {
+ this.setState(true)
+ }
+ })
- this.setVisibility(browser.showSampleNameButton)
+ this.button.addEventListener('mouseleave', () => {
+ if (false === browser.showSampleNames) {
+ this.setState(false)
+ }
+ })
this.button.addEventListener('click', () => {
browser.showSampleNames = !browser.showSampleNames
- this.setState(browser.showSampleNames)
-
- for (let {sampleNameViewport} of browser.trackViews) {
- if (false === browser.showSampleNames) {
- sampleNameViewport.hide()
- } else {
- sampleNameViewport.show()
- }
+ for (const {sampleNameViewport} of browser.trackViews) {
+ false === browser.showSampleNames ? sampleNameViewport.hide() : sampleNameViewport.show()
}
- browser.layoutChange()
+ this.setState(browser.showSampleNames)
+ browser.layoutChange()
})
- }
-
- setVisibility(showSampleNameButton) {
-
- if (true === showSampleNameButton) {
+ if (true === browser.config.showSampleNameButton) {
this.show()
} else {
this.hide()
}
- }
-
- setState(showSampleNames) {
- if (true === showSampleNames) {
- this.button.classList.add('igv-navbar-button-clicked')
- } else {
- this.button.classList.remove('igv-navbar-button-clicked')
- }
- }
-
- hide() {
- this.button.style.display = 'none'
- }
- show() {
- this.button.style.display = 'block'
}
}
diff --git a/js/trackBase.js b/js/trackBase.js
index ed2a498f2..ab5d868b1 100644
--- a/js/trackBase.js
+++ b/js/trackBase.js
@@ -25,6 +25,9 @@
import {isSimpleType} from "./util/igvUtils.js"
import {FeatureUtils, FileUtils, StringUtils} from "../node_modules/igv-utils/src/index.js"
+import {getMultiSelectedTrackViews, isMultiSelectedTrackView} from "./ui/menuUtils.js"
+import $ from "./vendor/jquery-3.3.1.slim.js"
+import {createCheckbox} from "./igv-icons.js"
const DEFAULT_COLOR = 'rgb(150,150,150)'
@@ -367,8 +370,7 @@ class TrackBase {
/**
* Default popup text function -- just extracts string and number properties in random order.
- * @param feature
- * @returns {Array}
+ * @param feature * @returns {Array}
*/
extractPopupData(feature, genomeId) {
@@ -503,6 +505,51 @@ class TrackBase {
return (typeof this.color === "function") ? this.color(feature) : this.color
}
+ numericDataMenuItems() {
+
+ const menuItems = []
+
+ menuItems.push('
')
+
+ // Data range
+ let object = $('
')
+ object.text('Set data range')
+
+ function dialogPresentationHandler() {
+
+ if (isMultiSelectedTrackView(this.trackView)) {
+ this.browser.dataRangeDialog.configure(getMultiSelectedTrackViews(this.trackView.browser))
+ } else {
+ this.browser.dataRangeDialog.configure(this.trackView)
+ }
+ this.browser.dataRangeDialog.present($(this.browser.columnContainer))
+ }
+ menuItems.push({ object, dialog:dialogPresentationHandler })
+
+ if (this.logScale !== undefined) {
+
+ object = $(createCheckbox("Log scale", this.logScale))
+
+ function logScaleHandler() {
+ this.logScale = !this.logScale
+ this.trackView.repaintViews()
+ }
+
+ menuItems.push({ object, click:logScaleHandler })
+ }
+
+ object = $(createCheckbox("Autoscale", this.autoscale))
+
+ function autoScaleHandler() {
+ this.autoscale = !this.autoscale
+ this.trackView.updateViews()
+ }
+
+ menuItems.push({ object, click:autoScaleHandler })
+
+ return menuItems
+ }
+
/**
* Track has been permanently removed. Release resources and other cleanup
*/
diff --git a/js/trackView.js b/js/trackView.js
index 06347ab26..46d09a82f 100644
--- a/js/trackView.js
+++ b/js/trackView.js
@@ -32,19 +32,26 @@ import {DOMUtils, Icon} from '../node_modules/igv-ui/dist/igv-ui.js'
import SampleInfoViewport from "./sample/sampleInfoViewport.js";
import SampleNameViewport from './sample/sampleNameViewport.js'
import MenuPopup from "./ui/menuPopup.js"
-import MenuUtils from "./ui/menuUtils.js"
+import {getMultiSelectedTrackViews, multiTrackSelectExclusionTypes} from "./ui/menuUtils.js"
+import { ENABLE_MULTI_TRACK_SELECTION, setMultiTrackSelectionState, setDragHandleSelectionState } from './ui/multiTrackSelectButton.js'
+import {hexToRGB} from "./util/colorPalletes.js"
const igv_axis_column_width = 50
-const scrollbarExclusionTypes = new Set(['ruler', 'ideogram'])
+const scrollbarExclusionTypes = new Set(['sequence', 'ruler', 'ideogram'])
const colorPickerExclusionTypes = new Set(['ruler', 'sequence', 'ideogram'])
class TrackView {
constructor(browser, columnContainer, track) {
+
+ this.namespace = `trackview-${DOMUtils.guid()}`
+
this.browser = browser
this.track = track
track.trackView = this
+
this.addDOMToColumnContainer(browser, columnContainer, browser.referenceFrameList)
+
}
/**
@@ -99,16 +106,11 @@ class TrackView {
const axis = DOMUtils.div()
browser.columnContainer.querySelector('.igv-axis-column').appendChild(axis)
+ axis.dataset.tracktype = track.type
+
axis.style.height = `${track.height}px`
if (typeof track.paintAxis === 'function') {
- if (track.dataRange) {
- axis.addEventListener('click', () => {
- browser.dataRangeDialog.configure(this)
- browser.dataRangeDialog.present($(browser.columnContainer))
- })
- }
-
const {width, height} = axis.getBoundingClientRect()
this.axisCanvas = document.createElement('canvas')
@@ -117,6 +119,25 @@ class TrackView {
axis.appendChild(this.axisCanvas)
}
+ if (false === multiTrackSelectExclusionTypes.has(this.track.type)) {
+
+ const trackSelectionContainer = DOMUtils.div()
+ axis.appendChild(trackSelectionContainer)
+
+ const html = `
`
+ const input = document.createRange().createContextualFragment(html).firstChild
+ trackSelectionContainer.appendChild(input)
+
+ input.addEventListener('change', event => {
+ event.preventDefault()
+ event.stopPropagation()
+ setDragHandleSelectionState(this, this.dragHandle, event.target.checked)
+ })
+
+ setMultiTrackSelectionState(this, axis, ENABLE_MULTI_TRACK_SELECTION)
+
+ }
+
return axis
}
@@ -192,26 +213,44 @@ class TrackView {
if (this.track.altColor && StringUtils.isString(this.track.altColor)) {
trackColors.push(this.track.altColor)
}
- const defaultColors = trackColors.map(c => c.startsWith("#") ? c : c.startsWith("rgb(") ? IGVColor.rgbToHex(c) : IGVColor.colorNameToHex(c))
- const colorHandlers =
+ let defaultColors = trackColors.map(c => c.startsWith("#") ? c : c.startsWith("rgb(") ? IGVColor.rgbToHex(c) : IGVColor.colorNameToHex(c))
+ let colorHandlers =
{
- color: color => {
- this.track.color = color
+ color: hex => {
+ this.track.color = hexToRGB(hex)
this.repaintViews()
},
- altColor: color => {
- this.track.altColor = color
+ altColor: hex => {
+ this.track.altColor = hexToRGB(hex)
this.repaintViews()
}
}
- this.browser.genericColorPicker.configure(defaultColors, colorHandlers)
+
+ const selected = getMultiSelectedTrackViews(this.browser)
+
+ if (selected && new Set(selected).has(this)) {
+
+ colorHandlers =
+ {
+ color: rgbString => {
+ for (let trackView of selected) {
+ trackView.track.color = rgbString
+ trackView.repaintViews()
+ }
+ }
+ }
+
+ this.browser.genericColorPicker.configure(defaultColors, colorHandlers)
+ } else {
+ this.browser.genericColorPicker.configure(defaultColors, colorHandlers)
+ }
+
this.browser.genericColorPicker.setActiveColorHandler(key)
this.browser.genericColorPicker.show()
}
}
-
setTrackHeight(newHeight, force) {
if (!force) {
@@ -541,6 +580,27 @@ class TrackView {
}
}
+ viewportsToReload(force) {
+
+ // List of viewports that need reloading
+ const viewports = this.viewports.filter(viewport => {
+ if (!viewport.isVisible()) {
+ return false
+ }
+ if (!viewport.checkZoomIn()) {
+ return false
+ } else {
+ const referenceFrame = viewport.referenceFrame
+ const chr = viewport.referenceFrame.chr
+ const start = referenceFrame.start
+ const end = start + referenceFrame.toBP($(viewport.contentDiv).width())
+ const bpPerPixel = referenceFrame.bpPerPixel
+ return force || (!viewport.tile || viewport.tile.invalidate || !viewport.tile.containsRange(chr, start, end, bpPerPixel))
+ }
+ })
+ return viewports
+ }
+
createTrackScrollbar(browser) {
const outerScroll = DOMUtils.div()
@@ -560,13 +620,17 @@ class TrackView {
createTrackDragHandle(browser) {
- const className = 'ideogram' === this.track.type || 'ruler' === this.track.type ? 'igv-track-drag-shim' : 'igv-track-drag-handle'
- this.dragHandle = DOMUtils.div({class: className})
- browser.columnContainer.querySelector('.igv-track-drag-column').appendChild(this.dragHandle)
- this.dragHandle.style.height = `${this.track.height}px`
+ if (true === multiTrackSelectExclusionTypes.has(this.track.type)) {
+ this.dragHandle = DOMUtils.div({ class: 'igv-track-drag-shim' })
+ } else {
+ this.dragHandle = DOMUtils.div({ class: 'igv-track-drag-handle' })
+ this.dragHandle.classList.add('igv-track-drag-handle-color')
+ this.dragHandle.dataset.selected = 'no'
+ }
+ browser.columnContainer.querySelector('.igv-track-drag-column').appendChild(this.dragHandle)
+ this.dragHandle.style.height = `${ this.track.height }px`
this.addTrackDragMouseHandlers(browser)
-
}
createTrackGearPopup(browser) {
@@ -592,9 +656,9 @@ class TrackView {
event.preventDefault()
event.stopPropagation()
if ('none' === this.trackGearPopup.popover.style.display) {
- this.trackGearPopup.presentMenuList(MenuUtils.trackMenuItemList(this))
+ this.trackGearPopup.presentMenuList(this, browser.menuUtils.trackMenuItemList(this))
} else {
- this.trackGearPopup.hide()
+ this.trackGearPopup.popover.style.display = 'none'
}
@@ -604,22 +668,6 @@ class TrackView {
}
- addAxisEventListener(axis) {
-
- this.boundAxisClickHander = axisClickHandler.bind(this)
- axis.addEventListener('click', this.boundAxisClickHander)
-
- function axisClickHandler(event) {
- this.browser.dataRangeDialog.configure(this)
- this.browser.dataRangeDialog.present($(this.browser.columnContainer))
- }
-
- }
-
- removeAxisEventListener(axis) {
- axis.removeEventListener('click', this.boundAxisClickHander)
- }
-
addTrackScrollMouseHandlers(browser) {
// Mouse Down
@@ -669,9 +717,7 @@ class TrackView {
addTrackDragMouseHandlers(browser) {
- if ('ideogram' === this.track.id || 'ruler' === this.track.id) {
- // do nothing
- } else {
+ if (false === multiTrackSelectExclusionTypes.has(this.track.type)) {
let currentDragHandle = undefined
@@ -684,7 +730,10 @@ class TrackView {
event.preventDefault()
currentDragHandle = event.target
- currentDragHandle.classList.add('igv-track-drag-handle-hover')
+ if ('no' === currentDragHandle.dataset.selected) {
+ currentDragHandle.classList.remove('igv-track-drag-handle-color')
+ currentDragHandle.classList.add('igv-track-drag-handle-hover-color')
+ }
browser.startTrackDrag(this)
@@ -699,7 +748,12 @@ class TrackView {
browser.endTrackDrag()
if (currentDragHandle && event.target !== currentDragHandle) {
- currentDragHandle.classList.remove('igv-track-drag-handle-hover')
+
+ if ('no' === currentDragHandle.dataset.selected) {
+ currentDragHandle.classList.remove('igv-track-drag-handle-hover-color')
+ currentDragHandle.classList.add('igv-track-drag-handle-color')
+ }
+
}
currentDragHandle = undefined
@@ -713,7 +767,10 @@ class TrackView {
event.preventDefault()
if (undefined === currentDragHandle) {
- event.target.classList.add('igv-track-drag-handle-hover')
+ if ('no' === event.target.dataset.selected) {
+ event.target.classList.remove('igv-track-drag-handle-color')
+ event.target.classList.add('igv-track-drag-handle-hover-color')
+ }
}
browser.updateTrackDrag(this)
@@ -721,11 +778,14 @@ class TrackView {
}
// Mouse Out
- this.dragHandle.addEventListener('mouseout', e => {
- e.preventDefault()
+ this.dragHandle.addEventListener('mouseout', event => {
+ event.preventDefault()
if (undefined === currentDragHandle) {
- e.target.classList.remove('igv-track-drag-handle-hover')
+ if ('no' === event.target.dataset.selected) {
+ event.target.classList.remove('igv-track-drag-handle-hover-color')
+ event.target.classList.add('igv-track-drag-handle-color')
+ }
}
})
@@ -736,7 +796,10 @@ class TrackView {
event.preventDefault()
if (undefined === currentDragHandle) {
- event.target.classList.remove('igv-track-drag-handle-hover')
+ if ('no' === event.target.dataset.selected) {
+ event.target.classList.remove('igv-track-drag-handle-hover-color')
+ event.target.classList.add('igv-track-drag-handle-color')
+ }
}
}
@@ -746,7 +809,7 @@ class TrackView {
removeTrackDragMouseHandlers() {
- if ('ideogram' === this.track.id || 'ruler' === this.track.id) {
+ if ('ideogram' === this.track.type || 'ruler' === this.track.type) {
// do nothing
} else {
this.dragHandle.removeEventListener('mousedown', this.boundTrackDragMouseDownHandler)
@@ -769,9 +832,6 @@ class TrackView {
removeDOMFromColumnContainer() {
// Axis
- if (this.boundAxisClickHander) {
- this.removeAxisEventListener(this.axis)
- }
this.axis.remove()
// Track Viewports
@@ -804,7 +864,6 @@ class TrackView {
*/
dispose() {
- this.removeAxisEventListener(this.axis)
this.axis.remove()
for (let viewport of this.viewports) {
@@ -882,6 +941,10 @@ function renderSVGAxis(context, track, axisCanvas, deltaX, deltaY) {
}
+function maxViewportContentHeight(viewports) {
+ const heights = viewports.map(viewport => viewport.getContentHeight())
+ return Math.max(...heights)
+}
-export {igv_axis_column_width}
+export {igv_axis_column_width, maxViewportContentHeight, setDragHandleSelectionState}
export default TrackView
diff --git a/js/trackViewport.js b/js/trackViewport.js
index 8a42e5594..1724c9159 100644
--- a/js/trackViewport.js
+++ b/js/trackViewport.js
@@ -39,7 +39,7 @@ class TrackViewport extends Viewport {
this.$trackLabel = $('
')
this.$viewport.append(this.$trackLabel)
this.setTrackLabel(track.name)
- if (false === this.browser.trackLabelsVisible) {
+ if (false === this.browser.doShowTrackLabels) {
this.$trackLabel.hide()
}
}
@@ -461,7 +461,7 @@ class TrackViewport extends Viewport {
return
}
- if (this.$trackLabel && true === this.browser.trackLabelsVisible) {
+ if (this.$trackLabel && true === this.browser.doShowTrackLabels) {
const {x, y, width, height} = DOMUtils.relativeDOMBBox(this.$viewport.get(0), this.$trackLabel.get(0))
this.renderTrackLabelSVG(context, deltaX + x, deltaY + y, width, height)
}
diff --git a/js/ui/centerLineButton.js b/js/ui/centerLineButton.js
index fe6b7087e..bd5636103 100644
--- a/js/ui/centerLineButton.js
+++ b/js/ui/centerLineButton.js
@@ -1,49 +1,71 @@
-import {DOMUtils} from '../../node_modules/igv-ui/dist/igv-ui.js'
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 University of California San Diego
+ * Author: Jim Robinson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
-class CenterLineButton {
+import NavbarButton from "./navbarButton.js"
+import GenomeUtils from "../genome/genomeUtils.js"
+import {centerlineImage, centerlineImageHover} from "./navbarIcons/centerline.js"
+import { buttonLabel } from "./navbarIcons/buttonLabel.js"
- constructor(browser, parent) {
+class CenterLineButton extends NavbarButton {
- this.browser = browser
+ constructor(browser, parent) {
- this.button = DOMUtils.div({class: 'igv-navbar-button'})
- parent.appendChild(this.button)
+ super(browser, parent, 'Center Line', buttonLabel, centerlineImage, centerlineImageHover, browser.config.showCenterGuide)
- this.button.textContent = 'center line'
+ this.button.addEventListener('mouseenter', () => {
+ if (false === browser.doShowCenterLine) {
+ this.setState(true)
+ }
+ })
- this.button.addEventListener('click', () => {
- browser.isCenterLineVisible = !browser.isCenterLineVisible
- browser.setCenterLineVisibility(browser.isCenterLineVisible)
- this.setButtonState(browser.isCenterLineVisible)
+ this.button.addEventListener('mouseleave', () => {
+ if (false === browser.doShowCenterLine) {
+ this.setState(false)
+ }
})
- this.setButtonState(browser.isCenterLineVisible)
+ const mouseClickHandler = () => {
- if (browser.config.showCenterGuideButton) {
- this.show()
- } else {
- this.hide()
- }
- }
+ if (false === browser.doShowCenterLine && GenomeUtils.isWholeGenomeView(browser.referenceFrameList[0].chr)) {
+ return
+ }
- setButtonState(isCenterLineVisible) {
- if (true === isCenterLineVisible) {
- this.button.classList.add('igv-navbar-button-clicked')
- } else {
- this.button.classList.remove('igv-navbar-button-clicked')
+ browser.doShowCenterLine = !browser.doShowCenterLine
+ browser.setCenterLineVisibility(browser.doShowCenterLine)
+ this.setState(browser.doShowCenterLine)
}
- }
- show() {
- this.isVisible = true
- this.button.style.display = 'block'
- this.setButtonState(this.browser.isCenterLineVisible)
- }
+ this.boundMouseClickHandler = mouseClickHandler.bind(this)
+
+ this.button.addEventListener('click', this.boundMouseClickHandler)
+
+ this.setVisibility(browser.config.showCenterGuideButton)
- hide() {
- this.isVisible = false
- this.button.style.display = 'none'
}
+
}
export default CenterLineButton
diff --git a/js/ui/cursorGuideButton.js b/js/ui/cursorGuideButton.js
index 93b84dcbc..aa0b38b67 100644
--- a/js/ui/cursorGuideButton.js
+++ b/js/ui/cursorGuideButton.js
@@ -24,51 +24,49 @@
* THE SOFTWARE.
*/
-import {DOMUtils} from '../../node_modules/igv-ui/dist/igv-ui.js'
+import NavbarButton from "./navbarButton.js"
+import GenomeUtils from "../genome/genomeUtils.js"
+import {cursorImage, cursorImageHover} from "./navbarIcons/cursor.js"
+import { buttonLabel } from "./navbarIcons/buttonLabel.js"
-class CursorGuideButton {
+class CursorGuideButton extends NavbarButton {
constructor(browser, parent) {
- this.browser = browser
+ super(browser, parent, 'Crosshairs', buttonLabel, cursorImage, cursorImageHover, browser.doShowCursorGuide)
- this.button = DOMUtils.div({class: 'igv-navbar-button'})
- parent.appendChild(this.button)
-
- this.button.textContent = 'cursor guide'
+ this.button.addEventListener('mouseenter', () => {
+ if (false === browser.doShowCursorGuide) {
+ this.setState(true)
+ }
+ })
- this.button.addEventListener('click', () => {
- browser.cursorGuideVisible = !browser.cursorGuideVisible
- browser.setCursorGuideVisibility(browser.cursorGuideVisible)
- this.setButtonState(browser.cursorGuideVisible)
+ this.button.addEventListener('mouseleave', () => {
+ if (false === browser.doShowCursorGuide) {
+ this.setState(false)
+ }
})
- this.setButtonState(browser.cursorGuideVisible)
+ const mouseClickHandler = () => {
- if (browser.config.showCursorTrackingGuideButton) {
- this.show()
- } else {
- this.hide()
- }
+ if (false === browser.doShowCursorGuide && GenomeUtils.isWholeGenomeView(browser.referenceFrameList[0].chr)) {
+ return
+ }
- }
+ browser.doShowCursorGuide = !browser.doShowCursorGuide
+ browser.setCursorGuideVisibility(browser.doShowCursorGuide)
+ this.setState(browser.doShowCursorGuide)
- setButtonState(cursorGuideVisible) {
- if (true === cursorGuideVisible) {
- this.button.classList.add('igv-navbar-button-clicked')
- } else {
- this.button.classList.remove('igv-navbar-button-clicked')
}
- }
- show() {
- this.button.style.display = 'block'
- this.setButtonState(this.browser.cursorGuideVisible)
- }
+ this.boundMouseClickHandler = mouseClickHandler.bind(this)
+
+ this.button.addEventListener('click', this.boundMouseClickHandler)
+
+ this.setVisibility(browser.config.showCursorTrackingGuideButton)
- hide() {
- this.button.style.display = 'none'
}
+
}
export default CursorGuideButton
diff --git a/js/ui/dataRangeDialog.js b/js/ui/dataRangeDialog.js
index 3e14f2f83..3b3f21f4f 100644
--- a/js/ui/dataRangeDialog.js
+++ b/js/ui/dataRangeDialog.js
@@ -4,7 +4,7 @@ import {makeDraggable, UIUtils} from "../../node_modules/igv-ui/dist/igv-ui.js"
class DataRangeDialog {
- constructor(browser, $parent, alert) {
+ constructor(browser, $parent) {
this.browser = browser
@@ -70,11 +70,23 @@ class DataRangeDialog {
this.$container.hide()
}
- configure(trackView) {
+ configure(trackViewOfTrackViewList) {
- const dataRange = trackView.dataRange()
let min
let max
+ let dataRange
+ if (Array.isArray(trackViewOfTrackViewList)) {
+ dataRange = { min: Number.MAX_SAFE_INTEGER, max:-Number.MAX_SAFE_INTEGER }
+ for (const trackView of trackViewOfTrackViewList) {
+ if (trackView.dataRange()) {
+ dataRange.min = Math.min(trackView.dataRange().min, dataRange.min)
+ dataRange.max = Math.max(trackView.dataRange().max, dataRange.max)
+ }
+ }
+ } else {
+ dataRange = trackViewOfTrackViewList.dataRange()
+ }
+
if (dataRange) {
min = dataRange.min
max = dataRange.max
@@ -89,32 +101,36 @@ class DataRangeDialog {
this.$minimum_input.unbind()
this.$minimum_input.on('keyup', (e) => {
if (13 === e.keyCode) {
- this.processResults(trackView)
+ this.processResults(trackViewOfTrackViewList)
}
})
this.$maximum_input.unbind()
this.$maximum_input.on('keyup', (e) => {
if (13 === e.keyCode) {
- this.processResults(trackView)
+ this.processResults(trackViewOfTrackViewList)
}
})
this.$ok.unbind()
this.$ok.on('click', (e) => {
- this.processResults(trackView)
+ this.processResults(trackViewOfTrackViewList)
})
}
-
- processResults(trackView) {
+ processResults(trackViewOfTrackViewList) {
const min = Number(this.$minimum_input.val())
const max = Number(this.$maximum_input.val())
if (isNaN(min) || isNaN(max)) {
this.browser.alert.present(new Error('Must input numeric values'), undefined)
} else {
- trackView.setDataRange(min, max)
+ const list = Array.isArray(trackViewOfTrackViewList) ? trackViewOfTrackViewList : [ trackViewOfTrackViewList ]
+
+ for (const trackView of list) {
+ trackView.setDataRange(min, max)
+ }
+
}
this.$minimum_input.val(undefined)
diff --git a/js/ui/menuPopup.js b/js/ui/menuPopup.js
index f20ec5c1f..4e83481cf 100644
--- a/js/ui/menuPopup.js
+++ b/js/ui/menuPopup.js
@@ -1,102 +1,178 @@
-import MenuUtils from "./menuUtils.js"
import {DOMUtils, makeDraggable, UIUtils} from "../../node_modules/igv-ui/dist/igv-ui.js"
import {GenericColorPicker} from '../../node_modules/igv-ui/dist/igv-ui.js'
import {createCheckbox} from "../igv-icons.js"
+import $ from "../vendor/jquery-3.3.1.slim.js"
+import {getMultiSelectedTrackViews, isMultiSelectedTrackView} from "./menuUtils.js"
-const MenuPopup = function (parent) {
+class MenuPopup {
+ constructor(parent) {
+ this.popover = DOMUtils.div({class: 'igv-menu-popup'})
- this.popover = DOMUtils.div({class: 'igv-menu-popup'})
- parent.appendChild(this.popover)
+ parent.appendChild(this.popover)
- const header = DOMUtils.div({class: 'igv-menu-popup-header'})
- this.popover.appendChild(header)
+ const header = DOMUtils.div({class: 'igv-menu-popup-header'})
+ this.popover.appendChild(header)
- UIUtils.attachDialogCloseHandlerWithParent(header, () => this.hide())
+ UIUtils.attachDialogCloseHandlerWithParent(header, () => this.popover.style.display = 'none')
- this.popoverContent = DOMUtils.div()
- this.popover.appendChild(this.popoverContent)
+ this.popoverContent = DOMUtils.div()
+ this.popover.appendChild(this.popoverContent)
- makeDraggable(this.popover, header)
+ makeDraggable(this.popover, header)
- header.addEventListener('click', e => {
- e.stopPropagation()
- e.preventDefault()
// absorb click to prevent it leaking through to parent DOM element
- })
+ header.addEventListener('click', e => {
+ e.stopPropagation()
+ e.preventDefault()
+ })
- this.hide()
+ this.popover.style.display = 'none'
-}
+ }
-MenuPopup.prototype.hide = function () {
- this.popover.style.display = 'none'
-}
+ presentMenuList(trackView, menuList) {
-MenuPopup.prototype.presentMenuList = function (menuList) {
+ hideAllMenuPopups()
- hideAllMenuPopups()
+ if (menuList.length > 0) {
- if (menuList.length > 0) {
+ this.popoverContent.innerHTML = ''
- this.popoverContent.innerHTML = ''
+ const parsedList = this.parseMenuList(trackView, menuList)
- menuList = MenuUtils.trackMenuItemListHelper(menuList, this)
+ for (let item of parsedList) {
- for (let item of menuList) {
+ if (item.init) {
+ item.init()
+ }
+
+ let $e = item.object
+ if (0 === parsedList.indexOf(item)) {
+ $e.removeClass('igv-track-menu-border-top')
+ }
+
+ if ($e.hasClass('igv-track-menu-border-top') || $e.hasClass('igv-menu-popup-check-container')) {
+ // do nothing
+ } else if ($e.is('div')) {
+ $e.addClass('igv-menu-popup-shim')
+ }
+
+ this.popoverContent.appendChild($e.get(0))
- if (item.init) {
- item.init()
}
- let $e = item.object
- if (0 === menuList.indexOf(item)) {
- $e.removeClass('igv-track-menu-border-top')
+ // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always
+ // yield a width of zero (0).
+ this.popover.style.display = 'flex'
+
+ const {width} = this.popover.getBoundingClientRect()
+
+ this.popover.style.left = `${-width}px`
+ this.popover.style.top = `${0}px`
+
+ }
+ }
+
+ parseMenuList(trackView, menuList) {
+
+ return menuList.map((item, i) => {
+
+ let $e
+
+ // name and object fields checked for backward compatibility
+ if (item.name) {
+ $e = $('
')
+ $e.text(item.name)
+ } else if (item.object) {
+ $e = item.object
+ } else if (typeof item.label === 'string') {
+ $e = $('
')
+ $e.html(item.label)
+ } else if (typeof item === 'string') {
+
+ if (item.startsWith("<")) {
+ $e = $(item)
+ } else {
+ $e = $("
" + item + "
")
+ }
}
- if ($e.hasClass('igv-track-menu-border-top') || $e.hasClass('igv-menu-popup-check-container')) {
- // do nothing
- } else if ($e.is('div')) {
- $e.addClass('igv-menu-popup-shim')
+ if (0 === i) {
+ $e.addClass('igv-track-menu-border-top')
}
- this.popoverContent.appendChild($e.get(0))
+ if (item.click || item.dialog) {
- }
+ const handleClick = e => {
+ e.preventDefault()
+ e.stopPropagation()
- // NOTE: style.display most NOT be 'none' when calculating width. a display = 'none' will always
- // yield a width of zero (0).
- this.popover.style.display = 'flex'
+ if (item.click) {
- const {width} = this.popover.getBoundingClientRect()
+ if (isMultiSelectedTrackView(trackView)) {
- this.popover.style.left = `${-width}px`
- this.popover.style.top = `${0}px`
+ if (true === item.doTrackOverlay) {
+ item.click.call(trackView.track, e)
+ } else {
+ for (const { track } of getMultiSelectedTrackViews(trackView.browser)) {
+ item.click.call(track, e)
+ }
+ }
- }
-}
+ } else {
+ item.click.call(trackView.track, e)
+ }
+
+ } else if (item.dialog) {
+ item.dialog.call(trackView.track, e)
+ }
+
+ this.popover.style.display = 'none'
+ }
+
+ $e.on('click', handleClick)
-MenuPopup.prototype.presentTrackContextMenu = function (e, menuItems) {
+ $e.on('touchend', e => handleClick(e))
+
+ $e.on('mouseup', function (e) {
+ e.preventDefault()
+ e.stopPropagation()
+ })
+
+ }
- this.popoverContent.innerHTML = ''
+ return {object: $e, init: (item.init || undefined)}
+ })
- const menuElements = createMenuElements(menuItems, this.popover)
- for (let {el} of menuElements) {
- this.popoverContent.appendChild(el)
}
- present(e, this.popover)
+ presentTrackContextMenu(e, menuList) {
-}
+ this.popoverContent.innerHTML = ''
+
+ const menuElements = createMenuElements(menuItems, this.popover)
+ for (let {el} of menuElements) {
+ this.popoverContent.appendChild(el)
+ }
-MenuPopup.prototype.dispose = function () {
+ present(e, this.popover)
- this.popoverContent.innerHTML = ''
- this.popover.innerHTML = ''
+ }
- Object.keys(this).forEach(function (key) {
- this[key] = undefined
- })
+ hide() {
+ this.popover.style.display = 'none'
+ }
+
+ dispose() {
+
+ this.popoverContent.innerHTML = ''
+ this.popover.innerHTML = ''
+
+ Object.keys(this).forEach(function (key) {
+ this[key] = undefined
+ })
+ }
}
function createMenuElements(itemList, popover) {
@@ -121,8 +197,8 @@ function createMenuElements(itemList, popover) {
el = createCheckbox("Show all bases", item.value)
} else if ("color" === item.type) {
- const colorPicker = new GenericColorPicker({parent: popover.parentElement, width: 364})
- colorPicker.configure(undefined, {color: color => item.click(color)})
+ const colorPicker = new GenericColorPicker(popover.parentElement)
+ colorPicker.configure({color: 'grey'})
el = DOMUtils.div({class: 'context-menu'})
if (typeof item.label === 'string') {
diff --git a/js/ui/menuUtils.js b/js/ui/menuUtils.js
index ca79cb5b0..990d53319 100644
--- a/js/ui/menuUtils.js
+++ b/js/ui/menuUtils.js
@@ -1,226 +1,312 @@
+import {DOMUtils} from '../../node_modules/igv-ui/dist/igv-ui.js'
import $ from "../vendor/jquery-3.3.1.slim.js"
-import {createCheckbox} from "../igv-icons.js"
-/**
- * Configure item list for track "gear" menu.
- * @param trackView
- */
-const MenuUtils = {
+const colorPickerTrackTypeSet = new Set([ 'bedtype', 'alignment', 'annotation', 'variant', 'wig', 'interact' ])
- trackMenuItemList: function (trackView) {
+const vizWindowTypes = new Set(['alignment', 'annotation', 'variant', 'eqtl', 'snp', 'shoebox'])
- const vizWindowTypes = new Set(['alignment', 'annotation', 'variant', 'eqtl', 'snp', 'shoebox'])
+const multiTrackSelectExclusionTypes = new Set(['sequence', 'ruler', 'ideogram'])
- const hasVizWindow = trackView.track.config && trackView.track.config.visibilityWindow !== undefined
+class MenuUtils {
+ constructor(browser) {
+ this.browser = browser
+ }
+
+ trackMenuItemList(trackView) {
- let menuItems = []
+ const list = []
if (trackView.track.config.type !== 'sequence') {
- menuItems.push(trackRenameMenuItem(trackView))
- menuItems.push(trackHeightMenuItem(trackView))
+ list.push(trackHeightMenuItem())
+ }
+
+ if (true === didMultiSelect(trackView)) {
+ list.push(...this.multiSelectMenuItems(trackView))
+ } else {
+ if (trackView.track.config.type !== 'sequence') {
+ list.push(trackRenameMenuItem())
+ }
+ list.push(...this.defaultMenuItems(trackView))
}
- if (this.showColorPicker(trackView.track)) {
- menuItems.push('
')
- menuItems.push(colorPickerMenuItem({trackView, label: "Set track color", option: "color"}))
- menuItems.push(unsetColorMenuItem({trackView, label: "Unset track color"}))
- if(trackView.track.config.type === 'wig' || trackView.track.config.type === 'annotation') {
- menuItems.push(colorPickerMenuItem({trackView, label: "Set alt color", option: "altColor"}))
- menuItems.push(unsetAltColorMenuItem({trackView, label: "Unset alt color"}))
- }
+ if (trackView.track.removable !== false) {
+ list.push('
')
+ list.push(trackRemovalMenuItem())
+ }
+
+ return list
+ }
+
+ defaultMenuItems(trackView) {
+
+ const list = []
+
+ if (canShowColorPicker(trackView.track)) {
+
+ list.push('
')
+ list.push(colorPickerMenuItem({trackView, label: "Set track color", option: "color"}))
+ list.push(unsetColorMenuItem({trackView, label: "Unset track color"}))
+
+ if(trackView.track.config.type === 'wig' || trackView.track.config.type === 'annotation') {
+ list.push(colorPickerMenuItem({trackView, label: "Set alt color", option: "altColor"}))
+ list.push(unsetAltColorMenuItem({trackView, label: "Unset alt color"}))
+ }
+
}
if (trackView.track.menuItemList) {
- menuItems = menuItems.concat(trackView.track.menuItemList())
+ list.push(...trackView.track.menuItemList())
}
- if (hasVizWindow || vizWindowTypes.has(trackView.track.type)) {
- menuItems.push('
')
- menuItems.push(visibilityWindowMenuItem(trackView))
+ if (isVisibilityWindowType(trackView)) {
+ list.push('
')
+ list.push(visibilityWindowMenuItem())
}
- if (trackView.track.removable !== false) {
- menuItems.push('
')
- menuItems.push(trackRemovalMenuItem(trackView))
+ if ('merged' === trackView.track.type) {
+ list.push('
')
+ list.push(trackSeparationMenuItem())
}
- return menuItems
- },
+ return list
+ }
- numericDataMenuItems: function (trackView) {
+ multiSelectMenuItems(trackView) {
- const menuItems = []
+ const list = []
- menuItems.push('
')
+ const selected = getMultiSelectedTrackViews(trackView.browser)
+ const isSingleTrackType = didSelectSingleTrackType(selected.map(({ track }) => track.type))
- // Data range
- const object = $('
')
- object.text('Set data range')
+ if (true === isSingleTrackType) {
- const click = () => {
- trackView.browser.dataRangeDialog.configure(trackView)
- trackView.browser.dataRangeDialog.present($(trackView.browser.columnContainer))
- }
- menuItems.push({object, click})
-
- if (trackView.track.logScale !== undefined) {
- menuItems.push({
- object: $(createCheckbox("Log scale", trackView.track.logScale)),
- click: () => {
- trackView.track.logScale = !trackView.track.logScale
- trackView.repaintViews()
- }
- }
- )
- }
+ list.push(...this.defaultMenuItems(trackView))
+
+ if ('wig' === trackView.track.type) {
+
+ list.push('
')
+ list.push(groupAutoScaleMenuItem())
+
+ list.push('
')
+ list.push(trackOverlayMenuItem())
+ }
+
+ } else {
+
+ if (canShowColorPicker(trackView.track)) {
- menuItems.push({
- object: $(createCheckbox("Autoscale", trackView.track.autoscale)),
- click: () => {
- trackView.track.autoscale = !trackView.track.autoscale
- trackView.updateViews()
+ list.push('
')
+ list.push(colorPickerMenuItem({trackView, label: "Set track color", option: "color"}))
+ list.push(unsetColorMenuItem({trackView, label: "Unset track color"}))
+
+ if(trackView.track.config.type === 'wig' || trackView.track.config.type === 'annotation') {
+ list.push(colorPickerMenuItem({trackView, label: "Set alt color", option: "altColor"}))
+ list.push(unsetAltColorMenuItem({trackView, label: "Unset alt color"}))
}
+
}
- )
+ }
- return menuItems
- },
+ return list
- trackMenuItemListHelper: function (itemList, menuPopup) {
+ }
- var list = []
+}
- if (itemList.length > 0) {
+function didMultiSelect(trackView) {
+ const selected = getMultiSelectedTrackViews(trackView.browser)
+ return selected && selected.length > 1 && new Set(selected).has(trackView)
+}
- list = itemList.map(function (item, i) {
- var $e
+function isVisibilityWindowType(track) {
+ const hasVizWindow = track.config && track.config.visibilityWindow !== undefined
+ return hasVizWindow || vizWindowTypes.has(track.type)
+}
+function groupAutoScaleMenuItem() {
- // name and object fields checked for backward compatibility
- if (item.name) {
- $e = $('
')
- $e.text(item.name)
- } else if (item.object) {
- $e = item.object
- } else if (typeof item.label === 'string') {
- $e = $('
')
- $e.html(item.label)
- } else if (typeof item === 'string') {
+ const object = $('
')
+ object.text('Group autoscale')
- if (item.startsWith("<")) {
- $e = $(item)
- } else {
- $e = $("
" + item + "
")
- }
- }
+ function click(e) {
- if (0 === i) {
- $e.addClass('igv-track-menu-border-top')
- }
+ const trackViews = getMultiSelectedTrackViews(this.browser)
- if (item.click) {
- $e.on('click', handleClick)
- $e.on('touchend', function (e) {
- handleClick(e)
- })
- $e.on('mouseup', function (e) {
- e.preventDefault()
- e.stopPropagation()
- })
-
- // eslint-disable-next-line no-inner-declarations
- function handleClick(e) {
- item.click(e)
- menuPopup.hide()
- e.preventDefault()
- e.stopPropagation()
- }
- }
+ const autoScaleGroupID = `auto-scale-group-${DOMUtils.guid()}`
+
+ for (const trackView of trackViews) {
+ trackView.track.autoscaleGroup = autoScaleGroupID
+ }
+
+ this.browser.updateViews()
+ }
+
+ return { object, click }
+
+}
+
+function trackOverlayMenuItem() {
+
+ const object = $('
')
+ object.text('Overlay tracks')
- return {object: $e, init: (item.init || undefined)}
+ function click(e) {
+
+ const trackViews = getMultiSelectedTrackViews(this.browser)
+
+ if (trackViews) {
+
+ const wigTracks = trackViews.filter(({ track }) => 'wig' === track.type).map(({ track }) => track)
+
+ const wigConfigs = wigTracks.map(( track ) => {
+ const config = Object.assign({}, track.config)
+ config.color = track.color
+ return config
})
+
+ for (const wigTrack of wigTracks) {
+ this.browser.removeTrack(wigTrack)
+ }
+
+ const fudge = 0.75
+
+ const config =
+ {
+ name: 'Overlay - autoscaled',
+ type: 'merged',
+ autoscale: true,
+ alpha: fudge * (1.0/wigTracks.length),
+ height: Math.max(...wigTracks.map(({ height }) => height)),
+ order: Math.min(...wigTracks.map(({ order }) => order)),
+ tracks: wigConfigs
+ }
+
+ this.browser.loadTrack(config)
+
}
- return list
- },
-
- showColorPicker(track) {
- return (
- undefined === track.type ||
- "bedtype" === track.type ||
- "alignment" === track.type ||
- "annotation" === track.type ||
- "variant" === track.type ||
- "wig" === track.type) ||
- 'interact' === track.type
- },
-
- createMenuItem(label, action) {
- const object = $('
')
- object.text(label)
- return {object, click: action}
}
+
+ return { object, doTrackOverlay:true, click }
+
+}
+
+function trackSeparationMenuItem() {
+
+ const object = $('
')
+ object.text('Separate tracks')
+
+ function click(e) {
+
+ const configs = this.config.tracks.map(overlayConfig => {
+ const config = { ...overlayConfig }
+ config.isMergedTrack = undefined
+ config.order = this.order
+ return config
+ })
+
+ const _browser = this.browser
+
+ _browser.removeTrack(this)
+ _browser.loadTrackList(configs)
+ }
+
+ return { object, click }
}
+function visibilityWindowMenuItem() {
-function visibilityWindowMenuItem(trackView) {
+ const object = $('
')
+ object.text('Set visibility window')
- const click = e => {
+ function click(e) {
const callback = () => {
- let value = trackView.browser.inputDialog.value
+ let value = this.browser.inputDialog.value
value = '' === value || undefined === value ? -1 : value.trim()
- trackView.track.visibilityWindow = Number.parseInt(value)
- trackView.track.config.visibilityWindow = Number.parseInt(value)
+ this.visibilityWindow = Number.parseInt(value)
+ this.config.visibilityWindow = Number.parseInt(value)
- trackView.updateViews()
+ this.trackView.updateViews()
}
const config =
{
label: 'Visibility Window',
- value: (trackView.track.visibilityWindow),
+ value: this.visibilityWindow,
callback
}
- trackView.browser.inputDialog.present(config, e)
+ this.browser.inputDialog.present(config, e)
}
- const object = $('
')
- object.text('Set visibility window')
return {object, click}
}
-function trackRemovalMenuItem(trackView) {
+// TODO: Implement dialog-presenting track removal for multi-select
+function IN_PROGRESS_PRESENTS_DIALOG_trackRemovalMenuItem() {
+
+ const object = $('
')
+ object.text('Remove track')
+
+ function dialogHandler() {
+
+ if (isMultiSelectedTrackView(this.trackView)) {
+
+ const browser = this.browser
+
+ const alertCallback = () => {
+ const trackViews = getMultiSelectedTrackViews(browser)
+ for (const { track } of trackViews) {
+ browser.removeTrack(track)
+ }
+ }
+
+ browser.alert.present('Delete Tracks?', alertCallback)
+
+ } else {
+ this.trackView.browser.removeTrack(this)
+ }
+
+ }
+
+ return { object, dialog:dialogHandler }
+}
+
+function trackRemovalMenuItem() {
const object = $('
')
object.text('Remove track')
- return {object, click: () => trackView.browser.removeTrack(trackView.track)}
+ function trackRemovalHandler(e) {
+ this.trackView.browser._removeTrack(this)
+ }
+
+ return { object, click:trackRemovalHandler }
}
function colorPickerMenuItem({trackView, label, option}) {
- const $e = $('
')
- $e.text(label)
+ const object = $('
')
+ object.text(label)
return {
- object: $e,
+ object,
click: () => trackView.presentColorPicker(option)
}
}
function unsetColorMenuItem({trackView, label}) {
- const $e = $('
')
- $e.text(label)
+ const object = $('
')
+ object.text(label)
return {
- object: $e,
+ object,
click: () => {
trackView.track.color = undefined
trackView.repaintViews()
@@ -242,78 +328,90 @@ function unsetAltColorMenuItem({trackView, label}) {
}
}
-function trackRenameMenuItem(trackView) {
+function trackRenameMenuItem() {
- const click = e => {
+ const object = $('
')
+ object.text('Set track name')
- const callback = function () {
- let value = trackView.browser.inputDialog.value
+ function click(e) {
+
+ const callback = () => {
+ let value = this.browser.inputDialog.value
value = ('' === value || undefined === value) ? 'untitled' : value.trim()
- trackView.track.name = value
+ this.name = value
}
const config =
{
label: 'Track Name',
- value: (getTrackLabelText(trackView.track) || 'unnamed'),
+ value: (getTrackLabelText(this) || 'unnamed'),
callback
}
- trackView.browser.inputDialog.present(config, e)
+ this.browser.inputDialog.present(config, e)
}
- const object = $('
')
- object.text('Set track name')
return {object, click}
}
-function trackHeightMenuItem(trackView) {
+function trackHeightMenuItem() {
+
+ const object = $('
')
+ object.text('Set track height')
- const click = e => {
+ function dialogHandler(e) {
const callback = () => {
- const number = Number(trackView.browser.inputDialog.value, 10)
+ const number = parseInt(this.browser.inputDialog.value, 10)
if (undefined !== number) {
- // If explicitly setting the height adust min or max, if neccessary.
- if (trackView.track.minHeight !== undefined && trackView.track.minHeight > number) {
- trackView.track.minHeight = number
- }
- if (trackView.track.maxHeight !== undefined && trackView.track.maxHeight < number) {
- trackView.track.minHeight = number
+ const tracks = []
+ if (isMultiSelectedTrackView(this.trackView)) {
+ tracks.push(...(getMultiSelectedTrackViews(this.trackView.browser).map(({ track }) => track)))
+ } else {
+ tracks.push(this)
}
- trackView.setTrackHeight(number, true)
- trackView.checkContentHeight()
- trackView.repaintViews()
+ for (const track of tracks) {
+ // If explicitly setting the height adjust min or max, if necessary
+ if (track.minHeight !== undefined && track.minHeight > number) {
+ track.minHeight = number
+ }
+ if (track.maxHeight !== undefined && track.maxHeight < number) {
+ track.minHeight = number
+ }
+ track.trackView.setTrackHeight(number, true)
- // Explicitly setting track height turns off autoHeight
- trackView.track.autoHeight = false
- }
+ track.trackView.checkContentHeight()
+ track.trackView.repaintViews()
- }
+ // Explicitly setting track height turns off autoHeight
+ track.trackView.autoHeight = false
+
+ } // for (tracks)
+
+ } // if (undefined !== number)
+
+ } // callback
const config =
{
label: 'Track Height',
- value: trackView.track.height,
+ value: this.height,
callback
}
- trackView.browser.inputDialog.present(config, e)
+ this.browser.inputDialog.present(config, e)
}
- const object = $('
')
- object.text('Set track height')
- return {object, click}
-
+ return { object, dialog:dialogHandler }
}
@@ -327,4 +425,31 @@ function getTrackLabelText(track) {
return txt
}
+function canShowColorPicker(track) {
+ return undefined === track.type || colorPickerTrackTypeSet.has(track.type)
+}
+
+function didSelectSingleTrackType(types) {
+ const unique = [ ...new Set(types) ]
+ return 1 === unique.length
+}
+
+function getMultiSelectedTrackViews(browser) {
+
+ const candidates = browser.trackViews.filter(({ track }) => { return false === multiTrackSelectExclusionTypes.has(track.type) })
+
+ let selected = candidates.filter(({ namespace, dragHandle }) => { return namespace === dragHandle.dataset.selected })
+
+ selected = 0 === selected.length ? undefined : selected
+
+ return selected
+}
+
+function isMultiSelectedTrackView(trackView) {
+ const selected = getMultiSelectedTrackViews(trackView.browser)
+ return selected && selected.length > 1 && new Set(selected).has(trackView)
+}
+
+export { canShowColorPicker, multiTrackSelectExclusionTypes, getMultiSelectedTrackViews, isMultiSelectedTrackView }
+
export default MenuUtils
diff --git a/js/ui/multiTrackSelectButton.js b/js/ui/multiTrackSelectButton.js
new file mode 100644
index 000000000..4a834e6d9
--- /dev/null
+++ b/js/ui/multiTrackSelectButton.js
@@ -0,0 +1,88 @@
+import NavbarButton from "./navbarButton.js"
+import {multiTrackSelectExclusionTypes} from './menuUtils.js'
+import {multiSelectImage, multiSelectImageHover} from "./navbarIcons/multiSelect.js"
+import { buttonLabel } from "./navbarIcons/buttonLabel.js"
+
+let ENABLE_MULTI_TRACK_SELECTION = false
+
+class MultiTrackSelectButton extends NavbarButton {
+ constructor(browser, parent) {
+
+ super(browser, parent, 'Select Tracks', buttonLabel, multiSelectImage, multiSelectImageHover, ENABLE_MULTI_TRACK_SELECTION)
+
+ this.button.addEventListener('mouseenter', event => {
+ if (false === ENABLE_MULTI_TRACK_SELECTION) {
+ this.setState(true)
+ }
+ })
+
+ this.button.addEventListener('mouseleave', event => {
+ if (false === ENABLE_MULTI_TRACK_SELECTION) {
+ this.setState(false)
+ }
+ })
+
+ const mouseClickHandler = () => {
+
+ ENABLE_MULTI_TRACK_SELECTION = !ENABLE_MULTI_TRACK_SELECTION
+
+ for (const trackView of this.browser.trackViews) {
+
+ if (false === multiTrackSelectExclusionTypes.has(trackView.track.type)) {
+
+ setMultiTrackSelectionState(trackView, trackView.axis, ENABLE_MULTI_TRACK_SELECTION)
+
+ } // if (false === multiTrackSelectExclusionTypes.has(trackView.track.type))
+
+ } // for (trackViews)
+
+ }
+
+ this.boundMouseClickHandler = mouseClickHandler.bind(this)
+
+ this.button.addEventListener('click', this.boundMouseClickHandler)
+
+ this.setVisibility(true)
+
+ }
+}
+
+function setMultiTrackSelectionState(trackView, axis, doEnableMultiSelection) {
+
+ const container = axis.querySelector('div')
+
+ if (true === doEnableMultiSelection) {
+ container.style.display = 'grid'
+ } else {
+
+ const trackSelectInput = container.querySelector('[name=track-select]')
+ trackSelectInput.checked = false
+
+ if (trackView.dragHandle) {
+ setDragHandleSelectionState(trackView, trackView.dragHandle, trackSelectInput.checked)
+ }
+
+ container.style.display = 'none'
+ }
+
+
+}
+
+function setDragHandleSelectionState(trackView, dragHandle, isSelected) {
+
+ if (isSelected) {
+ dragHandle.dataset.selected = trackView.namespace
+ dragHandle.classList.remove('igv-track-drag-handle-color')
+ dragHandle.classList.remove('igv-track-drag-handle-hover-color')
+ dragHandle.classList.add('igv-track-drag-handle-selected-color')
+ } else {
+ dragHandle.dataset.selected = 'no'
+ dragHandle.classList.remove('igv-track-drag-handle-hover-color')
+ dragHandle.classList.remove('igv-track-drag-handle-selected-color')
+ dragHandle.classList.add('igv-track-drag-handle-color')
+ }
+
+}
+
+export { ENABLE_MULTI_TRACK_SELECTION, setMultiTrackSelectionState, setDragHandleSelectionState }
+export default MultiTrackSelectButton
diff --git a/js/ui/navbarButton.js b/js/ui/navbarButton.js
new file mode 100644
index 000000000..31bfb3376
--- /dev/null
+++ b/js/ui/navbarButton.js
@@ -0,0 +1,138 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 University of California San Diego
+ * Author: Jim Robinson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+import {DOMUtils} from '../../node_modules/igv-ui/dist/igv-ui.js'
+
+class NavbarButton {
+
+ constructor(browser, parent, title, buttonLabel, imageSVG, imageHoverSVG, initialButtonState) {
+
+ this.browser = browser
+
+ this.button = DOMUtils.div({class: 'igv-navbar-text-button'})
+ parent.appendChild(this.button)
+
+ this.title = title
+
+ this.buttonLabel = buttonLabel
+
+ this.imageDictionary =
+ {
+ image: `url("data:image/svg+xml,${ encodeURIComponent(imageSVG) }")`,
+ imageHover: `url("data:image/svg+xml,${ encodeURIComponent(imageHoverSVG) }")`,
+ }
+
+ this.responsiveKey = 'text'
+
+ this.configureButton(title)
+
+ this.setState(initialButtonState)
+
+ browser.on('navbar-resize', navbarButtonCSSClass => {
+ const key = 'igv-navbar-icon-button' === navbarButtonCSSClass ? 'image' : 'text'
+ if (key !== this.responsiveKey) {
+ this.responsiveKey = key
+ this.configureButton(title)
+ this.setState(undefined)
+ }
+ })
+
+ }
+ configureButton(title) {
+
+ this.groupElement = undefined
+ this.button.innerHTML = ''
+ this.button.style.backgroundImage = 'none'
+ this.button.classList.remove('igv-navbar-icon-button')
+ this.button.classList.remove('igv-navbar-text-button')
+
+ 'text' === this.responsiveKey ? this.configureTextButton(title) : this.configureIconButton()
+
+ }
+
+ configureTextButton(title) {
+
+ this.button.classList.add('igv-navbar-text-button')
+
+ const tempDiv = document.createElement('div')
+ tempDiv.innerHTML = this.buttonLabel
+ const svgRoot = tempDiv.firstChild
+ this.button.appendChild(svgRoot)
+
+ this.groupElement = svgRoot.querySelector('#igv-navbar-button-group')
+
+ const tspanElement = svgRoot.querySelector('#igv-navbar-button-label')
+ tspanElement.textContent = title
+ }
+
+ configureIconButton() {
+ this.button.classList.add('igv-navbar-icon-button')
+ }
+
+ setState(doHover) {
+
+ if (undefined !== doHover) {
+ this.doHover = doHover
+ }
+
+ 'text' === this.responsiveKey ? this.setTextButtonState(this.doHover) : this.setIconButtonState(this.doHover)
+
+ }
+
+ setTextButtonState(doHover) {
+ this.groupElement.classList.remove(...this.groupElement.classList)
+ const className = true === doHover ? 'igv-navbar-text-button-svg-hover' : 'igv-navbar-text-button-svg-inactive'
+ this.groupElement.classList.add(className)
+ }
+
+ setIconButtonState(doHover) {
+ this.button.style.backgroundImage = true === doHover ? this.imageDictionary.imageHover : this.imageDictionary.image
+ }
+
+ show() {
+ // this.button.style.display = 'block'
+ this.button.style.display = 'flex'
+ }
+
+ hide() {
+ this.button.style.display = 'none'
+ }
+
+ setVisibility(isVisible) {
+ if (true === isVisible) {
+ this.show()
+ } else {
+ this.hide()
+ }
+ }
+
+ static currentNavbarButtonClass(browser) {
+ const el = browser.$navigation.get(0).querySelector('.igv-navbar-text-button')
+ return el ? 'igv-navbar-text-button' : 'igv-navbar-icon-button'
+ }
+}
+
+export default NavbarButton
diff --git a/js/ui/navbarIcons/buttonLabel.js b/js/ui/navbarIcons/buttonLabel.js
new file mode 100644
index 000000000..c29d7f7a9
--- /dev/null
+++ b/js/ui/navbarIcons/buttonLabel.js
@@ -0,0 +1,26 @@
+
+const buttonLabel =
+ `
+
+
+
+
+
+
+
+
+ `
+
+const sampleNameButtonLabel =
+ `
+
+
+
+
+
+
+
+
+ `
+
+export { buttonLabel, sampleNameButtonLabel }
diff --git a/js/ui/navbarIcons/centerline.js b/js/ui/navbarIcons/centerline.js
new file mode 100644
index 000000000..dc030f6a1
--- /dev/null
+++ b/js/ui/navbarIcons/centerline.js
@@ -0,0 +1,23 @@
+const centerlineImage =
+ `
+ centerline
+
+
+
+
+
+
+ `
+
+const centerlineImageHover =
+ `
+ centerline hover
+
+
+
+
+
+
+ `
+
+export { centerlineImage, centerlineImageHover }
diff --git a/js/ui/navbarIcons/cursor.js b/js/ui/navbarIcons/cursor.js
new file mode 100644
index 000000000..eebae6d78
--- /dev/null
+++ b/js/ui/navbarIcons/cursor.js
@@ -0,0 +1,31 @@
+const cursorImage =
+ `
+ cursor
+
+
+
+
+
+
+
+
+
+
+ `
+
+const cursorImageHover =
+ `
+ cursor hover
+
+
+
+
+
+
+
+
+
+
+ `
+
+export { cursorImage, cursorImageHover }
diff --git a/js/ui/navbarIcons/multiSelect.js b/js/ui/navbarIcons/multiSelect.js
new file mode 100644
index 000000000..c240c3502
--- /dev/null
+++ b/js/ui/navbarIcons/multiSelect.js
@@ -0,0 +1,45 @@
+const multiSelectImage =
+ `
+ multi select
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+
+const multiSelectImageHover =
+ `
+ multi select hover
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+
+export { multiSelectImage, multiSelectImageHover }
diff --git a/js/ui/navbarIcons/roi.js b/js/ui/navbarIcons/roi.js
new file mode 100644
index 000000000..378dfe8d4
--- /dev/null
+++ b/js/ui/navbarIcons/roi.js
@@ -0,0 +1,27 @@
+const roiImage =
+ `
+ roi
+
+
+
+
+ ROI
+
+
+
+ `
+
+const roiImageHover =
+ `
+ roi hover
+
+
+
+
+ ROI
+
+
+
+ `
+
+export { roiImage, roiImageHover }
diff --git a/js/ui/navbarIcons/sampleInfo.js b/js/ui/navbarIcons/sampleInfo.js
new file mode 100644
index 000000000..62ec52ceb
--- /dev/null
+++ b/js/ui/navbarIcons/sampleInfo.js
@@ -0,0 +1,72 @@
+const sampleInfoImage =
+ `
+ sample info
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+
+const sampleInfoImageHover =
+ `
+ sample info hover
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ `
+
+export { sampleInfoImage, sampleInfoImageHover }
diff --git a/js/ui/navbarIcons/sampleNames.js b/js/ui/navbarIcons/sampleNames.js
new file mode 100644
index 000000000..6f230afd9
--- /dev/null
+++ b/js/ui/navbarIcons/sampleNames.js
@@ -0,0 +1,27 @@
+const sampleNameImage =
+ `
+ sample names
+
+
+
+
+
+
+
+
+ `
+
+const sampleNameImageHover =
+ `
+ sample names hover
+
+
+
+
+
+
+
+
+ `
+
+export { sampleNameImage, sampleNameImageHover }
diff --git a/js/ui/navbarIcons/saveImage.js b/js/ui/navbarIcons/saveImage.js
new file mode 100644
index 000000000..ced39965b
--- /dev/null
+++ b/js/ui/navbarIcons/saveImage.js
@@ -0,0 +1,165 @@
+// DEPRICATED
+const imageSaveTextSVG =
+ `
+ save image text - LATEST
+
+
+
+
+
+ PNG
+
+
+
+
+
+ SVG
+
+
+
+
+
+ Sample Names
+
+
+
+
+ `
+// ------------
+
+// Icon Button
+const imageSaveImageSVG =
+ `
+ save image
+
+
+
+
+
+ Save
+
+
+
+ `
+
+const imageSaveImageHoverSVG =
+ `
+ save image hover
+
+
+
+
+
+ Save
+
+
+
+ `
+
+// Child SVG for Icon - PNG
+const pngImage =
+ `
+ PNG
+
+
+
+
+ PNG
+
+
+
+ `
+
+const pngHoverImage =
+ `
+ PNG hover
+
+
+
+
+ PNG
+
+
+
+ `
+
+// Child SVG for Icon Button - SVG
+const svgImage =
+ `
+ SVG
+
+
+
+
+ SVG
+
+
+
+ `
+
+const svgHoverImage =
+ `
+ SVG hover
+
+
+
+
+ SVG
+
+
+
+ `
+
+// Child SVG for Text Button - PNG
+const pngText =
+ `
+ png text
+
+
+
+
+ PNG
+
+
+
+ `
+
+const pngTextHover =
+ `
+ png text hover
+
+
+
+
+ PNG
+
+
+
+ `
+
+const svgText =
+ `
+
+
+
+
+ SVG
+
+
+
+ `
+const svgTextHover =
+ `
+
+
+
+
+ SVG
+
+
+
+ `
+
+export { imageSaveImageSVG, imageSaveImageHoverSVG, imageSaveTextSVG }
+export { pngImage, pngHoverImage, svgImage, svgHoverImage }
+export { pngText, pngTextHover, svgText, svgTextHover }
diff --git a/js/ui/navbarIcons/trackLabels.js b/js/ui/navbarIcons/trackLabels.js
new file mode 100644
index 000000000..946a4f8b1
--- /dev/null
+++ b/js/ui/navbarIcons/trackLabels.js
@@ -0,0 +1,29 @@
+const trackLabelsImage =
+ `
+ track labels
+
+
+
+
+
+
+
+
+
+ `
+
+const trackLabelsImageHover =
+ `
+ track labels hover
+
+
+
+
+
+
+
+
+
+ `
+
+export { trackLabelsImage, trackLabelsImageHover }
diff --git a/js/ui/roiTableControl.js b/js/ui/roiTableControl.js
deleted file mode 100644
index 0c7a26886..000000000
--- a/js/ui/roiTableControl.js
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * The MIT License (MIT)
- *
- * Copyright (c) 2016 University of California San Diego
- * Author: Jim Robinson
- *
- * Permission is hereby granted, free of charge, to any person obtaining a copy
- * of this software and associated documentation files (the "Software"), to deal
- * in the Software without restriction, including without limitation the rights
- * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
- * copies of the Software, and to permit persons to whom the Software is
- * furnished to do so, subject to the following conditions:
- *
- * The above copyright notice and this permission notice shall be included in
- * all copies or substantial portions of the Software.
- *
- *
- * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
- * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
- * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
- * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
- * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
- * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
- * THE SOFTWARE.
- */
-
-import {DOMUtils} from '../../node_modules/igv-ui/dist/igv-ui.js'
-
-class ROITableControl {
-
- constructor(parent, browser) {
- this.browser = browser
- this.button = DOMUtils.div({class: 'igv-navbar-button'})
- parent.appendChild(this.button)
- this.button.textContent = 'ROI Table'
-
- this.button.addEventListener('click', () => {
- this.buttonHandler(!browser.roiTableVisible)
- })
-
- this.browser = browser
-
- this.setVisibility(browser.showROITableButton)
-
- this.setState(browser.roiTableVisible)
- }
-
- buttonHandler(status) {
- this.browser.roiTableVisible = status
- this.setState(this.browser.roiTableVisible)
- this.browser.setROITableVisibility(this.browser.roiTableVisible)
- }
-
- setVisibility(doShowROITablelButton) {
- if (true === doShowROITablelButton) {
- this.show()
- } else {
- this.hide()
- }
- }
-
- setState(roiTableVisible) {
- if (true === roiTableVisible) {
- this.button.classList.add('igv-navbar-button-clicked')
- } else {
- this.button.classList.remove('igv-navbar-button-clicked')
- }
- }
-
- show() {
- this.button.style.display = 'block'
- this.setState(this.browser.roiTableVisible)
- }
-
- hide() {
- this.button.style.display = 'none'
- }
-}
-
-
-export default ROITableControl
diff --git a/js/ui/saveImageControl.js b/js/ui/saveImageControl.js
new file mode 100644
index 000000000..959a8847f
--- /dev/null
+++ b/js/ui/saveImageControl.js
@@ -0,0 +1,129 @@
+/*
+ * The MIT License (MIT)
+ *
+ * Copyright (c) 2016 University of California San Diego
+ * Author: Jim Robinson
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a copy
+ * of this software and associated documentation files (the "Software"), to deal
+ * in the Software without restriction, including without limitation the rights
+ * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+ * copies of the Software, and to permit persons to whom the Software is
+ * furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be included in
+ * all copies or substantial portions of the Software.
+ *
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+ * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+ * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+ * THE SOFTWARE.
+ */
+
+import {DOMUtils} from '../../node_modules/igv-ui/dist/igv-ui.js'
+import NavbarButton from "./navbarButton.js"
+
+// Icon Button SVG
+import { imageSaveImageSVG, imageSaveImageHoverSVG } from './navbarIcons/saveImage.js'
+
+// Icon Button child SVG for PNG and SVG
+import { pngImage, pngHoverImage, svgImage, svgHoverImage } from './navbarIcons/saveImage.js'
+
+// Text Button child SVG for PNG and SVG
+import { pngText, pngTextHover, svgText, svgTextHover } from './navbarIcons/saveImage.js'
+
+const pngImageURL = `url("data:image/svg+xml,${ encodeURIComponent(pngImage) }")`
+const svgImageURL = `url("data:image/svg+xml,${ encodeURIComponent(svgImage) }")`
+
+const pngHoverImageURL = `url("data:image/svg+xml,${ encodeURIComponent(pngHoverImage) }")`
+const svgHoverImageURL = `url("data:image/svg+xml,${ encodeURIComponent(svgHoverImage) }")`
+
+const pngTextURL = `url("data:image/svg+xml,${ encodeURIComponent(pngText) }")`
+const svgTextURL = `url("data:image/svg+xml,${ encodeURIComponent(svgText) }")`
+
+const pngHoverTextURL = `url("data:image/svg+xml,${ encodeURIComponent(pngTextHover) }")`
+const svgHoverTextURL = `url("data:image/svg+xml,${ encodeURIComponent(svgTextHover) }")`
+
+import { buttonLabel } from "./navbarIcons/buttonLabel.js"
+
+class SaveImageControl extends NavbarButton {
+ constructor(parent, browser) {
+
+ super(browser, parent, 'Save Image', buttonLabel, imageSaveImageSVG, imageSaveImageHoverSVG, false)
+
+ this.button.addEventListener('mouseenter', () => this.setState(true))
+
+ this.button.addEventListener('mouseleave', () => {
+
+ for (const el of this.button.querySelectorAll('div')) {
+ if('block' === el.style.display) {
+ return
+ }
+ }
+
+ this.setState(false)
+ })
+
+ this.button.addEventListener('click', () => {
+ for (const el of this.button.querySelectorAll('div')) {
+ el.style.display = 'none' === el.style.display ? 'block' : 'none'
+ }
+ })
+
+ this.setVisibility(browser.config.showSVGButton)
+
+ }
+
+ configureTextButton(title) {
+ super.configureTextButton(title)
+ this.configureSVG(svgTextURL, svgHoverTextURL, pngTextURL, pngHoverTextURL)
+ }
+
+ configureIconButton() {
+ this.button.classList.add('igv-navbar-icon-button')
+ this.configureSVG(svgImageURL, svgHoverImageURL, pngImageURL, pngHoverImageURL)
+ }
+
+ configureSVG(svgURL, svgHoverURL, pngURL, pngHoverURL) {
+
+ // save svg image
+ const svgElement = DOMUtils.div()
+ this.button.appendChild(svgElement)
+ svgElement.style.backgroundImage = svgURL
+
+ svgElement.addEventListener('click', () => {
+ this.browser.saveSVGtoFile({})
+ this.setState(false)
+ })
+
+ svgElement.addEventListener('mouseenter', () => svgElement.style.backgroundImage = svgHoverURL)
+
+ svgElement.addEventListener('mouseleave', () => svgElement.style.backgroundImage = svgURL)
+
+ svgElement.style.display = 'none'
+
+ // save png image
+ const pngElement = DOMUtils.div()
+ this.button.appendChild(pngElement)
+ pngElement.style.backgroundImage = pngURL
+
+ pngElement.addEventListener('click', e => {
+ this.browser.savePNGtoFile(undefined)
+ this.setState(false)
+ })
+
+ pngElement.addEventListener('mouseenter', () => pngElement.style.backgroundImage = pngHoverURL)
+
+ pngElement.addEventListener('mouseleave', () => pngElement.style.backgroundImage = pngURL)
+
+ pngElement.style.display = 'none'
+
+ }
+
+}
+
+export default SaveImageControl
diff --git a/js/ui/trackLabelControl.js b/js/ui/trackLabelControl.js
index e8c6aa345..adc43cfab 100644
--- a/js/ui/trackLabelControl.js
+++ b/js/ui/trackLabelControl.js
@@ -24,53 +24,42 @@
* THE SOFTWARE.
*/
-import {DOMUtils} from '../../node_modules/igv-ui/dist/igv-ui.js'
+import NavbarButton from "./navbarButton.js"
+import {trackLabelsImage, trackLabelsImageHover} from "./navbarIcons/trackLabels.js"
+import { buttonLabel } from "./navbarIcons/buttonLabel.js"
-class TrackLabelControl {
+class TrackLabelControl extends NavbarButton {
constructor(parent, browser) {
- this.button = DOMUtils.div({class: 'igv-navbar-button'})
- parent.appendChild(this.button)
- this.button.textContent = 'track labels'
+ super(browser, parent, 'Track Labels', buttonLabel, trackLabelsImage, trackLabelsImageHover, browser.config.showTrackLabels)
- this.button.addEventListener('click', () => {
- browser.trackLabelsVisible = !browser.trackLabelsVisible
- this.setState(browser.trackLabelsVisible)
- browser.setTrackLabelVisibility(browser.trackLabelsVisible)
+ this.button.addEventListener('mouseenter', () => {
+ if (false === browser.doShowTrackLabels) {
+ this.setState(true)
+ }
})
- this.browser = browser
+ this.button.addEventListener('mouseleave', () => {
+ if (false === browser.doShowTrackLabels) {
+ this.setState(false)
+ }
+ })
- this.setVisibility(browser.config.showTrackLabelButton)
+ const mouseClickHandler = () => {
+ browser.doShowTrackLabels = !browser.doShowTrackLabels
+ browser.setTrackLabelVisibility(browser.doShowTrackLabels)
+ this.setState(browser.doShowTrackLabels)
+ }
- this.setState(browser.trackLabelsVisible)
- }
+ this.boundMouseClickHandler = mouseClickHandler.bind(this)
- setVisibility(showTrackLabelButton) {
- if (true === showTrackLabelButton) {
- this.show()
- } else {
- this.hide()
- }
- }
+ this.button.addEventListener('click', this.boundMouseClickHandler)
- setState(trackLabelsVisible) {
- if (true === trackLabelsVisible) {
- this.button.classList.add('igv-navbar-button-clicked')
- } else {
- this.button.classList.remove('igv-navbar-button-clicked')
- }
- }
+ this.setVisibility(browser.config.showTrackLabelButton)
- show() {
- this.button.style.display = 'block'
- this.setState(this.browser.trackLabelsVisible)
}
- hide() {
- this.button.style.display = 'none'
- }
}
export default TrackLabelControl
diff --git a/js/ui/viewportCenterLine.js b/js/ui/viewportCenterLine.js
index 520c9c4a2..695d800af 100644
--- a/js/ui/viewportCenterLine.js
+++ b/js/ui/viewportCenterLine.js
@@ -37,7 +37,7 @@ class ViewportCenterLine {
this.container = DOMUtils.div({class: 'igv-center-line'})
column.appendChild(this.container)
- if (browser.isCenterLineVisible) {
+ if (browser.doShowCenterLine) {
this.show()
} else {
this.hide()
diff --git a/js/util/colorPalletes.js b/js/util/colorPalletes.js
index 0f1508cd8..9731e893c 100644
--- a/js/util/colorPalletes.js
+++ b/js/util/colorPalletes.js
@@ -1,5 +1,27 @@
import {IGVMath} from "../../node_modules/igv-utils/src/index.js"
+function hexToRGB(hex) {
+ // Ensure the hex value is in the proper format
+ hex = hex.replace(/^#/, '');
+
+ // If it's a shorthand hex color (like #f06), double each character
+ if (hex.length === 3) {
+ hex = hex.split('').map(char => char + char).join('');
+ }
+
+ if (hex.length !== 6) {
+ throw new Error('Invalid HEX color.');
+ }
+
+ // Parse the r, g, b values
+ let bigint = parseInt(hex, 16);
+ let r = (bigint >> 16) & 255;
+ let g = (bigint >> 8) & 255;
+ let b = bigint & 255;
+
+ return `rgb(${r}, ${g}, ${b})`;
+}
+
const appleCrayonPalette =
{
licorice: "#000000",
@@ -117,6 +139,41 @@ function appleCrayonRGBA(name, alpha) {
return `rgba(${r},${g},${b},${alpha})`
}
+const webColorRGBPalette =
+ {
+ white: 'rgb(255, 255, 255)',
+ silver: 'rgb(192, 192, 192)',
+ grey: 'rgb(128, 128, 128)',
+ black: 'rgb(0, 0, 0)',
+ red: 'rgb(255, 0, 0)',
+ maroon: 'rgb(128, 0, 0)',
+ yellow: 'rgb(255, 255, 0)',
+ olive: 'rgb(128, 128, 0)',
+ lime: 'rgb(0, 255, 0)',
+ green: 'rgb(0, 128, 0)',
+ aqua: 'rgb(0, 255, 255)',
+ teal: 'rgb(0, 128, 128)',
+ blue: 'rgb(0, 0, 255)',
+ navy: 'rgb(0, 0, 128)',
+ fuchsia: 'rgb(255, 0, 255)',
+ purple: 'rgb(128, 0, 128)',
+ }
+
+function isValidColorName(name) {
+ const a = new Set(Object.keys(webColorRGBPalette))
+ const b = new Set(Object.keys(appleCrayonPalette))
+ return a.has(name) || b.has(name)
+}
+
+function getColorNameRGBString(name) {
+
+ if (isValidColorName(name)) {
+ return webColorRGBPalette[ name ] || appleCrayonRGB(name)
+ } else {
+ return undefined
+ }
+}
+
const colorPalettes = {
Set1:
@@ -469,6 +526,8 @@ export {
appleCrayonRGB,
appleCrayonRGBA,
appleCrayonPalette,
+ isValidColorName,
+ getColorNameRGBString,
ColorTable,
PaletteColorTable,
randomColor,
@@ -481,5 +540,6 @@ export {
rgbaStringTokens,
rgbStringTokens,
rgbStringLerp,
- rgbStringHeatMapLerp
+ rgbStringHeatMapLerp,
+ hexToRGB
}
diff --git a/js/util/paintAxis.js b/js/util/paintAxis.js
index 199f3ee02..364fe9ab2 100644
--- a/js/util/paintAxis.js
+++ b/js/util/paintAxis.js
@@ -22,7 +22,8 @@ function paintAxis(ctx, pixelWidth, pixelHeight) {
let flipAxis = (undefined === this.flipAxis) ? false : this.flipAxis
- IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"})
+ // IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgb(255, 255, 255)"})
+ IGVGraphics.fillRect(ctx, 0, 0, pixelWidth, pixelHeight, {'fillStyle': "rgba(255, 255, 255, 0)"})
reference = 0.95 * pixelWidth
x1 = reference - 8
diff --git a/js/variant/variantTrack.js b/js/variant/variantTrack.js
index e7c30f184..628ebe1ff 100644
--- a/js/variant/variantTrack.js
+++ b/js/variant/variantTrack.js
@@ -564,9 +564,8 @@ class VariantTrack extends TrackBase {
menuItems.push({object: $('