@teselagen/ove 0.8.3 → 0.8.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (53) hide show
  1. package/AlignmentView/LabileSitesLayer.d.ts +13 -0
  2. package/AlignmentView/PairwiseAlignmentView.d.ts +1 -9
  3. package/BarPlot/index.d.ts +33 -0
  4. package/LinearView/SequenceName.d.ts +2 -1
  5. package/PropertySidePanel/calculateAminoAcidFrequency.d.ts +46 -0
  6. package/PropertySidePanel/index.d.ts +6 -0
  7. package/RowItem/Caret/index.d.ts +2 -1
  8. package/StatusBar/index.d.ts +2 -1
  9. package/aaprops.svg +2287 -0
  10. package/constants/dnaToColor.d.ts +122 -4
  11. package/index.cjs.js +4183 -2813
  12. package/index.es.js +2135 -765
  13. package/index.umd.js +3714 -2344
  14. package/ove.css +92 -6
  15. package/package.json +2 -2
  16. package/src/AlignmentView/AlignmentVisibilityTool.js +141 -37
  17. package/src/AlignmentView/LabileSitesLayer.js +33 -0
  18. package/src/AlignmentView/Minimap.js +5 -3
  19. package/src/AlignmentView/PairwiseAlignmentView.js +55 -61
  20. package/src/AlignmentView/index.js +476 -257
  21. package/src/AlignmentView/style.css +27 -0
  22. package/src/BarPlot/index.js +156 -0
  23. package/src/CircularView/Caret.js +8 -2
  24. package/src/CircularView/SelectionLayer.js +4 -2
  25. package/src/CircularView/index.js +5 -1
  26. package/src/Editor/darkmode.css +7 -0
  27. package/src/Editor/index.js +3 -0
  28. package/src/Editor/userDefinedHandlersAndOpts.js +2 -1
  29. package/src/FindBar/index.js +2 -3
  30. package/src/LinearView/SequenceName.js +8 -2
  31. package/src/LinearView/index.js +21 -0
  32. package/src/PropertySidePanel/calculateAminoAcidFrequency.js +77 -0
  33. package/src/PropertySidePanel/index.js +236 -0
  34. package/src/PropertySidePanel/style.css +39 -0
  35. package/src/RowItem/Caret/index.js +8 -2
  36. package/src/RowItem/Labels.js +1 -1
  37. package/src/RowItem/SelectionLayer/index.js +5 -1
  38. package/src/RowItem/Sequence.js +99 -5
  39. package/src/RowItem/Translations/Translation.js +3 -2
  40. package/src/RowItem/Translations/index.js +2 -0
  41. package/src/RowItem/index.js +74 -8
  42. package/src/RowItem/style.css +3 -4
  43. package/src/StatusBar/index.js +11 -4
  44. package/src/constants/dnaToColor.js +151 -0
  45. package/src/helperComponents/PinchHelper/PinchHelper.js +5 -1
  46. package/src/helperComponents/SelectDialog.js +5 -2
  47. package/src/style.css +2 -2
  48. package/src/utils/editorUtils.js +5 -3
  49. package/src/utils/getAlignedAminoAcidSequenceProps.js +379 -0
  50. package/src/withEditorInteractions/createSequenceInputPopup.js +15 -5
  51. package/src/withEditorInteractions/index.js +3 -1
  52. package/utils/editorUtils.d.ts +2 -1
  53. package/utils/getAlignedAminoAcidSequenceProps.d.ts +49 -0
package/index.es.js CHANGED
@@ -54,8 +54,8 @@ var __async = (__this, __arguments, generator) => {
54
54
  });
55
55
  };
56
56
  var _C, _D, _G, _J, _K, _R;
57
- import { Icon, Classes, Button, Intent, MenuItem, Keys, Tag, Popover, Tooltip, Spinner, Checkbox, Switch, Position, FormGroup, InputGroup, TextArea, EditableText, NumericInput, RadioGroup, Menu, Toaster, MenuDivider, ContextMenu, KeyCombo, useHotkeys, Callout, Dialog, Card, Tabs, Tab, Colors, HTMLSelect, AnchorButton, Slider as Slider$1, ButtonGroup, Label, ResizeSensor, FocusStyleManager } from "@blueprintjs/core";
58
- import * as React from "react";
57
+ import { Icon, Classes, Button, Intent, MenuItem, Keys, Tag, Popover, Tooltip, Spinner, Checkbox, Switch, Position, FormGroup, InputGroup, TextArea, EditableText, NumericInput, RadioGroup, Menu, Toaster, MenuDivider, KeyCombo, ContextMenu, useHotkeys, Callout, Dialog, Card, Tabs, Tab, Colors, HTMLSelect, AnchorButton, Slider as Slider$1, ButtonGroup, Label, ResizeSensor, FocusStyleManager } from "@blueprintjs/core";
58
+ import * as React$1 from "react";
59
59
  import React__default, { useState, useEffect, forwardRef as forwardRef$2, useImperativeHandle, Fragment, useMemo as useMemo$1, useRef, useReducer, useCallback as useCallback$1, createElement, Component, useLayoutEffect as useLayoutEffect$1, createContext as createContext$1, memo, useContext, isValidElement, PureComponent } from "react";
60
60
  import { formValueSelector, initialize, change, Field, reduxForm, SubmissionError, destroy as destroy$1, touch, FormName, reducer as reducer$4, getFormValues, FieldArray } from "redux-form";
61
61
  import ReactDOM, { unstable_batchedUpdates, createPortal, flushSync, render as render$2, findDOMNode, unmountComponentAtNode } from "react-dom";
@@ -12650,6 +12650,64 @@ const rectSortingStrategy = /* @__PURE__ */ __name((_ref) => {
12650
12650
  scaleY: newRect.height / oldRect.height
12651
12651
  };
12652
12652
  }, "rectSortingStrategy");
12653
+ const defaultScale$1 = {
12654
+ scaleX: 1,
12655
+ scaleY: 1
12656
+ };
12657
+ const verticalListSortingStrategy = /* @__PURE__ */ __name((_ref) => {
12658
+ var _rects$activeIndex;
12659
+ let {
12660
+ activeIndex,
12661
+ activeNodeRect: fallbackActiveRect,
12662
+ index: index2,
12663
+ rects,
12664
+ overIndex
12665
+ } = _ref;
12666
+ const activeNodeRect = (_rects$activeIndex = rects[activeIndex]) != null ? _rects$activeIndex : fallbackActiveRect;
12667
+ if (!activeNodeRect) {
12668
+ return null;
12669
+ }
12670
+ if (index2 === activeIndex) {
12671
+ const overIndexRect = rects[overIndex];
12672
+ if (!overIndexRect) {
12673
+ return null;
12674
+ }
12675
+ return __spreadValues({
12676
+ x: 0,
12677
+ y: activeIndex < overIndex ? overIndexRect.top + overIndexRect.height - (activeNodeRect.top + activeNodeRect.height) : overIndexRect.top - activeNodeRect.top
12678
+ }, defaultScale$1);
12679
+ }
12680
+ const itemGap = getItemGap$1(rects, index2, activeIndex);
12681
+ if (index2 > activeIndex && index2 <= overIndex) {
12682
+ return __spreadValues({
12683
+ x: 0,
12684
+ y: -activeNodeRect.height - itemGap
12685
+ }, defaultScale$1);
12686
+ }
12687
+ if (index2 < activeIndex && index2 >= overIndex) {
12688
+ return __spreadValues({
12689
+ x: 0,
12690
+ y: activeNodeRect.height + itemGap
12691
+ }, defaultScale$1);
12692
+ }
12693
+ return __spreadValues({
12694
+ x: 0,
12695
+ y: 0
12696
+ }, defaultScale$1);
12697
+ }, "verticalListSortingStrategy");
12698
+ function getItemGap$1(clientRects, index2, activeIndex) {
12699
+ const currentRect = clientRects[index2];
12700
+ const previousRect = clientRects[index2 - 1];
12701
+ const nextRect = clientRects[index2 + 1];
12702
+ if (!currentRect) {
12703
+ return 0;
12704
+ }
12705
+ if (activeIndex < index2) {
12706
+ return previousRect ? currentRect.top - (previousRect.top + previousRect.height) : nextRect ? nextRect.top - (currentRect.top + currentRect.height) : 0;
12707
+ }
12708
+ return nextRect ? nextRect.top - (currentRect.top + currentRect.height) : previousRect ? currentRect.top - (previousRect.top + previousRect.height) : 0;
12709
+ }
12710
+ __name(getItemGap$1, "getItemGap$1");
12653
12711
  const ID_PREFIX = "Sortable";
12654
12712
  const Context = /* @__PURE__ */ React__default.createContext({
12655
12713
  activeIndex: -1,
@@ -16620,6 +16678,7 @@ const ThComponent2 = /* @__PURE__ */ __name((_c) => {
16620
16678
  className,
16621
16679
  children,
16622
16680
  style: style2,
16681
+ path: path2,
16623
16682
  columnindex
16624
16683
  } = _d, rest = __objRest(_d, [
16625
16684
  "toggleSort",
@@ -16627,16 +16686,30 @@ const ThComponent2 = /* @__PURE__ */ __name((_c) => {
16627
16686
  "className",
16628
16687
  "children",
16629
16688
  "style",
16689
+ "path",
16630
16690
  "columnindex"
16631
16691
  ]);
16632
- const index2 = columnindex != null ? columnindex : -1;
16633
- const { attributes, listeners, setNodeRef, transform, transition } = useSortable({
16634
- id: `${index2}`,
16635
- disabled: immovable === "true"
16692
+ const index2 = columnindex ? path2 : -1;
16693
+ const disabled = !path2 || immovable === "true" || immovable === true;
16694
+ const {
16695
+ attributes,
16696
+ listeners,
16697
+ setNodeRef,
16698
+ transform,
16699
+ transition,
16700
+ isDragging: _isDragging
16701
+ } = useSortable({
16702
+ id: path2,
16703
+ disabled
16636
16704
  });
16705
+ const isDragging2 = _isDragging && !disabled;
16706
+ if (transform) {
16707
+ transform.scaleX = 1;
16708
+ }
16637
16709
  const sortStyles = {
16638
16710
  transform: CSS.Transform.toString(transform),
16639
- transition
16711
+ transition,
16712
+ zIndex: isDragging2 ? 999 : void 0
16640
16713
  };
16641
16714
  return /* @__PURE__ */ React__default.createElement(
16642
16715
  "div",
@@ -16644,11 +16717,12 @@ const ThComponent2 = /* @__PURE__ */ __name((_c) => {
16644
16717
  style: __spreadValues(__spreadValues({}, sortStyles), style2),
16645
16718
  ref: setNodeRef
16646
16719
  }, attributes), listeners), {
16647
- className: classNames("rt-th", className),
16720
+ className: classNames("rt-th", className, { "th-dragging": isDragging2 }),
16648
16721
  onClick: /* @__PURE__ */ __name((e) => toggleSort && toggleSort(e), "onClick"),
16649
16722
  role: "columnheader",
16650
16723
  tabIndex: "-1",
16651
16724
  columnindex,
16725
+ path: path2,
16652
16726
  index: index2
16653
16727
  }), rest),
16654
16728
  children
@@ -19560,36 +19634,49 @@ function tableQueryParamsToHasuraClauses({
19560
19634
  const uniqueFieldsByPath = {};
19561
19635
  const searchTerms = searchTerm.split(",");
19562
19636
  schema2.fields.forEach((field) => {
19563
- const { type: type2, path: path2, searchDisabled, isHidden } = field;
19564
- if (uniqueFieldsByPath[path2]) return;
19565
- uniqueFieldsByPath[path2] = true;
19566
- if (searchDisabled || field.filterDisabled || type2 === "color" || isHidden)
19567
- return;
19568
- searchTerms.forEach((term) => {
19569
- const filterValue = term.trim();
19570
- if (type2 === "string" || type2 === "lookup") {
19571
- const o2 = set$2({}, path2, { _ilike: `%${filterValue}%` });
19572
- searchTermFilters.push(o2);
19573
- } else if (type2 === "boolean") {
19574
- let regex;
19575
- try {
19576
- regex = new RegExp("^" + filterValue, "ig");
19577
- } catch (error) {
19578
- }
19579
- if (regex) {
19580
- if ("true".replace(regex, "") !== "true") {
19581
- const o2 = set$2({}, path2, { _eq: true });
19582
- searchTermFilters.push(o2);
19583
- } else if ("false".replace(regex, "") !== "false") {
19584
- const o2 = set$2({}, path2, { _eq: false });
19585
- searchTermFilters.push(o2);
19637
+ const {
19638
+ type: type2,
19639
+ path: path2,
19640
+ additionalSearchPaths = [],
19641
+ searchDisabled,
19642
+ isHidden
19643
+ } = field;
19644
+ const allPaths = [path2, ...additionalSearchPaths];
19645
+ allPaths.forEach((path22) => {
19646
+ addSearchTermFilters(path22);
19647
+ });
19648
+ function addSearchTermFilters(path22) {
19649
+ if (uniqueFieldsByPath[path22]) return;
19650
+ uniqueFieldsByPath[path22] = true;
19651
+ if (searchDisabled || field.filterDisabled || type2 === "color" || isHidden || !path22)
19652
+ return;
19653
+ searchTerms.forEach((term) => {
19654
+ const filterValue = term.trim();
19655
+ if (type2 === "string" || type2 === "lookup") {
19656
+ const o2 = set$2({}, path22, { _ilike: `%${filterValue}%` });
19657
+ searchTermFilters.push(o2);
19658
+ } else if (type2 === "boolean") {
19659
+ let regex;
19660
+ try {
19661
+ regex = new RegExp("^" + filterValue, "ig");
19662
+ } catch (error) {
19663
+ }
19664
+ if (regex) {
19665
+ if ("true".replace(regex, "") !== "true") {
19666
+ const o2 = set$2({}, path22, { _eq: true });
19667
+ searchTermFilters.push(o2);
19668
+ } else if ("false".replace(regex, "") !== "false") {
19669
+ const o2 = set$2({}, path22, { _eq: false });
19670
+ searchTermFilters.push(o2);
19671
+ }
19586
19672
  }
19673
+ } else if ((type2 === "number" || type2 === "integer") && !isNaN(filterValue)) {
19674
+ const o2 = set$2({}, path22, { _eq: parseFloat(filterValue) });
19675
+ searchTermFilters.push(o2);
19587
19676
  }
19588
- } else if ((type2 === "number" || type2 === "integer") && !isNaN(filterValue)) {
19589
- const o2 = set$2({}, path2, { _eq: parseFloat(filterValue) });
19590
- searchTermFilters.push(o2);
19591
- }
19592
- });
19677
+ });
19678
+ }
19679
+ __name(addSearchTermFilters, "addSearchTermFilters");
19593
19680
  });
19594
19681
  if (searchTermFilters.length > 0) {
19595
19682
  if (Object.keys(where).length > 0) {
@@ -19600,10 +19687,16 @@ function tableQueryParamsToHasuraClauses({
19600
19687
  }
19601
19688
  }
19602
19689
  if (filters && filters.length > 0) {
19603
- const filterClauses = filters.map((filter2) => {
19690
+ const filterClauses = flatMap(filters, (filter2) => {
19604
19691
  let { selectedFilter, filterOn, filterValue } = filter2;
19605
19692
  const fieldSchema = ccFields[filterOn] || {};
19606
- const { path: path2, reference: reference2, type: type2, customColumnFilter } = fieldSchema;
19693
+ const {
19694
+ path: path2,
19695
+ additionalSearchPaths = [],
19696
+ reference: reference2,
19697
+ type: type2,
19698
+ customColumnFilter
19699
+ } = fieldSchema;
19607
19700
  if (customColumnFilter) {
19608
19701
  return customColumnFilter(filterValue);
19609
19702
  }
@@ -19626,117 +19719,128 @@ function tableQueryParamsToHasuraClauses({
19626
19719
  }
19627
19720
  if (reference2) {
19628
19721
  filterOn = reference2.sourceField;
19722
+ return addColumnFilters(filterOn);
19629
19723
  } else {
19630
- filterOn = path2 || filterOn;
19724
+ if (path2) {
19725
+ const allPaths = [path2, ...additionalSearchPaths];
19726
+ return allPaths.map((p2) => addColumnFilters(p2));
19727
+ } else {
19728
+ return addColumnFilters(filterOn);
19729
+ }
19631
19730
  }
19632
- switch (selectedFilter) {
19633
- case "none":
19634
- return {};
19635
- case "startsWith":
19636
- return { [filterOn]: { _ilike: `${filterValue}%` } };
19637
- case "endsWith":
19638
- return { [filterOn]: { _ilike: `%${filterValue}` } };
19639
- case "contains":
19640
- return { [filterOn]: { _ilike: `%${filterValue}%` } };
19641
- case "notContains":
19642
- return { [filterOn]: { _nilike: `%${filterValue}%` } };
19643
- case "isExactly":
19644
- return { [filterOn]: { _eq: filterValue } };
19645
- case "isEmpty":
19646
- if (filterOn.includes(".")) {
19731
+ function addColumnFilters(filterOn2) {
19732
+ switch (selectedFilter) {
19733
+ case "none":
19734
+ return {};
19735
+ case "startsWith":
19736
+ return { [filterOn2]: { _ilike: `${filterValue}%` } };
19737
+ case "endsWith":
19738
+ return { [filterOn2]: { _ilike: `%${filterValue}` } };
19739
+ case "contains":
19740
+ return { [filterOn2]: { _ilike: `%${filterValue}%` } };
19741
+ case "notContains":
19742
+ return { [filterOn2]: { _nilike: `%${filterValue}%` } };
19743
+ case "isExactly":
19744
+ return { [filterOn2]: { _eq: filterValue } };
19745
+ case "isEmpty":
19746
+ if (filterOn2.includes(".")) {
19747
+ return {
19748
+ _not: {
19749
+ [filterOn2.split(".")[0]]: {}
19750
+ }
19751
+ };
19752
+ }
19647
19753
  return {
19648
- _not: {
19649
- [filterOn.split(".")[0]]: {}
19650
- }
19754
+ _or: [
19755
+ { [filterOn2]: { _eq: "" } },
19756
+ { [filterOn2]: { _is_null: true } }
19757
+ ]
19651
19758
  };
19652
- }
19653
- return {
19654
- _or: [
19655
- { [filterOn]: { _eq: "" } },
19656
- { [filterOn]: { _is_null: true } }
19657
- ]
19658
- };
19659
- case "notEmpty":
19660
- return {
19661
- _and: [
19662
- { [filterOn]: { _neq: "" } },
19663
- { [filterOn]: { _is_null: false } }
19664
- ]
19665
- };
19666
- case "inList":
19667
- return { [filterOn]: { _in: filterValue } };
19668
- case "notInList":
19669
- return { [filterOn]: { _nin: filterValue } };
19670
- case "true":
19671
- return { [filterOn]: { _eq: true } };
19672
- case "false":
19673
- return { [filterOn]: { _eq: false } };
19674
- case "dateIs":
19675
- return { [filterOn]: { _eq: filterValue } };
19676
- case "notBetween":
19677
- return {
19678
- _or: [
19679
- {
19680
- [filterOn]: {
19681
- _lt: new Date(arrayFilterValue[0])
19682
- }
19683
- },
19684
- {
19685
- [filterOn]: {
19686
- _gt: new Date(new Date(arrayFilterValue[1]).setHours(23, 59))
19759
+ case "notEmpty":
19760
+ return {
19761
+ _and: [
19762
+ { [filterOn2]: { _neq: "" } },
19763
+ { [filterOn2]: { _is_null: false } }
19764
+ ]
19765
+ };
19766
+ case "inList":
19767
+ return { [filterOn2]: { _in: filterValue } };
19768
+ case "notInList":
19769
+ return { [filterOn2]: { _nin: filterValue } };
19770
+ case "true":
19771
+ return { [filterOn2]: { _eq: true } };
19772
+ case "false":
19773
+ return { [filterOn2]: { _eq: false } };
19774
+ case "dateIs":
19775
+ return { [filterOn2]: { _eq: filterValue } };
19776
+ case "notBetween":
19777
+ return {
19778
+ _or: [
19779
+ {
19780
+ [filterOn2]: {
19781
+ _lt: new Date(arrayFilterValue[0])
19782
+ }
19783
+ },
19784
+ {
19785
+ [filterOn2]: {
19786
+ _gt: new Date(
19787
+ new Date(arrayFilterValue[1]).setHours(23, 59)
19788
+ )
19789
+ }
19687
19790
  }
19791
+ ]
19792
+ };
19793
+ case "isBetween":
19794
+ return {
19795
+ [filterOn2]: {
19796
+ _gte: new Date(arrayFilterValue[0]),
19797
+ _lte: new Date(new Date(arrayFilterValue[1]).setHours(23, 59))
19688
19798
  }
19689
- ]
19690
- };
19691
- case "isBetween":
19692
- return {
19693
- [filterOn]: {
19694
- _gte: new Date(arrayFilterValue[0]),
19695
- _lte: new Date(new Date(arrayFilterValue[1]).setHours(23, 59))
19696
- }
19697
- };
19698
- case "isBefore":
19699
- return { [filterOn]: { _lt: new Date(filterValue) } };
19700
- case "isAfter":
19701
- return { [filterOn]: { _gt: new Date(filterValue) } };
19702
- case "greaterThan":
19703
- return { [filterOn]: { _gt: parseFloat(filterValue) } };
19704
- case "lessThan":
19705
- return { [filterOn]: { _lt: parseFloat(filterValue) } };
19706
- case "inRange":
19707
- return {
19708
- [filterOn]: {
19709
- _gte: parseFloat(arrayFilterValue[0]),
19710
- _lte: parseFloat(arrayFilterValue[1])
19711
- }
19712
- };
19713
- case "outsideRange":
19714
- return {
19715
- _or: [
19716
- {
19717
- [filterOn]: {
19718
- _lt: parseFloat(arrayFilterValue[0])
19719
- }
19720
- },
19721
- {
19722
- [filterOn]: {
19723
- _gt: parseFloat(arrayFilterValue[1])
19799
+ };
19800
+ case "isBefore":
19801
+ return { [filterOn2]: { _lt: new Date(filterValue) } };
19802
+ case "isAfter":
19803
+ return { [filterOn2]: { _gt: new Date(filterValue) } };
19804
+ case "greaterThan":
19805
+ return { [filterOn2]: { _gt: parseFloat(filterValue) } };
19806
+ case "lessThan":
19807
+ return { [filterOn2]: { _lt: parseFloat(filterValue) } };
19808
+ case "inRange":
19809
+ return {
19810
+ [filterOn2]: {
19811
+ _gte: parseFloat(arrayFilterValue[0]),
19812
+ _lte: parseFloat(arrayFilterValue[1])
19813
+ }
19814
+ };
19815
+ case "outsideRange":
19816
+ return {
19817
+ _or: [
19818
+ {
19819
+ [filterOn2]: {
19820
+ _lt: parseFloat(arrayFilterValue[0])
19821
+ }
19822
+ },
19823
+ {
19824
+ [filterOn2]: {
19825
+ _gt: parseFloat(arrayFilterValue[1])
19826
+ }
19724
19827
  }
19828
+ ]
19829
+ };
19830
+ case "equalTo":
19831
+ return {
19832
+ [filterOn2]: {
19833
+ _eq: type2 === "number" || type2 === "integer" ? parseFloat(filterValue) : filterValue
19725
19834
  }
19726
- ]
19727
- };
19728
- case "equalTo":
19729
- return {
19730
- [filterOn]: {
19731
- _eq: type2 === "number" || type2 === "integer" ? parseFloat(filterValue) : filterValue
19732
- }
19733
- };
19734
- case "regex":
19735
- return { [filterOn]: { _regex: filterValue } };
19736
- default:
19737
- console.warn(`Unsupported filter type: ${selectedFilter}`);
19738
- return {};
19835
+ };
19836
+ case "regex":
19837
+ return { [filterOn2]: { _regex: filterValue } };
19838
+ default:
19839
+ console.warn(`Unsupported filter type: ${selectedFilter}`);
19840
+ return {};
19841
+ }
19739
19842
  }
19843
+ __name(addColumnFilters, "addColumnFilters");
19740
19844
  });
19741
19845
  if (filterClauses.length > 0) {
19742
19846
  if (Object.keys(where).length > 0) {
@@ -20259,10 +20363,15 @@ function getQueryParams({
20259
20363
  const ccDisplayName = orderVal.replace(/^-/gi, "");
20260
20364
  const schemaForField = ccFields[ccDisplayName];
20261
20365
  if (schemaForField) {
20262
- const { path: path2 } = schemaForField;
20366
+ const { path: path2, additionalSearchPaths } = schemaForField;
20263
20367
  const reversed = ccDisplayName !== orderVal;
20264
20368
  const prefix2 = reversed ? "-" : "";
20265
20369
  cleanedOrder.push(prefix2 + path2);
20370
+ if (additionalSearchPaths && additionalSearchPaths.length) {
20371
+ additionalSearchPaths.forEach((additionalPath) => {
20372
+ cleanedOrder.push(prefix2 + additionalPath);
20373
+ });
20374
+ }
20266
20375
  } else {
20267
20376
  !noOrderError && console.error(
20268
20377
  "No schema for field found!",
@@ -30315,19 +30424,19 @@ function dequal(foo, bar) {
30315
30424
  }
30316
30425
  __name(dequal, "dequal");
30317
30426
  function useDeepCompareMemoize(value) {
30318
- var ref2 = React.useRef(value);
30319
- var signalRef = React.useRef(0);
30427
+ var ref2 = React$1.useRef(value);
30428
+ var signalRef = React$1.useRef(0);
30320
30429
  if (!dequal(value, ref2.current)) {
30321
30430
  ref2.current = value;
30322
30431
  signalRef.current += 1;
30323
30432
  }
30324
- return React.useMemo(function() {
30433
+ return React$1.useMemo(function() {
30325
30434
  return ref2.current;
30326
30435
  }, [signalRef.current]);
30327
30436
  }
30328
30437
  __name(useDeepCompareMemoize, "useDeepCompareMemoize");
30329
30438
  function useDeepCompareEffect(callback2, dependencies) {
30330
- return React.useEffect(callback2, useDeepCompareMemoize(dependencies));
30439
+ return React$1.useEffect(callback2, useDeepCompareMemoize(dependencies));
30331
30440
  }
30332
30441
  __name(useDeepCompareEffect, "useDeepCompareEffect");
30333
30442
  var fuzzysearch_1;
@@ -32596,6 +32705,7 @@ const _TgSelect = class _TgSelect extends React__default.Component {
32596
32705
  }
32597
32706
  }, "onKeyDown"),
32598
32707
  inputProps: __spreadValues({
32708
+ autoComplete: "off",
32599
32709
  name: "tg-multiselect-input",
32600
32710
  autoFocus: autoFocus || autoOpen,
32601
32711
  onBlur
@@ -34209,6 +34319,159 @@ const SearchBar = /* @__PURE__ */ __name(({
34209
34319
  })
34210
34320
  );
34211
34321
  }, "SearchBar");
34322
+ const restrictToHorizontalAxis = /* @__PURE__ */ __name((_ref) => {
34323
+ let {
34324
+ transform
34325
+ } = _ref;
34326
+ return __spreadProps(__spreadValues({}, transform), {
34327
+ y: 0
34328
+ });
34329
+ }, "restrictToHorizontalAxis");
34330
+ const restrictToVerticalAxis = /* @__PURE__ */ __name((_ref) => {
34331
+ let {
34332
+ transform
34333
+ } = _ref;
34334
+ return __spreadProps(__spreadValues({}, transform), {
34335
+ x: 0
34336
+ });
34337
+ }, "restrictToVerticalAxis");
34338
+ const DraggableColumnOption = /* @__PURE__ */ __name(({
34339
+ field,
34340
+ index: index2,
34341
+ onVisibilityChange,
34342
+ numVisible
34343
+ }) => {
34344
+ const { displayName, isHidden, path: path2, subFrag, immovable, type: type2 } = field;
34345
+ const { attributes, listeners, setNodeRef, transform, transition } = useSortable({
34346
+ id: path2,
34347
+ disabled: immovable === "true"
34348
+ });
34349
+ if (type2 === "action") {
34350
+ return null;
34351
+ }
34352
+ const style2 = {
34353
+ transform: CSS.Transform.toString(transform),
34354
+ transition,
34355
+ cursor: "grab",
34356
+ marginBottom: 5
34357
+ };
34358
+ return /* @__PURE__ */ React__default.createElement(
34359
+ "div",
34360
+ __spreadValues(__spreadValues({
34361
+ ref: setNodeRef,
34362
+ style: style2,
34363
+ className: "SortableItem",
34364
+ "data-path": path2
34365
+ }, attributes), listeners),
34366
+ /* @__PURE__ */ React__default.createElement(
34367
+ Checkbox,
34368
+ {
34369
+ name: `${path2}-${index2}`,
34370
+ key: index2,
34371
+ onChange: /* @__PURE__ */ __name(() => {
34372
+ if (numVisible <= 1 && !isHidden) {
34373
+ return window.toastr.warning(
34374
+ "We have to display at least one column :)"
34375
+ );
34376
+ }
34377
+ onVisibilityChange({ shouldShow: isHidden, path: path2 });
34378
+ }, "onChange"),
34379
+ checked: !isHidden,
34380
+ label: /* @__PURE__ */ React__default.createElement("span", { style: { display: "flex", marginTop: -17 } }, displayName, " ", field.fieldGroup && /* @__PURE__ */ React__default.createElement(
34381
+ "span",
34382
+ {
34383
+ style: { fontSize: 10, marginLeft: 5, marginTop: 2 },
34384
+ className: Classes.TEXT_MUTED
34385
+ },
34386
+ "(",
34387
+ field.fieldGroup,
34388
+ ")"
34389
+ ), subFrag && /* @__PURE__ */ React__default.createElement(InfoHelper, { style: { marginLeft: 5 } }, "Note: Viewing this complex column may cause the table to load slower. Try hiding it for better performance."))
34390
+ }
34391
+ )
34392
+ );
34393
+ }, "DraggableColumnOption");
34394
+ const DraggableColumnOptions = /* @__PURE__ */ __name(({
34395
+ fields,
34396
+ onVisibilityChange,
34397
+ moveColumnPersist,
34398
+ numVisible
34399
+ }) => {
34400
+ const [sortedFields, setSortedFields] = useState(fields);
34401
+ useEffect(() => {
34402
+ setSortedFields(fields);
34403
+ }, [fields]);
34404
+ const mouseSensor = useSensor(MouseSensor, {
34405
+ activationConstraint: {
34406
+ distance: 5
34407
+ }
34408
+ });
34409
+ const sensors = useSensors(mouseSensor);
34410
+ const handleDragStart = /* @__PURE__ */ __name((event) => {
34411
+ document.body.classList.add("column-dragging");
34412
+ const { active: active2 } = event;
34413
+ if (active2) {
34414
+ const activeNode = document.querySelector(`[data-path="${active2.id}"]`);
34415
+ if (activeNode) {
34416
+ activeNode.classList.add("dragging");
34417
+ }
34418
+ }
34419
+ }, "handleDragStart");
34420
+ const handleDragEnd = /* @__PURE__ */ __name((event) => {
34421
+ document.body.classList.remove("column-dragging");
34422
+ const draggingItem = document.querySelector(".SortableItem.dragging");
34423
+ if (draggingItem) {
34424
+ draggingItem.classList.remove("dragging");
34425
+ }
34426
+ const { active: active2, over } = event;
34427
+ if (!over || !active2 || active2.id === over.id) {
34428
+ return;
34429
+ }
34430
+ const oldIndex = sortedFields.findIndex((f2) => f2.path === active2.id);
34431
+ const newIndex = sortedFields.findIndex((f2) => f2.path === over.id);
34432
+ const newSortedFields = arrayMove(sortedFields, oldIndex, newIndex);
34433
+ setSortedFields(newSortedFields);
34434
+ moveColumnPersist({ oldIndex, newIndex });
34435
+ }, "handleDragEnd");
34436
+ return /* @__PURE__ */ React__default.createElement(
34437
+ DndContext,
34438
+ {
34439
+ sensors,
34440
+ modifiers: [restrictToVerticalAxis],
34441
+ onDragStart: handleDragStart,
34442
+ onDragEnd: handleDragEnd
34443
+ },
34444
+ /* @__PURE__ */ React__default.createElement(
34445
+ SortableContext,
34446
+ {
34447
+ items: sortedFields.map((field) => field.path),
34448
+ strategy: verticalListSortingStrategy
34449
+ },
34450
+ /* @__PURE__ */ React__default.createElement("div", null, sortedFields.map((field, index2) => /* @__PURE__ */ React__default.createElement(
34451
+ DraggableColumnOption,
34452
+ {
34453
+ key: field.path || index2,
34454
+ field,
34455
+ index: index2,
34456
+ onVisibilityChange,
34457
+ numVisible
34458
+ }
34459
+ )))
34460
+ )
34461
+ );
34462
+ }, "DraggableColumnOptions");
34463
+ const dragNoticeEl = /* @__PURE__ */ React.createElement(
34464
+ "div",
34465
+ {
34466
+ className: Classes.TEXT_MUTED,
34467
+ style: {
34468
+ padding: 10,
34469
+ fontSize: "12px"
34470
+ }
34471
+ },
34472
+ /* @__PURE__ */ React.createElement(Icon, { icon: "info-sign", size: 12 }),
34473
+ " Drag columns to reorder them"
34474
+ );
34212
34475
  const DisplayOptions = /* @__PURE__ */ __name(({
34213
34476
  compact,
34214
34477
  extraCompact,
@@ -34218,13 +34481,13 @@ const DisplayOptions = /* @__PURE__ */ __name(({
34218
34481
  resetDefaultVisibility = noop$8,
34219
34482
  updateColumnVisibility = noop$8,
34220
34483
  updateTableDisplayDensity,
34484
+ moveColumnPersist = noop$8,
34221
34485
  showForcedHiddenColumns,
34222
34486
  setShowForcedHidden,
34223
34487
  hasOptionForForcedHidden,
34224
34488
  schema: schema2
34225
34489
  }) => {
34226
34490
  const [isOpen, setIsOpen] = useState(false);
34227
- const [searchTerms, setSearchTerms] = useState({});
34228
34491
  const changeTableDensity = /* @__PURE__ */ __name((e) => {
34229
34492
  updateTableDisplayDensity(e.target.value);
34230
34493
  setIsOpen(false);
@@ -34234,85 +34497,10 @@ const DisplayOptions = /* @__PURE__ */ __name(({
34234
34497
  return null;
34235
34498
  }
34236
34499
  const { fields } = schema2;
34237
- const fieldGroups = {};
34238
- const mainFields = [];
34500
+ let numVisible = 0;
34239
34501
  fields.forEach((field) => {
34240
- if (field.hideInMenu) return;
34241
- if (!field.fieldGroup) return mainFields.push(field);
34242
- if (!fieldGroups[field.fieldGroup]) fieldGroups[field.fieldGroup] = [];
34243
- fieldGroups[field.fieldGroup].push(field);
34502
+ if (!field.isHidden && field.type !== "action") numVisible++;
34244
34503
  });
34245
- let numVisible = 0;
34246
- const getFieldCheckbox = /* @__PURE__ */ __name((field, i) => {
34247
- const { displayName, isHidden, isForcedHidden, path: path2, subFrag } = field;
34248
- if (isForcedHidden) return;
34249
- if (!isHidden) numVisible++;
34250
- return /* @__PURE__ */ React__default.createElement(
34251
- Checkbox,
34252
- {
34253
- name: `${path2}-${i}`,
34254
- key: path2 || i,
34255
- onChange: /* @__PURE__ */ __name(() => {
34256
- if (numVisible <= 1 && !isHidden) {
34257
- return window.toastr.warning(
34258
- "We have to display at least one column :)"
34259
- );
34260
- }
34261
- updateColumnVisibility({ shouldShow: isHidden, path: path2 });
34262
- }, "onChange"),
34263
- checked: !isHidden,
34264
- label: /* @__PURE__ */ React__default.createElement("span", { style: { display: "flex", marginTop: -17 } }, displayName, subFrag && /* @__PURE__ */ React__default.createElement(
34265
- InfoHelper,
34266
- {
34267
- icon: "warning-sign",
34268
- intent: "warning",
34269
- style: { marginLeft: 5 }
34270
- },
34271
- "Viewing this column may cause the table to load slower"
34272
- ))
34273
- }
34274
- );
34275
- }, "getFieldCheckbox");
34276
- let fieldGroupMenu;
34277
- if (!isEmpty$1(fieldGroups)) {
34278
- fieldGroupMenu = map$3(fieldGroups, (groupFields, groupName) => {
34279
- const searchTerm = searchTerms[groupName] || "";
34280
- const anyVisible = groupFields.some(
34281
- (field) => !field.isHidden && !field.isForcedHidden
34282
- );
34283
- const anyNotForcedHidden = groupFields.some(
34284
- (field) => !field.isForcedHidden
34285
- );
34286
- if (!anyNotForcedHidden) return;
34287
- return /* @__PURE__ */ React__default.createElement(MenuItem, { key: groupName, text: groupName }, /* @__PURE__ */ React__default.createElement(
34288
- InputGroup,
34289
- {
34290
- leftIcon: "search",
34291
- value: searchTerm,
34292
- onChange: /* @__PURE__ */ __name((e) => {
34293
- setSearchTerms((prev) => __spreadProps(__spreadValues({}, prev), {
34294
- [groupName]: e.target.value
34295
- }));
34296
- }, "onChange")
34297
- }
34298
- ), /* @__PURE__ */ React__default.createElement(
34299
- Button,
34300
- {
34301
- className: Classes.MINIMAL,
34302
- text: (anyVisible ? "Hide" : "Show") + " All",
34303
- style: { margin: "10px 0" },
34304
- onClick: /* @__PURE__ */ __name(() => {
34305
- updateColumnVisibility({
34306
- shouldShow: !anyVisible,
34307
- paths: groupFields.map((field) => field.path)
34308
- });
34309
- }, "onClick")
34310
- }
34311
- ), groupFields.filter(
34312
- (field) => startCase(getCCDisplayName(field)).toLowerCase().indexOf(searchTerm.toLowerCase()) > -1
34313
- ).map(getFieldCheckbox));
34314
- });
34315
- }
34316
34504
  return /* @__PURE__ */ React__default.createElement(
34317
34505
  Popover,
34318
34506
  {
@@ -34339,14 +34527,22 @@ const DisplayOptions = /* @__PURE__ */ __name(({
34339
34527
  {
34340
34528
  style: {
34341
34529
  fontWeight: "bold",
34342
- marginBottom: 10,
34530
+ marginBottom: 0,
34343
34531
  marginTop: 10,
34344
34532
  display: "flex"
34345
34533
  }
34346
34534
  },
34347
34535
  "Displayed Columns:  ",
34348
34536
  doNotSearchHiddenColumns && /* @__PURE__ */ React__default.createElement(InfoHelper, null, "Note: Hidden columns will NOT be used when searching the datatable")
34349
- ), /* @__PURE__ */ React__default.createElement("div", { style: { maxHeight: 260, overflowY: "auto", padding: 2 } }, mainFields.map(getFieldCheckbox)), /* @__PURE__ */ React__default.createElement("div", null, fieldGroupMenu), hasOptionForForcedHidden && /* @__PURE__ */ React__default.createElement("div", { style: { marginTop: 15 } }, /* @__PURE__ */ React__default.createElement(
34537
+ ), dragNoticeEl, /* @__PURE__ */ React__default.createElement("div", { style: { maxHeight: 360, overflowY: "auto", padding: 2 } }, /* @__PURE__ */ React__default.createElement(
34538
+ DraggableColumnOptions,
34539
+ {
34540
+ fields,
34541
+ onVisibilityChange: updateColumnVisibility,
34542
+ moveColumnPersist,
34543
+ numVisible
34544
+ }
34545
+ )), hasOptionForForcedHidden && /* @__PURE__ */ React__default.createElement("div", { style: { marginTop: 15 } }, /* @__PURE__ */ React__default.createElement(
34350
34546
  Switch,
34351
34547
  {
34352
34548
  label: "Show Empty Columns",
@@ -34354,24 +34550,15 @@ const DisplayOptions = /* @__PURE__ */ __name(({
34354
34550
  onChange: toggleForcedHidden
34355
34551
  }
34356
34552
  )), /* @__PURE__ */ React__default.createElement(
34357
- "div",
34553
+ Button,
34358
34554
  {
34359
- style: {
34360
- width: "100%",
34361
- display: "flex",
34362
- justifyContent: "flex-end"
34363
- }
34555
+ style: { marginTop: 5 },
34556
+ onClick: resetDefaultVisibility,
34557
+ title: "Display Options",
34558
+ icon: "reset",
34559
+ minimal: true
34364
34560
  },
34365
- /* @__PURE__ */ React__default.createElement(
34366
- Button,
34367
- {
34368
- onClick: resetDefaultVisibility,
34369
- title: "Display Options",
34370
- icon: "reset",
34371
- minimal: true
34372
- },
34373
- "Reset Column Visibilites"
34374
- )
34561
+ "Reset Column Visibilites"
34375
34562
  )))
34376
34563
  },
34377
34564
  /* @__PURE__ */ React__default.createElement(
@@ -34398,22 +34585,22 @@ function DisabledLoadingComponent({ disabled, loading, loadingText }) {
34398
34585
  );
34399
34586
  }
34400
34587
  __name(DisabledLoadingComponent, "DisabledLoadingComponent");
34401
- const restrictToHorizontalAxis = /* @__PURE__ */ __name((_ref) => {
34402
- let {
34403
- transform
34404
- } = _ref;
34405
- return __spreadProps(__spreadValues({}, transform), {
34406
- y: 0
34407
- });
34408
- }, "restrictToHorizontalAxis");
34409
34588
  const CustomTheadComponent = /* @__PURE__ */ __name(({
34410
34589
  children: _children,
34411
34590
  className,
34412
- onSortEnd,
34413
- onSortStart,
34591
+ moveColumn,
34592
+ sortedItemsFull,
34414
34593
  style: style2
34415
34594
  }) => {
34416
34595
  const children = _children.props.children;
34596
+ const [sortedItems, setSortedItems] = useState(
34597
+ () => children.map((c2) => {
34598
+ return c2.props.path || c2.key.split("-")[1];
34599
+ })
34600
+ );
34601
+ useEffect(() => {
34602
+ setSortedItems(children.map((c2) => c2.props.path || c2.key.split("-")[1]));
34603
+ }, [children]);
34417
34604
  const mouseSensor = useSensor(MouseSensor, {
34418
34605
  activationConstraint: {
34419
34606
  distance: 10
@@ -34428,15 +34615,17 @@ const CustomTheadComponent = /* @__PURE__ */ __name(({
34428
34615
  if (active2.id === over.id) {
34429
34616
  return;
34430
34617
  }
34431
- onSortEnd({
34432
- oldIndex: parseInt(active2.id),
34433
- newIndex: parseInt(over.id)
34434
- });
34618
+ const oldPath = active2.id;
34619
+ const newPath = over.id;
34620
+ const oldIndex = sortedItemsFull.indexOf(oldPath);
34621
+ const newIndex = sortedItemsFull.indexOf(newPath);
34622
+ const newSortedItems = arrayMove(sortedItemsFull, oldIndex, newIndex);
34623
+ setSortedItems(newSortedItems);
34624
+ moveColumn({ oldIndex, newIndex });
34435
34625
  }, "handleDragEnd");
34436
34626
  return /* @__PURE__ */ React__default.createElement(
34437
34627
  DndContext,
34438
34628
  {
34439
- onDragStart: onSortStart,
34440
34629
  onDragEnd: handleDragEnd,
34441
34630
  modifiers: [restrictToHorizontalAxis],
34442
34631
  sensors
@@ -34444,36 +34633,31 @@ const CustomTheadComponent = /* @__PURE__ */ __name(({
34444
34633
  /* @__PURE__ */ React__default.createElement("div", { className: "rt-thead " + className, style: style2 }, /* @__PURE__ */ React__default.createElement("div", { className: "rt-tr" }, /* @__PURE__ */ React__default.createElement(
34445
34634
  SortableContext,
34446
34635
  {
34447
- items: children.map((_2, index2) => `${index2}`),
34636
+ items: sortedItems,
34448
34637
  strategy: horizontalListSortingStrategy
34449
34638
  },
34450
34639
  children
34451
34640
  )))
34452
34641
  );
34453
34642
  }, "CustomTheadComponent");
34454
- const SortableColumns = /* @__PURE__ */ __name(({ className, style: style2, children, moveColumn }) => {
34643
+ const SortableColumns = /* @__PURE__ */ __name(({
34644
+ className,
34645
+ style: style2,
34646
+ children,
34647
+ moveColumn,
34648
+ sortedItemsFull
34649
+ }) => {
34455
34650
  const shouldCancelStart = /* @__PURE__ */ __name((e) => {
34456
34651
  const className2 = e.target.className;
34457
34652
  return e.target instanceof SVGElement || className2.indexOf("rt-resizer") > -1;
34458
34653
  }, "shouldCancelStart");
34459
- const onSortEnd = /* @__PURE__ */ __name((...args) => {
34460
- const { oldIndex, newIndex } = args[0];
34461
- document.body.classList.remove("drag-active");
34462
- moveColumn({
34463
- oldIndex,
34464
- newIndex
34465
- });
34466
- }, "onSortEnd");
34467
- const onSortStart = /* @__PURE__ */ __name(() => {
34468
- document.body.classList.add("drag-active");
34469
- }, "onSortStart");
34470
34654
  return /* @__PURE__ */ React__default.createElement(
34471
34655
  CustomTheadComponent,
34472
34656
  {
34473
34657
  className,
34474
34658
  style: style2,
34475
- onSortStart,
34476
- onSortEnd,
34659
+ sortedItemsFull,
34660
+ moveColumn,
34477
34661
  helperClass: "above-dialog",
34478
34662
  shouldCancelStart
34479
34663
  },
@@ -36913,7 +37097,6 @@ __name(getTableConfigFromStorage, "getTableConfigFromStorage");
36913
37097
  const viewColumn = {
36914
37098
  width: 35,
36915
37099
  noEllipsis: true,
36916
- hideInMenu: true,
36917
37100
  immovable: true,
36918
37101
  type: "action",
36919
37102
  render: /* @__PURE__ */ __name(() => {
@@ -51427,6 +51610,7 @@ const RenderColumnHeader = /* @__PURE__ */ __name(({
51427
51610
  e.persist();
51428
51611
  showContextMenu(
51429
51612
  [
51613
+ dragNoticeEl,
51430
51614
  {
51431
51615
  text: "Hide Column",
51432
51616
  disabled: onlyOneVisibleColumn,
@@ -52104,7 +52288,10 @@ const useColumns = /* @__PURE__ */ __name(({
52104
52288
  }, "getProps")
52105
52289
  });
52106
52290
  }
52107
- const tableColumns = columns.map((column) => {
52291
+ const tableColumns = flatMap(columns, (column) => {
52292
+ if (column.isHidden) {
52293
+ return [];
52294
+ }
52108
52295
  const tableColumn = __spreadProps(__spreadValues({}, column), {
52109
52296
  Header: RenderColumnHeader({
52110
52297
  onlyOneVisibleColumn: columns.length === 1,
@@ -52136,8 +52323,9 @@ const useColumns = /* @__PURE__ */ __name(({
52136
52323
  getHeaderProps: /* @__PURE__ */ __name(() => ({
52137
52324
  // needs to be a string because it is getting passed
52138
52325
  // to the dom
52139
- immovable: column.immovable ? "true" : "false",
52140
- columnindex: column.columnIndex
52326
+ immovable: column.type === "action" || column.immovable ? "true" : "false",
52327
+ columnindex: column.columnIndex,
52328
+ path: column.path
52141
52329
  }), "getHeaderProps")
52142
52330
  });
52143
52331
  const noEllipsis = column.noEllipsis;
@@ -56345,7 +56533,6 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56345
56533
  "anyTouched",
56346
56534
  "blur"
56347
56535
  ]);
56348
- var _a2;
56349
56536
  if (isTableParamsConnected && _tableParams && !_tableParams.entities) {
56350
56537
  throw new Error(
56351
56538
  `No entities array detected in tableParams object (<DataTable {...tableParams}/>). You need to call withQuery() after withTableParams() like: compose(withTableParams(), withQuery(something)).`
@@ -56425,12 +56612,11 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56425
56612
  const {
56426
56613
  doNotCoercePageSize,
56427
56614
  isInfinite = isSimple && !withPaging,
56428
- syncDisplayOptionsToDb,
56429
56615
  urlConnected,
56430
56616
  withSelectedEntities: withSelectedEntities2
56431
56617
  } = props;
56432
56618
  const defaults2 = useMemo$1(() => {
56433
- var _a3;
56619
+ var _a2;
56434
56620
  const _defaults = __spreadValues({
56435
56621
  pageSize: controlled_pageSize || 25,
56436
56622
  order: [],
@@ -56446,11 +56632,11 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56446
56632
  // }
56447
56633
  ]
56448
56634
  }, props.defaults || {});
56449
- if (isLocalCall && orderByFirstColumn && !((_a3 = _defaults == null ? void 0 : _defaults.order) == null ? void 0 : _a3.length)) {
56635
+ if (isLocalCall && orderByFirstColumn && !((_a2 = _defaults == null ? void 0 : _defaults.order) == null ? void 0 : _a2.length)) {
56450
56636
  const r2 = [getCCDisplayName(convertedSchema.fields[0])];
56451
56637
  _defaults.order = r2;
56452
56638
  }
56453
- if (!syncDisplayOptionsToDb && userSetPageSize) {
56639
+ if (userSetPageSize) {
56454
56640
  _defaults.pageSize = userSetPageSize;
56455
56641
  }
56456
56642
  return _defaults;
@@ -56460,7 +56646,6 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56460
56646
  isLocalCall,
56461
56647
  orderByFirstColumn,
56462
56648
  props.defaults,
56463
- syncDisplayOptionsToDb,
56464
56649
  userSetPageSize
56465
56650
  ]);
56466
56651
  const selectedEntities = withSelectedEntities2 ? getRecordsFromIdMap(reduxFormSelectedEntityIdMap) : void 0;
@@ -56558,8 +56743,6 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56558
56743
  controlled_setPage,
56559
56744
  controlled_setPageSize,
56560
56745
  controlled_total,
56561
- currentUser,
56562
- deleteTableConfiguration,
56563
56746
  disabled = false,
56564
56747
  disableSetPageSize,
56565
56748
  doNotShowEmptyRows,
@@ -56629,15 +56812,13 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56629
56812
  setPageSize = noop$8,
56630
56813
  setSearchTerm = noop$8,
56631
56814
  shouldShowSubComponent,
56632
- showCount = false,
56815
+ showCount = true,
56633
56816
  style: style2 = {},
56634
56817
  SubComponent,
56635
56818
  subHeader,
56636
56819
  tableConfigurations,
56637
56820
  tableName,
56638
56821
  topLeftItems,
56639
- upsertFieldOption,
56640
- upsertTableConfiguration,
56641
56822
  variables,
56642
56823
  withCheckboxes = false,
56643
56824
  withDisplayOptions,
@@ -56694,11 +56875,7 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56694
56875
  useEffect(() => {
56695
56876
  if (withDisplayOptions) {
56696
56877
  let newTableConfig = {};
56697
- if (syncDisplayOptionsToDb) {
56698
- newTableConfig = tableConfigurations && tableConfigurations[0];
56699
- } else {
56700
- newTableConfig = getTableConfigFromStorage(formName);
56701
- }
56878
+ newTableConfig = getTableConfigFromStorage(formName);
56702
56879
  setTableConfig((prev) => {
56703
56880
  if (!newTableConfig) {
56704
56881
  newTableConfig = {
@@ -56719,7 +56896,6 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56719
56896
  // If the schema changes we want to take into account the synced tableConfig again
56720
56897
  formName,
56721
56898
  setTableConfig,
56722
- syncDisplayOptionsToDb,
56723
56899
  tableConfigurations,
56724
56900
  withDisplayOptions,
56725
56901
  noExcessiveCheck
@@ -56767,8 +56943,7 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56767
56943
  }
56768
56944
  if (noValsForField && entities.length) {
56769
56945
  return __spreadProps(__spreadValues({}, field), {
56770
- isHidden: true,
56771
- isForcedHidden: true
56946
+ isHidden: true
56772
56947
  });
56773
56948
  } else if (fieldOpt) {
56774
56949
  return __spreadProps(__spreadValues({}, field), {
@@ -56822,6 +56997,7 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56822
56997
  withDisplayOptions,
56823
56998
  recordIdToIsVisibleMap
56824
56999
  ]);
57000
+ const [columns, setColumns] = useState([]);
56825
57001
  const {
56826
57002
  moveColumnPersist,
56827
57003
  persistPageSize,
@@ -56838,69 +57014,37 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56838
57014
  let resizePersist2 = noop$8;
56839
57015
  if (withDisplayOptions) {
56840
57016
  const fieldOptsByPath = keyBy(tableConfig.fieldOptions, "path");
56841
- if (syncDisplayOptionsToDb) {
56842
- let tableConfigurationId;
56843
- resetDefaultVisibility2 = /* @__PURE__ */ __name(function() {
56844
- tableConfigurationId = tableConfig.id;
56845
- if (tableConfigurationId) {
56846
- deleteTableConfiguration(tableConfigurationId);
56847
- }
56848
- }, "resetDefaultVisibility2");
56849
- updateColumnVisibility2 = /* @__PURE__ */ __name(function({ shouldShow, path: path2 }) {
56850
- if (tableConfigurationId) {
56851
- const existingFieldOpt = fieldOptsByPath[path2] || {};
56852
- upsertFieldOption({
56853
- id: existingFieldOpt.id,
56854
- path: path2,
56855
- isHidden: !shouldShow,
56856
- tableConfigurationId
56857
- });
56858
- } else {
56859
- upsertTableConfiguration({
56860
- userId: currentUser.user.id,
56861
- formName,
56862
- fieldOptions: [
56863
- {
56864
- path: path2,
56865
- isHidden: !shouldShow
56866
- }
56867
- ]
56868
- });
56869
- }
56870
- }, "updateColumnVisibility2");
56871
- } else {
56872
- const syncStorage = /* @__PURE__ */ __name((newTableConfig) => {
56873
- setTableConfig(newTableConfig);
56874
- window.localStorage.setItem(formName, JSON.stringify(newTableConfig));
56875
- }, "syncStorage");
56876
- resetDefaultVisibility2 = /* @__PURE__ */ __name(function() {
56877
- setTableConfig({ fieldOptions: [] });
56878
- window.localStorage.removeItem(formName);
56879
- }, "resetDefaultVisibility2");
56880
- updateColumnVisibility2 = /* @__PURE__ */ __name(function({ path: path2, paths, shouldShow }) {
56881
- const newFieldOpts = __spreadValues({}, fieldOptsByPath);
56882
- const pathsToUse = paths ? paths : [path2];
56883
- pathsToUse.forEach((path22) => {
56884
- newFieldOpts[path22] = { path: path22, isHidden: !shouldShow };
56885
- });
56886
- syncStorage(__spreadProps(__spreadValues({}, tableConfig), { fieldOptions: toArray(newFieldOpts) }));
56887
- }, "updateColumnVisibility2");
56888
- updateTableDisplayDensity2 = /* @__PURE__ */ __name(function(density) {
56889
- syncStorage(__spreadProps(__spreadValues({}, tableConfig), { density }));
56890
- }, "updateTableDisplayDensity2");
56891
- persistPageSize2 = /* @__PURE__ */ __name(function(pageSize2) {
56892
- syncStorage(__spreadProps(__spreadValues({}, tableConfig), { userSetPageSize: pageSize2 }));
56893
- }, "persistPageSize2");
56894
- moveColumnPersist2 = /* @__PURE__ */ __name(function({ oldIndex, newIndex }) {
56895
- const columnOrderings = tableConfig.columnOrderings || schema2.fields.map(({ path: path2 }) => path2);
56896
- syncStorage(__spreadProps(__spreadValues({}, tableConfig), {
56897
- columnOrderings: arrayMove(columnOrderings, oldIndex, newIndex)
56898
- }));
56899
- }, "moveColumnPersist2");
56900
- resizePersist2 = /* @__PURE__ */ __name(function(newResized) {
56901
- syncStorage(__spreadProps(__spreadValues({}, tableConfig), { resized: newResized }));
56902
- }, "resizePersist2");
56903
- }
57017
+ const syncStorage = /* @__PURE__ */ __name((newTableConfig) => {
57018
+ setTableConfig(newTableConfig);
57019
+ window.localStorage.setItem(formName, JSON.stringify(newTableConfig));
57020
+ }, "syncStorage");
57021
+ resetDefaultVisibility2 = /* @__PURE__ */ __name(function() {
57022
+ setTableConfig({ fieldOptions: [] });
57023
+ window.localStorage.removeItem(formName);
57024
+ }, "resetDefaultVisibility2");
57025
+ updateColumnVisibility2 = /* @__PURE__ */ __name(function({ path: path2, paths, shouldShow }) {
57026
+ const newFieldOpts = __spreadValues({}, fieldOptsByPath);
57027
+ const pathsToUse = paths ? paths : [path2];
57028
+ pathsToUse.forEach((path22) => {
57029
+ newFieldOpts[path22] = { path: path22, isHidden: !shouldShow };
57030
+ });
57031
+ syncStorage(__spreadProps(__spreadValues({}, tableConfig), { fieldOptions: toArray(newFieldOpts) }));
57032
+ }, "updateColumnVisibility2");
57033
+ updateTableDisplayDensity2 = /* @__PURE__ */ __name(function(density) {
57034
+ syncStorage(__spreadProps(__spreadValues({}, tableConfig), { density }));
57035
+ }, "updateTableDisplayDensity2");
57036
+ persistPageSize2 = /* @__PURE__ */ __name(function(pageSize2) {
57037
+ syncStorage(__spreadProps(__spreadValues({}, tableConfig), { userSetPageSize: pageSize2 }));
57038
+ }, "persistPageSize2");
57039
+ moveColumnPersist2 = /* @__PURE__ */ __name(function({ oldIndex, newIndex }) {
57040
+ const columnOrderings = tableConfig.columnOrderings || columns.map(({ path: path2 }) => path2);
57041
+ syncStorage(__spreadProps(__spreadValues({}, tableConfig), {
57042
+ columnOrderings: arrayMove(columnOrderings, oldIndex, newIndex)
57043
+ }));
57044
+ }, "moveColumnPersist2");
57045
+ resizePersist2 = /* @__PURE__ */ __name(function(newResized) {
57046
+ syncStorage(__spreadProps(__spreadValues({}, tableConfig), { resized: newResized }));
57047
+ }, "resizePersist2");
56904
57048
  }
56905
57049
  return {
56906
57050
  moveColumnPersist: moveColumnPersist2,
@@ -56910,18 +57054,7 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
56910
57054
  updateColumnVisibility: updateColumnVisibility2,
56911
57055
  updateTableDisplayDensity: updateTableDisplayDensity2
56912
57056
  };
56913
- }, [
56914
- (_a2 = currentUser == null ? void 0 : currentUser.user) == null ? void 0 : _a2.id,
56915
- deleteTableConfiguration,
56916
- formName,
56917
- setTableConfig,
56918
- schema2.fields,
56919
- syncDisplayOptionsToDb,
56920
- tableConfig,
56921
- upsertFieldOption,
56922
- upsertTableConfiguration,
56923
- withDisplayOptions
56924
- ]);
57057
+ }, [formName, setTableConfig, columns, tableConfig, withDisplayOptions]);
56925
57058
  let compact = _compact;
56926
57059
  let extraCompact = _extraCompact;
56927
57060
  if (withDisplayOptions && tableConfig.density) {
@@ -57227,8 +57360,8 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
57227
57360
  const waitUntilAllRowsAreRendered = useCallback$1(() => {
57228
57361
  return new Promise((resolve) => {
57229
57362
  const interval = setInterval(() => {
57230
- var _a3, _b2;
57231
- const allRowEls = (_b2 = (_a3 = tableRef.current) == null ? void 0 : _a3.tableRef) == null ? void 0 : _b2.querySelectorAll(".rt-tr-group");
57363
+ var _a2, _b2;
57364
+ const allRowEls = (_b2 = (_a2 = tableRef.current) == null ? void 0 : _a2.tableRef) == null ? void 0 : _b2.querySelectorAll(".rt-tr-group");
57232
57365
  if ((allRowEls == null ? void 0 : allRowEls.length) === entities.length) {
57233
57366
  clearInterval(interval);
57234
57367
  resolve();
@@ -57545,7 +57678,6 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
57545
57678
  ]
57546
57679
  );
57547
57680
  const { handleKeyDown, handleKeyUp } = useHotkeys(hotKeys);
57548
- const [columns, setColumns] = useState([]);
57549
57681
  const [fullscreen, setFullscreen] = useState(false);
57550
57682
  const [selectingAll, setSelectingAll] = useState(false);
57551
57683
  useEffect(() => {
@@ -57726,16 +57858,15 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
57726
57858
  addFilters(additionalFilters);
57727
57859
  }, [additionalFilters]);
57728
57860
  useEffect(() => {
57729
- setColumns(
57730
- schema2.fields ? schema2.fields.reduce((col, field, i) => {
57731
- if (field.isHidden) {
57732
- return col;
57733
- }
57734
- return col.concat(__spreadProps(__spreadValues({}, field), {
57735
- columnIndex: i
57736
- }));
57737
- }, []) : []
57738
- );
57861
+ const newCols = schema2.fields ? schema2.fields.reduce((columns2, field, i) => {
57862
+ if (field.isHidden) {
57863
+ return columns2.concat(field);
57864
+ }
57865
+ return columns2.concat(__spreadProps(__spreadValues({}, field), {
57866
+ columnIndex: i
57867
+ }));
57868
+ }, []) : [];
57869
+ setColumns(newCols);
57739
57870
  }, [schema2 == null ? void 0 : schema2.fields]);
57740
57871
  const setSelectedIds = useCallback$1(
57741
57872
  (selectedIds2, scrollToFirst) => {
@@ -57804,25 +57935,19 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
57804
57935
  const TheadComponent = useCallback$1(
57805
57936
  ({ className: className2, style: style22, children: children2 }) => {
57806
57937
  const moveColumn = /* @__PURE__ */ __name(({ oldIndex, newIndex }) => {
57807
- let oldStateColumnIndex, newStateColumnIndex;
57808
- columns.forEach((column, i) => {
57809
- if (oldIndex === column.columnIndex) oldStateColumnIndex = i;
57810
- if (newIndex === column.columnIndex) newStateColumnIndex = i;
57811
- });
57812
- const newColumns = arrayMove(
57813
- columns,
57814
- oldStateColumnIndex,
57815
- newStateColumnIndex
57816
- ).map((column, i) => {
57817
- return __spreadProps(__spreadValues({}, column), {
57818
- columnIndex: i
57819
- });
57820
- });
57938
+ const newColumns = arrayMove(columns, oldIndex, newIndex).map(
57939
+ (column, i) => {
57940
+ return __spreadProps(__spreadValues({}, column), {
57941
+ columnIndex: i
57942
+ });
57943
+ }
57944
+ );
57821
57945
  setColumns(newColumns);
57822
57946
  }, "moveColumn");
57823
57947
  return /* @__PURE__ */ React__default.createElement(
57824
57948
  SortableColumns,
57825
57949
  {
57950
+ sortedItemsFull: columns.map((c2) => c2.path),
57826
57951
  className: className2,
57827
57952
  style: style22,
57828
57953
  moveColumn: moveColumnPersist || moveColumn
@@ -57855,8 +57980,8 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
57855
57980
  });
57856
57981
  }, "addEntitiesToSelection");
57857
57982
  const refocusTable = useCallback$1(() => {
57858
- var _a3, _b2;
57859
- const table2 = (_b2 = (_a3 = tableRef.current) == null ? void 0 : _a3.tableRef) == null ? void 0 : _b2.closest(
57983
+ var _a2, _b2;
57984
+ const table2 = (_b2 = (_a2 = tableRef.current) == null ? void 0 : _a2.tableRef) == null ? void 0 : _b2.closest(
57860
57985
  ".data-table-container>div"
57861
57986
  );
57862
57987
  table2 == null ? void 0 : table2.focus();
@@ -58690,8 +58815,8 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
58690
58815
  });
58691
58816
  const scrollToTop = useCallback$1(
58692
58817
  () => {
58693
- var _a3, _b2, _c, _d, _e, _f;
58694
- return (_f = (_e = (_d = (_c = (_b2 = (_a3 = tableRef.current) == null ? void 0 : _a3.tableRef) == null ? void 0 : _b2.children) == null ? void 0 : _c[0]) == null ? void 0 : _d.children) == null ? void 0 : _e[0]) == null ? void 0 : _f.scrollIntoView();
58818
+ var _a2, _b2, _c, _d, _e, _f;
58819
+ return (_f = (_e = (_d = (_c = (_b2 = (_a2 = tableRef.current) == null ? void 0 : _a2.tableRef) == null ? void 0 : _b2.children) == null ? void 0 : _c[0]) == null ? void 0 : _d.children) == null ? void 0 : _e[0]) == null ? void 0 : _f.scrollIntoView();
58695
58820
  },
58696
58821
  []
58697
58822
  );
@@ -58704,7 +58829,7 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
58704
58829
  noVirtual,
58705
58830
  className: classNames({
58706
58831
  isCellEditable,
58707
- "loading": isLoading,
58832
+ loading: isLoading,
58708
58833
  "tg-table-loading": isLoading,
58709
58834
  "tg-table-disabled": disabled
58710
58835
  }),
@@ -58808,10 +58933,10 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
58808
58933
  }, isCellEditable && {
58809
58934
  tabIndex: -1,
58810
58935
  onKeyDown: /* @__PURE__ */ __name((e) => {
58811
- var _a3, _b2, _c, _d, _e, _f, _g, _h;
58936
+ var _a2, _b2, _c, _d, _e, _f, _g, _h;
58812
58937
  const isTabKey = e.key === "Tab";
58813
58938
  const isArrowKey = e.key.startsWith("Arrow");
58814
- if (isArrowKey && ((_a3 = e.target) == null ? void 0 : _a3.tagName) !== "INPUT" || isTabKey) {
58939
+ if (isArrowKey && ((_a2 = e.target) == null ? void 0 : _a2.tagName) !== "INPUT" || isTabKey) {
58815
58940
  const left2 = e.key === "ArrowLeft";
58816
58941
  const up = e.key === "ArrowUp";
58817
58942
  const down = e.key === "ArrowDown" || e.key === "Enter";
@@ -59090,6 +59215,7 @@ const DataTable = /* @__PURE__ */ __name((_w) => {
59090
59215
  resetDefaultVisibility,
59091
59216
  updateColumnVisibility,
59092
59217
  updateTableDisplayDensity,
59218
+ moveColumnPersist,
59093
59219
  showForcedHiddenColumns,
59094
59220
  setShowForcedHidden,
59095
59221
  hasOptionForForcedHidden: withDisplayOptions && (isSimple || isInfinite),
@@ -68731,10 +68857,10 @@ var Resizer = (
68731
68857
  }
68732
68858
  __name(Resizer2, "Resizer");
68733
68859
  Resizer2.prototype.render = function() {
68734
- return React.createElement("div", { className: this.props.className || "", style: __assign$2(__assign$2({ position: "absolute", userSelect: "none" }, styles[this.props.direction]), this.props.replaceStyles || {}), onMouseDown: this.onMouseDown, onTouchStart: this.onTouchStart }, this.props.children);
68860
+ return React$1.createElement("div", { className: this.props.className || "", style: __assign$2(__assign$2({ position: "absolute", userSelect: "none" }, styles[this.props.direction]), this.props.replaceStyles || {}), onMouseDown: this.onMouseDown, onTouchStart: this.onTouchStart }, this.props.children);
68735
68861
  };
68736
68862
  return Resizer2;
68737
- }(React.PureComponent)
68863
+ }(React$1.PureComponent)
68738
68864
  );
68739
68865
  var src = { exports: {} };
68740
68866
  var hasRequiredSrc;
@@ -69511,11 +69637,11 @@ var Resizable = (
69511
69637
  }
69512
69638
  var resizers = Object.keys(enable).map(function(dir) {
69513
69639
  if (enable[dir] !== false) {
69514
- return React.createElement(Resizer, { key: dir, direction: dir, onResizeStart: _this.onResizeStart, replaceStyles: handleStyles && handleStyles[dir], className: handleClasses && handleClasses[dir] }, handleComponent && handleComponent[dir] ? handleComponent[dir] : null);
69640
+ return React$1.createElement(Resizer, { key: dir, direction: dir, onResizeStart: _this.onResizeStart, replaceStyles: handleStyles && handleStyles[dir], className: handleClasses && handleClasses[dir] }, handleComponent && handleComponent[dir] ? handleComponent[dir] : null);
69515
69641
  }
69516
69642
  return null;
69517
69643
  });
69518
- return React.createElement("div", { className: handleWrapperClass, style: handleWrapperStyle }, resizers);
69644
+ return React$1.createElement("div", { className: handleWrapperClass, style: handleWrapperStyle }, resizers);
69519
69645
  };
69520
69646
  Resizable2.prototype.render = function() {
69521
69647
  var _this = this;
@@ -69531,10 +69657,10 @@ var Resizable = (
69531
69657
  style2.flexBasis = this.state.flexBasis;
69532
69658
  }
69533
69659
  var Wrapper = this.props.as || "div";
69534
- return React.createElement(
69660
+ return React$1.createElement(
69535
69661
  Wrapper,
69536
69662
  __assign$1({ ref: this.ref, style: style2, className: this.props.className }, extendsProps),
69537
- this.state.isResizing && React.createElement("div", { style: this.state.backgroundStyle }),
69663
+ this.state.isResizing && React$1.createElement("div", { style: this.state.backgroundStyle }),
69538
69664
  this.props.children,
69539
69665
  this.renderResizer()
69540
69666
  );
@@ -69567,7 +69693,7 @@ var Resizable = (
69567
69693
  snapGap: 0
69568
69694
  };
69569
69695
  return Resizable2;
69570
- }(React.PureComponent)
69696
+ }(React$1.PureComponent)
69571
69697
  );
69572
69698
  /*! *****************************************************************************
69573
69699
  Copyright (c) Microsoft Corporation. All rights reserved.
@@ -97444,7 +97570,8 @@ function getSelectionMessage({
97444
97570
  //these are only passed in for the status bar
97445
97571
  GCDecimalDigits,
97446
97572
  //these are only passed in for the status bar
97447
- isProtein: isProtein2
97573
+ isProtein: isProtein2,
97574
+ showAminoAcidUnitAsCodon
97448
97575
  }) {
97449
97576
  let _selectionLayer = selectionLayer2;
97450
97577
  const isSelecting = selectionLayer2.start > -1;
@@ -97455,7 +97582,7 @@ function getSelectionMessage({
97455
97582
  getSequenceWithinRange(_selectionLayer, sequenceData2.sequence)
97456
97583
  ).toFixed(numDecimalDigits), "GCContent");
97457
97584
  const seqLen = divideBy3(length, isProtein2);
97458
- return `${customTitle || "Selecting"} ${seqLen} ${(isProtein2 ? "AA" : "bp") + (seqLen === 1 ? "" : "s")} from ${divideBy3(_selectionLayer.start, isProtein2) + 1} to ${divideBy3(
97585
+ return `${customTitle || "Selecting"} ${seqLen} ${(isProtein2 ? `${showAminoAcidUnitAsCodon ? "codon" : "AA"}` : "bp") + (seqLen === 1 ? "" : "s")} from ${divideBy3(_selectionLayer.start, isProtein2) + 1} to ${divideBy3(
97459
97586
  _selectionLayer.end + 1,
97460
97587
  isProtein2
97461
97588
  )}${showGCContent2 && !isProtein2 ? ` (${GCContent(GCDecimalDigits)}% GC)` : ""}`;
@@ -97465,7 +97592,7 @@ function getSelectionMessage({
97465
97592
  _selectionLayer,
97466
97593
  sequenceLength
97467
97594
  );
97468
- return `Caret Between ` + (isProtein2 ? `AAs ${divideBy3(insertBetween[0], true)} and ${divideBy3(
97595
+ return `Caret Between ` + (isProtein2 ? `${showAminoAcidUnitAsCodon ? "codons" : "AAs"} ${divideBy3(insertBetween[0], true)} and ${divideBy3(
97469
97596
  insertBetween[1] + 2,
97470
97597
  true
97471
97598
  )}` : `Bases ${insertBetween[0]} and ${insertBetween[1]}`);
@@ -108582,7 +108709,8 @@ function Caret$2({
108582
108709
  onRightClick,
108583
108710
  style: style2,
108584
108711
  selectionMessage,
108585
- className = ""
108712
+ className = "",
108713
+ showAminoAcidUnitAsCodon
108586
108714
  }) {
108587
108715
  if (row.start <= caretPosition2 && row.end + 1 >= caretPosition2 || row.end === sequenceLength - 1 && row.end < caretPosition2) {
108588
108716
  const cursorEl = /* @__PURE__ */ React__default.createElement(
@@ -108592,7 +108720,12 @@ function Caret$2({
108592
108720
  onContextMenu: onRightClick ? (e) => {
108593
108721
  onRightClick(e);
108594
108722
  } : void 0,
108595
- title: selectionMessage || getSelectionMessage({ caretPosition: caretPosition2, isProtein: isProtein2, sequenceLength }),
108723
+ title: selectionMessage || getSelectionMessage({
108724
+ caretPosition: caretPosition2,
108725
+ isProtein: isProtein2,
108726
+ sequenceLength,
108727
+ showAminoAcidUnitAsCodon
108728
+ }),
108596
108729
  className: classNames(
108597
108730
  {
108598
108731
  notClickable: !isDraggable
@@ -108640,6 +108773,7 @@ function SelectionLayer$2(props) {
108640
108773
  regions,
108641
108774
  leftMargin = 0,
108642
108775
  isProtein: isProtein2,
108776
+ showAminoAcidUnitAsCodon,
108643
108777
  getGaps: getGaps2,
108644
108778
  hideTitle: topLevelHideTitle,
108645
108779
  customTitle: topLevelCustomTitle,
@@ -108673,7 +108807,8 @@ function SelectionLayer$2(props) {
108673
108807
  selectionLayer: selectionLayer2,
108674
108808
  customTitle: customTitle || topLevelCustomTitle,
108675
108809
  sequenceLength,
108676
- isProtein: isProtein2
108810
+ isProtein: isProtein2,
108811
+ showAminoAcidUnitAsCodon
108677
108812
  });
108678
108813
  const onSelectionContextMenu = /* @__PURE__ */ __name(function(event) {
108679
108814
  selectionLayerRightClicked && selectionLayerRightClicked({
@@ -108714,6 +108849,7 @@ function SelectionLayer$2(props) {
108714
108849
  key: key + "caret1"
108715
108850
  }, {
108716
108851
  isProtein: isProtein2,
108852
+ showAminoAcidUnitAsCodon,
108717
108853
  leftMargin,
108718
108854
  onClick: _onClick || preventDefaultStopPropagation,
108719
108855
  onRightClick: onSelectionContextMenu,
@@ -108734,6 +108870,7 @@ function SelectionLayer$2(props) {
108734
108870
  key: key + "caret2"
108735
108871
  }, {
108736
108872
  isProtein: isProtein2,
108873
+ showAminoAcidUnitAsCodon,
108737
108874
  leftMargin,
108738
108875
  onClick: _onClick || preventDefaultStopPropagation,
108739
108876
  onRightClick: onSelectionContextMenu,
@@ -108822,6 +108959,183 @@ function getDnaColor(char, isReverse) {
108822
108959
  return dnaToColor[isReverse ? DNAComplementMap[char.toLowerCase()] : char.toLowerCase()] || "lightgrey";
108823
108960
  }
108824
108961
  __name(getDnaColor, "getDnaColor");
108962
+ const serineThreonineToColor = {
108963
+ s: "#FF69B4",
108964
+ t: "#FF69B4"
108965
+ };
108966
+ const hydrophobicityColor = {
108967
+ i: "#F84C52",
108968
+ // isoleucine
108969
+ v: "#F84C52",
108970
+ // valine
108971
+ l: "#F84C52",
108972
+ // leucine
108973
+ f: "#F84C52",
108974
+ // phenylalanine
108975
+ c: "#F84C52",
108976
+ // cysteine
108977
+ m: "#C44C86",
108978
+ // methionine
108979
+ a: "#C44C86",
108980
+ // alanine
108981
+ g: "#8D4CBD",
108982
+ // glycine
108983
+ t: "#8D4CBD",
108984
+ // threonine
108985
+ s: "#8D4CBD",
108986
+ // serine
108987
+ w: "#8D4CBD",
108988
+ // tryptophan
108989
+ y: "#8D4CBD",
108990
+ // tyrosine
108991
+ p: "#8D4CBD",
108992
+ // proline
108993
+ h: "#544CF7",
108994
+ // histidine
108995
+ q: "#544CF7",
108996
+ // glutamine
108997
+ n: "#544CF7",
108998
+ // asparagine
108999
+ e: "#544CF7",
109000
+ // glutamate
109001
+ d: "#544CF7",
109002
+ // aspartate
109003
+ k: "#4B4CFF",
109004
+ // lysine
109005
+ r: "#4B4CFF"
109006
+ // arginine
109007
+ };
109008
+ const mainHighlighter = "#4B91B8";
109009
+ const polarColors = {
109010
+ s: mainHighlighter,
109011
+ t: mainHighlighter,
109012
+ n: mainHighlighter,
109013
+ c: mainHighlighter,
109014
+ q: mainHighlighter,
109015
+ y: mainHighlighter
109016
+ };
109017
+ const negativeColors = {
109018
+ e: mainHighlighter,
109019
+ d: mainHighlighter
109020
+ };
109021
+ const positiveColors = {
109022
+ k: mainHighlighter,
109023
+ r: mainHighlighter,
109024
+ h: mainHighlighter
109025
+ };
109026
+ const chargedColors = __spreadValues(__spreadValues({}, negativeColors), positiveColors);
109027
+ const aliphaticColors = {
109028
+ g: mainHighlighter,
109029
+ a: mainHighlighter,
109030
+ v: mainHighlighter,
109031
+ l: mainHighlighter,
109032
+ i: mainHighlighter,
109033
+ p: mainHighlighter,
109034
+ m: mainHighlighter
109035
+ };
109036
+ const aromaticColors = {
109037
+ f: mainHighlighter,
109038
+ y: mainHighlighter,
109039
+ w: mainHighlighter,
109040
+ h: mainHighlighter
109041
+ };
109042
+ const colorScheme = {
109043
+ a: "#C8C8C8",
109044
+ // alanine
109045
+ r: "#145AFF",
109046
+ // arginine
109047
+ n: "#00DCDC",
109048
+ // asparagine
109049
+ d: "#E60A0A",
109050
+ // aspartate
109051
+ c: "#E6E600",
109052
+ // cysteine
109053
+ q: "#00DCDC",
109054
+ // glutamine
109055
+ e: "#E60A0A",
109056
+ // glutamate
109057
+ g: "#EBEBEB",
109058
+ // glycine
109059
+ h: "#8282D2",
109060
+ // histidine
109061
+ i: "#0F820F",
109062
+ // isoleucine
109063
+ l: "#0F820F",
109064
+ // leucine
109065
+ k: "#145AFF",
109066
+ // lysine
109067
+ m: "#E6E600",
109068
+ // methionine
109069
+ f: "#3232AA",
109070
+ // phenylalanine
109071
+ p: "#DC9682",
109072
+ // proline
109073
+ s: "#FA9600",
109074
+ // serine
109075
+ t: "#FA9600",
109076
+ // threonine
109077
+ w: "#B45AB4",
109078
+ // tryptophan
109079
+ y: "#3232AA",
109080
+ // tyrosine
109081
+ v: "#0F820F",
109082
+ // valine
109083
+ x: "#BEA06E"
109084
+ };
109085
+ function hexToRgba(hex) {
109086
+ const alpha = 0.6;
109087
+ if (hex === "transparent") return hex;
109088
+ hex = hex.replace(/^#/, "");
109089
+ const bigint = parseInt(hex, 16);
109090
+ let r2, g2, b3;
109091
+ if (hex.length === 6) {
109092
+ r2 = bigint >> 16 & 255;
109093
+ g2 = bigint >> 8 & 255;
109094
+ b3 = bigint & 255;
109095
+ } else {
109096
+ r2 = (bigint >> 8 & 15) * 17;
109097
+ g2 = (bigint >> 4 & 15) * 17;
109098
+ b3 = (bigint & 15) * 17;
109099
+ }
109100
+ return `rgba(${r2}, ${g2}, ${b3}, ${alpha})`;
109101
+ }
109102
+ __name(hexToRgba, "hexToRgba");
109103
+ function getAliphaticColor(char) {
109104
+ return hexToRgba(aliphaticColors[char.toLowerCase()] || "transparent");
109105
+ }
109106
+ __name(getAliphaticColor, "getAliphaticColor");
109107
+ function getAromaticColor(char) {
109108
+ return hexToRgba(aromaticColors[char.toLowerCase()] || "transparent");
109109
+ }
109110
+ __name(getAromaticColor, "getAromaticColor");
109111
+ function getNegativeColor(char) {
109112
+ return hexToRgba(negativeColors[char.toLowerCase()] || "transparent");
109113
+ }
109114
+ __name(getNegativeColor, "getNegativeColor");
109115
+ function getPositiveColor(char) {
109116
+ return hexToRgba(positiveColors[char.toLowerCase()] || "transparent");
109117
+ }
109118
+ __name(getPositiveColor, "getPositiveColor");
109119
+ function getChargedColor(char) {
109120
+ return hexToRgba(chargedColors[char.toLowerCase()] || "transparent");
109121
+ }
109122
+ __name(getChargedColor, "getChargedColor");
109123
+ function getPolarColor(char) {
109124
+ return hexToRgba(polarColors[char.toLowerCase()] || "transparent");
109125
+ }
109126
+ __name(getPolarColor, "getPolarColor");
109127
+ function getSerineThreonineColor(char) {
109128
+ return hexToRgba(serineThreonineToColor[char.toLowerCase()] || "transparent");
109129
+ }
109130
+ __name(getSerineThreonineColor, "getSerineThreonineColor");
109131
+ function getHydrophobicity(char) {
109132
+ return hexToRgba(hydrophobicityColor[char.toLowerCase()] || "transparent");
109133
+ }
109134
+ __name(getHydrophobicity, "getHydrophobicity");
109135
+ function getColorScheme(char) {
109136
+ return hexToRgba(colorScheme[char.toLowerCase()] || "transparent");
109137
+ }
109138
+ __name(getColorScheme, "getColorScheme");
108825
109139
  const HoveredIdContext = React__default.createContext({
108826
109140
  hoveredId: ""
108827
109141
  // default value
@@ -108912,6 +109226,30 @@ const partOverhangs = [
108912
109226
  "threePrimeUnderhang"
108913
109227
  ];
108914
109228
  const getChunk = /* @__PURE__ */ __name((sequence2, chunkSize, chunkNumber) => sequence2.slice(chunkSize * chunkNumber, chunkSize * (chunkNumber + 1)), "getChunk");
109229
+ function renderColoredLayer(props, fudge, width, toColor) {
109230
+ return /* @__PURE__ */ React__default.createElement(
109231
+ "svg",
109232
+ {
109233
+ style: {
109234
+ left: props.startOffset * props.charWidth,
109235
+ height: props.height,
109236
+ width,
109237
+ position: "absolute"
109238
+ },
109239
+ className: "rowViewTextContainer",
109240
+ height: Math.max(0, Number(props.height))
109241
+ },
109242
+ /* @__PURE__ */ React__default.createElement(
109243
+ ColoredSequence,
109244
+ __spreadProps(__spreadValues({}, props), {
109245
+ fudge,
109246
+ totalWidth: width,
109247
+ toColor
109248
+ })
109249
+ )
109250
+ );
109251
+ }
109252
+ __name(renderColoredLayer, "renderColoredLayer");
108915
109253
  const _Sequence = class _Sequence extends React__default.Component {
108916
109254
  render() {
108917
109255
  const {
@@ -108928,6 +109266,15 @@ const _Sequence = class _Sequence extends React__default.Component {
108928
109266
  chunkSize = 100,
108929
109267
  scrollData,
108930
109268
  showDnaColors,
109269
+ showSerineThreonine,
109270
+ showHydrophobicity,
109271
+ showPolar,
109272
+ showNegative,
109273
+ showPositive,
109274
+ showCharged,
109275
+ showAliphatic,
109276
+ showAromatic,
109277
+ showColorScheme,
108931
109278
  fivePrimeThreePrimeHints,
108932
109279
  alignmentData,
108933
109280
  sequenceLength,
@@ -108970,6 +109317,17 @@ const _Sequence = class _Sequence extends React__default.Component {
108970
109317
  ) : void 0;
108971
109318
  }
108972
109319
  });
109320
+ const colorLayers = [
109321
+ { show: showSerineThreonine, toColor: "serineThreonine" },
109322
+ { show: showHydrophobicity, toColor: "hydrophobicity" },
109323
+ { show: showPolar, toColor: "polar" },
109324
+ { show: showNegative, toColor: "negative" },
109325
+ { show: showPositive, toColor: "positive" },
109326
+ { show: showCharged, toColor: "charged" },
109327
+ { show: showAliphatic, toColor: "aliphatic" },
109328
+ { show: showAromatic, toColor: "aromatic" },
109329
+ { show: showColorScheme, toColor: "colorScheme" }
109330
+ ];
108973
109331
  const style2 = __spreadValues({
108974
109332
  position: "relative",
108975
109333
  height,
@@ -109047,6 +109405,9 @@ const _Sequence = class _Sequence extends React__default.Component {
109047
109405
  },
109048
109406
  "5'"
109049
109407
  ),
109408
+ colorLayers.map(
109409
+ ({ show, toColor }) => show && renderColoredLayer(this.props, fudge, width, toColor)
109410
+ ),
109050
109411
  !hideBps && /* @__PURE__ */ React__default.createElement(
109051
109412
  "svg",
109052
109413
  {
@@ -109063,7 +109424,8 @@ const _Sequence = class _Sequence extends React__default.Component {
109063
109424
  ColoredSequence,
109064
109425
  __spreadValues({}, __spreadProps(__spreadValues({}, this.props), {
109065
109426
  fudge,
109066
- totalWidth: width
109427
+ totalWidth: width,
109428
+ toColor: "dnaColor"
109067
109429
  }))
109068
109430
  ),
109069
109431
  inner2
@@ -109087,19 +109449,44 @@ const _ColoredSequence = class _ColoredSequence extends React__default.Component
109087
109449
  alignmentData,
109088
109450
  getGaps: getGaps2,
109089
109451
  fudge,
109090
- totalWidth
109452
+ totalWidth,
109453
+ toColor
109091
109454
  } = this.props;
109092
109455
  if (alignmentData) {
109093
109456
  sequence2 = sequence2.replace(/^-+/g, "").replace(/-+$/g, "");
109094
109457
  }
109095
- const colorPaths = Object.values(dnaToColor).reduce((acc, color2) => {
109458
+ const colorMap = {
109459
+ dnaColor: dnaToColor,
109460
+ serineThreonine: serineThreonineToColor,
109461
+ hydrophobicity: hydrophobicityColor,
109462
+ polar: polarColors,
109463
+ negative: negativeColors,
109464
+ positive: positiveColors,
109465
+ charged: chargedColors,
109466
+ aliphatic: aliphaticColors,
109467
+ aromatic: aromaticColors,
109468
+ colorScheme
109469
+ };
109470
+ const colorMethods = {
109471
+ dnaColor: getDnaColor,
109472
+ serineThreonine: getSerineThreonineColor,
109473
+ hydrophobicity: getHydrophobicity,
109474
+ polar: getPolarColor,
109475
+ negative: getNegativeColor,
109476
+ positive: getPositiveColor,
109477
+ charged: getChargedColor,
109478
+ aliphatic: getAliphaticColor,
109479
+ aromatic: getAromaticColor,
109480
+ colorScheme: getColorScheme
109481
+ };
109482
+ const colorPaths = Object.values(colorMap[toColor]).reduce((acc, color2) => {
109096
109483
  acc[color2] = "";
109097
109484
  return acc;
109098
109485
  }, {});
109099
109486
  const gapsBefore = getGaps2 ? getGaps2({ start: 0, end: 0 }).gapsBefore : 0;
109100
109487
  sequence2.split("").forEach((char, i) => {
109101
109488
  const width = Number(charWidth2);
109102
- const color2 = getDnaColor(char, isReverse);
109489
+ const color2 = colorMethods[toColor](char, isReverse);
109103
109490
  const x = (i + gapsBefore) * charWidth2;
109104
109491
  const y2 = 0;
109105
109492
  colorPaths[color2] = (colorPaths[color2] || "") + `M${x},${y2} L${x + width},${y2} L${x + width},${y2 + height} L${x},${y2 + height}`;
@@ -111175,6 +111562,7 @@ const _Translation = class _Translation extends React__default.Component {
111175
111562
  annotationRange,
111176
111563
  height,
111177
111564
  showAminoAcidNumbers,
111565
+ showAminoAcidUnitAsCodon,
111178
111566
  charWidth: charWidth2,
111179
111567
  aminoAcidNumbersHeight,
111180
111568
  onClick,
@@ -111277,8 +111665,8 @@ const _Translation = class _Translation extends React__default.Component {
111277
111665
  });
111278
111666
  }, "onContextMenu"),
111279
111667
  title: `${aminoAcid.name} -- Index: ${aminoAcidSliver.aminoAcidIndex + 1} -- Hydrophobicity: ${aminoAcid.hydrophobicity} -- Mass: ${aminoAcid.mass}
111280
-
111281
- Part of ${annotation.translationType} Translation from BPs ${annotation.start + 1} to ${annotation.end + 1} (${aminoAcids.length / 3} AAs)`,
111668
+
111669
+ Part of ${annotation.translationType} Translation from BPs ${annotation.start + 1} to ${annotation.end + 1} (${aminoAcids.length / 3} ${showAminoAcidUnitAsCodon ? "codons" : "AAs"})`,
111282
111670
  showAminoAcidNumbers,
111283
111671
  aminoAcidIndex: aminoAcidSliver.aminoAcidIndex,
111284
111672
  onDoubleClick: /* @__PURE__ */ __name(function(event) {
@@ -111305,6 +111693,7 @@ let Translation = _Translation;
111305
111693
  const Translation$1 = pure(Translation);
111306
111694
  function getExtraInnerCompProps(annotationRange, {
111307
111695
  showAminoAcidNumbers,
111696
+ showAminoAcidUnitAsCodon,
111308
111697
  getGaps: getGaps2,
111309
111698
  isProtein: isProtein2,
111310
111699
  colorType,
@@ -111316,6 +111705,7 @@ function getExtraInnerCompProps(annotationRange, {
111316
111705
  const anotationHeightNoSpace = annotationHeight - spaceBetweenAnnotations;
111317
111706
  return {
111318
111707
  showAminoAcidNumbers,
111708
+ showAminoAcidUnitAsCodon,
111319
111709
  getGaps: getGaps2,
111320
111710
  height: anotationHeightNoSpace,
111321
111711
  aminoAcidNumbersHeight,
@@ -114112,7 +114502,7 @@ const CutsiteSelectionLayers = connectToEditor(
114112
114502
  );
114113
114503
  });
114114
114504
  }, "CutsiteSelectionLayersInner"));
114115
- function filterRanges(ranges, extraProps = {}) {
114505
+ function filterRanges(ranges, isProteinAlignmentView, extraProps = {}) {
114116
114506
  if (!ranges) return ranges;
114117
114507
  if (extraProps.onlyForward) {
114118
114508
  ranges = filter(ranges, (a2) => a2.annotation.forward);
@@ -114120,12 +114510,30 @@ function filterRanges(ranges, extraProps = {}) {
114120
114510
  if (extraProps.onlyReverse) {
114121
114511
  ranges = filter(ranges, (a2) => !a2.annotation.forward);
114122
114512
  }
114513
+ if (isProteinAlignmentView) {
114514
+ ranges = map$3(ranges, (range2) => {
114515
+ const start2 = (range2.start + 3) / 3 - 1;
114516
+ const end2 = (range2.end + 1) / 3 - 1;
114517
+ return __spreadProps(__spreadValues({}, range2), {
114518
+ start: start2,
114519
+ end: end2,
114520
+ annotation: __spreadProps(__spreadValues({}, range2.annotation), {
114521
+ start: start2,
114522
+ end: end2
114523
+ })
114524
+ });
114525
+ });
114526
+ }
114123
114527
  return ranges;
114124
114528
  }
114125
114529
  __name(filterRanges, "filterRanges");
114126
- function getPropsForType(props, type2, pluralType, extraProps) {
114530
+ function getPropsForType(props, isProteinAlignmentView, type2, pluralType, extraProps) {
114127
114531
  const upperPluralType = startCase(pluralType);
114128
- const annotationRanges = filterRanges(props.row[pluralType], extraProps);
114532
+ const annotationRanges = filterRanges(
114533
+ props.row[pluralType],
114534
+ isProteinAlignmentView,
114535
+ extraProps
114536
+ );
114129
114537
  const toRet = {
114130
114538
  annotationColor: props[pluralType + "Color"],
114131
114539
  annotationHeight: props[pluralType + "Height"] || rowHeights[pluralType].height,
@@ -114141,7 +114549,7 @@ function getPropsForType(props, type2, pluralType, extraProps) {
114141
114549
  return toRet;
114142
114550
  }
114143
114551
  __name(getPropsForType, "getPropsForType");
114144
- function RowItem(props) {
114552
+ function RowItem$1(props) {
114145
114553
  let {
114146
114554
  noRedux,
114147
114555
  charWidth: charWidth2 = defaultCharWidth,
@@ -114198,7 +114606,8 @@ function RowItem(props) {
114198
114606
  isLinearView,
114199
114607
  scalePct,
114200
114608
  setScalePct,
114201
- extraAnnotationProps = {}
114609
+ extraAnnotationProps = {},
114610
+ showAminoAcidUnitAsCodon
114202
114611
  } = props;
114203
114612
  const {
114204
114613
  chromatogram: showChromatogram,
@@ -114210,6 +114619,15 @@ function RowItem(props) {
114210
114619
  // yellowAxis: showYellowAxis,
114211
114620
  aminoAcidNumbers: showAminoAcidNumbers,
114212
114621
  dnaColors: showDnaColors,
114622
+ serineThreonine: showSerineThreonine,
114623
+ hydrophobicity: showHydrophobicity,
114624
+ polar: showPolar,
114625
+ negative: showNegative,
114626
+ positive: showPositive,
114627
+ charged: showCharged,
114628
+ aliphatic: showAliphatic,
114629
+ aromatic: showAromatic,
114630
+ colorScheme: showColorScheme,
114213
114631
  fivePrimeThreePrimeHints,
114214
114632
  reverseSequence: showReverseSequence,
114215
114633
  sequence: showSequence,
@@ -114256,17 +114674,21 @@ function RowItem(props) {
114256
114674
  height,
114257
114675
  width: width + "px"
114258
114676
  };
114677
+ const isProteinAlignmentView = !!(props.isProtein && props.alignmentData);
114259
114678
  const annotationCommonProps = {
114260
114679
  noRedux,
114261
114680
  editorName,
114262
114681
  charWidth: charWidth2,
114263
114682
  bpsPerRow,
114264
114683
  getGaps: getGaps2,
114265
- isProtein: isProtein2,
114684
+ isProtein: isProteinAlignmentView ? false : isProtein2,
114266
114685
  readOnly: readOnly2,
114267
114686
  sequenceLength,
114268
114687
  isRowView,
114269
- row: { start: row.start, end: row.end }
114688
+ row: {
114689
+ start: row.start,
114690
+ end: isProteinAlignmentView ? sequenceLength - 1 : row.end
114691
+ }
114270
114692
  };
114271
114693
  const drawLabels = /* @__PURE__ */ __name((type2, noDraw, _a2 = {}) => {
114272
114694
  var _b2 = _a2, { filterOpts } = _b2, extraProps = __objRest(_b2, ["filterOpts"]);
@@ -114283,6 +114705,7 @@ function RowItem(props) {
114283
114705
  onDoubleClick: props[type2 + "DoubleClicked"]
114284
114706
  })
114285
114707
  ) : [],
114708
+ isProteinAlignmentView,
114286
114709
  filterOpts
114287
114710
  );
114288
114711
  if (!ranges.length) return null;
@@ -114317,6 +114740,13 @@ function RowItem(props) {
114317
114740
  if (shouldShow !== void 0 ? !shouldShow : !annotationVisibility2[pluralType] || Object.keys(row[pluralType] || {}).length <= 0) {
114318
114741
  return null;
114319
114742
  }
114743
+ const propsForType = getPropsForType(
114744
+ props,
114745
+ isProteinAlignmentView,
114746
+ type2,
114747
+ pluralType,
114748
+ extraProps
114749
+ );
114320
114750
  const CompToUse = CompOverride || StackedAnnotations;
114321
114751
  return /* @__PURE__ */ React__default.createElement(
114322
114752
  CompToUse,
@@ -114327,7 +114757,7 @@ function RowItem(props) {
114327
114757
  fullSequence,
114328
114758
  containerClassName: camelCase("veRowView-" + pluralType + "Container"),
114329
114759
  alignmentType: alignmentType2
114330
- }, annotationCommonProps), getPropsForType(props, type2, pluralType, extraProps)), otherExtraProps)
114760
+ }, annotationCommonProps), propsForType), otherExtraProps)
114331
114761
  );
114332
114762
  }, "drawAnnotations");
114333
114763
  const deletionLayersToDisplay = flatMap(
@@ -114366,6 +114796,7 @@ function RowItem(props) {
114366
114796
  const translationCommonProps = {
114367
114797
  CompOverride: Translations,
114368
114798
  showAminoAcidNumbers,
114799
+ showAminoAcidUnitAsCodon,
114369
114800
  sequenceLength,
114370
114801
  aminoAcidNumbersHeight
114371
114802
  };
@@ -114401,6 +114832,7 @@ function RowItem(props) {
114401
114832
  customTitleStart: "Search match",
114402
114833
  regions: searchLayers
114403
114834
  }, annotationCommonProps), {
114835
+ showAminoAcidUnitAsCodon,
114404
114836
  selectionLayerRightClicked: searchLayerRightClicked,
114405
114837
  row: alignmentData ? { start: 0, end: alignmentData.sequence.length - 1 } : row,
114406
114838
  onClick: searchLayerClicked
@@ -114415,7 +114847,8 @@ function RowItem(props) {
114415
114847
  regions: getAllSelectionLayers({
114416
114848
  additionalSelectionLayers,
114417
114849
  selectionLayer: selectionLayer2
114418
- })
114850
+ }),
114851
+ showAminoAcidUnitAsCodon
114419
114852
  })
114420
114853
  ), drawAnnotations2("warning"), drawAnnotations2("assemblyPiece"), drawAnnotations2("lineageAnnotation"), drawLabels("part"), drawAnnotations2("part", partProps), drawAnnotations2("orf", {
114421
114854
  CompOverride: Orfs
@@ -114448,6 +114881,16 @@ function RowItem(props) {
114448
114881
  sequenceLength,
114449
114882
  cutsites,
114450
114883
  showDnaColors,
114884
+ showSerineThreonine,
114885
+ showHydrophobicity,
114886
+ showPolar,
114887
+ showNegative,
114888
+ showPositive,
114889
+ showCharged,
114890
+ showAliphatic,
114891
+ showAromatic,
114892
+ showColorScheme,
114893
+ showPhysicalProperties: isProteinAlignmentView,
114451
114894
  fivePrimeThreePrimeHints,
114452
114895
  scrollData,
114453
114896
  hideBps: charWidth2 < 7,
@@ -114569,7 +115012,8 @@ function RowItem(props) {
114569
115012
  style: {
114570
115013
  left: startOffset * charWidth2,
114571
115014
  height: sequenceHeight,
114572
- position: "absolute"
115015
+ position: "absolute",
115016
+ userSelect: "none"
114573
115017
  },
114574
115018
  onClick: /* @__PURE__ */ __name(function(event) {
114575
115019
  replacementLayerClicked({
@@ -114616,7 +115060,8 @@ function RowItem(props) {
114616
115060
  Caret$2,
114617
115061
  __spreadProps(__spreadValues({
114618
115062
  caretPosition: caretPosition2,
114619
- isProtein: isProtein2
115063
+ isProtein: isProtein2,
115064
+ showAminoAcidUnitAsCodon
114620
115065
  }, __spreadValues(__spreadValues({}, annotationCommonProps), { getGaps: void 0 })), {
114621
115066
  row: alignmentData ? { start: 0, end: alignmentData.sequence.length - 1 } : row
114622
115067
  })
@@ -114624,7 +115069,7 @@ function RowItem(props) {
114624
115069
  rowBottomComp && rowBottomComp
114625
115070
  );
114626
115071
  }
114627
- __name(RowItem, "RowItem");
115072
+ __name(RowItem$1, "RowItem$1");
114628
115073
  function getGapMap$1(sequence2) {
114629
115074
  const gapMap = [0];
114630
115075
  sequence2.split("").forEach((char) => {
@@ -116141,7 +116586,7 @@ function showFileDialog({ multiple = false, onSelect }) {
116141
116586
  input.click();
116142
116587
  }
116143
116588
  __name(showFileDialog, "showFileDialog");
116144
- const version = "0.8.2";
116589
+ const version = "0.8.3";
116145
116590
  const packageJson = {
116146
116591
  version
116147
116592
  };
@@ -119869,7 +120314,8 @@ const _SequenceInputNoHotkeys = class _SequenceInputNoHotkeys extends React__def
119869
120314
  isProtein: isProtein2,
119870
120315
  caretPosition: caretPosition2,
119871
120316
  sequenceData: sequenceData2,
119872
- maxInsertSize
120317
+ maxInsertSize,
120318
+ showAminoAcidUnitAsCodon
119873
120319
  } = this.props;
119874
120320
  const { charsToInsert, hasTempError } = this.state;
119875
120321
  let message;
@@ -119879,9 +120325,9 @@ const _SequenceInputNoHotkeys = class _SequenceInputNoHotkeys extends React__def
119879
120325
  selectionLayer2,
119880
120326
  sequenceLength
119881
120327
  );
119882
- message = /* @__PURE__ */ React__default.createElement("span", null, "Press ", /* @__PURE__ */ React__default.createElement("span", { style: { fontWeight: "bolder" } }, "ENTER"), " to replace", " ", divideBy3(getRangeLength(selectionLayer2, sequenceLength), isProtein2), " ", isProtein2 ? "AAs" : "base pairs", " between", " ", isProtein2 ? convertDnaCaretPositionOrRangeToAA(betweenVals[0]) : betweenVals[0], " ", "and", " ", isProtein2 ? convertDnaCaretPositionOrRangeToAA(betweenVals[1] + 2) : betweenVals[1]);
120328
+ message = /* @__PURE__ */ React__default.createElement("span", null, "Press ", /* @__PURE__ */ React__default.createElement("span", { style: { fontWeight: "bolder" } }, "ENTER"), " to replace", " ", divideBy3(getRangeLength(selectionLayer2, sequenceLength), isProtein2), " ", isProtein2 ? showAminoAcidUnitAsCodon ? "codons" : "AAs" : "base pairs", " ", "between", " ", isProtein2 ? convertDnaCaretPositionOrRangeToAA(betweenVals[0]) : betweenVals[0], " ", "and", " ", isProtein2 ? convertDnaCaretPositionOrRangeToAA(betweenVals[1] + 2) : betweenVals[1]);
119883
120329
  } else {
119884
- message = /* @__PURE__ */ React__default.createElement("span", null, "Press ", /* @__PURE__ */ React__default.createElement("span", { style: { fontWeight: "bolder" } }, "ENTER"), " to insert", " ", charsToInsert.length, " ", isProtein2 ? "AAs" : "base pairs", " after", " ", isProtein2 ? "AA" : "base", " ", isProtein2 ? convertDnaCaretPositionOrRangeToAA(caretPosition2) : caretPosition2);
120330
+ message = /* @__PURE__ */ React__default.createElement("span", null, "Press ", /* @__PURE__ */ React__default.createElement("span", { style: { fontWeight: "bolder" } }, "ENTER"), " to insert", " ", charsToInsert.length, " ", isProtein2 ? `${showAminoAcidUnitAsCodon ? "codons" : "AAs"}` : "base pairs", " ", "after", " ", isProtein2 ? `${showAminoAcidUnitAsCodon ? "codon" : "AA"}` : "base", " ", isProtein2 ? convertDnaCaretPositionOrRangeToAA(caretPosition2) : caretPosition2);
119885
120331
  }
119886
120332
  return /* @__PURE__ */ React__default.createElement("div", { className: "sequenceInputBubble" }, /* @__PURE__ */ React__default.createElement(
119887
120333
  "input",
@@ -120933,7 +121379,8 @@ function VectorInteractionHOC(Component2) {
120933
121379
  sequenceData: sequenceData2 = { sequence: "" },
120934
121380
  readOnly: readOnly2,
120935
121381
  disableBpEditing,
120936
- maxInsertSize
121382
+ maxInsertSize,
121383
+ showAminoAcidUnitAsCodon
120937
121384
  // updateSequenceData,
120938
121385
  // wrappedInsertSequenceDataAtPositionOrRange
120939
121386
  // handleInsert
@@ -120955,6 +121402,7 @@ function VectorInteractionHOC(Component2) {
120955
121402
  sequenceLength,
120956
121403
  caretPosition: caretPosition2,
120957
121404
  maxInsertSize,
121405
+ showAminoAcidUnitAsCodon,
120958
121406
  handleInsert: /* @__PURE__ */ __name((seqDataToInsert) => __async(this, null, function* () {
120959
121407
  yield insertAndSelectHelper({
120960
121408
  props: this.props,
@@ -121877,8 +122325,14 @@ function getEditDeleteHandlers(type2, annotation) {
121877
122325
  ];
121878
122326
  }
121879
122327
  __name(getEditDeleteHandlers, "getEditDeleteHandlers");
121880
- function SequenceName({ sequenceName, sequenceLength, isProtein: isProtein2 }) {
121881
- return /* @__PURE__ */ React__default.createElement("div", { key: "sequenceNameText", className: "sequenceNameText" }, /* @__PURE__ */ React__default.createElement("span", null, sequenceName, " "), /* @__PURE__ */ React__default.createElement("br", null), /* @__PURE__ */ React__default.createElement("span", null, isProtein2 ? `${Math.floor(sequenceLength / 3)} AAs` : `${sequenceLength} bps`));
122328
+ function SequenceName({
122329
+ sequenceName,
122330
+ sequenceLength,
122331
+ isProtein: isProtein2,
122332
+ showAminoAcidUnitAsCodon
122333
+ }) {
122334
+ const proteinUnits = showAminoAcidUnitAsCodon ? "codons" : "AAs";
122335
+ return /* @__PURE__ */ React__default.createElement("div", { key: "sequenceNameText", className: "sequenceNameText" }, /* @__PURE__ */ React__default.createElement("span", null, sequenceName, " "), /* @__PURE__ */ React__default.createElement("br", null), /* @__PURE__ */ React__default.createElement("span", null, isProtein2 ? `${Math.floor(sequenceLength / 3)} ${proteinUnits}` : `${sequenceLength} bps`));
121882
122336
  }
121883
122337
  __name(SequenceName, "SequenceName");
121884
122338
  function massageTickSpacing(spacing) {
@@ -123153,7 +123607,15 @@ function PinchHelper({ children, onPinch }) {
123153
123607
  target
123154
123608
  }
123155
123609
  );
123156
- return /* @__PURE__ */ React__default.createElement("div", { ref: target, className: "tg-pinch-helper" }, children);
123610
+ return /* @__PURE__ */ React__default.createElement(
123611
+ "div",
123612
+ {
123613
+ ref: target,
123614
+ style: { overflowX: "hidden" },
123615
+ className: "tg-pinch-helper"
123616
+ },
123617
+ children
123618
+ );
123157
123619
  }
123158
123620
  __name(PinchHelper, "PinchHelper");
123159
123621
  function isElWithinAnotherEl(el, container) {
@@ -123416,6 +123878,78 @@ function ZoomLinearView({
123416
123878
  ));
123417
123879
  }
123418
123880
  __name(ZoomLinearView, "ZoomLinearView");
123881
+ function BarPlot({
123882
+ data,
123883
+ width = 300,
123884
+ height = 30,
123885
+ barColors,
123886
+ className
123887
+ }) {
123888
+ if (!data || data.length === 0) return null;
123889
+ const maxVal = Math.max(...data);
123890
+ const barWidth = width / data.length;
123891
+ return /* @__PURE__ */ React.createElement("svg", { width, height, className }, data.map((val2, i) => {
123892
+ const barHeight = val2 / maxVal * (height - 2);
123893
+ return /* @__PURE__ */ React.createElement(
123894
+ "rect",
123895
+ {
123896
+ "data-tip": `${val2 == null ? void 0 : val2.toFixed(1)}%`,
123897
+ key: i,
123898
+ x: i * barWidth + 1,
123899
+ y: height - barHeight,
123900
+ width: barWidth - 2,
123901
+ height: barHeight,
123902
+ fill: barColors ? barColors[i % barColors.length] : "#3498db",
123903
+ rx: 2
123904
+ }
123905
+ );
123906
+ }), /* @__PURE__ */ React.createElement(
123907
+ "line",
123908
+ {
123909
+ x1: 1,
123910
+ y1: height - 0.5 * (height - 2),
123911
+ x2: width,
123912
+ y2: height - 0.5 * (height - 2),
123913
+ stroke: "white",
123914
+ strokeDasharray: "4,2",
123915
+ strokeWidth: 1
123916
+ }
123917
+ ), /* @__PURE__ */ React.createElement(
123918
+ "line",
123919
+ {
123920
+ x1: 0,
123921
+ y1: height,
123922
+ x2: width,
123923
+ y2: height,
123924
+ stroke: "#333",
123925
+ strokeWidth: 1
123926
+ }
123927
+ ));
123928
+ }
123929
+ __name(BarPlot, "BarPlot");
123930
+ function AminoAcidCirclePlot({ data, width, className }) {
123931
+ const n2 = data.length;
123932
+ if (n2 === 0) return null;
123933
+ const padding = 5;
123934
+ const availableWidth = width - 3 * padding;
123935
+ const spacing = n2 > 1 ? availableWidth / (n2 - 1) : 0;
123936
+ const maxRadius = spacing / 2 - 2 > 0 ? spacing / 2 - 2 : 8;
123937
+ const radius = Math.max(8, Math.min(maxRadius, 20));
123938
+ const svgHeight = radius * 2 + 10;
123939
+ return /* @__PURE__ */ React.createElement("svg", { width, height: svgHeight, className }, data.map((d2, idx) => /* @__PURE__ */ React.createElement("g", { key: idx }, /* @__PURE__ */ React.createElement(
123940
+ "circle",
123941
+ {
123942
+ "data-tip": d2.group,
123943
+ cx: idx * spacing + radius,
123944
+ cy: radius + 2,
123945
+ r: radius,
123946
+ fill: d2.color,
123947
+ stroke: "#333",
123948
+ strokeWidth: 1
123949
+ }
123950
+ ))));
123951
+ }
123952
+ __name(AminoAcidCirclePlot, "AminoAcidCirclePlot");
123419
123953
  const defaultMarginWidth = 10;
123420
123954
  const __LinearView = class __LinearView extends React__default.Component {
123421
123955
  constructor() {
@@ -123522,6 +124056,7 @@ const __LinearView = class __LinearView extends React__default.Component {
123522
124056
  callback2(callbackVals);
123523
124057
  }
123524
124058
  render() {
124059
+ var _b2, _c;
123525
124060
  const _a2 = this.props, {
123526
124061
  sequenceData: sequenceData2 = { sequence: "" },
123527
124062
  alignmentData,
@@ -123544,7 +124079,8 @@ const __LinearView = class __LinearView extends React__default.Component {
123544
124079
  linearViewCharWidth,
123545
124080
  annotationVisibilityOverrides,
123546
124081
  isProtein: isProtein2,
123547
- noWarnings
124082
+ noWarnings,
124083
+ showAminoAcidUnitAsCodon
123548
124084
  } = _a2, rest = __objRest(_a2, [
123549
124085
  //currently found in props
123550
124086
  "sequenceData",
@@ -123568,7 +124104,8 @@ const __LinearView = class __LinearView extends React__default.Component {
123568
124104
  "linearViewCharWidth",
123569
124105
  "annotationVisibilityOverrides",
123570
124106
  "isProtein",
123571
- "noWarnings"
124107
+ "noWarnings",
124108
+ "showAminoAcidUnitAsCodon"
123572
124109
  ]);
123573
124110
  const bpsPerRow = this.getMaxLength();
123574
124111
  let innerWidth = Math.max(width - marginWidth - 20, 0);
@@ -123680,13 +124217,28 @@ const __LinearView = class __LinearView extends React__default.Component {
123680
124217
  SequenceName,
123681
124218
  __spreadValues({}, {
123682
124219
  isProtein: isProtein2,
124220
+ showAminoAcidUnitAsCodon,
123683
124221
  sequenceName,
123684
124222
  sequenceLength: sequenceData2.sequence ? sequenceData2.sequence.length : 0
123685
124223
  })
123686
124224
  ),
123687
124225
  !noWarnings && /* @__PURE__ */ React__default.createElement(VeTopRightContainer, null, this.paredDownMessages),
123688
- /* @__PURE__ */ React__default.createElement(PinchHelperToUse, __spreadValues({}, linearZoomEnabled && pinchHandler), /* @__PURE__ */ React__default.createElement(
123689
- RowItem,
124226
+ /* @__PURE__ */ React__default.createElement(PinchHelperToUse, __spreadValues({}, linearZoomEnabled && pinchHandler), sequenceData2.isProtein && sequenceData2.name === "Consensus" && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, annotationVisibilityOverrides.conservation && /* @__PURE__ */ React__default.createElement(
124227
+ BarPlot,
124228
+ {
124229
+ className: "ve-linear-view-conservation-plot",
124230
+ data: (_b2 = sequenceData2 == null ? void 0 : sequenceData2.aminoAcidProperties) == null ? void 0 : _b2.frequencies,
124231
+ width
124232
+ }
124233
+ ), annotationVisibilityOverrides.properties && /* @__PURE__ */ React__default.createElement(
124234
+ AminoAcidCirclePlot,
124235
+ {
124236
+ className: "ve-linear-view-property-analysis-plot",
124237
+ data: (_c = sequenceData2 == null ? void 0 : sequenceData2.aminoAcidProperties) == null ? void 0 : _c.propertyAnalysis,
124238
+ width
124239
+ }
124240
+ )), /* @__PURE__ */ React__default.createElement(
124241
+ RowItem$1,
123690
124242
  __spreadProps(__spreadValues({}, __spreadValues(__spreadProps(__spreadValues({}, rest), {
123691
124243
  editorName,
123692
124244
  onScroll: /* @__PURE__ */ __name(() => {
@@ -123890,7 +124442,8 @@ const _Minimap = class _Minimap extends React__default.Component {
123890
124442
  alignmentTracks = [],
123891
124443
  dimensions: { width = 200 },
123892
124444
  laneHeight,
123893
- laneSpacing = 1
124445
+ laneSpacing = 1,
124446
+ isTrackSelected = []
123894
124447
  } = this.props;
123895
124448
  const charWidth2 = this.getCharWidth();
123896
124449
  const {
@@ -123929,7 +124482,7 @@ const _Minimap = class _Minimap extends React__default.Component {
123929
124482
  "div",
123930
124483
  {
123931
124484
  key: i + "-lane",
123932
- className: "minimapLane",
124485
+ className: `minimapLane ${isTrackSelected[i] ? "isTrackSelected" : ""}`,
123933
124486
  "data-lane-index": i,
123934
124487
  style: { height: laneHeight, maxHeight: laneHeight }
123935
124488
  },
@@ -123953,7 +124506,8 @@ const _Minimap = class _Minimap extends React__default.Component {
123953
124506
  "numBpsShownInLinearView",
123954
124507
  "scrollAlignmentView",
123955
124508
  "laneHeight",
123956
- "laneSpacing"
124509
+ "laneSpacing",
124510
+ "isTrackSelected"
123957
124511
  ].some((key) => props[key] !== newProps[key]))
123958
124512
  return true;
123959
124513
  return false;
@@ -124267,6 +124821,17 @@ function VisibilityOptions$2({
124267
124821
  } else {
124268
124822
  annotationCountToUse = annotationsWithCounts[0];
124269
124823
  }
124824
+ const subMenuElements = ["physicalProperties", "plot"];
124825
+ const physicalPropertyElements = [
124826
+ "hydrophobicity",
124827
+ "polar",
124828
+ "negative",
124829
+ "positive",
124830
+ "charged",
124831
+ "aliphatic",
124832
+ "aromatic"
124833
+ ];
124834
+ const plotElements = ["conservation", "properties"];
124270
124835
  return /* @__PURE__ */ React__default.createElement(
124271
124836
  Menu,
124272
124837
  {
@@ -124274,36 +124839,107 @@ function VisibilityOptions$2({
124274
124839
  className: "alignmentAnnotationVisibilityToolInner"
124275
124840
  },
124276
124841
  map$3(togglableAlignmentAnnotationSettings, (visible, annotationName) => {
124277
- return /* @__PURE__ */ React__default.createElement(
124278
- MenuItem,
124279
- {
124280
- icon: visible ? "tick" : "",
124281
- onClick: /* @__PURE__ */ __name((e) => {
124282
- e.stopPropagation();
124283
- if (annotationName === "axis") {
124284
- return alignmentAnnotationVisibilityToggle({
124285
- axisNumbers: !visible,
124286
- axis: !visible
124842
+ if (!physicalPropertyElements.includes(annotationName) && !plotElements.includes(annotationName)) {
124843
+ return /* @__PURE__ */ React__default.createElement(
124844
+ MenuItem,
124845
+ {
124846
+ icon: visible && !subMenuElements.includes(annotationName) ? "tick" : "",
124847
+ onClick: /* @__PURE__ */ __name((e) => {
124848
+ e.stopPropagation();
124849
+ if (annotationName === "axis") {
124850
+ return alignmentAnnotationVisibilityToggle({
124851
+ axisNumbers: !visible,
124852
+ axis: !visible
124853
+ });
124854
+ }
124855
+ if (annotationName === "cdsFeatureTranslations" && !visible) {
124856
+ return alignmentAnnotationVisibilityToggle({
124857
+ cdsFeatureTranslations: !visible,
124858
+ translations: !visible
124859
+ });
124860
+ }
124861
+ alignmentAnnotationVisibilityToggle({
124862
+ [annotationName]: !visible
124287
124863
  });
124864
+ }, "onClick"),
124865
+ text: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, startCase(annotationName).replace("Cds", "CDS").replace("Dna", "DNA"), annotationName in annotationCountToUse ? /* @__PURE__ */ React__default.createElement(Tag, { round: true, style: { marginLeft: 7 } }, annotationCountToUse[annotationName]) : ""),
124866
+ key: annotationName
124867
+ },
124868
+ annotationName === "physicalProperties" ? map$3(
124869
+ togglableAlignmentAnnotationSettings,
124870
+ (_visible, _annotationName) => {
124871
+ if (physicalPropertyElements.includes(_annotationName)) {
124872
+ return /* @__PURE__ */ React__default.createElement(
124873
+ MenuItem,
124874
+ {
124875
+ icon: _visible ? "tick" : "",
124876
+ onClick: /* @__PURE__ */ __name((e) => {
124877
+ e.stopPropagation();
124878
+ alignmentAnnotationVisibilityToggle({
124879
+ [_annotationName]: !_visible
124880
+ });
124881
+ }, "onClick"),
124882
+ text: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, startCase(_annotationName)),
124883
+ key: _annotationName
124884
+ }
124885
+ );
124886
+ }
124288
124887
  }
124289
- if (annotationName === "cdsFeatureTranslations" && !visible) {
124290
- return alignmentAnnotationVisibilityToggle({
124291
- cdsFeatureTranslations: !visible,
124292
- translations: !visible
124293
- });
124888
+ ).filter(Boolean) : annotationName === "plot" ? map$3(
124889
+ togglableAlignmentAnnotationSettings,
124890
+ (_visible, _annotationName) => {
124891
+ if (plotElements.includes(_annotationName)) {
124892
+ return /* @__PURE__ */ React__default.createElement("div", { style: { position: "relative" } }, /* @__PURE__ */ React__default.createElement(
124893
+ MenuItem,
124894
+ {
124895
+ className: `plot-${_annotationName}`,
124896
+ icon: _visible ? "tick" : "",
124897
+ onClick: /* @__PURE__ */ __name((e) => {
124898
+ e.stopPropagation();
124899
+ alignmentAnnotationVisibilityToggle({
124900
+ [_annotationName]: !_visible
124901
+ });
124902
+ }, "onClick"),
124903
+ text: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, startCase(_annotationName)),
124904
+ key: _annotationName
124905
+ }
124906
+ ), _annotationName === "properties" ? /* @__PURE__ */ React__default.createElement(
124907
+ Button,
124908
+ {
124909
+ icon: "info-sign",
124910
+ style: {
124911
+ position: "absolute",
124912
+ top: 3,
124913
+ right: 0
124914
+ },
124915
+ onClick: /* @__PURE__ */ __name(() => {
124916
+ showDialog({
124917
+ ModalComponent: PropertyDialog
124918
+ });
124919
+ }, "onClick"),
124920
+ minimal: true,
124921
+ small: true
124922
+ }
124923
+ ) : null);
124924
+ }
124294
124925
  }
124295
- alignmentAnnotationVisibilityToggle({
124296
- [annotationName]: !visible
124297
- });
124298
- }, "onClick"),
124299
- text: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, startCase(annotationName).replace("Cds", "CDS").replace("Dna", "DNA"), annotationName in annotationCountToUse ? /* @__PURE__ */ React__default.createElement(Tag, { round: true, style: { marginLeft: 7 } }, annotationCountToUse[annotationName]) : ""),
124300
- key: annotationName
124301
- }
124302
- );
124926
+ ).filter(Boolean) : null
124927
+ );
124928
+ }
124303
124929
  })
124304
124930
  );
124305
124931
  }
124306
124932
  __name(VisibilityOptions$2, "VisibilityOptions$2");
124933
+ const PropertyDialog = compose$1(
124934
+ wrapDialog({
124935
+ title: "Amino Acid Properties",
124936
+ style: {
124937
+ width: 600
124938
+ }
124939
+ })
124940
+ )(function() {
124941
+ return /* @__PURE__ */ React__default.createElement("div", { style: { width: "100%", padding: 10 } }, /* @__PURE__ */ React__default.createElement("img", { src: "/aaprops.svg", width: 580, alt: "Amino Acid Properties" }));
124942
+ });
124307
124943
  const _SimpleGenericDialogForm = class _SimpleGenericDialogForm extends React__default.Component {
124308
124944
  render() {
124309
124945
  const {
@@ -124474,7 +125110,8 @@ function Caret({
124474
125110
  innerRadius,
124475
125111
  outerRadius,
124476
125112
  isProtein: isProtein2,
124477
- selectionMessage
125113
+ selectionMessage,
125114
+ showAminoAcidUnitAsCodon
124478
125115
  }) {
124479
125116
  const { startAngle, endAngle } = getRangeAngles(
124480
125117
  { start: caretPosition2, end: caretPosition2 },
@@ -124495,7 +125132,12 @@ function Caret({
124495
125132
  transform,
124496
125133
  className: className + " veCaret " + draggableClassnames.caret
124497
125134
  },
124498
- /* @__PURE__ */ React__default.createElement("title", null, selectionMessage || getSelectionMessage({ caretPosition: caretPosition2, isProtein: isProtein2, sequenceLength })),
125135
+ /* @__PURE__ */ React__default.createElement("title", null, selectionMessage || getSelectionMessage({
125136
+ caretPosition: caretPosition2,
125137
+ isProtein: isProtein2,
125138
+ sequenceLength,
125139
+ showAminoAcidUnitAsCodon
125140
+ })),
124499
125141
  /* @__PURE__ */ React__default.createElement(
124500
125142
  "line",
124501
125143
  {
@@ -124792,7 +125434,8 @@ function SelectionLayer({
124792
125434
  onRightClicked,
124793
125435
  onClick,
124794
125436
  index: index2,
124795
- isProtein: isProtein2
125437
+ isProtein: isProtein2,
125438
+ showAminoAcidUnitAsCodon
124796
125439
  }) {
124797
125440
  const {
124798
125441
  color: color2,
@@ -124817,7 +125460,8 @@ function SelectionLayer({
124817
125460
  const selectionMessage = getSelectionMessage({
124818
125461
  sequenceLength,
124819
125462
  selectionLayer: selectionLayer2,
124820
- isProtein: isProtein2
125463
+ isProtein: isProtein2,
125464
+ showAminoAcidUnitAsCodon
124821
125465
  });
124822
125466
  const { transform } = PositionAnnotationOnCircle({
124823
125467
  sAngle: startAngle,
@@ -125454,6 +126098,7 @@ function CircularView(props) {
125454
126098
  readOnly: readOnly2,
125455
126099
  hideName = false,
125456
126100
  editorName,
126101
+ showAminoAcidUnitAsCodon,
125457
126102
  smartCircViewLabelRender,
125458
126103
  showCicularViewInternalLabels,
125459
126104
  withRotateCircularView: _withRotateCircularView,
@@ -125833,6 +126478,7 @@ function CircularView(props) {
125833
126478
  key: "veCircularViewSelectionLayer" + index2
125834
126479
  }, {
125835
126480
  index: index2,
126481
+ showAminoAcidUnitAsCodon,
125836
126482
  isDraggable: true,
125837
126483
  isProtein: isProtein2,
125838
126484
  selectionLayer: selectionLayer22,
@@ -125859,6 +126505,7 @@ function CircularView(props) {
125859
126505
  key: "veCircularViewCaret"
125860
126506
  }, {
125861
126507
  caretPosition: caretPosition2,
126508
+ showAminoAcidUnitAsCodon,
125862
126509
  sequenceLength,
125863
126510
  isProtein: isProtein2,
125864
126511
  innerRadius,
@@ -125871,7 +126518,8 @@ function CircularView(props) {
125871
126518
  if (radius < 150) radius = 150;
125872
126519
  const widthToUse = Math.max(Number(width) || 300);
125873
126520
  const heightToUse = Math.max(Number(height) || 300);
125874
- const bpTitle = isProtein2 ? `${Math.floor(sequenceLength / 3)} AAs` : `${sequenceLength} bps`;
126521
+ const proteinUnits = showAminoAcidUnitAsCodon ? "codons" : "AAs";
126522
+ const bpTitle = isProtein2 ? `${Math.floor(sequenceLength / 3)} ${proteinUnits}` : `${sequenceLength} bps`;
125875
126523
  const nameEl = /* @__PURE__ */ React__default.createElement(
125876
126524
  "div",
125877
126525
  {
@@ -132845,7 +133493,7 @@ const __RowView = class __RowView extends React__default.Component {
132845
133493
  }
132846
133494
  if (rowData[index2]) {
132847
133495
  const rowItem = /* @__PURE__ */ React__default.createElement("div", { "data-row-number": index2, key: index2 }, /* @__PURE__ */ React__default.createElement("div", { className: "veRowItemSpacer" }), /* @__PURE__ */ React__default.createElement(
132848
- RowItem,
133496
+ RowItem$1,
132849
133497
  __spreadProps(__spreadValues({}, __spreadValues(__spreadProps(__spreadValues({}, rest), {
132850
133498
  rowTopComp,
132851
133499
  truncateLabelsThatDoNotFit,
@@ -133490,7 +134138,8 @@ const SelectDialog = compose$1(
133490
134138
  extraProps,
133491
134139
  isProtein: isProtein2,
133492
134140
  invalid,
133493
- handleSubmit
134141
+ handleSubmit,
134142
+ showAminoAcidUnitAsCodon
133494
134143
  } = this.props;
133495
134144
  const selectionLength = getRangeLength(
133496
134145
  {
@@ -133561,7 +134210,7 @@ const SelectDialog = compose$1(
133561
134210
  {
133562
134211
  type: "submit",
133563
134212
  intent: Intent.PRIMARY,
133564
- text: `Select ${invalid ? 0 : selectionLength} ${isProtein2 ? "AA" : "BP"}${selectionLength === 1 ? "" : "s"}`,
134213
+ text: `Select ${invalid ? 0 : selectionLength} ${isProtein2 ? `${showAminoAcidUnitAsCodon ? "codon" : "AA"}` : "BP"}${selectionLength === 1 ? "" : "s"}`,
133565
134214
  disabled: invalid
133566
134215
  }
133567
134216
  ))
@@ -133604,7 +134253,7 @@ const EnzymeViewer = /* @__PURE__ */ __name(({
133604
134253
  }
133605
134254
  ),
133606
134255
  /* @__PURE__ */ React__default.createElement(
133607
- RowItem,
134256
+ RowItem$1,
133608
134257
  __spreadValues({}, {
133609
134258
  charWidth: charWidth2,
133610
134259
  tickSpacing: 1,
@@ -137089,61 +137738,50 @@ function getPairwiseOverviewLinearViewOptions({ isTemplate }) {
137089
137738
  }
137090
137739
  }
137091
137740
  __name(getPairwiseOverviewLinearViewOptions, "getPairwiseOverviewLinearViewOptions");
137092
- const _PairwiseAlignmentView = class _PairwiseAlignmentView extends React__default.Component {
137093
- constructor() {
137094
- super(...arguments);
137095
- __publicField(this, "state", {
137096
- currentPairwiseAlignmentIndex: void 0
137097
- });
137098
- }
137099
- render() {
137100
- const { pairwiseAlignments, pairwiseOverviewAlignmentTracks } = this.props;
137101
- const { currentPairwiseAlignmentIndex } = this.state;
137102
- if (currentPairwiseAlignmentIndex > -1) {
137103
- const alignmentTracks = pairwiseAlignments[currentPairwiseAlignmentIndex];
137104
- const templateLength = alignmentTracks[0].alignmentData.sequence.length;
137105
- return /* @__PURE__ */ React__default.createElement(
137106
- AlignmentView,
137107
- __spreadValues({}, __spreadProps(__spreadValues({}, this.props), {
137108
- sequenceData: {
137109
- //pass fake seq data in so editor interactions work
137110
- sequence: Array.from(templateLength).map(() => "a").join("")
137111
- },
137112
- allowTrackRearrange: false,
137113
- alignmentTracks,
137114
- hasTemplate: true,
137115
- isPairwise: true,
137116
- currentPairwiseAlignmentIndex,
137117
- handleBackButtonClicked: /* @__PURE__ */ __name(() => {
137118
- this.setState({
137119
- currentPairwiseAlignmentIndex: void 0
137120
- });
137121
- }, "handleBackButtonClicked")
137122
- }))
137123
- );
137124
- } else {
137125
- return /* @__PURE__ */ React__default.createElement(
137126
- AlignmentView,
137127
- __spreadValues({}, __spreadProps(__spreadValues({}, this.props), {
137128
- alignmentTracks: pairwiseOverviewAlignmentTracks,
137129
- allowTrackRearrange: false,
137130
- allowTrimming: false,
137131
- hasTemplate: true,
137132
- isPairwise: true,
137133
- isInPairwiseOverviewView: true,
137134
- isFullyZoomedOut: true,
137135
- noClickDragHandlers: true,
137136
- linearViewOptions: getPairwiseOverviewLinearViewOptions,
137137
- handleSelectTrack: /* @__PURE__ */ __name((trackIndex) => {
137138
- this.setState({ currentPairwiseAlignmentIndex: trackIndex - 1 });
137139
- }, "handleSelectTrack")
137140
- }))
137141
- );
137142
- }
137741
+ function PairwiseAlignmentView(props) {
137742
+ const [currentPairwiseAlignmentIndex, setCurrentPairwiseAlignmentIndex] = useState(void 0);
137743
+ const { pairwiseAlignments, pairwiseOverviewAlignmentTracks } = props;
137744
+ if (currentPairwiseAlignmentIndex > -1) {
137745
+ const alignmentTracks = pairwiseAlignments[currentPairwiseAlignmentIndex];
137746
+ const templateLength = alignmentTracks[0].alignmentData.sequence.length;
137747
+ return /* @__PURE__ */ React__default.createElement(
137748
+ AlignmentView,
137749
+ __spreadValues({}, __spreadProps(__spreadValues({}, props), {
137750
+ sequenceData: {
137751
+ //pass fake seq data in so editor interactions work
137752
+ sequence: Array.from(templateLength).map(() => "a").join("")
137753
+ },
137754
+ allowTrackRearrange: false,
137755
+ alignmentTracks,
137756
+ hasTemplate: true,
137757
+ isPairwise: true,
137758
+ currentPairwiseAlignmentIndex,
137759
+ handleBackButtonClicked: /* @__PURE__ */ __name(() => {
137760
+ setCurrentPairwiseAlignmentIndex(void 0);
137761
+ }, "handleBackButtonClicked")
137762
+ }))
137763
+ );
137764
+ } else {
137765
+ return /* @__PURE__ */ React__default.createElement(
137766
+ AlignmentView,
137767
+ __spreadValues({}, __spreadProps(__spreadValues({}, props), {
137768
+ alignmentTracks: pairwiseOverviewAlignmentTracks,
137769
+ allowTrackRearrange: false,
137770
+ allowTrimming: false,
137771
+ hasTemplate: true,
137772
+ isPairwise: true,
137773
+ isInPairwiseOverviewView: true,
137774
+ isFullyZoomedOut: true,
137775
+ noClickDragHandlers: true,
137776
+ linearViewOptions: getPairwiseOverviewLinearViewOptions,
137777
+ handleSelectTrack: /* @__PURE__ */ __name((trackIndex) => {
137778
+ setCurrentPairwiseAlignmentIndex(trackIndex - 1);
137779
+ }, "handleSelectTrack")
137780
+ }))
137781
+ );
137143
137782
  }
137144
- };
137145
- __name(_PairwiseAlignmentView, "PairwiseAlignmentView");
137146
- let PairwiseAlignmentView = _PairwiseAlignmentView;
137783
+ }
137784
+ __name(PairwiseAlignmentView, "PairwiseAlignmentView");
137147
137785
  function updateTrackHelper({
137148
137786
  currentPairwiseAlignmentIndex,
137149
137787
  pairwiseAlignments,
@@ -137221,6 +137859,551 @@ function coerceInitialValue({ initialValue, minCharWidth }) {
137221
137859
  }
137222
137860
  __name(coerceInitialValue, "coerceInitialValue");
137223
137861
  const tabHeight = 34;
137862
+ const LabileSitesLayer = /* @__PURE__ */ __name(({ leftMargin, charWidth: charWidth2, positionsToMark = [] }) => {
137863
+ return /* @__PURE__ */ React__default.createElement("div", { className: "veLabileSites" }, positionsToMark == null ? void 0 : positionsToMark.map((pos, i) => {
137864
+ const x = leftMargin + (pos - 1.2) * charWidth2 + charWidth2 / 2;
137865
+ return /* @__PURE__ */ React__default.createElement(
137866
+ "div",
137867
+ {
137868
+ className: "veAlignmentViewLabileSiteLine",
137869
+ key: i,
137870
+ style: {
137871
+ left: x
137872
+ }
137873
+ }
137874
+ );
137875
+ }));
137876
+ }, "LabileSitesLayer");
137877
+ function calculateAminoAcidFrequency(sequence2, isProtein2) {
137878
+ if (!sequence2 || typeof sequence2 !== "string") {
137879
+ console.warn("Invalid or empty amino acid sequence provided.");
137880
+ }
137881
+ const standards = isProtein2 ? "ACDEFGHIKLMNPQRSTVWY-".split("") : "ATCG-".split("");
137882
+ const frequencies = {};
137883
+ standards.forEach((a2) => {
137884
+ frequencies[a2] = { count: 0, percentage: 0 };
137885
+ });
137886
+ const nonStandard = {};
137887
+ let totalCount = 0;
137888
+ for (const char of sequence2.toUpperCase()) {
137889
+ if (frequencies[char]) {
137890
+ frequencies[char].count++;
137891
+ totalCount++;
137892
+ } else {
137893
+ nonStandard[char] = (nonStandard[char] || 0) + 1;
137894
+ }
137895
+ }
137896
+ if (totalCount > 0) {
137897
+ for (const a2 of standards) {
137898
+ frequencies[a2].percentage = frequencies[a2].count / totalCount * 100;
137899
+ }
137900
+ }
137901
+ return {
137902
+ totalStandards: totalCount,
137903
+ // Total count of elements
137904
+ totalLength: sequence2.length,
137905
+ // Total length including non-standard
137906
+ frequencies,
137907
+ nonStandard
137908
+ };
137909
+ }
137910
+ __name(calculateAminoAcidFrequency, "calculateAminoAcidFrequency");
137911
+ const aminoAcidShortNames = {
137912
+ A: "Ala",
137913
+ C: "Cys",
137914
+ D: "Asp",
137915
+ E: "Glu",
137916
+ F: "Phe",
137917
+ G: "Gly",
137918
+ H: "His",
137919
+ I: "Ile",
137920
+ K: "Lys",
137921
+ L: "Leu",
137922
+ M: "Met",
137923
+ N: "Asn",
137924
+ P: "Pro",
137925
+ Q: "Gln",
137926
+ R: "Arg",
137927
+ S: "Ser",
137928
+ T: "Thr",
137929
+ V: "Val",
137930
+ W: "Trp",
137931
+ Y: "Tyr",
137932
+ "-": "Gaps"
137933
+ };
137934
+ const PropertySidePanel = /* @__PURE__ */ __name(({ properties: properties2, setProperties, style: style2 }) => {
137935
+ const sidebarRef = React__default.useRef(null);
137936
+ const [mismatchesCount, setMismatchesCount] = React__default.useState(0);
137937
+ const [mismatchesInRange, setMismatchesInRange] = React__default.useState(0);
137938
+ const { track, isOpen, selection, isPairwise } = properties2;
137939
+ const getSequenceInRegion = useCallback$1(() => {
137940
+ var _a2, _b2;
137941
+ const seq = (_b2 = (_a2 = track == null ? void 0 : track.alignmentData) == null ? void 0 : _a2.sequence) != null ? _b2 : "";
137942
+ if (!selection || selection.start === -1 || selection.end === -1) {
137943
+ return seq;
137944
+ }
137945
+ const start2 = Math.max(0, selection.start);
137946
+ const end2 = Math.min(seq.length - 1, selection.end);
137947
+ if (start2 > end2) return "";
137948
+ return seq.slice(start2, end2 + 1);
137949
+ }, [track, selection]);
137950
+ const mismatchKey = isPairwise ? "additionalSelectionLayers" : "mismatches";
137951
+ const trackMismatches = useMemo$1(() => {
137952
+ const tr = track == null ? void 0 : track[mismatchKey];
137953
+ if (!Array.isArray(tr)) return [];
137954
+ return isPairwise ? tr.filter((m2) => (m2 == null ? void 0 : m2.color) === "red") : tr;
137955
+ }, [track, mismatchKey, isPairwise]);
137956
+ useEffect(() => {
137957
+ if (!isOpen || sidebarRef.current === null || !track) {
137958
+ return;
137959
+ }
137960
+ sidebarRef.current.focus();
137961
+ let mismatchCount = 0;
137962
+ trackMismatches == null ? void 0 : trackMismatches.forEach((tm) => {
137963
+ if (tm === null || tm.start === null || tm.end === null) {
137964
+ return;
137965
+ }
137966
+ const overlapStart = tm.start;
137967
+ const overlapEnd = tm.end;
137968
+ if (overlapEnd >= overlapStart) {
137969
+ mismatchCount += overlapEnd - overlapStart + 1;
137970
+ }
137971
+ });
137972
+ setMismatchesCount(mismatchCount);
137973
+ setMismatchesInRange(mismatchCount);
137974
+ if (selection && selection.start > -1 && selection.end > -1) {
137975
+ let count2 = 0;
137976
+ trackMismatches == null ? void 0 : trackMismatches.forEach((tm) => {
137977
+ if (tm === null || tm.start === null || tm.end === null) {
137978
+ return;
137979
+ }
137980
+ const overlapStart = Math.max(tm.start, selection.start);
137981
+ const overlapEnd = Math.min(tm.end, selection.end);
137982
+ if (overlapEnd >= overlapStart) {
137983
+ count2 += overlapEnd - overlapStart + 1;
137984
+ }
137985
+ });
137986
+ setMismatchesInRange(count2);
137987
+ }
137988
+ }, [isOpen, track, selection, trackMismatches]);
137989
+ const aminoFreq = useMemo$1(() => {
137990
+ var _a2, _b2;
137991
+ const seq = getSequenceInRegion();
137992
+ return calculateAminoAcidFrequency(
137993
+ seq,
137994
+ (_b2 = (_a2 = track == null ? void 0 : track.sequenceData) == null ? void 0 : _a2.isProtein) != null ? _b2 : false
137995
+ );
137996
+ }, [getSequenceInRegion, track]);
137997
+ if (!isOpen) {
137998
+ return null;
137999
+ }
138000
+ let trackInner;
138001
+ if (track) {
138002
+ const {
138003
+ name: name2,
138004
+ isProtein: isProtein2,
138005
+ proteinSize,
138006
+ size,
138007
+ molecularWeight,
138008
+ isoPoint,
138009
+ extinctionCoefficient
138010
+ } = track.sequenceData;
138011
+ const frequencyEntries = Object.entries(aminoFreq.frequencies);
138012
+ trackInner = /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
138013
+ "div",
138014
+ {
138015
+ style: {
138016
+ display: "flex",
138017
+ padding: 4,
138018
+ paddingTop: 11,
138019
+ paddingBottom: 11,
138020
+ width: "100%"
138021
+ }
138022
+ }
138023
+ ), /* @__PURE__ */ React__default.createElement("h5", null, "Track Properties"), /* @__PURE__ */ React__default.createElement("div", { className: "bp3-tab-panel" }, /* @__PURE__ */ React__default.createElement(RowItem, { item: name2, title: "Name" }), /* @__PURE__ */ React__default.createElement(RowItem, { item: isProtein2 ? proteinSize : size, title: "Length" }), /* @__PURE__ */ React__default.createElement(
138024
+ RowItem,
138025
+ {
138026
+ item: molecularWeight == null ? void 0 : molecularWeight.toFixed(2),
138027
+ title: "Molecular Weight",
138028
+ units: isProtein2 ? "Da" : "g/mol"
138029
+ }
138030
+ ), name2 !== "Consensus" && isProtein2 && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(RowItem, { item: isoPoint, title: "Isoelectric Point" }), /* @__PURE__ */ React__default.createElement(
138031
+ RowItem,
138032
+ {
138033
+ item: extinctionCoefficient,
138034
+ title: "Extinction Coefficient"
138035
+ }
138036
+ )), /* @__PURE__ */ React__default.createElement(
138037
+ RowItem,
138038
+ {
138039
+ item: `${mismatchesInRange}/${mismatchesCount}`,
138040
+ title: "Mismatches"
138041
+ }
138042
+ ), /* @__PURE__ */ React__default.createElement(
138043
+ RowItem,
138044
+ {
138045
+ item: selection && selection.start > -1 ? /* @__PURE__ */ React__default.createElement("span", null, selection.start + 1, " - ", selection.end + 1) : /* @__PURE__ */ React__default.createElement("span", null, "1 - ", isProtein2 ? proteinSize : size),
138046
+ title: "Region"
138047
+ }
138048
+ )), /* @__PURE__ */ React__default.createElement("h5", null, isProtein2 ? "Amino Acid" : "Base Pair", " Frequencies"), /* @__PURE__ */ React__default.createElement("div", { className: "sidebar-table" }, /* @__PURE__ */ React__default.createElement("div", { className: "sidebar-row" }, /* @__PURE__ */ React__default.createElement("div", { className: "sidebar-cell" }, "Amino Acid"), /* @__PURE__ */ React__default.createElement("div", { className: "sidebar-cell" }, "Count"), /* @__PURE__ */ React__default.createElement("div", { className: "sidebar-cell" }, "Percentage")), frequencyEntries.map(([aa, data], idx) => {
138049
+ return /* @__PURE__ */ React__default.createElement("div", { className: `sidebar-row property-amino-acid-${idx}` }, /* @__PURE__ */ React__default.createElement("div", { className: "sidebar-cell" }, aa, " ", isProtein2 ? `(${aminoAcidShortNames[aa]})` : ""), /* @__PURE__ */ React__default.createElement("div", { className: "sidebar-cell" }, data.count), /* @__PURE__ */ React__default.createElement("div", { className: "sidebar-cell" }, data.percentage.toFixed(1), "%"));
138050
+ })));
138051
+ } else {
138052
+ trackInner = /* @__PURE__ */ React__default.createElement(
138053
+ "div",
138054
+ {
138055
+ style: {
138056
+ marginTop: 20,
138057
+ fontStyle: "italic",
138058
+ fontSize: 16
138059
+ }
138060
+ },
138061
+ "Click on a track to view its properties"
138062
+ );
138063
+ }
138064
+ return /* @__PURE__ */ React__default.createElement(
138065
+ "div",
138066
+ {
138067
+ ref: sidebarRef,
138068
+ style: __spreadValues({
138069
+ width: isOpen ? 350 : 0,
138070
+ minWidth: isOpen ? 350 : 0,
138071
+ maxWidth: isOpen ? 350 : 0,
138072
+ paddingLeft: 20,
138073
+ paddingRight: 20
138074
+ }, style2),
138075
+ className: "ove-sidebar-container",
138076
+ tabIndex: 0,
138077
+ onKeyDown: /* @__PURE__ */ __name((e) => {
138078
+ if (e.key === "Escape") {
138079
+ setProperties({ isOpen: false });
138080
+ }
138081
+ }, "onKeyDown")
138082
+ },
138083
+ /* @__PURE__ */ React__default.createElement(
138084
+ Button,
138085
+ {
138086
+ style: {
138087
+ position: "absolute",
138088
+ top: 5,
138089
+ right: 10,
138090
+ zIndex: 1,
138091
+ cursor: "pointer"
138092
+ },
138093
+ minimal: true,
138094
+ intent: "primary",
138095
+ "data-tip": "Hide Track Properties",
138096
+ icon: "cross",
138097
+ onClick: /* @__PURE__ */ __name(() => setProperties({ isOpen: false }), "onClick")
138098
+ }
138099
+ ),
138100
+ trackInner
138101
+ );
138102
+ }, "PropertySidePanel");
138103
+ function RowItem({ item, title, units }) {
138104
+ if (!item) return;
138105
+ const propertyClass = title.split(" ").join("-").toLowerCase();
138106
+ return /* @__PURE__ */ React__default.createElement("div", { className: `ve-flex-row property-${propertyClass}` }, /* @__PURE__ */ React__default.createElement("div", { className: "ve-column-left" }, title), /* @__PURE__ */ React__default.createElement("div", { className: "ve-column-right" }, item, " ", units != null ? units : ""));
138107
+ }
138108
+ __name(RowItem, "RowItem");
138109
+ function calculatePairwiseIdentity(seq1, seq2, excludeGaps = true) {
138110
+ if (seq1.length !== seq2.length) {
138111
+ throw new Error("Sequences must be aligned (same length)");
138112
+ }
138113
+ let identicalPositions = 0;
138114
+ let validPositions = 0;
138115
+ for (let i = 0; i < seq1.length; i++) {
138116
+ const aa1 = seq1[i].toUpperCase();
138117
+ const aa2 = seq2[i].toUpperCase();
138118
+ if (excludeGaps && aa1 === "-" && aa2 === "-") {
138119
+ continue;
138120
+ }
138121
+ validPositions++;
138122
+ if (aa1 === aa2) {
138123
+ identicalPositions++;
138124
+ }
138125
+ }
138126
+ return { validPositions, identicalPositions };
138127
+ }
138128
+ __name(calculatePairwiseIdentity, "calculatePairwiseIdentity");
138129
+ function calculateIdentityMatrix(alignedSequences) {
138130
+ const n2 = Object.keys(alignedSequences).length;
138131
+ const identityMatrix = Array(n2).fill(n2).map(() => Array(n2).fill(0));
138132
+ const sequenceNames = Object.keys(alignedSequences);
138133
+ const _identicalPositions = [];
138134
+ for (let i = 0; i < n2; i++) {
138135
+ for (let j2 = i; j2 < n2; j2++) {
138136
+ if (i === j2) {
138137
+ identityMatrix[i][j2] = 100;
138138
+ } else {
138139
+ const seq1 = alignedSequences[sequenceNames[i]];
138140
+ const seq2 = alignedSequences[sequenceNames[j2]];
138141
+ const { validPositions, identicalPositions } = calculatePairwiseIdentity(seq1, seq2, true);
138142
+ const identityPercentage = validPositions > 0 ? identicalPositions / validPositions * 100 : 0;
138143
+ _identicalPositions.push({
138144
+ identicalPositions,
138145
+ seqs: [sequenceNames[i], sequenceNames[j2]]
138146
+ });
138147
+ identityMatrix[i][j2] = identityPercentage;
138148
+ identityMatrix[j2][i] = identityPercentage;
138149
+ }
138150
+ }
138151
+ }
138152
+ return {
138153
+ matrix: identityMatrix,
138154
+ sequenceNames,
138155
+ identicalPositions: _identicalPositions
138156
+ };
138157
+ }
138158
+ __name(calculateIdentityMatrix, "calculateIdentityMatrix");
138159
+ function getPropertyAnalysis(alignedSequences) {
138160
+ const sequences = Object.values(alignedSequences).slice(1);
138161
+ function getResidueProperties(residue, map3) {
138162
+ return Object.keys(map3).filter((key) => map3[key].includes(residue));
138163
+ }
138164
+ __name(getResidueProperties, "getResidueProperties");
138165
+ function intersectHelper(arrays) {
138166
+ if (arrays.length === 0) return [];
138167
+ return arrays.reduce((a2, b3) => a2.filter((x) => b3.includes(x)));
138168
+ }
138169
+ __name(intersectHelper, "intersectHelper");
138170
+ const seqLength = sequences[0].length;
138171
+ return Array.from({ length: seqLength }, (_2, pos) => {
138172
+ const residues = sequences.map((seq) => seq[pos]).filter((r2) => r2 !== "-");
138173
+ const sizeProps = residues.map(
138174
+ (r2) => getResidueProperties(r2, residueSizeMap)
138175
+ );
138176
+ const polarityProps = residues.map(
138177
+ (r2) => getResidueProperties(r2, polarityMap)
138178
+ );
138179
+ const specificGroupProps = residues.map(
138180
+ (r2) => getResidueProperties(r2, specificGroupMap)
138181
+ );
138182
+ const shared = {
138183
+ size: intersectHelper(sizeProps),
138184
+ polarity: intersectHelper(polarityProps),
138185
+ specificGroup: intersectHelper(specificGroupProps)
138186
+ };
138187
+ const group = shared.specificGroup.length > 0 ? shared.specificGroup[0] : `${shared.size.length ? shared.size[0] : ""} ${shared.polarity.length ? shared.polarity[0] : ""}`;
138188
+ function mostFrequent(arr) {
138189
+ const freq = {};
138190
+ arr.forEach((val2) => {
138191
+ if (val2 !== "none") freq[val2] = (freq[val2] || 0) + 1;
138192
+ });
138193
+ const max2 = Math.max(...Object.values(freq), 0);
138194
+ const mostFrequentProps = Object.entries(freq).filter(([, count2]) => count2 === max2).map(([prop]) => prop);
138195
+ return {
138196
+ props: mostFrequentProps,
138197
+ count: max2
138198
+ };
138199
+ }
138200
+ __name(mostFrequent, "mostFrequent");
138201
+ let mostFreqGroup;
138202
+ if (group.trim() === "") {
138203
+ const mostFreqResidueGroups = {
138204
+ size: mostFrequent(sizeProps.flat()),
138205
+ polarity: mostFrequent(polarityProps.flat()),
138206
+ specificGroup: mostFrequent(specificGroupProps.flat())
138207
+ };
138208
+ const sortedGroups = Object.entries(mostFreqResidueGroups).sort(
138209
+ (a2, b3) => b3[1].count - a2[1].count
138210
+ );
138211
+ const topCount = sortedGroups[0][1].count;
138212
+ const topOrTiedGroups = sortedGroups.filter(
138213
+ ([, val2]) => val2.count === topCount
138214
+ );
138215
+ const specificGroupEntry = topOrTiedGroups.find(
138216
+ ([key]) => key === "specificGroup"
138217
+ );
138218
+ if (specificGroupEntry) {
138219
+ mostFreqGroup = specificGroupEntry[1].props.join(" ");
138220
+ } else {
138221
+ const allProps = [
138222
+ ...new Set(topOrTiedGroups.flatMap(([, val2]) => val2.props))
138223
+ ];
138224
+ mostFreqGroup = allProps.join(" ");
138225
+ }
138226
+ }
138227
+ const aaGroup = group.trim() || mostFreqGroup.trim();
138228
+ return {
138229
+ position: pos,
138230
+ residues,
138231
+ group: aaGroup,
138232
+ color: combineGroupColors(aaGroup.split(" "))
138233
+ };
138234
+ });
138235
+ }
138236
+ __name(getPropertyAnalysis, "getPropertyAnalysis");
138237
+ function getIdentityAndFrequencies(alignedSequences) {
138238
+ const sequences = Object.values(alignedSequences).slice(1);
138239
+ const alignmentLength = sequences[0].length;
138240
+ let totalScore = 0;
138241
+ let totalPositions = 0;
138242
+ const identityPercentages = [];
138243
+ for (let pos = 0; pos < alignmentLength; pos++) {
138244
+ const column = sequences.map((seq) => seq[pos]);
138245
+ const nonGapResidues = column;
138246
+ const propertyCounts = {};
138247
+ if (nonGapResidues.length === 0) identityPercentages.push(0);
138248
+ if (nonGapResidues.length < 2) continue;
138249
+ let totalProperties = 0;
138250
+ const residueCounts = {};
138251
+ nonGapResidues.forEach((aa) => {
138252
+ residueCounts[aa] = (residueCounts[aa] || 0) + 1;
138253
+ const props = residuePropertyMap[aa] || [];
138254
+ props.forEach((prop) => {
138255
+ propertyCounts[prop] = (propertyCounts[prop] || 0) + 1;
138256
+ });
138257
+ totalProperties++;
138258
+ });
138259
+ const propertyPercentages = {};
138260
+ Object.entries(propertyCounts).forEach(([prop, count2]) => {
138261
+ propertyPercentages[prop] = count2 / totalProperties * 100;
138262
+ });
138263
+ const maxCount = Math.max(...Object.values(residueCounts));
138264
+ const positionScore = maxCount / nonGapResidues.length;
138265
+ identityPercentages.push(maxCount / nonGapResidues.length * 100);
138266
+ totalScore += positionScore;
138267
+ totalPositions++;
138268
+ }
138269
+ const overallIdentity = totalPositions > 0 ? totalScore / totalPositions * 100 : 0;
138270
+ return {
138271
+ overallIdentity,
138272
+ frequencies: identityPercentages
138273
+ };
138274
+ }
138275
+ __name(getIdentityAndFrequencies, "getIdentityAndFrequencies");
138276
+ function getLabileSites(alignedSequences, threshold = 0.5) {
138277
+ const sequences = Object.values(alignedSequences);
138278
+ const alignmentLength = sequences[0].length;
138279
+ const labileSites = [];
138280
+ const conservationScores = [];
138281
+ for (let pos = 0; pos < alignmentLength; pos++) {
138282
+ const column = sequences.map((seq) => seq[pos]);
138283
+ const nonGapResidues = column.filter((aa) => aa !== "-");
138284
+ if (nonGapResidues.length < 2) {
138285
+ conservationScores.push(null);
138286
+ continue;
138287
+ }
138288
+ const counts = {};
138289
+ nonGapResidues.forEach((aa) => {
138290
+ counts[aa] = (counts[aa] || 0) + 1;
138291
+ });
138292
+ const maxCount = Math.max(...Object.values(counts));
138293
+ const conservationScore = maxCount / nonGapResidues.length;
138294
+ conservationScores.push(conservationScore);
138295
+ if (conservationScore <= threshold) {
138296
+ labileSites.push({
138297
+ position: pos + 1,
138298
+ // 1-based indexing
138299
+ conservationScore,
138300
+ residueVariation: Object.keys(counts),
138301
+ frequencies: counts
138302
+ });
138303
+ }
138304
+ }
138305
+ return {
138306
+ sites: labileSites,
138307
+ conservationScores,
138308
+ totalLabileSites: labileSites.length,
138309
+ percentageLabile: labileSites.length / alignmentLength * 100
138310
+ };
138311
+ }
138312
+ __name(getLabileSites, "getLabileSites");
138313
+ const getAlignedAminoAcidSequenceProps = /* @__PURE__ */ __name((tracks) => {
138314
+ let sequences = {};
138315
+ tracks.forEach((at) => {
138316
+ sequences = __spreadProps(__spreadValues({}, sequences), {
138317
+ [at.alignmentData.name]: at.alignmentData.sequence
138318
+ });
138319
+ });
138320
+ const identity4 = calculateIdentityMatrix(sequences);
138321
+ const { overallIdentity, frequencies } = getIdentityAndFrequencies(sequences);
138322
+ const labileSites = getLabileSites(sequences, 0.5);
138323
+ const propertyAnalysis = getPropertyAnalysis(sequences);
138324
+ return __spreadProps(__spreadValues({}, identity4), {
138325
+ overallIdentity,
138326
+ frequencies,
138327
+ labileSites,
138328
+ propertyAnalysis
138329
+ });
138330
+ }, "getAlignedAminoAcidSequenceProps");
138331
+ const residueSizeMap = {
138332
+ tiny: ["A", "C", "G", "S"],
138333
+ small: ["A", "C", "D", "G", "N", "P", "S", "T", "V"],
138334
+ large: ["E", "F", "H", "I", "K", "L", "M", "Q", "R", "W", "Y"]
138335
+ };
138336
+ const polarityMap = {
138337
+ hydrophobic: ["A", "C", "F", "I", "L", "M", "V", "W", "Y", "H", "K", "R"],
138338
+ polar: ["D", "E", "H", "K", "N", "Q", "R", "S", "T", "Y"],
138339
+ charged: ["D", "E", "H", "K", "R"]
138340
+ };
138341
+ const specificGroupMap = {
138342
+ aliphatic: ["I", "L", "V"],
138343
+ aromatic: ["F", "W", "Y", "H"],
138344
+ positive: ["H", "K", "R"],
138345
+ negative: ["D", "E"],
138346
+ amidic: ["N", "Q"],
138347
+ "sulphur-containing": ["C", "M"],
138348
+ hydroxylic: ["S", "T"]
138349
+ };
138350
+ const residuePropertyMap = {
138351
+ A: ["Small", "Tiny", "Hydrophobic"],
138352
+ C: ["Small", "Tiny", "Hydrophobic", "Sulphur-Containing"],
138353
+ D: ["Small", "Polar", "Charged", "Negative"],
138354
+ E: ["Large", "Polar", "Charged", "Negative"],
138355
+ F: ["Hydrophobic", "Aromatic"],
138356
+ G: ["Small", "Tiny"],
138357
+ H: ["Hydrophobic", "Polar", "Charged", "Aromatic", "Positive"],
138358
+ I: ["Hydrophobic", "Aliphatic"],
138359
+ K: ["Hydrophobic", "Polar", "Charged", "Positive"],
138360
+ L: ["Hydrophobic", "Aliphatic"],
138361
+ M: ["Hydrophobic", "Sulphur-Containing"],
138362
+ N: ["Polar", "Small", "Amidic"],
138363
+ P: ["Small"],
138364
+ Q: ["Polar", "Amidic"],
138365
+ R: ["Polar", "Charged", "Positive"],
138366
+ S: ["Polar", "Small", "Tiny", "Hydroxylic"],
138367
+ T: ["Polar", "Small", "Hydroxylic"],
138368
+ V: ["Hydrophobic", "Small", "Aliphatic"],
138369
+ W: ["Hydrophobic", "Polar", "Aromatic"],
138370
+ Y: ["Hydrophobic", "Polar", "Aromatic"]
138371
+ };
138372
+ const propertiesColorMap = {
138373
+ aliphatic: "#AE83A3",
138374
+ aromatic: "#EC8BA0",
138375
+ amidic: "#83C6C2",
138376
+ hydroxylic: "#65A3AC",
138377
+ "sulphur-containing": "#F8CD7F",
138378
+ positive: "#A1838F",
138379
+ negative: "#DC855C",
138380
+ large: "#C1B87E",
138381
+ small: "#B1DEF0",
138382
+ tiny: "#74BDA8",
138383
+ hydrophobic: "#F4B3A2",
138384
+ polar: "#C1DCAE",
138385
+ charged: "#D7AD7A",
138386
+ none: "#888"
138387
+ };
138388
+ function combineGroupColors(colorKeys, colorMap = propertiesColorMap) {
138389
+ if (!colorKeys.length || colorKeys[0] === "none") return "#000";
138390
+ const toRGB = /* @__PURE__ */ __name((hex) => {
138391
+ if (!hex) return [0, 0, 0];
138392
+ const h2 = hex.replace("#", "");
138393
+ return [
138394
+ parseInt(h2.substring(0, 2), 16),
138395
+ parseInt(h2.substring(2, 4), 16),
138396
+ parseInt(h2.substring(4, 6), 16)
138397
+ ];
138398
+ }, "toRGB");
138399
+ const rgbs = colorKeys.map((key) => toRGB(colorMap[key])).filter((rgb) => rgb.every(Number.isFinite));
138400
+ if (rgbs.length === 0) return "#888";
138401
+ const avg = [0, 1, 2].map(
138402
+ (i) => Math.round(rgbs.reduce((sum2, rgb) => sum2 + rgb[i], 0) / rgbs.length)
138403
+ );
138404
+ return "#" + avg.map((val2) => val2.toString(16).padStart(2, "0")).join("").toUpperCase();
138405
+ }
138406
+ __name(combineGroupColors, "combineGroupColors");
137224
138407
  let charWidthInLinearViewDefault = 12;
137225
138408
  try {
137226
138409
  const newVal2 = JSON.parse(
@@ -137332,6 +138515,12 @@ const AlignmentView = /* @__PURE__ */ __name((props) => {
137332
138515
  verticalVisibleRange: { start: 0, end: 0 }
137333
138516
  })
137334
138517
  );
138518
+ const [propertySidePanel, setPropertySidePanel] = useState({
138519
+ isOpen: false,
138520
+ selection: null,
138521
+ track: null,
138522
+ isPairwise: false
138523
+ });
137335
138524
  const getAllAlignmentsFastaText = useCallback$1(() => {
137336
138525
  const selectionLayer22 = store2.getState().VectorEditor.__allEditorsOptions.alignments[id2].selectionLayer || {};
137337
138526
  const seqDataOfAllTracksToCopy = [];
@@ -137388,6 +138577,59 @@ ${seqDataToCopy}\r
137388
138577
  if (window.Cypress) delete window.Cypress.scrollAlignmentToPercent;
137389
138578
  };
137390
138579
  }, []);
138580
+ const {
138581
+ alignmentAnnotationVisibility,
138582
+ togglableAlignmentAnnotationSettings
138583
+ } = alignmentVisibilityToolOptions;
138584
+ useEffect(() => {
138585
+ const dnaAnnotations = [
138586
+ "chromatogram",
138587
+ "reverseSequence",
138588
+ "cdsFeatureTranslations",
138589
+ "dnaColors",
138590
+ "translations",
138591
+ "compactNames"
138592
+ ];
138593
+ const aminoAcidAnnotations = [
138594
+ "physicalProperties",
138595
+ "serineThreonine",
138596
+ "labileSites",
138597
+ "colorScheme",
138598
+ "plot",
138599
+ "conservation",
138600
+ "properties",
138601
+ "hydrophobicity",
138602
+ "polar",
138603
+ "negative",
138604
+ "positive",
138605
+ "charged",
138606
+ "aliphatic",
138607
+ "aromatic",
138608
+ "compactNames"
138609
+ ];
138610
+ const noNeededAnnotationsForPairwise = ["plot", "labileSites"];
138611
+ if (alignmentTracks[0].sequenceData.isProtein) {
138612
+ dnaAnnotations.forEach((key) => {
138613
+ delete alignmentAnnotationVisibility[key];
138614
+ delete togglableAlignmentAnnotationSettings[key];
138615
+ });
138616
+ aminoAcidAnnotations.forEach((key) => {
138617
+ alignmentAnnotationVisibility[key] = false;
138618
+ togglableAlignmentAnnotationSettings[key] = false;
138619
+ });
138620
+ if (isPairwise) {
138621
+ noNeededAnnotationsForPairwise.forEach((key) => {
138622
+ delete alignmentAnnotationVisibility[key];
138623
+ delete togglableAlignmentAnnotationSettings[key];
138624
+ });
138625
+ }
138626
+ } else {
138627
+ aminoAcidAnnotations.forEach((key) => {
138628
+ delete alignmentAnnotationVisibility[key];
138629
+ delete togglableAlignmentAnnotationSettings[key];
138630
+ });
138631
+ }
138632
+ }, [alignmentTracks, isPairwise]);
137391
138633
  const maxLength = useMemo$1(() => {
137392
138634
  const { sequenceData: sequenceData22 = { sequence: "" }, alignmentData } = alignmentTracks[0];
137393
138635
  const data = alignmentData || sequenceData22;
@@ -137516,6 +138758,11 @@ ${seqDataToCopy}\r
137516
138758
  )
137517
138759
  };
137518
138760
  callback2(callbackVals);
138761
+ setPropertySidePanel((prev) => {
138762
+ return __spreadProps(__spreadValues({}, prev), {
138763
+ selection: easyStore2.current.selectionLayer
138764
+ });
138765
+ });
137519
138766
  },
137520
138767
  [
137521
138768
  caretPositionUpdate2,
@@ -137687,7 +138934,12 @@ ${seqDataToCopy}\r
137687
138934
  annotationLabelVisibility: alignmentVisibilityToolOptions.alignmentAnnotationLabelVisibility
137688
138935
  });
137689
138936
  }, "estimateRowHeight");
137690
- const renderItem = /* @__PURE__ */ __name((_i, key, isTemplate, cloneProps) => {
138937
+ const aminoAcidAlignmentProperties = useMemo$1(() => {
138938
+ if (isPairwise || !alignmentTracks[0].sequenceData.isProtein) return;
138939
+ return getAlignedAminoAcidSequenceProps(alignmentTracks);
138940
+ }, [alignmentTracks, isPairwise]);
138941
+ const renderItem = /* @__PURE__ */ __name((_i, _key, isTemplate, cloneProps) => {
138942
+ var _a3, _b2, _c, _d, _e;
137691
138943
  const isDragDisabled = !allowTrackRearrange || isPairwise;
137692
138944
  let i;
137693
138945
  if (isTemplate) {
@@ -137726,22 +138978,44 @@ ${seqDataToCopy}\r
137726
138978
  className: "tg-trimmed-region",
137727
138979
  color: "gray"
137728
138980
  }));
138981
+ const trackIdentifier = (track == null ? void 0 : track.sequenceData.id) ? "id" : "hash";
138982
+ const selectedTrack = propertySidePanel == null ? void 0 : propertySidePanel.track;
138983
+ const isTrackSelected = (selectedTrack == null ? void 0 : selectedTrack.sequenceData[trackIdentifier]) === (track == null ? void 0 : track.sequenceData[trackIdentifier]);
138984
+ let aaIdentity;
138985
+ let aaIdenticalPosition;
138986
+ if (sequenceData22.isProtein && !isPairwise) {
138987
+ aaIdentity = (_c = (_b2 = (_a3 = aminoAcidAlignmentProperties == null ? void 0 : aminoAcidAlignmentProperties.matrix) == null ? void 0 : _a3[0]) == null ? void 0 : _b2[i]) == null ? void 0 : _c.toFixed(1);
138988
+ aaIdenticalPosition = (_e = (_d = aminoAcidAlignmentProperties == null ? void 0 : aminoAcidAlignmentProperties.identicalPositions) == null ? void 0 : _d[i - 1]) == null ? void 0 : _e.identicalPositions;
138989
+ if (sequenceData22.name === "Consensus") {
138990
+ sequenceData22.aminoAcidProperties = isPairwise || !sequenceData22.isProtein ? null : aminoAcidAlignmentProperties;
138991
+ }
138992
+ }
137729
138993
  const innerRenderItem = /* @__PURE__ */ __name((provided = {}, snapshot) => {
137730
- var _a3;
138994
+ var _a4;
137731
138995
  return /* @__PURE__ */ React__default.createElement(
137732
138996
  "div",
137733
138997
  __spreadProps(__spreadValues({
137734
138998
  ref: provided == null ? void 0 : provided.innerRef
137735
138999
  }, provided == null ? void 0 : provided.draggableProps), {
137736
139000
  className: classNames("alignmentViewTrackContainer", {
137737
- isDragDisabled
139001
+ isDragDisabled,
139002
+ isTrackSelected
137738
139003
  }),
137739
139004
  "data-alignment-track-index": i,
137740
139005
  style: __spreadValues(__spreadValues({
137741
139006
  boxShadow: isTemplate ? "red 0px -1px 0px 0px inset, red 0px 1px 0px 0px inset" : "0px -1px 0px 0px inset",
137742
139007
  display: "flex"
137743
- }, (_a3 = provided == null ? void 0 : provided.draggableProps) == null ? void 0 : _a3.style), (snapshot == null ? void 0 : snapshot.isDragging) && { left: unset }),
137744
- key: i
139008
+ }, (_a4 = provided == null ? void 0 : provided.draggableProps) == null ? void 0 : _a4.style), (snapshot == null ? void 0 : snapshot.isDragging) && { left: unset }),
139009
+ key: i,
139010
+ onClick: /* @__PURE__ */ __name(() => {
139011
+ setPropertySidePanel((prev) => {
139012
+ return __spreadProps(__spreadValues({}, prev), {
139013
+ selection: easyStore2.current.selectionLayer,
139014
+ track,
139015
+ isPairwise
139016
+ });
139017
+ });
139018
+ }, "onClick")
137745
139019
  }),
137746
139020
  /* @__PURE__ */ React__default.createElement(
137747
139021
  "div",
@@ -137862,7 +139136,7 @@ ${seqDataToCopy}\r
137862
139136
  "data-tip": "This sequence was trimmed and resubmitted for alignment"
137863
139137
  },
137864
139138
  "TRIMMED"
137865
- ), sequenceData22.sequence.length, " bps")
139139
+ ), sequenceData22.isProtein ? /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("span", null, sequenceData22.proteinSequence.length, " AAs"), !compactNames && i > 0 && !isPairwise && /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("br", null), /* @__PURE__ */ React__default.createElement("span", null, "Identical Positions: ", aaIdenticalPosition), /* @__PURE__ */ React__default.createElement("br", null), /* @__PURE__ */ React__default.createElement("span", null, "Identity: ", aaIdentity, "%"))) : /* @__PURE__ */ React__default.createElement("span", null, sequenceData22.sequence.length, " bps"))
137866
139140
  ),
137867
139141
  /* @__PURE__ */ React__default.createElement(
137868
139142
  HorizontalPanelDragHandle,
@@ -138147,7 +139421,8 @@ ${seqDataToCopy}\r
138147
139421
  console.error("corrupted data!", props);
138148
139422
  return "corrupted data!";
138149
139423
  }
138150
- const getTrackVis = /* @__PURE__ */ __name((alignmentTracks2, isTemplate, allTracks) => {
139424
+ const getTrackVis = /* @__PURE__ */ __name((alignmentTracks2, isTemplate, allTracks, aminoAcidAlignmentProperties2, labileSites2) => {
139425
+ const labilePositions = (aminoAcidAlignmentProperties2 == null ? void 0 : aminoAcidAlignmentProperties2.labileSites.sites.map((ls) => ls.position)) || [];
138151
139426
  const rowData2 = {};
138152
139427
  const innerTrackVis = /* @__PURE__ */ __name((drop_provided, drop_snapshot) => {
138153
139428
  return /* @__PURE__ */ React__default.createElement(
@@ -138335,6 +139610,14 @@ ${seqDataToCopy}\r
138335
139610
  easyStore: easyStore2.current
138336
139611
  }
138337
139612
  ),
139613
+ labileSites2 && labilePositions.length > 0 && /* @__PURE__ */ React__default.createElement(
139614
+ LabileSitesLayer,
139615
+ {
139616
+ leftMargin: nameDivWidth,
139617
+ charWidth: charWidth2,
139618
+ positionsToMark: labilePositions
139619
+ }
139620
+ ),
138338
139621
  isTemplate ? renderItem(0, 0, isTemplate) : /* @__PURE__ */ React__default.createElement(
138339
139622
  ReactList,
138340
139623
  {
@@ -138407,251 +139690,310 @@ ${seqDataToCopy}\r
138407
139690
  updateLabelsForInViewFeatures();
138408
139691
  }, "onPinch")
138409
139692
  };
138410
- return /* @__PURE__ */ React__default.createElement(PinchHelper, __spreadValues({}, pinchHandler), /* @__PURE__ */ React__default.createElement(ResizeSensor, { onResize: handleResize }, /* @__PURE__ */ React__default.createElement(
139693
+ const { labileSites } = alignmentVisibilityToolOptions.alignmentAnnotationVisibility;
139694
+ return /* @__PURE__ */ React__default.createElement(PinchHelper, __spreadValues({}, pinchHandler), /* @__PURE__ */ React__default.createElement(
138411
139695
  "div",
138412
139696
  {
138413
- style: __spreadValues({
138414
- height: height || (isPairwise ? "auto" : viewportHeight * 0.88),
139697
+ style: {
138415
139698
  display: "flex",
138416
- flexDirection: "column",
138417
- justifyContent: "space-between",
138418
- position: "relative",
138419
- overflowY: "auto"
138420
- }, style2),
138421
- className: "alignmentView"
139699
+ flexDirection: "row"
139700
+ }
138422
139701
  },
138423
- /* @__PURE__ */ React__default.createElement(
138424
- DragDropContext,
139702
+ /* @__PURE__ */ React__default.createElement(ResizeSensor, { onResize: handleResize }, /* @__PURE__ */ React__default.createElement(
139703
+ "div",
138425
139704
  {
138426
- onDragStart: onTrackDragStart,
138427
- onDragEnd: onTrackDragEnd
139705
+ style: __spreadValues({
139706
+ height: height || (isPairwise ? "auto" : viewportHeight * 0.88),
139707
+ width: "100%",
139708
+ display: "flex",
139709
+ flexDirection: "column",
139710
+ justifyContent: "space-between",
139711
+ position: "relative",
139712
+ overflowY: "auto"
139713
+ }, style2),
139714
+ className: "alignmentView"
138428
139715
  },
138429
139716
  /* @__PURE__ */ React__default.createElement(
138430
- "div",
139717
+ DragDropContext,
138431
139718
  {
138432
- style: {
138433
- display: "flex",
138434
- flexDirection: "column",
138435
- position: "relative",
138436
- overflowY: "auto"
138437
- },
138438
- className: "alignmentView-top-container"
139719
+ onDragStart: onTrackDragStart,
139720
+ onDragEnd: onTrackDragEnd
138439
139721
  },
138440
139722
  /* @__PURE__ */ React__default.createElement(
138441
139723
  "div",
138442
139724
  {
138443
139725
  style: {
138444
- paddingTop: "3px",
138445
- paddingBottom: "5px",
138446
- borderBottom: "1px solid",
138447
139726
  display: "flex",
138448
- minHeight: "32px",
139727
+ flexDirection: "column",
139728
+ position: "relative",
138449
139729
  width: "100%",
138450
- flexWrap: "nowrap",
138451
- flexDirection: "row",
138452
- flex: "0 0 auto"
139730
+ overflowY: "auto"
138453
139731
  },
138454
- className: "ve-alignment-top-bar"
139732
+ className: "alignmentView-top-container"
138455
139733
  },
138456
- additionalTopLeftEl,
138457
- handleBackButtonClicked && /* @__PURE__ */ React__default.createElement(Tooltip, { content: "Back to Pairwise Alignment Overview" }, /* @__PURE__ */ React__default.createElement(
138458
- Button,
138459
- {
138460
- icon: "arrow-left",
138461
- onClick: /* @__PURE__ */ __name(() => {
138462
- handleBackButtonClicked();
138463
- caretPositionUpdate2(-1);
138464
- }, "onClick"),
138465
- small: true,
138466
- intent: Intent.PRIMARY,
138467
- minimal: true,
138468
- style: { marginRight: 10 },
138469
- className: "alignmentViewBackButton"
138470
- }
138471
- )),
138472
- /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex" } }, /* @__PURE__ */ React__default.createElement(
138473
- EditableText,
138474
- {
138475
- disabled: !handleAlignmentRename,
138476
- onChange: /* @__PURE__ */ __name((v2) => {
138477
- setAlignmentName(v2);
138478
- }, "onChange"),
138479
- maxLength: 399,
138480
- value: alignmentName,
138481
- onConfirm: /* @__PURE__ */ __name((v2) => __async(void 0, null, function* () {
138482
- if (!v2) {
138483
- setAlignmentName(_alignmentName);
138484
- return;
138485
- }
138486
- if (v2 === _alignmentName) {
138487
- return;
138488
- }
138489
- setSaveMessage("Alignment Renaming..");
138490
- setSaveMessageLoading(true);
138491
- yield handleAlignmentRename(v2, props);
138492
- setSaveMessage("Rename Successful");
138493
- setSaveMessageLoading(false);
138494
- setTimeout(() => {
138495
- setSaveMessage(void 0);
138496
- setSaveMessageLoading(false);
138497
- }, 5e3);
138498
- }), "onConfirm"),
138499
- selectAllOnFocus: true,
138500
- className: "veAlignmentName"
138501
- }
138502
- ), "   ", /* @__PURE__ */ React__default.createElement(
139734
+ /* @__PURE__ */ React__default.createElement(
138503
139735
  "div",
138504
139736
  {
138505
- className: "veAlignmentType",
138506
139737
  style: {
138507
139738
  paddingTop: "3px",
138508
- fontSize: "14px",
138509
- color: "grey",
138510
- maxWidth: "300px",
138511
- overflow: "hidden",
138512
- textOverflow: "ellipsis",
138513
- whiteSpace: "nowrap"
139739
+ paddingBottom: "5px",
139740
+ borderBottom: "1px solid",
139741
+ display: "flex",
139742
+ minHeight: "32px",
139743
+ width: "100%",
139744
+ flexWrap: "nowrap",
139745
+ flexDirection: "row",
139746
+ flex: "0 0 auto"
138514
139747
  },
138515
- "data-title": alignmentType || "Unknown Alignment Type"
139748
+ className: "ve-alignment-top-bar"
138516
139749
  },
138517
- alignmentType || "Unknown Alignment Type"
138518
- )),
138519
- unmappedSeqs && /* @__PURE__ */ React__default.createElement(
138520
- InfoHelper,
138521
- {
138522
- size: 20,
138523
- content: /* @__PURE__ */ React__default.createElement("div", null, "This alignment had sequences that did not map to the template sequence:", unmappedSeqs.map(({ sequenceData: sequenceData22 }, i) => /* @__PURE__ */ React__default.createElement("div", { key: i }, sequenceData22.name))),
138524
- intent: "warning",
138525
- icon: "warning-sign"
138526
- }
138527
- ),
138528
- !isInPairwiseOverviewView && /* @__PURE__ */ React__default.createElement(
138529
- UncontrolledSliderWithPlusMinusBtns,
138530
- {
138531
- noWraparound: true,
138532
- bindOutsideChangeHelper: bindOutsideChangeHelper.current,
138533
- onClick: /* @__PURE__ */ __name(() => {
138534
- setTimeout(scrollToCaret2, 0);
138535
- }, "onClick"),
138536
- minCharWidth: getMinCharWidth(),
138537
- onChange: /* @__PURE__ */ __name((zoomLvl) => __async(void 0, null, function* () {
138538
- isZooming.current = true;
138539
- setTimeout(() => {
138540
- isZooming.current = false;
138541
- }, 10);
138542
- const minCharWidth = getMinCharWidth();
138543
- const scaleFactor = Math.pow(12 / minCharWidth, 1 / 10);
138544
- const newCharWidth = minCharWidth * Math.pow(scaleFactor, zoomLvl);
138545
- yield setCharWidthInLinearView({
138546
- charWidthInLinearView: newCharWidth
138547
- });
138548
- yield scrollToCaret2();
138549
- yield updateLabelsForInViewFeatures({
138550
- rectElement: ".alignmentHolder"
138551
- });
138552
- }), "onChange"),
138553
- coerceInitialValue,
138554
- title: "Adjust Zoom Level",
138555
- style: { paddingTop: "4px", width: 100 },
138556
- className: "veZoomAlignmentSlider ove-slider",
138557
- labelRenderer: false,
138558
- initialValue: charWidth2,
138559
- stepSize: 0.05,
138560
- max: 10,
138561
- min: 0,
138562
- clickStepSize: 0.5
138563
- }
138564
- ),
138565
- !noVisibilityOptions && !isInPairwiseOverviewView && /* @__PURE__ */ React__default.createElement(
138566
- AlignmentVisibilityTool,
138567
- __spreadValues({
138568
- currentPairwiseAlignmentIndex
138569
- }, alignmentVisibilityToolOptions)
139750
+ additionalTopLeftEl,
139751
+ handleBackButtonClicked && /* @__PURE__ */ React__default.createElement(Tooltip, { content: "Back to Pairwise Alignment Overview" }, /* @__PURE__ */ React__default.createElement(
139752
+ Button,
139753
+ {
139754
+ icon: "arrow-left",
139755
+ onClick: /* @__PURE__ */ __name(() => {
139756
+ handleBackButtonClicked();
139757
+ caretPositionUpdate2(-1);
139758
+ }, "onClick"),
139759
+ small: true,
139760
+ intent: Intent.PRIMARY,
139761
+ minimal: true,
139762
+ style: { marginRight: 10 },
139763
+ className: "alignmentViewBackButton"
139764
+ }
139765
+ )),
139766
+ /* @__PURE__ */ React__default.createElement("div", { style: { display: "flex" } }, /* @__PURE__ */ React__default.createElement(
139767
+ EditableText,
139768
+ {
139769
+ disabled: !handleAlignmentRename,
139770
+ onChange: /* @__PURE__ */ __name((v2) => {
139771
+ setAlignmentName(v2);
139772
+ }, "onChange"),
139773
+ maxLength: 399,
139774
+ value: alignmentName,
139775
+ onConfirm: /* @__PURE__ */ __name((v2) => __async(void 0, null, function* () {
139776
+ if (!v2) {
139777
+ setAlignmentName(_alignmentName);
139778
+ return;
139779
+ }
139780
+ if (v2 === _alignmentName) {
139781
+ return;
139782
+ }
139783
+ setSaveMessage("Alignment Renaming..");
139784
+ setSaveMessageLoading(true);
139785
+ yield handleAlignmentRename(v2, props);
139786
+ setSaveMessage("Rename Successful");
139787
+ setSaveMessageLoading(false);
139788
+ setTimeout(() => {
139789
+ setSaveMessage(void 0);
139790
+ setSaveMessageLoading(false);
139791
+ }, 5e3);
139792
+ }), "onConfirm"),
139793
+ selectAllOnFocus: true,
139794
+ className: "veAlignmentName"
139795
+ }
139796
+ ), "   ", /* @__PURE__ */ React__default.createElement(
139797
+ "div",
139798
+ {
139799
+ className: "veAlignmentType",
139800
+ style: {
139801
+ paddingTop: "3px",
139802
+ fontSize: "14px",
139803
+ color: "grey",
139804
+ maxWidth: "300px",
139805
+ overflow: "hidden",
139806
+ textOverflow: "ellipsis",
139807
+ whiteSpace: "nowrap"
139808
+ },
139809
+ "data-title": alignmentType || "Unknown Alignment Type"
139810
+ },
139811
+ alignmentType || "Unknown Alignment Type"
139812
+ )),
139813
+ unmappedSeqs && /* @__PURE__ */ React__default.createElement(
139814
+ InfoHelper,
139815
+ {
139816
+ size: 20,
139817
+ content: /* @__PURE__ */ React__default.createElement("div", null, "This alignment had sequences that did not map to the template sequence:", unmappedSeqs.map(({ sequenceData: sequenceData22 }, i) => /* @__PURE__ */ React__default.createElement("div", { key: i }, sequenceData22.name))),
139818
+ intent: "warning",
139819
+ icon: "warning-sign"
139820
+ }
139821
+ ),
139822
+ !isInPairwiseOverviewView && /* @__PURE__ */ React__default.createElement(
139823
+ UncontrolledSliderWithPlusMinusBtns,
139824
+ {
139825
+ noWraparound: true,
139826
+ bindOutsideChangeHelper: bindOutsideChangeHelper.current,
139827
+ onClick: /* @__PURE__ */ __name(() => {
139828
+ setTimeout(scrollToCaret2, 0);
139829
+ }, "onClick"),
139830
+ minCharWidth: getMinCharWidth(),
139831
+ onChange: /* @__PURE__ */ __name((zoomLvl) => __async(void 0, null, function* () {
139832
+ isZooming.current = true;
139833
+ setTimeout(() => {
139834
+ isZooming.current = false;
139835
+ }, 10);
139836
+ const minCharWidth = getMinCharWidth();
139837
+ const scaleFactor = Math.pow(12 / minCharWidth, 1 / 10);
139838
+ const newCharWidth = minCharWidth * Math.pow(scaleFactor, zoomLvl);
139839
+ yield setCharWidthInLinearView({
139840
+ charWidthInLinearView: newCharWidth
139841
+ });
139842
+ yield scrollToCaret2();
139843
+ yield updateLabelsForInViewFeatures({
139844
+ rectElement: ".alignmentHolder"
139845
+ });
139846
+ }), "onChange"),
139847
+ coerceInitialValue,
139848
+ title: "Adjust Zoom Level",
139849
+ style: { paddingTop: "4px", width: 100 },
139850
+ className: "veZoomAlignmentSlider ove-slider",
139851
+ labelRenderer: false,
139852
+ initialValue: charWidth2,
139853
+ stepSize: 0.05,
139854
+ max: 10,
139855
+ min: 0,
139856
+ clickStepSize: 0.5
139857
+ }
139858
+ ),
139859
+ !noVisibilityOptions && !isInPairwiseOverviewView && /* @__PURE__ */ React__default.createElement(
139860
+ AlignmentVisibilityTool,
139861
+ __spreadValues({
139862
+ currentPairwiseAlignmentIndex
139863
+ }, alignmentVisibilityToolOptions)
139864
+ ),
139865
+ additionalTopEl,
139866
+ saveMessage && /* @__PURE__ */ React__default.createElement(
139867
+ "div",
139868
+ {
139869
+ className: "ove-menu-toast",
139870
+ style: {
139871
+ display: "flex",
139872
+ alignItems: "center",
139873
+ marginLeft: "auto",
139874
+ marginRight: 10
139875
+ }
139876
+ },
139877
+ saveMessageLoading ? /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement(Spinner, { size: 15 })) : /* @__PURE__ */ React__default.createElement(Icon, { icon: "tick-circle", intent: "success" }),
139878
+ " ",
139879
+ " ",
139880
+ saveMessage
139881
+ ),
139882
+ !propertySidePanel.isOpen && /* @__PURE__ */ React__default.createElement(
139883
+ Button,
139884
+ {
139885
+ small: true,
139886
+ minimal: true,
139887
+ className: "showTrackPropertiesBtn",
139888
+ icon: "menu-closed",
139889
+ intent: "primary",
139890
+ style: { marginLeft: "auto" },
139891
+ onClick: /* @__PURE__ */ __name(() => {
139892
+ setPropertySidePanel((prev) => {
139893
+ return __spreadProps(__spreadValues({}, prev), {
139894
+ isOpen: true
139895
+ });
139896
+ });
139897
+ }, "onClick"),
139898
+ "data-tip": "Show Track Properties"
139899
+ }
139900
+ )
138570
139901
  ),
138571
- additionalTopEl,
138572
- saveMessage && /* @__PURE__ */ React__default.createElement(
138573
- "div",
138574
- {
138575
- className: "ove-menu-toast",
138576
- style: {
138577
- display: "flex",
138578
- alignItems: "center",
138579
- marginLeft: "auto",
138580
- marginRight: 10
139902
+ hasTemplate ? /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("div", { className: "alignmentTrackFixedToTop" }, getTrackVis(
139903
+ [firstTrack],
139904
+ true,
139905
+ alignmentTracks,
139906
+ aminoAcidAlignmentProperties,
139907
+ labileSites
139908
+ )), getTrackVis(
139909
+ otherTracks,
139910
+ false,
139911
+ alignmentTracks,
139912
+ aminoAcidAlignmentProperties,
139913
+ labileSites
139914
+ )) : getTrackVis(
139915
+ alignmentTracks,
139916
+ false,
139917
+ alignmentTracks,
139918
+ aminoAcidAlignmentProperties,
139919
+ labileSites
139920
+ )
139921
+ )
139922
+ ),
139923
+ !isInPairwiseOverviewView && /* @__PURE__ */ React__default.createElement(
139924
+ "div",
139925
+ {
139926
+ className: "alignmentViewBottomBar",
139927
+ style: {
139928
+ // flexGrow: 1,
139929
+ // minHeight: "-webkit-min-content", //https://stackoverflow.com/questions/28029736/how-to-prevent-a-flex-item-from-shrinking-smaller-than-its-content
139930
+ maxHeight: 210,
139931
+ marginTop: 4,
139932
+ paddingTop: 4,
139933
+ borderTop: "1px solid lightgrey",
139934
+ display: "flex"
139935
+ }
139936
+ },
139937
+ /* @__PURE__ */ React__default.createElement(
139938
+ Minimap,
139939
+ {
139940
+ selectionLayerComp: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
139941
+ PerformantSelectionLayer,
139942
+ {
139943
+ is: true,
139944
+ hideCarets: true,
139945
+ className: "veAlignmentSelectionLayer veMinimapSelectionLayer",
139946
+ easyStore: easyStore2.current,
139947
+ sequenceLength: maxLength,
139948
+ charWidth: getMinCharWidth(true),
139949
+ row: { start: 0, end: maxLength - 1 }
139950
+ }
139951
+ ), /* @__PURE__ */ React__default.createElement(
139952
+ PerformantCaret,
139953
+ {
139954
+ style: {
139955
+ opacity: 0.2
139956
+ },
139957
+ className: "veAlignmentSelectionLayer veMinimapSelectionLayer",
139958
+ sequenceLength: maxLength,
139959
+ charWidth: getMinCharWidth(true),
139960
+ row: { start: 0, end: maxLength - 1 },
139961
+ easyStore: easyStore2.current
138581
139962
  }
139963
+ )),
139964
+ alignmentTracks,
139965
+ dimensions: {
139966
+ width: Math.max(width, 10) || 10
138582
139967
  },
138583
- saveMessageLoading ? /* @__PURE__ */ React__default.createElement("div", null, /* @__PURE__ */ React__default.createElement(Spinner, { size: 15 })) : /* @__PURE__ */ React__default.createElement(Icon, { icon: "tick-circle", intent: "success" }),
138584
- " ",
138585
- " ",
138586
- saveMessage
138587
- )
138588
- ),
138589
- hasTemplate ? /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement("div", { className: "alignmentTrackFixedToTop" }, getTrackVis([firstTrack], true, alignmentTracks)), getTrackVis(otherTracks, false, alignmentTracks)) : getTrackVis(alignmentTracks, false, alignmentTracks)
139968
+ nameDivOffsetPercent: 0,
139969
+ scrollYToTrack,
139970
+ onSizeAdjust: onMinimapSizeAdjust,
139971
+ minSliderSize,
139972
+ laneHeight: minimapLaneHeight || (alignmentTracks.length > 5 ? 10 : 17),
139973
+ laneSpacing: minimapLaneSpacing || (alignmentTracks.length > 5 ? 2 : 1),
139974
+ easyStore: easyStore2.current,
139975
+ numBpsShownInLinearView: getNumBpsShownInLinearView(),
139976
+ scrollAlignmentView: false,
139977
+ onMinimapScrollX: scrollAlignmentToPercent
139978
+ }
139979
+ )
139980
+ ),
139981
+ /* @__PURE__ */ React__default.createElement(
139982
+ GlobalDialog,
139983
+ null
138590
139984
  )
138591
- ),
138592
- !isInPairwiseOverviewView && /* @__PURE__ */ React__default.createElement(
138593
- "div",
139985
+ )),
139986
+ propertySidePanel.isOpen && /* @__PURE__ */ React__default.createElement(
139987
+ PropertySidePanel,
138594
139988
  {
138595
- className: "alignmentViewBottomBar",
139989
+ properties: propertySidePanel,
139990
+ setProperties: setPropertySidePanel,
138596
139991
  style: {
138597
- // flexGrow: 1,
138598
- // minHeight: "-webkit-min-content", //https://stackoverflow.com/questions/28029736/how-to-prevent-a-flex-item-from-shrinking-smaller-than-its-content
138599
- maxHeight: 210,
138600
- marginTop: 4,
138601
- paddingTop: 4,
138602
- borderTop: "1px solid lightgrey",
138603
- display: "flex"
139992
+ height: viewportHeight * 0.88
138604
139993
  }
138605
- },
138606
- /* @__PURE__ */ React__default.createElement(
138607
- Minimap,
138608
- {
138609
- selectionLayerComp: /* @__PURE__ */ React__default.createElement(React__default.Fragment, null, /* @__PURE__ */ React__default.createElement(
138610
- PerformantSelectionLayer,
138611
- {
138612
- is: true,
138613
- hideCarets: true,
138614
- className: "veAlignmentSelectionLayer veMinimapSelectionLayer",
138615
- easyStore: easyStore2.current,
138616
- sequenceLength: maxLength,
138617
- charWidth: getMinCharWidth(true),
138618
- row: { start: 0, end: maxLength - 1 }
138619
- }
138620
- ), /* @__PURE__ */ React__default.createElement(
138621
- PerformantCaret,
138622
- {
138623
- style: {
138624
- opacity: 0.2
138625
- },
138626
- className: "veAlignmentSelectionLayer veMinimapSelectionLayer",
138627
- sequenceLength: maxLength,
138628
- charWidth: getMinCharWidth(true),
138629
- row: { start: 0, end: maxLength - 1 },
138630
- easyStore: easyStore2.current
138631
- }
138632
- )),
138633
- alignmentTracks,
138634
- dimensions: {
138635
- width: Math.max(width, 10) || 10
138636
- },
138637
- nameDivOffsetPercent: 0,
138638
- scrollYToTrack,
138639
- onSizeAdjust: onMinimapSizeAdjust,
138640
- minSliderSize,
138641
- laneHeight: minimapLaneHeight || (alignmentTracks.length > 5 ? 10 : 17),
138642
- laneSpacing: minimapLaneSpacing || (alignmentTracks.length > 5 ? 2 : 1),
138643
- easyStore: easyStore2.current,
138644
- numBpsShownInLinearView: getNumBpsShownInLinearView(),
138645
- scrollAlignmentView: false,
138646
- onMinimapScrollX: scrollAlignmentToPercent
138647
- }
138648
- )
138649
- ),
138650
- /* @__PURE__ */ React__default.createElement(
138651
- GlobalDialog,
138652
- null
139994
+ }
138653
139995
  )
138654
- )));
139996
+ ));
138655
139997
  }, "AlignmentView");
138656
139998
  const AlignmentView$1 = compose(
138657
139999
  withStore,
@@ -138700,6 +140042,20 @@ const AlignmentView$1 = compose(
138700
140042
  "cdsFeatureTranslations",
138701
140043
  "chromatogram",
138702
140044
  "dnaColors",
140045
+ "physicalProperties",
140046
+ "serineThreonine",
140047
+ "labileSites",
140048
+ "colorScheme",
140049
+ "plot",
140050
+ "conservation",
140051
+ "properties",
140052
+ "hydrophobicity",
140053
+ "polar",
140054
+ "negative",
140055
+ "positive",
140056
+ "charged",
140057
+ "aliphatic",
140058
+ "aromatic",
138703
140059
  "compactNames"
138704
140060
  ];
138705
140061
  const togglableAlignmentAnnotationSettings = {};
@@ -141039,7 +142395,8 @@ const userDefinedHandlersAndOpts = [
141039
142395
  "onCreateNewFromSubsequence",
141040
142396
  "onPreviewModeFullscreenClose",
141041
142397
  "onPaste",
141042
- "menuFilter"
142398
+ "menuFilter",
142399
+ "showAminoAcidUnitAsCodon"
141043
142400
  ];
141044
142401
  const cutsiteTool = connectToEditor(
141045
142402
  ({ readOnly: readOnly2, annotationVisibility: annotationVisibility2 = {}, toolBar: toolBar2 = {} }) => {
@@ -141433,9 +142790,8 @@ const _FindBar = class _FindBar extends React__default.Component {
141433
142790
  display: "flex",
141434
142791
  minWidth: 300
141435
142792
  } : {
141436
- position: "fixed",
141437
- top: 120,
141438
- right: 25,
142793
+ position: "relative",
142794
+ top: 100,
141439
142795
  padding: 10,
141440
142796
  display: "flex",
141441
142797
  alignItems: "start",
@@ -141912,6 +143268,7 @@ const ShowSelectionItem = compose(
141912
143268
  caretPosition: caretPosition2 = -1,
141913
143269
  sequenceLength = 0,
141914
143270
  isProtein: isProtein2,
143271
+ showAminoAcidUnitAsCodon,
141915
143272
  sequenceData: sequenceData2 = { sequence: "" },
141916
143273
  showGCContent: showGCContent2,
141917
143274
  GCDecimalDigits,
@@ -141928,6 +143285,7 @@ const ShowSelectionItem = compose(
141928
143285
  sequenceLength,
141929
143286
  sequenceData: sequenceData2,
141930
143287
  showGCContent: showGCContent2,
143288
+ showAminoAcidUnitAsCodon,
141931
143289
  GCDecimalDigits,
141932
143290
  isProtein: isProtein2
141933
143291
  }), /* @__PURE__ */ React__default.createElement(
@@ -141952,10 +143310,10 @@ const ShowLengthItem = connectToEditor(
141952
143310
  ({ sequenceData: sequenceData2 = { sequence: "" } }) => ({
141953
143311
  sequenceLength: sequenceData2.sequence.length
141954
143312
  })
141955
- )(({ isProtein: isProtein2, sequenceLength = 0 }) => /* @__PURE__ */ React__default.createElement(StatusBarItem, { dataTest: "veStatusBar-length" }, `Length: ${divideBy3(
143313
+ )(({ isProtein: isProtein2, sequenceLength = 0, showAminoAcidUnitAsCodon }) => /* @__PURE__ */ React__default.createElement(StatusBarItem, { dataTest: "veStatusBar-length" }, `Length: ${divideBy3(
141956
143314
  sequenceLength,
141957
143315
  isProtein2
141958
- )} ${isProtein2 ? "AAs" : "bps"}`));
143316
+ )} ${isProtein2 ? `${showAminoAcidUnitAsCodon ? "codons" : "AAs"}` : "bps"}`));
141959
143317
  const ShowTypeItem = connectToEditor(({ sequenceData: sequenceData2 }) => ({
141960
143318
  isProtein: sequenceData2.isProtein,
141961
143319
  isOligo: sequenceData2.isOligo,
@@ -142035,6 +143393,7 @@ function StatusBar({
142035
143393
  onSelectionOrCaretChanged,
142036
143394
  GCDecimalDigits = 1,
142037
143395
  isProtein: isProtein2,
143396
+ showAminoAcidUnitAsCodon,
142038
143397
  beforeReadOnlyChange
142039
143398
  }) {
142040
143399
  return /* @__PURE__ */ React__default.createElement("div", { className: "veStatusBar" }, showMoleculeType && /* @__PURE__ */ React__default.createElement(ShowTypeItem, { editorName }), /* @__PURE__ */ React__default.createElement(
@@ -142062,13 +143421,21 @@ function StatusBar({
142062
143421
  ), /* @__PURE__ */ React__default.createElement(
142063
143422
  ShowSelectionItem,
142064
143423
  {
143424
+ showAminoAcidUnitAsCodon,
142065
143425
  editorName,
142066
143426
  isProtein: isProtein2,
142067
143427
  showGCContentByDefault,
142068
143428
  onSelectionOrCaretChanged,
142069
143429
  GCDecimalDigits
142070
143430
  }
142071
- ), /* @__PURE__ */ React__default.createElement(ShowLengthItem, { isProtein: isProtein2, editorName }));
143431
+ ), /* @__PURE__ */ React__default.createElement(
143432
+ ShowLengthItem,
143433
+ {
143434
+ isProtein: isProtein2,
143435
+ editorName,
143436
+ showAminoAcidUnitAsCodon
143437
+ }
143438
+ ));
142072
143439
  }
142073
143440
  __name(StatusBar, "StatusBar");
142074
143441
  function StatusBarItem({ children, dataTest }) {
@@ -144234,6 +145601,7 @@ const _Editor = class _Editor extends React__default.Component {
144234
145601
  hoveredId,
144235
145602
  isFullscreen,
144236
145603
  maxInsertSize,
145604
+ showAminoAcidUnitAsCodon,
144237
145605
  maxAnnotationsToDisplay,
144238
145606
  minHeight = 400,
144239
145607
  onlyShowLabelsThatDoNotFit = true,
@@ -144422,6 +145790,7 @@ const _Editor = class _Editor extends React__default.Component {
144422
145790
  }), panelPropsToSpread), {
144423
145791
  editorName,
144424
145792
  maxInsertSize,
145793
+ showAminoAcidUnitAsCodon,
144425
145794
  isProtein: sequenceData2.isProtein,
144426
145795
  onlyShowLabelsThatDoNotFit,
144427
145796
  tabHeight,
@@ -144775,7 +146144,8 @@ const _Editor = class _Editor extends React__default.Component {
144775
146144
  __spreadValues(__spreadProps(__spreadValues({}, pickedUserDefinedHandlersAndOpts), {
144776
146145
  isProtein: sequenceData2.isProtein,
144777
146146
  showCircularity: !!(showCircularity && !sequenceData2.isProtein && !sequenceData2.isOligo && !sequenceData2.isRna),
144778
- editorName
146147
+ editorName,
146148
+ showAminoAcidUnitAsCodon
144779
146149
  }), StatusBarProps)
144780
146150
  )
144781
146151
  ), /* @__PURE__ */ React__default.createElement(
@@ -146895,7 +148265,7 @@ export {
146895
148265
  LinearView$1 as LinearView,
146896
148266
  LinearView as LinearViewUnconnected,
146897
148267
  PositionAnnotationOnCircle,
146898
- RowItem,
148268
+ RowItem$1 as RowItem,
146899
148269
  RowView$1 as RowView,
146900
148270
  RowView as RowViewUnconnected,
146901
148271
  SimpleCircularOrLinearView,