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.
@@ -24,7 +24,7 @@ import _asyncToGenerator from '@babel/runtime/helpers/asyncToGenerator';
24
24
  import _regeneratorRuntime from '@babel/runtime/regenerator';
25
25
  import _classCallCheck$2 from '@babel/runtime/helpers/classCallCheck';
26
26
  import _createClass$2 from '@babel/runtime/helpers/createClass';
27
- import { KetSerializer, MolSerializer, KetcherLogger, Ketcher, defaultBondThickness, FormatterFactory, isClipboardAPIAvailable, notifyCopyCut, notifyRequestCompleted, isControlKey, StereLabelStyleType, StereoColoringType, ShowHydrogenLabels, ShowHydrogenLabelNames, SettingsManager, SdfSerializer, KETCHER_SAVED_OPTIONS_KEY, Bond as Bond$2, Elements, AtomList, getAtomType, StereoLabel, isAttachmentBond, Atom as Atom$2, findStereoAtoms, RxnArrowMode, SimpleObjectMode, SGroup as SGroup$1, Pile, getStereoAtomsMap, identifyStructFormat, SupportedFormat, ChemicalMimeType, RenderStruct, Struct, shortcutStr, MonomerMicromolecule, UnresolvedMonomer, FunctionalGroupsProvider, SaltsAndSolventsProvider, KetcherAsyncEvents, ElementColor, generateMenuShortcuts, Vec2, Scale, fromMultipleMove, FunctionalGroup, fromSgroupDeletion, fromFragmentDeletion, mergeMapOfItemsToSet, vectorUtils, fromBondAddition, Action, fromAtomAddition, fromAtomsAttrs, checkOverlapping, fromSeveralSgroupAddition, expandSGroupWithMultipleAttachmentPoint, SgContexts, fromSgroupAction, fromItemsFuse, ReBond, setExpandSGroup, fromBondsAttrs, OperationType, ReStruct, fromSimpleObjectResizing, fromArrowResizing, getItemsToFuse, getHoverToFuse, fromTextDeletion, fromTextUpdating, CoordinateTransformation, fromTemplateOnCanvas, fromTemplateOnBondAction, fromTemplateOnAtom, BondAttr, AtomAttr, formatProperties, ketcherProvider, runAsyncAction, getStructStringFromClipboardData, getStructure, initHotKeys, keyNorm, Fragment as Fragment$1, fromRGroupAttachmentPointUpdate, fromOneBondDeletion, bondChangingAction, fromChain, fromStereoFlagUpdate, fromOneAtomDeletion, fromArrowDeletion, fromPlusDeletion, fromSimpleObjectDeletion, fromRGroupAttachmentPointDeletion, notifyItemsToMergeInitializationComplete, fromPaste, RGroup as RGroup$2, fromRGroupFragment, fromUpdateIfThen, fromRGroupAttrs, fromArrowAddition, fromPlusAddition, fromRotate, fromFlip, fromSimpleObjectAddition, fromTextCreation, fromHighlightCreate, fromHighlightClear, provideEditorSettings, fromNewCanvas, Render, fromDescriptorsAlign, fromSgroupAttachmentPointAddition, SGroupAttachmentPoint, fromSgroupAddition, atomGetAttr, genericsList, getAtomCustomQuery, getFormatMimeTypeByFileName, getPropertiesByFormat, StereoFlag, getPropertiesByImgFormat, b64toBlob, Generics, TextCommand, DefaultStructServiceOptions } from 'ketcher-core';
27
+ import { KetSerializer, MolSerializer, KetcherLogger, Ketcher, defaultBondThickness, FormatterFactory, isClipboardAPIAvailable, notifyCopyCut, notifyRequestCompleted, isControlKey, StereLabelStyleType, StereoColoringType, ShowHydrogenLabels, ShowHydrogenLabelNames, SettingsManager, SdfSerializer, KETCHER_SAVED_OPTIONS_KEY, Bond as Bond$2, Elements, AtomList, getAtomType, StereoLabel, isAttachmentBond, Atom as Atom$2, findStereoAtoms, RxnArrowMode, SimpleObjectMode, IMAGE_KEY, SGroup as SGroup$1, Pile, getStereoAtomsMap, identifyStructFormat, SupportedFormat, ChemicalMimeType, RenderStruct, Struct, shortcutStr, MonomerMicromolecule, UnresolvedMonomer, FunctionalGroupsProvider, SaltsAndSolventsProvider, KetcherAsyncEvents, ElementColor, generateMenuShortcuts, Vec2, Scale, fromMultipleMove, FunctionalGroup, fromSgroupDeletion, fromFragmentDeletion, mergeMapOfItemsToSet, vectorUtils, fromBondAddition, Action, fromAtomAddition, fromAtomsAttrs, checkOverlapping, fromSeveralSgroupAddition, expandSGroupWithMultipleAttachmentPoint, SgContexts, fromSgroupAction, fromItemsFuse, ReBond, setExpandSGroup, fromBondsAttrs, OperationType, ReStruct, CoordinateTransformation, fromImageResize, fromSimpleObjectResizing, fromArrowResizing, getItemsToFuse, getHoverToFuse, imageReferencePositionToCursor, fromTextDeletion, fromTextUpdating, fromTemplateOnCanvas, fromTemplateOnBondAction, fromTemplateOnAtom, BondAttr, AtomAttr, formatProperties, ketcherProvider, runAsyncAction, getStructStringFromClipboardData, getStructure, initHotKeys, keyNorm, Fragment as Fragment$1, fromRGroupAttachmentPointUpdate, fromOneBondDeletion, bondChangingAction, fromChain, fromStereoFlagUpdate, fromOneAtomDeletion, fromArrowDeletion, fromPlusDeletion, fromSimpleObjectDeletion, fromRGroupAttachmentPointDeletion, fromImageDeletion, notifyItemsToMergeInitializationComplete, fromPaste, RGroup as RGroup$2, fromRGroupFragment, fromUpdateIfThen, fromRGroupAttrs, fromArrowAddition, fromPlusAddition, fromRotate, fromFlip, fromSimpleObjectAddition, fromTextCreation, fromImageMove, fromImageCreation, fromHighlightCreate, fromHighlightClear, provideEditorSettings, fromNewCanvas, Render, fromDescriptorsAlign, fromSgroupAttachmentPointAddition, SGroupAttachmentPoint, fromSgroupAddition, atomGetAttr, genericsList, getAtomCustomQuery, getFormatMimeTypeByFileName, getPropertiesByFormat, StereoFlag, getPropertiesByImgFormat, b64toBlob, Generics, TextCommand, DefaultStructServiceOptions } from 'ketcher-core';
28
28
  import * as React from 'react';
29
29
  import React__default, { createRef, Component, useRef, useEffect, useLayoutEffect, useState, useMemo, createElement, forwardRef, useCallback, Fragment as Fragment$2, PureComponent, lazy, Suspense } from 'react';
30
30
  import _objectWithoutProperties from '@babel/runtime/helpers/objectWithoutProperties';
@@ -76,11 +76,12 @@ import 'draft-js/dist/Draft.css';
76
76
  import { Modifier, EditorState, convertFromRaw, RichUtils, Editor as Editor$4, convertToRaw, getDefaultKeyBinding } from 'draft-js';
77
77
  import createStyles from 'draft-js-custom-styles';
78
78
  import _objectDestructuringEmpty from '@babel/runtime/helpers/objectDestructuringEmpty';
79
- import _extends$3j from '@babel/runtime/helpers/extends';
79
+ import _extends$3k from '@babel/runtime/helpers/extends';
80
80
  import MuiAutocomplete from '@mui/material/Autocomplete';
81
81
  import { createRoot } from 'react-dom/client';
82
82
 
83
83
  function createApi(structServiceProvider, defaultOptions) {
84
+ var _structService$destro;
84
85
  var structService = structServiceProvider.createStructService(defaultOptions);
85
86
  var info = structService.info();
86
87
  return Object.assign(info, {
@@ -97,7 +98,8 @@ function createApi(structServiceProvider, defaultOptions) {
97
98
  recognize: structService.recognize.bind(structService),
98
99
  generateImageAsBase64: structService.generateImageAsBase64.bind(structService),
99
100
  getInChIKey: structService.getInChIKey.bind(structService),
100
- toggleExplicitHydrogens: structService.toggleExplicitHydrogens.bind(structService)
101
+ toggleExplicitHydrogens: structService.toggleExplicitHydrogens.bind(structService),
102
+ destroy: (_structService$destro = structService.destroy) === null || _structService$destro === void 0 ? void 0 : _structService$destro.bind(structService)
101
103
  });
102
104
  }
103
105
 
@@ -276,7 +278,7 @@ function _unsupportedIterableToArray$g(o, minLen) { if (!o) return; if (typeof o
276
278
  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; }
277
279
  function _callSuper$b(t, o, e) { return o = _getPrototypeOf$2(o), _possibleConstructorReturn$2(t, _isNativeReflectConstruct$d() ? Reflect.construct(o, e || [], _getPrototypeOf$2(t).constructor) : o.apply(t, e)); }
278
280
  function _isNativeReflectConstruct$d() { try { var t = !Boolean.prototype.valueOf.call(Reflect.construct(Boolean, [], function () {})); } catch (t) {} return (_isNativeReflectConstruct$d = function _isNativeReflectConstruct() { return !!t; })(); }
279
- var ieCb = window.clipboardData;
281
+ var ieCb = typeof window !== 'undefined' ? window.clipboardData : {};
280
282
  var CLIP_AREA_BASE_CLASS = 'cliparea';
281
283
  var needSkipCopyEvent = false;
282
284
  var ClipArea = function (_Component) {
@@ -2539,7 +2541,7 @@ function isFlipDisabled(editor) {
2539
2541
  return getAmountOfAttachmentBonds() > 1;
2540
2542
  }
2541
2543
 
2542
- var toolActions = {
2544
+ var toolActions = _defineProperty$1({
2543
2545
  hand: {
2544
2546
  title: 'Hand tool',
2545
2547
  shortcut: 'Mod+Alt+h',
@@ -2970,7 +2972,15 @@ var toolActions = {
2970
2972
  return isHidden(options, 'bonds');
2971
2973
  }
2972
2974
  }
2973
- };
2975
+ }, IMAGE_KEY, {
2976
+ title: 'Add Image',
2977
+ action: {
2978
+ tool: IMAGE_KEY
2979
+ },
2980
+ hidden: function hidden(options) {
2981
+ return isHidden(options, IMAGE_KEY);
2982
+ }
2983
+ });
2974
2984
  var bondCuts = {
2975
2985
  single: '1',
2976
2986
  "double": '2',
@@ -3329,7 +3339,7 @@ function serverCall(editor, server, method, options, struct) {
3329
3339
  var selectedBonds = [];
3330
3340
  var aidMap = new Map();
3331
3341
  var bidMap = new Map();
3332
- var currentStruct = (struct || editor.struct()).clone(null, null, false, aidMap, null, null, null, bidMap);
3342
+ var currentStruct = (struct || editor.struct()).clone(null, null, false, aidMap, null, null, null, null, bidMap);
3333
3343
  var expSel = editor.explicitSelected();
3334
3344
  if (selection) {
3335
3345
  selectedAtoms = (selection.atoms ? selection.atoms : expSel.atoms).map(function (aid) {
@@ -3595,7 +3605,7 @@ var zoom = {
3595
3605
 
3596
3606
  var openHelpLink = function openHelpLink() {
3597
3607
  var _window$open;
3598
- 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();
3608
+ 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();
3599
3609
  };
3600
3610
  var help = {
3601
3611
  help: {
@@ -3623,6 +3633,8 @@ var KETCHER_ROOT_NODE_CLASS_NAME = 'Ketcher-root';
3623
3633
  var KETCHER_ROOT_NODE_CSS_SELECTOR = ".".concat(KETCHER_ROOT_NODE_CLASS_NAME);
3624
3634
  var EditorClassName = 'Ketcher-polymer-editor-root';
3625
3635
  var KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR = ".".concat(EditorClassName);
3636
+ var STRUCT_SERVICE_NO_RENDER_INITIALIZED_EVENT = 'struct-service-no-render-initialized';
3637
+ var STRUCT_SERVICE_INITIALIZED_EVENT = 'struct-service-initialized';
3626
3638
 
3627
3639
  var functionalGroupsLib = {
3628
3640
  'functional-groups': {
@@ -3983,16 +3995,16 @@ function hasSelection(editor) {
3983
3995
 
3984
3996
  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"};
3985
3997
 
3986
- var _path$3c, _rect$4, _rect2$3;
3987
- 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); }
3998
+ var _path$3d, _rect$4, _rect2$3;
3999
+ 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); }
3988
4000
  function SvgAbout(props) {
3989
- return /*#__PURE__*/React.createElement("svg", _extends$3i({
4001
+ return /*#__PURE__*/React.createElement("svg", _extends$3j({
3990
4002
  width: 24,
3991
4003
  height: 24,
3992
4004
  viewBox: "0 0 24 24",
3993
4005
  fill: "none",
3994
4006
  xmlns: "http://www.w3.org/2000/svg"
3995
- }, props), _path$3c || (_path$3c = /*#__PURE__*/React.createElement("path", {
4007
+ }, props), _path$3d || (_path$3d = /*#__PURE__*/React.createElement("path", {
3996
4008
  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",
3997
4009
  fill: "currentcolor"
3998
4010
  })), _rect$4 || (_rect$4 = /*#__PURE__*/React.createElement("rect", {
@@ -4012,6 +4024,20 @@ function SvgAbout(props) {
4012
4024
  })));
4013
4025
  }
4014
4026
 
4027
+ var _path$3c;
4028
+ 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); }
4029
+ function SvgAddImage(props) {
4030
+ return /*#__PURE__*/React.createElement("svg", _extends$3i({
4031
+ width: 16,
4032
+ height: 16,
4033
+ viewBox: "0 0 16 16",
4034
+ xmlns: "http://www.w3.org/2000/svg"
4035
+ }, props), _path$3c || (_path$3c = /*#__PURE__*/React.createElement("path", {
4036
+ 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",
4037
+ fill: "currentColor"
4038
+ })));
4039
+ }
4040
+
4015
4041
  var _path$3b;
4016
4042
  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); }
4017
4043
  function SvgAnalyse(props) {
@@ -7583,7 +7609,8 @@ function SvgNucleotide(props) {
7583
7609
  })));
7584
7610
  }
7585
7611
 
7586
- var iconNameToIcon = {
7612
+ var _iconNameToIcon;
7613
+ var iconNameToIcon = (_iconNameToIcon = {
7587
7614
  α: Svg$n,
7588
7615
  β: Svg$m,
7589
7616
  γ: Svg$l,
@@ -7735,67 +7762,8 @@ var iconNameToIcon = {
7735
7762
  'template-dialog': SvgTemplateDialog,
7736
7763
  'template-lib': SvgTemplateLib,
7737
7764
  'snake-mode': SvgSnakeMode,
7738
- text: SvgText,
7739
- 'text-bold': SvgTextBold,
7740
- 'text-italic': SvgTextItalic,
7741
- 'text-subscript': SvgTextSubscript,
7742
- 'text-superscript': SvgTextSuperscript,
7743
- 'transform-flip-h': SvgTransformFlipH,
7744
- 'transform-flip-v': SvgTransformFlipV,
7745
- undo: SvgUndo,
7746
- 'zoom-in': SvgZoomIn,
7747
- 'zoom-out': SvgZoomOut,
7748
- 'zoom-reset': SvgZoomReset,
7749
- 'shape-ellipse': SvgShapeEllipse,
7750
- 'shape-rectangle': SvgShapeRectangle,
7751
- 'shape-polyline': SvgShapePolyline,
7752
- 'shape-line': SvgShapeLine,
7753
- 'not-found': SvgNotFound,
7754
- 'save-1': SvgSave1,
7755
- 'open-1': SvgOpen1,
7756
- reset: SvgReset,
7757
- close: SvgClose,
7758
- general: SvgGeneral,
7759
- 'general-white': SvgGeneralWhite,
7760
- stereo: SvgStereo,
7761
- 'stereo-white': SvgStereoWhite,
7762
- atoms: SvgAtoms,
7763
- 'atoms-white': SvgAtomsWhite,
7764
- bonds: SvgBonds,
7765
- 'bonds-white': SvgBondsWhite,
7766
- server: SvgServer,
7767
- 'server-white': SvgServerWhite,
7768
- '3dviewer': Svg3D,
7769
- '3dviewer-white': Svg3DWhite,
7770
- debugging: SvgDebugging,
7771
- 'debugging-white': SvgDebuggingWhite,
7772
- 'dropdown-indicator': SvgDropdownIndicator,
7773
- 'text-special-symbols': SvgTextSpecialSymbols,
7774
- chevron: SvgChevron,
7775
- 'open-window-paste-icon': SvgOpenWindowPasteIcon,
7776
- 'open-window-upload-icon': SvgOpenWindowUploadIcon,
7777
- bracket: SvgBracket,
7778
- error: SvgError,
7779
- 'rap-left-link': SvgRapLeftLink,
7780
- 'rap-middle-link': SvgRapMiddleLink,
7781
- 'rap-right-link': SvgRapRightLink,
7782
- 'arrows-left': SvgArrowsLeft,
7783
- 'arrows-right': SvgArrowsRight,
7784
- sugar: SvgSugar,
7785
- base: SvgBase,
7786
- phosphate: SvgPhosphate,
7787
- preset: SvgPreset,
7788
- nucleotide: SvgNucleotide,
7789
- 'edit-filled': SvgEditFilled,
7790
- 'vertical-dots': SvgVerticalDots,
7791
- expand: SvgExpand,
7792
- 'minimize-expansion': SvgMinimizeExpantion,
7793
- 'explicit-hydrogens': SvgExplicitHydrogens,
7794
- 'flex-layout-mode': SvgFlexLayoutMode,
7795
- 'snake-layout-mode': SvgSnakeLayoutMode,
7796
- 'sequence-layout-mode': SvgSequenceLayoutMode,
7797
- questionMark: SvgQuestionMark
7798
- };
7765
+ text: SvgText
7766
+ }, _defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_iconNameToIcon, 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$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_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$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_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$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_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$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_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$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_defineProperty$1(_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));
7799
7767
 
7800
7768
  var getIconByName = function getIconByName(name) {
7801
7769
  return iconNameToIcon[name];
@@ -14024,6 +13992,7 @@ var _excluded$t = ["type"],
14024
13992
  _excluded2$5 = ["buttons"];
14025
13993
  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; }
14026
13994
  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$1(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; }
13995
+ var SET_SERVER = 'SET_SERVER';
14027
13996
  var shared = combineReducers({
14028
13997
  common: commonReducer,
14029
13998
  actionState: actionStateReducer,
@@ -14058,6 +14027,12 @@ function getRootReducer(setEditor) {
14058
14027
  var data = _objectWithoutProperties(action, _excluded$t);
14059
14028
  if (data) state = _objectSpread$12(_objectSpread$12({}, state), data);
14060
14029
  }
14030
+ case SET_SERVER:
14031
+ {
14032
+ state = _objectSpread$12(_objectSpread$12({}, state), {}, {
14033
+ server: action.server || state.server
14034
+ });
14035
+ }
14061
14036
  }
14062
14037
  var sh = shared(state, _objectSpread$12(_objectSpread$12({}, action), pick(['editor', 'server', 'options'], state)));
14063
14038
  var finalState = sh === state.shared ? state : _objectSpread$12(_objectSpread$12({}, state), sh);
@@ -14084,6 +14059,12 @@ function createStore (options, server, setEditor) {
14084
14059
  var rootReducer = getRootReducer(setEditor);
14085
14060
  return createStore$1(rootReducer, initState, applyMiddleware.apply(void 0, middleware));
14086
14061
  }
14062
+ function setServer(server) {
14063
+ return {
14064
+ type: SET_SERVER,
14065
+ server: server
14066
+ };
14067
+ }
14087
14068
 
14088
14069
  var disableableButtons$3 = [];
14089
14070
  var mapStateToProps$l = function mapStateToProps(state) {
@@ -14510,6 +14491,8 @@ var LeftToolbar = function LeftToolbar(props) {
14510
14491
  options: shapeOptions
14511
14492
  }, {
14512
14493
  id: 'text'
14494
+ }, {
14495
+ id: IMAGE_KEY
14513
14496
  }]
14514
14497
  })
14515
14498
  })]
@@ -15647,11 +15630,17 @@ function getElementsInRectangle(restruct, p0, p1) {
15647
15630
  var x1 = Math.max(p0.x, p1.x);
15648
15631
  var y0 = Math.min(p0.y, p1.y);
15649
15632
  var y1 = Math.max(p0.y, p1.y);
15633
+ var topLeftPosition = new Vec2(x0, y0);
15634
+ var topRightPosition = new Vec2(x1, y0);
15635
+ var bottomRightPosition = new Vec2(x1, y1);
15636
+ var bottomLeftPosition = new Vec2(x0, y1);
15650
15637
  restruct.bonds.forEach(function (bond, bid) {
15651
15638
  if (struct.isBondFromMacromolecule(bid)) {
15652
15639
  return;
15653
15640
  }
15654
- var centre = Vec2.lc2(restruct.atoms.get(bond.b.begin).a.pp, 0.5, restruct.atoms.get(bond.b.end).a.pp, 0.5);
15641
+ var centre = Vec2.lc2(
15642
+ restruct.atoms.get(bond.b.begin).a.pp, 0.5,
15643
+ restruct.atoms.get(bond.b.end).a.pp, 0.5);
15655
15644
  if (centre.x > x0 && centre.x < x1 && centre.y > y0 && centre.y < y1 && !FunctionalGroup.isBondInContractedFunctionalGroup(bond.b, sGroups, functionalGroups)) {
15656
15645
  bondList.push(bid);
15657
15646
  }
@@ -15659,7 +15648,8 @@ function getElementsInRectangle(restruct, p0, p1) {
15659
15648
  restruct.atoms.forEach(function (atom, aid) {
15660
15649
  var relatedFGId = FunctionalGroup.findFunctionalGroupByAtom(functionalGroups, aid);
15661
15650
  var reSGroup = restruct.sgroups.get(relatedFGId);
15662
- if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof MonomerMicromolecule) && atom.a.pp.x > x0 && atom.a.pp.x < x1 && atom.a.pp.y > y0 && atom.a.pp.y < y1 && (!FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) || aid === reSGroup.item.atoms[0])) {
15651
+ if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof MonomerMicromolecule) && atom.a.pp.x > x0 && atom.a.pp.x < x1 && atom.a.pp.y > y0 && atom.a.pp.y < y1 && (!FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) ||
15652
+ aid === reSGroup.item.atoms[0])) {
15663
15653
  atomList.push(aid);
15664
15654
  }
15665
15655
  });
@@ -15714,7 +15704,18 @@ function getElementsInRectangle(restruct, p0, p1) {
15714
15704
  rgroupAttachmentPointList.push(id);
15715
15705
  }
15716
15706
  });
15717
- return {
15707
+ var reImages = Array.from(restruct.images.entries()).reduce(function (acc, _ref) {
15708
+ var _ref2 = _slicedToArray$1(_ref, 2),
15709
+ id = _ref2[0],
15710
+ item = _ref2[1];
15711
+ if (Object.values(item.image.getReferencePositions()).some(function (point) {
15712
+ return point.isInsidePolygon([topLeftPosition, topRightPosition, bottomRightPosition, bottomLeftPosition]);
15713
+ })) {
15714
+ return acc.concat(id);
15715
+ }
15716
+ return acc;
15717
+ }, []);
15718
+ return _defineProperty$1({
15718
15719
  atoms: atomList,
15719
15720
  bonds: bondList,
15720
15721
  rxnArrows: rxnArrowsList,
@@ -15724,7 +15725,7 @@ function getElementsInRectangle(restruct, p0, p1) {
15724
15725
  simpleObjects: simpleObjectsList,
15725
15726
  texts: textsList,
15726
15727
  rgroupAttachmentPoints: rgroupAttachmentPointList
15727
- };
15728
+ }, IMAGE_KEY, reImages);
15728
15729
  }
15729
15730
  function getElementsInPolygon(restruct, rr) {
15730
15731
  var bondList = [];
@@ -15740,7 +15741,9 @@ function getElementsInPolygon(restruct, rr) {
15740
15741
  if (struct.isAtomFromMacromolecule(bond.b.begin) || struct.isAtomFromMacromolecule(bond.b.end)) {
15741
15742
  return;
15742
15743
  }
15743
- var centre = Vec2.lc2(restruct.atoms.get(bond.b.begin).a.pp, 0.5, restruct.atoms.get(bond.b.end).a.pp, 0.5);
15744
+ var centre = Vec2.lc2(
15745
+ restruct.atoms.get(bond.b.begin).a.pp, 0.5,
15746
+ restruct.atoms.get(bond.b.end).a.pp, 0.5);
15744
15747
  if (isPointInPolygon(r, centre) && !FunctionalGroup.isBondInContractedFunctionalGroup(bond.b, sGroups, functionalGroups)) {
15745
15748
  bondList.push(bid);
15746
15749
  }
@@ -15748,7 +15751,8 @@ function getElementsInPolygon(restruct, rr) {
15748
15751
  restruct.atoms.forEach(function (atom, aid) {
15749
15752
  var relatedFGId = FunctionalGroup.findFunctionalGroupByAtom(functionalGroups, aid);
15750
15753
  var reSGroup = restruct.sgroups.get(relatedFGId);
15751
- if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof MonomerMicromolecule) && isPointInPolygon(r, atom.a.pp) && (!FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) || aid === reSGroup.item.atoms[0])) {
15754
+ if (!((reSGroup === null || reSGroup === void 0 ? void 0 : reSGroup.item) instanceof MonomerMicromolecule) && isPointInPolygon(r, atom.a.pp) && (!FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) ||
15755
+ aid === reSGroup.item.atoms[0])) {
15752
15756
  atomList.push(aid);
15753
15757
  }
15754
15758
  });
@@ -15757,7 +15761,7 @@ function getElementsInPolygon(restruct, rr) {
15757
15761
  var simpleObjectsList = [];
15758
15762
  var textsList = [];
15759
15763
  restruct.rxnArrows.forEach(function (item, id) {
15760
- var referencePoints = item.getReferencePoints(true);
15764
+ var referencePoints = item.getReferencePoints();
15761
15765
  var referencePointInPolygon = referencePoints.find(function (point) {
15762
15766
  return isPointInPolygon(r, point);
15763
15767
  });
@@ -15806,7 +15810,18 @@ function getElementsInPolygon(restruct, rr) {
15806
15810
  rgroupAttachmentPointList.push(id);
15807
15811
  }
15808
15812
  });
15809
- return {
15813
+ var reImages = Array.from(restruct.images.entries()).reduce(function (acc, _ref4) {
15814
+ var _ref5 = _slicedToArray$1(_ref4, 2),
15815
+ id = _ref5[0],
15816
+ item = _ref5[1];
15817
+ if (Object.values(item.image.getReferencePositions()).some(function (point) {
15818
+ return isPointInPolygon(r, point);
15819
+ })) {
15820
+ return acc.concat(id);
15821
+ }
15822
+ return acc;
15823
+ }, []);
15824
+ return _defineProperty$1({
15810
15825
  atoms: atomList,
15811
15826
  bonds: bondList,
15812
15827
  rxnArrows: rxnArrowsList,
@@ -15816,7 +15831,7 @@ function getElementsInPolygon(restruct, rr) {
15816
15831
  simpleObjects: simpleObjectsList,
15817
15832
  texts: textsList,
15818
15833
  rgroupAttachmentPoints: rgroupAttachmentPointList
15819
- };
15834
+ }, IMAGE_KEY, reImages);
15820
15835
  }
15821
15836
  function isPointInPolygon(r, p) {
15822
15837
  var d = new Vec2(0, 1);
@@ -17167,8 +17182,8 @@ function getSelectionMap(structure) {
17167
17182
  return result;
17168
17183
  }, {});
17169
17184
  }
17170
- function getStructCenter(ReStruct, selection) {
17171
- var bb = ReStruct.getVBoxObj(selection || {});
17185
+ function getStructCenter(reStruct, selection) {
17186
+ var bb = reStruct.getVBoxObj(selection || {});
17172
17187
  return Vec2.lc2(bb.p0, 0.5, bb.p1, 0.5);
17173
17188
  }
17174
17189
 
@@ -17177,7 +17192,7 @@ var handleMovingPosibilityCursor = function handleMovingPosibilityCursor(item, c
17177
17192
  if (!item && isCursorShown) {
17178
17193
  canvas.removeAttribute('cursor');
17179
17194
  }
17180
- if (item && !isCursorShown) {
17195
+ if (item) {
17181
17196
  canvas.setAttribute('cursor', cursor);
17182
17197
  }
17183
17198
  };
@@ -17311,6 +17326,13 @@ var SelectTool = function () {
17311
17326
  info: degrees + 'º'
17312
17327
  });
17313
17328
  }
17329
+ if (dragCtx.item.map === IMAGE_KEY && dragCtx.item.ref) {
17330
+ if (dragCtx.action) dragCtx.action.perform(rnd.ctab);
17331
+ var position = CoordinateTransformation.pageToModel(event, rnd);
17332
+ dragCtx.action = fromImageResize(rnd.ctab, dragCtx.item.id, position, dragCtx.item.ref);
17333
+ editor.update(dragCtx.action, true);
17334
+ return true;
17335
+ }
17314
17336
  if (dragCtx.item.map === 'simpleObjects' && dragCtx.item.ref) {
17315
17337
  if (dragCtx.action) dragCtx.action.perform(rnd.ctab);
17316
17338
  var props = getResizingProps(editor, dragCtx, event);
@@ -17349,7 +17371,13 @@ var SelectTool = function () {
17349
17371
  var maps = getMapsForClosestItem(_classPrivateFieldGet(this, _lassoHelper).fragment || event.ctrlKey);
17350
17372
  var item = editor.findItem(event, maps, null);
17351
17373
  editor.hover(item, null, event);
17352
- handleMovingPosibilityCursor(item, this.editor.render.paper.canvas, this.editor.render.options.movingStyle.cursor);
17374
+ if ((item === null || item === void 0 ? void 0 : item.map) === IMAGE_KEY && item.ref) {
17375
+ var referencePositionInfo = item.ref;
17376
+ handleMovingPosibilityCursor(item, this.editor.render.paper.canvas,
17377
+ imageReferencePositionToCursor[referencePositionInfo.name]);
17378
+ } else {
17379
+ handleMovingPosibilityCursor(item, this.editor.render.paper.canvas, this.editor.render.options.movingStyle.cursor);
17380
+ }
17353
17381
  return true;
17354
17382
  }
17355
17383
  }, {
@@ -17692,7 +17720,7 @@ function preventSaltAndSolventsMerge(struct, dragCtx, editor) {
17692
17720
  });
17693
17721
  }
17694
17722
  function getMapsForClosestItem(selectFragment) {
17695
- return ['sgroups', 'functionalGroups', 'sgroupData', 'rgroups', 'rgroupAttachmentPoints', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts'].concat(_toConsumableArray(selectFragment ? ['frags'] : ['atoms', 'bonds']));
17723
+ return ['sgroups', 'functionalGroups', 'sgroupData', 'rgroups', 'rgroupAttachmentPoints', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts', IMAGE_KEY].concat(_toConsumableArray(selectFragment ? ['frags'] : ['atoms', 'bonds']));
17696
17724
  }
17697
17725
  function getResizingProps(editor, dragCtx, event) {
17698
17726
  var current = editor.render.page2obj(event);
@@ -18765,12 +18793,21 @@ function _isChangingFunctionalGroup() {
18765
18793
  return _isChangingFunctionalGroup.apply(this, arguments);
18766
18794
  }
18767
18795
 
18796
+ var keydownListener = null;
18768
18797
  function initKeydownListener(element) {
18769
18798
  return function (dispatch, getState) {
18770
18799
  var hotKeys = initHotKeys(config);
18771
- element.addEventListener('keydown', function (event) {
18800
+ keydownListener = function keydownListener(event) {
18772
18801
  return keyHandle(dispatch, getState, hotKeys, event);
18773
- });
18802
+ };
18803
+ element.addEventListener('keydown', keydownListener);
18804
+ };
18805
+ }
18806
+ function removeKeydownListener(element) {
18807
+ return function () {
18808
+ if (keydownListener) {
18809
+ element.removeEventListener('keydown', keydownListener);
18810
+ }
18774
18811
  };
18775
18812
  }
18776
18813
  function removeNotRenderedStruct(actionTool, group, dispatch) {
@@ -19226,7 +19263,7 @@ function _unsupportedIterableToArray$9(o, minLen) { if (!o) return; if (typeof o
19226
19263
  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; }
19227
19264
  var SELECTION_DISTANCE_COEFFICIENT = 0.4;
19228
19265
  var SELECTION_WITHIN_TEXT = 0;
19229
- var findMaps = {
19266
+ var findMaps = _defineProperty$1({
19230
19267
  atoms: findClosestAtom,
19231
19268
  bonds: findClosestBond,
19232
19269
  enhancedFlags: findClosestEnhancedFlag,
@@ -19240,15 +19277,15 @@ var findMaps = {
19240
19277
  rgroupAttachmentPoints: findClosestRgroupAttachmentPoints,
19241
19278
  simpleObjects: findClosestSimpleObject,
19242
19279
  texts: findClosestText
19243
- };
19280
+ }, IMAGE_KEY, findClosestImage);
19244
19281
  function rectangleContainsPoint(startX, startY, width, height, x, y) {
19245
19282
  return startX <= x && x <= startX + width && startY <= y && y <= startY + height;
19246
19283
  }
19247
19284
  function findClosestText(restruct, cursorPosition) {
19248
- var minDist = null;
19285
+ var minDist = Number.POSITIVE_INFINITY;
19249
19286
  var ret = null;
19250
19287
  restruct.texts.forEach(function (text, id) {
19251
- var referencePoints = text.getReferencePoints(restruct);
19288
+ var referencePoints = text.getReferencePoints();
19252
19289
  var topX = referencePoints[0].x;
19253
19290
  var topY = referencePoints[0].y;
19254
19291
  var bottomX = referencePoints[2].x;
@@ -19296,7 +19333,7 @@ function findClosestText(restruct, cursorPosition) {
19296
19333
  return ret;
19297
19334
  }
19298
19335
  function findClosestSimpleObject(restruct, pos) {
19299
- var minDist = null;
19336
+ var minDist = Number.POSITIVE_INFINITY;
19300
19337
  var refPoint = null;
19301
19338
  var ret = null;
19302
19339
  restruct.simpleObjects.forEach(function (simpleObject, id) {
@@ -19323,7 +19360,7 @@ function findClosestAtom(restruct, pos, skip, minDist) {
19323
19360
  minDist = Math.min(minDist, maxMinDist);
19324
19361
  restruct.atoms.forEach(function (atom, aid) {
19325
19362
  if (FunctionalGroup.isAtomInContractedFunctionalGroup(atom.a, sGroups, functionalGroups, true) || Atom$2.isHiddenLeavingGroupAtom(restruct.molecule, aid)) {
19326
- return null;
19363
+ return;
19327
19364
  }
19328
19365
  var isSkippedAtom = aid === skipId || atom.a.isPreview;
19329
19366
  if (isSkippedAtom) {
@@ -19361,7 +19398,7 @@ function findClosestBond(restruct, pos, skip, minDist, options) {
19361
19398
  var p1 = restruct.atoms.get(bond.b.begin).a.pp;
19362
19399
  var p2 = restruct.atoms.get(bond.b.end).a.pp;
19363
19400
  if (FunctionalGroup.isBondInContractedFunctionalGroup(bond.b, sGroups, functionalGroups) || SGroup$1.isBondInContractedSGroup(bond.b, sGroups) || Bond$2.isBondToHiddenLeavingGroup(restruct.molecule, bond.b)) {
19364
- return null;
19401
+ return;
19365
19402
  }
19366
19403
  var mid = Vec2.lc2(p1, 0.5, p2, 0.5);
19367
19404
  var cdist = Vec2.dist(pos, mid);
@@ -19399,10 +19436,10 @@ function findClosestBond(restruct, pos, skip, minDist, options) {
19399
19436
  }
19400
19437
  return null;
19401
19438
  }
19402
- function findClosestEnhancedFlag(restruct, pos, skip, _minDist, options) {
19439
+ function findClosestEnhancedFlag(restruct, pos, _skip, _minDist, options) {
19403
19440
  var minDist;
19404
19441
  var ret = null;
19405
- restruct.enhancedFlags.forEach(function (item, id) {
19442
+ restruct.enhancedFlags.forEach(function (_item, id) {
19406
19443
  var fragment = restruct.molecule.frags.get(id);
19407
19444
  if (!fragment || !fragment.enhancedStereoFlag || !options.showStereoFlags) return;
19408
19445
  var p = fragment.stereoFlagPosition ? new Vec2(fragment.stereoFlagPosition.x, fragment.stereoFlagPosition.y) : Fragment$1.getDefaultStereoFlagPosition(restruct.molecule, id);
@@ -19419,7 +19456,7 @@ function findClosestEnhancedFlag(restruct, pos, skip, _minDist, options) {
19419
19456
  return ret;
19420
19457
  }
19421
19458
  function findClosestDataSGroupData(restruct, pos) {
19422
- var minDist = null;
19459
+ var minDist = Number.POSITIVE_INFINITY;
19423
19460
  var ret = null;
19424
19461
  restruct.sgroupData.forEach(function (item, id) {
19425
19462
  if (item.sgroup.type !== 'DAT') throw new Error('Data group expected');
@@ -19479,7 +19516,7 @@ function findClosestRgroupAttachmentPoints(restruct, cursorPosition, _skip, minD
19479
19516
  var minDist = minDistToOtherItems !== null && minDistToOtherItems !== void 0 ? minDistToOtherItems : Number.POSITIVE_INFINITY;
19480
19517
  var closestItemId;
19481
19518
  restruct.visibleRGroupAttachmentPoints.forEach(function (reItem, id) {
19482
- var itemOutlinePoints = reItem.getOutlinePoints();
19519
+ var itemOutlinePoints = _toConsumableArray(reItem.getOutlinePoints());
19483
19520
  var isCursorInsideOutline = cursorPosition.isInsidePolygon(itemOutlinePoints);
19484
19521
  if (isCursorInsideOutline) {
19485
19522
  var dist = reItem.getDistanceTo(cursorPosition);
@@ -19495,7 +19532,7 @@ function findClosestRgroupAttachmentPoints(restruct, cursorPosition, _skip, minD
19495
19532
  };
19496
19533
  }
19497
19534
  function findClosestRxnArrow(restruct, pos) {
19498
- var minDist = null;
19535
+ var minDist = Number.POSITIVE_INFINITY;
19499
19536
  var refPoint = null;
19500
19537
  var ret = null;
19501
19538
  restruct.rxnArrows.forEach(function (rxnArrow, id) {
@@ -19513,7 +19550,7 @@ function findClosestRxnArrow(restruct, pos) {
19513
19550
  return ret;
19514
19551
  }
19515
19552
  function findClosestRxnPlus(restruct, pos) {
19516
- var minDist = null;
19553
+ var minDist = Number.POSITIVE_INFINITY;
19517
19554
  var ret = null;
19518
19555
  restruct.rxnPluses.forEach(function (plus, id) {
19519
19556
  var p = plus.item.pp;
@@ -19532,7 +19569,7 @@ function findClosestSGroup(restruct, pos) {
19532
19569
  var ret = null;
19533
19570
  var minDist = SELECTION_DISTANCE_COEFFICIENT;
19534
19571
  restruct.molecule.sgroups.forEach(function (sg, sgid) {
19535
- if (sg.isContracted() || sg.isSuperatomWithoutLabel) return null;
19572
+ if (sg.isContracted() || sg.isSuperatomWithoutLabel) return;
19536
19573
  var d = sg.bracketDirection;
19537
19574
  var n = d.rotateSC(1, 0);
19538
19575
  var pg = new Vec2(Vec2.dot(pos, d), Vec2.dot(pos, n));
@@ -19625,7 +19662,9 @@ function findCloseMerge(restruct, selected) {
19625
19662
  });
19626
19663
  selected.bonds.forEach(function (bid) {
19627
19664
  var bond = struct.bonds.get(bid);
19628
- pos.bonds.set(bid, Vec2.lc2(struct.atoms.get(bond.begin).pp, 0.5, struct.atoms.get(bond.end).pp, 0.5));
19665
+ pos.bonds.set(bid, Vec2.lc2(
19666
+ struct.atoms.get(bond.begin).pp, 0.5,
19667
+ struct.atoms.get(bond.end).pp, 0.5));
19629
19668
  });
19630
19669
  var result = {
19631
19670
  atoms: new Map(),
@@ -19638,7 +19677,8 @@ function findCloseMerge(restruct, selected) {
19638
19677
  mergeAtomToAtom(atomId, restruct, atomPosition, selected, result) || mergeAtomToFunctionalGroup(atomId, restruct, atomPosition, result);
19639
19678
  });
19640
19679
  } else {
19641
- result[map] = Array.from(pos[map].keys()).reduce(function (res, srcId) {
19680
+ result[map] = Array.from(pos[map].keys()).reduce(
19681
+ function (res, srcId) {
19642
19682
  var skip = {
19643
19683
  map: map,
19644
19684
  id: srcId
@@ -19678,6 +19718,31 @@ function mergeAtomToFunctionalGroup(atomId, restruct, atomPosition, result) {
19678
19718
  }
19679
19719
  return false;
19680
19720
  }
19721
+ function findClosestImage(reStruct, cursorPosition) {
19722
+ var renderOptions = reStruct.render.options;
19723
+ var canvasScaledPosition = Scale.modelToCanvas(cursorPosition, renderOptions);
19724
+ var maxDistance = renderOptions.microModeScale * SELECTION_DISTANCE_COEFFICIENT;
19725
+ return Array.from(reStruct.images.entries()).reduce(function (acc, _ref) {
19726
+ var _ref2 = _slicedToArray$1(_ref, 2),
19727
+ id = _ref2[0],
19728
+ item = _ref2[1];
19729
+ var distanceToPoint = item.calculateDistanceToPoint(canvasScaledPosition, renderOptions);
19730
+ if (distanceToPoint <= maxDistance) {
19731
+ if (acc && acc.dist < distanceToPoint) {
19732
+ return acc;
19733
+ }
19734
+ var dist = Math.max(distanceToPoint, maxDistance / 3);
19735
+ var closestPosition = item.calculateClosestReferencePosition(canvasScaledPosition, renderOptions);
19736
+ var includeRef = closestPosition.distance < maxDistance;
19737
+ return {
19738
+ id: id,
19739
+ dist: dist / renderOptions.microModeScale,
19740
+ ref: includeRef ? closestPosition.ref : null
19741
+ };
19742
+ }
19743
+ return acc;
19744
+ }, null);
19745
+ }
19681
19746
  var closest = {
19682
19747
  atom: findClosestAtom,
19683
19748
  item: findClosestItem,
@@ -20606,7 +20671,7 @@ var EraserTool = function () {
20606
20671
  function EraserTool(editor, mode) {
20607
20672
  _classCallCheck$2(this, EraserTool);
20608
20673
  this.editor = editor;
20609
- this.maps = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'sgroups', 'functionalGroups', 'sgroupData', 'simpleObjects', 'texts', 'rgroupAttachmentPoints'];
20674
+ this.maps = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'sgroups', 'functionalGroups', 'sgroupData', 'simpleObjects', 'texts', 'rgroupAttachmentPoints', IMAGE_KEY];
20610
20675
  this.lassoHelper = new LassoHelper(mode || 0, editor, null);
20611
20676
  if (editor.selection()) {
20612
20677
  var action = fromFragmentDeletion(editor.render.ctab, editor.selection());
@@ -20884,6 +20949,8 @@ var EraserTool = function () {
20884
20949
  this.editor.update(fromTextDeletion(restruct, ci.id));
20885
20950
  } else if (ci.map === 'rgroupAttachmentPoints') {
20886
20951
  this.editor.update(fromRGroupAttachmentPointDeletion(restruct, ci.id));
20952
+ } else if (ci.map === IMAGE_KEY) {
20953
+ this.editor.update(fromImageDeletion(restruct, ci.id));
20887
20954
  } else {
20888
20955
  return;
20889
20956
  }
@@ -22333,7 +22400,157 @@ function propsDialog(editor, id, position, pos) {
22333
22400
  });
22334
22401
  }
22335
22402
 
22336
- var toolsMap = {
22403
+ var TAG = 'tool/image.ts';
22404
+ var supportedMimes = ['png', 'svg+xml'];
22405
+ var supportedMimesForRegex = supportedMimes.map(function (item) {
22406
+ return item.replace('+', '\\+');
22407
+ }).join('|');
22408
+ var allowList = new RegExp("^image/(".concat(supportedMimesForRegex, ")$"));
22409
+ var MIN_DIMENSION_SIZE = 16;
22410
+ var ImageTool = function () {
22411
+ function ImageTool(editor) {
22412
+ _classCallCheck$2(this, ImageTool);
22413
+ _defineProperty$1(this, "dragCtx", null);
22414
+ this.editor = editor;
22415
+ this.element = this.getElement();
22416
+ }
22417
+ _createClass$2(ImageTool, [{
22418
+ key: "mousedown",
22419
+ value: function mousedown(event) {
22420
+ var render = this.editor.render;
22421
+ var closestItem = this.editor.findItem(event, [IMAGE_KEY]);
22422
+ this.editor.selection(null);
22423
+ if (closestItem) {
22424
+ this.editor.hover(null);
22425
+ this.editor.selection(_defineProperty$1({}, IMAGE_KEY, [closestItem.id]));
22426
+ this.dragCtx = {
22427
+ center: CoordinateTransformation.pageToModel(event, render),
22428
+ action: new Action(),
22429
+ closestItem: closestItem
22430
+ };
22431
+ }
22432
+ }
22433
+ }, {
22434
+ key: "click",
22435
+ value: function click(event) {
22436
+ var closestItem = this.editor.findItem(event, [IMAGE_KEY]);
22437
+ this.editor.hover(null);
22438
+ if (closestItem) {
22439
+ return;
22440
+ }
22441
+ var position = CoordinateTransformation.pageToModel(event, this.editor.render);
22442
+ this.element.onchange = this.onFileUpload.bind(this, position);
22443
+ this.element.click();
22444
+ }
22445
+ }, {
22446
+ key: "mousemove",
22447
+ value: function mousemove(event) {
22448
+ var render = this.editor.render;
22449
+ if (this.dragCtx) {
22450
+ this.dragCtx.action.perform(render.ctab);
22451
+ var click = CoordinateTransformation.pageToModel(event, render);
22452
+ this.dragCtx.action = this.dragCtx.closestItem.ref ? fromImageResize(render.ctab, this.dragCtx.closestItem.id, click, this.dragCtx.closestItem.ref) : fromImageMove(render.ctab, this.dragCtx.closestItem.id, click.sub(this.dragCtx.center));
22453
+ this.editor.update(this.dragCtx.action, true);
22454
+ } else {
22455
+ var item = this.editor.findItem(event, [IMAGE_KEY]);
22456
+ var _render = this.editor.render;
22457
+ if (item !== null && item !== void 0 && item.ref) {
22458
+ handleMovingPosibilityCursor(item, _render.paper.canvas, imageReferencePositionToCursor[item.ref.name]);
22459
+ } else {
22460
+ handleMovingPosibilityCursor(item, _render.paper.canvas, _render.options.movingStyle.cursor);
22461
+ }
22462
+ this.editor.hover(item, null, event);
22463
+ }
22464
+ }
22465
+ }, {
22466
+ key: "mouseup",
22467
+ value: function mouseup() {
22468
+ if (this.dragCtx) {
22469
+ this.editor.update(this.dragCtx.action);
22470
+ this.dragCtx = null;
22471
+ }
22472
+ return true;
22473
+ }
22474
+ }, {
22475
+ key: "onFileUpload",
22476
+ value: function onFileUpload(clickPosition) {
22477
+ var _this = this;
22478
+ var errorHandler = this.editor.errorHandler;
22479
+ this.element.onchange = null;
22480
+ if (this.element.files && this.element.files[0]) {
22481
+ var file = this.element.files[0];
22482
+ var image = new Image();
22483
+ var reader = new FileReader();
22484
+ if (!file.type || !file.type.match(allowList)) {
22485
+ var errorMessage = "Unsupported image type";
22486
+ KetcherLogger.error("".concat(TAG, ":onFileUpload"), errorMessage);
22487
+ if (errorHandler) {
22488
+ errorHandler(errorMessage);
22489
+ }
22490
+ this.resetElementValue();
22491
+ return;
22492
+ }
22493
+ reader.addEventListener('load', function () {
22494
+ image.src = reader.result;
22495
+ });
22496
+ image.onload = function () {
22497
+ _this.resetElementValue();
22498
+ if (image.width < MIN_DIMENSION_SIZE || image.height < MIN_DIMENSION_SIZE) {
22499
+ var _errorMessage = 'Image should be at least 16x16 pixels';
22500
+ KetcherLogger.error("".concat(TAG, ":onLoad"), _errorMessage);
22501
+ if (errorHandler) {
22502
+ errorHandler(_errorMessage);
22503
+ }
22504
+ return;
22505
+ }
22506
+ var halfSize = Scale.canvasToModel(new Vec2(image.width / 2, image.height / 2), _this.editor.render.options);
22507
+ _this.editor.update(fromImageCreation(_this.editor.render.ctab, image.src, clickPosition, halfSize));
22508
+ };
22509
+ image.onerror = function (e) {
22510
+ _this.resetElementValue();
22511
+ var errorMessage = 'Cannot load image';
22512
+ KetcherLogger.error("".concat(TAG, ":onerror"), errorMessage, e);
22513
+ if (errorHandler) {
22514
+ errorHandler(errorMessage);
22515
+ }
22516
+ };
22517
+ reader.readAsDataURL(this.element.files[0]);
22518
+ }
22519
+ }
22520
+ }, {
22521
+ key: "createElement",
22522
+ value: function createElement() {
22523
+ var uploader = document.createElement('input');
22524
+ uploader.style.display = 'none';
22525
+ uploader.id = ImageTool.INPUT_ID;
22526
+ uploader.type = 'file';
22527
+ uploader.accept = supportedMimes.map(function (item) {
22528
+ return "image/".concat(item);
22529
+ }).join(',');
22530
+ document.body.appendChild(uploader);
22531
+ return uploader;
22532
+ }
22533
+ }, {
22534
+ key: "getElement",
22535
+ value: function getElement() {
22536
+ var element = document.getElementById(ImageTool.INPUT_ID);
22537
+ if (element instanceof HTMLInputElement) {
22538
+ return element;
22539
+ }
22540
+ element === null || element === void 0 || element.remove();
22541
+ return this.createElement();
22542
+ }
22543
+ }, {
22544
+ key: "resetElementValue",
22545
+ value: function resetElementValue() {
22546
+ this.getElement().value = '';
22547
+ }
22548
+ }]);
22549
+ return ImageTool;
22550
+ }();
22551
+ _defineProperty$1(ImageTool, "INPUT_ID", 'image-upload');
22552
+
22553
+ var toolsMap = _defineProperty$1({
22337
22554
  hand: HandTool,
22338
22555
  rgroupatom: RGroupAtomTool,
22339
22556
  select: SelectTool,
@@ -22356,7 +22573,7 @@ var toolsMap = {
22356
22573
  enhancedStereo: EnhancedStereoTool,
22357
22574
  simpleobject: SimpleObjectTool,
22358
22575
  text: TextTool
22359
- };
22576
+ }, IMAGE_KEY, ImageTool);
22360
22577
 
22361
22578
  var Highlighter = function () {
22362
22579
  function Highlighter(editor) {
@@ -23227,8 +23444,8 @@ function _classPrivateFieldInitSpec(obj, privateMap, value) { _checkPrivateRedec
23227
23444
  function _checkPrivateRedeclaration(obj, privateCollection) { if (privateCollection.has(obj)) { throw new TypeError("Cannot initialize the same private elements twice on an object"); } }
23228
23445
  var SCALE = provideEditorSettings().microModeScale;
23229
23446
  var HISTORY_SIZE = 32;
23230
- var structObjects = ['atoms', 'bonds', 'frags', 'sgroups', 'sgroupData', 'rgroups', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts'];
23231
- var highlightTargets = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'functionalGroups', 'frags', 'merge', 'rgroups', 'rgroupAttachmentPoints', 'sgroups', 'sgroupData', 'enhancedFlags', 'simpleObjects', 'texts'];
23447
+ var structObjects = ['atoms', 'bonds', 'frags', 'sgroups', 'sgroupData', 'rgroups', 'rxnArrows', 'rxnPluses', 'enhancedFlags', 'simpleObjects', 'texts', IMAGE_KEY];
23448
+ var highlightTargets = ['atoms', 'bonds', 'rxnArrows', 'rxnPluses', 'functionalGroups', 'frags', 'merge', 'rgroups', 'rgroupAttachmentPoints', 'sgroups', 'sgroupData', 'enhancedFlags', 'simpleObjects', 'texts', IMAGE_KEY];
23232
23449
  function selectStereoFlagsIfNecessary(atoms, expAtoms) {
23233
23450
  var atomsOfFragments = {};
23234
23451
  atoms.forEach(function (atom, atomId) {
@@ -23658,7 +23875,7 @@ var Editor$3 = function () {
23658
23875
  value: function structSelected() {
23659
23876
  var struct = this.render.ctab.molecule;
23660
23877
  var selection = this.explicitSelected();
23661
- var dst = struct.clone(new Pile(selection.atoms), new Pile(selection.bonds), true, null, new Pile(selection.simpleObjects), new Pile(selection.texts));
23878
+ var dst = struct.clone(new Pile(selection.atoms), new Pile(selection.bonds), true, null, new Pile(selection.simpleObjects), new Pile(selection.texts), null, new Pile(selection.images));
23662
23879
  struct.rxnArrows.forEach(function (item, id) {
23663
23880
  if (selection.rxnArrows.indexOf(id) !== -1) dst.rxnArrows.add(item.clone());
23664
23881
  });
@@ -24018,6 +24235,10 @@ function ButtonGroup(_ref) {
24018
24235
  }, [onClick]);
24019
24236
  return jsx(ToggleButtonGroup, {
24020
24237
  exclusive: true,
24238
+ style: {
24239
+ overflowX: 'hidden',
24240
+ flexWrap: 'wrap'
24241
+ },
24021
24242
  children: buttons.map(function (_ref2) {
24022
24243
  var label = _ref2.label,
24023
24244
  buttonValue = _ref2.value;
@@ -24028,6 +24249,11 @@ function ButtonGroup(_ref) {
24028
24249
  return handleChange(event, buttonValue);
24029
24250
  },
24030
24251
  className: clsx(classes$F.button, _defineProperty$1({}, classes$F.selected, buttonValue === value)),
24252
+ style: {
24253
+ flex: '1 0 25%',
24254
+ margin: '2px',
24255
+ borderRadius: '3px'
24256
+ },
24031
24257
  children: label || 'none'
24032
24258
  }, label);
24033
24259
  })
@@ -24479,7 +24705,11 @@ var useBondTypeChange = function useBondTypeChange() {
24479
24705
  var disabled = useCallback(function (_ref2) {
24480
24706
  var props = _ref2.props;
24481
24707
  var selectedBondIds = props === null || props === void 0 ? void 0 : props.bondIds;
24708
+ var editor = getKetcherInstance().editor;
24482
24709
  if (Array.isArray(selectedBondIds) && selectedBondIds.length !== 0) {
24710
+ if (editor.struct().isBondFromMacromolecule(selectedBondIds[0])) {
24711
+ return true;
24712
+ }
24483
24713
  return false;
24484
24714
  }
24485
24715
  return true;
@@ -24496,8 +24726,9 @@ var BondMenuItems = function BondMenuItems(props) {
24496
24726
  _useBondEdit2 = _slicedToArray$1(_useBondEdit, 1),
24497
24727
  handleEdit = _useBondEdit2[0];
24498
24728
  var _useBondTypeChange = useBondTypeChange(),
24499
- _useBondTypeChange2 = _slicedToArray$1(_useBondTypeChange, 1),
24500
- handleTypeChange = _useBondTypeChange2[0];
24729
+ _useBondTypeChange2 = _slicedToArray$1(_useBondTypeChange, 2),
24730
+ handleTypeChange = _useBondTypeChange2[0],
24731
+ disabled = _useBondTypeChange2[1];
24501
24732
  var _useBondSGroupAttach = useBondSGroupAttach(),
24502
24733
  _useBondSGroupAttach2 = _slicedToArray$1(_useBondSGroupAttach, 2),
24503
24734
  handleSGroupAttach = _useBondSGroupAttach2[0],
@@ -24509,9 +24740,13 @@ var BondMenuItems = function BondMenuItems(props) {
24509
24740
  sGroupEditHidden = _useBondSGroupEdit2[2];
24510
24741
  var handleDelete = useDelete$1();
24511
24742
  var bondNamesWithoutEmptyValue = nonQueryBondNames.slice(1);
24743
+ var isDisabled = disabled({
24744
+ props: props.propsFromTrigger
24745
+ });
24512
24746
  return jsxs(Fragment, {
24513
24747
  children: [jsx(Item, _objectSpread$L(_objectSpread$L({}, props), {}, {
24514
24748
  onClick: handleEdit,
24749
+ disabled: isDisabled,
24515
24750
  children: (_props$propsFromTrigg = props.propsFromTrigger) !== null && _props$propsFromTrigg !== void 0 && _props$propsFromTrigg.extraItemsSelected ? 'Edit selected bonds...' : 'Edit...'
24516
24751
  })), bondNamesWithoutEmptyValue.map(function (name, i) {
24517
24752
  var iconName = getIconName(name);
@@ -24521,7 +24756,8 @@ var BondMenuItems = function BondMenuItems(props) {
24521
24756
  }, props), {}, {
24522
24757
  id: name,
24523
24758
  onClick: handleTypeChange,
24524
- key: name
24759
+ key: name,
24760
+ disabled: isDisabled
24525
24761
  }), iconName && jsx(Icon, {
24526
24762
  name: iconName,
24527
24763
  className: styles$e.icon
@@ -24537,6 +24773,7 @@ var BondMenuItems = function BondMenuItems(props) {
24537
24773
  className: styles$e.sameGroup,
24538
24774
  id: name,
24539
24775
  onClick: handleTypeChange,
24776
+ disabled: isDisabled,
24540
24777
  children: [iconName && jsx(Icon, {
24541
24778
  name: iconName,
24542
24779
  className: styles$e.icon
@@ -24827,19 +25064,62 @@ var props = {
24827
25064
  var ContextMenu = function ContextMenu() {
24828
25065
  var _useAppContext = useAppContext(),
24829
25066
  getKetcherInstance = _useAppContext.getKetcherInstance;
24830
- var resetMenuPosition = function resetMenuPosition() {
24831
- var contextMenuElement = document.querySelector('.contexify:last-of-type');
25067
+ var adjustSubmenuPosition = function adjustSubmenuPosition(submenuElement) {
25068
+ var rect = submenuElement.getBoundingClientRect();
25069
+ var ketcherRootElement = document.querySelector(KETCHER_ROOT_NODE_CSS_SELECTOR);
25070
+ var ketcherRootElementRect = ketcherRootElement === null || ketcherRootElement === void 0 ? void 0 : ketcherRootElement.getBoundingClientRect();
25071
+ var ketcherEditorWidth = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.width) || 0;
25072
+ var ketcherEditorHeight = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.height) || 0;
25073
+ var ketcherEditorLeft = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.left) || 0;
25074
+ var ketcherEditorTop = (ketcherRootElementRect === null || ketcherRootElementRect === void 0 ? void 0 : ketcherRootElementRect.top) || 0;
25075
+ if (rect.right - ketcherEditorLeft > ketcherEditorWidth) {
25076
+ submenuElement.style.left = 'auto';
25077
+ submenuElement.style.right = '100%';
25078
+ } else {
25079
+ submenuElement.style.left = '100%';
25080
+ submenuElement.style.right = 'auto';
25081
+ }
25082
+ if (rect.bottom - ketcherEditorTop > ketcherEditorHeight) {
25083
+ submenuElement.style.top = 'auto';
25084
+ submenuElement.style.bottom = '0';
25085
+ } else {
25086
+ submenuElement.style.top = '0';
25087
+ submenuElement.style.bottom = 'auto';
25088
+ }
25089
+ };
25090
+ var resetMenuPosition = function resetMenuPosition(menuElement) {
25091
+ var contextMenuElement = menuElement;
24832
25092
  var ketcherRootElement = document.querySelector(KETCHER_ROOT_NODE_CSS_SELECTOR);
24833
25093
  if (!contextMenuElement || !ketcherRootElement) {
24834
25094
  return;
24835
25095
  }
24836
25096
  var contextMenuElementBoundingBox = contextMenuElement.getBoundingClientRect();
24837
25097
  var ketcherRootElementBoundingBox = ketcherRootElement.getBoundingClientRect();
25098
+ var viewportWidth = window.innerWidth;
25099
+ var viewportHeight = window.innerHeight;
24838
25100
  if (!contextMenuElementBoundingBox || !ketcherRootElementBoundingBox) {
24839
25101
  return;
24840
25102
  }
24841
- var left = contextMenuElementBoundingBox.right > ketcherRootElementBoundingBox.right ? contextMenuElementBoundingBox.x - (contextMenuElementBoundingBox.right - ketcherRootElementBoundingBox.right) : contextMenuElementBoundingBox.x;
24842
- var top = contextMenuElementBoundingBox.bottom > ketcherRootElementBoundingBox.bottom ? contextMenuElementBoundingBox.y - (contextMenuElementBoundingBox.bottom - ketcherRootElementBoundingBox.bottom) : contextMenuElementBoundingBox.y;
25103
+ var left = contextMenuElementBoundingBox.left;
25104
+ var top = contextMenuElementBoundingBox.top;
25105
+ if (contextMenuElementBoundingBox.right > ketcherRootElementBoundingBox.right) {
25106
+ left = ketcherRootElementBoundingBox.right - contextMenuElementBoundingBox.width;
25107
+ }
25108
+ if (contextMenuElementBoundingBox.bottom > ketcherRootElementBoundingBox.bottom) {
25109
+ top = ketcherRootElementBoundingBox.bottom - contextMenuElementBoundingBox.height;
25110
+ }
25111
+ if (left < 0) {
25112
+ left = 0;
25113
+ }
25114
+ if (top < 0) {
25115
+ top = 0;
25116
+ }
25117
+ if (contextMenuElementBoundingBox.right > viewportWidth) {
25118
+ left = viewportWidth - contextMenuElementBoundingBox.width - 10;
25119
+ }
25120
+ if (contextMenuElementBoundingBox.bottom > viewportHeight) {
25121
+ top = viewportHeight - contextMenuElementBoundingBox.height - 10;
25122
+ }
24843
25123
  contextMenuElement.style.left = "".concat(left, "px");
24844
25124
  contextMenuElement.style.top = "".concat(top, "px");
24845
25125
  };
@@ -24847,7 +25127,18 @@ var ContextMenu = function ContextMenu() {
24847
25127
  var editor = getKetcherInstance().editor;
24848
25128
  if (visible) {
24849
25129
  editor.hoverIcon.hide();
24850
- resetMenuPosition();
25130
+ var contextMenuElement = document.querySelector('.contexify:last-of-type');
25131
+ var submenuElements = document.querySelectorAll('.contexify_submenu');
25132
+ if (contextMenuElement) {
25133
+ setTimeout(function () {
25134
+ return resetMenuPosition(contextMenuElement);
25135
+ }, 0);
25136
+ }
25137
+ if (submenuElements.length) {
25138
+ submenuElements.forEach(function (submenuElement) {
25139
+ adjustSubmenuPosition(submenuElement);
25140
+ });
25141
+ }
24851
25142
  }
24852
25143
  editor.contextMenu[id] = visible;
24853
25144
  }, [getKetcherInstance]);
@@ -28226,13 +28517,14 @@ function AtomListValid(value, atomType, isCustomQuery) {
28226
28517
  }
28227
28518
  return value.length >= 1;
28228
28519
  }
28229
- function pseudoAtomValid(value, atomType, isCustomQuery) {
28230
- genericsList.includes(capitalize$1(value));
28231
- var isGenericElement = genericsList.includes(value);
28232
- if (atomType !== 'pseudo' || isCustomQuery) {
28233
- return true;
28520
+ function pseudoAtomValid(value, atomType, isCustomQuery, disableQueryElements) {
28521
+ var capitalizedValue = capitalize$1(value);
28522
+ var isDisabledQueryElement = disableQueryElements === null || disableQueryElements === void 0 ? void 0 : disableQueryElements.includes(capitalizedValue);
28523
+ if (atomType === 'pseudo' && isDisabledQueryElement) {
28524
+ return false;
28234
28525
  }
28235
- return value && isGenericElement;
28526
+ var isGenericElement = genericsList.includes(capitalizedValue);
28527
+ return atomType !== 'pseudo' || isCustomQuery || value && isGenericElement;
28236
28528
  }
28237
28529
  function chargeValid(charge, isMultipleAtoms, isCustomQuery) {
28238
28530
  var result = matchCharge(charge);
@@ -28409,12 +28701,13 @@ var Atom = function Atom(props) {
28409
28701
  };
28410
28702
  var customValid = useMemo(function () {
28411
28703
  var atomType = formState.result.atomType;
28704
+ var disableQueryElements = SettingsManager.getOptions().disableQueryElements;
28412
28705
  return {
28413
28706
  label: function label(_label) {
28414
28707
  return atomValid(_label, isMultipleAtoms, atomType, isCustomQuery);
28415
28708
  },
28416
28709
  pseudo: function pseudo(value) {
28417
- return pseudoAtomValid(value, atomType, isCustomQuery);
28710
+ return pseudoAtomValid(value, atomType, isCustomQuery, disableQueryElements);
28418
28711
  },
28419
28712
  atomList: function atomList(value) {
28420
28713
  return AtomListValid(value, atomType, isCustomQuery);
@@ -30900,11 +31193,8 @@ function mapSelectionToProps(editor) {
30900
31193
  }
30901
31194
  return {};
30902
31195
  }
30903
- var mapStateToProps$2 = function mapStateToProps(state, ownProps) {
31196
+ var mapStateToProps$2 = function mapStateToProps(state) {
30904
31197
  var editor = state.editor;
30905
- if (ownProps.values || ownProps.label) {
30906
- return {};
30907
- }
30908
31198
  var disabledQueryElements = editor.render.options.disableQueryElements;
30909
31199
  return _objectSpread$c({
30910
31200
  disabledQueryElements: disabledQueryElements
@@ -32488,7 +32778,7 @@ function initEditor(dispatch, getState) {
32488
32778
  return dlg.then(toElement);
32489
32779
  },
32490
32780
  onEnhancedStereoEdit: function onEnhancedStereoEdit(_ref3) {
32491
- var init = _extends$3j({}, (_objectDestructuringEmpty(_ref3), _ref3));
32781
+ var init = _extends$3k({}, (_objectDestructuringEmpty(_ref3), _ref3));
32492
32782
  return sleep(0).then(function () {
32493
32783
  init = fromStereoLabel(init.stereoLabel);
32494
32784
  return openDialog(dispatch, 'enhancedStereo', {
@@ -32964,18 +33254,32 @@ var MOUSE_MOVE_THROTTLE_TIMEOUT = 300;
32964
33254
  var handleMouseMove = function handleMouseMove(dispatch, event) {
32965
33255
  dispatch(updateCursorPosition(event.clientX, event.clientY));
32966
33256
  };
33257
+ var pointerMoveListener = null;
33258
+ var mouseDownListener = null;
32967
33259
  function initMouseListener(element) {
32968
33260
  return function (dispatch, getState) {
32969
33261
  var throttledHandleMouseMove = throttle$1(handleMouseMove, MOUSE_MOVE_THROTTLE_TIMEOUT);
32970
- element.addEventListener('pointermove', function (event) {
33262
+ pointerMoveListener = function pointerMoveListener(event) {
32971
33263
  return throttledHandleMouseMove(dispatch, event);
32972
- });
32973
- element.addEventListener('mousedown', function (event) {
33264
+ };
33265
+ mouseDownListener = function mouseDownListener(event) {
32974
33266
  var areBothLeftAndRightButtonsClicked = event.buttons === 3;
32975
33267
  if (areBothLeftAndRightButtonsClicked) {
32976
33268
  handleRightClick(getState);
32977
33269
  }
32978
- }, true);
33270
+ };
33271
+ element.addEventListener('pointermove', pointerMoveListener);
33272
+ element.addEventListener('mousedown', mouseDownListener, true);
33273
+ };
33274
+ }
33275
+ function removeMouseListeners(element) {
33276
+ return function () {
33277
+ if (pointerMoveListener) {
33278
+ element.removeEventListener('pointermove', pointerMoveListener);
33279
+ }
33280
+ if (mouseDownListener) {
33281
+ element.addEventListener('mousedown', mouseDownListener, true);
33282
+ }
32979
33283
  };
32980
33284
  }
32981
33285
  function handleRightClick(getState) {
@@ -32992,14 +33296,22 @@ function initApp(element, appRoot, staticResourcesUrl, options, server, resolve,
32992
33296
  ketcherRef = ketcher;
32993
33297
  };
32994
33298
  var ketcherId = uniqueId();
33299
+ var getServerSetter;
32995
33300
  var setEditor = function setEditor(editor) {
33301
+ var setServer = getServerSetter();
32996
33302
  resolve({
32997
33303
  editor: editor,
32998
33304
  setKetcher: setKetcher,
32999
- ketcherId: ketcherId
33305
+ ketcherId: ketcherId,
33306
+ setServer: setServer
33000
33307
  });
33001
33308
  };
33002
33309
  var store = createStore(options, server, setEditor);
33310
+ getServerSetter = function getServerSetter() {
33311
+ return function (structService) {
33312
+ store.dispatch(setServer(structService));
33313
+ };
33314
+ };
33003
33315
  store.dispatch(initKeydownListener(element));
33004
33316
  store.dispatch(initMouseListener(element));
33005
33317
  store.dispatch(initResize());
@@ -33027,6 +33339,10 @@ function initApp(element, appRoot, staticResourcesUrl, options, server, resolve,
33027
33339
  })
33028
33340
  })
33029
33341
  }));
33342
+ return function () {
33343
+ store.dispatch(removeKeydownListener(element));
33344
+ store.dispatch(removeMouseListeners(element));
33345
+ };
33030
33346
  }
33031
33347
 
33032
33348
  var indigo;
@@ -33075,6 +33391,28 @@ var KetcherBuilder = function () {
33075
33391
  }
33076
33392
  return appendApiAsync;
33077
33393
  }()
33394
+ }, {
33395
+ key: "reinitializeApi",
33396
+ value: function reinitializeApi(structServiceProvider, setStructServiceToStore) {
33397
+ var _this = this;
33398
+ var oldStructService = this.structService;
33399
+ this.structService = createApi(structServiceProvider, DefaultStructServiceOptions);
33400
+ window.addEventListener(STRUCT_SERVICE_INITIALIZED_EVENT, function () {
33401
+ var _oldStructService$des;
33402
+ oldStructService === null || oldStructService === void 0 || (_oldStructService$des = oldStructService.destroy) === null || _oldStructService$des === void 0 || _oldStructService$des.call(oldStructService);
33403
+ if (!_this.structService) {
33404
+ KetcherLogger.warn('Structure service is not reinitialized');
33405
+ return;
33406
+ }
33407
+ var ketcher = ketcherProvider.getKetcher();
33408
+ ketcher.reinitializeIndigo(_this.structService);
33409
+ IndigoProvider.setIndigo(_this.structService);
33410
+ setStructServiceToStore(_this.structService);
33411
+ }, {
33412
+ once: true
33413
+ });
33414
+ return this.structService;
33415
+ }
33078
33416
  }, {
33079
33417
  key: "appendServiceMode",
33080
33418
  value: function appendServiceMode(mode) {
@@ -33084,35 +33422,39 @@ var KetcherBuilder = function () {
33084
33422
  key: "appendUiAsync",
33085
33423
  value: function () {
33086
33424
  var _appendUiAsync = _asyncToGenerator( _regeneratorRuntime.mark(function _callee2(element, appRoot, staticResourcesUrl, errorHandler, buttons, togglerComponent) {
33087
- var structService, _yield$Promise, editor, setKetcher, ketcherId;
33425
+ var structService, cleanup, _yield$Promise, editor, setKetcher, ketcherId, setServer;
33088
33426
  return _regeneratorRuntime.wrap(function _callee2$(_context2) {
33089
33427
  while (1) switch (_context2.prev = _context2.next) {
33090
33428
  case 0:
33091
33429
  structService = this.structService;
33092
- _context2.next = 3;
33430
+ cleanup = null;
33431
+ _context2.next = 4;
33093
33432
  return new Promise(function (resolve) {
33094
- initApp(element, appRoot, staticResourcesUrl, {
33433
+ cleanup = initApp(element, appRoot, staticResourcesUrl, {
33095
33434
  buttons: buttons || {},
33096
33435
  errorHandler: errorHandler || null,
33097
- version: "2.23.0-rc.2" ,
33098
- buildDate: "2024-07-10T19:46:12" ,
33436
+ version: "2.24.0-rc.1" ,
33437
+ buildDate: "2024-08-06T19:23:49" ,
33099
33438
  buildNumber: ''
33100
33439
  }, structService, resolve, togglerComponent);
33101
33440
  });
33102
- case 3:
33441
+ case 4:
33103
33442
  _yield$Promise = _context2.sent;
33104
33443
  editor = _yield$Promise.editor;
33105
33444
  setKetcher = _yield$Promise.setKetcher;
33106
33445
  ketcherId = _yield$Promise.ketcherId;
33446
+ setServer = _yield$Promise.setServer;
33107
33447
  this.editor = editor;
33108
33448
  this.editor.errorHandler = errorHandler && typeof errorHandler === 'function' ? errorHandler :
33109
33449
  function () {};
33110
33450
  this.formatterFactory = new FormatterFactory(structService);
33111
33451
  return _context2.abrupt("return", {
33112
33452
  setKetcher: setKetcher,
33113
- ketcherId: ketcherId
33453
+ ketcherId: ketcherId,
33454
+ cleanup: cleanup,
33455
+ setServer: setServer
33114
33456
  });
33115
- case 11:
33457
+ case 13:
33116
33458
  case "end":
33117
33459
  return _context2.stop();
33118
33460
  }
@@ -33159,7 +33501,7 @@ function buildKetcherAsync(_x) {
33159
33501
  }
33160
33502
  function _buildKetcherAsync() {
33161
33503
  _buildKetcherAsync = _asyncToGenerator( _regeneratorRuntime.mark(function _callee(_ref) {
33162
- var element, appRoot, staticResourcesUrl, structServiceProvider, buttons, errorHandler, togglerComponent, builder, _yield$builder$append, setKetcher, ketcherId, ketcher;
33504
+ var element, appRoot, staticResourcesUrl, structServiceProvider, buttons, errorHandler, togglerComponent, builder, _yield$builder$append, setKetcher, ketcherId, cleanup, setServer, ketcher;
33163
33505
  return _regeneratorRuntime.wrap(function _callee$(_context) {
33164
33506
  while (1) switch (_context.prev = _context.next) {
33165
33507
  case 0:
@@ -33175,15 +33517,20 @@ function _buildKetcherAsync() {
33175
33517
  _yield$builder$append = _context.sent;
33176
33518
  setKetcher = _yield$builder$append.setKetcher;
33177
33519
  ketcherId = _yield$builder$append.ketcherId;
33520
+ cleanup = _yield$builder$append.cleanup;
33521
+ setServer = _yield$builder$append.setServer;
33178
33522
  ketcher = builder.build();
33179
33523
  if (ketcher) {
33180
33524
  setKetcher(ketcher);
33181
33525
  }
33182
33526
  return _context.abrupt("return", {
33183
33527
  ketcher: ketcher,
33184
- ketcherId: ketcherId
33528
+ ketcherId: ketcherId,
33529
+ cleanup: cleanup,
33530
+ builder: builder,
33531
+ setServer: setServer
33185
33532
  });
33186
- case 13:
33533
+ case 15:
33187
33534
  case "end":
33188
33535
  return _context.stop();
33189
33536
  }
@@ -33201,30 +33548,60 @@ var mediaSizes = {
33201
33548
  smallHeight: 600
33202
33549
  };
33203
33550
  function Editor(props) {
33551
+ var initPromiseRef = useRef(null);
33552
+ var appRootRef = useRef(null);
33553
+ var cleanupRef = useRef(null);
33554
+ var ketcherBuilderRef = useRef(null);
33555
+ var setServerRef = useRef(function () {});
33556
+ var structServiceProvider = props.structServiceProvider;
33204
33557
  var rootElRef = useRef(null);
33205
- var onInit = props.onInit;
33206
33558
  var _useResizeObserver = useThrottleResizeObserver({
33207
33559
  ref: rootElRef
33208
33560
  }),
33209
33561
  height = _useResizeObserver.height,
33210
33562
  width = _useResizeObserver.width;
33211
33563
  useEffect(function () {
33212
- var appRoot = createRoot(rootElRef.current);
33213
- buildKetcherAsync(_objectSpread(_objectSpread({}, props), {}, {
33564
+ var _ketcherBuilderRef$cu;
33565
+ (_ketcherBuilderRef$cu = ketcherBuilderRef.current) === null || _ketcherBuilderRef$cu === void 0 || _ketcherBuilderRef$cu.reinitializeApi(props.structServiceProvider, setServerRef.current);
33566
+ }, [structServiceProvider]);
33567
+ var initKetcher = function initKetcher() {
33568
+ var _initPromiseRef$curre;
33569
+ appRootRef.current = createRoot(rootElRef.current);
33570
+ initPromiseRef.current = buildKetcherAsync(_objectSpread(_objectSpread({}, props), {}, {
33214
33571
  element: rootElRef.current,
33215
- appRoot: appRoot
33216
- })).then(function (_ref) {
33572
+ appRoot: appRootRef.current
33573
+ }));
33574
+ (_initPromiseRef$curre = initPromiseRef.current) === null || _initPromiseRef$curre === void 0 || _initPromiseRef$curre.then(function (_ref) {
33217
33575
  var ketcher = _ref.ketcher,
33218
- ketcherId = _ref.ketcherId;
33219
- if (typeof onInit === 'function' && ketcher) {
33220
- onInit(ketcher);
33576
+ ketcherId = _ref.ketcherId,
33577
+ cleanup = _ref.cleanup,
33578
+ builder = _ref.builder,
33579
+ setServer = _ref.setServer;
33580
+ cleanupRef.current = cleanup;
33581
+ ketcherBuilderRef.current = builder;
33582
+ setServerRef.current = setServer;
33583
+ if (typeof props.onInit === 'function' && ketcher) {
33584
+ props.onInit(ketcher);
33221
33585
  var ketcherInitEvent = new Event(ketcherInitEventName(ketcherId));
33222
33586
  window.dispatchEvent(ketcherInitEvent);
33223
33587
  }
33224
33588
  });
33589
+ };
33590
+ useEffect(function () {
33591
+ if (initPromiseRef.current === null) {
33592
+ initKetcher();
33593
+ } else {
33594
+ var _initPromiseRef$curre2;
33595
+ (_initPromiseRef$curre2 = initPromiseRef.current) === null || _initPromiseRef$curre2 === void 0 || _initPromiseRef$curre2["finally"](function () {
33596
+ initKetcher();
33597
+ });
33598
+ }
33225
33599
  return function () {
33226
- setTimeout(function () {
33227
- appRoot.unmount();
33600
+ var _initPromiseRef$curre3;
33601
+ (_initPromiseRef$curre3 = initPromiseRef.current) === null || _initPromiseRef$curre3 === void 0 || _initPromiseRef$curre3.then(function () {
33602
+ var _cleanupRef$current, _appRootRef$current;
33603
+ (_cleanupRef$current = cleanupRef.current) === null || _cleanupRef$current === void 0 || _cleanupRef$current.call(cleanupRef);
33604
+ (_appRootRef$current = appRootRef.current) === null || _appRootRef$current === void 0 || _appRootRef$current.unmount();
33228
33605
  });
33229
33606
  };
33230
33607
  }, []);
@@ -33234,5 +33611,5 @@ function Editor(props) {
33234
33611
  });
33235
33612
  }
33236
33613
 
33237
- export { Accordion$1 as Accordion, appContext as AppContext, Button, Dialog, Editor, EditorClassName, Icon, IconButton, IndigoProvider, InfoModal$1 as InfoModal, Input$2 as Input, KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR, KETCHER_ROOT_NODE_CLASS_NAME, KETCHER_ROOT_NODE_CSS_SELECTOR, MODES, STRUCT_TYPE, StructRender, getIconName, ketcherInitEventName };
33614
+ export { Accordion$1 as Accordion, appContext as AppContext, Button, Dialog, Editor, EditorClassName, Icon, IconButton, IndigoProvider, InfoModal$1 as InfoModal, Input$2 as Input, KETCHER_MACROMOLECULES_ROOT_NODE_SELECTOR, KETCHER_ROOT_NODE_CLASS_NAME, KETCHER_ROOT_NODE_CSS_SELECTOR, MODES, STRUCT_SERVICE_INITIALIZED_EVENT, STRUCT_SERVICE_NO_RENDER_INITIALIZED_EVENT, STRUCT_TYPE, StructRender, getIconName, ketcherInitEventName };
33238
33615
  //# sourceMappingURL=index.modern.js.map