@teselagen/ove 0.5.13 → 0.5.14
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/index.cjs.js +217 -133
- package/index.es.js +217 -133
- package/index.umd.js +175 -117
- package/package.json +2 -2
- package/src/RowItem/Translations/AASliver.js +12 -11
- package/src/RowItem/Translations/Translation.js +41 -9
package/index.umd.js
CHANGED
|
@@ -41069,25 +41069,16 @@ ${latestSubscriptionCallbackError.current.stack}
|
|
|
41069
41069
|
var _cof = /* @__PURE__ */ __name(function(it) {
|
|
41070
41070
|
return toString$3.call(it).slice(8, -1);
|
|
41071
41071
|
}, "_cof");
|
|
41072
|
-
var
|
|
41073
|
-
var
|
|
41074
|
-
|
|
41075
|
-
|
|
41076
|
-
return _iobject;
|
|
41077
|
-
hasRequired_iobject = 1;
|
|
41078
|
-
var cof2 = _cof;
|
|
41079
|
-
_iobject = Object("z").propertyIsEnumerable(0) ? Object : function(it) {
|
|
41080
|
-
return cof2(it) == "String" ? it.split("") : Object(it);
|
|
41081
|
-
};
|
|
41082
|
-
return _iobject;
|
|
41083
|
-
}
|
|
41084
|
-
__name(require_iobject, "require_iobject");
|
|
41072
|
+
var cof$2 = _cof;
|
|
41073
|
+
var _iobject = Object("z").propertyIsEnumerable(0) ? Object : function(it) {
|
|
41074
|
+
return cof$2(it) == "String" ? it.split("") : Object(it);
|
|
41075
|
+
};
|
|
41085
41076
|
var _defined = /* @__PURE__ */ __name(function(it) {
|
|
41086
41077
|
if (it == void 0)
|
|
41087
41078
|
throw TypeError("Can't call method on " + it);
|
|
41088
41079
|
return it;
|
|
41089
41080
|
}, "_defined");
|
|
41090
|
-
var IObject =
|
|
41081
|
+
var IObject = _iobject;
|
|
41091
41082
|
var defined$2 = _defined;
|
|
41092
41083
|
var _toIobject = /* @__PURE__ */ __name(function(it) {
|
|
41093
41084
|
return IObject(defined$2(it));
|
|
@@ -41208,7 +41199,7 @@ ${latestSubscriptionCallbackError.current.stack}
|
|
|
41208
41199
|
var gOPS2 = _objectGops;
|
|
41209
41200
|
var pIE2 = require_objectPie();
|
|
41210
41201
|
var toObject2 = _toObject;
|
|
41211
|
-
var IObject2 =
|
|
41202
|
+
var IObject2 = _iobject;
|
|
41212
41203
|
var $assign = Object.assign;
|
|
41213
41204
|
_objectAssign = !$assign || _fails(function() {
|
|
41214
41205
|
var A2 = {};
|
|
@@ -108790,123 +108781,167 @@ ${latestSubscriptionCallbackError.current.stack}
|
|
|
108790
108781
|
return proteinAlphabet[letter.toUpperCase()];
|
|
108791
108782
|
}
|
|
108792
108783
|
__name(getAminoAcidFromSequenceTriplet, "getAminoAcidFromSequenceTriplet");
|
|
108793
|
-
function
|
|
108784
|
+
function getNextTriplet(index2, sequenceString, exonRange) {
|
|
108785
|
+
let triplet = "";
|
|
108786
|
+
let internalIndex;
|
|
108787
|
+
const codonPositions = [];
|
|
108788
|
+
const isBaseInExon = /* @__PURE__ */ __name((baseIndex) => exonRange.some(
|
|
108789
|
+
(r2) => isPositionWithinRange(baseIndex, r2, sequenceString.length, true, false)
|
|
108790
|
+
), "isBaseInExon");
|
|
108791
|
+
for (internalIndex = index2; internalIndex < sequenceString.length; internalIndex++) {
|
|
108792
|
+
if (triplet.length === 3) {
|
|
108793
|
+
break;
|
|
108794
|
+
}
|
|
108795
|
+
if (isBaseInExon(internalIndex)) {
|
|
108796
|
+
triplet += sequenceString[internalIndex];
|
|
108797
|
+
codonPositions.push(internalIndex);
|
|
108798
|
+
}
|
|
108799
|
+
}
|
|
108800
|
+
return { triplet, basesRead: internalIndex - index2, codonPositions };
|
|
108801
|
+
}
|
|
108802
|
+
__name(getNextTriplet, "getNextTriplet");
|
|
108803
|
+
function getTranslatedSequenceProperties(originalSequenceString, forward, optionalSubrangeRange, isProteinSequence) {
|
|
108794
108804
|
const originalSequenceStringLength = isProteinSequence ? originalSequenceString.length * 3 : originalSequenceString.length;
|
|
108795
108805
|
let sequenceString = originalSequenceString;
|
|
108796
|
-
|
|
108806
|
+
const translationRange = { start: 0, end: originalSequenceStringLength - 1 };
|
|
108797
108807
|
if (optionalSubrangeRange) {
|
|
108798
108808
|
sequenceString = getSequenceWithinRange(
|
|
108799
108809
|
optionalSubrangeRange,
|
|
108800
108810
|
originalSequenceString
|
|
108801
108811
|
);
|
|
108802
|
-
|
|
108812
|
+
translationRange.start = optionalSubrangeRange.start;
|
|
108813
|
+
translationRange.end = optionalSubrangeRange.end;
|
|
108803
108814
|
}
|
|
108804
108815
|
const sequenceStringLength = isProteinSequence ? sequenceString.length * 3 : sequenceString.length;
|
|
108805
|
-
|
|
108806
|
-
|
|
108807
|
-
|
|
108808
|
-
|
|
108809
|
-
|
|
108810
|
-
|
|
108811
|
-
|
|
108812
|
-
|
|
108813
|
-
{
|
|
108814
|
-
start: 0,
|
|
108815
|
-
end: revCompGapLength - 1
|
|
108816
|
-
},
|
|
108817
|
-
startOffset,
|
|
108816
|
+
if (!isProteinSequence && !forward) {
|
|
108817
|
+
sequenceString = getReverseComplementSequenceString(sequenceString);
|
|
108818
|
+
}
|
|
108819
|
+
const absoluteExonRange = !isProteinSequence && optionalSubrangeRange && optionalSubrangeRange.locations ? optionalSubrangeRange.locations : [translationRange];
|
|
108820
|
+
const exonRange = absoluteExonRange.map((range2) => {
|
|
108821
|
+
let outputRange = translateRange(
|
|
108822
|
+
range2,
|
|
108823
|
+
-translationRange.start,
|
|
108818
108824
|
originalSequenceStringLength
|
|
108819
108825
|
);
|
|
108820
|
-
if (
|
|
108821
|
-
|
|
108822
|
-
|
|
108823
|
-
|
|
108824
|
-
|
|
108825
|
-
|
|
108826
|
-
aminoAcidIndex,
|
|
108827
|
-
sequenceIndex: codonRange.start + i2,
|
|
108828
|
-
codonRange,
|
|
108829
|
-
fullCodon: false
|
|
108830
|
-
});
|
|
108831
|
-
}
|
|
108832
|
-
aminoAcidIndex--;
|
|
108826
|
+
if (!forward) {
|
|
108827
|
+
outputRange = flipRelativeRange(
|
|
108828
|
+
outputRange,
|
|
108829
|
+
{ start: 0, end: sequenceStringLength - 1 },
|
|
108830
|
+
sequenceStringLength
|
|
108831
|
+
);
|
|
108833
108832
|
}
|
|
108833
|
+
return outputRange;
|
|
108834
|
+
});
|
|
108835
|
+
return {
|
|
108836
|
+
sequenceString,
|
|
108837
|
+
translationRange,
|
|
108838
|
+
sequenceStringLength,
|
|
108839
|
+
originalSequenceStringLength,
|
|
108840
|
+
exonRange
|
|
108841
|
+
};
|
|
108842
|
+
}
|
|
108843
|
+
__name(getTranslatedSequenceProperties, "getTranslatedSequenceProperties");
|
|
108844
|
+
function positionInCdsToPositionInMainSequence(index2, forward, translationRange, mainSequenceLength) {
|
|
108845
|
+
let outputRange = translateRange(
|
|
108846
|
+
{ start: index2, end: index2 },
|
|
108847
|
+
translationRange.start,
|
|
108848
|
+
mainSequenceLength
|
|
108849
|
+
);
|
|
108850
|
+
if (!forward) {
|
|
108851
|
+
outputRange = flipRelativeRange(
|
|
108852
|
+
outputRange,
|
|
108853
|
+
translationRange,
|
|
108854
|
+
mainSequenceLength
|
|
108855
|
+
);
|
|
108834
108856
|
}
|
|
108835
|
-
|
|
108857
|
+
return outputRange.start;
|
|
108858
|
+
}
|
|
108859
|
+
__name(positionInCdsToPositionInMainSequence, "positionInCdsToPositionInMainSequence");
|
|
108860
|
+
function getAminoAcidDataForEachBaseOfDna(originalSequenceString, forward, optionalSubrangeRange, isProteinSequence) {
|
|
108861
|
+
const {
|
|
108862
|
+
sequenceString,
|
|
108863
|
+
translationRange,
|
|
108864
|
+
sequenceStringLength,
|
|
108865
|
+
originalSequenceStringLength,
|
|
108866
|
+
exonRange
|
|
108867
|
+
} = getTranslatedSequenceProperties(
|
|
108868
|
+
originalSequenceString,
|
|
108869
|
+
forward,
|
|
108870
|
+
optionalSubrangeRange,
|
|
108871
|
+
isProteinSequence
|
|
108872
|
+
);
|
|
108873
|
+
const aminoAcidDataForEachBaseOfDNA = [];
|
|
108874
|
+
for (let index2 = 0; index2 < sequenceStringLength; index2 += 3) {
|
|
108836
108875
|
let aminoAcid;
|
|
108876
|
+
const aminoAcidIndex = index2 / 3;
|
|
108877
|
+
let codonPositionsInCDS;
|
|
108878
|
+
let basesRead;
|
|
108837
108879
|
if (isProteinSequence) {
|
|
108838
|
-
|
|
108880
|
+
codonPositionsInCDS = [0, 1, 2].map((i2) => index2 + i2);
|
|
108881
|
+
basesRead = 3;
|
|
108882
|
+
aminoAcid = proteinAlphabet[sequenceString[index2 / 3].toUpperCase()];
|
|
108839
108883
|
} else {
|
|
108840
|
-
|
|
108841
|
-
|
|
108842
|
-
|
|
108843
|
-
|
|
108844
|
-
|
|
108845
|
-
|
|
108846
|
-
|
|
108847
|
-
|
|
108848
|
-
|
|
108849
|
-
|
|
108850
|
-
|
|
108851
|
-
|
|
108852
|
-
|
|
108884
|
+
const {
|
|
108885
|
+
triplet,
|
|
108886
|
+
basesRead: _basesRead,
|
|
108887
|
+
codonPositions
|
|
108888
|
+
} = getNextTriplet(index2, sequenceString, exonRange);
|
|
108889
|
+
basesRead = _basesRead;
|
|
108890
|
+
codonPositionsInCDS = codonPositions;
|
|
108891
|
+
aminoAcid = triplet.length === 3 ? getAminoAcidFromSequenceTriplet(triplet) : getAminoAcidFromSequenceTriplet("xxx");
|
|
108892
|
+
}
|
|
108893
|
+
const absoluteCodonPositions = codonPositionsInCDS.map(
|
|
108894
|
+
(i2) => positionInCdsToPositionInMainSequence(
|
|
108895
|
+
i2,
|
|
108896
|
+
forward,
|
|
108897
|
+
translationRange,
|
|
108898
|
+
originalSequenceStringLength
|
|
108899
|
+
)
|
|
108853
108900
|
);
|
|
108854
|
-
|
|
108855
|
-
|
|
108856
|
-
|
|
108857
|
-
|
|
108858
|
-
|
|
108859
|
-
|
|
108860
|
-
|
|
108861
|
-
|
|
108862
|
-
|
|
108863
|
-
|
|
108864
|
-
|
|
108865
|
-
|
|
108866
|
-
|
|
108867
|
-
|
|
108868
|
-
|
|
108869
|
-
|
|
108870
|
-
|
|
108871
|
-
|
|
108872
|
-
|
|
108873
|
-
|
|
108874
|
-
|
|
108875
|
-
|
|
108876
|
-
|
|
108877
|
-
|
|
108878
|
-
|
|
108879
|
-
|
|
108880
|
-
|
|
108881
|
-
|
|
108882
|
-
|
|
108883
|
-
|
|
108884
|
-
|
|
108901
|
+
const codonRange = forward ? {
|
|
108902
|
+
start: absoluteCodonPositions[0],
|
|
108903
|
+
end: absoluteCodonPositions[codonPositionsInCDS.length - 1]
|
|
108904
|
+
} : {
|
|
108905
|
+
start: absoluteCodonPositions[codonPositionsInCDS.length - 1],
|
|
108906
|
+
end: absoluteCodonPositions[0]
|
|
108907
|
+
};
|
|
108908
|
+
let positionInCodon = 0;
|
|
108909
|
+
for (let i2 = 0; i2 < basesRead; i2++) {
|
|
108910
|
+
const posInCds = i2 + index2;
|
|
108911
|
+
if (codonPositionsInCDS.includes(posInCds)) {
|
|
108912
|
+
aminoAcidDataForEachBaseOfDNA.push({
|
|
108913
|
+
aminoAcid,
|
|
108914
|
+
positionInCodon,
|
|
108915
|
+
aminoAcidIndex,
|
|
108916
|
+
sequenceIndex: absoluteCodonPositions[i2],
|
|
108917
|
+
codonRange,
|
|
108918
|
+
fullCodon: codonPositionsInCDS.length === 3
|
|
108919
|
+
});
|
|
108920
|
+
positionInCodon++;
|
|
108921
|
+
} else {
|
|
108922
|
+
aminoAcidDataForEachBaseOfDNA.push({
|
|
108923
|
+
aminoAcid: null,
|
|
108924
|
+
positionInCodon: null,
|
|
108925
|
+
aminoAcidIndex: null,
|
|
108926
|
+
sequenceIndex: positionInCdsToPositionInMainSequence(
|
|
108927
|
+
posInCds,
|
|
108928
|
+
forward,
|
|
108929
|
+
translationRange,
|
|
108930
|
+
originalSequenceStringLength
|
|
108931
|
+
),
|
|
108932
|
+
codonRange: null,
|
|
108933
|
+
fullCodon: null
|
|
108934
|
+
});
|
|
108935
|
+
}
|
|
108885
108936
|
}
|
|
108886
|
-
|
|
108887
|
-
const lengthOfEndBpsNotCoveredByAminoAcids = sequenceStringLength - aminoAcidDataForEachBaseOfDNA.length;
|
|
108888
|
-
codonRange = translateRange(
|
|
108889
|
-
{
|
|
108890
|
-
start: sequenceStringLength - lengthOfEndBpsNotCoveredByAminoAcids,
|
|
108891
|
-
end: sequenceStringLength - 1
|
|
108892
|
-
},
|
|
108893
|
-
startOffset,
|
|
108894
|
-
originalSequenceStringLength
|
|
108895
|
-
);
|
|
108896
|
-
for (let j2 = 0; j2 < lengthOfEndBpsNotCoveredByAminoAcids; j2++) {
|
|
108897
|
-
aminoAcidDataForEachBaseOfDNA.push({
|
|
108898
|
-
aminoAcid: getAminoAcidFromSequenceTriplet("xxx"),
|
|
108899
|
-
//fake xxx triplet returns the gap amino acid
|
|
108900
|
-
positionInCodon: j2,
|
|
108901
|
-
aminoAcidIndex,
|
|
108902
|
-
sequenceIndex: codonRange.start + j2,
|
|
108903
|
-
fullCodon: false,
|
|
108904
|
-
codonRange
|
|
108905
|
-
});
|
|
108937
|
+
index2 += basesRead - codonPositionsInCDS.length;
|
|
108906
108938
|
}
|
|
108907
108939
|
if (sequenceStringLength !== aminoAcidDataForEachBaseOfDNA.length) {
|
|
108908
108940
|
throw new Error("something went wrong!");
|
|
108909
108941
|
}
|
|
108942
|
+
if (!forward) {
|
|
108943
|
+
aminoAcidDataForEachBaseOfDNA.reverse();
|
|
108944
|
+
}
|
|
108910
108945
|
return aminoAcidDataForEachBaseOfDNA;
|
|
108911
108946
|
}
|
|
108912
108947
|
__name(getAminoAcidDataForEachBaseOfDna, "getAminoAcidDataForEachBaseOfDna");
|
|
@@ -147931,7 +147966,7 @@ double click --> edit`}`;
|
|
|
147931
147966
|
fill: color2 || "gray"
|
|
147932
147967
|
}
|
|
147933
147968
|
)),
|
|
147934
|
-
!isFiller && /* @__PURE__ */ React$2.createElement(
|
|
147969
|
+
(!isFiller || isTruncatedEnd && isTruncatedStart) && /* @__PURE__ */ React$2.createElement(
|
|
147935
147970
|
"text",
|
|
147936
147971
|
{
|
|
147937
147972
|
fontSize: 25,
|
|
@@ -148008,18 +148043,39 @@ double click --> edit`}`;
|
|
|
148008
148043
|
subrangeStartRelativeToAnnotationStart,
|
|
148009
148044
|
aminoAcids
|
|
148010
148045
|
);
|
|
148046
|
+
let prevAaSliver;
|
|
148047
|
+
let nextAaSliver = aminoAcidsForSubrange[1];
|
|
148048
|
+
const lastIndex = aminoAcidsForSubrange.length - 1;
|
|
148011
148049
|
const translationSVG = aminoAcidsForSubrange.map(
|
|
148012
148050
|
function(aminoAcidSliver, index2) {
|
|
148013
|
-
|
|
148014
|
-
|
|
148015
|
-
|
|
148051
|
+
if (aminoAcidSliver.positionInCodon === null) {
|
|
148052
|
+
prevAaSliver = aminoAcidSliver;
|
|
148053
|
+
nextAaSliver = aminoAcidsForSubrange[index2 + 2];
|
|
148054
|
+
return /* @__PURE__ */ React$2.createElement(
|
|
148055
|
+
"rect",
|
|
148056
|
+
{
|
|
148057
|
+
x: index2 * charWidth2,
|
|
148058
|
+
y: height2 / 2 - height2 / 16,
|
|
148059
|
+
width: charWidth2,
|
|
148060
|
+
height: height2 / 8,
|
|
148061
|
+
fill: "grey",
|
|
148062
|
+
stroke: "black",
|
|
148063
|
+
strokeWidth: 1
|
|
148064
|
+
}
|
|
148065
|
+
);
|
|
148066
|
+
}
|
|
148067
|
+
const isEndFiller = (index2 === 0 || (prevAaSliver == null ? void 0 : prevAaSliver.positionInCodon) === null) && aminoAcidSliver.positionInCodon === (annotation.forward ? 2 : 0);
|
|
148068
|
+
const isStartFiller = (index2 === lastIndex || (nextAaSliver == null ? void 0 : nextAaSliver.positionInCodon) === null) && aminoAcidSliver.positionInCodon === (annotation.forward ? 0 : 2);
|
|
148069
|
+
let isTruncatedEnd = (index2 === 0 || (prevAaSliver == null ? void 0 : prevAaSliver.positionInCodon) === null) && aminoAcidSliver.positionInCodon === 1;
|
|
148070
|
+
let isTruncatedStart = (index2 === lastIndex || (nextAaSliver == null ? void 0 : nextAaSliver.positionInCodon) === null) && aminoAcidSliver.positionInCodon === 1;
|
|
148016
148071
|
if (!annotation.forward) {
|
|
148017
148072
|
const holder = isTruncatedEnd;
|
|
148018
148073
|
isTruncatedEnd = isTruncatedStart;
|
|
148019
148074
|
isTruncatedStart = holder;
|
|
148020
148075
|
}
|
|
148021
|
-
const isStartFiller = index2 === aminoAcidsForSubrange.length - 1 && aminoAcidSliver.positionInCodon === (annotation.forward ? 0 : 2);
|
|
148022
148076
|
if (aminoAcidSliver.positionInCodon !== 1 && !isStartFiller && !isEndFiller) {
|
|
148077
|
+
prevAaSliver = aminoAcidSliver;
|
|
148078
|
+
nextAaSliver = aminoAcidsForSubrange[index2 + 2];
|
|
148023
148079
|
return null;
|
|
148024
148080
|
}
|
|
148025
148081
|
const { gapsInside, gapsBefore } = getGaps(aminoAcidSliver.codonRange);
|
|
@@ -148036,10 +148092,12 @@ double click --> edit`}`;
|
|
|
148036
148092
|
} else {
|
|
148037
148093
|
color2 = aminoAcid.color;
|
|
148038
148094
|
}
|
|
148095
|
+
prevAaSliver = aminoAcidSliver;
|
|
148096
|
+
nextAaSliver = aminoAcidsForSubrange[index2 + 2];
|
|
148039
148097
|
return /* @__PURE__ */ React$2.createElement(
|
|
148040
148098
|
AASliver$1,
|
|
148041
148099
|
{
|
|
148042
|
-
isFiller: isEndFiller || isStartFiller,
|
|
148100
|
+
isFiller: isEndFiller || isStartFiller || isTruncatedEnd && isTruncatedStart,
|
|
148043
148101
|
isTruncatedEnd,
|
|
148044
148102
|
isTruncatedStart,
|
|
148045
148103
|
onClick: function(event) {
|
|
@@ -150251,7 +150309,7 @@ Part of ${annotation.translationType} Translation from BPs ${annotation.start +
|
|
|
150251
150309
|
}
|
|
150252
150310
|
__name(showFileDialog, "showFileDialog");
|
|
150253
150311
|
const name = "@teselagen/ove";
|
|
150254
|
-
const version = "0.5.
|
|
150312
|
+
const version = "0.5.13";
|
|
150255
150313
|
const main = "./src/index.js";
|
|
150256
150314
|
const type = "module";
|
|
150257
150315
|
const exports$1 = {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@teselagen/ove",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.14",
|
|
4
4
|
"main": "./src/index.js",
|
|
5
5
|
"exports": {
|
|
6
6
|
".": {
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
"dependencies": {
|
|
13
13
|
"@teselagen/sequence-utils": "0.3.24",
|
|
14
14
|
"@teselagen/range-utils": "0.3.7",
|
|
15
|
-
"@teselagen/ui": "0.4.
|
|
15
|
+
"@teselagen/ui": "0.4.11",
|
|
16
16
|
"@teselagen/file-utils": "0.3.16",
|
|
17
17
|
"@teselagen/bounce-loader": "0.3.11",
|
|
18
18
|
"@teselagen/bio-parsers": "0.4.18",
|
|
@@ -36,8 +36,8 @@ function AASliver(props) {
|
|
|
36
36
|
path = isFiller
|
|
37
37
|
? "25,0 49,0 60,50 49,100 25,100 38,50 25,0"
|
|
38
38
|
: isTruncatedStart
|
|
39
|
-
|
|
40
|
-
|
|
39
|
+
? // ? "0,0 50,0 60,50 50,100 00,100 16,50 0,0"
|
|
40
|
+
`M ${roundedCorner / 3}, 0
|
|
41
41
|
L ${50 - roundedCorner / 3}, 0
|
|
42
42
|
Q 50 0 ${50 + roundedCorner * dirX1} ${roundedCorner * dirY1}
|
|
43
43
|
L ${60 - roundedCorner * dirX1}, ${50 - roundedCorner * dirY1}
|
|
@@ -59,9 +59,9 @@ function AASliver(props) {
|
|
|
59
59
|
L ${roundedCorner * dirX2}, ${roundedCorner * dirY2}
|
|
60
60
|
Q 0 0 ${roundedCorner / 3} 0
|
|
61
61
|
z`
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
62
|
+
: isTruncatedEnd
|
|
63
|
+
? // ? "24,0 74,0 84,50 74,100 24,100 40,50 24,0"
|
|
64
|
+
`M ${24 + roundedCorner / 3}, 0
|
|
65
65
|
L ${74 - roundedCorner / 3}, 0
|
|
66
66
|
Q 74 0 ${74 + roundedCorner * dirX1} ${roundedCorner * dirY1}
|
|
67
67
|
L ${84 - roundedCorner * dirX1}, ${50 - roundedCorner * dirY1}
|
|
@@ -83,7 +83,7 @@ function AASliver(props) {
|
|
|
83
83
|
L ${24 + roundedCorner * dirX2}, ${roundedCorner * dirY2}
|
|
84
84
|
Q 24 0 ${24 + roundedCorner / 3} 0
|
|
85
85
|
z`
|
|
86
|
-
|
|
86
|
+
: `M ${roundedCorner / 3}, 0
|
|
87
87
|
L ${74 - roundedCorner / 3}, 0
|
|
88
88
|
Q 74 0 ${74 + roundedCorner * dirX1} ${roundedCorner * dirY1}
|
|
89
89
|
L ${84 - roundedCorner * dirX1}, ${50 - roundedCorner * dirY1}
|
|
@@ -130,10 +130,10 @@ function AASliver(props) {
|
|
|
130
130
|
isFiller
|
|
131
131
|
? "25,0 49,0 60,50 49,100 25,100 38,50 25,0"
|
|
132
132
|
: isTruncatedStart
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
133
|
+
? "0,0 50,0 60,50 50,100 00,100 16,50 0,0"
|
|
134
|
+
: isTruncatedEnd
|
|
135
|
+
? "24,0 74,0 84,50 74,100 24,100 40,50 24,0"
|
|
136
|
+
: "0,0 74,0 85,50 74,100 0,100 16,50 0,0"
|
|
137
137
|
}
|
|
138
138
|
strokeWidth="5"
|
|
139
139
|
fill={color || "gray"}
|
|
@@ -148,7 +148,8 @@ function AASliver(props) {
|
|
|
148
148
|
/>
|
|
149
149
|
))}
|
|
150
150
|
|
|
151
|
-
{
|
|
151
|
+
{/* isTruncatedEnd && isTruncatedStart is the special case of a single base exon */}
|
|
152
|
+
{(!isFiller || (isTruncatedEnd && isTruncatedStart)) && (
|
|
152
153
|
<text
|
|
153
154
|
fontSize={25}
|
|
154
155
|
stroke="black"
|
|
@@ -57,31 +57,55 @@ class Translation extends React.Component {
|
|
|
57
57
|
);
|
|
58
58
|
|
|
59
59
|
//we then loop over all the amino acids in the sub range and draw them onto the row
|
|
60
|
+
let prevAaSliver;
|
|
61
|
+
let nextAaSliver = aminoAcidsForSubrange[1];
|
|
62
|
+
// The last index in the sequence
|
|
63
|
+
const lastIndex = aminoAcidsForSubrange.length - 1;
|
|
64
|
+
|
|
60
65
|
const translationSVG = aminoAcidsForSubrange.map(
|
|
61
66
|
function (aminoAcidSliver, index) {
|
|
67
|
+
if (aminoAcidSliver.positionInCodon === null) {
|
|
68
|
+
prevAaSliver = aminoAcidSliver;
|
|
69
|
+
nextAaSliver = aminoAcidsForSubrange[index + 2];
|
|
70
|
+
return (
|
|
71
|
+
<rect
|
|
72
|
+
x={index * charWidth}
|
|
73
|
+
y={height / 2 - height / 16}
|
|
74
|
+
width={charWidth}
|
|
75
|
+
height={height / 8}
|
|
76
|
+
fill="grey"
|
|
77
|
+
stroke="black"
|
|
78
|
+
strokeWidth={1}
|
|
79
|
+
></rect>
|
|
80
|
+
);
|
|
81
|
+
}
|
|
62
82
|
const isEndFiller =
|
|
63
|
-
index === 0 &&
|
|
83
|
+
(index === 0 || prevAaSliver?.positionInCodon === null) &&
|
|
64
84
|
aminoAcidSliver.positionInCodon === (annotation.forward ? 2 : 0);
|
|
65
|
-
|
|
85
|
+
|
|
86
|
+
const isStartFiller =
|
|
87
|
+
(index === lastIndex || nextAaSliver?.positionInCodon === null) &&
|
|
88
|
+
aminoAcidSliver.positionInCodon === (annotation.forward ? 0 : 2);
|
|
89
|
+
|
|
66
90
|
let isTruncatedEnd =
|
|
67
|
-
index === 0
|
|
91
|
+
(index === 0 || prevAaSliver?.positionInCodon === null) &&
|
|
92
|
+
aminoAcidSliver.positionInCodon === 1;
|
|
68
93
|
let isTruncatedStart =
|
|
69
|
-
index ===
|
|
94
|
+
(index === lastIndex || nextAaSliver?.positionInCodon === null) &&
|
|
70
95
|
aminoAcidSliver.positionInCodon === 1;
|
|
96
|
+
|
|
71
97
|
if (!annotation.forward) {
|
|
72
98
|
const holder = isTruncatedEnd;
|
|
73
99
|
isTruncatedEnd = isTruncatedStart;
|
|
74
100
|
isTruncatedStart = holder;
|
|
75
101
|
}
|
|
76
|
-
const isStartFiller =
|
|
77
|
-
index === aminoAcidsForSubrange.length - 1 &&
|
|
78
|
-
aminoAcidSliver.positionInCodon === (annotation.forward ? 0 : 2);
|
|
79
|
-
|
|
80
102
|
if (
|
|
81
103
|
aminoAcidSliver.positionInCodon !== 1 &&
|
|
82
104
|
!isStartFiller &&
|
|
83
105
|
!isEndFiller
|
|
84
106
|
) {
|
|
107
|
+
prevAaSliver = aminoAcidSliver;
|
|
108
|
+
nextAaSliver = aminoAcidsForSubrange[index + 2];
|
|
85
109
|
return null;
|
|
86
110
|
}
|
|
87
111
|
const { gapsInside, gapsBefore } = getGaps(aminoAcidSliver.codonRange);
|
|
@@ -103,9 +127,17 @@ class Translation extends React.Component {
|
|
|
103
127
|
} else {
|
|
104
128
|
color = aminoAcid.color;
|
|
105
129
|
}
|
|
130
|
+
prevAaSliver = aminoAcidSliver;
|
|
131
|
+
nextAaSliver = aminoAcidsForSubrange[index + 2];
|
|
132
|
+
|
|
106
133
|
return (
|
|
107
134
|
<AASliver
|
|
108
|
-
|
|
135
|
+
// isTruncatedEnd && isTruncatedStart is the special case of a single base exon
|
|
136
|
+
isFiller={
|
|
137
|
+
isEndFiller ||
|
|
138
|
+
isStartFiller ||
|
|
139
|
+
(isTruncatedEnd && isTruncatedStart)
|
|
140
|
+
}
|
|
109
141
|
isTruncatedEnd={isTruncatedEnd}
|
|
110
142
|
isTruncatedStart={isTruncatedStart}
|
|
111
143
|
onClick={function (event) {
|