@apollo-annotation/jbrowse-plugin-apollo 0.3.9 → 0.3.10
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.esm.js +235 -120
- package/dist/index.esm.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.development.js +233 -118
- package/dist/jbrowse-plugin-apollo.cjs.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.cjs.production.min.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.development.js +391 -195
- package/dist/jbrowse-plugin-apollo.umd.development.js.map +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js +1 -1
- package/dist/jbrowse-plugin-apollo.umd.production.min.js.map +1 -1
- package/package.json +4 -4
- package/src/ApolloInternetAccount/components/AuthTypeSelector.tsx +1 -1
- package/src/ApolloInternetAccount/model.ts +6 -2
- package/src/BackendDrivers/CollaborationServerDriver.ts +11 -5
- package/src/ChangeManager.ts +19 -4
- package/src/FeatureDetailsWidget/TranscriptWidgetEditLocation.tsx +29 -9
- package/src/LinearApolloDisplay/glyphs/GeneGlyph.ts +2 -2
- package/src/LinearApolloDisplay/glyphs/util.ts +17 -0
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceOverlay.ts +18 -25
- package/src/LinearApolloReferenceSequenceDisplay/drawSequenceTrack.ts +41 -59
- package/src/LinearApolloSixFrameDisplay/stateModel/base.ts +33 -2
- package/src/LinearApolloSixFrameDisplay/stateModel/rendering.ts +101 -3
- package/src/components/AddAssembly.tsx +1 -1
- package/src/components/ImportFeatures.tsx +1 -1
- package/src/components/OntologyTermAutocomplete.tsx +2 -2
- package/src/components/OntologyTermMultiSelect.tsx +2 -2
- package/src/makeDisplayComponent.tsx +1 -1
- package/src/session/ClientDataStore.ts +1 -1
- package/src/session/session.ts +4 -0
- package/src/util/displayUtils.ts +28 -0
- package/src/util/glyphUtils.ts +18 -0
|
@@ -1615,7 +1615,6 @@
|
|
|
1615
1615
|
});
|
|
1616
1616
|
AssemblySpecificChange$3.AssemblySpecificChange = void 0;
|
|
1617
1617
|
AssemblySpecificChange$3.isAssemblySpecificChange = isAssemblySpecificChange$1;
|
|
1618
|
-
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
1619
1618
|
var Change_1$1 = Change$3;
|
|
1620
1619
|
function isAssemblySpecificChange$1(
|
|
1621
1620
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -1632,7 +1631,37 @@
|
|
|
1632
1631
|
_this.assembly = json.assembly;
|
|
1633
1632
|
return _this;
|
|
1634
1633
|
}
|
|
1635
|
-
|
|
1634
|
+
_createClass(AssemblySpecificChange, [{
|
|
1635
|
+
key: "getIndexedIds",
|
|
1636
|
+
value: function getIndexedIds(feature, idsToIndex) {
|
|
1637
|
+
var _a;
|
|
1638
|
+
var indexedIds = [];
|
|
1639
|
+
var _iterator = _createForOfIteratorHelper(idsToIndex !== null && idsToIndex !== void 0 ? idsToIndex : []),
|
|
1640
|
+
_step;
|
|
1641
|
+
try {
|
|
1642
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
1643
|
+
var additionalId = _step.value;
|
|
1644
|
+
var idValue = (_a = feature.attributes) === null || _a === void 0 ? void 0 : _a[additionalId];
|
|
1645
|
+
if (idValue) {
|
|
1646
|
+
indexedIds.push(idValue[0]);
|
|
1647
|
+
}
|
|
1648
|
+
}
|
|
1649
|
+
} catch (err) {
|
|
1650
|
+
_iterator.e(err);
|
|
1651
|
+
} finally {
|
|
1652
|
+
_iterator.f();
|
|
1653
|
+
}
|
|
1654
|
+
if (feature.children) {
|
|
1655
|
+
for (var _i = 0, _Object$values = Object.values(feature.children); _i < _Object$values.length; _i++) {
|
|
1656
|
+
var child = _Object$values[_i];
|
|
1657
|
+
var childIndexedIds = this.getIndexedIds(child, idsToIndex);
|
|
1658
|
+
indexedIds.push.apply(indexedIds, _toConsumableArray(childIndexedIds));
|
|
1659
|
+
}
|
|
1660
|
+
}
|
|
1661
|
+
return indexedIds;
|
|
1662
|
+
}
|
|
1663
|
+
}]);
|
|
1664
|
+
return AssemblySpecificChange;
|
|
1636
1665
|
}(Change_1$1.Change);
|
|
1637
1666
|
AssemblySpecificChange$3.AssemblySpecificChange = AssemblySpecificChange$2;
|
|
1638
1667
|
|
|
@@ -4706,7 +4735,6 @@
|
|
|
4706
4735
|
});
|
|
4707
4736
|
AssemblySpecificChange$1.AssemblySpecificChange = void 0;
|
|
4708
4737
|
AssemblySpecificChange$1.isAssemblySpecificChange = isAssemblySpecificChange;
|
|
4709
|
-
/* eslint-disable @typescript-eslint/no-unnecessary-condition */
|
|
4710
4738
|
var Change_1 = Change$1;
|
|
4711
4739
|
function isAssemblySpecificChange(
|
|
4712
4740
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
@@ -4723,7 +4751,37 @@
|
|
|
4723
4751
|
_this.assembly = json.assembly;
|
|
4724
4752
|
return _this;
|
|
4725
4753
|
}
|
|
4726
|
-
|
|
4754
|
+
_createClass(AssemblySpecificChange, [{
|
|
4755
|
+
key: "getIndexedIds",
|
|
4756
|
+
value: function getIndexedIds(feature, idsToIndex) {
|
|
4757
|
+
var _a;
|
|
4758
|
+
var indexedIds = [];
|
|
4759
|
+
var _iterator = _createForOfIteratorHelper(idsToIndex !== null && idsToIndex !== void 0 ? idsToIndex : []),
|
|
4760
|
+
_step;
|
|
4761
|
+
try {
|
|
4762
|
+
for (_iterator.s(); !(_step = _iterator.n()).done;) {
|
|
4763
|
+
var additionalId = _step.value;
|
|
4764
|
+
var idValue = (_a = feature.attributes) === null || _a === void 0 ? void 0 : _a[additionalId];
|
|
4765
|
+
if (idValue) {
|
|
4766
|
+
indexedIds.push(idValue[0]);
|
|
4767
|
+
}
|
|
4768
|
+
}
|
|
4769
|
+
} catch (err) {
|
|
4770
|
+
_iterator.e(err);
|
|
4771
|
+
} finally {
|
|
4772
|
+
_iterator.f();
|
|
4773
|
+
}
|
|
4774
|
+
if (feature.children) {
|
|
4775
|
+
for (var _i = 0, _Object$values = Object.values(feature.children); _i < _Object$values.length; _i++) {
|
|
4776
|
+
var child = _Object$values[_i];
|
|
4777
|
+
var childIndexedIds = this.getIndexedIds(child, idsToIndex);
|
|
4778
|
+
indexedIds.push.apply(indexedIds, _toConsumableArray(childIndexedIds));
|
|
4779
|
+
}
|
|
4780
|
+
}
|
|
4781
|
+
return indexedIds;
|
|
4782
|
+
}
|
|
4783
|
+
}]);
|
|
4784
|
+
return AssemblySpecificChange;
|
|
4727
4785
|
}(Change_1.Change);
|
|
4728
4786
|
AssemblySpecificChange$1.AssemblySpecificChange = AssemblySpecificChange;
|
|
4729
4787
|
|
|
@@ -5626,7 +5684,7 @@
|
|
|
5626
5684
|
var util_1$9 = require$$1__default$1["default"];
|
|
5627
5685
|
var bson_objectid_1$2 = /*#__PURE__*/tslib_1$4.__importDefault(objectid);
|
|
5628
5686
|
var gffReservedKeys_1 = gffReservedKeys;
|
|
5629
|
-
function gff3ToAnnotationFeature(gff3Feature, refSeq
|
|
5687
|
+
function gff3ToAnnotationFeature(gff3Feature, refSeq) {
|
|
5630
5688
|
var _gff3Feature = _slicedToArray(gff3Feature, 1),
|
|
5631
5689
|
firstFeature = _gff3Feature[0];
|
|
5632
5690
|
var end = firstFeature.end,
|
|
@@ -5650,7 +5708,7 @@
|
|
|
5650
5708
|
_getFeatureMinMax2 = _slicedToArray(_getFeatureMinMax, 2),
|
|
5651
5709
|
min = _getFeatureMinMax2[0],
|
|
5652
5710
|
max = _getFeatureMinMax2[1];
|
|
5653
|
-
var convertedChildren = convertChildren(gff3Feature, refSeq
|
|
5711
|
+
var convertedChildren = convertChildren(gff3Feature, refSeq);
|
|
5654
5712
|
var convertedAttributes = convertFeatureAttributes$1(gff3Feature);
|
|
5655
5713
|
var feature = {
|
|
5656
5714
|
_id: new bson_objectid_1$2["default"]().toHexString(),
|
|
@@ -5674,9 +5732,6 @@
|
|
|
5674
5732
|
if (convertedAttributes) {
|
|
5675
5733
|
feature.attributes = convertedAttributes;
|
|
5676
5734
|
}
|
|
5677
|
-
if (featureIds) {
|
|
5678
|
-
featureIds.push(feature._id);
|
|
5679
|
-
}
|
|
5680
5735
|
return feature;
|
|
5681
5736
|
}
|
|
5682
5737
|
function getFeatureMinMax(gff3Feature) {
|
|
@@ -5810,7 +5865,7 @@
|
|
|
5810
5865
|
if (firstChildFeatureLocation.type === 'CDS') {
|
|
5811
5866
|
cdsFeatures.push(childFeature);
|
|
5812
5867
|
} else {
|
|
5813
|
-
var child = gff3ToAnnotationFeature(childFeature, refSeq
|
|
5868
|
+
var child = gff3ToAnnotationFeature(childFeature, refSeq);
|
|
5814
5869
|
convertedChildren[child._id] = child;
|
|
5815
5870
|
}
|
|
5816
5871
|
}
|
|
@@ -5820,7 +5875,7 @@
|
|
|
5820
5875
|
_iterator2.f();
|
|
5821
5876
|
}
|
|
5822
5877
|
if (cdsFeatures.length > 0) {
|
|
5823
|
-
var processedCDS = processCDS(cdsFeatures, refSeq
|
|
5878
|
+
var processedCDS = processCDS(cdsFeatures, refSeq);
|
|
5824
5879
|
var _iterator3 = _createForOfIteratorHelper(processedCDS),
|
|
5825
5880
|
_step3;
|
|
5826
5881
|
try {
|
|
@@ -6052,7 +6107,7 @@
|
|
|
6052
6107
|
* should be represented in our internal structure
|
|
6053
6108
|
* @param cdsFeatures -
|
|
6054
6109
|
*/
|
|
6055
|
-
function processCDS(cdsFeatures, refSeq
|
|
6110
|
+
function processCDS(cdsFeatures, refSeq) {
|
|
6056
6111
|
var locationCounts = cdsFeatures.map(function (cds) {
|
|
6057
6112
|
return cds.length;
|
|
6058
6113
|
});
|
|
@@ -6063,7 +6118,7 @@
|
|
|
6063
6118
|
return count > 1;
|
|
6064
6119
|
})) {
|
|
6065
6120
|
return cdsFeatures.map(function (cds) {
|
|
6066
|
-
return gff3ToAnnotationFeature(cds, refSeq
|
|
6121
|
+
return gff3ToAnnotationFeature(cds, refSeq);
|
|
6067
6122
|
});
|
|
6068
6123
|
}
|
|
6069
6124
|
// If all CDS have a single location, we guess that this GFF3 represented CDS
|
|
@@ -6089,7 +6144,7 @@
|
|
|
6089
6144
|
});
|
|
6090
6145
|
// If no overlaps, assume it's a single CDS feature
|
|
6091
6146
|
if (!overlapping) {
|
|
6092
|
-
return [gff3ToAnnotationFeature(sortedCDSLocations, refSeq
|
|
6147
|
+
return [gff3ToAnnotationFeature(sortedCDSLocations, refSeq)];
|
|
6093
6148
|
}
|
|
6094
6149
|
// Some CDS locations overlap, the best we can do is use the original order to
|
|
6095
6150
|
// guess how to group the locations into features
|
|
@@ -6126,7 +6181,7 @@
|
|
|
6126
6181
|
_iterator12.f();
|
|
6127
6182
|
}
|
|
6128
6183
|
return groupedLocations.map(function (group) {
|
|
6129
|
-
return gff3ToAnnotationFeature(group, refSeq
|
|
6184
|
+
return gff3ToAnnotationFeature(group, refSeq);
|
|
6130
6185
|
});
|
|
6131
6186
|
}
|
|
6132
6187
|
|
|
@@ -6486,71 +6541,76 @@
|
|
|
6486
6541
|
key: "addFeatureIntoDb",
|
|
6487
6542
|
value: function () {
|
|
6488
6543
|
var _addFeatureIntoDb = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee3(gff3Feature, backend) {
|
|
6489
|
-
var
|
|
6544
|
+
var INDEXED_IDS, idsToIndex, assembly, refSeqCache, featureModel, refSeqModel, user, _gff3Feature, refName, refSeqDoc, _yield$refSeqModel$fi, newFeature, allIds, indexedIds;
|
|
6490
6545
|
return _regeneratorRuntime().wrap(function _callee3$(_context3) {
|
|
6491
6546
|
while (1) switch (_context3.prev = _context3.next) {
|
|
6492
6547
|
case 0:
|
|
6493
|
-
|
|
6548
|
+
INDEXED_IDS = browser$1.env.INDEXED_IDS;
|
|
6549
|
+
if (INDEXED_IDS) {
|
|
6550
|
+
idsToIndex = INDEXED_IDS.split(',');
|
|
6551
|
+
}
|
|
6494
6552
|
assembly = this.assembly, refSeqCache = this.refSeqCache;
|
|
6553
|
+
featureModel = backend.featureModel, refSeqModel = backend.refSeqModel, user = backend.user;
|
|
6495
6554
|
_gff3Feature = _slicedToArray(gff3Feature, 1), refName = _gff3Feature[0].seq_id;
|
|
6496
6555
|
if (refName) {
|
|
6497
|
-
_context3.next =
|
|
6556
|
+
_context3.next = 7;
|
|
6498
6557
|
break;
|
|
6499
6558
|
}
|
|
6500
6559
|
throw new Error("Valid seq_id not found in feature ".concat(JSON.stringify(gff3Feature)));
|
|
6501
|
-
case
|
|
6560
|
+
case 7:
|
|
6502
6561
|
refSeqDoc = refSeqCache.get(refName);
|
|
6503
6562
|
if (refSeqDoc) {
|
|
6504
|
-
_context3.next =
|
|
6563
|
+
_context3.next = 22;
|
|
6505
6564
|
break;
|
|
6506
6565
|
}
|
|
6507
|
-
_context3.next =
|
|
6566
|
+
_context3.next = 11;
|
|
6508
6567
|
return refSeqModel.findOne({
|
|
6509
6568
|
assembly: assembly,
|
|
6510
6569
|
name: refName
|
|
6511
6570
|
}).exec();
|
|
6512
|
-
case
|
|
6571
|
+
case 11:
|
|
6513
6572
|
_context3.t1 = _yield$refSeqModel$fi = _context3.sent;
|
|
6514
6573
|
_context3.t0 = _context3.t1 !== null;
|
|
6515
6574
|
if (!_context3.t0) {
|
|
6516
|
-
_context3.next =
|
|
6575
|
+
_context3.next = 15;
|
|
6517
6576
|
break;
|
|
6518
6577
|
}
|
|
6519
6578
|
_context3.t0 = _yield$refSeqModel$fi !== void 0;
|
|
6520
|
-
case
|
|
6579
|
+
case 15:
|
|
6521
6580
|
if (!_context3.t0) {
|
|
6522
|
-
_context3.next =
|
|
6581
|
+
_context3.next = 19;
|
|
6523
6582
|
break;
|
|
6524
6583
|
}
|
|
6525
6584
|
_context3.t2 = _yield$refSeqModel$fi;
|
|
6526
|
-
_context3.next =
|
|
6585
|
+
_context3.next = 20;
|
|
6527
6586
|
break;
|
|
6528
|
-
case
|
|
6587
|
+
case 19:
|
|
6529
6588
|
_context3.t2 = undefined;
|
|
6530
|
-
case
|
|
6589
|
+
case 20:
|
|
6531
6590
|
refSeqDoc = _context3.t2;
|
|
6532
6591
|
if (refSeqDoc) {
|
|
6533
6592
|
refSeqCache.set(refName, refSeqDoc);
|
|
6534
6593
|
}
|
|
6535
|
-
case
|
|
6594
|
+
case 22:
|
|
6536
6595
|
if (refSeqDoc) {
|
|
6537
|
-
_context3.next =
|
|
6596
|
+
_context3.next = 24;
|
|
6538
6597
|
break;
|
|
6539
6598
|
}
|
|
6540
6599
|
throw new Error("RefSeq was not found by assembly \"".concat(assembly, "\" and seq_id \"").concat(refName, "\" not found"));
|
|
6541
|
-
case
|
|
6542
|
-
|
|
6543
|
-
|
|
6544
|
-
|
|
6600
|
+
case 24:
|
|
6601
|
+
newFeature = (0, GFF3_1.gff3ToAnnotationFeature)(gff3Feature, refSeqDoc._id);
|
|
6602
|
+
allIds = this.getAllIds(newFeature);
|
|
6603
|
+
indexedIds = this.getIndexedIds(newFeature, idsToIndex); // Add into Mongo
|
|
6545
6604
|
// We cannot use Mongo 'session' / transaction here because Mongo has 16 MB limit for transaction
|
|
6546
|
-
_context3.next =
|
|
6605
|
+
_context3.next = 29;
|
|
6547
6606
|
return featureModel.create([_objectSpread2(_objectSpread2({
|
|
6548
|
-
allIds:
|
|
6607
|
+
allIds: allIds,
|
|
6608
|
+
indexedIds: indexedIds
|
|
6549
6609
|
}, newFeature), {}, {
|
|
6550
6610
|
user: user,
|
|
6551
6611
|
status: -1
|
|
6552
6612
|
})]);
|
|
6553
|
-
case
|
|
6613
|
+
case 29:
|
|
6554
6614
|
case "end":
|
|
6555
6615
|
return _context3.stop();
|
|
6556
6616
|
}
|
|
@@ -6561,6 +6621,19 @@
|
|
|
6561
6621
|
}
|
|
6562
6622
|
return addFeatureIntoDb;
|
|
6563
6623
|
}()
|
|
6624
|
+
}, {
|
|
6625
|
+
key: "getAllIds",
|
|
6626
|
+
value: function getAllIds(feature) {
|
|
6627
|
+
var allIds = [feature._id];
|
|
6628
|
+
if (feature.children) {
|
|
6629
|
+
for (var _i = 0, _Object$values = Object.values(feature.children); _i < _Object$values.length; _i++) {
|
|
6630
|
+
var child = _Object$values[_i];
|
|
6631
|
+
var childIds = this.getAllIds(child);
|
|
6632
|
+
allIds.push.apply(allIds, _toConsumableArray(childIds));
|
|
6633
|
+
}
|
|
6634
|
+
}
|
|
6635
|
+
return allIds;
|
|
6636
|
+
}
|
|
6564
6637
|
}]);
|
|
6565
6638
|
return FromFileBaseChange;
|
|
6566
6639
|
}(common_1$n.AssemblySpecificChange);
|
|
@@ -17288,7 +17361,7 @@
|
|
|
17288
17361
|
value: function () {
|
|
17289
17362
|
var _executeOnServer = /*#__PURE__*/_asyncToGenerator( /*#__PURE__*/_regeneratorRuntime().mark(function _callee(backend) {
|
|
17290
17363
|
var _logger$debug, _logger$debug2;
|
|
17291
|
-
var assemblyModel, featureModel, refSeqModel, session, user, assembly, changes, logger, assemblyDoc, errMsg, featureCnt, _iterator, _step, _logger$debug3, change, addedFeature, allIds, copyFeature, parentFeatureId, _id, refSeq, refSeqDoc, _logger$debug4, _yield$featureModel$c, _yield$featureModel$c2, newFeatureDoc, _topLevelFeature$allI, topLevelFeature, parentFeature, childIds, _logger$verbose, _childIds, allIdsV2, _yield$featureModel$c3, _yield$featureModel$c4, _newFeatureDoc;
|
|
17364
|
+
var assemblyModel, featureModel, refSeqModel, session, user, assembly, changes, logger, assemblyDoc, errMsg, featureCnt, INDEXED_IDS, idsToIndex, _iterator, _step, _logger$debug3, change, addedFeature, allIds, copyFeature, parentFeatureId, _id, refSeq, refSeqDoc, _logger$debug4, indexedIds, _yield$featureModel$c, _yield$featureModel$c2, newFeatureDoc, _topLevelFeature$allI, topLevelFeature, parentFeature, childIds, _logger$verbose, _childIds, allIdsV2, _indexedIds, _yield$featureModel$c3, _yield$featureModel$c4, _newFeatureDoc;
|
|
17292
17365
|
return _regeneratorRuntime().wrap(function _callee$(_context) {
|
|
17293
17366
|
while (1) switch (_context.prev = _context.next) {
|
|
17294
17367
|
case 0:
|
|
@@ -17308,119 +17381,127 @@
|
|
|
17308
17381
|
case 9:
|
|
17309
17382
|
featureCnt = 0;
|
|
17310
17383
|
(_logger$debug = logger.debug) === null || _logger$debug === void 0 || _logger$debug.call(logger, "changes: ".concat(JSON.stringify(changes)));
|
|
17384
|
+
INDEXED_IDS = browser$1.env.INDEXED_IDS;
|
|
17385
|
+
if (INDEXED_IDS) {
|
|
17386
|
+
idsToIndex = INDEXED_IDS.split(',');
|
|
17387
|
+
}
|
|
17311
17388
|
// Loop the changes
|
|
17312
17389
|
_iterator = _createForOfIteratorHelper(changes);
|
|
17313
|
-
_context.prev =
|
|
17390
|
+
_context.prev = 14;
|
|
17314
17391
|
_iterator.s();
|
|
17315
|
-
case
|
|
17392
|
+
case 16:
|
|
17316
17393
|
if ((_step = _iterator.n()).done) {
|
|
17317
|
-
_context.next =
|
|
17394
|
+
_context.next = 65;
|
|
17318
17395
|
break;
|
|
17319
17396
|
}
|
|
17320
17397
|
change = _step.value;
|
|
17321
17398
|
(_logger$debug3 = logger.debug) === null || _logger$debug3 === void 0 || _logger$debug3.call(logger, "change: ".concat(JSON.stringify(change)));
|
|
17322
17399
|
addedFeature = change.addedFeature, allIds = change.allIds, copyFeature = change.copyFeature, parentFeatureId = change.parentFeatureId;
|
|
17323
17400
|
_id = addedFeature._id, refSeq = addedFeature.refSeq;
|
|
17324
|
-
_context.next =
|
|
17401
|
+
_context.next = 23;
|
|
17325
17402
|
return refSeqModel.findById(refSeq).session(session).exec();
|
|
17326
|
-
case
|
|
17403
|
+
case 23:
|
|
17327
17404
|
refSeqDoc = _context.sent;
|
|
17328
17405
|
if (refSeqDoc) {
|
|
17329
|
-
_context.next =
|
|
17406
|
+
_context.next = 26;
|
|
17330
17407
|
break;
|
|
17331
17408
|
}
|
|
17332
17409
|
throw new Error("RefSeq was not found by assembly \"".concat(assembly, "\" and seq_id \"").concat(refSeq, "\" not found"));
|
|
17333
|
-
case
|
|
17410
|
+
case 26:
|
|
17334
17411
|
if (!copyFeature) {
|
|
17335
|
-
_context.next =
|
|
17412
|
+
_context.next = 37;
|
|
17336
17413
|
break;
|
|
17337
17414
|
}
|
|
17338
|
-
|
|
17415
|
+
indexedIds = this.getIndexedIds(addedFeature, idsToIndex); // Add into Mongo
|
|
17416
|
+
_context.next = 30;
|
|
17339
17417
|
return featureModel.create([_objectSpread2(_objectSpread2({}, addedFeature), {}, {
|
|
17340
17418
|
allIds: allIds,
|
|
17419
|
+
indexedIds: indexedIds,
|
|
17341
17420
|
status: -1,
|
|
17342
17421
|
user: user
|
|
17343
17422
|
})], {
|
|
17344
17423
|
session: session
|
|
17345
17424
|
});
|
|
17346
|
-
case
|
|
17425
|
+
case 30:
|
|
17347
17426
|
_yield$featureModel$c = _context.sent;
|
|
17348
17427
|
_yield$featureModel$c2 = _slicedToArray(_yield$featureModel$c, 1);
|
|
17349
17428
|
newFeatureDoc = _yield$featureModel$c2[0];
|
|
17350
17429
|
(_logger$debug4 = logger.debug) === null || _logger$debug4 === void 0 || _logger$debug4.call(logger, "Copied feature, docId \"".concat(newFeatureDoc._id, "\" to assembly \"").concat(assembly, "\""));
|
|
17351
17430
|
featureCnt++;
|
|
17352
|
-
_context.next =
|
|
17431
|
+
_context.next = 62;
|
|
17353
17432
|
break;
|
|
17354
|
-
case
|
|
17433
|
+
case 37:
|
|
17355
17434
|
if (!parentFeatureId) {
|
|
17356
|
-
_context.next =
|
|
17435
|
+
_context.next = 53;
|
|
17357
17436
|
break;
|
|
17358
17437
|
}
|
|
17359
|
-
_context.next =
|
|
17438
|
+
_context.next = 40;
|
|
17360
17439
|
return featureModel.findOne({
|
|
17361
17440
|
allIds: parentFeatureId
|
|
17362
17441
|
}).session(session).exec();
|
|
17363
|
-
case
|
|
17442
|
+
case 40:
|
|
17364
17443
|
topLevelFeature = _context.sent;
|
|
17365
17444
|
if (topLevelFeature) {
|
|
17366
|
-
_context.next =
|
|
17445
|
+
_context.next = 43;
|
|
17367
17446
|
break;
|
|
17368
17447
|
}
|
|
17369
17448
|
throw new Error("Could not find feature with ID \"".concat(parentFeatureId, "\""));
|
|
17370
|
-
case
|
|
17449
|
+
case 43:
|
|
17371
17450
|
parentFeature = this.getFeatureFromId(topLevelFeature, parentFeatureId);
|
|
17372
17451
|
if (parentFeature) {
|
|
17373
|
-
_context.next =
|
|
17452
|
+
_context.next = 46;
|
|
17374
17453
|
break;
|
|
17375
17454
|
}
|
|
17376
17455
|
throw new Error("Could not find feature with ID \"".concat(parentFeatureId, "\" in feature \"").concat(topLevelFeature._id, "\""));
|
|
17377
|
-
case
|
|
17456
|
+
case 46:
|
|
17378
17457
|
this.addChild(parentFeature, addedFeature);
|
|
17379
17458
|
childIds = this.getChildFeatureIds(addedFeature);
|
|
17380
17459
|
(_topLevelFeature$allI = topLevelFeature.allIds).push.apply(_topLevelFeature$allI, [_id].concat(_toConsumableArray(childIds)));
|
|
17381
|
-
_context.next =
|
|
17460
|
+
_context.next = 51;
|
|
17382
17461
|
return topLevelFeature.save();
|
|
17383
|
-
case
|
|
17384
|
-
_context.next =
|
|
17462
|
+
case 51:
|
|
17463
|
+
_context.next = 62;
|
|
17385
17464
|
break;
|
|
17386
|
-
case
|
|
17465
|
+
case 53:
|
|
17387
17466
|
_childIds = this.getChildFeatureIds(addedFeature);
|
|
17388
17467
|
allIdsV2 = [_id].concat(_toConsumableArray(_childIds));
|
|
17389
|
-
|
|
17468
|
+
_indexedIds = this.getIndexedIds(addedFeature, idsToIndex);
|
|
17469
|
+
_context.next = 58;
|
|
17390
17470
|
return featureModel.create([_objectSpread2({
|
|
17391
17471
|
allIds: allIdsV2,
|
|
17472
|
+
indexedIds: _indexedIds,
|
|
17392
17473
|
status: 0
|
|
17393
17474
|
}, addedFeature)], {
|
|
17394
17475
|
session: session
|
|
17395
17476
|
});
|
|
17396
|
-
case
|
|
17477
|
+
case 58:
|
|
17397
17478
|
_yield$featureModel$c3 = _context.sent;
|
|
17398
17479
|
_yield$featureModel$c4 = _slicedToArray(_yield$featureModel$c3, 1);
|
|
17399
17480
|
_newFeatureDoc = _yield$featureModel$c4[0];
|
|
17400
17481
|
(_logger$verbose = logger.verbose) === null || _logger$verbose === void 0 || _logger$verbose.call(logger, "Added docId \"".concat(_newFeatureDoc._id, "\""));
|
|
17401
|
-
case
|
|
17482
|
+
case 62:
|
|
17402
17483
|
featureCnt++;
|
|
17403
|
-
case
|
|
17404
|
-
_context.next =
|
|
17484
|
+
case 63:
|
|
17485
|
+
_context.next = 16;
|
|
17405
17486
|
break;
|
|
17406
|
-
case
|
|
17407
|
-
_context.next =
|
|
17487
|
+
case 65:
|
|
17488
|
+
_context.next = 70;
|
|
17408
17489
|
break;
|
|
17409
|
-
case
|
|
17410
|
-
_context.prev =
|
|
17411
|
-
_context.t0 = _context["catch"](
|
|
17490
|
+
case 67:
|
|
17491
|
+
_context.prev = 67;
|
|
17492
|
+
_context.t0 = _context["catch"](14);
|
|
17412
17493
|
_iterator.e(_context.t0);
|
|
17413
|
-
case
|
|
17414
|
-
_context.prev =
|
|
17494
|
+
case 70:
|
|
17495
|
+
_context.prev = 70;
|
|
17415
17496
|
_iterator.f();
|
|
17416
|
-
return _context.finish(
|
|
17417
|
-
case
|
|
17497
|
+
return _context.finish(70);
|
|
17498
|
+
case 73:
|
|
17418
17499
|
(_logger$debug2 = logger.debug) === null || _logger$debug2 === void 0 || _logger$debug2.call(logger, "Added ".concat(featureCnt, " new feature(s) into database."));
|
|
17419
|
-
case
|
|
17500
|
+
case 74:
|
|
17420
17501
|
case "end":
|
|
17421
17502
|
return _context.stop();
|
|
17422
17503
|
}
|
|
17423
|
-
}, _callee, this, [[
|
|
17504
|
+
}, _callee, this, [[14, 67, 70, 73]]);
|
|
17424
17505
|
}));
|
|
17425
17506
|
function executeOnServer(_x) {
|
|
17426
17507
|
return _executeOnServer.apply(this, arguments);
|
|
@@ -23804,7 +23885,7 @@
|
|
|
23804
23885
|
d: "M19 13h-6v6h-2v-6H5v-2h6V5h2v6h6z"
|
|
23805
23886
|
}), 'Add');
|
|
23806
23887
|
|
|
23807
|
-
var version = "0.3.
|
|
23888
|
+
var version = "0.3.10";
|
|
23808
23889
|
|
|
23809
23890
|
const ApolloConfigSchema = configuration.ConfigurationSchema('ApolloInternetAccount', {
|
|
23810
23891
|
baseURL: {
|
|
@@ -29343,6 +29424,19 @@
|
|
|
29343
29424
|
]);
|
|
29344
29425
|
},
|
|
29345
29426
|
});
|
|
29427
|
+
if (require$$1$2.isSessionModelWithWidgets(session)) {
|
|
29428
|
+
menuItems.push({
|
|
29429
|
+
label: 'Open feature details',
|
|
29430
|
+
onClick: () => {
|
|
29431
|
+
const apolloGeneWidget = session.addWidget('ApolloFeatureDetailsWidget', 'apolloFeatureDetailsWidget', {
|
|
29432
|
+
feature: sourceFeature,
|
|
29433
|
+
assembly: currentAssemblyId,
|
|
29434
|
+
refName: region.refName,
|
|
29435
|
+
});
|
|
29436
|
+
session.showWidget(apolloGeneWidget);
|
|
29437
|
+
},
|
|
29438
|
+
});
|
|
29439
|
+
}
|
|
29346
29440
|
return menuItems;
|
|
29347
29441
|
}
|
|
29348
29442
|
function navToFeatureCenter(feature, paddingPct, refSeqLength) {
|
|
@@ -29595,7 +29689,7 @@
|
|
|
29595
29689
|
statusMessage: 'Pre-validating',
|
|
29596
29690
|
progressPct: 0,
|
|
29597
29691
|
cancelCallback: () => {
|
|
29598
|
-
controller.abort();
|
|
29692
|
+
controller.abort('AddAssembly');
|
|
29599
29693
|
jobsManager.abortJob(job.name);
|
|
29600
29694
|
},
|
|
29601
29695
|
};
|
|
@@ -47874,7 +47968,7 @@
|
|
|
47874
47968
|
});
|
|
47875
47969
|
}
|
|
47876
47970
|
return () => {
|
|
47877
|
-
controller.abort();
|
|
47971
|
+
controller.abort('OntologyTermAutocomplete matcher');
|
|
47878
47972
|
};
|
|
47879
47973
|
}, [session, valueString, filterTerms, ontologyStore, needToLoadCurrentTerm]);
|
|
47880
47974
|
// effect for loading term autocompletions
|
|
@@ -47893,7 +47987,7 @@
|
|
|
47893
47987
|
});
|
|
47894
47988
|
}
|
|
47895
47989
|
return () => {
|
|
47896
|
-
controller.abort();
|
|
47990
|
+
controller.abort('OntologyTermAutocomplete loader');
|
|
47897
47991
|
};
|
|
47898
47992
|
}, [
|
|
47899
47993
|
needToLoadTermChoices,
|
|
@@ -48045,17 +48139,24 @@
|
|
|
48045
48139
|
// pre-validate
|
|
48046
48140
|
const session = require$$1$2.getSession(this.dataStore);
|
|
48047
48141
|
const controller = new AbortController();
|
|
48048
|
-
|
|
48142
|
+
// eslint-disable-next-line @typescript-eslint/unbound-method
|
|
48143
|
+
const { jobsManager, isLocked, changeInProgress, setChangeInProgress } = require$$1$2.getSession(this.dataStore);
|
|
48049
48144
|
if (isLocked) {
|
|
48050
48145
|
session.notify('Cannot submit changes in locked mode');
|
|
48146
|
+
setChangeInProgress(false);
|
|
48147
|
+
return;
|
|
48148
|
+
}
|
|
48149
|
+
if (changeInProgress) {
|
|
48150
|
+
session.notify('Could not submit change, there is another change still in progress');
|
|
48051
48151
|
return;
|
|
48052
48152
|
}
|
|
48153
|
+
setChangeInProgress(true);
|
|
48053
48154
|
const job = {
|
|
48054
48155
|
name: change.typeName,
|
|
48055
48156
|
statusMessage: 'Pre-validating',
|
|
48056
48157
|
progressPct: 0,
|
|
48057
48158
|
cancelCallback: () => {
|
|
48058
|
-
controller.abort();
|
|
48159
|
+
controller.abort('ChangeManager');
|
|
48059
48160
|
},
|
|
48060
48161
|
};
|
|
48061
48162
|
if (updateJobsManager) {
|
|
@@ -48068,6 +48169,7 @@
|
|
|
48068
48169
|
jobsManager.abortJob(job.name, msg);
|
|
48069
48170
|
}
|
|
48070
48171
|
session.notify(msg, 'error');
|
|
48172
|
+
setChangeInProgress(false);
|
|
48071
48173
|
return;
|
|
48072
48174
|
}
|
|
48073
48175
|
try {
|
|
@@ -48080,6 +48182,7 @@
|
|
|
48080
48182
|
}
|
|
48081
48183
|
console.error(error);
|
|
48082
48184
|
session.notify(`Error encountered in client: ${String(error)}. Data may be out of sync, please refresh the page`, 'error');
|
|
48185
|
+
setChangeInProgress(false);
|
|
48083
48186
|
return;
|
|
48084
48187
|
}
|
|
48085
48188
|
// post-validate
|
|
@@ -48110,6 +48213,7 @@
|
|
|
48110
48213
|
console.error(error);
|
|
48111
48214
|
session.notify(String(error), 'error');
|
|
48112
48215
|
await this.undo(change, false);
|
|
48216
|
+
setChangeInProgress(false);
|
|
48113
48217
|
return;
|
|
48114
48218
|
}
|
|
48115
48219
|
if (!backendResult.ok) {
|
|
@@ -48119,6 +48223,7 @@
|
|
|
48119
48223
|
}
|
|
48120
48224
|
session.notify(msg, 'error');
|
|
48121
48225
|
await this.undo(change, false);
|
|
48226
|
+
setChangeInProgress(false);
|
|
48122
48227
|
return;
|
|
48123
48228
|
}
|
|
48124
48229
|
if (change.notification) {
|
|
@@ -48132,6 +48237,7 @@
|
|
|
48132
48237
|
if (updateJobsManager) {
|
|
48133
48238
|
jobsManager.done(job);
|
|
48134
48239
|
}
|
|
48240
|
+
setChangeInProgress(false);
|
|
48135
48241
|
}
|
|
48136
48242
|
async undo(change, submitToBackend = true) {
|
|
48137
48243
|
const inverseChange = change.getInverse();
|
|
@@ -48237,17 +48343,22 @@
|
|
|
48237
48343
|
checkSocket(assembly, refSeq, internetAccount) {
|
|
48238
48344
|
const { socket } = internetAccount;
|
|
48239
48345
|
const token = internetAccount.retrieveToken();
|
|
48346
|
+
if (!token) {
|
|
48347
|
+
return;
|
|
48348
|
+
}
|
|
48349
|
+
const localSessionId = dist$2.makeUserSessionId(token);
|
|
48240
48350
|
const channel = `${assembly}-${refSeq}`;
|
|
48241
48351
|
const changeManager = new ChangeManager(this.clientStore);
|
|
48242
48352
|
if (!socket.hasListeners(channel)) {
|
|
48243
48353
|
socket.on(channel, async (message) => {
|
|
48244
48354
|
// Save server last change sequence into session storage
|
|
48245
48355
|
internetAccount.setLastChangeSequenceNumber(Number(message.changeSequence));
|
|
48246
|
-
if (message.userSessionId
|
|
48247
|
-
|
|
48248
|
-
|
|
48249
|
-
|
|
48250
|
-
|
|
48356
|
+
if (message.userSessionId === localSessionId) {
|
|
48357
|
+
return; // we did this change, no need to apply it again
|
|
48358
|
+
}
|
|
48359
|
+
const change = dist$3.Change.fromJSON(message.changeInfo);
|
|
48360
|
+
if (dist$3.isFeatureChange(change) && this.haveDataForChange(change)) {
|
|
48361
|
+
await changeManager.submit(change, { submitToBackend: false });
|
|
48251
48362
|
}
|
|
48252
48363
|
});
|
|
48253
48364
|
}
|
|
@@ -49740,7 +49851,7 @@
|
|
|
49740
49851
|
statusMessage: 'Uploading file, this may take awhile',
|
|
49741
49852
|
progressPct: 0,
|
|
49742
49853
|
cancelCallback: () => {
|
|
49743
|
-
controller.abort();
|
|
49854
|
+
controller.abort('ImportFeatures');
|
|
49744
49855
|
jobsManager.abortJob(job.name);
|
|
49745
49856
|
},
|
|
49746
49857
|
};
|
|
@@ -50991,7 +51102,7 @@
|
|
|
50991
51102
|
}
|
|
50992
51103
|
});
|
|
50993
51104
|
return () => {
|
|
50994
|
-
controller.abort();
|
|
51105
|
+
controller.abort('AuthTypeSelector');
|
|
50995
51106
|
};
|
|
50996
51107
|
}, [baseURL]);
|
|
50997
51108
|
function handleClick(authType) {
|
|
@@ -51428,8 +51539,13 @@
|
|
|
51428
51539
|
return;
|
|
51429
51540
|
}
|
|
51430
51541
|
if (self.role) {
|
|
51431
|
-
|
|
51432
|
-
|
|
51542
|
+
try {
|
|
51543
|
+
await self.initialize(self.role);
|
|
51544
|
+
reaction.dispose();
|
|
51545
|
+
}
|
|
51546
|
+
catch {
|
|
51547
|
+
// if initialize fails, do nothing so the autorun runs again
|
|
51548
|
+
}
|
|
51433
51549
|
}
|
|
51434
51550
|
}, { name: 'ApolloInternetAccount' });
|
|
51435
51551
|
},
|
|
@@ -55579,6 +55695,7 @@
|
|
|
55579
55695
|
const refData = currentAssembly?.getByRefName(refName);
|
|
55580
55696
|
const { changeManager } = session.apolloDataStore;
|
|
55581
55697
|
const seqRef = React.useRef(null);
|
|
55698
|
+
const { changeInProgress } = session;
|
|
55582
55699
|
if (!refData) {
|
|
55583
55700
|
return null;
|
|
55584
55701
|
}
|
|
@@ -56026,10 +56143,13 @@
|
|
|
56026
56143
|
// highlight start codon and stop codons
|
|
56027
56144
|
if (codonSeq === 'ATG') {
|
|
56028
56145
|
elements.push(React__default["default"].createElement(material.Typography, { component: 'span', style: {
|
|
56029
|
-
backgroundColor: 'yellow',
|
|
56146
|
+
backgroundColor: changeInProgress ? 'lightgray' : 'yellow',
|
|
56030
56147
|
cursor: 'pointer',
|
|
56031
56148
|
border: '1px solid black',
|
|
56032
56149
|
}, key: codonGenomicPos, onClick: () => {
|
|
56150
|
+
if (changeInProgress) {
|
|
56151
|
+
return;
|
|
56152
|
+
}
|
|
56033
56153
|
// NOTE: codonGenomicPos is important here for calculating the genomic location
|
|
56034
56154
|
// of the start codon. We are using the codonGenomicPos as the key in the typography
|
|
56035
56155
|
// elements to maintain the genomic postion of the codon start
|
|
@@ -56113,20 +56233,21 @@
|
|
|
56113
56233
|
}
|
|
56114
56234
|
// Trim any sequence before first start codon and after stop codon
|
|
56115
56235
|
const startCodonIndex = translationSequence.indexOf('M');
|
|
56116
|
-
const stopCodonIndex = translationSequence.indexOf('*')
|
|
56236
|
+
const stopCodonIndex = translationSequence.indexOf('*');
|
|
56117
56237
|
const startCodonPos = translSeqCodonStartGenomicPosArr[startCodonIndex].codonGenomicPos;
|
|
56118
56238
|
const stopCodonPos = translSeqCodonStartGenomicPosArr[stopCodonIndex].codonGenomicPos;
|
|
56119
56239
|
if (!startCodonPos || !stopCodonPos) {
|
|
56120
56240
|
return;
|
|
56121
56241
|
}
|
|
56122
56242
|
const startCodonGenomicLoc = getCodonGenomicLocation(startCodonPos);
|
|
56123
|
-
|
|
56243
|
+
let stopCodonGenomicLoc = getCodonGenomicLocation(stopCodonPos);
|
|
56124
56244
|
if (strand === 1) {
|
|
56125
56245
|
if (startCodonGenomicLoc > stopCodonGenomicLoc) {
|
|
56126
56246
|
notify('Start codon genomic location should be less than stop codon genomic location', 'error');
|
|
56127
56247
|
return;
|
|
56128
56248
|
}
|
|
56129
56249
|
let promise;
|
|
56250
|
+
stopCodonGenomicLoc += 3; // move to end of stop codon
|
|
56130
56251
|
if (startCodonGenomicLoc !== cdsMin) {
|
|
56131
56252
|
promise = new Promise((resolve) => {
|
|
56132
56253
|
updateCDSLocation(cdsMin, startCodonGenomicLoc, feature, true, () => {
|
|
@@ -56152,6 +56273,7 @@
|
|
|
56152
56273
|
return;
|
|
56153
56274
|
}
|
|
56154
56275
|
let promise;
|
|
56276
|
+
stopCodonGenomicLoc -= 3; // move to end of stop codon
|
|
56155
56277
|
if (startCodonGenomicLoc !== cdsMax) {
|
|
56156
56278
|
promise = new Promise((resolve) => {
|
|
56157
56279
|
updateCDSLocation(cdsMax, startCodonGenomicLoc, feature, false, () => {
|
|
@@ -56195,27 +56317,29 @@
|
|
|
56195
56317
|
gap: 10,
|
|
56196
56318
|
} },
|
|
56197
56319
|
React__default["default"].createElement(material.Tooltip, { title: "Copy" },
|
|
56198
|
-
React__default["default"].createElement(
|
|
56320
|
+
React__default["default"].createElement("button", { onClick: onCopyClick, style: { border: 'none', background: 'none', padding: 0 }, disabled: changeInProgress },
|
|
56321
|
+
React__default["default"].createElement(ContentCopyIcon, { style: { fontSize: 15 } }))),
|
|
56199
56322
|
React__default["default"].createElement(material.Tooltip, { title: "Trim" },
|
|
56200
|
-
React__default["default"].createElement(
|
|
56323
|
+
React__default["default"].createElement("button", { onClick: trimTranslationSequence, style: { border: 'none', background: 'none', padding: 0 }, disabled: changeInProgress },
|
|
56324
|
+
React__default["default"].createElement(ContentCutIcon, { style: { fontSize: 15 } })))))),
|
|
56201
56325
|
React__default["default"].createElement(material.Grid, { container: true, justifyContent: "center", alignItems: "center", style: { textAlign: 'center', marginTop: 10 } },
|
|
56202
56326
|
React__default["default"].createElement(material.Grid, { size: 1 }),
|
|
56203
56327
|
strand === 1 ? (React__default["default"].createElement(material.Grid, { size: 4 },
|
|
56204
56328
|
React__default["default"].createElement(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMin + 1, onChangeCommitted: (newLocation) => {
|
|
56205
56329
|
return updateCDSLocation(cdsMin, newLocation - 1, feature, true);
|
|
56206
|
-
}, style: { border: '1px solid black', borderRadius: 5 } }))) : (React__default["default"].createElement(material.Grid, { size: 4 },
|
|
56330
|
+
}, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }))) : (React__default["default"].createElement(material.Grid, { size: 4 },
|
|
56207
56331
|
React__default["default"].createElement(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMax, onChangeCommitted: (newLocation) => {
|
|
56208
56332
|
return updateCDSLocation(cdsMax, newLocation, feature, false);
|
|
56209
|
-
}, style: { border: '1px solid black', borderRadius: 5 } }))),
|
|
56333
|
+
}, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }))),
|
|
56210
56334
|
React__default["default"].createElement(material.Grid, { size: 2 },
|
|
56211
56335
|
React__default["default"].createElement(material.Typography, { component: 'span' }, "CDS")),
|
|
56212
56336
|
strand === 1 ? (React__default["default"].createElement(material.Grid, { size: 4 },
|
|
56213
56337
|
React__default["default"].createElement(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMax, onChangeCommitted: (newLocation) => {
|
|
56214
56338
|
return updateCDSLocation(cdsMax, newLocation, feature, false);
|
|
56215
|
-
}, style: { border: '1px solid black', borderRadius: 5 } }))) : (React__default["default"].createElement(material.Grid, { size: 4 },
|
|
56339
|
+
}, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }))) : (React__default["default"].createElement(material.Grid, { size: 4 },
|
|
56216
56340
|
React__default["default"].createElement(StyledTextField, { margin: "dense", variant: "outlined", value: cdsMin + 1, onChangeCommitted: (newLocation) => {
|
|
56217
56341
|
return updateCDSLocation(cdsMin, newLocation - 1, feature, true);
|
|
56218
|
-
}, style: { border: '1px solid black', borderRadius: 5 } }))),
|
|
56342
|
+
}, style: { border: '1px solid black', borderRadius: 5 }, disabled: changeInProgress }))),
|
|
56219
56343
|
React__default["default"].createElement(material.Grid, { size: 1 })))),
|
|
56220
56344
|
React__default["default"].createElement("div", { style: { marginTop: 5 } }, transcriptExonParts.map((loc, index) => {
|
|
56221
56345
|
return (React__default["default"].createElement("div", { key: index }, loc.type === 'exon' && (React__default["default"].createElement(material.Grid, { container: true, justifyContent: "center", alignItems: "center", style: { textAlign: 'center' } },
|
|
@@ -56224,19 +56348,19 @@
|
|
|
56224
56348
|
strand === 1 ? (React__default["default"].createElement(material.Grid, { size: 4, style: { padding: 0 } },
|
|
56225
56349
|
React__default["default"].createElement(StyledTextField, { margin: "dense", variant: "outlined", value: loc.min + 1, onChangeCommitted: (newLocation) => {
|
|
56226
56350
|
return handleExonLocationChange(loc.min, newLocation - 1, feature, true);
|
|
56227
|
-
} }))) : (React__default["default"].createElement(material.Grid, { size: 4, style: { padding: 0 } },
|
|
56351
|
+
}, disabled: changeInProgress }))) : (React__default["default"].createElement(material.Grid, { size: 4, style: { padding: 0 } },
|
|
56228
56352
|
React__default["default"].createElement(StyledTextField, { margin: "dense", variant: "outlined", value: loc.max, onChangeCommitted: (newLocation) => {
|
|
56229
56353
|
return handleExonLocationChange(loc.max, newLocation, feature, false);
|
|
56230
|
-
} }))),
|
|
56354
|
+
}, disabled: changeInProgress }))),
|
|
56231
56355
|
React__default["default"].createElement(material.Grid, { size: 2 },
|
|
56232
56356
|
React__default["default"].createElement(Strand, { strand: feature.strand })),
|
|
56233
56357
|
strand === 1 ? (React__default["default"].createElement(material.Grid, { size: 4, style: { padding: 0 } },
|
|
56234
56358
|
React__default["default"].createElement(StyledTextField, { margin: "dense", variant: "outlined", value: loc.max, onChangeCommitted: (newLocation) => {
|
|
56235
56359
|
return handleExonLocationChange(loc.max, newLocation, feature, false);
|
|
56236
|
-
} }))) : (React__default["default"].createElement(material.Grid, { size: 4, style: { padding: 0 } },
|
|
56360
|
+
}, disabled: changeInProgress }))) : (React__default["default"].createElement(material.Grid, { size: 4, style: { padding: 0 } },
|
|
56237
56361
|
React__default["default"].createElement(StyledTextField, { margin: "dense", variant: "outlined", value: loc.min + 1, onChangeCommitted: (newLocation) => {
|
|
56238
56362
|
return handleExonLocationChange(loc.min, newLocation - 1, feature, true);
|
|
56239
|
-
} }))),
|
|
56363
|
+
}, disabled: changeInProgress }))),
|
|
56240
56364
|
React__default["default"].createElement(material.Grid, { size: 1 }, index !== transcriptExonParts.length - 1 &&
|
|
56241
56365
|
getThreePrimeSpliceSite(loc, index).map((site, idx) => (React__default["default"].createElement(material.Typography, { key: idx, component: 'span', color: site.color }, site.spliceSite))))))));
|
|
56242
56366
|
}))));
|
|
@@ -57913,8 +58037,8 @@
|
|
|
57913
58037
|
},
|
|
57914
58038
|
});
|
|
57915
58039
|
if (require$$1$2.isSessionModelWithWidgets(session)) {
|
|
57916
|
-
contextMenuItemsForFeature.
|
|
57917
|
-
label: 'Open transcript
|
|
58040
|
+
contextMenuItemsForFeature.splice(1, 0, {
|
|
58041
|
+
label: 'Open transcript editor',
|
|
57918
58042
|
onClick: () => {
|
|
57919
58043
|
const apolloTranscriptWidget = session.addWidget('ApolloTranscriptDetails', 'apolloTranscriptDetails', {
|
|
57920
58044
|
feature,
|
|
@@ -58262,6 +58386,25 @@
|
|
|
58262
58386
|
clusters.sort((a, b) => a.message.localeCompare(b.message) || a.start - b.start);
|
|
58263
58387
|
return clusters;
|
|
58264
58388
|
}
|
|
58389
|
+
function codonColorCode(letter, theme, highContrast) {
|
|
58390
|
+
if (letter === 'M') {
|
|
58391
|
+
return theme.palette.startCodon;
|
|
58392
|
+
}
|
|
58393
|
+
if (letter === '*') {
|
|
58394
|
+
return highContrast ? theme.palette.text.primary : theme.palette.stopCodon;
|
|
58395
|
+
}
|
|
58396
|
+
return;
|
|
58397
|
+
}
|
|
58398
|
+
function colorCode(letter, theme) {
|
|
58399
|
+
const letterUpper = letter.toUpperCase();
|
|
58400
|
+
if (letterUpper === 'A' ||
|
|
58401
|
+
letterUpper === 'C' ||
|
|
58402
|
+
letterUpper === 'G' ||
|
|
58403
|
+
letterUpper === 'T') {
|
|
58404
|
+
return theme.palette.bases[letterUpper].main.toString();
|
|
58405
|
+
}
|
|
58406
|
+
return 'lightgray';
|
|
58407
|
+
}
|
|
58265
58408
|
|
|
58266
58409
|
const minDisplayHeight$2 = 20;
|
|
58267
58410
|
function baseModelFactory$2(_pluginManager, configSchema) {
|
|
@@ -59087,34 +59230,26 @@
|
|
|
59087
59230
|
|
|
59088
59231
|
const configSchema$1 = configuration.ConfigurationSchema('LinearApolloReferenceSequenceDisplay', {}, { explicitIdentifier: 'displayId', explicitlyTyped: true });
|
|
59089
59232
|
|
|
59090
|
-
function getSeqRow(strand, bpPerPx) {
|
|
59233
|
+
function getSeqRow(strand, bpPerPx, reversed) {
|
|
59091
59234
|
if (bpPerPx > 1 || strand === undefined) {
|
|
59092
59235
|
return;
|
|
59093
59236
|
}
|
|
59237
|
+
if (reversed) {
|
|
59238
|
+
return strand === 1 ? 4 : 3;
|
|
59239
|
+
}
|
|
59094
59240
|
return strand === 1 ? 3 : 4;
|
|
59095
59241
|
}
|
|
59096
|
-
function getTranslationRow(frame, bpPerPx) {
|
|
59097
|
-
const
|
|
59098
|
-
|
|
59099
|
-
|
|
59100
|
-
|
|
59101
|
-
|
|
59102
|
-
|
|
59103
|
-
|
|
59104
|
-
|
|
59105
|
-
case 1: {
|
|
59106
|
-
return 2;
|
|
59107
|
-
}
|
|
59108
|
-
case -1: {
|
|
59109
|
-
return 3 + offset;
|
|
59110
|
-
}
|
|
59111
|
-
case -2: {
|
|
59112
|
-
return 4 + offset;
|
|
59113
|
-
}
|
|
59114
|
-
case -3: {
|
|
59115
|
-
return 5 + offset;
|
|
59116
|
-
}
|
|
59242
|
+
function getTranslationRow(frame, bpPerPx, reversed) {
|
|
59243
|
+
const frameRows = bpPerPx <= 1 ? [2, 1, 0, 7, 6, 5] : [2, 1, 0, 5, 4, 3];
|
|
59244
|
+
if (reversed) {
|
|
59245
|
+
frameRows.reverse();
|
|
59246
|
+
}
|
|
59247
|
+
frameRows.unshift(0);
|
|
59248
|
+
const row = frameRows.at(frame);
|
|
59249
|
+
if (row === undefined) {
|
|
59250
|
+
throw new Error('could not find row');
|
|
59117
59251
|
}
|
|
59252
|
+
return row;
|
|
59118
59253
|
}
|
|
59119
59254
|
function getLeftPx$1(feature, bpPerPx, offsetPx, block) {
|
|
59120
59255
|
const blockLeftPx = block.offsetPx - offsetPx;
|
|
@@ -59136,7 +59271,7 @@
|
|
|
59136
59271
|
ctx.strokeRect(left, top, width, height);
|
|
59137
59272
|
}
|
|
59138
59273
|
function drawHighlight(ctx, feature, bpPerPx, offsetPx, rowHeight, block, theme, selected = false) {
|
|
59139
|
-
const row = getSeqRow(feature.strand, bpPerPx);
|
|
59274
|
+
const row = getSeqRow(feature.strand, bpPerPx, block.reversed);
|
|
59140
59275
|
if (!row) {
|
|
59141
59276
|
return;
|
|
59142
59277
|
}
|
|
@@ -59160,7 +59295,7 @@
|
|
|
59160
59295
|
}
|
|
59161
59296
|
for (const loc of cdsLocs) {
|
|
59162
59297
|
const frame = require$$1$2.getFrame(loc.min, loc.max, feature.strand ?? 1, loc.phase);
|
|
59163
|
-
const row = getTranslationRow(frame, bpPerPx);
|
|
59298
|
+
const row = getTranslationRow(frame, bpPerPx, block.reversed);
|
|
59164
59299
|
const left = getLeftPx$1(loc, bpPerPx, offsetPx, block);
|
|
59165
59300
|
const top = row * rowHeight;
|
|
59166
59301
|
const width = (loc.max - loc.min) / bpPerPx;
|
|
@@ -59183,76 +59318,71 @@
|
|
|
59183
59318
|
hoveredFeature?.feature,
|
|
59184
59319
|
].filter((f) => f !== undefined)) {
|
|
59185
59320
|
if (featureTypeOntology.isTypeOf(feature.type, 'CDS')) {
|
|
59186
|
-
drawCDSHighlight(ctx, feature, bpPerPx, offsetPx, rowHeight, block, theme,
|
|
59321
|
+
drawCDSHighlight(ctx, feature, bpPerPx, offsetPx, rowHeight, block, theme, feature._id === selectedFeature?._id);
|
|
59187
59322
|
}
|
|
59188
59323
|
else {
|
|
59189
|
-
drawHighlight(ctx, feature, bpPerPx, offsetPx, rowHeight, block, theme,
|
|
59324
|
+
drawHighlight(ctx, feature, bpPerPx, offsetPx, rowHeight, block, theme, feature._id === selectedFeature?._id);
|
|
59190
59325
|
}
|
|
59191
59326
|
}
|
|
59192
59327
|
ctx.restore();
|
|
59193
59328
|
}
|
|
59194
59329
|
}
|
|
59195
59330
|
|
|
59196
|
-
function
|
|
59197
|
-
const
|
|
59198
|
-
|
|
59199
|
-
|
|
59200
|
-
|
|
59201
|
-
|
|
59202
|
-
|
|
59203
|
-
|
|
59204
|
-
return
|
|
59331
|
+
function getLeftPx(display, feature, block) {
|
|
59332
|
+
const { lgv } = display;
|
|
59333
|
+
const { bpPerPx, offsetPx } = lgv;
|
|
59334
|
+
const blockLeftPx = block.offsetPx - offsetPx;
|
|
59335
|
+
const featureLeftBpDistanceFromBlockLeftBp = block.reversed
|
|
59336
|
+
? block.end - feature.max
|
|
59337
|
+
: feature.min - block.start;
|
|
59338
|
+
const featureLeftPxDistanceFromBlockLeftPx = featureLeftBpDistanceFromBlockLeftBp / bpPerPx;
|
|
59339
|
+
return blockLeftPx + featureLeftPxDistanceFromBlockLeftPx;
|
|
59205
59340
|
}
|
|
59206
|
-
|
|
59207
|
-
|
|
59208
|
-
|
|
59209
|
-
|
|
59210
|
-
|
|
59211
|
-
|
|
59212
|
-
|
|
59213
|
-
|
|
59341
|
+
/**
|
|
59342
|
+
* Perform a canvas strokeRect, but have the stroke be contained within the
|
|
59343
|
+
* given rect instead of centered on it.
|
|
59344
|
+
*/
|
|
59345
|
+
function strokeRectInner(ctx, left, top, width, height, color) {
|
|
59346
|
+
ctx.strokeStyle = color;
|
|
59347
|
+
ctx.lineWidth = 1;
|
|
59348
|
+
ctx.strokeRect(left + 0.5, top + 0.5, width - 1, height - 1);
|
|
59214
59349
|
}
|
|
59350
|
+
|
|
59215
59351
|
function drawLetter(seqTrackctx, left, top, width, letter) {
|
|
59216
59352
|
const fontSize = Math.min(width, 10);
|
|
59217
59353
|
seqTrackctx.fillStyle = '#000';
|
|
59218
59354
|
seqTrackctx.font = `${fontSize}px`;
|
|
59219
59355
|
const textWidth = seqTrackctx.measureText(letter).width;
|
|
59220
|
-
const textX = left + (width - textWidth) / 2;
|
|
59356
|
+
const textX = Math.round(left + (width - textWidth) / 2);
|
|
59221
59357
|
seqTrackctx.fillText(letter, textX, top + 10);
|
|
59222
59358
|
}
|
|
59223
|
-
function drawTranslationFrameBackgrounds(
|
|
59359
|
+
function drawTranslationFrameBackgrounds(ctx, bpPerPx, theme, highContrast, left, width, sequenceRowHeight, reversed) {
|
|
59224
59360
|
const frames = bpPerPx <= 1 ? [3, 2, 1, 0, 0, -1, -2, -3] : [3, 2, 1, -1, -2, -3];
|
|
59361
|
+
if (reversed) {
|
|
59362
|
+
frames.reverse();
|
|
59363
|
+
}
|
|
59225
59364
|
for (const [idx, frame] of frames.entries()) {
|
|
59226
59365
|
const frameColor = theme.palette.framesCDS.at(frame)?.main;
|
|
59227
59366
|
if (!frameColor) {
|
|
59228
59367
|
continue;
|
|
59229
59368
|
}
|
|
59230
59369
|
const top = idx * sequenceRowHeight;
|
|
59231
|
-
const { offsetPx } = dynamicBlocks;
|
|
59232
|
-
const left = Math.max(0, -offsetPx);
|
|
59233
|
-
const width = dynamicBlocks.totalWidthPx;
|
|
59234
59370
|
ctx.fillStyle = highContrast ? theme.palette.background.default : frameColor;
|
|
59235
59371
|
ctx.fillRect(left, top, width, sequenceRowHeight);
|
|
59236
59372
|
if (highContrast) {
|
|
59237
59373
|
// eslint-disable-next-line prefer-destructuring
|
|
59238
|
-
|
|
59239
|
-
ctx
|
|
59240
|
-
}
|
|
59241
|
-
}
|
|
59242
|
-
// allows inter-region padding lines to show through
|
|
59243
|
-
for (const block of dynamicBlocks.getBlocks()) {
|
|
59244
|
-
if (block.type === 'InterRegionPaddingBlock') {
|
|
59245
|
-
const left = block.offsetPx - dynamicBlocks.offsetPx;
|
|
59246
|
-
ctx.clearRect(left, 0, block.widthPx, canvas.height);
|
|
59374
|
+
const strokeStyle = theme.palette.grey[200];
|
|
59375
|
+
strokeRectInner(ctx, left, top, width, sequenceRowHeight, strokeStyle);
|
|
59247
59376
|
}
|
|
59248
59377
|
}
|
|
59249
59378
|
}
|
|
59250
59379
|
function drawBase(ctx, base, index, leftPx, bpPerPx, rowHeight, theme) {
|
|
59251
|
-
|
|
59252
|
-
if (width < 1) {
|
|
59380
|
+
if (1 / bpPerPx < 1) {
|
|
59253
59381
|
return;
|
|
59254
59382
|
}
|
|
59255
|
-
const left = leftPx + index / bpPerPx;
|
|
59383
|
+
const left = Math.round(leftPx + index / bpPerPx);
|
|
59384
|
+
const nextLeft = Math.round(leftPx + (index + 1) / bpPerPx);
|
|
59385
|
+
const width = nextLeft - left;
|
|
59256
59386
|
const strands = [-1, 1];
|
|
59257
59387
|
for (const strand of strands) {
|
|
59258
59388
|
const top = (strand === 1 ? 3 : 4) * rowHeight;
|
|
@@ -59260,13 +59390,13 @@
|
|
|
59260
59390
|
ctx.fillStyle = colorCode(baseCode, theme);
|
|
59261
59391
|
ctx.fillRect(left, top, width, rowHeight);
|
|
59262
59392
|
if (1 / bpPerPx >= 12) {
|
|
59263
|
-
|
|
59264
|
-
ctx
|
|
59393
|
+
const strokeStyle = theme.palette.text.disabled;
|
|
59394
|
+
strokeRectInner(ctx, left, top, width, rowHeight, strokeStyle);
|
|
59265
59395
|
drawLetter(ctx, left, top, width, baseCode);
|
|
59266
59396
|
}
|
|
59267
59397
|
}
|
|
59268
59398
|
}
|
|
59269
|
-
function drawCodon(ctx, codon, leftPx, index, theme, highContrast, bpPerPx, bp, rowHeight, showStartCodons, showStopCodons) {
|
|
59399
|
+
function drawCodon$1(ctx, codon, leftPx, index, theme, highContrast, bpPerPx, bp, rowHeight, showStartCodons, showStopCodons) {
|
|
59270
59400
|
const frameOffsets = (bpPerPx <= 1 ? [0, 2, 1, 0, 7, 6, 5] : [0, 2, 1, 0, 5, 4, 3]).map((b) => b * rowHeight);
|
|
59271
59401
|
const strands = [-1, 1];
|
|
59272
59402
|
for (const strand of strands) {
|
|
@@ -59276,7 +59406,8 @@
|
|
|
59276
59406
|
continue;
|
|
59277
59407
|
}
|
|
59278
59408
|
const left = Math.round(leftPx + index / bpPerPx);
|
|
59279
|
-
const
|
|
59409
|
+
const nextLeft = Math.round(leftPx + (index + 3) / bpPerPx);
|
|
59410
|
+
const width = nextLeft - left;
|
|
59280
59411
|
const codonCode = strand === 1 ? codon : require$$1$2.revcom(codon);
|
|
59281
59412
|
const aminoAcidCode = require$$1$2.defaultCodonTable[codonCode];
|
|
59282
59413
|
const fillColor = codonColorCode(aminoAcidCode, theme, highContrast);
|
|
@@ -59287,8 +59418,8 @@
|
|
|
59287
59418
|
ctx.fillRect(left, top, width, rowHeight);
|
|
59288
59419
|
}
|
|
59289
59420
|
if (1 / bpPerPx >= 4) {
|
|
59290
|
-
|
|
59291
|
-
ctx
|
|
59421
|
+
const strokeStyle = theme.palette.text.disabled;
|
|
59422
|
+
strokeRectInner(ctx, left, top, width, rowHeight, strokeStyle);
|
|
59292
59423
|
drawLetter(ctx, left, top, width, aminoAcidCode);
|
|
59293
59424
|
}
|
|
59294
59425
|
}
|
|
@@ -59299,9 +59430,10 @@
|
|
|
59299
59430
|
return;
|
|
59300
59431
|
}
|
|
59301
59432
|
ctx.clearRect(0, 0, canvas.width, canvas.height);
|
|
59302
|
-
drawTranslationFrameBackgrounds(canvas, ctx, bpPerPx, theme, dynamicBlocks, highContrast, sequenceRowHeight);
|
|
59303
59433
|
const { apolloDataStore } = session;
|
|
59304
59434
|
for (const block of dynamicBlocks.contentBlocks) {
|
|
59435
|
+
const totalOffsetPx = block.offsetPx - offsetPx;
|
|
59436
|
+
drawTranslationFrameBackgrounds(ctx, bpPerPx, theme, highContrast, totalOffsetPx, block.widthPx, sequenceRowHeight, block.reversed);
|
|
59305
59437
|
const assembly = apolloDataStore.assemblies.get(block.assemblyName);
|
|
59306
59438
|
const ref = assembly?.getByRefName(block.refName);
|
|
59307
59439
|
const roundedStart = Math.floor(block.start);
|
|
@@ -59311,16 +59443,20 @@
|
|
|
59311
59443
|
return;
|
|
59312
59444
|
}
|
|
59313
59445
|
seq = seq.toUpperCase();
|
|
59314
|
-
|
|
59315
|
-
|
|
59446
|
+
if (block.reversed) {
|
|
59447
|
+
seq = require$$1$2.revcom(seq);
|
|
59448
|
+
}
|
|
59449
|
+
const baseOffsetPx = (block.reversed ? roundedEnd - block.end : block.start - roundedStart) /
|
|
59450
|
+
bpPerPx;
|
|
59451
|
+
const seqLeftPx = totalOffsetPx - baseOffsetPx;
|
|
59316
59452
|
for (let i = 0; i < seq.length; i++) {
|
|
59317
|
-
const bp = roundedStart + i;
|
|
59453
|
+
const bp = block.reversed ? roundedEnd - i : roundedStart + i;
|
|
59318
59454
|
const codon = seq.slice(i, i + 3);
|
|
59319
59455
|
drawBase(ctx, seq[i], i, seqLeftPx, bpPerPx, sequenceRowHeight, theme);
|
|
59320
59456
|
if (codon.length !== 3) {
|
|
59321
59457
|
continue;
|
|
59322
59458
|
}
|
|
59323
|
-
drawCodon(ctx, codon, seqLeftPx, i, theme, highContrast, bpPerPx, bp, sequenceRowHeight, showStartCodons, showStopCodons);
|
|
59459
|
+
drawCodon$1(ctx, codon, seqLeftPx, i, theme, highContrast, bpPerPx, bp, sequenceRowHeight, showStartCodons, showStopCodons);
|
|
59324
59460
|
}
|
|
59325
59461
|
}
|
|
59326
59462
|
}
|
|
@@ -60384,6 +60520,8 @@
|
|
|
60384
60520
|
graphical: true,
|
|
60385
60521
|
table: false,
|
|
60386
60522
|
showFeatureLabels: true,
|
|
60523
|
+
showStartCodons: false,
|
|
60524
|
+
showStopCodons: true,
|
|
60387
60525
|
showCheckResults: true,
|
|
60388
60526
|
zoomThreshold: 200,
|
|
60389
60527
|
heightPreConfig: require$$1$3.types.maybe(require$$1$3.types.refinement('displayHeight', require$$1$3.types.number, (n) => n >= minDisplayHeight)),
|
|
@@ -60512,6 +60650,12 @@
|
|
|
60512
60650
|
toggleShowFeatureLabels() {
|
|
60513
60651
|
self.showFeatureLabels = !self.showFeatureLabels;
|
|
60514
60652
|
},
|
|
60653
|
+
toggleShowStartCodons() {
|
|
60654
|
+
self.showStartCodons = !self.showStartCodons;
|
|
60655
|
+
},
|
|
60656
|
+
toggleShowStopCodons() {
|
|
60657
|
+
self.showStopCodons = !self.showStopCodons;
|
|
60658
|
+
},
|
|
60515
60659
|
toggleShowCheckResults() {
|
|
60516
60660
|
self.showCheckResults = !self.showCheckResults;
|
|
60517
60661
|
},
|
|
@@ -60526,7 +60670,7 @@
|
|
|
60526
60670
|
const { filteredFeatureTypes, trackMenuItems: superTrackMenuItems } = self;
|
|
60527
60671
|
return {
|
|
60528
60672
|
trackMenuItems() {
|
|
60529
|
-
const { graphical, table, showFeatureLabels, showCheckResults } = self;
|
|
60673
|
+
const { graphical, table, showFeatureLabels, showStartCodons, showStopCodons, showCheckResults, } = self;
|
|
60530
60674
|
return [
|
|
60531
60675
|
...superTrackMenuItems(),
|
|
60532
60676
|
{
|
|
@@ -60565,6 +60709,22 @@
|
|
|
60565
60709
|
self.toggleShowFeatureLabels();
|
|
60566
60710
|
},
|
|
60567
60711
|
},
|
|
60712
|
+
{
|
|
60713
|
+
label: 'Show start codons',
|
|
60714
|
+
type: 'checkbox',
|
|
60715
|
+
checked: showStartCodons,
|
|
60716
|
+
onClick: () => {
|
|
60717
|
+
self.toggleShowStartCodons();
|
|
60718
|
+
},
|
|
60719
|
+
},
|
|
60720
|
+
{
|
|
60721
|
+
label: 'Show stop codons',
|
|
60722
|
+
type: 'checkbox',
|
|
60723
|
+
checked: showStopCodons,
|
|
60724
|
+
onClick: () => {
|
|
60725
|
+
self.toggleShowStopCodons();
|
|
60726
|
+
},
|
|
60727
|
+
},
|
|
60568
60728
|
{
|
|
60569
60729
|
label: 'Check Results',
|
|
60570
60730
|
type: 'checkbox',
|
|
@@ -60641,7 +60801,7 @@
|
|
|
60641
60801
|
return;
|
|
60642
60802
|
}
|
|
60643
60803
|
void self.session.apolloDataStore.loadFeatures(self.regions);
|
|
60644
|
-
if (self.lgv.bpPerPx <=
|
|
60804
|
+
if (self.lgv.bpPerPx <= self.zoomThreshold) {
|
|
60645
60805
|
void self.session.apolloDataStore.loadRefSeq(self.regions);
|
|
60646
60806
|
}
|
|
60647
60807
|
}, { name: 'LinearApolloSixFrameDisplayLoadFeatures', delay: 1000 }));
|
|
@@ -60833,6 +60993,28 @@
|
|
|
60833
60993
|
}));
|
|
60834
60994
|
}
|
|
60835
60995
|
|
|
60996
|
+
function drawCodon(ctx, codon, leftPx, index, theme, highContrast, bpPerPx, bp, rowHeight, showFeatureLabels, showStartCodons, showStopCodons) {
|
|
60997
|
+
const frameOffsets = (showFeatureLabels ? [0, 4, 2, 0, 14, 12, 10] : [0, 2, 1, 0, 7, 6, 5]).map((b) => b * rowHeight);
|
|
60998
|
+
const strands = [-1, 1];
|
|
60999
|
+
for (const strand of strands) {
|
|
61000
|
+
const frame = require$$1$2.getFrame(bp, bp + 3, strand, 0);
|
|
61001
|
+
const top = frameOffsets.at(frame);
|
|
61002
|
+
if (top === undefined) {
|
|
61003
|
+
continue;
|
|
61004
|
+
}
|
|
61005
|
+
const left = Math.round(leftPx + index / bpPerPx);
|
|
61006
|
+
const width = Math.round(3 / bpPerPx) === 0 ? 1 : Math.round(3 / bpPerPx);
|
|
61007
|
+
const codonCode = strand === 1 ? codon : require$$1$2.revcom(codon);
|
|
61008
|
+
const aminoAcidCode = require$$1$2.defaultCodonTable[codonCode];
|
|
61009
|
+
const fillColor = codonColorCode(aminoAcidCode, theme, highContrast);
|
|
61010
|
+
if (fillColor &&
|
|
61011
|
+
((showStopCodons && aminoAcidCode == '*') ||
|
|
61012
|
+
(showStartCodons && aminoAcidCode != '*'))) {
|
|
61013
|
+
ctx.fillStyle = fillColor;
|
|
61014
|
+
ctx.fillRect(left, top, width, rowHeight);
|
|
61015
|
+
}
|
|
61016
|
+
}
|
|
61017
|
+
}
|
|
60836
61018
|
function renderingModelFactory(pluginManager, configSchema) {
|
|
60837
61019
|
const LinearApolloSixFrameDisplayLayouts = layoutsModelFactory(pluginManager, configSchema);
|
|
60838
61020
|
return LinearApolloSixFrameDisplayLayouts.named('LinearApolloSixFrameDisplayRendering')
|
|
@@ -60922,11 +61104,11 @@
|
|
|
60922
61104
|
}
|
|
60923
61105
|
}, { name: 'LinearApolloSixFrameDisplayRenderCollaborators' }));
|
|
60924
61106
|
require$$1$3.addDisposer(self, mobx.autorun(() => {
|
|
60925
|
-
const { canvas, featureLayouts, featuresHeight, lgv } = self;
|
|
61107
|
+
const { apolloRowHeight, canvas, featureLayouts, featuresHeight, lgv, session, theme, showFeatureLabels, showStartCodons, showStopCodons, } = self;
|
|
60926
61108
|
if (!lgv.initialized || self.regionCannotBeRendered()) {
|
|
60927
61109
|
return;
|
|
60928
61110
|
}
|
|
60929
|
-
const { displayedRegions, dynamicBlocks } = lgv;
|
|
61111
|
+
const { bpPerPx, offsetPx, displayedRegions, dynamicBlocks } = lgv;
|
|
60930
61112
|
const ctx = canvas?.getContext('2d');
|
|
60931
61113
|
if (!ctx) {
|
|
60932
61114
|
return;
|
|
@@ -60950,6 +61132,27 @@
|
|
|
60950
61132
|
}
|
|
60951
61133
|
}
|
|
60952
61134
|
}
|
|
61135
|
+
if (showStartCodons || showStopCodons) {
|
|
61136
|
+
const { apolloDataStore } = session;
|
|
61137
|
+
for (const block of dynamicBlocks.contentBlocks) {
|
|
61138
|
+
const assembly = apolloDataStore.assemblies.get(block.assemblyName);
|
|
61139
|
+
const ref = assembly?.getByRefName(block.refName);
|
|
61140
|
+
const roundedStart = Math.floor(block.start);
|
|
61141
|
+
const roundedEnd = Math.ceil(block.end);
|
|
61142
|
+
let seq = ref?.getSequence(roundedStart, roundedEnd);
|
|
61143
|
+
if (!seq) {
|
|
61144
|
+
break;
|
|
61145
|
+
}
|
|
61146
|
+
seq = seq.toUpperCase();
|
|
61147
|
+
const baseOffsetPx = (block.start - roundedStart) / bpPerPx;
|
|
61148
|
+
const seqLeftPx = Math.round(block.offsetPx - offsetPx - baseOffsetPx);
|
|
61149
|
+
for (let i = 0; i < seq.length; i++) {
|
|
61150
|
+
const bp = roundedStart + i;
|
|
61151
|
+
const codon = seq.slice(i, i + 3);
|
|
61152
|
+
drawCodon(ctx, codon, seqLeftPx, i, theme, true, bpPerPx, bp, apolloRowHeight, showFeatureLabels, showStartCodons, showStopCodons);
|
|
61153
|
+
}
|
|
61154
|
+
}
|
|
61155
|
+
}
|
|
60953
61156
|
}, { name: 'LinearApolloSixFrameDisplayRenderFeatures' }));
|
|
60954
61157
|
},
|
|
60955
61158
|
}));
|
|
@@ -61912,17 +62115,6 @@
|
|
|
61912
62115
|
d: "M12 2C6.48 2 2 6.48 2 12s4.48 10 10 10 10-4.48 10-10S17.52 2 12 2m1 15h-2v-2h2zm0-4h-2V7h2z"
|
|
61913
62116
|
}), 'Error');
|
|
61914
62117
|
|
|
61915
|
-
function getLeftPx(display, feature, block) {
|
|
61916
|
-
const { lgv } = display;
|
|
61917
|
-
const { bpPerPx, offsetPx } = lgv;
|
|
61918
|
-
const blockLeftPx = block.offsetPx - offsetPx;
|
|
61919
|
-
const featureLeftBpDistanceFromBlockLeftBp = block.reversed
|
|
61920
|
-
? block.end - feature.max
|
|
61921
|
-
: feature.min - block.start;
|
|
61922
|
-
const featureLeftPxDistanceFromBlockLeftPx = featureLeftBpDistanceFromBlockLeftBp / bpPerPx;
|
|
61923
|
-
return blockLeftPx + featureLeftPxDistanceFromBlockLeftPx;
|
|
61924
|
-
}
|
|
61925
|
-
|
|
61926
62118
|
const CheckResultWarnings = mobxReact.observer(function CheckResultWarnings({ display, }) {
|
|
61927
62119
|
const { classes } = useStyles$1();
|
|
61928
62120
|
const { apolloDragging, apolloRowHeight, lgv, session, showCheckResults } = display;
|
|
@@ -62254,7 +62446,7 @@
|
|
|
62254
62446
|
const controller = new AbortController();
|
|
62255
62447
|
const { signal } = controller;
|
|
62256
62448
|
function abortDrag() {
|
|
62257
|
-
controller.abort();
|
|
62449
|
+
controller.abort('makeDisplayComponent');
|
|
62258
62450
|
}
|
|
62259
62451
|
globalThis.addEventListener('mousemove', mouseMove, { signal });
|
|
62260
62452
|
globalThis.addEventListener('mouseup', abortDrag, { signal });
|
|
@@ -62691,7 +62883,7 @@
|
|
|
62691
62883
|
statusMessage: `Loading ontology "${name}", version "${version}", this may take a while`,
|
|
62692
62884
|
progressPct: 0,
|
|
62693
62885
|
cancelCallback: () => {
|
|
62694
|
-
controller.abort();
|
|
62886
|
+
controller.abort('ClientDataStore');
|
|
62695
62887
|
jobsManager.abortJob(job.name);
|
|
62696
62888
|
},
|
|
62697
62889
|
};
|
|
@@ -62830,6 +63022,7 @@
|
|
|
62830
63022
|
apolloSelectedFeature: require$$1$3.types.safeReference(AnnotationFeatureExtended),
|
|
62831
63023
|
jobsManager: require$$1$3.types.optional(ApolloJobModel, {}),
|
|
62832
63024
|
isLocked: require$$1$3.types.optional(require$$1$3.types.boolean, false),
|
|
63025
|
+
changeInProgress: require$$1$3.types.optional(require$$1$3.types.boolean, false),
|
|
62833
63026
|
})
|
|
62834
63027
|
.volatile(() => ({
|
|
62835
63028
|
apolloHoveredFeature: undefined,
|
|
@@ -62892,6 +63085,9 @@
|
|
|
62892
63085
|
toggleLocked() {
|
|
62893
63086
|
self.isLocked = !self.isLocked;
|
|
62894
63087
|
},
|
|
63088
|
+
setChangeInProgress(changeInProgress) {
|
|
63089
|
+
self.changeInProgress = changeInProgress;
|
|
63090
|
+
},
|
|
62895
63091
|
getPluginConfiguration() {
|
|
62896
63092
|
const { jbrowse } = require$$1$3.getRoot(self);
|
|
62897
63093
|
const pluginConfiguration =
|