@complat/react-spectra-editor 1.6.0 → 1.7.0

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.
@@ -0,0 +1,217 @@
1
+ "use strict";
2
+
3
+ var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
4
+ var _reduxMockStore = _interopRequireDefault(require("redux-mock-store"));
5
+ var _reactRedux = require("react-redux");
6
+ var _react = require("@testing-library/react");
7
+ require("@testing-library/jest-dom");
8
+ var _r05_submit_btn = _interopRequireDefault(require("../../../../components/cmd_bar/r05_submit_btn"));
9
+ var _jsxRuntime = require("react/jsx-runtime");
10
+ jest.mock('../../../../helpers/extractPeaksEdit', () => ({
11
+ extractPeaksEdit: jest.fn(() => [{
12
+ x: 1,
13
+ y: 2
14
+ }])
15
+ }));
16
+ const mockStore = (0, _reduxMockStore.default)([]);
17
+ const buildBaseState = (overrides = {}) => ({
18
+ editPeak: {
19
+ present: {
20
+ selectedIdx: 0,
21
+ peaks: [{
22
+ pos: [],
23
+ neg: []
24
+ }]
25
+ }
26
+ },
27
+ threshold: {
28
+ list: [{
29
+ isEdit: true,
30
+ value: 10,
31
+ upper: false,
32
+ lower: false
33
+ }]
34
+ },
35
+ layout: '1H',
36
+ shift: {
37
+ shifts: []
38
+ },
39
+ scan: {
40
+ target: 5,
41
+ isAuto: false
42
+ },
43
+ forecast: {
44
+ predictions: {}
45
+ },
46
+ submit: {
47
+ decimal: 2
48
+ },
49
+ integration: {
50
+ present: {
51
+ integrations: [{
52
+ stack: [],
53
+ refArea: 1,
54
+ refFactor: 1
55
+ }]
56
+ }
57
+ },
58
+ multiplicity: {
59
+ present: {
60
+ multiplicities: [{
61
+ stack: [],
62
+ shift: 0
63
+ }]
64
+ }
65
+ },
66
+ wavelength: {},
67
+ cyclicvolta: {
68
+ useCurrentDensity: false,
69
+ areaUnit: 'cm²',
70
+ areaValue: 1.0
71
+ },
72
+ curve: {
73
+ curveIdx: 0,
74
+ listCurves: []
75
+ },
76
+ axesUnits: {
77
+ axes: [{
78
+ xUnit: '',
79
+ yUnit: ''
80
+ }]
81
+ },
82
+ detector: {},
83
+ meta: {
84
+ dscMetaData: {}
85
+ },
86
+ ...overrides
87
+ });
88
+ const renderBtnSubmit = (state, operationValue) => {
89
+ const store = mockStore(state);
90
+ const feature = {
91
+ xUnit: 'ppm',
92
+ yUnit: 'intensity',
93
+ scanAutoTarget: 1,
94
+ thresRef: 3
95
+ };
96
+ const view = (0, _react.render)(/*#__PURE__*/(0, _jsxRuntime.jsx)(_reactRedux.Provider, {
97
+ store: store,
98
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_r05_submit_btn.default, {
99
+ operation: {
100
+ name: 'save',
101
+ value: operationValue
102
+ },
103
+ feature: feature,
104
+ isAscend: true,
105
+ isIntensity: true
106
+ })
107
+ }));
108
+ const button = view.container.querySelector('.btn-sv-bar-submit');
109
+ _react.fireEvent.click(button);
110
+ return view;
111
+ };
112
+ describe('<BtnSubmit payload contract />', () => {
113
+ it('sends a spectra_list with length 1 in single-spectrum mode', () => {
114
+ const operationValue = jest.fn();
115
+ const state = buildBaseState({
116
+ curve: {
117
+ curveIdx: 0,
118
+ listCurves: []
119
+ }
120
+ });
121
+ renderBtnSubmit(state, operationValue);
122
+ expect(operationValue).toHaveBeenCalledTimes(1);
123
+ const payload = operationValue.mock.calls[0][0];
124
+ expect(Array.isArray(payload.spectra_list)).toBe(true);
125
+ expect(payload.spectra_list).toHaveLength(1);
126
+ expect(payload).toHaveProperty('curveSt');
127
+ expect(payload.curveSt).toEqual({
128
+ curveIdx: 0
129
+ });
130
+ });
131
+ it('sends a spectra_list with length N in multi-spectrum mode', () => {
132
+ const operationValue = jest.fn();
133
+ const state = buildBaseState({
134
+ curve: {
135
+ curveIdx: 1,
136
+ listCurves: [{
137
+ feature: {
138
+ xUnit: 'ppm',
139
+ yUnit: 'intensity',
140
+ scanAutoTarget: 1,
141
+ thresRef: 3
142
+ }
143
+ }, {
144
+ feature: {
145
+ xUnit: 'ppm',
146
+ yUnit: 'intensity',
147
+ scanAutoTarget: 2,
148
+ thresRef: 4
149
+ }
150
+ }, {
151
+ feature: {
152
+ xUnit: 'ppm',
153
+ yUnit: 'intensity',
154
+ scanAutoTarget: 3,
155
+ thresRef: 5
156
+ }
157
+ }]
158
+ },
159
+ threshold: {
160
+ list: [{
161
+ value: 10
162
+ }, {
163
+ value: 20
164
+ }, {
165
+ value: 30
166
+ }]
167
+ },
168
+ axesUnits: {
169
+ axes: [{
170
+ xUnit: '',
171
+ yUnit: ''
172
+ }, {
173
+ xUnit: '',
174
+ yUnit: ''
175
+ }, {
176
+ xUnit: '',
177
+ yUnit: ''
178
+ }]
179
+ }
180
+ });
181
+ renderBtnSubmit(state, operationValue);
182
+ const payload = operationValue.mock.calls[0][0];
183
+ expect(payload.spectra_list).toHaveLength(3);
184
+ expect(payload.curveSt).toEqual({
185
+ curveIdx: 1
186
+ });
187
+ });
188
+ it('controls presence/absence of keepPred and simulatenmr', () => {
189
+ const withFlagsCb = jest.fn();
190
+ const noFlagsCb = jest.fn();
191
+ const withFlagsState = buildBaseState({
192
+ forecast: {
193
+ predictions: {
194
+ keepPred: true,
195
+ simulatenmr: false
196
+ }
197
+ }
198
+ });
199
+ renderBtnSubmit(withFlagsState, withFlagsCb);
200
+ const withFlagsPayload = withFlagsCb.mock.calls[0][0];
201
+ expect(withFlagsPayload.spectra_list[0]).toMatchObject({
202
+ keepPred: true,
203
+ simulatenmr: false
204
+ });
205
+ const noFlagsState = buildBaseState({
206
+ forecast: {
207
+ predictions: {
208
+ keepPred: 'yes'
209
+ }
210
+ }
211
+ });
212
+ renderBtnSubmit(noFlagsState, noFlagsCb);
213
+ const noFlagsPayload = noFlagsCb.mock.calls[0][0];
214
+ expect(noFlagsPayload.spectra_list[0]).not.toHaveProperty('keepPred');
215
+ expect(noFlagsPayload.spectra_list[0]).not.toHaveProperty('simulatenmr');
216
+ });
217
+ });
@@ -33,6 +33,35 @@ const styles = () => Object.assign({
33
33
  width: 100
34
34
  }
35
35
  }, _common.commonStyle);
36
+ const chemSubStyle = {
37
+ fontSize: '0.85em',
38
+ position: 'relative',
39
+ top: '0.24em',
40
+ lineHeight: 1
41
+ };
42
+ const renderReadableSubscript = (txt = '') => {
43
+ if (typeof txt !== 'string') return txt;
44
+ const regex = /([A-Za-z])(\d+)/g;
45
+ if (!regex.test(txt)) return txt;
46
+ regex.lastIndex = 0;
47
+ const parts = [];
48
+ let cursor = 0;
49
+ let match = regex.exec(txt);
50
+ while (match) {
51
+ const [raw, prefix, digits] = match;
52
+ const at = match.index;
53
+ if (at > cursor) parts.push(txt.slice(cursor, at));
54
+ parts.push(prefix);
55
+ parts.push(/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
56
+ style: chemSubStyle,
57
+ children: digits
58
+ }, `${at}-${digits}`));
59
+ cursor = at + raw.length;
60
+ match = regex.exec(txt);
61
+ }
62
+ if (cursor < txt.length) parts.push(txt.slice(cursor));
63
+ return parts;
64
+ };
36
65
  const shiftSelect = (classes, layoutSt, setShiftRefAct, shiftSt, curveSt) => {
37
66
  if (_cfg.default.hideSolvent(layoutSt)) {
38
67
  return null;
@@ -73,9 +102,9 @@ const shiftSelect = (classes, layoutSt, setShiftRefAct, shiftSt, curveSt) => {
73
102
  className: (0, _classnames.default)(classes.selectInput, 'input-sv-bar-shift'),
74
103
  children: listShift.map(ref => /*#__PURE__*/(0, _jsxRuntime.jsx)(_material.MenuItem, {
75
104
  value: ref.name,
76
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
105
+ children: /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
77
106
  className: (0, _classnames.default)(classes.txtOpt, 'option-sv-bar-shift'),
78
- children: `${ref.name}: ${_format.default.strNumberFixedDecimal(ref.value, 2)} ppm`
107
+ children: [renderReadableSubscript(ref.name), `: ${_format.default.strNumberFixedDecimal(ref.value, 2)} ppm`]
79
108
  })
80
109
  }, ref.name))
81
110
  })]
@@ -77,7 +77,14 @@ const defaultThreshold = {
77
77
  lower: false
78
78
  };
79
79
  const pickFromList = (list, index, fallback = null) => Array.isArray(list) && list[index] !== undefined ? list[index] : fallback;
80
- const buildDstPayload = ({
80
+ const hasBoolean = value => typeof value === 'boolean';
81
+ const resolveOptionalBooleanFlags = analysis => {
82
+ const flags = {};
83
+ if (hasBoolean(analysis?.keepPred)) flags.keepPred = analysis.keepPred;
84
+ if (hasBoolean(analysis?.simulatenmr)) flags.simulatenmr = analysis.simulatenmr;
85
+ return flags;
86
+ };
87
+ const buildSpectrumPayload = ({
81
88
  feature,
82
89
  curveIdx,
83
90
  editPeakSt,
@@ -87,11 +94,8 @@ const buildDstPayload = ({
87
94
  scanSt,
88
95
  integrationSt,
89
96
  multiplicitySt,
90
- allIntegrationSt,
91
- aucValues,
92
97
  waveLengthSt,
93
98
  cyclicvoltaSt,
94
- curveSt,
95
99
  axesUnitsSt,
96
100
  detectorSt,
97
101
  dscMetaData,
@@ -107,6 +111,7 @@ const buildDstPayload = ({
107
111
  const peaksEdit = (0, _extractPeaksEdit.extractPeaksEdit)(feature, editPeakAtIndex, threshold, shiftSt, layoutSt, curveIdx);
108
112
  const scan = (0, _chem.Convert2Scan)(feature, scanSt);
109
113
  const thres = (0, _chem.Convert2Thres)(feature, threshold);
114
+ const shift = pickFromList(shiftSt?.shifts, curveIdx, shiftSt);
110
115
  const integration = pickFromList(integrationSt?.integrations, curveIdx, integrationSt);
111
116
  const multiplicity = pickFromList(multiplicitySt?.multiplicities, curveIdx, multiplicitySt);
112
117
  const {
@@ -127,13 +132,11 @@ const buildDstPayload = ({
127
132
  axisDisplay,
128
133
  cvDisplay
129
134
  };
130
- const perCurveSt = Object.assign({}, curveSt, {
131
- curveIdx
132
- });
135
+ const optionalBooleanFlags = resolveOptionalBooleanFlags(analysis);
133
136
  return {
134
137
  peaks: peaksEdit,
135
138
  layout: layoutSt,
136
- shift: shiftSt,
139
+ shift,
137
140
  scan,
138
141
  thres,
139
142
  isAscend,
@@ -142,48 +145,28 @@ const buildDstPayload = ({
142
145
  decimal: decimalSt,
143
146
  integration,
144
147
  multiplicity,
145
- allIntegration: allIntegrationSt,
146
- aucValues,
147
148
  waveLength: waveLengthSt,
148
149
  cyclicvoltaSt: cyclicvoltaPayload,
149
- curveSt: perCurveSt,
150
+ curveSt: {
151
+ curveIdx
152
+ },
150
153
  axesUnitsSt,
151
154
  detectorSt,
152
- dscMetaData
155
+ dscMetaData,
156
+ ...optionalBooleanFlags
153
157
  };
154
158
  };
155
- const onClickCb = (operation, peaksEdit, isAscend, isIntensity, scan, thres, layoutSt, shiftSt, analysis, decimalSt, integrationSt, multiplicitySt, allIntegrationSt, aucValues, waveLengthSt, cyclicvoltaSt, curveSt, axesUnitsSt, detectorSt, dscMetaData, curveList, editPeakSt, thresList, scanSt, feature) => () => {
156
- const payload = {
157
- peaks: peaksEdit,
158
- layout: layoutSt,
159
- shift: shiftSt,
160
- scan,
161
- thres,
162
- isAscend,
163
- isIntensity,
164
- analysis,
165
- decimal: decimalSt,
166
- integration: integrationSt,
167
- multiplicity: multiplicitySt,
168
- allIntegration: allIntegrationSt,
169
- aucValues,
170
- waveLength: waveLengthSt,
171
- cyclicvoltaSt,
172
- curveSt,
173
- axesUnitsSt,
174
- detectorSt,
175
- dscMetaData
176
- };
159
+ const onClickCb = (operationValue, isAscend, isIntensity, layoutSt, shiftSt, analysis, decimalSt, integrationSt, multiplicitySt, waveLengthSt, cyclicvoltaSt, curveSt, axesUnitsSt, detectorSt, dscMetaData, curveList, editPeakSt, thresList, scanSt, feature) => () => {
177
160
  const defaultCurves = feature ? [{
178
161
  feature
179
162
  }] : [];
180
163
  const curves = Array.isArray(curveList) && curveList.length > 0 ? curveList : defaultCurves;
181
164
  const fallbackIdx = Number.isFinite(curveSt?.curveIdx) ? curveSt.curveIdx : 0;
182
165
  const indicesToSend = curves.length > 0 ? curves.map((_, index) => index) : [fallbackIdx];
183
- payload.dst_list = indicesToSend.map(curveIdx => {
166
+ const spectraList = indicesToSend.map(curveIdx => {
184
167
  const curve = curves[curveIdx] || {};
185
168
  const curveFeature = curve.feature || feature;
186
- return buildDstPayload({
169
+ return buildSpectrumPayload({
187
170
  feature: curveFeature,
188
171
  curveIdx,
189
172
  editPeakSt,
@@ -193,11 +176,8 @@ const onClickCb = (operation, peaksEdit, isAscend, isIntensity, scan, thres, lay
193
176
  scanSt,
194
177
  integrationSt,
195
178
  multiplicitySt,
196
- allIntegrationSt,
197
- aucValues,
198
179
  waveLengthSt,
199
180
  cyclicvoltaSt,
200
- curveSt,
201
181
  axesUnitsSt,
202
182
  detectorSt,
203
183
  dscMetaData,
@@ -207,7 +187,15 @@ const onClickCb = (operation, peaksEdit, isAscend, isIntensity, scan, thres, lay
207
187
  decimalSt
208
188
  });
209
189
  });
210
- operation(payload);
190
+ const payload = {
191
+ spectra_list: spectraList
192
+ };
193
+ if (Number.isFinite(curveSt?.curveIdx)) {
194
+ payload.curveSt = {
195
+ curveIdx: curveSt.curveIdx
196
+ };
197
+ }
198
+ operationValue(payload);
211
199
  };
212
200
  const BtnSubmit = ({
213
201
  classes,
@@ -216,7 +204,6 @@ const BtnSubmit = ({
216
204
  isAscend,
217
205
  isIntensity,
218
206
  editPeakSt,
219
- thresSt,
220
207
  thresList,
221
208
  layoutSt,
222
209
  shiftSt,
@@ -225,7 +212,6 @@ const BtnSubmit = ({
225
212
  decimalSt,
226
213
  integrationSt,
227
214
  multiplicitySt,
228
- allIntegrationSt,
229
215
  waveLengthSt,
230
216
  cyclicvoltaSt,
231
217
  curveSt,
@@ -234,11 +220,7 @@ const BtnSubmit = ({
234
220
  detectorSt,
235
221
  metaSt
236
222
  }) => {
237
- const peaksEdit = (0, _extractPeaksEdit.extractPeaksEdit)(feature, editPeakSt, thresSt, shiftSt, layoutSt);
238
223
  // const disBtn = peaksEdit.length === 0 || statusSt.btnSubmit || disabled;
239
- const scan = (0, _chem.Convert2Scan)(feature, scanSt);
240
- const thres = (0, _chem.Convert2Thres)(feature, thresSt);
241
- const aucValues = (0, _extractPeaksEdit.extractAreaUnderCurve)(allIntegrationSt, integrationSt, layoutSt);
242
224
  const {
243
225
  dscMetaData
244
226
  } = metaSt;
@@ -270,7 +252,7 @@ const BtnSubmit = ({
270
252
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_common.MuButton, {
271
253
  className: (0, _classnames.default)('btn-sv-bar-submit'),
272
254
  color: "primary",
273
- onClick: onClickCb(operation.value, peaksEdit, isAscend, isIntensity, scan, thres, layoutSt, shiftSt, forecastSt.predictions, decimalSt, integrationSt, multiplicitySt, allIntegrationSt, aucValues, waveLengthSt, cyclicvoltaPayload, curveSt, axesUnitsSt, detectorSt, dscMetaData, curveList, editPeakSt, thresList, scanSt, feature),
255
+ onClick: onClickCb(operation.value, isAscend, isIntensity, layoutSt, shiftSt, forecastSt.predictions, decimalSt, integrationSt, multiplicitySt, waveLengthSt, cyclicvoltaPayload, curveSt, axesUnitsSt, detectorSt, dscMetaData, curveList, editPeakSt, thresList, scanSt, feature),
274
256
  children: /*#__PURE__*/(0, _jsxRuntime.jsx)(_PlayCircleOutline.default, {
275
257
  className: classes.icon
276
258
  })
@@ -281,7 +263,6 @@ const mapStateToProps = (state, props) => (
281
263
  // eslint-disable-line
282
264
  {
283
265
  editPeakSt: state.editPeak.present,
284
- thresSt: state.threshold.list[state.curve.curveIdx],
285
266
  thresList: state.threshold.list,
286
267
  layoutSt: state.layout,
287
268
  shiftSt: state.shift,
@@ -290,7 +271,6 @@ const mapStateToProps = (state, props) => (
290
271
  decimalSt: state.submit.decimal,
291
272
  integrationSt: state.integration.present,
292
273
  multiplicitySt: state.multiplicity.present,
293
- allIntegrationSt: state.integration.past.concat(state.integration.present),
294
274
  waveLengthSt: state.wavelength,
295
275
  cyclicvoltaSt: state.cyclicvolta,
296
276
  curveSt: state.curve,
@@ -307,7 +287,6 @@ BtnSubmit.propTypes = {
307
287
  isIntensity: _propTypes.default.bool.isRequired,
308
288
  operation: _propTypes.default.oneOfType([_propTypes.default.object, _propTypes.default.bool]).isRequired,
309
289
  editPeakSt: _propTypes.default.object.isRequired,
310
- thresSt: _propTypes.default.object.isRequired,
311
290
  thresList: _propTypes.default.array.isRequired,
312
291
  layoutSt: _propTypes.default.string.isRequired,
313
292
  shiftSt: _propTypes.default.object.isRequired,
@@ -316,7 +295,6 @@ BtnSubmit.propTypes = {
316
295
  decimalSt: _propTypes.default.number.isRequired,
317
296
  integrationSt: _propTypes.default.object.isRequired,
318
297
  multiplicitySt: _propTypes.default.object.isRequired,
319
- allIntegrationSt: _propTypes.default.object.isRequired,
320
298
  waveLengthSt: _propTypes.default.object.isRequired,
321
299
  cyclicvoltaSt: _propTypes.default.object.isRequired,
322
300
  curveSt: _propTypes.default.object,
@@ -136,8 +136,12 @@ const styles = () => ({
136
136
  },
137
137
  rowEven: {
138
138
  backgroundColor: '#fafafa',
139
- textOverflow: 'clip',
140
- whiteSpace: 'normal'
139
+ textOverflow: 'ellipsis',
140
+ whiteSpace: 'nowrap'
141
+ },
142
+ cvModeWarning: {
143
+ color: 'red',
144
+ marginLeft: 12
141
145
  }
142
146
  });
143
147
  const CyclicVoltammetryPanel = ({
@@ -252,12 +256,17 @@ const CyclicVoltammetryPanel = ({
252
256
  }
253
257
  },
254
258
  "aria-expanded": isExpanded,
255
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Typography, {
259
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsxs)(_material.Typography, {
256
260
  className: "txt-panel-header",
257
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
261
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
258
262
  className: (0, _classnames.default)(classes.txtBadge, 'txt-sv-panel-title'),
259
263
  children: "Voltammetry data"
260
- })
264
+ }), ' - ', /*#__PURE__*/(0, _jsxRuntime.jsxs)("span", {
265
+ children: ["Mode: ", cyclicVotaSt.useCurrentDensity ? 'Current Density' : 'Current']
266
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
267
+ className: classes.cvModeWarning,
268
+ children: "WE-ECSA must be set when switching to Current Density."
269
+ })]
261
270
  }), /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
262
271
  className: classes.panelActions,
263
272
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)(_material.Tooltip, {
@@ -117,6 +117,35 @@ const normalizeQuillValue = val => {
117
117
  if (val === '<p><br></p>' || val === '<p></p>') return '';
118
118
  return val;
119
119
  };
120
+ const chemSubStyle = {
121
+ fontSize: '0.85em',
122
+ position: 'relative',
123
+ top: '0.24em',
124
+ lineHeight: 1
125
+ };
126
+ const renderReadableSubscript = (txt = '') => {
127
+ if (typeof txt !== 'string') return txt;
128
+ const regex = /([A-Za-z])(\d+)/g;
129
+ if (!regex.test(txt)) return txt;
130
+ regex.lastIndex = 0;
131
+ const parts = [];
132
+ let cursor = 0;
133
+ let match = regex.exec(txt);
134
+ while (match) {
135
+ const [raw, prefix, digits] = match;
136
+ const at = match.index;
137
+ if (at > cursor) parts.push(txt.slice(cursor, at));
138
+ parts.push(prefix);
139
+ parts.push(/*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
140
+ style: chemSubStyle,
141
+ children: digits
142
+ }, `${at}-${digits}`));
143
+ cursor = at + raw.length;
144
+ match = regex.exec(txt);
145
+ }
146
+ if (cursor < txt.length) parts.push(txt.slice(cursor));
147
+ return parts;
148
+ };
120
149
  const handleDescriptionChanged = (content, delta, source, editor, onDescriptionChanged) => {
121
150
  if (!onDescriptionChanged) return;
122
151
  onDescriptionChanged(normalizeQuillValue(content), delta, source, editor);
@@ -388,7 +417,7 @@ const InfoPanel = ({
388
417
  children: "Solv : "
389
418
  }), /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
390
419
  className: (0, _classnames.default)(classes.tTxt, 'txt-sv-panel-txt'),
391
- children: showSolvName
420
+ children: renderReadableSubscript(showSolvName)
392
421
  })]
393
422
  }) : null, _format.default.isMsLayout(layoutSt) && exactMass ? /*#__PURE__*/(0, _jsxRuntime.jsxs)("div", {
394
423
  className: (0, _classnames.default)(classes.rowRoot, classes.rowOdd),
@@ -422,18 +451,7 @@ const InfoPanel = ({
422
451
  layout: layoutSt,
423
452
  dscMetaData: dscMetaData,
424
453
  updateAction: updateDSCMetaDataAct
425
- }), !editorOnly && _format.default.isNmrLayout(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
426
- children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
427
- className: classes.subSectionHeader,
428
- children: simTitle()
429
- }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
430
- className: (0, _classnames.default)(classes.rowRoot, classes.rowOddSim),
431
- children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
432
- className: (0, _classnames.default)(classes.tTxt, classes.tTxtSim, 'txt-sv-panel-txt'),
433
- children: simContent(simulationSt.nmrSimPeaks)
434
- })
435
- })]
436
- }) : null, !_format.default.isCyclicVoltaLayout(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
454
+ }), !_format.default.isCyclicVoltaLayout(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
437
455
  children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
438
456
  className: classes.subSectionHeader,
439
457
  children: "Content"
@@ -450,6 +468,17 @@ const InfoPanel = ({
450
468
  onChange: (content, delta, source, editor) => handleDescriptionChanged(content, delta, source, editor, onDescriptionChanged)
451
469
  })
452
470
  })]
471
+ }) : null, !editorOnly && _format.default.isNmrLayout(layoutSt) ? /*#__PURE__*/(0, _jsxRuntime.jsxs)(_jsxRuntime.Fragment, {
472
+ children: [/*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
473
+ className: classes.subSectionHeader,
474
+ children: simTitle()
475
+ }), /*#__PURE__*/(0, _jsxRuntime.jsx)("div", {
476
+ className: (0, _classnames.default)(classes.rowRoot, classes.rowOddSim),
477
+ children: /*#__PURE__*/(0, _jsxRuntime.jsx)("span", {
478
+ className: (0, _classnames.default)(classes.tTxt, classes.tTxtSim, 'txt-sv-panel-txt'),
479
+ children: simContent(simulationSt.nmrSimPeaks)
480
+ })
481
+ })]
453
482
  }) : null]
454
483
  })]
455
484
  });
@@ -13,35 +13,35 @@ const noReference = {
13
13
  label: false
14
14
  };
15
15
  const cActicAcidD4Sept = {
16
- name: 'Acetic acid-d₄ (sept)',
16
+ name: 'Acetic acid-d4 (sept)',
17
17
  value: 20.0,
18
18
  label: 'Acetic acid-d4'
19
19
  };
20
20
  const cActicAcidD4S = {
21
- name: 'Acetic acid-d₄ (s)',
21
+ name: 'Acetic acid-d4 (s)',
22
22
  value: 178.990,
23
23
  label: 'Acetic acid-d4'
24
24
  };
25
25
  const cAcetoneD6Sep = {
26
- name: 'Acetone-d₆ (sep)',
26
+ name: 'Acetone-d6 (sep)',
27
27
  value: 29.640,
28
28
  label: 'Acetone-d6',
29
29
  nsdb: 'Acetone-D6 ((CD3)2CO)'
30
30
  };
31
31
  const cAcetoneD6Broad = {
32
- name: 'Acetone-d₆ (broad)',
32
+ name: 'Acetone-d6 (broad)',
33
33
  value: 206.260,
34
34
  label: 'Acetone-d6',
35
35
  nsdb: 'Acetone-D6 ((CD3)2CO)'
36
36
  };
37
37
  const cAcetonitrileD3Sep = {
38
- name: 'Acetonitrile-d₃ (sep)',
38
+ name: 'Acetonitrile-d3 (sep)',
39
39
  value: 1.32,
40
40
  label: 'Acetonitrile-d3',
41
41
  nsdb: 'Acetonitrile-D3(CD3CN)'
42
42
  };
43
43
  const cAcetonitrileD3S = {
44
- name: 'Acetonitrile-d₃ (s)',
44
+ name: 'Acetonitrile-d3 (s)',
45
45
  value: 118.26,
46
46
  label: 'Acetonitrile-d3',
47
47
  nsdb: 'Acetonitrile-D3(CD3CN)'
@@ -59,83 +59,83 @@ const cChloroformDT = {
59
59
  nsdb: 'Chloroform-D1 (CDCl3)'
60
60
  };
61
61
  const cCyclohexaneD12Quin = {
62
- name: 'Cyclohexane-d₁₂ (quin)',
62
+ name: 'Cyclohexane-d12 (quin)',
63
63
  value: 26.430,
64
64
  label: 'C$6D$1$2'
65
65
  };
66
66
  const cDichloromethaneD2Quin = {
67
- name: 'Dichloromethane-d₂ (quin)',
67
+ name: 'Dichloromethane-d2 (quin)',
68
68
  value: 53.84,
69
69
  label: 'CD$2Cl$2'
70
70
  };
71
71
  const cDmfD7Sep1 = {
72
- name: 'DMF-d₇ (sep)-1',
72
+ name: 'DMF-d7 (sep)-1',
73
73
  value: 29.76,
74
74
  label: 'DMF-d7'
75
75
  };
76
76
  const cDmfD7Sep2 = {
77
- name: 'DMF-d₇ (sep)-2',
77
+ name: 'DMF-d7 (sep)-2',
78
78
  value: 34.89,
79
79
  label: 'DMF-d7'
80
80
  };
81
81
  const cDmfD7T3 = {
82
- name: 'DMF-d₇ (t)-3',
82
+ name: 'DMF-d7 (t)-3',
83
83
  value: 163.15,
84
84
  label: 'DMF-d7'
85
85
  };
86
86
  const cDioxaneD8Quin = {
87
- name: 'Dioxane-d₈ (quin)',
87
+ name: 'Dioxane-d8 (quin)',
88
88
  value: 66.660,
89
89
  label: 'Dioxane-d8'
90
90
  };
91
91
  const cDmsoD6 = {
92
- name: 'DMSO-d₆',
92
+ name: 'DMSO-d6',
93
93
  value: 39.52,
94
94
  label: 'DMSO-d6',
95
95
  nsdb: 'Dimethylsulphoxide-D6 (DMSO-D6, C2D6SO)'
96
96
  };
97
97
  const cEthanolD6Sep = {
98
- name: 'Ethanol-d₆ (sep)',
98
+ name: 'Ethanol-d6 (sep)',
99
99
  value: 17.3,
100
100
  label: 'Ethanol-d6'
101
101
  };
102
102
  const cEthanolD6Quin = {
103
- name: 'Ethanol-d₆ (quin)',
103
+ name: 'Ethanol-d6 (quin)',
104
104
  value: 56.96,
105
105
  label: 'Ethanol-d6'
106
106
  };
107
107
  const cMethanolD4Sep = {
108
- name: 'Methanol-d₄ (sep)',
108
+ name: 'Methanol-d4 (sep)',
109
109
  value: 49.00,
110
110
  label: 'Methanol-d4',
111
111
  nsdb: 'Methanol-D4 (CD3OD)'
112
112
  };
113
113
  const cPyridineD5T1 = {
114
- name: 'Pyridine-d₅ (t)-1',
114
+ name: 'Pyridine-d5 (t)-1',
115
115
  value: 123.87,
116
116
  label: 'Pyridine-d5',
117
117
  nsdb: 'Pyridin-D5 (C5D5N)'
118
118
  };
119
119
  const cPyridineD5T2 = {
120
- name: 'Pyridine-d₅ (t)-2',
120
+ name: 'Pyridine-d5 (t)-2',
121
121
  value: 135.91,
122
122
  label: 'Pyridine-d5',
123
123
  nsdb: 'Pyridin-D5 (C5D5N)'
124
124
  };
125
125
  const cPyridineD5T3 = {
126
- name: 'Pyridine-d₅ (t)-3',
126
+ name: 'Pyridine-d5 (t)-3',
127
127
  value: 150.35,
128
128
  label: 'Pyridine-d5',
129
129
  nsdb: 'Pyridin-D5 (C5D5N)'
130
130
  };
131
131
  const cThfD8Quin1 = {
132
- name: 'THF-d₈ (quin)-1',
132
+ name: 'THF-d8 (quin)-1',
133
133
  value: 25.37,
134
134
  label: 'THF-d8 ',
135
135
  nsdb: 'Tetrahydrofuran-D8 (THF-D8, C4D4O)'
136
136
  };
137
137
  const cThfD8Quin2 = {
138
- name: 'THF-d₈ (quin)-2',
138
+ name: 'THF-d8 (quin)-2',
139
139
  value: 67.57,
140
140
  label: 'THF-d8 ',
141
141
  nsdb: 'Tetrahydrofuran-D8 (THF-D8, C4D4O)'
@@ -146,27 +146,27 @@ const cTmsS = {
146
146
  label: 'TMS'
147
147
  };
148
148
  const cTolueneD8Sep1 = {
149
- name: 'Toluene-d₈ (sep)-1',
149
+ name: 'Toluene-d8 (sep)-1',
150
150
  value: 20.4,
151
151
  label: 'Toluene-d8'
152
152
  };
153
153
  const cTolueneD8T2 = {
154
- name: 'Toluene-d₈ (t)-2',
154
+ name: 'Toluene-d8 (t)-2',
155
155
  value: 125.49,
156
156
  label: 'Toluene-d8'
157
157
  };
158
158
  const cTolueneD8T3 = {
159
- name: 'Toluene-d₈ (t)-3',
159
+ name: 'Toluene-d8 (t)-3',
160
160
  value: 128.33,
161
161
  label: 'Toluene-d8'
162
162
  };
163
163
  const cTolueneD8T4 = {
164
- name: 'Toluene-d₈ (t)-4',
164
+ name: 'Toluene-d8 (t)-4',
165
165
  value: 129.24,
166
166
  label: 'Toluene-d8'
167
167
  };
168
168
  const cTolueneD8T5 = {
169
- name: 'Toluene-d₈ (s)-5',
169
+ name: 'Toluene-d8 (s)-5',
170
170
  value: 137.86,
171
171
  label: 'Toluene-d8'
172
172
  };
@@ -181,54 +181,54 @@ const cTfaDQ2 = {
181
181
  label: 'TFA-d'
182
182
  };
183
183
  const cTrifluoroethanolD3Quin = {
184
- name: 'Trifluoroethanol-d₃ (quin)',
184
+ name: 'Trifluoroethanol-d3 (quin)',
185
185
  value: 61.80,
186
186
  label: 'Trifluoroethanol-d3'
187
187
  };
188
188
  const cTrifluoroethanolD3Broad = {
189
- name: 'Trifluoroethanol-d₃ (broad)',
189
+ name: 'Trifluoroethanol-d3 (broad)',
190
190
  value: 126.28,
191
191
  label: 'Trifluoroethanol-d3'
192
192
  };
193
193
  const cC6D5Cl1 = {
194
- name: 'C₆D₅Cl (s)',
194
+ name: 'C6D5Cl (s)',
195
195
  value: 134.19,
196
196
  label: 'C6D5Cl'
197
197
  };
198
198
  const cC6D5Cl2 = {
199
- name: 'C₆D₅Cl (t)-1',
199
+ name: 'C6D5Cl (t)-1',
200
200
  value: 129.26,
201
201
  label: 'C6D5Cl'
202
202
  };
203
203
  const cC6D5Cl3 = {
204
- name: 'C₆D₅Cl (t)-2',
204
+ name: 'C6D5Cl (t)-2',
205
205
  value: 128.25,
206
206
  label: 'C6D5Cl'
207
207
  };
208
208
  const cC6D5Cl4 = {
209
- name: 'C₆D₅Cl (t)-3',
209
+ name: 'C6D5Cl (t)-3',
210
210
  value: 125.96,
211
211
  label: 'C6D5Cl'
212
212
  };
213
213
  const LIST_SHIFT_13C = exports.LIST_SHIFT_13C = [noReference, cActicAcidD4Sept, cActicAcidD4S, cAcetoneD6Sep, cAcetoneD6Broad, cAcetonitrileD3Sep, cAcetonitrileD3S, cBenzeneT, cChloroformDT, cCyclohexaneD12Quin, cDichloromethaneD2Quin, cDmfD7Sep1, cDmfD7Sep2, cDmfD7T3, cDioxaneD8Quin, cDmsoD6, cEthanolD6Sep, cEthanolD6Quin, cMethanolD4Sep, cPyridineD5T1, cPyridineD5T2, cPyridineD5T3, cThfD8Quin1, cThfD8Quin2, cTmsS, cTolueneD8Sep1, cTolueneD8T2, cTolueneD8T3, cTolueneD8T4, cTolueneD8T5, cTfaDQ1, cTfaDQ2, cTrifluoroethanolD3Quin, cTrifluoroethanolD3Broad, cC6D5Cl1, cC6D5Cl2, cC6D5Cl3, cC6D5Cl4];
214
214
  const hActicAcidD4Quin = {
215
- name: 'Acetic acid-d₄ (quin)',
215
+ name: 'Acetic acid-d4 (quin)',
216
216
  value: 2.04,
217
217
  label: 'Acetic acid-d4'
218
218
  };
219
219
  const hActicAcidD4S = {
220
- name: 'Acetic acid-d₄ (s)',
220
+ name: 'Acetic acid-d4 (s)',
221
221
  value: 11.65,
222
222
  label: 'Acetic acid-d4'
223
223
  };
224
224
  const hAcetoneD6Quin = {
225
- name: 'Acetone-d₆ (quin)',
225
+ name: 'Acetone-d6 (quin)',
226
226
  value: 2.05,
227
227
  label: 'Acetone-d6',
228
228
  nsdb: 'Acetone-D6 ((CD3)2CO)'
229
229
  };
230
230
  const hAcetonitrileD3Qquin = {
231
- name: 'Acetonitrile-d₃ (quin)',
231
+ name: 'Acetonitrile-d3 (quin)',
232
232
  value: 1.94,
233
233
  label: 'Acetonitrile-d3',
234
234
  nsdb: 'Acetonitrile-D3(CD3CN)'
@@ -246,111 +246,111 @@ const hChloroformDS = {
246
246
  nsdb: 'Chloroform-D1 (CDCl3)'
247
247
  };
248
248
  const hCyclohexaneD12S = {
249
- name: 'Cyclohexane-d₁₂ (s)',
249
+ name: 'Cyclohexane-d12 (s)',
250
250
  value: 1.38,
251
251
  label: 'C$6D$1$2'
252
252
  };
253
253
  const hDeuteriumOxideS = {
254
- name: 'D₂O (s)',
254
+ name: 'D2O (s)',
255
255
  value: 4.79,
256
256
  label: 'D$2O',
257
257
  nsdb: 'Deuteriumoxide (D2O)'
258
258
  };
259
259
  const hDichloroethaneD4S = {
260
- name: 'Dichloroethane-d₄ (s)',
260
+ name: 'Dichloroethane-d4 (s)',
261
261
  value: 3.72,
262
262
  label: 'Dichloroethane-d4'
263
263
  };
264
264
  const hDichloromethaneD2T = {
265
- name: 'Dichloromethane-d₂ (t)',
265
+ name: 'Dichloromethane-d2 (t)',
266
266
  value: 5.32,
267
267
  label: 'CD2Cl2',
268
268
  nsdb: 'Methylenchloride-D2 (CD2Cl2)'
269
269
  };
270
270
  const hDMFD7Quin1 = {
271
- name: 'DMF-d₇ (quin)-1',
271
+ name: 'DMF-d7 (quin)-1',
272
272
  value: 2.75,
273
273
  label: 'DMF-d7'
274
274
  };
275
275
  const hDMFD7Quin2 = {
276
- name: 'DMF-d₇ (quin)-2',
276
+ name: 'DMF-d7 (quin)-2',
277
277
  value: 2.92,
278
278
  label: 'DMF-d7'
279
279
  };
280
280
  const hDMFD7Broad3 = {
281
- name: 'DMF-d₇ (broad)-3',
281
+ name: 'DMF-d7 (broad)-3',
282
282
  value: 8.03,
283
283
  label: 'DMF-d7'
284
284
  };
285
285
  const hDioxaneD8Broad = {
286
- name: 'Dioxane-d₈ (broad)',
286
+ name: 'Dioxane-d8 (broad)',
287
287
  value: 3.53,
288
288
  label: 'Dioxane-d8'
289
289
  };
290
290
  const hDMSOD6Quin = {
291
- name: 'DMSO-d₆ (quin)',
291
+ name: 'DMSO-d6 (quin)',
292
292
  value: 2.50,
293
293
  label: 'DMSO-d6',
294
294
  nsdb: 'Dimethylsulphoxide-D6 (DMSO-D6, C2D6SO)'
295
295
  };
296
296
  const hEthanolD6Broad1 = {
297
- name: 'Ethanol-d₆ (broad)-1',
297
+ name: 'Ethanol-d6 (broad)-1',
298
298
  value: 1.11,
299
299
  label: 'Ethanol-d6'
300
300
  };
301
301
  const hEthanolD6S2 = {
302
- name: 'Ethanol-d₆ (s)-2',
302
+ name: 'Ethanol-d6 (s)-2',
303
303
  value: 3.56,
304
304
  label: 'Ethanol-d6'
305
305
  };
306
306
  const hEthanolD6S3 = {
307
- name: 'Ethanol-d₆ (s)-3',
307
+ name: 'Ethanol-d6 (s)-3',
308
308
  value: 5.29,
309
309
  label: 'Ethanol-d6'
310
310
  };
311
311
  const hMethanolD4Quin = {
312
- name: 'Methanol-d₄ (quin)',
312
+ name: 'Methanol-d4 (quin)',
313
313
  value: 3.31,
314
314
  label: 'Methanol-d4',
315
315
  nsdb: 'Methanol-D4 (CD3OD)'
316
316
  };
317
317
  const hMethanolD4S = {
318
- name: 'Methanol-d₄ (s)',
318
+ name: 'Methanol-d4 (s)',
319
319
  value: 4.87,
320
320
  label: 'Methanol-d4',
321
321
  nsdb: 'Methanol-D4 (CD3OD)'
322
322
  };
323
323
  const hNitromethaneD3S = {
324
- name: 'Nitromethane-d₃ (s)',
324
+ name: 'Nitromethane-d3 (s)',
325
325
  value: 4.33,
326
326
  label: 'Nitromethane-d3'
327
327
  };
328
328
  const hPyridineD5Broad1 = {
329
- name: 'Pyridine-d₅ (broad)-1',
329
+ name: 'Pyridine-d5 (broad)-1',
330
330
  value: 7.22,
331
331
  label: 'Pyridine-d5',
332
332
  nsdb: 'Pyridin-D5 (C5D5N)'
333
333
  };
334
334
  const hPyridineD5Broad2 = {
335
- name: 'Pyridine-d₅ (broad)-2',
335
+ name: 'Pyridine-d5 (broad)-2',
336
336
  value: 7.58,
337
337
  label: 'Pyridine-d5',
338
338
  nsdb: 'Pyridin-D5 (C5D5N)'
339
339
  };
340
340
  const hPyridineD5Broad3 = {
341
- name: 'Pyridine-d₅ (broad)-3',
341
+ name: 'Pyridine-d5 (broad)-3',
342
342
  value: 8.74,
343
343
  label: 'Pyridine-d5',
344
344
  nsdb: 'Pyridin-D5 (C5D5N)'
345
345
  };
346
346
  const hTHFD8S1 = {
347
- name: 'THF-d₈ (s)-1',
347
+ name: 'THF-d8 (s)-1',
348
348
  value: 1.73,
349
349
  label: 'THF-d8',
350
350
  nsdb: 'Tetrahydrofuran-D8 (THF-D8, C4D4O)'
351
351
  };
352
352
  const hTHFD8S2 = {
353
- name: 'THF-d₈ (s)-2',
353
+ name: 'THF-d8 (s)-2',
354
354
  value: 3.58,
355
355
  label: 'THF-d8',
356
356
  nsdb: 'Tetrahydrofuran-D8 (THF-D8, C4D4O)'
@@ -361,22 +361,22 @@ const hTMSS = {
361
361
  label: 'TMS'
362
362
  };
363
363
  const hTolueneD8Quin = {
364
- name: 'Toluene-d₈ (quin)-1',
364
+ name: 'Toluene-d8 (quin)-1',
365
365
  value: 2.09,
366
366
  label: 'Toluene-d8'
367
367
  };
368
368
  const hTolueneD8Boad2 = {
369
- name: 'Toluene-d₈ (boad)-2',
369
+ name: 'Toluene-d8 (boad)-2',
370
370
  value: 6.98,
371
371
  label: 'Toluene-d8'
372
372
  };
373
373
  const hTolueneD8S3 = {
374
- name: 'Toluene-d₈ (s)-3',
374
+ name: 'Toluene-d8 (s)-3',
375
375
  value: 7.00,
376
376
  label: 'Toluene-d8'
377
377
  };
378
378
  const hTolueneD8Broad4 = {
379
- name: 'Toluene-d₈ (broad)-4',
379
+ name: 'Toluene-d8 (broad)-4',
380
380
  value: 7.09,
381
381
  label: 'Toluene-d8'
382
382
  };
@@ -386,12 +386,12 @@ const hTFADS = {
386
386
  label: 'TFA-d'
387
387
  };
388
388
  const hTrifluoroethanolD31 = {
389
- name: 'Trifluoroethanol-d₃-1',
389
+ name: 'Trifluoroethanol-d3-1',
390
390
  value: 3.88,
391
391
  label: 'Trifluoroethanol-d3'
392
392
  };
393
393
  const hTrifluoroethanolD32 = {
394
- name: 'Trifluoroethanol-d₃-2',
394
+ name: 'Trifluoroethanol-d3-2',
395
395
  value: 5.02,
396
396
  label: 'Trifluoroethanol-d3'
397
397
  };
@@ -415,6 +415,12 @@ const peaksWrapper = (layout, shift, atIndex = 0) => {
415
415
  };
416
416
  }
417
417
  const ops = spectraOps[layout];
418
+ if (!ops) {
419
+ return {
420
+ head: '',
421
+ tail: ''
422
+ };
423
+ }
418
424
  return {
419
425
  head: `${ops.head}${solvTxt} = `,
420
426
  tail: ops.tail
package/dist/index.js CHANGED
@@ -51,6 +51,24 @@ require("./__tests__/style/svg.css");
51
51
  var _jsxRuntime = require("react/jsx-runtime");
52
52
  /* eslint-disable prefer-object-spread, default-param-last, no-nested-ternary */
53
53
 
54
+ const pickSelectedSpectrumFromPayload = payload => {
55
+ const spectraList = payload?.spectra_list;
56
+ if (!Array.isArray(spectraList)) return payload || {};
57
+ if (spectraList.length === 0) return {};
58
+ const selectedIdx = Number.isFinite(payload?.curveSt?.curveIdx) ? payload.curveSt.curveIdx : 0;
59
+ return spectraList[selectedIdx] || spectraList[0] || {};
60
+ };
61
+ const normalizeShiftForFormatting = shift => {
62
+ if (shift && Array.isArray(shift.shifts)) return shift;
63
+ return {
64
+ selectedIdx: 0,
65
+ shifts: [shift || {
66
+ ref: {},
67
+ peak: false,
68
+ enable: true
69
+ }]
70
+ };
71
+ };
54
72
  const nmr1HEntity = _app.FN.ExtractJcamp(_nmr1h_jcamp.default);
55
73
  const nmr1HEntity2 = _app.FN.ExtractJcamp(_nmr1h_2_jcamp.default);
56
74
  const nmr13CEntity = _app.FN.ExtractJcamp(_nmr13c_jcamp.default);
@@ -280,6 +298,7 @@ class DemoWriteIr extends _react.default.Component {
280
298
  curveSt
281
299
  }) {
282
300
  const entity = this.loadEntity();
301
+ const safeLayout = layout || entity?.layout;
283
302
  const {
284
303
  features
285
304
  } = entity;
@@ -294,11 +313,12 @@ class DemoWriteIr extends _react.default.Component {
294
313
  maxY,
295
314
  minY
296
315
  };
316
+ const shiftForFormatting = normalizeShiftForFormatting(shift);
297
317
  const body = _app.FN.peaksBody({
298
318
  peaks,
299
- layout,
319
+ layout: safeLayout,
300
320
  decimal,
301
- shift,
321
+ shift: shiftForFormatting,
302
322
  isAscend,
303
323
  isIntensity,
304
324
  boundary,
@@ -306,9 +326,9 @@ class DemoWriteIr extends _react.default.Component {
306
326
  waveLength,
307
327
  temperature
308
328
  });
309
- const wrapper = _app.FN.peaksWrapper(layout, shift);
329
+ const wrapper = _app.FN.peaksWrapper(safeLayout, shiftForFormatting);
310
330
  let desc = this.rmDollarSign(wrapper.head) + body + wrapper.tail;
311
- if (_app.FN.isCyclicVoltaLayout(layout)) {
331
+ if (_app.FN.isCyclicVoltaLayout(safeLayout) && cyclicvoltaSt?.spectraList && curveSt?.listCurves) {
312
332
  const {
313
333
  spectraList
314
334
  } = cyclicvoltaSt;
@@ -318,6 +338,7 @@ class DemoWriteIr extends _react.default.Component {
318
338
  } = curveSt;
319
339
  const selectedVolta = spectraList[curveIdx];
320
340
  const selectedCurve = listCurves[curveIdx];
341
+ if (!selectedVolta || !selectedCurve?.feature) return desc;
321
342
  const {
322
343
  feature
323
344
  } = selectedCurve;
@@ -380,10 +401,12 @@ class DemoWriteIr extends _react.default.Component {
380
401
  };
381
402
  const area = it.area * refFactor / refArea; // eslint-disable-line
382
403
  const center = _app.FN.calcMpyCenter(peaks, shiftVal, mpyType);
404
+ const safeCenter = Number.isFinite(center) ? center : 0;
383
405
  const xs = m.peaks.map(p => p.x).sort((a, b) => a - b);
384
406
  const [aIdx, bIdx] = isAscend ? [0, xs.length - 1] : [xs.length - 1, 0];
385
- const mxA = mpyType === 'm' ? (xs[aIdx] - shiftVal).toFixed(decimal) : 0;
386
- const mxB = mpyType === 'm' ? (xs[bIdx] - shiftVal).toFixed(decimal) : 0;
407
+ const hasValidRange = xs.length > 0 && Number.isFinite(shiftVal);
408
+ const mxA = mpyType === 'm' && hasValidRange ? (xs[aIdx] - shiftVal).toFixed(decimal) : safeCenter.toFixed(decimal);
409
+ const mxB = mpyType === 'm' && hasValidRange ? (xs[bIdx] - shiftVal).toFixed(decimal) : safeCenter.toFixed(decimal);
387
410
  return Object.assign({}, m, {
388
411
  area,
389
412
  center,
@@ -400,22 +423,25 @@ class DemoWriteIr extends _react.default.Component {
400
423
  const location = type === 'm' ? `${m.mxA}–${m.mxB}` : `${c.toFixed(decimal)}`;
401
424
  return m.js.length === 0 ? `${location} (${type}${atomCount})` : `${location} (${type}, ${js}${atomCount})`;
402
425
  }).join(', ');
426
+ const shiftRef = shift?.ref || {};
403
427
  const {
404
428
  label,
405
429
  value,
406
430
  name
407
- } = shift.ref;
408
- const solvent = label ? `${name.split('(')[0].trim()} [${value.toFixed(decimal)} ppm], ` : '';
431
+ } = shiftRef;
432
+ const hasValidShiftRef = !!label && Number.isFinite(value) && typeof name === 'string';
433
+ const solvent = hasValidShiftRef ? `${name.split('(')[0].trim()} [${value.toFixed(decimal)} ppm], ` : '';
409
434
  return `${layout} NMR (${freqStr}${solvent}ppm) δ = ${str}.`;
410
435
  }
411
- writeMpy({
412
- layout,
413
- shift,
414
- isAscend,
415
- decimal,
416
- multiplicity,
417
- integration
418
- }) {
436
+ writeMpy(payload) {
437
+ const {
438
+ layout,
439
+ shift,
440
+ isAscend,
441
+ decimal,
442
+ multiplicity,
443
+ integration
444
+ } = pickSelectedSpectrumFromPayload(payload);
419
445
  if (!_app.FN.isNmrLayout(layout)) return;
420
446
  const desc = this.formatMpy({
421
447
  multiplicity,
@@ -429,18 +455,19 @@ class DemoWriteIr extends _react.default.Component {
429
455
  desc
430
456
  });
431
457
  }
432
- writePeak({
433
- peaks,
434
- layout,
435
- shift,
436
- isAscend,
437
- decimal,
438
- isIntensity,
439
- integration,
440
- waveLength,
441
- cyclicvoltaSt,
442
- curveSt
443
- }) {
458
+ writePeak(payload) {
459
+ const {
460
+ peaks,
461
+ layout,
462
+ shift,
463
+ isAscend,
464
+ decimal,
465
+ isIntensity,
466
+ integration,
467
+ waveLength,
468
+ cyclicvoltaSt,
469
+ curveSt
470
+ } = pickSelectedSpectrumFromPayload(payload);
444
471
  const desc = this.formatPks({
445
472
  peaks,
446
473
  layout,
@@ -458,19 +485,21 @@ class DemoWriteIr extends _react.default.Component {
458
485
  desc
459
486
  });
460
487
  }
461
- savePeaks({
462
- peaks,
463
- layout,
464
- shift,
465
- isAscend,
466
- decimal,
467
- analysis,
468
- isIntensity,
469
- integration,
470
- multiplicity,
471
- waveLength
472
- }) {
488
+ savePeaks(payload) {
489
+ const {
490
+ peaks,
491
+ layout,
492
+ shift,
493
+ isAscend,
494
+ decimal,
495
+ analysis,
496
+ isIntensity,
497
+ integration,
498
+ multiplicity,
499
+ waveLength
500
+ } = pickSelectedSpectrumFromPayload(payload);
473
501
  const entity = this.loadEntity();
502
+ const safeLayout = layout || entity?.layout;
474
503
  const {
475
504
  features
476
505
  } = entity;
@@ -485,11 +514,12 @@ class DemoWriteIr extends _react.default.Component {
485
514
  maxY,
486
515
  minY
487
516
  };
517
+ const shiftForFormatting = normalizeShiftForFormatting(shift);
488
518
  const body = _app.FN.peaksBody({
489
519
  peaks,
490
- layout,
520
+ layout: safeLayout,
491
521
  decimal,
492
- shift,
522
+ shift: shiftForFormatting,
493
523
  isAscend,
494
524
  isIntensity,
495
525
  boundary,
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@complat/react-spectra-editor",
3
- "version": "1.6.0",
3
+ "version": "1.7.0",
4
4
  "description": "An editor to View and Edit Chemical Spectra data (NMR, IR, MS, CV, UIVIS, XRD, GC, and DSC).",
5
5
  "repository": {
6
6
  "type": "git",