react-msaview-cli 8.0.0 → 8.1.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.
- package/dist/index.js +355 -288
- package/package.json +3 -3
package/dist/index.js
CHANGED
|
@@ -50325,7 +50325,7 @@ var init_legendRows = __esm({
|
|
|
50325
50325
|
});
|
|
50326
50326
|
|
|
50327
50327
|
// ../lib/dist/constants.js
|
|
50328
|
-
var defaultRowHeight, defaultColWidth, defaultHeight, defaultScrollX, defaultScrollY, defaultCurrentAlignment, defaultShowDomains, defaultShowDomainLegend, defaultHideGaps, defaultAllowedGappyness, defaultSubFeatureRows, subFeatureRowHeight, domainUnderlineHeight, segmentFeatureTypes, segmentShades, defaultDrawMsaLetters, defaultScrollZoom, scrollZoomAxes, defaultScrollZoomAxis, minLetterRowHeight, minLetterColWidth, labelReferenceFontSize, minColWidth, minRowHeight, maxCellSize, defaultBgColor, defaultColorSchemeName, defaultShowColumnStats, defaultDrawLabels, defaultLabelsAlignRight, defaultTreeAreaWidth, defaultTreeWidth, defaultShowBranchLen, defaultDrawTree, defaultDrawNodeBubbles, defaultDrawNodeLabels, defaultShowTreeOverview, defaultOverviewHeight, maxNeighborJoiningRows, rowTintAlpha, cladeHighlightColor, cladeHighlightAlpha, maxInlineSnapshotBytes, rowPanelHeaderHeight, treeScaleBarHeight, defaultFeaturePanelWidth, msaOverlayZIndex, legendZIndex;
|
|
50328
|
+
var defaultRowHeight, defaultColWidth, defaultHeight, defaultScrollX, defaultScrollY, defaultCurrentAlignment, defaultShowDomains, defaultShowDomainLegend, defaultHideGaps, defaultAllowedGappyness, defaultSubFeatureRows, subFeatureRowHeight, domainUnderlineHeight, segmentFeatureTypes, segmentShades, defaultDrawMsaLetters, defaultScrollZoom, scrollZoomAxes, defaultScrollZoomAxis, minLetterRowHeight, minLetterColWidth, minFeatureLabelHeight, labelReferenceFontSize, minColWidth, minRowHeight, maxCellSize, defaultBgColor, defaultColorSchemeName, defaultShowColumnStats, defaultDrawLabels, defaultLabelsAlignRight, defaultTreeAreaWidth, defaultTreeWidth, defaultShowBranchLen, defaultDrawTree, defaultDrawNodeBubbles, defaultDrawNodeLabels, defaultShowTreeOverview, defaultOverviewHeight, maxNeighborJoiningRows, rowTintAlpha, cladeHighlightColor, cladeHighlightAlpha, maxInlineSnapshotBytes, rowPanelHeaderHeight, treeScaleBarHeight, defaultFeaturePanelWidth, msaOverlayZIndex, legendZIndex;
|
|
50329
50329
|
var init_constants = __esm({
|
|
50330
50330
|
"../lib/dist/constants.js"() {
|
|
50331
50331
|
"use strict";
|
|
@@ -50357,6 +50357,7 @@ var init_constants = __esm({
|
|
|
50357
50357
|
defaultScrollZoomAxis = "both";
|
|
50358
50358
|
minLetterRowHeight = 8;
|
|
50359
50359
|
minLetterColWidth = 5;
|
|
50360
|
+
minFeatureLabelHeight = 9;
|
|
50360
50361
|
labelReferenceFontSize = 16;
|
|
50361
50362
|
minColWidth = 0.2;
|
|
50362
50363
|
minRowHeight = 1;
|
|
@@ -50746,9 +50747,13 @@ function spanRows(leaves2, bandsByRow) {
|
|
|
50746
50747
|
return rows;
|
|
50747
50748
|
}
|
|
50748
50749
|
function drawFeatureSpans({ ctx, rows, layout, xOf, colors: colors2, labelOf, labelDrawn, contrastText, xMin, xMax }) {
|
|
50750
|
+
const placed = [];
|
|
50749
50751
|
for (const { y: y2, bands } of rows) {
|
|
50750
50752
|
const h2 = layout.height(bands[0].laneCount);
|
|
50751
50753
|
const headLen = layout.headLength(h2);
|
|
50754
|
+
const rise = layout.headRise?.(h2) ?? 0;
|
|
50755
|
+
const labelled = labelOf !== void 0 && h2 >= minFeatureLabelHeight;
|
|
50756
|
+
placed.length = 0;
|
|
50752
50757
|
for (const band of bands) {
|
|
50753
50758
|
const [xStart, xEnd] = xOf(band);
|
|
50754
50759
|
const w2 = xEnd - xStart;
|
|
@@ -50760,37 +50765,54 @@ function drawFeatureSpans({ ctx, rows, layout, xOf, colors: colors2, labelOf, la
|
|
|
50760
50765
|
ctx.fillStyle = fill;
|
|
50761
50766
|
ctx.strokeStyle = stroke;
|
|
50762
50767
|
const { strand } = band.annotation;
|
|
50768
|
+
const head = strand === void 0 ? 0 : Math.min(headLen, w2);
|
|
50763
50769
|
if (strand === void 0) {
|
|
50764
50770
|
ctx.fillRect(xStart, t3, w2, h2);
|
|
50765
50771
|
ctx.strokeRect(xStart, t3, w2, h2);
|
|
50766
50772
|
} else {
|
|
50767
|
-
drawGeneArrow({ ctx, x: xStart, t: t3, w: w2, h: h2,
|
|
50773
|
+
drawGeneArrow({ ctx, x: xStart, t: t3, w: w2, h: h2, head, rise, strand });
|
|
50774
|
+
}
|
|
50775
|
+
if (labelled) {
|
|
50776
|
+
placed.push({ band, xStart, w: w2, t: t3, head, fill });
|
|
50768
50777
|
}
|
|
50769
|
-
|
|
50770
|
-
|
|
50771
|
-
|
|
50772
|
-
|
|
50773
|
-
|
|
50778
|
+
}
|
|
50779
|
+
if (placed.length > 0) {
|
|
50780
|
+
ctx.font = `${Math.min(h2 - 2, 11)}px sans-serif`;
|
|
50781
|
+
ctx.textAlign = "center";
|
|
50782
|
+
ctx.textBaseline = "middle";
|
|
50783
|
+
for (const { band, xStart, w: w2, t: t3, head, fill } of placed) {
|
|
50784
|
+
const label = labelOf(band);
|
|
50785
|
+
if (label !== void 0 && ctx.measureText(label).width + 2 <= w2 - head / 2) {
|
|
50774
50786
|
labelDrawn?.(band);
|
|
50775
50787
|
ctx.fillStyle = contrastText(fill);
|
|
50776
|
-
ctx.textAlign = "center";
|
|
50777
|
-
ctx.textBaseline = "middle";
|
|
50778
50788
|
ctx.fillText(label, xStart + w2 / 2, t3 + h2 / 2);
|
|
50779
50789
|
}
|
|
50780
50790
|
}
|
|
50781
50791
|
}
|
|
50782
50792
|
}
|
|
50783
50793
|
}
|
|
50784
|
-
function drawGeneArrow({ ctx, x: x2, t: t3, w: w2, h: h2,
|
|
50785
|
-
const
|
|
50786
|
-
const
|
|
50787
|
-
const
|
|
50794
|
+
function drawGeneArrow({ ctx, x: x2, t: t3, w: w2, h: h2, head, rise, strand }) {
|
|
50795
|
+
const tip = strand > 0 ? x2 + w2 : x2;
|
|
50796
|
+
const tail = strand > 0 ? x2 : x2 + w2;
|
|
50797
|
+
const flange = strand > 0 ? tip - head : tip + head;
|
|
50798
|
+
const bottom2 = t3 + h2;
|
|
50799
|
+
const crown = t3 - rise;
|
|
50800
|
+
const point = (crown + bottom2) / 2;
|
|
50788
50801
|
ctx.beginPath();
|
|
50789
|
-
|
|
50790
|
-
|
|
50791
|
-
|
|
50792
|
-
|
|
50793
|
-
|
|
50802
|
+
if (head >= w2) {
|
|
50803
|
+
ctx.moveTo(tail, crown);
|
|
50804
|
+
ctx.lineTo(tip, point);
|
|
50805
|
+
ctx.lineTo(tail, bottom2);
|
|
50806
|
+
} else {
|
|
50807
|
+
ctx.moveTo(tail, t3);
|
|
50808
|
+
ctx.lineTo(flange, t3);
|
|
50809
|
+
if (rise > 0) {
|
|
50810
|
+
ctx.lineTo(flange, crown);
|
|
50811
|
+
}
|
|
50812
|
+
ctx.lineTo(tip, point);
|
|
50813
|
+
ctx.lineTo(flange, bottom2);
|
|
50814
|
+
ctx.lineTo(tail, bottom2);
|
|
50815
|
+
}
|
|
50794
50816
|
ctx.closePath();
|
|
50795
50817
|
ctx.fill();
|
|
50796
50818
|
ctx.stroke();
|
|
@@ -50798,6 +50820,7 @@ function drawGeneArrow({ ctx, x: x2, t: t3, w: w2, h: h2, headLen, strand }) {
|
|
|
50798
50820
|
var init_drawFeatureSpans = __esm({
|
|
50799
50821
|
"../lib/dist/components/msa/drawFeatureSpans.js"() {
|
|
50800
50822
|
"use strict";
|
|
50823
|
+
init_constants();
|
|
50801
50824
|
}
|
|
50802
50825
|
});
|
|
50803
50826
|
|
|
@@ -50814,9 +50837,8 @@ function renderBoxFeatureCanvasBlock({ model: model2, theme, offsetX, offsetY, c
|
|
|
50814
50837
|
ctx.scale(k2, k2);
|
|
50815
50838
|
ctx.translate(-offsetX, rowHeight / 2 - offsetY);
|
|
50816
50839
|
const barHeight = domainUnderline ? Math.min(domainUnderlineHeight, rowHeight) : rowHeight;
|
|
50817
|
-
const drawSegmentLabels = !featureLabels && !showMsaLetters && !subFeatureRows
|
|
50840
|
+
const drawSegmentLabels = !featureLabels && !showMsaLetters && !subFeatureRows;
|
|
50818
50841
|
const labelled = drawSegmentLabels ? /* @__PURE__ */ new Set() : void 0;
|
|
50819
|
-
const cull = rowHeight + colWidth;
|
|
50820
50842
|
drawFeatureSpans({
|
|
50821
50843
|
ctx,
|
|
50822
50844
|
rows: spanRows(getVisibleLeaves({ model: model2, offsetY, blockSizeY: by }), domainBands),
|
|
@@ -50825,17 +50847,19 @@ function renderBoxFeatureCanvasBlock({ model: model2, theme, offsetX, offsetY, c
|
|
|
50825
50847
|
// shares out the row height between them instead
|
|
50826
50848
|
height: (laneCount) => subFeatureRows ? Math.min(subFeatureRowHeight, rowHeight / laneCount) : barHeight,
|
|
50827
50849
|
top: (y2, lane, h2) => y2 - rowHeight + (subFeatureRows ? lane * h2 : domainUnderline ? rowHeight - h2 : 0),
|
|
50828
|
-
|
|
50829
|
-
//
|
|
50830
|
-
|
|
50850
|
+
headLength: (h2) => domainUnderline ? rowHeight / 2 : h2,
|
|
50851
|
+
// a head only as tall as an underline bar tapers over ten pixels of
|
|
50852
|
+
// three, which reads as nothing; it takes the lower two fifths of the
|
|
50853
|
+
// row instead, leaving the letters above it
|
|
50854
|
+
headRise: (h2) => domainUnderline ? Math.max(0, rowHeight * 0.4 - h2) : 0
|
|
50831
50855
|
},
|
|
50832
50856
|
xOf: (band) => [band.startCol * colWidth, band.endCol * colWidth],
|
|
50833
50857
|
colors: featureColors,
|
|
50834
50858
|
labelOf: (band) => featureLabels?.get(band.annotation) ?? (labelled && !labelled.has(band.annotation.accession) ? segmentLabels.get(band.annotation.accession) : void 0),
|
|
50835
50859
|
labelDrawn: (band) => labelled?.add(band.annotation.accession),
|
|
50836
50860
|
contrastText: contrastTextFn(theme),
|
|
50837
|
-
xMin: offsetX
|
|
50838
|
-
xMax: offsetX + bx
|
|
50861
|
+
xMin: offsetX,
|
|
50862
|
+
xMax: offsetX + bx
|
|
50839
50863
|
});
|
|
50840
50864
|
}
|
|
50841
50865
|
var init_renderBoxFeatureCanvasBlock = __esm({
|
|
@@ -51070,16 +51094,15 @@ function renderMSABlock({ model: model2, offsetX, offsetY, ctx, theme, highResSc
|
|
|
51070
51094
|
ctx.resetTransform();
|
|
51071
51095
|
}
|
|
51072
51096
|
function drawTilesAndText({ model: model2, ctx, theme, visibleLeaves, xStart, xEnd, referenceSeq, drawTiles, rasterTiles }) {
|
|
51073
|
-
const { bgColor, columns, colWidth, rowHeight, relativeTo, showMsaLetters, subFeatureRows, domainUnderline, domainBandsByStart } = model2;
|
|
51097
|
+
const { bgColor, columns, colWidth, rowHeight, fontSize: fontSize2, relativeTo, showMsaLetters, subFeatureRows, domainUnderline, domainBandsByStart, featureColors } = model2;
|
|
51074
51098
|
const tiles = drawTiles && bgColor;
|
|
51075
51099
|
const paintTiles = tiles && !rasterTiles;
|
|
51076
51100
|
if (paintTiles || showMsaLetters) {
|
|
51077
|
-
const needsColor = paintTiles || showMsaLetters;
|
|
51078
51101
|
const tileColor = tileColorFn(model2);
|
|
51079
51102
|
const contrastText = contrastTextFn(theme);
|
|
51080
51103
|
const offsetXAligned = xStart * colWidth;
|
|
51081
51104
|
const halfColWidth = colWidth / 2;
|
|
51082
|
-
const
|
|
51105
|
+
const baselineOffset = rowHeight / 2 - fontSize2 / 4;
|
|
51083
51106
|
const overDomains = !drawTiles && !subFeatureRows && !domainUnderline;
|
|
51084
51107
|
for (let i2 = 0, l1 = visibleLeaves.length; i2 < l1; i2++) {
|
|
51085
51108
|
const node2 = visibleLeaves[i2];
|
|
@@ -51088,14 +51111,14 @@ function drawTilesAndText({ model: model2, ctx, theme, visibleLeaves, xStart, xE
|
|
|
51088
51111
|
const str = columns.get(name)?.slice(xStart, xEnd);
|
|
51089
51112
|
if (str) {
|
|
51090
51113
|
const tileY = y2 - rowHeight;
|
|
51091
|
-
const textY = y2 -
|
|
51114
|
+
const textY = y2 - baselineOffset;
|
|
51092
51115
|
const bandAt = domainBandCursor(overDomains ? domainBandsByStart.get(name) : void 0);
|
|
51093
51116
|
for (let j2 = 0, l2 = str.length; j2 < l2; j2++) {
|
|
51094
51117
|
const col = xStart + j2;
|
|
51095
51118
|
const letter = str[j2];
|
|
51096
51119
|
const x2 = j2 * colWidth + offsetXAligned;
|
|
51097
51120
|
const isMatchingReference = referenceSeq && name !== relativeTo && letter === referenceSeq[j2];
|
|
51098
|
-
const color2 =
|
|
51121
|
+
const color2 = tileColor(col, letter);
|
|
51099
51122
|
if (paintTiles) {
|
|
51100
51123
|
ctx.fillStyle = isMatchingReference ? theme.palette.action.hover : color2 || theme.palette.background.default;
|
|
51101
51124
|
ctx.fillRect(x2, tileY, colWidth, rowHeight);
|
|
@@ -51104,7 +51127,7 @@ function drawTilesAndText({ model: model2, ctx, theme, visibleLeaves, xStart, xE
|
|
|
51104
51127
|
const covering = bandAt(col);
|
|
51105
51128
|
ctx.fillStyle = covering ? (
|
|
51106
51129
|
// on top of a domain box: contrast against the box fill
|
|
51107
|
-
contrastText(
|
|
51130
|
+
contrastText(featureColors.get(covering.annotation)?.fill)
|
|
51108
51131
|
) : isMatchingReference ? (
|
|
51109
51132
|
// the dot sits on the faint reference-match wash, which is
|
|
51110
51133
|
// the theme's background with a little of its text color in it
|
|
@@ -51593,7 +51616,7 @@ function drawSequenceLogo({ ctx, colStats, colorScheme, maxBits, textColor, colW
|
|
|
51593
51616
|
}
|
|
51594
51617
|
}
|
|
51595
51618
|
function drawTrackBlock({ model: model2, ctx, track, offsetX, offsetY = 0, theme, blockSizeXOverride, highResScaleFactorOverride }) {
|
|
51596
|
-
const { blockSize,
|
|
51619
|
+
const { blockSize, colWidth, highResScaleFactor } = model2;
|
|
51597
51620
|
const { id, kind, height: trackHeight, barColor, arcColor, arcs, customColorScheme, data } = track.model;
|
|
51598
51621
|
const blockSizeX = blockSizeXOverride ?? blockSize;
|
|
51599
51622
|
const k2 = highResScaleFactorOverride ?? highResScaleFactor;
|
|
@@ -51629,9 +51652,9 @@ function drawTrackBlock({ model: model2, ctx, track, offsetX, offsetY = 0, theme
|
|
|
51629
51652
|
case "logo": {
|
|
51630
51653
|
drawSequenceLogo({
|
|
51631
51654
|
ctx,
|
|
51632
|
-
colStats,
|
|
51633
|
-
colorScheme:
|
|
51634
|
-
maxBits: alphabetMaxBits,
|
|
51655
|
+
colStats: model2.colStats,
|
|
51656
|
+
colorScheme: model2.colorScheme,
|
|
51657
|
+
maxBits: model2.alphabetMaxBits,
|
|
51635
51658
|
textColor,
|
|
51636
51659
|
colWidth,
|
|
51637
51660
|
trackHeight,
|
|
@@ -51659,13 +51682,14 @@ function drawTrackBlock({ model: model2, ctx, track, offsetX, offsetY = 0, theme
|
|
|
51659
51682
|
break;
|
|
51660
51683
|
}
|
|
51661
51684
|
case "text": {
|
|
51685
|
+
const { bgColor, fontSize: fontSize2, rowHeight, showMsaLetters } = model2;
|
|
51662
51686
|
ctx.textAlign = "center";
|
|
51663
51687
|
ctx.textBaseline = "middle";
|
|
51664
51688
|
setFontSize(ctx, fontSize2);
|
|
51665
51689
|
drawTextTrackContent({
|
|
51666
51690
|
ctx,
|
|
51667
51691
|
data,
|
|
51668
|
-
colorScheme: customColorScheme ??
|
|
51692
|
+
colorScheme: customColorScheme ?? model2.colorScheme,
|
|
51669
51693
|
contrastText: contrastTextFn(theme),
|
|
51670
51694
|
bgColor,
|
|
51671
51695
|
drawLetters: showMsaLetters,
|
|
@@ -75836,7 +75860,7 @@ function createMakeStyles(params) {
|
|
|
75836
75860
|
function makeStyles2() {
|
|
75837
75861
|
return function(cssObjectByRuleNameOrGetCssObjectByRuleName) {
|
|
75838
75862
|
const getCssObjectByRuleName = typeof cssObjectByRuleNameOrGetCssObjectByRuleName === "function" ? cssObjectByRuleNameOrGetCssObjectByRuleName : () => cssObjectByRuleNameOrGetCssObjectByRuleName;
|
|
75839
|
-
return function
|
|
75863
|
+
return function useStyles25(_params, muiStyleOverridesParams) {
|
|
75840
75864
|
const theme = useTheme5();
|
|
75841
75865
|
const { css: css2, cx: cx2 } = useCssAndCx();
|
|
75842
75866
|
const classes2 = (0, import_react14.useMemo)(() => {
|
|
@@ -83864,10 +83888,6 @@ function useWheelScroll({ ref, onScrollX, onScrollY, onZoom, scrollZoom }) {
|
|
|
83864
83888
|
};
|
|
83865
83889
|
}, [mouseDragging, onScrollX, onScrollY]);
|
|
83866
83890
|
function onMouseDown(event) {
|
|
83867
|
-
const target = event.target;
|
|
83868
|
-
if (target.draggable || target.dataset.resizer) {
|
|
83869
|
-
return;
|
|
83870
|
-
}
|
|
83871
83891
|
if (event.button === 0) {
|
|
83872
83892
|
prevX.current = event.clientX;
|
|
83873
83893
|
prevY.current = event.clientY;
|
|
@@ -84198,7 +84218,7 @@ var init_Track = __esm({
|
|
|
84198
84218
|
} }, drawLabels ? name : ""),
|
|
84199
84219
|
import_react37.default.createElement(
|
|
84200
84220
|
IconButton_default,
|
|
84201
|
-
{ className: classes2.button, style: {
|
|
84221
|
+
{ className: classes2.button, "aria-label": `${name} track menu`, style: {
|
|
84202
84222
|
width: trackLabelHeight,
|
|
84203
84223
|
height: trackLabelHeight,
|
|
84204
84224
|
flexShrink: 0
|
|
@@ -84215,7 +84235,7 @@ var init_Track = __esm({
|
|
|
84215
84235
|
import_react37.default.createElement(MenuItem_default, { dense: true, onClick: () => {
|
|
84216
84236
|
model2.toggleTrack(track.model.id);
|
|
84217
84237
|
closeMenu();
|
|
84218
|
-
} }, "
|
|
84238
|
+
} }, "Hide track"),
|
|
84219
84239
|
import_react37.default.createElement(MenuItem_default, { dense: true, onClick: () => {
|
|
84220
84240
|
model2.queueDialog((onClose) => [
|
|
84221
84241
|
TrackInfoDialog2,
|
|
@@ -84838,10 +84858,15 @@ var init_FeatureDialog = __esm({
|
|
|
84838
84858
|
);
|
|
84839
84859
|
});
|
|
84840
84860
|
FeatureTable = (0, import_mobx_react12.observer)(function({ model: model2 }) {
|
|
84841
|
-
const { annotationTypes, annotations, fillPalette } = model2;
|
|
84861
|
+
const { annotationTypes, annotations, featureColors, fillPalette } = model2;
|
|
84842
84862
|
const counts = /* @__PURE__ */ new Map();
|
|
84863
|
+
const swatches = /* @__PURE__ */ new Map();
|
|
84843
84864
|
for (const annot of annotations) {
|
|
84844
|
-
|
|
84865
|
+
const { accession } = annot;
|
|
84866
|
+
counts.set(accession, (counts.get(accession) ?? 0) + 1);
|
|
84867
|
+
if (!swatches.has(accession)) {
|
|
84868
|
+
swatches.set(accession, featureColors.get(annot)?.fill ?? fillPalette[accession]);
|
|
84869
|
+
}
|
|
84845
84870
|
}
|
|
84846
84871
|
return import_react40.default.createElement(
|
|
84847
84872
|
import_react40.default.Fragment,
|
|
@@ -84880,7 +84905,7 @@ var init_FeatureDialog = __esm({
|
|
|
84880
84905
|
import_react40.default.createElement("div", { style: {
|
|
84881
84906
|
width: 20,
|
|
84882
84907
|
height: 20,
|
|
84883
|
-
background:
|
|
84908
|
+
background: swatches.get(accession)
|
|
84884
84909
|
} })
|
|
84885
84910
|
),
|
|
84886
84911
|
import_react40.default.createElement(TableCell_default, null, accession),
|
|
@@ -85470,6 +85495,9 @@ function parseAll(text2, opts) {
|
|
|
85470
85495
|
for (const line2 of lines) {
|
|
85471
85496
|
let match2;
|
|
85472
85497
|
if (formatStartRegex.test(line2)) {
|
|
85498
|
+
if (stock) {
|
|
85499
|
+
db.push(stock);
|
|
85500
|
+
}
|
|
85473
85501
|
stock = createStockholm();
|
|
85474
85502
|
treeContinues = false;
|
|
85475
85503
|
} else if (formatEndRegex.test(line2)) {
|
|
@@ -86068,7 +86096,7 @@ var init_AnnotationFileDialog = __esm({
|
|
|
86068
86096
|
import_react41.default.createElement(
|
|
86069
86097
|
DialogActions_default,
|
|
86070
86098
|
null,
|
|
86071
|
-
import_react41.default.createElement(Button_default, { variant: "contained", color: "primary", disabled: loading, onClick: () => {
|
|
86099
|
+
import_react41.default.createElement(Button_default, { variant: "contained", color: "primary", disabled: loading || (choice === "file" ? !file : !url.trim()), onClick: () => {
|
|
86072
86100
|
;
|
|
86073
86101
|
(async () => {
|
|
86074
86102
|
setLoading(true);
|
|
@@ -86085,7 +86113,10 @@ var init_AnnotationFileDialog = __esm({
|
|
|
86085
86113
|
setLoading(false);
|
|
86086
86114
|
}
|
|
86087
86115
|
})();
|
|
86088
|
-
} }, "Open annotations")
|
|
86116
|
+
} }, "Open annotations"),
|
|
86117
|
+
import_react41.default.createElement(Button_default, { variant: "contained", color: "secondary", onClick: () => {
|
|
86118
|
+
handleClose();
|
|
86119
|
+
} }, "Cancel")
|
|
86089
86120
|
)
|
|
86090
86121
|
);
|
|
86091
86122
|
});
|
|
@@ -90835,13 +90866,13 @@ function measureScrollbarSize(element, scrollbarSize) {
|
|
|
90835
90866
|
if (cached !== void 0 && cached.devicePixelRatio === devicePixelRatio2 && cached.measuredDirectly) {
|
|
90836
90867
|
return cached.size;
|
|
90837
90868
|
}
|
|
90838
|
-
const
|
|
90839
|
-
const canScrollY =
|
|
90840
|
-
const canScrollX =
|
|
90869
|
+
const computed3 = view?.getComputedStyle(htmlElement);
|
|
90870
|
+
const canScrollY = computed3?.overflowY === "auto" || computed3?.overflowY === "scroll";
|
|
90871
|
+
const canScrollX = computed3?.overflowX === "auto" || computed3?.overflowX === "scroll";
|
|
90841
90872
|
const hasScrollY = canScrollY && htmlElement.scrollHeight > htmlElement.clientHeight;
|
|
90842
90873
|
const hasScrollX = canScrollX && htmlElement.scrollWidth > htmlElement.clientWidth;
|
|
90843
|
-
const borderWidth = parseCSSPixelValue(
|
|
90844
|
-
const borderHeight = parseCSSPixelValue(
|
|
90874
|
+
const borderWidth = parseCSSPixelValue(computed3?.borderLeftWidth) + parseCSSPixelValue(computed3?.borderRightWidth);
|
|
90875
|
+
const borderHeight = parseCSSPixelValue(computed3?.borderTopWidth) + parseCSSPixelValue(computed3?.borderBottomWidth);
|
|
90845
90876
|
const directSize = Math.max(hasScrollY ? htmlElement.offsetWidth - htmlElement.clientWidth - borderWidth : 0, hasScrollX ? htmlElement.offsetHeight - htmlElement.clientHeight - borderHeight : 0);
|
|
90846
90877
|
if (hasScrollY || hasScrollX) {
|
|
90847
90878
|
const size6 = Math.max(0, directSize);
|
|
@@ -90860,8 +90891,8 @@ function measureScrollbarSize(element, scrollbarSize) {
|
|
|
90860
90891
|
scrollDiv.style.height = "99px";
|
|
90861
90892
|
scrollDiv.style.position = "absolute";
|
|
90862
90893
|
scrollDiv.style.overflow = "scroll";
|
|
90863
|
-
if (
|
|
90864
|
-
scrollDiv.style.scrollbarWidth =
|
|
90894
|
+
if (computed3?.scrollbarWidth) {
|
|
90895
|
+
scrollDiv.style.scrollbarWidth = computed3.scrollbarWidth;
|
|
90865
90896
|
}
|
|
90866
90897
|
scrollDiv.className = "scrollDiv";
|
|
90867
90898
|
element.appendChild(scrollDiv);
|
|
@@ -121076,8 +121107,7 @@ var init_SequenceTextArea = __esm({
|
|
|
121076
121107
|
},
|
|
121077
121108
|
dialogContent: {
|
|
121078
121109
|
background: theme.palette.action.selected,
|
|
121079
|
-
margin: 4
|
|
121080
|
-
minWidth: "80em"
|
|
121110
|
+
margin: 4
|
|
121081
121111
|
}
|
|
121082
121112
|
}));
|
|
121083
121113
|
}
|
|
@@ -121223,7 +121253,7 @@ function ExportSVGDialog({ model: model2, onClose }) {
|
|
|
121223
121253
|
});
|
|
121224
121254
|
});
|
|
121225
121255
|
}
|
|
121226
|
-
}, exporting ? "Exporting\u2026" : "
|
|
121256
|
+
}, exporting ? "Exporting\u2026" : "Export"),
|
|
121227
121257
|
import_react53.default.createElement(Button_default, { variant: "contained", color: "secondary", onClick: () => {
|
|
121228
121258
|
onClose();
|
|
121229
121259
|
} }, "Cancel")
|
|
@@ -121444,44 +121474,25 @@ var init_Warning = __esm({
|
|
|
121444
121474
|
});
|
|
121445
121475
|
|
|
121446
121476
|
// ../lib/dist/components/header/LoadWarnings.js
|
|
121447
|
-
var import_react58, import_mobx_react19,
|
|
121477
|
+
var import_react58, import_mobx_react19, LoadWarnings, LoadWarnings_default;
|
|
121448
121478
|
var init_LoadWarnings = __esm({
|
|
121449
121479
|
"../lib/dist/components/header/LoadWarnings.js"() {
|
|
121450
121480
|
"use strict";
|
|
121451
121481
|
import_react58 = __toESM(require_react(), 1);
|
|
121452
|
-
init_tss_react();
|
|
121453
121482
|
init_Warning();
|
|
121454
121483
|
init_material();
|
|
121455
121484
|
import_mobx_react19 = __toESM(require_dist3(), 1);
|
|
121456
|
-
useStyles22 = makeStyles()((theme) => ({
|
|
121457
|
-
warning: {
|
|
121458
|
-
display: "flex",
|
|
121459
|
-
alignItems: "center",
|
|
121460
|
-
gap: 4,
|
|
121461
|
-
margin: "auto",
|
|
121462
|
-
marginLeft: 10,
|
|
121463
|
-
whiteSpace: "nowrap",
|
|
121464
|
-
color: theme.palette.warning.main,
|
|
121465
|
-
cursor: "pointer"
|
|
121466
|
-
}
|
|
121467
|
-
}));
|
|
121468
121485
|
LoadWarnings = (0, import_mobx_react19.observer)(function({ model: model2 }) {
|
|
121469
121486
|
const { warnings } = model2;
|
|
121470
|
-
const { classes: classes2 } = useStyles22();
|
|
121471
121487
|
if (warnings.length === 0) {
|
|
121472
121488
|
return null;
|
|
121473
121489
|
}
|
|
121474
121490
|
return import_react58.default.createElement(
|
|
121475
121491
|
Tooltip_default,
|
|
121476
121492
|
{ title: `${warnings.join(" ")} (click to dismiss)` },
|
|
121477
|
-
import_react58.default.createElement(
|
|
121478
|
-
|
|
121479
|
-
|
|
121480
|
-
model2.clearWarnings();
|
|
121481
|
-
} },
|
|
121482
|
-
import_react58.default.createElement(Warning_default, { fontSize: "small" }),
|
|
121483
|
-
warnings.length > 1 ? `${warnings.length} warnings` : "Warning"
|
|
121484
|
-
)
|
|
121493
|
+
import_react58.default.createElement(Button_default, { "aria-label": "Dismiss warnings", color: "warning", size: "small", startIcon: import_react58.default.createElement(Warning_default, { fontSize: "small" }), style: { margin: "auto", marginLeft: 10, whiteSpace: "nowrap" }, onClick: () => {
|
|
121494
|
+
model2.clearWarnings();
|
|
121495
|
+
} }, warnings.length > 1 ? `${warnings.length} warnings` : "Warning")
|
|
121485
121496
|
);
|
|
121486
121497
|
});
|
|
121487
121498
|
LoadWarnings_default = LoadWarnings;
|
|
@@ -121534,10 +121545,10 @@ function msaSettingsMenuItems(model2) {
|
|
|
121534
121545
|
model2.setDrawMsaLetters(arg2);
|
|
121535
121546
|
}),
|
|
121536
121547
|
// inverted: bgColor colors the tile, and off colors the letter
|
|
121537
|
-
toggle("Color letters
|
|
121548
|
+
toggle("Color letters, not cells", !bgColor, (arg2) => {
|
|
121538
121549
|
model2.setBgColor(!arg2);
|
|
121539
121550
|
}),
|
|
121540
|
-
toggle("
|
|
121551
|
+
toggle("Hide gappy columns", hideGaps, (arg2) => {
|
|
121541
121552
|
model2.setHideGaps(arg2);
|
|
121542
121553
|
})
|
|
121543
121554
|
];
|
|
@@ -121695,7 +121706,7 @@ var init_LinkOff = __esm({
|
|
|
121695
121706
|
function size4(bytes) {
|
|
121696
121707
|
return bytes < 1e6 ? `${Math.round(bytes / 1e3)} kB` : `${(bytes / 1e6).toFixed(1)} MB`;
|
|
121697
121708
|
}
|
|
121698
|
-
var import_react62, import_mobx_react23,
|
|
121709
|
+
var import_react62, import_mobx_react23, useStyles22, UnshareableDataWarning, UnshareableDataWarning_default;
|
|
121699
121710
|
var init_UnshareableDataWarning = __esm({
|
|
121700
121711
|
"../lib/dist/components/header/UnshareableDataWarning.js"() {
|
|
121701
121712
|
"use strict";
|
|
@@ -121704,7 +121715,7 @@ var init_UnshareableDataWarning = __esm({
|
|
|
121704
121715
|
init_LinkOff();
|
|
121705
121716
|
init_material();
|
|
121706
121717
|
import_mobx_react23 = __toESM(require_dist3(), 1);
|
|
121707
|
-
|
|
121718
|
+
useStyles22 = makeStyles()((theme) => ({
|
|
121708
121719
|
warning: {
|
|
121709
121720
|
display: "flex",
|
|
121710
121721
|
alignItems: "center",
|
|
@@ -121718,7 +121729,7 @@ var init_UnshareableDataWarning = __esm({
|
|
|
121718
121729
|
}));
|
|
121719
121730
|
UnshareableDataWarning = (0, import_mobx_react23.observer)(function({ model: model2 }) {
|
|
121720
121731
|
const { unshareableData } = model2;
|
|
121721
|
-
const { classes: classes2 } =
|
|
121732
|
+
const { classes: classes2 } = useStyles22();
|
|
121722
121733
|
if (unshareableData.length === 0) {
|
|
121723
121734
|
return null;
|
|
121724
121735
|
}
|
|
@@ -121948,7 +121959,7 @@ var version3;
|
|
|
121948
121959
|
var init_version3 = __esm({
|
|
121949
121960
|
"../lib/dist/version.js"() {
|
|
121950
121961
|
"use strict";
|
|
121951
|
-
version3 = "8.
|
|
121962
|
+
version3 = "8.1.0";
|
|
121952
121963
|
}
|
|
121953
121964
|
});
|
|
121954
121965
|
|
|
@@ -121972,7 +121983,7 @@ function AboutDialog({ onClose }) {
|
|
|
121972
121983
|
"MSAView ",
|
|
121973
121984
|
version3,
|
|
121974
121985
|
" (",
|
|
121975
|
-
import_react66.default.createElement(Link_default, { href: "https://github.com/gmod/react-msaview" }, "Github"),
|
|
121986
|
+
import_react66.default.createElement(Link_default, { target: "_blank", rel: "noopener", href: "https://github.com/gmod/react-msaview" }, "Github"),
|
|
121976
121987
|
")"
|
|
121977
121988
|
),
|
|
121978
121989
|
import_react66.default.createElement(
|
|
@@ -121986,11 +121997,11 @@ function AboutDialog({ onClose }) {
|
|
|
121986
121997
|
null,
|
|
121987
121998
|
"We use some color schemes from the",
|
|
121988
121999
|
" ",
|
|
121989
|
-
import_react66.default.createElement(Link_default, { href: "https://github.com/biotite-dev/biotite" }, "biotite"),
|
|
122000
|
+
import_react66.default.createElement(Link_default, { target: "_blank", rel: "noopener", href: "https://github.com/biotite-dev/biotite" }, "biotite"),
|
|
121990
122001
|
" ",
|
|
121991
122002
|
"project, and their license is reproduced",
|
|
121992
122003
|
" ",
|
|
121993
|
-
import_react66.default.createElement(Link_default, { href: "https://github.com/biotite-dev/biotite/blob/master/LICENSE.rst" }, "here")
|
|
122004
|
+
import_react66.default.createElement(Link_default, { target: "_blank", rel: "noopener", href: "https://github.com/biotite-dev/biotite/blob/master/LICENSE.rst" }, "here")
|
|
121994
122005
|
)
|
|
121995
122006
|
),
|
|
121996
122007
|
import_react66.default.createElement(
|
|
@@ -122001,7 +122012,7 @@ function AboutDialog({ onClose }) {
|
|
|
122001
122012
|
null,
|
|
122002
122013
|
"See this page for some information on jalview colorings",
|
|
122003
122014
|
" ",
|
|
122004
|
-
import_react66.default.createElement(Link_default, { href: "https://www.jalview.org/help/html/colourSchemes/" }, "here")
|
|
122015
|
+
import_react66.default.createElement(Link_default, { target: "_blank", rel: "noopener", href: "https://www.jalview.org/help/html/colourSchemes/" }, "here")
|
|
122005
122016
|
)
|
|
122006
122017
|
),
|
|
122007
122018
|
import_react66.default.createElement(
|
|
@@ -122012,7 +122023,7 @@ function AboutDialog({ onClose }) {
|
|
|
122012
122023
|
null,
|
|
122013
122024
|
"See this page for some info on the clustal, cinema, maeditor, and lesk color schemes",
|
|
122014
122025
|
" ",
|
|
122015
|
-
import_react66.default.createElement(Link_default, { href: "http://www.bioinformatics.nl/~berndb/aacolour.html" }, "here")
|
|
122026
|
+
import_react66.default.createElement(Link_default, { target: "_blank", rel: "noopener", href: "http://www.bioinformatics.nl/~berndb/aacolour.html" }, "here")
|
|
122016
122027
|
)
|
|
122017
122028
|
),
|
|
122018
122029
|
import_react66.default.createElement(
|
|
@@ -122023,7 +122034,7 @@ function AboutDialog({ onClose }) {
|
|
|
122023
122034
|
null,
|
|
122024
122035
|
"See this paper about the flower color scheme",
|
|
122025
122036
|
" ",
|
|
122026
|
-
import_react66.default.createElement(Link_default, { href: "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7245768/" }, "here")
|
|
122037
|
+
import_react66.default.createElement(Link_default, { target: "_blank", rel: "noopener", href: "https://www.ncbi.nlm.nih.gov/pmc/articles/PMC7245768/" }, "here")
|
|
122027
122038
|
)
|
|
122028
122039
|
)
|
|
122029
122040
|
)
|
|
@@ -122077,7 +122088,7 @@ var init_Header = __esm({
|
|
|
122077
122088
|
}, [model2]);
|
|
122078
122089
|
return import_react67.default.createElement(
|
|
122079
122090
|
"div",
|
|
122080
|
-
{ ref, style: { display: "flex" } },
|
|
122091
|
+
{ ref, style: { display: "flex", flexWrap: "wrap" } },
|
|
122081
122092
|
import_react67.default.createElement(FileMenu_default, { model: model2 }),
|
|
122082
122093
|
import_react67.default.createElement(ColorSchemeMenu_default, { model: model2 }),
|
|
122083
122094
|
import_react67.default.createElement(TreeSettingsMenu_default, { model: model2 }),
|
|
@@ -122479,9 +122490,7 @@ var init_MSACanvas = __esm({
|
|
|
122479
122490
|
onZoom,
|
|
122480
122491
|
scrollZoom
|
|
122481
122492
|
});
|
|
122482
|
-
return import_react74.default.createElement("div", { ref, "data-testid": "msa_canvas", onMouseDown, onMouseUp,
|
|
122483
|
-
event.preventDefault();
|
|
122484
|
-
}, style: {
|
|
122493
|
+
return import_react74.default.createElement("div", { ref, "data-testid": "msa_canvas", onMouseDown, onMouseUp, style: {
|
|
122485
122494
|
position: "relative",
|
|
122486
122495
|
height: height2,
|
|
122487
122496
|
width: msaCanvasWidth,
|
|
@@ -122664,17 +122673,17 @@ var init_featureFields = __esm({
|
|
|
122664
122673
|
|
|
122665
122674
|
// ../lib/dist/components/PortalTooltip.js
|
|
122666
122675
|
function PortalTooltip({ clientX, clientY, children }) {
|
|
122667
|
-
const { classes: classes2 } =
|
|
122676
|
+
const { classes: classes2 } = useStyles23();
|
|
122668
122677
|
return (0, import_react_dom4.createPortal)(import_react78.default.createElement("div", { className: classes2.tooltip, style: { left: clientX + 12, top: clientY + 12 } }, children), document.body);
|
|
122669
122678
|
}
|
|
122670
|
-
var import_react78, import_react_dom4,
|
|
122679
|
+
var import_react78, import_react_dom4, useStyles23;
|
|
122671
122680
|
var init_PortalTooltip = __esm({
|
|
122672
122681
|
"../lib/dist/components/PortalTooltip.js"() {
|
|
122673
122682
|
"use strict";
|
|
122674
122683
|
import_react78 = __toESM(require_react(), 1);
|
|
122675
122684
|
init_tss_react();
|
|
122676
122685
|
import_react_dom4 = __toESM(require_react_dom(), 1);
|
|
122677
|
-
|
|
122686
|
+
useStyles23 = makeStyles()((theme) => ({
|
|
122678
122687
|
tooltip: {
|
|
122679
122688
|
position: "fixed",
|
|
122680
122689
|
pointerEvents: "none",
|
|
@@ -122954,7 +122963,7 @@ var init_TreeBranchMenu = __esm({
|
|
|
122954
122963
|
{ anchorReference: "anchorPosition", anchorPosition: {
|
|
122955
122964
|
left: node2.x,
|
|
122956
122965
|
top: node2.y
|
|
122957
|
-
}, transitionDuration: 0,
|
|
122966
|
+
}, transitionDuration: 0, open: true, onClose },
|
|
122958
122967
|
import_react83.default.createElement(MenuItem_default, { dense: true, disabled: true }, node2.name),
|
|
122959
122968
|
import_react83.default.createElement(MenuItem_default, { dense: true, onClick: () => {
|
|
122960
122969
|
model2.toggleCollapsed(node2.id);
|
|
@@ -123038,7 +123047,7 @@ var init_TreeNodeMenu = __esm({
|
|
|
123038
123047
|
{ anchorReference: "anchorPosition", anchorPosition: {
|
|
123039
123048
|
top: node2.y,
|
|
123040
123049
|
left: node2.x
|
|
123041
|
-
}, transitionDuration: 0,
|
|
123050
|
+
}, transitionDuration: 0, open: true, onClose },
|
|
123042
123051
|
import_react85.default.createElement(MenuItem_default, { dense: true, disabled: true }, name),
|
|
123043
123052
|
import_react85.default.createElement(MenuItem_default, { dense: true, onClick: () => {
|
|
123044
123053
|
model2.queueDialog((onClose2) => [
|
|
@@ -123657,7 +123666,7 @@ var init_useTreeHover = __esm({
|
|
|
123657
123666
|
});
|
|
123658
123667
|
|
|
123659
123668
|
// ../lib/dist/components/tree/TreeCanvasBlock.js
|
|
123660
|
-
var import_react87, import_mobx_react41,
|
|
123669
|
+
var import_react87, import_mobx_react41, useStyles24, TreeCanvasBlock, TreeCanvasBlock_default;
|
|
123661
123670
|
var init_TreeCanvasBlock = __esm({
|
|
123662
123671
|
"../lib/dist/components/tree/TreeCanvasBlock.js"() {
|
|
123663
123672
|
"use strict";
|
|
@@ -123671,16 +123680,16 @@ var init_TreeCanvasBlock = __esm({
|
|
|
123671
123680
|
init_TreeNodeMenu();
|
|
123672
123681
|
init_renderTreeCanvas();
|
|
123673
123682
|
init_useTreeHover();
|
|
123674
|
-
|
|
123683
|
+
useStyles24 = makeStyles()((theme) => ({
|
|
123675
123684
|
hover: {
|
|
123676
123685
|
position: "absolute",
|
|
123677
123686
|
pointerEvents: "none",
|
|
123678
123687
|
zIndex: 100,
|
|
123679
|
-
background:
|
|
123688
|
+
background: theme.palette.action.hover
|
|
123680
123689
|
}
|
|
123681
123690
|
}));
|
|
123682
123691
|
TreeCanvasBlock = (0, import_mobx_react41.observer)(function({ model: model2, offsetY }) {
|
|
123683
|
-
const { classes: classes2 } =
|
|
123692
|
+
const { classes: classes2 } = useStyles24();
|
|
123684
123693
|
const theme = useTheme4();
|
|
123685
123694
|
const [branchMenu, setBranchMenu] = (0, import_react87.useState)();
|
|
123686
123695
|
const [nodeMenu, setNodeMenu] = (0, import_react87.useState)();
|
|
@@ -123803,9 +123812,7 @@ var init_TreeCanvas = __esm({
|
|
|
123803
123812
|
});
|
|
123804
123813
|
return import_react88.default.createElement(
|
|
123805
123814
|
"div",
|
|
123806
|
-
{ ref, onMouseDown, onMouseUp,
|
|
123807
|
-
event.preventDefault();
|
|
123808
|
-
}, style: {
|
|
123815
|
+
{ ref, onMouseDown, onMouseUp, style: {
|
|
123809
123816
|
height: height2,
|
|
123810
123817
|
position: "relative",
|
|
123811
123818
|
width: treeAreaWidth
|
|
@@ -124162,7 +124169,7 @@ var init_ImportForm = __esm({
|
|
|
124162
124169
|
{ style: { width: "50%" } },
|
|
124163
124170
|
error ? import_react93.default.createElement(ErrorMessage, { error }) : null,
|
|
124164
124171
|
import_react93.default.createElement(Typography_default, null, "Open an MSA file (FASTA, Stockholm, Clustal, A3M or EMF format) and/or a tree file (Newick format)."),
|
|
124165
|
-
import_react93.default.createElement(Typography_default, { color: "
|
|
124172
|
+
import_react93.default.createElement(Typography_default, { color: "text.secondary" }, "An MSA alone or a tree alone is enough, and a Stockholm file with an embedded tree needs no separate tree file.")
|
|
124166
124173
|
),
|
|
124167
124174
|
import_react93.default.createElement(
|
|
124168
124175
|
"div",
|
|
@@ -124236,16 +124243,7 @@ var init_Loading2 = __esm({
|
|
|
124236
124243
|
return import_react94.default.createElement(
|
|
124237
124244
|
"div",
|
|
124238
124245
|
{ style: { display: "flex", alignItems: "center", gap: 12, padding: 20 } },
|
|
124239
|
-
import_react94.default.createElement(
|
|
124240
|
-
"svg",
|
|
124241
|
-
{ width: "24", height: "24", viewBox: "0 0 24 24", xmlns: "http://www.w3.org/2000/svg" },
|
|
124242
|
-
import_react94.default.createElement("style", null, `@keyframes spinner { to { transform: rotate(360deg); } }`),
|
|
124243
|
-
import_react94.default.createElement("circle", { cx: "12", cy: "12", r: "10", stroke: "#ccc", strokeWidth: "3", fill: "none" }),
|
|
124244
|
-
import_react94.default.createElement("path", { d: "M12 2a10 10 0 0 1 10 10", stroke: "#1976d2", strokeWidth: "3", fill: "none", strokeLinecap: "round", style: {
|
|
124245
|
-
animation: "spinner 1s linear infinite",
|
|
124246
|
-
transformOrigin: "center"
|
|
124247
|
-
} })
|
|
124248
|
-
),
|
|
124246
|
+
import_react94.default.createElement(CircularProgress_default, { size: 24 }),
|
|
124249
124247
|
import_react94.default.createElement(Typography_default, { variant: "h6" }, status?.msg ?? "Loading..."),
|
|
124250
124248
|
status?.onCancel ? import_react94.default.createElement(Button_default, { variant: "outlined", size: "small", onClick: () => status.onCancel?.() }, "Cancel") : null
|
|
124251
124249
|
);
|
|
@@ -124272,8 +124270,9 @@ var init_Loading2 = __esm({
|
|
|
124272
124270
|
// ../lib/dist/calculateBlocks.js
|
|
124273
124271
|
function calculateBlocks({ mapSize, blockSize, viewportPos, viewportSize }) {
|
|
124274
124272
|
const clamped = Math.max(0, Math.min(viewportPos, mapSize - viewportSize));
|
|
124273
|
+
const end = Math.min(clamped + viewportSize, mapSize);
|
|
124275
124274
|
const minTile = Math.floor(clamped / blockSize);
|
|
124276
|
-
const maxTile = Math.
|
|
124275
|
+
const maxTile = Math.ceil(end / blockSize) - 1;
|
|
124277
124276
|
const blocks = [];
|
|
124278
124277
|
for (let tile = minTile; tile <= maxTile; tile++) {
|
|
124279
124278
|
blocks.push(tile * blockSize);
|
|
@@ -125675,9 +125674,30 @@ function featureLabelMap(annotations, field) {
|
|
|
125675
125674
|
}
|
|
125676
125675
|
return labels;
|
|
125677
125676
|
}
|
|
125678
|
-
function
|
|
125677
|
+
function strandpileLanes(rows) {
|
|
125678
|
+
const piled = rows.map(([name, bands]) => {
|
|
125679
|
+
const reverse = packDomainLanes(bands.filter((b2) => b2.annotation.strand === -1));
|
|
125680
|
+
const forward = packDomainLanes(bands.filter((b2) => b2.annotation.strand !== -1));
|
|
125681
|
+
return { name, forward, reverse };
|
|
125682
|
+
});
|
|
125683
|
+
const up = Math.max(0, ...piled.map((p2) => p2.forward[0]?.laneCount ?? 0));
|
|
125684
|
+
const down = Math.max(0, ...piled.map((p2) => p2.reverse[0]?.laneCount ?? 0));
|
|
125685
|
+
const laneCount = up + down;
|
|
125686
|
+
return new Map(piled.map(({ name, forward, reverse }) => [
|
|
125687
|
+
name,
|
|
125688
|
+
[
|
|
125689
|
+
// forward level 0 is the lane just above the line, stacking upward
|
|
125690
|
+
...forward.map((b2) => ({ ...b2, lane: up - 1 - b2.lane, laneCount })),
|
|
125691
|
+
...reverse.map((b2) => ({ ...b2, lane: up + b2.lane, laneCount }))
|
|
125692
|
+
]
|
|
125693
|
+
]));
|
|
125694
|
+
}
|
|
125695
|
+
function panelLanes(panel, rows) {
|
|
125696
|
+
return panel.position === "strandpile" ? strandpileLanes(rows) : new Map(rows.map(([name, bands]) => [name, packDomainLanes(bands)]));
|
|
125697
|
+
}
|
|
125698
|
+
function featurePanelSpans({ panel, width: width3, colWidth, domainBands, annotationsByRow, shifts }) {
|
|
125679
125699
|
if (panel.x === "column") {
|
|
125680
|
-
return
|
|
125700
|
+
return panelLanes(panel, [...domainBands].map(([name, bands]) => [
|
|
125681
125701
|
name,
|
|
125682
125702
|
bands.map((band) => ({
|
|
125683
125703
|
...band,
|
|
@@ -125705,17 +125725,17 @@ function featurePanelSpans({ panel, width: width3, rowHeight, colWidth, domainBa
|
|
|
125705
125725
|
max3 = Math.max(max3, end);
|
|
125706
125726
|
}
|
|
125707
125727
|
}
|
|
125708
|
-
const drawable = Math.max(1, width3 -
|
|
125728
|
+
const drawable = Math.max(1, width3 - 1);
|
|
125709
125729
|
const scale = max3 > min3 ? drawable / (max3 - min3) : 0;
|
|
125710
|
-
return
|
|
125730
|
+
return panelLanes(panel, shifted.map(([name, features]) => [
|
|
125711
125731
|
name,
|
|
125712
|
-
|
|
125732
|
+
features.map(({ annotation, start, end }) => ({
|
|
125713
125733
|
annotation,
|
|
125714
125734
|
xStart: (start - min3) * scale,
|
|
125715
125735
|
xEnd: (end - min3) * scale,
|
|
125716
125736
|
startCol: start,
|
|
125717
125737
|
endCol: end - (end - start) * laneOverlap
|
|
125718
|
-
}))
|
|
125738
|
+
}))
|
|
125719
125739
|
]));
|
|
125720
125740
|
}
|
|
125721
125741
|
function resolveFeatureScale(field, scale, annotations) {
|
|
@@ -125975,11 +125995,7 @@ function stateModelFactory() {
|
|
|
125975
125995
|
* data from the loaded tree/msa/treeMetadata, generally loaded by
|
|
125976
125996
|
* autorun
|
|
125977
125997
|
*/
|
|
125978
|
-
data: types.optional(DataModelF(), {
|
|
125979
|
-
tree: "",
|
|
125980
|
-
msa: "",
|
|
125981
|
-
treeMetadata: ""
|
|
125982
|
-
}),
|
|
125998
|
+
data: types.optional(DataModelF(), {}),
|
|
125983
125999
|
/**
|
|
125984
126000
|
* #property
|
|
125985
126001
|
* the user's explicit hide choices per annotation accession, keyed by
|
|
@@ -126216,10 +126232,12 @@ function stateModelFactory() {
|
|
|
126216
126232
|
/**
|
|
126217
126233
|
* #action
|
|
126218
126234
|
* record a non-fatal load problem: a layer that failed to load, a file
|
|
126219
|
-
* that failed to parse
|
|
126235
|
+
* that failed to parse. A message already on the list is not added again
|
|
126220
126236
|
*/
|
|
126221
126237
|
addWarning(warning) {
|
|
126222
|
-
self.warnings
|
|
126238
|
+
if (!self.warnings.includes(warning)) {
|
|
126239
|
+
self.warnings = [...self.warnings, warning];
|
|
126240
|
+
}
|
|
126223
126241
|
},
|
|
126224
126242
|
/**
|
|
126225
126243
|
* #action
|
|
@@ -126827,7 +126845,7 @@ function stateModelFactory() {
|
|
|
126827
126845
|
*/
|
|
126828
126846
|
get insertionPositions() {
|
|
126829
126847
|
const { blanks, rows } = this;
|
|
126830
|
-
if (blanks.length === 0
|
|
126848
|
+
if (blanks.length === 0) {
|
|
126831
126849
|
return /* @__PURE__ */ new Map();
|
|
126832
126850
|
}
|
|
126833
126851
|
const result = /* @__PURE__ */ new Map();
|
|
@@ -127048,7 +127066,7 @@ function stateModelFactory() {
|
|
|
127048
127066
|
* cladogram mode. The tree's scale bar uses it.
|
|
127049
127067
|
*/
|
|
127050
127068
|
get pxPerBranchLength() {
|
|
127051
|
-
const max3 =
|
|
127069
|
+
const max3 = this.rootToTipLength;
|
|
127052
127070
|
return this.showBranchLenEffective && max3 ? self.treeWidth / max3 : 0;
|
|
127053
127071
|
},
|
|
127054
127072
|
/**
|
|
@@ -127091,7 +127109,107 @@ function stateModelFactory() {
|
|
|
127091
127109
|
get showTreeText() {
|
|
127092
127110
|
return self.drawLabels && self.rowHeight >= minLetterRowHeight;
|
|
127093
127111
|
}
|
|
127094
|
-
})).views((self) =>
|
|
127112
|
+
})).views((self) => {
|
|
127113
|
+
const columnTrackModels = /* @__PURE__ */ new WeakMap();
|
|
127114
|
+
return {
|
|
127115
|
+
/**
|
|
127116
|
+
* #getter
|
|
127117
|
+
* a data track's values or string, projected from its row's residues
|
|
127118
|
+
* onto alignment columns when it names a row
|
|
127119
|
+
*/
|
|
127120
|
+
get columnTrackContent() {
|
|
127121
|
+
const { MSA, blanks, hideGapsEffective } = self;
|
|
127122
|
+
const width3 = MSA?.getWidth() ?? 0;
|
|
127123
|
+
const project = (track, items, fill) => {
|
|
127124
|
+
if (!track.row) {
|
|
127125
|
+
return items;
|
|
127126
|
+
}
|
|
127127
|
+
const out = Array.from({ length: width3 }, () => fill);
|
|
127128
|
+
const index3 = self.seqPosIndex(track.row);
|
|
127129
|
+
items.forEach((item, seqPos) => {
|
|
127130
|
+
const col = index3?.[seqPos];
|
|
127131
|
+
if (col !== void 0) {
|
|
127132
|
+
out[col] = item;
|
|
127133
|
+
}
|
|
127134
|
+
});
|
|
127135
|
+
return out;
|
|
127136
|
+
};
|
|
127137
|
+
const skip2 = (items) => hideGapsEffective ? dropBlanks(blanks, items) : items;
|
|
127138
|
+
const resolve = (track, pos) => {
|
|
127139
|
+
const col = track.row ? self.seqPosIndex(track.row)?.[pos - 1] : pos - 1;
|
|
127140
|
+
if (col === void 0 || col < 0 || col >= width3) {
|
|
127141
|
+
return void 0;
|
|
127142
|
+
}
|
|
127143
|
+
return hideGapsEffective ? visibleColsBefore(blanks, col) : col;
|
|
127144
|
+
};
|
|
127145
|
+
return new Map(self.columnTracks.map((track) => {
|
|
127146
|
+
if (track.kind === "arc") {
|
|
127147
|
+
const arcs = (track.arcs ?? []).map((arc) => {
|
|
127148
|
+
const start = resolve(track, Math.min(arc.start, arc.end));
|
|
127149
|
+
const end = resolve(track, Math.max(arc.start, arc.end));
|
|
127150
|
+
return start !== void 0 && end !== void 0 && start < end ? { start, end, color: arc.color } : void 0;
|
|
127151
|
+
}).filter(notEmpty);
|
|
127152
|
+
return [track.id, { arcs }];
|
|
127153
|
+
}
|
|
127154
|
+
if (track.kind === "bar") {
|
|
127155
|
+
const max3 = track.max ?? 1;
|
|
127156
|
+
const values4 = skip2(project(track, track.values ?? [], 0)).map((v2) => Math.min(1, Math.max(0, v2 / max3)));
|
|
127157
|
+
return [track.id, { values: values4 }];
|
|
127158
|
+
}
|
|
127159
|
+
const data = skip2(project(track, (track.data ?? "").split(""), " "));
|
|
127160
|
+
return [track.id, { data: data.join("") }];
|
|
127161
|
+
}));
|
|
127162
|
+
},
|
|
127163
|
+
/**
|
|
127164
|
+
* #method
|
|
127165
|
+
* the height a track draws at: what the user dragged its divider to,
|
|
127166
|
+
* then the height its snapshot asked for, then its kind's default. Only
|
|
127167
|
+
* a text track falls through to rowHeight
|
|
127168
|
+
*/
|
|
127169
|
+
trackHeight(kind, heightKey = kind, given) {
|
|
127170
|
+
return self.trackHeights.get(heightKey) ?? given ?? defaultTrackHeights[kind] ?? self.rowHeight;
|
|
127171
|
+
},
|
|
127172
|
+
/**
|
|
127173
|
+
* #method
|
|
127174
|
+
* the track a column track spec draws as, computed once per spec. A
|
|
127175
|
+
* text track's height falls through to rowHeight, and its own computed
|
|
127176
|
+
* confines the vertical zoom to it, so a sibling keeps its object and
|
|
127177
|
+
* its canvas skips the redraw
|
|
127178
|
+
*/
|
|
127179
|
+
columnTrackModel(track) {
|
|
127180
|
+
let computedModel = columnTrackModels.get(track);
|
|
127181
|
+
if (!computedModel) {
|
|
127182
|
+
computedModel = (0, import_mobx5.computed)(() => {
|
|
127183
|
+
const heightKey = resizableKinds.has(track.kind) ? ownHeightKey(track.id) : void 0;
|
|
127184
|
+
const content = this.columnTrackContent.get(track.id);
|
|
127185
|
+
return {
|
|
127186
|
+
model: {
|
|
127187
|
+
id: track.id,
|
|
127188
|
+
name: track.name,
|
|
127189
|
+
kind: track.kind,
|
|
127190
|
+
heightKey,
|
|
127191
|
+
height: this.trackHeight(track.kind, heightKey, track.height),
|
|
127192
|
+
barColor: track.color,
|
|
127193
|
+
arcColor: track.color,
|
|
127194
|
+
customColorScheme: track.colors,
|
|
127195
|
+
data: content?.data,
|
|
127196
|
+
arcs: content?.arcs
|
|
127197
|
+
},
|
|
127198
|
+
ReactComponent: TrackBlocks_default
|
|
127199
|
+
};
|
|
127200
|
+
});
|
|
127201
|
+
columnTrackModels.set(track, computedModel);
|
|
127202
|
+
}
|
|
127203
|
+
return computedModel.get();
|
|
127204
|
+
},
|
|
127205
|
+
/**
|
|
127206
|
+
* #getter
|
|
127207
|
+
*/
|
|
127208
|
+
get columnTrackModels() {
|
|
127209
|
+
return self.columnTracks.map((track) => this.columnTrackModel(track));
|
|
127210
|
+
}
|
|
127211
|
+
};
|
|
127212
|
+
}).views((self) => ({
|
|
127095
127213
|
/**
|
|
127096
127214
|
* #getter
|
|
127097
127215
|
*/
|
|
@@ -127172,87 +127290,6 @@ function stateModelFactory() {
|
|
|
127172
127290
|
ReactComponent: TrackBlocks_default
|
|
127173
127291
|
}));
|
|
127174
127292
|
},
|
|
127175
|
-
/**
|
|
127176
|
-
* #getter
|
|
127177
|
-
* a data track's values or string, projected from its row's residues
|
|
127178
|
-
* onto alignment columns when it names a row
|
|
127179
|
-
*/
|
|
127180
|
-
get columnTrackContent() {
|
|
127181
|
-
const { MSA, blanks, hideGapsEffective } = self;
|
|
127182
|
-
const width3 = MSA?.getWidth() ?? 0;
|
|
127183
|
-
const project = (track, items, fill) => {
|
|
127184
|
-
if (!track.row) {
|
|
127185
|
-
return items;
|
|
127186
|
-
}
|
|
127187
|
-
const out = Array.from({ length: width3 }, () => fill);
|
|
127188
|
-
const index3 = self.seqPosIndex(track.row);
|
|
127189
|
-
items.forEach((item, seqPos) => {
|
|
127190
|
-
const col = index3?.[seqPos];
|
|
127191
|
-
if (col !== void 0) {
|
|
127192
|
-
out[col] = item;
|
|
127193
|
-
}
|
|
127194
|
-
});
|
|
127195
|
-
return out;
|
|
127196
|
-
};
|
|
127197
|
-
const skip2 = (items) => hideGapsEffective ? dropBlanks(blanks, items) : items;
|
|
127198
|
-
const resolve = (track, pos) => {
|
|
127199
|
-
const col = track.row ? self.seqPosIndex(track.row)?.[pos - 1] : pos - 1;
|
|
127200
|
-
if (col === void 0 || col < 0 || col >= width3) {
|
|
127201
|
-
return void 0;
|
|
127202
|
-
}
|
|
127203
|
-
return hideGapsEffective ? visibleColsBefore(blanks, col) : col;
|
|
127204
|
-
};
|
|
127205
|
-
return new Map(self.columnTracks.map((track) => {
|
|
127206
|
-
if (track.kind === "arc") {
|
|
127207
|
-
const arcs = (track.arcs ?? []).map((arc) => {
|
|
127208
|
-
const start = resolve(track, Math.min(arc.start, arc.end));
|
|
127209
|
-
const end = resolve(track, Math.max(arc.start, arc.end));
|
|
127210
|
-
return start !== void 0 && end !== void 0 && start < end ? { start, end, color: arc.color } : void 0;
|
|
127211
|
-
}).filter(notEmpty);
|
|
127212
|
-
return [track.id, { arcs }];
|
|
127213
|
-
}
|
|
127214
|
-
if (track.kind === "bar") {
|
|
127215
|
-
const max3 = track.max ?? 1;
|
|
127216
|
-
const values4 = skip2(project(track, track.values ?? [], 0)).map((v2) => Math.min(1, Math.max(0, v2 / max3)));
|
|
127217
|
-
return [track.id, { values: values4 }];
|
|
127218
|
-
}
|
|
127219
|
-
const data = skip2(project(track, (track.data ?? "").split(""), " "));
|
|
127220
|
-
return [track.id, { data: data.join("") }];
|
|
127221
|
-
}));
|
|
127222
|
-
},
|
|
127223
|
-
/**
|
|
127224
|
-
* #method
|
|
127225
|
-
* the height a track draws at: what the user dragged its divider to,
|
|
127226
|
-
* then the height its snapshot asked for, then its kind's default. Only
|
|
127227
|
-
* a text track falls through to rowHeight, and `??` short-circuits
|
|
127228
|
-
* before reading it, so vertical zoom does not rebuild the other tracks
|
|
127229
|
-
*/
|
|
127230
|
-
trackHeight(kind, heightKey = kind, given) {
|
|
127231
|
-
return self.trackHeights.get(heightKey) ?? given ?? defaultTrackHeights[kind] ?? self.rowHeight;
|
|
127232
|
-
},
|
|
127233
|
-
/**
|
|
127234
|
-
* #getter
|
|
127235
|
-
*/
|
|
127236
|
-
get columnTrackModels() {
|
|
127237
|
-
return self.columnTracks.map((track) => {
|
|
127238
|
-
const heightKey = resizableKinds.has(track.kind) ? ownHeightKey(track.id) : void 0;
|
|
127239
|
-
return {
|
|
127240
|
-
model: {
|
|
127241
|
-
id: track.id,
|
|
127242
|
-
name: track.name,
|
|
127243
|
-
kind: track.kind,
|
|
127244
|
-
heightKey,
|
|
127245
|
-
height: this.trackHeight(track.kind, heightKey, track.height),
|
|
127246
|
-
barColor: track.color,
|
|
127247
|
-
arcColor: track.color,
|
|
127248
|
-
customColorScheme: track.colors,
|
|
127249
|
-
data: this.columnTrackContent.get(track.id)?.data,
|
|
127250
|
-
arcs: this.columnTrackContent.get(track.id)?.arcs
|
|
127251
|
-
},
|
|
127252
|
-
ReactComponent: TrackBlocks_default
|
|
127253
|
-
};
|
|
127254
|
-
});
|
|
127255
|
-
},
|
|
127256
127293
|
/**
|
|
127257
127294
|
* #getter
|
|
127258
127295
|
* the consensus secondary structure as a track, when there is one. A
|
|
@@ -127268,7 +127305,7 @@ function stateModelFactory() {
|
|
|
127268
127305
|
name: "Base pairs",
|
|
127269
127306
|
kind: "arc",
|
|
127270
127307
|
heightKey: "arc",
|
|
127271
|
-
height:
|
|
127308
|
+
height: self.trackHeight("arc"),
|
|
127272
127309
|
arcs
|
|
127273
127310
|
},
|
|
127274
127311
|
ReactComponent: TrackBlocks_default
|
|
@@ -127313,7 +127350,7 @@ function stateModelFactory() {
|
|
|
127313
127350
|
model: {
|
|
127314
127351
|
...model2,
|
|
127315
127352
|
heightKey: resizableKinds.has(model2.kind) ? model2.kind : void 0,
|
|
127316
|
-
height:
|
|
127353
|
+
height: self.trackHeight(model2.kind)
|
|
127317
127354
|
},
|
|
127318
127355
|
ReactComponent: TrackBlocks_default
|
|
127319
127356
|
}));
|
|
@@ -127322,7 +127359,7 @@ function stateModelFactory() {
|
|
|
127322
127359
|
return [
|
|
127323
127360
|
...this.adapterTrackModels,
|
|
127324
127361
|
...this.basePairTrackModels,
|
|
127325
|
-
...
|
|
127362
|
+
...self.columnTrackModels,
|
|
127326
127363
|
// every computed track reads the alignment's columns, and a tree, a
|
|
127327
127364
|
// GFF and a features panel draw a figure with none
|
|
127328
127365
|
...self.numColumns > 0 ? this.computedTrackModels : []
|
|
@@ -128063,12 +128100,6 @@ function stateModelFactory() {
|
|
|
128063
128100
|
const categorical = createPaletteMap(this.categoricalDomainTypes.map((d3) => d3.accession));
|
|
128064
128101
|
return { ...segments, ...categorical };
|
|
128065
128102
|
},
|
|
128066
|
-
get strokePalette() {
|
|
128067
|
-
return transform(this.fillPalette, ([key, val]) => [
|
|
128068
|
-
key,
|
|
128069
|
-
outlineColor2(val)
|
|
128070
|
-
]);
|
|
128071
|
-
},
|
|
128072
128103
|
/**
|
|
128073
128104
|
* #getter
|
|
128074
128105
|
* the encoding coloring the overlay's spans, undefined when none does,
|
|
@@ -128310,20 +128341,6 @@ function stateModelFactory() {
|
|
|
128310
128341
|
propertyConservation
|
|
128311
128342
|
});
|
|
128312
128343
|
},
|
|
128313
|
-
/**
|
|
128314
|
-
* #getter
|
|
128315
|
-
* `columnStatsAt` for the hovered column, undefined when nothing is
|
|
128316
|
-
* hovered
|
|
128317
|
-
*/
|
|
128318
|
-
get mouseOverColumnStats() {
|
|
128319
|
-
const { mouseCol, colStats, conservation, propertyConservation } = self;
|
|
128320
|
-
return mouseCol === void 0 ? void 0 : columnStats({
|
|
128321
|
-
col: mouseCol,
|
|
128322
|
-
colStats,
|
|
128323
|
-
conservation,
|
|
128324
|
-
propertyConservation
|
|
128325
|
-
});
|
|
128326
|
-
},
|
|
128327
128344
|
/**
|
|
128328
128345
|
* #method
|
|
128329
128346
|
*/
|
|
@@ -128379,7 +128396,6 @@ function stateModelFactory() {
|
|
|
128379
128396
|
spans: featurePanelSpans({
|
|
128380
128397
|
panel,
|
|
128381
128398
|
width: width3,
|
|
128382
|
-
rowHeight: self.rowHeight,
|
|
128383
128399
|
colWidth: self.colWidth,
|
|
128384
128400
|
domainBands: this.domainBands,
|
|
128385
128401
|
annotationsByRow: self.annotationsByRow,
|
|
@@ -128625,7 +128641,7 @@ function stateModelFactory() {
|
|
|
128625
128641
|
}
|
|
128626
128642
|
let cladesSeeded = false;
|
|
128627
128643
|
addDisposer(self, (0, import_mobx5.autorun)(() => {
|
|
128628
|
-
if (cladesSeeded || !self.dataInitialized || self.clades.length === 0) {
|
|
128644
|
+
if (cladesSeeded || !self.dataInitialized || self.treeFilehandle && !self.data.tree || self.clades.length === 0) {
|
|
128629
128645
|
return;
|
|
128630
128646
|
}
|
|
128631
128647
|
cladesSeeded = true;
|
|
@@ -128751,6 +128767,12 @@ function stateModelFactory() {
|
|
|
128751
128767
|
self.setAnnotations([]);
|
|
128752
128768
|
}
|
|
128753
128769
|
}));
|
|
128770
|
+
addDisposer(self, (0, import_mobx5.autorun)(() => {
|
|
128771
|
+
const { annotations, rowNamesSet } = self;
|
|
128772
|
+
if (annotations.length > 0 && rowNamesSet.size > 0 && !annotations.some((a3) => rowNamesSet.has(a3.id))) {
|
|
128773
|
+
self.addWarning(`0 of ${annotations.length} annotations name a row in this alignment`);
|
|
128774
|
+
}
|
|
128775
|
+
}));
|
|
128754
128776
|
loadOnFilehandleChange({
|
|
128755
128777
|
what: "annotations",
|
|
128756
128778
|
optional: true,
|
|
@@ -129768,6 +129790,37 @@ async function runGeneStructure(options2) {
|
|
|
129768
129790
|
init_src2();
|
|
129769
129791
|
import * as fs4 from "node:fs";
|
|
129770
129792
|
|
|
129793
|
+
// src/fetchWithRetry.ts
|
|
129794
|
+
var RETRYABLE = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
129795
|
+
function delay(ms) {
|
|
129796
|
+
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
129797
|
+
}
|
|
129798
|
+
function retryAfterMs(response) {
|
|
129799
|
+
const header = response.headers.get("retry-after");
|
|
129800
|
+
const seconds = header ? Number(header) : Number.NaN;
|
|
129801
|
+
return Number.isFinite(seconds) && seconds > 0 ? Math.min(seconds, 60) * 1e3 : void 0;
|
|
129802
|
+
}
|
|
129803
|
+
async function fetchWithRetry(url, { attempts = 4, baseDelayMs = 1e3 } = {}) {
|
|
129804
|
+
let lastError;
|
|
129805
|
+
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
129806
|
+
let wait = baseDelayMs * 2 ** attempt;
|
|
129807
|
+
try {
|
|
129808
|
+
const response = await fetch(url);
|
|
129809
|
+
if (!RETRYABLE.has(response.status)) {
|
|
129810
|
+
return response;
|
|
129811
|
+
}
|
|
129812
|
+
lastError = new Error(`${response.status} ${response.statusText}`);
|
|
129813
|
+
wait = retryAfterMs(response) ?? wait;
|
|
129814
|
+
} catch (e3) {
|
|
129815
|
+
lastError = e3;
|
|
129816
|
+
}
|
|
129817
|
+
if (attempt < attempts - 1) {
|
|
129818
|
+
await delay(wait);
|
|
129819
|
+
}
|
|
129820
|
+
}
|
|
129821
|
+
throw new Error(`${url} failed after ${attempts} attempts: ${lastError}`);
|
|
129822
|
+
}
|
|
129823
|
+
|
|
129771
129824
|
// src/interpro-cache.ts
|
|
129772
129825
|
import * as fs3 from "node:fs";
|
|
129773
129826
|
import * as os from "node:os";
|
|
@@ -129807,35 +129860,6 @@ function writeCached(release, database, accession, value) {
|
|
|
129807
129860
|
function cacheLocation() {
|
|
129808
129861
|
return CACHE_DIR;
|
|
129809
129862
|
}
|
|
129810
|
-
var RETRYABLE = /* @__PURE__ */ new Set([408, 425, 429, 500, 502, 503, 504]);
|
|
129811
|
-
function delay(ms) {
|
|
129812
|
-
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
129813
|
-
}
|
|
129814
|
-
function retryAfterMs(response) {
|
|
129815
|
-
const header = response.headers.get("retry-after");
|
|
129816
|
-
const seconds = header ? Number(header) : Number.NaN;
|
|
129817
|
-
return Number.isFinite(seconds) && seconds > 0 ? Math.min(seconds, 60) * 1e3 : void 0;
|
|
129818
|
-
}
|
|
129819
|
-
async function fetchWithRetry(url, { attempts = 4, baseDelayMs = 1e3 } = {}) {
|
|
129820
|
-
let lastError;
|
|
129821
|
-
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
129822
|
-
let wait = baseDelayMs * 2 ** attempt;
|
|
129823
|
-
try {
|
|
129824
|
-
const response = await fetch(url);
|
|
129825
|
-
if (!RETRYABLE.has(response.status)) {
|
|
129826
|
-
return response;
|
|
129827
|
-
}
|
|
129828
|
-
lastError = new Error(`${response.status} ${response.statusText}`);
|
|
129829
|
-
wait = retryAfterMs(response) ?? wait;
|
|
129830
|
-
} catch (e3) {
|
|
129831
|
-
lastError = e3;
|
|
129832
|
-
}
|
|
129833
|
-
if (attempt < attempts - 1) {
|
|
129834
|
-
await delay(wait);
|
|
129835
|
-
}
|
|
129836
|
-
}
|
|
129837
|
-
throw new Error(`${url} failed after ${attempts} attempts: ${lastError}`);
|
|
129838
|
-
}
|
|
129839
129863
|
|
|
129840
129864
|
// src/interpro-precomputed.ts
|
|
129841
129865
|
var API2 = "https://www.ebi.ac.uk/interpro/api";
|
|
@@ -129865,12 +129889,27 @@ async function fetchRelease() {
|
|
|
129865
129889
|
const json = await res.json();
|
|
129866
129890
|
return json.databases.interpro.version;
|
|
129867
129891
|
}
|
|
129892
|
+
async function fetchNotFoundRetried(url, attempts = 3) {
|
|
129893
|
+
for (let attempt = 0; attempt < attempts; attempt++) {
|
|
129894
|
+
const res = await fetchWithRetry(url);
|
|
129895
|
+
if (res.status !== 404) {
|
|
129896
|
+
return res;
|
|
129897
|
+
}
|
|
129898
|
+
if (attempt < attempts - 1) {
|
|
129899
|
+
await new Promise((resolve) => setTimeout(resolve, 1e3 * 2 ** attempt));
|
|
129900
|
+
}
|
|
129901
|
+
}
|
|
129902
|
+
return void 0;
|
|
129903
|
+
}
|
|
129868
129904
|
async function fetchEntries(accession, database) {
|
|
129869
129905
|
const results = [];
|
|
129870
129906
|
let url = `${API2}/entry/${database}/protein/uniprot/${accession}/?page_size=200`;
|
|
129871
129907
|
while (url) {
|
|
129872
|
-
const res = await
|
|
129873
|
-
if (res
|
|
129908
|
+
const res = await fetchNotFoundRetried(url);
|
|
129909
|
+
if (!res) {
|
|
129910
|
+
return void 0;
|
|
129911
|
+
}
|
|
129912
|
+
if (res.status === 204) {
|
|
129874
129913
|
break;
|
|
129875
129914
|
}
|
|
129876
129915
|
if (!res.ok) {
|
|
@@ -129894,6 +129933,7 @@ async function runInterProPrecomputed(options2) {
|
|
|
129894
129933
|
`InterPro release ${release}; reading precomputed ${database} matches...`
|
|
129895
129934
|
);
|
|
129896
129935
|
const entriesByAccession = /* @__PURE__ */ new Map();
|
|
129936
|
+
const unresolved = [];
|
|
129897
129937
|
let fetched = 0;
|
|
129898
129938
|
let cached = 0;
|
|
129899
129939
|
for (const [i2, accession] of distinct.entries()) {
|
|
@@ -129911,14 +129951,23 @@ async function runInterProPrecomputed(options2) {
|
|
|
129911
129951
|
${i2} of ${distinct.length} accessions are cached; re-run to resume from ${accession}.`
|
|
129912
129952
|
);
|
|
129913
129953
|
}
|
|
129914
|
-
|
|
129915
|
-
|
|
129954
|
+
if (entries3) {
|
|
129955
|
+
writeCached(release, database, accession, entries3);
|
|
129956
|
+
fetched++;
|
|
129957
|
+
} else {
|
|
129958
|
+
unresolved.push(accession);
|
|
129959
|
+
}
|
|
129916
129960
|
}
|
|
129917
|
-
entriesByAccession.set(accession, entries3);
|
|
129961
|
+
entriesByAccession.set(accession, entries3 ?? []);
|
|
129962
|
+
const count2 = entries3 ? `${entries3.length} ${database} entries` : "no answer";
|
|
129918
129963
|
console.log(
|
|
129919
|
-
` [${i2 + 1}/${distinct.length}] ${accession}: ${
|
|
129964
|
+
` [${i2 + 1}/${distinct.length}] ${accession}: ${count2}${hit ? " (cached)" : ""}`
|
|
129920
129965
|
);
|
|
129921
|
-
if (entries3
|
|
129966
|
+
if (!entries3) {
|
|
129967
|
+
console.warn(
|
|
129968
|
+
` the API answered 404 for ${accession} every time; it carries no domains in the GFF, and a re-run tries it again`
|
|
129969
|
+
);
|
|
129970
|
+
} else if (entries3.length === 0) {
|
|
129922
129971
|
console.warn(
|
|
129923
129972
|
` no ${database} matches for ${accession}; check it is a UniProtKB accession and that --database is the right member database`
|
|
129924
129973
|
);
|
|
@@ -129939,6 +129988,11 @@ ${i2} of ${distinct.length} accessions are cached; re-run to resume from ${acces
|
|
|
129939
129988
|
)
|
|
129940
129989
|
);
|
|
129941
129990
|
console.log(`${fetched} fetched, ${cached} from ${cacheLocation()}`);
|
|
129991
|
+
if (unresolved.length > 0) {
|
|
129992
|
+
console.warn(
|
|
129993
|
+
`${unresolved.length} of ${distinct.length} accessions did not resolve: ${unresolved.join(", ")}. Re-run to try them again.`
|
|
129994
|
+
);
|
|
129995
|
+
}
|
|
129942
129996
|
if (options2.msaFile) {
|
|
129943
129997
|
checkLengths(
|
|
129944
129998
|
options2.msaFile,
|
|
@@ -129998,14 +130052,14 @@ ${sequence.seq}`,
|
|
|
129998
130052
|
return response.text();
|
|
129999
130053
|
}
|
|
130000
130054
|
async function checkStatus(jobId) {
|
|
130001
|
-
const response = await
|
|
130055
|
+
const response = await fetchWithRetry(`${BASE_URL}/status/${jobId}`);
|
|
130002
130056
|
if (!response.ok) {
|
|
130003
130057
|
throw new Error(`Failed to check status: ${response.statusText}`);
|
|
130004
130058
|
}
|
|
130005
130059
|
return response.text();
|
|
130006
130060
|
}
|
|
130007
130061
|
async function getResults(jobId) {
|
|
130008
|
-
const response = await
|
|
130062
|
+
const response = await fetchWithRetry(`${BASE_URL}/result/${jobId}/json`);
|
|
130009
130063
|
if (!response.ok) {
|
|
130010
130064
|
throw new Error(`Failed to get results: ${response.statusText}`);
|
|
130011
130065
|
}
|
|
@@ -130494,6 +130548,19 @@ function readFormat(format2) {
|
|
|
130494
130548
|
}
|
|
130495
130549
|
return format2;
|
|
130496
130550
|
}
|
|
130551
|
+
function readNumber(name, value, integer2 = false) {
|
|
130552
|
+
const n2 = integer2 ? Number.parseInt(value, 10) : Number.parseFloat(value);
|
|
130553
|
+
if (Number.isNaN(n2)) {
|
|
130554
|
+
throw new Error(`--${name} must be a number, got "${value}"`);
|
|
130555
|
+
}
|
|
130556
|
+
return n2;
|
|
130557
|
+
}
|
|
130558
|
+
function readInt(name, value) {
|
|
130559
|
+
return readNumber(name, value, true);
|
|
130560
|
+
}
|
|
130561
|
+
function readList(value) {
|
|
130562
|
+
return value.split(",").map((s2) => s2.trim());
|
|
130563
|
+
}
|
|
130497
130564
|
async function main() {
|
|
130498
130565
|
const { values: values4, positionals } = parseArgs({ allowPositionals: true, options });
|
|
130499
130566
|
if (values4.help || positionals.length === 0) {
|
|
@@ -130515,13 +130582,13 @@ async function main() {
|
|
|
130515
130582
|
gffFile: values4.gff,
|
|
130516
130583
|
outputFile,
|
|
130517
130584
|
colorScheme: values4["color-scheme"],
|
|
130518
|
-
width:
|
|
130519
|
-
height:
|
|
130520
|
-
treeAreaWidth: values4["tree-area-width"] !== void 0 ?
|
|
130521
|
-
colWidth: values4["col-width"] !== void 0 ?
|
|
130522
|
-
rowHeight: values4["row-height"] !== void 0 ?
|
|
130585
|
+
width: readInt("width", values4.width),
|
|
130586
|
+
height: readInt("height", values4.height),
|
|
130587
|
+
treeAreaWidth: values4["tree-area-width"] !== void 0 ? readInt("tree-area-width", values4["tree-area-width"]) : void 0,
|
|
130588
|
+
colWidth: values4["col-width"] !== void 0 ? readNumber("col-width", values4["col-width"]) : void 0,
|
|
130589
|
+
rowHeight: values4["row-height"] !== void 0 ? readNumber("row-height", values4["row-height"]) : void 0,
|
|
130523
130590
|
format: format2,
|
|
130524
|
-
tracks: values4.tracks
|
|
130591
|
+
tracks: values4.tracks !== void 0 ? readList(values4.tracks) : void 0,
|
|
130525
130592
|
viewport: values4.viewport,
|
|
130526
130593
|
minimap: values4.minimap
|
|
130527
130594
|
});
|
|
@@ -130542,7 +130609,7 @@ async function main() {
|
|
|
130542
130609
|
dockerImage: values4["docker-image"],
|
|
130543
130610
|
interproscanPath: values4["interproscan-path"],
|
|
130544
130611
|
dataDir: values4["interproscan-data"],
|
|
130545
|
-
programs: values4.programs
|
|
130612
|
+
programs: readList(values4.programs),
|
|
130546
130613
|
email: values4.email,
|
|
130547
130614
|
format: format2
|
|
130548
130615
|
});
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "react-msaview-cli",
|
|
3
|
-
"version": "8.
|
|
3
|
+
"version": "8.1.0",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"repository": {
|
|
@@ -20,8 +20,8 @@
|
|
|
20
20
|
"@types/node": "^26.5.1",
|
|
21
21
|
"esbuild": "^0.28.2",
|
|
22
22
|
"mobx-react": "^10.0.2",
|
|
23
|
-
"msa-parsers": "8.
|
|
24
|
-
"react-msaview": "8.
|
|
23
|
+
"msa-parsers": "8.1.0",
|
|
24
|
+
"react-msaview": "8.1.0"
|
|
25
25
|
},
|
|
26
26
|
"dependencies": {
|
|
27
27
|
"jsdom": "^30.0.1"
|