@jbrowse/plugin-alignments 1.6.5 → 1.6.6

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (34) hide show
  1. package/dist/AlignmentsFeatureDetail/index.d.ts +1 -1
  2. package/dist/BamAdapter/BamSlightlyLazyFeature.d.ts +3 -2
  3. package/dist/BamAdapter/configSchema.d.ts +1 -1
  4. package/dist/CramAdapter/configSchema.d.ts +1 -1
  5. package/dist/HtsgetBamAdapter/configSchema.d.ts +1 -1
  6. package/dist/LinearAlignmentsDisplay/models/configSchema.d.ts +1 -1
  7. package/dist/LinearAlignmentsDisplay/models/model.d.ts +1 -1
  8. package/dist/LinearPileupDisplay/configSchema.d.ts +1 -1
  9. package/dist/LinearSNPCoverageDisplay/components/Tooltip.d.ts +1 -1
  10. package/dist/LinearSNPCoverageDisplay/models/configSchema.d.ts +1 -1
  11. package/dist/PileupRenderer/configSchema.d.ts +1 -1
  12. package/dist/SNPCoverageAdapter/configSchema.d.ts +1 -1
  13. package/dist/SNPCoverageRenderer/SNPCoverageRenderer.d.ts +1 -1
  14. package/dist/SNPCoverageRenderer/configSchema.d.ts +1 -1
  15. package/dist/SNPCoverageRenderer/index.d.ts +1 -1
  16. package/dist/plugin-alignments.cjs.development.js +254 -180
  17. package/dist/plugin-alignments.cjs.development.js.map +1 -1
  18. package/dist/plugin-alignments.cjs.production.min.js +1 -1
  19. package/dist/plugin-alignments.cjs.production.min.js.map +1 -1
  20. package/dist/plugin-alignments.esm.js +254 -180
  21. package/dist/plugin-alignments.esm.js.map +1 -1
  22. package/package.json +4 -4
  23. package/src/AlignmentsFeatureDetail/AlignmentsFeatureDetail.tsx +23 -14
  24. package/src/BamAdapter/BamSlightlyLazyFeature.ts +8 -4
  25. package/src/LinearAlignmentsDisplay/components/AlignmentsDisplay.tsx +38 -30
  26. package/src/LinearAlignmentsDisplay/models/model.tsx +6 -3
  27. package/src/LinearPileupDisplay/model.ts +6 -6
  28. package/src/LinearSNPCoverageDisplay/components/Tooltip.tsx +5 -3
  29. package/src/LinearSNPCoverageDisplay/models/configSchema.ts +4 -5
  30. package/src/PileupRenderer/PileupRenderer.tsx +28 -17
  31. package/src/PileupRenderer/components/PileupRendering.tsx +5 -3
  32. package/src/SNPCoverageAdapter/SNPCoverageAdapter.ts +28 -24
  33. package/src/SNPCoverageRenderer/SNPCoverageRenderer.ts +86 -56
  34. package/src/SNPCoverageRenderer/configSchema.js +1 -1
@@ -29,6 +29,7 @@ var DisplayType = _interopDefault(require('@jbrowse/core/pluggableElementTypes/D
29
29
  var pluginLinearGenomeView = require('@jbrowse/plugin-linear-genome-view');
30
30
  var models = require('@jbrowse/core/pluggableElementTypes/models');
31
31
  var mobx = require('mobx');
32
+ var core = require('@material-ui/core');
32
33
  var SerializableFilterChain = _interopDefault(require('@jbrowse/core/pluggableElementTypes/renderers/util/serializableFilterChain'));
33
34
  var tracks = require('@jbrowse/core/util/tracks');
34
35
  var VisibilityIcon = _interopDefault(require('@material-ui/icons/Visibility'));
@@ -46,7 +47,6 @@ var RpcMethodType = _interopDefault(require('@jbrowse/core/pluggableElementTypes
46
47
  var cram = require('@gmod/cram');
47
48
  var io = require('@jbrowse/core/util/io');
48
49
  var bam = require('@gmod/bam');
49
- var core = require('@material-ui/core');
50
50
  var CloseIcon = _interopDefault(require('@material-ui/icons/Close'));
51
51
  var BaseFeatureDetail = require('@jbrowse/core/BaseFeatureWidget/BaseFeatureDetail');
52
52
 
@@ -1949,18 +1949,16 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
1949
1949
  bins = _yield$_this$generate.bins;
1950
1950
  skipmap = _yield$_this$generate.skipmap;
1951
1951
  bins.forEach(function (bin, index) {
1952
- if (bin.total) {
1953
- observer.next(new SimpleFeature({
1954
- id: "".concat(_this.id, "-").concat(region.start, "-").concat(index),
1955
- data: {
1956
- score: bin.total,
1957
- snpinfo: bin,
1958
- start: region.start + index,
1959
- end: region.start + index + 1,
1960
- refName: region.refName
1961
- }
1962
- }));
1963
- }
1952
+ observer.next(new SimpleFeature({
1953
+ id: "".concat(_this.id, "-").concat(region.start, "-").concat(index),
1954
+ data: {
1955
+ score: bin.total,
1956
+ snpinfo: bin,
1957
+ start: region.start + index,
1958
+ end: region.start + index + 1,
1959
+ refName: region.refName
1960
+ }
1961
+ }));
1964
1962
  }); // make fake features from the coverage
1965
1963
 
1966
1964
  Object.entries(skipmap).forEach(function (_ref2) {
@@ -2126,7 +2124,7 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
2126
2124
  var fstrand = feature.get('strand');
2127
2125
  var cigarOps = parseCigar(cigar);
2128
2126
 
2129
- for (var j = fstart; j < fend; j++) {
2127
+ for (var j = fstart; j < fend + 1; j++) {
2130
2128
  var i = j - region.start;
2131
2129
 
2132
2130
  if (i >= 0 && i < binMax) {
@@ -2138,8 +2136,12 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
2138
2136
  noncov: {},
2139
2137
  ref: {}
2140
2138
  };
2141
- bin.total++;
2142
- inc(bin, fstrand, 'ref', 'ref');
2139
+
2140
+ if (j !== fend) {
2141
+ bin.total++;
2142
+ inc(bin, fstrand, 'ref', 'ref');
2143
+ }
2144
+
2143
2145
  bins[i] = bin;
2144
2146
  }
2145
2147
  }
@@ -2172,7 +2174,14 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
2172
2174
  var epos = pos + fstart - region.start;
2173
2175
 
2174
2176
  if (epos >= 0 && epos < bins.length && pos + fstart < fend) {
2175
- var _bin = bins[epos];
2177
+ var _bin = bins[epos] || {
2178
+ total: 0,
2179
+ lowqual: {},
2180
+ cov: {},
2181
+ delskips: {},
2182
+ noncov: {},
2183
+ ref: {}
2184
+ };
2176
2185
 
2177
2186
  if (probabilities[probIndex] > 0.5) {
2178
2187
  inc(_bin, fstrand, 'cov', mod);
@@ -2261,9 +2270,9 @@ var SNPCoverageAdapter = /*#__PURE__*/function (_BaseFeatureDataAdapt) {
2261
2270
  if (mismatches) {
2262
2271
  for (var _i2 = 0; _i2 < mismatches.length; _i2++) {
2263
2272
  var mismatch = mismatches[_i2];
2264
- var mstart = fstart + mismatch.start;
2273
+ var ms = fstart + mismatch.start;
2265
2274
 
2266
- for (var _j2 = mstart; _j2 < mstart + mismatchLen(mismatch); _j2++) {
2275
+ for (var _j2 = ms; _j2 < ms + mismatchLen(mismatch); _j2++) {
2267
2276
  var epos = _j2 - region.start;
2268
2277
 
2269
2278
  if (epos >= 0 && epos < bins.length) {
@@ -2379,7 +2388,7 @@ var ConfigSchema = /*#__PURE__*/configuration.ConfigurationSchema('SNPCoverageRe
2379
2388
  indicatorThreshold: {
2380
2389
  type: 'number',
2381
2390
  description: 'the proportion of reads containing a insertion/clip indicator',
2382
- defaultValue: 0.3
2391
+ defaultValue: 0.4
2383
2392
  },
2384
2393
  drawArcs: {
2385
2394
  type: 'boolean',
@@ -2420,12 +2429,13 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2420
2429
  regions = props.regions,
2421
2430
  bpPerPx = props.bpPerPx,
2422
2431
  displayCrossHatches = props.displayCrossHatches,
2423
- modificationTagMap = props.modificationTagMap,
2432
+ _props$modificationTa = props.modificationTagMap,
2433
+ modificationTagMap = _props$modificationTa === void 0 ? {} : _props$modificationTa,
2424
2434
  scaleOpts = props.scaleOpts,
2425
2435
  unadjustedHeight = props.height,
2426
2436
  configTheme = props.theme,
2427
2437
  cfg = props.config,
2428
- values = props.ticks.values;
2438
+ ticks = props.ticks;
2429
2439
  var theme = ui.createJBrowseTheme(configTheme);
2430
2440
 
2431
2441
  var _regions = _slicedToArray(regions, 1),
@@ -2437,6 +2447,11 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2437
2447
 
2438
2448
  var offset = pluginWiggle.YSCALEBAR_LABEL_OFFSET;
2439
2449
  var height = unadjustedHeight - offset * 2;
2450
+ var domain = scaleOpts.domain;
2451
+
2452
+ if (!domain) {
2453
+ return;
2454
+ }
2440
2455
 
2441
2456
  var opts = _objectSpread2(_objectSpread2({}, scaleOpts), {}, {
2442
2457
  range: [0, height]
@@ -2444,6 +2459,12 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2444
2459
 
2445
2460
  var viewScale = pluginWiggle.getScale(opts);
2446
2461
  var snpViewScale = pluginWiggle.getScale(_objectSpread2(_objectSpread2({}, opts), {}, {
2462
+ range: [0, height],
2463
+ scaleType: 'linear'
2464
+ })); // clipping and insertion indicators, uses a smaller height/2 scale
2465
+
2466
+ var indicatorViewScale = pluginWiggle.getScale(_objectSpread2(_objectSpread2({}, opts), {}, {
2467
+ range: [0, height / 2],
2447
2468
  scaleType: 'linear'
2448
2469
  }));
2449
2470
  var originY = pluginWiggle.getOrigin(scaleOpts.scaleType);
@@ -2466,10 +2487,18 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2466
2487
  return height - (snpViewScale(n) || 0) + offset;
2467
2488
  };
2468
2489
 
2490
+ var indicatorToY = function indicatorToY(n) {
2491
+ return height - (indicatorViewScale(n) || 0) + offset;
2492
+ };
2493
+
2469
2494
  var snpToHeight = function snpToHeight(n) {
2470
2495
  return snpToY(snpOriginY) - snpToY(n);
2471
2496
  };
2472
2497
 
2498
+ var indicatorToHeight = function indicatorToHeight(n) {
2499
+ return indicatorToY(snpOriginY) - indicatorToY(n);
2500
+ };
2501
+
2473
2502
  var colorForBase = {
2474
2503
  A: theme.palette.bases.A.main,
2475
2504
  C: theme.palette.bases.C.main,
@@ -2495,7 +2524,10 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2495
2524
  // bpPerPx First pass: draw the gray background
2496
2525
 
2497
2526
  ctx.fillStyle = colorForBase.total;
2498
- coverage.forEach(function (feature) {
2527
+
2528
+ for (var i = 0; i < coverage.length; i++) {
2529
+ var feature = coverage[i];
2530
+
2499
2531
  var _featureSpanPx = util.featureSpanPx(feature, region, bpPerPx),
2500
2532
  _featureSpanPx2 = _slicedToArray(_featureSpanPx, 2),
2501
2533
  leftPx = _featureSpanPx2[0],
@@ -2504,96 +2536,97 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2504
2536
  var w = rightPx - leftPx + 0.3;
2505
2537
  var score = feature.get('score');
2506
2538
  ctx.fillRect(leftPx, toY(score), w, toHeight(score));
2507
- });
2508
- ctx.fillStyle = 'grey';
2509
- ctx.beginPath();
2510
- ctx.lineTo(0, 0);
2511
- ctx.moveTo(0, width);
2512
- ctx.stroke(); // Second pass: draw the SNP data, and add a minimum feature width of 1px
2539
+ } // Keep track of previous total which we will use it to draw the interbase
2540
+ // indicator (if there is a sudden clip, there will be no read coverage but
2541
+ // there will be "clip" coverage) at that position beyond the read. if the
2542
+ // clip is right at a block boundary then prevTotal will not be available,
2543
+ // so this is a best attempt to plot interbase indicator at the "cliffs"
2544
+
2545
+
2546
+ var prevTotal = 0; // extraHorizontallyFlippedOffset is used to draw interbase items, which
2547
+ // are located to the left when forward and right when reversed
2548
+
2549
+ var extraHorizontallyFlippedOffset = region.reversed ? 1 / bpPerPx : 0; // Second pass: draw the SNP data, and add a minimum feature width of 1px
2513
2550
  // which can be wider than the actual bpPerPx This reduces overdrawing of
2514
2551
  // the grey background over the SNPs
2515
2552
 
2516
- coverage.forEach(function (feature) {
2517
- var _featureSpanPx3 = util.featureSpanPx(feature, region, bpPerPx),
2518
- _featureSpanPx4 = _slicedToArray(_featureSpanPx3, 2),
2519
- leftPx = _featureSpanPx4[0],
2520
- rightPx = _featureSpanPx4[1];
2553
+ for (var _i = 0; _i < coverage.length; _i++) {
2554
+ var _feature = coverage[_i];
2521
2555
 
2522
- var snpinfo = feature.get('snpinfo');
2523
- var w = Math.max(rightPx - leftPx + 0.3, 1);
2524
- var totalScore = snpinfo.total;
2525
- Object.entries(snpinfo.cov).sort(function (_ref, _ref2) {
2526
- var _ref3 = _slicedToArray(_ref, 1),
2527
- a = _ref3[0];
2556
+ var _featureSpanPx3 = util.featureSpanPx(_feature, region, bpPerPx),
2557
+ _featureSpanPx4 = _slicedToArray(_featureSpanPx3, 2),
2558
+ _leftPx = _featureSpanPx4[0],
2559
+ _rightPx = _featureSpanPx4[1];
2528
2560
 
2529
- var _ref4 = _slicedToArray(_ref2, 1),
2530
- b = _ref4[0];
2561
+ var snpinfo = _feature.get('snpinfo');
2531
2562
 
2532
- if (a < b) {
2533
- return -1;
2534
- }
2563
+ var _w = Math.max(_rightPx - _leftPx + 0.3, 1);
2535
2564
 
2536
- if (a > b) {
2537
- return 1;
2538
- }
2565
+ var totalScore = snpinfo.total;
2566
+ var keys = Object.keys(snpinfo.cov).sort();
2567
+ var curr = 0;
2568
+
2569
+ for (var _i2 = 0; _i2 < keys.length; _i2++) {
2570
+ var base = keys[_i2];
2571
+ var total = snpinfo.cov[base].total;
2572
+ ctx.fillStyle = colorForBase[base] || modificationTagMap[base.replace('mod_', '')] || '#888';
2573
+ ctx.fillRect(_leftPx, snpToY(total + curr), _w, snpToHeight(total));
2574
+ curr += total;
2575
+ }
2539
2576
 
2540
- return 0;
2541
- }).reduce(function (curr, _ref5) {
2542
- var _ref6 = _slicedToArray(_ref5, 2),
2543
- base = _ref6[0],
2544
- total = _ref6[1].total;
2545
-
2546
- ctx.fillStyle = colorForBase[base] || modificationTagMap[base.replace('mod_', '')] || 'red';
2547
- ctx.fillRect(leftPx, snpToY(total + curr), w, snpToHeight(total));
2548
- return curr + total;
2549
- }, 0);
2550
- var interbaseEvents = Object.entries(snpinfo.noncov);
2577
+ var interbaseEvents = Object.keys(snpinfo.noncov);
2551
2578
  var indicatorHeight = 4.5;
2552
2579
 
2553
2580
  if (drawInterbaseCounts) {
2554
- interbaseEvents.reduce(function (curr, _ref7) {
2555
- var _ref8 = _slicedToArray(_ref7, 2),
2556
- base = _ref8[0],
2557
- total = _ref8[1].total;
2558
-
2559
- ctx.fillStyle = colorForBase[base];
2560
- ctx.fillRect(leftPx - 0.6, indicatorHeight + snpToHeight(curr), 1.2, snpToHeight(total));
2561
- return curr + total;
2562
- }, 0);
2581
+ var _curr = 0;
2582
+
2583
+ for (var _i3 = 0; _i3 < interbaseEvents.length; _i3++) {
2584
+ var _base = interbaseEvents[_i3];
2585
+ var _total = snpinfo.noncov[_base].total;
2586
+ ctx.fillStyle = colorForBase[_base];
2587
+ ctx.fillRect(_leftPx - 0.6 + extraHorizontallyFlippedOffset, indicatorHeight + indicatorToHeight(_curr), 1.2, indicatorToHeight(_total));
2588
+ _curr += _total;
2589
+ }
2563
2590
  }
2564
2591
 
2565
2592
  if (drawIndicators) {
2566
2593
  var accum = 0;
2567
2594
  var max = 0;
2568
2595
  var maxBase = '';
2569
- interbaseEvents.forEach(function (_ref9) {
2570
- var _ref10 = _slicedToArray(_ref9, 2),
2571
- base = _ref10[0],
2572
- total = _ref10[1].total;
2573
2596
 
2574
- accum += total;
2597
+ for (var _i4 = 0; _i4 < interbaseEvents.length; _i4++) {
2598
+ var _base2 = interbaseEvents[_i4];
2599
+ var _total2 = snpinfo.noncov[_base2].total;
2600
+ accum += _total2;
2575
2601
 
2576
- if (total > max) {
2577
- max = total;
2578
- maxBase = base;
2602
+ if (_total2 > max) {
2603
+ max = _total2;
2604
+ maxBase = _base2;
2579
2605
  }
2580
- }); // avoid drawing a bunch of indicators if coverage is very low e.g.
2581
- // less than 7
2606
+ } // avoid drawing a bunch of indicators if coverage is very low e.g.
2607
+ // less than 7, uses the prev total in the case of the "cliff"
2582
2608
 
2583
- if (accum > totalScore * indicatorThreshold && totalScore > 7) {
2609
+
2610
+ var indicatorComparatorScore = Math.max(totalScore, prevTotal);
2611
+
2612
+ if (accum > indicatorComparatorScore * indicatorThreshold && indicatorComparatorScore > 7) {
2584
2613
  ctx.fillStyle = colorForBase[maxBase];
2585
2614
  ctx.beginPath();
2586
- ctx.moveTo(leftPx - 3, 0);
2587
- ctx.lineTo(leftPx + 3, 0);
2588
- ctx.lineTo(leftPx, indicatorHeight);
2615
+ var l = _leftPx + extraHorizontallyFlippedOffset;
2616
+ ctx.moveTo(l - 3.5, 0);
2617
+ ctx.lineTo(l + 3.5, 0);
2618
+ ctx.lineTo(l, indicatorHeight);
2589
2619
  ctx.fill();
2590
2620
  }
2591
2621
  }
2592
- });
2593
- ctx.globalAlpha = 0.7;
2622
+
2623
+ prevTotal = totalScore;
2624
+ }
2594
2625
 
2595
2626
  if (drawArcs) {
2596
- skips.forEach(function (f) {
2627
+ for (var _i5 = 0; _i5 < skips.length; _i5++) {
2628
+ var f = skips[_i5];
2629
+
2597
2630
  var _bpSpanPx = util.bpSpanPx(f.get('start'), f.get('end'), region, bpPerPx),
2598
2631
  _bpSpanPx2 = _slicedToArray(_bpSpanPx, 2),
2599
2632
  left = _bpSpanPx2[0],
@@ -2602,9 +2635,9 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2602
2635
  ctx.beginPath();
2603
2636
  var str = f.get('strand');
2604
2637
  var xs = f.get('xs');
2605
- var pos = 'rgb(255,200,200)';
2606
- var neg = 'rgb(200,200,255)';
2607
- var neutral = 'rgb(200,200,200)';
2638
+ var pos = 'rgba(255,200,200,0.7)';
2639
+ var neg = 'rgba(200,200,255,0.7)';
2640
+ var neutral = 'rgba(200,200,200,0.7)';
2608
2641
 
2609
2642
  if (xs === '+') {
2610
2643
  ctx.strokeStyle = pos;
@@ -2622,13 +2655,13 @@ var SNPCoverageRenderer = /*#__PURE__*/function (_WiggleBaseRenderer) {
2622
2655
  ctx.moveTo(left, height - offset * 2);
2623
2656
  ctx.bezierCurveTo(left, 0, right, 0, right, height - offset * 2);
2624
2657
  ctx.stroke();
2625
- });
2658
+ }
2626
2659
  }
2627
2660
 
2628
2661
  if (displayCrossHatches) {
2629
2662
  ctx.lineWidth = 1;
2630
2663
  ctx.strokeStyle = 'rgba(140,140,140,0.8)';
2631
- values.forEach(function (tick) {
2664
+ ticks.values.forEach(function (tick) {
2632
2665
  ctx.beginPath();
2633
2666
  ctx.moveTo(0, Math.round(toY(tick)));
2634
2667
  ctx.lineTo(width, Math.round(toY(tick)));
@@ -3065,9 +3098,11 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3065
3098
  var modifications = getModificationPositions(mm, seq, strand); // probIndex applies across multiple modifications e.g.
3066
3099
 
3067
3100
  var probIndex = 0;
3068
- modifications.forEach(function (_ref2) {
3069
- var type = _ref2.type,
3070
- positions = _ref2.positions;
3101
+
3102
+ for (var i = 0; i < modifications.length; i++) {
3103
+ var _modifications$i = modifications[i],
3104
+ type = _modifications$i.type,
3105
+ positions = _modifications$i.positions;
3071
3106
  var col = modificationTagMap[type] || 'black';
3072
3107
  var base = Color(col);
3073
3108
 
@@ -3097,7 +3132,7 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3097
3132
  } finally {
3098
3133
  _iterator.f();
3099
3134
  }
3100
- });
3135
+ }
3101
3136
  } // Color by methylation is slightly modified version of color by
3102
3137
  // modifications
3103
3138
  //
@@ -3124,9 +3159,12 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3124
3159
  var rstart = region.start,
3125
3160
  rend = region.end;
3126
3161
  var methBins = new Array(rend - rstart).fill(0);
3127
- getModificationPositions(mm, seq, strand).forEach(function (_ref3) {
3128
- var type = _ref3.type,
3129
- positions = _ref3.positions;
3162
+ var modifications = getModificationPositions(mm, seq, strand);
3163
+
3164
+ for (var i = 0; i < modifications.length; i++) {
3165
+ var _modifications$i2 = modifications[i],
3166
+ type = _modifications$i2.type,
3167
+ positions = _modifications$i2.positions;
3130
3168
 
3131
3169
  if (type === 'm' && positions) {
3132
3170
  var _iterator2 = _createForOfIteratorHelper(getNextRefPos(cigarOps, positions)),
@@ -3147,25 +3185,27 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3147
3185
  _iterator2.f();
3148
3186
  }
3149
3187
  }
3150
- });
3188
+ }
3151
3189
 
3152
3190
  for (var j = fstart; j < fend; j++) {
3153
- var i = j - rstart;
3191
+ var _i = j - rstart;
3192
+
3193
+ if (_i >= 0 && _i < methBins.length) {
3194
+ var l1 = regionSequence[_i].toLowerCase();
3195
+
3196
+ var l2 = regionSequence[_i + 1].toLowerCase(); // if we are zoomed out, display just a block over the cpg
3154
3197
 
3155
- if (i >= 0 && i < methBins.length) {
3156
- var l1 = regionSequence[i].toLowerCase();
3157
- var l2 = regionSequence[i + 1].toLowerCase(); // if we are zoomed out, display just a block over the cpg
3158
3198
 
3159
3199
  if (bpPerPx > 2) {
3160
3200
  if (l1 === 'c' && l2 === 'g') {
3161
- var s = rstart + i;
3201
+ var s = rstart + _i;
3162
3202
 
3163
3203
  var _bpSpanPx7 = util.bpSpanPx(s, s + 2, region, bpPerPx),
3164
3204
  _bpSpanPx8 = _slicedToArray(_bpSpanPx7, 2),
3165
3205
  leftPx = _bpSpanPx8[0],
3166
3206
  rightPx = _bpSpanPx8[1];
3167
3207
 
3168
- if (methBins[i] || methBins[i + 1]) {
3208
+ if (methBins[_i] || methBins[_i + 1]) {
3169
3209
  ctx.fillStyle = 'red';
3170
3210
  } else {
3171
3211
  ctx.fillStyle = 'blue';
@@ -3177,14 +3217,14 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3177
3217
  else {
3178
3218
  // color
3179
3219
  if (l1 === 'c' && l2 === 'g') {
3180
- var _s = rstart + i;
3220
+ var _s = rstart + _i;
3181
3221
 
3182
3222
  var _bpSpanPx9 = util.bpSpanPx(_s, _s + 1, region, bpPerPx),
3183
3223
  _bpSpanPx10 = _slicedToArray(_bpSpanPx9, 2),
3184
3224
  _leftPx = _bpSpanPx10[0],
3185
3225
  _rightPx = _bpSpanPx10[1];
3186
3226
 
3187
- if (methBins[i]) {
3227
+ if (methBins[_i]) {
3188
3228
  ctx.fillStyle = 'red';
3189
3229
  } else {
3190
3230
  ctx.fillStyle = 'blue';
@@ -3197,7 +3237,7 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3197
3237
  leftPx2 = _bpSpanPx12[0],
3198
3238
  rightPx2 = _bpSpanPx12[1];
3199
3239
 
3200
- if (methBins[i + 1]) {
3240
+ if (methBins[_i + 1]) {
3201
3241
  ctx.fillStyle = 'red';
3202
3242
  } else {
3203
3243
  ctx.fillStyle = 'blue';
@@ -3264,11 +3304,11 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3264
3304
  _props$colorTagMap = props.colorTagMap,
3265
3305
  colorTagMap = _props$colorTagMap === void 0 ? {} : _props$colorTagMap;
3266
3306
 
3267
- var _ref4 = colorBy || {},
3268
- _ref4$tag = _ref4.tag,
3269
- tag = _ref4$tag === void 0 ? '' : _ref4$tag,
3270
- _ref4$type = _ref4.type,
3271
- colorType = _ref4$type === void 0 ? '' : _ref4$type;
3307
+ var _ref2 = colorBy || {},
3308
+ _ref2$tag = _ref2.tag,
3309
+ tag = _ref2$tag === void 0 ? '' : _ref2$tag,
3310
+ _ref2$type = _ref2.type,
3311
+ colorType = _ref2$type === void 0 ? '' : _ref2$type;
3272
3312
 
3273
3313
  var feature = feat.feature;
3274
3314
  var region = regions[0]; // first pass for simple color changes that change the color of the
@@ -3395,9 +3435,12 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3395
3435
  }
3396
3436
 
3397
3437
  return color;
3398
- } // two pass rendering: first pass, draw all the mismatches except wide
3399
- // insertion markers
3438
+ } // extraHorizontallyFlippedOffset is used to draw interbase items, which
3439
+ // are located to the left when forward and right when reversed
3440
+
3400
3441
 
3442
+ var extraHorizontallyFlippedOffset = region.reversed ? 1 / bpPerPx + 1 : -1; // two pass rendering: first pass, draw all the mismatches except wide
3443
+ // insertion markers
3401
3444
 
3402
3445
  for (var i = 0; i < mismatches.length; i += 1) {
3403
3446
  var mismatch = mismatches[i];
@@ -3435,32 +3478,36 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3435
3478
  }
3436
3479
  } else if (mismatch.type === 'insertion' && drawIndels) {
3437
3480
  ctx.fillStyle = 'purple';
3438
- var pos = leftPx - 1;
3481
+ var pos = leftPx + extraHorizontallyFlippedOffset;
3439
3482
  var len = +mismatch.base || mismatch.length;
3483
+ var insW = Math.max(minWidth, Math.min(1.2, 1 / bpPerPx));
3440
3484
 
3441
3485
  if (len < 10) {
3442
- ctx.fillRect(pos, topPx, w, heightPx);
3486
+ ctx.fillRect(pos, topPx, insW, heightPx);
3443
3487
 
3444
3488
  if (1 / bpPerPx >= charWidth) {
3445
- ctx.fillRect(pos - w, topPx, w * 3, 1);
3446
- ctx.fillRect(pos - w, topPx + heightPx - 1, w * 3, 1);
3489
+ ctx.fillRect(pos - insW, topPx, insW * 3, 1);
3490
+ ctx.fillRect(pos - insW, topPx + heightPx - 1, insW * 3, 1);
3447
3491
  }
3448
3492
 
3449
3493
  if (1 / bpPerPx >= charWidth && heightPx >= heightLim) {
3450
- ctx.fillText("(".concat(mismatch.base, ")"), leftPx + 2, topPx + heightPx);
3494
+ ctx.fillText("(".concat(mismatch.base, ")"), pos + 3, topPx + heightPx);
3451
3495
  }
3452
3496
  }
3453
3497
  } else if (mismatch.type === 'hardclip' || mismatch.type === 'softclip') {
3454
3498
  ctx.fillStyle = mismatch.type === 'hardclip' ? 'red' : 'blue';
3455
3499
 
3456
- var _pos = leftPx - 1;
3500
+ var _pos = leftPx + extraHorizontallyFlippedOffset;
3501
+
3502
+ ctx.fillRect(_pos, topPx, w, heightPx);
3457
3503
 
3458
- ctx.fillRect(_pos, topPx + 1, w, heightPx - 2);
3459
- ctx.fillRect(_pos - w, topPx, w * 3, 1);
3460
- ctx.fillRect(_pos - w, topPx + heightPx - 1, w * 3, 1);
3504
+ if (1 / bpPerPx >= charWidth) {
3505
+ ctx.fillRect(_pos - w, topPx, w * 3, 1);
3506
+ ctx.fillRect(_pos - w, topPx + heightPx - 1, w * 3, 1);
3507
+ }
3461
3508
 
3462
3509
  if (widthPx >= charWidth && heightPx >= heightLim) {
3463
- ctx.fillText("(".concat(mismatch.base, ")"), leftPx + 2, topPx + heightPx);
3510
+ ctx.fillText("(".concat(mismatch.base, ")"), _pos + 3, topPx + heightPx);
3464
3511
  }
3465
3512
  } else if (mismatch.type === 'skip') {
3466
3513
  // fix to avoid bad rendering note that this was also related to chrome
@@ -3478,8 +3525,8 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3478
3525
 
3479
3526
 
3480
3527
  if (drawIndels) {
3481
- for (var _i = 0; _i < mismatches.length; _i += 1) {
3482
- var _mismatch = mismatches[_i];
3528
+ for (var _i2 = 0; _i2 < mismatches.length; _i2 += 1) {
3529
+ var _mismatch = mismatches[_i2];
3483
3530
 
3484
3531
  var _mstart = start + _mismatch.start;
3485
3532
 
@@ -3547,7 +3594,8 @@ var PileupRenderer = /*#__PURE__*/function (_BoxRendererType) {
3547
3594
  return mismatch.type === 'softclip';
3548
3595
  }).forEach(function (mismatch) {
3549
3596
  var softClipLength = mismatch.cliplen || 0;
3550
- var softClipStart = mismatch.start === 0 ? feature.get('start') - softClipLength : feature.get('start') + mismatch.start;
3597
+ var s = feature.get('start');
3598
+ var softClipStart = mismatch.start === 0 ? s - softClipLength : s + mismatch.start;
3551
3599
 
3552
3600
  for (var k = 0; k < softClipLength; k += 1) {
3553
3601
  var base = seq.charAt(k + mismatch.start); // If softclip length+start is longer than sequence, no need to
@@ -3943,10 +3991,15 @@ function PileupRendering(props) {
3943
3991
 
3944
3992
  var offsetX = 0;
3945
3993
  var offsetY = 0;
3994
+ var canvas = highlightOverlayCanvas.current;
3946
3995
 
3947
- if (highlightOverlayCanvas.current) {
3948
- offsetX = highlightOverlayCanvas.current.getBoundingClientRect().left;
3949
- offsetY = highlightOverlayCanvas.current.getBoundingClientRect().top;
3996
+ if (canvas) {
3997
+ var _canvas$getBoundingCl = canvas.getBoundingClientRect(),
3998
+ left = _canvas$getBoundingCl.left,
3999
+ top = _canvas$getBoundingCl.top;
4000
+
4001
+ offsetX = left;
4002
+ offsetY = top;
3950
4003
  }
3951
4004
 
3952
4005
  offsetX = event.clientX - offsetX;
@@ -4330,45 +4383,51 @@ var stateModelFactory = function stateModelFactory(pluginManager, configSchema)
4330
4383
  });
4331
4384
  };
4332
4385
 
4386
+ var useStyles = /*#__PURE__*/core.makeStyles(function () {
4387
+ return {
4388
+ resizeHandle: {
4389
+ height: 2,
4390
+ position: 'absolute',
4391
+ zIndex: 2
4392
+ }
4393
+ };
4394
+ });
4395
+
4333
4396
  function AlignmentsDisplay(_ref) {
4334
4397
  var model = _ref.model;
4335
4398
  var PileupDisplay = model.PileupDisplay,
4336
4399
  SNPCoverageDisplay = model.SNPCoverageDisplay,
4337
4400
  showPileup = model.showPileup,
4338
4401
  showCoverage = model.showCoverage;
4402
+ var classes = useStyles();
4403
+ var top = SNPCoverageDisplay.height;
4339
4404
  return /*#__PURE__*/React__default.createElement("div", {
4340
4405
  "data-testid": "display-".concat(configuration.getConf(model, 'displayId')),
4341
4406
  style: {
4342
4407
  position: 'relative'
4343
4408
  }
4344
- }, /*#__PURE__*/React__default.createElement("div", {
4409
+ }, showCoverage ? /*#__PURE__*/React__default.createElement(React__default.Fragment, null, /*#__PURE__*/React__default.createElement("div", {
4345
4410
  "data-testid": "Blockset-snpcoverage"
4346
- }, showCoverage ? /*#__PURE__*/React__default.createElement(SNPCoverageDisplay.RenderingComponent, {
4411
+ }, /*#__PURE__*/React__default.createElement(SNPCoverageDisplay.RenderingComponent, {
4347
4412
  model: SNPCoverageDisplay
4348
- }) : null), /*#__PURE__*/React__default.createElement(ui.ResizeHandle, {
4413
+ })), /*#__PURE__*/React__default.createElement(ui.ResizeHandle, {
4349
4414
  onDrag: function onDrag(delta) {
4350
- if (SNPCoverageDisplay) {
4351
- SNPCoverageDisplay.setHeight(SNPCoverageDisplay.height + delta);
4352
- return delta;
4353
- }
4354
-
4355
- return 0;
4415
+ SNPCoverageDisplay.setHeight(SNPCoverageDisplay.height + delta);
4416
+ return delta;
4356
4417
  },
4418
+ className: classes.resizeHandle,
4357
4419
  style: {
4358
- position: 'absolute',
4359
- top: showCoverage ? SNPCoverageDisplay.height + 2 : 0,
4360
- height: 3
4420
+ top: top
4361
4421
  }
4362
- }), /*#__PURE__*/React__default.createElement("div", {
4422
+ })) : null, showPileup ? /*#__PURE__*/React__default.createElement("div", {
4363
4423
  "data-testid": "Blockset-pileup",
4364
4424
  style: {
4365
4425
  position: 'absolute',
4366
- top: showCoverage ? SNPCoverageDisplay.height + 5 : 0,
4367
- height: 3
4426
+ top: showCoverage ? SNPCoverageDisplay.height : 0
4368
4427
  }
4369
- }, showPileup ? /*#__PURE__*/React__default.createElement(PileupDisplay.RenderingComponent, {
4428
+ }, /*#__PURE__*/React__default.createElement(PileupDisplay.RenderingComponent, {
4370
4429
  model: PileupDisplay
4371
- }) : null));
4430
+ })) : null);
4372
4431
  }
4373
4432
 
4374
4433
  var ReactComponent$1 = /*#__PURE__*/mobxReact.observer(AlignmentsDisplay);
@@ -4417,10 +4476,10 @@ function SNPCoverageConfigFactory(pluginManager) {
4417
4476
  description: 'draw upside down',
4418
4477
  defaultValue: false
4419
4478
  },
4420
- headroom: {
4421
- type: 'number',
4422
- description: 'round the upper value of the domain scale to the nearest N',
4423
- defaultValue: 0
4479
+ multiTicks: {
4480
+ type: 'boolean',
4481
+ description: 'Display multiple values for the ticks',
4482
+ defaultValue: false
4424
4483
  },
4425
4484
  renderers: configuration.ConfigurationSchema('RenderersConfiguration', {
4426
4485
  SNPCoverageRenderer: SNPCoverageRendererConfigSchema
@@ -4440,10 +4499,10 @@ var TooltipContents = /*#__PURE__*/React__default.forwardRef(function (_ref, ref
4440
4499
  var start = feature.get('start');
4441
4500
  var end = feature.get('end');
4442
4501
  var name = feature.get('refName');
4502
+ var info = feature.get('snpinfo');
4443
4503
  var loc = [name, start === end ? en(start) : "".concat(en(start), "..").concat(en(end))].filter(function (f) {
4444
4504
  return !!f;
4445
4505
  }).join(':');
4446
- var info = feature.get('snpinfo');
4447
4506
  var total = info === null || info === void 0 ? void 0 : info.total;
4448
4507
  return /*#__PURE__*/React__default.createElement("div", {
4449
4508
  ref: ref
@@ -4460,7 +4519,7 @@ var TooltipContents = /*#__PURE__*/React__default.forwardRef(function (_ref, ref
4460
4519
  var strands = score.strands;
4461
4520
  return /*#__PURE__*/React__default.createElement("tr", {
4462
4521
  key: base
4463
- }, /*#__PURE__*/React__default.createElement("td", null, base.toUpperCase()), /*#__PURE__*/React__default.createElement("td", null, score.total), /*#__PURE__*/React__default.createElement("td", null, base === 'total' || base === 'skip' ? '---' : "".concat(Math.floor(score.total / total * 100), "%")), /*#__PURE__*/React__default.createElement("td", null, strands['-1'] ? "".concat(strands['-1'], "(-)") : '', strands['1'] ? "".concat(strands['1'], "(+)") : ''), /*#__PURE__*/React__default.createElement("td", null, key));
4522
+ }, /*#__PURE__*/React__default.createElement("td", null, base.toUpperCase()), /*#__PURE__*/React__default.createElement("td", null, score.total), /*#__PURE__*/React__default.createElement("td", null, base === 'total' || base === 'skip' ? '---' : "".concat(Math.floor(score.total / (total || score.total || 1) * 100), "%")), /*#__PURE__*/React__default.createElement("td", null, strands['-1'] ? "".concat(strands['-1'], "(-)") : '', strands['1'] ? "".concat(strands['1'], "(+)") : ''), /*#__PURE__*/React__default.createElement("td", null, key));
4464
4523
  });
4465
4524
  }))));
4466
4525
  });
@@ -6780,6 +6839,7 @@ var BamSlightlyLazyFeature = /*#__PURE__*/function () {
6780
6839
  this.record = record;
6781
6840
  this.adapter = adapter;
6782
6841
  this.ref = ref;
6842
+ this.cachedMD = '';
6783
6843
  }
6784
6844
 
6785
6845
  _createClass(BamSlightlyLazyFeature, [{
@@ -6843,11 +6903,15 @@ var BamSlightlyLazyFeature = /*#__PURE__*/function () {
6843
6903
  }, {
6844
6904
  key: "_get_MD",
6845
6905
  value: function _get_MD() {
6846
- var md = this.record.get('MD');
6847
- var seq = this.get('seq');
6906
+ var md = this.record.get('MD') || this.cachedMD;
6907
+
6908
+ if (!md) {
6909
+ var seq = this.get('seq');
6848
6910
 
6849
- if (!md && seq && this.ref) {
6850
- return generateMD(this.ref, this.record.getReadBases(), this.get('CIGAR'));
6911
+ if (seq && this.ref) {
6912
+ this.cachedMD = generateMD(this.ref, this.get('seq'), this.get('CIGAR'));
6913
+ return this.cachedMD;
6914
+ }
6851
6915
  }
6852
6916
 
6853
6917
  return md;
@@ -7560,7 +7624,7 @@ var HtsgetBamAdapter$1 = {
7560
7624
  'default': HtsgetBamAdapter
7561
7625
  };
7562
7626
 
7563
- var useStyles = /*#__PURE__*/core.makeStyles(function (theme) {
7627
+ var useStyles$1 = /*#__PURE__*/core.makeStyles(function (theme) {
7564
7628
  return {
7565
7629
  root: {
7566
7630
  width: 300
@@ -7575,7 +7639,7 @@ var useStyles = /*#__PURE__*/core.makeStyles(function (theme) {
7575
7639
  });
7576
7640
 
7577
7641
  function ColorByTagDlg$1(props) {
7578
- var classes = useStyles();
7642
+ var classes = useStyles$1();
7579
7643
  var model = props.model,
7580
7644
  handleClose = props.handleClose;
7581
7645
 
@@ -7638,7 +7702,7 @@ var ColorByTag$1 = {
7638
7702
  'default': ColorByTag
7639
7703
  };
7640
7704
 
7641
- var useStyles$1 = /*#__PURE__*/core.makeStyles(function (theme) {
7705
+ var useStyles$2 = /*#__PURE__*/core.makeStyles(function (theme) {
7642
7706
  return {
7643
7707
  root: {
7644
7708
  width: 500
@@ -7696,7 +7760,7 @@ function FilterByTagDlg$1(props) {
7696
7760
 
7697
7761
  var model = props.model,
7698
7762
  handleClose = props.handleClose;
7699
- var classes = useStyles$1();
7763
+ var classes = useStyles$2();
7700
7764
  var filterBy = model.filterBy;
7701
7765
 
7702
7766
  var _useState = React.useState(filterBy === null || filterBy === void 0 ? void 0 : filterBy.flagInclude),
@@ -7817,7 +7881,7 @@ var FilterByTag$1 = {
7817
7881
  'default': FilterByTag
7818
7882
  };
7819
7883
 
7820
- var useStyles$2 = /*#__PURE__*/core.makeStyles(function (theme) {
7884
+ var useStyles$3 = /*#__PURE__*/core.makeStyles(function (theme) {
7821
7885
  return {
7822
7886
  root: {
7823
7887
  margin: 0,
@@ -7833,7 +7897,7 @@ var useStyles$2 = /*#__PURE__*/core.makeStyles(function (theme) {
7833
7897
  });
7834
7898
 
7835
7899
  function SortByTagDlg$1(props) {
7836
- var classes = useStyles$2();
7900
+ var classes = useStyles$3();
7837
7901
  var model = props.model,
7838
7902
  handleClose = props.handleClose;
7839
7903
 
@@ -7883,7 +7947,7 @@ var SortByTag$1 = {
7883
7947
  'default': SortByTag
7884
7948
  };
7885
7949
 
7886
- var useStyles$3 = /*#__PURE__*/core.makeStyles(function (theme) {
7950
+ var useStyles$4 = /*#__PURE__*/core.makeStyles(function (theme) {
7887
7951
  return {
7888
7952
  root: {
7889
7953
  margin: theme.spacing(4)
@@ -7898,7 +7962,7 @@ var useStyles$3 = /*#__PURE__*/core.makeStyles(function (theme) {
7898
7962
  });
7899
7963
 
7900
7964
  function SetFeatureHeightDlg$1(props) {
7901
- var classes = useStyles$3();
7965
+ var classes = useStyles$4();
7902
7966
  var model = props.model,
7903
7967
  handleClose = props.handleClose;
7904
7968
  var featureHeightSetting = model.featureHeightSetting,
@@ -7961,7 +8025,7 @@ var SetFeatureHeight$1 = {
7961
8025
  'default': SetFeatureHeight
7962
8026
  };
7963
8027
 
7964
- var useStyles$4 = /*#__PURE__*/core.makeStyles(function (theme) {
8028
+ var useStyles$5 = /*#__PURE__*/core.makeStyles(function (theme) {
7965
8029
  return {
7966
8030
  root: {
7967
8031
  width: 500
@@ -7981,7 +8045,7 @@ var useStyles$4 = /*#__PURE__*/core.makeStyles(function (theme) {
7981
8045
  function SetMaxHeightDlg$1(props) {
7982
8046
  var model = props.model,
7983
8047
  handleClose = props.handleClose;
7984
- var classes = useStyles$4();
8048
+ var classes = useStyles$5();
7985
8049
  var _model$maxHeight = model.maxHeight,
7986
8050
  maxHeight = _model$maxHeight === void 0 ? '' : _model$maxHeight;
7987
8051
 
@@ -8028,7 +8092,7 @@ var SetMaxHeight$1 = {
8028
8092
  'default': SetMaxHeight
8029
8093
  };
8030
8094
 
8031
- var useStyles$5 = /*#__PURE__*/core.makeStyles(function (theme) {
8095
+ var useStyles$6 = /*#__PURE__*/core.makeStyles(function (theme) {
8032
8096
  return {
8033
8097
  root: {},
8034
8098
  closeButton: {
@@ -8049,7 +8113,7 @@ var useStyles$5 = /*#__PURE__*/core.makeStyles(function (theme) {
8049
8113
 
8050
8114
  function ModificationTable(_ref) {
8051
8115
  var modifications = _ref.modifications;
8052
- var classes = useStyles$5();
8116
+ var classes = useStyles$6();
8053
8117
  return /*#__PURE__*/React__default.createElement("table", {
8054
8118
  className: classes.table
8055
8119
  }, /*#__PURE__*/React__default.createElement("tbody", null, modifications.map(function (_ref2) {
@@ -8069,7 +8133,7 @@ function ModificationTable(_ref) {
8069
8133
  }
8070
8134
 
8071
8135
  function ColorByTagDlg$2(props) {
8072
- var classes = useStyles$5();
8136
+ var classes = useStyles$6();
8073
8137
  var model = props.model,
8074
8138
  handleClose = props.handleClose;
8075
8139
  var colorBy = model.colorBy,
@@ -8143,7 +8207,7 @@ var ColorByModifications$1 = {
8143
8207
  'default': ColorByModifications
8144
8208
  };
8145
8209
 
8146
- var useStyles$6 = /*#__PURE__*/core.makeStyles(function () {
8210
+ var useStyles$7 = /*#__PURE__*/core.makeStyles(function () {
8147
8211
  return {
8148
8212
  compact: {
8149
8213
  paddingRight: 0,
@@ -8155,7 +8219,7 @@ var useStyles$6 = /*#__PURE__*/core.makeStyles(function () {
8155
8219
  var omit = ['clipPos', 'flags']; // eslint-disable-next-line @typescript-eslint/no-explicit-any
8156
8220
 
8157
8221
  function AlignmentFlags(props) {
8158
- var classes = useStyles$6();
8222
+ var classes = useStyles$7();
8159
8223
  var feature = props.feature;
8160
8224
  var flags = feature.flags;
8161
8225
  var flagNames = ['read paired', 'read mapped in proper pair', 'read unmapped', 'mate unmapped', 'read reverse strand', 'mate reverse strand', 'first in pair', 'second in pair', 'not primary alignment', 'read fails platform/vendor quality checks', 'read is PCR or optical duplicate', 'supplementary alignment'];
@@ -8257,10 +8321,15 @@ function SupplementaryAlignments(props) {
8257
8321
  onClick: function onClick() {
8258
8322
  var view = model.view;
8259
8323
 
8260
- if (view) {
8261
- view.navToLocString(locString);
8262
- } else {
8263
- session.notify('No view associated with this feature detail panel anymore', 'warning');
8324
+ try {
8325
+ if (view) {
8326
+ view.navToLocString(locString);
8327
+ } else {
8328
+ throw new Error('No view associated with this view anymore');
8329
+ }
8330
+ } catch (e) {
8331
+ console.error(e);
8332
+ session.notify("".concat(e));
8264
8333
  }
8265
8334
  },
8266
8335
  href: "#"
@@ -8277,10 +8346,15 @@ function PairLink(_ref2) {
8277
8346
  onClick: function onClick() {
8278
8347
  var view = model.view;
8279
8348
 
8280
- if (view) {
8281
- view.navToLocString(locString);
8282
- } else {
8283
- session.notify('No view associated with this feature detail panel anymore', 'warning');
8349
+ try {
8350
+ if (view) {
8351
+ view.navToLocString(locString);
8352
+ } else {
8353
+ session.notify('No view associated with this feature detail panel anymore', 'warning');
8354
+ }
8355
+ } catch (e) {
8356
+ console.error(e);
8357
+ session.notify("".concat(e));
8284
8358
  }
8285
8359
  },
8286
8360
  href: "#"