From bd71cd39ba5a59de248562382ff7bb4c64f1660b Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 9 Jan 2023 12:14:52 -0700 Subject: [PATCH 1/2] [skip ci] Human vs mouse synteny --- .../src/ChainAdapter/ChainAdapter.ts | 161 +----------------- .../src/ChainAdapter/util.ts | 159 +++++++++++++++++ .../src/DeltaAdapter/DeltaAdapter.ts | 134 +-------------- .../src/DeltaAdapter/util.ts | 132 ++++++++++++++ products/jbrowse-web/src/Loader.tsx | 1 + test_data/human_vs_mouse.json | 100 +++++++++++ 6 files changed, 394 insertions(+), 293 deletions(-) create mode 100644 plugins/comparative-adapters/src/ChainAdapter/util.ts create mode 100644 plugins/comparative-adapters/src/DeltaAdapter/util.ts create mode 100644 test_data/human_vs_mouse.json diff --git a/plugins/comparative-adapters/src/ChainAdapter/ChainAdapter.ts b/plugins/comparative-adapters/src/ChainAdapter/ChainAdapter.ts index d99104e82e..c19f436f3e 100644 --- a/plugins/comparative-adapters/src/ChainAdapter/ChainAdapter.ts +++ b/plugins/comparative-adapters/src/ChainAdapter/ChainAdapter.ts @@ -2,171 +2,12 @@ import { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter' import { openLocation } from '@jbrowse/core/util/io' import { unzip } from '@gmod/bgzf-filehandle' import PAFAdapter from '../PAFAdapter/PAFAdapter' +import { paf_chain2paf } from './util' function isGzip(buf: Buffer) { return buf[0] === 31 && buf[1] === 139 && buf[2] === 8 } -/* adapted from chain2paf by Andrea Guarracino, license reproduced below - * - * MIT License - * - * Copyright (c) 2021 Andrea Guarracino - * - * 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. - */ - -function generate_record( - qname: string, - qstart: number, - qend: number, - qstrand: string, - tname: string, - tstart: number, - tend: number, - cigar: string, - numMatches: number, -) { - return { - qname, - qstart, - qend, - tname, - tstart, - tend, - strand: qstrand === '-' ? -1 : 1, - extra: { - numMatches, - blockLen: Math.max(qend - qstart, tend - tstart), - mappingQual: 0, - cg: cigar, - }, - } -} - -function paf_chain2paf(lines: string[]) { - let t_name = '' - let t_start = 0 - let t_end = 0 - let q_name = '' - let q_size = '' - let q_strand = '' - let q_start = 0 - let q_end = 0 - let num_matches = 0 - let cigar = '' - const records = [] - for (let i = 0; i < lines.length; i++) { - const l = lines[i] - const l_tab = l.replace(/ /g, '\t') // There are CHAIN files with space-separated fields - const l_vec = l_tab.split('\t') - - if (l_vec[0] === 'chain') { - // Emit previous PAF row, if available - if (cigar) { - records.push( - generate_record( - q_name, - q_start, - q_end, - q_strand, - t_name, - t_start, - t_end, - cigar, - num_matches, - ), - ) - } - - // Save query/target information - // score -- chain score - // tName -- chromosome (reference sequence) - // tSize -- chromosome size (reference sequence) - // tStrand -- strand (reference sequence) - // tStart -- alignment start position (reference sequence) - // tEnd -- alignment end position (reference sequence) - // qName -- chromosome (query sequence) - // qSize -- chromosome size (query sequence) - // qStrand -- strand (query sequence) - // qStart -- alignment start position (query sequence) - // qEnd -- alignment end position (query sequence) - // id -- chain ID - t_name = l_vec[2] - t_start = +l_vec[5] - t_end = +l_vec[6] - q_name = l_vec[7] - q_size = l_vec[8] - q_strand = l_vec[9] - q_start = +l_vec[10] - q_end = +l_vec[11] - if (q_strand === '-') { - const tmp = q_start - q_start = +q_size - q_end - q_end = +q_size - tmp - } - - // Initialize PAF fields - num_matches = 0 - cigar = '' - } else { - // size -- the size of the ungapped alignment - // - // dt -- the difference between the end of this block and the beginning - // of the next block (reference sequence) - // - // dq -- the difference between the end of this block and the beginning - // of the next block (query sequence) - const size_ungapped_alignment = +l_vec[0] || 0 - const diff_in_target = l_vec.length > 1 ? +l_vec[1] : 0 - const diff_in_query = l_vec.length > 2 ? +l_vec[2] : 0 - - if (size_ungapped_alignment !== 0) { - num_matches += +size_ungapped_alignment - cigar += size_ungapped_alignment + 'M' - } - if (diff_in_query !== 0) { - cigar += diff_in_query + 'I' - } - if (diff_in_target !== 0) { - cigar += diff_in_target + 'D' - } - } - } - - // Emit last PAF row, if available - if (cigar) { - generate_record( - q_name, - q_start, - q_end, - q_strand, - t_name, - t_start, - t_end, - cigar, - num_matches, - ) - } - return records -} - export default class ChainAdapter extends PAFAdapter { async setupPre(opts?: BaseOptions) { const loc = openLocation(this.getConf('chainLocation'), this.pluginManager) diff --git a/plugins/comparative-adapters/src/ChainAdapter/util.ts b/plugins/comparative-adapters/src/ChainAdapter/util.ts new file mode 100644 index 0000000000..20b2c61ced --- /dev/null +++ b/plugins/comparative-adapters/src/ChainAdapter/util.ts @@ -0,0 +1,159 @@ +/* adapted from chain2paf by Andrea Guarracino, license reproduced below + * + * MIT License + * + * Copyright (c) 2021 Andrea Guarracino + * + * 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. + */ + +function generate_record( + qname: string, + qstart: number, + qend: number, + qstrand: string, + tname: string, + tstart: number, + tend: number, + cigar: string, + numMatches: number, +) { + return { + qname, + qstart, + qend, + tname, + tstart, + tend, + strand: qstrand === '-' ? -1 : 1, + extra: { + numMatches, + blockLen: Math.max(qend - qstart, tend - tstart), + mappingQual: 0, + cg: cigar, + }, + } +} + +export function paf_chain2paf(lines: string[]) { + let t_name = '' + let t_start = 0 + let t_end = 0 + let q_name = '' + let q_size = '' + let q_strand = '' + let q_start = 0 + let q_end = 0 + let num_matches = 0 + let cigar = '' + const records = [] + for (let i = 0; i < lines.length; i++) { + const l = lines[i] + const l_tab = l.replace(/ /g, '\t') // There are CHAIN files with space-separated fields + const l_vec = l_tab.split('\t') + + if (l_vec[0] === 'chain') { + // Emit previous PAF row, if available + if (cigar) { + records.push( + generate_record( + q_name, + q_start, + q_end, + q_strand, + t_name, + t_start, + t_end, + cigar, + num_matches, + ), + ) + } + + // Save query/target information + // score -- chain score + // tName -- chromosome (reference sequence) + // tSize -- chromosome size (reference sequence) + // tStrand -- strand (reference sequence) + // tStart -- alignment start position (reference sequence) + // tEnd -- alignment end position (reference sequence) + // qName -- chromosome (query sequence) + // qSize -- chromosome size (query sequence) + // qStrand -- strand (query sequence) + // qStart -- alignment start position (query sequence) + // qEnd -- alignment end position (query sequence) + // id -- chain ID + t_name = l_vec[2] + t_start = +l_vec[5] + t_end = +l_vec[6] + q_name = l_vec[7] + q_size = l_vec[8] + q_strand = l_vec[9] + q_start = +l_vec[10] + q_end = +l_vec[11] + if (q_strand === '-') { + const tmp = q_start + q_start = +q_size - q_end + q_end = +q_size - tmp + } + + // Initialize PAF fields + num_matches = 0 + cigar = '' + } else { + // size -- the size of the ungapped alignment + // + // dt -- the difference between the end of this block and the beginning + // of the next block (reference sequence) + // + // dq -- the difference between the end of this block and the beginning + // of the next block (query sequence) + const size_ungapped_alignment = +l_vec[0] || 0 + const diff_in_target = l_vec.length > 1 ? +l_vec[1] : 0 + const diff_in_query = l_vec.length > 2 ? +l_vec[2] : 0 + + if (size_ungapped_alignment !== 0) { + num_matches += +size_ungapped_alignment + cigar += size_ungapped_alignment + 'M' + } + if (diff_in_query !== 0) { + cigar += diff_in_query + 'I' + } + if (diff_in_target !== 0) { + cigar += diff_in_target + 'D' + } + } + } + + // Emit last PAF row, if available + if (cigar) { + generate_record( + q_name, + q_start, + q_end, + q_strand, + t_name, + t_start, + t_end, + cigar, + num_matches, + ) + } + return records +} diff --git a/plugins/comparative-adapters/src/DeltaAdapter/DeltaAdapter.ts b/plugins/comparative-adapters/src/DeltaAdapter/DeltaAdapter.ts index 5ab5139f20..48fe926ad9 100644 --- a/plugins/comparative-adapters/src/DeltaAdapter/DeltaAdapter.ts +++ b/plugins/comparative-adapters/src/DeltaAdapter/DeltaAdapter.ts @@ -2,144 +2,12 @@ import { BaseOptions } from '@jbrowse/core/data_adapters/BaseAdapter' import { openLocation } from '@jbrowse/core/util/io' import { unzip } from '@gmod/bgzf-filehandle' import PAFAdapter from '../PAFAdapter/PAFAdapter' +import { paf_delta2paf } from './util' function isGzip(buf: Buffer) { return buf[0] === 31 && buf[1] === 139 && buf[2] === 8 } -/* paf2delta from paftools.js in the minimap2 repository, license reproduced below - * - * The MIT License - * - * Copyright (c) 2018- Dana-Farber Cancer Institute - * 2017-2018 Broad Institute, Inc. - * - * 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. - */ - -function paf_delta2paf(lines: string[]) { - let rname = '' - let qname = '' - let qs = 0 - let qe = 0 - let rs = 0 - let re = 0 - let strand = 0 - let NM = 0 - let cigar = [] as number[] - let x = 0 - let y = 0 - let seen_gt = false - - const records = [] - const regex = new RegExp(/^>(\S+)\s+(\S+)\s+(\d+)\s+(\d+)/) - for (let i = 0; i < lines.length; i++) { - const line = lines[i] - const m = regex.exec(line) - if (m !== null) { - rname = m[1] - qname = m[2] - seen_gt = true - continue - } - if (!seen_gt) { - continue - } - const t = line.split(' ') - if (t.length === 7) { - const t0 = +t[0] - const t1 = +t[1] - const t2 = +t[2] - const t3 = +t[3] - const t4 = +t[4] - strand = (t0 < t1 && t2 < t3) || (t0 > t1 && t2 > t3) ? 1 : -1 - rs = +(t0 < t1 ? t0 : t1) - 1 - re = +(t1 > t0 ? t1 : t0) - qs = +(t2 < t3 ? t2 : t3) - 1 - qe = +(t3 > t2 ? t3 : t2) - x = y = 0 - NM = t4 - cigar = [] - } else if (t.length === 1) { - const d = +t[0] - if (d === 0) { - let blen = 0 - const cigar_str = [] - - if (re - rs - x !== qe - qs - y) { - throw new Error(`inconsistent alignment on line ${i}`) - } - cigar.push((re - rs - x) << 4) - for (let i = 0; i < cigar.length; ++i) { - const rlen = cigar[i] >> 4 - blen += rlen - cigar_str.push(rlen + 'MID'.charAt(cigar[i] & 0xf)) - } - - records.push({ - qname, - qstart: qs, - qend: qe, - tname: rname, - tstart: rs, - tend: re, - strand, - extra: { - numMatches: blen - NM, - blockLen: blen, - mappingQual: 0, - NM, - cg: cigar_str.join(''), - }, - }) - } else if (d > 0) { - const l = d - 1 - x += l + 1 - y += l - if (l > 0) { - cigar.push(l << 4) - } - if (cigar.length > 0 && (cigar[cigar.length - 1] & 0xf) === 2) { - cigar[cigar.length - 1] += 1 << 4 - } else { - cigar.push((1 << 4) | 2) - } // deletion - } else { - const l = -d - 1 - x += l - y += l + 1 - if (l > 0) { - cigar.push(l << 4) - } - if (cigar.length > 0 && (cigar[cigar.length - 1] & 0xf) === 1) { - cigar[cigar.length - 1] += 1 << 4 - } else { - cigar.push((1 << 4) | 1) - } // insertion - } - } - } - return records -} - export default class DeltaAdapter extends PAFAdapter { async setupPre(opts?: BaseOptions) { const loc = openLocation(this.getConf('deltaLocation'), this.pluginManager) diff --git a/plugins/comparative-adapters/src/DeltaAdapter/util.ts b/plugins/comparative-adapters/src/DeltaAdapter/util.ts new file mode 100644 index 0000000000..3caf30b887 --- /dev/null +++ b/plugins/comparative-adapters/src/DeltaAdapter/util.ts @@ -0,0 +1,132 @@ +/* paf2delta from paftools.js in the minimap2 repository, license reproduced below + * + * The MIT License + * + * Copyright (c) 2018- Dana-Farber Cancer Institute + * 2017-2018 Broad Institute, Inc. + * + * 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. + */ + +export function paf_delta2paf(lines: string[]) { + let rname = '' + let qname = '' + let qs = 0 + let qe = 0 + let rs = 0 + let re = 0 + let strand = 0 + let NM = 0 + let cigar = [] as number[] + let x = 0 + let y = 0 + let seen_gt = false + + const records = [] + const regex = new RegExp(/^>(\S+)\s+(\S+)\s+(\d+)\s+(\d+)/) + for (let i = 0; i < lines.length; i++) { + const line = lines[i] + const m = regex.exec(line) + if (m !== null) { + rname = m[1] + qname = m[2] + seen_gt = true + continue + } + if (!seen_gt) { + continue + } + const t = line.split(' ') + if (t.length === 7) { + const t0 = +t[0] + const t1 = +t[1] + const t2 = +t[2] + const t3 = +t[3] + const t4 = +t[4] + strand = (t0 < t1 && t2 < t3) || (t0 > t1 && t2 > t3) ? 1 : -1 + rs = +(t0 < t1 ? t0 : t1) - 1 + re = +(t1 > t0 ? t1 : t0) + qs = +(t2 < t3 ? t2 : t3) - 1 + qe = +(t3 > t2 ? t3 : t2) + x = y = 0 + NM = t4 + cigar = [] + } else if (t.length === 1) { + const d = +t[0] + if (d === 0) { + let blen = 0 + const cigar_str = [] + + if (re - rs - x !== qe - qs - y) { + throw new Error(`inconsistent alignment on line ${i}`) + } + cigar.push((re - rs - x) << 4) + for (let i = 0; i < cigar.length; ++i) { + const rlen = cigar[i] >> 4 + blen += rlen + cigar_str.push(rlen + 'MID'.charAt(cigar[i] & 0xf)) + } + + records.push({ + qname, + qstart: qs, + qend: qe, + tname: rname, + tstart: rs, + tend: re, + strand, + extra: { + numMatches: blen - NM, + blockLen: blen, + mappingQual: 0, + NM, + cg: cigar_str.join(''), + }, + }) + } else if (d > 0) { + const l = d - 1 + x += l + 1 + y += l + if (l > 0) { + cigar.push(l << 4) + } + if (cigar.length > 0 && (cigar[cigar.length - 1] & 0xf) === 2) { + cigar[cigar.length - 1] += 1 << 4 + } else { + cigar.push((1 << 4) | 2) + } // deletion + } else { + const l = -d - 1 + x += l + y += l + 1 + if (l > 0) { + cigar.push(l << 4) + } + if (cigar.length > 0 && (cigar[cigar.length - 1] & 0xf) === 1) { + cigar[cigar.length - 1] += 1 << 4 + } else { + cigar.push((1 << 4) | 1) + } // insertion + } + } + } + return records +} diff --git a/products/jbrowse-web/src/Loader.tsx b/products/jbrowse-web/src/Loader.tsx index 39c0701ff5..7f33687818 100644 --- a/products/jbrowse-web/src/Loader.tsx +++ b/products/jbrowse-web/src/Loader.tsx @@ -43,6 +43,7 @@ function NoConfigMessage() { ['test_data/breakpoint/config.json', 'Breakpoint'], ['test_data/config_dotplot.json', 'Grape/Peach dotplot'], ['test_data/config_synteny_grape_peach.json', 'Grape/Peach synteny'], + ['test_data/human_vs_mouse.json', 'Human vs mouse synteny'], ['test_data/yeast_synteny/config.json', 'Yeast synteny'], ['test_data/config_many_contigs.json', 'Many contigs'], ['test_data/config_honeybee.json', 'Honeybee'], diff --git a/test_data/human_vs_mouse.json b/test_data/human_vs_mouse.json new file mode 100644 index 0000000000..099d482a72 --- /dev/null +++ b/test_data/human_vs_mouse.json @@ -0,0 +1,100 @@ +{ + "assemblies": [ + { + "name": "hs1", + "sequence": { + "type": "ReferenceSequenceTrack", + "trackId": "hs1-ReferenceSequenceTrack", + "adapter": { + "type": "TwoBitAdapter", + "twoBitLocation": { + "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/hs1/bigZips/hs1.2bit" + }, + "chromSizesLocation": { + "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/hs1/bigZips/hs1.chrom.sizes.txt" + } + } + } + }, + { + "name": "mm39", + "sequence": { + "type": "ReferenceSequenceTrack", + "trackId": "mm39-ReferenceSequenceTrack", + "adapter": { + "type": "TwoBitAdapter", + "twoBitLocation": { + "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/mm39/bigZips/mm39.2bit" + }, + "chromSizesLocation": { + "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/mm39/bigZips/mm39.chrom.sizes" + } + } + } + } + ], + "configuration": {}, + "connections": [], + "defaultSession": { + "name": "New Session" + }, + "tracks": [ + { + "type": "FeatureTrack", + "trackId": "liftoff_genes", + "name": "liftOff genes", + "assemblyNames": ["hs1"], + "category": ["Annotation"], + "adapter": { + "type": "GtfAdapter", + "gtfLocation": { + "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/hs1/bigZips/genes/catLiftOffGenesV1.gtf.gz", + "locationType": "UriLocation" + } + } + }, + { + "type": "FeatureTrack", + "trackId": "refgene", + "name": "refGene", + "assemblyNames": ["mm39"], + "category": ["Annotation"], + "adapter": { + "type": "GtfAdapter", + "gtfLocation": { + "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/mm39/bigZips/genes/refGene.gtf.gz", + "locationType": "UriLocation" + } + } + }, + + { + "type": "FeatureTrack", + "trackId": "ncbiRefSeq", + "name": "ncbiRefSeq", + "adapter": { + "type": "BigBedAdapter", + "bigBedLocation": { + "uri": "https://hgdownload.soe.ucsc.edu/gbdb/hs1/bbi/ncbiRefSeq.bb", + "locationType": "UriLocation" + } + }, + "assemblyNames": ["hs1"] + }, + { + "type": "SyntenyTrack", + "trackId": "liftover", + "name": "liftover", + "adapter": { + "type": "ChainAdapter", + "chainLocation": { + "uri": "https://hgdownload.soe.ucsc.edu/goldenPath/hs1/liftOver/hs1ToMm39.over.chain.gz", + "locationType": "UriLocation" + }, + "targetAssembly": "hs1", + "queryAssembly": "mm39" + }, + "assemblyNames": ["hs1", "mm39"] + } + ] +} From 9a231d34cece236b35cfe9b00e9b0c8617aeff08 Mon Sep 17 00:00:00 2001 From: Colin Date: Mon, 9 Jan 2023 14:38:55 -0700 Subject: [PATCH 2/2] Optimize drawing long alignments with useCallback --- .../components/LinearSyntenyRendering.tsx | 45 +++++++++--------- .../src/LinearSyntenyDisplay/drawSynteny.ts | 7 ++- ...ally-flipped-inverted-alignment-1-snap.png | Bin 1715 -> 1680 bytes ...ation-both-horizontally-flipped-1-snap.png | Bin 8793 -> 8433 bytes ...-orientation-inverted-alignment-1-snap.png | Bin 8947 -> 8586 bytes ...ation-inverted-alignment-bottom-1-snap.png | Bin 1745 -> 1660 bytes ...ation-both-horizontally-flipped-1-snap.png | Bin 9711 -> 9262 bytes ...h-horizontally-flipped-both-rev-1-snap.png | Bin 9703 -> 9336 bytes ...both-horizontally-flipped-rev-1-1-snap.png | Bin 2076 -> 1938 bytes ...both-horizontally-flipped-rev-2-1-snap.png | Bin 2071 -> 1931 bytes 10 files changed, 26 insertions(+), 26 deletions(-) diff --git a/plugins/linear-comparative-view/src/LinearSyntenyDisplay/components/LinearSyntenyRendering.tsx b/plugins/linear-comparative-view/src/LinearSyntenyDisplay/components/LinearSyntenyRendering.tsx index 038c610274..5a88bd1541 100644 --- a/plugins/linear-comparative-view/src/LinearSyntenyDisplay/components/LinearSyntenyRendering.tsx +++ b/plugins/linear-comparative-view/src/LinearSyntenyDisplay/components/LinearSyntenyRendering.tsx @@ -1,6 +1,5 @@ -import React, { useState } from 'react' +import React, { useState, useCallback } from 'react' import { observer } from 'mobx-react' -import { isAlive } from 'mobx-state-tree' import { assembleLocString, getContainingView, @@ -27,24 +26,34 @@ export default observer(function LinearSyntenyRendering({ const [currX, setCurrX] = useState() const [currY, setCurrY] = useState() + // these useCallbacks avoid new refs from being created on any mouseover, etc. + const k1 = useCallback( + (ref: HTMLCanvasElement) => model.setMouseoverCanvasRef(ref), + [model], + ) + const k2 = useCallback( + (ref: HTMLCanvasElement) => model.setMainCanvasRef(ref), + [model], + ) + const k3 = useCallback( + (ref: HTMLCanvasElement) => model.setClickMapCanvasRef(ref), + [model], + ) + const k4 = useCallback( + (ref: HTMLCanvasElement) => model.setCigarClickMapCanvasRef(ref), + [model], + ) + return (
{ - if (isAlive(model)) { - model.setMouseoverCanvasRef(ref) - } - }} + ref={k1} width={width} height={height} style={{ width, height, position: 'absolute', pointerEvents: 'none' }} /> { - if (isAlive(model)) { - model.setMainCanvasRef(ref) - } - }} + ref={k2} onMouseMove={event => { const ref1 = model.clickMapCanvas const ref2 = model.cigarClickMapCanvas @@ -150,11 +159,7 @@ export default observer(function LinearSyntenyRendering({ height={height * highResolutionScaling} /> { - if (isAlive(model)) { - model.setCigarClickMapCanvasRef(ref) - } - }} + ref={k3} style={{ imageRendering: 'pixelated', pointerEvents: 'none', @@ -165,11 +170,7 @@ export default observer(function LinearSyntenyRendering({ height={height} /> { - if (isAlive(model)) { - model.setClickMapCanvasRef(ref) - } - }} + ref={k4} style={{ imageRendering: 'pixelated', pointerEvents: 'none', diff --git a/plugins/linear-comparative-view/src/LinearSyntenyDisplay/drawSynteny.ts b/plugins/linear-comparative-view/src/LinearSyntenyDisplay/drawSynteny.ts index 197551a5f4..0d2f4bdee5 100644 --- a/plugins/linear-comparative-view/src/LinearSyntenyDisplay/drawSynteny.ts +++ b/plugins/linear-comparative-view/src/LinearSyntenyDisplay/drawSynteny.ts @@ -121,7 +121,6 @@ export function drawRef(model: LinearSyntenyDisplayModel) { // cx1/cx2 are the current x positions on top and bottom rows let cx1 = k1 let cx2 = s1 === -1 ? x22 : x21 - if (cigar?.length && drawCIGAR) { // continuingFlag skips drawing commands on very small CIGAR features let continuingFlag = false @@ -132,7 +131,6 @@ export function drawRef(model: LinearSyntenyDisplayModel) { const unitMultiplier2 = Math.floor(MAX_COLOR_RANGE / cigar.length) for (let j = 0; j < cigar.length; j += 2) { const idx = j * unitMultiplier2 + 1 - ctx3.fillStyle = makeColor(idx) const len = +cigar[j] const op = cigar[j + 1] as keyof typeof colorMap @@ -167,8 +165,8 @@ export function drawRef(model: LinearSyntenyDisplayModel) { // it on), then turn on continuing flag const isNotLast = j < cigar.length - 2 if ( - Math.abs(cx1 - px1) < 1 && - Math.abs(cx2 - px2) < 1 && + Math.abs(cx1 - px1) <= 1 && + Math.abs(cx2 - px2) <= 1 && isNotLast ) { continuingFlag = true @@ -180,6 +178,7 @@ export function drawRef(model: LinearSyntenyDisplayModel) { // feature, else just use match ctx1.fillStyle = colorMap[(continuingFlag && d1 > 1) || d2 > 1 ? op : 'M'] + ctx3.fillStyle = makeColor(idx) draw(ctx1, px1, cx1, y1, cx2, px2, y2, mid, drawCurves) draw(ctx3, px1, cx1, y1, cx2, px2, y2, mid, drawCurves) diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-horizontally-flipped-inverted-alignment-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-horizontally-flipped-inverted-alignment-1-snap.png index aa41e57e9decf2017644bafd7271db1d9aecff48..fcbcc7e886dd8128200b5a267dc07b9250559608 100644 GIT binary patch literal 1680 zcmYLK2{crD82|1VX3APwMsG%Ba2`fO*^)7~7*y)nvPD{?V@V|=be|S4@zMw_LY-cl zro|&=sgXyd;!(u0RF67RD5OPs->rAfJ9EyR`@i4s`~834@B9Au9`s)6raXK8YyeOe zxx1_ZkkiHc4NL{RrmprmjDHI2J>6VjhWZuPoX^1rt|AvlpTvT#VIWo7k)M{V|-SjU*U+GuXzoDFu2vFubYp#A1&!pO8={Ho~TxO*OdZr?BB z#GT)^pQ{q3&IZe`1$V~%Z%5TA0n4L5iGbw0MN%z*y1BZL`}LT>NZgsE4SaQi=G|r3 zWMwVQC%}1*F8J~!m)i!l?vxNVY@I0Z<)l3Qlz7B!(VH}gW6_yH-{DgZ>+BdbS-2X4 zrMnXBQ&)7x833P!OixBs8dZnJAFwoG+(-zQlB%`XK@kD)pa_TyuZQ}k{2Q*pF$W6y zE;O#-Y|DKLX^6<~Hz{}A-!CVDA4{VbUz+6YnM!)^3$o(xTLwK!F8E_+N`61^ovH9c z9#QHZ|FaN|Ekdrp-`90UXND8}2#lSXG)l02)IPJh0EFA9wObK0d!s~gkpVrd5XoFC zddc$Phujh%YiFsE86WzI(ox?^Q^U2hK*@sypNWr)twVV2gFTcqeIXcs?on}nVPy)N zL>S$X+-xWO5Hi1x7M4n}71`}8eHCd{M<(9){ezDzLy{W@04a^XIp_oUB(v z@9&y1VO$q&`qakB=H5zBp_5{?{|UQ4!up>IJDorV*??*+r@9F7aY0K~IN?n>{&INt z$fjWJI$E)SqJCL86SGxGk^KA}s$J_L$(iV4Vbtn-l(5sjN@qejx)L=~B`4v=GJ@nG z(+R6C^@^V$Ioa(Kwxx;YU$qf*^E|)&kfk%a%_RIPSz5$a%`ZGgVHn16NHk1`=d$l zdd!=4VSS@X;x2p7{L!~*;Jp_&TYnjux4sg>1xGZ-yo2c{nO-_Jc^l$Zeb3${3_aJf z9cR9bIsmNg*!>&W+{jgkzOEzodQFY|TlCntf&G66cqqDdVN+BZC!>=_CvTu=dAE7{ zYfp*<^6)JO_kGsnLd2gCm{jRP88wvwD<*6Yaq|(JK!GFHq2ZJJisWH8wLEOplWXJY z&~!aqh>+76ujxG$zo43ahTu6A#AJm)R zu07W*?prZ^5pe800#+?c%e|?rNE%Y)JlcRoh-S_nW0={F`Q;m9P88g;@yK6{ReO1o zP-ZnrOoRk=zN7K6uGa3#aC)#<1^7Hw9kL^Egv9sDV>F>1kB78eDf=(H&%v3Ha;#N= zqG)tx6qk3{>9({D?#6PxoRRWF$lhJ#n<{GZw_wjY{G?iH6t+PQu}1Ok8HKZ!#Itx!hIFCG`_xrE_1{Rc=pjXWYBaU zzG2xGRQk5slGv8E{K`{`KN2n_C~(CN2X^WSft8MOF5VAnow|iy9>F^DI^^B1Nd}gs z-|f g-+}E9@0ErZSRG7N^%r>Y@e>0g*Oe|;oWj!n1-PY&BLDyZ literal 1715 zcmXX{3pCVe6uqEPI#QA9XIBVsnClSiatRUVy_ zSW9CgZDlskG+|kaVU;=)VTi;^g}q4GfS#3 z7AQhXi`Yxw+`5tTf~T32)5HtgGo6=_Dtq}TbUHUDz|uW#wo|`iRfy*gjUnEL_J`ay ziC#NY-#%eIu>RZ(zM+z>F}xft|vg?`>s|^kVMU3OP*$Wr!Gac^W4j^SlBSlOU&FEGaB}PRJmf;BHaY0NBHi(VK`Wo+ zqPx3C``E{d&(<&=qirS0|F`(V+qTA)a{l8YP(*$8-W+tD$%fJ_pz@B&-cKg&3v&dK z5OL(QR-ab3Y`ar0P25Wd8Ji0(MgfrQw776GjE-P!d&VQF|iYD`1wUWYB~M zW*reiQGH6;u+=gsy@Y^zk5MTmM~n;UaB>M=pZub?Av)cnW!GLB$mVcCXL8UojMvjQ zlDGl`l1M|(&kq-x0rMl3YPEIOp zr>1ykn#e;{-D~enA@rbd>2zeegY)SoF}XOlcqcf4Kam5kK$Nidc1? zFS@5N>;^o`O6fG72eJ5e)m3fn4F}G^PC~lZiz+`9;fbYP*&G;kLY?mP`@XHbaR%lt zM$*C+d)7u~Wo(NGUktrh(Em+QZd-b8-5MOJJU)5{Hz|9cH3m2`vKJt5c~p{g%q#<& z%%6?WA{9#3lSLkx^Q&mty5zblvnwq+*vtm*q6B6=_XkdS^>?L@eu;x1Qv?^cp0%*^ zxCjTt9d|*e?&nPR(8Fli5X)geVj{m!_#?wPpj|=_zHE`DP^YprFm+9SEq^$`CWONT zYm%F#vF`pC#?UxCdqtm-9e3j$B}n`U79Mhi1l-Y*Qh)K_hXbq2Y+z_1MQiGK@VX_> zX_ar-F?cD&*6zw;sXN=!-lDepxL-blyOgS|dAKm^$fb*tPBoIsD0EXtRE(*}BlLd( zM26(PwootmO+Ai(f&(elCT5tt$JO3!%merRI?UvxmTofrv8HI-nz6ZpVBAXmOswO3 z)yvIK3zkSA1wBSNlS3=N>M)5qm>cP8CA*~%8JadA8BdqV z3w&@m8w>TI{1oo1yPKXZ-K!=3czUU)8jL4m4sYp4JKgx>6V0gQ3PL8)XicbFrfsnSM diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-regular-orientation-both-horizontally-flipped-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-regular-orientation-both-horizontally-flipped-1-snap.png index f33ab05e3c350be0f006cb214f8b370f0289802a..f67fc40e25d78962a70869092b83550a417ff6e4 100644 GIT binary patch literal 8433 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 diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-regular-orientation-inverted-alignment-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-regular-orientation-inverted-alignment-1-snap.png index d2bfbf38a8ca66e0de0b34179ad8c21b6b222a19..26bf63c9147a0bd8eb8e8fa195c2d58f3452d7a3 100644 GIT binary patch literal 8586 zcmXY11yoeu*QFcjZlndJk!Gl$lynG^1JWSnfOL2F(A{0q4N?P0x8#U)NGRy{hX1!_ zt(jT#?mKb!x#!-u_e5&E{SP098V3mp318`rycQA?DkJdS5(@)(_tVsg2R<+?RQ{7k z`iFSscb6q2Au%E;$%Aw}vrjfuVpvu@GPeJ%|0n-JulGZ#wIb~RGmloYlHuN)Ld)6D zgK5al&GjNTiZsZZ*yoA?+p*}L&v6+oDap|&O>F*q)tqP+9H7>hKu&Dt4IVGHjNGyR zO66KAy0M^}nn~nxCTb$DqxMN%U%K+h7*4~IpqZKI^`ffmXSVm5C=-TsoEuCOLN%$> zH5B9A~80u#NpLB4x={<0qTIw0pTBHIntUi91cFZo%c#F6=Hc((X^;yc)&sbGW* z?%v_e`6EVxHfa_f7T z_jwQTP4rQKUp=tmmRyK`hMK@HD#Q{NsUPAFr_ zml4^ZKP+G=$#nAC^&7mS1up52MGJPptO@yV?_N4LKo;d(f$%M@p#c)HWvW`t1Z-?3 zf@j%o=_}bo)0ZSH|P^<_oFq1 zp0i!R9V3JPcYEhc ze2m`nd^eaeOKt#d({u7E>Gv{c3Rf`Ew!^{qyI>#cm5jcMYoAOJ*hd|hC_Ju@BthV# zs=`%n@oRW(n104Z(F4n+2HmE3SAW!J#Uj8RL_RklTN`jE&8_JIYmc^nyVLaWI&lTn zR3zoq)sz5rDv%faJN8%fUnvS#1Kw+$09J?zfcQDKu5Gxdi?mPt##7wOb~_dILUD~$ zQySNdKIm>rcRO{ETz7)Z>399A1p?N|4S4T@m=*DKdZ)I|Ln+AJOYt%ZW&oMdArit{ z`DsnTe;;Wq)U^N$^pWRc0vcxoVFJ^OIr3t!j0A#&=f+c+&1y1nOu zy!Cp@GZ7e}L#sX81-WrO<@XMy%G(h*vj^N{`RtPZhX@YM6J-a6{|X8@#SyOt?#>nR z@6RfG%?0>p?;|0E6wu1eKKwnIT@%lCv)-)-{BQ1L;r-x@{R$Kz_66FIu^15jI{FpC zy?8i~xIV{&X^)380x?LC1hR|%x8$gU?LZa;Wa6CC!{J~038XH(w&3`BcxAkZG}$Lf z2;t8f5{o5jZTy;=(kZ6IZ@Eq23!{KFYYzW@5p{EUAltWr?2ItFS?y0ZmxW$%`u*qY z-=F*ZoB;wly)fSNdWb3k0Er$1Y`vY)CZBR<;{@V**;{4{WLx*Yxn|1^cnukeTV9!n zKG+x*WWUh%IcPZfByw`;+cVrvLXUt{dk;IpjiS%Z{bp6-hGjUXM)f;|S56p>x-V?$ z?l*QEB5kU3w4rvD9i^v=&uKT^BT;u~>#P8$_wJpL&>{+6;5%SNe@K9QilH@XN8#$! z#xIQFb0q@3{T2p9m+?Z`$rk?@Qg|PJqydyo_tsI@c$Lp_CXCbFC)7D_2GMJBnABym z-KO^<6s`y;X1pcGbuajwE;LQx?~=c@-I1ey<_|_pa~d$sFuG1S2lN(Zl0Nog@{UD% zq{(Sbo6Gb9mp}}@ZnY0YbE-;PVDq=WgA_u)!Fch`@3La;#HnKtvRoh?s0plQaZH4n z92NC^$gU1xpa<`a_j5c@pu-_qviC7?-&BQERbQcN)< zFWnah(32#p4UpyCN`cs@rLlr;Y}}%=B7{t8f7U|6G0( zB?&4LdPYO3YHw?dU8sB^+oE9dOS=RpO@r6r2i$j1`RH#@OJhs{l_ZwYQpEt9MP+L0LBq%- z4r*;hok$R}E&<vrvrnrfb#MNPyVB|lZcI!_v8gOAl3M{ezr4PuZbRY?lA zu#Y7Nj}-1JGght=2F;UdYjIFFREx4lS4Mu~U>+-MVI4Ij!4Vo29?_*yEwM`wPUo;_ zI14T*=Tn%f1nrvb8?Gkud~)MIQYbkJl~*YK2CvqNEtjJdlp!W-dVP(`s$ls+oSalw zDXGM!T#HvIlvWj2h_twvjcmMc22FRS&#&Hus>}(845WdBLrGRtR%F%{`>km(DlRv0 zKr*em0;#&xDjw_}ieeKiN0RfH2NTG13zd?FXLr)(7Bnr5{XhO^=NMI-8XwaqvakC} z2dE-Hfzj)j_={FN!xAF*I0J=4R2kp?(@T|Mr0ohKsuToeC46>_A(Vd(a{J1~BwxX4 z8BHxWZ{m?{^_B^3fmpVg+5(*!w8$jvSnkfs43bqQuL?6LjG!_nvQsQ5?#uURCDWT_ zv128yW?{*|uNcy4H0RU#ZDtcbWb=VZYd#2?DxrNCt*IL2V5=*nW6yzxRhg3Tbr=J+ z5Jqab#;paW*f(vsygJ`QI?Gm{x?yvCCB_&xnB=r&imKx^5244O-Z znmP`Z?aw8xpU(TkFj6EG@9(K9PXG98Flb{CWxFW%s{Gb}{Ydg9q4ZDDvJ0wm+P~fO zxKCY;__NlmghWEIg!k;j6|g;)>Gb#vx0*_-Y0zWu1^3Q^&$}5i*7`3fGhUdlmeAS0 zp_DCQM&r+XGgQjMK!`ne6nAx1oSwq6Qddu~QY zQ=p)96H1I?Y!s$b-9TN9!9%WK$almt?_sJ9U0HRg?_t!HhZdB*NLx~JApc1i4*C-@ z|Bj14Ww|ZbozC}9(6TVJWw3mdCQ}yXZr=j*o@d*rlh#y9lq(Xm=&Dp&cm-5*5@IYQX=9Nql&qS)lf&agD@h2m;KZl^v8I7o zT0U^GJrZ&gWA)D$7t%%2P9<0b?=#!+X;%?fMr2@ArU^!5CJ=HFqc9p+H@v}SMK2b~ zw4%XiT&D`)8J{80vfm>7X*OKk98!R*U>Oe!vZ1ZyI(qFqK&aCxSpDKL-?qgN?#JP- z-A7-Vm#np%tJibNUoU>*=-*31&{OAf{x2BVIy@=3fvr6JSmcd_!DyoA$8SISN4=S4 zEizDABB13 ztVQyS`SN?;&!%3_!R95c!e13tV{<6y=L~4)d`P0c`eZIzw!ztD;FI+tB`t%QzwemQnO0{{)(^rmfmJUmI-WB$t<#CeEpqWuWz{;nSWJ z4r-xjR^;OH^I424N2^5wQEoR5zWk0(r!Z~{;kjiafytqtpYRG6OZS{+lC*3KxoWCg z|D=c6Z#!i}JUB$ti90(YRI0?z7CrdZcj(u)Lp|s^wuLs)^6l4tKi|kZ!Th@a9gd>l zH)tJ`<3AMkmOGEOcld)f zYYl5jIBtv8Ox_R$7w5LrkA1hRr%^2*^d$~SF`lR)IA7A-fsO@77L-vSIQId{hfYaC zkV)S=EHlCz!#{Njujt=F`ASJ8Zt#Z^3l(?8>&S4<7RRG5vODBG#6moUu+xQF`n^%D zbcJt5xB;F@Vc4)`Ng5?4Nwh(HNInt18^%ghiIX1ZAK+3Q<~Y&PV7VC#hN#MsloH&F~xHm;=@`fR9F za&QNPP~1Z3@-2J_zdY+wGmAV&jq#@XRJNvuB2xBv=q(d{ekqvtXU^f)0_=brQ-dj0 z#K*X0ftSJXz&*0`zL7ySJ`L;D^Dflm!uQY5`A5XDBu8+uq7T@8lo$w0`ac2%%qYA zM@%j1rP3<*+3A}rCDAsYy%10XMYfzpp(WP)KSJ=CSemHAKy!`rrM18FE3a}2-ZyRZ z)T%;f2%7%2zI;%#%+-TZ3|>ul{F4}GV0g%??L)ertI3KBKlJnerjUqu9tvk?gb#sH zOkYbRNRErfXW906_TQSr9q4@2mSu&53^Sy!#i9>e(QrmQP+qAD464MeVYN}p6|$cH zBqhA0 zB2H?c>uy`Ha&FIN(^j^}19zG>;f8A7fAJU3c4O`>#5VmO7C`~@2DI*i`k&2k!HhFt z?y{Ae9NS=65TE8D0~TrMegEbIU&faIU&k16EFvph0}{=YwEA_UVh1q6Z(Y8Etnlt` zVN`C2>+@CR8n({cHrI6}FCl@kTW$GaOFg@HBZ3)9#cAbZ79j-;12a~k5sOU4R-^%J zx<_a6x7t{Z?`>7DG!_cK=7t4oXh#e84!9Ibs~4tJY+__&6aGkp!I`^h?eFMo?huVW>E zqcKJr+w=!jecc9qH>cG08Kl--Nz3LbveR51NjmmS1kVAV#8G<0! zew#Ac393M{Fs(>5lZ>Fjxbf^hTr`vsnG)8IH2oSKd;ylxGM2|X-3s5y1I;@!U>-Xl z4XOMt)$d}mphI3Kl4T3L#uwu%a~BpkL3K=cXykLPDIZqBJtC5rA;@5Fs5t|wJ8uk6 ziV>wV(V+%)2%dJ*rP=llJ+G?3x+>f{qqRAv-}eLFCgzPdCe_;9(gbOW0Qw(cRvK@b zHH&Z8zjz&&l;-R=vU<{^E*vezT5TtJ#qTnE+S>d~Go|W6c&wNPo#MC)e4NQU7r2wm z&o&Yo6*D)2U>3`MRgNvVfwZjEt_B3eZY0ep)d481fz@i3j#_2@3&If%NL(paQGANU zX@+{7%8IMC^W7d%X@bpa6-OS=I5Ub3DmO)_AV)GQb25&_1%@?bsnx=GVn@36+_LFk zgBROV?2N6A9ydR;`Fh#Hy}g%KI5WW+iIDi4cJNy%q`y;%uqfU~hF>-xz>Y(Hu9rRX z3a|ejAp?Y)x3I{}eLl}!+QTkz&ZbhP zOEX`%U7-UwqXnGkeMPx+KcZ}w4>*Z}qr$1s!F1MoAtK?_(!2fWFbt^{KL-h!yCMmC9 zmECTba()^8!ZnKoA#4S5phoMTSUSfe?~cLEl$=H-paD_q{9A573U8`{o& znW`uyeU4UxI#0?{eqv!qjx?^UIw{XL%Vc8@vLjf;#Mc8?m6R5w6f~F>iXCN%P1GH>6S{t!`F7}FZOo7Arbhw(w3$=w587{w_affsi6LOJPQl?gV`YmsR5Zxa(;H=K!epOG&*CvDs72$V(RlUUN&Zbi!Iyj0fs``Iv{R3YS8lv!oep;25 z$~7$$J>r$Dn<0GmQfgk~>zqsWhkeumnc{p*Dn&v2^|a+ zm5~>zaYlwC0TAhktvo&k=}ec>M|xG{rbejApH9U%14-jHt@rB;2{7kB&b z{Aej=PnbsH_9=6XAU0}>_tlq8r_sJrnJ-(#77EHJhpY9fqG5tMk!)2=Wh;evO))1P z(V6JFT-Bf8j;28xAPihAy{q?V$(AK{GR!jQB&y=_7@9~VvF3!v9&d2itWv9aO5T8e zGwmsQP)5ny2C+~Dd%7wk+5U)X87quX>NSEMb&s1}jMN_wSEmUXu&;ir`EcZ6)pt-m zZ+*BCdO7i-VH@81qzihbP}dh@J4J7u0dP{5MidKqHk&{@ndGicw>pOZid#4CVS_T}U?P!*_F4otxW-(O|NeK0I*f1T2EOIM!3*BSVhf;D-BMR zDnVefxwk=j+FV1-4LWboafpZ`GLZ}>nfPo-^d$p4Dn;NaQA)?3Q-?K>ES7A$G<7kO zo2jL1e~Bp>QlQ%C=fK80kUTZc*0Jx=#{V%(d>Wk7O@y6^yXxmA}W;_G;jAO-Wz7@ zWzh>esxCdz5FtDjFwy&|fZ~nzsq9qn6%wTM-QB&8oCcp0^MnY6?U&>+T!TZ2nqDHX z5*yR-d`+Rjm~gMqo23@Mo5IPZMI{cp8k03&x9~mfLoV*9=Yy165`jxS8F&DN4>JZ`TGw^`Rhd|Cu2}w3A|yQDL!9)3&{fq} z;hRQ!fm(xX@}Gj_lpoJ+7gHGvJ*M}Dk6P*&J?N}jmrsf!7E(ipr}mLFJ|(Qg7TT)> z(nW~a*ZAVKx0yv(TD?iqXM5Aq7!^pyQehZQxNGPTed6RlBP9oDL+p&G|5C?a<;>s= z`zzjCkFKj7T?%Zj?fm*GKYXN_?M4yn;I@1Ad6WiV`yaehOvU@rw&y5KFBjrTJ{tTF zqa2kneG-83zBtnHJ3+G-_)EF3((~IzHn+5CX*cTNHkovb>o{AS>~KsSP~{*MkNo4# zIUmjMoO6Fvb+TUpiokliOUo9<>q`rTrc%6AuqD^&2T59IC; zCMt4CMhLJ?l~V3O0QK+t3{_p`C9=7LF0Tpfmgsm);c9bbLKOaj5%9vAV+l}^5MC2G zi9L53fTeGL0n1*p7_f*C;F%I2x*HVr4GUU>0Sbf{z}nf@guNW)0bY4jHK0yZgehsl0P7EcQ_Hi zVUw&k<`T2aohJ_Y4sAr=_t#*KJptrN{&*YsKP%@{Dbsm7p-BG-_pAK2L6B2PHS4;^ z&nZ(wLxA4m{p^Wnw7O-Ad6g{-q>?8-eCv8@DQQ3Zfa<}42tZ+-$#qeX;-7U+;dpM}*$#SDm$aZQP%r%QY zJ#Imqjyp*a0z&)5Pl)E*_Vs*q5-`wlx*)edeQ|E%7Nh-Op zk3HeQe~&kQmN!dYz6E;sI}|gg6Ddv$P|J|Jmx{hTzj{J}TPozDS9Am5(9`DrY+an_ z!;G2Yxe&U=X`~N2z$3j3Zn6O+qALza*WG&iivzEy157}PJRSP)5JvYDYN2=)Alyj7 zUogPhZ!ZeHZr?mjs{(`^Q9#K1(*QD}5SD@2Izj)BTgfTW!+=1N-TCz|S*oez?tn8w znFJ=?dG^6CsgPY-=T@)_YXfjx>F*jwS9kNskh1h-fys0BL3I16@`!vf_OIZK=eG+4 z@b%$~;==pK)Rf>C6T1pm>;q4!7m7|G)TGFZL9D^dxB=jKa1IdKF#G*qNJT!?hJq`} zZgjTqCGu`4CgxKJ$`^(A;O|fNHMuFp-#)I3E`M$r@}x5NT0{kq!?hJqYIjw*dZOYf zhR<@7_fSU`;!Elf8Z8lBNz+mZC-fG|;e#PPZ8Bss*K0oWaQDfVldKW7%7-+U@39%5oZm3eEnG&WypEySa zAR!?OApQ%$NFx<{QR1e71~iw`*T+jm4s2}ffaRyyO?*jrqrbK*OZ7xtvH}GLYggH` z{i*rv=-8vU(CY~?iH^t%^zR3vMz(it){;m-+p+#`5PcwtsL!hp4sG^6*V#3K527O! z(<>PWp^XBlD-oI_O|hrjyY7usrgH~n{)zCtwtm46JZ!(jLFP}G-eLeAEjq_XK6S#+ zAXi3|dD7v#2mx;Uj)4T&pI`ayXSb|vTr9bxC^*U??b*H4|~_S;j0p} z6yUf840AiZzegU&fe7#MVrtduGY3_Jz!+YA{I`0KBt9tV6On#jvY z!Ms2}d0i!mFfbG_ASrQm&#bczn`pB&jb+G-j!&+dhW^HNJKI`3VRc>T8+ThOH2h_( z-azGhurG2XGcCB-mnK&^o=RFO5(~~GC>|>!q`(&>@l9%wy6)>&F>#3mu{x7z2iw}Z zzBrqi?6&!ua+m2%n|;abbKN^{Z!+QeiFdni`WxCU;36dkHrCG$`Hp!=1Y2qr##8G zdhlQN>}<}SNtTV0JAoUK4+rib`lquEMOin>63CP!EL#`BaKaUM3Di}zj3;Ab2lp4Q zo#eoktj>#V{q=3TCzKxlMM)IOkV~UG1u?QA9kBD3)R5K(8a2%dTHVf+QW6?^q&rEV z)xAf}XF9_fpVldhwvpY+a2yHboxa%YK%wYLYtZe;nhHqnpy`cy@MBE@7d`hd&>4bt z-b=KLZFrc@!I2qHE?^jBeG#-2aT0kjYkOzioAE`HBWvC)lChf{V7xybqQo|^9gnhY*5 ze0FKLE5cY6uAa@650M9w$UC6UM2BA|UNa{mx8~2}@Hf$)pk{TJ*Uq~!I^Jof)kge4KMgf=6SC+u1*(dRWdJyhZI2LOZ5Qse_Z#iYy3g*K3QMcNs~V&MDx#9)VQxkNA&suDiqguoETkS3aaap~)m|H)|tV!wIY z>)wGxvPUc8gbJ0NBPtav%1#d7gRn)PjcA}a<4D;l>N2Tb<=pe~|G8(v*RSuNP#A(1cJdu(7B?z{Ltgvj6l z>c9me-j8tkCcA5~#YY;9J*_GEe(lU4;FqZgP7^uMj}9Fs^$USJF=PLkaqXh+aJXZC$|F7zuv94SPpCTZ*-J|mKTp3Us2Ee92-xPPM#^W}! z;K4EA;=oR5Mv(j@tsgA9pGeR3>gmf`@(-Zn#A=!Spr=Y_@<~=Lf-Qhpl=d2)a zj$mkPQhn3(;pKbqv&lLd$1nE*gr;kRKaG z7I{b22UYrdcICv$H?U`lyBo4R62N0E3OK2cf;!oko_$igV(pGNBx?W?CVYNL)P0Hj zI`;{^b#BuHdcg{YACZhQ`HK@={kmmC7i|m9npW)R*^8NrY@2Gn+wnC0@oHV@&bUan z(FppyIkjfqz$KQl!EABg6^hkg42gf8C#mymUYr3@m{&9(q;r2^KD^2G_lAb>+I(!C zU@vzpxOdZ$H0}3ChoULTHJA-4H;$9{RX^leSL8MOkibfvS~w8enBvtEM66lWjSQ{% zn7K%;hWw2b-34jpl^>_0DK}=B-dpQUnQovI^o#3i`#)VR5>-~sl&p4B`bdeN*?4)* z?d+5tacnI9xn_7=tEYapaT@hYZ2u+8RQ|P9q47T&AL?C>S+M0v7|o1o@qw+v^gzt6 zktI10M9M6%3`0gwT6R~CMdHQ51zE-3LJ)1o6Hm`GE+F1ks&j&$@TXI2JlyEYTuMSm z|J8GdxxqqE9$jr=Shp7w%==;RR#F$SKWEuKayrY|9go%1@GGQqDa_Sdw4BPjS>C-3JLS-0bR8nO|8Z=45<-Rh)65=nZ<5Hjq^;1wG&|5m|9 zF&9T#FD_C2TstA06{*%bf{2c`kVS|`g10(02Zh3Q% ztp~RhG$kuD$}BpB5Oi!5W4te4c$B}>h?UYbrzHt3&@!!n{5X@1bLd!eB3qc+nlpsG zC47NncauO_Qe0Ff)PDrYv6aDq3mDE_boG9u57qc*u18X_%$?<#1?Z`w@(h zb;f_;s%AgT#+Y(Gd;!r!bl{Sg#&d#fSn#YlW>z(?V>2f8oRisQYr+$(&0(+=`<$}I z#gvK%j*dRpn}r9_3X^&)=NBRw<(@M?o9baB%Fqc6+&>ZXM^{kYi4L10&;aX^w2|MZ zZuS393OwLAd27Ys>VKk{vmfenqGVMj%HaZS?ZgTmVq1;GF{Xgup;q`MxP5AxgB+z9d9q-- zyDF_t&tU5%``;AsL?daX^6YrLWd+>9rD>SQt!<^-Y1%5_s3rA{w~A~AO~sz3!CFev zL%ug6rI{K74-gWd8g^<>-izuy!78ncS4W#regk#o4viN1Z~CU!b%ZiNvL+<|U6^h{2Oh zhU7YLyNiT9>?*Lv<>#Ht&m|-V=RbFU)uGRD@aFV398xX{Lq*g6buHrf}1Qq2Ay|5 z>!&N|#A~g~X3gf4vQ_IdzZI*OG?m{rHi5XQb58O?f3;fMXeiXn4JBGD$dz}2>=wY^ zxDN!9B56V2)ZJW&g?tJ%hBlCF^cp?;=eOJBlFdJGV-|QOP^mi?3>|fi&rvp^E%$CK z*X!tpcao$`6@Uh!cfG_?+LTv?WLeso;k&-rlxSXn=(|d1wHXPE^O1i_%z$I{^LEt@ z%rnP(zsBYa?aY{Ytdm`DQ(Tp9-<66%w$nz?yW>#($#Ff&xX%mWwt^4I?jHHA(dcBz zaaa?8g#z+Uq>j8QnQQUG&9p&<)c!wT;O$CU!7)NF6t})}y>5Q!CjOuT`w(9IoGrueGN7ITMCAobeyBO$qYj&0Lh=rDEnK}ncM0E5_jk_PO zI_`*LQkc3BZ)qAm__Oo1nUNiczib!xT0{Z-O@iY@-d!OFp(IsEeW}RA8Z7TN6@weT zj_!#K$+|o?3XbAJS+Xro`EDes_!V!4yV$yQRXJ09L$=CT8m~;E-`fU>iF?mL-Nke> z;(kJ(gJ)8XceFRJI!x>OtCeW6EYDgM-GX-wlm2v(2>O7*qP-DlOuuE#-EZb=P7s3C z6Th45Y3v6>5A9l)UzLw#lYe7-fF-jU7B}?SgYlrmzJHS_H9ycxl=snV<64-dKgl2M zCkJ}E``L{yO_DL%eHK4Dx*OUsDkq26dO0jQCx-+nxu8o3;vqgfxmenErF#b^7lRkt zRX#ZAKWTPc-M3e6Le@9SD~I!Ft_%qDv$44Y!%k#0n8R?i4dr%3ft#7`9F@a$r$rhQ zR&dAJUq)Q8tNt{-OK7~1C}-ikHZ!;e4-w>@#y>$S!4U7efl39kEKs@93bA%dbZE0!6_(ir6OetYfA-IKB>AB zWdThq&iGUcErKT#dIBf6hmVVmj}5-5oA&mYl0CjQf5GslJZG2H=P$Q=Gv&bp>9@sC z>XU@Pejo*^9}D{|D^Y8@u6-k(>)d#+x8s@Yn?aD&|GZKrISDTcqjM#_ys|(6u&^8f zLG>}tZ}+QuwLqtNgz1bCGx2Sp9fS~shz_%qy|nKnlMU4e%{UQSqv|0R?B9`Ftk^@M z3mD#p9BBs%*0~{e;CeJ*mA^CBmX3RCCQ5 zs^Q{`SP)#vx8?Yu4C0%Bq=$`*nZ(W-HS$G4Hb_S&1X4Fr4;!Y{PYl*rg_P#)1@$$p z^ie@>G54CN=J7)S)7hPH(Pms+x{opC+Zecz_0Fc@+$LrGxyGyt!s4b+zA5^VF0i- zs2#?HTdqmw7Z4LUPWuyR8jIS>Df42m8GtsEu!zdB!=FW5iAwY~-Nx*|CP*_%RaQL- zJ?q4VbDmdwssVG4E`oQb5m~+$iw88R><%;VAdr>GXGqr|xy#Z^H!b3bxr09*9TIna zj1xle5ivvyvty9t&FVC+1&-y&CVj=`-Y}Z+r(zjdvG+Y&2(`Vkge(%$+7v?Jj>P$< z6!TYbp=&hwge}SkgdLTC%O(R6`c2jyUEVGuoNv=)ozU1f$id|hTO9U8QzEy>p2iAm zbBs5rH-r8?3!!gvaVfj=&fT8H9L-6EYpp&wm!vP_zLTGSR?Ng+C@)z|xi>4kov60^ znU}EY;nSAf>y-E7z;w^ ztAQ#0A91Htr~FV@3(oCzY(O2FJhlP(i;u2LDK1;O^?{lx|4v&Ta~!JMXPM+G(N(+Z>e0!qZ_Qs=1xJAp4AZDVmT3Ku z*l|t<-gn+cn1^0j{1uK?hw;Rem$UM5$eHsF`M@gwTl}_A4Z++;|snG zWN~NxWHX9?kIp1|g{%AM|8=}Ya&(=hkT5g|WgMTVSec=b=78&0o#aT; zpxd0MadtmGx-Rk~-=lgrhIyoF88dqhCAo+p<2qHG;QEJHcKR4%6U5$?yuRTT=i&5I zGK+|hq!tj5I(9KOTey~yrHNMBVrf~zzm-L1GYe`fpH|2$UIbB>91p@pRb=_mk4mhoKgFlgCB=z=6k2JzuPJA3vm2QB4{a@U+vJD)ALY0mUgjs zL8$ek#yk#F4KF{<)K*n0w->H303q0xeb%FGLvNm3;RL7pojuaYbBt9jbgSVxDd4Ji)?Q@W%LStZZV@Lr8`8{HVMYsNlL$K;Gy8^OdNN64+kHDv z@Hr@DK{FoSA&W7WYOk_NxzrYJp54hQq{``b&FPl?0C`EpY~4e6WaYhKPj6bj(1f+- z6Gm;&rQ6;fLIuSIzQoW9trMwfVlWv+#pef>H$$b!I7t>x=Tx0?`}pH-(QM$Al2}g2 z^h9O#px0ZAAZMf!gv}6+-en_Y&y?}ao$GPkS_nIrI**fx%ol=Ie*0oCJX42tcT0jo=P6&<%huj?Hf%nbbMFMAiT z4sbjl?Wt|4^#)eNmWj5uVj%xIWlU`JVvKxWIP2GQl&tMTgnvIlgrddwya+DRkWkBhqvzSq>Q5zk1^@z~rw&D2J zjy_lZ_2+7ZH~zZ@VZCyOKsHAtm1twx#nuXsV;-7BokY1Zuir>Y1yl>`;IXiiMphrv zL73J30*4eyQB##K9Z}-!nGFO>=E#>yME9X3LJ?QA(GG<4e2RwVHw3#e6%0|3X3~v# zU|DHaHDg)T-xQqgOk|N_n8{d!?9QjQsf=~%_`OqAJ2sBq^ieX<#*{*c)M9Lny)yGh z+~cB_>2g6KQJmk|!-Aem@Vx3sZ$lrWP*g+2d}5jDrJ#738J)Vl@+h+WRqI73Og~xr zo5_)t%Y8nzEN%VY{+WZ;Y=4>V|DjgcQKEm6p;BvOKd0OxZkcT)bkS_s$Fp?g(a!E~ zcd`LRxe%Lspq<~T+zwAME(Ho>M>$R6ggA&}3P!acqYv|NoC}7hj87nY1TjwErv2s{ z#x};Jj0-Ij+)F8WxYr&@GDpP4=6G(r8(|T3F^Z@qv{)9*k|2$;{SZ2d$nm^x93>&X zLXyZTeh)V;5}Km{hAbibd_0|`_p`1=;8@S*+SuSJVKyLOU6)T3*N`1M=HQO{Z@&2t z=m*C8jl2m|pNTPFM_zDE0k@v3(9#=&KB4VBz>rQ-60J{EZGAbz~S zH|JnR3`9Pb?#(5DK%+r+gNiKmo7B8b2gFC9ltu*FOD4kdHuG$#^%a2p|%mV?2MM}hekt9D5 zm4VvfDu#!C|Le9(tMN z+BKRj1#wkHp`{4fwcZv_F%PXyO?$8E5vaN}IL;O6yMLzt($!ibH*RpWu0Lg!I6hZl zGc^_FYS5lvx49Oxo}SdFN6Tvx9JC{#)-sKE116qT?ZP8Qv;w!W8<+Z6@yx=d=Ubl$ zBdEV^h(Q0s$|{-NRNT^M&eX({*nL;7Bd+YinfwWz^k-8roXO)iHb?k`X>$SQ@Zdm^ zFGrHd1j8hIm_Z)7z4&Eho=C%o)3%QbUZwyFK;A(G$8}v!=jwewV%E}VEIIzKhqQ0Wt%cU+Pazk>J z*uXpS)MuXe*x>q~GJ4FnKSgU`Ukz&{1xwLFX%<1OZNtsZZ%+X91sN7y?$M`FbRzAU*8O#Y zi)G4)n+E8P3*(42KxE$de+?oR?OTn0k=}t`mmn){SPBO45ID*CN)jMOg*Eo1zzeAS zUWG~2r$2N@)NiN5K;IQW6%u^BP)Y!BB4PFCYZQklZIOMi<^*Kvr*)$mVbAN>)T%Rsn?X07{IA6zzP4Nm#GWK3K&<41+9`_#Rqg zAQyXjE};w~J#)TLLL)s00{BpM2C!Vs^2qIPE;THe8#$Ko%$8xyFjRWwLGp9}1d(X9 z_D}CeQrfwAAsc2J^r9n~D0GJ+5iHg`K6YUBqj80U=6fF^Xh3?e5q-ut6M}PH3)J#y zprPZF8QhVy5dH=bm6C0lvZn(^x5DEfhoO5{+aA=z49MSCO4HByExinA2zAp36~I^j z@ROBfPBt9Rh2<=2g1wV&s-P&R9|uY^uvj}d4NuXLnLcKmtIJTFV?+)qdJ{(3-xUX2}9j*0%WQ&pFLPNishm;FI3dZRy|jN~zvb zD`ErLAo@p>jG5cFbsuMhm0csjM;WKehr(^|i#xtyo zb*osn34j$6%nun`F*LMUMcUBpPyFgqf1V)13w*&&?ow+XH3m>BNr~k%h4Bh?YXBCa1!mA9REXpn9Toz zryh_y-XpO0Ywtz*A((UhFMy>!jC4U2m>cw(EGlod0K8E*i0UVa0BSE&f;S#0}T1O=qQ;6Q$JB9WW`4jmDK#;ZM zaHm8OfYJnjfY}lJ;SYygYHzGD_qK9^ouGTKYX$&hg2t0SWW>EHD$+3jO8AiG_lr4` zkA)r#a43La$w|ORKLbF}&>|$&JptNNp$qoqT`yZ!q7=Z)SZhX(PTle&52&FzyFMpZ zy-z))0ahs7sD{zkGQe&e9x1yETDZ(vLOqy~p7qUwIui0>OAhdue%1`2L7f30`B!C4 zyb!fmMOBPrl|@0HY|GiF2Z1sunV*UxB$u|D@uskOrVou9YNH0)Oc((~Y$(pJ33!u& zdTWn>bo5TS`~U={l-mFScs(DwQj?_!RNj0J-+M2z5&@+7jJ9_-y^;pS#RP!Xcn$6L zS7V^#p3Vfu-R(m7`-K@e_yC07(U^3xP>RwRu%xeW?>J<8xW^t25DMReg2$cLqV?gB zsE7r0ic;OW`s6_mXq5lo3Eq0ODYJhEIxGj6mvD3og{=%MG@tYYuX0>87`)GRSp>RT zW0K$tJzAjis;~xE1EBQ%JK`;781TRH-69~P7W+*=>vs+i2bG6)elkPA%iF^jc)Kj6 WoUwh(3*ZzB3`km0s#?P6>;D0`cI<-y diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-regular-orientation-inverted-alignment-bottom-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-regular-orientation-inverted-alignment-bottom-1-snap.png index 65ba756b4f73a88ebeaab6083bb24a5c5fdab560..83a43c8e9b10d71ded51b92544360aa3850c7ef4 100644 GIT binary patch literal 1660 zcmXX{3pA8z82-kLjB8Y8)k-6kO@(whO&Gu28kdPhF0oCmY2`k-ri`IBlsJu2t;*O= zIAKVrn2g;v4$4?I8f}VM$}P8YnVo9if9#oaX6Bpc`QGn&p6`AC$?{~nXlty|KnQ6w z_B(!$5RnSsL&(eEo$KY33m?mly16)_ulP&wxFipL*v@dY_er`j@!B@r(9hu9fJ<6r zU4Ze1EdebLy=1F6diF8rOF1S-BQ&>Z{3e_YpDj4nkA@L@rXs=VncA*P~=x#eoAyt^banoUe#E6g~{ zNCHcON|R`!L^AC+CcRLZPU2bNa2?~Tc%J)`K={s$hb*Jt^(wAAyhm)jaQGFvX>U1O z&AAHQT|q_9dNabCEBPVYu>Y6wGCxMOVn&m90xwkKJ~Nje|Lj#K!4)TWAFn@@NYf#a zF(>eFvhTEPGWe;cCm$4YDUAM9ncz`b(h^njDlUL)g3V>K2tFGybgi%;N?hMYreF-% zxwsgUF@IX|KA4L1aZy9_aZ<5E5H6Sjf-O?}rz2WoA&Vt6*IF2yfFY%X7EZlLBee05eDYKNE543~vEH#o~4P<3=nwdCR zc#o*!nFD)`==8Uqi$#!X7`XlP*uAjOsOp#$WVrB<=bI8WJoI_tplYczzLpXlj@nMe zqNz~u(AP6ED^DA{qPKKX?adO&V47XS?sQd8=m0_8a}#cl4jH2Xwf^A9?66+=3p48g zodp|Y^9$g@=O)dS<`c=^kg<(8r9*8&i=g6p9-v}2KabF}*>76q@_G!Fj-=GvcSMgb zpIVKya2ee{LXu$;h!WqJOkpt9k~3On?dht#H1I!4^SC;M5l*~kpG8;j_3FX7GB=$f zqOutK(mzjl4V3l zhs>j1VflN`&u5^M@VW-ciqS41WM>B1#cSDe<6Axal~C9MEhWc!uVoZTQvjwg?bPCL zC+^SVt$-IAkY)A`HOA;$VESNS?uTN@0TUskgNH5y8ammXiMOELXbCZ9IgWQY8(m7q zOKCu9RlI<_QqYNR6S`m5(c~fEg;Dj+GnkYSie3o{I(axWbn;KhW8Lp}>_? z z%8i9bU~V@np2_X+bp_6 zKDE1I-CIh#g&2kI14HF-U4so;(Dj|!a0C9)-E3bQ41bPo`KltFKXd8yV6U1<0 KItur((*FbUV5O)4 literal 1745 zcmXX{3piAH6#w5DuT+LwN?$Z0m6VoJ7>vr+RHXgTdX$ldN_j-aEACdy7SYmpg=`5m z8fCdVv-LJJwY zcKnJEnF{}psHwnj+S#_ zj%#6Qt)hchuc25Lu6k>^y>Ru^mO|+_U%q1IP z-Mx{SZuca5tZe(eY=pr2rAv`#Ba8DemM1C zp=|)rH=?7Z#Xfu*o8y;1!~}Y82$b;f`kAluH1UgsVZrz&n%{eOr*MHX&efu#WKoi- z#Y3jX1Xp{`BP{lUVDt$$5;Ivu96P4^tZM91QlmRUaiL=|8QBL9Pj{?fnj&v#FVkDY zth!2gtPias>iIm77S>uT4MlggfL$a_WKJ=&VxRF%A(uQi3qTD$2i-HLzZf<4Yui!k zs01H{C7btsOp@P#)in_Iz$PxO`cv&@_EH1-W+G$cwa=W#7Bb)E$U6!0E!VKj;_D3K z$kmXJO1_4=M@2uKT5$o$pM~(DsYf4oH`pd>k$xP92rvH@PSZd;gLm)hY1IQ*fgzmd6nRK918H$XuQN$X1&c5e-KmWK<;YA!?YTfC z)+Ow#`gV~W&a3AFqKz4cB7UMeZ&zL82oyz4vCk`RSi!8Xtc3EU)`^t-h%VprhyzkR zo^2E*`8XL~#$ShtF~C}H&&tlzkQSc-In6pmwJI7vkGwjKIHNZg(ASrpDt;?-O51Cb zvJ6=o171&}X^h9c5NNF~khM;U_PmwFk~E#h1m*yzr>bWU%=1BP+klIZU;3@EIO<;q zvjfUZGWah`DgPqxaHpdenpE^IMBJ16UF<al-0=4RqwW7~rKP3jJiWs~_}mV4n~! z9+*?8I0xjuR8;;Vy`#@snnr6ojA)Gml=F_$(8yHdyLK!MZEQ$?6Gz+I)Op9}nLs N#Bg-p!P~|>`#&l$x(0?z7K(JhkmO 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 literal 9711 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 diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-switch-rows-regular-orientation-both-horizontally-flipped-both-rev-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-switch-rows-regular-orientation-both-horizontally-flipped-both-rev-1-snap.png index a0a6c2c8ed9e86360984e766248763919b481703..2e0a3765c69149f8437828b5b3c9018a2e733e18 100644 GIT binary patch literal 9336 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 literal 9703 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 NQ&rRg*UDRj{SP0HGI9U_ diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-switch-rows-regular-orientation-both-horizontally-flipped-rev-1-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-switch-rows-regular-orientation-both-horizontally-flipped-rev-1-1-snap.png index b7032a2f0c5097b424b092f393067c39b2f3e6ec..038be94030f4690fac5fbd7bda4a8163d1be74c4 100644 GIT binary patch literal 1938 zcmYjR3sh5A7QHV7`~3&i+M?=KR=r1F^8&&Ll|R+vc)wci#6o&h5))t+`av&Y&Mk zFYcjI|6M|*wifE9cCj}eJWNgYaQULlkrXqOGB*xyc!ZD^NcN#PZ%`WSJF!M;iN zGSQmMn)77Y5cSs}EUJSq65NoSa$^LGNB*}q=Xf)^?$KpYGBIg~Aqi>b!mU246o)L( zms>>7|NowEx%*B?0rXNxx9nk`qtmLH+dJFcCyKp>eQguX%Ek%7gZM2IO&pesVzn6ied4`d1&~0 zU~`@$m$lml%^H!AM~FJ;LDvD=hfRr}B#do3KqNLC#0U&6U%U_44l0D>gP&EB2rj!B zi1jC~M7eAT;rbwe`ClH8$K1=B>DCBj%q^mAuN}y1=CbS;RmSFw7)bD*L6nf>ABAx2k@#lqUQ;w-2GX!d2F~IitwGA z_-U-^z*ZqTOR_=K(SFIu&uQ{wsn2uGm^^&nUpqgMV6`WEowNavc+kb_ThOQS$e^`} zf^9nE9m%>+aA5F|Fp0Ae|N6qc$aoU0v>pO69xka^(^)p$42}6Y9swdwgb#5{ObMGw z>+vVDOKyG(LD5`R3wgZPtalA^u94JB_W()PvLmYwDDp7CJXWht|8$aFYYA~U%3yYt zQ$fq(-xgil0-ME6uhLdykUJ>E`0SeUB~Ue)M(1&)XODxmHv%cj^F})vn?S7QAlVy zp}}oy*%95YuJ&Z0LQt(d$?lG4*6qq+?B)8K*PDU?L?3`iOIDdkP7Sw}`& z6t-n21365ECZ;ZgV+3aZ2M^lHz=IrsP)qdt97f(zq&12ulR;_46ReHc- ze@F^9QSR~QtA$&cE^2zEz1vNb@4{a5VcUUQE1S5ZTlr2QQc3`Uw z`T;*-CE|VR^ovtd$2A#SkOmyae3qrOf(|&`9-V<%HdsMo8P}8^qmEB6bqjO#nMFXe z`)Z1oDZL4Yyu|ZN^SHV}Dx;65*UZnn8?nn@N6wtgOzfV|vH^XU;GoROKX6$D;yRvF zt*r6>if*}hOgOGFKac(n1)DD37tyyD!&-g7AQqL2%5Ut+P*eBKU`L#I&-|f#9JwX5E_8lo94%}^XrJhUKC=vHg}8~&H*|ep@u~)@hL5d^jf?8n=d9M);Z-~| zim%k=wM83|cr`d;N{MS**8wr)R06?i|MhL8#kOBG*8^S?)&ZI*lBH+p7JP!^S9WN| zxN8?`Wx4)@-fQ5)U!O=0Y`a3sP;dD;wmu9x)ECJ6ty?iCj@Je>%JDihHPQwr((^{yA6(j(9{Q^2RftlKC)rN9`cAOAyuY!ZIW%#Ud!xq zr^wy1>j`*%$6zh?UDC&s?w(M~)(^Q<74%T${@UbJG5E6(ia7CzH8dVY3v>EfcZM(w kiB0(Ga^AC-G3HNFEaq&CUA36PM{pfI;_uz@X;kii0OG4NJ^%m! literal 2076 zcmXw43pmty7ykW?%+R=@NE?+xrV2{ntS`h>zdU*ePZzq~zTsFJwl zgs-8X-rY-uw5~R&_rQ6J(xX{pOM=;@tQV6WdzK4CMh3BkVsX;kpm*R}L~hrfX^UOC zHY7IXUe4$o5q^1*JAN&Y_%LvEy%{1{vEmjz?hZTZ*T%Pe(m-<-nAAhcuG}uy2jf31 zx~=?*FhdU}GV>{>^Tq?3en{5R%oXhJv$aHx1qciJ!%M{Pq4xV&FMsZdMEyKz5+cmU z+rM-u95r$)NaoO!Wl>5Vp4hDQ=u71Fkp1W4+DK{?M=5Eh>&>T6dZ>T74|cKwr5+aQ zQ&9NhS&rYRx{#*!o{84!;eq{rahtVi)@S>u2fv0o0|b8aZE2L4p69b_4^ zljUKm>u!;q{|3Vh_cBrU{cKK8SumNWK%(GOtrhg zzGa~SIsqq{S(=V;uVxiF6sltXM};eh!fMPbFH}~t(uivi^zRCPEcL2+rK~{^MsoxR z?d}Kze#d-yl8MPsAQ0-tD4yjl#r+wwKbsE1RKXN^a9dIe1TshFsvVS>MLHCu{(v&KEm?^0@D6Q09yK94VQ?4FC+ zWu1z%?@&JzVeIq83x`Ig1GHbM3-`vn#;`khFlWaCue-H6nXWE$!#*NlKNQ%R;dGFq>pcqQgW{t5}z?}1aF z2bfr{Fz!=H*n}n^{3~Y-OG%2h8)yf@g$$eZnvK_v=~F#-X)vRqT(sfa0Z~&g z&&^(kMtYExQ2ECI`&V%1U0bV5dSl<#AUkPHilXXz?*?loW=m`*L_3 z*91!P_}Z_?>C`IuRC1(o#RlF1Xs9gUtXgaHR2G8RfD7Y1qbgwin;_~t#zYtT(M{9R1hwnb>eIXi<>Fv&Qll|JF#LExk5w=WR~OFcH~nDDZ&$D#5rS> z;02ZnR5(2w_^&91Rt2_TU4j#w8hF2v*B2`@UHORf4xs7+RW(d}vD#6tc#TYLEmRx`rxoQInF-xV!gKB!aF-tNp@TFX;GDQR^FSXCpzHZGi{4SLR(e&8-%6W&zbD;Ep&K zcW-vDeHy45H$JgSkfcrU$CjKjf`96rhY}ygOPsQmr5!=8$X{Wzq#i2Bf{#Q!Ynzt# zmU?dfalM91Fcq#avT}FF_|YxI9)79{6$>H)^0$wSH!tV@aVW{j98DI5HxCHa{Y+0n zdp1BLB5!tRzSej&5f;cq5+V)Lv6&k!4bbf>xDOLhIRAIy&FV>ZFB&Y*S{14$LLS`E zZlh900yTIT7LW~y@*j;ii9T8xv6(lY4{Q3h0j#_01~Uuo#hjXPlk>nN$r8~_qBL}R zIUz8CyP+z=T;3VawrYjZNRXooawhGrd%J}(CQmi$^wN(>n^Ml;PAnTc)cv|(U-`m) z{kF#SE$7KcY+YYK1^wc09H>%pGb1&z0_o5IVnO)mDDeM~%9j$n?aEC#IP! z{UOLKlkCNBaf{14(=``{pz8zp<-d&^w7$`|v1@TCGnlhRiya684g~LHHLr@xI@brt zB1M>mepRm#4^bnJSUL#%bvx|Es$)8dwk-mO4_iC7aE?l^W$(jr@A?An7wHju=a*%C zzHMP+{Z?LM9!EBBn;gnGg!yRWIP=0$0WWFs&Dg3kb03`E_*6V|M4XOjQ!P7+!v1r@ T#pD(|?vcBTmvhzbpwoW?ChT+; diff --git a/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-switch-rows-regular-orientation-both-horizontally-flipped-rev-2-1-snap.png b/products/jbrowse-web/src/tests/__image_snapshots__/synteny-test-tsx-switch-rows-regular-orientation-both-horizontally-flipped-rev-2-1-snap.png index c3b5b5983684cdfa3cff84ad421df6edb126372f..52dc216a523c46450c0b6dcf7bc0df991882a330 100644 GIT binary patch literal 1931 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