spectraview 1.3.0 → 1.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.
package/dist/index.cjs CHANGED
@@ -1,16 +1,16 @@
1
1
  "use client";
2
- "use strict";var Ge=Object.defineProperty;var pr=Object.getOwnPropertyDescriptor;var fr=Object.getOwnPropertyNames;var dr=Object.prototype.hasOwnProperty;var br=(e,t)=>{for(var r in t)Ge(e,r,{get:t[r],enumerable:!0})},gr=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of fr(t))!dr.call(e,n)&&n!==r&&Ge(e,n,{get:()=>t[n],enumerable:!(o=pr(t,n))||o.enumerable});return e};var hr=e=>gr(Ge({},"__esModule",{value:!0}),e);var Qr={};br(Qr,{AnnotationLayer:()=>Ce,AxisLayer:()=>ne,Crosshair:()=>we,DARK_THEME:()=>Qe,DropZone:()=>Me,ExportMenu:()=>Vt,KEYBOARD_SHORTCUTS:()=>At,LIGHT_THEME:()=>qe,LINE_DASH_PATTERNS:()=>ot,Legend:()=>le,Minimap:()=>Et,PeakMarkers:()=>Se,RegionSelector:()=>ve,SPECTRUM_COLORS:()=>he,SpectraView:()=>Tt,SpectrumCanvas:()=>re,StackedView:()=>Te,Toolbar:()=>Re,addSpectra:()=>Gt,baselineRubberBand:()=>Zt,binarySearchClosest:()=>et,computeXExtent:()=>be,computeYExtent:()=>Q,correlationCoefficient:()=>Jt,createXScale:()=>ge,createYScale:()=>ee,derivative1st:()=>Wt,derivative2nd:()=>Yt,detectPeaks:()=>De,differenceSpectrum:()=>jt,downloadSvg:()=>ze,generateChartDescription:()=>Fe,generateSvg:()=>Oe,getSpectrumColor:()=>F,getThemeColors:()=>X,interpolateToGrid:()=>Qt,lttbDownsample:()=>xe,normalizeArea:()=>_t,normalizeMinMax:()=>Bt,normalizeSNV:()=>Ht,parseCsv:()=>Ue,parseCsvMulti:()=>Ut,parseJcamp:()=>Ne,parseJson:()=>Ie,parseSpc:()=>er,prefersReducedMotion:()=>Mt,residualSpectrum:()=>qt,scaleSpectrum:()=>Kt,smoothSavitzkyGolay:()=>Xt,snapToNearestSpectrum:()=>ke,useExport:()=>zt,useKeyboardNavigation:()=>Pe,usePeakPicking:()=>Pt,useRegionSelect:()=>Ee,useResizeObserver:()=>Le,useSpectrumData:()=>Ot,useZoomPan:()=>ye});module.exports=hr(Qr);var A=require("react");var Ke=require("d3-scale"),Je=require("d3-array"),yr=.05;function be(e){let t=1/0,r=-1/0;for(let o of e){if(o.visible===!1)continue;let[n,a]=(0,Je.extent)(o.x);n<t&&(t=n),a>r&&(r=a)}return isFinite(t)?[t,r]:[0,1]}function Q(e){let t=1/0,r=-1/0;for(let a of e){if(a.visible===!1)continue;let[s,i]=(0,Je.extent)(a.y);s<t&&(t=s),i>r&&(r=i)}if(!isFinite(t))return[0,1];let n=(r-t)*yr;return[t-n,r+n]}function ge(e,t,r,o){let n=t-r.left-r.right,a=o?[e[1],e[0]]:e;return(0,Ke.scaleLinear)().domain(a).range([0,n])}function ee(e,t,r){let o=t-r.top-r.bottom;return(0,Ke.scaleLinear)().domain(e).range([o,0])}var he=["#2563eb","#dc2626","#16a34a","#9333ea","#ea580c","#0891b2","#be185d","#854d0e","#4f46e5","#65a30d"],qe={background:"#ffffff",axisColor:"#374151",gridColor:"#e5e7eb",tickColor:"#6b7280",labelColor:"#111827",crosshairColor:"#9ca3af",regionFill:"rgba(37, 99, 235, 0.1)",regionStroke:"rgba(37, 99, 235, 0.4)",tooltipBg:"#ffffff",tooltipBorder:"#d1d5db",tooltipText:"#111827"},Qe={background:"#111827",axisColor:"#d1d5db",gridColor:"#374151",tickColor:"#9ca3af",labelColor:"#f9fafb",crosshairColor:"#6b7280",regionFill:"rgba(96, 165, 250, 0.15)",regionStroke:"rgba(96, 165, 250, 0.5)",tooltipBg:"#1f2937",tooltipBorder:"#4b5563",tooltipText:"#f9fafb"};function F(e){return he[e%he.length]}function X(e){return e==="dark"?Qe:qe}var L=require("react"),te=require("d3-zoom"),W=require("d3-selection"),nn=require("d3-transition"),bt=1.5;function ye(e){let{plotWidth:t,plotHeight:r,xScale:o,yScale:n,scaleExtent:a=[1,50],enabled:s=!0,onViewChange:i}=e,l=(0,L.useRef)(null),c=(0,L.useRef)(null),u=(0,L.useRef)(i);u.current=i;let p=(0,L.useRef)(a);p.current=a;let[f,m]=(0,L.useState)(te.zoomIdentity),d=(0,L.useMemo)(()=>f.rescaleX(o.copy()),[f,o]),g=(0,L.useMemo)(()=>f.rescaleY(n.copy()),[f,n]);(0,L.useEffect)(()=>{let S=l.current;if(!S||!s)return;let k=(0,te.zoom)().scaleExtent(p.current).extent([[0,0],[t,r]]).translateExtent([[-1/0,-1/0],[1/0,1/0]]).on("zoom",h=>{let v=h.transform;if(m(v),u.current){let w=v.rescaleX(o.copy()),C=v.rescaleY(n.copy());u.current(w.domain(),C.domain())}});return c.current=k,(0,W.select)(S).call(k),(0,W.select)(S).on("dblclick.zoom",()=>{(0,W.select)(S).transition().duration(300).call(k.transform,te.zoomIdentity)}),()=>{(0,W.select)(S).on(".zoom",null)}},[t,r,s,o,n]);let y=(0,L.useCallback)(()=>{!l.current||!c.current||(0,W.select)(l.current).transition().duration(300).call(c.current.transform,te.zoomIdentity)},[]),b=(0,L.useCallback)(()=>{!l.current||!c.current||(0,W.select)(l.current).transition().duration(200).call(c.current.scaleBy,bt)},[]),x=(0,L.useCallback)(()=>{!l.current||!c.current||(0,W.select)(l.current).transition().duration(200).call(c.current.scaleBy,1/bt)},[]);return{zoomRef:l,state:{transform:f,isZoomed:f.k!==1||f.x!==0||f.y!==0},zoomedXScale:d,zoomedYScale:g,resetZoom:y,zoomIn:b,zoomOut:x}}var $=require("react");function xe(e,t,r,o,n,a,s){let i=o-r;if(i<=s){let f=[];for(let m=r;m<o;m++)f.push({px:n(e[m]),py:a(t[m]),index:m});return f}let l=[];l.push({px:n(e[r]),py:a(t[r]),index:r});let c=s-2,u=(i-2)/c,p=r;for(let f=0;f<c;f++){let m=r+1+Math.floor(f*u),d=r+1+Math.min(Math.floor((f+1)*u),i-2),g=d,y=r+1+Math.min(Math.floor((f+2)*u),i-2),b,x;if(f===c-1)b=n(e[o-1]),x=a(t[o-1]);else{b=0,x=0;let w=y-g;for(let C=g;C<y;C++)b+=n(e[C]),x+=a(t[C]);w>0&&(b/=w,x/=w)}let S=n(e[p]),k=a(t[p]),h=-1,v=m;for(let w=m;w<d;w++){let C=n(e[w]),M=a(t[w]),E=Math.abs((S-b)*(M-k)-(S-C)*(x-k));E>h&&(h=E,v=w)}l.push({px:n(e[v]),py:a(t[v]),index:v}),p=v}return l.push({px:n(e[o-1]),py:a(t[o-1]),index:o-1}),l}var xr=1.5,Sr={solid:[],dashed:[8,4],dotted:[2,2],"dash-dot":[8,4,2,4]},vr=2e3;function wr(e,t,r){e.clearRect(0,0,t,r)}function Cr(e,t,r,o,n,a,s){let{highlighted:i=!1,opacity:l=1}=s??{},c=Math.min(t.x.length,t.y.length);if(c<2)return;let u=t.color??F(r),p=t.lineWidth??xr,f=i?p+1:p,m=Sr[t.lineStyle??"solid"]??[],[d,g]=o.domain(),y=Math.min(d,g),b=Math.max(d,g),x=0,S=c;for(let h=0;h<c;h++)if(t.x[h]>=y||h<c-1&&t.x[h+1]>=y){x=Math.max(0,h-1);break}for(let h=c-1;h>=0;h--)if(t.x[h]<=b||h>0&&t.x[h-1]<=b){S=Math.min(c,h+2);break}let k=S-x;if(e.save(),e.beginPath(),e.strokeStyle=u,e.lineWidth=f,e.globalAlpha=l,e.lineJoin="round",e.setLineDash(m),k>vr){let h=Math.max(Math.ceil(a*2),200),v=xe(t.x,t.y,x,S,o,n,h);if(v.length>0){e.moveTo(v[0].px,v[0].py);for(let w=1;w<v.length;w++)e.lineTo(v[w].px,v[w].py)}}else{let h=!1;for(let v=x;v<S;v++){let w=o(t.x[v]),C=n(t.y[v]);h?e.lineTo(w,C):(e.moveTo(w,C),h=!0)}}e.stroke(),e.restore()}function gt(e,t,r,o,n,a,s){wr(e,n,a),t.forEach((i,l)=>{i.visible!==!1&&Cr(e,i,l,r,o,n,{highlighted:i.id===s,opacity:s&&i.id!==s?.3:1})})}var ht=require("react/jsx-runtime"),re=(0,$.forwardRef)(function({spectra:t,xScale:r,yScale:o,width:n,height:a,highlightedId:s},i){let l=(0,$.useRef)(null),c=(0,$.useRef)(1);return(0,$.useImperativeHandle)(i,()=>l.current,[]),(0,$.useEffect)(()=>{let u=l.current;if(!u)return;let p=window.devicePixelRatio||1;c.current=p,u.width=n*p,u.height=a*p},[n,a]),(0,$.useEffect)(()=>{let u=l.current;if(!u)return;let p=u.getContext("2d");if(!p)return;let f=c.current;p.setTransform(f,0,0,f,0,0),gt(p,t,r,o,n,a,s)},[t,r,o,n,a,s]),(0,ht.jsx)("canvas",{ref:l,style:{width:n,height:a,position:"absolute",top:0,left:0,pointerEvents:"none"}})});var T=require("react/jsx-runtime");function yt(e,t){let[r,o]=e.domain(),n=Math.min(r,o),s=(Math.max(r,o)-n)/(t-1);return Array.from({length:t},(i,l)=>n+l*s)}function xt(e){return Math.abs(e)>=1e3?Math.round(e).toString():Math.abs(e)>=1?e.toFixed(1):Math.abs(e)>=.01?e.toFixed(3):e.toExponential(1)}function ne({xScale:e,yScale:t,width:r,height:o,xLabel:n,yLabel:a,showGrid:s=!0,colors:i}){let l=yt(e,8),c=yt(t,6);return(0,T.jsxs)("g",{children:[s&&(0,T.jsxs)("g",{children:[l.map(u=>(0,T.jsx)("line",{x1:e(u),x2:e(u),y1:0,y2:o,stroke:i.gridColor,strokeWidth:.5},`xgrid-${u}`)),c.map(u=>(0,T.jsx)("line",{x1:0,x2:r,y1:t(u),y2:t(u),stroke:i.gridColor,strokeWidth:.5},`ygrid-${u}`))]}),(0,T.jsxs)("g",{transform:`translate(0, ${o})`,children:[(0,T.jsx)("line",{x1:0,x2:r,y1:0,y2:0,stroke:i.axisColor}),l.map(u=>(0,T.jsxs)("g",{transform:`translate(${e(u)}, 0)`,children:[(0,T.jsx)("line",{y1:0,y2:6,stroke:i.axisColor}),(0,T.jsx)("text",{y:20,textAnchor:"middle",fill:i.tickColor,fontSize:11,fontFamily:"system-ui, sans-serif",children:xt(u)})]},`xtick-${u}`)),n&&(0,T.jsx)("text",{x:r/2,y:42,textAnchor:"middle",fill:i.labelColor,fontSize:13,fontFamily:"system-ui, sans-serif",children:n})]}),(0,T.jsxs)("g",{children:[(0,T.jsx)("line",{x1:0,x2:0,y1:0,y2:o,stroke:i.axisColor}),c.map(u=>(0,T.jsxs)("g",{transform:`translate(0, ${t(u)})`,children:[(0,T.jsx)("line",{x1:-6,x2:0,stroke:i.axisColor}),(0,T.jsx)("text",{x:-10,textAnchor:"end",dominantBaseline:"middle",fill:i.tickColor,fontSize:11,fontFamily:"system-ui, sans-serif",children:xt(u)})]},`ytick-${u}`)),a&&(0,T.jsx)("text",{transform:`translate(-50, ${o/2}) rotate(-90)`,textAnchor:"middle",fill:i.labelColor,fontSize:13,fontFamily:"system-ui, sans-serif",children:a})]})]})}var oe=require("react/jsx-runtime");function Se({peaks:e,xScale:t,yScale:r,colors:o,onPeakClick:n}){let[a,s]=t.domain(),i=Math.min(a,s),l=Math.max(a,s),c=e.filter(u=>u.x>=i&&u.x<=l);return(0,oe.jsx)("g",{className:"spectraview-peaks",children:c.map((u,p)=>{let f=t(u.x),m=r(u.y);return(0,oe.jsxs)("g",{transform:`translate(${f}, ${m})`,style:{cursor:n?"pointer":"default"},onClick:()=>n?.(u),children:[(0,oe.jsx)("polygon",{points:`0,-5 -5,${-5*2.5} 5,${-5*2.5}`,fill:o.labelColor,opacity:.8}),u.label&&(0,oe.jsx)("text",{y:-5*2.5-14,textAnchor:"middle",fill:o.labelColor,fontSize:10,fontFamily:"system-ui, sans-serif",fontWeight:500,children:u.label})]},`peak-${u.x}-${p}`)})})}var ie=require("react/jsx-runtime");function ve({regions:e,xScale:t,height:r,colors:o}){return(0,ie.jsx)("g",{className:"spectraview-regions",children:e.map((n,a)=>{let s=t(n.xStart),i=t(n.xEnd),l=Math.min(s,i),c=Math.abs(i-s);return(0,ie.jsxs)("g",{children:[(0,ie.jsx)("rect",{x:l,y:0,width:c,height:r,fill:n.color??o.regionFill,stroke:o.regionStroke,strokeWidth:1}),n.label&&(0,ie.jsx)("text",{x:l+c/2,y:12,textAnchor:"middle",fill:o.labelColor,fontSize:10,fontFamily:"system-ui, sans-serif",children:n.label})]},`region-${a}`)})})}var z=require("react/jsx-runtime");function we({position:e,width:t,height:r,colors:o,snapPoint:n}){return e?(0,z.jsxs)("g",{className:"spectraview-crosshair",pointerEvents:"none",children:[(0,z.jsx)("line",{x1:e.px,x2:e.px,y1:0,y2:r,stroke:o.crosshairColor,strokeWidth:1,strokeDasharray:"4 4"}),(0,z.jsx)("line",{x1:0,x2:t,y1:e.py,y2:e.py,stroke:o.crosshairColor,strokeWidth:1,strokeDasharray:"4 4"}),n&&(0,z.jsx)("circle",{cx:n.px,cy:n.py,r:4,fill:n.color??o.crosshairColor,stroke:o.background,strokeWidth:1.5}),(0,z.jsxs)("g",{transform:`translate(${Math.min(e.px+10,t-100)}, ${Math.max(e.py-10,20)})`,children:[(0,z.jsx)("rect",{x:0,y:-14,width:90,height:18,rx:3,fill:o.tooltipBg,stroke:o.tooltipBorder,strokeWidth:.5,opacity:.9}),(0,z.jsxs)("text",{x:5,y:0,fill:o.tooltipText,fontSize:10,fontFamily:"monospace",children:[St(n?.dataX??e.dataX),","," ",St(n?.dataY??e.dataY)]})]})]}):null}function St(e){return Math.abs(e)>=100?Math.round(e).toString():Math.abs(e)>=1?e.toFixed(1):e.toFixed(4)}var Y=require("react/jsx-runtime");function Ce({annotations:e,xScale:t,yScale:r,colors:o}){return e.length===0?null:(0,Y.jsx)("g",{className:"spectraview-annotations",pointerEvents:"none",children:e.map(n=>{let a=t(n.x),s=r(n.y),[i,l]=n.offset??[0,-20],c=a+i,u=s+l,p=n.fontSize??11,f=n.color??o.tickColor,m=n.showAnchorLine!==!1;return(0,Y.jsxs)("g",{children:[m&&(0,Y.jsx)("line",{x1:a,y1:s,x2:c,y2:u,stroke:f,strokeWidth:.75,strokeDasharray:"3 2",opacity:.6}),(0,Y.jsx)("circle",{cx:a,cy:s,r:2.5,fill:f,opacity:.8}),(0,Y.jsx)("text",{x:c,y:u,fill:o.background,fontSize:p,fontFamily:"system-ui, sans-serif",textAnchor:"middle",dominantBaseline:"auto",stroke:o.background,strokeWidth:3,strokeLinejoin:"round",children:n.text}),(0,Y.jsx)("text",{x:c,y:u,fill:f,fontSize:p,fontFamily:"system-ui, sans-serif",textAnchor:"middle",dominantBaseline:"auto",children:n.text})]},n.id)})})}function et(e,t,r){if(r===0)return-1;if(r===1)return 0;let o=e[r-1]>=e[0],n=0,a=r-1;for(;n<a-1;){let l=n+a>>>1,c=e[l];o?c<=t?n=l:a=l:c>=t?n=l:a=l}let s=Math.abs(e[n]-t),i=Math.abs(e[a]-t);return s<=i?n:a}function ke(e,t,r,o,n){let a=null;for(let s of e){if(s.visible===!1)continue;let i=Math.min(s.x.length,s.y.length);if(i<2)continue;let l=et(s.x,t,i);if(l<0)continue;let c=s.x[l],u=s.y[l],p=Math.abs(o(c)-o(t)),f=Math.abs(n(u)-r),m=Math.sqrt(p*p+f*f);(!a||m<a.distance)&&(a={spectrumId:s.id,index:l,x:c,y:u,distance:m})}return a}var vt=require("react"),ae=require("react/jsx-runtime"),tt=e=>({display:"inline-flex",alignItems:"center",justifyContent:"center",width:28,height:28,border:`1px solid ${e==="dark"?"#4b5563":"#d1d5db"}`,borderRadius:4,background:e==="dark"?"#1f2937":"#ffffff",color:e==="dark"?"#d1d5db":"#374151",fontSize:14,cursor:"pointer",padding:0,lineHeight:1}),kr=e=>({display:"flex",gap:4,padding:"4px 0",borderBottom:`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`}),Re=(0,vt.memo)(function({onZoomIn:t,onZoomOut:r,onReset:o,isZoomed:n,theme:a}){return(0,ae.jsxs)("div",{style:kr(a),className:"spectraview-toolbar",children:[(0,ae.jsx)("button",{type:"button",style:tt(a),onClick:t,title:"Zoom in","aria-label":"Zoom in",children:"+"}),(0,ae.jsx)("button",{type:"button",style:tt(a),onClick:r,title:"Zoom out","aria-label":"Zoom out",children:"\u2212"}),(0,ae.jsx)("button",{type:"button",style:{...tt(a),opacity:n?1:.4},onClick:o,disabled:!n,title:"Reset zoom","aria-label":"Reset zoom",children:"\u21BA"})]})});var wt=require("react");var se=require("react/jsx-runtime"),Rr=(e,t)=>({display:"flex",flexDirection:t==="left"||t==="right"?"column":"row",flexWrap:"wrap",gap:6,padding:"4px 8px",fontSize:12,fontFamily:"system-ui, sans-serif",borderTop:t==="bottom"?`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`:void 0,borderBottom:t==="top"?`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`:void 0,borderLeft:t==="right"?`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`:void 0,borderRight:t==="left"?`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`:void 0}),Mr=(e,t,r)=>({display:"inline-flex",alignItems:"center",gap:4,cursor:"pointer",opacity:t?.4:1,fontWeight:r?600:400,color:e==="dark"?"#e5e7eb":"#374151",userSelect:"none",padding:"2px 4px",borderRadius:3,background:r?e==="dark"?"rgba(255,255,255,0.08)":"rgba(0,0,0,0.04)":"transparent",transition:"background 0.15s, opacity 0.15s"}),Ar=(e,t)=>({width:12,height:3,borderRadius:1,background:e,opacity:t?.4:1,flexShrink:0}),le=(0,wt.memo)(function({spectra:t,theme:r,position:o,onToggleVisibility:n,onHighlight:a,highlightedId:s}){return t.length<=1?null:(0,se.jsx)("div",{className:"spectraview-legend",style:Rr(r,o),role:"list","aria-label":"Spectrum legend",children:t.map((i,l)=>{let c=i.color??F(l),u=i.visible===!1,p=s===i.id;return(0,se.jsxs)("div",{role:"listitem",style:Mr(r,u,p),onClick:()=>n?.(i.id),onMouseEnter:()=>a?.(i.id),onMouseLeave:()=>a?.(null),title:u?`Show ${i.label}`:`Hide ${i.label}`,children:[(0,se.jsx)("span",{style:Ar(c,u)}),(0,se.jsx)("span",{style:{textDecoration:u?"line-through":"none",maxWidth:120,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:i.label})]},i.id)})})});var q=require("react"),Ae=require("react/jsx-runtime");function Me({enabled:e,theme:t,width:r,height:o,onDrop:n,children:a}){let[s,i]=(0,q.useState)(!1),l={current:0},c=(0,q.useCallback)(m=>{e&&(m.preventDefault(),l.current++,i(!0))},[e]),u=(0,q.useCallback)(m=>{e&&(m.preventDefault(),l.current--,l.current<=0&&(l.current=0,i(!1)))},[e]),p=(0,q.useCallback)(m=>{e&&(m.preventDefault(),m.dataTransfer.dropEffect="copy")},[e]),f=(0,q.useCallback)(m=>{if(!e)return;m.preventDefault(),l.current=0,i(!1);let d=Array.from(m.dataTransfer.files);d.length>0&&n?.(d)},[e,n]);return(0,Ae.jsxs)("div",{style:{position:"relative",width:r,height:o},onDragEnter:c,onDragLeave:u,onDragOver:p,onDrop:f,children:[a,s&&(0,Ae.jsx)("div",{"data-testid":"dropzone-overlay",style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:t==="dark"?"rgba(30, 58, 138, 0.6)":"rgba(59, 130, 246, 0.15)",border:`2px dashed ${t==="dark"?"#60a5fa":"#3b82f6"}`,borderRadius:4,zIndex:100,pointerEvents:"none",fontSize:14,fontFamily:"system-ui, sans-serif",color:t==="dark"?"#93c5fd":"#1d4ed8",fontWeight:500},children:"Drop spectrum files here"})]})}var kt=require("react");var V=require("react/jsx-runtime"),Ct=8;function Te({spectra:e,xScale:t,plotWidth:r,plotHeight:o,margin:n,theme:a,showGrid:s,xLabel:i,yLabel:l}){let c=e.filter(d=>d.visible!==!1),u=(0,kt.useMemo)(()=>X(a),[a]),p=c.length,f=(p-1)*Ct,m=Math.max(40,Math.floor((o-f)/Math.max(p,1)));return(0,V.jsx)("g",{className:"spectraview-stacked",children:c.map((d,g)=>{let y=g*(m+Ct),b=Q([d]),x=ee(b,m+n.top+n.bottom,{...n,top:0,bottom:0}),S=d.color??F(g),k={...d,color:S};return(0,V.jsxs)("g",{transform:`translate(0, ${y})`,children:[(0,V.jsx)("rect",{x:0,y:0,width:r,height:m,fill:"transparent",stroke:u.gridColor,strokeWidth:.5,rx:2}),(0,V.jsx)(ne,{xScale:t,yScale:x,width:r,height:m,xLabel:g===p-1?i:"",yLabel:l,showGrid:s,colors:u}),(0,V.jsx)("text",{x:4,y:14,fill:S,fontSize:11,fontFamily:"system-ui, sans-serif",fontWeight:500,children:d.label}),(0,V.jsx)("foreignObject",{x:0,y:0,width:r,height:m,children:(0,V.jsx)(re,{spectra:[k],xScale:t,yScale:x,width:r,height:m})})]},d.id)})})}var j=require("react");function Ee(e){let{enabled:t,xScale:r,onRegionSelect:o}=e,[n,a]=(0,j.useState)(null),s=(0,j.useRef)(null),i=(0,j.useCallback)(u=>{if(!t||!u.shiftKey)return;u.preventDefault();let p=u.currentTarget.getBoundingClientRect(),f=u.clientX-p.left,m=r.invert(f);s.current=m,a({xStart:m,xEnd:m})},[t,r]),l=(0,j.useCallback)(u=>{if(s.current===null)return;let p=u.currentTarget.getBoundingClientRect(),f=u.clientX-p.left,m=r.invert(f),d=s.current;a({xStart:Math.min(d,m),xEnd:Math.max(d,m)})},[r]),c=(0,j.useCallback)(()=>{if(s.current===null||!n)return;Math.abs(n.xEnd-n.xStart)>0&&o?.(n),s.current=null,a(null)},[n,o]);return{pendingRegion:n,handleMouseDown:i,handleMouseMove:l,handleMouseUp:c}}var Z=require("react");function Le(){let[e,t]=(0,Z.useState)(null),r=(0,Z.useRef)(null),o=(0,Z.useRef)(null),n=(0,Z.useCallback)(a=>{if(r.current&&(r.current.disconnect(),r.current=null),o.current=a,!a)return;let s=new ResizeObserver(c=>{let u=c[0];if(!u)return;let{width:p,height:f}=u.contentRect;t({width:Math.round(p),height:Math.round(f)})});s.observe(a),r.current=s;let{width:i,height:l}=a.getBoundingClientRect();t({width:Math.round(i),height:Math.round(l)})},[]);return(0,Z.useEffect)(()=>()=>{r.current?.disconnect()},[]),{ref:n,size:e}}var Rt=require("react");function Pe(e){let{onZoomIn:t,onZoomOut:r,onReset:o,enabled:n=!0}=e;return(0,Rt.useCallback)(s=>{if(n)switch(s.key){case"+":case"=":s.preventDefault(),t();break;case"-":s.preventDefault(),r();break;case"Escape":s.preventDefault(),o();break}},[n,t,r,o])}function Mt(){return typeof window>"u"?!1:window.matchMedia("(prefers-reduced-motion: reduce)").matches}function Fe(e,t,r){return e===0?"Empty spectrum viewer":`Interactive spectrum viewer showing ${e} ${e===1?"spectrum":"spectra"}. X-axis: ${t}. Y-axis: ${r}. Use arrow keys to pan, +/- to zoom, Escape to reset.`}var At={PAN_LEFT:"ArrowLeft",PAN_RIGHT:"ArrowRight",PAN_UP:"ArrowUp",PAN_DOWN:"ArrowDown",ZOOM_IN:"+",ZOOM_IN_ALT:"=",ZOOM_OUT:"-",RESET:"Escape",NEXT_PEAK:"Tab",PREV_PEAK:"Shift+Tab"};var R=require("react/jsx-runtime"),Tr={top:20,right:20,bottom:50,left:65},Er=800,Lr=400;function Pr(e){return{width:e.width??Er,height:e.height??Lr,reverseX:e.reverseX??!1,showGrid:e.showGrid??!0,showCrosshair:e.showCrosshair??!0,showToolbar:e.showToolbar??!0,showLegend:e.showLegend??!0,legendPosition:e.legendPosition??"bottom",displayMode:e.displayMode??"overlay",margin:{...Tr,...e.margin},theme:e.theme??"light",responsive:e.responsive??!1,enableDragDrop:e.enableDragDrop??!1,enableRegionSelect:e.enableRegionSelect??!1}}function Fr(e,t,r){let o=e[0];return{xLabel:t??o?.xUnit??"x",yLabel:r??o?.yUnit??"y"}}function Tt(e){let{spectra:t,peaks:r=[],regions:o=[],annotations:n=[],onPeakClick:a,onViewChange:s,onCrosshairMove:i,onToggleVisibility:l,onFileDrop:c,onRegionSelect:u,canvasRef:p,snapCrosshair:f=!0}=e,{ref:m,size:d}=Le(),y=`spectraview-clip-${(0,A.useId)().replace(/:/g,"")}`,b=(0,A.useMemo)(()=>Pr(e),[e.width,e.height,e.reverseX,e.showGrid,e.showCrosshair,e.showToolbar,e.showLegend,e.legendPosition,e.displayMode,e.margin,e.theme,e.responsive,e.enableDragDrop,e.enableRegionSelect]),x=b.responsive&&d?d.width:b.width,{height:S,margin:k,reverseX:h,theme:v}=b,w=x-k.left-k.right,C=S-k.top-k.bottom,M=(0,A.useMemo)(()=>X(v),[v]),E=(0,A.useMemo)(()=>Fr(t,e.xLabel,e.yLabel),[t,e.xLabel,e.yLabel]),D=(0,A.useMemo)(()=>be(t),[t]),U=(0,A.useMemo)(()=>Q(t),[t]),_e=(0,A.useMemo)(()=>ge(D,x,k,h),[D,x,k,h]),K=(0,A.useMemo)(()=>ee(U,S,k),[U,S,k]),J=(0,A.useRef)(s);J.current=s;let tr=(0,A.useMemo)(()=>(H,fe)=>{J.current?.({xDomain:H,yDomain:fe})},[]),{zoomRef:it,state:rr,zoomedXScale:P,zoomedYScale:_,resetZoom:at,zoomIn:st,zoomOut:lt}=ye({plotWidth:w,plotHeight:C,xScale:_e,yScale:K,onViewChange:s?tr:void 0}),{pendingRegion:ue,handleMouseDown:nr,handleMouseMove:or,handleMouseUp:ir}=Ee({enabled:b.enableRegionSelect,xScale:P,onRegionSelect:u}),[He,ct]=(0,A.useState)(null),[ar,mt]=(0,A.useState)(null),[sr,Xe]=(0,A.useState)(null),pe=(0,A.useRef)(i);pe.current=i;let ut=(0,A.useCallback)(H=>{if(!b.showCrosshair)return;let fe=H.currentTarget.getBoundingClientRect(),ft=H.clientX-fe.left,Ye=H.clientY-fe.top,de=P.invert(ft),je=_.invert(Ye);if(mt({px:ft,py:Ye,dataX:de,dataY:je}),f&&t.length>0){let O=ke(t,de,Ye,P,_);if(O&&O.distance<50){let dt=t.findIndex(ur=>ur.id===O.spectrumId);Xe({px:P(O.x),py:_(O.y),dataX:O.x,dataY:O.y,color:t[dt]?.color??F(dt)}),pe.current?.(O.x,O.y)}else Xe(null),pe.current?.(de,je)}else pe.current?.(de,je)},[P,_,b.showCrosshair,f,t]),pt=(0,A.useCallback)(()=>{mt(null),Xe(null)},[]),lr=Pe({onZoomIn:st,onZoomOut:lt,onReset:at}),cr=(0,A.useMemo)(()=>Fe(t.length,E.xLabel,E.yLabel),[t.length,E.xLabel,E.yLabel]),mr=b.displayMode==="stacked";if(t.length===0)return(0,R.jsx)("div",{ref:b.responsive?m:void 0,style:{width:b.responsive?"100%":x,height:S,display:"flex",alignItems:"center",justifyContent:"center",border:`1px dashed ${M.gridColor}`,borderRadius:8,color:M.tickColor,fontFamily:"system-ui, sans-serif",fontSize:14},className:e.className,children:"No spectra loaded"});let We=b.showToolbar?37:0;return(0,R.jsxs)("div",{ref:b.responsive?m:void 0,style:{width:b.responsive?"100%":x,background:M.background,borderRadius:4,overflow:"hidden"},className:e.className,role:"img","aria-label":cr,tabIndex:0,onKeyDown:lr,children:[b.showToolbar&&(0,R.jsx)(Re,{onZoomIn:st,onZoomOut:lt,onReset:at,isZoomed:rr.isZoomed,theme:v}),b.showLegend&&b.legendPosition==="top"&&(0,R.jsx)(le,{spectra:t,theme:v,position:"top",onToggleVisibility:l,onHighlight:ct,highlightedId:He}),(0,R.jsx)(Me,{enabled:b.enableDragDrop,theme:v,width:x,height:S-We,onDrop:c,children:mr?(0,R.jsx)("svg",{width:x,height:S-We,style:{position:"absolute",top:0,left:0},children:(0,R.jsxs)("g",{transform:`translate(${k.left}, ${k.top})`,children:[(0,R.jsx)(Te,{spectra:t,xScale:P,plotWidth:w,plotHeight:C,margin:k,theme:v,showGrid:b.showGrid,xLabel:E.xLabel,yLabel:E.yLabel}),(0,R.jsx)("rect",{ref:it,x:0,y:0,width:w,height:C,fill:"transparent",style:{cursor:"grab"},onMouseMove:ut,onMouseLeave:pt})]})}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)("div",{style:{position:"absolute",top:k.top,left:k.left,width:w,height:C,overflow:"hidden"},children:(0,R.jsx)(re,{ref:p,spectra:t,xScale:P,yScale:_,width:w,height:C,highlightedId:He??void 0})}),(0,R.jsx)("svg",{width:x,height:S-We,style:{position:"absolute",top:0,left:0},children:(0,R.jsxs)("g",{transform:`translate(${k.left}, ${k.top})`,children:[(0,R.jsx)(ne,{xScale:P,yScale:_,width:w,height:C,xLabel:E.xLabel,yLabel:E.yLabel,showGrid:b.showGrid,colors:M}),(0,R.jsx)("defs",{children:(0,R.jsx)("clipPath",{id:y,children:(0,R.jsx)("rect",{x:0,y:0,width:w,height:C})})}),(0,R.jsxs)("g",{clipPath:`url(#${y})`,children:[o.length>0&&(0,R.jsx)(ve,{regions:o,xScale:P,height:C,colors:M}),r.length>0&&(0,R.jsx)(Se,{peaks:r,xScale:P,yScale:_,colors:M,onPeakClick:a})]}),n.length>0&&(0,R.jsx)(Ce,{annotations:n,xScale:P,yScale:_,colors:M}),b.showCrosshair&&(0,R.jsx)(we,{position:ar,width:w,height:C,colors:M,snapPoint:sr}),ue&&(0,R.jsx)("rect",{x:P(ue.xStart),y:0,width:Math.abs(P(ue.xEnd)-P(ue.xStart)),height:C,fill:M.regionFill,stroke:M.regionStroke,strokeWidth:1,pointerEvents:"none"}),(0,R.jsx)("rect",{ref:it,x:0,y:0,width:w,height:C,fill:"transparent",style:{cursor:b.showCrosshair?"crosshair":"grab"},onMouseDown:nr,onMouseMove:H=>{ut(H),or(H)},onMouseUp:ir,onMouseLeave:pt})]})})]})}),b.showLegend&&b.legendPosition==="bottom"&&(0,R.jsx)(le,{spectra:t,theme:v,position:"bottom",onToggleVisibility:l,onHighlight:ct,highlightedId:He})]})}var N=require("react"),rt=require("d3-scale");var G=require("react/jsx-runtime"),Et=(0,N.memo)(function({spectra:t,xExtent:r,yExtent:o,visibleXDomain:n,width:a=200,height:s=50,theme:i="light",isZoomed:l=!1}){let c=(0,N.useRef)(null),u=(0,N.useMemo)(()=>X(i),[i]),p=(0,N.useMemo)(()=>(0,rt.scaleLinear)().domain(r).range([0,a]),[r,a]),f=(0,N.useMemo)(()=>(0,rt.scaleLinear)().domain(o).range([s-2,2]),[o,s]);(0,N.useEffect)(()=>{let y=c.current?.getContext("2d");if(y){y.clearRect(0,0,a,s);for(let b=0;b<t.length;b++){let x=t[b];if(x.visible===!1)continue;let S=Math.min(x.x.length,x.y.length);if(S<2)continue;let k=x.color??F(b);y.beginPath(),y.strokeStyle=k,y.lineWidth=1,y.globalAlpha=.7;let h=Math.max(1,Math.floor(S/a)),v=!1;for(let w=0;w<S;w+=h){let C=p(x.x[w]),M=f(x.y[w]);v?y.lineTo(C,M):(y.moveTo(C,M),v=!0)}y.stroke()}}},[t,p,f,a,s]);let m=p(Math.min(n[0],n[1])),d=p(Math.max(n[0],n[1])),g=Math.max(d-m,2);return(0,G.jsxs)("div",{className:"spectraview-minimap",style:{position:"relative",width:a,height:s,border:`1px solid ${u.gridColor}`,borderRadius:3,overflow:"hidden",background:u.background},children:[(0,G.jsx)("canvas",{ref:c,width:a,height:s,style:{position:"absolute",top:0,left:0}}),l&&(0,G.jsxs)("svg",{width:a,height:s,style:{position:"absolute",top:0,left:0},children:[(0,G.jsx)("rect",{x:0,y:0,width:m,height:s,fill:u.background,opacity:.6}),(0,G.jsx)("rect",{x:m+g,y:0,width:a-m-g,height:s,fill:u.background,opacity:.6}),(0,G.jsx)("rect",{x:m,y:0,width:g,height:s,fill:"none",stroke:i==="dark"?"#60a5fa":"#3b82f6",strokeWidth:1.5,rx:1})]})]})});var Lt=require("react");function De(e,t,r={}){let{prominence:o=.01,minDistance:n=5,maxPeaks:a}=r;if(e.length<3||t.length<3)return[];let s=1/0,i=-1/0;for(let m=0;m<t.length;m++)t[m]<s&&(s=t[m]),t[m]>i&&(i=t[m]);let l=i-s;if(l===0)return[];let c=o*l,u=[];for(let m=1;m<t.length-1;m++)if(t[m]>t[m-1]&&t[m]>t[m+1]){let d=Dr(t,m),g=Ur(t,m),y=t[m]-Math.max(d,g);y>=c&&u.push({index:m,prom:y})}u.sort((m,d)=>d.prom-m.prom);let p=[];for(let m of u)p.some(g=>Math.abs(g.index-m.index)<n)||p.push(m);return(a?p.slice(0,a):p).map(m=>({x:e[m.index],y:t[m.index],label:Ir(e[m.index])})).sort((m,d)=>m.x-d.x)}function Dr(e,t){let r=e[t];for(let o=t-1;o>=0&&!(e[o]>e[t]);o--)e[o]<r&&(r=e[o]);return r}function Ur(e,t){let r=e[t];for(let o=t+1;o<e.length&&!(e[o]>e[t]);o++)e[o]<r&&(r=e[o]);return r}function Ir(e){return Math.round(e).toString()}function Pt(e,t={}){let{enabled:r=!0,spectrumIds:o,prominence:n,minDistance:a,maxPeaks:s}=t;return(0,Lt.useMemo)(()=>{if(!r)return[];let i=o?e.filter(c=>o.includes(c.id)):e,l=[];for(let c of i){if(c.visible===!1)continue;let u=De(c.x,c.y,{prominence:n,minDistance:a,maxPeaks:s});for(let p of u)l.push({...p,spectrumId:c.id})}return l},[e,r,o,n,a,s])}var I=require("react");var Ft=0,$r=[" ",",",";"," "];function Dt(e){let t=e.trim().split(/\r?\n/).slice(0,5),r=",",o=0;for(let n of $r){let a=t.map(i=>i.split(n).length-1),s=Math.min(...a);s>0&&s>=o&&(a.every(l=>l===a[0])||s>o)&&(o=s,r=n)}return r}function Ue(e,t={}){let{xColumn:r=0,yColumn:o=1,hasHeader:n=!0,label:a="CSV Spectrum"}=t,s=t.delimiter??Dt(e),i=e.trim().split(/\r?\n/);if(i.length<2)throw new Error("CSV file must contain at least 2 lines");let l=a,c=0;if(n){let f=i[0].split(s).map(m=>m.trim());!t.label&&f[o]&&(l=f[o]),c=1}let u=[],p=[];for(let f=c;f<i.length;f++){let m=i[f].trim();if(m===""||m.startsWith("#"))continue;let d=m.split(s),g=parseFloat(d[r]),y=parseFloat(d[o]);!isNaN(g)&&!isNaN(y)&&(u.push(g),p.push(y))}if(u.length===0)throw new Error("No valid numeric data found in CSV");return{id:`csv-${++Ft}`,label:l,x:new Float64Array(u),y:new Float64Array(p)}}function Ut(e,t={}){let{hasHeader:r=!0,label:o}=t,n=t.delimiter??Dt(e),a=e.trim().split(/\r?\n/);if(a.length<2)throw new Error("CSV file must contain at least 2 lines");let i=a[r?1:0].split(n).length;if(i<2)throw new Error("CSV must have at least 2 columns (x + y)");let l,c=0;r&&(l=a[0].split(n).map(m=>m.trim()),c=1);let u=[],p=Array.from({length:i-1},()=>[]);for(let m=c;m<a.length;m++){let d=a[m].trim();if(d===""||d.startsWith("#"))continue;let g=d.split(n),y=parseFloat(g[0]);if(!isNaN(y)){u.push(y);for(let b=1;b<i;b++){let x=parseFloat(g[b]);p[b-1].push(isNaN(x)?0:x)}}}let f=new Float64Array(u);return p.map((m,d)=>({id:`csv-${++Ft}`,label:o??l?.[d+1]??`Spectrum ${d+1}`,x:f,y:new Float64Array(m)}))}var Nr=0;function Ie(e){let t;try{t=JSON.parse(e)}catch{throw new Error("Invalid JSON: failed to parse input")}if(Array.isArray(t))return t.map((r,o)=>nt(r,o));if(typeof t=="object"&&t!==null){let r=t;return Array.isArray(r.spectra)?r.spectra.map((o,n)=>nt(o,n)):[nt(t,0)]}throw new Error("Invalid JSON structure: expected an object or array")}function nt(e,t){let r=e.x??e.wavenumbers??e.wavelengths;if(!r||!Array.isArray(r))throw new Error(`Spectrum ${t}: missing x-axis data (expected "x", "wavenumbers", or "wavelengths")`);let o=e.y??e.intensities??e.absorbance;if(!o||!Array.isArray(o))throw new Error(`Spectrum ${t}: missing y-axis data (expected "y", "intensities", or "absorbance")`);if(r.length!==o.length)throw new Error(`Spectrum ${t}: x and y arrays must have the same length (got ${r.length} and ${o.length})`);let n=e.label??e.title??e.name??`Spectrum ${t+1}`;return{id:`json-${++Nr}`,label:n,x:new Float64Array(r),y:new Float64Array(o),xUnit:e.xUnit,yUnit:e.yUnit,type:e.type,meta:e.meta}}var $t=0,$e=null,It=!1;async function Or(){if(It)return $e;It=!0;try{$e=await import("jcampconverter")}catch{$e=null}return $e}function Nt(e){let t=(e["DATA TYPE"]??e.DATATYPE??"").toLowerCase();return t.includes("infrared")||t.includes("ir")?"IR":t.includes("raman")?"Raman":t.includes("nir")||t.includes("near")?"NIR":t.includes("uv")||t.includes("vis")?"UV-Vis":t.includes("fluor")?"fluorescence":"other"}async function Ne(e){let t=await Or();return t?zr(e,t):[Vr(e)]}function zr(e,t){return t.convert(e,{keepRecordsRegExp:/.*/}).flatten.map((o,n)=>{let a=o.spectra?.[0]?.data?.[0];if(!a)throw new Error(`JCAMP block ${n}: no spectral data found`);return{id:`jcamp-${++$t}`,label:o.info?.TITLE??`Spectrum ${n+1}`,x:new Float64Array(a.x),y:new Float64Array(a.y),xUnit:o.info?.XUNITS??"cm\u207B\xB9",yUnit:o.info?.YUNITS??"Absorbance",type:Nt(o.info),meta:o.info}})}function Vr(e){let t=e.split(/\r?\n/),r={},o=[],n=[],a=!1;for(let s of t){let i=s.trim();if(i.startsWith("##")){let l=i.match(/^##(.+?)=\s*(.*)$/);if(l){let c=l[1].trim().toUpperCase(),u=l[2].trim();if(c==="XYDATA"||c==="XYPOINTS"){a=!0;continue}if(c==="END"){a=!1;continue}r[c]=u}continue}if(a&&i!==""){let l=i.split(/[\s,]+/).map(Number);if(l.length>=2&&!l.some(isNaN)){let c=l[0],u=parseFloat(r.FIRSTX??"0"),p=parseFloat(r.LASTX??"0"),f=parseInt(r.NPOINTS??"0",10);if(f>0&&l.length===2)o.push(l[0]),n.push(l[1]);else if(l.length>1){let m=f>1?(p-u)/(f-1):0;for(let d=1;d<l.length;d++)o.push(c+(d-1)*m),n.push(l[d])}}}}if(o.length===0)throw new Error("Failed to parse JCAMP-DX: no data found. Install jcampconverter for full format support.");return{id:`jcamp-${++$t}`,label:r.TITLE??"JCAMP Spectrum",x:new Float64Array(o),y:new Float64Array(n),xUnit:r.XUNITS??"cm\u207B\xB9",yUnit:r.YUNITS??"Absorbance",type:Nt(r),meta:r}}function Zr(e){switch(e.toLowerCase().split(".").pop()){case"dx":case"jdx":case"jcamp":return"jcamp";case"csv":case"tsv":case"txt":return"csv";case"json":return"json";default:return null}}function Ot(e=[]){let[t,r]=(0,I.useState)(e),[o,n]=(0,I.useState)(!1),[a,s]=(0,I.useState)(null),i=(0,I.useCallback)(async(m,d)=>{n(!0),s(null);try{let g;switch(d){case"jcamp":g=await Ne(m);break;case"csv":g=[Ue(m)];break;case"json":g=Ie(m);break}r(y=>[...y,...g])}catch(g){let y=g instanceof Error?g.message:"Failed to parse file";s(y)}finally{n(!1)}},[]),l=(0,I.useCallback)(async m=>{let d=Zr(m.name);if(!d){s(`Unsupported file format: ${m.name}`);return}let g=await m.text();await i(g,d)},[i]),c=(0,I.useCallback)(m=>{r(d=>[...d,m])},[]),u=(0,I.useCallback)(m=>{r(d=>d.filter(g=>g.id!==m))},[]),p=(0,I.useCallback)(m=>{r(d=>d.map(g=>g.id===m?{...g,visible:g.visible===!1}:g))},[]),f=(0,I.useCallback)(()=>{r([]),s(null)},[]);return{spectra:t,loading:o,error:a,loadFile:l,loadText:i,addSpectrum:c,removeSpectrum:u,toggleVisibility:p,clear:f}}var ce=require("react");var ot={solid:"",dashed:"8 4",dotted:"2 2","dash-dot":"8 4 2 4"};function Oe(e,t,r,o){let{width:n,height:a,background:s="#ffffff",title:i}=o,l=e.filter(c=>c.visible!==!1).map((c,u)=>{let p=c.color??F(u),f=c.lineStyle??"solid",m=c.lineWidth??1.5,d=ot[f]??"",g=Math.min(c.x.length,c.y.length);if(g<2)return"";let y=[];for(let b=0;b<g;b++){let x=t(c.x[b]).toFixed(2),S=r(c.y[b]).toFixed(2);y.push(`${b===0?"M":"L"}${x},${S}`)}return`<path d="${y.join(" ")}" fill="none" stroke="${p}" stroke-width="${m}"${d?` stroke-dasharray="${d}"`:""}/>
2
+ "use strict";var qe=Object.defineProperty;var gr=Object.getOwnPropertyDescriptor;var hr=Object.getOwnPropertyNames;var yr=Object.prototype.hasOwnProperty;var xr=(e,t)=>{for(var r in t)qe(e,r,{get:t[r],enumerable:!0})},Sr=(e,t,r,o)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of hr(t))!yr.call(e,n)&&n!==r&&qe(e,n,{get:()=>t[n],enumerable:!(o=gr(t,n))||o.enumerable});return e};var vr=e=>Sr(qe({},"__esModule",{value:!0}),e);var nn={};xr(nn,{AnnotationLayer:()=>Me,AxisLayer:()=>oe,Crosshair:()=>Re,DARK_THEME:()=>rt,DropZone:()=>Ee,ExportMenu:()=>Ht,KEYBOARD_SHORTCUTS:()=>Pt,LIGHT_THEME:()=>tt,LINE_DASH_PATTERNS:()=>st,Legend:()=>me,Minimap:()=>Ft,PeakMarkers:()=>Ce,RegionSelector:()=>ke,SPECTRUM_COLORS:()=>Se,SpectraView:()=>Lt,SpectrumCanvas:()=>ne,StackedView:()=>Le,Toolbar:()=>Ae,Tooltip:()=>Dt,addSpectra:()=>Qt,baselineRubberBand:()=>Xt,binarySearchClosest:()=>ce,computeXExtent:()=>ye,computeYExtent:()=>ee,correlationCoefficient:()=>tr,createXScale:()=>xe,createYScale:()=>te,derivative1st:()=>Kt,derivative2nd:()=>Jt,detectPeaks:()=>$e,differenceSpectrum:()=>qt,downloadSvg:()=>Ze,generateChartDescription:()=>Ie,generateSvg:()=>Be,getSpectrumColor:()=>P,getThemeColors:()=>W,interpolateToGrid:()=>nr,lttbDownsample:()=>we,normalizeArea:()=>Yt,normalizeMinMax:()=>Wt,normalizeSNV:()=>jt,parseCsv:()=>Ne,parseCsvMulti:()=>Ot,parseJcamp:()=>Ve,parseJson:()=>Oe,parseSpc:()=>or,prefersReducedMotion:()=>Et,residualSpectrum:()=>rr,scaleSpectrum:()=>er,smoothSavitzkyGolay:()=>Gt,snapToNearestSpectrum:()=>Te,useExport:()=>_t,useKeyboardNavigation:()=>Ue,usePeakPicking:()=>It,useRegionSelect:()=>Fe,useResizeObserver:()=>De,useSpectrumData:()=>Zt,useZoomPan:()=>ve});module.exports=vr(nn);var T=require("react");var Qe=require("d3-scale"),et=require("d3-array"),wr=.05;function ye(e){let t=1/0,r=-1/0;for(let o of e){if(o.visible===!1)continue;let[n,s]=(0,et.extent)(o.x);n<t&&(t=n),s>r&&(r=s)}return isFinite(t)?[t,r]:[0,1]}function ee(e){let t=1/0,r=-1/0;for(let s of e){if(s.visible===!1)continue;let[a,i]=(0,et.extent)(s.y);a<t&&(t=a),i>r&&(r=i)}if(!isFinite(t))return[0,1];let n=(r-t)*wr;return[t-n,r+n]}function xe(e,t,r,o){let n=t-r.left-r.right,s=o?[e[1],e[0]]:e;return(0,Qe.scaleLinear)().domain(s).range([0,n])}function te(e,t,r){let o=t-r.top-r.bottom;return(0,Qe.scaleLinear)().domain(e).range([o,0])}var Se=["#2563eb","#dc2626","#16a34a","#9333ea","#ea580c","#0891b2","#be185d","#854d0e","#4f46e5","#65a30d"],tt={background:"#ffffff",axisColor:"#374151",gridColor:"#e5e7eb",tickColor:"#6b7280",labelColor:"#111827",crosshairColor:"#9ca3af",regionFill:"rgba(37, 99, 235, 0.1)",regionStroke:"rgba(37, 99, 235, 0.4)",tooltipBg:"#ffffff",tooltipBorder:"#d1d5db",tooltipText:"#111827"},rt={background:"#111827",axisColor:"#d1d5db",gridColor:"#374151",tickColor:"#9ca3af",labelColor:"#f9fafb",crosshairColor:"#6b7280",regionFill:"rgba(96, 165, 250, 0.15)",regionStroke:"rgba(96, 165, 250, 0.5)",tooltipBg:"#1f2937",tooltipBorder:"#4b5563",tooltipText:"#f9fafb"};function P(e){return Se[e%Se.length]}function W(e){return e==="dark"?rt:tt}var L=require("react"),re=require("d3-zoom"),Y=require("d3-selection"),ln=require("d3-transition"),yt=1.5;function ve(e){let{plotWidth:t,plotHeight:r,xScale:o,yScale:n,scaleExtent:s=[1,50],enabled:a=!0,onViewChange:i}=e,l=(0,L.useRef)(null),c=(0,L.useRef)(null),u=(0,L.useRef)(i);u.current=i;let p=(0,L.useRef)(s);p.current=s;let[f,m]=(0,L.useState)(re.zoomIdentity),d=(0,L.useMemo)(()=>f.rescaleX(o.copy()),[f,o]),g=(0,L.useMemo)(()=>f.rescaleY(n.copy()),[f,n]);(0,L.useEffect)(()=>{let S=l.current;if(!S||!a)return;let v=(0,re.zoom)().scaleExtent(p.current).extent([[0,0],[t,r]]).translateExtent([[-1/0,-1/0],[1/0,1/0]]).on("zoom",x=>{let w=x.transform;if(m(w),u.current){let C=w.rescaleX(o.copy()),k=w.rescaleY(n.copy());u.current(C.domain(),k.domain())}});return c.current=v,(0,Y.select)(S).call(v),(0,Y.select)(S).on("dblclick.zoom",()=>{(0,Y.select)(S).transition().duration(300).call(v.transform,re.zoomIdentity)}),()=>{(0,Y.select)(S).on(".zoom",null)}},[t,r,a,o,n]);let h=(0,L.useCallback)(()=>{!l.current||!c.current||(0,Y.select)(l.current).transition().duration(300).call(c.current.transform,re.zoomIdentity)},[]),b=(0,L.useCallback)(()=>{!l.current||!c.current||(0,Y.select)(l.current).transition().duration(200).call(c.current.scaleBy,yt)},[]),y=(0,L.useCallback)(()=>{!l.current||!c.current||(0,Y.select)(l.current).transition().duration(200).call(c.current.scaleBy,1/yt)},[]);return{zoomRef:l,state:{transform:f,isZoomed:f.k!==1||f.x!==0||f.y!==0},zoomedXScale:d,zoomedYScale:g,resetZoom:h,zoomIn:b,zoomOut:y}}var $=require("react");function we(e,t,r,o,n,s,a){let i=o-r;if(i<=a){let f=[];for(let m=r;m<o;m++)f.push({px:n(e[m]),py:s(t[m]),index:m});return f}let l=[];l.push({px:n(e[r]),py:s(t[r]),index:r});let c=a-2,u=(i-2)/c,p=r;for(let f=0;f<c;f++){let m=r+1+Math.floor(f*u),d=r+1+Math.min(Math.floor((f+1)*u),i-2),g=d,h=r+1+Math.min(Math.floor((f+2)*u),i-2),b,y;if(f===c-1)b=n(e[o-1]),y=s(t[o-1]);else{b=0,y=0;let C=h-g;for(let k=g;k<h;k++)b+=n(e[k]),y+=s(t[k]);C>0&&(b/=C,y/=C)}let S=n(e[p]),v=s(t[p]),x=-1,w=m;for(let C=m;C<d;C++){let k=n(e[C]),M=s(t[C]),E=Math.abs((S-b)*(M-v)-(S-k)*(y-v));E>x&&(x=E,w=C)}l.push({px:n(e[w]),py:s(t[w]),index:w}),p=w}return l.push({px:n(e[o-1]),py:s(t[o-1]),index:o-1}),l}var Cr=1.5,kr={solid:[],dashed:[8,4],dotted:[2,2],"dash-dot":[8,4,2,4]},Rr=2e3;function Mr(e,t,r){e.clearRect(0,0,t,r)}function Tr(e,t,r,o,n,s,a){let{highlighted:i=!1,opacity:l=1}=a??{},c=Math.min(t.x.length,t.y.length);if(c<2)return;let u=t.color??P(r),p=t.lineWidth??Cr,f=i?p+1:p,m=kr[t.lineStyle??"solid"]??[],[d,g]=o.domain(),h=Math.min(d,g),b=Math.max(d,g),y=0,S=c;for(let x=0;x<c;x++)if(t.x[x]>=h||x<c-1&&t.x[x+1]>=h){y=Math.max(0,x-1);break}for(let x=c-1;x>=0;x--)if(t.x[x]<=b||x>0&&t.x[x-1]<=b){S=Math.min(c,x+2);break}let v=S-y;if(e.save(),e.beginPath(),e.strokeStyle=u,e.lineWidth=f,e.globalAlpha=l,e.lineJoin="round",e.setLineDash(m),v>Rr){let x=Math.max(Math.ceil(s*2),200),w=we(t.x,t.y,y,S,o,n,x);if(w.length>0){e.moveTo(w[0].px,w[0].py);for(let C=1;C<w.length;C++)e.lineTo(w[C].px,w[C].py)}}else{let x=!1;for(let w=y;w<S;w++){let C=o(t.x[w]),k=n(t.y[w]);x?e.lineTo(C,k):(e.moveTo(C,k),x=!0)}}e.stroke(),e.restore()}function xt(e,t,r,o,n,s,a){Mr(e,n,s),t.forEach((i,l)=>{i.visible!==!1&&Tr(e,i,l,r,o,n,{highlighted:i.id===a,opacity:a&&i.id!==a?.3:1})})}var St=require("react/jsx-runtime"),ne=(0,$.forwardRef)(function({spectra:t,xScale:r,yScale:o,width:n,height:s,highlightedId:a},i){let l=(0,$.useRef)(null),c=(0,$.useRef)(1);return(0,$.useImperativeHandle)(i,()=>l.current,[]),(0,$.useEffect)(()=>{let u=l.current;if(!u)return;let p=window.devicePixelRatio||1;c.current=p,u.width=n*p,u.height=s*p},[n,s]),(0,$.useEffect)(()=>{let u=l.current;if(!u)return;let p=u.getContext("2d");if(!p)return;let f=c.current;p.setTransform(f,0,0,f,0,0),xt(p,t,r,o,n,s,a)},[t,r,o,n,s,a]),(0,St.jsx)("canvas",{ref:l,style:{width:n,height:s,position:"absolute",top:0,left:0,pointerEvents:"none"}})});var A=require("react/jsx-runtime");function vt(e,t){let[r,o]=e.domain(),n=Math.min(r,o),a=(Math.max(r,o)-n)/(t-1);return Array.from({length:t},(i,l)=>n+l*a)}function wt(e){return Math.abs(e)>=1e3?Math.round(e).toString():Math.abs(e)>=1?e.toFixed(1):Math.abs(e)>=.01?e.toFixed(3):e.toExponential(1)}function oe({xScale:e,yScale:t,width:r,height:o,xLabel:n,yLabel:s,showGrid:a=!0,colors:i}){let l=vt(e,8),c=vt(t,6);return(0,A.jsxs)("g",{children:[a&&(0,A.jsxs)("g",{children:[l.map(u=>(0,A.jsx)("line",{x1:e(u),x2:e(u),y1:0,y2:o,stroke:i.gridColor,strokeWidth:.5},`xgrid-${u}`)),c.map(u=>(0,A.jsx)("line",{x1:0,x2:r,y1:t(u),y2:t(u),stroke:i.gridColor,strokeWidth:.5},`ygrid-${u}`))]}),(0,A.jsxs)("g",{transform:`translate(0, ${o})`,children:[(0,A.jsx)("line",{x1:0,x2:r,y1:0,y2:0,stroke:i.axisColor}),l.map(u=>(0,A.jsxs)("g",{transform:`translate(${e(u)}, 0)`,children:[(0,A.jsx)("line",{y1:0,y2:6,stroke:i.axisColor}),(0,A.jsx)("text",{y:20,textAnchor:"middle",fill:i.tickColor,fontSize:11,fontFamily:"system-ui, sans-serif",children:wt(u)})]},`xtick-${u}`)),n&&(0,A.jsx)("text",{x:r/2,y:42,textAnchor:"middle",fill:i.labelColor,fontSize:13,fontFamily:"system-ui, sans-serif",children:n})]}),(0,A.jsxs)("g",{children:[(0,A.jsx)("line",{x1:0,x2:0,y1:0,y2:o,stroke:i.axisColor}),c.map(u=>(0,A.jsxs)("g",{transform:`translate(0, ${t(u)})`,children:[(0,A.jsx)("line",{x1:-6,x2:0,stroke:i.axisColor}),(0,A.jsx)("text",{x:-10,textAnchor:"end",dominantBaseline:"middle",fill:i.tickColor,fontSize:11,fontFamily:"system-ui, sans-serif",children:wt(u)})]},`ytick-${u}`)),s&&(0,A.jsx)("text",{transform:`translate(-50, ${o/2}) rotate(-90)`,textAnchor:"middle",fill:i.labelColor,fontSize:13,fontFamily:"system-ui, sans-serif",children:s})]})]})}var ie=require("react/jsx-runtime");function Ce({peaks:e,xScale:t,yScale:r,colors:o,onPeakClick:n}){let[s,a]=t.domain(),i=Math.min(s,a),l=Math.max(s,a),c=e.filter(u=>u.x>=i&&u.x<=l);return(0,ie.jsx)("g",{className:"spectraview-peaks",children:c.map((u,p)=>{let f=t(u.x),m=r(u.y);return(0,ie.jsxs)("g",{transform:`translate(${f}, ${m})`,style:{cursor:n?"pointer":"default"},onClick:()=>n?.(u),children:[(0,ie.jsx)("polygon",{points:`0,-5 -5,${-5*2.5} 5,${-5*2.5}`,fill:o.labelColor,opacity:.8}),u.label&&(0,ie.jsx)("text",{y:-5*2.5-14,textAnchor:"middle",fill:o.labelColor,fontSize:10,fontFamily:"system-ui, sans-serif",fontWeight:500,children:u.label})]},`peak-${u.x}-${p}`)})})}var ae=require("react/jsx-runtime");function ke({regions:e,xScale:t,height:r,colors:o}){return(0,ae.jsx)("g",{className:"spectraview-regions",children:e.map((n,s)=>{let a=t(n.xStart),i=t(n.xEnd),l=Math.min(a,i),c=Math.abs(i-a);return(0,ae.jsxs)("g",{children:[(0,ae.jsx)("rect",{x:l,y:0,width:c,height:r,fill:n.color??o.regionFill,stroke:o.regionStroke,strokeWidth:1}),n.label&&(0,ae.jsx)("text",{x:l+c/2,y:12,textAnchor:"middle",fill:o.labelColor,fontSize:10,fontFamily:"system-ui, sans-serif",children:n.label})]},`region-${s}`)})})}var z=require("react/jsx-runtime");function Re({position:e,width:t,height:r,colors:o,snapPoint:n}){return e?(0,z.jsxs)("g",{className:"spectraview-crosshair",pointerEvents:"none",children:[(0,z.jsx)("line",{x1:e.px,x2:e.px,y1:0,y2:r,stroke:o.crosshairColor,strokeWidth:1,strokeDasharray:"4 4"}),(0,z.jsx)("line",{x1:0,x2:t,y1:e.py,y2:e.py,stroke:o.crosshairColor,strokeWidth:1,strokeDasharray:"4 4"}),n&&(0,z.jsx)("circle",{cx:n.px,cy:n.py,r:4,fill:n.color??o.crosshairColor,stroke:o.background,strokeWidth:1.5}),(0,z.jsxs)("g",{transform:`translate(${Math.min(e.px+10,t-100)}, ${Math.max(e.py-10,20)})`,children:[(0,z.jsx)("rect",{x:0,y:-14,width:90,height:18,rx:3,fill:o.tooltipBg,stroke:o.tooltipBorder,strokeWidth:.5,opacity:.9}),(0,z.jsxs)("text",{x:5,y:0,fill:o.tooltipText,fontSize:10,fontFamily:"monospace",children:[Ct(n?.dataX??e.dataX),","," ",Ct(n?.dataY??e.dataY)]})]})]}):null}function Ct(e){return Math.abs(e)>=100?Math.round(e).toString():Math.abs(e)>=1?e.toFixed(1):e.toFixed(4)}var j=require("react/jsx-runtime");function Me({annotations:e,xScale:t,yScale:r,colors:o}){return e.length===0?null:(0,j.jsx)("g",{className:"spectraview-annotations",pointerEvents:"none",children:e.map(n=>{let s=t(n.x),a=r(n.y),[i,l]=n.offset??[0,-20],c=s+i,u=a+l,p=n.fontSize??11,f=n.color??o.tickColor,m=n.showAnchorLine!==!1;return(0,j.jsxs)("g",{children:[m&&(0,j.jsx)("line",{x1:s,y1:a,x2:c,y2:u,stroke:f,strokeWidth:.75,strokeDasharray:"3 2",opacity:.6}),(0,j.jsx)("circle",{cx:s,cy:a,r:2.5,fill:f,opacity:.8}),(0,j.jsx)("text",{x:c,y:u,fill:o.background,fontSize:p,fontFamily:"system-ui, sans-serif",textAnchor:"middle",dominantBaseline:"auto",stroke:o.background,strokeWidth:3,strokeLinejoin:"round",children:n.text}),(0,j.jsx)("text",{x:c,y:u,fill:f,fontSize:p,fontFamily:"system-ui, sans-serif",textAnchor:"middle",dominantBaseline:"auto",children:n.text})]},n.id)})})}function ce(e,t,r){if(r===0)return-1;if(r===1)return 0;let o=e[r-1]>=e[0],n=0,s=r-1;for(;n<s-1;){let l=n+s>>>1,c=e[l];o?c<=t?n=l:s=l:c>=t?n=l:s=l}let a=Math.abs(e[n]-t),i=Math.abs(e[s]-t);return a<=i?n:s}function Te(e,t,r,o,n){let s=null;for(let a of e){if(a.visible===!1)continue;let i=Math.min(a.x.length,a.y.length);if(i<2)continue;let l=ce(a.x,t,i);if(l<0)continue;let c=a.x[l],u=a.y[l],p=Math.abs(o(c)-o(t)),f=Math.abs(n(u)-r),m=Math.sqrt(p*p+f*f);(!s||m<s.distance)&&(s={spectrumId:a.id,index:l,x:c,y:u,distance:m})}return s}var kt=require("react"),se=require("react/jsx-runtime"),nt=e=>({display:"inline-flex",alignItems:"center",justifyContent:"center",width:28,height:28,border:`1px solid ${e==="dark"?"#4b5563":"#d1d5db"}`,borderRadius:4,background:e==="dark"?"#1f2937":"#ffffff",color:e==="dark"?"#d1d5db":"#374151",fontSize:14,cursor:"pointer",padding:0,lineHeight:1}),Ar=e=>({display:"flex",gap:4,padding:"4px 0",borderBottom:`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`}),Ae=(0,kt.memo)(function({onZoomIn:t,onZoomOut:r,onReset:o,isZoomed:n,theme:s}){return(0,se.jsxs)("div",{style:Ar(s),className:"spectraview-toolbar",children:[(0,se.jsx)("button",{type:"button",style:nt(s),onClick:t,title:"Zoom in","aria-label":"Zoom in",children:"+"}),(0,se.jsx)("button",{type:"button",style:nt(s),onClick:r,title:"Zoom out","aria-label":"Zoom out",children:"\u2212"}),(0,se.jsx)("button",{type:"button",style:{...nt(s),opacity:n?1:.4},onClick:o,disabled:!n,title:"Reset zoom","aria-label":"Reset zoom",children:"\u21BA"})]})});var Rt=require("react");var le=require("react/jsx-runtime"),Er=(e,t)=>({display:"flex",flexDirection:t==="left"||t==="right"?"column":"row",flexWrap:"wrap",gap:6,padding:"4px 8px",fontSize:12,fontFamily:"system-ui, sans-serif",borderTop:t==="bottom"?`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`:void 0,borderBottom:t==="top"?`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`:void 0,borderLeft:t==="right"?`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`:void 0,borderRight:t==="left"?`1px solid ${e==="dark"?"#374151":"#e5e7eb"}`:void 0}),Pr=(e,t,r)=>({display:"inline-flex",alignItems:"center",gap:4,cursor:"pointer",opacity:t?.4:1,fontWeight:r?600:400,color:e==="dark"?"#e5e7eb":"#374151",userSelect:"none",padding:"2px 4px",borderRadius:3,background:r?e==="dark"?"rgba(255,255,255,0.08)":"rgba(0,0,0,0.04)":"transparent",transition:"background 0.15s, opacity 0.15s"}),Lr=(e,t)=>({width:12,height:3,borderRadius:1,background:e,opacity:t?.4:1,flexShrink:0}),me=(0,Rt.memo)(function({spectra:t,theme:r,position:o,onToggleVisibility:n,onHighlight:s,highlightedId:a}){return t.length<=1?null:(0,le.jsx)("div",{className:"spectraview-legend",style:Er(r,o),role:"list","aria-label":"Spectrum legend",children:t.map((i,l)=>{let c=i.color??P(l),u=i.visible===!1,p=a===i.id;return(0,le.jsxs)("div",{role:"listitem",style:Pr(r,u,p),onClick:()=>n?.(i.id),onMouseEnter:()=>s?.(i.id),onMouseLeave:()=>s?.(null),title:u?`Show ${i.label}`:`Hide ${i.label}`,children:[(0,le.jsx)("span",{style:Lr(c,u)}),(0,le.jsx)("span",{style:{textDecoration:u?"line-through":"none",maxWidth:120,overflow:"hidden",textOverflow:"ellipsis",whiteSpace:"nowrap"},children:i.label})]},i.id)})})});var Q=require("react"),Pe=require("react/jsx-runtime");function Ee({enabled:e,theme:t,width:r,height:o,onDrop:n,children:s}){let[a,i]=(0,Q.useState)(!1),l={current:0},c=(0,Q.useCallback)(m=>{e&&(m.preventDefault(),l.current++,i(!0))},[e]),u=(0,Q.useCallback)(m=>{e&&(m.preventDefault(),l.current--,l.current<=0&&(l.current=0,i(!1)))},[e]),p=(0,Q.useCallback)(m=>{e&&(m.preventDefault(),m.dataTransfer.dropEffect="copy")},[e]),f=(0,Q.useCallback)(m=>{if(!e)return;m.preventDefault(),l.current=0,i(!1);let d=Array.from(m.dataTransfer.files);d.length>0&&n?.(d)},[e,n]);return(0,Pe.jsxs)("div",{style:{position:"relative",width:r,height:o},onDragEnter:c,onDragLeave:u,onDragOver:p,onDrop:f,children:[s,a&&(0,Pe.jsx)("div",{"data-testid":"dropzone-overlay",style:{position:"absolute",inset:0,display:"flex",alignItems:"center",justifyContent:"center",background:t==="dark"?"rgba(30, 58, 138, 0.6)":"rgba(59, 130, 246, 0.15)",border:`2px dashed ${t==="dark"?"#60a5fa":"#3b82f6"}`,borderRadius:4,zIndex:100,pointerEvents:"none",fontSize:14,fontFamily:"system-ui, sans-serif",color:t==="dark"?"#93c5fd":"#1d4ed8",fontWeight:500},children:"Drop spectrum files here"})]})}var Tt=require("react");var V=require("react/jsx-runtime"),Mt=8;function Le({spectra:e,xScale:t,plotWidth:r,plotHeight:o,margin:n,theme:s,showGrid:a,xLabel:i,yLabel:l}){let c=e.filter(d=>d.visible!==!1),u=(0,Tt.useMemo)(()=>W(s),[s]),p=c.length,f=(p-1)*Mt,m=Math.max(40,Math.floor((o-f)/Math.max(p,1)));return(0,V.jsx)("g",{className:"spectraview-stacked",children:c.map((d,g)=>{let h=g*(m+Mt),b=ee([d]),y=te(b,m+n.top+n.bottom,{...n,top:0,bottom:0}),S=d.color??P(g),v={...d,color:S};return(0,V.jsxs)("g",{transform:`translate(0, ${h})`,children:[(0,V.jsx)("rect",{x:0,y:0,width:r,height:m,fill:"transparent",stroke:u.gridColor,strokeWidth:.5,rx:2}),(0,V.jsx)(oe,{xScale:t,yScale:y,width:r,height:m,xLabel:g===p-1?i:"",yLabel:l,showGrid:a,colors:u}),(0,V.jsx)("text",{x:4,y:14,fill:S,fontSize:11,fontFamily:"system-ui, sans-serif",fontWeight:500,children:d.label}),(0,V.jsx)("foreignObject",{x:0,y:0,width:r,height:m,children:(0,V.jsx)(ne,{spectra:[v],xScale:t,yScale:y,width:r,height:m})})]},d.id)})})}var G=require("react");function Fe(e){let{enabled:t,xScale:r,onRegionSelect:o}=e,[n,s]=(0,G.useState)(null),a=(0,G.useRef)(null),i=(0,G.useCallback)(u=>{if(!t||!u.shiftKey)return;u.preventDefault();let p=u.currentTarget.getBoundingClientRect(),f=u.clientX-p.left,m=r.invert(f);a.current=m,s({xStart:m,xEnd:m})},[t,r]),l=(0,G.useCallback)(u=>{if(a.current===null)return;let p=u.currentTarget.getBoundingClientRect(),f=u.clientX-p.left,m=r.invert(f),d=a.current;s({xStart:Math.min(d,m),xEnd:Math.max(d,m)})},[r]),c=(0,G.useCallback)(()=>{if(a.current===null||!n)return;Math.abs(n.xEnd-n.xStart)>0&&o?.(n),a.current=null,s(null)},[n,o]);return{pendingRegion:n,handleMouseDown:i,handleMouseMove:l,handleMouseUp:c}}var B=require("react");function De(){let[e,t]=(0,B.useState)(null),r=(0,B.useRef)(null),o=(0,B.useRef)(null),n=(0,B.useCallback)(s=>{if(r.current&&(r.current.disconnect(),r.current=null),o.current=s,!s)return;let a=new ResizeObserver(c=>{let u=c[0];if(!u)return;let{width:p,height:f}=u.contentRect;t({width:Math.round(p),height:Math.round(f)})});a.observe(s),r.current=a;let{width:i,height:l}=s.getBoundingClientRect();t({width:Math.round(i),height:Math.round(l)})},[]);return(0,B.useEffect)(()=>()=>{r.current?.disconnect()},[]),{ref:n,size:e}}var At=require("react");function Ue(e){let{onZoomIn:t,onZoomOut:r,onReset:o,enabled:n=!0}=e;return(0,At.useCallback)(a=>{if(n)switch(a.key){case"+":case"=":a.preventDefault(),t();break;case"-":a.preventDefault(),r();break;case"Escape":a.preventDefault(),o();break}},[n,t,r,o])}function Et(){return typeof window>"u"?!1:window.matchMedia("(prefers-reduced-motion: reduce)").matches}function Ie(e,t,r){return e===0?"Empty spectrum viewer":`Interactive spectrum viewer showing ${e} ${e===1?"spectrum":"spectra"}. X-axis: ${t}. Y-axis: ${r}. Use arrow keys to pan, +/- to zoom, Escape to reset.`}var Pt={PAN_LEFT:"ArrowLeft",PAN_RIGHT:"ArrowRight",PAN_UP:"ArrowUp",PAN_DOWN:"ArrowDown",ZOOM_IN:"+",ZOOM_IN_ALT:"=",ZOOM_OUT:"-",RESET:"Escape",NEXT_PEAK:"Tab",PREV_PEAK:"Shift+Tab"};var R=require("react/jsx-runtime"),Fr={top:20,right:20,bottom:50,left:65},Dr=800,Ur=400;function Ir(e){return{width:e.width??Dr,height:e.height??Ur,reverseX:e.reverseX??!1,showGrid:e.showGrid??!0,showCrosshair:e.showCrosshair??!0,showToolbar:e.showToolbar??!0,showLegend:e.showLegend??!0,legendPosition:e.legendPosition??"bottom",displayMode:e.displayMode??"overlay",margin:{...Fr,...e.margin},theme:e.theme??"light",responsive:e.responsive??!1,enableDragDrop:e.enableDragDrop??!1,enableRegionSelect:e.enableRegionSelect??!1}}function $r(e,t,r){let o=e[0];return{xLabel:t??o?.xUnit??"x",yLabel:r??o?.yUnit??"y"}}function Lt(e){let{spectra:t,peaks:r=[],regions:o=[],annotations:n=[],onPeakClick:s,onViewChange:a,onCrosshairMove:i,onToggleVisibility:l,onFileDrop:c,onRegionSelect:u,canvasRef:p,snapCrosshair:f=!0}=e,{ref:m,size:d}=De(),h=`spectraview-clip-${(0,T.useId)().replace(/:/g,"")}`,b=(0,T.useMemo)(()=>Ir(e),[e.width,e.height,e.reverseX,e.showGrid,e.showCrosshair,e.showToolbar,e.showLegend,e.legendPosition,e.displayMode,e.margin,e.theme,e.responsive,e.enableDragDrop,e.enableRegionSelect]),y=b.responsive&&d?d.width:b.width,{height:S,margin:v,reverseX:x,theme:w}=b,C=y-v.left-v.right,k=S-v.top-v.bottom,M=(0,T.useMemo)(()=>W(w),[w]),E=(0,T.useMemo)(()=>$r(t,e.xLabel,e.yLabel),[t,e.xLabel,e.yLabel]),D=(0,T.useMemo)(()=>ye(t),[t]),U=(0,T.useMemo)(()=>ee(t),[t]),We=(0,T.useMemo)(()=>xe(D,y,v,x),[D,y,v,x]),J=(0,T.useMemo)(()=>te(U,S,v),[U,S,v]),q=(0,T.useRef)(a);q.current=a;let ir=(0,T.useMemo)(()=>(X,ge)=>{q.current?.({xDomain:X,yDomain:ge})},[]),{zoomRef:lt,state:ar,zoomedXScale:F,zoomedYScale:H,resetZoom:ct,zoomIn:mt,zoomOut:ut}=ve({plotWidth:C,plotHeight:k,xScale:We,yScale:J,onViewChange:a?ir:void 0}),{pendingRegion:de,handleMouseDown:sr,handleMouseMove:lr,handleMouseUp:cr}=Fe({enabled:b.enableRegionSelect,xScale:F,onRegionSelect:u}),[Ye,pt]=(0,T.useState)(null),[mr,ft]=(0,T.useState)(null),[ur,je]=(0,T.useState)(null),be=(0,T.useRef)(i);be.current=i;let dt=(0,T.useCallback)(X=>{if(!b.showCrosshair)return;let ge=X.currentTarget.getBoundingClientRect(),gt=X.clientX-ge.left,Ke=X.clientY-ge.top,he=F.invert(gt),Je=H.invert(Ke);if(ft({px:gt,py:Ke,dataX:he,dataY:Je}),f&&t.length>0){let O=Te(t,he,Ke,F,H);if(O&&O.distance<50){let ht=t.findIndex(br=>br.id===O.spectrumId);je({px:F(O.x),py:H(O.y),dataX:O.x,dataY:O.y,color:t[ht]?.color??P(ht)}),be.current?.(O.x,O.y)}else je(null),be.current?.(he,Je)}else be.current?.(he,Je)},[F,H,b.showCrosshair,f,t]),bt=(0,T.useCallback)(()=>{ft(null),je(null)},[]),pr=Ue({onZoomIn:mt,onZoomOut:ut,onReset:ct}),fr=(0,T.useMemo)(()=>Ie(t.length,E.xLabel,E.yLabel),[t.length,E.xLabel,E.yLabel]),dr=b.displayMode==="stacked";if(t.length===0)return(0,R.jsx)("div",{ref:b.responsive?m:void 0,style:{width:b.responsive?"100%":y,height:S,display:"flex",alignItems:"center",justifyContent:"center",border:`1px dashed ${M.gridColor}`,borderRadius:8,color:M.tickColor,fontFamily:"system-ui, sans-serif",fontSize:14},className:e.className,children:"No spectra loaded"});let Ge=b.showToolbar?37:0;return(0,R.jsxs)("div",{ref:b.responsive?m:void 0,style:{width:b.responsive?"100%":y,background:M.background,borderRadius:4,overflow:"hidden"},className:e.className,role:"img","aria-label":fr,tabIndex:0,onKeyDown:pr,children:[b.showToolbar&&(0,R.jsx)(Ae,{onZoomIn:mt,onZoomOut:ut,onReset:ct,isZoomed:ar.isZoomed,theme:w}),b.showLegend&&b.legendPosition==="top"&&(0,R.jsx)(me,{spectra:t,theme:w,position:"top",onToggleVisibility:l,onHighlight:pt,highlightedId:Ye}),(0,R.jsx)(Ee,{enabled:b.enableDragDrop,theme:w,width:y,height:S-Ge,onDrop:c,children:dr?(0,R.jsx)("svg",{width:y,height:S-Ge,style:{position:"absolute",top:0,left:0},children:(0,R.jsxs)("g",{transform:`translate(${v.left}, ${v.top})`,children:[(0,R.jsx)(Le,{spectra:t,xScale:F,plotWidth:C,plotHeight:k,margin:v,theme:w,showGrid:b.showGrid,xLabel:E.xLabel,yLabel:E.yLabel}),(0,R.jsx)("rect",{ref:lt,x:0,y:0,width:C,height:k,fill:"transparent",style:{cursor:"grab"},onMouseMove:dt,onMouseLeave:bt})]})}):(0,R.jsxs)(R.Fragment,{children:[(0,R.jsx)("div",{style:{position:"absolute",top:v.top,left:v.left,width:C,height:k,overflow:"hidden"},children:(0,R.jsx)(ne,{ref:p,spectra:t,xScale:F,yScale:H,width:C,height:k,highlightedId:Ye??void 0})}),(0,R.jsx)("svg",{width:y,height:S-Ge,style:{position:"absolute",top:0,left:0},children:(0,R.jsxs)("g",{transform:`translate(${v.left}, ${v.top})`,children:[(0,R.jsx)(oe,{xScale:F,yScale:H,width:C,height:k,xLabel:E.xLabel,yLabel:E.yLabel,showGrid:b.showGrid,colors:M}),(0,R.jsx)("defs",{children:(0,R.jsx)("clipPath",{id:h,children:(0,R.jsx)("rect",{x:0,y:0,width:C,height:k})})}),(0,R.jsxs)("g",{clipPath:`url(#${h})`,children:[o.length>0&&(0,R.jsx)(ke,{regions:o,xScale:F,height:k,colors:M}),r.length>0&&(0,R.jsx)(Ce,{peaks:r,xScale:F,yScale:H,colors:M,onPeakClick:s})]}),n.length>0&&(0,R.jsx)(Me,{annotations:n,xScale:F,yScale:H,colors:M}),b.showCrosshair&&(0,R.jsx)(Re,{position:mr,width:C,height:k,colors:M,snapPoint:ur}),de&&(0,R.jsx)("rect",{x:F(de.xStart),y:0,width:Math.abs(F(de.xEnd)-F(de.xStart)),height:k,fill:M.regionFill,stroke:M.regionStroke,strokeWidth:1,pointerEvents:"none"}),(0,R.jsx)("rect",{ref:lt,x:0,y:0,width:C,height:k,fill:"transparent",style:{cursor:b.showCrosshair?"crosshair":"grab"},onMouseDown:sr,onMouseMove:X=>{dt(X),lr(X)},onMouseUp:cr,onMouseLeave:bt})]})})]})}),b.showLegend&&b.legendPosition==="bottom"&&(0,R.jsx)(me,{spectra:t,theme:w,position:"bottom",onToggleVisibility:l,onHighlight:pt,highlightedId:Ye})]})}var N=require("react"),ot=require("d3-scale");var K=require("react/jsx-runtime"),Ft=(0,N.memo)(function({spectra:t,xExtent:r,yExtent:o,visibleXDomain:n,width:s=200,height:a=50,theme:i="light",isZoomed:l=!1}){let c=(0,N.useRef)(null),u=(0,N.useMemo)(()=>W(i),[i]),p=(0,N.useMemo)(()=>(0,ot.scaleLinear)().domain(r).range([0,s]),[r,s]),f=(0,N.useMemo)(()=>(0,ot.scaleLinear)().domain(o).range([a-2,2]),[o,a]);(0,N.useEffect)(()=>{let h=c.current?.getContext("2d");if(h){h.clearRect(0,0,s,a);for(let b=0;b<t.length;b++){let y=t[b];if(y.visible===!1)continue;let S=Math.min(y.x.length,y.y.length);if(S<2)continue;let v=y.color??P(b);h.beginPath(),h.strokeStyle=v,h.lineWidth=1,h.globalAlpha=.7;let x=Math.max(1,Math.floor(S/s)),w=!1;for(let C=0;C<S;C+=x){let k=p(y.x[C]),M=f(y.y[C]);w?h.lineTo(k,M):(h.moveTo(k,M),w=!0)}h.stroke()}}},[t,p,f,s,a]);let m=p(Math.min(n[0],n[1])),d=p(Math.max(n[0],n[1])),g=Math.max(d-m,2);return(0,K.jsxs)("div",{className:"spectraview-minimap",style:{position:"relative",width:s,height:a,border:`1px solid ${u.gridColor}`,borderRadius:3,overflow:"hidden",background:u.background},children:[(0,K.jsx)("canvas",{ref:c,width:s,height:a,style:{position:"absolute",top:0,left:0}}),l&&(0,K.jsxs)("svg",{width:s,height:a,style:{position:"absolute",top:0,left:0},children:[(0,K.jsx)("rect",{x:0,y:0,width:m,height:a,fill:u.background,opacity:.6}),(0,K.jsx)("rect",{x:m+g,y:0,width:s-m-g,height:a,fill:u.background,opacity:.6}),(0,K.jsx)("rect",{x:m,y:0,width:g,height:a,fill:"none",stroke:i==="dark"?"#60a5fa":"#3b82f6",strokeWidth:1.5,rx:1})]})]})});var ue=require("react");var Z=require("react/jsx-runtime");function it(e,t){switch(t){case"fixed2":return e.toFixed(2);case"fixed4":return e.toFixed(4);case"scientific":return e.toExponential(2);default:return Math.abs(e)>=100?Math.round(e).toString():Math.abs(e)>=1?e.toFixed(2):Math.abs(e)>=.01?e.toFixed(4):e.toExponential(2)}}var Dt=(0,ue.memo)(function({data:t,spectra:r,peaks:o=[],plotWidth:n,plotHeight:s,colors:a,numberFormat:i="auto"}){if(!t)return null;let l=(0,ue.useMemo)(()=>t?r.filter(b=>b.visible!==!1).map((b,y)=>{let S=Math.min(b.x.length,b.y.length);if(S<1)return null;let v=ce(b.x,t.dataX,S);return v<0?null:{label:b.label,color:b.color??P(y),value:b.y[v],x:b.x[v]}}).filter(Boolean):[],[t?.dataX,r]),c=(0,ue.useMemo)(()=>{if(!t||o.length===0)return null;let b=null,y=1/0;for(let S of o){let v=Math.abs(S.x-t.dataX);v<y&&(y=v,b=S)}return b},[t?.dataX,o]),u=16,p=18,f=c?u:0,m=p+l.length*u+f+8,d=160,g=t.px+15,h=t.py-m/2;return g+d>n&&(g=t.px-d-15),h<0&&(h=4),h+m>s&&(h=s-m-4),(0,Z.jsxs)("g",{className:"spectraview-tooltip",transform:`translate(${g}, ${h})`,pointerEvents:"none",children:[(0,Z.jsx)("rect",{x:0,y:0,width:d,height:m,rx:4,fill:a.tooltipBg,stroke:a.tooltipBorder,strokeWidth:.5,opacity:.95}),(0,Z.jsxs)("text",{x:8,y:14,fill:a.tooltipText,fontSize:10,fontFamily:"monospace",fontWeight:600,children:["x = ",it(t.dataX,i)]}),l.map((b,y)=>(0,Z.jsxs)("g",{transform:`translate(0, ${p+y*u})`,children:[(0,Z.jsx)("circle",{cx:12,cy:8,r:3,fill:b.color}),(0,Z.jsxs)("text",{x:20,y:11,fill:a.tooltipText,fontSize:9,fontFamily:"monospace",children:[b.label.slice(0,10),": ",it(b.value,i)]})]},b.label)),c&&(0,Z.jsxs)("text",{x:8,y:p+l.length*u+12,fill:a.labelColor,fontSize:9,fontFamily:"monospace",fontStyle:"italic",children:["Peak: ",c.label??it(c.x,i)]})]})});var Ut=require("react");function $e(e,t,r={}){let{prominence:o=.01,minDistance:n=5,maxPeaks:s}=r;if(e.length<3||t.length<3)return[];let a=1/0,i=-1/0;for(let m=0;m<t.length;m++)t[m]<a&&(a=t[m]),t[m]>i&&(i=t[m]);let l=i-a;if(l===0)return[];let c=o*l,u=[];for(let m=1;m<t.length-1;m++)if(t[m]>t[m-1]&&t[m]>t[m+1]){let d=Nr(t,m),g=Or(t,m),h=t[m]-Math.max(d,g);h>=c&&u.push({index:m,prom:h})}u.sort((m,d)=>d.prom-m.prom);let p=[];for(let m of u)p.some(g=>Math.abs(g.index-m.index)<n)||p.push(m);return(s?p.slice(0,s):p).map(m=>({x:e[m.index],y:t[m.index],label:zr(e[m.index])})).sort((m,d)=>m.x-d.x)}function Nr(e,t){let r=e[t];for(let o=t-1;o>=0&&!(e[o]>e[t]);o--)e[o]<r&&(r=e[o]);return r}function Or(e,t){let r=e[t];for(let o=t+1;o<e.length&&!(e[o]>e[t]);o++)e[o]<r&&(r=e[o]);return r}function zr(e){return Math.round(e).toString()}function It(e,t={}){let{enabled:r=!0,spectrumIds:o,prominence:n,minDistance:s,maxPeaks:a}=t;return(0,Ut.useMemo)(()=>{if(!r)return[];let i=o?e.filter(c=>o.includes(c.id)):e,l=[];for(let c of i){if(c.visible===!1)continue;let u=$e(c.x,c.y,{prominence:n,minDistance:s,maxPeaks:a});for(let p of u)l.push({...p,spectrumId:c.id})}return l},[e,r,o,n,s,a])}var I=require("react");var $t=0,Vr=[" ",",",";"," "];function Nt(e){let t=e.trim().split(/\r?\n/).slice(0,5),r=",",o=0;for(let n of Vr){let s=t.map(i=>i.split(n).length-1),a=Math.min(...s);a>0&&a>=o&&(s.every(l=>l===s[0])||a>o)&&(o=a,r=n)}return r}function Ne(e,t={}){let{xColumn:r=0,yColumn:o=1,hasHeader:n=!0,label:s="CSV Spectrum"}=t,a=t.delimiter??Nt(e),i=e.trim().split(/\r?\n/);if(i.length<2)throw new Error("CSV file must contain at least 2 lines");let l=s,c=0;if(n){let f=i[0].split(a).map(m=>m.trim());!t.label&&f[o]&&(l=f[o]),c=1}let u=[],p=[];for(let f=c;f<i.length;f++){let m=i[f].trim();if(m===""||m.startsWith("#"))continue;let d=m.split(a),g=parseFloat(d[r]),h=parseFloat(d[o]);!isNaN(g)&&!isNaN(h)&&(u.push(g),p.push(h))}if(u.length===0)throw new Error("No valid numeric data found in CSV");return{id:`csv-${++$t}`,label:l,x:new Float64Array(u),y:new Float64Array(p)}}function Ot(e,t={}){let{hasHeader:r=!0,label:o}=t,n=t.delimiter??Nt(e),s=e.trim().split(/\r?\n/);if(s.length<2)throw new Error("CSV file must contain at least 2 lines");let i=s[r?1:0].split(n).length;if(i<2)throw new Error("CSV must have at least 2 columns (x + y)");let l,c=0;r&&(l=s[0].split(n).map(m=>m.trim()),c=1);let u=[],p=Array.from({length:i-1},()=>[]);for(let m=c;m<s.length;m++){let d=s[m].trim();if(d===""||d.startsWith("#"))continue;let g=d.split(n),h=parseFloat(g[0]);if(!isNaN(h)){u.push(h);for(let b=1;b<i;b++){let y=parseFloat(g[b]);p[b-1].push(isNaN(y)?0:y)}}}let f=new Float64Array(u);return p.map((m,d)=>({id:`csv-${++$t}`,label:o??l?.[d+1]??`Spectrum ${d+1}`,x:f,y:new Float64Array(m)}))}var Br=0;function Oe(e){let t;try{t=JSON.parse(e)}catch{throw new Error("Invalid JSON: failed to parse input")}if(Array.isArray(t))return t.map((r,o)=>at(r,o));if(typeof t=="object"&&t!==null){let r=t;return Array.isArray(r.spectra)?r.spectra.map((o,n)=>at(o,n)):[at(t,0)]}throw new Error("Invalid JSON structure: expected an object or array")}function at(e,t){let r=e.x??e.wavenumbers??e.wavelengths;if(!r||!Array.isArray(r))throw new Error(`Spectrum ${t}: missing x-axis data (expected "x", "wavenumbers", or "wavelengths")`);let o=e.y??e.intensities??e.absorbance;if(!o||!Array.isArray(o))throw new Error(`Spectrum ${t}: missing y-axis data (expected "y", "intensities", or "absorbance")`);if(r.length!==o.length)throw new Error(`Spectrum ${t}: x and y arrays must have the same length (got ${r.length} and ${o.length})`);let n=e.label??e.title??e.name??`Spectrum ${t+1}`;return{id:`json-${++Br}`,label:n,x:new Float64Array(r),y:new Float64Array(o),xUnit:e.xUnit,yUnit:e.yUnit,type:e.type,meta:e.meta}}var Vt=0,ze=null,zt=!1;async function Zr(){if(zt)return ze;zt=!0;try{ze=await import("jcampconverter")}catch{ze=null}return ze}function Bt(e){let t=(e["DATA TYPE"]??e.DATATYPE??"").toLowerCase();return t.includes("infrared")||t.includes("ir")?"IR":t.includes("raman")?"Raman":t.includes("nir")||t.includes("near")?"NIR":t.includes("uv")||t.includes("vis")?"UV-Vis":t.includes("fluor")?"fluorescence":"other"}async function Ve(e){let t=await Zr();return t?_r(e,t):[Hr(e)]}function _r(e,t){return t.convert(e,{keepRecordsRegExp:/.*/}).flatten.map((o,n)=>{let s=o.spectra?.[0]?.data?.[0];if(!s)throw new Error(`JCAMP block ${n}: no spectral data found`);return{id:`jcamp-${++Vt}`,label:o.info?.TITLE??`Spectrum ${n+1}`,x:new Float64Array(s.x),y:new Float64Array(s.y),xUnit:o.info?.XUNITS??"cm\u207B\xB9",yUnit:o.info?.YUNITS??"Absorbance",type:Bt(o.info),meta:o.info}})}function Hr(e){let t=e.split(/\r?\n/),r={},o=[],n=[],s=!1;for(let a of t){let i=a.trim();if(i.startsWith("##")){let l=i.match(/^##(.+?)=\s*(.*)$/);if(l){let c=l[1].trim().toUpperCase(),u=l[2].trim();if(c==="XYDATA"||c==="XYPOINTS"){s=!0;continue}if(c==="END"){s=!1;continue}r[c]=u}continue}if(s&&i!==""){let l=i.split(/[\s,]+/).map(Number);if(l.length>=2&&!l.some(isNaN)){let c=l[0],u=parseFloat(r.FIRSTX??"0"),p=parseFloat(r.LASTX??"0"),f=parseInt(r.NPOINTS??"0",10);if(f>0&&l.length===2)o.push(l[0]),n.push(l[1]);else if(l.length>1){let m=f>1?(p-u)/(f-1):0;for(let d=1;d<l.length;d++)o.push(c+(d-1)*m),n.push(l[d])}}}}if(o.length===0)throw new Error("Failed to parse JCAMP-DX: no data found. Install jcampconverter for full format support.");return{id:`jcamp-${++Vt}`,label:r.TITLE??"JCAMP Spectrum",x:new Float64Array(o),y:new Float64Array(n),xUnit:r.XUNITS??"cm\u207B\xB9",yUnit:r.YUNITS??"Absorbance",type:Bt(r),meta:r}}function Xr(e){switch(e.toLowerCase().split(".").pop()){case"dx":case"jdx":case"jcamp":return"jcamp";case"csv":case"tsv":case"txt":return"csv";case"json":return"json";default:return null}}function Zt(e=[]){let[t,r]=(0,I.useState)(e),[o,n]=(0,I.useState)(!1),[s,a]=(0,I.useState)(null),i=(0,I.useCallback)(async(m,d)=>{n(!0),a(null);try{let g;switch(d){case"jcamp":g=await Ve(m);break;case"csv":g=[Ne(m)];break;case"json":g=Oe(m);break}r(h=>[...h,...g])}catch(g){let h=g instanceof Error?g.message:"Failed to parse file";a(h)}finally{n(!1)}},[]),l=(0,I.useCallback)(async m=>{let d=Xr(m.name);if(!d){a(`Unsupported file format: ${m.name}`);return}let g=await m.text();await i(g,d)},[i]),c=(0,I.useCallback)(m=>{r(d=>[...d,m])},[]),u=(0,I.useCallback)(m=>{r(d=>d.filter(g=>g.id!==m))},[]),p=(0,I.useCallback)(m=>{r(d=>d.map(g=>g.id===m?{...g,visible:g.visible===!1}:g))},[]),f=(0,I.useCallback)(()=>{r([]),a(null)},[]);return{spectra:t,loading:o,error:s,loadFile:l,loadText:i,addSpectrum:c,removeSpectrum:u,toggleVisibility:p,clear:f}}var pe=require("react");var st={solid:"",dashed:"8 4",dotted:"2 2","dash-dot":"8 4 2 4"};function Be(e,t,r,o){let{width:n,height:s,background:a="#ffffff",title:i}=o,l=e.filter(c=>c.visible!==!1).map((c,u)=>{let p=c.color??P(u),f=c.lineStyle??"solid",m=c.lineWidth??1.5,d=st[f]??"",g=Math.min(c.x.length,c.y.length);if(g<2)return"";let h=[];for(let b=0;b<g;b++){let y=t(c.x[b]).toFixed(2),S=r(c.y[b]).toFixed(2);h.push(`${b===0?"M":"L"}${y},${S}`)}return`<path d="${h.join(" ")}" fill="none" stroke="${p}" stroke-width="${m}"${d?` stroke-dasharray="${d}"`:""}/>
3
3
  <!-- ${c.label} -->`}).filter(Boolean).join(`
4
4
  `);return`<?xml version="1.0" encoding="UTF-8"?>
5
- <svg xmlns="http://www.w3.org/2000/svg" width="${n}" height="${a}" viewBox="0 0 ${n} ${a}">
6
- <rect width="${n}" height="${a}" fill="${s}"/>
5
+ <svg xmlns="http://www.w3.org/2000/svg" width="${n}" height="${s}" viewBox="0 0 ${n} ${s}">
6
+ <rect width="${n}" height="${s}" fill="${a}"/>
7
7
  ${i?`<text x="${n/2}" y="20" text-anchor="middle" font-family="system-ui" font-size="14">${i}</text>`:""}
8
8
  <g>
9
9
  ${l}
10
10
  </g>
11
- </svg>`}function ze(e,t="spectrum.svg"){let r=new Blob([e],{type:"image/svg+xml"}),o=URL.createObjectURL(r),n=document.createElement("a");n.href=o,n.download=t,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(o)}function Ve(e,t){let r=URL.createObjectURL(e),o=document.createElement("a");o.href=r,o.download=t,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(r)}function zt(){let e=(0,ce.useCallback)((n,a="spectrum.png")=>{n.toBlob(s=>{s&&Ve(s,a)},"image/png")},[]),t=(0,ce.useCallback)((n,a="spectra.csv")=>{let s=n.filter(i=>i.visible!==!1);if(s.length!==0)if(s.length===1){let i=s[0],l=`${i.xUnit??"x"},${i.yUnit??"y"}
11
+ </svg>`}function Ze(e,t="spectrum.svg"){let r=new Blob([e],{type:"image/svg+xml"}),o=URL.createObjectURL(r),n=document.createElement("a");n.href=o,n.download=t,document.body.appendChild(n),n.click(),document.body.removeChild(n),URL.revokeObjectURL(o)}function _e(e,t){let r=URL.createObjectURL(e),o=document.createElement("a");o.href=r,o.download=t,document.body.appendChild(o),o.click(),document.body.removeChild(o),URL.revokeObjectURL(r)}function _t(){let e=(0,pe.useCallback)((n,s="spectrum.png")=>{n.toBlob(a=>{a&&_e(a,s)},"image/png")},[]),t=(0,pe.useCallback)((n,s="spectra.csv")=>{let a=n.filter(i=>i.visible!==!1);if(a.length!==0)if(a.length===1){let i=a[0],l=`${i.xUnit??"x"},${i.yUnit??"y"}
12
12
  `,c=Array.from(i.x).map((p,f)=>`${p},${i.y[f]}`),u=l+c.join(`
13
- `);Ve(new Blob([u],{type:"text/csv"}),a)}else{let i=Math.max(...s.map(p=>p.x.length)),l=s.map(p=>`${p.label}_x,${p.label}_y`).join(","),c=[];for(let p=0;p<i;p++){let f=s.map(m=>p<m.x.length?`${m.x[p]},${m.y[p]}`:",");c.push(f.join(","))}let u=l+`
13
+ `);_e(new Blob([u],{type:"text/csv"}),s)}else{let i=Math.max(...a.map(p=>p.x.length)),l=a.map(p=>`${p.label}_x,${p.label}_y`).join(","),c=[];for(let p=0;p<i;p++){let f=a.map(m=>p<m.x.length?`${m.x[p]},${m.y[p]}`:",");c.push(f.join(","))}let u=l+`
14
14
  `+c.join(`
15
- `);Ve(new Blob([u],{type:"text/csv"}),a)}},[]),r=(0,ce.useCallback)((n,a="spectra.json")=>{let i=n.filter(c=>c.visible!==!1).map(c=>({label:c.label,x:Array.from(c.x),y:Array.from(c.y),xUnit:c.xUnit,yUnit:c.yUnit,type:c.type})),l=JSON.stringify(i,null,2);Ve(new Blob([l],{type:"application/json"}),a)},[]),o=(0,ce.useCallback)((n,a,s,i,l,c="spectrum.svg")=>{let u=Oe(n,a,s,{width:i,height:l});ze(u,c)},[]);return{exportPng:e,exportSvg:o,exportCsv:t,exportJson:r}}var Be=require("react"),B=require("react/jsx-runtime"),Br=e=>({display:"inline-flex",alignItems:"center",justifyContent:"center",height:28,padding:"0 8px",border:`1px solid ${e==="dark"?"#4b5563":"#d1d5db"}`,borderRadius:4,background:e==="dark"?"#1f2937":"#ffffff",color:e==="dark"?"#d1d5db":"#374151",fontSize:12,cursor:"pointer",lineHeight:1,position:"relative"}),_r=e=>({position:"absolute",top:30,left:0,background:e==="dark"?"#1f2937":"#ffffff",border:`1px solid ${e==="dark"?"#4b5563":"#d1d5db"}`,borderRadius:4,boxShadow:"0 2px 8px rgba(0,0,0,0.15)",zIndex:200,minWidth:100,overflow:"hidden"}),Ze=e=>({display:"block",width:"100%",padding:"6px 12px",border:"none",background:"transparent",color:e==="dark"?"#d1d5db":"#374151",fontSize:12,textAlign:"left",cursor:"pointer"});function Vt({theme:e,onExportPng:t,onExportSvg:r,onExportCsv:o,onExportJson:n}){let[a,s]=(0,Be.useState)(!1),i=(0,Be.useCallback)(l=>{s(!1),l?.()},[]);return(0,B.jsxs)("div",{style:{position:"relative",display:"inline-block"},children:[(0,B.jsx)("button",{type:"button",style:Br(e),onClick:()=>s(!a),"aria-label":"Export","aria-expanded":a,"aria-haspopup":"true",children:"Export"}),a&&(0,B.jsxs)("div",{style:_r(e),role:"menu",children:[t&&(0,B.jsx)("button",{type:"button",role:"menuitem",style:Ze(e),onClick:()=>i(t),children:"PNG Image"}),r&&(0,B.jsx)("button",{type:"button",role:"menuitem",style:Ze(e),onClick:()=>i(r),children:"SVG Vector"}),o&&(0,B.jsx)("button",{type:"button",role:"menuitem",style:Ze(e),onClick:()=>i(o),children:"CSV Data"}),n&&(0,B.jsx)("button",{type:"button",role:"menuitem",style:Ze(e),onClick:()=>i(n),children:"JSON Data"})]})]})}function Zt(e){let t=e.length;if(t<3)return new Float64Array(e);let r=[0];for(let s=1;s<t;s++){for(;r.length>=2;){let i=r.length-1,l=r[i-1],c=r[i];if((s-l)*(e[c]-e[l])-(c-l)*(e[s]-e[l])>=0)r.pop();else break}r.push(s)}let o=new Float64Array(t),n=0;for(let s=0;s<t;s++){for(;n<r.length-1&&r[n+1]<=s;)n++;if(n>=r.length-1)o[s]=e[r[r.length-1]];else{let i=r[n],l=r[n+1],c=(s-i)/(l-i);o[s]=e[i]*(1-c)+e[l]*c}}let a=new Float64Array(t);for(let s=0;s<t;s++)a[s]=e[s]-o[s];return a}function Bt(e){let t=e.length,r=new Float64Array(t),o=1/0,n=-1/0;for(let s=0;s<t;s++){let i=e[s];i<o&&(o=i),i>n&&(n=i)}let a=n-o;if(a===0)return r;for(let s=0;s<t;s++)r[s]=(e[s]-o)/a;return r}function _t(e,t){let r=Math.min(e.length,t.length);if(r<2)return new Float64Array(t);let o=0;for(let a=1;a<r;a++)o+=Math.abs(e[a]-e[a-1])*(Math.abs(t[a])+Math.abs(t[a-1]))*.5;if(o===0)return new Float64Array(t);let n=new Float64Array(r);for(let a=0;a<r;a++)n[a]=t[a]/o;return n}function Ht(e){let t=e.length;if(t===0)return new Float64Array(0);let r=0;for(let i=0;i<t;i++)r+=e[i];let o=r/t,n=0;for(let i=0;i<t;i++){let l=e[i]-o;n+=l*l}let a=Math.sqrt(n/t);if(a===0)return new Float64Array(t);let s=new Float64Array(t);for(let i=0;i<t;i++)s[i]=(e[i]-o)/a;return s}function Xt(e,t=5){let r=e.length;if(r<t||t<3)return new Float64Array(e);let o=t%2===0?t+1:t,n=(o-1)/2,a=Hr(o),s=new Float64Array(r);for(let i=0;i<n;i++)s[i]=e[i],s[r-1-i]=e[r-1-i];for(let i=n;i<r-n;i++){let l=0;for(let c=-n;c<=n;c++)l+=a[c+n]*e[i+c];s[i]=l}return s}function Hr(e){let t={5:[-3,12,17,12,-3].map(r=>r/35),7:[-2,3,6,7,6,3,-2].map(r=>r/21),9:[-21,14,39,54,59,54,39,14,-21].map(r=>r/231),11:[-36,9,44,69,84,89,84,69,44,9,-36].map(r=>r/429)};return t[e]?t[e]:Array(e).fill(1/e)}function Wt(e,t){let r=Math.min(e.length,t.length);if(r<2)return new Float64Array(r);let o=new Float64Array(r);o[0]=(t[1]-t[0])/(e[1]-e[0]);for(let n=1;n<r-1;n++)o[n]=(t[n+1]-t[n-1])/(e[n+1]-e[n-1]);return o[r-1]=(t[r-1]-t[r-2])/(e[r-1]-e[r-2]),o}function Yt(e,t){let r=Math.min(e.length,t.length);if(r<3)return new Float64Array(r);let o=new Float64Array(r);for(let n=1;n<r-1;n++){let a=e[n]-e[n-1],s=e[n+1]-e[n],i=(a+s)/2;o[n]=(t[n+1]-2*t[n]+t[n-1])/(i*i)}return o[0]=o[1],o[r-1]=o[r-2],o}var me=0;function jt(e,t){let r=Math.min(e.y.length,t.y.length),o=new Float64Array(r);for(let n=0;n<r;n++)o[n]=e.y[n]-t.y[n];return{id:`diff-${++me}`,label:`${e.label} \u2212 ${t.label}`,x:e.x.length<=t.x.length?new Float64Array(e.x):new Float64Array(t.x),y:o,xUnit:e.xUnit,yUnit:e.yUnit,color:"#ef4444",type:e.type}}function Gt(e,t){let r=Math.min(e.y.length,t.y.length),o=new Float64Array(r);for(let n=0;n<r;n++)o[n]=e.y[n]+t.y[n];return{id:`add-${++me}`,label:`${e.label} + ${t.label}`,x:e.x.length<=t.x.length?new Float64Array(e.x):new Float64Array(t.x),y:o,xUnit:e.xUnit,yUnit:e.yUnit,type:e.type}}function Kt(e,t){let r=e.y.length,o=new Float64Array(r);for(let n=0;n<r;n++)o[n]=e.y[n]*t;return{id:`scaled-${++me}`,label:`${e.label} \xD7 ${t}`,x:new Float64Array(e.x),y:o,xUnit:e.xUnit,yUnit:e.yUnit,color:e.color,type:e.type}}function Jt(e,t){let r=Math.min(e.y.length,t.y.length);if(r===0)return 0;let o=0,n=0;for(let p=0;p<r;p++)o+=e.y[p],n+=t.y[p];let a=o/r,s=n/r,i=0,l=0,c=0;for(let p=0;p<r;p++){let f=e.y[p]-a,m=t.y[p]-s;i+=f*m,l+=f*f,c+=m*m}let u=Math.sqrt(l*c);return u===0?0:i/u}function qt(e,t){let r=Math.min(e.y.length,t.y.length),o=new Float64Array(r);for(let n=0;n<r;n++)o[n]=Math.abs(e.y[n]-t.y[n]);return{id:`residual-${++me}`,label:`|${e.label} \u2212 ${t.label}|`,x:e.x.length<=t.x.length?new Float64Array(e.x):new Float64Array(t.x),y:o,xUnit:e.xUnit,yUnit:e.yUnit,color:"#f97316",lineStyle:"dashed",type:e.type}}function Qt(e,t){let r=Math.min(e.x.length,e.y.length),o=t.length,n=new Float64Array(o);if(r<2)return{...e,x:new Float64Array(t),y:n};let a=e.x[r-1]>e.x[0];for(let s=0;s<o;s++){let i=t[s],l=0,c=r-1;for(;l<c-1;){let d=l+c>>>1;a?e.x[d]<=i?l=d:c=d:e.x[d]>=i?l=d:c=d}let u=e.x[l],p=e.x[c],f=e.y[l],m=e.y[c];if(u===p)n[s]=f;else{let d=(i-u)/(p-u);n[s]=f+d*(m-f)}}return{...e,id:`interp-${++me}`,x:new Float64Array(t),y:n}}var Xr=0,Wr=1,Yr=4,jr=128,Gr={0:"Arbitrary",1:"cm\u207B\xB9",2:"\xB5m",3:"nm",4:"s",5:"min",6:"Hz",7:"kHz",8:"MHz",9:"m/z",10:"Da",11:"ppm",12:"days",13:"years",14:"Raman shift (cm\u207B\xB9)",15:"eV",16:"Text label",255:"Double interferogram"},Kr={0:"Arbitrary",1:"Interferogram",2:"Absorbance",3:"Kubelka-Munk",4:"Counts",5:"V",6:"\xB0",7:"mA",8:"mm",9:"mV",10:"log(1/R)",11:"%",12:"Intensity",13:"Relative intensity",14:"Energy",16:"dB",19:"\xB0C",20:"\xB0F",21:"K",22:"Index of refraction [n]",23:"Extinction coeff. [k]",24:"Real",25:"Imaginary",26:"Complex",128:"Transmittance",129:"Reflectance",130:"Arbitrary (Valley to peak)",131:"Emission"};function Jr(e,t){return e===1?"IR":e===14?"Raman":e===3&&(t===2||t===128)?"UV-Vis":e===2?"NIR":t===131?"fluorescence":"other"}function er(e){let t=new DataView(e);if(e.byteLength<512)throw new Error("Invalid SPC file: too small for SPC header");let o=t.getUint8(0),n=t.getUint8(1);if(n!==75&&n!==77)throw new Error(`Unsupported SPC version: 0x${n.toString(16)}. Expected 0x4B or 0x4D.`);let a=t.getUint8(2),s=t.getUint8(3),i=t.getUint32(4,!0),l=t.getFloat64(8,!0),c=t.getFloat64(16,!0),u=t.getUint32(24,!0),p=Gr[a]??"Arbitrary",f=Kr[s]??"Arbitrary",m=new Uint8Array(e,30,130),d=qr(m),g=(o&Yr)!==0,y=(o&jr)!==0,b=(o&Wr)!==0,x=Jr(a,s),S=null;if(!y&&i>0){S=new Float64Array(i);let C=i>1?(c-l)/(i-1):0;for(let M=0;M<i;M++)S[M]=l+M*C}let k=[],h=512,v=null;if(y&&!g){v=new Float64Array(i);for(let C=0;C<i;C++)v[C]=t.getFloat32(h,!0),h+=4}let w=g?u:1;for(let C=0;C<w;C++){let M,E,D=i;if(g){if(h+32>e.byteLength)break;let U=t.getFloat32(h+4,!0),_e=t.getFloat32(h+8,!0);if(D=t.getUint32(h+12,!0)||i,h+=32,y){M=new Float64Array(D);for(let K=0;K<D&&!(h+4>e.byteLength);K++)M[K]=t.getFloat32(h,!0),h+=4}else if(S)M=S;else{M=new Float64Array(D);let K=D>1?(_e-U)/(D-1):0;for(let J=0;J<D;J++)M[J]=U+J*K}}else M=v??S??new Float64Array(0);if(E=new Float64Array(D),b)for(let U=0;U<D&&!(h+2>e.byteLength);U++)E[U]=t.getInt16(h,!0),h+=2;else for(let U=0;U<D&&!(h+4>e.byteLength);U++)E[U]=t.getFloat32(h,!0),h+=4;k.push({id:`spc-${++Xr}`,label:d||`SPC Spectrum ${C+1}`,x:M,y:E,xUnit:p,yUnit:f,type:x,meta:{format:"SPC",version:n===75?"new":"old",xType:a.toString(),yType:s.toString()}})}if(k.length===0)throw new Error("Invalid SPC file: no spectra found");return k}function qr(e){let t=e.indexOf(0),r=t>=0?e.slice(0,t):e;return new TextDecoder("ascii").decode(r).trim()}0&&(module.exports={AnnotationLayer,AxisLayer,Crosshair,DARK_THEME,DropZone,ExportMenu,KEYBOARD_SHORTCUTS,LIGHT_THEME,LINE_DASH_PATTERNS,Legend,Minimap,PeakMarkers,RegionSelector,SPECTRUM_COLORS,SpectraView,SpectrumCanvas,StackedView,Toolbar,addSpectra,baselineRubberBand,binarySearchClosest,computeXExtent,computeYExtent,correlationCoefficient,createXScale,createYScale,derivative1st,derivative2nd,detectPeaks,differenceSpectrum,downloadSvg,generateChartDescription,generateSvg,getSpectrumColor,getThemeColors,interpolateToGrid,lttbDownsample,normalizeArea,normalizeMinMax,normalizeSNV,parseCsv,parseCsvMulti,parseJcamp,parseJson,parseSpc,prefersReducedMotion,residualSpectrum,scaleSpectrum,smoothSavitzkyGolay,snapToNearestSpectrum,useExport,useKeyboardNavigation,usePeakPicking,useRegionSelect,useResizeObserver,useSpectrumData,useZoomPan});
15
+ `);_e(new Blob([u],{type:"text/csv"}),s)}},[]),r=(0,pe.useCallback)((n,s="spectra.json")=>{let i=n.filter(c=>c.visible!==!1).map(c=>({label:c.label,x:Array.from(c.x),y:Array.from(c.y),xUnit:c.xUnit,yUnit:c.yUnit,type:c.type})),l=JSON.stringify(i,null,2);_e(new Blob([l],{type:"application/json"}),s)},[]),o=(0,pe.useCallback)((n,s,a,i,l,c="spectrum.svg")=>{let u=Be(n,s,a,{width:i,height:l});Ze(u,c)},[]);return{exportPng:e,exportSvg:o,exportCsv:t,exportJson:r}}var Xe=require("react"),_=require("react/jsx-runtime"),Wr=e=>({display:"inline-flex",alignItems:"center",justifyContent:"center",height:28,padding:"0 8px",border:`1px solid ${e==="dark"?"#4b5563":"#d1d5db"}`,borderRadius:4,background:e==="dark"?"#1f2937":"#ffffff",color:e==="dark"?"#d1d5db":"#374151",fontSize:12,cursor:"pointer",lineHeight:1,position:"relative"}),Yr=e=>({position:"absolute",top:30,left:0,background:e==="dark"?"#1f2937":"#ffffff",border:`1px solid ${e==="dark"?"#4b5563":"#d1d5db"}`,borderRadius:4,boxShadow:"0 2px 8px rgba(0,0,0,0.15)",zIndex:200,minWidth:100,overflow:"hidden"}),He=e=>({display:"block",width:"100%",padding:"6px 12px",border:"none",background:"transparent",color:e==="dark"?"#d1d5db":"#374151",fontSize:12,textAlign:"left",cursor:"pointer"});function Ht({theme:e,onExportPng:t,onExportSvg:r,onExportCsv:o,onExportJson:n}){let[s,a]=(0,Xe.useState)(!1),i=(0,Xe.useCallback)(l=>{a(!1),l?.()},[]);return(0,_.jsxs)("div",{style:{position:"relative",display:"inline-block"},children:[(0,_.jsx)("button",{type:"button",style:Wr(e),onClick:()=>a(!s),"aria-label":"Export","aria-expanded":s,"aria-haspopup":"true",children:"Export"}),s&&(0,_.jsxs)("div",{style:Yr(e),role:"menu",children:[t&&(0,_.jsx)("button",{type:"button",role:"menuitem",style:He(e),onClick:()=>i(t),children:"PNG Image"}),r&&(0,_.jsx)("button",{type:"button",role:"menuitem",style:He(e),onClick:()=>i(r),children:"SVG Vector"}),o&&(0,_.jsx)("button",{type:"button",role:"menuitem",style:He(e),onClick:()=>i(o),children:"CSV Data"}),n&&(0,_.jsx)("button",{type:"button",role:"menuitem",style:He(e),onClick:()=>i(n),children:"JSON Data"})]})]})}function Xt(e){let t=e.length;if(t<3)return new Float64Array(e);let r=[0];for(let a=1;a<t;a++){for(;r.length>=2;){let i=r.length-1,l=r[i-1],c=r[i];if((a-l)*(e[c]-e[l])-(c-l)*(e[a]-e[l])>=0)r.pop();else break}r.push(a)}let o=new Float64Array(t),n=0;for(let a=0;a<t;a++){for(;n<r.length-1&&r[n+1]<=a;)n++;if(n>=r.length-1)o[a]=e[r[r.length-1]];else{let i=r[n],l=r[n+1],c=(a-i)/(l-i);o[a]=e[i]*(1-c)+e[l]*c}}let s=new Float64Array(t);for(let a=0;a<t;a++)s[a]=e[a]-o[a];return s}function Wt(e){let t=e.length,r=new Float64Array(t),o=1/0,n=-1/0;for(let a=0;a<t;a++){let i=e[a];i<o&&(o=i),i>n&&(n=i)}let s=n-o;if(s===0)return r;for(let a=0;a<t;a++)r[a]=(e[a]-o)/s;return r}function Yt(e,t){let r=Math.min(e.length,t.length);if(r<2)return new Float64Array(t);let o=0;for(let s=1;s<r;s++)o+=Math.abs(e[s]-e[s-1])*(Math.abs(t[s])+Math.abs(t[s-1]))*.5;if(o===0)return new Float64Array(t);let n=new Float64Array(r);for(let s=0;s<r;s++)n[s]=t[s]/o;return n}function jt(e){let t=e.length;if(t===0)return new Float64Array(0);let r=0;for(let i=0;i<t;i++)r+=e[i];let o=r/t,n=0;for(let i=0;i<t;i++){let l=e[i]-o;n+=l*l}let s=Math.sqrt(n/t);if(s===0)return new Float64Array(t);let a=new Float64Array(t);for(let i=0;i<t;i++)a[i]=(e[i]-o)/s;return a}function Gt(e,t=5){let r=e.length;if(r<t||t<3)return new Float64Array(e);let o=t%2===0?t+1:t,n=(o-1)/2,s=jr(o),a=new Float64Array(r);for(let i=0;i<n;i++)a[i]=e[i],a[r-1-i]=e[r-1-i];for(let i=n;i<r-n;i++){let l=0;for(let c=-n;c<=n;c++)l+=s[c+n]*e[i+c];a[i]=l}return a}function jr(e){let t={5:[-3,12,17,12,-3].map(r=>r/35),7:[-2,3,6,7,6,3,-2].map(r=>r/21),9:[-21,14,39,54,59,54,39,14,-21].map(r=>r/231),11:[-36,9,44,69,84,89,84,69,44,9,-36].map(r=>r/429)};return t[e]?t[e]:Array(e).fill(1/e)}function Kt(e,t){let r=Math.min(e.length,t.length);if(r<2)return new Float64Array(r);let o=new Float64Array(r);o[0]=(t[1]-t[0])/(e[1]-e[0]);for(let n=1;n<r-1;n++)o[n]=(t[n+1]-t[n-1])/(e[n+1]-e[n-1]);return o[r-1]=(t[r-1]-t[r-2])/(e[r-1]-e[r-2]),o}function Jt(e,t){let r=Math.min(e.length,t.length);if(r<3)return new Float64Array(r);let o=new Float64Array(r);for(let n=1;n<r-1;n++){let s=e[n]-e[n-1],a=e[n+1]-e[n],i=(s+a)/2;o[n]=(t[n+1]-2*t[n]+t[n-1])/(i*i)}return o[0]=o[1],o[r-1]=o[r-2],o}var fe=0;function qt(e,t){let r=Math.min(e.y.length,t.y.length),o=new Float64Array(r);for(let n=0;n<r;n++)o[n]=e.y[n]-t.y[n];return{id:`diff-${++fe}`,label:`${e.label} \u2212 ${t.label}`,x:e.x.length<=t.x.length?new Float64Array(e.x):new Float64Array(t.x),y:o,xUnit:e.xUnit,yUnit:e.yUnit,color:"#ef4444",type:e.type}}function Qt(e,t){let r=Math.min(e.y.length,t.y.length),o=new Float64Array(r);for(let n=0;n<r;n++)o[n]=e.y[n]+t.y[n];return{id:`add-${++fe}`,label:`${e.label} + ${t.label}`,x:e.x.length<=t.x.length?new Float64Array(e.x):new Float64Array(t.x),y:o,xUnit:e.xUnit,yUnit:e.yUnit,type:e.type}}function er(e,t){let r=e.y.length,o=new Float64Array(r);for(let n=0;n<r;n++)o[n]=e.y[n]*t;return{id:`scaled-${++fe}`,label:`${e.label} \xD7 ${t}`,x:new Float64Array(e.x),y:o,xUnit:e.xUnit,yUnit:e.yUnit,color:e.color,type:e.type}}function tr(e,t){let r=Math.min(e.y.length,t.y.length);if(r===0)return 0;let o=0,n=0;for(let p=0;p<r;p++)o+=e.y[p],n+=t.y[p];let s=o/r,a=n/r,i=0,l=0,c=0;for(let p=0;p<r;p++){let f=e.y[p]-s,m=t.y[p]-a;i+=f*m,l+=f*f,c+=m*m}let u=Math.sqrt(l*c);return u===0?0:i/u}function rr(e,t){let r=Math.min(e.y.length,t.y.length),o=new Float64Array(r);for(let n=0;n<r;n++)o[n]=Math.abs(e.y[n]-t.y[n]);return{id:`residual-${++fe}`,label:`|${e.label} \u2212 ${t.label}|`,x:e.x.length<=t.x.length?new Float64Array(e.x):new Float64Array(t.x),y:o,xUnit:e.xUnit,yUnit:e.yUnit,color:"#f97316",lineStyle:"dashed",type:e.type}}function nr(e,t){let r=Math.min(e.x.length,e.y.length),o=t.length,n=new Float64Array(o);if(r<2)return{...e,x:new Float64Array(t),y:n};let s=e.x[r-1]>e.x[0];for(let a=0;a<o;a++){let i=t[a],l=0,c=r-1;for(;l<c-1;){let d=l+c>>>1;s?e.x[d]<=i?l=d:c=d:e.x[d]>=i?l=d:c=d}let u=e.x[l],p=e.x[c],f=e.y[l],m=e.y[c];if(u===p)n[a]=f;else{let d=(i-u)/(p-u);n[a]=f+d*(m-f)}}return{...e,id:`interp-${++fe}`,x:new Float64Array(t),y:n}}var Gr=0,Kr=1,Jr=4,qr=128,Qr={0:"Arbitrary",1:"cm\u207B\xB9",2:"\xB5m",3:"nm",4:"s",5:"min",6:"Hz",7:"kHz",8:"MHz",9:"m/z",10:"Da",11:"ppm",12:"days",13:"years",14:"Raman shift (cm\u207B\xB9)",15:"eV",16:"Text label",255:"Double interferogram"},en={0:"Arbitrary",1:"Interferogram",2:"Absorbance",3:"Kubelka-Munk",4:"Counts",5:"V",6:"\xB0",7:"mA",8:"mm",9:"mV",10:"log(1/R)",11:"%",12:"Intensity",13:"Relative intensity",14:"Energy",16:"dB",19:"\xB0C",20:"\xB0F",21:"K",22:"Index of refraction [n]",23:"Extinction coeff. [k]",24:"Real",25:"Imaginary",26:"Complex",128:"Transmittance",129:"Reflectance",130:"Arbitrary (Valley to peak)",131:"Emission"};function tn(e,t){return e===1?"IR":e===14?"Raman":e===3&&(t===2||t===128)?"UV-Vis":e===2?"NIR":t===131?"fluorescence":"other"}function or(e){let t=new DataView(e);if(e.byteLength<512)throw new Error("Invalid SPC file: too small for SPC header");let o=t.getUint8(0),n=t.getUint8(1);if(n!==75&&n!==77)throw new Error(`Unsupported SPC version: 0x${n.toString(16)}. Expected 0x4B or 0x4D.`);let s=t.getUint8(2),a=t.getUint8(3),i=t.getUint32(4,!0),l=t.getFloat64(8,!0),c=t.getFloat64(16,!0),u=t.getUint32(24,!0),p=Qr[s]??"Arbitrary",f=en[a]??"Arbitrary",m=new Uint8Array(e,30,130),d=rn(m),g=(o&Jr)!==0,h=(o&qr)!==0,b=(o&Kr)!==0,y=tn(s,a),S=null;if(!h&&i>0){S=new Float64Array(i);let k=i>1?(c-l)/(i-1):0;for(let M=0;M<i;M++)S[M]=l+M*k}let v=[],x=512,w=null;if(h&&!g){w=new Float64Array(i);for(let k=0;k<i;k++)w[k]=t.getFloat32(x,!0),x+=4}let C=g?u:1;for(let k=0;k<C;k++){let M,E,D=i;if(g){if(x+32>e.byteLength)break;let U=t.getFloat32(x+4,!0),We=t.getFloat32(x+8,!0);if(D=t.getUint32(x+12,!0)||i,x+=32,h){M=new Float64Array(D);for(let J=0;J<D&&!(x+4>e.byteLength);J++)M[J]=t.getFloat32(x,!0),x+=4}else if(S)M=S;else{M=new Float64Array(D);let J=D>1?(We-U)/(D-1):0;for(let q=0;q<D;q++)M[q]=U+q*J}}else M=w??S??new Float64Array(0);if(E=new Float64Array(D),b)for(let U=0;U<D&&!(x+2>e.byteLength);U++)E[U]=t.getInt16(x,!0),x+=2;else for(let U=0;U<D&&!(x+4>e.byteLength);U++)E[U]=t.getFloat32(x,!0),x+=4;v.push({id:`spc-${++Gr}`,label:d||`SPC Spectrum ${k+1}`,x:M,y:E,xUnit:p,yUnit:f,type:y,meta:{format:"SPC",version:n===75?"new":"old",xType:s.toString(),yType:a.toString()}})}if(v.length===0)throw new Error("Invalid SPC file: no spectra found");return v}function rn(e){let t=e.indexOf(0),r=t>=0?e.slice(0,t):e;return new TextDecoder("ascii").decode(r).trim()}0&&(module.exports={AnnotationLayer,AxisLayer,Crosshair,DARK_THEME,DropZone,ExportMenu,KEYBOARD_SHORTCUTS,LIGHT_THEME,LINE_DASH_PATTERNS,Legend,Minimap,PeakMarkers,RegionSelector,SPECTRUM_COLORS,SpectraView,SpectrumCanvas,StackedView,Toolbar,Tooltip,addSpectra,baselineRubberBand,binarySearchClosest,computeXExtent,computeYExtent,correlationCoefficient,createXScale,createYScale,derivative1st,derivative2nd,detectPeaks,differenceSpectrum,downloadSvg,generateChartDescription,generateSvg,getSpectrumColor,getThemeColors,interpolateToGrid,lttbDownsample,normalizeArea,normalizeMinMax,normalizeSNV,parseCsv,parseCsvMulti,parseJcamp,parseJson,parseSpc,prefersReducedMotion,residualSpectrum,scaleSpectrum,smoothSavitzkyGolay,snapToNearestSpectrum,useExport,useKeyboardNavigation,usePeakPicking,useRegionSelect,useResizeObserver,useSpectrumData,useZoomPan});
16
16
  //# sourceMappingURL=index.cjs.map