ketcher-react 3.9.0-rc.1 → 3.9.0-rc.3

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.js CHANGED
@@ -42,7 +42,6 @@ import _, { isNumber, throttle as throttle$1, debounce as debounce$1, intersecti
42
42
  import _taggedTemplateLiteral from '@babel/runtime/helpers/taggedTemplateLiteral';
43
43
  import styled from '@emotion/styled';
44
44
  import { css } from '@emotion/react';
45
- import * as KN from 'w3c-keyname';
46
45
  import require$$0$3 from 'util';
47
46
  import ReactDOM, { createPortal } from 'react-dom';
48
47
  import { connect, useDispatch, useSelector, Provider } from 'react-redux';
@@ -2791,7 +2790,7 @@ var toolActions = (_toolActions = {
2791
2790
  }
2792
2791
  },
2793
2792
  'charge-plus': {
2794
- shortcut: '+',
2793
+ shortcut: ['Equal', 'Shift+Equal', 'NumpadAdd'],
2795
2794
  title: 'Charge Plus',
2796
2795
  action: {
2797
2796
  tool: 'charge',
@@ -2802,7 +2801,7 @@ var toolActions = (_toolActions = {
2802
2801
  }
2803
2802
  },
2804
2803
  'charge-minus': {
2805
- shortcut: '-',
2804
+ shortcut: ['Minus', 'NumpadSubtract'],
2806
2805
  title: 'Charge Minus',
2807
2806
  action: {
2808
2807
  tool: 'charge',
@@ -3203,6 +3202,9 @@ var toolActions = (_toolActions = {
3203
3202
  },
3204
3203
  disabled: function disabled(editor) {
3205
3204
  return editor.isMonomerCreationWizardActive || !editor.isMonomerCreationWizardEnabled;
3205
+ },
3206
+ hidden: function hidden(options) {
3207
+ return isHidden(options, CREATE_MONOMER_TOOL_NAME);
3206
3208
  }
3207
3209
  }), _defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_toolActions, "shapes", {
3208
3210
  disabled: function disabled(editor) {
@@ -3839,7 +3841,7 @@ var zoom = {
3839
3841
  }
3840
3842
  },
3841
3843
  'zoom-out': {
3842
- shortcut: ['Ctrl+_', 'Ctrl+-'],
3844
+ shortcut: ['Mod+Minus', 'Mod+NumpadSubtract'],
3843
3845
  title: 'Zoom Out',
3844
3846
  enabledInViewOnly: true,
3845
3847
  disabled: function disabled(editor) {
@@ -3861,7 +3863,7 @@ var zoom = {
3861
3863
  }
3862
3864
  },
3863
3865
  'zoom-in': {
3864
- shortcut: ['Ctrl+=', 'Ctrl++'],
3866
+ shortcut: ['Mod+Equal', 'Mod+NumpadAdd'],
3865
3867
  title: 'Zoom In',
3866
3868
  enabledInViewOnly: true,
3867
3869
  disabled: function disabled(editor) {
@@ -3892,7 +3894,7 @@ var zoom = {
3892
3894
 
3893
3895
  var openHelpLink = function openHelpLink() {
3894
3896
  var _window$open;
3895
- return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v3.9.0-rc.1\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3897
+ return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v3.9.0-rc.3\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3896
3898
  };
3897
3899
  var help = {
3898
3900
  help: {
@@ -8853,7 +8855,7 @@ var Dialog = function Dialog(props) {
8853
8855
  }
8854
8856
  };
8855
8857
  var keyDown = function keyDown(event) {
8856
- var key = KN.keyName(event);
8858
+ var key = event.key;
8857
8859
  var active = document.activeElement;
8858
8860
  var activeTextarea = active && active.tagName === 'TEXTAREA';
8859
8861
  if (key === 'Escape' || key === 'Enter' && !activeTextarea) {
@@ -20353,8 +20355,8 @@ function keyHandle(dispatch, getState, hotKeys, event) {
20353
20355
  var hoveredItem = getHoveredItem(render.ctab);
20354
20356
  if (key && key.length === 1 && !hoveredItem) {
20355
20357
  var currentlyPressedKeys = selectAbbreviationLookupValue(state);
20356
- var isShortcutKey = shortcutKeys.includes(key === null || key === void 0 ? void 0 : key.toLowerCase());
20357
- var isTheSameKey = key === currentlyPressedKeys;
20358
+ var isShortcutKey = shortcutKeys.includes(key.toLowerCase());
20359
+ var isTheSameKey = key.toLowerCase() === currentlyPressedKeys;
20358
20360
  var isAbbreviationLookupShown = (!isTheSameKey || !isShortcutKey) && currentlyPressedKeys;
20359
20361
  if (isAbbreviationLookupShown) {
20360
20362
  dispatch(showAbbreviationLookup(event.key));
@@ -20372,7 +20374,7 @@ function keyHandle(dispatch, getState, hotKeys, event) {
20372
20374
  dispatch(initAbbreviationLookup(event.key));
20373
20375
  }
20374
20376
  }
20375
- if (key && key.length === 1 && key.match('/')) {
20377
+ if (key === 'Slash') {
20376
20378
  var hotkeyDialogTypes = {
20377
20379
  atoms: configWithNonViewOnlyActionsDisabled['atom-props'].action,
20378
20380
  bonds: configWithNonViewOnlyActionsDisabled['bond-props'].action
@@ -25578,11 +25580,35 @@ var Editor$3 = function () {
25578
25580
  }
25579
25581
  return false;
25580
25582
  }
25583
+ }, {
25584
+ key: "isMinimalViableStructure",
25585
+ value: function isMinimalViableStructure() {
25586
+ var _this = this;
25587
+ var nonLeavingAtoms = this.struct().atoms.filter(function (atomId) {
25588
+ assert_1(_this.monomerCreationState);
25589
+ return Array.from(_this.monomerCreationState.assignedAttachmentPoints.values()).every(function (atomPair) {
25590
+ return atomPair[1] !== atomId;
25591
+ });
25592
+ });
25593
+ if (nonLeavingAtoms.size < 2) {
25594
+ return false;
25595
+ }
25596
+ var nonLeavingAtomBonds = this.struct().bonds.filter(function (_, bond) {
25597
+ return nonLeavingAtoms.has(bond.begin) && nonLeavingAtoms.has(bond.end);
25598
+ });
25599
+ if (nonLeavingAtomBonds.size < 1) {
25600
+ return false;
25601
+ }
25602
+ var simpleSingleBonds = nonLeavingAtomBonds.filter(function (_, bond) {
25603
+ return bond.type === Bond$2.PATTERN.TYPE.SINGLE && bond.stereo === Bond$2.PATTERN.STEREO.NONE;
25604
+ });
25605
+ return simpleSingleBonds.size >= 1;
25606
+ }
25581
25607
  }, {
25582
25608
  key: "openMonomerCreationWizard",
25583
25609
  value: function openMonomerCreationWizard() {
25584
25610
  var _selection$atoms2,
25585
- _this = this;
25611
+ _this2 = this;
25586
25612
  var currentStruct = this.render.ctab.molecule;
25587
25613
  var selection = this.selection();
25588
25614
  assert_1(selection);
@@ -25594,7 +25620,7 @@ var Editor$3 = function () {
25594
25620
  return a - b;
25595
25621
  }).forEach(function (atomId, i) {
25596
25622
  originalToSelectedAtomsIdMap.set(atomId, i);
25597
- _this.selectedToOriginalAtomsIdMap.set(i, atomId);
25623
+ _this2.selectedToOriginalAtomsIdMap.set(i, atomId);
25598
25624
  });
25599
25625
  var assignedAttachmentPoints = new Map();
25600
25626
  var sideTerminalSGroupAtoms = this.terminalRGroupAtoms.filter(function (_ref) {
@@ -25663,10 +25689,10 @@ var Editor$3 = function () {
25663
25689
  pp: leavingAtom.pp
25664
25690
  });
25665
25691
  var selectedStructLeavingAtomId = selectedStruct.atoms.add(selectedStructLeavingAtom);
25666
- _this.selectedToOriginalAtomsIdMap.set(selectedStructLeavingAtomId, atomId);
25692
+ _this2.selectedToOriginalAtomsIdMap.set(selectedStructLeavingAtomId, atomId);
25667
25693
  var selectedStructAttachmentAtomId = originalToSelectedAtomsIdMap.get(attachmentAtomId);
25668
25694
  assert_1(selectedStructAttachmentAtomId !== undefined);
25669
- _this.selectedToOriginalAtomsIdMap.set(selectedStructAttachmentAtomId, attachmentAtomId);
25695
+ _this2.selectedToOriginalAtomsIdMap.set(selectedStructAttachmentAtomId, attachmentAtomId);
25670
25696
  var newBond = new Bond$2({
25671
25697
  type: Bond$2.PATTERN.TYPE.SINGLE,
25672
25698
  begin: selectedStructAttachmentAtomId,
@@ -25760,7 +25786,7 @@ var Editor$3 = function () {
25760
25786
  }, {
25761
25787
  key: "assignConnectionPointAtom",
25762
25788
  value: function assignConnectionPointAtom(atomId) {
25763
- var _this2 = this;
25789
+ var _this3 = this;
25764
25790
  assert_1(this.monomerCreationState);
25765
25791
  var potentialLeavingAtoms = this.monomerCreationState.potentialAttachmentPoints.get(atomId);
25766
25792
  var leavingAtomId;
@@ -25769,7 +25795,7 @@ var Editor$3 = function () {
25769
25795
  return a - b;
25770
25796
  }).reduce(function (acc, currentAtomId) {
25771
25797
  var _Elements$get;
25772
- var atom = _this2.struct().atoms.get(currentAtomId);
25798
+ var atom = _this3.struct().atoms.get(currentAtomId);
25773
25799
  assert_1(atom);
25774
25800
  var atomicNumber = (_Elements$get = Elements.get(atom.label)) === null || _Elements$get === void 0 ? void 0 : _Elements$get.number;
25775
25801
  if (atomicNumber !== undefined) {
@@ -25825,14 +25851,16 @@ var Editor$3 = function () {
25825
25851
  assert_1(isNumber(originalLeavingAtomId));
25826
25852
  var originalLeavingAtom = this.originalStruct.atoms.get(originalLeavingAtomId);
25827
25853
  assert_1(originalLeavingAtom);
25828
- originalLeavingAtom.rglabel = null;
25829
- originalLeavingAtom.label = leavingAtom.label;
25830
- this.originalStruct.calcImplicitHydrogen(originalLeavingAtomId);
25854
+ if (originalLeavingAtom.rglabel !== null) {
25855
+ originalLeavingAtom.rglabel = null;
25856
+ originalLeavingAtom.label = leavingAtom.label;
25857
+ this.originalStruct.calcImplicitHydrogen(originalLeavingAtomId);
25858
+ }
25831
25859
  }
25832
25860
  }, {
25833
25861
  key: "saveNewMonomer",
25834
25862
  value: function saveNewMonomer(data) {
25835
- var _this3 = this,
25863
+ var _this4 = this,
25836
25864
  _this$originalSelecti;
25837
25865
  if (!this.monomerCreationState) {
25838
25866
  throw new Error('Monomer creation wizard is not active, cannot save new monomer');
@@ -25889,25 +25917,25 @@ var Editor$3 = function () {
25889
25917
  this.monomerCreationState.assignedAttachmentPoints.forEach(function (_ref11) {
25890
25918
  var _ref12 = _slicedToArray$1(_ref11, 2),
25891
25919
  leavingAtomId = _ref12[1];
25892
- return _this3.cleanupAttachmentPoint(leavingAtomId);
25920
+ return _this4.cleanupAttachmentPoint(leavingAtomId);
25893
25921
  });
25894
25922
  this.monomerCreationState.potentialAttachmentPoints.forEach(function (leavingAtomIds) {
25895
25923
  return Array.from(leavingAtomIds.values()).forEach(function (leavingAtomId) {
25896
- return _this3.cleanupAttachmentPoint(leavingAtomId);
25924
+ return _this4.cleanupAttachmentPoint(leavingAtomId);
25897
25925
  });
25898
25926
  });
25899
25927
  this.closeMonomerCreationWizard();
25900
25928
  (_this$originalSelecti = this.originalSelection.atoms) === null || _this$originalSelecti === void 0 || _this$originalSelecti.forEach(function (atomId) {
25901
- var atom = _this3.render.ctab.molecule.atoms.get(atomId);
25929
+ var atom = _this4.render.ctab.molecule.atoms.get(atomId);
25902
25930
  if (atom) {
25903
25931
  atom.fragment = -1;
25904
25932
  }
25905
25933
  });
25906
25934
  var sGroupAttachmentPoints = MacromoleculesConverter.convertMonomerAttachmentPointsToSGroupAttachmentPoints(monomer, this.selectedToOriginalAtomsIdMap);
25907
25935
  sGroupAttachmentPoints.forEach(function (ap) {
25908
- _this3.render.ctab.molecule.bonds.forEach(function (bond) {
25909
- var _this3$originalSelect, _this3$originalSelect2;
25910
- if ((bond.begin === ap.atomId || bond.end === ap.atomId) && (!((_this3$originalSelect = _this3.originalSelection.atoms) !== null && _this3$originalSelect !== void 0 && _this3$originalSelect.includes(bond.begin)) || !((_this3$originalSelect2 = _this3.originalSelection.atoms) !== null && _this3$originalSelect2 !== void 0 && _this3$originalSelect2.includes(bond.end)))) {
25936
+ _this4.render.ctab.molecule.bonds.forEach(function (bond) {
25937
+ var _this4$originalSelect, _this4$originalSelect2;
25938
+ if ((bond.begin === ap.atomId || bond.end === ap.atomId) && (!((_this4$originalSelect = _this4.originalSelection.atoms) !== null && _this4$originalSelect !== void 0 && _this4$originalSelect.includes(bond.begin)) || !((_this4$originalSelect2 = _this4.originalSelection.atoms) !== null && _this4$originalSelect2 !== void 0 && _this4$originalSelect2.includes(bond.end)))) {
25911
25939
  bond.beginSuperatomAttachmentPointNumber = ap.attachmentPointNumber;
25912
25940
  }
25913
25941
  });
@@ -25976,6 +26004,7 @@ var Editor$3 = function () {
25976
26004
  }, {
25977
26005
  key: "removeAttachmentPoint",
25978
26006
  value: function removeAttachmentPoint(name) {
26007
+ var _this5 = this;
25979
26008
  assert_1(this.monomerCreationState);
25980
26009
  var atomPair = this.monomerCreationState.assignedAttachmentPoints.get(name);
25981
26010
  assert_1(atomPair);
@@ -25992,8 +26021,18 @@ var Editor$3 = function () {
25992
26021
  var action = fromOneBondDeletion(this.render.ctab, preservedBondId).mergeWith(fromOneAtomDeletion(this.render.ctab, preservedLeavingAtomId));
25993
26022
  this.update(action, true);
25994
26023
  }
26024
+ this.preservedConnectionPointData["delete"](attachmentAtomId);
26025
+ } else {
26026
+ var leavingAtoms = this.findPotentialLeavingAtoms(attachmentAtomId);
26027
+ var leavingAtomIdsSet = new Set();
26028
+ leavingAtoms.forEach(function (atom) {
26029
+ var atomId = _this5.struct().atoms.keyOf(atom);
26030
+ if (atomId !== null) {
26031
+ leavingAtomIdsSet.add(atomId);
26032
+ }
26033
+ });
26034
+ this.monomerCreationState.potentialAttachmentPoints.set(attachmentAtomId, leavingAtomIdsSet);
25995
26035
  }
25996
- this.preservedConnectionPointData["delete"](attachmentAtomId);
25997
26036
  this.monomerCreationState.assignedAttachmentPoints["delete"](name);
25998
26037
  this.monomerCreationState = Object.assign({}, this.monomerCreationState);
25999
26038
  this.render.update(true);
@@ -26042,7 +26081,7 @@ var Editor$3 = function () {
26042
26081
  }, {
26043
26082
  key: "findPotentialLeavingAtoms",
26044
26083
  value: function findPotentialLeavingAtoms(attachmentAtomId) {
26045
- var _this4 = this;
26084
+ var _this6 = this;
26046
26085
  var bondsToOutside = this.struct().bonds.filter(function (_, bond) {
26047
26086
  return attachmentAtomId === bond.begin && attachmentAtomId !== bond.end || attachmentAtomId === bond.end && attachmentAtomId !== bond.begin;
26048
26087
  });
@@ -26052,7 +26091,7 @@ var Editor$3 = function () {
26052
26091
  return;
26053
26092
  }
26054
26093
  var atomIdToUse = attachmentAtomId === bond.begin ? bond.end : bond.begin;
26055
- var atom = _this4.struct().atoms.get(atomIdToUse);
26094
+ var atom = _this6.struct().atoms.get(atomIdToUse);
26056
26095
  assert_1(atom);
26057
26096
  if (atom.neighbors.length === 1) {
26058
26097
  potentialLeavingAtoms.push(atom);
@@ -26063,15 +26102,15 @@ var Editor$3 = function () {
26063
26102
  }, {
26064
26103
  key: "subscribeToChangeEventInMonomerCreationWizard",
26065
26104
  value: function subscribeToChangeEventInMonomerCreationWizard() {
26066
- var _this5 = this;
26105
+ var _this7 = this;
26067
26106
  if (this.changeEventSubscriber) {
26068
26107
  return;
26069
26108
  }
26070
26109
  var handleChangeEvent = function handleChangeEvent(data) {
26071
- if (!_this5.isMonomerCreationWizardActive || data.length === 0) {
26110
+ if (!_this7.isMonomerCreationWizardActive || data.length === 0) {
26072
26111
  return;
26073
26112
  }
26074
- _this5.collectChangesForMonomerCreationStateInvalidation(data);
26113
+ _this7.collectChangesForMonomerCreationStateInvalidation(data);
26075
26114
  };
26076
26115
  this.changeEventSubscriber = this.subscribe('change', handleChangeEvent);
26077
26116
  }
@@ -26114,7 +26153,7 @@ var Editor$3 = function () {
26114
26153
  }, {
26115
26154
  key: "invalidateMonomerCreationWizardState",
26116
26155
  value: function invalidateMonomerCreationWizardState(changesMap) {
26117
- var _this6 = this;
26156
+ var _this8 = this;
26118
26157
  if (!this.monomerCreationState) {
26119
26158
  return;
26120
26159
  }
@@ -26128,7 +26167,7 @@ var Editor$3 = function () {
26128
26167
  switch (operation) {
26129
26168
  case OperationType.ATOM_DELETE:
26130
26169
  {
26131
- var attachmentPointsToInvalidate = Array.from(_this6.monomerCreationState.assignedAttachmentPoints.entries()).filter(function (_ref13) {
26170
+ var attachmentPointsToInvalidate = Array.from(_this8.monomerCreationState.assignedAttachmentPoints.entries()).filter(function (_ref13) {
26132
26171
  var _ref14 = _slicedToArray$1(_ref13, 2),
26133
26172
  atomPair = _ref14[1];
26134
26173
  return ids.has(atomPair[0]) || ids.has(atomPair[1]);
@@ -26144,18 +26183,39 @@ var Editor$3 = function () {
26144
26183
  attachmentAtomId = _atomPair4[0],
26145
26184
  leavingAtomId = _atomPair4[1];
26146
26185
  if (ids.has(attachmentAtomId)) {
26147
- var _this6$monomerCreatio;
26148
- (_this6$monomerCreatio = _this6.monomerCreationState) === null || _this6$monomerCreatio === void 0 || _this6$monomerCreatio.assignedAttachmentPoints["delete"](attachmentPointName);
26186
+ var _this8$monomerCreatio;
26187
+ (_this8$monomerCreatio = _this8.monomerCreationState) === null || _this8$monomerCreatio === void 0 || _this8$monomerCreatio.assignedAttachmentPoints["delete"](attachmentPointName);
26149
26188
  } else if (ids.has(leavingAtomId)) {
26150
- var potentialLeavingAtoms = _this6.findPotentialLeavingAtoms(attachmentAtomId);
26189
+ var potentialLeavingAtoms = _this8.findPotentialLeavingAtoms(attachmentAtomId);
26151
26190
  if (potentialLeavingAtoms.length === 0) {
26152
- var _this6$monomerCreatio2;
26153
- (_this6$monomerCreatio2 = _this6.monomerCreationState) === null || _this6$monomerCreatio2 === void 0 || _this6$monomerCreatio2.assignedAttachmentPoints["delete"](attachmentPointName);
26191
+ var _this8$monomerCreatio2;
26192
+ (_this8$monomerCreatio2 = _this8.monomerCreationState) === null || _this8$monomerCreatio2 === void 0 || _this8$monomerCreatio2.assignedAttachmentPoints["delete"](attachmentPointName);
26154
26193
  } else {
26155
- var _this6$monomerCreatio3;
26156
- var newLeavingAtomId = _this6.struct().atoms.keyOf(potentialLeavingAtoms[0]);
26194
+ var _this8$monomerCreatio3;
26195
+ var newLeavingAtomId = _this8.struct().atoms.keyOf(potentialLeavingAtoms[0]);
26157
26196
  assert_1(newLeavingAtomId !== null);
26158
- (_this6$monomerCreatio3 = _this6.monomerCreationState) === null || _this6$monomerCreatio3 === void 0 || _this6$monomerCreatio3.assignedAttachmentPoints.set(attachmentPointName, [attachmentAtomId, newLeavingAtomId]);
26197
+ (_this8$monomerCreatio3 = _this8.monomerCreationState) === null || _this8$monomerCreatio3 === void 0 || _this8$monomerCreatio3.assignedAttachmentPoints.set(attachmentPointName, [attachmentAtomId, newLeavingAtomId]);
26198
+ }
26199
+ }
26200
+ });
26201
+ var potentialAttachmentPointsToInvalidate = Array.from(_this8.monomerCreationState.potentialAttachmentPoints.entries());
26202
+ potentialAttachmentPointsToInvalidate.forEach(function (_ref17) {
26203
+ var _ref18 = _slicedToArray$1(_ref17, 2),
26204
+ attachmentAtomId = _ref18[0],
26205
+ leavingAtomIds = _ref18[1];
26206
+ if (ids.has(attachmentAtomId)) {
26207
+ var _this8$monomerCreatio4;
26208
+ (_this8$monomerCreatio4 = _this8.monomerCreationState) === null || _this8$monomerCreatio4 === void 0 || _this8$monomerCreatio4.potentialAttachmentPoints["delete"](attachmentAtomId);
26209
+ } else {
26210
+ var updatedLeavingAtomIds = new Set(Array.from(leavingAtomIds).filter(function (id) {
26211
+ return !ids.has(id);
26212
+ }));
26213
+ if (updatedLeavingAtomIds.size === 0) {
26214
+ var _this8$monomerCreatio5;
26215
+ (_this8$monomerCreatio5 = _this8.monomerCreationState) === null || _this8$monomerCreatio5 === void 0 || _this8$monomerCreatio5.potentialAttachmentPoints["delete"](attachmentAtomId);
26216
+ } else {
26217
+ var _this8$monomerCreatio6;
26218
+ (_this8$monomerCreatio6 = _this8.monomerCreationState) === null || _this8$monomerCreatio6 === void 0 || _this8$monomerCreatio6.potentialAttachmentPoints.set(attachmentAtomId, updatedLeavingAtomIds);
26159
26219
  }
26160
26220
  }
26161
26221
  });
@@ -26168,24 +26228,40 @@ var Editor$3 = function () {
26168
26228
  try {
26169
26229
  var _loop2 = function _loop2() {
26170
26230
  var id = _step3.value;
26171
- var bond = _this6.struct().bonds.get(id);
26231
+ var bond = _this8.struct().bonds.get(id);
26172
26232
  assert_1(bond);
26173
- var attachmentPointWithBond = Array.from(_this6.monomerCreationState.assignedAttachmentPoints.entries()).find(function (_ref17) {
26174
- var _ref18 = _slicedToArray$1(_ref17, 2),
26175
- atomPair = _ref18[1];
26233
+ var attachmentPointWithBond = Array.from(_this8.monomerCreationState.assignedAttachmentPoints.entries()).find(function (_ref19) {
26234
+ var _ref20 = _slicedToArray$1(_ref19, 2),
26235
+ atomPair = _ref20[1];
26176
26236
  return bond.begin === atomPair[0] && bond.end === atomPair[1] || bond.begin === atomPair[1] && bond.end === atomPair[0];
26177
26237
  });
26178
- if (!attachmentPointWithBond) {
26179
- return 1;
26238
+ if (attachmentPointWithBond) {
26239
+ if (bond.type !== Bond$2.PATTERN.TYPE.SINGLE || bond.stereo !== Bond$2.PATTERN.STEREO.NONE) {
26240
+ _this8.monomerCreationState.problematicAttachmentPoints.add(attachmentPointWithBond[0]);
26241
+ } else {
26242
+ _this8.monomerCreationState.problematicAttachmentPoints["delete"](attachmentPointWithBond[0]);
26243
+ }
26180
26244
  }
26181
26245
  if (bond.type !== Bond$2.PATTERN.TYPE.SINGLE || bond.stereo !== Bond$2.PATTERN.STEREO.NONE) {
26182
- _this6.monomerCreationState.problematicAttachmentPoints.add(attachmentPointWithBond[0]);
26183
- } else {
26184
- _this6.monomerCreationState.problematicAttachmentPoints["delete"](attachmentPointWithBond[0]);
26246
+ _this8.monomerCreationState.potentialAttachmentPoints.forEach(function (leavingAtomIds, attachmentAtomId) {
26247
+ var updatedLeavingAtomIds = new Set(leavingAtomIds);
26248
+ var bondFromAttachmentAtom = bond.begin === attachmentAtomId && leavingAtomIds.has(bond.end);
26249
+ var bondToAttachmentAtom = bond.end === attachmentAtomId && leavingAtomIds.has(bond.begin);
26250
+ if (bondFromAttachmentAtom || bondToAttachmentAtom) {
26251
+ updatedLeavingAtomIds["delete"](bondFromAttachmentAtom ? bond.end : bond.begin);
26252
+ }
26253
+ if (updatedLeavingAtomIds.size === 0) {
26254
+ var _this8$monomerCreatio7;
26255
+ (_this8$monomerCreatio7 = _this8.monomerCreationState) === null || _this8$monomerCreatio7 === void 0 || _this8$monomerCreatio7.potentialAttachmentPoints["delete"](attachmentAtomId);
26256
+ } else {
26257
+ var _this8$monomerCreatio8;
26258
+ (_this8$monomerCreatio8 = _this8.monomerCreationState) === null || _this8$monomerCreatio8 === void 0 || _this8$monomerCreatio8.potentialAttachmentPoints.set(attachmentAtomId, updatedLeavingAtomIds);
26259
+ }
26260
+ });
26185
26261
  }
26186
26262
  };
26187
26263
  for (_iterator3.s(); !(_step3 = _iterator3.n()).done;) {
26188
- if (_loop2()) continue;
26264
+ _loop2();
26189
26265
  }
26190
26266
  } catch (err) {
26191
26267
  _iterator3.e(err);
@@ -26201,23 +26277,44 @@ var Editor$3 = function () {
26201
26277
  try {
26202
26278
  var _loop3 = function _loop3() {
26203
26279
  var id = _step4.value;
26204
- var bond = _this6.struct().bonds.get(id);
26280
+ var bond = _this8.struct().bonds.get(id);
26205
26281
  assert_1(bond);
26206
- var attachmentPointWithBondToLeavingAtom = Array.from(_this6.monomerCreationState.assignedAttachmentPoints.entries()).find(function (_ref19) {
26207
- var _ref20 = _slicedToArray$1(_ref19, 2),
26208
- _ref20$ = _slicedToArray$1(_ref20[1], 2),
26209
- leavingAtomId = _ref20$[1];
26282
+ var attachmentPointWithBondToLeavingAtom = Array.from(_this8.monomerCreationState.assignedAttachmentPoints.entries()).find(function (_ref21) {
26283
+ var _ref22 = _slicedToArray$1(_ref21, 2),
26284
+ _ref22$ = _slicedToArray$1(_ref22[1], 2),
26285
+ leavingAtomId = _ref22$[1];
26210
26286
  return bond.begin === leavingAtomId || bond.end === leavingAtomId;
26211
26287
  });
26212
- if (!attachmentPointWithBondToLeavingAtom) {
26213
- return 1;
26288
+ if (attachmentPointWithBondToLeavingAtom) {
26289
+ var _attachmentPointWithB = _slicedToArray$1(attachmentPointWithBondToLeavingAtom, 1),
26290
+ attachmentPointName = _attachmentPointWithB[0];
26291
+ _this8.monomerCreationState.assignedAttachmentPoints["delete"](attachmentPointName);
26292
+ }
26293
+ if (bond.type === Bond$2.PATTERN.TYPE.SINGLE && bond.stereo === Bond$2.PATTERN.STEREO.NONE) {
26294
+ if (_this8.monomerCreationState.potentialAttachmentPoints.has(bond.begin)) {
26295
+ var leavingAtomIds = _this8.monomerCreationState.potentialAttachmentPoints.get(bond.begin);
26296
+ assert_1(leavingAtomIds);
26297
+ var endAtom = _this8.struct().atoms.get(bond.end);
26298
+ if (endAtom && endAtom.neighbors.length === 1) {
26299
+ var updatedLeavingAtomIds = new Set(leavingAtomIds);
26300
+ updatedLeavingAtomIds.add(bond.end);
26301
+ _this8.monomerCreationState.potentialAttachmentPoints.set(bond.begin, updatedLeavingAtomIds);
26302
+ }
26303
+ }
26304
+ if (_this8.monomerCreationState.potentialAttachmentPoints.has(bond.end)) {
26305
+ var _leavingAtomIds = _this8.monomerCreationState.potentialAttachmentPoints.get(bond.end);
26306
+ assert_1(_leavingAtomIds);
26307
+ var beginAtom = _this8.struct().atoms.get(bond.begin);
26308
+ if (beginAtom && beginAtom.neighbors.length === 1) {
26309
+ var _updatedLeavingAtomIds = new Set(_leavingAtomIds);
26310
+ _updatedLeavingAtomIds.add(bond.begin);
26311
+ _this8.monomerCreationState.potentialAttachmentPoints.set(bond.end, _updatedLeavingAtomIds);
26312
+ }
26313
+ }
26214
26314
  }
26215
- var _attachmentPointWithB = _slicedToArray$1(attachmentPointWithBondToLeavingAtom, 1),
26216
- attachmentPointName = _attachmentPointWithB[0];
26217
- _this6.monomerCreationState.assignedAttachmentPoints["delete"](attachmentPointName);
26218
26315
  };
26219
26316
  for (_iterator4.s(); !(_step4 = _iterator4.n()).done;) {
26220
- if (_loop3()) continue;
26317
+ _loop3();
26221
26318
  }
26222
26319
  } catch (err) {
26223
26320
  _iterator4.e(err);
@@ -26592,6 +26689,17 @@ var Editor$3 = function () {
26592
26689
  }
26593
26690
  return visited.size === atomIds.length;
26594
26691
  }
26692
+ }, {
26693
+ key: "isStructureImpure",
26694
+ value: function isStructureImpure(struct) {
26695
+ var atoms = struct.atoms,
26696
+ sgroups = struct.sgroups,
26697
+ rgroups = struct.rgroups,
26698
+ functionalGroups = struct.functionalGroups;
26699
+ return sgroups.size > 0 || rgroups.size > 0 || functionalGroups.size > 0 || Array.from(atoms.values()).some(function (atom) {
26700
+ return genericsList.includes(atom.label);
26701
+ });
26702
+ }
26595
26703
  }]);
26596
26704
  return Editor;
26597
26705
  }();
@@ -26667,10 +26775,10 @@ function domEventSetup(editor, clientArea) {
26667
26775
  eventName: 'mouseover',
26668
26776
  toolEventHandler: 'mouseover'
26669
26777
  }];
26670
- trackedDomEvents.forEach(function (_ref21) {
26671
- var target = _ref21.target,
26672
- eventName = _ref21.eventName,
26673
- toolEventHandler = _ref21.toolEventHandler;
26778
+ trackedDomEvents.forEach(function (_ref23) {
26779
+ var target = _ref23.target,
26780
+ eventName = _ref23.eventName,
26781
+ toolEventHandler = _ref23.toolEventHandler;
26674
26782
  editor.event[eventName] = new DOMSubscription();
26675
26783
  var subs = editor.event[eventName];
26676
26784
  target.addEventListener(eventName, function () {
@@ -27832,6 +27940,10 @@ var useCreateMonomer = function useCreateMonomer() {
27832
27940
  return [handler, disabled];
27833
27941
  };
27834
27942
 
27943
+ var optionsSelector = function optionsSelector(state) {
27944
+ return state.options;
27945
+ };
27946
+
27835
27947
  function ownKeys$O(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
27836
27948
  function _objectSpread$O(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$O(Object(t), !0).forEach(function (r) { _defineProperty$1(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$O(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
27837
27949
  var bondNames = getBondNames(tools);
@@ -27872,6 +27984,7 @@ var SelectionMenuItems = function SelectionMenuItems(props) {
27872
27984
  color: color === '' ? 'transparent' : color
27873
27985
  });
27874
27986
  };
27987
+ var options = useSelector(optionsSelector);
27875
27988
  return jsxs(Fragment, {
27876
27989
  children: [jsx(Item, _objectSpread$O(_objectSpread$O({}, props), {}, {
27877
27990
  "data-testid": "Edit selected bonds...-option",
@@ -27901,7 +28014,7 @@ var SelectionMenuItems = function SelectionMenuItems(props) {
27901
28014
  })]
27902
28015
  }, name);
27903
28016
  })
27904
- })), jsx(Item, _objectSpread$O(_objectSpread$O({}, props), {}, {
28017
+ })), !isHidden(options, CREATE_MONOMER_TOOL_NAME) && jsx(Item, _objectSpread$O(_objectSpread$O({}, props), {}, {
27905
28018
  "data-testid": "Create a monomer-option",
27906
28019
  onClick: handleCreateMonomer,
27907
28020
  disabled: createMonomerDisabled,
@@ -29376,9 +29489,11 @@ var useAttachmentPointSelectsData = function useAttachmentPointSelectsData(edito
29376
29489
  leavingAtomId = _atomPair[1];
29377
29490
  var attachmentAtom = editor.struct().atoms.get(attachmentAtomId);
29378
29491
  assert_1(attachmentAtom);
29379
- var attachmentPointNameOptionsLength = Math.max.apply(Math, _toConsumableArray(Array.from(assignedAttachmentPoints.keys()).map(function (name) {
29492
+ var usedNumbers = Array.from(assignedAttachmentPoints.keys()).map(function (name) {
29380
29493
  return getAttachmentPointNumberFromLabel(name);
29381
- })));
29494
+ });
29495
+ var maxUsedNumber = Math.max.apply(Math, _toConsumableArray(usedNumbers));
29496
+ var attachmentPointNameOptionsLength = maxUsedNumber <= 3 ? 3 : Math.min(maxUsedNumber, 8);
29382
29497
  var nameOptions = Array.from({
29383
29498
  length: attachmentPointNameOptionsLength
29384
29499
  }).map(function (_, i) {
@@ -29538,7 +29653,9 @@ var NotificationMessages = {
29538
29653
  noAttachmentPoints: 'The monomer must have at least one attachment point.',
29539
29654
  incorrectAttachmentPointsOrder: 'Attachment point numbers must be in order, but R1 and R2 may be skipped.',
29540
29655
  creationSuccessful: 'The monomer was successfully added to the library.',
29541
- incontinuousStructure: 'All monomers must have a continuous structure.'
29656
+ incontinuousStructure: 'All monomers must have a continuous structure.',
29657
+ notMinimalViableStructure: 'Minimal monomer structure is two atoms connected via a single bond.',
29658
+ impureStructure: 'Monomer structure cannot contain S-groups, R-groups, special atoms, or any other query properties.'
29542
29659
  };
29543
29660
  var NotificationTypes = {
29544
29661
  defaultAttachmentPoints: 'info',
@@ -29549,7 +29666,9 @@ var NotificationTypes = {
29549
29666
  noAttachmentPoints: 'error',
29550
29667
  incorrectAttachmentPointsOrder: 'error',
29551
29668
  creationSuccessful: 'info',
29552
- incontinuousStructure: 'error'
29669
+ incontinuousStructure: 'error',
29670
+ notMinimalViableStructure: 'error',
29671
+ impureStructure: 'error'
29553
29672
  };
29554
29673
  var MonomerCreationExternalNotificationAction = 'MonomerCreationExternalNotification';
29555
29674
 
@@ -29804,6 +29923,21 @@ var validateAttachmentPoints = function validateAttachmentPoints(attachmentPoint
29804
29923
  };
29805
29924
  var validateStructure = function validateStructure(editor) {
29806
29925
  var notifications = new Map();
29926
+ var isStructureImpure = Editor$3.isStructureImpure(editor.struct());
29927
+ if (isStructureImpure) {
29928
+ notifications.set('impureStructure', {
29929
+ type: 'error',
29930
+ message: NotificationMessages.impureStructure
29931
+ });
29932
+ }
29933
+ var isMinimalViableStructure = editor.isMinimalViableStructure();
29934
+ if (!isMinimalViableStructure) {
29935
+ notifications.set('notMinimalViableStructure', {
29936
+ type: 'error',
29937
+ message: NotificationMessages.notMinimalViableStructure
29938
+ });
29939
+ return notifications;
29940
+ }
29807
29941
  var isStructureContinuous = Editor$3.isStructureContinuous(editor.struct());
29808
29942
  if (!isStructureContinuous) {
29809
29943
  notifications.set('incontinuousStructure', {
@@ -36641,6 +36775,11 @@ var TemplateDialog = function TemplateDialog(props) {
36641
36775
  onTabChange(initialTab);
36642
36776
  }
36643
36777
  }, [initialTab, onTabChange]);
36778
+ useEffect(function () {
36779
+ if (isMonomerCreationWizardActive && tab === TemplateTabs.FunctionalGroupLibrary) {
36780
+ onTabChange(TemplateTabs.TemplateLibrary);
36781
+ }
36782
+ }, [isMonomerCreationWizardActive, tab, onTabChange]);
36644
36783
  var handleAccordionChange = function handleAccordionChange(accordion) {
36645
36784
  return function (_, isExpanded) {
36646
36785
  setExpandedAccordions(isExpanded ? [].concat(_toConsumableArray(expandedAccordions), [accordion]) : _toConsumableArray(expandedAccordions).filter(function (expandedAccordion) {
@@ -37848,12 +37987,12 @@ var AbbreviationLookup = function AbbreviationLookup(_ref) {
37848
37987
  });
37849
37988
  },
37850
37989
  renderOption: function renderOption(props, option) {
37851
- return jsx("li", _objectSpread$2(_objectSpread$2({}, props), {}, {
37990
+ return createElement("li", _objectSpread$2(_objectSpread$2({}, props), {}, {
37852
37991
  title: option.label,
37853
- children: jsx("div", {
37854
- className: classes.optionItemContent,
37855
- children: highlightOptionLabel(option, loweredLookupValue)
37856
- })
37992
+ key: option.label
37993
+ }), jsx("div", {
37994
+ className: classes.optionItemContent,
37995
+ children: highlightOptionLabel(option, loweredLookupValue)
37857
37996
  }));
37858
37997
  },
37859
37998
  "data-testid": ABBREVIATION_LOOKUP_TEST_ID
@@ -38131,8 +38270,8 @@ var KetcherBuilder = function () {
38131
38270
  cleanup = initApp(prevKetcherId, ketcherId, element, appRoot, staticResourcesUrl, {
38132
38271
  buttons: buttons || {},
38133
38272
  errorHandler: errorHandler || null,
38134
- version: "3.9.0-rc.1" ,
38135
- buildDate: "2025-10-02T16:45:46" ,
38273
+ version: "3.9.0-rc.3" ,
38274
+ buildDate: "2025-10-22T18:27:52" ,
38136
38275
  buildNumber: '',
38137
38276
  customButtons: customButtons || []
38138
38277
  }, structService, resolve, togglerComponent);
@@ -38427,7 +38566,7 @@ var ModeControl = function ModeControl(_ref3) {
38427
38566
  function ownKeys(e, r) { var t = Object.keys(e); if (Object.getOwnPropertySymbols) { var o = Object.getOwnPropertySymbols(e); r && (o = o.filter(function (r) { return Object.getOwnPropertyDescriptor(e, r).enumerable; })), t.push.apply(t, o); } return t; }
38428
38567
  function _objectSpread(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys(Object(t), !0).forEach(function (r) { _defineProperty$1(e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
38429
38568
  var MacromoleculesEditorComponent = lazy(function () {
38430
- return import('./index.modern-dbbd94e2.js');
38569
+ return import('./index.modern-ef47c610.js');
38431
38570
  });
38432
38571
  var Editor = function Editor(props) {
38433
38572
  var _useState = useState(false),