ketcher-react 2.23.0-rc.2 → 2.24.0-rc.1

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
@@ -79,7 +79,7 @@ require('draft-js/dist/Draft.css');
79
79
  var draftJs = require('draft-js');
80
80
  var createStyles = require('draft-js-custom-styles');
81
81
  var _objectDestructuringEmpty = require('@babel/runtime/helpers/objectDestructuringEmpty');
82
- var _extends$3j = require('@babel/runtime/helpers/extends');
82
+ var _extends$3k = require('@babel/runtime/helpers/extends');
83
83
  var MuiAutocomplete = require('@mui/material/Autocomplete');
84
84
  var client = require('react-dom/client');
85
85
 
@@ -142,10 +142,11 @@ var Tabs__default = /*#__PURE__*/_interopDefaultLegacy(Tabs$1);
142
142
  var Tab__default = /*#__PURE__*/_interopDefaultLegacy(Tab);
143
143
  var createStyles__default = /*#__PURE__*/_interopDefaultLegacy(createStyles);
144
144
  var _objectDestructuringEmpty__default = /*#__PURE__*/_interopDefaultLegacy(_objectDestructuringEmpty);
145
- var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends$3j);
145
+ var _extends__default = /*#__PURE__*/_interopDefaultLegacy(_extends$3k);
146
146
  var MuiAutocomplete__default = /*#__PURE__*/_interopDefaultLegacy(MuiAutocomplete);
147
147
 
148
148
  function createApi(structServiceProvider, defaultOptions) {
149
+ var _structService$destro;
149
150
  var structService = structServiceProvider.createStructService(defaultOptions);
150
151
  var info = structService.info();
151
152
  return Object.assign(info, {
@@ -162,7 +163,8 @@ function createApi(structServiceProvider, defaultOptions) {
162
163
  recognize: structService.recognize.bind(structService),
163
164
  generateImageAsBase64: structService.generateImageAsBase64.bind(structService),
164
165
  getInChIKey: structService.getInChIKey.bind(structService),
165
- toggleExplicitHydrogens: structService.toggleExplicitHydrogens.bind(structService)
166
+ toggleExplicitHydrogens: structService.toggleExplicitHydrogens.bind(structService),
167
+ destroy: (_structService$destro = structService.destroy) === null || _structService$destro === void 0 ? void 0 : _structService$destro.bind(structService)
166
168
  });
167
169
  }
168
170
 
@@ -341,7 +343,7 @@ function _unsupportedIterableToArray$g(o, minLen) { if (!o) return; if (typeof o
341
343
  function _arrayLikeToArray$g(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
342
344
  function _callSuper$b(t, o, e) { return o = _getPrototypeOf__default["default"](o), _possibleConstructorReturn__default["default"](t, _isNativeReflectConstruct$d() ? Reflect.construct(o, e || [], _getPrototypeOf__default["default"](t).constructor) : o.apply(t, e)); }
343
345
  function _isNativeReflectConstruct$d() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct$d = function _isNativeReflectConstruct() { return !!t; })(); }
344
- var ieCb = window.clipboardData;
346
+ var ieCb = typeof window !== 'undefined' ? window.clipboardData : {};
345
347
  var CLIP_AREA_BASE_CLASS = 'cliparea';
346
348
  var needSkipCopyEvent = false;
347
349
  var ClipArea = function (_Component) {
@@ -2604,7 +2606,7 @@ function isFlipDisabled(editor) {
2604
2606
  return getAmountOfAttachmentBonds() > 1;
2605
2607
  }
2606
2608
 
2607
- var toolActions = {
2609
+ var toolActions = _defineProperty__default["default"]({
2608
2610
  hand: {
2609
2611
  title: 'Hand tool',
2610
2612
  shortcut: 'Mod+Alt+h',
@@ -3035,7 +3037,15 @@ var toolActions = {
3035
3037
  return isHidden(options, 'bonds');
3036
3038
  }
3037
3039
  }
3038
- };
3040
+ }, ketcherCore.IMAGE_KEY, {
3041
+ title: 'Add Image',
3042
+ action: {
3043
+ tool: ketcherCore.IMAGE_KEY
3044
+ },
3045
+ hidden: function hidden(options) {
3046
+ return isHidden(options, ketcherCore.IMAGE_KEY);
3047
+ }
3048
+ });
3039
3049
  var bondCuts = {
3040
3050
  single: '1',
3041
3051
  "double": '2',
@@ -3394,7 +3404,7 @@ function serverCall(editor, server, method, options, struct) {
3394
3404
  var selectedBonds = [];
3395
3405
  var aidMap = new Map();
3396
3406
  var bidMap = new Map();
3397
- var currentStruct = (struct || editor.struct()).clone(null, null, false, aidMap, null, null, null, bidMap);
3407
+ var currentStruct = (struct || editor.struct()).clone(null, null, false, aidMap, null, null, null, null, bidMap);
3398
3408
  var expSel = editor.explicitSelected();
3399
3409
  if (selection) {
3400
3410
  selectedAtoms = (selection.atoms ? selection.atoms : expSel.atoms).map(function (aid) {
@@ -3660,7 +3670,7 @@ var zoom = {
3660
3670
 
3661
3671
  var openHelpLink = function openHelpLink() {
3662
3672
  var _window$open;
3663
- return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v2.23.0-rc.2\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3673
+ return (_window$open = window.open("https://github.com/epam/ketcher/blob/".concat("v2.24.0-rc.1\n", "/documentation/help.md#ketcher-overview"))) === null || _window$open === void 0 ? void 0 : _window$open.focus();
3664
3674
  };
3665
3675
  var help = {
3666
3676
  help: {
@@ -3688,6 +3698,8 @@ var KETCHER_ROOT_NODE_CLASS_NAME = 'Ketcher-root';
3688
3698
  var KETCHER_ROOT_NODE_CSS_SELECTOR = ".".concat(KETCHER_ROOT_NODE_CLASS_NAME);
3689
3699
  var EditorClassName = 'Ketcher-polymer-editor-root';
3690
3700
  var KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR = ".".concat(EditorClassName);
3701
+ var STRUCT_SERVICE_NO_RENDER_INITIALIZED_EVENT = 'struct-service-no-render-initialized';
3702
+ var STRUCT_SERVICE_INITIALIZED_EVENT = 'struct-service-initialized';
3691
3703
 
3692
3704
  var functionalGroupsLib = {
3693
3705
  'functional-groups': {
@@ -4048,16 +4060,16 @@ function hasSelection(editor) {
4048
4060
 
4049
4061
  var classes$Q = {"button-common-styles":"ActionButton-module_button-common-styles__y-hng","scrollbar":"ActionButton-module_scrollbar__lD3MH","button":"ActionButton-module_button__nfoWQ","selected":"ActionButton-module_selected__kPCxA"};
4050
4062
 
4051
- var _path$3c, _rect$4, _rect2$3;
4052
- function _extends$3i() { _extends$3i = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3i.apply(this, arguments); }
4063
+ var _path$3d, _rect$4, _rect2$3;
4064
+ function _extends$3j() { _extends$3j = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3j.apply(this, arguments); }
4053
4065
  function SvgAbout(props) {
4054
- return /*#__PURE__*/React__namespace.createElement("svg", _extends$3i({
4066
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$3j({
4055
4067
  width: 24,
4056
4068
  height: 24,
4057
4069
  viewBox: "0 0 24 24",
4058
4070
  fill: "none",
4059
4071
  xmlns: "http://www.w3.org/2000/svg"
4060
- }, props), _path$3c || (_path$3c = /*#__PURE__*/React__namespace.createElement("path", {
4072
+ }, props), _path$3d || (_path$3d = /*#__PURE__*/React__namespace.createElement("path", {
4061
4073
  d: "M12 4.5a7.5 7.5 0 100 15 7.5 7.5 0 000-15zM12 18c-3.307 0-6-2.693-6-6s2.693-6 6-6 6 2.693 6 6-2.693 6-6 6z",
4062
4074
  fill: "currentcolor"
4063
4075
  })), _rect$4 || (_rect$4 = /*#__PURE__*/React__namespace.createElement("rect", {
@@ -4077,6 +4089,20 @@ function SvgAbout(props) {
4077
4089
  })));
4078
4090
  }
4079
4091
 
4092
+ var _path$3c;
4093
+ function _extends$3i() { _extends$3i = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3i.apply(this, arguments); }
4094
+ function SvgAddImage(props) {
4095
+ return /*#__PURE__*/React__namespace.createElement("svg", _extends$3i({
4096
+ width: 16,
4097
+ height: 16,
4098
+ viewBox: "0 0 16 16",
4099
+ xmlns: "http://www.w3.org/2000/svg"
4100
+ }, props), _path$3c || (_path$3c = /*#__PURE__*/React__namespace.createElement("path", {
4101
+ d: "M12.19 14.476H1.524V3.81H8.38V2.286H1.524C.686 2.286 0 2.97 0 3.81v10.666C0 15.314.686 16 1.524 16H12.19c.839 0 1.524-.686 1.524-1.524V7.62H12.19v6.857zm-5.935-2.415l-1.493-1.798-2.095 2.69h8.38L8.35 9.362l-2.095 2.698zm7.46-9.775V0H12.19v2.286H9.905c.007.007 0 1.524 0 1.524h2.286v2.278c.007.007 1.523 0 1.523 0V3.81H16V2.286h-2.286z",
4102
+ fill: "currentColor"
4103
+ })));
4104
+ }
4105
+
4080
4106
  var _path$3b;
4081
4107
  function _extends$3h() { _extends$3h = Object.assign ? Object.assign.bind() : function (target) { for (var i = 1; i < arguments.length; i++) { var source = arguments[i]; for (var key in source) { if (Object.prototype.hasOwnProperty.call(source, key)) { target[key] = source[key]; } } } return target; }; return _extends$3h.apply(this, arguments); }
4082
4108
  function SvgAnalyse(props) {
@@ -7648,7 +7674,8 @@ function SvgNucleotide(props) {
7648
7674
  })));
7649
7675
  }
7650
7676
 
7651
- var iconNameToIcon = {
7677
+ var _iconNameToIcon;
7678
+ var iconNameToIcon = (_iconNameToIcon = {
7652
7679
  α: Svg$n,
7653
7680
  β: Svg$m,
7654
7681
  γ: Svg$l,
@@ -7800,67 +7827,8 @@ var iconNameToIcon = {
7800
7827
  'template-dialog': SvgTemplateDialog,
7801
7828
  'template-lib': SvgTemplateLib,
7802
7829
  'snake-mode': SvgSnakeMode,
7803
- text: SvgText,
7804
- 'text-bold': SvgTextBold,
7805
- 'text-italic': SvgTextItalic,
7806
- 'text-subscript': SvgTextSubscript,
7807
- 'text-superscript': SvgTextSuperscript,
7808
- 'transform-flip-h': SvgTransformFlipH,
7809
- 'transform-flip-v': SvgTransformFlipV,
7810
- undo: SvgUndo,
7811
- 'zoom-in': SvgZoomIn,
7812
- 'zoom-out': SvgZoomOut,
7813
- 'zoom-reset': SvgZoomReset,
7814
- 'shape-ellipse': SvgShapeEllipse,
7815
- 'shape-rectangle': SvgShapeRectangle,
7816
- 'shape-polyline': SvgShapePolyline,
7817
- 'shape-line': SvgShapeLine,
7818
- 'not-found': SvgNotFound,
7819
- 'save-1': SvgSave1,
7820
- 'open-1': SvgOpen1,
7821
- reset: SvgReset,
7822
- close: SvgClose,
7823
- general: SvgGeneral,
7824
- 'general-white': SvgGeneralWhite,
7825
- stereo: SvgStereo,
7826
- 'stereo-white': SvgStereoWhite,
7827
- atoms: SvgAtoms,
7828
- 'atoms-white': SvgAtomsWhite,
7829
- bonds: SvgBonds,
7830
- 'bonds-white': SvgBondsWhite,
7831
- server: SvgServer,
7832
- 'server-white': SvgServerWhite,
7833
- '3dviewer': Svg3D,
7834
- '3dviewer-white': Svg3DWhite,
7835
- debugging: SvgDebugging,
7836
- 'debugging-white': SvgDebuggingWhite,
7837
- 'dropdown-indicator': SvgDropdownIndicator,
7838
- 'text-special-symbols': SvgTextSpecialSymbols,
7839
- chevron: SvgChevron,
7840
- 'open-window-paste-icon': SvgOpenWindowPasteIcon,
7841
- 'open-window-upload-icon': SvgOpenWindowUploadIcon,
7842
- bracket: SvgBracket,
7843
- error: SvgError,
7844
- 'rap-left-link': SvgRapLeftLink,
7845
- 'rap-middle-link': SvgRapMiddleLink,
7846
- 'rap-right-link': SvgRapRightLink,
7847
- 'arrows-left': SvgArrowsLeft,
7848
- 'arrows-right': SvgArrowsRight,
7849
- sugar: SvgSugar,
7850
- base: SvgBase,
7851
- phosphate: SvgPhosphate,
7852
- preset: SvgPreset,
7853
- nucleotide: SvgNucleotide,
7854
- 'edit-filled': SvgEditFilled,
7855
- 'vertical-dots': SvgVerticalDots,
7856
- expand: SvgExpand,
7857
- 'minimize-expansion': SvgMinimizeExpantion,
7858
- 'explicit-hydrogens': SvgExplicitHydrogens,
7859
- 'flex-layout-mode': SvgFlexLayoutMode,
7860
- 'snake-layout-mode': SvgSnakeLayoutMode,
7861
- 'sequence-layout-mode': SvgSequenceLayoutMode,
7862
- questionMark: SvgQuestionMark
7863
- };
7830
+ text: SvgText
7831
+ }, _defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_iconNameToIcon, ketcherCore.IMAGE_KEY, SvgAddImage), 'text-bold', SvgTextBold), 'text-italic', SvgTextItalic), 'text-subscript', SvgTextSubscript), 'text-superscript', SvgTextSuperscript), 'transform-flip-h', SvgTransformFlipH), 'transform-flip-v', SvgTransformFlipV), "undo", SvgUndo), 'zoom-in', SvgZoomIn), 'zoom-out', SvgZoomOut), _defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_iconNameToIcon, 'zoom-reset', SvgZoomReset), 'shape-ellipse', SvgShapeEllipse), 'shape-rectangle', SvgShapeRectangle), 'shape-polyline', SvgShapePolyline), 'shape-line', SvgShapeLine), 'not-found', SvgNotFound), 'save-1', SvgSave1), 'open-1', SvgOpen1), "reset", SvgReset), "close", SvgClose), _defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_iconNameToIcon, "general", SvgGeneral), 'general-white', SvgGeneralWhite), "stereo", SvgStereo), 'stereo-white', SvgStereoWhite), "atoms", SvgAtoms), 'atoms-white', SvgAtomsWhite), "bonds", SvgBonds), 'bonds-white', SvgBondsWhite), "server", SvgServer), 'server-white', SvgServerWhite), _defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_iconNameToIcon, '3dviewer', Svg3D), '3dviewer-white', Svg3DWhite), "debugging", SvgDebugging), 'debugging-white', SvgDebuggingWhite), 'dropdown-indicator', SvgDropdownIndicator), 'text-special-symbols', SvgTextSpecialSymbols), "chevron", SvgChevron), 'open-window-paste-icon', SvgOpenWindowPasteIcon), 'open-window-upload-icon', SvgOpenWindowUploadIcon), "bracket", SvgBracket), _defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_iconNameToIcon, "error", SvgError), 'rap-left-link', SvgRapLeftLink), 'rap-middle-link', SvgRapMiddleLink), 'rap-right-link', SvgRapRightLink), 'arrows-left', SvgArrowsLeft), 'arrows-right', SvgArrowsRight), "sugar", SvgSugar), "base", SvgBase), "phosphate", SvgPhosphate), "preset", SvgPreset), _defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_defineProperty__default["default"](_iconNameToIcon, "nucleotide", SvgNucleotide), 'edit-filled', SvgEditFilled), 'vertical-dots', SvgVerticalDots), "expand", SvgExpand), 'minimize-expansion', SvgMinimizeExpantion), 'explicit-hydrogens', SvgExplicitHydrogens), 'flex-layout-mode', SvgFlexLayoutMode), 'snake-layout-mode', SvgSnakeLayoutMode), 'sequence-layout-mode', SvgSequenceLayoutMode), "questionMark", SvgQuestionMark));
7864
7832
 
7865
7833
  var getIconByName = function getIconByName(name) {
7866
7834
  return iconNameToIcon[name];
@@ -14089,6 +14057,7 @@ var _excluded$t = ["type"],
14089
14057
  _excluded2$5 = ["buttons"];
14090
14058
  function ownKeys$12(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; }
14091
14059
  function _objectSpread$12(e) { for (var r = 1; r < arguments.length; r++) { var t = null != arguments[r] ? arguments[r] : {}; r % 2 ? ownKeys$12(Object(t), !0).forEach(function (r) { _defineProperty__default["default"](e, r, t[r]); }) : Object.getOwnPropertyDescriptors ? Object.defineProperties(e, Object.getOwnPropertyDescriptors(t)) : ownKeys$12(Object(t)).forEach(function (r) { Object.defineProperty(e, r, Object.getOwnPropertyDescriptor(t, r)); }); } return e; }
14060
+ var SET_SERVER = 'SET_SERVER';
14092
14061
  var shared = redux.combineReducers({
14093
14062
  common: commonReducer,
14094
14063
  actionState: actionStateReducer,
@@ -14123,6 +14092,12 @@ function getRootReducer(setEditor) {
14123
14092
  var data = _objectWithoutProperties__default["default"](action, _excluded$t);
14124
14093
  if (data) state = _objectSpread$12(_objectSpread$12({}, state), data);
14125
14094
  }
14095
+ case SET_SERVER:
14096
+ {
14097
+ state = _objectSpread$12(_objectSpread$12({}, state), {}, {
14098
+ server: action.server || state.server
14099
+ });
14100
+ }
14126
14101
  }
14127
14102
  var sh = shared(state, _objectSpread$12(_objectSpread$12({}, action), fp.pick(['editor', 'server', 'options'], state)));
14128
14103
  var finalState = sh === state.shared ? state : _objectSpread$12(_objectSpread$12({}, state), sh);
@@ -14149,6 +14124,12 @@ function createStore (options, server, setEditor) {
14149
14124
  var rootReducer = getRootReducer(setEditor);
14150
14125
  return redux.createStore(rootReducer, initState, redux.applyMiddleware.apply(void 0, middleware));
14151
14126
  }
14127
+ function setServer(server) {
14128
+ return {
14129
+ type: SET_SERVER,
14130
+ server: server
14131
+ };
14132
+ }
14152
14133
 
14153
14134
  var disableableButtons$3 = [];
14154
14135
  var mapStateToProps$l = function mapStateToProps(state) {
@@ -14575,6 +14556,8 @@ var LeftToolbar = function LeftToolbar(props) {
14575
14556
  options: shapeOptions
14576
14557
  }, {
14577
14558
  id: 'text'
14559
+ }, {
14560
+ id: ketcherCore.IMAGE_KEY
14578
14561
  }]
14579
14562
  })
14580
14563
  })]
@@ -15712,11 +15695,17 @@ function getElementsInRectangle(restruct, p0, p1) {
15712
15695
  var x1 = Math.max(p0.x, p1.x);
15713
15696
  var y0 = Math.min(p0.y, p1.y);
15714
15697
  var y1 = Math.max(p0.y, p1.y);
15698
+ var topLeftPosition = new ketcherCore.Vec2(x0, y0);
15699
+ var topRightPosition = new ketcherCore.Vec2(x1, y0);
15700
+ var bottomRightPosition = new ketcherCore.Vec2(x1, y1);
15701
+ var bottomLeftPosition = new ketcherCore.Vec2(x0, y1);
15715
15702
  restruct.bonds.forEach(function (bond, bid) {
15716
15703
  if (struct.isBondFromMacromolecule(bid)) {
15717
15704
  return;
15718
15705
  }
15719
- var centre = ketcherCore.Vec2.lc2(restruct.atoms.get(bond.b.begin).a.pp, 0.5, restruct.atoms.get(bond.b.end).a.pp, 0.5);
15706
+ var centre = ketcherCore.Vec2.lc2(
15707
+ restruct.atoms.get(bond.b.begin).a.pp, 0.5,
15708
+ restruct.atoms.get(bond.b.end).a.pp, 0.5);
15720
15709
  if (centre.x > x0 && centre.x < x1 && centre.y > y0 && centre.y < y1 && !ketcherCore.FunctionalGroup.isBondInContractedFunctionalGroup(bond.b, sGroups, functionalGroups)) {
15721
15710
  bondList.push(bid);
15722
15711
  }
@@ -15724,7 +15713,8 @@ function getElementsInRectangle(restruct, p0, p1) {
15724
15713
  restruct.atoms.forEach(function (atom, aid) {
15725
15714
  var relatedFGId = ketcherCore.FunctionalGroup.findFunctionalGroupByAtom(functionalGroups, aid);
15726
15715
  var reSGroup = restruct.sgroups.get(relatedFGId);
15727
- if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof ketcherCore.MonomerMicromolecule) && atom.a.pp.x > x0 && atom.a.pp.x < x1 && atom.a.pp.y > y0 && atom.a.pp.y < y1 && (!ketcherCore.FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) || aid === reSGroup.item.atoms[0])) {
15716
+ if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof ketcherCore.MonomerMicromolecule) && atom.a.pp.x > x0 && atom.a.pp.x < x1 && atom.a.pp.y > y0 && atom.a.pp.y < y1 && (!ketcherCore.FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) ||
15717
+ aid === reSGroup.item.atoms[0])) {
15728
15718
  atomList.push(aid);
15729
15719
  }
15730
15720
  });
@@ -15779,7 +15769,18 @@ function getElementsInRectangle(restruct, p0, p1) {
15779
15769
  rgroupAttachmentPointList.push(id);
15780
15770
  }
15781
15771
  });
15782
- return {
15772
+ var reImages = Array.from(restruct.images.entries()).reduce(function (acc, _ref) {
15773
+ var _ref2 = _slicedToArray__default["default"](_ref, 2),
15774
+ id = _ref2[0],
15775
+ item = _ref2[1];
15776
+ if (Object.values(item.image.getReferencePositions()).some(function (point) {
15777
+ return point.isInsidePolygon([topLeftPosition, topRightPosition, bottomRightPosition, bottomLeftPosition]);
15778
+ })) {
15779
+ return acc.concat(id);
15780
+ }
15781
+ return acc;
15782
+ }, []);
15783
+ return _defineProperty__default["default"]({
15783
15784
  atoms: atomList,
15784
15785
  bonds: bondList,
15785
15786
  rxnArrows: rxnArrowsList,
@@ -15789,7 +15790,7 @@ function getElementsInRectangle(restruct, p0, p1) {
15789
15790
  simpleObjects: simpleObjectsList,
15790
15791
  texts: textsList,
15791
15792
  rgroupAttachmentPoints: rgroupAttachmentPointList
15792
- };
15793
+ }, ketcherCore.IMAGE_KEY, reImages);
15793
15794
  }
15794
15795
  function getElementsInPolygon(restruct, rr) {
15795
15796
  var bondList = [];
@@ -15805,7 +15806,9 @@ function getElementsInPolygon(restruct, rr) {
15805
15806
  if (struct.isAtomFromMacromolecule(bond.b.begin) || struct.isAtomFromMacromolecule(bond.b.end)) {
15806
15807
  return;
15807
15808
  }
15808
- var centre = ketcherCore.Vec2.lc2(restruct.atoms.get(bond.b.begin).a.pp, 0.5, restruct.atoms.get(bond.b.end).a.pp, 0.5);
15809
+ var centre = ketcherCore.Vec2.lc2(
15810
+ restruct.atoms.get(bond.b.begin).a.pp, 0.5,
15811
+ restruct.atoms.get(bond.b.end).a.pp, 0.5);
15809
15812
  if (isPointInPolygon(r, centre) && !ketcherCore.FunctionalGroup.isBondInContractedFunctionalGroup(bond.b, sGroups, functionalGroups)) {
15810
15813
  bondList.push(bid);
15811
15814
  }
@@ -15813,7 +15816,8 @@ function getElementsInPolygon(restruct, rr) {
15813
15816
  restruct.atoms.forEach(function (atom, aid) {
15814
15817
  var relatedFGId = ketcherCore.FunctionalGroup.findFunctionalGroupByAtom(functionalGroups, aid);
15815
15818
  var reSGroup = restruct.sgroups.get(relatedFGId);
15816
- if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof ketcherCore.MonomerMicromolecule) && isPointInPolygon(r, atom.a.pp) && (!ketcherCore.FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) || aid === reSGroup.item.atoms[0])) {
15819
+ if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof ketcherCore.MonomerMicromolecule) && isPointInPolygon(r, atom.a.pp) && (!ketcherCore.FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) ||
15820
+ aid === reSGroup.item.atoms[0])) {
15817
15821
  atomList.push(aid);
15818
15822
  }
15819
15823
  });
@@ -15822,7 +15826,7 @@ function getElementsInPolygon(restruct, rr) {
15822
15826
  var simpleObjectsList = [];
15823
15827
  var textsList = [];
15824
15828
  restruct.rxnArrows.forEach(function (item, id) {
15825
- var referencePoints = item.getReferencePoints(true);
15829
+ var referencePoints = item.getReferencePoints();
15826
15830
  var referencePointInPolygon = referencePoints.find(function (point) {
15827
15831
  return isPointInPolygon(r, point);
15828
15832
  });
@@ -15871,7 +15875,18 @@ function getElementsInPolygon(restruct, rr) {
15871
15875
  rgroupAttachmentPointList.push(id);
15872
15876
  }
15873
15877
  });
15874
- return {
15878
+ var reImages = Array.from(restruct.images.entries()).reduce(function (acc, _ref4) {
15879
+ var _ref5 = _slicedToArray__default["default"](_ref4, 2),
15880
+ id = _ref5[0],
15881
+ item = _ref5[1];
15882
+ if (Object.values(item.image.getReferencePositions()).some(function (point) {
15883
+ return isPointInPolygon(r, point);
15884
+ })) {
15885
+ return acc.concat(id);
15886
+ }
15887
+ return acc;
15888
+ }, []);
15889
+ return _defineProperty__default["default"]({
15875
15890
  atoms: atomList,
15876
15891
  bonds: bondList,
15877
15892
  rxnArrows: rxnArrowsList,
@@ -15881,7 +15896,7 @@ function getElementsInPolygon(restruct, rr) {
15881
15896
  simpleObjects: simpleObjectsList,
15882
15897
  texts: textsList,
15883
15898
  rgroupAttachmentPoints: rgroupAttachmentPointList
15884
- };
15899
+ }, ketcherCore.IMAGE_KEY, reImages);
15885
15900
  }
15886
15901
  function isPointInPolygon(r, p) {
15887
15902
  var d = new ketcherCore.Vec2(0, 1);
@@ -17232,8 +17247,8 @@ function getSelectionMap(structure) {
17232
17247
  return result;
17233
17248
  }, {});
17234
17249
  }
17235
- function getStructCenter(ReStruct, selection) {
17236
- var bb = ReStruct.getVBoxObj(selection || {});
17250
+ function getStructCenter(reStruct, selection) {
17251
+ var bb = reStruct.getVBoxObj(selection || {});
17237
17252
  return ketcherCore.Vec2.lc2(bb.p0, 0.5, bb.p1, 0.5);
17238
17253
  }
17239
17254
 
@@ -17242,7 +17257,7 @@ var handleMovingPosibilityCursor = function handleMovingPosibilityCursor(item, c
17242
17257
  if (!item && isCursorShown) {
17243
17258
  canvas.removeAttribute('cursor');
17244
17259
  }
17245
- if (item && !isCursorShown) {
17260
+ if (item) {
17246
17261
  canvas.setAttribute('cursor', cursor);
17247
17262
  }
17248
17263
  };
@@ -17376,6 +17391,13 @@ var SelectTool = function () {
17376
17391
  info: degrees + 'º'
17377
17392
  });
17378
17393
  }
17394
+ if (dragCtx.item.map === ketcherCore.IMAGE_KEY && dragCtx.item.ref) {
17395
+ if (dragCtx.action) dragCtx.action.perform(rnd.ctab);
17396
+ var position = ketcherCore.CoordinateTransformation.pageToModel(event, rnd);
17397
+ dragCtx.action = ketcherCore.fromImageResize(rnd.ctab, dragCtx.item.id, position, dragCtx.item.ref);
17398
+ editor.update(dragCtx.action, true);
17399
+ return true;
17400
+ }
17379
17401
  if (dragCtx.item.map === 'simpleObjects' && dragCtx.item.ref) {
17380
17402
  if (dragCtx.action) dragCtx.action.perform(rnd.ctab);
17381
17403
  var props = getResizingProps(editor, dragCtx, event);
@@ -17414,7 +17436,13 @@ var SelectTool = function () {
17414
17436
  var maps = getMapsForClosestItem(_classPrivateFieldGet__default["default"](this, _lassoHelper).fragment || event.ctrlKey);
17415
17437
  var item = editor.findItem(event, maps, null);
17416
17438
  editor.hover(item, null, event);
17417
- handleMovingPosibilityCursor(item, this.editor.render.paper.canvas, this.editor.render.options.movingStyle.cursor);
17439
+ if ((item === null || item === void 0 ? void 0 : item.map) === ketcherCore.IMAGE_KEY && item.ref) {
17440
+ var referencePositionInfo = item.ref;
17441
+ handleMovingPosibilityCursor(item, this.editor.render.paper.canvas,
17442
+ ketcherCore.imageReferencePositionToCursor[referencePositionInfo.name]);
17443
+ } else {
17444
+ handleMovingPosibilityCursor(item, this.editor.render.paper.canvas, this.editor.render.options.movingStyle.cursor);
17445
+ }
17418
17446
  return true;
17419
17447
  }
17420
17448
  }, {
@@ -17757,7 +17785,7 @@ function preventSaltAndSolventsMerge(struct, dragCtx, editor) {
17757
17785
  });
17758
17786
  }
17759
17787
  function getMapsForClosestItem(selectFragment) {
17760
- return ['sgroups', 'functionalGroups', 'sgroupData', 'rgroups', 'rgroupAttachmentPoints', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts'].concat(_toConsumableArray__default["default"](selectFragment ? ['frags'] : ['atoms', 'bonds']));
17788
+ return ['sgroups', 'functionalGroups', 'sgroupData', 'rgroups', 'rgroupAttachmentPoints', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts', ketcherCore.IMAGE_KEY].concat(_toConsumableArray__default["default"](selectFragment ? ['frags'] : ['atoms', 'bonds']));
17761
17789
  }
17762
17790
  function getResizingProps(editor, dragCtx, event) {
17763
17791
  var current = editor.render.page2obj(event);
@@ -18830,12 +18858,21 @@ function _isChangingFunctionalGroup() {
18830
18858
  return _isChangingFunctionalGroup.apply(this, arguments);
18831
18859
  }
18832
18860
 
18861
+ var keydownListener = null;
18833
18862
  function initKeydownListener(element) {
18834
18863
  return function (dispatch, getState) {
18835
18864
  var hotKeys = ketcherCore.initHotKeys(config);
18836
- element.addEventListener('keydown', function (event) {
18865
+ keydownListener = function keydownListener(event) {
18837
18866
  return keyHandle(dispatch, getState, hotKeys, event);
18838
- });
18867
+ };
18868
+ element.addEventListener('keydown', keydownListener);
18869
+ };
18870
+ }
18871
+ function removeKeydownListener(element) {
18872
+ return function () {
18873
+ if (keydownListener) {
18874
+ element.removeEventListener('keydown', keydownListener);
18875
+ }
18839
18876
  };
18840
18877
  }
18841
18878
  function removeNotRenderedStruct(actionTool, group, dispatch) {
@@ -19291,7 +19328,7 @@ function _unsupportedIterableToArray$9(o, minLen) { if (!o) return; if (typeof o
19291
19328
  function _arrayLikeToArray$9(arr, len) { if (len == null || len > arr.length) len = arr.length; for (var i = 0, arr2 = new Array(len); i < len; i++) arr2[i] = arr[i]; return arr2; }
19292
19329
  var SELECTION_DISTANCE_COEFFICIENT = 0.4;
19293
19330
  var SELECTION_WITHIN_TEXT = 0;
19294
- var findMaps = {
19331
+ var findMaps = _defineProperty__default["default"]({
19295
19332
  atoms: findClosestAtom,
19296
19333
  bonds: findClosestBond,
19297
19334
  enhancedFlags: findClosestEnhancedFlag,
@@ -19305,15 +19342,15 @@ var findMaps = {
19305
19342
  rgroupAttachmentPoints: findClosestRgroupAttachmentPoints,
19306
19343
  simpleObjects: findClosestSimpleObject,
19307
19344
  texts: findClosestText
19308
- };
19345
+ }, ketcherCore.IMAGE_KEY, findClosestImage);
19309
19346
  function rectangleContainsPoint(startX, startY, width, height, x, y) {
19310
19347
  return startX <= x && x <= startX + width && startY <= y && y <= startY + height;
19311
19348
  }
19312
19349
  function findClosestText(restruct, cursorPosition) {
19313
- var minDist = null;
19350
+ var minDist = Number.POSITIVE_INFINITY;
19314
19351
  var ret = null;
19315
19352
  restruct.texts.forEach(function (text, id) {
19316
- var referencePoints = text.getReferencePoints(restruct);
19353
+ var referencePoints = text.getReferencePoints();
19317
19354
  var topX = referencePoints[0].x;
19318
19355
  var topY = referencePoints[0].y;
19319
19356
  var bottomX = referencePoints[2].x;
@@ -19361,7 +19398,7 @@ function findClosestText(restruct, cursorPosition) {
19361
19398
  return ret;
19362
19399
  }
19363
19400
  function findClosestSimpleObject(restruct, pos) {
19364
- var minDist = null;
19401
+ var minDist = Number.POSITIVE_INFINITY;
19365
19402
  var refPoint = null;
19366
19403
  var ret = null;
19367
19404
  restruct.simpleObjects.forEach(function (simpleObject, id) {
@@ -19388,7 +19425,7 @@ function findClosestAtom(restruct, pos, skip, minDist) {
19388
19425
  minDist = Math.min(minDist, maxMinDist);
19389
19426
  restruct.atoms.forEach(function (atom, aid) {
19390
19427
  if (ketcherCore.FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) || ketcherCore.Atom.isHiddenLeavingGroupAtom(restruct.molecule, aid)) {
19391
- return null;
19428
+ return;
19392
19429
  }
19393
19430
  var isSkippedAtom = aid === skipId || atom.a.isPreview;
19394
19431
  if (isSkippedAtom) {
@@ -19426,7 +19463,7 @@ function findClosestBond(restruct, pos, skip, minDist, options) {
19426
19463
  var p1 = restruct.atoms.get(bond.b.begin).a.pp;
19427
19464
  var p2 = restruct.atoms.get(bond.b.end).a.pp;
19428
19465
  if (ketcherCore.FunctionalGroup.isBondInContractedFunctionalGroup(bond.b, sGroups, functionalGroups) || ketcherCore.SGroup.isBondInContractedSGroup(bond.b, sGroups) || ketcherCore.Bond.isBondToHiddenLeavingGroup(restruct.molecule, bond.b)) {
19429
- return null;
19466
+ return;
19430
19467
  }
19431
19468
  var mid = ketcherCore.Vec2.lc2(p1, 0.5, p2, 0.5);
19432
19469
  var cdist = ketcherCore.Vec2.dist(pos, mid);
@@ -19464,10 +19501,10 @@ function findClosestBond(restruct, pos, skip, minDist, options) {
19464
19501
  }
19465
19502
  return null;
19466
19503
  }
19467
- function findClosestEnhancedFlag(restruct, pos, skip, _minDist, options) {
19504
+ function findClosestEnhancedFlag(restruct, pos, _skip, _minDist, options) {
19468
19505
  var minDist;
19469
19506
  var ret = null;
19470
- restruct.enhancedFlags.forEach(function (item, id) {
19507
+ restruct.enhancedFlags.forEach(function (_item, id) {
19471
19508
  var fragment = restruct.molecule.frags.get(id);
19472
19509
  if (!fragment || !fragment.enhancedStereoFlag || !options.showStereoFlags) return;
19473
19510
  var p = fragment.stereoFlagPosition ? new ketcherCore.Vec2(fragment.stereoFlagPosition.x, fragment.stereoFlagPosition.y) : ketcherCore.Fragment.getDefaultStereoFlagPosition(restruct.molecule, id);
@@ -19484,7 +19521,7 @@ function findClosestEnhancedFlag(restruct, pos, skip, _minDist, options) {
19484
19521
  return ret;
19485
19522
  }
19486
19523
  function findClosestDataSGroupData(restruct, pos) {
19487
- var minDist = null;
19524
+ var minDist = Number.POSITIVE_INFINITY;
19488
19525
  var ret = null;
19489
19526
  restruct.sgroupData.forEach(function (item, id) {
19490
19527
  if (item.sgroup.type !== 'DAT') throw new Error('Data group expected');
@@ -19544,7 +19581,7 @@ function findClosestRgroupAttachmentPoints(restruct, cursorPosition, _skip, minD
19544
19581
  var minDist = minDistToOtherItems !== null && minDistToOtherItems !== void 0 ? minDistToOtherItems : Number.POSITIVE_INFINITY;
19545
19582
  var closestItemId;
19546
19583
  restruct.visibleRGroupAttachmentPoints.forEach(function (reItem, id) {
19547
- var itemOutlinePoints = reItem.getOutlinePoints();
19584
+ var itemOutlinePoints = _toConsumableArray__default["default"](reItem.getOutlinePoints());
19548
19585
  var isCursorInsideOutline = cursorPosition.isInsidePolygon(itemOutlinePoints);
19549
19586
  if (isCursorInsideOutline) {
19550
19587
  var dist = reItem.getDistanceTo(cursorPosition);
@@ -19560,7 +19597,7 @@ function findClosestRgroupAttachmentPoints(restruct, cursorPosition, _skip, minD
19560
19597
  };
19561
19598
  }
19562
19599
  function findClosestRxnArrow(restruct, pos) {
19563
- var minDist = null;
19600
+ var minDist = Number.POSITIVE_INFINITY;
19564
19601
  var refPoint = null;
19565
19602
  var ret = null;
19566
19603
  restruct.rxnArrows.forEach(function (rxnArrow, id) {
@@ -19578,7 +19615,7 @@ function findClosestRxnArrow(restruct, pos) {
19578
19615
  return ret;
19579
19616
  }
19580
19617
  function findClosestRxnPlus(restruct, pos) {
19581
- var minDist = null;
19618
+ var minDist = Number.POSITIVE_INFINITY;
19582
19619
  var ret = null;
19583
19620
  restruct.rxnPluses.forEach(function (plus, id) {
19584
19621
  var p = plus.item.pp;
@@ -19597,7 +19634,7 @@ function findClosestSGroup(restruct, pos) {
19597
19634
  var ret = null;
19598
19635
  var minDist = SELECTION_DISTANCE_COEFFICIENT;
19599
19636
  restruct.molecule.sgroups.forEach(function (sg, sgid) {
19600
- if (sg.isContracted() || sg.isSuperatomWithoutLabel) return null;
19637
+ if (sg.isContracted() || sg.isSuperatomWithoutLabel) return;
19601
19638
  var d = sg.bracketDirection;
19602
19639
  var n = d.rotateSC(1, 0);
19603
19640
  var pg = new ketcherCore.Vec2(ketcherCore.Vec2.dot(pos, d), ketcherCore.Vec2.dot(pos, n));
@@ -19690,7 +19727,9 @@ function findCloseMerge(restruct, selected) {
19690
19727
  });
19691
19728
  selected.bonds.forEach(function (bid) {
19692
19729
  var bond = struct.bonds.get(bid);
19693
- pos.bonds.set(bid, ketcherCore.Vec2.lc2(struct.atoms.get(bond.begin).pp, 0.5, struct.atoms.get(bond.end).pp, 0.5));
19730
+ pos.bonds.set(bid, ketcherCore.Vec2.lc2(
19731
+ struct.atoms.get(bond.begin).pp, 0.5,
19732
+ struct.atoms.get(bond.end).pp, 0.5));
19694
19733
  });
19695
19734
  var result = {
19696
19735
  atoms: new Map(),
@@ -19703,7 +19742,8 @@ function findCloseMerge(restruct, selected) {
19703
19742
  mergeAtomToAtom(atomId, restruct, atomPosition, selected, result) || mergeAtomToFunctionalGroup(atomId, restruct, atomPosition, result);
19704
19743
  });
19705
19744
  } else {
19706
- result[map] = Array.from(pos[map].keys()).reduce(function (res, srcId) {
19745
+ result[map] = Array.from(pos[map].keys()).reduce(
19746
+ function (res, srcId) {
19707
19747
  var skip = {
19708
19748
  map: map,
19709
19749
  id: srcId
@@ -19743,6 +19783,31 @@ function mergeAtomToFunctionalGroup(atomId, restruct, atomPosition, result) {
19743
19783
  }
19744
19784
  return false;
19745
19785
  }
19786
+ function findClosestImage(reStruct, cursorPosition) {
19787
+ var renderOptions = reStruct.render.options;
19788
+ var canvasScaledPosition = ketcherCore.Scale.modelToCanvas(cursorPosition, renderOptions);
19789
+ var maxDistance = renderOptions.microModeScale * SELECTION_DISTANCE_COEFFICIENT;
19790
+ return Array.from(reStruct.images.entries()).reduce(function (acc, _ref) {
19791
+ var _ref2 = _slicedToArray__default["default"](_ref, 2),
19792
+ id = _ref2[0],
19793
+ item = _ref2[1];
19794
+ var distanceToPoint = item.calculateDistanceToPoint(canvasScaledPosition, renderOptions);
19795
+ if (distanceToPoint <= maxDistance) {
19796
+ if (acc && acc.dist < distanceToPoint) {
19797
+ return acc;
19798
+ }
19799
+ var dist = Math.max(distanceToPoint, maxDistance / 3);
19800
+ var closestPosition = item.calculateClosestReferencePosition(canvasScaledPosition, renderOptions);
19801
+ var includeRef = closestPosition.distance < maxDistance;
19802
+ return {
19803
+ id: id,
19804
+ dist: dist / renderOptions.microModeScale,
19805
+ ref: includeRef ? closestPosition.ref : null
19806
+ };
19807
+ }
19808
+ return acc;
19809
+ }, null);
19810
+ }
19746
19811
  var closest = {
19747
19812
  atom: findClosestAtom,
19748
19813
  item: findClosestItem,
@@ -20671,7 +20736,7 @@ var EraserTool = function () {
20671
20736
  function EraserTool(editor, mode) {
20672
20737
  _classCallCheck__default["default"](this, EraserTool);
20673
20738
  this.editor = editor;
20674
- this.maps = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'sgroups', 'functionalGroups', 'sgroupData', 'simpleObjects', 'texts', 'rgroupAttachmentPoints'];
20739
+ this.maps = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'sgroups', 'functionalGroups', 'sgroupData', 'simpleObjects', 'texts', 'rgroupAttachmentPoints', ketcherCore.IMAGE_KEY];
20675
20740
  this.lassoHelper = new LassoHelper(mode || 0, editor, null);
20676
20741
  if (editor.selection()) {
20677
20742
  var action = ketcherCore.fromFragmentDeletion(editor.render.ctab, editor.selection());
@@ -20949,6 +21014,8 @@ var EraserTool = function () {
20949
21014
  this.editor.update(ketcherCore.fromTextDeletion(restruct, ci.id));
20950
21015
  } else if (ci.map === 'rgroupAttachmentPoints') {
20951
21016
  this.editor.update(ketcherCore.fromRGroupAttachmentPointDeletion(restruct, ci.id));
21017
+ } else if (ci.map === ketcherCore.IMAGE_KEY) {
21018
+ this.editor.update(ketcherCore.fromImageDeletion(restruct, ci.id));
20952
21019
  } else {
20953
21020
  return;
20954
21021
  }
@@ -22398,7 +22465,157 @@ function propsDialog(editor, id, position, pos) {
22398
22465
  });
22399
22466
  }
22400
22467
 
22401
- var toolsMap = {
22468
+ var TAG = 'tool/image.ts';
22469
+ var supportedMimes = ['png', 'svg+xml'];
22470
+ var supportedMimesForRegex = supportedMimes.map(function (item) {
22471
+ return item.replace('+', '\\+');
22472
+ }).join('|');
22473
+ var allowList = new RegExp("^image/(".concat(supportedMimesForRegex, ")$"));
22474
+ var MIN_DIMENSION_SIZE = 16;
22475
+ var ImageTool = function () {
22476
+ function ImageTool(editor) {
22477
+ _classCallCheck__default["default"](this, ImageTool);
22478
+ _defineProperty__default["default"](this, "dragCtx", null);
22479
+ this.editor = editor;
22480
+ this.element = this.getElement();
22481
+ }
22482
+ _createClass__default["default"](ImageTool, [{
22483
+ key: "mousedown",
22484
+ value: function mousedown(event) {
22485
+ var render = this.editor.render;
22486
+ var closestItem = this.editor.findItem(event, [ketcherCore.IMAGE_KEY]);
22487
+ this.editor.selection(null);
22488
+ if (closestItem) {
22489
+ this.editor.hover(null);
22490
+ this.editor.selection(_defineProperty__default["default"]({}, ketcherCore.IMAGE_KEY, [closestItem.id]));
22491
+ this.dragCtx = {
22492
+ center: ketcherCore.CoordinateTransformation.pageToModel(event, render),
22493
+ action: new ketcherCore.Action(),
22494
+ closestItem: closestItem
22495
+ };
22496
+ }
22497
+ }
22498
+ }, {
22499
+ key: "click",
22500
+ value: function click(event) {
22501
+ var closestItem = this.editor.findItem(event, [ketcherCore.IMAGE_KEY]);
22502
+ this.editor.hover(null);
22503
+ if (closestItem) {
22504
+ return;
22505
+ }
22506
+ var position = ketcherCore.CoordinateTransformation.pageToModel(event, this.editor.render);
22507
+ this.element.onchange = this.onFileUpload.bind(this, position);
22508
+ this.element.click();
22509
+ }
22510
+ }, {
22511
+ key: "mousemove",
22512
+ value: function mousemove(event) {
22513
+ var render = this.editor.render;
22514
+ if (this.dragCtx) {
22515
+ this.dragCtx.action.perform(render.ctab);
22516
+ var click = ketcherCore.CoordinateTransformation.pageToModel(event, render);
22517
+ this.dragCtx.action = this.dragCtx.closestItem.ref ? ketcherCore.fromImageResize(render.ctab, this.dragCtx.closestItem.id, click, this.dragCtx.closestItem.ref) : ketcherCore.fromImageMove(render.ctab, this.dragCtx.closestItem.id, click.sub(this.dragCtx.center));
22518
+ this.editor.update(this.dragCtx.action, true);
22519
+ } else {
22520
+ var item = this.editor.findItem(event, [ketcherCore.IMAGE_KEY]);
22521
+ var _render = this.editor.render;
22522
+ if (item !== null && item !== void 0 && item.ref) {
22523
+ handleMovingPosibilityCursor(item, _render.paper.canvas, ketcherCore.imageReferencePositionToCursor[item.ref.name]);
22524
+ } else {
22525
+ handleMovingPosibilityCursor(item, _render.paper.canvas, _render.options.movingStyle.cursor);
22526
+ }
22527
+ this.editor.hover(item, null, event);
22528
+ }
22529
+ }
22530
+ }, {
22531
+ key: "mouseup",
22532
+ value: function mouseup() {
22533
+ if (this.dragCtx) {
22534
+ this.editor.update(this.dragCtx.action);
22535
+ this.dragCtx = null;
22536
+ }
22537
+ return true;
22538
+ }
22539
+ }, {
22540
+ key: "onFileUpload",
22541
+ value: function onFileUpload(clickPosition) {
22542
+ var _this = this;
22543
+ var errorHandler = this.editor.errorHandler;
22544
+ this.element.onchange = null;
22545
+ if (this.element.files && this.element.files[0]) {
22546
+ var file = this.element.files[0];
22547
+ var image = new Image();
22548
+ var reader = new FileReader();
22549
+ if (!file.type || !file.type.match(allowList)) {
22550
+ var errorMessage = "Unsupported image type";
22551
+ ketcherCore.KetcherLogger.error("".concat(TAG, ":onFileUpload"), errorMessage);
22552
+ if (errorHandler) {
22553
+ errorHandler(errorMessage);
22554
+ }
22555
+ this.resetElementValue();
22556
+ return;
22557
+ }
22558
+ reader.addEventListener('load', function () {
22559
+ image.src = reader.result;
22560
+ });
22561
+ image.onload = function () {
22562
+ _this.resetElementValue();
22563
+ if (image.width < MIN_DIMENSION_SIZE || image.height < MIN_DIMENSION_SIZE) {
22564
+ var _errorMessage = 'Image should be at least 16x16 pixels';
22565
+ ketcherCore.KetcherLogger.error("".concat(TAG, ":onLoad"), _errorMessage);
22566
+ if (errorHandler) {
22567
+ errorHandler(_errorMessage);
22568
+ }
22569
+ return;
22570
+ }
22571
+ var halfSize = ketcherCore.Scale.canvasToModel(new ketcherCore.Vec2(image.width / 2, image.height / 2), _this.editor.render.options);
22572
+ _this.editor.update(ketcherCore.fromImageCreation(_this.editor.render.ctab, image.src, clickPosition, halfSize));
22573
+ };
22574
+ image.onerror = function (e) {
22575
+ _this.resetElementValue();
22576
+ var errorMessage = 'Cannot load image';
22577
+ ketcherCore.KetcherLogger.error("".concat(TAG, ":onerror"), errorMessage, e);
22578
+ if (errorHandler) {
22579
+ errorHandler(errorMessage);
22580
+ }
22581
+ };
22582
+ reader.readAsDataURL(this.element.files[0]);
22583
+ }
22584
+ }
22585
+ }, {
22586
+ key: "createElement",
22587
+ value: function createElement() {
22588
+ var uploader = document.createElement('input');
22589
+ uploader.style.display = 'none';
22590
+ uploader.id = ImageTool.INPUT_ID;
22591
+ uploader.type = 'file';
22592
+ uploader.accept = supportedMimes.map(function (item) {
22593
+ return "image/".concat(item);
22594
+ }).join(',');
22595
+ document.body.appendChild(uploader);
22596
+ return uploader;
22597
+ }
22598
+ }, {
22599
+ key: "getElement",
22600
+ value: function getElement() {
22601
+ var element = document.getElementById(ImageTool.INPUT_ID);
22602
+ if (element instanceof HTMLInputElement) {
22603
+ return element;
22604
+ }
22605
+ element === null || element === void 0 || element.remove();
22606
+ return this.createElement();
22607
+ }
22608
+ }, {
22609
+ key: "resetElementValue",
22610
+ value: function resetElementValue() {
22611
+ this.getElement().value = '';
22612
+ }
22613
+ }]);
22614
+ return ImageTool;
22615
+ }();
22616
+ _defineProperty__default["default"](ImageTool, "INPUT_ID", 'image-upload');
22617
+
22618
+ var toolsMap = _defineProperty__default["default"]({
22402
22619
  hand: HandTool,
22403
22620
  rgroupatom: RGroupAtomTool,
22404
22621
  select: SelectTool,
@@ -22421,7 +22638,7 @@ var toolsMap = {
22421
22638
  enhancedStereo: EnhancedStereoTool,
22422
22639
  simpleobject: SimpleObjectTool,
22423
22640
  text: TextTool
22424
- };
22641
+ }, ketcherCore.IMAGE_KEY, ImageTool);
22425
22642
 
22426
22643
  var Highlighter = function () {
22427
22644
  function Highlighter(editor) {
@@ -23292,8 +23509,8 @@ function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedec
23292
23509
  function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
23293
23510
  var SCALE = ketcherCore.provideEditorSettings().microModeScale;
23294
23511
  var HISTORY_SIZE = 32;
23295
- var structObjects = ['atoms', 'bonds', 'frags', 'sgroups', 'sgroupData', 'rgroups', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts'];
23296
- var highlightTargets = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'functionalGroups', 'frags', 'merge', 'rgroups', 'rgroupAttachmentPoints', 'sgroups', 'sgroupData', 'enhancedFlags', 'simpleObjects', 'texts'];
23512
+ var structObjects = ['atoms', 'bonds', 'frags', 'sgroups', 'sgroupData', 'rgroups', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts', ketcherCore.IMAGE_KEY];
23513
+ var highlightTargets = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'functionalGroups', 'frags', 'merge', 'rgroups', 'rgroupAttachmentPoints', 'sgroups', 'sgroupData', 'enhancedFlags', 'simpleObjects', 'texts', ketcherCore.IMAGE_KEY];
23297
23514
  function selectStereoFlagsIfNecessary(atoms, expAtoms) {
23298
23515
  var atomsOfFragments = {};
23299
23516
  atoms.forEach(function (atom, atomId) {
@@ -23723,7 +23940,7 @@ var Editor$3 = function () {
23723
23940
  value: function structSelected() {
23724
23941
  var struct = this.render.ctab.molecule;
23725
23942
  var selection = this.explicitSelected();
23726
- var dst = struct.clone(new ketcherCore.Pile(selection.atoms), new ketcherCore.Pile(selection.bonds), true, null, new ketcherCore.Pile(selection.simpleObjects), new ketcherCore.Pile(selection.texts));
23943
+ var dst = struct.clone(new ketcherCore.Pile(selection.atoms), new ketcherCore.Pile(selection.bonds), true, null, new ketcherCore.Pile(selection.simpleObjects), new ketcherCore.Pile(selection.texts), null, new ketcherCore.Pile(selection.images));
23727
23944
  struct.rxnArrows.forEach(function (item, id) {
23728
23945
  if (selection.rxnArrows.indexOf(id) !== -1) dst.rxnArrows.add(item.clone());
23729
23946
  });
@@ -24083,6 +24300,10 @@ function ButtonGroup(_ref) {
24083
24300
  }, [onClick]);
24084
24301
  return jsxRuntime.jsx(material.ToggleButtonGroup, {
24085
24302
  exclusive: true,
24303
+ style: {
24304
+ overflowX: 'hidden',
24305
+ flexWrap: 'wrap'
24306
+ },
24086
24307
  children: buttons.map(function (_ref2) {
24087
24308
  var label = _ref2.label,
24088
24309
  buttonValue = _ref2.value;
@@ -24093,6 +24314,11 @@ function ButtonGroup(_ref) {
24093
24314
  return handleChange(event, buttonValue);
24094
24315
  },
24095
24316
  className: clsx__default["default"](classes$F.button, _defineProperty__default["default"]({}, classes$F.selected, buttonValue === value)),
24317
+ style: {
24318
+ flex: '1 0 25%',
24319
+ margin: '2px',
24320
+ borderRadius: '3px'
24321
+ },
24096
24322
  children: label || 'none'
24097
24323
  }, label);
24098
24324
  })
@@ -24544,7 +24770,11 @@ var useBondTypeChange = function useBondTypeChange() {
24544
24770
  var disabled = React.useCallback(function (_ref2) {
24545
24771
  var props = _ref2.props;
24546
24772
  var selectedBondIds = props === null || props === void 0 ? void 0 : props.bondIds;
24773
+ var editor = getKetcherInstance().editor;
24547
24774
  if (Array.isArray(selectedBondIds) && selectedBondIds.length !== 0) {
24775
+ if (editor.struct().isBondFromMacromolecule(selectedBondIds[0])) {
24776
+ return true;
24777
+ }
24548
24778
  return false;
24549
24779
  }
24550
24780
  return true;
@@ -24561,8 +24791,9 @@ var BondMenuItems = function BondMenuItems(props) {
24561
24791
  _useBondEdit2 = _slicedToArray__default["default"](_useBondEdit, 1),
24562
24792
  handleEdit = _useBondEdit2[0];
24563
24793
  var _useBondTypeChange = useBondTypeChange(),
24564
- _useBondTypeChange2 = _slicedToArray__default["default"](_useBondTypeChange, 1),
24565
- handleTypeChange = _useBondTypeChange2[0];
24794
+ _useBondTypeChange2 = _slicedToArray__default["default"](_useBondTypeChange, 2),
24795
+ handleTypeChange = _useBondTypeChange2[0],
24796
+ disabled = _useBondTypeChange2[1];
24566
24797
  var _useBondSGroupAttach = useBondSGroupAttach(),
24567
24798
  _useBondSGroupAttach2 = _slicedToArray__default["default"](_useBondSGroupAttach, 2),
24568
24799
  handleSGroupAttach = _useBondSGroupAttach2[0],
@@ -24574,9 +24805,13 @@ var BondMenuItems = function BondMenuItems(props) {
24574
24805
  sGroupEditHidden = _useBondSGroupEdit2[2];
24575
24806
  var handleDelete = useDelete$1();
24576
24807
  var bondNamesWithoutEmptyValue = nonQueryBondNames.slice(1);
24808
+ var isDisabled = disabled({
24809
+ props: props.propsFromTrigger
24810
+ });
24577
24811
  return jsxRuntime.jsxs(jsxRuntime.Fragment, {
24578
24812
  children: [jsxRuntime.jsx(reactContexify.Item, _objectSpread$L(_objectSpread$L({}, props), {}, {
24579
24813
  onClick: handleEdit,
24814
+ disabled: isDisabled,
24580
24815
  children: (_props$propsFromTrigg = props.propsFromTrigger) !== null && _props$propsFromTrigg !== void 0 && _props$propsFromTrigg.extraItemsSelected ? 'Edit selected bonds...' : 'Edit...'
24581
24816
  })), bondNamesWithoutEmptyValue.map(function (name, i) {
24582
24817
  var iconName = getIconName(name);
@@ -24586,7 +24821,8 @@ var BondMenuItems = function BondMenuItems(props) {
24586
24821
  }, props), {}, {
24587
24822
  id: name,
24588
24823
  onClick: handleTypeChange,
24589
- key: name
24824
+ key: name,
24825
+ disabled: isDisabled
24590
24826
  }), iconName && jsxRuntime.jsx(Icon, {
24591
24827
  name: iconName,
24592
24828
  className: styles$e.icon
@@ -24602,6 +24838,7 @@ var BondMenuItems = function BondMenuItems(props) {
24602
24838
  className: styles$e.sameGroup,
24603
24839
  id: name,
24604
24840
  onClick: handleTypeChange,
24841
+ disabled: isDisabled,
24605
24842
  children: [iconName && jsxRuntime.jsx(Icon, {
24606
24843
  name: iconName,
24607
24844
  className: styles$e.icon
@@ -24892,19 +25129,62 @@ var props = {
24892
25129
  var ContextMenu = function ContextMenu() {
24893
25130
  var _useAppContext = useAppContext(),
24894
25131
  getKetcherInstance = _useAppContext.getKetcherInstance;
24895
- var resetMenuPosition = function resetMenuPosition() {
24896
- var contextMenuElement = document.querySelector('.contexify:last-of-type');
25132
+ var adjustSubmenuPosition = function adjustSubmenuPosition(submenuElement) {
25133
+ var rect = submenuElement.getBoundingClientRect();
25134
+ var ketcherRootElement = document.querySelector(KETCHER_ROOT_NODE_CSS_SELECTOR);
25135
+ var ketcherRootElementRect = ketcherRootElement === null || ketcherRootElement === void 0 ? void 0 : ketcherRootElement.getBoundingClientRect();
25136
+ var ketcherEditorWidth = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.width) || 0;
25137
+ var ketcherEditorHeight = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.height) || 0;
25138
+ var ketcherEditorLeft = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.left) || 0;
25139
+ var ketcherEditorTop = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.top) || 0;
25140
+ if (rect.right - ketcherEditorLeft > ketcherEditorWidth) {
25141
+ submenuElement.style.left = 'auto';
25142
+ submenuElement.style.right = '100%';
25143
+ } else {
25144
+ submenuElement.style.left = '100%';
25145
+ submenuElement.style.right = 'auto';
25146
+ }
25147
+ if (rect.bottom - ketcherEditorTop > ketcherEditorHeight) {
25148
+ submenuElement.style.top = 'auto';
25149
+ submenuElement.style.bottom = '0';
25150
+ } else {
25151
+ submenuElement.style.top = '0';
25152
+ submenuElement.style.bottom = 'auto';
25153
+ }
25154
+ };
25155
+ var resetMenuPosition = function resetMenuPosition(menuElement) {
25156
+ var contextMenuElement = menuElement;
24897
25157
  var ketcherRootElement = document.querySelector(KETCHER_ROOT_NODE_CSS_SELECTOR);
24898
25158
  if (!contextMenuElement || !ketcherRootElement) {
24899
25159
  return;
24900
25160
  }
24901
25161
  var contextMenuElementBoundingBox = contextMenuElement.getBoundingClientRect();
24902
25162
  var ketcherRootElementBoundingBox = ketcherRootElement.getBoundingClientRect();
25163
+ var viewportWidth = window.innerWidth;
25164
+ var viewportHeight = window.innerHeight;
24903
25165
  if (!contextMenuElementBoundingBox || !ketcherRootElementBoundingBox) {
24904
25166
  return;
24905
25167
  }
24906
- var left = contextMenuElementBoundingBox.right > ketcherRootElementBoundingBox.right ? contextMenuElementBoundingBox.x - (contextMenuElementBoundingBox.right - ketcherRootElementBoundingBox.right) : contextMenuElementBoundingBox.x;
24907
- var top = contextMenuElementBoundingBox.bottom > ketcherRootElementBoundingBox.bottom ? contextMenuElementBoundingBox.y - (contextMenuElementBoundingBox.bottom - ketcherRootElementBoundingBox.bottom) : contextMenuElementBoundingBox.y;
25168
+ var left = contextMenuElementBoundingBox.left;
25169
+ var top = contextMenuElementBoundingBox.top;
25170
+ if (contextMenuElementBoundingBox.right > ketcherRootElementBoundingBox.right) {
25171
+ left = ketcherRootElementBoundingBox.right - contextMenuElementBoundingBox.width;
25172
+ }
25173
+ if (contextMenuElementBoundingBox.bottom > ketcherRootElementBoundingBox.bottom) {
25174
+ top = ketcherRootElementBoundingBox.bottom - contextMenuElementBoundingBox.height;
25175
+ }
25176
+ if (left < 0) {
25177
+ left = 0;
25178
+ }
25179
+ if (top < 0) {
25180
+ top = 0;
25181
+ }
25182
+ if (contextMenuElementBoundingBox.right > viewportWidth) {
25183
+ left = viewportWidth - contextMenuElementBoundingBox.width - 10;
25184
+ }
25185
+ if (contextMenuElementBoundingBox.bottom > viewportHeight) {
25186
+ top = viewportHeight - contextMenuElementBoundingBox.height - 10;
25187
+ }
24908
25188
  contextMenuElement.style.left = "".concat(left, "px");
24909
25189
  contextMenuElement.style.top = "".concat(top, "px");
24910
25190
  };
@@ -24912,7 +25192,18 @@ var ContextMenu = function ContextMenu() {
24912
25192
  var editor = getKetcherInstance().editor;
24913
25193
  if (visible) {
24914
25194
  editor.hoverIcon.hide();
24915
- resetMenuPosition();
25195
+ var contextMenuElement = document.querySelector('.contexify:last-of-type');
25196
+ var submenuElements = document.querySelectorAll('.contexify_submenu');
25197
+ if (contextMenuElement) {
25198
+ setTimeout(function () {
25199
+ return resetMenuPosition(contextMenuElement);
25200
+ }, 0);
25201
+ }
25202
+ if (submenuElements.length) {
25203
+ submenuElements.forEach(function (submenuElement) {
25204
+ adjustSubmenuPosition(submenuElement);
25205
+ });
25206
+ }
24916
25207
  }
24917
25208
  editor.contextMenu[id] = visible;
24918
25209
  }, [getKetcherInstance]);
@@ -28291,13 +28582,14 @@ function AtomListValid(value, atomType, isCustomQuery) {
28291
28582
  }
28292
28583
  return value.length >= 1;
28293
28584
  }
28294
- function pseudoAtomValid(value, atomType, isCustomQuery) {
28295
- ketcherCore.genericsList.includes(_.capitalize(value));
28296
- var isGenericElement = ketcherCore.genericsList.includes(value);
28297
- if (atomType !== 'pseudo' || isCustomQuery) {
28298
- return true;
28585
+ function pseudoAtomValid(value, atomType, isCustomQuery, disableQueryElements) {
28586
+ var capitalizedValue = _.capitalize(value);
28587
+ var isDisabledQueryElement = disableQueryElements === null || disableQueryElements === void 0 ? void 0 : disableQueryElements.includes(capitalizedValue);
28588
+ if (atomType === 'pseudo' && isDisabledQueryElement) {
28589
+ return false;
28299
28590
  }
28300
- return value && isGenericElement;
28591
+ var isGenericElement = ketcherCore.genericsList.includes(capitalizedValue);
28592
+ return atomType !== 'pseudo' || isCustomQuery || value && isGenericElement;
28301
28593
  }
28302
28594
  function chargeValid(charge, isMultipleAtoms, isCustomQuery) {
28303
28595
  var result = matchCharge(charge);
@@ -28474,12 +28766,13 @@ var Atom = function Atom(props) {
28474
28766
  };
28475
28767
  var customValid = React.useMemo(function () {
28476
28768
  var atomType = formState.result.atomType;
28769
+ var disableQueryElements = ketcherCore.SettingsManager.getOptions().disableQueryElements;
28477
28770
  return {
28478
28771
  label: function label(_label) {
28479
28772
  return atomValid(_label, isMultipleAtoms, atomType, isCustomQuery);
28480
28773
  },
28481
28774
  pseudo: function pseudo(value) {
28482
- return pseudoAtomValid(value, atomType, isCustomQuery);
28775
+ return pseudoAtomValid(value, atomType, isCustomQuery, disableQueryElements);
28483
28776
  },
28484
28777
  atomList: function atomList(value) {
28485
28778
  return AtomListValid(value, atomType, isCustomQuery);
@@ -30965,11 +31258,8 @@ function mapSelectionToProps(editor) {
30965
31258
  }
30966
31259
  return {};
30967
31260
  }
30968
- var mapStateToProps$2 = function mapStateToProps(state, ownProps) {
31261
+ var mapStateToProps$2 = function mapStateToProps(state) {
30969
31262
  var editor = state.editor;
30970
- if (ownProps.values || ownProps.label) {
30971
- return {};
30972
- }
30973
31263
  var disabledQueryElements = editor.render.options.disableQueryElements;
30974
31264
  return _objectSpread$c({
30975
31265
  disabledQueryElements: disabledQueryElements
@@ -33029,18 +33319,32 @@ var MOUSE_MOVE_THROTTLE_TIMEOUT = 300;
33029
33319
  var handleMouseMove = function handleMouseMove(dispatch, event) {
33030
33320
  dispatch(updateCursorPosition(event.clientX, event.clientY));
33031
33321
  };
33322
+ var pointerMoveListener = null;
33323
+ var mouseDownListener = null;
33032
33324
  function initMouseListener(element) {
33033
33325
  return function (dispatch, getState) {
33034
33326
  var throttledHandleMouseMove = _.throttle(handleMouseMove, MOUSE_MOVE_THROTTLE_TIMEOUT);
33035
- element.addEventListener('pointermove', function (event) {
33327
+ pointerMoveListener = function pointerMoveListener(event) {
33036
33328
  return throttledHandleMouseMove(dispatch, event);
33037
- });
33038
- element.addEventListener('mousedown', function (event) {
33329
+ };
33330
+ mouseDownListener = function mouseDownListener(event) {
33039
33331
  var areBothLeftAndRightButtonsClicked = event.buttons === 3;
33040
33332
  if (areBothLeftAndRightButtonsClicked) {
33041
33333
  handleRightClick(getState);
33042
33334
  }
33043
- }, true);
33335
+ };
33336
+ element.addEventListener('pointermove', pointerMoveListener);
33337
+ element.addEventListener('mousedown', mouseDownListener, true);
33338
+ };
33339
+ }
33340
+ function removeMouseListeners(element) {
33341
+ return function () {
33342
+ if (pointerMoveListener) {
33343
+ element.removeEventListener('pointermove', pointerMoveListener);
33344
+ }
33345
+ if (mouseDownListener) {
33346
+ element.addEventListener('mousedown', mouseDownListener, true);
33347
+ }
33044
33348
  };
33045
33349
  }
33046
33350
  function handleRightClick(getState) {
@@ -33057,14 +33361,22 @@ function initApp(element, appRoot, staticResourcesUrl, options, server, resolve,
33057
33361
  ketcherRef = ketcher;
33058
33362
  };
33059
33363
  var ketcherId = _.uniqueId();
33364
+ var getServerSetter;
33060
33365
  var setEditor = function setEditor(editor) {
33366
+ var setServer = getServerSetter();
33061
33367
  resolve({
33062
33368
  editor: editor,
33063
33369
  setKetcher: setKetcher,
33064
- ketcherId: ketcherId
33370
+ ketcherId: ketcherId,
33371
+ setServer: setServer
33065
33372
  });
33066
33373
  };
33067
33374
  var store = createStore(options, server, setEditor);
33375
+ getServerSetter = function getServerSetter() {
33376
+ return function (structService) {
33377
+ store.dispatch(setServer(structService));
33378
+ };
33379
+ };
33068
33380
  store.dispatch(initKeydownListener(element));
33069
33381
  store.dispatch(initMouseListener(element));
33070
33382
  store.dispatch(initResize());
@@ -33092,6 +33404,10 @@ function initApp(element, appRoot, staticResourcesUrl, options, server, resolve,
33092
33404
  })
33093
33405
  })
33094
33406
  }));
33407
+ return function () {
33408
+ store.dispatch(removeKeydownListener(element));
33409
+ store.dispatch(removeMouseListeners(element));
33410
+ };
33095
33411
  }
33096
33412
 
33097
33413
  var indigo;
@@ -33140,6 +33456,28 @@ var KetcherBuilder = function () {
33140
33456
  }
33141
33457
  return appendApiAsync;
33142
33458
  }()
33459
+ }, {
33460
+ key: "reinitializeApi",
33461
+ value: function reinitializeApi(structServiceProvider, setStructServiceToStore) {
33462
+ var _this = this;
33463
+ var oldStructService = this.structService;
33464
+ this.structService = createApi(structServiceProvider, ketcherCore.DefaultStructServiceOptions);
33465
+ window.addEventListener(STRUCT_SERVICE_INITIALIZED_EVENT, function () {
33466
+ var _oldStructService$des;
33467
+ oldStructService === null || oldStructService === void 0 || (_oldStructService$des = oldStructService.destroy) === null || _oldStructService$des === void 0 || _oldStructService$des.call(oldStructService);
33468
+ if (!_this.structService) {
33469
+ ketcherCore.KetcherLogger.warn('Structure service is not reinitialized');
33470
+ return;
33471
+ }
33472
+ var ketcher = ketcherCore.ketcherProvider.getKetcher();
33473
+ ketcher.reinitializeIndigo(_this.structService);
33474
+ IndigoProvider.setIndigo(_this.structService);
33475
+ setStructServiceToStore(_this.structService);
33476
+ }, {
33477
+ once: true
33478
+ });
33479
+ return this.structService;
33480
+ }
33143
33481
  }, {
33144
33482
  key: "appendServiceMode",
33145
33483
  value: function appendServiceMode(mode) {
@@ -33149,35 +33487,39 @@ var KetcherBuilder = function () {
33149
33487
  key: "appendUiAsync",
33150
33488
  value: function () {
33151
33489
  var _appendUiAsync = _asyncToGenerator__default["default"]( _regeneratorRuntime__default["default"].mark(function _callee2(element, appRoot, staticResourcesUrl, errorHandler, buttons, togglerComponent) {
33152
- var structService, _yield$Promise, editor, setKetcher, ketcherId;
33490
+ var structService, cleanup, _yield$Promise, editor, setKetcher, ketcherId, setServer;
33153
33491
  return _regeneratorRuntime__default["default"].wrap(function _callee2$(_context2) {
33154
33492
  while (1) switch (_context2.prev = _context2.next) {
33155
33493
  case 0:
33156
33494
  structService = this.structService;
33157
- _context2.next = 3;
33495
+ cleanup = null;
33496
+ _context2.next = 4;
33158
33497
  return new Promise(function (resolve) {
33159
- initApp(element, appRoot, staticResourcesUrl, {
33498
+ cleanup = initApp(element, appRoot, staticResourcesUrl, {
33160
33499
  buttons: buttons || {},
33161
33500
  errorHandler: errorHandler || null,
33162
- version: "2.23.0-rc.2" ,
33163
- buildDate: "2024-07-10T19:46:12" ,
33501
+ version: "2.24.0-rc.1" ,
33502
+ buildDate: "2024-08-06T19:23:49" ,
33164
33503
  buildNumber: ''
33165
33504
  }, structService, resolve, togglerComponent);
33166
33505
  });
33167
- case 3:
33506
+ case 4:
33168
33507
  _yield$Promise = _context2.sent;
33169
33508
  editor = _yield$Promise.editor;
33170
33509
  setKetcher = _yield$Promise.setKetcher;
33171
33510
  ketcherId = _yield$Promise.ketcherId;
33511
+ setServer = _yield$Promise.setServer;
33172
33512
  this.editor = editor;
33173
33513
  this.editor.errorHandler = errorHandler && typeof errorHandler === 'function' ? errorHandler :
33174
33514
  function () {};
33175
33515
  this.formatterFactory = new ketcherCore.FormatterFactory(structService);
33176
33516
  return _context2.abrupt("return", {
33177
33517
  setKetcher: setKetcher,
33178
- ketcherId: ketcherId
33518
+ ketcherId: ketcherId,
33519
+ cleanup: cleanup,
33520
+ setServer: setServer
33179
33521
  });
33180
- case 11:
33522
+ case 13:
33181
33523
  case "end":
33182
33524
  return _context2.stop();
33183
33525
  }
@@ -33224,7 +33566,7 @@ function buildKetcherAsync(_x) {
33224
33566
  }
33225
33567
  function _buildKetcherAsync() {
33226
33568
  _buildKetcherAsync = _asyncToGenerator__default["default"]( _regeneratorRuntime__default["default"].mark(function _callee(_ref) {
33227
- var element, appRoot, staticResourcesUrl, structServiceProvider, buttons, errorHandler, togglerComponent, builder, _yield$builder$append, setKetcher, ketcherId, ketcher;
33569
+ var element, appRoot, staticResourcesUrl, structServiceProvider, buttons, errorHandler, togglerComponent, builder, _yield$builder$append, setKetcher, ketcherId, cleanup, setServer, ketcher;
33228
33570
  return _regeneratorRuntime__default["default"].wrap(function _callee$(_context) {
33229
33571
  while (1) switch (_context.prev = _context.next) {
33230
33572
  case 0:
@@ -33240,15 +33582,20 @@ function _buildKetcherAsync() {
33240
33582
  _yield$builder$append = _context.sent;
33241
33583
  setKetcher = _yield$builder$append.setKetcher;
33242
33584
  ketcherId = _yield$builder$append.ketcherId;
33585
+ cleanup = _yield$builder$append.cleanup;
33586
+ setServer = _yield$builder$append.setServer;
33243
33587
  ketcher = builder.build();
33244
33588
  if (ketcher) {
33245
33589
  setKetcher(ketcher);
33246
33590
  }
33247
33591
  return _context.abrupt("return", {
33248
33592
  ketcher: ketcher,
33249
- ketcherId: ketcherId
33593
+ ketcherId: ketcherId,
33594
+ cleanup: cleanup,
33595
+ builder: builder,
33596
+ setServer: setServer
33250
33597
  });
33251
- case 13:
33598
+ case 15:
33252
33599
  case "end":
33253
33600
  return _context.stop();
33254
33601
  }
@@ -33266,30 +33613,60 @@ var mediaSizes = {
33266
33613
  smallHeight: 600
33267
33614
  };
33268
33615
  function Editor(props) {
33616
+ var initPromiseRef = React.useRef(null);
33617
+ var appRootRef = React.useRef(null);
33618
+ var cleanupRef = React.useRef(null);
33619
+ var ketcherBuilderRef = React.useRef(null);
33620
+ var setServerRef = React.useRef(function () {});
33621
+ var structServiceProvider = props.structServiceProvider;
33269
33622
  var rootElRef = React.useRef(null);
33270
- var onInit = props.onInit;
33271
33623
  var _useResizeObserver = useThrottleResizeObserver({
33272
33624
  ref: rootElRef
33273
33625
  }),
33274
33626
  height = _useResizeObserver.height,
33275
33627
  width = _useResizeObserver.width;
33276
33628
  React.useEffect(function () {
33277
- var appRoot = client.createRoot(rootElRef.current);
33278
- buildKetcherAsync(_objectSpread(_objectSpread({}, props), {}, {
33629
+ var _ketcherBuilderRef$cu;
33630
+ (_ketcherBuilderRef$cu = ketcherBuilderRef.current) === null || _ketcherBuilderRef$cu === void 0 || _ketcherBuilderRef$cu.reinitializeApi(props.structServiceProvider, setServerRef.current);
33631
+ }, [structServiceProvider]);
33632
+ var initKetcher = function initKetcher() {
33633
+ var _initPromiseRef$curre;
33634
+ appRootRef.current = client.createRoot(rootElRef.current);
33635
+ initPromiseRef.current = buildKetcherAsync(_objectSpread(_objectSpread({}, props), {}, {
33279
33636
  element: rootElRef.current,
33280
- appRoot: appRoot
33281
- })).then(function (_ref) {
33637
+ appRoot: appRootRef.current
33638
+ }));
33639
+ (_initPromiseRef$curre = initPromiseRef.current) === null || _initPromiseRef$curre === void 0 || _initPromiseRef$curre.then(function (_ref) {
33282
33640
  var ketcher = _ref.ketcher,
33283
- ketcherId = _ref.ketcherId;
33284
- if (typeof onInit === 'function' && ketcher) {
33285
- onInit(ketcher);
33641
+ ketcherId = _ref.ketcherId,
33642
+ cleanup = _ref.cleanup,
33643
+ builder = _ref.builder,
33644
+ setServer = _ref.setServer;
33645
+ cleanupRef.current = cleanup;
33646
+ ketcherBuilderRef.current = builder;
33647
+ setServerRef.current = setServer;
33648
+ if (typeof props.onInit === 'function' && ketcher) {
33649
+ props.onInit(ketcher);
33286
33650
  var ketcherInitEvent = new Event(ketcherInitEventName(ketcherId));
33287
33651
  window.dispatchEvent(ketcherInitEvent);
33288
33652
  }
33289
33653
  });
33654
+ };
33655
+ React.useEffect(function () {
33656
+ if (initPromiseRef.current === null) {
33657
+ initKetcher();
33658
+ } else {
33659
+ var _initPromiseRef$curre2;
33660
+ (_initPromiseRef$curre2 = initPromiseRef.current) === null || _initPromiseRef$curre2 === void 0 || _initPromiseRef$curre2["finally"](function () {
33661
+ initKetcher();
33662
+ });
33663
+ }
33290
33664
  return function () {
33291
- setTimeout(function () {
33292
- appRoot.unmount();
33665
+ var _initPromiseRef$curre3;
33666
+ (_initPromiseRef$curre3 = initPromiseRef.current) === null || _initPromiseRef$curre3 === void 0 || _initPromiseRef$curre3.then(function () {
33667
+ var _cleanupRef$current, _appRootRef$current;
33668
+ (_cleanupRef$current = cleanupRef.current) === null || _cleanupRef$current === void 0 || _cleanupRef$current.call(cleanupRef);
33669
+ (_appRootRef$current = appRootRef.current) === null || _appRootRef$current === void 0 || _appRootRef$current.unmount();
33293
33670
  });
33294
33671
  };
33295
33672
  }, []);
@@ -33314,6 +33691,8 @@ exports.KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR = KETCHER_MACROMOLECULES_ROOT_
33314
33691
  exports.KETCHER_ROOT_NODE_CLASS_NAME = KETCHER_ROOT_NODE_CLASS_NAME;
33315
33692
  exports.KETCHER_ROOT_NODE_CSS_SELECTOR = KETCHER_ROOT_NODE_CSS_SELECTOR;
33316
33693
  exports.MODES = MODES;
33694
+ exports.STRUCT_SERVICE_INITIALIZED_EVENT = STRUCT_SERVICE_INITIALIZED_EVENT;
33695
+ exports.STRUCT_SERVICE_NO_RENDER_INITIALIZED_EVENT = STRUCT_SERVICE_NO_RENDER_INITIALIZED_EVENT;
33317
33696
  exports.STRUCT_TYPE = STRUCT_TYPE;
33318
33697
  exports.StructRender = StructRender;
33319
33698
  exports.getIconName = getIconName;