@teselagen/ove 0.8.40 → 0.8.42

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/index.umd.js CHANGED
@@ -119217,17 +119217,20 @@ ${latestSubscriptionCallbackError.current.stack}
119217
119217
  const b3 = new fxpExports.XMLParser({
119218
119218
  ignoreAttributes: false,
119219
119219
  attributeNamePrefix: "",
119220
- isArray: /* @__PURE__ */ __name((name2) => name2 === "Feature" || name2 === "Segment", "isArray")
119220
+ isArray: /* @__PURE__ */ __name((name2) => ["Feature", "Segment", "Q", "V"].includes(name2), "isArray")
119221
119221
  }).parse(xml2);
119222
119222
  const { Features: { Feature: Feature2 = [] } = {} } = b3;
119223
119223
  data.features = [];
119224
119224
  Feature2.forEach((feat) => {
119225
+ var _a2, _b2, _c2, _d2;
119225
119226
  const { directionality, Segment = [], name: name2, type: type2 } = feat;
119227
+ let color2;
119226
119228
  let maxStart = 0;
119227
119229
  let maxEnd = 0;
119228
119230
  const locations = Segment && Segment.map((seg) => {
119229
119231
  if (!seg) throw new Error("invalid feature definition");
119230
119232
  const { range: range2 } = seg;
119233
+ if (seg.color) color2 = seg.color;
119231
119234
  let { start: start2, end: end2 } = getStartAndEndFromRangeString(range2);
119232
119235
  start2 = isProtein2 ? start2 * 3 : start2;
119233
119236
  end2 = isProtein2 ? end2 * 3 + 2 : end2;
@@ -119238,6 +119241,10 @@ ${latestSubscriptionCallbackError.current.stack}
119238
119241
  end: end2
119239
119242
  };
119240
119243
  });
119244
+ const colorQual = (_a2 = feat.Q) == null ? void 0 : _a2.find((q2) => q2.name === "color");
119245
+ if (colorQual) {
119246
+ color2 = ((_c2 = (_b2 = colorQual.V) == null ? void 0 : _b2[0]) == null ? void 0 : _c2.text) || ((_d2 = colorQual.V) == null ? void 0 : _d2[0]);
119247
+ }
119241
119248
  data.features.push(__spreadProps(__spreadValues({
119242
119249
  name: name2,
119243
119250
  type: type2
@@ -119245,8 +119252,8 @@ ${latestSubscriptionCallbackError.current.stack}
119245
119252
  strand: directionality ? strand_dict[directionality][0] : 1,
119246
119253
  arrowheadType: directionality ? strand_dict[directionality][1] : "NONE",
119247
119254
  start: maxStart,
119248
- end: maxEnd
119249
- // color,
119255
+ end: maxEnd,
119256
+ color: color2
119250
119257
  }));
119251
119258
  });
119252
119259
  } else if (ord(next_byte) === 6) {
@@ -124411,14 +124418,34 @@ ${seq.sequence}
124411
124418
  track.alignmentData.sequence
124412
124419
  );
124413
124420
  const mismatches = matchHighlightRanges.filter(({ isMatch }) => !isMatch);
124421
+ const alignedSeq = track.alignmentData.sequence;
124422
+ const seqLen = alignedSeq.length;
124423
+ const startIndex = seqLen - alignedSeq.replace(/^-+/, "").length;
124424
+ const endIndex = alignedSeq.replace(/-+$/, "").length;
124425
+ const gapRanges = [
124426
+ startIndex > 0 && {
124427
+ start: 0,
124428
+ end: startIndex - 1,
124429
+ differenceType: "gap"
124430
+ },
124431
+ endIndex < seqLen && {
124432
+ start: endIndex,
124433
+ end: seqLen - 1,
124434
+ differenceType: "gap"
124435
+ }
124436
+ ].filter(Boolean);
124414
124437
  return __spreadProps(__spreadValues({}, track), {
124415
124438
  sequenceData: sequenceData2,
124416
124439
  matchHighlightRanges,
124417
- additionalSelectionLayers: matchHighlightRanges.filter(({ isMatch }) => !isMatch).map((range2) => {
124418
- return __spreadProps(__spreadValues(__spreadValues({}, range2), highlightRangeProps), {
124440
+ additionalSelectionLayers: [
124441
+ ...matchHighlightRanges.filter(({ isMatch }) => !isMatch).map((range2) => __spreadProps(__spreadValues(__spreadValues({}, range2), highlightRangeProps), {
124419
124442
  className: "veAlignmentMismatch"
124420
- });
124421
- }),
124443
+ })),
124444
+ ...gapRanges.map((range2) => __spreadProps(__spreadValues(__spreadValues({}, range2), highlightRangeProps), {
124445
+ className: "veAlignmentMismatch"
124446
+ }))
124447
+ ],
124448
+ gapRanges,
124422
124449
  mismatches
124423
124450
  });
124424
124451
  });
@@ -124552,23 +124579,30 @@ ${seq.sequence}
124552
124579
  const startIndex = seqLength - nonTempSeqWithoutLeadingDashes.length;
124553
124580
  const endIndex = seqLength - (seqLength - nonTempSeqWithoutTrailingDashes.length);
124554
124581
  for (let index2 = startIndex; index2 < endIndex; index2++) {
124555
- const isMatch = tempSeq[index2].toLowerCase() === nonTempSeq[index2].toLowerCase();
124556
- const previousRange = ranges[ranges.length - 1];
124557
- if (previousRange) {
124558
- if (previousRange.isMatch === isMatch) {
124559
- previousRange.end++;
124582
+ const tempBase = tempSeq[index2].toLowerCase();
124583
+ const nonTempBase = nonTempSeq[index2].toLowerCase();
124584
+ const isMatch = tempBase === nonTempBase;
124585
+ let differenceType = null;
124586
+ if (!isMatch) {
124587
+ if (tempBase === "-") {
124588
+ differenceType = "insertion";
124589
+ } else if (nonTempBase === "-") {
124590
+ differenceType = "deletion";
124560
124591
  } else {
124561
- ranges.push({
124562
- start: index2,
124563
- end: index2,
124564
- isMatch
124565
- });
124592
+ differenceType = "mismatch";
124566
124593
  }
124594
+ }
124595
+ const previousRange = ranges[ranges.length - 1];
124596
+ if (previousRange && previousRange.isMatch === isMatch && previousRange.differenceType === differenceType) {
124597
+ previousRange.end++;
124598
+ } else if (previousRange) {
124599
+ ranges.push({ start: index2, end: index2, isMatch, differenceType });
124567
124600
  } else {
124568
124601
  ranges.push({
124569
124602
  start: startIndex,
124570
124603
  end: startIndex,
124571
- isMatch
124604
+ isMatch,
124605
+ differenceType
124572
124606
  });
124573
124607
  }
124574
124608
  }
@@ -145343,7 +145377,7 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
145343
145377
  input.click();
145344
145378
  }
145345
145379
  __name(showFileDialog, "showFileDialog");
145346
- const version = "0.8.40";
145380
+ const version = "0.8.42";
145347
145381
  const packageJson = {
145348
145382
  version
145349
145383
  };
@@ -151610,11 +151644,13 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
151610
151644
  dimensions: { width = 200 },
151611
151645
  laneHeight,
151612
151646
  laneSpacing = 1,
151613
- isTrackSelected = []
151647
+ isTrackSelected = [],
151648
+ activeFilterType = "all"
151614
151649
  } = this.props;
151615
151650
  const charWidth2 = this.getCharWidth();
151616
151651
  const {
151617
151652
  matchHighlightRanges: _matchHighlightRanges,
151653
+ gapRanges = [],
151618
151654
  alignmentData: { trimmedRange } = {}
151619
151655
  } = alignmentTracks[i2];
151620
151656
  const matchHighlightRanges = !trimmedRange ? _matchHighlightRanges : flatMap(_matchHighlightRanges, (r2) => {
@@ -151641,10 +151677,19 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
151641
151677
  charWidth2
151642
151678
  );
151643
151679
  const toAdd = `M${xStart},${y2} L${xStart + width2},${y2} L${xStart + width2},${y2 + height} L${xStart},${y2 + height}`;
151644
- if (!range2.isMatch) {
151680
+ if (!range2.isMatch && (activeFilterType === "all" || range2.differenceType === activeFilterType)) {
151645
151681
  redPath += toAdd;
151646
151682
  }
151647
151683
  });
151684
+ if (activeFilterType === "gap") {
151685
+ gapRanges.forEach((range2) => {
151686
+ const { xStart, width: width2 } = getXStartAndWidthFromNonCircularRange(
151687
+ range2,
151688
+ charWidth2
151689
+ );
151690
+ redPath += `M${xStart},${y2} L${xStart + width2},${y2} L${xStart + width2},${y2 + height} L${xStart},${y2 + height}`;
151691
+ });
151692
+ }
151648
151693
  return /* @__PURE__ */ React.createElement(
151649
151694
  "div",
151650
151695
  {
@@ -151674,7 +151719,8 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
151674
151719
  "scrollAlignmentView",
151675
151720
  "laneHeight",
151676
151721
  "laneSpacing",
151677
- "isTrackSelected"
151722
+ "isTrackSelected",
151723
+ "activeFilterType"
151678
151724
  ].some((key) => props[key] !== newProps[key]))
151679
151725
  return true;
151680
151726
  return false;
@@ -151952,6 +151998,66 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
151952
151998
  return splitRangeIntoTwoPartsIfItIsCircular(inverted, seqLen);
151953
151999
  }
151954
152000
  __name(getTrimmedRangesToDisplay, "getTrimmedRangesToDisplay");
152001
+ function groupConsecutiveDifferences(differences) {
152002
+ const grouped = [];
152003
+ for (const diff of differences) {
152004
+ if (diff.type === "mismatch") {
152005
+ grouped.push(__spreadProps(__spreadValues({}, diff), { start: diff.position, end: diff.position }));
152006
+ continue;
152007
+ }
152008
+ const last2 = grouped[grouped.length - 1];
152009
+ if (last2 && last2.type === diff.type && last2.end === diff.position - 1) {
152010
+ grouped[grouped.length - 1] = __spreadProps(__spreadValues({}, last2), { end: diff.position });
152011
+ } else {
152012
+ grouped.push(__spreadProps(__spreadValues({}, diff), { start: diff.position, end: diff.position }));
152013
+ }
152014
+ }
152015
+ return grouped;
152016
+ }
152017
+ __name(groupConsecutiveDifferences, "groupConsecutiveDifferences");
152018
+ function findAlignmentDifferences(alignedSeqs) {
152019
+ var _a2;
152020
+ if (alignedSeqs.length < 2 || !((_a2 = alignedSeqs[0]) == null ? void 0 : _a2.length)) return [];
152021
+ const template = alignedSeqs[0].toLowerCase();
152022
+ const nonTemplates = alignedSeqs.slice(1).map((s2) => s2.toLowerCase());
152023
+ const trackBounds = nonTemplates.map((seq) => {
152024
+ const withoutLeading = seq.replace(/^-+/, "");
152025
+ const withoutTrailing = seq.replace(/-+$/, "");
152026
+ const start2 = seq.length - withoutLeading.length;
152027
+ const end2 = seq.length - (seq.length - withoutTrailing.length);
152028
+ return { start: start2, end: end2 };
152029
+ });
152030
+ const differences = [];
152031
+ for (let i2 = 0; i2 < template.length; i2++) {
152032
+ const templateBase = template[i2];
152033
+ const allNonTemplateBases = nonTemplates.map((seq) => seq[i2]);
152034
+ const bases = [templateBase, ...allNonTemplateBases];
152035
+ const alignedIndices = trackBounds.reduce((acc, { start: start2, end: end2 }, idx) => {
152036
+ if (i2 >= start2 && i2 < end2) acc.push(idx);
152037
+ return acc;
152038
+ }, []);
152039
+ if (alignedIndices.length === 0) {
152040
+ differences.push({ position: i2, type: "gap", bases });
152041
+ continue;
152042
+ }
152043
+ const alignedBases = alignedIndices.map((idx) => allNonTemplateBases[idx]);
152044
+ const templateIsGap = templateBase === "-";
152045
+ const nonTemplateHasBase = alignedBases.some((b3) => b3 !== "-");
152046
+ const nonTemplateHasGap = alignedBases.some((b3) => b3 === "-");
152047
+ if (templateIsGap && nonTemplateHasBase) {
152048
+ differences.push({ position: i2, type: "insertion", bases });
152049
+ } else if (!templateIsGap && nonTemplateHasGap) {
152050
+ differences.push({ position: i2, type: "deletion", bases });
152051
+ } else if (!templateIsGap) {
152052
+ const uniqueBases = /* @__PURE__ */ new Set([templateBase, ...alignedBases]);
152053
+ if (uniqueBases.size > 1) {
152054
+ differences.push({ position: i2, type: "mismatch", bases });
152055
+ }
152056
+ }
152057
+ }
152058
+ return differences;
152059
+ }
152060
+ __name(findAlignmentDifferences, "findAlignmentDifferences");
151955
152061
  function scrollToAlignmentSelection() {
151956
152062
  const el = document.querySelector(".veCaret");
151957
152063
  if (el) {
@@ -151965,159 +152071,145 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
151965
152071
  }
151966
152072
  }
151967
152073
  __name(updateCaretPosition, "updateCaretPosition");
152074
+ const FILTER_OPTIONS = [
152075
+ { value: "all", label: "All" },
152076
+ { value: "mismatch", label: "Mismatches" },
152077
+ { value: "insertion", label: "Insertions" },
152078
+ { value: "deletion", label: "Deletions" },
152079
+ { value: "gap", label: "Gaps" }
152080
+ ];
151968
152081
  function FindMismatches(props) {
151969
- const { alignmentJson, id: id2 } = props;
152082
+ var _a2;
152083
+ const { alignmentJson, id: id2, onFilterChange } = props;
151970
152084
  const alignedSeqs = reactExports.useMemo(
151971
152085
  () => alignmentJson.map((t2) => {
151972
- var _a2;
151973
- return ((_a2 = t2.alignmentData) == null ? void 0 : _a2.sequence) || "";
152086
+ var _a3;
152087
+ return ((_a3 = t2.alignmentData) == null ? void 0 : _a3.sequence) || "";
151974
152088
  }),
151975
152089
  [alignmentJson]
151976
152090
  );
151977
- const mismatches = reactExports.useMemo(() => {
151978
- const result = [{ position: 0, bases: [""] }];
151979
- if (alignedSeqs.length > 1 && alignedSeqs[0].length) {
151980
- for (let i2 = 0; i2 < alignedSeqs[0].length; i2++) {
151981
- const bases = alignedSeqs.map((seq) => seq[i2]);
151982
- const uniqueBases = new Set(bases);
151983
- if (uniqueBases.size > 1 && !uniqueBases.has("-")) {
151984
- result.push({ position: i2, bases });
151985
- }
151986
- }
151987
- }
151988
- return result;
151989
- }, [alignedSeqs]);
152091
+ const [activeFilter, setActiveFilter] = React.useState("all");
152092
+ const allDifferences = reactExports.useMemo(
152093
+ () => groupConsecutiveDifferences(findAlignmentDifferences(alignedSeqs)),
152094
+ [alignedSeqs]
152095
+ );
152096
+ const countsByType = reactExports.useMemo(() => {
152097
+ const counts = { all: 0, mismatch: 0, insertion: 0, deletion: 0, gap: 0 };
152098
+ allDifferences.forEach((d2) => {
152099
+ counts[d2.type] = (counts[d2.type] || 0) + 1;
152100
+ counts.all++;
152101
+ });
152102
+ return counts;
152103
+ }, [allDifferences]);
152104
+ const differences = reactExports.useMemo(() => {
152105
+ const filtered = activeFilter === "all" ? allDifferences : allDifferences.filter((d2) => d2.type === activeFilter);
152106
+ return [{ position: -1, start: -1, end: -1, bases: [""] }, ...filtered];
152107
+ }, [allDifferences, activeFilter]);
151990
152108
  const currentCaretPosition = useSelector(
151991
152109
  (state2) => {
151992
- var _a2;
151993
- return (_a2 = state2.VectorEditor.__allEditorsOptions.alignments[id2]) == null ? void 0 : _a2.caretPosition;
152110
+ var _a3;
152111
+ return (_a3 = state2.VectorEditor.__allEditorsOptions.alignments[id2]) == null ? void 0 : _a3.caretPosition;
151994
152112
  }
151995
152113
  );
151996
152114
  const [currentIdx, setCurrentIdx] = React.useState(0);
151997
- const [disablePrev, setDisablePrev] = React.useState(true);
151998
- const [disableNext, setDisableNext] = React.useState(false);
151999
- const currentMismatch = mismatches[currentIdx];
152000
- const handleButtonsState = reactExports.useCallback(
152001
- (caret) => {
152002
- if (mismatches.length <= 1) {
152003
- setDisablePrev(true);
152004
- setDisableNext(true);
152005
- return;
152006
- }
152007
- const firstMismatchPos = mismatches[1].position;
152008
- const lastMismatchPos = mismatches[mismatches.length - 1].position;
152009
- setDisablePrev(caret <= firstMismatchPos);
152010
- setDisableNext(caret >= lastMismatchPos);
152011
- },
152012
- [mismatches]
152013
- );
152115
+ const currentDiff = differences[currentIdx];
152116
+ const disablePrev = currentIdx <= 1;
152117
+ const disableNext = currentIdx >= differences.length - 1;
152118
+ reactExports.useEffect(() => {
152119
+ setCurrentIdx(0);
152120
+ }, [activeFilter]);
152121
+ reactExports.useEffect(() => {
152122
+ onFilterChange == null ? void 0 : onFilterChange({ activeFilter });
152123
+ }, [activeFilter, onFilterChange]);
152014
152124
  reactExports.useEffect(() => {
152015
152125
  if (currentCaretPosition !== -1) {
152016
- const mismatchIdx = mismatches.findIndex(
152017
- (m2) => m2.position === currentCaretPosition || m2.position === currentCaretPosition - 1
152126
+ const diffIdx = differences.findIndex(
152127
+ (d2, i2) => i2 > 0 && currentCaretPosition >= d2.start && currentCaretPosition <= d2.end + 1
152018
152128
  );
152019
- if (mismatchIdx !== -1 && mismatchIdx !== currentIdx) {
152020
- handleButtonsState(currentCaretPosition);
152021
- setCurrentIdx(mismatchIdx);
152129
+ if (diffIdx !== -1 && diffIdx !== currentIdx) {
152130
+ setCurrentIdx(diffIdx);
152022
152131
  }
152023
152132
  }
152024
- }, [currentCaretPosition, mismatches, currentIdx, handleButtonsState]);
152025
- const updateView = /* @__PURE__ */ __name((mismatch) => {
152026
- const idx = mismatches.indexOf(mismatch);
152027
- const position2 = mismatch.position;
152028
- handleButtonsState(position2);
152133
+ }, [currentCaretPosition, differences, currentIdx]);
152134
+ const updateView = /* @__PURE__ */ __name((diff) => {
152135
+ const idx = differences.indexOf(diff);
152136
+ const { start: start2, end: end2 } = diff;
152029
152137
  setCurrentIdx(idx);
152030
- updateCaretPosition({ start: position2, end: position2 });
152138
+ updateCaretPosition({ start: start2, end: end2 });
152031
152139
  setTimeout(() => {
152032
152140
  scrollToAlignmentSelection();
152033
152141
  }, 0);
152034
152142
  }, "updateView");
152035
- const prevMismatch = /* @__PURE__ */ __name(() => {
152036
- if (currentIdx > 1) {
152037
- const newIdx = Math.max(0, currentIdx - 1);
152038
- let prev = mismatches[newIdx];
152039
- if (currentCaretPosition > 0) {
152040
- prev = [...mismatches].reverse().find((m2) => m2.position < currentCaretPosition);
152041
- }
152042
- if (prev) {
152043
- updateView(prev);
152044
- }
152045
- }
152046
- }, "prevMismatch");
152047
- const nextMismatch = /* @__PURE__ */ __name(() => {
152048
- if (currentIdx < mismatches.length - 1) {
152049
- const newIdx = Math.min(mismatches.length - 1, currentIdx + 1);
152050
- let next = mismatches[newIdx];
152051
- if (currentCaretPosition > 0) {
152052
- next = mismatches.find(
152053
- (m2) => m2.position > currentCaretPosition && m2.position > 1
152054
- );
152055
- }
152056
- if (next) {
152057
- updateView(next);
152143
+ const prevDifference = /* @__PURE__ */ __name(() => {
152144
+ var _a3, _b2;
152145
+ const pivot = currentCaretPosition >= 0 ? currentCaretPosition : (_b2 = (_a3 = differences[currentIdx]) == null ? void 0 : _a3.start) != null ? _b2 : 0;
152146
+ const prev = [...differences].reverse().find((d2) => d2.start >= 0 && d2.start < pivot);
152147
+ if (prev) updateView(prev);
152148
+ }, "prevDifference");
152149
+ const nextDifference = /* @__PURE__ */ __name(() => {
152150
+ var _a3, _b2;
152151
+ const pivot = currentCaretPosition >= 0 ? currentCaretPosition : (_b2 = (_a3 = differences[currentIdx]) == null ? void 0 : _a3.start) != null ? _b2 : -1;
152152
+ const next = differences.find((d2) => d2.start > pivot && d2.start >= 0);
152153
+ if (next) updateView(next);
152154
+ }, "nextDifference");
152155
+ const noDifferences = differences.length <= 1;
152156
+ const activeOption = FILTER_OPTIONS.find((o2) => o2.value === activeFilter);
152157
+ const activeLabel = (_a2 = activeOption == null ? void 0 : activeOption.label) != null ? _a2 : "Differences";
152158
+ const filterMenu = /* @__PURE__ */ React.createElement(Menu, null, FILTER_OPTIONS.map(({ value, label }) => {
152159
+ var _a3;
152160
+ const count2 = (_a3 = countsByType[value]) != null ? _a3 : 0;
152161
+ const isActive2 = activeFilter === value;
152162
+ return /* @__PURE__ */ React.createElement(
152163
+ MenuItem,
152164
+ {
152165
+ key: value,
152166
+ active: isActive2,
152167
+ onClick: /* @__PURE__ */ __name(() => setActiveFilter(value), "onClick"),
152168
+ text: /* @__PURE__ */ React.createElement("span", { className: "veDiffMenuItem-inner" }, label, /* @__PURE__ */ React.createElement(Tag, { round: true, minimal: true, style: { marginLeft: 6 } }, count2))
152058
152169
  }
152059
- }
152060
- }, "nextMismatch");
152061
- return /* @__PURE__ */ React.createElement(
152062
- "div",
152170
+ );
152171
+ }));
152172
+ return /* @__PURE__ */ React.createElement("div", { className: "veDiffNavigator" }, /* @__PURE__ */ React.createElement(
152173
+ Popover,
152063
152174
  {
152064
- style: {
152065
- display: "flex",
152066
- flexDirection: "row",
152067
- justifyContent: "center",
152068
- alignItems: "center",
152069
- gap: 10
152070
- }
152071
- },
152072
- mismatches.length === 1 ? /* @__PURE__ */ React.createElement("span", { style: { fontStyle: "italic", color: "grey" } }, "no mismatches") : /* @__PURE__ */ React.createElement("div", { style: { display: "flex", flexDirection: "column" } }, /* @__PURE__ */ React.createElement(
152073
- "div",
152074
- {
152075
- style: {
152076
- display: "flex",
152077
- alignItems: "center"
152078
- }
152079
- },
152080
- /* @__PURE__ */ React.createElement("strong", null, "Mismatches"),
152081
- /* @__PURE__ */ React.createElement("div", { style: { display: "flex", gap: 2 } }, /* @__PURE__ */ React.createElement(
152082
- Button,
152083
- {
152084
- intent: "primary",
152085
- icon: "arrow-left",
152086
- "data-tip": "Previous Mismatch",
152087
- onClick: prevMismatch,
152088
- disabled: disablePrev,
152089
- small: true,
152090
- minimal: true
152091
- }
152092
- ), /* @__PURE__ */ React.createElement(
152175
+ minimal: true,
152176
+ position: Position.BOTTOM_LEFT,
152177
+ content: filterMenu,
152178
+ target: /* @__PURE__ */ React.createElement(
152093
152179
  Button,
152094
152180
  {
152095
- intent: "primary",
152096
- icon: "arrow-right",
152097
- "data-tip": "Next Mismatch",
152098
- onClick: nextMismatch,
152099
- disabled: disableNext,
152181
+ minimal: true,
152182
+ "data-tip": "Filter Difference Type",
152100
152183
  small: true,
152101
- minimal: true
152102
- }
152103
- ))
152104
- ), /* @__PURE__ */ React.createElement(
152105
- "span",
152106
- {
152107
- style: {
152108
- fontSize: "0.8em",
152109
- color: "grey",
152110
- lineHeight: "0.8em"
152111
- }
152112
- },
152113
- currentMismatch.position > 1 && /* @__PURE__ */ React.createElement("span", null, "Position: ", currentMismatch.position + 1, " | "),
152114
- "(",
152115
- currentIdx,
152116
- " of ",
152117
- mismatches.length - 1,
152118
- ")"
152119
- ))
152120
- );
152184
+ rightIcon: "caret-down",
152185
+ className: "veDiffFilter-trigger"
152186
+ },
152187
+ activeLabel
152188
+ )
152189
+ }
152190
+ ), noDifferences ? /* @__PURE__ */ React.createElement("span", { className: "veDiffNav-empty" }, "no", " ", activeFilter === "all" ? "differences" : activeLabel.toLowerCase()) : /* @__PURE__ */ React.createElement("div", { className: "veDiffNav" }, /* @__PURE__ */ React.createElement(
152191
+ Button,
152192
+ {
152193
+ minimal: true,
152194
+ small: true,
152195
+ "data-tip": "Previous Difference",
152196
+ icon: "arrow-left",
152197
+ intent: Intent.PRIMARY,
152198
+ onClick: prevDifference,
152199
+ disabled: disablePrev
152200
+ }
152201
+ ), /* @__PURE__ */ React.createElement("div", { className: "veDiffNav-center" }, /* @__PURE__ */ React.createElement("span", { className: "veDiffNav-fraction" }, currentIdx, /* @__PURE__ */ React.createElement("span", { className: "veDiffNav-sep" }, "/"), differences.length - 1), (currentDiff == null ? void 0 : currentDiff.start) > -1 && /* @__PURE__ */ React.createElement("span", { className: "veDiffNav-pos" }, ":", currentDiff.start + 1)), /* @__PURE__ */ React.createElement(
152202
+ Button,
152203
+ {
152204
+ minimal: true,
152205
+ small: true,
152206
+ "data-tip": "Next Difference",
152207
+ icon: "arrow-right",
152208
+ intent: Intent.PRIMARY,
152209
+ onClick: nextDifference,
152210
+ disabled: disableNext
152211
+ }
152212
+ )));
152121
152213
  }
152122
152214
  __name(FindMismatches, "FindMismatches");
152123
152215
  function getGapMap(sequence2) {
@@ -152806,17 +152898,18 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
152806
152898
  minimal: true,
152807
152899
  position: "bottom",
152808
152900
  content: /* @__PURE__ */ React.createElement(VisibilityOptions$2, __spreadValues({}, props)),
152809
- target: /* @__PURE__ */ React.createElement(Tooltip, { content: "Visibility Options" }, /* @__PURE__ */ React.createElement(
152901
+ target: /* @__PURE__ */ React.createElement(
152810
152902
  Button,
152811
152903
  {
152812
152904
  className: "tg-alignment-visibility-toggle",
152813
152905
  small: true,
152906
+ "data-tip": "Visibility Options",
152814
152907
  rightIcon: "caret-down",
152815
152908
  intent: Intent.PRIMARY,
152816
152909
  minimal: true,
152817
152910
  icon: "eye-open"
152818
152911
  }
152819
- ))
152912
+ )
152820
152913
  }
152821
152914
  );
152822
152915
  }, "AlignmentVisibilityTool"));
@@ -166604,6 +166697,10 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
166604
166697
  const [tempTrimAfter, setTempTrimAfter] = reactExports.useState({});
166605
166698
  const [tempTrimmingCaret, setTempTrimmingCaret] = reactExports.useState({});
166606
166699
  const [searchMatchLayers, setSearchMatchLayers] = React.useState([]);
166700
+ const [activeFilterType, setActiveFilterType] = reactExports.useState("all");
166701
+ const handleFilterChange = reactExports.useCallback(({ activeFilter }) => {
166702
+ setActiveFilterType(activeFilter);
166703
+ }, []);
166607
166704
  const bindOutsideChangeHelper = reactExports.useRef({});
166608
166705
  const alignmentHolder = reactExports.useRef(null);
166609
166706
  const alignmentHolderTop = reactExports.useRef(null);
@@ -167329,7 +167426,9 @@ ${seqDataToCopy}\r
167329
167426
  chromatogramData
167330
167427
  }) : linearViewOptions)), {
167331
167428
  additionalSelectionLayers: [
167332
- ...additionalSelectionLayers || [],
167429
+ ...i2 !== 0 ? (additionalSelectionLayers || []).filter(
167430
+ (layer) => activeFilterType === "all" ? layer.differenceType !== "gap" : layer.differenceType === activeFilterType
167431
+ ) : additionalSelectionLayers || [],
167333
167432
  ...searchMatchLayers || []
167334
167433
  ],
167335
167434
  dimensions: {
@@ -167988,7 +168087,14 @@ ${seqDataToCopy}\r
167988
168087
  setSearchMatchLayers
167989
168088
  }
167990
168089
  ),
167991
- /* @__PURE__ */ React.createElement(FindMismatches, { alignmentJson: alignmentTracks, id: id2 }),
168090
+ /* @__PURE__ */ React.createElement(
168091
+ FindMismatches,
168092
+ {
168093
+ alignmentJson: alignmentTracks,
168094
+ id: id2,
168095
+ onFilterChange: handleFilterChange
168096
+ }
168097
+ ),
167992
168098
  additionalTopEl,
167993
168099
  saveMessage && /* @__PURE__ */ React.createElement(
167994
168100
  "div",
@@ -168089,6 +168195,7 @@ ${seqDataToCopy}\r
168089
168195
  }
168090
168196
  )),
168091
168197
  alignmentTracks,
168198
+ activeFilterType,
168092
168199
  dimensions: {
168093
168200
  width: Math.max(width, 10) || 10
168094
168201
  },