react-msaview-cli 9.1.1 → 9.3.0

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 (2) hide show
  1. package/dist/index.js +510 -251
  2. package/package.json +3 -3
package/dist/index.js CHANGED
@@ -4694,7 +4694,7 @@ var init_identifier = __esm({
4694
4694
  }
4695
4695
  });
4696
4696
 
4697
- // ../../node_modules/.pnpm/@babel+runtime@7.29.7/node_modules/@babel/runtime/helpers/esm/extends.js
4697
+ // ../../node_modules/.pnpm/@babel+runtime@7.29.10/node_modules/@babel/runtime/helpers/esm/extends.js
4698
4698
  function _extends() {
4699
4699
  return _extends = Object.assign ? Object.assign.bind() : function(n2) {
4700
4700
  for (var e3 = 1; e3 < arguments.length; e3++) {
@@ -4705,7 +4705,7 @@ function _extends() {
4705
4705
  }, _extends.apply(null, arguments);
4706
4706
  }
4707
4707
  var init_extends = __esm({
4708
- "../../node_modules/.pnpm/@babel+runtime@7.29.7/node_modules/@babel/runtime/helpers/esm/extends.js"() {
4708
+ "../../node_modules/.pnpm/@babel+runtime@7.29.10/node_modules/@babel/runtime/helpers/esm/extends.js"() {
4709
4709
  }
4710
4710
  });
4711
4711
 
@@ -5641,6 +5641,12 @@ var init_emotion_cache_esm = __esm({
5641
5641
  }
5642
5642
  });
5643
5643
 
5644
+ // ../../node_modules/.pnpm/@babel+runtime@7.29.7/node_modules/@babel/runtime/helpers/esm/extends.js
5645
+ var init_extends2 = __esm({
5646
+ "../../node_modules/.pnpm/@babel+runtime@7.29.7/node_modules/@babel/runtime/helpers/esm/extends.js"() {
5647
+ }
5648
+ });
5649
+
5644
5650
  // ../../node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js
5645
5651
  var require_react_is_production_min = __commonJS({
5646
5652
  "../../node_modules/.pnpm/react-is@16.13.1/node_modules/react-is/cjs/react-is.production.min.js"(exports) {
@@ -6202,7 +6208,7 @@ var init_emotion_element_d59e098f_esm = __esm({
6202
6208
  React2 = __toESM(require_react());
6203
6209
  import_react = __toESM(require_react());
6204
6210
  init_emotion_cache_esm();
6205
- init_extends();
6211
+ init_extends2();
6206
6212
  init_emotion_weak_memoize_esm();
6207
6213
  init_emotion_utils_esm();
6208
6214
  init_emotion_serialize_esm();
@@ -6318,16 +6324,16 @@ var init_emotion_element_d59e098f_esm = __esm({
6318
6324
  // ../../node_modules/.pnpm/@babel+runtime@7.29.7/node_modules/@babel/runtime/helpers/extends.js
6319
6325
  var require_extends = __commonJS({
6320
6326
  "../../node_modules/.pnpm/@babel+runtime@7.29.7/node_modules/@babel/runtime/helpers/extends.js"(exports, module) {
6321
- function _extends2() {
6322
- return module.exports = _extends2 = Object.assign ? Object.assign.bind() : function(n2) {
6327
+ function _extends3() {
6328
+ return module.exports = _extends3 = Object.assign ? Object.assign.bind() : function(n2) {
6323
6329
  for (var e3 = 1; e3 < arguments.length; e3++) {
6324
6330
  var t3 = arguments[e3];
6325
6331
  for (var r4 in t3) ({}).hasOwnProperty.call(t3, r4) && (n2[r4] = t3[r4]);
6326
6332
  }
6327
6333
  return n2;
6328
- }, module.exports.__esModule = true, module.exports["default"] = module.exports, _extends2.apply(null, arguments);
6334
+ }, module.exports.__esModule = true, module.exports["default"] = module.exports, _extends3.apply(null, arguments);
6329
6335
  }
6330
- module.exports = _extends2, module.exports.__esModule = true, module.exports["default"] = module.exports;
6336
+ module.exports = _extends3, module.exports.__esModule = true, module.exports["default"] = module.exports;
6331
6337
  }
6332
6338
  });
6333
6339
 
@@ -6619,12 +6625,28 @@ var init_emotion_styled_base_esm = __esm({
6619
6625
  }
6620
6626
  });
6621
6627
 
6628
+ // ../../node_modules/.pnpm/@babel+runtime@7.29.10/node_modules/@babel/runtime/helpers/extends.js
6629
+ var require_extends2 = __commonJS({
6630
+ "../../node_modules/.pnpm/@babel+runtime@7.29.10/node_modules/@babel/runtime/helpers/extends.js"(exports, module) {
6631
+ function _extends3() {
6632
+ return module.exports = _extends3 = Object.assign ? Object.assign.bind() : function(n2) {
6633
+ for (var e3 = 1; e3 < arguments.length; e3++) {
6634
+ var t3 = arguments[e3];
6635
+ for (var r4 in t3) ({}).hasOwnProperty.call(t3, r4) && (n2[r4] = t3[r4]);
6636
+ }
6637
+ return n2;
6638
+ }, module.exports.__esModule = true, module.exports["default"] = module.exports, _extends3.apply(null, arguments);
6639
+ }
6640
+ module.exports = _extends3, module.exports.__esModule = true, module.exports["default"] = module.exports;
6641
+ }
6642
+ });
6643
+
6622
6644
  // ../../node_modules/.pnpm/@emotion+styled@11.14.1_@emotion+react@11.14.0_@types+react@19.3.0_react@19.3.1_support_96e6059dc34d61fb5723d6878bab7582/node_modules/@emotion/styled/dist/emotion-styled.esm.js
6623
6645
  var import_extends4, import_react3, tags, styled;
6624
6646
  var init_emotion_styled_esm = __esm({
6625
6647
  "../../node_modules/.pnpm/@emotion+styled@11.14.1_@emotion+react@11.14.0_@types+react@19.3.0_react@19.3.1_support_96e6059dc34d61fb5723d6878bab7582/node_modules/@emotion/styled/dist/emotion-styled.esm.js"() {
6626
6648
  init_emotion_styled_base_esm();
6627
- import_extends4 = __toESM(require_extends());
6649
+ import_extends4 = __toESM(require_extends2());
6628
6650
  init_emotion_serialize_esm();
6629
6651
  init_emotion_use_insertion_effect_with_fallbacks_esm();
6630
6652
  init_emotion_utils_esm();
@@ -44846,7 +44868,6 @@ var init_material = __esm({
44846
44868
  init_Alert2();
44847
44869
  init_AlertTitle();
44848
44870
  init_AppBar2();
44849
- init_AppBar2();
44850
44871
  init_Autocomplete2();
44851
44872
  init_Autocomplete2();
44852
44873
  init_Avatar();
@@ -44861,7 +44882,6 @@ var init_material = __esm({
44861
44882
  init_Button2();
44862
44883
  init_Button2();
44863
44884
  init_ButtonBase2();
44864
- init_ButtonBase2();
44865
44885
  init_ButtonGroup();
44866
44886
  init_Card();
44867
44887
  init_CardActionArea();
@@ -45038,11 +45058,13 @@ function useDragScroll(axis, onScroll) {
45038
45058
  };
45039
45059
  var onMove = onMove2, onUp = onUp2;
45040
45060
  const { client: startClient, startScroll } = mouseDown;
45041
- document.addEventListener("mousemove", onMove2);
45042
- document.addEventListener("mouseup", onUp2);
45061
+ document.addEventListener("pointermove", onMove2);
45062
+ document.addEventListener("pointerup", onUp2);
45063
+ document.addEventListener("pointercancel", onUp2);
45043
45064
  return () => {
45044
- document.removeEventListener("mousemove", onMove2);
45045
- document.removeEventListener("mouseup", onUp2);
45065
+ document.removeEventListener("pointermove", onMove2);
45066
+ document.removeEventListener("pointerup", onUp2);
45067
+ document.removeEventListener("pointercancel", onUp2);
45046
45068
  };
45047
45069
  }
45048
45070
  }, [axis, onScroll, mouseDown]);
@@ -45077,10 +45099,11 @@ function DragHandle({ axis, variant, getStart, onDrag, style: style3 }) {
45077
45099
  setHovered(true);
45078
45100
  }, onMouseLeave: () => {
45079
45101
  setHovered(false);
45080
- }, onMouseDown: (event) => {
45102
+ }, onPointerDown: (event) => {
45081
45103
  startDrag(event, getStart());
45082
45104
  }, style: {
45083
45105
  position: position3,
45106
+ touchAction: "none",
45084
45107
  zIndex: zIndex3,
45085
45108
  cursor: cursor2(axis),
45086
45109
  background: hovered ? fillHovered(theme) : fill(theme),
@@ -45763,13 +45786,14 @@ var init_renderHighlights = __esm({
45763
45786
  function fontSizeFor(rowHeight) {
45764
45787
  return Math.min(Math.max(6, rowHeight - 3), 18);
45765
45788
  }
45766
- var defaultRowHeight, defaultColWidth, defaultHeight, defaultScrollX, defaultScrollY, defaultCurrentAlignment, defaultShowDomains, defaultShowDomainLegend, defaultHideGaps, defaultAllowedGappyness, defaultSubFeatureRows, subFeatureRowHeight, domainUnderlineHeight, segmentFeatureTypes, segmentShades, defaultDrawMsaLetters, defaultScrollZoom, scrollZoomAxes, defaultScrollZoomAxis, minLetterRowHeight, minLetterColWidth, zoomFrameMaxLetters, minFeatureLabelHeight, labelFitFontSize, minColWidth, minRowHeight, maxCellSize, settingsPanelWidth, defaultBgColor, defaultColorSchemeName, defaultShowColumnStats, defaultDrawLabels, defaultLabelsAlignRight, minTreeWidth, maxFitTreeWidth, pxPerTreeDepth, maxTreeAreaShare, defaultShowBranchLen, treeOrders, defaultTreeOrder, defaultDrawTree, defaultDrawNodeBubbles, defaultDrawNodeLabels, defaultShowTreeOverview, defaultShowTreeScaleBar, defaultOverviewHeight, maxNeighborJoiningRows, rowTintAlpha, cladeHighlightColor, cladeHighlightAlpha, maxInlineSnapshotBytes, rowPanelHeaderHeight, treeScaleBarHeight, defaultFeaturePanelWidth, msaOverlayZIndex, legendZIndex;
45789
+ var defaultRowHeight, defaultColWidth, defaultHeight, resizeHandleWidth, defaultScrollX, defaultScrollY, defaultCurrentAlignment, defaultShowDomains, defaultShowDomainLegend, defaultHideGaps, defaultAllowedGappyness, defaultSubFeatureRows, subFeatureRowHeight, domainUnderlineHeight, segmentFeatureTypes, segmentShades, defaultDrawMsaLetters, defaultScrollZoom, scrollZoomAxes, defaultScrollZoomAxis, minLetterRowHeight, minLetterColWidth, zoomFrameMaxLetters, minFeatureLabelHeight, labelFitFontSize, minColWidth, minRowHeight, maxCellSize, settingsPanelWidth, defaultBgColor, defaultColorSchemeName, defaultShowColumnStats, defaultDrawLabels, defaultLabelsAlignRight, minTreeWidth, maxFitTreeWidth, pxPerTreeDepth, maxTreeAreaShare, defaultShowBranchLen, treeOrders, defaultTreeOrder, defaultDrawTree, defaultDrawNodeBubbles, defaultDrawNodeLabels, defaultShowTreeOverview, defaultShowTreeScaleBar, defaultOverviewHeight, maxNeighborJoiningRows, rowTintAlpha, cladeHighlightColor, cladeHighlightAlpha, maxInlineSnapshotBytes, rowPanelHeaderHeight, treeScaleBarHeight, defaultFeaturePanelWidth, msaOverlayZIndex, legendZIndex;
45767
45790
  var init_constants = __esm({
45768
45791
  "../lib/dist/constants.js"() {
45769
45792
  "use strict";
45770
45793
  defaultRowHeight = 16;
45771
45794
  defaultColWidth = 12;
45772
45795
  defaultHeight = 550;
45796
+ resizeHandleWidth = 5;
45773
45797
  defaultScrollX = 0;
45774
45798
  defaultScrollY = 0;
45775
45799
  defaultCurrentAlignment = 0;
@@ -46935,7 +46959,7 @@ function drawArcs({ ctx, arcs, color: color2, colWidth, trackHeight, offsetX, bl
46935
46959
  ctx.stroke();
46936
46960
  }
46937
46961
  }
46938
- function drawTextTrackContent({ ctx, data, colorScheme, contrastText, bgColor, drawLetters, colWidth, rowHeight, offsetX, blockSize }) {
46962
+ function drawTextTrackContent({ ctx, data, colorAt, contrastText, bgColor, drawLetters, colWidth, rowHeight, offsetX, blockSize }) {
46939
46963
  const { xStart, xEnd } = visibleColRange({
46940
46964
  offsetX,
46941
46965
  blockWidth: blockSize,
@@ -46944,9 +46968,9 @@ function drawTextTrackContent({ ctx, data, colorScheme, contrastText, bgColor, d
46944
46968
  const str = data?.slice(xStart, xEnd);
46945
46969
  for (let i2 = 0; str && i2 < str.length; i2++) {
46946
46970
  const letter = str[i2];
46947
- const upper = letter.toUpperCase();
46948
- const fill = bgColor ? colorScheme[upper] : void 0;
46949
- const x2 = (xStart + i2) * colWidth;
46971
+ const col = xStart + i2;
46972
+ const fill = bgColor ? colorAt(col, letter) : void 0;
46973
+ const x2 = col * colWidth;
46950
46974
  if (fill) {
46951
46975
  ctx.fillStyle = fill;
46952
46976
  ctx.fillRect(x2, 0, colWidth, rowHeight);
@@ -47106,15 +47130,19 @@ function drawTrackBlock({ model: model2, ctx, track, offsetX, offsetY = 0, theme
47106
47130
  });
47107
47131
  break;
47108
47132
  }
47109
- case "text": {
47133
+ case "text":
47134
+ case "reference": {
47110
47135
  const { bgColor, fontSize: fontSize2, rowHeight, showMsaLetters } = model2;
47136
+ const scheme = customColorScheme ?? model2.colorScheme;
47111
47137
  ctx.textAlign = "center";
47112
47138
  ctx.textBaseline = "middle";
47113
47139
  setFontSize(ctx, fontSize2);
47114
47140
  drawTextTrackContent({
47115
47141
  ctx,
47116
47142
  data,
47117
- colorScheme: customColorScheme ?? model2.colorScheme,
47143
+ // the reference row takes its colors from the alignment's own
47144
+ // scheme, per column under a dynamic one
47145
+ colorAt: kind === "reference" ? tileColorFn(model2) : (_col, letter) => scheme[letter.toUpperCase()],
47118
47146
  contrastText: contrastTextFn(theme),
47119
47147
  bgColor,
47120
47148
  drawLetters: showMsaLetters,
@@ -47151,6 +47179,7 @@ var init_drawTracks = __esm({
47151
47179
  init_sequenceLogo();
47152
47180
  init_setFontSize();
47153
47181
  init_util3();
47182
+ init_tileColor();
47154
47183
  init_visibleColRange();
47155
47184
  RULER_FONT_SIZE = 10;
47156
47185
  TICK_HEIGHT = 4;
@@ -49529,7 +49558,7 @@ var require_react_dom_client_production = __commonJS({
49529
49558
  return true;
49530
49559
  }
49531
49560
  }
49532
- var aliases2 = /* @__PURE__ */ new Map([
49561
+ var aliases3 = /* @__PURE__ */ new Map([
49533
49562
  ["acceptCharset", "accept-charset"],
49534
49563
  ["htmlFor", "for"],
49535
49564
  ["httpEquiv", "http-equiv"],
@@ -59114,7 +59143,7 @@ var require_react_dom_client_production = __commonJS({
59114
59143
  return;
59115
59144
  default:
59116
59145
  if (!(2 < key.length) || "o" !== key[0] && "O" !== key[0] || "n" !== key[1] && "N" !== key[1])
59117
- key = aliases2.get(key) || key, setValueForAttribute(domElement, key, value);
59146
+ key = aliases3.get(key) || key, setValueForAttribute(domElement, key, value);
59118
59147
  else return;
59119
59148
  }
59120
59149
  viewTransitionMutationContext = true;
@@ -84839,19 +84868,35 @@ var init_wheelZoom = __esm({
84839
84868
  });
84840
84869
 
84841
84870
  // ../lib/dist/useWheelScroll.js
84842
- function useWheelScroll({ ref, onScrollX, onScrollY, onZoom, onZoomSettle, onWheelScroll, scrollZoom }) {
84871
+ function canScrollY(model2, delta) {
84872
+ const { scrollY, maxScrollY } = model2;
84873
+ return delta > 0 ? scrollY > maxScrollY : delta < 0 && scrollY < 0;
84874
+ }
84875
+ function withPinch(pan) {
84876
+ return pinchZoom ? `${pan} ${pinchZoom}` : pan;
84877
+ }
84878
+ function panTouchAction(model2, axes) {
84879
+ const x2 = axes.includes("x") && model2.maxScrollX < 0;
84880
+ const y2 = axes.includes("y") && model2.maxScrollY < 0;
84881
+ return x2 && y2 ? pinchZoom ?? "none" : x2 ? withPinch("pan-y") : y2 ? withPinch("pan-x") : "auto";
84882
+ }
84883
+ function useWheelScroll({ ref, model: model2, axes, zoom, onWheelScroll }) {
84843
84884
  const scheduled = (0, import_react39.useRef)(false);
84844
84885
  const zoomFrame = (0, import_react39.useRef)(void 0);
84845
84886
  const zoomSettle = (0, import_react39.useRef)(void 0);
84846
84887
  const deltaX = (0, import_react39.useRef)(0);
84847
84888
  const deltaY = (0, import_react39.useRef)(0);
84889
+ const lastTaken = (0, import_react39.useRef)(Number.NEGATIVE_INFINITY);
84848
84890
  const zoomSmoother = (0, import_react39.useRef)(new WheelZoomSmoother());
84849
84891
  const zoomX = (0, import_react39.useRef)(0);
84850
84892
  const zoomY = (0, import_react39.useRef)(0);
84851
84893
  const lastZoomTime = (0, import_react39.useRef)(null);
84852
- const prevX = (0, import_react39.useRef)(0);
84853
- const prevY = (0, import_react39.useRef)(0);
84854
- const [mouseDragging, setMouseDragging] = (0, import_react39.useState)(false);
84894
+ const prev2 = (0, import_react39.useRef)({ x: 0, y: 0 });
84895
+ const latest = (0, import_react39.useRef)({ x: 0, y: 0 });
84896
+ const panFrame = (0, import_react39.useRef)(false);
84897
+ const [panPointer, setPanPointer] = (0, import_react39.useState)();
84898
+ const x2 = axes.includes("x");
84899
+ const y2 = axes.includes("y");
84855
84900
  (0, import_react39.useEffect)(() => {
84856
84901
  const curr = ref.current;
84857
84902
  if (!curr) {
@@ -84859,9 +84904,8 @@ function useWheelScroll({ ref, onScrollX, onScrollY, onZoom, onZoomSettle, onWhe
84859
84904
  }
84860
84905
  function onWheel(event) {
84861
84906
  const isCtrlZoom = event.ctrlKey || event.metaKey;
84862
- const isScrollZoom = scrollZoom && !event.shiftKey && Math.abs(event.deltaY) >= Math.abs(event.deltaX);
84863
- if (onZoom && (isCtrlZoom || isScrollZoom)) {
84864
- const zoom = onZoom;
84907
+ const isScrollZoom = model2.scrollZoom && !event.shiftKey && Math.abs(event.deltaY) >= Math.abs(event.deltaX);
84908
+ if (zoom && (isCtrlZoom || isScrollZoom)) {
84865
84909
  const rect = curr.getBoundingClientRect();
84866
84910
  zoomSmoother.current.add(event.deltaY, event.deltaMode, isCtrlZoom);
84867
84911
  zoomX.current = event.clientX - rect.left;
@@ -84871,10 +84915,10 @@ function useWheelScroll({ ref, onScrollX, onScrollY, onZoom, onZoomSettle, onWhe
84871
84915
  const frame = (now) => {
84872
84916
  const elapsed = lastZoomTime.current === null ? 16.67 : now - lastZoomTime.current;
84873
84917
  lastZoomTime.current = now;
84874
- zoom(zoomSmoother.current.step(Math.min(100, elapsed)), zoomX.current, zoomY.current);
84918
+ model2.wheelZoomToPos(zoomSmoother.current.step(Math.min(100, elapsed)), zoomX.current, zoomY.current);
84875
84919
  clearTimeout(zoomSettle.current);
84876
84920
  zoomSettle.current = setTimeout(() => {
84877
- onZoomSettle?.();
84921
+ model2.endWheelZoom();
84878
84922
  }, zoomSettleMs);
84879
84923
  zoomFrame.current = zoomSmoother.current.idle ? void 0 : requestAnimationFrame(frame);
84880
84924
  };
@@ -84884,27 +84928,25 @@ function useWheelScroll({ ref, onScrollX, onScrollY, onZoom, onZoomSettle, onWhe
84884
84928
  event.stopPropagation();
84885
84929
  return;
84886
84930
  }
84887
- const consumeX = !!onScrollX && event.deltaX !== 0;
84888
- const consumeY = !!onScrollY && event.deltaY !== 0;
84889
- if (consumeX || consumeY) {
84890
- onWheelScroll?.(event);
84891
- if (onScrollX) {
84892
- deltaX.current += event.deltaX;
84893
- }
84894
- if (onScrollY) {
84895
- deltaY.current += event.deltaY;
84931
+ const { deltaX: dx, deltaY: dy } = event;
84932
+ const vertical = Math.abs(dy) >= Math.abs(dx);
84933
+ const latched = event.timeStamp - lastTaken.current < wheelLatchMs;
84934
+ const takeY = y2 && dy !== 0 && (latched || canScrollY(model2, dy) || !vertical);
84935
+ const takeX = x2 && dx !== 0 && (!vertical || takeY);
84936
+ if (takeX || takeY) {
84937
+ if (takeY && vertical) {
84938
+ lastTaken.current = event.timeStamp;
84896
84939
  }
84940
+ onWheelScroll?.(event);
84941
+ deltaX.current += takeX ? event.deltaX : 0;
84942
+ deltaY.current += takeY ? event.deltaY : 0;
84897
84943
  if (!scheduled.current) {
84898
84944
  scheduled.current = true;
84899
84945
  requestAnimationFrame(() => {
84900
- if (onScrollX) {
84901
- onScrollX(-deltaX.current);
84902
- deltaX.current = 0;
84903
- }
84904
- if (onScrollY) {
84905
- onScrollY(-deltaY.current);
84906
- deltaY.current = 0;
84907
- }
84946
+ model2.doScrollX(-deltaX.current);
84947
+ model2.doScrollY(-deltaY.current);
84948
+ deltaX.current = 0;
84949
+ deltaY.current = 0;
84908
84950
  scheduled.current = false;
84909
84951
  });
84910
84952
  }
@@ -84921,68 +84963,60 @@ function useWheelScroll({ ref, onScrollX, onScrollY, onZoom, onZoomSettle, onWhe
84921
84963
  }
84922
84964
  clearTimeout(zoomSettle.current);
84923
84965
  };
84924
- }, [
84925
- ref,
84926
- onScrollX,
84927
- onScrollY,
84928
- onZoom,
84929
- onZoomSettle,
84930
- onWheelScroll,
84931
- scrollZoom
84932
- ]);
84966
+ }, [ref, model2, x2, y2, zoom, onWheelScroll]);
84933
84967
  (0, import_react39.useEffect)(() => {
84934
- if (!mouseDragging) {
84968
+ if (panPointer === void 0) {
84935
84969
  return;
84936
84970
  }
84937
- function globalMouseMove(event) {
84971
+ function onMove(event) {
84972
+ if (event.pointerId !== panPointer) {
84973
+ return;
84974
+ }
84938
84975
  event.preventDefault();
84939
- const distanceX = event.clientX - prevX.current;
84940
- const distanceY = event.clientY - prevY.current;
84941
- if (distanceX && onScrollX || distanceY && onScrollY) {
84942
- if (!scheduled.current) {
84943
- scheduled.current = true;
84944
- requestAnimationFrame(() => {
84945
- onScrollX?.(distanceX);
84946
- onScrollY?.(distanceY);
84947
- scheduled.current = false;
84948
- prevX.current = event.clientX;
84949
- prevY.current = event.clientY;
84950
- });
84951
- }
84976
+ latest.current = { x: event.clientX, y: event.clientY };
84977
+ if (!panFrame.current) {
84978
+ panFrame.current = true;
84979
+ requestAnimationFrame(() => {
84980
+ const to = latest.current;
84981
+ model2.doScrollX(x2 ? to.x - prev2.current.x : 0);
84982
+ model2.doScrollY(y2 ? to.y - prev2.current.y : 0);
84983
+ prev2.current = to;
84984
+ panFrame.current = false;
84985
+ });
84952
84986
  }
84953
84987
  }
84954
- function globalMouseUp() {
84955
- prevX.current = 0;
84956
- prevY.current = 0;
84957
- setMouseDragging(false);
84988
+ function onUp(event) {
84989
+ if (event.pointerId === panPointer) {
84990
+ setPanPointer(void 0);
84991
+ }
84958
84992
  }
84959
- window.addEventListener("mousemove", globalMouseMove, true);
84960
- window.addEventListener("mouseup", globalMouseUp, true);
84993
+ window.addEventListener("pointermove", onMove, true);
84994
+ window.addEventListener("pointerup", onUp, true);
84995
+ window.addEventListener("pointercancel", onUp, true);
84961
84996
  return () => {
84962
- window.removeEventListener("mousemove", globalMouseMove, true);
84963
- window.removeEventListener("mouseup", globalMouseUp, true);
84997
+ window.removeEventListener("pointermove", onMove, true);
84998
+ window.removeEventListener("pointerup", onUp, true);
84999
+ window.removeEventListener("pointercancel", onUp, true);
84964
85000
  };
84965
- }, [mouseDragging, onScrollX, onScrollY]);
84966
- function onMouseDown(event) {
84967
- if (event.button === 0) {
84968
- prevX.current = event.clientX;
84969
- prevY.current = event.clientY;
84970
- setMouseDragging(true);
85001
+ }, [panPointer, model2, x2, y2]);
85002
+ function onPointerDown(event) {
85003
+ if (event.button === 0 && event.isPrimary && panPointer === void 0) {
85004
+ prev2.current = { x: event.clientX, y: event.clientY };
85005
+ latest.current = prev2.current;
85006
+ setPanPointer(event.pointerId);
84971
85007
  }
84972
85008
  }
84973
- function onMouseUp(event) {
84974
- event.preventDefault();
84975
- setMouseDragging(false);
84976
- }
84977
- return { onMouseDown, onMouseUp };
85009
+ return { onPointerDown, touchAction: panTouchAction(model2, axes) };
84978
85010
  }
84979
- var import_react39, zoomSettleMs;
85011
+ var import_react39, zoomSettleMs, wheelLatchMs, pinchZoom;
84980
85012
  var init_useWheelScroll = __esm({
84981
85013
  "../lib/dist/useWheelScroll.js"() {
84982
85014
  "use strict";
84983
85015
  import_react39 = __toESM(require_react(), 1);
84984
85016
  init_wheelZoom();
84985
85017
  zoomSettleMs = 150;
85018
+ wheelLatchMs = 150;
85019
+ pinchZoom = typeof CSS !== "undefined" && CSS.supports("touch-action", "pinch-zoom") ? "pinch-zoom" : void 0;
84986
85020
  }
84987
85021
  });
84988
85022
 
@@ -85264,7 +85298,8 @@ var init_TrackTooltipContent = __esm({
85264
85298
  case "logo": {
85265
85299
  return import_react43.default.createElement(LogoTooltip, { model: model2, col });
85266
85300
  }
85267
- case "text": {
85301
+ case "text":
85302
+ case "reference": {
85268
85303
  return import_react43.default.createElement(TextTooltip, { model: model2, track, col });
85269
85304
  }
85270
85305
  case "arc": {
@@ -85567,13 +85602,10 @@ var init_Track = __esm({
85567
85602
  );
85568
85603
  });
85569
85604
  Track = (0, import_mobx_react35.observer)(function({ model: model2, track }) {
85570
- const { resizeHandleWidth, rowPanelsWidth, showColumnStats } = model2;
85605
+ const { resizeHandleWidth: resizeHandleWidth2, rowPanelsWidth, showColumnStats } = model2;
85571
85606
  const { model: { height: height2 } } = track;
85572
85607
  const ref = (0, import_react47.useRef)(null);
85573
- const onScrollX = (0, import_react47.useCallback)((d3) => {
85574
- model2.doScrollX(d3);
85575
- }, [model2]);
85576
- useWheelScroll({ ref, onScrollX });
85608
+ useWheelScroll({ ref, model: model2, axes: "x" });
85577
85609
  const { classes } = useStyles10();
85578
85610
  const { anchor, onMouseMove, onMouseDown, onMouseLeave } = useTrackHover({
85579
85611
  model: model2,
@@ -85583,7 +85615,7 @@ var init_Track = __esm({
85583
85615
  "div",
85584
85616
  { className: classes.row, style: { height: height2 } },
85585
85617
  import_react47.default.createElement(TrackLabel, { model: model2, track }),
85586
- import_react47.default.createElement("div", { style: { width: rowPanelsWidth + resizeHandleWidth, flexShrink: 0 } }),
85618
+ import_react47.default.createElement("div", { style: { width: rowPanelsWidth + resizeHandleWidth2, flexShrink: 0 } }),
85587
85619
  import_react47.default.createElement(
85588
85620
  "div",
85589
85621
  { ref, "data-testid": `track_${track.model.id}`, tabIndex: -1, style: { outline: "none" }, onKeyDown: (event) => {
@@ -85633,7 +85665,7 @@ var init_VerticalScrollbar = __esm({
85633
85665
  }, [model2, unit]);
85634
85666
  return import_react48.default.createElement(
85635
85667
  "div",
85636
- { onMouseDown: (event) => {
85668
+ { onPointerDown: (event) => {
85637
85669
  if (event.button === 0 && event.target === event.currentTarget) {
85638
85670
  const y2 = event.clientY - event.currentTarget.getBoundingClientRect().top;
85639
85671
  model2.setScrollY(-y2 / unit + msaAreaHeight / 2);
@@ -86496,7 +86528,7 @@ var version2;
86496
86528
  var init_version3 = __esm({
86497
86529
  "../lib/dist/version.js"() {
86498
86530
  "use strict";
86499
- version2 = "9.1.1";
86531
+ version2 = "9.3.0";
86500
86532
  }
86501
86533
  });
86502
86534
 
@@ -87815,6 +87847,7 @@ var init_Header = __esm({
87815
87847
  init_useMeasure();
87816
87848
  init_Tune();
87817
87849
  init_material();
87850
+ init_AppBar2();
87818
87851
  import_mobx_react54 = __toESM(require_dist3(), 1);
87819
87852
  init_StatusMessage();
87820
87853
  init_HeaderInfoArea();
@@ -87931,7 +87964,7 @@ var init_Minimap = __esm({
87931
87964
  width: msaCanvasWidth,
87932
87965
  flexShrink: 0
87933
87966
  } },
87934
- import_react76.default.createElement("canvas", { ref, width: barWidth, height: barHeight, onMouseDown: (event) => {
87967
+ import_react76.default.createElement("canvas", { ref, width: barWidth, height: barHeight, onPointerDown: (event) => {
87935
87968
  if (event.button === 0 && unit > 0) {
87936
87969
  const x2 = event.clientX - event.currentTarget.getBoundingClientRect().left;
87937
87970
  model2.setScrollX(-x2 / unit + msaCanvasWidth / 2);
@@ -88362,51 +88395,52 @@ var init_MSACanvas = __esm({
88362
88395
  init_WheelZoomHint();
88363
88396
  init_msaKeys();
88364
88397
  MSACanvas = (0, import_mobx_react58.observer)(function({ model: model2 }) {
88365
- const { MSA, msaFilehandle, height: height2, msaCanvasWidth, blocks2d, scrollZoom, scrollX, scrollY, zoomSnapshot } = model2;
88398
+ const { MSA, msaFilehandle, height: height2, msaCanvasWidth, blocks2d, scrollX, scrollY, zoomSnapshot } = model2;
88366
88399
  const blocks = zoomSnapshot ? zoomSnapshot.blocksY.flatMap((by) => zoomSnapshot.blocksX.map((bx) => [bx, by])) : blocks2d;
88367
88400
  const scale = zoomSnapshot ? zoomSnapshotScale(model2, zoomSnapshot) : void 0;
88368
88401
  const ref = (0, import_react82.useRef)(null);
88369
- const onScrollX = (0, import_react82.useCallback)((d3) => {
88370
- model2.doScrollX(d3);
88371
- }, [model2]);
88372
- const onScrollY = (0, import_react82.useCallback)((d3) => {
88373
- model2.doScrollY(d3);
88374
- }, [model2]);
88375
- const onZoom = (0, import_react82.useCallback)((scaleFactor, offsetX, offsetY) => {
88376
- model2.wheelZoomToPos(scaleFactor, offsetX, offsetY);
88377
- }, [model2]);
88378
- const onZoomSettle = (0, import_react82.useCallback)(() => {
88379
- model2.endWheelZoom();
88380
- }, [model2]);
88381
88402
  const hint = useWheelZoomHint(model2);
88382
- const { onMouseDown, onMouseUp } = useWheelScroll({
88403
+ const { onPointerDown, touchAction } = useWheelScroll({
88383
88404
  ref,
88384
- onScrollX,
88385
- onScrollY,
88386
- onZoom,
88387
- onZoomSettle,
88388
- onWheelScroll: hint.onWheelScroll,
88389
- scrollZoom
88405
+ model: model2,
88406
+ axes: "xy",
88407
+ zoom: true,
88408
+ onWheelScroll: hint.onWheelScroll
88390
88409
  });
88391
88410
  return import_react82.default.createElement(
88392
88411
  "div",
88393
- { ref, "data-testid": "msa_canvas", tabIndex: 0, "aria-label": alignmentAriaLabel, onKeyDown: (event) => {
88394
- if (onMsaKey(model2, event)) {
88395
- event.preventDefault();
88396
- }
88397
- }, onMouseDown: (event) => {
88398
- if (event.shiftKey) {
88399
- event.preventDefault();
88400
- ref.current?.focus({ preventScroll: true });
88401
- } else {
88402
- onMouseDown(event);
88412
+ {
88413
+ ref,
88414
+ "data-testid": "msa_canvas",
88415
+ tabIndex: 0,
88416
+ "aria-label": alignmentAriaLabel,
88417
+ onKeyDown: (event) => {
88418
+ if (onMsaKey(model2, event)) {
88419
+ event.preventDefault();
88420
+ }
88421
+ },
88422
+ // a shifted press selects cells (useMsaBlockMouse), so it takes the
88423
+ // focus Escape clears from, and leaves out the pan and the page's own
88424
+ // text selection
88425
+ onMouseDown: (event) => {
88426
+ if (event.shiftKey) {
88427
+ event.preventDefault();
88428
+ ref.current?.focus({ preventScroll: true });
88429
+ }
88430
+ },
88431
+ onPointerDown: (event) => {
88432
+ if (!event.shiftKey) {
88433
+ onPointerDown(event);
88434
+ }
88435
+ },
88436
+ style: {
88437
+ position: "relative",
88438
+ touchAction,
88439
+ height: height2,
88440
+ width: msaCanvasWidth,
88441
+ overflow: "hidden"
88403
88442
  }
88404
- }, onMouseUp, style: {
88405
- position: "relative",
88406
- height: height2,
88407
- width: msaCanvasWidth,
88408
- overflow: "hidden"
88409
- } },
88443
+ },
88410
88444
  !MSA && !msaFilehandle ? null : MSA ? import_react82.default.createElement("div", { style: {
88411
88445
  position: "absolute",
88412
88446
  top: 0,
@@ -88680,13 +88714,15 @@ var init_RowPanels = __esm({
88680
88714
  RowPanel = (0, import_mobx_react63.observer)(function({ model: model2, panel }) {
88681
88715
  const ref = (0, import_react87.useRef)(null);
88682
88716
  const { height: height2, blocksY, scrollY } = model2;
88683
- const onScrollY = (0, import_react87.useCallback)((d3) => {
88684
- model2.doScrollY(d3);
88685
- }, [model2]);
88686
- const { onMouseDown, onMouseUp } = useWheelScroll({ ref, onScrollY });
88717
+ const { onPointerDown, touchAction } = useWheelScroll({
88718
+ ref,
88719
+ model: model2,
88720
+ axes: "y"
88721
+ });
88687
88722
  return import_react87.default.createElement(
88688
88723
  "div",
88689
- { ref, "data-testid": `rowpanel_${panel.id}`, onMouseDown, onMouseUp, style: {
88724
+ { ref, "data-testid": `rowpanel_${panel.id}`, onPointerDown, style: {
88725
+ touchAction,
88690
88726
  height: height2,
88691
88727
  width: panel.width,
88692
88728
  flexShrink: 0,
@@ -88825,16 +88861,15 @@ function trackGroups(model2) {
88825
88861
  const computed3 = new Set(model2.computedTrackModels.map((t3) => t3.model.id));
88826
88862
  const computedEntries = [];
88827
88863
  const alignmentEntries = [];
88864
+ const referenceEntries = [];
88828
88865
  for (const { model: t3 } of model2.tracks) {
88829
- ;
88830
- (computed3.has(t3.id) ? computedEntries : alignmentEntries).push({
88831
- id: t3.id,
88832
- label: t3.name
88833
- });
88866
+ const entries3 = t3.kind === "reference" ? referenceEntries : computed3.has(t3.id) ? computedEntries : alignmentEntries;
88867
+ entries3.push({ id: t3.id, label: t3.name });
88834
88868
  }
88835
88869
  return [
88836
88870
  { title: "Computed from the alignment", entries: computedEntries },
88837
- { title: "Alignment annotations", entries: alignmentEntries }
88871
+ { title: "Alignment annotations", entries: alignmentEntries },
88872
+ { title: "Reference row", entries: referenceEntries }
88838
88873
  ].filter((g2) => g2.entries.length > 0);
88839
88874
  }
88840
88875
  var import_react89, import_mobx_react64, filterFrom, TrackList, TrackList_default;
@@ -88929,6 +88964,7 @@ var init_SettingsPanel = __esm({
88929
88964
  init_ArrowRight();
88930
88965
  init_Close2();
88931
88966
  init_material();
88967
+ init_ButtonBase2();
88932
88968
  import_mobx_react65 = __toESM(require_dist3(), 1);
88933
88969
  init_constants();
88934
88970
  init_getAnnotationsMenu();
@@ -89948,10 +89984,11 @@ var init_TreeCanvas = __esm({
89948
89984
  TreeCanvas = (0, import_mobx_react71.observer)(function({ model: model2 }) {
89949
89985
  const ref = (0, import_react97.useRef)(null);
89950
89986
  const { height: height2, blocksY, effectiveTreeAreaWidth, scrollY, highResScaleFactor } = model2;
89951
- const onScrollY = (0, import_react97.useCallback)((d3) => {
89952
- model2.doScrollY(d3);
89953
- }, [model2]);
89954
- const { onMouseDown, onMouseUp } = useWheelScroll({ ref, onScrollY });
89987
+ const { onPointerDown, touchAction } = useWheelScroll({
89988
+ ref,
89989
+ model: model2,
89990
+ axes: "y"
89991
+ });
89955
89992
  const canvasWidth = effectiveTreeAreaWidth * highResScaleFactor;
89956
89993
  const canvasHeight = height2 * highResScaleFactor;
89957
89994
  const mouseoverRef = useCanvasAutorun({
@@ -89966,7 +90003,8 @@ var init_TreeCanvas = __esm({
89966
90003
  });
89967
90004
  return import_react97.default.createElement(
89968
90005
  "div",
89969
- { ref, onMouseDown, onMouseUp, style: {
90006
+ { ref, onPointerDown, style: {
90007
+ touchAction,
89970
90008
  height: height2,
89971
90009
  position: "relative",
89972
90010
  width: effectiveTreeAreaWidth
@@ -90066,7 +90104,7 @@ var init_MSAView = __esm({
90066
90104
  init_TreePanel();
90067
90105
  init_TreeRuler();
90068
90106
  TopArea = (0, import_mobx_react74.observer)(function({ model: model2 }) {
90069
- const { showHorizontalScrollbar, showTreeOverview, resizeHandleWidth } = model2;
90107
+ const { showHorizontalScrollbar, showTreeOverview, resizeHandleWidth: resizeHandleWidth2 } = model2;
90070
90108
  return import_react100.default.createElement(
90071
90109
  "div",
90072
90110
  { style: { display: "flex" } },
@@ -90077,12 +90115,12 @@ var init_MSAView = __esm({
90077
90115
  import_react100.default.createElement(TreeRuler_default, { model: model2 })
90078
90116
  ),
90079
90117
  import_react100.default.createElement(RowPanelHeaders_default, { model: model2 }),
90080
- import_react100.default.createElement("div", { style: { width: resizeHandleWidth, flexShrink: 0 } }),
90118
+ import_react100.default.createElement("div", { style: { width: resizeHandleWidth2, flexShrink: 0 } }),
90081
90119
  showHorizontalScrollbar ? import_react100.default.createElement(Minimap_default, { model: model2 }) : null
90082
90120
  );
90083
90121
  });
90084
90122
  TrackColumnIndicator = (0, import_mobx_react74.observer)(function({ model: model2 }) {
90085
- const { mouseCol, mouseClickCol, colWidth, scrollX, effectiveTreeAreaWidth, rowPanelsWidth, resizeHandleWidth, totalTrackAreaHeight, msaCanvasWidth, resolvedSelection } = model2;
90123
+ const { mouseCol, mouseClickCol, colWidth, scrollX, effectiveTreeAreaWidth, rowPanelsWidth, resizeHandleWidth: resizeHandleWidth2, totalTrackAreaHeight, msaCanvasWidth, resolvedSelection } = model2;
90086
90124
  const bands = [
90087
90125
  {
90088
90126
  start: resolvedSelection?.startCol,
@@ -90094,7 +90132,7 @@ var init_MSAView = __esm({
90094
90132
  ];
90095
90133
  return import_react100.default.createElement("div", { style: {
90096
90134
  position: "absolute",
90097
- left: effectiveTreeAreaWidth + rowPanelsWidth + resizeHandleWidth,
90135
+ left: effectiveTreeAreaWidth + rowPanelsWidth + resizeHandleWidth2,
90098
90136
  top: 0,
90099
90137
  width: msaCanvasWidth,
90100
90138
  height: totalTrackAreaHeight,
@@ -90966,9 +91004,9 @@ var init_scaleBar = __esm({
90966
91004
 
90967
91005
  // ../lib/dist/ggplotPalettes.js
90968
91006
  function paletteNamed(name) {
90969
- return name === void 0 ? void 0 : namedPalettes[name];
91007
+ return name === void 0 ? void 0 : Object.hasOwn(namedPalettes, name) ? namedPalettes[name] : Object.hasOwn(aliases2, name) ? namedPalettes[aliases2[name]] : void 0;
90970
91008
  }
90971
- var palettes, ggplotPalettes_default, namedPalettes;
91009
+ var palettes, ggplotPalettes_default, namedPalettes, aliases2;
90972
91010
  var init_ggplotPalettes = __esm({
90973
91011
  "../lib/dist/ggplotPalettes.js"() {
90974
91012
  "use strict";
@@ -91039,6 +91077,10 @@ var init_ggplotPalettes = __esm({
91039
91077
  "#bab0ac"
91040
91078
  ]
91041
91079
  };
91080
+ aliases2 = {
91081
+ okabeIto: "okabeito",
91082
+ tableau10: "tableau"
91083
+ };
91042
91084
  }
91043
91085
  });
91044
91086
 
@@ -91075,32 +91117,6 @@ var init_exportFileName = __esm({
91075
91117
  }
91076
91118
  });
91077
91119
 
91078
- // ../lib/dist/scales.js
91079
- function resolveScale(spec, values3) {
91080
- const domain = [...new Set(values3)].sort((a3, b2) => a3.localeCompare(b2));
91081
- const { map: map2, palette: palette2 } = spec ?? {};
91082
- const colors2 = map2 ?? createPaletteMap(domain, paletteNamed(palette2));
91083
- const present = new Set(domain);
91084
- const labels = map2 ? Object.keys(map2).filter((v2) => present.has(v2)) : domain;
91085
- return {
91086
- kind: "categorical",
91087
- colorOf: (value) => colors2[value],
91088
- // a categorical value is its own label, and the id a legend keys on
91089
- legend: labels.map((value) => ({
91090
- id: value,
91091
- label: value,
91092
- color: colors2[value]
91093
- }))
91094
- };
91095
- }
91096
- var init_scales = __esm({
91097
- "../lib/dist/scales.js"() {
91098
- "use strict";
91099
- init_createPaletteMap();
91100
- init_ggplotPalettes();
91101
- }
91102
- });
91103
-
91104
91120
  // ../lib/dist/featurePanels.js
91105
91121
  function rowPanelWidth(panel, view) {
91106
91122
  return panel.width ?? (panel.kind === "features" ? defaultFeaturePanelWidth : view.rowHeight);
@@ -91221,25 +91237,13 @@ function featurePanelSpans({ panel, width: width3, colWidth, domainBands, annota
91221
91237
  }))
91222
91238
  ]));
91223
91239
  }
91224
- function resolveFeatureScale(field, scale, annotations, drawn) {
91225
- const valuesOf = (list) => list.map((a3) => featureField(a3, field)).filter(notEmpty);
91226
- const resolved = resolveScale(scale, valuesOf(annotations));
91227
- const shown = new Set(valuesOf(drawn));
91228
- return {
91229
- field,
91230
- ...resolved,
91231
- legend: resolved.legend.filter((entry) => shown.has(entry.id))
91232
- };
91233
- }
91234
91240
  var UNSCALED_FEATURE, laneOverlap;
91235
91241
  var init_featurePanels = __esm({
91236
91242
  "../lib/dist/featurePanels.js"() {
91237
91243
  "use strict";
91238
- init_util5();
91239
91244
  init_packDomainLanes();
91240
91245
  init_constants();
91241
91246
  init_featureFields();
91242
- init_scales();
91243
91247
  init_util3();
91244
91248
  UNSCALED_FEATURE = "#d9d9d9";
91245
91249
  laneOverlap = 0.1;
@@ -92231,6 +92235,166 @@ var init_rowCoordinateCalculations = __esm({
92231
92235
  }
92232
92236
  });
92233
92237
 
92238
+ // ../lib/dist/groupKeys.js
92239
+ function compareRuns(a3, b2) {
92240
+ const runsA = a3.match(DIGIT_RUNS) ?? [];
92241
+ const runsB = b2.match(DIGIT_RUNS) ?? [];
92242
+ const shared = Math.min(runsA.length, runsB.length);
92243
+ for (let i2 = 0; i2 < shared; i2++) {
92244
+ const x2 = runsA[i2];
92245
+ const y2 = runsB[i2];
92246
+ if (x2 === y2) {
92247
+ continue;
92248
+ }
92249
+ if (/^\d/.test(x2) && /^\d/.test(y2)) {
92250
+ const nx = Number(x2);
92251
+ const ny = Number(y2);
92252
+ if (nx !== ny) {
92253
+ return nx < ny ? -1 : 1;
92254
+ }
92255
+ return x2.length < y2.length ? -1 : 1;
92256
+ }
92257
+ return x2 < y2 ? -1 : 1;
92258
+ }
92259
+ return runsA.length - runsB.length;
92260
+ }
92261
+ function compareGroupKeys(a3, b2) {
92262
+ if (a3 === b2) {
92263
+ return 0;
92264
+ }
92265
+ if (a3 === "" || b2 === "") {
92266
+ return a3 === "" ? 1 : -1;
92267
+ }
92268
+ const numA = NUMERIC.test(a3);
92269
+ const numB = NUMERIC.test(b2);
92270
+ if (numA !== numB) {
92271
+ return numA ? -1 : 1;
92272
+ }
92273
+ if (numA) {
92274
+ const diff = Number(a3) - Number(b2);
92275
+ if (diff !== 0) {
92276
+ return diff < 0 ? -1 : 1;
92277
+ }
92278
+ }
92279
+ return compareRuns(a3, b2);
92280
+ }
92281
+ var NUMERIC, DIGIT_RUNS;
92282
+ var init_groupKeys = __esm({
92283
+ "../lib/dist/groupKeys.js"() {
92284
+ "use strict";
92285
+ NUMERIC = /^-?\d+(\.\d+)?$/;
92286
+ DIGIT_RUNS = /\d+|\D+/g;
92287
+ }
92288
+ });
92289
+
92290
+ // ../lib/dist/scales.js
92291
+ function rangeList(range) {
92292
+ if (typeof range !== "string") {
92293
+ return range;
92294
+ }
92295
+ if (paletteNamed(range)) {
92296
+ return void 0;
92297
+ }
92298
+ const colors2 = range.split(/,(?![^(]*\))/).map((c2) => c2.trim());
92299
+ return colors2.every((c2) => A(c2).isValid()) ? colors2 : void 0;
92300
+ }
92301
+ function rangeColors(range, order2) {
92302
+ const list = rangeList(range);
92303
+ return list ? new Map(order2.slice(0, list.length).map((value, i2) => [value, list[i2]])) : new Map(Object.entries(createPaletteMap(order2, paletteNamed(typeof range === "string" ? range : void 0))));
92304
+ }
92305
+ function resolveScale(spec, values3) {
92306
+ const present = new Set(values3);
92307
+ const listed = new Set(spec?.domain);
92308
+ const order2 = [
92309
+ ...listed,
92310
+ ...[...present].filter((v2) => !listed.has(v2)).sort(compareGroupKeys)
92311
+ ];
92312
+ const colors2 = rangeColors(spec?.range, order2);
92313
+ return {
92314
+ kind: "categorical",
92315
+ colorOf: (value) => colors2.get(value),
92316
+ legend: order2.filter((value) => present.has(value) && colors2.has(value)).map((value) => ({ id: value, label: value, color: colors2.get(value) }))
92317
+ };
92318
+ }
92319
+ function declarationKey({ spec, field, table }) {
92320
+ const { scale = "categorical", domain, range, title = field } = spec;
92321
+ return JSON.stringify([table, scale, domain, range, title]);
92322
+ }
92323
+ function resolveShared(uses) {
92324
+ const groups = /* @__PURE__ */ new Map();
92325
+ for (const use4 of uses) {
92326
+ const key = declarationKey(use4);
92327
+ groups.set(key, [...groups.get(key) ?? [], use4]);
92328
+ }
92329
+ return new Map([...groups].map(([key, group]) => {
92330
+ const { spec, field } = group[0];
92331
+ const resolved = resolveScale(spec, group.flatMap((u2) => u2.values));
92332
+ const shown = group[0].shown ? new Set(group.flatMap((u2) => u2.shown ?? [])) : void 0;
92333
+ const scale = {
92334
+ ...resolved,
92335
+ key,
92336
+ title: spec.title ?? field,
92337
+ legend: shown ? resolved.legend.filter((entry) => shown.has(entry.id)) : resolved.legend
92338
+ };
92339
+ return [key, scale];
92340
+ }));
92341
+ }
92342
+ function readColor(record) {
92343
+ const { scale, legend, ...rest } = record;
92344
+ if (typeof scale !== "object" && legend === void 0) {
92345
+ return record;
92346
+ }
92347
+ const lifted = typeof scale !== "object" ? scale === void 0 ? {} : { scale } : scale.map ? { domain: Object.keys(scale.map), range: Object.values(scale.map) } : scale.palette === void 0 ? {} : { range: scale.palette };
92348
+ return {
92349
+ ...legend === void 0 ? {} : { title: legend },
92350
+ ...lifted,
92351
+ ...rest
92352
+ };
92353
+ }
92354
+ function readEncoding(encoding) {
92355
+ return readColor(encoding);
92356
+ }
92357
+ function readRowPanel(panel) {
92358
+ if (panel.kind === "strip") {
92359
+ return readColor(panel);
92360
+ }
92361
+ const color2 = panel.encoding?.color;
92362
+ return color2 ? { ...panel, encoding: { ...panel.encoding, color: readColor(color2) } } : panel;
92363
+ }
92364
+ function readColumnTrack(track) {
92365
+ const { max: max3, colors: colors2, ...rest } = track;
92366
+ if (max3 === void 0 && colors2 === void 0) {
92367
+ return track;
92368
+ }
92369
+ return {
92370
+ ...colors2 ? {
92371
+ encoding: {
92372
+ color: {
92373
+ domain: Object.keys(colors2),
92374
+ range: Object.values(colors2)
92375
+ }
92376
+ }
92377
+ } : {},
92378
+ ...max3 === void 0 ? {} : { scales: { y: { domainMax: max3 } } },
92379
+ ...rest
92380
+ };
92381
+ }
92382
+ function colorTable(spec, values3) {
92383
+ return Object.fromEntries(resolveScale(spec, values3).legend.map((e3) => [e3.id, e3.color]));
92384
+ }
92385
+ function letterColors(scheme) {
92386
+ return "map" in scheme ? scheme.map : colorTable(scheme, scheme.domain ?? []);
92387
+ }
92388
+ var init_scales = __esm({
92389
+ "../lib/dist/scales.js"() {
92390
+ "use strict";
92391
+ init_colord();
92392
+ init_createPaletteMap();
92393
+ init_ggplotPalettes();
92394
+ init_groupKeys();
92395
+ }
92396
+ });
92397
+
92234
92398
  // ../lib/dist/seqPosToGlobalCol.js
92235
92399
  function buildSeqPosIndex(row) {
92236
92400
  const index3 = new Int32Array(row.length);
@@ -93038,7 +93202,9 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
93038
93202
  * tracks supplied as data: per-column values drawn as bars, or a
93039
93203
  * per-column string drawn as a text track. See docs/layers.md
93040
93204
  */
93041
- columnTracks: stripDefault2(types.array(types.frozen()), []),
93205
+ columnTracks: stripDefault2(types.array(types.snapshotProcessor(types.frozen(), {
93206
+ preProcessor: readColumnTrack
93207
+ })), []),
93042
93208
  /**
93043
93209
  * #property
93044
93210
  * row-to-structure residue correspondence, computed outside the viewer
@@ -93118,20 +93284,25 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
93118
93284
  clades: stripDefault2(types.array(types.frozen()), []),
93119
93285
  /**
93120
93286
  * #property
93121
- * what the viewer's own marks read from `rowData`:
93122
- * `{channel, field, scale?}` per channel, where `channel` is
93123
- * `tipLabel` or `rowTint`. See docs/layers.md
93287
+ * what the viewer's own marks read from `rowData` or the feature
93288
+ * table: `{channel, field, range?, domain?, title?}` per channel. The
93289
+ * earlier `scale: {palette}` and `scale: {map}` read as `range` and
93290
+ * `domain`. See docs/layers.md
93124
93291
  */
93125
- encodings: stripDefault2(types.array(types.frozen()), []),
93292
+ encodings: stripDefault2(types.array(types.snapshotProcessor(types.frozen(), {
93293
+ preProcessor: readEncoding
93294
+ })), []),
93126
93295
  /**
93127
93296
  * #property
93128
93297
  * panels drawn between the tree and the alignment:
93129
- * `{kind: "strip", field, scale?, width?, header?}` colors one cell
93130
- * per row from a `rowData` field, and
93298
+ * `{kind: "strip", field, range?, domain?, title?, width?, header?}`
93299
+ * colors one cell per row from a `rowData` field, and
93131
93300
  * `{kind: "features", x, encoding?, transform?, width?, header?}`
93132
93301
  * draws the spans the GFF carries. See docs/layers.md
93133
93302
  */
93134
- rowPanels: stripDefault2(types.array(types.frozen()), [])
93303
+ rowPanels: stripDefault2(types.array(types.snapshotProcessor(types.frozen(), {
93304
+ preProcessor: readRowPanel
93305
+ })), [])
93135
93306
  })).volatile(() => ({
93136
93307
  /**
93137
93308
  * #volatile
@@ -93191,9 +93362,10 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
93191
93362
  volatileWidth: void 0,
93192
93363
  /**
93193
93364
  * #volatile
93194
- * resize handle width between tree and msa area, px
93365
+ * thickness of the dividers, between the tree and the alignment and under
93366
+ * the view, px
93195
93367
  */
93196
- resizeHandleWidth: 5,
93368
+ resizeHandleWidth,
93197
93369
  /**
93198
93370
  * #volatile
93199
93371
  * size of blocks of content to be drawn, px
@@ -94486,7 +94658,7 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
94486
94658
  return [track.id, { arcs }];
94487
94659
  }
94488
94660
  if (track.kind === "bar") {
94489
- const max3 = track.max ?? 1;
94661
+ const max3 = track.scales?.y?.domainMax ?? 1;
94490
94662
  const values3 = skip2(project(track, track.values ?? [], 0)).map((v2) => Math.min(1, Math.max(0, v2 / max3)));
94491
94663
  return [track.id, { values: values3 }];
94492
94664
  }
@@ -94525,7 +94697,10 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
94525
94697
  height: this.trackHeight(track.kind, heightKey, track.height),
94526
94698
  barColor: track.color,
94527
94699
  arcColor: track.color,
94528
- customColorScheme: track.colors,
94700
+ customColorScheme: track.encoding?.color ? colorTable(track.encoding.color, [
94701
+ ...track.encoding.color.domain ?? [],
94702
+ ...new Set(track.data)
94703
+ ]) : void 0,
94529
94704
  data: content?.data,
94530
94705
  arcs: content?.arcs
94531
94706
  }
@@ -94648,6 +94823,26 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
94648
94823
  }
94649
94824
  }));
94650
94825
  },
94826
+ /**
94827
+ * #getter
94828
+ * the reference row (`relativeTo`) repeated above the alignment, so it
94829
+ * stays in view while the rows compared against it scroll
94830
+ */
94831
+ get referenceTrackModels() {
94832
+ const { relativeTo } = self;
94833
+ const data = relativeTo === void 0 ? void 0 : self.columns.get(relativeTo);
94834
+ return relativeTo === void 0 || data === void 0 ? [] : [
94835
+ {
94836
+ model: {
94837
+ id: "reference-row",
94838
+ name: relativeTo,
94839
+ kind: "reference",
94840
+ data,
94841
+ height: self.rowHeight
94842
+ }
94843
+ }
94844
+ ];
94845
+ },
94651
94846
  get tracks() {
94652
94847
  return [
94653
94848
  ...this.adapterTrackModels,
@@ -94655,7 +94850,8 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
94655
94850
  ...self.columnTrackModels,
94656
94851
  // every computed track reads the alignment's columns, and a tree, a
94657
94852
  // GFF and a features panel draw a figure with none
94658
- ...self.numColumns > 0 ? this.computedTrackModels : []
94853
+ ...self.numColumns > 0 ? this.computedTrackModels : [],
94854
+ ...this.referenceTrackModels
94659
94855
  ];
94660
94856
  },
94661
94857
  /**
@@ -95365,7 +95561,7 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
95365
95561
  * #action
95366
95562
  */
95367
95563
  setColumnTracks(tracks) {
95368
- self.columnTracks.replace(tracks);
95564
+ self.columnTracks.replace(tracks.map(readColumnTrack));
95369
95565
  },
95370
95566
  /**
95371
95567
  * #action
@@ -95380,14 +95576,14 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
95380
95576
  * replace what the viewer's marks read from the row table
95381
95577
  */
95382
95578
  setEncodings(encodings) {
95383
- self.encodings.replace(encodings);
95579
+ self.encodings.replace(encodings.map(readEncoding));
95384
95580
  },
95385
95581
  /**
95386
95582
  * #action
95387
95583
  * replace the panels drawn between the tree and the alignment
95388
95584
  */
95389
95585
  setRowPanels(panels) {
95390
- self.rowPanels.replace(panels);
95586
+ self.rowPanels.replace(panels.map(readRowPanel));
95391
95587
  },
95392
95588
  /**
95393
95589
  * #action
@@ -95556,46 +95752,42 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
95556
95752
  * the categorical color keys drawn for this view, shared by the on-screen
95557
95753
  * legend overlay and the SVG export's reserved column. The domain overlay
95558
95754
  * produces the first, listing the `featureFill` scale where an encoding
95559
- * names one. Every field a row-table encoding or a row panel reads
95560
- * produces one more, so two channels over one field, or two strips over
95561
- * it, list that field once. A strip's `legend` names the title it lists
95562
- * under, so strips over eight fields with one set of colors list one
95563
- * legend between them
95755
+ * names one. Every scale a row-table encoding or a row panel reads
95756
+ * produces one more, keyed by its declaration, so two channels or two
95757
+ * strips declaring one scale list it once, and strips over eight fields
95758
+ * naming one `title` list one legend between them
95564
95759
  */
95565
95760
  get legends() {
95566
95761
  const { featureFillEncoding, fillPalette, visibleDomainTypes } = this;
95567
95762
  const byKey = /* @__PURE__ */ new Map();
95568
- const add = (field, entries3, id) => {
95569
- if (entries3.length === 0) {
95763
+ const ids = /* @__PURE__ */ new Set();
95764
+ const add = (key, title, entries3, overlay = false) => {
95765
+ const k2 = key ?? "domains";
95766
+ if (entries3.length === 0 || byKey.has(k2)) {
95570
95767
  return;
95571
95768
  }
95572
- const key = field === void 0 ? "domains" : `field:${field}`;
95573
- const legend = byKey.get(key);
95574
- if (legend) {
95575
- const seen = new Set(legend.entries.map((e3) => e3.id));
95576
- legend.entries.push(...entries3.filter((e3) => !seen.has(e3.id)));
95577
- } else {
95578
- byKey.set(key, {
95579
- id: id ?? (field === void 0 ? "domains" : `rowData-${field}`),
95580
- title: field ?? "Domains",
95581
- entries: [...entries3]
95582
- });
95769
+ const base = overlay || key === void 0 ? "domains" : `rowData-${title}`;
95770
+ let id = base;
95771
+ for (let n2 = 2; ids.has(id); n2++) {
95772
+ id = `${base}-${n2}`;
95583
95773
  }
95774
+ ids.add(id);
95775
+ byKey.set(k2, { id, title: title ?? "Domains", entries: entries3 });
95584
95776
  };
95585
95777
  if (self.actuallyShowDomains && self.numColumns > 0) {
95586
- add(featureFillEncoding?.field, featureFillEncoding ? featureFillEncoding.legend : visibleDomainTypes.map((d3) => ({
95778
+ add(featureFillEncoding?.key, featureFillEncoding?.title, featureFillEncoding ? featureFillEncoding.legend : visibleDomainTypes.map((d3) => ({
95587
95779
  id: d3.accession,
95588
95780
  label: d3.name,
95589
95781
  color: d3.color ?? fillPalette[d3.accession]
95590
- })), "domains");
95782
+ })), true);
95591
95783
  }
95592
- for (const { channel, field, legend } of this.resolvedEncodings) {
95784
+ for (const { channel, key, title, legend } of this.resolvedEncodings) {
95593
95785
  if (!featureChannels.has(channel)) {
95594
- add(field, legend);
95786
+ add(key, title, legend);
95595
95787
  }
95596
95788
  }
95597
- for (const { legendTitle, legend } of this.rowPanelScales) {
95598
- add(legendTitle, legend);
95789
+ for (const { legendKey, legendTitle, legend } of this.rowPanelScales) {
95790
+ add(legendKey, legendTitle, legend);
95599
95791
  }
95600
95792
  return [...byKey.values()];
95601
95793
  },
@@ -95827,12 +96019,46 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
95827
96019
  * table or the encodings, never per row per frame.
95828
96020
  */
95829
96021
  get resolvedEncodings() {
95830
- const rows = Object.values(self.rowData);
95831
96022
  return self.encodings.map((encoding) => ({
95832
96023
  ...encoding,
95833
- ...featureChannels.has(encoding.channel) ? resolveFeatureScale(encoding.field, encoding.scale, self.allAnnotations, self.filteredAnnotations) : resolveScale(encoding.scale, rows.map((row) => row?.[encoding.field]).filter(notEmpty))
96024
+ ...this.scaleOf(encoding, featureChannels.has(encoding.channel) ? "features" : "rows")
95834
96025
  }));
95835
96026
  },
96027
+ /**
96028
+ * #getter
96029
+ * every color object the encodings and the row panels declare, keyed
96030
+ * by declaration (`declarationKey`) and resolved once over the union
96031
+ * of the values its records' fields take, so a value two strips share
96032
+ * takes one color in both. A feature field reads every feature loaded,
96033
+ * so hiding a type in the filter dialog leaves the rest in their
96034
+ * colors, and its legend lists the values of the drawn features.
96035
+ */
96036
+ get resolvedScales() {
96037
+ const rows = Object.values(self.rowData);
96038
+ const featureValues = (list, field) => list.map((a3) => featureField(a3, field)).filter(notEmpty);
96039
+ const use4 = (channel, table) => ({
96040
+ spec: channel,
96041
+ field: channel.field,
96042
+ table,
96043
+ ...table === "rows" ? {
96044
+ values: rows.map((row) => row?.[channel.field]).filter(notEmpty)
96045
+ } : {
96046
+ values: featureValues(self.allAnnotations, channel.field),
96047
+ shown: featureValues(self.filteredAnnotations, channel.field)
96048
+ }
96049
+ });
96050
+ return resolveShared([
96051
+ ...self.encodings.map((encoding) => use4(encoding, featureChannels.has(encoding.channel) ? "features" : "rows")),
96052
+ ...self.rowPanels.flatMap((panel) => panel.kind === "strip" ? [use4(panel, "rows")] : panel.encoding?.color ? [use4(panel.encoding.color, "features")] : [])
96053
+ ]);
96054
+ },
96055
+ /**
96056
+ * #method
96057
+ * the shared scale a record's color object resolves to
96058
+ */
96059
+ scaleOf(channel, table) {
96060
+ return this.resolvedScales.get(declarationKey({ spec: channel, field: channel.field, table }));
96061
+ },
95836
96062
  /**
95837
96063
  * #getter
95838
96064
  * each row panel's scale resolved against the values its field takes,
@@ -95846,14 +96072,15 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
95846
96072
  return self.rowPanels.map((panel) => {
95847
96073
  if (panel.kind === "features") {
95848
96074
  const color2 = panel.encoding?.color;
95849
- const encoding = color2 ? resolveFeatureScale(color2.field, color2.scale, self.allAnnotations, annotations) : featureFillEncoding;
96075
+ const encoding = color2 ? { field: color2.field, ...this.scaleOf(color2, "features") } : featureFillEncoding;
95850
96076
  const label2 = panel.encoding?.label;
95851
96077
  return {
95852
96078
  kind: panel.kind,
95853
96079
  x: panel.x,
95854
96080
  header: panel.header ?? "",
95855
96081
  field: encoding?.field,
95856
- legendTitle: encoding?.field,
96082
+ legendKey: encoding?.key,
96083
+ legendTitle: encoding?.title,
95857
96084
  colors: color2 ? featureColorMap(annotations, encoding, fillPalette) : this.featureColors,
95858
96085
  labels: label2 ? featureLabelMap(annotations, label2) : featureLabels,
95859
96086
  legend: encoding?.legend ?? this.visibleDomainTypes.map((d3) => ({
@@ -95863,12 +96090,13 @@ function stateModelFactory({ maxInlineSnapshotBytes: maxInlineSnapshotBytes2 = m
95863
96090
  }))
95864
96091
  };
95865
96092
  }
95866
- const { colorOf, legend } = resolveScale(panel.scale, Object.values(rowData).map((row) => row?.[panel.field]).filter(notEmpty));
96093
+ const { colorOf, legend, key, title } = this.scaleOf(panel, "rows");
95867
96094
  return {
95868
96095
  kind: panel.kind,
95869
96096
  field: panel.field,
95870
96097
  header: panel.header ?? panel.field,
95871
- legendTitle: panel.legend ?? panel.field,
96098
+ legendKey: key,
96099
+ legendTitle: title,
95872
96100
  colors: colorByRow(rowData, panel.field, colorOf),
95873
96101
  legend
95874
96102
  };
@@ -96412,7 +96640,7 @@ var init_model = __esm({
96412
96640
 
96413
96641
  // ../lib/dist/viewerSnapshot.js
96414
96642
  function colorSchemeSnapshot(scheme) {
96415
- return typeof scheme === "string" ? { colorSchemeName: scheme } : scheme ? { customColorScheme: scheme.map } : {};
96643
+ return typeof scheme === "string" ? { colorSchemeName: scheme } : scheme ? { customColorScheme: letterColors(scheme) } : {};
96416
96644
  }
96417
96645
  function columnHighlights(columns = []) {
96418
96646
  const sorted = [...new Set(columns)].sort((a3, b2) => a3 - b2);
@@ -96488,6 +96716,7 @@ var init_viewerSnapshot = __esm({
96488
96716
  "../lib/dist/viewerSnapshot.js"() {
96489
96717
  "use strict";
96490
96718
  init_theme();
96719
+ init_scales();
96491
96720
  }
96492
96721
  });
96493
96722
 
@@ -96602,6 +96831,7 @@ var init_MSAViewer = __esm({
96602
96831
  init_styles();
96603
96832
  import_mobx7 = __toESM(require_dist(), 1);
96604
96833
  init_model();
96834
+ init_scales();
96605
96835
  init_viewerSnapshot();
96606
96836
  init_Loading2();
96607
96837
  MSAViewer = (0, import_react104.forwardRef)(function MSAViewer2(props, ref) {
@@ -96663,7 +96893,7 @@ var init_MSAViewer = __esm({
96663
96893
  if (typeof scheme === "string") {
96664
96894
  m2.setColorSchemeName(scheme);
96665
96895
  } else if (scheme) {
96666
- m2.setCustomColorScheme(scheme.map);
96896
+ m2.setCustomColorScheme(letterColors(scheme));
96667
96897
  }
96668
96898
  }),
96669
96899
  synced(viewerHighlights, (m2, v2) => {
@@ -96788,6 +97018,7 @@ function defineMsaElement(tagName = "jbrowse-msa") {
96788
97018
  class MsaElement extends HTMLElement {
96789
97019
  static observedAttributes = [...ownAttributes, ...nightingaleAttributes];
96790
97020
  #viewer;
97021
+ #nearby;
96791
97022
  #model;
96792
97023
  #manager;
96793
97024
  #cancelRange;
@@ -96921,7 +97152,18 @@ function defineMsaElement(tagName = "jbrowse-msa") {
96921
97152
  if (!this.style.display) {
96922
97153
  this.style.display = "block";
96923
97154
  }
96924
- this.#viewer = mount(this, this.#props());
97155
+ if (this.#lazy) {
97156
+ const height2 = numberAttribute(this.getAttribute("height")) ?? defaultHeight;
97157
+ this.style.minHeight = `${height2 + resizeHandleWidth}px`;
97158
+ this.#nearby = new IntersectionObserver((entries3) => {
97159
+ if (entries3.some((entry) => entry.isIntersecting)) {
97160
+ this.#mount();
97161
+ }
97162
+ }, { rootMargin: lazyMargin });
97163
+ this.#nearby.observe(this);
97164
+ } else {
97165
+ this.#mount();
97166
+ }
96925
97167
  const manager2 = this.closest("nightingale-manager");
96926
97168
  if (manager2) {
96927
97169
  void customElements.whenDefined("nightingale-manager").then(() => {
@@ -96932,7 +97174,17 @@ function defineMsaElement(tagName = "jbrowse-msa") {
96932
97174
  });
96933
97175
  }
96934
97176
  }
97177
+ get #lazy() {
97178
+ return this.getAttribute("loading") === "lazy" && typeof IntersectionObserver !== "undefined";
97179
+ }
97180
+ #mount() {
97181
+ this.#nearby?.disconnect();
97182
+ this.#nearby = void 0;
97183
+ this.#viewer ??= mount(this, this.#props());
97184
+ }
96935
97185
  disconnectedCallback() {
97186
+ this.#nearby?.disconnect();
97187
+ this.#nearby = void 0;
96936
97188
  this.#manager?.unregister(this);
96937
97189
  this.#manager = void 0;
96938
97190
  this.#cancelRange?.();
@@ -96951,6 +97203,10 @@ function defineMsaElement(tagName = "jbrowse-msa") {
96951
97203
  }
96952
97204
  } else if (name === "highlight") {
96953
97205
  this.#followHighlight();
97206
+ } else if (name === "loading") {
97207
+ if (this.#nearby && !this.#lazy) {
97208
+ this.#mount();
97209
+ }
96954
97210
  } else {
96955
97211
  this.#viewer?.update(this.#props());
96956
97212
  }
@@ -96959,11 +97215,12 @@ function defineMsaElement(tagName = "jbrowse-msa") {
96959
97215
  customElements.define(tagName, MsaElement);
96960
97216
  return MsaElement;
96961
97217
  }
96962
- var import_mobx8, dataProperties, ownAttributes, nightingaleAttributes;
97218
+ var import_mobx8, dataProperties, ownAttributes, lazyMargin, nightingaleAttributes;
96963
97219
  var init_element = __esm({
96964
97220
  "../lib/dist/element.js"() {
96965
97221
  "use strict";
96966
97222
  import_mobx8 = __toESM(require_dist(), 1);
97223
+ init_constants();
96967
97224
  init_mount();
96968
97225
  dataProperties = [
96969
97226
  "msa",
@@ -96984,8 +97241,10 @@ var init_element = __esm({
96984
97241
  "hide-header",
96985
97242
  "theme",
96986
97243
  "reference-row",
96987
- "tree-area-width"
97244
+ "tree-area-width",
97245
+ "loading"
96988
97246
  ];
97247
+ lazyMargin = "200px";
96989
97248
  nightingaleAttributes = ["display-start", "display-end", "highlight"];
96990
97249
  }
96991
97250
  });