David Ko commited on
Commit
ea52b48
Β·
1 Parent(s): a757b4d

style(frontend): responsive preview container using viewport height so entire image fits; rebuild and sync

Browse files
frontend/src/components/ImageUploader.js CHANGED
@@ -56,10 +56,10 @@ const useStyles = makeStyles((theme) => ({
56
  imageContainer: {
57
  position: 'relative',
58
  width: '100%',
59
- // Use a fixed, responsive height so the preview image scales correctly
60
- height: 420,
61
  [theme.breakpoints.down('sm')]: {
62
- height: 320,
63
  },
64
  display: 'flex',
65
  justifyContent: 'center',
 
56
  imageContainer: {
57
  position: 'relative',
58
  width: '100%',
59
+ // Use viewport-based height so any aspect ratio fits inside
60
+ height: '60vh',
61
  [theme.breakpoints.down('sm')]: {
62
+ height: '45vh',
63
  },
64
  display: 'flex',
65
  justifyContent: 'center',
static/asset-manifest.json CHANGED
@@ -1,8 +1,8 @@
1
  {
2
  "files": {
3
  "main.css": "/static/css/main.3b4eede1.chunk.css",
4
- "main.js": "/static/js/main.9549fb04.chunk.js",
5
- "main.js.map": "/static/js/main.9549fb04.chunk.js.map",
6
  "runtime-main.js": "/static/js/runtime-main.25710301.js",
7
  "runtime-main.js.map": "/static/js/runtime-main.25710301.js.map",
8
  "static/js/2.9b5b80e8.chunk.js": "/static/js/2.9b5b80e8.chunk.js",
@@ -10,7 +10,7 @@
10
  "static/js/3.9013e23f.chunk.js": "/static/js/3.9013e23f.chunk.js",
11
  "static/js/3.9013e23f.chunk.js.map": "/static/js/3.9013e23f.chunk.js.map",
12
  "index.html": "/index.html",
13
- "precache-manifest.4cdbfb3ad91c466419484ccc9bd70e38.js": "/precache-manifest.4cdbfb3ad91c466419484ccc9bd70e38.js",
14
  "service-worker.js": "/service-worker.js",
15
  "static/css/main.3b4eede1.chunk.css.map": "/static/css/main.3b4eede1.chunk.css.map",
16
  "static/js/2.9b5b80e8.chunk.js.LICENSE.txt": "/static/js/2.9b5b80e8.chunk.js.LICENSE.txt"
@@ -19,6 +19,6 @@
19
  "static/js/runtime-main.25710301.js",
20
  "static/js/2.9b5b80e8.chunk.js",
21
  "static/css/main.3b4eede1.chunk.css",
22
- "static/js/main.9549fb04.chunk.js"
23
  ]
24
  }
 
1
  {
2
  "files": {
3
  "main.css": "/static/css/main.3b4eede1.chunk.css",
4
+ "main.js": "/static/js/main.13ed4cd9.chunk.js",
5
+ "main.js.map": "/static/js/main.13ed4cd9.chunk.js.map",
6
  "runtime-main.js": "/static/js/runtime-main.25710301.js",
7
  "runtime-main.js.map": "/static/js/runtime-main.25710301.js.map",
8
  "static/js/2.9b5b80e8.chunk.js": "/static/js/2.9b5b80e8.chunk.js",
 
10
  "static/js/3.9013e23f.chunk.js": "/static/js/3.9013e23f.chunk.js",
11
  "static/js/3.9013e23f.chunk.js.map": "/static/js/3.9013e23f.chunk.js.map",
12
  "index.html": "/index.html",
13
+ "precache-manifest.7ffa256e4ee99cb22c2ef5bb2f02bd1a.js": "/precache-manifest.7ffa256e4ee99cb22c2ef5bb2f02bd1a.js",
14
  "service-worker.js": "/service-worker.js",
15
  "static/css/main.3b4eede1.chunk.css.map": "/static/css/main.3b4eede1.chunk.css.map",
16
  "static/js/2.9b5b80e8.chunk.js.LICENSE.txt": "/static/js/2.9b5b80e8.chunk.js.LICENSE.txt"
 
19
  "static/js/runtime-main.25710301.js",
20
  "static/js/2.9b5b80e8.chunk.js",
21
  "static/css/main.3b4eede1.chunk.css",
22
+ "static/js/main.13ed4cd9.chunk.js"
23
  ]
24
  }
static/index.html CHANGED
@@ -1 +1 @@
1
- <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Multi-Model Object Detection Demo"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Vision Web App</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><link href="/static/css/main.3b4eede1.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,i,a=r[0],c=r[1],l=r[2],p=0,s=[];p<a.length;p++)i=a[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"9013e23f"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this["webpackJsonpvision-web-app"]=this["webpackJsonpvision-web-app"]||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var l=0;l<a.length;l++)r(a[l]);var f=c;t()}([])</script><script src="/static/js/2.9b5b80e8.chunk.js"></script><script src="/static/js/main.9549fb04.chunk.js"></script></body></html>
 
1
+ <!doctype html><html lang="en"><head><meta charset="utf-8"/><link rel="icon" href="/favicon.ico"/><meta name="viewport" content="width=device-width,initial-scale=1"/><meta name="theme-color" content="#000000"/><meta name="description" content="Multi-Model Object Detection Demo"/><link rel="apple-touch-icon" href="/logo192.png"/><link rel="manifest" href="/manifest.json"/><title>Vision Web App</title><link rel="stylesheet" href="https://fonts.googleapis.com/css?family=Roboto:300,400,500,700&display=swap"/><link href="/static/css/main.3b4eede1.chunk.css" rel="stylesheet"></head><body><noscript>You need to enable JavaScript to run this app.</noscript><div id="root"></div><script>!function(e){function r(r){for(var n,i,a=r[0],c=r[1],l=r[2],p=0,s=[];p<a.length;p++)i=a[p],Object.prototype.hasOwnProperty.call(o,i)&&o[i]&&s.push(o[i][0]),o[i]=0;for(n in c)Object.prototype.hasOwnProperty.call(c,n)&&(e[n]=c[n]);for(f&&f(r);s.length;)s.shift()();return u.push.apply(u,l||[]),t()}function t(){for(var e,r=0;r<u.length;r++){for(var t=u[r],n=!0,a=1;a<t.length;a++){var c=t[a];0!==o[c]&&(n=!1)}n&&(u.splice(r--,1),e=i(i.s=t[0]))}return e}var n={},o={1:0},u=[];function i(r){if(n[r])return n[r].exports;var t=n[r]={i:r,l:!1,exports:{}};return e[r].call(t.exports,t,t.exports,i),t.l=!0,t.exports}i.e=function(e){var r=[],t=o[e];if(0!==t)if(t)r.push(t[2]);else{var n=new Promise((function(r,n){t=o[e]=[r,n]}));r.push(t[2]=n);var u,a=document.createElement("script");a.charset="utf-8",a.timeout=120,i.nc&&a.setAttribute("nonce",i.nc),a.src=function(e){return i.p+"static/js/"+({}[e]||e)+"."+{3:"9013e23f"}[e]+".chunk.js"}(e);var c=new Error;u=function(r){a.onerror=a.onload=null,clearTimeout(l);var t=o[e];if(0!==t){if(t){var n=r&&("load"===r.type?"missing":r.type),u=r&&r.target&&r.target.src;c.message="Loading chunk "+e+" failed.\n("+n+": "+u+")",c.name="ChunkLoadError",c.type=n,c.request=u,t[1](c)}o[e]=void 0}};var l=setTimeout((function(){u({type:"timeout",target:a})}),12e4);a.onerror=a.onload=u,document.head.appendChild(a)}return Promise.all(r)},i.m=e,i.c=n,i.d=function(e,r,t){i.o(e,r)||Object.defineProperty(e,r,{enumerable:!0,get:t})},i.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},i.t=function(e,r){if(1&r&&(e=i(e)),8&r)return e;if(4&r&&"object"==typeof e&&e&&e.__esModule)return e;var t=Object.create(null);if(i.r(t),Object.defineProperty(t,"default",{enumerable:!0,value:e}),2&r&&"string"!=typeof e)for(var n in e)i.d(t,n,function(r){return e[r]}.bind(null,n));return t},i.n=function(e){var r=e&&e.__esModule?function(){return e.default}:function(){return e};return i.d(r,"a",r),r},i.o=function(e,r){return Object.prototype.hasOwnProperty.call(e,r)},i.p="/",i.oe=function(e){throw console.error(e),e};var a=this["webpackJsonpvision-web-app"]=this["webpackJsonpvision-web-app"]||[],c=a.push.bind(a);a.push=r,a=a.slice();for(var l=0;l<a.length;l++)r(a[l]);var f=c;t()}([])</script><script src="/static/js/2.9b5b80e8.chunk.js"></script><script src="/static/js/main.13ed4cd9.chunk.js"></script></body></html>
static/{precache-manifest.4cdbfb3ad91c466419484ccc9bd70e38.js β†’ precache-manifest.7ffa256e4ee99cb22c2ef5bb2f02bd1a.js} RENAMED
@@ -1,10 +1,10 @@
1
  self.__precacheManifest = (self.__precacheManifest || []).concat([
2
  {
3
- "revision": "aaaee67ddcadfc18878039e4aef06c9d",
4
  "url": "/index.html"
5
  },
6
  {
7
- "revision": "c052d5fdc8c36187e270",
8
  "url": "/static/css/main.3b4eede1.chunk.css"
9
  },
10
  {
@@ -20,8 +20,8 @@ self.__precacheManifest = (self.__precacheManifest || []).concat([
20
  "url": "/static/js/3.9013e23f.chunk.js"
21
  },
22
  {
23
- "revision": "c052d5fdc8c36187e270",
24
- "url": "/static/js/main.9549fb04.chunk.js"
25
  },
26
  {
27
  "revision": "d8c310b0ac7ffa6d8151",
 
1
  self.__precacheManifest = (self.__precacheManifest || []).concat([
2
  {
3
+ "revision": "0b39b3518ff769f69904f679df2e185f",
4
  "url": "/index.html"
5
  },
6
  {
7
+ "revision": "d64110ad919024c5c0ac",
8
  "url": "/static/css/main.3b4eede1.chunk.css"
9
  },
10
  {
 
20
  "url": "/static/js/3.9013e23f.chunk.js"
21
  },
22
  {
23
+ "revision": "d64110ad919024c5c0ac",
24
+ "url": "/static/js/main.13ed4cd9.chunk.js"
25
  },
26
  {
27
  "revision": "d8c310b0ac7ffa6d8151",
static/service-worker.js CHANGED
@@ -14,7 +14,7 @@
14
  importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
15
 
16
  importScripts(
17
- "/precache-manifest.4cdbfb3ad91c466419484ccc9bd70e38.js"
18
  );
19
 
20
  self.addEventListener('message', (event) => {
 
14
  importScripts("https://storage.googleapis.com/workbox-cdn/releases/4.3.1/workbox-sw.js");
15
 
16
  importScripts(
17
+ "/precache-manifest.7ffa256e4ee99cb22c2ef5bb2f02bd1a.js"
18
  );
19
 
20
  self.addEventListener('message', (event) => {
static/static/js/main.13ed4cd9.chunk.js ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ (this["webpackJsonpvision-web-app"]=this["webpackJsonpvision-web-app"]||[]).push([[0],{102:function(e,a,t){},103:function(e,a,t){"use strict";t.r(a);var n=t(0),r=t.n(n),l=t(11),o=t.n(l),c=(t(97),t(78)),i=t(155),s=t(159),m=t(156),d=t(157),u=t(48),g=t(158),p=t(138),E=t(81),h=t(143),y=t(136),b=t(137),f=t(63),v=t.n(f),x=t(75),S=t.n(x),C=t(133);const j=Object(C.a)(e=>({paper:{padding:e.spacing(2),display:"flex",flexDirection:"column",alignItems:"center",height:"100%",minHeight:300,transition:"all 0.3s ease"},dragActive:{border:"2px dashed #3f51b5",backgroundColor:"rgba(63, 81, 181, 0.05)"},dragInactive:{border:"2px dashed #ccc",backgroundColor:"white"},uploadBox:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100%",width:"100%",cursor:"pointer"},uploadIcon:{fontSize:60,color:"#3f51b5",marginBottom:e.spacing(2)},supportText:{marginTop:e.spacing(2)},previewBox:{display:"flex",flexDirection:"column",alignItems:"center",width:"100%",height:"100%",position:"relative"},imageContainer:{position:"relative",width:"100%",height:"60vh",[e.breakpoints.down("sm")]:{height:"45vh"},display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",marginTop:e.spacing(2)},deleteButton:{position:"absolute",top:0,right:0,backgroundColor:"rgba(255, 255, 255, 0.7)","&:hover":{backgroundColor:"rgba(255, 255, 255, 0.9)"}}}));var w=e=>{let{onImageUpload:a}=e;const t=j(),[l,o]=Object(n.useState)(null),[c,i]=Object(n.useState)(!1),m=Object(n.useRef)(null),d=e=>{e.preventDefault(),e.stopPropagation(),"dragenter"===e.type||"dragover"===e.type?i(!0):"dragleave"===e.type&&i(!1)},g=e=>{e.type.startsWith("image/")?(o(URL.createObjectURL(e)),a(e)):alert("Please upload an image file")};return r.a.createElement(E.a,{className:"".concat(t.paper," ").concat(c?t.dragActive:t.dragInactive),onDragEnter:d,onDragLeave:d,onDragOver:d,onDrop:e=>{e.preventDefault(),e.stopPropagation(),i(!1),e.dataTransfer.files&&e.dataTransfer.files[0]&&g(e.dataTransfer.files[0])}},r.a.createElement("input",{ref:m,type:"file",accept:"image/*",onChange:e=>{e.preventDefault(),e.target.files&&e.target.files[0]&&g(e.target.files[0])},style:{display:"none"}}),l?r.a.createElement(s.a,{className:t.previewBox},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Preview"),r.a.createElement(s.a,{className:t.imageContainer},r.a.createElement("img",{src:l,alt:"Preview",className:"preview-image"}),r.a.createElement(b.a,{"aria-label":"delete",className:t.deleteButton,onClick:()=>{o(null),a(null),m.current.value=""}},r.a.createElement(S.a,null)))):r.a.createElement(s.a,{className:t.uploadBox,onClick:()=>{m.current.click()}},r.a.createElement(v.a,{className:t.uploadIcon}),r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Drag & Drop an image here"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",gutterBottom:!0},"or"),r.a.createElement(y.a,{variant:"contained",color:"primary",component:"span",startIcon:r.a.createElement(v.a,null)},"Browse Files"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",className:t.supportText},"Supported formats: JPG, PNG, GIF")))},O=t(139),N=t(140),B=t(166),T=t(141),I=t(64),k=t.n(I),P=t(76),D=t.n(P),A=t(77),F=t.n(A);const R=Object(C.a)(e=>({card:{height:"100%",display:"flex",flexDirection:"column"},selectedCard:{border:"2px solid #3f51b5"},unavailableCard:{opacity:.6},cardContent:{flexGrow:1},chipContainer:{marginBottom:e.spacing(1.5)},successChip:{backgroundColor:"#34C759",color:"#fff"},errorChip:{backgroundColor:"#FF3B3F",color:"#fff"},modelType:{marginTop:e.spacing(1)},processButton:{marginTop:e.spacing(3),textAlign:"center"}}));var z=e=>{let{onModelSelect:a,onProcess:t,isProcessing:n,modelsStatus:l,selectedModel:o,imageSelected:c}=e;const i=R(),m=[{id:"yolo",name:"YOLOv8",description:"Fast and accurate object detection",icon:r.a.createElement(k.a,null),available:l.yolo},{id:"detr",name:"DETR",description:"DEtection TRansformer for object detection",icon:r.a.createElement(k.a,null),available:l.detr},{id:"vit",name:"ViT",description:"Vision Transformer for image classification",icon:r.a.createElement(D.a,null),available:l.vit}],d=e=>{m.find(a=>a.id===e).available&&a(e)};return r.a.createElement(s.a,{sx:{p:2,height:"100%"}},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Select Model"),r.a.createElement(p.a,{container:!0,spacing:2},m.map(e=>r.a.createElement(p.a,{item:!0,xs:12,sm:4,key:e.id},r.a.createElement(O.a,{className:"\n ".concat(i.card," \n ").concat(o===e.id?i.selectedCard:""," \n ").concat(e.available?"":i.unavailableCard,"\n "),onClick:()=>d(e.id)},r.a.createElement(N.a,{className:i.cardContent},r.a.createElement(s.a,{sx:{mb:2,color:"primary"}},e.icon),r.a.createElement(u.a,{variant:"h5",component:"div",gutterBottom:!0},e.name),r.a.createElement("div",{className:i.chipContainer},e.available?r.a.createElement(B.a,{label:"Available",className:i.successChip,size:"small"}):r.a.createElement(B.a,{label:"Not Available",className:i.errorChip,size:"small"})),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},e.description)),r.a.createElement(T.a,null,r.a.createElement(y.a,{size:"small",onClick:()=>d(e.id),disabled:!e.available,color:o===e.id?"primary":"default",variant:o===e.id?"contained":"outlined",fullWidth:!0},o===e.id?"Selected":"Select")))))),r.a.createElement("div",{className:i.processButton},r.a.createElement(y.a,{variant:"contained",color:"primary",size:"large",startIcon:r.a.createElement(F.a,null),onClick:t,disabled:!o||!c||n},n?"Processing...":"Process Image")))},L=t(153),M=t(150),W=t(105),_=t(154),J=t(142),U=t(164),H=t(163),V=t(145),G=t(146),Y=t(147),q=t(167),K=t(160),Q=t(151),X=t(169),Z=t(152),$=t(161);const ee=Object(C.a)(e=>({root:{marginTop:e.spacing(2),marginBottom:e.spacing(2),padding:e.spacing(2),backgroundColor:"#f5f5f5",borderRadius:e.shape.borderRadius},button:{marginRight:e.spacing(2)},searchDialog:{minWidth:"500px"},formControl:{marginBottom:e.spacing(2),minWidth:"100%"},searchResults:{marginTop:e.spacing(2)},resultCard:{marginBottom:e.spacing(2)},resultImage:{height:140,objectFit:"contain"},chip:{margin:e.spacing(.5)},similarityChip:{backgroundColor:e.palette.primary.main,color:"white"}}));var ae=e=>{let{results:a}=e;const t=ee(),[l,o]=Object(n.useState)(!1),[c,i]=Object(n.useState)(!1),[m,d]=Object(n.useState)(null),[g,E]=Object(n.useState)(!1),[b,f]=Object(n.useState)("image"),[v,x]=Object(n.useState)(""),[S,C]=Object(n.useState)([]),[j,w]=Object(n.useState)(!1),[T,I]=Object(n.useState)(null),{model:k,data:P}=a,D=()=>{E(!1)},A=()=>"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){const a=16*Math.random()|0;return("x"===e?a:3&a|8).toString(16)}));return r.a.createElement(s.a,{className:t.root},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Vector Database Actions"),r.a.createElement(s.a,{display:"flex",alignItems:"center",mb:2},r.a.createElement(y.a,{variant:"contained",color:"primary",onClick:async()=>{o(!0),d(null);try{let e;if(e="vit"===k?await fetch("/api/add-to-collection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:P.image,metadata:{model:"vit",classifications:P.classifications}})}):await fetch("/api/add-detected-objects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:P.image,objects:P.detections,imageId:A()})}),!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const a=await e.json();if(a.error)throw new Error(a.error);i(!0),setTimeout(()=>i(!1),5e3)}catch(e){console.error("Error saving to vector DB:",e),d("Error saving to vector DB: ".concat(e.message))}finally{o(!1)}},disabled:l,className:t.button},l?r.a.createElement(r.a.Fragment,null,r.a.createElement(h.a,{size:20,color:"inherit",style:{marginRight:8}}),"Saving..."):"Save to Vector DB"),r.a.createElement(y.a,{variant:"outlined",color:"primary",onClick:()=>{E(!0),C([]),I(null)},className:t.button},"Search Similar")),m&&r.a.createElement($.a,{severity:"error",style:{marginTop:8}},m),r.a.createElement(U.a,{open:c,autoHideDuration:5e3,onClose:()=>i(!1)},r.a.createElement($.a,{severity:"success"},"vit"===k?"Image and classifications successfully saved to vector DB!":"Detected objects successfully saved to vector DB!")),r.a.createElement(H.a,{open:g,onClose:D,maxWidth:"md",fullWidth:!0},r.a.createElement(V.a,null,"Search Vector Database"),r.a.createElement(G.a,null,r.a.createElement(Y.a,{className:t.formControl},r.a.createElement(q.a,{id:"search-type-label"},"Search Type"),r.a.createElement(K.a,{labelId:"search-type-label",id:"search-type",value:b,onChange:e=>{f(e.target.value),C([]),I(null)}},r.a.createElement(Q.a,{value:"image"},"Search by Current Image"),r.a.createElement(Q.a,{value:"class"},"Search by Class Name"))),"class"===b&&r.a.createElement(Y.a,{className:t.formControl},r.a.createElement(X.a,{label:"Class Name",value:v,onChange:e=>{x(e.target.value)},placeholder:"e.g. person, car, dog...",fullWidth:!0})),T&&r.a.createElement($.a,{severity:"error",style:{marginBottom:16}},T),r.a.createElement(s.a,{className:t.searchResults},j?r.a.createElement(s.a,{display:"flex",justifyContent:"center",alignItems:"center",p:4},r.a.createElement(h.a,null),r.a.createElement(u.a,{variant:"body1",style:{marginLeft:16}},"Searching...")):r.a.createElement(r.a.Fragment,null,console.log("Search dialog render - searchResults:",S),S.length>0?(console.log("Rendering search results:",S),console.log("Search results length:",S.length),0===S.length?(console.log("No results to render"),r.a.createElement(u.a,{variant:"body1"},"No results found.")):r.a.createElement(p.a,{container:!0,spacing:2},S.map((e,a)=>{const n=100*(1-e.distance);return r.a.createElement(p.a,{item:!0,xs:12,sm:6,key:a},r.a.createElement(O.a,{className:t.resultCard},e.metadata&&e.metadata.image_data?r.a.createElement(J.a,{className:t.resultImage,component:"img",height:"200",image:"data:image/jpeg;base64,".concat(e.metadata.image_data),alt:e.metadata&&e.metadata.class?e.metadata.class:"Object"}):r.a.createElement(s.a,{className:t.resultImage,style:{backgroundColor:"#f0f0f0",display:"flex",alignItems:"center",justifyContent:"center",height:200}},r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},e.metadata&&e.metadata.class?e.metadata.class:"Object"," Image")),r.a.createElement(N.a,null,r.a.createElement(s.a,{display:"flex",justifyContent:"space-between",alignItems:"center",mb:1},r.a.createElement(u.a,{variant:"subtitle1"},"Result #",a+1),r.a.createElement(B.a,{label:"Similarity: ".concat(n.toFixed(2),"%"),className:t.similarityChip,size:"small"})),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Class:")," ",e.metadata.class||"N/A"),e.metadata.confidence&&r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Confidence:")," ",(100*e.metadata.confidence).toFixed(2),"%"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Object ID:")," ",e.id))))}))):r.a.createElement(u.a,{variant:"body1"},"No results found. Please try another search.")))),r.a.createElement(Z.a,null,r.a.createElement(y.a,{onClick:D,color:"default"},"Close"),r.a.createElement(y.a,{onClick:async()=>{w(!0),I(null);try{let e={};if("image"===b)e={searchType:"image",image:P.image,n_results:5};else{if(!v.trim())throw new Error("Please enter a class name");e={searchType:"class",class_name:v.trim(),n_results:5}}const a=await fetch("/api/search-similar-objects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!a.ok)throw new Error("HTTP error! Status: ".concat(a.status));const t=await a.json();if(t.error)throw new Error(t.error);if(console.log("Search API response:",t),!t.success||!Array.isArray(t.results))throw console.error("Unexpected API response format:",t),new Error("Unexpected API response format");console.log("Setting search results array:",t.results),console.log("Results array length:",t.results.length),console.log("First result item:",t.results[0]),C(t.results)}catch(e){console.error("Error searching vector DB:",e),I("Error searching vector DB: ".concat(e.message))}finally{w(!1)}},color:"primary",variant:"contained",disabled:j||"class"===b&&!v.trim()},"Search"))))};const te=Object(C.a)(e=>({paper:{padding:e.spacing(2)},marginBottom:{marginBottom:e.spacing(2)},resultImage:{maxWidth:"100%",maxHeight:"400px",objectFit:"contain"},dividerMargin:{margin:"".concat(e.spacing(2),"px 0")},chipContainer:{display:"flex",gap:e.spacing(1),flexWrap:"wrap"}}));var ne=e=>{let{results:a}=e;const t=te();if(!a)return null;const{model:n,data:l}=a;if(l.error)return r.a.createElement(E.a,{sx:{p:2,bgcolor:"#ffebee"}},r.a.createElement(u.a,{color:"error"},l.error));const o=()=>l.performance?r.a.createElement(s.a,{className:"performance-info"},r.a.createElement(L.a,{className:t.dividerMargin}),r.a.createElement(u.a,{variant:"body2"},"Inference time: ",(e=>{if(void 0===e||null===e||isNaN(e))return"-";const a=Number(e);return a<1e3?"".concat(a.toFixed(2)," ms"):"".concat((a/1e3).toFixed(2)," s")})(l.performance.inference_time)," on ",l.performance.device)):null;return"yolo"===n||"detr"===n?r.a.createElement(E.a,{className:t.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"yolo"===n?"YOLOv8":"DETR"," Detection Results"),r.a.createElement(p.a,{container:!0,spacing:3},r.a.createElement(p.a,{item:!0,xs:12,md:6},l.image&&r.a.createElement(s.a,{className:t.marginBottom},r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Detection Result"),r.a.createElement("img",{src:"data:image/png;base64,".concat(l.image),alt:"Detection Result",className:t.resultImage}))),r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(s.a,{className:t.marginBottom},r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Detected Objects:"),l.detections&&l.detections.length>0?r.a.createElement(M.a,null,l.detections.map((e,a)=>r.a.createElement(r.a.Fragment,{key:a},r.a.createElement(W.a,null,r.a.createElement(_.a,{primary:r.a.createElement(s.a,{style:{display:"flex",alignItems:"center"}},r.a.createElement(u.a,{variant:"body1",component:"span"},e.class),r.a.createElement(B.a,{label:"".concat((100*e.confidence).toFixed(0),"%"),size:"small",color:"primary",style:{marginLeft:8}})),secondary:"Bounding Box: [".concat(e.bbox.join(", "),"]")})),a<l.detections.length-1&&r.a.createElement(L.a,null)))):r.a.createElement(u.a,{variant:"body1"},"No objects detected")))),o(),r.a.createElement(ae,{results:a})):"vit"===n?r.a.createElement(E.a,{className:t.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"ViT Classification Results"),r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Top Predictions:"),l.top_predictions&&l.top_predictions.length>0?r.a.createElement(M.a,null,l.top_predictions.map((e,a)=>r.a.createElement(r.a.Fragment,{key:a},r.a.createElement(W.a,null,r.a.createElement(_.a,{primary:r.a.createElement(s.a,{style:{display:"flex",alignItems:"center"}},r.a.createElement(u.a,{variant:"body1",component:"span"},e.rank,". ",e.class),r.a.createElement(B.a,{label:"".concat((100*e.probability).toFixed(1),"%"),size:"small",color:0===a?"primary":"default",style:{marginLeft:8}}))})),a<l.top_predictions.length-1&&r.a.createElement(L.a,null)))):r.a.createElement(u.a,{variant:"body1"},"No classifications available"),o(),r.a.createElement(ae,{results:a})):null};const re=Object(C.a)(e=>({paper:{padding:e.spacing(2),marginTop:e.spacing(2)},marginBottom:{marginBottom:e.spacing(2)},dividerMargin:{margin:"".concat(e.spacing(2),"px 0")},responseBox:{padding:e.spacing(2),backgroundColor:"#f5f5f5",borderRadius:e.shape.borderRadius,marginTop:e.spacing(2),whiteSpace:"pre-wrap"},buttonProgress:{marginLeft:e.spacing(1)}}));var le=e=>{let{visionResults:a,model:t}=e;const l=re(),[o,c]=Object(n.useState)(""),[i,m]=Object(n.useState)(!1),[d,g]=Object(n.useState)(null),[p,b]=Object(n.useState)(null);return a?r.a.createElement(E.a,{className:l.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Ask AI about the ","vit"===t?"Classification":"Detection"," Results"),r.a.createElement(u.a,{variant:"body2",className:l.marginBottom},"Ask a question about the detected objects or classifications to get an AI-powered analysis."),r.a.createElement(X.a,{fullWidth:!0,label:"Your question about the image",variant:"outlined",value:o,onChange:e=>c(e.target.value),disabled:i,className:l.marginBottom,placeholder:"vit"===t?"E.g., What category does this image belong to?":"E.g., How many people are in this image?"}),r.a.createElement(y.a,{variant:"contained",color:"primary",onClick:async()=>{if(o.trim()){m(!0),b(null);try{const e=await fetch("/api/analyze",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({visionResults:a,userQuery:o})});if(!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const t=await e.json();t.error?b(t.error):g(t)}catch(e){console.error("Error analyzing with LLM:",e),b("Error analyzing with LLM: ".concat(e.message))}finally{m(!1)}}},disabled:i||!o.trim()},"Analyze with AI",i&&r.a.createElement(h.a,{size:24,className:l.buttonProgress})),p&&r.a.createElement(s.a,{mt:2},r.a.createElement(u.a,{color:"error"},p)),d&&r.a.createElement(r.a.Fragment,null,r.a.createElement(L.a,{className:l.dividerMargin}),r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"AI Analysis:"),r.a.createElement(s.a,{className:l.responseBox},r.a.createElement(u.a,{variant:"body1"},d.response)),d.performance&&r.a.createElement(s.a,{mt:1},r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},"Analysis time: ",(e=>{if(void 0===e||null===e||isNaN(e))return"-";const a=Number(e);return a<1e3?"".concat(a.toFixed(2)," ms"):"".concat((a/1e3).toFixed(2)," s")})(d.performance.inference_time)," on ",d.performance.device)))):null};var oe=function(){const[e,a]=Object(n.useState)("gpt-4"),[t,l]=Object(n.useState)(""),[o,c]=Object(n.useState)("You are a helpful assistant."),[i,s]=Object(n.useState)(""),[m,d]=Object(n.useState)(""),[g,h]=Object(n.useState)(!1),[b,f]=Object(n.useState)("");return r.a.createElement(E.a,{style:{padding:16}},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"OpenAI Chat (OpenAI API)"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",gutterBottom:!0},"If the server env var OPENAI_API_KEY is set, the API Key field is optional."),r.a.createElement(p.a,{container:!0,spacing:2},r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(X.a,{label:"Model",value:e,onChange:e=>a(e.target.value),fullWidth:!0,variant:"outlined",size:"small"})),r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(X.a,{label:"OpenAI API Key (optional)",value:t,onChange:e=>l(e.target.value),fullWidth:!0,variant:"outlined",size:"small",type:"password",placeholder:"sk-..."})),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(X.a,{label:"System Prompt (optional)",value:o,onChange:e=>c(e.target.value),fullWidth:!0,variant:"outlined",size:"small"})),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(X.a,{label:"User Question",value:i,onChange:e=>s(e.target.value),fullWidth:!0,multiline:!0,rows:4,variant:"outlined"})),b&&r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(u.a,{color:"error"},b)),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement("div",{style:{display:"flex",gap:8}},r.a.createElement(y.a,{color:"primary",variant:"contained",onClick:async()=>{f(""),d("");const a=(i||"").trim();if(a){h(!0);try{const r=await fetch("/api/openai/chat",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({prompt:a,model:(e||"").trim()||"gpt-4",api_key:t||void 0,system:o||void 0})});if(!r.ok){let e=await r.text();try{e=JSON.stringify(JSON.parse(e),null,2)}catch(n){}throw new Error(e)}const l=await r.json(),c="Model: ".concat(l.model," | Latency: ").concat(l.latency_sec,"s")+(l.usage?" | Usage: ".concat(JSON.stringify(l.usage)):"");d((l.response||"(Empty response)")+"\n\n---\n"+c)}catch(r){f("Error: "+r.message)}finally{h(!1)}}else f("Please enter a question.")},disabled:g},g?"Sending...":"Send Question"),r.a.createElement(y.a,{variant:"outlined",onClick:()=>{s(""),d(""),f("")}},"Clear"))),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(L.a,{style:{margin:"12px 0"}}),r.a.createElement(u.a,{variant:"subtitle2",color:"textSecondary"},"Response"),r.a.createElement("pre",{style:{whiteSpace:"pre-wrap",fontFamily:"ui-monospace, monospace"}},m))))};t(102);const ce=Object(c.a)({palette:{primary:{main:"#3f51b5"},secondary:{main:"#f50057"}},typography:{fontFamily:"Roboto, Arial, sans-serif"}});var ie=function(){const[e,a]=Object(n.useState)(null),[t,l]=Object(n.useState)(""),[o,c]=Object(n.useState)(!1),[y,b]=Object(n.useState)(null),[f,v]=Object(n.useState)(null),[x,S]=Object(n.useState)({yolo:!1,detr:!1,vit:!1});return Object(n.useEffect)(()=>{fetch("/api/status").then(e=>e.json()).then(e=>{S(e.models)}).catch(e=>{console.error("Error checking API status:",e),v("Error connecting to the backend API. Please make sure the server is running.")})},[]),r.a.createElement(i.a,{theme:ce},r.a.createElement(s.a,{style:{flexGrow:1}},r.a.createElement(m.a,{position:"static"},r.a.createElement(d.a,null,r.a.createElement(u.a,{variant:"h6",style:{flexGrow:1}},"Multi-Model Object Detection Demo"))),r.a.createElement(g.a,{maxWidth:"lg",style:{marginTop:ce.spacing(4),marginBottom:ce.spacing(4)}},r.a.createElement(p.a,{container:!0,spacing:3},r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(E.a,{style:{padding:ce.spacing(2)}},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"Upload an image to see how each model performs!"),r.a.createElement(u.a,{variant:"body1",paragraph:!0},"This demo showcases three different object detection and image classification models:"),r.a.createElement(u.a,{variant:"body1",component:"div"},r.a.createElement("ul",null,r.a.createElement("li",null,r.a.createElement("strong",null,"YOLOv8"),": Fast and accurate object detection"),r.a.createElement("li",null,r.a.createElement("strong",null,"DETR"),": DEtection TRansformer for object detection"),r.a.createElement("li",null,r.a.createElement("strong",null,"ViT"),": Vision Transformer for image classification"))))),r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(w,{onImageUpload:e=>{a(e),b(null),v(null)}})),r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(z,{onModelSelect:e=>{l(e),b(null),v(null)},onProcess:async()=>{if(!e||!t)return void v("Please select both an image and a model");c(!0),v(null);const a=new FormData;a.append("image",e);let n="";switch(t){case"yolo":n="/api/detect/yolo";break;case"detr":n="/api/detect/detr";break;case"vit":n="/api/classify/vit";break;default:return v("Invalid model selection"),void c(!1)}try{const e=await fetch(n,{method:"POST",body:a});if(!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const r=await e.json();b({model:t,data:r})}catch(r){console.error("Error processing image:",r),v("Error processing image: ".concat(r.message))}finally{c(!1)}},isProcessing:o,modelsStatus:x,selectedModel:t,imageSelected:!!e})),f&&r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(E.a,{style:{padding:ce.spacing(2),backgroundColor:"#ffebee"}},r.a.createElement(u.a,{color:"error"},f))),o&&r.a.createElement(p.a,{item:!0,xs:12,style:{textAlign:"center",margin:"".concat(ce.spacing(4),"px 0")}},r.a.createElement(h.a,null),r.a.createElement(u.a,{variant:"h6",style:{marginTop:ce.spacing(2)}},"Processing image...")),y&&r.a.createElement(r.a.Fragment,null,r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(ne,{results:y})),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(le,{visionResults:y.data,model:y.model}))),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(oe,null))))))};var se=e=>{e&&e instanceof Function&&t.e(3).then(t.bind(null,170)).then(a=>{let{getCLS:t,getFID:n,getFCP:r,getLCP:l,getTTFB:o}=a;t(e),n(e),r(e),l(e),o(e)})};o.a.render(r.a.createElement(r.a.StrictMode,null,r.a.createElement(ie,null)),document.getElementById("root")),se()},92:function(e,a,t){e.exports=t(103)},97:function(e,a,t){}},[[92,1,2]]]);
2
+ //# sourceMappingURL=main.13ed4cd9.chunk.js.map
static/static/js/{main.9549fb04.chunk.js.map β†’ main.13ed4cd9.chunk.js.map} RENAMED
The diff for this file is too large to render. See raw diff
 
static/static/js/main.9549fb04.chunk.js DELETED
@@ -1,2 +0,0 @@
1
- (this["webpackJsonpvision-web-app"]=this["webpackJsonpvision-web-app"]||[]).push([[0],{102:function(e,a,t){},103:function(e,a,t){"use strict";t.r(a);var n=t(0),r=t.n(n),l=t(11),o=t.n(l),c=(t(97),t(78)),i=t(155),s=t(159),m=t(156),d=t(157),u=t(48),g=t(158),p=t(138),E=t(81),h=t(143),y=t(136),b=t(137),f=t(63),v=t.n(f),x=t(75),S=t.n(x),C=t(133);const j=Object(C.a)(e=>({paper:{padding:e.spacing(2),display:"flex",flexDirection:"column",alignItems:"center",height:"100%",minHeight:300,transition:"all 0.3s ease"},dragActive:{border:"2px dashed #3f51b5",backgroundColor:"rgba(63, 81, 181, 0.05)"},dragInactive:{border:"2px dashed #ccc",backgroundColor:"white"},uploadBox:{display:"flex",flexDirection:"column",alignItems:"center",justifyContent:"center",height:"100%",width:"100%",cursor:"pointer"},uploadIcon:{fontSize:60,color:"#3f51b5",marginBottom:e.spacing(2)},supportText:{marginTop:e.spacing(2)},previewBox:{display:"flex",flexDirection:"column",alignItems:"center",width:"100%",height:"100%",position:"relative"},imageContainer:{position:"relative",width:"100%",height:420,[e.breakpoints.down("sm")]:{height:320},display:"flex",justifyContent:"center",alignItems:"center",overflow:"hidden",marginTop:e.spacing(2)},deleteButton:{position:"absolute",top:0,right:0,backgroundColor:"rgba(255, 255, 255, 0.7)","&:hover":{backgroundColor:"rgba(255, 255, 255, 0.9)"}}}));var w=e=>{let{onImageUpload:a}=e;const t=j(),[l,o]=Object(n.useState)(null),[c,i]=Object(n.useState)(!1),m=Object(n.useRef)(null),d=e=>{e.preventDefault(),e.stopPropagation(),"dragenter"===e.type||"dragover"===e.type?i(!0):"dragleave"===e.type&&i(!1)},g=e=>{e.type.startsWith("image/")?(o(URL.createObjectURL(e)),a(e)):alert("Please upload an image file")};return r.a.createElement(E.a,{className:"".concat(t.paper," ").concat(c?t.dragActive:t.dragInactive),onDragEnter:d,onDragLeave:d,onDragOver:d,onDrop:e=>{e.preventDefault(),e.stopPropagation(),i(!1),e.dataTransfer.files&&e.dataTransfer.files[0]&&g(e.dataTransfer.files[0])}},r.a.createElement("input",{ref:m,type:"file",accept:"image/*",onChange:e=>{e.preventDefault(),e.target.files&&e.target.files[0]&&g(e.target.files[0])},style:{display:"none"}}),l?r.a.createElement(s.a,{className:t.previewBox},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Preview"),r.a.createElement(s.a,{className:t.imageContainer},r.a.createElement("img",{src:l,alt:"Preview",className:"preview-image"}),r.a.createElement(b.a,{"aria-label":"delete",className:t.deleteButton,onClick:()=>{o(null),a(null),m.current.value=""}},r.a.createElement(S.a,null)))):r.a.createElement(s.a,{className:t.uploadBox,onClick:()=>{m.current.click()}},r.a.createElement(v.a,{className:t.uploadIcon}),r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Drag & Drop an image here"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",gutterBottom:!0},"or"),r.a.createElement(y.a,{variant:"contained",color:"primary",component:"span",startIcon:r.a.createElement(v.a,null)},"Browse Files"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",className:t.supportText},"Supported formats: JPG, PNG, GIF")))},O=t(139),N=t(140),B=t(166),T=t(141),I=t(64),k=t.n(I),P=t(76),D=t.n(P),A=t(77),F=t.n(A);const R=Object(C.a)(e=>({card:{height:"100%",display:"flex",flexDirection:"column"},selectedCard:{border:"2px solid #3f51b5"},unavailableCard:{opacity:.6},cardContent:{flexGrow:1},chipContainer:{marginBottom:e.spacing(1.5)},successChip:{backgroundColor:"#34C759",color:"#fff"},errorChip:{backgroundColor:"#FF3B3F",color:"#fff"},modelType:{marginTop:e.spacing(1)},processButton:{marginTop:e.spacing(3),textAlign:"center"}}));var z=e=>{let{onModelSelect:a,onProcess:t,isProcessing:n,modelsStatus:l,selectedModel:o,imageSelected:c}=e;const i=R(),m=[{id:"yolo",name:"YOLOv8",description:"Fast and accurate object detection",icon:r.a.createElement(k.a,null),available:l.yolo},{id:"detr",name:"DETR",description:"DEtection TRansformer for object detection",icon:r.a.createElement(k.a,null),available:l.detr},{id:"vit",name:"ViT",description:"Vision Transformer for image classification",icon:r.a.createElement(D.a,null),available:l.vit}],d=e=>{m.find(a=>a.id===e).available&&a(e)};return r.a.createElement(s.a,{sx:{p:2,height:"100%"}},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Select Model"),r.a.createElement(p.a,{container:!0,spacing:2},m.map(e=>r.a.createElement(p.a,{item:!0,xs:12,sm:4,key:e.id},r.a.createElement(O.a,{className:"\n ".concat(i.card," \n ").concat(o===e.id?i.selectedCard:""," \n ").concat(e.available?"":i.unavailableCard,"\n "),onClick:()=>d(e.id)},r.a.createElement(N.a,{className:i.cardContent},r.a.createElement(s.a,{sx:{mb:2,color:"primary"}},e.icon),r.a.createElement(u.a,{variant:"h5",component:"div",gutterBottom:!0},e.name),r.a.createElement("div",{className:i.chipContainer},e.available?r.a.createElement(B.a,{label:"Available",className:i.successChip,size:"small"}):r.a.createElement(B.a,{label:"Not Available",className:i.errorChip,size:"small"})),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},e.description)),r.a.createElement(T.a,null,r.a.createElement(y.a,{size:"small",onClick:()=>d(e.id),disabled:!e.available,color:o===e.id?"primary":"default",variant:o===e.id?"contained":"outlined",fullWidth:!0},o===e.id?"Selected":"Select")))))),r.a.createElement("div",{className:i.processButton},r.a.createElement(y.a,{variant:"contained",color:"primary",size:"large",startIcon:r.a.createElement(F.a,null),onClick:t,disabled:!o||!c||n},n?"Processing...":"Process Image")))},L=t(153),M=t(150),W=t(105),_=t(154),J=t(142),U=t(164),H=t(163),V=t(145),G=t(146),Y=t(147),q=t(167),K=t(160),Q=t(151),X=t(169),Z=t(152),$=t(161);const ee=Object(C.a)(e=>({root:{marginTop:e.spacing(2),marginBottom:e.spacing(2),padding:e.spacing(2),backgroundColor:"#f5f5f5",borderRadius:e.shape.borderRadius},button:{marginRight:e.spacing(2)},searchDialog:{minWidth:"500px"},formControl:{marginBottom:e.spacing(2),minWidth:"100%"},searchResults:{marginTop:e.spacing(2)},resultCard:{marginBottom:e.spacing(2)},resultImage:{height:140,objectFit:"contain"},chip:{margin:e.spacing(.5)},similarityChip:{backgroundColor:e.palette.primary.main,color:"white"}}));var ae=e=>{let{results:a}=e;const t=ee(),[l,o]=Object(n.useState)(!1),[c,i]=Object(n.useState)(!1),[m,d]=Object(n.useState)(null),[g,E]=Object(n.useState)(!1),[b,f]=Object(n.useState)("image"),[v,x]=Object(n.useState)(""),[S,C]=Object(n.useState)([]),[j,w]=Object(n.useState)(!1),[T,I]=Object(n.useState)(null),{model:k,data:P}=a,D=()=>{E(!1)},A=()=>"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,(function(e){const a=16*Math.random()|0;return("x"===e?a:3&a|8).toString(16)}));return r.a.createElement(s.a,{className:t.root},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Vector Database Actions"),r.a.createElement(s.a,{display:"flex",alignItems:"center",mb:2},r.a.createElement(y.a,{variant:"contained",color:"primary",onClick:async()=>{o(!0),d(null);try{let e;if(e="vit"===k?await fetch("/api/add-to-collection",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:P.image,metadata:{model:"vit",classifications:P.classifications}})}):await fetch("/api/add-detected-objects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({image:P.image,objects:P.detections,imageId:A()})}),!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const a=await e.json();if(a.error)throw new Error(a.error);i(!0),setTimeout(()=>i(!1),5e3)}catch(e){console.error("Error saving to vector DB:",e),d("Error saving to vector DB: ".concat(e.message))}finally{o(!1)}},disabled:l,className:t.button},l?r.a.createElement(r.a.Fragment,null,r.a.createElement(h.a,{size:20,color:"inherit",style:{marginRight:8}}),"Saving..."):"Save to Vector DB"),r.a.createElement(y.a,{variant:"outlined",color:"primary",onClick:()=>{E(!0),C([]),I(null)},className:t.button},"Search Similar")),m&&r.a.createElement($.a,{severity:"error",style:{marginTop:8}},m),r.a.createElement(U.a,{open:c,autoHideDuration:5e3,onClose:()=>i(!1)},r.a.createElement($.a,{severity:"success"},"vit"===k?"Image and classifications successfully saved to vector DB!":"Detected objects successfully saved to vector DB!")),r.a.createElement(H.a,{open:g,onClose:D,maxWidth:"md",fullWidth:!0},r.a.createElement(V.a,null,"Search Vector Database"),r.a.createElement(G.a,null,r.a.createElement(Y.a,{className:t.formControl},r.a.createElement(q.a,{id:"search-type-label"},"Search Type"),r.a.createElement(K.a,{labelId:"search-type-label",id:"search-type",value:b,onChange:e=>{f(e.target.value),C([]),I(null)}},r.a.createElement(Q.a,{value:"image"},"Search by Current Image"),r.a.createElement(Q.a,{value:"class"},"Search by Class Name"))),"class"===b&&r.a.createElement(Y.a,{className:t.formControl},r.a.createElement(X.a,{label:"Class Name",value:v,onChange:e=>{x(e.target.value)},placeholder:"e.g. person, car, dog...",fullWidth:!0})),T&&r.a.createElement($.a,{severity:"error",style:{marginBottom:16}},T),r.a.createElement(s.a,{className:t.searchResults},j?r.a.createElement(s.a,{display:"flex",justifyContent:"center",alignItems:"center",p:4},r.a.createElement(h.a,null),r.a.createElement(u.a,{variant:"body1",style:{marginLeft:16}},"Searching...")):r.a.createElement(r.a.Fragment,null,console.log("Search dialog render - searchResults:",S),S.length>0?(console.log("Rendering search results:",S),console.log("Search results length:",S.length),0===S.length?(console.log("No results to render"),r.a.createElement(u.a,{variant:"body1"},"No results found.")):r.a.createElement(p.a,{container:!0,spacing:2},S.map((e,a)=>{const n=100*(1-e.distance);return r.a.createElement(p.a,{item:!0,xs:12,sm:6,key:a},r.a.createElement(O.a,{className:t.resultCard},e.metadata&&e.metadata.image_data?r.a.createElement(J.a,{className:t.resultImage,component:"img",height:"200",image:"data:image/jpeg;base64,".concat(e.metadata.image_data),alt:e.metadata&&e.metadata.class?e.metadata.class:"Object"}):r.a.createElement(s.a,{className:t.resultImage,style:{backgroundColor:"#f0f0f0",display:"flex",alignItems:"center",justifyContent:"center",height:200}},r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},e.metadata&&e.metadata.class?e.metadata.class:"Object"," Image")),r.a.createElement(N.a,null,r.a.createElement(s.a,{display:"flex",justifyContent:"space-between",alignItems:"center",mb:1},r.a.createElement(u.a,{variant:"subtitle1"},"Result #",a+1),r.a.createElement(B.a,{label:"Similarity: ".concat(n.toFixed(2),"%"),className:t.similarityChip,size:"small"})),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Class:")," ",e.metadata.class||"N/A"),e.metadata.confidence&&r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Confidence:")," ",(100*e.metadata.confidence).toFixed(2),"%"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},r.a.createElement("strong",null,"Object ID:")," ",e.id))))}))):r.a.createElement(u.a,{variant:"body1"},"No results found. Please try another search.")))),r.a.createElement(Z.a,null,r.a.createElement(y.a,{onClick:D,color:"default"},"Close"),r.a.createElement(y.a,{onClick:async()=>{w(!0),I(null);try{let e={};if("image"===b)e={searchType:"image",image:P.image,n_results:5};else{if(!v.trim())throw new Error("Please enter a class name");e={searchType:"class",class_name:v.trim(),n_results:5}}const a=await fetch("/api/search-similar-objects",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(e)});if(!a.ok)throw new Error("HTTP error! Status: ".concat(a.status));const t=await a.json();if(t.error)throw new Error(t.error);if(console.log("Search API response:",t),!t.success||!Array.isArray(t.results))throw console.error("Unexpected API response format:",t),new Error("Unexpected API response format");console.log("Setting search results array:",t.results),console.log("Results array length:",t.results.length),console.log("First result item:",t.results[0]),C(t.results)}catch(e){console.error("Error searching vector DB:",e),I("Error searching vector DB: ".concat(e.message))}finally{w(!1)}},color:"primary",variant:"contained",disabled:j||"class"===b&&!v.trim()},"Search"))))};const te=Object(C.a)(e=>({paper:{padding:e.spacing(2)},marginBottom:{marginBottom:e.spacing(2)},resultImage:{maxWidth:"100%",maxHeight:"400px",objectFit:"contain"},dividerMargin:{margin:"".concat(e.spacing(2),"px 0")},chipContainer:{display:"flex",gap:e.spacing(1),flexWrap:"wrap"}}));var ne=e=>{let{results:a}=e;const t=te();if(!a)return null;const{model:n,data:l}=a;if(l.error)return r.a.createElement(E.a,{sx:{p:2,bgcolor:"#ffebee"}},r.a.createElement(u.a,{color:"error"},l.error));const o=()=>l.performance?r.a.createElement(s.a,{className:"performance-info"},r.a.createElement(L.a,{className:t.dividerMargin}),r.a.createElement(u.a,{variant:"body2"},"Inference time: ",(e=>{if(void 0===e||null===e||isNaN(e))return"-";const a=Number(e);return a<1e3?"".concat(a.toFixed(2)," ms"):"".concat((a/1e3).toFixed(2)," s")})(l.performance.inference_time)," on ",l.performance.device)):null;return"yolo"===n||"detr"===n?r.a.createElement(E.a,{className:t.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"yolo"===n?"YOLOv8":"DETR"," Detection Results"),r.a.createElement(p.a,{container:!0,spacing:3},r.a.createElement(p.a,{item:!0,xs:12,md:6},l.image&&r.a.createElement(s.a,{className:t.marginBottom},r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Detection Result"),r.a.createElement("img",{src:"data:image/png;base64,".concat(l.image),alt:"Detection Result",className:t.resultImage}))),r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(s.a,{className:t.marginBottom},r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Detected Objects:"),l.detections&&l.detections.length>0?r.a.createElement(M.a,null,l.detections.map((e,a)=>r.a.createElement(r.a.Fragment,{key:a},r.a.createElement(W.a,null,r.a.createElement(_.a,{primary:r.a.createElement(s.a,{style:{display:"flex",alignItems:"center"}},r.a.createElement(u.a,{variant:"body1",component:"span"},e.class),r.a.createElement(B.a,{label:"".concat((100*e.confidence).toFixed(0),"%"),size:"small",color:"primary",style:{marginLeft:8}})),secondary:"Bounding Box: [".concat(e.bbox.join(", "),"]")})),a<l.detections.length-1&&r.a.createElement(L.a,null)))):r.a.createElement(u.a,{variant:"body1"},"No objects detected")))),o(),r.a.createElement(ae,{results:a})):"vit"===n?r.a.createElement(E.a,{className:t.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"ViT Classification Results"),r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"Top Predictions:"),l.top_predictions&&l.top_predictions.length>0?r.a.createElement(M.a,null,l.top_predictions.map((e,a)=>r.a.createElement(r.a.Fragment,{key:a},r.a.createElement(W.a,null,r.a.createElement(_.a,{primary:r.a.createElement(s.a,{style:{display:"flex",alignItems:"center"}},r.a.createElement(u.a,{variant:"body1",component:"span"},e.rank,". ",e.class),r.a.createElement(B.a,{label:"".concat((100*e.probability).toFixed(1),"%"),size:"small",color:0===a?"primary":"default",style:{marginLeft:8}}))})),a<l.top_predictions.length-1&&r.a.createElement(L.a,null)))):r.a.createElement(u.a,{variant:"body1"},"No classifications available"),o(),r.a.createElement(ae,{results:a})):null};const re=Object(C.a)(e=>({paper:{padding:e.spacing(2),marginTop:e.spacing(2)},marginBottom:{marginBottom:e.spacing(2)},dividerMargin:{margin:"".concat(e.spacing(2),"px 0")},responseBox:{padding:e.spacing(2),backgroundColor:"#f5f5f5",borderRadius:e.shape.borderRadius,marginTop:e.spacing(2),whiteSpace:"pre-wrap"},buttonProgress:{marginLeft:e.spacing(1)}}));var le=e=>{let{visionResults:a,model:t}=e;const l=re(),[o,c]=Object(n.useState)(""),[i,m]=Object(n.useState)(!1),[d,g]=Object(n.useState)(null),[p,b]=Object(n.useState)(null);return a?r.a.createElement(E.a,{className:l.paper},r.a.createElement(u.a,{variant:"h6",gutterBottom:!0},"Ask AI about the ","vit"===t?"Classification":"Detection"," Results"),r.a.createElement(u.a,{variant:"body2",className:l.marginBottom},"Ask a question about the detected objects or classifications to get an AI-powered analysis."),r.a.createElement(X.a,{fullWidth:!0,label:"Your question about the image",variant:"outlined",value:o,onChange:e=>c(e.target.value),disabled:i,className:l.marginBottom,placeholder:"vit"===t?"E.g., What category does this image belong to?":"E.g., How many people are in this image?"}),r.a.createElement(y.a,{variant:"contained",color:"primary",onClick:async()=>{if(o.trim()){m(!0),b(null);try{const e=await fetch("/api/analyze",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({visionResults:a,userQuery:o})});if(!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const t=await e.json();t.error?b(t.error):g(t)}catch(e){console.error("Error analyzing with LLM:",e),b("Error analyzing with LLM: ".concat(e.message))}finally{m(!1)}}},disabled:i||!o.trim()},"Analyze with AI",i&&r.a.createElement(h.a,{size:24,className:l.buttonProgress})),p&&r.a.createElement(s.a,{mt:2},r.a.createElement(u.a,{color:"error"},p)),d&&r.a.createElement(r.a.Fragment,null,r.a.createElement(L.a,{className:l.dividerMargin}),r.a.createElement(u.a,{variant:"subtitle1",gutterBottom:!0},"AI Analysis:"),r.a.createElement(s.a,{className:l.responseBox},r.a.createElement(u.a,{variant:"body1"},d.response)),d.performance&&r.a.createElement(s.a,{mt:1},r.a.createElement(u.a,{variant:"body2",color:"textSecondary"},"Analysis time: ",(e=>{if(void 0===e||null===e||isNaN(e))return"-";const a=Number(e);return a<1e3?"".concat(a.toFixed(2)," ms"):"".concat((a/1e3).toFixed(2)," s")})(d.performance.inference_time)," on ",d.performance.device)))):null};var oe=function(){const[e,a]=Object(n.useState)("gpt-4"),[t,l]=Object(n.useState)(""),[o,c]=Object(n.useState)("You are a helpful assistant."),[i,s]=Object(n.useState)(""),[m,d]=Object(n.useState)(""),[g,h]=Object(n.useState)(!1),[b,f]=Object(n.useState)("");return r.a.createElement(E.a,{style:{padding:16}},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"OpenAI Chat (OpenAI API)"),r.a.createElement(u.a,{variant:"body2",color:"textSecondary",gutterBottom:!0},"If the server env var OPENAI_API_KEY is set, the API Key field is optional."),r.a.createElement(p.a,{container:!0,spacing:2},r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(X.a,{label:"Model",value:e,onChange:e=>a(e.target.value),fullWidth:!0,variant:"outlined",size:"small"})),r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(X.a,{label:"OpenAI API Key (optional)",value:t,onChange:e=>l(e.target.value),fullWidth:!0,variant:"outlined",size:"small",type:"password",placeholder:"sk-..."})),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(X.a,{label:"System Prompt (optional)",value:o,onChange:e=>c(e.target.value),fullWidth:!0,variant:"outlined",size:"small"})),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(X.a,{label:"User Question",value:i,onChange:e=>s(e.target.value),fullWidth:!0,multiline:!0,rows:4,variant:"outlined"})),b&&r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(u.a,{color:"error"},b)),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement("div",{style:{display:"flex",gap:8}},r.a.createElement(y.a,{color:"primary",variant:"contained",onClick:async()=>{f(""),d("");const a=(i||"").trim();if(a){h(!0);try{const r=await fetch("/api/openai/chat",{method:"POST",headers:{"Content-Type":"application/json"},credentials:"include",body:JSON.stringify({prompt:a,model:(e||"").trim()||"gpt-4",api_key:t||void 0,system:o||void 0})});if(!r.ok){let e=await r.text();try{e=JSON.stringify(JSON.parse(e),null,2)}catch(n){}throw new Error(e)}const l=await r.json(),c="Model: ".concat(l.model," | Latency: ").concat(l.latency_sec,"s")+(l.usage?" | Usage: ".concat(JSON.stringify(l.usage)):"");d((l.response||"(Empty response)")+"\n\n---\n"+c)}catch(r){f("Error: "+r.message)}finally{h(!1)}}else f("Please enter a question.")},disabled:g},g?"Sending...":"Send Question"),r.a.createElement(y.a,{variant:"outlined",onClick:()=>{s(""),d(""),f("")}},"Clear"))),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(L.a,{style:{margin:"12px 0"}}),r.a.createElement(u.a,{variant:"subtitle2",color:"textSecondary"},"Response"),r.a.createElement("pre",{style:{whiteSpace:"pre-wrap",fontFamily:"ui-monospace, monospace"}},m))))};t(102);const ce=Object(c.a)({palette:{primary:{main:"#3f51b5"},secondary:{main:"#f50057"}},typography:{fontFamily:"Roboto, Arial, sans-serif"}});var ie=function(){const[e,a]=Object(n.useState)(null),[t,l]=Object(n.useState)(""),[o,c]=Object(n.useState)(!1),[y,b]=Object(n.useState)(null),[f,v]=Object(n.useState)(null),[x,S]=Object(n.useState)({yolo:!1,detr:!1,vit:!1});return Object(n.useEffect)(()=>{fetch("/api/status").then(e=>e.json()).then(e=>{S(e.models)}).catch(e=>{console.error("Error checking API status:",e),v("Error connecting to the backend API. Please make sure the server is running.")})},[]),r.a.createElement(i.a,{theme:ce},r.a.createElement(s.a,{style:{flexGrow:1}},r.a.createElement(m.a,{position:"static"},r.a.createElement(d.a,null,r.a.createElement(u.a,{variant:"h6",style:{flexGrow:1}},"Multi-Model Object Detection Demo"))),r.a.createElement(g.a,{maxWidth:"lg",style:{marginTop:ce.spacing(4),marginBottom:ce.spacing(4)}},r.a.createElement(p.a,{container:!0,spacing:3},r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(E.a,{style:{padding:ce.spacing(2)}},r.a.createElement(u.a,{variant:"h5",gutterBottom:!0},"Upload an image to see how each model performs!"),r.a.createElement(u.a,{variant:"body1",paragraph:!0},"This demo showcases three different object detection and image classification models:"),r.a.createElement(u.a,{variant:"body1",component:"div"},r.a.createElement("ul",null,r.a.createElement("li",null,r.a.createElement("strong",null,"YOLOv8"),": Fast and accurate object detection"),r.a.createElement("li",null,r.a.createElement("strong",null,"DETR"),": DEtection TRansformer for object detection"),r.a.createElement("li",null,r.a.createElement("strong",null,"ViT"),": Vision Transformer for image classification"))))),r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(w,{onImageUpload:e=>{a(e),b(null),v(null)}})),r.a.createElement(p.a,{item:!0,xs:12,md:6},r.a.createElement(z,{onModelSelect:e=>{l(e),b(null),v(null)},onProcess:async()=>{if(!e||!t)return void v("Please select both an image and a model");c(!0),v(null);const a=new FormData;a.append("image",e);let n="";switch(t){case"yolo":n="/api/detect/yolo";break;case"detr":n="/api/detect/detr";break;case"vit":n="/api/classify/vit";break;default:return v("Invalid model selection"),void c(!1)}try{const e=await fetch(n,{method:"POST",body:a});if(!e.ok)throw new Error("HTTP error! Status: ".concat(e.status));const r=await e.json();b({model:t,data:r})}catch(r){console.error("Error processing image:",r),v("Error processing image: ".concat(r.message))}finally{c(!1)}},isProcessing:o,modelsStatus:x,selectedModel:t,imageSelected:!!e})),f&&r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(E.a,{style:{padding:ce.spacing(2),backgroundColor:"#ffebee"}},r.a.createElement(u.a,{color:"error"},f))),o&&r.a.createElement(p.a,{item:!0,xs:12,style:{textAlign:"center",margin:"".concat(ce.spacing(4),"px 0")}},r.a.createElement(h.a,null),r.a.createElement(u.a,{variant:"h6",style:{marginTop:ce.spacing(2)}},"Processing image...")),y&&r.a.createElement(r.a.Fragment,null,r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(ne,{results:y})),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(le,{visionResults:y.data,model:y.model}))),r.a.createElement(p.a,{item:!0,xs:12},r.a.createElement(oe,null))))))};var se=e=>{e&&e instanceof Function&&t.e(3).then(t.bind(null,170)).then(a=>{let{getCLS:t,getFID:n,getFCP:r,getLCP:l,getTTFB:o}=a;t(e),n(e),r(e),l(e),o(e)})};o.a.render(r.a.createElement(r.a.StrictMode,null,r.a.createElement(ie,null)),document.getElementById("root")),se()},92:function(e,a,t){e.exports=t(103)},97:function(e,a,t){}},[[92,1,2]]]);
2
- //# sourceMappingURL=main.9549fb04.chunk.js.map