@teselagen/ove 0.7.27 → 0.7.28

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 (304) hide show
  1. package/AASliver.js +187 -0
  2. package/AddLaddersDialog.js +82 -0
  3. package/AdditionalCutsiteInfoDialog.js +599 -0
  4. package/AlignmentView/Mismatches.d.ts +3 -3
  5. package/AlignmentVisibilityTool.js +105 -0
  6. package/AnnotationContainerHolder.js +20 -0
  7. package/AnnotationPositioner.js +27 -0
  8. package/AutoAnnotate.js +501 -0
  9. package/AutoAnnotateBpMatchingDialog.js +208 -0
  10. package/Axis.js +151 -0
  11. package/AxisNumbers.js +35 -0
  12. package/Browser.js +106 -0
  13. package/Caret.js +63 -0
  14. package/Chromatogram.js +293 -0
  15. package/CircularDnaSequence.js +73 -0
  16. package/CircularView/Labels/index.d.ts +1 -1
  17. package/CircularView/index.d.ts +0 -1
  18. package/CircularZoomMinimap.js +16 -0
  19. package/ColorPicker.js +30 -0
  20. package/CommandHotkeyHandler.js +44 -0
  21. package/CreateAnnotationsPage.d.ts +4 -4
  22. package/CreateAnnotationsPage.js +98 -0
  23. package/Cutsite.js +18 -0
  24. package/CutsiteProperties.js +176 -0
  25. package/CutsiteSelectionLayers.js +47 -0
  26. package/Cutsites.js +271 -0
  27. package/DeletionLayer.js +28 -0
  28. package/DigestTool/Ladder.d.ts +1 -1
  29. package/DropHandler.css +21 -0
  30. package/DropHandler.js +64 -0
  31. package/EditCaretPosition.js +234 -0
  32. package/EditTrackNameDialog.js +30 -0
  33. package/Feature.js +83 -0
  34. package/FeatureProperties.js +6 -0
  35. package/FillWindow.js +47 -0
  36. package/GenbankView.js +74 -0
  37. package/GeneralProperties.js +117 -0
  38. package/GenericAnnotationProperties.js +406 -0
  39. package/GlobalDialog.js +73 -0
  40. package/GlobalDialogUtils.js +110 -0
  41. package/GoToDialog.js +25 -0
  42. package/HorizontalPanelDragHandle.js +35 -0
  43. package/Keyboard.js +85 -0
  44. package/Labels.js +327 -0
  45. package/Ladder.css +20 -0
  46. package/Ladder.js +303 -0
  47. package/MeltingTemp.js +85 -0
  48. package/Menlo.ttf +0 -0
  49. package/Minimap.js +515 -0
  50. package/Mismatches.js +134 -0
  51. package/Monaco.ttf +0 -0
  52. package/MultipleSeqsDetectedOnImportDialog.js +74 -0
  53. package/Orf.js +109 -0
  54. package/OrfProperties.js +117 -0
  55. package/Orfs.js +35 -0
  56. package/PCRTool.js +179 -0
  57. package/PairwiseAlignmentView.js +68 -0
  58. package/Part.js +34 -0
  59. package/PartProperties.js +9 -0
  60. package/PassThrough.js +3 -0
  61. package/PerformantSelectionLayer.js +32 -0
  62. package/PinchHelper.js +24 -0
  63. package/PointedAnnotation.js +347 -0
  64. package/PositionAnnotationOnCircle.js +26 -0
  65. package/Primer.js +41 -0
  66. package/PrimerProperties.js +19 -0
  67. package/Reflex/index.d.ts +0 -1
  68. package/ReflexContainer.js +802 -0
  69. package/ReflexElement.js +160 -0
  70. package/ReflexEvents.js +77 -0
  71. package/ReflexSplitter.js +205 -0
  72. package/RenameSequenceDialog.js +7 -0
  73. package/RotateCircularViewSlider.js +93 -0
  74. package/RowView/index.d.ts +0 -1
  75. package/SelectDialog.js +150 -0
  76. package/SequenceName.js +15 -0
  77. package/SimpleCircularOrLinearView.js +381 -0
  78. package/SimpleOligoPreview.js +39 -0
  79. package/SingleEnzymeCutsiteInfo.js +139 -0
  80. package/ToolBar/ToolbarItem.d.ts +1 -3
  81. package/ToolbarItem.js +192 -0
  82. package/Translation.js +198 -0
  83. package/TranslationProperties.js +149 -0
  84. package/UncontrolledSliderWithPlusMinusBtns.css +5 -0
  85. package/UncontrolledSliderWithPlusMinusBtns.js +134 -0
  86. package/VeTopRightContainer.js +12 -0
  87. package/ZoomCircularViewSlider.js +62 -0
  88. package/ZoomLinearView.js +47 -0
  89. package/addAlignment.js +6 -0
  90. package/addMetaToActionCreators.js +12 -0
  91. package/addWrappedAddons.js +20 -0
  92. package/alignmentTool.js +503 -0
  93. package/alignments.js +379 -0
  94. package/annotationLabelVisibility.js +2 -0
  95. package/annotationSearchSelector.js +24 -0
  96. package/annotationTypes.js +35 -0
  97. package/annotationVisibility.js +196 -0
  98. package/annotationsToSupport.js +104 -0
  99. package/arrayToObjWithIds.js +17 -0
  100. package/arrayUtils.js +19 -0
  101. package/array_move.js +10 -0
  102. package/calculateTickMarkPositionsForGivenRange.js +47 -0
  103. package/caretPosition.js +27 -0
  104. package/cdsFeaturesSelector.js +9 -0
  105. package/charWidth.js +22 -0
  106. package/circular.js +19 -0
  107. package/circularSelector.js +4 -0
  108. package/clickAndDragUtils.js +576 -0
  109. package/coerceInitialValue.js +7 -0
  110. package/combineReducersDontIgnoreKeys.js +12 -0
  111. package/commandUtils.js +20 -0
  112. package/constants.js +2 -0
  113. package/copyOptions.js +34 -0
  114. package/createFragmentLines.js +120 -0
  115. package/createMergedDefaultStateReducer.js +30 -0
  116. package/createMetaAction.js +12 -0
  117. package/createSequenceInputPopup.js +290 -0
  118. package/createSequenceInputPopupStyle.css +87 -0
  119. package/createSimpleDialog.js +89 -0
  120. package/createYourOwnEnzyme.js +39 -0
  121. package/cutsiteLabelColorSelector.js +6 -0
  122. package/cutsiteTool.js +88 -0
  123. package/cutsitesByRangeSelector.js +5 -0
  124. package/cutsitesSelector.js +61 -0
  125. package/darkmode.css +98 -0
  126. package/defaultConfig.js +150 -0
  127. package/deletionLayers.js +36 -0
  128. package/description.js +21 -0
  129. package/digestTool.js +34 -0
  130. package/dnaToColor.js +17 -0
  131. package/downloadTool.js +39 -0
  132. package/draggableClassnames.js +5 -0
  133. package/drawAnnotations.js +440 -0
  134. package/drawDirectedPiePiece.js +142 -0
  135. package/editTool.js +49 -0
  136. package/editorSelector.js +2 -0
  137. package/editorUtils.js +205 -0
  138. package/estimateRowHeight.js +184 -0
  139. package/featureLengthsToHide.js +27 -0
  140. package/featureTool.js +34 -0
  141. package/features.js +19 -0
  142. package/featuresSelector.js +8 -0
  143. package/filteredCutsitesSelector.js +136 -0
  144. package/filteredFeaturesSelector.js +32 -0
  145. package/filteredPartsSelector.js +57 -0
  146. package/filteredPrimersSelector.js +27 -0
  147. package/filteredRestrictionEnzymesSelector.js +1 -0
  148. package/find.png +0 -0
  149. package/findTool.js +79 -0
  150. package/findToolConstants.js +1 -0
  151. package/frameTranslations.js +52 -0
  152. package/fullscreen.png +0 -0
  153. package/getAdditionalEnzymesSelector.js +46 -0
  154. package/getAngleForPositionMidpoint.js +3 -0
  155. package/getAnnotationClassnames.js +12 -0
  156. package/getAnnotationNameAndStartStopString.js +61 -0
  157. package/getBpsPerRow.js +19 -0
  158. package/getCutsiteLabelHeights.js +56 -0
  159. package/getGapMap.js +12 -0
  160. package/getGaps.js +27 -0
  161. package/getInternalLabel.js +40 -0
  162. package/getOveHotkeyDefs.js +12 -0
  163. package/getPairwiseOverviewLinearViewOptions.js +38 -0
  164. package/getRangeAnglesSpecial.js +12 -0
  165. package/getStructuredBases.js +97 -0
  166. package/getTrackFromEvent.js +25 -0
  167. package/getVisibleStartEnd.js +7 -0
  168. package/getXStartAndWidthFromNonCircularRange.js +12 -0
  169. package/getXStartAndWidthOfRangeWrtRow.js +27 -0
  170. package/getXStartAndWidthOfRowAnnotation.js +19 -0
  171. package/getYOffset.js +15 -0
  172. package/hoveredAnnotation.js +24 -0
  173. package/{html2canvas.esm--JN4fLQL.js → html2canvas.esm-DiGWN1gP.js} +187 -229
  174. package/{html2canvas.esm-B7d7VJmQ.cjs → html2canvas.esm-J1esNpMJ.cjs} +187 -229
  175. package/importTool.js +27 -0
  176. package/index.cjs.js +48165 -47142
  177. package/index.es.js +47699 -46676
  178. package/index.js +71 -0
  179. package/inlineFindTool.js +38 -0
  180. package/isElementInViewport.js +29 -0
  181. package/isEnzymeFilterAndSelector.js +1 -0
  182. package/isTargetWithinEl.js +6 -0
  183. package/labelLineIntensity.js +25 -0
  184. package/labelSize.js +23 -0
  185. package/ladderDefaults.js +25 -0
  186. package/lastSavedId.js +20 -0
  187. package/lineageLines.js +11 -0
  188. package/linear.png +0 -0
  189. package/makeStore.js +34 -0
  190. package/massageTickSpacing.js +19 -0
  191. package/materiallyAvailable.js +19 -0
  192. package/middleware.js +112 -0
  193. package/minimumOrfSize.js +24 -0
  194. package/minimumOrfSizeSelector.js +2 -0
  195. package/modalActions.js +3 -0
  196. package/moveCaret.js +58 -0
  197. package/name.js +19 -0
  198. package/normalizeAngle.js +3 -0
  199. package/normalizeAngleRange.js +9 -0
  200. package/oligoTool.js +30 -0
  201. package/onlyUpdateForKeysDeep.js +31 -0
  202. package/orfFrameToColorMap.js +10 -0
  203. package/orfTool.js +136 -0
  204. package/orfsSelector.js +15 -0
  205. package/ove.css +12107 -0
  206. package/package.json +6 -5
  207. package/panelsShown.js +294 -0
  208. package/partLengthsToHide.js +23 -0
  209. package/partOverhangs.js +6 -0
  210. package/partTagSearch.js +69 -0
  211. package/partTool.js +45 -0
  212. package/parts.js +19 -0
  213. package/partsSelector.js +8 -0
  214. package/pie.png +0 -0
  215. package/polarToSpecialCartesian.js +7 -0
  216. package/positionCutsites.js +6 -0
  217. package/prepareRowData.js +64 -0
  218. package/primerBases.js +221 -0
  219. package/primerLengthsToHide.js +27 -0
  220. package/primers.js +19 -0
  221. package/primersSelector.js +8 -0
  222. package/print.png +0 -0
  223. package/printTool.js +31 -0
  224. package/propertiesTool.js +40 -0
  225. package/proteinUtils.js +3 -0
  226. package/pureNoFunc.js +18 -0
  227. package/readOnly.js +25 -0
  228. package/redoTool.js +30 -0
  229. package/reflex-styles.css +128 -0
  230. package/reflex-styles.css.map +9 -0
  231. package/relaxLabelAngles.js +157 -0
  232. package/relaxLabels_DEPRECATED.js +105 -0
  233. package/replacementLayers.js +36 -0
  234. package/restrictionEnzymes.js +52 -0
  235. package/restrictionEnzymesSelector.js +34 -0
  236. package/rowviewContants.js +3 -0
  237. package/ruler.css +89 -0
  238. package/save.png +0 -0
  239. package/saveTool.js +44 -0
  240. package/searchLayersSelector.js +71 -0
  241. package/selectedAnnotations.js +89 -0
  242. package/selectedAnnotationsSelector.js +1 -0
  243. package/selectedCutsitesSelector.js +21 -0
  244. package/selectedPartTags.js +21 -0
  245. package/selectionLayer.js +25 -0
  246. package/selectors/annotationSearchSelector.d.ts +1 -1
  247. package/sequence.js +12 -0
  248. package/sequenceDataHistory.js +43 -0
  249. package/sequenceDataSelector.js +2 -0
  250. package/sequenceLengthSelector.js +5 -0
  251. package/sequenceSelector.js +4 -0
  252. package/sharedActionCreators.js +0 -0
  253. package/shouldFlipText.js +4 -0
  254. package/shouldRerender.js +27 -0
  255. package/showFileDialog.js +25 -0
  256. package/showGCContent.js +23 -0
  257. package/show_cut_sites.png +0 -0
  258. package/show_features.png +0 -0
  259. package/show_orfs.png +0 -0
  260. package/show_primers.png +0 -0
  261. package/simpleDialog.css +13 -0
  262. package/specialCutsiteFilterOptions.js +22 -0
  263. package/src/Editor/DropHandler.js +2 -1
  264. package/src/Editor/index.js +0 -2
  265. package/src/RowItem/StackedAnnotations/getStructuredBases.js +20 -6
  266. package/src/ToolBar/cutsiteTool.js +1 -1
  267. package/src/helperComponents/PropertiesDialog/TranslationProperties.js +2 -1
  268. package/style.css +3 -12100
  269. package/tagsToBoldSelector.js +2 -0
  270. package/toggle_views.svg +1 -0
  271. package/toolBar.js +23 -0
  272. package/translationSearchMatchesSelector.js +14 -0
  273. package/translations.js +20 -0
  274. package/translationsRawSelector.js +8 -0
  275. package/translationsSelector.js +137 -0
  276. package/typeField.js +24 -0
  277. package/undoTool.js +30 -0
  278. package/updateEditor.d.ts +1 -3
  279. package/updateEditor.js +200 -0
  280. package/updateLabelsForInViewFeatures.js +55 -0
  281. package/updateLabelsForInViewFeaturesCircView.js +41 -0
  282. package/updateTrackHelper.js +58 -0
  283. package/uppercaseSequenceMapFont.js +25 -0
  284. package/upsertDeleteActionGenerator.js +31 -0
  285. package/useAAColorType.js +8 -0
  286. package/useAdditionalOrfStartCodons.js +24 -0
  287. package/useAnnotationLimits.js +42 -0
  288. package/useChromatogramPrefs.js +31 -0
  289. package/useFormValue.js +7 -0
  290. package/useLadders.js +6 -0
  291. package/useMeltingTemp.js +7 -0
  292. package/useTmType.js +10 -0
  293. package/userDefinedHandlersAndOpts.js +61 -0
  294. package/utils/getAnnotationNameAndStartStopString.d.ts +1 -5
  295. package/utils/selectionLayer.d.ts +2 -2
  296. package/utils.js +37 -0
  297. package/versionHistory.js +26 -0
  298. package/versionHistoryTool.js +21 -0
  299. package/viewSubmenu.js +479 -0
  300. package/visibilityTool.js +39 -0
  301. package/withEditorInteractions/getBpsPerRow.d.ts +1 -3
  302. package/withHover.js +113 -0
  303. package/withRestrictionEnzymes.js +15 -0
  304. package/index.umd.js +0 -188322
@@ -0,0 +1,74 @@
1
+ import { DialogFooter, wrapDialog } from "@teselagen/ui";
2
+
3
+ import { Button, Callout, Card } from "@blueprintjs/core";
4
+
5
+ import { hideDialog } from "../GlobalDialogUtils";
6
+ import SimpleCircularOrLinearView from "../SimpleCircularOrLinearView";
7
+ import React, { useState } from "react";
8
+ import { tidyUpSequenceData } from "@teselagen/sequence-utils";
9
+
10
+ export const MultipleSeqsDetectedOnImportDialog = wrapDialog({
11
+ title: "Multiple Sequences Detected"
12
+ // style: { height: 600, width: 800 }
13
+ })(({ results, finishDisplayingSeq }) => {
14
+ const [_selectedSeqData, setSelectedSeqData] = useState(
15
+ results[0].parsedSequence
16
+ );
17
+ const selectedSeqData = tidyUpSequenceData(_selectedSeqData);
18
+ return (
19
+ <div>
20
+ <div className="bp3-dialog-body">
21
+ <Callout intent="primary">
22
+ Multiple sequences were detected in the input file. Please choose one
23
+ to continue
24
+ </Callout>
25
+ <br></br>
26
+ <div style={{ display: "flex" }}>
27
+ <div style={{ maxHeight: 300, overflowY: "auto" }}>
28
+ {results.map((res, i) => {
29
+ const { parsedSequence } = res;
30
+ if (!parsedSequence) return null;
31
+ const { name } = parsedSequence;
32
+ return (
33
+ <div key={i}>
34
+ <Button
35
+ active={parsedSequence === selectedSeqData}
36
+ onClick={() => {
37
+ setSelectedSeqData(parsedSequence);
38
+ }}
39
+ minimal
40
+ >
41
+ {name}
42
+ </Button>
43
+ </div>
44
+ );
45
+ })}
46
+ </div>
47
+ &nbsp;
48
+ <Card elevation={1}>
49
+ <SimpleCircularOrLinearView
50
+ sequenceData={selectedSeqData || { sequence: "" }}
51
+ // tabHeight={tabHeight}
52
+ editorName="previewEditor"
53
+ height={null}
54
+ isProtein={selectedSeqData && selectedSeqData.isProtein}
55
+ annotationLabelVisibility={{
56
+ features: true,
57
+ parts: true,
58
+ cutsites: false,
59
+ primers: true
60
+ }}
61
+ ></SimpleCircularOrLinearView>
62
+ </Card>
63
+ </div>
64
+ </div>
65
+ <DialogFooter
66
+ text="Select"
67
+ onClick={() => {
68
+ finishDisplayingSeq(selectedSeqData);
69
+ hideDialog();
70
+ }}
71
+ ></DialogFooter>
72
+ </div>
73
+ );
74
+ });
package/Orf.js ADDED
@@ -0,0 +1,109 @@
1
+ import getAnnotationNameAndStartStopString from "../utils/getAnnotationNameAndStartStopString";
2
+ import React from "react";
3
+ import orfFrameToColorMap from "../constants/orfFrameToColorMap";
4
+
5
+ function Orf(props) {
6
+ const {
7
+ height,
8
+ rangeType,
9
+ normalizedInternalStartCodonIndices = [],
10
+ forward,
11
+ frame = 0,
12
+ annotation,
13
+ width,
14
+ onClick,
15
+ isProtein,
16
+ onRightClick,
17
+ charWidth,
18
+ readOnly,
19
+ gapsInside,
20
+ gapsBefore
21
+ } = props;
22
+ const heightToUse = height / 1.5;
23
+ const color = orfFrameToColorMap[frame];
24
+ let arrow = null;
25
+ let endCircle = null;
26
+ const circle = (
27
+ <circle
28
+ key="circle"
29
+ r={heightToUse / 2}
30
+ cx={heightToUse / 2}
31
+ cy={heightToUse / 2}
32
+ />
33
+ );
34
+ if (rangeType === "end" || rangeType === "beginningAndEnd") {
35
+ arrow = (
36
+ <path
37
+ transform={`translate(${
38
+ width + gapsInside - Math.max(charWidth, 5)
39
+ },0) scale(${Math.max(charWidth, 8) / 64},${heightToUse / 64})`}
40
+ d={
41
+ rangeType === "start"
42
+ ? "M0 16 L0 48 L16 64 L48 64 L64 48 L64 16 L48 0 L16 0 Z"
43
+ : "M0 64 L64 32 L0 0 Z"
44
+ }
45
+ />
46
+ );
47
+ }
48
+ if (rangeType === "start" || rangeType === "beginningAndEnd") {
49
+ endCircle = circle;
50
+ }
51
+ const internalStartCodonCircles = normalizedInternalStartCodonIndices.map(
52
+ function (internalStartCodon, index) {
53
+ return React.cloneElement(circle, {
54
+ key: index,
55
+ transform: `translate(${charWidth * internalStartCodon},0)`
56
+ });
57
+ }
58
+ );
59
+ return (
60
+ <g
61
+ onClick={function (event) {
62
+ onClick({ annotation, event, gapsInside, gapsBefore });
63
+ }}
64
+ onContextMenu={function (event) {
65
+ onRightClick({ annotation, event, gapsInside, gapsBefore });
66
+ }}
67
+ className={`veRowViewOrf clickable frame${frame}`}
68
+ strokeWidth="1"
69
+ stroke={color}
70
+ fillOpacity={1}
71
+ fill={color}
72
+ transform={
73
+ forward ? null : `translate(${width + gapsInside},0) scale(-1,1)`
74
+ }
75
+ >
76
+ <path
77
+ transform={
78
+ (rangeType === "start" ? `translate(${charWidth},0)` : "") +
79
+ `scale(${
80
+ (width + gapsInside - (rangeType === "middle" ? 0 : charWidth)) / 64
81
+ },${heightToUse / 64})`
82
+ }
83
+ d="M0 40 L64 40 L64 20 L0 20 Z"
84
+ />
85
+ {arrow}
86
+ {endCircle}
87
+ {internalStartCodonCircles}
88
+ <title>
89
+ {" "}
90
+ {getAnnotationNameAndStartStopString(annotation, {
91
+ startText: "Open Reading Frame:",
92
+ isProtein,
93
+ readOnly
94
+ })}{" "}
95
+ </title>
96
+ </g>
97
+ );
98
+ }
99
+
100
+ // Orf.propTypes = {
101
+ // width: PropTypes.number.isRequired,
102
+ // charWidth: PropTypes.number.isRequired,
103
+ // frame: PropTypes.number.isRequired,
104
+ // height: PropTypes.number.isRequired,
105
+ // rangeType: PropTypes.string.isRequired,
106
+ // forward: PropTypes.bool.isRequired
107
+ // };
108
+
109
+ export default Orf;
@@ -0,0 +1,117 @@
1
+ import React from "react";
2
+ import {
3
+ DataTable,
4
+ withSelectedEntities,
5
+ createCommandMenu
6
+ } from "@teselagen/ui";
7
+ import { map } from "lodash-es";
8
+ // import { Button } from "@blueprintjs/core";
9
+ import { getRangeLength } from "@teselagen/range-utils";
10
+ import { getOrfColor } from "../../constants/orfFrameToColorMap";
11
+ import { connectToEditor } from "../../withEditorProps";
12
+ import { compose } from "recompose";
13
+ import selectors from "../../selectors";
14
+
15
+ import getCommands from "../../commands";
16
+ import { sizeSchema } from "./utils";
17
+ import { orfsSubmenu } from "../../MenuBar/viewSubmenu";
18
+ import { getVisFilter } from "./GenericAnnotationProperties";
19
+
20
+ class OrfProperties extends React.Component {
21
+ constructor(props) {
22
+ super(props);
23
+ this.commands = getCommands(this);
24
+ }
25
+ onRowSelect = ([record]) => {
26
+ if (!record) return;
27
+ const { dispatch, editorName } = this.props;
28
+ dispatch({
29
+ type: "SELECTION_LAYER_UPDATE",
30
+ payload: record,
31
+ meta: {
32
+ editorName
33
+ }
34
+ });
35
+ };
36
+ render() {
37
+ const { orfs, sequenceLength, annotationVisibility } = this.props;
38
+ const orfsToUse = map(orfs, orf => {
39
+ return {
40
+ ...orf,
41
+ color: getOrfColor(orf),
42
+ frame: orf.frame + 1,
43
+ ...(orf.strand === undefined && {
44
+ strand: orf.forward ? 1 : -1
45
+ }),
46
+ size: getRangeLength(orf, sequenceLength),
47
+ sizeAa: Math.floor(getRangeLength(orf, sequenceLength) / 3 - 1)
48
+ };
49
+ });
50
+ return (
51
+ <React.Fragment>
52
+ <DataTable
53
+ topLeftItems={getVisFilter(
54
+ createCommandMenu(orfsSubmenu, this.commands, {
55
+ useTicks: true
56
+ })
57
+ )}
58
+ annotationVisibility={annotationVisibility} //we need to pass this in order to force the DT to rerender
59
+ noPadding
60
+ noFullscreenButton
61
+ onRowSelect={this.onRowSelect}
62
+ withSearch={false}
63
+ formName="orfProperties"
64
+ noRouter
65
+ compact
66
+ isInfinite
67
+ schema={{
68
+ fields: [
69
+ {
70
+ path: "color",
71
+ type: "string",
72
+ render: color => {
73
+ return (
74
+ <div style={{ height: 20, width: 20, background: color }} />
75
+ );
76
+ }
77
+ },
78
+ {
79
+ path: "sizeAa",
80
+ displayName: "Size (aa)",
81
+ type: "number"
82
+ },
83
+ sizeSchema(this.props.isProtein),
84
+ { path: "frame", type: "number" },
85
+ { path: "strand", type: "number" }
86
+ ]
87
+ }}
88
+ entities={orfsToUse}
89
+ />
90
+ <br />
91
+ </React.Fragment>
92
+ );
93
+ }
94
+ }
95
+
96
+ export default compose(
97
+ connectToEditor(editorState => {
98
+ const {
99
+ readOnly,
100
+ annotationVisibility = {},
101
+ sequenceData: { sequence = "" } = {},
102
+ sequenceData,
103
+ minimumOrfSize,
104
+ useAdditionalOrfStartCodons
105
+ } = editorState;
106
+ return {
107
+ readOnly,
108
+ annotationVisibility,
109
+ useAdditionalOrfStartCodons,
110
+ orfs: selectors.orfsSelector(editorState),
111
+ sequenceLength: sequence.length,
112
+ sequenceData,
113
+ minimumOrfSize
114
+ };
115
+ }),
116
+ withSelectedEntities("orfProperties")
117
+ )(OrfProperties);
package/Orfs.js ADDED
@@ -0,0 +1,35 @@
1
+ import React from "react";
2
+ import Orf from "./Orf";
3
+ import StackedAnnotations from "./StackedAnnotations";
4
+
5
+ function getExtraInnerCompProps(annotationRange, props) {
6
+ const { row } = props;
7
+ const { annotation, start, end } = annotationRange;
8
+ const { frame, internalStartCodonIndices = [] } = annotation;
9
+ const normalizedInternalStartCodonIndices = internalStartCodonIndices
10
+ .filter(function (position) {
11
+ if (
12
+ position >= row.start &&
13
+ position >= start &&
14
+ position <= end &&
15
+ position <= row.end
16
+ ) {
17
+ return true;
18
+ } else return false;
19
+ })
20
+ .map(function (position) {
21
+ return position - start;
22
+ });
23
+
24
+ return { normalizedInternalStartCodonIndices, frame };
25
+ }
26
+
27
+ function Orfs(props) {
28
+ return (
29
+ <StackedAnnotations
30
+ {...{ ...props, getExtraInnerCompProps, InnerComp: Orf }}
31
+ />
32
+ );
33
+ }
34
+
35
+ export default Orfs;
package/PCRTool.js ADDED
@@ -0,0 +1,179 @@
1
+ import { compose } from "recompose";
2
+ import React from "react";
3
+
4
+ import withEditorInteractions from "../withEditorInteractions";
5
+ import { ReactSelectField, tgFormValues } from "@teselagen/ui";
6
+ import { reduxForm } from "redux-form";
7
+ import { flatMap, forEach, keyBy } from "lodash-es";
8
+ import SimpleCircularOrLinearView from "../SimpleCircularOrLinearView";
9
+ import {
10
+ getReverseComplementSequenceString,
11
+ getSequenceDataBetweenRange,
12
+ tidyUpSequenceData,
13
+ shiftAnnotationsByLen
14
+ } from "@teselagen/sequence-utils";
15
+ import { getRangeLength, getSequenceWithinRange } from "@teselagen/range-utils";
16
+
17
+ function PCRTool(props) {
18
+ const {
19
+ sequenceData,
20
+ dimensions: { width, height },
21
+ forwardPrimer,
22
+ reversePrimer,
23
+ primerClicked
24
+ } = props;
25
+ const origSeqLen = sequenceData.sequence.length;
26
+ forEach(sequenceData.primers, p => (p.originalId = p.id));
27
+ const fPrimer = sequenceData.primers[forwardPrimer];
28
+ const rPrimer = sequenceData.primers[reversePrimer];
29
+ let seqBetween;
30
+ if (fPrimer && rPrimer) {
31
+ const r = {
32
+ start: fPrimer.start,
33
+ end: rPrimer.end
34
+ };
35
+
36
+ const newSeqData = getSequenceDataBetweenRange(sequenceData, r);
37
+
38
+ if (rPrimer.bases) {
39
+ // remove rPrimer length from end of seq
40
+ const rPrimerLen = getRangeLength(rPrimer, origSeqLen);
41
+
42
+ newSeqData.sequence = getSequenceWithinRange(
43
+ { start: 0, end: newSeqData.sequence.length - rPrimerLen - 1 },
44
+ newSeqData.sequence
45
+ );
46
+ // tack back in the rPrimer.bases
47
+ newSeqData.sequence =
48
+ newSeqData.sequence + getReverseComplementSequenceString(rPrimer.bases);
49
+ const newRPrimer = keyBy(newSeqData.primers, "id")[reversePrimer];
50
+
51
+ newRPrimer.end = newSeqData.sequence.length - 1;
52
+ }
53
+ if (fPrimer.bases) {
54
+ const fPrimerLength = getRangeLength(fPrimer, origSeqLen);
55
+ const newSeqLen1 = newSeqData.sequence.length;
56
+ // remove fPrimer length from start of seq
57
+ newSeqData.sequence = getSequenceWithinRange(
58
+ { start: fPrimerLength, end: newSeqData.sequence.length },
59
+ newSeqData.sequence
60
+ );
61
+ // add back in the fPrimer.bases
62
+ newSeqData.sequence = fPrimer.bases + newSeqData.sequence;
63
+ // shift the existing annotations by the difference in seqLen before and after that operation
64
+ const newSeqLen2 = newSeqData.sequence.length;
65
+ const diff = newSeqLen2 - newSeqLen1;
66
+ shiftAnnotationsByLen({
67
+ seqData: newSeqData,
68
+ insertLength: diff,
69
+ caretPosition: 0
70
+ });
71
+ const newFPrimer = keyBy(newSeqData.primers, "id")[forwardPrimer];
72
+ newFPrimer.start = 0;
73
+ }
74
+
75
+ seqBetween = tidyUpSequenceData(newSeqData, {
76
+ provideNewIdsForAnnotations: true
77
+ });
78
+ seqBetween.name = `PCR Product from ${sequenceData.name} `;
79
+ }
80
+ const getPrimers = opts => {
81
+ return flatMap(
82
+ sequenceData.primers,
83
+ ({ name, id, forward, start, end }) => {
84
+ if (opts.forward && !forward) return [];
85
+ if (!opts.forward && forward) return [];
86
+ return {
87
+ label: (
88
+ <div
89
+ style={{
90
+ width: "100%",
91
+ display: "flex",
92
+ alignItems: "center",
93
+ justifyContent: "space-between"
94
+ }}
95
+ >
96
+ <div>{name}</div>
97
+ <div
98
+ style={{
99
+ marginLeft: 8,
100
+ fontStyle: "italic",
101
+ color: "grey",
102
+ fontSize: 11
103
+ }}
104
+ >
105
+ ({start + 1} - {end + 1})
106
+ </div>
107
+ </div>
108
+ ),
109
+ value: id
110
+ };
111
+ }
112
+ );
113
+ };
114
+ const forwardPrimers = getPrimers({ forward: true });
115
+ const reversePrimers = getPrimers({ forward: false });
116
+ return (
117
+ <div
118
+ className="createPcrTool"
119
+ style={{ padding: 10, overflowY: "auto", height }}
120
+ >
121
+ <ReactSelectField
122
+ noResultsText="Create a new primer in the forward direction to use it in this tool"
123
+ inlineLabel
124
+ tooltipError
125
+ options={forwardPrimers}
126
+ defaultValue={
127
+ forwardPrimer ??
128
+ (forwardPrimers[0] ? forwardPrimers[0].value : undefined)
129
+ }
130
+ name="forwardPrimer"
131
+ label="Forward Primer:"
132
+ />
133
+ <ReactSelectField
134
+ noResultsText="Create a new primer in the reverse direction to use it in this tool"
135
+ inlineLabel
136
+ tooltipError
137
+ options={reversePrimers}
138
+ defaultValue={
139
+ reversePrimer ??
140
+ (reversePrimers[0] ? reversePrimers[0].value : undefined)
141
+ }
142
+ name="reversePrimer"
143
+ label="Reverse Primer:"
144
+ />
145
+ <div style={{ fontWeight: "600", fontSize: 13 }}>Output Product:</div>
146
+ {seqBetween ? (
147
+ <SimpleCircularOrLinearView
148
+ noWarnings
149
+ withZoomLinearView
150
+ withZoomCircularView
151
+ withChoosePreviewType
152
+ withDownload
153
+ smallSlider
154
+ withCaretEnabled
155
+ width={width - 50}
156
+ height={Math.max(height - 250, 400)}
157
+ sequenceData={seqBetween}
158
+ primerClicked={args => {
159
+ primerClicked({
160
+ ...args,
161
+ annotation: sequenceData.primers[args.annotation.originalId]
162
+ });
163
+ }}
164
+ ></SimpleCircularOrLinearView>
165
+ ) : (
166
+ <div style={{ marginTop: 5, fontStyle: "italic", color: "grey" }}>
167
+ Please choose a forward and reverse primer to see the resulting PCR
168
+ sequence
169
+ </div>
170
+ )}
171
+ </div>
172
+ );
173
+ }
174
+
175
+ export default compose(
176
+ withEditorInteractions,
177
+ reduxForm({ form: "PCRTool" }),
178
+ tgFormValues("forwardPrimer", "reversePrimer")
179
+ )(PCRTool);
@@ -0,0 +1,68 @@
1
+ import React from "react";
2
+ import { getPairwiseOverviewLinearViewOptions } from "./getPairwiseOverviewLinearViewOptions";
3
+ import { AlignmentView } from "./index";
4
+
5
+ //this view is shown if we detect pairwise alignments
6
+ export class PairwiseAlignmentView extends React.Component {
7
+ state = {
8
+ currentPairwiseAlignmentIndex: undefined
9
+ };
10
+ render() {
11
+ const { pairwiseAlignments, pairwiseOverviewAlignmentTracks } = this.props;
12
+ const { currentPairwiseAlignmentIndex } = this.state;
13
+ if (currentPairwiseAlignmentIndex > -1) {
14
+ //we can render the AlignmentView directly
15
+ //get the alignmentTracks based on currentPairwiseAlignmentIndex
16
+ const alignmentTracks = pairwiseAlignments[currentPairwiseAlignmentIndex];
17
+
18
+ const templateLength = alignmentTracks[0].alignmentData.sequence.length;
19
+ return (
20
+ <AlignmentView
21
+ {...{
22
+ ...this.props,
23
+ sequenceData: {
24
+ //pass fake seq data in so editor interactions work
25
+ sequence: Array.from(templateLength)
26
+ .map(() => "a")
27
+ .join("")
28
+ },
29
+ allowTrackRearrange: false,
30
+ alignmentTracks,
31
+ hasTemplate: true,
32
+ isPairwise: true,
33
+ currentPairwiseAlignmentIndex,
34
+ handleBackButtonClicked: () => {
35
+ this.setState({
36
+ currentPairwiseAlignmentIndex: undefined
37
+ });
38
+ }
39
+ }}
40
+ />
41
+ );
42
+ } else {
43
+ //we haven't yet selected an alignment to view
44
+ // render the AlignmentView zoomed out for each track in pairwiseOverviewAlignmentTracks
45
+ // when the view eye icon is hit (maybe next to the name?)
46
+ return (
47
+ <AlignmentView
48
+ {...{
49
+ ...this.props,
50
+ alignmentTracks: pairwiseOverviewAlignmentTracks,
51
+ allowTrackRearrange: false,
52
+ allowTrimming: false,
53
+ hasTemplate: true,
54
+ isPairwise: true,
55
+ isInPairwiseOverviewView: true,
56
+ isFullyZoomedOut: true,
57
+ noClickDragHandlers: true,
58
+ linearViewOptions: getPairwiseOverviewLinearViewOptions,
59
+ handleSelectTrack: trackIndex => {
60
+ //set currentPairwiseAlignmentIndex
61
+ this.setState({ currentPairwiseAlignmentIndex: trackIndex - 1 });
62
+ }
63
+ }}
64
+ />
65
+ );
66
+ }
67
+ }
68
+ }
package/Part.js ADDED
@@ -0,0 +1,34 @@
1
+ import React from "react";
2
+ import { startsWith } from "lodash-es";
3
+ import drawDirectedPiePiece from "./drawDirectedPiePiece";
4
+
5
+ export default function Part({
6
+ radius,
7
+ arrowheadLength = 0.5,
8
+ annotationHeight,
9
+ totalAngle,
10
+ color,
11
+ overlapsSelf,
12
+ className
13
+ }) {
14
+ const path = drawDirectedPiePiece({
15
+ radius,
16
+ overlapsSelf,
17
+ annotationHeight,
18
+ totalAngle,
19
+ arrowheadLength,
20
+ tailThickness: 1 //feature specific
21
+ });
22
+ const colorToUse = startsWith(color, "override_")
23
+ ? color.replace("override_", "")
24
+ : "#ac68cc";
25
+ return (
26
+ <path
27
+ className={className}
28
+ strokeWidth="0.5"
29
+ stroke={colorToUse}
30
+ // fill={colorToUse}
31
+ d={path.print()}
32
+ />
33
+ );
34
+ }
@@ -0,0 +1,9 @@
1
+ import { partsSubmenu } from "../../MenuBar/viewSubmenu";
2
+ import genericAnnotationProperties from "./GenericAnnotationProperties";
3
+ export default genericAnnotationProperties({
4
+ annotationType: "part",
5
+ noColor: true,
6
+ visSubmenu: partsSubmenu,
7
+ withTags: true,
8
+ noType: true
9
+ });
package/PassThrough.js ADDED
@@ -0,0 +1,3 @@
1
+ export default function ({ children }) {
2
+ return children;
3
+ }
@@ -0,0 +1,32 @@
1
+ import React from "react";
2
+ import SelectionLayer from "../RowItem/SelectionLayer";
3
+ import { view } from "@risingstack/react-easy-state";
4
+
5
+ export const PerformantSelectionLayer = view(({ easyStore, ...rest }) => {
6
+ const seqLen = rest.sequenceLength - 1;
7
+
8
+ return (
9
+ <SelectionLayer
10
+ regions={[
11
+ { ...easyStore.selectionLayer, ignoreGaps: true },
12
+ {
13
+ start: Math.floor(
14
+ (easyStore.percentScrolledPreZoom || easyStore.percentScrolled) *
15
+ seqLen
16
+ ),
17
+ end: Math.floor(
18
+ (easyStore.percentScrolledPreZoom || easyStore.percentScrolled) *
19
+ seqLen
20
+ ),
21
+ className: "zoomSelection",
22
+ ignoreGaps: true,
23
+ style: {
24
+ zIndex: -1,
25
+ opacity: 0
26
+ }
27
+ }
28
+ ]}
29
+ {...rest}
30
+ />
31
+ );
32
+ });
package/PinchHelper.js ADDED
@@ -0,0 +1,24 @@
1
+ import { usePinch } from "@use-gesture/react";
2
+ import React from "react";
3
+ /**
4
+ * wrapper for the react usePinch gesture
5
+ * @param {*} children child components to be enveloped
6
+ * @param {*} onPinch the action to be performed when pinch gesture is registered
7
+ */
8
+ export default function PinchHelper({ children, onPinch }) {
9
+ const target = React.useRef();
10
+
11
+ usePinch(
12
+ arg => {
13
+ if (onPinch) onPinch(arg);
14
+ },
15
+ {
16
+ target
17
+ }
18
+ );
19
+ return (
20
+ <div ref={target} className="tg-pinch-helper">
21
+ {children}
22
+ </div>
23
+ );
24
+ }