pivtools 0.1.3__cp311-cp311-win_amd64.whl

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.
Files changed (127) hide show
  1. pivtools-0.1.3.dist-info/METADATA +222 -0
  2. pivtools-0.1.3.dist-info/RECORD +127 -0
  3. pivtools-0.1.3.dist-info/WHEEL +5 -0
  4. pivtools-0.1.3.dist-info/entry_points.txt +3 -0
  5. pivtools-0.1.3.dist-info/top_level.txt +3 -0
  6. pivtools_cli/__init__.py +5 -0
  7. pivtools_cli/_build_marker.c +25 -0
  8. pivtools_cli/_build_marker.cp311-win_amd64.pyd +0 -0
  9. pivtools_cli/cli.py +225 -0
  10. pivtools_cli/example.py +139 -0
  11. pivtools_cli/lib/PIV_2d_cross_correlate.c +334 -0
  12. pivtools_cli/lib/PIV_2d_cross_correlate.h +22 -0
  13. pivtools_cli/lib/common.h +36 -0
  14. pivtools_cli/lib/interp2custom.c +146 -0
  15. pivtools_cli/lib/interp2custom.h +48 -0
  16. pivtools_cli/lib/peak_locate_gsl.c +711 -0
  17. pivtools_cli/lib/peak_locate_gsl.h +40 -0
  18. pivtools_cli/lib/peak_locate_gsl_print.c +736 -0
  19. pivtools_cli/lib/peak_locate_lm.c +751 -0
  20. pivtools_cli/lib/peak_locate_lm.h +27 -0
  21. pivtools_cli/lib/xcorr.c +342 -0
  22. pivtools_cli/lib/xcorr.h +31 -0
  23. pivtools_cli/lib/xcorr_cache.c +78 -0
  24. pivtools_cli/lib/xcorr_cache.h +26 -0
  25. pivtools_cli/piv/interp2custom/interp2custom.py +69 -0
  26. pivtools_cli/piv/piv.py +240 -0
  27. pivtools_cli/piv/piv_backend/base.py +825 -0
  28. pivtools_cli/piv/piv_backend/cpu_instantaneous.py +1005 -0
  29. pivtools_cli/piv/piv_backend/factory.py +28 -0
  30. pivtools_cli/piv/piv_backend/gpu_instantaneous.py +15 -0
  31. pivtools_cli/piv/piv_backend/infilling.py +445 -0
  32. pivtools_cli/piv/piv_backend/outlier_detection.py +306 -0
  33. pivtools_cli/piv/piv_backend/profile_cpu_instantaneous.py +230 -0
  34. pivtools_cli/piv/piv_result.py +40 -0
  35. pivtools_cli/piv/save_results.py +342 -0
  36. pivtools_cli/piv_cluster/cluster.py +108 -0
  37. pivtools_cli/preprocessing/filters.py +399 -0
  38. pivtools_cli/preprocessing/preprocess.py +79 -0
  39. pivtools_cli/tests/helpers.py +107 -0
  40. pivtools_cli/tests/instantaneous_piv/test_piv_integration.py +167 -0
  41. pivtools_cli/tests/instantaneous_piv/test_piv_integration_multi.py +553 -0
  42. pivtools_cli/tests/preprocessing/test_filters.py +41 -0
  43. pivtools_core/__init__.py +5 -0
  44. pivtools_core/config.py +703 -0
  45. pivtools_core/config.yaml +135 -0
  46. pivtools_core/image_handling/__init__.py +0 -0
  47. pivtools_core/image_handling/load_images.py +464 -0
  48. pivtools_core/image_handling/readers/__init__.py +53 -0
  49. pivtools_core/image_handling/readers/generic_readers.py +50 -0
  50. pivtools_core/image_handling/readers/lavision_reader.py +190 -0
  51. pivtools_core/image_handling/readers/registry.py +24 -0
  52. pivtools_core/paths.py +49 -0
  53. pivtools_core/vector_loading.py +248 -0
  54. pivtools_gui/__init__.py +3 -0
  55. pivtools_gui/app.py +687 -0
  56. pivtools_gui/calibration/__init__.py +0 -0
  57. pivtools_gui/calibration/app/__init__.py +0 -0
  58. pivtools_gui/calibration/app/views.py +1186 -0
  59. pivtools_gui/calibration/calibration_planar/planar_calibration_production.py +570 -0
  60. pivtools_gui/calibration/vector_calibration_production.py +544 -0
  61. pivtools_gui/config.py +703 -0
  62. pivtools_gui/image_handling/__init__.py +0 -0
  63. pivtools_gui/image_handling/load_images.py +464 -0
  64. pivtools_gui/image_handling/readers/__init__.py +53 -0
  65. pivtools_gui/image_handling/readers/generic_readers.py +50 -0
  66. pivtools_gui/image_handling/readers/lavision_reader.py +190 -0
  67. pivtools_gui/image_handling/readers/registry.py +24 -0
  68. pivtools_gui/masking/__init__.py +0 -0
  69. pivtools_gui/masking/app/__init__.py +0 -0
  70. pivtools_gui/masking/app/views.py +123 -0
  71. pivtools_gui/paths.py +49 -0
  72. pivtools_gui/piv_runner.py +261 -0
  73. pivtools_gui/pivtools.py +58 -0
  74. pivtools_gui/plotting/__init__.py +0 -0
  75. pivtools_gui/plotting/app/__init__.py +0 -0
  76. pivtools_gui/plotting/app/views.py +1671 -0
  77. pivtools_gui/plotting/plot_maker.py +220 -0
  78. pivtools_gui/post_processing/POD/__init__.py +0 -0
  79. pivtools_gui/post_processing/POD/app/__init__.py +0 -0
  80. pivtools_gui/post_processing/POD/app/views.py +647 -0
  81. pivtools_gui/post_processing/POD/pod_decompose.py +979 -0
  82. pivtools_gui/post_processing/POD/views.py +1096 -0
  83. pivtools_gui/post_processing/__init__.py +0 -0
  84. pivtools_gui/static/404.html +1 -0
  85. pivtools_gui/static/_next/static/chunks/117-d5793c8e79de5511.js +2 -0
  86. pivtools_gui/static/_next/static/chunks/484-cfa8b9348ce4f00e.js +1 -0
  87. pivtools_gui/static/_next/static/chunks/869-320a6b9bdafbb6d3.js +1 -0
  88. pivtools_gui/static/_next/static/chunks/app/_not-found/page-12f067ceb7415e55.js +1 -0
  89. pivtools_gui/static/_next/static/chunks/app/layout-b907d5f31ac82e9d.js +1 -0
  90. pivtools_gui/static/_next/static/chunks/app/page-334cc4e8444cde2f.js +1 -0
  91. pivtools_gui/static/_next/static/chunks/fd9d1056-ad15f396ddf9b7e5.js +1 -0
  92. pivtools_gui/static/_next/static/chunks/framework-f66176bb897dc684.js +1 -0
  93. pivtools_gui/static/_next/static/chunks/main-a1b3ced4d5f6d998.js +1 -0
  94. pivtools_gui/static/_next/static/chunks/main-app-8a63c6f5e7baee11.js +1 -0
  95. pivtools_gui/static/_next/static/chunks/pages/_app-72b849fbd24ac258.js +1 -0
  96. pivtools_gui/static/_next/static/chunks/pages/_error-7ba65e1336b92748.js +1 -0
  97. pivtools_gui/static/_next/static/chunks/polyfills-42372ed130431b0a.js +1 -0
  98. pivtools_gui/static/_next/static/chunks/webpack-4a8ca7c99e9bb3d8.js +1 -0
  99. pivtools_gui/static/_next/static/css/7d3f2337d7ea12a5.css +3 -0
  100. pivtools_gui/static/_next/static/vQeR20OUdSSKlK4vukC4q/_buildManifest.js +1 -0
  101. pivtools_gui/static/_next/static/vQeR20OUdSSKlK4vukC4q/_ssgManifest.js +1 -0
  102. pivtools_gui/static/file.svg +1 -0
  103. pivtools_gui/static/globe.svg +1 -0
  104. pivtools_gui/static/grid.svg +8 -0
  105. pivtools_gui/static/index.html +1 -0
  106. pivtools_gui/static/index.txt +8 -0
  107. pivtools_gui/static/next.svg +1 -0
  108. pivtools_gui/static/vercel.svg +1 -0
  109. pivtools_gui/static/window.svg +1 -0
  110. pivtools_gui/stereo_reconstruction/__init__.py +0 -0
  111. pivtools_gui/stereo_reconstruction/app/__init__.py +0 -0
  112. pivtools_gui/stereo_reconstruction/app/views.py +1985 -0
  113. pivtools_gui/stereo_reconstruction/stereo_calibration_production.py +606 -0
  114. pivtools_gui/stereo_reconstruction/stereo_reconstruction_production.py +544 -0
  115. pivtools_gui/utils.py +63 -0
  116. pivtools_gui/vector_loading.py +248 -0
  117. pivtools_gui/vector_merging/__init__.py +1 -0
  118. pivtools_gui/vector_merging/app/__init__.py +1 -0
  119. pivtools_gui/vector_merging/app/views.py +759 -0
  120. pivtools_gui/vector_statistics/app/__init__.py +1 -0
  121. pivtools_gui/vector_statistics/app/views.py +710 -0
  122. pivtools_gui/vector_statistics/ensemble_statistics.py +49 -0
  123. pivtools_gui/vector_statistics/instantaneous_statistics.py +311 -0
  124. pivtools_gui/video_maker/__init__.py +0 -0
  125. pivtools_gui/video_maker/app/__init__.py +0 -0
  126. pivtools_gui/video_maker/app/views.py +436 -0
  127. pivtools_gui/video_maker/video_maker.py +662 -0
@@ -0,0 +1 @@
1
+ (self.webpackChunk_N_E=self.webpackChunk_N_E||[]).push([[931],{8893:function(e,t,a){Promise.resolve().then(a.bind(a,540))},540:function(e,t,a){"use strict";a.r(t),a.d(t,{default:function(){return eZ}});var s=a(7437),r=a(2265),l=a(8728),n=a(5135),i=a(5685),o=a(2489),c=a(8293);function d(){let[e,t]=(0,r.useState)(!1),[a,d]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{let e=()=>{t(window.scrollY>10)};return window.addEventListener("scroll",e),()=>window.removeEventListener("scroll",e)},[]),(0,s.jsx)("nav",{className:"fixed top-0 w-full z-50 transition-all duration-300 ".concat(e?"bg-white/95 backdrop-blur-md shadow-lg":"bg-transparent"),children:(0,s.jsxs)("div",{className:"max-w-7xl mx-auto px-4 sm:px-6 lg:px-8",children:[(0,s.jsxs)("div",{className:"flex justify-between items-center h-16",children:[(0,s.jsx)("div",{className:"flex items-center",children:(0,s.jsxs)("div",{className:"flex-shrink-0",children:[(0,s.jsx)("span",{className:"text-2xl font-bold text-soton-blue",children:"PIVTOOLS"}),(0,s.jsx)("span",{className:"text-sm ml-2 text-gray-500",children:"Desktop"})]})}),(0,s.jsxs)("div",{className:"hidden md:flex items-center space-x-4",children:[(0,s.jsxs)("a",{href:"#",className:"text-gray-600 hover:text-soton-blue px-3 py-2 rounded-md text-sm font-medium flex items-center gap-2",onClick:()=>{},children:[(0,s.jsx)(l.Z,{size:18}),"Settings"]}),(0,s.jsxs)("a",{href:"https://github.com/MTT69/PIVTOOLS",target:"_blank",rel:"noopener noreferrer",className:"text-gray-600 hover:text-soton-blue px-3 py-2 rounded-md text-sm font-medium flex items-center gap-2",children:[(0,s.jsx)(n.Z,{size:18}),"GitHub"]}),(0,s.jsxs)("a",{href:"#",className:"text-gray-600 hover:text-soton-blue px-3 py-2 rounded-md text-sm font-medium flex items-center gap-2",onClick:()=>{},children:[(0,s.jsx)(i.Z,{size:18}),"Documentation"]})]}),(0,s.jsx)("div",{className:"md:hidden",children:(0,s.jsx)("button",{onClick:()=>d(!a),className:"text-gray-700 hover:text-soton-blue p-2",children:a?(0,s.jsx)(o.Z,{size:24}):(0,s.jsx)(c.Z,{size:24})})})]}),a&&(0,s.jsx)("div",{className:"md:hidden",children:(0,s.jsxs)("div",{className:"px-2 pt-2 pb-3 space-y-1 sm:px-3 bg-white rounded-lg shadow-lg",children:[(0,s.jsxs)("a",{href:"#",className:"text-gray-600 hover:text-soton-blue block px-3 py-2 rounded-md text-base font-medium flex items-center gap-2",onClick:()=>d(!1),children:[(0,s.jsx)(l.Z,{size:18}),"Settings"]}),(0,s.jsxs)("a",{href:"https://github.com/MTT69/PIVTOOLS",target:"_blank",rel:"noopener noreferrer",className:"text-gray-600 hover:text-soton-blue block px-3 py-2 rounded-md text-base font-medium flex items-center gap-2",onClick:()=>d(!1),children:[(0,s.jsx)(n.Z,{size:18}),"GitHub"]}),(0,s.jsxs)("a",{href:"#",className:"text-gray-600 hover:text-soton-blue block px-3 py-2 rounded-md text-base font-medium flex items-center gap-2",onClick:()=>d(!1),children:[(0,s.jsx)(i.Z,{size:18}),"Documentation"]})]})})]})})}var u=a(6478),m=a(2735),h=a(3276),x=a(875);function g(e){let{onGetStarted:t}=e,[a,l]=(0,r.useState)(!1);return(0,r.useEffect)(()=>{l(!0)},[]),(0,s.jsxs)("section",{id:"hero",className:"relative min-h-screen flex items-center justify-center bg-gradient-to-br from-soton-blue via-soton-darkblue to-gray-900 pt-32 md:pt-40",children:[(0,s.jsx)("div",{className:"absolute inset-0 bg-[url('/grid.svg')] bg-center opacity-20"}),(0,s.jsxs)("div",{className:"relative z-10 max-w-7xl mx-auto px-4 sm:px-6 lg:px-8 text-center",children:[(0,s.jsxs)(u.E.div,{initial:{opacity:0,y:50},animate:{opacity:1,y:0},transition:{duration:.8},className:"mb-8",children:[(0,s.jsxs)("h1",{className:"text-7xl md:text-9xl font-bold text-white mb-8",children:["PIV",(0,s.jsx)("span",{className:"text-soton-gold",children:"TOOLS"})]}),(0,s.jsx)("p",{className:"text-2xl md:text-3xl text-gray-200 max-w-4xl mx-auto mb-10 font-medium",children:"High-Performance Particle Image Velocimetry Processing"}),(0,s.jsx)("p",{className:"text-xl md:text-2xl text-gray-300 max-w-3xl mx-auto leading-relaxed",children:"Accelerate your PIV analysis with our cluster optimised Python and C wrapped algorithms."})]}),(0,s.jsxs)(u.E.div,{initial:{opacity:0,y:30},animate:{opacity:1,y:0},transition:{duration:.8,delay:.3},className:"flex flex-col sm:flex-row gap-4 justify-center mb-12",children:[(0,s.jsxs)("button",{onClick:()=>{if(t)t();else try{localStorage.setItem("pivtools_seen_hero","true")}catch(e){}},className:"bg-soton-gold text-soton-darkblue px-8 py-4 rounded-lg font-semibold text-lg hover:bg-yellow-400 transition-colors duration-200 flex items-center gap-2 justify-center",children:[(0,s.jsx)(m.Z,{size:20}),"Get Started"]}),(0,s.jsxs)("button",{className:"border-2 border-white text-white px-8 py-4 rounded-lg font-semibold text-lg hover:bg-white hover:text-soton-darkblue transition-colors duration-200 flex items-center gap-2 justify-center",children:[(0,s.jsx)(h.Z,{size:20}),"Watch Demo"]})]}),(0,s.jsxs)(u.E.div,{initial:{opacity:0},animate:{opacity:1},transition:{duration:.8,delay:.6},className:"grid grid-cols-1 md:grid-cols-3 gap-8 mb-16",children:[(0,s.jsxs)("div",{className:"text-center",children:[(0,s.jsx)("div",{className:"text-4xl font-bold text-soton-gold mb-2",children:"10x"}),(0,s.jsx)("div",{className:"text-gray-300",children:"Faster Processing"})]}),(0,s.jsxs)("div",{className:"text-center",children:[(0,s.jsx)("div",{className:"text-4xl font-bold text-soton-gold mb-2",children:"2D & 3D"}),(0,s.jsx)("div",{className:"text-gray-300",children:"PIV Analysis"})]}),(0,s.jsxs)("div",{className:"text-center",children:[(0,s.jsx)("div",{className:"text-4xl font-bold text-soton-gold mb-2",children:"100%"}),(0,s.jsx)("div",{className:"text-gray-300",children:"Open Source"})]})]}),(0,s.jsx)(u.E.div,{initial:{opacity:0,y:20},animate:{opacity:1,y:0},transition:{duration:.8,delay:.9},className:"flex justify-center",children:(0,s.jsx)("a",{href:"#features",className:"text-white hover:text-soton-gold transition-colors duration-200",children:(0,s.jsx)(x.Z,{size:32,className:"animate-bounce"})})})]}),a&&(0,s.jsx)("div",{className:"absolute inset-0 overflow-hidden pointer-events-none",children:[...Array(100)].map((e,t)=>(0,s.jsx)(u.E.div,{className:"absolute w-2 h-2 bg-soton-gold rounded-full opacity-60",animate:{y:[0,-100,0],x:[0,100*Math.random()-50,0],opacity:[.6,.2,.6]},transition:{duration:3+2*Math.random(),repeat:1/0,delay:5*Math.random()},style:{left:"".concat(100*Math.random(),"%"),top:"".concat(100*Math.random(),"%")}},t))})]})}var p=a(1312),f=a(3448);let v=p.fC,j=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)(p.aV,{ref:t,className:(0,f.cn)("inline-flex h-10 items-center justify-center rounded-md bg-gray-100 p-1 text-gray-500",a),...r})});j.displayName=p.aV.displayName;let b=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)(p.xz,{ref:t,className:(0,f.cn)("inline-flex items-center justify-center whitespace-nowrap rounded-sm px-3 py-1.5 text-sm font-medium ring-offset-background transition-all focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 disabled:pointer-events-none disabled:opacity-50 data-[state=active]:bg-background data-[state=active]:text-foreground data-[state=active]:shadow-sm",a),...r})});b.displayName=p.xz.displayName;let y=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)(p.VY,{ref:t,className:(0,f.cn)("mt-2 ring-offset-background focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2",a),...r})});y.displayName=p.VY.displayName;let N=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)("div",{ref:t,className:(0,f.cn)("rounded-lg border bg-card text-card-foreground shadow-sm",a),...r})});N.displayName="Card";let w=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)("div",{ref:t,className:(0,f.cn)("flex flex-col space-y-1.5 p-6",a),...r})});w.displayName="CardHeader";let _=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)("h3",{ref:t,className:(0,f.cn)("text-lg font-semibold leading-none tracking-tight",a),...r})});_.displayName="CardTitle";let S=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)("p",{ref:t,className:(0,f.cn)("text-sm text-muted-foreground",a),...r})});S.displayName="CardDescription";let k=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)("div",{ref:t,className:(0,f.cn)("p-6 pt-0",a),...r})});k.displayName="CardContent",r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)("div",{ref:t,className:(0,f.cn)("flex items-center p-6 pt-0",a),...r})}).displayName="CardFooter";var C=a(7053),P=a(535);let M=(0,P.j)("inline-flex items-center justify-center whitespace-nowrap rounded-md text-sm font-medium transition-colors focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:pointer-events-none disabled:opacity-50",{variants:{variant:{default:"bg-primary text-primary-foreground shadow hover:bg-primary/90",destructive:"bg-destructive text-destructive-foreground shadow-sm hover:bg-destructive/90",outline:"border border-input bg-background shadow-sm hover:bg-accent hover:text-accent-foreground",secondary:"bg-secondary text-secondary-foreground shadow-sm hover:bg-secondary/80",ghost:"hover:bg-accent hover:text-accent-foreground",link:"text-primary underline-offset-4 hover:underline"},size:{default:"h-9 px-4 py-2",sm:"h-8 rounded-md px-3 text-xs",lg:"h-10 rounded-md px-8",icon:"h-9 w-9"}},defaultVariants:{variant:"default",size:"default"}}),E=r.forwardRef((e,t)=>{let{className:a,variant:r,size:l,asChild:n=!1,...i}=e,o=n?C.g7:"button";return(0,s.jsx)(o,{className:(0,f.cn)(M({variant:r,size:l,className:a})),ref:t,...i})});E.displayName="Button";let F=r.forwardRef((e,t)=>{let{className:a,type:r,...l}=e;return(0,s.jsx)("input",{type:r,className:(0,f.cn)("flex h-9 w-full rounded-md border border-input bg-transparent px-3 py-1 text-sm shadow-sm transition-colors file:border-0 file:bg-transparent file:text-sm file:font-medium placeholder:text-muted-foreground focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-ring disabled:cursor-not-allowed disabled:opacity-50",a),ref:t,...l})});F.displayName="Input";var T=a(6394);let I=(0,P.j)("text-sm font-medium leading-none peer-disabled:cursor-not-allowed peer-disabled:opacity-70"),R=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)(T.f,{ref:t,className:(0,f.cn)(I(),a),...r})});R.displayName=T.f.displayName;var A=a(9930),z=a(2135),O=a(401);let D=A.fC;A.ZA;let V=A.B4,L=r.forwardRef((e,t)=>{let{className:a,children:r,...l}=e;return(0,s.jsxs)(A.xz,{ref:t,className:(0,f.cn)("flex h-9 w-full items-center justify-between rounded-md border border-input bg-transparent px-3 py-2 text-sm shadow-sm ring-offset-background placeholder:text-muted-foreground focus:outline-none focus:ring-1 focus:ring-ring disabled:cursor-not-allowed disabled:opacity-50 [&>span]:line-clamp-1",a),...l,children:[r,(0,s.jsx)(A.JO,{asChild:!0,children:(0,s.jsx)(x.Z,{className:"h-4 w-4 opacity-50"})})]})});L.displayName=A.xz.displayName;let B=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)(A.u_,{ref:t,className:(0,f.cn)("flex cursor-default items-center justify-center py-1",a),...r,children:(0,s.jsx)(z.Z,{className:"h-4 w-4"})})});B.displayName=A.u_.displayName;let U=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)(A.$G,{ref:t,className:(0,f.cn)("flex cursor-default items-center justify-center py-1",a),...r,children:(0,s.jsx)(x.Z,{className:"h-4 w-4"})})});U.displayName=A.$G.displayName;let W=r.forwardRef((e,t)=>{let{className:a,children:r,position:l="popper",...n}=e;return(0,s.jsx)(A.h_,{children:(0,s.jsxs)(A.VY,{ref:t,className:(0,f.cn)("relative z-50 max-h-96 min-w-[8rem] overflow-hidden rounded-md border bg-popover text-popover-foreground shadow-md data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[side=bottom]:slide-in-from-top-2 data-[side=left]:slide-in-from-right-2 data-[side=right]:slide-in-from-left-2 data-[side=top]:slide-in-from-bottom-2","popper"===l&&"data-[side=bottom]:translate-y-1 data-[side=left]:-translate-x-1 data-[side=right]:translate-x-1 data-[side=top]:-translate-y-1",a),position:l,...n,children:[(0,s.jsx)(B,{}),(0,s.jsx)(A.l_,{className:(0,f.cn)("p-1","popper"===l&&"h-[var(--radix-select-trigger-height)] w-full min-w-[var(--radix-select-trigger-width)]"),children:r}),(0,s.jsx)(U,{})]})})});W.displayName=A.VY.displayName,r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)(A.__,{ref:t,className:(0,f.cn)("py-1.5 pl-8 pr-2 text-sm font-semibold",a),...r})}).displayName=A.__.displayName;let Z=r.forwardRef((e,t)=>{let{className:a,children:r,...l}=e;return(0,s.jsxs)(A.ck,{ref:t,className:(0,f.cn)("relative flex w-full cursor-default select-none items-center rounded-sm py-1.5 pl-8 pr-2 text-sm outline-none focus:bg-accent focus:text-accent-foreground data-[disabled]:pointer-events-none data-[disabled]:opacity-50",a),...l,children:[(0,s.jsx)("span",{className:"absolute left-2 flex h-3.5 w-3.5 items-center justify-center",children:(0,s.jsx)(A.wU,{children:(0,s.jsx)(O.Z,{className:"h-4 w-4"})})}),(0,s.jsx)(A.eT,{children:r})]})});Z.displayName=A.ck.displayName,r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)(A.Z0,{ref:t,className:(0,f.cn)("-mx-1 my-1 h-px bg-muted",a),...r})}).displayName=A.Z0.displayName;var Y=a(9397),G=a(3581),J=a(3229),X=a(4822),H=a(407),K=a(1671),$=a(3577),q=a(4428);function Q(e,t){if(e.length!==t.length)return!1;for(let a=0;a<e.length;a++)if(e[a].windowX!==t[a].windowX||e[a].windowY!==t[a].windowY||e[a].overlap!==t[a].overlap||e[a].store!==t[a].store)return!1;return!0}var ee=a(721);let et=r.forwardRef((e,t)=>{let{className:a,...r}=e;return(0,s.jsx)(ee.fC,{className:(0,f.cn)("peer inline-flex h-[24px] w-[44px] shrink-0 cursor-pointer items-center rounded-full border-2 border-gray-200 transition-colors focus-visible:outline-none focus-visible:ring-2 focus-visible:ring-ring focus-visible:ring-offset-2 focus-visible:ring-offset-background disabled:cursor-not-allowed disabled:opacity-50",r.checked?"bg-[#003C71] !important":"bg-gray-200",a),style:{backgroundColor:r.checked?"#003C71":""},...r,ref:t,children:(0,s.jsx)(ee.bU,{className:(0,f.cn)("pointer-events-none block h-5 w-5 rounded-full bg-white shadow-md ring-1 ring-gray-300 transition-transform data-[state=checked]:translate-x-5 data-[state=unchecked]:translate-x-0")})})});function ea(e){let t=parseInt(e.replace("#",""),16);return[t>>16&255,t>>8&255,255&t]}function es(e,t){let a;let s=e.length,r=Math.min(s,2e5);if(r===s)a=Array.from(e);else{a=[];let t=Math.max(1,Math.floor(s/r));for(let l=0;l<s&&a.length<r;l+=t)a.push(e[l])}a.sort((e,t)=>e-t);let l=Math.min(a.length-1,Math.max(0,Math.floor(t/100*a.length)));return a[l]}function er(e,t){let a;let s=function(e){let t=window.atob(e),a=t.length,s=new Uint8Array(a);for(let e=0;e<a;e++)s[e]=t.charCodeAt(e);return s.buffer}(e);return a="uint16"===t?new Uint16Array(s):new Uint8Array(s),console.log("[decodeTypedArray] base64 length:",e.length,"decoded array length:",a.length,"sample:",a.slice(0,8)),a}function el(e,t,a,s){let[l,n]=(0,r.useState)(!1),[i,o]=(0,r.useState)(null),[c,d]=(0,r.useState)(null),[u,m]=(0,r.useState)(null),[h,x]=(0,r.useState)(null),[g,p]=(0,r.useState)(null),[f,v]=(0,r.useState)(null),[j,b]=(0,r.useState)(0),[y,N]=(0,r.useState)(255),w=async e=>new Promise((t,a)=>{let s=new Image;s.onload=()=>{try{let e=document.createElement("canvas"),a=e.getContext("2d");if(!a)throw Error("Canvas context not available");e.width=s.width,e.height=s.height,a.drawImage(s,0,0);let r=a.getImageData(0,0,s.width,s.height).data,l=[];for(let e=0;e<r.length;e+=4){let t=r[e],a=r[e+1],s=r[e+2],n=Math.round(.299*t+.587*a+.114*s);l.push(n)}l.sort((e,t)=>e-t);let n=Math.floor(.01*l.length),i=Math.floor(.99*l.length),o=l[n],c=l[i];t({vmin:o,vmax:c})}catch(e){a(e)}},s.onerror=()=>a(Error("Failed to load PNG for analysis")),s.src=e}),_=async()=>{if(a){n(!0),o(null),d(null),m(null),x(null),p(null);try{var r;let l=parseInt(a.replace(/\D/g,""),10),n="".concat(e,"/get_frame_pair?camera=").concat(l,"&idx=").concat(s,"&source_path_idx=").concat(t),i=await fetch(n),c=await i.json();if("".concat(t,"-").concat(a,"-").concat(s),!i.ok)throw Error(c.error||"Image pair not found (frame ".concat(s,")"));if((null===(r=c.meta)||void 0===r?void 0:r.width)&&(c.A_raw||c.B_raw)){let e=c.meta;v({bitDepth:e.bitDepth,dtype:e.dtype,dims:{w:e.width,h:e.height}});let t=null,a=null;if(c.A_raw)try{t={...e,data:er(c.A_raw,e.dtype)}}catch(a){let e="object"==typeof a&&null!==a&&"message"in a?a.message:String(a);o("Failed to decode A_raw: "+e),t=null}if(c.B_raw)try{a={...e,data:er(c.B_raw,e.dtype)}}catch(t){let e="object"==typeof t&&null!==t&&"message"in t?t.message:String(t);o("Failed to decode B_raw: "+e),a=null}if(x(t),p(a),t&&t.data){let e=Math.floor(es(t.data,1)),a=Math.ceil(es(t.data,99));b(e),N(a)}}else{v({bitDepth:8,dtype:"uint8"}),d(c.A),m(c.B);try{if(c.A){let e="data:image/png;base64,".concat(c.A),{vmin:t,vmax:a}=await w(e);b(t),N(a)}else b(0),N(255)}catch(e){console.warn("[ImagePairViewer] PNG auto-contrast analysis failed, using default 0-255:",e),b(0),N(255)}console.warn("[ImagePairViewer] No raw image data or meta in backend response.")}}catch(e){o(e.message),console.error("[ImagePairViewer] Error fetching image pair:",e)}finally{n(!1)}}};return(0,r.useEffect)(()=>{_()},[e,t,a,s]),{loading:l,error:i,imgA:c,imgB:u,imgARaw:h,imgBRaw:g,metadata:f,vmin:j,setVmin:b,vmax:y,setVmax:N,reload:_}}et.displayName=ee.fC.displayName;let en=[{type:"time",name:"Time Filter",description:"Subtract local minimum across time for each pixel",category:"batch",parameters:[]},{type:"pod",name:"POD Filter",description:"Proper Orthogonal Decomposition - removes coherent structures",category:"batch",parameters:[]},{type:"clip",name:"Clip Filter",description:"Clip pixel intensities to threshold or median-based range",category:"spatial",parameters:[{name:"Auto-threshold (std devs)",key:"n",type:"number",default:2,min:.5,max:5,step:.1,description:"Number of standard deviations for auto-threshold"}]},{type:"invert",name:"Invert",description:"Invert image intensities",category:"spatial",parameters:[{name:"Offset",key:"offset",type:"number",default:255,min:0,max:65535,step:1,description:"Scalar value to subtract pixels from"}]},{type:"gaussian",name:"Gaussian Blur",description:"Gaussian smoothing filter",category:"spatial",parameters:[{name:"Sigma",key:"sigma",type:"number",default:1,min:.1,max:10,step:.1,description:"Standard deviation for Gaussian kernel"}]},{type:"median",name:"Median Filter",description:"Median filtering for noise reduction",category:"spatial",parameters:[{name:"Kernel Size",key:"size",type:"tuple",default:[5,5],min:3,max:21,step:2,description:"Kernel size [height, width] (odd numbers only)"}]},{type:"lmax",name:"Local Maximum",description:"Morphological dilation using local maximum",category:"spatial",parameters:[{name:"Kernel Size",key:"size",type:"tuple",default:[7,7],min:3,max:21,step:2,description:"Kernel size [height, width]"}]},{type:"maxnorm",name:"Max-Norm",description:"Normalize by local max-min contrast with smoothing",category:"spatial",parameters:[{name:"Kernel Size",key:"size",type:"tuple",default:[7,7],min:3,max:21,step:2,description:"Kernel size [height, width]"},{name:"Max Gain",key:"max_gain",type:"number",default:1,min:.1,max:10,step:.1,description:"Maximum normalization gain"}]},{type:"norm",name:"Normalization",description:"Normalize by subtracting local min and dividing by range",category:"spatial",parameters:[{name:"Kernel Size",key:"size",type:"tuple",default:[7,7],min:3,max:21,step:2,description:"Kernel size [height, width]"},{name:"Max Gain",key:"max_gain",type:"number",default:1,min:.1,max:10,step:.1,description:"Maximum normalization gain"}]},{type:"transpose",name:"Transpose",description:"Transpose images (swap height and width dimensions)",category:"spatial",parameters:[]},{type:"sbg",name:"Subtract Background",description:"Subtract a background image",category:"spatial",parameters:[{name:"Background Path",key:"bg",type:"text",default:null,description:"Path to background image (leave empty for none)"}]},{type:"levelize",name:"Levelize",description:"Normalize by dividing by white reference image",category:"spatial",parameters:[{name:"White Reference Path",key:"white",type:"text",default:null,description:"Path to white reference image"}]}];function ei(e){var t;let{filter:a,index:r,onUpdate:l,onRemove:n,onMoveUp:i,onMoveDown:c,isFirst:d,isLast:u}=e,m=(t=a.type,en.find(e=>e.type===t));return m?(0,s.jsxs)(N,{className:"p-3 space-y-2",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsxs)("span",{className:"text-sm font-semibold",children:[r+1,". ",m.name]}),(0,s.jsx)("span",{className:"text-xs px-2 py-0.5 rounded bg-muted",children:m.category})]}),(0,s.jsxs)("div",{className:"flex gap-1",children:[(0,s.jsx)(E,{size:"sm",variant:"ghost",onClick:()=>i(r),disabled:d,className:"h-7 w-7 p-0",children:(0,s.jsx)(z.Z,{className:"h-4 w-4"})}),(0,s.jsx)(E,{size:"sm",variant:"ghost",onClick:()=>c(r),disabled:u,className:"h-7 w-7 p-0",children:(0,s.jsx)(x.Z,{className:"h-4 w-4"})}),(0,s.jsx)(E,{size:"sm",variant:"ghost",onClick:()=>n(r),className:"h-7 w-7 p-0 text-destructive hover:text-destructive",children:(0,s.jsx)(o.Z,{className:"h-4 w-4"})})]})]}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground",children:m.description}),m.parameters.length>0&&(0,s.jsx)("div",{className:"space-y-2 pt-2 border-t",children:m.parameters.map(e=>{let t=a[e.key];switch(e.type){case"number":return(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:e.name}),(0,s.jsx)(F,{type:"number",value:null!=t?t:e.default,onChange:t=>l(r,{[e.key]:parseFloat(t.target.value)}),min:e.min,max:e.max,step:e.step,className:"h-8 text-xs"}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground",children:e.description})]},e.key);case"tuple":let n=null!=t?t:e.default;return(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:e.name}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(F,{type:"number",value:n[0],onChange:t=>{let a=parseInt(t.target.value);l(r,{[e.key]:[a,n[1]]})},min:e.min,max:e.max,step:e.step,className:"h-8 text-xs",placeholder:"H"}),(0,s.jsx)(F,{type:"number",value:n[1],onChange:t=>{let a=parseInt(t.target.value);l(r,{[e.key]:[n[0],a]})},min:e.min,max:e.max,step:e.step,className:"h-8 text-xs",placeholder:"W"})]}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground",children:e.description})]},e.key);case"text":return(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:e.name}),(0,s.jsx)(F,{type:"text",value:String(null!=t?t:""),onChange:t=>l(r,{[e.key]:t.target.value||null}),className:"h-8 text-xs",placeholder:e.description}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground",children:e.description})]},e.key);default:return null}})})]}):null}function eo(e){let{onAddFilter:t}=e,[a,l]=r.useState("gaussian");return(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsxs)(D,{value:a,onValueChange:e=>l(e),children:[(0,s.jsx)(L,{className:"w-64",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)("div",{className:"px-2 py-1 text-xs font-semibold text-muted-foreground",children:"Batch Filters"}),en.filter(e=>"batch"===e.category).map(e=>(0,s.jsx)(Z,{value:e.type,children:e.name},e.type)),(0,s.jsx)("div",{className:"px-2 py-1 text-xs font-semibold text-muted-foreground border-t mt-1",children:"Spatial Filters"}),en.filter(e=>"spatial"===e.category).map(e=>(0,s.jsx)(Z,{value:e.type,children:e.name},e.type))]})]}),(0,s.jsx)(E,{onClick:()=>{t(a)},size:"sm",children:"Add Filter"})]})}function ec(e){let{raw:t,src:a,error:l,vmin:n,vmax:i,colormap:o,title:c,useGrid:d,gridSize:u=16,zoomLevel:m,panX:h,panY:x,onZoomChange:g}=e,p=(0,r.useRef)(null),f=(0,r.useRef)(null),[v,j]=(0,r.useState)(null),b=(0,r.useMemo)(()=>(function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:256,a=new Uint8ClampedArray(3*t);if("gray"===e){for(let e=0;e<t;e++)a[3*e]=e,a[3*e+1]=e,a[3*e+2]=e;return a}let s=["#440154","#414487","#2A788E","#22A884","#7AD151","#FDE725"].map(ea);for(let e=0;e<t;e++){var r,l,n;let i=e/(t-1),o=(s.length-1)*i,c=Math.floor(o),d=Math.min(c+1,s.length-1),u=o-c,m=Math.round((r=s[c][0])+(s[d][0]-r)*u),h=Math.round((l=s[c][1])+(s[d][1]-l)*u),x=Math.round((n=s[c][2])+(s[d][2]-n)*u);a[3*e]=m,a[3*e+1]=h,a[3*e+2]=x}return a})(o),[o]),y=null!=m?m:1,N={x:null!=h?h:0,y:null!=x?x:0},[w,_]=(0,r.useState)(!1),S=(0,r.useRef)({x:0,y:0}),[k,C]=(0,r.useState)(!1),[P,M]=(0,r.useState)(!1),F=(0,r.useRef)({x:0,y:0}),[T,I]=(0,r.useState)(null);(0,r.useEffect)(()=>{if(!a){j(null);return}let e=new Image;e.onload=()=>j(e),e.src="data:image/png;base64,".concat(a)},[a]),(0,r.useEffect)(()=>{let e=f.current,a=null==e?void 0:e.getContext("2d");if(a&&e){if(null==t?void 0:t.data){let{width:s,height:r,data:l}=t;e.width=s,e.height=r;let o=new Uint8ClampedArray(s*r*4),c=Math.max(1e-9,i-n);for(let e=0;e<s*r;e++){let t=Math.floor(255*Math.max(0,Math.min(1,(Number(l[e])-n)/c))),a=4*e;[o[a],o[a+1],o[a+2]]=[b[3*t],b[3*t+1],b[3*t+2]],o[a+3]=255}a.putImageData(new ImageData(o,s,r),0,0)}else if(v){e.width=v.naturalWidth,e.height=v.naturalHeight,a.drawImage(v,0,0);try{let t=a.getImageData(0,0,e.width,e.height).data,s=new Uint8ClampedArray(t.length),r=Math.max(1e-9,i-n);for(let e=0;e<t.length;e+=4){let a=t[e],l=Math.max(0,Math.min(1,(a-n)/r)),i=Math.floor(255*l);s[e]=b[3*i],s[e+1]=b[3*i+1],s[e+2]=b[3*i+2],s[e+3]=255}a.putImageData(new ImageData(s,e.width,e.height),0,0)}catch(t){a.clearRect(0,0,e.width,e.height)}}else a.clearRect(0,0,e.width,e.height)}},[t,v,n,i,b]);let R=()=>{let e=p.current,a=(null==t?void 0:t.width)||(null==v?void 0:v.naturalWidth),s=(null==t?void 0:t.height)||(null==v?void 0:v.naturalHeight);if(!e||!a||!s)return;let r=.98*Math.min(e.clientWidth/a,e.clientHeight/s),l={x:(e.clientWidth-a*r)/2,y:(e.clientHeight-s*r)/2};null==g||g(r,l.x,l.y)},A=(0,r.useRef)(!1);(0,r.useEffect)(()=>{!A.current&&(t||v)&&(R(),A.current=!0)},[t,v]);let z=()=>{if(P&&T&&T.w>10&&T.h>10){let e=p.current;if(!e)return;let t=Math.min(e.clientWidth/T.w,e.clientHeight/T.h)*y,a={x:N.x-T.x*(t/y-1),y:N.y-T.y*(t/y-1)};null==g||g(t,a.x,a.y),C(!1)}_(!1),M(!1),I(null)};return(0,s.jsxs)("div",{className:"flex flex-col h-full",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,s.jsx)("span",{className:"text-sm font-medium",children:c}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(E,{variant:k?"default":"outline",size:"sm",onClick:()=>C(!k),children:"Box Zoom"}),(0,s.jsx)(E,{variant:"outline",size:"sm",onClick:R,children:"Fit"})]})]}),(0,s.jsx)("div",{ref:p,className:"relative w-full flex-1 bg-black/80 rounded-md overflow-hidden border",style:{cursor:k?"crosshair":w?"grabbing":"grab"},onMouseDown:e=>{var t;let a=null===(t=p.current)||void 0===t?void 0:t.getBoundingClientRect();if(!a)return;let s=e.clientX-a.left,r=e.clientY-a.top;k?(M(!0),F.current={x:s,y:r},I({x:s,y:r,w:0,h:0})):(_(!0),S.current={x:e.clientX,y:e.clientY})},onMouseMove:e=>{var t;let a=null===(t=p.current)||void 0===t?void 0:t.getBoundingClientRect();if(!a)return;if(P){let t=e.clientX-a.left,s=e.clientY-a.top;I({x:Math.min(F.current.x,t),y:Math.min(F.current.y,s),w:Math.abs(t-F.current.x),h:Math.abs(s-F.current.y)});return}if(!w)return;let s=e.clientX-S.current.x,r=e.clientY-S.current.y;S.current={x:e.clientX,y:e.clientY},null==g||g(y,N.x+s,N.y+r)},onMouseUp:z,onMouseLeave:z,children:l?(0,s.jsx)("div",{className:"absolute inset-0 flex items-center justify-center text-red-400 p-4",children:l}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("div",{style:{transform:"translate(".concat(N.x,"px, ").concat(N.y,"px) scale(").concat(y,")"),transformOrigin:"0 0"},children:(0,s.jsx)("canvas",{ref:f})}),d&&(0,s.jsx)("div",{className:"absolute inset-0 pointer-events-none",style:{backgroundSize:"".concat(u*y,"px ").concat(u*y,"px"),backgroundImage:"linear-gradient(to right, rgba(0,150,255,0.2) 1px, transparent 1px),\n linear-gradient(to bottom, rgba(0,150,255,0.2) 1px, transparent 1px)"}}),T&&(0,s.jsx)("div",{className:"absolute pointer-events-none border-2 border-dashed border-white bg-blue-500/20",style:{left:T.x,top:T.y,width:T.w,height:T.h}})]})})]})}var ed=a(8873);let eu=e=>{let{className:t=""}=e;return(0,s.jsx)("div",{className:"flex items-center justify-center ".concat(t),children:(0,s.jsxs)("div",{className:"relative",children:[(0,s.jsx)("div",{className:"w-8 h-8 border-4 border-gray-200 border-t-blue-500 rounded-full animate-spin"}),(0,s.jsx)("div",{className:"absolute inset-0 w-8 h-8 border-4 border-transparent border-t-blue-300 rounded-full animate-spin",style:{animationDirection:"reverse",animationDuration:"1.5s"}})]})})};function em(e){var t;let{backendUrl:a="/backend",config:l,onFiltersChange:n}=e,[i,o]=(0,r.useState)(0),[c,d]=(0,r.useState)(1),[u,m]=(0,r.useState)(1),[h,x]=(0,r.useState)("gray"),[g,p]=(0,r.useState)(!1),[v,j]=(0,r.useState)(16),[b,y]=(0,r.useState)("A"),[C,P]=(0,r.useState)("A"),[M,T]=(0,r.useState)(0),[I,A]=(0,r.useState)(255),[z,O]=(0,r.useState)(0),[B,U]=(0,r.useState)(255),[Y,G]=(0,r.useState)(!0),[J,X]=(0,r.useState)(!0),[H,K]=(0,r.useState)(!1),[$,q]=(0,r.useState)(!1),[Q,ee]=(0,r.useState)(1),[ea,es]=(0,r.useState)(0),[er,en]=(0,r.useState)(0),[em,eh]=(0,r.useState)(!1),ex=(0,r.useRef)(null),eg=(0,r.useMemo)(()=>{var e;return(null==l?void 0:null===(e=l.images)||void 0===e?void 0:e.num_images)||100},[l]),[ep,ef]=(0,r.useState)(!1),{loading:ev,error:ej,imgARaw:eb,imgBRaw:ey,imgA:eN,imgB:ew,vmin:e_,vmax:eS,metadata:ek}=el(a,i,"Cam".concat(c),u),{filters:eC,setFilters:eP,addFilter:eM,removeFilter:eE,runProcessing:eF,autoProcessFrame:eT,procLoading:eI,procImgA:eR,procImgB:eA,fetchProcessed:ez,updateFilter:eO,moveFilter:eD,downloadImage:eV}=function(e){let[t,a]=(0,r.useState)([]),[s,l]=(0,r.useState)(!1),[n,i]=(0,r.useState)(null),[o,c]=(0,r.useState)(null),d=(0,r.useCallback)(async(a,s,r)=>{l(!0),i(null),c(null);try{var n,o,d,u;let l=parseInt(a.replace(/\D/g,""),10);if(t.some(e=>"time"===e.type||"pod"===e.type)){await fetch("".concat(e,"/filter"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({camera:l,start_idx:s,count:1,filters:t,source_path_idx:r})});let a=0,d=!1;for(;a<60&&!d;){await new Promise(e=>setTimeout(e,1e3));let t=await fetch("".concat(e,"/status"));if(!(await t.json()).processing){d=!0;break}a++}if(!d)throw Error("Processing timeout - batch filter took too long");let u=new URLSearchParams({type:"processed",frame:String(s),camera:String(l),source_path_idx:String(r)}),m=await fetch("".concat(e,"/get_processed_pair?").concat(u.toString())),h=await m.json();if(!m.ok)throw Error(h.error||"Failed to fetch processed pair");i(null!==(n=h.A)&&void 0!==n?n:null),c(null!==(o=h.B)&&void 0!==o?o:null)}else{let a=await fetch("".concat(e,"/filter_single_frame"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({camera:l,frame_idx:s,filters:t,source_path_idx:r})}),n=await a.json();if(!a.ok)throw Error(n.error||"Failed to process frame");i(null!==(d=n.A)&&void 0!==d?d:null),c(null!==(u=n.B)&&void 0!==u?u:null)}}catch(e){console.error("Processing failed:",e)}finally{l(!1)}},[e,t]),u=(0,r.useCallback)(async(a,s,r)=>{i(null),c(null);try{var l,n,o,d;let u=parseInt(a.replace(/\D/g,""),10);if(t.some(e=>"time"===e.type||"pod"===e.type)){let t=new URLSearchParams({type:"processed",frame:String(s),camera:String(u),source_path_idx:String(r)}),a=await fetch("".concat(e,"/get_processed_pair?").concat(t.toString()));if(a.ok){let e=await a.json();i(null!==(l=e.A)&&void 0!==l?l:null),c(null!==(n=e.B)&&void 0!==n?n:null)}else i(null),c(null)}else{let a=await fetch("".concat(e,"/filter_single_frame"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({camera:u,frame_idx:s,filters:t,source_path_idx:r})}),l=await a.json();if(!a.ok)throw Error(l.error||"Failed to process frame");i(null!==(o=l.A)&&void 0!==o?o:null),c(null!==(d=l.B)&&void 0!==d?d:null)}}catch(e){console.error("Auto-processing failed:",e),i(null),c(null)}},[e,t]),m=(0,r.useCallback)(async(t,a,s)=>{try{let n=parseInt(t.replace(/\D/g,""),10),o=new URLSearchParams({type:"processed",frame:String(a),camera:String(n),source_path_idx:String(s)}),d=await fetch("".concat(e,"/get_processed_pair?").concat(o.toString()));if(d.ok){var r,l;let e=await d.json();i(null!==(r=e.A)&&void 0!==r?r:null),c(null!==(l=e.B)&&void 0!==l?l:null)}else i(null),c(null)}catch(e){i(null),c(null)}},[e]);return(0,r.useEffect)(()=>{i(null),c(null)},[t]),{filters:t,setFilters:a,addFilter:function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:{},s={time:{},pod:{},clip:{n:2},invert:{offset:255},levelize:{white:null},lmax:{size:[7,7]},maxnorm:{size:[7,7],max_gain:1},median:{size:[5,5]},norm:{size:[7,7],max_gain:1},sbg:{bg:null},transpose:{},gaussian:{sigma:1}};a(a=>[...a,{type:e,...s[e],...t}])},updateFilter:(e,t)=>a(a=>a.map((a,s)=>s===e?{...a,...t}:a)),removeFilter:e=>a(t=>t.filter((t,a)=>a!==e)),moveFilter:(e,t)=>{a(a=>{let s=[...a],r="up"===t?e-1:e+1;return r<0||r>=a.length?a:([s[e],s[r]]=[s[r],s[e]],s)})},runProcessing:d,autoProcessFrame:u,procLoading:s,procImgA:n,procImgB:o,fetchProcessed:m,downloadImage:(0,r.useCallback)(async(t,a,s,r,l)=>{try{let n=await fetch("".concat(e,"/download_image"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({type:t,frame:a,data:s,frame_idx:r,camera:l})});if(!n.ok)throw Error("Download failed");let i=await n.blob(),o=window.URL.createObjectURL(i),c=document.createElement("a");c.href=o,c.download="Cam".concat(l,"_frame").concat(r.toString().padStart(5,"0"),"_").concat(a,"_").concat(t,".png"),document.body.appendChild(c),c.click(),document.body.removeChild(c),window.URL.revokeObjectURL(o)}catch(e){console.error("Download failed:",e)}},[e])}}(a),eL=(0,r.useMemo)(()=>{var e;return(null==l?void 0:null===(e=l.paths)||void 0===e?void 0:e.camera_numbers)||[]},[null==l?void 0:null===(t=l.paths)||void 0===t?void 0:t.camera_numbers]);(0,r.useEffect)(()=>{eL.length>0&&d(eL[0])},[eL]),(0,r.useEffect)(()=>{(null==l?void 0:l.filters)&&eP(l.filters.map(e=>{let t={type:e.type};return void 0!==e.size&&(t.size=e.size),void 0!==e.sigma&&(t.sigma=e.sigma),void 0!==e.threshold&&(t.threshold=e.threshold),void 0!==e.n&&(t.n=e.n),void 0!==e.offset&&(t.offset=e.offset),void 0!==e.white&&(t.white=e.white),void 0!==e.max_gain&&(t.max_gain=e.max_gain),void 0!==e.bg&&(t.bg=e.bg),t}))},[null==l?void 0:l.filters,eP]),(0,r.useEffect)(()=>{(async()=>{var e;if(!l||!c)return;let t=(null==l?void 0:null===(e=l.batches)||void 0===e?void 0:e.size)||30;try{console.log("Preloading ".concat(t," images for camera ").concat(c,", source ").concat(i)),await fetch("".concat(a,"/preload_images"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({camera:c,start_idx:1,count:t,source_path_idx:i})}),console.log("Preload request sent")}catch(e){console.warn("Failed to preload images:",e)}})()},[a,c,i,l]),(0,r.useEffect)(()=>{(async()=>{eC.length>0&&await eT("Cam".concat(c),u,i)})()},[c,u,i,eT,eC.length]),(0,r.useEffect)(()=>{Y&&K(!1)},[Y]),(0,r.useEffect)(()=>{J&&q(!1)},[J]),(0,r.useEffect)(()=>{K(!1),q(!1)},[i,c,u]),(0,r.useEffect)(()=>{Y&&!H&&(0!==e_||255!==eS)&&(T(e_),A(eS))},[e_,eS,Y,H]),(0,r.useEffect)(()=>{(async()=>{if(J&&!$&&(eR||eA))try{let e="A"===C?eR:eA;if(e){let t=new Image;t.onload=()=>{try{let e=document.createElement("canvas"),a=e.getContext("2d");if(!a)return;e.width=t.width,e.height=t.height,a.drawImage(t,0,0);let s=a.getImageData(0,0,t.width,t.height).data,r=[];for(let e=0;e<s.length;e+=4){let t=s[e],a=s[e+1],l=s[e+2],n=Math.round(.299*t+.587*a+.114*l);r.push(n)}r.sort((e,t)=>e-t);let l=Math.floor(.01*r.length),n=Math.floor(.99*r.length),i=r[l],o=r[n];O(i),U(o)}catch(e){console.warn("[ImagePairViewer] Processed image auto-contrast failed:",e)}},t.src="data:image/png;base64,".concat(e)}else O(0),U(255)}catch(e){console.warn("[ImagePairViewer] Processed image auto-contrast failed:",e),O(0),U(255)}})()},[eR,eA,C,J,$]),(0,r.useEffect)(()=>{var e;let t=async()=>{let e=eC.map(e=>{let t={type:e.type};return void 0!==e.size&&(t.size=e.size),void 0!==e.sigma&&(t.sigma=e.sigma),void 0!==e.threshold&&(t.threshold=e.threshold),void 0!==e.n&&(t.n=e.n),void 0!==e.offset&&(t.offset=e.offset),void 0!==e.white&&(t.white=e.white),void 0!==e.max_gain&&(t.max_gain=e.max_gain),void 0!==e.bg&&(t.bg=e.bg),t});try{await fetch("".concat(a,"/update_config"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({filters:e})})}catch(e){console.error("Failed to save filters to backend",e)}};(eC.length>0||(null==l?void 0:null===(e=l.filters)||void 0===e?void 0:e.length)>0)&&t()},[eC,a]);let eB=(0,r.useMemo)(()=>{var e;return(null==l?void 0:null===(e=l.paths)||void 0===e?void 0:e.source_paths)||[]},[l]),eU=(null==ek?void 0:ek.bitDepth)?2**ek.bitDepth-1:255;return(0,r.useEffect)(()=>{ef(!0)},[u,c,i]),(0,r.useEffect)(()=>{ev||ef(!1)},[ev]),(0,r.useEffect)(()=>(em?ex.current=setInterval(()=>{ep||m(e=>e>=eg?1:e+1)},1e3):ex.current&&(clearInterval(ex.current),ex.current=null),()=>{ex.current&&clearInterval(ex.current)}),[em,eg,ep]),(0,s.jsxs)(N,{children:[(0,s.jsxs)(w,{children:[(0,s.jsx)(_,{children:"Image Pre-Processing & Viewer"}),(0,s.jsx)(S,{children:"Load raw images, define a filter stack, and process them for inspection. All controls are in this panel."})]}),(0,s.jsxs)(k,{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"space-y-3 p-4 border rounded-lg",children:[(0,s.jsx)("h3",{className:"text-lg font-semibold",children:"Filter Stack"}),(0,s.jsx)(eo,{onAddFilter:eM}),(0,s.jsxs)("div",{className:"space-y-2 p-2 border rounded-md min-h-[100px] bg-muted/50",children:[0===eC.length&&(0,s.jsx)("p",{className:"text-sm text-muted-foreground",children:"No filters applied"}),eC.map((e,t)=>(0,s.jsx)(ei,{filter:e,index:t,onUpdate:eO,onRemove:eE,onMoveUp:()=>eD(t,"up"),onMoveDown:()=>eD(t,"down"),isFirst:0===t,isLast:t===eC.length-1},t))]}),(0,s.jsx)(E,{className:"w-full",onClick:()=>eF("Cam".concat(c),u,i),disabled:eI||0===eC.length,children:eI?"Processing...":"Apply Filters to Frame"})]}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4 items-end",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{children:"Source Path"}),(0,s.jsxs)(D,{value:String(i),onValueChange:e=>o(Number(e)),children:[(0,s.jsx)(L,{children:(0,s.jsx)(V,{})}),(0,s.jsx)(W,{children:eB.map((e,t)=>(0,s.jsx)(Z,{value:String(t),children:(0,f.E)(e)},t))})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{children:"Camera"}),(0,s.jsxs)(D,{value:String(c),onValueChange:e=>d(Number(e)),disabled:0===eL.length,children:[(0,s.jsx)(L,{children:(0,s.jsx)(V,{placeholder:0===eL.length?"No cameras":void 0})}),(0,s.jsx)(W,{children:0===eL.length?(0,s.jsx)(Z,{value:"none",disabled:!0,children:"No cameras available"}):eL.map(e=>(0,s.jsx)(Z,{value:String(e),children:e},e))})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{children:"Colormap"}),(0,s.jsxs)(D,{value:h,onValueChange:e=>x(e),children:[(0,s.jsx)(L,{children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"gray",children:"Grayscale"}),(0,s.jsx)(Z,{value:"viridis",children:"Viridis"})]})]})]})]}),(0,s.jsxs)("div",{className:"flex flex-col md:flex-row items-center justify-center gap-4 mt-4",children:[(0,s.jsx)("label",{htmlFor:"frame-slider",className:"text-sm font-medium",children:"Frame:"}),(0,s.jsxs)("div",{className:"flex items-center gap-3 w-full md:w-auto",children:[(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>m(Math.max(1,u-1)),disabled:u<=1,className:"rounded-full p-2",children:(0,s.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-4 h-4",viewBox:"0 0 20 20",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:(0,s.jsx)("path",{d:"M12 4L6 10l6 6"})})}),(0,s.jsx)("input",{id:"frame-slider",type:"range",min:1,max:eg,value:u,onChange:e=>m(Number(e.target.value)),className:"w-64"}),(0,s.jsx)(F,{id:"frame-input",type:"number",min:1,max:eg,value:u,onChange:e=>m(Math.max(1,Math.min(eg,Number(e.target.value||1)))),className:"w-24"}),(0,s.jsxs)("span",{className:"text-xs text-gray-500 whitespace-nowrap",children:[u," / ",eg]}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>m(Math.min(eg,u+1)),disabled:u>=eg,className:"rounded-full p-2",children:(0,s.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-4 h-4",viewBox:"0 0 20 20",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:(0,s.jsx)("path",{d:"M8 4l6 6-6 6"})})})]}),(0,s.jsx)(E,{size:"sm",variant:em?"default":"outline",onClick:()=>eh(!em),className:"flex items-center gap-1",children:em?(0,s.jsx)("span",{children:"❙❙ Pause"}):(0,s.jsx)("span",{children:"▶ Play"})})]}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"h-[480px] relative",children:[(0,s.jsx)(ec,{raw:"A"===b?eb:"B"===b?ey:void 0,src:"A"===b?eb?void 0:eN:"B"===b?ey?void 0:ew:void 0,error:ej,vmin:M,vmax:I,colormap:h,title:"Raw Image ".concat(b),useGrid:g,gridSize:v,zoomLevel:Q,panX:ea,panY:er,onZoomChange:(e,t,a)=>{ee(e),es(t),en(a)}}),ev&&(0,s.jsx)("div",{className:"absolute inset-0 bg-black bg-opacity-20 flex items-center justify-center rounded-lg",children:(0,s.jsx)(eu,{})})]}),(0,s.jsxs)("div",{className:"space-y-3 p-3 border rounded-md",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(R,{children:"View"}),(0,s.jsx)(E,{size:"sm",variant:"A"===b?"default":"outline",onClick:()=>y("A"),children:"A"}),(0,s.jsx)(E,{size:"sm",variant:"B"===b?"default":"outline",onClick:()=>y("B"),children:"B"}),(0,s.jsxs)("div",{className:"flex items-center gap-2 ml-auto",children:[(0,s.jsx)(et,{id:"raw-auto-scale",checked:Y,onCheckedChange:G}),(0,s.jsx)(R,{htmlFor:"raw-auto-scale",className:"text-sm",children:"Auto Scale"}),(0,s.jsx)(et,{id:"use-grid",checked:g,onCheckedChange:p}),(0,s.jsx)(R,{htmlFor:"use-grid",children:"Grid"})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(F,{type:"number",value:M,min:0,max:I,onChange:e=>{K(!0),G(!1);let t=Math.min(Number(e.target.value),I);T(t),t>I&&A(t)},className:"w-20 h-8"}),(0,s.jsx)("div",{className:"w-full min-w-0",children:(0,s.jsxs)(ed.fC,{className:"relative flex items-center select-none touch-none w-full h-5",min:0,max:eU,step:1,value:[M,I],onValueChange:e=>{let[t,a]=e;K(!0),G(!1),T(t),A(a)},children:[(0,s.jsx)(ed.fQ,{className:"bg-gray-200 relative grow rounded-full h-[3px]",children:(0,s.jsx)(ed.e6,{className:"absolute bg-blue-500 rounded-full h-full"})}),(0,s.jsx)(ed.bU,{className:"block w-5 h-5 bg-white rounded-[10px] border border-gray-300 hover:bg-gray-50 data-[disabled]:pointer-events-none data-[disabled]:opacity-50"}),(0,s.jsx)(ed.bU,{className:"block w-5 h-5 bg-white rounded-[10px] border border-gray-300 hover:bg-gray-50 data-[disabled]:pointer-events-none data-[disabled]:opacity-50"})]})}),(0,s.jsx)(F,{type:"number",value:I,min:M,max:eU,onChange:e=>{K(!0),G(!1);let t=Math.max(Number(e.target.value),M);A(t),t<M&&T(t)},className:"w-20 h-8"})]})]}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(E,{size:"sm",onClick:()=>eV("raw","A",eN||"",u,c),disabled:!eN&&!eb,children:"Download Raw A"}),(0,s.jsx)(E,{size:"sm",onClick:()=>eV("raw","B",ew||"",u,c),disabled:!ew&&!ey,children:"Download Raw B"})]})]}),(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"h-[480px] relative",children:[(0,s.jsx)(ec,{raw:void 0,src:"A"===C?eR:eA,vmin:z,vmax:B,colormap:h,title:"Processed Image ".concat(C),zoomLevel:Q,panX:ea,panY:er,onZoomChange:(e,t,a)=>{ee(e),es(t),en(a)}}),eI&&(0,s.jsx)("div",{className:"absolute inset-0 bg-black bg-opacity-20 flex items-center justify-center rounded-lg",children:(0,s.jsx)(eu,{})})]}),(0,s.jsxs)("div",{className:"space-y-3 p-3 border rounded-md",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(R,{children:"View"}),(0,s.jsx)(E,{size:"sm",variant:"A"===C?"default":"outline",onClick:()=>P("A"),children:"A"}),(0,s.jsx)(E,{size:"sm",variant:"B"===C?"default":"outline",onClick:()=>P("B"),children:"B"}),(0,s.jsxs)("div",{className:"flex items-center gap-2 ml-auto",children:[(0,s.jsx)(et,{id:"proc-auto-scale",checked:J,onCheckedChange:X}),(0,s.jsx)(R,{htmlFor:"proc-auto-scale",className:"text-sm",children:"Auto Scale"})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(F,{type:"number",value:z,min:0,max:B,onChange:e=>{q(!0),X(!1);let t=Math.min(Number(e.target.value),B);O(t),t>B&&U(t)},className:"w-20 h-8"}),(0,s.jsx)("div",{className:"w-full min-w-0",children:(0,s.jsxs)(ed.fC,{className:"relative flex items-center select-none touch-none w-full h-5",min:0,max:eU,step:1,value:[z,B],onValueChange:e=>{let[t,a]=e;q(!0),X(!1),O(t),U(a)},children:[(0,s.jsx)(ed.fQ,{className:"bg-gray-200 relative grow rounded-full h-[3px]",children:(0,s.jsx)(ed.e6,{className:"absolute bg-blue-500 rounded-full h-full"})}),(0,s.jsx)(ed.bU,{className:"block w-5 h-5 bg-white rounded-[10px] border border-gray-300 hover:bg-gray-50 focus:shadow-[0_0_0_5px] focus:shadow-blackA8 data-[disabled]:pointer-events-none data-[disabled]:opacity-50"}),(0,s.jsx)(ed.bU,{className:"block w-5 h-5 bg-white rounded-[10px] border border-gray-300 hover:bg-gray-50 focus:shadow-[0_0_0_5px] focus:shadow-blackA8 data-[disabled]:pointer-events-none data-[disabled]:opacity-50"})]})}),(0,s.jsx)(F,{type:"number",value:B,min:z,max:eU,onChange:e=>{q(!0),X(!1);let t=Math.max(Number(e.target.value),z);U(t),t<z&&O(t)},className:"w-20 h-8"})]})]}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(E,{size:"sm",onClick:()=>eV("processed","A",eR||"",u,c),disabled:!eR,children:"Download Processed A"}),(0,s.jsx)(E,{size:"sm",onClick:()=>eV("processed","B",eA||"",u,c),disabled:!eA,children:"Download Processed B"})]})]})]})]})]})}let eh=e=>{let{value:t,className:a=""}=e,r=Math.min(Math.max(Number(t)||0,0),100);return(0,s.jsxs)("div",{className:"relative w-full h-5 bg-gray-200 rounded-md overflow-hidden ".concat(a),role:"progressbar","aria-valuemin":0,"aria-valuemax":100,"aria-valuenow":Math.round(r),children:[(0,s.jsx)("div",{className:"absolute top-0 left-0 h-full bg-soton-blue transition-all duration-300",style:{width:"".concat(r,"%")}}),(0,s.jsxs)("span",{className:"absolute inset-0 flex items-center justify-center text-sm font-medium transition-colors duration-300 ".concat(r>=50?"text-white":"text-gray-900"),children:[Math.round(r),"%"]})]})},ex=e=>(null==e?void 0:e.replace(/\\/g,"/").split("/").filter(Boolean).pop())||e;var eg=e=>{let{config:t}=e,[a,l]=(0,r.useState)(0),[n,i]=(0,r.useState)("ux"),[o,c]=(0,r.useState)("default"),[d,u]=(0,r.useState)(1),[m,h]=(0,r.useState)(""),[x,g]=(0,r.useState)(""),[p,f]=(0,r.useState)(!0),[v,j]=(0,r.useState)(!0),[b,y]=(0,r.useState)(["ux","uy","nan_mask","peak_mag"]),[S,C]=(0,r.useState)(!1),P=(0,r.useMemo)(()=>{var e;return(null==t?void 0:null===(e=t.paths)||void 0===e?void 0:e.source_paths)||[]},[t]),{isLoading:M,isPolling:T,progress:I,statusImage:R,logs:A,run:z,cancel:O}=function(e){let[t,a]=(0,r.useState)(!1),[s,l]=(0,r.useState)(!1),[n,i]=(0,r.useState)(0),[o,c]=(0,r.useState)({src:null,error:null}),[d,u]=(0,r.useState)(null),[m,h]=(0,r.useState)(""),x=(0,r.useRef)(1),g=(0,r.useRef)(e),p=(0,r.useRef)(0),f=(0,r.useRef)([]);return(0,r.useEffect)(()=>{g.current=e},[e]),(0,r.useEffect)(()=>{if(!s)return;let e=async()=>{let e=g.current;try{let a=new URLSearchParams({basepath_idx:String(e.sourcePathIdx),var:e.varType,is_uncalibrated:"1"});"default"!==e.cmap&&a.set("cmap",e.cmap);let[s,r]=await Promise.all([fetch("/backend/get_uncalibrated_count?".concat(a.toString())),d?fetch("/backend/piv_logs?job_id=".concat(d)):Promise.resolve(null)]),n=0,o=[];if(s.ok){var t;let e=await s.json();n=Math.round(null!==(t=e.percent)&&void 0!==t?t:0),i(e=>Math.max(e,n)),n>=100&&l(!1),e.files&&Array.isArray(e.files)&&((o=e.files.map(e=>{let t=e.match(/(\d+)\.mat$/);return t?parseInt(t[1],10):null}).filter(e=>null!==e)).sort((e,t)=>e-t),f.current=o)}if(r&&r.ok){let e=await r.json();h(e.logs||"")}let u=Date.now(),m=u-p.current;if(e.showStatusImage&&o.length>0&&(0===p.current||m>=2e3)){let e;if(0===p.current)e=o[0],x.current=0;else{let t=x.current+1;t<o.length?(e=o[t],x.current=t):(e=o[o.length-1],x.current=o.length-1)}let t=new URLSearchParams(a);t.set("index",String(e));let s=await fetch("/backend/plot/get_uncalibrated_image?".concat(t.toString()));if(s.ok){let e=await s.json();e.image&&(c({src:e.image,error:null}),p.current=u)}else 404!==s.status&&c(e=>({...e,error:"Image Error: ".concat(s.statusText)}))}}catch(e){c(e=>({...e,src:null,error:"Polling failed. Check connection."}))}};e();let t=setInterval(e,500);return()=>clearInterval(t)},[s,d]),{isLoading:t,isPolling:s,progress:n,statusImage:o,logs:m,run:(0,r.useCallback)(async()=>{a(!0),c({src:null,error:null}),i(0),h(""),x.current=0,p.current=0,f.current=[],u(null);try{let e=await fetch("/backend/run_piv",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sourcePathIdx:g.current.sourcePathIdx})});if(!e.ok)throw Error("Failed to start PIV: ".concat(e.statusText));let t=await e.json();u(t.job_id),l(!0)}catch(e){alert(e.message||"Error starting PIV")}finally{a(!1)}},[]),cancel:(0,r.useCallback)(async()=>{a(!0);try{let e=await fetch("/backend/cancel_run",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({job_id:d})});if(!e.ok)throw Error("Failed to cancel PIV: ".concat(e.statusText));l(!1),i(0),u(null)}catch(e){alert(e.message||"Error cancelling run")}finally{a(!1)}},[d])}}({sourcePathIdx:a,varType:n,cmap:o,run:d,lowerLimit:m,upperLimit:x,showStatusImage:p});return(0,r.useEffect)(()=>{if(!T||0===I)return;let e=setTimeout(async()=>{C(!0);try{let e=new URLSearchParams({basepath_idx:String(a),frame:"1",is_uncalibrated:"1"}),t=await fetch("/backend/plot/check_vars?".concat(e.toString()));if(t.ok){let e=await t.json(),a=["ux","uy","nan_mask","peak_mag"],s=(e.vars||[]).filter(e=>a.includes(e));s.length>0?(y(s),i(e=>s.includes(e)?e:s[0])):y(a)}else console.log("Frame not ready yet, using default variables")}catch(e){console.log("Waiting for frames to be available...",e)}finally{C(!1)}},1e3);return()=>clearTimeout(e)},[T,I,a]),(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Run PIV"})}),(0,s.jsxs)(k,{className:"space-y-6",children:[(0,s.jsx)("div",{className:"grid grid-cols-1 gap-4",children:(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Source Path"}),(0,s.jsxs)(D,{value:String(a),onValueChange:e=>l(Number(e)),children:[(0,s.jsx)(L,{children:(0,s.jsx)(V,{})}),(0,s.jsx)(W,{children:P.length>0?P.map((e,t)=>(0,s.jsx)(Z,{value:String(t),children:ex(e)},t)):(0,s.jsx)(Z,{value:"0",disabled:!0,children:"No paths"})})]})]})}),(0,s.jsxs)("div",{className:"grid grid-cols-2 lg:grid-cols-4 gap-4 items-end",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Variable"}),(0,s.jsxs)(D,{value:n,onValueChange:i,disabled:S,children:[(0,s.jsx)(L,{children:(0,s.jsx)(V,{})}),(0,s.jsx)(W,{children:S?(0,s.jsx)(Z,{value:"loading",disabled:!0,children:"Loading..."}):b.map(e=>(0,s.jsx)(Z,{value:e,children:e},e))})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Colormap"}),(0,s.jsxs)(D,{value:o,onValueChange:c,children:[(0,s.jsx)(L,{children:(0,s.jsx)(V,{})}),(0,s.jsx)(W,{children:["default","viridis","plasma","inferno","magma","cividis","jet","gray"].map(e=>(0,s.jsx)(Z,{value:e,children:e},e))})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Lower Limit"}),(0,s.jsx)(F,{type:"number",value:m,onChange:e=>h(e.target.value),placeholder:"auto"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Upper Limit"}),(0,s.jsx)(F,{type:"number",value:x,onChange:e=>g(e.target.value),placeholder:"auto"})]})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)(eh,{value:I}),(0,s.jsx)("p",{className:"text-sm text-center font-medium text-gray-500",children:T?"Processing... ".concat(I,"%"):100===I?"✅ Completed!":"Idle"})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)(E,{variant:"outline",size:"sm",onClick:()=>f(!p),children:[p?"Hide":"Show"," Status Image"]}),p&&(0,s.jsxs)("div",{className:"mt-2 border rounded-lg p-2 bg-gray-50 min-h-[200px] flex items-center justify-center",children:[R.error&&(0,s.jsx)("p",{className:"text-red-600 font-semibold",children:R.error}),R.src&&!R.error&&(0,s.jsx)("img",{src:"data:image/png;base64,".concat(R.src),alt:"PIV Status",className:"rounded max-w-full"}),!R.src&&!R.error&&T&&(0,s.jsxs)("div",{className:"flex flex-col items-center",children:[(0,s.jsx)("div",{className:"animate-spin rounded-full h-8 w-8 border-b-2 border-gray-900 mb-2"}),(0,s.jsx)("p",{className:"text-gray-500",children:0===I?"Waiting for run to commence...":"Processing first frame..."})]}),!R.src&&!R.error&&!T&&(0,s.jsx)("p",{className:"text-gray-500",children:"No image available"})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)(E,{variant:"outline",size:"sm",onClick:()=>j(!v),children:[v?"Hide":"Show"," Console Logs"]}),v&&(0,s.jsxs)("div",{className:"mt-2 border rounded-lg bg-gray-900 text-green-400 font-mono text-xs overflow-hidden",children:[(0,s.jsxs)("div",{className:"bg-gray-800 px-3 py-2 border-b border-gray-700 flex items-center justify-between",children:[(0,s.jsx)("span",{className:"text-gray-300 font-semibold",children:"PIV Console Output"}),T&&(0,s.jsxs)("span",{className:"flex items-center gap-2 text-xs text-gray-400",children:[(0,s.jsxs)("span",{className:"relative flex h-2 w-2",children:[(0,s.jsx)("span",{className:"animate-ping absolute inline-flex h-full w-full rounded-full bg-green-400 opacity-75"}),(0,s.jsx)("span",{className:"relative inline-flex rounded-full h-2 w-2 bg-green-500"})]}),"Live"]})]}),(0,s.jsx)("div",{className:"p-3 max-h-[300px] overflow-y-auto scrollbar-thin scrollbar-thumb-gray-700 scrollbar-track-gray-800",children:A?(0,s.jsx)(s.Fragment,{children:(0,s.jsx)("pre",{className:"whitespace-pre-wrap break-words",children:A})}):(0,s.jsx)("p",{className:"text-gray-500 italic",children:T?"Waiting for output...":"No logs available. Start a PIV run to see output."})})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4 pt-2",children:[(0,s.jsx)(E,{className:"bg-green-600 hover:bg-green-700",onClick:z,disabled:M||T,children:T?"Running...":"Run PIV"}),(0,s.jsx)(E,{className:"bg-red-600 hover:bg-red-700",onClick:O,disabled:!T&&!M,children:"Cancel Run"})]})]})]})};function ep(e){let{config:t,updateConfigValue:a}=e,l=(null==t?void 0:t.outlier_detection)||{enabled:!0,methods:[]},n=l.methods||[],[i,c]=(0,r.useState)([]);(0,r.useEffect)(()=>{c(n.map(e=>{var t,a,s,r;return{...e,threshold:null!==(s=null===(t=e.threshold)||void 0===t?void 0:t.toString())&&void 0!==s?s:"median_2d"===e.type?"2.0":"0.4",epsilon:null!==(r=null===(a=e.epsilon)||void 0===a?void 0:a.toString())&&void 0!==r?r:"0.2"}}))},[n]);let d=e=>{a(["outlier_detection","methods"],n.filter((t,a)=>a!==e))},u=(e,t,s)=>{let r=[...n];r[e]={...r[e],[t]:s},a(["outlier_detection","methods"],r)};return(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between",children:[(0,s.jsx)(R,{children:"Enable Outlier Detection"}),(0,s.jsx)(E,{variant:l.enabled?"default":"outline",size:"sm",onClick:()=>{a(["outlier_detection","enabled"],!l.enabled)},children:l.enabled?"Enabled":"Disabled"})]}),l.enabled&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"flex items-center justify-between",children:[(0,s.jsx)(R,{className:"text-sm font-semibold",children:"Detection Methods"}),(0,s.jsxs)(E,{variant:"outline",size:"sm",onClick:()=>{a(["outlier_detection","methods"],[...n,{type:"peak_mag",threshold:.4}])},children:[(0,s.jsx)(Y.Z,{className:"h-3 w-3 mr-1"})," Add Method"]})]}),(0,s.jsx)("div",{className:"space-y-3",children:n.map((e,t)=>{var a,r,l,n,m,h;return(0,s.jsxs)("div",{className:"p-3 bg-white border rounded-lg space-y-3",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between",children:[(0,s.jsxs)(R,{className:"text-xs font-medium",children:["Method ",t+1]}),(0,s.jsx)(E,{variant:"ghost",size:"sm",onClick:()=>d(t),children:(0,s.jsx)(o.Z,{className:"h-3 w-3 text-red-500"})})]}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Type"}),(0,s.jsxs)(D,{value:e.type||"peak_mag",onValueChange:e=>u(t,"type",e),children:[(0,s.jsx)(L,{className:"h-8 text-sm",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"peak_mag",children:"Peak Magnitude"}),(0,s.jsx)(Z,{value:"median_2d",children:"Median 2D"})]})]})]}),"peak_mag"===e.type&&(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Threshold"}),(0,s.jsx)(F,{className:"h-8 text-sm",type:"text",value:null!==(n=null===(a=i[t])||void 0===a?void 0:a.threshold)&&void 0!==n?n:"0.4",onChange:e=>{let a=e.target.value,s=[...i];s[t]={...s[t],threshold:a},c(s);let r=parseFloat(a);isNaN(r)||u(t,"threshold",r)},onBlur:()=>{var e;let a=null===(e=i[t])||void 0===e?void 0:e.threshold;if(""===a||void 0===a){let e=[...i];e[t]={...e[t],threshold:"0.4"},c(e),u(t,"threshold",.4)}}})]}),"median_2d"===e.type&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Epsilon"}),(0,s.jsx)(F,{className:"h-8 text-sm",type:"text",value:null!==(m=null===(r=i[t])||void 0===r?void 0:r.epsilon)&&void 0!==m?m:"0.2",onChange:e=>{let a=e.target.value,s=[...i];s[t]={...s[t],epsilon:a},c(s);let r=parseFloat(a);isNaN(r)||u(t,"epsilon",r)},onBlur:()=>{var e;let a=null===(e=i[t])||void 0===e?void 0:e.epsilon;if(""===a||void 0===a){let e=[...i];e[t]={...e[t],epsilon:"0.2"},c(e),u(t,"epsilon",.2)}}})]}),(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Threshold"}),(0,s.jsx)(F,{className:"h-8 text-sm",type:"text",value:null!==(h=null===(l=i[t])||void 0===l?void 0:l.threshold)&&void 0!==h?h:"2.0",onChange:e=>{let a=e.target.value,s=[...i];s[t]={...s[t],threshold:a},c(s);let r=parseFloat(a);isNaN(r)||u(t,"threshold",r)},onBlur:()=>{var e;let a=null===(e=i[t])||void 0===e?void 0:e.threshold;if(""===a||void 0===a){let e=[...i];e[t]={...e[t],threshold:"2"},c(e),u(t,"threshold",2)}}})]})]})]})]},t)})}),0===n.length&&(0,s.jsx)("p",{className:"text-xs text-muted-foreground text-center py-2",children:'No detection methods configured. Click "Add Method" to add one.'})]})]})}function ef(e){var t,a,r,l,n,i,o,c,d,u,m,h,x,g,p,f,v,j,b,y,N,w,_,S,k;let{config:C,updateConfigValue:P}=e,M=(null==C?void 0:C.infilling)||{mid_pass:{},final_pass:{}},T=(e,t)=>{P(["infilling","mid_pass"],{...M.mid_pass,[e]:t})},I=(e,t)=>{var a;T("parameters",{...(null===(a=M.mid_pass)||void 0===a?void 0:a.parameters)||{},[e]:t})},A=(e,t)=>{P(["infilling","final_pass"],{...M.final_pass,[e]:t})},z=(e,t)=>{var a;A("parameters",{...(null===(a=M.final_pass)||void 0===a?void 0:a.parameters)||{},[e]:t})};return(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"space-y-3",children:[(0,s.jsx)(R,{className:"text-sm font-semibold",children:"Mid-Pass Infilling"}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Method"}),(0,s.jsxs)(D,{value:(null===(t=M.mid_pass)||void 0===t?void 0:t.method)||"local_median",onValueChange:e=>T("method",e),children:[(0,s.jsx)(L,{className:"h-8 text-sm",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"local_median",children:"Local Median"}),(0,s.jsx)(Z,{value:"knn",children:"K-Nearest Neighbors"}),(0,s.jsx)(Z,{value:"biharmonic",children:"Biharmonic"})]})]})]}),(null===(a=M.mid_pass)||void 0===a?void 0:a.method)==="local_median"&&(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Kernel Size"}),(0,s.jsx)(F,{className:"h-8 text-sm",type:"text",value:null===(l=M.mid_pass)||void 0===l?void 0:null===(r=l.parameters)||void 0===r?void 0:r.ksize,onChange:e=>I("ksize",e.target.value)})]}),(null===(n=M.mid_pass)||void 0===n?void 0:n.method)==="knn"&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Neighbors"}),(0,s.jsx)(F,{className:"h-8 text-sm",type:"text",value:null===(o=M.mid_pass)||void 0===o?void 0:null===(i=o.parameters)||void 0===i?void 0:i.n_neighbors,onChange:e=>I("n_neighbors",e.target.value)})]}),(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Weights"}),(0,s.jsxs)(D,{value:(null===(d=M.mid_pass)||void 0===d?void 0:null===(c=d.parameters)||void 0===c?void 0:c.weights)||"distance",onValueChange:e=>I("weights",e),children:[(0,s.jsx)(L,{className:"h-8 text-sm",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"uniform",children:"Uniform"}),(0,s.jsx)(Z,{value:"distance",children:"Distance"})]})]})]}),(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Algorithm"}),(0,s.jsxs)(D,{value:(null===(m=M.mid_pass)||void 0===m?void 0:null===(u=m.parameters)||void 0===u?void 0:u.algorithm)||"kd_tree",onValueChange:e=>I("algorithm",e),children:[(0,s.jsx)(L,{className:"h-8 text-sm",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"auto",children:"Auto"}),(0,s.jsx)(Z,{value:"ball_tree",children:"Ball Tree"}),(0,s.jsx)(Z,{value:"kd_tree",children:"KD Tree"}),(0,s.jsx)(Z,{value:"brute",children:"Brute Force"})]})]})]})]})]})]}),(0,s.jsxs)("div",{className:"space-y-3 pt-3 border-t",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between",children:[(0,s.jsx)(R,{className:"text-sm font-semibold",children:"Final Pass Infilling"}),(0,s.jsx)(E,{variant:(null===(h=M.final_pass)||void 0===h?void 0:h.enabled)?"default":"outline",size:"sm",onClick:()=>{var e;return A("enabled",!(null===(e=M.final_pass)||void 0===e?void 0:e.enabled))},children:(null===(x=M.final_pass)||void 0===x?void 0:x.enabled)?"Enabled":"Disabled"})]}),(null===(g=M.final_pass)||void 0===g?void 0:g.enabled)&&(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-3",children:[(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Method"}),(0,s.jsxs)(D,{value:(null===(p=M.final_pass)||void 0===p?void 0:p.method)||"local_median",onValueChange:e=>A("method",e),children:[(0,s.jsx)(L,{className:"h-8 text-sm",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"local_median",children:"Local Median"}),(0,s.jsx)(Z,{value:"knn",children:"K-Nearest Neighbors"}),(0,s.jsx)(Z,{value:"biharmonic",children:"Biharmonic"})]})]})]}),(null===(f=M.final_pass)||void 0===f?void 0:f.method)==="local_median"&&(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Kernel Size"}),(0,s.jsx)(F,{className:"h-8 text-sm",type:"text",value:null===(j=M.final_pass)||void 0===j?void 0:null===(v=j.parameters)||void 0===v?void 0:v.ksize,onChange:e=>z("ksize",e.target.value)})]}),(null===(b=M.final_pass)||void 0===b?void 0:b.method)==="knn"&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Neighbors"}),(0,s.jsx)(F,{className:"h-8 text-sm",type:"text",value:null===(N=M.final_pass)||void 0===N?void 0:null===(y=N.parameters)||void 0===y?void 0:y.n_neighbors,onChange:e=>z("n_neighbors",e.target.value)})]}),(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Weights"}),(0,s.jsxs)(D,{value:(null===(_=M.final_pass)||void 0===_?void 0:null===(w=_.parameters)||void 0===w?void 0:w.weights)||"distance",onValueChange:e=>z("weights",e),children:[(0,s.jsx)(L,{className:"h-8 text-sm",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"uniform",children:"Uniform"}),(0,s.jsx)(Z,{value:"distance",children:"Distance"})]})]})]}),(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)(R,{className:"text-xs",children:"Algorithm"}),(0,s.jsxs)(D,{value:(null===(k=M.final_pass)||void 0===k?void 0:null===(S=k.parameters)||void 0===S?void 0:S.algorithm)||"kd_tree",onValueChange:e=>z("algorithm",e),children:[(0,s.jsx)(L,{className:"h-8 text-sm",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"auto",children:"Auto"}),(0,s.jsx)(Z,{value:"ball_tree",children:"Ball Tree"}),(0,s.jsx)(Z,{value:"kd_tree",children:"KD Tree"}),(0,s.jsx)(Z,{value:"brute",children:"Brute Force"})]})]})]})]})]})]})]})}function ev(e){var t,a,n,i,c,d,u,m,h,g,p,f,v;let{config:j,updateConfig:b}=e,{passes:y,addPass:C,removePass:P,movePass:M,updatePassField:T,toggleStore:I}=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=arguments.length>1?arguments[1]:void 0,a=e.runs||[6],s=(e.window_size||[]).map((t,s)=>{var r,l,n,i;return{windowX:null!==(l=t[0])&&void 0!==l?l:128,windowY:null!==(n=t[1])&&void 0!==n?n:128,overlap:null!==(i=null===(r=e.overlap)||void 0===r?void 0:r[s])&&void 0!==i?i:50,store:a.includes(s+1)}});0===s.length&&s.push({windowX:128,windowY:128,overlap:50,store:!0}),s.length>0&&(s[s.length-1].store=!0);let[l,n]=(0,r.useState)(s),i=(0,r.useRef)(null),o=(0,r.useRef)(0),c=(0,r.useRef)({passes:s}),d=(0,r.useCallback)(e=>{Date.now()<o.current||Q(e,c.current.passes)||(c.current={passes:JSON.parse(JSON.stringify(e))},i.current&&clearTimeout(i.current),i.current=window.setTimeout(async()=>{let a=e.map((e,t)=>e.store?t+1:null).filter(e=>null!==e),s={window_size:e.map(e=>["number"==typeof e.windowX?e.windowX:parseInt(e.windowX)||128,"number"==typeof e.windowY?e.windowY:parseInt(e.windowY)||128]),overlap:e.map(e=>"number"==typeof e.overlap?e.overlap:parseInt(e.overlap)||50),runs:a};try{let e=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({instantaneous_piv:s})});e.ok?(t(["instantaneous_piv"],s),o.current=Date.now()+1500):console.error("Failed to update config:",await e.json())}catch(e){console.error("Auto-save failed:",e)}},400))},[t]);return(0,r.useEffect)(()=>{d(l)},[l,d]),(0,r.useEffect)(()=>{if(Date.now()<o.current)return;let t=e.runs||[],a=(e.window_size||[]).map((a,s)=>{var r,l,n,i;return{windowX:null!==(l=a[0])&&void 0!==l?l:128,windowY:null!==(n=a[1])&&void 0!==n?n:128,overlap:null!==(i=null===(r=e.overlap)||void 0===r?void 0:r[s])&&void 0!==i?i:50,store:t.includes(s+1)}});a.length>0&&(a[a.length-1].store=!0),a.length>0&&!Q(a,l)&&n(a)},[e.window_size,e.overlap,e.runs]),{passes:l,addPass:()=>n(e=>{let t=e[e.length-1],a="number"==typeof t.windowX?t.windowX:parseInt(t.windowX)||128,s="number"==typeof t.windowY?t.windowY:parseInt(t.windowY)||128;return[...e.map((t,a)=>a===e.length-1?{...t,store:!1}:t),{windowX:Math.max(8,Math.floor(a/2)),windowY:Math.max(8,Math.floor(s/2)),overlap:t.overlap,store:!0}]}),removePass:e=>n(t=>{if(t.length<=1)return t;let a=t.filter((t,a)=>a!==e);return a.length>0&&(a[a.length-1].store=!0),a}),movePass:(e,t)=>n(a=>{let s=e+t;if(s<0||s>=a.length)return a;let r=[...a];return[r[e],r[s]]=[r[s],r[e]],r.length>0&&r.forEach((e,t)=>{t===r.length-1&&(e.store=!0)}),r}),updatePassField:(e,t,a)=>n(s=>{let r=[...s];return r[e]={...r[e],[t]:a},"store"===t&&r.length>0&&(r[r.length-1].store=!0),r}),toggleStore:e=>n(t=>{if(e===t.length-1)return t;let a=[...t];return a[e]={...a[e],store:!a[e].store},a})}}(j.instantaneous_piv,b),A=(null==j?void 0:null===(t=j.paths)||void 0===t?void 0:t.camera_count)||1,[O,B]=(0,r.useState)([]),[U,ee]=(0,r.useState)(!1),[et,ea]=(0,r.useState)(!1),[es,er]=(0,r.useState)(!1),[el,en]=(0,r.useState)(!1),[ei,eo]=(0,r.useState)("6"),[ec,ed]=(0,r.useState)("GB"),eu=async e=>{try{let a=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({paths:{...j.paths,camera_numbers:e}})});if(a.ok){var t;let e=await a.json();(null===(t=e.updated)||void 0===t?void 0:t.paths)&&b(["paths"],{...j.paths,...e.updated.paths})}}catch(e){console.error("Failed to save camera selection:",e)}};(0,r.useEffect)(()=>{var e;let t=(null==j?void 0:null===(e=j.paths)||void 0===e?void 0:e.camera_numbers)||[];if(t.length>0){let e=t.filter(e=>e>=1&&e<=A);if(e.length>0)B(e);else{let e=[1];B(e),eu(e)}}else{let e=[1];B(e),eu(e)}},[null==j?void 0:null===(a=j.paths)||void 0===a?void 0:a.camera_numbers,A]),(0,r.useEffect)(()=>{var e;let t=((null==j?void 0:null===(e=j.processing)||void 0===e?void 0:e.dask_memory_limit)||"6GB").match(/^(\d+)(MB|GB)?$/);t?(eo(t[1]),ed(t[2]||"GB")):(eo("6"),ed("GB"))},[null==j?void 0:null===(n=j.processing)||void 0===n?void 0:n.dask_memory_limit]);let eh=async e=>{let t;if(O.includes(e)){if(1===O.length)return;t=O.filter(t=>t!==e)}else t=[...O,e].sort((e,t)=>e-t);B(t),await eu(t)},ex=async(e,t)=>{try{let a=[...e],s={},r=s;for(let e=0;e<a.length-1;e++)r[a[e]]={},r=r[a[e]];r[a[a.length-1]]=t;let l=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)});l.ok&&(await l.json(),b(e,t))}catch(e){console.error("Failed to update config:",e)}};return(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)(N,{children:[(0,s.jsxs)(w,{children:[(0,s.jsx)(_,{children:"Instantaneous PIV"}),(0,s.jsx)(S,{children:"Configure processing passes and select cameras"})]}),(0,s.jsxs)(k,{className:"space-y-4",children:[A>1&&(0,s.jsxs)("div",{className:"mb-6 p-4 bg-gray-50 rounded-lg",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 mb-3",children:[(0,s.jsx)(G.Z,{className:"h-5 w-5 text-soton-blue"}),(0,s.jsx)(R,{className:"text-sm font-semibold",children:"Select Cameras to Process"})]}),(0,s.jsx)("div",{className:"flex flex-wrap gap-2",children:Array.from({length:A},(e,t)=>t+1).map(e=>(0,s.jsxs)(E,{variant:O.includes(e)?"default":"outline",size:"sm",onClick:()=>eh(e),className:"min-w-[80px]",children:["Camera ",e]},e))}),(0,s.jsxs)("p",{className:"text-xs text-muted-foreground mt-2",children:["Selected cameras: ",O.join(", ")," (at least one required)"]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4 flex-wrap mb-6",children:[(0,s.jsx)("div",{className:"flex items-center gap-3",children:(0,s.jsx)("p",{className:"text-sm text-muted-foreground",children:"Configure passes and toggle which to store (final pass always stored)"})}),(0,s.jsx)("div",{className:"ml-auto flex items-center gap-2",children:(0,s.jsxs)(E,{variant:"outline",size:"sm",onClick:C,children:[(0,s.jsx)(Y.Z,{className:"h-4 w-4 mr-1"})," Add Pass"]})})]}),(0,s.jsxs)("div",{className:"grid grid-cols-12 gap-x-2 text-xs font-semibold text-muted-foreground px-2",children:[(0,s.jsx)("div",{className:"col-span-2",children:"Window X"}),(0,s.jsx)("div",{className:"col-span-2",children:"Window Y"}),(0,s.jsx)("div",{className:"col-span-2",children:"Overlap %"}),(0,s.jsx)("div",{className:"col-span-1 text-center",children:"Store"}),(0,s.jsx)("div",{className:"col-span-3 text-center",children:"Actions"}),(0,s.jsx)("div",{className:"col-span-2 text-right",children:"Pass #"})]}),(0,s.jsx)("div",{className:"space-y-2",children:y.map((e,t)=>{let a=t===y.length-1;return(0,s.jsxs)("div",{className:"grid grid-cols-12 gap-x-2 items-center bg-gray-50 p-2 rounded-md",children:[(0,s.jsx)(F,{className:"col-span-2",type:"text",value:e.windowX,onChange:e=>T(t,"windowX",e.target.value)}),(0,s.jsx)(F,{className:"col-span-2",type:"text",value:e.windowY,onChange:e=>T(t,"windowY",e.target.value)}),(0,s.jsx)(F,{className:"col-span-2",type:"text",value:e.overlap,onChange:e=>T(t,"overlap",e.target.value)}),(0,s.jsx)("div",{className:"col-span-1 flex justify-center",children:(0,s.jsx)(E,{variant:e.store?"default":"outline",size:"sm",onClick:()=>I(t),disabled:a,className:"h-8 px-2",title:a?"Final pass always stored":e.store?"Click to disable storing":"Click to enable storing",children:(0,s.jsx)(J.Z,{className:"h-3 w-3"})})}),(0,s.jsxs)("div",{className:"col-span-3 flex justify-center gap-1",children:[(0,s.jsx)(E,{variant:"ghost",size:"icon",onClick:()=>M(t,-1),disabled:0===t,children:(0,s.jsx)(z.Z,{className:"h-4 w-4"})}),(0,s.jsx)(E,{variant:"ghost",size:"icon",onClick:()=>M(t,1),disabled:t===y.length-1,children:(0,s.jsx)(x.Z,{className:"h-4 w-4"})}),(0,s.jsx)(E,{variant:"ghost",size:"icon",onClick:()=>P(t),disabled:y.length<=1,children:(0,s.jsx)(o.Z,{className:"h-4 w-4 text-red-500"})})]}),(0,s.jsxs)("div",{className:"col-span-2 text-sm font-medium text-muted-foreground text-right",children:["Pass ",t+1]})]},t)})}),(0,s.jsx)("p",{className:"text-xs text-gray-500 pt-2",children:"Changes are saved automatically."})]})]}),(0,s.jsxs)(N,{children:[(0,s.jsxs)(w,{children:[(0,s.jsxs)(_,{className:"flex items-center gap-2",children:[(0,s.jsx)(l.Z,{className:"h-5 w-5"}),"Advanced PIV Settings"]}),(0,s.jsx)(S,{children:"Performance tuning, outlier detection, infilling, and peak finding"})]}),(0,s.jsxs)(k,{className:"space-y-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsxs)(E,{variant:"outline",className:"w-full justify-between",onClick:()=>ee(!U),children:[(0,s.jsxs)("span",{className:"flex items-center gap-2",children:[(0,s.jsx)(X.Z,{className:"h-4 w-4"}),"Performance & Compute Settings"]}),(0,s.jsx)(H.Z,{className:"h-4 w-4 transition-transform ".concat(U?"rotate-90":"")})]}),U&&(0,s.jsx)("div",{className:"mt-4 space-y-4 p-4 bg-gray-50 rounded-lg",children:(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4",children:[(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)(R,{htmlFor:"batch-size",children:"Batch Size"}),(0,s.jsx)(F,{id:"batch-size",type:"text",value:(null==j?void 0:null===(i=j.batches)||void 0===i?void 0:i.size)===""?"":null!==(p=null==j?void 0:null===(c=j.batches)||void 0===c?void 0:c.size)&&void 0!==p?p:10,onChange:e=>{let t=parseInt(e.target.value,10);ex(["batches","size"],isNaN(t)?"":t)}}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground",children:"Number of images processed per batch"})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)(R,{htmlFor:"omp-threads",children:"Threads (OMP)"}),(0,s.jsx)(F,{id:"omp-threads",type:"text",value:(null==j?void 0:null===(d=j.processing)||void 0===d?void 0:d.omp_threads)===""?"":null!==(f=null==j?void 0:null===(u=j.processing)||void 0===u?void 0:u.omp_threads)&&void 0!==f?f:4,onChange:e=>{let t=parseInt(e.target.value,10);ex(["processing","omp_threads"],isNaN(t)?"":t)}}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground",children:"OpenMP threads for parallel processing"})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)(R,{htmlFor:"dask-workers",children:"Dask Workers"}),(0,s.jsx)(F,{id:"dask-workers",type:"text",value:(null==j?void 0:null===(m=j.processing)||void 0===m?void 0:m.dask_workers_per_node)===""?"":null!==(v=null==j?void 0:null===(h=j.processing)||void 0===h?void 0:h.dask_workers_per_node)&&void 0!==v?v:10,onChange:e=>{let t=parseInt(e.target.value,10);ex(["processing","dask_workers_per_node"],isNaN(t)?"":t)}}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground",children:"Number of Dask workers per node"})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)(R,{children:"Memory per Worker"}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(F,{type:"text",value:ei,onChange:e=>{let t=e.target.value;eo(t);let a=parseInt(t,10);isNaN(a)||ex(["processing","dask_memory_limit"],"".concat(a).concat(ec))},onBlur:()=>{""===ei&&(eo("6"),ex(["processing","dask_memory_limit"],"6".concat(ec)))},className:"flex-1"}),(0,s.jsxs)(D,{value:ec,onValueChange:e=>{ed(e);let t=parseInt(ei,10);isNaN(t)||ex(["processing","dask_memory_limit"],"".concat(t).concat(e))},children:[(0,s.jsx)(L,{className:"w-20",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"MB",children:"MB"}),(0,s.jsx)(Z,{value:"GB",children:"GB"})]})]})]}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground",children:"Memory limit per worker"})]})]})})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)(E,{variant:"outline",className:"w-full justify-between",onClick:()=>en(!el),children:[(0,s.jsxs)("span",{className:"flex items-center gap-2",children:[(0,s.jsx)(K.Z,{className:"h-4 w-4"}),"Peak Finding Method"]}),(0,s.jsx)(H.Z,{className:"h-4 w-4 transition-transform ".concat(el?"rotate-90":"")})]}),el&&(0,s.jsx)("div",{className:"mt-4 space-y-4 p-4 bg-gray-50 rounded-lg",children:(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)(R,{htmlFor:"peak-finder",children:"Peak Finder Algorithm"}),(0,s.jsxs)(D,{value:(null==j?void 0:null===(g=j.instantaneous_piv)||void 0===g?void 0:g.peak_finder)||"gauss3",onValueChange:e=>ex(["instantaneous_piv","peak_finder"],e),children:[(0,s.jsx)(L,{id:"peak-finder",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"gauss3",children:"Gaussian 3-point"}),(0,s.jsx)(Z,{value:"gauss4",children:"Gaussian 4-point"}),(0,s.jsx)(Z,{value:"gauss5",children:"Gaussian 5-point"}),(0,s.jsx)(Z,{value:"gauss6",children:"Gaussian 6-point"})]})]}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground",children:"Subpixel peak detection method. Higher point counts provide better accuracy but slower processing."})]})})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)(E,{variant:"outline",className:"w-full justify-between",onClick:()=>ea(!et),children:[(0,s.jsxs)("span",{className:"flex items-center gap-2",children:[(0,s.jsx)($.Z,{className:"h-4 w-4"}),"Outlier Detection"]}),(0,s.jsx)(H.Z,{className:"h-4 w-4 transition-transform ".concat(et?"rotate-90":"")})]}),et&&(0,s.jsx)("div",{className:"mt-4 space-y-4 p-4 bg-gray-50 rounded-lg",children:(0,s.jsx)(ep,{config:j,updateConfigValue:ex})})]}),(0,s.jsxs)("div",{children:[(0,s.jsxs)(E,{variant:"outline",className:"w-full justify-between",onClick:()=>er(!es),children:[(0,s.jsxs)("span",{className:"flex items-center gap-2",children:[(0,s.jsx)(q.Z,{className:"h-4 w-4"}),"Infilling Methods"]}),(0,s.jsx)(H.Z,{className:"h-4 w-4 transition-transform ".concat(es?"rotate-90":"")})]}),es&&(0,s.jsx)("div",{className:"mt-4 space-y-4 p-4 bg-gray-50 rounded-lg",children:(0,s.jsx)(ef,{config:j,updateConfigValue:ex})})]})," "]})]}),(0,s.jsx)(em,{backendUrl:"/backend",config:j}),(0,s.jsx)(eg,{config:j})]})}var ej=a(1817),eb=a(9388),ey=a(4924);function eN(e){let{config:t,updateConfig:a}=e,[l,n]=(0,r.useState)([]),[i,c]=(0,r.useState)([]),[d,u]=(0,r.useState)("idle");(0,r.useEffect)(()=>{var e,a;n((null===(e=t.paths)||void 0===e?void 0:e.base_paths)||[]),c((null===(a=t.paths)||void 0===a?void 0:a.source_paths)||[]),u("idle")},[t.paths]);let m=e=>e.replace(/^["']+|["']+$/g,"").trim(),h=async(e,s)=>{var r,l;u("saving");let n={paths:{base_paths:e.filter(Boolean).map(m),source_paths:s.filter(Boolean).map(m),camera_numbers:null===(r=t.paths)||void 0===r?void 0:r.camera_numbers}};try{let e=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n)}),s=await e.json();if(!e.ok)throw Error(s.error||"Failed to save paths");(null===(l=s.updated)||void 0===l?void 0:l.paths)&&a(["paths"],{...t.paths,...s.updated.paths}),u("success")}catch(e){u("error")}};return(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-6",children:[(0,s.jsxs)("div",{className:"flex items-center space-x-2",children:[(0,s.jsx)(ey.Z,{className:"h-6 w-6 text-soton-blue"}),(0,s.jsx)("h2",{className:"text-2xl font-bold text-gray-800",children:"Directories Configuration"})]}),(0,s.jsx)("div",{className:"flex items-center gap-2 h-8",children:(0,s.jsx)(()=>"saving"===d?(0,s.jsx)(ej.Z,{className:"h-4 w-4 animate-spin text-muted-foreground"}):"success"===d?(0,s.jsx)(K.Z,{className:"h-4 w-4 text-green-500"}):"error"===d?(0,s.jsx)(eb.Z,{className:"h-4 w-4 text-red-500"}):null,{})})]}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[(0,s.jsxs)(N,{children:[(0,s.jsxs)(w,{children:[(0,s.jsx)(_,{children:"Output Directories"}),(0,s.jsx)(S,{children:"Locations for saved results"})]}),(0,s.jsx)(k,{children:(0,s.jsxs)("div",{className:"space-y-4",children:[l.map((e,t)=>(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(F,{value:e,onChange:e=>{let a=[...l];a[t]=e.target.value,n(a)},onBlur:()=>h(l,i),placeholder:"/your/output/path/",className:"font-mono"}),(0,s.jsx)(E,{variant:"ghost",size:"icon",onClick:()=>{let e=l.filter((e,a)=>a!==t);n(e),h(e,i)},className:"text-red-500 hover:text-red-700",children:(0,s.jsx)(o.Z,{className:"h-4 w-4"})})]},t)),(0,s.jsxs)(E,{variant:"outline",onClick:()=>{n([...l,""])},className:"flex items-center gap-2 w-full",children:[(0,s.jsx)(Y.Z,{className:"h-4 w-4"})," Add Output Directory"]})]})})]}),(0,s.jsxs)(N,{children:[(0,s.jsxs)(w,{children:[(0,s.jsx)(_,{children:"Source Directories"}),(0,s.jsx)(S,{children:"Locations of raw image sequences"})]}),(0,s.jsx)(k,{children:(0,s.jsxs)("div",{className:"space-y-4",children:[i.map((e,t)=>(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(F,{value:e,onChange:e=>{let a=[...i];a[t]=e.target.value,c(a)},onBlur:()=>h(l,i),placeholder:"/your/source/path/",className:"font-mono"}),(0,s.jsx)(E,{variant:"ghost",size:"icon",onClick:()=>{let e=i.filter((e,a)=>a!==t);c(e),h(l,e)},className:"text-red-500 hover:text-red-700",children:(0,s.jsx)(o.Z,{className:"h-4 w-4"})})]},t)),(0,s.jsxs)(E,{variant:"outline",onClick:()=>{c([...i,""])},className:"flex items-center gap-2 w-full",children:[(0,s.jsx)(Y.Z,{className:"h-4 w-4"})," Add Source Directory"]})]})})]})]})]})}var ew=a(8752);function e_(e){let{config:t,updateConfig:a}=e,[l,n]=(0,r.useState)(()=>{try{return JSON.parse(localStorage.getItem("piv_base_paths")||"[]")}catch(e){return[]}}),[i,o]=(0,r.useState)(0),c=(0,r.useMemo)(()=>{var e,a;let s=null==t?void 0:null===(e=t.paths)||void 0===e?void 0:e.camera_numbers,r=null==t?void 0:null===(a=t.imProperties)||void 0===a?void 0:a.cameraCount,l=1;if(Array.isArray(s)){if(1===s.length){let e=Number(s[0]);!Number.isNaN(e)&&e>0&&(l=e)}else s.length>1&&(l=s.length)}else"number"==typeof r&&Number.isFinite(r)&&r>0&&(l=r);return Array.from({length:Math.max(1,Math.floor(l))},(e,t)=>String(t+1))},[t]),[d,u]=(0,r.useState)(()=>c&&c.length>0?c[0]:"1");(0,r.useEffect)(()=>{0===c.length||c.includes(d)||u(c[0]||"1")},[c.join(",")]);let[m,h]=(0,r.useState)(!1),[x,g]=(0,r.useState)(!1),[p,f]=(0,r.useState)(!1),[v,j]=(0,r.useState)(!1),[b,y]=(0,r.useState)(""),[S,C]=(0,r.useState)(!1),{toast:P}=(0,ew.pm)(),[M,T]=(0,r.useState)(0),[I,R]=(0,r.useState)(!1),A=(0,r.useRef)(null),[z,O]=(0,r.useState)(1),[D,V]=(0,r.useState)(Math.max(1,Number(b)||100)),[L,B]=(0,r.useState)(!1),U=(0,r.useRef)(null),[W,Z]=(0,r.useState)(z),[Y,G]=(0,r.useState)(!1),J=(0,r.useRef)(null),[X,H]=(0,r.useState)("ux"),[K,$]=(0,r.useState)("default"),[q,Q]=(0,r.useState)(!1),[ee,ea]=(0,r.useState)(1),[es,er]=(0,r.useState)(""),[el,en]=(0,r.useState)(""),[ei,eo]=(0,r.useState)(null),[ec,ed]=(0,r.useState)(null),[eu,em]=(0,r.useState)(!1),[ex,eg]=(0,r.useState)(null),[ep,ef]=(0,r.useState)(!1),[ev,ej]=(0,r.useState)(null),[eb,ey]=(0,r.useState)([]),[eN,e_]=(0,r.useState)(1),[ek,eC]=(0,r.useState)({}),[eP,eM]=(0,r.useState)(!0),[eE,eF]=(0,r.useState)(!1),[eT,eI]=(0,r.useState)(null),[eR,eA]=(0,r.useState)(null),[ez,eO]=(0,r.useState)(!1),[eD,eV]=(0,r.useState)(null),[eL,eB]=(0,r.useState)(null),[eU,eW]=(0,r.useState)(!1),[eZ,eY]=(0,r.useState)(null),[eG,eJ]=(0,r.useState)(null);(0,r.useEffect)(()=>{try{let e=((t||{}).post_processing||[]).find(e=>"pod"===String(e.type||"").toLowerCase()),a=(null==e?void 0:e.settings)||{};"boolean"==typeof a.randomised&&g(a.randomised),"boolean"==typeof a.normalise&&f(a.normalise);let s="boolean"==typeof a.stack_u_y?a.stack_u_y:"boolean"==typeof a.stack_U_y?a.stack_U_y:"boolean"==typeof a.stackUy?a.stackUy:void 0;"boolean"==typeof s&&j(s),"number"==typeof a.k_modes&&y(a.k_modes),"number"==typeof a.basepath_idx&&o(a.basepath_idx),e&&"boolean"==typeof e.use_merged?h(!!e.use_merged):"boolean"==typeof a.use_merged&&h(!!a.use_merged),a.camera&&u(String(a.camera))}catch(e){}},[t]);let eX=async e=>{C(!0);try{let t={post_processing:[{type:"POD",settings:e}]},s=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(t)}),r=await s.json();if(!s.ok)throw Error(r.error||"Failed to update POD settings");let l=r.updated||{};a&&a(["post_processing"],l.post_processing||t.post_processing)}catch(e){var t;P({title:"Failed to save POD",description:null!==(t=null==e?void 0:e.message)&&void 0!==t?t:"Unknown error"})}finally{C(!1)}},eH=async()=>{try{var e,t;let a=await fetch("/backend/pod_status",{method:"GET",cache:"no-store"});if(!a.ok)return;let s=await a.json(),r=Number(null!==(t=null!==(e=s.status)&&void 0!==e?e:s.progress)&&void 0!==t?t:0),l=Number.isFinite(r)?Math.min(Math.max(r,0),100):0;T(e=>l>e?l:e),R(!!s.processing),(!s.processing||l>=100)&&e$()}catch(e){}},eK=()=>{e$({resetProgress:!1}),eH(),A.current=setInterval(eH,2e4)},e$=e=>{A.current&&(clearInterval(A.current),A.current=null),R(!1),(null==e?void 0:e.resetProgress)&&T(0)};(0,r.useEffect)(()=>()=>{A.current&&clearInterval(A.current)},[]),(0,r.useEffect)(()=>{(async()=>{eF(!0),eI(null),eM(!1);try{let e=e2();if(!e)throw Error("No base path selected");let t=new URLSearchParams;t.set("base_path",e),t.set("camera",d),t.set("frame",String(eN)),t.set("merged",m?"1":"0");let a="/backend/plot/check_vars?".concat(t.toString()),s=await fetch(a),r=await s.json();if(!s.ok)throw Error(r.error||"Failed to check data");let l=Array.isArray(r.vars)?r.vars.map(String):[],n=l.includes("ux")&&l.includes("uy");eM(n),eC(e=>({...e,[eN]:n})),n||eI("No calibrated ux/uy data found for this run.")}catch(t){var e;eM(!1),eI(null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Unknown error")}finally{eF(!1)}})()},[eN,i,d,m,t]);let eq=async()=>{try{let e=e2();if(!e)return null;let a=t||{},s="",r="instantaneous";try{for(let e of a.post_processing||[])if("POD"===e.type){let t=e.settings||{};s=e.endpoint||t.endpoint||"",r=e.source_type||t.source_type||"instantaneous";break}}catch(e){}return{stats_base:"".concat(e,"/statistics/").concat(a.num_images||1e3,"/Cam").concat(d,"/").concat(r).concat(s?"/"+s:"")}}catch(e){return null}},eQ=async()=>{eO(!0),eV(null);try{let e=await eq();if(!e)throw Error("Could not resolve stats directory");let t=["".concat(e.stats_base,"/pod_randomised"),"".concat(e.stats_base,"/POD")],a=new Set;for(let e of t)for(let e=1;e<=10;++e){let t=new URLSearchParams;t.set("base_path",e2()||""),t.set("camera",d),t.set("run",String(e)),t.set("merged",m?"1":"0");let s="/backend/pod_energy_modes?".concat(t.toString());try{(await fetch(s,{method:"HEAD"})).ok&&a.add(e)}catch(e){}}eA(Array.from(a).sort((e,t)=>e-t))}catch(t){var e;eV(null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Failed to list POD runs"),eA(null)}finally{eO(!1)}};(0,r.useEffect)(()=>{eQ()},[i,d,m,t]),(0,r.useEffect)(()=>{let e=!1;return(async()=>{try{let a=t||{},s=[];if(Array.isArray(a.instantaneous_runs)&&a.instantaneous_runs.length>0)s=a.instantaneous_runs.map(e=>Number(e)).filter(e=>Number.isFinite(e)&&e>0);else if(Number.isFinite(Number(a.num_images))){let e=Math.max(1,Math.min(50,Math.floor(Number(a.num_images)/10)));s=Array.from({length:e},(e,t)=>t+1)}else s=Array.from({length:10},(e,t)=>t+1);ey(s);let r=e2();if(!r){eC(e=>{let t={...e};return s.forEach(e=>{t[e]=!1}),t}),s.includes(eN)||e_(s[0]||1);return}let l=[],n={};if(await Promise.all(s.map(async t=>{if(!e)try{let e=new URLSearchParams;e.set("base_path",r),e.set("camera",d),e.set("frame",String(t)),e.set("merged",m?"1":"0");let a="/backend/plot/check_vars?".concat(e.toString()),s=await fetch(a),i=await s.json(),o=Array.isArray(i.vars)?i.vars.map(String):[],c=o.includes("ux")&&o.includes("uy");n[t]=c,c&&l.push(t)}catch(e){n[t]=!1}})),e)return;eC(e=>({...e,...n})),l.length>0?(l.sort((e,t)=>e-t),ey(l),e_(e=>l.includes(e)?e:l[l.length-1])):(ey(s),s.includes(eN)||e_(s[0]||1))}catch(e){ey([1]),e_(1)}})(),()=>{e=!0}},[t,l,i,d,m]),(0,r.useEffect)(()=>{if(!eR){eB(null);return}eR.includes(eN)?eB(null):eB("Warning: Run ".concat(eN," has no POD data. Please select a run with data."))},[eR,eN]);let e0=async()=>{if(eP){C(!0),T(0);try{let e=Array.isArray(l)&&l.length>0&&i>=0&&i<l.length?l[i]:null,t=await fetch("/backend/start_pod",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({basepath_idx:i,base_path:e,camera:d,instantaneous_runs:[eN]})});if(!t.ok)throw Error("Failed to start POD: ".concat(t.statusText));await t.json().catch(()=>({})),R(!0),eK()}catch(t){var e;P({title:"Failed to start POD",description:null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Unknown error"})}finally{C(!1)}}},e1=async()=>{C(!0);try{let e=await fetch("/backend/cancel_pod",{method:"POST"});if(!e.ok)throw Error("Failed to cancel POD: ".concat(e.statusText));await e.json().catch(()=>({})),e$({resetProgress:!0}),R(!1)}catch(t){var e;P({title:"Failed to cancel POD",description:null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Unknown error"})}finally{C(!1)}};(0,r.useEffect)(()=>{"number"==typeof b&&b>0&&(V(b),z>b&&O(b))},[b]);let e2=()=>Array.isArray(l)&&l.length>0&&i>=0&&i<l.length?l[i]:null,e4=async function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:z;ef(!0),ej(null);try{let t=e2();if(!t)throw Error("Please select a base path");let a=new URLSearchParams;a.set("base_path",t),a.set("frame",String(e)),a.set("camera",d),a.set("merged",m?"1":"0");let s="/backend/plot/check_vars?".concat(a.toString()),r=await fetch(s),l=await r.json();if(!r.ok)throw Error(l.error||"Failed to fetch vars (".concat(r.status,")"));let n=Array.isArray(l.vars)?l.vars.map(String):[];eg(n),n.length>0&&H(e=>n.includes(e)?e:n[0]),Q(!0)}catch(e){var t;ej(null!==(t=null==e?void 0:e.message)&&void 0!==t?t:"Unknown error"),eg(null)}finally{ef(!1)}},e5=async function(){var e,t,a;let s=arguments.length>0&&void 0!==arguments[0]?arguments[0]:z;em(!0);try{let a=e2();if(!a)throw Error("Please select a base path");let r=new URLSearchParams;r.set("base_path",a),r.set("frame",String(s)),r.set("var",X),r.set("cmap",K),ee&&ee>0&&r.set("run",String(ee)),""!==es.trim()&&r.set("lower_limit",String(Number(es))),""!==el.trim()&&r.set("upper_limit",String(Number(el))),r.set("camera",d),r.set("merged",m?"1":"0");let l="/backend/plot/plot_vector?".concat(r.toString()),n=await fetch(l),i=await n.json();if(!n.ok)throw Error(i.error||"Failed to fetch plot (".concat(n.status,")"));eo(null!==(e=i.image)&&void 0!==e?e:null),ed(null!==(t=i.meta)&&void 0!==t?t:null)}catch(e){P({title:"Visualization error",description:null!==(a=null==e?void 0:e.message)&&void 0!==a?a:"Unknown error"}),eo(null),ed(null)}finally{em(!1)}};(0,r.useEffect)(()=>{!(M<100)&&e2()&&!q&&e4(z)},[z,i,d,m,M,q]),(0,r.useEffect)(()=>{if(M<100||!e2())return;let e=!1;return(async()=>{try{if(!q&&(await e4(z),e))return;await e5(z)}catch(e){}})(),()=>{e=!0}},[z,X,K,i,d,m,M,q]),(0,r.useEffect)(()=>(L?U.current=setInterval(()=>{O(e=>e<D?e+1:(B(!1),e))},400):U.current&&(clearInterval(U.current),U.current=null),()=>{U.current&&(clearInterval(U.current),U.current=null)}),[L,D]),(0,r.useEffect)(()=>{Z(z)},[z]),(0,r.useEffect)(()=>()=>{J.current&&(clearTimeout(J.current),J.current=null),U.current&&(clearInterval(U.current),U.current=null)},[]);let[e3,e6]=(0,r.useState)("ux"),e8=async()=>{var e,t;eW(!0),eY(null);try{let t=e2();if(!t)throw Error("Please select a base path");let a=new URLSearchParams;a.set("base_path",t),a.set("camera",d),a.set("run",String(ee)),a.set("merged",m?"1":"0");let s="/backend/pod_energy_modes?".concat(a.toString()),r=await fetch(s),l=await r.json();if(!r.ok)throw Error(l.error||"Failed to fetch POD energy");eJ(l),l.stacked&&Array.isArray(l.energy_fraction)?V(l.energy_fraction.length):!l.stacked&&Array.isArray(l.energy_fraction_ux)&&V(Math.max(l.energy_fraction_ux.length,(null===(e=l.energy_fraction_uy)||void 0===e?void 0:e.length)||0))}catch(e){eY(null!==(t=null==e?void 0:e.message)&&void 0!==t?t:"Unknown error"),eJ(null)}finally{eW(!1)}};return(0,r.useEffect)(()=>{M<100||I||!eN||e8()},[M,I,i,d,m,eN]),(0,s.jsx)("div",{className:"space-y-6",children:(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{className:"items-start",children:(0,s.jsx)(_,{className:"text-left",children:"Proper Orthogonal Decomposition (POD)"})}),(0,s.jsxs)(k,{children:[(0,s.jsx)("div",{className:"bg-white rounded-xl shadow p-4 mb-4",children:(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Base Path:"}),l.length>0?(0,s.jsx)("select",{value:String(i),onChange:e=>{let t=Number(e.target.value);o(t),eX({basepath_idx:t})},className:"border rounded px-2 py-1",children:l.map((e,t)=>{let a=e.replace(/\\/g,"/").replace(/\/+$|\\$/g,""),r=a.split("/").filter(Boolean),l=r.length>=2?r.slice(-2).join("/"):a;return(0,s.jsx)("option",{value:t,children:"".concat(t,": /").concat(l)},t)})}):(0,s.jsx)(F,{type:"text",value:"No base paths",readOnly:!0,className:"w-full"})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsx)("label",{htmlFor:"camera",className:"text-sm font-medium",children:"Camera:"}),(0,s.jsx)("select",{id:"camera",value:d,onChange:e=>{let t=e.target.value;u(t);let a=Number(t);Number.isFinite(a)&&eX({camera:a})},className:"border rounded px-2 py-1",children:c.map(e=>(0,s.jsxs)("option",{value:e,children:["Camera ",e]},e))}),(0,s.jsxs)("label",{className:"flex items-center gap-2 text-sm font-medium ml-2",children:[(0,s.jsx)("input",{type:"checkbox",checked:m,onChange:e=>{let t=e.target.checked;h(t),eX({use_merged:t})},className:"accent-soton-blue w-4 h-4 rounded border-gray-300"}),"Merged Data"]}),(0,s.jsx)("label",{className:"text-sm font-medium ml-4",children:"Run:"}),(0,s.jsx)("select",{value:eN,onChange:e=>e_(Number(e.target.value)),className:"border rounded px-2 py-1",disabled:eE,children:eb.map(e=>(0,s.jsxs)("option",{value:e,disabled:!1===ek[e],children:[e,!1===ek[e]?" (no ux/uy)":""]},e))}),eE&&(0,s.jsx)("span",{className:"text-xs text-gray-500 ml-2",children:"Checking data..."}),eT&&(0,s.jsx)("span",{className:"text-xs text-red-600 ml-2",children:eT})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsxs)("div",{className:"w-2/3 flex flex-col justify-center",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Number of modes (k_modes)"}),(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"Minimum 1"})]}),(0,s.jsx)("div",{className:"w-1/3 text-right",children:(0,s.jsx)(F,{type:"number",min:1,max:99999,className:"w-20 inline-block",value:b,onChange:e=>{let t=e.target.value;if(""===t){y("");return}let a=Number(t);Number.isFinite(a)||(a=1),y(a=Math.max(1,Math.floor(a))),eX({k_modes:a})}})})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsxs)("div",{className:"w-2/3",children:[(0,s.jsx)("div",{className:"text-sm font-medium",children:"Randomised"}),(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"Randomise snapshot order before decomposition"})]}),(0,s.jsx)("div",{className:"w-1/3 text-right",children:(0,s.jsx)(et,{checked:x,onCheckedChange:e=>{g(!!e),eX({randomised:!!e})}})})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsxs)("div",{className:"w-2/3",children:[(0,s.jsx)("div",{className:"text-sm font-medium",children:"Normalise"}),(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"Normalise snapshots prior to decomposition"})]}),(0,s.jsx)("div",{className:"w-1/3 text-right",children:(0,s.jsx)(et,{checked:p,onCheckedChange:e=>{f(!!e),eX({normalise:!!e})}})})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsxs)("div",{className:"w-2/3",children:[(0,s.jsx)("div",{className:"text-sm font-medium",children:"Stack U/Y"}),(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"Stack U and Y components instead of separate decompositions"})]}),(0,s.jsx)("div",{className:"w-1/3 text-right",children:(0,s.jsx)(et,{checked:v,onCheckedChange:e=>{j(!!e),eX({stack_u_y:!!e})}})})]})]})}),(0,s.jsxs)("div",{className:"bg-white rounded-xl shadow p-4 mb-4",children:[(0,s.jsx)("div",{className:"flex flex-col gap-2",children:(0,s.jsx)(eh,{value:M,className:"w-full"})}),(0,s.jsxs)("div",{className:"flex items-center justify-center gap-4 mt-4",children:[(0,s.jsx)(E,{className:"bg-green-600 hover:bg-green-700",onClick:e0,disabled:S||I||!eP,children:S?"Starting...":I?"Running...":"Start POD"}),(0,s.jsx)(E,{className:"bg-red-600 hover:bg-red-700",onClick:e1,disabled:S||!I,children:S?"Canceling...":"Cancel POD"})]})]}),M>=100&&(0,s.jsx)("div",{className:"bg-white rounded-xl shadow p-4 mb-4",children:(0,s.jsxs)("div",{className:"space-y-3",children:[(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Mode:"}),(0,s.jsx)("select",{value:String(z),onChange:e=>O(Math.max(1,Number(e.target.value))),className:"border rounded px-2 py-1",children:Array.from({length:Math.max(1,D)},(e,t)=>t+1).map(e=>(0,s.jsx)("option",{value:e,children:e},e))}),(0,s.jsx)("input",{type:"range",min:1,max:Math.max(1,D),value:W,onChange:e=>{let t=Math.max(1,Number(e.target.value));Z(t),Y||(J.current&&clearTimeout(J.current),J.current=setTimeout(()=>{O(t),J.current=null},80))},onPointerDown:()=>{G(!0),J.current&&(clearTimeout(J.current),J.current=null)},onPointerUp:()=>{G(!1),J.current&&clearTimeout(J.current),J.current=setTimeout(()=>{O(W),J.current=null},20)},className:"w-48"}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("button",{onClick:()=>B(e=>!e),className:"px-3 py-1 rounded border bg-white hover:bg-gray-50","aria-pressed":L,children:L?(0,s.jsx)("span",{children:"❙❙ Pause"}):(0,s.jsx)("span",{children:"▶ Play"})}),(0,s.jsxs)("span",{className:"text-xs text-gray-500",children:[z,"/",Math.max(1,D)]})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-3 flex-wrap",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Type:"}),(0,s.jsx)("select",{value:X,onChange:e=>H(e.target.value),className:"border rounded px-2 py-1",children:ep?(0,s.jsx)("option",{children:"Loading..."}):ex&&ex.length>0?ex.map(e=>(0,s.jsx)("option",{value:e,children:e},e)):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("option",{value:"ux",children:"ux"}),(0,s.jsx)("option",{value:"uy",children:"uy"})]})}),(0,s.jsx)("label",{className:"text-sm font-medium",children:"Colormap:"}),(0,s.jsxs)("select",{value:K,onChange:e=>$(e.target.value),className:"border rounded px-2 py-1",children:[(0,s.jsx)("option",{value:"default",children:"default"}),(0,s.jsx)("option",{value:"viridis",children:"viridis"}),(0,s.jsx)("option",{value:"plasma",children:"plasma"}),(0,s.jsx)("option",{value:"inferno",children:"inferno"}),(0,s.jsx)("option",{value:"magma",children:"magma"}),(0,s.jsx)("option",{value:"cividis",children:"cividis"}),(0,s.jsx)("option",{value:"jet",children:"jet"}),(0,s.jsx)("option",{value:"gray",children:"gray"})]}),(0,s.jsx)("label",{className:"text-sm font-medium",children:"Run:"}),(0,s.jsx)(F,{type:"number",min:1,value:ee,onChange:e=>ea(Math.max(1,Number(e.target.value))),className:"w-24"}),(0,s.jsx)("label",{className:"text-sm font-medium",children:"Lower:"}),(0,s.jsx)(F,{type:"number",value:es,onChange:e=>er(e.target.value),placeholder:"auto",className:"w-28"}),(0,s.jsx)("label",{className:"text-sm font-medium",children:"Upper:"}),(0,s.jsx)(F,{type:"number",value:el,onChange:e=>en(e.target.value),placeholder:"auto",className:"w-28"}),(0,s.jsx)(E,{className:"bg-soton-blue",onClick:async()=>{q||await e4(z),await e5(z)},disabled:eu||ep,children:eu||ep?"Loading...":"Render"})]})]})}),M>=100&&(0,s.jsxs)("div",{className:"mb-4",children:[ez&&(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"Checking available POD runs..."}),eD&&(0,s.jsx)("div",{className:"text-xs text-red-500",children:eD}),eR&&(0,s.jsxs)("div",{className:"flex items-center gap-4 mb-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Available POD Runs:"}),(0,s.jsx)("select",{value:ee,onChange:e=>ea(Number(e.target.value)),className:"border rounded px-2 py-1",children:eR.map(e=>(0,s.jsx)("option",{value:e,children:e},e))}),eL&&(0,s.jsx)("span",{className:"text-xs text-red-600",children:eL})]}),eL&&!eR&&(0,s.jsx)("div",{className:"text-xs text-red-600",children:eL})]}),M>=100&&!I&&eG&&(0,s.jsxs)("div",{className:"bg-white rounded-xl shadow p-4 mb-4",children:[eU&&(0,s.jsx)("div",{className:"text-xs text-gray-500",children:"Loading energy breakdown..."}),eZ&&(0,s.jsx)("div",{className:"text-xs text-red-500",children:eZ}),(0,s.jsx)(eS,{data:eG,component:e3,onComponentChange:e6,downloadUrl:"/backend/pod_energy_png?base_path=".concat(encodeURIComponent(e2()||""),"&camera=").concat(encodeURIComponent(String(d)),"&run=").concat(encodeURIComponent(String(ee)),"&merged=").concat(encodeURIComponent(m?"1":"0"))})]}),M>=100&&(0,s.jsx)("div",{className:"mt-4",children:ei?(0,s.jsxs)("div",{className:"flex flex-col items-center relative",children:[(0,s.jsx)("img",{src:"data:image/png;base64,".concat(ei),alt:"POD Vector",className:"rounded border w-full max-w-3xl"}),eu&&(0,s.jsx)("div",{className:"absolute inset-0 flex items-center justify-center bg-white bg-opacity-60",children:(0,s.jsx)("span",{className:"text-gray-500",children:"Rendering..."})}),ec&&(0,s.jsxs)("div",{className:"text-xs text-gray-500 mt-2",children:["Run: ",ec.run," • Var: ",ec.var]})]}):(0,s.jsx)("div",{className:"w-full h-48 flex items-center justify-center bg-gray-100 border rounded",children:(0,s.jsx)("span",{className:"text-gray-500",children:"No visualization loaded"})})})]})]})})}function eS(e){let{data:t,component:a,onComponentChange:r,downloadUrl:l}=e;if(!t)return null;let n=[],i=[];return t.stacked?(n=t.energy_fraction||[],i=t.energy_cumulative||[]):"ux"===a?(n=t.energy_fraction_ux||[],i=t.energy_cumulative_ux||[]):(n=t.energy_fraction_uy||[],i=t.energy_cumulative_uy||[]),(0,s.jsxs)("div",{children:[(0,s.jsxs)("div",{className:"flex items-center gap-4 mb-2",children:[(0,s.jsx)("span",{className:"font-medium text-sm",children:"Cumulative Energy Breakdown"}),!t.stacked&&(0,s.jsxs)("select",{value:a,onChange:e=>r(e.target.value),className:"border rounded px-2 py-1 text-xs",children:[(0,s.jsx)("option",{value:"ux",children:"ux"}),(0,s.jsx)("option",{value:"uy",children:"uy"})]})]}),(0,s.jsx)("div",{className:"text-xs text-gray-500 mb-2",children:n.length>0&&(0,s.jsxs)("span",{children:["Mode 1: ",(100*n[0]).toFixed(1),"% | Mode ",n.length,": ",(100*i[n.length-1]).toFixed(1),"% total"]})}),i.length>0&&(0,s.jsxs)("div",{className:"w-full max-w-md",children:[(0,s.jsxs)("svg",{viewBox:"0 0 300 120",width:"100%",height:"120",className:"border rounded",children:[(0,s.jsx)("rect",{x:"0",y:"0",width:"300",height:"120",fill:"#fff"}),[0,.25,.5,.75,1].map((e,t)=>(0,s.jsx)("line",{x1:40,x2:280,y1:10+(1-e)*90,y2:10+(1-e)*90,stroke:"#eee"},t)),(0,s.jsx)("line",{x1:40,y1:10,x2:40,y2:100,stroke:"#333"}),(0,s.jsx)("line",{x1:40,y1:100,x2:280,y2:100,stroke:"#333"}),(()=>{let e=i.map((e,t)=>{let a=40+t/Math.max(1,i.length-1)*240;return"".concat(a,",").concat(10+(1-Math.min(1,Math.max(0,e)))*90)}).join(" ");return(0,s.jsx)("polyline",{points:e,fill:"none",stroke:"#1f77b4",strokeWidth:2})})()]}),l&&(0,s.jsx)("div",{className:"mt-2 text-xs",children:(0,s.jsx)("a",{className:"text-soton-blue underline",href:l,target:"_blank",rel:"noreferrer",children:"Download cumulative energy PNG"})})]})]})}var ek=a(3113),eC=a(1047),eP=a(2636);function eM(e){let{config:t,updateConfig:a}=e,[l,n]=(0,r.useState)(""),[i,o]=(0,r.useState)("1"),[c,d]=(0,r.useState)(!1),[u,m]=(0,r.useState)([]),[h,x]=(0,r.useState)(""),[g,p]=(0,r.useState)("");(0,r.useEffect)(()=>{var e;let a=t.images||{},s=t.paths||{};console.log("ImageConfig received paths:",s),console.log("Camera count from config:",s.camera_count),n(void 0!==a.num_images?String(a.num_images):""),o(String(void 0!==s.camera_count?s.camera_count:Array.isArray(s.camera_numbers)?s.camera_numbers.length:1)),d(!!a.time_resolved),x((null===(e=a.vector_format)||void 0===e?void 0:e[0])||"%05d.mat");let r=a.image_format;a.time_resolved?"string"==typeof r?m([r]):Array.isArray(r)&&r.length?m([r[0]]):m(["B%05d.tif"]):Array.isArray(r)&&r.length?m(r):m(["B%05d_A.tif","B%05d_B.tif"])},[t]);let f=async(e,s,r,l,n)=>{p("Saving...");let i={images:{num_images:""===e?null:Number(e),time_resolved:r,image_format:r?l[0]:l,vector_format:[n]},paths:{camera_count:Number(s)}};try{let e=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(i)}),s=await e.json();if(!e.ok)throw Error(s.error||"Failed to update config");s.updated&&(s.updated.images&&a(["images"],{...t.images,...s.updated.images}),s.updated.paths&&a(["paths"],{...t.paths,...s.updated.paths})),p("Saved successfully!")}catch(e){p("Error: ".concat(e.message))}finally{setTimeout(()=>p(""),2e3)}};return(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)("div",{className:"flex items-center space-x-2 mb-6",children:[(0,s.jsx)(ek.Z,{className:"h-6 w-6 text-soton-blue"}),(0,s.jsx)("h2",{className:"text-2xl font-bold text-gray-800",children:"Image Configuration"})]}),(0,s.jsxs)(N,{children:[(0,s.jsxs)(w,{children:[(0,s.jsx)(_,{children:"Core Properties"}),(0,s.jsx)(S,{children:"Number of images, cameras, and processing mode"})]}),(0,s.jsxs)(k,{children:[(0,s.jsxs)("div",{className:"grid md:grid-cols-2 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"num_images",children:"Number of Images"}),(0,s.jsx)(F,{id:"num_images",type:"number",min:"0",value:l,onChange:e=>n(e.target.value),onBlur:()=>f(l,i,c,u,h)})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"num_cameras",children:"Camera Count"}),(0,s.jsx)(F,{id:"num_cameras",type:"number",min:"1",value:i,onChange:e=>o(e.target.value.replace(/[^0-9]/g,"")),onBlur:()=>f(l,i,c,u,h)}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Total number of cameras in your setup"})]})]}),(0,s.jsxs)("div",{className:"mt-4 flex items-center gap-2",children:[(0,s.jsx)(et,{id:"time_resolved",checked:c,onCheckedChange:e=>{let t;if(d(e),e)m(t=[(u[0]||"B%05d.tif").replace(/_A\.tif$/i,".tif")]);else{if(1===u.length){let e=u[0].replace(/\.tif$/i,"");t=["".concat(e,"_A.tif"),"".concat(e,"_B.tif")]}else t=["B%05d_A.tif","B%05d_B.tif"];m(t)}f(l,i,e,t,h)}}),(0,s.jsx)(R,{htmlFor:"time_resolved",children:"Time Resolved (single image pattern)"})]})]})]}),(0,s.jsxs)(N,{children:[(0,s.jsxs)(w,{children:[(0,s.jsx)(_,{children:"Filename Patterns"}),(0,s.jsx)(S,{children:"Define the naming convention for your files"})]}),(0,s.jsxs)(k,{className:"space-y-6",children:[(0,s.jsxs)("div",{children:[(0,s.jsxs)(R,{className:"font-semibold",children:["Raw Image Pattern",c?"":"s"]}),(0,s.jsxs)("div",{className:"space-y-2 mt-2",children:[u.map((e,t)=>(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(F,{className:"font-mono",value:e,onChange:e=>{let a=[...u];a[t]=e.target.value,m(a)},onBlur:()=>f(l,i,c,u,h)}),!c&&u.length>1&&(0,s.jsx)(E,{variant:"ghost",size:"icon",onClick:()=>{let e=u.filter((e,a)=>a!==t);m(e),f(l,i,c,e,h)},children:(0,s.jsx)(eC.Z,{className:"h-4 w-4"})})]},t)),!c&&(0,s.jsxs)(E,{variant:"outline",size:"sm",onClick:()=>{m([...u,""])},children:[(0,s.jsx)(Y.Z,{className:"h-4 w-4 mr-2"})," Add Pattern"]}),(0,s.jsxs)("p",{className:"text-xs text-muted-foreground",children:["Use format codes like ",(0,s.jsx)("code",{children:"%05d"})," for the frame index. ",(0,s.jsx)("br",{}),(0,s.jsx)("code",{children:"%05d"})," means a 5-digit number, zero-padded (e.g. ",(0,s.jsx)("code",{children:"b00001"}),")."]})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{className:"font-semibold",children:"Vector Pattern"}),(0,s.jsx)(F,{className:"font-mono mt-2",value:h,onChange:e=>x(e.target.value),onBlur:()=>f(l,i,c,u,h)})]}),(0,s.jsxs)("div",{className:"text-xs text-muted-foreground flex items-center gap-2",children:[(0,s.jsx)(eP.Z,{className:"h-3 w-3"})," ",g||"Changes are saved when you finish editing a box."]})]})]})]})}let eE=e=>{let{backendUrl:t,config:a}=e,[s,l]=(0,r.useState)(()=>{var e;return(null==a?void 0:null===(e=a.paths)||void 0===e?void 0:e.base_paths)||[]}),[n,i]=(0,r.useState)(0),[o,c]=(0,r.useState)(1),[d,u]=(0,r.useState)("ux"),[m,h]=(0,r.useState)(1),[x,g]=(0,r.useState)(""),[p,f]=(0,r.useState)(""),[v,j]=(0,r.useState)("default"),[b,y]=(0,r.useState)(null),[N,w]=(0,r.useState)(null),[_,S]=(0,r.useState)(!1),[k,C]=(0,r.useState)(null),[P,M]=(0,r.useState)(!1),E=(0,r.useMemo)(()=>{var e;return(null==a?void 0:null===(e=a.paths)||void 0===e?void 0:e.camera_numbers)||[]},[a]),[F,T]=(0,r.useState)(()=>E.length>0?E[0]:1);(0,r.useEffect)(()=>{0===E.length||E.includes(F)||T(E[0])},[E.length,E[0]]);let[I,R]=(0,r.useState)(!1),[A,z]=(0,r.useState)(!1),[O,D]=(0,r.useState)(o),[V,L]=(0,r.useState)(!1);(0,r.useRef)(null);let B=(0,r.useRef)(null),[U,W]=(0,r.useState)(!1),[Z,Y]=(0,r.useState)(!1),[G,J]=(0,r.useState)(!1),[X,H]=(0,r.useState)(null),[K,$]=(0,r.useState)(null),[q,Q]=(0,r.useState)(!1),[ee,et]=(0,r.useState)(null),[ea,es]=(0,r.useState)(null),[er,el]=(0,r.useState)(!1),[en,ei]=(0,r.useState)(null),[eo,ec]=(0,r.useState)(!1),[ed,eu]=(0,r.useState)("0"),[em,eh]=(0,r.useState)("0"),[ex,eg]=(0,r.useState)(null),[ep,ef]=(0,r.useState)(!1),ev=(0,r.useMemo)(()=>s.length>0&&n>=0&&n<s.length?s[n]:"",[s,n]);(0,r.useMemo)(()=>"".concat(ev,"/").concat(String(o).padStart(5,"0"),".mat"),[ev,o]),(0,r.useMemo)(()=>"".concat(ev,"/coordinates.mat"),[ev]);let ej=(0,r.useRef)(null),[eb,ey]=(0,r.useState)(null),eN=(0,r.useRef)(null),ew=(0,r.useRef)(null),e_=(0,r.useRef)(!1),eS=(0,r.useRef)(null),[ek,eC]=(0,r.useState)(!1),[eP,eM]=(0,r.useState)({left:0,top:0}),eE=window.devicePixelRatio||1,[eF,eT]=(0,r.useState)(9999),[eI,eR]=(0,r.useState)([]),eA=(0,r.useCallback)(async()=>{S(!0),C(null);try{var e,a;if(!ev)throw Error("Please provide a base path");let s=new URLSearchParams;s.set("base_path",ev),s.set("frame",String(o)),s.set("var",d),s.set("cmap",v),m&&m>0&&s.set("run",String(m)),""!==x.trim()&&s.set("lower_limit",String(Number(x))),""!==p.trim()&&s.set("upper_limit",String(Number(p))),s.set("camera",String(F)),s.set("merged",I?"1":"0"),""!==ed.trim()&&s.set("x_offset",ed),""!==em.trim()&&s.set("y_offset",em);let r="".concat(t,"/plot/plot_vector?").concat(s.toString()),l=await fetch(r),n=await l.json();if(!l.ok)throw Error(n.error||"Failed to fetch vector plot");if(y(null!==(e=n.image)&&void 0!==e?e:null),w(null!==(a=n.meta)&&void 0!==a?a:null),n.meta&&null!=n.meta.run){let e=Number(n.meta.run);Number.isFinite(e)&&e>0&&h(e)}return n.meta&&null!=n.meta.var&&"string"==typeof n.meta.var&&n.meta.var!==d&&u(n.meta.var),!0}catch(e){return C(e.message||"Unknown error"),!1}finally{S(!1)}},[ev,o,d,m,x,p,v,t,F,I,ed,em]),ez=(0,r.useCallback)(async()=>{Q(!0),et(null);try{if(!ev)throw Error("Please provide a base path");let e=new URLSearchParams;e.set("base_path",ev),e.set("camera",String(F)),e.set("merged",I?"1":"0");let a="".concat(t,"/plot/check_stat_vars?").concat(e.toString()),s=await fetch(a),r=await s.json();if(!s.ok)throw Error(r.error||"Failed to fetch stat vars (".concat(s.status,")"));let l=Array.isArray(r.vars)?r.vars.map(String):[];$(l),l.length>0&&u(e=>l.includes(e)?e:l[0])}catch(t){var e;et(null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Unknown error"),$(null)}finally{Q(!1)}},[ev,F,I,t]),eO=(0,r.useCallback)(async()=>{el(!0),ei(null);try{if(!ev)throw Error("Please provide a base path");let e=new URLSearchParams;e.set("base_path",ev),e.set("frame",String(o)),e.set("camera",String(F)),e.set("merged",I?"1":"0");let a="".concat(t,"/plot/check_vars?").concat(e.toString()),s=await fetch(a),r=await s.json();if(!s.ok)throw Error(r.error||"Failed to fetch frame vars (".concat(s.status,")"));let l=Array.isArray(r.vars)?r.vars.map(String):[];es(l),l.length>0&&u(e=>l.includes(e)?e:l[0])}catch(t){var e;ei(null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Unknown error"),es(null)}finally{el(!1)}},[ev,o,F,I,t]),eD=(0,r.useCallback)(async()=>{W(!0);try{if(!ev)throw Error("Please provide a base path");let e=new URLSearchParams;e.set("base_path",ev),e.set("camera",String(F)),e.set("merged",I?"1":"0"),e.set("var",d);let a="".concat(t,"/plot/check_limits?").concat(e.toString()),s=await fetch(a),r=await s.json();if(!s.ok)throw Error(r.error||"Failed to fetch limits (".concat(s.status,")"));"number"==typeof r.min&&"number"==typeof r.max?(g(String(r.min)),f(String(r.max))):console.warn("check_limits returned unexpected payload",r)}catch(e){console.error("Error fetching limits:",e)}finally{W(!1)}},[ev,F,I,d,t,g,f]),eV=(0,r.useCallback)(async()=>{try{if(!ev)return[];let e=new URLSearchParams;e.set("base_path",ev),e.set("camera",String(F)),e.set("merged",I?"1":"0");let a="".concat(t,"/plot/check_runs?").concat(e.toString()),s=await fetch(a),r=await s.json();if(!s.ok)return[];return Array.isArray(r.runs)?r.runs.map(Number).filter(e=>Number.isFinite(e)&&e>0):[]}catch(e){return[]}},[ev,F,I,t]),eL=(0,r.useCallback)(async()=>{var e,a,s;J(!0),H(null);try{if(!ev)throw Error("Please provide a base path");let s=new URLSearchParams;s.set("base_path",ev),s.set("frame",String(o)),s.set("var",d),s.set("cmap",v),m&&m>0&&s.set("run",String(m)),""!==x.trim()&&s.set("lower_limit",String(Number(x))),""!==p.trim()&&s.set("upper_limit",String(Number(p))),s.set("camera",String(F)),s.set("merged",I?"1":"0");let r="".concat(t,"/plot/plot_stats?").concat(s.toString()),l=await fetch(r),n=await l.json();if(!l.ok)throw Error(n.error||"Failed to fetch stats plot (".concat(l.status,")"));if(y(null!==(e=n.image)&&void 0!==e?e:null),w(null!==(a=n.meta)&&void 0!==a?a:null),n.meta&&null!=n.meta.run){let e=Number(n.meta.run);Number.isFinite(e)&&e>0&&h(e)}n.meta&&null!=n.meta.var&&"string"==typeof n.meta.var&&n.meta.var!==d&&u(n.meta.var),M(!0)}catch(e){H(null!==(s=null==e?void 0:e.message)&&void 0!==s?s:"Unknown error")}finally{J(!1)}},[ev,o,d,m,x,p,v,t,F,I]),eB=(0,r.useCallback)(async()=>{if(M(!0),Z){await eL();return}await eO(),await eA()},[Z,eO,eA,eL]),eU=async()=>{let e=!Z;Y(e),e?(g(""),f(""),H(null),await ez(),await eL()):(H(null),$(null),et(null))},eW=async e=>{if(!eo||!(null==N?void 0:N.axes_bbox)||!ej.current)return;let a=ej.current.getBoundingClientRect(),s=e.clientX-a.left,r=e.clientY-a.top,l=N.axes_bbox,n=l.png_width/a.width,i=l.png_height/a.height,c=s*n,u=r*i;if(c<l.left||c>l.left+l.width||u<l.top||u>l.top+l.height)return;let h=(c-l.left)/l.width,x=(u-l.top)/l.height;try{var g,p;let e=new URLSearchParams;e.set("base_path",ev),e.set("camera",String(F)),e.set("frame",String(o)),e.set("var",d),e.set("run",String(m)),e.set("merged",I?"1":"0"),e.set("x_percent",h.toString()),e.set("y_percent",x.toString());let a="".concat(t,"/plot/get_vector_at_position?").concat(e.toString()),s=await fetch(a),r=await s.json();if(!s.ok||r.error)throw Error(r.error||"Failed to get vector value");alert("New datum set at physical position: x=".concat(null===(g=r.x)||void 0===g?void 0:g.toFixed(4),", y=").concat(null===(p=r.y)||void 0===p?void 0:p.toFixed(4))),await eY(r.x,r.y),eA()}catch(e){C("Failed to set datum: ".concat(e.message))}ec(!1)},eZ=async()=>{try{let e={base_path_idx:n,camera:F,run:m,x_offset:Number(ed)||0,y_offset:Number(em)||0,merged:I?1:0},a="".concat(t,"/calibration/set_datum"),s=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)}),r=await s.json();if(!s.ok)throw Error(r.error||"Failed to update offsets");eA()}catch(e){C("Failed to update offsets: ".concat(e.message))}},eY=async(e,a)=>{try{let s={base_path_idx:n,camera:F,run:m,x:e,y:a,x_offset:Number(ed)||0,y_offset:Number(em)||0,merged:I?1:0},r="".concat(t,"/calibration/set_datum"),l=await fetch(r,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(s)}),i=await l.json();if(!l.ok)throw Error(i.error||"Failed to set datum")}catch(e){C("Failed to set datum: ".concat(e.message))}},eG=async()=>{ef(!1),eg(null),C(null);try{if(!ev)throw Error("Please provide a base path");let e=async(e,a)=>{let s=new URLSearchParams;s.set("base_path",ev),s.set("camera",String(F)),s.set("frame",String(o)),s.set("var",d),s.set("run",String(m)),s.set("merged",I?"1":"0"),s.set("x_percent",e.toString()),s.set("y_percent",a.toString());let r="".concat(t,"/plot/get_vector_at_position?").concat(s.toString()),l=await fetch(r),n=await l.json();if(!l.ok||n.error)throw Error(n.error||"Failed to get corner coordinate");return{x:n.x,y:n.y}},[a,s,r,l]=await Promise.all([e(0,0),e(1,0),e(0,1),e(1,1)]);eg({topLeft:a,topRight:s,bottomLeft:r,bottomRight:l}),ef(!0)}catch(e){C("Failed to get corner coordinates: ".concat(e.message))}},eJ=(0,r.useCallback)(()=>{eN.current&&(window.clearTimeout(eN.current),eN.current=null),e_.current=!1,ey(null)},[]);(0,r.useEffect)(()=>{eJ()},[b,N,d,o,Z,F,I,eJ]);let eX=(0,r.useCallback)((e,a)=>{if(e_.current)return;e_.current=!0;let s=Z?"get_stats_value_at_position":"get_vector_at_position",r=new URLSearchParams;r.set("base_path",ev),r.set("camera",String(F)),r.set("frame",String(o)),r.set("var",d),r.set("run",String(m)),r.set("merged",I?"1":"0"),r.set("x_percent",e.toString()),r.set("y_percent",a.toString()),fetch("".concat(t,"/plot/").concat(s,"?").concat(r.toString())).then(e=>e.json().then(t=>({ok:e.ok,json:t}))).then(e=>{let{ok:t,json:a}=e;e_.current=!1,t&&!a.error&&ey(e=>e?{...e,...a}:null)}).catch(()=>{e_.current=!1})},[t,ev,F,o,d,m,I,Z]),eH=(0,r.useCallback)(e=>{let t=null==N?void 0:N.axes_bbox,a=ej.current;if(!a||!t)return;let s=a.getBoundingClientRect(),r=e.clientX-s.left,l=e.clientY-s.top;if(r<0||l<0||r>s.width||l>s.height){eJ();return}let n=t.png_width/s.width,i=t.png_height/s.height,c=r*n,u=l*i;if(c<t.left||c>t.left+t.width||u<t.top||u>t.top+t.height){eJ();return}let m=(c-t.left)/t.width,h=(u-t.top)/t.height;ey({x:NaN,y:NaN,ux:null,uy:null,value:null,i:-1,j:-1,clientX:e.clientX,clientY:e.clientY});let x=ew.current;x&&x.px===Math.round(c)&&x.py===Math.round(u)&&x.frame===o&&x.varName===d&&x.mean===Z||(ew.current={px:Math.round(c),py:Math.round(u),frame:o,varName:d,mean:Z},eN.current&&window.clearTimeout(eN.current),eN.current=window.setTimeout(()=>{eX(m,h)},120))},[N,eX,o,d,Z,eJ]),eK=(0,r.useCallback)(()=>{eJ()},[eJ]);(0,r.useEffect)(()=>{(async function(){try{var e;let a=await fetch("".concat(t,"/config"));if(!a.ok)return;let s=await a.json(),r=null===(e=s.images)||void 0===e?void 0:e.num_images;Number.isFinite(r)&&r>0&&eT(r)}catch(e){console.error("Error fetching config for frame count:",e)}})()},[t]),(0,r.useEffect)(()=>{ev&&!Z&&eV().then(e=>{e.length>0&&(h(Math.max(...e)),M(!0))}).catch(()=>{})},[ev,Z,eV]),(0,r.useEffect)(()=>{P&&(ev||s.length>0)&&(Z?eL():eA())},[P,ev,o,d,m,x,p,v,F,I,n,Z,eA,eL]),(0,r.useEffect)(()=>(A?B.current=setInterval(()=>{c(e=>e+1)},300):B.current&&(clearInterval(B.current),B.current=null),()=>{B.current&&(clearInterval(B.current),B.current=null)}),[A]),(0,r.useEffect)(()=>{k&&A&&z(!1)},[k,A]);let e$=(0,r.useCallback)(function(e){let t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:"image/png",a=atob(e),s=[];for(let e=0;e<a.length;e+=512){let t=a.slice(e,e+512),r=Array(t.length);for(let e=0;e<t.length;e++)r[e]=t.charCodeAt(e);s.push(new Uint8Array(r))}return new Blob(s,{type:t})},[]),eq=(0,r.useCallback)(()=>{if(!b)return;let e="vector_".concat(Z?"mean":"frame_".concat(o),"_").concat(d,".png"),t=document.createElement("a");t.href="data:image/png;base64,".concat(b),t.download=e,document.body.appendChild(t),t.click(),document.body.removeChild(t)},[b,Z,o,d]),eQ=(0,r.useCallback)(async()=>{if(b)try{let e=e$(b,"image/png"),t=window.ClipboardItem;if(navigator.clipboard&&"write"in navigator.clipboard&&t)await navigator.clipboard.write([new t({"image/png":e})]);else{let t=URL.createObjectURL(e);window.open(t,"_blank","noopener,noreferrer"),setTimeout(()=>URL.revokeObjectURL(t),1e4)}}catch(t){var e;C("Failed to copy image: ".concat(null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Unknown error"))}},[b,e$]),e0=(0,r.useCallback)(async e=>{try{S(!0),C(null);let a=await fetch("".concat(t,"/plot/transform_frame"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({base_path:ev,camera:F,frame:o,transformation:e,merged:I,type_name:"instantaneous"})}),s=await a.json();s.success?(eR(t=>[...t,e]),await eB()):C(s.error||"Transformation failed")}catch(e){var a;C("Transformation failed: ".concat(null!==(a=null==e?void 0:e.message)&&void 0!==a?a:"Unknown error"))}finally{S(!1)}},[t,ev,F,o,I,eB]),e1=(0,r.useCallback)(async()=>{try{S(!0),C(null);let e=await fetch("".concat(t,"/plot/clear_transform"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({base_path:ev,camera:F,frame:o,merged:I,type_name:"instantaneous"})}),a=await e.json();a.success?(eR([]),await eB()):C(a.error||"Clear transforms failed")}catch(t){var e;C("Clear transforms failed: ".concat(null!==(e=null==t?void 0:t.message)&&void 0!==e?e:"Unknown error"))}finally{S(!1)}},[t,ev,F,o,I,eB]),[e2,e4]=(0,r.useState)(null),e5=(0,r.useCallback)(async e=>{try{S(!0),C(null),e4(null);let a=await fetch("".concat(t,"/plot/transform_all_frames"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({base_path:ev,camera:F,transformations:e,merged:I,type_name:"instantaneous",image_count:eF})}),s=await a.json();s.job_id?(e4({job_id:s.job_id,status:s.status,progress:0,processed_frames:0,total_frames:s.total_frames}),e3(s.job_id)):C(s.error||"Failed to start transformation job")}catch(e){var a;C("Failed to start transformation: ".concat(null!==(a=null==e?void 0:e.message)&&void 0!==a?a:"Unknown error"))}finally{S(!1)}},[t,ev,F,I,eF]),e3=(0,r.useCallback)(async e=>{try{let a=await fetch("".concat(t,"/plot/transform_all_frames/status/").concat(e)),s=await a.json();e4(s),"running"===s.status||"starting"===s.status?setTimeout(()=>e3(e),1e3):"completed"===s.status&&await eB()}catch(e){var a;C("Failed to check transformation status: ".concat(null!==(a=null==e?void 0:e.message)&&void 0!==a?a:"Unknown error"))}},[t,eB]);return{basePaths:s,basePathIdx:n,setBasePathIdx:i,index:o,setIndex:c,type:d,setType:u,run:m,setRun:h,lower:x,setLower:g,upper:p,setUpper:f,cmap:v,setCmap:j,imageSrc:b,meta:N,loading:_,error:k,cameraOptions:E,camera:F,setCamera:T,merged:I,setMerged:R,playing:A,setPlaying:z,limitsLoading:U,meanMode:Z,setMeanMode:Y,statsLoading:G,statsError:X,statVars:K,statVarsLoading:q,frameVars:ea,frameVarsLoading:er,datumMode:eo,setDatumMode:ec,xOffset:ed,setXOffset:eu,yOffset:em,setYOffset:eh,cornerCoordinates:ex,showCorners:ep,setShowCorners:ef,imgRef:ej,hoverData:eb,magnifierRef:eS,magVisible:ek,magPos:eP,maxFrameCount:eF,MAG_SIZE:180,dpr:eE,handlePlayToggle:()=>{z(e=>!e)},handleRender:eB,toggleMeanMode:eU,handleImageClick:eW,updateOffsets:eZ,fetchCornerCoordinates:eG,fetchLimits:eD,onMouseMove:eH,onMouseLeave:eK,handleMagnifierMove:e=>{let t=ej.current,a=eS.current;if(!t||!a){eC(!1);return}let s=t.getBoundingClientRect(),r=e.clientX-s.left,l=e.clientY-s.top;if(r<0||l<0||r>s.width||l>s.height){eC(!1);return}eC(!0),eM({left:e.clientX-90,top:e.clientY-90});let n=a.getContext("2d");if(!n)return;n.clearRect(0,0,180*eE,180*eE),n.save(),n.beginPath(),n.arc(180*eE/2,180*eE/2,180*eE/2,0,2*Math.PI),n.clip();let i=r/s.width*t.naturalWidth,o=l/s.height*t.naturalHeight;n.drawImage(t,i-36,o-36,72,72,0,0,180*eE,180*eE);let c=180*eE/2,d=180*eE/2,u=180*eE*.3;n.save(),n.beginPath(),n.lineWidth=Math.max(2,1.5*eE),n.strokeStyle="rgba(0,0,0,0.8)",n.moveTo(c-u,d),n.lineTo(c+u,d),n.moveTo(c,d-u),n.lineTo(c,d+u),n.stroke(),n.beginPath(),n.lineWidth=Math.max(1,eE),n.strokeStyle="rgba(255,255,255,0.95)",n.moveTo(c-u,d),n.lineTo(c+u,d),n.moveTo(c,d-u),n.lineTo(c,d+u),n.stroke(),n.restore(),n.restore(),n.beginPath(),n.arc(c,d,180*eE/2-2*eE,0,2*Math.PI),n.lineWidth=3*eE,n.strokeStyle="#005fa3",n.stroke()},handleMagnifierLeave:()=>{eC(!1)},basename:e=>e?e.replace(/\\/g,"/").split("/").filter(Boolean).pop()||e:"",downloadCurrentView:eq,copyCurrentView:eQ,applyTransformation:e0,applyTransformationToAllFrames:e5,transformationJob:e2,appliedTransforms:eI,setAppliedTransforms:eR,clearTransforms:e1,effectiveDir:ev}},eF=(e,t,a,s)=>{let[l,n]=(0,r.useState)([]),[i,o]=(0,r.useState)(!1),[c,d]=(0,r.useState)(null),[u,m]=(0,r.useState)(!1),[h,x]=(0,r.useState)("not_started"),[g,p]=(0,r.useState)(null);(0,r.useEffect)(()=>{a.length>=2&&0===l.length&&n([a[0],a[1]])},[a,l.length]);let f=(0,r.useCallback)(async a=>{if(l.length<2){alert("Please select at least 2 cameras to merge");return}o(!0),x("starting");try{let r={base_path_idx:t,cameras:l,type_name:"instantaneous",endpoint:"",image_count:s};void 0!==a&&(r.frame_idx=a);let n=await fetch("".concat(e).concat(void 0!==a?"/merge_vectors/merge_one":"/merge_vectors/merge_all"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r)}),i=await n.json();if(!n.ok)throw Error(i.error||"Failed to start merging");void 0!==a?(x("completed"),p({progress:100,message:i.message}),o(!1)):(d(i.job_id),x("running"))}catch(e){console.error("Error starting merge:",e),x("failed"),p({error:e.message}),o(!1)}},[e,t,l,s]);return(0,r.useEffect)(()=>{if(!c||"completed"===h||"failed"===h)return;let t=setInterval(async()=>{try{let a=await fetch("".concat(e,"/merge_vectors/status/").concat(c)),s=await a.json();x(s.status),p(s),("completed"===s.status||"failed"===s.status)&&(o(!1),clearInterval(t))}catch(e){console.error("Error polling merge status:",e)}},1e3);return()=>clearInterval(t)},[c,h,e]),{selectedCameras:l,setSelectedCameras:n,merging:i,mergingJobId:c,showDialog:u,setShowDialog:m,jobStatus:h,jobDetails:g,mergeVectors:f,resetMerging:(0,r.useCallback)(()=>{o(!1),d(null),x("not_started"),p(null)},[])}};function eT(e){var t;let{backendUrl:a="/backend",config:l}=e,{basePaths:n,basePathIdx:i,setBasePathIdx:o,index:c,setIndex:d,type:u,setType:m,run:h,setRun:x,lower:g,setLower:p,upper:f,setUpper:v,cmap:j,setCmap:b,imageSrc:y,meta:S,loading:C,error:P,cameraOptions:M,camera:T,setCamera:I,merged:R,setMerged:A,playing:z,limitsLoading:O,meanMode:B,statsLoading:U,statsError:Y,statVars:G,statVarsLoading:J,frameVars:X,frameVarsLoading:H,datumMode:K,setDatumMode:$,xOffset:q,setXOffset:Q,yOffset:ee,setYOffset:et,cornerCoordinates:ea,showCorners:es,setShowCorners:er,imgRef:el,hoverData:en,magnifierRef:ei,magVisible:eo,magPos:ec,maxFrameCount:ed,handlePlayToggle:eu,handleRender:em,toggleMeanMode:eh,handleImageClick:ex,updateOffsets:eg,fetchCornerCoordinates:ep,onMouseMove:ef,onMouseLeave:ev,handleMagnifierMove:ej,handleMagnifierLeave:eb,basename:ey,downloadCurrentView:eN,copyCurrentView:ew,fetchLimits:e_,applyTransformation:eS,applyTransformationToAllFrames:ek,transformationJob:eC,appliedTransforms:eP,setAppliedTransforms:eM,clearTransforms:eT,MAG_SIZE:eI,dpr:eR,effectiveDir:eA}=eE({backendUrl:a,config:l}),ez=(0,r.useMemo)(()=>{var e;let t=(null==l?void 0:null===(e=l.paths)||void 0===e?void 0:e.camera_numbers)||[];return t.length>0?t:M},[null==l?void 0:null===(t=l.paths)||void 0===t?void 0:t.camera_numbers,M]);(0,r.useEffect)(()=>{ez.length>0&&!T&&I(ez[0])},[ez,T,I]);let[eO,eD]=(0,r.useState)(null);(0,r.useEffect)(()=>{en&&"number"==typeof en.x&&!isNaN(en.x)&&en.i>=0&&eD(en)},[en]);let{selectedCameras:eV,includeMerged:eL,calculating:eB,statisticsJobId:eU,showDialog:eW,setSelectedCameras:eZ,setIncludeMerged:eY,setShowDialog:eG,jobStatus:eJ,jobDetails:eX,calculateStatistics:eH,resetStatistics:eK}=function(){let e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"/backend",t=arguments.length>1&&void 0!==arguments[1]?arguments[1]:0,a=(arguments.length>2&&void 0!==arguments[2]&&arguments[2],arguments.length>3&&void 0!==arguments[3]?arguments[3]:1e3),[s,l]=(0,r.useState)([]),[n,i]=(0,r.useState)(!1),[o,c]=(0,r.useState)(!1),[d,u]=(0,r.useState)(null),[m,h]=(0,r.useState)(!1),{status:x,details:g}=(t=>{let[a,s]=(0,r.useState)("not_started"),[l,n]=(0,r.useState)(null),i=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!t){s("not_started"),n(null),i.current&&(clearInterval(i.current),i.current=null);return}let a=!0,r=async()=>{try{let l=await fetch("".concat(e,"/statistics/status/").concat(t));if(!l.ok)throw Error("Failed to fetch status");let o=await l.json();a&&(s(o.status||"not_started"),n(o),"completed"===o.status||"failed"===o.status?(i.current&&(clearInterval(i.current),i.current=null),c(!1)):"running"!==o.status&&"starting"!==o.status||i.current||(i.current=setInterval(r,1e3)))}catch(e){console.error("Error fetching statistics status:",e),a&&(s("error"),n({status:"error",progress:0,error:String(e)})),i.current&&(clearInterval(i.current),i.current=null)}};return r(),()=>{a=!1,i.current&&(clearInterval(i.current),i.current=null)}},[t,e]),{status:a,details:l}})(d),p=async()=>{if(0===s.length&&!n){alert("Please select at least one camera or merged data");return}c(!0);try{let r=await fetch("".concat(e,"/statistics/calculate"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({base_path_idx:t,cameras:s.map(e=>parseInt(e.replace("Cam",""))),include_merged:n,image_count:a,type_name:"instantaneous",endpoint:""})});if(!r.ok){let e=await r.json();throw Error(e.error||"Failed to start statistics calculation")}let l=await r.json();u(l.parent_job_id),h(!1),console.log("Statistics calculation started! Job ID: ".concat(l.parent_job_id))}catch(e){console.error("Error starting statistics calculation:",e),alert("Error: ".concat(e.message)),c(!1)}};return{selectedCameras:s,includeMerged:n,calculating:o,statisticsJobId:d,showDialog:m,setSelectedCameras:l,setIncludeMerged:i,setCalculating:c,setStatisticsJobId:u,setShowDialog:h,jobStatus:x,jobDetails:g,calculateStatistics:p,resetStatistics:()=>{u(null),c(!1)}}}(a,i,ez,ed),e$=(null==eX?void 0:eX.overall_progress)||(null==eX?void 0:eX.progress)||0,eq=(null==eX?void 0:eX.error)||null,{selectedCameras:eQ,merging:e0,mergingJobId:e1,showDialog:e2,setSelectedCameras:e4,setShowDialog:e5,jobStatus:e3,jobDetails:e6,mergeVectors:e8,resetMerging:e7}=eF(a,i,ez,ed),e9=(null==e6?void 0:e6.progress)||0,te=(null==e6?void 0:e6.error)||null;return(0,s.jsx)("div",{className:"space-y-6",children:(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Results Viewer"})}),(0,s.jsxs)(k,{children:[(0,s.jsx)("div",{className:"flex flex-col gap-4 mb-4",children:(0,s.jsxs)("div",{className:"flex flex-col gap-4 mb-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Base Path:"}),(0,s.jsxs)(D,{value:String(i),onValueChange:e=>o(Number(e)),children:[(0,s.jsx)(L,{id:"basepath",children:(0,s.jsx)(V,{placeholder:"Pick base path"})}),(0,s.jsx)(W,{children:n.map((e,t)=>(0,s.jsx)(Z,{value:String(t),children:ey(e)},t))})]})]}),(0,s.jsx)("div",{className:"p-3 bg-gray-50 border border-gray-200 rounded-lg",children:(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{htmlFor:"camera",className:"text-sm font-medium text-gray-700",children:"Camera:"}),(0,s.jsxs)(D,{value:String(T),onValueChange:e=>I(Number(e)),disabled:0===ez.length,children:[(0,s.jsx)(L,{id:"camera",className:"w-28",children:(0,s.jsx)(V,{placeholder:0===ez.length?"No cameras":"Select"})}),(0,s.jsx)(W,{children:0===ez.length?(0,s.jsx)(Z,{value:"none",disabled:!0,children:"No cameras available"}):ez.map((e,t)=>(0,s.jsx)(Z,{value:String(e),children:e},t))})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4 ml-4",children:[(0,s.jsxs)("label",{className:"inline-flex items-center gap-2 px-3 py-1.5 bg-white border border-gray-300 rounded-md hover:bg-gray-50 cursor-pointer transition-colors",children:[(0,s.jsx)("input",{type:"checkbox",checked:R,onChange:e=>A(e.target.checked),className:"w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500 focus:ring-2"}),(0,s.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Use Merged Data"})]}),(0,s.jsxs)("label",{className:"inline-flex items-center gap-2 px-3 py-1.5 bg-white border border-gray-300 rounded-md hover:bg-gray-50 cursor-pointer transition-colors",children:[(0,s.jsx)("input",{type:"checkbox",checked:B,onChange:()=>{eh()},className:"w-4 h-4 text-blue-600 border-gray-300 rounded focus:ring-blue-500 focus:ring-2"}),(0,s.jsx)("span",{className:"text-sm font-medium text-gray-700",children:"Show Mean Statistics"}),J&&(0,s.jsx)("span",{className:"text-xs text-gray-500",children:"(loading...)"})]})]})]})}),B&&Y&&(0,s.jsx)("div",{className:"p-4 bg-amber-50 border-l-4 border-amber-400 rounded-r-lg",children:(0,s.jsxs)("div",{className:"flex items-start gap-3",children:[(0,s.jsx)("svg",{className:"w-5 h-5 text-amber-600 mt-0.5 flex-shrink-0",fill:"currentColor",viewBox:"0 0 20 20",children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M8.257 3.099c.765-1.36 2.722-1.36 3.486 0l5.58 9.92c.75 1.334-.213 2.98-1.742 2.98H4.42c-1.53 0-2.493-1.646-1.743-2.98l5.58-9.92zM11 13a1 1 0 11-2 0 1 1 0 012 0zm-1-8a1 1 0 00-1 1v3a1 1 0 002 0V6a1 1 0 00-1-1z",clipRule:"evenodd"})}),(0,s.jsxs)("div",{className:"flex-1",children:[(0,s.jsx)("h4",{className:"text-sm font-semibold text-amber-800 mb-1",children:"Mean Statistics Not Available"}),(0,s.jsx)("p",{className:"text-sm text-amber-700",children:Y}),(0,s.jsx)("p",{className:"text-sm text-amber-600 mt-2",children:'You need to calculate statistics first. Use the "Statistics Calculation" section below to get started.'})]})]})}),!B&&(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsx)("label",{htmlFor:"x-offset",className:"text-sm font-medium",children:"X Offset:"}),(0,s.jsx)(F,{id:"x-offset",type:"number",value:q,onChange:e=>Q(e.target.value),className:"w-24",placeholder:"0"}),(0,s.jsx)("label",{htmlFor:"y-offset",className:"text-sm font-medium",children:"Y Offset:"}),(0,s.jsx)(F,{id:"y-offset",type:"number",value:ee,onChange:e=>et(e.target.value),className:"w-24",placeholder:"0"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:eg,children:"Update Offsets"}),(0,s.jsx)(E,{size:"sm",variant:K?"default":"outline",onClick:()=>$(!K),className:"".concat(K?"bg-yellow-500 hover:bg-yellow-600":""),children:K?"Cancel Set Datum":"Set New Datum"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>ep(),children:"Show Corner Coordinates"})]}),es&&ea&&(0,s.jsxs)("div",{className:"p-3 bg-gray-50 border rounded-md",children:[(0,s.jsx)("h4",{className:"font-medium mb-2",children:"Vector Field Corner Coordinates:"}),(0,s.jsxs)("div",{className:"grid grid-cols-2 gap-2 text-sm",children:[(0,s.jsxs)("div",{className:"flex gap-1",children:[(0,s.jsx)("span",{className:"font-medium",children:"Top Left:"}),(0,s.jsxs)("span",{children:["(",ea.topLeft.x.toFixed(2),", ",ea.topLeft.y.toFixed(2),")"]})]}),(0,s.jsxs)("div",{className:"flex gap-1",children:[(0,s.jsx)("span",{className:"font-medium",children:"Top Right:"}),(0,s.jsxs)("span",{children:["(",ea.topRight.x.toFixed(2),", ",ea.topRight.y.toFixed(2),")"]})]}),(0,s.jsxs)("div",{className:"flex gap-1",children:[(0,s.jsx)("span",{className:"font-medium",children:"Bottom Left:"}),(0,s.jsxs)("span",{children:["(",ea.bottomLeft.x.toFixed(2),", ",ea.bottomLeft.y.toFixed(2),")"]})]}),(0,s.jsxs)("div",{className:"flex gap-1",children:[(0,s.jsx)("span",{className:"font-medium",children:"Bottom Right:"}),(0,s.jsxs)("span",{children:["(",ea.bottomRight.x.toFixed(2),", ",ea.bottomRight.y.toFixed(2),")"]})]})]}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>er(!1),className:"mt-2",children:"Hide"})]}),ez.length>1&&(0,s.jsxs)("div",{className:"p-3 bg-gradient-to-r from-green-50 to-emerald-50 border border-green-200 rounded-lg",children:[(0,s.jsxs)("button",{onClick:()=>e5(!e2),className:"w-full flex items-center justify-between text-left",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("h4",{className:"text-sm font-semibold text-green-900",children:"Merge Vectors"}),(0,s.jsx)("span",{className:"text-xs text-green-700 bg-green-100 px-2 py-0.5 rounded",children:"Combine camera views"})]}),(0,s.jsx)("svg",{className:"w-5 h-5 text-green-700 transition-transform ".concat(e2?"rotate-180":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,s.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),e2&&(0,s.jsxs)("div",{className:"mt-3 space-y-3",children:[(0,s.jsx)("p",{className:"text-xs text-green-800",children:"Merge vector fields from multiple cameras into a single combined field."}),!e1&&(0,s.jsxs)("div",{className:"space-y-3",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-xs font-medium text-gray-700 mb-1.5 block",children:"Select Cameras to Merge:"}),(0,s.jsx)("div",{className:"flex flex-wrap gap-2",children:ez.map(e=>(0,s.jsxs)("label",{className:"inline-flex items-center gap-1.5 px-2.5 py-1.5 bg-white border border-gray-300 rounded-md hover:bg-gray-50 cursor-pointer transition-colors text-sm",children:[(0,s.jsx)("input",{type:"checkbox",checked:eQ.includes(e),onChange:t=>{t.target.checked?e4([...eQ,e]):e4(eQ.filter(t=>t!==e))},className:"w-3.5 h-3.5 text-green-600 border-gray-300 rounded focus:ring-green-500"}),(0,s.jsxs)("span",{className:"text-xs font-medium",children:["Cam ",e]})]},e))})]}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(E,{onClick:()=>e8(c),disabled:e0||eQ.length<2,className:"flex-1 bg-green-600 hover:bg-green-700 text-white text-xs py-2",children:e0?"Merging...":"Merge Frame ".concat(c)}),(0,s.jsx)(E,{onClick:()=>e8(),disabled:e0||eQ.length<2,className:"flex-1 bg-green-700 hover:bg-green-800 text-white text-xs py-2",children:e0?"Merging...":"Merge All (".concat(ed,")")})]}),(0,s.jsx)("p",{className:"text-xs text-gray-600 italic",children:'Use "Merge Frame" to test on current frame, or "Merge All" to process all frames with multiprocessing.'})]}),e1&&(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("div",{className:"flex items-center gap-2",children:(0,s.jsxs)("div",{className:"flex-1",children:[(0,s.jsx)("div",{className:"text-xs font-medium text-gray-700 mb-1",children:"completed"===e3?"Merge Complete!":"failed"===e3?"Merge Failed":"running"===e3?"Merging vectors...":"Starting..."}),(0,s.jsx)("div",{className:"w-full bg-gray-200 rounded-full h-2",children:(0,s.jsx)("div",{className:"bg-green-600 h-2 rounded-full transition-all duration-300",style:{width:"".concat(e9,"%")}})}),(0,s.jsxs)("div",{className:"text-xs text-gray-600 mt-1",children:[(null==e6?void 0:e6.processed_frames)||0," / ",(null==e6?void 0:e6.total_frames)||0," frames"]})]})}),"completed"===e3&&(0,s.jsx)("div",{className:"p-3 bg-green-50 border-l-4 border-green-500 rounded-r",children:(0,s.jsxs)("div",{className:"flex items-start gap-2",children:[(0,s.jsx)("svg",{className:"w-4 h-4 text-green-600 mt-0.5 flex-shrink-0",fill:"currentColor",viewBox:"0 0 20 20",children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",clipRule:"evenodd"})}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h5",{className:"text-xs font-semibold text-green-800",children:"Merge Successful"}),(0,s.jsx)("p",{className:"text-xs text-green-700 mt-0.5",children:'Vectors merged successfully. Enable "Use Merged Data" to view the results.'})]})]})}),"failed"===e3&&te&&(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("div",{className:"p-3 bg-red-50 border-l-4 border-red-500 rounded-r",children:(0,s.jsxs)("div",{className:"flex items-start gap-2",children:[(0,s.jsx)("svg",{className:"w-4 h-4 text-red-600 mt-0.5 flex-shrink-0",fill:"currentColor",viewBox:"0 0 20 20",children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h5",{className:"text-xs font-semibold text-red-800",children:"Merge Failed"}),(0,s.jsx)("p",{className:"text-xs text-red-700 mt-0.5",children:te})]})]})}),(0,s.jsx)(E,{size:"sm",onClick:e7,variant:"outline",className:"w-full text-xs",children:"Try Again"})]})]})]})]}),(0,s.jsxs)("div",{className:"p-3 bg-gradient-to-r from-blue-50 to-indigo-50 border border-blue-200 rounded-lg",children:[(0,s.jsxs)("button",{onClick:()=>eG(!eW),className:"w-full flex items-center justify-between text-left",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("h4",{className:"text-sm font-semibold text-blue-900",children:"Statistics Calculation"}),(0,s.jsx)("span",{className:"text-xs text-blue-700 bg-blue-100 px-2 py-0.5 rounded",children:"Required for mean statistics"})]}),(0,s.jsx)("svg",{className:"w-5 h-5 text-blue-700 transition-transform ".concat(eW?"rotate-180":""),fill:"none",stroke:"currentColor",viewBox:"0 0 24 24",children:(0,s.jsx)("path",{strokeLinecap:"round",strokeLinejoin:"round",strokeWidth:2,d:"M19 9l-7 7-7-7"})})]}),eW&&(0,s.jsxs)("div",{className:"mt-3 space-y-3",children:[(0,s.jsx)("p",{className:"text-xs text-blue-800",children:"Calculate mean velocities and Reynolds stresses across all frames."}),!eU&&(0,s.jsxs)("div",{className:"space-y-3",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-xs font-medium text-gray-700 mb-1.5 block",children:"Select Cameras:"}),(0,s.jsx)("div",{className:"flex flex-wrap gap-2",children:ez.map(e=>(0,s.jsxs)("label",{className:"inline-flex items-center gap-1.5 px-2.5 py-1.5 bg-white border border-gray-300 rounded-md hover:bg-gray-50 cursor-pointer transition-colors text-sm",children:[(0,s.jsx)("input",{type:"checkbox",checked:eV.includes(e),onChange:t=>{t.target.checked?eZ([...eV,e]):eZ(eV.filter(t=>t!==e))},className:"w-3.5 h-3.5 text-blue-600 border-gray-300 rounded focus:ring-blue-500 focus:ring-2"}),(0,s.jsx)("span",{className:"font-medium",children:e})]},e))})]}),(0,s.jsxs)("label",{className:"inline-flex items-center gap-2 px-2.5 py-1.5 bg-white border border-gray-300 rounded-md hover:bg-gray-50 cursor-pointer transition-colors text-sm",children:[(0,s.jsx)("input",{type:"checkbox",checked:eL,onChange:e=>eY(e.target.checked),className:"w-3.5 h-3.5 text-blue-600 border-gray-300 rounded focus:ring-blue-500 focus:ring-2"}),(0,s.jsx)("span",{className:"font-medium",children:"Include Merged Data"}),(0,s.jsx)("span",{className:"text-xs text-gray-500",children:"(if available)"})]}),(0,s.jsx)(E,{onClick:eH,disabled:eB||0===eV.length&&!eL,className:"w-full bg-green-600 hover:bg-green-700 text-white",size:"sm",children:eB?"Starting Calculation...":"Calculate Statistics"})]}),eU&&"completed"!==eJ&&"failed"!==eJ&&(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between text-xs",children:[(0,s.jsx)("span",{className:"font-medium text-gray-700",children:"Status:"}),(0,s.jsx)("span",{className:"font-medium ".concat("running"===eJ?"text-blue-600":"text-gray-600"),children:"running"===eJ?"Processing...":eJ})]}),(0,s.jsxs)("div",{className:"space-y-1",children:[(0,s.jsx)("div",{className:"w-full bg-gray-200 h-2 rounded-full overflow-hidden",children:(0,s.jsx)("div",{className:"h-2 bg-gradient-to-r from-blue-500 to-blue-600 transition-all duration-300",style:{width:"".concat(e$,"%")}})}),(0,s.jsxs)("p",{className:"text-xs text-gray-600 text-right",children:[e$.toFixed(1),"% complete"]})]}),(null==eX?void 0:eX.camera)&&(0,s.jsxs)("p",{className:"text-xs text-gray-600",children:["Processing: ",(0,s.jsx)("span",{className:"font-medium",children:eX.camera})]})]}),"completed"===eJ&&(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("div",{className:"p-3 bg-green-50 border-l-4 border-green-500 rounded-r",children:(0,s.jsxs)("div",{className:"flex items-start gap-2",children:[(0,s.jsx)("svg",{className:"w-4 h-4 text-green-600 mt-0.5 flex-shrink-0",fill:"currentColor",viewBox:"0 0 20 20",children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zm3.707-9.293a1 1 0 00-1.414-1.414L9 10.586 7.707 9.293a1 1 0 00-1.414 1.414l2 2a1 1 0 001.414 0l4-4z",clipRule:"evenodd"})}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h5",{className:"text-xs font-semibold text-green-800",children:"Statistics Calculated!"}),(0,s.jsx)("p",{className:"text-xs text-green-700 mt-0.5",children:'Enable "Show Mean Statistics" above to view them.'})]})]})}),(0,s.jsx)(E,{size:"sm",onClick:eK,variant:"outline",className:"w-full text-xs",children:"Calculate New Statistics"})]}),"failed"===eJ&&eq&&(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("div",{className:"p-3 bg-red-50 border-l-4 border-red-500 rounded-r",children:(0,s.jsxs)("div",{className:"flex items-start gap-2",children:[(0,s.jsx)("svg",{className:"w-4 h-4 text-red-600 mt-0.5 flex-shrink-0",fill:"currentColor",viewBox:"0 0 20 20",children:(0,s.jsx)("path",{fillRule:"evenodd",d:"M10 18a8 8 0 100-16 8 8 0 000 16zM8.707 7.293a1 1 0 00-1.414 1.414L8.586 10l-1.293 1.293a1 1 0 101.414 1.414L10 11.414l1.293 1.293a1 1 0 001.414-1.414L11.414 10l1.293-1.293a1 1 0 00-1.414-1.414L10 8.586 8.707 7.293z",clipRule:"evenodd"})}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h5",{className:"text-xs font-semibold text-red-800",children:"Calculation Failed"}),(0,s.jsx)("p",{className:"text-xs text-red-700 mt-0.5",children:eq})]})]})}),(0,s.jsx)(E,{size:"sm",onClick:eK,variant:"outline",className:"w-full text-xs",children:"Try Again"})]})]})]}),(0,s.jsxs)("div",{className:"p-3 bg-white border border-gray-200 rounded-lg",children:[(0,s.jsx)("h4",{className:"text-sm font-semibold text-gray-700 mb-3",children:"Visualization Settings"}),(0,s.jsxs)("div",{className:"flex items-center gap-4 mb-3 flex-wrap",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{htmlFor:"type",className:"text-sm font-medium text-gray-700",children:"Variable:"}),(0,s.jsxs)(D,{value:u,onValueChange:e=>m(e),children:[(0,s.jsx)(L,{id:"type",className:"w-32",children:(0,s.jsx)(V,{placeholder:"Select"})}),(0,s.jsx)(W,{children:B?J?(0,s.jsx)(Z,{value:"loading",children:"Loading..."}):G&&G.length>0?G.map(e=>(0,s.jsx)(Z,{value:e,children:e},e)):(0,s.jsx)(Z,{value:"none",disabled:!0,children:"No variables"}):H?(0,s.jsx)(Z,{value:"loading",children:"Loading..."}):X&&X.length>0?X.map(e=>(0,s.jsx)(Z,{value:e,children:e},e)):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(Z,{value:"ux",children:"ux"}),(0,s.jsx)(Z,{value:"uy",children:"uy"})]})})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{htmlFor:"cmap",className:"text-sm font-medium text-gray-700",children:"Colormap:"}),(0,s.jsxs)(D,{value:j,onValueChange:e=>b(e),children:[(0,s.jsx)(L,{id:"cmap",className:"w-32",children:(0,s.jsx)(V,{placeholder:"Select"})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"default",children:"default"}),(0,s.jsx)(Z,{value:"viridis",children:"viridis"}),(0,s.jsx)(Z,{value:"plasma",children:"plasma"}),(0,s.jsx)(Z,{value:"inferno",children:"inferno"}),(0,s.jsx)(Z,{value:"magma",children:"magma"}),(0,s.jsx)(Z,{value:"cividis",children:"cividis"}),(0,s.jsx)(Z,{value:"jet",children:"jet"}),(0,s.jsx)(Z,{value:"gray",children:"gray"}),(0,s.jsx)(Z,{value:"bone",children:"bone"}),(0,s.jsx)(Z,{value:"copper",children:"copper"}),(0,s.jsx)(Z,{value:"pink",children:"pink"}),(0,s.jsx)(Z,{value:"spring",children:"spring"}),(0,s.jsx)(Z,{value:"summer",children:"summer"}),(0,s.jsx)(Z,{value:"autumn",children:"autumn"}),(0,s.jsx)(Z,{value:"winter",children:"winter"}),(0,s.jsx)(Z,{value:"hot",children:"hot"}),(0,s.jsx)(Z,{value:"cool",children:"cool"}),(0,s.jsx)(Z,{value:"Wistia",children:"Wistia"}),(0,s.jsx)(Z,{value:"twilight",children:"twilight"}),(0,s.jsx)(Z,{value:"hsv",children:"hsv"})]})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{htmlFor:"run",className:"text-sm font-medium text-gray-700",children:"Run:"}),(0,s.jsx)(F,{id:"run",type:"number",min:1,value:h,onChange:e=>x(Math.max(1,Number(e.target.value))),className:"w-20"})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-4 flex-wrap",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Lower:"}),(0,s.jsx)(F,{type:"number",value:g,onChange:e=>p(e.target.value),placeholder:"auto",className:"w-24"})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium text-gray-700",children:"Upper:"}),(0,s.jsx)(F,{type:"number",value:f,onChange:e=>v(e.target.value),placeholder:"auto",className:"w-24"})]}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>{e_()},disabled:O,className:"text-xs",children:O?"Getting...":"Auto-Calculate Limits"}),(0,s.jsxs)("div",{className:"ml-auto flex items-center gap-2 flex-wrap",children:[(0,s.jsx)(E,{className:"bg-blue-600 hover:bg-blue-700 text-white",onClick:()=>{em()},disabled:C||U||H,children:C||U||H?"Loading...":"Render"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:eN,disabled:!y||C||U,children:"Download PNG"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>{ew()},disabled:!y||C||U,children:"Copy PNG"})]})]})]})]})}),(0,s.jsxs)("div",{className:"mt-6",children:[P&&(0,s.jsx)("div",{className:"w-full p-3 mb-3 rounded border border-red-200 bg-red-50 text-red-700 text-sm",children:P}),K&&(0,s.jsxs)("div",{className:"w-full p-3 mb-3 rounded border border-yellow-200 bg-yellow-50 text-yellow-700 text-sm",children:[(0,s.jsx)("strong",{children:"Set Datum Mode Active:"})," Click on the image to set a new coordinate system origin."]}),y&&!P&&(0,s.jsx)("div",{className:"p-4 bg-gradient-to-br from-blue-50 to-indigo-50 border-2 border-blue-200 rounded-lg mb-4 shadow-sm",children:(0,s.jsxs)("div",{className:"flex flex-col gap-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-3",children:[(0,s.jsxs)(E,{size:"default",onClick:()=>ek(eP),disabled:C||0===eP.length,className:"flex items-center gap-2 bg-blue-600 hover:bg-blue-700 text-white font-semibold px-6 py-2 shadow-md",children:[(0,s.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-5 h-5",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[(0,s.jsx)("path",{d:"M21 14h-5a2 2 0 0 1-2-2V7"}),(0,s.jsx)("path",{d:"M14 2L7 9l7 7"})]}),"Apply to All Frames"]}),(0,s.jsx)(E,{size:"default",variant:"destructive",onClick:eT,disabled:C,className:"font-semibold px-6 py-2 shadow-md",children:"Clear Transforms"}),eP.length>0&&(0,s.jsxs)("span",{className:"text-sm font-medium text-blue-700 bg-blue-100 px-3 py-1 rounded-full",children:[eP.length," transform",1!==eP.length?"s":""," applied"]})]}),(0,s.jsxs)("div",{className:"flex flex-wrap items-center gap-2 pt-3 border-t border-blue-200",children:[(0,s.jsx)("label",{className:"text-sm font-semibold text-gray-700 mr-2",children:"Apply individually to current frame:"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>eS("rotate_90_ccw"),children:"Rotate Left"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>eS("rotate_90_cw"),children:"Rotate Right"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>eS("flip_lr"),children:"Flip Horizontal"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>eS("flip_ud"),children:"Flip Vertical"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>eS("swap_ux_uy"),children:"Swap UX/UY"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>eS("invert_ux_uy"),children:"Invert UX/UY"})]})]})}),y&&!P&&(0,s.jsx)("div",{className:"mb-4 p-3 bg-gradient-to-r from-gray-50 to-gray-100 border rounded-lg shadow-sm",style:{minHeight:56,height:56,display:"flex",alignItems:"center"},children:(0,s.jsxs)("div",{className:"flex items-center justify-between w-full h-full",children:[(0,s.jsxs)("div",{className:"flex items-center gap-6 h-full",children:[(0,s.jsx)("div",{className:"text-sm font-medium text-gray-700",children:"Cursor Position:"}),(()=>{let e=en&&"number"==typeof en.x&&!isNaN(en.x)&&en.i>=0?en:eO;if(!e)return(0,s.jsx)("div",{className:"text-sm text-gray-500 italic h-full flex items-center",children:"Hover over the plot area to see coordinates"});let t=null;return"ux"===u&&null!=e.ux?t=e.ux:"uy"===u&&null!=e.uy?t=e.uy:null!=e.value&&(t=e.value),(0,s.jsxs)("div",{className:"flex items-center gap-6 h-full",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-gray-600 uppercase tracking-wide",children:"X:"}),(0,s.jsx)("span",{className:"font-mono text-sm font-semibold text-soton-blue bg-white px-2 py-1 rounded border",style:{minWidth:70,textAlign:"center",display:"inline-block"},children:e.x.toFixed(3)})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("span",{className:"text-xs font-medium text-gray-600 uppercase tracking-wide",children:"Y:"}),(0,s.jsx)("span",{className:"font-mono text-sm font-semibold text-soton-blue bg-white px-2 py-1 rounded border",style:{minWidth:70,textAlign:"center",display:"inline-block"},children:e.y.toFixed(3)})]}),null!=t?(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsxs)("span",{className:"text-xs font-medium text-gray-600 uppercase tracking-wide",children:[u,":"]}),(0,s.jsx)("span",{className:"font-mono text-sm font-semibold text-white bg-soton-blue px-2 py-1 rounded border",style:{minWidth:70,textAlign:"center",display:"inline-block"},children:t.toFixed(3)})]}):null]})})()]}),(0,s.jsx)("div",{className:"text-xs text-gray-500",children:B?"Mean Statistics Mode":"Frame ".concat(c)})]})}),eC&&(0,s.jsxs)("div",{className:"mt-4 p-4 bg-blue-50 border border-blue-200 rounded-lg",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,s.jsx)("span",{className:"text-sm font-medium text-blue-900",children:"Applying transformations to all frames..."}),(0,s.jsx)("span",{className:"text-sm text-blue-700",children:"completed"===eC.status?"Complete":"failed"===eC.status?"Failed":"".concat(eC.progress,"%")})]}),(0,s.jsx)("div",{className:"w-full bg-blue-200 rounded-full h-2",children:(0,s.jsx)("div",{className:"bg-blue-600 h-2 rounded-full transition-all duration-300",style:{width:"".concat(eC.progress,"%")}})}),(0,s.jsxs)("div",{className:"mt-2 text-xs text-blue-700",children:[eC.processed_frames," / ",eC.total_frames," frames processed",eC.elapsed_time&&(0,s.jsxs)("span",{className:"ml-2",children:["(",Math.round(eC.elapsed_time),"s elapsed)"]}),eC.estimated_remaining&&"running"===eC.status&&(0,s.jsxs)("span",{className:"ml-2",children:["(~",Math.round(eC.estimated_remaining),"s remaining)"]})]}),eC.error&&(0,s.jsxs)("div",{className:"mt-2 text-xs text-red-600",children:["Error: ",eC.error]})]}),y&&!P&&(0,s.jsxs)("div",{className:"flex flex-col items-center relative",style:{width:"100%",maxWidth:"1100px",margin:"0 auto",cursor:K?"crosshair":eo?"none":"default"},onMouseMove:e=>{ef(e),ej(e)},onMouseLeave:e=>{ev(),eb()},onClick:e=>{K&&ex(e)},children:[(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>d(Math.max(1,c-1)),disabled:B||c<=1,title:"Previous frame","aria-label":"Previous frame",className:"absolute left-3 top-1/2 -translate-y-1/2 z-50 rounded-full p-2 bg-white bg-opacity-90 text-gray-700 border border-gray-200 hover:bg-gray-100",children:(0,s.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-4 h-4",viewBox:"0 0 20 20",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:(0,s.jsx)("path",{d:"M12 4L6 10l6 6"})})}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:()=>d(Math.min(ed,c+1)),disabled:B||c>=ed,title:"Next frame","aria-label":"Next frame",className:"absolute right-3 top-1/2 -translate-y-1/2 z-50 rounded-full p-2 bg-white bg-opacity-90 text-gray-700 border border-gray-200 hover:bg-gray-100",children:(0,s.jsx)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"w-4 h-4",viewBox:"0 0 20 20",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round","aria-hidden":"true",focusable:"false",children:(0,s.jsx)("path",{d:"M8 4l6 6-6 6"})})}),(0,s.jsx)("img",{ref:el,src:"data:image/png;base64,".concat(y),alt:"Vector Result",className:"rounded border w-full max-w-5xl select-none pointer-events-auto",style:{width:"100%",maxWidth:"1000px",height:"auto",display:"block"},draggable:!1}),(0,s.jsx)("canvas",{ref:ei,style:{display:eo?"block":"none",position:"fixed",pointerEvents:"none",zIndex:9999,width:eI,height:eI,left:ec.left,top:ec.top,borderRadius:"50%",boxShadow:"0 2px 8px rgba(0,0,0,0.25)",border:"2px solid #333"},width:eI*eR,height:eI*eR}),C&&!z&&(0,s.jsx)("div",{className:"absolute inset-0 flex items-center justify-center bg-white bg-opacity-60",children:(0,s.jsx)("span",{className:"text-gray-500",children:"Rendering..."})})]}),ed>0&&!B&&(0,s.jsxs)("div",{className:"flex flex-col md:flex-row items-center justify-center gap-6 mt-6 p-4 bg-gray-50 border rounded-lg",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{htmlFor:"frame-camera",className:"text-sm font-medium whitespace-nowrap",children:"Camera:"}),(0,s.jsxs)(D,{value:String(T),onValueChange:e=>I(Number(e)),disabled:0===ez.length,children:[(0,s.jsx)(L,{id:"frame-camera",className:"w-28",children:(0,s.jsx)(V,{placeholder:0===ez.length?"No cameras":"Select"})}),(0,s.jsx)(W,{children:0===ez.length?(0,s.jsx)(Z,{value:"none",disabled:!0,children:"No cameras available"}):ez.map((e,t)=>(0,s.jsx)(Z,{value:String(e),children:e},t))})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-3 flex-1",children:[(0,s.jsx)("label",{htmlFor:"frame-slider",className:"text-sm font-medium whitespace-nowrap",children:"Frame:"}),(0,s.jsx)("input",{id:"frame-slider",type:"range",min:1,max:ed,value:c,onChange:e=>d(Number(e.target.value)),className:"flex-1 min-w-[200px]"}),(0,s.jsx)(F,{id:"frame-input",type:"number",min:1,max:ed,value:c,onChange:e=>d(Math.max(1,Math.min(ed,Number(e.target.value||1)))),className:"w-24"}),(0,s.jsxs)("span",{className:"text-xs text-gray-500 whitespace-nowrap",children:[c," / ",ed]})]}),(0,s.jsx)("div",{className:"flex items-center gap-2",children:(0,s.jsx)(E,{size:"sm",variant:z?"default":"outline",onClick:()=>{eu()},className:"flex items-center gap-1",children:z?(0,s.jsx)("span",{children:"❙❙ Pause"}):(0,s.jsx)("span",{children:"▶ Play"})})})]}),(!y||P)&&(0,s.jsx)("div",{className:"w-full h-64 flex items-center justify-center bg-gray-100 border rounded",children:(0,s.jsx)("span",{className:"text-gray-500",children:"No image loaded"})})]})]})]})})}function eI(e){let{backendUrl:t="/backend",config:a}=e,{directory:l,setDirectory:n,dirInputRef:i,basePaths:o,basePathIdx:c,setBasePathIdx:d,cameraOptions:u,camera:m,setCamera:h,type:x,setType:g,cmap:p,setCmap:f,run:S,setRun:C,lower:P,setLower:M,upper:T,setUpper:I,merged:R,setMerged:A,resolution:z,setResolution:O,resolutionOptions:B,fps:U,setFps:Y,activeTab:G,setActiveTab:J,availableVideos:X,selectedVideo:H,setSelectedVideo:K,loadingVideos:$,creating:q,videoResult:Q,videoStatus:ee,videoReady:et,videoError:ea,effectiveDir:es,handleBrowse:er,onDirPicked:el,fetchAvailableVideos:en,handleCreateVideo:ei,handleCancelVideo:eo,basename:ec,createVideoUrl:ed,handleVideoError:eu,handleRetryVideo:em}=function(){var e;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:"/backend",a=arguments.length>1?arguments[1]:void 0,[s,l]=(0,r.useState)(""),n=(0,r.useRef)(null),i=(0,r.useMemo)(()=>{var e;return(null==a?void 0:null===(e=a.paths)||void 0===e?void 0:e.base_paths)||[]},[a]),[o,c]=(0,r.useState)(0),d=(0,r.useMemo)(()=>{var e;return((null==a?void 0:null===(e=a.paths)||void 0===e?void 0:e.camera_numbers)||[]).map(e=>"Cam".concat(e))},[null==a?void 0:null===(e=a.paths)||void 0===e?void 0:e.camera_numbers]),[u,m]=(0,r.useState)(()=>d.length>0?parseInt(d[0].replace("Cam","")):1);(0,r.useEffect)(()=>{0===d.length||d.includes("Cam".concat(u))||m(parseInt(d[0].replace("Cam","")))},[d.length,d[0]]);let[h,x]=(0,r.useState)("ux"),[g,p]=(0,r.useState)("default"),[f,v]=(0,r.useState)(1),[j,b]=(0,r.useState)(""),[y,N]=(0,r.useState)(""),[w,_]=(0,r.useState)(!1),[S,k]=(0,r.useState)("1080p"),[C,P]=(0,r.useState)(30),[M,E]=(0,r.useState)("create"),[F,T]=(0,r.useState)([]),[I,R]=(0,r.useState)(""),[A,z]=(0,r.useState)(!1),[O,D]=(0,r.useState)(!1),[V,L]=(0,r.useState)(null),[B,U]=(0,r.useState)(null),[W,Z]=(0,r.useState)(!1),[Y,G]=(0,r.useState)(!1),J=(0,r.useMemo)(()=>i.length>0&&o>=0&&o<i.length?i[o]:s,[i,o,s]);(0,r.useEffect)(()=>{J&&l(J)},[J]),(0,r.useEffect)(()=>{"browse"===M&&X()},[M,J]);let X=async()=>{if(J){z(!0),T([]),R("");try{var e,a;console.log("Fetching videos from: ".concat(J));let s=await fetch("".concat(t,"/video/list_videos?base_path=").concat(encodeURIComponent(J)));if(!s.ok)throw Error("Server returned ".concat(s.status));let r=await s.json();console.log("Found ".concat((null===(e=r.videos)||void 0===e?void 0:e.length)||0," videos")),(null===(a=r.videos)||void 0===a?void 0:a.length)?(T(r.videos),R(r.videos[0])):T([])}catch(e){console.error("Error fetching videos:",e),T([])}finally{z(!1)}}},H=()=>{var e;return{base_path:J,camera:u,var:h,run:String(f),merged:w?"1":"0",cmap:g,lower:j,upper:y,num_images:(null==a?void 0:null===(e=a.images)||void 0===e?void 0:e.num_images)||0,resolution:S,fps:String(C)}},K=async function(){let e=arguments.length>0&&void 0!==arguments[0]&&arguments[0];D(!0),L(null),U(null);try{let a=H();e&&(a.test_mode=!0,a.test_frames=50);let s=await fetch("".concat(t,"/video/start_video"),{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(a)}),r=await s.json();if(!s.ok)throw Error(r.error||"Failed to start video creation");let l=()=>{fetch("".concat(t,"/video/video_status")).then(e=>e.json()).then(t=>{U(t),t.processing?setTimeout(l,500):(D(!1),t.error?L({success:!1,message:t.error}):(L({success:!0,message:e?"Test video created successfully!":"Video creation completed!",out_path:t.out_path}),"browse"===M&&X()))}).catch(e=>{console.error("Polling error",e),D(!1),L({success:!1,message:"Error polling status."})})};l()}catch(e){L({success:!1,message:"Error: ".concat(e.message)}),D(!1)}},$=async()=>{try{if(!(await fetch("".concat(t,"/video/cancel_video"),{method:"POST",headers:{"Content-Type":"application/json"}})).ok)throw Error("Failed to cancel video");U({processing:!1,progress:0,status:"canceled"}),L({success:!1,message:"Video creation canceled."}),D(!1)}catch(e){console.error("Cancel error",e),L({success:!1,message:"Error canceling: ".concat(e.message)})}};return(0,r.useEffect)(()=>{if(null==V?void 0:V.out_path){Z(!1),G(!1);let e=setTimeout(()=>Z(!0),2e3);return()=>clearTimeout(e)}},[null==V?void 0:V.out_path]),{directory:s,setDirectory:l,dirInputRef:n,basePaths:i,basePathIdx:o,setBasePathIdx:c,cameraOptions:d,camera:u,setCamera:m,type:h,setType:x,cmap:g,setCmap:p,run:f,setRun:v,lower:j,setLower:b,upper:y,setUpper:N,merged:w,setMerged:_,resolution:S,setResolution:k,resolutionOptions:[{label:"1080p (1920x1080)",value:"1080p"},{label:"4K (3840x2160)",value:"4k"}],fps:C,setFps:P,activeTab:M,setActiveTab:E,availableVideos:F,selectedVideo:I,setSelectedVideo:R,loadingVideos:A,creating:O,videoResult:V,videoStatus:B,videoReady:W,videoError:Y,effectiveDir:J,handleBrowse:()=>{var e;null===(e=n.current)||void 0===e||e.click()},onDirPicked:e=>{let t=e.target.files;if(!t||0===t.length)return;let a=t[0],s=a.webkitRelativePath||"",r=s.split("/")[0]||"",n=r;a.path&&s&&(n=a.path.replace(/\\/g,"/").split("/"+s)[0]||r),l(n),e.currentTarget.value=""},fetchAvailableVideos:X,handleCreateVideo:K,handleCancelVideo:$,basename:e=>e?e.replace(/\\/g,"/").split("/").filter(Boolean).pop()||e:"",createVideoUrl:e=>{if(!e)return"";try{let a=encodeURIComponent(e);return"".concat(t,"/video/download?path=").concat(a)}catch(e){return console.error("Error creating video URL:",e),""}},handleVideoError:()=>{G(!0)},handleRetryVideo:()=>{G(!1),Z(!1),setTimeout(()=>Z(!0),1500)}}}(t,a);return(0,s.jsx)("div",{className:"space-y-6",children:(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Video Creation & Browsing"})}),(0,s.jsx)(k,{children:(0,s.jsxs)("div",{className:"flex flex-col gap-4 mb-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Base Path:"}),o.length>0?(0,s.jsxs)(D,{value:String(c),onValueChange:e=>d(Number(e)),children:[(0,s.jsx)(L,{id:"basepath",children:(0,s.jsx)(V,{placeholder:"Pick base path"})}),(0,s.jsx)(W,{children:o.map((e,t)=>(0,s.jsx)(Z,{value:String(t),children:ec(e)},t))})]}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(F,{type:"text",value:l,onChange:e=>n(e.target.value),placeholder:"Select directory",className:"w-full"}),(0,s.jsx)("input",{ref:i,type:"file",style:{display:"none"},onChange:el}),(0,s.jsx)(E,{variant:"outline",onClick:er,children:"Browse"})]})]}),(0,s.jsxs)(v,{value:G,onValueChange:J,className:"w-full",children:[(0,s.jsxs)(j,{className:"w-full",children:[(0,s.jsx)(b,{value:"create",className:"flex-1",children:"Create Video"}),(0,s.jsx)(b,{value:"browse",className:"flex-1",children:"Browse Videos"})]}),(0,s.jsxs)(y,{value:"create",className:"pt-4",children:[(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsx)("label",{htmlFor:"camera",className:"text-sm font-medium",children:"Camera:"}),(0,s.jsxs)(D,{value:String(m),onValueChange:e=>h(Number(e)),children:[(0,s.jsx)(L,{id:"camera",children:(0,s.jsx)(V,{placeholder:"Select camera"})}),(0,s.jsx)(W,{children:u.map((e,t)=>(0,s.jsx)(Z,{value:String(e),children:e},t))})]}),(0,s.jsxs)("label",{className:"flex items-center gap-2 text-sm font-medium",children:[(0,s.jsx)("input",{type:"checkbox",checked:R,onChange:e=>A(e.target.checked),className:"accent-soton-blue w-4 h-4 rounded border-gray-300"}),"Merged Data"]})]}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-3 gap-4 mt-4",children:[(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Type (variable)"}),(0,s.jsxs)(D,{value:x,onValueChange:e=>g(e),children:[(0,s.jsx)(L,{id:"type",children:(0,s.jsx)(V,{placeholder:"Select type"})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"ux",children:"ux"}),(0,s.jsx)(Z,{value:"uy",children:"uy"}),(0,s.jsx)(Z,{value:"mag",children:"mag"})]})]})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Colormap"}),(0,s.jsxs)(D,{value:p,onValueChange:e=>f(e),children:[(0,s.jsx)(L,{id:"cmap",children:(0,s.jsx)(V,{placeholder:"Select colormap"})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"default",children:"default"}),(0,s.jsx)(Z,{value:"viridis",children:"viridis"}),(0,s.jsx)(Z,{value:"plasma",children:"plasma"}),(0,s.jsx)(Z,{value:"inferno",children:"inferno"}),(0,s.jsx)(Z,{value:"magma",children:"magma"}),(0,s.jsx)(Z,{value:"cividis",children:"cividis"}),(0,s.jsx)(Z,{value:"jet",children:"jet"}),(0,s.jsx)(Z,{value:"gray",children:"gray"}),(0,s.jsx)(Z,{value:"bone",children:"bone"}),(0,s.jsx)(Z,{value:"copper",children:"copper"}),(0,s.jsx)(Z,{value:"pink",children:"pink"}),(0,s.jsx)(Z,{value:"spring",children:"spring"}),(0,s.jsx)(Z,{value:"summer",children:"summer"}),(0,s.jsx)(Z,{value:"autumn",children:"autumn"}),(0,s.jsx)(Z,{value:"winter",children:"winter"}),(0,s.jsx)(Z,{value:"hot",children:"hot"}),(0,s.jsx)(Z,{value:"cool",children:"cool"}),(0,s.jsx)(Z,{value:"Wistia",children:"Wistia"}),(0,s.jsx)(Z,{value:"twilight",children:"twilight"}),(0,s.jsx)(Z,{value:"hsv",children:"hsv"})]})]})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Run"}),(0,s.jsx)(F,{type:"number",min:1,value:S,onChange:e=>C(Number(e.target.value||1))})]})]}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4",children:[(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Lower limit"}),(0,s.jsx)(F,{value:P,onChange:e=>M(e.target.value),placeholder:"auto"})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Upper limit"}),(0,s.jsx)(F,{value:T,onChange:e=>I(e.target.value),placeholder:"auto"})]})]}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-4 mt-4",children:[(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Resolution"}),(0,s.jsxs)(D,{value:z,onValueChange:O,children:[(0,s.jsx)(L,{id:"resolution",children:(0,s.jsx)(V,{placeholder:"Select resolution"})}),(0,s.jsx)(W,{children:B.map(e=>(0,s.jsx)(Z,{value:e.value,children:e.label},e.value))})]})]}),(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"FPS"}),(0,s.jsx)(F,{type:"number",min:1,value:U,onChange:e=>Y(Number(e.target.value||30))})]})]}),Q&&(0,s.jsxs)("div",{className:"w-full p-3 mt-4 rounded border ".concat(Q.success?"border-green-200 bg-green-50 text-green-700":"border-red-200 bg-red-50 text-red-700"," text-sm"),children:[Q.message,(null==ee?void 0:ee.computed_limits)&&(0,s.jsxs)("div",{className:"mt-2 p-2 bg-white bg-opacity-50 rounded text-xs",children:[(0,s.jsx)("div",{className:"font-medium mb-1",children:"Video Limits:"}),(0,s.jsxs)("div",{children:["Lower: ",ee.computed_limits.lower.toFixed(3)," | Upper: ",ee.computed_limits.upper.toFixed(3)]}),(0,s.jsxs)("div",{children:["Data range: ",ee.computed_limits.actual_min.toFixed(3)," to ",ee.computed_limits.actual_max.toFixed(3)]}),ee.computed_limits.percentile_based&&(0,s.jsx)("div",{className:"text-gray-600 italic",children:"Limits auto-computed from 5th-95th percentiles"})]}),Q.out_path&&et&&(0,s.jsxs)("div",{className:"mt-2",children:[(0,s.jsx)("video",{controls:!0,className:"w-full rounded border",style:{maxHeight:512},src:ed(Q.out_path),onError:eu,children:"Your browser does not support the video tag."}),ea&&(0,s.jsxs)("div",{className:"p-2 bg-red-50 text-red-600 text-sm mt-1 rounded flex items-center gap-2",children:["Error loading video. The file might not be ready yet.",(0,s.jsx)(E,{variant:"outline",size:"sm",onClick:em,children:"Retry"})]})]})]}),ee&&ee.processing&&(0,s.jsxs)("div",{className:"w-full space-y-2 mt-4",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between text-sm",children:[(0,s.jsx)("span",{children:"Processing video..."}),(0,s.jsxs)("span",{children:[ee.progress,"%"]})]}),(0,s.jsx)("div",{className:"w-full bg-gray-200 rounded-full h-2",children:(0,s.jsx)("div",{className:"bg-soton-blue h-2 rounded-full transition-all duration-300",style:{width:"".concat(ee.progress,"%")}})}),ee.message&&(0,s.jsx)("div",{className:"text-xs text-gray-600",children:ee.message})]}),(0,s.jsx)("div",{className:"pt-4 flex flex-col gap-2",children:(0,s.jsxs)("div",{className:"flex justify-end gap-2",children:[(0,s.jsx)(E,{variant:"outline",onClick:eo,disabled:!(null==ee?void 0:ee.processing),children:"Cancel"}),(0,s.jsx)(E,{variant:"outline",onClick:()=>ei(!0),disabled:q||(null==ee?void 0:ee.processing),children:"Test Video (50 frames)"}),(0,s.jsx)(E,{className:"bg-soton-blue",onClick:()=>ei(!1),disabled:q||(null==ee?void 0:ee.processing),children:q?"Starting...":(null==ee?void 0:ee.processing)?"Processing...":"Create Full Video"})]})})]}),(0,s.jsx)(y,{value:"browse",className:"pt-4",children:$?(0,s.jsx)("div",{className:"text-center p-4",children:"Loading available videos..."}):X.length>0?(0,s.jsxs)("div",{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"space-y-2",children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Select Video"}),(0,s.jsxs)(D,{value:H,onValueChange:K,children:[(0,s.jsx)(L,{id:"videoSelect",children:(0,s.jsx)(V,{placeholder:"Select a video"})}),(0,s.jsx)(W,{children:X.map((e,t)=>(0,s.jsx)(Z,{value:e,children:ec(e)},t))})]})]}),H&&(0,s.jsxs)("div",{className:"mt-4",children:[(0,s.jsxs)("div",{className:"mb-2 text-xs text-gray-500 break-all",children:["Path: ",H]}),(0,s.jsx)("video",{controls:!0,className:"w-full rounded border",style:{maxHeight:512},src:ed(H),onError:e=>{console.error("Video playback error:",e),e.target.insertAdjacentHTML("afterend",'<div class="p-2 bg-red-50 text-red-600 text-sm mt-1 rounded">\n Error loading video. Please check the file path.\n </div>')},children:"Your browser does not support the video tag."})]}),(0,s.jsx)("div",{className:"flex justify-end",children:(0,s.jsx)(E,{variant:"outline",onClick:en,className:"mt-2",children:"Refresh Videos"})})]}):(0,s.jsx)("div",{className:"text-center p-4",children:"No videos found. Create a video first or select a different base path."})})]})]})})]})})}var eR=function(e){let{raw:t,src:a,vmin:l,vmax:n,title:i,meta:o,arrayPostUrl:c}=e,d=(0,r.useRef)(null),u=(0,r.useRef)(null),m=(0,r.useRef)(null),h=(0,r.useRef)(null),x=(0,r.useRef)(null),g=(0,r.useRef)(null),[p,f]=(0,r.useState)(!1),[v,j]=(0,r.useState)(!1),[b,y]=(0,r.useState)({left:0,top:0}),N=window.devicePixelRatio||1,[w,_]=(0,r.useState)({w:0,h:0}),[S,k]=(0,r.useState)([{points:[],closed:!1,name:"Polygon 1"}]),[C,P]=(0,r.useState)(0),[M,F]=(0,r.useState)(!1);(0,r.useEffect)(()=>{(async function(){if((null==o?void 0:o.basePathIdx)!==void 0&&(null==o?void 0:o.camera)){F(!0);try{let e=new URLSearchParams({basepath_idx:o.basePathIdx.toString(),camera:o.camera}),t=await fetch("/backend/load_mask?".concat(e));if(!t.ok){console.log("No existing mask found, starting fresh");return}let a=await t.json();if(a.polygons&&a.polygons.length>0){let e=a.polygons.map(e=>({name:e.name||"Polygon ".concat(e.index+1),closed:!0,points:e.points.map(e=>({x:e[0],y:e[1]}))}));k(e),P(e.length>0?0:-1),console.log("Loaded ".concat(e.length," polygon(s) from existing mask"))}}catch(e){console.error("Error loading existing mask:",e)}finally{F(!1)}}})()},[null==o?void 0:o.basePathIdx,null==o?void 0:o.camera]),(0,r.useEffect)(()=>{if(!a){h.current=null;return}let e=new Image;e.onload=()=>{h.current=e,_({w:e.naturalWidth,h:e.naturalHeight}),R()},e.src="data:image/png;base64,".concat(a)},[a]),(0,r.useEffect)(()=>{(null==t?void 0:t.data)&&_({w:t.width,h:t.height})},[t]);let T=(0,r.useMemo)(()=>{if(!(null==t?void 0:t.data))return null;let{width:e,height:a,data:s}=t,r=new Uint8ClampedArray(e*a*4),i=Math.max(1e-12,n-l);for(let t=0;t<e*a;t++){let e=(Number(s[t])-l)/i;e<0&&(e=0),e>1&&(e=1);let a=Math.round(255*e),n=4*t;r[n]=a,r[n+1]=a,r[n+2]=a,r[n+3]=255}return new ImageData(r,e,a)},[t,l,n]),I=(0,r.useMemo)(()=>{if((null==t?void 0:t.data)||!h.current||!w.w||!w.h)return null;let{w:e,h:a}=w,s=document.createElement("canvas");s.width=e,s.height=a;let r=s.getContext("2d");if(!r)return null;r.drawImage(h.current,0,0);let i=r.getImageData(0,0,e,a),o=i.data,c=Math.max(1e-12,n-l);for(let e=0;e<o.length;e+=4){let t=(.299*o[e]+.587*o[e+1]+.114*o[e+2]-l)/c;t<0&&(t=0),t>1&&(t=1);let a=Math.round(255*t);o[e]=a,o[e+1]=a,o[e+2]=a}return i},[t,l,n,w]);function R(){let e=u.current,t=m.current,a=d.current;if(!e||!t||!a)return;let{w:s,h:r}=w;if(!s||!r)return;let l=Math.min((a.clientWidth||s)/s,720/r),n=Math.max(1,Math.round(s*l)),i=Math.max(1,Math.round(r*l));d.current&&(d.current.style.minHeight="".concat(i+50,"px"),d.current.style.minWidth="".concat(n+200,"px"),d.current.style.padding="".concat(25,"px ").concat(100,"px"),d.current.style.position="relative"),e.width=n,e.height=i,e.style.width="".concat(n,"px"),e.style.height="".concat(i,"px"),x.current&&(x.current.style.width="".concat(n,"px"),x.current.style.height="".concat(i,"px"),x.current.style.position="relative",x.current.style.margin="0"),t.width=n,t.height=i,t.style.width="".concat(n,"px"),t.style.height="".concat(i,"px"),t.style.position="absolute",t.style.left="0",t.style.top="0";let o=e.getContext("2d");if(o.clearRect(0,0,n,i),T){let e=document.createElement("canvas");e.width=s,e.height=r,e.getContext("2d").putImageData(T,0,0),o.imageSmoothingEnabled=!0,o.drawImage(e,0,0,s,r,0,0,n,i)}else if(I){let e=document.createElement("canvas");e.width=s,e.height=r,e.getContext("2d").putImageData(I,0,0),o.imageSmoothingEnabled=!0,o.drawImage(e,0,0,s,r,0,0,n,i)}let c=t.getContext("2d");c.strokeStyle="rgba(100, 100, 100, 0.5)",c.lineWidth=2,c.strokeRect(0,0,n,i);for(let e=0;e<S.length;e++){let t=S[e];if(0!==t.points.length){c.beginPath(),t.points.forEach((e,t)=>{let a=e.x/s*n,l=e.y/r*i;0===t?c.moveTo(a,l):c.lineTo(a,l)}),t.closed&&t.points.length>=3&&c.closePath(),c.strokeStyle=e===C?"#00ff88":"#ffcc00",c.stroke();for(let a=0;a<t.points.length;a++){let l=t.points[a],o=l.x/s*n,d=l.y/r*i;0===a&&e===C&&!t.closed&&t.points.length>=3?(c.fillStyle="#ff3366",c.beginPath(),c.arc(o,d,8,0,2*Math.PI),c.fill(),c.strokeStyle="#ffffff",c.lineWidth=2,c.stroke()):(c.fillStyle=e===C?"#00ff88":"#ffcc00",c.beginPath(),c.arc(o,d,3,0,2*Math.PI),c.fill())}}}}(0,r.useEffect)(()=>{if(!d.current)return;let e=new ResizeObserver(()=>R());return e.observe(d.current),()=>e.disconnect()},[]),(0,r.useEffect)(()=>{R()},[T,I,w,S,C]),(0,r.useEffect)(()=>{if(g.current){g.current.width=Math.round(180*N),g.current.height=Math.round(180*N);let e=g.current.getContext("2d");e&&(e.imageSmoothingEnabled=!0)}},[180,N]);let A=e=>!e.closed&&e.points.length>=3?{...e,closed:!0}:e;function z(){k(e=>{if(C>=0&&C<e.length){let t=e[C];if(!t.closed&&t.points.length>=3){let a=e.slice();return a[C]={...t,closed:!0},a}}return e})}function O(){let e=S.map(A);return k(e),e}function D(e){e.preventDefault(),0!==w.w&&k(t=>{let a=[...t],s=C;(s<0||s>=a.length)&&(s=a.length,a.push({points:[],closed:!1,name:"Polygon ".concat(s+1)}),C!==s&&P(s));let r=a[s];if(r.closed)return a;let l=function(e){let t=x.current.getBoundingClientRect(),{w:a,h:s}=w,r=e.clientX-t.left,l=e.clientY-t.top,n=r/t.width*a,i=l/t.height*s;return(n<0||n>=a||i<0||i>=s)&&(n<0&&(n=0),n>=a&&(n=a-1),i<0&&(i=0),i>=s&&(i=s-1),console.log("Snapped to corner or edge: (".concat(n.toFixed(1),", ").concat(i.toFixed(1),")"))),{x:n,y:i}}(e);if(r.points.length>=3){let e=r.points[0];if(8>=Math.sqrt(Math.pow(l.x-e.x,2)+Math.pow(l.y-e.y,2))){a[s]={...r,closed:!0};let e=a.length;return a.push({points:[],closed:!1,name:"Polygon ".concat(e+1)}),setTimeout(()=>P(e),0),a}}return a[s]={...r,points:[...r.points,l]},a})}function V(e){let{w:t,h:a}=w;if(!t||!a)return null;let s=document.createElement("canvas");s.width=t,s.height=a;let r=s.getContext("2d");for(let s of(r.clearRect(0,0,t,a),r.fillStyle="#ffffff",e))if(!(s.points.length<3)){r.beginPath(),r.moveTo(s.points[0].x,s.points[0].y);for(let e=1;e<s.points.length;e++)r.lineTo(s.points[e].x,s.points[e].y);r.closePath(),r.fill()}return s}async function L(){let e=V(O());if(!e)return;let t=await new Promise(t=>e.toBlob(e=>t(e),"image/png")),a=URL.createObjectURL(t),s=document.createElement("a");s.href=a,s.download="mask_".concat(o.camera,"_").concat(o.index,"_").concat(o.frame,".png"),document.body.appendChild(s),s.click(),s.remove(),URL.revokeObjectURL(a)}async function B(){let e=O(),t=V(e);if(!t)return;let a=t.getContext("2d"),{w:s,h:r}=w,l=a.getImageData(0,0,s,r),n=s*r,i=new Uint8Array(n);for(let e=0;e<n;e++)i[e]=l.data[4*e]>0?1:0;let d=e.filter(e=>e.points.length>=3).map((e,t)=>({index:t,name:e.name,points:e.points.map(e=>[e.x,e.y])})),u={meta:o,width:s,height:r,data:Array.from(i),polygons:d};await fetch(c,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(u)})}return(0,s.jsxs)("div",{className:"w-full",children:[(0,s.jsxs)("div",{className:"flex items-center justify-between mb-2",children:[(0,s.jsx)("span",{className:"text-sm font-medium text-gray-600",children:i}),w.w>0&&w.h>0&&(0,s.jsxs)("span",{className:"text-xs text-gray-500",children:["Native: ",w.w," \xd7 ",w.h," px"]})]}),M&&(0,s.jsx)("div",{className:"mb-2 px-3 py-2 bg-yellow-50 border border-yellow-200 rounded-md text-xs text-yellow-700",children:(0,s.jsx)("strong",{children:"⏳ Loading existing mask..."})}),!M&&S.length>0&&S[0].points.length>0&&(0,s.jsxs)("div",{className:"mb-2 px-3 py-2 bg-green-50 border border-green-200 rounded-md text-xs text-green-700",children:[(0,s.jsxs)("strong",{children:["✅ Loaded ",S.filter(e=>e.closed).length," polygon(s) from existing mask"]})," - You can edit, add, or delete polygons."]}),(0,s.jsxs)("div",{className:"mb-2 px-3 py-2 bg-blue-50 border border-blue-200 rounded-md text-xs text-blue-700",children:[(0,s.jsx)("strong",{children:"\uD83D\uDCA1 Tips:"})," Click near image edges to snap to edge pixels (magnifier turns ",(0,s.jsx)("span",{className:"text-orange-600 font-semibold",children:"orange"}),"). Click within 8 pixels of the starting point (shown as a ",(0,s.jsx)("span",{className:"text-pink-600 font-semibold",children:"larger red circle"}),") to auto-close and start a new polygon."]}),(0,s.jsxs)("div",{className:"mb-3 grid grid-cols-1 md:grid-cols-3 gap-3",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 justify-start",children:[(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:function(){z(),k(e=>{let t=e.length,a=[...e,{points:[],closed:!1,name:"Polygon ".concat(t+1)}];return P(t),a})},children:"New polygon"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:function(){C<0||C>=S.length||k(e=>{let t=e.slice(),a={...t[C]};return a.closed||0===a.points.length||(a.points=a.points.slice(0,-1),t[C]=a),t})},disabled:C<0,children:"Undo point"}),(0,s.jsx)(E,{size:"sm",variant:"outline",onClick:function(){C<0||C>=S.length||k(e=>{let t=e.filter((e,t)=>t!==C);return t.length>0?P(t.length-1):P(-1),t})},disabled:C<0,children:"Delete"})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2 justify-center",children:[(0,s.jsx)(E,{size:"sm",onClick:function(){0!==S.length&&(z(),P(e=>e<0?S.length-1:(e-1+S.length)%S.length))},disabled:0===S.length,children:"Prev"}),(0,s.jsxs)("select",{className:"border rounded px-2 py-1 text-sm",value:C,onChange:e=>P(parseInt(e.target.value)),children:[(0,s.jsx)("option",{value:-1,children:"None"}),S.map((e,t)=>(0,s.jsx)("option",{value:t,children:e.name||"Polygon ".concat(t+1)},t))]}),(0,s.jsx)(E,{size:"sm",onClick:function(){0!==S.length&&(z(),P(e=>e<0?0:(e+1)%S.length))},disabled:0===S.length,children:"Next"})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2 justify-end",children:[(0,s.jsx)(E,{size:"sm",variant:p?"default":"outline",onClick:()=>f(e=>!e),children:p?"\uD83D\uDD0E On":"\uD83D\uDD0D"}),(0,s.jsx)(E,{size:"sm",className:"bg-soton-blue text-white",onClick:L,disabled:0===w.w,children:"Save PNG"}),(0,s.jsx)(E,{size:"sm",variant:"secondary",onClick:B,disabled:0===w.w,children:"Save Mask"}),(0,s.jsx)(E,{size:"sm",variant:"destructive",onClick:function(){k([]),P(-1)},children:"Clear all"})]})]}),(0,s.jsx)("div",{ref:d,className:"bg-black/80 rounded-md overflow-visible border border-gray-200 flex justify-center items-center cursor-crosshair",onPointerDown:e=>{e.currentTarget===e.target&&(e.preventDefault(),D(e))},children:(0,s.jsxs)("div",{ref:x,className:"relative cursor-crosshair",onPointerMove:function(e){if(!p||!g.current||!u.current||!x.current)return;let t=u.current,a=x.current.getBoundingClientRect(),s=e.clientX-a.left,r=e.clientY-a.top;if(s<0||r<0||s>a.width||r>a.height){j(!1);return}j(!0),y({left:e.clientX-90,top:e.clientY-90});let l=g.current.getContext("2d");if(!l)return;l.clearRect(0,0,180*N,180*N),l.save(),l.beginPath(),l.arc(180*N/2,180*N/2,180*N/2,0,2*Math.PI),l.clip();let n=t.getBoundingClientRect(),i=e.clientX-n.left,o=e.clientY-n.top;i=Math.max(0,Math.min(n.width,i)),o=Math.max(0,Math.min(n.height,o));let c=i/n.width*t.width,d=o/n.height*t.height,h=c-36,f=d-36;l.drawImage(t,h,f,72,72,0,0,180*N,180*N),m.current&&l.drawImage(m.current,h,f,72,72,0,0,180*N,180*N);let v=180*N/2,b=180*N/2,w=180*N*.3;l.save(),l.beginPath(),l.lineWidth=Math.max(2,1.5*N),l.strokeStyle="rgba(0,0,0,0.8)",l.moveTo(v-w,b),l.lineTo(v+w,b),l.moveTo(v,b-w),l.lineTo(v,b+w),l.stroke(),l.beginPath(),l.lineWidth=Math.max(1,N),l.strokeStyle="rgba(255,255,255,0.95)",l.moveTo(v-w,b),l.lineTo(v+w,b),l.moveTo(v,b-w),l.lineTo(v,b+w),l.stroke(),l.restore(),l.restore();let _=t.getBoundingClientRect(),S=e.clientX-_.left,k=e.clientY-_.top,C=S<0||k<0||S>_.width||k>_.height;l.beginPath(),l.arc(v,b,180*N/2-2*N,0,2*Math.PI),l.lineWidth=3*N,l.strokeStyle=C?"#ff6b35":"#005fa3",l.stroke()},onPointerLeave:function(){j(!1)},children:[(0,s.jsx)("canvas",{ref:u,className:"block"}),(0,s.jsx)("canvas",{ref:m,className:"absolute cursor-crosshair",onPointerDown:e=>{e.stopPropagation(),D(e)}}),(0,s.jsx)("canvas",{ref:g,style:{display:v&&p?"block":"none",position:"fixed",pointerEvents:"none",zIndex:9999,width:180,height:180,left:b.left,top:b.top,borderRadius:"50%",boxShadow:"0 2px 8px rgba(0,0,0,0.25)",border:"2px solid #333"}})]})})]})},eA=e=>{var t,a;let{config:l,updateConfig:n}=e,i=(null==l?void 0:null===(t=l.paths)||void 0===t?void 0:t.source_paths)||[],[o,c]=(0,r.useState)(0),[d,u]=(0,r.useState)(1),m=(null==l?void 0:null===(a=l.paths)||void 0===a?void 0:a.camera_numbers)||[];(0,r.useEffect)(()=>{0===m.length||m.includes(d)||u(m[0])},[m.length,m[0]]);let[h,x]=(0,r.useState)(1),[g,p]=(0,r.useState)("A"),[v,j]=(0,r.useState)(0),[b,y]=(0,r.useState)(255),[C,P]=(0,r.useState)(!0),[M,T]=(0,r.useState)(!1),[I,A]=(0,r.useState)(""),{enabled:z,mode:O,rectangularTop:B,rectangularBottom:U,rectangularLeft:Y,rectangularRight:G,setRectangularTop:J,setRectangularBottom:X,setRectangularLeft:H,setRectangularRight:K,updateEnabled:$,updateMode:q}=function(e,t){var a,s,l,n,i,o,c,d,u;let[m,h]=(0,r.useState)(null!==(i=null==e?void 0:e.enabled)&&void 0!==i&&i),[x,g]=(0,r.useState)(()=>"rectangular"===(null==e?void 0:e.mode)?"pixel_border":"polygon"),[p,f]=(0,r.useState)(null!==(o=null==e?void 0:null===(a=e.rectangular)||void 0===a?void 0:a.top)&&void 0!==o?o:64),[v,j]=(0,r.useState)(null!==(c=null==e?void 0:null===(s=e.rectangular)||void 0===s?void 0:s.bottom)&&void 0!==c?c:64),[b,y]=(0,r.useState)(null!==(d=null==e?void 0:null===(l=e.rectangular)||void 0===l?void 0:l.left)&&void 0!==d?d:0),[N,w]=(0,r.useState)(null!==(u=null==e?void 0:null===(n=e.rectangular)||void 0===n?void 0:n.right)&&void 0!==u?u:0);(0,r.useEffect)(()=>{(null==e?void 0:e.enabled)!==void 0&&h(e.enabled)},[null==e?void 0:e.enabled]),(0,r.useEffect)(()=>{(null==e?void 0:e.mode)&&g("rectangular"===e.mode?"pixel_border":"polygon")},[null==e?void 0:e.mode]),(0,r.useEffect)(()=>{if(null==e?void 0:e.rectangular){var t,a,s,r;f(null!==(t=e.rectangular.top)&&void 0!==t?t:64),j(null!==(a=e.rectangular.bottom)&&void 0!==a?a:64),y(null!==(s=e.rectangular.left)&&void 0!==s?s:0),w(null!==(r=e.rectangular.right)&&void 0!==r?r:0)}},[null==e?void 0:e.rectangular]);let _=(0,r.useCallback)(async e=>{try{var a;let s=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({masking:e})}),r=await s.json();if(!s.ok)throw Error(r.error||"Failed to update masking config");return(null===(a=r.updated)||void 0===a?void 0:a.masking)&&t(["masking"],r.updated.masking),!0}catch(e){return console.error("Error updating masking config:",e),!1}},[t]),S=(0,r.useCallback)(async e=>{h(e),await _({enabled:e,mode:"polygon"===x?"file":"rectangular",..."pixel_border"===x&&{rectangular:{top:p,bottom:v,left:b,right:N}}})},[x,p,v,b,N,_]),k=(0,r.useCallback)(async e=>{g(e),await _({enabled:m,mode:"polygon"===e?"file":"rectangular",..."pixel_border"===e&&{rectangular:{top:p,bottom:v,left:b,right:N}}})},[m,p,v,b,N,_]),C=(0,r.useCallback)(async e=>{f(e.top),j(e.bottom),y(e.left),w(e.right),"pixel_border"===x&&await _({enabled:m,mode:"rectangular",rectangular:e})},[m,x,_]);return{enabled:m,mode:x,rectangularTop:p,rectangularBottom:v,rectangularLeft:b,rectangularRight:N,setRectangularTop:f,setRectangularBottom:j,setRectangularLeft:y,setRectangularRight:w,updateEnabled:S,updateMode:k,updateRectangular:C}}(null==l?void 0:l.masking,n),{loading:Q,error:ee,imgA:ea,imgB:es,imgARaw:er,imgBRaw:en,metadata:ei,vmin:eo,vmax:ec,reload:eu}=el("/backend",o,"Cam".concat(d),h),em="A"===g?ea:es,eh="A"===g?er:en,ex=(null==ei?void 0:ei.bitDepth)?2**ei.bitDepth-1:255;return(0,r.useEffect)(()=>{C&&(T(!1),A(""))},[C]),(0,r.useEffect)(()=>{T(!1)},[o,d,h,g]),(0,r.useEffect)(()=>{let e="".concat(o,"-").concat(d,"-").concat(h,"-").concat(g);(eh||em)&&C&&!M&&(I!==e||""===I)&&(eh?void 0!==eo&&void 0!==ec&&(0!==eo||255!==ec)&&(j(eo),y(ec),A(e)):em&&(async()=>{try{let t="data:image/png;base64,".concat(em),a=new Image;a.onload=()=>{try{let t=document.createElement("canvas"),s=t.getContext("2d");if(!s)return;t.width=a.width,t.height=a.height,s.drawImage(a,0,0);let r=s.getImageData(0,0,a.width,a.height).data,l=[];for(let e=0;e<r.length;e+=4){let t=r[e],a=r[e+1],s=r[e+2],n=Math.round(.299*t+.587*a+.114*s);l.push(n)}l.sort((e,t)=>e-t);let n=Math.floor(.01*l.length),i=Math.floor(.99*l.length),o=l[n],c=l[i];j(o),y(c),A(e)}catch(t){console.warn("[Masking] PNG auto-contrast analysis failed:",t),j(0),y(255),A(e)}},a.src=t}catch(t){console.warn("[Masking] PNG auto-contrast failed:",t),j(0),y(255),A(e)}})())},[em,eh,eo,ec,o,d,h,g,I,M,C]),(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsxs)(N,{children:[(0,s.jsxs)(w,{children:[(0,s.jsx)(_,{children:"Raw Image Viewer"}),(0,s.jsx)(S,{children:"Load and view raw images. Select masking mode and toggle to apply masks for PIV processing."})]}),(0,s.jsxs)(k,{children:[(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-6 gap-4 items-end",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"basepath",children:"Source Path"}),(0,s.jsxs)(D,{value:String(o),onValueChange:e=>c(Number(e)),children:[(0,s.jsx)(L,{id:"basepath",children:(0,s.jsx)(V,{placeholder:"Pick base path"})}),(0,s.jsx)(W,{children:i.map((e,t)=>(0,s.jsx)(Z,{value:String(t),children:(0,f.E)(e)},t))})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"camera",children:"Camera"}),(0,s.jsxs)(D,{value:String(d),onValueChange:e=>u(Number(e)),children:[(0,s.jsx)(L,{id:"camera",children:(0,s.jsx)(V,{placeholder:"Select camera"})}),(0,s.jsx)(W,{children:m.map((e,t)=>(0,s.jsx)(Z,{value:String(e),children:e},t))})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"index",children:"Image Index"}),(0,s.jsx)(F,{id:"index",type:"number",value:h,min:1,onChange:e=>x(Math.max(1,Number(e.target.value)))})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{children:"Frame"}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(E,{size:"sm",variant:"A"===g?"default":"outline",onClick:()=>p("A"),children:"A"}),(0,s.jsx)(E,{size:"sm",variant:"B"===g?"default":"outline",onClick:()=>p("B"),children:"B"})]})]}),(0,s.jsx)("div",{className:"md:col-span-2 flex items-center gap-3",children:(0,s.jsx)(E,{id:"load-image-btn",className:"bg-soton-blue hover:bg-soton-darkblue",onClick:eu,disabled:Q,children:Q?"Loading...":"Load Image"})})]}),(0,s.jsxs)("div",{className:"mt-4 space-y-3 p-3 border rounded-md",children:[(0,s.jsx)("div",{className:"flex items-center justify-between",children:(0,s.jsxs)("div",{className:"flex items-center gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"masking-mode-select",children:"Masking Mode"}),(0,s.jsxs)(D,{value:O,onValueChange:e=>q(e),children:[(0,s.jsx)(L,{id:"masking-mode-select",className:"w-40",children:(0,s.jsx)(V,{})}),(0,s.jsxs)(W,{children:[(0,s.jsx)(Z,{value:"polygon",children:"Polygon"}),(0,s.jsx)(Z,{value:"pixel_border",children:"Pixel Border"})]})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(et,{id:"apply-mask-piv",checked:z,onCheckedChange:$}),(0,s.jsx)(R,{htmlFor:"apply-mask-piv",className:"text-sm",children:"Apply Mask for PIV"})]})]})}),"pixel_border"===O?(0,s.jsxs)("div",{className:"grid grid-cols-2 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"rect-top",children:"Top (pixels)"}),(0,s.jsx)(F,{id:"rect-top",type:"number",value:B,min:0,onChange:e=>J(Math.max(0,Number(e.target.value)))})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"rect-bottom",children:"Bottom (pixels)"}),(0,s.jsx)(F,{id:"rect-bottom",type:"number",value:U,min:0,onChange:e=>X(Math.max(0,Number(e.target.value)))})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"rect-left",children:"Left (pixels)"}),(0,s.jsx)(F,{id:"rect-left",type:"number",value:Y,min:0,onChange:e=>H(Math.max(0,Number(e.target.value)))})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)(R,{htmlFor:"rect-right",children:"Right (pixels)"}),(0,s.jsx)(F,{id:"rect-right",type:"number",value:G,min:0,onChange:e=>K(Math.max(0,Number(e.target.value)))})]})]}):(0,s.jsx)("div",{className:"text-sm text-gray-600",children:"Polygon mode: Create custom polygon masks using the editor below"})]})]})]}),(0,s.jsxs)("div",{className:"flex flex-col items-center mt-6",children:[em&&"polygon"===O&&(0,s.jsxs)("div",{className:"w-full space-y-4",children:[(0,s.jsxs)("div",{className:"space-y-3 p-3 border rounded-md",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(R,{children:"Contrast Controls"}),(0,s.jsxs)("div",{className:"flex items-center gap-2 ml-auto",children:[(0,s.jsx)(et,{id:"auto-scale",checked:C,onCheckedChange:P}),(0,s.jsx)(R,{htmlFor:"auto-scale",className:"text-sm",children:"Auto Scale"})]})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)(F,{type:"number",value:v,min:0,max:b,onChange:e=>{T(!0),P(!1);let t=Math.min(Number(e.target.value),b);j(t),t>b&&y(t)},className:"w-20 h-8"}),(0,s.jsx)("div",{className:"w-full min-w-0",children:(0,s.jsxs)(ed.fC,{className:"relative flex items-center select-none touch-none w-full h-5",min:0,max:ex,step:1,value:[v,b],onValueChange:e=>{let[t,a]=e;T(!0),P(!1),j(t),y(a)},children:[(0,s.jsx)(ed.fQ,{className:"bg-gray-200 relative grow rounded-full h-[3px]",children:(0,s.jsx)(ed.e6,{className:"absolute bg-blue-500 rounded-full h-full"})}),(0,s.jsx)(ed.bU,{className:"block w-5 h-5 bg-white rounded-[10px] border border-gray-300 hover:bg-gray-50 data-[disabled]:pointer-events-none data-[disabled]:opacity-50"}),(0,s.jsx)(ed.bU,{className:"block w-5 h-5 bg-white rounded-[10px] border border-gray-300 hover:bg-gray-50 data-[disabled]:pointer-events-none data-[disabled]:opacity-50"})]})}),(0,s.jsx)(F,{type:"number",value:b,min:v,max:ex,onChange:e=>{T(!0),P(!1);let t=Math.max(Number(e.target.value),v);y(t),t<v&&j(t)},className:"w-20 h-8"})]})]}),(0,s.jsx)(eR,{raw:eh,src:eh?void 0:em,vmin:v,vmax:b,title:"Polygon Mask Editor",meta:{basePathIdx:o,camera:"Cam".concat(d),index:h,frame:g},arrayPostUrl:"/backend/save_mask_array"},"".concat(o,"-").concat(d,"-").concat(h,"-").concat(g))]}),"pixel_border"===O&&(0,s.jsx)("div",{className:"text-center text-gray-600 p-8 border rounded-md bg-gray-50",children:"Pixel border mode enabled. Rectangular masking will be applied with the specified border values."}),Q&&(0,s.jsx)("div",{className:"text-center text-gray-500",children:"Loading image..."}),!em&&!Q&&(0,s.jsx)("div",{className:"text-center text-gray-400",children:"No image loaded."}),ee&&(0,s.jsx)("div",{className:"text-red-600 mt-2",children:ee})]})]})};let ez=e=>e?e.replace(/\\/g,"/").split("/").filter(Boolean).pop()||e:"",eO=e=>{var t,a;let{config:l,updateConfig:n,cameraOptions:i,sourcePaths:o,imageCount:c=1e3}=e,{dt:d,pxPerMm:u,sourcePathIdx:m,calibrating:h,scaleFactorJobId:x,setDt:g,setPxPerMm:p,setSourcePathIdx:f,status:v,scaleFactorJobStatus:j,scaleFactorJobDetails:b,calibrateVectors:y}=function(){var e;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},a=arguments.length>1?arguments[1]:void 0,s=arguments.length>2?arguments[2]:void 0,l=arguments.length>3?arguments[3]:void 0,n=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1e3,[i,o]=(0,r.useState)(void 0!==t.dt?String(t.dt):""),[c,d]=(0,r.useState)(void 0!==t.px_per_mm?String(t.px_per_mm):""),[u,m]=(0,r.useState)(null!==(e=t.source_path_idx)&&void 0!==e?e:0),[h,x]=(0,r.useState)(!1),[g,p]=(0,r.useState)(null),f=(0,r.useRef)(null);(0,r.useEffect)(()=>{var e;o(void 0!==t.dt?String(t.dt):""),d(void 0!==t.px_per_mm?String(t.px_per_mm):""),m(null!==(e=t.source_path_idx)&&void 0!==e?e:0)},[t]),(0,r.useEffect)(()=>{},[s.length]),(0,r.useEffect)(()=>(f.current&&clearTimeout(f.current),f.current=setTimeout(async()=>{let e=Number(i),t=Number(c);if(!isNaN(e)&&""!==i&&!isNaN(t)&&""!==c&&Number.isFinite(u))try{var s,r;let l=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({calibration:{scale_factor:{dt:e,px_per_mm:t,source_path_idx:u}}})}),n=await l.json();if(!l.ok)throw Error(n.error||"Failed to save scale factor");(null===(r=n.updated)||void 0===r?void 0:null===(s=r.calibration)||void 0===s?void 0:s.scale_factor)&&a(["calibration","scale_factor"],n.updated.calibration.scale_factor)}catch(e){console.error("Failed to save scale factor:",e)}},500),()=>{f.current&&clearTimeout(f.current)}),[i,c,u,a]);let v=(e=>{let[t,a]=(0,r.useState)("not_started");return(0,r.useEffect)(()=>()=>{},[e]),t})(u),{status:j,details:b}=(e=>{let[t,a]=(0,r.useState)("not_started"),[s,l]=(0,r.useState)(null),n=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!e){a("not_started"),l(null),n.current&&(clearInterval(n.current),n.current=null);return}let t=!0,s=async()=>{try{let r=await fetch("/backend/calibration/scale_factor/status/".concat(e)),i=await r.json();t&&(a(i.status||"not_started"),l(i),"completed"===i.status||"failed"===i.status||i.progress>=100?n.current&&(clearInterval(n.current),n.current=null):"running"!==i.status&&"starting"!==i.status||n.current||(n.current=setInterval(s,500)))}catch(e){t&&a("not_started"),n.current&&(clearInterval(n.current),n.current=null)}};return s(),()=>{t=!1,n.current&&(clearInterval(n.current),n.current=null)}},[e]),{status:t,details:s}})(g),y=async()=>{x(!0);try{let e=await fetch("/backend/calibration/scale_factor/calibrate_vectors",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({source_path_idx:u,dt:Number(i),px_per_mm:Number(c),image_count:n,type_name:"instantaneous"})}),t=await e.json();if(e.ok)console.log("Scale factor calibration started! Job ID: ".concat(t.job_id)),p(t.job_id);else throw Error(t.error||"Failed to start scale factor calibration")}catch(e){console.error("Error starting scale factor calibration: ".concat(e.message))}finally{x(!1)}};return{dt:i,pxPerMm:c,sourcePathIdx:u,calibrating:h,scaleFactorJobId:g,setDt:o,setPxPerMm:d,setSourcePathIdx:m,setCalibrating:x,setScaleFactorJobId:p,status:v,scaleFactorJobStatus:j,scaleFactorJobDetails:b,cameraOptions:s,sourcePaths:l,calibrateVectors:y}}((null===(t=l.calibration)||void 0===t?void 0:t.scale_factor)||{},n,i,o,c),S=async()=>{try{var e;let t=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({calibration:{active:"scale_factor"}})}),a=await t.json();if(!t.ok)throw Error(a.error||"Failed to set active method");(null===(e=a.updated)||void 0===e?void 0:e.calibration)&&n(["calibration"],{...l.calibration,...a.updated.calibration})}catch(e){console.error("Failed to set active calibration method:",e)}},C=(null===(a=l.calibration)||void 0===a?void 0:a.active)==="scale_factor";return(0,s.jsxs)(N,{children:[x&&b&&(0,s.jsxs)("div",{className:"mb-4 p-4 border rounded bg-blue-50",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 text-sm mb-2",children:[(0,s.jsx)("strong",{children:"Scale Factor Calibration Progress:"}),(0,s.jsx)("span",{className:"font-medium",children:j})]}),("running"===j||"starting"===j)&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-green-600 text-sm",children:[(0,s.jsx)("span",{className:"animate-spin inline-block w-4 h-4 border-2 border-green-600 border-t-transparent rounded-full"}),"Processing files..."]}),(0,s.jsx)("div",{className:"w-full bg-gray-200 h-2 rounded overflow-hidden",children:(0,s.jsx)("div",{className:"h-2 bg-green-600",style:{width:"".concat(b.progress||0,"%")}})}),(0,s.jsxs)("div",{className:"text-xs text-muted-foreground mt-1",children:["Progress: ",b.progress||0,"%",void 0!==b.processed_files&&void 0!==b.total_files&&" (Files: ".concat(b.processed_files,"/").concat(b.total_files,")")]}),"completed"===j&&(0,s.jsxs)("div",{className:"mt-2 text-xs text-green-600",children:["Scale factor calibration completed! Processed ",b.processed_files," files."]}),"failed"===j&&b.error&&(0,s.jsxs)("div",{className:"mt-2 text-xs text-red-600",children:["Error: ",b.error]})]}),(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Scale Factor Calibration"})}),(0,s.jsxs)(k,{className:"space-y-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"block text-xs font-medium",children:"Source Path"}),(0,s.jsxs)(D,{value:String(m),onValueChange:e=>f(Number(e)),children:[(0,s.jsx)(L,{id:"srcpath",children:(0,s.jsx)(V,{placeholder:"Pick source path"})}),(0,s.jsx)(W,{children:o.map((e,t)=>(0,s.jsx)(Z,{value:String(t),children:ez(e)},t))})]}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Configured in Settings → Directories."})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"block text-xs font-medium",children:"Δt (seconds)"}),(0,s.jsx)(F,{type:"number",value:d,onChange:e=>g(e.target.value),step:"any",min:"0",placeholder:"1.0"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"block text-xs font-medium",children:"Pixels per mm"}),(0,s.jsx)(F,{type:"number",value:u,onChange:e=>p(e.target.value),step:"any",min:"0",placeholder:"1.0"})]}),(0,s.jsxs)("div",{className:"mb-2",children:["running"===v&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-blue-600 text-sm",children:[(0,s.jsx)("span",{className:"animate-spin inline-block w-4 h-4 border-2 border-blue-600 border-t-transparent rounded-full"}),"Calibration is running..."]}),"completed"===v&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-green-600 text-sm",children:[(0,s.jsx)("span",{className:"inline-block w-3 h-3 bg-green-600 rounded-full"}),"Calibration completed!"]}),"error"===v&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-red-600 text-sm",children:[(0,s.jsx)("span",{className:"inline-block w-3 h-3 bg-red-600 rounded-full"}),"Calibration error!"]})]}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsx)(E,{onClick:y,disabled:!1,className:"bg-green-600 hover:bg-green-700 text-white px-6 py-3",children:h?"Calibrating...":"Calibrate All Vectors"}),(0,s.jsx)(E,{onClick:S,disabled:C,className:C?"bg-green-600 hover:bg-green-600 text-white px-6 py-3":"",variant:C?"default":"outline",children:C?"Active":"Set as Active Method"})]}),(0,s.jsxs)("div",{className:"text-xs text-gray-500 mt-2",children:["This method calibrates all vectors using scale factor conversion: pixels / px_per_mm / dt.",(0,s.jsx)("br",{}),"Automatically places bottom-left corner at origin (0,0).",(0,s.jsx)("br",{}),"Updates the calibration.scale_factor block in config.yaml."]})]})]})},eD=e=>e?e.replace(/\\/g,"/").split("/").filter(Boolean).pop()||e:"",eV=e=>{var t,a,l,n,i,o,c,d,u,m,h,x,g,p,f,v;let{config:j,updateConfig:b,cameraOptions:y,sourcePaths:S,imageCount:C=1e3}=e,{sourcePathIdx:P,camera:M,filePattern:T,patternCols:I,patternRows:R,dotSpacingMm:A,enhanceDots:z,asymmetric:O,dt:B,imageB64:U,totalImages:Y,gridPoints:G,showIndices:J,dewarpedB64:X,cameraModel:H,gridData:K,nativeSize:$,generating:q,vectorJobId:Q,planarJobId:ee,loadingResults:et,setSourcePathIdx:ea,setCamera:es,setFilePattern:er,setPatternCols:el,setPatternRows:en,setDotSpacingMm:ei,setEnhanceDots:eo,setAsymmetric:ec,setDt:ed,calibrationStatus:eu,calibrationDetails:em,vectorStatus:eh,vectorDetails:ex,generateCameraModel:eg,calibrateVectors:ep}=function(){var e,t,a,s,l;let n=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},i=arguments.length>1?arguments[1]:void 0,o=arguments.length>2?arguments[2]:void 0,c=arguments.length>3?arguments[3]:void 0,d=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1e3,u=null!==(e=n.source_path_idx)&&void 0!==e?e:0,m=u<c.length?u:0,[h,x]=(0,r.useState)(m),[g,p]=(0,r.useState)(null!==(t=n.camera)&&void 0!==t?t:1),[f,v]=(0,r.useState)(void 0!==n.image_index?String(n.image_index):"0"),[j,b]=(0,r.useState)(null!==(a=n.file_pattern)&&void 0!==a?a:"calib%05d.tif"),[y,N]=(0,r.useState)(void 0!==n.pattern_cols?String(n.pattern_cols):"10"),[w,_]=(0,r.useState)(void 0!==n.pattern_rows?String(n.pattern_rows):"10"),[S,k]=(0,r.useState)(void 0!==n.dot_spacing_mm?String(n.dot_spacing_mm):"28.89"),[C,P]=(0,r.useState)(null===(s=n.enhance_dots)||void 0===s||s),[M,E]=(0,r.useState)(null!==(l=n.asymmetric)&&void 0!==l&&l),[F,T]=(0,r.useState)(void 0!==n.dt?String(n.dt):"1.0"),[I,R]=(0,r.useState)(null),[A,z]=(0,r.useState)(0),[O,D]=(0,r.useState)([]),[V,L]=(0,r.useState)(!0),[B,U]=(0,r.useState)(null),[W,Z]=(0,r.useState)(null),[Y,G]=(0,r.useState)(null),[J,X]=(0,r.useState)({w:1024,h:1024}),[H,K]=(0,r.useState)(!1),[$,q]=(0,r.useState)(null),[Q,ee]=(0,r.useState)(null),[et,ea]=(0,r.useState)(!1),es=(0,r.useRef)(null);(0,r.useEffect)(()=>{var e,t,a,s,r;let l=null!==(e=n.source_path_idx)&&void 0!==e?e:0;x(l<c.length?l:0),p(null!==(t=n.camera)&&void 0!==t?t:1),v(void 0!==n.image_index?String(n.image_index):"0"),b(null!==(a=n.file_pattern)&&void 0!==a?a:"calib%05d.tif"),N(void 0!==n.pattern_cols?String(n.pattern_cols):"10"),_(void 0!==n.pattern_rows?String(n.pattern_rows):"10"),k(void 0!==n.dot_spacing_mm?String(n.dot_spacing_mm):"28.89"),P(null===(s=n.enhance_dots)||void 0===s||s),E(null!==(r=n.asymmetric)&&void 0!==r&&r),T(void 0!==n.dt?String(n.dt):"1.0")},[n,c.length]),(0,r.useEffect)(()=>{let e=Number.isFinite(h)&&""!==f&&!isNaN(Number(f))&&""!==y&&!isNaN(Number(y))&&""!==w&&!isNaN(Number(w))&&""!==S&&!isNaN(Number(S))&&""!==F&&!isNaN(Number(F));return es.current&&clearTimeout(es.current),es.current=setTimeout(async()=>{if(!e)return;let t={source_path_idx:h,camera:g,image_index:Number(f),file_pattern:j,pattern_cols:Number(y),pattern_rows:Number(w),dot_spacing_mm:Number(S),enhance_dots:C,asymmetric:M,dt:Number(F)};try{var a,s;let e=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({calibration:{pinhole:t}})}),r=await e.json();if(!e.ok)throw Error(r.error||"Failed to save pinhole config");(null===(s=r.updated)||void 0===s?void 0:null===(a=s.calibration)||void 0===a?void 0:a.pinhole)&&i(["calibration","pinhole"],r.updated.calibration.pinhole)}catch(e){console.error("Failed to save pinhole config:",e)}},500),()=>{es.current&&clearTimeout(es.current)}},[h,g,f,j,y,w,S,C,M,F,i]),(0,r.useEffect)(()=>{o.length>0&&!o.includes(g)&&p(o[0])},[o,g]);let{status:er,details:el}=((e,t)=>{let[a,s]=(0,r.useState)("not_started"),[l,n]=(0,r.useState)(null);return(0,r.useEffect)(()=>()=>{},[e,t]),{status:a,details:l}})(h,g),{status:en,details:ei}=(e=>{let[t,a]=(0,r.useState)("not_started"),[s,l]=(0,r.useState)(null),n=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!e){a("not_started"),l(null),n.current&&(clearInterval(n.current),n.current=null);return}let t=!0,s=async()=>{try{let r=await fetch("/backend/calibration/vectors/status/".concat(e)),i=await r.json();t&&(a(i.status||"not_started"),l(i),"completed"===i.status||"failed"===i.status||i.progress>=100?n.current&&(clearInterval(n.current),n.current=null):"running"!==i.status&&"starting"!==i.status||n.current||(n.current=setInterval(s,500)))}catch(e){t&&(a("not_started"),n.current&&(clearInterval(n.current),n.current=null))}};return s(),()=>{t=!1,n.current&&(clearInterval(n.current),n.current=null)}},[e]),{status:t,details:s}})($),eo=async()=>{ea(!0);try{console.log("Loading calibration results for image index ".concat(f,"..."));let s=await fetch("/backend/calibration/planar/compute",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({source_path_idx:h,camera:g,image_index:f,file_pattern:j,pattern_cols:y,pattern_rows:w,dot_spacing_mm:S,enhance_dots:C,asymmetric:M,dt:F})}),r=await s.json();if(s.ok){var e,t,a;console.log("Raw response data:",r),(null===(e=r.results)||void 0===e?void 0:e.grid_data)&&(console.log("Setting grid data:",r.results.grid_data),G(r.results.grid_data),D(r.results.grid_data.grid_points||[]),r.results.grid_data.grid_png?console.log("Grid PNG found in response"):console.log("No grid PNG in response")),(null===(t=r.results)||void 0===t?void 0:t.camera_model)&&(console.log("Setting camera model:",r.results.camera_model),Z(r.results.camera_model)),(null===(a=r.results)||void 0===a?void 0:a.dewarped_image)&&U(r.results.dewarped_image),console.log("Calibration results loaded successfully")}else console.error("Error in response:",r)}catch(e){console.error("Error loading results: ".concat(e.message))}finally{ea(!1)}},ec=async()=>{K(!0),ea(!0);try{let e=await fetch("/backend/calibration/planar/get_image?source_path_idx=".concat(h,"&camera=").concat(g,"&image_index=").concat(f,"&file_pattern=").concat(encodeURIComponent(j)));if(404===e.status){alert("Calibration image not found. (File or folder does not exist)"),K(!1);return}let t=await e.json();if(e.ok){R(t.image),X({w:t.width,h:t.height}),z(t.total_images);let e=await fetch("/backend/calibration/planar/calibrate_all",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({source_path_idx:h,camera:g,file_pattern:j,pattern_cols:y,pattern_rows:w,dot_spacing_mm:S,enhance_dots:C,asymmetric:M,dt:F})}),a=await e.json();if(e.ok&&a.job_id)ee(a.job_id),(()=>{let e=setInterval(async()=>{try{let t=await fetch("/backend/calibration/planar/calibrate_all/status/".concat(a.job_id)),s=await t.json();"completed"===s.status?(clearInterval(e),setTimeout(()=>{eo()},1e3)):("failed"===s.status||"error"===s.status)&&(clearInterval(e),console.error("Calibration failed:",s.error))}catch(e){console.log("Error polling planar calibration job:",e)}},2e3)})();else throw Error(a.error||"Failed to start camera model generation")}else throw Error(t.error||"Failed to load image")}catch(e){console.error("Error starting camera model generation: ".concat(e.message))}finally{K(!1)}},ed=async()=>{try{let e=await fetch("/backend/calibration/vectors/calibrate_all",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({source_path_idx:h,camera:g,model_index:f,dt:F,image_count:d,vector_pattern:"%05d.mat",type_name:"instantaneous"})}),t=await e.json();if(e.ok)console.log("Vector calibration started using model ".concat(t.model_used,"!")),q(t.job_id);else throw Error(t.error||"Failed to start vector calibration")}catch(e){console.error("Error starting vector calibration: ".concat(e.message))}};return{sourcePathIdx:h,camera:g,imageIndex:f,filePattern:j,patternCols:y,patternRows:w,dotSpacingMm:S,enhanceDots:C,asymmetric:M,dt:F,imageB64:I,totalImages:A,gridPoints:O,showIndices:V,dewarpedB64:B,cameraModel:W,gridData:Y,nativeSize:J,generating:H,vectorJobId:$,planarJobId:Q,loadingResults:et,setSourcePathIdx:x,setCamera:p,setImageIndex:v,setFilePattern:b,setPatternCols:N,setPatternRows:_,setDotSpacingMm:k,setEnhanceDots:P,setAsymmetric:E,setDt:T,setImageB64:R,setTotalImages:z,setGridPoints:D,setShowIndices:L,setDewarpedB64:U,setCameraModel:Z,setGridData:G,setNativeSize:X,setGenerating:K,setVectorJobId:q,setPlanarJobId:ee,setLoadingResults:ea,calibrationStatus:er,calibrationDetails:el,vectorStatus:en,vectorDetails:ei,cameraOptions:o,sourcePaths:c,generateCameraModel:ec,calibrateVectors:ed,loadResultsForCurrentImage:eo}}((null===(t=j.calibration)||void 0===t?void 0:t.pinhole)||{},b,y,S,C),[ef,ev]=(0,r.useState)(String(B)),[ej,eb]=(0,r.useState)(String(A)),[ey,eN]=(0,r.useState)(String(I)),[ew,e_]=(0,r.useState)(String(R));(0,r.useEffect)(()=>{ev(String(B))},[B]),(0,r.useEffect)(()=>{eb(String(A))},[A]),(0,r.useEffect)(()=>{eN(String(I))},[I]),(0,r.useEffect)(()=>{e_(String(R))},[R]);let eS=async()=>{try{var e;let t=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({calibration:{active:"pinhole"}})}),a=await t.json();if(!t.ok)throw Error(a.error||"Failed to set active method");(null===(e=a.updated)||void 0===e?void 0:e.calibration)&&b(["calibration"],{...j.calibration,...a.updated.calibration})}catch(e){console.error("Failed to set active calibration method:",e)}},ek=(null===(a=j.calibration)||void 0===a?void 0:a.active)==="pinhole";return(0,s.jsxs)("div",{className:"space-y-6",children:[Q&&ex&&(0,s.jsxs)(N,{className:"mb-4",children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Vector Calibration Status"})}),(0,s.jsxs)(k,{className:"space-y-2",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 text-sm",children:["Status: ",(0,s.jsx)("span",{className:"font-medium",children:eh})]}),("running"===eh||"starting"===eh)&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-green-600 text-sm",children:[(0,s.jsx)("span",{className:"animate-spin inline-block w-4 h-4 border-2 border-green-600 border-t-transparent rounded-full"}),"Vector calibration is running..."]}),(0,s.jsx)("div",{className:"w-full bg-gray-200 h-2 rounded overflow-hidden",children:(0,s.jsx)("div",{className:"h-2 bg-green-600",style:{width:"".concat(ex.progress||0,"%")}})}),(0,s.jsxs)("div",{className:"text-xs text-muted-foreground",children:["Progress: ",ex.progress||0,"% ",void 0!==ex.processed_frames&&void 0!==ex.total_frames&&"(Frames: ".concat(ex.processed_frames,"/").concat(ex.total_frames,")")]}),"completed"===eh&&(0,s.jsx)("div",{className:"mt-2 text-xs text-green-600",children:"Vector calibration completed successfully! All runs with valid data were processed."}),"failed"===eh&&ex.error&&(0,s.jsxs)("div",{className:"mt-2 text-xs text-red-600",children:["Error: ",ex.error]})]})]}),(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Pinhole Calibration (Planar)"})}),(0,s.jsxs)(k,{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"grid md:grid-cols-2 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Source Path"}),(0,s.jsxs)(D,{value:String(P),onValueChange:e=>ea(Number(e)),children:[(0,s.jsx)(L,{id:"srcpath",children:(0,s.jsx)(V,{placeholder:"Pick source path"})}),(0,s.jsx)(W,{children:S.map((e,t)=>(0,s.jsx)(Z,{value:String(t),children:eD(e)},t))})]}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Configured in Settings → Directories."})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Camera"}),(0,s.jsxs)(D,{value:String(M),onValueChange:e=>es(Number(e)),children:[(0,s.jsx)(L,{id:"camera",children:(0,s.jsx)(V,{placeholder:"Select camera"})}),(0,s.jsx)(W,{children:y.map((e,t)=>(0,s.jsx)(Z,{value:String(e),children:"Camera ".concat(e)},t))})]})]})]}),(0,s.jsxs)("div",{className:"grid md:grid-cols-2 lg:grid-cols-3 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"File Pattern:"}),(0,s.jsx)(F,{value:T,onChange:e=>er(e.target.value),placeholder:"calib%05d.tif"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Pattern Cols:"}),(0,s.jsx)(F,{type:"number",value:ey,onChange:e=>eN(e.target.value),onBlur:()=>el(ey),min:"1",step:"1"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Pattern Rows:"}),(0,s.jsx)(F,{type:"number",value:ew,onChange:e=>e_(e.target.value),onBlur:()=>en(ew),min:"1",step:"1"})]})]}),(0,s.jsxs)("div",{className:"grid md:grid-cols-2 lg:grid-cols-3 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Dot Spacing (mm):"}),(0,s.jsx)(F,{type:"number",value:ej,onChange:e=>eb(e.target.value),onBlur:()=>ei(ej),step:"any",min:"0"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Δt (seconds):"}),(0,s.jsx)(F,{type:"number",value:ef,onChange:e=>ev(e.target.value),onBlur:()=>ed(ef),step:"any",min:"0.001"})]}),(0,s.jsx)("div",{children:(0,s.jsxs)("label",{className:"block text-xs font-medium",children:[(0,s.jsx)("input",{type:"checkbox",checked:z,onChange:e=>eo(e.target.checked),className:"mr-2"}),"Enhance Dots"]})})]}),(0,s.jsxs)("div",{className:"mb-2",children:["running"===eu&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-blue-600 text-sm",children:[(0,s.jsx)("span",{className:"animate-spin inline-block w-4 h-4 border-2 border-blue-600 border-t-transparent rounded-full"}),"Calibration is running..."]}),"completed"===eu&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-green-600 text-sm",children:[(0,s.jsx)("span",{className:"inline-block w-3 h-3 bg-green-600 rounded-full"}),"Calibration completed!"]}),"error"===eu&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-red-600 text-sm",children:[(0,s.jsx)("span",{className:"inline-block w-3 h-3 bg-red-600 rounded-full"}),"Calibration error: ",null==em?void 0:em.error]}),"not_started"===eu&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-gray-400 text-sm",children:[(0,s.jsx)("span",{className:"inline-block w-3 h-3 bg-gray-400 rounded-full"}),"Calibration not started."]})]}),(0,s.jsxs)("div",{className:"border-t pt-4",children:[(0,s.jsxs)("div",{className:"flex gap-4 items-center",children:[(0,s.jsx)(E,{onClick:eg,disabled:q||"running"===eh||"running"===eu,className:"bg-blue-600 hover:bg-blue-700 text-white px-6 py-3",children:q?"Generating...":"Generate Camera Model"}),(0,s.jsx)(E,{onClick:ep,disabled:"running"===eh||"starting"===eh,className:"bg-green-600 hover:bg-green-700 text-white px-6 py-3",children:"running"===eh||"starting"===eh?"Calibrating...":"Calibrate Vectors"}),(0,s.jsx)(E,{onClick:eS,disabled:ek,className:ek?"bg-green-600 hover:bg-green-600 text-white px-6 py-3":"",variant:ek?"default":"outline",children:ek?"Active":"Set as Active Method"})]}),(0,s.jsxs)("div",{className:"text-xs text-gray-500 mt-2",children:[(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Generate Camera Model:"})," Process all calibration images to create camera models."]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Calibrate Vectors:"})," Use camera model to calibrate PIV vectors."]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Load Results:"})," Load existing calibration results."]})]})]})]})]}),et&&(0,s.jsxs)("div",{className:"flex items-center justify-center py-8",children:[(0,s.jsx)("span",{className:"animate-spin inline-block w-8 h-8 border-4 border-blue-600 border-t-transparent rounded-full"}),(0,s.jsx)("span",{className:"ml-3 text-blue-600 text-sm",children:"Loading calibration results..."})]}),K&&K.grid_png&&!et&&(0,s.jsxs)("div",{className:"grid lg:grid-cols-2 gap-6",children:[(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Grid Visualization (Detected Indices)"})}),(0,s.jsxs)(k,{children:[(0,s.jsxs)("div",{className:"relative border rounded inline-block",children:[(0,s.jsx)("img",{src:"data:image/png;base64,".concat(K.grid_png),alt:"Grid visualization",style:{maxWidth:"512px",width:"100%"}}),(0,s.jsxs)("div",{className:"absolute top-2 right-2 bg-black bg-opacity-70 text-white px-2 py-1 rounded text-xs",children:["Calibration Model (",Y," images found)"]})]}),G.length>0&&(0,s.jsxs)("div",{className:"text-xs text-gray-600 mt-2",children:["Grid points detected: ",G.length]})]})]}),(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Camera Metrics"})}),(0,s.jsx)(k,{children:(0,s.jsxs)("div",{className:"text-xs space-y-2",children:[K&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Reprojection Error (overall):"})," ",null===(l=K.reprojection_error)||void 0===l?void 0:l.toFixed(3)," px"]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Mean |x| Error:"})," ",null===(n=K.reprojection_error_x_mean)||void 0===n?void 0:n.toFixed(3)," px"]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Mean |y| Error:"})," ",null===(i=K.reprojection_error_y_mean)||void 0===i?void 0:i.toFixed(3)," px"]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Pattern Size:"})," ",null===(o=K.pattern_size)||void 0===o?void 0:o.join(" x ")]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Dot Spacing:"})," ",K.dot_spacing_mm," mm"]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Estimated Pixels per mm:"})," ",K.pixels_per_mm?K.pixels_per_mm.toFixed(3):"N/A"]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Image Name:"})," ",K.original_filename]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Timestamp:"})," ",K.timestamp]})]}),H&&(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)("div",{children:(0,s.jsx)("b",{children:"Camera Matrix:"})}),H.camera_matrix&&H.camera_matrix.map((e,t)=>(0,s.jsxs)("div",{children:["[",e.map(e=>e.toFixed(3)).join(", "),"]"]},t)),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Focal Length:"})," fx=",null===(d=H.focal_length)||void 0===d?void 0:null===(c=d[0])||void 0===c?void 0:c.toFixed(1),", fy=",null===(m=H.focal_length)||void 0===m?void 0:null===(u=m[1])||void 0===u?void 0:u.toFixed(1)]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Principal Point:"})," cx=",null===(x=H.principal_point)||void 0===x?void 0:null===(h=x[0])||void 0===h?void 0:h.toFixed(1),", cy=",null===(p=H.principal_point)||void 0===p?void 0:null===(g=p[1])||void 0===g?void 0:g.toFixed(1)]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Distortion Coeffs:"})," [",null===(f=H.dist_coeffs)||void 0===f?void 0:f.map(e=>e.toFixed(4)).join(", "),"]"]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("b",{children:"Reprojection Error:"})," ",null===(v=H.reprojection_error)||void 0===v?void 0:v.toFixed(3)," px"]})]})]})})]})]})]})},eL=e=>{if(!e)return"";let t=e.replace(/\\/g,"/").split("/");return t.length>=2?t.slice(-2).join("/"):t.filter(Boolean).pop()||e},eB=e=>{var t,a;let{config:l,updateConfig:n,cameraOptions:i,sourcePaths:o,imageCount:c=1e3}=e,{sourcePathIdx:d,cameraPair:u,filePattern:m,patternCols:h,patternRows:x,dotSpacingMm:g,enhanceDots:p,asymmetric:f,dt:v,jobId:j,calibrationResults:b,vectorJob:y,isLoading:S,gridImages:C,currentGridIndex:P,vectorPollingActive:M,vectorJobId:T,showCompletionMessage:I,setSourcePathIdx:R,setCameraPair:A,setFilePattern:z,setPatternCols:O,setPatternRows:B,setDotSpacingMm:U,setEnhanceDots:Y,setAsymmetric:G,setDt:J,setJobId:X,setCalibrationResults:H,setVectorJob:K,setIsLoading:$,setGridImages:q,setCurrentGridIndex:Q,setVectorPollingActive:ee,setVectorJobId:et,setShowCompletionMessage:ea,calibrationStatus:es,calibrationDetails:er,vectorStatus:el,vectorDetails:en,camera1:ei,camera2:eo,startStereoCalibration:ec,calibrateVectors:ed}=function(){var e,t,a,s,l,n,i,o,c;let d=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},u=arguments.length>1?arguments[1]:void 0,m=arguments.length>2?arguments[2]:void 0,h=arguments.length>3?arguments[3]:void 0,x=arguments.length>4&&void 0!==arguments[4]?arguments[4]:1e3,[g,p]=(0,r.useState)(null!==(e=d.source_path_idx)&&void 0!==e?e:0),[f,v]=(0,r.useState)(null!==(t=d.camera_pair)&&void 0!==t?t:[1,2]),[j,b]=(0,r.useState)(null!==(a=d.file_pattern)&&void 0!==a?a:"planar_calibration_plate_*.tif"),[y,N]=(0,r.useState)(String(null!==(s=d.pattern_cols)&&void 0!==s?s:10)),[w,_]=(0,r.useState)(String(null!==(l=d.pattern_rows)&&void 0!==l?l:10)),[S,k]=(0,r.useState)(String(null!==(n=d.dot_spacing_mm)&&void 0!==n?n:28.89)),[C,P]=(0,r.useState)(null===(i=d.enhance_dots)||void 0===i||i),[M,E]=(0,r.useState)(null!==(o=d.asymmetric)&&void 0!==o&&o),[F,T]=(0,r.useState)(String(null!==(c=d.dt)&&void 0!==c?c:1)),[I,R]=(0,r.useState)(null),[A,z]=(0,r.useState)(null),[O,D]=(0,r.useState)(null),[V,L]=(0,r.useState)(!1),[B,U]=(0,r.useState)(null),[W,Z]=(0,r.useState)(1),[Y,G]=(0,r.useState)(!1),[J,X]=(0,r.useState)(null),[H,K]=(0,r.useState)(!1),$=(0,r.useRef)(null),q=(0,r.useRef)(null);(0,r.useEffect)(()=>{var e,t,a,s,r,l,n,i,o;p(null!==(e=d.source_path_idx)&&void 0!==e?e:0),v(null!==(t=d.camera_pair)&&void 0!==t?t:[1,2]),b(null!==(a=d.file_pattern)&&void 0!==a?a:"planar_calibration_plate_*.tif"),N(String(null!==(s=d.pattern_cols)&&void 0!==s?s:10)),_(String(null!==(r=d.pattern_rows)&&void 0!==r?r:10)),k(String(null!==(l=d.dot_spacing_mm)&&void 0!==l?l:28.89)),P(null===(n=d.enhance_dots)||void 0===n||n),E(null!==(i=d.asymmetric)&&void 0!==i&&i),T(String(null!==(o=d.dt)&&void 0!==o?o:1))},[d]),(0,r.useEffect)(()=>{let e={source_path_idx:g,camera_pair:f,file_pattern:j,pattern_cols:Number(y),pattern_rows:Number(w),dot_spacing_mm:Number(S),enhance_dots:C,asymmetric:M,dt:Number(F)};return q.current&&function e(t,a){if(t===a)return!0;if(typeof t!=typeof a||"object"!=typeof t||null===t||null===a)return!1;if(Array.isArray(t)&&Array.isArray(a)){if(t.length!==a.length)return!1;for(let s=0;s<t.length;s++)if(!e(t[s],a[s]))return!1;return!0}let s=Object.keys(t),r=Object.keys(a);if(s.length!==r.length)return!1;for(let r of s)if(!e(t[r],a[r]))return!1;return!0}(q.current,e)||(q.current=e,$.current&&clearTimeout($.current),$.current=setTimeout(async()=>{console.log("Updating stereo config after debounce");try{var t,a;let s=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({calibration:{stereo:e}})}),r=await s.json();if(!s.ok)throw Error(r.error||"Failed to save stereo config");(null===(a=r.updated)||void 0===a?void 0:null===(t=a.calibration)||void 0===t?void 0:t.stereo)&&u(["calibration","stereo"],r.updated.calibration.stereo)}catch(e){console.error("Failed to save stereo config:",e)}},500)),()=>{$.current&&clearTimeout($.current)}},[g,f,j,y,w,S,C,M,F,u]),(0,r.useEffect)(()=>{!(m.length>=2)||f[0]!==f[1]&&m.includes(f[0])&&m.includes(f[1])||v([m[0],m[1]])},[m,f]);let{status:Q,details:ee}=(e=>{let[t,a]=(0,r.useState)("not_started"),[s,l]=(0,r.useState)(null),n=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!e){a("not_started"),l(null),n.current&&(clearInterval(n.current),n.current=null);return}let t=!0,s=async()=>{try{let r=await fetch("/backend/stereo/calibration/status/".concat(e)),i=await r.json();t&&(a(i.status||"not_started"),l(i),"completed"===i.status||"failed"===i.status||i.progress>=100?n.current&&(clearInterval(n.current),n.current=null):"running"!==i.status&&"starting"!==i.status||n.current||(n.current=setInterval(s,500)))}catch(e){t&&(a("not_started"),n.current&&(clearInterval(n.current),n.current=null))}};return s(),()=>{t=!1,n.current&&(clearInterval(n.current),n.current=null)}},[e]),{status:t,details:s}})(I),{status:et,details:ea}=(e=>{let[t,a]=(0,r.useState)("not_started"),[s,l]=(0,r.useState)(null),n=(0,r.useRef)(null);return(0,r.useEffect)(()=>{if(!e){a("not_started"),l(null),n.current&&(clearInterval(n.current),n.current=null);return}let t=!0,s=async()=>{try{let r=await fetch("/backend/stereo/calibration/vectors/status/".concat(e)),i=await r.json();t&&(a(i.status||"not_started"),l(i),"completed"===i.status||"failed"===i.status||i.progress>=100?n.current&&(clearInterval(n.current),n.current=null):"running"!==i.status&&"starting"!==i.status||n.current||(n.current=setInterval(s,500)))}catch(e){t&&(a("not_started"),n.current&&(clearInterval(n.current),n.current=null))}};return s(),()=>{t=!1,n.current&&(clearInterval(n.current),n.current=null)}},[e]),{status:t,details:s}})(J),es=async()=>{L(!0);try{let e=await fetch("/backend/stereo/calibration/start",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({source_path_idx:g,camera_pair:f,file_pattern:j,pattern_cols:Number(y),pattern_rows:Number(w),dot_spacing_mm:Number(S),enhance_dots:C,asymmetric:M,dt:Number(F)})}),t=await e.json();if(e.ok)R(t.job_id),console.log("Stereo calibration started:",t.job_id);else throw Error(t.error||"Failed to start stereo calibration")}catch(e){console.error("Error starting stereo calibration:",e.message)}finally{L(!1)}},er=async()=>{G(!0);try{let e=await fetch("/backend/stereo/calibration/vectors/start",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({source_path_idx:g,camera_pair:f,dt:Number(F),image_count:x})}),t=await e.json();if(e.ok)X(t.job_id),console.log("Stereo vector calibration started:",t.job_id);else throw Error(t.error||"Failed to start stereo vector calibration")}catch(e){console.error("Error starting stereo vector calibration:",e.message),G(!1)}};return{sourcePathIdx:g,cameraPair:f,filePattern:j,patternCols:y,patternRows:w,dotSpacingMm:S,enhanceDots:C,asymmetric:M,dt:F,jobId:I,calibrationResults:A,vectorJob:O,isLoading:V,gridImages:B,currentGridIndex:W,vectorPollingActive:Y,vectorJobId:J,showCompletionMessage:H,setSourcePathIdx:p,setCameraPair:v,setFilePattern:b,setPatternCols:N,setPatternRows:_,setDotSpacingMm:k,setEnhanceDots:P,setAsymmetric:E,setDt:T,setJobId:R,setCalibrationResults:z,setVectorJob:D,setIsLoading:L,setGridImages:U,setCurrentGridIndex:Z,setVectorPollingActive:G,setVectorJobId:X,setShowCompletionMessage:K,calibrationStatus:Q,calibrationDetails:ee,vectorStatus:et,vectorDetails:ea,cameraOptions:m,sourcePaths:h,camera1:f[0],camera2:f[1],startStereoCalibration:es,calibrateVectors:er}}((null===(t=l.calibration)||void 0===t?void 0:t.stereo)||{},n,i,o,c),eu=async()=>{try{var e;let t=await fetch("/backend/update_config",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({calibration:{active:"stereo"}})}),a=await t.json();if(!t.ok)throw Error(a.error||"Failed to set active method");(null===(e=a.updated)||void 0===e?void 0:e.calibration)&&n(["calibration"],{...l.calibration,...a.updated.calibration})}catch(e){console.error("Failed to set active calibration method:",e)}},em=(null===(a=l.calibration)||void 0===a?void 0:a.active)==="stereo";return(0,s.jsxs)("div",{className:"space-y-6",children:[T&&en&&(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Stereo Vector Calibration Status"})}),(0,s.jsxs)(k,{className:"space-y-2",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 text-sm",children:["Status: ",(0,s.jsx)("span",{className:"font-medium",children:el})]}),("running"===el||"starting"===el)&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-green-600 text-sm",children:[(0,s.jsx)("span",{className:"animate-spin inline-block w-4 h-4 border-2 border-green-600 border-t-transparent rounded-full"}),"Stereo vector calibration is running..."]}),(0,s.jsx)("div",{className:"w-full bg-gray-200 h-2 rounded overflow-hidden",children:(0,s.jsx)("div",{className:"h-2 bg-green-600",style:{width:"".concat(en.progress||0,"%")}})}),(0,s.jsxs)("div",{className:"text-xs text-muted-foreground",children:["Progress: ",en.progress||0,"% ",void 0!==en.processed_frames&&void 0!==en.total_frames&&"(Frames: ".concat(en.processed_frames,"/").concat(en.total_frames,")")]}),"completed"===el&&(0,s.jsx)("div",{className:"mt-2 text-xs text-green-600",children:"Stereo vector calibration completed successfully!"}),"failed"===el&&en.error&&(0,s.jsxs)("div",{className:"mt-2 text-xs text-red-600",children:["Error: ",en.error]})]})]}),(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Stereo Calibration"})}),(0,s.jsxs)(k,{className:"space-y-4",children:[(0,s.jsxs)("div",{className:"grid md:grid-cols-2 lg:grid-cols-3 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Source Path"}),(0,s.jsxs)(D,{value:String(d),onValueChange:e=>R(Number(e)),children:[(0,s.jsx)(L,{id:"srcpath",children:(0,s.jsx)(V,{placeholder:"Pick source path"})}),(0,s.jsx)(W,{children:o.map((e,t)=>(0,s.jsx)(Z,{value:String(t),children:eL(e)},t))})]}),(0,s.jsx)("p",{className:"text-xs text-muted-foreground mt-1",children:"Configured in Settings → Directories."})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Camera Pair"}),(0,s.jsxs)("div",{className:"flex gap-2",children:[(0,s.jsxs)(D,{value:String(ei),onValueChange:e=>A([Number(e),eo]),children:[(0,s.jsx)(L,{className:"w-20",children:(0,s.jsx)(V,{})}),(0,s.jsx)(W,{children:i.filter(e=>e!==eo).map(e=>(0,s.jsx)(Z,{value:String(e),children:e},e))})]}),(0,s.jsxs)(D,{value:String(eo),onValueChange:e=>A([ei,Number(e)]),children:[(0,s.jsx)(L,{className:"w-20",children:(0,s.jsx)(V,{})}),(0,s.jsx)(W,{children:i.filter(e=>e!==ei).map(e=>(0,s.jsx)(Z,{value:String(e),children:e},e))})]})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Δt (seconds)"}),(0,s.jsx)(F,{type:"number",value:v,onChange:e=>J(e.target.value),step:"any",min:"0",placeholder:"1.0"})]})]}),(0,s.jsxs)("div",{className:"grid md:grid-cols-2 lg:grid-cols-3 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"File Pattern"}),(0,s.jsx)(F,{value:m,onChange:e=>z(e.target.value),placeholder:"planar_calibration_plate_*.tif"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Pattern Cols"}),(0,s.jsx)(F,{type:"number",value:h,onChange:e=>O(e.target.value),min:"1",step:"1"})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Pattern Rows"}),(0,s.jsx)(F,{type:"number",value:x,onChange:e=>B(e.target.value),min:"1",step:"1"})]})]}),(0,s.jsxs)("div",{className:"grid md:grid-cols-2 lg:grid-cols-3 gap-4",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("label",{className:"text-sm font-medium",children:"Dot Spacing (mm)"}),(0,s.jsx)(F,{type:"number",value:g,onChange:e=>U(e.target.value),step:"any",min:"0"})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("input",{type:"checkbox",checked:p,onChange:e=>Y(e.target.checked),className:"w-4 h-4"}),(0,s.jsx)("label",{className:"text-sm font-medium",children:"Enhance Dots"})]}),(0,s.jsxs)("div",{className:"flex items-center gap-2",children:[(0,s.jsx)("input",{type:"checkbox",checked:f,onChange:e=>G(e.target.checked),className:"w-4 h-4"}),(0,s.jsx)("label",{className:"text-sm font-medium",children:"Asymmetric"})]})]}),(0,s.jsxs)("div",{className:"mb-2",children:["running"===es&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-blue-600 text-sm",children:[(0,s.jsx)("span",{className:"animate-spin inline-block w-4 h-4 border-2 border-blue-600 border-t-transparent rounded-full"}),"Stereo calibration is running..."]}),"completed"===es&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-green-600 text-sm",children:[(0,s.jsx)("span",{className:"inline-block w-3 h-3 bg-green-600 rounded-full"}),"Stereo calibration completed!"]}),"error"===es&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-red-600 text-sm",children:[(0,s.jsx)("span",{className:"inline-block w-3 h-3 bg-red-600 rounded-full"}),"Stereo calibration error!"]}),"not_started"===es&&(0,s.jsxs)("div",{className:"flex items-center gap-2 text-gray-400 text-sm",children:[(0,s.jsx)("span",{className:"inline-block w-3 h-3 bg-gray-400 rounded-full"}),"Stereo calibration not started."]})]}),(0,s.jsxs)("div",{className:"flex gap-4 items-center",children:[(0,s.jsx)(E,{onClick:ec,disabled:S||"running"===es,className:"bg-blue-600 hover:bg-blue-700 text-white px-6 py-3",children:S?"Starting...":"Start Stereo Calibration"}),(0,s.jsx)(E,{onClick:ed,disabled:"running"===el||"starting"===el,className:"bg-green-600 hover:bg-green-700 text-white px-6 py-3",children:"running"===el||"starting"===el?"Calibrating...":"Calibrate Vectors"}),(0,s.jsx)(E,{onClick:eu,disabled:em,className:em?"bg-green-600 hover:bg-green-600 text-white px-6 py-3":"",variant:em?"default":"outline",children:em?"Active":"Set as Active Method"})]}),(0,s.jsxs)("div",{className:"text-xs text-gray-500 mt-2",children:[(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Stereo Calibration:"})," Process calibration images for both cameras to create stereo camera models."]}),(0,s.jsxs)("p",{children:[(0,s.jsx)("strong",{children:"Calibrate Vectors:"})," Use stereo camera models to calibrate PIV vectors."]}),(0,s.jsx)("p",{children:"Updates the calibration.stereo block in config.yaml."})]})]})]})]})},eU=e=>{var t;let{config:a,updateConfig:l}=e,{activeMethod:n,setActiveMethod:i,getCameraOptions:o,sourcePaths:c}=function(){var e;let t=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{images:{},paths:{}},a=arguments.length>1?arguments[1]:void 0,[s,l]=(0,r.useState)(t.calibration||{}),n=(0,r.useRef)(null);(0,r.useEffect)(()=>{l(t.calibration||{})},[t.calibration]);let i=(0,r.useCallback)((e,t)=>{n.current&&clearTimeout(n.current),n.current=window.setTimeout(()=>{a(e,t)},500)},[a]),o=(0,r.useCallback)(e=>{i(["calibration","active"],e)},[i]),c=(0,r.useCallback)((e,t)=>{i(["calibration",e],t)},[i]),d=(0,r.useCallback)(()=>{var e,a;let s=null==t?void 0:null===(e=t.paths)||void 0===e?void 0:e.camera_numbers;if(Array.isArray(s)&&s.length>0)return s;let r=null==t?void 0:null===(a=t.paths)||void 0===a?void 0:a.camera_count;return"number"==typeof r&&r>0?Array.from({length:r},(e,t)=>t+1):[1]},[t]),u=(null==t?void 0:null===(e=t.paths)||void 0===e?void 0:e.source_paths)||[];return{calibrationConfig:s,activeMethod:s.active||"pinhole",setActiveMethod:o,updateCalibrationConfig:c,getCameraOptions:d,sourcePaths:u,config:t,updateConfig:i}}(a,l),d=o(),u=(null==a?void 0:null===(t=a.images)||void 0===t?void 0:t.num_images)||1e3,[m,h]=(0,r.useState)(n);(0,r.useEffect)(()=>{h(n)},[n]);let x=[{id:"scale_factor",label:"Scale Factor",component:eO},{id:"pinhole",label:"Pinhole",component:eV},{id:"stereo",label:"Stereo",component:eB}];return(0,s.jsx)("div",{className:"space-y-6",children:(0,s.jsxs)(N,{children:[(0,s.jsx)(w,{children:(0,s.jsx)(_,{children:"Calibration Setup"})}),(0,s.jsxs)(k,{children:[(0,s.jsx)("p",{className:"text-sm text-muted-foreground mb-4",children:"Configure and run calibration procedures for your PIV system. Each calibration method serves a different purpose:"}),(0,s.jsxs)("ul",{className:"text-sm text-muted-foreground space-y-1 mb-6",children:[(0,s.jsxs)("li",{children:[(0,s.jsx)("strong",{children:"Scale Factor:"})," Calibrate physical dimensions and coordinate system"]}),(0,s.jsxs)("li",{children:[(0,s.jsx)("strong",{children:"Pinhole:"})," Calibrate individual camera intrinsic parameters"]}),(0,s.jsxs)("li",{children:[(0,s.jsx)("strong",{children:"Stereo:"})," Calibrate camera pairs for 3D reconstruction"]})]}),(0,s.jsxs)(v,{value:m,onValueChange:h,children:[(0,s.jsx)(j,{className:"grid w-full grid-cols-3",children:x.map(e=>(0,s.jsx)(b,{value:e.id,children:e.label},e.id))}),x.map(e=>{let t=e.component;return(0,s.jsx)(y,{value:e.id,className:"mt-6",children:(0,s.jsx)(t,{config:a,updateConfig:l,cameraOptions:d,sourcePaths:c,imageCount:u})},e.id)})]})]})]})})},eW={paths:{base_dir:[],source:[]},images:{}};function eZ(){let[e,t]=(0,r.useState)(!1),[a,l]=(0,r.useState)(!1),[n,i]=(0,r.useState)(eW),[o,c]=(0,r.useState)(null);(0,r.useEffect)(()=>{try{localStorage.removeItem("pivtools_seen_hero"),console.log("Hero state reset for testing")}catch(e){console.error("Failed to reset hero state:",e)}try{let e=localStorage.getItem("pivtools_seen_hero");t("true"===e),console.log("Hero visibility check:",{v:e,seenHero:"true"===e,mounted:!0})}catch(e){console.error("Error accessing localStorage:",e),t(!1)}l(!0)},[]),(0,r.useEffect)(()=>{let e=!1;return async function(){try{let n=await fetch("/backend/config");if(!n.ok){e||c("Cannot connect to backend server. Please ensure the server is running.");return}let o=await n.json();if(!e){var t,a,s,r,l;let e={...o,paths:{base_paths:(null===(t=o.paths)||void 0===t?void 0:t.base_paths)||[],source_paths:(null===(a=o.paths)||void 0===a?void 0:a.source_paths)||[],camera_numbers:(null===(s=o.paths)||void 0===s?void 0:s.camera_numbers)||[],camera_count:null===(r=o.paths)||void 0===r?void 0:r.camera_count},images:o.images||{},batches:o.batches||{},processing:o.processing||{},post_processing:o.post_processing||[],plots:o.plots||{},videos:o.videos||[],statistics_extraction:null!==(l=o.statistics_extraction)&&void 0!==l?l:null,instantaneous_piv:o.instantaneous_piv||{},ensemble_piv:o.ensemble_piv||{},calibration_format:o.calibration_format||{},calibration:o.calibration||{},filters:o.filters||[]};i(e),c(null)}}catch(t){e||c("Cannot connect to backend server. Please ensure the server is running.")}}(),()=>{e=!0}},[]);let[u,m]=(0,r.useState)("environment"),h=(0,r.useCallback)((e,t)=>{Array.isArray(e)&&0!==e.length&&i(a=>{let s=JSON.parse(JSON.stringify(a||{})),r=s;for(let t=0;t<e.length-1;t++){let a=e[t];(void 0===r[a]||null===r[a]||"object"!=typeof r[a])&&(r[a]={}),r=r[a]}return r[e[e.length-1]]=t,s})},[]);return console.log("Render state:",{mounted:a,seenHero:e}),(0,s.jsxs)("main",{className:"min-h-screen bg-gray-50",children:[a&&e&&(0,s.jsx)(d,{}),a?e?o?(0,s.jsx)("div",{className:"max-w-2xl mx-auto px-4 pt-24 pb-16",children:(0,s.jsxs)("div",{className:"bg-red-100 border border-red-400 text-red-700 px-4 py-6 rounded-xl shadow-lg",children:[(0,s.jsx)("h2",{className:"text-2xl font-bold mb-2",children:"Backend Server Not Detected"}),(0,s.jsx)("p",{children:o}),(0,s.jsx)("p",{className:"mt-2 text-gray-700",children:"The frontend cannot run without the backend server. Please start the backend and reload this page."})]})}):(0,s.jsx)("div",{className:"max-w-7xl mx-auto px-4 pt-24 pb-16",children:(0,s.jsxs)("div",{className:"bg-white rounded-xl shadow-lg p-6 mb-6",children:[(0,s.jsx)("h1",{className:"text-3xl font-bold text-soton-blue mb-2",children:"PIVTOOLS Configuration"}),(0,s.jsx)("p",{className:"text-gray-600 mb-6",children:"Configure your PIV processing pipeline with this intuitive interface. Changes are applied automatically."}),(0,s.jsxs)(v,{value:u,onValueChange:m,className:"w-full",children:[(0,s.jsxs)(j,{className:"grid grid-cols-6 mb-6",children:[(0,s.jsx)(b,{value:"setup",className:"data-[state=active]:bg-soton-blue data-[state=active]:text-white",children:"Setup"}),(0,s.jsx)(b,{value:"masking",className:"data-[state=active]:bg-soton-blue data-[state=active]:text-white",children:"Masking"}),(0,s.jsx)(b,{value:"instantaneous",className:"data-[state=active]:bg-soton-blue data-[state=active]:text-white",children:"PIV"}),(0,s.jsx)(b,{value:"calibration",className:"data-[state=active]:bg-soton-blue data-[state=active]:text-white",children:"Calibration"}),(0,s.jsx)(b,{value:"results",className:"data-[state=active]:bg-soton-blue data-[state=active]:text-white",children:"Results"}),(0,s.jsx)(b,{value:"video",className:"data-[state=active]:bg-soton-blue data-[state=active]:text-white",children:"Video"})]}),(0,s.jsx)(y,{value:"setup",children:(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsx)(eM,{config:n,updateConfig:h}),(0,s.jsx)("div",{children:(0,s.jsx)(eN,{config:n,updateConfig:h})})]})}),(0,s.jsx)(y,{value:"masking",children:(0,s.jsx)(eA,{config:n,updateConfig:h})}),(0,s.jsx)(y,{value:"instantaneous",children:(0,s.jsxs)("div",{className:"space-y-6",children:[(0,s.jsx)("div",{children:(0,s.jsx)(ev,{config:n,updateConfig:h})}),(0,s.jsx)("div",{className:"mt-4",children:(0,s.jsxs)("div",{className:"bg-white rounded-xl shadow p-6",children:[(0,s.jsxs)("div",{className:"flex items-center gap-2 mb-2",children:[(0,s.jsx)("span",{className:"inline-block",children:(0,s.jsxs)("svg",{xmlns:"http://www.w3.org/2000/svg",className:"h-5 w-5 text-soton-blue",fill:"none",viewBox:"0 0 24 24",stroke:"currentColor",children:[(0,s.jsx)("rect",{x:"3",y:"3",width:"7",height:"7",strokeWidth:"2"}),(0,s.jsx)("rect",{x:"14",y:"3",width:"7",height:"7",strokeWidth:"2"}),(0,s.jsx)("rect",{x:"3",y:"14",width:"7",height:"7",strokeWidth:"2"}),(0,s.jsx)("rect",{x:"14",y:"14",width:"7",height:"7",strokeWidth:"2"})]})}),(0,s.jsx)("span",{className:"text-xl font-semibold",children:"Window Size Selection Guidelines"})]}),(0,s.jsx)("div",{className:"text-gray-600 mb-4",children:"Best practices for configuring correlation windows"}),(0,s.jsxs)("div",{className:"grid grid-cols-1 md:grid-cols-2 gap-6",children:[(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"text-lg font-medium mb-2",children:"Window Size Recommendations"}),(0,s.jsxs)("ul",{className:"space-y-1 text-sm list-disc pl-5",children:[(0,s.jsx)("li",{children:"Start with larger windows (128x128, 64x64) and progressively refine"}),(0,s.jsx)("li",{children:"For final pass, aim for 16x16 or 32x32 depending on particle density"}),(0,s.jsx)("li",{children:"Window size should contain at least 5-10 particles for good correlation"}),(0,s.jsx)("li",{children:"Keep window sizes as powers of 2 for optimal FFT performance"})]})]}),(0,s.jsxs)("div",{children:[(0,s.jsx)("h3",{className:"text-lg font-medium mb-2",children:"Overlap Settings"}),(0,s.jsxs)("ul",{className:"space-y-1 text-sm list-disc pl-5",children:[(0,s.jsx)("li",{children:"50% overlap is standard and provides good vector density"}),(0,s.jsx)("li",{children:"Higher overlap (75%) increases spatial resolution but not information content"}),(0,s.jsx)("li",{children:"Lower overlap (25%) reduces computation time but may miss flow features"}),(0,s.jsx)("li",{children:"Consistent overlap between passes maintains stable refinement"})]})]})]})]})})]})}),(0,s.jsx)(y,{value:"calibration",children:(0,s.jsx)(eU,{config:n,updateConfig:h})}),(0,s.jsx)(y,{value:"pod",children:(0,s.jsx)(e_,{config:n,updateConfig:h})}),(0,s.jsx)(y,{value:"results",children:(0,s.jsx)(eT,{config:n})}),(0,s.jsx)(y,{value:"video",children:(0,s.jsx)(eI,{config:n})})]})]})}):(0,s.jsx)(g,{onGetStarted:()=>{try{localStorage.setItem("pivtools_seen_hero","true"),console.log("Hero marked as seen")}catch(e){console.error("Error setting localStorage:",e)}t(!0),m("setup")}}):(0,s.jsx)("div",{className:"max-w-7xl mx-auto px-4 pt-24 pb-16"})]})}},8752:function(e,t,a){"use strict";a.d(t,{pm:function(){return m}});var s=a(2265);let r=0,l=new Map,n=e=>{if(l.has(e))return;let t=setTimeout(()=>{l.delete(e),d({type:"REMOVE_TOAST",toastId:e})},1e3);l.set(e,t)},i=(e,t)=>{switch(t.type){case"ADD_TOAST":return{...e,toasts:[t.toast,...e.toasts].slice(0,5)};case"UPDATE_TOAST":return{...e,toasts:e.toasts.map(e=>e.id===t.toast.id?{...e,...t.toast}:e)};case"DISMISS_TOAST":{let{toastId:a}=t;return a?n(a):e.toasts.forEach(e=>{n(e.id)}),{...e,toasts:e.toasts.map(e=>e.id===a||void 0===a?{...e,open:!1}:e)}}case"REMOVE_TOAST":if(void 0===t.toastId)return{...e,toasts:[]};return{...e,toasts:e.toasts.filter(e=>e.id!==t.toastId)}}},o=[],c={toasts:[]};function d(e){c=i(c,e),o.forEach(e=>{e(c)})}function u(e){let{...t}=e,a=(r=(r+1)%Number.MAX_SAFE_INTEGER).toString(),s=()=>d({type:"DISMISS_TOAST",toastId:a});return d({type:"ADD_TOAST",toast:{...t,id:a,open:!0,onOpenChange:e=>{e||s()}}}),{id:a,dismiss:s,update:e=>d({type:"UPDATE_TOAST",toast:{...e,id:a}})}}function m(){let[e,t]=(0,s.useState)(c);return(0,s.useEffect)(()=>(o.push(t),()=>{let e=o.indexOf(t);e>-1&&o.splice(e,1)}),[e]),{...e,toast:u,dismiss:e=>d({type:"DISMISS_TOAST",toastId:e})}}},3448:function(e,t,a){"use strict";a.d(t,{E:function(){return n},cn:function(){return l}});var s=a(1994),r=a(3335);function l(){for(var e=arguments.length,t=Array(e),a=0;a<e;a++)t[a]=arguments[a];return(0,r.m6)((0,s.W)(t))}function n(e){if(!e)return"";let t=e.replace(/\\/g,"/").replace(/\/+$/g,""),a=t.split("/").filter(Boolean);return a.length?a[a.length-1]:t}}},function(e){e.O(0,[869,484,971,117,744],function(){return e(e.s=8893)}),_N_E=e.O()}]);