@zakodium/nmrium-core 0.2.3 → 0.4.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.
@@ -1,4 +1,5 @@
1
1
  import type { CorrelationData } from 'nmr-correlation';
2
+ import type { ExtraFileContent } from 'file-collection';
2
3
  import type { FifoLoggerOptions } from 'fifo-logger';
3
4
  import { FileCollection } from 'file-collection';
4
5
  import type { FileItem } from 'file-collection';
@@ -17,6 +18,7 @@ import type { Peaks } from '@zakodium/nmr-types';
17
18
  import type { Ranges } from '@zakodium/nmr-types';
18
19
  import type { ReactNode } from 'react';
19
20
  import type { Source } from 'file-collection';
21
+ import type { ZipFileContent } from 'file-collection';
20
22
  import type { Zones } from '@zakodium/nmr-types';
21
23
 
22
24
  export declare interface ACSExportOptions {
@@ -138,7 +140,9 @@ export declare interface BaseNucleusPreferences<T> {
138
140
 
139
141
  declare interface BaseSpectrum {
140
142
  id: string;
143
+ sourceId?: string;
141
144
  sourceSelector?: NmrLoaderSelectors;
145
+ fileCollectionId?: string;
142
146
  meta: Metadata;
143
147
  customInfo: any;
144
148
  }
@@ -210,7 +214,7 @@ declare interface ContourOptions_2 {
210
214
 
211
215
  export declare type ContoursLevels = Record<string, Level>;
212
216
 
213
- export declare const CURRENT_EXPORT_VERSION = 9;
217
+ export declare const CURRENT_EXPORT_VERSION = 10;
214
218
 
215
219
  export declare type CustomWorkspaces = Record<string, InnerWorkspace>;
216
220
 
@@ -375,7 +379,7 @@ export declare const generateID: () => `${string}-${string}-${string}-${string}-
375
379
  */
376
380
  export declare function getOneIfArray<T extends PosibleInput>(data: T | T[], index?: number): T;
377
381
 
378
- declare type IncludeData = 'rawData' | 'dataSource' | 'noData';
382
+ export declare type IncludeData = 'rawData' | 'dataSource' | 'noData' | 'selfContained' | 'selfContainedExternalDatasource';
379
383
 
380
384
  declare interface InfoBlock {
381
385
  visible: boolean;
@@ -487,25 +491,43 @@ export declare interface MultipleSpectraAnalysisPreferences {
487
491
 
488
492
  export declare class NMRiumCore {
489
493
  #private;
490
- readonly version = 9;
494
+ readonly version = 10;
491
495
  registerPlugin(plugin: NMRiumPlugin): void;
492
496
  registerPlugins(plugins: NMRiumPlugin[]): void;
493
497
  private migrate;
494
498
  read(input: FileCollection | FileItem, options?: Partial<ParsingOptions>): ReturnType<typeof read>;
495
- readNMRiumObject(nmriumObjectInput: object, options?: ParsingOptions): Promise<Partial<NmriumState>>;
496
- readFromWebSource(source: Source, options?: ParsingOptions): Promise<Partial<NmriumState>>;
499
+ readNMRiumArchive(input: ZipFileContent, options?: Partial<ParsingOptions>): ReturnType<typeof readNMRiumArchive>;
500
+ readNMRiumObject(nmriumObjectInput: object, options?: ParsingOptions): ReturnType<typeof readNMRiumObject>;
501
+ readFromWebSource(source: Source, options?: ParsingOptions): Promise<[state: Partial<NmriumState>, fileCollection: FileCollection]>;
502
+ /**
503
+ * Serialize a state to nmrium object.
504
+ * It can be serialized to json then,
505
+ * it should be saved in a file with the extension ".nmrium"
506
+ * And served with the content-type "application/nmrium+json"
507
+ * or "application/nmrium+json+zip" if it is a single .nmrium file in a zip archive.
508
+ * @param nmriumState
509
+ * @param options
510
+ */
497
511
  serializeNmriumState(nmriumState: NmriumState, options?: SerializeNmriumStateOptions): SerializedNmriumState;
512
+ /**
513
+ * Serialize nmrium state to nmrium archive.
514
+ * It should be save in a file with the extension ".nmrium.zip"
515
+ * and served with the content-type "application/nmrium+zip".
516
+ * @param options
517
+ */
518
+ serializeNmriumArchive(options: SerializeNmriumArchiveOptions): Promise<Uint8Array<ArrayBuffer>>;
519
+ serializePlugins(): NmriumStatePlugins;
498
520
  slot(slot: SupportedUISlot): IteratorObject<[pluginId: string, Component: PluginUIComponent], void>;
499
521
  }
500
522
 
501
523
  export declare interface NmriumData extends BaseNmriumData {
502
524
  spectra: Spectrum[];
503
- source?: Source;
525
+ sources?: SourceNmriumData[];
504
526
  }
505
527
 
506
528
  export declare interface NmriumDataSource extends BaseNmriumData {
507
529
  spectra: SpectraSource[];
508
- source: Source;
530
+ sources: SourceNmriumData[];
509
531
  }
510
532
 
511
533
  export declare interface NMRiumGeneralPreferences {
@@ -686,8 +708,12 @@ export declare interface NMRiumPluginMigration {
686
708
 
687
709
  export declare interface NMRiumPluginOnReadProcess {
688
710
  /**
689
- * Hooks on processFileCollection, in first steps, to extract data from file collection.
711
+ * Hooks on processFileCollection, in first steps, to extract data from a file collection.
690
712
  * Usefully to parse files like nmredata, jcamp, bruker, etc.
713
+ *
714
+ * Plugins implementing this hook must return a nmrium data object.
715
+ * Spectra contained must include a sourceSelector with subset files used to extract the spectra.
716
+ *
691
717
  * @param files
692
718
  * @param options
693
719
  */
@@ -701,6 +727,12 @@ export declare interface NMRiumPluginOnReadProcess {
701
727
  * Hooks on processFileCollection, on file iteration.
702
728
  * Each file could be processed by all plugins to load and merge to nmrium data.
703
729
  * use `supportedExtensions` to filter files to be processed by the plugin.
730
+ *
731
+ * Plugins implementing this hook must return a nmrium data object.
732
+ * Each spectrum contained must include a sourceSelector with the file used to extract spectra.
733
+ * If the file contains multiple spectra,
734
+ * sourceSelector must explain have extra metadata to link to this specific spectrum.
735
+ *
704
736
  * @param file
705
737
  * @param options
706
738
  */
@@ -820,11 +852,6 @@ export declare interface ParsingOptions {
820
852
  name?: string;
821
853
  converter?: Partial<ParsingOptionsConverter>;
822
854
  sourceSelector?: Partial<NmrLoaderSelectors>;
823
- /**
824
- * if it is true the source object with files will be keeped
825
- * @default false
826
- */
827
- keepSource?: boolean;
828
855
  onLoadProcessing?: OnLoadProcessing;
829
856
  experimentalFeatures?: boolean;
830
857
  logger?: Logger;
@@ -1026,6 +1053,35 @@ export declare interface RangesViewState {
1026
1053
 
1027
1054
  declare function read(_options: ReadOptions): Promise<ReadReturn>;
1028
1055
 
1056
+ declare function readNMRiumArchive(_options: ReadNMRiumArchiveOptions): Promise<readonly [NmriumState, Map<string, FileCollection>]>;
1057
+
1058
+ declare interface ReadNMRiumArchiveOptions {
1059
+ input: ZipFileContent;
1060
+ options?: Partial<ParsingOptions>;
1061
+ plugins: Map<string, NMRiumPlugin>;
1062
+ migrator: (state: object) => any;
1063
+ }
1064
+
1065
+ declare function readNMRiumObject(_options: ReadNMRiumObjectOptions): Promise<ReadNMRiumObjectReturn>;
1066
+
1067
+ declare interface ReadNMRiumObjectOptions {
1068
+ nmriumObjectInput: object;
1069
+ migrator: (state: object) => any;
1070
+ plugins: Map<string, NMRiumPlugin>;
1071
+ options?: ParsingOptions;
1072
+ }
1073
+
1074
+ declare type ReadNMRiumObjectReturn = [
1075
+ /**
1076
+ * State read from `nmriumObjectInput`
1077
+ */
1078
+ state: Partial<NmriumState>,
1079
+ /**
1080
+ * A map of file collection where the key is the source id
1081
+ */
1082
+ fileCollections: Map<string, FileCollection>
1083
+ ];
1084
+
1029
1085
  declare interface ReadOptions {
1030
1086
  input: FileCollection | FileItem;
1031
1087
  migrator: (state: object) => any;
@@ -1036,19 +1092,59 @@ declare interface ReadOptions {
1036
1092
  declare interface ReadReturn {
1037
1093
  nmriumState: Partial<NmriumState>;
1038
1094
  containsNmrium: boolean;
1095
+ fileCollection: FileCollection;
1039
1096
  }
1040
1097
 
1041
- declare type SerializedNmriumState = Omit<Partial<NmriumState>, 'data'> & {
1098
+ export declare type SerializedNmriumState = Omit<Partial<NmriumState>, 'data'> & {
1042
1099
  version: number;
1043
1100
  data?: NmriumData | NmriumDataSource;
1044
1101
  };
1045
1102
 
1046
- declare interface SerializeNmriumStateOptions {
1103
+ export declare interface SerializeNmriumArchiveOptions {
1104
+ /**
1105
+ * Spectra to include in the archive.
1106
+ * Must be tracked by nmrium applications to be able to serialize them into a nmrium archive.
1107
+ */
1108
+ spectra: Spectrum[];
1109
+ /**
1110
+ * Molecules to include in the archive.
1111
+ * Must be tracked by nmrium applications to be able to serialize them into a nmrium archive.
1112
+ */
1113
+ molecules: StateMolecule[];
1114
+ /**
1115
+ * FileCollections to include in the archive.
1116
+ * Applications managing a NMRium State are in charge to memorize files collections aside the state,
1117
+ * to be able to serialize them into a nmrium archive.
1118
+ * Record key is linked to source id
1119
+ * Key can be orphan (no related source).
1120
+ * It generally means that data was imported from a local file.
1121
+ * */
1122
+ fileCollections: Record<string, FileCollection>;
1123
+ /**
1124
+ * If true, it will include all the data in to the archive even if they are referenced sources as external files.
1125
+ * If false, it will include only the data not referenced by sources as external files (index.json sources).
1126
+ * @default true
1127
+ * */
1128
+ includeData?: boolean;
1129
+ /**
1130
+ * Serialized state of nmrium. Produced by core.serializeNmriumState() or a transformation to NMRiumState.
1131
+ * As a blob or buffer ready to be put into an archive.
1132
+ * */
1133
+ serializedState: ExtraFileContent;
1134
+ }
1135
+
1136
+ export declare function serializeNmriumState(nmriumState: NmriumState, plugins: Map<string, NMRiumPlugin>, options?: SerializeNmriumStateOptions): SerializedNmriumState;
1137
+
1138
+ export declare interface SerializeNmriumStateOptions {
1047
1139
  includeData?: IncludeData;
1048
1140
  includeSettings?: boolean;
1049
1141
  includeView?: boolean;
1050
1142
  }
1051
1143
 
1144
+ declare interface SourceNmriumData extends Source {
1145
+ id: string;
1146
+ }
1147
+
1052
1148
  export declare interface SpectraAnalysisColumn {
1053
1149
  type: AnalysisColumnsTypes;
1054
1150
  valueKey: AnalysisColumnsValuesKeys;
@@ -1139,6 +1235,9 @@ export declare interface StateMolecule {
1139
1235
  id?: string;
1140
1236
  molfile: string;
1141
1237
  label?: string;
1238
+ sourceId?: string;
1239
+ sourceSelector?: NmrLoaderSelectors;
1240
+ fileCollectionId?: string;
1142
1241
  }
1143
1242
 
1144
1243
  declare interface StructuresPreferences {
@@ -1,4 +1,6 @@
1
- var ue={NORMAL:"NORMAL",FORMULA:"FORMULA"};var me={RELATIVE:"relative",ABSOLUTE:"absolute",MIN:"min",MAX:"max"};var fe=[{name:"pixels",unit:"px"},{name:"inches",unit:"in"},{name:"feet",unit:"ft"},{name:"yards",unit:"yd"},{name:"centimeters",unit:"cm"},{name:"millimeters",unit:"mm"},{name:"meters",unit:"m"},{name:"points",unit:"pt"},{name:"picas",unit:"pc"}];var P=9;var ge=[{key:"CT",description:"CT from NMR Solutions"}];import{isAnyArray as Se}from"is-any-array";import{xMultiply as j}from"ml-spectra-processing";var de=crypto.randomUUID.bind(crypto),b=de;function N(e){let{id:t=b(),meta:o,peaks:r={},filters:n=[],info:i={},ranges:p={},integrals:s={},selector:a,dependentVariables:l=[],...u}=e,c={id:t,meta:o,filters:n},{data:d=ye(l[0].components)}=e;if(Array.isArray(i.nucleus)&&(i.nucleus=i.nucleus[0]),c.data={x:[],re:[],im:[],...d},"scaleFactor"in i){let{scaleFactor:m}=i,{re:g,im:S}=c.data;j(g,m,{output:g}),S&&j(S,m,{output:S})}a&&(c.selector=a);let f=Se(d.im);if(c.info={phc0:0,phc1:0,nucleus:"1H",isFid:!1,isComplex:f,dimension:1,name:i?.name||t,...i},i.isFid&&i.reverse&&f){let{im:m}=c.data;j(m,-1,{output:m}),c.info.reverse=!1}return c.display={isVisible:!0,isPeaksMarkersVisible:!0,isRealSpectrumVisible:!0,isVisibleInDomain:!0,...e.display},c.peaks={values:[],options:{},...r},c.ranges={values:[],options:{sum:null,isSumConstant:!0,sumAuto:!0},...p},c.integrals={values:[],options:{},...s},{...u,...c}}function ye(e){let t=e[0]?.data?.x||[],o=e[0]?.data?.re||e[0]?.data?.y||[],r=e[0]?.data?.im||e[1]?.data?.y||null;return t.length>0&&t[0]>t[1]&&(t.reverse(),o.reverse(),r&&r.reverse()),{x:t,re:o,im:r}}import{matrixToArray as Pe,xMinMaxValues as xe,xNoiseSanPlot as be}from"ml-spectra-processing";var L={z:[[]],minX:0,minY:0,maxX:0,maxY:0},Ne={re:L,im:L},he={rr:L};function O(e){let{id:t=b(),meta:o={},dependentVariables:r=[],info:n={},filters:i=[],zones:p=[],...s}=e,a={id:t,meta:o,filters:i};a.info={nucleus:["1H","1H"],isFid:!1,isComplex:!1,name:n?.name||b(),...n},a.originalInfo=structuredClone(a.info),a.display={isPositiveVisible:!0,isNegativeVisible:!0,isVisible:!0,dimension:2,...e.display,...e.display};let{data:l=r[0].components}=e;if(a.data={...a.info.isFid?Ne:he,...l},a.originalData=structuredClone(a.data),!("spectrumSize"in n)){let u=n.isFid?"re":"rr",c=a.data[u].z.length,d=c>0?a.data[u].z[0].length:0;a.info.spectrumSize=[d,c]}if(!n.isFid){let u=a.data.rr,c=Pe(u.z),{positive:d,negative:f}=be(c),{min:m,max:g}=xe(c);a.data.rr={...u,minZ:m,maxZ:g},a.info.noise={positive:d,negative:f}}return a.zones={values:[],options:{},...p},{...s,...a}}import{xSequentialFillFromTo as Oe}from"ml-spectra-processing";import{isAnyArray as De}from"is-any-array";function U(e,t=0){if(De(e)){let o=e.at(t);if(o!==void 0)return o;throw new RangeError("An array with a index out of boundaries")}return e}var Re=new Set(["t1ir","T1"]);function J(e){let t=[];for(let o of e){let{info:{pulseSequence:r,isFid:n}}=o,{data:i,info:p,meta:{vdlistValues:s=[]}}=o;if(!(r&&Re.has(r))||s.length===0){t.push(o);continue}let l=n?"re":"rr",u={};for(let y in p)u[y]=U(p[y]);let{z:c,maxX:d,minX:f}=i[l],m=Oe({from:f,to:d,size:c[0].length}),[g,S]=Ie(o);for(let y=0;y<s.length;y++){let h={re:m,x:m};for(let D in i)h[Ce(D)]=i[D].z.at(g*(y+S));t.push(N({data:h,info:{...u,name:`${u.name}_${s[y]}`,dimension:1,vd:s[y]}}))}}return t}function Ce(e){return["rr","re"].includes(e)?"re":["im","ri","ir","ii"].includes(e)?"im":"x"}function Ie(e){let{meta:{PAGE:t}}=e,o=!0;if(t){let r=n=>Number.parseFloat(n.replace(/[F|T]1=/,""));o=r(t[0])>r(t[2])}return o?[-1,1]:[1,0]}var ve=2,Ae=1;function Te(e){let{spectra:t=[],molecules:o}=e,r=[];for(let n of t){let{info:i}=n;switch(i.dimension){case Ae:r.push(N(n));break;case ve:r.push(O(n));break;default:throw new Error("dimension does not supported")}}return{molecules:o,spectra:J(r)}}function we(e){return e}function R(e,t){e.plugins||(e.plugins={});let o=e.plugins;for(let r of t.values()){if(!r.shouldSerialize){delete o[r.id];continue}o[r.id]||(o[r.id]={id:r.id,version:r.version}),o[r.id].id=r.id,o[r.id].version=r.version}}function x(e,t){return JSON.parse(JSON.stringify(e),function(r,n){if(r in t){this[t[r]]=n;return}return n})}function V(e){if(e?.version===1)return e;let t={...e,version:1},o={j:"js",signal:"signals",integral:"integration",peak:"peaks",diaID:"diaIDs"};for(let r of t.spectra){if(r.ranges){let n=x(r.ranges,o);r.ranges=Array.isArray(n)?{values:n}:n}else if(r.zones){let n=x(r.zones,o);r.zones=Array.isArray(n)?{values:n}:n}r.peaks&&(r.peaks=Array.isArray(r.peaks)?{values:r.peaks}:r.peaks),r.integrals&&(r.integrals=Array.isArray(r.integrals)?{values:r.integrals}:r.integrals)}return t}function _(e){if(e?.version===2)return e;let t={...e,version:2},o={peaks:{delta:"x",originDelta:"originalX",intensity:"y"},ranges:{atomIDs:"atoms",intensity:"y"}};for(let r of t.spectra)r.peaks?r.peaks=x(r.peaks,o.peaks):r.ranges?r.ranges=x(r.ranges,o.ranges):r.zones&&(r.zones.values=Ee(r.zones.values));return t}function Ee(e){return e.map(t=>(t.signals&&(t.signals=t.signals.map(o=>{if(o.x&&o.y){let{x:{fromTo:r,...n},y:{fromTo:i,...p}}=o;o={...o,x:{...n,...r},y:{...p,...i}}}else{let{fromTo:r,deltaX:n,resolutionX:i,nucleusX:p,deltaY:s,resolutionY:a,nucleusY:l,shiftX:u,shiftY:c,...d}=o;o={...d,x:{from:r[0].from,to:r[0].to,delta:n,resolution:i,nucleus:p},y:{from:r[1].from,to:r[1].to,delta:s,resolution:a,nucleus:l}}}return o},[])),t),[])}var Me={name:"apodization",label:"Apodization",value:{lineBroadening:1,gaussBroadening:0,lineBroadeningCenter:0}};function z(e){if(e?.version===3)return e;let t={...e,version:3};for(let o of t.spectra)if(Array.isArray(o?.filters)&&o?.filters.length>0){let r=o.filters.findIndex(n=>n.name==="lineBroadening");if(r!==-1){let n={...o.filters[r],...Me};o.filters[r]=o.filters[r-1],o.filters[r-1]=n}}return t}function B(e){if(e?.version===4)return e;let{version:t,...o}=e,r=[],n={};for(let{source:s,...a}of o.spectra){let l={},{info:u={},display:c={}}=a;if(u?.dimension===2&&!s?.jcampURL)if(u.isFt)l.data={rr:a.data};else continue;if(s?.jcampURL){let{jcampURL:m,jcampSpectrumIndex:g}=s,S=m.match(/(?<baseURL>^\w+:\/{2}\w+\/)(?<relativePath>.*)/);n[m]||(n[m]={baseURL:S?.groups.baseURL||"",relativePath:S?.groups.relativePath||m.replace(/^\.\//,"")}),l.sourceSelector={files:[n[m].relativePath]},g!==void 0&&(l.sourceSelector.jcamp={index:g})}l.filters=Fe(a.filters);let{name:d,...f}=c;d&&(l.info={...u,name:d}),l.display=f,r.push({...a,...l})}let i={data:{...o,spectra:r},version:4},p={entries:Object.values(n)};return p.entries.length>0&&(i.data.source=p),i}function Fe(e=[]){let t=[];for(let o of e){let{name:r,value:n}=o;switch(r){case"zeroFilling":t.push({...o,value:{nbPoints:n}});break;case"shiftX":case"shift2DX":case"shift2DY":t.push({...o,value:{shift:n}});break;default:t.push({...o})}}return t}function K(e){if(e?.version===5)return e;let t={...e,version:5},o={originFrom:"originalFrom",originTo:"originalTo",originDelta:"originalDelta",originX:"originalX",originY:"originalY",originZ:"originalZ"};for(let r of t?.data?.spectra||[])for(let n of["peaks","ranges","zones"])r?.[n]&&(r[n]=x(r[n],o));return t}function X(e){if(e?.version===6)return e;let t={...e,version:6};for(let o of t?.data?.spectra||[]){let{digitalFilter:r,fft:n,phaseCorrection:i}=ke(o);n?.flag&&r?.flag&&i&&Math.floor(r.value.digitalFilterValue)%2>0&&(i.value.ph0-=180)}return t}function ke(e,t=["phaseCorrection","fft","digitalFilter"]){let{filters:o=[]}=e,r={};for(let n of t)r[n]=o.find(i=>i.name===n);return r}function C(e,t="localStorage"){if(e?.version===7)return e;if(t==="nmrium")return H(e);let o={...e,version:7};for(let r in e.workspaces)o.workspaces[r]=H(o.workspaces[r]);return o}function H(e){let{formatting:{nuclei:t,panels:o}={nuclei:null,panels:null},version:r,...n}=e,i={...n};return t&&(i.nuclei=je(t)),o&&(i.panels=o),i}function je(e){let t=[],o={name:"nucleus",ppm:"ppmFormat",hz:"hzFormat"};for(let r in e)t.push(x(e[r],o));return t}function Y(e){if(e?.version===7)return e;let t={...e,version:7};return t?.settings&&(t.settings=C(t.settings,"nmrium")),t}function I(e,t="localStorage"){if(e?.version===8)return e;if(t==="nmrium")return Q(e);let o={...e,version:8};for(let r in e.workspaces)o.workspaces[r]=Q(o.workspaces[r]);return o}function Q(e){let{version:t,...o}=e,r={...o};return r.display.panels=Le(e),r}function Le(e){let t={},o=e.display.panels;for(let r of Object.keys(o)){let{display:n,open:i}=o[r];t[r]={display:n,visible:n,open:i}}return t}function W(e){if(e?.version===8)return e;let t={...e,version:8};t?.settings&&(t.settings=I(t.settings,"nmrium"));for(let o of t?.data?.spectra||[]){let{filters:r=[]}=o;for(let s=0;s<r.length;s++){let{flag:a,isDeleteAllow:l,label:u,...c}=r[s];r[s]={...c,enabled:a}}let n=r.findIndex(s=>s.name==="apodization");if(n!==-1){let s=r[n],{lineBroadening:a,gaussBroadening:l,lineBroadeningCenter:u}=s.value;s.value={exponential:{apply:!0,options:{lineBroadening:l>0?-a:a}}},l>0&&(s.value.gaussian={apply:!0,options:{lineBroadening:.6*l,lineBroadeningCenter:u}}),r[n]=s}let i=r.findIndex(s=>s.name==="apodizationDimension1"),p=r.findIndex(s=>s.name==="apodizationDimension2");if(i!==-1){let s=r[i],{shapes:a}=s.value.compose;s.value=ee(a)}if(p!==-1){let s=r[p],{shapes:a}=s.value.compose;s.value=ee(a)}}return t}function ee(e){let t={};for(let{shape:o}of e){let{kind:r,options:n}=o;if(r==="sineBell"){let{exponent:i,offset:p}=n,s=i===2?"sineSquare":"sineBell";t[s]={apply:!0,options:{offset:p}}}}return t}function $(e){let{version:t,plugins:o,...r}=e;return t===9?e:{version:9,plugins:{},...r}}var Ue=[V,_,z,B,K,X,Y,W,$];function te(e,t,o){let r=structuredClone(e),n=Object.entries(e?.plugins??{});for(let[s,{version:a}]of n){let l=o.get(s);if(!(l&&l.version>=a)){if(l){console.warn(`Plugin "${l.id}" is loaded with a version older (${l.version}) than the one used to save the state (${a}).
1
+ var be={NORMAL:"NORMAL",FORMULA:"FORMULA"};var Re={RELATIVE:"relative",ABSOLUTE:"absolute",MIN:"min",MAX:"max"};var Ce=[{name:"pixels",unit:"px"},{name:"inches",unit:"in"},{name:"feet",unit:"ft"},{name:"yards",unit:"yd"},{name:"centimeters",unit:"cm"},{name:"millimeters",unit:"mm"},{name:"meters",unit:"m"},{name:"points",unit:"pt"},{name:"picas",unit:"pc"}];var P=10;var Ie=[{key:"CT",description:"CT from NMR Solutions"}];import{isAnyArray as Me}from"is-any-array";import{xMultiply as U}from"ml-spectra-processing";var Oe=crypto.randomUUID.bind(crypto),N=Oe;function h(e){let{id:t=N(),meta:o,peaks:r={},filters:i=[],info:n={},ranges:a={},integrals:s={},selector:c,sourceId:l,dependentVariables:p=[],...m}=e,u={id:t,meta:o,filters:i},{data:d=De(p[0].components)}=e;if(Array.isArray(n.nucleus)&&(n.nucleus=n.nucleus[0]),u.data={x:[],re:[],im:[],...d},"scaleFactor"in n){let{scaleFactor:g}=n,{re:S,im:y}=u.data;U(S,g,{output:S}),y&&U(y,g,{output:y})}c&&(u.selector=c),l&&(u.sourceId=l,u.fileCollectionId=l);let f=Me(d.im);if(u.info={phc0:0,phc1:0,nucleus:"1H",isFid:!1,isComplex:f,dimension:1,name:n?.name||t,...n},n.isFid&&n.reverse&&f){let{im:g}=u.data;U(g,-1,{output:g}),u.info.reverse=!1}return u.display={isVisible:!0,isPeaksMarkersVisible:!0,isRealSpectrumVisible:!0,isVisibleInDomain:!0,...e.display},u.peaks={values:[],options:{},...r},u.ranges={values:[],options:{sum:null,isSumConstant:!0,sumAuto:!0},...a},u.integrals={values:[],options:{},...s},{...m,...u}}function De(e){let t=e[0]?.data?.x||[],o=e[0]?.data?.re||e[0]?.data?.y||[],r=e[0]?.data?.im||e[1]?.data?.y||null;return t.length>0&&t[0]>t[1]&&(t.reverse(),o.reverse(),r&&r.reverse()),{x:t,re:o,im:r}}import{matrixToArray as Fe,xMinMaxValues as ve,xNoiseSanPlot as Ae}from"ml-spectra-processing";var V={z:[[]],minX:0,minY:0,maxX:0,maxY:0},we={re:V,im:V},Te={rr:V};function I(e){let{id:t=N(),meta:o={},dependentVariables:r=[],info:i={},filters:n=[],zones:a=[],sourceId:s,...c}=e,l={id:t,meta:o,filters:n};s&&(l.sourceId=s,l.fileCollectionId=s),l.info={nucleus:["1H","1H"],isFid:!1,isComplex:!1,name:i?.name||N(),...i},l.originalInfo=structuredClone(l.info),l.display={isPositiveVisible:!0,isNegativeVisible:!0,isVisible:!0,dimension:2,...e.display,...e.display};let{data:p=r[0].components}=e;if(l.data={...l.info.isFid?we:Te,...p},l.originalData=structuredClone(l.data),!("spectrumSize"in i)){let m=i.isFid?"re":"rr",u=l.data[m].z.length,d=u>0?l.data[m].z[0].length:0;l.info.spectrumSize=[d,u]}if(!i.isFid){let m=l.data.rr,u=Fe(m.z),{positive:d,negative:f}=Ae(u),{min:g,max:S}=ve(u);l.data.rr={...m,minZ:g,maxZ:S},l.info.noise={positive:d,negative:f}}return l.zones={values:[],options:{},...a},{...c,...l}}import{xSequentialFillFromTo as je}from"ml-spectra-processing";import{isAnyArray as Ee}from"is-any-array";function _(e,t=0){if(Ee(e)){let o=e.at(t);if(o!==void 0)return o;throw new RangeError("An array with a index out of boundaries")}return e}var ze=new Set(["t1ir","T1"]);function oe(e){let t=[];for(let o of e){let{info:{pulseSequence:r,isFid:i}}=o,{data:n,info:a,meta:{vdlistValues:s=[]}}=o;if(!(r&&ze.has(r))||s.length===0){t.push(o);continue}let l=i?"re":"rr",p={};for(let y in a)p[y]=_(a[y]);let{z:m,maxX:u,minX:d}=n[l],f=je({from:d,to:u,size:m[0].length}),[g,S]=Le(o);for(let y=0;y<s.length;y++){let te={re:f,x:f};for(let re in n)te[ke(re)]=n[re].z.at(g*(y+S));t.push(h({data:te,info:{...p,name:`${p.name}_${s[y]}`,dimension:1,vd:s[y]}}))}}return t}function ke(e){return["rr","re"].includes(e)?"re":["im","ri","ir","ii"].includes(e)?"im":"x"}function Le(e){let{meta:{PAGE:t}}=e,o=!0;if(t){let r=i=>Number.parseFloat(i.replace(/[F|T]1=/,""));o=r(t[0])>r(t[2])}return o?[-1,1]:[1,0]}var Ue=2,Ve=1;function _e(e){let{spectra:t=[],molecules:o}=e,r=[];for(let i of t){let{info:n}=i;switch(n.dimension){case Ve:r.push(h(i));break;case Ue:r.push(I(i));break;default:throw new Error("dimension does not supported")}}return{molecules:o,spectra:oe(r)}}function Be(e){return e}function b(e,t){e.plugins||(e.plugins={});let o=e.plugins;for(let r of t.values()){if(!r.shouldSerialize){delete o[r.id];continue}o[r.id]||(o[r.id]={id:r.id,version:r.version}),o[r.id].id=r.id,o[r.id].version=r.version}}function x(e,t){return JSON.parse(JSON.stringify(e),function(r,i){if(r in t){this[t[r]]=i;return}return i})}function B(e){if(e?.version===1)return e;let t={...e,version:1},o={j:"js",signal:"signals",integral:"integration",peak:"peaks",diaID:"diaIDs"};for(let r of t.spectra){if(r.ranges){let i=x(r.ranges,o);r.ranges=Array.isArray(i)?{values:i}:i}else if(r.zones){let i=x(r.zones,o);r.zones=Array.isArray(i)?{values:i}:i}r.peaks&&(r.peaks=Array.isArray(r.peaks)?{values:r.peaks}:r.peaks),r.integrals&&(r.integrals=Array.isArray(r.integrals)?{values:r.integrals}:r.integrals)}return t}function K(e){if(e?.version===2)return e;let t={...e,version:2},o={peaks:{delta:"x",originDelta:"originalX",intensity:"y"},ranges:{atomIDs:"atoms",intensity:"y"}};for(let r of t.spectra)r.peaks?r.peaks=x(r.peaks,o.peaks):r.ranges?r.ranges=x(r.ranges,o.ranges):r.zones&&(r.zones.values=Ke(r.zones.values));return t}function Ke(e){return e.map(t=>(t.signals&&(t.signals=t.signals.map(o=>{if(o.x&&o.y){let{x:{fromTo:r,...i},y:{fromTo:n,...a}}=o;o={...o,x:{...i,...r},y:{...a,...n}}}else{let{fromTo:r,deltaX:i,resolutionX:n,nucleusX:a,deltaY:s,resolutionY:c,nucleusY:l,shiftX:p,shiftY:m,...u}=o;o={...u,x:{from:r[0].from,to:r[0].to,delta:i,resolution:n,nucleus:a},y:{from:r[1].from,to:r[1].to,delta:s,resolution:c,nucleus:l}}}return o},[])),t),[])}var Xe={name:"apodization",label:"Apodization",value:{lineBroadening:1,gaussBroadening:0,lineBroadeningCenter:0}};function X(e){if(e?.version===3)return e;let t={...e,version:3};for(let o of t.spectra)if(Array.isArray(o?.filters)&&o?.filters.length>0){let r=o.filters.findIndex(i=>i.name==="lineBroadening");if(r!==-1){let i={...o.filters[r],...Xe};o.filters[r]=o.filters[r-1],o.filters[r-1]=i}}return t}function W(e){if(e?.version===4)return e;let{version:t,...o}=e,r=[],i={};for(let{source:s,...c}of o.spectra){let l={},{info:p={},display:m={}}=c;if(p?.dimension===2&&!s?.jcampURL)if(p.isFt)l.data={rr:c.data};else continue;if(s?.jcampURL){let{jcampURL:f,jcampSpectrumIndex:g}=s,S=f.match(/(?<baseURL>^\w+:\/{2}\w+\/)(?<relativePath>.*)/);i[f]||(i[f]={baseURL:S?.groups.baseURL||"",relativePath:S?.groups.relativePath||f.replace(/^\.\//,"")}),l.sourceSelector={files:[i[f].relativePath]},g!==void 0&&(l.sourceSelector.jcamp={index:g})}l.filters=We(c.filters);let{name:u,...d}=m;u&&(l.info={...p,name:u}),l.display=d,r.push({...c,...l})}let n={data:{...o,spectra:r},version:4},a={entries:Object.values(i)};return a.entries.length>0&&(n.data.source=a),n}function We(e=[]){let t=[];for(let o of e){let{name:r,value:i}=o;switch(r){case"zeroFilling":t.push({...o,value:{nbPoints:i}});break;case"shiftX":case"shift2DX":case"shift2DY":t.push({...o,value:{shift:i}});break;default:t.push({...o})}}return t}function Y(e){if(e?.version===5)return e;let t={...e,version:5},o={originFrom:"originalFrom",originTo:"originalTo",originDelta:"originalDelta",originX:"originalX",originY:"originalY",originZ:"originalZ"};for(let r of t?.data?.spectra||[])for(let i of["peaks","ranges","zones"])r?.[i]&&(r[i]=x(r[i],o));return t}function $(e){if(e?.version===6)return e;let t={...e,version:6};for(let o of t?.data?.spectra||[]){let{digitalFilter:r,fft:i,phaseCorrection:n}=Ye(o);i?.flag&&r?.flag&&n&&Math.floor(r.value.digitalFilterValue)%2>0&&(n.value.ph0-=180)}return t}function Ye(e,t=["phaseCorrection","fft","digitalFilter"]){let{filters:o=[]}=e,r={};for(let i of t)r[i]=o.find(n=>n.name===i);return r}function O(e,t="localStorage"){if(e?.version===7)return e;if(t==="nmrium")return ie(e);let o={...e,version:7};for(let r in e.workspaces)o.workspaces[r]=ie(o.workspaces[r]);return o}function ie(e){let{formatting:{nuclei:t,panels:o}={nuclei:null,panels:null},version:r,...i}=e,n={...i};return t&&(n.nuclei=$e(t)),o&&(n.panels=o),n}function $e(e){let t=[],o={name:"nucleus",ppm:"ppmFormat",hz:"hzFormat"};for(let r in e)t.push(x(e[r],o));return t}function Z(e){if(e?.version===7)return e;let t={...e,version:7};return t?.settings&&(t.settings=O(t.settings,"nmrium")),t}function M(e,t="localStorage"){if(e?.version===8)return e;if(t==="nmrium")return ne(e);let o={...e,version:8};for(let r in e.workspaces)o.workspaces[r]=ne(o.workspaces[r]);return o}function ne(e){let{version:t,...o}=e,r={...o};return r.display.panels=Ze(e),r}function Ze(e){let t={},o=e.display.panels;for(let r of Object.keys(o)){let{display:i,open:n}=o[r];t[r]={display:i,visible:i,open:n}}return t}function G(e){if(e?.version===8)return e;let t={...e,version:8};t?.settings&&(t.settings=M(t.settings,"nmrium"));for(let o of t?.data?.spectra||[]){let{filters:r=[]}=o;for(let s=0;s<r.length;s++){let{flag:c,isDeleteAllow:l,label:p,...m}=r[s];r[s]={...m,enabled:c}}let i=r.findIndex(s=>s.name==="apodization");if(i!==-1){let s=r[i],{lineBroadening:c,gaussBroadening:l,lineBroadeningCenter:p}=s.value;s.value={exponential:{apply:!0,options:{lineBroadening:l>0?-c:c}}},l>0&&(s.value.gaussian={apply:!0,options:{lineBroadening:.6*l,lineBroadeningCenter:p}}),r[i]=s}let n=r.findIndex(s=>s.name==="apodizationDimension1"),a=r.findIndex(s=>s.name==="apodizationDimension2");if(n!==-1){let s=r[n],{shapes:c}=s.value.compose;s.value=se(c)}if(a!==-1){let s=r[a],{shapes:c}=s.value.compose;s.value=se(c)}}return t}function se(e){let t={};for(let{shape:o}of e){let{kind:r,options:i}=o;if(r==="sineBell"){let{exponent:n,offset:a}=i,s=n===2?"sineSquare":"sineBell";t[s]={apply:!0,options:{offset:a}}}}return t}function J(e){let{version:t,plugins:o,...r}=e;return t===9?e:{version:9,plugins:{},...r}}function q(e){if(e?.version>=10)return e;let{data:t,...o}=e,{source:r,spectra:i,...n}=t,a=r?crypto.randomUUID():void 0,s=r?[{...r,id:a}]:[];return{...o,version:10,data:{...n,sources:s,spectra:r?i.map(c=>({...c,sourceId:a})):i}}}var Ge=[B,K,X,W,Y,$,Z,G,J,q];function ae(e,t,o){let r=structuredClone(e),i=Object.entries(e?.plugins??{});for(let[s,{version:c}]of i){let l=o.get(s);if(!(l&&l.version>=c)){if(l){console.warn(`Plugin "${l.id}" is loaded with a version older (${l.version}) than the one used to save the state (${c}).
2
2
  NMRium may fail to load the state.
3
- Please update the plugin to the latest version.`);continue}console.warn(`Plugin "${s}@${a}" is not registered. NMRium may fail to load the state.
4
- Please consider open this file with the plugin installed.`)}}let i=new Set,p=()=>{let s=r.version;for(let a of o.values())for(let l of a.migrations){if(i.has(l)||s<l.minCore||l.maxCore&&s>l.maxCore)continue;if((r.plugins?.[a.id]?.version||0)===a.version)break;r=l.up(r),i.add(l)}};for(let s=e?.version||0;s<t;s++){let a=Ue[s];r=a(r),p()}return p(),R(r,o),r}import{FileCollection as $e}from"file-collection";var re={SDF:"sdf",MOL:"mol",NMRIUM:"nmrium",JSON:"json",JCAMP:"jcamp",DX:"dx",JDX:"jdx",JDF:"jdf",NMREDATA:"nmredata",SMILES:"smiles",SMI:"smi"};function v(e){return e.includes(".")?e.replace(/^.*\./,"").toLowerCase():""}function T(e,t={},o){let{data:r,...n}=e;if(!r)return e;let{spectra:i=[]}=r,{keep1D:p=!0,keep2D:s=!0,onlyReal:a}=t,l=a?"ft":t.dataSelection||"both",u=[];for(let c of i){if(!c.info){u.push(c);continue}let{isFid:d,dimension:f,name:m}=c.info;if(!A(f===1&&!p,m,o)&&!A(f===2&&!s,m,o)&&!A(d&&l==="ft",m,o)&&!A(!d&&l==="fid",m,o))if(a&&!d)if(c.info.isComplex=!1,Ve(c)){let{rr:g}=c.data;u.push({...c,data:{rr:g}})}else{let{re:g,x:S}=c.data;u.push({...c,data:{re:g,x:S}})}else u.push(c)}return{data:{...r,spectra:u},...n}}function A(e,t,o){return e?(o?.warn(`Skipping ${t} because it didn't match the import filters.`),!0):!1}function Ve(e){let{info:t}=e;return t?.dimension===2}function w(e){let{nmriumState:t,plugins:o,options:r}=e;for(let n of o.values()){let i=n.onReadProcess?.onProcessing;i&&i(t,r)}}async function E(e,t,o={}){let{sourceSelector:r,converter:n,keepSource:i,logger:p}=o,s=[],a=[];for(let f of t.values()){let{onReadProcess:m}=f;m&&(m?.onFiles&&s.push(f),m?.supportedExtensions?.length&&m?.onFile&&a.push(f))}let l=await Promise.allSettled(s.map(f=>f.onReadProcess.onFiles(e,o))),u=[],c=await Promise.allSettled(e.files.flatMap(f=>{let m=v(f.name).toLowerCase();return a.flatMap(g=>{let{supportedExtensions:S,onFile:y}=g.onReadProcess;return S.includes(m)?(u.push({file:f,plugin:g}),y(f,{logger:p,sourceSelector:r,converter:n,keepSource:i})):[]})})),d={spectra:[],molecules:[]};for(let f=0;f<l.length;f++){let m=l[f];switch(m.status){case"fulfilled":{let{spectra:g=[],molecules:S=[]}=m.value||{};d.spectra.push(...g),d.molecules.push(...S);break}case"rejected":{let g=m.reason,S=s[f];o.logger?.error(`Load file collection with plugin ${S.id}@${S.version} fails with: ${g}`);break}}}for(let f=0;f<c.length;f++){let m=c[f];switch(m.status){case"fulfilled":{let{spectra:g=[],molecules:S=[]}=m.value||{};d.spectra.push(...g),d.molecules.push(...S);break}case"rejected":{let g=m.reason,{file:S,plugin:y}=u[f];o.logger?.error(`Load file ${S.relativePath} with plugin ${y.id}@${y.version} fails with: ${g}`);break}}}return d}import{FileCollection as Xe}from"file-collection";import{FileCollection as _e}from"file-collection";import oe from"lodash.merge";import{xIsEquallySpaced as ze}from"ml-spectra-processing";async function M(e){let{nmriumObjectInput:t,options:o={},migrator:r,plugins:n}=e,i=r(t),{data:p,...s}=i;if(!p)return{...s};let a={data:{...p,spectra:[]},...s},l=a.data,{source:u,spectra:c,molecules:d}=l,f;u&&(f=await _e.fromSource(u,{unzip:{zipExtensions:["zip","nmredata"]}}));let m=[];for(let g of p.spectra)if(f){let{sourceSelector:S}=g,y=F({input:f,migrator:r,plugins:n,options:{...o,sourceSelector:S}}).then(h=>{let{nmriumState:{data:D}}=h,{spectra:pe=[],molecules:q=[]}=D||{};q.length>0&&d.length===0&&d.push(...q);for(let ce of pe)c.push(Be(g,Ke(ce)))});m.push(y)}else{let{dimension:S}=g.info;if(S===1){if(!ze(g.data)){o.logger?.error('The ".nmrium" file is corrupted; the X-axis values are not equally distant.');continue}c.push(N(g))}else S===2&&c.push(O(g))}return await Promise.allSettled(m),a}function Be(e,t){let{data:o,...r}=e;if("ranges"in t){let{data:n,...i}=t;return{...oe(i,r),data:n}}else if("zones"in t){let{data:n,...i}=t;return{...oe(i,r),data:n}}else return t}function Ke(e){return{...e,id:b()}}async function ne(e){let{file:t,options:o={},migrator:r,plugins:n}=e,i=await t.arrayBuffer(),p=await(We(i)?Ye(i):t.text());return M({nmriumObjectInput:JSON.parse(p),plugins:n,migrator:r,options:o})}async function Ye(e){let t=await Xe.fromZip(e);if(t.files.length===0)throw new Error("compressed nmrium file is corrupted");return t.files[0].text()}function We(e){if(e.byteLength<4)return!1;let t=new Uint8Array(e);return t[0]===80&&t[1]===75&&(t[2]===3||t[2]===5||t[2]===7)&&(t[3]===4||t[3]===6||t[3]===8)}async function F(e){let{options:t={},input:o,migrator:r,plugins:n}=e,i=qe(await Ge(o),t.sourceSelector?.files),p=Je(i);if(p)return{nmriumState:await ne({file:p,migrator:r,plugins:n,options:t}),containsNmrium:!0};let s=await E(i,n,t),a=T({version:9,data:s},t?.sourceSelector?.general,t.logger),{onLoadProcessing:l,experimentalFeatures:u}=t,c={...l,autoProcessing:l?.autoProcessing??!1,experimentalFeatures:u};return w({nmriumState:a,plugins:n,options:c}),{nmriumState:a,containsNmrium:!1}}function Ge(e){return Array.isArray(e)?Promise.reject(new Error("For a set of fileCollectionItems pass a FileCollection instance")):Ze(e)?Promise.resolve(e):new $e().appendExtendedSource({...e,uuid:crypto.randomUUID()})}function Ze(e){return typeof e=="object"&&"files"in e}function qe(e,t){if(!t)return e;let o=new Set(t);return e.filter(r=>o.has(r.relativePath))}function Je(e){return e.files.find(t=>v(t.name).toLowerCase()===re.NMRIUM)}function k(e,t){let o={};for(let r in e)t.includes(r)||(o[r]=e[r]);return o}var He=["data","originalData","info","originalInfo","meta","customInfo"],Qe=["sourceSelector","originalData","originalInfo"];function ie(e,t,o={}){let{version:r,data:n}=e;if(n.actionType)return e;let i={version:r,plugins:e.plugins},{includeData:p}=o;p!=="noData"&&(i.data=et({...n},p));let{includeSettings:s,includeView:a}=o;return s&&(i.settings=e.settings),a&&(i.view=e.view),R(i,t),i}function et(e,t="rawData"){let{spectra:o}=e;switch(t){case"dataSource":return tt(e);case"rawData":return{...k(e,["source"]),spectra:o.map(ot)};default:return e}}function tt(e){let{spectra:t}=e;if(!e.source)throw new Error("source property should exists for dataSource serialization");return{...e,spectra:t.map(rt)}}function rt(e){return k(e,He)}function ot(e){let{data:t,info:o,originalData:r,originalInfo:n}=e,i=k(e,Qe);return i.data=r||t,i.info=n||o,i}var nt=["topbar.right","topbar.about_us.modal"],it=[],qr=[...nt,...it],st={},G={};{let e=st,t=G;for(let[o,r]of Object.entries(e))t[r]||(t[r]=[]),t[r]?.push(o)}function*se(e){let{slot:t,plugins:o,supportedToDeprecatedSlots:r=G}=e,n=r[t];for(let[i,p]of o.entries()){let s=p.ui;if(!s)continue;let a=s[t];if(a){yield[i,a];continue}if(n)for(let l of n){let u=p.ui?.[l];if(u){yield[i,u],console.warn(`Plugin ${p.id} used deprecated slot "${l}". Please update this plugin to use "${t}" instead.`);break}}}}import{FileCollection as at}from"file-collection";async function ae(e){let{source:t,plugins:o,options:r={}}=e,{keepSource:n=!0,converter:i,...p}=r,s={source:t,spectra:[],molecules:[]},a=await at.fromSource(t,{unzip:{zipExtensions:["zip","nmredata"]}}),{spectra:l=[],molecules:u=[]}=await E(a,o,{keepSource:n,converter:{...i,bruker:{keepFiles:!0,...Reflect.get(i??{},"bruker")}},...p});s.spectra.push(...l),s.molecules.push(...u);let c=T({version:9,data:s},r?.sourceSelector?.general),{onLoadProcessing:d}=p,f={filters:d?.filters,autoProcessing:d?.autoProcessing??!1,experimentalFeatures:r.experimentalFeatures};return w({nmriumState:c,plugins:o,options:f}),c}var Z=class{version=9;#e=new Map;registerPlugin(t){if(this.#e.has(t.id)){console.warn(`Plugin ${t.id} is already registered. skip.`),console.debug("Plugin already registered:",this.#e.get(t.id)),console.debug("Plugin to register:",t);return}this.#e.set(t.id,t)}registerPlugins(t){for(let o of t)this.registerPlugin(o)}migrate(t){return te(t,this.version,this.#e)}read(t,o={}){return F({input:t,migrator:this.migrate.bind(this),plugins:this.#e,options:o})}readNMRiumObject(t,o){return M({nmriumObjectInput:t,options:o,plugins:this.#e,migrator:this.migrate.bind(this)})}readFromWebSource(t,o){return ae({source:t,options:o,plugins:this.#e})}serializeNmriumState(t,o){return ie(t,this.#e,o)}slot(t){return se({slot:t,plugins:this.#e})}};function lt(e,t){if(t>9)return 0;let o=-1;for(let r=0;r<e.length;r++)if(e[r].version>t){o=r;break}return o}var le=[{version:6,fun:C},{version:7,fun:I}];function pt(e){let{version:t}=e||{},o=lt(le,t);if(o===-1)return{...e,version:9};let r=le.slice(o);for(let n of r)e=n.fun(e);return e}export{ue as ANALYSIS_COLUMN_TYPES,me as ANALYSIS_COLUMN_VALUES_KEYS,P as CURRENT_EXPORT_VERSION,ge as EXTERNAL_API_KEYS,Z as NMRiumCore,we as defineNMRiumPlugin,Te as formatSpectra,b as generateID,U as getOneIfArray,pt as migrateSettings,fe as units};
3
+ Please update the plugin to the latest version.`);continue}console.warn(`Plugin "${s}@${c}" is not registered. NMRium may fail to load the state.
4
+ Please consider open this file with the plugin installed.`)}}let n=new Set,a=()=>{let s=r.version;for(let c of o.values())for(let l of c.migrations){if(n.has(l)||s<l.minCore||l.maxCore&&s>l.maxCore)continue;if((r.plugins?.[c.id]?.version||0)===c.version)break;r=l.up(r),n.add(l)}};for(let s=e?.version||0;s<t;s++){let c=Ge[s];r=c(r),a()}return a(),b(r,o),r}import{FileCollection as ot}from"file-collection";var le={SDF:"sdf",MOL:"mol",NMRIUM:"nmrium",NMRIUM_ARCHIVE:"nmrium.zip",JSON:"json",JCAMP:"jcamp",DX:"dx",JDX:"jdx",JDF:"jdf",NMREDATA:"nmredata",SMILES:"smiles",SMI:"smi"};function D(e){return e.includes(".")?e.replace(/^.*\./,"").toLowerCase():""}function v(e,t={},o){let{data:r,...i}=e;if(!r)return e;let{spectra:n=[]}=r,{keep1D:a=!0,keep2D:s=!0,onlyReal:c}=t,l=c?"ft":t.dataSelection||"both",p=[];for(let m of n){if(!m.info){p.push(m);continue}let{isFid:u,dimension:d,name:f}=m.info;if(!F(d===1&&!a,f,o)&&!F(d===2&&!s,f,o)&&!F(u&&l==="ft",f,o)&&!F(!u&&l==="fid",f,o))if(c&&!u)if(m.info.isComplex=!1,Je(m)){let{rr:g}=m.data;p.push({...m,data:{rr:g}})}else{let{re:g,x:S}=m.data;p.push({...m,data:{re:g,x:S}})}else p.push(m)}return{data:{...r,spectra:p},...i}}function F(e,t,o){return e?(o?.warn(`Skipping ${t} because it didn't match the import filters.`),!0):!1}function Je(e){let{info:t}=e;return t?.dimension===2}function A(e){let{nmriumState:t,plugins:o,options:r}=e;for(let i of o.values()){let n=i.onReadProcess?.onProcessing;n&&n(t,r)}}async function w(e,t,o={}){let{sourceSelector:r,converter:i,logger:n}=o,a=[],s=[];for(let u of t.values()){let{onReadProcess:d}=u;d&&(d?.onFiles&&a.push(u),d?.supportedExtensions?.length&&d?.onFile&&s.push(u))}let c=await Promise.allSettled(a.map(u=>u.onReadProcess.onFiles(e,o))),l=[],p=await Promise.allSettled(e.files.flatMap(u=>{let d=D(u.name).toLowerCase();return s.flatMap(f=>{let{supportedExtensions:g,onFile:S}=f.onReadProcess;return g.includes(d)?(l.push({file:u,plugin:f}),S(u,{logger:n,sourceSelector:r,converter:i})):[]})})),m={spectra:[],molecules:[]};for(let u=0;u<c.length;u++){let d=c[u];switch(d.status){case"fulfilled":{let{spectra:f=[],molecules:g=[]}=d.value||{};m.spectra.push(...f),m.molecules.push(...g);break}case"rejected":{let f=d.reason,g=a[u];o.logger?.error(`Load file collection with plugin ${g.id}@${g.version} fails with: ${f}`);break}}}for(let u=0;u<p.length;u++){let d=p[u];switch(d.status){case"fulfilled":{let{spectra:f=[],molecules:g=[]}=d.value||{};m.spectra.push(...f),m.molecules.push(...g);break}case"rejected":{let f=d.reason,{file:g,plugin:S}=l[u];o.logger?.error(`Load file ${g.relativePath} with plugin ${S.id}@${S.version} fails with: ${f}`);break}}}return m}import{FileCollection as et}from"file-collection";import{FileCollection as Qe}from"file-collection";import ce from"lodash.merge";import{xIsEquallySpaced as qe}from"ml-spectra-processing";async function T(e){let{input:t,spectraResult:o,unserializedSpectrum:r,options:i,plugins:n,migrator:a}=e,c=(await R({input:t,migrator:a,plugins:n,options:{...i,sourceSelector:r.sourceSelector}}))?.nmriumState?.data?.spectra??[],l=c.pop();if(l){o.push(ue(r,l));for(let p of c)o.push(ue(r,He(p)))}}function ue(e,t){!e.fileCollectionId&&e.sourceId&&(e.fileCollectionId=e.sourceId),!t.fileCollectionId&&t.sourceId&&(t.fileCollectionId=t.sourceId);let{data:o,...r}=e;if("ranges"in t){let{data:i,...n}=t;return{...ce(n,r),data:i}}else if("zones"in t){let{data:i,...n}=t;return{...ce(n,r),data:i}}else return t}function He(e){return{...e,id:N()}}function E(e){let{spectrum:t,spectraResult:o,logger:r}=e,{dimension:i}=t.info;if(i===1){if(!qe(t.data)){r?.error('The ".nmrium" file is corrupted; the X-axis values are not equally distant.');return}o.push(h(t))}else i===2&&o.push(I(t))}async function j(e){let{input:t,moleculesResult:o,unserializedMolecule:r,options:i,plugins:n,migrator:a}=e,{sourceSelector:s,sourceId:c}=r,p=(await R({input:t,migrator:a,plugins:n,options:{...i,sourceSelector:s}}))?.nmriumState?.data?.molecules??[];for(let m of p)o.push({...m,sourceId:c,fileCollectionId:c})}function z(e){let{molecule:t,moleculesResult:o}=e;o.push(t)}async function k(e){let{nmriumObjectInput:t,options:o={},migrator:r,plugins:i}=e,n=r(t),{data:a,...s}=n;if(!a)return[{...s},new Map];let c={data:{...a,spectra:[],molecules:[]},...s},l=c.data,{sources:p=[],spectra:m,molecules:u}=l,d=await Promise.all(p.map(async S=>{let y=await Qe.fromSource(S,{unzip:{zipExtensions:["zip","nmredata"]}});return[S.id,y]})),f=new Map(d),g=[];for(let S of a.spectra){let y=f.get(S.sourceId);if(!y){E({spectrum:S,spectraResult:m,logger:o.logger});continue}g.push(T({input:y,spectraResult:m,unserializedSpectrum:S,migrator:r,plugins:i,options:o}))}for(let S of a.molecules??[]){let y=f.get(S.sourceId);if(!y){z({molecule:S,moleculesResult:u,logger:o.logger});continue}g.push(j({input:y,unserializedMolecule:S,moleculesResult:u,migrator:r,plugins:i,options:o}))}return await Promise.allSettled(g),[c,f]}async function pe(e){let{file:t,options:o={},migrator:r,plugins:i}=e,n=await t.arrayBuffer(),a=await(rt(n)?tt(n):t.text());return k({nmriumObjectInput:JSON.parse(a),plugins:i,migrator:r,options:o})}async function tt(e){let t=await et.fromZip(e);if(t.files.length===0)throw new Error("compressed nmrium file is corrupted");return t.files[0].text()}function rt(e){if(e.byteLength<4)return!1;let t=new Uint8Array(e);return t[0]===80&&t[1]===75&&(t[2]===3||t[2]===5||t[2]===7)&&(t[3]===4||t[3]===6||t[3]===8)}async function R(e){let{options:t={},input:o,migrator:r,plugins:i}=e,n=st(await it(o),t.sourceSelector?.files),a=at(n);if(a){let[u]=await pe({file:a,migrator:r,plugins:i,options:t});return{nmriumState:u,containsNmrium:!0,fileCollection:n}}let s=await w(n,i,t),c=v({version:10,data:s},t?.sourceSelector?.general,t.logger),{onLoadProcessing:l,experimentalFeatures:p}=t,m={...l,autoProcessing:l?.autoProcessing??!1,experimentalFeatures:p};return A({nmriumState:c,plugins:i,options:m}),{nmriumState:c,containsNmrium:!1,fileCollection:n}}function it(e){return Array.isArray(e)?Promise.reject(new Error("For a set of fileCollectionItems pass a FileCollection instance")):nt(e)?Promise.resolve(e):new ot().appendExtendedSource({...e,uuid:crypto.randomUUID()})}function nt(e){return typeof e=="object"&&"files"in e}function st(e,t){if(!t)return e;let o=new Set(t);return e.filter(r=>o.has(r.relativePath))}function at(e){return e.files.find(t=>D(t.name).toLowerCase()===le.NMRIUM)}function C(e,t){let o={};for(let r in e)t.includes(r)||(o[r]=e[r]);return o}var lt=["data","originalData","info","originalInfo","meta","customInfo"],ct=["data","originalData","info","originalInfo","meta","customInfo"],ut=["sourceSelector","sourceId","fileCollectionId","originalData","originalInfo"];function me(e,t,o={}){let{version:r,data:i}=e;if(i.actionType)return e;let n={version:r,plugins:e.plugins},{includeData:a}=o;a!=="noData"&&(n.data=pt({...i},a));let{includeSettings:s,includeView:c}=o;return s&&(n.settings=e.settings),c&&(n.view=e.view),b(n,t),n}function pt(e,t="rawData"){let{spectra:o}=e;switch(t){case"dataSource":return mt(e);case"selfContained":case"selfContainedExternalDatasource":return ft(e);case"rawData":return{...C(e,["sources"]),spectra:o.map(St)};default:return e}}function mt(e){let{spectra:t}=e;if(!e.sources)throw new Error("sources property should exists for dataSource serialization");return{...e,spectra:t.map(dt)}}function ft(e){let{spectra:t}=e;return{...e,spectra:t.map(gt)}}function dt(e){return C(e,lt)}function gt(e){return C(e,ct)}function St(e){let{data:t,info:o,originalData:r,originalInfo:i}=e,n=C(e,ut);return n.data=r||t,n.info=i||o,n}import{FileCollection as yt}from"file-collection";async function de(e){let{spectra:t,molecules:o,fileCollections:r,serializedState:i,includeData:n=!0}=e,a=new yt({filter:{ignoreDotfiles:!1}}),s=new Set,c=[];for(let l of t)fe({builder:a,fileCollections:r,fileCollectionId:l.fileCollectionId,includeData:n,alreadyAdded:s,asyncTasks:c});for(let l of o)fe({builder:a,fileCollections:r,fileCollectionId:l.fileCollectionId,includeData:n,alreadyAdded:s,asyncTasks:c});return await Promise.all(c),a.toIum({*getExtraFiles(){yield{relativePath:"state.json",data:i},yield{relativePath:".META-NMRIUM/NMRIUM_ARCHIVE.json",data:JSON.stringify(Pt({fileCollections:r,toSerialize:s}),null,2)},n?yield{relativePath:".META-NMRIUM/EMBED_ALL_DATA",data:""}:yield{relativePath:".META-NMRIUM/USE_EXTERNAL_SOURCES",data:""},yield{relativePath:"index.txt",data:xt({fileCollections:r,toIndex:s})}}})}function fe(e){let{builder:t,fileCollections:o,fileCollectionId:r,includeData:i,alreadyAdded:n,asyncTasks:a}=e;if(!r||n.has(r))return;let s=o[r];s&&(n.add(r),a.push(s.toIum({includeData:i}).then(c=>{let l=new Blob([c],{type:"application/zip"});return t.appendExtendedSource({uuid:r,name:r,relativePath:`${r}.ium.zip`,size:l.size,text:()=>l.text(),stream:()=>l.stream(),arrayBuffer:()=>l.arrayBuffer()},{unzip:{zipExtensions:[]}})})))}function Pt(e){let{fileCollections:t,toSerialize:o}=e,r={};for(let i of o){let n=t[i];if(!n)continue;let{logger:a,...s}=n.options;r[i]={sourceUUID:i,filePath:`${i}.ium.zip`,options:s}}return r}function xt(e){let{fileCollections:t,toIndex:o}=e,r=[];for(let i of o){let n=t[i];if(n){r.push(`data/${i}.ium.zip`);for(let a of n.sources)r.push(` data/${a.relativePath}`);r.push(`
5
+ `)}}return r.join(`
6
+ `)}var Nt=["topbar.right","topbar.about_us.modal"],ht=[],Co=[...Nt,...ht],bt={},H={};{let e=bt,t=H;for(let[o,r]of Object.entries(e))t[r]||(t[r]=[]),t[r]?.push(o)}function*ge(e){let{slot:t,plugins:o,supportedToDeprecatedSlots:r=H}=e,i=r[t];for(let[n,a]of o.entries()){let s=a.ui;if(!s)continue;let c=s[t];if(c){yield[n,c];continue}if(i)for(let l of i){let p=a.ui?.[l];if(p){yield[n,p],console.warn(`Plugin ${a.id} used deprecated slot "${l}". Please update this plugin to use "${t}" instead.`);break}}}}import{FileCollection as Q}from"file-collection";async function Se(e){let t={},o=[];for(let r of e.sources)switch(r.relativePath){case"state.json":o.push(r.text().then(i=>{t.state=JSON.parse(i)}));break;case".META-NMRIUM/NMRIUM_ARCHIVE.json":o.push(r.text().then(i=>{t.archive=JSON.parse(i)}));break;case".META-NMRIUM/EMBED_ALL_DATA":t.embed=r;break;case".META-NMRIUM/USE_EXTERNAL_SOURCES":t.external=r;break;default:}return await Promise.all(o),t}function ye(e){if(!e.archive)throw new Error("Not a valid NMRium archive");if(!e.state)throw new Error("NMRium Archive corrupted, state.json is missing");if(!e.embed&&!e.external)throw new Error("NMRium Archive corrupted, no embedded data or external sources")}async function Pe(e){let{options:t,plugins:o,migrator:r}=e,i=await Q.fromIum(e.input),n=await Se(i);ye(n);let a=r(n.state),s={...a,data:{...a.data,spectra:[],molecules:[]}},c=s.data.spectra,l=s.data.molecules,p=Rt(a.data.sources),m=Ct(i,n.archive),u=[];for(let f of a.data.spectra)u.push(Ot({archive:n,externalSources:p,embedFiles:m,unserializedSpectrum:f,spectraResult:c,options:t,plugins:o,migrator:r}));for(let f of a.data.molecules??[])u.push(Mt({archive:n,externalSources:p,embedFiles:m,unserializedMolecule:f,moleculesResult:l,options:t,plugins:o,migrator:r}));await Promise.allSettled(u);let d=await It(m,p);return[s,d]}function Rt(e){e??=[];let t=new Map(e.map(r=>[r.id,r])),o=new Map;return{get(r){let i=t.get(r);if(!i)return;let n=o.get(r);return n||(n=Q.fromSource(i,{unzip:{zipExtensions:["zip","nmredata"]}}),o.set(r,n)),n},async all(){let r=new Map;return await Promise.all(L(o.entries(),async([i,n])=>{r.set(i,await n)})),r},[Symbol("debug")]:{sources:e,mapSources:t,fileCollections:o}}}function Ct(e,t){let o=new Map,r=new Map(e.sources.map(i=>[i.relativePath,i]));return{get(i){let n=t[i];if(!n)return;let a=r.get(n.filePath);if(!a)return;let s=o.get(i);return s||(s=Q.fromIum(a.stream()),o.set(i,s)),s},async all(){let i=new Map;return await Promise.all(L(o.entries(),async([n,a])=>{i.set(n,await a)})),i},[Symbol("debug")]:{ium:e,record:t,iumSources:r,fileCollections:o}}}async function It(e,t){let o=new Map;return await Promise.allSettled(L(await e.all(),async([r,i])=>{o.set(r,i)})),await Promise.allSettled(L(await t.all(),async([r,i])=>{o.has(r)||o.set(r,i)})),o}function*L(e,t){for(let o of e)yield t(o)}async function Ot(e){let{archive:t,externalSources:o,embedFiles:r}=e,{unserializedSpectrum:i,spectraResult:n}=e,{options:a,plugins:s,migrator:c}=e,l=await xe({archive:t,externalSources:o,embedFiles:r,pickableInput:i});if(!l)return E({spectrum:i,spectraResult:n,logger:a?.logger});await T({input:l,unserializedSpectrum:i,spectraResult:n,options:a,plugins:s,migrator:c})}async function Mt(e){let{archive:t,externalSources:o,embedFiles:r}=e,{unserializedMolecule:i,moleculesResult:n}=e,{options:a,plugins:s,migrator:c}=e,l=await xe({archive:t,externalSources:o,embedFiles:r,pickableInput:i});if(!l)return z({molecule:i,moleculesResult:n,logger:a?.logger});await j({input:l,unserializedMolecule:i,moleculesResult:n,options:a,plugins:s,migrator:c})}async function xe(e){let{archive:t,externalSources:o,embedFiles:r,pickableInput:i}=e,{fileCollectionId:n,sourceId:a}=i,s;return t.external&&a&&(s=await o.get(a)),!s&&t.external&&a&&n&&(s=await r.get(n)),!s&&t.embed&&n&&(s=await r.get(n)),s}import{FileCollection as Dt}from"file-collection";async function Ne(e){let{source:t,plugins:o,options:r={}}=e,{converter:i,...n}=r,a={spectra:[],molecules:[]},s=await Dt.fromSource(t,{unzip:{zipExtensions:["zip","nmredata"]}}),{spectra:c=[],molecules:l=[]}=await w(s,o,{converter:{...i,bruker:{keepFiles:!0,...Reflect.get(i??{},"bruker")}},...n});a.spectra.push(...c),a.molecules.push(...l);let p=crypto.randomUUID(),m={...t,id:p};for(let g of a.spectra)g.sourceId=p;for(let g of a.molecules)g.sourceId=p;a.sources??=[],a.sources.push(m);let u=v({version:10,data:a},r?.sourceSelector?.general),{onLoadProcessing:d}=n,f={filters:d?.filters,autoProcessing:d?.autoProcessing??!1,experimentalFeatures:r.experimentalFeatures};return A({nmriumState:u,plugins:o,options:f}),[u,s]}var ee=class{version=10;#e=new Map;registerPlugin(t){if(this.#e.has(t.id)){console.warn(`Plugin ${t.id} is already registered. skip.`),console.debug("Plugin already registered:",this.#e.get(t.id)),console.debug("Plugin to register:",t);return}this.#e.set(t.id,t)}registerPlugins(t){for(let o of t)this.registerPlugin(o)}migrate(t){return ae(t,this.version,this.#e)}read(t,o={}){return R({input:t,migrator:this.migrate.bind(this),plugins:this.#e,options:o})}readNMRiumArchive(t,o={}){return Pe({input:t,options:o,plugins:this.#e,migrator:this.migrate.bind(this)})}readNMRiumObject(t,o){return k({nmriumObjectInput:t,options:o,plugins:this.#e,migrator:this.migrate.bind(this)})}readFromWebSource(t,o){return Ne({source:t,options:o,plugins:this.#e})}serializeNmriumState(t,o){return me(t,this.#e,o)}serializeNmriumArchive(t){return de(t)}serializePlugins(){let t={plugins:{}};return b(t,this.#e),t.plugins}slot(t){return ge({slot:t,plugins:this.#e})}};function Ft(e,t){if(t>10)return 0;let o=-1;for(let r=0;r<e.length;r++)if(e[r].version>t){o=r;break}return o}var he=[{version:6,fun:O},{version:7,fun:M}];function vt(e){let{version:t}=e||{},o=Ft(he,t);if(o===-1)return{...e,version:10};let r=he.slice(o);for(let i of r)e=i.fun(e);return e}export{be as ANALYSIS_COLUMN_TYPES,Re as ANALYSIS_COLUMN_VALUES_KEYS,P as CURRENT_EXPORT_VERSION,Ie as EXTERNAL_API_KEYS,ee as NMRiumCore,Be as defineNMRiumPlugin,_e as formatSpectra,N as generateID,_ as getOneIfArray,vt as migrateSettings,Ce as units};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@zakodium/nmrium-core",
3
- "version": "0.2.3",
3
+ "version": "0.4.0",
4
4
  "description": "The core of NMRium: types, state, state migration and plugin system.",
5
5
  "author": "Zakodium Sàrl",
6
6
  "license": "CC-BY-NC-SA-4.0",
@@ -26,17 +26,17 @@
26
26
  "@types/lodash.merge": "^4.6.9",
27
27
  "@types/node": "^24.7.2",
28
28
  "@types/react": "^18.3.13",
29
- "@zakodium/nmr-types": "^0.2.1",
29
+ "@zakodium/nmr-types": "^0.3.0",
30
30
  "esbuild": "^0.25.10",
31
31
  "jest-matcher-deep-close-to": "^3.0.2",
32
32
  "rimraf": "^6.0.1",
33
33
  "typescript": "~5.9.3",
34
- "vitest": "^3.2.4"
34
+ "vitest": "^4.0.1"
35
35
  },
36
36
  "dependencies": {
37
37
  "cheminfo-types": "^1.8.1",
38
38
  "fifo-logger": "^2.0.1",
39
- "file-collection": "^5.1.1",
39
+ "file-collection": "^5.4.0",
40
40
  "is-any-array": "^2.0.1",
41
41
  "lodash.merge": "^4.6.2",
42
42
  "ml-spectra-processing": "^14.17.1",
@@ -45,5 +45,5 @@
45
45
  "volta": {
46
46
  "extends": "../../../package.json"
47
47
  },
48
- "gitHead": "590a8e4b1d464902733151fcefa7c9a739fddccf"
48
+ "gitHead": "9e3ff9aee0df39502b56fe15fab3d8e12d939b32"
49
49
  }